1 /*
2 Copyright (C) 2007 The Android Open Source Project
3
4 */
5
6 #include "quakedef.h"
7
8 unsigned short d_8to16table[256];
9 unsigned d_8to24table[256];
10
11 #ifdef SUPPORT_8BIT_MIPMAPGENERATION
12 unsigned char d_15to8table[65536];
13 #endif
14
15 cvar_t mouse_button_commands[3] =
16 {
17 CVAR2("mouse1","+attack"),
18 CVAR2("mouse2","+strafe"),
19 CVAR2("mouse3","+forward"),
20 };
21
22 static const int MOUSE_LEFTBUTTON = 1;
23 static const int MOUSE_MIDDLEBUTTON = 2;
24 static const int MOUSE_RIGHTBUTTON = 4;
25
26 bool mouse_tap;
27 float mouse_x, mouse_y;
28 float old_mouse_x, old_mouse_y;
29 int mx, my;
30 bool mouse_buttonstate;
31 bool mouse_oldbuttonstate;
32
33 cvar_t m_filter = CVAR2("m_filter","1");
34
35 int scr_width, scr_height;
36
37 cvar_t _windowed_mouse = CVAR3("_windowed_mouse","0", true);
38
39 /*-----------------------------------------------------------------------*/
40
41 //int texture_mode = GL_NEAREST;
42 //int texture_mode = GL_NEAREST_MIPMAP_NEAREST;
43 //int texture_mode = GL_NEAREST_MIPMAP_LINEAR;
44 int texture_mode = GL_LINEAR;
45 // int texture_mode = GL_LINEAR_MIPMAP_NEAREST;
46 //int texture_mode = GL_LINEAR_MIPMAP_LINEAR;
47
48 int texture_extension_number = 1;
49
50 float gldepthmin, gldepthmax;
51
52 cvar_t gl_ztrick = CVAR2("gl_ztrick","0");
53
54 const char *gl_vendor;
55 const char *gl_renderer;
56 const char *gl_version;
57 const char *gl_extensions;
58
59 qboolean is8bit = false;
60 qboolean isPermedia = false;
61 qboolean gl_mtexable = false;
62
63 /*-----------------------------------------------------------------------*/
D_BeginDirectRect(int x,int y,byte * pbitmap,int width,int height)64 void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
65 {
66 }
67
D_EndDirectRect(int x,int y,int width,int height)68 void D_EndDirectRect (int x, int y, int width, int height)
69 {
70 }
71
VID_Shutdown(void)72 void VID_Shutdown(void)
73 {
74 }
75
VID_ShiftPalette(unsigned char * p)76 void VID_ShiftPalette(unsigned char *p)
77 {
78 // VID_SetPalette(p);
79 }
80
VID_SetPalette(unsigned char * palette)81 void VID_SetPalette (unsigned char *palette)
82 {
83 byte *pal;
84 unsigned r,g,b;
85 unsigned v;
86 int r1,g1,b1;
87 int k;
88 unsigned short i;
89 unsigned *table;
90 FILE *f;
91 char s[255];
92 int dist, bestdist;
93 static qboolean palflag = false;
94
95 PMPBEGIN(("VID_SetPalette"));
96 //
97 // 8 8 8 encoding
98 //
99 Con_Printf("Converting 8to24\n");
100
101 pal = palette;
102 table = d_8to24table;
103 for (i=0 ; i<256 ; i++)
104 {
105 r = pal[0];
106 g = pal[1];
107 b = pal[2];
108 pal += 3;
109
110 // v = (255<<24) + (r<<16) + (g<<8) + (b<<0);
111 // v = (255<<0) + (r<<8) + (g<<16) + (b<<24);
112 v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
113 *table++ = v;
114 }
115 d_8to24table[255] &= 0xffffff; // 255 is transparent
116
117 #ifdef SUPPORT_8BIT_MIPMAPGENERATION
118
119 // JACK: 3D distance calcs - k is last closest, l is the distance.
120 // FIXME: Precalculate this and cache to disk.
121 if (palflag)
122 return;
123 palflag = true;
124
125 COM_FOpenFile("glquake/15to8.pal", &f);
126 if (f) {
127 fread(d_15to8table, 1<<15, 1, f);
128 fclose(f);
129 } else {
130 PMPBEGIN(("Creating 15to8 palette"));
131 for (i=0; i < (1<<15); i++) {
132 /* Maps
133 0000.0000.0000.0000
134 0000.0000.0001.1111 = Red = 0x001F
135 0000.0011.1110.0000 = Green = 0x03E0
136 0111.1100.0000.0000 = Blue = 0x7C00
137 */
138 r = ((i & 0x1F) << 3)+4;
139 g = ((i & 0x03E0) >> (5-3)) +4;
140 b = ((i & 0x7C00) >> (10-3))+4;
141 pal = (unsigned char *)d_8to24table;
142 for (v=0,k=0,bestdist=0x7FFFFFFF; v<256; v++,pal+=4) {
143 r1 = (int)r - (int)pal[0];
144 g1 = (int)g - (int)pal[1];
145 b1 = (int)b - (int)pal[2];
146 dist = ((r1*r1)+(g1*g1)+(b1*b1));
147 if (dist < bestdist) {
148 k=v;
149 bestdist = dist;
150 }
151 }
152 d_15to8table[i]=k;
153 }
154 PMPEND(("Creating 15to8 palette"));
155 sprintf(s, "%s/glquake", com_gamedir);
156 Sys_mkdir (s);
157 sprintf(s, "%s/glquake/15to8.pal", com_gamedir);
158 if ((f = fopen(s, "wb")) != NULL) {
159 fwrite(d_15to8table, 1<<15, 1, f);
160 fclose(f);
161 }
162 else
163 {
164 Con_Printf("Could not write %s\n", s);
165 }
166 }
167
168 #endif // SUPPORT_8BIT_MIPMAPGENERATION
169 PMPEND(("VID_SetPalette"));
170 }
171
172 /*
173 ===============
174 GL_Init
175 ===============
176 */
GL_Init(void)177 void GL_Init (void)
178 {
179 gl_vendor = (char*) glGetString (GL_VENDOR);
180 Con_Printf ("GL_VENDOR: %s\n", gl_vendor);
181 GLCHECK("glGetString");
182 gl_renderer = (char*) glGetString (GL_RENDERER);
183 Con_Printf ("GL_RENDERER: %s\n", gl_renderer);
184 GLCHECK("glGetString");
185
186 gl_version = (char*) glGetString (GL_VERSION);
187 Con_Printf ("GL_VERSION: %s\n", gl_version);
188 GLCHECK("glGetString");
189 gl_extensions = (char*) glGetString (GL_EXTENSIONS);
190 Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions);
191 GLCHECK("glGetString");
192
193 // Con_Printf ("%s %s\n", gl_renderer, gl_version);
194
195 // Enable/disable multitexture:
196
197 gl_mtexable = true;
198
199 glClearColor (1,0,0,0);
200 glCullFace(GL_FRONT);
201 glEnable(GL_TEXTURE_2D);
202
203 glEnable(GL_ALPHA_TEST);
204 glAlphaFunc(GL_GREATER, 0.666);
205
206 #ifdef USE_OPENGLES
207 #else
208 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
209 #endif
210 glShadeModel(GL_FLAT);
211 glDisable(GL_DITHER);
212
213 // perspective correction don't work well currently
214 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
215
216 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
217 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
218 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
219 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
220
221 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
222
223 // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
224 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
225
226 #ifdef USE_OPENGLES
227 glEnableClientState(GL_VERTEX_ARRAY);
228 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
229 #endif
230 }
231
232 /*
233 =================
234 GL_BeginRendering
235
236 =================
237 */
GL_BeginRendering(int * x,int * y,int * width,int * height)238 void GL_BeginRendering (int *x, int *y, int *width, int *height)
239 {
240 extern cvar_t gl_clear;
241
242 *x = *y = 0;
243 *width = scr_width;
244 *height = scr_height;
245
246 // if (!wglMakeCurrent( maindc, baseRC ))
247 // Sys_Error ("wglMakeCurrent failed");
248
249 // glViewport (*x, *y, *width, *height);
250 }
251
252
GL_EndRendering(void)253 void GL_EndRendering (void)
254 {
255 //glFlush();
256 // !!! Swap buffers.
257 }
258
Init_KBD(void)259 void Init_KBD(void)
260 {
261 }
262
263 // This function controls whether or not 8-bit paletted textures are used:
264
VID_Is8bit(void)265 qboolean VID_Is8bit(void)
266 {
267 return 0;
268 }
269
Check_Gamma(unsigned char * pal)270 static void Check_Gamma (unsigned char *pal)
271 {
272 float vid_gamma;
273 float f, inf;
274 unsigned char palette[768];
275 int i;
276
277 if ((i = COM_CheckParm("-gamma")) == 0) {
278 vid_gamma = 0.5; // brighten up game.
279 } else
280 vid_gamma = Q_atof(com_argv[i+1]);
281
282 if(vid_gamma != 1)
283 {
284 for (i=0 ; i<768 ; i++)
285 {
286 f = pow ( (pal[i]+1)/256.0 , vid_gamma );
287 inf = f*255 + 0.5;
288 if (inf < 0)
289 inf = 0;
290 if (inf > 255)
291 inf = 255;
292 palette[i] = (unsigned char) inf;
293 }
294 }
295
296 memcpy (pal, palette, sizeof(palette));
297 }
298
VID_Init(unsigned char * palette)299 void VID_Init(unsigned char *palette)
300 {
301 int i;
302 GLint attribs[32];
303 char gldir[MAX_OSPATH];
304 int width = scr_width, height = scr_height;
305
306 S_Init();
307
308 Init_KBD();
309
310 Cvar_RegisterVariable (&gl_ztrick);
311
312 vid.maxwarpwidth = scr_width;
313 vid.maxwarpheight = height;
314 vid.colormap = host_colormap;
315 vid.fullbright = 0xffff;
316 vid.aspect = (float) scr_width / (float) scr_height;
317 vid.numpages = 2;
318 vid.rowbytes = 2 * scr_width;
319 vid.width = scr_width;
320 vid.height = scr_height;
321
322 vid.conwidth = scr_width;
323 vid.conheight = scr_height;
324
325 // interpret command-line params
326
327 // set vid parameters
328
329 GL_Init();
330
331 sprintf (gldir, "%s/glquake", com_gamedir);
332 Sys_mkdir (gldir);
333
334 Check_Gamma(palette);
335 VID_SetPalette(palette);
336
337 Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height);
338
339 vid.recalc_refdef = 1; // force a surface cache flush
340 }
341
342 // Android Key event codes. Some of these are
343 // only generated from the simulator.
344 // Not all Android devices can generate all codes.
345
346 byte scantokey[] =
347 {
348 '$', K_ESCAPE, '$', '$', K_ESCAPE, '$', '$', '0', // 0.. 7
349 '1', '2', '3', '4', '5', '6', '7', '8', // 8..15
350 '9', '$', '$', K_UPARROW, K_DOWNARROW, K_LEFTARROW, K_RIGHTARROW, K_ENTER, // 16..23
351 '$', '$', '$', '$', '$', 'a', 'b', 'c', // 24..31
352
353 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', // 32..39
354 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', // 40..47
355 't', 'u', 'v', 'w', 'x', 'y', 'z', ',', // 48..55
356 '.', K_CTRL, K_SHIFT, K_TAB, ' ', '$', '$', '$', // 56..63
357 '$', '$', K_ENTER, K_BACKSPACE, '`', '-', '=', '[', // 64..71
358 ']', '\\', ';', '\'', '/', '@', '#', '$', // 72..79
359 '$', '$', K_ESCAPE, '$' // 80..83
360 };
361
362 byte scantokeyAlt[] =
363 {
364 0, 0, 0, 0, 0, 0, 0, 0, // 0.. 7
365 0, 0, 0, 0, 0, 0, 0, 0, // 8..15
366 0, 0, 0, 0, 0, 0, 0, 0, // 16..23
367 0, 0, 0, 0, 0, '%', '=', '8', // 24..31
368
369 '5', '2', '6', '-', '[', '$', ']', '"', // 32..39
370 '\'', '>', '<', '(', ')', '*', '3', '4', // 40..47
371 '+', '&', '9', '1', '7', '!', '#', ';', // 48..55
372 ':', 0, 0, 0, K_TAB, 0, 0, 0, // 56..63
373 0, 0, 0, 0, 0, 0, 0, 0, // 64..71
374 0, 0, '?', '0', 0, 0, 0, 0, // 72..79
375 0, 0, K_ESCAPE, 0 // 80..83
376 };
377
378 #if 0
379
380 byte scantokeyCap[] =
381 {
382 0, 0, 0, 0, 0, 0, 0, 0, // 0.. 7
383 0, 0, 0, 0, 0, 0, 0, 0, // 8..15
384 0, 0, 0, 0, 0, 0, 0, 0, // 16..23
385 0, 0, 0, 0, 0, 'A', 'B', 'C', // 24..31
386
387 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', // 32..39
388 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', // 40..47
389 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 0, // 48..55
390 0, 0, 0, 0, 0, 0, 0, 0, // 56..63
391 0, 0, 0, 0, 0, 0, 0, 0, // 64..71
392 0, 0, 0, 0, 0, 0, 0, 0, // 72..79
393 0, 0, K_ESCAPE, 0 // 80..83
394 };
395
396 #endif
397
398 byte scantokeySym[] =
399 {
400 0, 0, 0, 0, 0, 0, 0, 0, // 0.. 7
401 0, 0, 0, 0, 0, 0, 0, 0, // 8..15
402 0, 0, 0, 0, 0, 0, 0, 0, // 16..23
403 0, 0, 0, 0, 0, 0, 0, K_F8, // 24..31
404
405 K_F5, K_F2, K_F6, '_', 0, 0, 0, 0, // 32..39
406 0, 0, 0, 0, 0, 0, K_F3, K_F4, // 40..47
407 K_F11, 0, K_F9, K_F1, K_F7, K_F12, K_PAUSE, 0, // 48..55
408 0, 0, 0, 0, 0, 0, 0, 0, // 56..63
409 0, 0, 0, 0, 0, 0, 0, 0, // 64..71
410 0, 0, '`', K_F10, 0, 0, 0, 0, // 72..79
411 0, 0, K_ESCAPE, 0 // 80..83
412 };
413
414 #define ALT_KEY_VALUE 57
415 // #define CAPS_KEY_VALUE 58
416 #define SYM_KEY_VALUE 61
417
418 byte modifierKeyInEffect;
419
420 qboolean symKeyDown;
421 byte symKeyCode;
422
423 // Called from stand-alone main() function to process an event.
424 // Return non-zero if the event is handled.
425
AndroidEvent(int type,int value)426 int AndroidEvent(int type, int value)
427 {
428 if(value >= 0 && value < (int) sizeof(scantokey))
429 {
430 byte key;
431 qboolean isPress = type != 0;
432
433 qboolean isModifier = value == ALT_KEY_VALUE || value == SYM_KEY_VALUE;
434
435 if(isModifier)
436 {
437 if(isPress)
438 {
439 if(modifierKeyInEffect == value)
440 {
441 // Press modifier twice to cancel modifier
442 modifierKeyInEffect = 0;
443 }
444 else
445 {
446 // Most recent modifier key wins
447 modifierKeyInEffect = value;
448 }
449 }
450 return 1;
451 }
452 else
453 {
454 switch(modifierKeyInEffect)
455 {
456 default: key = scantokey[value]; break;
457 case ALT_KEY_VALUE: key = scantokeyAlt[value]; break;
458 // case CAP_KEY_VALUE: key = scantokeyCap[value]; break;
459 case SYM_KEY_VALUE: key = scantokeySym[value]; break;
460 }
461 if(!key)
462 {
463 key = scantokey[value];
464 }
465
466 // Hack: Remap @ and / to K_CTRL in game mode
467 if(key_dest == key_game && ! modifierKeyInEffect && (key == '@' || key == '/'))
468 {
469 key = K_CTRL;
470 }
471
472 if(!isPress)
473 {
474 modifierKeyInEffect = 0;
475 }
476 }
477
478 Key_Event(key, type);
479 // PMPLOG(("type: %d, value: %d -> %d '%c'\n", type, value, key, key));
480
481 return 1;
482 }
483 else
484 {
485 PMPWARNING(("unexpected event type: %d, value: %d\n", type, value));
486 }
487 return 0;
488 }
489
490 // Called from Java to process an event.
491 // Return non-zero if the event is handled.
492
493 #if !defined(__clang__)
AndroidEvent2(int type,int value)494 int AndroidEvent2(int type, int value)
495 #else
496 extern "C" int AndroidEvent2_LLVM(int type, int value)
497 #endif
498 {
499 Key_Event(value, type);
500 return 0;
501 }
502
503 static const int MOTION_DOWN = 0;
504 static const int MOTION_UP = 1;
505 static const int MOTION_MOVE = 2;
506 static const int MOTION_CANCEL = 3;
507
508 class GestureDetector {
509 private:
510 bool mIsScroll;
511 bool mIsTap;
512 bool mIsDoubleTap;
513
514 float mScrollX;
515 float mScrollY;
516
517 static const unsigned long long TAP_TIME_MS = 200;
518 static const unsigned long long DOUBLE_TAP_TIME_MS = 400;
519 static const int TAP_REGION_MANHATTAN_DISTANCE = 10;
520
521 bool mAlwaysInTapRegion;
522 float mDownX;
523 float mDownY;
524 unsigned long long mDownTime;
525 unsigned long long mPreviousDownTime;
526
527 /**
528 * Position of the last motion event.
529 */
530 float mLastMotionY;
531 float mLastMotionX;
532
533 public:
534 /**
535 * Analyze a motion event. Call this once for each motion event
536 * that is received by a view.
537 * @param ev the motion event to analyze.
538 */
analyze(unsigned long long eventTime,int action,float x,float y,float pressure,float size,int deviceId)539 void analyze(unsigned long long eventTime, int action,
540 float x, float y, float pressure, float size, int deviceId) {
541 mIsScroll = false;
542 mIsTap = false;
543 mIsDoubleTap = false;
544
545 switch (action) {
546 case MOTION_DOWN:
547 printf("Down");
548 // Remember where the motion event started
549 mLastMotionX = x;
550 mLastMotionY = y;
551 mDownX = x;
552 mDownY = y;
553 mPreviousDownTime = mDownTime;
554 mDownTime = eventTime;
555 mAlwaysInTapRegion = true;
556 break;
557
558 case MOTION_MOVE:
559 {
560 mIsScroll = true;
561 mScrollX = mLastMotionX - x;
562 mScrollY = mLastMotionY - y;
563 mLastMotionX = x;
564 mLastMotionY = y;
565 int manhattanTapDistance = (int) (absf(x - mDownX) +
566 absf(y - mDownY));
567 if (manhattanTapDistance > TAP_REGION_MANHATTAN_DISTANCE) {
568 mAlwaysInTapRegion = false;
569 }
570 }
571 break;
572
573 case MOTION_UP:
574 {
575 unsigned long long doubleTapDelta =
576 eventTime - mPreviousDownTime;
577 unsigned long long singleTapDelta =
578 eventTime - mDownTime;
579
580 if (mAlwaysInTapRegion) {
581 if (doubleTapDelta < DOUBLE_TAP_TIME_MS) {
582 mIsDoubleTap = true;
583 }
584 else if (singleTapDelta < TAP_TIME_MS) {
585 mIsTap = true;
586 }
587 }
588 }
589 break;
590 }
591 }
592
593 /**
594 * @return true if the current motion event is a scroll
595 * event.
596 */
isScroll()597 bool isScroll() {
598 return mIsScroll;
599 }
600
601 /**
602 * This value is only defined if {@link #isScroll} is true.
603 * @return the X position of the current scroll event.
604 * event.
605 */
scrollX()606 float scrollX() {
607 return mScrollX;
608 }
609
610 /**
611 * This value is only defined if {@link #isScroll} is true.
612 * @return the Y position of the current scroll event.
613 * event.
614 */
scrollY()615 float scrollY() {
616 return mScrollY;
617 }
618
619 /**
620 * @return true if the current motion event is a single-tap
621 * event.
622 */
isTap()623 bool isTap() {
624 return mIsTap;
625 }
626
627 /**
628 * This value is only defined if either {@link #isTap} or
629 * {@link #isDoubleTap} is true.
630 * @return the X position of the current tap event.
631 * event.
632 */
tapX()633 float tapX() {
634 return mDownX;
635 }
636
637 /**
638 * This value is only defined if either {@link #isTap} or
639 * {@link #isDoubleTap} is true.
640 * @return the Y position of the current tap event.
641 * event.
642 */
tapY()643 float tapY() {
644 return mDownY;
645 }
646
647 /**
648 * @return true if the current motion event is a double-tap
649 * event.
650 */
isDoubleTap()651 bool isDoubleTap() {
652 return mIsDoubleTap;
653 }
654
655 private:
absf(float a)656 inline float absf(float a) {
657 return a >= 0.0f ? a : -a;
658 }
659 };
660
661 GestureDetector gGestureDetector;
662
663 #if !defined(__clang__)
AndroidMotionEvent(unsigned long long eventTime,int action,float x,float y,float pressure,float size,int deviceId)664 int AndroidMotionEvent
665 #else
666 extern "C" int AndroidMotionEvent_LLVM
667 #endif
668 (unsigned long long eventTime, int action,
669 float x, float y, float pressure, float size, int deviceId)
670 {
671 gGestureDetector.analyze(eventTime, action, x, y, pressure, size, deviceId);
672
673 if (gGestureDetector.isTap()) {
674 mouse_tap = true;
675 }
676 else if (gGestureDetector.isScroll()) {
677 mx += (int) gGestureDetector.scrollX();
678 my += (int) gGestureDetector.scrollY();
679 }
680
681 return true;
682 }
683
684 #if !defined(__clang__)
AndroidTrackballEvent(unsigned long long eventTime,int action,float x,float y)685 int AndroidTrackballEvent
686 #else
687 extern "C" int AndroidTrackballEvent_LLVM
688 #endif
689 (unsigned long long eventTime, int action,
690 float x, float y)
691 {
692 switch (action ) {
693 case MOTION_DOWN:
694 mouse_buttonstate = true;
695 break;
696 case MOTION_UP:
697 mouse_buttonstate = false;
698 break;
699 case MOTION_MOVE:
700 mx += (int) (20.0f * x);
701 my += (int) (20.0f * y);
702 break;
703 }
704
705 return true;
706 }
707
Sys_SendKeyEvents(void)708 void Sys_SendKeyEvents(void)
709 {
710 // Used to poll keyboards on systems that need to poll keyboards.
711 }
712
Force_CenterView_f(void)713 void Force_CenterView_f (void)
714 {
715 cl.viewangles[PITCH] = 0;
716 }
717
IN_Init(void)718 void IN_Init(void)
719 {
720 Cvar_RegisterVariable (&mouse_button_commands[0]);
721 Cvar_RegisterVariable (&mouse_button_commands[1]);
722 Cvar_RegisterVariable (&mouse_button_commands[2]);
723 Cmd_AddCommand ("force_centerview", Force_CenterView_f);
724
725 }
726
IN_Shutdown(void)727 void IN_Shutdown(void)
728 {
729 }
730
731 /*
732 ===========
733 IN_Commands
734 ===========
735 */
IN_Commands(void)736 void IN_Commands (void)
737 {
738 // perform button actions
739 if (mouse_tap) {
740 Key_Event (K_MOUSE1, true);
741 Key_Event (K_MOUSE1, false);
742 mouse_tap = false;
743 }
744 if (mouse_buttonstate != mouse_oldbuttonstate) {
745 Key_Event (K_MOUSE1, mouse_buttonstate ? true : false);
746 mouse_oldbuttonstate = mouse_buttonstate;
747 }
748 }
749
750 /*
751 ===========
752 IN_Move
753 ===========
754 */
IN_MouseMove(usercmd_t * cmd)755 void IN_MouseMove (usercmd_t *cmd)
756 {
757 #if 0
758 if (m_filter.value)
759 {
760 mouse_x = (mx + old_mouse_x) * 0.5;
761 mouse_y = (my + old_mouse_y) * 0.5;
762 }
763 else
764 #endif
765 {
766 mouse_x = mx;
767 mouse_y = my;
768 }
769 old_mouse_x = mx;
770 old_mouse_y = my;
771 mx = my = 0; // clear for next update
772
773 mouse_x *= 5.0f * sensitivity.value;
774 mouse_y *= 5.0f * sensitivity.value;
775
776 // add mouse X/Y movement to cmd
777 if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
778 cmd->sidemove += m_side.value * mouse_x;
779 else
780 cl.viewangles[YAW] -= m_yaw.value * mouse_x;
781
782 if (in_mlook.state & 1)
783 V_StopPitchDrift ();
784
785 if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
786 {
787 cl.viewangles[PITCH] += m_pitch.value * mouse_y;
788 if (cl.viewangles[PITCH] > 80)
789 cl.viewangles[PITCH] = 80;
790 if (cl.viewangles[PITCH] < -70)
791 cl.viewangles[PITCH] = -70;
792 }
793 else
794 {
795 if ((in_strafe.state & 1) && noclip_anglehack)
796 cmd->upmove -= m_forward.value * mouse_y;
797 else
798 cmd->forwardmove -= m_forward.value * mouse_y;
799 }
800 }
801
IN_Move(usercmd_t * cmd)802 void IN_Move (usercmd_t *cmd)
803 {
804 IN_MouseMove(cmd);
805 }
806
807
808