1 /*
2 ** GLW_IMP.C
3 **
4 ** This file contains ALL Linux specific stuff having to do with the
5 ** OpenGL refresh.  When a port is being made the following functions
6 ** must be implemented by the port:
7 **
8 ** GLimp_EndFrame
9 ** GLimp_Init
10 ** GLimp_Shutdown
11 ** GLimp_SwitchFullscreen
12 **
13 */
14 
15 #include <termios.h>
16 #include <sys/ioctl.h>
17 #include <sys/stat.h>
18 #include <sys/vt.h>
19 #include <stdarg.h>
20 #include <stdio.h>
21 #include <signal.h>
22 
23 #include "../ref_gl/gl_local.h"
24 #include "../client/keys.h"
25 #include "../linux/rw_linux.h"
26 
27 #include <GL/fxmesa.h>
28 
29 /*****************************************************************************/
30 
31 static qboolean GLimp_SwitchFullscreen( int width, int height );
32 qboolean GLimp_InitGL (void);
33 
34 extern cvar_t *vid_fullscreen;
35 extern cvar_t *vid_ref;
36 
37 static fxMesaContext fc = NULL;
38 
39 #define NUM_RESOLUTIONS 3
40 
41 static resolutions[NUM_RESOLUTIONS][3]={
42   { 512, 384, GR_RESOLUTION_512x384 },
43   { 640, 400, GR_RESOLUTION_640x400 },
44   { 640, 480, GR_RESOLUTION_640x480 }
45 };
46 
findres(int * width,int * height)47 static int findres(int *width, int *height)
48 {
49 	int i;
50 
51 	for(i=0;i<NUM_RESOLUTIONS;i++)
52 		if((*width<=resolutions[i][0]) && (*height<=resolutions[i][1])) {
53 			*width = resolutions[i][0];
54 			*height = resolutions[i][1];
55 			return resolutions[i][2];
56 		}
57 
58 	*width = 640;
59 	*height = 480;
60 	return GR_RESOLUTION_640x480;
61 }
62 
signal_handler(int sig)63 static void signal_handler(int sig)
64 {
65 	printf("Received signal %d, exiting...\n", sig);
66 	GLimp_Shutdown();
67 	_exit(0);
68 }
69 
InitSig(void)70 static void InitSig(void)
71 {
72 	signal(SIGHUP, signal_handler);
73 	signal(SIGQUIT, signal_handler);
74 	signal(SIGILL, signal_handler);
75 	signal(SIGTRAP, signal_handler);
76 	signal(SIGIOT, signal_handler);
77 	signal(SIGBUS, signal_handler);
78 	signal(SIGFPE, signal_handler);
79 	signal(SIGSEGV, signal_handler);
80 	signal(SIGTERM, signal_handler);
81 }
82 
83 /*
84 ** GLimp_SetMode
85 */
GLimp_SetMode(int * pwidth,int * pheight,int mode,qboolean fullscreen)86 int GLimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen )
87 {
88 	int width, height;
89 	GLint attribs[32];
90 
91 	ri.Con_Printf( PRINT_ALL, "Initializing OpenGL display\n");
92 
93 	ri.Con_Printf (PRINT_ALL, "...setting mode %d:", mode );
94 
95 	if ( !ri.Vid_GetModeInfo( &width, &height, mode ) )
96 	{
97 		ri.Con_Printf( PRINT_ALL, " invalid mode\n" );
98 		return rserr_invalid_mode;
99 	}
100 
101 	ri.Con_Printf( PRINT_ALL, " %d %d\n", width, height );
102 
103 	// destroy the existing window
104 	GLimp_Shutdown ();
105 
106 	// set fx attribs
107 	attribs[0] = FXMESA_DOUBLEBUFFER;
108 	attribs[1] = FXMESA_ALPHA_SIZE;
109 	attribs[2] = 1;
110 	attribs[3] = FXMESA_DEPTH_SIZE;
111 	attribs[4] = 1;
112 	attribs[5] = FXMESA_NONE;
113 
114 	fc = fxMesaCreateContext(0, findres(&width, &height), GR_REFRESH_75Hz,
115 		attribs);
116 	if (!fc)
117 		return rserr_invalid_mode;
118 
119 	*pwidth = width;
120 	*pheight = height;
121 
122 	// let the sound and input subsystems know about the new window
123 	ri.Vid_NewWindow (width, height);
124 
125 	fxMesaMakeCurrent(fc);
126 
127 	return rserr_ok;
128 }
129 
130 /*
131 ** GLimp_Shutdown
132 **
133 ** This routine does all OS specific shutdown procedures for the OpenGL
134 ** subsystem.  Under OpenGL this means NULLing out the current DC and
135 ** HGLRC, deleting the rendering context, and releasing the DC acquired
136 ** for the window.  The state structure is also nulled out.
137 **
138 */
GLimp_Shutdown(void)139 void GLimp_Shutdown( void )
140 {
141 	if (fc) {
142 		fxMesaDestroyContext(fc);
143 		fc = NULL;
144 	}
145 }
146 
147 /*
148 ** GLimp_Init
149 **
150 ** This routine is responsible for initializing the OS specific portions
151 ** of OpenGL.
152 */
GLimp_Init(void * hinstance,void * wndproc)153 int GLimp_Init( void *hinstance, void *wndproc )
154 {
155 	InitSig();
156 
157 	return true;
158 }
159 
160 /*
161 ** GLimp_BeginFrame
162 */
GLimp_BeginFrame(float camera_seperation)163 void GLimp_BeginFrame( float camera_seperation )
164 {
165 }
166 
167 /*
168 ** GLimp_EndFrame
169 **
170 ** Responsible for doing a swapbuffers and possibly for other stuff
171 ** as yet to be determined.  Probably better not to make this a GLimp
172 ** function and instead do a call to GLimp_SwapBuffers.
173 */
GLimp_EndFrame(void)174 void GLimp_EndFrame (void)
175 {
176 	glFlush();
177 	fxMesaSwapBuffers();
178 }
179 
180 /*
181 ** GLimp_AppActivate
182 */
GLimp_AppActivate(qboolean active)183 void GLimp_AppActivate( qboolean active )
184 {
185 }
186 
187 extern void gl3DfxSetPaletteEXT(GLuint *pal);
188 
Fake_glColorTableEXT(GLenum target,GLenum internalformat,GLsizei width,GLenum format,GLenum type,const GLvoid * table)189 void Fake_glColorTableEXT( GLenum target, GLenum internalformat,
190                              GLsizei width, GLenum format, GLenum type,
191                              const GLvoid *table )
192 {
193 	byte temptable[256][4];
194 	byte *intbl;
195 	int i;
196 
197 	for (intbl = (byte *)table, i = 0; i < 256; i++) {
198 		temptable[i][2] = *intbl++;
199 		temptable[i][1] = *intbl++;
200 		temptable[i][0] = *intbl++;
201 		temptable[i][3] = 255;
202 	}
203 	gl3DfxSetPaletteEXT((GLuint *)temptable);
204 }
205 
206 
207