diff --git a/bin/segment2.c b/bin/segment2.c
index afaf6f87..882a3725 100644
--- a/bin/segment2.c
+++ b/bin/segment2.c
@@ -3550,7 +3550,7 @@ const u8* const font_normal_chars[] = {
texture_font_normal_char_92, // |
texture_font_normal_char_93, // }
texture_font_char_us_tilde, // ~
- texture_font_char_us_interpunct, // DEL
+ texture_font_char_us_star_filled, // DEL
};
const f32 font_normal_widths[] = {
@@ -3567,5 +3567,5 @@ const f32 font_normal_widths[] = {
/* a b c d e f g h i j k l m n o p q r s t u v w x y z */
0.3750f, 0.3125f, 0.3125f, 0.3750f, 0.3125f, 0.3125f, 0.3750f, 0.3125f, 0.2500f, 0.3125f, 0.3125f, 0.1875f, 0.4375f, 0.3125f, 0.3125f, 0.3125f, 0.3750f, 0.3125f, 0.3125f, 0.3125f, 0.3125f, 0.3125f, 0.4375f, 0.4375f, 0.3125f, 0.3125f,
/* { | } ~ DEL */
- 0.3125f, 0.2500f, 0.3125f, 0.5000f, 0.4375f
+ 0.3125f, 0.2500f, 0.3125f, 0.5000f, 0.5000f
};
\ No newline at end of file
diff --git a/build-windows-visual-studio/sm64ex.vcxproj b/build-windows-visual-studio/sm64ex.vcxproj
index 3155c82e..de6cdfbc 100644
--- a/build-windows-visual-studio/sm64ex.vcxproj
+++ b/build-windows-visual-studio/sm64ex.vcxproj
@@ -3947,6 +3947,7 @@
+
@@ -4390,6 +4391,7 @@
+
diff --git a/build-windows-visual-studio/sm64ex.vcxproj.filters b/build-windows-visual-studio/sm64ex.vcxproj.filters
index 39eb45db..a9bc71dd 100644
--- a/build-windows-visual-studio/sm64ex.vcxproj.filters
+++ b/build-windows-visual-studio/sm64ex.vcxproj.filters
@@ -15255,6 +15255,9 @@
Source Files\src\pc\djui\component\compound
+
+ Source Files\src\pc\djui\panel
+
@@ -16330,5 +16333,8 @@
Source Files\src\pc\djui\component\compound
+
+ Source Files\src\pc\djui\panel
+
\ No newline at end of file
diff --git a/src/game/level_update.c b/src/game/level_update.c
index 6017be7e..43067d4b 100644
--- a/src/game/level_update.c
+++ b/src/game/level_update.c
@@ -1306,7 +1306,8 @@ s32 init_level(void) {
set_mario_action(gMarioState, ACT_IDLE, 0);
} else if (gDebugLevelSelect == 0) {
if (gMarioState->action != ACT_UNINITIALIZED) {
- if (save_file_exists(gCurrSaveFileNum - 1)) {
+ bool skipIntro = (gNetworkType == NT_NONE);
+ if (save_file_exists(gCurrSaveFileNum - 1) || skipIntro) {
set_mario_action(gMarioState, ACT_IDLE, 0);
} else if (gCLIOpts.SkipIntro == 0 && configSkipIntro == 0 && gServerSettings.skipIntro == 0) {
set_mario_action(gMarioState, ACT_INTRO_CUTSCENE, 0);
@@ -1377,6 +1378,7 @@ s32 lvl_init_from_save_file(UNUSED s16 arg0, s32 levelNum) {
sWarpDest.type = WARP_TYPE_NOT_WARPING;
sDelayedWarpOp = WARP_OP_NONE;
gShouldNotPlayCastleMusic = !save_file_exists(gCurrSaveFileNum - 1) && gCLIOpts.SkipIntro == 0 && configSkipIntro == 0;
+ if (gNetworkType == NT_NONE) { gShouldNotPlayCastleMusic = true; }
gCurrLevelNum = levelNum;
gCurrCourseNum = COURSE_NONE;
diff --git a/src/pc/djui/djui.h b/src/pc/djui/djui.h
index f4f2d63f..bd277344 100644
--- a/src/pc/djui/djui.h
+++ b/src/pc/djui/djui.h
@@ -34,6 +34,7 @@
#include "djui_panel_debug.h"
#include "djui_panel_main.h"
#include "djui_panel_host.h"
+#include "djui_panel_host_save.h"
#include "djui_panel_host_message.h"
#include "djui_panel_join.h"
#include "djui_panel_join_message.h"
diff --git a/src/pc/djui/djui_panel_host.c b/src/pc/djui/djui_panel_host.c
index 5b604405..436645da 100644
--- a/src/pc/djui/djui_panel_host.c
+++ b/src/pc/djui/djui_panel_host.c
@@ -1,5 +1,6 @@
#include
#include "djui.h"
+#include "game/save_file.h"
#include "pc/network/network.h"
#include "pc/utils/misc.h"
#include "pc/configfile.h"
@@ -91,6 +92,26 @@ void djui_panel_host_create(struct DjuiBase* caller) {
#endif
sInputboxPort = inputbox1;
}
+
+ struct DjuiRect* rect2 = djui_rect_create(&body->base);
+ djui_base_set_size_type(&rect2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
+ djui_base_set_size(&rect2->base, 1.0f, 32);
+ djui_base_set_color(&rect2->base, 0, 0, 0, 0);
+ {
+ struct DjuiText* text1 = djui_text_create(&rect2->base, "Save Slot");
+ djui_base_set_size_type(&text1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
+ djui_base_set_color(&text1->base, 200, 200, 200, 255);
+ djui_base_set_size(&text1->base, 0.485f, 64);
+ djui_base_set_alignment(&text1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
+
+ char starString[32] = { 0 };
+ snprintf(starString, 32, "%c x%d", '~' + 1, save_file_get_total_star_count(configHostSaveSlot - 1, 0, 24));
+ struct DjuiButton* button1 = djui_button_create(&rect2->base, starString);
+ djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
+ djui_base_set_size(&button1->base, 0.5f, 32);
+ djui_base_set_alignment(&button1->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
+ djui_interactable_hook_click(&button1->base, djui_panel_host_save_create);
+ }
char* iChoices[3] = { "Non-solid", "Solid", "Friendly Fire" };
struct DjuiSelectionbox* selectionbox2 = djui_selectionbox_create(&body->base, "Player interaction", iChoices, 3, &configFiltering);
@@ -109,19 +130,19 @@ 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 DjuiRect* rect2 = djui_rect_create(&body->base);
- djui_base_set_size_type(&rect2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
- djui_base_set_size(&rect2->base, 1.0f, 64);
- djui_base_set_color(&rect2->base, 0, 0, 0, 0);
+ 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);
+ djui_base_set_color(&rect3->base, 0, 0, 0, 0);
{
- struct DjuiButton* button1 = djui_button_create(&rect2->base, "Back");
+ struct DjuiButton* button1 = djui_button_create(&rect3->base, "Back");
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&button1->base, 0.485f, 64);
djui_base_set_alignment(&button1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
djui_button_set_style(button1, 1);
djui_interactable_hook_click(&button1->base, djui_panel_menu_back);
- struct DjuiButton* button2 = djui_button_create(&rect2->base, "Host");
+ struct DjuiButton* button2 = djui_button_create(&rect3->base, "Host");
djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&button2->base, 0.485f, 64);
djui_base_set_alignment(&button2->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
diff --git a/src/pc/djui/djui_panel_host_message.c b/src/pc/djui/djui_panel_host_message.c
index dfd35afe..491386c7 100644
--- a/src/pc/djui/djui_panel_host_message.c
+++ b/src/pc/djui/djui_panel_host_message.c
@@ -23,6 +23,8 @@ Forward port '\\#d0d0ff\\%d\\#c8c8c8\\' for UDP.\
void djui_panel_host_message_do_host(struct DjuiBase* caller) {
djui_panel_shutdown();
+ extern s16 gCurrSaveFileNum;
+ gCurrSaveFileNum = configHostSaveSlot;
#ifndef DISCORD_SDK
configNetworkSystem = 1;
network_set_system(NS_SOCKET);
diff --git a/src/pc/djui/djui_panel_host_save.c b/src/pc/djui/djui_panel_host_save.c
new file mode 100644
index 00000000..b5fdfb37
--- /dev/null
+++ b/src/pc/djui/djui_panel_host_save.c
@@ -0,0 +1,59 @@
+#include
+#include "djui.h"
+#include "game/save_file.h"
+#include "pc/configfile.h"
+
+static struct DjuiBase* sSaveButtonCaller = NULL;
+static struct DjuiButton* sSaveButtons[4] = { NULL };
+
+static void djui_panel_host_save_update_button(struct DjuiButton* button, int slot) {
+ char starString[32] = { 0 };
+ snprintf(starString, 32, "%c x%d", '~' + 1, save_file_get_total_star_count(slot, 0, 24));
+ djui_text_set_text(button->text, starString);
+}
+
+static void djui_panel_host_save_button_click(struct DjuiBase* caller) {
+ configHostSaveSlot = caller->tag + 1;
+ djui_panel_host_save_update_button((struct DjuiButton*)sSaveButtonCaller, configHostSaveSlot - 1);
+ djui_panel_menu_back(caller);
+}
+
+static void djui_panel_host_save_erase_button_click(struct DjuiBase* caller) {
+ save_file_erase(caller->tag);
+ djui_panel_host_save_update_button(sSaveButtons[caller->tag], caller->tag);
+}
+
+void djui_panel_host_save_create(struct DjuiBase* caller) {
+ f32 bodyHeight = 32 * 4 + 64 * 1 + 16 * 5;
+ sSaveButtonCaller = caller;
+
+ struct DjuiBase* defaultBase = NULL;
+ struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\S\\#1be700\\A\\#00b3ff\\V\\#ffef00\\E");
+ struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
+ {
+ for (int i = 0; i < 4; i++) {
+ struct DjuiRect* rect1 = djui_rect_create(&body->base);
+ djui_base_set_size_type(&rect1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
+ djui_base_set_size(&rect1->base, 1.0f, 32);
+ djui_base_set_color(&rect1->base, 0, 0, 0, 0);
+ {
+ struct DjuiButton* button1 = djui_button_create(&rect1->base, "");
+ djui_panel_host_save_update_button(button1, i);
+ djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
+ djui_base_set_size(&button1->base, 0.74f, 32);
+ djui_interactable_hook_click(&button1->base, djui_panel_host_save_button_click);
+ button1->base.tag = i;
+ if (i == (int)(configHostSaveSlot - 1)) { defaultBase = &button1->base; }
+ sSaveButtons[i] = button1;
+
+ struct DjuiButton* button2 = djui_button_create(&rect1->base, "erase");
+ djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
+ djui_base_set_size(&button2->base, 0.24f, 32);
+ djui_base_set_alignment(&button2->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
+ djui_interactable_hook_click(&button2->base, djui_panel_host_save_erase_button_click);
+ }
+ }
+ }
+
+ djui_panel_add(caller, &panel->base, defaultBase);
+}
diff --git a/src/pc/djui/djui_panel_host_save.h b/src/pc/djui/djui_panel_host_save.h
new file mode 100644
index 00000000..0ce88cb6
--- /dev/null
+++ b/src/pc/djui/djui_panel_host_save.h
@@ -0,0 +1,4 @@
+#pragma once
+#include "djui.h"
+
+void djui_panel_host_save_create(struct DjuiBase* caller);