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