From c10b6129136c7e8d7ea5925fc74258290203bc42 Mon Sep 17 00:00:00 2001 From: stephena Date: Fri, 25 Feb 2005 02:29:38 +0000 Subject: [PATCH] - More restructuring of the event handling code. - Finally able to quit a game and start another within the same program invocation (Escape quits current game, Ctrl-Q quits emulator) - More tightly integrated SDL into the codebase. It's about time we make use of SDL exclusively, and possibly speed up the code. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@374 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/common/mainSDL.cxx | 383 ++++++++++------------------ stella/src/emucore/Console.cxx | 5 +- stella/src/emucore/Event.hxx | 12 +- stella/src/emucore/EventHandler.cxx | 258 +++++++++++-------- stella/src/emucore/EventHandler.hxx | 94 ++++--- stella/src/emucore/PropsSet.cxx | 4 +- 6 files changed, 368 insertions(+), 388 deletions(-) diff --git a/stella/src/common/mainSDL.cxx b/stella/src/common/mainSDL.cxx index cace40a71..599fc68ad 100644 --- a/stella/src/common/mainSDL.cxx +++ b/stella/src/common/mainSDL.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: mainSDL.cxx,v 1.25 2005-02-22 20:19:24 stephena Exp $ +// $Id: mainSDL.cxx,v 1.26 2005-02-25 02:29:37 stephena Exp $ //============================================================================ #include @@ -153,123 +153,6 @@ struct KeyList StellaEvent::KeyCode keyCode; }; -// Place the most used keys first to speed up access -// Todo - initialize this array in the same order as the SDLK -// keys are defined, so it can be a constant-time LUT -static KeyList keyList[] = { - { SDLK_F1, StellaEvent::KCODE_F1 }, - { SDLK_F2, StellaEvent::KCODE_F2 }, - { SDLK_F3, StellaEvent::KCODE_F3 }, - { SDLK_F4, StellaEvent::KCODE_F4 }, - { SDLK_F5, StellaEvent::KCODE_F5 }, - { SDLK_F6, StellaEvent::KCODE_F6 }, - { SDLK_F7, StellaEvent::KCODE_F7 }, - { SDLK_F8, StellaEvent::KCODE_F8 }, - { SDLK_F9, StellaEvent::KCODE_F9 }, - { SDLK_F10, StellaEvent::KCODE_F10 }, - { SDLK_F11, StellaEvent::KCODE_F11 }, - { SDLK_F12, StellaEvent::KCODE_F12 }, - { SDLK_F13, StellaEvent::KCODE_F13 }, - { SDLK_F14, StellaEvent::KCODE_F14 }, - { SDLK_F15, StellaEvent::KCODE_F15 }, - - { SDLK_UP, StellaEvent::KCODE_UP }, - { SDLK_DOWN, StellaEvent::KCODE_DOWN }, - { SDLK_LEFT, StellaEvent::KCODE_LEFT }, - { SDLK_RIGHT, StellaEvent::KCODE_RIGHT }, - { SDLK_SPACE, StellaEvent::KCODE_SPACE }, - { SDLK_LCTRL, StellaEvent::KCODE_LCTRL }, - { SDLK_RCTRL, StellaEvent::KCODE_RCTRL }, - { SDLK_LALT, StellaEvent::KCODE_LALT }, - { SDLK_RALT, StellaEvent::KCODE_RALT }, - { SDLK_LSUPER, StellaEvent::KCODE_LWIN }, - { SDLK_RSUPER, StellaEvent::KCODE_RWIN }, - { SDLK_MENU, StellaEvent::KCODE_MENU }, - - { SDLK_a, StellaEvent::KCODE_a }, - { SDLK_b, StellaEvent::KCODE_b }, - { SDLK_c, StellaEvent::KCODE_c }, - { SDLK_d, StellaEvent::KCODE_d }, - { SDLK_e, StellaEvent::KCODE_e }, - { SDLK_f, StellaEvent::KCODE_f }, - { SDLK_g, StellaEvent::KCODE_g }, - { SDLK_h, StellaEvent::KCODE_h }, - { SDLK_i, StellaEvent::KCODE_i }, - { SDLK_j, StellaEvent::KCODE_j }, - { SDLK_k, StellaEvent::KCODE_k }, - { SDLK_l, StellaEvent::KCODE_l }, - { SDLK_m, StellaEvent::KCODE_m }, - { SDLK_n, StellaEvent::KCODE_n }, - { SDLK_o, StellaEvent::KCODE_o }, - { SDLK_p, StellaEvent::KCODE_p }, - { SDLK_q, StellaEvent::KCODE_q }, - { SDLK_r, StellaEvent::KCODE_r }, - { SDLK_s, StellaEvent::KCODE_s }, - { SDLK_t, StellaEvent::KCODE_t }, - { SDLK_u, StellaEvent::KCODE_u }, - { SDLK_v, StellaEvent::KCODE_v }, - { SDLK_w, StellaEvent::KCODE_w }, - { SDLK_x, StellaEvent::KCODE_x }, - { SDLK_y, StellaEvent::KCODE_y }, - { SDLK_z, StellaEvent::KCODE_z }, - - { SDLK_0, StellaEvent::KCODE_0 }, - { SDLK_1, StellaEvent::KCODE_1 }, - { SDLK_2, StellaEvent::KCODE_2 }, - { SDLK_3, StellaEvent::KCODE_3 }, - { SDLK_4, StellaEvent::KCODE_4 }, - { SDLK_5, StellaEvent::KCODE_5 }, - { SDLK_6, StellaEvent::KCODE_6 }, - { SDLK_7, StellaEvent::KCODE_7 }, - { SDLK_8, StellaEvent::KCODE_8 }, - { SDLK_9, StellaEvent::KCODE_9 }, - - { SDLK_KP0, StellaEvent::KCODE_KP0 }, - { SDLK_KP1, StellaEvent::KCODE_KP1 }, - { SDLK_KP2, StellaEvent::KCODE_KP2 }, - { SDLK_KP3, StellaEvent::KCODE_KP3 }, - { SDLK_KP4, StellaEvent::KCODE_KP4 }, - { SDLK_KP5, StellaEvent::KCODE_KP5 }, - { SDLK_KP6, StellaEvent::KCODE_KP6 }, - { SDLK_KP7, StellaEvent::KCODE_KP7 }, - { SDLK_KP8, StellaEvent::KCODE_KP8 }, - { SDLK_KP9, StellaEvent::KCODE_KP9 }, - { SDLK_KP_PERIOD, StellaEvent::KCODE_KP_PERIOD }, - { SDLK_KP_DIVIDE, StellaEvent::KCODE_KP_DIVIDE }, - { SDLK_KP_MULTIPLY, StellaEvent::KCODE_KP_MULTIPLY}, - { SDLK_KP_MINUS, StellaEvent::KCODE_KP_MINUS }, - { SDLK_KP_PLUS, StellaEvent::KCODE_KP_PLUS }, - { SDLK_KP_ENTER, StellaEvent::KCODE_KP_ENTER }, - { SDLK_KP_EQUALS, StellaEvent::KCODE_KP_EQUALS }, - - { SDLK_BACKSPACE, StellaEvent::KCODE_BACKSPACE }, - { SDLK_TAB, StellaEvent::KCODE_TAB }, - { SDLK_CLEAR, StellaEvent::KCODE_CLEAR }, - { SDLK_RETURN, StellaEvent::KCODE_RETURN }, - { SDLK_ESCAPE, StellaEvent::KCODE_ESCAPE }, - { SDLK_COMMA, StellaEvent::KCODE_COMMA }, - { SDLK_MINUS, StellaEvent::KCODE_MINUS }, - { SDLK_PERIOD, StellaEvent::KCODE_PERIOD }, - { SDLK_SLASH, StellaEvent::KCODE_SLASH }, - { SDLK_BACKSLASH, StellaEvent::KCODE_BACKSLASH }, - { SDLK_SEMICOLON, StellaEvent::KCODE_SEMICOLON }, - { SDLK_EQUALS, StellaEvent::KCODE_EQUALS }, - { SDLK_QUOTE, StellaEvent::KCODE_QUOTE }, - { SDLK_BACKQUOTE, StellaEvent::KCODE_BACKQUOTE }, - { SDLK_LEFTBRACKET, StellaEvent::KCODE_LEFTBRACKET}, - { SDLK_RIGHTBRACKET,StellaEvent::KCODE_RIGHTBRACKET}, - - { SDLK_PRINT, StellaEvent::KCODE_PRTSCREEN }, - { SDLK_MODE, StellaEvent::KCODE_SCRLOCK }, - { SDLK_PAUSE, StellaEvent::KCODE_PAUSE }, - { SDLK_INSERT, StellaEvent::KCODE_INSERT }, - { SDLK_HOME, StellaEvent::KCODE_HOME }, - { SDLK_PAGEUP, StellaEvent::KCODE_PAGEUP }, - { SDLK_DELETE, StellaEvent::KCODE_DELETE }, - { SDLK_END, StellaEvent::KCODE_END }, - { SDLK_PAGEDOWN, StellaEvent::KCODE_PAGEDOWN } - }; - /** Set the mouse to emulate the given paddle @@ -410,9 +293,9 @@ void HandleEvents() case SDL_KEYUP: case SDL_KEYDOWN: { - SDLKey key = event.key.keysym.sym; - SDLMod mod = event.key.keysym.mod; - uInt32 state = event.key.type == SDL_KEYDOWN ? 1 : 0; + SDLKey key = event.key.keysym.sym; + SDLMod mod = event.key.keysym.mod; + uInt8 state = event.key.type == SDL_KEYDOWN ? 1 : 0; // An attempt to speed up event processing // All SDL-specific event actions are accessed by either @@ -444,120 +327,130 @@ void HandleEvents() case SDLK_f: theDisplay->toggleFilter(); break; + } #ifdef DEVELOPER_SUPPORT - case SDLK_END: // Alt-End increases XStart - theOSystem->console().changeXStart(1); - theDisplay->resize(0); - break; + if(theOSystem->eventHandler().state() == EventHandler::S_EMULATE) + { + switch(int(key)) + { + case SDLK_END: // Alt-End increases XStart + theOSystem->console().changeXStart(1); + theDisplay->resize(0); + break; - case SDLK_HOME: // Alt-Home decreases XStart - theOSystem->console().changeXStart(0); - theDisplay->resize(0); - break; + case SDLK_HOME: // Alt-Home decreases XStart + theOSystem->console().changeXStart(0); + theDisplay->resize(0); + break; - case SDLK_PAGEUP: // Alt-PageUp increases YStart - theOSystem->console().changeYStart(1); - theDisplay->resize(0); - break; + case SDLK_PAGEUP: // Alt-PageUp increases YStart + theOSystem->console().changeYStart(1); + theDisplay->resize(0); + break; - case SDLK_PAGEDOWN: // Alt-PageDown decreases YStart - theOSystem->console().changeYStart(0); - theDisplay->resize(0); - break; + case SDLK_PAGEDOWN: // Alt-PageDown decreases YStart + theOSystem->console().changeYStart(0); + theDisplay->resize(0); + break; + } } #endif } else if(mod & KMOD_CTRL && state) { - switch(int(key)) + if(key == SDLK_q) { - case SDLK_g: - // don't change grabmouse in fullscreen mode - if(!theDisplay->fullScreen()) - { - theGrabMouseIndicator = !theGrabMouseIndicator; - theSettings->setBool("grabmouse", theGrabMouseIndicator); - theDisplay->grabMouse(theGrabMouseIndicator); - } - break; + theOSystem->eventHandler().handleEvent(Event::Quit, 1); + } + else if(theOSystem->eventHandler().state() == EventHandler::S_EMULATE) + { + switch(int(key)) + { + case SDLK_g: + // don't change grabmouse in fullscreen mode + if(!theDisplay->fullScreen()) + { + theGrabMouseIndicator = !theGrabMouseIndicator; + theSettings->setBool("grabmouse", theGrabMouseIndicator); + theDisplay->grabMouse(theGrabMouseIndicator); + } + break; - case SDLK_h: - // don't change hidecursor in fullscreen mode - if(!theDisplay->fullScreen()) - { - theHideCursorIndicator = !theHideCursorIndicator; - theSettings->setBool("hidecursor", theHideCursorIndicator); - theDisplay->showCursor(!theHideCursorIndicator); - } - break; + case SDLK_h: + // don't change hidecursor in fullscreen mode + if(!theDisplay->fullScreen()) + { + theHideCursorIndicator = !theHideCursorIndicator; + theSettings->setBool("hidecursor", theHideCursorIndicator); + theDisplay->showCursor(!theHideCursorIndicator); + } + break; - case SDLK_f: // Ctrl-f toggles NTSC/PAL mode - theOSystem->console().toggleFormat(); - theDisplay->setupPalette(); - break; + case SDLK_0: // Ctrl-0 sets the mouse to paddle 0 + SetPaddleMode(0); + break; - case SDLK_p: // Ctrl-p toggles different palettes - theOSystem->console().togglePalette(); - theDisplay->setupPalette(); - break; + case SDLK_1: // Ctrl-1 sets the mouse to paddle 1 + SetPaddleMode(1); + break; - case SDLK_0: // Ctrl-0 sets the mouse to paddle 0 - SetPaddleMode(0); - break; + case SDLK_2: // Ctrl-2 sets the mouse to paddle 2 + SetPaddleMode(2); + break; - case SDLK_1: // Ctrl-1 sets the mouse to paddle 1 - SetPaddleMode(1); - break; + case SDLK_3: // Ctrl-3 sets the mouse to paddle 3 + SetPaddleMode(3); + break; - case SDLK_2: // Ctrl-2 sets the mouse to paddle 2 - SetPaddleMode(2); - break; + case SDLK_f: // Ctrl-f toggles NTSC/PAL mode + theOSystem->console().toggleFormat(); + theDisplay->setupPalette(); + break; - case SDLK_3: // Ctrl-3 sets the mouse to paddle 3 - SetPaddleMode(3); - break; + case SDLK_p: // Ctrl-p toggles different palettes + theOSystem->console().togglePalette(); + theDisplay->setupPalette(); + break; #ifdef DEVELOPER_SUPPORT - case SDLK_END: // Ctrl-End increases Width - theOSystem->console().changeWidth(1); - theDisplay->resize(0); - break; + case SDLK_END: // Ctrl-End increases Width + theOSystem->console().changeWidth(1); + theDisplay->resize(0); + break; - case SDLK_HOME: // Ctrl-Home decreases Width - theOSystem->console().changeWidth(0); - theDisplay->resize(0); - break; + case SDLK_HOME: // Ctrl-Home decreases Width + theOSystem->console().changeWidth(0); + theDisplay->resize(0); + break; - case SDLK_PAGEUP: // Ctrl-PageUp increases Height - theOSystem->console().changeHeight(1); - theDisplay->resize(0); - break; + case SDLK_PAGEUP: // Ctrl-PageUp increases Height + theOSystem->console().changeHeight(1); + theDisplay->resize(0); + break; - case SDLK_PAGEDOWN: // Ctrl-PageDown decreases Height - theOSystem->console().changeHeight(0); - theDisplay->resize(0); - break; + case SDLK_PAGEDOWN: // Ctrl-PageDown decreases Height + theOSystem->console().changeHeight(0); + theDisplay->resize(0); + break; #endif - case SDLK_s: // Ctrl-s saves properties to a file - // Attempt to merge with propertiesSet - if(theSettings->getBool("mergeprops")) - theOSystem->console().saveProperties(theOSystem->propertiesOutputFilename(), true); - else // Save to file in home directory - { - string newPropertiesFile = theOSystem->baseDir() + "/" + \ - theOSystem->console().properties().get("Cartridge.Name") + ".pro"; - theOSystem->console().saveProperties(newPropertiesFile); - } - break; + case SDLK_s: // Ctrl-s saves properties to a file + // Attempt to merge with propertiesSet + if(theSettings->getBool("mergeprops")) + theOSystem->console().saveProperties(theOSystem->propertiesOutputFilename(), true); + else // Save to file in home directory + { + string newPropertiesFile = theOSystem->baseDir() + "/" + \ + theOSystem->console().properties().get("Cartridge.Name") + ".pro"; + theOSystem->console().saveProperties(newPropertiesFile); + } + break; + } } } - // check all the other keys - for(uInt32 i = 0; i < sizeof(keyList) / sizeof(KeyList); ++i) - if(keyList[i].scanCode == key) - theOSystem->eventHandler().sendKeyEvent(keyList[i].keyCode, state); - + // Otherwise, let the event handler deal with it + theOSystem->eventHandler().handleKeyEvent(key, mod, state); break; // SDL_KEYUP, SDL_KEYDOWN } @@ -582,7 +475,7 @@ void HandleEvents() Int32 resistance = (Int32)(1000000.0 * (width - mouseX) / width); - theOSystem->eventHandler().sendEvent(Paddle_Resistance[thePaddleMode], resistance); + theOSystem->eventHandler().handleEvent(Paddle_Resistance[thePaddleMode], resistance); break; // SDL_MOUSEMOTION } @@ -592,7 +485,7 @@ void HandleEvents() { Int32 value = event.button.type == SDL_MOUSEBUTTONDOWN ? 1 : 0; - theOSystem->eventHandler().sendEvent(Paddle_Button[thePaddleMode], value); + theOSystem->eventHandler().handleEvent(Paddle_Button[thePaddleMode], value); break; // SDL_MOUSEBUTTONUP, SDL_MOUSEBUTTONDOWN } @@ -602,7 +495,7 @@ void HandleEvents() if((event.active.state & SDL_APPACTIVE) && (event.active.gain == 0)) { if(!theOSystem->eventHandler().doPause()) - theOSystem->eventHandler().sendEvent(Event::Pause, 1); + theOSystem->eventHandler().handleEvent(Event::Pause, 1); } break; // SDL_ACTIVEEVENT @@ -610,15 +503,13 @@ void HandleEvents() case SDL_QUIT: { - theOSystem->eventHandler().sendEvent(Event::Quit, 1); - + theOSystem->eventHandler().handleEvent(Event::Quit, 1); break; // SDL_QUIT } case SDL_VIDEOEXPOSE: { theDisplay->refresh(); - break; // SDL_VIDEOEXPOSE } } @@ -697,23 +588,23 @@ void HandleEvents() { if(type == JT_STELLADAPTOR_1) { - theOSystem->eventHandler().sendEvent(Event::JoystickZeroFire, state); - theOSystem->eventHandler().sendEvent(Event::DrivingZeroFire, state); - theOSystem->eventHandler().sendEvent(Event::PaddleZeroFire, state); + theOSystem->eventHandler().handleEvent(Event::JoystickZeroFire, state); + theOSystem->eventHandler().handleEvent(Event::DrivingZeroFire, state); + theOSystem->eventHandler().handleEvent(Event::PaddleZeroFire, state); } else { - theOSystem->eventHandler().sendEvent(Event::JoystickOneFire, state); - theOSystem->eventHandler().sendEvent(Event::DrivingOneFire, state); - theOSystem->eventHandler().sendEvent(Event::PaddleTwoFire, state); + theOSystem->eventHandler().handleEvent(Event::JoystickOneFire, state); + theOSystem->eventHandler().handleEvent(Event::DrivingOneFire, state); + theOSystem->eventHandler().handleEvent(Event::PaddleTwoFire, state); } } else if(button == 1) { if(type == JT_STELLADAPTOR_1) - theOSystem->eventHandler().sendEvent(Event::PaddleOneFire, state); + theOSystem->eventHandler().handleEvent(Event::PaddleOneFire, state); else - theOSystem->eventHandler().sendEvent(Event::PaddleThreeFire, state); + theOSystem->eventHandler().handleEvent(Event::PaddleThreeFire, state); } break; @@ -722,26 +613,26 @@ void HandleEvents() value = event.jaxis.value; // Send axis events for the joysticks - theOSystem->eventHandler().sendEvent(SA_Axis[type-2][axis][0], + theOSystem->eventHandler().handleEvent(SA_Axis[type-2][axis][0], (value < -16384) ? 1 : 0); - theOSystem->eventHandler().sendEvent(SA_Axis[type-2][axis][1], + theOSystem->eventHandler().handleEvent(SA_Axis[type-2][axis][1], (value > 16384) ? 1 : 0); // Send axis events for the paddles resistance = (Int32) (1000000.0 * (32767 - value) / 65534); - theOSystem->eventHandler().sendEvent(SA_Axis[type-2][axis][2], resistance); + theOSystem->eventHandler().handleEvent(SA_Axis[type-2][axis][2], resistance); // Send events for the driving controllers if(axis == 1) { if(value <= -16384-4096) - theOSystem->eventHandler().sendEvent(SA_DrivingValue[type-2],2); + theOSystem->eventHandler().handleEvent(SA_DrivingValue[type-2],2); else if(value > 16384+4096) - theOSystem->eventHandler().sendEvent(SA_DrivingValue[type-2],1); + theOSystem->eventHandler().handleEvent(SA_DrivingValue[type-2],1); else if(value >= 16384-4096) - theOSystem->eventHandler().sendEvent(SA_DrivingValue[type-2],0); + theOSystem->eventHandler().handleEvent(SA_DrivingValue[type-2],0); else - theOSystem->eventHandler().sendEvent(SA_DrivingValue[type-2],3); + theOSystem->eventHandler().handleEvent(SA_DrivingValue[type-2],3); } break; } @@ -767,7 +658,8 @@ void SetupProperties(PropertiesSet& set) // When 'listrominfo' or 'mergeprops' is specified, we need to have the // full list in memory - if(theSettings->getBool("listrominfo") || theSettings->getBool("mergeprops")) +// FIXME - we need the whole list in memory +// if(theSettings->getBool("listrominfo") || theSettings->getBool("mergeprops")) useMemList = true; stringstream buf; @@ -843,10 +735,9 @@ void mainGameLoop() for(;;) { // Exit if the user wants to quit - if(theOSystem->eventHandler().doQuit()) - { + if(theOSystem->eventHandler().doExitGame() || + theOSystem->eventHandler().doQuit()) break; - } startTime = GetTicks(); HandleEvents(); @@ -879,10 +770,9 @@ void mainGameLoop() for(;;) { // Exit if the user wants to quit - if(theOSystem->eventHandler().doQuit()) - { + if(theOSystem->eventHandler().doExitGame() || + theOSystem->eventHandler().doQuit()) break; - } startTime = GetTicks(); HandleEvents(); @@ -1070,16 +960,21 @@ int main(int argc, char* argv[]) for(;;) { // theOSystem->gui().showRomLauncher(); - cerr << "GUI not yet written, run game again (y or n): "; - char runagain; - cin >> runagain; - if(runagain == 'n') + if(theOSystem->eventHandler().doQuit()) break; - else + else // FIXME - add code here to delay a little { -cerr << "Attempting to open " << romfile << endl; - theConsole = CreateConsole(romfile); - mainGameLoop(); + cerr << "GUI not yet written, run game again (y or n): "; + char runagain; + cin >> runagain; + if(runagain == 'n') + break; + else + { + cerr << "Attempting to open " << romfile << endl; + theConsole = CreateConsole(romfile); + mainGameLoop(); + } } } } diff --git a/stella/src/emucore/Console.cxx b/stella/src/emucore/Console.cxx index bc8eaf420..6adc63e41 100644 --- a/stella/src/emucore/Console.cxx +++ b/stella/src/emucore/Console.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Console.cxx,v 1.41 2005-02-22 02:59:53 stephena Exp $ +// $Id: Console.cxx,v 1.42 2005-02-25 02:29:37 stephena Exp $ //============================================================================ #include @@ -64,6 +64,9 @@ Console::Console(const uInt8* image, uInt32 size, OSystem* osystem) // Add the current console to the system myOSystem->attach(this); + // Indicate that emulation should start now + myOSystem->eventHandler().reset(EventHandler::S_EMULATE); + // Attach the event subsystem to the current console myEvent = myOSystem->eventHandler().event(); diff --git a/stella/src/emucore/Event.hxx b/stella/src/emucore/Event.hxx index 87816022a..1fafa0634 100644 --- a/stella/src/emucore/Event.hxx +++ b/stella/src/emucore/Event.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Event.hxx,v 1.5 2004-06-04 12:22:12 stephena Exp $ +// $Id: Event.hxx,v 1.6 2005-02-25 02:29:38 stephena Exp $ //============================================================================ #ifndef EVENT_HXX @@ -25,13 +25,15 @@ class Event; /** @author Bradford W. Mott - @version $Id: Event.hxx,v 1.5 2004-06-04 12:22:12 stephena Exp $ + @version $Id: Event.hxx,v 1.6 2005-02-25 02:29:38 stephena Exp $ */ class Event { public: /** - Enumeration of console and controller event types + Enumeration of all possible events in Stella, including both + console and controller event types as well as events that aren't + technically part of the core */ enum Type { @@ -69,7 +71,7 @@ class Event DrivingOneClockwise, DrivingOneCounterClockwise, DrivingOneValue, DrivingOneFire, - ChangeState, LoadState, SaveState, TakeSnapshot, Pause, Quit, + ChangeState, LoadState, SaveState, TakeSnapshot, Pause, Quit, ExitGame, LastType }; @@ -103,5 +105,5 @@ class Event // Array of values associated with each event type Int32 myValues[LastType]; }; -#endif +#endif diff --git a/stella/src/emucore/EventHandler.cxx b/stella/src/emucore/EventHandler.cxx index db033fcc6..54d65710f 100644 --- a/stella/src/emucore/EventHandler.cxx +++ b/stella/src/emucore/EventHandler.cxx @@ -13,11 +13,12 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: EventHandler.cxx,v 1.33 2005-02-22 02:59:53 stephena Exp $ +// $Id: EventHandler.cxx,v 1.34 2005-02-25 02:29:38 stephena Exp $ //============================================================================ #include #include +#include #include "Event.hxx" #include "EventHandler.hxx" @@ -36,11 +37,11 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EventHandler::EventHandler(OSystem* osystem) : myOSystem(osystem), - myCurrentState(0), - myPauseStatus(false), - myQuitStatus(false), - myMenuStatus(false), - myRemapEnabledFlag(true) + myState(S_NONE), + myLSState(0), + myPauseFlag(false), + myExitGameFlag(false), + myQuitFlag(false) { // Add this eventhandler object to the OSystem myOSystem->attach(this); @@ -48,9 +49,13 @@ EventHandler::EventHandler(OSystem* osystem) // Create the event object which will be used for this handler myEvent = new Event(); - // Erase the KeyEvent array - for(Int32 i = 0; i < StellaEvent::LastKCODE; ++i) - myKeyTable[i] = Event::NoType; + // Erase the KeyEvent arrays + for(Int32 i = 0; i < 256; ++i) + { + myKeyTable[i] = Event::NoType; + myAltKeyTable[i] = Event::NoType; + myCtrlKeyTable[i] = Event::NoType; + } // Erase the JoyEvent array for(Int32 i = 0; i < StellaEvent::LastJSTICK*StellaEvent::LastJCODE; ++i) @@ -86,45 +91,91 @@ Event* EventHandler::event() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::sendKeyEvent(StellaEvent::KeyCode key, Int32 state) +void EventHandler::reset(State state) { - // First check if we are changing menu mode, and only change when not paused - // Sound is paused when entering menu mode, but the framebuffer is kept active - if(myRemapEnabledFlag && key == StellaEvent::KCODE_TAB && state == 1 && !myPauseStatus) + myState = state; + myLSState = 0; + myPauseFlag = false; + myExitGameFlag = false; + myQuitFlag = false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EventHandler::handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state) +{ + // Handle keys here that are accessible no matter which mode we're in + + // Toggle menu mode + if(key == SDLK_TAB && state == 1 && !myPauseFlag) { - myMenuStatus = !myMenuStatus; - myOSystem->frameBuffer().showMenu(myMenuStatus); - myOSystem->sound().mute(myMenuStatus); - return; + if(myState == S_EMULATE) + { + myState = S_MENU; + myOSystem->frameBuffer().showMenu(true); // FIXME - move this into gui class + myOSystem->sound().mute(true); + return; + } + else if(myState == S_MENU) + { + myState = S_EMULATE; + myOSystem->frameBuffer().showMenu(false); // FIXME - move this into gui class + myOSystem->sound().mute(false); + return; + } } - // Determine where the event should be sent - if(myMenuStatus) - myOSystem->frameBuffer().sendKeyEvent(key, state); - else - sendEvent(myKeyTable[key], state); + // Determine which mode we're in, then send the event to the appropriate place + switch(myState) + { + case S_NONE: + return; + break; + + case S_EMULATE: +// if(mod & KMOD_ALT && state) +// handleEvent(myAltKeyTable[key], state); +// else if(mod & KMOD_CTRL && state) +// handleEvent(myCtrlKeyTable[key], state); +// else + handleEvent(myKeyTable[key], state); + break; + + case S_BROWSER: +//FIXME myOSystem->gui().browser().handleKeyEvent(key, mod, state); + break; + + case S_MENU: +//FIXME myOSystem->gui().menu().handleKeyEvent(key, mod, state); + break; + + case S_DEBUGGER: + // Not yet implemented + break; + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandler::sendJoyEvent(StellaEvent::JoyStick stick, StellaEvent::JoyCode code, Int32 state) { +// FIXME +/* // Determine where the event should be sent if(myMenuStatus) myOSystem->frameBuffer().sendJoyEvent(stick, code, state); else - sendEvent(myJoyTable[stick*StellaEvent::LastJCODE + code], state); + handleEvent(myJoyTable[stick*StellaEvent::LastJCODE + code], state); +*/ } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::sendEvent(Event::Type event, Int32 state) +void EventHandler::handleEvent(Event::Type event, Int32 state) { // Ignore unmapped events if(event == Event::NoType) return; - // Take care of special events that aren't technically part of - // the emulation core + // Take care of special events that aren't part of the emulation core if(state == 1) { if(event == Event::SaveState) @@ -149,14 +200,20 @@ void EventHandler::sendEvent(Event::Type event, Int32 state) } else if(event == Event::Pause) { - myPauseStatus = !myPauseStatus; - myOSystem->frameBuffer().pause(myPauseStatus); - myOSystem->sound().mute(myPauseStatus); + myPauseFlag = !myPauseFlag; + myOSystem->frameBuffer().pause(myPauseFlag); + myOSystem->sound().mute(myPauseFlag); + return; + } + else if(event == Event::ExitGame) + { + myExitGameFlag = true; + myOSystem->sound().mute(true); return; } else if(event == Event::Quit) { - myQuitStatus = !myQuitStatus; + myQuitFlag = true; myOSystem->settings().saveConfig(); return; } @@ -234,73 +291,72 @@ void EventHandler::getJoymapArray(Event::Type** array, uInt32* size) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandler::setDefaultKeymap() { - myKeyTable[StellaEvent::KCODE_1] = Event::KeyboardZero1; - myKeyTable[StellaEvent::KCODE_2] = Event::KeyboardZero2; - myKeyTable[StellaEvent::KCODE_3] = Event::KeyboardZero3; - myKeyTable[StellaEvent::KCODE_q] = Event::KeyboardZero4; - myKeyTable[StellaEvent::KCODE_w] = Event::KeyboardZero5; - myKeyTable[StellaEvent::KCODE_e] = Event::KeyboardZero6; - myKeyTable[StellaEvent::KCODE_a] = Event::KeyboardZero7; - myKeyTable[StellaEvent::KCODE_s] = Event::KeyboardZero8; - myKeyTable[StellaEvent::KCODE_d] = Event::KeyboardZero9; - myKeyTable[StellaEvent::KCODE_z] = Event::KeyboardZeroStar; - myKeyTable[StellaEvent::KCODE_x] = Event::KeyboardZero0; - myKeyTable[StellaEvent::KCODE_c] = Event::KeyboardZeroPound; + myKeyTable[ SDLK_1 ] = Event::KeyboardZero1; + myKeyTable[ SDLK_2 ] = Event::KeyboardZero2; + myKeyTable[ SDLK_3 ] = Event::KeyboardZero3; + myKeyTable[ SDLK_q ] = Event::KeyboardZero4; + myKeyTable[ SDLK_w ] = Event::KeyboardZero5; + myKeyTable[ SDLK_e ] = Event::KeyboardZero6; + myKeyTable[ SDLK_a ] = Event::KeyboardZero7; + myKeyTable[ SDLK_s ] = Event::KeyboardZero8; + myKeyTable[ SDLK_d ] = Event::KeyboardZero9; + myKeyTable[ SDLK_z ] = Event::KeyboardZeroStar; + myKeyTable[ SDLK_x ] = Event::KeyboardZero0; + myKeyTable[ SDLK_c ] = Event::KeyboardZeroPound; - myKeyTable[StellaEvent::KCODE_8] = Event::KeyboardOne1; - myKeyTable[StellaEvent::KCODE_9] = Event::KeyboardOne2; - myKeyTable[StellaEvent::KCODE_0] = Event::KeyboardOne3; - myKeyTable[StellaEvent::KCODE_i] = Event::KeyboardOne4; - myKeyTable[StellaEvent::KCODE_o] = Event::KeyboardOne5; - myKeyTable[StellaEvent::KCODE_p] = Event::KeyboardOne6; - myKeyTable[StellaEvent::KCODE_k] = Event::KeyboardOne7; - myKeyTable[StellaEvent::KCODE_l] = Event::KeyboardOne8; - myKeyTable[StellaEvent::KCODE_SEMICOLON] = Event::KeyboardOne9; - myKeyTable[StellaEvent::KCODE_COMMA] = Event::KeyboardOneStar; - myKeyTable[StellaEvent::KCODE_PERIOD] = Event::KeyboardOne0; - myKeyTable[StellaEvent::KCODE_SLASH] = Event::KeyboardOnePound; + myKeyTable[ SDLK_8 ] = Event::KeyboardOne1; + myKeyTable[ SDLK_9 ] = Event::KeyboardOne2; + myKeyTable[ SDLK_0 ] = Event::KeyboardOne3; + myKeyTable[ SDLK_i ] = Event::KeyboardOne4; + myKeyTable[ SDLK_o ] = Event::KeyboardOne5; + myKeyTable[ SDLK_p ] = Event::KeyboardOne6; + myKeyTable[ SDLK_k ] = Event::KeyboardOne7; + myKeyTable[ SDLK_l ] = Event::KeyboardOne8; + myKeyTable[ SDLK_SEMICOLON ] = Event::KeyboardOne9; + myKeyTable[ SDLK_COMMA ] = Event::KeyboardOneStar; + myKeyTable[ SDLK_PERIOD ] = Event::KeyboardOne0; + myKeyTable[ SDLK_SLASH ] = Event::KeyboardOnePound; - myKeyTable[StellaEvent::KCODE_UP] = Event::JoystickZeroUp; - myKeyTable[StellaEvent::KCODE_DOWN] = Event::JoystickZeroDown; - myKeyTable[StellaEvent::KCODE_LEFT] = Event::JoystickZeroLeft; - myKeyTable[StellaEvent::KCODE_RIGHT] = Event::JoystickZeroRight; - myKeyTable[StellaEvent::KCODE_SPACE] = Event::JoystickZeroFire; - myKeyTable[StellaEvent::KCODE_4] = Event::BoosterGripZeroTrigger; - myKeyTable[StellaEvent::KCODE_5] = Event::BoosterGripZeroBooster; + myKeyTable[ SDLK_UP ] = Event::JoystickZeroUp; + myKeyTable[ SDLK_DOWN ] = Event::JoystickZeroDown; + myKeyTable[ SDLK_LEFT ] = Event::JoystickZeroLeft; + myKeyTable[ SDLK_RIGHT ] = Event::JoystickZeroRight; + myKeyTable[ SDLK_SPACE ] = Event::JoystickZeroFire; + myKeyTable[ SDLK_4 ] = Event::BoosterGripZeroTrigger; + myKeyTable[ SDLK_5 ] = Event::BoosterGripZeroBooster; - myKeyTable[StellaEvent::KCODE_y] = Event::JoystickOneUp; - myKeyTable[StellaEvent::KCODE_h] = Event::JoystickOneDown; - myKeyTable[StellaEvent::KCODE_g] = Event::JoystickOneLeft; - myKeyTable[StellaEvent::KCODE_j] = Event::JoystickOneRight; - myKeyTable[StellaEvent::KCODE_f] = Event::JoystickOneFire; - myKeyTable[StellaEvent::KCODE_6] = Event::BoosterGripOneTrigger; - myKeyTable[StellaEvent::KCODE_7] = Event::BoosterGripOneBooster; + myKeyTable[ SDLK_y ] = Event::JoystickOneUp; + myKeyTable[ SDLK_h ] = Event::JoystickOneDown; + myKeyTable[ SDLK_g ] = Event::JoystickOneLeft; + myKeyTable[ SDLK_j ] = Event::JoystickOneRight; + myKeyTable[ SDLK_f ] = Event::JoystickOneFire; + myKeyTable[ SDLK_6 ] = Event::BoosterGripOneTrigger; + myKeyTable[ SDLK_7 ] = Event::BoosterGripOneBooster; - myKeyTable[StellaEvent::KCODE_INSERT] = Event::DrivingZeroCounterClockwise; - myKeyTable[StellaEvent::KCODE_PAGEUP] = Event::DrivingZeroClockwise; - myKeyTable[StellaEvent::KCODE_HOME] = Event::DrivingZeroFire; + myKeyTable[ SDLK_INSERT ] = Event::DrivingZeroCounterClockwise; + myKeyTable[ SDLK_PAGEUP ] = Event::DrivingZeroClockwise; + myKeyTable[ SDLK_HOME ] = Event::DrivingZeroFire; - myKeyTable[StellaEvent::KCODE_DELETE] = Event::DrivingOneCounterClockwise; - myKeyTable[StellaEvent::KCODE_PAGEDOWN] = Event::DrivingOneClockwise; - myKeyTable[StellaEvent::KCODE_END] = Event::DrivingOneFire; + myKeyTable[ SDLK_DELETE ] = Event::DrivingOneCounterClockwise; + myKeyTable[ SDLK_PAGEDOWN ] = Event::DrivingOneClockwise; + myKeyTable[ SDLK_END ] = Event::DrivingOneFire; - myKeyTable[StellaEvent::KCODE_F1] = Event::ConsoleSelect; - myKeyTable[StellaEvent::KCODE_F2] = Event::ConsoleReset; - myKeyTable[StellaEvent::KCODE_F3] = Event::ConsoleColor; - myKeyTable[StellaEvent::KCODE_F4] = Event::ConsoleBlackWhite; - myKeyTable[StellaEvent::KCODE_F5] = Event::ConsoleLeftDifficultyA; - myKeyTable[StellaEvent::KCODE_F6] = Event::ConsoleLeftDifficultyB; - myKeyTable[StellaEvent::KCODE_F7] = Event::ConsoleRightDifficultyA; - myKeyTable[StellaEvent::KCODE_F8] = Event::ConsoleRightDifficultyB; - myKeyTable[StellaEvent::KCODE_F9] = Event::SaveState; - myKeyTable[StellaEvent::KCODE_F10] = Event::ChangeState; - myKeyTable[StellaEvent::KCODE_F11] = Event::LoadState; - myKeyTable[StellaEvent::KCODE_F12] = Event::TakeSnapshot; - - myKeyTable[StellaEvent::KCODE_PAUSE] = Event::Pause; + myKeyTable[ SDLK_F1 ] = Event::ConsoleSelect; + myKeyTable[ SDLK_F2 ] = Event::ConsoleReset; + myKeyTable[ SDLK_F3 ] = Event::ConsoleColor; + myKeyTable[ SDLK_F4 ] = Event::ConsoleBlackWhite; + myKeyTable[ SDLK_F5 ] = Event::ConsoleLeftDifficultyA; + myKeyTable[ SDLK_F6 ] = Event::ConsoleLeftDifficultyB; + myKeyTable[ SDLK_F7 ] = Event::ConsoleRightDifficultyA; + myKeyTable[ SDLK_F8 ] = Event::ConsoleRightDifficultyB; + myKeyTable[ SDLK_F9 ] = Event::SaveState; + myKeyTable[ SDLK_F10 ] = Event::ChangeState; + myKeyTable[ SDLK_F11 ] = Event::LoadState; + myKeyTable[ SDLK_F12 ] = Event::TakeSnapshot; + myKeyTable[ SDLK_PAUSE ] = Event::Pause; #ifndef MAC_OSX - myKeyTable[StellaEvent::KCODE_ESCAPE] = Event::Quit; + myKeyTable[ SDLK_ESCAPE ] = Event::ExitGame; #endif } @@ -343,17 +399,17 @@ void EventHandler::saveState() { // Do a state save using the System string md5 = myOSystem->console().properties().get("Cartridge.MD5"); - string filename = myOSystem->stateFilename(md5, myCurrentState); + string filename = myOSystem->stateFilename(md5, myLSState); int result = myOSystem->console().system().saveState(filename, md5); // Print appropriate message ostringstream buf; if(result == 1) - buf << "State " << myCurrentState << " saved"; + buf << "State " << myLSState << " saved"; else if(result == 2) - buf << "Error saving state " << myCurrentState; + buf << "Error saving state " << myLSState; else if(result == 3) - buf << "Invalid state " << myCurrentState << " file"; + buf << "Invalid state " << myLSState << " file"; myOSystem->frameBuffer().showMessage(buf.str()); } @@ -361,14 +417,14 @@ void EventHandler::saveState() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandler::changeState() { - if(myCurrentState == 9) - myCurrentState = 0; + if(myLSState == 9) + myLSState = 0; else - ++myCurrentState; + ++myLSState; // Print appropriate message ostringstream buf; - buf << "Changed to slot " << myCurrentState; + buf << "Changed to slot " << myLSState; myOSystem->frameBuffer().showMessage(buf.str()); } @@ -378,17 +434,17 @@ void EventHandler::loadState() { // Do a state save using the System string md5 = myOSystem->console().properties().get("Cartridge.MD5"); - string filename = myOSystem->stateFilename(md5, myCurrentState); + string filename = myOSystem->stateFilename(md5, myLSState); int result = myOSystem->console().system().loadState(filename, md5); // Print appropriate message ostringstream buf; if(result == 1) - buf << "State " << myCurrentState << " loaded"; + buf << "State " << myLSState << " loaded"; else if(result == 2) - buf << "Error loading state " << myCurrentState; + buf << "Error loading state " << myLSState; else if(result == 3) - buf << "Invalid state " << myCurrentState << " file"; + buf << "Invalid state " << myLSState << " file"; myOSystem->frameBuffer().showMessage(buf.str()); } diff --git a/stella/src/emucore/EventHandler.hxx b/stella/src/emucore/EventHandler.hxx index 23b55f86a..2654f0ef1 100644 --- a/stella/src/emucore/EventHandler.hxx +++ b/stella/src/emucore/EventHandler.hxx @@ -13,12 +13,14 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: EventHandler.hxx,v 1.16 2005-02-21 20:42:21 stephena Exp $ +// $Id: EventHandler.hxx,v 1.17 2005-02-25 02:29:38 stephena Exp $ //============================================================================ #ifndef EVENTHANDLER_HXX #define EVENTHANDLER_HXX +#include + #include "bspf.hxx" #include "Event.hxx" #include "StellaEvent.hxx" @@ -40,7 +42,7 @@ class OSystem; mapping can take place. @author Stephen Anthony - @version $Id: EventHandler.hxx,v 1.16 2005-02-21 20:42:21 stephena Exp $ + @version $Id: EventHandler.hxx,v 1.17 2005-02-25 02:29:38 stephena Exp $ */ class EventHandler { @@ -55,6 +57,9 @@ class EventHandler */ virtual ~EventHandler(); + // Enumeration representing the different states of operation + enum State { S_NONE, S_EMULATE, S_BROWSER, S_MENU, S_DEBUGGER }; + /** Returns the event object associated with this handler class. @@ -62,13 +67,37 @@ class EventHandler */ Event* event(); + /** + Returns the current state of the EventHandler + + @return The State type + */ + inline State state() { return myState; } + + /** + Resets the state machine of the EventHandler to the defaults + + @param The current state to set + */ + void reset(State state); + + /** + Send an event directly to the event handler. + These events cannot be remapped. + + @param type The event + @param value The value for the event + */ + void handleEvent(Event::Type type, Int32 value); + /** Send a keyboard event to the handler. - @param code The StellaEvent code - @param state The StellaEvent state + @param key keysym + @param mod modifiers + @param state state of key */ - void sendKeyEvent(StellaEvent::KeyCode code, Int32 state); + void handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state); /** Send a joystick button event to the handler. @@ -79,32 +108,21 @@ class EventHandler */ void sendJoyEvent(StellaEvent::JoyStick stick, StellaEvent::JoyCode code, Int32 state); - - /** - Send an event directly to the event handler. - These events cannot be remapped. - - @param type The event - @param value The value for the event - */ - void sendEvent(Event::Type type, Int32 value); - /** - Enable/disable remapping mode. - - @param status The toggle for enable/disable - */ - void enableRemapping(bool status) { myRemapEnabledFlag = status; } - /** This method indicates whether a pause event has been received. */ - bool doPause() { return myPauseStatus; } + inline bool doPause() { return myPauseFlag; } + + /** + This method indicates whether a exit game event has been received. + */ + inline bool doExitGame() { return myExitGameFlag; } /** This method indicates whether a quit event has been received. */ - bool doQuit() { return myQuitStatus; } + inline bool doQuit() { return myQuitFlag; } void getKeymapArray(Event::Type** array, uInt32* size); void getJoymapArray(Event::Type** array, uInt32* size); @@ -126,8 +144,14 @@ class EventHandler // Global OSystem object OSystem* myOSystem; - // Array of key events - Event::Type myKeyTable[StellaEvent::LastKCODE]; + // Array of key events, indexed by SDLKey + Event::Type myKeyTable[256]; + + // Array of alt-key events, indexed by SDLKey + Event::Type myAltKeyTable[256]; + + // Array of ctrl-key events, indexed by SDLKey + Event::Type myCtrlKeyTable[256]; // Array of joystick events Event::Type myJoyTable[StellaEvent::LastJSTICK*StellaEvent::LastJCODE]; @@ -135,29 +159,29 @@ class EventHandler // Array of messages for each Event string ourMessageTable[Event::LastType]; + // Indicates the current state of the system (ie, which mode is current) + State myState; + // Global Event object Event* myEvent; // Indicates the current state to use for state loading/saving - uInt32 myCurrentState; + uInt32 myLSState; // Indicates the current pause status - bool myPauseStatus; + bool myPauseFlag; - // Indicates the current quit status - bool myQuitStatus; + // Indicates whether to quit the current game + bool myExitGameFlag; + + // Indicates whether to quit the emulator + bool myQuitFlag; // The current keymap in string form string myKeymapString; // The current joymap in string form string myJoymapString; - - // Indicates that the main menu is being entered - bool myMenuStatus; - - // Indicates that remapping mode is enabled - bool myRemapEnabledFlag; }; #endif diff --git a/stella/src/emucore/PropsSet.cxx b/stella/src/emucore/PropsSet.cxx index 6e9501284..f72ab05b6 100644 --- a/stella/src/emucore/PropsSet.cxx +++ b/stella/src/emucore/PropsSet.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: PropsSet.cxx,v 1.8 2004-07-10 13:20:35 stephena Exp $ +// $Id: PropsSet.cxx,v 1.9 2005-02-25 02:29:38 stephena Exp $ //============================================================================ #include @@ -66,7 +66,7 @@ void PropertiesSet::getMD5(string md5, Properties &properties) } // Else, do a BST search for the node with the given md5 - TreeNode *current = myRoot; + TreeNode* current = myRoot; while(current) {