add n64 configs, ext ram and crash screen

This commit is contained in:
AloXado320 2021-05-10 21:20:38 -05:00
parent 0f694a8ba8
commit f51e14249f
16 changed files with 241 additions and 321 deletions

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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)
/**

View file

@ -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

View file

@ -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),

View file

@ -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

View file

@ -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),

View file

@ -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);

View file

@ -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);

View file

@ -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

View 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

View 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

View file

@ -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

View file

@ -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);