libeditwl
Lightweight C++ library for Nintendo DS(i) formats
Loading...
Searching...
No Matches
fmt_BMG.hpp
1
2#pragma once
3#include <twl/fs/fs_FileFormat.hpp>
4#include <twl/fmt/fmt_Common.hpp>
5#include <optional>
6
7namespace twl::fmt {
8
9 struct BMG : public fs::FileFormat {
10
11 enum class Encoding : u8 {
12 CP1252 = 1,
13 UTF16 = 2,
14 ShiftJIS = 3,
15 UTF8 = 4
16 };
17
18 static inline constexpr size_t GetCharacterSize(const Encoding enc) {
19 switch(enc) {
20 case Encoding::CP1252: {
21 // Unsupported anyway
22 return 1;
23 }
24 case Encoding::UTF16: {
25 return sizeof(char16_t);
26 }
27 case Encoding::UTF8: {
28 return sizeof(char);
29 }
30 case Encoding::ShiftJIS: {
31 // Unsupported anyway
32 return 1;
33 }
34 }
35
36 // Default for unknown encodings
37 return 0;
38 }
39
40 static inline constexpr bool IsValidEncoding(const Encoding enc) {
41 return GetCharacterSize(enc) > 0;
42 }
43
44 struct Header : public MagicStartBase<u64, 0x31676D624753454D /* "MESGbmg1" */ > {
45 u32 file_size;
46 u32 section_count;
47 Encoding encoding;
48 u8 unk_1;
49 u16 unk_2;
50 u32 unk_3;
51 u32 unk_4;
52 u32 unk_5;
53 };
54
55 struct InfoSection : public CommonBlock<0x31464E49 /* "INF1" */ > {
56 u16 entry_count;
57 u16 entry_size;
58 u32 file_id;
59
60 static constexpr size_t OffsetSize = sizeof(u32);
61
62 inline size_t GetAttributesSize() {
63 return this->entry_size - OffsetSize;
64 }
65
66 inline void SetAttributesSize(const size_t size) {
67 this->entry_size = OffsetSize + size;
68 }
69 };
70
71 struct DataSection : public CommonBlock<0x31544144 /* "DAT1" */ > {
72 };
73
74 struct MessageIdSection : public CommonBlock<0x3144494D /* "MID1" */ > {
75 u16 id_count;
76 u8 unk_1;
77 u8 unk_2;
78 u32 unk_3;
79 };
80
81 enum class MessageTokenType : u8 {
82 Text,
83 Escape
84 };
85
87 std::vector<u8> esc_data;
88 };
89
90 struct MessageToken {
91 MessageTokenType type;
92 std::u16string text;
93 MessageEscape escape;
94
95 inline size_t GetByteLength(const Encoding enc) const {
96 switch(this->type) {
97 case MessageTokenType::Escape: {
98 return GetCharacterSize(enc) + 1 + this->escape.esc_data.size();
99 }
100 case MessageTokenType::Text: {
101 return this->text.length() * GetCharacterSize(enc);
102 }
103 default: {
104 return 0;
105 }
106 }
107 }
108 };
109
110 struct Message {
111 std::vector<MessageToken> msg;
112 std::vector<u8> attrs;
113 u32 id;
114
115 inline size_t GetByteLength(const Encoding enc) const {
116 size_t size = GetCharacterSize(enc); // All messages end with a null character
117 for(const auto &token: this->msg) {
118 size += token.GetByteLength(enc);
119 }
120 return size;
121 }
122 };
123
124 Header header;
125 InfoSection info;
126 DataSection data;
127 std::optional<MessageIdSection> msg_id;
128 std::vector<Message> messages;
129
130 BMG() {}
131 BMG(const BMG&) = delete;
132 BMG(BMG&&) = default;
133
134 inline bool HasMessageIds() {
135 return this->msg_id.has_value();
136 }
137
138 void CreateFrom(const Encoding enc, const bool has_message_ids, const size_t attr_size, const std::vector<Message> &msgs, const u32 file_id);
139
140 Result ReadValidateFrom(fs::File &rf) override;
141 Result ReadAllFrom(fs::File &rf) override;
142 Result WriteTo(fs::File &wf) override;
143 };
144
145}
Definition fs_FileFormat.hpp:7
Definition fs_File.hpp:232
Definition twl_Include.hpp:62
Definition fmt_BMG.hpp:71
Definition fmt_BMG.hpp:44
Definition fmt_BMG.hpp:55
Definition fmt_BMG.hpp:86
Definition fmt_BMG.hpp:74
Definition fmt_BMG.hpp:90
Definition fmt_BMG.hpp:110
Definition fmt_BMG.hpp:9
Definition fmt_Common.hpp:53
Definition fmt_Common.hpp:8