- change uKeys to be event based rather than polling
- missing engine+frontend exit
- missing controller support
- needs testing on different platforms and keyboards
--- 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;