| 253 | } |
| 254 | |
| 255 | std::vector<std::vector<uint8_t>> EXEReader::GetLogos() { |
| 256 | corefile.clear(); |
| 257 | |
| 258 | if (!resource_ofs) { |
| 259 | return {}; |
| 260 | } |
| 261 | |
| 262 | if (Player::player_config.show_startup_logos.Get() == ConfigEnum::StartupLogos::None) { |
| 263 | return {}; |
| 264 | } |
| 265 | |
| 266 | std::vector<std::vector<uint8_t>> logos; |
| 267 | |
| 268 | uint32_t resourcesIDEs = GetU16(resource_ofs + 0x0C); |
| 269 | if (resourcesIDEs == 1) { |
| 270 | uint32_t resourcesIDEbase = resource_ofs + 0x10; |
| 271 | if (ResNameCheck(exe_reader_roffset(resource_ofs, GetU32(resourcesIDEbase)), "XYZ")) { |
| 272 | uint32_t xyz_base = exe_reader_roffset(resource_ofs, GetU32(resourcesIDEbase + 4)); |
| 273 | uint16_t xyz_logos = std::min<uint16_t>(GetU16(xyz_base + 0x0C), 9); |
| 274 | uint32_t xyz_logo_base = xyz_base + 0x10; |
| 275 | |
| 276 | bool only_custom_logos = (Player::player_config.show_startup_logos.Get() == ConfigEnum::StartupLogos::Custom); |
| 277 | std::string res_name = "LOGOX"; |
| 278 | |
| 279 | for (int i = 0; i <= xyz_logos; ++i) { |
| 280 | uint32_t name = GetU32(xyz_logo_base); |
| 281 | // Actually a name? |
| 282 | if (name & 0x80000000) { |
| 283 | name = exe_reader_roffset(resource_ofs, name); |
| 284 | res_name.back() = '1' + i; |
| 285 | |
| 286 | if (ResNameCheck(name, res_name.c_str()) || (i == 0 && ResNameCheck(name, "LOGO"))) { |
| 287 | uint32_t dataent = GetU32(xyz_logo_base + 4); |
| 288 | if (dataent & 0x80000000) { |
| 289 | dataent = exe_reader_roffset(resource_ofs, dataent); |
| 290 | dataent = resource_ofs + GetU32(dataent + 0x14); |
| 291 | } |
| 292 | uint32_t filebase = (GetU32(dataent) - resource_rva) + resource_ofs; |
| 293 | uint32_t filesize = GetU32(dataent + 0x04); |
| 294 | Output::Debug("EXEReader: {} resource found (DE {:#x}; {:#x}; len {:#x})", res_name, dataent, filebase, filesize); |
| 295 | std::vector<uint8_t> logo; |
| 296 | logo.resize(filesize); |
| 297 | |
| 298 | corefile.seekg(filebase, std::ios_base::beg); |
| 299 | corefile.read(reinterpret_cast<char*>(logo.data()), filesize); |
| 300 | if (logo.size() < 8 || strncmp(reinterpret_cast<char*>(logo.data()), "XYZ1", 4) != 0) { |
| 301 | Output::Debug("EXEReader: {}: Not a XYZ image", res_name); |
| 302 | return {}; |
| 303 | } |
| 304 | |
| 305 | if (corefile.gcount() != filesize) { |
| 306 | Output::Debug("EXEReader: {}: Error reading resource (read {}, expected {})", res_name, corefile.gcount(), filesize); |
| 307 | return {}; |
| 308 | } |
| 309 | |
| 310 | if (only_custom_logos) { |
| 311 | auto crc = static_cast<uint32_t>(crc32(0, logo.data(), logo.size())); |
| 312 | if (std::find(logo_crc32.begin(), logo_crc32.end(), crc) == logo_crc32.end()) { |