diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/uKeys.pas --- a/hedgewars/uKeys.pas Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/uKeys.pas Mon Oct 12 16:44:30 2009 +0000 @@ -32,10 +32,27 @@ procedure SetBinds(var binds: TBinds); procedure SetDefaultBinds; -var KbdKeyPressed: boolean; +procedure ControllerInit; +procedure ControllerClose; +procedure ControllerAxisEvent(joy, axis: Byte; value: Integer); +procedure ControllerHatEvent(joy, hat, value: Byte); +procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean); + +var hideAmmoMenu: boolean; wheelUp: boolean = false; wheelDown: boolean = false; + ControllerNumControllers: Integer; + ControllerEnabled: Integer; + ControllerNumAxes: array[0..5] of Integer; + //ControllerNumBalls: array[0..5] of Integer; + ControllerNumHats: array[0..5] of Integer; + ControllerNumButtons: array[0..5] of Integer; + ControllerAxes: array[0..5] of array[0..19] of Integer; + //ControllerBalls: array[0..5] of array[0..19] of array[0..1] of Integer; + ControllerHats: array[0..5] of array[0..19] of Byte; + ControllerButtons: array[0..5] of array[0..19] of Byte; + implementation uses SDLh, uTeams, uConsole, uMisc, uStore; const KeyNumber = 1024; @@ -53,17 +70,22 @@ KeyNameToCode:= Result end; + procedure ProcessKbd; -var i: LongInt; - s: shortstring; +var i, j, k: LongInt; pkbd: PByteArray; Trusted: boolean; + s: shortstring; begin -KbdKeyPressed:= false; + +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)? +movecursor(5 * CursorMovementX, 5 * CursorMovementY); {$IFDEF SDL13} pkbd := SDL_GetKeyboardState(nil); i := SDL_GetMouseState(0, nil, nil); @@ -71,7 +93,6 @@ pkbd := SDL_GetKeyState(nil); i := SDL_GetMouseState(nil, nil); {$ENDIF} - // mouse buttons {$IFDEF DARWIN} pkbd^[1]:= ((i and 1) and not (pkbd^[306] or pkbd^[305])); @@ -88,11 +109,36 @@ wheelUp:= false; wheelDown:= false; +// Controller(s) +k:= 500; // should we test k for hitting the limit? sounds rather unlikely to ever reach it +for j:= 0 to Pred(ControllerNumControllers) do + begin + for i:= 0 to Pred(ControllerNumAxes[j]) do + begin + if ControllerAxes[j][i] > 20000 then pkbd^[k + 0]:= 1 else pkbd^[k + 0]:= 0; + if ControllerAxes[j][i] < -20000 then pkbd^[k + 1]:= 1 else pkbd^[k + 1]:= 0; + inc(k, 2); + end; + for i:= 0 to Pred(ControllerNumHats[j]) do + begin + pkbd^[k + 0]:= ControllerHats[j][i] and SDL_HAT_UP; + pkbd^[k + 1]:= ControllerHats[j][i] and SDL_HAT_RIGHT; + pkbd^[k + 2]:= ControllerHats[j][i] and SDL_HAT_DOWN; + pkbd^[k + 3]:= ControllerHats[j][i] and SDL_HAT_LEFT; + inc(k, 4); + end; + for i:= 0 to Pred(ControllerNumButtons[j]) do + begin + pkbd^[k]:= ControllerButtons[j][i]; + inc(k, 1); + end; + end; + // now process strokes for i:= 1 to cKeyMaxIndex do if CurrentBinds[i][0] <> #0 then begin - if (i > 3) and (pkbd^[i] <> 0) then KbdKeyPressed:= true; + if (i > 3) and (pkbd^[i] <> 0) and not (hideAmmoMenu or (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 (pkbd^[i] <> 0) then ParseCommand(CurrentBinds[i], Trusted) else if (CurrentBinds[i][1] = '+') and (pkbd^[i] = 0) @@ -103,11 +149,11 @@ ParseCommand(s, Trusted) end; tkbd[i]:= pkbd^[i] - end + end; end; procedure ResetKbd; -var i, t: LongInt; +var i, j, k, t: LongInt; pkbd: PByteArray; begin @@ -118,12 +164,36 @@ {$ENDIF} TryDo(i < cKeyMaxIndex, 'SDL keys number is more than expected (' + inttostr(i) + ')', true); +k:= 500; +for j:= 0 to Pred(ControllerNumControllers) do + begin + for i:= 0 to Pred(ControllerNumAxes[j]) do + begin + pkbd^[k + 0]:= 0; + pkbd^[k + 1]:= 0; + inc(k, 2); + end; + for i:= 0 to Pred(ControllerNumHats[j]) do + begin + pkbd^[k + 0]:= 0; + pkbd^[k + 1]:= 0; + pkbd^[k + 2]:= 0; + pkbd^[k + 3]:= 0; + inc(k, 4); + end; + for i:= 0 to Pred(ControllerNumButtons[j]) do + begin + pkbd^[k]:= 0; + inc(k, 1); + end; + end; + for t:= 0 to Pred(i) do tkbd[i]:= pkbd^[i] end; procedure InitKbdKeyTable; -var i, t: LongInt; +var i, j, k, t: LongInt; s: string[15]; begin KeyNames[1]:= 'mousel'; @@ -144,6 +214,31 @@ end; end; +// Controller(s) +k:= 500; +for j:= 0 to Pred(ControllerNumControllers) do + begin + for i:= 0 to Pred(ControllerNumAxes[j]) do + begin + keynames[k + 0]:= 'j' + inttostr(j) + 'a' + inttostr(i) + 'u'; + keynames[k + 1]:= 'j' + inttostr(j) + 'a' + inttostr(i) + 'd'; + inc(k, 2); + end; + for i:= 0 to Pred(ControllerNumHats[j]) do + begin + keynames[k + 0]:= 'j' + inttostr(j) + 'h' + inttostr(i) + 'u'; + keynames[k + 1]:= 'j' + inttostr(j) + 'h' + inttostr(i) + 'r'; + keynames[k + 2]:= 'j' + inttostr(j) + 'h' + inttostr(i) + 'd'; + keynames[k + 3]:= 'j' + inttostr(j) + 'h' + inttostr(i) + 'l'; + inc(k, 4); + end; + for i:= 0 to Pred(ControllerNumButtons[j]) do + begin + keynames[k]:= 'j' + inttostr(j) + 'b' + inttostr(i); + inc(k, 1); + end; + end; + DefaultBinds[ 27]:= 'quit'; DefaultBinds[ 96]:= 'history'; DefaultBinds[127]:= 'rotmask'; @@ -182,6 +277,87 @@ tkbd[271]:= 1 end; +var Controller: array [0..5] of PSDLJoystick; + +procedure ControllerInit; +var i, j: Integer; +begin +ControllerEnabled:= 0; +ControllerNumControllers:= SDL_NumJoysticks; + +if ControllerNumControllers > 6 then ControllerNumControllers:= 6; + +WriteLnToConsole('Number of game controllers: ' + inttostr(ControllerNumControllers)); + +if ControllerNumControllers > 0 then + begin + for j:= 0 to pred(ControllerNumControllers) do + begin + WriteLnToConsole('Using game controller: ' + SDL_JoystickName(j)); + Controller[j]:= SDL_JoystickOpen(j); + if Controller[j] = nil then + WriteLnToConsole('* Failed to open game controller!') + else + begin + ControllerNumAxes[j]:= SDL_JoystickNumAxes(Controller[j]); + //ControllerNumBalls[j]:= SDL_JoystickNumBalls(Controller[j]); + ControllerNumHats[j]:= SDL_JoystickNumHats(Controller[j]); + ControllerNumButtons[j]:= SDL_JoystickNumButtons(Controller[j]); + WriteLnToConsole('* Number of axes: ' + inttostr(ControllerNumAxes[j])); + //WriteLnToConsole('* Number of balls: ' + inttostr(ControllerNumBalls[j])); + WriteLnToConsole('* Number of hats: ' + inttostr(ControllerNumHats[j])); + WriteLnToConsole('* Number of buttons: ' + inttostr(ControllerNumButtons[j])); + ControllerEnabled:= 1; + + if ControllerNumAxes[j] > 20 then ControllerNumAxes[j]:= 20; + //if ControllerNumBalls[j] > 20 then ControllerNumBalls[j]:= 20; + if ControllerNumHats[j] > 20 then ControllerNumHats[j]:= 20; + if ControllerNumButtons[j] > 20 then ControllerNumButtons[j]:= 20; + + // reset all buttons/axes + for i:= 0 to pred(ControllerNumAxes[j]) do + ControllerAxes[j][i]:= 0; + (*for i:= 0 to pred(ControllerNumBalls[j]) do + begin + ControllerBalls[j][i][0]:= 0; + ControllerBalls[j][i][1]:= 0; + end;*) + for i:= 0 to pred(ControllerNumHats[j]) do + ControllerHats[j][i]:= SDL_HAT_CENTERED; + for i:= 0 to pred(ControllerNumButtons[j]) do + ControllerButtons[j][i]:= 0; + end; + end; + // enable event generation/controller updating + SDL_JoystickEventState(1); + end +else + WriteLnToConsole('Not using any game controller'); +end; + +procedure ControllerClose; +var j: Integer; +begin +if ControllerEnabled > 0 then + for j:= 0 to pred(ControllerNumControllers) do + SDL_JoystickClose(Controller[j]); +end; + +procedure ControllerAxisEvent(joy, axis: Byte; value: Integer); +begin + ControllerAxes[joy][axis]:= value; +end; + +procedure ControllerHatEvent(joy, hat, value: Byte); +begin + ControllerHats[joy][hat]:= value; +end; + +procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean); +begin + if pressed then ControllerButtons[joy][button]:= 1 else ControllerButtons[joy][button]:= 0; +end; + initialization end.