#pragma once #include #include #include #include namespace PSXRecompV4 { // Language-independent authoring data. Stable IDs identify a message's role; // original text and source digest detect stale adapters/catalogs independently. struct NativeTextEntry { std::string id, original, translation, source_sha256; }; class NativeTextCatalog { public: bool load(const std::string& json, const std::string& language, std::string& error); const NativeTextEntry* find(const std::string& id) const; const std::map& entries() const { return entries_; } private: std::map entries_; }; using NativeGlyphMap = std::map; bool native_text_utf8(const std::string& text, std::vector& codepoints, std::string& error); struct NativeTextLayout { uint32_t columns=20, rows=3; uint16_t space=0, line_end=0, page_end=0, text_end=0; uint16_t style=0, progressive=0; }; // Encodes into the original game's glyph/control codes. Wraps at word // boundaries; pages are explicit \f or generated when the native box fills. // Unsupported glyphs and overlong words fail, never silently lose accents. bool native_text_encode(const std::string& text, const NativeGlyphMap& glyphs, const NativeTextLayout& layout, std::vector& words, std::string& error); // Native 4-bpp indexed atlas. New Latin glyphs copy the source font's cells, // including its palette indices and outline; marks use that font's own ink. // Destination cells must be blank. No host font or presentation overlay. struct NativeFontAtlas { uint32_t width=256,height=256,cell_width=16,cell_height=16; std::vector packed; }; enum class NativeGlyphMark { Acute, Tilde, Diaeresis, Inverted, Grave, Circumflex, Cedilla }; // omit_top_rows is an adapter-provided crop of the copied glyph, for example // to remove i's dot before composing í. The source atlas cell is preserved. bool native_font_compose(NativeFontAtlas& atlas, uint16_t base, uint16_t destination, NativeGlyphMark mark, std::string& error, uint32_t omit_top_rows=0); } // namespace PSXRecompV4