More code for event handling

almost working, for some reason the event handler creates 2 instances instead of one
if anyone can see why from the code I'll be like SOOOO happy:P



git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1798 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
nakeee 2009-01-05 22:51:35 +00:00
parent bfe43d0c61
commit 790ee70b36
7 changed files with 255 additions and 105 deletions

View file

@ -60,7 +60,6 @@
#include "MemTools.h"
#include "Host.h"
#include "LogManager.h"
#include "InputCommon.h"
#include "State.h"
@ -135,8 +134,6 @@ bool Init(const SCoreStartupParameter _CoreParameter)
g_CoreStartupParameter = _CoreParameter;
InputCommon::Init();
// start the thread again
_dbg_assert_(HLE, g_pThread == NULL);
@ -238,44 +235,44 @@ void* GetWindowHandle()
THREAD_RETURN CpuThread(void *pArg)
{
Common::SetCurrentThreadName("CPU thread");
const SCoreStartupParameter& _CoreParameter = g_CoreStartupParameter;
const SCoreStartupParameter& _CoreParameter = g_CoreStartupParameter;
if (!g_CoreStartupParameter.bUseDualCore)
{
PluginVideo::Video_Prepare(); //wglMakeCurrent
}
if (_CoreParameter.bRunCompareServer)
{
CPUCompare::StartServer();
PowerPC::state = PowerPC::CPU_RUNNING;
PluginVideo::Video_Prepare(); //wglMakeCurrent
}
else if (_CoreParameter.bRunCompareClient)
if (_CoreParameter.bRunCompareServer)
{
PanicAlert("Compare Debug : Press OK when ready.");
CPUCompare::ConnectAsClient();
CPUCompare::StartServer();
PowerPC::state = PowerPC::CPU_RUNNING;
}
if (_CoreParameter.bLockThreads)
Common::Thread::SetCurrentThreadAffinity(1); //Force to first core
if (_CoreParameter.bUseFastMem)
else if (_CoreParameter.bRunCompareClient)
{
PanicAlert("Compare Debug : Press OK when ready.");
CPUCompare::ConnectAsClient();
}
if (_CoreParameter.bLockThreads)
Common::Thread::SetCurrentThreadAffinity(1); //Force to first core
if (_CoreParameter.bUseFastMem)
{
#ifdef _M_X64
// Let's run under memory watch
EMM::InstallExceptionHandler();
// Let's run under memory watch
EMM::InstallExceptionHandler();
#else
PanicAlert("32-bit platforms do not support fastmem yet. Report this bug.");
PanicAlert("32-bit platforms do not support fastmem yet. Report this bug.");
#endif
}
CCPU::Run();
if (_CoreParameter.bRunCompareServer || _CoreParameter.bRunCompareClient)
CCPU::Run();
if (_CoreParameter.bRunCompareServer || _CoreParameter.bRunCompareClient)
{
CPUCompare::Stop();
CPUCompare::Stop();
}
return 0;
return 0;
}
//////////////////////////////////////////
@ -370,55 +367,55 @@ THREAD_RETURN EmuThread(void *pArg)
else
PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
// update the window again because all stuff is initialized
Host_UpdateDisasmDialog();
Host_UpdateMainFrame();
// update the window again because all stuff is initialized
Host_UpdateDisasmDialog();
Host_UpdateMainFrame();
//This thread, after creating the EmuWindow, spawns a CPU thread,
//then takes over and becomes the graphics thread
//In single core mode, the CPU thread does the graphics. In fact, the
//CPU thread should in this case also create the emuwindow...
// Spawn the CPU thread
Common::Thread *cpuThread = NULL;
//////////////////////////////////////////////////////////////////////////
// ENTER THE VIDEO THREAD LOOP
//////////////////////////////////////////////////////////////////////////
if (!Core::GetStartupParameter().bUseDualCore)
{
#ifdef _WIN32
cpuThread = new Common::Thread(CpuThread, pArg);
//Common::SetCurrentThreadName("Idle thread");
//TODO(ector) : investigate using GetMessage instead .. although
//then we lose the powerdown check. ... unless powerdown sends a message :P
while (PowerPC::state != PowerPC::CPU_POWERDOWN)
{
if (Callback_PeekMessages) {
Callback_PeekMessages();
}
Common::SleepCurrentThread(20);
}
#else
// In single-core mode, the Emulation main thread is also the CPU thread
CpuThread(pArg);
#endif
#ifdef _WIN32
cpuThread = new Common::Thread(CpuThread, pArg);
//Common::SetCurrentThreadName("Idle thread");
//TODO(ector) : investigate using GetMessage instead .. although
//then we lose the powerdown check. ... unless powerdown sends a message :P
while (PowerPC::state != PowerPC::CPU_POWERDOWN)
{
if (Callback_PeekMessages) {
Callback_PeekMessages();
}
Common::SleepCurrentThread(20);
}
#else
// In single-core mode, the Emulation main thread is also the CPU thread
CpuThread(pArg);
#endif
}
else
{
cpuThread = new Common::Thread(CpuThread, pArg);
PluginVideo::Video_Prepare(); //wglMakeCurrent
Common::SetCurrentThreadName("Video thread");
PluginVideo::Video_EnterLoop();
cpuThread = new Common::Thread(CpuThread, pArg);
PluginVideo::Video_Prepare(); //wglMakeCurrent
Common::SetCurrentThreadName("Video thread");
PluginVideo::Video_EnterLoop();
}
// Wait for CPU thread to exit - it should have been signaled to do so by now
if (cpuThread)
cpuThread->WaitForDeath();
cpuThread->WaitForDeath();
if (g_pUpdateFPSDisplay != NULL)
g_pUpdateFPSDisplay("Stopping...");
g_pUpdateFPSDisplay("Stopping...");
if (cpuThread)
{
@ -427,20 +424,19 @@ THREAD_RETURN EmuThread(void *pArg)
cpuThread = NULL;
}
g_bHwInit = false;
PluginPAD::PAD_Shutdown();
PluginPAD::UnloadPlugin();
if (_CoreParameter.bWii)
{
PluginWiimote::Wiimote_Shutdown();
PluginWiimote::UnloadPlugin();
PluginWiimote::Wiimote_Shutdown();
PluginWiimote::UnloadPlugin();
}
PluginDSP::DSP_Shutdown();
PluginDSP::UnloadPlugin();
PluginVideo::Video_Shutdown();
PluginVideo::UnloadPlugin();
InputCommon::Shutdown();
HW::Shutdown();
LOG(MASTER_LOG, "EmuThread exited");

View file

@ -8,8 +8,8 @@ EventHandler *EventHandler::m_Instance = 0;
EventHandler::EventHandler() {
for (int i=0; i<NUMKEYS; i++)
for (int j=0; j<NUMMODS; j++)
keys[i][j] = NULL;
for (int j=0; j<NUMMODS; j++)
keys[i][j] = NULL;
// memset(keys, sizeof(listenFuncPtr) * NUMKEYS*NUMMODS, 0);
memset(mouse, sizeof(listenFuncPtr) * (sf::Mouse::Count+1), 0);
memset(joys, sizeof(listenFuncPtr) * (sf::Joy::Count+1), 0);
@ -20,25 +20,29 @@ EventHandler::~EventHandler() {
}
EventHandler *EventHandler::GetInstance() {
fprintf(stderr, "handler instance %p\n", m_Instance);
if (! m_Instance)
m_Instance = new EventHandler();
return m_Instance;
}
void EventHandler::Destroy() {
if (m_Instance)
delete m_Instance;
fprintf(stderr, "deleting instance %p\n", m_Instance);
m_Instance = 0;
}
bool EventHandler::RegisterEventListener(listenFuncPtr func, Keys key) {
if (key.inputType == KeyboardInput) {
// fprintf(stderr, "Registering %d:%d %p\n", key.keyCode, key.mods, func);
fprintf(stderr, "Registering %d:%d %p\n", key.keyCode, key.mods, func);
if (key.keyCode == sf::Key::Count || key.mods >= NUMMODS ||
key.keyCode >= NUMKEYS || keys[key.keyCode][key.mods])
key.keyCode >= NUMKEYS)
return false;
if (keys[key.keyCode][key.mods] && keys[key.keyCode][key.mods] != func)
return false
;
keys[key.keyCode][key.mods] = func;
} else if (key.inputType == MouseInput) {
if (mouse[key.mouseButton])
@ -68,12 +72,15 @@ void EventHandler::Update() {
for (unsigned int i = 0; i < eventQueue.size();i++) {
sf::Event ev = eventQueue.front();
eventQueue.pop();
keys[ev.Key.Code][ev.Key.Alt+2*ev.Key.Shift+4*ev.Key.Control](ev);
fprintf(stderr, "Updating event type %d code %d mod %d func %p\n", ev.Type, ev.Key.Code, ev.Key.Alt+2*ev.Key.Shift+4*ev.Key.Control, keys[ev.Key.Code][ev.Key.Alt+2*ev.Key.Shift+4*ev.Key.Control]);
if(keys[ev.Key.Code][ev.Key.Alt+2*ev.Key.Shift+4*ev.Key.Control])
keys[ev.Key.Code][ev.Key.Alt+2*ev.Key.Shift+4*ev.Key.Control](ev);
}
}
bool EventHandler::addEvent(sf::Event *ev) {
eventQueue.push(*ev);
fprintf(stderr, "Got event type %d code %d\n", ev->Type, ev->Key.Code);
return true;
}

View file

@ -108,12 +108,16 @@ bool registerKey(int nPad, int id, sf::Key::Code code, int mods) {
}
// FIXME: unregister old event
// We need to handle mod change
// and double registers
if (pad[nPad].keyForControl[id] != 0) {
oldKey.inputType = KeyboardInput;
oldKey.keyCode = pad[nPad].keyForControl[id];
oldKey.mods = mods;
// Might be not be registered yet
// eventHandler->RemoveEventListener(oldKey);
}
@ -236,6 +240,16 @@ void PAD_Shutdown()
}
bool ParseKeyEvent(sf::Event ev) {
fprintf(stderr, "parsing type %d code %d\n", ev.Type, ev.Key.Code);
// FIXME: should we support more than one control?
for (int i = 0; i < NUMCONTROLS; i++) {
if (ev.Key.Code == pad[0].keyForControl[i]) {
KeyStatus[i] = (ev.Type == sf::Event::KeyPressed);
break;
}
}
return true;
}
@ -384,7 +398,6 @@ void LoadConfig()
file.Get(SectionName, controlNames[x],
&key, (i==0)?defaultKeyForControl[x]:0);
// pad[i].keyForControl[x] = (sf::Key::Code)key;
registerKey(i, x, (sf::Key::Code)key);
}
}

View file

@ -2,6 +2,7 @@
#define _GLWINDOW_H
#include "Common.h"
#include "EventHandler.h"
#include "Globals.h"
#include "Config.h"
#include "pluginspecs_video.h"

View file

@ -41,6 +41,7 @@ if gfxenv['GLTEST']:
'nmain.cpp',
'nGLUtil.cpp',
]
libs += [ 'inputcommon' ]
else:
files += [
'main.cpp',

View file

@ -203,48 +203,62 @@ bool X11Window::PeekMessages() {
// TODO: implement
return false;
}
// Taken from sfml code
void X11Window::ProcessEvent(XEvent WinEvent) {
switch (WinEvent.type) {
case KeyPress :
{
// Get the keysym of the key that has been pressed
static XComposeStatus KeyboardStatus;
char Buffer[32];
KeySym Sym;
XLookupString(&WinEvent.xkey, Buffer, sizeof(Buffer), &Sym, &KeyboardStatus);
// Fill the event parameters
sf::Event Evt;
Evt.Type = sf::Event::KeyPressed;
Evt.Key.Code = KeysymToSF(Sym);
Evt.Key.Alt = WinEvent.xkey.state & Mod1Mask;
Evt.Key.Control = WinEvent.xkey.state & ControlMask;
Evt.Key.Shift = WinEvent.xkey.state & ShiftMask;
EventHandler::GetInstance()->addEvent(&Evt);
break;
}
// Key up event
case KeyRelease :
{
// Get the keysym of the key that has been pressed
char Buffer[32];
KeySym Sym;
XLookupString(&WinEvent.xkey, Buffer, 32, &Sym, NULL);
// Fill the event parameters
sf::Event Evt;
Evt.Type = sf::Event::KeyReleased;
Evt.Key.Code = KeysymToSF(Sym);
Evt.Key.Alt = WinEvent.xkey.state & Mod1Mask;
Evt.Key.Control = WinEvent.xkey.state & ControlMask;
Evt.Key.Shift = WinEvent.xkey.state & ShiftMask;
EventHandler::GetInstance()->addEvent(&Evt);
break;
}
}
}
void X11Window::Update() {
// We just check all of our events here
XEvent event;
KeySym key;
static bool ShiftPressed = false;
static bool ControlPressed = false;
static int FKeyPressed = -1;
int x,y;
u32 w,h,depth;
// KeySym key;
// int x,y;
// u32 w,h,depth;
int num_events;
for (num_events = XPending(dpy);num_events > 0;num_events--) {
XNextEvent(dpy, &event);
switch(event.type) {
case KeyRelease:
key = XLookupKeysym((XKeyEvent*)&event, 0);
if(key >= XK_F1 && key <= XK_F9) {
g_VideoInitialize.pKeyPress(FKeyPressed, ShiftPressed, ControlPressed);
FKeyPressed = -1;
} else {
if(key == XK_Shift_L || key == XK_Shift_R)
ShiftPressed = false;
else if(key == XK_Control_L || key == XK_Control_R)
ControlPressed = false;
else
XPutBackEvent(dpy, &event);
}
break;
case KeyPress:
key = XLookupKeysym((XKeyEvent*)&event, 0);
if(key >= XK_F1 && key <= XK_F9)
FKeyPressed = key - 0xff4e;
else {
if(key == XK_Shift_L || key == XK_Shift_R)
ShiftPressed = true;
else if(key == XK_Control_L || key == XK_Control_R)
ControlPressed = true;
else
XPutBackEvent(dpy, &event);
}
break;
case ButtonPress:
XNextEvent(dpy, &event);
ProcessEvent(event);
/* case ButtonPress:
case ButtonRelease:
XPutBackEvent(dpy, &event);
break;
@ -265,9 +279,11 @@ void X11Window::Update() {
// But to be safe, let's but them back anyway
//XPutBackEvent(dpy, &event);
break;
}
}*/
}
EventHandler::GetInstance()->Update();
float FactorW = 640.0f / (float)GetWidth();
float FactorH = 480.0f / (float)GetHeight();
float Max = (FactorW < FactorH) ? FactorH : FactorW;
@ -308,3 +324,115 @@ bool X11Window::MakeCurrent() {
return true;
}
// Taken from SF code
sf::Key::Code X11Window::KeysymToSF(KeySym Sym) {
// First convert to uppercase (to avoid dealing with two different keysyms for the same key)
KeySym Lower, Key;
XConvertCase(Sym, &Lower, &Key);
switch (Key)
{
case XK_Shift_L : return sf::Key::LShift;
case XK_Shift_R : return sf::Key::RShift;
case XK_Control_L : return sf::Key::LControl;
case XK_Control_R : return sf::Key::RControl;
case XK_Alt_L : return sf::Key::LAlt;
case XK_Alt_R : return sf::Key::RAlt;
case XK_Super_L : return sf::Key::LSystem;
case XK_Super_R : return sf::Key::RSystem;
case XK_Menu : return sf::Key::Menu;
case XK_Escape : return sf::Key::Escape;
case XK_semicolon : return sf::Key::SemiColon;
case XK_slash : return sf::Key::Slash;
case XK_equal : return sf::Key::Equal;
case XK_minus : return sf::Key::Dash;
case XK_bracketleft : return sf::Key::LBracket;
case XK_bracketright : return sf::Key::RBracket;
case XK_comma : return sf::Key::Comma;
case XK_period : return sf::Key::Period;
case XK_dead_acute : return sf::Key::Quote;
case XK_backslash : return sf::Key::BackSlash;
case XK_dead_grave : return sf::Key::Tilde;
case XK_space : return sf::Key::Space;
case XK_Return : return sf::Key::Return;
case XK_KP_Enter : return sf::Key::Return;
case XK_BackSpace : return sf::Key::Back;
case XK_Tab : return sf::Key::Tab;
case XK_Prior : return sf::Key::PageUp;
case XK_Next : return sf::Key::PageDown;
case XK_End : return sf::Key::End;
case XK_Home : return sf::Key::Home;
case XK_Insert : return sf::Key::Insert;
case XK_Delete : return sf::Key::Delete;
case XK_KP_Add : return sf::Key::Add;
case XK_KP_Subtract : return sf::Key::Subtract;
case XK_KP_Multiply : return sf::Key::Multiply;
case XK_KP_Divide : return sf::Key::Divide;
case XK_Pause : return sf::Key::Pause;
case XK_F1 : return sf::Key::F1;
case XK_F2 : return sf::Key::F2;
case XK_F3 : return sf::Key::F3;
case XK_F4 : return sf::Key::F4;
case XK_F5 : return sf::Key::F5;
case XK_F6 : return sf::Key::F6;
case XK_F7 : return sf::Key::F7;
case XK_F8 : return sf::Key::F8;
case XK_F9 : return sf::Key::F9;
case XK_F10 : return sf::Key::F10;
case XK_F11 : return sf::Key::F11;
case XK_F12 : return sf::Key::F12;
case XK_F13 : return sf::Key::F13;
case XK_F14 : return sf::Key::F14;
case XK_F15 : return sf::Key::F15;
case XK_Left : return sf::Key::Left;
case XK_Right : return sf::Key::Right;
case XK_Up : return sf::Key::Up;
case XK_Down : return sf::Key::Down;
case XK_KP_0 : return sf::Key::Numpad0;
case XK_KP_1 : return sf::Key::Numpad1;
case XK_KP_2 : return sf::Key::Numpad2;
case XK_KP_3 : return sf::Key::Numpad3;
case XK_KP_4 : return sf::Key::Numpad4;
case XK_KP_5 : return sf::Key::Numpad5;
case XK_KP_6 : return sf::Key::Numpad6;
case XK_KP_7 : return sf::Key::Numpad7;
case XK_KP_8 : return sf::Key::Numpad8;
case XK_Z : return sf::Key::Z;
case XK_E : return sf::Key::E;
case XK_R : return sf::Key::R;
case XK_T : return sf::Key::T;
case XK_Y : return sf::Key::Y;
case XK_U : return sf::Key::U;
case XK_I : return sf::Key::I;
case XK_O : return sf::Key::O;
case XK_P : return sf::Key::P;
case XK_Q : return sf::Key::Q;
case XK_S : return sf::Key::S;
case XK_D : return sf::Key::D;
case XK_F : return sf::Key::F;
case XK_G : return sf::Key::G;
case XK_H : return sf::Key::H;
case XK_J : return sf::Key::J;
case XK_K : return sf::Key::K;
case XK_L : return sf::Key::L;
case XK_M : return sf::Key::M;
case XK_W : return sf::Key::W;
case XK_X : return sf::Key::X;
case XK_C : return sf::Key::C;
case XK_V : return sf::Key::V;
case XK_B : return sf::Key::B;
case XK_N : return sf::Key::N;
case XK_0 : return sf::Key::Num0;
case XK_1 : return sf::Key::Num1;
case XK_2 : return sf::Key::Num2;
case XK_3 : return sf::Key::Num3;
case XK_4 : return sf::Key::Num4;
case XK_5 : return sf::Key::Num5;
case XK_6 : return sf::Key::Num6;
case XK_7 : return sf::Key::Num7;
case XK_8 : return sf::Key::Num8;
case XK_9 : return sf::Key::Num9;
}
return sf::Key::Code(0);
}

View file

@ -34,6 +34,10 @@ public:
static bool valid() { return true; }
~X11Window();
X11Window(int _iwidth, int _iheight);
static sf::Key::Code KeysymToSF(KeySym Sym);
private:
void ProcessEvent(XEvent WinEvent);
};
#else
class X11Window : public GLWindow