123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- /*
- ** 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 <termios.h>
- #include <sys/ioctl.h>
- #include <sys/stat.h>
- #include <sys/vt.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <signal.h>
- #include <sys/mman.h>
- #include <asm/io.h>
- #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 ; i<num_modes ; i++)
- {
- if (vga_hasmode(i))
- memcpy(&modes[i], vga_getmodeinfo(i), sizeof (vga_modeinfo));
- else
- modes[i].width = 0; // means not available
- }
- // filter for modes i don't support
- for (i=0 ; i<num_modes ; i++)
- {
- if (modes[i].bytesperpixel != 1 && modes[i].colors != 256)
- modes[i].width = 0;
- }
- for (i = 0; i < num_modes; i++)
- if (modes[i].width)
- ri.Con_Printf(PRINT_ALL, "mode %d: %d %d\n", modes[i].width, modes[i].height);
- }
- /*
- ** SWimp_Init
- **
- ** This routine is responsible for initializing the implementation
- ** specific stuff in a software rendering subsystem.
- */
- int SWimp_Init( void *hInstance, void *wndProc )
- {
- vga_init();
- VID_InitModes();
- return true;
- }
- int get_mode(int width, int height)
- {
- int i;
- int ok, match;
- for (i=0 ; i<num_modes ; i++)
- if (modes[i].width &&
- modes[i].width == width && modes[i].height == height)
- break;
- if (i==num_modes)
- return -1; // not found
- return i;
- }
- /*
- ** SWimp_InitGraphics
- **
- ** This initializes the software refresh's implementation specific
- ** graphics subsystem. In the case of Windows it creates DIB or
- ** DDRAW surfaces.
- **
- ** The necessary width and height parameters are grabbed from
- ** vid.width and vid.height.
- */
- static qboolean SWimp_InitGraphics( qboolean fullscreen )
- {
- int bsize, zsize, tsize;
- SWimp_Shutdown();
- current_mode = get_mode(vid.width, vid.height);
- if (current_mode < 0) {
- ri.Con_Printf (PRINT_ALL, "Mode %d %d not found\n", vid.width, vid.height);
- return false; // mode not found
- }
- // let the sound and input subsystems know about the new window
- ri.Vid_NewWindow (vid.width, vid.height);
- ri.Con_Printf (PRINT_ALL, "Setting VGAMode: %d\n", current_mode );
- // Cvar_SetValue ("vid_mode", (float)modenum);
-
- VGA_width = modes[current_mode].width;
- VGA_height = modes[current_mode].height;
- VGA_planar = modes[current_mode].bytesperpixel == 0;
- VGA_rowbytes = modes[current_mode].linewidth;
- vid.rowbytes = modes[current_mode].linewidth;
- if (VGA_planar) {
- VGA_bufferrowbytes = modes[current_mode].linewidth * 4;
- vid.rowbytes = modes[current_mode].linewidth*4;
- }
- // get goin'
- vga_setmode(current_mode);
- VGA_pagebase = framebuffer_ptr = (char *) vga_getgraphmem();
- // if (vga_setlinearaddressing()>0)
- // 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;offset<total;offset+=0x10000) {
- vga_setpage(offset/0x10000);
- memcpy(framebuffer_ptr,
- vid.buffer + offset,
- ((total-offset>0x10000)?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");
- }
|