Torch
Loading...
Searching...
No Matches
ConfigFactory.h
1#pragma once
2
3#include <cstdint>
4#include <filesystem>
5#include <string>
6#include <vector>
7#include <yaml-cpp/yaml.h>
8
9namespace BK64 {
10
11// Classification of a >16MB BK ROM.
12enum class RomhackKind {
13 NotRomhack, // vanilla-sized ROM
14 BBRomhack, // standard Banjo's Backpack build
15 CustomBuild, // BK boot overlay present, but rebuilt/relocated internals
16 UnknownRom, // extended ROM with no recognizable BK boot overlay
17};
18
19// Binary aGameConfig format: 'BKCF' header + typed sections
20
21constexpr uint32_t GAMECONFIG_MAGIC = 0x46434B42;
22constexpr uint16_t GAMECONFIG_VERSION = 1;
23// Its entry in modding.yml, and with .yaml its file in the modding folder.
24constexpr const char* GAMECONFIG_MODDING_NAME = "assets/aGameConfig";
25
26enum class ConfigSectionType : uint16_t {
27 CODE_CONSTANTS = 1,
28 SCENE_REMAP = 2,
29 RETURN_TO_LAIR = 3,
30 MUSIC = 4,
31 SKYBOX = 5,
32 SCENE_DEF = 6,
33 NOTE_DOORS = 7,
34 JIGGY_PUZZLES = 8,
35 LEVEL_NAMES = 9,
36 WARP_DESTINATIONS = 10,
37 CUSTOM_CODE = 11,
38 ROM_HASH = 12,
39 CUSTOM_CODE_INFO = 13,
40};
41
42enum class CustomCodeKind : uint16_t {
43 NONE = 0,
44 BB_GLOBALIZATION = 1,
45 BB_INJECTED = 2,
46};
47
48// CODE_CONSTANTS key IDs - they index into the sBBConfigs table.
49enum class CodeConstantKey : uint16_t {
50 NEW_GAME_MAP = 0,
51 START_LEVEL_1,
52 START_LEVEL_2,
53 KNOW_ALL_MOVES,
54 MUMBO_COST_TERMITE,
55 MUMBO_COST_CROC,
56 MUMBO_COST_WALRUS,
57 MUMBO_COST_PUMPKIN,
58 MUMBO_COST_BEE,
59 EGGS_NORMAL_MAX,
60 RED_FEATHERS_NORMAL_MAX,
61 GOLD_FEATHERS_NORMAL_MAX,
62 EGGS_CHEATO_MAX,
63 RED_FEATHERS_CHEATO_MAX,
64 GOLD_FEATHERS_CHEATO_MAX,
65 NOTES_MAX,
66 JIGGIES_PER_WORLD,
67 HONEYCOMBS_PER_WORLD,
68 EXTRA_HC_START,
69 WARP_EXIT_BANJOS_HOUSE,
70 WARP_ENTER_LAIR,
71 SPECIAL_LEVEL,
72 HIDE_JIGGIES_LEVEL,
73 HIDE_COLLECTIBLES_LEVEL,
74 COUNT
75};
76
77// Vanilla BK is exactly 16MB. Anything bigger has been through Banjo's Backpack.
78inline bool IsRomhack(const std::vector<uint8_t>& rom) {
79 return rom.size() > 0x1000000;
80}
81
82// The aGameConfig blob read back out. Each table keeps its entries in blob order, so writing one back
83// gives the same bytes.
85 struct Constant {
86 uint16_t key;
87 uint16_t value;
88 };
89 struct WorldMap {
90 uint16_t map;
91 uint16_t level;
92 };
93 struct LairReturn {
94 uint8_t world;
95 uint16_t map;
96 uint16_t exit;
97 };
98 struct Music {
99 uint16_t map;
100 uint16_t track;
101 uint16_t alternate;
102 };
103 struct SkyLayer {
104 int16_t model;
105 float scale;
106 float spin; // degrees per second
107 };
108 struct Sky {
109 uint16_t map;
110 SkyLayer layers[3];
111 };
112 struct LevelModels {
113 uint16_t map;
114 int16_t opaque;
115 int16_t translucent;
116 int16_t cubeMin[3];
117 int16_t cubeMax[3];
118 float scale;
119 };
120 struct Title {
121 uint8_t index;
122 std::string text;
123 };
124 struct Warp {
125 uint16_t warp;
126 uint16_t dest; // map << 8 | entrance
127 };
128 struct NoteDoor {
129 uint8_t door;
130 uint16_t notes;
131 };
132 struct Puzzle {
133 uint8_t picture;
134 uint8_t cost;
135 uint8_t size;
136 uint16_t flag;
137 };
138
139 std::string romName;
140 std::vector<Constant> constants;
141 std::vector<WorldMap> worldByMap;
142 std::vector<LairReturn> returnToLair;
143 std::vector<Music> music;
144 std::vector<Sky> skybox;
145 std::vector<LevelModels> levelModels;
146 std::vector<Title> titles;
147 std::vector<Warp> warps;
148 std::vector<NoteDoor> noteDoors;
149 std::vector<Puzzle> puzzles;
150 bool hasCustomCode = false;
151 uint32_t customCodeRamBase = 0;
152 uint8_t customCodeSha1[20] = {};
153 CustomCodeKind customCodeKind = CustomCodeKind::NONE;
154 bool hasRomHash = false;
155 uint8_t romHash[20] = {};
156};
157
158bool ReadGameConfig(const std::vector<char>& blob, GameConfigData& out, std::string& error);
159std::vector<char> WriteGameConfig(const GameConfigData& config);
160std::string GameConfigToYaml(const GameConfigData& config);
161bool GameConfigFromYaml(const std::string& text, GameConfigData& out, std::string& error);
162const char* CodeConstantName(uint16_t key);
163
164RomhackKind ClassifyRomhack(const std::vector<uint8_t>& rom);
165
166// When a romhack, generate a config for it based on us v1.0.
167bool TrySynthesizeRomConfig(YAML::Node& config, const std::string& cartHash, const std::filesystem::path& romPath,
168 const std::vector<uint8_t>& rom);
169
170// Build the binary aGameConfig blob from a BB romhack ROM.
171std::vector<char> BuildGameConfigBlob(const std::vector<uint8_t>& rom, const std::string& romName);
172
173// True for injected custom-code blobs and for CustomBuild ROMs.
174bool HasCustomCodeBlob(const std::vector<uint8_t>& rom);
175
176// Pre-extraction probe for callers that decide the warning policy themselves
177// (e.g. the extraction UI checks RomhackTable for ported hashes): reports
178// the detected blob's kind and its SHA1 as 40 lowercase hex chars + NUL.
179// Returns false (kind NONE, empty hash) when no blob is found.
180bool GetCustomCodeBlobInfo(const std::vector<uint8_t>& rom, CustomCodeKind& outKind, char outSha1Hex[41]);
181
182// Maintainer tool, creates a hashes.yml.
183void EmitAssetHashes(const std::filesystem::path& romPath, const std::filesystem::path& outputPath);
184
185// How many slots differ from the baseline hashes - a missing baseline entry counts as
186// changed. The port-side extractor uses it to size its progress bar to the real romhack
187// delta instead of every vanilla slot.
188size_t CountModifiedSlots(const std::vector<uint8_t>& rom, const std::filesystem::path& hashesYamlPath);
189
190// Baseline SHA-1 for one slot, or empty if there's no hashes.yaml or no entry for it.
191// Loaded lazily from gAssetPath/hashes.yaml on the first call, then held for the run.
192const std::string& GetBaselineAssetHash(uint32_t assetId);
193
194// Vanilla warp destination (MAP << 8 | ENTRY) for a warp-table index, from the
195// `warps:` section of hashes.yaml. Returns -1 if unknown. Loaded lazily like the
196// baseline hashes.
197int GetVanillaWarpDest(uint32_t warpIndex);
198
199} // namespace BK64
Definition ConfigFactory.h:85
Definition ConfigFactory.h:93
Definition ConfigFactory.h:112
Definition ConfigFactory.h:98
Definition ConfigFactory.h:128
Definition ConfigFactory.h:132
Definition ConfigFactory.h:103
Definition ConfigFactory.h:108
Definition ConfigFactory.h:120
Definition ConfigFactory.h:124
Definition ConfigFactory.h:89
Definition ConfigFactory.h:84