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;
27 g_touch_offset
: Single;
28 g_touch_fire
: Boolean;
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_weapons
, g_console
;
47 keyFinger
: array [VK_FIRSTKEY
..VK_LASTKEY
] of Integer;
49 procedure GetKeyRect(key
: Integer; out x
, y
, w
, h
: Integer; out founded
: Boolean);
54 if SDL_GetDisplayDPI(0, @dpi
, nil, nil) <> 0 then
58 sz
:= Trunc(g_touch_size
* dpi
);
59 sw
:= gScreenWidth
; sh
:= gScreenHeight
;
62 w
:= sz
div 2; h
:= sz
div 2;
64 VK_CONSOLE
: begin x
:= 0; y
:= 0 end;
65 VK_ESCAPE
: begin x
:= sw
- 1*w
- 1; y
:= 0 end;
66 VS_KEYBOARD
:begin x
:= sw
- 2*w
- 1; y
:= 0 end;
67 VK_CHAT
: begin x
:= sw
div 2 - w
div 2 - w
; y
:= 0 end;
68 VK_STATUS
: begin x
:= sw
div 2 - w
div 2 + 0; y
:= 0 end;
69 VK_TEAM
: begin x
:= sw
div 2 - w
div 2 + w
; y
:= 0 end;
70 VK_PREV
: begin x
:= 0; y
:= sh
- 4*sz
- 1; w
:= sz
end;
71 VK_NEXT
: begin x
:= sw
- sz
- 1; y
:= sh
- 4*sz
- 1; w
:= sz
end;
75 VK_LEFT
: begin x
:= 0; y
:= sh
- h
- 1 end;
76 VK_RIGHT
: begin x
:= w
; y
:= sh
- h
- 1 end;
80 VK_UP
: begin x
:= sw
- 2*w
- 1; y
:= sh
- 3*h
- 1 end;
81 VK_FIRE
: begin x
:= sw
- 2*w
- 1; y
:= sh
- 2*h
- 1 end;
82 VK_DOWN
: begin x
:= sw
- 2*w
- 1; y
:= sh
- 1*h
- 1 end;
83 VK_OPEN
: begin x
:= sw
- 1*w
- 1; y
:= sh
- 1*h
- h
div 2 - 1 end;
84 VK_JUMP
: begin x
:= sw
- 1*w
- 1; y
:= sh
- 2*h
- h
div 2 - 1 end;
93 x
:= 0; y
:= Round(sh
* g_touch_offset
/ 100); w
:= sz
; h
:= sz
;
95 VK_ESCAPE
: begin x
:= 0; y
:= y
- 3*h
div 2; w
:= w
; h
:= h
div 2 end;
96 VK_LSTRAFE
: begin x
:= 0; y
:= y
- h
div 2; w
:= w
div 2 end;
97 VK_LEFT
: begin x
:= w
div 2; y
:= y
- h
div 2 end;
98 VK_RIGHT
: begin x
:= w
div 2 + 1*w
; y
:= y
- h
div 2 end;
99 VK_RSTRAFE
: begin x
:= w
div 2 + 2*w
; y
:= y
- h
div 2; w
:= w
div 2 end;
100 VK_UP
: begin x
:= sw
- w
- 1; y
:= y
- h
div 2 - h
end;
101 VK_FIRE
: begin x
:= sw
- 1*w
- 1; y
:= y
- h
div 2 end;
102 VK_DOWN
: begin x
:= sw
- w
- 1; y
:= y
- h
div 2 + h
end;
103 VK_NEXT
: begin x
:= sw
- 2*w
- 1; y
:= y
- h
div 2 - h
end;
104 VK_JUMP
: begin x
:= sw
- 2*w
- 1; y
:= y
- h
div 2 end;
105 VK_PREV
: begin x
:= sw
- 3*w
- 1; y
:= y
- h
div 2 - h
end;
106 VK_OPEN
: begin x
:= sw
- 3*w
- 1; y
:= y
- h
div 2 end;
108 x
:= 0; y
:= 0; w
:= sz
div 2; h
:= sz
div 2;
110 VK_0
: begin x
:= sw
div 2 - w
div 2 - 5*w
- 1; y
:= sh
- 1*h
- 1 end;
111 VK_1
: begin x
:= sw
div 2 - w
div 2 - 4*w
- 1; y
:= sh
- 1*h
- 1 end;
112 VK_2
: begin x
:= sw
div 2 - w
div 2 - 3*w
- 1; y
:= sh
- 1*h
- 1 end;
113 VK_3
: begin x
:= sw
div 2 - w
div 2 - 2*w
- 1; y
:= sh
- 1*h
- 1 end;
114 VK_4
: begin x
:= sw
div 2 - w
div 2 - 1*w
- 1; y
:= sh
- 1*h
- 1 end;
115 VK_5
: begin x
:= sw
div 2 - w
div 2 + 0*w
- 1; y
:= sh
- 1*h
- 1 end;
116 VK_6
: begin x
:= sw
div 2 - w
div 2 + 1*w
- 1; y
:= sh
- 1*h
- 1 end;
117 VK_7
: begin x
:= sw
div 2 - w
div 2 + 2*w
- 1; y
:= sh
- 1*h
- 1 end;
118 VK_8
: begin x
:= sw
div 2 - w
div 2 + 3*w
- 1; y
:= sh
- 1*h
- 1 end;
119 VK_9
: begin x
:= sw
div 2 - w
div 2 + 4*w
- 1; y
:= sh
- 1*h
- 1 end;
120 VK_A
: begin x
:= sw
div 2 - w
div 2 + 5*w
- 1; y
:= sh
- 1*h
- 1 end;
121 VK_CHAT
: begin x
:= sw
div 2 - w
div 2 - 2*w
- 1; y
:= sh
- 2*h
- 1 end;
122 VK_CONSOLE
: begin x
:= sw
div 2 - w
div 2 - 1*w
- 1; y
:= sh
- 2*h
- 1 end;
123 VK_STATUS
: begin x
:= sw
div 2 - w
div 2 + 0*w
- 1; y
:= sh
- 2*h
- 1 end;
124 VK_TEAM
: begin x
:= sw
div 2 - w
div 2 + 1*w
- 1; y
:= sh
- 2*h
- 1 end;
125 VS_KEYBOARD
:begin x
:= sw
div 2 - w
div 2 + 2*w
- 1; y
:= sh
- 2*h
- 1 end;
133 function GetKeyName(key
: Integer): String;
136 VS_KEYBOARD
: result
:= 'KBD';
137 VK_LEFT
: result
:= 'LEFT';
138 VK_RIGHT
: result
:= 'RIGHT';
139 VK_UP
: result
:= 'UP';
140 VK_DOWN
: result
:= 'DOWN';
141 VK_FIRE
: result
:= 'FIRE';
142 VK_OPEN
: result
:= 'OPEN';
143 VK_JUMP
: result
:= 'JUMP';
144 VK_CHAT
: result
:= 'CHAT';
145 VK_ESCAPE
: result
:= 'ESC';
156 VK_A
: result
:= '10';
157 VK_B
: result
:= '11';
158 VK_C
: result
:= '12';
159 VK_D
: result
:= '13';
160 VK_E
: result
:= '14';
161 VK_F
: result
:= '15';
162 VK_CONSOLE
: result
:= 'CON';
163 VK_STATUS
: result
:= 'STAT';
164 VK_TEAM
: result
:= 'TEAM';
165 VK_PREV
: result
:= '<PREW';
166 VK_NEXT
: result
:= 'NEXT>';
167 VK_LSTRAFE
: result
:= '<';
168 VK_RSTRAFE
: result
:= '>';
170 if (key
> 0) and (key
< e_MaxInputKeys
) then
171 result
:= e_KeyNames
[key
]
173 result
:= '<' + IntToStr(key
) + '>'
177 function IntersectControl(ctl
, xx
, yy
: Integer): Boolean;
182 GetKeyRect(ctl
, x
, y
, w
, h
, founded
);
183 result
:= founded
and (xx
>= x
) and (yy
>= y
) and (xx
<= x
+ w
) and (yy
<= y
+ h
);
186 procedure g_Touch_Init
;
189 g_touch_enabled
:= SDL_GetNumTouchDevices() > 0
193 procedure g_Touch_ShowKeyboard(yes
: Boolean);
196 if not g_touch_enabled
then
206 procedure g_Touch_HandleEvent(const ev
: TSDL_TouchFingerEvent
);
208 x
, y
, i
, finger
: Integer;
210 if not g_touch_enabled
then
212 if SDL_IsTextInputActive() = SDL_True
then
215 finger
:= ev
.fingerId
+ 2;
216 x
:= Trunc(ev
.x
* gScreenWidth
);
217 y
:= Trunc(ev
.y
* gScreenHeight
);
219 for i
:= VK_FIRSTKEY
to VK_LASTKEY
do
221 if IntersectControl(i
, x
, y
) then
223 if ev
.type_
= SDL_FINGERUP
then
225 else if ev
.type_
= SDL_FINGERMOTION
then
226 keyFinger
[i
] := finger
227 else if ev
.type_
= SDL_FINGERDOWN
then
229 KeyPress(i
); // Menu events
230 keyFinger
[i
] := finger
;
233 else if keyFinger
[i
] = finger
then
235 if ev
.type_
= SDL_FINGERUP
then
237 else if ev
.type_
= SDL_FINGERMOTION
then
241 e_KeyUpDown(i
, keyFinger
[i
] <> 0);
244 if IntersectControl(VS_KEYBOARD
, x
, y
) then
245 g_Touch_ShowKeyboard(true);
247 (* emulate up+fire / donw+fire *)
248 if g_touch_fire
and (gGameSettings
.GameType
<> GT_NONE
) then
250 if keyFinger
[VK_UP
] <> 0 then
253 keyFinger
[VK_FIRE
] := keyFinger
[VK_UP
];
254 e_KeyUpDown(VK_FIRE
, true);
256 else if keyFinger
[VK_DOWN
] <> 0 then
259 keyFinger
[VK_FIRE
] := keyFinger
[VK_DOWN
];
260 e_KeyUpDown(VK_FIRE
, true);
262 else if angleFire
then
265 keyFinger
[VK_FIRE
] := 0;
266 e_KeyUpDown(VK_FIRE
, false);
270 (* left/right strafe *)
271 if gGameSettings
.GameType
<> GT_NONE
then
273 if keyFinger
[VK_LSTRAFE
] <> 0 then
275 keyFinger
[VK_LEFT
] := finger
;
276 keyFinger
[VK_RIGHT
] := 0;
277 keyFinger
[VK_STRAFE
] := finger
;
278 e_KeyUpDown(VK_LEFT
, true);
279 e_KeyUpDown(VK_RIGHT
, false);
280 e_KeyUpDown(VK_STRAFE
, true);
282 else if keyFinger
[VK_RSTRAFE
] <> 0 then
284 keyFinger
[VK_LEFT
] := 0;
285 keyFinger
[VK_RIGHT
] := finger
;
286 keyFinger
[VK_STRAFE
] := finger
;
287 e_KeyUpDown(VK_LEFT
, false);
288 e_KeyUpDown(VK_RIGHT
, true);
289 e_KeyUpDown(VK_STRAFE
, true);
293 keyFinger
[VK_STRAFE
] := 0;
294 e_KeyUpDown(VK_STRAFE
, false);
299 procedure g_Touch_Draw
;
302 procedure Draw (i
: Integer);
303 var x
, y
, w
, h
: Integer; founded
: Boolean;
305 GetKeyRect(i
, x
, y
, w
, h
, founded
);
308 e_DrawQuad(x
, y
, x
+ w
, y
+ h
, 0, 255, 0, 31);
309 e_TextureFontPrintEx(x
, y
, GetKeyName(i
), gStdFont
, 255, 255, 255, 1, True)
315 if not g_touch_enabled
then
317 if SDL_IsTextInputActive() = SDL_True
then
320 for i
:= VK_FIRSTKEY
to VK_LASTKEY
do
328 conRegVar('touch_enable', @g_touch_enabled
, 'enable/disable virtual buttons', 'draw buttons');
329 conRegVar('touch_fire', @g_touch_fire
, 'enable/disable fire when press virtual up/down', 'fire when press up/down');
330 conRegVar('touch_size', @g_touch_size
, 0.1, 10, 'size of virtual buttons', 'button size');
331 conRegVar('touch_offset', @g_touch_offset
, 0, 100, '', '');
332 conRegVar('touch_alt', @g_touch_alt
, 'althernative virtual buttons layout', 'althernative layout');