#pragma once #include #include #include // Commands emitted by the 40250 UI drawing calls, consumed by Godot's CanvasItem. // The port layer stays independent of godot-cpp. struct UIRenderCommand { enum Kind { Bar, Line, Text, Image, GradientBar } kind; float x1, y1, x2, y2; std::uint32_t argb; std::uint32_t end_argb = 0; // GradientBar only: colour on the bottom edge. float clip_x1 = 0, clip_y1 = 0, clip_x2 = 0, clip_y2 = 0; std::string text; // Image only: text is the texture's file, drawn as the quad (vertices 0..3 = TL, TR, BL, BR) // with texture coordinates su,sv..eu,ev; x1..y2 is the quad's bounding box. bool quad = false; float qx[4] = {}, qy[4] = {}; float su = 0, sv = 0, eu = 1, ev = 1; int blend = 0; // CGraphicExpandedImageInstance::RENDERING_MODE_* // A second texture stage that modulates the colour and replaces the alpha (40250 CPythonMiniMap's // circular minimap_image_filter): the mask's texture coordinates at the quad's four corners. std::string mask; float mu[4] = {}, mv[4] = {}; bool behind_3d = false; }; // D3DXCOLOR (0..1 floats) -> the 0xAARRGGBB the commands carry. template std::uint32_t UIRenderColor(const Color& color) { auto channel = [](float value) -> std::uint32_t { return static_cast((value < 0 ? 0 : value > 1 ? 1 : value) * 255.0f + 0.5f); }; return (channel(color.a) << 24) | (channel(color.r) << 16) | (channel(color.g) << 8) | channel(color.b); } class CGraphicTexture; // A file-backed texture is named by its pack path; a memory texture (CGraphicImageTexture::Create, // filled through Lock/Unlock: the CGraphicFontTexture glyph pages) by "mem:@", the // revision counting Unlocks so the canvas knows when to fetch the pixels again. std::string UIRenderTextureName(const CGraphicTexture* texture); // The pixels of memory texture "mem:" (the part of the name before '@'), as 0xAARRGGBB. struct UIMemoryTexture { int width = 0; int height = 0; std::uint32_t revision = 0; std::vector argb; }; bool UIRenderMemoryTexture(const std::string& name, UIMemoryTexture* out); struct IDirect3DTexture8; struct IDirect3DBaseTexture8; // Frees the platform texture behind a CGraphicTexture: a memory texture or a file texture's handle. void UIRenderReleaseMemoryTexture(IDirect3DTexture8* texture); // The name (as UIRenderTextureName) of the texture a D3D handle belongs to; "" for null or unknown. std::string UIRenderTextureNameFromHandle(const IDirect3DBaseTexture8* handle); std::string MtCpuTextureNameFromHandle(const IDirect3DBaseTexture8* handle); bool MtCpuMemoryTexture(const std::string& name, UIMemoryTexture* out); // A textured quad from 40250's TPDTVertex[4] (TL, TR, BL, BR) positions and texture coordinates. // PORT: D3D8 puts pixel centres on integers, which is why 40250 subtracts 0.5 from every vertex; the // Godot canvas puts them on .5, so the quad is shifted back by +0.5 here. void UIRenderAddImage(const CGraphicTexture* texture, const float x[4], const float y[4], float su, float sv, float eu, float ev, std::uint32_t argb, int blend = 0); void UIRenderSetSize(int width, int height); void UIRenderGetSize(unsigned* width, unsigned* height); void UIRenderBeginFrame(); std::uint64_t UIRenderFrameId(); void UIRenderAdd(UIRenderCommand command); const std::vector& UIRenderCommands(); void UIRenderSetClip(float x, float y, float width, float height); void UIRenderRestoreClip(); // HiDPI text: CGraphicFontTexture rasterises its glyph pages at this multiple of the logical font // size (the swapchain's pixels per UI pixel) while keeping the 40250 glyph metrics and page UVs in // logical pixels. 1 (the default) is the verbatim 40250 path. Latched when the first font page is // created, so set it before the game creates fonts. void UISetFontOversample(int scale); int UIFontOversample();