1 /* -*- c++ -*-
2 FILE: WrapDD.cpp
3 RCS REVISION: $Revision: 1.9 $
4
5 COPYRIGHT: (c) 1999 -- 2003 Melinda Green, Don Hatch, and Jay Berkenbilt - Superliminal Software
6
7 LICENSE: Free to use and modify for non-commercial purposes as long as the
8 following conditions are adhered to:
9 1) Obvious credit for the source of this code and the designs it embodies
10 are clearly made, and
11 2) Ports and derived versions of 4D Magic Cube programs are not distributed
12 without the express written permission of the authors.
13
14 DESCRIPTION:
15 Abstraction on top of DirectX
16 */
17
18 #include "WrapDX.h"
19 #include "assert.h"
20
21 #define TRACE Trace
22 #define RELEASE(x) if (x != NULL) {x->Release(); x = NULL;}
23
24 #ifdef _DEBUG
25
26 extern "C" int vsprintf(char *, const char *, va_list);
27
28 void
Trace(const char * format,...)29 Trace(const char *format, ...)
30 {
31 va_list args;
32 int count;
33 char buffer[512];
34
35 va_start(args, format);
36 count = vsprintf(buffer, format, args);
37 va_end(args);
38
39 OutputDebugString(buffer);
40 }
41
42 #else
43
44 inline void
Trace(const char *,...)45 Trace(const char *, ...)
46 {
47 }
48
49 #endif /* _DEBUG */
50
WrapDD()51 WrapDD::WrapDD ()
52 {
53 m_pFrontBuffer = 0;
54 m_pBackBuffer = 0;
55 m_pZBuffer = 0;
56 m_pClipper = 0;
57 m_pPalette = 0;
58 m_pDirectDraw = 0;
59 m_bIsOnPrimaryDevice = TRUE;
60 m_pText1Surface = 0;
61 m_pText2Surface = 0;
62 memset(&m_HWddsCaps, 0, sizeof(m_HWddsCaps));
63
64 // instead of AppInfo app
65 m_hWndMain = 0;
66 m_modeCount = 0;
67 m_bIgnoreWM_SIZE = FALSE;
68
69 // Parameters and status flags
70 m_bPrimaryPalettized = FALSE;
71 m_bOnlySystemMemory = FALSE;
72
73 memset(&m_guid, 0, sizeof(m_guid));
74 m_bFullScreen = FALSE;
75 m_bOnlySoftRender = FALSE;
76
77 m_pauseCount = 0;
78
79 m_pErrorHandler = 0;
80 m_pFatalErrorHandler = 0;
81 m_pErrorHandlerArg = 0;
82 m_pFatalErrorHandlerArg = 0;
83 }
84
~WrapDD()85 WrapDD:: ~WrapDD ()
86 {
87 Destroy();
88 }
89
90 BOOL
Create(HWND hWnd,BOOL fullScreen,int width,int height,int bpp,const PALETTEENTRY * pPaletteEntries,int paletteEntryCount)91 WrapDD::Create(HWND hWnd,
92 BOOL fullScreen,
93 int width, int height, int bpp,
94 const PALETTEENTRY * pPaletteEntries,
95 int paletteEntryCount)
96 {
97 // assert(!m_hWndMain);
98
99 // ??? we should reset all data members
100
101 m_hWndMain = hWnd;
102
103 if (!m_pDirectDraw)
104 {
105 CacheOriginalPaletteEntries();
106
107 if (!DDCreate())
108 {
109 return FALSE;
110 }
111 }
112
113 // if DirectDraw is not on primary display, assume it only does
114 // fullscreen
115 if (!m_bIsOnPrimaryDevice)
116 {
117 fullScreen = TRUE;
118 }
119
120 if (!DDInit(fullScreen))
121 {
122 return FALSE;
123 }
124
125 if (!SetPaletteEntries(pPaletteEntries, paletteEntryCount, fullScreen))
126 {
127 return FALSE;
128 }
129
130 if (!DDSetMode(width, height, bpp))
131 {
132 return FALSE;
133 }
134
135 return TRUE;
136 }
137
138 // Save the original palette for when we are paused
139 // In case we start in fullScreen, put it in m_paletteEntries
CacheOriginalPaletteEntries()140 BOOL WrapDD::CacheOriginalPaletteEntries()
141 {
142 HDC hdc;
143
144 hdc = GetDC(NULL);
145 GetSystemPaletteEntries(hdc, 0, (1 << 8), &m_originalPaletteEntries[0]);
146 #if 0
147 for (i = 0; i < 256; i++)
148 {
149 m_paletteEntries[i] = m_originalPaletteEntries[i];
150 }
151 #endif
152 ReleaseDC(NULL, hdc);
153
154 return TRUE;
155 }
156
157
SetPaletteEntries(const PALETTEENTRY * pPaletteEntries,int paletteEntryCount,BOOL fullScreen)158 BOOL WrapDD::SetPaletteEntries(const PALETTEENTRY * pPaletteEntries,
159 int paletteEntryCount, BOOL fullScreen)
160 {
161 int reservedLowEntryCount;
162 int reservedHighEntryCount;
163 HDC hdc;
164 int i;
165
166 hdc = GetDC(NULL);
167 // start out with system palette
168 GetSystemPaletteEntries(hdc, 0, (1 << 8), m_paletteEntries);
169 ReleaseDC(NULL, hdc);
170
171 if (fullScreen)
172 {
173 reservedLowEntryCount = 1;
174 reservedHighEntryCount = 1;
175 }
176 else
177 {
178 reservedLowEntryCount = 10;
179 reservedHighEntryCount = 10;
180 }
181
182 for (i = 0; i < reservedLowEntryCount; i++)
183 {
184 m_paletteEntries[i].peFlags = D3DPAL_READONLY;
185 }
186
187 for (i = reservedLowEntryCount; i < 256 - reservedHighEntryCount; i++)
188 {
189 m_paletteEntries[i].peFlags = D3DPAL_READONLY;
190 }
191
192 for (i = 256 - reservedHighEntryCount; i < 256; i++)
193 {
194 m_paletteEntries[i].peFlags = D3DPAL_READONLY;
195 }
196
197 // then replace entries as specified
198 assert(paletteEntryCount <=
199 (sizeof(m_paletteEntries) / sizeof(m_paletteEntries[0])));
200 // ??? In fullscreen: should we set entry 0 and 255
201 // In window mode: should we set entry 0-9 and 246-255
202 for (i = reservedLowEntryCount;
203 (i < paletteEntryCount) && (i < 256 - reservedHighEntryCount); i++)
204 {
205 m_paletteEntries[i].peRed = pPaletteEntries[i].peRed;
206 m_paletteEntries[i].peGreen = pPaletteEntries[i].peGreen;
207 m_paletteEntries[i].peBlue = pPaletteEntries[i].peBlue;
208 }
209
210 if (m_pPalette)
211 {
212 HRESULT result;
213
214 result = m_pPalette->SetEntries(0, 0,
215 sizeof(m_paletteEntries) /
216 sizeof(m_paletteEntries[0]),
217 m_paletteEntries);
218 if (result != DD_OK)
219 {
220 Error("SetEntries failed", result);
221 return FALSE;
222 }
223 }
224
225 return TRUE;
226 }
227
228 // Releases all objects, scene, textures and other memory.
Destroy()229 void WrapDD::Destroy()
230 {
231 DestroyButNotDirectDraw();
232 RELEASE(m_pDirectDraw);
233
234 // ??? reset other members, or in Create()
235 m_bIsOnPrimaryDevice = TRUE;
236 }
237
238 // Releases all objects, scene, textures and other memory except DirectDraw
DestroyButNotDirectDraw()239 void WrapDD::DestroyButNotDirectDraw()
240 {
241 // ???
242 RestoreOriginalPaletteEntries();
243
244 if (m_bFullScreen)
245 {
246 if (m_pDirectDraw)
247 {
248 m_bIgnoreWM_SIZE = TRUE;
249 m_pDirectDraw->RestoreDisplayMode();
250 m_bIgnoreWM_SIZE = FALSE;
251 }
252 }
253
254 RELEASE(m_pPalette);
255 RELEASE(m_pClipper);
256 RELEASE(m_pText1Surface);
257 RELEASE(m_pText2Surface);
258 RELEASE(m_pZBuffer);
259 RELEASE(m_pBackBuffer);
260 RELEASE(m_pFrontBuffer);
261 }
262
SetErrorHandler(ErrorHandler errorHandler,void * pArg)263 void WrapDD::SetErrorHandler(ErrorHandler errorHandler, void *pArg)
264 {
265 m_pErrorHandler = errorHandler;
266 m_pErrorHandlerArg = pArg;
267 }
268
SetFatalErrorHandler(ErrorHandler errorHandler,void * pArg)269 void WrapDD::SetFatalErrorHandler(ErrorHandler errorHandler, void *pArg)
270 {
271 m_pFatalErrorHandler = errorHandler;
272 m_pFatalErrorHandlerArg = pArg;
273 }
274
275 /*************************************************************************
276 DirectDraw functions
277 *************************************************************************/
278
279 // Checks to see if there is enough free video memory
FreeVideoMemory()280 long WrapDD::FreeVideoMemory()
281 {
282 HRESULT result;
283 DDCAPS ddcaps;
284
285 memset(&ddcaps, 0, sizeof(ddcaps));
286 ddcaps.dwSize = sizeof(ddcaps);
287 result = m_pDirectDraw->GetCaps(&ddcaps, NULL);
288 if (result != DD_OK)
289 {
290 Error("GetCaps failed while checking for free memory", result);
291 return FALSE;
292 }
293 return ddcaps.dwVidMemFree;
294 }
295
TotalVideoMemory()296 long WrapDD::TotalVideoMemory()
297 {
298 HRESULT result;
299 DDCAPS ddcaps;
300
301 memset(&ddcaps, 0, sizeof(ddcaps));
302 ddcaps.dwSize = sizeof(ddcaps);
303 result = m_pDirectDraw->GetCaps(&ddcaps, NULL);
304 if (result != DD_OK)
305 {
306 Error("GetCaps failed while checking for total video memory", result);
307 return FALSE;
308 }
309
310 return (long)(ddcaps.dwVidMemTotal);
311 }
312
313 // Determines Z buffer depth.
GetHardwareCaps(DDCAPS & rDriverCaps,DDCAPS & rHELCaps)314 BOOL WrapDD::GetHardwareCaps(DDCAPS &rDriverCaps, DDCAPS &rHELCaps)
315 {
316 HRESULT result;
317
318 memset(&rDriverCaps, 0, sizeof(rDriverCaps));
319 memset(&rHELCaps, 0, sizeof(rHELCaps));
320 rDriverCaps.dwSize = sizeof(DDCAPS);
321 rHELCaps.dwSize = sizeof(DDCAPS);
322
323 result = m_pDirectDraw->GetCaps(&rDriverCaps, &rHELCaps);
324 if (result != DD_OK)
325 {
326 Error("GetCaps failed", result);
327 }
328
329 return (result == DD_OK);
330 }
331
332 BOOL CALLBACK
EnumDirectDrawCallback(GUID * pGUID,char * pDriverDesc,char * pDriverName,void * pContext)333 WrapDD::EnumDirectDrawCallback(GUID * pGUID,
334 char *pDriverDesc,
335 char *pDriverName, void *pContext)
336 {
337 WrapDD *pDirectDraw = (WrapDD *)pContext;
338
339 return pDirectDraw->EnumDirectDrawCallback(pGUID, pDriverDesc,
340 pDriverName);
341 }
342
EnumDirectDrawCallback(GUID * pGUID,char * pDriverDesc,char * pDriverName)343 BOOL WrapDD::EnumDirectDrawCallback(GUID * pGUID,
344 char *pDriverDesc, char *pDriverName)
345 {
346 if (pGUID)
347 {
348 IDirectDraw *pDirectDraw;
349 DDCAPS driverCaps, helCaps;
350 HRESULT result;
351
352 result = DirectDrawCreate(pGUID, &pDirectDraw, NULL);
353 if (result != DD_OK)
354 {
355 Error
356 ("Failing creating a DirectDraw device for testing. Continuing...",
357 result);
358 return DDENUMRET_OK;
359 }
360
361 if (!GetHardwareCaps(driverCaps, helCaps))
362 {
363 pDirectDraw->Release();
364 return DDENUMRET_OK;
365 }
366
367 if (driverCaps.dwCaps & DDCAPS_3D)
368 {
369 // We have found a 3d hardware device
370 memcpy(&m_guid, pGUID, sizeof(GUID));
371
372 m_bIsOnPrimaryDevice = FALSE;
373 m_pDirectDraw = pDirectDraw;
374 return DDENUMRET_CANCEL;
375 }
376
377 // just to be sure
378 m_bIsOnPrimaryDevice = TRUE;
379 m_pDirectDraw = 0;
380 pDirectDraw->Release();
381 }
382
383 return DDENUMRET_OK;
384 }
385
386 // Create the DirectDraw object.
DDCreate()387 BOOL WrapDD::DDCreate()
388 {
389 HRESULT result;
390
391 assert(!m_pDirectDraw);
392
393 // search for a 3D DirectDraw device
394 result = DirectDrawEnumerate(EnumDirectDrawCallback, (void *)this);
395 if (result != DD_OK)
396 {
397 Error("DirectDrawEnumerate failed", result);
398 }
399
400 if (!m_pDirectDraw)
401 {
402 // did not find 3D DirectDraw device, use HEL
403 m_bIsOnPrimaryDevice = TRUE;
404 memset(&m_guid, 0, sizeof(m_guid));
405 result = DirectDrawCreate(0, &m_pDirectDraw, NULL);
406 if (result != DD_OK)
407 {
408 Error("DirectDrawCreate failed", result);
409 }
410 }
411
412 return (m_pDirectDraw != 0);
413 }
414
415 // Initialize the DirectDraw object.
DDInit(BOOL fullScreen)416 BOOL WrapDD::DDInit(BOOL fullScreen)
417 {
418 DDSURFACEDESC ddsd;
419 DDCAPS driverCaps, helCaps;
420 HRESULT result;
421
422 assert(m_pDirectDraw);
423
424 if (fullScreen)
425 {
426 m_bIgnoreWM_SIZE = TRUE;
427 result = m_pDirectDraw->SetCooperativeLevel(m_hWndMain,
428 #ifdef _DEBUG
429 DDSCL_ALLOWREBOOT |
430 #endif
431 #if 0
432 DDSCL_ALLOWMODEX |
433 #endif
434 DDSCL_EXCLUSIVE |
435 DDSCL_FULLSCREEN);
436 m_bIgnoreWM_SIZE = FALSE;
437 }
438 else
439 {
440 result = m_pDirectDraw->SetCooperativeLevel(m_hWndMain, DDSCL_NORMAL);
441 }
442
443 if (result != DD_OK)
444 {
445 Error("SetCooperativeLevel failed", result);
446 return FALSE;
447 }
448
449 if (!GetHardwareCaps(driverCaps, helCaps))
450 {
451 return FALSE;
452 }
453 memcpy(&m_HWddsCaps, &driverCaps.ddsCaps, sizeof(m_HWddsCaps));
454
455 m_totalVideoMemory = TotalVideoMemory();
456
457 if (!EnumerateDisplayModes())
458 {
459 return FALSE;
460 }
461
462 memset(&ddsd, 0, sizeof(ddsd));
463 ddsd.dwSize = sizeof(ddsd);
464 result = m_pDirectDraw->GetDisplayMode(&ddsd);
465 if (result != DD_OK)
466 {
467 Error("GetDisplayMode failed", result);
468 return FALSE;
469 }
470
471 #if 0
472 m_szWindowsDisplay.cx = ddsd.dwWidth;
473 m_szWindowsDisplay.cy = ddsd.dwHeight;
474 #endif
475
476 m_bFullScreen = fullScreen;
477
478 return TRUE;
479 }
480
IsSupportedMode(int width,int height,int bpp)481 BOOL WrapDD::IsSupportedMode(int width, int height, int bpp)
482 {
483 Mode mode = { width, height, bpp };
484 int i;
485
486 for (i = 0; i < m_modeCount; i++)
487 {
488 if (mode == m_modes[i])
489 {
490 return TRUE;
491 }
492 }
493
494 return FALSE;
495 }
496 void
EnableResizing(HWND hwnd,BOOL flag)497 EnableResizing(HWND hwnd, BOOL flag)
498 {
499 static DWORD dwStyle;
500
501 if (!flag)
502 {
503 dwStyle = GetWindowLong(hwnd, GWL_STYLE);
504 if (dwStyle & WS_THICKFRAME)
505 {
506 SetWindowLong(hwnd, GWL_STYLE,
507 GetWindowLong(hwnd, GWL_STYLE) ^ WS_THICKFRAME);
508 }
509 }
510 else
511 {
512 SetWindowLong(hwnd, GWL_STYLE, dwStyle);
513 }
514 }
515
516 // Initializes DirectDraw for a new display mode or window size.
DDSetMode(int width,int height,int bpp)517 BOOL WrapDD::DDSetMode(int width, int height, int bpp)
518 {
519 HRESULT result;
520
521 if (m_bFullScreen)
522 {
523 EnableResizing(m_hWndMain, FALSE);
524
525 // For fullScreen, set the actual display mode.
526 if (!IsSupportedMode(width, height, bpp))
527 {
528 width = m_modes[0].width;
529 height = m_modes[0].height;
530 bpp = m_modes[0].bitsPerPixel;
531 }
532
533 m_bIgnoreWM_SIZE = TRUE;
534 result = m_pDirectDraw->SetDisplayMode(width, height, bpp);
535 m_bIgnoreWM_SIZE = FALSE;
536
537 if (result != DD_OK)
538 {
539 Error("SetDisplayMode failed", result);
540 return FALSE;
541 }
542 }
543 else
544 {
545 if (!m_bIsOnPrimaryDevice)
546 {
547 Error
548 ("Attempt made enter a windowed mode on a DirectDraw device that is not the primary display",
549 DDERR_GENERIC);
550 return FALSE;
551 }
552 /*
553 * I don't understand this code, but it doesn't seem to work at all,
554 * and taking it out helps. Bad, I know, but a girl's got to do what a
555 * girl's got to do.
556 */
557 #if 0
558 // For a window, set the window size.
559 RECT rc;
560 DWORD dwStyle;
561
562 // Convert to a normal app window if we are still a WS_POPUP window.
563 m_bIgnoreWM_SIZE = TRUE;
564 dwStyle = GetWindowLong(m_hWndMain, GWL_STYLE);
565 dwStyle &= ~WS_POPUP;
566 dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME;
567 SetWindowLong(m_hWndMain, GWL_STYLE, dwStyle);
568 SetRect(&rc, 0, 0, width, height);
569 AdjustWindowRectEx(&rc, GetWindowLong(m_hWndMain, GWL_STYLE),
570 GetMenu(m_hWndMain) != NULL,
571 GetWindowLong(m_hWndMain, GWL_EXSTYLE));
572 SetWindowPos(m_hWndMain, NULL,
573 0, 0, rc.right - rc.left, rc.bottom - rc.top,
574 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
575 SetWindowPos(m_hWndMain, HWND_NOTOPMOST,
576 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
577 m_bIgnoreWM_SIZE = FALSE;
578 #endif
579 }
580
581 m_currentMode.width = width;
582 m_currentMode.height = height;
583 m_currentMode.bitsPerPixel = bpp;
584
585 // Create the front and back buffer surfaces
586 if (!DDCreateSurfaces())
587 {
588 return FALSE;
589 }
590
591 // Palettize if we are not in a 16-bit mode.
592 DDSURFACEDESC ddsd;
593
594 if (!GetDDSurfaceDesc(&ddsd, m_pBackBuffer))
595 {
596 return FALSE;
597 }
598
599 if (ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
600 {
601 m_bPrimaryPalettized = TRUE;
602 }
603 else
604 {
605 m_bPrimaryPalettized = FALSE;
606 }
607
608 if (m_bPrimaryPalettized)
609 {
610 result =
611 m_pDirectDraw->
612 CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 |
613 DDPCAPS_INITIALIZE, m_paletteEntries, &m_pPalette,
614 NULL);
615 if (result != DD_OK)
616 {
617 Error("CreatePalette failed", result);
618 return FALSE;
619 }
620 result = m_pBackBuffer->SetPalette(m_pPalette);
621 result = m_pFrontBuffer->SetPalette(m_pPalette);
622 if (result != DD_OK)
623 {
624 Error("SetPalette failed", result);
625 return FALSE;
626 }
627 }
628
629 if (!CreateTextSurfaces())
630 return FALSE;
631 return TRUE;
632 }
633
634 // Used to create surfaces instead of calling DD directly.
635 HRESULT
CreateDDSurface(LPDDSURFACEDESC lpDDSurfDesc,LPDIRECTDRAWSURFACE FAR * lpDDSurface,IUnknown FAR * pUnkOuter)636 WrapDD::CreateDDSurface(LPDDSURFACEDESC lpDDSurfDesc,
637 LPDIRECTDRAWSURFACE FAR * lpDDSurface,
638 IUnknown FAR * pUnkOuter)
639 {
640 HRESULT result;
641 result =
642 m_pDirectDraw->CreateSurface(lpDDSurfDesc, lpDDSurface, pUnkOuter);
643 // TRACE("Created Surface<0x%x>\n", (void*) *lpDDSurface);
644 return result;
645 }
646
647 // Gets a surface description.
648 BOOL
GetDDSurfaceDesc(LPDDSURFACEDESC lpDDSurfDesc,LPDIRECTDRAWSURFACE lpDDSurf)649 WrapDD::GetDDSurfaceDesc(LPDDSURFACEDESC lpDDSurfDesc,
650 LPDIRECTDRAWSURFACE lpDDSurf)
651 {
652 HRESULT result;
653
654 memset(lpDDSurfDesc, 0, sizeof(DDSURFACEDESC));
655 lpDDSurfDesc->dwSize = sizeof(DDSURFACEDESC);
656 result = lpDDSurf->GetSurfaceDesc(lpDDSurfDesc);
657 if (result != DD_OK)
658 {
659 Error("Error getting a surface description", result);
660 }
661
662 return (result == DD_OK);
663 }
664
665 // Create front and back buffers as DirectDraw surfaces.
DDCreateSurfaces()666 BOOL WrapDD::DDCreateSurfaces()
667 {
668 HRESULT result;
669 DDSURFACEDESC ddsd;
670 DDSCAPS ddscaps;
671
672 if (m_bFullScreen)
673 {
674 // Create a complex flipping surface for fullScreen mode.
675 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
676 ddsd.dwSize = sizeof(ddsd);
677 ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
678 ddsd.ddsCaps.dwCaps =
679 DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_3DDEVICE |
680 DDSCAPS_COMPLEX;
681 if (m_bOnlySystemMemory)
682 ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
683 ddsd.dwBackBufferCount = 1;
684 result = CreateDDSurface(&ddsd, &m_pFrontBuffer, NULL);
685 // TRACE("Created Front Buffer<0x%x>\n", (void*) m_pFrontBuffer);
686 if (result != DD_OK)
687 {
688 Error("CreateSurface for front/back fullScreen buffer failed",
689 result);
690 return FALSE;
691 }
692 ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
693 result = m_pFrontBuffer->GetAttachedSurface(&ddscaps, &m_pBackBuffer);
694 if (result != DD_OK)
695 {
696 Error("GetAttachedSurface failed to get back buffer", result);
697 return FALSE;
698 }
699 if (!GetDDSurfaceDesc(&ddsd, m_pBackBuffer))
700 {
701 return FALSE;
702 }
703
704 if (!(ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
705 {
706 // ???
707 m_bOnlySoftRender;
708 }
709 }
710 else
711 {
712 // Window case
713 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
714 ddsd.dwSize = sizeof(DDSURFACEDESC);
715 ddsd.dwFlags = DDSD_CAPS;
716 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
717 result = CreateDDSurface(&ddsd, &m_pFrontBuffer, NULL);
718 // TRACE("Created Front Buffer<0x%x>\n", (void*) m_pFrontBuffer);
719 if (result != DD_OK)
720 {
721 Error("CreateSurface for window front buffer failed", result);
722 return FALSE;
723 }
724 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
725 ddsd.dwHeight = m_currentMode.height;
726 ddsd.dwWidth = m_currentMode.width;
727 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
728 if (m_bOnlySystemMemory)
729 ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
730 result = CreateDDSurface(&ddsd, &m_pBackBuffer, NULL);
731 // TRACE("Created Back Buffer<0x%x>\n", (void*) m_pBackBuffer);
732 if (result != DD_OK)
733 {
734 Error("CreateSurface for window back buffer failed", result);
735 return FALSE;
736 }
737 if (!GetDDSurfaceDesc(&ddsd, m_pBackBuffer))
738 {
739 return FALSE;
740 }
741 if (!(ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
742 {
743 // ???
744 m_bOnlySoftRender;
745 }
746
747 // Create a DirectDrawClipper object.
748 result = m_pDirectDraw->CreateClipper(0, &m_pClipper, NULL);
749 if (result != DD_OK)
750 {
751 Error("CreateClipper failed", result);
752 return FALSE;
753 }
754 result = m_pClipper->SetHWnd(0, m_hWndMain);
755 if (result != DD_OK)
756 {
757 Error("Clipper SetHWnd failed", result);
758 return FALSE;
759 }
760 result = m_pFrontBuffer->SetClipper(m_pClipper);
761 if (result != DD_OK)
762 {
763 Error("SetClipper failed", result);
764 return FALSE;
765 }
766 }
767
768 return TRUE;
769 }
770
771 BOOL
TextSurfaceToBackBuffer(IDirectDrawSurface * pSurface,SIZE & textSizeOnSurface,int y)772 WrapDD::TextSurfaceToBackBuffer(IDirectDrawSurface * pSurface,
773 SIZE & textSizeOnSurface, int y)
774 {
775 if (textSizeOnSurface.cx > 0 &&
776 textSizeOnSurface.cy > 0 &&
777 textSizeOnSurface.cx < m_currentMode.width &&
778 textSizeOnSurface.cy < m_currentMode.height)
779 {
780 HRESULT result;
781 RECT rc;
782 int x;
783
784 SetRect(&rc, 0, 0, textSizeOnSurface.cx, textSizeOnSurface.cy);
785 x = (int)(0.5 * (m_currentMode.width - textSizeOnSurface.cx) + 0.5);
786 result = m_pBackBuffer->BltFast(x, y, pSurface, &rc,
787 DDBLTFAST_SRCCOLORKEY |
788 DDBLTFAST_WAIT);
789 if (result != DD_OK)
790 {
791 return FALSE;
792 }
793 }
794
795 return TRUE;
796 }
797
TextSurface1ToBackBuffer()798 BOOL WrapDD::TextSurface1ToBackBuffer()
799 {
800 return TextSurfaceToBackBuffer(m_pText1Surface, m_text1SizeOnSurface, 0);
801 }
802
TextSurface2ToBackBuffer()803 BOOL WrapDD::TextSurface2ToBackBuffer()
804 {
805 return TextSurfaceToBackBuffer(m_pText2Surface,
806 m_text2SizeOnSurface,
807 m_currentMode.height -
808 m_text2SizeOnSurface.cy);
809 }
810
811 BOOL
TextToTextSurface(const char * text,IDirectDrawSurface * pSurface,SIZE & textSizeOnSurface)812 WrapDD::TextToTextSurface(const char *text,
813 IDirectDrawSurface * pSurface,
814 SIZE & textSizeOnSurface)
815 {
816 HRESULT result;
817 HDC hdc;
818 RECT rc;
819 size_t textLength;
820
821 if (!pSurface)
822 return FALSE;
823
824 result = pSurface->GetDC(&hdc);
825 if (result != DD_OK)
826 {
827 Error("GetDC for text surface failed", result);
828 return FALSE;
829 }
830
831 textLength = strlen(text);
832
833 SelectObject(hdc, m_hFont);
834 SetTextColor(hdc, RGB(255, 255, 0));
835 SetBkColor(hdc, RGB(0, 0, 0));
836 SetBkMode(hdc, OPAQUE);
837 GetTextExtentPoint32(hdc, text, textLength, &textSizeOnSurface);
838 SetRect(&rc, 0, 0, textSizeOnSurface.cx, textSizeOnSurface.cy);
839 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, text, textLength, NULL);
840 pSurface->ReleaseDC(hdc);
841
842 return TRUE;
843 }
844
TextToTextSurface1(const char * text)845 BOOL WrapDD::TextToTextSurface1(const char *text)
846 {
847 return TextToTextSurface(text, m_pText1Surface, m_text1SizeOnSurface);
848 }
849
TextToTextSurface2(const char * text)850 BOOL WrapDD::TextToTextSurface2(const char *text)
851 {
852 return TextToTextSurface(text, m_pText2Surface, m_text2SizeOnSurface);
853 }
854
CreateTextSurfaces()855 BOOL WrapDD::CreateTextSurfaces()
856 {
857 HRESULT result;
858 DDCOLORKEY ddck;
859 DDSURFACEDESC ddsd;
860 HDC hdc;
861 char dummyinfo[] = "000x000x00 (RAMP) 0000";
862 char dummyfps[] = "000.00 fps (000.00 fps (000.00 fps) 00000 tps)";
863 /*
864 * Create the font.
865 */
866 if (m_hFont != NULL)
867 {
868 DeleteObject(m_hFont);
869 }
870 m_hFont = CreateFont(m_currentMode.width <= 600 ? 12 : 24,
871 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
872 ANSI_CHARSET,
873 OUT_DEFAULT_PRECIS,
874 CLIP_DEFAULT_PRECIS,
875 DEFAULT_QUALITY, VARIABLE_PITCH, "Arial");
876
877 hdc = GetDC(NULL);
878 SelectObject(hdc, m_hFont);
879 GetTextExtentPoint(hdc, dummyfps, strlen(dummyfps),
880 &m_text1SizeOnSurface);
881 GetTextExtentPoint(hdc, dummyinfo, strlen(dummyinfo),
882 &m_text2SizeOnSurface);
883 ReleaseDC(NULL, hdc);
884
885 memset(&ddsd, 0, sizeof(ddsd));
886 ddsd.dwSize = sizeof(ddsd);
887 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
888 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
889 if (m_bOnlySystemMemory)
890 ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
891 ddsd.dwHeight = m_text1SizeOnSurface.cy;
892 ddsd.dwWidth = m_text1SizeOnSurface.cx;
893 result = CreateDDSurface(&ddsd, &m_pText1Surface, NULL);
894 // TRACE("Created Text1 Surface<0x%x>\n", (void*) m_pText1Surface);
895 if (result != DD_OK)
896 {
897 Error("CreateSurface for text surface 1 failed", result);
898 return FALSE;
899 }
900 memset(&ddck, 0, sizeof(ddck));
901 m_pText1Surface->SetColorKey(DDCKEY_SRCBLT, &ddck);
902 if (!TextToTextSurface1(dummyfps))
903 return FALSE;
904
905 memset(&ddsd, 0, sizeof(ddsd));
906 ddsd.dwSize = sizeof(ddsd);
907 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
908 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
909 if (m_bOnlySystemMemory)
910 ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
911 ddsd.dwHeight = m_text2SizeOnSurface.cy;
912 ddsd.dwWidth = m_text2SizeOnSurface.cx;
913 result = CreateDDSurface(&ddsd, &m_pText2Surface, NULL);
914 // TRACE("Created Text2 Surface<0x%x>\n", (void*) m_pText2Surface);
915 if (result != DD_OK)
916 {
917 Error("CreateSurface for text surface 2 failed", result);
918 return FALSE;
919 }
920 memset(&ddck, 0, sizeof(ddck));
921 m_pText2Surface->SetColorKey(DDCKEY_SRCBLT, &ddck);
922 if (!TextToTextSurface2(dummyinfo))
923 return FALSE;
924 return TRUE;
925 }
926
927 // Restores any lost surfaces.
RestoreSurfaces()928 BOOL WrapDD::RestoreSurfaces()
929 {
930 HRESULT result;
931
932 if (m_pFrontBuffer->IsLost() == DDERR_SURFACELOST)
933 {
934 result = m_pFrontBuffer->Restore();
935 if (result != DD_OK)
936 {
937 Error("Restore of front buffer failed", result);
938 return FALSE;
939 }
940 }
941 if (m_pBackBuffer->IsLost() == DDERR_SURFACELOST)
942 {
943 result = m_pBackBuffer->Restore();
944 if (result != DD_OK)
945 {
946 Error("Restore of back buffer failed", result);
947 return FALSE;
948 }
949 }
950 if (m_pZBuffer->IsLost() == DDERR_SURFACELOST)
951 {
952 result = m_pZBuffer->Restore();
953 if (result != DD_OK)
954 {
955 Error("Restore of Z-buffer failed", result);
956 return FALSE;
957 }
958 }
959 if (m_pText1Surface->IsLost() == DDERR_SURFACELOST)
960 {
961 result = m_pText1Surface->Restore();
962 if (result != DD_OK)
963 {
964 Error("Restore of text surface 1 failed", result);
965 return FALSE;
966 }
967 }
968 if (m_pText2Surface->IsLost() == DDERR_SURFACELOST)
969 {
970 result = m_pText2Surface->Restore();
971 if (result != DD_OK)
972 {
973 Error("Restore of text surface 2 failed", result);
974 return FALSE;
975 }
976 }
977
978 return TRUE;
979 }
980
981 /*************************************************************************
982 Enumerating the display modes.
983 *************************************************************************/
984
EnumDisplayModesCallback(LPDDSURFACEDESC pddsd,LPVOID pContext)985 HRESULT CALLBACK WrapDD::EnumDisplayModesCallback(LPDDSURFACEDESC pddsd,
986 LPVOID pContext)
987 {
988 WrapDD *pDirectDraw = (WrapDD *)pContext;
989
990 return pDirectDraw->EnumDisplayModesCallback(pddsd);
991 }
992
EnumDisplayModesCallback(LPDDSURFACEDESC pddsd)993 HRESULT WrapDD::EnumDisplayModesCallback(LPDDSURFACEDESC pddsd)
994 {
995 if (FilterDisplayModes(pddsd))
996 {
997 m_modes[m_modeCount].width = pddsd->dwWidth;
998 m_modes[m_modeCount].height = pddsd->dwHeight;
999 m_modes[m_modeCount].bitsPerPixel =
1000 pddsd->ddpfPixelFormat.dwRGBBitCount;
1001 // TRACE("DisplayMode %d [%dx%dx%d]\n",
1002 // m_modeCount,
1003 // m_modes[m_modeCount].width,
1004 // m_modes[m_modeCount].height,
1005 // m_modes[m_modeCount].bitsPerPixel);
1006 m_modeCount++;
1007 }
1008
1009 if (m_modeCount >= (sizeof(m_modes) / sizeof(m_modes[0])))
1010 {
1011 assert(0);
1012 return DDENUMRET_CANCEL;
1013 }
1014
1015 return DDENUMRET_OK;
1016 }
1017
FilterDisplayModes(LPDDSURFACEDESC)1018 BOOL WrapDD::FilterDisplayModes(LPDDSURFACEDESC)
1019 {
1020 return TRUE;
1021 }
1022
1023 // Compare two display modes for sorting purposes.
CompareModes(const void * element1,const void * element2)1024 int _cdecl WrapDD::CompareModes(const void *element1, const void *element2)
1025 {
1026 Mode *pMode1 = (Mode *) element1;
1027 Mode *pMode2 = (Mode *) element2;
1028
1029 if (pMode1->bitsPerPixel > pMode2->bitsPerPixel)
1030 return -1;
1031 else if (pMode2->bitsPerPixel > pMode1->bitsPerPixel)
1032 return 1;
1033 else if (pMode1->width > pMode2->width)
1034 return -1;
1035 else if (pMode2->width > pMode1->width)
1036 return 1;
1037 else if (pMode1->height > pMode2->height)
1038 return -1;
1039 else if (pMode2->height > pMode1->height)
1040 return 1;
1041 else
1042 return 0;
1043 }
1044
1045 // Generates the list of available display modes.
EnumerateDisplayModes()1046 BOOL WrapDD::EnumerateDisplayModes()
1047 {
1048 HRESULT result;
1049
1050 m_modeCount = 0;
1051 result = m_pDirectDraw->EnumDisplayModes(0, 0, (void *)this,
1052 EnumDisplayModesCallback);
1053 if (result != DD_OK)
1054 {
1055 Error("EnumDisplayModes failed", result);
1056 return FALSE;
1057 }
1058 qsort((void *)&m_modes[0], (size_t) m_modeCount, sizeof(m_modes[0]),
1059 CompareModes);
1060
1061 return TRUE;
1062 }
1063
1064 /*************************************************************************
1065 Direct3D initialization
1066 *************************************************************************/
1067
CreateZBuffer(DWORD memorytype,DWORD depth)1068 BOOL WrapDD::CreateZBuffer(DWORD memorytype, DWORD depth)
1069 {
1070 HRESULT result;
1071 LPDIRECTDRAWSURFACE lpZBuffer;
1072 DDSURFACEDESC ddsd;
1073
1074 // Create a Z-Buffer and attach it to the back buffer.
1075
1076 memset(&ddsd, 0, sizeof(ddsd));
1077 ddsd.dwSize = sizeof(ddsd);
1078 ddsd.dwFlags =
1079 DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH;
1080 ddsd.dwHeight = m_currentMode.height;
1081 ddsd.dwWidth = m_currentMode.width;
1082 ddsd.dwZBufferBitDepth = depth;
1083 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | memorytype;
1084 result = CreateDDSurface(&ddsd, &lpZBuffer, 0);
1085
1086 // TRACE("Created Z Buffer<0x%x>\n", (void*) lpZBuffer);
1087
1088 if (result != DD_OK)
1089 {
1090 Error("CreateSurface for fullScreen Z-buffer failed", result);
1091 return FALSE;
1092 }
1093
1094 result = m_pBackBuffer->AddAttachedSurface(lpZBuffer);
1095 if (result != DD_OK)
1096 {
1097 Error("AddAttachedBuffer failed for Z-Buffer", result);
1098 return FALSE;
1099 }
1100
1101 m_pZBuffer = lpZBuffer;
1102 return TRUE;
1103 }
1104
1105 // application should call this when it "pauses"
Pause(BOOL pause)1106 BOOL WrapDD::Pause(BOOL pause)
1107 {
1108 if (pause)
1109 {
1110 ++m_pauseCount;
1111
1112 if (m_pauseCount > 1)
1113 {
1114 return TRUE;
1115 }
1116
1117 if (!RestoreOriginalPaletteEntries())
1118 {
1119 return FALSE;
1120 }
1121
1122 if (m_bFullScreen)
1123 {
1124 if (!FlipToGDISurface())
1125 {
1126 return FALSE;
1127 }
1128
1129 // ???
1130 DrawMenuBar(m_hWndMain);
1131 RedrawWindow(m_hWndMain, NULL, NULL, RDW_FRAME);
1132 }
1133 }
1134 else
1135 {
1136 --m_pauseCount;
1137
1138 if (m_pauseCount > 0)
1139 {
1140 return TRUE;
1141 }
1142
1143 if (m_pauseCount < 0)
1144 {
1145 m_pauseCount = 0;
1146 }
1147
1148 if (!RestorePaletteEntries())
1149 {
1150 return FALSE;
1151 }
1152 }
1153
1154 return TRUE;
1155 }
1156
Flip()1157 BOOL WrapDD::Flip()
1158 {
1159 HRESULT result;
1160
1161 result = m_pFrontBuffer->Flip(m_pBackBuffer, DDFLIP_WAIT);
1162 if (result != DD_OK)
1163 {
1164 Error("Flip failed", result);
1165 }
1166
1167 return (result == DD_OK);
1168 }
1169
BltBackBuffer(RECT & to,RECT & from)1170 BOOL WrapDD::BltBackBuffer(RECT &to, RECT &from)
1171 {
1172 HRESULT result;
1173
1174 result = m_pFrontBuffer->Blt(&to, m_pBackBuffer, &from, DDBLT_WAIT, NULL);
1175 if (result != DD_OK)
1176 {
1177 Error("Blt of back to front buffer failed", result);
1178 }
1179
1180 return (result == DD_OK);
1181 }
1182
Activate()1183 BOOL WrapDD::Activate()
1184 {
1185 if (m_bPrimaryPalettized)
1186 {
1187 HRESULT result;
1188
1189 result = m_pFrontBuffer->SetPalette(m_pPalette);
1190 if (result != DD_OK)
1191 {
1192 Error("SetPalette on front buffer failed", result);
1193 }
1194
1195 return (result == DD_OK);
1196 }
1197
1198 return TRUE;
1199 }
1200
RestorePaletteEntries()1201 BOOL WrapDD::RestorePaletteEntries()
1202 {
1203 if (m_bFullScreen && m_bPrimaryPalettized)
1204 {
1205 if (m_pPalette)
1206 {
1207 HRESULT result;
1208
1209 result = m_pPalette->SetEntries(0, 0,
1210 sizeof(m_paletteEntries) /
1211 sizeof(m_paletteEntries[0]),
1212 m_paletteEntries);
1213 if (result != DD_OK)
1214 {
1215 Error("SetEntries failed", result);
1216 return FALSE;
1217 }
1218 }
1219 }
1220
1221 return TRUE;
1222 }
1223
RestoreOriginalPaletteEntries()1224 BOOL WrapDD::RestoreOriginalPaletteEntries()
1225 {
1226 if (m_bPrimaryPalettized)
1227 {
1228 #if 0
1229 HRESULT result;
1230
1231 result = m_pPalette->GetEntries(0, 0, 256, &m_paletteEntries[0]);
1232 if (result != DD_OK)
1233 {
1234 Error("GetEntries failed", result);
1235 return FALSE;
1236 }
1237
1238 for (int i = 10; i < 246; i++)
1239 {
1240 m_originalPaletteEntries[i] = m_paletteEntries[i];
1241 }
1242 #endif
1243 if (m_pPalette)
1244 {
1245 HRESULT result;
1246
1247 result = m_pPalette->SetEntries(0, 0,
1248 sizeof(m_originalPaletteEntries) /
1249 sizeof(m_originalPaletteEntries
1250 [0]),
1251 m_originalPaletteEntries);
1252 if (result != DD_OK)
1253 {
1254 Error("SetEntries failed", result);
1255 return FALSE;
1256 }
1257 }
1258 }
1259
1260 return TRUE;
1261 }
1262
FlipToGDISurface()1263 BOOL WrapDD::FlipToGDISurface()
1264 {
1265 if (m_pDirectDraw)
1266 {
1267 HRESULT result;
1268
1269 result = m_pDirectDraw->FlipToGDISurface();
1270 if (result != DD_OK)
1271 {
1272 Error("FlipToGDISurface failed", result);
1273 }
1274
1275 return (result == DD_OK);
1276 }
1277
1278 return TRUE;
1279 }
1280
1281 #if 0
1282 // ???
1283 case WM_PAINT:
1284 if (stat.bFullscreen && !app.bAppPaused)
1285 {
1286 ValidateRect(hWnd, NULL);
1287 return 1;
1288 }
1289 break;
1290 case WM_NCPAINT:
1291 if (stat.bFullscreen && !app.bAppPaused)
1292 return 1;
1293 break;
1294 case WM_ERASEBKGND:
1295 if (stat.bFullscreen && !app.bAppPaused)
1296 return 1;
1297 break;
1298 case WM_MOVING:
1299 if (stat.bFullscreen)
1300 {
1301 GetWindowRect(app.hWndMain, (LPRECT) lParam);
1302 return 1;
1303 }
1304 break;
1305 case WM_MOVE:
1306 p1.x = p1.y = 0;
1307 ClientToScreen(app.hWndMain, &p1);
1308 p2.x = app.Mode.cx;
1309 p2.y = app.Mode.cy;
1310 ClientToScreen(app.hWndMain, &p2);
1311 SetRect(&app.rcClient, p1.x, p1.y, p2.x, p2.y);
1312 break;
1313
1314 case WM_SIZE:
1315 ...;
1316 if (app.Mode.cx > szWindowsDisplay.cx)
1317 app.Mode.cx = szWindowsDisplay.cx;
1318 if (app.Mode.cy > szWindowsDisplay.cy)
1319 app.Mode.cy = szWindowsDisplay.cy;
1320 ...break;
1321
1322 case MENU_FULLSCREEN:
1323 if (!dd.bIsPrimary)
1324 break;
1325 stat.bFullscreen = !stat.bFullscreen;
1326 if (!SwitchMode())
1327 {
1328 CleanUpAndPostQuit();
1329 break;
1330 }
1331 #endif
1332
FatalError(const char * message,HRESULT error)1333 void WrapDD::FatalError(const char *message, HRESULT error)
1334 {
1335 static BOOL g_isInsideFatalError = FALSE;
1336
1337 if (g_isInsideFatalError)
1338 {
1339 return;
1340 }
1341
1342 g_isInsideFatalError = TRUE;
1343
1344 Destroy();
1345
1346 if (m_pFatalErrorHandler)
1347 {
1348 m_pFatalErrorHandler(message, error, m_pFatalErrorHandlerArg);
1349 }
1350 }
1351
Error(const char * message,HRESULT error)1352 void WrapDD::Error(const char *message, HRESULT error)
1353 {
1354 static BOOL g_isInsideError = FALSE;
1355
1356 if (g_isInsideError)
1357 {
1358 return;
1359 }
1360
1361 g_isInsideError = TRUE;
1362
1363 Destroy();
1364
1365 if (m_pErrorHandler)
1366 {
1367 m_pErrorHandler(message, error, m_pErrorHandlerArg);
1368 }
1369
1370 g_isInsideError = FALSE;
1371 }
1372
1373 // Returns a pointer to a string describing the given error code.
ErrorToString(HRESULT error)1374 const char *WrapDD::ErrorToString(HRESULT error)
1375 {
1376 switch (error)
1377 {
1378 case DD_OK:
1379 return "No error.\0";
1380 case DDERR_ALREADYINITIALIZED:
1381 return "This object is already initialized.\0";
1382 case DDERR_BLTFASTCANTCLIP:
1383 return
1384 "Return if a clipper object is attached to the source surface passed into a BltFast call.\0";
1385 case DDERR_CANNOTATTACHSURFACE:
1386 return "This surface can not be attached to the requested surface.\0";
1387 case DDERR_CANNOTDETACHSURFACE:
1388 return
1389 "This surface can not be detached from the requested surface.\0";
1390 case DDERR_CANTCREATEDC:
1391 return "Windows can not create any more DCs.\0";
1392 case DDERR_CANTDUPLICATE:
1393 return
1394 "Can't duplicate primary & 3D surfaces, or surfaces that are implicitly created.\0";
1395 case DDERR_CLIPPERISUSINGHWND:
1396 return
1397 "An attempt was made to set a cliplist for a clipper object that is already monitoring an hwnd.\0";
1398 case DDERR_COLORKEYNOTSET:
1399 return "No src color key specified for this operation.\0";
1400 case DDERR_CURRENTLYNOTAVAIL:
1401 return "Support is currently not available.\0";
1402 case DDERR_DIRECTDRAWALREADYCREATED:
1403 return
1404 "A DirectDraw object representing this driver has already been created for this process.\0";
1405 case DDERR_EXCEPTION:
1406 return
1407 "An exception was encountered while performing the requested operation.\0";
1408 case DDERR_EXCLUSIVEMODEALREADYSET:
1409 return
1410 "An attempt was made to set the cooperative level when it was already set to exclusive.\0";
1411 case DDERR_GENERIC:
1412 return "Generic failure.\0";
1413 case DDERR_HEIGHTALIGN:
1414 return
1415 "Height of rectangle provided is not a multiple of reqd alignment.\0";
1416 case DDERR_HWNDALREADYSET:
1417 return
1418 "The CooperativeLevel HWND has already been set. It can not be reset while the process has surfaces or palettes created.\0";
1419 case DDERR_HWNDSUBCLASSED:
1420 return
1421 "HWND used by DirectDraw CooperativeLevel has been subclassed, this prevents DirectDraw from restoring state.\0";
1422 case DDERR_IMPLICITLYCREATED:
1423 return
1424 "This surface can not be restored because it is an implicitly created surface.\0";
1425 case DDERR_INCOMPATIBLEPRIMARY:
1426 return
1427 "Unable to match primary surface creation request with existing primary surface.\0";
1428 case DDERR_INVALIDCAPS:
1429 return
1430 "One or more of the caps bits passed to the callback are incorrect.\0";
1431 case DDERR_INVALIDCLIPLIST:
1432 return "DirectDraw does not support the provided cliplist.\0";
1433 case DDERR_INVALIDDIRECTDRAWGUID:
1434 return
1435 "The GUID passed to DirectDrawCreate is not a valid DirectDraw driver identifier.\0";
1436 case DDERR_INVALIDMODE:
1437 return "DirectDraw does not support the requested mode.\0";
1438 case DDERR_INVALIDOBJECT:
1439 return
1440 "DirectDraw received a pointer that was an invalid DIRECTDRAW object.\0";
1441 case DDERR_INVALIDPARAMS:
1442 return
1443 "One or more of the parameters passed to the function are incorrect.\0";
1444 case DDERR_INVALIDPIXELFORMAT:
1445 return "The pixel format was invalid as specified.\0";
1446 case DDERR_INVALIDPOSITION:
1447 return
1448 "Returned when the position of the overlay on the destination is no longer legal for that destination.\0";
1449 case DDERR_INVALIDRECT:
1450 return "Rectangle provided was invalid.\0";
1451 case DDERR_LOCKEDSURFACES:
1452 return
1453 "Operation could not be carried out because one or more surfaces are locked.\0";
1454 case DDERR_NO3D:
1455 return "There is no 3D present.\0";
1456 case DDERR_NOALPHAHW:
1457 return
1458 "Operation could not be carried out because there is no alpha accleration hardware present or available.\0";
1459 case DDERR_NOBLTHW:
1460 return "No blitter hardware present.\0";
1461 case DDERR_NOCLIPLIST:
1462 return "No cliplist available.\0";
1463 case DDERR_NOCLIPPERATTACHED:
1464 return "No clipper object attached to surface object.\0";
1465 case DDERR_NOCOLORCONVHW:
1466 return
1467 "Operation could not be carried out because there is no color conversion hardware present or available.\0";
1468 case DDERR_NOCOLORKEY:
1469 return "Surface doesn't currently have a color key\0";
1470 case DDERR_NOCOLORKEYHW:
1471 return
1472 "Operation could not be carried out because there is no hardware support of the destination color key.\0";
1473 case DDERR_NOCOOPERATIVELEVELSET:
1474 return
1475 "Create function called without DirectDraw object method SetCooperativeLevel being called.\0";
1476 case DDERR_NODC:
1477 return "No DC was ever created for this surface.\0";
1478 case DDERR_NODDROPSHW:
1479 return "No DirectDraw ROP hardware.\0";
1480 case DDERR_NODIRECTDRAWHW:
1481 return
1482 "A hardware-only DirectDraw object creation was attempted but the driver did not support any hardware.\0";
1483 case DDERR_NOEMULATION:
1484 return "Software emulation not available.\0";
1485 case DDERR_NOEXCLUSIVEMODE:
1486 return
1487 "Operation requires the application to have exclusive mode but the application does not have exclusive mode.\0";
1488 case DDERR_NOFLIPHW:
1489 return "Flipping visible surfaces is not supported.\0";
1490 case DDERR_NOGDI:
1491 return "There is no GDI present.\0";
1492 case DDERR_NOHWND:
1493 return
1494 "Clipper notification requires an HWND or no HWND has previously been set as the CooperativeLevel HWND.\0";
1495 case DDERR_NOMIRRORHW:
1496 return
1497 "Operation could not be carried out because there is no hardware present or available.\0";
1498 case DDERR_NOOVERLAYDEST:
1499 return
1500 "Returned when GetOverlayPosition is called on an overlay that UpdateOverlay has never been called on to establish a destination.\0";
1501 case DDERR_NOOVERLAYHW:
1502 return
1503 "Operation could not be carried out because there is no overlay hardware present or available.\0";
1504 case DDERR_NOPALETTEATTACHED:
1505 return "No palette object attached to this surface.\0";
1506 case DDERR_NOPALETTEHW:
1507 return "No hardware support for 16 or 256 color palettes.\0";
1508 case DDERR_NORASTEROPHW:
1509 return
1510 "Operation could not be carried out because there is no appropriate raster op hardware present or available.\0";
1511 case DDERR_NOROTATIONHW:
1512 return
1513 "Operation could not be carried out because there is no rotation hardware present or available.\0";
1514 case DDERR_NOSTRETCHHW:
1515 return
1516 "Operation could not be carried out because there is no hardware support for stretching.\0";
1517 case DDERR_NOT4BITCOLOR:
1518 return
1519 "DirectDrawSurface is not in 4 bit color palette and the requested operation requires 4 bit color palette.\0";
1520 case DDERR_NOT4BITCOLORINDEX:
1521 return
1522 "DirectDrawSurface is not in 4 bit color index palette and the requested operation requires 4 bit color index palette.\0";
1523 case DDERR_NOT8BITCOLOR:
1524 return
1525 "DirectDrawSurface is not in 8 bit color mode and the requested operation requires 8 bit color.\0";
1526 case DDERR_NOTAOVERLAYSURFACE:
1527 return
1528 "Returned when an overlay member is called for a non-overlay surface.\0";
1529 case DDERR_NOTEXTUREHW:
1530 return
1531 "Operation could not be carried out because there is no texture mapping hardware present or available.\0";
1532 case DDERR_NOTFLIPPABLE:
1533 return
1534 "An attempt has been made to flip a surface that is not flippable.\0";
1535 case DDERR_NOTFOUND:
1536 return "Requested item was not found.\0";
1537 case DDERR_NOTLOCKED:
1538 return
1539 "Surface was not locked. An attempt to unlock a surface that was not locked at all, or by this process, has been attempted.\0";
1540 case DDERR_NOTPALETTIZED:
1541 return "The surface being used is not a palette-based surface.\0";
1542 case DDERR_NOVSYNCHW:
1543 return
1544 "Operation could not be carried out because there is no hardware support for vertical blank synchronized operations.\0";
1545 case DDERR_NOZBUFFERHW:
1546 return
1547 "Operation could not be carried out because there is no hardware support for zbuffer blitting.\0";
1548 case DDERR_NOZOVERLAYHW:
1549 return
1550 "Overlay surfaces could not be z layered based on their BltOrder because the hardware does not support z layering of overlays.\0";
1551 case DDERR_OUTOFCAPS:
1552 return
1553 "The hardware needed for the requested operation has already been allocated.\0";
1554 case DDERR_OUTOFMEMORY:
1555 return
1556 "DirectDraw does not have enough memory to perform the operation.\0";
1557 case DDERR_OUTOFVIDEOMEMORY:
1558 return
1559 "DirectDraw does not have enough memory to perform the operation.\0";
1560 case DDERR_OVERLAYCANTCLIP:
1561 return "The hardware does not support clipped overlays.\0";
1562 case DDERR_OVERLAYCOLORKEYONLYONEACTIVE:
1563 return
1564 "Can only have ony color key active at one time for overlays.\0";
1565 case DDERR_OVERLAYNOTVISIBLE:
1566 return
1567 "Returned when GetOverlayPosition is called on a hidden overlay.\0";
1568 case DDERR_PALETTEBUSY:
1569 return
1570 "Access to this palette is being refused because the palette is already locked by another thread.\0";
1571 case DDERR_PRIMARYSURFACEALREADYEXISTS:
1572 return "This process already has created a primary surface.\0";
1573 case DDERR_REGIONTOOSMALL:
1574 return "Region passed to Clipper::GetClipList is too small.\0";
1575 case DDERR_SURFACEALREADYATTACHED:
1576 return
1577 "This surface is already attached to the surface it is being attached to.\0";
1578 case DDERR_SURFACEALREADYDEPENDENT:
1579 return
1580 "This surface is already a dependency of the surface it is being made a dependency of.\0";
1581 case DDERR_SURFACEBUSY:
1582 return
1583 "Access to this surface is being refused because the surface is already locked by another thread.\0";
1584 case DDERR_SURFACEISOBSCURED:
1585 return "Access to surface refused because the surface is obscured.\0";
1586 case DDERR_SURFACELOST:
1587 return
1588 "Access to this surface is being refused because the surface memory is gone. The DirectDrawSurface object representing this surface should have Restore called on it.\0";
1589 case DDERR_SURFACENOTATTACHED:
1590 return "The requested surface is not attached.\0";
1591 case DDERR_TOOBIGHEIGHT:
1592 return "Height requested by DirectDraw is too large.\0";
1593 case DDERR_TOOBIGSIZE:
1594 return
1595 "Size requested by DirectDraw is too large, but the individual height and width are OK.\0";
1596 case DDERR_TOOBIGWIDTH:
1597 return "Width requested by DirectDraw is too large.\0";
1598 case DDERR_UNSUPPORTED:
1599 return "Action not supported.\0";
1600 case DDERR_UNSUPPORTEDFORMAT:
1601 return "FOURCC format requested is unsupported by DirectDraw.\0";
1602 case DDERR_UNSUPPORTEDMASK:
1603 return
1604 "Bitmask in the pixel format requested is unsupported by DirectDraw.\0";
1605 case DDERR_VERTICALBLANKINPROGRESS:
1606 return "Vertical blank is in progress.\0";
1607 case DDERR_WASSTILLDRAWING:
1608 return
1609 "Informs DirectDraw that the previous Blt which is transfering information to or from this Surface is incomplete.\0";
1610 case DDERR_WRONGMODE:
1611 return
1612 "This surface can not be restored because it was created in a different mode.\0";
1613 case DDERR_XALIGN:
1614 return
1615 "Rectangle provided was not horizontally aligned on required boundary.\0";
1616 default:
1617 return "Unrecognized error value.\0";
1618 }
1619 }
1620
1621 // Local Variables:
1622 // c-basic-offset: 4
1623 // c-comment-only-line-offset: 0
1624 // c-file-offsets: ((defun-block-intro . +) (block-open . 0) (substatement-open . 0) (statement-cont . +) (statement-case-open . +4) (arglist-intro . +) (arglist-close . +) (inline-open . 0))
1625 // indent-tabs-mode: nil
1626 // End:
1627