bool CDirectDraw::SetDisplayMode( int pWidth, int pHeight, int pScale, char pDepth, int pRefreshRate, bool pWindowed, bool pDoubleBuffered) { if(pScale < 2) pScale = 2; static bool BLOCK = false; DDSURFACEDESC ddsd; PALETTEENTRY PaletteEntries [256]; if (BLOCK) return (false); BLOCK = true; if (pWindowed) pDoubleBuffered = false; if (pDepth == 0) pDepth = depth; if (lpDDSPrimary2 != NULL) { lpDDSPrimary2->Release(); lpDDSPrimary2 = NULL; } if (lpDDSOffScreen2 != NULL) { lpDDSOffScreen2->PageUnlock(0); lpDDSOffScreen2->Release(); lpDDSOffScreen2 = NULL; } if( lpDDPalette != NULL) { lpDDPalette->Release(); lpDDPalette = NULL; } lpDD->FlipToGDISurface(); if (pWindowed) { lpDD->RestoreDisplayMode(); ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_PIXELFORMAT; dErr = lpDD->GetDisplayMode (&ddsd); if (FAILED(dErr)) pDepth = 8; else { if (ddsd.ddpfPixelFormat.dwFlags&DDPF_RGB) pDepth = (char) ddsd.ddpfPixelFormat.dwRGBBitCount; else pDepth = 8; } if (pDepth == 8) dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_FULLSCREEN| DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT); else dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_NORMAL|DDSCL_ALLOWREBOOT); } else { dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN|DDSCL_ALLOWREBOOT); // XXX: TODO: use pRefreshRate! dErr = lpDD->SetDisplayMode (pWidth, pHeight, pDepth); } if (FAILED(dErr)) { BLOCK = false; return false; } ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; if(GUI.BilinearFilter) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | (GUI.LocalVidMem ? DDSCAPS_LOCALVIDMEM : DDSCAPS_NONLOCALVIDMEM); } else { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; } ddsd.dwWidth = SNES_WIDTH * pScale; ddsd.dwHeight = SNES_HEIGHT_EXTENDED * pScale; LPDIRECTDRAWSURFACE lpDDSOffScreen; if (FAILED(lpDD->CreateSurface (&ddsd, &lpDDSOffScreen, NULL))) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | (GUI.LocalVidMem ? DDSCAPS_NONLOCALVIDMEM : DDSCAPS_LOCALVIDMEM); if(!GUI.BilinearFilter || FAILED(lpDD->CreateSurface (&ddsd, &lpDDSOffScreen, NULL))) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; if(!GUI.BilinearFilter || FAILED(lpDD->CreateSurface (&ddsd, &lpDDSOffScreen, NULL))) { BLOCK = false; return (false); } } } if (FAILED (lpDDSOffScreen->QueryInterface (IID_IDirectDrawSurface2, (void **)&lpDDSOffScreen2))) { lpDDSOffScreen->Release(); BLOCK = false; return (false); } lpDDSOffScreen2->PageLock(0); lpDDSOffScreen->Release(); ZeroMemory (&ddsd, sizeof (ddsd)); if (pDoubleBuffered) { ddsd.dwSize = sizeof( ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; GUI.NumFlipFrames = 3; ddsd.dwBackBufferCount = 2; } else { GUI.NumFlipFrames = 1; ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; } LPDIRECTDRAWSURFACE lpDDSPrimary; dErr = lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL); if( FAILED(dErr) ) { if (pDoubleBuffered) { ddsd.dwBackBufferCount = 1; GUI.NumFlipFrames = 2; if (FAILED(dErr = lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL))) { ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; pDoubleBuffered = false; GUI.NumFlipFrames = 1; dErr = lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL); } } if (FAILED(dErr)) { BLOCK = false; lpDDSOffScreen2->PageUnlock(0); lpDDSOffScreen2->Release(); lpDDSOffScreen2 = NULL; return (false); } } ZeroMemory (&DDPixelFormat, sizeof (DDPixelFormat)); DDPixelFormat.dwSize = sizeof (DDPixelFormat); lpDDSPrimary->GetPixelFormat (&DDPixelFormat); clipped = true; if((!pWindowed && pDoubleBuffered) || FAILED(lpDDSPrimary->SetClipper( lpDDClipper))) clipped = false; if (FAILED (lpDDSPrimary->QueryInterface (IID_IDirectDrawSurface2, (void **)&lpDDSPrimary2))) { BLOCK = false; lpDDSPrimary->Release(); lpDDSPrimary = NULL; return (FALSE); } lpDDSPrimary->Release(); lpDDSPrimary = NULL; if((!pWindowed && pDoubleBuffered) || FAILED(lpDDSPrimary2->SetClipper( lpDDClipper))) clipped = false; if (pDepth == 8) { dErr = lpDD->CreatePalette (DDPCAPS_8BIT | DDPCAPS_ALLOW256, PaletteEntries, &lpDDPalette, NULL); if( FAILED(dErr)) { lpDDPalette = NULL; BLOCK = false; return false; } } depth = pDepth; height = pHeight; width = pWidth; doubleBuffered = pDoubleBuffered; BLOCK = false; return (true); }
//----------------------------------------------------------------------------- // Name: GetDXVersion() // Desc: This function returns the DirectX version number as follows: // 0x0000 = No DirectX installed // 0x0100 = DirectX version 1 installed // 0x0200 = DirectX 2 installed // 0x0300 = DirectX 3 installed // 0x0500 = At least DirectX 5 installed. // 0x0600 = At least DirectX 6 installed. // 0x0601 = At least DirectX 6.1 installed. // 0x0700 = At least DirectX 7 installed. // 0x0800 = At least DirectX 8 installed. // // Please note that this code is intended as a general guideline. Your // app will probably be able to simply query for functionality (via // QueryInterface) for one or two components. // // Please also note: // "if( dwDXVersion != 0x500 ) return FALSE;" is VERY BAD. // "if( dwDXVersion < 0x500 ) return FALSE;" is MUCH BETTER. // to ensure your app will run on future releases of DirectX. //----------------------------------------------------------------------------- DWORD GetDXVersion() { DIRECTDRAWCREATE DirectDrawCreate = NULL; DIRECTDRAWCREATEEX DirectDrawCreateEx = NULL; DIRECTINPUTCREATE DirectInputCreate = NULL; HINSTANCE hDDrawDLL = NULL; HINSTANCE hDInputDLL = NULL; HINSTANCE hD3D8DLL = NULL; HINSTANCE hDPNHPASTDLL = NULL; LPDIRECTDRAW pDDraw = NULL; LPDIRECTDRAW2 pDDraw2 = NULL; LPDIRECTDRAWSURFACE pSurf = NULL; LPDIRECTDRAWSURFACE3 pSurf3 = NULL; LPDIRECTDRAWSURFACE4 pSurf4 = NULL; DWORD dwDXVersion = 0; HRESULT hr; // First see if DDRAW.DLL even exists. hDDrawDLL = LoadLibrary(_T("DDRAW.DLL")); if( hDDrawDLL == NULL ) { dwDXVersion = 0; OutputDebugString(_T("Couldn't LoadLibrary DDraw\r\n")); return dwDXVersion; } // See if we can create the DirectDraw object. DirectDrawCreate = (DIRECTDRAWCREATE)GetProcAddress( hDDrawDLL, "DirectDrawCreate" ); if( DirectDrawCreate == NULL ) { dwDXVersion = 0; FreeLibrary( hDDrawDLL ); OutputDebugString(_T("Couldn't GetProcAddress DirectDrawCreate\r\n")); return dwDXVersion; } hr = DirectDrawCreate( NULL, &pDDraw, NULL ); if( FAILED(hr) ) { dwDXVersion = 0; FreeLibrary( hDDrawDLL ); OutputDebugString(_T("Couldn't create DDraw\r\n")); return dwDXVersion; } // So DirectDraw exists. We are at least DX1. dwDXVersion = 0x100; // Let's see if IID_IDirectDraw2 exists. hr = pDDraw->QueryInterface( IID_IDirectDraw2, (VOID**)&pDDraw2 ); if( FAILED(hr) ) { // No IDirectDraw2 exists... must be DX1 pDDraw->Release(); FreeLibrary( hDDrawDLL ); OutputDebugString(_T("Couldn't QI DDraw2\r\n")); return dwDXVersion; } // IDirectDraw2 exists. We must be at least DX2 pDDraw2->Release(); dwDXVersion = 0x200; //------------------------------------------------------------------------- // DirectX 3.0 Checks //------------------------------------------------------------------------- // DirectInput was added for DX3 hDInputDLL = LoadLibrary(_T("DINPUT.DLL")); if( hDInputDLL == NULL ) { // No DInput... must not be DX3 pDDraw->Release(); FreeLibrary( hDDrawDLL ); OutputDebugString(_T("Couldn't LoadLibrary DInput\r\n")); return dwDXVersion; } DirectInputCreate = (DIRECTINPUTCREATE)GetProcAddress( hDInputDLL, "DirectInputCreateA" ); if( DirectInputCreate == NULL ) { // No DInput... must be DX2 FreeLibrary( hDInputDLL ); pDDraw->Release(); FreeLibrary( hDDrawDLL ); OutputDebugString(_T("Couldn't GetProcAddress DInputCreate\r\n")); return dwDXVersion; } // DirectInputCreate exists. We are at least DX3 dwDXVersion = 0x300; FreeLibrary( hDInputDLL ); // Can do checks for 3a vs 3b here //------------------------------------------------------------------------- // DirectX 5.0 Checks //------------------------------------------------------------------------- // We can tell if DX5 is present by checking for the existence of // IDirectDrawSurface3. First, we need a surface to QI off of. DDSURFACEDESC ddsd; ZeroMemory( &ddsd, sizeof(ddsd) ); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; hr = pDDraw->SetCooperativeLevel( NULL, DDSCL_NORMAL ); if( FAILED(hr) ) { // Failure. This means DDraw isn't properly installed. pDDraw->Release(); FreeLibrary( hDDrawDLL ); dwDXVersion = 0; OutputDebugString(_T("Couldn't Set coop level\r\n")); return dwDXVersion; } hr = pDDraw->CreateSurface( &ddsd, &pSurf, NULL ); if( FAILED(hr) ) { // Failure. This means DDraw isn't properly installed. pDDraw->Release(); FreeLibrary( hDDrawDLL ); dwDXVersion = 0; OutputDebugString(_T("Couldn't CreateSurface\r\n")); return dwDXVersion; } // Query for the IDirectDrawSurface3 interface if( FAILED( pSurf->QueryInterface( IID_IDirectDrawSurface3, (VOID**)&pSurf3 ) ) ) { pSurf->Release(); pDDraw->Release(); FreeLibrary( hDDrawDLL ); OutputDebugString(_T("Couldn't QI DDS3\r\n")); return dwDXVersion; } // QI for IDirectDrawSurface3 succeeded. We must be at least DX5 dwDXVersion = 0x500; pSurf3->Release(); //------------------------------------------------------------------------- // DirectX 6.0 Checks //------------------------------------------------------------------------- // The IDirectDrawSurface4 interface was introduced with DX 6.0 if( FAILED( pSurf->QueryInterface( IID_IDirectDrawSurface4, (VOID**)&pSurf4 ) ) ) { pSurf->Release(); pDDraw->Release(); FreeLibrary( hDDrawDLL ); OutputDebugString(_T("Couldn't QI DDS4\r\n")); return dwDXVersion; } // IDirectDrawSurface4 was create successfully. We must be at least DX6 dwDXVersion = 0x600; pSurf4->Release(); pSurf->Release(); pDDraw->Release(); //------------------------------------------------------------------------- // DirectX 6.1 Checks //------------------------------------------------------------------------- // Check for DMusic, which was introduced with DX6.1 LPDIRECTMUSIC pDMusic = NULL; CoInitialize( NULL ); hr = CoCreateInstance( CLSID_DirectMusic, NULL, CLSCTX_INPROC_SERVER, IID_IDirectMusic, (VOID**)&pDMusic ); if( FAILED(hr) ) { FreeLibrary( hDDrawDLL ); OutputDebugString(_T("Couldn't create CLSID_DirectMusic\r\n")); return dwDXVersion; } // DirectMusic was created successfully. We must be at least DX6.1 dwDXVersion = 0x601; pDMusic->Release(); CoUninitialize(); //------------------------------------------------------------------------- // DirectX 7.0 Checks //------------------------------------------------------------------------- // Check for DirectX 7 by creating a DDraw7 object LPDIRECTDRAW7 pDD7; DirectDrawCreateEx = (DIRECTDRAWCREATEEX)GetProcAddress( hDDrawDLL, "DirectDrawCreateEx" ); if( NULL == DirectDrawCreateEx ) { FreeLibrary( hDDrawDLL ); OutputDebugString(_T("Couldn't GetProcAddress DirectDrawCreateEx\r\n")); return dwDXVersion; } if( FAILED( DirectDrawCreateEx( NULL, (VOID**)&pDD7, IID_IDirectDraw7, NULL ) ) ) { FreeLibrary( hDDrawDLL ); OutputDebugString(_T("Couldn't DirectDrawCreateEx\r\n")); return dwDXVersion; } // DDraw7 was created successfully. We must be at least DX7.0 dwDXVersion = 0x700; pDD7->Release(); //------------------------------------------------------------------------- // DirectX 8.0 Checks //------------------------------------------------------------------------- // Simply see if D3D8.dll exists. hD3D8DLL = LoadLibrary(_T("D3D8.DLL")); if( hD3D8DLL == NULL ) { FreeLibrary( hDDrawDLL ); OutputDebugString(_T("Couldn't LoadLibrary D3D8.DLL\r\n")); return dwDXVersion; } // D3D8.dll exists. We must be at least DX8.0 dwDXVersion = 0x800; //------------------------------------------------------------------------- // DirectX 8.1 Checks //------------------------------------------------------------------------- // Simply see if dpnhpast.dll exists. hDPNHPASTDLL = LoadLibrary(_T("dpnhpast.dll")); if( hDPNHPASTDLL == NULL ) { FreeLibrary( hDPNHPASTDLL ); OutputDebugString(_T("Couldn't LoadLibrary dpnhpast.dll\r\n")); return dwDXVersion; } // dpnhpast.dll exists. We must be at least DX8.1 dwDXVersion = 0x801; //------------------------------------------------------------------------- // End of checking for versions of DirectX //------------------------------------------------------------------------- // Close open libraries and return FreeLibrary( hDDrawDLL ); FreeLibrary( hD3D8DLL ); return dwDXVersion; }
extern "C" HRESULT InitDirectDraw(HWND hWnd, int w, int h, void* pixelData) { WNDCLASS wc; DDSURFACEDESC ddsd; HRESULT hRet; hRet = DirectDrawCreate(NULL, &g_pDD, NULL); if (hRet != DD_OK) return InitFail(hWnd, hRet, szDDrawFailedMsg); // Get exclusive mode hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_FULLSCREEN); //DDSCL_NORMAL);// if (hRet != DD_OK) return InitFail(hWnd, hRet, szSetCooperativeFailMsg); #if 0 DDCAPS ddCaps; DDCAPS ddHelCaps; g_pDD->GetCaps(&ddCaps, &ddHelCaps); if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER)) { return InitFail(hWnd, E_FAIL, szNoBackBufferMsg); } if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_FLIP)) { return InitFail(hWnd, E_FAIL, szNoFlipSurfacesMsg); } #endif // Create the primary surface with 1 back buffer memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS;// | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; //| DDSCAPS_FLIP; //ddsd.dwBackBufferCount = 1; hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL); if (hRet != DD_OK) { return InitFail(hWnd, hRet, szCreateSurfaceFailMsg); } DWORD dwID; g_hRefreshScreen = CreateEvent(NULL, FALSE, FALSE, NULL); CreateThread(NULL, 0, ScreenRefresThread, NULL, 0, &dwID); return DD_OK; #if 0 #define WIDTH w // in pixels #define HEIGHT h #define DEPTH 2 // in bytes (2 bytes == 16 bits) if (ddsd.dwBackBufferCount > 0) { hRet = g_pDDSPrimary->EnumAttachedSurfaces(&g_pDDSBack, EnumFunction); if (hRet != DD_OK) return InitFail(hWnd, hRet, szEnumAttachedSurfacesFailMsg); } ZeroMemory(&ddsd, sizeof(DDSURFACEDESC)); ZeroMemory(&ddsd.ddpfPixelFormat, sizeof(DDPIXELFORMAT)); ddsd.dwSize = sizeof(ddsd); hRet = g_pDDSBack->Lock(NULL, &ddsd, DDLOCK_WAITNOTBUSY, NULL); g_pDDSPrimary->Unlock(NULL); ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT; ddsd.dwWidth = WIDTH; ddsd.dwHeight= HEIGHT; //ddsd.lPitch = (LONG)DEPTH * WIDTH; ddsd.lpSurface = pixelData; /* // Set up the pixel format for 24-bit RGB (8-8-8). ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwFlags= DDPF_RGB; ddsd.ddpfPixelFormat.dwRGBBitCount = (DWORD)DEPTH*8; ddsd.ddpfPixelFormat.dwRBitMask = 0xF800;//surface->format->Rmask; ddsd.ddpfPixelFormat.dwGBitMask = 0x07E0;//surface->format->Gmask; ddsd.ddpfPixelFormat.dwBBitMask = 0x001F;//surface->format->Bmask; //ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000; //ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00; //ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF; */ // Create the surface hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSBack, NULL); if (hRet != DD_OK) return InitFail(hWnd, hRet, szEnumAttachedSurfacesFailMsg); return DD_OK; #endif if (ddsd.dwBackBufferCount > 0) { hRet = g_pDDSPrimary->EnumAttachedSurfaces(&g_pDDSBack, EnumFunction); if (hRet != DD_OK) return InitFail(hWnd, hRet, szEnumAttachedSurfacesFailMsg); } return DD_OK; #if 1 ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PITCH | DDSD_LPSURFACE | DDSD_PIXELFORMAT); ddsd.dwWidth = w; ddsd.dwHeight= h; #if defined(NONAMELESSUNION) ddsd.u1.lPitch = SDL_CalculatePitch(w, 2);; #else ddsd.lPitch = SDL_CalculatePitch(w, 2);; #endif ddsd.lpSurface = pixelData; const int SDL_HWSURFACE = 1; int flag = 1; if ( (flag & SDL_HWSURFACE) == SDL_HWSURFACE ) { ddsd.ddsCaps.dwCaps = (/*DDSCAPS_OFFSCREENPLAIN | */DDSCAPS_VIDEOMEMORY); } else { ddsd.ddsCaps.dwCaps = (/*DDSCAPS_OFFSCREENPLAIN | */DDSCAPS_SYSTEMMEMORY); } ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; // if ( surface->format->palette ) { // ddsd.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8; // } #if defined(NONAMELESSUNION) ddsd.ddpfPixelFormat.u1.dwRGBBitCount = surface->format->BitsPerPixel; ddsd.ddpfPixelFormat.u2.dwRBitMask = surface->format->Rmask; ddsd.ddpfPixelFormat.u3.dwGBitMask = surface->format->Gmask; ddsd.ddpfPixelFormat.u4.dwBBitMask = surface->format->Bmask; #else ddsd.ddpfPixelFormat.dwRGBBitCount = 16;//surface->format->BitsPerPixel; ddsd.ddpfPixelFormat.dwRBitMask = 0xF800;//surface->format->Rmask; ddsd.ddpfPixelFormat.dwGBitMask = 0x07E0;//surface->format->Gmask; ddsd.ddpfPixelFormat.dwBBitMask = 0x001F;//surface->format->Bmask; #endif /* Create the DirectDraw video surface */ //if ( requested != NULL ) { // g_pDDSOne = requested; //} else { hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSBack, NULL); #if 0 if ( hRet != DD_OK ) { SetDDerror("DirectDraw2::CreateSurface", hRet); goto error_end; } hRet = g_pDDSBack->QueryInterface( &IID_IDirectDrawSurface3, (LPVOID *)&g_pDDSOne); g_pDDSBack->Release(); if ( hRet != DD_OK ) { SetDDerror("DirectDrawSurface::QueryInterface", hRet); goto error_end; } #endif } #if 0 if ( (flag & SDL_HWSURFACE) == SDL_HWSURFACE ) { /* Check to see whether the surface actually ended up in video memory, and fail if not. We expect the surfaces we create here to actually be in hardware! */ hRet = g_pDDSOne->GetCaps(&ddsd.ddsCaps); if ( hRet != DD_OK ) { //SetDDerror("DirectDrawSurface3::GetCaps", hRet); goto error_end; } if ( (ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) != DDSCAPS_VIDEOMEMORY ) { //SDL_SetError("No room in video memory"); goto error_end; } } else { /* Try to hook our surface memory */ ddsd.dwFlags = DDSD_LPSURFACE; ddsd.lpSurface = pixelData;//surface->pixels; hRet = g_pDDSOne->SetSurfaceDesc( &ddsd, 0); if ( hRet != DD_OK ) { //SetDDerror("DirectDraw2::SetSurfaceDesc", hRet); goto error_end; } } /* Make sure the surface format was set properly */ SDL_memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); hRet = IDirectDrawSurface3_Lock(g_pDDSOne, NULL, &ddsd, (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL); if ( hRet != DD_OK ) { //SetDDerror("DirectDrawSurface3::Lock", hRet); goto error_end; } IDirectDrawSurface3_Unlock(g_pDDSOne, NULL); if ( (flag & SDL_HWSURFACE) == SDL_SWSURFACE ) { if ( ddsd.lpSurface != surface->pixels ) { //SDL_SetError("DDraw didn't use SDL surface memory"); goto error_end; } if ( #if defined(NONAMELESSUNION) ddsd.u1.lPitch #else ddsd.lPitch #endif != (LONG)surface->pitch ) { //SDL_SetError("DDraw created surface with wrong pitch"); goto error_end; } } else { #if defined(NONAMELESSUNION) surface->pitch = (Uint16)ddsd.u1.lPitch; #else surface->pitch = (Uint16)ddsd.lPitch; #endif } #if defined(NONAMELESSUNION) if ( (ddsd.ddpfPixelFormat.u1.dwRGBBitCount != surface->format->BitsPerPixel) || (ddsd.ddpfPixelFormat.u2.dwRBitMask != surface->format->Rmask) || (ddsd.ddpfPixelFormat.u3.dwGBitMask != surface->format->Gmask) || (ddsd.ddpfPixelFormat.u4.dwBBitMask != surface->format->Bmask) ){ #else if ( (ddsd.ddpfPixelFormat.dwRGBBitCount != surface->format->BitsPerPixel) || (ddsd.ddpfPixelFormat.dwRBitMask != surface->format->Rmask) || (ddsd.ddpfPixelFormat.dwGBitMask != surface->format->Gmask) || (ddsd.ddpfPixelFormat.dwBBitMask != surface->format->Bmask) ){ #endif //SDL_SetError("DDraw didn't use SDL surface description"); goto error_end; } if ( (ddsd.dwWidth != (DWORD)surface->w) || (ddsd.dwHeight != (DWORD)surface->h) ) { //SDL_SetError("DDraw created surface with wrong size"); goto error_end; } /* Set the surface private data */ surface->flags |= flag; surface->hwdata->dd_surface = g_pDDSOne; if ( (surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { LPDIRECTDRAWSURFACE3 dd_writebuf; ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; hRet = IDirectDrawSurface3_GetAttachedSurface(g_pDDSOne, &ddsd.ddsCaps, &dd_writebuf); if ( hRet != DD_OK ) { //SetDDerror("DirectDrawSurface3::GetAttachedSurface", hRet); } else {
//----------------------------------------------------------------------------- // Name: GetDXVersion() // Desc: This function returns two arguments: // dwDXVersion: // 0x0000 = No DirectX installed // 0x0100 = DirectX version 1 installed // 0x0200 = DirectX 2 installed // 0x0300 = DirectX 3 installed // 0x0500 = At least DirectX 5 installed. // 0x0600 = At least DirectX 6 installed. // 0x0601 = At least DirectX 6.1 installed. // 0x0700 = At least DirectX 7 installed. // dwDXPlatform: // 0 = Unknown (This is a failure case) // VER_PLATFORM_WIN32_WINDOWS = Windows 9X platform // VER_PLATFORM_WIN32_NT = Windows NT platform // // Please note that this code is intended as a general guideline. Your // app will probably be able to simply query for functionality (via // QueryInterface) for one or two components. // // Please also note: // "if (dxVer != 0x500) return FALSE;" is BAD. // "if (dxVer < 0x500) return FALSE;" is MUCH BETTER. // to ensure your app will run on future releases of DirectX. //----------------------------------------------------------------------------- VOID GetDXVersion( DWORD* pdwDXVersion, DWORD* pdwDXPlatform ) { HRESULT hr; HINSTANCE DDHinst = 0; HINSTANCE DIHinst = 0; LPDIRECTDRAW pDDraw = 0; LPDIRECTDRAW2 pDDraw2 = 0; DIRECTDRAWCREATE DirectDrawCreate = 0; DIRECTDRAWCREATEEX DirectDrawCreateEx = 0; DIRECTINPUTCREATE DirectInputCreate = 0; OSVERSIONINFO osVer; LPDIRECTDRAWSURFACE pSurf = 0; LPDIRECTDRAWSURFACE3 pSurf3 = 0; LPDIRECTDRAWSURFACE4 pSurf4 = 0; // First get the windows platform osVer.dwOSVersionInfoSize = sizeof(osVer); if( !GetVersionEx( &osVer ) ) { (*pdwDXPlatform) = 0; (*pdwDXVersion) = 0; return; } if( osVer.dwPlatformId == VER_PLATFORM_WIN32_NT ) { (*pdwDXPlatform) = VER_PLATFORM_WIN32_NT; // NT is easy... NT 4.0 is DX2, 4.0 SP3 is DX3, 5.0 is DX5 // and no DX on earlier versions. if( osVer.dwMajorVersion < 4 ) { (*pdwDXVersion) = 0; // No DX on NT3.51 or earlier return; } if( osVer.dwMajorVersion == 4 ) { // NT4 up to SP2 is DX2, and SP3 onwards is DX3, so we are at least DX2 (*pdwDXVersion) = 0x200; // We're not supposed to be able to tell which SP we're on, so check for dinput DIHinst = LoadLibrary( "DINPUT.DLL" ); if( DIHinst == 0 ) { // No DInput... must be DX2 on NT 4 pre-SP3 OutputDebugString( "Couldn't LoadLibrary DInput\r\n" ); return; } DirectInputCreate = (DIRECTINPUTCREATE)GetProcAddress( DIHinst, "DirectInputCreateA" ); FreeLibrary( DIHinst ); if( DirectInputCreate == 0 ) { // No DInput... must be pre-SP3 DX2 OutputDebugString( "Couldn't GetProcAddress DInputCreate\r\n" ); return; } // It must be NT4, DX2 (*pdwDXVersion) = 0x300; // DX3 on NT4 SP3 or higher return; } // Else it's NT5 or higher, and it's DX5a or higher: Drop through to // Win9x tests for a test of DDraw (DX6 or higher) } else { // Not NT... must be Win9x (*pdwDXPlatform) = VER_PLATFORM_WIN32_WINDOWS; } // Now we know we are in Windows 9x (or maybe 3.1), so anything's possible. // First see if DDRAW.DLL even exists. DDHinst = LoadLibrary( "DDRAW.DLL" ); if( DDHinst == 0 ) { (*pdwDXVersion) = 0; (*pdwDXPlatform) = 0; FreeLibrary( DDHinst ); return; } // See if we can create the DirectDraw object. DirectDrawCreate = (DIRECTDRAWCREATE)GetProcAddress( DDHinst, "DirectDrawCreate" ); if( DirectDrawCreate == 0 ) { (*pdwDXVersion) = 0; (*pdwDXPlatform) = 0; FreeLibrary( DDHinst ); OutputDebugString( "Couldn't LoadLibrary DDraw\r\n" ); return; } hr = DirectDrawCreate( NULL, &pDDraw, NULL ); if( FAILED(hr) ) { (*pdwDXVersion) = 0; (*pdwDXPlatform) = 0; FreeLibrary( DDHinst ); OutputDebugString( "Couldn't create DDraw\r\n" ); return; } // So DirectDraw exists. We are at least DX1. (*pdwDXVersion) = 0x100; // Let's see if IID_IDirectDraw2 exists. hr = pDDraw->QueryInterface( IID_IDirectDraw2, (VOID**)&pDDraw2 ); if( FAILED(hr) ) { // No IDirectDraw2 exists... must be DX1 pDDraw->Release(); FreeLibrary( DDHinst ); OutputDebugString( "Couldn't QI DDraw2\r\n" ); return; } // IDirectDraw2 exists. We must be at least DX2 pDDraw2->Release(); (*pdwDXVersion) = 0x200; /////////////////////////////////////////////////////////////////////////// // DirectX 3.0 Checks /////////////////////////////////////////////////////////////////////////// // DirectInput was added for DX3 DIHinst = LoadLibrary( "DINPUT.DLL" ); if( DIHinst == 0 ) { // No DInput... must not be DX3 OutputDebugString( "Couldn't LoadLibrary DInput\r\n" ); pDDraw->Release(); FreeLibrary( DDHinst ); return; } DirectInputCreate = (DIRECTINPUTCREATE)GetProcAddress( DIHinst, "DirectInputCreateA" ); if( DirectInputCreate == 0 ) { // No DInput... must be DX2 FreeLibrary( DIHinst ); FreeLibrary( DDHinst ); pDDraw->Release(); OutputDebugString( "Couldn't GetProcAddress DInputCreate\r\n" ); return; } // DirectInputCreate exists. We are at least DX3 (*pdwDXVersion) = 0x300; FreeLibrary( DIHinst ); // Can do checks for 3a vs 3b here /////////////////////////////////////////////////////////////////////////// // DirectX 5.0 Checks /////////////////////////////////////////////////////////////////////////// // We can tell if DX5 is present by checking for the existence of // IDirectDrawSurface3. First, we need a surface to QI off of. DDSURFACEDESC ddsd; ZeroMemory( &ddsd, sizeof(ddsd) ); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; hr = pDDraw->SetCooperativeLevel( NULL, DDSCL_NORMAL ); if( FAILED(hr) ) { // Failure. This means DDraw isn't properly installed. pDDraw->Release(); FreeLibrary( DDHinst ); (*pdwDXVersion) = 0; OutputDebugString( "Couldn't Set coop level\r\n" ); return; } hr = pDDraw->CreateSurface( &ddsd, &pSurf, NULL ); if( FAILED(hr) ) { // Failure. This means DDraw isn't properly installed. pDDraw->Release(); FreeLibrary( DDHinst ); *pdwDXVersion = 0; OutputDebugString( "Couldn't CreateSurface\r\n" ); return; } // Query for the IDirectDrawSurface3 interface if( FAILED( pSurf->QueryInterface( IID_IDirectDrawSurface3, (VOID**)&pSurf3 ) ) ) { pDDraw->Release(); FreeLibrary( DDHinst ); return; } // QI for IDirectDrawSurface3 succeeded. We must be at least DX5 (*pdwDXVersion) = 0x500; /////////////////////////////////////////////////////////////////////////// // DirectX 6.0 Checks /////////////////////////////////////////////////////////////////////////// // The IDirectDrawSurface4 interface was introduced with DX 6.0 if( FAILED( pSurf->QueryInterface( IID_IDirectDrawSurface4, (VOID**)&pSurf4 ) ) ) { pDDraw->Release(); FreeLibrary( DDHinst ); return; } // IDirectDrawSurface4 was create successfully. We must be at least DX6 (*pdwDXVersion) = 0x600; pSurf->Release(); pDDraw->Release(); /////////////////////////////////////////////////////////////////////////// // DirectX 6.1 Checks /////////////////////////////////////////////////////////////////////////// // Check for DMusic, which was introduced with DX6.1 LPDIRECTMUSIC pDMusic = NULL; CoInitialize( NULL ); hr = CoCreateInstance( CLSID_DirectMusic, NULL, CLSCTX_INPROC_SERVER, IID_IDirectMusic, (VOID**)&pDMusic ); if( FAILED(hr) ) { OutputDebugString( "Couldn't create CLSID_DirectMusic\r\n" ); FreeLibrary( DDHinst ); return; } // DirectMusic was created successfully. We must be at least DX6.1 (*pdwDXVersion) = 0x601; pDMusic->Release(); CoUninitialize(); /////////////////////////////////////////////////////////////////////////// // DirectX 7.0 Checks /////////////////////////////////////////////////////////////////////////// // Check for DirectX 7 by creating a DDraw7 object LPDIRECTDRAW7 pDD7; DirectDrawCreateEx = (DIRECTDRAWCREATEEX)GetProcAddress( DDHinst, "DirectDrawCreateEx" ); if( NULL == DirectDrawCreateEx ) { FreeLibrary( DDHinst ); return; } if( FAILED( DirectDrawCreateEx( NULL, (VOID**)&pDD7, IID_IDirectDraw7, NULL ) ) ) { FreeLibrary( DDHinst ); return; } // DDraw7 was created successfully. We must be at least DX7.0 (*pdwDXVersion) = 0x700; pDD7->Release(); /////////////////////////////////////////////////////////////////////////// // End of checks /////////////////////////////////////////////////////////////////////////// // Close open libraries and return FreeLibrary( DDHinst ); return; }
bool CDirectDraw::SetDisplayMode( int pWidth, int pHeight, int pScale, char pDepth, int pRefreshRate, bool pWindowed, bool pDoubleBuffered) { if(pScale < 2) pScale = 2; static bool BLOCK = false; DDSURFACEDESC ddsd; PALETTEENTRY PaletteEntries [256]; if (BLOCK) return (false); BLOCK = true; if (pWindowed) pDoubleBuffered = false; if (pDepth == 0) pDepth = Depth; if (lpDDSPrimary2 != NULL) { lpDDSPrimary2->Release(); lpDDSPrimary2 = NULL; } if (lpDDSOffScreen2 != NULL) { lpDDSOffScreen2->PageUnlock(0); lpDDSOffScreen2->Release(); lpDDSOffScreen2 = NULL; } if( lpDDPalette != NULL) { lpDDPalette->Release(); lpDDPalette = NULL; } lpDD->FlipToGDISurface(); if (pWindowed) { lpDD->RestoreDisplayMode(); SetWindowLong( GUI.hWnd, GWL_STYLE, WS_POPUPWINDOW|WS_CAPTION| WS_THICKFRAME|WS_VISIBLE|WS_MINIMIZEBOX|WS_MAXIMIZEBOX); // disabled because it messes up window maximization //if (!VOODOO_MODE) // SetWindowPos( GUI.hWnd, HWND_TOP, 0, 0, 0, 0, // SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE); //else // SetWindowPos( GUI.hWnd, HWND_TOP, 0, 0, 0, 0, // SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE); ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_PIXELFORMAT; dErr = lpDD->GetDisplayMode (&ddsd); if (FAILED(dErr)) pDepth = 8; else { if (ddsd.ddpfPixelFormat.dwFlags&DDPF_RGB) pDepth = (char) ddsd.ddpfPixelFormat.dwRGBBitCount; else pDepth = 8; } if (pDepth == 8) dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_FULLSCREEN| DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT); else dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_NORMAL|DDSCL_ALLOWREBOOT); } else { SetWindowLong (GUI.hWnd, GWL_STYLE, WS_POPUP|WS_VISIBLE); if (!VOODOO_MODE) { SetWindowPos (GUI.hWnd, HWND_TOP, 0, 0, 0, 0, SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE); dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN|DDSCL_ALLOWREBOOT); // XXX: TODO: use pRefreshRate! dErr = lpDD->SetDisplayMode (pWidth, pHeight, pDepth); } else { SetWindowPos (GUI.hWnd, HWND_TOP, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE); dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_NORMAL|DDSCL_ALLOWREBOOT); } } if (FAILED(dErr)) { BLOCK = false; return false; } ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; if(GUI.ddrawUseVideoMemory) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | (GUI.ddrawUseLocalVidMem ? DDSCAPS_LOCALVIDMEM : DDSCAPS_NONLOCALVIDMEM); } else { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; } ddsd.dwWidth = SNES_WIDTH * pScale; ddsd.dwHeight = SNES_HEIGHT_EXTENDED * pScale; LPDIRECTDRAWSURFACE lpDDSOffScreen; if (FAILED(lpDD->CreateSurface (&ddsd, &lpDDSOffScreen, NULL))) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | (GUI.ddrawUseLocalVidMem ? DDSCAPS_NONLOCALVIDMEM : DDSCAPS_LOCALVIDMEM); if(!GUI.ddrawUseVideoMemory || FAILED(lpDD->CreateSurface (&ddsd, &lpDDSOffScreen, NULL))) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; if(!GUI.ddrawUseVideoMemory || FAILED(lpDD->CreateSurface (&ddsd, &lpDDSOffScreen, NULL))) { BLOCK = false; return (false); } } } if (FAILED (lpDDSOffScreen->QueryInterface (IID_IDirectDrawSurface2, (void **)&lpDDSOffScreen2))) { lpDDSOffScreen->Release(); BLOCK = false; return (false); } lpDDSOffScreen2->PageLock(0); lpDDSOffScreen->Release(); ZeroMemory (&ddsd, sizeof (ddsd)); if (pDoubleBuffered) { ddsd.dwSize = sizeof( ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; GUI.NumFlipFrames = 3; ddsd.dwBackBufferCount = 2; } else { GUI.NumFlipFrames = 1; ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; } LPDIRECTDRAWSURFACE lpDDSPrimary; dErr = lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL); if( FAILED(dErr) ) { if (pDoubleBuffered) { ddsd.dwBackBufferCount = 1; GUI.NumFlipFrames = 2; if (FAILED(dErr = lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL))) { ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; pDoubleBuffered = false; GUI.NumFlipFrames = 1; dErr = lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL); } } if (FAILED(dErr)) { BLOCK = false; lpDDSOffScreen2->PageUnlock(0); lpDDSOffScreen2->Release(); lpDDSOffScreen2 = NULL; return (false); } } ZeroMemory (&DDPixelFormat, sizeof (DDPixelFormat)); DDPixelFormat.dwSize = sizeof (DDPixelFormat); lpDDSPrimary->GetPixelFormat (&DDPixelFormat); Clipped = true; if((!pWindowed && pDoubleBuffered) || FAILED(lpDDSPrimary->SetClipper( lpDDClipper))) Clipped = false; if (FAILED (lpDDSPrimary->QueryInterface (IID_IDirectDrawSurface2, (void **)&lpDDSPrimary2))) { BLOCK = false; lpDDSPrimary->Release(); lpDDSPrimary = NULL; return (FALSE); } lpDDSPrimary->Release(); lpDDSPrimary = NULL; if((!pWindowed && pDoubleBuffered) || FAILED(lpDDSPrimary2->SetClipper( lpDDClipper))) Clipped = false; if (pDepth == 8) { dErr = lpDD->CreatePalette (DDPCAPS_8BIT | DDPCAPS_ALLOW256, PaletteEntries, &lpDDPalette, NULL); if( FAILED(dErr)) { lpDDPalette = NULL; BLOCK = false; return false; } } Depth = pDepth; Height = pHeight; Width = pWidth; DoubleBuffered = pDoubleBuffered; BLOCK = false; return (true); }