📄 sdl_dx5video.c
字号:
static int DX5_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key);static int DX5_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha);static int DX5_LockHWSurface(_THIS, SDL_Surface *surface);static void DX5_UnlockHWSurface(_THIS, SDL_Surface *surface);static int DX5_FlipHWSurface(_THIS, SDL_Surface *surface);static void DX5_FreeHWSurface(_THIS, SDL_Surface *surface);static int DX5_AllocDDSurface(_THIS, SDL_Surface *surface, LPDIRECTDRAWSURFACE3 requested, Uint32 flag);/* Windows message handling functions */static void DX5_RealizePalette(_THIS);static void DX5_PaletteChanged(_THIS, HWND window);static void DX5_WinPAINT(_THIS, HDC hdc);/* WinDIB driver functions for manipulating gamma ramps */extern int DIB_SetGammaRamp(_THIS, Uint16 *ramp);extern int DIB_GetGammaRamp(_THIS, Uint16 *ramp);extern void DIB_QuitGamma(_THIS);/* DX5 driver bootstrap functions */static int DX5_Available(void){ HINSTANCE DInputDLL; HINSTANCE DDrawDLL; int dinput_ok; int ddraw_ok; /* Version check DINPUT.DLL and DDRAW.DLL (Is DirectX okay?) */ dinput_ok = 0; DInputDLL = LoadLibrary(TEXT("DINPUT.DLL")); if ( DInputDLL != NULL ) { dinput_ok = 1; FreeLibrary(DInputDLL); } ddraw_ok = 0; DDrawDLL = LoadLibrary(TEXT("DDRAW.DLL")); if ( DDrawDLL != NULL ) { HRESULT (WINAPI *DDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *); LPDIRECTDRAW DDraw; /* Try to create a valid DirectDraw object */ DDrawCreate = (void *)GetProcAddress(DDrawDLL, TEXT("DirectDrawCreate")); if ( (DDrawCreate != NULL) && !FAILED(DDrawCreate(NULL, &DDraw, NULL)) ) { if ( !FAILED(IDirectDraw_SetCooperativeLevel(DDraw, NULL, DDSCL_NORMAL)) ) { DDSURFACEDESC desc; LPDIRECTDRAWSURFACE DDrawSurf; LPDIRECTDRAWSURFACE3 DDrawSurf3; /* Try to create a DirectDrawSurface3 object */ SDL_memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); desc.dwFlags = DDSD_CAPS; desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_VIDEOMEMORY; if ( !FAILED(IDirectDraw_CreateSurface(DDraw, &desc, &DDrawSurf, NULL)) ) { if ( !FAILED(IDirectDrawSurface_QueryInterface(DDrawSurf, &IID_IDirectDrawSurface3, (LPVOID *)&DDrawSurf3)) ) { /* Yay! */ ddraw_ok = 1; /* Clean up.. */ IDirectDrawSurface3_Release(DDrawSurf3); } IDirectDrawSurface_Release(DDrawSurf); } } IDirectDraw_Release(DDraw); } FreeLibrary(DDrawDLL); } return(dinput_ok && ddraw_ok);}/* Functions for loading the DirectX functions dynamically */static HINSTANCE DDrawDLL = NULL;static HINSTANCE DInputDLL = NULL;static void DX5_Unload(void){ if ( DDrawDLL != NULL ) { FreeLibrary(DDrawDLL); DDrawCreate = NULL; DDrawDLL = NULL; } if ( DInputDLL != NULL ) { FreeLibrary(DInputDLL); DInputCreate = NULL; DInputDLL = NULL; }}static int DX5_Load(void){ int status; DX5_Unload(); DDrawDLL = LoadLibrary(TEXT("DDRAW.DLL")); if ( DDrawDLL != NULL ) { DDrawCreate = (void *)GetProcAddress(DDrawDLL, TEXT("DirectDrawCreate")); } DInputDLL = LoadLibrary(TEXT("DINPUT.DLL")); if ( DInputDLL != NULL ) { DInputCreate = (void *)GetProcAddress(DInputDLL, TEXT("DirectInputCreateA")); } if ( DDrawDLL && DDrawCreate && DInputDLL && DInputCreate ) { status = 0; } else { DX5_Unload(); status = -1; } return status;}static void DX5_DeleteDevice(SDL_VideoDevice *this){ /* Free DirectDraw object */ if ( ddraw2 != NULL ) { IDirectDraw2_Release(ddraw2); } DX5_Unload(); if ( this ) { if ( this->hidden ) { SDL_free(this->hidden); } if ( this->gl_data ) { SDL_free(this->gl_data); } SDL_free(this); }}static SDL_VideoDevice *DX5_CreateDevice(int devindex){ SDL_VideoDevice *device; /* Load DirectX */ if ( DX5_Load() < 0 ) { return(NULL); } /* Initialize all variables that we clean on shutdown */ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); if ( device ) { SDL_memset(device, 0, (sizeof *device)); device->hidden = (struct SDL_PrivateVideoData *) SDL_malloc((sizeof *device->hidden)); device->gl_data = (struct SDL_PrivateGLData *) SDL_malloc((sizeof *device->gl_data)); } if ( (device == NULL) || (device->hidden == NULL) || (device->gl_data == NULL) ) { SDL_OutOfMemory(); DX5_DeleteDevice(device); return(NULL); } SDL_memset(device->hidden, 0, (sizeof *device->hidden)); SDL_memset(device->gl_data, 0, (sizeof *device->gl_data)); /* Set the function pointers */ device->VideoInit = DX5_VideoInit; device->ListModes = DX5_ListModes; device->SetVideoMode = DX5_SetVideoMode; device->UpdateMouse = WIN_UpdateMouse; device->CreateYUVOverlay = DX5_CreateYUVOverlay; device->SetColors = DX5_SetColors; device->UpdateRects = NULL; device->VideoQuit = DX5_VideoQuit; device->AllocHWSurface = DX5_AllocHWSurface; device->CheckHWBlit = DX5_CheckHWBlit; device->FillHWRect = DX5_FillHWRect; device->SetHWColorKey = DX5_SetHWColorKey; device->SetHWAlpha = DX5_SetHWAlpha; device->LockHWSurface = DX5_LockHWSurface; device->UnlockHWSurface = DX5_UnlockHWSurface; device->FlipHWSurface = DX5_FlipHWSurface; device->FreeHWSurface = DX5_FreeHWSurface; device->SetGammaRamp = DX5_SetGammaRamp; device->GetGammaRamp = DX5_GetGammaRamp;#if SDL_VIDEO_OPENGL device->GL_LoadLibrary = WIN_GL_LoadLibrary; device->GL_GetProcAddress = WIN_GL_GetProcAddress; device->GL_GetAttribute = WIN_GL_GetAttribute; device->GL_MakeCurrent = WIN_GL_MakeCurrent; device->GL_SwapBuffers = WIN_GL_SwapBuffers;#endif device->SetCaption = WIN_SetWMCaption; device->SetIcon = WIN_SetWMIcon; device->IconifyWindow = WIN_IconifyWindow; device->GrabInput = WIN_GrabInput; device->GetWMInfo = WIN_GetWMInfo; device->FreeWMCursor = WIN_FreeWMCursor; device->CreateWMCursor = WIN_CreateWMCursor; device->ShowWMCursor = WIN_ShowWMCursor; device->WarpWMCursor = WIN_WarpWMCursor; device->CheckMouseMode = WIN_CheckMouseMode; device->InitOSKeymap = DX5_InitOSKeymap; device->PumpEvents = DX5_PumpEvents; /* Set up the windows message handling functions */ WIN_RealizePalette = DX5_RealizePalette; WIN_PaletteChanged = DX5_PaletteChanged; WIN_WinPAINT = DX5_WinPAINT; HandleMessage = DX5_HandleMessage; device->free = DX5_DeleteDevice; /* We're finally ready */ return device;}VideoBootStrap DIRECTX_bootstrap = { "directx", "Win95/98/2000 DirectX", DX5_Available, DX5_CreateDevice};static int cmpmodes(const void *va, const void *vb){ SDL_Rect *a = *(SDL_Rect **)va; SDL_Rect *b = *(SDL_Rect **)vb; if ( a->w == b->w ) return b->h - a->h; else return b->w - a->w;}static HRESULT WINAPI EnumModes2(DDSURFACEDESC *desc, VOID *udata){ SDL_VideoDevice *this = (SDL_VideoDevice *)udata; struct DX5EnumRect *enumrect;#if defined(NONAMELESSUNION) int bpp = desc->ddpfPixelFormat.u1.dwRGBBitCount; int refreshRate = desc->u2.dwRefreshRate;#else int bpp = desc->ddpfPixelFormat.dwRGBBitCount; int refreshRate = desc->dwRefreshRate;#endif int maxRefreshRate; if ( desc->dwWidth <= SDL_desktop_mode.dmPelsWidth && desc->dwHeight <= SDL_desktop_mode.dmPelsHeight ) { maxRefreshRate = SDL_desktop_mode.dmDisplayFrequency; } else { maxRefreshRate = 85; /* safe value? */ } switch (bpp) { case 8: case 16: case 24: case 32: bpp /= 8; --bpp; if ( enumlists[bpp] && enumlists[bpp]->r.w == (Uint16)desc->dwWidth && enumlists[bpp]->r.h == (Uint16)desc->dwHeight ) { if ( refreshRate > enumlists[bpp]->refreshRate && refreshRate <= maxRefreshRate ) { enumlists[bpp]->refreshRate = refreshRate;#ifdef DDRAW_DEBUG fprintf(stderr, "New refresh rate for %d bpp: %dx%d at %d Hz\n", (bpp+1)*8, (int)desc->dwWidth, (int)desc->dwHeight, refreshRate);#endif } break; } ++SDL_nummodes[bpp]; enumrect = (struct DX5EnumRect*)SDL_malloc(sizeof(struct DX5EnumRect)); if ( !enumrect ) { SDL_OutOfMemory(); return(DDENUMRET_CANCEL); } enumrect->refreshRate = refreshRate; enumrect->r.x = 0; enumrect->r.y = 0; enumrect->r.w = (Uint16)desc->dwWidth; enumrect->r.h = (Uint16)desc->dwHeight; enumrect->next = enumlists[bpp]; enumlists[bpp] = enumrect;#ifdef DDRAW_DEBUG fprintf(stderr, "New mode for %d bpp: %dx%d at %d Hz\n", (bpp+1)*8, (int)desc->dwWidth, (int)desc->dwHeight, refreshRate);#endif break; } return(DDENUMRET_OK);}void SetDDerror(const char *function, int code){ static char *error; static char errbuf[1024]; errbuf[0] = 0; switch (code) { case DDERR_GENERIC: error = "Undefined error!"; break; case DDERR_EXCEPTION: error = "Exception encountered"; break; case DDERR_INVALIDOBJECT: error = "Invalid object"; break; case DDERR_INVALIDPARAMS: error = "Invalid parameters"; break; case DDERR_NOTFOUND: error = "Object not found"; break; case DDERR_INVALIDRECT: error = "Invalid rectangle"; break; case DDERR_INVALIDCAPS: error = "Invalid caps member"; break; case DDERR_INVALIDPIXELFORMAT: error = "Invalid pixel format"; break; case DDERR_OUTOFMEMORY: error = "Out of memory"; break; case DDERR_OUTOFVIDEOMEMORY: error = "Out of video memory"; break; case DDERR_SURFACEBUSY: error = "Surface busy"; break; case DDERR_SURFACELOST: error = "Surface was lost"; break; case DDERR_WASSTILLDRAWING: error = "DirectDraw is still drawing"; break; case DDERR_INVALIDSURFACETYPE: error = "Invalid surface type"; break; case DDERR_NOEXCLUSIVEMODE: error = "Not in exclusive access mode"; break; case DDERR_NOPALETTEATTACHED: error = "No palette attached"; break; case DDERR_NOPALETTEHW: error = "No palette hardware"; break; case DDERR_NOT8BITCOLOR: error = "Not 8-bit color"; break; case DDERR_EXCLUSIVEMODEALREADYSET: error = "Exclusive mode was already set"; break; case DDERR_HWNDALREADYSET: error = "Window handle already set"; break; case DDERR_HWNDSUBCLASSED: error = "Window handle is subclassed"; break; case DDERR_NOBLTHW: error = "No blit hardware"; break; case DDERR_IMPLICITLYCREATED: error = "Surface was implicitly created"; break; case DDERR_INCOMPATIBLEPRIMARY: error = "Incompatible primary surface"; break; case DDERR_NOCOOPERATIVELEVELSET: error = "No cooperative level set"; break; case DDERR_NODIRECTDRAWHW: error = "No DirectDraw hardware"; break; case DDERR_NOEMULATION: error = "No emulation available"; break; case DDERR_NOFLIPHW: error = "No flip hardware"; break; case DDERR_NOTFLIPPABLE: error = "Surface not flippable"; break; case DDERR_PRIMARYSURFACEALREADYEXISTS: error = "Primary surface already exists"; break; case DDERR_UNSUPPORTEDMODE: error = "Unsupported mode"; break; case DDERR_WRONGMODE: error = "Surface created in different mode"; break; case DDERR_UNSUPPORTED: error = "Operation not supported"; break; case E_NOINTERFACE: error = "Interface not present"; break; default: SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: Unknown DirectDraw error: 0x%x", function, code); break; } if ( ! errbuf[0] ) { SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, error); } SDL_SetError("%s", errbuf); return;}static int DX5_UpdateVideoInfo(_THIS){ /* This needs to be DDCAPS_DX5 for the DirectDraw2 interface */#if DIRECTDRAW_VERSION <= 0x300#error Your version of DirectX must be greater than or equal to 5.0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -