support already-encoded GVM files for Ep3 lobby banners
This commit is contained in:
+28
-9
@@ -754,20 +754,39 @@ void ServerState::load_config() {
|
|||||||
if (!this->is_replay) {
|
if (!this->is_replay) {
|
||||||
this->ep3_lobby_banners.clear();
|
this->ep3_lobby_banners.clear();
|
||||||
for (const auto& it : json.get("Episode3LobbyBanners", JSON::list()).as_list()) {
|
for (const auto& it : json.get("Episode3LobbyBanners", JSON::list()).as_list()) {
|
||||||
Image img("system/ep3/banners/" + it->at(2).as_string());
|
string path = "system/ep3/banners/" + it->at(2).as_string();
|
||||||
string gvm = encode_gvm(img, img.get_has_alpha() ? GVRDataFormat::RGB5A3 : GVRDataFormat::RGB565);
|
|
||||||
if (gvm.size() > 0x37000) {
|
string compressed_gvm_data;
|
||||||
throw runtime_error(string_printf("banner %s is too large (0x%zX bytes; maximum size is 0x37000 bytes)", it->at(2).as_string().c_str(), gvm.size()));
|
string decompressed_gvm_data;
|
||||||
|
if (ends_with(path, ".gvm.prs")) {
|
||||||
|
compressed_gvm_data = load_file(path);
|
||||||
|
} else if (ends_with(path, ".gvm")) {
|
||||||
|
decompressed_gvm_data = load_file(path);
|
||||||
|
} else if (ends_with(path, ".bmp")) {
|
||||||
|
Image img(path);
|
||||||
|
decompressed_gvm_data = encode_gvm(img, img.get_has_alpha() ? GVRDataFormat::RGB5A3 : GVRDataFormat::RGB565);
|
||||||
|
} else {
|
||||||
|
throw runtime_error(string_printf("banner %s is in an unknown format", path.c_str()));
|
||||||
}
|
}
|
||||||
string compressed = prs_compress_optimal(gvm.data(), gvm.size());
|
|
||||||
if (compressed.size() > 0x3800) {
|
size_t decompressed_size = decompressed_gvm_data.empty()
|
||||||
throw runtime_error(string_printf("banner %s cannot be compressed small enough (0x%zX bytes; maximum size is 0x3800 bytes compressed)", it->at(2).as_string().c_str(), compressed.size()));
|
? prs_decompress_size(compressed_gvm_data)
|
||||||
|
: decompressed_gvm_data.size();
|
||||||
|
if (decompressed_size > 0x37000) {
|
||||||
|
throw runtime_error(string_printf("banner %s is too large (0x%zX bytes; maximum size is 0x37000 bytes)", path.c_str(), decompressed_size));
|
||||||
}
|
}
|
||||||
config_log.info("Loaded Episode 3 lobby banner %s (0x%zX -> 0x%zX bytes)", it->at(2).as_string().c_str(), gvm.size(), compressed.size());
|
|
||||||
|
if (compressed_gvm_data.empty()) {
|
||||||
|
compressed_gvm_data = prs_compress_optimal(decompressed_gvm_data);
|
||||||
|
}
|
||||||
|
if (compressed_gvm_data.size() > 0x3800) {
|
||||||
|
throw runtime_error(string_printf("banner %s cannot be compressed small enough (0x%zX bytes; maximum size is 0x3800 bytes compressed)", it->at(2).as_string().c_str(), compressed_gvm_data.size()));
|
||||||
|
}
|
||||||
|
config_log.info("Loaded Episode 3 lobby banner %s (0x%zX -> 0x%zX bytes)", path.c_str(), decompressed_size, compressed_gvm_data.size());
|
||||||
this->ep3_lobby_banners.emplace_back(
|
this->ep3_lobby_banners.emplace_back(
|
||||||
Ep3LobbyBannerEntry{.type = static_cast<uint32_t>(it->at(0).as_int()),
|
Ep3LobbyBannerEntry{.type = static_cast<uint32_t>(it->at(0).as_int()),
|
||||||
.which = static_cast<uint32_t>(it->at(1).as_int()),
|
.which = static_cast<uint32_t>(it->at(1).as_int()),
|
||||||
.data = std::move(compressed)});
|
.data = std::move(compressed_gvm_data)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -448,12 +448,13 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Episode 3 lobby banners. Currently only images are supported.
|
// Episode 3 lobby banners. Currently only images are supported.
|
||||||
// Image files are expected to be in BMP or PPM format, and should be placed
|
// Image files are expected to be in .bmp, .ppm, .gvm, or .gvm.prs format,
|
||||||
// in the system/ep3/banners directory. Image sizes must be a multiple of 4
|
// and should be placed in the system/ep3/banners directory. Image sizes must
|
||||||
// pixels in both dimensions, must be no larger than 0x37000 bytes when
|
// be a multiple of 4 pixels in both dimensions, must be no larger than
|
||||||
// encoded as a GVM file (newserv will do this encoding internally), and must
|
// 0x37000 bytes when encoded as a GVM file (newserv will do this encoding
|
||||||
// compress to no larger than 0x3800 bytes. newserv will fail on startup if
|
// internally if it's not a .gvm or .gvm.prs file), and must compress to no
|
||||||
// any of these constraints aren't satisfied.
|
// larger than 0x3800 bytes. newserv will fail on startup if any of these
|
||||||
|
// constraints aren't satisfied.
|
||||||
// Banners are specified as lists of [type, where, filename]. type should be
|
// Banners are specified as lists of [type, where, filename]. type should be
|
||||||
// 1 for image files. where is a bitmask specifying where in the lobby the
|
// 1 for image files. where is a bitmask specifying where in the lobby the
|
||||||
// banner should appear; the bits are:
|
// banner should appear; the bits are:
|
||||||
|
|||||||
Reference in New Issue
Block a user