]> icculus.org git repositories - theoddone33/hhexen.git/blob - sdl/i_sdlgl.c
Drop in SDL
[theoddone33/hhexen.git] / sdl / i_sdlgl.c
1 //**************************************************************************
2 //**
3 //** $Id$
4 //**
5 //**************************************************************************
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include <unistd.h>
11 #include <sys/time.h>
12 #include <SDL/SDL.h> 
13 #include <GL/gl.h>
14 #include <GL/glu.h>
15 #include "h2def.h"
16 #include "r_local.h"
17 #include "p_local.h"    // for P_AproxDistance
18 #include "sounds.h"
19 #include "i_sound.h"
20 #include "soundst.h"
21 #include "st_start.h"
22
23 // Public Data
24
25 int screenWidth  = SCREENWIDTH*2;
26 int screenHeight = SCREENHEIGHT*2;
27 int maxTexSize = 256;
28 int ratioLimit = 0;             // Zero if none.
29 int test3dfx = 0;
30
31 int DisplayTicker = 0;
32
33
34 // Code
35 extern void OGL_InitData();
36 extern void OGL_InitRenderer();
37 extern void OGL_ResetData();
38 extern void OGL_ResetLumpTexData();
39
40 void I_StartupNet (void);
41 void I_ShutdownNet (void);
42 void I_ReadExternDriver(void);
43 void GrabScreen (void);
44
45 extern int usemouse, usejoystick;
46
47 extern void **lumpcache;
48
49 int i_Vector;
50 externdata_t *i_ExternData;
51 boolean useexterndriver;
52
53 boolean mousepresent;
54
55 int ticcount;
56
57 boolean novideo; // if true, stay in text mode for debugging
58
59 #define KEY_INS         0x52
60 #define KEY_DEL         0x53
61 #define KEY_PGUP        0x49
62 #define KEY_PGDN        0x51
63 #define KEY_HOME        0x47
64 #define KEY_END         0x4f
65
66 //--------------------------------------------------------------------------
67 //
68 // PROC I_WaitVBL
69 //
70 //--------------------------------------------------------------------------
71
72 void I_WaitVBL(int vbls)
73 {
74         if( novideo )
75         {
76                 return;
77         }
78         while( vbls-- )
79         {
80         SDL_Delay( 16667/1000 );
81         }
82 }
83
84 //--------------------------------------------------------------------------
85 //
86 // PROC I_SetPalette
87 //
88 // Palette source must use 8 bit RGB elements.
89 //
90 //--------------------------------------------------------------------------
91
92 void I_SetPalette(byte *palette)
93 {
94 /*
95     SDL_Color* c;
96     SDL_Color* cend;
97     SDL_Color cmap[ 256 ];
98
99         if(novideo)
100         {
101                 return;
102         }
103         I_WaitVBL(1);
104
105     c = cmap;
106     cend = c + 256;
107         for( ; c != cend; c++ )
108         {
109                 //_outbyte(PEL_DATA, (gammatable[usegamma][*palette++])>>2);
110
111         c->r = gammatable[usegamma][*palette++];
112         c->g = gammatable[usegamma][*palette++];
113         c->b = gammatable[usegamma][*palette++];
114         }
115     SDL_SetColors( sdl_screen, cmap, 0, 256 );
116 */
117 }
118
119 /*
120 ============================================================================
121
122                                                         GRAPHICS MODE
123
124 ============================================================================
125 */
126
127 byte *pcscreen, *destscreen, *destview;
128
129 /*
130 ==============
131 =
132 = I_Update
133 =
134 ==============
135 */
136
137 int UpdateState;
138 extern int screenblocks;
139
140 void I_Update (void)
141 {
142         if(UpdateState == I_NOUPDATE)
143                 return;
144
145         SDL_GL_SwapBuffers();
146         UpdateState = I_NOUPDATE;
147 }
148
149 //--------------------------------------------------------------------------
150 //
151 // PROC I_InitGraphics
152 //
153 //--------------------------------------------------------------------------
154
155 void I_InitGraphics(void)
156 {
157     int p;
158     char text[20];
159     Uint32 flags = SDL_OPENGL;
160
161     if( novideo )
162     {
163         return;
164     }
165
166     p = M_CheckParm ("-fullscreen");
167     if (p) {
168         flags |= SDL_FULLSCREEN;
169         setenv ("MESA_GLX_FX","fullscreen", 1);
170     } else {
171         setenv ("MESA_GLX_FX","disable",1);
172     }   
173     p = M_CheckParm ("-height");
174     if (p && p < myargc - 1)
175     {
176         screenHeight = atoi (myargv[p+1]);
177     }
178     p = M_CheckParm ("-width");
179     if (p && p < myargc - 1) {
180         screenWidth = atoi(myargv[p+1]);
181     }
182     ST_Message("Screen size:  %dx%d\n",screenWidth, screenHeight);
183
184     if(SDL_SetVideoMode(screenWidth, screenHeight, 8, flags) == NULL)
185     {
186         fprintf( stderr, "Couldn't set video mode %dx%d: %s\n",
187                  screenWidth, screenHeight, SDL_GetError() );
188         exit( 3 );
189     }
190
191     OGL_InitRenderer ();
192
193     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
194
195     // Print some OpenGL information.
196     ST_Message( "I_InitGraphics: OpenGL information:\n" );
197     ST_Message( "  Vendor: %s\n", glGetString(GL_VENDOR) );
198     ST_Message( "  Renderer: %s\n", glGetString(GL_RENDERER) );
199     ST_Message( "  Version: %s\n", glGetString(GL_VERSION) );
200     ST_Message( "  GLU Version: %s\n", gluGetString((GLenum)GLU_VERSION) );
201
202     // Check the maximum texture size.
203     glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxTexSize );
204     ST_Message("  Maximum texture size: %d\n", maxTexSize);
205     if( maxTexSize == 256 )
206     {
207             //ST_Message("  Is this Voodoo? Using size ratio limit.\n");
208             ratioLimit = 8;
209     }
210
211     if( M_CheckParm("-3dfxtest") )
212     {
213             test3dfx = 1;
214             ST_Message("  3dfx test mode.\n");
215     }
216
217     // Only grab if we want to
218     if (!M_CheckParm ("--nograb") && !M_CheckParm ("-g")) {
219             SDL_WM_GrabInput (SDL_GRAB_ON);
220     }
221
222     SDL_ShowCursor( 0 );
223     snprintf (text, 20, "HHexen v%s", HHEXEN_VERSION);
224     SDL_WM_SetCaption( text, "HHEXEN" );
225
226
227     //I_SetPalette( W_CacheLumpName("PLAYPAL", PU_CACHE) );
228 }
229
230 //--------------------------------------------------------------------------
231 //
232 // PROC I_ShutdownGraphics
233 //
234 //--------------------------------------------------------------------------
235
236 void I_ShutdownGraphics(void)
237 {
238     OGL_ResetData ();
239     OGL_ResetLumpTexData ();
240     SDL_Quit ();
241 }
242
243 //===========================================================================
244
245 //
246 //  Translates the key 
247 //
248
249 int xlatekey(SDL_keysym *key)
250 {
251
252     int rc;
253
254     switch(key->sym)
255     {
256       case SDLK_LEFT:   rc = KEY_LEFTARROW;     break;
257       case SDLK_RIGHT:  rc = KEY_RIGHTARROW;    break;
258       case SDLK_DOWN:   rc = KEY_DOWNARROW;     break;
259       case SDLK_UP:     rc = KEY_UPARROW;       break;
260       case SDLK_ESCAPE: rc = KEY_ESCAPE;        break;
261       case SDLK_RETURN: rc = KEY_ENTER;         break;
262       case SDLK_F1:     rc = KEY_F1;            break;
263       case SDLK_F2:     rc = KEY_F2;            break;
264       case SDLK_F3:     rc = KEY_F3;            break;
265       case SDLK_F4:     rc = KEY_F4;            break;
266       case SDLK_F5:     rc = KEY_F5;            break;
267       case SDLK_F6:     rc = KEY_F6;            break;
268       case SDLK_F7:     rc = KEY_F7;            break;
269       case SDLK_F8:     rc = KEY_F8;            break;
270       case SDLK_F9:     rc = KEY_F9;            break;
271       case SDLK_F10:    rc = KEY_F10;           break;
272       case SDLK_F11:    rc = KEY_F11;           break;
273       case SDLK_F12:    rc = KEY_F12;           break;
274         
275       case SDLK_INSERT: rc = KEY_INS;           break;
276       case SDLK_DELETE: rc = KEY_DEL;           break;
277       case SDLK_PAGEUP: rc = KEY_PGUP;          break;
278       case SDLK_PAGEDOWN: rc = KEY_PGDN;        break;
279       case SDLK_HOME:   rc = KEY_HOME;          break;
280       case SDLK_END:    rc = KEY_END;           break;
281
282       case SDLK_BACKSPACE: rc = KEY_BACKSPACE;  break;
283
284       case SDLK_PAUSE:  rc = KEY_PAUSE;         break;
285
286       case SDLK_EQUALS: rc = KEY_EQUALS;        break;
287
288       case SDLK_KP_MINUS:
289       case SDLK_MINUS:  rc = KEY_MINUS;         break;
290
291       case SDLK_LSHIFT:
292       case SDLK_RSHIFT:
293         rc = KEY_RSHIFT;
294         break;
295         
296       case SDLK_LCTRL:
297       case SDLK_RCTRL:
298         rc = KEY_RCTRL;
299         break;
300         
301       case SDLK_LALT:
302       case SDLK_LMETA:
303       case SDLK_RALT:
304       case SDLK_RMETA:
305         rc = KEY_RALT;
306         break;
307         
308       default:
309         rc = key->sym;
310         break;
311     }
312
313     return rc;
314
315 }
316
317
318 /* This processes SDL events */
319 void I_GetEvent(SDL_Event *Event)
320 {
321     Uint8 buttonstate;
322     event_t event;
323     SDLMod mod;
324
325     switch (Event->type)
326     {
327       case SDL_KEYDOWN:
328         mod = SDL_GetModState ();
329         if (mod & KMOD_RALT || mod & KMOD_LALT) {
330                 if (Event->key.keysym.sym == 'g') {
331                         if (SDL_WM_GrabInput (SDL_GRAB_QUERY) == SDL_GRAB_OFF)
332                                 SDL_WM_GrabInput (SDL_GRAB_ON);
333                         else
334                                 SDL_WM_GrabInput (SDL_GRAB_OFF);
335                 }
336         } else { 
337                 event.type = ev_keydown;
338                 event.data1 = xlatekey(&Event->key.keysym);
339                 H2_PostEvent(&event);
340         }
341         break;
342
343       case SDL_KEYUP:
344         event.type = ev_keyup;
345         event.data1 = xlatekey(&Event->key.keysym);
346         H2_PostEvent(&event);
347         break;
348
349       case SDL_MOUSEBUTTONDOWN:
350       case SDL_MOUSEBUTTONUP:
351         buttonstate = SDL_GetMouseState(NULL, NULL);
352         event.type = ev_mouse;
353         event.data1 = 0
354             | (buttonstate & SDL_BUTTON(1) ? 1 : 0)
355             | (buttonstate & SDL_BUTTON(2) ? 2 : 0)
356             | (buttonstate & SDL_BUTTON(3) ? 4 : 0);
357         event.data2 = event.data3 = 0;
358         H2_PostEvent(&event);
359         break;
360
361       case SDL_MOUSEMOTION:
362         /* Ignore mouse warp events */
363         if ( (Event->motion.x != SCREENWIDTH/2) ||
364              (Event->motion.y != SCREENHEIGHT/2) )
365         {
366             /* Warp the mouse back to the center */
367             event.type = ev_mouse;
368             event.data1 = 0
369                 | (Event->motion.state & SDL_BUTTON(1) ? 1 : 0)
370                 | (Event->motion.state & SDL_BUTTON(2) ? 2 : 0)
371                 | (Event->motion.state & SDL_BUTTON(3) ? 4 : 0);
372             event.data2 = Event->motion.xrel << 3;
373             event.data3 = -Event->motion.yrel << 3;
374             H2_PostEvent(&event);
375         }
376         break;
377
378       case SDL_QUIT:
379         I_Quit();
380     }
381
382 }
383
384 //
385 // I_StartTic
386 //
387 void I_StartTic (void)
388 {
389     SDL_Event Event;
390
391     while ( SDL_PollEvent(&Event) )
392         I_GetEvent(&Event);
393 }
394
395
396 /*
397 ============================================================================
398
399                                         TIMER INTERRUPT
400
401 ============================================================================
402 */
403
404
405 /*
406 ================
407 =
408 = I_TimerISR
409 =
410 ================
411 */
412
413 int I_TimerISR (void)
414 {
415         ticcount++;
416         return 0;
417 }
418
419 /*
420 ============================================================================
421
422                                                         MOUSE
423
424 ============================================================================
425 */
426
427 /*
428 ================
429 =
430 = StartupMouse
431 =
432 ================
433 */
434
435 void I_StartupMouse (void)
436 {
437         mousepresent = 1;
438 }
439
440 static int makeUniqueFilename( char* filename )
441 {
442     int i;
443
444     for( i = 0; i < 100; i++ )
445     {
446         sprintf( filename, "hexen%02d.bmp", i );
447
448         if( access( filename, F_OK ) == -1 )
449         {
450             // It does not exist.
451             return 1;
452         }
453     }
454
455     return 0;
456 }
457
458 void GrabScreen ()
459 {
460     SDL_Surface *image;
461     SDL_Surface *temp;
462     int idx;
463     char filename[80];
464
465     if (makeUniqueFilename(filename)) {
466         image = SDL_CreateRGBSurface(SDL_SWSURFACE, screenWidth, screenHeight,
467                                     24, 0x0000FF, 0x00FF00, 0xFF0000,0xFFFFFF);
468         temp = SDL_CreateRGBSurface(SDL_SWSURFACE, screenWidth, screenHeight,
469                                     24, 0x0000FF, 0x00FF00, 0xFF0000, 0xFFFFFF);
470
471         glReadPixels(0, 0, screenWidth, screenHeight, GL_RGB,
472                      GL_UNSIGNED_BYTE, image->pixels);
473         for (idx = 0; idx < screenHeight; idx++)
474         {
475                memcpy(temp->pixels + 3 * screenWidth * idx,
476                         (char *)image->pixels + 3
477                         * screenWidth*(screenHeight - idx),
478                         3*screenWidth);
479         }
480         memcpy(image->pixels,temp->pixels,screenWidth * screenHeight * 3);
481         SDL_SaveBMP(image, filename);
482         SDL_FreeSurface(image);
483     }
484 }
485