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