The phone magnifies the 600-high 40250 UI about 1.8x, so the 1x window art
and icons look soft next to the oversampled text. scripts/build_hd_ui.py
upscales every UI image the zh client loads (d:/ymir work/ui/, icon/,
locale/zh/) with realesrgan-x4plus, reduces it to 2x and back-projects the
residual so the board grain the network denoises away comes back; the host
uploads a texture found in hd_ui.pak in place of the pack file. Layout,
sizes and UVs stay the engine's 1x ones. MT_HD_UI=0 disables it; the pak
(135 MB, Ymir art) is built into the client dir and synced to the phone,
never committed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
40250 runs CPythonApplication::Process every 16/17 ms and only skips the
render when late, so GamePhase gets its three-packets-a-poll budget 60
times a second. The host polled once per rendered frame: at 30 fps idle
(or a slow phone) mob move packets queued behind character add/del
bursts for up to a second and mobs stopped, then jumped. Poll once per
elapsed 60 Hz tick. Real-server A/B: move push gap p50 138-178 -> 70-92
ms, p90 580-785 -> 358-403 ms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both units are the 40250 bodies; only the PDT-stream draw becomes
UIRenderAddImage (with the rendering mode). SCREEN/COLOR_DODGE were packed as
0x28 (INVDESTALPHA+ONE); 40250 uses INVDESTCOLOR+ONE (0x2A). OnIsType calls the
base OnIsType instead of 40250's recursing IsType. port.grp_resource covers the
quads, UVs, colour and blend mode.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-fno-strict-aliasing on the port targets: 40250 relies on MSVC's lack of
type-based alias analysis (DXTCImage reads Color8888 through DWORD*).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Host-side window records + message queue; WM_SIZE/WM_MOVE/WM_DESTROY sent
synchronously as Win32 does; PostQuitMessage also queues WM_QUIT. 64-bit
pointer casts ADAPTED. port.ms_window.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TextBar and DibBar verbatim over the FreeType GDI shim (+GetTextExtentPoint32A);
BlockTexture verbatim except Render, which records the clipped quad as a UI
image of the device CPU texture (UIRenderAddImageNamed). Notices now render;
port.text_bar covers block split, pixels, colour, ClearBar and TipBoard clip.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
port.grp_math pins the 40250 conventions: D3DXVec3Rotation applies the
inverse rotation, GetRotationFromMatrix returns negated Z*X*Y angles, and
CGraphicColor defaults to opaque white.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds CreateSemaphore/ReleaseSemaphore/WaitForSingleObject/CloseHandle/
SetThreadPriority/_beginthreadex to Win32Crt; port.file_loader_thread covers
the shims, CThread and both the un-Created (40250 live) and Created loader.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CPythonGraphic::SaveScreenShot queues a readback of the next presented
frame (ScreenShotHost -> VulkanWindow::request_frame); WriteScreenShot runs
the rest of 40250's function verbatim (X8R8G8B8 rows, SaveJPEG, EXIF tag).
jpeg_save is encoded with stb_image_write. SHGetSpecialFolderPath returns
$HOME/Documents (else cwd); CreateDirectory/_access/jpeg_save accept '\\'.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The CSpeedTreeRT stand-in now returns the collision objects stored in
the .spt (12000 section: spheres and cylinders) instead of one fixed trunk
cylinder, and takes leaf texture rects from the 10000 section instead of
hand-picked atlas rects (trees without leaf maps use the frond rect).
SpeedGrass/BoundaryShapeManager are N_A (no 40250 caller).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copy SoundBase/SoundData/SoundInstance*/SoundManager*/Type from 40250 and
implement the AIL_* calls they make in MilesAil.cpp (2D pan, 3D distance and
listener pan, threaded stream decode, loop counts). The SDL host drains the
mixer. CSoundManager is created/updated/destroyed where 40250 does it and the
old AudioCommands bridge is removed. Port-map MilesLib 142/142 PORTED.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DXT DDS textures upload the file's own mip levels like 40250
CGraphicImageTexture::CreateDDSTexture (max(1, dwMipMapCount), level i read
at sum(dwLinearSize>>2k), Copy of dwLinearSize>>2i bytes) instead of a
regenerated chain. Non-DDS images keep the D3DX_DEFAULT full chain and mem:
textures get one level. The invented is_ui_tex no-mip rule (icon/, ui/,
locale/, <=128px) is deleted. dxt_decode_test is registered in ctest with
mip-level cases.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Process now runs 40250's render-time / face-count block and sets view
distance set 0 each frame (25600 under 5000 faces, else scaled by render
time, or the forced range). SetForceSightRange and SkipRenderBuffering are
ported from stubs; the invented SetCursorPosition in UpdateGame is removed.
Port-map boilerplate notes replaced; Destroy recorded as DIVERGENT.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SetGamma, RenderCoolTimeBox, RenderUp/DownButton and GetAvailableMemory are
transliterated from 40250 in place of stubs. The cooldown fan is emitted as
untextured polygon UI commands (native_render + python_ui_surface.gd draw
Bar+quad as a polygon); D3D8 shim gains SetGammaRamp/D3DGAMMARAMP.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MapOutdoorRenderHTP.cpp is the full 40250 source behind the native-terrain
gate: no invented texture-0 fallback, first-splat stage-1 ALPHAOP DISABLE,
GetNumTextures() bound, 40250 shadow-pass states (FOGCOLOR white, CLAMP,
TEXTURE1 m_matDynamicShadow). Fixes the white far-terrain band.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the platform_stub skeleton (every member unimplemented) with the 40250 source, so
guild marks in text tails and mark boxes load and draw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Delete the platform proxy tree renderer and copy SpeedTreeWrapper, SpeedTreeForest,
SpeedTreeForestDirectX8, SpeedTreeConfig.h and VertexShaders.h from 40250. The SDK
SpeedTreeRT.h public API becomes the shim; the closed CSpeedTreeRT is reimplemented in
platform/SpeedTreeLib/SpeedTreeRT.cpp (procedural geometry, static lighting, single LOD,
DIVERGENT). Shims gain the D3D8 vertex shader declaration tokens, D3D_OK,
CreateVertexShader/DeleteVertexShader, ID3DXBuffer/D3DXAssembleShader, MessageBox and
__min/__max.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replaces the platform_stub skeleton with the 40250 source and mirrors
m_LightManager.Initialize() from 40250 PythonApplication.cpp:1263.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Texture coordinates: TEXCOORDINDEX generation (camera-space normal /
position / reflection vector, LOCALVIEWER) and D3DTS_TEXTUREn under
TEXTURETRANSFORMFLAGS (incl. PROJECTED) now run in native.vert; the
RecordingDevice CPU uv baking and the sphere-map / multiplicative-shadow
shader hacks are removed. Godot consumer uses Render3DStageTexcoords.
- Lighting: 8 D3D lights in camera space, 1/(a0+a1d+a2d^2) without clamp,
spot cone theta/2 phi/2 with falloff, diffuse/ambient/emissive material
sources, NORMALIZENORMALS, inverse-transpose normal matrix.
- Alpha test compares 8-bit alpha against ALPHAREF with ALPHAFUNC.
- Back-buffer Clear() is recorded in draw order and executed with
vkCmdClearAttachments; render pass clears to 0xff000000.
- D3DVIEWPORT8 (incl. MinZ/MaxZ) is dynamic per-draw state.
- Missing vertex diffuse is opaque white; alpha blend mirrors SRC/DESTBLEND.
- CScreen::ms_clearDepth / ms_diffuseColor initialised to 40250's
1.0f / 0xffffffff (were zero; exposed once clears were executed).
- Capture format v8; --screenshot-out FILE.bmp swapchain readback.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>