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