diff --git a/src/android/cpp/interface.cpp b/src/android/cpp/interface.cpp index b364f9f..fe6213b 100644 --- a/src/android/cpp/interface.cpp +++ b/src/android/cpp/interface.cpp @@ -394,6 +394,11 @@ extern "C" JNIEXPORT jint JNICALL Java_com_hydra_noods_SettingsMenu_getScreenFil return Settings::screenFilter; } +extern "C" JNIEXPORT jint JNICALL Java_com_hydra_noods_SettingsMenu_getAspectRatio(JNIEnv* env, jobject obj) +{ + return ScreenLayout::aspectRatio; +} + extern "C" JNIEXPORT jint JNICALL Java_com_hydra_noods_SettingsMenu_getIntegerScale(JNIEnv* env, jobject obj) { return ScreenLayout::integerScale; @@ -509,6 +514,11 @@ extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_SettingsMenu_setScreenFil Settings::screenFilter = value; } +extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_SettingsMenu_setAspectRatio(JNIEnv* env, jobject obj, jint value) +{ + ScreenLayout::aspectRatio = value; +} + extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_SettingsMenu_setIntegerScale(JNIEnv* env, jobject obj, jint value) { ScreenLayout::integerScale = value; diff --git a/src/android/java/com/hydra/noods/SettingsMenu.java b/src/android/java/com/hydra/noods/SettingsMenu.java index b20ecdf..b046bb8 100644 --- a/src/android/java/com/hydra/noods/SettingsMenu.java +++ b/src/android/java/com/hydra/noods/SettingsMenu.java @@ -99,6 +99,7 @@ protected void onCreate(Bundle savedInstanceState) editor.putString("screen_sizing", Integer.toString(getScreenSizing())); editor.putString("screen_gap", Integer.toString(getScreenGap())); editor.putString("screen_filter", Integer.toString(getScreenFilter())); + editor.putString("aspect_ratio", Integer.toString(getAspectRatio())); editor.putBoolean("integer_scale", (getIntegerScale() == 0) ? false : true); editor.putBoolean("gba_crop", (getGbaCrop() == 0) ? false : true); editor.putBoolean("screen_ghost", (getScreenGhost() == 0) ? false : true); @@ -157,7 +158,8 @@ public void onBackPressed() setScreenArrangement(Integer.parseInt(prefs.getString("screen_arrangement", "0"))); setScreenSizing(Integer.parseInt(prefs.getString("screen_sizing", "0"))); setScreenGap(Integer.parseInt(prefs.getString("screen_gap", "0"))); - setScreenFilter(Integer.parseInt(prefs.getString("screen_filter", "1"))); + setScreenFilter(Integer.parseInt(prefs.getString("screen_filter", "2"))); + setAspectRatio(Integer.parseInt(prefs.getString("aspect_ratio", "0"))); setIntegerScale(prefs.getBoolean("integer_scale", false) ? 1 : 0); setGbaCrop(prefs.getBoolean("gba_crop", true) ? 1 : 0); setScreenGhost(prefs.getBoolean("screen_ghost", false) ? 1 : 0); @@ -187,6 +189,7 @@ public void onBackPressed() public static native int getScreenSizing(); public static native int getScreenGap(); public static native int getScreenFilter(); + public static native int getAspectRatio(); public static native int getIntegerScale(); public static native int getGbaCrop(); public static native int getScreenGhost(); @@ -210,6 +213,7 @@ public void onBackPressed() public static native void setScreenSizing(int value); public static native void setScreenGap(int value); public static native void setScreenFilter(int value); + public static native void setAspectRatio(int value); public static native void setIntegerScale(int value); public static native void setGbaCrop(int value); public static native void setScreenGhost(int value); diff --git a/src/android/res/values/arrays.xml b/src/android/res/values/arrays.xml index b9a46f8..7e016d0 100644 --- a/src/android/res/values/arrays.xml +++ b/src/android/res/values/arrays.xml @@ -49,6 +49,13 @@ Linear + + Default + 16:10 + 16:9 + 18:9 + + 0 1 diff --git a/src/android/res/xml/settings.xml b/src/android/res/xml/settings.xml index 87e2096..418bab2 100644 --- a/src/android/res/xml/settings.xml +++ b/src/android/res/xml/settings.xml @@ -156,6 +156,16 @@ app:allowDividerAbove="true" app:allowDividerBelow="true" /> + + layoutSettings = { - Setting("screenPosition", &screenPosition, false), - Setting("screenRotation", &screenRotation, false), + Setting("screenPosition", &screenPosition, false), + Setting("screenRotation", &screenRotation, false), Setting("screenArrangement", &screenArrangement, false), - Setting("screenSizing", &screenSizing, false), - Setting("screenGap", &screenGap, false), - Setting("integerScale", &integerScale, false), - Setting("gbaCrop", &gbaCrop, false) + Setting("screenSizing", &screenSizing, false), + Setting("screenGap", &screenGap, false), + Setting("aspectRatio", &aspectRatio, false), + Setting("integerScale", &integerScale, false), + Setting("gbaCrop", &gbaCrop, false) }; // Add the layout settings @@ -52,12 +55,23 @@ void ScreenLayout::update(int winWidth, int winHeight, bool gbaMode, bool splitS this->winWidth = winWidth; this->winHeight = winHeight; - if (screenArrangement == 3 || (gbaMode && gbaCrop) || splitScreens) // Single screen + // Set the screen dimensions based on mode and aspect ratio + bool gba = (gbaMode && gbaCrop); + int width, height = (gba ? 160 : 192); + switch (aspectRatio) { - // Determine the screen dimensions based on the current rotation - int width = (gbaMode && gbaCrop) ? (screenRotation ? 160 : 240) : (screenRotation ? 192 : 256); - int height = (gbaMode && gbaCrop) ? (screenRotation ? 240 : 160) : (screenRotation ? 256 : 192); + default: width = (gba ? 240 : 256); break; // Default + case 1: width = (gba ? 256 : 308); break; // 16:10 + case 2: width = (gba ? 284 : 342); break; // 16:9 + case 3: width = (gba ? 320 : 384); break; // 18:9 + } + + // Swap the screen dimensions if rotated + if (screenRotation) + SWAP(width, height); + if (screenArrangement == 3 || gba || splitScreens) // Single screen + { // Set the minimum dimensions for the layout minWidth = width; minHeight = height; @@ -96,10 +110,6 @@ void ScreenLayout::update(int winWidth, int winHeight, bool gbaMode, bool splitS // In automatic mode, the arrangement is horizontal if rotated and vertical otherwise bool vertical = (screenArrangement == 1 || (screenArrangement == 0 && screenRotation == 0)); - // Determine the screen dimensions based on the current rotation - int width = (screenRotation ? 192 : 256); - int height = (screenRotation ? 256 : 192); - // Determine the screen gap based on the current setting int gap = (screenGap ? (12 * (1 << screenGap)) : 0); if (gap > 96) gap = 96; diff --git a/src/common/screen_layout.h b/src/common/screen_layout.h index 2b0dd0f..18cb8af 100644 --- a/src/common/screen_layout.h +++ b/src/common/screen_layout.h @@ -28,6 +28,7 @@ class ScreenLayout static int screenArrangement; static int screenSizing; static int screenGap; + static int aspectRatio; static int integerScale; static int gbaCrop; diff --git a/src/console/console_ui.cpp b/src/console/console_ui.cpp index 7da2735..4e4425e 100644 --- a/src/console/console_ui.cpp +++ b/src/console/console_ui.cpp @@ -820,6 +820,7 @@ void ConsoleUI::settingsMenu() const std::vector sizing = { "Even", "Enlarge Top", "Enlarge Bottom" }; const std::vector gap = { "None", "Quarter", "Half", "Full" }; const std::vector filter = { "Nearest", "Upscaled", "Linear" }; + const std::vector aspect = { "Default", "16:10", "16:9", "18:9" }; const std::vector theme = { "Dark", "Light" }; int index = 0; @@ -844,6 +845,7 @@ void ConsoleUI::settingsMenu() MenuItem("Screen Sizing", sizing[ScreenLayout::screenSizing]), MenuItem("Screen Gap", gap[ScreenLayout::screenGap]), MenuItem("Screen Filter", filter[Settings::screenFilter]), + MenuItem("Aspect Ratio", aspect[ScreenLayout::aspectRatio]), MenuItem("Integer Scale", toggle[ScreenLayout::integerScale]), MenuItem("GBA Crop", toggle[ScreenLayout::gbaCrop]), MenuItem("Simulate Ghosting", toggle[Settings::screenGhost]), @@ -875,11 +877,12 @@ void ConsoleUI::settingsMenu() case 13: ScreenLayout::screenSizing = (ScreenLayout::screenSizing + 1) % 3; break; case 14: ScreenLayout::screenGap = (ScreenLayout::screenGap + 1) % 4; break; case 15: Settings::screenFilter = (Settings::screenFilter + 1) % 3; break; - case 16: ScreenLayout::integerScale = (ScreenLayout::integerScale + 1) % 2; break; - case 17: ScreenLayout::gbaCrop = (ScreenLayout::gbaCrop + 1) % 2; break; - case 18: Settings::screenGhost = (Settings::screenGhost + 1) % 2; break; + case 16: ScreenLayout::aspectRatio = (ScreenLayout::aspectRatio + 1) % 4; break; + case 17: ScreenLayout::integerScale = (ScreenLayout::integerScale + 1) % 2; break; + case 18: ScreenLayout::gbaCrop = (ScreenLayout::gbaCrop + 1) % 2; break; + case 19: Settings::screenGhost = (Settings::screenGhost + 1) % 2; break; - case 19: + case 20: // Update the palette when changing themes menuTheme = (menuTheme + 1) % 2; palette = &themeColors[menuTheme * 6]; diff --git a/src/desktop/layout_dialog.cpp b/src/desktop/layout_dialog.cpp index d4d2a55..12823d2 100644 --- a/src/desktop/layout_dialog.cpp +++ b/src/desktop/layout_dialog.cpp @@ -46,6 +46,10 @@ enum LayoutEvent FILT_NEAREST, FILT_UPSCALE, FILT_LINEAR, + ASPECT_DEFAULT, + ASPECT_16_10, + ASPECT_16_9, + ASPECT_18_9, INT_SCALE, GBA_CROP, SPLIT_SCREENS, @@ -75,6 +79,10 @@ EVT_RADIOBUTTON(GAP_FULL, LayoutDialog::gapFull) EVT_RADIOBUTTON(FILT_NEAREST, LayoutDialog::filtNearest) EVT_RADIOBUTTON(FILT_UPSCALE, LayoutDialog::filtUpscale) EVT_RADIOBUTTON(FILT_LINEAR, LayoutDialog::filtLinear) +EVT_RADIOBUTTON(ASPECT_DEFAULT, LayoutDialog::aspectDefault) +EVT_RADIOBUTTON(ASPECT_16_10, LayoutDialog::aspect16x10) +EVT_RADIOBUTTON(ASPECT_16_9, LayoutDialog::aspect16x9) +EVT_RADIOBUTTON(ASPECT_18_9, LayoutDialog::aspect18x9) EVT_CHECKBOX(INT_SCALE, LayoutDialog::intScale) EVT_CHECKBOX(GBA_CROP, LayoutDialog::gbaCrop) EVT_CHECKBOX(SPLIT_SCREENS, LayoutDialog::splitScreens) @@ -91,11 +99,12 @@ LayoutDialog::LayoutDialog(NooApp *app): wxDialog(nullptr, wxID_ANY, "Screen Lay prevSettings[2] = ScreenLayout::screenArrangement; prevSettings[3] = ScreenLayout::screenSizing; prevSettings[4] = ScreenLayout::screenGap; - prevSettings[5] = Settings::screenFilter; - prevSettings[6] = ScreenLayout::integerScale; - prevSettings[7] = ScreenLayout::gbaCrop; - prevSettings[8] = NooApp::splitScreens; - prevSettings[9] = Settings::screenGhost; + prevSettings[5] = ScreenLayout::aspectRatio; + prevSettings[6] = Settings::screenFilter; + prevSettings[7] = ScreenLayout::integerScale; + prevSettings[8] = ScreenLayout::gbaCrop; + prevSettings[9] = NooApp::splitScreens; + prevSettings[10] = Settings::screenGhost; // Determine the height of a button // Borders are measured in pixels, so this value can be used to make values that scale with the DPI/font size @@ -167,6 +176,17 @@ LayoutDialog::LayoutDialog(NooApp *app): wxDialog(nullptr, wxID_ANY, "Screen Lay filtSizer->Add(filtBtns[1] = new wxRadioButton(this, FILT_UPSCALE, "Upscaled"), 0, wxLEFT, size / 8); filtSizer->Add(filtBtns[2] = new wxRadioButton(this, FILT_LINEAR, "Linear"), 0, wxLEFT, size / 8); + // Set up the aspect ratio settings + wxRadioButton *aspectBtns[4]; + wxBoxSizer *aspectSizer = new wxBoxSizer(wxHORIZONTAL); + aspectSizer->Add(new wxStaticText(this, wxID_ANY, "Aspect Ratio:", wxDefaultPosition, + wxSize(wxDefaultSize.GetWidth(), size)), 0, wxALIGN_CENTRE | wxRIGHT, size / 8); + aspectSizer->Add(aspectBtns[0] = new wxRadioButton(this, ASPECT_DEFAULT, "Default", + wxDefaultPosition, wxDefaultSize, wxRB_GROUP), 0, wxLEFT, size / 8); + aspectSizer->Add(aspectBtns[1] = new wxRadioButton(this, ASPECT_16_10, "16:10"), 0, wxLEFT, size / 8); + aspectSizer->Add(aspectBtns[2] = new wxRadioButton(this, ASPECT_16_9, "16:9"), 0, wxLEFT, size / 8); + aspectSizer->Add(aspectBtns[3] = new wxRadioButton(this, ASPECT_18_9, "18:9"), 0, wxLEFT, size / 8); + // Set up the checkbox settings wxCheckBox *boxes[4]; wxBoxSizer *checkSizer = new wxBoxSizer(wxHORIZONTAL); @@ -188,6 +208,8 @@ LayoutDialog::LayoutDialog(NooApp *app): wxDialog(nullptr, wxID_ANY, "Screen Lay gapBtns[ScreenLayout::screenGap]->SetValue(true); if (Settings::screenFilter < 3) filtBtns[Settings::screenFilter]->SetValue(true); + if (ScreenLayout::aspectRatio < 4) + aspectBtns[ScreenLayout::aspectRatio]->SetValue(true); // Set the current values of the checkboxes boxes[0]->SetValue(ScreenLayout::integerScale); @@ -209,6 +231,7 @@ LayoutDialog::LayoutDialog(NooApp *app): wxDialog(nullptr, wxID_ANY, "Screen Lay contents->Add(sizeSizer, 1, wxEXPAND); contents->Add(gapSizer, 1, wxEXPAND); contents->Add(filtSizer, 1, wxEXPAND); + contents->Add(aspectSizer, 1, wxEXPAND); contents->Add(checkSizer, 1, wxEXPAND); contents->Add(buttonSizer, 1, wxEXPAND); @@ -377,6 +400,34 @@ void LayoutDialog::filtLinear(wxCommandEvent &event) app->updateLayouts(); } +void LayoutDialog::aspectDefault(wxCommandEvent &event) +{ + // Set the aspect ratio setting to default + ScreenLayout::aspectRatio = 0; + app->updateLayouts(); +} + +void LayoutDialog::aspect16x10(wxCommandEvent &event) +{ + // Set the aspect ratio setting to 16:10 + ScreenLayout::aspectRatio = 1; + app->updateLayouts(); +} + +void LayoutDialog::aspect16x9(wxCommandEvent &event) +{ + // Set the aspect ratio setting to 16:9 + ScreenLayout::aspectRatio = 2; + app->updateLayouts(); +} + +void LayoutDialog::aspect18x9(wxCommandEvent &event) +{ + // Set the aspect ratio setting to 18:9 + ScreenLayout::aspectRatio = 3; + app->updateLayouts(); +} + void LayoutDialog::intScale(wxCommandEvent &event) { // Toggle the integer scale setting @@ -413,11 +464,12 @@ void LayoutDialog::cancel(wxCommandEvent &event) ScreenLayout::screenArrangement = prevSettings[2]; ScreenLayout::screenSizing = prevSettings[3]; ScreenLayout::screenGap = prevSettings[4]; - Settings::screenFilter = prevSettings[5]; - ScreenLayout::integerScale = prevSettings[6]; - ScreenLayout::gbaCrop = prevSettings[7]; - NooApp::splitScreens = prevSettings[8]; - Settings::screenGhost = prevSettings[9]; + ScreenLayout::aspectRatio = prevSettings[5]; + Settings::screenFilter = prevSettings[6]; + ScreenLayout::integerScale = prevSettings[7]; + ScreenLayout::gbaCrop = prevSettings[8]; + NooApp::splitScreens = prevSettings[9]; + Settings::screenGhost = prevSettings[10]; app->updateLayouts(); event.Skip(true); } diff --git a/src/desktop/layout_dialog.h b/src/desktop/layout_dialog.h index ef22bae..0e37594 100644 --- a/src/desktop/layout_dialog.h +++ b/src/desktop/layout_dialog.h @@ -31,7 +31,7 @@ class LayoutDialog: public wxDialog private: NooApp *app; - int prevSettings[10]; + int prevSettings[11]; void posCenter(wxCommandEvent &event); void posTop(wxCommandEvent &event); @@ -55,6 +55,10 @@ class LayoutDialog: public wxDialog void filtNearest(wxCommandEvent &event); void filtUpscale(wxCommandEvent &event); void filtLinear(wxCommandEvent &event); + void aspectDefault(wxCommandEvent &event); + void aspect16x10(wxCommandEvent &event); + void aspect16x9(wxCommandEvent &event); + void aspect18x9(wxCommandEvent &event); void intScale(wxCommandEvent &event); void gbaCrop(wxCommandEvent &event); void splitScreens(wxCommandEvent &event);