Ticket #8532: keyboard-repeat.diff
File keyboard-repeat.diff, 14.3 KB (added by , 19 years ago) |
---|
-
gui/newgui.cpp
46 46 47 47 enum { 48 48 kDoubleClickDelay = 500, // milliseconds 49 kCursorAnimateDelay = 250, 50 kKeyRepeatInitialDelay = 400, 51 kKeyRepeatSustainDelay = 100 49 kCursorAnimateDelay = 250 52 50 }; 53 51 54 52 #if defined(__SYMBIAN32__) // Testing: could be removed? Just making sure that an CVS update doesn't break my code :P … … 96 94 // Clear the cursor 97 95 memset(_cursor, 0xFF, sizeof(_cursor)); 98 96 99 // Reset key repeat100 _currentKeyDown.keycode = 0;101 102 97 #ifndef DISABLE_FANCY_THEMES 103 98 ConfMan.registerDefault("gui_theme", "default"); 104 99 Common::String style = ConfMan.get("gui_theme"); … … 186 181 187 182 switch (event.type) { 188 183 case OSystem::EVENT_KEYDOWN: 189 #if !defined(PALMOS_MODE)190 // init continuous event stream191 // not done on PalmOS because keyboard is emulated and keyup is not generated192 _currentKeyDown.ascii = event.kbd.ascii;193 _currentKeyDown.keycode = event.kbd.keycode;194 _currentKeyDown.flags = event.kbd.flags;195 _keyRepeatTime = time + kKeyRepeatInitialDelay;196 #endif197 184 activeDialog->handleKeyDown(event.kbd.ascii, event.kbd.keycode, event.kbd.flags); 198 185 break; 199 186 case OSystem::EVENT_KEYUP: 200 187 activeDialog->handleKeyUp(event.kbd.ascii, event.kbd.keycode, event.kbd.flags); 201 if (event.kbd.keycode == _currentKeyDown.keycode)202 // only stop firing events if it's the current key203 _currentKeyDown.keycode = 0;204 188 break; 205 189 case OSystem::EVENT_MOUSEMOVE: 206 190 activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); … … 247 231 } 248 232 } 249 233 250 // check if event should be sent again (keydown)251 if (_currentKeyDown.keycode != 0) {252 if (_keyRepeatTime < time) {253 // fire event254 activeDialog->handleKeyDown(_currentKeyDown.ascii, _currentKeyDown.keycode, _currentKeyDown.flags);255 _keyRepeatTime = time + kKeyRepeatSustainDelay;256 }257 }258 259 234 // Delay for a moment 260 235 _system->delayMillis(10); 261 236 } … … 274 249 // Backup old cursor 275 250 _oldCursorMode = _system->showMouse(true); 276 251 277 _currentKeyDown.keycode = 0;278 252 _lastClick.x = _lastClick.y = 0; 279 253 _lastClick.time = 0; 280 254 _lastClick.count = 0; -
gui/newgui.h
91 91 92 92 bool _stateIsSaved; 93 93 94 // for continuous events (keyDown)95 struct {96 uint16 ascii;97 byte flags;98 int keycode;99 } _currentKeyDown;100 uint32 _keyRepeatTime;101 102 94 // position and time of last mouse click (used to detect double clicks) 103 95 struct { 104 96 int16 x, y; // Position of mouse when the click occured -
engines/sword1/control.h
139 139 uint8 *_font, *_redFont; 140 140 uint8 *_screenBuf; 141 141 uint8 _keyPressed; 142 uint8 _keyRepeat;143 uint32 _keyRepeatTime;144 142 void delay(uint32 msecs); 145 143 uint16 _mouseX, _mouseY, _mouseState; 146 144 bool _mouseDown; -
engines/sword1/control.cpp
42 42 43 43 namespace Sword1 { 44 44 45 enum {46 kKeyRepeatInitialDelay = 400,47 kKeyRepeatSustainDelay = 10048 };49 50 45 enum LangStrings { 51 46 STR_PAUSED = 0, 52 47 STR_INSERT_CD_A, … … 171 166 _music = pMusic; 172 167 _sound = pSound; 173 168 _lStrings = _languageStrings + SwordEngine::_systemVars.language * 20; 174 _keyRepeat = 0;175 _keyRepeatTime = 0;176 169 } 177 170 178 171 void Control::askForCd(void) { … … 1054 1047 _keyPressed = 8; 1055 1048 else 1056 1049 _keyPressed = (byte)event.kbd.ascii; 1057 _keyRepeatTime = now + kKeyRepeatInitialDelay;1058 _keyRepeat = _keyPressed;1059 1050 // we skip the rest of the delay and return immediately 1060 1051 // to handle keyboard input 1061 1052 return; 1062 case OSystem::EVENT_KEYUP:1063 _keyRepeatTime = 0;1064 _keyRepeat = 0;1065 break;1066 1053 case OSystem::EVENT_MOUSEMOVE: 1067 1054 _mouseX = event.mouse.x; 1068 1055 _mouseY = event.mouse.y; … … 1094 1081 break; 1095 1082 } 1096 1083 } 1097 if (_keyRepeatTime && now > _keyRepeatTime) {1098 _keyRepeatTime += kKeyRepeatSustainDelay;1099 _keyPressed = _keyRepeat;1100 }1101 1084 1102 1085 _system->updateScreen(); 1103 1086 _system->delayMillis(10); -
engines/sword2/sword2.cpp
148 148 _debugger = NULL; 149 149 150 150 _keyboardEvent.pending = false; 151 _keyboardEvent.repeat = 0;152 151 _mouseEvent.pending = false; 153 152 154 153 _wantSfxDebug = false; … … 506 505 507 506 void Sword2Engine::clearInputEvents() { 508 507 _keyboardEvent.pending = false; 509 _keyboardEvent.repeat = 0;510 508 _mouseEvent.pending = false; 511 509 } 512 510 … … 517 515 void Sword2Engine::parseInputEvents() { 518 516 OSystem::Event event; 519 517 520 uint32 now = _system->getMillis();521 522 518 while (_system->pollEvent(event)) { 523 519 switch (event.type) { 524 520 case OSystem::EVENT_KEYDOWN: 525 521 if (!(_inputEventFilter & RD_KEYDOWN)) { 526 522 _keyboardEvent.pending = true; 527 _keyboardEvent.repeat = now + 400;528 523 _keyboardEvent.ascii = event.kbd.ascii; 529 524 _keyboardEvent.keycode = event.kbd.keycode; 530 525 _keyboardEvent.modifiers = event.kbd.flags; 531 526 } 532 527 break; 533 case OSystem::EVENT_KEYUP:534 _keyboardEvent.repeat = 0;535 break;536 528 case OSystem::EVENT_MOUSEMOVE: 537 529 if (!(_inputEventFilter & RD_KEYDOWN)) { 538 530 _mouse->setPos(event.mouse.x, event.mouse.y - MENUDEEP); … … 581 573 break; 582 574 } 583 575 } 584 585 // Handle keyboard auto-repeat586 if (!_keyboardEvent.pending && _keyboardEvent.repeat && now >= _keyboardEvent.repeat) {587 _keyboardEvent.pending = true;588 _keyboardEvent.repeat = now + 100;589 }590 576 } 591 577 592 578 void Sword2Engine::gameCycle() { -
engines/sword2/sword2.h
72 72 73 73 struct KeyboardEvent { 74 74 bool pending; 75 uint32 repeat;76 75 uint16 ascii; 77 76 int keycode; 78 77 int modifiers; -
engines/kyra/kyra.cpp
89 89 _scriptMain = 0; 90 90 _scriptClickData = 0; 91 91 _scriptClick = 0; 92 _keyPressed = 0; 92 93 _characterList = 0; 93 94 _movFacingTable = 0; 94 95 memset(_shapes, 0, sizeof(_shapes)); -
engines/kyra/gui.cpp
514 514 calcCoords(_menu[i]); 515 515 516 516 _menuRestoreScreen = true; 517 _keyboardEvent.pending = 0;518 _keyboardEvent.repeat = 0;519 517 _mousePressFlag = false; 520 518 521 519 _toplevelMenu = 0; … … 704 702 705 703 void KyraEngine::gui_getInput() { 706 704 OSystem::Event event; 707 uint32 now = _system->getMillis();708 705 709 706 _mouseWheel = 0; 710 707 while (_system->pollEvent(event)) { … … 730 727 _mouseWheel = 1; 731 728 break; 732 729 case OSystem::EVENT_KEYDOWN: 733 _keyboardEvent.pending = true; 734 _keyboardEvent.repeat = now + 400; 735 _keyboardEvent.ascii = event.kbd.ascii; 730 _keyPressed = event.kbd.ascii; 736 731 break; 737 case OSystem::EVENT_KEYUP:738 _keyboardEvent.repeat = 0;739 break;740 732 default: 741 733 break; 742 734 } 743 735 } 744 736 745 if (!_keyboardEvent.pending && _keyboardEvent.repeat && now >= _keyboardEvent.repeat) {746 _keyboardEvent.pending = true;747 _keyboardEvent.repeat = now + 100;748 }749 737 _system->delayMillis(3); 750 738 } 751 739 … … 910 898 void KyraEngine::gui_updateSavegameString() { 911 899 int length; 912 900 913 if (_key boardEvent.pending && _keyboardEvent.ascii) {901 if (_keyPressed) { 914 902 length = strlen(_savegameName); 915 903 916 if (_key boardEvent.ascii > 31 && _keyboardEvent.ascii< 127) {904 if (_keyPressed > 31 && _keyPressed < 127) { 917 905 if (length < 31) { 918 _savegameName[length] = _key boardEvent.ascii;906 _savegameName[length] = _keyPressed; 919 907 _savegameName[length+1] = 0; 920 908 gui_redrawTextfield(); 921 909 } 922 } else if (_key boardEvent.ascii == 8 ||_keyboardEvent.ascii== 127) {910 } else if (_keyPressed == 8 ||_keyPressed == 127) { 923 911 if (length > 0) { 924 912 _savegameName[length-1] = 0; 925 913 gui_redrawTextfield(); 926 914 } 927 } else if (_key boardEvent.ascii== 13) {915 } else if (_keyPressed == 13) { 928 916 _displaySubMenu = false; 929 917 } 930 918 } 931 919 932 _key boardEvent.pending = false;920 _keyPressed = 0; 933 921 } 934 922 935 923 int KyraEngine::gui_saveGame(Button *button) { -
engines/kyra/kyra.h
230 230 MenuItem item[6]; 231 231 }; 232 232 233 struct KeyboardEvent {234 bool pending;235 uint32 repeat;236 uint8 ascii;237 };238 239 233 class KyraEngine : public Engine { 240 234 friend class MusicPlayer; 241 235 friend class Debugger; … … 823 817 int _gameToLoad; 824 818 char _savegameName[31]; 825 819 const char *_specialSavegameString; 826 KeyboardEvent _keyboardEvent;820 uint8 _keyPressed; 827 821 828 822 struct KyragemState { 829 823 uint16 nextOperation; -
engines/saga/input.cpp
119 119 break; 120 120 } 121 121 break; 122 case OSystem::EVENT_KEYUP:123 _interface->processKeyUp(event.kbd.ascii);124 break;125 122 case OSystem::EVENT_LBUTTONUP: 126 123 _leftMouseButtonPressed = false; 127 124 break; -
engines/saga/interface.h
222 222 void drawStatusBar(); 223 223 void setVerbState(int verb, int state); 224 224 225 bool processAscii(uint16 ascii, bool synthetic = false); 226 void processKeyUp(uint16 ascii); 225 bool processAscii(uint16 ascii); 227 226 228 227 void keyBoss(); 229 228 void keyBossExit(); … … 243 242 } 244 243 245 244 private: 246 static void textInputRepeatCallback(void *refCon);247 248 245 void drawInventory(Surface *backBuffer); 249 246 void updateInventory(int pos); 250 247 void inventoryChangePos(int chg); … … 343 340 void calcOptionSaveSlider(); 344 341 bool processTextInput(uint16 ascii); 345 342 void processStatusTextInput(uint16 ascii); 346 void textInputStartRepeat(uint16 ascii);347 void textInputRepeat(void);348 343 349 344 public: 350 345 void converseInit(void); … … 452 447 453 448 uint _statusTextInputPos; 454 449 455 int _textInputRepeatPhase;456 uint16 _textInputRepeatChar;457 458 450 PalEntry _mapSavedPal[PAL_ENTRIES]; 459 451 bool _mapPanelCrossHairState; 460 452 -
engines/saga/interface.cpp
47 47 48 48 #include "common/config-manager.h" 49 49 #include "common/system.h" 50 #include "common/timer.h"51 50 52 51 namespace Saga { 53 52 … … 212 211 error("Interface::Interface(): not enough memory"); 213 212 } 214 213 215 _textInputRepeatPhase = 0;216 214 _textInput = false; 217 215 _statusTextInput = false; 218 216 _statusTextInputState = kStatusTextInputFirstRun; … … 316 314 _textInput = true; 317 315 _textInputStringLength = strlen(_textInputString); 318 316 _textInputPos = _textInputStringLength + 1; 319 _textInputRepeatPhase = 0;320 317 break; 321 318 case kPanelMap: 322 319 mapPanelShow(); … … 337 334 _textInputString[0] = 0; 338 335 _textInputStringLength = 0; 339 336 _textInputPos = _textInputStringLength + 1; 340 _textInputRepeatPhase = 0;341 337 break; 342 338 } 343 339 344 340 draw(); 345 341 } 346 342 347 bool Interface::processAscii(uint16 ascii , bool synthetic) {343 bool Interface::processAscii(uint16 ascii) { 348 344 // TODO: Checking for Esc and Enter below is a bit hackish, and 349 345 // and probably only works with the English version. Maybe we should 350 346 // add a flag to the button so it can indicate if it's the default or … … 352 348 353 349 int i; 354 350 PanelButton *panelButton; 355 if (!synthetic)356 _textInputRepeatPhase = 0;357 351 if (_statusTextInput) { 358 352 processStatusTextInput(ascii); 359 353 return true; … … 536 530 return false; 537 531 } 538 532 539 #define KEYBOARD_REPEAT_DELAY1 300000L540 #define KEYBOARD_REPEAT_DELAY2 50000L541 542 void Interface::textInputRepeatCallback(void *refCon) {543 ((Interface *)refCon)->textInputRepeat();544 }545 546 void Interface::textInputStartRepeat(uint16 ascii) {547 if (!_textInputRepeatPhase) {548 _textInputRepeatPhase = 1;549 Common::g_timer->removeTimerProc(&textInputRepeatCallback);550 Common::g_timer->installTimerProc(&textInputRepeatCallback, KEYBOARD_REPEAT_DELAY1, this);551 }552 553 _textInputRepeatChar = ascii;554 }555 556 void Interface::textInputRepeat() {557 if (_textInputRepeatPhase == 1) {558 _textInputRepeatPhase = 2;559 Common::g_timer->removeTimerProc(&textInputRepeatCallback);560 Common::g_timer->installTimerProc(&textInputRepeatCallback, KEYBOARD_REPEAT_DELAY2, this);561 } else if (_textInputRepeatPhase == 2) {562 processAscii(_textInputRepeatChar, true);563 }564 }565 566 void Interface::processKeyUp(uint16 ascii) {567 if (_textInputRepeatPhase) {568 Common::g_timer->removeTimerProc(&textInputRepeatCallback);569 _textInputRepeatPhase = 0;570 }571 }572 573 533 void Interface::setStatusText(const char *text, int statusColor) { 574 534 assert(text != NULL); 575 535 assert(strlen(text) < STATUS_TEXT_LEN); … … 928 888 929 889 void Interface::processStatusTextInput(uint16 ascii) { 930 890 931 textInputStartRepeat(ascii);932 891 switch (ascii) { 933 892 case 27: // esc 934 893 _statusTextInputState = kStatusTextInputAborted; … … 968 927 memset(tempString, 0, SAVE_TITLE_SIZE); 969 928 ch[1] = 0; 970 929 971 textInputStartRepeat(ascii);972 973 930 switch (ascii) { 974 931 case 13: 975 932 return false; -
backends/sdl/sdl.cpp
132 132 // Enable unicode support if possible 133 133 SDL_EnableUNICODE(1); 134 134 135 SDL_EnableKeyRepeat(kKeyRepeatInitialDelay, kKeyRepeatSustainDelay); 136 135 137 _cksumValid = false; 136 138 #if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) && !defined(DISABLE_SCALERS) 137 139 _mode = GFX_DOUBLESIZE; -
backends/sdl/sdl-common.h
53 53 GFX_DOTMATRIX = 11 54 54 }; 55 55 56 enum { 57 kKeyRepeatInitialDelay = 400, 58 kKeyRepeatSustainDelay = 100 59 }; 56 60 61 57 62 class OSystem_SDL : public OSystem { 58 63 public: 59 64 OSystem_SDL();