MCPcopy Create free account
hub / github.com/EasyRPG/Player / ExtractExFont

Function ExtractExFont

src/exe_reader.cpp:159–212  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

157}
158
159static std::vector<uint8_t> ExtractExFont(Filesystem_Stream::InputStream& corefile, uint32_t position, uint32_t len) {
160 std::vector<uint8_t> exfont;
161 constexpr int header_size = 14; // Size of BITMAPFILEHEADER
162 exfont.resize(len + header_size);
163
164 corefile.seekg(position, std::ios_base::beg);
165 corefile.read(reinterpret_cast<char*>(exfont.data()) + header_size, len);
166 if (corefile.gcount() != len) {
167 Output::Debug("EXEReader: ExFont: Error reading resource (read {}, expected {})", corefile.gcount(), len);
168 return {};
169 }
170
171 auto* exfont_data = reinterpret_cast<const uint8_t*>(exfont.data()) + header_size;
172 auto* e = exfont_data + len;
173 auto header = ImageBMP::ParseHeader(exfont_data, e);
174
175 // As it turns out, EXFONTs appear to operate on all the same restrictions as an ordinary BMP.
176 // Bitmap resources lack the BITMAPFILEHEADER. This header must be generated based on the BITMAPINFOHEADER.
177 // And the header that's going to be prepended.
178 int header_len = header_size + header.size;
179 if (header.depth != 8) {
180 Output::Debug("EXEReader: ExFont: Unsupported depth {}", header.depth);
181 return {};
182 }
183 header_len += header.num_colors * 4;
184
185 // 0 (these are in decimal)
186 int pos = 0;
187 exfont[pos++] = 'B';
188 exfont[pos++] = 'M';
189 // 2
190 uint32_t totallen = exfont.size();
191 exfont[pos++] = (totallen) & 0xFF;
192 exfont[pos++] = (totallen >> 8) & 0xFF;
193 exfont[pos++] = (totallen >> 16) & 0xFF;
194 exfont[pos++] = (totallen >> 24) & 0xFF;
195 // 6 - Reserved data
196 exfont[pos++] = 'E';
197 exfont[pos++] = 'x';
198 exfont[pos++] = 'F';
199 exfont[pos++] = 'n';
200 // 10
201 exfont[pos++] = (header_len) & 0xFF;
202 exfont[pos++] = (header_len >> 8) & 0xFF;
203 exfont[pos++] = (header_len >> 16) & 0xFF;
204 exfont[pos++] = (header_len >> 24) & 0xFF;
205
206 // Check if the ExFont is the original through a fast hash function
207 auto crc = crc32(0, exfont.data() + header_size, exfont.size() - header_size);
208 if (crc != 0x86bc6c68) {
209 Output::Debug("EXEReader: Custom ExFont found");
210 }
211 return exfont;
212}
213
214static uint32_t exe_reader_roffset(uint32_t bas, uint32_t ofs) {
215 return bas + (ofs ^ 0x80000000);

Callers 1

GetExFontMethod · 0.85

Calls 2

dataMethod · 0.80
sizeMethod · 0.45

Tested by

no test coverage detected