home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quakeworld_src / client / vid_svgalib.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-17  |  22.4 KB  |  1,026 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 "d_local.h"
  36.  
  37. #define stringify(m) { #m, m }
  38.  
  39. unsigned short       d_8to16table[256];
  40. static byte   *vid_surfcache;
  41. static int    VID_highhunkmark;
  42.  
  43. int num_modes;
  44. vga_modeinfo *modes;
  45. int current_mode;
  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. static byte vid_current_palette[768];
  65.  
  66. int num_mice = sizeof (mice) / sizeof(mice[0]);
  67.  
  68. int d_con_indirect = 0;
  69.  
  70. int   svgalib_inited=0;
  71. int   UseMouse = 1;
  72. int   UseDisplay = 1;
  73. int   UseKeyboard = 1;
  74.  
  75. int   mouserate = MOUSE_DEFAULTSAMPLERATE;
  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 _windowed_mouse = {"_windowed_mouse", "1", true};
  98. cvar_t  m_filter = {"m_filter","0"};
  99.  
  100. static byte     backingbuf[48*24];
  101.  
  102. int   VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes, VGA_planar;
  103. byte  *VGA_pagebase;
  104.  
  105. void VGA_UpdatePlanarScreen (void *srcbuffer);
  106.  
  107. void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
  108. {
  109.   int i, j, k, plane, reps, repshift, offset, vidpage, off;
  110.  
  111.   if (!svgalib_inited || !vid.direct || !vga_oktowrite()) return;
  112.  
  113.   if (vid.aspect > 1.5)
  114.   {
  115.     reps = 2;
  116.     repshift = 1;
  117.   } else {
  118.     reps = 1;
  119.     repshift = 0;
  120.   }
  121.  
  122.   vidpage = 0;
  123.   vga_setpage(0);
  124.  
  125.   if (VGA_planar)
  126.   {
  127.     for (plane=0 ; plane<4 ; plane++)
  128.     {
  129.     // select the correct plane for reading and writing
  130.       outb(0x02, 0x3C4);
  131.       outb(1 << plane, 0x3C5);
  132.       outb(4, 0x3CE);
  133.       outb(plane, 0x3CF);
  134.  
  135.       for (i=0 ; i<(height << repshift) ; i += reps)
  136.       {
  137.         for (k=0 ; k<reps ; k++)
  138.         {
  139.           for (j=0 ; j<(width >> 2) ; j++)
  140.           {
  141.             backingbuf[(i + k) * 24 + (j << 2) + plane] =
  142.                 vid.direct[(y + i + k) * VGA_rowbytes +
  143.                 (x >> 2) + j];
  144.             vid.direct[(y + i + k) * VGA_rowbytes + (x>>2) + j] =
  145.                 pbitmap[(i >> repshift) * 24 +
  146.                 (j << 2) + plane];
  147.           }
  148.         }
  149.       }
  150.     }
  151.   } else {
  152.     for (i=0 ; i<(height << repshift) ; i += reps)
  153.     {
  154.       for (j=0 ; j<reps ; j++)
  155.       {
  156.         offset = x + ((y << repshift) + i + j) * vid.rowbytes;
  157.         off = offset % 0x10000;
  158.         if ((offset / 0x10000) != vidpage) {
  159.           vidpage=offset / 0x10000;
  160.           vga_setpage(vidpage);
  161.         }
  162.         memcpy (&backingbuf[(i + j) * 24],
  163.             vid.direct + off, width);
  164.         memcpy (vid.direct + off,
  165.             &pbitmap[(i >> repshift)*width], width);
  166.       }
  167.     }
  168.   }
  169. }
  170.  
  171. void D_EndDirectRect (int x, int y, int width, int height)
  172. {
  173.   int i, j, k, plane, reps, repshift, offset, vidpage, off;
  174.  
  175.   if (!svgalib_inited || !vid.direct || !vga_oktowrite()) return;
  176.  
  177.   if (vid.aspect > 1.5)
  178.   {
  179.     reps = 2;
  180.     repshift = 1;
  181.   } else {
  182.     reps = 1;
  183.     repshift = 0;
  184.   }
  185.  
  186.   vidpage = 0;
  187.   vga_setpage(0);
  188.  
  189.   if (VGA_planar)
  190.   {
  191.     for (plane=0 ; plane<4 ; plane++)
  192.     {
  193.     // select the correct plane for writing
  194.       outb(2, 0x3C4);
  195.       outb(1 << plane, 0x3C5);
  196.       outb(4, 0x3CE);
  197.       outb(plane, 0x3CF);
  198.  
  199.       for (i=0 ; i<(height << repshift) ; i += reps)
  200.       {
  201.         for (k=0 ; k<reps ; k++)
  202.         {
  203.           for (j=0 ; j<(width >> 2) ; j++)
  204.           {
  205.             vid.direct[(y + i + k) * VGA_rowbytes + (x>>2) + j] =
  206.                 backingbuf[(i + k) * 24 + (j << 2) + plane];
  207.           }
  208.         }
  209.       }
  210.     }
  211.   } else {
  212.     for (i=0 ; i<(height << repshift) ; i += reps)
  213.     {
  214.       for (j=0 ; j<reps ; j++)
  215.       {
  216.         offset = x + ((y << repshift) + i + j) * vid.rowbytes;
  217.         off = offset % 0x10000;
  218.         if ((offset / 0x10000) != vidpage) {
  219.           vidpage=offset / 0x10000;
  220.           vga_setpage(vidpage);
  221.         }
  222.         memcpy (vid.direct + off, 
  223.             &backingbuf[(i +j)*24],
  224.             width);
  225.       }
  226.     }
  227.   }
  228. }
  229.  
  230. /*
  231. =================
  232. VID_Gamma_f
  233.  
  234. Keybinding command
  235. =================
  236. */
  237. void VID_Gamma_f (void)
  238. {
  239.   float gamma, f, inf;
  240.   unsigned char palette[768];
  241.   int   i;
  242.  
  243.   if (Cmd_Argc () == 2)
  244.   {
  245.     gamma = Q_atof (Cmd_Argv(1));
  246.  
  247.     for (i=0 ; i<768 ; i++)
  248.     {
  249.       f = pow ( (host_basepal[i]+1)/256.0 , gamma );
  250.       inf = f*255 + 0.5;
  251.       if (inf < 0)
  252.         inf = 0;
  253.       if (inf > 255)
  254.         inf = 255;
  255.       palette[i] = inf;
  256.     }
  257.  
  258.     VID_SetPalette (palette);
  259.  
  260.     vid.recalc_refdef = 1;        // force a surface cache flush
  261.   }
  262. }
  263.  
  264. void VID_DescribeMode_f (void)
  265. {
  266.   int modenum;
  267.   
  268.   modenum = Q_atoi (Cmd_Argv(1));
  269.   if ((modenum >= num_modes) || (modenum < 0 ) || !modes[modenum].width)
  270.     Con_Printf("Invalid video mode: %d!\n",modenum);
  271.   Con_Printf("%d: %d x %d - ",modenum,modes[modenum].width,modes[modenum].height);
  272.   if (modes[modenum].bytesperpixel == 0)
  273.     Con_Printf("ModeX\n");
  274.   else
  275.     Con_Printf("%d bpp\n", modes[modenum].bytesperpixel<<3);
  276. }
  277.  
  278. void VID_DescribeModes_f (void)
  279. {
  280.   int i;
  281.   
  282.   for (i=0;i<num_modes;i++)
  283.     if (modes[i].width) {
  284.       Con_Printf("%d: %d x %d - ", i, modes[i].width,modes[i].height);
  285.       if (modes[i].bytesperpixel == 0)
  286.         Con_Printf("ModeX\n");
  287.       else
  288.         Con_Printf("%d bpp\n", modes[i].bytesperpixel<<3);
  289.     }
  290. }
  291.  
  292. /*
  293. ================
  294. VID_NumModes
  295. ================
  296. */
  297. int VID_NumModes ()
  298. {
  299.   int i,i1=0;
  300.   
  301.   for (i=0;i<num_modes;i++)
  302.     i1+=(modes[i].width?1:0);
  303.   return (i1);
  304. }
  305.  
  306. void VID_NumModes_f (void)
  307. {
  308.   Con_Printf("%d modes\n",VID_NumModes());
  309. }
  310.  
  311. void VID_Debug_f (void)
  312. {
  313.   Con_Printf("mode: %d\n",current_mode);
  314.   Con_Printf("height x width: %d x %d\n",vid.height,vid.width);
  315.   Con_Printf("bpp: %d\n",modes[current_mode].bytesperpixel*8);
  316.   Con_Printf("vid.aspect: %f\n",vid.aspect);
  317. }
  318.  
  319.  
  320.  
  321. void VID_InitModes(void)
  322. {
  323.  
  324.   int i;
  325.  
  326. // get complete information on all modes
  327.  
  328.   num_modes = vga_lastmodenumber()+1;
  329.   modes = Z_Malloc(num_modes * sizeof(vga_modeinfo));
  330.   for (i=0 ; i<num_modes ; i++)
  331.   {
  332.     if (vga_hasmode(i))
  333.       Q_memcpy(&modes[i], vga_getmodeinfo(i), sizeof (vga_modeinfo));
  334.     else
  335.       modes[i].width = 0; // means not available
  336.   }
  337.  
  338. // filter for modes i don't support
  339.  
  340.   for (i=0 ; i<num_modes ; i++)
  341.   {
  342.     if (modes[i].bytesperpixel != 1 && modes[i].colors != 256) 
  343.       modes[i].width = 0;
  344.   }
  345.  
  346. }
  347.  
  348. int get_mode(char *name, int width, int height, int depth)
  349. {
  350.  
  351.   int i;
  352.   int ok, match;
  353.  
  354.   match = (!!width) + (!!height)*2 + (!!depth)*4;
  355.  
  356.   if (name)
  357.   {
  358.     i = vga_getmodenumber(name);
  359.     if (!modes[i].width)
  360.     {
  361.       Sys_Printf("Mode [%s] not supported\n", name);
  362.       i = G320x200x256;
  363.     }
  364.   }
  365.   else
  366.   {
  367.     for (i=0 ; i<num_modes ; i++)
  368.       if (modes[i].width)
  369.       {
  370.         ok = (modes[i].width == width)
  371.           + (modes[i].height == height)*2
  372.           + (modes[i].bytesperpixel == depth/8)*4;
  373.         if ((ok & match) == ok)
  374.           break;
  375.       }
  376.     if (i==num_modes)
  377.     {
  378.       Sys_Printf("Mode %dx%d (%d bits) not supported\n",
  379.         width, height, depth);
  380.       i = G320x200x256;
  381.     }
  382.   }
  383.  
  384.   return i;
  385.  
  386. }
  387.  
  388. int matchmouse(int mouse, char *name)
  389. {
  390.   int i;
  391.   for (i=0 ; i<num_mice ; i++)
  392.     if (!strcmp(mice[i].name, name))
  393.       return i;
  394.   return mouse;
  395. }
  396.  
  397. #if 0
  398.  
  399. void vtswitch(int newconsole)
  400. {
  401.  
  402.   int fd;
  403.   struct vt_stat x;
  404.  
  405. // switch consoles and wait until reactivated
  406.   fd = open("/dev/console", O_RDONLY);
  407.   ioctl(fd, VT_GETSTATE, &x);
  408.   ioctl(fd, VT_ACTIVATE, newconsole);
  409.   ioctl(fd, VT_WAITACTIVE, x.v_active);
  410.   close(fd);
  411.  
  412. }
  413.  
  414. #endif
  415.  
  416. void keyhandler(int scancode, int state)
  417. {
  418.   
  419.   int sc;
  420.  
  421.   sc = scancode & 0x7f;
  422. //  Con_Printf("scancode=%x (%d%s)\n", scancode, sc, scancode&0x80?"+128":"");
  423.   Key_Event(scantokey[sc], state == KEY_EVENTPRESS);
  424.  
  425. }
  426.  
  427. void VID_Shutdown(void)
  428. {
  429.  
  430.   if (!svgalib_inited) return;
  431.  
  432. //  printf("shutdown graphics called\n");
  433.   if (UseKeyboard)
  434.     keyboard_close();
  435.   if (UseDisplay)
  436.     vga_setmode(TEXT);
  437. //  printf("shutdown graphics finished\n");
  438.  
  439.   svgalib_inited = 0;
  440.  
  441. }
  442.  
  443. void VID_ShiftPalette(unsigned char *p)
  444. {
  445.   VID_SetPalette(p);
  446. }
  447.  
  448. void VID_SetPalette(byte *palette)
  449. {
  450.  
  451.   static int tmppal[256*3];
  452.   int *tp;
  453.   int i;
  454.  
  455.   if (!svgalib_inited)
  456.     return;
  457.  
  458.   memcpy(vid_current_palette, palette, sizeof(vid_current_palette));
  459.  
  460.   if (vga_getcolors() == 256)
  461.   {
  462.  
  463.     tp = tmppal;
  464.     for (i=256*3 ; i ; i--)
  465.       *(tp++) = *(palette++) >> 2;
  466.  
  467.     if (UseDisplay && vga_oktowrite())
  468.       vga_setpalvec(0, 256, tmppal);
  469.  
  470.   }
  471. }
  472.  
  473. int VID_SetMode (int modenum, unsigned char *palette)
  474. {
  475.   int bsize, zsize, tsize;
  476.  
  477.   if ((modenum >= num_modes) || (modenum < 0) || !modes[modenum].width)
  478.   {
  479.     Cvar_SetValue ("vid_mode", (float)current_mode);
  480.     
  481.     Con_Printf("No such video mode: %d\n",modenum);
  482.     
  483.     return 0;
  484.   }
  485.  
  486.   Cvar_SetValue ("vid_mode", (float)modenum);
  487.   
  488.   current_mode=modenum;
  489.  
  490.   vid.width = modes[current_mode].width;
  491.   vid.height = modes[current_mode].height;
  492.  
  493.   VGA_width = modes[current_mode].width;
  494.   VGA_height = modes[current_mode].height;
  495.   VGA_planar = modes[current_mode].bytesperpixel == 0;
  496.   VGA_rowbytes = modes[current_mode].linewidth;
  497.   vid.rowbytes = modes[current_mode].linewidth;
  498.   if (VGA_planar) {
  499.     VGA_bufferrowbytes = modes[current_mode].linewidth * 4;
  500.     vid.rowbytes = modes[current_mode].linewidth*4;
  501.   }
  502.  
  503.   vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
  504.   vid.colormap = (pixel_t *) host_colormap;
  505.   vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
  506.   vid.conrowbytes = vid.rowbytes;
  507.   vid.conwidth = vid.width;
  508.   vid.conheight = vid.height;
  509.   vid.numpages = 1;
  510.   
  511.   vid.maxwarpwidth = WARP_WIDTH;
  512.   vid.maxwarpheight = WARP_HEIGHT;
  513.  
  514.   // alloc zbuffer and surface cache
  515.   if (d_pzbuffer) {
  516.     D_FlushCaches();
  517.     Hunk_FreeToHighMark (VID_highhunkmark);
  518.     d_pzbuffer = NULL;
  519.     vid_surfcache = NULL;
  520.   }
  521.  
  522.   bsize = vid.rowbytes * vid.height;
  523.   tsize = D_SurfaceCacheForRes (vid.width, vid.height);
  524.   zsize = vid.width * vid.height * sizeof(*d_pzbuffer);
  525.  
  526.   VID_highhunkmark = Hunk_HighMark ();
  527.  
  528.   d_pzbuffer = Hunk_HighAllocName (bsize+tsize+zsize, "video");
  529.  
  530.   vid_surfcache = ((byte *)d_pzbuffer) + zsize;
  531.  
  532.   vid.conbuffer = vid.buffer = (pixel_t *)(((byte *)d_pzbuffer) + zsize + tsize);
  533.  
  534.   D_InitCaches (vid_surfcache, tsize);
  535.  
  536. // get goin'
  537.  
  538.   vga_setmode(current_mode);
  539.   VID_SetPalette(palette);
  540.  
  541.   VGA_pagebase = vid.direct = framebuffer_ptr = (char *) vga_getgraphmem();
  542. //    if (vga_setlinearaddressing()>0)
  543. //      framebuffer_ptr = (char *) vga_getgraphmem();
  544.   if (!framebuffer_ptr)
  545.     Sys_Error("This mode isn't hapnin'\n");
  546.  
  547.   vga_setpage(0);
  548.  
  549.   svgalib_inited=1;
  550.  
  551.   vid.recalc_refdef = 1;        // force a surface cache flush
  552.  
  553.   return 0;
  554. }
  555.  
  556. void VID_Init(unsigned char *palette)
  557. {
  558.  
  559.   int i;
  560.   int w, h, d;
  561.  
  562.   S_Init(); // sound gets initialized here
  563.  
  564.   if (svgalib_inited)
  565.     return;
  566.  
  567. //  Cmd_AddCommand ("gamma", VID_Gamma_f);
  568.  
  569.   if (UseDisplay)
  570.   {
  571.     vga_init();
  572.  
  573.     VID_InitModes();
  574.  
  575.     Cvar_RegisterVariable (&vid_mode);
  576.     Cvar_RegisterVariable (&vid_redrawfull);
  577.     Cvar_RegisterVariable (&vid_waitforrefresh);
  578.     
  579.     Cmd_AddCommand("vid_nummodes", VID_NumModes_f);
  580.     Cmd_AddCommand("vid_describemode", VID_DescribeMode_f);
  581.     Cmd_AddCommand("vid_describemodes", VID_DescribeModes_f);
  582.     Cmd_AddCommand("vid_debug", VID_Debug_f);
  583.  
  584.   // interpret command-line params
  585.  
  586.     w = h = d = 0;
  587.     if (getenv("GSVGAMODE"))
  588.       current_mode = get_mode(getenv("GSVGAMODE"), w, h, d);
  589.     else if (COM_CheckParm("-mode"))
  590.       current_mode = get_mode(com_argv[COM_CheckParm("-mode")+1], w, h, d);
  591.     else if (COM_CheckParm("-w") || COM_CheckParm("-h")
  592.       || COM_CheckParm("-d"))
  593.     {
  594.       if (COM_CheckParm("-w"))
  595.         w = Q_atoi(com_argv[COM_CheckParm("-w")+1]);
  596.       if (COM_CheckParm("-h"))
  597.         h = Q_atoi(com_argv[COM_CheckParm("-h")+1]);
  598.       if (COM_CheckParm("-d"))
  599.         d = Q_atoi(com_argv[COM_CheckParm("-d")+1]);
  600.       current_mode = get_mode(0, w, h, d);
  601.     }
  602.     else
  603.       current_mode = G320x200x256;
  604.  
  605.   // set vid parameters
  606.     VID_SetMode(current_mode, palette);
  607.  
  608.     VID_SetPalette(palette);
  609.  
  610.     // we do want to run in the background when switched away
  611.     vga_runinbackground(1); 
  612.   }
  613.  
  614.   if (COM_CheckParm("-nokbd")) UseKeyboard = 0;
  615.  
  616.   if (UseKeyboard)
  617.   {
  618.     for (i=0 ; i<128 ; i++)
  619.       scantokey[i] = ' ';
  620.  
  621.     scantokey[  1] = K_ESCAPE;
  622.     scantokey[  2] = '1';
  623.     scantokey[  3] = '2';
  624.     scantokey[  4] = '3';
  625.     scantokey[  5] = '4';
  626.     scantokey[  6] = '5';
  627.     scantokey[  7] = '6';
  628.     scantokey[  8] = '7';
  629.     scantokey[  9] = '8';
  630.     scantokey[ 10] = '9';
  631.     scantokey[ 11] = '0';
  632.     scantokey[ 12] = '-';
  633.     scantokey[ 13] = '=';
  634.     scantokey[ 14] = K_BACKSPACE;
  635.     scantokey[ 15] = K_TAB;
  636.     scantokey[ 16] = 'q';       
  637.     scantokey[ 17] = 'w';       
  638.     scantokey[ 18] = 'e';       
  639.     scantokey[ 19] = 'r';       
  640.     scantokey[ 20] = 't';       
  641.     scantokey[ 21] = 'y';       
  642.     scantokey[ 22] = 'u';       
  643.     scantokey[ 23] = 'i';       
  644.     scantokey[ 24] = 'o';       
  645.     scantokey[ 25] = 'p';       
  646.     scantokey[ 26] = '[';
  647.     scantokey[ 27] = ']';
  648.     scantokey[ 28] = K_ENTER;
  649.     scantokey[ 29] = K_CTRL; //left
  650.     scantokey[ 30] = 'a';
  651.     scantokey[ 31] = 's';       
  652.     scantokey[ 32] = 'd';       
  653.     scantokey[ 33] = 'f';       
  654.     scantokey[ 34] = 'g';       
  655.     scantokey[ 35] = 'h';       
  656.     scantokey[ 36] = 'j';       
  657.     scantokey[ 37] = 'k';       
  658.     scantokey[ 38] = 'l';       
  659.     scantokey[ 39] = ';';
  660.     scantokey[ 40] = '\'';
  661.     scantokey[ 41] = '`';
  662.     scantokey[ 42] = K_SHIFT; //left
  663.     scantokey[ 43] = '\\';
  664.     scantokey[ 44] = 'z';       
  665.     scantokey[ 45] = 'x';  
  666.     scantokey[ 46] = 'c';
  667.     scantokey[ 47] = 'v';       
  668.     scantokey[ 48] = 'b';
  669.     scantokey[ 49] = 'n';       
  670.     scantokey[ 50] = 'm';       
  671.     scantokey[ 51] = ',';
  672.     scantokey[ 52] = '.';
  673.     scantokey[ 53] = '/';
  674.     scantokey[ 54] = K_SHIFT; //right
  675.     scantokey[ 55] = '*'; //keypad
  676.     scantokey[ 56] = K_ALT; //left
  677.     scantokey[ 57] = ' ';
  678.     // 58 caps lock
  679.     scantokey[ 59] = K_F1;
  680.     scantokey[ 60] = K_F2;
  681.     scantokey[ 61] = K_F3;
  682.     scantokey[ 62] = K_F4;
  683.     scantokey[ 63] = K_F5;
  684.     scantokey[ 64] = K_F6;
  685.     scantokey[ 65] = K_F7;
  686.     scantokey[ 66] = K_F8;
  687.     scantokey[ 67] = K_F9;
  688.     scantokey[ 68] = K_F10;
  689.     // 69 numlock
  690.     // 70 scrollock
  691.     scantokey[ 71] = K_HOME;
  692.     scantokey[ 72] = K_UPARROW;
  693.     scantokey[ 73] = K_PGUP;
  694.     scantokey[ 74] = '-';
  695.     scantokey[ 75] = K_LEFTARROW;
  696.     scantokey[ 76] = '5';
  697.     scantokey[ 77] = K_RIGHTARROW;
  698.     scantokey[ 79] = K_END;
  699.     scantokey[ 78] = '+';
  700.     scantokey[ 80] = K_DOWNARROW;
  701.     scantokey[ 81] = K_PGDN;
  702.     scantokey[ 82] = K_INS;
  703.     scantokey[ 83] = K_DEL;
  704.     // 84 to 86 not used
  705.     scantokey[ 87] = K_F11;
  706.     scantokey[ 88] = K_F12;
  707.     // 89 to 95 not used
  708.     scantokey[ 96] = K_ENTER; //keypad enter
  709.     scantokey[ 97] = K_CTRL; //right
  710.     scantokey[ 98] = '/';
  711.     scantokey[ 99] = K_F12; // print screen, bind to screenshot by default
  712.     scantokey[100] = K_ALT; // right
  713.  
  714.     scantokey[101] = K_PAUSE; // break
  715.     scantokey[102] = K_HOME;
  716.     scantokey[103] = K_UPARROW;
  717.     scantokey[104] = K_PGUP;
  718.     scantokey[105] = K_LEFTARROW;
  719.     scantokey[106] = K_RIGHTARROW;
  720.     scantokey[107] = K_END;
  721.     scantokey[108] = K_DOWNARROW;
  722.     scantokey[109] = K_PGDN;
  723.     scantokey[110] = K_INS;
  724.     scantokey[111] = K_DEL;
  725.  
  726.     scantokey[119] = K_PAUSE;
  727.  
  728.     if (keyboard_init())
  729.       Sys_Error("keyboard_init() failed");
  730.     keyboard_seteventhandler(keyhandler);
  731.   }
  732.  
  733. }
  734.  
  735. void VID_Update(vrect_t *rects)
  736. {
  737.   if (!svgalib_inited)
  738.     return;
  739.  
  740.   if (!vga_oktowrite())
  741.     return; // can't update screen if it's not active
  742.  
  743.   if (vid_waitforrefresh.value)
  744.     vga_waitretrace();
  745.  
  746.   if (VGA_planar)
  747.     VGA_UpdatePlanarScreen (vid.buffer);
  748.  
  749.   else if (vid_redrawfull.value) {
  750.     int total = vid.rowbytes * vid.height;
  751.     int offset;
  752.  
  753.     for (offset=0;offset<total;offset+=0x10000) {
  754.       vga_setpage(offset/0x10000);
  755.       memcpy(framebuffer_ptr,
  756.           vid.buffer + offset,
  757.           ((total-offset>0x10000)?0x10000:(total-offset)));
  758.     }
  759.   } else {
  760.     int ycount;
  761.     int offset;
  762.     int vidpage=0;
  763.  
  764.     vga_setpage(0);
  765.  
  766.     while (rects)
  767.     {
  768.       ycount = rects->height;
  769.       offset = rects->y * vid.rowbytes + rects->x;
  770.       while (ycount--)
  771.       {
  772.         register int i = offset % 0x10000;
  773.   
  774.         if ((offset / 0x10000) != vidpage) {
  775.           vidpage=offset / 0x10000;
  776.           vga_setpage(vidpage);
  777.         }
  778.         if (rects->width + i > 0x10000) {
  779.           memcpy(framebuffer_ptr + i, 
  780.               vid.buffer + offset, 
  781.               0x10000 - i);
  782.           vga_setpage(++vidpage);
  783.           memcpy(framebuffer_ptr,
  784.               vid.buffer + offset + 0x10000 - i, 
  785.               rects->width - 0x10000 + i);
  786.         } else
  787.           memcpy(framebuffer_ptr + i, 
  788.               vid.buffer + offset, 
  789.               rects->width);
  790.         offset += vid.rowbytes;
  791.       }
  792.   
  793.       rects = rects->pnext;
  794.     }
  795.   }
  796.   
  797.   if (vid_mode.value != current_mode)
  798.     VID_SetMode ((int)vid_mode.value, vid_current_palette);
  799. }
  800.  
  801. static int dither;
  802.  
  803. void VID_DitherOn(void)
  804. {
  805.     if (dither == 0)
  806.     {
  807. //    R_ViewChanged (&vrect, sb_lines, vid.aspect);
  808.         dither = 1;
  809.     }
  810. }
  811.  
  812. void VID_DitherOff(void)
  813. {
  814.     if (dither)
  815.     {
  816. //    R_ViewChanged (&vrect, sb_lines, vid.aspect);
  817.         dither = 0;
  818.     }
  819. }
  820.  
  821. void Sys_SendKeyEvents(void)
  822. {
  823.   if (!svgalib_inited)
  824.     return;
  825.  
  826.   if (UseKeyboard)
  827.     while (keyboard_update());
  828. }
  829.  
  830. void Force_CenterView_f (void)
  831. {
  832.   cl.viewangles[PITCH] = 0;
  833. }
  834.  
  835.  
  836. void mousehandler(int buttonstate, int dx, int dy)
  837. {
  838.   mouse_buttonstate = buttonstate;
  839.   mx += dx;
  840.   my += dy;
  841. }
  842.  
  843. void IN_Init(void)
  844. {
  845.  
  846.   int mtype;
  847.   char *mousedev;
  848.   int mouserate;
  849.  
  850.   Cvar_RegisterVariable (&m_filter);
  851.  
  852.   if (UseMouse)
  853.   {
  854.     Cvar_RegisterVariable (&mouse_button_commands[0]);
  855.     Cvar_RegisterVariable (&mouse_button_commands[1]);
  856.     Cvar_RegisterVariable (&mouse_button_commands[2]);
  857.     Cmd_AddCommand ("force_centerview", Force_CenterView_f);
  858.  
  859.     mouse_buttons = 3;
  860.  
  861.     mtype = vga_getmousetype();
  862.  
  863.     mousedev = "/dev/mouse";
  864.     if (getenv("MOUSEDEV")) mousedev = getenv("MOUSEDEV");
  865.     if (COM_CheckParm("-mdev"))
  866.       mousedev = com_argv[COM_CheckParm("-mdev")+1];
  867.  
  868.     mouserate = 1200;
  869.     if (getenv("MOUSERATE")) mouserate = atoi(getenv("MOUSERATE"));
  870.     if (COM_CheckParm("-mrate"))
  871.       mouserate = atoi(com_argv[COM_CheckParm("-mrate")+1]);
  872.  
  873. //    printf("Mouse: dev=%s,type=%s,speed=%d\n",
  874. //      mousedev, mice[mtype].name, mouserate);
  875.     if (mouse_init(mousedev, mtype, mouserate))
  876.     {
  877.       Con_Printf("No mouse found\n");
  878.       UseMouse = 0;
  879.     }
  880.     else
  881.       mouse_seteventhandler(mousehandler);
  882.  
  883.   }
  884.  
  885. }
  886.  
  887. void IN_Shutdown(void)
  888. {
  889.   if (UseMouse)
  890.     mouse_close();
  891. }
  892.  
  893. /*
  894. ===========
  895. IN_Commands
  896. ===========
  897. */
  898. void IN_Commands (void)
  899. {
  900.   if (UseMouse /*&& cls.state != ca_dedicated*/)
  901.   {
  902.     // poll mouse values
  903.     while (mouse_update())
  904.       ;
  905.  
  906.     // perform button actions
  907.     if ((mouse_buttonstate & MOUSE_LEFTBUTTON) &&
  908.       !(mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
  909.       Key_Event (K_MOUSE1, true);
  910.     else if (!(mouse_buttonstate & MOUSE_LEFTBUTTON) &&
  911.       (mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
  912.       Key_Event (K_MOUSE1, false);
  913.  
  914.     if ((mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
  915.       !(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
  916.       Key_Event (K_MOUSE2, true);
  917.     else if (!(mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
  918.       (mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
  919.       Key_Event (K_MOUSE2, false);
  920.  
  921.     if ((mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
  922.       !(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
  923.       Key_Event (K_MOUSE3, true);
  924.     else if (!(mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
  925.       (mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
  926.       Key_Event (K_MOUSE3, false);
  927.  
  928.     mouse_oldbuttonstate = mouse_buttonstate;
  929.   }
  930. }
  931.  
  932. /*
  933. ===========
  934. IN_Move
  935. ===========
  936. */
  937. void IN_MouseMove (usercmd_t *cmd)
  938. {
  939.   if (!UseMouse)
  940.     return;
  941.  
  942.   // poll mouse values
  943.   while (mouse_update())
  944.     ;
  945.  
  946.   if (m_filter.value)
  947.   {
  948.     mouse_x = (mx + old_mouse_x) * 0.5;
  949.     mouse_y = (my + old_mouse_y) * 0.5;
  950.   }
  951.   else
  952.   {
  953.     mouse_x = mx;
  954.     mouse_y = my;
  955.   }
  956.   old_mouse_x = mx;
  957.   old_mouse_y = my;
  958.   mx = my = 0; // clear for next update
  959.  
  960.   mouse_x *= sensitivity.value;
  961.   mouse_y *= sensitivity.value;
  962.  
  963. // add mouse X/Y movement to cmd
  964.   if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
  965.     cmd->sidemove += m_side.value * mouse_x;
  966.   else
  967.     cl.viewangles[YAW] -= m_yaw.value * mouse_x;
  968.   
  969.   if (in_mlook.state & 1)
  970.     V_StopPitchDrift ();
  971.     
  972.   if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
  973.   {
  974.     cl.viewangles[PITCH] += m_pitch.value * mouse_y;
  975.     if (cl.viewangles[PITCH] > 80)
  976.       cl.viewangles[PITCH] = 80;
  977.     if (cl.viewangles[PITCH] < -70)
  978.       cl.viewangles[PITCH] = -70;
  979.   }
  980.   else
  981.   {
  982.     if ((in_strafe.state & 1) && noclip_anglehack)
  983.       cmd->upmove -= m_forward.value * mouse_y;
  984.     else
  985.       cmd->forwardmove -= m_forward.value * mouse_y;
  986.   }
  987. }
  988.  
  989. void IN_Move (usercmd_t *cmd)
  990. {
  991.   IN_MouseMove(cmd);
  992. }
  993.  
  994.  
  995. /*
  996. ================
  997. VID_ModeInfo
  998. ================
  999. */
  1000. char *VID_ModeInfo (int modenum)
  1001. {
  1002.   static char *badmodestr = "Bad mode number";
  1003.   static char modestr[40];
  1004.  
  1005.   if (modenum == 0)
  1006.   {
  1007.     sprintf (modestr, "%d x %d, %d bpp",
  1008.          vid.width, vid.height, modes[current_mode].bytesperpixel*8);
  1009.     return (modestr);
  1010.   }
  1011.   else
  1012.   {
  1013.     return (badmodestr);
  1014.   }
  1015. }
  1016.  
  1017. void VID_LockBuffer (void)
  1018. {
  1019. }
  1020.  
  1021. void VID_UnlockBuffer (void)
  1022. {
  1023. }
  1024.  
  1025.  
  1026.