home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quakeworld_src / client / gl_vidlinux.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-17  |  18.1 KB  |  817 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the 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, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. #include <termios.h>
  21. #include <sys/ioctl.h>
  22. #include <sys/stat.h>
  23. #include <sys/vt.h>
  24. #include <stdarg.h>
  25. #include <stdio.h>
  26. #include <signal.h>
  27.  
  28. #include <asm/io.h>
  29.  
  30. #include "vga.h"
  31. #include "vgakeyboard.h"
  32. #include "vgamouse.h"
  33.  
  34. #include "quakedef.h"
  35. #include "GL/fxmesa.h"
  36.  
  37. #define WARP_WIDTH              320
  38. #define WARP_HEIGHT             200
  39.  
  40. static fxMesaContext fc = NULL;
  41. #define stringify(m) { #m, m }
  42.  
  43. unsigned short  d_8to16table[256];
  44. unsigned  d_8to24table[256];
  45. unsigned char d_15to8table[65536];
  46.  
  47. int num_shades=32;
  48.  
  49. struct
  50. {
  51.   char *name;
  52.   int num;
  53. } mice[] =
  54. {
  55.   stringify(MOUSE_MICROSOFT),
  56.   stringify(MOUSE_MOUSESYSTEMS),
  57.   stringify(MOUSE_MMSERIES),
  58.   stringify(MOUSE_LOGITECH),
  59.   stringify(MOUSE_BUSMOUSE),
  60.   stringify(MOUSE_PS2),
  61. };
  62.  
  63. static unsigned char scantokey[128];
  64.  
  65. int num_mice = sizeof (mice) / sizeof(mice[0]);
  66.  
  67. int d_con_indirect = 0;
  68.  
  69. int   svgalib_inited=0;
  70. int   UseMouse = 1;
  71. int   UseKeyboard = 1;
  72.  
  73. int   mouserate = MOUSE_DEFAULTSAMPLERATE;
  74.  
  75. cvar_t  _windowed_mouse = {"_windowed_mouse","0", true};
  76.  
  77. cvar_t    vid_mode = {"vid_mode","5",false};
  78. cvar_t    vid_redrawfull = {"vid_redrawfull","0",false};
  79. cvar_t    vid_waitforrefresh = {"vid_waitforrefresh","0",true};
  80.  
  81. char  *framebuffer_ptr;
  82.  
  83. cvar_t  mouse_button_commands[3] =
  84. {
  85.     {"mouse1","+attack"},
  86.     {"mouse2","+strafe"},
  87.     {"mouse3","+forward"},
  88. };
  89.  
  90. int     mouse_buttons;
  91. int     mouse_buttonstate;
  92. int     mouse_oldbuttonstate;
  93. float   mouse_x, mouse_y;
  94. float old_mouse_x, old_mouse_y;
  95. int   mx, my;
  96.  
  97. cvar_t  m_filter = {"m_filter","1"};
  98.  
  99. int scr_width, scr_height;
  100.  
  101. /*-----------------------------------------------------------------------*/
  102.  
  103. //int   texture_mode = GL_NEAREST;
  104. //int   texture_mode = GL_NEAREST_MIPMAP_NEAREST;
  105. //int   texture_mode = GL_NEAREST_MIPMAP_LINEAR;
  106. int   texture_mode = GL_LINEAR;
  107. //int   texture_mode = GL_LINEAR_MIPMAP_NEAREST;
  108. //int   texture_mode = GL_LINEAR_MIPMAP_LINEAR;
  109.  
  110. int   texture_extension_number = 1;
  111.  
  112. float   gldepthmin, gldepthmax;
  113.  
  114. cvar_t  gl_ztrick = {"gl_ztrick","1"};
  115.  
  116. const char *gl_vendor;
  117. const char *gl_renderer;
  118. const char *gl_version;
  119. const char *gl_extensions;
  120.  
  121. qboolean is8bit = false;
  122. qboolean isPermedia = false;
  123. qboolean gl_mtexable = false;
  124.  
  125. /*-----------------------------------------------------------------------*/
  126. void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
  127. {
  128. }
  129.  
  130. void D_EndDirectRect (int x, int y, int width, int height)
  131. {
  132. }
  133.  
  134. int matchmouse(int mouse, char *name)
  135. {
  136.   int i;
  137.   for (i=0 ; i<num_mice ; i++)
  138.     if (!strcmp(mice[i].name, name))
  139.       return i;
  140.   return mouse;
  141. }
  142.  
  143. #if 0
  144.  
  145. void vtswitch(int newconsole)
  146. {
  147.  
  148.   int fd;
  149.   struct vt_stat x;
  150.  
  151. // switch consoles and wait until reactivated
  152.   fd = open("/dev/console", O_RDONLY);
  153.   ioctl(fd, VT_GETSTATE, &x);
  154.   ioctl(fd, VT_ACTIVATE, newconsole);
  155.   ioctl(fd, VT_WAITACTIVE, x.v_active);
  156.   close(fd);
  157.  
  158. }
  159.  
  160. #endif
  161.  
  162. void keyhandler(int scancode, int state)
  163. {
  164.   
  165.   int sc;
  166.  
  167.   sc = scancode & 0x7f;
  168.  
  169.   Key_Event(scantokey[sc], state == KEY_EVENTPRESS);
  170.  
  171. }
  172.  
  173. void VID_Shutdown(void)
  174. {
  175.   if (!fc)
  176.     return;
  177.  
  178.   fxMesaDestroyContext(fc);
  179.  
  180.   if (UseKeyboard)
  181.     keyboard_close();
  182. }
  183.  
  184. void signal_handler(int sig)
  185. {
  186.   printf("Received signal %d, exiting...\n", sig);
  187.   Sys_Quit();
  188.   exit(0);
  189. }
  190.  
  191. void InitSig(void)
  192. {
  193.   signal(SIGHUP, signal_handler);
  194.   signal(SIGINT, signal_handler);
  195.   signal(SIGQUIT, signal_handler);
  196.   signal(SIGILL, signal_handler);
  197.   signal(SIGTRAP, signal_handler);
  198.   signal(SIGIOT, signal_handler);
  199.   signal(SIGBUS, signal_handler);
  200.   signal(SIGFPE, signal_handler);
  201.   signal(SIGSEGV, signal_handler);
  202.   signal(SIGTERM, signal_handler);
  203. }
  204.  
  205. void VID_ShiftPalette(unsigned char *p)
  206. {
  207. //  VID_SetPalette(p);
  208. }
  209.  
  210. void  VID_SetPalette (unsigned char *palette)
  211. {
  212.   byte  *pal;
  213.   unsigned r,g,b;
  214.   unsigned v;
  215.   int     r1,g1,b1;
  216.   int   k;
  217.   unsigned short i;
  218.   unsigned  *table;
  219.   FILE *f;
  220.   char s[255];
  221.   float dist, bestdist;
  222.   static qboolean palflag = false;
  223.  
  224. //
  225. // 8 8 8 encoding
  226. //
  227.   Con_Printf("Converting 8to24\n");
  228.  
  229.   pal = palette;
  230.   table = d_8to24table;
  231.   for (i=0 ; i<256 ; i++)
  232.   {
  233.     r = pal[0];
  234.     g = pal[1];
  235.     b = pal[2];
  236.     pal += 3;
  237.     
  238. //    v = (255<<24) + (r<<16) + (g<<8) + (b<<0);
  239. //    v = (255<<0) + (r<<8) + (g<<16) + (b<<24);
  240.     v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
  241.     *table++ = v;
  242.   }
  243.   d_8to24table[255] &= 0xffffff;  // 255 is transparent
  244.  
  245.   // JACK: 3D distance calcs - k is last closest, l is the distance.
  246.   // FIXME: Precalculate this and cache to disk.
  247.   if (palflag)
  248.     return;
  249.   palflag = true;
  250.  
  251.   COM_FOpenFile("glquake/15to8.pal", &f);
  252.   if (f) {
  253.     fread(d_15to8table, 1<<15, 1, f);
  254.     fclose(f);
  255.   } else {
  256.     for (i=0; i < (1<<15); i++) {
  257.       /* Maps
  258.       000000000000000
  259.       000000000011111 = Red  = 0x1F
  260.       000001111100000 = Blue = 0x03E0
  261.       111110000000000 = Grn  = 0x7C00
  262.       */
  263.       r = ((i & 0x1F) << 3)+4;
  264.       g = ((i & 0x03E0) >> 2)+4;
  265.       b = ((i & 0x7C00) >> 7)+4;
  266.       pal = (unsigned char *)d_8to24table;
  267.       for (v=0,k=0,bestdist=10000.0; v<256; v++,pal+=4) {
  268.         r1 = (int)r - (int)pal[0];
  269.         g1 = (int)g - (int)pal[1];
  270.         b1 = (int)b - (int)pal[2];
  271.         dist = sqrt(((r1*r1)+(g1*g1)+(b1*b1)));
  272.         if (dist < bestdist) {
  273.           k=v;
  274.           bestdist = dist;
  275.         }
  276.       }
  277.       d_15to8table[i]=k;
  278.     }
  279.     sprintf(s, "%s/glquake", com_gamedir);
  280.     Sys_mkdir (s);
  281.     sprintf(s, "%s/glquake/15to8.pal", com_gamedir);
  282.     if ((f = fopen(s, "wb")) != NULL) {
  283.       fwrite(d_15to8table, 1<<15, 1, f);
  284.       fclose(f);
  285.     }
  286.   }
  287. }
  288.  
  289. /*
  290. ===============
  291. GL_Init
  292. ===============
  293. */
  294. void GL_Init (void)
  295. {
  296.   gl_vendor = glGetString (GL_VENDOR);
  297.   Con_Printf ("GL_VENDOR: %s\n", gl_vendor);
  298.   gl_renderer = glGetString (GL_RENDERER);
  299.   Con_Printf ("GL_RENDERER: %s\n", gl_renderer);
  300.  
  301.   gl_version = glGetString (GL_VERSION);
  302.   Con_Printf ("GL_VERSION: %s\n", gl_version);
  303.   gl_extensions = glGetString (GL_EXTENSIONS);
  304.   Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions);
  305.  
  306. //  Con_Printf ("%s %s\n", gl_renderer, gl_version);
  307.  
  308.   glClearColor (1,0,0,0);
  309.   glCullFace(GL_FRONT);
  310.   glEnable(GL_TEXTURE_2D);
  311.  
  312.   glEnable(GL_ALPHA_TEST);
  313.   glAlphaFunc(GL_GREATER, 0.666);
  314.  
  315.   glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  316.   glShadeModel (GL_FLAT);
  317.  
  318.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  319.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  320.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  321.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  322.  
  323.   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  324.  
  325. //  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  326.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  327. }
  328.  
  329. /*
  330. =================
  331. GL_BeginRendering
  332.  
  333. =================
  334. */
  335. void GL_BeginRendering (int *x, int *y, int *width, int *height)
  336. {
  337.   extern cvar_t gl_clear;
  338.  
  339.   *x = *y = 0;
  340.   *width = scr_width;
  341.   *height = scr_height;
  342.  
  343. //    if (!wglMakeCurrent( maindc, baseRC ))
  344. //    Sys_Error ("wglMakeCurrent failed");
  345.  
  346. //  glViewport (*x, *y, *width, *height);
  347. }
  348.  
  349.  
  350. void GL_EndRendering (void)
  351. {
  352.   glFlush();
  353.   fxMesaSwapBuffers();
  354. }
  355.  
  356. void Init_KBD(void)
  357. {
  358.   int i;
  359.  
  360.   if (COM_CheckParm("-nokbd")) UseKeyboard = 0;
  361.  
  362.   if (UseKeyboard)
  363.   {
  364.     for (i=0 ; i<128 ; i++)
  365.       scantokey[i] = ' ';
  366.  
  367.     scantokey[42] = K_SHIFT;
  368.     scantokey[54] = K_SHIFT;
  369.     scantokey[72] = K_UPARROW;
  370.     scantokey[103] = K_UPARROW;
  371.     scantokey[80] = K_DOWNARROW;
  372.     scantokey[108] = K_DOWNARROW;
  373.     scantokey[75] = K_LEFTARROW;
  374.     scantokey[105] = K_LEFTARROW;
  375.     scantokey[77] = K_RIGHTARROW;
  376.     scantokey[106] = K_RIGHTARROW;
  377.     scantokey[29] = K_CTRL;
  378.     scantokey[97] = K_CTRL;
  379.     scantokey[56] = K_ALT;
  380.     scantokey[100] = K_ALT;
  381. //    scantokey[58] = JK_CAPS;
  382. //    scantokey[69] = JK_NUM_LOCK;
  383.     scantokey[71] = K_HOME;
  384.     scantokey[73] = K_PGUP;
  385.     scantokey[79] = K_END;
  386.     scantokey[81] = K_PGDN;
  387.     scantokey[82] = K_INS;
  388.     scantokey[83] = K_DEL;
  389.     scantokey[1 ] = K_ESCAPE;
  390.     scantokey[28] = K_ENTER;
  391.     scantokey[15] = K_TAB;
  392.     scantokey[14] = K_BACKSPACE;
  393.     scantokey[119] = K_PAUSE;
  394.     scantokey[57] = ' ';
  395.  
  396.     scantokey[102] = K_HOME;
  397.     scantokey[104] = K_PGUP;
  398.     scantokey[107] = K_END;
  399.     scantokey[109] = K_PGDN;
  400.     scantokey[110] = K_INS;
  401.     scantokey[111] = K_DEL;
  402.  
  403.     scantokey[2] = '1';
  404.     scantokey[3] = '2';
  405.     scantokey[4] = '3';
  406.     scantokey[5] = '4';
  407.     scantokey[6] = '5';
  408.     scantokey[7] = '6';
  409.     scantokey[8] = '7';
  410.     scantokey[9] = '8';
  411.     scantokey[10] = '9';
  412.     scantokey[11] = '0';
  413.     scantokey[12] = '-';
  414.     scantokey[13] = '=';
  415.     scantokey[41] = '`';
  416.     scantokey[26] = '[';
  417.     scantokey[27] = ']';
  418.     scantokey[39] = ';';
  419.     scantokey[40] = '\'';
  420.     scantokey[51] = ',';
  421.     scantokey[52] = '.';
  422.     scantokey[53] = '/';
  423.     scantokey[43] = '\\';
  424.  
  425.     scantokey[59] = K_F1;
  426.     scantokey[60] = K_F2;
  427.     scantokey[61] = K_F3;
  428.     scantokey[62] = K_F4;
  429.     scantokey[63] = K_F5;
  430.     scantokey[64] = K_F6;
  431.     scantokey[65] = K_F7;
  432.     scantokey[66] = K_F8;
  433.     scantokey[67] = K_F9;
  434.     scantokey[68] = K_F10;
  435.     scantokey[87] = K_F11;
  436.     scantokey[88] = K_F12;
  437.     scantokey[30] = 'a';
  438.     scantokey[48] = 'b';
  439.     scantokey[46] = 'c';
  440.     scantokey[32] = 'd';       
  441.     scantokey[18] = 'e';       
  442.     scantokey[33] = 'f';       
  443.     scantokey[34] = 'g';       
  444.     scantokey[35] = 'h';       
  445.     scantokey[23] = 'i';       
  446.     scantokey[36] = 'j';       
  447.     scantokey[37] = 'k';       
  448.     scantokey[38] = 'l';       
  449.     scantokey[50] = 'm';       
  450.     scantokey[49] = 'n';       
  451.     scantokey[24] = 'o';       
  452.     scantokey[25] = 'p';       
  453.     scantokey[16] = 'q';       
  454.     scantokey[19] = 'r';       
  455.     scantokey[31] = 's';       
  456.     scantokey[20] = 't';       
  457.     scantokey[22] = 'u';       
  458.     scantokey[47] = 'v';       
  459.     scantokey[17] = 'w';       
  460.     scantokey[45] = 'x';       
  461.     scantokey[21] = 'y';       
  462.     scantokey[44] = 'z';       
  463.  
  464.     scantokey[78] = '+';
  465.     scantokey[74] = '-';
  466.  
  467.     if (keyboard_init())
  468.       Sys_Error("keyboard_init() failed");
  469.     keyboard_seteventhandler(keyhandler);
  470.   }
  471. }
  472.  
  473. #define NUM_RESOLUTIONS 3
  474.  
  475. static resolutions[NUM_RESOLUTIONS][3]={ 
  476.   { 512, 384, GR_RESOLUTION_512x384 },
  477.   { 640, 400, GR_RESOLUTION_640x400 },
  478.   { 640, 480, GR_RESOLUTION_640x480 }
  479. };
  480.  
  481. int findres(int *width, int *height)
  482. {
  483.   int i;
  484.  
  485.   for(i=0;i<NUM_RESOLUTIONS;i++)
  486.     if((*width<=resolutions[i][0]) && (*height<=resolutions[i][1])) {
  487.       *width = resolutions[i][0];
  488.       *height = resolutions[i][1];
  489.       return resolutions[i][2];
  490.     }
  491.         
  492.   *width = 640;
  493.   *height = 480;
  494.   return GR_RESOLUTION_640x480;
  495. }
  496.  
  497. qboolean VID_Is8bit(void)
  498. {
  499.   return is8bit;
  500. }
  501.  
  502. #ifdef GL_EXT_SHARED
  503. void VID_Init8bitPalette() 
  504. {
  505.   // Check for 8bit Extensions and initialize them.
  506.   int i;
  507.   char thePalette[256*3];
  508.   char *oldPalette, *newPalette;
  509.  
  510.   if (strstr(gl_extensions, "GL_EXT_shared_texture_palette") == NULL)
  511.     return;
  512.  
  513.   Con_SafePrintf("8-bit GL extensions enabled.\n");
  514.   glEnable( GL_SHARED_TEXTURE_PALETTE_EXT );
  515.   oldPalette = (char *) d_8to24table; //d_8to24table3dfx;
  516.   newPalette = thePalette;
  517.   for (i=0;i<256;i++) {
  518.     *newPalette++ = *oldPalette++;
  519.     *newPalette++ = *oldPalette++;
  520.     *newPalette++ = *oldPalette++;
  521.     oldPalette++;
  522.   }
  523.   glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, (void *) thePalette);
  524.   is8bit = true;
  525. }
  526.  
  527. #else
  528. extern void gl3DfxSetPaletteEXT(GLuint *pal);
  529.  
  530. void VID_Init8bitPalette(void) 
  531. {
  532.   // Check for 8bit Extensions and initialize them.
  533.   int i;
  534.   GLubyte table[256][4];
  535.   char *oldpal;
  536.  
  537.   if (strstr(gl_extensions, "3DFX_set_global_palette") == NULL)
  538.     return;
  539.  
  540.   Con_SafePrintf("8-bit GL extensions enabled.\n");
  541.   glEnable( GL_SHARED_TEXTURE_PALETTE_EXT );
  542.   oldpal = (char *) d_8to24table; //d_8to24table3dfx;
  543.   for (i=0;i<256;i++) {
  544.     table[i][2] = *oldpal++;
  545.     table[i][1] = *oldpal++;
  546.     table[i][0] = *oldpal++;
  547.     table[i][3] = 255;
  548.     oldpal++;
  549.   }
  550.   gl3DfxSetPaletteEXT((GLuint *)table);
  551.   is8bit = true;
  552. }
  553. #endif
  554.  
  555. void VID_Init(unsigned char *palette)
  556. {
  557.   int i;
  558.   GLint attribs[32];
  559.   char  gldir[MAX_OSPATH];
  560.   int width = 640, height = 480;
  561.  
  562.   S_Init();
  563.  
  564.   Init_KBD();
  565.  
  566.   Cvar_RegisterVariable (&vid_mode);
  567.   Cvar_RegisterVariable (&vid_redrawfull);
  568.   Cvar_RegisterVariable (&vid_waitforrefresh);
  569.   Cvar_RegisterVariable (&gl_ztrick);
  570.   
  571.         vid.maxwarpwidth = WARP_WIDTH;
  572.         vid.maxwarpheight = WARP_HEIGHT;
  573.         vid.colormap = host_colormap;
  574.         vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
  575.  
  576. // interpret command-line params
  577.  
  578. // set vid parameters
  579.   attribs[0] = FXMESA_DOUBLEBUFFER;
  580.   attribs[1] = FXMESA_ALPHA_SIZE;
  581.   attribs[2] = 1;
  582.   attribs[3] = FXMESA_DEPTH_SIZE;
  583.   attribs[4] = 1;
  584.   attribs[5] = FXMESA_NONE;
  585.  
  586.   if ((i = COM_CheckParm("-width")) != 0)
  587.     width = atoi(com_argv[i+1]);
  588.   if ((i = COM_CheckParm("-height")) != 0)
  589.     height = atoi(com_argv[i+1]);
  590.  
  591.   if ((i = COM_CheckParm("-conwidth")) != 0)
  592.     vid.conwidth = Q_atoi(com_argv[i+1]);
  593.   else
  594.     vid.conwidth = 640;
  595.  
  596.   vid.conwidth &= 0xfff8; // make it a multiple of eight
  597.  
  598.   if (vid.conwidth < 320)
  599.     vid.conwidth = 320;
  600.  
  601.   // pick a conheight that matches with correct aspect
  602.   vid.conheight = vid.conwidth*3 / 4;
  603.  
  604.   if ((i = COM_CheckParm("-conheight")) != 0)
  605.     vid.conheight = Q_atoi(com_argv[i+1]);
  606.   if (vid.conheight < 200)
  607.     vid.conheight = 200;
  608.  
  609.   fc = fxMesaCreateContext(0, findres(&width, &height), GR_REFRESH_75Hz, 
  610.     attribs);
  611.   if (!fc)
  612.     Sys_Error("Unable to create 3DFX context.\n");
  613.  
  614.   scr_width = width;
  615.   scr_height = height;
  616.  
  617.   fxMesaMakeCurrent(fc);
  618.  
  619.   if (vid.conheight > height)
  620.     vid.conheight = height;
  621.   if (vid.conwidth > width)
  622.     vid.conwidth = width;
  623.   vid.width = vid.conwidth;
  624.   vid.height = vid.conheight;
  625.  
  626.   vid.aspect = ((float)vid.height / (float)vid.width) *
  627.         (320.0 / 240.0);
  628.   vid.numpages = 2;
  629.  
  630.   InitSig(); // trap evil signals
  631.  
  632.   GL_Init();
  633.  
  634.   sprintf (gldir, "%s/glquake", com_gamedir);
  635.   Sys_mkdir (gldir);
  636.  
  637.   VID_SetPalette(palette);
  638.  
  639.   // Check for 3DFX Extensions and initialize them.
  640.   VID_Init8bitPalette();
  641.  
  642.   Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height);
  643.  
  644.   vid.recalc_refdef = 1;        // force a surface cache flush
  645. }
  646.  
  647. void Sys_SendKeyEvents(void)
  648. {
  649.   if (UseKeyboard)
  650.     while (keyboard_update());
  651. }
  652.  
  653. void Force_CenterView_f (void)
  654. {
  655.   cl.viewangles[PITCH] = 0;
  656. }
  657.  
  658.  
  659. void mousehandler(int buttonstate, int dx, int dy)
  660. {
  661.   mouse_buttonstate = buttonstate;
  662.   mx += dx;
  663.   my += dy;
  664. }
  665.  
  666. void IN_Init(void)
  667. {
  668.  
  669.   int mtype;
  670.   char *mousedev;
  671.   int mouserate;
  672.  
  673.   if (UseMouse)
  674.   {
  675.  
  676.     Cvar_RegisterVariable (&mouse_button_commands[0]);
  677.     Cvar_RegisterVariable (&mouse_button_commands[1]);
  678.     Cvar_RegisterVariable (&mouse_button_commands[2]);
  679.     Cmd_AddCommand ("force_centerview", Force_CenterView_f);
  680.  
  681.     mouse_buttons = 3;
  682.  
  683.     mtype = vga_getmousetype();
  684.  
  685.     mousedev = "/dev/mouse";
  686.     if (getenv("MOUSEDEV")) mousedev = getenv("MOUSEDEV");
  687.     if (COM_CheckParm("-mdev"))
  688.       mousedev = com_argv[COM_CheckParm("-mdev")+1];
  689.  
  690.     mouserate = 1200;
  691.     if (getenv("MOUSERATE")) mouserate = atoi(getenv("MOUSERATE"));
  692.     if (COM_CheckParm("-mrate"))
  693.       mouserate = atoi(com_argv[COM_CheckParm("-mrate")+1]);
  694.  
  695.     if (mouse_init(mousedev, mtype, mouserate))
  696.     {
  697.       Con_Printf("No mouse found\n");
  698.       UseMouse = 0;
  699.     }
  700.     else
  701.       mouse_seteventhandler(mousehandler);
  702.  
  703.   }
  704.  
  705. }
  706.  
  707. void IN_Shutdown(void)
  708. {
  709.   if (UseMouse)
  710.     mouse_close();
  711. }
  712.  
  713. /*
  714. ===========
  715. IN_Commands
  716. ===========
  717. */
  718. void IN_Commands (void)
  719. {
  720.   if (UseMouse)
  721.   {
  722.     // poll mouse values
  723.     while (mouse_update())
  724.       ;
  725.  
  726.     // perform button actions
  727.     if ((mouse_buttonstate & MOUSE_LEFTBUTTON) &&
  728.       !(mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
  729.       Key_Event (K_MOUSE1, true);
  730.     else if (!(mouse_buttonstate & MOUSE_LEFTBUTTON) &&
  731.       (mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
  732.       Key_Event (K_MOUSE1, false);
  733.  
  734.     if ((mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
  735.       !(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
  736.       Key_Event (K_MOUSE2, true);
  737.     else if (!(mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
  738.       (mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
  739.       Key_Event (K_MOUSE2, false);
  740.  
  741.     if ((mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
  742.       !(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
  743.       Key_Event (K_MOUSE3, true);
  744.     else if (!(mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
  745.       (mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
  746.       Key_Event (K_MOUSE3, false);
  747.  
  748.     mouse_oldbuttonstate = mouse_buttonstate;
  749.   }
  750. }
  751.  
  752. /*
  753. ===========
  754. IN_Move
  755. ===========
  756. */
  757. void IN_MouseMove (usercmd_t *cmd)
  758. {
  759.   if (!UseMouse)
  760.     return;
  761.  
  762.   // poll mouse values
  763.   while (mouse_update())
  764.     ;
  765.  
  766.   if (m_filter.value)
  767.   {
  768.     mouse_x = (mx + old_mouse_x) * 0.5;
  769.     mouse_y = (my + old_mouse_y) * 0.5;
  770.   }
  771.   else
  772.   {
  773.     mouse_x = mx;
  774.     mouse_y = my;
  775.   }
  776.   old_mouse_x = mx;
  777.   old_mouse_y = my;
  778.   mx = my = 0; // clear for next update
  779.  
  780.   mouse_x *= sensitivity.value;
  781.   mouse_y *= sensitivity.value;
  782.  
  783. // add mouse X/Y movement to cmd
  784.   if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
  785.     cmd->sidemove += m_side.value * mouse_x;
  786.   else
  787.     cl.viewangles[YAW] -= m_yaw.value * mouse_x;
  788.   
  789.   if (in_mlook.state & 1)
  790.     V_StopPitchDrift ();
  791.     
  792.   if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
  793.   {
  794.     cl.viewangles[PITCH] += m_pitch.value * mouse_y;
  795.     if (cl.viewangles[PITCH] > 80)
  796.       cl.viewangles[PITCH] = 80;
  797.     if (cl.viewangles[PITCH] < -70)
  798.       cl.viewangles[PITCH] = -70;
  799.   }
  800.   else
  801.   {
  802.     if ((in_strafe.state & 1) && noclip_anglehack)
  803.       cmd->upmove -= m_forward.value * mouse_y;
  804.     else
  805.       cmd->forwardmove -= m_forward.value * mouse_y;
  806.   }
  807. }
  808.  
  809. void IN_Move (usercmd_t *cmd)
  810. {
  811.   IN_MouseMove(cmd);
  812. }
  813.  
  814. void VID_UnlockBuffer() {}
  815. void VID_LockBuffer() {}
  816.  
  817.