- change uKeys to be event based rather than polling
authorXeli
Mon, 23 Apr 2012 19:22:16 +0200
changeset 6917 4889c2b779b4
parent 6916 50243b6ffab5
child 6918 13d6cce2056c
- change uKeys to be event based rather than polling - missing engine+frontend exit - missing controller support - needs testing on different platforms and keyboards
hedgewars/SDLh.pas
hedgewars/hwengine.pas
hedgewars/uConsts.pas
hedgewars/uKeys.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;
--- 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
--- 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;
--- 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;