Compare commits

...

14 Commits

Author SHA1 Message Date
Ian Brun
b4f2e9af49
Merge pull request #154 from meekee7/32bit-colordepth-support
32bit color depth support
2021-06-08 18:10:58 +02:00
Michael
0f90d25dea Root/README.md: update documentation to reflect 32bit color depth support 2021-04-25 18:31:44 +02:00
Michael
dc41653877 supportfn.cpp: use backbuffer as screenshot source 2021-02-14 23:17:11 +01:00
Michael
07b9964a95 mainwnd.cpp: repaint before creating screenshot 2021-02-14 23:16:39 +01:00
Michael
6274981a6b tpassglobals.cpp: use getter for backbuffer
- disable client basepoint correction
2021-02-14 22:58:51 +01:00
Michael
858a856ee0 gamewnd.cpp: repaint before background capture and use backbuffer 2021-02-14 22:57:25 +01:00
Michael
5a45dca103 trespass/video.cpp: use backbuffer surface to render video
- clear backbuffer before rendering, flip buffers afterwards
2021-02-14 22:12:16 +01:00
Michael
c0031c0051 RasterVid.hpp: add getter for backbuffer surface
- remove redundant function GetPrimarySurface4
2021-02-14 22:10:48 +01:00
Michael
606aef21d5 trespass/trespass.rc: add display configuration invalidity error message 2021-02-14 20:56:44 +01:00
Michael
aa4207f77c trespass/resource.h: add display configuration invalidity error message 2021-02-14 20:55:57 +01:00
Michael
232892aeba trespass/main.cpp: add display configuration validity check 2021-02-14 20:55:12 +01:00
Michael
27040b09e9 Direct3D.cpp: rename GetPrimarySurface function 2021-02-14 20:53:58 +01:00
Michael
85fe250634 RasterVid.cpp: force backbuffer into 16bit color depth when system is in 32bit color mode 2021-02-14 20:44:56 +01:00
Michael
eff7be4601 DisplayMode: add query for current system bit depth
- add configuration validation
2021-02-14 19:49:34 +01:00
14 changed files with 102 additions and 24 deletions

View File

@ -40,9 +40,10 @@ Depending on your system configuration, a program running in the Trespasser dire
### 16bit color depth mode
The renderer only supports 16bit color depth. Adding 32bit support is an open issue.
The game works in both 16bit and 32bit color depth.
An exception applies to D3D rendering together with exclusive fullscreen mode: this combination only works with 16bit color depth.
Running the game with 32bit color depth is possible, but the graphics are faulty and it will inevitably crash after a few minutes. Some apps like GUIApp completely refuse to start in 32bit color depth mode.
Additional tools like GUIApp have not yet been tested in 32bit color depth and might completely refuse to start in that configuration.
We do not know how to make VS start a program in 16bit color depth mode. Perhaps it can be done by starting VS with 16bit color depth, but that would be very inconvenient.

View File

@ -9,3 +9,24 @@ WindowMode GetWindowModeConfigured()
selection = 0;
return static_cast<WindowMode>(selection);
}
int GetSystemBitDepth(HWND wnd)
{
return GetSystemBitDepth(GetDC(wnd));
}
int GetSystemBitDepth(HDC dc)
{
//Gives 16bit when program is set to 16bit color depth compatibility mode
return GetDeviceCaps(dc, BITSPIXEL);
}
bool IsDisplayConfigurationValid(int colorDepth, bool d3dEnabled, WindowMode mode)
{
if (mode == WindowMode::UNDEFINED)
return false;
if (mode == WindowMode::EXCLUSIVE && d3dEnabled && colorDepth != 16)
return false;
return true;
}

View File

@ -1,5 +1,7 @@
#pragma once
#include <Windows.h>
enum class WindowMode {
UNDEFINED = 0,
FRAMED = 1,
@ -8,3 +10,8 @@ enum class WindowMode {
};
WindowMode GetWindowModeConfigured();
int GetSystemBitDepth(HWND wnd);
int GetSystemBitDepth(HDC dc);
bool IsDisplayConfigurationValid(int colorDepth, bool d3dEnabled, WindowMode mode);

View File

@ -595,14 +595,14 @@ public:
//******************************************************************************************
//
IDirectDrawSurface4 * GetPrimarySurface4()
IDirectDrawSurface4 * GetRenderTargetSurface()
{
return pddsPrimary4;
return pddsDraw4;
}
//
// Returns a pointer to the primary surface. This is necessary for Videos.
//
//**********************************
// Returns a pointer to the backbuffer, which generally should be the rendering target.
//
//**********************************
//******************************************************************************************

View File

@ -130,6 +130,18 @@ static HRESULT WINAPI EnumZBufferFormats
return D3DENUMRET_OK;
}
static void Set16BitPixelFormat(DDSURFACEDESC2& desc)
{
desc.dwFlags |= DDSD_PIXELFORMAT;
CDDSize<DDPIXELFORMAT>::InitStruct(desc.ddpfPixelFormat);
desc.ddpfPixelFormat.dwRGBBitCount = 16;
desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
desc.ddpfPixelFormat.dwRBitMask = 0xF800;
desc.ddpfPixelFormat.dwGBitMask = 0x07E0;
desc.ddpfPixelFormat.dwBBitMask = 0x001F;
}
//
// Private class definitions.
@ -240,6 +252,7 @@ private:
int i_height,
int i_bits, // How many bits deep for full-screen, 0 for windowed.
int i_buffers, // How many buffers to construct.
bool force16Bit,
CSet<ERasterFlag> seteras // Any special flags for the raster.
)
//
@ -253,7 +266,7 @@ private:
sd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
DirectDraw::err = DirectDraw::pdd4->CreateSurface(&sd, &pddsPrimary4, 0);
if (i_buffers > 1)
if (i_buffers > 1 || force16Bit)
{
sd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
@ -268,6 +281,9 @@ private:
sd.dwHeight = i_height;
sd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
if (force16Bit)
Set16BitPixelFormat(sd);
if (!seteras[erasVideoMem])
// Video mem not wanted, force system memory.
sd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
@ -306,7 +322,8 @@ private:
int i_height,
int i_bits, // How many bits deep for full-screen, 0 for windowed.
int i_buffers, // How many buffers to construct.
CSet<ERasterFlag> seteras // Any special flags for the raster.
CSet<ERasterFlag> seteras, // Any special flags for the raster.
bool force16Bit = false
)
//
// Creates a screen raster for use with the software rasterizer.
@ -336,7 +353,7 @@ private:
}
// Try to construct the backbuffer in video memory.
if (i_bits && i_buffers > 1 && seteras[erasVideoMem])
if (i_bits && !force16Bit && i_buffers > 1 && seteras[erasVideoMem])
{
if (bConstructSoftwareVidRam(i_width, i_height, i_bits, i_buffers))
{
@ -346,7 +363,7 @@ private:
}
// Creating a buffer in video memory failed. Create one in system memory.
bConstructSoftwareSysRam(i_width, i_height, i_bits, i_buffers, seteras);
bConstructSoftwareSysRam(i_width, i_height, i_bits, i_buffers, force16Bit, seteras);
bFlippable = false;
}
@ -356,7 +373,8 @@ private:
(
HWND hwnd, // A previously constructed Windows HWND.
int i_width, int i_height, // The desired dimensions of the raster.
int i_bits = 16
int i_bits = 16,
bool force16Bit = false
);
//
// Creates a screen raster for use with Direct3D.
@ -374,7 +392,8 @@ private:
(
HWND hwnd, // A previously constructed Windows HWND.
int i_width, int i_height, // The desired dimensions of the raster.
int i_bits = 16
int i_bits = 16,
bool force16Bit = false
);
//******************************************************************************************
@ -1191,8 +1210,10 @@ rptr<CRaster> prasReadBMP(const char* str_bitmap_name, bool b_vid)
bFullScreen = i_bits != 0;
bool force16Bit = GetSystemBitDepth(hwnd) != 16;
// Use separate creation code for Direct3D.
if (priv_self.bConstructD3D(hwnd, i_width, i_height, 16))
if (priv_self.bConstructD3D(hwnd, i_width, i_height, 16, force16Bit))
{
AlwaysAssert(pddsDraw4);
AlwaysAssert(pddsPrimary4);
@ -1203,7 +1224,7 @@ rptr<CRaster> prasReadBMP(const char* str_bitmap_name, bool b_vid)
d3dDriver.Uninitialize();
// Construct a regular DirectDraw interface.
priv_self.ConstructSoftware(hwnd, i_width, i_height, i_bits, i_buffers, seteras);
priv_self.ConstructSoftware(hwnd, i_width, i_height, i_bits, i_buffers, seteras, force16Bit);
}
ConstructClipper(hwnd);
AlwaysAssert(pddsDraw4);
@ -1712,12 +1733,12 @@ rptr<CRaster> prasReadBMP(const char* str_bitmap_name, bool b_vid)
}
//******************************************************************************************
bool CRasterWin::CPriv::bConstructD3D(HWND hwnd, int i_width, int i_height, int i_bits)
bool CRasterWin::CPriv::bConstructD3D(HWND hwnd, int i_width, int i_height, int i_bits, bool force16Bit)
{
if (GetWindowModeConfigured() == WindowMode::EXCLUSIVE)
return bConstructD3DExclusive(hwnd, i_width, i_height, i_bits);
else
return bConstructD3DWindowed(hwnd, i_width, i_height, i_bits);
return bConstructD3DWindowed(hwnd, i_width, i_height, i_bits, force16Bit);
}
bool CRasterWin::CPriv::bConstructD3DExclusive(HWND hwnd, int i_width, int i_height, int i_bits)
@ -1857,7 +1878,7 @@ rptr<CRaster> prasReadBMP(const char* str_bitmap_name, bool b_vid)
return pddsDraw4 && pddsPrimary4;
}
bool CRasterWin::CPriv::bConstructD3DWindowed(HWND hwnd, int i_width, int i_height, int i_bits)
bool CRasterWin::CPriv::bConstructD3DWindowed(HWND hwnd, int i_width, int i_height, int i_bits, bool force16Bit)
{
AlwaysAssert(hwnd);
AlwaysAssert(i_width > 0);
@ -1913,6 +1934,9 @@ rptr<CRaster> prasReadBMP(const char* str_bitmap_name, bool b_vid)
backbufferddsd.dwWidth = i_width;
backbufferddsd.dwHeight = i_height;
if (force16Bit)
Set16BitPixelFormat(backbufferddsd);
hres = DirectDraw::pdd4->CreateSurface(&backbufferddsd, &pddsDraw4, nullptr);
if (FAILED(hres))

View File

@ -856,7 +856,7 @@ public:
return false;
}
LPDIRECTDRAWSURFACE4 pdds_back = prasMainScreen->pddsDraw4;
LPDIRECTDRAWSURFACE4 pdds_front = prasMainScreen->GetPrimarySurface4();
LPDIRECTDRAWSURFACE4 pdds_front = prasMainScreen->GetPrimarySurface();
return bInitialize(pdds_back, pdds_front);
}

View File

@ -419,6 +419,9 @@ void CGameWnd::SetupGameStoppage()
// Stop the simulation
msg.Dispatch();
//Repaint in case we have a cleared framebuffer right now
this->OnPaint(g_hwnd);
m_bPaused = TRUE;
m_pUIMgr->m_bDrawMouse = TRUE;
@ -434,7 +437,7 @@ void CGameWnd::SetupGameStoppage()
SetCursorPos(prasMainScreen->iWidth / 2,
prasMainScreen->iHeight / 2);
g_CTPassGlobals.CaptureBackground();
g_CTPassGlobals.CaptureBackground(true);
g_CTPassGlobals.bHardReset = false;
}

View File

@ -455,6 +455,15 @@ int DoWinMain(HINSTANCE hInstance,
return -1;
}
if ( !IsDisplayConfigurationValid( GetSystemBitDepth(g_hwnd), bGetD3D(), GetWindowModeConfigured()))
{
if (MsgDlg(g_hwnd,
MB_YESNOCANCEL | MB_SETFOREGROUND,
IDS_ERROR_TITLE,
IDS_ERR_INVALID_DISPLAY_CONFIGURATION) != IDYES)
goto Cleanup;
}
//
// Check To see if the installed registry flag is set. If it has not been
// set then we haven't been installed.

View File

@ -174,6 +174,8 @@ void CMainWnd::OnKey(HWND hwnd, UINT vk, BOOL fDown, int cRepeat, UINT flags)
if (vk == VK_SNAPSHOT)
{
//Repaint in case we have a cleared framebuffer right now
this->OnPaint(hwnd);
ScreenCapture();
return;
}

View File

@ -46,6 +46,7 @@
#define IDS_ERR_PDETECT_FAILED 40
#define IDS_ERR_NO_ACCELERATORS 41
#define IDS_ERR_DISPLAY_README 42
#define IDS_ERR_INVALID_DISPLAY_CONFIGURATION 43
#define IDI_APP 101
#define IDTIMER_MAINRANDOM 101
#define IDB_DEF_PAL 102

View File

@ -1147,7 +1147,7 @@ void ScreenCapture()
// Save out a blank bitmap if a real one cannot be found.
pSurface = prasMainScreen->GetPrimarySurface();
pSurface = prasMainScreen->GetRenderTargetSurface();
hr = pSurface->GetDC(&hdcSrc);
SetStretchBltMode(hdcDst, COLORONCOLOR);

View File

@ -181,7 +181,7 @@ void CTPassGlobals::CaptureBackground(bool bBackbuffer /* = false */)
if (bBackbuffer)
{
pSurface = prasMainScreen->pddsDraw4;
pSurface = prasMainScreen->GetRenderTargetSurface();
}
else
{
@ -193,7 +193,8 @@ void CTPassGlobals::CaptureBackground(bool bBackbuffer /* = false */)
hdcDst = m_prasBkgnd->hdcGet();
POINT basepoint = { 0,0 };
ClientToScreen(g_hwnd, &basepoint);
//Enable this if the background is shifted in windowed mode
//ClientToScreen(g_hwnd, &basepoint);
BitBlt(hdcDst,
0,

View File

@ -208,6 +208,8 @@ BEGIN
IDS_ERR_PDETECT_FAILED "Failed to detect local processor. Do you want to continue?"
IDS_ERR_NO_ACCELERATORS "No hardware accelerators compatible with Trespasser have been found.\r\nConsult the 'Readme.txt' file for more information on supported\r\nhardware accelerators."
IDS_ERR_DISPLAY_README "Unable to display the 'Readme.txt' file. Please open the file\nmanually from the 'Setup' directory on your distribution CD-ROM\nusing a program like Notepad or Wordpad."
IDS_ERR_INVALID_DISPLAY_CONFIGURATION
"The current combination of display settings is invalid. This error involves a combination of these settings:\r\n\r\n- 16bit color depth compatibility mode\r\n- Window Mode\r\n- D3D enabled\r\n\r\nIf you continue, then the game will have visual errors and not run stable.\r\nDo you want to continue?"
END
#endif // English (U.S.) resources

View File

@ -107,7 +107,7 @@ void CVideoWnd::NextNonDirect()
CDDSize<DDSURFACEDESC2> dds;
HRESULT hr;
pSurface = prasMainScreen->GetPrimarySurface();
pSurface = prasMainScreen->GetRenderTargetSurface();
do
{
hr = pSurface->Lock(NULL,
@ -179,6 +179,10 @@ void CVideoWnd::NextNonDirect()
void CVideoWnd::NextSmackerFrame()
{
CDDSize<DDBLTFX> fx;
fx.dwFillColor = 0;
HRESULT blt = prasMainScreen->GetRenderTargetSurface()->Blt(nullptr, nullptr, nullptr, DDBLT_WAIT | DDBLT_COLORFILL, &fx);
if (m_fDirect)
{
NextDirect();
@ -188,6 +192,9 @@ void CVideoWnd::NextSmackerFrame()
NextNonDirect();
}
prasMainScreen->Flip();
if (m_pSmack->FrameNum == m_pSmack->Frames - 1)
{
m_fVideoOver = true;