// DDSetPalette // ---------------------------------------------------------------------------- void DDSetPalette(LPDIRECTDRAWPALETTE lpDDPal) { HRESULT ddresult; ddresult = IDirectDrawSurface_SetPalette(_lpDDSPrimary, lpDDPal); if (ddresult != DD_OK) { if (ddresult == DDERR_SURFACELOST) { IDirectDrawSurface_Restore(_lpDDSPrimary); IDirectDrawSurface_SetPalette(_lpDDSPrimary, lpDDPal); } else { Error("Unable to attach palette to primary surface: %x.", ddresult); } } }
// // Set a a full palette of 256 PALETTEENTRY entries // VOID SetDDPalette(PALETTEENTRY* pal) { // create palette first time if (DDPalette == NULL) CreateDDPalette(pal); else IDirectDrawPalette_SetEntries(DDPalette, 0, 0, 256, pal); // setting the same palette to the same surface again does not increase // the reference count IDirectDrawSurface_SetPalette(ScreenReal, DDPalette); }
static void WINAPI VGA_DoExit(ULONG_PTR arg) { VGA_DeinstallTimer(); IDirectDrawSurface_SetPalette(lpddsurf,NULL); IDirectDrawSurface_Release(lpddsurf); lpddsurf=NULL; IDirectDrawPalette_Release(lpddpal); lpddpal=NULL; IDirectDraw_Release(lpddraw); lpddraw=NULL; }
// // Restore the palette. Useful when we regain focus. // VOID RestoreDDPalette(VOID) { if (DDPalette) IDirectDrawSurface_SetPalette(ScreenReal, DDPalette); }
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 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; }
static LRESULT CALLBACK WindowProc(HWND hWnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { PAINTSTRUCT paintStruct; HDC hDC; if (uMsg == (unsigned int) MyHelpMsg) { win32_help(NULL, helptopic); return 0; } switch (uMsg) { case WM_COMMAND: win32_pressed(wParam); break; case WM_SIZE: // resize window if (directX == DXFULLSCREEN) return 0; if (LOWORD(lParam) == 0 && HIWORD(lParam) == 0) { active = 0; break; } /*Minimized window */ active = 1; if (displayX != LOWORD(lParam) || displayY != HIWORD(lParam)) resized = 1; displayX = LOWORD(lParam); displayY = HIWORD(lParam); break; case WM_DISPLAYCHANGE: if (directX == DXFULLSCREEN) return 0; mouseButtons = 0; resized = 1; hDC = GetDC(hWnd); bitDepth = GetDeviceCaps(hDC, BITSPIXEL); ReleaseDC(hWnd, hDC); break; case WM_CLOSE: // close window closeFlag = TRUE; return 0; case WM_MOUSEMOVE: case WM_LBUTTONUP: case WM_LBUTTONDOWN: case WM_RBUTTONUP: case WM_RBUTTONDOWN: case WM_MBUTTONUP: case WM_MBUTTONDOWN: // handle mouse move and mouse buttons mouseButtons = wParam; if (!captured) { if (mouseButtons && !tmpcaptured) SetCapture(hWnd), tmpcaptured = 1; if (!mouseButtons && tmpcaptured) ReleaseCapture(), tmpcaptured = 0; } mouseX = (short) LOWORD(lParam); mouseY = (short) HIWORD(lParam); #ifdef DDRAW_DRIVER if (directX == DXFULLSCREEN) { POINT p; GetCursorPos(&p); mouseX = p.x; mouseY = p.y; UpdateMouseDD(); } #endif break; case WM_PAINT: // redraw screen if (directX == DXFULLSCREEN) return 0; needredraw = 1; if (GetUpdateRect(hWnd, NULL, FALSE)) { HDC hDC = BeginPaint(hWnd, &paintStruct); if (hDC) { #ifdef DDRAW_DRIVER if (directX) PaintDD(); else #endif Paint(hDC); EndPaint(hWnd, &paintStruct); } } return 0; case WM_QUERYNEWPALETTE: // windows calls this when window is reactivated. if (directX == DXFULLSCREEN) return 0; hDC = GetDC(hWnd); #ifdef DDRAW_DRIVER if (directX == DXWINDOWED) { if (dxPalette) { IDirectDrawSurface_SetPalette(lpSurfaces[0], dxPalette); IDirectDrawPalette_SetEntries(dxPalette, 0, 0, 255, (PALETTEENTRY *) backpalette); } } else #endif { SelectPalette(hDC, hPalette, FALSE); RealizePalette(hDC); } ReleaseDC(hWnd, hDC); return TRUE; case WM_MOVE: if (directX != DXFULLSCREEN) { GetWindowRect(hWnd, &rcWindow); GetClientRect(hWnd, &rcViewport); GetClientRect(hWnd, &rcScreen); ClientToScreen(hWnd, (POINT *) & rcScreen.left); ClientToScreen(hWnd, (POINT *) & rcScreen.right); } break; case WM_SETCURSOR: if (directX == DXFULLSCREEN) { SetCursor(NULL); return TRUE; } break; #ifdef DDRAW_DRIVER case WM_ACTIVATEAPP: { int oldactive = active; mouseButtons = 0; if (directX == DXFULLSCREEN) { needredraw = 1; active = (wParam == WA_ACTIVE) || (wParam == WA_CLICKACTIVE) /*(BOOL) wParam */ ; PaintDD(); if (!oldactive && active && captured) SetCursor(NULL), SetCapture(hWnd); if (oldactive && !active && captured) ReleaseCapture(); return 0L; } } #endif break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
static void WINAPI VGA_DoSetMode(ULONG_PTR arg) { LRESULT res; ModeSet *par = (ModeSet *)arg; par->ret=1; if (lpddraw) VGA_DoExit(0); if (!lpddraw) { if (!pDirectDrawCreate) { HMODULE hmod = LoadLibraryA( "ddraw.dll" ); if (hmod) pDirectDrawCreate = (DirectDrawCreateProc)GetProcAddress( hmod, "DirectDrawCreate" ); if (!pDirectDrawCreate) { ERR("Can't lookup DirectDrawCreate from ddraw.dll.\n"); return; } } res = pDirectDrawCreate(NULL,&lpddraw,NULL); if (!lpddraw) { ERR("DirectDraw is not available (res = %lx)\n",res); return; } if (!vga_hwnd) { vga_hwnd = CreateWindowExA(0,"STATIC","WINEDOS VGA", WS_POPUP|WS_VISIBLE|SS_NOTIFY,0,0, par->Xres,par->Yres,0,0,0,NULL); if (!vga_hwnd) { ERR("Failed to create user window.\n"); IDirectDraw_Release(lpddraw); lpddraw=NULL; return; } } else SetWindowPos(vga_hwnd,0,0,0,par->Xres,par->Yres,SWP_NOMOVE|SWP_NOZORDER); if ((res=IDirectDraw_SetCooperativeLevel(lpddraw,vga_hwnd,DDSCL_FULLSCREEN|DDSCL_EXCLUSIVE))) { ERR("Could not set cooperative level to exclusive (%lx)\n",res); } if ((res=IDirectDraw_SetDisplayMode(lpddraw,par->Xres,par->Yres,par->Depth))) { ERR("DirectDraw does not support requested display mode (%dx%dx%d), res = %lx!\n",par->Xres,par->Yres,par->Depth,res); IDirectDraw_Release(lpddraw); lpddraw=NULL; return; } res=IDirectDraw_CreatePalette(lpddraw,DDPCAPS_8BIT,NULL,&lpddpal,NULL); if (res) { ERR("Could not create palette (res = %lx)\n",res); IDirectDraw_Release(lpddraw); lpddraw=NULL; return; } if ((res=IDirectDrawPalette_SetEntries(lpddpal,0,0,256,vga_def_palette))) { ERR("Could not set default palette entries (res = %lx)\n", res); } memset(&sdesc,0,sizeof(sdesc)); sdesc.dwSize=sizeof(sdesc); sdesc.dwFlags = DDSD_CAPS; sdesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if (IDirectDraw_CreateSurface(lpddraw,&sdesc,&lpddsurf,NULL)||(!lpddsurf)) { ERR("DirectDraw surface is not available\n"); IDirectDraw_Release(lpddraw); lpddraw=NULL; return; } IDirectDrawSurface_SetPalette(lpddsurf,lpddpal); vga_retrace_vertical = vga_retrace_horizontal = FALSE; /* poll every 20ms (50fps should provide adequate responsiveness) */ VGA_InstallTimer(20); } par->ret=0; return; }