Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions runner/src/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ bool nds_parse_boot_mode(const std::string& value, NdsBootMode* out);
// still be harmless but is rejected anyway, to keep bad CLI input loud).
bool nds_parse_instance_index(const std::string& value, uint32_t* out);
bool nds_parse_adaptive_screens(const std::string& value, uint8_t* out);
bool nds_parse_widescreen_width(const std::string& value, uint16_t* out);
bool nds_parse_supersampling(const std::string& value, uint8_t* out);
bool nds_parse_antialiasing(const std::string& value, uint8_t* out);
bool nds_parse_internal_resolution(const std::string& value, uint8_t* out);
Expand Down
21 changes: 17 additions & 4 deletions runner/src/frontend_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,19 @@ bool nds_parse_adaptive_screens(const std::string& value, uint8_t* out) {
return false;
}

bool nds_parse_widescreen_width(const std::string& value, uint16_t* out) {
if (!out || value.empty()) return false;
char* end = nullptr;
const long parsed = std::strtol(value.c_str(), &end, 10);
if (!end || *end != '\0' ||
(parsed != 256 && parsed != 320 &&
parsed != 384 && parsed != 448)) {
return false;
}
*out = static_cast<uint16_t>(parsed);
return true;
}

bool nds_parse_supersampling(const std::string& value, uint8_t* out) {
if (!out || value.empty()) return false;
char* end = nullptr;
Expand Down Expand Up @@ -544,15 +557,15 @@ bool nds_load_frontend_config(const std::string& path,
}
if (const auto value =
(*display)["adaptive_width"].value<int64_t>()) {
if (*value < 256 || *value > 448 || (*value & 1) != 0) {
uint16_t width = 0;
if (!nds_parse_widescreen_width(std::to_string(*value), &width)) {
if (error) {
*error =
"display.adaptive_width must be an even value from "
"256 through 448";
"display.adaptive_width must be 256, 320, 384, "
"or 448";
}
return false;
}
const uint16_t width = static_cast<uint16_t>(*value);
if (options->adaptive_supported & NDS_ADAPTIVE_TOP)
options->adaptive_max_width[0] = width;
if (options->adaptive_supported & NDS_ADAPTIVE_BOTTOM)
Expand Down
30 changes: 30 additions & 0 deletions runner/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ int main(int argc, char** argv) {
std::string cli_screen_layout;
std::string cli_fullscreen;
std::string cli_adaptive_screens;
std::string cli_widescreen_width;
std::string cli_supersampling;
std::string cli_internal_resolution;
std::string cli_texture_upscale;
Expand Down Expand Up @@ -445,6 +446,8 @@ int main(int argc, char** argv) {
cli_fullscreen = argv[++i];
} else if (a == "--adaptive-widescreen" && i + 1 < argc) {
cli_adaptive_screens = argv[++i];
} else if (a == "--widescreen-width" && i + 1 < argc) {
cli_widescreen_width = argv[++i];
} else if (a == "--supersampling" && i + 1 < argc) {
cli_supersampling = argv[++i];
} else if (a == "--internal-resolution" && i + 1 < argc) {
Expand Down Expand Up @@ -573,6 +576,7 @@ int main(int argc, char** argv) {
"[--screen-layout stacked|separate] "
"[--fullscreen off|borderless|exclusive] "
"[--adaptive-widescreen none|top|bottom|both] "
"[--widescreen-width even:256..448] "
"[--supersampling 1|2|3|4] "
"[--internal-resolution 1|2|3|4] "
"[--texture-upscale 1|2|4] "
Expand Down Expand Up @@ -672,6 +676,22 @@ int main(int argc, char** argv) {
return 2;
}
}
auto apply_adaptive_width = [&](uint16_t width) {
if (frontend_options.adaptive_supported & NDS_ADAPTIVE_TOP)
frontend_options.adaptive_max_width[0] = width;
if (frontend_options.adaptive_supported & NDS_ADAPTIVE_BOTTOM)
frontend_options.adaptive_max_width[1] = width;
};
if (const char* value = std::getenv("NDS_WIDESCREEN_WIDTH")) {
uint16_t width = 0;
if (!nds_parse_widescreen_width(value, &width)) {
std::fprintf(stderr,
"invalid NDS_WIDESCREEN_WIDTH "
"(expected 256, 320, 384, or 448)\n");
return 2;
}
apply_adaptive_width(width);
}
if (const char* value = std::getenv("NDS_SUPERSAMPLING")) {
if (!nds_parse_supersampling(value,
&frontend_options.supersampling)) {
Expand Down Expand Up @@ -775,6 +795,16 @@ int main(int argc, char** argv) {
"(expected none, top, bottom, or both)\n");
return 2;
}
if (!cli_widescreen_width.empty()) {
uint16_t width = 0;
if (!nds_parse_widescreen_width(cli_widescreen_width, &width)) {
std::fprintf(stderr,
"invalid --widescreen-width "
"(expected 256, 320, 384, or 448)\n");
return 2;
}
apply_adaptive_width(width);
}
if (!cli_supersampling.empty() &&
!nds_parse_supersampling(cli_supersampling,
&frontend_options.supersampling)) {
Expand Down
26 changes: 26 additions & 0 deletions runner/tests/frontend_config_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,32 @@ int main() {
if (!require(
!nds_load_frontend_config(path.string(), &options, &error)))
return 11;
{
std::ofstream file(path);
file << "[game]\n"
"sha1 = \"90164d1ac127ee5f9815ea4ae7de798c7b5fc629\"\n"
"[display]\n"
"adaptive_capability = \"top\"\n"
"adaptive_width = 320\n";
}
options = {};
if (!require(
nds_load_frontend_config(path.string(), &options, &error)))
return 25;
if (!require(options.adaptive_max_width[0] == 320))
return 26;
{
uint16_t width = 0;
if (!require(nds_parse_widescreen_width("448", &width) &&
width == 448))
return 27;
if (!require(!nds_parse_widescreen_width("255", &width)))
return 28;
if (!require(!nds_parse_widescreen_width("449", &width)))
return 29;
if (!require(!nds_parse_widescreen_width("342", &width)))
return 30;
}

{
std::ofstream file(path);
Expand Down