97 |
97 |
98 // Takes a control name (e.g. 'quit') and returns the corresponding key code, |
98 // Takes a control name (e.g. 'quit') and returns the corresponding key code, |
99 // if it has been bound. |
99 // if it has been bound. |
100 // Returns -1 if the control has not been bound. |
100 // Returns -1 if the control has not been bound. |
101 function KeyBindToCode(bind: shortstring): LongInt; |
101 function KeyBindToCode(bind: shortstring): LongInt; |
102 var code: LongInt; |
102 var code, index: LongInt; |
103 begin |
103 begin |
104 code:= 0; |
104 index:= 0; |
105 while (code <= cKeyMaxIndex) and (CurrentBinds[code] <> bind) do inc(code); |
105 while (index <= High(CurrentBinds.binds)) and (CurrentBinds.binds[index] <> bind) do inc(index); |
106 if code > cKeyMaxIndex then |
106 if index > High(CurrentBinds.binds) then |
107 // Return error |
107 // Return error |
108 KeyBindToCode:= -1 |
108 KeyBindToCode:= -1 |
109 else |
109 else begin |
|
110 code:= 0; |
|
111 while (code <= High(CurrentBinds.indices)) and (CurrentBinds.indices[code] <> index) do inc(code); |
|
112 checkFails(code <= High(CurrentBinds.indices), 'binds registry inconsistency', True); |
110 KeyBindToCode:= code; |
113 KeyBindToCode:= code; |
|
114 end; |
111 end; |
115 end; |
112 |
116 |
113 // Takes a control name (e.g. 'quit') and returns the corresponding |
117 // Takes a control name (e.g. 'quit') and returns the corresponding |
114 // human-readable key name from SDL. |
118 // human-readable key name from SDL. |
115 // FIXME: Does not work 100% for all keys yet, but at least it no |
119 // FIXME: Does not work 100% for all keys yet, but at least it no |
207 // on OS X it this is expected behaviour |
211 // on OS X it this is expected behaviour |
208 if tkbd[KeyNameToCode('left_meta')] or tkbd[KeyNameToCode('right_meta')] then |
212 if tkbd[KeyNameToCode('left_meta')] or tkbd[KeyNameToCode('right_meta')] then |
209 {$ELSE} |
213 {$ELSE} |
210 // on other systems use this shortcut only if the keys are not bound to any command |
214 // on other systems use this shortcut only if the keys are not bound to any command |
211 if tkbd[KeyNameToCode('left_ctrl')] or tkbd[KeyNameToCode('right_ctrl')] then |
215 if tkbd[KeyNameToCode('left_ctrl')] or tkbd[KeyNameToCode('right_ctrl')] then |
212 if ((CurrentBinds[KeyNameToCode('left_ctrl')] = '') or |
216 if ((CurrentBinds.indices[KeyNameToCode('left_ctrl')] = 0) or |
213 (CurrentBinds[KeyNameToCode('right_ctrl')] = '')) and |
217 (CurrentBinds.indices[KeyNameToCode('right_ctrl')] = 0)) and |
214 (CurrentBinds[SDLK_w] = '') then |
218 (CurrentBinds.indices[SDLK_w] = 0) then |
215 {$ENDIF} |
219 {$ENDIF} |
216 ParseCommand('forcequit', true); |
220 ParseCommand('forcequit', true); |
217 end; |
221 end; |
218 |
222 |
219 if CurrentBinds[code][0] <> #0 then |
223 if CurrentBinds.indices[code] > 0 then |
220 begin |
224 begin |
221 if (code < cKeyMaxIndex - 2) // means not mouse buttons |
225 if (code < cKeyMaxIndex - 2) // means not mouse buttons |
222 and KeyDown |
226 and KeyDown |
223 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'))) |
227 and (not ((CurrentBinds.binds[CurrentBinds.indices[code]] = 'put') |
|
228 or (CurrentBinds.binds[CurrentBinds.indices[code]] = 'ammomenu') |
|
229 or (CurrentBinds.binds[CurrentBinds.indices[code]] = '+cur_u') |
|
230 or (CurrentBinds.binds[CurrentBinds.indices[code]] = '+cur_d') |
|
231 or (CurrentBinds.binds[CurrentBinds.indices[code]] = '+cur_l') |
|
232 or (CurrentBinds.binds[CurrentBinds.indices[code]] = '+cur_r'))) |
224 and (CurrentTeam <> nil) |
233 and (CurrentTeam <> nil) |
225 and (not CurrentTeam^.ExtDriven) |
234 and (not CurrentTeam^.ExtDriven) |
226 then bShowAmmoMenu:= false; |
235 then bShowAmmoMenu:= false; |
227 |
236 |
228 if KeyDown then |
237 if KeyDown then |
229 begin |
238 begin |
230 Trusted:= Trusted and (not isPaused); //releasing keys during pause should be allowed on the other hand |
239 Trusted:= Trusted and (not isPaused); //releasing keys during pause should be allowed on the other hand |
231 |
240 |
232 if CurrentBinds[code] = 'switch' then |
241 if CurrentBinds.binds[CurrentBinds.indices[code]] = 'switch' then |
233 LocalMessage:= LocalMessage or gmSwitch |
242 LocalMessage:= LocalMessage or gmSwitch |
234 else if CurrentBinds[code] = '+precise' then |
243 else if CurrentBinds.binds[CurrentBinds.indices[code]] = '+precise' then |
235 LocalMessage:= LocalMessage or gmPrecise; |
244 LocalMessage:= LocalMessage or gmPrecise; |
236 |
245 |
237 ParseCommand(CurrentBinds[code], Trusted); |
246 ParseCommand(CurrentBinds.binds[CurrentBinds.indices[code]], Trusted); |
238 if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then |
247 if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then |
239 ParseCommand('gencmd R', true) |
248 ParseCommand('gencmd R', true) |
240 end |
249 end |
241 else if (CurrentBinds[code][1] = '+') then |
250 else if (CurrentBinds.binds[CurrentBinds.indices[code]][1] = '+') then |
242 begin |
251 begin |
243 if CurrentBinds[code] = '+precise' then |
252 if CurrentBinds.binds[CurrentBinds.indices[code]] = '+precise' then |
244 LocalMessage:= LocalMessage and (not gmPrecise); |
253 LocalMessage:= LocalMessage and (not gmPrecise); |
245 s:= CurrentBinds[code]; |
254 s:= CurrentBinds.binds[CurrentBinds.indices[code]]; |
246 s[1]:= '-'; |
255 s[1]:= '-'; |
247 ParseCommand(s, Trusted); |
256 ParseCommand(s, Trusted); |
248 if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then |
257 if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then |
249 ParseCommand('gencmd R', true) |
258 ParseCommand('gencmd R', true) |
250 end |
259 end |
251 else |
260 else |
252 begin |
261 begin |
253 if CurrentBinds[code] = 'switch' then |
262 if CurrentBinds.binds[CurrentBinds.indices[code]] = 'switch' then |
254 LocalMessage:= LocalMessage and (not gmSwitch) |
263 LocalMessage:= LocalMessage and (not gmSwitch) |
255 end |
264 end |
256 end |
265 end |
257 end; |
266 end; |
258 |
267 |
319 for t:= 0 to cKbdMaxIndex do |
328 for t:= 0 to cKbdMaxIndex do |
320 if tkbd[t] then |
329 if tkbd[t] then |
321 ProcessKey(t, False); |
330 ProcessKey(t, False); |
322 end; |
331 end; |
323 |
332 |
|
333 procedure RegisterBind(var binds: TBinds; key, value: shortstring); |
|
334 var code: LongInt; |
|
335 begin |
|
336 checkFails(binds.lastIndex < 255, 'too many binds', true); |
|
337 |
|
338 code:= KeyNameToCode(key); |
|
339 |
|
340 checkFails(code >= 0, 'unknown key', true); |
|
341 |
|
342 inc(binds.lastIndex); |
|
343 binds.indices[code]:= binds.lastIndex; |
|
344 binds.binds[binds.lastIndex]:= value |
|
345 end; |
324 |
346 |
325 procedure InitDefaultBinds; |
347 procedure InitDefaultBinds; |
326 var i: Longword; |
348 var i: Longword; |
327 begin |
349 begin |
328 DefaultBinds[KeyNameToCode('escape')]:= 'quit'; |
350 RegisterBind(DefaultBinds, 'escape', 'quit'); |
329 DefaultBinds[KeyNameToCode(_S'`')]:= 'history'; |
351 RegisterBind(DefaultBinds, _S'`', 'history'); |
330 DefaultBinds[KeyNameToCode('delete')]:= 'rotmask'; |
352 RegisterBind(DefaultBinds, 'delete', 'rotmask'); |
331 DefaultBinds[KeyNameToCode('home')]:= 'rottags'; |
353 RegisterBind(DefaultBinds, 'home', 'rottags'); |
332 |
354 |
333 //numpad |
355 //numpad |
334 //DefaultBinds[265]:= '+volup'; |
356 //DefaultBinds[265]:= '+volup'; |
335 //DefaultBinds[256]:= '+voldown'; |
357 //DefaultBinds[256]:= '+voldown'; |
336 |
358 |
337 DefaultBinds[KeyNameToCode(_S'0')]:= '+volup'; |
359 RegisterBind(DefaultBinds, _S'0', '+volup'); |
338 DefaultBinds[KeyNameToCode(_S'9')]:= '+voldown'; |
360 RegisterBind(DefaultBinds, _S'9', '+voldown'); |
339 DefaultBinds[KeyNameToCode(_S'8')]:= 'mute'; |
361 RegisterBind(DefaultBinds, _S'8', 'mute'); |
340 DefaultBinds[KeyNameToCode(_S'c')]:= 'capture'; |
362 RegisterBind(DefaultBinds, _S'c', 'capture'); |
341 DefaultBinds[KeyNameToCode(_S'r')]:= 'record'; |
363 RegisterBind(DefaultBinds, _S'r', 'record'); |
342 DefaultBinds[KeyNameToCode(_S'h')]:= 'findhh'; |
364 RegisterBind(DefaultBinds, _S'h', 'findhh'); |
343 DefaultBinds[KeyNameToCode(_S'p')]:= 'pause'; |
365 RegisterBind(DefaultBinds, _S'p', 'pause'); |
344 DefaultBinds[KeyNameToCode(_S's')]:= '+speedup'; |
366 RegisterBind(DefaultBinds, _S's', '+speedup'); |
345 DefaultBinds[KeyNameToCode(_S't')]:= 'chat'; |
367 RegisterBind(DefaultBinds, _S't', 'chat'); |
346 DefaultBinds[KeyNameToCode(_S'y')]:= 'confirm'; |
368 RegisterBind(DefaultBinds, _S'y', 'confirm'); |
347 |
369 |
348 DefaultBinds[KeyNameToCode('mousem')]:= 'zoomreset'; |
370 RegisterBind(DefaultBinds, 'mousem', 'zoomreset'); |
349 DefaultBinds[KeyNameToCode('wheelup')]:= 'zoomin'; |
371 RegisterBind(DefaultBinds, 'wheelup', 'zoomin'); |
350 DefaultBinds[KeyNameToCode('wheeldown')]:= 'zoomout'; |
372 RegisterBind(DefaultBinds, 'wheeldown', 'zoomout'); |
351 |
373 |
352 DefaultBinds[KeyNameToCode('f12')]:= 'fullscr'; |
374 RegisterBind(DefaultBinds, 'f12', 'fullscr'); |
353 |
375 |
354 |
376 |
355 DefaultBinds[KeyNameToCode('mousel')]:= '/put'; |
377 RegisterBind(DefaultBinds, 'mousel', '/put'); |
356 DefaultBinds[KeyNameToCode('mouser')]:= 'ammomenu'; |
378 RegisterBind(DefaultBinds, 'mouser', 'ammomenu'); |
357 DefaultBinds[KeyNameToCode('backspace')]:= 'hjump'; |
379 RegisterBind(DefaultBinds, 'backspace', 'hjump'); |
358 DefaultBinds[KeyNameToCode('tab')]:= 'switch'; |
380 RegisterBind(DefaultBinds, 'tab', 'switch'); |
359 DefaultBinds[KeyNameToCode('return')]:= 'ljump'; |
381 RegisterBind(DefaultBinds, 'return', 'ljump'); |
360 DefaultBinds[KeyNameToCode('space')]:= '+attack'; |
382 RegisterBind(DefaultBinds, 'space', '+attack'); |
361 DefaultBinds[KeyNameToCode('up')]:= '+up'; |
383 RegisterBind(DefaultBinds, 'up', '+up'); |
362 DefaultBinds[KeyNameToCode('down')]:= '+down'; |
384 RegisterBind(DefaultBinds, 'down', '+down'); |
363 DefaultBinds[KeyNameToCode('left')]:= '+left'; |
385 RegisterBind(DefaultBinds, 'left', '+left'); |
364 DefaultBinds[KeyNameToCode('right')]:= '+right'; |
386 RegisterBind(DefaultBinds, 'right', '+right'); |
365 DefaultBinds[KeyNameToCode('left_shift')]:= '+precise'; |
387 RegisterBind(DefaultBinds, 'left_shift', '+precise'); |
366 |
388 |
367 |
389 |
368 DefaultBinds[KeyNameToCode('j0a0u')]:= '+left'; |
390 RegisterBind(DefaultBinds, 'j0a0u', '+left'); |
369 DefaultBinds[KeyNameToCode('j0a0d')]:= '+right'; |
391 RegisterBind(DefaultBinds, 'j0a0d', '+right'); |
370 DefaultBinds[KeyNameToCode('j0a1u')]:= '+up'; |
392 RegisterBind(DefaultBinds, 'j0a1u', '+up'); |
371 DefaultBinds[KeyNameToCode('j0a1d')]:= '+down'; |
393 RegisterBind(DefaultBinds, 'j0a1d', '+down'); |
372 for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+char(48+i); |
394 for i:= 1 to 10 do RegisterBind(DefaultBinds, 'f'+IntToStr(i), 'slot '+char(48+i)); |
373 for i:= 1 to 5 do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i); |
395 for i:= 1 to 5 do RegisterBind(DefaultBinds, IntToStr(i), 'timer '+IntToStr(i)); |
374 |
396 |
375 loadBinds('dbind', cPathz[ptConfig] + '/settings.ini'); |
397 loadBinds('dbind', cPathz[ptConfig] + '/settings.ini'); |
376 end; |
398 end; |
377 |
399 |
378 |
400 |