00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #pragma warning(disable : 4201 4214 4115)
00025 #include <windows.h>
00026 #include <assert.h>
00027 #include "ddraw.h"
00028 #include <stdio.h>
00029 #pragma warning(default : 4201 4214 4115; disable : 4514)
00030
00031 #include "DDRAWDisplay.h"
00032
00033 #ifdef GENESIS_VERSION_2
00034 #include "errorlog.h"
00035 #else
00036 #define geErrorLog_AddString(Error,xx,yy)
00037 #endif
00038
00039
00040 #define DDRAWDISPLAY_DESCRIPTION_STRING "Software (Full Screen) "
00041
00042 typedef struct
00043 {
00044 LPDIRECTDRAW4 lpDD4;
00045 HANDLE ddrawinst;
00046 } DDRAWDisplay_DLLHooks;
00047
00048 typedef struct DDRAWDisplay
00049 {
00050 DDRAWDisplay_DLLHooks DLL;
00051
00052 LPDIRECTDRAWSURFACE4 lpDDSPrimary;
00053 LPDIRECTDRAWSURFACE4 lpDDSBack;
00054 BOOL bActive;
00055
00056 int Width;
00057 int Height;
00058 int BitsPerPixel;
00059 int ModeFlags;
00060
00061 HWND hWnd;
00062 geBoolean Locked;
00063 uint8 *Buffer;
00064 int32 Pitch;
00065 } DDRAWDisplay;
00066
00067 typedef HRESULT (WINAPI *LPDIRECTDRAWCREATE)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );
00068
00069
00070 static geBoolean DDRAWDisplay_IsValid(DDRAWDisplay *D)
00071 {
00072 if ( D == NULL )
00073 return GE_FALSE;
00074
00075 if (D->DLL.ddrawinst == NULL )
00076 return GE_FALSE;
00077
00078 if (D->DLL.lpDD4 == NULL)
00079 return GE_FALSE;
00080
00081 if (D->hWnd == NULL )
00082 return GE_FALSE;
00083
00084 return GE_TRUE;
00085 }
00086
00087 static void DDRAWDisplay_UnloadDLL( DDRAWDisplay_DLLHooks *H )
00088 {
00089 assert( H != NULL );
00090 if (H->lpDD4)
00091 {
00092 H->lpDD4->lpVtbl->Release(H->lpDD4);
00093 H->lpDD4 = NULL;
00094 }
00095 if (H->ddrawinst)
00096 {
00097 FreeLibrary(H->ddrawinst);
00098 H->ddrawinst = NULL;
00099 }
00100 }
00101
00102 static geBoolean DDRAWDisplay_LoadDLL( DDRAWDisplay_DLLHooks *H )
00103 {
00104 LPDIRECTDRAW lpDD = NULL;
00105 LPDIRECTDRAWCREATE lpDDCreate = NULL;
00106 HRESULT ddrval;
00107 assert( H != NULL );
00108
00109 H->ddrawinst = NULL;
00110 H->lpDD4 = NULL;
00111
00112
00113 H->ddrawinst =LoadLibrary("ddraw.dll");
00114
00115 if(!H->ddrawinst)
00116 {
00117 geErrorLog_AddString(-1,"failed to load","ddraw.dll");
00118 goto LoadDLL_ERROR;
00119 }
00120
00121 lpDDCreate =(LPDIRECTDRAWCREATE)GetProcAddress(H->ddrawinst, "DirectDrawCreate");
00122 if(lpDDCreate)
00123 {
00124 ddrval =lpDDCreate(NULL, &(lpDD), NULL);
00125 if((ddrval != DD_OK) || ((lpDD)==NULL))
00126 {
00127 geErrorLog_AddString(-1,"ddraw lpDDCreate failed", geErrorLog_IntToString(ddrval));
00128 goto LoadDLL_ERROR;
00129 }
00130 }
00131 else
00132 {
00133 geErrorLog_AddString(-1 ,"Unable to find DirectDrawCreate entry into ddraw.dll",NULL);
00134 goto LoadDLL_ERROR;
00135 }
00136
00137 ddrval = lpDD->lpVtbl->QueryInterface(lpDD, &IID_IDirectDraw4, (LPVOID *)&(H->lpDD4));
00138 if(ddrval!=DD_OK)
00139 {
00140 geErrorLog_AddString(-1,"QueryInterface failed", geErrorLog_IntToString(ddrval));
00141 goto LoadDLL_ERROR;
00142 }
00143
00144 lpDD->lpVtbl->Release(lpDD);
00145 lpDD =NULL;
00146
00147
00148 return GE_TRUE;
00149
00150
00151 LoadDLL_ERROR:
00152 if (lpDD != NULL )
00153 {
00154 lpDD->lpVtbl->Release(lpDD);
00155 lpDD =NULL;
00156 }
00157 DDRAWDisplay_UnloadDLL(H);
00158 return GE_FALSE;
00159 }
00160
00161 void DDRAWDisplay_GetDisplayFormat( const DDRAWDisplay *D,
00162 int32 *Width,
00163 int32 *Height,
00164 int32 *BitsPerPixel,
00165 uint32 *Flags)
00166 {
00167 assert( D != NULL );
00168 assert( Width != NULL );
00169 assert( Height != NULL );
00170 assert( BitsPerPixel != NULL );
00171 assert( Flags != NULL );
00172
00173 *Width = D->Width;
00174 *Height = D->Height;
00175 *BitsPerPixel = D->BitsPerPixel;
00176 *Flags = D->ModeFlags;
00177 }
00178
00179 void DDRAWDisplay_Destroy(DDRAWDisplay **pD)
00180 {
00181 DDRAWDisplay *D;
00182
00183 assert( pD );
00184 assert( DDRAWDisplay_IsValid(*pD)!=GE_FALSE );
00185 D = *pD;
00186
00187 if (D->Locked == GE_TRUE)
00188 DDRAWDisplay_Unlock(D);
00189
00190 if (D->ModeFlags & FLIP)
00191 {
00192 D->lpDDSBack =NULL;
00193 }
00194 else
00195 {
00196 if(D->lpDDSBack)
00197 {
00198 D->lpDDSBack->lpVtbl->Release(D->lpDDSBack);
00199 D->lpDDSBack =NULL;
00200 }
00201 }
00202 if(D->lpDDSPrimary)
00203 {
00204 D->lpDDSPrimary->lpVtbl->Release(D->lpDDSPrimary);
00205 D->lpDDSPrimary =NULL;
00206 }
00207
00208 DDRAWDisplay_UnloadDLL(&(D->DLL));
00209
00210 free(D);
00211 *pD = NULL;
00212 }
00213
00214 static geBoolean DDRAWDisplay_RestoreAll(DDRAWDisplay *D)
00215 {
00216 HRESULT ddrval;
00217 assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00218
00219 ddrval =D->DLL.lpDD4->lpVtbl->SetCooperativeLevel(D->DLL.lpDD4, D->hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
00220 if(ddrval!=DD_OK)
00221 {
00222 geErrorLog_AddString(-1,"DDRAWDisplay_RestoreAll(): ddraw SetCooperativeLevel", geErrorLog_IntToString(ddrval));
00223 return GE_FALSE;
00224 }
00225
00226 ddrval =D->DLL.lpDD4->lpVtbl->SetDisplayMode(D->DLL.lpDD4, D->Width, D->Height, D->BitsPerPixel, 0, 0);
00227 if(ddrval!=DD_OK)
00228 {
00229 geErrorLog_AddString(-1,"DDRAWDisplay_RestoreAll: ddraw SetDisplayMode", geErrorLog_IntToString(ddrval));
00230 return GE_FALSE;
00231 }
00232 ddrval =D->DLL.lpDD4->lpVtbl->RestoreAllSurfaces(D->DLL.lpDD4);
00233 if(ddrval!=DD_OK)
00234 {
00235 geErrorLog_AddString(-1,"DDRAWDisplay_RestoreAll: ddraw RestoreAllSurfaces", geErrorLog_IntToString(ddrval));
00236 return GE_FALSE;
00237 }
00238 return GE_TRUE;
00239 }
00240
00241
00242 geBoolean DDRAWDisplay_Lock(DDRAWDisplay *D, uint8 **Buffer, int32 *Pitch)
00243 {
00244 HRESULT ddrval;
00245 DDSURFACEDESC2 ddsd;
00246 RECT wrect;
00247 int Forever = 1;
00248 assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00249
00250 if(!D->bActive)
00251 return GE_TRUE;
00252
00253
00254 assert( Buffer != NULL );
00255 assert( Pitch != NULL );
00256
00257 if (D->Locked != GE_FALSE)
00258 {
00259 geErrorLog_AddString(-1,"DDRAWDisplay_Lock: already locked",NULL );
00260 return GE_FALSE;
00261 }
00262
00263 memset(&ddsd, 0, sizeof(DDSCAPS2));
00264 ddsd.dwSize =sizeof(ddsd);
00265 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00266
00267 D->lpDDSBack->lpVtbl->GetSurfaceDesc(D->lpDDSBack, &ddsd);
00268 wrect.left = 0;
00269 wrect.top = 0;
00270 wrect.right = ddsd.dwWidth-1;
00271 wrect.bottom = ddsd.dwHeight-1;
00272
00273 while(Forever)
00274 {
00275 ddrval =D->lpDDSBack->lpVtbl->Lock(D->lpDDSBack, &wrect, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL);
00276 if(ddrval==DD_OK)
00277 {
00278 break;
00279 }
00280
00281 if(ddrval==DDERR_SURFACELOST)
00282 {
00283 if (DDRAWDisplay_RestoreAll(D) == GE_FALSE)
00284 {
00285 geErrorLog_AddString(-1,"DDRAWDisplay_Lock: lost ddraw surface", NULL);
00286 return GE_FALSE;
00287 }
00288 }
00289 else if(ddrval!=DDERR_WASSTILLDRAWING)
00290 {
00291 geErrorLog_AddString(-1,"DDRAWDisplay_Lock: was still drawing",geErrorLog_IntToString(ddrval));
00292 return GE_FALSE;
00293 }
00294 }
00295 *Buffer = (uint8 *)ddsd.lpSurface;
00296 *Pitch = ddsd.lPitch;
00297 D->Locked = GE_TRUE;
00298 D->Buffer = *Buffer;
00299 D->Pitch = *Pitch;
00300 return GE_TRUE;
00301 }
00302
00303 geBoolean DDRAWDisplay_Unlock(DDRAWDisplay *D)
00304 {
00305 int Forever=1;
00306 HRESULT ddrval =DD_OK;
00307 assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00308
00309 if(!D->bActive)
00310 return GE_TRUE;
00311
00312
00313 if (D->Locked != GE_TRUE)
00314 {
00315 geErrorLog_AddString(-1,"DDRAWDisplay_Unlock: surface not locked",NULL);
00316 return GE_FALSE;
00317 }
00318
00319 D->Locked = GE_FALSE;
00320
00321 while(Forever)
00322 {
00323 ddrval =D->lpDDSBack->lpVtbl->Unlock(D->lpDDSBack, NULL);
00324 if(ddrval==DD_OK)
00325 break;
00326
00327 #pragma message (" can you loose a locked surface?")
00328 if(ddrval==DDERR_SURFACELOST)
00329 {
00330 if (DDRAWDisplay_RestoreAll(D) == GE_FALSE)
00331 {
00332 geErrorLog_AddString(-1,"DDRAWDisplay_Unlock: surface lost\n",NULL);
00333 return GE_FALSE;
00334 }
00335 }
00336 else if(ddrval!=DDERR_WASSTILLDRAWING)
00337 {
00338 geErrorLog_AddString(-1,"DDRAWDisplay_Unlock: was still drawing.",geErrorLog_IntToString(ddrval));
00339 return GE_FALSE;
00340 }
00341 }
00342
00343 D->Locked = GE_FALSE;
00344 return GE_TRUE;
00345 }
00346
00347 geBoolean DDRAWDisplay_Blit(DDRAWDisplay *D)
00348 {
00349 HRESULT ddrval;
00350 DDSURFACEDESC2 ddsd;
00351 RECT rDest, rSrc;
00352 int Forever=1;
00353 assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00354
00355 if(!D->bActive)
00356 {
00357 return GE_TRUE;
00358 }
00359
00360 memset(&ddsd, 0, sizeof(DDSCAPS2));
00361 ddsd.dwSize =sizeof(ddsd);
00362 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00363
00364 D->lpDDSBack->lpVtbl->GetSurfaceDesc(D->lpDDSBack, &ddsd);
00365 rDest.left =rDest.top =0;
00366 rDest.right =ddsd.dwWidth-1;
00367 rDest.bottom=ddsd.dwHeight-1;
00368
00369 memset(&ddsd, 0, sizeof(DDSCAPS2));
00370 ddsd.dwSize =sizeof(ddsd);
00371 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00372
00373 D->lpDDSPrimary->lpVtbl->GetSurfaceDesc(D->lpDDSPrimary, &ddsd);
00374 rSrc.left =rSrc.top =0;
00375 rSrc.right =ddsd.dwWidth-1;
00376 rSrc.bottom =ddsd.dwHeight-1;
00377
00378 ddrval =DD_OK;
00379 if((D->ModeFlags & VIDEO) && (D->ModeFlags & FASTBLT))
00380 {
00381 while(Forever)
00382 {
00383 ddrval =D->lpDDSPrimary->lpVtbl->BltFast(D->lpDDSPrimary, 0, 0, D->lpDDSBack, NULL, 0);
00384 if(ddrval==DD_OK)
00385 {
00386 break;
00387 }
00388
00389 if(ddrval==DDERR_SURFACELOST)
00390 {
00391 if (DDRAWDisplay_RestoreAll(D) == GE_FALSE)
00392 {
00393 geErrorLog_AddString(-1,"DDRAWDisplay_Blit: lost surface",NULL);
00394 return GE_FALSE;
00395 }
00396 }
00397 else if(ddrval!=DDERR_WASSTILLDRAWING)
00398 {
00399 geErrorLog_AddString(-1,"DDRAWDisplay_Blit: was still drawing",NULL);
00400 return GE_FALSE;
00401 }
00402 }
00403 }
00404 else if(D->ModeFlags & FLIP)
00405 {
00406 while(Forever)
00407 {
00408 ddrval =D->lpDDSPrimary->lpVtbl->Flip(D->lpDDSPrimary, D->lpDDSBack, DDFLIP_NOVSYNC);
00409 if(ddrval==DD_OK)
00410 {
00411 break;
00412 }
00413
00414 if(ddrval==DDERR_SURFACELOST)
00415 {
00416 if (DDRAWDisplay_RestoreAll(D)==GE_FALSE)
00417 {
00418 geErrorLog_AddString(-1,"DDRAWDisplay_Blit: lost surface",NULL);
00419 return GE_FALSE;
00420 }
00421 }
00422 else if(ddrval!=DDERR_WASSTILLDRAWING)
00423 {
00424 geErrorLog_AddString(-1,"DDRAWDisplay_Blit: was still drawing",NULL);
00425 return GE_FALSE;
00426 }
00427 }
00428 }
00429 else
00430 {
00431 while(Forever)
00432 {
00433 ddrval =D->lpDDSPrimary->lpVtbl->Blt(D->lpDDSPrimary, NULL, D->lpDDSBack, NULL, DDBLT_WAIT, NULL);
00434 if(ddrval==DD_OK)
00435 break;
00436
00437 if(ddrval==DDERR_SURFACELOST)
00438 {
00439 if (DDRAWDisplay_RestoreAll(D)==GE_FALSE)
00440 {
00441 geErrorLog_AddString(-1,"DDRAWDisplay_Blit: lost surface",NULL);
00442 return GE_FALSE;
00443 }
00444 }
00445 else if(ddrval!=DDERR_WASSTILLDRAWING)
00446 {
00447 geErrorLog_AddString(-1,"DDRAWDisplay_Blit: was still drawing",NULL);
00448 return GE_FALSE;
00449 }
00450 }
00451 }
00452 return GE_TRUE;
00453 }
00454
00455
00456
00457
00458
00459 static geBoolean DDRAWDisplay_SetMode(DDRAWDisplay *D, int width, int height, int bpp, uint32 flags)
00460 {
00461 HRESULT ddrval;
00462 DDSURFACEDESC2 ddsd;
00463 DDSCAPS2 ddscaps;
00464
00465 assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00466
00467
00468 D->ModeFlags = 0;
00469
00470 ddrval =D->DLL.lpDD4->lpVtbl->SetDisplayMode(D->DLL.lpDD4, width, height, bpp, 0, 0);
00471
00472 D->Height =height;
00473 D->Width =width;
00474 D->BitsPerPixel =bpp;
00475
00476 if(!(flags & MODEXMODE))
00477 {
00478
00479 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00480 ddsd.dwSize =sizeof(ddsd);
00481 ddsd.dwFlags =DDSD_CAPS;
00482 ddsd.ddsCaps.dwCaps =DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
00483
00484 ddrval =D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSPrimary, NULL);
00485 if(ddrval==DD_OK)
00486 {
00487
00488 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00489 ddsd.dwSize =sizeof(ddsd);
00490 ddsd.dwFlags =DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
00491 ddsd.ddsCaps.dwCaps =DDSCAPS_SYSTEMMEMORY;
00492
00493 ddsd.dwHeight =height;
00494 ddsd.dwWidth =width;
00495
00496 ddrval =D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSBack, NULL);
00497 if(ddrval==DD_OK)
00498 {
00499
00500
00501 memset(&ddscaps, 0, sizeof(DDSCAPS2));
00502 D->lpDDSPrimary->lpVtbl->GetCaps(D->lpDDSPrimary, &ddscaps);
00503 if(ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY)
00504 {
00505 memset(&ddscaps, 0, sizeof(DDSCAPS2));
00506 D->lpDDSBack->lpVtbl->GetCaps(D->lpDDSBack, &ddscaps);
00507 if(ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY)
00508 {
00509
00510
00511 D->ModeFlags |=VIDEO;
00512
00513
00514 if(!(flags & STRETCHMODE))
00515 {
00516 D->ModeFlags |=FASTBLT;
00517 }
00518 }
00519 }
00520 }
00521 }
00522 #pragma message ("this cant be set can it?")
00523 else if(!(D->ModeFlags & VIDEO)
00524 && !(D->ModeFlags & STRETCHMODE))
00525 {
00526 if(D->lpDDSBack) D->lpDDSBack->lpVtbl->Release(D->lpDDSBack);
00527 if(D->lpDDSPrimary) D->lpDDSPrimary->lpVtbl->Release(D->lpDDSPrimary);
00528
00529 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00530 ddsd.dwSize =sizeof(ddsd);
00531 ddsd.dwFlags =DDSD_CAPS;
00532 ddsd.ddsCaps.dwCaps =DDSCAPS_PRIMARYSURFACE;
00533
00534 ddrval =D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSPrimary, NULL);
00535 if(ddrval==DD_OK)
00536 {
00537 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00538 ddsd.dwSize =sizeof(ddsd);
00539 ddsd.dwFlags =DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
00540 ddsd.dwHeight =height;
00541 ddsd.dwWidth =width;
00542
00543 ddrval =D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSBack, NULL);
00544 if(ddrval==DD_OK)
00545 {
00546
00547 D->ModeFlags |=SYSTEM|SAFEBLT;
00548 }
00549 }
00550 }
00551 }
00552 if((flags & MODEXMODE) || D->lpDDSBack==NULL)
00553 {
00554 if(D->lpDDSBack) D->lpDDSBack->lpVtbl->Release(D->lpDDSBack);
00555 if(D->lpDDSPrimary) D->lpDDSPrimary->lpVtbl->Release(D->lpDDSPrimary);
00556
00557
00558 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00559 ddsd.dwSize =sizeof(ddsd);
00560 ddsd.dwFlags =DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
00561 ddsd.ddsCaps.dwCaps =DDSCAPS_PRIMARYSURFACE |
00562 DDSCAPS_COMPLEX | DDSCAPS_FLIP;
00563 ddsd.dwBackBufferCount =1;
00564
00565 ddrval =D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSPrimary, NULL);
00566 if(ddrval==DD_OK)
00567 {
00568 memset(&ddscaps, 0, sizeof(DDSCAPS2));
00569 ddscaps.dwCaps =DDSCAPS_BACKBUFFER;
00570 ddrval =D->lpDDSPrimary->lpVtbl->GetAttachedSurface(D->lpDDSPrimary, &ddscaps, &D->lpDDSBack);
00571 if(ddrval==DD_OK)
00572 {
00573 D->ModeFlags |=SYSTEM|FLIP;
00574 }
00575 else
00576 {
00577 geErrorLog_AddString(-1,"Unable to create primary buffer",NULL);
00578 return GE_FALSE;
00579 }
00580 }
00581 }
00582 return GE_TRUE;
00583 }
00584
00585
00586
00587
00588 DDRAWDisplay *DDRAWDisplay_Create(HWND hwnd, int Width, int Height, int BPP, uint32 Flags)
00589 {
00590 DDRAWDisplay *D = NULL;
00591
00592 HRESULT ddrval = 0;
00593
00594 D = malloc(sizeof(DDRAWDisplay));
00595 if (D == NULL)
00596 {
00597 geErrorLog_AddString(-1,"Failed to create DDRAWDisplay object",NULL);
00598 return NULL;
00599 }
00600
00601 memset(D,0,sizeof(DDRAWDisplay));
00602
00603
00604 if (DDRAWDisplay_LoadDLL(&(D->DLL))==GE_FALSE)
00605 {
00606 geErrorLog_AddString(-1,"failed to load ddraw dll",NULL);
00607 goto Create_ERROR;
00608 }
00609 D->hWnd = hwnd;
00610 D->bActive = GE_FALSE;
00611
00612 ddrval =D->DLL.lpDD4->lpVtbl->SetCooperativeLevel(D->DLL.lpDD4, hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
00613 if(ddrval!=DD_OK)
00614 {
00615 geErrorLog_AddString(-1,"DDRAWDisplay_Create: failed to set cooperative level", geErrorLog_IntToString(ddrval));
00616 goto Create_ERROR;
00617 }
00618
00619 if (DDRAWDisplay_SetMode(D, Width, Height, BPP, Flags)==GE_FALSE)
00620 {
00621 geErrorLog_AddString(-1,"Failed to create buffers",NULL);
00622 goto Create_ERROR;
00623 }
00624
00625 assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00626 return D;
00627
00628 Create_ERROR:
00629 if (D)
00630 {
00631 DDRAWDisplay_UnloadDLL(&(D->DLL));
00632 free(D);
00633 }
00634 return NULL;
00635 }
00636
00637
00638
00639
00640 geBoolean DDRAWDisplay_GetPixelFormat( DDRAWDisplay *D,
00641
00642 int32 *bytes_per_pixel,
00643 int32 *R_shift,
00644 uint32 *R_mask,
00645 int32 *R_width,
00646 int32 *G_shift,
00647 uint32 *G_mask,
00648 int32 *G_width,
00649 int32 *B_shift,
00650 uint32 *B_mask,
00651 int32 *B_width)
00652 {
00653 DDPIXELFORMAT ddpf;
00654 uint32 i, j;
00655
00656 assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00657
00658 assert( bytes_per_pixel != NULL );
00659 assert( R_shift != NULL );
00660 assert( R_mask != NULL );
00661 assert( R_width != NULL );
00662 assert( G_shift != NULL );
00663 assert( G_mask != NULL );
00664 assert( G_width != NULL );
00665 assert( B_shift != NULL );
00666 assert( B_mask != NULL );
00667 assert( B_width != NULL );
00668
00669 ddpf.dwSize =sizeof(ddpf);
00670 D->lpDDSPrimary->lpVtbl->GetPixelFormat(D->lpDDSPrimary, &ddpf);
00671
00672 if(!(ddpf.dwFlags & DDPF_RGB))
00673 {
00674 return GE_FALSE;
00675 }
00676 *bytes_per_pixel =ddpf.dwRGBBitCount / 8;
00677 *R_mask =ddpf.dwRBitMask;
00678 *G_mask =ddpf.dwGBitMask;
00679 *B_mask =ddpf.dwBBitMask;
00680
00681 for(j=0,i=ddpf.dwRBitMask;!(i & 1);i>>=1,j++);
00682 *R_shift =j;
00683
00684 for(j=0,i=ddpf.dwGBitMask;!(i & 1);i>>=1,j++);
00685 *G_shift =j;
00686
00687 for(j=0,i=ddpf.dwBBitMask;!(i & 1);i>>=1,j++);
00688 *B_shift =j;
00689
00690 for(i=(ddpf.dwRBitMask>>*R_shift),*R_width=0;i;i >>= 1, (*R_width)++);
00691 for(i=(ddpf.dwGBitMask>>*G_shift),*G_width=0;i;i >>= 1, (*G_width)++);
00692 for(i=(ddpf.dwBBitMask>>*B_shift),*B_width=0;i;i >>= 1, (*B_width)++);
00693 return GE_TRUE;
00694 }
00695
00696
00697 geBoolean DDRAWDisplay_Wipe(DDRAWDisplay *D,uint32 color)
00698 {
00699 DDSURFACEDESC2 ddsd;
00700 int Width, Height;
00701
00702 assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00703
00704 if(!D->bActive)
00705 {
00706 return GE_FALSE;
00707 }
00708
00709 if (!D->Locked)
00710 {
00711 geErrorLog_AddString(-1,"DDRAWDisplay_Wipe: surface not locked",NULL );
00712 return GE_FALSE;
00713 }
00714 memset(&ddsd, 0, sizeof(DDSCAPS2));
00715 ddsd.dwSize =sizeof(ddsd);
00716 ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00717 #pragma message ("this may not be necessary")
00718 D->lpDDSBack->lpVtbl->GetSurfaceDesc(D->lpDDSBack, &ddsd);
00719
00720 Width =ddsd.dwWidth;
00721 Height =ddsd.dwHeight;
00722
00723 memset(D->Buffer, color, (Height*D->Pitch));
00724 return GE_TRUE;
00725 }
00726
00727 geBoolean DDRAWDisplay_SetActive(DDRAWDisplay *D, geBoolean wParam)
00728 {
00729 assert( D != NULL );
00730
00731 D->bActive =wParam;
00732
00733 if(D->bActive)
00734 {
00735 if(D->lpDDSPrimary->lpVtbl->IsLost(D->lpDDSPrimary)==DDERR_SURFACELOST)
00736 {
00737 if(DDRAWDisplay_RestoreAll(D)!=GE_FALSE)
00738 {
00739 ShowWindow(D->hWnd, SW_SHOWNORMAL);
00740 }
00741 else
00742 {
00743 geErrorLog_AddString(-1,"DDRAWDisplay_SetActive: Couldn't restore surfaces",NULL);
00744 return GE_FALSE;
00745 }
00746 }
00747 }
00748 return GE_TRUE;
00749 }
00750
00751
00752
00753
00754 static HRESULT WINAPI DDRAWDisplay_ModeCallback(LPDDSURFACEDESC2 pdds, LPVOID lParam)
00755 {
00756 DisplayModeInfo *Info =(DisplayModeInfo *)lParam;
00757
00758 #pragma message ("only 16 bit display is supported")
00759 if(pdds->ddpfPixelFormat.dwRGBBitCount==16)
00760 {
00761 DisplayModeInfo_AddEntry(Info,
00762 pdds->dwWidth,
00763 pdds->dwHeight,
00764 pdds->ddpfPixelFormat.dwRGBBitCount,
00765 pdds->ddpfPixelFormat.dwRGBBitCount);
00766 }
00767 return S_FALSE;
00768 }
00769
00770 geBoolean DDRAWDisplay_GetDescriptionString(char *DescriptionString, unsigned int DescriptionStringMaxLength)
00771 {
00772 DDRAWDisplay_DLLHooks DLL={NULL,0};
00773
00774 DDDEVICEIDENTIFIER DDDeviceIdentifier;
00775 HRESULT hRet;
00776
00777 assert( DescriptionString != NULL );
00778
00779 if (DDRAWDisplay_LoadDLL(&DLL)==GE_FALSE)
00780 {
00781 geErrorLog_AddString(-1,"unable to load ddraw dll",NULL);
00782 goto GetDescriptionString_ERROR;
00783 }
00784
00785 memset(&DDDeviceIdentifier, 0, sizeof(DDDeviceIdentifier));
00786
00787 hRet =DLL.lpDD4->lpVtbl->GetDeviceIdentifier(DLL.lpDD4, &DDDeviceIdentifier,0);
00788
00789 if(hRet != DD_OK)
00790 {
00791 geErrorLog_AddString(-1,"DDRAWDisplay_GetDescriptionString: ddraw GetDeviceIdentifier() failed", NULL);
00792 goto GetDescriptionString_ERROR;
00793 }
00794
00795 DDRAWDisplay_UnloadDLL(&DLL);
00796 if (strlen(DDDeviceIdentifier.szDescription) + strlen(DDRAWDISPLAY_DESCRIPTION_STRING) >= DescriptionStringMaxLength)
00797 {
00798 geErrorLog_AddString(-1,"DDRAWDisplay_GetDescriptionString: description string too short",NULL);
00799 goto GetDescriptionString_ERROR;
00800 }
00801
00802 strcpy(DescriptionString,DDRAWDISPLAY_DESCRIPTION_STRING);
00803
00804
00805 return GE_TRUE;
00806
00807
00808 GetDescriptionString_ERROR:
00809 DDRAWDisplay_UnloadDLL(&DLL);
00810 return GE_FALSE;
00811 }
00812
00813
00814 geBoolean DDRAWDisplay_GetDisplayInfo( char *DescriptionString,
00815 unsigned int DescriptionStringMaxLength,
00816 DisplayModeInfo *Info)
00817 {
00818 DDDEVICEIDENTIFIER DDDeviceIdentifier;
00819 DDRAWDisplay_DLLHooks DLL={NULL,0};
00820 HRESULT ddrval = 0;
00821
00822 assert( Info != NULL );
00823
00824 if (DDRAWDisplay_LoadDLL( &DLL )==GE_FALSE)
00825 {
00826 geErrorLog_AddString(-1,"failed to load DDRAW dll",NULL);
00827 return GE_FALSE;
00828 }
00829
00830 #if 0
00831 {
00832
00833 DDCAPS ddcaps;
00834 memset(&ddcaps, 0, sizeof(DDCAPS));
00835 ddcaps.dwSize =sizeof(ddcaps);
00836 DLL.lpDD4->lpVtbl->GetCaps(DLL.lpDD4, &ddcaps, NULL);
00837
00838 if(ddcaps.dwCaps & DDCAPS_CANBLTSYSMEM)
00839 {
00840
00841 if(ddcaps.dwSVBCaps & DDCAPS_BLTQUEUE)
00842 {
00843 D->bDMA =TRUE;
00844 }
00845 }
00846 }
00847 #endif
00848
00849
00850 #if 0 // need this?
00851 ddrval =DLL.lpDD4->lpVtbl->SetCooperativeLevel(DLL.lpDD4, ActiveWnd,
00852 DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
00853 if(ddrval != DD_OK)
00854 {
00855 geErrorLog_Add(-1,"Failed to set Cooperative Level",NULL);
00856 goto GetDisplayInfo_ERROR;
00857 }
00858 #endif
00859
00860 memset(&DDDeviceIdentifier, 0, sizeof(DDDeviceIdentifier));
00861
00862 ddrval =DLL.lpDD4->lpVtbl->GetDeviceIdentifier(DLL.lpDD4, &DDDeviceIdentifier,0);
00863
00864 if(ddrval != DD_OK)
00865 {
00866 geErrorLog_AddString(-1,"ddraw GetDeviceIdentifier() failed", NULL);
00867 goto GetDisplayInfo_ERROR;
00868 }
00869
00870 if (strlen(DDDeviceIdentifier.szDescription) + strlen(DDRAWDISPLAY_DESCRIPTION_STRING) >= DescriptionStringMaxLength)
00871 {
00872 geErrorLog_AddString(-1,"description string too short",NULL);
00873 goto GetDisplayInfo_ERROR;
00874 }
00875
00876 strcpy(DescriptionString,DDRAWDISPLAY_DESCRIPTION_STRING);
00877
00878
00879
00880 DLL.lpDD4->lpVtbl->EnumDisplayModes(DLL.lpDD4, 0, NULL, (LPVOID)Info, DDRAWDisplay_ModeCallback);
00881
00882 DDRAWDisplay_UnloadDLL(&DLL);
00883 return GE_TRUE;
00884
00885 GetDisplayInfo_ERROR:
00886 DDRAWDisplay_UnloadDLL(&DLL);
00887 return GE_FALSE;
00888
00889 }
00890
00891