X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_touch.pas;h=0638cc2713bfbfb432e484160ff431faa77adcbf;hb=31039aaf7e1623de1a4be292d0c77532fcfbf3e6;hp=0a02e577bf040487632ffbcbf09fd1e52540b38f;hpb=1b5401f0727c171cf02d4484624bb3198f7a10bd;p=d2df-sdl.git diff --git a/src/game/g_touch.pas b/src/game/g_touch.pas index 0a02e57..0638cc2 100644 --- a/src/game/g_touch.pas +++ b/src/game/g_touch.pas @@ -21,6 +21,14 @@ interface uses SDL2; + var + g_touch_enabled: Boolean = False; + g_touch_size: Single = 1.0; + g_touch_offset: Single = 50.0; + g_touch_fire: Boolean = True; + g_touch_alt: Boolean = False; + + procedure g_Touch_Init; procedure g_Touch_ShowKeyboard(yes: Boolean); procedure g_Touch_HandleEvent(const ev: TSDL_TouchFingerEvent); procedure g_Touch_Draw; @@ -31,190 +39,159 @@ implementation SysUtils, 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; - 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 + VK_HIDEKBD: 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); + VK_SHOWKBD: 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); + VK_SHOWKBD: 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 + VK_SHOWKBD: result := 'KBD'; + VK_HIDEKBD: 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 := ' 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 @@ -227,73 +204,114 @@ implementation procedure g_Touch_HandleEvent(const ev: TSDL_TouchFingerEvent); var x, y, i, finger: Integer; + + procedure KeyUp (finger, i: Integer); + begin + keyFinger[i] := 0; + e_KeyUpDown(i, False); + g_Console_ProcessBind(i, False); + + (* up/down + fire hack *) + if g_touch_fire and (gGameSettings.GameType <> GT_NONE) and angleFire then + begin + if (i = VK_UP) or (i = VK_DOWN) then + begin + angleFire := False; + keyFinger[VK_FIRE] := 0; + e_KeyUpDown(VK_FIRE, False); + g_Console_ProcessBind(VK_FIRE, False) + end + end + end; + + procedure KeyDown (finger, i: Integer); + begin + KeyPress(i); // Menu events + keyFinger[i] := finger; + e_KeyUpDown(i, True); + g_Console_ProcessBind(i, True); + + (* up/down + fire hack *) + if g_touch_fire and (gGameSettings.GameType <> GT_NONE) then + begin + if i = VK_UP then + begin + angleFire := True; + keyFinger[VK_FIRE] := -1; + e_KeyUpDown(VK_FIRE, True); + g_Console_ProcessBind(VK_FIRE, True) + end + else if i = VK_DOWN then + begin + angleFire := True; + keyFinger[VK_FIRE] := -1; + e_KeyUpDown(VK_FIRE, True); + g_Console_ProcessBind(VK_FIRE, True) + end + end + end; + + procedure KeyMotion (finger, i: Integer); + begin + if keyFinger[i] <> finger then + begin + KeyUp(finger, i); + KeyDown(finger, i) + end + end; + 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 if ev.type_ = SDL_FINGERUP then - keyFinger[i] := 0 + KeyUp(finger, i) else if ev.type_ = SDL_FINGERMOTION then - keyFinger[i] := finger + KeyMotion(finger, i) else if ev.type_ = SDL_FINGERDOWN then - begin - KeyPress(GetMenuKey(i)); - keyFinger[i] := finger; - end + keyDown(finger, i) end else if keyFinger[i] = finger then begin if ev.type_ = SDL_FINGERUP then - keyFinger[i] := 0 + KeyUp(finger, i) else if ev.type_ = SDL_FINGERMOTION then - keyFinger[i] := 0 - end; - - e_KeyUpDown(GetPlayerKey(i), keyFinger[i] <> 0); - e_KeyUpDown(GetMenuKey(i), keyFinger[i] <> 0); - end; + KeyUp(finger, i) + end + end end; procedure g_Touch_Draw; - var - i, x, y, w, h: Integer; - founded: Boolean; + var i, x, y, w, h: Integer; founded: Boolean; begin {$IFNDEF HEADLESS} - if not enabled then - Exit; - if SDL_IsTextInputActive() = SDL_True then + if not g_touch_enabled then Exit; - for i := 1 to CTL_LAST do + for i := VK_FIRSTKEY to VK_LASTKEY do 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) - end; - end; + 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 {$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. - -