diff --git a/build-windows-visual-studio/sm64ex.vcxproj b/build-windows-visual-studio/sm64ex.vcxproj index 407ce5d8..31c4ff6b 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj +++ b/build-windows-visual-studio/sm64ex.vcxproj @@ -3944,6 +3944,7 @@ + @@ -4389,6 +4390,7 @@ + diff --git a/build-windows-visual-studio/sm64ex.vcxproj.filters b/build-windows-visual-studio/sm64ex.vcxproj.filters index 8ab7358d..c95d9792 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj.filters +++ b/build-windows-visual-studio/sm64ex.vcxproj.filters @@ -15261,6 +15261,9 @@ Source Files\src\pc\djui\panel + + Source Files\src\pc\djui\panel + @@ -16342,5 +16345,8 @@ Source Files\src\pc\djui\panel + + Source Files\src\pc\djui\panel + \ No newline at end of file diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 1b948d01..101b247c 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -92,7 +92,8 @@ bool configCameraAnalog = true; bool configCameraMouse = false; #endif bool configSkipIntro = 0; -bool configShareLives = 0; +bool configShareLives = 0; +bool configEnableCheats = 0; bool configHUD = true; #ifdef DISCORDRPC bool configDiscordRPC = true; @@ -153,6 +154,7 @@ static const struct ConfigOption options[] = { #endif {.name = "skip_intro", .type = CONFIG_TYPE_BOOL, .boolValue = &configSkipIntro}, {.name = "share_lives", .type = CONFIG_TYPE_BOOL, .boolValue = &configShareLives}, + {.name = "enable_cheats", .type = CONFIG_TYPE_BOOL, .boolValue = &configEnableCheats}, #ifdef DISCORDRPC {.name = "discordrpc_enable", .type = CONFIG_TYPE_BOOL, .boolValue = &configDiscordRPC}, #endif diff --git a/src/pc/configfile.h b/src/pc/configfile.h index b71ecc7a..0059b0c4 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -61,6 +61,7 @@ extern bool configCameraAnalog; extern bool configHUD; extern bool configSkipIntro; extern bool configShareLives; +extern bool configEnableCheats; #ifdef DISCORDRPC extern bool configDiscordRPC; #endif diff --git a/src/pc/djui/djui.h b/src/pc/djui/djui.h index 533bdca2..c810cf4b 100644 --- a/src/pc/djui/djui.h +++ b/src/pc/djui/djui.h @@ -45,6 +45,7 @@ #include "djui_panel_display.h" #include "djui_panel_sound.h" #include "djui_panel_confirm.h" +#include "djui_panel_cheats.h" extern struct DjuiRoot* gDjuiRoot; extern struct DjuiText* gDjuiPauseOptions; diff --git a/src/pc/djui/djui_panel_cheats.c b/src/pc/djui/djui_panel_cheats.c new file mode 100644 index 00000000..ee4b2de4 --- /dev/null +++ b/src/pc/djui/djui_panel_cheats.c @@ -0,0 +1,47 @@ +#include "djui.h" +#include "pc/cheats.h" + +void djui_panel_cheats_create(struct DjuiBase* caller) { + f32 bodyHeight = 32 * 5 + 64 * 1 + 16 * 6; + + struct DjuiBase* defaultBase = NULL; + struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\C\\#1be700\\H\\#00b3ff\\E\\#ffef00\\A\\#ff0800\\T\\#1be700\\S"); + struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel); + + { + { + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Moon jump", &Cheats.MoonJump); + djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&checkbox->base, 1.0f, 32); + defaultBase = &checkbox->base; + } + { + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "God mode", &Cheats.GodMode); + djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&checkbox->base, 1.0f, 32); + } + { + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Infinite lives", &Cheats.InfiniteLives); + djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&checkbox->base, 1.0f, 32); + } + { + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Super speed", &Cheats.SuperSpeed); + djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&checkbox->base, 1.0f, 32); + } + { + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Responsive controls", &Cheats.Responsive); + djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&checkbox->base, 1.0f, 32); + } + + struct DjuiButton* button1 = djui_button_create(&body->base, "Back"); + djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&button1->base, 1.0f, 64); + djui_button_set_style(button1, 1); + djui_interactable_hook_click(&button1->base, djui_panel_menu_back); + } + + djui_panel_add(caller, &panel->base, defaultBase); +} diff --git a/src/pc/djui/djui_panel_cheats.h b/src/pc/djui/djui_panel_cheats.h new file mode 100644 index 00000000..d26290f5 --- /dev/null +++ b/src/pc/djui/djui_panel_cheats.h @@ -0,0 +1,4 @@ +#pragma once +#include "djui.h" + +void djui_panel_cheats_create(struct DjuiBase* caller); diff --git a/src/pc/djui/djui_panel_host.c b/src/pc/djui/djui_panel_host.c index 430dac3d..ee5b31ae 100644 --- a/src/pc/djui/djui_panel_host.c +++ b/src/pc/djui/djui_panel_host.c @@ -4,6 +4,7 @@ #include "pc/network/network.h" #include "pc/utils/misc.h" #include "pc/configfile.h" +#include "pc/cheats.h" #ifdef DISCORD_SDK #define DJUI_HOST_NS_IS_SOCKET (configNetworkSystem == 1) @@ -60,9 +61,9 @@ static void djui_panel_host_do_host(struct DjuiBase* caller) { void djui_panel_host_create(struct DjuiBase* caller) { #ifdef DISCORD_SDK - f32 bodyHeight = 32 * 6 + 64 * 2 + 16 * 8; + f32 bodyHeight = 32 * 7 + 64 * 2 + 16 * 9; #else - f32 bodyHeight = 32 * 5 + 64 * 2 + 16 * 7; + f32 bodyHeight = 32 * 6 + 64 * 2 + 16 * 8; #endif struct DjuiBase* defaultBase = NULL; @@ -148,6 +149,10 @@ void djui_panel_host_create(struct DjuiBase* caller) { djui_base_set_size_type(&checkbox3->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&checkbox3->base, 1.0f, 32); + struct DjuiCheckbox* checkbox4 = djui_checkbox_create(&body->base, "Enable cheats", &configEnableCheats); + djui_base_set_size_type(&checkbox4->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&checkbox4->base, 1.0f, 32); + struct DjuiRect* rect3 = djui_rect_create(&body->base); djui_base_set_size_type(&rect3->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&rect3->base, 1.0f, 64); diff --git a/src/pc/djui/djui_panel_pause.c b/src/pc/djui/djui_panel_pause.c index 1ff0ef63..1aa843db 100644 --- a/src/pc/djui/djui_panel_pause.c +++ b/src/pc/djui/djui_panel_pause.c @@ -1,4 +1,5 @@ #include "djui.h" +#include "pc/cheats.h" bool gDjuiPanelPauseCreated = false; @@ -19,6 +20,7 @@ static void djui_panel_pause_quit(struct DjuiBase* caller) { void djui_panel_pause_create(struct DjuiBase* caller) { f32 bodyHeight = 64 * 3 + 16 * 2; + if (Cheats.EnableCheats) { bodyHeight += 64 + 16; } struct DjuiBase* defaultBase = NULL; struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\P\\#1be700\\A\\#00b3ff\\U\\#ffef00\\S\\#ff0800\\E"); @@ -30,6 +32,13 @@ void djui_panel_pause_create(struct DjuiBase* caller) { djui_interactable_hook_click(&button1->base, djui_panel_options_create); defaultBase = &button1->base; + if (Cheats.EnableCheats) { + struct DjuiButton* button1 = djui_button_create(&body->base, "Cheats"); + 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_cheats_create); + } + 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); diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 36adfe94..24e7c663 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -9,6 +9,7 @@ #include "discord/discord.h" #endif #include "pc/configfile.h" +#include "pc/cheats.h" #include "pc/debuglog.h" // Mario 64 specific externs @@ -37,6 +38,7 @@ struct ServerSettings gServerSettings = { .playerKnockbackStrength = 25, .skipIntro = 0, .shareLives = 0, + .enableCheats = 0, }; void network_set_system(enum NetworkSystemType nsType) { @@ -62,6 +64,8 @@ bool network_init(enum NetworkType inNetworkType) { gServerSettings.stayInLevelAfterStar = configStayInLevelAfterStar; gServerSettings.skipIntro = configSkipIntro; gServerSettings.shareLives = configShareLives; + gServerSettings.enableCheats = configEnableCheats; + Cheats.EnableCheats = gServerSettings.enableCheats; // initialize the network system int rc = gNetworkSystem->initialize(inNetworkType); diff --git a/src/pc/network/network.h b/src/pc/network/network.h index f9e18249..d6dd42cc 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -76,6 +76,7 @@ struct ServerSettings { u8 stayInLevelAfterStar; u8 skipIntro; u8 shareLives; + u8 enableCheats; }; // Networking-specific externs diff --git a/src/pc/network/packets/packet_join.c b/src/pc/network/packets/packet_join.c index 173eadf6..9de84ee8 100644 --- a/src/pc/network/packets/packet_join.c +++ b/src/pc/network/packets/packet_join.c @@ -11,6 +11,7 @@ #include "PR/os_eeprom.h" #include "pc/network/version.h" #include "pc/djui/djui.h" +#include "pc/cheats.h" #include "pc/utils/string_builder.h" #define DISABLE_MODULE_LOG 1 #include "pc/debuglog.h" @@ -65,6 +66,7 @@ void network_send_join(struct Packet* joinRequestPacket) { packet_write(&p, &gServerSettings.stayInLevelAfterStar, sizeof(u8)); packet_write(&p, &gServerSettings.skipIntro, sizeof(u8)); packet_write(&p, &gServerSettings.shareLives, sizeof(u8)); + packet_write(&p, &gServerSettings.enableCheats, sizeof(u8)); packet_write(&p, eeprom, sizeof(u8) * 512); u8 modCount = string_linked_list_count(&gRegisteredMods); @@ -124,9 +126,12 @@ void network_receive_join(struct Packet* p) { packet_read(p, &gServerSettings.stayInLevelAfterStar, sizeof(u8)); packet_read(p, &gServerSettings.skipIntro, sizeof(u8)); packet_read(p, &gServerSettings.shareLives, sizeof(u8)); + packet_read(p, &gServerSettings.enableCheats, sizeof(u8)); packet_read(p, eeprom, sizeof(u8) * 512); packet_read(p, &modCount, sizeof(u8)); + Cheats.EnableCheats = gServerSettings.enableCheats; + struct StringLinkedList head = { 0 }; for (int i = 0; i < modCount; i++) { char* modName = (char*) &p->buffer[p->cursor];