libeditwl
Lightweight C++ library for Nintendo DS(i) formats
Loading...
Searching...
No Matches
fmt_ROM.hpp
1
2#pragma once
3#include <twl/fmt/nfs/nfs_NitroFs.hpp>
4#include <twl/fs/fs_FileFormat.hpp>
5#include <twl/util/util_String.hpp>
6#include <twl/gfx/gfx_BannerIcon.hpp>
7#include <optional>
8
9namespace twl::fmt {
10
11 struct ROM : public fs::FileFormat, public nfs::NitroFileSystemFormat {
12
13 enum class ProcessorType : u8 {
14 ARM7,
15 ARM9
16 };
17
18 enum class Language : u8 {
19 Ja,
20 En,
21 Fr,
22 Ge,
23 It,
24 Es,
25
26 Count
27 };
28
29 enum class Region : u8 {
30 Normal = 0x00,
31 Korea = 0x40,
32 China = 0x80
33 };
34
35 enum class UnitCode : u8 {
36 NDS = 0x00,
37 NDS_NDSi = 0x02,
38 NDSi = 0x03
39 };
40
41 enum class AutostartFlags : u8 {
42 None = 0,
43 SkipHealthSafetyPress = TWL_BITMASK(2)
44 };
45
46 struct Header {
47 char game_title[12];
48 char game_code[4];
49 char developer_code[2];
50 UnitCode unit_code;
51 u8 encryption_seed_select;
52 u8 device_capacity;
53 u8 reserved_1[7];
54 union {
55 u16 ndsi;
56 struct {
57 u8 reserved;
58 Region region;
59 } nds;
60 } game_revision;
61 u8 version;
62 AutostartFlags autostart_flags;
63 u32 arm9_rom_offset;
64 u32 arm9_entry_address;
65 u32 arm9_ram_address;
66 u32 arm9_rom_size;
67 u32 arm7_rom_offset;
68 u32 arm7_entry_address;
69 u32 arm7_ram_address;
70 u32 arm7_rom_size;
71 u32 fnt_offset;
72 u32 fnt_size;
73 u32 fat_offset;
74 u32 fat_size;
75 u32 arm9_overlay_table_offset;
76 u32 arm9_overlay_table_size;
77 u32 arm7_overlay_table_offset;
78 u32 arm7_overlay_table_size;
79 u32 normal_card_control_register_settings;
80 u32 secure_card_control_register_settings;
81 u32 banner_offset;
82 u16 secure_area_crc;
83 u16 secure_transfer_timeout;
84 u32 arm9_autoload;
85 u32 arm7_autoload;
86 u64 secure_area_disable;
87 u32 rom_size;
88 u32 header_size;
89 u8 reserved_2[56];
90 u8 nintendo_logo[156];
91 u16 nintendo_logo_crc;
92 u16 header_crc;
93 u32 debug_rom_offset;
94 u32 debug_rom_size;
95 u32 debug_ram_address;
96 u32 reserved_3;
97 u8 reserved_4[0x50];
98 u32 arm9i_rom_offset;
99 u32 reserved_5;
100 u32 arm9i_ram_addr;
101 u32 arm9i_rom_size;
102 u32 arm7i_rom_offset;
103 u32 sd_mmc_dev_list;
104 u32 arm7i_ram_addr;
105 u32 arm7i_rom_size;
106 u8 reserved_6[0x20];
107
108 // Note: helpers since these strings don't neccessarily end with a null character, so std::string(<c_str>) wouldn't work as expected there
109
110 inline std::string GetGameTitle() {
111 return util::GetNonNullTerminatedCString(this->game_title);
112 }
113
114 inline void SetGameTitle(const std::string &game_title_str) {
115 return util::SetNonNullTerminatedCString(this->game_title, game_title_str);
116 }
117
118 inline std::string GetGameCode() {
119 return util::GetNonNullTerminatedCString(this->game_code);
120 }
121
122 inline void SetGameCode(const std::string &game_code_str) {
123 return util::SetNonNullTerminatedCString(this->game_code, game_code_str);
124 }
125
126 inline std::string GetDeveloperCode() {
127 return util::GetNonNullTerminatedCString(this->developer_code);
128 }
129
130 inline void SetDeveloperCode(const std::string &dev_code_str) {
131 return util::SetNonNullTerminatedCString(this->developer_code, dev_code_str);
132 }
133 };
134 static_assert(sizeof(Header) == 0x200);
135
136 static constexpr u32 GameTitleLength = 128;
137
138 struct Banner {
139 u8 version;
140 u8 reserved_1;
141 u16 crc16_v1;
142 u8 reserved_2[28];
143 u8 icon_chr[gfx::IconCharSize];
144 u8 icon_plt[gfx::IconPaletteSize];
145 char16_t game_titles[static_cast<u32>(Language::Count)][GameTitleLength];
146
147 inline std::u16string GetGameTitle(const Language lang) {
148 if(lang < Language::Count) {
149 return util::GetNonNullTerminatedCString(this->game_titles[static_cast<u32>(lang)]);
150 }
151 return u"";
152 }
153
154 inline void SetGameTitle(const Language lang, const std::u16string &game_title_str) {
155 if(lang < Language::Count) {
156 util::SetNonNullTerminatedCString(this->game_titles[static_cast<u32>(lang)], game_title_str);
157 }
158 }
159 };
160
162 u32 id;
163 u32 ram_address;
164 u32 ram_size;
165 u32 bss_size;
166 u32 static_init_start_address;
167 u32 static_init_end_address;
168 u32 file_id;
169 u32 compressed_size_and_flags;
170 };
171 static_assert(sizeof(OverlayTableEntry) == 0x20);
172
173 struct NitroFooter {
174 u32 code;
175 u32 start_module_params_offset;
176 u32 unk;
177
178 static constexpr u32 Code = 0xDEC00621;
179 };
180 static_assert(sizeof(NitroFooter) == 0xC);
181
183 u32 autoload_list_start;
184 u32 autoload_list_end;
185 u32 autoload_start;
186 u32 static_bss_start;
187 u32 static_bss_end;
188 u32 compressed_static_end;
189 u32 sdk_version;
190 u32 nitro_code_le;
191 u32 nitro_code_be;
192 };
193 static_assert(sizeof(StartModuleParams) == 0x24);
194
195 static constexpr size_t SectionAlignment = 0x200;
196
197 Header header;
198 Banner banner;
199 std::vector<std::string> lib_symbols;
202 std::optional<NitroFooter> footer;
203 std::optional<StartModuleParams> start_module_params;
204 std::vector<OverlayTableEntry> arm7_ovl_table;
205 std::vector<OverlayTableEntry> arm9_ovl_table;
206
207 ROM() {}
208 ROM(const ROM&) = delete;
209 ROM(ROM&&) = default;
210
211 Result ReadValidateFrom(fs::File &rf) override;
212 Result ReadAllFrom(fs::File &rf) override;
213 Result WriteTo(fs::File &wf) override;
214
215 inline Result CreateOverlayFile(nfs::NitroFileSystemFile &file, const OverlayTableEntry &entry) {
216 TWL_R_TRY(this->CreateFileById(file, entry.file_id));
217 TWL_R_SUCCEED();
218 }
219 };
220
221 TWL_ENUM_BIT_OPERATORS(ROM::AutostartFlags, u8)
222
223}
Definition nfs_NitroFs.hpp:52
Definition nfs_NitroFs.hpp:100
Definition fs_File.hpp:170
Definition fs_FileFormat.hpp:7
Definition fs_File.hpp:236
Definition twl_Include.hpp:62
Definition fmt_ROM.hpp:138
Definition fmt_ROM.hpp:46
Definition fmt_ROM.hpp:173
Definition fmt_ROM.hpp:161
Definition fmt_ROM.hpp:182
Definition fmt_ROM.hpp:11