mirror of
https://github.com/AloUltraExt/sm64ex-alo.git
synced 2025-01-23 16:15:36 -05:00
add n64 configs, ext ram and crash screen
This commit is contained in:
parent
0f694a8ba8
commit
f51e14249f
16 changed files with 241 additions and 321 deletions
3
Makefile
3
Makefile
|
@ -1266,6 +1266,9 @@ $(BUILD_DIR)/src/menu/file_select.o: $(BUILD_DIR)/include/text_strings.h $(LA
|
|||
$(BUILD_DIR)/src/menu/star_select.o: $(BUILD_DIR)/include/text_strings.h $(LANG_O_FILES)
|
||||
$(BUILD_DIR)/src/game/ingame_menu.o: $(BUILD_DIR)/include/text_strings.h $(LANG_O_FILES)
|
||||
|
||||
ifeq ($(TARGET_N64),1)
|
||||
$(BUILD_DIR)/src/game/mem_error_screen.o: $(BUILD_DIR)/include/text_strings.h
|
||||
endif
|
||||
|
||||
ifeq ($(EXT_OPTIONS_MENU),1)
|
||||
|
||||
|
|
|
@ -1,299 +0,0 @@
|
|||
diff --git a/Makefile b/Makefile
|
||||
index f81fd27b..318140f2 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -419,6 +419,7 @@ $(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_menu_strings.h
|
||||
$(BUILD_DIR)/src/menu/file_select.o: $(BUILD_DIR)/include/text_strings.h
|
||||
$(BUILD_DIR)/src/menu/star_select.o: $(BUILD_DIR)/include/text_strings.h
|
||||
$(BUILD_DIR)/src/game/ingame_menu.o: $(BUILD_DIR)/include/text_strings.h
|
||||
+$(BUILD_DIR)/src/game/mem_error_screen.o: $(BUILD_DIR)/include/text_strings.h
|
||||
|
||||
|
||||
#==============================================================================#
|
||||
diff --git a/include/segments.h b/include/segments.h
|
||||
index a8c1bf97..84c3d7a4 100644
|
||||
--- a/include/segments.h
|
||||
+++ b/include/segments.h
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef SEGMENTS_H
|
||||
#define SEGMENTS_H
|
||||
|
||||
+/* Use expansion pack RAM */
|
||||
+#define USE_EXT_RAM 1
|
||||
+
|
||||
/*
|
||||
* Memory addresses for segments. Ideally, this header file would not be
|
||||
* needed, and the addresses would be defined in sm64.ld and linker-inserted
|
||||
diff --git a/include/text_strings.h.in b/include/text_strings.h.in
|
||||
index 749179b1..2f6f7a3c 100644
|
||||
--- a/include/text_strings.h.in
|
||||
+++ b/include/text_strings.h.in
|
||||
@@ -25,6 +25,11 @@
|
||||
#define TEXT_PAUSE _("PAUSE") // Pause text, Castle Courses
|
||||
#define TEXT_HUD_CONGRATULATIONS _("CONGRATULATIONS") // Course Complete Text, Bowser Courses
|
||||
|
||||
+// Memory Expansion Error Screen
|
||||
+#define TEXT_CONSOLE_8MB _("If you're using an N64 console, then you will need to buy an\nExpansion Pak to play this ROM hack.")
|
||||
+#define TEXT_PJ64 _("If you are using PJ64 1.6, go to:\nOptions > Settings > Rom Settings Tab > Memory Size\nthen select 8 MB from the drop-down box.")
|
||||
+#define TEXT_PJ64_2 _("If you are using PJ64 2.X, go to:\nOptions > Settings > Config: > Memory Size, select 8 MB")
|
||||
+
|
||||
#if defined(VERSION_JP) || defined(VERSION_SH)
|
||||
|
||||
/**
|
||||
diff --git a/levels/entry.c b/levels/entry.c
|
||||
index 17c773ed..677a5ae9 100644
|
||||
--- a/levels/entry.c
|
||||
+++ b/levels/entry.c
|
||||
@@ -15,3 +15,12 @@ const LevelScript level_script_entry[] = {
|
||||
EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, /*entry*/ level_intro_splash_screen),
|
||||
JUMP(/*target*/ level_script_entry),
|
||||
};
|
||||
+
|
||||
+const LevelScript level_script_entry_error_screen[] = {
|
||||
+ INIT_LEVEL(),
|
||||
+ SLEEP(/*frames*/ 2),
|
||||
+ BLACKOUT(/*active*/ FALSE),
|
||||
+ SET_REG(/*value*/ 0),
|
||||
+ EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, /*entry*/ level_intro_entry_error_screen),
|
||||
+ JUMP(/*target*/ level_script_entry_error_screen),
|
||||
+};
|
||||
diff --git a/levels/intro/geo.c b/levels/intro/geo.c
|
||||
index 7a297fe7..71b16442 100644
|
||||
--- a/levels/intro/geo.c
|
||||
+++ b/levels/intro/geo.c
|
||||
@@ -15,6 +15,24 @@
|
||||
|
||||
#include "levels/intro/header.h"
|
||||
|
||||
+const GeoLayout intro_geo_error_screen[] = {
|
||||
+ GEO_NODE_SCREEN_AREA(0, SCREEN_WIDTH/2, SCREEN_HEIGHT/2, SCREEN_WIDTH/2, SCREEN_HEIGHT/2),
|
||||
+ GEO_OPEN_NODE(),
|
||||
+ GEO_ZBUFFER(0),
|
||||
+ GEO_OPEN_NODE(),
|
||||
+ GEO_NODE_ORTHO(100),
|
||||
+ GEO_OPEN_NODE(),
|
||||
+ GEO_BACKGROUND_COLOR(0x0001),
|
||||
+ GEO_CLOSE_NODE(),
|
||||
+ GEO_CLOSE_NODE(),
|
||||
+ GEO_ZBUFFER(0),
|
||||
+ GEO_OPEN_NODE(),
|
||||
+ GEO_ASM(0, geo18_display_error_message),
|
||||
+ GEO_CLOSE_NODE(),
|
||||
+ GEO_CLOSE_NODE(),
|
||||
+ GEO_END(),
|
||||
+};
|
||||
+
|
||||
// 0x0E0002D0
|
||||
const GeoLayout intro_geo_0002D0[] = {
|
||||
GEO_NODE_SCREEN_AREA(0, SCREEN_WIDTH/2, SCREEN_HEIGHT/2, SCREEN_WIDTH/2, SCREEN_HEIGHT/2),
|
||||
diff --git a/levels/intro/header.h b/levels/intro/header.h
|
||||
index 99277e86..04797cd7 100644
|
||||
--- a/levels/intro/header.h
|
||||
+++ b/levels/intro/header.h
|
||||
@@ -26,4 +26,8 @@ extern const LevelScript script_intro_L3[];
|
||||
extern const LevelScript script_intro_L4[];
|
||||
extern const LevelScript script_intro_L5[];
|
||||
|
||||
+extern const GeoLayout intro_geo_error_screen[];
|
||||
+extern const LevelScript level_intro_entry_error_screen[];
|
||||
+extern Gfx *geo18_display_error_message(u32 run, UNUSED struct GraphNode *sp44, UNUSED u32 sp48);
|
||||
+
|
||||
#endif
|
||||
diff --git a/levels/intro/script.c b/levels/intro/script.c
|
||||
index a130cc04..926c0d09 100644
|
||||
--- a/levels/intro/script.c
|
||||
+++ b/levels/intro/script.c
|
||||
@@ -18,6 +18,21 @@
|
||||
#include "make_const_nonconst.h"
|
||||
#include "levels/intro/header.h"
|
||||
|
||||
+const LevelScript level_intro_entry_error_screen[] = {
|
||||
+ INIT_LEVEL(),
|
||||
+ FIXED_LOAD(/*loadAddr*/ _goddardSegmentStart, /*romStart*/ _goddardSegmentRomStart, /*romEnd*/ _goddardSegmentRomEnd),
|
||||
+ LOAD_MIO0(/*seg*/ 0x07, _intro_segment_7SegmentRomStart, _intro_segment_7SegmentRomEnd),
|
||||
+ ALLOC_LEVEL_POOL(),
|
||||
+
|
||||
+ AREA(/*index*/ 1, intro_geo_error_screen),
|
||||
+ END_AREA(),
|
||||
+
|
||||
+ FREE_LEVEL_POOL(),
|
||||
+ LOAD_AREA(/*area*/ 1),
|
||||
+ SLEEP(/*frames*/ 32767),
|
||||
+ EXIT_AND_EXECUTE(/*seg*/ 0x14, _introSegmentRomStart, _introSegmentRomEnd, level_intro_entry_error_screen),
|
||||
+};
|
||||
+
|
||||
const LevelScript level_intro_splash_screen[] = {
|
||||
INIT_LEVEL(),
|
||||
FIXED_LOAD(/*loadAddr*/ _goddardSegmentStart, /*romStart*/ _goddardSegmentRomStart, /*romEnd*/ _goddardSegmentRomEnd),
|
||||
diff --git a/src/engine/level_script.h b/src/engine/level_script.h
|
||||
index d41a91c8..7d047236 100644
|
||||
--- a/src/engine/level_script.h
|
||||
+++ b/src/engine/level_script.h
|
||||
@@ -6,6 +6,7 @@
|
||||
struct LevelCommand;
|
||||
|
||||
extern u8 level_script_entry[];
|
||||
+extern u8 level_script_entry_error_screen[];
|
||||
|
||||
struct LevelCommand *level_script_execute(struct LevelCommand *cmd);
|
||||
|
||||
diff --git a/src/game/main.c b/src/game/main.c
|
||||
index 9615f25a..e2d7b3d4 100644
|
||||
--- a/src/game/main.c
|
||||
+++ b/src/game/main.c
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "segments.h"
|
||||
#include "main.h"
|
||||
#include "rumble_init.h"
|
||||
+#include "mem_error_screen.h"
|
||||
|
||||
// Message IDs
|
||||
#define MESG_SP_COMPLETE 100
|
||||
@@ -127,6 +128,10 @@ void alloc_pool(void) {
|
||||
void *start = (void *) SEG_POOL_START;
|
||||
void *end = (void *) SEG_POOL_END;
|
||||
|
||||
+ // Detect memory size
|
||||
+ if (does_pool_end_lie_out_of_bounds(end))
|
||||
+ end = (void *)SEG_POOL_END_4MB;
|
||||
+
|
||||
main_pool_init(start, end);
|
||||
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);
|
||||
}
|
||||
@@ -332,7 +337,10 @@ void thread3_main(UNUSED void *arg) {
|
||||
create_thread(&gSoundThread, 4, thread4_sound, NULL, gThread4Stack + 0x2000, 20);
|
||||
osStartThread(&gSoundThread);
|
||||
|
||||
- create_thread(&gGameLoopThread, 5, thread5_game_loop, NULL, gThread5Stack + 0x2000, 10);
|
||||
+ if (!gNotEnoughMemory)
|
||||
+ create_thread(&gGameLoopThread, 5, thread5_game_loop, NULL, gThread5Stack + 0x2000, 10);
|
||||
+ else
|
||||
+ create_thread(&gGameLoopThread, 5, thread5_mem_error_message_loop, NULL, gThread5Stack + 0x2000, 10);
|
||||
osStartThread(&gGameLoopThread);
|
||||
|
||||
while (TRUE) {
|
||||
diff --git a/src/game/mem_error_screen.c b/src/game/mem_error_screen.c
|
||||
new file mode 100644
|
||||
index 00000000..81efaf91
|
||||
--- /dev/null
|
||||
+++ b/src/game/mem_error_screen.c
|
||||
@@ -0,0 +1,104 @@
|
||||
+/* clang-format off */
|
||||
+/*
|
||||
+ * mem_error_screen.inc.c
|
||||
+ *
|
||||
+ * This enhancement should be used for ROM hacks that require the expansion pak.
|
||||
+ *
|
||||
+ */
|
||||
+/* clang-format on */
|
||||
+
|
||||
+#include <types.h>
|
||||
+#include "segments.h"
|
||||
+#include "text_strings.h"
|
||||
+#include "game_init.h"
|
||||
+#include "main.h"
|
||||
+#include "print.h"
|
||||
+#include "ingame_menu.h"
|
||||
+#include "segment2.h"
|
||||
+#include "../engine/level_script.h"
|
||||
+
|
||||
+// Ensure that USE_EXT_RAM is defined.
|
||||
+#ifndef USE_EXT_RAM
|
||||
+#error You have to define USE_EXT_RAM in 'include/segments.h'
|
||||
+#endif
|
||||
+
|
||||
+// Require 8 MB of RAM, even if the pool doesn't go into extended memory.
|
||||
+// Change the '8' to whatever MB limit you want.
|
||||
+// Note: only special emulators allow for RAM sizes above 8 MB.
|
||||
+#define REQUIRED_MIN_MEM_SIZE 1048576 * 8
|
||||
+
|
||||
+u8 gNotEnoughMemory = FALSE;
|
||||
+u8 gDelayForErrorMessage = 0;
|
||||
+
|
||||
+u8 does_pool_end_lie_out_of_bounds(void *end) {
|
||||
+ u32 endPhy = ((u32) end) & 0x1FFFFFFF;
|
||||
+ u32 memSize = *((u32 *) 0x80000318);
|
||||
+
|
||||
+ if (endPhy > memSize) {
|
||||
+ gNotEnoughMemory = TRUE;
|
||||
+ return TRUE;
|
||||
+ } else {
|
||||
+ if (memSize < REQUIRED_MIN_MEM_SIZE) {
|
||||
+ gNotEnoughMemory = TRUE;
|
||||
+ }
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+// If you're using an N64 console, then you will need to buy an\nexpansion pak to play this ROM hack.
|
||||
+u8 text_console_8mb[] = { TEXT_CONSOLE_8MB };
|
||||
+
|
||||
+// If you are using PJ64 1.6, go to: Options ► Settings ► Rom Settings Tab ► Memory Size then select 8
|
||||
+// MB from the drop-down box.
|
||||
+u8 text_pj64[] = { TEXT_PJ64 };
|
||||
+
|
||||
+// If you are using PJ64 2.X, go to: Options ► Settings ► Config: ► Memory Size, select 8 MB
|
||||
+u8 text_pj64_2[] = { TEXT_PJ64_2 };
|
||||
+
|
||||
+Gfx *geo18_display_error_message(u32 run, UNUSED struct GraphNode *sp44, UNUSED u32 sp48) {
|
||||
+ if (run) {
|
||||
+ if (gDelayForErrorMessage > 0) {
|
||||
+ // Draw color text title.
|
||||
+ print_text(10, 210, "ERROR Need more memory");
|
||||
+
|
||||
+ // Init generic text rendering
|
||||
+ create_dl_ortho_matrix();
|
||||
+ gSPDisplayList(gDisplayListHead++,
|
||||
+ dl_ia_text_begin); // Init rendering stuff for generic text
|
||||
+
|
||||
+ // Set text color to white
|
||||
+ gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
||||
+
|
||||
+ print_generic_string(8, 170, text_console_8mb);
|
||||
+ print_generic_string(8, 120, text_pj64);
|
||||
+ print_generic_string(8, 54, text_pj64_2);
|
||||
+
|
||||
+ // Cleanup
|
||||
+ gSPDisplayList(gDisplayListHead++,
|
||||
+ dl_ia_text_end); // Reset back to default render settings.
|
||||
+ gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
+ } else {
|
||||
+ gDelayForErrorMessage += 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+// Basic main loop for the error screen. Note that controllers are not enabled here.
|
||||
+void thread5_mem_error_message_loop(UNUSED void *arg) {
|
||||
+ struct LevelCommand *addr;
|
||||
+
|
||||
+ setup_game_memory();
|
||||
+ set_vblank_handler(2, &gGameVblankHandler, &gGameVblankQueue, (OSMesg) 1);
|
||||
+
|
||||
+ addr = segmented_to_virtual(level_script_entry_error_screen);
|
||||
+
|
||||
+ rendering_init();
|
||||
+
|
||||
+ while (1) {
|
||||
+ config_gfx_pool();
|
||||
+ addr = level_script_execute(addr);
|
||||
+ display_and_vsync();
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/game/mem_error_screen.h b/src/game/mem_error_screen.h
|
||||
new file mode 100644
|
||||
index 00000000..9fbff34c
|
||||
--- /dev/null
|
||||
+++ b/src/game/mem_error_screen.h
|
||||
@@ -0,0 +1,8 @@
|
||||
+#ifndef MEM_ERROR_SCREEN_H
|
||||
+#define MEM_ERROR_SCREEN_H
|
||||
+
|
||||
+extern u8 gNotEnoughMemory;
|
||||
+void thread5_mem_error_message_loop(UNUSED void *arg);
|
||||
+u8 does_pool_end_lie_out_of_bounds(void *end);
|
||||
+
|
||||
+#endif
|
|
@ -38,6 +38,14 @@
|
|||
/// Fixes bug where the angle speed isn't preserved while in a pole
|
||||
#define BUGFIX_PRESERVE_VEL_POLE (0 || VERSION_SH || QOL_FIXES)
|
||||
|
||||
// Define Settings
|
||||
// Enables extended ram on N64
|
||||
#define N64_USE_EXTENDED_RAM TRUE
|
||||
// Enables crash screen on N64
|
||||
#define N64_CRASH_SCREEN TRUE
|
||||
// Ignores checks and fully defines if intro should be skipped
|
||||
#define SKIP_PEACH_CUTSCENE FALSE
|
||||
|
||||
// Test End Cutscene without beating Bowser 3
|
||||
#define DEBUG_TEST_ENDCUTSCENE 0
|
||||
// Test Credits without beating Bowser 3 (Recommended to use with TEST_ENDCUTSCENE)
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
#ifndef SEGMENTS_H
|
||||
#define SEGMENTS_H
|
||||
|
||||
#ifdef BETTERCAMERA
|
||||
#define USE_EXT_RAM
|
||||
#endif
|
||||
#include "config.h"
|
||||
|
||||
#ifndef LINKER
|
||||
#include "segment_symbols.h"
|
||||
|
@ -17,11 +15,11 @@
|
|||
* to cast the addresses to pointers in this file, since that would be invalid
|
||||
* linker script syntax.
|
||||
*/
|
||||
|
||||
#ifndef USE_EXT_RAM
|
||||
#define RAM_END 0x80400000
|
||||
#else
|
||||
#if N64_USE_EXTENDED_RAM
|
||||
#define RAM_END 0x80800000
|
||||
#define RAM_END_4MB 0x80400000
|
||||
#else
|
||||
#define RAM_END 0x80400000
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -32,6 +30,10 @@
|
|||
#define SEG_POOL_START _framebuffersSegmentNoloadEnd // 0x0165000 in size
|
||||
#define SEG_GODDARD SEG_POOL_START + 0x113000
|
||||
|
||||
#if N64_USE_EXTENDED_RAM
|
||||
#define POOL_SIZE_4MB RAM_END_4MB - SEG_POOL_START
|
||||
#endif
|
||||
|
||||
#define POOL_SIZE RAM_END - SEG_POOL_START
|
||||
|
||||
#endif // SEGMENTS_H
|
||||
|
|
|
@ -33,6 +33,13 @@
|
|||
#define TEXT_PAUSE _("PAUSE") // Pause text, Castle Courses
|
||||
#define TEXT_HUD_CONGRATULATIONS _("CONGRATULATIONS") // Course Complete Text, Bowser Courses
|
||||
|
||||
#ifdef TARGET_N64
|
||||
// Memory Expansion Error Screen
|
||||
#define TEXT_CONSOLE_8MB _("If you're using an N64 console, then you will need to buy an\nExpansion Pak to play this ROM hack.")
|
||||
#define TEXT_PJ64 _("If you are using PJ64 1.6, go to:\nOptions > Settings > Rom Settings Tab > Memory Size\nthen select 8 MB from the drop-down box.")
|
||||
#define TEXT_PJ64_2 _("If you are using PJ64 2.X, go to:\nOptions > Settings > Config: > Memory Size, select 8 MB")
|
||||
#endif
|
||||
|
||||
#if defined(VERSION_JP) || defined(VERSION_SH)
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,3 +15,16 @@ const LevelScript level_script_entry[] = {
|
|||
EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, /*entry*/ level_intro_splash_screen),
|
||||
JUMP(/*target*/ level_script_entry),
|
||||
};
|
||||
|
||||
#ifdef TARGET_N64
|
||||
#if N64_USE_EXTENDED_RAM
|
||||
const LevelScript level_script_entry_error_screen[] = {
|
||||
INIT_LEVEL(),
|
||||
SLEEP(/*frames*/ 2),
|
||||
BLACKOUT(/*active*/ FALSE),
|
||||
SET_REG(/*value*/ 0),
|
||||
EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, /*entry*/ level_intro_entry_error_screen),
|
||||
JUMP(/*target*/ level_script_entry_error_screen),
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,28 @@
|
|||
|
||||
#include "levels/intro/header.h"
|
||||
|
||||
#ifdef TARGET_N64
|
||||
#if N64_USE_EXTENDED_RAM
|
||||
const GeoLayout intro_geo_error_screen[] = {
|
||||
GEO_NODE_SCREEN_AREA(0, SCREEN_WIDTH/2, SCREEN_HEIGHT/2, SCREEN_WIDTH/2, SCREEN_HEIGHT/2),
|
||||
GEO_OPEN_NODE(),
|
||||
GEO_ZBUFFER(0),
|
||||
GEO_OPEN_NODE(),
|
||||
GEO_NODE_ORTHO(100),
|
||||
GEO_OPEN_NODE(),
|
||||
GEO_BACKGROUND_COLOR(0x0001),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_ZBUFFER(0),
|
||||
GEO_OPEN_NODE(),
|
||||
GEO_ASM(0, geo_display_error_message),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_END(),
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// 0x0E0002D0
|
||||
const GeoLayout intro_geo_0002D0[] = {
|
||||
GEO_NODE_SCREEN_AREA(0, SCREEN_WIDTH/2, SCREEN_HEIGHT/2, SCREEN_WIDTH/2, SCREEN_HEIGHT/2),
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef TARGET_N64
|
||||
#include "extras/n64_mem_error_screen.h"
|
||||
#endif
|
||||
|
||||
// geo
|
||||
extern const GeoLayout intro_geo_0002D0[];
|
||||
extern const GeoLayout intro_geo_mario_head_regular[];
|
||||
|
@ -26,4 +30,9 @@ extern const LevelScript script_intro_L3[];
|
|||
extern const LevelScript script_intro_L4[];
|
||||
extern const LevelScript script_intro_L5[];
|
||||
|
||||
#ifdef TARGET_N64
|
||||
extern const GeoLayout intro_geo_error_screen[];
|
||||
extern const LevelScript level_intro_entry_error_screen[];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,25 @@
|
|||
#include "make_const_nonconst.h"
|
||||
#include "levels/intro/header.h"
|
||||
|
||||
#ifdef TARGET_N64
|
||||
#if N64_USE_EXTENDED_RAM
|
||||
const LevelScript level_intro_entry_error_screen[] = {
|
||||
INIT_LEVEL(),
|
||||
FIXED_LOAD(/*loadAddr*/ _goddardSegmentStart, /*romStart*/ _goddardSegmentRomStart, /*romEnd*/ _goddardSegmentRomEnd),
|
||||
LOAD_MIO0(/*seg*/ 0x07, _intro_segment_7SegmentRomStart, _intro_segment_7SegmentRomEnd),
|
||||
ALLOC_LEVEL_POOL(),
|
||||
|
||||
AREA(/*index*/ 1, intro_geo_error_screen),
|
||||
END_AREA(),
|
||||
|
||||
FREE_LEVEL_POOL(),
|
||||
LOAD_AREA(/*area*/ 1),
|
||||
SLEEP(/*frames*/ 32767),
|
||||
EXIT_AND_EXECUTE(/*seg*/ 0x14, _introSegmentRomStart, _introSegmentRomEnd, level_intro_entry_error_screen),
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const LevelScript level_intro_splash_screen[] = {
|
||||
INIT_LEVEL(),
|
||||
FIXED_LOAD(/*loadAddr*/ _goddardSegmentStart, /*romStart*/ _goddardSegmentRomStart, /*romEnd*/ _goddardSegmentRomEnd),
|
||||
|
|
1
sm64.ld
1
sm64.ld
|
@ -360,6 +360,7 @@ SECTIONS
|
|||
BUILD_DIR/libultra.a:osSetThreadPri.o(.text);
|
||||
BUILD_DIR/libultra.a:osInitialize.o(.text);
|
||||
BUILD_DIR/libultra.a:osViSwapBuffer.o(.text);
|
||||
BUILD_DIR/libultra.a:__osGetCurrFaultedThread.o(.text); // for crash screen
|
||||
BUILD_DIR/libultra.a:sqrtf.o(.text);
|
||||
BUILD_DIR/libultra.a:osContStartReadData.o(.text);
|
||||
BUILD_DIR/libultra.a:osContInit.o(.text);
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
struct LevelCommand;
|
||||
|
||||
extern u8 level_script_entry[];
|
||||
#ifdef TARGET_N64
|
||||
extern u8 level_script_entry_error_screen[];
|
||||
#endif
|
||||
|
||||
struct LevelCommand *level_script_execute(struct LevelCommand *cmd);
|
||||
|
||||
|
|
|
@ -57,10 +57,6 @@
|
|||
#include "pc/cliopts.h"
|
||||
#endif
|
||||
|
||||
// Define Settings
|
||||
// Ignores checks and fully defines if intro should be skipped
|
||||
#define SKIP_PEACH_CUTSCENE FALSE
|
||||
|
||||
// Ifdef hell but it does the job
|
||||
u8 should_intro_be_skipped(void) {
|
||||
#if SKIP_PEACH_CUTSCENE
|
||||
|
|
103
src/extras/n64_mem_error_screen.c
Normal file
103
src/extras/n64_mem_error_screen.c
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* mem_error_screen.inc.c
|
||||
*
|
||||
* This enhancement should be used for ROM hacks that require the expansion pak.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include "segments.h"
|
||||
#include "text_strings.h"
|
||||
#include "game/game_init.h"
|
||||
#include "game/main.h"
|
||||
#include "game/print.h"
|
||||
#include "game/ingame_menu.h"
|
||||
#include "game/segment2.h"
|
||||
#include "engine/level_script.h"
|
||||
|
||||
#ifdef TARGET_N64
|
||||
#if N64_USE_EXTENDED_RAM
|
||||
// Require 8 MB of RAM, even if the pool doesn't go into extended memory.
|
||||
// Change the '8' to whatever MB limit you want.
|
||||
// Note: only special emulators allow for RAM sizes above 8 MB.
|
||||
#define REQUIRED_MIN_MEM_SIZE 1048576 * 8
|
||||
|
||||
u8 gNotEnoughMemory = FALSE;
|
||||
u8 gDelayForErrorMessage = 0;
|
||||
|
||||
u8 does_pool_end_lie_out_of_bounds(void *end) {
|
||||
u32 endPhy = ((u32) end) & 0x1FFFFFFF;
|
||||
u32 memSize = *((u32 *) 0x80000318); // osMemSize
|
||||
|
||||
if (endPhy > memSize) {
|
||||
gNotEnoughMemory = TRUE;
|
||||
return TRUE;
|
||||
} else {
|
||||
if (memSize < REQUIRED_MIN_MEM_SIZE) {
|
||||
gNotEnoughMemory = TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// If you're using an N64 console, then you will need to buy an\nexpansion pak to play this ROM hack.
|
||||
u8 text_console_8mb[] = { TEXT_CONSOLE_8MB };
|
||||
|
||||
// If you are using PJ64 1.6, go to: Options ► Settings ► Rom Settings Tab ► Memory Size then select 8
|
||||
// MB from the drop-down box.
|
||||
u8 text_pj64[] = { TEXT_PJ64 };
|
||||
|
||||
// If you are using PJ64 2.X, go to: Options ► Settings ► Config: ► Memory Size, select 8 MB
|
||||
u8 text_pj64_2[] = { TEXT_PJ64_2 };
|
||||
|
||||
Gfx *geo_display_error_message(u32 callContext, UNUSED struct GraphNode *node, UNUSED u32 unused) {
|
||||
if (callContext) {
|
||||
if (gDelayForErrorMessage > 0) {
|
||||
// Draw color text title.
|
||||
print_text(10, 210, "ERROR Need more memory");
|
||||
|
||||
// Init generic text rendering
|
||||
create_dl_ortho_matrix();
|
||||
gSPDisplayList(gDisplayListHead++,
|
||||
dl_ia_text_begin); // Init rendering stuff for generic text
|
||||
|
||||
// Set text color to white
|
||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
||||
|
||||
print_generic_string(8, 170, text_console_8mb);
|
||||
print_generic_string(8, 120, text_pj64);
|
||||
print_generic_string(8, 54, text_pj64_2);
|
||||
|
||||
// Cleanup
|
||||
gSPDisplayList(gDisplayListHead++,
|
||||
dl_ia_text_end); // Reset back to default render settings.
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
} else {
|
||||
gDelayForErrorMessage += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Basic main loop for the error screen. Note that controllers are not enabled here.
|
||||
void thread5_mem_error_message_loop(UNUSED void *arg) {
|
||||
struct LevelCommand *addr;
|
||||
|
||||
setup_game_memory();
|
||||
set_vblank_handler(2, &gGameVblankHandler, &gGameVblankQueue, (OSMesg) 1);
|
||||
|
||||
addr = segmented_to_virtual(level_script_entry_error_screen);
|
||||
|
||||
rendering_init();
|
||||
|
||||
while (1) {
|
||||
config_gfx_pool();
|
||||
addr = level_script_execute(addr);
|
||||
display_and_vsync();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
9
src/extras/n64_mem_error_screen.h
Normal file
9
src/extras/n64_mem_error_screen.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef N64_MEM_ERROR_SCREEN_H
|
||||
#define N64_MEM_ERROR_SCREEN_H
|
||||
|
||||
extern u8 gNotEnoughMemory;
|
||||
void thread5_mem_error_message_loop(UNUSED void *arg);
|
||||
Gfx *geo_display_error_message(u32 callContext, UNUSED struct GraphNode *node, UNUSED u32 unused);
|
||||
u8 does_pool_end_lie_out_of_bounds(void *end);
|
||||
|
||||
#endif
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
#include "sm64.h"
|
||||
|
||||
#if defined(TARGET_N64) && (defined(VERSION_EU) || defined(VERSION_SH))
|
||||
#ifdef TARGET_N64
|
||||
#if N64_CRASH_SCREEN
|
||||
|
||||
#include "lib/src/printf.h"
|
||||
|
||||
|
@ -117,7 +118,7 @@ void crash_screen_print(s32 x, s32 y, const char *fmt, ...) {
|
|||
if (size > 0) {
|
||||
ptr = buf;
|
||||
|
||||
#ifdef VERSION_SH
|
||||
#if 1
|
||||
while (size > 0) {
|
||||
#else
|
||||
while (*ptr) {
|
||||
|
@ -129,7 +130,7 @@ void crash_screen_print(s32 x, s32 y, const char *fmt, ...) {
|
|||
crash_screen_draw_glyph(x, y, glyph);
|
||||
}
|
||||
|
||||
#ifdef VERSION_SH
|
||||
#if 1
|
||||
size--;
|
||||
#endif
|
||||
|
||||
|
@ -190,14 +191,14 @@ void draw_crash_screen(OSThread *thread) {
|
|||
cause = 17;
|
||||
}
|
||||
|
||||
#ifdef VERSION_SH
|
||||
#if 1
|
||||
osWritebackDCacheAll();
|
||||
#endif
|
||||
|
||||
crash_screen_draw_rect(25, 20, 270, 25);
|
||||
crash_screen_print(30, 25, "THREAD:%d (%s)", thread->id, gCauseDesc[cause]);
|
||||
crash_screen_print(30, 35, "PC:%08XH SR:%08XH VA:%08XH", tc->pc, tc->sr, tc->badvaddr);
|
||||
#ifdef VERSION_EU
|
||||
#if 0
|
||||
osWritebackDCacheAll();
|
||||
#endif
|
||||
crash_screen_sleep(2000);
|
||||
|
@ -222,7 +223,7 @@ void draw_crash_screen(OSThread *thread) {
|
|||
(u32) tc->sp);
|
||||
crash_screen_print(30, 140, "S8:%08XH RA:%08XH", (u32) tc->s8, (u32) tc->ra);
|
||||
crash_screen_print_fpcsr(tc->fpcsr);
|
||||
#ifdef VERSION_EU
|
||||
#if 0
|
||||
osWritebackDCacheAll();
|
||||
#endif
|
||||
crash_screen_print_float_reg(30, 170, 0, &tc->fp0.f.f_even);
|
||||
|
@ -241,7 +242,7 @@ void draw_crash_screen(OSThread *thread) {
|
|||
crash_screen_print_float_reg(120, 210, 26, &tc->fp26.f.f_even);
|
||||
crash_screen_print_float_reg(210, 210, 28, &tc->fp28.f.f_even);
|
||||
crash_screen_print_float_reg(30, 220, 30, &tc->fp30.f.f_even);
|
||||
#ifdef VERSION_EU
|
||||
#if 0
|
||||
osWritebackDCacheAll();
|
||||
#endif
|
||||
osViBlack(FALSE);
|
||||
|
@ -278,7 +279,7 @@ void thread2_crash_screen(UNUSED void *arg) {
|
|||
}
|
||||
|
||||
void crash_screen_set_framebuffer(u16 *framebuffer, u16 width, u16 height) {
|
||||
#ifdef VERSION_EU
|
||||
#if 0
|
||||
gCrashScreen.framebuffer = framebuffer;
|
||||
#else
|
||||
gCrashScreen.framebuffer = (u16 *)((uintptr_t)framebuffer | 0xa0000000);
|
||||
|
@ -288,13 +289,13 @@ void crash_screen_set_framebuffer(u16 *framebuffer, u16 width, u16 height) {
|
|||
}
|
||||
|
||||
void crash_screen_init(void) {
|
||||
#ifdef VERSION_EU
|
||||
#if 0
|
||||
gCrashScreen.framebuffer = (u16 *) (osMemSize | 0x80000000) - SCREEN_WIDTH * SCREEN_HEIGHT;
|
||||
#else
|
||||
gCrashScreen.framebuffer = (u16 *) (osMemSize | 0xA0000000) - SCREEN_WIDTH * SCREEN_HEIGHT;
|
||||
#endif
|
||||
gCrashScreen.width = SCREEN_WIDTH;
|
||||
#ifdef VERSION_EU
|
||||
#if 0
|
||||
gCrashScreen.height = SCREEN_HEIGHT;
|
||||
#else
|
||||
gCrashScreen.height = 0x10;
|
||||
|
@ -302,7 +303,7 @@ void crash_screen_init(void) {
|
|||
osCreateMesgQueue(&gCrashScreen.mesgQueue, &gCrashScreen.mesg, 1);
|
||||
osCreateThread(&gCrashScreen.thread, 2, thread2_crash_screen, NULL,
|
||||
(u8 *) gCrashScreen.stack + sizeof(gCrashScreen.stack),
|
||||
#ifdef VERSION_EU
|
||||
#if 0
|
||||
OS_PRIORITY_APPMAX
|
||||
#else
|
||||
OS_PRIORITY_RMON
|
||||
|
@ -312,3 +313,5 @@ void crash_screen_init(void) {
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
#include "segments.h"
|
||||
#include "main.h"
|
||||
#include "rumble_init.h"
|
||||
#if N64_USE_EXTENDED_RAM
|
||||
#include "extras/n64_mem_error_screen.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This entry point is only used in TARGET_N64.
|
||||
|
@ -130,6 +133,12 @@ void alloc_pool(void) {
|
|||
void *start = (void *) SEG_POOL_START;
|
||||
void *end = (void *) (SEG_POOL_START + POOL_SIZE);
|
||||
|
||||
#if N64_USE_EXTENDED_RAM
|
||||
// Detect memory size
|
||||
if (does_pool_end_lie_out_of_bounds(end))
|
||||
end = (void *) (SEG_POOL_START + POOL_SIZE_4MB);
|
||||
#endif
|
||||
|
||||
main_pool_init(start, end);
|
||||
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);
|
||||
}
|
||||
|
@ -334,7 +343,15 @@ void thread3_main(UNUSED void *arg) {
|
|||
create_thread(&gSoundThread, 4, thread4_sound, NULL, gThread4Stack + 0x2000, 20);
|
||||
osStartThread(&gSoundThread);
|
||||
|
||||
#if N64_USE_EXTENDED_RAM
|
||||
if (!gNotEnoughMemory)
|
||||
create_thread(&gGameLoopThread, 5, thread5_game_loop, NULL, gThread5Stack + 0x2000, 10);
|
||||
else
|
||||
create_thread(&gGameLoopThread, 5, thread5_mem_error_message_loop, NULL, gThread5Stack + 0x2000, 10);
|
||||
#else
|
||||
create_thread(&gGameLoopThread, 5, thread5_game_loop, NULL, gThread5Stack + 0x2000, 10);
|
||||
#endif
|
||||
|
||||
osStartThread(&gGameLoopThread);
|
||||
|
||||
while (TRUE) {
|
||||
|
@ -437,6 +454,10 @@ void thread1_idle(UNUSED void *arg) {
|
|||
osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON);
|
||||
osViSetSpecialFeatures(OS_VI_GAMMA_OFF);
|
||||
osCreatePiManager(OS_PRIORITY_PIMGR, &gPIMesgQueue, gPIMesgBuf, ARRAY_COUNT(gPIMesgBuf));
|
||||
#if N64_CRASH_SCREEN
|
||||
extern void crash_screen_init(void);
|
||||
crash_screen_init();
|
||||
#endif
|
||||
create_thread(&gMainThread, 3, thread3_main, NULL, gThread3Stack + 0x2000, 100);
|
||||
if (D_8032C650 == 0) {
|
||||
osStartThread(&gMainThread);
|
||||
|
|
Loading…
Add table
Reference in a new issue