mirror of
https://github.com/isledecomp/isle-portable.git
synced 2024-11-26 17:36:12 -05:00
196259c6c9
Some checks failed
Build / Current ${{ matrix.toolchain.name }} (map[clang-tidy:true d3drm-from-wine:true dx5-libs:false msys-env:mingw-w64-i686 msystem:mingw32 name:msys2 mingw32 shell:msys2 {0} werror:true]) (push) Has been cancelled
Build / Current ${{ matrix.toolchain.name }} (map[clang-tidy:true d3drm-from-wine:true dx5-libs:false msys-env:mingw-w64-x86_64 msystem:mingw64 name:msys2 mingw64 shell:msys2 {0} werror:true]) (push) Has been cancelled
Build / Current ${{ matrix.toolchain.name }} (map[d3drm-from-wine:false dx5-libs:true name:MSVC (32-bit) setup-cmake:true setup-msvc:true setup-ninja:true shell:sh vc-arch:amd64_x86]) (push) Has been cancelled
Build / Current ${{ matrix.toolchain.name }} (map[d3drm-from-wine:true dx5-libs:false name:MSVC (64-bit) setup-cmake:true setup-msvc:true setup-ninja:true shell:sh vc-arch:amd64]) (push) Has been cancelled
Format / C++ (push) Has been cancelled
Naming / C++ (push) Has been cancelled
* cmake: copy DLL dependencies to output path This also copies SDL3.dll from an external path when using system dependencies. * Only include <SDL3/SDL.h> * isle: parse cli argument (--ini for custom ini path) * Use SDL_CreateWIndowWithProperties to create SDL window Less branching => Clearer code * Log mxdirectx failure using SDL_Log + E_NOINTERFACE * Fix d3drm32.def for msvc * Define D3DRM_WINE when using d3drm from wine * Ignore failed assertions from d3drm unimplemented functions * inparser will/should create libiniparser.lib for static libraries and iniparser.lib for a shared library
255 lines
6 KiB
C++
255 lines
6 KiB
C++
// TglSurface.cpp : implementation file
|
|
|
|
#include "tglsurface.h"
|
|
|
|
#include "decomp.h"
|
|
|
|
DECOMP_SIZE_ASSERT(TglSurface, 0x70);
|
|
|
|
using namespace Tgl;
|
|
|
|
#ifdef D3DRM_WINE
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
#define d3drm_wine_assert(COND) \
|
|
do { \
|
|
if (!(COND)) { \
|
|
SDL_Log( \
|
|
"%s:%d Assertion failed: \"%s\" (ignored because wine-d3d does not implement it)", \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
#COND \
|
|
); \
|
|
} \
|
|
} while (0)
|
|
#else
|
|
#define d3drm_wine_assert(X) assert(X)
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// TglSurface
|
|
|
|
// FUNCTION: LEGO1 0x100abbf0
|
|
// FUNCTION: BETA10 0x1017d490
|
|
TglSurface::TglSurface()
|
|
{
|
|
m_pRenderer = 0;
|
|
m_pDevice = 0;
|
|
m_pView = 0;
|
|
m_pScene = 0;
|
|
|
|
m_width = 0;
|
|
m_height = 0;
|
|
|
|
m_stopRendering = FALSE;
|
|
m_isInitialized = FALSE;
|
|
|
|
// statistics
|
|
m_frameCount = 0;
|
|
#ifdef _DEBUG
|
|
m_triangleCount = 0;
|
|
#endif
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100abd60
|
|
// FUNCTION: BETA10 0x1017d5a2
|
|
TglSurface::~TglSurface()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100abde0
|
|
// FUNCTION: BETA10 0x1017d647
|
|
void TglSurface::Destroy()
|
|
{
|
|
DestroyView();
|
|
|
|
delete m_pDevice;
|
|
m_pDevice = 0;
|
|
|
|
m_pRenderer = 0;
|
|
m_pScene = 0;
|
|
}
|
|
|
|
// ???
|
|
// FUNCTION: LEGO1 0x100abe10
|
|
// FUNCTION: BETA10 0x1017d6b0
|
|
int GetBitsPerPixel(IDirectDrawSurface* pSurface)
|
|
{
|
|
DDPIXELFORMAT pixelFormat;
|
|
HRESULT result;
|
|
|
|
memset(&pixelFormat, 0, sizeof(pixelFormat));
|
|
pixelFormat.dwSize = sizeof(pixelFormat);
|
|
|
|
result = pSurface->GetPixelFormat(&pixelFormat);
|
|
assert(result == DD_OK);
|
|
assert(pixelFormat.dwFlags & DDPF_RGB);
|
|
|
|
return pixelFormat.dwRGBBitCount;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100abe50
|
|
// FUNCTION: BETA10 0x1017d742
|
|
BOOL TglSurface::Create(const CreateStruct& rCreateStruct, Renderer* pRenderer, Group* pScene)
|
|
{
|
|
DeviceDirect3DCreateData createData = {rCreateStruct.m_direct3d, rCreateStruct.m_d3dDevice};
|
|
int bitsPerPixel = GetBitsPerPixel(rCreateStruct.m_pFrontBuffer);
|
|
|
|
ColorModel colorModel = Ramp;
|
|
ShadingModel shadingModel = Gouraud;
|
|
int shadeCount = 32;
|
|
BOOL dither = TRUE;
|
|
int textureShadeCount = -1;
|
|
int textureColorCount = -1;
|
|
Result result;
|
|
|
|
m_pRenderer = pRenderer;
|
|
m_pScene = pScene;
|
|
m_pDevice = m_pRenderer->CreateDevice(createData);
|
|
|
|
if (!m_pDevice) {
|
|
assert(0);
|
|
m_pRenderer = 0;
|
|
m_pScene = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
if (bitsPerPixel == 1) {
|
|
shadeCount = 4;
|
|
textureShadeCount = 4;
|
|
}
|
|
else if (bitsPerPixel == 8) {
|
|
shadeCount = 32;
|
|
shadeCount = 16;
|
|
dither = FALSE;
|
|
textureShadeCount = shadeCount;
|
|
textureColorCount = 256;
|
|
}
|
|
else if (bitsPerPixel == 16) {
|
|
shadeCount = 32;
|
|
dither = FALSE;
|
|
textureShadeCount = shadeCount;
|
|
textureColorCount = 256;
|
|
}
|
|
else if (bitsPerPixel >= 24) {
|
|
shadeCount = 256;
|
|
dither = FALSE;
|
|
textureShadeCount = 256;
|
|
textureColorCount = 64;
|
|
}
|
|
else {
|
|
dither = FALSE;
|
|
}
|
|
|
|
if (textureShadeCount != -1) {
|
|
result = pRenderer->SetTextureDefaultShadeCount(textureShadeCount);
|
|
d3drm_wine_assert(Succeeded(result));
|
|
}
|
|
if (textureColorCount != -1) {
|
|
result = pRenderer->SetTextureDefaultColorCount(textureColorCount);
|
|
d3drm_wine_assert(Succeeded(result));
|
|
}
|
|
|
|
result = m_pDevice->SetColorModel(colorModel);
|
|
assert(Succeeded(result));
|
|
result = m_pDevice->SetShadingModel(shadingModel);
|
|
assert(Succeeded(result));
|
|
result = m_pDevice->SetShadeCount(shadeCount);
|
|
d3drm_wine_assert(Succeeded(result));
|
|
result = m_pDevice->SetDither(dither);
|
|
assert(Succeeded(result));
|
|
|
|
m_width = m_pDevice->GetWidth();
|
|
m_height = m_pDevice->GetHeight();
|
|
|
|
m_pView = CreateView(m_pRenderer, m_pDevice);
|
|
if (!m_pView) {
|
|
delete m_pDevice;
|
|
m_pDevice = 0;
|
|
m_pRenderer = 0;
|
|
m_pScene = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
m_frameRateMeter.Reset();
|
|
m_renderingRateMeter.Reset();
|
|
#ifdef _DEBUG
|
|
m_triangleRateMeter.Reset();
|
|
#endif
|
|
m_frameRateMeter.StartOperation();
|
|
|
|
m_isInitialized = TRUE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100ac030
|
|
// FUNCTION: BETA10 0x1017db86
|
|
void TglSurface::DestroyView()
|
|
{
|
|
delete m_pView;
|
|
m_pView = 0;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100ac050
|
|
// FUNCTION: BETA10 0x1017dbd0
|
|
double TglSurface::Render()
|
|
{
|
|
MxStopWatch renderTimer;
|
|
|
|
if (m_isInitialized && !m_stopRendering) {
|
|
Result result;
|
|
|
|
#ifdef _DEBUG
|
|
m_triangleRateMeter.StartOperation();
|
|
#endif
|
|
m_renderingRateMeter.StartOperation();
|
|
renderTimer.Start();
|
|
|
|
result = m_pView->Render(m_pScene);
|
|
|
|
renderTimer.Stop();
|
|
assert(Succeeded(result));
|
|
m_renderingRateMeter.EndOperation();
|
|
#ifdef _DEBUG
|
|
m_triangleRateMeter.EndOperation();
|
|
#endif
|
|
m_frameRateMeter.EndOperation();
|
|
m_frameCount++;
|
|
|
|
#ifdef _DEBUG
|
|
{
|
|
#if 0
|
|
// FIXME: Tgl::Device::GetDrawnTriangleCount does not exist
|
|
unsigned long triangleCount = m_pDevice->GetDrawnTriangleCount();
|
|
#else
|
|
unsigned long triangleCount = 0;
|
|
#endif
|
|
|
|
m_triangleRateMeter.IncreaseOperationCount(triangleCount - m_triangleCount - 1);
|
|
m_triangleCount = triangleCount;
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
// reset rate meters every 20 frames
|
|
if ((++m_frameCount % 20) == 0)
|
|
#else
|
|
// reset rate meters every 4 seconds
|
|
if (m_frameRateMeter.ElapsedSeconds() > 4.0)
|
|
#endif
|
|
{
|
|
m_frameRateMeter.Reset();
|
|
m_renderingRateMeter.Reset();
|
|
#ifdef _DEBUG
|
|
m_triangleRateMeter.Reset();
|
|
#endif
|
|
}
|
|
|
|
m_frameRateMeter.StartOperation();
|
|
}
|
|
|
|
return renderTimer.ElapsedSeconds();
|
|
}
|