1 /*
2
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 */
19 /*
20 * $Source: r:/prj/cit/src/RCS/input.c $
21 * $Revision: 1.293 $
22 * $Author: jaemz $
23 * $Date: 1994/11/23 00:16:31 $
24 */
25
26 // lets get this somewhere else so we can get it in the manual or something, and not get warnings..
27 #ifdef SPACEBALL_SUPPORT
28 static char sbcopy[] = "Spaceball Interface Copyright 1994 Spaceball Technologies Inc.";
29 #endif
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <limits.h>
34
35 #include "Shock.h"
36 #include "ShockBitmap.h"
37 #include "InitMac.h"
38 #include "Prefs.h"
39 #include "DialogHelpers.h"
40 #include "ShockHelp.h"
41
42 #if __profile__
43 #include <Profiler.h>
44 #endif
45
46 #define __INPUT_SRC
47
48 #include "input.h"
49
50 #include "ai.h"
51 #include "aiflags.h"
52 #include "citres.h"
53 #include "colors.h"
54 #include "criterr.h"
55 #include "cybstrng.h"
56 #include "doorparm.h"
57 #include "drugs.h"
58 #include "emailbit.h"
59 #include "faketime.h"
60 #include "frflags.h" // until we do the right thing re: static
61 #include "FrUtils.h"
62 #include "fullscrn.h"
63 #include "gamesys.h"
64 #include "gamescr.h"
65 #include "gamestrn.h"
66 #include "gr2ss.h"
67 #include "grenades.h"
68 #include "hkeyfunc.h"
69 #include "MacTune.h"
70 #include "mainloop.h"
71 #include "musicai.h"
72 #include "newmfd.h"
73 #include "objbit.h"
74 #include "objects.h"
75 #include "objload.h"
76 #include "objsim.h"
77 #include "objprop.h"
78 #include "objuse.h"
79 #include "olhext.h"
80 #include "otrip.h"
81 #include "physics.h"
82 #include "player.h"
83 #include "game_screen.h"
84 #include "status.h"
85 #include "svgacurs.h"
86 #include "tools.h"
87 #include "weapons.h"
88 #include "mouselook.h"
89 #include "wrapper.h"
90
91 #ifdef NOT_YET // KLC - for VR headsets
92
93 #include <conio.h>
94 #include <config.h>
95 #include <inp6d.h>
96 #ifdef STEREO_SUPPORT
97 #include <i6dvideo.h>
98 #include <mfddims.h>
99 #endif
100
101 #include <paintbit.h>
102 #include <editscrn.h>
103 #include <frcamera.h>
104 #include <frprotox.h>
105 #ifdef SVGA_SUPPORT
106 #include <frtypes.h>
107 #endif
108
109 #endif // NOT_YET
110
111 #include "OpenGL.h"
112
113 #define CHECK_FOR_A_PACKET
114
115 #ifdef SVGA_SUPPORT
116 extern frc *svga_render_context;
117 #endif
118
119 // -------
120 // DEFINES
121 // -------
122
123 extern bool DoubleSize;
124
125 #define CFG_DCLICK_RATE_VAR "dclick_time"
126 #define CFG_OOMPHOMETER "throw_oomph"
127 #define CFG_INP6D_GO "inp6d"
128
129 ubyte use_distance_mod = 0;
130 ubyte pickup_distance_mod = 0;
131 ubyte fatigue_threshold = 5;
132
133 #define MAX_FATIGUE 10000 // this is stolen from gamesys.c
134 #define FATIGUE_COEFF CIT_CYCLE
135 #define FATIGUE_THRESHOLD \
136 ((player_struct.drug_status[CPTRIP(STAMINA_DRUG_TRIPLE)] == 0) ? (fatigue_threshold * CIT_CYCLE) : MAX_FATIGUE)
137 #define PLAYER_FATIGUE \
138 ((player_struct.fatigue > FATIGUE_THRESHOLD) ? (player_struct.fatigue - FATIGUE_THRESHOLD) / FATIGUE_COEFF : 0)
139
140 #define MOTION_FOOTPLANT_SCANCODE 0x2A
141
142 #define AIM_SCREEN_MARGIN 5
143 #define sqr(x) ((x) * (x))
144
145 extern LGRect target_screen_rect;
146 extern int fr_get_at_raw(frc *fr, int x, int y, uchar again, uchar transp);
147
148 extern void mouse_unconstrain(void);
149
150 char *get_object_lookname(ObjID id, char use_string[], int sz);
151
152 extern uiSlab fullscreen_slab;
153 extern uiSlab main_slab;
154
155 static ushort mouse_constrain_bits = 0;
156
157 #define FIREKEY_CONSTRAIN_BIT 1
158 #define LBUTTON_CONSTRAIN_BIT MOUSE_LDOWN
159 #define RBUTTON_CONSTRAIN_BIT MOUSE_RDOWN
160 #define LOCK_CONSTRAIN_BIT 0x8000
161
162 typedef struct _3d_mouse_stuff {
163 uchar ldown;
164 uchar rdown;
165 int lastsect;
166 LGPoint lastleft;
167 LGPoint lastright;
168 frc *fr;
169 } view3d_data;
170
171 // -------
172 // GLOBALS
173 // -------
174
175 Ref motion_cursor_ids[] = {
176 REF_IMG_bmUpLeftCursor, REF_IMG_bmUpCursor, REF_IMG_bmUpRightCursor, 0,
177 REF_IMG_bmLeftCursor, REF_IMG_bmDownCursor, REF_IMG_bmRightCursor, 0,
178 REF_IMG_bmCircLeftCursor, REF_IMG_bmTargetCursor, REF_IMG_bmCircRightCursor, 0,
179 REF_IMG_bmUpLeftCursor, REF_IMG_bmSprintCursor, REF_IMG_bmUpRightCursor,
180 };
181
182 #define NUM_MOTION_CURSORS 15
183 #define NUM_CYBER_CURSORS 9
184 #define CYBER_CURSOR_BASE REF_IMG_bmCyberUpLeftCursor
185
186 LGCursor motion_cursors[NUM_MOTION_CURSORS];
187 grs_bitmap motion_cursor_bitmaps[NUM_MOTION_CURSORS];
188
189 static uchar posture_keys[NUM_POSTURES] = {'t', 'g', 'b'};
190
191 int input_cursor_mode = INPUT_NORMAL_CURSOR;
192 int throw_oomph = 5;
193
194 uchar inp6d_headset = FALSE;
195 uchar inp6d_stereo = FALSE;
196 uchar inp6d_doom = FALSE;
197 uchar inp6d_stereo_active = FALSE;
198 int inp6d_stereo_div = fix_make(3, 0x4000); // 3.25 inches apart
199 fix inpJoystickSens = FIX_UNIT;
200
201 // checking for game paused
202 extern uchar game_paused;
203
204 #ifdef SVGA_SUPPORT
205 extern uchar change_svga_mode(ushort keycode, uint32_t context, intptr_t data);
206 #endif
207 extern uchar toggle_bool_func(ushort keycode, uint32_t context, intptr_t thebool);
208 LGPoint use_cursor_pos;
209
210 #ifdef RCACHE_TEST
211 extern uchar res_cache_usage_func(ushort keycode, uint32_t context, intptr_t data);
212 #endif
213 // extern uchar texture_annihilate_func(ushort keycode, uint32_t context, intptrr_t data);
214
215 // 6d wackiness
216 uchar inp6d_exists = FALSE;
217 void inp6d_chk(void);
218
219 #if defined(VFX1_SUPPORT) || defined(CTM_SUPPORT)
220 #include <i6dvideo.h>
221
222 static int tracker_initial_pos[3] = {0, 0, 0};
223 uchar recenter_headset(ushort keycode, uint32_t context, intptr_t data);
224 #endif
225
226 // globals for doubling headset angular values
227 uchar inp6d_hdouble = FALSE;
228 uchar inp6d_pdouble = FALSE;
229 uchar inp6d_bdouble = FALSE;
230
231 // and joysticks, heck, why be efficient
232 uchar joystick_mouse_emul = FALSE;
233 uchar joystick_count = 0;
234 uchar recenter_joystick(ushort keycode, uint32_t context, intptr_t data);
235
236 uchar change_gamma(ushort keycode, uint32_t context, intptr_t data);
237
238 // -------------
239 // PROTOTYPES
240 // -------------
241 void handle_keyboard_fatigue(void);
242 void poll_mouse(void);
243 uchar eye_hotkey_func(ushort keycode, uint32_t context, intptr_t data);
244
245 void reload_motion_cursors(uchar cyber);
246 void free_cursor_bitmaps();
247 void alloc_cursor_bitmaps(void);
248
249 int view3d_mouse_input(LGPoint pos, LGRegion *reg, uchar move, int *lastsect);
250 void view3d_dclick(LGPoint pos, frc *fr, bool shifted);
251 void look_at_object(ObjID id);
252 uchar view3d_mouse_handler(uiEvent *ev, LGRegion *r, intptr_t data);
253 void view3d_rightbutton_handler(uiEvent *ev, LGRegion *r, view3d_data *data);
254 uchar view3d_key_handler(uiEvent *ev, LGRegion *r, intptr_t data);
255 void use_object_in_3d(ObjID obj, bool shifted);
256
257 uchar MacResFunc(ushort keycode, uint32_t context, intptr_t data);
258 uchar MacSkiplinesFunc(ushort keycode, uint32_t context, intptr_t data);
259
260 //EXTERN FUNCTIONS
261
262 extern uchar cycle_weapons_func(ushort keycode, uint32_t context, intptr_t data);
263
264 // -------------
265 // INPUT POLLING
266 // -------------
267
handle_keyboard_fatigue(void)268 void handle_keyboard_fatigue(void) {
269 byte cval;
270 physics_get_one_control(KEYBD_CONTROL_BANK, CONTROL_YVEL, &cval);
271 if (cval > 0) {
272 int f = lg_max(CONTROL_MAX_VAL - PLAYER_FATIGUE, SPRINT_CONTROL_THRESHOLD);
273 if (cval > f)
274 physics_set_one_control(KEYBD_CONTROL_BANK, CONTROL_YVEL, f);
275 }
276 physics_get_one_control(KEYBD_CONTROL_BANK, CONTROL_ZVEL, &cval);
277 if (cval > 0) {
278 int f = lg_max(MAX_JUMP_CONTROL - PLAYER_FATIGUE, MAX_JUMP_CONTROL / 2);
279 if (cval > f)
280 physics_set_one_control(KEYBD_CONTROL_BANK, CONTROL_ZVEL, f);
281 }
282 }
283
284 #ifdef NOT_YET //
285
286 //#define CONSTRAIN_TO_FAUXREND
287
288 #pragma disable_message(202)
view3d_constrain_mouse(LGRegion * view,int mouse_bit)289 void view3d_constrain_mouse(LGRegion *view, int mouse_bit) {
290 mouse_constrain_bits |= mouse_bit;
291 if (mouse_constrain_bits != 0) {
292 #ifdef CONSTRAIN_TO_FAUXREND
293 {
294 fauxrend_context *cc = (fauxrend_context *)_current_fr_context;
295 mouse_constrain_xy(cc->xtop, cc->ytop, cc->xtop + cc->xwid - 1, cc->ytop + cc->ywid - 1);
296 Warning(("cc->ytop = %d! view->abs_y = %d!\n", cc->ytop, view->abs_y));
297 }
298 #else
299 ui_mouse_constrain_xy(view->abs_x, view->abs_y, view->abs_x + RectWidth(view->r) - 1,
300 view->abs_y + RectHeight(view->r) - 1);
301 #endif
302 }
303 }
304 #pragma enable_message(202)
305
view3d_unconstrain_mouse(int mouse_bit)306 void view3d_unconstrain_mouse(int mouse_bit) {
307 mouse_constrain_bits &= ~mouse_bit;
308 if (mouse_constrain_bits == 0) {
309 mouse_unconstrain();
310 }
311 }
312
313 #ifdef PLAYTEST
314 uchar inp6d_player = TRUE, inp6d_motion = TRUE, inp6d_conform = TRUE;
315 #endif
316
317 #endif // NOT_YET
318
319 // Sends a motion event to the 3d view.
320
321 uchar view3d_got_event = FALSE;
322
poll_mouse(void)323 void poll_mouse(void) {
324 if (_current_view != NULL) {
325 uiEvent ev;
326 uiMakeMotionEvent(&ev);
327 ev.type = UI_EVENT_USER_DEFINED;
328 mouse_constrain_bits |= LOCK_CONSTRAIN_BIT;
329 uiDispatchEventToRegion(&ev, _current_view);
330 mouse_constrain_bits &= ~LOCK_CONSTRAIN_BIT;
331 }
332 }
333
334 uchar checking_mouse_button_emulation = FALSE;
335 uchar mouse_button_emulated = FALSE;
336
337 uchar citadel_check_input(void);
338 // HATE HATE HATE HATE
339
citadel_check_input(void)340 uchar citadel_check_input(void) {
341 if (uiCheckInput())
342 return (TRUE);
343
344 if (checking_mouse_button_emulation)
345 mouse_button_emulated = FALSE;
346
347 /*KLC - no headsets in Mac version
348
349 if (inp6d_exists)
350 #ifdef PLAYTEST
351 if (inp6d_motion)
352 #endif
353 {
354 switch (i6d_device)
355 {
356 #ifdef SPACEBALL_SUPPORT
357 case I6D_SBALL: sball_chk(); break;
358 #endif
359 #ifdef CTM_SUPPORT
360 case I6D_ALLPRO:
361 case I6D_CTM: ctm_chk(); break;
362 #endif
363 case I6D_CYBERMAN: cyberman_chk(); break;
364 #ifdef VFX1_SUPPORT
365 case I6D_VFX1: vfx1_chk(); break;
366 #endif
367 case I6D_SWIFT: swift_chk(); break;
368 default: inp6d_chk(); break;
369 }
370 }
371 if (joystick_count)
372 joystick_chk();
373 */
374
375 // if we're suppose to emulate a mouse button - let's do it!
376 if (mouse_button_emulated)
377 return (TRUE);
378 return (FALSE);
379 }
380
input_chk(void)381 void input_chk(void) {
382 extern void setup_motion_polling(void);
383 extern void process_motion_keys(void);
384
385 setup_motion_polling();
386 view3d_got_event = FALSE;
387 uiPoll();
388 if (!view3d_got_event)
389 poll_mouse();
390
391 // KLC - not needed on MAC kb_flush_bios();
392 // KLC - not needed on MAC mouse_set_velocity(0,0);
393
394 /* KLC - comment out for now
395 if (inp6d_exists)
396 #ifdef PLAYTEST
397 if (inp6d_motion)
398 #endif
399 {
400 switch (i6d_device)
401 {
402 #ifdef SPACEBALL_SUPPORT
403 case I6D_SBALL: sball_chk(); break;
404 #endif
405 #ifdef CTM_SUPPORT
406 case I6D_ALLPRO:
407 case I6D_CTM: ctm_chk(); break;
408 #endif
409 case I6D_CYBERMAN: cyberman_chk(); break;
410 #ifdef VFX1_SUPPORT
411 case I6D_VFX1: vfx1_chk(); break;
412 #endif
413 case I6D_SWIFT: swift_chk(); break;
414 default: inp6d_chk(); break;
415 }
416 }
417
418 if (joystick_count)
419 joystick_chk();
420 */
421 process_motion_keys();
422 handle_keyboard_fatigue();
423 }
424
425 #ifdef NOT_YET // KLC - stuff for VR headsets
426
427 #define Y_CEN 0
428 #define MAX_VAL (1 << 15)
429 #define TRA_TOL (MAX_VAL >> 8)
430 #define ROT_TOL (MAX_VAL >> 5)
431 #define Tra_Scale(x) (((x)*CONTROL_MAX_VAL) / (MAX_VAL - TRA_TOL))
432 #define Rot_Scale(x) (((x)*CONTROL_MAX_VAL) / (MAX_VAL - ROT_TOL))
433
434 #ifdef SPACEBALL_SUPPORT
435 // i really really really want to rewrite all of this cruft
436
437 #define abs(x) ((x) < 0 ? -(x) : (x))
438 #define isqr(x) (((x) * (x)) >> 16)
439 #define icube(x) ((isqr(x) * x) >> 16)
440 #define sign(x) ((x) < 0 ? -1 : 1)
441
442 int sb_rot_sens = 21;
443 int sb_tran_sens = 13;
444 int sb_pitch_sens = 35;
445 int sb_float_sens = 1;
446 int sb_jump_thresh = 40;
447 int sb_jump_sens = 30;
448 int sb_pitch_thresh = 5;
449 int sb_crouch_thresh = 60;
450 int sb_prone_thresh = 90;
451
452 // The number of pitch angles (looking up and down ) allowed
453 #define NUM_PITCH 10
454 int sb_num_pitch = NUM_PITCH;
455 int sb_pitch_div = 100 / NUM_PITCH;
456 int sb_pitch_angles = FALSE;
457
458 uchar sb_major_axis = FALSE;
459
FilterSpaceballDataMajorAxis(long * vals)460 void FilterSpaceballDataMajorAxis(long *vals) {
461 int i, ind;
462 long max;
463
464 max = abs(vals[0]);
465 ind = 0;
466
467 for (i = 1; i < 6; i++) {
468
469 if (abs(vals[i]) < max) {
470 vals[i] = 0;
471 continue;
472 }
473
474 max = abs(vals[i]);
475 vals[ind] = 0;
476 ind = i;
477 }
478 }
479
FilterSpaceballDataSimple(long * tx,long * ty,long * tz,long * rx,long * ry,long * rz)480 void FilterSpaceballDataSimple(long *tx, long *ty, long *tz, long *rx, long *ry, long *rz) {
481 *rx /= sb_pitch_sens;
482 *ry /= sb_rot_sens;
483 *rz /= sb_rot_sens;
484 *tx /= sb_tran_sens;
485 *ty /= sb_tran_sens;
486 *tz /= sb_jump_sens;
487 }
488
FilterSpaceballDataSquare(long * tx,long * ty,long * tz,long * rx,long * ry,long * rz)489 void FilterSpaceballDataSquare(long *tx, long *ty, long *tz, long *rx, long *ry, long *rz) {
490
491 *rx = sign(*rx) * isqr(*rx) / sb_pitch_sens;
492 *ry = icube(*ry) / sb_rot_sens;
493 *rz = sign(*rz) * isqr(*rz) / sb_rot_sens;
494 *tx = sign(*tx) * isqr(*tx) / sb_tran_sens;
495 *ty = sign(*ty) * isqr(*ty) / sb_tran_sens;
496 *tz = sign(*tz) * isqr(*tz) / sb_jump_sens;
497 }
498
FilterSpaceballDataFloating(long * tx,long * ty,long * tz,long * rx,long * ry,long * rz)499 void FilterSpaceballDataFloating(long *tx, long *ty, long *tz, long *rx, long *ry, long *rz) {
500 long max;
501
502 max = abs(*tx);
503
504 if (abs(*ty) > max)
505 max = abs(*ty);
506
507 if (abs(*tz) > max)
508 max = abs(*tz);
509
510 if (abs(*rx) > max)
511 max = abs(*rx);
512
513 if (abs(*ry) > max)
514 max = abs(*ry);
515
516 if (abs(*rz) > max)
517 max = abs(*rz);
518
519 *tx = ((*tx * (0x8000 - (max - abs(*tx)) * sb_float_sens)) >> 16) / sb_tran_sens;
520
521 *ty = ((*ty * (0x8000 - (max - abs(*ty)) * sb_float_sens)) >> 16) / sb_tran_sens;
522
523 *tz = ((*tz * (0x8000 - (max - abs(*tz)) * sb_float_sens)) >> 16) / sb_jump_sens;
524
525 *rx = ((*rx * (0x8000 - (max - abs(*rx)) * sb_float_sens)) >> 16) / sb_pitch_sens;
526
527 *ry = ((*ry * (0x8000 - (max - abs(*ry)) * sb_float_sens)) >> 16) / sb_rot_sens;
528
529 *rz = ((*rz * (0x8000 - (max - abs(*rz)) * sb_float_sens)) >> 16) / sb_rot_sens;
530 }
531
532 // *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
533 // WARNING *** These #defines are also used in panels.c - if your change them here be sure to change them there!
534
535 #define SB_FILTER_ORIG 0 // original SB input by Looking glass
536 #define SB_FILTER_SIMPLE 1 // Using a simple sensitivity value to map values
537 #define SB_FILTER_SQUARE 2 // Square the SB data to give emphasis to larger values and de-emphasize low values
538 #define SB_FILTER_FLOATING 3 // Floating sensitivity depending upon input from SB
539
FilterSpaceballDataOrig(long * tx,long * ty,long * tz,long * rx,long * ry,long * rz)540 void FilterSpaceballDataOrig(long *tx, long *ty, long *tz, long *rx, long *ry, long *rz) {
541
542 if (abs(*tx) > TRA_TOL) {
543
544 if (*tx > TRA_TOL)
545 *tx = Tra_Scale(*tx - TRA_TOL);
546 else
547 *tx = Tra_Scale(*tx + TRA_TOL);
548
549 }
550
551 else
552 *tx = 0;
553
554 if (abs(*ty) > TRA_TOL) {
555
556 if (*ty > TRA_TOL)
557 *ty = Tra_Scale(*ty - TRA_TOL);
558 else
559 *ty = Tra_Scale(*ty + TRA_TOL);
560
561 }
562
563 else
564 *ty = 0;
565
566 if (abs(*tz) > TRA_TOL) {
567
568 if (*tz > TRA_TOL)
569 *tz = Tra_Scale(*tz - TRA_TOL);
570 else
571 *tz = Tra_Scale(*tz + TRA_TOL);
572
573 } else
574 *tz = 0;
575
576 if (*rx > ROT_TOL)
577 *rx = Rot_Scale(*rx - ROT_TOL);
578 else if (*rx < -ROT_TOL)
579 *rx = Rot_Scale(*rx + ROT_TOL);
580 else
581 *rx = 0;
582
583 if (*ry > ROT_TOL)
584 *ry = Rot_Scale(*ry - ROT_TOL);
585 else if (*ry < -ROT_TOL)
586 *ry = Rot_Scale(*ry + ROT_TOL);
587 else
588 *ry = 0;
589
590 if (*rz > ROT_TOL)
591 *rz = Rot_Scale(*rz - ROT_TOL);
592 else if (*rz < -ROT_TOL)
593 *rz = Rot_Scale(*rz + ROT_TOL);
594 else
595 *rz = 0;
596 }
597
598 static void (*SbFilterFunc)(long *, long *, long *, long *, long *, long *) = FilterSpaceballDataSquare;
599
SetSbFilterFunc(int val)600 void SetSbFilterFunc(int val) {
601
602 switch (val) {
603
604 case SB_FILTER_ORIG:
605 SbFilterFunc = FilterSpaceballDataOrig;
606 break;
607
608 case SB_FILTER_SIMPLE:
609 SbFilterFunc = FilterSpaceballDataSimple;
610 break;
611
612 case SB_FILTER_SQUARE:
613 SbFilterFunc = FilterSpaceballDataSquare;
614 break;
615
616 case SB_FILTER_FLOATING:
617 SbFilterFunc = FilterSpaceballDataFloating;
618 break;
619 ;
620 }
621 }
622
623 #define JUMP_MULTIPLE 20
624
sball_jump_filter(int jump_val)625 sball_jump_filter(int jump_val) {
626 static int old_val = 0;
627 static int count = 0;
628
629 // mprintf( "Jump value %d ", jump_val );
630
631 // If the jump value is really a duck value then bag outta here
632 if (jump_val < 0)
633 return jump_val;
634
635 /* if ( count > 10 ) {
636
637 count = old_val = 0;
638 return jump_val;
639
640 }
641 */
642
643 // Make the jump value be a multiple of JUMP_MULTIPLE
644 jump_val = (jump_val / JUMP_MULTIPLE) * JUMP_MULTIPLE;
645
646 // mprintf( "%d\n", jump_val );
647
648 // If the jump value is in the same bin as the old duck value then
649 // we assume the is the jump value we want and return the value
650 if (old_val == jump_val) {
651
652 // mprintf( "Stable value %d\n", jump_val );
653 count = old_val = 0;
654 return jump_val;
655 }
656
657 // If the new value is in a bin that is less than the old value then
658 // (the person is letting up on the spaceball) then use the old value
659 // as the jump value
660 if (jump_val < old_val) {
661 int ret;
662
663 // mprintf( "Less value %d %d\n", old_val, jump_val );
664 ret = old_val;
665 count = old_val = 0;
666 return ret;
667 }
668
669 old_val = jump_val;
670 ++count;
671
672 return 0;
673 }
674
675 #define PITCH_MAX_DELTA 15
676
677 int sb_pitch_constant = FALSE;
678
679 #define SAMPLE_SIZE 20
680
FilterPitch(long * pitch)681 int FilterPitch(long *pitch) {
682 long i;
683 static long ring_buf[SAMPLE_SIZE];
684 static long ring_index = 0;
685
686 #if 0
687 static long max_val = 0;
688 #endif
689 long accum;
690
691 if (abs(*pitch) < sb_pitch_thresh)
692 *pitch = 0;
693
694 else {
695
696 if (*pitch > 0)
697 *pitch -= sb_pitch_thresh;
698 else
699 *pitch += sb_pitch_thresh;
700 }
701
702 #if 0
703 if ( sb_pitch_constant ) {
704
705 if ( max_val > 0 && *pitch > 0 ) {
706
707 if ( *pitch < max_val )
708 *pitch = max_val;
709 else
710 max_val = *pitch;
711
712 return FALSE;
713 }
714
715
716 if ( max_val < 0 && *pitch < 0 ) {
717
718 if ( *pitch > max_val )
719 *pitch = max_val;
720 else
721 max_val = *pitch;
722
723
724 return FALSE;
725 }
726
727 max_val += *pitch;
728 *pitch = max_val;
729
730 // mprintf( "%d %d\n", max_val, *pitch );
731
732 return FALSE;
733
734 }
735 #endif
736
737 ring_buf[ring_index] = *pitch;
738
739 ++ring_index;
740 if (ring_index == SAMPLE_SIZE)
741 ring_index = 0;
742
743 accum = 0;
744 for (i = 0; i < SAMPLE_SIZE; i++)
745 accum += ring_buf[i];
746
747 *pitch = accum / SAMPLE_SIZE;
748
749 if (*pitch)
750 return TRUE;
751
752 return FALSE;
753 }
754
sball_chk(void)755 void sball_chk(void) {
756 i6s_event *inp6d_in;
757 float foo;
758 long vals[6];
759
760 static int count = 0;
761 static int down_doo_be_doo = FALSE;
762 static int did_a_jump = FALSE;
763 static int doing_pitch = FALSE;
764
765 // we'll want to put in code here to check for mouse_button_emulation
766 // if (checking_mouse_button_emulation && <SOME CODE TO CHECK FOR BUTTON PRESS>)
767 // mouse_button_emulated = TRUE;
768
769 if (game_paused)
770 return;
771
772 if (did_a_jump)
773 physics_set_player_controls(INP6D_CONTROL_BANK, 0, 0, 0, 0, 0, 0);
774
775 inp6d_in = i6_poll();
776
777 if (inp6d_in == NULL) {
778 if (doing_pitch) {
779 inp6d_in->x = 0;
780 inp6d_in->y = 0;
781 inp6d_in->z = 0;
782 inp6d_in->rx = 0;
783 inp6d_in->ry = 0;
784 inp6d_in->rz = 0;
785 } else
786 return;
787 }
788
789 vals[0] = (float)inp6d_in->x * 0.9;
790 vals[1] = -inp6d_in->z;
791 vals[2] = inp6d_in->y;
792
793 foo = -(float)inp6d_in->ry * 1.8;
794
795 if (foo > 32000)
796 vals[3] = 32000;
797 else if (foo < -32000)
798 vals[3] = -32000;
799 else
800 vals[3] = foo;
801
802 vals[4] = inp6d_in->rx;
803 vals[5] = -(float)inp6d_in->rz * 0.9;
804
805 if (sb_major_axis)
806 FilterSpaceballDataMajorAxis(vals);
807
808 (*SbFilterFunc)(&vals[0], &vals[1], &vals[2], &vals[4], &vals[3], &vals[5]);
809
810 #ifdef PLAYTEST
811 if (!inp6d_player) {
812 /* mprintf("Parsed %d %d %d %d %d %d to %d %d %d %d %d %d\n",
813 inp6d_in->x, inp6d_in->y, inp6d_in->z, inp6d_in->rx,
814 inp6d_in->ry, inp6d_in->rz, vals[0], vals[1], vals[2],
815 vals[3], vals[4], vals[5] );
816 */
817 fr_camera_slewcam(NULL, EYE_X, vals[0] / 5);
818 fr_camera_slewcam(NULL, EYE_Y, vals[1] / 5);
819 fr_camera_slewcam(NULL, EYE_Z, vals[2] / 5);
820 fr_camera_slewcam(NULL, EYE_H, vals[3] / 3);
821 fr_camera_slewcam(NULL, EYE_P, vals[4] / 3);
822 fr_camera_slewcam(NULL, EYE_B, vals[5] / 3);
823 } else
824 #endif
825 {
826
827 if (abs(vals[2]) > sb_jump_thresh) {
828
829 if (vals[2] > 0)
830 vals[2] -= sb_jump_thresh;
831 else
832 vals[2] += sb_jump_thresh;
833
834 } else
835 vals[2] = 0;
836
837 doing_pitch = FilterPitch(&vals[4]);
838
839 if (abs(vals[0]) > CONTROL_MAX_VAL)
840 vals[0] = sign(vals[0]) * CONTROL_MAX_VAL;
841 if (abs(vals[1]) > CONTROL_MAX_VAL)
842 vals[1] = sign(vals[1]) * CONTROL_MAX_VAL;
843 if (abs(vals[2]) > CONTROL_MAX_VAL)
844 vals[2] = sign(vals[2]) * CONTROL_MAX_VAL;
845 if (abs(vals[3]) > CONTROL_MAX_VAL)
846 vals[3] = sign(vals[3]) * CONTROL_MAX_VAL;
847 if (abs(vals[4]) > CONTROL_MAX_VAL)
848 vals[4] = sign(vals[4]) * CONTROL_MAX_VAL;
849 if (abs(vals[5]) > CONTROL_MAX_VAL)
850 vals[5] = sign(vals[5]) * CONTROL_MAX_VAL;
851
852 vals[2] = sball_jump_filter(vals[2]);
853 if (vals[2] > 0)
854 did_a_jump = TRUE;
855
856 /* mprintf("%d Parsed %d %d %d %d %d %d to %d %d %d %d %d %d\n", count,
857 inp6d_in->x, inp6d_in->y, inp6d_in->z, inp6d_in->rx,
858 inp6d_in->ry, inp6d_in->rz, vals[0], vals[1], vals[2],
859 vals[3], vals[4], vals[5] );
860 */
861 ++count;
862
863 if (sb_pitch_angles)
864 vals[4] = (vals[4] / sb_pitch_div) * sb_pitch_div;
865
866 if (vals[2] >= 0) {
867
868 if (down_doo_be_doo) {
869 player_set_posture(POSTURE_STAND);
870 down_doo_be_doo = FALSE;
871 }
872
873 physics_set_player_controls(INP6D_CONTROL_BANK, vals[0], vals[1], vals[2], vals[3], 0, 0);
874
875 }
876
877 else {
878
879 physics_set_player_controls(INP6D_CONTROL_BANK, vals[0], vals[1], 0, vals[3], 0, 0);
880
881 if (abs(vals[2]) < sb_crouch_thresh) {
882 // mprintf( "Stand\n" );
883 player_set_posture(POSTURE_STAND);
884 down_doo_be_doo = FALSE;
885 }
886
887 else if (abs(vals[2]) < sb_prone_thresh * 2) {
888 // mprintf( "Stoop!\n" );
889 player_set_posture(POSTURE_STOOP);
890 down_doo_be_doo = TRUE;
891 }
892
893 else {
894 // mprintf( "Prone\n" );
895 player_set_posture(POSTURE_PRONE);
896 down_doo_be_doo = TRUE;
897 }
898 }
899
900 player_set_lean(vals[5], 0);
901 player_set_eye(vals[4]);
902 }
903 }
904 #endif
905
906 #endif // NOT_YET
907
main_kb_callback(uiEvent * h,LGRegion * r,intptr_t udata)908 uchar main_kb_callback(uiEvent *h, LGRegion *r, intptr_t udata) {
909
910 LGRegion *dummy2;
911 intptr_t dummy3;
912 dummy2 = r;
913 dummy3 = udata;
914
915 #ifdef INPUT_CHAINING
916 kb_flush_bios();
917 #endif // INPUT_CHAINING
918
919 if (h->type == UI_EVENT_KBD_COOKED)
920 return hotkey_dispatch(h->subtype) == OK;
921 return FALSE;
922 }
923
posture_hotkey_func(ushort keycode,uint32_t context,intptr_t data)924 uchar posture_hotkey_func(ushort keycode, uint32_t context, intptr_t data) {
925 #ifndef NO_DUMMIES
926 uint32_t dummy;
927 dummy = context + keycode;
928 #endif
929 return player_set_posture((unsigned int)data) == OK;
930 }
931
eye_hotkey_func(ushort keycode,uint32_t context,intptr_t data)932 uchar eye_hotkey_func(ushort keycode, uint32_t context, intptr_t data) {
933 extern void player_set_eye(byte);
934 extern byte player_get_eye(void);
935 byte eyectl = player_get_eye();
936 int r = 1 + (player_struct.drug_status[DRUG_REFLEX] > 0 && !global_fullmap->cyber);
937
938 if (data == 0) {
939 player_set_eye(0);
940 return TRUE;
941 }
942 for (; r > 0; r--) {
943 if (data < 0) {
944 if (eyectl > 0)
945 eyectl = 0;
946 else
947 eyectl = (eyectl - CONTROL_MAX_VAL) / 3;
948 } else {
949 if (eyectl < 0)
950 eyectl = 0;
951 else
952 eyectl = (eyectl + CONTROL_MAX_VAL) / 3;
953 }
954 }
955 player_set_eye(eyectl);
956 return TRUE;
957 }
958
959 #define EYE_POLLING
960 #ifndef EYE_POLLING
961 static ushort eye_up_keys[] = {
962 KEY_UP | KB_FLAG_SHIFT,
963 KEY_PAD_UP | KB_FLAG_SHIFT,
964 'r',
965 'R',
966 };
967
968 #define NUM_EYE_UP_KEYS (sizeof(eye_up_keys) / sizeof(ushort))
969
970 static ushort eye_dn_keys[] = {
971 KEY_DOWN | KB_FLAG_SHIFT,
972 KEY_PAD_DOWN | KB_FLAG_SHIFT,
973 'v',
974 'V',
975 };
976
977 #define NUM_EYE_DN_KEYS (sizeof(eye_dn_keys) / sizeof(ushort))
978 #endif // !EYE_POLLING
979
980 static ushort eye_lvl_keys[] = {
981 'f',
982 'F',
983 };
984
985 #define NUM_EYE_LVL_KEYS (sizeof(eye_lvl_keys) / sizeof(ushort))
986 // -------------------------------------
987 // INITIALIZATION
988 extern errtype simple_load_res_bitmap_cursor(LGCursor *c, grs_bitmap *bmp, Ref rid);
989 extern uchar unpause_game_func(ushort keycode, uint32_t context, intptr_t data);
990 extern uchar keyhelp_hotkey_func(ushort keycode, uint32_t context, intptr_t data);
991 extern uchar demo_quit_func(ushort keycode, uint32_t context, intptr_t data);
992 extern void init_side_icon_hotkeys(void);
993 extern void init_invent_hotkeys(void);
994 extern uchar toggle_view_func(ushort keycode, uint32_t context, intptr_t data);
995 uchar toggle_profile(ushort keycode, uint32_t context, intptr_t data);
996 #ifdef PLAYTEST
997 extern uchar automap_seen(ushort keycode, uint32_t context, intptr_t data);
998 extern uchar maim_player(ushort keycode, uint32_t context, intptr_t data);
999 extern uchar salt_the_player(ushort keycode, uint32_t context, intptr_t data);
1000 extern uchar give_player_hotkey(ushort keycode, uint32_t context, intptr_t data);
1001 extern uchar change_clipper(ushort keycode, uint32_t context, intptr_t data);
1002 #endif
1003 #ifndef PLAYTEST
1004 extern uchar version_spew_func(ushort keycode, uint32_t context, intptr_t data);
1005 extern uchar location_spew_func(ushort keycode, uint32_t context, intptr_t data);
1006 #endif
1007
1008 #define ckpoint_input(val) Spew(DSRC_TESTING_Test0, ("ii %s @%d\n", val, *tmd_ticks));
1009
reload_motion_cursors(uchar cyber)1010 void reload_motion_cursors(uchar cyber)
1011 {
1012 extern short cursor_color_offset;
1013
1014 for (int i = 0; i < NUM_MOTION_CURSORS; i++)
1015 {
1016 grs_bitmap *bm = &motion_cursor_bitmaps[i];
1017 if (bm->bits != NULL)
1018 {
1019 free(bm->bits);
1020 memset(bm, 0, sizeof(grs_bitmap));
1021 }
1022 }
1023
1024 if (!cyber)
1025 {
1026 for (int i = 0; i < NUM_MOTION_CURSORS; i++)
1027 {
1028 grs_bitmap *bm = &motion_cursor_bitmaps[i];
1029 if (motion_cursor_ids[i] != 0)
1030 load_res_bitmap_cursor(&motion_cursors[i], bm, motion_cursor_ids[i], TRUE);
1031 }
1032
1033 // slam the cursor color back to it's childhood colors
1034 cursor_color_offset = RED_BASE + 4;
1035
1036 void SetMotionCursorsColorForActiveWeapon(void);
1037 SetMotionCursorsColorForActiveWeapon();
1038 }
1039 else
1040 {
1041 for (int i = 0; i < NUM_CYBER_CURSORS; i++)
1042 {
1043 grs_bitmap *bm = &motion_cursor_bitmaps[i];
1044 load_res_bitmap_cursor(&motion_cursors[i], bm, CYBER_CURSOR_BASE + i, TRUE);
1045 }
1046 }
1047 }
1048
free_cursor_bitmaps(void)1049 void free_cursor_bitmaps(void)
1050 {
1051 //reload_motion_cursors() does everything now
1052 }
1053
alloc_cursor_bitmaps(void)1054 void alloc_cursor_bitmaps(void)
1055 {
1056 //reload_motion_cursors() does everything now
1057
1058 //I would just like to point out that this function
1059 //was a good example of what were they thinking?
1060 }
1061
1062 #include "frtypes.h"
1063 extern bool gPlayingGame;
1064 extern bool DoubleSize;
1065 extern bool SkipLines;
1066 extern void change_svga_screen_mode(void);
1067 bool gShowFrameCounter = false;
1068 bool gShowMusicGlobals = false;
1069
MacQuitFunc(ushort keycode,uint32_t context,intptr_t data)1070 uchar MacQuitFunc(ushort keycode, uint32_t context, intptr_t data) {
1071 gPlayingGame = FALSE;
1072 return TRUE;
1073 }
1074
MacResFunc(ushort keycode,uint32_t context,intptr_t data)1075 uchar MacResFunc(ushort keycode, uint32_t context, intptr_t data) {
1076 DoubleSize = !DoubleSize;
1077 change_svga_screen_mode();
1078
1079 if (DoubleSize)
1080 message_info("Low res.");
1081 else {
1082 message_info("High res.");
1083 SkipLines = FALSE;
1084 }
1085 gShockPrefs.doResolution = (DoubleSize) ? 1 : 0; // KLC - Yeah, got to update this one too
1086 gShockPrefs.doUseQD = SkipLines; // KLC - and this one
1087 SavePrefs(); // KLC - and save the prefs out to disk.
1088
1089 return TRUE;
1090 }
1091
MacSkiplinesFunc(ushort keycode,uint32_t context,intptr_t data)1092 uchar MacSkiplinesFunc(ushort keycode, uint32_t context, intptr_t data) {
1093 if (!DoubleSize) // Skip lines only applies in double-size mode.
1094 {
1095 message_info("Skip lines works only in low-res mode.");
1096 return FALSE;
1097 }
1098 SkipLines = !SkipLines;
1099 gShockPrefs.doUseQD = SkipLines;
1100 SavePrefs();
1101 return TRUE;
1102 }
1103
MacDetailFunc(ushort keycode,uint32_t context,intptr_t data)1104 uchar MacDetailFunc(ushort keycode, uint32_t context, intptr_t data) {
1105 char msg[32];
1106 char detailStr[8];
1107 fauxrend_context *_frc = (fauxrend_context *)svga_render_context;
1108
1109 if (_frc->detail == 4) // Adjust for that global detail nonsense.
1110 _frc->detail = _fr_global_detail;
1111
1112 _frc->detail++; // Cycle through the detail levels.
1113 if (_frc->detail >= 4)
1114 _frc->detail = 0;
1115 _fr_global_detail = _frc->detail; // Update the global guy.
1116
1117 gShockPrefs.doDetail = _frc->detail; // Update and save our prefs.
1118 SavePrefs();
1119
1120 switch (_frc->detail) // Show a nice, informative message.
1121 {
1122 case 0:
1123 strcpy(detailStr, "Min");
1124 break;
1125 case 1:
1126 strcpy(detailStr, "Low");
1127 break;
1128 case 2:
1129 strcpy(detailStr, "High");
1130 break;
1131 case 3:
1132 strcpy(detailStr, "Max");
1133 }
1134 sprintf(msg, "Detail level: %s", detailStr);
1135 message_info(msg);
1136 return TRUE;
1137 }
1138
1139 /*
1140 // Temporary function. Remove for final build
1141
1142 uchar temp_FrameCounter_func(ushort keycode, uint32_t context, intptr_t data)
1143 {
1144 gShowFrameCounter = !gShowFrameCounter;
1145
1146 if (gShowFrameCounter)
1147 message_info("Frame counter on.");
1148 else
1149 message_info("Frame counter off.");
1150 }
1151
1152 // end temp functions
1153 */
1154
1155 /*
1156 uchar MacHelpFunc(ushort keycode, uint32_t context, intptr_t data) {
1157 if (music_on) // Setup the environment for doing Mac stuff.
1158 MacTuneKillCurrentTheme();
1159 uiHideMouse(NULL);
1160 status_bio_end();
1161
1162 // CopyBits(&gMainWindow->portBits, &gMainOffScreen.bits->portBits, &gActiveArea, &gOffActiveArea, srcCopy, 0L);
1163
1164 SS_ShowCursor();
1165
1166 // ShowShockHelp();
1167
1168 SetPort(gMainWindow); // Update area behind the alert
1169 // BeginUpdate(gMainWindow);
1170
1171 // CopyBits(&gMainOffScreen.bits->portBits, &gMainWindow->portBits, &gOffActiveArea, &gActiveArea, srcCopy, 0L);
1172
1173 // EndUpdate(gMainWindow);
1174
1175 HideCursor(); // go back to Shock.
1176 uiShowMouse(NULL);
1177 status_bio_start();
1178 if (music_on)
1179 MacTuneStartCurrentTheme();
1180
1181 return TRUE;
1182 }
1183 */
1184
toggle_opengl_func(ushort keycode,uint32_t context,intptr_t data)1185 uchar toggle_opengl_func(ushort keycode, uint32_t context, intptr_t data) {
1186 toggle_opengl();
1187 return TRUE;
1188 }
1189
1190 //most of original init_input() is now either commented out or done elsewhere, so do what's left here
1191 //and comment out original function below
init_input(void)1192 void init_input(void) {
1193 uiDoubleClickDelay = 8;
1194 uiDoubleClickTime = 45;
1195 uiDoubleClicksOn[MOUSE_LBUTTON] = TRUE; // turn on left double clicks
1196 uiAltDoubleClick = TRUE;
1197
1198 alloc_cursor_bitmaps();
1199 reload_motion_cursors(FALSE);
1200 }
1201
1202 /*
1203 void init_input(void) {
1204 extern void init_motion_polling();
1205 int i = 0;
1206 // KLC int kbdt, joy_type;
1207 int dvec[2];
1208
1209 // init keyboard
1210 // KLC for (i = 0; i < 0x80; i++)
1211 // KLC kb_clear_state(i,KBA_REPEAT);
1212 hotkey_init(NUM_HOTKEYS);
1213
1214 // KLC
1215 // kbdt=dt_keyboard();
1216 // if (kbdt!=kb_get_country())
1217 // {
1218 // kb_set_country(kbdt);
1219 // Warning(("Setting kb country to %d\n",kbdt));
1220 // }
1221 //
1222 init_motion_polling();
1223
1224 // init mouse
1225 // KLC mouse_set_timestamp_register((ulong*)tmd_ticks);
1226 dvec[0] = 8; // KLC 30; // default double click deleay;
1227 dvec[1] = 45; // 175; // default double click time
1228 i = 2;
1229 // KLC config_get_value(CFG_DCLICK_RATE_VAR,CONFIG_INT_TYPE,dvec,&i);
1230 uiDoubleClickDelay = dvec[0];
1231 uiDoubleClickTime = dvec[1];
1232 uiDoubleClicksOn[MOUSE_LBUTTON] = TRUE; // turn on left double clicks
1233 uiAltDoubleClick = TRUE;
1234 i = 1;
1235 //uiSetMouseMotionPolling(TRUE);
1236
1237 // Load cursors
1238
1239 alloc_cursor_bitmaps();
1240 reload_motion_cursors(FALSE);
1241
1242 // GAME HOTKEYS
1243
1244 // MFDs
1245 keyboard_init_mfd();
1246
1247 // Game wrapper hotkeys
1248 // these are in all versions, playtest and not
1249 hotkey_add(CONTROL('f'), DEMO_CONTEXT, change_mode_func, FULLSCREEN_LOOP);
1250 #ifdef AUDIOLOGS
1251 hotkey_add(CONTROL('.'), DEMO_CONTEXT, audiolog_cancel_func, 0);
1252 #endif
1253 hotkey_add(CONTROL('s'), DEMO_CONTEXT, save_hotkey_func, 0);
1254 hotkey_add(CONTROL('S'), DEMO_CONTEXT, save_hotkey_func, 0);
1255 hotkey_add(CONTROL('l'), DEMO_CONTEXT, saveload_hotkey_func, TRUE);
1256 hotkey_add(CONTROL('L'), DEMO_CONTEXT, saveload_hotkey_func, TRUE);
1257
1258 //KLC - not in Mac version
1259 // hotkey_add('?', DEMO_CONTEXT, keyhelp_hotkey_func, 0);
1260 //
1261 // hotkey_add('/',DEMO_CONTEXT,toggle_bool_func,&joystick_mouse_emul);
1262 //
1263 hotkey_add(ALT(KEY_BS), DEMO_CONTEXT, reload_weapon_hotkey, 0);
1264 hotkey_add(CONTROL(KEY_BS), DEMO_CONTEXT, reload_weapon_hotkey, 1);
1265 hotkey_add(ALT('\''), DEMO_CONTEXT, arm_grenade_hotkey, 0);
1266 hotkey_add(CONTROL('\''), DEMO_CONTEXT, select_grenade_hotkey, 0);
1267 hotkey_add(ALT(';'), DEMO_CONTEXT, use_drug_hotkey, 0);
1268 hotkey_add(CONTROL(';'), DEMO_CONTEXT, select_drug_hotkey, 0);
1269
1270 //#ifndef PLAYTEST
1271 // hotkey_add(DOWN(KEY_PRNTSCRN), EVERY_CONTEXT, gifdump_func, 0);
1272
1273 hotkey_add(DOWN(KEY_BS), DEMO_CONTEXT, clear_fullscreen_func, 0);
1274 hotkey_add(ALT('h'), DEMO_CONTEXT, hud_color_bank_cycle, 0);
1275 hotkey_add(ALT('H'), DEMO_CONTEXT, hud_color_bank_cycle, 0);
1276 hotkey_add(CONTROL('m'), DEMO_CONTEXT, toggle_music_func, 0);
1277 hotkey_add(CONTROL('M'), DEMO_CONTEXT, toggle_music_func, 0);
1278 // hotkey_add(DOWN(KEY_SPACE),DEMO_CONTEXT,unpause_game_func,TRUE);
1279
1280 hotkey_add(DOWN('f'), DEMO_CONTEXT, toggle_mouse_look, TRUE);
1281
1282 hotkey_add(DOWN('p'), DEMO_CONTEXT, pause_game_func, TRUE);
1283
1284 // Cheats!
1285 hotkey_add(CONTROL('2'), DEMO_CONTEXT, toggle_giveall_func, TRUE);
1286 hotkey_add(CONTROL('3'), DEMO_CONTEXT, toggle_physics_func, TRUE);
1287 hotkey_add(CONTROL('4'), DEMO_CONTEXT, toggle_up_level_func, TRUE);
1288 hotkey_add(CONTROL('5'), DEMO_CONTEXT, toggle_down_level_func, TRUE);
1289
1290 hotkey_add(DOWN(KEY_ESC), DEMO_CONTEXT, wrapper_options_func, TRUE);
1291 for (i = 0; i < NUM_POSTURES; i++) {
1292 hotkey_add(DOWN(posture_keys[i]), DEMO_CONTEXT, posture_hotkey_func, i);
1293 hotkey_add(DOWN(toupper(posture_keys[i])), DEMO_CONTEXT, posture_hotkey_func, i);
1294 }
1295 hotkey_add(CONTROL('q'), DEMO_CONTEXT, MacQuitFunc, 0);
1296 hotkey_add(CONTROL('1'), DEMO_CONTEXT, MacDetailFunc, 0);
1297 hotkey_add(CONTROL('/'), DEMO_CONTEXT, MacHelpFunc, 0);
1298 hotkey_add(CONTROL('?'), DEMO_CONTEXT, MacHelpFunc, 0);
1299
1300 //
1301 // hotkey_add(ALT('x'),DEMO_CONTEXT,demo_quit_func,0);
1302 // hotkey_add(ALT('x'),SETUP_CONTEXT,really_quit_key_func,0);
1303 // hotkey_add(ALT('v'),DEMO_CONTEXT,toggle_view_func,0);
1304 // hotkey_add(ALT('V'),DEMO_CONTEXT,toggle_view_func,0);
1305 // hotkey_add(ALT(KEY_F7),DEMO_CONTEXT,version_spew_func,0);
1306 //
1307 // hotkey_add(CONTROL('8'),DEMO_CONTEXT,location_spew_func,0); //testing
1308 // hotkey_add(CONTROL('0'),DEMO_CONTEXT,temp_FrameCounter_func, 0); //testing
1309
1310 hotkey_add(CONTROL('d'), DEMO_CONTEXT, change_mode_func, GAME_LOOP);
1311 hotkey_add(CONTROL('D'), DEMO_CONTEXT, change_mode_func, FULLSCREEN_LOOP);
1312 hotkey_add(CONTROL('a'), DEMO_CONTEXT, change_mode_func, AUTOMAP_LOOP);
1313 hotkey_add(CONTROL('A'), DEMO_CONTEXT, change_mode_func, AUTOMAP_LOOP);
1314 //
1315 //#else
1316 // hotkey_add(DOWN(KEY_SPACE),DEMO_CONTEXT,unpause_game_func,TRUE);
1317 // hotkey_add(CONTROL('a'), DEMO_CONTEXT, change_mode_func, AUTOMAP_LOOP);
1318 // hotkey_add(CONTROL('A'), DEMO_CONTEXT, change_mode_func, AUTOMAP_LOOP);
1319 //
1320 // hotkey_add_help(DOWN(KEY_BS), DEMO_CONTEXT,clear_fullscreen_func, 0,
1321 // "Clears all overlays from the fullscreen view.");
1322 // hotkey_add_help(DOWN(KEY_PAUSE),DEMO_CONTEXT,pause_game_func,TRUE, "pause the game, gee.");
1323 // hotkey_add_help(DOWN('p'),DEMO_CONTEXT,pause_game_func,TRUE, "pause the game, gee.");
1324 // hotkey_add_help(DOWN(KEY_ESC),DEMO_CONTEXT,wrapper_options_func,TRUE,
1325 // "Opens up the options menu on the main game screen.");
1326 // hotkey_add_help(CONTROL('h'), DEMO_CONTEXT, hud_color_bank_cycle, 0, "cycle hud colors");
1327 // hotkey_add_help(CONTROL('H'), DEMO_CONTEXT, hud_color_bank_cycle, 0, "cycle hud colors");
1328 // hotkey_add_help(CONTROL(ALT('~')),EVERY_CONTEXT,toggle_profile,TRUE, "toggle profile");
1329 //
1330 // for (i = 0; i < NUM_POSTURES; i++)
1331 // {
1332 // hotkey_add_help(DOWN(posture_keys[i]),DEMO_CONTEXT,posture_hotkey_func,i,"change posture");
1333 // hotkey_add_help(DOWN(toupper(posture_keys[i])),DEMO_CONTEXT,posture_hotkey_func,i,"change posture");
1334 // }
1335 // hotkey_add_help(ALT('x'),EDIT_CONTEXT|SETUP_CONTEXT,quit_key_func,0,"quit, but ask for confirm.");
1336 // hotkey_add_help(ALT('x'),DEMO_CONTEXT,demo_quit_func,0,"quit, but ask for confirm on options panel.");
1337 // hotkey_add_help(ALT('X'),EVERY_CONTEXT,really_quit_key_func,0, "quit, no questions asked.");
1338 // hotkey_add_help(ALT('v'),EVERY_CONTEXT,toggle_view_func,0, "toggles between game mode and fullscreen mode.");
1339 // hotkey_add_help(ALT('V'),EVERY_CONTEXT,toggle_view_func,0, "toggles between game mode and fullscreen mode.");
1340 // hotkey_add(ALT('d'),EVERY_CONTEXT,mono_config_func,0
1341 //
1342 // // these are some random hotkeys - debugging
1343 // hotkey_add(CONTROL('q'),EVERY_CONTEXT,maim_player,"maim player");
1344 // hotkey_add(CONTROL('z'),EVERY_CONTEXT,change_clipper,"maim player");
1345 // hotkey_add(ALT(KEY_F2),EVERY_CONTEXT,salt_the_player, "Salt the Player");
1346 // hotkey_add(ALT(KEY_F3),EVERY_CONTEXT,give_player_hotkey, "Give Player Loot");
1347 //
1348 // // Meta-slewing
1349 // hotkey_add(DOWN('r'), EDIT_CONTEXT, stupid_slew_func, 13);
1350 // hotkey_add(DOWN('>'), DEMO_CONTEXT|EDIT_CONTEXT, stupid_slew_func, 14);
1351 // hotkey_add(DOWN('<'), DEMO_CONTEXT|EDIT_CONTEXT, stupid_slew_func, 15);
1352 //
1353 // // 3d zoomin
1354 // hotkey_add(CONTROL('['), DEMO_CONTEXT|EDIT_CONTEXT, zoom_3d_func, TRUE);
1355 // hotkey_add(CONTROL(']'), DEMO_CONTEXT|EDIT_CONTEXT, zoom_3d_func, FALSE);
1356 //
1357 // ckpoint_input("hotkeys in");
1358 //
1359 // hotkey_add(DOWN('['),EDIT_CONTEXT,zoom_func,ZOOM_IN);
1360 // hotkey_add(DOWN(']'),EDIT_CONTEXT,zoom_func,ZOOM_OUT);
1361 // hotkey_add(CONTROL('d'),EDIT_CONTEXT,to_demo_mode_func,0);
1362 //
1363 //#endif
1364 // hotkey_add(KEY_F11,DEMO_CONTEXT|EDIT_CONTEXT,change_gamma, 1);
1365 // hotkey_add(KEY_F12,DEMO_CONTEXT|EDIT_CONTEXT,change_gamma,-1);
1366 //
1367 hotkey_add(CONTROL('h'), DEMO_CONTEXT, toggle_olh_func, 0);
1368 hotkey_add(CONTROL('H'), DEMO_CONTEXT, toggle_olh_func, 0);
1369 hotkey_add(ALT('o'), DEMO_CONTEXT, olh_overlay_func, &olh_overlay_on);
1370 hotkey_add(ALT('O'), DEMO_CONTEXT, olh_overlay_func, &olh_overlay_on);
1371 hotkey_add(CONTROL('g'), EVERY_CONTEXT, toggle_opengl_func, 0);
1372 //
1373 // // take these ifdefs out if memory bashing on shippable
1374 //// hotkey_add(ALT(CONTROL(KEY_F4)),EVERY_CONTEXT,texture_annihilate_func,0);
1375 //#ifdef RCACHE_TEST
1376 // hotkey_add(ALT(KEY_F4),EVERY_CONTEXT,res_cache_usage_func,TRUE);
1377 // hotkey_add(CONTROL(KEY_F4),EVERY_CONTEXT,res_cache_usage_func,FALSE);
1378 //#endif
1379 // init_side_icon_hotkeys();
1380 //
1381 init_invent_hotkeys();
1382
1383 //for (i = 0; i < NUM_EYE_LVL_KEYS; i++)
1384 //{
1385 // hotkey_add(DOWN(eye_lvl_keys[i]),DEMO_CONTEXT,eye_hotkey_func,0);
1386 //}
1387
1388 // KLC - stuff for VR headsets
1389 // if (config_get_raw(CFG_INP6D_GO,NULL,0))
1390 // {
1391 // ckpoint_input("inp6d start");
1392 //
1393 // // hack for these config variables, not sure where else to put them
1394 // inp6d_hdouble = config_get_raw("inp6d_hdouble",NULL,0);
1395 // inp6d_pdouble = config_get_raw("inp6d_pdouble",NULL,0);
1396 // inp6d_bdouble = config_get_raw("inp6d_bdouble",NULL,0);
1397 //
1398 //#if defined(VFX1_SUPPORT)||defined(CTM_SUPPORT)||defined(SPACEBALL_SUPPORT)
1399 // inp6d_exists=(i6_probe()==0 && i6_startup()==0);
1400 // if ((config_get_raw("inp6d_force",NULL,0)))
1401 // inp6d_exists=(i6_force(I6D_VFX1) == 0);
1402 //#else
1403 // inp6d_exists=(i6_probe_small()==0 && i6_startup()==0);
1404 //#endif
1405 //#if defined(VFX1_SUPPORT)||defined(CTM_SUPPORT)
1406 // if ((i6d_device==I6D_VFX1)||(i6d_device==I6D_CTM)||(i6d_device==I6D_ALLPRO))
1407 // {
1408 // extern uchar fullscrn_vitals, fullscrn_icons;
1409 // i6s_event *inp6d_geth;
1410 // do {
1411 // inp6d_geth=i6_poll();
1412 // } while (inp6d_geth==NULL);
1413 //
1414 // {
1415 // hotkey_add(ALT('g'),DEMO_CONTEXT|EDIT_CONTEXT,recenter_headset,0);
1416 // inp6d_headset=TRUE;
1417 // tracker_initial_pos[0]= inp6d_geth->ry;
1418 // tracker_initial_pos[1]= inp6d_geth->rx;
1419 // tracker_initial_pos[2]=-inp6d_geth->rz;
1420 // fullscrn_vitals=fullscrn_icons=FALSE;
1421 // if (i6_video(I6VID_STARTUP,NULL))
1422 // Warning(("Headset video startup failed\n"));
1423 // if ((config_get_raw("inp6d_stereo",NULL,0))&&(i6d_device!=I6D_ALLPRO))
1424 // {
1425 // int cnt=1, rval[1];
1426 // if (i6_video(I6VID_STR_START,NULL))
1427 // Warning(("Headset stereo startup failed\n"));
1428 // else
1429 // { inp6d_stereo=TRUE; inp6d_stereo_active=FALSE; }
1430 // config_get_value("inp6d_stereo",CONFIG_INT_TYPE,rval,&cnt);
1431 // if (cnt>0) inp6d_stereo_div=rval[0];
1432 // }
1433 // if (config_get_raw("inp6d_doom",NULL,0))
1434 // inp6d_doom=TRUE;
1435 // }
1436 // } // end of is it a tracker....
1437 //#endif
1438 // ckpoint_input("inp6d end");
1439 // } else inp6d_exists=FALSE;
1440 // {
1441 // int cnt=1, rval[1];
1442 // config_get_value("joystick",CONFIG_INT_TYPE,rval,&cnt);
1443 // if (cnt>0)
1444 // {
1445 // extern ushort wrap_joy_type;
1446 // extern ushort high_joy_flags;
1447 // joy_type=rval[0];
1448 // wrap_joy_type = joy_type & ~JOY_NO_NGP;
1449 // high_joy_flags = joy_type & JOY_NO_NGP;
1450 // }
1451 // }
1452 // if (joystick_count=joy_init(joy_type))
1453 // {
1454 //#ifdef PLAYTEST
1455 // mprintf("Got %d joystick pots\n",joystick_count);
1456 //#endif
1457 // hotkey_add(ALT('j'),DEMO_CONTEXT|EDIT_CONTEXT,recenter_joystick,0);
1458 // }
1459 //
1460 }
1461 */
1462
shutdown_input(void)1463 void shutdown_input(void) {
1464 hotkey_shutdown();
1465 kb_flush_bios();
1466
1467 // kb_clear_state(0x1d, 3);
1468 // kb_clear_state(0x9d, 3);
1469 // kb_clear_state(0x38, 3);
1470 // kb_clear_state(0xb8, 3);
1471 }
1472
1473 // ------------------------
1474 // 3D VIEW/MOTION INTERFACE
1475 // ------------------------
1476
1477 // -------
1478 // DEFINES
1479 // -------
1480
1481 #define VIEW_LSIDE 0
1482 #define VIEW_HCENTER 1
1483 #define VIEW_RSIDE 2
1484
1485 #define VIEW_TOP 0
1486 #define VIEW_BOTTOM 4
1487 #define VIEW_VCENTER 8
1488 #define VIEW_WAYTOP 12
1489
1490 #define CYBER_VIEW_TOP 0
1491 #define CYBER_VIEW_CENTER 3
1492 #define CYBER_VIEW_BOTTOM 6
1493
1494 #define CENTER_WD_N 1
1495 #define CENTER_WD_D 8
1496 #define CYBER_CENTER_WD_D 6
1497 #define CENTER_HT_N 1
1498 #define CENTER_HT_D 8
1499 #define CYBER_CENTER_HT_D 6
1500
1501 // -------
1502 // GLOBALS
1503 // -------
1504
1505 short object_on_cursor = 0;
1506 LGCursor object_cursor;
1507
1508 // ------------------------------------------------------------------------------
1509 // view3d_rightbutton_handler deals with firing/throwing objects in 3d.
1510
1511 uchar mouse_jump_ui = TRUE;
1512 uchar fire_slam = FALSE;
1513 uchar left_down_jump = FALSE;
1514
reset_input_system(void)1515 void reset_input_system(void) {
1516 if (fire_slam) {
1517 if (full_game_3d)
1518 uiPopSlabCursor(&fullscreen_slab);
1519 else
1520 uiPopSlabCursor(&main_slab);
1521 fire_slam = FALSE;
1522 }
1523 mouse_unconstrain();
1524 }
1525
1526 #define DROP_REGION_Y(reg) ((reg)->abs_y + 7 * RectHeight((reg)->r) / 8)
1527 uchar weapon_button_up = TRUE;
1528
1529 // ---------
1530 // INTERNALS
1531 // ---------
1532
1533 // -------------------------------------------------------------------------------------------
1534 // CalcMotionCurOffset gets cursor position offset data for
1535 // SetMotionCursorForMouseXY() and view3d_mouse_input()
1536
CalcMotionCurOffset(uchar cyber,LGRegion * reg,short * cx,short * cy,short * cw,short * ch,short * x,short * y)1537 void CalcMotionCurOffset(uchar cyber, LGRegion *reg, short *cx, short *cy, short *cw, short *ch, short *x, short *y)
1538 {
1539 if (DoubleSize)
1540 {
1541 (*x) *= 2;
1542 (*y) *= 2;
1543 }
1544
1545 if (!cyber)
1546 {
1547 (*cx) = reg->abs_x + RectWidth(reg->r) / 2;
1548 (*cy) = reg->abs_y + 2 * RectHeight(reg->r) / 3;
1549 (*cw) = RectWidth(reg->r) * CENTER_WD_N / CENTER_WD_D;
1550 (*ch) = RectHeight(reg->r) * CENTER_HT_N / CENTER_HT_D;
1551 }
1552 else
1553 {
1554 (*cx) = reg->abs_x + RectWidth(reg->r) / 2;
1555 (*cy) = reg->abs_y + RectHeight(reg->r) / 2;
1556 (*cw) = RectWidth(reg->r) * CENTER_WD_N / CYBER_CENTER_WD_D;
1557 (*ch) = RectHeight(reg->r) * CENTER_HT_N / CYBER_CENTER_HT_D;
1558 }
1559
1560 #ifdef SVGA_SUPPORT
1561 ss_point_convert(cx, cy, FALSE);
1562 ss_point_convert(cw, ch, FALSE);
1563 #endif
1564
1565 (*x) -= (*cx);
1566 (*y) -= (*cy);
1567 }
1568
1569 // -------------------------------------------------------------------------------------------
1570 // SetMotionCursorForMouseXY sets motion cursor for current mouse x,y position
1571
1572 // Used to set cursor to weapon color immediately without having to move the mouse
1573
1574 // called at end of:
1575 // fullscreen_start() fullscrn.c
1576 // screen_start() screen.c
1577
SetMotionCursorForMouseXY(void)1578 void SetMotionCursorForMouseXY(void)
1579 {
1580 if (global_fullmap->cyber) return;
1581
1582 int cnum;
1583
1584 LGRegion *reg;
1585
1586 if (full_game_3d)
1587 reg = fullview_region;
1588 else
1589 reg = mainview_region;
1590
1591 extern int mlook_enabled;
1592
1593 if (mlook_enabled)
1594 cnum = VIEW_HCENTER | VIEW_VCENTER;
1595 else
1596 {
1597 short cx, cy, cw, ch, x, y;
1598
1599 mouse_get_xy(&x, &y);
1600
1601 CalcMotionCurOffset(FALSE, reg, &cx, &cy, &cw, &ch, &x, &y);
1602
1603 if (x < -cw) cnum = VIEW_LSIDE;
1604 else if (x > cw) cnum = VIEW_RSIDE;
1605 else cnum = VIEW_HCENTER;
1606
1607 if (y < -ch) cnum |= VIEW_TOP;
1608 else if (y > ch) cnum |= VIEW_BOTTOM;
1609 else cnum |= VIEW_VCENTER;
1610 }
1611
1612 LGCursor *c = &motion_cursors[cnum];
1613
1614 if (reg == fullview_region)
1615 uiSetGlobalDefaultCursor(c);
1616 else
1617 uiSetRegionDefaultCursor(reg, c);
1618 }
1619
1620 // -------------------------------------------------------------------------------------------
1621 // view3d_mouse_input sets/unsets physics controls based on mouse position in 3d
1622
1623 // return whether any control was applied
view3d_mouse_input(LGPoint pos,LGRegion * reg,uchar move,int * lastsect)1624 int view3d_mouse_input(LGPoint pos, LGRegion *reg, uchar move,
1625 int *lastsect) { // do we really recompute these every frame?? couldnt we have a context or
1626 // something... something, a call to reinit, something
1627 static int dougs_goofy_hack = FALSE;
1628
1629 int cnum = 0;
1630 byte xvel = 0;
1631 byte yvel = 0;
1632 byte xyrot = 0;
1633 uchar thrust = FALSE;
1634 uchar cyber = global_fullmap->cyber && time_passes;
1635
1636 short cx, cy, cw, ch, x, y;
1637
1638 x = pos.x;
1639 y = pos.y;
1640
1641 CalcMotionCurOffset(cyber, reg, &cx, &cy, &cw, &ch, &x, &y);
1642
1643 // ok, the idea here is to make sure single left click doesnt move, or at least tells you whats up...
1644 if ((dougs_goofy_hack == FALSE) && move) {
1645 dougs_goofy_hack = TRUE;
1646 move = FALSE;
1647 } else if (!move)
1648 dougs_goofy_hack = FALSE;
1649
1650 if (x < -cw) {
1651 cnum = VIEW_LSIDE;
1652 if (move) {
1653 xyrot = (x + cw) * 100 / (cx - cw - reg->abs_x);
1654 }
1655 } else if (x > cw) {
1656 cnum = VIEW_RSIDE;
1657 if (move)
1658 xyrot = (x - cw) * 100 / (cx - cw - reg->abs_x);
1659 } else
1660 cnum = VIEW_HCENTER;
1661
1662 if (cyber) {
1663 if (y < -ch) {
1664 if (move)
1665 yvel = -(-ch - y) * CONTROL_MAX_VAL / (cy - ch - reg->abs_y);
1666 cnum += CYBER_VIEW_TOP;
1667 } else if (y > ch) {
1668 cnum += CYBER_VIEW_BOTTOM;
1669 if (move) {
1670 #ifdef CYBER_ROLL_REGION
1671 if (xyrot == 0)
1672 #endif // CYBER_ROLL_REGION
1673 yvel = -(ch - y) * CONTROL_MAX_VAL / (cy - ch - reg->abs_y);
1674 #ifdef CYBER_ROLL_REGION
1675 else {
1676 xvel = xyrot;
1677 xyrot = 0;
1678 }
1679 #endif // CYBER_ROLL_REGION
1680 }
1681 } else {
1682 if ((thrust = ((cnum == VIEW_HCENTER) && move)) == TRUE)
1683 physics_set_one_control(MOUSE_CONTROL_BANK, CONTROL_ZVEL, MAX_JUMP_CONTROL);
1684
1685 cnum += CYBER_VIEW_CENTER;
1686 }
1687 } else {
1688 if (y < -ch) {
1689 short ycntl = (-ch - y) * CONTROL_MAX_VAL / (cy - ch - reg->abs_y);
1690 if (move) {
1691 int f = PLAYER_FATIGUE;
1692 if (ycntl + f > CONTROL_MAX_VAL) { // compute new mouse cursor position
1693 int newy;
1694 f = lg_max(CONTROL_MAX_VAL - f, SPRINT_CONTROL_THRESHOLD);
1695 newy = f * (ch + reg->abs_y - cy) / CONTROL_MAX_VAL - ch + cy;
1696 ycntl = (ycntl + f) / 2;
1697 // put the cursor between here and there
1698 if (newy > pos.y)
1699 mouse_put_xy(pos.x, newy);
1700 }
1701 yvel = ycntl;
1702 }
1703
1704 if (ycntl > SPRINT_CONTROL_THRESHOLD)
1705 cnum |= VIEW_WAYTOP;
1706 else
1707 cnum |= VIEW_TOP;
1708
1709 } else if (y > ch) {
1710 cnum |= VIEW_BOTTOM;
1711 if (move) {
1712 if (xyrot == 0)
1713 yvel = (ch - y) * CONTROL_MAX_VAL / (cy - ch - reg->abs_y);
1714 else {
1715 xvel = xyrot;
1716 xyrot = 0;
1717 }
1718 }
1719 } else
1720 cnum |= VIEW_VCENTER;
1721 }
1722
1723 // If mouse look is enabled, just use the centered cursor
1724 extern int mlook_enabled;
1725 if (mlook_enabled) {
1726 cnum = VIEW_HCENTER | VIEW_VCENTER;
1727
1728 if (cyber)
1729 cnum = VIEW_HCENTER + CYBER_VIEW_CENTER;
1730 }
1731
1732 if (*lastsect != cnum) {
1733 extern LGRegion *fullview_region;
1734 LGCursor *c = &motion_cursors[cnum];
1735 // Warning(("hey, cursor num = %d!\n",cnum));
1736
1737 // set the cursor to the motion cursor
1738 if (reg == fullview_region)
1739 uiSetGlobalDefaultCursor(c);
1740 else
1741 uiSetRegionDefaultCursor(reg, c);
1742
1743 *lastsect = cnum;
1744 }
1745
1746 if (!thrust)
1747 physics_set_player_controls(MOUSE_CONTROL_BANK, xvel, yvel, CONTROL_NO_CHANGE, xyrot, CONTROL_NO_CHANGE,
1748 CONTROL_NO_CHANGE);
1749
1750 if (dougs_goofy_hack)
1751 return xvel | yvel | xyrot;
1752 return 0;
1753 }
1754
1755 // Not a directly-installed mouse handler, called from view3d_mouse_handler
view3d_rightbutton_handler(uiEvent * ev,LGRegion * r,view3d_data * data)1756 void view3d_rightbutton_handler(uiEvent *ev, LGRegion *r, view3d_data *data) {
1757 extern LGCursor fire_cursor;
1758 extern uchar hack_takeover;
1759 LGPoint aimpos = ev->pos;
1760
1761 if (DoubleSize) // If double sizing, convert the y to 640x480, then
1762 aimpos.y = SCONV_Y(aimpos.y) >> 1; // half it. The x stays as is.
1763 else
1764 ss_point_convert(&(aimpos.x), &(aimpos.y), FALSE);
1765
1766 // Don't do nuthin if we're in a hack camera
1767 if (hack_takeover)
1768 return;
1769
1770 if (ev->mouse_data.action & MOUSE_RUP) {
1771 if (!data->rdown)
1772 data->lastright = aimpos;
1773 else
1774 data->rdown = FALSE;
1775 left_down_jump = FALSE;
1776 weapon_button_up = TRUE;
1777 if (fire_slam) {
1778 if (full_game_3d)
1779 uiPopSlabCursor(&fullscreen_slab);
1780 else
1781 uiPopSlabCursor(&main_slab);
1782 fire_slam = FALSE;
1783 }
1784 }
1785
1786 if (ev->mouse_data.action & MOUSE_RDOWN) {
1787 data->rdown = TRUE;
1788 data->lastright = aimpos;
1789 left_down_jump = data->ldown && !global_fullmap->cyber;
1790 // view3d_constrain_mouse(r,RBUTTON_CONSTRAIN_BIT);
1791 }
1792
1793 /*
1794 if (mouse_jump_ui && data->ldown && !global_fullmap->cyber)
1795 {
1796 if (ev->action & MOUSE_RDOWN)
1797 {
1798 physics_set_one_control(MOUSE_CONTROL_BANK,CONTROL_ZVEL, MAX_JUMP_CONTROL);
1799 return;
1800 }
1801 }
1802 */
1803
1804 switch (input_cursor_mode) {
1805 case INPUT_NORMAL_CURSOR:
1806 if (!global_fullmap->cyber && (player_struct.fire_rate == 0) &&
1807 !(ev->mouse_data.action & MOUSE_RDOWN))
1808 break;
1809 if (left_down_jump)
1810 break;
1811 if (data->rdown) {
1812 // printf("FIRE WEAPON!\n");
1813 if (fire_player_weapon(&aimpos, r, weapon_button_up) && (ev->mouse_data.action & MOUSE_RDOWN) && !fire_slam) {
1814 if (full_game_3d)
1815 uiPushSlabCursor(&fullscreen_slab, &fire_cursor);
1816 else
1817 uiPushSlabCursor(&main_slab, &fire_cursor);
1818 fire_slam = TRUE;
1819 }
1820 weapon_button_up = FALSE;
1821 }
1822 break;
1823 case INPUT_OBJECT_CURSOR:
1824 if (ev->mouse_data.action & MOUSE_RUP) {
1825 fix vel = throw_oomph * FIX_UNIT;
1826 short dropy = DROP_REGION_Y(r);
1827 short y = aimpos.y;
1828 // if (convert_use_mode != 0)
1829 if (DoubleSize) // If double sizing, convert the y to 640x480, then
1830 dropy = SCONV_Y(dropy) >> 1; // half it. The x stays as is.
1831 else
1832 dropy = SCONV_Y(dropy);
1833 if (y >= dropy && data->lastright.y >= dropy) {
1834 vel = 0;
1835 }
1836 if (player_throw_object(object_on_cursor, aimpos.x, y, data->lastright.x, data->lastright.y, vel)) {
1837 pop_cursor_object();
1838 uiShowMouse(NULL); // KLC - added to make sure new cursor shows.
1839 }
1840 data->rdown = FALSE;
1841 }
1842 break;
1843 }
1844 }
1845
1846 // ----------------------------------------------------------------
1847 // use_object_in_3d deals with double-clicking on an object in the 3d
1848
check_object_dist(ObjID obj1,ObjID obj2,fix crit)1849 uchar check_object_dist(ObjID obj1, ObjID obj2, fix crit) {
1850 uchar retval = FALSE;
1851 extern fix ID2radius(ObjID);
1852 fix critrad = ID2radius(obj2);
1853 fix dx = fix_from_obj_coord(objs[obj1].loc.x) - fix_from_obj_coord(objs[obj2].loc.x);
1854 fix dy = fix_from_obj_coord(objs[obj1].loc.y) - fix_from_obj_coord(objs[obj2].loc.y);
1855 fix dz = fix_from_obj_height(obj1) - fix_from_obj_height(obj2);
1856 if (-dz > critrad / 2 && -dz < critrad + FIX_UNIT / 4) {
1857 crit *= 2;
1858 }
1859 retval = fix_fast_pyth_dist(dx, dy) < crit;
1860 if (retval) {
1861 retval = -(critrad * 2 + crit / 2) < dz && dz < crit / 2 + critrad * 2;
1862 }
1863 return retval;
1864 }
1865
1866 #define TELE_ROD_DIST 16 // 16 feet
1867
use_object_in_3d(ObjID obj,bool shifted)1868 void use_object_in_3d(ObjID obj, bool shifted) {
1869 uchar success = FALSE;
1870 ObjID telerod = OBJ_NULL;
1871 uchar showname = FALSE;
1872 extern uchar object_use(ObjID id, uchar in_inv, ObjID cursor_obj);
1873 extern ObjID physics_handle_id[MAX_OBJ];
1874 int mode = USE_MODE(obj);
1875 char buf[80];
1876 Ref usemode = ID_NULL;
1877 extern short loved_textures[];
1878 extern char *get_texture_name(int, char *, int);
1879 extern char *get_texture_use_string(int, char *, int);
1880
1881 if (global_fullmap->cyber) {
1882 if (ID2TRIP(obj) != INFONODE_TRIPLE) {
1883 switch (USE_MODE(obj)) {
1884 case USE_USE_MODE:
1885 usemode = REF_STR_PhraseUse;
1886 break;
1887 case PICKUP_USE_MODE:
1888 usemode = REF_STR_PhrasePickUp;
1889 break;
1890 }
1891 // exceptions
1892 switch (objs[obj].obclass) {
1893 case CLASS_BIGSTUFF:
1894 usemode = REF_STR_PhrasePickUp;
1895 break;
1896 case CLASS_CRITTER:
1897 usemode = ID_NULL;
1898 break;
1899 }
1900 if (usemode != ID_NULL) {
1901 sprintf(buf, get_temp_string(REF_STR_CyberspaceUse), get_temp_string(usemode));
1902 message_info(buf);
1903 }
1904 return;
1905 }
1906 }
1907
1908 if (input_cursor_mode == INPUT_OBJECT_CURSOR) {
1909 mode = USE_USE_MODE;
1910 if (ID2TRIP(object_on_cursor) == ROD_TRIPLE) {
1911 telerod = object_on_cursor;
1912 object_on_cursor = OBJ_NULL;
1913 use_distance_mod += TELE_ROD_DIST;
1914 }
1915 }
1916
1917 switch (ID2TRIP(obj)) {
1918
1919 case TMAP_TRIPLE:
1920 get_texture_use_string(loved_textures[objBigstuffs[objs[obj].specID].data2], buf, 80);
1921 message_info(buf);
1922 return;
1923 case BRIDGE_TRIPLE: {
1924 int dat = ((objBigstuffs[objs[obj].specID].data1) >> 16) & 0xFF;
1925 if (dat & 0x80) {
1926 get_texture_name(loved_textures[dat & (~0x80)], buf, 80);
1927 message_info(buf);
1928 return;
1929 }
1930 break;
1931 }
1932 }
1933
1934 switch (mode) {
1935 case PICKUP_USE_MODE: {
1936 ObjLocState del_loc_state;
1937 void grenade_contact(ObjID id, int severity);
1938
1939 if (!check_object_dist(obj, PLAYER_OBJ, MAX_PICKUP_DIST)) {
1940 string_message_info(REF_STR_PickupTooFar);
1941 showname = FALSE;
1942 break;
1943 }
1944 // yank the object out of the map.
1945 del_loc_state.obj = obj;
1946 del_loc_state.loc = objs[obj].loc;
1947 del_loc_state.loc.x = -1;
1948 ObjRefStateBinSetNull(del_loc_state.refs[0].bin);
1949 ObjUpdateLocs(&del_loc_state);
1950 if (objs[obj].info.ph != -1) {
1951 EDMS_kill_object(objs[obj].info.ph);
1952 physics_handle_id[objs[obj].info.ph] = OBJ_NULL;
1953 objs[obj].info.ph = -1;
1954 }
1955 // Put it on the cursor
1956 // showname = TRUE;
1957 push_cursor_object(obj);
1958
1959 if (objs[obj].obclass == CLASS_GRENADE)
1960 grenade_contact(obj, INT_MAX);
1961
1962 if (shifted)
1963 {
1964 extern void absorb_object_on_cursor(ushort keycode, uint32_t context, intptr_t data); //see invent.c
1965 absorb_object_on_cursor(0, 0, 0); //parameters unused
1966 }
1967 else
1968 mouse_look_off();
1969
1970 success = TRUE;
1971 } break;
1972 case USE_USE_MODE:
1973 showname = FALSE;
1974 if (objs[obj].obclass != CLASS_CRITTER && ID2TRIP(obj) != MAPNOTE_TRIPLE &&
1975 !check_object_dist(obj, PLAYER_OBJ, MAX_USE_DIST)) {
1976 string_message_info(REF_STR_UseTooFar);
1977 break;
1978 }
1979
1980 extern bool ObjectUseShifted; //see objuse.c
1981 ObjectUseShifted = shifted;
1982 if (!object_use(obj, FALSE, object_on_cursor)) {
1983 if (objs[obj].obclass != CLASS_DOOR)
1984 goto cantuse;
1985 else
1986 showname = TRUE;
1987 }
1988 if (telerod != OBJ_NULL) {
1989 object_on_cursor = telerod;
1990 use_distance_mod -= TELE_ROD_DIST;
1991 }
1992 success = TRUE;
1993
1994 break;
1995 cantuse:
1996 default: {
1997 char use_str[80], buf2[50];
1998 sprintf(use_str, get_temp_string(REF_STR_CantUse), get_object_lookname(obj, buf2, 50));
1999 message_info(use_str);
2000 } break;
2001 }
2002 if (success && !global_fullmap->cyber) {
2003 objs[obj].info.inst_flags |= OLH_INST_FLAG;
2004 }
2005 if (showname)
2006 look_at_object(obj);
2007 }
2008
2009 //-------------------------------------------------------------------------
2010 // look_at_object prints a descriptive string of the object in the message line
2011
2012 // these are just cribbed here from email.c...
2013 #define EMAIL_BASE_ID RES_email0
2014 #define TITLE_IDX 1
2015 #define SENDER_IDX 2
2016
get_object_lookname(ObjID id,char use_string[],int sz)2017 char *get_object_lookname(ObjID id, char use_string[], int sz) {
2018 int ref = -1;
2019 int l;
2020 int usetrip = ID2TRIP(id);
2021 extern short loved_textures[];
2022 extern char *get_texture_name(int, char *, int);
2023
2024 strcpy(use_string, "");
2025
2026 switch (objs[id].obclass) {
2027 case CLASS_FIXTURE:
2028 case CLASS_DOOR:
2029 if (objs[id].info.make_info != 0)
2030 ref = REF_STR_Name0 + objs[id].info.make_info;
2031 break;
2032 case CLASS_GRENADE:
2033 if (objGrenades[objs[id].specID].flags & GREN_ACTIVE_FLAG) {
2034 get_string(REF_STR_WordLiveGrenade, use_string, sz);
2035 l = strlen(use_string);
2036 if (l + 1 < sz)
2037 use_string[l] = ' ';
2038 }
2039 break;
2040 case CLASS_SOFTWARE:
2041 if (objs[id].subclass == SOFTWARE_SUBCLASS_DATA) {
2042 short cont = objSoftwares[objs[id].specID].data_munge;
2043 short num = cont & 0xFF;
2044 if (global_fullmap->cyber) {
2045 ref = REF_STR_DataObj;
2046 break;
2047 }
2048 switch (cont >> 8) {
2049 case LOG_VER:
2050 num += NUM_EMAIL_PROPER;
2051 break;
2052 case DATA_VER:
2053 num += (NUM_EMAIL - NUM_DATA);
2054 break;
2055 }
2056 ref = MKREF(EMAIL_BASE_ID + num, TITLE_IDX);
2057 }
2058 break;
2059 case CLASS_BIGSTUFF:
2060 if (global_fullmap->cyber) {
2061 usetrip =
2062 MAKETRIP(CLASS_SOFTWARE, objBigstuffs[objs[id].specID].data1, objBigstuffs[objs[id].specID].data2);
2063 } else {
2064 switch (ID2TRIP(id)) {
2065 case ICON_TRIPLE:
2066 ref = REF_STR_IconName0 + objs[id].info.current_frame;
2067 break;
2068 case TMAP_TRIPLE:
2069 get_texture_name(loved_textures[objBigstuffs[objs[id].specID].data2], use_string, sz);
2070 return (use_string);
2071 case BRIDGE_TRIPLE: {
2072 int dat = ((objBigstuffs[objs[id].specID].data1) >> 16) & 0xFF;
2073 if (dat & 0x80) {
2074 get_texture_name(loved_textures[dat & (~0x80)], use_string, sz);
2075 return (use_string);
2076 }
2077 break;
2078 }
2079 }
2080 if (ref < 0) {
2081 if (objs[id].info.make_info != 0)
2082 ref = REF_STR_Name0 + objs[id].info.make_info;
2083 }
2084 }
2085 break;
2086 case CLASS_SMALLSTUFF: {
2087 switch (ID2TRIP(id)) {
2088 case PERSCARD_TRIPLE: {
2089 char buf[50];
2090 int acc, len;
2091 acc = objSmallstuffs[objs[id].specID].data1;
2092 #define PERSONAL_BITS_SHIFT 24
2093 // get rid of all but personal access bits
2094 get_object_long_name(ID2TRIP(id), use_string, sz);
2095 acc = acc >> PERSONAL_BITS_SHIFT;
2096 ref = PERSONAL_BITS_SHIFT;
2097 if (acc == 0)
2098 return (use_string);
2099 for (; (acc & 1) == 0; acc = acc >> 1)
2100 ref++;
2101 ref = MKREF(RES_accessCards, (ref << 1) + 1);
2102 get_string(ref, buf, sizeof(buf));
2103 len = strlen(buf);
2104 while (!isspace(buf[len]) && len > 0)
2105 len--;
2106 if (isspace(buf[len])) {
2107 strcat(use_string, "-");
2108 strcat(use_string, buf + len + 1);
2109 }
2110 return (use_string);
2111 }
2112 case HEAD_TRIPLE:
2113 case HEAD2_TRIPLE:
2114 if (objs[id].info.make_info != 0)
2115 ref = REF_STR_Name0 + objs[id].info.make_info;
2116 break;
2117 }
2118 } break;
2119 case CLASS_HARDWARE: {
2120 sprintf(use_string, "%s v%d", get_object_long_name(ID2TRIP(id), NULL, sz), objHardwares[objs[id].specID].version);
2121 return (use_string);
2122 }
2123 case CLASS_CRITTER: {
2124 char temp[128];
2125 Ref mod_refid = -1;
2126 if (objCritters[objs[id].specID].orders == AI_ORDERS_SLEEP)
2127 mod_refid = REF_STR_Sleeping;
2128 else if (objCritters[objs[id].specID].flags & AI_FLAG_TRANQ)
2129 mod_refid = REF_STR_Drugged;
2130 else if (objCritters[objs[id].specID].flags & AI_FLAG_CONFUSED)
2131 mod_refid = REF_STR_Stunned;
2132 if (mod_refid != -1) {
2133 get_string(mod_refid, temp, 128);
2134 sprintf(use_string, temp, get_object_long_name(usetrip, NULL, 0));
2135 return (use_string);
2136 }
2137 } break;
2138 }
2139 // If we haven't set ref or ref is garbage, use the long name.
2140 char *temp = (ref == -1) ? NULL : RefGet(ref);
2141 if (temp == NULL) {
2142 strcat(use_string, get_object_long_name(usetrip, NULL, 0));
2143 } else {
2144 strncpy(use_string, temp, sz);
2145 use_string[sz-1] = '\0';
2146 }
2147 return (use_string);
2148 }
2149
look_at_object(ObjID id)2150 void look_at_object(ObjID id) {
2151 char buf[50];
2152 get_object_lookname(id, buf, sizeof(buf));
2153 message_info(buf);
2154 }
2155
2156 // ------------------------------------------------------------------------
2157 // view3d_dclick dispatches double clicks based on cursor mode
2158
2159 // Not a directly-installed mouse handler, called from view3d_mouse_handler
view3d_dclick(LGPoint pos,frc * fr,bool shifted)2160 void view3d_dclick(LGPoint pos, frc *fr, bool shifted) {
2161 extern short loved_textures[];
2162 extern char *get_texture_use_string(int, char *, int);
2163 extern uchar hack_takeover;
2164 short obj_trans, obj;
2165 frc *use_frc;
2166
2167 extern int _fr_glob_flags;
2168
2169 if (hack_takeover)
2170 return;
2171 switch (input_cursor_mode) {
2172 case INPUT_NORMAL_CURSOR:
2173 case INPUT_OBJECT_CURSOR:
2174 use_frc = svga_render_context;
2175 obj = fr_get_at_raw(use_frc, pos.x, pos.y, FALSE, FALSE);
2176 if ((obj > 0) && (objs[obj].obclass == CLASS_DOOR)) {
2177 obj_trans = fr_get_at_raw(use_frc, pos.x, pos.y, FALSE, TRUE);
2178 if (obj != obj_trans) {
2179 if (DOOR_REALLY_CLOSED(obj)) {
2180 string_message_info(REF_STR_PickupTooFar);
2181 return;
2182 } else
2183 obj = obj_trans;
2184 }
2185 } else if (obj > 0) {
2186 obj = fr_get_at_raw(use_frc, pos.x, pos.y, FALSE, TRUE);
2187 }
2188 if ((short)obj < 0) {
2189 // Don't display texture look strings in cspace....eventually we should do some cool hack
2190 // for looking through walls, some sort of cspace fr_get_at or something
2191 if (global_fullmap->cyber)
2192 string_message_info(REF_STR_CybWallUse);
2193 else
2194 message_info(get_texture_use_string(loved_textures[~obj], NULL, 0));
2195 } else if ((short)obj > 0) {
2196 use_cursor_pos = pos;
2197 use_object_in_3d(obj, shifted);
2198 } else {
2199 if (!global_fullmap->cyber) {
2200 if (!(_fr_glob_flags & FR_SOLIDFR_STATIC))
2201 string_message_info(REF_STR_InkyUse);
2202 }
2203 }
2204 }
2205 }
2206
2207 // -------------------------------------------------------------------------------
2208 // view3d_mouse_handler is the actual installed mouse handler, dispatching to the above functions
view3d_mouse_handler(uiEvent * ev,LGRegion * r,intptr_t v)2209 uchar view3d_mouse_handler(uiEvent *ev, LGRegion *r, intptr_t v) {
2210 static uchar got_focus = FALSE;
2211 uiMouseData *md = &ev->mouse_data;
2212 view3d_data *data = (view3d_data*)v;
2213 uchar retval = TRUE;
2214 LGPoint pt;
2215 LGPoint evp = ev->pos;
2216 extern int _fr_glob_flags;
2217
2218 pt = evp;
2219
2220 #ifdef STEREO_SUPPORT
2221 if (convert_use_mode == 5) {
2222 extern uchar inventory_mouse_handler(uiEvent * ev, LGRegion * r, intptr_t data);
2223 extern uchar mfd_view_callback(uiEvent * e, LGRegion * r, intptr_t udata);
2224 switch (i6d_device) {
2225 case I6D_CTM:
2226 if (full_visible & FULL_INVENT_MASK)
2227 return (inventory_mouse_handler(ev, r, v));
2228 if ((full_visible & FULL_L_MFD_MASK) && (evp.x < ((MFD_VIEW_LFTX + MFD_VIEW_WID) << 1)))
2229 return (mfd_view_callback(ev, r, 0));
2230 if ((full_visible & FULL_R_MFD_MASK) && (evp.x > ((MFD_VIEW_RGTX + MFD_VIEW_WID) >> 1)))
2231 return (mfd_view_callback(ev, r, 1));
2232 break;
2233 case I6D_VFX1:
2234 if (full_visible & FULL_INVENT_MASK)
2235 return (inventory_mouse_handler(ev, r, v));
2236 if ((full_visible & FULL_L_MFD_MASK) && (evp.x < ((MFD_VIEW_LFTX + MFD_VIEW_WID) << 1)))
2237 return (mfd_view_callback(ev, r, 0));
2238 if ((full_visible & FULL_R_MFD_MASK) && (evp.x > ((MFD_VIEW_RGTX + MFD_VIEW_WID) >> 1)))
2239 return (mfd_view_callback(ev, r, 1));
2240 break;
2241 }
2242 }
2243 #endif
2244
2245 #ifdef STEREO_SUPPORT
2246 if (convert_use_mode != 5)
2247 #endif
2248 if (DoubleSize) // If double sizing, convert the y to 640x480, then
2249 evp.y = SCONV_Y(evp.y) >> 1; // half it. The x stays as is.
2250 else
2251 ss_point_convert(&(evp.x), &(evp.y), FALSE);
2252
2253 view3d_got_event = TRUE;
2254 pt.x += r->r->ul.x - r->abs_x;
2255 pt.y += r->r->ul.y - r->abs_y;
2256
2257 if (!RECT_TEST_PT(r->r, pt)) {
2258 data->ldown = FALSE;
2259 physics_set_player_controls(MOUSE_CONTROL_BANK, 0, 0, CONTROL_NO_CHANGE, 0, CONTROL_NO_CHANGE,
2260 CONTROL_NO_CHANGE);
2261 return (FALSE);
2262 }
2263 if (md->action & MOUSE_LDOWN) {
2264 data->ldown = TRUE;
2265 data->lastleft = evp;
2266 if (full_game_3d && !got_focus) {
2267 if (uiGrabFocus(r, UI_EVENT_MOUSE | UI_EVENT_MOUSE_MOVE) == OK)
2268 got_focus = TRUE;
2269 }
2270 chg_set_flg(_current_3d_flag);
2271 // view3d_constrain_mouse(r,LBUTTON_CONSTRAIN_BIT);
2272 }
2273 if (md->action & MOUSE_LUP || !(md->buttons & (1 << MOUSE_LBUTTON))) {
2274 data->ldown = FALSE;
2275 if (full_game_3d && got_focus) {
2276 if (uiReleaseFocus(r, UI_EVENT_MOUSE | UI_EVENT_MOUSE_MOVE) == OK)
2277 got_focus = FALSE;
2278 }
2279 // view3d_unconstrain_mouse(LBUTTON_CONSTRAIN_BIT);
2280 }
2281 if (md->action & MOUSE_LUP && abs(evp.y - data->lastleft.y) < uiDoubleClickTolerance &&
2282 abs(evp.x - data->lastleft.x) < uiDoubleClickTolerance) {
2283 //make shift+leftclick act as double-leftclick with alternate effects
2284 if (md->modifiers & 1) { //shifted click; see sdl_events.c
2285 view3d_dclick(evp, data->fr, TRUE); //TRUE indicates shifted
2286 data->lastleft = MakePoint(-100, -100);
2287 }
2288 else {
2289 ObjID id;
2290 frc *use_frc;
2291 short rabsx, rabsy;
2292
2293 use_frc = svga_render_context;
2294 rabsx = r->abs_x;
2295 rabsy = r->abs_y;
2296 if (!DoubleSize)
2297 ss_point_convert(&rabsx, &rabsy, FALSE);
2298
2299 id = fr_get_at(use_frc, evp.x - rabsx, evp.y - rabsy, TRUE);
2300 if ((short)id > 0) {
2301 look_at_object(id);
2302 } else if ((short)id < 0) {
2303 extern short loved_textures[];
2304 extern char *get_texture_name(int, char *, int);
2305 int tnum = loved_textures[~id];
2306 if (global_fullmap->cyber)
2307 string_message_info(REF_STR_CybWall);
2308 else
2309 message_info(get_texture_name(tnum, NULL, 0));
2310 } else {
2311 if (!global_fullmap->cyber) {
2312 if (!(_fr_glob_flags & FR_SOLIDFR_STATIC))
2313 string_message_info(REF_STR_InkyBlack);
2314 }
2315 }
2316 data->lastleft.x = -255;
2317 }
2318 }
2319 if ((md->action & (MOUSE_RDOWN | MOUSE_RUP)) || (md->buttons & (1 << MOUSE_RBUTTON)))
2320 view3d_rightbutton_handler(ev, r, data);
2321
2322 /* KLC - done in another place now.
2323 else
2324 {
2325 view3d_unconstrain_mouse(RBUTTON_CONSTRAIN_BIT);
2326 if (fire_slam)
2327 {
2328 if (full_game_3d)
2329 uiPopSlabCursor(&fullscreen_slab);
2330 else
2331 uiPopSlabCursor(&main_slab);
2332 fire_slam = FALSE;
2333 }
2334 }
2335
2336 */
2337 if ((md->buttons & (1 << MOUSE_RBUTTON)) == 0 ||
2338 ((md->buttons & (1 << MOUSE_RBUTTON)) == 0 && global_fullmap->cyber))
2339 physics_set_one_control(MOUSE_CONTROL_BANK, CONTROL_ZVEL, 0);
2340
2341 if (md->action & UI_MOUSE_LDOUBLE) {
2342 // Spew(DSRC_USER_I_Motion,("use this, bay-bee!\n"));
2343 view3d_dclick(evp, data->fr, FALSE);
2344 data->lastleft = MakePoint(-100, -100);
2345 }
2346
2347 if (md->action & (MOUSE_WHEELUP | MOUSE_WHEELDN)) {
2348 cycle_weapons_func(0, 0, md->action & MOUSE_WHEELUP ? -1 : 1);
2349 }
2350
2351 // data->ldown = TRUE;
2352
2353 // Do mouse motion.
2354 if (view3d_mouse_input(evp, r, data->ldown, &data->lastsect) != 0)
2355 data->lastleft = MakePoint(-1, -1); // if the player is moving, not a down
2356
2357 return (retval);
2358 }
2359
2360 typedef struct _view3d_kdata {
2361 int maxctrl; // max control as affected by fatigue
2362 } view3d_kdata;
2363
2364 extern int FireKeys[]; //see MacSrc/Prefs.c
2365
view3d_key_handler(uiEvent * ev,LGRegion * r,intptr_t data)2366 uchar view3d_key_handler(uiEvent *ev, LGRegion *r, intptr_t data)
2367 {
2368 uiCookedKeyData *kd = &ev->cooked_key_data;
2369 int i, detect = 0, fire_pressed = 0;
2370
2371 i = 0;
2372 while (FireKeys[i] != 0)
2373 {
2374 if (kd->code == FireKeys[i]) detect = 1;
2375 if (kd->code == (FireKeys[i] | KB_FLAG_DOWN)) {detect = 1; fire_pressed = 1; break;}
2376 i++;
2377 }
2378 if (!detect) return FALSE;
2379
2380 if (fire_pressed)
2381 {
2382 if (weapon_button_up) // if we haven't fired already
2383 {
2384 LGPoint evp = ev->pos;
2385 ss_point_convert(&(evp.x), &(evp.y), FALSE);
2386 fire_player_weapon(&evp, r, !fire_slam);
2387 fire_slam = TRUE;
2388 weapon_button_up = FALSE;
2389 }
2390 }
2391 else
2392 {
2393 weapon_button_up = TRUE;
2394 fire_slam = FALSE;
2395 }
2396
2397 return FALSE;
2398 }
2399
2400 #ifdef NOT_YET // KLC - for VR headsets
2401
2402 #define CORE6D_MAX_VAL (1 << 15)
2403 #define CORE6D_TRA_TOL (MAX_VAL >> 8)
2404 #define CORE6D_ROT_TOL (MAX_VAL >> 5)
2405 #define Tra_Scale(x) (((x)*CONTROL_MAX_VAL) / (MAX_VAL - TRA_TOL))
2406 #define Rot_Scale(x) (((x)*CONTROL_MAX_VAL) / (MAX_VAL - ROT_TOL))
2407
2408 // total hack lame inp6d function for now....
inp6d_chk(void)2409 void inp6d_chk(void) {
2410 // static inp6d_raw_event last_swift;
2411 i6s_event *inp6d_in;
2412 int xp, yp, zv, h, p, b;
2413
2414 // we'll want to put in code here to check for mouse_button_emulation
2415 // if (checking_mouse_button_emulation && <SOME CODE TO CHECK FOR BUTTON PRESS>)
2416 // mouse_button_emulated = TRUE;
2417
2418 if (game_paused)
2419 return;
2420 inp6d_in = i6_poll();
2421 if (inp6d_in == NULL)
2422 return;
2423 xp = inp6d_in->x;
2424 if (abs(xp) > TRA_TOL)
2425 if (xp > TRA_TOL)
2426 xp = Tra_Scale(xp - TRA_TOL);
2427 else
2428 xp = Tra_Scale(xp + TRA_TOL);
2429 else
2430 xp = 0;
2431 yp = -inp6d_in->z;
2432 if (abs(yp) > TRA_TOL)
2433 if (yp > TRA_TOL)
2434 yp = Tra_Scale(yp - TRA_TOL);
2435 else
2436 yp = Tra_Scale(yp + TRA_TOL);
2437 else
2438 yp = 0;
2439 zv = inp6d_in->y;
2440 if (abs(zv) > TRA_TOL)
2441 if (zv > TRA_TOL)
2442 zv = Tra_Scale(zv - TRA_TOL);
2443 else
2444 zv = Tra_Scale(zv + TRA_TOL);
2445 else
2446 zv = 0;
2447
2448 h = -inp6d_in->ry;
2449 if (h > ROT_TOL)
2450 h = Rot_Scale(h - ROT_TOL);
2451 else if (h < -ROT_TOL)
2452 h = Rot_Scale(h + ROT_TOL);
2453 else
2454 h = 0;
2455 p = inp6d_in->rx;
2456 if (p > ROT_TOL)
2457 p = Rot_Scale(p - ROT_TOL);
2458 else if (p < -ROT_TOL)
2459 p = Rot_Scale(p + ROT_TOL);
2460 else
2461 p = 0;
2462 b = -inp6d_in->rz;
2463 if (b > ROT_TOL)
2464 b = Rot_Scale(b - ROT_TOL);
2465 else if (b < -ROT_TOL)
2466 b = Rot_Scale(b + ROT_TOL);
2467 else
2468 b = 0;
2469
2470 #ifdef PLAYTEST
2471 if (inp6d_dbg)
2472 mprintf("Parsed %04x %04x %04x %04x %04x %04x to %d %d %d %d %d %d\n", inp6d_in->x, inp6d_in->y, inp6d_in->z,
2473 inp6d_in->rx, inp6d_in->ry, inp6d_in->rz, xp, yp, zv, h, p, b);
2474 #endif
2475
2476 #ifdef PLAYTEST
2477 if (!inp6d_player) {
2478 fr_camera_slewcam(NULL, EYE_X, xp / 5);
2479 fr_camera_slewcam(NULL, EYE_Y, yp / 5);
2480 fr_camera_slewcam(NULL, EYE_Z, zv / 5);
2481 fr_camera_slewcam(NULL, EYE_H, h / 3);
2482 fr_camera_slewcam(NULL, EYE_P, p / 3);
2483 fr_camera_slewcam(NULL, EYE_B, b / 3);
2484 } else
2485 #endif
2486 {
2487 physics_set_player_controls(INP6D_CONTROL_BANK, xp, yp, zv, h, p, b);
2488 fr_camera_slewcam(NULL, EYE_P, p / 3); // hack horribly for now... yea!
2489 fr_camera_slewcam(NULL, EYE_B, b / 3);
2490 }
2491 }
2492
2493 #define ANG_P 0
2494 #define ANG_B 1
2495 #define ANG_H 2
2496 #if defined(VFX1_SUPPORT) || defined(CTM_SUPPORT)
2497 short l_angs[3];
2498
set_abs_head(i6s_event * e)2499 short *set_abs_head(i6s_event *e) {
2500 if (!inp6d_doom) {
2501 l_angs[ANG_B] = (e->ry) - tracker_initial_pos[0];
2502 l_angs[ANG_P] = (e->rx) - tracker_initial_pos[1];
2503 } else
2504 l_angs[ANG_B] = l_angs[ANG_P] = 0;
2505 l_angs[ANG_H] = (-e->rz) - tracker_initial_pos[2];
2506 if (inp6d_hdouble)
2507 l_angs[ANG_H] += l_angs[ANG_H];
2508 if (inp6d_pdouble)
2509 l_angs[ANG_P] += l_angs[ANG_P];
2510 if (inp6d_bdouble)
2511 l_angs[ANG_B] += l_angs[ANG_B];
2512 return l_angs;
2513 }
2514
2515 #define BREAK_REGION (CONTROL_MAX_VAL / 4)
2516 #define XTRA_REGION (CONTROL_MAX_VAL - BREAK_REGION)
2517
2518 // add a double LGRegion fix...
deparse_angle_region(short angle,short min,short mid,short max)2519 short deparse_angle_region(short angle, short min, short mid, short max) {
2520 int sgn;
2521 if (abs(angle) < min)
2522 return 0;
2523 sgn = angle > 0 ? 1 : -1;
2524 angle = abs(angle);
2525 if (angle < mid)
2526 return sgn * ((angle - min) * BREAK_REGION / (mid - min));
2527 if (angle < max)
2528 return sgn * (BREAK_REGION + (angle - mid) * XTRA_REGION / (max - mid));
2529 return sgn * CONTROL_MAX_VAL;
2530 }
2531
slam_head(short * angs)2532 void slam_head(short *angs) {
2533 #ifdef PLAYTEST
2534 static int last_head_h;
2535 #endif
2536 // if (global_fullmap->cyber)
2537 // { // secret head joystick dented with the promise of power
2538 // short h,p,b;
2539 // h=deparse_angle_region(angs[ANG_H],0x0400,0x1400,0x2000);
2540 // p=deparse_angle_region(angs[ANG_P],0x0400,0x1400,0x2000);
2541 // b=deparse_angle_region(angs[ANG_B],0x0300,0x0B00,0x1400);
2542 // physics_set_player_controls(INP6D_CONTROL_BANK, b, -p, 0, h, 0, 0);
2543 // }
2544 // else
2545 {
2546 fr_camera_setone(NULL, EYE_P, angs[ANG_P]);
2547 fr_camera_setone(NULL, EYE_B, angs[ANG_B]);
2548 #ifdef PLAYTEST
2549 if (!inp6d_link)
2550 #endif
2551 fr_camera_setone(NULL, EYE_HEADH, angs[ANG_H]);
2552 #ifdef PLAYTEST
2553 else {
2554 int h_diff = (angs[ANG_H] - last_head_h) / cam_slew_scale[EYE_H]; // HAQ
2555 fr_camera_slewone(NULL, EYE_H, h_diff);
2556 last_head_h = angs[ANG_H];
2557 }
2558 #endif
2559 }
2560 }
2561 #endif
2562
2563 #define USE_UPPER_BOUND (CIT_CYCLE / 4)
2564 #define RELOAD_TIME (CIT_CYCLE * 2)
2565
2566 uchar reload_current_weapon(void);
2567 uchar inp_reloaded = FALSE;
2568 uchar inp_sidestep = FALSE;
2569 int use_but_time = 0;
2570 int weap_time = 0;
inp_weapon_button(uchar pull)2571 void inp_weapon_button(uchar pull) {
2572 int w = player_struct.actives[ACTIVE_WEAPON]; // check if we need to reload
2573 uchar reloaded = FALSE;
2574
2575 if (object_on_cursor) {
2576 LGPoint pos = MakePoint(_current_view->abs_x + RectWidth(_current_view->r) / 2,
2577 _current_view->abs_y + RectHeight(_current_view->r) / 2);
2578
2579 ui_mouse_put_xy(pos.x, pos.y);
2580 #ifdef SVGA_SUPPORT
2581 ss_point_convert(&(pos.x), &(pos.y), FALSE);
2582 #endif
2583 if (player_throw_object(object_on_cursor, pos.x, pos.y, pos.x, pos.y, throw_oomph * FIX_UNIT))
2584 pop_cursor_object();
2585 return;
2586 }
2587
2588 // reload if conditions are right
2589 if ((player_struct.weapons[w].type != GUN_SUBCLASS_BEAM) &&
2590 (player_struct.weapons[w].type != GUN_SUBCLASS_HANDTOHAND) &&
2591 (player_struct.weapons[w].type != GUN_SUBCLASS_BEAMPROJ) && (player_struct.weapons[w].ammo == 0)) { // reload
2592
2593 if (weap_time == 0) {
2594 weap_time = *tmd_ticks;
2595 reloaded = FALSE;
2596 } else if (!reloaded)
2597 if (*tmd_ticks > weap_time + RELOAD_TIME) {
2598 reload_current_weapon();
2599 reloaded = TRUE;
2600 }
2601 } else if (weap_time == 0) {
2602 LGPoint pos =
2603 MakePoint(_current_view->abs_x + RectWidth(_current_view->r) / 2,
2604 _current_view->abs_y + RectHeight(_current_view->r) / 2 + (RectHeight(_current_view->r) >> 4));
2605
2606 ui_mouse_put_xy(pos.x, pos.y);
2607 #ifdef SVGA_SUPPORT
2608 ss_point_convert(&(pos.x), &(pos.y), FALSE);
2609 #endif
2610 fire_player_weapon(&pos, _current_view, pull);
2611 }
2612 }
2613
2614 #define inp_weapon_junk() weap_time = 0
2615
inp_use_sidestep_button()2616 void inp_use_sidestep_button() {
2617 if (use_but_time) { // if long enough, go to sidestep....
2618 if (*tmd_ticks > use_but_time + USE_UPPER_BOUND) {
2619 inp_sidestep = TRUE;
2620 use_but_time = 0;
2621 }
2622 } else if (!inp_sidestep)
2623 use_but_time = *tmd_ticks;
2624 }
2625
2626 // teach this that if you have obj on cursor it knows whether to throw or
2627 // put in your inventory. do this by storing when you pick up w/joystick
2628 // and if mouse moves cancelling but otherwise when joyclicking again with
2629 // an obj already on cursor the put it in inventory
2630
inp_use_sidestep_junk()2631 void inp_use_sidestep_junk() {
2632 if (use_but_time) {
2633 LGPoint pos;
2634
2635 if (input_cursor_mode == INPUT_OBJECT_CURSOR) {
2636 extern void absorb_object_on_cursor(ushort keycode, uint32_t context, intptr_t data);
2637 absorb_object_on_cursor(0, 0, 0);
2638 } else {
2639 pos = MakePoint(_current_view->abs_x + RectWidth(_current_view->r) / 2,
2640 _current_view->abs_y + RectHeight(_current_view->r) / 2);
2641 #ifdef SVGA_SUPPORT
2642 ss_point_convert(&pos.x, &pos.y, FALSE);
2643 #endif
2644 mouse_put_xy(pos.x, pos.y);
2645 view3d_dclick(pos, NULL, FALSE);
2646 }
2647 use_but_time = 0;
2648 } else
2649 inp_sidestep = FALSE;
2650 }
2651
2652 #ifdef VFX1_SUPPORT
2653
2654 #define VFX1_MAX_VAL (1 << 15)
2655 #define VFX1_TRA_TOL (MAX_VAL >> 5)
2656 #define VFX1_Tra_Scale(x) (((x)*CONTROL_MAX_VAL) / (VFX1_MAX_VAL - VFX1_TRA_TOL))
2657
2658 // total hack lame guess at a vfx1 function...
vfx1_chk(void)2659 void vfx1_chk(void) {
2660 static uchar last_but;
2661 // static LGPoint targ_loc={160,100};
2662 i6s_event *inp6d_in;
2663 int xp, yp, xp1, xp2, zv;
2664 short *angs;
2665
2666 if (game_paused)
2667 return;
2668 inp6d_in = i6_poll();
2669 if (inp6d_in == NULL)
2670 return;
2671
2672 xp = inp6d_in->x;
2673
2674 xp += (xp >> 1); // add fifty percent
2675 if (abs(xp) > VFX1_TRA_TOL)
2676 if (xp > VFX1_TRA_TOL)
2677 xp = VFX1_Tra_Scale(xp - VFX1_TRA_TOL);
2678 else
2679 xp = VFX1_Tra_Scale(xp + VFX1_TRA_TOL);
2680 else
2681 xp = 0;
2682
2683 yp = -inp6d_in->y; // flip it so + is forward motion
2684 yp *= 2; // since the bat, forward 90 degrees is full speed
2685 if (abs(yp) > VFX1_TRA_TOL)
2686 if (yp > VFX1_TRA_TOL)
2687 yp = CONTROL_MAX_VAL / 4 + VFX1_Tra_Scale(yp - VFX1_TRA_TOL);
2688 else
2689 yp = VFX1_Tra_Scale(yp + VFX1_TRA_TOL);
2690 else
2691 yp = 0;
2692 xp1 = xp;
2693 xp2 = 0;
2694 zv = 0;
2695
2696 angs = set_abs_head(inp6d_in);
2697
2698 if (inp6d_in->but) {
2699 if (joystick_mouse_emul) {
2700 extern void joystick_emulate_mouse(int x, int y, uchar bstate, uchar last_bstate);
2701 joystick_emulate_mouse(xp, -yp, inp6d_in->but >> 1, last_but >> 1);
2702 xp2 = xp1 = yp = zv = 0;
2703 } else {
2704 if (inp6d_in->but & 1)
2705 inp_weapon_button((last_but & 1) != (inp6d_in->but & 1));
2706 if (inp6d_in->but & 2)
2707 zv = 100; // jump jump jump
2708 if (inp6d_in->but & 4)
2709 inp_use_sidestep_button();
2710 }
2711 }
2712
2713 if (inp_sidestep) {
2714 xp2 = xp1 * 2;
2715 xp1 = 0;
2716 } // switch bat X from heading to sidestep
2717
2718 if (!joystick_mouse_emul) {
2719 if ((inp6d_in->but & 4) == 0)
2720 inp_use_sidestep_junk();
2721
2722 if ((inp6d_in->but & 1) == 0 && (last_but & 1) == 1) {
2723 inp_weapon_junk();
2724 }
2725 }
2726
2727 #ifdef PLAYTEST
2728 if (inp6d_dbg)
2729 mprintf("Parsed %04x %04x %04x %04x %04x %04x to %d %d %d %d %d %d\n", inp6d_in->x, inp6d_in->y, inp6d_in->z,
2730 inp6d_in->rx, inp6d_in->ry, inp6d_in->rz, xp, yp, zv, angs[ANG_P], angs[ANG_B], angs[ANG_H]);
2731 #endif
2732
2733 #ifdef PLAYTEST
2734 if (!inp6d_player) {
2735 fr_camera_slewcam(NULL, EYE_X, xp / 5);
2736 fr_camera_slewcam(NULL, EYE_Y, yp / 5);
2737 // fr_camera_slewcam(NULL,EYE_Z,zv/5);
2738 // fr_camera_setone(NULL,EYE_HEADH,h);
2739 fr_camera_setone(NULL, EYE_H, angs[ANG_H]);
2740 fr_camera_setone(NULL, EYE_P, angs[ANG_P]);
2741 fr_camera_setone(NULL, EYE_B, angs[ANG_B]);
2742 } else
2743 #endif // PLAYTEST
2744 {
2745 // combine the two when in cyberspace
2746 if (global_fullmap->cyber) {
2747 xp1 += deparse_angle_region(angs[ANG_H], 0x0400, 0x1400, 0x2000);
2748 yp -= deparse_angle_region(angs[ANG_P], 0x0400, 0x1400, 0x2000) / 2;
2749 xp2 += deparse_angle_region(angs[ANG_B], 0x0300, 0x0B00, 0x1400);
2750
2751 if (xp1 > CONTROL_MAX_VAL)
2752 xp1 = CONTROL_MAX_VAL;
2753 else if (xp1 < -CONTROL_MAX_VAL)
2754 xp1 = -CONTROL_MAX_VAL;
2755
2756 if (yp > CONTROL_MAX_VAL)
2757 yp = CONTROL_MAX_VAL;
2758 else if (yp < -CONTROL_MAX_VAL)
2759 yp = -CONTROL_MAX_VAL;
2760
2761 if (xp2 > CONTROL_MAX_VAL)
2762 xp2 = CONTROL_MAX_VAL;
2763 else if (xp2 < -CONTROL_MAX_VAL)
2764 xp2 = -CONTROL_MAX_VAL;
2765
2766 } else {
2767 slam_head(angs);
2768 }
2769
2770 // b+xp2, -p+yp, 0+zv, h+xp1, 0, 0
2771 physics_set_player_controls(INP6D_CONTROL_BANK, xp2, yp, zv, xp1, 0, 0);
2772 }
2773 last_but = inp6d_in->but;
2774 }
2775 #endif // VFX1_SUPPORT
2776
2777 #ifdef CTM_SUPPORT
2778
2779 // note secret filtering code these days....
ctm_chk(void)2780 void ctm_chk(void) {
2781 i6s_event *inp6d_in;
2782 short *angs;
2783
2784 if (game_paused)
2785 return;
2786 inp6d_in = i6_poll();
2787 if (inp6d_in == NULL)
2788 return;
2789
2790 angs = set_abs_head(inp6d_in);
2791
2792 #ifdef PLAYTEST
2793 if (inp6d_dbg)
2794 mprintf("Parsed %04x %04x %04x to %d %d %d\n", inp6d_in->rx, inp6d_in->ry, inp6d_in->rz, angs[ANG_H],
2795 angs[ANG_P], angs[ANG_B]);
2796 #endif // PLAYTEST
2797
2798 #ifdef PLAYTEST
2799 if (!inp6d_player) {
2800 if (!inp6d_link)
2801 fr_camera_setone(NULL, EYE_HEADH, angs[ANG_H]);
2802 else
2803 fr_camera_setone(NULL, EYE_H, angs[ANG_H]);
2804 fr_camera_setone(NULL, EYE_P, angs[ANG_P]);
2805 fr_camera_setone(NULL, EYE_B, angs[ANG_B]);
2806 } else
2807 #endif // PLAYTEST
2808 {
2809 // combine the two when in cyberspace
2810 if (global_fullmap->cyber) {
2811 short h, p, b;
2812 h = deparse_angle_region(angs[ANG_H], 0x0400, 0x1400, 0x2000);
2813 p = deparse_angle_region(angs[ANG_P], 0x0400, 0x1400, 0x2000) / 2;
2814 b = deparse_angle_region(angs[ANG_B], 0x0300, 0x0B00, 0x1400);
2815 physics_set_player_controls(INP6D_CONTROL_BANK, b, -p, 0, h, 0, 0);
2816
2817 } else {
2818 slam_head(angs);
2819 }
2820 }
2821 }
2822 #endif // CTM_SUPPORT
2823
swift_chk(void)2824 void swift_chk(void) {
2825 i6s_event *inp6d_in;
2826 int our_vals[6], i, tmp;
2827
2828 // we'll want to put in code here to check for mouse_button_emulation
2829 // if (checking_mouse_button_emulation && <SOME CODE TO CHECK FOR BUTTON PRESS>)
2830 // mouse_button_emulated = TRUE;
2831
2832 if (game_paused)
2833 return;
2834 inp6d_in = i6_poll();
2835 if (inp6d_in == NULL)
2836 return;
2837
2838 inp6d_in->y = -inp6d_in->y; // doug cheats, film at 11
2839
2840 // translation
2841 for (i = 0; i < 3; i++) {
2842 tmp = inp6d_in->els[i];
2843 if (abs(tmp) > TRA_TOL)
2844 if (tmp > TRA_TOL)
2845 tmp = Tra_Scale(tmp - TRA_TOL);
2846 else
2847 tmp = Tra_Scale(tmp + TRA_TOL);
2848 else
2849 tmp = 0;
2850 our_vals[i] = tmp;
2851 }
2852
2853 // rotation
2854 for (i = 3; i < 6; i++) {
2855 tmp = inp6d_in->els[i];
2856 if (tmp > ROT_TOL)
2857 tmp = Rot_Scale(tmp - ROT_TOL);
2858 else if (tmp < -ROT_TOL)
2859 tmp = Rot_Scale(tmp + ROT_TOL);
2860 else
2861 tmp = 0;
2862 our_vals[i] = tmp;
2863 } // was h = -ry, p = rx, b = -rz
2864
2865 #ifdef PLAYTEST
2866 if (inp6d_dbg)
2867 mprintf("Parsed %04x %04x %04x %04x %04x %04x to %d %d %d %d %d %d\n", inp6d_in->els[0], inp6d_in->els[1],
2868 inp6d_in->els[2], inp6d_in->els[3], inp6d_in->els[4], inp6d_in->els[5], our_vals[0], our_vals[1],
2869 our_vals[2], our_vals[3], our_vals[4], our_vals[5]);
2870 #endif
2871
2872 #ifdef PLAYTEST
2873 if (!inp6d_player) {
2874 for (i = 0; i < 3; i++)
2875 fr_camera_slewcam(NULL, i, our_vals[i] / 5); // cheat cheat cheat
2876 fr_camera_slewcam(NULL, EYE_H, our_vals[ANG_H] / 3);
2877 fr_camera_slewcam(NULL, EYE_P, our_vals[ANG_P] / 3);
2878 fr_camera_slewcam(NULL, EYE_B, our_vals[ANG_B] / 3);
2879 } else
2880 #endif
2881 {
2882 physics_set_player_controls(INP6D_CONTROL_BANK, our_vals[0], our_vals[1], our_vals[2], our_vals[3], our_vals[4],
2883 our_vals[5]);
2884 }
2885 }
2886
2887 // various hacked hotkey functions....
2888 #pragma disable_message(202)
2889 #if defined(VFX1_SUPPORT) || defined(CTM_SUPPORT)
recenter_headset(ushort keycode,uint32_t context,intptr_t data)2890 uchar recenter_headset(ushort keycode, uint32_t context, intptr_t data) {
2891 long start_time = *tmd_ticks;
2892 i6s_event *inp6d_geth;
2893 do {
2894 inp6d_geth = i6_poll();
2895 } while ((inp6d_geth == NULL) && (*tmd_ticks < start_time + (280 / 4)));
2896 if (inp6d_geth != NULL) {
2897 tracker_initial_pos[0] = inp6d_geth->ry;
2898 tracker_initial_pos[1] = inp6d_geth->rx;
2899 tracker_initial_pos[2] = -inp6d_geth->rz;
2900 // mprintf("Tip %x %x %x\n",tracker_initial_pos[0],tracker_initial_pos[1],tracker_initial_pos[2]);
2901 message_info("Headset ReCentered");
2902 } // should message_info here with no headset found
2903 return FALSE;
2904 }
2905 #endif
2906
recenter_joystick(ushort keycode,uint32_t context,intptr_t data)2907 uchar recenter_joystick(ushort keycode, uint32_t context, intptr_t data) {
2908 joy_center();
2909 string_message_info(REF_STR_CenterJoyDone);
2910 return FALSE;
2911 }
2912
change_gamma(ushort keycode,uint32_t context,intptr_t data)2913 uchar change_gamma(ushort keycode, uint32_t context, intptr_t data) {
2914 static fix cit_gamma = fix_make(1, 0);
2915 int dir = (int)data;
2916 if ((dir < 0) && (cit_gamma > fix_make(0, 0x6000)))
2917 cit_gamma -= fix_make(0, 0x0400);
2918 else if ((dir > 0) && (cit_gamma < fix_make(1, 0x6000)))
2919 cit_gamma += fix_make(0, 0x0800);
2920 else
2921 dir = 0;
2922 if (dir != 0)
2923 gr_set_gamma_pal(0, 256, cit_gamma);
2924 // here, should do message_info ResXXX+1-dir, have 3 strings in file, Lowered, Maxed, Raised
2925 // instead, ill do a switch for now...
2926 switch (dir) {
2927 case -1:
2928 message_info("Gamma Lowered");
2929 break;
2930 case 0:
2931 message_info("Gamma Maxed Out");
2932 break;
2933 case 1:
2934 message_info("Gamma Raised");
2935 break;
2936 }
2937 return FALSE;
2938 }
2939 #pragma enable_message(202)
2940
2941 #define CYBERMAN_MOTION (1 << 1)
2942 #define CYBERMAN_FIRE (1 << 0) // either other button
2943
2944 #define CYB_MAX_VAL (1 << 15)
2945 #define CYB_TOL (CYB_MAX_VAL >> 14)
2946 #define CYB_Scale(x) (((x)*CONTROL_MAX_VAL) / (CYB_MAX_VAL - CYB_TOL))
2947
2948 // total hack lame inp6d function for now....
cyberman_chk(void)2949 void cyberman_chk(void) {
2950 // static inp6d_raw_event last_swift;
2951 i6s_event *inp6d_in;
2952 int xp, yp, zv, h, p, b;
2953 static uchar cyb_mouse_around = TRUE, pchange = FALSE;
2954 static int p_vel = 0, b_vel = 0; // , h_vel=0;
2955
2956 // we'll want to put in code here to check for mouse_button_emulation
2957 // if (checking_mouse_button_emulation && <SOME CODE TO CHECK FOR BUTTON PRESS>)
2958 // mouse_button_emulated = TRUE;
2959
2960 if (game_paused)
2961 return;
2962 inp6d_in = i6_poll();
2963 if (inp6d_in == NULL)
2964 return;
2965
2966 // should wait for a motion prior to flipping over
2967 if ((inp6d_in->but & CYBERMAN_MOTION) == 0) {
2968 if (!cyb_mouse_around) {
2969 #ifdef PLAYTEST
2970 mprintf("CMA punt, zero controls\n");
2971 #endif
2972 physics_set_player_controls(INP6D_CONTROL_BANK, 0, 0, 0, 0, 0, 0);
2973 uiGlobalEventMask |= (UI_EVENT_MOUSE | UI_EVENT_MOUSE_MOVE);
2974 uiSetMouseMotionPolling(TRUE);
2975 uiShowMouse(NULL);
2976 cyb_mouse_around = TRUE;
2977 }
2978 return; // should allow mouse in this case, since we really need to do that
2979 } else {
2980 if (cyb_mouse_around) {
2981 uiGlobalEventMask &= ~(UI_EVENT_MOUSE | UI_EVENT_MOUSE_MOVE);
2982 uiSetMouseMotionPolling(FALSE);
2983 uiHideMouse(NULL);
2984 cyb_mouse_around = FALSE;
2985 }
2986 }
2987
2988 if (inp6d_in->but & CYBERMAN_FIRE) {
2989 LGPoint pos =
2990 MakePoint(_current_view->abs_x + RectWidth(_current_view->r) / 2,
2991 _current_view->abs_y + RectHeight(_current_view->r) / 2 + (RectHeight(_current_view->r) >> 5));
2992
2993 #ifdef SVGA_SUPPORT
2994 ss_point_convert(&(pos.x), &(pos.y), FALSE);
2995 #endif
2996 fire_player_weapon(&pos, _current_view, TRUE);
2997 }
2998
2999 // fire hack, mouse hack
3000 xp = inp6d_in->x;
3001 if (abs(xp) > CYB_TOL)
3002 if (xp > CYB_TOL)
3003 xp = CYB_Scale(xp - CYB_TOL);
3004 else
3005 xp = CYB_Scale(xp + CYB_TOL);
3006 else
3007 xp = 0;
3008 yp = -inp6d_in->y;
3009 if (abs(yp) > CYB_TOL)
3010 if (yp > CYB_TOL)
3011 yp = CYB_Scale(yp - CYB_TOL);
3012 else
3013 yp = CYB_Scale(yp + CYB_TOL);
3014 else
3015 yp = 0;
3016 zv = inp6d_in->z;
3017 if (abs(zv) > CYB_TOL)
3018 if (zv > CYB_TOL)
3019 zv = CYB_Scale(zv - CYB_TOL);
3020 else
3021 zv = CYB_Scale(zv + CYB_TOL);
3022 else
3023 zv = 0;
3024
3025 h = -(short)inp6d_in->ry;
3026 if (h > ROT_TOL)
3027 h = Rot_Scale(h - ROT_TOL);
3028 else if (h < -ROT_TOL)
3029 h = Rot_Scale(h + ROT_TOL);
3030 else
3031 h = 0;
3032 p = (short)inp6d_in->rx;
3033 if (p > ROT_TOL)
3034 p = Rot_Scale(p - ROT_TOL);
3035 else if (p < -ROT_TOL)
3036 p = Rot_Scale(p + ROT_TOL);
3037 else
3038 p = 0;
3039 b = -(short)inp6d_in->rz;
3040 if (b > ROT_TOL)
3041 b = Rot_Scale(b - ROT_TOL);
3042 else if (b < -ROT_TOL)
3043 b = Rot_Scale(b + ROT_TOL);
3044 else
3045 b = 0;
3046
3047 #ifdef PLAYTEST
3048 if (inp6d_dbg)
3049 mprintf("Parsed %04x %04x %04x %04x %04x %04x b%x to %d %d %d %d %d %d\n", inp6d_in->x, inp6d_in->y,
3050 inp6d_in->z, inp6d_in->rx, inp6d_in->ry, inp6d_in->rz, inp6d_in->but, xp, yp, zv, h, p, b);
3051 #endif
3052
3053 #ifdef PLAYTEST
3054 if (!inp6d_player) {
3055 fr_camera_slewcam(NULL, EYE_X, xp / 5);
3056 fr_camera_slewcam(NULL, EYE_Y, yp / 5);
3057 fr_camera_slewcam(NULL, EYE_Z, zv / 5);
3058 fr_camera_slewcam(NULL, EYE_H, h / 3);
3059 fr_camera_slewcam(NULL, EYE_P, p / 3);
3060 fr_camera_slewcam(NULL, EYE_B, b / 3);
3061 } else
3062 #endif
3063 {
3064 if (abs(xp) < 12)
3065 xp = 0;
3066 if (abs(yp) < 12)
3067 yp = 0;
3068 // if ((abs(xp)>80)||(abs(yp)>80))
3069 // p=b=0; // how bout that cyberman, eh?
3070 if (b != 0)
3071 xp = yp = zv = p = 0;
3072 if (b > 0) {
3073 if (b_vel > 0)
3074 b_vel += 4;
3075 else
3076 b_vel = 4;
3077 if (b_vel > CONTROL_MAX_VAL)
3078 b_vel = CONTROL_MAX_VAL;
3079 } else if (b < 0) {
3080 if (b_vel < 0)
3081 b_vel -= 4;
3082 else
3083 b_vel = -4;
3084 if (b_vel < -CONTROL_MAX_VAL)
3085 b_vel = -CONTROL_MAX_VAL;
3086 } else
3087 b_vel = 0;
3088 b = b_vel;
3089
3090 if (p > 0) {
3091 if (p_vel > 0)
3092 p_vel += 6;
3093 else
3094 p_vel = 16;
3095 if (p_vel > CONTROL_MAX_VAL)
3096 p_vel = CONTROL_MAX_VAL;
3097 } else if (p < 0) {
3098 if (p_vel < 0)
3099 p_vel -= 6;
3100 else
3101 p_vel = -16;
3102 if (p_vel < -CONTROL_MAX_VAL)
3103 p_vel = -CONTROL_MAX_VAL;
3104 } else
3105 p_vel = 0;
3106 p = p_vel;
3107
3108 // if ((abs(b_vel)>80)||(abs(p_vel)>80))
3109 // zv=0; // no posture changes while zipping along in pitch
3110 if ((b_vel | p_vel) || (abs(xp) > 10) || (abs(yp) > 10))
3111 zv = 0; // no longer can posture change while pitch or banking
3112 // but should be able to jump........ arrrrghghghhh
3113
3114 if (zv > 0) {
3115 if (player_struct.posture != POSTURE_STAND) {
3116 if (pchange == FALSE)
3117 player_struct.posture--;
3118 pchange = TRUE;
3119 zv = 0;
3120 } else if (pchange)
3121 zv = 0; // dont jump as you stand
3122 // else
3123 // pchange=TRUE; // treat a jump like a posture change...
3124 } else if (zv < 0) {
3125 if (player_struct.posture != POSTURE_PRONE)
3126 if (pchange == FALSE)
3127 player_struct.posture++;
3128 pchange = TRUE;
3129 zv = 0;
3130 } else
3131 pchange = FALSE;
3132
3133 #ifdef PLAYTEST
3134 if (inp6d_link)
3135 p = b = 0; // no p or b
3136 #endif
3137 physics_set_player_controls(INP6D_CONTROL_BANK, xp, yp, zv, h, p, b);
3138 }
3139 }
3140
3141 #define JOY_USE_CONTROL_MAX_VAL (128)
3142 #define JOY_MAX_VAL (128)
3143 #define JOY_TOL (30)
3144
3145 #define SENSITIVITY_CONTROL
3146 #ifdef SENSITIVITY_CONTROL
3147 #define JOY_Scale(x) fix_mul(inpJoystickSens, (((x)*JOY_USE_CONTROL_MAX_VAL) / (JOY_MAX_VAL - JOY_TOL)))
3148 #else
3149 #define JOY_Scale(x) (((x)*JOY_USE_CONTROL_MAX_VAL) / (JOY_MAX_VAL - JOY_TOL))
3150 #endif
3151
joystick_emulate_mouse(int x,int y,uchar bstate,uchar last_bstate)3152 void joystick_emulate_mouse(int x, int y, uchar bstate, uchar last_bstate) {
3153 mouse_add_velocity((x)*abs(x) << (MOUSE_VEL_UNIT_SHF - APPROX_CIT_CYCLE_SHFT - 4),
3154 -y * abs(y) << (MOUSE_VEL_UNIT_SHF - APPROX_CIT_CYCLE_SHFT - 4));
3155 // if any button states are changed, generate
3156 // a low level mouse event.
3157 if ((bstate) != (last_bstate)) {
3158 // sadly, there is no good api to get at this mouse library
3159 // variable, so we will employ gnosis for now.
3160 extern short mouseInstantButts;
3161 mouse_event me;
3162
3163 ui_mouse_get_xy(&me.x, &me.y);
3164 #ifdef SVGA_SUPPORT
3165 ss_point_convert(&me.x, &me.y, FALSE);
3166 #endif
3167 me.type = 0;
3168 me.buttons = (uchar)mouseInstantButts;
3169 if ((bstate & 1) != (last_bstate & 1)) {
3170 me.type |= (bstate & 1) ? MOUSE_LDOWN : MOUSE_LUP;
3171 if (bstate & 1)
3172 me.buttons |= (1 << MOUSE_LBUTTON);
3173 else
3174 me.buttons &= ~(1 << MOUSE_LBUTTON);
3175 }
3176 if ((bstate & 2) != (last_bstate & 2)) {
3177 me.type |= (bstate & 2) ? MOUSE_RDOWN : MOUSE_RUP;
3178 if (bstate & 2)
3179 me.buttons |= (1 << MOUSE_RBUTTON);
3180 else
3181 me.buttons &= ~(1 << MOUSE_RBUTTON);
3182 }
3183 me.timestamp = *tmd_ticks;
3184 mouse_generate(me);
3185 }
3186 }
3187
joystick_chk(void)3188 void joystick_chk(void) {
3189 static uchar last_bstate;
3190 int xp, yp, zv = 0, h, p, b = 0;
3191 char pot_vals[4];
3192 uchar bstate;
3193
3194 // this has to be fixed...
3195 {
3196 static uchar once = 0;
3197 if (!once) {
3198 once = 1;
3199 joy_center();
3200 }
3201 } // i wonder if we can punt this???
3202
3203 bstate = joy_read_buttons();
3204 if (checking_mouse_button_emulation && (last_bstate != bstate)) {
3205 mouse_button_emulated = TRUE;
3206 last_bstate = bstate;
3207 }
3208
3209 if (game_paused)
3210 return;
3211
3212 joy_read_pots(pot_vals);
3213
3214 yp = -((int)pot_vals[1]);
3215 // mprintf("have %d from %d...",yp,pot_vals[1]);
3216 if (abs(yp) > JOY_TOL)
3217 if (yp > JOY_TOL)
3218 yp = JOY_Scale(yp - JOY_TOL);
3219 else if (yp < -JOY_TOL)
3220 yp = JOY_Scale(yp + JOY_TOL);
3221 else
3222 yp = 0;
3223 h = pot_vals[0];
3224 // mprintf("have %d from %d...",h,pot_vals[0]);
3225 if (abs(h) > JOY_TOL)
3226 if (h > JOY_TOL)
3227 h = JOY_Scale(h - JOY_TOL);
3228 else if (h < -JOY_TOL)
3229 h = JOY_Scale(h + JOY_TOL);
3230 else
3231 h = 0;
3232
3233 if (h > CONTROL_MAX_VAL)
3234 h = CONTROL_MAX_VAL;
3235 else if (h < -CONTROL_MAX_VAL)
3236 h = -CONTROL_MAX_VAL;
3237 if (yp > CONTROL_MAX_VAL)
3238 yp = CONTROL_MAX_VAL;
3239 else if (yp < -CONTROL_MAX_VAL)
3240 yp = -CONTROL_MAX_VAL;
3241 // mprintf("final %d and %d...",h,yp);
3242
3243 // pitch with throttle here, maybe pedal heading or something
3244 // if (joystick_count==4)
3245
3246 if (inp_sidestep) // toggle h/sidestep, forward/pitch
3247 {
3248 xp = h;
3249 p = -yp;
3250 h = yp = 0;
3251 } else
3252 p = xp = 0;
3253 // mprintf("net %d %d %d %d\n",xp,yp,h,p);
3254
3255 #ifdef PLAYTEST
3256 if (inp6d_dbg) {
3257 if (bstate != 0)
3258 mprintf("Yo buttons %2.2x..", bstate);
3259 else
3260 mprintf(" ");
3261 mprintf("cntrl %d %d %d %d from pots %d %d %d %d\n", xp, yp, h, p, pot_vals[0], pot_vals[1], pot_vals[2],
3262 pot_vals[3]);
3263 }
3264 #endif
3265
3266 if (joystick_mouse_emul) {
3267 joystick_emulate_mouse(h, yp, bstate, last_bstate);
3268 h = yp = xp = p = 0;
3269 } else if (_current_loop <= FULLSCREEN_LOOP) {
3270 if (bstate & 1)
3271 inp_weapon_button((bstate & 1) != (last_bstate & 1));
3272 // reset on release
3273 else if ((last_bstate & 1) == 1) {
3274 inp_weapon_junk();
3275 }
3276 if (bstate & 2)
3277 inp_use_sidestep_button();
3278 else
3279 inp_use_sidestep_junk();
3280 if (bstate & 4)
3281 zv = MAX_JUMP_CONTROL;
3282
3283 // if (bstate&8) // ??, who knows
3284
3285 if (bstate >= 16) // hat behavior
3286 { // coolie... HAT
3287 switch (bstate & JOY_HAT_MASK) {
3288 case JOY_HAT_N:
3289 if (p == 0)
3290 p = -CONTROL_MAX_VAL;
3291 break;
3292 case JOY_HAT_E:
3293 if (b == 0)
3294 b = CONTROL_MAX_VAL;
3295 break;
3296 case JOY_HAT_S:
3297 if (p == 0)
3298 p = CONTROL_MAX_VAL;
3299 break;
3300 case JOY_HAT_W:
3301 if (b == 0)
3302 b = -CONTROL_MAX_VAL;
3303 break;
3304 }
3305 }
3306 }
3307
3308 if (_current_loop <= FULLSCREEN_LOOP)
3309 physics_set_player_controls(JOYST_CONTROL_BANK, xp, yp, zv, h, p, b);
3310 last_bstate = bstate;
3311 }
3312
3313 #ifdef PLAYTEST
3314 #include <wsample.h>
3315 #pragma disable_message(202)
toggle_profile(ushort keycode,uint32_t context,intptr_t data)3316 uchar toggle_profile(ushort keycode, uint32_t context, intptr_t data) {
3317 static uchar UserProf = FALSE;
3318 if (UserProf)
3319 _MARK_("User Off");
3320 else
3321 _MARK_("User On");
3322 UserProf = !UserProf;
3323 return TRUE;
3324 }
3325 #pragma enable_message(202)
3326 #endif
3327
3328 #endif // NOT_YET
3329
3330 // ---------
3331 // EXTERNALS
3332 // ---------
3333
install_motion_mouse_handler(LGRegion * r,frc * fr)3334 void install_motion_mouse_handler(LGRegion *r, frc *fr) {
3335 int cid;
3336 view3d_data *data = (view3d_data *)malloc(sizeof(view3d_data));
3337 data->ldown = FALSE;
3338 data->rdown = FALSE;
3339 data->lastsect = 0;
3340 data->lastleft.x = 0;
3341 data->lastleft.y = 0;
3342 data->lastright.x = 0;
3343 data->lastright.y = 0;
3344 data->fr = fr;
3345 uiInstallRegionHandler(r, UI_EVENT_MOUSE | UI_EVENT_MOUSE_MOVE | UI_EVENT_USER_DEFINED,
3346 view3d_mouse_handler, (intptr_t)data, &cid);
3347
3348 // Yeah, yeah, I know, it's not a mouse handler...
3349 uiInstallRegionHandler(r, UI_EVENT_KBD_COOKED, view3d_key_handler, 0, &cid);
3350 uiSetRegionDefaultCursor(r, NULL);
3351 }
3352
3353 extern uchar motion_keycheck_handler(uiEvent *, LGRegion *, intptr_t);
3354
install_motion_keyboard_handler(LGRegion * r)3355 void install_motion_keyboard_handler(LGRegion *r) {
3356 int cid;
3357 uiInstallRegionHandler(r, UI_EVENT_KBD_POLL, motion_keycheck_handler, 0, &cid);
3358 }
3359
pop_cursor_object(void)3360 void pop_cursor_object(void) {
3361 if (input_cursor_mode != INPUT_OBJECT_CURSOR)
3362 return;
3363 object_on_cursor = OBJ_NULL;
3364 uiPopSlabCursor(&fullscreen_slab);
3365 uiPopSlabCursor(&main_slab);
3366 input_cursor_mode = INPUT_NORMAL_CURSOR;
3367 }
3368
3369 extern void push_live_grenade_cursor(ObjID obj);
3370
push_cursor_object(short obj)3371 void push_cursor_object(short obj) {
3372 LGPoint hotspot;
3373 grs_bitmap *bmp;
3374 #ifdef CURSOR_BACKUPS
3375 extern LGCursor backup_object_cursor;
3376 #endif
3377 if (objs[obj].obclass == CLASS_GRENADE && objGrenades[objs[obj].specID].flags & GREN_ACTIVE_FLAG) {
3378 push_live_grenade_cursor(obj);
3379 return;
3380 }
3381 uiHideMouse(NULL);
3382 if ((ID2TRIP(obj) == HEAD_TRIPLE) || (ID2TRIP(obj) == HEAD2_TRIPLE))
3383 bmp = bitmaps_3d[BMAP_NUM_3D(ObjProps[OPNUM(obj)].bitmap_3d) + objs[obj].info.current_frame];
3384 else
3385 bmp = bitmaps_2d[OPNUM(obj)];
3386
3387 if (bmp == NULL) return;
3388
3389 object_on_cursor = obj;
3390 input_cursor_mode = INPUT_OBJECT_CURSOR;
3391 #ifdef SVGA_SUPPORT
3392 if (convert_use_mode != 0) {
3393 grs_canvas temp_canv;
3394 // Get a new bigger bitmap
3395 gr_init_bm(&svga_cursor_bmp, svga_cursor_bits, BMT_FLAT8, BMF_TRANS,
3396 lg_min(MODE_SCONV_X(bmp->w, 2), SVGA_CURSOR_WIDTH),
3397 lg_min(MODE_SCONV_Y(bmp->h, 2), SVGA_CURSOR_HEIGHT));
3398 gr_make_canvas(&svga_cursor_bmp, &temp_canv);
3399
3400 // Draw into it
3401 gr_push_canvas(&temp_canv);
3402 gr_clear(0);
3403 gr_scale_bitmap(bmp, 0, 0, svga_cursor_bmp.w, svga_cursor_bmp.h);
3404 gr_pop_canvas();
3405
3406 // use it
3407 bmp = &svga_cursor_bmp;
3408 }
3409 #endif
3410 hotspot.x = bmp->w / 2;
3411 hotspot.y = bmp->h / 2;
3412 uiMakeBitmapCursor(&object_cursor, bmp, hotspot);
3413 #ifdef CURSOR_BACKUPS
3414 uiMakeBitmapCursor(&backup_object_cursor, bmp, hotspot);
3415 #endif
3416 uiPushSlabCursor(&fullscreen_slab, &object_cursor);
3417 uiPushSlabCursor(&main_slab, &object_cursor);
3418 uiShowMouse(NULL);
3419 look_at_object(obj);
3420 }
3421