diff --git a/src/game/g_touch.pas b/src/game/g_touch.pas
index 0a02e577bf040487632ffbcbf09fd1e52540b38f..15ecb11f6c5d84b74de96133d5d6715a476ca538 100644 (file)
--- a/src/game/g_touch.pas
+++ b/src/game/g_touch.pas
uses
SDL2;
+ var
+ g_touch_enabled: Boolean;
+ g_touch_size: Single;
+ g_touch_offset: Single;
+ g_touch_fire: Boolean;
+ g_touch_alt: Boolean;
+
+ procedure g_Touch_Init;
procedure g_Touch_ShowKeyboard(yes: Boolean);
procedure g_Touch_HandleEvent(const ev: TSDL_TouchFingerEvent);
procedure g_Touch_Draw;
e_log, e_graphics, e_input, g_options, g_game, g_main, g_weapons, g_console;
const
- CTL_NONE = 0;
- CTL_LEFT = 1;
- CTL_RIGHT = 2;
- CTL_UP = 3;
- CTL_DOWN = 4;
- CTL_FIRE = 5;
- CTL_OPEN = 6;
- CTL_JUMP = 7;
- CTL_CHAT = 8;
- CTL_ESC = 9;
- CTL_W0 = 10;
- CTL_W1 = 11;
- CTL_W2 = 12;
- CTL_W3 = 13;
- CTL_W4 = 14;
- CTL_W5 = 15;
- CTL_W6 = 16;
- CTL_W7 = 17;
- CTL_W8 = 18;
- CTL_W9 = 19;
- CTL_W10 = 20;
- CTL_CON = 21;
- CTL_STAT = 22;
- CTL_TCHAT = 23;
- CTL_LAST = 23;
+ VS_KEYBOARD = 60000;
+ VS_HIDEKEYBOARD = 60001;
var
- size: Single;
- enabled: Boolean;
- keyFinger: array [1..CTL_LAST] of Integer;
+ angleFire: Boolean;
+ keyFinger: array [VK_FIRSTKEY..VK_LASTKEY] of Integer;
+
+ procedure GetKeyRect(key: Integer; out x, y, w, h: Integer; out founded: Boolean);
+ var
+ sw, sh, sz: Integer;
+ dpi: Single;
+
+ procedure S (xx, yy, ww, hh: Single);
+ begin
+ x := Trunc(xx);
+ y := Trunc(yy);
+ w := Trunc(ww);
+ h := Trunc(hh);
+ founded := true;
+ end;
- procedure GetControlRect(control: Integer; out x, y, w, h: Integer; out founded: Boolean);
- var
- sw, sh, sz: Integer;
- dpi: Single;
begin
+ founded := false;
if SDL_GetDisplayDPI(0, @dpi, nil, nil) <> 0 then
dpi := 96;
- founded := true;
- sz := Trunc(size * dpi);
- x := 0; y := 0; w := sz; h := sz;
- sw := gScreenWidth; sh := gScreenHeight;
- case control of
- CTL_LEFT: begin x := 0; y := sh div 2 - h div 2; end;
- CTL_RIGHT: begin x := w; y := sh div 2 - h div 2; end;
- CTL_UP: begin x := sw - w - 1; y := sh div 2 - h div 2 - h; end;
- CTL_DOWN: begin x := sw - w - 1; y := sh div 2 - h div 2 + h; end;
- CTL_FIRE: begin x := sw - 1*w - 1; y := sh div 2 - h div 2; end;
- CTL_OPEN: begin x := sw - 3*w - 1; y := sh div 2 - h div 2; end;
- CTL_JUMP: begin x := sw - 2*w - 1; y := sh div 2 - h div 2; end;
- else
- w := sz div 2; h := sz div 2;
- case control of
- CTL_W0: begin x := sw div 2 - w div 2 - 5*w - 1; y := sh - 1*h - 1; end;
- CTL_W1: begin x := sw div 2 - w div 2 - 4*w - 1; y := sh - 1*h - 1; end;
- CTL_W2: begin x := sw div 2 - w div 2 - 3*w - 1; y := sh - 1*h - 1; end;
- CTL_W3: begin x := sw div 2 - w div 2 - 2*w - 1; y := sh - 1*h - 1; end;
- CTL_W4: begin x := sw div 2 - w div 2 - 1*w - 1; y := sh - 1*h - 1; end;
- CTL_W5: begin x := sw div 2 - w div 2 + 0*w - 1; y := sh - 1*h - 1; end;
- CTL_W6: begin x := sw div 2 - w div 2 + 1*w - 1; y := sh - 1*h - 1; end;
- CTL_W7: begin x := sw div 2 - w div 2 + 2*w - 1; y := sh - 1*h - 1; end;
- CTL_W8: begin x := sw div 2 - w div 2 + 3*w - 1; y := sh - 1*h - 1; end;
- CTL_W9: begin x := sw div 2 - w div 2 + 4*w - 1; y := sh - 1*h - 1; end;
- CTL_W10: begin x := sw div 2 - w div 2 + 5*w - 1; y := sh - 1*h - 1; end;
- CTL_CHAT: begin x := sw div 2 - w div 2 - 2*w - 1; y := sh - 2*h - 1; end;
- CTL_ESC: begin x := sw div 2 - w div 2 - 1*w - 1; y := sh - 2*h - 1; end;
- CTL_CON: begin x := sw div 2 - w div 2 + 0*w - 1; y := sh - 2*h - 1; end;
- CTL_STAT: begin x := sw div 2 - w div 2 + 1*w - 1; y := sh - 2*h - 1; end;
- CTL_TCHAT: begin x := sw div 2 - w div 2 + 2*w - 1; y := sh - 2*h - 1; end;
- else
- founded := false
- end
- end
- end;
-
- function GetMenuKey(control: Integer): Word;
- begin
- case control of
- CTL_LEFT: result := IK_LEFT;
- CTL_RIGHT: result := IK_RIGHT;
- CTL_UP: result := IK_UP;
- CTL_DOWN: result := IK_DOWN;
- CTL_OPEN: result := IK_ENTER;
- CTL_FIRE: result := IK_ENTER;
- CTL_JUMP: result := IK_SPACE;
- CTL_ESC: result := IK_ESCAPE;
- CTL_W0: result := SDL_SCANCODE_0;
- CTL_W1: result := SDL_SCANCODE_1;
- CTL_W2: result := SDL_SCANCODE_2;
- CTL_W3: result := SDL_SCANCODE_3;
- CTL_W4: result := SDL_SCANCODE_4;
- CTL_W5: result := SDL_SCANCODE_5;
- CTL_W6: result := SDL_SCANCODE_6;
- CTL_W7: result := SDL_SCANCODE_7;
- CTL_W8: result := SDL_SCANCODE_8;
- CTL_W9: result := SDL_SCANCODE_9;
- CTL_CON: result := IK_GRAVE;
- else
- result := IK_INVALID;
- end
- end;
+ sz := Trunc(g_touch_size * dpi); sw := gScreenWidth; sh := gScreenHeight;
+ x := 0; y := Round(sh * g_touch_offset / 100);
+ w := sz; h := sz;
- function GetPlayerKey(control: Integer): Word;
- begin
- case control of
- CTL_LEFT: result := gGameControls.P1Control.KeyLeft;
- CTL_RIGHT: result := gGameControls.P1Control.KeyRight;
- CTL_UP: result := gGameControls.P1Control.KeyUp;
- CTL_DOWN: result := gGameControls.P1Control.KeyDown;
- CTL_OPEN: result := gGameControls.P1Control.KeyOpen;
- CTL_FIRE: result := gGameControls.P1Control.KeyFire;
- CTL_JUMP: result := gGameControls.P1Control.KeyJump;
- CTL_CHAT: result := gGameControls.GameControls.Chat;
- CTL_ESC: result := IK_ESCAPE;
- CTL_W0: result := gGameControls.P1Control.KeyWeapon[WEAPON_KASTET];
- CTL_W1: result := gGameControls.P1Control.KeyWeapon[WEAPON_SAW];
- CTL_W2: result := gGameControls.P1Control.KeyWeapon[WEAPON_PISTOL];
- CTL_W3: result := gGameControls.P1Control.KeyWeapon[WEAPON_SHOTGUN1];
- CTL_W4: result := gGameControls.P1Control.KeyWeapon[WEAPON_SHOTGUN2];
- CTL_W5: result := gGameControls.P1Control.KeyWeapon[WEAPON_CHAINGUN];
- CTL_W6: result := gGameControls.P1Control.KeyWeapon[WEAPON_ROCKETLAUNCHER];
- CTL_W7: result := gGameControls.P1Control.KeyWeapon[WEAPON_PLASMA];
- CTL_W8: result := gGameControls.P1Control.KeyWeapon[WEAPON_BFG];
- CTL_W9: result := gGameControls.P1Control.KeyWeapon[WEAPON_SUPERPULEMET];
- CTL_W10: result := gGameControls.P1Control.KeyWeapon[WEAPON_FLAMETHROWER];
- CTL_CON: result := IK_GRAVE;
- CTL_STAT: result := gGameControls.GameControls.Stat;
- CTL_TCHAT: result := gGameControls.GameControls.TeamChat;
+ if SDL_IsTextInputActive() = SDL_True then
+ case key of
+ VS_HIDEKEYBOARD: S(sw - (sz/2), 0, sz / 2, sz / 2);
+ end
+ else if g_touch_alt then
+ case key of
+ (* top ------- x ------------------------------- y w ----- h -- *)
+ VK_CONSOLE: S(0, 0, sz / 2, sz / 2);
+ VK_ESCAPE: S(sw - 1*(sz/2) - 1, 0, sz / 2, sz / 2);
+ VS_KEYBOARD: S(sw - 2*(sz/2) - 1, 0, sz / 2, sz / 2);
+ VK_CHAT: S(sw / 2 - (sz/2) / 2 - (sz/2) - 1, 0, sz / 2, sz / 2);
+ VK_STATUS: S(sw / 2 - (sz/2) / 2 - 1, 0, sz / 2, sz / 2);
+ VK_TEAM: S(sw / 2 - (sz/2) / 2 + (sz/2) - 1, 0, sz / 2, sz / 2);
+ (* left --- x - y -------------- w - h --- *)
+ VK_PREV: S(0, sh - 3.0*sz - 1, sz, sz / 2);
+ VK_LEFT: S(0, sh - 2.0*sz - 1, sz, sz * 2);
+ VK_RIGHT: S(sz, sh - 2.0*sz - 1, sz, sz * 2);
+ (* right - x ------------ y -------------- w - h -- *)
+ VK_NEXT: S(sw - 1*sz - 1, sh - 3.0*sz - 1, sz, sz / 2);
+ VK_UP: S(sw - 2*sz - 1, sh - 2.0*sz - 1, sz, sz / 2);
+ VK_FIRE: S(sw - 2*sz - 1, sh - 1.5*sz - 1, sz, sz);
+ VK_DOWN: S(sw - 2*sz - 1, sh - 0.5*sz - 1, sz, sz / 2);
+ VK_JUMP: S(sw - 1*sz - 1, sh - 2.0*sz - 1, sz, sz);
+ VK_OPEN: S(sw - 1*sz - 1, sh - 1.0*sz - 1, sz, sz);
+ end
else
- result := IK_INVALID
- end
+ case key of
+ (* left ----- x ----- y -------------- w ----- h -- *)
+ VK_ESCAPE: S(0.0*sz, y - 1*sz - sz/2, sz, sz / 2);
+ VK_LSTRAFE: S(0.0*sz, y - 0*sz - sz/2, sz / 2, sz);
+ VK_LEFT: S(0.5*sz, y - 0*sz - sz/2, sz, sz);
+ VK_RIGHT: S(1.5*sz, y - 0*sz - sz/2, sz, sz);
+ VK_RSTRAFE: S(2.5*sz, y - 0*sz - sz/2, sz / 2, sz);
+ (* right - x ------------ y --------------- w - h *)
+ VK_UP: S(sw - 1*sz - 1, y - 1*sz - sz/2, sz, sz);
+ VK_FIRE: S(sw - 1*sz - 1, y - 0*sz - sz/2, sz, sz);
+ VK_DOWN: S(sw - 1*sz - 1, y - -1*sz - sz/2, sz, sz);
+ VK_NEXT: S(sw - 2*sz - 1, y - 1*sz - sz/2, sz, sz);
+ VK_JUMP: S(sw - 2*sz - 1, y - 0*sz - sz/2, sz, sz);
+ VK_PREV: S(sw - 3*sz - 1, y - 1*sz - sz/2, sz, sz);
+ VK_OPEN: S(sw - 3*sz - 1, y - 0*sz - sz/2, sz, sz);
+ (* bottom ---- x -------------------------- y ---------------- w ----- h -- *)
+ VK_CHAT: S(sw/2 - sz/4 - 2*(sz/2) - 1, sh - 2*(sz/2) - 1, sz / 2, sz / 2);
+ VK_CONSOLE: S(sw/2 - sz/4 - 1*(sz/2) - 1, sh - 2*(sz/2) - 1, sz / 2, sz / 2);
+ VK_STATUS: S(sw/2 - sz/4 - 0*(sz/2) - 1, sh - 2*(sz/2) - 1, sz / 2, sz / 2);
+ VK_TEAM: S(sw/2 - sz/4 - -1*(sz/2) - 1, sh - 2*(sz/2) - 1, sz / 2, sz / 2);
+ VS_KEYBOARD: S(sw/2 - sz/4 - -2*(sz/2) - 1, sh - 2*(sz/2) - 1, sz / 2, sz / 2);
+ VK_0: S(sw/2 - sz/4 - 5*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
+ VK_1: S(sw/2 - sz/4 - 4*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
+ VK_2: S(sw/2 - sz/4 - 3*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
+ VK_3: S(sw/2 - sz/4 - 2*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
+ VK_4: S(sw/2 - sz/4 - 1*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
+ VK_5: S(sw/2 - sz/4 - 0*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
+ VK_6: S(sw/2 - sz/4 - -1*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
+ VK_7: S(sw/2 - sz/4 - -2*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
+ VK_8: S(sw/2 - sz/4 - -3*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
+ VK_9: S(sw/2 - sz/4 - -4*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
+ VK_A: S(sw/2 - sz/4 - -5*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
+ end
end;
- function GetControlName(control: Integer): String;
+ function GetKeyName(key: Integer): String;
begin
- case control of
- CTL_LEFT: result := 'LEFT';
- CTL_RIGHT: result := 'RIGHT';
- CTL_UP: result := 'UP';
- CTL_DOWN: result := 'DOWN';
- CTL_OPEN: result := 'OPEN';
- CTL_FIRE: result := 'FIRE';
- CTL_JUMP: result := 'JUMP';
- CTL_CHAT: result := 'CHAT';
- CTL_ESC: result := 'ESC';
- CTL_W0: result := '0';
- CTL_W1: result := '1';
- CTL_W2: result := '2';
- CTL_W3: result := '3';
- CTL_W4: result := '4';
- CTL_W5: result := '5';
- CTL_W6: result := '6';
- CTL_W7: result := '7';
- CTL_W8: result := '8';
- CTL_W9: result := '9';
- CTL_W10: result := '10';
- CTL_CON: result := 'CON';
- CTL_STAT: result := 'STAT';
- CTL_TCHAT: result := 'TEAM';
+ case key of
+ VS_KEYBOARD: result := 'KBD';
+ VS_HIDEKEYBOARD: result := 'KBD';
+ VK_LEFT: result := 'LEFT';
+ VK_RIGHT: result := 'RIGHT';
+ VK_UP: result := 'UP';
+ VK_DOWN: result := 'DOWN';
+ VK_FIRE: result := 'FIRE';
+ VK_OPEN: result := 'OPEN';
+ VK_JUMP: result := 'JUMP';
+ VK_CHAT: result := 'CHAT';
+ VK_ESCAPE: result := 'ESC';
+ VK_0: result := '0';
+ VK_1: result := '1';
+ VK_2: result := '2';
+ VK_3: result := '3';
+ VK_4: result := '4';
+ VK_5: result := '5';
+ VK_6: result := '6';
+ VK_7: result := '7';
+ VK_8: result := '8';
+ VK_9: result := '9';
+ VK_A: result := '10';
+ VK_B: result := '11';
+ VK_C: result := '12';
+ VK_D: result := '13';
+ VK_E: result := '14';
+ VK_F: result := '15';
+ VK_CONSOLE: result := 'CON';
+ VK_STATUS: result := 'STAT';
+ VK_TEAM: result := 'TEAM';
+ VK_PREV: result := '<PREW';
+ VK_NEXT: result := 'NEXT>';
+ VK_LSTRAFE: result := '<';
+ VK_RSTRAFE: result := '>';
else
- result := '(WAT?)'
+ if (key > 0) and (key < e_MaxInputKeys) then
+ result := e_KeyNames[key]
+ else
+ result := '<' + IntToStr(key) + '>'
end
end;
- procedure DrawRect(x, y, w, h: Integer);
- begin
- e_DrawQuad(x, y, x + w, y + h, 0, 255, 0, 127);
- end;
-
function IntersectControl(ctl, xx, yy: Integer): Boolean;
var
x, y, w, h: Integer;
founded: Boolean;
begin
- GetControlRect(ctl, x, y, w, h, founded);
+ GetKeyRect(ctl, x, y, w, h, founded);
result := founded and (xx >= x) and (yy >= y) and (xx <= x + w) and (yy <= y + h);
end;
+ procedure g_Touch_Init;
+ begin
+{$IFNDEF HEADLESS}
+ g_touch_enabled := SDL_GetNumTouchDevices() > 0
+{$ENDIF}
+ end;
+
procedure g_Touch_ShowKeyboard(yes: Boolean);
begin
{$IFNDEF HEADLESS}
- if not enabled then
+ if not g_touch_enabled then
Exit;
if yes then
var
x, y, i, finger: Integer;
begin
- if not enabled then
- Exit;
- if SDL_IsTextInputActive() = SDL_True then
+ if not g_touch_enabled then
Exit;
finger := ev.fingerId + 2;
x := Trunc(ev.x * gScreenWidth);
y := Trunc(ev.y * gScreenHeight);
- for i := 1 to CTL_LAST do
+ for i := VK_FIRSTKEY to VK_LASTKEY do
begin
if IntersectControl(i, x, y) then
begin
keyFinger[i] := finger
else if ev.type_ = SDL_FINGERDOWN then
begin
- KeyPress(GetMenuKey(i));
+ KeyPress(i); // Menu events
keyFinger[i] := finger;
end
end
keyFinger[i] := 0
end;
- e_KeyUpDown(GetPlayerKey(i), keyFinger[i] <> 0);
- e_KeyUpDown(GetMenuKey(i), keyFinger[i] <> 0);
+ e_KeyUpDown(i, keyFinger[i] <> 0);
+ end;
+
+ if IntersectControl(VS_KEYBOARD, x, y) then
+ g_Touch_ShowKeyboard(true);
+ if IntersectControl(VS_HIDEKEYBOARD, x, y) then
+ g_Touch_ShowKeyboard(false);
+
+ (* emulate up+fire / donw+fire *)
+ if g_touch_fire and (gGameSettings.GameType <> GT_NONE) then
+ begin
+ if keyFinger[VK_UP] <> 0 then
+ begin
+ angleFire := true;
+ keyFinger[VK_FIRE] := keyFinger[VK_UP];
+ e_KeyUpDown(VK_FIRE, true);
+ end
+ else if keyFinger[VK_DOWN] <> 0 then
+ begin
+ angleFire := true;
+ keyFinger[VK_FIRE] := keyFinger[VK_DOWN];
+ e_KeyUpDown(VK_FIRE, true);
+ end
+ else if angleFire then
+ begin
+ angleFire := false;
+ keyFinger[VK_FIRE] := 0;
+ e_KeyUpDown(VK_FIRE, false);
+ end
+ end;
+
+ (* left/right strafe *)
+ if gGameSettings.GameType <> GT_NONE then
+ begin
+ if keyFinger[VK_LSTRAFE] <> 0 then
+ begin
+ keyFinger[VK_LEFT] := finger;
+ keyFinger[VK_RIGHT] := 0;
+ keyFinger[VK_STRAFE] := finger;
+ e_KeyUpDown(VK_LEFT, true);
+ e_KeyUpDown(VK_RIGHT, false);
+ e_KeyUpDown(VK_STRAFE, true);
+ end
+ else if keyFinger[VK_RSTRAFE] <> 0 then
+ begin
+ keyFinger[VK_LEFT] := 0;
+ keyFinger[VK_RIGHT] := finger;
+ keyFinger[VK_STRAFE] := finger;
+ e_KeyUpDown(VK_LEFT, false);
+ e_KeyUpDown(VK_RIGHT, true);
+ e_KeyUpDown(VK_STRAFE, true);
+ end
+ else
+ begin
+ keyFinger[VK_STRAFE] := 0;
+ e_KeyUpDown(VK_STRAFE, false);
+ end
+
end;
end;
procedure g_Touch_Draw;
- var
- i, x, y, w, h: Integer;
- founded: Boolean;
- begin
-{$IFNDEF HEADLESS}
- if not enabled then
- Exit;
- if SDL_IsTextInputActive() = SDL_True then
- Exit;
+ var i: Integer;
- for i := 1 to CTL_LAST do
+ procedure Draw (i: Integer);
+ var x, y, w, h: Integer; founded: Boolean;
begin
- GetControlRect(i, x, y, w, h, founded);
+ GetKeyRect(i, x, y, w, h, founded);
if founded then
begin
- DrawRect(x, y, w, h);
- e_TextureFontPrint(x, y, GetControlName(i), gStdFont)
+ e_DrawQuad(x, y, x + w, y + h, 0, 255, 0, 31);
+ e_TextureFontPrintEx(x, y, GetKeyName(i), gStdFont, 255, 255, 255, 1, True)
end;
end;
+
+ begin
+{$IFNDEF HEADLESS}
+ if not g_touch_enabled then
+ Exit;
+
+ for i := VK_FIRSTKEY to VK_LASTKEY do
+ Draw(i);
+
+ Draw(VS_KEYBOARD);
+ Draw(VS_HIDEKEYBOARD);
{$ENDIF}
end;
initialization
-{$IFDEF ANDROID}
- enabled := true;
-{$ENDIF}
- size := 1;
- conRegVar('touch_enable', @enabled, 'enable/disable virtual buttons', 'draw buttons');
- conRegVar('touch_size', @size, 0.1, 10, 'size of virtual buttons', 'button size');
+ conRegVar('touch_enable', @g_touch_enabled, 'enable/disable virtual buttons', 'draw buttons');
+ conRegVar('touch_fire', @g_touch_fire, 'enable/disable fire when press virtual up/down', 'fire when press up/down');
+ conRegVar('touch_size', @g_touch_size, 0.1, 10, 'size of virtual buttons', 'button size');
+ conRegVar('touch_offset', @g_touch_offset, 0, 100, '', '');
+ conRegVar('touch_alt', @g_touch_alt, 'althernative virtual buttons layout', 'althernative layout');
end.
-
-