yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
menu_tilemap_sources.h
Go to the documentation of this file.
1#ifndef YAZE_APP_ZELDA3_SCREEN_MENU_TILEMAP_SOURCES_H
2#define YAZE_APP_ZELDA3_SCREEN_MENU_TILEMAP_SOURCES_H
3
4#include <array>
5#include <cstddef>
6#include <cstdint>
7#include <optional>
8#include <string>
9#include <string_view>
10#include <vector>
11
12#include "absl/status/statusor.h"
14
15namespace yaze {
16class Rom;
17namespace emu::debug {
18class SymbolProvider;
19}
20} // namespace yaze
21
22namespace yaze::zelda3 {
23
24struct GameData;
25
26// --- Palette sources (menu_tilemap.h's ComposeMenuTilemapRgba() wants a
27// 32-entry std::array<gfx::SnesColor, 32> indexed by [subpalette*4+color])
28// ---------------------------------------------------------------------
29
30// Source (a): 32 SNES colors read from a ROM symbol's address, applying
31// the menu upload's CGRAM +1 offset. Oracle of Secrets' Menu_UploadLeft
32// copies its 32-word Menu_Palette table to CGRAM starting at color 1 (not
33// color 0), so table[i] lands on CGRAM color i+1: sub-palette p, color c
34// (c=1..3) = table[p*4 + c - 1]; color 0 of every sub-palette is always
35// transparent and is intentionally never read from the table (see
36// docs/public/usage/screen-editor.md for the derivation).
37//
38// IMPORTANT (Oracle of Secrets specifically): labels like
39// "Oracle_Menu_Palette" are produced by asar assembling the ASM sources
40// (Menu/menu_palette.asm et al.) and only exist in the *patched* ROM
41// (oos168x.sfc in the two-ROM build pipeline), not in the "clean" base
42// ROM that a yaze project normally points at (oos168.sfc, where
43// ZScream/yaze-authored room/overworld/graphics data lives). If `rom` is
44// the base ROM, the resolved address typically reads back all zero bytes;
45// this function detects that case and returns a descriptive error instead
46// of silently returning a black palette, naming the label and suggesting
47// the patched ROM or an explicit CGRAM dump / .pal file source instead.
48absl::StatusOr<std::array<gfx::SnesColor, 32>> ResolveMenuPaletteFromSymbol(
49 const Rom& rom, const emu::debug::SymbolProvider& symbols,
50 const std::string& label);
51
52// Source (b): palette_groups.hud[0], the 32-color HUD palette group
53// GameData already loads from the base ROM. This is vanilla ALTTP's HUD
54// palette (or whatever static replacement a project has written into
55// that ROM location via yaze/ZScream); Oracle's *runtime* HUD palette
56// patches at $1BD662 etc. are ASM-only and are not reflected here.
57absl::StatusOr<std::array<gfx::SnesColor, 32>> ResolveMenuPaletteFromHud(
58 const GameData& game_data);
59
60// Source (c): a raw CGRAM dump (512 bytes = 256 SNES colors) or a plain
61// .pal file (concatenated little-endian 16-bit SNES color words). Reads
62// 32 colors starting at `byte_offset` (default 2, i.e. CGRAM color 1 --
63// the first color menu uploads actually land on, matching the +1 offset
64// used by ResolveMenuPaletteFromSymbol so swapping sources doesn't shift
65// the palette).
66absl::StatusOr<std::array<gfx::SnesColor, 32>> ResolveMenuPaletteFromFile(
67 const std::string& path, size_t byte_offset = 2);
68
69// Source (d): Oracle of Secrets' Menu/menu_palette.asm parsed directly, so
70// the palette is available even when the project ROM is the *base* ROM
71// (oos168.sfc), where the assembled Menu_Palette table reads all zero
72// (see the note on source (a)). Same +1 CGRAM mapping as source (a).
73//
74// Accepted grammar after the `Menu_Palette:` label (CRLF or LF, `;`
75// comments, blank lines, one or several comma-separated operands per
76// `dw`):
77// dw hexto555($RRGGBB) -> Hexto555() (menu_palette.asm's macro)
78// dw $XXXX / 0xXXXX / N -> that raw 16-bit BGR555 word
79// The table ends at the first line that is not a `dw`, blank or comment,
80// or after 32 entries. At least 31 are required (8 sub-palettes x 3
81// colors + the unused final slot; the real file defines exactly 31).
82// Errors carry the 1-based line number ("line N: ...").
83
84// $RRGGBB -> SNES BGR555, exactly menu_palette.asm's
85// function hexto555(h) = (((h&$FF)/8)<<10)|(((h>>8&$FF)/8)<<5)|
86// (((h>>16&$FF)/8)<<0)
87// i.e. each 8-bit channel is divided by 8 (floor) and packed B<<10 | G<<5
88// | R. Example: $814f16 -> 0x0930, $f9f9f9 -> 0x7FFF.
89uint16_t Hexto555(uint32_t rgb);
90
91// Pure text parser (no I/O) for the table under `label` (default
92// "Menu_Palette"). Returns the raw BGR555 words (31 or 32 of them).
93absl::StatusOr<std::vector<uint16_t>> ParseMenuPaletteAsmText(
94 std::string_view text, std::string_view label = "Menu_Palette");
95
96// Reads `path` and applies ParseMenuPaletteAsmText(). If `label` starts
97// with "Oracle_" (the symbol-file spelling, e.g. "Oracle_Menu_Palette")
98// and is not found, retries with that prefix stripped, so one label
99// field can drive both this source and the symbol source. Parse errors
100// are prefixed with the file path ("<path>: line N: ...").
101absl::StatusOr<std::array<gfx::SnesColor, 32>> ResolveMenuPaletteFromAsm(
102 const std::string& path, const std::string& label = "Menu_Palette");
103
104// Looks for `Menu/menu_palette.asm` under a project: first
105// <project_dir>/Menu/, then <project_dir>/<code_folder>/Menu/ (if
106// code_folder is set and relative; an absolute code_folder is tried as
107// is). Returns the first existing regular file.
108std::optional<std::string> FindMenuPaletteAsm(
109 const std::string& project_dir, const std::string& code_folder = "");
110
111// --- CHR (tile graphics) sources ---------------------------------------
112
113// Source (a), default: the ROM's 2bpp sheets the game puts in BG3 while
114// the item/menu screen is open (zelda3::Load2BppGraphics: sheets 0x71,
115// 0x72, 0xDA-0xDE, concatenated into 128-tile chunks). These are
116// ZScream/yaze-managed compressed graphics sheets, not ASM-injected, so
117// (unlike the palette symbol above) they are present in Oracle of
118// Secrets' base ROM (oos168.sfc) as well as the patched one.
119absl::StatusOr<std::vector<uint8_t>> ResolveMenuChrFromRom(const Rom& rom);
120
121// Source (b): a raw 2bpp .bin chr file or VRAM dump, decoded into the
122// same 128-tile-chunk layout as ResolveMenuChrFromRom() so both can be
123// used interchangeably with zelda3::MakeChrPixelFn().
124absl::StatusOr<std::vector<uint8_t>> ResolveMenuChrFromFile(
125 const std::string& path);
126
127} // namespace yaze::zelda3
128
129#endif // YAZE_APP_ZELDA3_SCREEN_MENU_TILEMAP_SOURCES_H
Zelda 3 specific classes and functions.
absl::StatusOr< std::array< gfx::SnesColor, 32 > > ResolveMenuPaletteFromHud(const GameData &game_data)
uint16_t Hexto555(uint32_t rgb)
absl::StatusOr< std::array< gfx::SnesColor, 32 > > ResolveMenuPaletteFromFile(const std::string &path, size_t byte_offset)
absl::StatusOr< std::vector< uint8_t > > ResolveMenuChrFromRom(const Rom &rom)
std::optional< std::string > FindMenuPaletteAsm(const std::string &project_dir, const std::string &code_folder)
absl::StatusOr< std::vector< uint16_t > > ParseMenuPaletteAsmText(std::string_view text_in, std::string_view label_in)
absl::StatusOr< std::vector< uint8_t > > ResolveMenuChrFromFile(const std::string &path)
absl::StatusOr< std::array< gfx::SnesColor, 32 > > ResolveMenuPaletteFromAsm(const std::string &path, const std::string &label)
absl::StatusOr< std::array< gfx::SnesColor, 32 > > ResolveMenuPaletteFromSymbol(const Rom &rom, const emu::debug::SymbolProvider &symbols, const std::string &label)