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