I have C++ working example with using DirectDraw SetDisplayMode to 8 bpp.
I'm trying to do the same with .NET and pinvoke. Main window is created with WinApi calls too. But it allows to use only 32 bpp. All other values throw NotImplementedException.
Is it possible to resolve this issue?
UPDATE (example code added)
С++ window init:
HWND InitWindow(int iCmdShow)
{
HWND hWnd;
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hInst;
wc.hIcon = LoadIcon(g_hInst, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = TEXT("");
wc.lpszClassName = TEXT("Basic DD");
RegisterClass(&wc);
hWnd = CreateWindowEx(
WS_EX_TOPMOST,
TEXT("Basic DD"),
TEXT("Basic DD"),
WS_POPUP,
0,
0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
NULL,
NULL,
g_hInst,
NULL);
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
SetFocus(hWnd);
return hWnd;
}
C++ SetDisplayMode
hRet = DirectDrawCreateEx(NULL, (VOID**)&g_pDD, IID_IDirectDraw7, NULL);
if( hRet != DD_OK )
return -1;
hRet = g_pDD->SetCooperativeLevel(g_hMainWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
if( hRet != DD_OK )
return -2;
hRet = g_pDD->SetDisplayMode(640, 480, 8, 0, 0);
if( hRet != DD_OK )
return -3;
C# window init
IntPtr InitWindow(int iCmdShow)
{
IntPtr hWnd = IntPtr.Zero;
WNDCLASS wc = new WNDCLASS();
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hInst;
//wc.hIcon = LoadIcon(g_hInst, IDI_APPLICATION);
//wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = WinApi.GetStockObject(StockObjects.BLACK_BRUSH);
wc.lpszMenuName = "";
wc.lpszClassName = "Basic DD";
var cls = WinApi.RegisterClassA(wc);
hWnd = WinApi.CreateWindowEx(
WS_EX_TOPMOST,
cls,
"Basic DD",
WS_POPUP,
0,
0,
WinApi.GetSystemMetrics(SM_CXSCREEN),
WinApi.GetSystemMetrics(SM_CYSCREEN),
IntPtr.Zero,
IntPtr.Zero,
g_hInst,
IntPtr.Zero);
WinApi.ShowWindow(hWnd, iCmdShow);
WinApi.UpdateWindow(hWnd);
WinApi.SetFocus(hWnd);
return hWnd;
}
C# SetDisplayMode
hRet = DdrawApi.DirectDrawCreateEx(0, out g_pDD, ref IID_IDirectDraw7, IntPtr.Zero);
if (hRet != DD_OK)
return -1;
hRet = g_pDD.SetCooperativeLevel(g_hMainWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
if (hRet != DD_OK)
return -2;
hRet = g_pDD.SetDisplayMode(640, 480, 8, 0, 0);
if (hRet != DD_OK)
return -3;
IDirectDraw7
GUID for IDirectDraw7:
public static GUID IID_IDirectDraw7 =
CreateIID.DEFINE_GUID(0x15e65ec0, 0x3b9c, 0x11d2, 0xb9,
0x2f, 0x00, 0x60, 0x97, 0x97, 0xea, 0x5b);
UPDATE 2 (interfaces added)
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("15e65ec0-3B9C-11D2-B92F-00609797EA5B")]
public interface IDirectDraw7 : IUnknown
{
//0xC
uint Compact();
//10
uint CreateClipper(uint dwFlags, out IDirectDrawClipper lplpDDClipper, IntPtr pUnkOuter);
//14
uint CreatePalette(uint dwFlags, ref tagPALETTEENTRY lpDDColorArray, ref IDirectDrawPalette ppPalette, IUnknown pUnkOuter);
//18
uint CreateSurface(ref DDSURFACEDESC lpDDSurfaceDesc, ref IDirectDrawSurface lplpDDSurface, IUnknown pUnkOuter);
//1C
uint DuplicateSurface(ref IDirectDrawSurface a1, ref IDirectDrawSurface a2);
//20
uint EnumDisplayModes(uint dwFlags, ref DDSURFACEDESC lpDDSurfaceDesc2,
IntPtr lpContext, IntPtr lpEnumModesCallback);
//24
uint EnumSurfaces(uint dwFlags, ref DDSURFACEDESC lpDDSD2,
IntPtr lpContext, IntPtr lpEnumSurfacesCallback);
//28
uint FlipToGDISurface();
//2C
uint GetCaps(out DDCAPS halCaps, out DDCAPS helCaps);
//30
uint GetDisplayMode(out DDSURFACEDESC lpDDSurfaceDesc2);
//34
uint GetFourCCCodes(ref int lpNumCodes, IntPtr lpCodes);
//38
uint GetGDISurface(out IDirectDrawSurface lplpGDIDDSSurface4);
//3C
uint GetMonitorFrequency(ref uint lpdwFrequency);
//40
uint GetScanLine(ref uint lpdwScanLine);
//44
uint GetVerticalBlankStatus(ref bool lpbIsInVB);
//48
uint Initialize(GUID guid);
//4C
uint RestoreDisplayMode();
// 50
uint SetCooperativeLevel(IntPtr hWnd, uint flags);
//54
uint SetDisplayMode(uint width, uint height, uint depth, uint dwRefreshRate, uint dwFlags);
//uint SetDisplayMode(int width, int height, int depth);
//58
uint WaitForVerticalBlank(uint flags, IntPtr handle);
/*** Added in the v2 interface ***/
uint GetAvailableVidMem(ref DDSCAPS lpDDSCaps2, ref uint lpdwTotal, ref uint lpdwFree);
/*** Added in the V4 Interface ***/
uint GetSurfaceFromDC(IntPtr hdc, out IDirectDrawSurface lpDDS4);
uint RestoreAllSurfaces();
uint TestCooperativeLevel();
uint GetDeviceIdentifier(ref DDDEVICEIDENTIFIER lpDDDeviceIdentifier, uint dwFlags);
uint StartModeTest(ref SIZE lpModesToTest, uint dwNumEntries, uint dwFlags);
uint EvaluateMode(uint dwFlags, ref uint pSecondsUntilTimeout);
}
IDirectDrawSurface
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("6C14DB81-A733-11CE-A521-0020AF0BE560")]
public interface IDirectDrawSurface : IUnknown
{
uint AddOverlayDirtyRect(ref tagRECT rec);
uint Blt(ref tagRECT lpDestRect, IDirectDrawSurface lpDDSrcSurface, ref tagRECT lpSrcRect, uint dwFlags, ref DDBLTFX lpDDBltFx);
uint EnumAttachedSurfaces(IntPtr lpContext, IntPtr lpEnumSurfacesCallback);
uint EnumOverlayZOrders(uint dwFlags, IntPtr lpContext, IntPtr lpEnumModesCallback);
uint Flip(IntPtr lpDDSurfaceTargetOverride, uint dwFlags);
uint GetBltStatus(uint dwFlags);
uint GetCaps(ref DDSCAPS lpDDSCaps);
uint GetClipper(out IDirectDrawClipper lplpDDClipper);
uint GetColorKey(uint dwFlags, ref DDCOLORKEY lpDDColorKey);
uint GetDC(ref IntPtr lphDC);
uint GetFlipStatus(uint dwFlags);
uint GetOverlayPosition(ref int lplX, ref int lplY);
uint GetPalette(out IDirectDrawPalette lpDDPalette);
uint GetPixelFormat(ref DDPIXELFORMAT lpDDPixelFormat);
uint GetSurfaceDesc(ref DDSURFACEDESC lpDDSurfaceDesc);
uint IsLost();
uint Lock(ref tagRECT lpDestRect, ref DDSURFACEDESC lpDDSurfaceDesc, uint dwFlags, IntPtr hEvent);
uint ReleaseDC(IntPtr hDC);
uint Restore();
uint SetClipper(IDirectDrawClipper lpDDClipper);
uint SetColorKey(uint dwFlags, ref DDCOLORKEY lpDDColorKey);
uint SetOverlayPosition(int lX, int lY);
uint SetPalette(IDirectDrawPalette lpDDPalette);
uint Unlock(ref tagRECT lpRect);
uint UpdateOverlay(ref tagRECT lpSrcRect, IDirectDrawSurface lpDDDestSurface, ref tagRECT lpDestRect, uint dwFlags, ref DDOVERLAYFX lpDDOverlayFx);
uint UpdateOverlayZOrder(uint dwFlags, IDirectDrawSurface lpDDSReference);
uint GetDDInterface(ref IntPtr lplpDD);
uint AlphaBlt(ref tagRECT lpDestRect, IDirectDrawSurface lpDDSrcSurface, ref tagRECT lpSrcRect, uint dwFlags, ref DDALPHABLTFX lpDDAlphaBltFX);
}
Ddraw imports
[DllImport("ddraw.dll", EntryPoint = "DirectDrawCreate")]
public extern static uint DirectDrawCreate(int pcGuidDevice, out IDirectDraw lplpDD, IntPtr pUnkOuter);
[DllImport("DDraw.DLL", CharSet = CharSet.Auto, SetLastError = true)]
public static extern uint DirectDrawCreateEx(int NO_GUID, out IDirectDraw lplpDD, ref GUID iid, IntPtr pUnkOuter);
[DllImport("DDraw.DLL", CharSet = CharSet.Auto, SetLastError = true)]
public static extern uint DirectDrawCreateEx(int NO_GUID, out IDirectDraw7 lplpDD, ref GUID iid, IntPtr pUnkOuter);
Example of struct
[StructLayout(LayoutKind.Sequential)]
public struct DDPIXELFORMAT
{
public uint dwSize;
public uint dwFlags;
public uint dwFourCC;
public uint anonymous_0;
public uint anonymous_1;
public uint anonymous_2;
public uint anonymous_3;
public uint anonymous_4;
}