hedgewars/uKeys.pas
changeset 2948 3f21a9dc93d0
parent 2905 f3c79f7193a9
child 3038 4e48c276a468
equal deleted inserted replaced
2947:803b277e4894 2948:3f21a9dc93d0
    41 procedure ControllerClose;
    41 procedure ControllerClose;
    42 procedure ControllerAxisEvent(joy, axis: Byte; value: Integer);
    42 procedure ControllerAxisEvent(joy, axis: Byte; value: Integer);
    43 procedure ControllerHatEvent(joy, hat, value: Byte);
    43 procedure ControllerHatEvent(joy, hat, value: Byte);
    44 procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean);
    44 procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean);
    45 
    45 
    46 var	hideAmmoMenu: boolean;
    46 var hideAmmoMenu: boolean;
    47 	wheelUp: boolean;
    47     wheelUp: boolean;
    48 	wheelDown: boolean;
    48     wheelDown: boolean;
    49 
    49 
    50 	ControllerNumControllers: Integer;
    50     ControllerNumControllers: Integer;
    51 	ControllerEnabled: Integer;
    51     ControllerEnabled: Integer;
    52 	ControllerNumAxes: array[0..5] of Integer;
    52     ControllerNumAxes: array[0..5] of Integer;
    53 	//ControllerNumBalls: array[0..5] of Integer;
    53     //ControllerNumBalls: array[0..5] of Integer;
    54 	ControllerNumHats: array[0..5] of Integer;
    54     ControllerNumHats: array[0..5] of Integer;
    55 	ControllerNumButtons: array[0..5] of Integer;
    55     ControllerNumButtons: array[0..5] of Integer;
    56 	ControllerAxes: array[0..5] of array[0..19] of Integer;
    56     ControllerAxes: array[0..5] of array[0..19] of Integer;
    57 	//ControllerBalls: array[0..5] of array[0..19] of array[0..1] of Integer;
    57     //ControllerBalls: array[0..5] of array[0..19] of array[0..1] of Integer;
    58 	ControllerHats: array[0..5] of array[0..19] of Byte;
    58     ControllerHats: array[0..5] of array[0..19] of Byte;
    59 	ControllerButtons: array[0..5] of array[0..19] of Byte;
    59     ControllerButtons: array[0..5] of array[0..19] of Byte;
    60 
    60 
    61 	DefaultBinds, CurrentBinds: TBinds;
    61     DefaultBinds, CurrentBinds: TBinds;
    62 
    62 
    63 {$IFDEF IPHONEOS}
    63 {$IFDEF IPHONEOS}
    64 	leftClick: boolean;
    64     leftClick: boolean;
    65 	middleClick: boolean;
    65     middleClick: boolean;
    66 	rightClick: boolean;
    66     rightClick: boolean;
    67 
    67 
    68 	upKey: boolean;
    68     upKey: boolean;
    69 	downKey: boolean;
    69     downKey: boolean;
    70 	rightKey: boolean;
    70     rightKey: boolean;
    71 	leftKey: boolean;
    71     leftKey: boolean;
    72 
    72 
    73 	backspaceKey: boolean;
    73     backspaceKey: boolean;
    74 	spaceKey: boolean;
    74     spaceKey: boolean;
    75 	enterKey: boolean;
    75     enterKey: boolean;
    76 	tabKey: boolean;
    76     tabKey: boolean;
    77 	
    77     
    78 	chatAction: boolean;
    78     chatAction: boolean;
    79 	pauseAction: boolean;
    79     pauseAction: boolean;
    80 	switchAction: boolean;
    80     switchAction: boolean;
    81 
    81 
    82 	theJoystick: PSDL_Joystick;
    82     theJoystick: PSDL_Joystick;
    83 	
    83     
    84 procedure setiPhoneBinds;
    84 procedure setiPhoneBinds;
    85 {$ENDIF}
    85 {$ENDIF}
    86 implementation
    86 implementation
    87 uses uTeams, uConsole, uMisc, uStore;
    87 uses uTeams, uConsole, uMisc, uStore;
    88 const KeyNumber = 1024;
    88 const KeyNumber = 1024;
    89 
    89 
    90 var tkbd, tkbdn: TKeyboardState;
    90 var tkbd, tkbdn: TKeyboardState;
    91     KeyNames: array [0..cKeyMaxIndex] of string[15];
    91     KeyNames: array [0..cKeyMaxIndex] of string[15];
    92 	
    92     
    93 function KeyNameToCode(name: shortstring): word;
    93 function KeyNameToCode(name: shortstring): word;
    94 var code: Word;
    94 var code: Word;
    95 begin
    95 begin
    96 	code:= cKeyMaxIndex;
    96     code:= cKeyMaxIndex;
    97 	while (code > 0) and (KeyNames[code] <> name) do dec(code);
    97     while (code > 0) and (KeyNames[code] <> name) do dec(code);
    98 	KeyNameToCode:= code;
    98     KeyNameToCode:= code;
    99 end;
    99 end;
   100 
   100 
   101 
   101 
   102 procedure ProcessKbd;
   102 procedure ProcessKbd;
   103 var  i, j, k: LongInt;
   103 var  i, j, k: LongInt;
   117 k:= SDL_GetMouseState(nil, nil);
   117 k:= SDL_GetMouseState(nil, nil);
   118 pkbd:= SDL_GetKeyState(@j);
   118 pkbd:= SDL_GetKeyState(@j);
   119 
   119 
   120 {$IFNDEF IPHONEOS}
   120 {$IFNDEF IPHONEOS}
   121 for i:= 6 to pred(j) do // first 6 will be overwritten
   121 for i:= 6 to pred(j) do // first 6 will be overwritten
   122 	tkbdn[i]:= pkbd^[i];
   122     tkbdn[i]:= pkbd^[i];
   123 {$ENDIF}
   123 {$ENDIF}
   124 
   124 
   125 // mouse buttons
   125 // mouse buttons
   126 {$IFDEF DARWIN}
   126 {$IFDEF DARWIN}
   127 tkbdn[1]:= ((k and 1) and not (tkbdn[306] or tkbdn[305]));
   127 tkbdn[1]:= ((k and 1) and not (tkbdn[306] or tkbdn[305]));
   143 {$ENDIF}
   143 {$ENDIF}
   144 
   144 
   145 // Controller(s)
   145 // Controller(s)
   146 k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it
   146 k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it
   147 for j:= 0 to Pred(ControllerNumControllers) do
   147 for j:= 0 to Pred(ControllerNumControllers) do
   148 	begin
   148     begin
   149 	for i:= 0 to Pred(ControllerNumAxes[j]) do
   149     for i:= 0 to Pred(ControllerNumAxes[j]) do
   150 		begin
   150         begin
   151 		if ControllerAxes[j][i] > 20000 then tkbdn[k + 0]:= 1 else tkbdn[k + 0]:= 0;
   151         if ControllerAxes[j][i] > 20000 then tkbdn[k + 0]:= 1 else tkbdn[k + 0]:= 0;
   152 		if ControllerAxes[j][i] < -20000 then tkbdn[k + 1]:= 1 else tkbdn[k + 1]:= 0;
   152         if ControllerAxes[j][i] < -20000 then tkbdn[k + 1]:= 1 else tkbdn[k + 1]:= 0;
   153 		inc(k, 2);
   153         inc(k, 2);
   154 		end;
   154         end;
   155 	for i:= 0 to Pred(ControllerNumHats[j]) do
   155     for i:= 0 to Pred(ControllerNumHats[j]) do
   156 		begin
   156         begin
   157 		tkbdn[k + 0]:= ControllerHats[j][i] and SDL_HAT_UP;
   157         tkbdn[k + 0]:= ControllerHats[j][i] and SDL_HAT_UP;
   158 		tkbdn[k + 1]:= ControllerHats[j][i] and SDL_HAT_RIGHT;
   158         tkbdn[k + 1]:= ControllerHats[j][i] and SDL_HAT_RIGHT;
   159 		tkbdn[k + 2]:= ControllerHats[j][i] and SDL_HAT_DOWN;
   159         tkbdn[k + 2]:= ControllerHats[j][i] and SDL_HAT_DOWN;
   160 		tkbdn[k + 3]:= ControllerHats[j][i] and SDL_HAT_LEFT;
   160         tkbdn[k + 3]:= ControllerHats[j][i] and SDL_HAT_LEFT;
   161 		inc(k, 4);
   161         inc(k, 4);
   162 		end;
   162         end;
   163 	for i:= 0 to Pred(ControllerNumButtons[j]) do
   163     for i:= 0 to Pred(ControllerNumButtons[j]) do
   164 		begin
   164         begin
   165 		tkbdn[k]:= ControllerButtons[j][i];
   165         tkbdn[k]:= ControllerButtons[j][i];
   166 		inc(k, 1);
   166         inc(k, 1);
   167 		end;
   167         end;
   168 	end;
   168     end;
   169 
   169 
   170 // now process strokes
   170 // now process strokes
   171 for i:= 0 to cKeyMaxIndex do
   171 for i:= 0 to cKeyMaxIndex do
   172 if CurrentBinds[i][0] <> #0 then
   172 if CurrentBinds[i][0] <> #0 then
   173 	begin
   173     begin
   174 	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;
   174     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;
   175 	if (tkbd[i] = 0) and (tkbdn[i] <> 0) then ParseCommand(CurrentBinds[i], Trusted)
   175     if (tkbd[i] = 0) and (tkbdn[i] <> 0) then ParseCommand(CurrentBinds[i], Trusted)
   176 	else if (CurrentBinds[i][1] = '+')
   176     else if (CurrentBinds[i][1] = '+')
   177 			and (tkbdn[i] = 0)
   177             and (tkbdn[i] = 0)
   178 			and (tkbd[i] <> 0) then
   178             and (tkbd[i] <> 0) then
   179 			begin
   179             begin
   180 			s:= CurrentBinds[i];
   180             s:= CurrentBinds[i];
   181 			s[1]:= '-';
   181             s[1]:= '-';
   182 			ParseCommand(s, Trusted)
   182             ParseCommand(s, Trusted)
   183 			end;
   183             end;
   184 	tkbd[i]:= tkbdn[i]
   184     tkbd[i]:= tkbdn[i]
   185 	end
   185     end
   186 end;
   186 end;
   187 
   187 
   188 procedure ResetKbd;
   188 procedure ResetKbd;
   189 var i, j, k, t: LongInt;
   189 var i, j, k, t: LongInt;
   190     pkbd: PByteArray;
   190     pkbd: PByteArray;
   195 
   195 
   196 TryDo(j < cKeyMaxIndex, 'SDL keys number is more than expected (' + inttostr(j) + ')', true);
   196 TryDo(j < cKeyMaxIndex, 'SDL keys number is more than expected (' + inttostr(j) + ')', true);
   197 
   197 
   198 {$IFNDEF IPHONEOS}
   198 {$IFNDEF IPHONEOS}
   199 for i:= 1 to pred(j) do
   199 for i:= 1 to pred(j) do
   200 	tkbdn[i]:= pkbd^[i];
   200     tkbdn[i]:= pkbd^[i];
   201 {$ENDIF}
   201 {$ENDIF}
   202 
   202 
   203 // mouse buttons
   203 // mouse buttons
   204 {$IFDEF DARWIN}
   204 {$IFDEF DARWIN}
   205 tkbdn[1]:= ((k and 1) and not (tkbdn[306] or tkbdn[305]));
   205 tkbdn[1]:= ((k and 1) and not (tkbdn[306] or tkbdn[305]));
   221 {$ENDIF}
   221 {$ENDIF}
   222 
   222 
   223 // Controller(s)
   223 // Controller(s)
   224 k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it
   224 k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it
   225 for j:= 0 to Pred(ControllerNumControllers) do
   225 for j:= 0 to Pred(ControllerNumControllers) do
   226 	begin
   226     begin
   227 	for i:= 0 to Pred(ControllerNumAxes[j]) do
   227     for i:= 0 to Pred(ControllerNumAxes[j]) do
   228 		begin
   228         begin
   229 		if ControllerAxes[j][i] > 20000 then tkbdn[k + 0]:= 1 else tkbdn[k + 0]:= 0;
   229         if ControllerAxes[j][i] > 20000 then tkbdn[k + 0]:= 1 else tkbdn[k + 0]:= 0;
   230 		if ControllerAxes[j][i] < -20000 then tkbdn[k + 1]:= 1 else tkbdn[k + 1]:= 0;
   230         if ControllerAxes[j][i] < -20000 then tkbdn[k + 1]:= 1 else tkbdn[k + 1]:= 0;
   231 		inc(k, 2);
   231         inc(k, 2);
   232 		end;
   232         end;
   233 	for i:= 0 to Pred(ControllerNumHats[j]) do
   233     for i:= 0 to Pred(ControllerNumHats[j]) do
   234 		begin
   234         begin
   235 		tkbdn[k + 0]:= ControllerHats[j][i] and SDL_HAT_UP;
   235         tkbdn[k + 0]:= ControllerHats[j][i] and SDL_HAT_UP;
   236 		tkbdn[k + 1]:= ControllerHats[j][i] and SDL_HAT_RIGHT;
   236         tkbdn[k + 1]:= ControllerHats[j][i] and SDL_HAT_RIGHT;
   237 		tkbdn[k + 2]:= ControllerHats[j][i] and SDL_HAT_DOWN;
   237         tkbdn[k + 2]:= ControllerHats[j][i] and SDL_HAT_DOWN;
   238 		tkbdn[k + 3]:= ControllerHats[j][i] and SDL_HAT_LEFT;
   238         tkbdn[k + 3]:= ControllerHats[j][i] and SDL_HAT_LEFT;
   239 		inc(k, 4);
   239         inc(k, 4);
   240 		end;
   240         end;
   241 	for i:= 0 to Pred(ControllerNumButtons[j]) do
   241     for i:= 0 to Pred(ControllerNumButtons[j]) do
   242 		begin
   242         begin
   243 		tkbdn[k]:= ControllerButtons[j][i];
   243         tkbdn[k]:= ControllerButtons[j][i];
   244 		inc(k, 1);
   244         inc(k, 1);
   245 		end;
   245         end;
   246 	end;
   246     end;
   247 	
   247     
   248 for t:= 0 to cKeyMaxIndex do
   248 for t:= 0 to cKeyMaxIndex do
   249     tkbd[i]:= tkbdn[i]
   249     tkbd[i]:= tkbdn[i]
   250 end;
   250 end;
   251 
   251 
   252 procedure InitKbdKeyTable;
   252 procedure InitKbdKeyTable;
   258 KeyNames[3]:= 'mouser';
   258 KeyNames[3]:= 'mouser';
   259 KeyNames[4]:= 'wheelup';
   259 KeyNames[4]:= 'wheelup';
   260 KeyNames[5]:= 'wheeldown';
   260 KeyNames[5]:= 'wheeldown';
   261 
   261 
   262 for i:= 6 to cKeyMaxIndex do
   262 for i:= 6 to cKeyMaxIndex do
   263 	begin
   263     begin
   264     	s:= shortstring(sdl_getkeyname(i));
   264         s:= shortstring(sdl_getkeyname(i));
   265 	//writeln(stdout,inttostr(i) + ': ' + s);
   265     //writeln(stdout,inttostr(i) + ': ' + s);
   266     	if s = 'unknown key' then KeyNames[i]:= ''
   266         if s = 'unknown key' then KeyNames[i]:= ''
   267        	else begin
   267         else begin
   268 		for t:= 1 to Length(s) do
   268         for t:= 1 to Length(s) do
   269 			if s[t] = ' ' then s[t]:= '_';
   269             if s[t] = ' ' then s[t]:= '_';
   270        		KeyNames[i]:= s
   270             KeyNames[i]:= s
   271        	end;
   271         end;
   272 end;
   272 end;
   273 
   273 
   274 //for i:= 0 to cKeyMaxIndex do writeln(stdout,inttostr(i) + ': ' + KeyNames[i]);
   274 //for i:= 0 to cKeyMaxIndex do writeln(stdout,inttostr(i) + ': ' + KeyNames[i]);
   275 
   275 
   276 // get the size of keyboard array
   276 // get the size of keyboard array
   277 SDL_GetKeyState(@k);
   277 SDL_GetKeyState(@k);
   278 
   278 
   279 // Controller(s)
   279 // Controller(s)
   280 for j:= 0 to Pred(ControllerNumControllers) do
   280 for j:= 0 to Pred(ControllerNumControllers) do
   281 	begin
   281     begin
   282 	for i:= 0 to Pred(ControllerNumAxes[j]) do
   282     for i:= 0 to Pred(ControllerNumAxes[j]) do
   283 		begin
   283         begin
   284 		keynames[k + 0]:= 'j' + inttostr(j) + 'a' + inttostr(i) + 'u';
   284         keynames[k + 0]:= 'j' + inttostr(j) + 'a' + inttostr(i) + 'u';
   285 		keynames[k + 1]:= 'j' + inttostr(j) + 'a' + inttostr(i) + 'd';
   285         keynames[k + 1]:= 'j' + inttostr(j) + 'a' + inttostr(i) + 'd';
   286 		inc(k, 2);
   286         inc(k, 2);
   287 		end;
   287         end;
   288 	for i:= 0 to Pred(ControllerNumHats[j]) do
   288     for i:= 0 to Pred(ControllerNumHats[j]) do
   289 		begin
   289         begin
   290 		keynames[k + 0]:= 'j' + inttostr(j) + 'h' + inttostr(i) + 'u';
   290         keynames[k + 0]:= 'j' + inttostr(j) + 'h' + inttostr(i) + 'u';
   291 		keynames[k + 1]:= 'j' + inttostr(j) + 'h' + inttostr(i) + 'r';
   291         keynames[k + 1]:= 'j' + inttostr(j) + 'h' + inttostr(i) + 'r';
   292 		keynames[k + 2]:= 'j' + inttostr(j) + 'h' + inttostr(i) + 'd';
   292         keynames[k + 2]:= 'j' + inttostr(j) + 'h' + inttostr(i) + 'd';
   293 		keynames[k + 3]:= 'j' + inttostr(j) + 'h' + inttostr(i) + 'l';
   293         keynames[k + 3]:= 'j' + inttostr(j) + 'h' + inttostr(i) + 'l';
   294 		inc(k, 4);
   294         inc(k, 4);
   295 		end;
   295         end;
   296 	for i:= 0 to Pred(ControllerNumButtons[j]) do
   296     for i:= 0 to Pred(ControllerNumButtons[j]) do
   297 		begin
   297         begin
   298 		keynames[k]:= 'j' + inttostr(j) + 'b' + inttostr(i);
   298         keynames[k]:= 'j' + inttostr(j) + 'b' + inttostr(i);
   299 		inc(k, 1);
   299         inc(k, 1);
   300 		end;
   300         end;
   301 	end;
   301     end;
   302 
   302 
   303 DefaultBinds[ 27]:= 'quit';
   303 DefaultBinds[ 27]:= 'quit';
   304 DefaultBinds[ 96]:= 'history';
   304 DefaultBinds[ 96]:= 'history';
   305 DefaultBinds[127]:= 'rotmask';
   305 DefaultBinds[127]:= 'rotmask';
   306 
   306 
   349 SetDefaultBinds();
   349 SetDefaultBinds();
   350 end;
   350 end;
   351 
   351 
   352 procedure SetBinds(var binds: TBinds);
   352 procedure SetBinds(var binds: TBinds);
   353 begin
   353 begin
   354 	CurrentBinds:= binds;
   354     CurrentBinds:= binds;
   355 end;
   355 end;
   356 
   356 
   357 procedure SetDefaultBinds;
   357 procedure SetDefaultBinds;
   358 begin
   358 begin
   359 	CurrentBinds:= DefaultBinds;
   359     CurrentBinds:= DefaultBinds;
   360 end;
   360 end;
   361 
   361 
   362 {$IFDEF IPHONEOS}
   362 {$IFDEF IPHONEOS}
   363 procedure setiPhoneBinds;
   363 procedure setiPhoneBinds;
   364 // set to false the keys that only need one stoke
   364 // set to false the keys that only need one stoke
   365 begin
   365 begin
   366 	tkbdn[1]:= ord(leftClick);
   366     tkbdn[1]:= ord(leftClick);
   367 	tkbdn[2]:= ord(middleClick);
   367     tkbdn[2]:= ord(middleClick);
   368 	tkbdn[3]:= ord(rightClick);
   368     tkbdn[3]:= ord(rightClick);
   369 
   369 
   370 	tkbdn[23]:= ord(upKey);
   370     tkbdn[23]:= ord(upKey);
   371 	tkbdn[24]:= ord(downKey);
   371     tkbdn[24]:= ord(downKey);
   372 	tkbdn[25]:= ord(leftKey);
   372     tkbdn[25]:= ord(leftKey);
   373 	tkbdn[26]:= ord(rightKey);
   373     tkbdn[26]:= ord(rightKey);
   374 
   374 
   375 	tkbdn[ 8]:= ord(backspaceKey);
   375     tkbdn[ 8]:= ord(backspaceKey);
   376 	tkbdn[ 9]:= ord(tabKey);
   376     tkbdn[ 9]:= ord(tabKey);
   377 	tkbdn[13]:= ord(enterKey);
   377     tkbdn[13]:= ord(enterKey);
   378 	tkbdn[32]:= ord(spaceKey);
   378     tkbdn[32]:= ord(spaceKey);
   379 
   379 
   380 	tkbdn[44]:= ord(chatAction);
   380     tkbdn[44]:= ord(chatAction);
   381 	tkbdn[55]:= ord(pauseAction);
   381     tkbdn[55]:= ord(pauseAction);
   382 	//tkbdn[100]:= ord(switchAction);
   382     //tkbdn[100]:= ord(switchAction);
   383 	
   383     
   384 	leftClick:= false;
   384     leftClick:= false;
   385 	middleClick:= false;
   385     middleClick:= false;
   386 	rightClick:= false;
   386     rightClick:= false;
   387 
   387 
   388 	tabKey:= false;
   388     tabKey:= false;
   389 	enterKey:= false;
   389     enterKey:= false;
   390 	backspaceKey:= false;
   390     backspaceKey:= false;
   391 	
   391     
   392 	chatAction:= false;
   392     chatAction:= false;
   393 	pauseAction:= false;
   393     pauseAction:= false;
   394 	//switchAction:= false;
   394     //switchAction:= false;
   395 end;
   395 end;
   396 {$ENDIF}
   396 {$ENDIF}
   397 
   397 
   398 procedure FreezeEnterKey;
   398 procedure FreezeEnterKey;
   399 begin
   399 begin
   400 tkbd[13]:= 1;
   400 tkbd[13]:= 1;
   401 tkbd[271]:= 1;
   401 tkbd[271]:= 1;
   402 end;
   402 end;
   403 
   403 
   404 var Controller: array [0..5] of PSDL_Joystick;
   404 var Controller: array [0..5] of PSDL_Joystick;
   405 	
   405     
   406 procedure ControllerInit;
   406 procedure ControllerInit;
   407 var i, j: Integer;
   407 var i, j: Integer;
   408 begin
   408 begin
   409 SDL_InitSubSystem(SDL_INIT_JOYSTICK);
   409 SDL_InitSubSystem(SDL_INIT_JOYSTICK);
   410 
   410 
   414 if ControllerNumControllers > 6 then ControllerNumControllers:= 6;
   414 if ControllerNumControllers > 6 then ControllerNumControllers:= 6;
   415 
   415 
   416 WriteLnToConsole('Number of game controllers: ' + inttostr(ControllerNumControllers));
   416 WriteLnToConsole('Number of game controllers: ' + inttostr(ControllerNumControllers));
   417 
   417 
   418 if ControllerNumControllers > 0 then
   418 if ControllerNumControllers > 0 then
   419 	begin
   419     begin
   420 	for j:= 0 to pred(ControllerNumControllers) do
   420     for j:= 0 to pred(ControllerNumControllers) do
   421 		begin
   421         begin
   422 		WriteLnToConsole('Using game controller: ' + SDL_JoystickName(j));
   422         WriteLnToConsole('Using game controller: ' + SDL_JoystickName(j));
   423 		Controller[j]:= SDL_JoystickOpen(j);
   423         Controller[j]:= SDL_JoystickOpen(j);
   424 		if Controller[j] = nil then
   424         if Controller[j] = nil then
   425 			WriteLnToConsole('* Failed to open game controller!')
   425             WriteLnToConsole('* Failed to open game controller!')
   426 		else
   426         else
   427 			begin
   427             begin
   428 			ControllerNumAxes[j]:= SDL_JoystickNumAxes(Controller[j]);
   428             ControllerNumAxes[j]:= SDL_JoystickNumAxes(Controller[j]);
   429 			//ControllerNumBalls[j]:= SDL_JoystickNumBalls(Controller[j]);
   429             //ControllerNumBalls[j]:= SDL_JoystickNumBalls(Controller[j]);
   430 			ControllerNumHats[j]:= SDL_JoystickNumHats(Controller[j]);
   430             ControllerNumHats[j]:= SDL_JoystickNumHats(Controller[j]);
   431 			ControllerNumButtons[j]:= SDL_JoystickNumButtons(Controller[j]);
   431             ControllerNumButtons[j]:= SDL_JoystickNumButtons(Controller[j]);
   432 			WriteLnToConsole('* Number of axes: ' + inttostr(ControllerNumAxes[j]));
   432             WriteLnToConsole('* Number of axes: ' + inttostr(ControllerNumAxes[j]));
   433 			//WriteLnToConsole('* Number of balls: ' + inttostr(ControllerNumBalls[j]));
   433             //WriteLnToConsole('* Number of balls: ' + inttostr(ControllerNumBalls[j]));
   434 			WriteLnToConsole('* Number of hats: ' + inttostr(ControllerNumHats[j]));
   434             WriteLnToConsole('* Number of hats: ' + inttostr(ControllerNumHats[j]));
   435 			WriteLnToConsole('* Number of buttons: ' + inttostr(ControllerNumButtons[j]));
   435             WriteLnToConsole('* Number of buttons: ' + inttostr(ControllerNumButtons[j]));
   436 			ControllerEnabled:= 1;
   436             ControllerEnabled:= 1;
   437 			
   437             
   438 			if ControllerNumAxes[j] > 20 then ControllerNumAxes[j]:= 20;
   438             if ControllerNumAxes[j] > 20 then ControllerNumAxes[j]:= 20;
   439 			//if ControllerNumBalls[j] > 20 then ControllerNumBalls[j]:= 20;
   439             //if ControllerNumBalls[j] > 20 then ControllerNumBalls[j]:= 20;
   440 			if ControllerNumHats[j] > 20 then ControllerNumHats[j]:= 20;
   440             if ControllerNumHats[j] > 20 then ControllerNumHats[j]:= 20;
   441 			if ControllerNumButtons[j] > 20 then ControllerNumButtons[j]:= 20;
   441             if ControllerNumButtons[j] > 20 then ControllerNumButtons[j]:= 20;
   442 			
   442             
   443 			// reset all buttons/axes
   443             // reset all buttons/axes
   444 			for i:= 0 to pred(ControllerNumAxes[j]) do
   444             for i:= 0 to pred(ControllerNumAxes[j]) do
   445 				ControllerAxes[j][i]:= 0;
   445                 ControllerAxes[j][i]:= 0;
   446 			(*for i:= 0 to pred(ControllerNumBalls[j]) do
   446             (*for i:= 0 to pred(ControllerNumBalls[j]) do
   447 				begin
   447                 begin
   448 				ControllerBalls[j][i][0]:= 0;
   448                 ControllerBalls[j][i][0]:= 0;
   449 				ControllerBalls[j][i][1]:= 0;
   449                 ControllerBalls[j][i][1]:= 0;
   450 				end;*)
   450                 end;*)
   451 			for i:= 0 to pred(ControllerNumHats[j]) do
   451             for i:= 0 to pred(ControllerNumHats[j]) do
   452 				ControllerHats[j][i]:= SDL_HAT_CENTERED;
   452                 ControllerHats[j][i]:= SDL_HAT_CENTERED;
   453 			for i:= 0 to pred(ControllerNumButtons[j]) do
   453             for i:= 0 to pred(ControllerNumButtons[j]) do
   454 				ControllerButtons[j][i]:= 0;
   454                 ControllerButtons[j][i]:= 0;
   455 			end;
   455             end;
   456 		end;
   456         end;
   457 	// enable event generation/controller updating
   457     // enable event generation/controller updating
   458 	SDL_JoystickEventState(1);
   458     SDL_JoystickEventState(1);
   459 	end
   459     end
   460 else	
   460 else    
   461 	WriteLnToConsole('Not using any game controller');
   461     WriteLnToConsole('Not using any game controller');
   462 {$IFDEF IPHONEOS}
   462 {$IFDEF IPHONEOS}
   463 theJoystick:= Controller[0];
   463 theJoystick:= Controller[0];
   464 {$ENDIF}
   464 {$ENDIF}
   465 end;
   465 end;
   466 
   466 
   467 procedure ControllerClose;
   467 procedure ControllerClose;
   468 var j: Integer;
   468 var j: Integer;
   469 begin
   469 begin
   470 	if ControllerEnabled > 0 then
   470     if ControllerEnabled > 0 then
   471 		for j:= 0 to pred(ControllerNumControllers) do
   471         for j:= 0 to pred(ControllerNumControllers) do
   472 			SDL_JoystickClose(Controller[j]);
   472             SDL_JoystickClose(Controller[j]);
   473 end;
   473 end;
   474 
   474 
   475 procedure ControllerAxisEvent(joy, axis: Byte; value: Integer);
   475 procedure ControllerAxisEvent(joy, axis: Byte; value: Integer);
   476 begin
   476 begin
   477 	ControllerAxes[joy][axis]:= value;
   477     ControllerAxes[joy][axis]:= value;
   478 end;
   478 end;
   479 
   479 
   480 procedure ControllerHatEvent(joy, hat, value: Byte);
   480 procedure ControllerHatEvent(joy, hat, value: Byte);
   481 begin
   481 begin
   482 	ControllerHats[joy][hat]:= value;
   482     ControllerHats[joy][hat]:= value;
   483 end;
   483 end;
   484 
   484 
   485 procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean);
   485 procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean);
   486 begin
   486 begin
   487 	if pressed then ControllerButtons[joy][button]:= 1
   487     if pressed then ControllerButtons[joy][button]:= 1
   488 	else ControllerButtons[joy][button]:= 0;
   488     else ControllerButtons[joy][button]:= 0;
   489 end;
   489 end;
   490 
   490 
   491 procedure init_uKeys;
   491 procedure init_uKeys;
   492 begin
   492 begin
   493 	wheelUp:= false;
   493     wheelUp:= false;
   494 	wheelDown:= false;
   494     wheelDown:= false;
   495 {$IFDEF IPHONEOS}
   495 {$IFDEF IPHONEOS}
   496 	// this function is called by HW_allKeysUp so be careful
   496     // this function is called by HW_allKeysUp so be careful
   497 	leftClick:= false;
   497     leftClick:= false;
   498 	middleClick:= false;
   498     middleClick:= false;
   499 	rightClick:= false;
   499     rightClick:= false;
   500 
   500 
   501 	upKey:= false;
   501     upKey:= false;
   502 	downKey:= false;
   502     downKey:= false;
   503 	rightKey:= false;
   503     rightKey:= false;
   504 	leftKey:= false;
   504     leftKey:= false;
   505 
   505 
   506 	backspaceKey:= false;
   506     backspaceKey:= false;
   507 	spaceKey:= false;
   507     spaceKey:= false;
   508 	enterKey:= false;
   508     enterKey:= false;
   509 	tabKey:= false;
   509     tabKey:= false;
   510 	
   510     
   511 	chatAction:= false;
   511     chatAction:= false;
   512 	pauseAction:= false;
   512     pauseAction:= false;
   513 	switchAction:= false;
   513     switchAction:= false;
   514 {$ENDIF}
   514 {$ENDIF}
   515 end;
   515 end;
   516 
   516 
   517 procedure free_uKeys;
   517 procedure free_uKeys;
   518 begin
   518 begin