DEADSOFTWARE

0a02e577bf040487632ffbcbf09fd1e52540b38f
[d2df-sdl.git] / src / game / g_touch.pas
1 (* Copyright (C) Doom 2D: Forever Developers
2 *
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.
7 *
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.
12 *
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/>.
15 *)
16 {$INCLUDE ../shared/a_modes.inc}
17 unit g_touch;
19 interface
21 uses
22 SDL2;
24 procedure g_Touch_ShowKeyboard(yes: Boolean);
25 procedure g_Touch_HandleEvent(const ev: TSDL_TouchFingerEvent);
26 procedure g_Touch_Draw;
28 implementation
30 uses
31 SysUtils,
32 e_log, e_graphics, e_input, g_options, g_game, g_main, g_weapons, g_console;
34 const
35 CTL_NONE = 0;
36 CTL_LEFT = 1;
37 CTL_RIGHT = 2;
38 CTL_UP = 3;
39 CTL_DOWN = 4;
40 CTL_FIRE = 5;
41 CTL_OPEN = 6;
42 CTL_JUMP = 7;
43 CTL_CHAT = 8;
44 CTL_ESC = 9;
45 CTL_W0 = 10;
46 CTL_W1 = 11;
47 CTL_W2 = 12;
48 CTL_W3 = 13;
49 CTL_W4 = 14;
50 CTL_W5 = 15;
51 CTL_W6 = 16;
52 CTL_W7 = 17;
53 CTL_W8 = 18;
54 CTL_W9 = 19;
55 CTL_W10 = 20;
56 CTL_CON = 21;
57 CTL_STAT = 22;
58 CTL_TCHAT = 23;
59 CTL_LAST = 23;
61 var
62 size: Single;
63 enabled: Boolean;
64 keyFinger: array [1..CTL_LAST] of Integer;
66 procedure GetControlRect(control: Integer; out x, y, w, h: Integer; out founded: Boolean);
67 var
68 sw, sh, sz: Integer;
69 dpi: Single;
70 begin
71 if SDL_GetDisplayDPI(0, @dpi, nil, nil) <> 0 then
72 dpi := 96;
74 founded := true;
75 sz := Trunc(size * dpi);
76 x := 0; y := 0; w := sz; h := sz;
77 sw := gScreenWidth; sh := gScreenHeight;
78 case control of
79 CTL_LEFT: begin x := 0; y := sh div 2 - h div 2; end;
80 CTL_RIGHT: begin x := w; y := sh div 2 - h div 2; end;
81 CTL_UP: begin x := sw - w - 1; y := sh div 2 - h div 2 - h; end;
82 CTL_DOWN: begin x := sw - w - 1; y := sh div 2 - h div 2 + h; end;
83 CTL_FIRE: begin x := sw - 1*w - 1; y := sh div 2 - h div 2; end;
84 CTL_OPEN: begin x := sw - 3*w - 1; y := sh div 2 - h div 2; end;
85 CTL_JUMP: begin x := sw - 2*w - 1; y := sh div 2 - h div 2; end;
86 else
87 w := sz div 2; h := sz div 2;
88 case control of
89 CTL_W0: begin x := sw div 2 - w div 2 - 5*w - 1; y := sh - 1*h - 1; end;
90 CTL_W1: begin x := sw div 2 - w div 2 - 4*w - 1; y := sh - 1*h - 1; end;
91 CTL_W2: begin x := sw div 2 - w div 2 - 3*w - 1; y := sh - 1*h - 1; end;
92 CTL_W3: begin x := sw div 2 - w div 2 - 2*w - 1; y := sh - 1*h - 1; end;
93 CTL_W4: begin x := sw div 2 - w div 2 - 1*w - 1; y := sh - 1*h - 1; end;
94 CTL_W5: begin x := sw div 2 - w div 2 + 0*w - 1; y := sh - 1*h - 1; end;
95 CTL_W6: begin x := sw div 2 - w div 2 + 1*w - 1; y := sh - 1*h - 1; end;
96 CTL_W7: begin x := sw div 2 - w div 2 + 2*w - 1; y := sh - 1*h - 1; end;
97 CTL_W8: begin x := sw div 2 - w div 2 + 3*w - 1; y := sh - 1*h - 1; end;
98 CTL_W9: begin x := sw div 2 - w div 2 + 4*w - 1; y := sh - 1*h - 1; end;
99 CTL_W10: begin x := sw div 2 - w div 2 + 5*w - 1; y := sh - 1*h - 1; end;
100 CTL_CHAT: begin x := sw div 2 - w div 2 - 2*w - 1; y := sh - 2*h - 1; end;
101 CTL_ESC: begin x := sw div 2 - w div 2 - 1*w - 1; y := sh - 2*h - 1; end;
102 CTL_CON: begin x := sw div 2 - w div 2 + 0*w - 1; y := sh - 2*h - 1; end;
103 CTL_STAT: begin x := sw div 2 - w div 2 + 1*w - 1; y := sh - 2*h - 1; end;
104 CTL_TCHAT: begin x := sw div 2 - w div 2 + 2*w - 1; y := sh - 2*h - 1; end;
105 else
106 founded := false
107 end
108 end
109 end;
111 function GetMenuKey(control: Integer): Word;
112 begin
113 case control of
114 CTL_LEFT: result := IK_LEFT;
115 CTL_RIGHT: result := IK_RIGHT;
116 CTL_UP: result := IK_UP;
117 CTL_DOWN: result := IK_DOWN;
118 CTL_OPEN: result := IK_ENTER;
119 CTL_FIRE: result := IK_ENTER;
120 CTL_JUMP: result := IK_SPACE;
121 CTL_ESC: result := IK_ESCAPE;
122 CTL_W0: result := SDL_SCANCODE_0;
123 CTL_W1: result := SDL_SCANCODE_1;
124 CTL_W2: result := SDL_SCANCODE_2;
125 CTL_W3: result := SDL_SCANCODE_3;
126 CTL_W4: result := SDL_SCANCODE_4;
127 CTL_W5: result := SDL_SCANCODE_5;
128 CTL_W6: result := SDL_SCANCODE_6;
129 CTL_W7: result := SDL_SCANCODE_7;
130 CTL_W8: result := SDL_SCANCODE_8;
131 CTL_W9: result := SDL_SCANCODE_9;
132 CTL_CON: result := IK_GRAVE;
133 else
134 result := IK_INVALID;
135 end
136 end;
138 function GetPlayerKey(control: Integer): Word;
139 begin
140 case control of
141 CTL_LEFT: result := gGameControls.P1Control.KeyLeft;
142 CTL_RIGHT: result := gGameControls.P1Control.KeyRight;
143 CTL_UP: result := gGameControls.P1Control.KeyUp;
144 CTL_DOWN: result := gGameControls.P1Control.KeyDown;
145 CTL_OPEN: result := gGameControls.P1Control.KeyOpen;
146 CTL_FIRE: result := gGameControls.P1Control.KeyFire;
147 CTL_JUMP: result := gGameControls.P1Control.KeyJump;
148 CTL_CHAT: result := gGameControls.GameControls.Chat;
149 CTL_ESC: result := IK_ESCAPE;
150 CTL_W0: result := gGameControls.P1Control.KeyWeapon[WEAPON_KASTET];
151 CTL_W1: result := gGameControls.P1Control.KeyWeapon[WEAPON_SAW];
152 CTL_W2: result := gGameControls.P1Control.KeyWeapon[WEAPON_PISTOL];
153 CTL_W3: result := gGameControls.P1Control.KeyWeapon[WEAPON_SHOTGUN1];
154 CTL_W4: result := gGameControls.P1Control.KeyWeapon[WEAPON_SHOTGUN2];
155 CTL_W5: result := gGameControls.P1Control.KeyWeapon[WEAPON_CHAINGUN];
156 CTL_W6: result := gGameControls.P1Control.KeyWeapon[WEAPON_ROCKETLAUNCHER];
157 CTL_W7: result := gGameControls.P1Control.KeyWeapon[WEAPON_PLASMA];
158 CTL_W8: result := gGameControls.P1Control.KeyWeapon[WEAPON_BFG];
159 CTL_W9: result := gGameControls.P1Control.KeyWeapon[WEAPON_SUPERPULEMET];
160 CTL_W10: result := gGameControls.P1Control.KeyWeapon[WEAPON_FLAMETHROWER];
161 CTL_CON: result := IK_GRAVE;
162 CTL_STAT: result := gGameControls.GameControls.Stat;
163 CTL_TCHAT: result := gGameControls.GameControls.TeamChat;
164 else
165 result := IK_INVALID
166 end
167 end;
169 function GetControlName(control: Integer): String;
170 begin
171 case control of
172 CTL_LEFT: result := 'LEFT';
173 CTL_RIGHT: result := 'RIGHT';
174 CTL_UP: result := 'UP';
175 CTL_DOWN: result := 'DOWN';
176 CTL_OPEN: result := 'OPEN';
177 CTL_FIRE: result := 'FIRE';
178 CTL_JUMP: result := 'JUMP';
179 CTL_CHAT: result := 'CHAT';
180 CTL_ESC: result := 'ESC';
181 CTL_W0: result := '0';
182 CTL_W1: result := '1';
183 CTL_W2: result := '2';
184 CTL_W3: result := '3';
185 CTL_W4: result := '4';
186 CTL_W5: result := '5';
187 CTL_W6: result := '6';
188 CTL_W7: result := '7';
189 CTL_W8: result := '8';
190 CTL_W9: result := '9';
191 CTL_W10: result := '10';
192 CTL_CON: result := 'CON';
193 CTL_STAT: result := 'STAT';
194 CTL_TCHAT: result := 'TEAM';
195 else
196 result := '(WAT?)'
197 end
198 end;
200 procedure DrawRect(x, y, w, h: Integer);
201 begin
202 e_DrawQuad(x, y, x + w, y + h, 0, 255, 0, 127);
203 end;
205 function IntersectControl(ctl, xx, yy: Integer): Boolean;
206 var
207 x, y, w, h: Integer;
208 founded: Boolean;
209 begin
210 GetControlRect(ctl, x, y, w, h, founded);
211 result := founded and (xx >= x) and (yy >= y) and (xx <= x + w) and (yy <= y + h);
212 end;
214 procedure g_Touch_ShowKeyboard(yes: Boolean);
215 begin
216 {$IFNDEF HEADLESS}
217 if not enabled then
218 Exit;
220 if yes then
221 SDL_StartTextInput
222 else
223 SDL_StopTextInput
224 {$ENDIF}
225 end;
227 procedure g_Touch_HandleEvent(const ev: TSDL_TouchFingerEvent);
228 var
229 x, y, i, finger: Integer;
230 begin
231 if not enabled then
232 Exit;
233 if SDL_IsTextInputActive() = SDL_True then
234 Exit;
236 finger := ev.fingerId + 2;
237 x := Trunc(ev.x * gScreenWidth);
238 y := Trunc(ev.y * gScreenHeight);
240 for i := 1 to CTL_LAST do
241 begin
242 if IntersectControl(i, x, y) then
243 begin
244 if ev.type_ = SDL_FINGERUP then
245 keyFinger[i] := 0
246 else if ev.type_ = SDL_FINGERMOTION then
247 keyFinger[i] := finger
248 else if ev.type_ = SDL_FINGERDOWN then
249 begin
250 KeyPress(GetMenuKey(i));
251 keyFinger[i] := finger;
252 end
253 end
254 else if keyFinger[i] = finger then
255 begin
256 if ev.type_ = SDL_FINGERUP then
257 keyFinger[i] := 0
258 else if ev.type_ = SDL_FINGERMOTION then
259 keyFinger[i] := 0
260 end;
262 e_KeyUpDown(GetPlayerKey(i), keyFinger[i] <> 0);
263 e_KeyUpDown(GetMenuKey(i), keyFinger[i] <> 0);
264 end;
265 end;
267 procedure g_Touch_Draw;
268 var
269 i, x, y, w, h: Integer;
270 founded: Boolean;
271 begin
272 {$IFNDEF HEADLESS}
273 if not enabled then
274 Exit;
275 if SDL_IsTextInputActive() = SDL_True then
276 Exit;
278 for i := 1 to CTL_LAST do
279 begin
280 GetControlRect(i, x, y, w, h, founded);
281 if founded then
282 begin
283 DrawRect(x, y, w, h);
284 e_TextureFontPrint(x, y, GetControlName(i), gStdFont)
285 end;
286 end;
287 {$ENDIF}
288 end;
290 initialization
291 {$IFDEF ANDROID}
292 enabled := true;
293 {$ENDIF}
294 size := 1;
295 conRegVar('touch_enable', @enabled, 'enable/disable virtual buttons', 'draw buttons');
296 conRegVar('touch_size', @size, 0.1, 10, 'size of virtual buttons', 'button size');
297 end.