static int DxGetCaps(void) { DDCAPS capsDrv; ZeroMemory(&capsDrv, sizeof(capsDrv)); capsDrv.dwSize = sizeof(capsDrv); if (IDirectDraw_GetCaps(g_lpdd, &capsDrv, NULL) != DD_OK) { return FALSE; } if (capsDrv.dwCaps & DDCAPS_OVERLAYSTRETCH) { g_StretchFactor1000 = capsDrv.dwMinOverlayStretch > 1000 ? capsDrv.dwMinOverlayStretch : 1000; } else { g_StretchFactor1000 = 1000; } av_log(NULL, AV_LOG_INFO, "StretchFactor1000: %u\n", g_StretchFactor1000); g_align_src = (capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC) ? capsDrv.dwAlignSizeSrc : 0; g_align_dst = (capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST) ? capsDrv.dwAlignSizeDest : 0; g_boundary_src = (capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYSRC) ? capsDrv.dwAlignBoundarySrc : 0; g_boundary_dst = (capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYDEST) ? capsDrv.dwAlignBoundaryDest : 0; av_log(NULL, AV_LOG_INFO, "align_src: %u, align_dst: %u, bd_src: %u, db_dst: %u\n", g_align_src, g_align_dst, g_boundary_src, g_boundary_dst); g_allow_shrink_x = capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKX; g_allow_shrink_y = capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKY; g_allow_zoom_x = capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHX; g_allow_zoom_y = capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHY; g_overlay_key = capsDrv.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY; 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; }
BOOL DDCreateScreen(int flags) { DDSCAPS ddscaps; DDCAPS ddcaps, ddcaps2; DDSURFACEDESC ddsd; HRESULT ddresult; memset(&ddcaps, 0, sizeof(ddcaps)); memset(&ddcaps2, 0, sizeof(ddcaps2)); ddcaps.dwSize = sizeof(ddcaps); ddcaps2.dwSize = sizeof(ddcaps); ddresult = IDirectDraw_GetCaps(_lpDD, &ddcaps, &ddcaps2); if (!CheckDDResult(ddresult, "DDCreateScreen::GetCaps")) return FALSE; logentry("DirectDraw HW Caps: %x\nDirectDraw HEL Caps: %x\n",ddcaps.dwCaps,ddcaps2.dwCaps); 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; } // Determine GFX caps. if (ddcaps.dwCaps & DDCAPS_COLORKEYHWASSIST) ddDriverCaps.hwcolorkey = 1; else ddDriverCaps.hwcolorkey = 0; if (ddcaps.dwCaps & DDCAPS_BLTSTRETCH) ddDriverCaps.hwbltstretch = 1; else ddDriverCaps.hwbltstretch = 0; memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); if (_DDFullScreen && GRMODEINFO(paged)) { // We should use page flipping ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount = 1; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddresult = IDirectDraw_CreateSurface(_lpDD, &ddsd, &_lpDDSPrimary, NULL); if (!CheckDDResult(ddresult, "DDCreateScreen::CreateSurface -fullscreen")) return FALSE; ddscaps.dwCaps = DDSCAPS_BACKBUFFER; ddresult = IDirectDrawSurface_GetAttachedSurface(_lpDDSPrimary, &ddscaps, &_lpDDSBack); if (!CheckDDResult(ddresult, "DDCreateScreen::GetAttachedSurface")) return FALSE; } else { // We just create a primary and offscreen buffer if (GRMODEINFO(emul) && !_lpDDSPrimary) { // make sure we don't reinitialize the screen if we already made it // beforehand for windowed version ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; ddresult = IDirectDraw_CreateSurface(_lpDD, &ddsd, &_lpDDSPrimary, NULL); if (!CheckDDResult(ddresult, "DDCreateScreen::CreateSurface -windowed")) return FALSE; } else if (!GRMODEINFO(emul)) { // If we aren't emulating ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; ddresult = IDirectDraw_CreateSurface(_lpDD, &ddsd, &_lpDDSPrimary, NULL); if (!CheckDDResult(ddresult, "DDCreateScreen::CreateSurface -windowed")) return FALSE; } if (GRMODEINFO(emul)) { _lpDDSBack = DDCreateSurface(_DDModeList[W95DisplayMode].rw, _DDModeList[W95DisplayMode].rh, 1); if (!_lpDDSBack) { mprintf((0,"Call to create DDSBackBuffer failed.")); return FALSE; } } else _lpDDSBack = NULL; } // Create 8-bit palette { ubyte pal[768]; memset(pal, 0, 768); memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); IDirectDrawSurface_GetSurfaceDesc(_lpDDSPrimary, &ddsd); logentry("Primary surface pixel format: %x, %d\n", ddsd.ddpfPixelFormat.dwFlags, ddsd.ddpfPixelFormat.dwRGBBitCount); _lpDDPalette = DDCreatePalette(pal); Assert(_lpDDPalette != NULL); DDSetPalette(_lpDDPalette); } return TRUE; }