hedgewars/uKeys.pas
changeset 6917 4889c2b779b4
parent 6909 2b9c1228d516
child 6942 11f52445e8cd
equal deleted inserted replaced
6916:50243b6ffab5 6917:4889c2b779b4
    25 procedure initModule;
    25 procedure initModule;
    26 procedure freeModule;
    26 procedure freeModule;
    27 
    27 
    28 function  KeyNameToCode(name: shortstring): word;
    28 function  KeyNameToCode(name: shortstring): word;
    29 procedure ProcessKbd;
    29 procedure ProcessKbd;
       
    30 procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean);
       
    31 procedure ProcessKey(event: TSDL_KeyboardEvent);
    30 procedure ResetKbd;
    32 procedure ResetKbd;
    31 procedure FreezeEnterKey;
    33 procedure FreezeEnterKey;
    32 procedure InitKbdKeyTable;
    34 procedure InitKbdKeyTable;
    33 
    35 
    34 procedure SetBinds(var binds: TBinds);
    36 procedure SetBinds(var binds: TBinds);
    38 procedure ControllerClose;
    40 procedure ControllerClose;
    39 procedure ControllerAxisEvent(joy, axis: Byte; value: Integer);
    41 procedure ControllerAxisEvent(joy, axis: Byte; value: Integer);
    40 procedure ControllerHatEvent(joy, hat, value: Byte);
    42 procedure ControllerHatEvent(joy, hat, value: Byte);
    41 procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean);
    43 procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean);
    42 
    44 
    43 {$IFDEF MOBILE}
       
    44 procedure setTouchWidgetStates;
       
    45 {$ENDIF}
       
    46 
       
    47 implementation
    45 implementation
    48 uses uConsole, uCommands, uMisc, uVariables, uConsts, uUtils, uDebug;
    46 uses uConsole, uCommands, uMisc, uVariables, uConsts, uUtils, uDebug;
    49 
    47 
    50 var tkbd, tkbdn: TKeyboardState;
    48 var tkbd, tkbdn: TKeyboardState;
    51     KeyNames: array [0..cKeyMaxIndex] of string[15];
    49     KeyNames: array [0..cKeyMaxIndex] of string[15];
    52 
    50 
    53 function KeyNameToCode(name: shortstring): word;
    51 function KeyNameToCode(name: shortstring): word;
    54 var code: Word;
    52 var code: Word;
    55 begin
    53 begin
       
    54     name:= LowerCase(name);
    56     code:= cKeyMaxIndex;
    55     code:= cKeyMaxIndex;
    57     while (code > 0) and (KeyNames[code] <> name) do dec(code);
    56     while (code > 0) and (KeyNames[code] <> name) do dec(code);
    58     KeyNameToCode:= code;
    57     KeyNameToCode:= code;
    59 end;
    58 end;
    60 
       
    61 
    59 
    62 procedure ProcessKbd;
    60 procedure ProcessKbd;
    63 var  i, j, k: LongInt;
    61 var  i, j, k: LongInt;
    64      s: shortstring;
    62      s: shortstring;
    65      Trusted: boolean;
    63      Trusted: boolean;
    66      pkbd: PByteArray;
    64      pkbd: PByteArray;
    67 begin
    65 begin
    68 hideAmmoMenu:= false;
       
    69 Trusted:= (CurrentTeam <> nil)
       
    70           and (not CurrentTeam^.ExtDriven)
       
    71           and (CurrentHedgehog^.BotLevel = 0);
       
    72 
    66 
    73 // move cursor/camera
    67 // move cursor/camera
    74 // TODO: Scale on screen dimensions and/or axis value (game controller)?
    68 // TODO: Scale on screen dimensions and/or axis value (game controller)?
       
    69 //TODO what is this for?
    75 movecursor(5 * CursorMovementX, 5 * CursorMovementY);
    70 movecursor(5 * CursorMovementX, 5 * CursorMovementY);
    76 
    71 
    77 pkbd:= SDL_GetKeyState(@j);
       
    78 for i:= 6 to pred(j) do // first 6 will be overwritten
       
    79     tkbdn[i]:= pkbd^[i];
       
    80 
       
    81 k:= SDL_GetMouseState(nil, nil);
       
    82 // mouse buttons
       
    83 {$IFDEF DARWIN}
       
    84 tkbdn[1]:= ((k and 1) and not (tkbdn[306] or tkbdn[305]));
       
    85 tkbdn[3]:= ((k and 1) and (tkbdn[306] or tkbdn[305])) or (k and 4);
       
    86 {$ELSE}
       
    87 tkbdn[1]:= (k and 1);
       
    88 tkbdn[3]:= ((k shr 2) and 1);
       
    89 {$ENDIF}
       
    90 tkbdn[2]:= ((k shr 1) and 1);
       
    91 
       
    92 // mouse wheels
       
    93 tkbdn[4]:= ord(wheelDown);
       
    94 tkbdn[5]:= ord(wheelUp);
       
    95 wheelUp:= false;
       
    96 wheelDown:= false;
       
    97 
       
    98 {$IFDEF MOBILE}
       
    99 setTouchWidgetStates();
       
   100 {$ENDIF}
       
   101 
    72 
   102 {$IFNDEF MOBILE}
    73 {$IFNDEF MOBILE}
       
    74 
       
    75 //TODO reimplement
   103 // Controller(s)
    76 // Controller(s)
   104 k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it
    77 k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it
   105 for j:= 0 to Pred(ControllerNumControllers) do
    78 for j:= 0 to Pred(ControllerNumControllers) do
   106     begin
    79     begin
   107     for i:= 0 to Pred(ControllerNumAxes[j]) do
    80     for i:= 0 to Pred(ControllerNumAxes[j]) do
   130         inc(k, 1);
   103         inc(k, 1);
   131         end;
   104         end;
   132     end;
   105     end;
   133 {$ENDIF}
   106 {$ENDIF}
   134 
   107 
       
   108 
       
   109 //TODO reimplement this
   135 // ctrl/cmd + q to close engine and frontend
   110 // ctrl/cmd + q to close engine and frontend
   136 {$IFDEF DARWIN}
   111 {$IFDEF DARWIN}
   137     if ((tkbdn[KeyNameToCode('left_meta')] = 1) or (tkbdn[KeyNameToCode('right_meta')] = 1)) then
   112     if ((tkbdn[KeyNameToCode('left_meta')] = 1) or (tkbdn[KeyNameToCode('right_meta')] = 1)) then
   138 {$ELSE}
   113 {$ELSE}
   139     if ((tkbdn[KeyNameToCode('left_ctrl')] = 1) or (tkbdn[KeyNameToCode('right_ctrl')] = 1)) then
   114     if ((tkbdn[KeyNameToCode('left_ctrl')] = 1) or (tkbdn[KeyNameToCode('right_ctrl')] = 1)) then
   140 {$ENDIF}
   115 {$ENDIF}
   141     begin
   116     begin
   142         if tkbdn[KeyNameToCode('q')] = 1 then ParseCommand ('halt', true)
   117         if tkbdn[KeyNameToCode('q')] = 1 then ParseCommand ('halt', true)
   143     end;
   118     end;
   144 
   119 end;
   145 // now process strokes
   120 
   146 for i:= 0 to cKeyMaxIndex do
   121 
   147 if CurrentBinds[i][0] <> #0 then
   122 procedure ProcessKey(code: LongInt; KeyDown: boolean);
   148     begin
   123 var
   149     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;
   124     Trusted: boolean;
   150     if (tkbd[i] = 0) and (tkbdn[i] <> 0) then
   125     s      : string;
   151         begin
   126 begin
   152         ParseCommand(CurrentBinds[i], Trusted);
   127 hideAmmoMenu:= false;
       
   128 Trusted:= (CurrentTeam <> nil)
       
   129           and (not CurrentTeam^.ExtDriven)
       
   130           and (CurrentHedgehog^.BotLevel = 0);
       
   131 
       
   132 tkbdn[code]:= ord(KeyDown);
       
   133 
       
   134 if CurrentBinds[code][0] <> #0 then
       
   135     begin
       
   136     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;
       
   137     if (tkbd[code] = 0) and (tkbdn[code] <> 0) then
       
   138         begin
       
   139         ParseCommand(CurrentBinds[code], Trusted);
   153         if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then
   140         if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then
   154             ParseCommand('gencmd R', true)
   141             ParseCommand('gencmd R', true)
   155         end
   142         end
   156     else if (CurrentBinds[i][1] = '+') and (tkbdn[i] = 0) and (tkbd[i] <> 0) then
   143     else if (CurrentBinds[code][1] = '+') and (tkbdn[code] = 0) and (tkbd[code] <> 0) then
   157         begin
   144         begin
   158         s:= CurrentBinds[i];
   145         s:= CurrentBinds[code];
   159         s[1]:= '-';
   146         s[1]:= '-';
   160         ParseCommand(s, Trusted);
   147         ParseCommand(s, Trusted);
   161         if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then
   148         if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then
   162             ParseCommand('gencmd R', true)
   149             ParseCommand('gencmd R', true)
   163         end;
   150         end;
   164     tkbd[i]:= tkbdn[i]
   151     tkbd[code]:= tkbdn[code]
   165     end
   152     end
       
   153 
       
   154 end;
       
   155 
       
   156 procedure ProcessKey(event: TSDL_KeyboardEvent); 
       
   157 begin
       
   158     ProcessKey(event.keysym.sym, event.type_ = SDL_KEYDOWN);
       
   159 end;
       
   160 
       
   161 procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean);
       
   162 begin
       
   163 case event.button of
       
   164     SDL_BUTTON_LEFT:
       
   165         ProcessKey(KeyNameToCode('mousel'), ButtonDown);
       
   166     SDL_BUTTON_MIDDLE:
       
   167         ProcessKey(KeyNameToCode('mousem'), ButtonDown);
       
   168     SDL_BUTTON_RIGHT:
       
   169         ProcessKey(KeyNameToCode('mouser'), ButtonDown);
       
   170     SDL_BUTTON_WHEELDOWN:
       
   171         ProcessKey(KeyNameToCode('wheeldown'), ButtonDown);
       
   172     SDL_BUTTON_WHEELUP:
       
   173         ProcessKey(KeyNameToCode('wheelup'), ButtonDown);
       
   174     end;
   166 end;
   175 end;
   167 
   176 
   168 procedure ResetKbd;
   177 procedure ResetKbd;
   169 var j, k, t: LongInt;
   178 var j, k, t: LongInt;
   170     i: LongInt;
   179     i: LongInt;
   172 begin
   181 begin
   173 
   182 
   174 k:= SDL_GetMouseState(nil, nil);
   183 k:= SDL_GetMouseState(nil, nil);
   175 pkbd:=SDL_GetKeyState(@j);
   184 pkbd:=SDL_GetKeyState(@j);
   176 
   185 
   177 TryDo(j < cKeyMaxIndex, 'SDL keys number is more than expected (' + IntToStr(j) + ')', true);
   186 //TryDo(j < cKeyMaxIndex, 'SDL keys number is more than expected (' + IntToStr(j) + ')', true);
   178 
   187 
   179 for i:= 1 to pred(j) do
   188 for i:= 1 to pred(j) do
   180     tkbdn[i]:= pkbd^[i];
   189     tkbdn[i]:= pkbd^[i];
   181 
       
   182 // mouse buttons
       
   183 {$IFDEF DARWIN}
       
   184 tkbdn[1]:= ((k and 1) and not (tkbdn[306] or tkbdn[305]));
       
   185 tkbdn[3]:= ((k and 1) and (tkbdn[306] or tkbdn[305])) or (k and 4);
       
   186 {$ELSE}
       
   187 tkbdn[1]:= (k and 1);
       
   188 tkbdn[3]:= ((k shr 2) and 1);
       
   189 {$ENDIF}
       
   190 tkbdn[2]:= ((k shr 1) and 1);
       
   191 
       
   192 // mouse wheels
       
   193 tkbdn[4]:= ord(wheelDown);
       
   194 tkbdn[5]:= ord(wheelUp);
       
   195 wheelUp:= false;
       
   196 wheelDown:= false;
       
   197 
       
   198 {$IFDEF MOBILE}
       
   199 setTouchWidgetStates();
       
   200 {$ENDIF}
       
   201 
   190 
   202 {$IFNDEF MOBILE}
   191 {$IFNDEF MOBILE}
   203 // Controller(s)
   192 // Controller(s)
   204 k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it
   193 k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it
   205 for j:= 0 to Pred(ControllerNumControllers) do
   194 for j:= 0 to Pred(ControllerNumControllers) do
   239 
   228 
   240 procedure InitKbdKeyTable;
   229 procedure InitKbdKeyTable;
   241 var i, j, k, t: LongInt;
   230 var i, j, k, t: LongInt;
   242     s: string[15];
   231     s: string[15];
   243 begin
   232 begin
       
   233 //TODO in sdl13 this overrides some values (A and B) change indices to some other values at the back perhaps?
   244 KeyNames[1]:= 'mousel';
   234 KeyNames[1]:= 'mousel';
   245 KeyNames[2]:= 'mousem';
   235 KeyNames[2]:= 'mousem';
   246 KeyNames[3]:= 'mouser';
   236 KeyNames[3]:= 'mouser';
   247 KeyNames[4]:= 'wheelup';
   237 KeyNames[4]:= 'wheelup';
   248 KeyNames[5]:= 'wheeldown';
   238 KeyNames[5]:= 'wheeldown';
   249 
   239 
   250 for i:= 6 to cKeyMaxIndex do
   240 for i:= 6 to cKeyMaxIndex do
   251     begin
   241     begin
       
   242 {$IFDEF SDL13}
       
   243     s:= shortstring(SDL_GetScancodeName(i));
       
   244 {$ELSE}
   252     s:= shortstring(sdl_getkeyname(i));
   245     s:= shortstring(sdl_getkeyname(i));
   253     //WriteToConsole(IntToStr(i) + ': ' + s);
   246 {$ENDIF}
       
   247     WriteToConsole(IntToStr(i) + ': ' + s + ' ' + IntToStr(cKeyMaxIndex));
   254     if s = 'unknown key' then KeyNames[i]:= ''
   248     if s = 'unknown key' then KeyNames[i]:= ''
   255     else 
   249     else 
   256         begin
   250         begin
   257         for t:= 1 to Length(s) do
   251         for t:= 1 to Length(s) do
   258             if s[t] = ' ' then
   252             if s[t] = ' ' then
   259                 s[t]:= '_';
   253                 s[t]:= '_';
   260         KeyNames[i]:= s
   254         KeyNames[i]:= LowerCase(s)
   261         end;
   255         end;
   262     end;
   256     end;
   263 
   257 
   264 //for i:= 0 to cKeyMaxIndex do writeln(stdout,IntToStr(i) + ': ' + KeyNames[i]);
   258 //for i:= 0 to cKeyMaxIndex do writeln(stdout,IntToStr(i) + ': ' + KeyNames[i]);
   265 
   259 
   288         keynames[k]:= 'j' + IntToStr(j) + 'b' + IntToStr(i);
   282         keynames[k]:= 'j' + IntToStr(j) + 'b' + IntToStr(i);
   289         inc(k, 1);
   283         inc(k, 1);
   290         end;
   284         end;
   291     end;
   285     end;
   292 
   286 
   293 DefaultBinds[ 27]:= 'quit';
   287 DefaultBinds[KeyNameToCode('escape')]:= 'quit';
   294 DefaultBinds[ 96]:= 'history';
   288 DefaultBinds[KeyNameToCode('grave')]:= 'history';
   295 DefaultBinds[127]:= 'rotmask';
   289 DefaultBinds[KeyNameToCode('delete')]:= 'rotmask';
   296 
   290 
   297 //numpad
   291 //numpad
   298 //DefaultBinds[265]:= '+volup';
   292 //DefaultBinds[265]:= '+volup';
   299 //DefaultBinds[256]:= '+voldown';
   293 //DefaultBinds[256]:= '+voldown';
   300 
   294 
   312 DefaultBinds[KeyNameToCode('wheeldown')]:= 'zoomin';
   306 DefaultBinds[KeyNameToCode('wheeldown')]:= 'zoomin';
   313 
   307 
   314 DefaultBinds[KeyNameToCode('f12')]:= 'fullscr';
   308 DefaultBinds[KeyNameToCode('f12')]:= 'fullscr';
   315 
   309 
   316 
   310 
   317 DefaultBinds[ 1]:= '/put';
   311 DefaultBinds[KeyNameToCode('mousel')]:= '/put';
   318 DefaultBinds[ 3]:= 'ammomenu';
   312 DefaultBinds[KeyNameToCode('mouser')]:= 'ammomenu';
   319 DefaultBinds[ 8]:= 'hjump';
   313 DefaultBinds[KeyNameToCode('backspace')]:= 'hjump';
   320 DefaultBinds[ 9]:= 'switch';
   314 DefaultBinds[KeyNameToCode('tab')]:= 'switch';
   321 DefaultBinds[13]:= 'ljump';
   315 DefaultBinds[KeyNameToCode('return')]:= 'ljump';
   322 DefaultBinds[32]:= '+attack';
   316 DefaultBinds[KeyNameToCode('space')]:= '+attack';
   323 {$IFDEF MOBILE}
       
   324 DefaultBinds[23]:= '+up';
       
   325 DefaultBinds[24]:= '+down';
       
   326 DefaultBinds[25]:= '+left';
       
   327 DefaultBinds[26]:= '+right';
       
   328 DefaultBinds[27]:= '+precise';
       
   329 DefaultBinds[44]:= 'chat';
       
   330 DefaultBinds[55]:= 'pause';
       
   331 {$ELSE}
       
   332 DefaultBinds[KeyNameToCode('up')]:= '+up';
   317 DefaultBinds[KeyNameToCode('up')]:= '+up';
   333 DefaultBinds[KeyNameToCode('down')]:= '+down';
   318 DefaultBinds[KeyNameToCode('down')]:= '+down';
   334 DefaultBinds[KeyNameToCode('left')]:= '+left';
   319 DefaultBinds[KeyNameToCode('left')]:= '+left';
   335 DefaultBinds[KeyNameToCode('right')]:= '+right';
   320 DefaultBinds[KeyNameToCode('right')]:= '+right';
   336 DefaultBinds[KeyNameToCode('left_shift')]:= '+precise';
   321 DefaultBinds[KeyNameToCode('left_shift')]:= '+precise';
   337 {$ENDIF}
       
   338 
   322 
   339 for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+IntToStr(i);
   323 for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+IntToStr(i);
   340 for i:= 1 to 5  do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i);
   324 for i:= 1 to 5  do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i);
   341 
   325 
   342 SetDefaultBinds();
   326 SetDefaultBinds();
   354 
   338 
   355 procedure SetDefaultBinds;
   339 procedure SetDefaultBinds;
   356 begin
   340 begin
   357     CurrentBinds:= DefaultBinds;
   341     CurrentBinds:= DefaultBinds;
   358 end;
   342 end;
   359 
       
   360 {$IFDEF MOBILE}
       
   361 procedure setTouchWidgetStates;
       
   362 begin
       
   363     tkbdn[ 1]:= ord(leftClick);
       
   364     tkbdn[ 2]:= ord(middleClick);
       
   365     tkbdn[ 3]:= ord(rightClick);
       
   366 
       
   367     tkbdn[23]:= ord(upKey);
       
   368     tkbdn[24]:= ord(downKey);
       
   369     tkbdn[25]:= ord(leftKey);
       
   370     tkbdn[26]:= ord(rightKey);
       
   371     tkbdn[27]:= ord(preciseKey);
       
   372 
       
   373     tkbdn[ 8]:= ord(backspaceKey);
       
   374     tkbdn[ 9]:= ord(tabKey);
       
   375     tkbdn[13]:= ord(enterKey);
       
   376     tkbdn[32]:= ord(spaceKey);
       
   377 
       
   378     tkbdn[44]:= ord(chatAction);
       
   379     tkbdn[55]:= ord(pauseAction);
       
   380 
       
   381     // set to false the keys that only need one stoke
       
   382     leftClick:= false;
       
   383     middleClick:= false;
       
   384     rightClick:= false;
       
   385 
       
   386     tabKey:= false;
       
   387     enterKey:= false;
       
   388     backspaceKey:= false;
       
   389 
       
   390     chatAction:= false;
       
   391     pauseAction:= false;
       
   392 end;
       
   393 {$ENDIF}
       
   394 
   343 
   395 procedure FreezeEnterKey;
   344 procedure FreezeEnterKey;
   396 begin
   345 begin
   397     tkbd[3]:= 1;
   346     tkbd[3]:= 1;
   398     tkbd[13]:= 1;
   347     tkbd[13]:= 1;