render parity unit G: 40250 tiling selection + verbatim STP terrain

- PythonApplication::Create mirrors 40250 :1196-1251 (SOFTWARE_TILING cfg,
  auto tiling IsFastTNL ? HTP : STP, MinLOD on !IsFastTNL)
- RecordingDevice caps: VertexShaderVersion 1.1 + CLIPTLVERTS (fast T&L -> HTP)
- MapOutdoorRenderSTP.cpp replaced by the full 40250 source (native gate only)
- native_render XYZRHW: fix inverted screen->NDC Y, negative rhw clip,
  no texture transform on TL vertices, specular-alpha vertex fog (capture v9)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-28 13:54:11 +09:00
co-authored by Claude Opus 5.5
parent 91ce13c3cf
commit 863f3771af
10 changed files with 864 additions and 66 deletions
+6 -3
View File
@@ -23,11 +23,12 @@
// - Version 8: eight lights, back-buffer clear entries, viewport MinZ/MaxZ, border color,
// TEXCOORDINDEX / TEXTURETRANSFORMFLAGS / D3DTS_TEXTUREn per stage, emissive
// material source, NORMALIZENORMALS and LOCALVIEWER; UVs are raw vertex sets.
// - Version 9: adds XYZRHW vertex fog (specular alpha).
// Capture is opt-in and never runs in the normal game path.
namespace native_draw_capture {
struct Capture {
std::uint32_t version = 8;
std::uint32_t version = 9;
std::vector<Render3DDraw> draws;
std::unordered_map<std::string, std::vector<std::uint8_t>> textures;
std::uint32_t ui_width = 960;
@@ -113,7 +114,7 @@ inline void write(
std::ofstream file(path, std::ios::binary | std::ios::trunc);
if (!file) throw std::runtime_error("cannot create native draw capture: " + path);
const std::uint32_t magic = 0x4d544452; // MTDR
const std::uint32_t version = 8;
const std::uint32_t version = 9;
const auto count = static_cast<std::uint32_t>(draws.size());
write_scalar(file, magic); write_scalar(file, version); write_scalar(file, count);
for (const auto& draw : draws) {
@@ -188,6 +189,7 @@ inline void write(
write_scalar(file, draw.emissive_material_source);
write_scalar(file, draw.normalize_normals);
write_scalar(file, draw.local_viewer);
write_vector(file, draw.vertex_fog);
write_vector(file, draw.bone_indices);
write_vector(file, draw.bone_weights);
write_vector(file, draw.bone_matrices);
@@ -237,7 +239,7 @@ inline Capture read_capture(const std::string& path) {
if (!file) throw std::runtime_error("cannot open native draw capture: " + path);
std::uint32_t magic = 0, version = 0, count = 0;
read_scalar(file, magic); read_scalar(file, version); read_scalar(file, count);
if (magic != 0x4d544452 || (version < 1 || version > 8) || count > 10'000)
if (magic != 0x4d544452 || (version < 1 || version > 9) || count > 10'000)
throw std::runtime_error("unsupported native draw capture format");
Capture capture;
capture.version = version;
@@ -328,6 +330,7 @@ inline Capture read_capture(const std::string& path) {
read_scalar(file, draw.emissive_material_source);
read_scalar(file, draw.normalize_normals);
read_scalar(file, draw.local_viewer);
if (version >= 9) read_vector(file, draw.vertex_fog);
} else if (draw.light0) {
auto& light = draw.lights[0];
light.type = 3;