diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index ed816859fb..b9c471b3d2 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -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"); diff --git a/Source/Core/InputCommon/Src/EventHandler.cpp b/Source/Core/InputCommon/Src/EventHandler.cpp index 465a73ca4d..9565e0bce6 100644 --- a/Source/Core/InputCommon/Src/EventHandler.cpp +++ b/Source/Core/InputCommon/Src/EventHandler.cpp @@ -8,8 +8,8 @@ EventHandler *EventHandler::m_Instance = 0; EventHandler::EventHandler() { for (int i=0; i= 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; } diff --git a/Source/Plugins/Plugin_PadSimpleEvnt/Src/PadSimple.cpp b/Source/Plugins/Plugin_PadSimpleEvnt/Src/PadSimple.cpp index f89720d24f..b70ca46dd6 100644 --- a/Source/Plugins/Plugin_PadSimpleEvnt/Src/PadSimple.cpp +++ b/Source/Plugins/Plugin_PadSimpleEvnt/Src/PadSimple.cpp @@ -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); } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h b/Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h index 5126847ac2..a75dc3e082 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h @@ -2,6 +2,7 @@ #define _GLWINDOW_H #include "Common.h" +#include "EventHandler.h" #include "Globals.h" #include "Config.h" #include "pluginspecs_video.h" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/SConscript b/Source/Plugins/Plugin_VideoOGL/Src/SConscript index 1bf8705852..c2f07d7c31 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/SConscript +++ b/Source/Plugins/Plugin_VideoOGL/Src/SConscript @@ -41,6 +41,7 @@ if gfxenv['GLTEST']: 'nmain.cpp', 'nGLUtil.cpp', ] + libs += [ 'inputcommon' ] else: files += [ 'main.cpp', diff --git a/Source/Plugins/Plugin_VideoOGL/Src/X11Window.cpp b/Source/Plugins/Plugin_VideoOGL/Src/X11Window.cpp index db592b5cc5..6ce0e0c98b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/X11Window.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/X11Window.cpp @@ -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); +} diff --git a/Source/Plugins/Plugin_VideoOGL/Src/X11Window.h b/Source/Plugins/Plugin_VideoOGL/Src/X11Window.h index 023c19de3b..be83801129 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/X11Window.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/X11Window.h @@ -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