/** * Create a clipper that will be used when blitting the RGB surface to the main display. * * This clipper prevents us to modify by mistake anything on the screen * which doesn't belong to our window. For example when a part of our video * window is hidden by another window. */ static void DirectXCreateClipper(vout_display_t *vd) { vout_display_sys_t *sys = vd->sys; HRESULT hr; /* Create the clipper */ hr = IDirectDraw2_CreateClipper(sys->ddobject, 0, &sys->clipper, NULL); if (hr != DD_OK) { msg_Warn(vd, "cannot create clipper (error %li)", hr); goto error; } /* Associate the clipper to the window */ hr = IDirectDrawClipper_SetHWnd(sys->clipper, 0, sys->hvideownd); if (hr != DD_OK) { msg_Warn(vd, "cannot attach clipper to window (error %li)", hr); goto error; } /* associate the clipper with the surface */ hr = IDirectDrawSurface_SetClipper(sys->display, sys->clipper); if (hr != DD_OK) { msg_Warn(vd, "cannot attach clipper to surface (error %li)", hr); goto error; } return; error: if (sys->clipper) IDirectDrawClipper_Release(sys->clipper); sys->clipper = NULL; }
int renderer_dd::create_clipper() { HRESULT result; // create a clipper for the primary surface result = IDirectDraw7_CreateClipper(ddraw, 0, &clipper, NULL); if (result != DD_OK) { osd_printf_verbose("DirectDraw: Error %08X creating clipper\n", (int)result); return 1; } // set the clipper's hwnd result = IDirectDrawClipper_SetHWnd(clipper, 0, window().m_hwnd); if (result != DD_OK) { osd_printf_verbose("DirectDraw: Error %08X setting clipper hwnd\n", (int)result); return 1; } // set the clipper on the primary surface result = IDirectDrawSurface7_SetClipper(primary, clipper); if (result != DD_OK) { osd_printf_verbose("DirectDraw: Error %08X setting clipper on primary surface\n", (int)result); return 1; } return 0; }
static int create_clipper(win_window_info *window) { dd_info *dd = window->drawdata; HRESULT result; // create a clipper for the primary surface result = IDirectDraw7_CreateClipper(dd->ddraw, 0, &dd->clipper, NULL); if (result != DD_OK) { mame_printf_verbose("DirectDraw: Error %08X creating clipper\n", (int)result); return 1; } // set the clipper's hwnd result = IDirectDrawClipper_SetHWnd(dd->clipper, 0, window->hwnd); if (result != DD_OK) { mame_printf_verbose("DirectDraw: Error %08X setting clipper hwnd\n", (int)result); return 1; } // set the clipper on the primary surface result = IDirectDrawSurface7_SetClipper(dd->primary, dd->clipper); if (result != DD_OK) { mame_printf_verbose("DirectDraw: Error %08X setting clipper on primary surface\n", (int)result); return 1; } return 0; }
static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) { IDirect3DDevice7 *device = NULL; IDirectDrawSurface7 *surface; DDSURFACEDESC2 surface_desc; IDirectDraw7 *ddraw; IDirect3D7 *d3d7; HRESULT hr; if (!(ddraw = create_ddraw())) return NULL; hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, coop_level); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; surface_desc.dwWidth = 640; surface_desc.dwHeight = 480; hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); if (coop_level & DDSCL_NORMAL) { IDirectDrawClipper *clipper; hr = IDirectDraw7_CreateClipper(ddraw, 0, &clipper, NULL); ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr); hr = IDirectDrawClipper_SetHWnd(clipper, 0, window); ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr); hr = IDirectDrawSurface7_SetClipper(surface, clipper); ok(SUCCEEDED(hr), "Failed to set surface clipper, hr %#x.\n", hr); IDirectDrawClipper_Release(clipper); } hr = IDirectDraw7_QueryInterface(ddraw, &IID_IDirect3D7, (void **)&d3d7); IDirectDraw7_Release(ddraw); if (FAILED(hr)) { IDirectDrawSurface7_Release(surface); return NULL; } hr = IDirect3D7_CreateDevice(d3d7, &IID_IDirect3DTnLHalDevice, surface, &device); IDirect3D7_Release(d3d7); IDirectDrawSurface7_Release(surface); if (FAILED(hr)) return NULL; return device; }
BOOL gldSwapBuffers_DX( DGL_ctx *ctx, HDC hDC, HWND hWnd) { HRESULT hr; GLD_driver_dx7 *gld = NULL; DWORD dwFlags; if (ctx == NULL) return FALSE; gld = ctx->glPriv; if (gld == NULL) return FALSE; // End the scene if one is started if (ctx->bSceneStarted) { IDirect3DDevice7_EndScene(gld->pDev); ctx->bSceneStarted = FALSE; } // Needed by D3DX for MDI multi-window apps (DaveM) if (lpDDClipper) IDirectDrawClipper_SetHWnd(lpDDClipper, 0, hWnd); // Swap the buffers. hWnd may override the hWnd used for CreateDevice() // hr = IDirect3DDevice8_Present(gld->pDev, NULL, NULL, hWnd, NULL); // Set refresh sync flag dwFlags = glb.bWaitForRetrace ? 0 : D3DX_UPDATE_NOVSYNC; // Render and show frame hr = gld->pD3DXContext->lpVtbl->UpdateFrame(gld->pD3DXContext, dwFlags); if (FAILED(hr)) ddlogError(DDLOG_WARN, "gldSwapBuffers_DX: UpdateFrame", hr); if (hr == DDERR_SURFACELOST) { hr = gld->pD3DXContext->lpVtbl->RestoreSurfaces(gld->pD3DXContext); if (FAILED(hr)) ddlogError(DDLOG_WARN, "gldSwapBuffers_DX: RestoreSurfaces", hr); } exit_swap: // Begin a new scene IDirect3DDevice7_BeginScene(gld->pDev); ctx->bSceneStarted = TRUE; return (FAILED(hr)) ? FALSE : TRUE; }
static int win32_gui_data_exchange( vo_driver_t * vo_driver, int data_type, void * data ) { win32_driver_t *win32_driver = ( win32_driver_t * ) vo_driver; switch( data_type ) { case GUI_WIN32_MOVED_OR_RESIZED: UpdateRect( win32_driver->win32_visual ); DisplayFrame( win32_driver ); break; case XINE_GUI_SEND_DRAWABLE_CHANGED: { HRESULT result; HWND newWndHnd = (HWND) data; /* set cooperative level */ result = IDirectDraw_SetCooperativeLevel( win32_driver->ddobj, newWndHnd, DDSCL_NORMAL ); if( result != DD_OK ) { Error( 0, "SetCooperativeLevel : error 0x%lx", result ); return 0; } /* associate our clipper with new window */ result = IDirectDrawClipper_SetHWnd( win32_driver->ddclipper, 0, newWndHnd ); if( result != DD_OK ) { Error( 0, "ddclipper->SetHWnd : error 0x%lx", result ); return 0; } /* store our objects in our visual struct */ win32_driver->win32_visual->WndHnd = newWndHnd; /* update video area and redraw current frame */ UpdateRect( win32_driver->win32_visual ); DisplayFrame( win32_driver ); break; } } return 0; }
boolean CreatePrimary( win32_driver_t * win32_driver ) { LPDIRECTDRAW ddobj; DDSURFACEDESC2 ddsd; HRESULT result; // create direct draw object result = DirectDrawCreate( 0, &ddobj, 0 ); if( result != DD_OK ) { Error( 0, "DirectDrawCreate : error %i", result ); printf( "vo_out_directx : DirectDrawCreate : error %i\n", result ); return 0; } // set cooperative level result = IDirectDraw_SetCooperativeLevel( ddobj, win32_driver->win32_visual->WndHnd, DDSCL_NORMAL ); if( result != DD_OK ) { Error( 0, "SetCooperativeLevel : error %i", result ); return 0; } // try to get new interface result = IDirectDraw_QueryInterface( ddobj, &IID_IDirectDraw7, (LPVOID *) &win32_driver->ddobj ); if( result != DD_OK ) { Error( 0, "ddobj->QueryInterface : DirectX 7 or higher required" ); return 0; } // release our old interface IDirectDraw_Release( ddobj ); // create primary_surface memset( &ddsd, 0, sizeof( ddsd ) ); ddsd.dwSize = sizeof( ddsd ); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; result = IDirectDraw7_CreateSurface( win32_driver->ddobj, &ddsd, &win32_driver->primary, 0 ); if( result != DD_OK ) { Error( 0, "CreateSurface ( primary ) : error %i ", result ); return 0; } // create our clipper object result = IDirectDraw7_CreateClipper( win32_driver->ddobj, 0, &win32_driver->ddclipper, 0 ); if( result != DD_OK ) { Error( 0, "CreateClipper : error %i", result ); return 0; } // associate our clipper with our window result = IDirectDrawClipper_SetHWnd( win32_driver->ddclipper, 0, win32_driver->win32_visual->WndHnd ); if( result != DD_OK ) { Error( 0, "ddclipper->SetHWnd : error %i", result ); return 0; } // associate our primary surface with our clipper result = IDirectDrawSurface7_SetClipper( win32_driver->primary, win32_driver->ddclipper ); if( result != DD_OK ) { Error( 0, "ddclipper->SetHWnd : error %i", result ); return 0; } // store our objects in our visual struct UpdateRect( win32_driver->win32_visual ); return 1; }
// // - returns true if DirectDraw was initialized properly // int InitDirectDrawe (HWND appWin, int width, int height, int bpp, int fullScr) { DDSURFACEDESC ddsd; // DirectDraw surface description for allocating DDSCAPS ddscaps; HRESULT ddrval; DWORD dwStyle; RECT rect; // enumerate directdraw devices //if (FAILED(DirectDrawEnumerate (myEnumDDDevicesCallback, NULL))) // I_Error("Error with DirectDrawEnumerate"); if (!DDr2) CreateDirectDrawInstance(); // remember what screen mode we are in bAppFullScreen = fullScr; ScreenHeight = height; ScreenWidth = width; if (bAppFullScreen) { // Change window attributes dwStyle = WS_POPUP | WS_VISIBLE; SetWindowLong (appWin, GWL_STYLE, dwStyle); SetWindowPos(appWin, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); // Get exclusive mode ddrval = IDirectDraw2_SetCooperativeLevel(DDr2, appWin, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT); if (ddrval != DD_OK) I_Error("SetCooperativeLevel FAILED: %s\n", DXErrorToString(ddrval)); // Switch from windows desktop to fullscreen #ifdef NT4COMPAT ddrval = IDirectDraw2_SetDisplayMode(DDr2, width, height, bpp, 0, 0); #else ddrval = IDirectDraw2_SetDisplayMode(DDr2, width, height, bpp, 0, DDSDM_STANDARDVGAMODE); #endif if (ddrval != DD_OK) I_Error("SetDisplayMode FAILED: %s\n", DXErrorToString(ddrval)); // This is not really needed, except in certain cases. One case // is while using MFC. When the desktop is initally at 16bpp, a mode // switch to 8bpp somehow causes the MFC window to not fully initialize // and a CreateSurface will fail with DDERR_NOEXCLUSIVEMODE. This will // ensure that the window is initialized properly after a mode switch. ShowWindow(appWin, SW_SHOW); // Create the primary surface with 1 back buffer. Always zero the // DDSURFACEDESC structure and set the dwSize member! ZeroMemory(&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; // for fullscreen we use page flipping, for windowed mode, we blit the hidden surface to // the visible surface, in both cases we have a visible (or 'real') surface, and a hidden // (or 'virtual', or 'backbuffer') surface. ddsd.dwBackBufferCount = 2; ddrval = IDirectDraw2_CreateSurface(DDr2,&ddsd, &ScreenReal, NULL); if (ddrval != DD_OK) I_Error("CreateSurface Primary Screen FAILED"); // Get a pointer to the back buffer ddscaps.dwCaps = DDSCAPS_BACKBUFFER; ddrval = IDirectDrawSurface_GetAttachedSurface(ScreenReal,&ddscaps, &ScreenVirtual); if (ddrval != DD_OK) I_Error("GetAttachedSurface FAILED"); } else { rect.top = 0; rect.left = 0; rect.bottom = height; rect.right = width; // Change window attributes dwStyle = GetWindowStyle(appWin); dwStyle &= ~WS_POPUP; dwStyle |= WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION; SetWindowLong(appWin, GWL_STYLE, dwStyle); // Resize the window so that the client area is the requested width/height AdjustWindowRectEx(&rect, GetWindowStyle(appWin), GetMenu(appWin) != NULL, GetWindowExStyle(appWin)); // Just in case the window was moved off the visible area of the // screen. SetWindowPos(appWin, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); SetWindowPos(appWin, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); // Exclusive mode is normal since it's in windowed mode and needs // to cooperate with GDI ddrval = IDirectDraw2_SetCooperativeLevel(DDr2,appWin, DDSCL_NORMAL); if (ddrval != DD_OK) I_Error("SetCooperativeLevel FAILED"); // Always zero the DDSURFACEDESC structure and set the dwSize member! ZeroMemory(&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; // Create the primary surface ddrval = IDirectDraw2_CreateSurface(DDr2,&ddsd, &ScreenReal, NULL); if (ddrval != DD_OK) I_Error("CreateSurface Primary Screen FAILED"); // Create a back buffer for offscreen rendering, this will be used to // blt to the primary ScreenVirtual = CreateNewSurface(width, height, DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY); if (ScreenVirtual == NULL) I_Error("CreateSurface Secondary Screen FAILED"); /// \todo get the desktop bit depth, and build a lookup table /// for quick conversions of 8bit color indexes 0-255 to desktop colors /// eg: 256 entries of equivalent of palette colors 0-255 in 15,16,24,32 bit format /// when blit virtual to real, convert pixels through lookup table.. // Use a clipper object for clipping when in windowed mode // (make sure our drawing doesn't affect other windows) ddrval = IDirectDraw2_CreateClipper (DDr2, 0, &windclip, 0); if (ddrval != DD_OK) I_Error("CreateClipper FAILED"); // Associate the clipper with the window. ddrval = IDirectDrawClipper_SetHWnd (windclip,0, appWin); if (ddrval != DD_OK) I_Error("Clipper -> SetHWnd FAILED"); // Attach the clipper to the surface. ddrval = IDirectDrawSurface_SetClipper (ScreenReal,windclip); if (ddrval != DD_OK) I_Error("PrimaryScreen -> SetClipperClipper FAILED"); } return TRUE; }
BOOL DDInit(int mode) { LPDIRECTDRAW lpdd; DDCAPS ddcaps, ddcaps2; HRESULT ddresult; int num; DDWnd = GetLibraryWindow(); // Create Direct Draw Object (Use Emulation if Hardware is off) if (!_lpDD) { ddresult = DirectDrawCreate(NULL, &lpdd, NULL); if (ddresult == DDERR_NODIRECTDRAWHW) { ddresult = DirectDrawCreate( (LPVOID) DDCREATE_EMULATIONONLY, &lpdd, NULL ); if (!CheckDDResult(ddresult, "InitDD:DirectDrawCreate emulation")) return FALSE; DDUseEmulation = TRUE; logentry("DirectDraw: forcing emulation.\n"); } else if (ddresult != DD_OK) return FALSE; logentry("DirectDraw: DirectX API hardware compliant.\n"); } else return FALSE; atexit(DDKill); // Determine hardware caps // Determine capture mode (fullscreen takes exclusive, window is normal) if (mode == DDGR_FULLSCREEN) { DWORD flags; flags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN; #ifndef NDEBUG if (!FindArg("-nomodex")) flags |= DDSCL_ALLOWMODEX; #else flags |= DDSCL_ALLOWMODEX; #endif if (!FindArg("-disallowreboot")) flags |= DDSCL_ALLOWREBOOT; ddresult = IDirectDraw_SetCooperativeLevel(lpdd, DDWnd, flags); if (!CheckDDResult(ddresult, "DDInit::SetCooperativeLevel")) { IDirectDraw_Release(lpdd); return FALSE; } _DDExclusive = TRUE; _DDFullScreen = TRUE; } else if (mode == DDGR_EXWINDOW) { ddresult = IDirectDraw_SetCooperativeLevel(lpdd, DDWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (!CheckDDResult(ddresult, "DDInit::SetCooperativeLevel")) return FALSE; _DDExclusive = TRUE; _DDFullScreen = FALSE; } else if (mode == DDGR_WINDOW) { ddresult = IDirectDraw_SetCooperativeLevel(lpdd, DDWnd, DDSCL_NORMAL); if (!CheckDDResult(ddresult, "DDInit::SetCooperativeLevel")) return FALSE; _DDExclusive = FALSE; _DDFullScreen = FALSE; } else return FALSE; // Get Display modes/Window Sizes // Force invalidation of all modes for now for (num = 0; num < 16; num++) { _DDModeList[num].rw = _DDModeList[num].w = -1; _DDModeList[num].rh = _DDModeList[num].h = -1; } W95DisplayMode = SM95_640x480x8; num = 0; if (mode == DDGR_FULLSCREEN) { ddresult = IDirectDraw_EnumDisplayModes(lpdd, 0, NULL, 0, EnumDispModesCB); if(!CheckDDResult(ddresult, "DDInit::EnumDisplayModes")) { IDirectDraw_Release(lpdd); return FALSE; } } else if (mode == DDGR_EXWINDOW) { _DDModeList[SM95_320x200x8X].rw = 320; _DDModeList[SM95_320x200x8X].rh = 200; _DDModeList[SM95_320x200x8X].w = 640; _DDModeList[SM95_320x200x8X].h = 480; _DDModeList[SM95_320x200x8X].emul = 1; _DDModeList[SM95_320x200x8X].dbuf = 0; _DDModeList[SM95_320x200x8X].modex = 0; _DDModeList[SM95_320x200x8X].paged = 0; _DDModeList[SM95_640x480x8].rw = 640; _DDModeList[SM95_640x480x8].rh = 480; _DDModeList[SM95_640x480x8].w = 640; _DDModeList[SM95_640x480x8].h = 480; _DDModeList[SM95_640x480x8].emul = 1; _DDModeList[SM95_640x480x8].dbuf = 0; _DDModeList[SM95_640x480x8].modex = 0; _DDModeList[SM95_640x480x8].paged = 0; _DDModeList[SM95_800x600x8].rw = 800; _DDModeList[SM95_800x600x8].rh = 600; _DDModeList[SM95_800x600x8].w = 640; _DDModeList[SM95_800x600x8].h = 480; _DDModeList[SM95_800x600x8].emul = 1; _DDModeList[SM95_800x600x8].dbuf = 0; _DDModeList[SM95_800x600x8].modex = 0; _DDModeList[SM95_800x600x8].paged = 0; _DDNumModes = 3; } else if (mode == DDGR_WINDOW) { _DDModeList[SM95_320x200x8X].rw = 320; _DDModeList[SM95_320x200x8X].rh = 200; _DDModeList[SM95_320x200x8X].w = 640; _DDModeList[SM95_320x200x8X].h = 480; _DDModeList[SM95_320x200x8X].emul = 1; _DDModeList[SM95_320x200x8X].dbuf = 0; _DDModeList[SM95_320x200x8X].modex = 0; _DDModeList[SM95_320x200x8X].paged = 0; _DDModeList[SM95_640x480x8].rw = 640; _DDModeList[SM95_640x480x8].rh = 480; _DDModeList[SM95_640x480x8].w = 640; _DDModeList[SM95_640x480x8].h = 480; _DDModeList[SM95_640x480x8].emul = 1; _DDModeList[SM95_640x480x8].dbuf = 0; _DDModeList[SM95_640x480x8].modex = 0; _DDModeList[SM95_640x480x8].paged = 0; _DDModeList[SM95_800x600x8].rw = 800; _DDModeList[SM95_800x600x8].rh = 600; _DDModeList[SM95_800x600x8].w = 800; _DDModeList[SM95_800x600x8].h = 600; _DDModeList[SM95_800x600x8].emul = 1; _DDModeList[SM95_800x600x8].dbuf = 0; _DDModeList[SM95_800x600x8].modex = 0; _DDModeList[SM95_800x600x8].paged = 0; _DDNumModes = 3; } else return FALSE; // Set appropriate display mode or window mode _lpDD = lpdd; memset(&ddcaps, 0, sizeof(ddcaps)); ddcaps.dwSize = sizeof(ddcaps); ddcaps2.dwSize = sizeof(ddcaps); ddresult = IDirectDraw_GetCaps(_lpDD, &ddcaps, NULL); if (!CheckDDResult(ddresult, "InitDD::GetCaps")) return FALSE; logentry("DirectDraw: VRAM free: %d\n", ddcaps.dwVidMemFree); logentry("DirectDraw: VRAM total: %d\n", ddcaps.dwVidMemTotal); #ifndef NDEBUG if (FindArg("-TsengDebug1")) { IDirectDraw_Release(lpdd); return FALSE; } #endif DDSetDisplayMode(W95DisplayMode, 0); #ifndef NDEBUG if (FindArg("-TsengDebug2")) { IDirectDraw_Release(lpdd); return FALSE; } #endif // If 'windowed' do this. if (!_DDFullScreen) { ddresult = IDirectDraw_CreateClipper(_lpDD, 0, &_lpDDClipper, NULL); if (!CheckDDResult(ddresult, "DDCreateScreen::CreateClipper")) return FALSE; ddresult = IDirectDrawClipper_SetHWnd(_lpDDClipper, 0, DDWnd); if (!CheckDDResult(ddresult, "DDCreateScreen::SetHWnd")) return FALSE; ddresult = IDirectDrawSurface_SetClipper(_lpDDSPrimary, _lpDDClipper); if (!CheckDDResult(ddresult, "DDCreateScreen::SetClipper")) return FALSE; } // Register Optimizations ddcaps.dwSize = sizeof(ddcaps); ddcaps2.dwSize = sizeof(ddcaps); ddresult = IDirectDraw_GetCaps(lpdd, &ddcaps, &ddcaps2); if (!CheckDDResult(ddresult, "DDInit::GetCaps")) return FALSE; #ifndef NDEBUG if (FindArg("-TsengDebug3")) { IDirectDraw_Release(lpdd); return FALSE; } #endif if (FindArg("-vidram")) { logentry("DirectDraw: Forcing VRAM rendering.\n"); _DDSysMemSurfacing = FALSE; } else if (FindArg("-sysram")) { logentry("DirectDraw: Forcing SRAM rendering.\n"); _DDSysMemSurfacing = TRUE; } else if (ddcaps.dwCaps & DDCAPS_BANKSWITCHED) { logentry("DirectDraw: Hardware is bank-switched. Using SRAM rendering.\n"); _DDSysMemSurfacing = TRUE; } else { logentry("DirectDraw: Hardware is not bank-switched. Using VRAM rendering.\n"); _DDSysMemSurfacing = FALSE; } if (ddcaps.dwCaps & DDCAPS_COLORKEYHWASSIST) ddDriverCaps.hwcolorkey = 1; else ddDriverCaps.hwcolorkey = 0; if (ddcaps.dwCaps & DDCAPS_BLTSTRETCH) ddDriverCaps.hwbltstretch = 1; else ddDriverCaps.hwbltstretch = 0; //@@ mprintf((0, "DD::Hardware=")); //@@ if (ddcaps.dwCaps & DDCAPS_NOHARDWARE) mprintf((0, "Off\n")); //@@ else mprintf((0, "On\n")); //@@ //@@ mprintf((0, "DD::VideoMem=%u bytes\n", ddcaps.dwVidMemTotal)); //@@ mprintf((0, "DD::SrcColorKey=")); //@@ if (ddcaps.dwCKeyCaps & DDCKEYCAPS_SRCBLT) mprintf((0, "Hardware\n")); //@@ else mprintf((0, "Emulation\n")); return TRUE; }
int directdraw_init(HWND hwndp) { int width = 320, height = 200; RECT rect; DDPIXELFORMAT format; DDSURFACEDESC descriptor; DIRECTDRAWCREATE DirectDrawCreate; if(lpDDS) return 0; if(!hwndp) return 0; if(video_window) return 0; /* you gotta uninitialize it first */ library = (HMODULE) LoadLibrary(uni("ddraw.dll")); if(!library) return 0; DirectDrawCreate = (DIRECTDRAWCREATE) GetProcAddress(library, "DirectDrawCreate"); if(!DirectDrawCreate) return 0; if(FAILED(DirectDrawCreate(0,&lpDD,0))) return 0; wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = 0; wc.hIcon = 0; wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hbrBackground = 0; wc.lpszMenuName = 0; wc.lpszClassName = window_class_name; RegisterClass(&wc); video_window = CreateWindow(window_class_name, uni("Video"), WS_CHILD, 0, 0, width, height, hwndp, 0, 0, 0); ShowWindow(video_window, SW_NORMAL); if(FAILED(IDirectDraw2_SetCooperativeLevel(lpDD, video_window, DDSCL_NORMAL))) return 0; descriptor.dwSize = sizeof(descriptor); descriptor.dwFlags = DDSD_CAPS; descriptor.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY; if(FAILED(IDirectDraw2_CreateSurface(lpDD, &descriptor, &lpDDS, 0))) return 0; descriptor.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; descriptor.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; descriptor.dwWidth = d_width ; descriptor.dwHeight = d_height; if(FAILED(IDirectDraw2_CreateSurface(lpDD, &descriptor, &lpDDS_secondary, 0))) return 0; if(FAILED(IDirectDraw2_CreateClipper(lpDD, 0, &lpDDC, 0))) return 0; if(FAILED(IDirectDrawClipper_SetHWnd(lpDDC, 0, video_window))) return 0; if(FAILED(IDirectDrawSurface2_SetClipper(lpDDS, lpDDC))) return 0; lpDDS_back = lpDDS_secondary; format.dwSize = sizeof(format); if(FAILED(IDirectDrawSurface2_GetPixelFormat(lpDDS, &format))) return 0; if(!(format.dwFlags & DDPF_RGB)) return 0; IDirectDraw2_EnumDisplayModes(lpDD, DDEDM_STANDARDVGAMODES, 0, 0, EnumDisplayModesCallback); osd_initialize(); osd_created = 0; return 1; }
static int DDCreateSurface(directx_priv *priv, ggi_mode *mode) { HRESULT hr; LPDIRECTDRAWCLIPPER pClipper; DDSURFACEDESC pddsd, bddsd; int i; if (!priv->fullscreen) IDirectDraw2_SetCooperativeLevel(priv->lpddext, priv->hWnd, DDSCL_NORMAL); else { /* Only the thread that has excluse access (Cooperative level) * may restore the surfaces when they are lost. Therefore * let the helper thread get exclusive access so that it can * later do restores. */ directx_fullscreen dxfull; dxfull.priv = priv; dxfull.mode = mode; dxfull.event = CreateEvent(NULL, FALSE, FALSE, NULL); PostThreadMessage(priv->nThreadID, WM_DDFULLSCREEN, 0, (long)&dxfull); WaitForSingleObject(dxfull.event, INFINITE); CloseHandle(dxfull.event); } /* create the primary surface */ memset(&pddsd, 0, sizeof(pddsd)); pddsd.dwSize = sizeof(pddsd); pddsd.dwFlags = DDSD_CAPS; pddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if (priv->fullscreen) pddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; hr = IDirectDraw2_CreateSurface(priv->lpddext, &pddsd, &priv->lppdds, NULL); if (hr != 0) { fprintf(stderr, "Init Primary Surface Failed RC = %lx. Exiting\n", hr); exit(-1); } IDirectDraw2_CreateClipper(priv->lpddext, 0, &pClipper, NULL); IDirectDrawClipper_SetHWnd(pClipper, 0, priv->hWnd); IDirectDrawSurface_SetClipper(priv->lppdds, pClipper); IDirectDrawClipper_Release(pClipper); pddsd.dwSize = sizeof(pddsd); IDirectDrawSurface_GetSurfaceDesc(priv->lppdds, &pddsd); DPRINT_MISC("DDraw pixel format:\n"); DPRINT_MISC(" Size %u\n", pddsd.ddpfPixelFormat.dwSize); DPRINT_MISC(" Flags %08x\n", pddsd.ddpfPixelFormat.dwFlags); DPRINT_MISC(" FourCC %08x\n", pddsd.ddpfPixelFormat.dwFourCC); DPRINT_MISC(" Count %u\n", pddsd.ddpfPixelFormat.dwRGBBitCount); DPRINT_MISC(" R-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwRBitMask); DPRINT_MISC(" G-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwGBitMask); DPRINT_MISC(" B-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwBBitMask); DPRINT_MISC(" Z-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwRGBZBitMask); /* create the back storages */ for (i = 0; i < mode->frames; ++i) { memset(&bddsd, 0, sizeof(bddsd)); bddsd.dwSize = sizeof(bddsd); bddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; bddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; bddsd.dwWidth = mode->virt.x; bddsd.dwHeight = mode->virt.y; /* set up the pixel format */ ZeroMemory(&bddsd.ddpfPixelFormat, sizeof(DDPIXELFORMAT)); bddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); bddsd.ddpfPixelFormat.dwFlags = pddsd.ddpfPixelFormat.dwFlags; bddsd.ddpfPixelFormat.dwFourCC = pddsd.ddpfPixelFormat.dwFourCC; bddsd.ddpfPixelFormat.dwRGBBitCount = pddsd.ddpfPixelFormat.dwRGBBitCount; bddsd.ddpfPixelFormat.dwRBitMask = pddsd.ddpfPixelFormat.dwRBitMask; bddsd.ddpfPixelFormat.dwGBitMask = pddsd.ddpfPixelFormat.dwGBitMask; bddsd.ddpfPixelFormat.dwBBitMask = pddsd.ddpfPixelFormat.dwBBitMask; bddsd.ddpfPixelFormat.dwRGBAlphaBitMask = pddsd.ddpfPixelFormat.dwRGBAlphaBitMask; hr = IDirectDraw2_CreateSurface(priv->lpddext, &bddsd, &priv->lpbdds[i], NULL); if (hr) { fprintf(stderr, "Init Backup Failed RC = %lx. Exiting\n", hr); exit(-1); } IDirectDrawSurface2_Lock(priv->lpbdds[i], NULL, &bddsd, DDLOCK_SURFACEMEMORYPTR, NULL); priv->lpSurfaceAdd[i] = (char *) bddsd.lpSurface; IDirectDrawSurface2_Unlock(priv->lpbdds[i], bddsd.lpSurface); } /* set private mode parameters */ priv->maxX = mode->virt.x; priv->maxY = mode->virt.y; priv->ColorDepth = pddsd.ddpfPixelFormat.dwRGBBitCount; priv->pitch = bddsd.lPitch; if (pddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { static PALETTEENTRY pal[256]; /* todo fill in pal */ hr = IDirectDraw_CreatePalette(priv->lpddext, DDPCAPS_8BIT|DDPCAPS_ALLOW256, pal, &priv->lpddp, NULL); if (hr) { fprintf(stderr, "Init Palette failed RC = %lx. Exiting\n", hr); exit(-1); } hr = IDirectDrawSurface_SetPalette(priv->lppdds, priv->lpddp); if (hr) { fprintf(stderr, "Install Palette failed RC = %lx. Exiting\n", hr); exit(-1); } } return 1; }
static Bool winAllocateFBShadowDD (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; HRESULT ddrval = DD_OK; DDSURFACEDESC ddsd; DDSURFACEDESC *pddsdShadow = NULL; #if CYGDEBUG winDebug ("winAllocateFBShadowDD\n"); #endif /* Create a clipper */ ddrval = (*g_fpDirectDrawCreateClipper) (0, &pScreenPriv->pddcPrimary, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not create clipper: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Created a clipper\n"); #endif /* Get a device context for the screen */ pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); /* Attach the clipper to our display window */ ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary, 0, pScreenPriv->hwndScreen); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Clipper not attached to " "window: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Attached clipper to window\n"); #endif /* Create a DirectDraw object, store the address at lpdd */ ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not start DirectDraw: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD () - Created and initialized DD\n"); #endif /* Get a DirectDraw2 interface pointer */ ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, &IID_IDirectDraw2, (LPVOID*) &pScreenPriv->pdd2); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Failed DD2 query: %08x\n", (unsigned int) ddrval); return FALSE; } /* Are we full screen? */ if (pScreenInfo->fFullScreen) { DDSURFACEDESC ddsdCurrent; DWORD dwRefreshRateCurrent = 0; HDC hdc = NULL; /* Set the cooperative level to full screen */ ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, pScreenPriv->hwndScreen, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not set " "cooperative level: %08x\n", (unsigned int) ddrval); return FALSE; } /* * We only need to get the current refresh rate for comparison * if a refresh rate has been passed on the command line. */ if (pScreenInfo->dwRefreshRate != 0) { ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent)); ddsdCurrent.dwSize = sizeof (ddsdCurrent); /* Get information about current display settings */ ddrval = IDirectDraw2_GetDisplayMode (pScreenPriv->pdd2, &ddsdCurrent); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not get current " "refresh rate: %08x. Continuing.\n", (unsigned int) ddrval); dwRefreshRateCurrent = 0; } else { /* Grab the current refresh rate */ dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate; } } /* Clean up the refresh rate */ if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) { /* * Refresh rate is non-specified or equal to current. */ pScreenInfo->dwRefreshRate = 0; } /* Grab a device context for the screen */ hdc = GetDC (NULL); if (hdc == NULL) { ErrorF ("winAllocateFBShadowDD - GetDC () failed\n"); return FALSE; } /* Only change the video mode when different than current mode */ if (!pScreenInfo->fMultipleMonitors && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN) || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN) || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL) || pScreenInfo->dwRefreshRate != 0)) { ErrorF ("winAllocateFBShadowDD - Changing video mode\n"); /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */ ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, pScreenInfo->dwRefreshRate, 0); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not set "\ "full screen display mode: %08x\n", (unsigned int) ddrval); ErrorF ("winAllocateFBShadowDD - Using default driver refresh rate\n"); ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, 0, 0); if (FAILED(ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not set default refresh rate " "full screen display mode: %08x\n", (unsigned int) ddrval); return FALSE; } } } else { ErrorF ("winAllocateFBShadowDD - Not changing video mode\n"); } /* Release our DC */ ReleaseDC (NULL, hdc); hdc = NULL; } else { /* Set the cooperative level for windowed mode */ ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, pScreenPriv->hwndScreen, DDSCL_NORMAL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not set "\ "cooperative level: %08x\n", (unsigned int) ddrval); return FALSE; } } /* Create the primary surface */ if (!winCreatePrimarySurfaceShadowDD (pScreen)) { ErrorF ("winAllocateFBShadowDD - winCreatePrimarySurfaceShadowDD " "failed\n"); return FALSE; } /* Describe the shadow surface to be created */ /* NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, * as drawing, locking, and unlocking take forever * with video memory surfaces. In addition, * video memory is a somewhat scarce resource, * so you shouldn't be allocating video memory when * you have the option of using system memory instead. */ ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; ddsd.dwHeight = pScreenInfo->dwHeight; ddsd.dwWidth = pScreenInfo->dwWidth; /* Create the shadow surface */ ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, &ddsd, &pScreenPriv->pddsShadow, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not create shadow "\ "surface: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Created shadow\n"); #endif /* Allocate a DD surface description for our screen privates */ pddsdShadow = pScreenPriv->pddsdShadow = malloc (sizeof (DDSURFACEDESC)); if (pddsdShadow == NULL) { ErrorF ("winAllocateFBShadowDD - Could not allocate surface "\ "description memory\n"); return FALSE; } ZeroMemory (pddsdShadow, sizeof (*pddsdShadow)); pddsdShadow->dwSize = sizeof (*pddsdShadow); #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Locking shadow\n"); #endif /* Lock the shadow surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, NULL, pddsdShadow, DDLOCK_WAIT, NULL); if (FAILED (ddrval) || pddsdShadow->lpSurface == NULL) { ErrorF ("winAllocateFBShadowDD - Could not lock shadow "\ "surface: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Locked shadow\n"); #endif /* We don't know how to deal with anything other than RGB */ if (!(pddsdShadow->ddpfPixelFormat.dwFlags & DDPF_RGB)) { ErrorF ("winAllocateFBShadowDD - Color format other than RGB\n"); return FALSE; } /* Grab the pitch from the surface desc */ pScreenInfo->dwStride = (pddsdShadow->u1.lPitch * 8) / pScreenInfo->dwBPP; /* Save the pointer to our surface memory */ pScreenInfo->pfb = pddsdShadow->lpSurface; /* Grab the color depth and masks from the surface description */ pScreenPriv->dwRedMask = pddsdShadow->ddpfPixelFormat.u2.dwRBitMask; pScreenPriv->dwGreenMask = pddsdShadow->ddpfPixelFormat.u3.dwGBitMask; pScreenPriv->dwBlueMask = pddsdShadow->ddpfPixelFormat.u4.dwBBitMask; #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Returning\n"); #endif return TRUE; }
static int ResizeDD(int fullscreen) { HRESULT ddrval; DDSURFACEDESC ddsd; /*DDCAPS2 ddscaps; */ LPDIRECTDRAWCLIPPER pClipper; int dxwidth; int dxheight; int dxbpp; // free DirectX objects if (lpSurfaces[0]) IDirectDrawSurface_Release(lpSurfaces[0]); lpSurfaces[0] = NULL; if (dxPalette) IDirectDrawPalette_Release(dxPalette); dxPalette = NULL; /* Set cooperative level */ ddrval = IDirectDraw2_SetCooperativeLevel(lpDD2, hWnd, fullscreen ? (DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT) : DDSCL_NORMAL); if (ddrval != DD_OK) { DeInitDD(); x_error("Failed to set cooperative level"); return 0; } if (fullscreen) { if (sscanf(dxsize, "%ix%ix%i", &dxwidth, &dxheight, &dxbpp) != 3) { dxwidth = DXWIDTH; dxheight = DXHEIGHT; dxbpp = DXBPP; } displayX = dxwidth; displayY = dxheight; bitDepth = dxbpp; if (bitDepth < 10) bitDepth = 8; if (bitDepth >= 10 && bitDepth < 20) bitDepth = 16; if (bitDepth >= 20 && bitDepth < 28) bitDepth = 24; if (bitDepth >= 32 && bitDepth < 32) bitDepth = 32; /* set resolution and bit depth */ ddrval = IDirectDraw2_SetDisplayMode(lpDD2, displayX, displayY, bitDepth, 0, 0); if (ddrval != DD_OK) { /* The display mode cannot be changed. The mode is either not supported or another application has exclusive mode. Try 320x200x256 and 640x480x256 modes before giving up */ displayX = 320; displayY = 200; bitDepth = 8; ddrval = IDirectDraw2_SetDisplayMode(lpDD2, displayX, displayY, bitDepth, 0, 0); if (ddrval != DD_OK) { displayY = 240; if (ddrval != DD_OK) { displayX = 640; displayY = 480; ddrval = IDirectDraw2_SetDisplayMode(lpDD2, displayX, displayY, bitDepth, 0, 0); if (ddrval != DD_OK) { /* Bad luck... give up. */ DeInitDD(); return 0; } } } } SetRect(&rcViewport, 0, 0, displayX, displayY); rcScreen = rcViewport; } else { /* Get the dimensions of the viewport and screen bounds */ GetClientRect(hWnd, &rcViewport); GetClientRect(hWnd, &rcScreen); ClientToScreen(hWnd, (POINT *) & rcScreen.left); ClientToScreen(hWnd, (POINT *) & rcScreen.right); /*bitDepth = GetDeviceCaps (hDC, BITSPIXEL); */ /* Create clipper object for window */ ddrval = IDirectDraw_CreateClipper(lpDD, 0, &pClipper, NULL); if (ddrval != DD_OK) { DeInitDD(); x_error("Failed to create clipper object"); return 0; } /* Asociate it */ IDirectDrawClipper_SetHWnd(pClipper, 0, hWnd); } /* Create the primary surface with one back buffer */ CalculateBITMAPINFO(); // calculate BITMAPINFO structure memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; ddrval = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurfaces[0], NULL); if (ddrval != DD_OK) { DeInitDD(); x_error("Failed to create flipping surface"); return 0; } if (!fullscreen) { IDirectDrawSurface_SetClipper(lpSurfaces[0], pClipper); IDirectDrawClipper_Release(pClipper); if (IDirectDrawSurface_GetSurfaceDesc(lpSurfaces[0], &ddsd) != DD_OK) { DeInitDD(); x_error("Failed to get pixel format"); return 0; } bitDepth = ddsd.ddpfPixelFormat.u1.dwRGBBitCount; } if (bitDepth == 8) { /* create palette */ ddrval = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT, (LPPALETTEENTRY) bmp->bmiColors, &dxPalette, NULL); if (ddrval != DD_OK) { DeInitDD(); x_error("Failed to create palette"); return 0; } /* set palette */ IDirectDrawSurface_SetPalette(lpSurfaces[0], dxPalette); } if (fullscreen) SetCursor(NULL); needredraw = 1; return 1; }
EXPORT int CALL angrylionRomOpen (void) { #ifndef HAVE_DIRECTDRAW screen_width = SCREEN_WIDTH; screen_height = SCREEN_HEIGHT; blitter_buf = (uint32_t*)calloc(screen_width * screen_height, sizeof(uint32_t)); pitchindwords = screen_width * 4; screen_pitch = PRESCALE_WIDTH << 2; #else DDPIXELFORMAT ftpixel; LPDIRECTDRAWCLIPPER lpddcl; RECT bigrect, smallrect, statusrect; POINT p; int rightdiff; int bottomdiff; GetWindowRect(gfx.hWnd,&bigrect); GetClientRect(gfx.hWnd,&smallrect); rightdiff = screen_width - smallrect.right; bottomdiff = screen_height - smallrect.bottom; if (gfx.hStatusBar) { GetClientRect(gfx.hStatusBar, &statusrect); bottomdiff += statusrect.bottom; } MoveWindow(gfx.hWnd, bigrect.left, bigrect.top, bigrect.right - bigrect.left + rightdiff, bigrect.bottom - bigrect.top + bottomdiff, true); res = DirectDrawCreateEx(0, (LPVOID*)&lpdd, &IID_IDirectDraw7, 0); if (res != DD_OK) { DisplayError("Couldn't create a DirectDraw object."); return; /* to-do: move to InitiateGFX? */ } res = IDirectDraw_SetCooperativeLevel(lpdd, gfx.hWnd, DDSCL_NORMAL); if (res != DD_OK) { DisplayError("Couldn't set a cooperative level."); return; /* to-do: move to InitiateGFX? */ } zerobuf(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; res = IDirectDraw_CreateSurface(lpdd, &ddsd, &lpddsprimary, 0); if (res != DD_OK) { DisplayError("CreateSurface for a primary surface failed."); return; /* to-do: move to InitiateGFX? */ } ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = PRESCALE_WIDTH; ddsd.dwHeight = PRESCALE_HEIGHT; zerobuf(&ftpixel, sizeof(ftpixel)); ftpixel.dwSize = sizeof(ftpixel); ftpixel.dwFlags = DDPF_RGB; ftpixel.dwRGBBitCount = 32; ftpixel.dwRBitMask = 0xff0000; ftpixel.dwGBitMask = 0xff00; ftpixel.dwBBitMask = 0xff; ddsd.ddpfPixelFormat = ftpixel; res = IDirectDraw_CreateSurface(lpdd, &ddsd, &lpddsback, 0); if (res == DDERR_INVALIDPIXELFORMAT) { DisplayError( "ARGB8888 is not supported. You can try changing desktop color "\ "depth to 32-bit, but most likely that won't help."); return; /* InitiateGFX fails. */ } else if (res != DD_OK) { DisplayError("CreateSurface for a secondary surface failed."); return; /* InitiateGFX should fail. */ } res = IDirectDrawSurface_GetSurfaceDesc(lpddsback, &ddsd); if (res != DD_OK) { DisplayError("GetSurfaceDesc failed."); return; /* InitiateGFX should fail. */ } if ((ddsd.lPitch & 3) || ddsd.lPitch < (PRESCALE_WIDTH << 2)) { DisplayError( "Pitch of a secondary surface is either not 32 bit aligned or "\ "too small."); return; /* InitiateGFX should fail. */ } pitchindwords = ddsd.lPitch >> 2; res = IDirectDraw_CreateClipper(lpdd, 0, &lpddcl, 0); if (res != DD_OK) { DisplayError("Couldn't create a clipper."); return; /* InitiateGFX should fail. */ } res = IDirectDrawClipper_SetHWnd(lpddcl, 0, gfx.hWnd); if (res != DD_OK) { DisplayError("Couldn't register a windows handle as a clipper."); return; /* InitiateGFX should fail. */ } res = IDirectDrawSurface_SetClipper(lpddsprimary, lpddcl); if (res != DD_OK) { DisplayError("Couldn't attach a clipper to a surface."); return; /* InitiateGFX should fail. */ } src.top = src.left = 0; src.bottom = 0; #if SCREEN_WIDTH < PRESCALE_WIDTH src.right = PRESCALE_WIDTH - 1; /* fix for undefined video card behavior */ #else src.right = PRESCALE_WIDTH; #endif p.x = p.y = 0; GetClientRect(gfx.hWnd, &dst); ClientToScreen(gfx.hWnd, &p); OffsetRect(&dst, p.x, p.y); GetClientRect(gfx.hStatusBar, &statusrect); dst.bottom -= statusrect.bottom; #endif rdp_init(); overlay = 0; return 1; }
static void test_clipper_blt(void) { IDirectDrawSurface7 *src_surface, *dst_surface; RECT client_rect, src_rect, *rect; IDirectDrawClipper *clipper; DDSURFACEDESC2 surface_desc; unsigned int i, j, x, y; IDirectDraw7 *ddraw; RGNDATA *rgn_data; D3DCOLOR color; HRGN r1, r2; HWND window; DDBLTFX fx; HRESULT hr; DWORD ret; static const D3DCOLOR expected1[] = { 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000, 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff, 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff, }; static const D3DCOLOR expected2[] = { 0x000000ff, 0x000000ff, 0x00000000, 0x00000000, 0x000000ff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000ff, 0x000000ff, 0x00000000, 0x00000000, 0x000000ff, 0x000000ff, }; window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 10, 10, 640, 480, 0, 0, 0, 0); ShowWindow(window, SW_SHOW); if (!(ddraw = create_ddraw())) { skip("Failed to create a ddraw object, skipping test.\n"); DestroyWindow(window); return; } ret = GetClientRect(window, &client_rect); ok(ret, "Failed to get client rect.\n"); ret = MapWindowPoints(window, NULL, (POINT *)&client_rect, 2); ok(ret, "Failed to map client rect.\n"); hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); hr = IDirectDraw7_CreateClipper(ddraw, 0, &clipper, NULL); ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr); hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret); ok(hr == DDERR_NOCLIPLIST, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawClipper_SetHWnd(clipper, 0, window); ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr); hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret); ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr); rgn_data = HeapAlloc(GetProcessHeap(), 0, ret); hr = IDirectDrawClipper_GetClipList(clipper, NULL, rgn_data, &ret); ok(SUCCEEDED(hr), "Failed to get clip list, hr %#x.\n", hr); ok(rgn_data->rdh.dwSize == sizeof(rgn_data->rdh), "Got unexpected structure size %#x.\n", rgn_data->rdh.dwSize); ok(rgn_data->rdh.iType == RDH_RECTANGLES, "Got unexpected type %#x.\n", rgn_data->rdh.iType); ok(rgn_data->rdh.nCount == 1, "Got unexpected count %u.\n", rgn_data->rdh.nCount); ok(rgn_data->rdh.nRgnSize == 16, "Got unexpected region size %u.\n", rgn_data->rdh.nRgnSize); ok(EqualRect(&rgn_data->rdh.rcBound, &client_rect), "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n", rgn_data->rdh.rcBound.left, rgn_data->rdh.rcBound.top, rgn_data->rdh.rcBound.right, rgn_data->rdh.rcBound.bottom, client_rect.left, client_rect.top, client_rect.right, client_rect.bottom); rect = (RECT *)&rgn_data->Buffer[0]; ok(EqualRect(rect, &client_rect), "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n", rect->left, rect->top, rect->right, rect->bottom, client_rect.left, client_rect.top, client_rect.right, client_rect.bottom); HeapFree(GetProcessHeap(), 0, rgn_data); r1 = CreateRectRgn(0, 0, 320, 240); ok(!!r1, "Failed to create region.\n"); r2 = CreateRectRgn(320, 240, 640, 480); ok(!!r2, "Failed to create region.\n"); CombineRgn(r1, r1, r2, RGN_OR); ret = GetRegionData(r1, 0, NULL); rgn_data = HeapAlloc(GetProcessHeap(), 0, ret); ret = GetRegionData(r1, ret, rgn_data); ok(!!ret, "Failed to get region data.\n"); DeleteObject(r2); DeleteObject(r1); hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0); ok(hr == DDERR_CLIPPERISUSINGHWND, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL); ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr); hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0); ok(SUCCEEDED(hr), "Failed to set clip list, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, rgn_data); memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; surface_desc.dwWidth = 640; surface_desc.dwHeight = 480; U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat); U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB; U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32; U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0x00ff0000; U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00; U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff; hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &src_surface, NULL); ok(SUCCEEDED(hr), "Failed to create source surface, hr %#x.\n", hr); hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &dst_surface, NULL); ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr); memset(&fx, 0, sizeof(fx)); fx.dwSize = sizeof(fx); hr = IDirectDrawSurface7_Blt(src_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); ok(SUCCEEDED(hr), "Failed to clear source surface, hr %#x.\n", hr); hr = IDirectDrawSurface7_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr); hr = IDirectDrawSurface7_Lock(src_surface, NULL, &surface_desc, 0, NULL); ok(SUCCEEDED(hr), "Failed to lock source surface, hr %#x.\n", hr); ((DWORD *)surface_desc.lpSurface)[0] = 0xff0000ff; ((DWORD *)surface_desc.lpSurface)[1] = 0xff00ff00; ((DWORD *)surface_desc.lpSurface)[2] = 0xffff0000; ((DWORD *)surface_desc.lpSurface)[3] = 0xffffffff; hr = IDirectDrawSurface7_Unlock(src_surface, NULL); ok(SUCCEEDED(hr), "Failed to unlock source surface, hr %#x.\n", hr); hr = IDirectDrawSurface7_SetClipper(dst_surface, clipper); ok(SUCCEEDED(hr), "Failed to set clipper, hr %#x.\n", hr); SetRect(&src_rect, 0, 0, 4, 1); hr = IDirectDrawSurface7_Blt(dst_surface, NULL, src_surface, &src_rect, DDBLT_WAIT, NULL); ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr); for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) { x = 80 * ((2 * j) + 1); y = 60 * ((2 * i) + 1); color = get_surface_color(dst_surface, x, y); ok(compare_color(color, expected1[i * 4 + j], 1), "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1[i * 4 + j], x, y, color); } } U5(fx).dwFillColor = 0xff0000ff; hr = IDirectDrawSurface7_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr); for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) { x = 80 * ((2 * j) + 1); y = 60 * ((2 * i) + 1); color = get_surface_color(dst_surface, x, y); ok(compare_color(color, expected2[i * 4 + j], 1), "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2[i * 4 + j], x, y, color); } } hr = IDirectDrawSurface7_BltFast(dst_surface, 0, 0, src_surface, NULL, DDBLTFAST_WAIT); ok(hr == DDERR_BLTFASTCANTCLIP, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawClipper_SetHWnd(clipper, 0, window); ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr); hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret); ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr); DestroyWindow(window); hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret); ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL); ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr); hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret); ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr); hr = IDirectDrawClipper_SetClipList(clipper, NULL, 0); ok(SUCCEEDED(hr), "Failed to set clip list, hr %#x.\n", hr); hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret); ok(hr == DDERR_NOCLIPLIST, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface7_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); ok(hr == DDERR_NOCLIPLIST, "Got unexpected hr %#x.\n", hr); IDirectDrawSurface7_Release(dst_surface); IDirectDrawSurface7_Release(src_surface); IDirectDrawClipper_Release(clipper); IDirectDraw7_Release(ddraw); }
BOOL gldCreateDrawable_DX( DGL_ctx *ctx, // BOOL bDefaultDriver, BOOL bDirectDrawPersistant, BOOL bPersistantBuffers) { // // bDirectDrawPersistant: applies to IDirect3D8 // bPersistantBuffers: applies to IDirect3DDevice8 // // D3DDEVTYPE d3dDevType; // D3DPRESENT_PARAMETERS d3dpp; // D3DDISPLAYMODE d3ddm; // DWORD dwBehaviourFlags; // D3DADAPTER_IDENTIFIER8 d3dIdent; HRESULT hr; GLD_driver_dx7 *lpCtx = NULL; D3DX_VIDMODEDESC d3ddm; // Parameters for D3DXCreateContextEx // These will be different for fullscreen and windowed DWORD dwDeviceIndex; DWORD dwFlags; HWND hwnd; HWND hwndFocus; DWORD numColorBits; DWORD numAlphaBits; DWORD numDepthBits; DWORD numStencilBits; DWORD numBackBuffers; DWORD dwWidth; DWORD dwHeight; DWORD refreshRate; // Error if context is NULL. if (ctx == NULL) return FALSE; if (ctx->glPriv) { lpCtx = ctx->glPriv; // Release any existing interfaces (in reverse order) SAFE_RELEASE(lpCtx->pDev); SAFE_RELEASE(lpCtx->pD3D); lpCtx->pD3DXContext->lpVtbl->Release(lpCtx->pD3DXContext); lpCtx->pD3DXContext = NULL; } else { lpCtx = (GLD_driver_dx7*)malloc(sizeof(GLD_driver_dx7)); ZeroMemory(lpCtx, sizeof(lpCtx)); } // d3dDevType = (glb.dwDriver == GLDS_DRIVER_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF; // Use REF device if requested. Otherwise D3DX_DEFAULT will choose highest level // of HW acceleration. dwDeviceIndex = (glb.dwDriver == GLDS_DRIVER_REF) ? D3DX_HWLEVEL_REFERENCE : D3DX_DEFAULT; // TODO: Check this // if (bDefaultDriver) // d3dDevType = D3DDEVTYPE_REF; #ifdef _GLD_PERSISTANT // Use persistant interface if needed if (bDirectDrawPersistant && dx7Globals.bDirect3D) { lpCtx->pD3D = dx7Globals.pD3D; IDirect3D7_AddRef(lpCtx->pD3D); goto SkipDirectDrawCreate; } #endif /* // Create Direct3D7 object lpCtx->pD3D = dx7Globals.fnDirect3DCreate8(D3D_SDK_VERSION_DX8_SUPPORT_WIN95); if (lpCtx->pD3D == NULL) { MessageBox(NULL, "Unable to initialize Direct3D8", "GLDirect", MB_OK); ddlogMessage(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D8 interface"); nContextError = GLDERR_D3D; goto return_with_error; } */ #ifdef _GLD_PERSISTANT // Cache Direct3D interface for subsequent GLRCs if (bDirectDrawPersistant && !dx8Globals.bDirect3D) { dx7Globals.pD3D = lpCtx->pD3D; IDirect3D7_AddRef(dx7Globals.pD3D); dx7Globals.bDirect3D = TRUE; } SkipDirectDrawCreate: #endif /* // Get the display mode so we can make a compatible backbuffer hResult = IDirect3D8_GetAdapterDisplayMode(lpCtx->pD3D, glb.dwAdapter, &d3ddm); if (FAILED(hResult)) { nContextError = GLDERR_D3D; goto return_with_error; } */ #if 0 // Get device caps hResult = IDirect3D8_GetDeviceCaps(lpCtx->pD3D, glb.dwAdapter, d3dDevType, &lpCtx->d3dCaps8); if (FAILED(hResult)) { ddlogError(DDLOG_CRITICAL_OR_WARN, "IDirect3D8_GetDeviceCaps failed", hResult); nContextError = GLDERR_D3D; goto return_with_error; } // Check for hardware transform & lighting lpCtx->bHasHWTnL = lpCtx->d3dCaps8.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ? TRUE : FALSE; // If this flag is present then we can't default to Mesa // SW rendering between BeginScene() and EndScene(). if (lpCtx->d3dCaps8.Caps2 & D3DCAPS2_NO2DDURING3DSCENE) { ddlogMessage(DDLOG_WARN, "Warning : No 2D allowed during 3D scene.\n"); } #endif // // Create the Direct3D context // #ifdef _GLD_PERSISTANT // Re-use original IDirect3DDevice if persistant buffers exist. // Note that we test for persistant IDirect3D8 as well // bDirectDrawPersistant == persistant IDirect3D8 (DirectDraw8 does not exist) if (bDirectDrawPersistant && bPersistantBuffers && dx7Globals.pD3D && dx7Globals.pDev) { lpCtx->pDev = dx7Globals.pDev; IDirect3DDevice7_AddRef(dx7Globals.pDev); goto skip_direct3ddevice_create; } #endif /* // Clear the presentation parameters (sets all members to zero) ZeroMemory(&d3dpp, sizeof(d3dpp)); // Recommended by MS; needed for MultiSample. // Be careful if altering this for FullScreenBlit d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = d3ddm.Format; d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = _gldGetDeviceMultiSampleType(lpCtx->pD3D, d3ddm.Format, d3dDevType, !ctx->bFullscreen); d3dpp.AutoDepthStencilFormat = ctx->lpPF->dwDriverData; d3dpp.EnableAutoDepthStencil = (d3dpp.AutoDepthStencilFormat == D3DFMT_UNKNOWN) ? FALSE : TRUE; if (ctx->bFullscreen) { ddlogWarnOption(FALSE); // Don't popup any messages in fullscreen d3dpp.Windowed = FALSE; d3dpp.BackBufferWidth = d3ddm.Width; d3dpp.BackBufferHeight = d3ddm.Height; d3dpp.hDeviceWindow = ctx->hWnd; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; // Support for vertical retrace synchronisation. // Set default presentation interval in case caps bits are missing d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; if (glb.bWaitForRetrace) { if (lpCtx->d3dCaps8.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; } else { if (lpCtx->d3dCaps8.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } } else { ddlogWarnOption(glb.bMessageBoxWarnings); // OK to popup messages d3dpp.Windowed = TRUE; d3dpp.BackBufferWidth = ctx->dwWidth; d3dpp.BackBufferHeight = ctx->dwHeight; d3dpp.hDeviceWindow = ctx->hWnd; d3dpp.FullScreen_RefreshRateInHz = 0; // FullScreen_PresentationInterval must be default for Windowed mode d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; } // Decide if we can use hardware TnL dwBehaviourFlags = (lpCtx->bHasHWTnL) ? D3DCREATE_MIXED_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING; // Add flag to tell D3D to be thread-safe if (glb.bMultiThreaded) dwBehaviourFlags |= D3DCREATE_MULTITHREADED; hResult = IDirect3D8_CreateDevice(lpCtx->pD3D, glb.dwAdapter, d3dDevType, ctx->hWnd, dwBehaviourFlags, &d3dpp, &lpCtx->pDev); if (FAILED(hResult)) { ddlogError(DDLOG_CRITICAL_OR_WARN, "IDirect3D8_CreateDevice failed", hResult); nContextError = GLDERR_D3D; goto return_with_error; } */ // Create D3DX context if (ctx->bFullscreen) { // // FULLSCREEN // // Get display mode D3DXGetCurrentVideoMode(D3DX_DEFAULT, &d3ddm); // Fullscreen Parameters dwFlags = D3DX_CONTEXT_FULLSCREEN; hwnd = ctx->hWnd; hwndFocus = ctx->hWnd; numColorBits = ctx->lpPF->pfd.cColorBits; numAlphaBits = ctx->lpPF->pfd.cAlphaBits; numDepthBits = ctx->lpPF->pfd.cDepthBits + ctx->lpPF->pfd.cStencilBits; numStencilBits = ctx->lpPF->pfd.cStencilBits; numBackBuffers = D3DX_DEFAULT; // Default is 1 backbuffer dwWidth = d3ddm.width; dwHeight = d3ddm.height; refreshRate = d3ddm.refreshRate; // D3DX_DEFAULT; } else { // // WINDOWED // // Windowed Parameters dwFlags = 0; // No flags means "windowed" hwnd = ctx->hWnd; hwndFocus = (HWND)D3DX_DEFAULT; numColorBits = D3DX_DEFAULT; // Use Desktop depth numAlphaBits = ctx->lpPF->pfd.cAlphaBits; numDepthBits = ctx->lpPF->pfd.cDepthBits + ctx->lpPF->pfd.cStencilBits; numStencilBits = ctx->lpPF->pfd.cStencilBits; numBackBuffers = D3DX_DEFAULT; // Default is 1 backbuffer dwWidth = ctx->dwWidth; dwHeight = ctx->dwHeight; refreshRate = D3DX_DEFAULT; } hr = D3DXCreateContextEx(dwDeviceIndex, dwFlags, hwnd, hwndFocus, numColorBits, numAlphaBits, numDepthBits, numStencilBits, numBackBuffers, dwWidth, dwHeight, refreshRate, &lpCtx->pD3DXContext); if (FAILED(hr)) { ddlogError(DDLOG_CRITICAL_OR_WARN, "D3DXCreateContextEx failed", hr); nContextError = GLDERR_D3D; goto return_with_error; } // Obtain D3D7 interfaces from ID3DXContext // lpCtx->pDD = ID3DXContext_GetDD(lpCtx->pD3DXContext); lpCtx->pDD = lpCtx->pD3DXContext->lpVtbl->GetDD(lpCtx->pD3DXContext); if (lpCtx->pDD == NULL) goto return_with_error; lpCtx->pD3D = lpCtx->pD3DXContext->lpVtbl->GetD3D(lpCtx->pD3DXContext); if (lpCtx->pD3D == NULL) goto return_with_error; lpCtx->pDev = lpCtx->pD3DXContext->lpVtbl->GetD3DDevice(lpCtx->pD3DXContext); if (lpCtx->pDev == NULL) goto return_with_error; // Need to manage clipper manually for multiple windows // since DX7 D3DX utility lib does not appear to do that. (DaveM) if (!ctx->bFullscreen) { // Get primary surface too lpDDSPrimary = lpCtx->pD3DXContext->lpVtbl->GetPrimary(lpCtx->pD3DXContext); if (lpDDSPrimary == NULL) { ddlogPrintf(DDLOG_WARN, "GetPrimary"); goto return_with_error; } // Create clipper for correct window updates if (IDirectDraw7_CreateClipper(lpCtx->pDD, 0, &lpDDClipper, NULL) != DD_OK) { ddlogPrintf(DDLOG_WARN, "CreateClipper"); goto return_with_error; } // Set the window that the clipper belongs to if (IDirectDrawClipper_SetHWnd(lpDDClipper, 0, hwnd) != DD_OK) { ddlogPrintf(DDLOG_WARN, "SetHWnd"); goto return_with_error; } // Attach the clipper to the primary surface if (IDirectDrawSurface7_SetClipper(lpDDSPrimary, lpDDClipper) != DD_OK) { ddlogPrintf(DDLOG_WARN, "SetClipper"); goto return_with_error; } } // Get device caps IDirect3DDevice7_GetCaps(lpCtx->pDev, &lpCtx->d3dCaps); // Determine HW TnL lpCtx->bHasHWTnL = lpCtx->d3dCaps.dwDevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ? TRUE : FALSE; #ifdef _GLD_PERSISTANT if (bDirectDrawPersistant && bPersistantBuffers && dx7Globals.pD3D) { dx7Globals.pDev = lpCtx->pDev; dx7Globals.bDirect3DDevice = TRUE; } #endif #if 0 // Dump some useful stats hResult = IDirect3D8_GetAdapterIdentifier( lpCtx->pD3D, glb.dwAdapter, D3DENUM_NO_WHQL_LEVEL, // Avoids 1 to 2 second delay &d3dIdent); if (SUCCEEDED(hResult)) { ddlogPrintf(DDLOG_INFO, "[Driver Description: %s]", &d3dIdent.Description); ddlogPrintf(DDLOG_INFO, "[Driver file: %s %d.%d.%02d.%d]", d3dIdent.Driver, HIWORD(d3dIdent.DriverVersion.HighPart), LOWORD(d3dIdent.DriverVersion.HighPart), HIWORD(d3dIdent.DriverVersion.LowPart), LOWORD(d3dIdent.DriverVersion.LowPart)); ddlogPrintf(DDLOG_INFO, "[VendorId: 0x%X, DeviceId: 0x%X, SubSysId: 0x%X, Revision: 0x%X]", d3dIdent.VendorId, d3dIdent.DeviceId, d3dIdent.SubSysId, d3dIdent.Revision); } #endif // Init projection matrix for D3D TnL D3DXMatrixIdentity((D3DXMATRIX*)&lpCtx->matProjection); lpCtx->matModelView = lpCtx->matProjection; // gld->bUseMesaProjection = TRUE; skip_direct3ddevice_create: // Create buffers to hold primitives lpCtx->PB2d.dwFVF = GLD_FVF_2D_VERTEX; // lpCtx->PB2d.dwPool = D3DPOOL_SYSTEMMEM; lpCtx->PB2d.dwStride = sizeof(GLD_2D_VERTEX); lpCtx->PB2d.dwCreateFlags = D3DVBCAPS_DONOTCLIP | D3DVBCAPS_SYSTEMMEMORY | D3DVBCAPS_WRITEONLY; hr = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PB2d); if (FAILED(hr)) goto return_with_error; lpCtx->PB3d.dwFVF = GLD_FVF_3D_VERTEX; // lpCtx->PB3d.dwPool = D3DPOOL_DEFAULT; lpCtx->PB3d.dwStride = sizeof(GLD_3D_VERTEX); lpCtx->PB3d.dwCreateFlags = D3DVBCAPS_WRITEONLY; hr = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PB3d); if (FAILED(hr)) goto return_with_error; // Zero the pipeline usage counters lpCtx->PipelineUsage.qwMesa.QuadPart = // lpCtx->PipelineUsage.dwD3D2SVS.QuadPart = lpCtx->PipelineUsage.qwD3DFVF.QuadPart = 0; // Assign drawable to GL private ctx->glPriv = lpCtx; return TRUE; return_with_error: // Clean up and bail _gldDestroyPrimitiveBuffer(&lpCtx->PB3d); _gldDestroyPrimitiveBuffer(&lpCtx->PB2d); SAFE_RELEASE(lpCtx->pDev); SAFE_RELEASE(lpCtx->pD3D); //SAFE_RELEASE(lpCtx->pD3DXContext); lpCtx->pD3DXContext->lpVtbl->Release(lpCtx->pD3DXContext); return FALSE; }
Bool winAllocateFBShadowDDNL (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; HRESULT ddrval = DD_OK; DDSURFACEDESC2 ddsdShadow; char *lpSurface = NULL; DDPIXELFORMAT ddpfPrimary; #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - w %d h %d d %d\n", pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwDepth); #endif /* Set the padded screen width */ pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth, pScreenInfo->dwBPP); /* Allocate memory for our shadow surface */ lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); if (lpSurface == NULL) { ErrorF ("winAllocateFBShadowDDNL - Could not allocate bits\n"); return FALSE; } /* * Initialize the framebuffer memory so we don't get a * strange display at startup */ ZeroMemory (lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); /* Create a clipper */ ddrval = (*g_fpDirectDrawCreateClipper) (0, &pScreenPriv->pddcPrimary, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not attach clipper: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Created a clipper\n"); #endif /* Attach the clipper to our display window */ ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary, 0, pScreenPriv->hwndScreen); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Clipper not attached " "to window: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Attached clipper to window\n"); #endif /* Create a DirectDraw object, store the address at lpdd */ ddrval = (*g_fpDirectDrawCreate) (NULL, (LPDIRECTDRAW*) &pScreenPriv->pdd, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not start " "DirectDraw: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Created and initialized DD\n"); #endif /* Get a DirectDraw4 interface pointer */ ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, &IID_IDirectDraw4, (LPVOID*) &pScreenPriv->pdd4); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Failed DD4 query: %08x\n", (unsigned int) ddrval); return FALSE; } /* Are we full screen? */ if (pScreenInfo->fFullScreen) { DDSURFACEDESC2 ddsdCurrent; DWORD dwRefreshRateCurrent = 0; HDC hdc = NULL; /* Set the cooperative level to full screen */ ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4, pScreenPriv->hwndScreen, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not set " "cooperative level: %08x\n", (unsigned int) ddrval); return FALSE; } /* * We only need to get the current refresh rate for comparison * if a refresh rate has been passed on the command line. */ if (pScreenInfo->dwRefreshRate != 0) { ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent)); ddsdCurrent.dwSize = sizeof (ddsdCurrent); /* Get information about current display settings */ ddrval = IDirectDraw4_GetDisplayMode (pScreenPriv->pdd4, &ddsdCurrent); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not get current " "refresh rate: %08x. Continuing.\n", (unsigned int) ddrval); dwRefreshRateCurrent = 0; } else { /* Grab the current refresh rate */ dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate; } } /* Clean up the refresh rate */ if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) { /* * Refresh rate is non-specified or equal to current. */ pScreenInfo->dwRefreshRate = 0; } /* Grab a device context for the screen */ hdc = GetDC (NULL); if (hdc == NULL) { ErrorF ("winAllocateFBShadowDDNL - GetDC () failed\n"); return FALSE; } /* Only change the video mode when different than current mode */ if (!pScreenInfo->fMultipleMonitors && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN) || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN) || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL) || pScreenInfo->dwRefreshRate != 0)) { winDebug ("winAllocateFBShadowDDNL - Changing video mode\n"); /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */ ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, pScreenInfo->dwRefreshRate, 0); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not set " "full screen display mode: %08x\n", (unsigned int) ddrval); ErrorF ("winAllocateFBShadowDDNL - Using default driver refresh rate\n"); ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, 0, 0); if (FAILED(ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not set default refresh rate " "full screen display mode: %08x\n", (unsigned int) ddrval); return FALSE; } } } else { winDebug ("winAllocateFBShadowDDNL - Not changing video mode\n"); } /* Release our DC */ ReleaseDC (NULL, hdc); hdc = NULL; } else { /* Set the cooperative level for windowed mode */ ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4, pScreenPriv->hwndScreen, DDSCL_NORMAL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not set " "cooperative level: %08x\n", (unsigned int) ddrval); return FALSE; } } /* Create the primary surface */ if (!winCreatePrimarySurfaceShadowDDNL (pScreen)) { ErrorF ("winAllocateFBShadowDDNL - winCreatePrimarySurfaceShadowDDNL " "failed\n"); return FALSE; } /* Get primary surface's pixel format */ ZeroMemory (&ddpfPrimary, sizeof (ddpfPrimary)); ddpfPrimary.dwSize = sizeof (ddpfPrimary); ddrval = IDirectDrawSurface4_GetPixelFormat (pScreenPriv->pddsPrimary4, &ddpfPrimary); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not get primary " "pixformat: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Primary masks: %08x %08x %08x " "dwRGBBitCount: %d\n", ddpfPrimary.u2.dwRBitMask, ddpfPrimary.u3.dwGBitMask, ddpfPrimary.u4.dwBBitMask, ddpfPrimary.u1.dwRGBBitCount); #endif /* Describe the shadow surface to be created */ /* * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, * as drawing, locking, and unlocking take forever * with video memory surfaces. In addition, * video memory is a somewhat scarce resource, * so you shouldn't be allocating video memory when * you have the option of using system memory instead. */ ZeroMemory (&ddsdShadow, sizeof (ddsdShadow)); ddsdShadow.dwSize = sizeof (ddsdShadow); ddsdShadow.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT; ddsdShadow.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; ddsdShadow.dwHeight = pScreenInfo->dwHeight; ddsdShadow.dwWidth = pScreenInfo->dwWidth; ddsdShadow.u1.lPitch = pScreenInfo->dwPaddedWidth; ddsdShadow.lpSurface = lpSurface; ddsdShadow.u4.ddpfPixelFormat = ddpfPrimary; winDebug ("winAllocateFBShadowDDNL - lPitch: %d\n", (int) pScreenInfo->dwPaddedWidth); /* Create the shadow surface */ ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4, &ddsdShadow, &pScreenPriv->pddsShadow4, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not create shadow " "surface: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG || YES winDebug ("winAllocateFBShadowDDNL - Created shadow pitch: %d\n", (int) ddsdShadow.u1.lPitch); #endif /* Grab the pitch from the surface desc */ pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8) / pScreenInfo->dwBPP; #if CYGDEBUG || YES winDebug ("winAllocateFBShadowDDNL - Created shadow stride: %d\n", (int) pScreenInfo->dwStride); #endif /* Save the pointer to our surface memory */ pScreenInfo->pfb = lpSurface; /* Grab the masks from the surface description */ pScreenPriv->dwRedMask = ddsdShadow.u4.ddpfPixelFormat.u2.dwRBitMask; pScreenPriv->dwGreenMask = ddsdShadow.u4.ddpfPixelFormat.u3.dwGBitMask; pScreenPriv->dwBlueMask = ddsdShadow.u4.ddpfPixelFormat.u4.dwBBitMask; #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Returning\n"); #endif return TRUE; }
// 创建 DirectDraw屏幕 // 如果 bpp为0的话则创建窗口模式,w,h失效,否则全屏幕 CSURFACE *DDrawCreateScreen(HWND hWnd, int w, int h, int bpp, HRESULT *HR) { DDSURFACEDESC2 ddsd; CSURFACE *surface; HRESULT hr; if (lpDirectDraw7 == NULL) { if (DDrawInit() != 0) return NULL; } memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); // 创建窗口模式 if (bpp == 0) { hr = IDirectDraw7_SetCooperativeLevel(lpDirectDraw7, hWnd, DDSCL_NORMAL); if (hr != DD_OK) { fprintf(stderr, "DirectDraw: SetCooperativeLevel failed\n"); fflush(stderr); if (HR) *HR = hr; return NULL; } ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; surface = DDrawCreateFromDesc(&ddsd, &hr); if (surface == NULL) { fprintf(stderr, "DirectDraw: Create Primary Surface failed\n"); fflush(stderr); if (HR) *HR = hr; return NULL; } hr = IDirectDraw7_CreateClipper(lpDirectDraw7, 0, &surface->clip, 0); if (hr != DD_OK) { fprintf(stderr, "DirectDraw: Create Clipper failed\n"); fflush(stderr); if (HR) *HR = hr; surface->clip = NULL; DDrawSurfaceRelease(surface); return NULL; } hr = IDirectDrawClipper_SetHWnd(surface->clip, 0, hWnd); if (hr != DD_OK) { fprintf(stderr, "DirectDraw: SetHWnd failed\n"); fflush(stderr); if (HR) *HR = hr; DDrawSurfaceRelease(surface); return NULL; } hr = IDirectDrawSurface7_SetClipper(surface->lpDDS, surface->clip); if (hr != DD_OK) { fprintf(stderr, "DirectDraw: SetClipper failed\n"); fflush(stderr); if (HR) *HR = hr; DDrawSurfaceRelease(surface); return NULL; } } else { // 创建全屏模式 DWORD dwFlags; if (hFullScreenMode) { fprintf(stderr, "DirectDraw: Already in Full Screen Mode\n"); fflush(stderr); return NULL; } dwFlags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT | DDSCL_ALLOWMODEX; hr = IDirectDraw7_SetCooperativeLevel(lpDirectDraw7, hWnd, dwFlags); if (hr != DD_OK) { fprintf(stderr, "DirectDraw: SetCooperativeLevel failed\n"); fflush(stderr); if (HR) *HR = hr; return NULL; } hr = IDirectDraw7_SetDisplayMode(lpDirectDraw7, w, h, bpp, 0, DDSDM_STANDARDVGAMODE); if (hr != DD_OK) { fprintf(stderr, "DirectDraw: SetDisplayMode failed\n"); fflush(stderr); if (HR) *HR = hr; return NULL; } ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; surface = DDrawCreateFromDesc(&ddsd, &hr); if (surface == NULL) { fprintf(stderr, "DirectDraw: Create Primary Surface failed\n"); fflush(stderr); IDirectDraw7_RestoreDisplayMode(lpDirectDraw7); if (HR) *HR = hr; return NULL; } hFullScreenMode = 1; } IDirectDraw7_GetDisplayMode(lpDirectDraw7, &ddsd); surface->primary = 1; surface->hWnd = hWnd; return surface; }
static int _directdraw_init (HWND window, LPDIRECTDRAW *object, LPDIRECTDRAWSURFACE *surface_primary, LPDIRECTDRAWSURFACE *surface_back, int *depth, int width, int height) { DDSURFACEDESC2 surface_desc; DDPIXELFORMAT pixel_format; LPDIRECTDRAWCLIPPER clipper; LPDIRECTDRAW o; DDSURFACEDESC2 *sd; HRESULT res; res = DirectDrawCreateEx (NULL, (void **)&o, &IID_IDirectDraw7, NULL); if (FAILED(res)) return 0; res = IDirectDraw7_SetCooperativeLevel (o, window, DDSCL_NORMAL); if (FAILED(res)) { IDirectDraw7_Release (o); return 0; } res = IDirectDraw7_CreateClipper (o, 0, &clipper, NULL); if (FAILED(res)) { IDirectDraw7_Release (o); return 0; } res = IDirectDrawClipper_SetHWnd (clipper, 0, window); if (FAILED(res)) { IDirectDrawClipper_Release (clipper); IDirectDraw7_Release (o); return 0; } memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS; surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; sd=&surface_desc; res = IDirectDraw7_CreateSurface (o, &surface_desc, surface_primary, NULL); if (FAILED(res)) { IDirectDrawClipper_Release (clipper); IDirectDraw7_Release (o); return 0; } res = IDirectDrawSurface7_SetClipper (*surface_primary, clipper); if (FAILED(res)) { IDirectDrawClipper_Release (clipper); IDirectDrawSurface7_Release (*surface_primary); IDirectDraw7_Release (o); return 0; } memset (&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; surface_desc.dwWidth = width; surface_desc.dwHeight = height; sd=&surface_desc; res = IDirectDraw7_CreateSurface (o, (DDSURFACEDESC *)sd, surface_back, NULL); if (FAILED(res)) { IDirectDrawClipper_Release (clipper); IDirectDrawSurface7_Release (*surface_primary); IDirectDraw7_Release (o); return 0; } ZeroMemory(&pixel_format, sizeof(pixel_format)); pixel_format.dwSize = sizeof(pixel_format); IDirectDrawSurface7_GetPixelFormat(*surface_primary, &pixel_format); *object = o; *depth = pixel_format.dwRGBBitCount; return 1; }
EXPORT void CALL RomOpen (void) { RECT bigrect, smallrect, statusrect; GetWindowRect(gfx.hWnd,&bigrect); GetClientRect(gfx.hWnd,&smallrect); int rightdiff = screen_width - smallrect.right; int bottomdiff = screen_height - smallrect.bottom; if (gfx.hStatusBar) { GetClientRect(gfx.hStatusBar, &statusrect); bottomdiff += statusrect.bottom; } MoveWindow(gfx.hWnd, bigrect.left, bigrect.top, bigrect.right - bigrect.left + rightdiff, bigrect.bottom - bigrect.top + bottomdiff, TRUE); DDPIXELFORMAT ftpixel; LPDIRECTDRAWCLIPPER lpddcl; res = DirectDrawCreateEx(0, (LPVOID*)&lpdd, IID_IDirectDraw7, 0); if(res != DD_OK) fatalerror("Couldn't create a DirectDraw object"); res = IDirectDraw_SetCooperativeLevel(lpdd, gfx.hWnd, DDSCL_NORMAL); if(res != DD_OK) fatalerror("Couldn't set a cooperative level. Error code %x", res); memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; res = IDirectDraw_CreateSurface(lpdd, &ddsd, &lpddsprimary, 0); if(res != DD_OK) fatalerror("CreateSurface for a primary surface failed. Error code %x", res); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = PRESCALE_WIDTH; ddsd.dwHeight = PRESCALE_HEIGHT; memset(&ftpixel, 0, sizeof(ftpixel)); ftpixel.dwSize = sizeof(ftpixel); ftpixel.dwFlags = DDPF_RGB; ftpixel.dwRGBBitCount = 32; ftpixel.dwRBitMask = 0xff0000; ftpixel.dwGBitMask = 0xff00; ftpixel.dwBBitMask = 0xff; ddsd.ddpfPixelFormat = ftpixel; res = IDirectDraw_CreateSurface(lpdd, &ddsd, &lpddsback, 0); if (res == DDERR_INVALIDPIXELFORMAT) fatalerror("ARGB8888 is not supported. You can try changing desktop color depth to 32-bit, but most likely that won't help."); else if(res != DD_OK) fatalerror("CreateSurface for a secondary surface failed. Error code %x", res); res = IDirectDrawSurface_GetSurfaceDesc(lpddsback, &ddsd); if (res != DD_OK) fatalerror("GetSurfaceDesc failed."); if ((ddsd.lPitch & 3) || ddsd.lPitch < (PRESCALE_WIDTH << 2)) fatalerror("Pitch of a secondary surface is either not 32 bit aligned or two small."); pitchindwords = ddsd.lPitch >> 2; res = IDirectDraw_CreateClipper(lpdd, 0, &lpddcl, 0); if (res != DD_OK) fatalerror("Couldn't create a clipper."); res = IDirectDrawClipper_SetHWnd(lpddcl, 0, gfx.hWnd); if (res != DD_OK) fatalerror("Couldn't register a windows handle as a clipper."); res = IDirectDrawSurface_SetClipper(lpddsprimary, lpddcl); if (res != DD_OK) fatalerror("Couldn't attach a clipper to a surface."); src.top = src.left = 0; src.bottom = 0; src.right = PRESCALE_WIDTH; POINT p; p.x = p.y = 0; GetClientRect(gfx.hWnd, &dst); ClientToScreen(gfx.hWnd, &p); OffsetRect(&dst, p.x, p.y); GetClientRect(gfx.hStatusBar, &statusrect); dst.bottom -= statusrect.bottom; rdp_init(); }
static boolean CreatePrimary( win32_driver_t * win32_driver ) { LPDIRECTDRAW ddobj; DDSURFACEDESC ddsd; HRESULT result; /* create direct draw object */ result = DirectDrawCreate( 0, &ddobj, 0 ); if( result != DD_OK ) { Error( 0, "DirectDrawCreate : error %ld", result ); xprintf(win32_driver->xine, XINE_VERBOSITY_DEBUG, "vo_out_directx : DirectDrawCreate : error %ld\n", result ); return 0; } /* set cooperative level */ result = IDirectDraw_SetCooperativeLevel( ddobj, win32_driver->win32_visual->WndHnd, DDSCL_NORMAL ); if( result != DD_OK ) { Error( 0, "SetCooperativeLevel : error 0x%lx", result ); return 0; } /* try to get new interface */ result = IDirectDraw_QueryInterface( ddobj, &IID_IDirectDraw, (LPVOID *) &win32_driver->ddobj ); if( result != DD_OK ) { Error( 0, "ddobj->QueryInterface : DirectX required" ); return 0; } /* release our old interface */ IDirectDraw_Release( ddobj ); /* create primary_surface */ memset( &ddsd, 0, sizeof( ddsd ) ); ddsd.dwSize = sizeof( ddsd ); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; result = IDirectDraw_CreateSurface( win32_driver->ddobj, &ddsd, &win32_driver->primary, 0 ); if( result != DD_OK ) { Error( 0, "CreateSurface ( primary ) : error 0x%lx", result ); return 0; } /* create our clipper object */ result = IDirectDraw_CreateClipper( win32_driver->ddobj, 0, &win32_driver->ddclipper, 0 ); if( result != DD_OK ) { Error( 0, "CreateClipper : error 0x%lx", result ); return 0; } /* associate our clipper with our window */ result = IDirectDrawClipper_SetHWnd( win32_driver->ddclipper, 0, win32_driver->win32_visual->WndHnd ); if( result != DD_OK ) { Error( 0, "ddclipper->SetHWnd : error 0x%lx", result ); return 0; } /* associate our primary surface with our clipper */ result = IDirectDrawSurface_SetClipper( win32_driver->primary, win32_driver->ddclipper ); if( result != DD_OK ) { Error( 0, "ddclipper->SetHWnd : error 0x%lx", result ); return 0; } /* store our objects in our visual struct */ UpdateRect( win32_driver->win32_visual ); return 1; }