Win32Video::~Win32Video () { FreeModes (); if (DDraw != NULL) { if (m_IsFullscreen) { DDraw->SetCooperativeLevel (NULL, DDSCL_NORMAL); } DDraw->Release(); DDraw = NULL; } if (D3D != NULL) { D3D->Release(); D3D = NULL; } STOPLOG; }
void MFDisplay_DestroyDisplay() { MFCALLSTACK; if((!gDisplay.windowed) && (originalVidMode != NULL) && xdisplay != NULL && numModes > 1) { XF86VidModeSwitchToMode(xdisplay, screen, originalVidMode); } MFRenderer_DestroyDisplay(); if(sizeHints != NULL) { XFree(sizeHints); sizeHints = NULL; } if(window != 0) { XDestroyWindow(xdisplay, window); window = 0; } if(colorMap != 0) { XFreeColormap(xdisplay, colorMap); colorMap = 0L; } if(xdisplay != NULL) { XCloseDisplay(xdisplay); xdisplay = NULL; } FreeModes(); }
void Win32Video::InitDDraw () { DIRECTDRAWCREATEFUNC directdraw_create; LPDIRECTDRAW ddraw1; STARTLOG; HRESULT dderr; // Load the DirectDraw library. if ((DDraw_dll = LoadLibraryA ("ddraw.dll")) == NULL) { I_FatalError ("Could not load ddraw.dll"); } // Obtain an IDirectDraw interface. if ((directdraw_create = (DIRECTDRAWCREATEFUNC)GetProcAddress (DDraw_dll, "DirectDrawCreate")) == NULL) { I_FatalError ("The system file ddraw.dll is missing the DirectDrawCreate export"); } dderr = directdraw_create (NULL, &ddraw1, NULL); if (FAILED(dderr)) I_FatalError ("Could not create DirectDraw object: %08lx", dderr); dderr = ddraw1->QueryInterface (IID_IDirectDraw2, (LPVOID*)&DDraw); if (FAILED(dderr)) { ddraw1->Release (); DDraw = NULL; I_FatalError ("Could not initialize IDirectDraw2 interface: %08lx", dderr); } // Okay, we have the IDirectDraw2 interface now, so we can release the // really old-fashioned IDirectDraw one. ddraw1->Release (); DDraw->SetCooperativeLevel (Window, DDSCL_NORMAL); FreeModes (); dderr = DDraw->EnumDisplayModes (0, NULL, this, EnumDDModesCB); if (FAILED(dderr)) { DDraw->Release (); DDraw = NULL; I_FatalError ("Could not enumerate display modes: %08lx", dderr); } if (m_Modes == NULL) { DDraw->Release (); DDraw = NULL; I_FatalError ("DirectDraw returned no display modes.\n\n" "If you started ZDoom from a fullscreen DOS box, run it from " "a DOS window instead. If that does not work, you may need to reboot."); } if (Args->CheckParm ("-2")) { // Force all modes to be pixel-doubled. ScaleModes(1); } else if (Args->CheckParm ("-4")) { // Force all modes to be pixel-quadrupled. ScaleModes(2); } else { if (OSPlatform == os_Win95) { // Windows 95 will let us use Mode X. If we didn't find any linear // modes in the loop above, add the Mode X modes here. AddMode (320, 200, 8, 200, 0); AddMode (320, 240, 8, 240, 0); } AddLowResModes (); } AddLetterboxModes (); }
bool Win32Video::InitD3D9 () { DIRECT3DCREATE9FUNC direct3d_create_9; if (vid_forceddraw) { return false; } // Load the Direct3D 9 library. if ((D3D9_dll = LoadLibraryA ("d3d9.dll")) == NULL) { return false; } // Obtain an IDirect3D interface. if ((direct3d_create_9 = (DIRECT3DCREATE9FUNC)GetProcAddress (D3D9_dll, "Direct3DCreate9")) == NULL) { goto closelib; } if ((D3D = direct3d_create_9 (D3D_SDK_VERSION)) == NULL) { goto closelib; } // Check that we have at least PS 1.4 available. D3DCAPS9 devcaps; if (FAILED(D3D->GetDeviceCaps (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &devcaps))) { goto d3drelease; } if ((devcaps.PixelShaderVersion & 0xFFFF) < 0x104) { goto d3drelease; } if (!(devcaps.Caps2 & D3DCAPS2_DYNAMICTEXTURES)) { goto d3drelease; } // Enumerate available display modes. FreeModes (); AddD3DModes (D3DFMT_X8R8G8B8); AddD3DModes (D3DFMT_R5G6B5); if (Args->CheckParm ("-2")) { // Force all modes to be pixel-doubled. ScaleModes (1); } else if (Args->CheckParm ("-4")) { // Force all modes to be pixel-quadrupled. ScaleModes (2); } else { AddLowResModes (); } AddLetterboxModes (); if (m_Modes == NULL) { // Too bad. We didn't find any modes for D3D9. We probably won't find any // for DDraw either... goto d3drelease; } return true; d3drelease: D3D->Release(); D3D = NULL; closelib: FreeLibrary (D3D9_dll); return false; }
int MFDisplay_CreateDisplay(int width, int height, int bpp, int rate, bool vsync, bool triplebuffer, bool wide, bool progressive) { MFCALLSTACK; MFZeroMemory(gXKeys, sizeof(gXKeys)); MFZeroMemory(&gXMouse, sizeof(gXMouse)); gXMouse.x = -1; gDisplay.fullscreenWidth = gDisplay.width = width; gDisplay.fullscreenHeight = gDisplay.height = height; gDisplay.refreshRate = 0; gDisplay.colourDepth = 0; /* Use default. Chances are, it's something sane */ gDisplay.windowed = true; gDisplay.wide = false; gDisplay.progressive = true; if(!(xdisplay = XOpenDisplay(NULL))) { MFDebug_Error("Unable to open display"); MFDisplay_DestroyDisplay(); return 1; } screen = DefaultScreen(xdisplay); rootWindow = RootWindow(xdisplay, screen); // build our internal list of available video modes GetModes(&modes, !gDisplay.windowed); while(!FindMode(modes, width, height)) { if(!gDisplay.windowed) { // no fullscreen mode, try windowed mode instead MFDebug_Warn(1, "No suitable modes for fullscreen mode, trying windowed mode"); gDisplay.windowed = true; FreeModes(); GetModes(&modes, false); } else { // default is some sort of custom mode that doesn't appear in the windowed mode list // HACK: we'll add it to the end.. modes[numModes].width = width; modes[numModes].height = height; currentMode = numModes; ++numModes; break; } } DebugMenu_AddItem("Resolution", "Display Options", &resSelect, ChangeResCallback); DebugMenu_AddItem("Apply", "Display Options", &applyDisplayMode, ApplyDisplayModeCallback); // Set full screen mode, if necessary if(!gDisplay.windowed && numModes > 1) { if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode])) { MFDebug_Error("Unable to switch screenmodes, defaulting to windowed mode"); MFDisplay_DestroyDisplay(); return 1; } } XVisualInfo *MFRenderer_GetVisualInfo(); XVisualInfo *visualInfo = MFRenderer_GetVisualInfo(); if(!visualInfo) return 1; if(!(colorMap = XCreateColormap(xdisplay, rootWindow, visualInfo->visual, AllocNone))) { MFDebug_Error("Unable to create colourmap"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } XSetWindowAttributes windowAttrs; windowAttrs.colormap = colorMap; windowAttrs.cursor = None; windowAttrs.event_mask = StructureNotifyMask; windowAttrs.border_pixel = BlackPixel(xdisplay, screen); windowAttrs.background_pixel = BlackPixel(xdisplay, screen); if(!(window = XCreateWindow(xdisplay, rootWindow, 0, 0, width, height, 0, visualInfo->depth, InputOutput, visualInfo->visual, CWBackPixel | CWBorderPixel | CWCursor | CWColormap | CWEventMask, &windowAttrs))) { MFDebug_Error("Unable to create X Window"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } // Tell the window manager not to allow our window to be resized. But some window managers can ignore me and do it anyway. Typical X-Windows. if((sizeHints = XAllocSizeHints()) == NULL) { MFDebug_Error("Unable to alloc XSizeHints structure, out of memory?"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } sizeHints->flags = PSize | PMinSize | PMaxSize; sizeHints->min_width = sizeHints->max_width = sizeHints->base_width = width; sizeHints->min_height = sizeHints->max_height = sizeHints->base_height = height; XSetWMNormalHints(xdisplay, window, sizeHints); // Window title XStoreName(xdisplay, window, gDefaults.display.pWindowTitle); XWMHints *wmHints; if((wmHints = XAllocWMHints()) == NULL) { MFDebug_Error("Unable to alloc XWMHints structure, out of memory?"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } wmHints->flags = InputHint | StateHint; wmHints->input = true; wmHints->initial_state = NormalState; if(!XSetWMHints(xdisplay, window, wmHints)) { MFDebug_Error("Unable to set WM hints for window"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } XFree(wmHints); XFree(visualInfo); // Tell the window manager that I want to be notified if the window's closed wm_delete_window = XInternAtom(xdisplay, "WM_DELETE_WINDOW", false); if(!XSetWMProtocols(xdisplay, window, &wm_delete_window, 1)) { MFDebug_Error("Unable to set Window Manager protocols"); MFDisplay_DestroyDisplay(); return 1; } XSelectInput(xdisplay, window, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ExposureMask); if(!XMapRaised(xdisplay, window)) { MFDebug_Error("Unable to map new window"); MFDisplay_DestroyDisplay(); return 1; } // Wait for the window to be mapped, etc. The documentation doesn't indicate that this is necessary, but every GLX program I've ever seen does it, so I assume it is. XEvent event; XIfEvent(xdisplay, &event, WaitForNotify, (char *)window); MFRenderer_CreateDisplay(); if(!gDisplay.windowed && numModes > 1) { if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode])) { MFDebug_Error("Unable to set screen mode"); MFDisplay_DestroyDisplay(); return 1; } XGrabPointer(xdisplay, window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, window, None, CurrentTime); XFlush(xdisplay); // A little trick to make sure the entire window is on the screen XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, width - 1, height - 1); XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, 0, 0); XFlush(xdisplay); } return 0; }