/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* ** RW_SVGALBI.C ** ** This file contains ALL Linux specific stuff having to do with the ** software refresh. When a port is being made the following functions ** must be implemented by the port: ** ** SWimp_EndFrame ** SWimp_Init ** SWimp_InitGraphics ** SWimp_SetPalette ** SWimp_Shutdown ** SWimp_SwitchFullscreen */ #include #include #include #include #include #include #include #include #include #include "vga.h" #include "vgakeyboard.h" #include "vgamouse.h" #include "../ref_soft/r_local.h" #include "../client/keys.h" #include "../linux/rw_linux.h" /*****************************************************************************/ int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes, VGA_planar; byte *VGA_pagebase; char *framebuffer_ptr; void VGA_UpdatePlanarScreen (void *srcbuffer); int num_modes; vga_modeinfo *modes; int current_mode; // Console variables that we need to access from this module /*****************************************************************************/ void VID_InitModes(void) { int i; // get complete information on all modes num_modes = vga_lastmodenumber()+1; modes = malloc(num_modes * sizeof(vga_modeinfo)); for (i=0 ; i0) // framebuffer_ptr = (char *) vga_getgraphmem(); if (!framebuffer_ptr) Sys_Error("This mode isn't hapnin'\n"); vga_setpage(0); vid.buffer = malloc(vid.rowbytes * vid.height); if (!vid.buffer) Sys_Error("Unabled to alloc vid.buffer!\n"); return true; } /* ** SWimp_EndFrame ** ** This does an implementation specific copy from the backbuffer to the ** front buffer. In the Win32 case it uses BitBlt or BltFast depending ** on whether we're using DIB sections/GDI or DDRAW. */ void SWimp_EndFrame (void) { if (!vga_oktowrite()) return; // can't update screen if it's not active // if (vid_waitforrefresh.value) // vga_waitretrace(); if (VGA_planar) VGA_UpdatePlanarScreen (vid.buffer); else { int total = vid.rowbytes * vid.height; int offset; for (offset=0;offset0x10000)?0x10000:(total-offset))); } } } /* ** SWimp_SetMode */ rserr_t SWimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen ) { rserr_t retval = rserr_ok; ri.Con_Printf (PRINT_ALL, "setting mode %d:", mode ); if ( !ri.Vid_GetModeInfo( pwidth, pheight, mode ) ) { ri.Con_Printf( PRINT_ALL, " invalid mode\n" ); return rserr_invalid_mode; } ri.Con_Printf( PRINT_ALL, " %d %d\n", *pwidth, *pheight); if ( !SWimp_InitGraphics( false ) ) { // failed to set a valid mode in windowed mode return rserr_invalid_mode; } R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table ); return retval; } /* ** SWimp_SetPalette ** ** System specific palette setting routine. A NULL palette means ** to use the existing palette. The palette is expected to be in ** a padded 4-byte xRGB format. */ void SWimp_SetPalette( const unsigned char *palette ) { static int tmppal[256*3]; const unsigned char *pal; int *tp; int i; if ( !palette ) palette = ( const unsigned char * ) sw_state.currentpalette; if (vga_getcolors() == 256) { tp = tmppal; pal = palette; for (i=0 ; i < 256 ; i++, pal += 4, tp += 3) { tp[0] = pal[0] >> 2; tp[1] = pal[1] >> 2; tp[2] = pal[2] >> 2; } if (vga_oktowrite()) vga_setpalvec(0, 256, tmppal); } } /* ** SWimp_Shutdown ** ** System specific graphics subsystem shutdown routine. Destroys ** DIBs or DDRAW surfaces as appropriate. */ void SWimp_Shutdown( void ) { if (vid.buffer) { free(vid.buffer); vid.buffer = NULL; } vga_setmode(TEXT); } /* ** SWimp_AppActivate */ void SWimp_AppActivate( qboolean active ) { } //=============================================================================== /* ================ Sys_MakeCodeWriteable ================ */ void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length) { int r; unsigned long addr; int psize = getpagesize(); addr = (startaddr & ~(psize-1)) - psize; // fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr, // addr, startaddr+length, length); r = mprotect((char*)addr, length + startaddr - addr + psize, 7); if (r < 0) Sys_Error("Protection change failed\n"); }