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