]> icculus.org git repositories - btb/d2x.git/blob - arch/win32/vid.c
more header cleanup
[btb/d2x.git] / arch / win32 / vid.c
1 // Windows video functions.
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <windows.h>
7 #include <wtypes.h>
8 #include <ddraw.h>
9 #ifdef __GCC__
10 #include <Windows32/Errors.h>
11 #endif
12
13 #include "gr.h"
14 #include "u_mem.h"
15 #include "error.h"
16 #include "vers_id.h"
17 #include "gamefont.h"
18
19 //added 10/05/98 by Matt Mueller - make fullscreen mode optional
20 #include "args.h"
21
22 //removed 07/11/99 by adb - now option
23 ////added 02/20/99 by adb - put descent in a window, sort of. Needed for debugging
24 ////(needs a 256 color mode to be useful)
25 //#ifndef NDEBUG
26 //#define DD_NOT_EXCL
27 //#endif
28 //end remove - adb
29
30 char *backbuffer = NULL;
31
32 int vid_installed = 0;
33
34 // Min without sideeffects.
35 #ifdef _MSC_VER
36 #define inline __inline
37 #endif
38
39 #undef min
40 inline static int min(int x, int y) { return x < y ? x : y; }
41
42 // Windows specific
43 HINSTANCE hInst;
44 HWND g_hWnd;
45 LPDIRECTDRAW            lpDD;           
46 LPDIRECTDRAWSURFACE     lpDDSPrimary;   
47 LPDIRECTDRAWSURFACE     lpDDSOne;       
48 LPDIRECTDRAWPALETTE     lpDDPal;
49 PALETTEENTRY pe[256];
50
51 //added 02/20/99 by adb - put descent in a window, sort of. Needed for debugging
52 //(needs a 256 color mode to be useful)
53 //#define DD_NOT_EXCL
54
55 void gr_palette_clear(); // Function prototype for vid_init;
56
57
58 static char *DDerror(int code)
59 {
60         static char *error;
61         switch (code) {
62 /*                case DDERR_GENERIC:
63                         error = "Undefined error!";
64                         break;*/
65                 case DDERR_EXCEPTION:
66                         error = "Exception encountered";
67                         break;
68                 case DDERR_INVALIDOBJECT:
69                         error = "Invalid object";
70                         break;
71 /*                case DDERR_INVALIDPARAMS:
72                         error = "Invalid parameters";
73                         break;*/
74                 case DDERR_NOTFOUND:
75                         error = "Object not found";
76                         break;
77                 case DDERR_INVALIDRECT:
78                         error = "Invalid rectangle";
79                         break;
80                 case DDERR_INVALIDCAPS:
81                         error = "Invalid caps member";
82                         break;
83                 case DDERR_INVALIDPIXELFORMAT:
84                         error = "Invalid pixel format";
85                         break;
86 /*                case DDERR_OUTOFMEMORY:
87                         error = "Out of memory";
88                         break;*/
89                 case DDERR_OUTOFVIDEOMEMORY:
90                         error = "Out of video memory";
91                         break;
92                 case DDERR_SURFACEBUSY:
93                         error = "Surface busy";
94                         break;
95                 case DDERR_SURFACELOST:
96                         error = "Surface was lost";
97                         break;
98                 case DDERR_WASSTILLDRAWING:
99                         error = "DirectDraw is still drawing";
100                         break;
101                 case DDERR_INVALIDSURFACETYPE:
102                         error = "Invalid surface type";
103                         break;
104                 case DDERR_NOEXCLUSIVEMODE:
105                         error = "Not in exclusive access mode";
106                         break;
107                 case DDERR_NOPALETTEATTACHED:
108                         error = "No palette attached";
109                         break;
110                 case DDERR_NOPALETTEHW:
111                         error = "No palette hardware";
112                         break;
113                 case DDERR_NOT8BITCOLOR:
114                         error = "Not 8-bit color";
115                         break;
116                 case DDERR_EXCLUSIVEMODEALREADYSET:
117                         error = "Exclusive mode was already set";
118                         break;
119                 case DDERR_HWNDALREADYSET:
120                         error = "Window handle already set";
121                         break;
122                 case DDERR_HWNDSUBCLASSED:
123                         error = "Window handle is subclassed";
124                         break;
125                 case DDERR_NOBLTHW:
126                         error = "No blit hardware";
127                         break;
128                 case DDERR_IMPLICITLYCREATED:
129                         error = "Surface was implicitly created";
130                         break;
131                 case DDERR_INCOMPATIBLEPRIMARY:
132                         error = "Incompatible primary surface";
133                         break;
134                 case DDERR_NOCOOPERATIVELEVELSET:
135                         error = "No cooperative level set";
136                         break;
137                 case DDERR_NODIRECTDRAWHW:
138                         error = "No DirectDraw hardware";
139                         break;
140                 case DDERR_NOEMULATION:
141                         error = "No emulation available";
142                         break;
143                 case DDERR_NOFLIPHW:
144                         error = "No flip hardware";
145                         break;
146                 case DDERR_NOTFLIPPABLE:
147                         error = "Surface not flippable";
148                         break;
149                 case DDERR_PRIMARYSURFACEALREADYEXISTS:
150                         error = "Primary surface already exists";
151                         break;
152                 case DDERR_UNSUPPORTEDMODE:
153                         error = "Unsupported mode";
154                         break;
155                 case DDERR_WRONGMODE:
156                         error = "Surface created in different mode";
157                         break;
158 /*                case DDERR_UNSUPPORTED:
159                         error = "Operation not supported";
160                         break;*/
161                 default:
162                 error = "unknown";
163                         break;
164         }
165         return error;
166 }
167
168
169 void vid_update()
170 {
171   DDSURFACEDESC       ddsd;
172   HRESULT             ddrval;
173   int i;
174   int w, h;
175   char *j;
176   char *k;
177
178   ddsd.dwSize=sizeof(ddsd);
179   ddrval=IDirectDrawSurface_Lock(lpDDSPrimary,NULL,&ddsd,0,NULL);
180   if (ddrval!=DD_OK) {
181    printf("lock failed, %s\n", DDerror(ddrval));
182    Assert(ddrval==DD_OK);
183   }
184
185   j=backbuffer; k=ddsd.lpSurface;
186   h=grd_curscreen->sc_canvas.cv_bitmap.bm_h;
187   w=grd_curscreen->sc_canvas.cv_bitmap.bm_w;
188   for (i=0; i<h; i++) {
189     memcpy(k, j, w);
190   j+=grd_curscreen->sc_canvas.cv_bitmap.bm_rowsize;
191   //j+=ddsd.dwWidth;
192 #ifdef NONAMELESSUNION
193   k+=ddsd.u1.lPitch;
194 #else
195   k+=ddsd.lPitch;
196 #endif
197   }
198   IDirectDrawSurface_Unlock(lpDDSPrimary,NULL);
199 /*   while (1)
200  {
201    ddrval=IDirectDrawSurface_Flip(lpDDSPrimary,NULL,0);
202    if (ddrval == DD_OK)
203    {
204      printf("Flip was successful\n");
205      break;
206    }
207    if (ddrval == DDERR_SURFACELOST)
208    {
209       printf("surface was lost\n");
210      ddrval=IDirectDrawSurface_Restore(lpDDSPrimary);
211      if (ddrval != DD_OK)
212      {
213        printf("restore failed\n"); 
214        break;
215      }
216    }
217    if (ddrval == DDERR_WASSTILLDRAWING )
218    {
219      printf("was still drawing\n");
220      break;
221    }
222  }*/
223 }
224
225
226 int vid_set_mode(uint32_t mode)
227 {
228         DDSURFACEDESC       ddsd;
229 //        DDSURFACEDESC       DDSDesc;
230 //        DDSCAPS             ddcaps;
231         HRESULT             ddrval;
232         unsigned int w,h;
233         
234         if (mode<=0)
235                 return 0;
236
237         w=SM_W(mode);
238         h=SM_H(mode);
239
240         if(lpDDSPrimary!=NULL)
241         {
242             IDirectDrawSurface_Release(lpDDSPrimary);
243             lpDDSPrimary=NULL;
244         }
245
246         if (backbuffer) free(backbuffer);
247
248
249         //changed 07/11/99 by adb - nonfullscreen mode now option
250         if (!FindArg("-semiwin"))
251         {
252         ddrval=IDirectDraw_SetDisplayMode(lpDD,w,h,8);
253
254         if (ddrval!=DD_OK)
255         {
256           fprintf(stderr, "Hmmm... I had a problem changing screen modes... is %ix%ix8 supported? If so, try again... :-( %s\n",w,h, DDerror(ddrval));
257           return -3; // This is **not** good...
258         }
259         }
260         //end changes - adb
261        ddsd.dwSize=sizeof(ddsd);
262        ddsd.dwFlags=DDSD_CAPS /*| DDSD_BACKBUFFERCOUNT*/;
263        ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE /*| DDSCAPS_FLIP | DDSCAPS_COMPLEX*/;
264        //ddsd.dwBackBufferCount=1;
265
266        ddrval=IDirectDraw_CreateSurface(lpDD,&ddsd,&lpDDSPrimary,NULL);
267        if(ddrval!=DD_OK)
268        {
269         return -4;
270        }
271
272 #if 0
273        memset(&ddcaps,0,sizeof(ddcaps));
274 //       ddcaps.dwSize=sizeof(ddcaps);
275        ddcaps.dwCaps=DDSCAPS_BACKBUFFER;
276
277        ddrval=IDirectDrawSurface_GetAttachedSurface(lpDDSPrimary,&ddcaps,&lpDDSOne);
278        Assert(ddrval==DD_OK);
279        if(lpDDSOne==NULL)
280        {
281          return -5;
282        }
283 #endif
284
285        ddrval=IDirectDraw_CreatePalette(lpDD,DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,pe,&lpDDPal,NULL);
286        Assert(ddrval==DD_OK);
287        if(ddrval!=DD_OK)
288        {
289          return FALSE;
290        }
291
292        IDirectDrawSurface_SetPalette(lpDDSPrimary,lpDDPal);
293 //       IDirectDrawSurface_SetPalette(lpDDSOne,lpDDPal);
294
295        gr_palette_clear();
296
297        backbuffer = malloc(w*h);
298        memset(backbuffer, 0, w*h);
299        gr_init_screen(BM_LINEAR, w, h, 0 0, w, (unsigned char *)backbuffer);
300
301        ddsd.dwSize=sizeof(ddsd);
302        ddrval=IDirectDrawSurface_Lock(lpDDSPrimary,NULL,&ddsd,0,NULL);
303        if(ddrval!=DD_OK)
304        {
305         return -6;
306        }
307        
308        memset(ddsd.lpSurface,0,w*h); // Black the canvas out to stop nasty kludgy display
309        IDirectDrawSurface_Unlock(lpDDSPrimary,NULL);
310
311            gamefont_choose_game_font(w,h);
312
313        printf("Successfully completed set_mode\n");
314        return 0;
315 }
316
317
318
319 void Win32_DoSetPalette (PALETTEENTRY *rgpe)
320 {
321         IDirectDraw_WaitForVerticalBlank(lpDD,DDWAITVB_BLOCKBEGIN,NULL);
322         IDirectDrawPalette_SetEntries(lpDDPal,0,0,256,rgpe);
323 }
324
325 void Win32_DoGetPalette (PALETTEENTRY *rgpe)
326 {
327         IDirectDrawPalette_GetEntries(lpDDPal,0,0,256,rgpe);
328 }
329
330 //added 07/11/99 by adb for d3d
331 void Win32_MakePalVisible(void)
332 {
333 }
334 //end additions - adb
335
336
337 void vid_close(void);
338
339
340 int vid_init(int mode)
341 {
342  int retcode;
343         // Only do this function once!
344         if (vid_installed == 1)
345                 return -1;
346
347         // Set the mode.
348         if ((retcode = vid_set_mode(mode))) {
349                 return retcode;
350         }
351
352         vid_installed = 1;
353         // added on 980913 by adb to add cleanup
354         atexit(vid_close);
355         // end changes by adb
356
357         return 0;
358 }
359
360
361 void vid_close(void)
362 {
363         if (vid_installed == 1)
364         {
365                 vid_installed = 0;
366                 free(grd_curscreen);
367                 free(backbuffer);
368         }
369 }
370
371