diff --git a/Makefile b/Makefile
index ba6c61f57..cd4d39d80 100644
--- a/Makefile
+++ b/Makefile
@@ -858,9 +858,6 @@ $(BUILD_DIR)/include/text_strings.h: include/text_strings.h.in
$(BUILD_DIR)/include/text_menu_strings.h: include/text_menu_strings.h.in
$(TEXTCONV) charmap_menu.txt $< $@
-$(BUILD_DIR)/include/text_options_strings.h: include/text_options_strings.h.in
- $(TEXTCONV) charmap.txt $< $@
-
ifeq ($(VERSION),eu)
TEXT_DIRS := text/de text/us text/fr
@@ -899,7 +896,6 @@ ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(GOD
DUMMY != mkdir -p $(ALL_DIRS)
$(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_menu_strings.h
-$(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_options_strings.h
ifeq ($(VERSION),eu)
$(BUILD_DIR)/src/menu/file_select.o: $(BUILD_DIR)/include/text_strings.h $(BUILD_DIR)/bin/eu/translation_en.o $(BUILD_DIR)/bin/eu/translation_de.o $(BUILD_DIR)/bin/eu/translation_fr.o
diff --git a/build-windows-visual-studio/sm64ex.vcxproj b/build-windows-visual-studio/sm64ex.vcxproj
index bf0a6773c..407ce5d86 100644
--- a/build-windows-visual-studio/sm64ex.vcxproj
+++ b/build-windows-visual-studio/sm64ex.vcxproj
@@ -3951,6 +3951,7 @@
+
@@ -4395,6 +4396,7 @@
+
diff --git a/build-windows-visual-studio/sm64ex.vcxproj.filters b/build-windows-visual-studio/sm64ex.vcxproj.filters
index f8398e6b2..8ab7358dc 100644
--- a/build-windows-visual-studio/sm64ex.vcxproj.filters
+++ b/build-windows-visual-studio/sm64ex.vcxproj.filters
@@ -15258,6 +15258,9 @@
Source Files\src\pc\djui\panel
+
+ Source Files\src\pc\djui\panel
+
@@ -16336,5 +16339,8 @@
Source Files\src\pc\djui\panel
+
+ Source Files\src\pc\djui\panel
+
\ No newline at end of file
diff --git a/include/text_options_strings.h.in b/include/text_options_strings.h.in
deleted file mode 100644
index e4f54480a..000000000
--- a/include/text_options_strings.h.in
+++ /dev/null
@@ -1,156 +0,0 @@
-#ifndef TEXT_OPTIONS_STRINGS_H
-#define TEXT_OPTIONS_STRINGS_H
-
-/* Extended options menu text */
-
-// Menu title strings
-
-#define TEXT_OPT_OPTIONS _("OPTIONS")
-#define TEXT_OPT_CAMERA _("CAMERA")
-#define TEXT_OPT_CONTROLS _("CONTROLS")
-#define TEXT_OPT_VIDEO _("DISPLAY")
-#define TEXT_OPT_AUDIO _("SOUND")
-#define TEXT_OPT_CHEATS _("CHEATS")
-
-// Markers
-
-#define TEXT_OPT_HIGHLIGHT _("O")
-#define TEXT_OPT_UNBOUND _("NONE")
-
-// Language specific strings
-
-#if defined(VERSION_JP) || defined(VERSION_SH)
-
-// TODO: Actually translate this to JP
-
-// No . in JP
-
-#define TEXT_OPT_PRESSKEY _("・・・")
-
-// Option strings
-
-#define TEXT_OPT_BUTTON1 _("R OPTIONS")
-#define TEXT_OPT_BUTTON2 _("R RETURN")
-#define TEXT_OPT_ENABLED _("ENABLED")
-#define TEXT_OPT_DISABLED _("DISABLED")
-#define TEXT_OPT_CAMX _("CAMERA X SENSITIVITY")
-#define TEXT_OPT_CAMY _("CAMERA Y SENSITIVITY")
-#define TEXT_OPT_INVERTX _("INVERT X AXIS")
-#define TEXT_OPT_INVERTY _("INVERT Y AXIS")
-#define TEXT_OPT_CAMC _("CAMERA CENTRE AGGRESSION")
-#define TEXT_OPT_CAMP _("CAMERA PAN LEVEL")
-#define TEXT_OPT_CAMD _("CAMERA DECELERATION")
-#define TEXT_OPT_CAMON _("FREE CAMERA")
-#define TEXT_OPT_ANALOGUE _("ANALOGUE CAMERA")
-#define TEXT_OPT_MOUSE _("MOUSE LOOK")
-#define TEXT_OPT_TEXFILTER _("TEXTURE FILTERING")
-#define TEXT_OPT_FSCREEN _("FULLSCREEN")
-#define TEXT_OPT_NEAREST _("NEAREST")
-#define TEXT_OPT_LINEAR _("LINEAR")
-#define TEXT_OPT_MVOLUME _("MASTER VOLUME")
-#define TEXT_OPT_MUSVOLUME _("MUSIC VOLUME")
-#define TEXT_OPT_SFXVOLUME _("SFX VOLUME")
-#define TEXT_OPT_ENVVOLUME _("ENV VOLUME")
-#define TEXT_OPT_VSYNC _("VERTICAL SYNC")
-#define TEXT_OPT_AUTO _("AUTO")
-#define TEXT_OPT_HUD _("HUD")
-#define TEXT_OPT_THREEPT _("THREE POINT")
-#define TEXT_OPT_APPLY _("APPLY")
-#define TEXT_OPT_RESETWND _("RESET WINDOW")
-
-#define TEXT_BIND_A _("A BUTTON")
-#define TEXT_BIND_B _("B BUTTON")
-#define TEXT_BIND_START _("START BUTTON")
-#define TEXT_BIND_L _("L TRIGGER")
-#define TEXT_BIND_R _("R TRIGGER")
-#define TEXT_BIND_Z _("Z TRIGGER")
-#define TEXT_BIND_C_UP _("C-UP")
-#define TEXT_BIND_C_DOWN _("C-DOWN")
-#define TEXT_BIND_C_LEFT _("C-LEFT")
-#define TEXT_BIND_C_RIGHT _("C-RIGHT")
-#define TEXT_BIND_UP _("STICK UP")
-#define TEXT_BIND_DOWN _("STICK DOWN")
-#define TEXT_BIND_LEFT _("STICK LEFT")
-#define TEXT_BIND_RIGHT _("STICK RIGHT")
-#define TEXT_OPT_DEADZONE _("STICK DEADZONE")
-#define TEXT_OPT_RUMBLE _("RUMBLE STRENGTH")
-
-#define TEXT_OPT_CHEAT1 _("ENABLE CHEATS")
-#define TEXT_OPT_CHEAT2 _("MOONJUMP (PRESS L)")
-#define TEXT_OPT_CHEAT3 _("INVINCIBLE MARIO")
-#define TEXT_OPT_CHEAT4 _("INFINITE LIVES")
-#define TEXT_OPT_CHEAT5 _("SUPER SPEED")
-#define TEXT_OPT_CHEAT6 _("SUPER RESPONSIVE CONTROLS")
-#define TEXT_OPT_CHEAT7 _("EXIT COURSE AT ANY TIME")
-#define TEXT_OPT_CHEAT8 _("HUGE MARIO")
-#define TEXT_OPT_CHEAT9 _("TINY MARIO")
-
-#else // VERSION
-
-// Markers
-
-#define TEXT_OPT_PRESSKEY _("...")
-
-// Option strings
-
-#define TEXT_OPT_BUTTON1 _("[R] Options")
-#define TEXT_OPT_BUTTON2 _("[R] Return")
-#define TEXT_OPT_ENABLED _("Enabled")
-#define TEXT_OPT_DISABLED _("Disabled")
-#define TEXT_OPT_CAMX _("Camera X Sensitivity")
-#define TEXT_OPT_CAMY _("Camera Y Sensitivity")
-#define TEXT_OPT_INVERTX _("Invert X Axis")
-#define TEXT_OPT_INVERTY _("Invert Y Axis")
-#define TEXT_OPT_CAMC _("Camera Centre Aggression")
-#define TEXT_OPT_CAMP _("Camera Pan Level")
-#define TEXT_OPT_CAMD _("Camera Deceleration")
-#define TEXT_OPT_CAMON _("Free Camera")
-#define TEXT_OPT_ANALOGUE _("Analogue Camera")
-#define TEXT_OPT_MOUSE _("Mouse Look")
-#define TEXT_OPT_TEXFILTER _("Texture Filtering")
-#define TEXT_OPT_FSCREEN _("Fullscreen")
-#define TEXT_OPT_NEAREST _("Nearest")
-#define TEXT_OPT_LINEAR _("Linear")
-#define TEXT_OPT_MVOLUME _("Master Volume")
-#define TEXT_OPT_MUSVOLUME _("Music Volume")
-#define TEXT_OPT_SFXVOLUME _("Sfx Volume")
-#define TEXT_OPT_ENVVOLUME _("Env Volume")
-#define TEXT_OPT_VSYNC _("Vertical Sync")
-#define TEXT_OPT_AUTO _("Auto")
-#define TEXT_OPT_HUD _("HUD")
-#define TEXT_OPT_THREEPT _("Three-point")
-#define TEXT_OPT_APPLY _("Apply")
-#define TEXT_OPT_RESETWND _("Reset Window")
-
-#define TEXT_BIND_A _("A Button")
-#define TEXT_BIND_B _("B Button")
-#define TEXT_BIND_START _("Start Button")
-#define TEXT_BIND_L _("L Trigger")
-#define TEXT_BIND_R _("R Trigger")
-#define TEXT_BIND_Z _("Z Trigger")
-#define TEXT_BIND_C_UP _("C-Up")
-#define TEXT_BIND_C_DOWN _("C-Down")
-#define TEXT_BIND_C_LEFT _("C-Left")
-#define TEXT_BIND_C_RIGHT _("C-Right")
-#define TEXT_BIND_UP _("Stick Up")
-#define TEXT_BIND_DOWN _("Stick Down")
-#define TEXT_BIND_LEFT _("Stick Left")
-#define TEXT_BIND_RIGHT _("Stick Right")
-#define TEXT_OPT_DEADZONE _("Stick Deadzone")
-#define TEXT_OPT_RUMBLE _("Rumble Strength")
-
-#define TEXT_OPT_CHEAT1 _("Enable cheats")
-#define TEXT_OPT_CHEAT2 _("Moonjump (Press L)")
-#define TEXT_OPT_CHEAT3 _("Invincible Mario")
-#define TEXT_OPT_CHEAT4 _("Infinite lives")
-#define TEXT_OPT_CHEAT5 _("Super speed")
-#define TEXT_OPT_CHEAT6 _("Super responsive controls")
-#define TEXT_OPT_CHEAT7 _("Exit course at any time")
-#define TEXT_OPT_CHEAT8 _("Huge Mario")
-#define TEXT_OPT_CHEAT9 _("Tiny Mario")
-
-#define TEXT_OPT_LUIGISND _("Luigi Sounds")
-
-#endif // VERSION
-
-#endif // TEXT_OPTIONS_STRINGS_H
diff --git a/include/text_strings.h.in b/include/text_strings.h.in
index e5065c570..b97a5cc93 100644
--- a/include/text_strings.h.in
+++ b/include/text_strings.h.in
@@ -3,10 +3,6 @@
#include "text_menu_strings.h"
-#ifdef EXT_OPTIONS_MENU
-#include "text_options_strings.h"
-#endif
-
/**
* Global Symbols
*/
diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c
index 459161e51..8031afda2 100644
--- a/src/game/ingame_menu.c
+++ b/src/game/ingame_menu.c
@@ -26,12 +26,10 @@
#include "macros.h"
#include "pc/cheats.h"
#include "pc/network/network.h"
+#include "pc/djui/djui.h"
#ifdef BETTERCAMERA
#include "bettercamera.h"
#endif
-#ifdef EXT_OPTIONS_MENU
-#include "options_menu.h"
-#endif
u16 gDialogColorFadeTimer;
s8 gLastDialogLineNum;
@@ -2735,9 +2733,6 @@ s16 render_pause_courses_and_castle(void) {
#ifdef VERSION_EU
gInGameLanguage = eu_get_language();
-#endif
-#ifdef EXT_OPTIONS_MENU
- if (optmenu_open == 0) {
#endif
switch (gDialogBoxState) {
case DIALOG_STATE_OPENING:
@@ -2815,14 +2810,10 @@ s16 render_pause_courses_and_castle(void) {
if (gDialogTextAlpha < 250) {
gDialogTextAlpha += 25;
}
-#ifdef EXT_OPTIONS_MENU
- } else {
- shade_screen();
- optmenu_draw();
- }
- optmenu_check_buttons();
- optmenu_draw_prompt();
-#endif
+
+ if (gDjuiPanelPauseCreated) { shade_screen(); }
+ if (gPlayer1Controller->buttonPressed & R_TRIG)
+ djui_panel_pause_create(NULL);
return 0;
}
diff --git a/src/game/level_update.c b/src/game/level_update.c
index 43067d4b7..295ff3fd3 100644
--- a/src/game/level_update.c
+++ b/src/game/level_update.c
@@ -35,6 +35,7 @@
#include "pc/cliopts.h"
#include "pc/configfile.h"
#include "pc/network/network.h"
+#include "pc/djui/djui.h"
#include "game/screen_transition.h"
@@ -218,6 +219,13 @@ u32 pressed_pause(void) {
}
void set_play_mode(s16 playMode) {
+ if (sCurrPlayMode == PLAY_MODE_PAUSED && playMode != PLAY_MODE_PAUSED) {
+ djui_base_set_visible(&gDjuiPauseOptions->base, false);
+ }
+ if (playMode == PLAY_MODE_PAUSED && sCurrPlayMode != PLAY_MODE_PAUSED) {
+ djui_base_set_visible(&gDjuiPauseOptions->base, true);
+ }
+
sCurrPlayMode = playMode;
D_80339ECA = 0;
}
diff --git a/src/game/options_menu.c b/src/game/options_menu.c
deleted file mode 100644
index c8e0ecce8..000000000
--- a/src/game/options_menu.c
+++ /dev/null
@@ -1,634 +0,0 @@
-#ifdef EXT_OPTIONS_MENU
-
-#include "sm64.h"
-#include "include/text_strings.h"
-#include "engine/math_util.h"
-#include "audio/external.h"
-#include "game/camera.h"
-#include "game/level_update.h"
-#include "game/print.h"
-#include "game/segment2.h"
-#include "game/save_file.h"
-#ifdef BETTERCAMERA
-#include "game/bettercamera.h"
-#endif
-#include "game/mario_misc.h"
-#include "game/game_init.h"
-#include "game/ingame_menu.h"
-#include "game/options_menu.h"
-#include "pc/pc_main.h"
-#include "pc/cliopts.h"
-#include "pc/cheats.h"
-#include "pc/configfile.h"
-#include "pc/controller/controller_api.h"
-
-#include
-#include "../../include/libc/stdlib.h"
-
-u8 optmenu_open = 0;
-
-static u8 optmenu_binding = 0;
-static u8 optmenu_bind_idx = 0;
-
-/* Keeps track of how many times the user has pressed L while in the options menu, so cheats can be unlocked */
-static s32 l_counter = 0;
-
-// How to add stuff:
-// strings: add them to include/text_strings.h.in
-// and to menuStr[] / opts*Str[]
-// options: add them to the relevant options list
-// menus: add a new submenu definition and a new
-// option to the optsMain list
-
-static const u8 toggleStr[][16] = {
- { TEXT_OPT_DISABLED },
- { TEXT_OPT_ENABLED },
-};
-
-static const u8 menuStr[][32] = {
- { TEXT_OPT_HIGHLIGHT },
- { TEXT_OPT_BUTTON1 },
- { TEXT_OPT_BUTTON2 },
- { TEXT_OPT_OPTIONS },
- { TEXT_OPT_CAMERA },
- { TEXT_OPT_CONTROLS },
- { TEXT_OPT_VIDEO },
- { TEXT_OPT_AUDIO },
- { TEXT_EXIT_GAME },
- { TEXT_OPT_CHEATS },
-
-};
-
-static const u8 optsCameraStr[][32] = {
- { TEXT_OPT_CAMX },
- { TEXT_OPT_CAMY },
- { TEXT_OPT_INVERTX },
- { TEXT_OPT_INVERTY },
- { TEXT_OPT_CAMC },
- { TEXT_OPT_CAMP },
- { TEXT_OPT_ANALOGUE },
- { TEXT_OPT_MOUSE },
- { TEXT_OPT_CAMD },
- { TEXT_OPT_CAMON },
-};
-
-static const u8 optsVideoStr[][32] = {
- { TEXT_OPT_FSCREEN },
- { TEXT_OPT_TEXFILTER },
- { TEXT_OPT_NEAREST },
- { TEXT_OPT_LINEAR },
- { TEXT_OPT_RESETWND },
- { TEXT_OPT_VSYNC },
- { TEXT_OPT_AUTO },
- { TEXT_OPT_HUD },
- { TEXT_OPT_THREEPT },
- { TEXT_OPT_APPLY },
-};
-
-static const u8 optsAudioStr[][32] = {
- { TEXT_OPT_MVOLUME },
- { TEXT_OPT_MUSVOLUME },
- { TEXT_OPT_SFXVOLUME },
- { TEXT_OPT_ENVVOLUME },
- { TEXT_OPT_LUIGISND },
-};
-
-static const u8 optsCheatsStr[][64] = {
- { TEXT_OPT_CHEAT1 },
- { TEXT_OPT_CHEAT2 },
- { TEXT_OPT_CHEAT3 },
- { TEXT_OPT_CHEAT4 },
- { TEXT_OPT_CHEAT5 },
- { TEXT_OPT_CHEAT6 },
- { TEXT_OPT_CHEAT7 },
- { TEXT_OPT_CHEAT8 },
- { TEXT_OPT_CHEAT9 },
-};
-
-#define TEXT_BIND_CHAT 0x0C,0x2B,0x24,0x37,0xFF
-
-static const u8 bindStr[][32] = {
- { TEXT_OPT_UNBOUND },
- { TEXT_OPT_PRESSKEY },
- { TEXT_BIND_A },
- { TEXT_BIND_B },
- { TEXT_BIND_START },
- { TEXT_BIND_L },
- { TEXT_BIND_R },
- { TEXT_BIND_Z },
- { TEXT_BIND_C_UP },
- { TEXT_BIND_C_DOWN },
- { TEXT_BIND_C_LEFT },
- { TEXT_BIND_C_RIGHT },
- { TEXT_BIND_UP },
- { TEXT_BIND_DOWN },
- { TEXT_BIND_LEFT },
- { TEXT_BIND_RIGHT },
- { TEXT_BIND_CHAT },
- { TEXT_OPT_DEADZONE },
- { TEXT_OPT_RUMBLE }
-};
-
-static const u8 *filterChoices[] = {
- optsVideoStr[2],
- optsVideoStr[3],
- optsVideoStr[8],
-};
-
-static const u8 *vsyncChoices[] = {
- toggleStr[0],
- toggleStr[1],
- optsVideoStr[6],
-};
-
-enum OptType {
- OPT_INVALID = 0,
- OPT_TOGGLE,
- OPT_CHOICE,
- OPT_SCROLL,
- OPT_SUBMENU,
- OPT_BIND,
- OPT_BUTTON,
-};
-
-struct SubMenu;
-
-struct Option {
- enum OptType type;
- const u8 *label;
- union {
- u32 *uval;
- bool *bval;
- };
- union {
- struct {
- const u8 **choices;
- u32 numChoices;
- };
- struct {
- u32 scrMin;
- u32 scrMax;
- u32 scrStep;
- };
- struct SubMenu *nextMenu;
- void (*actionFn)(struct Option *, s32);
- };
-};
-
-struct SubMenu {
- struct SubMenu *prev; // this is set at runtime to avoid needless complication
- const u8 *label;
- struct Option *opts;
- s32 numOpts;
- s32 select;
- s32 scroll;
-};
-
-/* helper macros */
-
-#define DEF_OPT_TOGGLE(lbl, bv) \
- { .type = OPT_TOGGLE, .label = lbl, .bval = bv }
-#define DEF_OPT_SCROLL(lbl, uv, min, max, st) \
- { .type = OPT_SCROLL, .label = lbl, .uval = uv, .scrMin = min, .scrMax = max, .scrStep = st }
-#define DEF_OPT_CHOICE(lbl, uv, ch) \
- { .type = OPT_CHOICE, .label = lbl, .uval = uv, .choices = ch, .numChoices = sizeof(ch) / sizeof(ch[0]) }
-#define DEF_OPT_SUBMENU(lbl, nm) \
- { .type = OPT_SUBMENU, .label = lbl, .nextMenu = nm }
-#define DEF_OPT_BIND(lbl, uv) \
- { .type = OPT_BIND, .label = lbl, .uval = uv }
-#define DEF_OPT_BUTTON(lbl, act) \
- { .type = OPT_BUTTON, .label = lbl, .actionFn = act }
-#define DEF_SUBMENU(lbl, opt) \
- { .label = lbl, .opts = opt, .numOpts = sizeof(opt) / sizeof(opt[0]) }
-
-/* button action functions */
-
-static void optmenu_act_exit(UNUSED struct Option *self, s32 arg) {
- if (!arg) game_exit(); // only exit on A press and not directions
-}
-
-static void optvideo_reset_window(UNUSED struct Option *self, s32 arg) {
- if (!arg) {
- // Restrict reset to A press and not directions
- configWindow.reset = true;
- configWindow.settings_changed = true;
- }
-}
-
-static void optvideo_apply(UNUSED struct Option *self, s32 arg) {
- if (!arg) configWindow.settings_changed = true;
-}
-
-/* submenu option lists */
-
-#ifdef BETTERCAMERA
-static struct Option optsCamera[] = {
- DEF_OPT_TOGGLE( optsCameraStr[9], &configEnableCamera ),
- DEF_OPT_TOGGLE( optsCameraStr[6], &configCameraAnalog ),
- DEF_OPT_TOGGLE( optsCameraStr[7], &configCameraMouse ),
- DEF_OPT_TOGGLE( optsCameraStr[2], &configCameraInvertX ),
- DEF_OPT_TOGGLE( optsCameraStr[3], &configCameraInvertY ),
- DEF_OPT_SCROLL( optsCameraStr[0], &configCameraXSens, 1, 100, 1 ),
- DEF_OPT_SCROLL( optsCameraStr[1], &configCameraYSens, 1, 100, 1 ),
- DEF_OPT_SCROLL( optsCameraStr[4], &configCameraAggr, 0, 100, 1 ),
- DEF_OPT_SCROLL( optsCameraStr[5], &configCameraPan, 0, 100, 1 ),
- DEF_OPT_SCROLL( optsCameraStr[8], &configCameraDegrade, 0, 100, 1 ),
-};
-#endif
-
-static struct Option optsControls[] = {
- DEF_OPT_BIND( bindStr[ 2], configKeyA ),
- DEF_OPT_BIND( bindStr[ 3], configKeyB ),
- DEF_OPT_BIND( bindStr[ 4], configKeyStart ),
- DEF_OPT_BIND( bindStr[ 5], configKeyL ),
- DEF_OPT_BIND( bindStr[ 6], configKeyR ),
- DEF_OPT_BIND( bindStr[ 7], configKeyZ ),
- DEF_OPT_BIND( bindStr[ 8], configKeyCUp ),
- DEF_OPT_BIND( bindStr[ 9], configKeyCDown ),
- DEF_OPT_BIND( bindStr[10], configKeyCLeft ),
- DEF_OPT_BIND( bindStr[11], configKeyCRight ),
- DEF_OPT_BIND( bindStr[12], configKeyStickUp ),
- DEF_OPT_BIND( bindStr[13], configKeyStickDown ),
- DEF_OPT_BIND( bindStr[14], configKeyStickLeft ),
- DEF_OPT_BIND( bindStr[15], configKeyStickRight ),
- DEF_OPT_BIND( bindStr[16], configKeyChat ),
- // max deadzone is 31000; this is less than the max range of ~32768, but this
- // way, the player can't accidentally lock themselves out of using the stick
- DEF_OPT_SCROLL( bindStr[17], &configStickDeadzone, 0, 100, 1 ),
- DEF_OPT_SCROLL( bindStr[18], &configRumbleStrength, 0, 100, 1)
-};
-
-static struct Option optsVideo[] = {
- DEF_OPT_TOGGLE( optsVideoStr[0], &configWindow.fullscreen ),
- DEF_OPT_TOGGLE( optsVideoStr[5], &configWindow.vsync ),
- DEF_OPT_CHOICE( optsVideoStr[1], &configFiltering, filterChoices ),
- DEF_OPT_TOGGLE( optsVideoStr[7], &configHUD ),
- DEF_OPT_BUTTON( optsVideoStr[4], optvideo_reset_window ),
- DEF_OPT_BUTTON( optsVideoStr[9], optvideo_apply ),
-};
-
-static struct Option optsAudio[] = {
- DEF_OPT_SCROLL( optsAudioStr[0], &configMasterVolume, 0, MAX_VOLUME, 1 ),
- DEF_OPT_SCROLL( optsAudioStr[1], &configMusicVolume, 0, MAX_VOLUME, 1),
- DEF_OPT_SCROLL( optsAudioStr[2], &configSfxVolume, 0, MAX_VOLUME, 1),
- DEF_OPT_SCROLL( optsAudioStr[3], &configEnvVolume, 0, MAX_VOLUME, 1),
- DEF_OPT_TOGGLE( optsAudioStr[4], &configLuigiSounds ),
-};
-
-static struct Option optsCheats[] = {
- DEF_OPT_TOGGLE( optsCheatsStr[0], &Cheats.EnableCheats ),
- DEF_OPT_TOGGLE( optsCheatsStr[1], &Cheats.MoonJump ),
- DEF_OPT_TOGGLE( optsCheatsStr[2], &Cheats.GodMode ),
- DEF_OPT_TOGGLE( optsCheatsStr[3], &Cheats.InfiniteLives ),
- DEF_OPT_TOGGLE( optsCheatsStr[4], &Cheats.SuperSpeed ),
- DEF_OPT_TOGGLE( optsCheatsStr[5], &Cheats.Responsive ),
-
-};
-
-/* submenu definitions */
-
-#ifdef BETTERCAMERA
-static struct SubMenu menuCamera = DEF_SUBMENU( menuStr[4], optsCamera );
-#endif
-static struct SubMenu menuControls = DEF_SUBMENU( menuStr[5], optsControls );
-static struct SubMenu menuVideo = DEF_SUBMENU( menuStr[6], optsVideo );
-static struct SubMenu menuAudio = DEF_SUBMENU( menuStr[7], optsAudio );
-static struct SubMenu menuCheats = DEF_SUBMENU( menuStr[9], optsCheats );
-
-/* main options menu definition */
-
-static struct Option optsMain[] = {
-#ifdef BETTERCAMERA
- DEF_OPT_SUBMENU( menuStr[4], &menuCamera ),
-#endif
- DEF_OPT_SUBMENU( menuStr[5], &menuControls ),
- DEF_OPT_SUBMENU( menuStr[6], &menuVideo ),
- DEF_OPT_SUBMENU( menuStr[7], &menuAudio ),
- DEF_OPT_BUTTON ( menuStr[8], optmenu_act_exit ),
- // NOTE: always keep cheats the last option here because of the half-assed way I toggle them
- DEF_OPT_SUBMENU( menuStr[9], &menuCheats )
-};
-
-static struct SubMenu menuMain = DEF_SUBMENU( menuStr[3], optsMain );
-
-/* implementation */
-
-static s32 optmenu_option_timer = 0;
-static u8 optmenu_hold_count = 0;
-
-static struct SubMenu *currentMenu = &menuMain;
-
-static inline s32 wrap_add(s32 a, const s32 b, const s32 min, const s32 max) {
- a += b;
- if (a < min) a = max - (min - a) + 1;
- else if (a > max) a = min + (a - max) - 1;
- return a;
-}
-
-static void uint_to_hex(u32 num, u8 *dst) {
- u8 places = 4;
- while (places--) {
- const u32 digit = num & 0xF;
- dst[places] = digit;
- num >>= 4;
- }
- dst[4] = DIALOG_CHAR_TERMINATOR;
-}
-
-//Displays a box.
-static void optmenu_draw_box(s16 x1, s16 y1, s16 x2, s16 y2, u8 r, u8 g, u8 b) {
- gDPPipeSync(gDisplayListHead++);
- gDPSetRenderMode(gDisplayListHead++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
- gDPSetCycleType(gDisplayListHead++, G_CYC_FILL);
- gDPSetFillColor(gDisplayListHead++, GPACK_RGBA5551(r, g, b, 255));
- gDPFillRectangle(gDisplayListHead++, x1, y1, x2 - 1, y2 - 1);
- gDPPipeSync(gDisplayListHead++);
- gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE);
-}
-
-static void optmenu_draw_text(s16 x, s16 y, const u8 *str, u8 col) {
- const u8 textX = get_str_x_pos_from_center(x, (u8*)str, 10.0f);
- gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255);
- print_generic_string(textX+1, y-1, str);
- if (col == 0) {
- gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
- } else {
- gDPSetEnvColor(gDisplayListHead++, 255, 32, 32, 255);
- }
- print_generic_string(textX, y, str);
-}
-
-static void optmenu_draw_opt(const struct Option *opt, s16 x, s16 y, u8 sel) {
- u8 buf[32] = { 0 };
-
- if (opt->type == OPT_SUBMENU || opt->type == OPT_BUTTON)
- y -= 6;
-
- optmenu_draw_text(x, y, opt->label, sel);
-
- switch (opt->type) {
- case OPT_TOGGLE:
- optmenu_draw_text(x, y-13, toggleStr[(int)*opt->bval], sel);
- break;
-
- case OPT_CHOICE:
- optmenu_draw_text(x, y-13, opt->choices[*opt->uval], sel);
- break;
-
- case OPT_SCROLL:
- int_to_str(*opt->uval, buf);
- optmenu_draw_text(x, y-13, buf, sel);
- break;
-
- case OPT_BIND:
- x = 112;
- for (u8 i = 0; i < MAX_BINDS; ++i, x += 48) {
- const u8 white = (sel && (optmenu_bind_idx == i));
- // TODO: button names
- if (opt->uval[i] == VK_INVALID) {
- if (optmenu_binding && white)
- optmenu_draw_text(x, y-13, bindStr[1], 1);
- else
- optmenu_draw_text(x, y-13, bindStr[0], white);
- } else {
- uint_to_hex(opt->uval[i], buf);
- optmenu_draw_text(x, y-13, buf, white);
- }
- }
- break;
-
- default: break;
- };
-}
-
-static void optmenu_opt_change(struct Option *opt, s32 val) {
- switch (opt->type) {
- case OPT_TOGGLE:
- *opt->bval = !*opt->bval;
- break;
-
- case OPT_CHOICE:
- *opt->uval = wrap_add(*opt->uval, val, 0, opt->numChoices - 1);
- break;
-
- case OPT_SCROLL:
- *opt->uval = wrap_add(*opt->uval, opt->scrStep * val, opt->scrMin, opt->scrMax);
- break;
-
- case OPT_SUBMENU:
- opt->nextMenu->prev = currentMenu;
- currentMenu = opt->nextMenu;
- break;
-
- case OPT_BUTTON:
- if (opt->actionFn)
- opt->actionFn(opt, val);
- break;
-
- case OPT_BIND:
- if (val == 0xFF) {
- // clear the bind
- opt->uval[optmenu_bind_idx] = VK_INVALID;
- } else if (val == 0) {
- opt->uval[optmenu_bind_idx] = VK_INVALID;
- optmenu_binding = 1;
- controller_get_raw_key(); // clear the last key, which is probably A
- } else {
- optmenu_bind_idx = wrap_add(optmenu_bind_idx, val, 0, MAX_BINDS - 1);
- }
- break;
-
- default: break;
- }
-}
-
-static inline s16 get_hudstr_centered_x(const s16 sx, const u8 *str) {
- const u8 *chr = str;
- s16 len = 0;
- while (*chr != GLOBAR_CHAR_TERMINATOR) ++chr, ++len;
- return sx - len * 6; // stride is 12
-}
-
-//Options menu
-void optmenu_draw(void) {
- s16 scroll;
- s16 scrollpos;
-
- const s16 labelX = get_hudstr_centered_x(160, currentMenu->label);
- gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
- gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
- print_hud_lut_string(HUD_LUT_GLOBAL, labelX, 40, currentMenu->label);
- gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
-
- if (currentMenu->numOpts > 4) {
- optmenu_draw_box(272, 90, 280, 208, 0x80, 0x80, 0x80);
- scrollpos = 54 * ((f32)currentMenu->scroll / (currentMenu->numOpts-4));
- optmenu_draw_box(272, 90+scrollpos, 280, 154+scrollpos, 0xFF, 0xFF, 0xFF);
- }
-
- gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
- gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, 80, SCREEN_WIDTH, SCREEN_HEIGHT);
- for (u8 i = 0; i < currentMenu->numOpts; i++) {
- scroll = 140 - 32 * i + currentMenu->scroll * 32;
- // FIXME: just start from the first visible option bruh
- if (scroll <= 140 && scroll > 32)
- optmenu_draw_opt(¤tMenu->opts[i], 160, scroll, (currentMenu->select == i));
- }
-
- gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
- gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
- gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
- gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
- print_hud_lut_string(HUD_LUT_GLOBAL, 80, 90 + (32 * (currentMenu->select - currentMenu->scroll)), menuStr[0]);
- print_hud_lut_string(HUD_LUT_GLOBAL, 224, 90 + (32 * (currentMenu->select - currentMenu->scroll)), menuStr[0]);
- gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
-}
-
-//This has been separated for interesting reasons. Don't question it.
-void optmenu_draw_prompt(void) {
- gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
- optmenu_draw_text(264, 212, menuStr[1 + optmenu_open], 0);
- gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
-}
-
-void optmenu_toggle(void) {
- if (optmenu_open == 0) {
- #ifndef nosound
- play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
- #endif
-
- // HACK: hide the last option in main if cheats are disabled
- menuMain.numOpts = sizeof(optsMain) / sizeof(optsMain[0]);
- if (!Cheats.EnableCheats) {
- menuMain.numOpts--;
- if (menuMain.select >= menuMain.numOpts) {
- menuMain.select = 0; // don't bother
- menuMain.scroll = 0;
- }
- }
-
- currentMenu = &menuMain;
- optmenu_open = 1;
-
- /* Resets l_counter to 0 every time the options menu is open */
- l_counter = 0;
- } else {
- #ifndef nosound
- play_sound(SOUND_MENU_MARIO_CASTLE_WARP2, gDefaultSoundArgs);
- #endif
- optmenu_open = 0;
- #ifdef BETTERCAMERA
- newcam_init_settings(); // load bettercam settings from config vars
- #endif
- controller_reconfigure(); // rebind using new config values
- configfile_save(configfile_name());
- }
-}
-
-void optmenu_check_buttons(void) {
- if (optmenu_binding) {
- u32 key = controller_get_raw_key();
- if (key != VK_INVALID) {
- #ifndef nosound
- play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
- #endif
- currentMenu->opts[currentMenu->select].uval[optmenu_bind_idx] = key;
- optmenu_binding = 0;
- optmenu_option_timer = 12;
- }
- return;
- }
-
- if (gPlayer1Controller->buttonPressed & R_TRIG)
- optmenu_toggle();
-
- /* Enables cheats if the user press the L trigger 3 times while in the options menu. Also plays a sound. */
-
- if ((gPlayer1Controller->buttonPressed & L_TRIG) && !Cheats.EnableCheats) {
- if (l_counter == 2) {
- Cheats.EnableCheats = true;
- play_sound(SOUND_MENU_STAR_SOUND, gDefaultSoundArgs);
- l_counter = 0;
- } else {
- l_counter++;
- }
- }
-
- if (!optmenu_open) return;
-
- u8 allowInput = 0;
-
- optmenu_option_timer--;
- if (optmenu_option_timer <= 0) {
- if (optmenu_hold_count == 0) {
- optmenu_hold_count++;
- optmenu_option_timer = 10;
- } else {
- optmenu_option_timer = 3;
- }
- allowInput = 1;
- }
-
- if (ABS(gPlayer1Controller->stickY) > 60) {
- if (allowInput) {
- #ifndef nosound
- play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
- #endif
-
- if (gPlayer1Controller->stickY >= 60) {
- currentMenu->select--;
- if (currentMenu->select < 0)
- currentMenu->select = currentMenu->numOpts-1;
- } else {
- currentMenu->select++;
- if (currentMenu->select >= currentMenu->numOpts)
- currentMenu->select = 0;
- }
-
- if (currentMenu->select < currentMenu->scroll)
- currentMenu->scroll = currentMenu->select;
- else if (currentMenu->select > currentMenu->scroll + 3)
- currentMenu->scroll = currentMenu->select - 3;
- }
- } else if (ABS(gPlayer1Controller->stickX) > 60) {
- if (allowInput) {
- #ifndef nosound
- play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
- #endif
- if (gPlayer1Controller->stickX >= 60)
- optmenu_opt_change(¤tMenu->opts[currentMenu->select], 1);
- else
- optmenu_opt_change(¤tMenu->opts[currentMenu->select], -1);
- }
- } else if (gPlayer1Controller->buttonPressed & A_BUTTON) {
- if (allowInput) {
- #ifndef nosound
- play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
- #endif
- optmenu_opt_change(¤tMenu->opts[currentMenu->select], 0);
- }
- } else if (gPlayer1Controller->buttonPressed & B_BUTTON) {
- if (allowInput) {
- if (currentMenu->prev) {
- #ifndef nosound
- play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
- #endif
- currentMenu = currentMenu->prev;
- } else {
- // can't go back, exit the menu altogether
- optmenu_toggle();
- }
- }
- } else if (gPlayer1Controller->buttonPressed & Z_TRIG) {
- // HACK: clear binds with Z
- if (allowInput && currentMenu->opts[currentMenu->select].type == OPT_BIND)
- optmenu_opt_change(¤tMenu->opts[currentMenu->select], 0xFF);
- } else if (gPlayer1Controller->buttonPressed & START_BUTTON) {
- if (allowInput) optmenu_toggle();
- } else {
- optmenu_hold_count = 0;
- optmenu_option_timer = 0;
- }
-}
-
-#endif // EXT_OPTIONS_MENU
diff --git a/src/game/options_menu.h b/src/game/options_menu.h
deleted file mode 100644
index 4828ae9da..000000000
--- a/src/game/options_menu.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef OPTIONS_MENU_H
-#define OPTIONS_MENU_H
-
-void optmenu_toggle(void);
-void optmenu_draw(void);
-void optmenu_draw_prompt(void);
-void optmenu_check_buttons(void);
-
-extern u8 optmenu_open;
-
-#endif // OPTIONS_MENU_H
diff --git a/src/pc/djui/djui.c b/src/pc/djui/djui.c
index c49ccf0fb..af4b1064d 100644
--- a/src/pc/djui/djui.c
+++ b/src/pc/djui/djui.c
@@ -5,11 +5,19 @@
static Gfx* sSavedDisplayListHead = NULL;
struct DjuiRoot* gDjuiRoot = NULL;
-struct DjuiFlowLayout* buttonContainer;
+struct DjuiText* gDjuiPauseOptions = NULL;
void djui_init(void) {
gDjuiRoot = djui_root_create();
+ gDjuiPauseOptions = djui_text_create(&gDjuiRoot->base, "R Button - Options");
+ djui_base_set_size_type(&gDjuiPauseOptions->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
+ djui_base_set_size(&gDjuiPauseOptions->base, 1.0f, 32);
+ djui_base_set_location(&gDjuiPauseOptions->base, 0, 16);
+ djui_text_set_drop_shadow(gDjuiPauseOptions, 0, 0, 0, 255);
+ djui_text_set_alignment(gDjuiPauseOptions, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
+ djui_base_set_visible(&gDjuiPauseOptions->base, false);
+
if (gCLIOpts.Network != NT_SERVER) {
djui_panel_main_create(NULL);
//djui_panel_debug_create();
diff --git a/src/pc/djui/djui.h b/src/pc/djui/djui.h
index 01a625410..533bdca21 100644
--- a/src/pc/djui/djui.h
+++ b/src/pc/djui/djui.h
@@ -38,6 +38,7 @@
#include "djui_panel_host_message.h"
#include "djui_panel_join.h"
#include "djui_panel_join_message.h"
+#include "djui_panel_pause.h"
#include "djui_panel_options.h"
#include "djui_panel_camera.h"
#include "djui_panel_controls.h"
@@ -46,6 +47,7 @@
#include "djui_panel_confirm.h"
extern struct DjuiRoot* gDjuiRoot;
+extern struct DjuiText* gDjuiPauseOptions;
void djui_init(void);
void djui_connect_menu_open(void);
diff --git a/src/pc/djui/djui_interactable.c b/src/pc/djui/djui_interactable.c
index cfcb6b2c3..e1e91723a 100644
--- a/src/pc/djui/djui_interactable.c
+++ b/src/pc/djui/djui_interactable.c
@@ -309,6 +309,9 @@ void djui_interactable_update(void) {
} else if ((padButtons & PAD_BUTTON_B) && !(sLastInteractablePad.button & PAD_BUTTON_B)) {
// pressed back button on controller
djui_panel_back();
+ } else if ((padButtons & PAD_BUTTON_START) && !(sLastInteractablePad.button & PAD_BUTTON_START)) {
+ // pressed start button
+ if (gDjuiPanelPauseCreated) { djui_panel_shutdown(); }
}
if (sInteractableBinding != NULL) {
diff --git a/src/pc/djui/djui_interactable.h b/src/pc/djui/djui_interactable.h
index e16508b19..f83d555f2 100644
--- a/src/pc/djui/djui_interactable.h
+++ b/src/pc/djui/djui_interactable.h
@@ -2,8 +2,9 @@
#include "djui.h"
#include "djui_base.h"
-#define PAD_BUTTON_A ((u16)(1 << 15))
-#define PAD_BUTTON_B ((u16)(1 << 14))
+#define PAD_BUTTON_A ((u16)(1 << 15))
+#define PAD_BUTTON_B ((u16)(1 << 14))
+#define PAD_BUTTON_START ((u16)(1 << 12))
#define MOUSE_BUTTON_1 ((u16)(1 << 0))
diff --git a/src/pc/djui/djui_panel.c b/src/pc/djui/djui_panel.c
index 02182f64f..2660fc7ac 100644
--- a/src/pc/djui/djui_panel.c
+++ b/src/pc/djui/djui_panel.c
@@ -64,7 +64,10 @@ void djui_panel_add(struct DjuiBase* caller, struct DjuiBase* panelBase, struct
void djui_panel_back(void) {
if (sPanelList == NULL) { return; }
- if (sPanelList->parent == NULL) { return; }
+ if (sPanelList->parent == NULL) {
+ if (gDjuiPanelPauseCreated) { djui_panel_shutdown(); }
+ return;
+ }
// deselect cursor input
djui_cursor_input_controlled_center(NULL);
@@ -144,5 +147,6 @@ void djui_panel_shutdown(void) {
gInteractableOverridePad = false;
gDjuiPanelJoinMessageVisible = false;
gDjuiPanelMainCreated = false;
+ gDjuiPanelPauseCreated = false;
djui_cursor_set_visible(false);
}
\ No newline at end of file
diff --git a/src/pc/djui/djui_panel_pause.c b/src/pc/djui/djui_panel_pause.c
new file mode 100644
index 000000000..1ff0ef630
--- /dev/null
+++ b/src/pc/djui/djui_panel_pause.c
@@ -0,0 +1,49 @@
+#include "djui.h"
+
+bool gDjuiPanelPauseCreated = false;
+
+static void djui_panel_pause_resume(struct DjuiBase* caller) {
+ djui_panel_shutdown();
+}
+
+static void djui_panel_pause_quit_yes(struct DjuiBase* caller) {
+ exit(0);
+}
+
+static void djui_panel_pause_quit(struct DjuiBase* caller) {
+ djui_panel_confirm_create(caller,
+ "\\#ff0800\\Q\\#1be700\\U\\#00b3ff\\I\\#ffef00\\T",
+ "Are you sure you want to quit?",
+ djui_panel_pause_quit_yes);
+}
+
+void djui_panel_pause_create(struct DjuiBase* caller) {
+ f32 bodyHeight = 64 * 3 + 16 * 2;
+
+ struct DjuiBase* defaultBase = NULL;
+ struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\P\\#1be700\\A\\#00b3ff\\U\\#ffef00\\S\\#ff0800\\E");
+ struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
+ {
+ struct DjuiButton* button1 = djui_button_create(&body->base, "Options");
+ djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
+ djui_base_set_size(&button1->base, 1.0f, 64);
+ djui_interactable_hook_click(&button1->base, djui_panel_options_create);
+ defaultBase = &button1->base;
+
+ struct DjuiButton* button2 = djui_button_create(&body->base, "Resume");
+ djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
+ djui_base_set_size(&button2->base, 1.0f, 64);
+ djui_interactable_hook_click(&button2->base, djui_panel_pause_resume);
+
+ struct DjuiButton* button3 = djui_button_create(&body->base, "Quit");
+ djui_base_set_size_type(&button3->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
+ djui_base_set_size(&button3->base, 1.0f, 64);
+ djui_interactable_hook_click(&button3->base, djui_panel_pause_quit);
+ djui_button_set_style(button3, 1);
+ }
+
+ djui_panel_add(caller, &panel->base, defaultBase);
+ gInteractableOverridePad = true;
+ gDjuiPanelPauseCreated = true;
+ djui_base_set_visible(&gDjuiPauseOptions->base, false);
+}
diff --git a/src/pc/djui/djui_panel_pause.h b/src/pc/djui/djui_panel_pause.h
new file mode 100644
index 000000000..3d6263187
--- /dev/null
+++ b/src/pc/djui/djui_panel_pause.h
@@ -0,0 +1,6 @@
+#pragma once
+#include "djui.h"
+
+extern bool gDjuiPanelPauseCreated;
+
+void djui_panel_pause_create(struct DjuiBase* caller);