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, version 3 of the License ONLY.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 {$INCLUDE ../shared/a_modes.inc}
24 g_touch_enabled
: Boolean = False;
25 g_touch_size
: Single = 1.0;
26 g_touch_offset
: Single = 50.0;
27 g_touch_fire
: Boolean = True;
28 g_touch_alt
: Boolean = False;
30 procedure g_Touch_Init
;
31 procedure g_Touch_ShowKeyboard(yes
: Boolean);
32 procedure g_Touch_HandleEvent(const ev
: TSDL_TouchFingerEvent
);
33 procedure g_Touch_Draw
;
39 e_log
, e_graphics
, e_input
, g_options
, g_game
, g_main
, g_gui
, g_weapons
, g_console
, g_window
;
43 keyFinger
: array [VK_FIRSTKEY
..VK_LASTKEY
] of Integer;
45 procedure GetKeyRect(key
: Integer; out x
, y
, w
, h
: Integer; out founded
: Boolean);
50 procedure S (xx
, yy
, ww
, hh
: Single);
62 if SDL_GetDisplayDPI(0, @dpi
, nil, nil) <> 0 then
68 sz
:= Trunc(g_touch_size
* dpi
); sw
:= gWinSizeX
; sh
:= gWinSizeY
;
69 x
:= 0; y
:= Round(sh
* g_touch_offset
/ 100);
72 if SDL_IsTextInputActive() = SDL_True
then
74 VK_HIDEKBD
: S(sw
- (sz
/2), 0, sz
/ 2, sz
/ 2);
76 else if g_touch_alt
then
78 (* top ------- x ------------------------------- y w ----- h -- *)
79 VK_CONSOLE
: S(0, 0, sz
/ 2, sz
/ 2);
80 VK_ESCAPE
: S(sw
- 1*(sz
/2) - 1, 0, sz
/ 2, sz
/ 2);
81 VK_SHOWKBD
: S(sw
- 2*(sz
/2) - 1, 0, sz
/ 2, sz
/ 2);
82 VK_CHAT
: S(sw
/ 2 - (sz
/2) / 2 - (sz
/2) - 1, 0, sz
/ 2, sz
/ 2);
83 VK_STATUS
: S(sw
/ 2 - (sz
/2) / 2 - 1, 0, sz
/ 2, sz
/ 2);
84 VK_TEAM
: S(sw
/ 2 - (sz
/2) / 2 + (sz
/2) - 1, 0, sz
/ 2, sz
/ 2);
85 (* left --- x - y -------------- w - h --- *)
86 VK_PREV
: S(0, sh
- 3.0*sz
- 1, sz
, sz
/ 2);
87 VK_LEFT
: S(0, sh
- 2.0*sz
- 1, sz
, sz
* 2);
88 VK_RIGHT
: S(sz
, sh
- 2.0*sz
- 1, sz
, sz
* 2);
89 (* right - x ------------ y -------------- w - h -- *)
90 VK_NEXT
: S(sw
- 1*sz
- 1, sh
- 3.0*sz
- 1, sz
, sz
/ 2);
91 VK_UP
: S(sw
- 2*sz
- 1, sh
- 2.0*sz
- 1, sz
, sz
/ 2);
92 VK_FIRE
: S(sw
- 2*sz
- 1, sh
- 1.5*sz
- 1, sz
, sz
);
93 VK_DOWN
: S(sw
- 2*sz
- 1, sh
- 0.5*sz
- 1, sz
, sz
/ 2);
94 VK_JUMP
: S(sw
- 1*sz
- 1, sh
- 2.0*sz
- 1, sz
, sz
);
95 VK_OPEN
: S(sw
- 1*sz
- 1, sh
- 1.0*sz
- 1, sz
, sz
);
99 (* left ----- x ----- y -------------- w ----- h -- *)
100 VK_ESCAPE
: S(0.0*sz
, y
- 1*sz
- sz
/2, sz
, sz
/ 2);
101 VK_LSTRAFE
: S(0.0*sz
, y
- 0*sz
- sz
/2, sz
/ 2, sz
);
102 VK_LEFT
: S(0.5*sz
, y
- 0*sz
- sz
/2, sz
, sz
);
103 VK_RIGHT
: S(1.5*sz
, y
- 0*sz
- sz
/2, sz
, sz
);
104 VK_RSTRAFE
: S(2.5*sz
, y
- 0*sz
- sz
/2, sz
/ 2, sz
);
105 (* right - x ------------ y --------------- w - h *)
106 VK_UP
: S(sw
- 1*sz
- 1, y
- 1*sz
- sz
/2, sz
, sz
);
107 VK_FIRE
: S(sw
- 1*sz
- 1, y
- 0*sz
- sz
/2, sz
, sz
);
108 VK_DOWN
: S(sw
- 1*sz
- 1, y
- -1*sz
- sz
/2, sz
, sz
);
109 VK_NEXT
: S(sw
- 2*sz
- 1, y
- 1*sz
- sz
/2, sz
, sz
);
110 VK_JUMP
: S(sw
- 2*sz
- 1, y
- 0*sz
- sz
/2, sz
, sz
);
111 VK_PREV
: S(sw
- 3*sz
- 1, y
- 1*sz
- sz
/2, sz
, sz
);
112 VK_OPEN
: S(sw
- 3*sz
- 1, y
- 0*sz
- sz
/2, sz
, sz
);
113 (* bottom ---- x -------------------------- y ---------------- w ----- h -- *)
114 VK_CHAT
: S(sw
/2 - sz
/4 - 2*(sz
/2) - 1, sh
- 2*(sz
/2) - 1, sz
/ 2, sz
/ 2);
115 VK_CONSOLE
: S(sw
/2 - sz
/4 - 1*(sz
/2) - 1, sh
- 2*(sz
/2) - 1, sz
/ 2, sz
/ 2);
116 VK_STATUS
: S(sw
/2 - sz
/4 - 0*(sz
/2) - 1, sh
- 2*(sz
/2) - 1, sz
/ 2, sz
/ 2);
117 VK_TEAM
: S(sw
/2 - sz
/4 - -1*(sz
/2) - 1, sh
- 2*(sz
/2) - 1, sz
/ 2, sz
/ 2);
118 VK_SHOWKBD
: S(sw
/2 - sz
/4 - -2*(sz
/2) - 1, sh
- 2*(sz
/2) - 1, sz
/ 2, sz
/ 2);
119 VK_0
: S(sw
/2 - sz
/4 - 5*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
120 VK_1
: S(sw
/2 - sz
/4 - 4*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
121 VK_2
: S(sw
/2 - sz
/4 - 3*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
122 VK_3
: S(sw
/2 - sz
/4 - 2*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
123 VK_4
: S(sw
/2 - sz
/4 - 1*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
124 VK_5
: S(sw
/2 - sz
/4 - 0*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
125 VK_6
: S(sw
/2 - sz
/4 - -1*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
126 VK_7
: S(sw
/2 - sz
/4 - -2*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
127 VK_8
: S(sw
/2 - sz
/4 - -3*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
128 VK_9
: S(sw
/2 - sz
/4 - -4*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
129 VK_A
: S(sw
/2 - sz
/4 - -5*(sz
/2) - 1, sh
- 1*(sz
/2) - 1, sz
/ 2, sz
/ 2);
133 function GetKeyName(key
: Integer): String;
136 VK_SHOWKBD
: result
:= 'KBD';
137 VK_HIDEKBD
: result
:= 'KBD';
138 VK_LEFT
: result
:= 'LEFT';
139 VK_RIGHT
: result
:= 'RIGHT';
140 VK_UP
: result
:= 'UP';
141 VK_DOWN
: result
:= 'DOWN';
142 VK_FIRE
: result
:= 'FIRE';
143 VK_OPEN
: result
:= 'OPEN';
144 VK_JUMP
: result
:= 'JUMP';
145 VK_CHAT
: result
:= 'CHAT';
146 VK_ESCAPE
: result
:= 'ESC';
157 VK_A
: result
:= '10';
158 VK_B
: result
:= '11';
159 VK_C
: result
:= '12';
160 VK_D
: result
:= '13';
161 VK_E
: result
:= '14';
162 VK_F
: result
:= '15';
163 VK_CONSOLE
: result
:= 'CON';
164 VK_STATUS
: result
:= 'STAT';
165 VK_TEAM
: result
:= 'TEAM';
166 VK_PREV
: result
:= '<PREW';
167 VK_NEXT
: result
:= 'NEXT>';
168 VK_LSTRAFE
: result
:= '<';
169 VK_RSTRAFE
: result
:= '>';
171 if (key
> 0) and (key
< e_MaxInputKeys
) then
172 result
:= e_KeyNames
[key
]
174 result
:= '<' + IntToStr(key
) + '>'
178 function IntersectControl(ctl
, xx
, yy
: Integer): Boolean;
183 GetKeyRect(ctl
, x
, y
, w
, h
, founded
);
184 result
:= founded
and (xx
>= x
) and (yy
>= y
) and (xx
<= x
+ w
) and (yy
<= y
+ h
);
187 procedure g_Touch_Init
;
190 g_Touch_ShowKeyboard(FALSE);
191 g_touch_enabled
:= SDL_GetNumTouchDevices() > 0
195 procedure g_Touch_ShowKeyboard(yes
: Boolean);
199 e_LogWritefln('g_Touch_ShowKeyboard(%s)', [yes
]);
200 (* on desktop we always receive text (needed for cheats) *)
201 if yes
or (SDL_HasScreenKeyboardSupport() = SDL_FALSE
) then
208 procedure g_Touch_HandleEvent(const ev
: TSDL_TouchFingerEvent
);
210 x
, y
, i
, finger
: Integer;
212 procedure KeyUp (finger
, i
: Integer);
215 e_LogWritefln('Input Debug: g_touch.KeyUp, finger=%s, key=%s', [finger
, i
]);
218 e_KeyUpDown(i
, False);
219 g_Console_ProcessBind(i
, False);
221 (* up/down + fire hack *)
222 if g_touch_fire
and (gGameSettings
.GameType
<> GT_NONE
) and (g_ActiveWindow
= nil) and angleFire
then
224 if (i
= VK_UP
) or (i
= VK_DOWN
) then
227 keyFinger
[VK_FIRE
] := 0;
228 e_KeyUpDown(VK_FIRE
, False);
229 g_Console_ProcessBind(VK_FIRE
, False)
234 procedure KeyDown (finger
, i
: Integer);
237 e_LogWritefln('Input Debug: g_touch.KeyDown, finger=%s, key=%s', [finger
, i
]);
239 keyFinger
[i
] := finger
;
240 e_KeyUpDown(i
, True);
241 g_Console_ProcessBind(i
, True);
243 (* up/down + fire hack *)
244 if g_touch_fire
and (gGameSettings
.GameType
<> GT_NONE
) and (g_ActiveWindow
= nil) then
249 keyFinger
[VK_FIRE
] := -1;
250 e_KeyUpDown(VK_FIRE
, True);
251 g_Console_ProcessBind(VK_FIRE
, True)
253 else if i
= VK_DOWN
then
256 keyFinger
[VK_FIRE
] := -1;
257 e_KeyUpDown(VK_FIRE
, True);
258 g_Console_ProcessBind(VK_FIRE
, True)
263 procedure KeyMotion (finger
, i
: Integer);
265 if keyFinger
[i
] <> finger
then
273 if not g_touch_enabled
then
276 finger
:= ev
.fingerId
+ 2;
277 x
:= Trunc(ev
.x
* gWinSizeX
);
278 y
:= Trunc(ev
.y
* gWinSizeY
);
280 for i
:= VK_FIRSTKEY
to VK_LASTKEY
do
282 if IntersectControl(i
, x
, y
) then
284 if ev
.type_
= SDL_FINGERUP
then
286 else if ev
.type_
= SDL_FINGERMOTION
then
288 else if ev
.type_
= SDL_FINGERDOWN
then
291 else if keyFinger
[i
] = finger
then
293 if ev
.type_
= SDL_FINGERUP
then
295 else if ev
.type_
= SDL_FINGERMOTION
then
301 procedure g_Touch_Draw
;
302 var i
, x
, y
, w
, h
: Integer; founded
: Boolean;
305 if not g_touch_enabled
then
308 for i
:= VK_FIRSTKEY
to VK_LASTKEY
do
310 GetKeyRect(i
, x
, y
, w
, h
, founded
);
313 e_DrawQuad(x
, y
, x
+ w
, y
+ h
, 0, 255, 0, 31);
314 e_TextureFontPrintEx(x
, y
, GetKeyName(i
), gStdFont
, 255, 255, 255, 1, True)
321 conRegVar('touch_enable', @g_touch_enabled
, 'enable/disable virtual buttons', 'draw buttons');
322 conRegVar('touch_fire', @g_touch_fire
, 'enable/disable fire when press virtual up/down', 'fire when press up/down');
323 conRegVar('touch_size', @g_touch_size
, 0.1, 10, 'size of virtual buttons', 'button size');
324 conRegVar('touch_offset', @g_touch_offset
, 0, 100, '', '');
325 conRegVar('touch_alt', @g_touch_alt
, 'althernative virtual buttons layout', 'althernative layout');