home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 14 / MA_Cover_14.iso / source / c / q1source_amy / qw / client / vid_svgalib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-21  |  21.0 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.