# HG changeset patch # User Xeli # Date 1335201736 -7200 # Node ID 4889c2b779b416aa1f9dda7d818618dc364203e6 # Parent 50243b6ffab5ad039bc33c26a1349774bd7c3688 - change uKeys to be event based rather than polling - missing engine+frontend exit - missing controller support - needs testing on different platforms and keyboards diff -r 50243b6ffab5 -r 4889c2b779b4 hedgewars/SDLh.pas --- a/hedgewars/SDLh.pas Mon Apr 23 13:22:30 2012 +0000 +++ b/hedgewars/SDLh.pas Mon Apr 23 19:22:16 2012 +0200 @@ -111,6 +111,10 @@ SDL_ALLEVENTS = $FFFFFFFF; SDL_APPINPUTFOCUS = $02; + + SDL_BUTTON_LEFT = 1; + SDL_BUTTON_MIDDLE = 2; + SDL_BUTTON_RIGHT = 3; SDL_BUTTON_WHEELUP = 4; SDL_BUTTON_WHEELDOWN = 5; @@ -705,7 +709,7 @@ {$IFDEF SDL13} TSDL_KeySym = record scancode: LongInt; - sym: LongInt; + sym: LongWord; modifier: Word; unicode: LongWord; end; @@ -809,9 +813,9 @@ TSDL_KeyboardEvent = record {$IFDEF SDL13} type_: LongWord; - timestamp: LongWord; +// timestamp: LongWord; windowID: LongWord; - state, repeat_, padding2, padding3: Byte; + state, repeat_ {*,padding2, padding3*}: Byte; {$ELSE} type_, which, state: Byte; {$ENDIF} @@ -836,7 +840,7 @@ type_: LongWord; timestamp: LongWord; windowID: LongWord; - buttonm, state, padding1, padding2: Byte; + button, state, padding1, padding2: Byte; x, y: LongInt; {$ELSE} type_, which, button, state: Byte; @@ -1183,6 +1187,8 @@ function SDL_GetMouseState(x, y: PLongInt): Byte; cdecl; external SDLLibName; function SDL_GetKeyName(key: LongWord): PChar; cdecl; external SDLLibName; function SDL_GetScancodeName(key: LongWord): PChar; cdecl; external SDLLibName; +function SDL_GetKeyFromScancode(key: LongWord): LongInt; cdecl; external SDLLibName; + procedure SDL_PumpEvents; cdecl; external SDLLibName; function SDL_PollEvent(event: PSDL_Event): LongInt; cdecl; external SDLLibName; diff -r 50243b6ffab5 -r 4889c2b779b4 hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Mon Apr 23 13:22:30 2012 +0000 +++ b/hedgewars/hwengine.pas Mon Apr 23 19:22:16 2012 +0200 @@ -86,7 +86,7 @@ gsConfirm, gsGame: begin DrawWorld(Lag); // never place between ProcessKbd and DoGameTick - bugs due to /put cmd and isCursorVisible - ProcessKbd; +// ProcessKbd; DoGameTick(Lag); ProcessVisualGears(Lag); end; @@ -168,7 +168,12 @@ SDL_KEYDOWN: if GameState = gsChat then // sdl on iphone supports only ashii keyboards and the unicode field is deprecated in sdl 1.3 - KeyPressChat(event.key.keysym.sym); + KeyPressChat(SDL_GetKeyFromScancode(event.key.keysym.sym))//TODO correct for keymodifiers + else + ProcessKey(event.key); + SDL_KEYUP: + if GameState <> gsChat then + ProcessKey(event.key); SDL_WINDOWEVENT: if event.window.event = SDL_WINDOWEVENT_SHOWN then @@ -207,15 +212,17 @@ {$ELSE} SDL_KEYDOWN: if GameState = gsChat then - KeyPressChat(event.key.keysym.unicode); + KeyPressChat(event.key.keysym.unicode) + else + ProcessKey(event.key); + SDL_KEYUP: + if GameState <> gsChat then + ProcessKey(event.key); SDL_MOUSEBUTTONDOWN: - if event.button.button = SDL_BUTTON_WHEELDOWN then - wheelDown:= true; - + ProcessMouse(event.button, true); SDL_MOUSEBUTTONUP: - if event.button.button = SDL_BUTTON_WHEELUP then - wheelUp:= true; + ProcessMouse(event.button, false); SDL_ACTIVEEVENT: if (event.active.state and SDL_APPINPUTFOCUS) <> 0 then diff -r 50243b6ffab5 -r 4889c2b779b4 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Mon Apr 23 13:22:30 2012 +0000 +++ b/hedgewars/uConsts.pas Mon Apr 23 19:22:16 2012 +0200 @@ -155,7 +155,12 @@ cShotgunRadius = 22; cBlowTorchC = 6; +{$IFDEF SDL13} + cKeyMaxIndex = SDL_NUM_SCANCODES; +{$ELSE} cKeyMaxIndex = 1023; +{$ENDIF} + // do not change this value cDefaultZoomLevel = 2.0; @@ -261,6 +266,7 @@ ammoprop_Utility = $00001000; ammoprop_Effect = $00002000; ammoprop_SetBounce = $00004000; + ammoprop_NeedUpDown = $00008000;//Used by ammoprop_NoRoundEnd = $10000000; AMMO_INFINITE = 100; diff -r 50243b6ffab5 -r 4889c2b779b4 hedgewars/uKeys.pas --- a/hedgewars/uKeys.pas Mon Apr 23 13:22:30 2012 +0000 +++ b/hedgewars/uKeys.pas Mon Apr 23 19:22:16 2012 +0200 @@ -27,6 +27,8 @@ function KeyNameToCode(name: shortstring): word; procedure ProcessKbd; +procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean); +procedure ProcessKey(event: TSDL_KeyboardEvent); procedure ResetKbd; procedure FreezeEnterKey; procedure InitKbdKeyTable; @@ -40,10 +42,6 @@ procedure ControllerHatEvent(joy, hat, value: Byte); procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean); -{$IFDEF MOBILE} -procedure setTouchWidgetStates; -{$ENDIF} - implementation uses uConsole, uCommands, uMisc, uVariables, uConsts, uUtils, uDebug; @@ -53,53 +51,28 @@ function KeyNameToCode(name: shortstring): word; var code: Word; begin + name:= LowerCase(name); code:= cKeyMaxIndex; while (code > 0) and (KeyNames[code] <> name) do dec(code); KeyNameToCode:= code; end; - procedure ProcessKbd; var i, j, k: LongInt; s: shortstring; Trusted: boolean; pkbd: PByteArray; begin -hideAmmoMenu:= false; -Trusted:= (CurrentTeam <> nil) - and (not CurrentTeam^.ExtDriven) - and (CurrentHedgehog^.BotLevel = 0); // move cursor/camera // TODO: Scale on screen dimensions and/or axis value (game controller)? +//TODO what is this for? movecursor(5 * CursorMovementX, 5 * CursorMovementY); -pkbd:= SDL_GetKeyState(@j); -for i:= 6 to pred(j) do // first 6 will be overwritten - tkbdn[i]:= pkbd^[i]; - -k:= SDL_GetMouseState(nil, nil); -// mouse buttons -{$IFDEF DARWIN} -tkbdn[1]:= ((k and 1) and not (tkbdn[306] or tkbdn[305])); -tkbdn[3]:= ((k and 1) and (tkbdn[306] or tkbdn[305])) or (k and 4); -{$ELSE} -tkbdn[1]:= (k and 1); -tkbdn[3]:= ((k shr 2) and 1); -{$ENDIF} -tkbdn[2]:= ((k shr 1) and 1); - -// mouse wheels -tkbdn[4]:= ord(wheelDown); -tkbdn[5]:= ord(wheelUp); -wheelUp:= false; -wheelDown:= false; - -{$IFDEF MOBILE} -setTouchWidgetStates(); -{$ENDIF} {$IFNDEF MOBILE} + +//TODO reimplement // Controller(s) k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it for j:= 0 to Pred(ControllerNumControllers) do @@ -132,6 +105,8 @@ end; {$ENDIF} + +//TODO reimplement this // ctrl/cmd + q to close engine and frontend {$IFDEF DARWIN} if ((tkbdn[KeyNameToCode('left_meta')] = 1) or (tkbdn[KeyNameToCode('right_meta')] = 1)) then @@ -141,28 +116,62 @@ begin if tkbdn[KeyNameToCode('q')] = 1 then ParseCommand ('halt', true) end; +end; -// now process strokes -for i:= 0 to cKeyMaxIndex do -if CurrentBinds[i][0] <> #0 then + +procedure ProcessKey(code: LongInt; KeyDown: boolean); +var + Trusted: boolean; + s : string; +begin +hideAmmoMenu:= false; +Trusted:= (CurrentTeam <> nil) + and (not CurrentTeam^.ExtDriven) + and (CurrentHedgehog^.BotLevel = 0); + +tkbdn[code]:= ord(KeyDown); + +if CurrentBinds[code][0] <> #0 then begin - if (i > 3) and (tkbdn[i] <> 0) and not ((CurrentBinds[i] = 'put') or (CurrentBinds[i] = 'ammomenu') or (CurrentBinds[i] = '+cur_u') or (CurrentBinds[i] = '+cur_d') or (CurrentBinds[i] = '+cur_l') or (CurrentBinds[i] = '+cur_r')) then hideAmmoMenu:= true; - if (tkbd[i] = 0) and (tkbdn[i] <> 0) then + if (code > 3) and (tkbdn[code] <> 0) and not ((CurrentBinds[code] = 'put') or (CurrentBinds[code] = 'ammomenu') or (CurrentBinds[code] = '+cur_u') or (CurrentBinds[code] = '+cur_d') or (CurrentBinds[code] = '+cur_l') or (CurrentBinds[code] = '+cur_r')) then hideAmmoMenu:= true; + if (tkbd[code] = 0) and (tkbdn[code] <> 0) then begin - ParseCommand(CurrentBinds[i], Trusted); + ParseCommand(CurrentBinds[code], Trusted); if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then ParseCommand('gencmd R', true) end - else if (CurrentBinds[i][1] = '+') and (tkbdn[i] = 0) and (tkbd[i] <> 0) then + else if (CurrentBinds[code][1] = '+') and (tkbdn[code] = 0) and (tkbd[code] <> 0) then begin - s:= CurrentBinds[i]; + s:= CurrentBinds[code]; s[1]:= '-'; ParseCommand(s, Trusted); if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then ParseCommand('gencmd R', true) end; - tkbd[i]:= tkbdn[i] + tkbd[code]:= tkbdn[code] end + +end; + +procedure ProcessKey(event: TSDL_KeyboardEvent); +begin + ProcessKey(event.keysym.sym, event.type_ = SDL_KEYDOWN); +end; + +procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean); +begin +case event.button of + SDL_BUTTON_LEFT: + ProcessKey(KeyNameToCode('mousel'), ButtonDown); + SDL_BUTTON_MIDDLE: + ProcessKey(KeyNameToCode('mousem'), ButtonDown); + SDL_BUTTON_RIGHT: + ProcessKey(KeyNameToCode('mouser'), ButtonDown); + SDL_BUTTON_WHEELDOWN: + ProcessKey(KeyNameToCode('wheeldown'), ButtonDown); + SDL_BUTTON_WHEELUP: + ProcessKey(KeyNameToCode('wheelup'), ButtonDown); + end; end; procedure ResetKbd; @@ -174,31 +183,11 @@ k:= SDL_GetMouseState(nil, nil); pkbd:=SDL_GetKeyState(@j); -TryDo(j < cKeyMaxIndex, 'SDL keys number is more than expected (' + IntToStr(j) + ')', true); +//TryDo(j < cKeyMaxIndex, 'SDL keys number is more than expected (' + IntToStr(j) + ')', true); for i:= 1 to pred(j) do tkbdn[i]:= pkbd^[i]; -// mouse buttons -{$IFDEF DARWIN} -tkbdn[1]:= ((k and 1) and not (tkbdn[306] or tkbdn[305])); -tkbdn[3]:= ((k and 1) and (tkbdn[306] or tkbdn[305])) or (k and 4); -{$ELSE} -tkbdn[1]:= (k and 1); -tkbdn[3]:= ((k shr 2) and 1); -{$ENDIF} -tkbdn[2]:= ((k shr 1) and 1); - -// mouse wheels -tkbdn[4]:= ord(wheelDown); -tkbdn[5]:= ord(wheelUp); -wheelUp:= false; -wheelDown:= false; - -{$IFDEF MOBILE} -setTouchWidgetStates(); -{$ENDIF} - {$IFNDEF MOBILE} // Controller(s) k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it @@ -241,6 +230,7 @@ var i, j, k, t: LongInt; s: string[15]; begin +//TODO in sdl13 this overrides some values (A and B) change indices to some other values at the back perhaps? KeyNames[1]:= 'mousel'; KeyNames[2]:= 'mousem'; KeyNames[3]:= 'mouser'; @@ -249,15 +239,19 @@ for i:= 6 to cKeyMaxIndex do begin +{$IFDEF SDL13} + s:= shortstring(SDL_GetScancodeName(i)); +{$ELSE} s:= shortstring(sdl_getkeyname(i)); - //WriteToConsole(IntToStr(i) + ': ' + s); +{$ENDIF} + WriteToConsole(IntToStr(i) + ': ' + s + ' ' + IntToStr(cKeyMaxIndex)); if s = 'unknown key' then KeyNames[i]:= '' else begin for t:= 1 to Length(s) do if s[t] = ' ' then s[t]:= '_'; - KeyNames[i]:= s + KeyNames[i]:= LowerCase(s) end; end; @@ -290,9 +284,9 @@ end; end; -DefaultBinds[ 27]:= 'quit'; -DefaultBinds[ 96]:= 'history'; -DefaultBinds[127]:= 'rotmask'; +DefaultBinds[KeyNameToCode('escape')]:= 'quit'; +DefaultBinds[KeyNameToCode('grave')]:= 'history'; +DefaultBinds[KeyNameToCode('delete')]:= 'rotmask'; //numpad //DefaultBinds[265]:= '+volup'; @@ -314,27 +308,17 @@ DefaultBinds[KeyNameToCode('f12')]:= 'fullscr'; -DefaultBinds[ 1]:= '/put'; -DefaultBinds[ 3]:= 'ammomenu'; -DefaultBinds[ 8]:= 'hjump'; -DefaultBinds[ 9]:= 'switch'; -DefaultBinds[13]:= 'ljump'; -DefaultBinds[32]:= '+attack'; -{$IFDEF MOBILE} -DefaultBinds[23]:= '+up'; -DefaultBinds[24]:= '+down'; -DefaultBinds[25]:= '+left'; -DefaultBinds[26]:= '+right'; -DefaultBinds[27]:= '+precise'; -DefaultBinds[44]:= 'chat'; -DefaultBinds[55]:= 'pause'; -{$ELSE} +DefaultBinds[KeyNameToCode('mousel')]:= '/put'; +DefaultBinds[KeyNameToCode('mouser')]:= 'ammomenu'; +DefaultBinds[KeyNameToCode('backspace')]:= 'hjump'; +DefaultBinds[KeyNameToCode('tab')]:= 'switch'; +DefaultBinds[KeyNameToCode('return')]:= 'ljump'; +DefaultBinds[KeyNameToCode('space')]:= '+attack'; DefaultBinds[KeyNameToCode('up')]:= '+up'; DefaultBinds[KeyNameToCode('down')]:= '+down'; DefaultBinds[KeyNameToCode('left')]:= '+left'; DefaultBinds[KeyNameToCode('right')]:= '+right'; DefaultBinds[KeyNameToCode('left_shift')]:= '+precise'; -{$ENDIF} for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+IntToStr(i); for i:= 1 to 5 do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i); @@ -357,41 +341,6 @@ CurrentBinds:= DefaultBinds; end; -{$IFDEF MOBILE} -procedure setTouchWidgetStates; -begin - tkbdn[ 1]:= ord(leftClick); - tkbdn[ 2]:= ord(middleClick); - tkbdn[ 3]:= ord(rightClick); - - tkbdn[23]:= ord(upKey); - tkbdn[24]:= ord(downKey); - tkbdn[25]:= ord(leftKey); - tkbdn[26]:= ord(rightKey); - tkbdn[27]:= ord(preciseKey); - - tkbdn[ 8]:= ord(backspaceKey); - tkbdn[ 9]:= ord(tabKey); - tkbdn[13]:= ord(enterKey); - tkbdn[32]:= ord(spaceKey); - - tkbdn[44]:= ord(chatAction); - tkbdn[55]:= ord(pauseAction); - - // set to false the keys that only need one stoke - leftClick:= false; - middleClick:= false; - rightClick:= false; - - tabKey:= false; - enterKey:= false; - backspaceKey:= false; - - chatAction:= false; - pauseAction:= false; -end; -{$ENDIF} - procedure FreezeEnterKey; begin tkbd[3]:= 1;