1 (* Copyright (C) Doom 2D: Forever Developers
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 {$INCLUDE ../shared/a_modes.inc}
25 g_touch_enabled
: Boolean = False;
26 g_touch_size
: Single = 1.0;
27 g_touch_offset
: Single = 50.0;
28 g_touch_fire
: Boolean = True;
29 g_touch_alt
: Boolean = False;
31 procedure g_Touch_Init
;
32 procedure g_Touch_ShowKeyboard(yes
: Boolean);
33 procedure g_Touch_HandleEvent(const ev
: TSDL_TouchFingerEvent
);
34 procedure g_Touch_Draw
;
40 e_log
, e_graphics
, e_input
, g_options
, g_game
, g_main
, g_gui
, g_weapons
, g_console
, g_window
;
44 keyFinger
: array [VK_FIRSTKEY
..VK_LASTKEY
] of Integer;
46 procedure GetKeyRect(key
: Integer; out x
, y
, w
, h
: Integer; out founded
: Boolean);
51 procedure S (xx
, yy
, ww
, hh
: Single);
62 if SDL_GetDisplayDPI(0, @dpi
, nil, nil) <> 0 then
65 sz
:= Trunc(g_touch_size
* dpi
); sw
:= gScreenWidth
; sh
:= gScreenHeight
;
66 x
:= 0; y
:= Round(sh
* g_touch_offset
/ 100);
69 if SDL_IsTextInputActive() = SDL_True
then
71 VK_HIDEKBD
: S(sw
- (sz
/2), 0, sz
/ 2, sz
/ 2);
73 else if g_touch_alt
then
75 (* top ------- x ------------------------------- y w ----- h -- *)
76 VK_CONSOLE
: S(0, 0, sz
/ 2, sz
/ 2);
77 VK_ESCAPE
: S(sw
- 1*(sz
/2) - 1, 0, sz
/ 2, sz
/ 2);
78 VK_SHOWKBD
: S(sw
- 2*(sz
/2) - 1, 0, sz
/ 2, sz
/ 2);
79 VK_CHAT
: S(sw
/ 2 - (sz
/2) / 2 - (sz
/2) - 1, 0, sz
/ 2, sz
/ 2);
80 VK_STATUS
: S(sw
/ 2 - (sz
/2) / 2 - 1, 0, sz
/ 2, sz
/ 2);
81 VK_TEAM
: S(sw
/ 2 - (sz
/2) / 2 + (sz
/2) - 1, 0, sz
/ 2, sz
/ 2);
82 (* left --- x - y -------------- w - h --- *)
83 VK_PREV
: S(0, sh
- 3.0*sz
- 1, sz
, sz
/ 2);
84 VK_LEFT
: S(0, sh
- 2.0*sz
- 1, sz
, sz
* 2);
85 VK_RIGHT
: S(sz
, sh
- 2.0*sz
- 1, sz
, sz
* 2);
86 (* right - x ------------ y -------------- w - h -- *)
87 VK_NEXT
: S(sw
- 1*sz
- 1, sh
- 3.0*sz
- 1, sz
, sz
/ 2);
88 VK_UP
: S(sw
- 2*sz
- 1, sh
- 2.0*sz
- 1, sz
, sz
/ 2);
89 VK_FIRE
: S(sw
- 2*sz
- 1, sh
- 1.5*sz
- 1, sz
, sz
);
90 VK_DOWN
: S(sw
- 2*sz
- 1, sh
- 0.5*sz
- 1, sz
, sz
/ 2);
91 VK_JUMP
: S(sw
- 1*sz
- 1, sh
- 2.0*sz
- 1, sz
, sz
);
92 VK_OPEN
: S(sw
- 1*sz
- 1, sh
- 1.0*sz
- 1, sz
, sz
);
96 (* left ----- x ----- y -------------- w ----- h -- *)
97 VK_ESCAPE
: S(0.0*sz
, y
- 1*sz
- sz
/2, sz
, sz
/ 2);
98 VK_LSTRAFE
: S(0.0*sz
, y
- 0*sz
- sz
/2, sz
/ 2, sz
);
99 VK_LEFT
: S(0.5*sz
, y
- 0*sz
- sz
/2, sz
, sz
);
100 VK_RIGHT
: S(1.5*sz
, y
- 0*sz
- sz
/2, sz
, sz
);
101 VK_RSTRAFE
: S(2.5*sz
, y
- 0*sz
- sz
/2, sz
/ 2, sz
);
102 (* right - x ------------ y --------------- w - h *)
103 VK_UP
: S(sw
- 1*sz
- 1, y
- 1*sz
- sz
/2, sz
, sz
);
104 VK_FIRE
: S(sw
- 1*sz
- 1, y
- 0*sz
- sz
/2, sz
, sz
);
105 VK_DOWN
: S(sw
- 1*sz
- 1, y
- -1*sz
- sz
/2, sz
, sz
);
106 VK_NEXT
: S(sw
- 2*sz
- 1, y
- 1*sz
- sz
/2, sz
, sz
);
107 VK_JUMP
: S(sw
- 2*sz
- 1, y
- 0*sz
- sz
/2, sz
, sz
);
108 VK_PREV
: S(sw
- 3*sz
- 1, y
- 1*sz
- sz
/2, sz
, sz
);
109 VK_OPEN
: S(sw
- 3*sz
- 1, y
- 0*sz
- sz
/2, sz
, sz
);
110 (* bottom ---- x -------------------------- y ---------------- w ----- h -- *)
111 VK_CHAT
: S(sw
/2 - sz
/4 - 2*(sz
/2) - 1, sh
- 2*(sz
/2) - 1, sz
/ 2, sz
/ 2);
112 VK_CONSOLE
: S(sw
/2 - sz
/4 - 1*(sz
/2) - 1, sh
- 2*(sz
/2) - 1, sz
/ 2, sz
/ 2);
113 VK_STATUS
: S(sw
/2 - sz
/4 - 0*(sz
/2) - 1, sh
- 2*(sz
/2) - 1, sz
/ 2, sz
/ 2);
114 VK_TEAM
: S(sw
/2 - sz
/4 - -1*(sz
/2) - 1, sh
- 2*(sz
/2) - 1, sz
/ 2, sz
/ 2);
115 VK_SHOWKBD
: S(sw
/2 - sz
/4 - -2*(sz
/2) - 1, sh
- 2*(sz
/2) - 1, sz
/ 2, sz
/ 2);
116 VK_0
: S(sw
/2 - sz
/4 - 5*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
117 VK_1
: S(sw
/2 - sz
/4 - 4*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
118 VK_2
: S(sw
/2 - sz
/4 - 3*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
119 VK_3
: S(sw
/2 - sz
/4 - 2*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
120 VK_4
: S(sw
/2 - sz
/4 - 1*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
121 VK_5
: S(sw
/2 - sz
/4 - 0*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
122 VK_6
: S(sw
/2 - sz
/4 - -1*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
123 VK_7
: S(sw
/2 - sz
/4 - -2*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
124 VK_8
: S(sw
/2 - sz
/4 - -3*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
125 VK_9
: S(sw
/2 - sz
/4 - -4*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
126 VK_A
: S(sw
/2 - sz
/4 - -5*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
130 function GetKeyName(key
: Integer): String;
133 VK_SHOWKBD
: result
:= 'KBD';
134 VK_HIDEKBD
: result
:= 'KBD';
135 VK_LEFT
: result
:= 'LEFT';
136 VK_RIGHT
: result
:= 'RIGHT';
137 VK_UP
: result
:= 'UP';
138 VK_DOWN
: result
:= 'DOWN';
139 VK_FIRE
: result
:= 'FIRE';
140 VK_OPEN
: result
:= 'OPEN';
141 VK_JUMP
: result
:= 'JUMP';
142 VK_CHAT
: result
:= 'CHAT';
143 VK_ESCAPE
: result
:= 'ESC';
154 VK_A
: result
:= '10';
155 VK_B
: result
:= '11';
156 VK_C
: result
:= '12';
157 VK_D
: result
:= '13';
158 VK_E
: result
:= '14';
159 VK_F
: result
:= '15';
160 VK_CONSOLE
: result
:= 'CON';
161 VK_STATUS
: result
:= 'STAT';
162 VK_TEAM
: result
:= 'TEAM';
163 VK_PREV
: result
:= '<PREW';
164 VK_NEXT
: result
:= 'NEXT>';
165 VK_LSTRAFE
: result
:= '<';
166 VK_RSTRAFE
: result
:= '>';
168 if (key
> 0) and (key
< e_MaxInputKeys
) then
169 result
:= e_KeyNames
[key
]
171 result
:= '<' + IntToStr(key
) + '>'
175 function IntersectControl(ctl
, xx
, yy
: Integer): Boolean;
180 GetKeyRect(ctl
, x
, y
, w
, h
, founded
);
181 result
:= founded
and (xx
>= x
) and (yy
>= y
) and (xx
<= x
+ w
) and (yy
<= y
+ h
);
184 procedure g_Touch_Init
;
187 g_Touch_ShowKeyboard(FALSE);
188 g_touch_enabled
:= SDL_GetNumTouchDevices() > 0
192 procedure g_Touch_ShowKeyboard(yes
: Boolean);
196 e_LogWritefln('g_Touch_ShowKeyboard(%s)', [yes
]);
204 procedure g_Touch_HandleEvent(const ev
: TSDL_TouchFingerEvent
);
206 x
, y
, i
, finger
: Integer;
208 procedure KeyUp (finger
, i
: Integer);
211 e_LogWritefln('Input Debug: g_touch.KeyUp, finger=%s, key=%s', [finger
, i
]);
214 e_KeyUpDown(i
, False);
215 g_Console_ProcessBind(i
, False);
217 (* up/down + fire hack *)
218 if g_touch_fire
and (gGameSettings
.GameType
<> GT_NONE
) and (g_ActiveWindow
= nil) and angleFire
then
220 if (i
= VK_UP
) or (i
= VK_DOWN
) then
223 keyFinger
[VK_FIRE
] := 0;
224 e_KeyUpDown(VK_FIRE
, False);
225 g_Console_ProcessBind(VK_FIRE
, False)
230 procedure KeyDown (finger
, i
: Integer);
233 e_LogWritefln('Input Debug: g_touch.KeyDown, finger=%s, key=%s', [finger
, i
]);
235 keyFinger
[i
] := finger
;
236 e_KeyUpDown(i
, True);
237 g_Console_ProcessBind(i
, True);
239 (* up/down + fire hack *)
240 if g_touch_fire
and (gGameSettings
.GameType
<> GT_NONE
) and (g_ActiveWindow
= nil) then
245 keyFinger
[VK_FIRE
] := -1;
246 e_KeyUpDown(VK_FIRE
, True);
247 g_Console_ProcessBind(VK_FIRE
, True)
249 else if i
= VK_DOWN
then
252 keyFinger
[VK_FIRE
] := -1;
253 e_KeyUpDown(VK_FIRE
, True);
254 g_Console_ProcessBind(VK_FIRE
, True)
259 procedure KeyMotion (finger
, i
: Integer);
261 if keyFinger
[i
] <> finger
then
269 if not g_touch_enabled
then
272 finger
:= ev
.fingerId
+ 2;
273 x
:= Trunc(ev
.x
* gScreenWidth
);
274 y
:= Trunc(ev
.y
* gScreenHeight
);
276 for i
:= VK_FIRSTKEY
to VK_LASTKEY
do
278 if IntersectControl(i
, x
, y
) then
280 if ev
.type_
= SDL_FINGERUP
then
282 else if ev
.type_
= SDL_FINGERMOTION
then
284 else if ev
.type_
= SDL_FINGERDOWN
then
287 else if keyFinger
[i
] = finger
then
289 if ev
.type_
= SDL_FINGERUP
then
291 else if ev
.type_
= SDL_FINGERMOTION
then
297 procedure g_Touch_Draw
;
298 var i
, x
, y
, w
, h
: Integer; founded
: Boolean;
301 if not g_touch_enabled
then
304 for i
:= VK_FIRSTKEY
to VK_LASTKEY
do
306 GetKeyRect(i
, x
, y
, w
, h
, founded
);
309 e_DrawQuad(x
, y
, x
+ w
, y
+ h
, 0, 255, 0, 31);
310 e_TextureFontPrintEx(x
, y
, GetKeyName(i
), gStdFont
, 255, 255, 255, 1, True)
317 conRegVar('touch_enable', @g_touch_enabled
, 'enable/disable virtual buttons', 'draw buttons');
318 conRegVar('touch_fire', @g_touch_fire
, 'enable/disable fire when press virtual up/down', 'fire when press up/down');
319 conRegVar('touch_size', @g_touch_size
, 0.1, 10, 'size of virtual buttons', 'button size');
320 conRegVar('touch_offset', @g_touch_offset
, 0, 100, '', '');
321 conRegVar('touch_alt', @g_touch_alt
, 'althernative virtual buttons layout', 'althernative layout');