|
|
1.1 root 1: /* 1.1.1.2 ! root 2: Copyright (C) 1997-2001 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: /* 1.1 root 21: ** RW_SVGALBI.C 22: ** 23: ** This file contains ALL Linux specific stuff having to do with the 24: ** software refresh. When a port is being made the following functions 25: ** must be implemented by the port: 26: ** 27: ** SWimp_EndFrame 28: ** SWimp_Init 29: ** SWimp_InitGraphics 30: ** SWimp_SetPalette 31: ** SWimp_Shutdown 32: ** SWimp_SwitchFullscreen 33: */ 34: 35: #include <termios.h> 36: #include <sys/ioctl.h> 37: #include <sys/stat.h> 38: #include <sys/vt.h> 39: #include <stdarg.h> 40: #include <stdio.h> 41: #include <signal.h> 42: #include <sys/mman.h> 43: 44: #include <asm/io.h> 45: 46: #include "vga.h" 47: #include "vgakeyboard.h" 48: #include "vgamouse.h" 49: 50: #include "../ref_soft/r_local.h" 51: #include "../client/keys.h" 52: #include "../linux/rw_linux.h" 53: 54: /*****************************************************************************/ 55: 56: int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes, VGA_planar; 57: byte *VGA_pagebase; 58: char *framebuffer_ptr; 59: 60: void VGA_UpdatePlanarScreen (void *srcbuffer); 61: 62: int num_modes; 63: vga_modeinfo *modes; 64: int current_mode; 65: 66: // Console variables that we need to access from this module 67: 68: /*****************************************************************************/ 69: 70: void VID_InitModes(void) 71: { 72: 73: int i; 74: 75: // get complete information on all modes 76: 77: num_modes = vga_lastmodenumber()+1; 78: modes = malloc(num_modes * sizeof(vga_modeinfo)); 79: for (i=0 ; i<num_modes ; i++) 80: { 81: if (vga_hasmode(i)) 82: memcpy(&modes[i], vga_getmodeinfo(i), sizeof (vga_modeinfo)); 83: else 84: modes[i].width = 0; // means not available 85: } 86: 87: // filter for modes i don't support 88: 89: for (i=0 ; i<num_modes ; i++) 90: { 91: if (modes[i].bytesperpixel != 1 && modes[i].colors != 256) 92: modes[i].width = 0; 93: } 94: 95: for (i = 0; i < num_modes; i++) 96: if (modes[i].width) 97: ri.Con_Printf(PRINT_ALL, "mode %d: %d %d\n", modes[i].width, modes[i].height); 98: 99: } 100: 101: /* 102: ** SWimp_Init 103: ** 104: ** This routine is responsible for initializing the implementation 105: ** specific stuff in a software rendering subsystem. 106: */ 107: int SWimp_Init( void *hInstance, void *wndProc ) 108: { 109: vga_init(); 110: 111: VID_InitModes(); 112: 113: return true; 114: } 115: 116: int get_mode(int width, int height) 117: { 118: 119: int i; 120: int ok, match; 121: 122: for (i=0 ; i<num_modes ; i++) 123: if (modes[i].width && 124: modes[i].width == width && modes[i].height == height) 125: break; 126: if (i==num_modes) 127: return -1; // not found 128: 129: return i; 130: } 131: 132: /* 133: ** SWimp_InitGraphics 134: ** 135: ** This initializes the software refresh's implementation specific 136: ** graphics subsystem. In the case of Windows it creates DIB or 137: ** DDRAW surfaces. 138: ** 139: ** The necessary width and height parameters are grabbed from 140: ** vid.width and vid.height. 141: */ 142: static qboolean SWimp_InitGraphics( qboolean fullscreen ) 143: { 144: int bsize, zsize, tsize; 145: 146: SWimp_Shutdown(); 147: 148: current_mode = get_mode(vid.width, vid.height); 149: 150: if (current_mode < 0) { 151: ri.Con_Printf (PRINT_ALL, "Mode %d %d not found\n", vid.width, vid.height); 152: return false; // mode not found 153: } 154: 155: // let the sound and input subsystems know about the new window 156: ri.Vid_NewWindow (vid.width, vid.height); 157: 158: ri.Con_Printf (PRINT_ALL, "Setting VGAMode: %d\n", current_mode ); 159: 160: // Cvar_SetValue ("vid_mode", (float)modenum); 161: 162: VGA_width = modes[current_mode].width; 163: VGA_height = modes[current_mode].height; 164: VGA_planar = modes[current_mode].bytesperpixel == 0; 165: VGA_rowbytes = modes[current_mode].linewidth; 166: 167: vid.rowbytes = modes[current_mode].linewidth; 168: 169: if (VGA_planar) { 170: VGA_bufferrowbytes = modes[current_mode].linewidth * 4; 171: vid.rowbytes = modes[current_mode].linewidth*4; 172: } 173: 174: // get goin' 175: 176: vga_setmode(current_mode); 177: 178: VGA_pagebase = framebuffer_ptr = (char *) vga_getgraphmem(); 179: // if (vga_setlinearaddressing()>0) 180: // framebuffer_ptr = (char *) vga_getgraphmem(); 181: if (!framebuffer_ptr) 182: Sys_Error("This mode isn't hapnin'\n"); 183: 184: vga_setpage(0); 185: 186: vid.buffer = malloc(vid.rowbytes * vid.height); 187: if (!vid.buffer) 188: Sys_Error("Unabled to alloc vid.buffer!\n"); 189: 190: return true; 191: } 192: 193: /* 194: ** SWimp_EndFrame 195: ** 196: ** This does an implementation specific copy from the backbuffer to the 197: ** front buffer. In the Win32 case it uses BitBlt or BltFast depending 198: ** on whether we're using DIB sections/GDI or DDRAW. 199: */ 200: void SWimp_EndFrame (void) 201: { 202: if (!vga_oktowrite()) 203: return; // can't update screen if it's not active 204: 205: // if (vid_waitforrefresh.value) 206: // vga_waitretrace(); 207: 208: if (VGA_planar) 209: VGA_UpdatePlanarScreen (vid.buffer); 210: 211: else { 212: int total = vid.rowbytes * vid.height; 213: int offset; 214: 215: for (offset=0;offset<total;offset+=0x10000) { 216: vga_setpage(offset/0x10000); 217: memcpy(framebuffer_ptr, 218: vid.buffer + offset, 219: ((total-offset>0x10000)?0x10000:(total-offset))); 220: } 221: } 222: } 223: 224: /* 225: ** SWimp_SetMode 226: */ 227: rserr_t SWimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen ) 228: { 229: rserr_t retval = rserr_ok; 230: 231: ri.Con_Printf (PRINT_ALL, "setting mode %d:", mode ); 232: 233: if ( !ri.Vid_GetModeInfo( pwidth, pheight, mode ) ) 234: { 235: ri.Con_Printf( PRINT_ALL, " invalid mode\n" ); 236: return rserr_invalid_mode; 237: } 238: 239: ri.Con_Printf( PRINT_ALL, " %d %d\n", *pwidth, *pheight); 240: 241: if ( !SWimp_InitGraphics( false ) ) { 242: // failed to set a valid mode in windowed mode 243: return rserr_invalid_mode; 244: } 245: 246: R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table ); 247: 248: return retval; 249: } 250: 251: /* 252: ** SWimp_SetPalette 253: ** 254: ** System specific palette setting routine. A NULL palette means 255: ** to use the existing palette. The palette is expected to be in 256: ** a padded 4-byte xRGB format. 257: */ 258: void SWimp_SetPalette( const unsigned char *palette ) 259: { 260: static int tmppal[256*3]; 261: const unsigned char *pal; 262: int *tp; 263: int i; 264: 265: if ( !palette ) 266: palette = ( const unsigned char * ) sw_state.currentpalette; 267: 268: if (vga_getcolors() == 256) 269: { 270: tp = tmppal; 271: pal = palette; 272: 273: for (i=0 ; i < 256 ; i++, pal += 4, tp += 3) { 274: tp[0] = pal[0] >> 2; 275: tp[1] = pal[1] >> 2; 276: tp[2] = pal[2] >> 2; 277: } 278: 279: if (vga_oktowrite()) 280: vga_setpalvec(0, 256, tmppal); 281: } 282: } 283: 284: /* 285: ** SWimp_Shutdown 286: ** 287: ** System specific graphics subsystem shutdown routine. Destroys 288: ** DIBs or DDRAW surfaces as appropriate. 289: */ 290: void SWimp_Shutdown( void ) 291: { 292: if (vid.buffer) { 293: free(vid.buffer); 294: vid.buffer = NULL; 295: } 296: vga_setmode(TEXT); 297: } 298: 299: /* 300: ** SWimp_AppActivate 301: */ 302: void SWimp_AppActivate( qboolean active ) 303: { 304: } 305: 306: //=============================================================================== 307: 308: /* 309: ================ 310: Sys_MakeCodeWriteable 311: ================ 312: */ 313: void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length) 314: { 315: 316: int r; 317: unsigned long addr; 318: int psize = getpagesize(); 319: 320: addr = (startaddr & ~(psize-1)) - psize; 321: 322: // fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr, 323: // addr, startaddr+length, length); 324: 325: r = mprotect((char*)addr, length + startaddr - addr + psize, 7); 326: 327: if (r < 0) 328: Sys_Error("Protection change failed\n"); 329: } 330:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.