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[0x90];
98
99 // Note: helpers since these strings don't neccessarily end with a null character, so std::string(<c_str>) wouldn't work as expected there
100
101 inline std::string GetGameTitle() {
102 return util::GetNonNullTerminatedCString(this->game_title);
103 }
104
105 inline void SetGameTitle(const std::string &game_title_str) {
106 return util::SetNonNullTerminatedCString(this->game_title, game_title_str);
107 }
108
109 inline std::string GetGameCode() {
110 return util::GetNonNullTerminatedCString(this->game_code);
111 }
112
113 inline void SetGameCode(const std::string &game_code_str) {
114 return util::SetNonNullTerminatedCString(this->game_code, game_code_str);
115 }
116
117 inline std::string GetDeveloperCode() {
118 return util::GetNonNullTerminatedCString(this->developer_code);
119 }
120
121 inline void SetDeveloperCode(const std::string &dev_code_str) {
122 return util::SetNonNullTerminatedCString(this->developer_code, dev_code_str);
123 }
124 };
125 static_assert(sizeof(Header) == 0x200);
126
127 static constexpr u32 GameTitleLength = 128;
128
129 struct Banner {
130 u8 version;
131 u8 reserved_1;
132 u16 crc16_v1;
133 u8 reserved_2[28];
134 u8 icon_chr[gfx::IconCharSize];
135 u8 icon_plt[gfx::IconPaletteSize];
136 char16_t game_titles[static_cast<u32>(Language::Count)][GameTitleLength];
137
138 inline std::u16string GetGameTitle(const Language lang) {
139 if(lang < Language::Count) {
140 return util::GetNonNullTerminatedCString(this->game_titles[static_cast<u32>(lang)]);
141 }
142 return u"";
143 }
144
145 inline void SetGameTitle(const Language lang, const std::u16string &game_title_str) {
146 if(lang < Language::Count) {
147 util::SetNonNullTerminatedCString(this->game_titles[static_cast<u32>(lang)], game_title_str);
148 }
149 }
150 };
151
153 u32 id;
154 u32 ram_address;
155 u32 ram_size;
156 u32 bss_size;
157 u32 static_init_start_address;
158 u32 static_init_end_address;
159 u32 file_id;
160 u32 compressed_size_and_flags;
161 };
162 static_assert(sizeof(OverlayTableEntry) == 0x20);
163
164 struct NitroFooter {
165 u32 code;
166 u32 start_module_params_offset;
167 u32 unk;
168
169 static constexpr u32 Code = 0xDEC00621;
170 };
171 static_assert(sizeof(NitroFooter) == 0xC);
172
174 u32 autoload_list_start;
175 u32 autoload_list_end;
176 u32 autoload_start;
177 u32 static_bss_start;
178 u32 static_bss_end;
179 u32 compressed_static_end;
180 u32 sdk_version;
181 u32 nitro_code_le;
182 u32 nitro_code_be;
183 };
184 static_assert(sizeof(StartModuleParams) == 0x24);
185
186 static constexpr size_t SectionAlignment = 0x200;
187
188 Header header;
189 Banner banner;
190 std::vector<std::string> lib_symbols;
193 std::optional<NitroFooter> footer;
194 std::optional<StartModuleParams> start_module_params;
195 std::vector<OverlayTableEntry> arm7_ovl_table;
196 std::vector<OverlayTableEntry> arm9_ovl_table;
197
198 ROM() {}
199 ROM(const ROM&) = delete;
200 ROM(ROM&&) = default;
201
202 Result ReadValidateFrom(fs::File &rf) override;
203 Result ReadAllFrom(fs::File &rf) override;
204 Result WriteTo(fs::File &wf) override;
205
206 inline Result CreateOverlayFile(nfs::NitroFileSystemFile &file, const OverlayTableEntry &entry) {
207 TWL_R_TRY(this->CreateFileById(file, entry.file_id));
208 TWL_R_SUCCEED();
209 }
210 };
211
212 TWL_ENUM_BIT_OPERATORS(ROM::AutostartFlags, u8)
213
214}
Definition nfs_NitroFs.hpp:52
Definition nfs_NitroFs.hpp:100
Definition fs_File.hpp:166
Definition fs_FileFormat.hpp:7
Definition fs_File.hpp:232
Definition twl_Include.hpp:62
Definition fmt_ROM.hpp:129
Definition fmt_ROM.hpp:46
Definition fmt_ROM.hpp:164
Definition fmt_ROM.hpp:152
Definition fmt_ROM.hpp:173
Definition fmt_ROM.hpp:11