Ticket #8532: keyboard-repeat2.diff
File keyboard-repeat2.diff, 14.2 KB (added by , 17 years ago) |
---|
-
gui/newgui.cpp
48 48 49 49 enum { 50 50 kDoubleClickDelay = 500, // milliseconds 51 kCursorAnimateDelay = 250, 52 kKeyRepeatInitialDelay = 400, 53 kKeyRepeatSustainDelay = 100 51 kCursorAnimateDelay = 250 54 52 }; 55 53 56 54 // HACK. FIXME. This doesn't belong here. But otherwise it creates compilation problems … … 92 90 // Clear the cursor 93 91 memset(_cursor, 0xFF, sizeof(_cursor)); 94 92 95 // Reset key repeat96 _currentKeyDown.keycode = 0;97 98 93 #ifndef DISABLE_FANCY_THEMES 99 94 ConfMan.registerDefault("gui_theme", "default"); 100 95 Common::String style(ConfMan.get("gui_theme")); … … 208 203 209 204 switch (event.type) { 210 205 case OSystem::EVENT_KEYDOWN: 211 #if !defined(PALMOS_MODE)212 // init continuous event stream213 // not done on PalmOS because keyboard is emulated and keyup is not generated214 _currentKeyDown.ascii = event.kbd.ascii;215 _currentKeyDown.keycode = event.kbd.keycode;216 _currentKeyDown.flags = event.kbd.flags;217 _keyRepeatTime = time + kKeyRepeatInitialDelay;218 #endif219 206 activeDialog->handleKeyDown(event.kbd.ascii, event.kbd.keycode, event.kbd.flags); 220 207 break; 221 208 case OSystem::EVENT_KEYUP: 222 209 activeDialog->handleKeyUp(event.kbd.ascii, event.kbd.keycode, event.kbd.flags); 223 if (event.kbd.keycode == _currentKeyDown.keycode)224 // only stop firing events if it's the current key225 _currentKeyDown.keycode = 0;226 210 break; 227 211 case OSystem::EVENT_MOUSEMOVE: 228 212 activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); … … 272 256 } 273 257 } 274 258 275 // check if event should be sent again (keydown)276 if (_currentKeyDown.keycode != 0 && activeDialog == _dialogStack.top()) {277 if (_keyRepeatTime < time) {278 // fire event279 activeDialog->handleKeyDown(_currentKeyDown.ascii, _currentKeyDown.keycode, _currentKeyDown.flags);280 _keyRepeatTime = time + kKeyRepeatSustainDelay;281 }282 }283 284 259 // Delay for a moment 285 260 _system->delayMillis(10); 286 261 } … … 298 273 #pragma mark - 299 274 300 275 void NewGui::saveState() { 301 // Backup old cursor302 _currentKeyDown.keycode = 0;303 276 _lastClick.x = _lastClick.y = 0; 304 277 _lastClick.time = 0; 305 278 _lastClick.count = 0; -
gui/newgui.h
94 94 95 95 bool _stateIsSaved; 96 96 97 // for continuous events (keyDown)98 struct {99 uint16 ascii;100 byte flags;101 int keycode;102 } _currentKeyDown;103 uint32 _keyRepeatTime;104 105 97 // position and time of last mouse click (used to detect double clicks) 106 98 struct { 107 99 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) { … … 1051 1044 _keyPressed = 8; 1052 1045 else 1053 1046 _keyPressed = (byte)event.kbd.ascii; 1054 _keyRepeatTime = now + kKeyRepeatInitialDelay;1055 _keyRepeat = _keyPressed;1056 1047 // we skip the rest of the delay and return immediately 1057 1048 // to handle keyboard input 1058 1049 return; 1059 case OSystem::EVENT_KEYUP:1060 _keyRepeatTime = 0;1061 _keyRepeat = 0;1062 break;1063 1050 case OSystem::EVENT_MOUSEMOVE: 1064 1051 _mouseX = event.mouse.x; 1065 1052 _mouseY = event.mouse.y; … … 1091 1078 break; 1092 1079 } 1093 1080 } 1094 if (_keyRepeatTime && now > _keyRepeatTime) {1095 _keyRepeatTime += kKeyRepeatSustainDelay;1096 _keyPressed = _keyRepeat;1097 }1098 1081 1099 1082 _system->updateScreen(); 1100 1083 _system->delayMillis(10); -
engines/sword2/sword2.cpp
147 147 _debugger = NULL; 148 148 149 149 _keyboardEvent.pending = false; 150 _keyboardEvent.repeat = 0;151 150 _mouseEvent.pending = false; 152 151 153 152 _wantSfxDebug = false; … … 504 503 505 504 void Sword2Engine::clearInputEvents() { 506 505 _keyboardEvent.pending = false; 507 _keyboardEvent.repeat = 0;508 506 _mouseEvent.pending = false; 509 507 } 510 508 … … 515 513 void Sword2Engine::parseInputEvents() { 516 514 OSystem::Event event; 517 515 518 uint32 now = _system->getMillis();519 520 516 while (_system->pollEvent(event)) { 521 517 switch (event.type) { 522 518 case OSystem::EVENT_KEYDOWN: 523 519 if (!(_inputEventFilter & RD_KEYDOWN)) { 524 520 _keyboardEvent.pending = true; 525 _keyboardEvent.repeat = now + 400;526 521 _keyboardEvent.ascii = event.kbd.ascii; 527 522 _keyboardEvent.keycode = event.kbd.keycode; 528 523 _keyboardEvent.modifiers = event.kbd.flags; 529 524 } 530 525 break; 531 case OSystem::EVENT_KEYUP:532 _keyboardEvent.repeat = 0;533 break;534 526 case OSystem::EVENT_MOUSEMOVE: 535 527 if (!(_inputEventFilter & RD_KEYDOWN)) { 536 528 _mouse->setPos(event.mouse.x, event.mouse.y - MENUDEEP); … … 579 571 break; 580 572 } 581 573 } 582 583 // Handle keyboard auto-repeat584 if (!_keyboardEvent.pending && _keyboardEvent.repeat && now >= _keyboardEvent.repeat) {585 _keyboardEvent.pending = true;586 _keyboardEvent.repeat = now + 100;587 }588 574 } 589 575 590 576 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
92 92 _scriptMain = 0; 93 93 _scriptClickData = 0; 94 94 _scriptClick = 0; 95 _keyPressed = 0; 95 96 _characterList = 0; 96 97 _movFacingTable = 0; 97 98 memset(_shapes, 0, sizeof(_shapes)); -
engines/kyra/gui.cpp
616 616 calcCoords(_menu[i]); 617 617 618 618 _menuRestoreScreen = true; 619 _keyboardEvent.pending = 0;620 _keyboardEvent.repeat = 0;621 619 _mousePressFlag = false; 622 620 623 621 _toplevelMenu = 0; … … 834 832 _mouseWheel = 1; 835 833 break; 836 834 case OSystem::EVENT_KEYDOWN: 837 _keyboardEvent.pending = true; 838 _keyboardEvent.repeat = now + 400; 839 _keyboardEvent.ascii = event.kbd.ascii; 835 _keyPressed = event.kbd.ascii; 840 836 break; 841 case OSystem::EVENT_KEYUP:842 _keyboardEvent.repeat = 0;843 break;844 837 default: 845 838 break; 846 839 } … … 851 844 lastScreenUpdate = now; 852 845 } 853 846 854 if (!_keyboardEvent.pending && _keyboardEvent.repeat && now >= _keyboardEvent.repeat) {855 _keyboardEvent.pending = true;856 _keyboardEvent.repeat = now + 100;857 }858 847 _system->delayMillis(3); 859 848 } 860 849 … … 1019 1008 void KyraEngine::gui_updateSavegameString() { 1020 1009 int length; 1021 1010 1022 if (_key boardEvent.pending && _keyboardEvent.ascii) {1011 if (_keyPressed) { 1023 1012 length = strlen(_savegameName); 1024 1013 1025 if (_key boardEvent.ascii > 31 && _keyboardEvent.ascii< 127) {1014 if (_keyPressed > 31 && _keyPressed < 127) { 1026 1015 if (length < 31) { 1027 _savegameName[length] = _key boardEvent.ascii;1016 _savegameName[length] = _keyPressed; 1028 1017 _savegameName[length+1] = 0; 1029 1018 gui_redrawTextfield(); 1030 1019 } 1031 } else if (_key boardEvent.ascii == 8 ||_keyboardEvent.ascii== 127) {1020 } else if (_keyPressed == 8 || _keyPressed == 127) { 1032 1021 if (length > 0) { 1033 1022 _savegameName[length-1] = 0; 1034 1023 gui_redrawTextfield(); 1035 1024 } 1036 } else if (_key boardEvent.ascii== 13) {1025 } else if (_keyPressed == 13) { 1037 1026 _displaySubMenu = false; 1038 1027 } 1039 1028 } 1040 1029 1041 _key boardEvent.pending = false;1030 _keyPressed = 0; 1042 1031 } 1043 1032 1044 1033 int KyraEngine::gui_saveGame(Button *button) { -
engines/kyra/kyra.h
232 232 MenuItem item[6]; 233 233 }; 234 234 235 struct KeyboardEvent {236 bool pending;237 uint32 repeat;238 uint8 ascii;239 };240 241 235 class KyraEngine : public Engine { 242 236 friend class MusicPlayer; 243 237 friend class Debugger; … … 836 830 int _gameToLoad; 837 831 char _savegameName[31]; 838 832 const char *_specialSavegameString; 839 KeyboardEvent _keyboardEvent;833 uint8 _keyPressed; 840 834 841 835 struct KyragemState { 842 836 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/platform/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/platform/sdl/sdl-common.h
54 54 GFX_DOTMATRIX = 11 55 55 }; 56 56 57 enum { 58 kKeyRepeatInitialDelay = 400, 59 kKeyRepeatSustainDelay = 100 60 }; 57 61 58 62 class OSystem_SDL : public OSystem { 59 63 public: