Files
metin2-client/src/platform/EterLib/UIRenderCommands.h
T
2026-09-30 16:13:31 -07:00

90 lines
4.6 KiB
C++

#pragma once
#include <cstdint>
#include <string>
#include <vector>
// 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 <class Color>
std::uint32_t UIRenderColor(const Color& color) {
auto channel = [](float value) -> std::uint32_t {
return static_cast<std::uint32_t>((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:<id>@<revision>", 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:<id>" (the part of the name before '@'), as 0xAARRGGBB.
struct UIMemoryTexture {
int width = 0;
int height = 0;
std::uint32_t revision = 0;
std::vector<std::uint32_t> 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);
// The same quad for a texture named as UIRenderTextureNameFromHandle (a raw device texture: CBlockTexture).
void UIRenderAddImageNamed(const std::string& texture_name, 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<UIRenderCommand>& UIRenderCommands();
void UIRenderSetClip(float x, float y, float width, float height);
// PORT (mobile safe area): shifts the commands (and clips) recorded after it right by x canvas
// pixels, so the 40250 window layers can sit inside the rounded screen corners while the GAME layer
// (3D world, text tails) keeps the full canvas. 0 is the verbatim 40250 path.
void UIRenderSetOffsetX(float x);
float UIRenderOffsetX();
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. Changing the scale between
// AppFrame steps rebuilds existing pages without invalidating cached glyph pointers.
void UISetFontOversample(int scale);
int UIFontOversample();