]> icculus.org git repositories - theoddone33/hheretic.git/blob - sdl/i_sdl.c
Get rid of autoconf, the abomination.
[theoddone33/hheretic.git] / sdl / i_sdl.c
1 //**************************************************************************
2 //**
3 //** $Id$
4 //**
5 //**************************************************************************
6
7
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include <sys/time.h>
11 #include <SDL/SDL.h> 
12 #include "doomdef.h"
13 #include "r_local.h"
14 #include "p_local.h"    // for P_AproxDistance
15 #include "sounds.h"
16 #include "i_sound.h"
17 #include "soundst.h"
18
19 // Public Data
20
21 int DisplayTicker = 0;
22
23
24 // Code
25
26 void I_StartupNet (void);
27 void I_ShutdownNet (void);
28 void I_ReadExternDriver(void);
29 void GrabScreen (void);
30
31 extern int usemouse, usejoystick;
32
33 extern void **lumpcache;
34
35 int i_Vector;
36 externdata_t *i_ExternData;
37 boolean useexterndriver;
38
39 SDL_Surface* sdl_screen;
40 int grabMouse;
41
42 boolean mousepresent;
43
44 //===============================
45
46 int ticcount;
47
48
49 boolean novideo; // if true, stay in text mode for debugging
50
51 #define KEY_INS         0x52
52 #define KEY_DEL         0x53
53 #define KEY_PGUP        0x49
54 #define KEY_PGDN        0x51
55 #define KEY_HOME        0x47
56 #define KEY_END         0x4f
57
58 /*
59 ============================================================================
60
61                                                                 USER INPUT
62
63 ============================================================================
64 */
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     SDL_Color* c;
95     SDL_Color* cend;
96     SDL_Color cmap[ 256 ];
97
98         if(novideo)
99         {
100                 return;
101         }
102         I_WaitVBL(1);
103
104     c = cmap;
105     cend = c + 256;
106         for( ; c != cend; c++ )
107         {
108                 //_outbyte(PEL_DATA, (gammatable[usegamma][*palette++])>>2);
109
110         c->r = gammatable[usegamma][*palette++];
111         c->g = gammatable[usegamma][*palette++];
112         c->b = gammatable[usegamma][*palette++];
113         }
114     SDL_SetColors( sdl_screen, cmap, 0, 256 );
115 }
116
117 /*
118 ============================================================================
119
120                                                         GRAPHICS MODE
121
122 ============================================================================
123 */
124
125 byte *pcscreen, *destscreen, *destview;
126
127 /*
128 ==============
129 =
130 = I_Update
131 =
132 ==============
133 */
134
135 int UpdateState;
136 extern int screenblocks;
137
138 void I_Update (void)
139 {
140         int i;
141         byte *dest;
142         int tics;
143         static int lasttic;
144
145 //
146 // blit screen to video
147 //
148         if(DisplayTicker)
149         {
150                 if(screenblocks > 9 || UpdateState&(I_FULLSCRN|I_MESSAGES))
151                 {
152                         dest = (byte *)screen;
153                 }
154                 else
155                 {
156                         dest = (byte *)pcscreen;
157                 }
158                 tics = ticcount-lasttic;
159                 lasttic = ticcount;
160                 if(tics > 20)
161                 {
162                         tics = 20;
163                 }
164                 for(i = 0; i < tics; i++)
165                 {
166                         *dest = 0xff;
167                         dest += 2;
168                 }
169                 for(i = tics; i < 20; i++)
170                 {
171                         *dest = 0x00;
172                         dest += 2;
173                 }
174         }
175
176         //memset(pcscreen, 255, SCREENHEIGHT*SCREENWIDTH);
177
178         if(UpdateState == I_NOUPDATE)
179         {
180                 return;
181         }
182         if(UpdateState&I_FULLSCRN)
183         {
184                 memcpy(pcscreen, screen, SCREENWIDTH*SCREENHEIGHT);
185                 UpdateState = I_NOUPDATE; // clear out all draw types
186
187         SDL_UpdateRect( sdl_screen, 0, 0, SCREENWIDTH, SCREENHEIGHT );
188         }
189         if(UpdateState&I_FULLVIEW)
190         {
191                 if(UpdateState&I_MESSAGES && screenblocks > 7)
192                 {
193                         for(i = 0; i <
194                                 (viewwindowy+viewheight)*SCREENWIDTH; i += SCREENWIDTH)
195                         {
196                                 memcpy(pcscreen+i, screen+i, SCREENWIDTH);
197                         }
198                         UpdateState &= ~(I_FULLVIEW|I_MESSAGES);
199
200             SDL_UpdateRect( sdl_screen, 0, 0, SCREENWIDTH,
201                             viewwindowy+viewheight );
202                 }
203                 else
204                 {
205                         for(i = viewwindowy*SCREENWIDTH+viewwindowx; i <
206                                 (viewwindowy+viewheight)*SCREENWIDTH; i += SCREENWIDTH)
207                         {
208                                 memcpy(pcscreen+i, screen+i, viewwidth);
209                         }
210                         UpdateState &= ~I_FULLVIEW;
211
212             SDL_UpdateRect( sdl_screen, viewwindowx, viewwindowy, viewwidth,
213                             viewheight );
214                 }
215         }
216         if(UpdateState&I_STATBAR)
217         {
218                 memcpy(pcscreen+SCREENWIDTH*(SCREENHEIGHT-SBARHEIGHT),
219                         screen+SCREENWIDTH*(SCREENHEIGHT-SBARHEIGHT),
220                         SCREENWIDTH*SBARHEIGHT);
221                 UpdateState &= ~I_STATBAR;
222
223         SDL_UpdateRect( sdl_screen, 0, SCREENHEIGHT-SBARHEIGHT,
224                         SCREENWIDTH, SBARHEIGHT );
225         }
226         if(UpdateState&I_MESSAGES)
227         {
228                 memcpy(pcscreen, screen, SCREENWIDTH*28);
229                 UpdateState &= ~I_MESSAGES;
230
231         SDL_UpdateRect( sdl_screen, 0, 0, SCREENWIDTH, 28 );
232         }
233 }
234
235 //--------------------------------------------------------------------------
236 //
237 // PROC I_InitGraphics
238 //
239 //--------------------------------------------------------------------------
240
241 void I_InitGraphics(void)
242 {
243         char text[20];
244
245         if( novideo )
246         {
247                 return;
248         }
249     
250     // SDL_DOUBLEBUF does not work in full screen mode.  Does not seem to
251     // be necessary anyway.
252
253     sdl_screen = SDL_SetVideoMode(SCREENWIDTH, SCREENHEIGHT, 8, SDL_SWSURFACE);
254                                    //SDL_HWSURFACE | SDL_FULLSCREEN );
255                                    //0 );
256     if( sdl_screen == NULL )
257     {
258         fprintf( stderr, "Couldn't set video mode %dx%d: %s\n",
259                  SCREENWIDTH, SCREENHEIGHT, SDL_GetError() );
260         exit( 3 );
261     }
262
263     if( SDL_MUSTLOCK( sdl_screen ) )
264     {
265         printf( "SDL_MUSTLOCK\n" );
266         exit( 4 );
267     }
268
269     // Only grab if we want to
270     if (M_CheckParm ("-nograb")) {
271             grabMouse = 0;
272     } else {
273             grabMouse = 1;
274             SDL_WM_GrabInput (1);
275     }
276
277     snprintf (text, 20, "HHeretic v%s", HHERETIC_VERSION);
278     SDL_ShowCursor( 0 );
279     SDL_WM_SetCaption( text, "HHERETIC" );
280
281
282         pcscreen = destscreen = sdl_screen->pixels;
283
284         I_SetPalette( W_CacheLumpName("PLAYPAL", PU_CACHE) );
285 }
286
287 //--------------------------------------------------------------------------
288 //
289 // PROC I_ShutdownGraphics
290 //
291 //--------------------------------------------------------------------------
292 extern byte *screen;
293
294 void I_ShutdownGraphics(void)
295 {
296         free (screen);
297         SDL_Quit ();
298 }
299
300 //--------------------------------------------------------------------------
301 //
302 // PROC I_ReadScreen
303 //
304 // Reads the screen currently displayed into a linear buffer.
305 //
306 //--------------------------------------------------------------------------
307
308 /*
309 void I_ReadScreen(byte *scr)
310 {
311         memcpy(scr, screen, SCREENWIDTH*SCREENHEIGHT);
312 }
313 */
314
315 //===========================================================================
316
317
318 //
319 //  Translates the key 
320 //
321
322 int xlatekey(SDL_keysym *key)
323 {
324
325     int rc;
326
327     switch(key->sym)
328     {
329       case SDLK_LEFT:   rc = KEY_LEFTARROW;     break;
330       case SDLK_RIGHT:  rc = KEY_RIGHTARROW;    break;
331       case SDLK_DOWN:   rc = KEY_DOWNARROW;     break;
332       case SDLK_UP:     rc = KEY_UPARROW;       break;
333       case SDLK_ESCAPE: rc = KEY_ESCAPE;        break;
334       case SDLK_RETURN: rc = KEY_ENTER;         break;
335       case SDLK_F1:     rc = KEY_F1;            break;
336       case SDLK_F2:     rc = KEY_F2;            break;
337       case SDLK_F3:     rc = KEY_F3;            break;
338       case SDLK_F4:     rc = KEY_F4;            break;
339       case SDLK_F5:     rc = KEY_F5;            break;
340       case SDLK_F6:     rc = KEY_F6;            break;
341       case SDLK_F7:     rc = KEY_F7;            break;
342       case SDLK_F8:     rc = KEY_F8;            break;
343       case SDLK_F9:     rc = KEY_F9;            break;
344       case SDLK_F10:    rc = KEY_F10;           break;
345       case SDLK_F11:    rc = KEY_F11;           break;
346       case SDLK_F12:    rc = KEY_F12;           break;
347         
348       case SDLK_INSERT: rc = KEY_INS;           break;
349       case SDLK_DELETE: rc = KEY_DEL;           break;
350       case SDLK_PAGEUP: rc = KEY_PGUP;          break;
351       case SDLK_PAGEDOWN: rc = KEY_PGDN;        break;
352       case SDLK_HOME:   rc = KEY_HOME;          break;
353       case SDLK_END:    rc = KEY_END;           break;
354
355       case SDLK_BACKSPACE: rc = KEY_BACKSPACE;  break;
356
357       case SDLK_PAUSE:  rc = KEY_PAUSE;         break;
358
359       case SDLK_EQUALS: rc = KEY_EQUALS;        break;
360
361       case SDLK_KP_MINUS:
362       case SDLK_MINUS:  rc = KEY_MINUS;         break;
363
364       case SDLK_LSHIFT:
365       case SDLK_RSHIFT:
366         rc = KEY_RSHIFT;
367         break;
368         
369       case SDLK_LCTRL:
370       case SDLK_RCTRL:
371         rc = KEY_RCTRL;
372         break;
373         
374       case SDLK_LALT:
375       case SDLK_LMETA:
376       case SDLK_RALT:
377       case SDLK_RMETA:
378         rc = KEY_RALT;
379         break;
380         
381       default:
382         rc = key->sym;
383         break;
384     }
385
386     return rc;
387
388 }
389
390
391 /* This processes SDL events */
392 void I_GetEvent(SDL_Event *Event)
393 {
394     Uint8 buttonstate;
395     event_t event;
396
397     switch (Event->type)
398     {
399       case SDL_KEYDOWN:
400         event.type = ev_keydown;
401         event.data1 = xlatekey(&Event->key.keysym);
402         D_PostEvent(&event);
403         break;
404
405       case SDL_KEYUP:
406         event.type = ev_keyup;
407         event.data1 = xlatekey(&Event->key.keysym);
408         D_PostEvent(&event);
409         break;
410
411       case SDL_MOUSEBUTTONDOWN:
412       case SDL_MOUSEBUTTONUP:
413         buttonstate = SDL_GetMouseState(NULL, NULL);
414         event.type = ev_mouse;
415         event.data1 = 0
416             | (buttonstate & SDL_BUTTON(1) ? 1 : 0)
417             | (buttonstate & SDL_BUTTON(2) ? 2 : 0)
418             | (buttonstate & SDL_BUTTON(3) ? 4 : 0);
419         event.data2 = event.data3 = 0;
420         D_PostEvent(&event);
421         break;
422
423       case SDL_MOUSEMOTION:
424         /* Ignore mouse warp events */
425         if ( (Event->motion.x != sdl_screen->w/2) ||
426              (Event->motion.y != sdl_screen->h/2) )
427         {
428             /* Warp the mouse back to the center */
429             if (grabMouse) {
430                 SDL_WarpMouse(sdl_screen->w/2, sdl_screen->h/2);
431             }
432             event.type = ev_mouse;
433             event.data1 = 0
434                 | (Event->motion.state & SDL_BUTTON(1) ? 1 : 0)
435                 | (Event->motion.state & SDL_BUTTON(2) ? 2 : 0)
436                 | (Event->motion.state & SDL_BUTTON(3) ? 4 : 0);
437             event.data2 = Event->motion.xrel << 3;
438             event.data3 = -Event->motion.yrel << 3;
439             D_PostEvent(&event);
440         }
441         break;
442
443       case SDL_QUIT:
444         I_Quit();
445     }
446
447 }
448
449 //
450 // I_StartTic
451 //
452 void I_StartTic (void)
453 {
454     SDL_Event Event;
455
456     while ( SDL_PollEvent(&Event) )
457         I_GetEvent(&Event);
458 }
459
460
461 /*
462 ============================================================================
463
464                                         TIMER INTERRUPT
465
466 ============================================================================
467 */
468
469
470 /*
471 ================
472 =
473 = I_TimerISR
474 =
475 ================
476 */
477
478 int I_TimerISR (void)
479 {
480         ticcount++;
481         return 0;
482 }
483
484 /*
485 ============================================================================
486
487                                                 KEYBOARD
488
489 ============================================================================
490 */
491
492 int lastpress;
493
494
495
496 /*
497 ============================================================================
498
499                                                         MOUSE
500
501 ============================================================================
502 */
503
504
505 /*
506 ================
507 =
508 = StartupMouse
509 =
510 ================
511 */
512
513
514 void I_StartupMouse (void)
515 {
516         mousepresent = 1;
517 }
518
519 void GrabScreen (void)
520 {
521 }