00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #define INITGUID
00023 #include <windows.h>
00024 #include "softdrv.h"
00025 #include "ddraw.h"
00026 #include <stdio.h>
00027
00028 LPDIRECTDRAW lpDD;
00029 LPDIRECTDRAW4 lpDD4;
00030 LPDIRECTDRAWSURFACE4 lpDDSPrimary;
00031 LPDIRECTDRAWSURFACE4 lpDDSBack;
00032 BOOL bActive =TRUE;
00033 BOOL bInitDone =FALSE;
00034 BOOL bWindowed =FALSE;
00035 HWND mhWnd =NULL;
00036 static BOOL bDMA =FALSE;
00037 static BOOL bHardBlt =FALSE;
00038 static BOOL bDMAPageLock=FALSE;
00039 BOOL bBackLocked =FALSE;
00040 #ifdef STRICT
00041 WNDPROC pOldWndProc;
00042 #else
00043 FARPROC pOldWndProc;
00044 #endif
00045 HINSTANCE ddrawinst;
00046
00047 typedef HRESULT (WINAPI *LPDIRECTDRAWCREATE)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );
00048
00049 extern int NumDevices;
00050 typedef struct DecalDelayTag
00051 {
00052 LPDIRECTDRAWSURFACE4 surf;
00053 RECT srect;
00054 S32 x;
00055 S32 y;
00056 } DecalDelay;
00057
00058 static DecalDelay DecalQ[8192];
00059 static int NumDecalsQd;
00060 char* MyErrorToString(HRESULT error);
00061
00062
00063 static int CurrentModeWidth, CurrentModeHeight, CurrentModeDepth;
00064
00065
00066 BOOL WINAPI DDrawDriverEnumCallbackEx(GUID *pGUID, LPSTR pDescription, LPSTR pName, LPVOID pContext, HMONITOR hm)
00067 {
00068 LPDIRECTDRAWCREATE lpDDCreate;
00069 LPDIRECTDRAW pDD;
00070 LPDIRECTDRAW4 pDD4 =NULL;
00071 HRESULT hRet;
00072 VidEnumInfo *vinfo =&((VidEnumInfo *)pContext)[NumDevices];
00073
00074 ddrawinst =LoadLibrary("ddraw.dll");
00075
00076 if(!ddrawinst)
00077 {
00078 return DDENUMRET_CANCEL;
00079 }
00080
00081 lpDDCreate =(LPDIRECTDRAWCREATE)GetProcAddress(ddrawinst, "DirectDrawCreate");
00082 if(lpDDCreate)
00083 {
00084 hRet =lpDDCreate(NULL, &pDD, NULL);
00085 }
00086 else
00087 {
00088 return DDENUMRET_CANCEL;
00089 }
00090 vinfo->DeviceGuid =pGUID;
00091
00092 if(hRet != DD_OK)
00093 {
00094 ErrorPrintf("DirectDrawCreate FAILED : DDrawDriverEnumCallbackEx\n");
00095 return DDENUMRET_CANCEL;
00096 }
00097
00098 hRet =pDD->lpVtbl->QueryInterface(pDD, &IID_IDirectDraw4, (LPVOID *)&pDD4);
00099 if(hRet != DD_OK)
00100 {
00101 ErrorPrintf("QueryInterface FAILED : DDrawDriverEnumCallbackEx\n");
00102 return DDENUMRET_CANCEL;
00103 }
00104
00105 hRet =pDD4->lpVtbl->GetDeviceIdentifier(pDD4, &vinfo->DeviceInfo,0);
00106 hRet =pDD4->lpVtbl->GetDeviceIdentifier(pDD4, &vinfo->DeviceInfoHost, DDGDI_GETHOSTIDENTIFIER);
00107
00108 if(pDD4)
00109 {
00110 pDD4->lpVtbl->Release(pDD4);
00111 }
00112
00113 FreeLibrary(ddrawinst);
00114
00115 if(NumDevices < 16)
00116 {
00117 NumDevices++;
00118 }
00119 else
00120 {
00121 return DDENUMRET_CANCEL;
00122 }
00123 return DDENUMRET_OK;
00124 }
00125
00126 BOOL WINAPI OldDDrawDriverEnumCallback(GUID *pGUID, LPSTR pDescription, LPSTR pName, LPVOID context)
00127 {
00128 return (DDrawDriverEnumCallbackEx(pGUID, pDescription, pName, context, NULL));
00129 }
00130
00131 HRESULT WINAPI ModeCallback(LPDDSURFACEDESC2 pdds, LPVOID lParam)
00132 {
00133 VidEnumInfo *vinfo =(VidEnumInfo *)lParam;
00134
00135 if(pdds->ddpfPixelFormat.dwRGBBitCount==vinfo->bpp)
00136 {
00137 vinfo->VidModes[vinfo->NumVidModes].width =pdds->dwWidth;
00138 vinfo->VidModes[vinfo->NumVidModes].flags =0;
00139 vinfo->VidModes[vinfo->NumVidModes].height =pdds->dwHeight;
00140 vinfo->VidModes[vinfo->NumVidModes++].bpp =pdds->ddpfPixelFormat.dwRGBBitCount;
00141 }
00142
00143 return S_FALSE;
00144 }
00145
00146 void FreeDDraw(VidEnumInfo *vinfo)
00147 {
00148 int x =0;
00149
00150 if(lpDD4)
00151 {
00152 if(vinfo->VidModes[vinfo->CurrentVidMode].current & FLIP)
00153 {
00154 lpDDSBack =NULL;
00155 }
00156 else
00157 {
00158 if(lpDDSBack)
00159 {
00160 lpDDSBack->lpVtbl->Release(lpDDSBack);
00161 lpDDSBack =NULL;
00162 }
00163 }
00164 if(lpDDSPrimary)
00165 {
00166 lpDDSPrimary->lpVtbl->Release(lpDDSPrimary);
00167 lpDDSPrimary =NULL;
00168 }
00169 lpDD4->lpVtbl->Release(lpDD4);
00170 lpDD4 =NULL;
00171 }
00172 FreeLibrary(ddrawinst);
00173 }
00174
00175 HRESULT RestoreAll(void)
00176 {
00177 HRESULT ddrval;
00178
00179 ddrval =lpDD4->lpVtbl->SetCooperativeLevel(lpDD4, mhWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
00180 if(ddrval!=DD_OK)
00181 {
00182 ErrorPrintf("Error During SetCooperativeLevel() in RestoreAll()\n%s\n", MyErrorToString(ddrval));
00183 return FALSE;
00184 }
00185
00186 ddrval =lpDD4->lpVtbl->SetDisplayMode(lpDD4, CurrentModeWidth, CurrentModeHeight, CurrentModeDepth, 0, 0);
00187 if(ddrval!=DD_OK)
00188 {
00189 ErrorPrintf("Error During SetDisplayMode() in RestoreAll()\n%s\n", MyErrorToString(ddrval));
00190 return FALSE;
00191 }
00192 ddrval =lpDD4->lpVtbl->RestoreAllSurfaces(lpDD4);
00193 if(ddrval!=DD_OK)
00194 {
00195 ErrorPrintf("Error During RestoreAllSurfaces() in RestoreAll()\n%s\n", MyErrorToString(ddrval));
00196 return FALSE;
00197 }
00198 return ddrval;
00199 }
00200
00201 void SetDDrawWindow(HWND hwnd)
00202 {
00203 mhWnd =hwnd;
00204 }
00205
00206 BOOL LockDDrawBackBuffer(DRV_Window *cwnd, RECT *wrect)
00207 {
00208 HRESULT ddrval;
00209 DDSURFACEDESC2 ddsd;
00210
00211 if(!bActive)
00212 return TRUE;
00213
00214 memset(&ddsd, 0, sizeof(DDSCAPS2));
00215 ddsd.dwSize =sizeof(ddsd);
00216 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00217
00218 lpDDSBack->lpVtbl->GetSurfaceDesc(lpDDSBack, &ddsd);
00219 if(((int)ddsd.dwWidth < wrect->right) || ((int)ddsd.dwHeight < wrect->bottom))
00220 {
00221 ErrorPrintf("ERROR: World render rect passed by the engine is larger than the drawing surface.\n");
00222 ErrorPrintf("WorldRect: %d, %d, %d, %d\n", wrect->left, wrect->top, wrect->right, wrect->bottom);
00223 ErrorPrintf("Surface: %d, %d\n", ddsd.dwWidth, ddsd.dwHeight);
00224 return FALSE;
00225 }
00226
00227 while(1)
00228 {
00229 ddrval =lpDDSBack->lpVtbl->Lock(lpDDSBack, wrect, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL);
00230 if(ddrval==DD_OK)
00231 {
00232 break;
00233 }
00234
00235 if(ddrval==DDERR_SURFACELOST)
00236 {
00237 ddrval =RestoreAll();
00238 if(ddrval!=DD_OK )
00239 {
00240 ErrorPrintf("Error During Lock() in LockDDrawBackBuffer()...\n");
00241 ErrorPrintf("DirectDraw Surfaces were lost and could not be restored : %s\n", MyErrorToString(ddrval));
00242 return FALSE;
00243 }
00244 }
00245 else if(ddrval!=DDERR_WASSTILLDRAWING)
00246 {
00247 ErrorPrintf("Error During Lock() in LockDDrawBackBuffer() : %s\n", MyErrorToString(ddrval));
00248 return FALSE;
00249 }
00250 SleepEx(5, FALSE);
00251 }
00252 cwnd->Buffer =(U8 *)ddsd.lpSurface;
00253 cwnd->PixelPitch=ddsd.lPitch;
00254 bBackLocked =TRUE;
00255 return TRUE;
00256 }
00257
00258 BOOL UnlockDDrawBackBuffer(DRV_Window *cwnd, RECT *wrect)
00259 {
00260 HRESULT ddrval =DD_OK;
00261
00262 if(!bActive)
00263 return TRUE;
00264
00265 while(1)
00266 {
00267 ddrval =lpDDSBack->lpVtbl->Unlock(lpDDSBack, NULL);
00268 if(ddrval==DD_OK)
00269 break;
00270
00271 if(ddrval==DDERR_SURFACELOST)
00272 {
00273 ddrval =RestoreAll();
00274 if(ddrval!=DD_OK )
00275 {
00276 ErrorPrintf("Error During Unlock() in UnlockDDrawBackBuffer()...\n");
00277 ErrorPrintf("DirectDraw Surfaces were lost and could not be restored : %s\n", MyErrorToString(ddrval));
00278 return FALSE;
00279 }
00280 }
00281 else if(ddrval!=DDERR_WASSTILLDRAWING)
00282 {
00283 ErrorPrintf("Error During Unlock() in UnlockDDrawBackBuffer() : %s\n", MyErrorToString(ddrval));
00284 return FALSE;
00285 }
00286 SleepEx(5, FALSE);
00287 }
00288 bBackLocked =FALSE;
00289 return TRUE;
00290 }
00291
00292 BOOL RefreshDDraw(DRV_Window *cwnd, VidModeList *cmode, RECT *src, RECT *dst)
00293 {
00294 HRESULT ddrval;
00295 DDSURFACEDESC2 ddsd;
00296
00297 RECT rDest, rSrc;
00298
00299 if(!bActive)
00300 {
00301 return TRUE;
00302 }
00303
00304 memset(&ddsd, 0, sizeof(DDSCAPS2));
00305 ddsd.dwSize =sizeof(ddsd);
00306 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00307
00308 lpDDSBack->lpVtbl->GetSurfaceDesc(lpDDSBack, &ddsd);
00309 rDest.left =rDest.top =0;
00310 rDest.right =ddsd.dwWidth-1;
00311 rDest.bottom=ddsd.dwHeight-1;
00312
00313 memset(&ddsd, 0, sizeof(DDSCAPS2));
00314 ddsd.dwSize =sizeof(ddsd);
00315 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00316
00317 lpDDSPrimary->lpVtbl->GetSurfaceDesc(lpDDSPrimary, &ddsd);
00318 rSrc.left =rSrc.top =0;
00319 rSrc.right =ddsd.dwWidth-1;
00320 rSrc.bottom =ddsd.dwHeight-1;
00321
00322 ddrval =DD_OK;
00323 if((cmode->current & VIDEO) && (cmode->current & FASTBLT))
00324 {
00325 while(1)
00326 {
00327 ddrval =lpDDSPrimary->lpVtbl->BltFast(lpDDSPrimary, 0, 0, lpDDSBack, NULL, 0);
00328 if(ddrval==DD_OK)
00329 {
00330 break;
00331 }
00332
00333 if(ddrval==DDERR_SURFACELOST)
00334 {
00335 ddrval =RestoreAll();
00336 if(ddrval!=DD_OK)
00337 {
00338 ErrorPrintf("Error During BltFast() in RefreshDDraw()...\n");
00339 ErrorPrintf("DirectDraw Surfaces were lost and could not be restored : %s\n", MyErrorToString(ddrval));
00340 return FALSE;
00341 }
00342 }
00343 else if(ddrval!=DDERR_WASSTILLDRAWING)
00344 {
00345 ErrorPrintf("Error During BltFast() in RefreshDDraw() : %s\n", MyErrorToString(ddrval));
00346 return FALSE;
00347 }
00348 SleepEx(5, FALSE);
00349 }
00350 }
00351 else if(cmode->current & FLIP)
00352 {
00353 while(1)
00354 {
00355 ddrval =lpDDSPrimary->lpVtbl->Flip(lpDDSPrimary, lpDDSBack, DDFLIP_NOVSYNC);
00356 if(ddrval==DD_OK)
00357 {
00358 break;
00359 }
00360
00361 if(ddrval==DDERR_SURFACELOST)
00362 {
00363 ddrval =RestoreAll();
00364 if(ddrval!=DD_OK)
00365 {
00366 ErrorPrintf("Error During Flip() in RefreshDDraw()...\n");
00367 ErrorPrintf("DirectDraw Surfaces were lost and could not be restored : %s\n", MyErrorToString(ddrval));
00368 return FALSE;
00369 }
00370 }
00371 else if(ddrval!=DDERR_WASSTILLDRAWING)
00372 {
00373 ErrorPrintf("Error During Flip() in RefreshDDraw() : %s\n", MyErrorToString(ddrval));
00374 return FALSE;
00375 }
00376 SleepEx(5, FALSE);
00377 }
00378 }
00379 else
00380 {
00381 if(cmode->current & STRETCHMODE)
00382 {
00383 while(1)
00384 {
00385 ddrval =lpDDSPrimary->lpVtbl->Blt(lpDDSPrimary, NULL, lpDDSBack, NULL, 0, NULL);
00386 if(ddrval==DD_OK)
00387 break;
00388
00389 if(ddrval==DDERR_SURFACELOST)
00390 {
00391 ddrval =RestoreAll();
00392 if(ddrval!=DD_OK)
00393 {
00394 ErrorPrintf("Error During StretchMode Blt() in RefreshDDraw()...\n");
00395 ErrorPrintf("DirectDraw Surfaces were lost and could not be restored : %s\n", MyErrorToString(ddrval));
00396 return FALSE;
00397 }
00398 }
00399 else if(ddrval!=DDERR_WASSTILLDRAWING)
00400 {
00401 ErrorPrintf("Error During StretchMode Blt() in RefreshDDraw() : %s\n", MyErrorToString(ddrval));
00402 return FALSE;
00403 }
00404 SleepEx(5, FALSE);
00405 }
00406 }
00407 else
00408 {
00409 while(1)
00410 {
00411 ddrval =lpDDSPrimary->lpVtbl->Blt(lpDDSPrimary, NULL, lpDDSBack, NULL, 0, NULL);
00412 if(ddrval==DD_OK)
00413 break;
00414
00415 if(ddrval==DDERR_SURFACELOST)
00416 {
00417 ddrval =RestoreAll();
00418 if(ddrval!=DD_OK)
00419 {
00420 ErrorPrintf("Error During Blt() in RefreshDDraw()...\n");
00421 ErrorPrintf("DirectDraw Surfaces were lost and could not be restored : %s\n", MyErrorToString(ddrval));
00422 return FALSE;
00423 }
00424 }
00425 else if(ddrval!=DDERR_WASSTILLDRAWING)
00426 {
00427 ErrorPrintf("Error During Blt() in RefreshDDraw() : %s\n", MyErrorToString(ddrval));
00428 return FALSE;
00429 }
00430 SleepEx(5, FALSE);
00431 }
00432 }
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 return TRUE;
00447 }
00448
00449
00450
00451
00452
00453 geBoolean SetDDrawMode(U32 top, VidEnumInfo *vinfo)
00454 {
00455 HRESULT ddrval;
00456 DDSURFACEDESC2 ddsd;
00457 DDSCAPS2 ddscaps;
00458
00459 if(vinfo->VidModes[top].flags & STRETCHMODE)
00460 {
00461 if((vinfo->VidModes[top].width > 640)
00462 ||((vinfo->VidModes[top].width == 640)
00463 &&(vinfo->VidModes[top].height > 480)))
00464 {
00465 ddrval =lpDD4->lpVtbl->SetDisplayMode(lpDD4, vinfo->VidModes[top].width, vinfo->VidModes[top].height, vinfo->VidModes[top].bpp, 0, 0);
00466 }
00467 else
00468 {
00469 ddrval =lpDD4->lpVtbl->SetDisplayMode(lpDD4, 640, 480, vinfo->VidModes[top].bpp, 0, 0);
00470 }
00471 vinfo->VidModes[top].current |=STRETCHMODE;
00472 }
00473 else
00474 {
00475 ddrval =lpDD4->lpVtbl->SetDisplayMode(lpDD4, vinfo->VidModes[top].width, vinfo->VidModes[top].height, vinfo->VidModes[top].bpp, 0, 0);
00476 }
00477 if(ddrval != DD_OK)
00478 {
00479 return GE_FALSE;
00480 }
00481 CurrentModeHeight =vinfo->VidModes[top].height;
00482 CurrentModeWidth =vinfo->VidModes[top].width;
00483 CurrentModeDepth =vinfo->VidModes[top].bpp;
00484
00485 if(!(vinfo->VidModes[top].flags & MODEXMODE))
00486 {
00487 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00488 ddsd.dwSize =sizeof(ddsd);
00489 ddsd.dwFlags =DDSD_CAPS;
00490 ddsd.ddsCaps.dwCaps =DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
00491
00492 ddrval =lpDD4->lpVtbl->CreateSurface(lpDD4, &ddsd, &lpDDSPrimary, NULL);
00493 if(ddrval==DD_OK)
00494 {
00495 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00496 ddsd.dwSize =sizeof(ddsd);
00497 ddsd.dwFlags =DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
00498 ddsd.ddsCaps.dwCaps =DDSCAPS_SYSTEMMEMORY;
00499 if(vinfo->VidModes[top].flags & STRETCHMODE)
00500 {
00501 if((vinfo->VidModes[top].width > 640)
00502 ||((vinfo->VidModes[top].width == 640)
00503 &&(vinfo->VidModes[top].height > 480)))
00504 {
00505 ddsd.dwHeight =640;
00506 ddsd.dwWidth =480;
00507 }
00508 else
00509 {
00510 ddsd.dwHeight =vinfo->VidModes[top].height;
00511 ddsd.dwWidth =vinfo->VidModes[top].width;
00512 }
00513 }
00514 else
00515 {
00516 ddsd.dwHeight =vinfo->VidModes[top].height;
00517 ddsd.dwWidth =vinfo->VidModes[top].width;
00518 }
00519
00520 ddrval =lpDD4->lpVtbl->CreateSurface(lpDD4, &ddsd, &lpDDSBack, NULL);
00521 if(ddrval==DD_OK)
00522 {
00523
00524
00525 memset(&ddsd, 0, sizeof(DDSCAPS2));
00526 ddsd.dwSize =sizeof(ddsd);
00527 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00528 lpDDSBack->lpVtbl->GetSurfaceDesc(lpDDSBack, &ddsd);
00529 vinfo->VidModes[top].pitch =ddsd.lPitch;
00530
00531
00532 memset(&ddscaps, 0, sizeof(DDSCAPS2));
00533 lpDDSPrimary->lpVtbl->GetCaps(lpDDSPrimary, &ddscaps);
00534 if(ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY)
00535 {
00536 memset(&ddscaps, 0, sizeof(DDSCAPS2));
00537 lpDDSBack->lpVtbl->GetCaps(lpDDSBack, &ddscaps);
00538 if(ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY)
00539 {
00540
00541 vinfo->VidModes[top].current |=VIDEO;
00542
00543
00544 if(!(vinfo->VidModes[top].flags & STRETCHMODE))
00545 {
00546 vinfo->VidModes[top].current |=FASTBLT;
00547 }
00548 }
00549 }
00550 }
00551 }
00552 else if(!(vinfo->VidModes[top].current & VIDEO)
00553 && !(vinfo->VidModes[top].current & STRETCHMODE))
00554 {
00555 if(lpDDSBack) lpDDSBack->lpVtbl->Release(lpDDSBack);
00556 if(lpDDSPrimary) lpDDSPrimary->lpVtbl->Release(lpDDSPrimary);
00557
00558 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00559 ddsd.dwSize =sizeof(ddsd);
00560 ddsd.dwFlags =DDSD_CAPS;
00561 ddsd.ddsCaps.dwCaps =DDSCAPS_PRIMARYSURFACE;
00562
00563 ddrval =lpDD4->lpVtbl->CreateSurface(lpDD4, &ddsd, &lpDDSPrimary, NULL);
00564 if(ddrval==DD_OK)
00565 {
00566 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00567 ddsd.dwSize =sizeof(ddsd);
00568 ddsd.dwFlags =DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
00569 ddsd.dwHeight =vinfo->VidModes[top].height;
00570 ddsd.dwWidth =vinfo->VidModes[top].width;
00571
00572 ddrval =lpDD4->lpVtbl->CreateSurface(lpDD4, &ddsd, &lpDDSBack, NULL);
00573 if(ddrval==DD_OK)
00574 {
00575
00576
00577 memset(&ddsd, 0, sizeof(DDSCAPS2));
00578 ddsd.dwSize =sizeof(ddsd);
00579 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00580 lpDDSBack->lpVtbl->GetSurfaceDesc(lpDDSBack, &ddsd);
00581 vinfo->VidModes[top].pitch =ddsd.lPitch;
00582
00583
00584 vinfo->VidModes[top].current |=SYSTEM|SAFEBLT;
00585 }
00586 }
00587 }
00588 }
00589 if((vinfo->VidModes[top].flags & MODEXMODE) || lpDDSBack==NULL)
00590 {
00591 if(lpDDSBack) lpDDSBack->lpVtbl->Release(lpDDSBack);
00592 if(lpDDSPrimary) lpDDSPrimary->lpVtbl->Release(lpDDSPrimary);
00593
00594
00595 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00596 ddsd.dwSize =sizeof(ddsd);
00597 ddsd.dwFlags =DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
00598 ddsd.ddsCaps.dwCaps =DDSCAPS_PRIMARYSURFACE |
00599 DDSCAPS_COMPLEX | DDSCAPS_FLIP;
00600 ddsd.dwBackBufferCount =1;
00601
00602 ddrval =lpDD4->lpVtbl->CreateSurface(lpDD4, &ddsd, &lpDDSPrimary, NULL);
00603 if(ddrval==DD_OK)
00604 {
00605 memset(&ddscaps, 0, sizeof(DDSCAPS2));
00606 ddscaps.dwCaps =DDSCAPS_BACKBUFFER;
00607 ddrval =lpDDSPrimary->lpVtbl->GetAttachedSurface(lpDDSPrimary, &ddscaps, &lpDDSBack);
00608 if(ddrval==DD_OK)
00609 {
00610
00611
00612 memset(&ddsd, 0, sizeof(DDSCAPS2));
00613 ddsd.dwSize =sizeof(ddsd);
00614 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00615 lpDDSBack->lpVtbl->GetSurfaceDesc(lpDDSBack, &ddsd);
00616 vinfo->VidModes[top].pitch =ddsd.lPitch;
00617
00618 vinfo->VidModes[top].current |=SYSTEM|FLIP;
00619 }
00620 }
00621 }
00622
00623 return GE_TRUE;
00624 }
00625
00626
00627
00628
00629
00630 void SortDDrawVideoModeList(VidEnumInfo *vinfo)
00631 {
00632 int top, search;
00633 VidModeList temp;
00634 DDSURFACEDESC2 ddsd;
00635 DDSCAPS2 ddscaps;
00636 HRESULT ddrval;
00637
00638 for(top=0;top < vinfo->NumVidModes;top++)
00639 {
00640 if(vinfo->VidModes[top].flags & MODEXMODE)
00641 {
00642
00643 vinfo->VidModes[top].flags |=(SYSTEM | FLIP);
00644 }
00645 else
00646 {
00647 vinfo->VidModes[top].flags |=SAFEBLT;
00648 ddrval =lpDD4->lpVtbl->SetDisplayMode(lpDD4, vinfo->VidModes[top].width, vinfo->VidModes[top].height, vinfo->VidModes[top].bpp, 0, 0);
00649
00650
00651 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00652 ddsd.dwSize =sizeof(ddsd);
00653 ddsd.dwFlags =DDSD_CAPS;
00654 ddsd.ddsCaps.dwCaps =DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
00655
00656 ddrval =lpDD4->lpVtbl->CreateSurface(lpDD4, &ddsd, &lpDDSPrimary, NULL);
00657 if(ddrval==DD_OK)
00658 {
00659 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00660 ddsd.dwSize =sizeof(ddsd);
00661 ddsd.dwFlags =DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
00662 ddsd.dwHeight =vinfo->VidModes[top].height;
00663 ddsd.dwWidth =vinfo->VidModes[top].width;
00664
00665 ddrval =lpDD4->lpVtbl->CreateSurface(lpDD4, &ddsd, &lpDDSBack, NULL);
00666 if(ddrval==DD_OK)
00667 {
00668
00669
00670 memset(&ddscaps, 0, sizeof(DDSCAPS2));
00671 lpDDSPrimary->lpVtbl->GetCaps(lpDDSPrimary, &ddscaps);
00672 if(ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY)
00673 {
00674 memset(&ddscaps, 0, sizeof(DDSCAPS2));
00675 lpDDSBack->lpVtbl->GetCaps(lpDDSBack, &ddscaps);
00676 if(ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY)
00677 {
00678
00679 vinfo->VidModes[top].flags |=VIDEO;
00680 }
00681 }
00682 lpDDSBack->lpVtbl->Release(lpDDSBack);
00683 }
00684 lpDDSPrimary->lpVtbl->Release(lpDDSPrimary);
00685 }
00686
00687 if(bDMA)
00688 {
00689
00690 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00691 ddsd.dwSize =sizeof(ddsd);
00692 ddsd.dwFlags =DDSD_CAPS;
00693 ddsd.ddsCaps.dwCaps =DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY;
00694
00695 ddrval =lpDD4->lpVtbl->CreateSurface(lpDD4, &ddsd, &lpDDSPrimary, NULL);
00696 if(ddrval==DD_OK)
00697 {
00698 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00699 ddsd.dwSize =sizeof(ddsd);
00700 ddsd.dwFlags =DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
00701 ddsd.ddsCaps.dwCaps =DDSCAPS_SYSTEMMEMORY;
00702 ddsd.dwHeight =vinfo->VidModes[top].height;
00703 ddsd.dwWidth =vinfo->VidModes[top].width;
00704
00705 ddrval =lpDD4->lpVtbl->CreateSurface(lpDD4, &ddsd, &lpDDSBack, NULL);
00706 if(ddrval==DD_OK)
00707 {
00708 memset(&ddscaps, 0, sizeof(DDSCAPS2));
00709 lpDDSPrimary->lpVtbl->GetCaps(lpDDSPrimary, &ddscaps);
00710 if(ddscaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
00711 {
00712 memset(&ddscaps, 0, sizeof(DDSCAPS2));
00713 lpDDSBack->lpVtbl->GetCaps(lpDDSBack, &ddscaps);
00714 if(ddscaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
00715 {
00716
00717 vinfo->VidModes[top].flags |=(SYSTEM|DMABLT);
00718 }
00719 }
00720 lpDDSBack->lpVtbl->Release(lpDDSBack);
00721 }
00722 lpDDSPrimary->lpVtbl->Release(lpDDSPrimary);
00723 }
00724 }
00725
00726
00727 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00728 ddsd.dwSize =sizeof(ddsd);
00729 ddsd.dwFlags =DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
00730 ddsd.ddsCaps.dwCaps =DDSCAPS_PRIMARYSURFACE |
00731 DDSCAPS_COMPLEX | DDSCAPS_FLIP;
00732 ddsd.dwBackBufferCount =1;
00733
00734 ddrval =lpDD4->lpVtbl->CreateSurface(lpDD4, &ddsd, &lpDDSPrimary, NULL);
00735 if(ddrval==DD_OK)
00736 {
00737 memset(&ddscaps, 0, sizeof(DDSCAPS2));
00738 ddscaps.dwCaps =DDSCAPS_BACKBUFFER;
00739 ddrval =lpDDSPrimary->lpVtbl->GetAttachedSurface(lpDDSPrimary, &ddscaps, &lpDDSBack);
00740 if(ddrval==DD_OK)
00741 {
00742
00743
00744 memset(&ddsd, 0, sizeof(DDSCAPS2));
00745 ddsd.dwSize =sizeof(ddsd);
00746 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00747 lpDDSBack->lpVtbl->GetSurfaceDesc(lpDDSBack, &ddsd);
00748 vinfo->VidModes[top].pitch =ddsd.lPitch;
00749
00750 vinfo->VidModes[top].flags |=(SYSTEM|FLIP);
00751 lpDDSPrimary->lpVtbl->Release(lpDDSPrimary);
00752 }
00753 }
00754
00755 if(bHardBlt)
00756 {
00757 vinfo->VidModes[top].flags |=HARDWARE;
00758 }
00759 }
00760 }
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 for(top=0;top < vinfo->NumVidModes-1;top++)
00781 {
00782 for(search=top+1;search < vinfo->NumVidModes;search++)
00783 {
00784 if(vinfo->VidModes[search].width < vinfo->VidModes[top].width)
00785 {
00786 temp =vinfo->VidModes[search];
00787
00788 vinfo->VidModes[search]=vinfo->VidModes[top];
00789 vinfo->VidModes[top] =temp;
00790 }
00791 }
00792 }
00793 }
00794
00795 BOOL DoDDrawInit(HWND hwnd, VidEnumInfo *vinfo)
00796 {
00797 LPDIRECTDRAWCREATE lpDDCreate;
00798 HRESULT ddrval;
00799
00800 bInitDone =FALSE;
00801 ddrawinst =LoadLibrary("ddraw.dll");
00802
00803 if(!ddrawinst)
00804 {
00805 return FALSE;
00806 }
00807 SetDDrawWindow(hwnd);
00808
00809 lpDDCreate =(LPDIRECTDRAWCREATE)GetProcAddress(ddrawinst, "DirectDrawCreate");
00810 if(lpDDCreate)
00811 {
00812 ddrval =lpDDCreate(NULL, &lpDD, NULL);
00813 }
00814 else
00815 {
00816 return DDENUMRET_CANCEL;
00817 }
00818
00819 if(ddrval!=DD_OK)
00820 {
00821 ErrorPrintf("Non Fatal Error During DirectDrawCreate() in DoDDrawInit()\n%s\n", MyErrorToString(ddrval));
00822 return FALSE;
00823 }
00824
00825 ddrval = lpDD->lpVtbl->QueryInterface(lpDD, &IID_IDirectDraw4, (LPVOID *)&lpDD4);
00826 if(ddrval!=DD_OK)
00827 {
00828 ErrorPrintf("Non Fatal Error During QueryInterface() in DoDDrawInit()\n%s\n", MyErrorToString(ddrval));
00829 return FALSE;
00830 }
00831
00832 lpDD->lpVtbl->Release(lpDD);
00833 lpDD =NULL;
00834
00835 ddrval =lpDD4->lpVtbl->SetCooperativeLevel(lpDD4, mhWnd,
00836 DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
00837 if(ddrval!=DD_OK)
00838 {
00839 ErrorPrintf("Non Fatal Error During SetCooperativeLevel() in DoDDrawInit()\n%s\n", MyErrorToString(ddrval));
00840 return FALSE;
00841 }
00842 FreeLibrary(ddrawinst);
00843
00844 bInitDone =TRUE;
00845 NumDecalsQd =0;
00846 return TRUE;
00847 }
00848
00849
00850 BOOL DoEnumeration(VidEnumInfo *vinfo)
00851 {
00852 LPDIRECTDRAWCREATE lpDDCreate;
00853 LPDIRECTDRAW pDD;
00854 LPDIRECTDRAW4 pDD4 =NULL;
00855 HRESULT hRet;
00856 bInitDone =FALSE;
00857
00858
00859 ddrawinst =LoadLibrary("ddraw.dll");
00860
00861 if(!ddrawinst)
00862 {
00863 return FALSE;
00864 }
00865
00866 lpDDCreate =(LPDIRECTDRAWCREATE)GetProcAddress(ddrawinst, "DirectDrawCreate");
00867 if(lpDDCreate)
00868 {
00869 hRet =lpDDCreate(NULL, &pDD, NULL);
00870 }
00871 else
00872 {
00873 return DDENUMRET_CANCEL;
00874 }
00875
00876 vinfo->DeviceGuid =NULL;
00877
00878 if(hRet != DD_OK)
00879 {
00880 ErrorPrintf("Non Fatal Error During DirectDrawCreate() in DoEnumeration()\n%s\n", MyErrorToString(hRet));
00881 return DDENUMRET_CANCEL;
00882 }
00883 memset(&vinfo->DeviceInfo, 0, sizeof(vinfo->DeviceInfo));
00884 memset(&vinfo->DeviceInfoHost, 0, sizeof(vinfo->DeviceInfo));
00885
00886 hRet =pDD->lpVtbl->QueryInterface(pDD, &IID_IDirectDraw4, (LPVOID *)&pDD4);
00887 if(hRet != DD_OK)
00888 {
00889 ErrorPrintf("Non Fatal Error During QueryInterface() in DoEnumeration()\n%s\n", MyErrorToString(hRet));
00890 return DDENUMRET_CANCEL;
00891 }
00892
00893 hRet =pDD4->lpVtbl->GetDeviceIdentifier(pDD4, &vinfo->DeviceInfo,0);
00894 hRet =pDD4->lpVtbl->GetDeviceIdentifier(pDD4, &vinfo->DeviceInfoHost, DDGDI_GETHOSTIDENTIFIER);
00895
00896 if(pDD4)
00897 {
00898 pDD4->lpVtbl->Release(pDD4);
00899 }
00900
00901 FreeLibrary(ddrawinst);
00902
00903 if(NumDevices < 16)
00904 {
00905 NumDevices++;
00906 }
00907 else
00908 {
00909 return DDENUMRET_CANCEL;
00910 }
00911 return DDENUMRET_OK;
00912
00913 return TRUE;
00914 }
00915
00916 BOOL DoModeEnumeration(VidEnumInfo *vinfo)
00917 {
00918 LPDIRECTDRAWCREATE lpDDCreate;
00919 HRESULT ddrval;
00920 DDCAPS ddcaps;
00921
00922 bInitDone =FALSE;
00923
00924 ddrawinst =LoadLibrary("ddraw.dll");
00925
00926 if(!ddrawinst)
00927 {
00928 return FALSE;
00929 }
00930
00931 lpDDCreate =(LPDIRECTDRAWCREATE)GetProcAddress(ddrawinst, "DirectDrawCreate");
00932 if(lpDDCreate)
00933 {
00934 ddrval =lpDDCreate(NULL, &lpDD, NULL);
00935 }
00936 else
00937 {
00938 return DDENUMRET_CANCEL;
00939 }
00940
00941 if(ddrval != DD_OK)
00942 {
00943 ErrorPrintf("DirectDrawCreate FAILED : DoModeEnumeration\n%s\n", MyErrorToString(ddrval));
00944 return 0;
00945 }
00946
00947 ddrval = lpDD->lpVtbl->QueryInterface(lpDD, &IID_IDirectDraw4, (LPVOID *)&lpDD4);
00948 if(ddrval != DD_OK)
00949 {
00950 ErrorPrintf("QueryInterface FAILED : DoModeEnumeration\n%s\n", MyErrorToString(ddrval));
00951 return 0;
00952 }
00953
00954 lpDD->lpVtbl->Release(lpDD);
00955 lpDD =NULL;
00956
00957
00958 memset(&ddcaps, 0, sizeof(DDCAPS));
00959 ddcaps.dwSize =sizeof(ddcaps);
00960 lpDD4->lpVtbl->GetCaps(lpDD4, &ddcaps, NULL);
00961
00962 if(ddcaps.dwCaps & DDCAPS_CANBLTSYSMEM)
00963 {
00964 ErrorPrintf("System to video blits supported\n");
00965 if(ddcaps.dwVSBCaps & DDCAPS_BLTQUEUE)
00966 {
00967 ErrorPrintf("DMA Asynch Video to System blits supported\n");
00968 }
00969 if(ddcaps.dwSSBCaps & DDCAPS_BLTQUEUE)
00970 {
00971 ErrorPrintf("DMA Asynch System to System blits supported\n");
00972 }
00973 if(ddcaps.dwSVBCaps & DDCAPS_BLTQUEUE)
00974 {
00975 bDMA =TRUE;
00976
00977 ErrorPrintf("DMA Asynch System to Video blits supported\n");
00978 if(ddcaps.dwCaps & DDCAPS2_NOPAGELOCKREQUIRED)
00979 {
00980 ErrorPrintf("DMA Asynch page lock not required\n");
00981 }
00982 else
00983 {
00984 bDMAPageLock =TRUE;
00985 ErrorPrintf("DMA Asynch page lock required\n");
00986 }
00987 }
00988 }
00989 if(ddcaps.dwCaps2 & DDCAPS_BLT)
00990 {
00991 ErrorPrintf("Hardware Blt supported\n");
00992 bHardBlt =TRUE;
00993 }
00994
00995
00996
00997
00998
00999
01000
01001
01002 lpDD4->lpVtbl->EnumDisplayModes(lpDD4, 0, NULL, (LPVOID)vinfo, ModeCallback);
01003
01004
01005
01006 lpDD4->lpVtbl->Release(lpDD4);
01007 lpDD4 =NULL;
01008
01009 FreeLibrary(ddrawinst);
01010
01011 return TRUE;
01012 }
01013
01014 void GetDDrawPixelFormat(DRV_Window *cwnd)
01015 {
01016 DDPIXELFORMAT ddpf;
01017 U32 i, j;
01018
01019 ddpf.dwSize =sizeof(ddpf);
01020 lpDDSPrimary->lpVtbl->GetPixelFormat(lpDDSPrimary, &ddpf);
01021
01022 if(!(ddpf.dwFlags & DDPF_RGB))
01023 {
01024 return;
01025 }
01026 cwnd->BytesPerPixel =ddpf.dwRGBBitCount / 8;
01027 cwnd->R_mask =ddpf.dwRBitMask;
01028 cwnd->G_mask =ddpf.dwGBitMask;
01029 cwnd->B_mask =ddpf.dwBBitMask;
01030
01031 for(j=0,i=ddpf.dwRBitMask;!(i & 1);i>>=1,j++);
01032 cwnd->R_shift =j;
01033
01034 for(j=0,i=ddpf.dwGBitMask;!(i & 1);i>>=1,j++);
01035 cwnd->G_shift =j;
01036
01037 for(j=0,i=ddpf.dwBBitMask;!(i & 1);i>>=1,j++);
01038 cwnd->B_shift =j;
01039
01040 for(i=(ddpf.dwRBitMask>>cwnd->R_shift),cwnd->R_width=0;i;i >>= 1, cwnd->R_width++);
01041 for(i=(ddpf.dwGBitMask>>cwnd->G_shift),cwnd->G_width=0;i;i >>= 1, cwnd->G_width++);
01042 for(i=(ddpf.dwBBitMask>>cwnd->B_shift),cwnd->B_width=0;i;i >>= 1, cwnd->B_width++);
01043 }
01044
01045 LPDIRECTDRAWSURFACE4 DDrawLoadSurface(U32 dwWidth, U32 dwHeight, const void *pixels, const char *pal)
01046 {
01047 LPDIRECTDRAWSURFACE4 lpDDS;
01048 DDSURFACEDESC2 ddsd;
01049 HRESULT ddrval;
01050 int i;
01051
01052 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
01053 ddsd.dwSize =sizeof(DDSURFACEDESC2);
01054 ddsd.dwFlags =DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_CKSRCBLT;
01055 ddsd.ddsCaps.dwCaps =DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
01056 ddsd.dwHeight =dwHeight;
01057 ddsd.dwWidth =dwWidth;
01058
01059 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue =((((U8 *)pal)[765])<<16)
01060 |((((U8 *)pal)[766])<<8)
01061 |(((U8 *)pal)[767]);
01062 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue =((((U8 *)pal)[765])<<16)
01063 |((((U8 *)pal)[766])<<8)
01064 |(((U8 *)pal)[767]);
01065
01066
01067 ddrval =lpDD4->lpVtbl->CreateSurface(lpDD4, &ddsd, &lpDDS, NULL);
01068
01069 if(ddrval != DD_OK)
01070 {
01071 return NULL;
01072 }
01073
01074 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
01075 ddsd.dwSize =sizeof(DDSURFACEDESC2);
01076 ddrval =lpDDS->lpVtbl->Lock(lpDDS, NULL, &ddsd, DDLOCK_WAIT, NULL);
01077
01078 if(ddrval != DD_OK)
01079 {
01080 lpDDS->lpVtbl->Release(lpDDS);
01081 return NULL;
01082 }
01083
01084 for(i=0;i < (S32)(dwHeight * dwWidth);i++)
01085 {
01086 ((U32 *)ddsd.lpSurface)[i] =(((U8 *)pal)[(((U8 *)pixels)[i]) * 3])<<16
01087 |((((U8 *)pal)[((((U8 *)pixels)[i]) * 3)+1])<<8)
01088 |((((U8 *)pal)[((((U8 *)pixels)[i]) * 3)+2])<<0);
01089 }
01090
01091 lpDDS->lpVtbl->Unlock(lpDDS, NULL);
01092
01093 return lpDDS;
01094 }
01095
01096 char* MyErrorToString(HRESULT error)
01097 {
01098 switch(error) {
01099 case DD_OK:
01100
01101 return "No error.\0";
01102 case DDERR_ALREADYINITIALIZED:
01103 return "This object is already initialized.\0";
01104 case DDERR_BLTFASTCANTCLIP:
01105 return "Return if a clipper object is attached to the source surface passed into a BltFast call.\0";
01106 case DDERR_CANNOTATTACHSURFACE:
01107 return "This surface can not be attached to the requested surface.\0";
01108 case DDERR_CANNOTDETACHSURFACE:
01109 return "This surface can not be detached from the requested surface.\0";
01110 case DDERR_CANTCREATEDC:
01111 return "Windows can not create any more DCs.\0";
01112 case DDERR_CANTDUPLICATE:
01113 return "Can't duplicate primary & 3D surfaces, or surfaces that are implicitly created.\0";
01114 case DDERR_CLIPPERISUSINGHWND:
01115 return "An attempt was made to set a cliplist for a clipper object that is already monitoring an hwnd.\0";
01116 case DDERR_COLORKEYNOTSET:
01117 return "No src color key specified for this operation.\0";
01118 case DDERR_CURRENTLYNOTAVAIL:
01119 return "Support is currently not available.\0";
01120 case DDERR_DIRECTDRAWALREADYCREATED:
01121 return "A DirectDraw object representing this driver has already been created for this process.\0";
01122 case DDERR_EXCEPTION:
01123 return "An exception was encountered while performing the requested operation.\0";
01124 case DDERR_EXCLUSIVEMODEALREADYSET:
01125 return "An attempt was made to set the cooperative level when it was already set to exclusive.\0";
01126 case DDERR_GENERIC:
01127 return "Generic failure.\0";
01128 case DDERR_HEIGHTALIGN:
01129 return "Height of rectangle provided is not a multiple of reqd alignment.\0";
01130 case DDERR_HWNDALREADYSET:
01131 return "The CooperativeLevel HWND has already been set. It can not be reset while the process has surfaces or palettes created.\0";
01132 case DDERR_HWNDSUBCLASSED:
01133 return "HWND used by DirectDraw CooperativeLevel has been subclassed, this prevents DirectDraw from restoring state.\0";
01134 case DDERR_IMPLICITLYCREATED:
01135 return "This surface can not be restored because it is an implicitly created surface.\0";
01136 case DDERR_INCOMPATIBLEPRIMARY:
01137 return "Unable to match primary surface creation request with existing primary surface.\0";
01138 case DDERR_INVALIDCAPS:
01139 return "One or more of the caps bits passed to the callback are incorrect.\0";
01140 case DDERR_INVALIDCLIPLIST:
01141 return "DirectDraw does not support the provided cliplist.\0";
01142 case DDERR_INVALIDDIRECTDRAWGUID:
01143 return "The GUID passed to DirectDrawCreate is not a valid DirectDraw driver identifier.\0";
01144 case DDERR_INVALIDMODE:
01145 return "DirectDraw does not support the requested mode.\0";
01146 case DDERR_INVALIDOBJECT:
01147 return "DirectDraw received a pointer that was an invalid DIRECTDRAW object.\0";
01148 case DDERR_INVALIDPARAMS:
01149 return "One or more of the parameters passed to the function are incorrect.\0";
01150 case DDERR_INVALIDPIXELFORMAT:
01151 return "The pixel format was invalid as specified.\0";
01152 case DDERR_INVALIDPOSITION:
01153 return "Returned when the position of the overlay on the destination is no longer legal for that destination.\0";
01154 case DDERR_INVALIDRECT:
01155 return "Rectangle provided was invalid.\0";
01156 case DDERR_LOCKEDSURFACES:
01157 return "Operation could not be carried out because one or more surfaces are locked.\0";
01158 case DDERR_NO3D:
01159 return "There is no 3D present.\0";
01160 case DDERR_NOALPHAHW:
01161 return "Operation could not be carried out because there is no alpha accleration hardware present or available.\0";
01162 case DDERR_NOBLTHW:
01163 return "No blitter hardware present.\0";
01164 case DDERR_NOCLIPLIST:
01165 return "No cliplist available.\0";
01166 case DDERR_NOCLIPPERATTACHED:
01167 return "No clipper object attached to surface object.\0";
01168 case DDERR_NOCOLORCONVHW:
01169 return "Operation could not be carried out because there is no color conversion hardware present or available.\0";
01170 case DDERR_NOCOLORKEY:
01171 return "Surface doesn't currently have a color key\0";
01172 case DDERR_NOCOLORKEYHW:
01173 return "Operation could not be carried out because there is no hardware support of the destination color key.\0";
01174 case DDERR_NOCOOPERATIVELEVELSET:
01175 return "Create function called without DirectDraw object method SetCooperativeLevel being called.\0";
01176 case DDERR_NODC:
01177 return "No DC was ever created for this surface.\0";
01178 case DDERR_NODDROPSHW:
01179 return "No DirectDraw ROP hardware.\0";
01180 case DDERR_NODIRECTDRAWHW:
01181 return "A hardware-only DirectDraw object creation was attempted but the driver did not support any hardware.\0";
01182 case DDERR_NOEMULATION:
01183 return "Software emulation not available.\0";
01184 case DDERR_NOEXCLUSIVEMODE:
01185 return "Operation requires the application to have exclusive mode but the application does not have exclusive mode.\0";
01186 case DDERR_NOFLIPHW:
01187 return "Flipping visible surfaces is not supported.\0";
01188 case DDERR_NOGDI:
01189 return "There is no GDI present.\0";
01190 case DDERR_NOHWND:
01191 return "Clipper notification requires an HWND or no HWND has previously been set as the CooperativeLevel HWND.\0";
01192 case DDERR_NOMIRRORHW:
01193 return "Operation could not be carried out because there is no hardware present or available.\0";
01194 case DDERR_NOOVERLAYDEST:
01195 return "Returned when GetOverlayPosition is called on an overlay that UpdateOverlay has never been called on to establish a destination.\0";
01196 case DDERR_NOOVERLAYHW:
01197 return "Operation could not be carried out because there is no overlay hardware present or available.\0";
01198 case DDERR_NOPALETTEATTACHED:
01199 return "No palette object attached to this surface.\0";
01200 case DDERR_NOPALETTEHW:
01201 return "No hardware support for 16 or 256 color palettes.\0";
01202 case DDERR_NORASTEROPHW:
01203 return "Operation could not be carried out because there is no appropriate raster op hardware present or available.\0";
01204 case DDERR_NOROTATIONHW:
01205 return "Operation could not be carried out because there is no rotation hardware present or available.\0";
01206 case DDERR_NOSTRETCHHW:
01207 return "Operation could not be carried out because there is no hardware support for stretching.\0";
01208 case DDERR_NOT4BITCOLOR:
01209 return "DirectDrawSurface is not in 4 bit color palette and the requested operation requires 4 bit color palette.\0";
01210 case DDERR_NOT4BITCOLORINDEX:
01211 return "DirectDrawSurface is not in 4 bit color index palette and the requested operation requires 4 bit color index palette.\0";
01212 case DDERR_NOT8BITCOLOR:
01213 return "DirectDrawSurface is not in 8 bit color mode and the requested operation requires 8 bit color.\0";
01214 case DDERR_NOTAOVERLAYSURFACE:
01215 return "Returned when an overlay member is called for a non-overlay surface.\0";
01216 case DDERR_NOTEXTUREHW:
01217 return "Operation could not be carried out because there is no texture mapping hardware present or available.\0";
01218 case DDERR_NOTFLIPPABLE:
01219 return "An attempt has been made to flip a surface that is not flippable.\0";
01220 case DDERR_NOTFOUND:
01221 return "Requested item was not found.\0";
01222 case DDERR_NOTLOCKED:
01223 return "Surface was not locked. An attempt to unlock a surface that was not locked at all, or by this process, has been attempted.\0";
01224 case DDERR_NOTPALETTIZED:
01225 return "The surface being used is not a palette-based surface.\0";
01226 case DDERR_NOVSYNCHW:
01227 return "Operation could not be carried out because there is no hardware support for vertical blank synchronized operations.\0";
01228 case DDERR_NOZBUFFERHW:
01229 return "Operation could not be carried out because there is no hardware support for zbuffer blitting.\0";
01230 case DDERR_NOZOVERLAYHW:
01231 return "Overlay surfaces could not be z layered based on their BltOrder because the hardware does not support z layering of overlays.\0";
01232 case DDERR_OUTOFCAPS:
01233 return "The hardware needed for the requested operation has already been allocated.\0";
01234 case DDERR_OUTOFMEMORY:
01235 return "DirectDraw does not have enough memory to perform the operation.\0";
01236 case DDERR_OUTOFVIDEOMEMORY:
01237 return "DirectDraw does not have enough memory to perform the operation.\0";
01238 case DDERR_OVERLAYCANTCLIP:
01239 return "The hardware does not support clipped overlays.\0";
01240 case DDERR_OVERLAYCOLORKEYONLYONEACTIVE:
01241 return "Can only have ony color key active at one time for overlays.\0";
01242 case DDERR_OVERLAYNOTVISIBLE:
01243 return "Returned when GetOverlayPosition is called on a hidden overlay.\0";
01244 case DDERR_PALETTEBUSY:
01245 return "Access to this palette is being refused because the palette is already locked by another thread.\0";
01246 case DDERR_PRIMARYSURFACEALREADYEXISTS:
01247 return "This process already has created a primary surface.\0";
01248 case DDERR_REGIONTOOSMALL:
01249 return "Region passed to Clipper::GetClipList is too small.\0";
01250 case DDERR_SURFACEALREADYATTACHED:
01251 return "This surface is already attached to the surface it is being attached to.\0";
01252 case DDERR_SURFACEALREADYDEPENDENT:
01253 return "This surface is already a dependency of the surface it is being made a dependency of.\0";
01254 case DDERR_SURFACEBUSY:
01255 return "Access to this surface is being refused because the surface is already locked by another thread.\0";
01256 case DDERR_SURFACEISOBSCURED:
01257 return "Access to surface refused because the surface is obscured.\0";
01258 case DDERR_SURFACELOST:
01259 return "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";
01260 case DDERR_SURFACENOTATTACHED:
01261 return "The requested surface is not attached.\0";
01262 case DDERR_TOOBIGHEIGHT:
01263 return "Height requested by DirectDraw is too large.\0";
01264 case DDERR_TOOBIGSIZE:
01265 return "Size requested by DirectDraw is too large, but the individual height and width are OK.\0";
01266 case DDERR_TOOBIGWIDTH:
01267 return "Width requested by DirectDraw is too large.\0";
01268 case DDERR_UNSUPPORTED:
01269 return "Action not supported.\0";
01270 case DDERR_UNSUPPORTEDFORMAT:
01271 return "FOURCC format requested is unsupported by DirectDraw.\0";
01272 case DDERR_UNSUPPORTEDMASK:
01273 return "Bitmask in the pixel format requested is unsupported by DirectDraw.\0";
01274 case DDERR_VERTICALBLANKINPROGRESS:
01275 return "Vertical blank is in progress.\0";
01276 case DDERR_WASSTILLDRAWING:
01277 return "Informs DirectDraw that the previous Blt which is transfering information to or from this Surface is incomplete.\0";
01278 case DDERR_WRONGMODE:
01279 return "This surface can not be restored because it was created in a different mode.\0";
01280 case DDERR_XALIGN:
01281 return "Rectangle provided was not horizontally aligned on required boundary.\0";
01282 default:
01283 return "Unrecognized error value.\0";
01284 }
01285 }
01286
01287 BOOL DDrawBlitDecal(LPDIRECTDRAWSURFACE4 lpDDSDecal, RECT *SRect, S32 x, S32 y)
01288 {
01289 HRESULT ddrval;
01290 DDSURFACEDESC2 ddsd;
01291 RECT rDest;
01292 char szTemp[256];
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307 if(SRect)
01308 {
01309 rDest.left =x;
01310 rDest.top =y;
01311 rDest.right =x + (SRect->right - SRect->left);
01312 rDest.bottom=y + (SRect->bottom- SRect->top);
01313 }
01314 else
01315 {
01316 memset(&ddsd, 0, sizeof(DDSCAPS2));
01317 ddsd.dwSize =sizeof(ddsd);
01318 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
01319 lpDDSDecal->lpVtbl->GetSurfaceDesc(lpDDSDecal, &ddsd);
01320
01321 rDest.left =x;
01322 rDest.top =y;
01323 rDest.right =x + ddsd.dwWidth;
01324 rDest.bottom=y + ddsd.dwHeight;
01325 }
01326
01327 ddrval =DD_OK;
01328 while(1)
01329 {
01330 if(SRect)
01331 {
01332 ddrval =lpDDSBack->lpVtbl->Blt(lpDDSBack, &rDest, lpDDSDecal, SRect, DDBLT_WAIT | DDBLT_KEYSRC, NULL);
01333 }
01334 else
01335 {
01336 ddrval =lpDDSBack->lpVtbl->Blt(lpDDSBack, &rDest, lpDDSDecal, NULL, DDBLT_WAIT | DDBLT_KEYSRC, NULL);
01337 }
01338 if(ddrval==DD_OK)
01339 break;
01340
01341 if(ddrval==DDERR_SURFACELOST)
01342 {
01343 ddrval =RestoreAll();
01344 if(ddrval!=DD_OK)
01345 {
01346 ErrorPrintf("Error During Blt() in DDrawBltDecal()...\n");
01347 ErrorPrintf("DirectDraw Surfaces were lost and could not be restored : %s\n", MyErrorToString(ddrval));
01348 return FALSE;
01349 }
01350 }
01351 else if(ddrval!=DDERR_WASSTILLDRAWING)
01352 {
01353 ErrorPrintf("Error During Blt() in DDrawBltDecal() : %s\n", MyErrorToString(ddrval));
01354 if(SRect)
01355 {
01356 sprintf(szTemp, "SLeft:%d, STop:%d, SRight:%d, SBottom:%d\n", SRect->left, SRect->top, SRect->right, SRect->bottom);
01357 ErrorPrintf(szTemp);
01358 }
01359 sprintf(szTemp, "DLeft:%d, DTop:%d, DRight:%d, DBottom:%d\n%x", rDest.left, rDest.top, rDest.right, rDest.bottom, (U32)lpDDSDecal);
01360 ErrorPrintf(szTemp);
01361 return FALSE;
01362 }
01363 }
01364 return TRUE;
01365 }
01366
01367 BOOL DDrawBlitDecalToFront(LPDIRECTDRAWSURFACE4 lpDDSDecal, RECT *SRect, S32 x, S32 y)
01368 {
01369 HRESULT ddrval;
01370 DDSURFACEDESC2 ddsd;
01371 RECT rDest;
01372 char szTemp[256];
01373
01374 if(SRect)
01375 {
01376 rDest.left =x;
01377 rDest.top =y;
01378 rDest.right =x + (SRect->right - SRect->left);
01379 rDest.bottom=y + (SRect->bottom- SRect->top);
01380 }
01381 else
01382 {
01383 memset(&ddsd, 0, sizeof(DDSCAPS2));
01384 ddsd.dwSize =sizeof(ddsd);
01385 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
01386 lpDDSDecal->lpVtbl->GetSurfaceDesc(lpDDSDecal, &ddsd);
01387
01388 rDest.left =x;
01389 rDest.top =y;
01390 rDest.right =x + ddsd.dwWidth;
01391 rDest.bottom=y + ddsd.dwHeight;
01392 }
01393
01394 ddrval =DD_OK;
01395 while(1)
01396 {
01397 if(SRect)
01398 {
01399 ddrval =lpDDSPrimary->lpVtbl->Blt(lpDDSPrimary, &rDest, lpDDSDecal, SRect, DDBLT_WAIT | DDBLT_KEYSRC, NULL);
01400 }
01401 else
01402 {
01403 ddrval =lpDDSPrimary->lpVtbl->Blt(lpDDSPrimary, &rDest, lpDDSDecal, NULL, DDBLT_WAIT | DDBLT_KEYSRC, NULL);
01404 }
01405 if(ddrval==DD_OK)
01406 break;
01407
01408 if(ddrval==DDERR_SURFACELOST)
01409 {
01410 ddrval =RestoreAll();
01411 if(ddrval!=DD_OK)
01412 {
01413 ErrorPrintf("Error During Blt() in DDrawBltDecalToFront()...\n");
01414 ErrorPrintf("DirectDraw Surfaces were lost and could not be restored : %s\n", MyErrorToString(ddrval));
01415 return FALSE;
01416 }
01417 }
01418 else if(ddrval!=DDERR_WASSTILLDRAWING)
01419 {
01420 ErrorPrintf("Error During Blt() in DDrawBltDecalToFront() : %s\n", MyErrorToString(ddrval));
01421 if(SRect)
01422 {
01423 sprintf(szTemp, "SLeft:%d, STop:%d, SRight:%d, SBottom:%d\n", SRect->left, SRect->top, SRect->right, SRect->bottom);
01424 ErrorPrintf(szTemp);
01425 }
01426 sprintf(szTemp, "DLeft:%d, DTop:%d, DRight:%d, DBottom:%d\n%x", rDest.left, rDest.top, rDest.right, rDest.bottom, (U32)lpDDSDecal);
01427 ErrorPrintf(szTemp);
01428 return FALSE;
01429 }
01430 }
01431 return TRUE;
01432 }
01433
01434 BOOL DDrawBlitDecalDelayed(LPDIRECTDRAWSURFACE4 lpDDSDecal, RECT *SRect, S32 x, S32 y)
01435 {
01436 DecalQ[NumDecalsQd].surf =lpDDSDecal;
01437 if(SRect)
01438 {
01439 DecalQ[NumDecalsQd].srect =*SRect;
01440 }
01441 else
01442 {
01443 DecalQ[NumDecalsQd].srect.left =-1;
01444 }
01445 DecalQ[NumDecalsQd].x =x;
01446 DecalQ[NumDecalsQd].y =y;
01447
01448 if(NumDecalsQd < 8191)
01449 {
01450 NumDecalsQd++;
01451 }
01452 return TRUE;
01453 }
01454
01455 void ClearBackBuffer(DRV_Window *cwnd)
01456 {
01457 DDBLTFX bfx;
01458
01459 if(!bActive)
01460 {
01461 return;
01462 }
01463
01464 memset(&bfx, 0, sizeof(bfx));
01465 bfx.dwSize =sizeof(bfx);
01466 bfx.dwFillColor =0;
01467
01468 lpDDSBack->lpVtbl->Blt(lpDDSBack, NULL, NULL, NULL, DDBLT_COLORFILL, &bfx);
01469 }
01470
01471 geBoolean DRIVERCC DrvSetActive(geBoolean wParam)
01472 {
01473 bActive =wParam;
01474
01475 if(bInitDone && bActive)
01476 {
01477 ErrorPrintf("Regaining Focus\n");
01478 OutputDebugString("Regaining Focus\n");
01479 if(lpDDSPrimary->lpVtbl->IsLost(lpDDSPrimary)==DDERR_SURFACELOST)
01480 {
01481 if(RestoreAll()==DD_OK)
01482 {
01483 ErrorPrintf("Regained focus and restored all DirectDraw surfaces\n");
01484 OutputDebugString("Regained focus and restored all DirectDraw surfaces\n");
01485 ShowWindow(mhWnd, SW_SHOWNORMAL);
01486 }
01487 else
01488 {
01489 ErrorPrintf("Couldn't restore surfaces!\n");
01490 OutputDebugString("Couldn't restore surfaces!\n");
01491 }
01492 }
01493 else
01494 {
01495 ErrorPrintf("Regained focus, no surfaces lost\n");
01496 OutputDebugString("Regained focus, no surfaces lost\n");
01497 }
01498 }
01499 else
01500 {
01501 ErrorPrintf("Lost Focus\n");
01502 OutputDebugString("Lost Focus\n");
01503 }
01504 return GE_TRUE;
01505 }
01506