1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 /*
21 ** RW_DDRAW.C
22 **
23 ** This handles DirectDraw management under Windows.
24 */
25 #ifndef _WIN32
26 #  error You should not be compiling this file on this platform
27 #endif
28 
29 #ifndef USE_DDRAW
30 #  error You should not be compiling this file without USE_DDRAW defined
31 #endif
32 
33 #include "win_local.h"
34 #include "win_swimp.h"
35 
DDrawError(int code)36 static const char *DDrawError (int code) {
37     switch(code) {
38         case DD_OK:
39             return "DD_OK";
40         case DDERR_ALREADYINITIALIZED:
41             return "DDERR_ALREADYINITIALIZED";
42         case DDERR_BLTFASTCANTCLIP:
43             return "DDERR_BLTFASTCANTCLIP";
44         case DDERR_CANNOTATTACHSURFACE:
45             return "DDER_CANNOTATTACHSURFACE";
46         case DDERR_CANNOTDETACHSURFACE:
47             return "DDERR_CANNOTDETACHSURFACE";
48         case DDERR_CANTCREATEDC:
49             return "DDERR_CANTCREATEDC";
50         case DDERR_CANTDUPLICATE:
51             return "DDER_CANTDUPLICATE";
52         case DDERR_CLIPPERISUSINGHWND:
53             return "DDER_CLIPPERUSINGHWND";
54         case DDERR_COLORKEYNOTSET:
55             return "DDERR_COLORKEYNOTSET";
56         case DDERR_CURRENTLYNOTAVAIL:
57             return "DDERR_CURRENTLYNOTAVAIL";
58         case DDERR_DIRECTDRAWALREADYCREATED:
59             return "DDERR_DIRECTDRAWALREADYCREATED";
60         case DDERR_EXCEPTION:
61             return "DDERR_EXCEPTION";
62         case DDERR_EXCLUSIVEMODEALREADYSET:
63             return "DDERR_EXCLUSIVEMODEALREADYSET";
64         case DDERR_GENERIC:
65             return "DDERR_GENERIC";
66         case DDERR_HEIGHTALIGN:
67             return "DDERR_HEIGHTALIGN";
68         case DDERR_HWNDALREADYSET:
69             return "DDERR_HWNDALREADYSET";
70         case DDERR_HWNDSUBCLASSED:
71             return "DDERR_HWNDSUBCLASSED";
72         case DDERR_IMPLICITLYCREATED:
73             return "DDERR_IMPLICITLYCREATED";
74         case DDERR_INCOMPATIBLEPRIMARY:
75             return "DDERR_INCOMPATIBLEPRIMARY";
76         case DDERR_INVALIDCAPS:
77             return "DDERR_INVALIDCAPS";
78         case DDERR_INVALIDCLIPLIST:
79             return "DDERR_INVALIDCLIPLIST";
80         case DDERR_INVALIDDIRECTDRAWGUID:
81             return "DDERR_INVALIDDIRECTDRAWGUID";
82         case DDERR_INVALIDMODE:
83             return "DDERR_INVALIDMODE";
84         case DDERR_INVALIDOBJECT:
85             return "DDERR_INVALIDOBJECT";
86         case DDERR_INVALIDPARAMS:
87             return "DDERR_INVALIDPARAMS";
88         case DDERR_INVALIDPIXELFORMAT:
89             return "DDERR_INVALIDPIXELFORMAT";
90         case DDERR_INVALIDPOSITION:
91             return "DDERR_INVALIDPOSITION";
92         case DDERR_INVALIDRECT:
93             return "DDERR_INVALIDRECT";
94         case DDERR_LOCKEDSURFACES:
95             return "DDERR_LOCKEDSURFACES";
96         case DDERR_NO3D:
97             return "DDERR_NO3D";
98         case DDERR_NOALPHAHW:
99             return "DDERR_NOALPHAHW";
100         case DDERR_NOBLTHW:
101             return "DDERR_NOBLTHW";
102         case DDERR_NOCLIPLIST:
103             return "DDERR_NOCLIPLIST";
104         case DDERR_NOCLIPPERATTACHED:
105             return "DDERR_NOCLIPPERATTACHED";
106         case DDERR_NOCOLORCONVHW:
107             return "DDERR_NOCOLORCONVHW";
108         case DDERR_NOCOLORKEY:
109             return "DDERR_NOCOLORKEY";
110         case DDERR_NOCOLORKEYHW:
111             return "DDERR_NOCOLORKEYHW";
112         case DDERR_NOCOOPERATIVELEVELSET:
113             return "DDERR_NOCOOPERATIVELEVELSET";
114         case DDERR_NODC:
115             return "DDERR_NODC";
116         case DDERR_NODDROPSHW:
117             return "DDERR_NODDROPSHW";
118         case DDERR_NODIRECTDRAWHW:
119             return "DDERR_NODIRECTDRAWHW";
120         case DDERR_NOEMULATION:
121             return "DDERR_NOEMULATION";
122         case DDERR_NOEXCLUSIVEMODE:
123             return "DDERR_NOEXCLUSIVEMODE";
124         case DDERR_NOFLIPHW:
125             return "DDERR_NOFLIPHW";
126         case DDERR_NOGDI:
127             return "DDERR_NOGDI";
128         case DDERR_NOHWND:
129             return "DDERR_NOHWND";
130         case DDERR_NOMIRRORHW:
131             return "DDERR_NOMIRRORHW";
132         case DDERR_NOOVERLAYDEST:
133             return "DDERR_NOOVERLAYDEST";
134         case DDERR_NOOVERLAYHW:
135             return "DDERR_NOOVERLAYHW";
136         case DDERR_NOPALETTEATTACHED:
137             return "DDERR_NOPALETTEATTACHED";
138         case DDERR_NOPALETTEHW:
139             return "DDERR_NOPALETTEHW";
140         case DDERR_NORASTEROPHW:
141             return "Operation could not be carried out because there is no appropriate raster op hardware present or available.\0";
142         case DDERR_NOROTATIONHW:
143             return "Operation could not be carried out because there is no rotation hardware present or available.\0";
144         case DDERR_NOSTRETCHHW:
145             return "Operation could not be carried out because there is no hardware support for stretching.\0";
146         case DDERR_NOT4BITCOLOR:
147             return "DirectDrawSurface is not in 4 bit color palette and the requested operation requires 4 bit color palette.\0";
148         case DDERR_NOT4BITCOLORINDEX:
149             return "DirectDrawSurface is not in 4 bit color index palette and the requested operation requires 4 bit color index palette.\0";
150         case DDERR_NOT8BITCOLOR:
151             return "DDERR_NOT8BITCOLOR";
152         case DDERR_NOTAOVERLAYSURFACE:
153             return "Returned when an overlay member is called for a non-overlay surface.\0";
154         case DDERR_NOTEXTUREHW:
155             return "Operation could not be carried out because there is no texture mapping hardware present or available.\0";
156         case DDERR_NOTFLIPPABLE:
157             return "DDERR_NOTFLIPPABLE";
158         case DDERR_NOTFOUND:
159             return "DDERR_NOTFOUND";
160         case DDERR_NOTLOCKED:
161             return "DDERR_NOTLOCKED";
162         case DDERR_NOTPALETTIZED:
163             return "DDERR_NOTPALETTIZED";
164         case DDERR_NOVSYNCHW:
165             return "DDERR_NOVSYNCHW";
166         case DDERR_NOZBUFFERHW:
167             return "Operation could not be carried out because there is no hardware support for zbuffer blitting.\0";
168         case DDERR_NOZOVERLAYHW:
169             return "Overlay surfaces could not be z layered based on their BltOrder because the hardware does not support z layering of overlays.\0";
170         case DDERR_OUTOFCAPS:
171             return "The hardware needed for the requested operation has already been allocated.\0";
172         case DDERR_OUTOFMEMORY:
173             return "DDERR_OUTOFMEMORY";
174         case DDERR_OUTOFVIDEOMEMORY:
175             return "DDERR_OUTOFVIDEOMEMORY";
176         case DDERR_OVERLAYCANTCLIP:
177             return "The hardware does not support clipped overlays.\0";
178         case DDERR_OVERLAYCOLORKEYONLYONEACTIVE:
179             return "Can only have ony color key active at one time for overlays.\0";
180         case DDERR_OVERLAYNOTVISIBLE:
181             return "Returned when GetOverlayPosition is called on a hidden overlay.\0";
182         case DDERR_PALETTEBUSY:
183             return "DDERR_PALETTEBUSY";
184         case DDERR_PRIMARYSURFACEALREADYEXISTS:
185             return "DDERR_PRIMARYSURFACEALREADYEXISTS";
186         case DDERR_REGIONTOOSMALL:
187             return "Region passed to Clipper::GetClipList is too small.\0";
188         case DDERR_SURFACEALREADYATTACHED:
189             return "DDERR_SURFACEALREADYATTACHED";
190         case DDERR_SURFACEALREADYDEPENDENT:
191             return "DDERR_SURFACEALREADYDEPENDENT";
192         case DDERR_SURFACEBUSY:
193             return "DDERR_SURFACEBUSY";
194         case DDERR_SURFACEISOBSCURED:
195             return "Access to surface refused because the surface is obscured.\0";
196         case DDERR_SURFACELOST:
197             return "DDERR_SURFACELOST";
198         case DDERR_SURFACENOTATTACHED:
199             return "DDERR_SURFACENOTATTACHED";
200         case DDERR_TOOBIGHEIGHT:
201             return "Height requested by DirectDraw is too large.\0";
202         case DDERR_TOOBIGSIZE:
203             return "Size requested by DirectDraw is too large, but the individual height and width are OK.\0";
204         case DDERR_TOOBIGWIDTH:
205             return "Width requested by DirectDraw is too large.\0";
206         case DDERR_UNSUPPORTED:
207             return "DDERR_UNSUPPORTED";
208         case DDERR_UNSUPPORTEDFORMAT:
209             return "FOURCC format requested is unsupported by DirectDraw.\0";
210         case DDERR_UNSUPPORTEDMASK:
211             return "Bitmask in the pixel format requested is unsupported by DirectDraw.\0";
212         case DDERR_VERTICALBLANKINPROGRESS:
213             return "Vertical blank is in progress.\0";
214         case DDERR_WASSTILLDRAWING:
215             return "DDERR_WASSTILLDRAWING";
216         case DDERR_WRONGMODE:
217             return "This surface can not be restored because it was created in a different mode.\0";
218         case DDERR_XALIGN:
219             return "Rectangle provided was not horizontally aligned on required boundary.\0";
220         default:
221             return "UNKNOWN\0";
222 	}
223 }
224 
DDRAW_EndFrame(byte ** buffer,int * rowbytes)225 void DDRAW_EndFrame( byte **buffer, int *rowbytes ) {
226 	RECT r;
227 	HRESULT rval;
228 	DDSURFACEDESC ddsd;
229 
230 	r.left = 0;
231 	r.top = 0;
232 	r.right = sww_state.width;
233 	r.bottom = sww_state.height;
234 
235 	IDirectDrawSurface_Unlock( sww_state.lpddsOffScreenBuffer, *buffer );
236 
237 	if( sww_state.modex ) {
238 		if( ( rval = IDirectDrawSurface_BltFast( sww_state.lpddsBackBuffer,
239 																0, 0,
240 																sww_state.lpddsOffScreenBuffer,
241 																&r,
242 																DDBLTFAST_WAIT ) ) == DDERR_SURFACELOST )
243 		{
244 			IDirectDrawSurface_Restore( sww_state.lpddsBackBuffer );
245 			IDirectDrawSurface_BltFast( sww_state.lpddsBackBuffer,
246 														0, 0,
247 														sww_state.lpddsOffScreenBuffer,
248 														&r,
249 														DDBLTFAST_WAIT );
250 		}
251 
252 		if( ( rval = IDirectDrawSurface_Flip( sww_state.lpddsFrontBuffer,
253 														 NULL, DDFLIP_WAIT ) ) == DDERR_SURFACELOST )
254 		{
255 			IDirectDrawSurface_Restore( sww_state.lpddsFrontBuffer );
256 			IDirectDrawSurface_Flip( sww_state.lpddsFrontBuffer, NULL, DDFLIP_WAIT );
257 		}
258 	} else {
259 		if ( ( rval = IDirectDrawSurface_BltFast( sww_state.lpddsFrontBuffer,
260 																0, 0,
261 																sww_state.lpddsOffScreenBuffer,
262 																&r,
263 																DDBLTFAST_WAIT ) ) == DDERR_SURFACELOST )
264 		{
265 			IDirectDrawSurface_Restore( sww_state.lpddsFrontBuffer );
266 			IDirectDrawSurface_BltFast( sww_state.lpddsFrontBuffer,
267 														0, 0,
268 														sww_state.lpddsOffScreenBuffer,
269 														&r,
270 														DDBLTFAST_WAIT );
271 		}
272 	}
273 
274 	memset( &ddsd, 0, sizeof( ddsd ) );
275 	ddsd.dwSize = sizeof( ddsd );
276 
277 	IDirectDrawSurface_Lock( sww_state.lpddsOffScreenBuffer, NULL, &ddsd, DDLOCK_WAIT, NULL );
278 
279 	*buffer = ( byte * )ddsd.lpSurface;
280 	*rowbytes = ( int )ddsd.lPitch;
281 
282 }
283 
284 typedef HRESULT (WINAPI *LPDIRECTDRAWCREATE)( LPCGUID, LPDIRECTDRAW *, LPUNKNOWN );
285 
286 /*
287 ** DDRAW_Init
288 **
289 ** Builds our DDRAW stuff
290 */
DDRAW_Init(byte ** ppbuffer,int * ppitch,const byte * palette)291 qboolean DDRAW_Init( byte **ppbuffer, int *ppitch, const byte *palette ) {
292 	HRESULT ddrval;
293 	DDSURFACEDESC ddsd;
294 	DDSCAPS ddscaps;
295 	PALETTEENTRY palentries[256];
296 	int i;
297 	LPDIRECTDRAWCREATE	pDirectDrawCreate;
298 
299 	Com_Printf( "Initializing DirectDraw\n");
300 
301 	/*
302 	** load DLL and fetch pointer to entry point
303 	*/
304 	if ( !sww_state.hinstDDRAW ) {
305 		Com_Printf( "...loading DDRAW.DLL: ");
306 		if ( ( sww_state.hinstDDRAW = LoadLibrary( "ddraw.dll" ) ) == NULL ) {
307 			Com_Printf( "failed\n" );
308 			goto fail;
309 		}
310 		Com_Printf( "ok\n" );
311 	}
312 
313 	pDirectDrawCreate = ( LPDIRECTDRAWCREATE )
314 		GetProcAddress( sww_state.hinstDDRAW, "DirectDrawCreate" );
315 	if( pDirectDrawCreate == NULL ) {
316 		Com_Printf( "*** DirectDrawCreate == NULL ***\n" );
317 		goto fail;
318 	}
319 
320 	/*
321 	** create the direct draw object
322 	*/
323 	Com_Printf( "...creating DirectDraw object: ");
324 	if ( ( ddrval = pDirectDrawCreate( NULL, &sww_state.lpDirectDraw, NULL ) ) != DD_OK ) {
325 		Com_Printf( "failed - %s\n", DDrawError( ddrval ) );
326 		goto fail;
327 	}
328 	Com_Printf( "ok\n" );
329 
330 	/*
331 	** see if linear modes exist first
332 	*/
333 	sww_state.modex = qfalse;
334 
335 	Com_Printf( "...setting exclusive mode: ");
336 	if ( ( ddrval = IDirectDraw_SetCooperativeLevel( sww_state.lpDirectDraw,
337 													sww_state.hWnd,
338 													DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN ) ) != DD_OK )
339 	{
340 		Com_Printf( "failed - %s\n", DDrawError (ddrval) );
341 		goto fail;
342 	}
343 	Com_Printf( "ok\n" );
344 
345 	/*
346 	** try changing the display mode normally
347 	*/
348 	Com_Printf( "...finding display mode\n" );
349 	Com_Printf( "...setting linear mode: " );
350 	if ( ( ddrval = IDirectDraw_SetDisplayMode( sww_state.lpDirectDraw,
351 												sww_state.width,
352 												sww_state.height, 8 ) ) == DD_OK )
353 	{
354 		Com_Printf( "ok\n" );
355 	}
356 	/*
357 	** if no linear mode found, go for modex if we're trying 320x240
358 	*/
359 	else if ( !cvar.VariableInteger( "sw_mode" ) && cvar.VariableInteger( "sw_allow_modex" ) ) {
360 		Com_Printf( "failed\n" );
361 		Com_Printf( "...attempting ModeX 320x240: ");
362 
363 		/*
364 		** reset to normal cooperative level
365 		*/
366 		IDirectDraw_SetCooperativeLevel( sww_state.lpDirectDraw,
367 										sww_state.hWnd,
368 										DDSCL_NORMAL );
369 
370 		/*
371 		** set exclusive mode
372 		*/
373 		if ( ( ddrval = IDirectDraw_SetCooperativeLevel( sww_state.lpDirectDraw,
374 														sww_state.hWnd,
375 														DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN |
376 														DDSCL_NOWINDOWCHANGES | DDSCL_ALLOWMODEX ) ) != DD_OK )
377 		{
378 			Com_Printf( "failed SCL - %s\n", DDrawError (ddrval) );
379 			goto fail;
380 		}
381 
382 		/*
383 		** change our display mode
384 		*/
385 		if ( ( ddrval = IDirectDraw_SetDisplayMode( sww_state.lpDirectDraw,
386 													sww_state.width,
387 													sww_state.height, 8 ) ) != DD_OK )
388 		{
389 			Com_Printf( "failed SDM - %s\n", DDrawError( ddrval ) );
390 			goto fail;
391 		}
392 		Com_Printf( "ok\n" );
393 
394 		sww_state.modex = qtrue;
395 	} else {
396 		Com_Printf( "failed\n" );
397 		goto fail;
398 	}
399 
400 	/*
401 	** create our front buffer
402 	*/
403 	memset( &ddsd, 0, sizeof( ddsd ) );
404 	ddsd.dwSize = sizeof( ddsd );
405 	ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
406 	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
407 	ddsd.dwBackBufferCount = 1;
408 
409 	Com_Printf( "...creating front buffer: ");
410 	if ( ( ddrval = IDirectDraw_CreateSurface( sww_state.lpDirectDraw, &ddsd,
411 		&sww_state.lpddsFrontBuffer, NULL ) ) != DD_OK )
412 	{
413 		Com_Printf( "failed - %s\n", DDrawError( ddrval ) );
414 		goto fail;
415 	}
416 	Com_Printf( "ok\n" );
417 
418 	/*
419 	** see if we're a ModeX mode
420 	*/
421 	IDirectDrawSurface_GetCaps( sww_state.lpddsFrontBuffer, &ddscaps );
422 	if ( ddscaps.dwCaps & DDSCAPS_MODEX )
423 		Com_Printf( "...using ModeX\n" );
424 
425 	/*
426 	** create our back buffer
427 	*/
428 	ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
429 
430 	Com_Printf( "...creating back buffer: " );
431 	if ( ( ddrval = IDirectDrawSurface_GetAttachedSurface( sww_state.lpddsFrontBuffer,
432 		&ddsd.ddsCaps, &sww_state.lpddsBackBuffer ) ) != DD_OK )
433 	{
434 		Com_Printf( "failed - %s\n", DDrawError( ddrval ) );
435 		goto fail;
436 	}
437 	Com_Printf( "ok\n" );
438 
439 	/*
440 	** create our rendering buffer
441 	*/
442 	memset( &ddsd, 0, sizeof( ddsd ) );
443 	ddsd.dwSize = sizeof( ddsd );
444 	ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
445 	ddsd.dwHeight = sww_state.height;
446 	ddsd.dwWidth = sww_state.width;
447 	ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
448 
449 	Com_Printf( "...creating offscreen buffer: " );
450 	if ( ( ddrval = IDirectDraw_CreateSurface( sww_state.lpDirectDraw, &ddsd,
451 		&sww_state.lpddsOffScreenBuffer, NULL ) ) != DD_OK )
452 	{
453 		Com_Printf( "failed - %s\n", DDrawError( ddrval ) );
454 		goto fail;
455 	}
456 	Com_Printf( "ok\n" );
457 
458 	for ( i = 0; i < 256; i++ ) {
459 		palentries[i].peRed		= palette[i*4+0];
460 		palentries[i].peGreen	= palette[i*4+1];
461 		palentries[i].peBlue	= palette[i*4+2];
462 	}
463 
464 	/*
465 	** create our DIRECTDRAWPALETTE
466 	*/
467 	Com_Printf( "...creating palette: " );
468 	if ( ( ddrval = IDirectDraw_CreatePalette( sww_state.lpDirectDraw,
469 												DDPCAPS_8BIT | DDPCAPS_ALLOW256,
470 												palentries,
471 												&sww_state.lpddpPalette,
472 												NULL ) ) != DD_OK )
473 	{
474 		Com_Printf( "failed - %s\n", DDrawError( ddrval ) );
475 		goto fail;
476 	}
477 	Com_Printf( "ok\n" );
478 
479 	Com_Printf( "...setting palette: " );
480 	if ( ( ddrval = IDirectDrawSurface_SetPalette( sww_state.lpddsFrontBuffer,
481 												sww_state.lpddpPalette ) ) != DD_OK )
482 	{
483 		Com_Printf( "failed - %s\n", DDrawError( ddrval ) );
484 		goto fail;
485 	}
486 	Com_Printf( "ok\n" );
487 
488 	/*
489 	** lock the back buffer
490 	*/
491 	memset( &ddsd, 0, sizeof( ddsd ) );
492 	ddsd.dwSize = sizeof( ddsd );
493 
494 	Com_Printf( "...locking backbuffer: " );
495 	if ( ( ddrval = IDirectDrawSurface_Lock( sww_state.lpddsOffScreenBuffer,
496 		NULL, &ddsd, DDLOCK_WAIT, NULL ) ) != DD_OK )
497 	{
498 		Com_Printf( "failed - %s\n", DDrawError( ddrval ) );
499 		goto fail;
500 	}
501 	Com_Printf( "ok\n" );
502 
503 	*ppbuffer = ( byte * )ddsd.lpSurface;
504 	*ppitch   = ( int )ddsd.lPitch;
505 
506 	for ( i = 0; i < sww_state.height; i++ ) {
507 		memset( *ppbuffer + i * *ppitch, 0, *ppitch );
508 	}
509 
510 	sww_state.palettized = qtrue;
511 
512 	return qtrue;
513 fail:
514 	Com_Printf( "*** DDraw init failure ***\n" );
515 
516 	DDRAW_Shutdown();
517 	return qfalse;
518 }
519 
520 /*
521 ** DDRAW_SetPalette
522 **
523 ** Sets the color table in our DIB section, and also sets the system palette
524 ** into an identity mode if we're running in an 8-bit palettized display mode.
525 **
526 ** The palette is expected to be 1024 bytes, in the format:
527 **
528 ** R = offset 0
529 ** G = offset 1
530 ** B = offset 2
531 ** A = offset 3
532 */
DDRAW_SetPalette(const byte * pal)533 void DDRAW_SetPalette( const byte *pal )
534 {
535 	PALETTEENTRY palentries[256];
536 	int i;
537 
538 	if (!sww_state.lpddpPalette)
539 		return;
540 
541 	for ( i = 0; i < 256; i++, pal += 4 )
542 	{
543 		palentries[i].peRed   = pal[0];
544 		palentries[i].peGreen = pal[1];
545 		palentries[i].peBlue  = pal[2];
546 		palentries[i].peFlags = PC_RESERVED | PC_NOCOLLAPSE;
547 	}
548 
549 	if ( IDirectDrawPalette_SetEntries( sww_state.lpddpPalette,
550 		                                0,
551 										0,
552 										256,
553 										palentries ) != DD_OK )
554 	{
555 		Com_Printf( "DDRAW_SetPalette() - SetEntries failed\n" );
556 	}
557 }
558 
DDRAW_FatalShutdown(void)559 void DDRAW_FatalShutdown( void )
560 {
561 	if ( sww_state.lpddsOffScreenBuffer )
562 	{
563 		IDirectDrawSurface_Unlock( sww_state.lpddsOffScreenBuffer, /*vid.buffer*/NULL );
564 		IDirectDrawSurface_Release( sww_state.lpddsOffScreenBuffer );
565 		sww_state.lpddsOffScreenBuffer = NULL;
566 	}
567 
568 	if ( sww_state.lpddsBackBuffer )
569 	{
570 		IDirectDrawSurface_Release( sww_state.lpddsBackBuffer );
571 		sww_state.lpddsBackBuffer = NULL;
572 	}
573 
574 	if ( sww_state.lpddsFrontBuffer )
575 	{
576 		IDirectDrawSurface_Release( sww_state.lpddsFrontBuffer );
577 		sww_state.lpddsFrontBuffer = NULL;
578 	}
579 
580 	if (sww_state.lpddpPalette)
581 	{
582 		IDirectDrawPalette_Release ( sww_state.lpddpPalette );
583 		sww_state.lpddpPalette = NULL;
584 	}
585 
586 	if ( sww_state.lpDirectDraw )
587 	{
588 		IDirectDraw_RestoreDisplayMode( sww_state.lpDirectDraw );
589 	    IDirectDraw_SetCooperativeLevel( sww_state.lpDirectDraw, sww_state.hWnd, DDSCL_NORMAL );
590 		IDirectDraw_Release( sww_state.lpDirectDraw );
591 		sww_state.lpDirectDraw = NULL;
592 	}
593 }
594 
595 /*
596 ** DDRAW_Shutdown
597 */
DDRAW_Shutdown(void)598 void DDRAW_Shutdown( void )
599 {
600 	if ( sww_state.lpddsOffScreenBuffer )
601 	{
602 		Com_Printf( "...releasing offscreen buffer\n");
603 		IDirectDrawSurface_Unlock( sww_state.lpddsOffScreenBuffer, /*vid.buffer*/NULL );
604 		IDirectDrawSurface_Release( sww_state.lpddsOffScreenBuffer );
605 		sww_state.lpddsOffScreenBuffer = NULL;
606 	}
607 
608 	if ( sww_state.lpddsBackBuffer )
609 	{
610 		Com_Printf( "...releasing back buffer\n");
611 		IDirectDrawSurface_Release( sww_state.lpddsBackBuffer );
612 		sww_state.lpddsBackBuffer = NULL;
613 	}
614 
615 	if ( sww_state.lpddsFrontBuffer )
616 	{
617 		Com_Printf( "...releasing front buffer\n");
618 		IDirectDrawSurface_Release( sww_state.lpddsFrontBuffer );
619 		sww_state.lpddsFrontBuffer = NULL;
620 	}
621 
622 	if (sww_state.lpddpPalette)
623 	{
624 		Com_Printf( "...releasing palette\n");
625 		IDirectDrawPalette_Release ( sww_state.lpddpPalette );
626 		sww_state.lpddpPalette = NULL;
627 	}
628 
629 	if ( sww_state.lpDirectDraw )
630 	{
631 		Com_Printf( "...restoring display mode\n");
632 		IDirectDraw_RestoreDisplayMode( sww_state.lpDirectDraw );
633 		Com_Printf( "...restoring normal coop mode\n");
634 	    IDirectDraw_SetCooperativeLevel( sww_state.lpDirectDraw, sww_state.hWnd, DDSCL_NORMAL );
635 		Com_Printf( "...releasing lpDirectDraw\n");
636 		IDirectDraw_Release( sww_state.lpDirectDraw );
637 		sww_state.lpDirectDraw = NULL;
638 	}
639 
640 	if ( sww_state.hinstDDRAW )
641 	{
642 		Com_Printf( "...freeing library\n");
643 		FreeLibrary( sww_state.hinstDDRAW );
644 		sww_state.hinstDDRAW = NULL;
645 	}
646 }
647 
648 
649 
650