|
|
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.