1 #ifdef USE_SDL
2
3 #include <stdio.h>
4 #include <SDL.h>
5 #include <SDL_video.h>
6 #include <SDL_events.h>
7 #include "h2def.h"
8 #include "soundst.h"
9 #include "sdlvideo.h"
10
11 int SDLWidth;
12 int SDLHeight;
13 int SDLMaxWidth;
14 int SDLMaxHeight;
15 int SDLBPP;
16 int SDLVFlags=SDL_HWSURFACE | SDL_FULLSCREEN;
17 int WMAvailable;
18
19 Uint32 Rmask, Gmask, Bmask, Amask;
20 Uint8 Rshift, Gshift, Bshift, Ashift;
21 Uint8 Rloss, Gloss, Bloss, Aloss;
22 Uint32 colorkey;
23 Uint8 alpha;
24
25
26 SDL_Surface *Surface;
27 int unknown_surface;
28
29 static event_t event;
30 SDL_Overlay *Overlay;
31 SDL_Rect OvRect;
32
33 int mouse_scale_factor;
34 int save_buttons;
35 int grab_input;
36
37 extern int usemouse;
38
39 void (*SetSDLColors)(byte *);
40 void (*PaintOnSDLSurface)(void);
41
42 /* RGB palette for RGB rendering with direct color coding */
43
44 Uint32 Palette[256];
45
46 /* YUV palettes for YUV rendering */
47
48 int Ypal[256];
49 int Upal[256];
50 int Vpal[256];
51 int YUVPaletteChanged;
52
53
SetSDLColorsDirect(byte * palette)54 void SetSDLColorsDirect(byte *palette) {
55 Uint32 red,green,blue;
56 int i,j;
57 for (i=0,j=0 ; i<768 ; i+=3,j++)
58 {
59 red = gammatable[usegamma][palette[i]];
60 green = gammatable[usegamma][palette[i+1]];
61 blue = gammatable[usegamma][palette[i+2]];
62 red>>=Rloss;
63 green>>=Gloss;
64 blue>>=Bloss;
65 Palette[j]=((red<<Rshift)&Rmask)|((green<<Gshift)&Gmask)|((blue<<Bshift)&Bmask);
66 }
67 }
68
SetSDLColorsFor8bit(byte * palette)69 void SetSDLColorsFor8bit(byte *palette) {
70 SDL_Color c[256];
71 Uint32 red,green,blue;
72 int i,j;
73 for (i=0,j=0 ; i<768 ; i+=3,j++)
74 {
75 red = gammatable[usegamma][palette[i]];
76 green = gammatable[usegamma][palette[i+1]];
77 blue = gammatable[usegamma][palette[i+2]];
78 c[j].r=red;
79 c[j].g=green;
80 c[j].b=blue;
81 }
82 SDL_SetColors(Surface, c, 0, 256);
83 }
84
SetSDLColorsYUV(byte * palette)85 void SetSDLColorsYUV(byte *palette) {
86 Uint32 red,green,blue;
87 int i,j;
88 for (i=0,j=0 ; i<768 ; i+=3,j++)
89 {
90 red = gammatable[usegamma][palette[i]];
91 green = gammatable[usegamma][palette[i+1]];
92 blue = gammatable[usegamma][palette[i+2]];
93 Ypal[j]=0.257*red+0.504*green+0.098*blue+16;
94 Upal[j]=-0.148*red-0.291*green+0.439*blue+128;
95 Vpal[j]=0.439*red-0.368*green-0.071*blue+128;
96 }
97 YUVPaletteChanged=1;
98 }
99
PaintOnSDLSurface1(void)100 void PaintOnSDLSurface1(void) {
101 int i,j,dx,dy;
102 Uint8 *s,*os;
103 Uint8 *d;
104
105 SDL_LockSurface(Surface);
106 s=screen;
107 d=(Uint8 *)Surface->pixels;
108 dy=0;
109 for (i=0;i<SDLHeight;i++) {
110 dx=0;
111 os=s;
112 for (j=0;j<SDLWidth;j++) {
113 *d++=*s;
114 if ((dx+=WIDTH)>=SDLWidth) { dx-=SDLWidth; s++; }
115 }
116 s=os;
117 if ((dy+=HEIGHT)>=SDLHeight) { dy-=SDLHeight; s+=WIDTH; }
118 }
119 SDL_UnlockSurface(Surface);
120 SDL_UpdateRect(Surface,0,0,0,0);
121 }
122
123
PaintOnSDLSurface2(void)124 void PaintOnSDLSurface2(void) {
125 int i,j,dx,dy;
126 Uint8 *s,*os;
127 Uint16 *d;
128
129 SDL_LockSurface(Surface);
130 s=screen;
131 d=(Uint16 *)Surface->pixels;
132 dy=0;
133 for (i=0;i<SDLHeight;i++) {
134 dx=0;
135 os=s;
136 for (j=0;j<SDLWidth;j++) {
137 *d++=(Uint16)Palette[*s];
138 if ((dx+=WIDTH)>=SDLWidth) { dx-=SDLWidth; s++; }
139 }
140 s=os;
141 if ((dy+=HEIGHT)>=SDLHeight) { dy-=SDLHeight; s+=WIDTH; }
142 }
143 SDL_UnlockSurface(Surface);
144 SDL_UpdateRect(Surface,0,0,0,0);
145 }
146
PaintOnSDLSurface3(void)147 void PaintOnSDLSurface3(void) {
148 int i,j,dx,dy;
149 Uint8 *s,*os;
150 Uint8 *d;
151 union palent {
152 Uint32 i;
153 Uint8 b[4];
154 } pe;
155
156 SDL_LockSurface(Surface);
157 s=screen;
158 d=(Uint8 *)Surface->pixels;
159 dy=0;
160 for (i=0;i<SDLHeight;i++) {
161 dx=0;
162 os=s;
163 for (j=0;j<SDLWidth;j++) {
164 pe.i=Palette[*s];
165 *d++=pe.b[0];
166 *d++=pe.b[1];
167 *d++=pe.b[2];
168 if ((dx+=WIDTH)>=SDLWidth) { dx-=SDLWidth; s++; }
169 }
170 s=os;
171 if ((dy+=HEIGHT)>=SDLHeight) { dy-=SDLHeight; s+=WIDTH; }
172 }
173 SDL_UnlockSurface(Surface);
174 SDL_UpdateRect(Surface,0,0,0,0);
175 }
176
PaintOnSDLSurface4(void)177 void PaintOnSDLSurface4(void) {
178 int i,j,dx,dy;
179 Uint8 *s,*os;
180 Uint32 *d;
181
182 SDL_LockSurface(Surface);
183 s=screen;
184 d=(Uint32 *)Surface->pixels;
185 dy=0;
186 for (i=0;i<SDLHeight;i++) {
187 dx=0;
188 os=s;
189 for (j=0;j<SDLWidth;j++) {
190 *d++=Palette[*s];
191 if ((dx+=WIDTH)>=SDLWidth) { dx-=SDLWidth; s++; }
192 }
193 s=os;
194 if ((dy+=HEIGHT)>=SDLHeight) { dy-=SDLHeight; s+=WIDTH; }
195 }
196 SDL_UnlockSurface(Surface);
197 SDL_UpdateRect(Surface,0,0,0,0);
198 }
199
200
201
AdjustYUVPalette(void)202 void AdjustYUVPalette(void) {
203 /* int maxbits;
204 int i,j;
205 int minU,minV;
206
207 maxbits=0;
208 minU=0; minV=0;
209
210 for (i=0;i<256;i++) {
211 if (Upal[i]<minU) minU=Upal[i];
212 if (Vpal[i]<minU) minU=Vpal[i];
213 }
214
215
216 for (i=0;i<256;i++) {
217 Upal[i]-=minU;
218 Vpal[i]-=minU;
219 }
220
221 for(i=0;i<256;i++) {
222 for(j=31;j>0;j--)
223 if (Ypal[i]&(1<<j)) break;
224 if (j>maxbits) maxbits=j;
225 }
226
227 for(i=0;i<256;i++) {
228 for(j=31;j>0;j--)
229 if (Upal[i]&(1<<j)) break;
230 if (j>maxbits) maxbits=j;
231 }
232
233 for(i=0;i<256;i++) {
234 for(j=31;j>0;j--)
235 if (Vpal[i]&(1<<j)) break;
236 if (j>maxbits) maxbits=j;
237 }
238 printf("maxbits=%d\n",maxbits);*/
239 YUVPaletteChanged=0;
240 }
241
242
PaintYUVPlanes(Uint8 * Y,Uint8 * U,Uint8 * V)243 void PaintYUVPlanes(Uint8 *Y, Uint8 *U, Uint8 *V) {
244 int i,j,k,l;
245 Uint8 *s;
246 s=(Uint8 *)screen;
247 k=0; l=0;
248 for (i=0; i<HEIGHT; i++) {
249 for (j=0; j<WIDTH; j++) {
250 Y[k]=Y[k+1]=Y[k+WIDTH*2]=Y[k+WIDTH*2+1]=Ypal[*s];
251 U[l]=Upal[*s];
252 V[l]=Vpal[*s];
253 l++; k+=2;
254 s++;
255 }
256 k+=WIDTH*2;
257 }
258 }
259
PaintOnSDLSurfaceIYUV(void)260 void PaintOnSDLSurfaceIYUV(void) {
261 if (YUVPaletteChanged) AdjustYUVPalette();
262 SDL_LockYUVOverlay(Overlay);
263 PaintYUVPlanes(Overlay->pixels[0],Overlay->pixels[1],Overlay->pixels[2]);
264 SDL_UnlockYUVOverlay(Overlay);
265 SDL_DisplayYUVOverlay(Overlay,&OvRect);
266 }
267
PaintOnSDLSurfaceYV12(void)268 void PaintOnSDLSurfaceYV12(void) {
269 if (YUVPaletteChanged) AdjustYUVPalette();
270 SDL_LockYUVOverlay(Overlay);
271 PaintYUVPlanes(Overlay->pixels[0],Overlay->pixels[2],Overlay->pixels[1]);
272 SDL_UnlockYUVOverlay(Overlay);
273 SDL_DisplayYUVOverlay(Overlay,&OvRect);
274 }
275
276
I_TrySDLOverlay(Uint32 format)277 int I_TrySDLOverlay(Uint32 format) {
278 Overlay=SDL_CreateYUVOverlay(WIDTH*2,HEIGHT*2,format,Surface);
279 if (!Overlay->hw_overlay) {
280 SDL_FreeYUVOverlay(Overlay);
281 Overlay=NULL;
282 return 0;
283 }
284 return 1;
285 }
286
I_InitSDLOverlay(void)287 void I_InitSDLOverlay(void) {
288 if (I_TrySDLOverlay(SDL_IYUV_OVERLAY)) {
289 PaintOnSDLSurface=PaintOnSDLSurfaceIYUV;
290 printf("Using IYUV accelerated blits.\n");
291 return;
292 }
293 if (I_TrySDLOverlay(SDL_YV12_OVERLAY)) {
294 PaintOnSDLSurface=PaintOnSDLSurfaceYV12;
295 printf("Using YV12 accelerated blits.\n");
296 return;
297 }
298 printf("No YUV acceleration supported.\n");
299 }
300
VSDL_InitGraphics(void)301 int VSDL_InitGraphics(void) {
302 char drvname[256];
303 SDL_Rect **modes;
304 int i;
305 int wid, hei;
306 SDL_VideoInfo *vinfo;
307
308 unknown_surface=0;
309
310 if (M_CheckParm("-windowed"))
311 SDLVFlags&=~SDL_FULLSCREEN;
312
313 vinfo=SDL_GetVideoInfo();
314 if (!vinfo)
315 {
316 printf("SDL: Cannot obtain video info!\n");
317 return 0;
318 }
319 SDLBPP=vinfo->vfmt->BitsPerPixel;
320 WMAvailable=(int)vinfo->wm_available;
321
322 switch (vinfo->vfmt->BytesPerPixel) {
323 case 2:
324 SetSDLColors=SetSDLColorsDirect;
325 PaintOnSDLSurface=PaintOnSDLSurface2;
326 break;
327 case 4:
328 SetSDLColors=SetSDLColorsDirect;
329 PaintOnSDLSurface=PaintOnSDLSurface4;
330 break;
331 case 3:
332 SetSDLColors=SetSDLColorsDirect;
333 PaintOnSDLSurface=PaintOnSDLSurface3;
334 break;
335 case 1:
336 SDLVFlags|=SDL_HWPALETTE;
337 SetSDLColors=SetSDLColorsFor8bit;
338 PaintOnSDLSurface=PaintOnSDLSurface1;
339 break;
340 default:
341 unknown_surface=1;
342 SDLBPP=8;
343 SetSDLColors=SetSDLColorsFor8bit;
344 PaintOnSDLSurface=PaintOnSDLSurface1;
345 printf("SDL video: This surface is unknown to me, trying 8 bpp.\n");
346 }
347
348 Rmask=vinfo->vfmt->Rmask;
349 Gmask=vinfo->vfmt->Gmask;
350 Bmask=vinfo->vfmt->Bmask;
351 Amask=vinfo->vfmt->Amask;
352
353 Rshift=vinfo->vfmt->Rshift;
354 Gshift=vinfo->vfmt->Gshift;
355 Bshift=vinfo->vfmt->Bshift;
356 Ashift=vinfo->vfmt->Ashift;
357
358 Rloss=vinfo->vfmt->Rloss;
359 Gloss=vinfo->vfmt->Gloss;
360 Bloss=vinfo->vfmt->Bloss;
361 Aloss=vinfo->vfmt->Aloss;
362
363 colorkey=vinfo->vfmt->colorkey;
364 alpha=vinfo->vfmt->alpha;
365
366 if (!SDL_VideoDriverName(drvname,256)) {
367 printf("SDL: No video driver attached\n");
368 return 0;
369 }
370
371 printf("SDL: Using video driver:%s\n",drvname);
372 modes=SDL_ListModes(NULL,SDLVFlags);
373
374 if (modes==(SDL_Rect **)0) {
375 printf("SDL: No video modes available!\n");
376 return 0;
377 }
378
379 /* Find the best resolution to render 320x200 picture.
380 Use 320x240 for realistic picture in windowed modes */
381
382 if (modes==(SDL_Rect **)-1) {
383 printf("SDL: All modes available\n");
384 SDLWidth=SDLMaxWidth=320;
385 SDLHeight=SDLMaxHeight=240;
386
387 if (M_CheckParm("-2")) {
388 SDLWidth*=2; SDLMaxWidth*=2;
389 SDLHeight*=2; SDLMaxHeight*=2;
390 }
391
392 if (M_CheckParm("-3")) {
393 SDLWidth*=3; SDLMaxWidth*=3;
394 SDLHeight*=3; SDLMaxHeight*=3;
395 }
396
397 if (M_CheckParm("-4")) {
398 SDLWidth*=4; SDLMaxWidth*=4;
399 SDLHeight*=4; SDLMaxHeight*=4;
400 }
401
402 }
403 else
404 {
405 SDLMaxWidth=SDLMaxHeight=wid=hei=0;
406 for (i=0; modes[i];i++) {
407 if (!wid) wid=modes[i]->w;
408 if (!hei) hei=modes[i]->h;
409 if ((wid>modes[i]->w && modes[i]->w>=320) ||
410 (hei>modes[i]->h && modes[i]->h>=240)) {
411 wid=modes[i]->w;
412 hei=modes[i]->h;
413 }
414 if ((SDLMaxWidth<modes[i]->w) || (SDLMaxHeight<modes[i]->h)) {
415 SDLMaxHeight=modes[i]->h;
416 SDLMaxWidth=modes[i]->w;
417 }
418 }
419 SDLWidth=wid;
420 SDLHeight=hei;
421 if (!SDLWidth || !SDLHeight) {
422 printf("SDL: Can't set video mode");
423 return 0;
424 }
425 }
426 printf("Found best mode: %dx%dx%d\n",SDLWidth,SDLHeight,SDLBPP);
427 Surface=SDL_SetVideoMode(SDLWidth, SDLHeight, SDLBPP, SDLVFlags);
428
429 if (!Surface) {
430 /* We cannot set video mode with desired parameters. Try to rely on SDL's
431 knowledge about it */
432 unknown_surface=1;
433 SDLBPP=8;
434 SDLVFlags|=SDL_HWPALETTE;
435 Surface=SDL_SetVideoMode(SDLWidth, SDLHeight, SDLBPP, SDLVFlags);
436 if (Surface) goto success;
437 SDLVFlags&=~SDL_HWPALETTE;
438 Surface=SDL_SetVideoMode(SDLWidth, SDLHeight, SDLBPP, SDLVFlags);
439 if (Surface) goto success;
440 SDLVFlags&=~SDL_HWSURFACE;
441 Surface=SDL_SetVideoMode(SDLWidth, SDLHeight, SDLBPP, SDLVFlags);
442 if (Surface) goto success;
443 /* Give up */
444 printf("SDL: Can't set video mode!\n");
445 return 0;
446 }
447
448 if ((SDLMaxWidth>=WIDTH*2 || SDLMaxHeight>=HEIGHT*2) && !unknown_surface) {
449 I_InitSDLOverlay();
450 if (Overlay) {
451 SetSDLColors=SetSDLColorsYUV;
452 SDLWidth=SDLMaxWidth;
453 SDLHeight=SDLMaxHeight;
454 OvRect.x=OvRect.y=0;
455 OvRect.w=SDLWidth;
456 OvRect.h=SDLHeight;
457 Surface=SDL_SetVideoMode(SDLWidth, SDLHeight, SDLBPP, SDLVFlags);
458 }
459 }
460
461 success:
462 if (WMAvailable) {
463 SDL_WM_SetCaption("U-Hexen 0.6",NULL);
464 if(M_CheckParm("-nograb")) {
465 grab_input = 0;
466 }
467 else {
468 grab_input = 1;
469 SDL_WM_GrabInput(SDL_GRAB_ON);
470 }
471 }
472 SDL_WarpMouse(SDLWidth/2,SDLHeight/2);
473 SDL_ShowCursor(SDL_DISABLE);
474 return 1;
475 }
476
VSDL_ShutdownGraphics(void)477 void VSDL_ShutdownGraphics(void)
478 {
479 if (WMAvailable) {
480 if(grab_input == 1) SDL_WM_GrabInput(SDL_GRAB_OFF);
481 }
482 }
483
VSDL_GetEvent(void)484 void VSDL_GetEvent(void)
485 {
486 SDL_Event Event;
487 while (SDL_PollEvent(&Event)) {
488
489 switch(Event.type) {
490 case SDL_KEYUP:
491 case SDL_KEYDOWN:
492 switch(Event.key.keysym.sym) {
493 case SDLK_UP:
494 case SDLK_KP8:
495 event.data1=KEY_UPARROW; break;
496
497 case SDLK_DOWN:
498 case SDLK_KP2:
499 event.data1=KEY_DOWNARROW; break;
500
501 case SDLK_RIGHT:
502 case SDLK_KP6:
503 event.data1=KEY_RIGHTARROW; break;
504
505 case SDLK_LEFT:
506 case SDLK_KP4:
507 event.data1=KEY_LEFTARROW; break;
508
509 case SDLK_HOME:
510 case SDLK_KP7:
511 event.data1=KEY_HOME; break;
512
513 case SDLK_PAGEUP:
514 case SDLK_KP9:
515 event.data1=KEY_PGUP; break;
516
517 case SDLK_PAGEDOWN:
518 case SDLK_KP3:
519 event.data1=KEY_PGDN; break;
520
521 case SDLK_END:
522 case SDLK_KP1:
523 event.data1=KEY_END; break;
524
525 case SDLK_RSHIFT:
526 case SDLK_LSHIFT:
527 event.data1=KEY_RSHIFT; break;
528
529 case SDLK_RCTRL:
530 case SDLK_LCTRL:
531 event.data1=KEY_RCTRL; break;
532
533 case SDLK_RALT:
534 case SDLK_LALT:
535 event.data1=KEY_RALT; break;
536
537 case SDLK_F1:
538 event.data1=KEY_F1; break;
539 case SDLK_F2:
540 event.data1=KEY_F2; break;
541 case SDLK_F3:
542 event.data1=KEY_F3; break;
543 case SDLK_F4:
544 event.data1=KEY_F4; break;
545 case SDLK_F5:
546 event.data1=KEY_F5; break;
547 case SDLK_F6:
548 event.data1=KEY_F6; break;
549 case SDLK_F7:
550 event.data1=KEY_F7; break;
551 case SDLK_F8:
552 event.data1=KEY_F8; break;
553 case SDLK_F9:
554 event.data1=KEY_F9; break;
555 case SDLK_F10:
556 event.data1=KEY_F10; break;
557 case SDLK_F11:
558 event.data1=KEY_F11; break;
559 case SDLK_F12:
560 event.data1=KEY_F12; break;
561
562 default:
563 event.data1=Event.key.keysym.sym;
564
565 }
566 event.type=Event.type==SDL_KEYDOWN ? ev_keydown : ev_keyup;
567 H2_PostEvent(&event);
568 break;
569 case SDL_MOUSEBUTTONUP:
570 if (!usemouse) break;
571 event.data1=0;
572 switch(Event.button.button) {
573 case SDL_BUTTON_LEFT:
574 event.data1&=1; break;
575 case SDL_BUTTON_RIGHT:
576 event.data1&=~4; break;
577 case SDL_BUTTON_MIDDLE:
578 event.data1&=~2; break;
579 }
580 save_buttons=event.data1;
581 event.data2=0;
582 event.data3=0;
583 event.type=ev_mouse;
584 H2_PostEvent(&event);
585 break;
586 case SDL_MOUSEBUTTONDOWN:
587 if (!usemouse) break;
588 event.data1=0;
589 switch(Event.button.button) {
590 case SDL_BUTTON_LEFT:
591 event.data1|=1; break;
592 case SDL_BUTTON_RIGHT:
593 event.data1|=4; break;
594 case SDL_BUTTON_MIDDLE:
595 event.data1|=2; break;
596 }
597 save_buttons=event.data1;
598 event.data2=0;
599 event.data3=0;
600 event.type=ev_mouse;
601 H2_PostEvent(&event);
602 break;
603 case SDL_MOUSEMOTION:
604 if (!usemouse) break;
605 event.data1=save_buttons;
606 if (Event.motion.x==SDLWidth/2 && Event.motion.y==SDLHeight/2) break;
607 if ((event.data2=(Event.motion.xrel)*mouse_scale_factor) ||
608 (event.data3=(-Event.motion.yrel)*mouse_scale_factor)) {
609 if(grab_input == 1) SDL_WarpMouse(SDLWidth/2,SDLHeight/2);
610 event.type=ev_mouse;
611 H2_PostEvent(&event);
612 }
613 break;
614 }
615 }
616 }
617
618
VSDL_FinishUpdate(void)619 void VSDL_FinishUpdate(void)
620 {
621 PaintOnSDLSurface();
622 SDL_Delay(10); /* give time to another threads */
623 }
624
VSDL_SetPalette(byte * palette)625 void VSDL_SetPalette(byte *palette)
626 {
627 SetSDLColors(palette);
628 }
629
630 #endif
VSDL_Stub(void)631 void VSDL_Stub(void)
632 {
633
634 }
635