Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 59 additions & 96 deletions Render/RenderStub.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
// Render-backend stub for the cross-platform build.
// Where the renderer is created, and the seam the D3D9 retirement left behind.
//
// The real renderer is the D3D9 backend (Render/D3D/*.cpp), which drives
// IDirect3DDevice9 / IDirect3D9 directly and is therefore Windows-only (gated in
// Render/CMakeLists.txt). Off-Windows the fake d3d9.h only makes the render
// headers parse, not the device-creation call sites, so we provide no-op
// definitions for the render-backend symbols the rest of the engine references.
// The real cross-platform renderer is the SDL GPU backend (Track B); until then
// the game links and runs with a silent renderer.
// CreateIRenderDevice() below is the engine's one entry point into the renderer: it builds
// gb_VisGeneric and the SDL GPU device every platform now draws through. The D3D9 backend it
// replaced is retired -- Render/D3D/*.cpp is compiled nowhere, nothing assigns
// gb_RenderDevice3D, so that pointer is null for the life of the process, on Windows too.
// Every D3D name below resolves through the fake d3d9.h; there is no Direct3D in this build.
//
// Only the symbols actually referenced by the compiled (non-WIN32) sources are
// stubbed here — see the undefined-symbol set at the final Game link.
// The rest of the file is what retirement could not reach. Portable engine code still speaks
// D3D9 nouns -- cTexture::CalcTextureSize asks GetTextureFormatSize(D3DFORMAT),
// GrassMap::BuildGrass packs normals with ColorByNormalRGBA, Camera::SetRenderTarget takes an
// IDirect3DSurface9* -- and it still owns classes whose only implementation was D3D9:
// cOcclusionQuery (cObject3dx's silhouette test, the lens flare), sVideoWrite (GameShell's
// movie recorder), cVertexBufferInternal / cQuadBufferInternal (the dynamic buffer family,
// Documents/Render-PORTING.md #15). The call sites are real and have to link; these bodies are
// what they land on.
//
// Two different kinds of body, and the difference matters. The cD3DRender:: helpers are
// unreachable -- every call goes through the null gb_RenderDevice3D, so nothing runs them.
// The rest DO run, and their return values are consumed: GrassMap::BuildGrass writes
// ColorByNormalRGBA's result into every bush (so each one gets a white normal), cOcclusionQuery
// answers IsVisible() = true, GetTextureFormatSize reports 0 bits per pixel. Those are answers
// the game acts on, not silence. Before treating one as inert, check what reads it.
//
// Only the symbols the linker actually asks for are defined here. When a feature above is
// ported -- or the dead D3D9 reference sources go -- delete what goes with it; the way to find
// out what is still owed is to remove a body and relink.
#include "StdAfxRD.h"
#include "VisGeneric.h"
#include "SDLRenderDevice.h"
#include "D3DRender.h"
#include "D3DRenderTilemap.h"
#include "src/WinVideo.h"

// ---------------------------------------------------------------------------
// Globals (defined in D3DRender.cpp / RenderDevice.cpp on Windows).
// Globals. cD3DRender's constructor used to define and own these; it no longer runs
// anywhere, so gb_RenderDevice3D keeps the null it is initialised with here.
// ---------------------------------------------------------------------------
RENDER_API cInterfaceRenderDevice* gb_RenderDevice = 0;
RENDER_API cD3DRender* gb_RenderDevice3D = 0;
Expand All @@ -31,8 +46,8 @@ RENDER_API SAMPLER_DATA sampler_clamp_linear;
RENDER_API SAMPLER_DATA sampler_clamp_anisotropic;

// The six samplers the engine names when it calls SetSamplerData/SetSamplerDataVirtual.
// cD3DRender::InitSamplerConstants fills them on Windows; without this they stay zeroed
// off it, and a caller asking for sampler_wrap_linear (the selection frame's tiled centre)
// cD3DRender::InitSamplerConstants used to fill them at device init; without this they stay
// zeroed, and a caller asking for sampler_wrap_linear (the selection frame's tiled centre)
// would be asking for address mode 0, which is not a mode at all.
static void initSamplerConstants()
{
Expand Down Expand Up @@ -60,21 +75,19 @@ static void initSamplerConstants()
sampler_clamp_point.addressv = DX_TADDRESS_CLAMP;
sampler_clamp_point.addressw = DX_TADDRESS_CLAMP;

// cD3DRender rounds these to linear until SetAnisotropic(n) raises them, and nothing
// off-Windows raises them yet.
// cD3DRender rounded these to linear until SetAnisotropic(n) raised them, and nothing
// raises them now: cVisGeneric::SetAnisotropic forwards to the null gb_RenderDevice3D.
sampler_wrap_anisotropic = sampler_wrap_linear;
sampler_clamp_anisotropic = sampler_clamp_linear;
}

RENDER_API cInterfaceRenderDevice* CreateIRenderDevice(bool multiThread)
{
// Half 1 of the real CreateIRenderDevice (RenderDevice.cpp): construct the
// backend-agnostic cVisGeneric so gb_VisGeneric is non-null. Its constructor
// is pure file-IO/config (no GPU device), and VisGeneric.cpp is compiled into
// this library off-Windows, so this links and runs today.
// Half 1, unchanged from the original (RenderDevice.cpp): construct the backend-agnostic
// cVisGeneric so gb_VisGeneric is non-null. Its constructor is pure file-IO/config and
// touches no GPU device.
//
// Half 2: the cross-platform render device is the SDL GPU backend
// (cSDLRenderDevice), replacing the Windows-only cD3DRender.
// Half 2 is where the backends part: cSDLRenderDevice, not cD3DRender.
initSamplerConstants();
gb_VisGeneric = new cVisGeneric(multiThread);
return gb_RenderDevice = new cSDLRenderDevice;
Expand All @@ -89,7 +102,7 @@ ManagedResource::~ManagedResource() {}

// ---------------------------------------------------------------------------
// sPtrVertexBuffer / sPtrIndexBuffer — lifetime routes through the interface
// (mirrors the Windows D3DRender.cpp bodies), so the SDL backend owns the GPU
// (the shape the D3DRender.cpp bodies had), so the SDL backend owns the GPU
// buffers behind the slot and releases them on Destroy/dtor.
//
// The gb_RenderDevice guard matters for handles with *static storage duration*:
Expand Down Expand Up @@ -128,10 +141,10 @@ void sPtrIndexBuffer::CopyAddRef(const sPtrIndexBuffer& from)
}

// ---------------------------------------------------------------------------
// Vertex-format declaration registration. On Windows this queues (decl,elements)
// pairs for CreateVertexDeclaration at device init; off-Windows there is no D3D
// object, so we point the declaration at its immortal static element table (from
// the BEGIN_VERTEX_DECLARATION macro) so the SDL backend can read the layout.
// Vertex-format declaration registration. The D3D9 original queued (decl,elements)
// pairs for CreateVertexDeclaration at device init; there is no D3D object to create
// now, so the declaration points at its immortal static element table (from the
// BEGIN_VERTEX_DECLARATION macro) and the SDL backend reads the layout straight off it.
// The vertex::declaration statics themselves are defined by VertexDeclaration.cpp.
// ---------------------------------------------------------------------------
void cD3DRender::RegisterVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9& declaration,
Expand All @@ -146,43 +159,19 @@ void cD3DRender::RegisterVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9& declara
}

// ---------------------------------------------------------------------------
// DrawStrip / PoolManager
// ---------------------------------------------------------------------------
// DrawStrip has no off-Windows implementation: its Set() is an inline in
// DrawStrip has no implementation, deliberately. Its Set() is an inline in
// Render/D3D/VertexBuffer.h that writes straight into a locked cVertexBuffer, and there is
// no such buffer here. These bodies exist only so the class still links -- and they leave
// `buf` null and `pointer` uninitialised, so the first Set() writes through a garbage
// pointer. Every off-Windows caller therefore takes SDLWorldQuadRenderer's triangle route
// instead (cUnkLight::Draw, CircleManager::Layer::drawSpline, Lighting::OneLight::Draw);
// the assert is here to catch a new one before it corrupts the heap.
void DrawStrip::Begin() { xassert(0 && "DrawStrip is Windows-only: use SDLWorldQuadRenderer"); }
void DrawStrip::End() {}

PoolManager::PoolManager() {}
PoolManager::~PoolManager() {}

// Pool hierarchy (D3D/PoolManager.cpp): defining Pool's virtual dtor (key
// function) emits its vtable+typeinfo; VertexPool/IndexPool define their full
// override set so their vtables resolve when constructed.
Pool::Pool() : total_pages(0), free_pages(0), free_pages_list(0), parameter(0) {}
Pool::~Pool() {}

VertexPool::VertexPool() : vb(0), page_size(0), vertex_declaration(0), vertex_size(0) {}
VertexPool::~VertexPool() {}
void VertexPool::Create(const PoolParameter*) {}
void VertexPool::Select(int) {}
void* VertexPool::LockPage(int) { return 0; }
void VertexPool::UnlockPage(int) {}
void VertexPool::GetUsedMemory(int& total, int& free) { total = 0; free = 0; }
void* VertexPool::InternalLockPage(int) { return 0; }

IndexPool::IndexPool() : ib(0), page_size(0) {}
IndexPool::~IndexPool() {}
void IndexPool::Create(const PoolParameter*) {}
void IndexPool::Select(int) {}
void* IndexPool::LockPage(int) { return 0; }
void IndexPool::UnlockPage(int) {}
void IndexPool::GetUsedMemory(int& total, int& free) { total = 0; free = 0; }
// no such buffer here: a body would leave `buf` null and `pointer` uninitialised, so the
// first Set() would write through a garbage pointer. Every caller takes
// SDLWorldQuadRenderer's triangle route instead (cUnkLight::Draw,
// CircleManager::Layer::drawSpline, Lighting::OneLight::Draw), and a new one now fails at
// link time rather than corrupting the heap at run time.
//
// PoolManager / Pool / VertexPool / IndexPool (the D3D9 tilemap's page allocator), DrawType
// and cTileMapRender were stubbed here for the same reason and are not stubbed any more:
// nothing left in the build references them. They live on in Render/D3D/, which is compiled
// nowhere.
// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
// Render free functions (D3D/*.cpp): logging, format/size queries, debug stats.
Expand Down Expand Up @@ -217,8 +206,8 @@ void cQuadBufferInternal::EndDraw() {}
void* cQuadBufferInternal::Get() { return 0; }
void cQuadBufferInternal::SetMatrix(const MatXf& /*m*/) {}

// cSkinVertex (ctor / GetWeight / GetDeclaration / declaration[] / Register) is
// defined by VertexDeclaration.cpp, which is now compiled off-Windows too.
// cSkinVertex (ctor / GetWeight / GetDeclaration / declaration[] / Register) is not stubbed:
// VertexDeclaration.cpp is real, portable, and in the build.

// ---------------------------------------------------------------------------
// cOcclusionQuery
Expand All @@ -235,44 +224,18 @@ void cOcclusionQuery::Begin() {}
void cOcclusionQuery::End() {}

// ---------------------------------------------------------------------------
// DrawType (abstract; only these non-virtual members are referenced — DrawType
// itself is never constructed off-Windows, so no vtable is needed).
// ---------------------------------------------------------------------------
void DrawType::BeginDraw() {}
void DrawType::SetTileColor(Color4f /*color*/) {}

// ---------------------------------------------------------------------------
// cTileMapRender (polymorphic via ManagedResource; defining the destructor
// emits its vtable + typeinfo, so the pure-virtual overrides are defined too).
// ---------------------------------------------------------------------------
cTileMapRender::cTileMapRender(cTileMap* /*pTileMap*/) {}
cTileMapRender::~cTileMapRender() {}
void cTileMapRender::deleteManagedResource() {}
void cTileMapRender::restoreManagedResource() {}
void cTileMapRender::dumpManagedResource(XBuffer& /*buffer*/) {}
void cTileMapRender::PreDraw(Camera* /*camera*/) {}
void cTileMapRender::DrawBump(Camera* /*camera*/, eBlendMode /*MatMode*/, bool /*shadow*/, bool /*zbuffer*/) {}

// ---------------------------------------------------------------------------
// cD3DRender — the helper (non-virtual) methods called from compiled code.
// cD3DRender — the helper (non-virtual) methods still named by compiled code.
// Every call reaches them through the permanently null gb_RenderDevice3D, so none of
// these bodies ever runs; they exist so those call sites link. Only the methods the
// linker actually asks for are here — the rest of cD3DRender's helpers went with the
// pools above.
// ---------------------------------------------------------------------------
void* cD3DRender::LockTexture(cTexture* /*Texture*/, int& /*Pitch*/) { return 0; }
void* cD3DRender::LockTexture(cTexture* /*Texture*/, int& /*Pitch*/, Vect2i /*lock_min*/, Vect2i /*lock_size*/) { return 0; }
void cD3DRender::UnlockTexture(cTexture* /*Texture*/) {}
void cD3DRender::DrawQuad(float, float, float, float, float, float, float, float, Color4c) {}
Mat4f cD3DRender::shadowMatBias() const { return Mat4f(); }
bool cD3DRender::createRenderTargets(int /*xysize*/) { return false; }
void cD3DRender::deleteRenderTargets() {}
bool cD3DRender::CreateFloatTexture(int /*width*/, int /*height*/) { return false; }
void cD3DRender::CreateMirageMap(int /*x*/, int /*y*/, bool /*recreate*/) {}
void cD3DRender::SetAdvance(bool /*is_shadow*/) {}
void cD3DRender::SetAnisotropic(int /*level*/) {}
int cD3DRender::GetAnisotropic() { return 0; }
int cD3DRender::GetMaxAnisotropicLevels() { return 0; }
void cD3DRender::SetBlendState(eBlendMode /*blend*/) {}
void cD3DRender::SetBlendStateAlphaRef(eBlendMode /*blend*/) {}
void cD3DRender::SetRenderTarget(cTexture* /*target*/, IDirect3DSurface9* /*pZBuffer*/) {}
void cD3DRender::SetRenderTarget1(cTexture* /*target1*/) {}
void cD3DRender::RestoreRenderTarget() {}
void cD3DRender::FlushPrimitive3DWorld() {}
bool cD3DRender::ReinitOcclusion() { return false; }
Expand Down
Loading