38 procedure ControllerClose; |
40 procedure ControllerClose; |
39 procedure ControllerAxisEvent(joy, axis: Byte; value: Integer); |
41 procedure ControllerAxisEvent(joy, axis: Byte; value: Integer); |
40 procedure ControllerHatEvent(joy, hat, value: Byte); |
42 procedure ControllerHatEvent(joy, hat, value: Byte); |
41 procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean); |
43 procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean); |
42 |
44 |
43 {$IFDEF MOBILE} |
|
44 procedure setTouchWidgetStates; |
|
45 {$ENDIF} |
|
46 |
|
47 implementation |
45 implementation |
48 uses uConsole, uCommands, uMisc, uVariables, uConsts, uUtils, uDebug; |
46 uses uConsole, uCommands, uMisc, uVariables, uConsts, uUtils, uDebug; |
49 |
47 |
50 var tkbd, tkbdn: TKeyboardState; |
48 var tkbd, tkbdn: TKeyboardState; |
51 KeyNames: array [0..cKeyMaxIndex] of string[15]; |
49 KeyNames: array [0..cKeyMaxIndex] of string[15]; |
52 |
50 |
53 function KeyNameToCode(name: shortstring): word; |
51 function KeyNameToCode(name: shortstring): word; |
54 var code: Word; |
52 var code: Word; |
55 begin |
53 begin |
|
54 name:= LowerCase(name); |
56 code:= cKeyMaxIndex; |
55 code:= cKeyMaxIndex; |
57 while (code > 0) and (KeyNames[code] <> name) do dec(code); |
56 while (code > 0) and (KeyNames[code] <> name) do dec(code); |
58 KeyNameToCode:= code; |
57 KeyNameToCode:= code; |
59 end; |
58 end; |
60 |
|
61 |
59 |
62 procedure ProcessKbd; |
60 procedure ProcessKbd; |
63 var i, j, k: LongInt; |
61 var i, j, k: LongInt; |
64 s: shortstring; |
62 s: shortstring; |
65 Trusted: boolean; |
63 Trusted: boolean; |
66 pkbd: PByteArray; |
64 pkbd: PByteArray; |
67 begin |
65 begin |
68 hideAmmoMenu:= false; |
|
69 Trusted:= (CurrentTeam <> nil) |
|
70 and (not CurrentTeam^.ExtDriven) |
|
71 and (CurrentHedgehog^.BotLevel = 0); |
|
72 |
66 |
73 // move cursor/camera |
67 // move cursor/camera |
74 // TODO: Scale on screen dimensions and/or axis value (game controller)? |
68 // TODO: Scale on screen dimensions and/or axis value (game controller)? |
|
69 //TODO what is this for? |
75 movecursor(5 * CursorMovementX, 5 * CursorMovementY); |
70 movecursor(5 * CursorMovementX, 5 * CursorMovementY); |
76 |
71 |
77 pkbd:= SDL_GetKeyState(@j); |
|
78 for i:= 6 to pred(j) do // first 6 will be overwritten |
|
79 tkbdn[i]:= pkbd^[i]; |
|
80 |
|
81 k:= SDL_GetMouseState(nil, nil); |
|
82 // mouse buttons |
|
83 {$IFDEF DARWIN} |
|
84 tkbdn[1]:= ((k and 1) and not (tkbdn[306] or tkbdn[305])); |
|
85 tkbdn[3]:= ((k and 1) and (tkbdn[306] or tkbdn[305])) or (k and 4); |
|
86 {$ELSE} |
|
87 tkbdn[1]:= (k and 1); |
|
88 tkbdn[3]:= ((k shr 2) and 1); |
|
89 {$ENDIF} |
|
90 tkbdn[2]:= ((k shr 1) and 1); |
|
91 |
|
92 // mouse wheels |
|
93 tkbdn[4]:= ord(wheelDown); |
|
94 tkbdn[5]:= ord(wheelUp); |
|
95 wheelUp:= false; |
|
96 wheelDown:= false; |
|
97 |
|
98 {$IFDEF MOBILE} |
|
99 setTouchWidgetStates(); |
|
100 {$ENDIF} |
|
101 |
72 |
102 {$IFNDEF MOBILE} |
73 {$IFNDEF MOBILE} |
|
74 |
|
75 //TODO reimplement |
103 // Controller(s) |
76 // Controller(s) |
104 k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it |
77 k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it |
105 for j:= 0 to Pred(ControllerNumControllers) do |
78 for j:= 0 to Pred(ControllerNumControllers) do |
106 begin |
79 begin |
107 for i:= 0 to Pred(ControllerNumAxes[j]) do |
80 for i:= 0 to Pred(ControllerNumAxes[j]) do |
130 inc(k, 1); |
103 inc(k, 1); |
131 end; |
104 end; |
132 end; |
105 end; |
133 {$ENDIF} |
106 {$ENDIF} |
134 |
107 |
|
108 |
|
109 //TODO reimplement this |
135 // ctrl/cmd + q to close engine and frontend |
110 // ctrl/cmd + q to close engine and frontend |
136 {$IFDEF DARWIN} |
111 {$IFDEF DARWIN} |
137 if ((tkbdn[KeyNameToCode('left_meta')] = 1) or (tkbdn[KeyNameToCode('right_meta')] = 1)) then |
112 if ((tkbdn[KeyNameToCode('left_meta')] = 1) or (tkbdn[KeyNameToCode('right_meta')] = 1)) then |
138 {$ELSE} |
113 {$ELSE} |
139 if ((tkbdn[KeyNameToCode('left_ctrl')] = 1) or (tkbdn[KeyNameToCode('right_ctrl')] = 1)) then |
114 if ((tkbdn[KeyNameToCode('left_ctrl')] = 1) or (tkbdn[KeyNameToCode('right_ctrl')] = 1)) then |
140 {$ENDIF} |
115 {$ENDIF} |
141 begin |
116 begin |
142 if tkbdn[KeyNameToCode('q')] = 1 then ParseCommand ('halt', true) |
117 if tkbdn[KeyNameToCode('q')] = 1 then ParseCommand ('halt', true) |
143 end; |
118 end; |
144 |
119 end; |
145 // now process strokes |
120 |
146 for i:= 0 to cKeyMaxIndex do |
121 |
147 if CurrentBinds[i][0] <> #0 then |
122 procedure ProcessKey(code: LongInt; KeyDown: boolean); |
148 begin |
123 var |
149 if (i > 3) and (tkbdn[i] <> 0) and not ((CurrentBinds[i] = 'put') or (CurrentBinds[i] = 'ammomenu') or (CurrentBinds[i] = '+cur_u') or (CurrentBinds[i] = '+cur_d') or (CurrentBinds[i] = '+cur_l') or (CurrentBinds[i] = '+cur_r')) then hideAmmoMenu:= true; |
124 Trusted: boolean; |
150 if (tkbd[i] = 0) and (tkbdn[i] <> 0) then |
125 s : string; |
151 begin |
126 begin |
152 ParseCommand(CurrentBinds[i], Trusted); |
127 hideAmmoMenu:= false; |
|
128 Trusted:= (CurrentTeam <> nil) |
|
129 and (not CurrentTeam^.ExtDriven) |
|
130 and (CurrentHedgehog^.BotLevel = 0); |
|
131 |
|
132 tkbdn[code]:= ord(KeyDown); |
|
133 |
|
134 if CurrentBinds[code][0] <> #0 then |
|
135 begin |
|
136 if (code > 3) and (tkbdn[code] <> 0) and not ((CurrentBinds[code] = 'put') or (CurrentBinds[code] = 'ammomenu') or (CurrentBinds[code] = '+cur_u') or (CurrentBinds[code] = '+cur_d') or (CurrentBinds[code] = '+cur_l') or (CurrentBinds[code] = '+cur_r')) then hideAmmoMenu:= true; |
|
137 if (tkbd[code] = 0) and (tkbdn[code] <> 0) then |
|
138 begin |
|
139 ParseCommand(CurrentBinds[code], Trusted); |
153 if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then |
140 if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then |
154 ParseCommand('gencmd R', true) |
141 ParseCommand('gencmd R', true) |
155 end |
142 end |
156 else if (CurrentBinds[i][1] = '+') and (tkbdn[i] = 0) and (tkbd[i] <> 0) then |
143 else if (CurrentBinds[code][1] = '+') and (tkbdn[code] = 0) and (tkbd[code] <> 0) then |
157 begin |
144 begin |
158 s:= CurrentBinds[i]; |
145 s:= CurrentBinds[code]; |
159 s[1]:= '-'; |
146 s[1]:= '-'; |
160 ParseCommand(s, Trusted); |
147 ParseCommand(s, Trusted); |
161 if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then |
148 if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then |
162 ParseCommand('gencmd R', true) |
149 ParseCommand('gencmd R', true) |
163 end; |
150 end; |
164 tkbd[i]:= tkbdn[i] |
151 tkbd[code]:= tkbdn[code] |
165 end |
152 end |
|
153 |
|
154 end; |
|
155 |
|
156 procedure ProcessKey(event: TSDL_KeyboardEvent); |
|
157 begin |
|
158 ProcessKey(event.keysym.sym, event.type_ = SDL_KEYDOWN); |
|
159 end; |
|
160 |
|
161 procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean); |
|
162 begin |
|
163 case event.button of |
|
164 SDL_BUTTON_LEFT: |
|
165 ProcessKey(KeyNameToCode('mousel'), ButtonDown); |
|
166 SDL_BUTTON_MIDDLE: |
|
167 ProcessKey(KeyNameToCode('mousem'), ButtonDown); |
|
168 SDL_BUTTON_RIGHT: |
|
169 ProcessKey(KeyNameToCode('mouser'), ButtonDown); |
|
170 SDL_BUTTON_WHEELDOWN: |
|
171 ProcessKey(KeyNameToCode('wheeldown'), ButtonDown); |
|
172 SDL_BUTTON_WHEELUP: |
|
173 ProcessKey(KeyNameToCode('wheelup'), ButtonDown); |
|
174 end; |
166 end; |
175 end; |
167 |
176 |
168 procedure ResetKbd; |
177 procedure ResetKbd; |
169 var j, k, t: LongInt; |
178 var j, k, t: LongInt; |
170 i: LongInt; |
179 i: LongInt; |
172 begin |
181 begin |
173 |
182 |
174 k:= SDL_GetMouseState(nil, nil); |
183 k:= SDL_GetMouseState(nil, nil); |
175 pkbd:=SDL_GetKeyState(@j); |
184 pkbd:=SDL_GetKeyState(@j); |
176 |
185 |
177 TryDo(j < cKeyMaxIndex, 'SDL keys number is more than expected (' + IntToStr(j) + ')', true); |
186 //TryDo(j < cKeyMaxIndex, 'SDL keys number is more than expected (' + IntToStr(j) + ')', true); |
178 |
187 |
179 for i:= 1 to pred(j) do |
188 for i:= 1 to pred(j) do |
180 tkbdn[i]:= pkbd^[i]; |
189 tkbdn[i]:= pkbd^[i]; |
181 |
|
182 // mouse buttons |
|
183 {$IFDEF DARWIN} |
|
184 tkbdn[1]:= ((k and 1) and not (tkbdn[306] or tkbdn[305])); |
|
185 tkbdn[3]:= ((k and 1) and (tkbdn[306] or tkbdn[305])) or (k and 4); |
|
186 {$ELSE} |
|
187 tkbdn[1]:= (k and 1); |
|
188 tkbdn[3]:= ((k shr 2) and 1); |
|
189 {$ENDIF} |
|
190 tkbdn[2]:= ((k shr 1) and 1); |
|
191 |
|
192 // mouse wheels |
|
193 tkbdn[4]:= ord(wheelDown); |
|
194 tkbdn[5]:= ord(wheelUp); |
|
195 wheelUp:= false; |
|
196 wheelDown:= false; |
|
197 |
|
198 {$IFDEF MOBILE} |
|
199 setTouchWidgetStates(); |
|
200 {$ENDIF} |
|
201 |
190 |
202 {$IFNDEF MOBILE} |
191 {$IFNDEF MOBILE} |
203 // Controller(s) |
192 // Controller(s) |
204 k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it |
193 k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it |
205 for j:= 0 to Pred(ControllerNumControllers) do |
194 for j:= 0 to Pred(ControllerNumControllers) do |
239 |
228 |
240 procedure InitKbdKeyTable; |
229 procedure InitKbdKeyTable; |
241 var i, j, k, t: LongInt; |
230 var i, j, k, t: LongInt; |
242 s: string[15]; |
231 s: string[15]; |
243 begin |
232 begin |
|
233 //TODO in sdl13 this overrides some values (A and B) change indices to some other values at the back perhaps? |
244 KeyNames[1]:= 'mousel'; |
234 KeyNames[1]:= 'mousel'; |
245 KeyNames[2]:= 'mousem'; |
235 KeyNames[2]:= 'mousem'; |
246 KeyNames[3]:= 'mouser'; |
236 KeyNames[3]:= 'mouser'; |
247 KeyNames[4]:= 'wheelup'; |
237 KeyNames[4]:= 'wheelup'; |
248 KeyNames[5]:= 'wheeldown'; |
238 KeyNames[5]:= 'wheeldown'; |
249 |
239 |
250 for i:= 6 to cKeyMaxIndex do |
240 for i:= 6 to cKeyMaxIndex do |
251 begin |
241 begin |
|
242 {$IFDEF SDL13} |
|
243 s:= shortstring(SDL_GetScancodeName(i)); |
|
244 {$ELSE} |
252 s:= shortstring(sdl_getkeyname(i)); |
245 s:= shortstring(sdl_getkeyname(i)); |
253 //WriteToConsole(IntToStr(i) + ': ' + s); |
246 {$ENDIF} |
|
247 WriteToConsole(IntToStr(i) + ': ' + s + ' ' + IntToStr(cKeyMaxIndex)); |
254 if s = 'unknown key' then KeyNames[i]:= '' |
248 if s = 'unknown key' then KeyNames[i]:= '' |
255 else |
249 else |
256 begin |
250 begin |
257 for t:= 1 to Length(s) do |
251 for t:= 1 to Length(s) do |
258 if s[t] = ' ' then |
252 if s[t] = ' ' then |
259 s[t]:= '_'; |
253 s[t]:= '_'; |
260 KeyNames[i]:= s |
254 KeyNames[i]:= LowerCase(s) |
261 end; |
255 end; |
262 end; |
256 end; |
263 |
257 |
264 //for i:= 0 to cKeyMaxIndex do writeln(stdout,IntToStr(i) + ': ' + KeyNames[i]); |
258 //for i:= 0 to cKeyMaxIndex do writeln(stdout,IntToStr(i) + ': ' + KeyNames[i]); |
265 |
259 |
312 DefaultBinds[KeyNameToCode('wheeldown')]:= 'zoomin'; |
306 DefaultBinds[KeyNameToCode('wheeldown')]:= 'zoomin'; |
313 |
307 |
314 DefaultBinds[KeyNameToCode('f12')]:= 'fullscr'; |
308 DefaultBinds[KeyNameToCode('f12')]:= 'fullscr'; |
315 |
309 |
316 |
310 |
317 DefaultBinds[ 1]:= '/put'; |
311 DefaultBinds[KeyNameToCode('mousel')]:= '/put'; |
318 DefaultBinds[ 3]:= 'ammomenu'; |
312 DefaultBinds[KeyNameToCode('mouser')]:= 'ammomenu'; |
319 DefaultBinds[ 8]:= 'hjump'; |
313 DefaultBinds[KeyNameToCode('backspace')]:= 'hjump'; |
320 DefaultBinds[ 9]:= 'switch'; |
314 DefaultBinds[KeyNameToCode('tab')]:= 'switch'; |
321 DefaultBinds[13]:= 'ljump'; |
315 DefaultBinds[KeyNameToCode('return')]:= 'ljump'; |
322 DefaultBinds[32]:= '+attack'; |
316 DefaultBinds[KeyNameToCode('space')]:= '+attack'; |
323 {$IFDEF MOBILE} |
|
324 DefaultBinds[23]:= '+up'; |
|
325 DefaultBinds[24]:= '+down'; |
|
326 DefaultBinds[25]:= '+left'; |
|
327 DefaultBinds[26]:= '+right'; |
|
328 DefaultBinds[27]:= '+precise'; |
|
329 DefaultBinds[44]:= 'chat'; |
|
330 DefaultBinds[55]:= 'pause'; |
|
331 {$ELSE} |
|
332 DefaultBinds[KeyNameToCode('up')]:= '+up'; |
317 DefaultBinds[KeyNameToCode('up')]:= '+up'; |
333 DefaultBinds[KeyNameToCode('down')]:= '+down'; |
318 DefaultBinds[KeyNameToCode('down')]:= '+down'; |
334 DefaultBinds[KeyNameToCode('left')]:= '+left'; |
319 DefaultBinds[KeyNameToCode('left')]:= '+left'; |
335 DefaultBinds[KeyNameToCode('right')]:= '+right'; |
320 DefaultBinds[KeyNameToCode('right')]:= '+right'; |
336 DefaultBinds[KeyNameToCode('left_shift')]:= '+precise'; |
321 DefaultBinds[KeyNameToCode('left_shift')]:= '+precise'; |
337 {$ENDIF} |
|
338 |
322 |
339 for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+IntToStr(i); |
323 for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+IntToStr(i); |
340 for i:= 1 to 5 do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i); |
324 for i:= 1 to 5 do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i); |
341 |
325 |
342 SetDefaultBinds(); |
326 SetDefaultBinds(); |
354 |
338 |
355 procedure SetDefaultBinds; |
339 procedure SetDefaultBinds; |
356 begin |
340 begin |
357 CurrentBinds:= DefaultBinds; |
341 CurrentBinds:= DefaultBinds; |
358 end; |
342 end; |
359 |
|
360 {$IFDEF MOBILE} |
|
361 procedure setTouchWidgetStates; |
|
362 begin |
|
363 tkbdn[ 1]:= ord(leftClick); |
|
364 tkbdn[ 2]:= ord(middleClick); |
|
365 tkbdn[ 3]:= ord(rightClick); |
|
366 |
|
367 tkbdn[23]:= ord(upKey); |
|
368 tkbdn[24]:= ord(downKey); |
|
369 tkbdn[25]:= ord(leftKey); |
|
370 tkbdn[26]:= ord(rightKey); |
|
371 tkbdn[27]:= ord(preciseKey); |
|
372 |
|
373 tkbdn[ 8]:= ord(backspaceKey); |
|
374 tkbdn[ 9]:= ord(tabKey); |
|
375 tkbdn[13]:= ord(enterKey); |
|
376 tkbdn[32]:= ord(spaceKey); |
|
377 |
|
378 tkbdn[44]:= ord(chatAction); |
|
379 tkbdn[55]:= ord(pauseAction); |
|
380 |
|
381 // set to false the keys that only need one stoke |
|
382 leftClick:= false; |
|
383 middleClick:= false; |
|
384 rightClick:= false; |
|
385 |
|
386 tabKey:= false; |
|
387 enterKey:= false; |
|
388 backspaceKey:= false; |
|
389 |
|
390 chatAction:= false; |
|
391 pauseAction:= false; |
|
392 end; |
|
393 {$ENDIF} |
|
394 |
343 |
395 procedure FreezeEnterKey; |
344 procedure FreezeEnterKey; |
396 begin |
345 begin |
397 tkbd[3]:= 1; |
346 tkbd[3]:= 1; |
398 tkbd[13]:= 1; |
347 tkbd[13]:= 1; |