1/* 2Copyright (C) 1996-1997 Id Software, Inc. 3 4This program is free software; you can redistribute it and/or 5modify it under the terms of the GNU General Public License 6as published by the Free Software Foundation; either version 2 7of the License, or (at your option) any later version. 8 9This program is distributed in the hope that it will be useful, 10but WITHOUT ANY WARRANTY; without even the implied warranty of 11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13See the GNU General Public License for more details. 14 15You should have received a copy of the GNU General Public License 16along with this program; if not, write to the Free Software 17Foundation, 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 39unsigned short d_8to16table[256]; 40static byte *vid_surfcache; 41static int VID_highhunkmark; 42 43int num_modes; 44vga_modeinfo *modes; 45int current_mode; 46 47int num_shades=32; 48 49struct 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 63static unsigned char scantokey[128]; 64static byte vid_current_palette[768]; 65 66int num_mice = sizeof (mice) / sizeof(mice[0]); 67 68int d_con_indirect = 0; 69 70int svgalib_inited=0; 71int UseMouse = 1; 72int UseDisplay = 1; 73int UseKeyboard = 1; 74 75int mouserate = MOUSE_DEFAULTSAMPLERATE; 76 77cvar_t vid_mode = {"vid_mode","5",false}; 78cvar_t vid_redrawfull = {"vid_redrawfull","0",false}; 79cvar_t vid_waitforrefresh = {"vid_waitforrefresh","0",true}; 80 81char *framebuffer_ptr; 82 83cvar_t mouse_button_commands[3] = 84{ 85 {"mouse1","+attack"}, 86 {"mouse2","+strafe"}, 87 {"mouse3","+forward"}, 88}; 89 90int mouse_buttons; 91int mouse_buttonstate; 92int mouse_oldbuttonstate; 93float mouse_x, mouse_y; 94float old_mouse_x, old_mouse_y; 95int mx, my; 96 97cvar_t _windowed_mouse = {"_windowed_mouse", "1", true}; 98cvar_t m_filter = {"m_filter","0"}; 99 100static byte backingbuf[48*24]; 101 102int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes, VGA_planar; 103byte *VGA_pagebase; 104 105void VGA_UpdatePlanarScreen (void *srcbuffer); 106 107void 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 171void 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================= 232VID_Gamma_f 233 234Keybinding command 235================= 236*/ 237void 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 264void 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 278void 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================ 294VID_NumModes 295================ 296*/ 297int 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 306void VID_NumModes_f (void) 307{ 308 Con_Printf("%d modes\n",VID_NumModes()); 309} 310 311void 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 321void 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 348int 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 388int 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 399void 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 416void 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 427void 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 443void VID_ShiftPalette(unsigned char *p) 444{ 445 VID_SetPalette(p); 446} 447 448void 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 473int 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 556void 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 735void 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 801static int dither; 802 803void VID_DitherOn(void) 804{ 805 if (dither == 0) 806 { 807// R_ViewChanged (&vrect, sb_lines, vid.aspect); 808 dither = 1; 809 } 810} 811 812void VID_DitherOff(void) 813{ 814 if (dither) 815 { 816// R_ViewChanged (&vrect, sb_lines, vid.aspect); 817 dither = 0; 818 } 819} 820 821void Sys_SendKeyEvents(void) 822{ 823 if (!svgalib_inited) 824 return; 825 826 if (UseKeyboard) 827 while (keyboard_update()); 828} 829 830void Force_CenterView_f (void) 831{ 832 cl.viewangles[PITCH] = 0; 833} 834 835 836void mousehandler(int buttonstate, int dx, int dy) 837{ 838 mouse_buttonstate = buttonstate; 839 mx += dx; 840 my += dy; 841} 842 843void 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 887void IN_Shutdown(void) 888{ 889 if (UseMouse) 890 mouse_close(); 891} 892 893/* 894=========== 895IN_Commands 896=========== 897*/ 898void 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=========== 934IN_Move 935=========== 936*/ 937void 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 989void IN_Move (usercmd_t *cmd) 990{ 991 IN_MouseMove(cmd); 992} 993 994 995/* 996================ 997VID_ModeInfo 998================ 999*/ 1000char *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 1017void VID_LockBuffer (void) 1018{ 1019} 1020 1021void VID_UnlockBuffer (void) 1022{ 1023} 1024 1025 1026