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) {
|
||||
this->ep3_lobby_banners.clear();
|
||||
for (const auto& it : json.get("Episode3LobbyBanners", JSON::list()).as_list()) {
|
||||
Image img("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) {
|
||||
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 path = "system/ep3/banners/" + it->at(2).as_string();
|
||||
|
||||
string compressed_gvm_data;
|
||||
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) {
|
||||
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()));
|
||||
|
||||
size_t decompressed_size = decompressed_gvm_data.empty()
|
||||
? 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(
|
||||
Ep3LobbyBannerEntry{.type = static_cast<uint32_t>(it->at(0).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.
|
||||
// Image files are expected to be in BMP or PPM format, and should be placed
|
||||
// in the system/ep3/banners directory. Image sizes must be a multiple of 4
|
||||
// pixels in both dimensions, must be no larger than 0x37000 bytes when
|
||||
// encoded as a GVM file (newserv will do this encoding internally), and must
|
||||
// compress to no larger than 0x3800 bytes. newserv will fail on startup if
|
||||
// any of these constraints aren't satisfied.
|
||||
// Image files are expected to be in .bmp, .ppm, .gvm, or .gvm.prs format,
|
||||
// and should be placed in the system/ep3/banners directory. Image sizes must
|
||||
// be a multiple of 4 pixels in both dimensions, must be no larger than
|
||||
// 0x37000 bytes when encoded as a GVM file (newserv will do this encoding
|
||||
// internally if it's not a .gvm or .gvm.prs file), and must compress to no
|
||||
// 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
|
||||
// 1 for image files. where is a bitmask specifying where in the lobby the
|
||||
// banner should appear; the bits are:
|
||||
|
||||
Reference in New Issue
Block a user