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