EU now successfully builds + misc

And has the language related stuff without the need of ifdef hell
ROM now pads only to 1.1MB
And collision has some unnecessary typecasting removed for performance
This commit is contained in:
Fazana
2021-08-16 17:41:27 +01:00
parent c294980de2
commit 0395d1a40d
20 changed files with 406 additions and 268 deletions

View File

@@ -801,7 +801,7 @@ $(ELF): $(BUILD_DIR)/sm64_prelim.elf $(O_FILES) $(YAY0_OBJ_FILES) $(SEG_FILES) $
$(ROM): $(ELF)
$(call print,Building ROM:,$<,$@)
ifeq ($(CONSOLE),n64)
$(V)$(OBJCOPY) --pad-to=0x800000 --gap-fill=0xFF $< $@ -O binary
$(V)$(OBJCOPY) --pad-to=0x101000 --gap-fill=0xFF $< $@ -O binary
else ifeq ($(CONSOLE),bb)
$(V)$(OBJCOPY) --gap-fill=0x00 $< $@ -O binary
$(V)dd if=$@ of=tmp bs=16K conv=sync

View File

@@ -14,23 +14,15 @@
.word 0x00000000 /* Checksum 2 */
.word 0x00000000 /* Unknown */
.word 0x00000000 /* Unknown */
.if VERSION_SH == 1
.ascii INTERNAL_ROM_NAME /* Internal ROM name */
.else
.ascii INTERNAL_ROM_NAME /* Internal ROM name */
.endif
.word 0x00000000 /* Unknown */
.word 0x0000004E /* Cartridge */
.ascii "SM" /* Cartridge ID */
.ascii "ED" /* Cartridge ID */
/* Region */
#ifdef VERSION_EU
.ascii "P" /* PAL (Europe) */
#elif defined(VERSION_US)
.ascii "E" /* NTSC-U (North America) */
#else
#ifdef defined(VERSION_JP) || defined(VERSION_SH)
.ascii "J" /* NTSC-J (Japan) */
#else
.ascii "E" /* NTSC-U (North America) */
#endif
.byte 0x00 /* Version */

View File

@@ -2166,7 +2166,6 @@ const Gfx dl_draw_text_bg_box[] = {
gsSPEndDisplayList(),
};
#ifndef VERSION_EU
// 0x0200EE28 - 0x0200EE68
static const Vtx vertex_ia8_char[] = {
#if defined(VERSION_JP) || defined(VERSION_SH)
@@ -2181,21 +2180,8 @@ static const Vtx vertex_ia8_char[] = {
{{{ 0, 16, 0}, 0, { 480, 256}, {0xff, 0xff, 0xff, 0xff}}},
#endif
};
// !EU
#endif
#ifdef VERSION_EU
// 0x020073B0
const Gfx dl_ia_text_begin[] = {
gsDPPipeSync(),
gsDPSetTexturePersp(G_TP_NONE),
gsDPSetCombineMode(G_CC_FADEA, G_CC_FADEA),
gsDPSetEnvColor(255, 255, 255, 255),
gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2),
gsDPSetTextureFilter(G_TF_POINT),
gsSPEndDisplayList(),
};
// 0x020073E8 - 0x02007418
const Gfx dl_ia_text_tex_settings[] = {
gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_MIRROR, 3, G_TX_NOLOD, G_TX_WRAP | G_TX_MIRROR, 4, G_TX_NOLOD),
@@ -2203,21 +2189,14 @@ const Gfx dl_ia_text_tex_settings[] = {
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, ((16 * 8 + G_IM_SIZ_4b_INCR) >> G_IM_SIZ_4b_SHIFT) - 1, CALC_DXT(16, G_IM_SIZ_4b_BYTES)),
gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_4b, 1, 0, G_TX_RENDERTILE, 0, G_TX_WRAP | G_TX_MIRROR, 3, G_TX_NOLOD, G_TX_WRAP | G_TX_MIRROR, 4, G_TX_NOLOD),
gsDPSetTileSize(0, 0, 0, (16 - 1) << G_TEXTURE_IMAGE_FRAC, (8 - 1) << G_TEXTURE_IMAGE_FRAC),
gsSPVertex(vertex_ia8_char, 4, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0),
gsSPEndDisplayList(),
gsSPEndDisplayList(),
};
#endif
// 0x02007418 - 0x02007450
const Gfx dl_ia_text_end[] = {
gsDPPipeSync(),
gsDPSetTexturePersp(G_TP_PERSP),
gsDPSetRenderMode(G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2),
gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),
gsDPSetEnvColor(255, 255, 255, 255),
gsDPSetTextureFilter(G_TF_BILERP),
gsSPEndDisplayList(),
};
#elif defined(VERSION_US)
#if defined(VERSION_US) || defined(VERSION_EU)
const Gfx dl_ia_text_begin[] = {
gsDPPipeSync(),
gsSPClearGeometryMode(G_LIGHTING),
@@ -2228,7 +2207,9 @@ const Gfx dl_ia_text_begin[] = {
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
gsSPEndDisplayList(),
};
#endif
#ifdef VERSION_US
const Gfx dl_ia_text_tex_settings[] = {
gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, 3, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD),
gsDPLoadSync(),
@@ -2239,8 +2220,9 @@ const Gfx dl_ia_text_tex_settings[] = {
gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0),
gsSPEndDisplayList(),
};
#endif
#else
#if defined(VERSION_JP) || defined(VERSION_SH)
// 0x0200EE68 - 0x0200EEA8
const Gfx dl_ia_text_begin[] = {
gsDPPipeSync(),
@@ -2266,7 +2248,6 @@ const Gfx dl_ia_text_tex_settings[] = {
};
#endif
#ifndef VERSION_EU
// 0x0200EEF0 - 0x0200EF30
const Gfx dl_ia_text_end[] = {
gsDPPipeSync(),
@@ -2278,7 +2259,6 @@ const Gfx dl_ia_text_end[] = {
gsDPSetTextureFilter(G_TF_BILERP),
gsSPEndDisplayList(),
};
#endif
// 0x0200EF30 - 0x0200EF60
static const Vtx vertex_triangle[] = {

View File

@@ -98,6 +98,8 @@
#define PARALLEL_LAKITU_CAM
// Allows Mario to ledgegrab sloped floors
#define NO_FALSE_LEDGEGRABS
//Adds multiple languages to the game. Just a placeholder for the most part, because it only works with EU, and must be enabled with EU.
#define MULTILANG (0 || VERSION_EU)
//Enables Puppy Camera 2, a rewritten camera that can be freely configured and modified.
//#define PUPPYCAM

View File

@@ -4,7 +4,8 @@
// EU changes most text to arrays for each language. This define allows these
// differences to be combined.
#ifdef VERSION_EU
#define LANGUAGE_ARRAY(cmd) cmd[LANGUAGE_FUNCTION]
//#define LANGUAGE_ARRAY(cmd) cmd[LANGUAGE_FUNCTION]
#define LANGUAGE_ARRAY(cmd) cmd
#else
#define LANGUAGE_ARRAY(cmd) cmd
#endif

View File

@@ -3,12 +3,10 @@
#include "text_menu_strings.h"
#ifdef PUPPYCAM
#if defined(PUPPYCAM)
#define NC_CAMX_EN _("Camera X Sensitivity")
#define NC_CAMY_EN _("Camera Y Sensitivity")
#define NC_INVERTX_EN _("Invert X Axis")
#define NC_INVERTX_FR _("Invertir Axe X")
#define NC_INVERTX_DE _("Invert X Axis")
#define NC_INVERTY_EN _("Invert Y Axis")
#define NC_CAMC_EN _("Camera Centre Speed")
#define NC_ANALOGUE_EN _("Analogue Camera")
@@ -18,59 +16,50 @@
#define OPTION_SCHEME1_EN _("Double Tap")
#define OPTION_SCHEME2_EN _("Single Press")
#define OPTION_SCHEME3_EN _("Classic")
#define OPTION_LANGUAGE_EN _("Language")
#define NC_WIDE_EN _("Widescreen")
#define NC_HIGHLIGHT_L _(">")
#define NC_HIGHLIGHT_R _("<")
#define NC_BUTTON_EN _("[R]: Options")
#define NC_BUTTON2_EN _("[R]: Return")
#define NC_OPTION_EN _("PUPPYCAM OPTIONS")
#define NC_OPTION_EN _("OPTIONS")
#if defined(VERSION_EU)
#if MULTILANG
#define NC_CAMX_FR _("Sensibilite sur l'axe X")
#define NC_CAMX_DE _("Camera X Sensitivity")
#define NC_CAMY_FR _("Sensibilite sur l'axe Y")
#define NC_CAMY_DE _("Camera Y Sensitivity")
#define NC_INVERTX_FR _("Invertir Axe X")
#define NC_INVERTY_FR _("Invertir Axe Y")
#define NC_INVERTY_DE _("Invert Y Axis")
#define NC_CAMC_FR _("Vitesse de Centrage")
#define NC_CAMC_DE _("Camera Centre Speed")
#define NC_ANALOGUE_FR _("Camera Analogue")
#define NC_ANALOGUE_DE _("Analogue Camera")
#define NC_SCHEME_FR _("Control Scheme")
#define NC_SCHEME_DE _("Control Scheme")
#define OPTION_ENABLED_FR _("Active")
#define OPTION_DISABLED_FR _("Desactive")
#define OPTION_SCHEME1_FR _("Double Tap")
#define OPTION_SCHEME2_FR _("Single Press")
#define OPTION_SCHEME3_FR _("Classic")
#define OPTION_LANGUAGE_FR _("Language")
#define NC_WIDE_FR _("Widescreen")
#define NC_BUTTON_FR _("[R]: Options")
#define NC_BUTTON2_FR _("[R]: Retournez")
#define NC_OPTION_FR _("OPTIONS")
#define NC_CAMX_DE _("Camera X Sensitivity")
#define NC_CAMY_DE _("Camera Y Sensitivity")
#define NC_INVERTY_DE _("Invert Y Axis")
#define NC_INVERTX_DE _("Invert X Axis")
#define NC_CAMC_DE _("Camera Centre Speed")
#define NC_ANALOGUE_DE _("Analogue Camera")
#define NC_SCHEME_DE _("Control Scheme")
#define OPTION_ENABLED_DE _("Enabled")
#define OPTION_DISABLED_DE _("Disabled")
#define OPTION_SCHEME1_DE _("Double Tap")
#define OPTION_SCHEME2_DE _("Single Press")
#define OPTION_SCHEME3_DE _("Classic")
#define OPTION_LANGUAGE_DE _("Language")
#define NC_WIDE_DE _("Widescreen")
#define OPTION_ENABLED_FR _("Active")
#define OPTION_ENABLED_DE _("Enabled")
#define OPTION_DISABLED_FR _("Desactive")
#define OPTION_DISABLED_DE _("Disabled")
#define OPTION_SCHEME1_FR _("Double Tap")
#define OPTION_SCHEME1_DE _("Double Tap")
#define OPTION_SCHEME2_FR _("Single Press")
#define OPTION_SCHEME2_DE _("Single Press")
#define OPTION_SCHEME3_FR _("Classic")
#define OPTION_SCHEME3_DE _("Classic")
#define NC_BUTTON_FR _("[R]: Options")
#define NC_BUTTON_DE _("[R]: Options")
#define NC_BUTTON2_FR _("[R]: Retournez")
#define NC_BUTTON2_DE _("[R]: Return")
#define NC_OPTION_FR _("OPTIONS PUPPYCAM")
#define NC_OPTION_DE _("PUPPYCAM OPTIONS")
#define NC_BUTTON_DE _("[R]: Options")
#define NC_BUTTON2_DE _("[R]: Return")
#define NC_OPTION_DE _("OPTIONS")
#endif
#endif
@@ -97,7 +86,7 @@
#define TEXT_HUD_CONGRATULATIONS _("CONGRATULATIONS") // Course Complete Text, Bowser Courses
//Widescreen stuff
#ifdef WIDE
#if defined(WIDE) && !defined(PUPPYCAM)
#define TEXT_HUD_CURRENT_RATIO_43 _("ASPECT RATIO: 4:3")
#define TEXT_HUD_CURRENT_RATIO_169 _("ASPECT RATIO: 16:9")
#define TEXT_HUD_PRESS_L _("PRESS L TO SWITCH")
@@ -303,7 +292,12 @@
#endif
#ifdef VERSION_EU
#define TEXT_ENGLISH _("ENGLISH")
#define TEXT_FRENCH _("FRANÇAIS")
#define TEXT_GERMAN _("DEUTSCH")
#if MULTILANG
/**
* File Select Text
@@ -387,10 +381,6 @@
#define TEXT_MONO_DE _("MONO")
#define TEXT_HEADSET_DE _("PHONES")
#define TEXT_ENGLISH _("ENGLISH")
#define TEXT_FRENCH _("FRANÇAIS")
#define TEXT_GERMAN _("DEUTSCH")
#define TEXT_HI_SCORE_FR _("MEILLEUR SCORE")
#define TEXT_HI_SCORE_DE _("BESTLEISTUNG")

View File

@@ -116,8 +116,8 @@ extern u32 gAudioRandom;
#define EXT_AUDIO_INIT_POOL_SIZE 0x8000
#else
// EU and SH versions not yet supported for extended audio heap
#define EXT_AUDIO_HEAP_SIZE 0x0
#define EXT_AUDIO_INIT_POOL_SIZE 0x0
#define EXT_AUDIO_HEAP_SIZE 0x24400
#define EXT_AUDIO_INIT_POOL_SIZE 0x8000
#endif
#else
#define EXT_AUDIO_HEAP_SIZE 0x0

View File

@@ -1000,8 +1000,9 @@ void audio_init() {
}
#endif
D_EU_802298D0 = 20.03042f;
gRefreshRate = 50;
//D_EU_802298D0 = 20.03042f;
D_EU_802298D0 = 16.713f;
gRefreshRate = 60;
port_eu_init();
if (k) {
}

View File

@@ -10,13 +10,7 @@
#include "audio/synthesis.h"
ALIGNED8 u8 gDecompressionHeap[0xD000];
#if defined(VERSION_EU)
ALIGNED16 u8 gAudioHeap[DOUBLE_SIZE_ON_64_BIT(0x31200 + EXT_AUDIO_HEAP_SIZE + EXT_AUDIO_INIT_POOL_SIZE) - 0x3800];
#elif defined(VERSION_SH)
ALIGNED16 u8 gAudioHeap[DOUBLE_SIZE_ON_64_BIT(0x31200 + EXT_AUDIO_HEAP_SIZE + EXT_AUDIO_INIT_POOL_SIZE) - 0x4800];
#else
ALIGNED16 u8 gAudioHeap[DOUBLE_SIZE_ON_64_BIT(0x31200 + EXT_AUDIO_HEAP_SIZE + EXT_AUDIO_INIT_POOL_SIZE + BETTER_REVERB_SIZE)];
#endif
ALIGNED8 u8 gIdleThreadStack[0x800];
ALIGNED8 u8 gThread3Stack[0x2000];
@@ -26,9 +20,14 @@ ALIGNED8 u8 gThread5Stack[0x2000];
ALIGNED8 u8 gThread6Stack[0x2000];
#endif
// 0x400 bytes
ALIGNED8 u8 gGfxSPTaskStack[SP_DRAM_STACK_SIZE8];
#if UNF
ALIGNED16 u8 gGfxSPTaskStack[SP_DRAM_STACK_SIZE8];
ALIGNED16 u8 gGfxSPTaskYieldBuffer[OS_YIELD_DATA_SIZE];
#else
// 0xc00 bytes for f3dex, 0x900 otherwise
ALIGNED8 u8 gGfxSPTaskStack[SP_DRAM_STACK_SIZE8];
ALIGNED8 u8 gGfxSPTaskYieldBuffer[OS_YIELD_DATA_SIZE];
#endif // UNF
// 0x200 bytes
struct SaveBuffer __attribute__ ((aligned (8))) gSaveBuffer;
// 0x190a0 bytes

View File

@@ -184,10 +184,10 @@ s32 f32_find_wall_collision(f32 *xPtr, f32 *yPtr, f32 *zPtr, f32 offsetY, f32 ra
*/
s32 find_wall_collisions(struct WallCollisionData *colData) {
struct SurfaceNode *node;
s16 cellX, cellZ;
s32 cellX, cellZ;
s32 numCollisions = 0;
s16 x = colData->x;
s16 z = colData->z;
s32 x = colData->x;
s32 z = colData->z;
#ifdef PUPPYPRINT
OSTime first = osGetTime();
#endif
@@ -271,7 +271,7 @@ static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32
nx = surf->normal.x;
ny = surf->normal.y;
nz = surf->normal.z;
oo = surf->originOffset;
oo = surf->originOffset;
// If a wall, ignore it. Likely a remnant, should never occur.
if (ny == 0.0f) {
continue;
@@ -301,22 +301,19 @@ static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32
* Find the lowest ceiling above a given position and return the height.
*/
f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
s16 cellZ, cellX;
s32 cellZ, cellX;
struct Surface *ceil, *dynamicCeil;
struct SurfaceNode *surfaceList;
f32 height = CELL_HEIGHT_LIMIT;
f32 dynamicHeight = CELL_HEIGHT_LIMIT;
s16 x, y, z;
s32 x, y, z;
#ifdef PUPPYPRINT
OSTime first = osGetTime();
#endif
//! (Parallel Universes) Because position is casted to an s16, reaching higher
// float locations can return ceilings despite them not existing there.
//(Dynamic ceilings will unload due to the range.)
x = (s16) posX;
y = (s16) posY;
z = (s16) posZ;
x = posX;
y = posY;
z = posZ;
*pceil = NULL;
if (x <= -LEVEL_BOUNDARY_MAX || x >= LEVEL_BOUNDARY_MAX) {
@@ -491,17 +488,17 @@ static f32 get_floor_height_at_location(s32 x, s32 z, struct Surface *surf) {
* Iterate through the list of water floors and find the first water floor under a given point.
*/
struct Surface *find_water_floor_from_list(struct SurfaceNode *surfaceNode, s32 x, s32 y, s32 z,
f32 *pheight) {
s32 *pheight) {
register struct Surface *surf;
struct Surface *floor = NULL;
struct SurfaceNode *topSurfaceNode = surfaceNode;
struct SurfaceNode *bottomSurfaceNode = surfaceNode;
f32 height = FLOOR_LOWER_LIMIT;
f32 bottomHeight = FLOOR_LOWER_LIMIT;
s32 height = FLOOR_LOWER_LIMIT;
s32 bottomHeight = FLOOR_LOWER_LIMIT;
// Iterate through the list of water floors until there are no more water floors.
while (bottomSurfaceNode != NULL) {
f32 curBottomHeight = FLOOR_LOWER_LIMIT;
s32 curBottomHeight = FLOOR_LOWER_LIMIT;
surf = bottomSurfaceNode->surface;
bottomSurfaceNode = bottomSurfaceNode->next;
@@ -515,7 +512,7 @@ struct Surface *find_water_floor_from_list(struct SurfaceNode *surfaceNode, s32
// Iterate through the list of water tops until there are no more water tops.
while (topSurfaceNode != NULL) {
f32 curHeight = FLOOR_LOWER_LIMIT;
s32 curHeight = FLOOR_LOWER_LIMIT;
surf = topSurfaceNode->surface;
topSurfaceNode = topSurfaceNode->next;
@@ -556,13 +553,13 @@ f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfl
f32 floorHeight = FLOOR_LOWER_LIMIT;
// Would normally cause PUs, but dynamic floors unload at that range.
s16 x = (s16) xPos;
s16 y = (s16) yPos;
s16 z = (s16) zPos;
s32 x = xPos;
s32 y = yPos;
s32 z = zPos;
// Each level is split into cells to limit load, find the appropriate cell.
s16 cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
s16 cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
s32 cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
s32 cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
floor = find_floor_from_list(surfaceList, x, y, z, &floorHeight);
@@ -576,7 +573,7 @@ f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfl
* Find the highest floor under a given position and return the height.
*/
f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
s16 cellZ, cellX;
s32 cellZ, cellX;
#ifdef PUPPYPRINT
OSTime first = osGetTime();
#endif
@@ -590,9 +587,9 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
//! (Parallel Universes) Because position is casted to an s16, reaching higher
// float locations can return floors despite them not existing there.
//(Dynamic floors will unload due to the range.)
s16 x = (s16) xPos;
s16 y = (s16) yPos;
s16 z = (s16) zPos;
s32 x = xPos;
s32 y = yPos;
s32 z = zPos;
*pfloor = NULL;
@@ -662,17 +659,17 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
/**
* Find the highest water floor under a given position and return the height.
*/
f32 find_water_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
s16 cellZ, cellX;
s32 find_water_floor(s32 xPos, s32 yPos, s32 zPos, struct Surface **pfloor) {
s32 cellZ, cellX;
struct Surface *floor = NULL;
struct SurfaceNode *surfaceList;
f32 height = FLOOR_LOWER_LIMIT;
s32 height = FLOOR_LOWER_LIMIT;
s16 x = (s16) xPos;
s16 y = (s16) yPos;
s16 z = (s16) zPos;
s32 x = xPos;
s32 y = yPos;
s32 z = zPos;
if (x <= -LEVEL_BOUNDARY_MAX || x >= LEVEL_BOUNDARY_MAX) {
return height;
@@ -705,12 +702,12 @@ f32 find_water_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
/**
* Finds the height of water at a given location.
*/
f32 find_water_level_and_floor(f32 x, f32 z, struct Surface **pfloor) {
s32 find_water_level_and_floor(s32 x, s32 z, struct Surface **pfloor) {
s32 i;
s32 numRegions;
s16 val;
f32 loX, hiX, loZ, hiZ;
f32 waterLevel = FLOOR_LOWER_LIMIT;
s32 val;
s32 loX, hiX, loZ, hiZ;
s32 waterLevel = FLOOR_LOWER_LIMIT;
s16 *p = gEnvironmentRegions;
struct Surface *floor = NULL;
#ifdef PUPPYPRINT
@@ -756,12 +753,12 @@ f32 find_water_level_and_floor(f32 x, f32 z, struct Surface **pfloor) {
/**
* Finds the height of water at a given location.
*/
f32 find_water_level(f32 x, f32 z) {
s32 find_water_level(s32 x, s32 z) {
s32 i;
s32 numRegions;
s16 val;
f32 loX, hiX, loZ, hiZ;
f32 waterLevel = FLOOR_LOWER_LIMIT;
s32 val;
s32 loX, hiX, loZ, hiZ;
s32 waterLevel = FLOOR_LOWER_LIMIT;
s16 *p = gEnvironmentRegions;
struct Surface *floor;
#ifdef PUPPYPRINT
@@ -805,13 +802,13 @@ f32 find_water_level(f32 x, f32 z) {
/**
* Finds the height of the poison gas (used only in HMC) at a given location.
*/
f32 find_poison_gas_level(f32 x, f32 z) {
s32 find_poison_gas_level(s32 x, s32 z) {
s32 i;
s32 numRegions;
UNUSED s32 unused;
s16 val;
f32 loX, hiX, loZ, hiZ;
f32 gasLevel = FLOOR_LOWER_LIMIT;
s32 val;
s32 loX, hiX, loZ, hiZ;
s32 gasLevel = FLOOR_LOWER_LIMIT;
s16 *p = gEnvironmentRegions;
#ifdef PUPPYPRINT
OSTime first = osGetTime();

View File

@@ -11,7 +11,7 @@
#define CELL_HEIGHT_LIMIT 20000
#define FLOOR_LOWER_LIMIT -11000
#define FLOOR_LOWER_LIMIT_MISC (FLOOR_LOWER_LIMIT + 1000)
// same as FLOOR_LOWER_LIMIT_MISC, explicitly for shadow.c
// same as FLOOR_LOWER_LIMIT_MISC, explicitly for shadow.c
// It doesn't match if ".0" is removed or ".f" is added
#define FLOOR_LOWER_LIMIT_SHADOW (FLOOR_LOWER_LIMIT + 1000.0)
@@ -40,9 +40,9 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil);
f32 find_floor_height_and_data(f32 xPos, f32 yPos, f32 zPos, struct FloorGeometry **floorGeo);
f32 find_floor_height(f32 x, f32 y, f32 z);
f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor);
f32 find_water_level_and_floor(f32 x, f32 z, struct Surface **pfloor);
f32 find_water_level(f32 x, f32 z);
f32 find_poison_gas_level(f32 x, f32 z);
s32 find_water_level_and_floor(s32 x, s32 z, struct Surface **pfloor);
s32 find_water_level(s32 x, s32 z);
s32 find_poison_gas_level(s32 x, s32 z);
void debug_surface_list_info(f32 xPos, f32 zPos);
#endif // SURFACE_COLLISION_H

View File

@@ -9,7 +9,7 @@
#include "types.h"
#include "memory.h"
#define GFX_POOL_SIZE 6400 // Size of how large the master display list (gDisplayListHead) can be
#define GFX_POOL_SIZE 10000 // Size of how large the master display list (gDisplayListHead) can be
struct GfxPool {
Gfx buffer[GFX_POOL_SIZE];

View File

@@ -8,6 +8,7 @@
#include "dialog_ids.h"
#include "engine/math_util.h"
#include "eu_translation.h"
#include "segment_symbols.h"
#include "game_init.h"
#include "gfx_dimensions.h"
#include "ingame_menu.h"
@@ -32,13 +33,32 @@ u16 gDialogTextAlpha;
s16 gCutsceneMsgXOffset;
s16 gCutsceneMsgYOffset;
s8 gRedCoinsCollected;
#ifdef WIDE
#if defined(WIDE) && !defined(PUPPYCAM)
u8 textCurrRatio43[] = { TEXT_HUD_CURRENT_RATIO_43 };
u8 textCurrRatio169[] = { TEXT_HUD_CURRENT_RATIO_169 };
u8 textPressL[] = { TEXT_HUD_PRESS_L };
u8 textWideInfo[] = { TEXT_HUD_WIDE_INFO };
#endif
#if MULTILANG
#define seg2_course_name_table course_name_table_eu_en
#define seg2_act_name_table act_name_table_eu_en
#define seg2_dialog_table dialog_table_eu_en
#endif
s16 gInGameLanguage = 0;
s16 gLoadedLanguage = 0;
void *languageTable[][3] =
{
{&seg2_dialog_table, &seg2_course_name_table, &seg2_act_name_table}, //In EU, this is just mirroring English.
#if MULTILANG
{&dialog_table_eu_en, &course_name_table_eu_en, &act_name_table_eu_en},
{&dialog_table_eu_fr, &course_name_table_eu_fr, &act_name_table_eu_fr},
{&dialog_table_eu_de, &course_name_table_eu_de, &act_name_table_eu_de},
#endif
};
extern u8 gLastCompletedCourseNum;
extern u8 gLastCompletedStarNum;
@@ -65,6 +85,7 @@ enum DialogMark { DIALOG_MARK_NONE = 0, DIALOG_MARK_DAKUTEN = 1, DIALOG_MARK_HAN
#define DEFAULT_DIALOG_BOX_ANGLE 90.0f
#define DEFAULT_DIALOG_BOX_SCALE 19.0f
#if defined(VERSION_US) || defined(VERSION_EU)
u8 gDialogCharWidths[256] = { // TODO: Is there a way to auto generate this?
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6,
6, 6, 5, 6, 6, 5, 8, 8, 6, 6, 6, 6, 6, 5, 6, 6,
@@ -72,17 +93,30 @@ u8 gDialogCharWidths[256] = { // TODO: Is there a way to auto generate this?
7, 5, 5, 5, 6, 5, 5, 5, 5, 5, 7, 7, 5, 5, 4, 4,
8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8, 8, 8, 8, 7, 7, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0,
#ifdef VERSION_EU
6, 6, 6, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 4,
5, 5, 5, 5, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0,
5, 5, 5, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 5, 5, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 5, 6,
0, 4, 4, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#else
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#endif
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#ifdef VERSION_EU
7, 5, 10, 5, 9, 8, 4, 0, 0, 0, 0, 5, 5, 6, 5, 0,
#else
7, 5, 10, 5, 9, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#endif
0, 0, 5, 7, 7, 6, 6, 8, 0, 8, 10, 6, 4, 10, 0, 0
};
#endif
s8 gDialogBoxState = DIALOG_STATE_OPENING;
f32 gDialogBoxOpenTimer = DEFAULT_DIALOG_BOX_ANGLE;
@@ -217,15 +251,50 @@ static u8 *alloc_ia8_text_from_i1(u16 *in, s16 width, s16 height) {
return out;
}
u8 *alloc_ia4_tex_from_i1(u8 *in, s16 width, s16 height) {
u32 size = (u32) width * (u32) height;
u8 *out;
s32 inPos;
s16 outPos;
u8 bitMask;
outPos = 0;
out = (u8 *) alloc_display_list(size);
if (out == NULL) {
return NULL;
}
for (inPos = 0; inPos < (width * height) / 4; inPos++) {
bitMask = 0x80;
while (bitMask != 0) {
out[outPos] = (in[inPos] & bitMask) ? 0xF0 : 0x00;
bitMask /= 2;
out[outPos] = (in[inPos] & bitMask) ? out[outPos] + 0x0F : out[outPos];
bitMask /= 2;
outPos++;
}
}
return out;
}
void render_generic_char(u8 c) {
void **fontLUT;
void *packedTexture;
void *unpackedTexture;
fontLUT = segmented_to_virtual(main_font_lut);
packedTexture = segmented_to_virtual(fontLUT[c]);
#ifdef VERSION_EU
unpackedTexture = alloc_ia4_tex_from_i1(packedTexture, 8, 8);
gDPPipeSync(gDisplayListHead++);
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, VIRTUAL_TO_PHYSICAL(unpackedTexture));
#else
gDPPipeSync(gDisplayListHead++);
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, VIRTUAL_TO_PHYSICAL(packedTexture));
#endif
gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings);
}
@@ -1106,7 +1175,7 @@ void render_dialog_entries(void) {
void **dialogTable;
struct DialogEntry *dialog;
s8 lowerBound = 0;
dialogTable = segmented_to_virtual(seg2_dialog_table);
dialogTable = segmented_to_virtual(languageTable[gInGameLanguage][0]);
dialog = segmented_to_virtual(dialogTable[gDialogID]);
// if the dialog entry is invalid, set the ID to -1.
@@ -1354,7 +1423,7 @@ void print_peach_letter_message(void) {
void **dialogTable;
struct DialogEntry *dialog;
u8 *str;
dialogTable = segmented_to_virtual(seg2_dialog_table);
dialogTable = segmented_to_virtual(languageTable[gInGameLanguage][0]);
dialog = segmented_to_virtual(dialogTable[gDialogID]);
str = segmented_to_virtual(dialog->str);
@@ -1536,8 +1605,8 @@ void render_pause_my_score_coins(void) {
u8 courseIndex;
u8 starFlags;
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
actNameTbl = segmented_to_virtual(seg2_act_name_table);
courseNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][1]);
actNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][2]);
courseIndex = gCurrCourseNum - 1;
starFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1);
@@ -1738,7 +1807,7 @@ void render_pause_castle_course_stars(s16 x, s16 y, s16 fileNum, s16 courseNum)
}
void render_pause_castle_main_strings(s16 x, s16 y) {
void **courseNameTbl = segmented_to_virtual(seg2_course_name_table);
void **courseNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][1]);
u8 textCoin[] = { TEXT_COIN_X };
@@ -1981,8 +2050,8 @@ void render_course_complete_lvl_info_and_hud_str(void) {
u8 strCourseNum[4];
actNameTbl = segmented_to_virtual(seg2_act_name_table);
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
actNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][2]);
courseNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][1]);
if (gLastCompletedCourseNum <= COURSE_STAGES_MAX) {
print_hud_course_complete_coins(118, 103);
@@ -2068,9 +2137,6 @@ void render_save_confirmation(s16 x, s16 y, s8 *index, s16 sp6e)
s16 render_course_complete_screen(void) {
s16 index;
#ifdef VERSION_EU
gInGameLanguage = eu_get_language();
#endif
switch (gDialogBoxState) {
case DIALOG_STATE_OPENING:

View File

@@ -37,6 +37,7 @@ enum MenuMode {
extern s8 gDialogCourseActNum;
extern s8 gHudFlash;
extern s16 gInGameLanguage;
struct DialogEntry
{

View File

@@ -20,7 +20,7 @@
#include "obj_behaviors.h"
#include "save_file.h"
#include "debug_course.h"
#ifdef VERSION_EU
#if MULTILANG
#include "memory.h"
#include "eu_translation.h"
#include "segment_symbols.h"
@@ -1281,23 +1281,28 @@ s32 lvl_init_or_update(s16 initOrUpdate, UNUSED s32 unused) {
return result;
}
s32 lvl_init_from_save_file(UNUSED s16 arg0, s32 levelNum) {
#ifdef VERSION_EU
s16 var = eu_get_language();
switch (var) {
#if MULTILANG
void load_language_text(void)
{
switch (gInGameLanguage-1)
{
case LANGUAGE_ENGLISH:
load_segment_decompress(0x19, _translation_en_yay0SegmentRomStart,
_translation_en_yay0SegmentRomEnd);
load_segment_decompress(0x19, _translation_en_yay0SegmentRomStart, _translation_en_yay0SegmentRomEnd);
break;
case LANGUAGE_FRENCH:
load_segment_decompress(0x19, _translation_fr_yay0SegmentRomStart,
_translation_fr_yay0SegmentRomEnd);
load_segment_decompress(0x19, _translation_fr_yay0SegmentRomStart, _translation_fr_yay0SegmentRomEnd);
break;
case LANGUAGE_GERMAN:
load_segment_decompress(0x19, _translation_de_yay0SegmentRomStart,
_translation_de_yay0SegmentRomEnd);
load_segment_decompress(0x19, _translation_de_yay0SegmentRomStart, _translation_de_yay0SegmentRomEnd);
break;
}
}
#endif
s32 lvl_init_from_save_file(UNUSED s16 arg0, s32 levelNum) {
#if MULTILANG
gInGameLanguage = eu_get_language()+1;
load_language_text();
#endif
sWarpDest.type = WARP_TYPE_NOT_WARPING;
sDelayedWarpOp = WARP_OP_NONE;

View File

@@ -70,6 +70,7 @@ extern u16 D_80339ECA;
extern s16 sTransitionTimer;
extern void (*sTransitionUpdate)(s16 *);
extern u8 unused3[4];
extern void load_language_text(void);
struct WarpDest {
u8 type;

View File

@@ -22,11 +22,12 @@
#include "behavior_data.h"
#include "save_file.h"
#include "mario.h"
#include "puppyprint.h"
#ifdef PUPPYCAM
#define OFFSET 30.0f
#define STEPS 1
#define STEPS 4
#define DECELERATION 0.66f
#define DEADZONE 20
#define SCRIPT_MEMORY_POOL 0x1000
@@ -44,18 +45,16 @@ struct MemoryPool *gPuppyMemoryPool;
s32 gPuppyError = 0;
#if defined(VERSION_EU)
static u8 gPCOptionStringsFR[][64] = {{NC_ANALOGUE_FR}, {NC_CAMX_FR}, {NC_CAMY_FR}, {NC_INVERTX_FR}, {NC_INVERTY_FR}, {NC_CAMC_FR}, {NC_SCHEME_FR}, {NC_WIDE_FR},};
static u8 gPCOptionStringsDE[][64] = {{NC_ANALOGUE_DE}, {NC_CAMX_DE}, {NC_CAMY_DE}, {NC_INVERTX_DE}, {NC_INVERTY_DE}, {NC_CAMC_DE}, {NC_SCHEME_DE}, {NC_WIDE_DE},};
static u8 gPCFlagStringsFR[][64] = {{OPTION_DISABLED_FR}, {OPTION_ENABLED_FR}, {OPTION_SCHEME1_FR}, {OPTION_SCHEME2_FR}, {OPTION_SCHEME3_FR}};
static u8 gPCFlagStringsDE[][64] = {{OPTION_DISABLED_DE}, {OPTION_ENABLED_DE}, {OPTION_SCHEME1_DE}, {OPTION_SCHEME2_DE}, {OPTION_SCHEME3_DE}};
static u8 gPCToggleStringsFR[][64] = {{NC_ANALOGUE_EN}, {NC_ANALOGUE_EN}, {NC_ANALOGUE_EN}, {NC_ANALOGUE_EN}, {NC_ANALOGUE_EN}};
static u8 gPCToggleStringsDE[][64] = {{NC_ANALOGUE_EN}, {NC_ANALOGUE_EN}, {NC_ANALOGUE_EN}, {NC_ANALOGUE_EN}, {NC_ANALOGUE_EN}};
//static u8 gPCToggleStringsFR[][64] = {{NC_BUTTON_FR}, {NC_BUTTON2_FR}, {NC_OPTION_FR}, {NC_HIGHLIGHT_L_FR}, {NC_HIGHLIGHT_R_FR}};
//static u8 gPCToggleStringsDE[][64] = {{NC_BUTTON_DE}, {NC_BUTTON2_DE}, {NC_OPTION_DE}, {NC_HIGHLIGHT_L_DE}, {NC_HIGHLIGHT_R_DE}};
static u8 gPCOptionStringsFR[][64] = {{NC_ANALOGUE_FR}, {NC_CAMX_FR}, {NC_CAMY_FR}, {NC_INVERTX_FR}, {NC_INVERTY_FR}, {NC_CAMC_FR}, {NC_SCHEME_FR}, {NC_WIDE_FR}, {OPTION_LANGUAGE_FR}};
static u8 gPCOptionStringsDE[][64] = {{NC_ANALOGUE_DE}, {NC_CAMX_DE}, {NC_CAMY_DE}, {NC_INVERTX_DE}, {NC_INVERTY_DE}, {NC_CAMC_DE}, {NC_SCHEME_DE}, {NC_WIDE_DE}, {OPTION_LANGUAGE_DE}};
static u8 gPCFlagStringsFR[][64] = {{OPTION_DISABLED_FR}, {OPTION_ENABLED_FR}, {OPTION_SCHEME1_FR}, {OPTION_SCHEME2_FR}, {OPTION_SCHEME3_FR}, {TEXT_ENGLISH}, {TEXT_FRENCH}, {TEXT_GERMAN},};
static u8 gPCFlagStringsDE[][64] = {{OPTION_DISABLED_DE}, {OPTION_ENABLED_DE}, {OPTION_SCHEME1_DE}, {OPTION_SCHEME2_DE}, {OPTION_SCHEME3_DE}, {TEXT_ENGLISH}, {TEXT_FRENCH}, {TEXT_GERMAN},};
static u8 gPCToggleStringsFR[][64] = {{NC_BUTTON_FR}, {NC_BUTTON2_FR}, {NC_OPTION_FR}, {NC_HIGHLIGHT_L}, {NC_HIGHLIGHT_R},};
static u8 gPCToggleStringsDE[][64] = {{NC_BUTTON_DE}, {NC_BUTTON2_DE}, {NC_OPTION_DE}, {NC_HIGHLIGHT_L}, {NC_HIGHLIGHT_R},};
#endif
static u8 gPCOptionStringsEN[][64] = {{NC_ANALOGUE_EN}, {NC_CAMX_EN}, {NC_CAMY_EN}, {NC_INVERTX_EN}, {NC_INVERTY_EN}, {NC_CAMC_EN}, {NC_SCHEME_EN}, {NC_WIDE_EN},};
static u8 gPCFlagStringsEN[][64] = {{OPTION_DISABLED_EN}, {OPTION_ENABLED_EN}, {OPTION_SCHEME1_EN}, {OPTION_SCHEME2_EN}, {OPTION_SCHEME3_EN}};
static u8 gPCToggleStringsEN[][64] = {{NC_BUTTON_EN}, {NC_BUTTON2_EN}, {NC_OPTION_EN}, {NC_HIGHLIGHT_L}, {NC_HIGHLIGHT_R}};
static u8 gPCOptionStringsEN[][64] = {{NC_ANALOGUE_EN}, {NC_CAMX_EN}, {NC_CAMY_EN}, {NC_INVERTX_EN}, {NC_INVERTY_EN}, {NC_CAMC_EN}, {NC_SCHEME_EN}, {NC_WIDE_EN}, {OPTION_LANGUAGE_EN}};
static u8 gPCFlagStringsEN[][64] = {{OPTION_DISABLED_EN}, {OPTION_ENABLED_EN}, {OPTION_SCHEME1_EN}, {OPTION_SCHEME2_EN}, {OPTION_SCHEME3_EN}, {TEXT_ENGLISH}, {TEXT_FRENCH}, {TEXT_GERMAN},};
static u8 gPCToggleStringsEN[][64] = {{NC_BUTTON_EN}, {NC_BUTTON2_EN}, {NC_OPTION_EN}, {NC_HIGHLIGHT_L}, {NC_HIGHLIGHT_R},};
#define OPT 32 //Just a temp thing
@@ -76,7 +75,12 @@ static const struct gPCOptionStruct
static const struct gPCOptionStruct gPCOptions[]=
{ //If the min and max are 0 and 1, then the value text is used, otherwise it's ignored.
#ifdef WIDE
{/*Option Name*/ 7, /*Option Variable*/ &gWidescreen, /*Option Value Text Start*/ 0, /*Option Minimum*/ FALSE, /*Option Maximum*/ TRUE},
#endif
#if MULTILANG
{/*Option Name*/ 8, /*Option Variable*/ &gInGameLanguage, /*Option Value Text Start*/ 4, /*Option Minimum*/ 1, /*Option Maximum*/ 3},
#endif
{/*Option Name*/ 0, /*Option Variable*/ &gPuppyCam.options.analogue, /*Option Value Text Start*/ 0, /*Option Minimum*/ FALSE, /*Option Maximum*/ TRUE},
{/*Option Name*/ 6, /*Option Variable*/ &gPuppyCam.options.inputType, /*Option Value Text Start*/ 2, /*Option Minimum*/ 0, /*Option Maximum*/ 2},
{/*Option Name*/ 1, /*Option Variable*/ &gPuppyCam.options.sensitivityX, /*Option Value Text Start*/ 255, /*Option Minimum*/ 10, /*Option Maximum*/ 500},
@@ -161,10 +165,10 @@ void puppycam_warp(f32 displacementX, f32 displacementY, f32 displacementZ)
gPuppyCam.floorY[1] += displacementY;
}
#if defined(VERSION_EU)
#if MULTILANG
static void newcam_set_language(void)
{
switch (eu_get_language())
switch (gInGameLanguage-1)
{
case 0:
gPCOptionStringsPtr = &gPCOptionStringsEN;
@@ -213,7 +217,7 @@ static void newcam_process_cutscene(void)
#define BLANK 0, 0, 0, ENVIRONMENT, 0, 0, 0, ENVIRONMENT
static void puppycam_display_box(s16 x1, s16 y1, s16 x2, s16 y2, u8 r, u8 g, u8 b, u8 a)
static void puppycam_display_box(s32 x1, s32 y1, s32 x2, s32 y2, u8 r, u8 g, u8 b, u8 a)
{
gDPSetCombineMode(gDisplayListHead++, BLANK, BLANK);
gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE);
@@ -249,11 +253,15 @@ void puppycam_change_setting(s8 toggle)
*gPCOptions[gPCOptionSelected].gPCOptionVar += toggle;
//Forgive me father, for I have sinned. I guess if you wanted a selling point for a 21:9 monitor though, "I can view this line in puppycam's code without scrolling!" can be added to it.
*gPCOptions[gPCOptionSelected].gPCOptionVar = CLAMP(*gPCOptions[gPCOptionSelected].gPCOptionVar, gPCOptions[gPCOptionSelected].gPCOptionMin, gPCOptions[gPCOptionSelected].gPCOptionMax);
#if defined(VERSION_EU)
newcam_set_language();
#endif
}
void puppycam_print_text(s16 x, s16 y, u8 str[], u8 col)
void puppycam_print_text(s32 x, s32 y, u8 str[], s32 col)
{
u8 textX;
s32 textX;
textX = get_str_x_pos_from_center(x,str,10.0f);
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255);
print_generic_string(textX+1,y-1,str);
@@ -271,14 +279,14 @@ void puppycam_print_text(s16 x, s16 y, u8 str[], u8 col)
//Options menu
void puppycam_display_options()
{
u8 i = 0;
u8 newstring[32];
s16 scroll;
s16 scrollpos;
s32 i = 0;
char newstring[32];
s32 scroll;
s32 scrollpos;
s16 var = gPCOptions;
s16 vr;
u16 maxvar;
u16 minvar;
s32 vr;
s32 maxvar;
s32 minvar;
f32 newcam_sinpos;
puppycam_display_box(47,83,281,84,0x0,0x0,0x0, 0xFF);
@@ -290,7 +298,7 @@ void puppycam_display_options()
puppycam_display_box(48,84,272,218,0x0,0x0,0x0, 0x50);
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
print_hud_lut_string(HUD_LUT_GLOBAL, 64, 40, (*gPCToggleStringsPtr)[2]);
print_hud_lut_string(HUD_LUT_GLOBAL, 112, 40, (*gPCToggleStringsPtr)[2]);
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
if (gPCOptionCap>4)
@@ -353,14 +361,17 @@ void puppycam_check_pause_buttons()
if (gPCOptionOpen == 0)
{
gPCOptionOpen = 1;
#if defined(VERSION_EU)
#if MULTILANG
newcam_set_language();
eu_set_language(gInGameLanguage-1);
#endif
}
else
{
gPCOptionOpen = 0;
#if MULTILANG
load_language_text();
#endif
puppycam_set_save();
}
}

View File

@@ -226,7 +226,7 @@ static void save_main_menu_data(void) {
add_save_block_signature(&gSaveBuffer.menuData[0], sizeof(gSaveBuffer.menuData[0]), MENU_DATA_MAGIC);
// Back up data
bcopy(&gSaveBuffer.menuData[0], &gSaveBuffer.menuData[1], sizeof(gSaveBuffer.menuData[1]));
//bcopy(&gSaveBuffer.menuData[0], &gSaveBuffer.menuData[1], sizeof(gSaveBuffer.menuData[1]));
// Write to EEPROM
write_eeprom_data(gSaveBuffer.menuData, sizeof(gSaveBuffer.menuData));
@@ -360,7 +360,7 @@ void save_file_load_all(void) {
// Verify the main menu data and create a backup copy if only one of the slots is valid.
validSlots = verify_save_block_signature(&gSaveBuffer.menuData[0], sizeof(gSaveBuffer.menuData[0]), MENU_DATA_MAGIC);
validSlots |= verify_save_block_signature(&gSaveBuffer.menuData[1], sizeof(gSaveBuffer.menuData[1]),MENU_DATA_MAGIC) << 1;
//validSlots |= verify_save_block_signature(&gSaveBuffer.menuData[1], sizeof(gSaveBuffer.menuData[1]),MENU_DATA_MAGIC) << 1;
switch (validSlots) {
case 0: // Neither copy is correct
wipe_main_menu_data();
@@ -407,6 +407,9 @@ void puppycam_get_save(void)
gPuppyCam.options = gSaveBuffer.menuData[0].saveOptions;
gSaveBuffer.menuData[0].firstBoot = gSaveBuffer.menuData[0].firstBoot;
#ifdef WIDE
gWidescreen = save_file_get_widescreen_mode();
#endif
puppycam_check_save();
}
@@ -417,6 +420,10 @@ void puppycam_set_save(void)
gSaveBuffer.menuData[0].firstBoot = 4;
#ifdef WIDE
save_file_set_widescreen_mode(gWidescreen);
#endif
gMainMenuDataModified = TRUE;
save_main_menu_data();
}

View File

@@ -23,6 +23,13 @@
#include "text_strings.h"
#include "eu_translation.h"
#if MULTILANG
#undef LANGUAGE_FUNCTION
#define LANGUAGE_FUNCTION sLanguageMode
s8 sLanguageMode = LANGUAGE_ENGLISH;
#endif
extern void *languageTable[][3];
/**
* @file file_select.c
@@ -32,7 +39,7 @@
*/
// The current sound mode is automatically centered on US and Shindou.
static s16 sSoundTextX;
s16 sSoundTextX;
//! @Bug (UB Array Access) For EU, more buttons were added than the array was extended.
//! This causes no currently known issues on console (as the other variables are not changed
@@ -41,121 +48,128 @@ static s16 sSoundTextX;
// Amount of main menu buttons defined in the code called by spawn_object_rel_with_rot.
// See file_select.h for the names in MenuButtonTypes.
static struct Object *sMainMenuButtons[NUM_BUTTONS];
struct Object *sMainMenuButtons[NUM_BUTTONS];
// Used to defined yes/no fade colors after a file is selected in the erase menu.
// sYesNoColor[0]: YES | sYesNoColor[1]: NO
static u8 sYesNoColor[2];
u8 sYesNoColor[2];
// The button that is selected when it is clicked.
static s8 sSelectedButtonID = MENU_BUTTON_NONE;
s8 sSelectedButtonID = MENU_BUTTON_NONE;
// Whether we are on the main menu or one of the submenus.
static s8 sCurrentMenuLevel = MENU_LAYER_MAIN;
s8 sCurrentMenuLevel = MENU_LAYER_MAIN;
// Used for text opacifying. If it is below 250, it is constantly incremented.
static u8 sTextBaseAlpha = 0;
u8 sTextBaseAlpha = 0;
// 2D position of the cursor on the screen.
// sCursorPos[0]: X | sCursorPos[1]: Y
static f32 sCursorPos[] = {0, 0};
f32 sCursorPos[] = {0, 0};
// Determines which graphic to use for the cursor.
static s16 sCursorClickingTimer = 0;
s16 sCursorClickingTimer = 0;
// Equal to sCursorPos if the cursor gets clicked, {-10000, -10000} otherwise.
static s16 sClickPos[] = {-10000, -10000};
s16 sClickPos[] = {-10000, -10000};
// Used for determining which file has been selected during copying and erasing.
static s8 sSelectedFileIndex = -1;
s8 sSelectedFileIndex = -1;
// Whether to fade out text or not.
static s8 sFadeOutText = FALSE;
s8 sFadeOutText = FALSE;
// The message currently being displayed at the top of a menu.
static s8 sStatusMessageID = 0;
s8 sStatusMessageID = 0;
// Used for text fading. The alpha value of text is calculated as
// sTextBaseAlpha - sTextFadeAlpha.
static u8 sTextFadeAlpha = 0;
u8 sTextFadeAlpha = 0;
// File select timer that keeps counting until it reaches 1000.
// Used to prevent buttons from being clickable as soon as a menu loads.
// Gets reset when you click an empty save, existing saves in copy and erase menus
// and when you click yes/no in the erase confirmation prompt.
static s16 sMainMenuTimer = 0;
s16 sMainMenuTimer = 0;
// Sound mode menu buttonID, has different values compared to gSoundMode in audio.
// 0: gSoundMode = 0 (Stereo) | 1: gSoundMode = 3 (Mono) | 2: gSoundMode = 1 (Headset)
static s8 sSoundMode = 0;
s8 sSoundMode = 0;
// Active language for EU arrays, values defined similar to sSoundMode
// 0: English | 1: French | 2: German
// Tracks which button will be pressed in the erase confirmation prompt (yes/no).
static s8 sEraseYesNoHoverState = MENU_ERASE_HOVER_NONE;
s8 sEraseYesNoHoverState = MENU_ERASE_HOVER_NONE;
// Used for the copy menu, defines if the game as all 4 save slots with data.
// if TRUE, it doesn't allow copying more files.
static s8 sAllFilesExist = FALSE;
s8 sAllFilesExist = FALSE;
// Defines the value of the save slot selected in the menu.
// Mario A: 1 | Mario B: 2 | Mario C: 3 | Mario D: 4
static s8 sSelectedFileNum = 0;
s8 sSelectedFileNum = 0;
// Which coin score mode to use when scoring files. 0 for local
// coin high score, 1 for high score across all files.
static s8 sScoreFileCoinScoreMode = 0;
s8 sScoreFileCoinScoreMode = 0;
// In EU, if no save file exists, open the language menu so the user can find it.
static unsigned char textReturn[] = { TEXT_RETURN };
unsigned char textReturn[][8] = { {TEXT_RETURN}, };
static unsigned char textViewScore[] = { TEXT_CHECK_SCORE };
unsigned char textViewScore[] = { TEXT_CHECK_SCORE };
static unsigned char textCopyFileButton[] = { TEXT_COPY_FILE_BUTTON };
unsigned char textCopyFileButton[] = { TEXT_COPY_FILE_BUTTON };
static unsigned char textEraseFileButton[] = { TEXT_ERASE_FILE_BUTTON };
unsigned char textEraseFileButton[] = { TEXT_ERASE_FILE_BUTTON };
static unsigned char textSoundModes[][8] = { { TEXT_STEREO }, { TEXT_MONO }, { TEXT_HEADSET } };
unsigned char textSoundModes[][8] = { { TEXT_STEREO }, { TEXT_MONO }, { TEXT_HEADSET } };
static unsigned char textMarioA[] = { TEXT_FILE_MARIO_A };
static unsigned char textMarioB[] = { TEXT_FILE_MARIO_B };
static unsigned char textMarioC[] = { TEXT_FILE_MARIO_C };
static unsigned char textMarioD[] = { TEXT_FILE_MARIO_D };
#if MULTILANG
unsigned char textLanguageSelect[][17] = { { TEXT_LANGUAGE_SELECT }};
#endif
static unsigned char textNew[] = { TEXT_NEW };
static unsigned char starIcon[] = { GLYPH_STAR, GLYPH_SPACE };
static unsigned char xIcon[] = { GLYPH_MULTIPLY, GLYPH_SPACE };
unsigned char textSoundSelect[][13] = { { TEXT_SOUND_SELECT },};
static unsigned char textSelectFile[] = { TEXT_SELECT_FILE };
unsigned char textMarioA[] = { TEXT_FILE_MARIO_A };
unsigned char textMarioB[] = { TEXT_FILE_MARIO_B };
unsigned char textMarioC[] = { TEXT_FILE_MARIO_C };
unsigned char textMarioD[] = { TEXT_FILE_MARIO_D };
static unsigned char textScore[] = { TEXT_SCORE };
unsigned char textNew[] = { TEXT_NEW };
unsigned char starIcon[] = { GLYPH_STAR, GLYPH_SPACE };
unsigned char xIcon[] = { GLYPH_MULTIPLY, GLYPH_SPACE };
static unsigned char textCopy[] = { TEXT_COPY };
unsigned char textSelectFile[] = { TEXT_SELECT_FILE };
static unsigned char textErase[] = { TEXT_ERASE };
unsigned char textScore[] = { TEXT_SCORE };
unsigned char textCopy[] = { TEXT_COPY };
static unsigned char textCheckFile[] = { TEXT_CHECK_FILE };
unsigned char textErase[] = { TEXT_ERASE };
static unsigned char textNoSavedDataExists[] = { TEXT_NO_SAVED_DATA_EXISTS };
unsigned char textLanguage[][9] = {{ TEXT_ENGLISH }, { TEXT_FRENCH }, { TEXT_GERMAN }};
static unsigned char textCopyFile[] = { TEXT_COPY_FILE };
unsigned char textCheckFile[] = { TEXT_CHECK_FILE };
static unsigned char textCopyItToWhere[] = { TEXT_COPY_IT_TO_WHERE };
unsigned char textNoSavedDataExists[] = { TEXT_NO_SAVED_DATA_EXISTS };
static unsigned char textNoSavedDataExistsCopy[] = { TEXT_NO_SAVED_DATA_EXISTS };
unsigned char textCopyFile[] = { TEXT_COPY_FILE };
static unsigned char textCopyCompleted[] = { TEXT_COPYING_COMPLETED };
unsigned char textCopyItToWhere[] = { TEXT_COPY_IT_TO_WHERE };
static unsigned char textSavedDataExists[] = { TEXT_SAVED_DATA_EXISTS };
unsigned char textNoSavedDataExistsCopy[] = { TEXT_NO_SAVED_DATA_EXISTS };
static unsigned char textNoFileToCopyFrom[] = { TEXT_NO_FILE_TO_COPY_FROM };
unsigned char textCopyCompleted[] = { TEXT_COPYING_COMPLETED };
static unsigned char textYes[] = { TEXT_YES };
unsigned char textSavedDataExists[] = { TEXT_SAVED_DATA_EXISTS };
static unsigned char textNo[] = { TEXT_NO };
unsigned char textNoFileToCopyFrom[] = { TEXT_NO_FILE_TO_COPY_FROM };
unsigned char textYes[] = { TEXT_YES };
unsigned char textNo[] = { TEXT_NO };
/**
@@ -198,7 +212,7 @@ s32 check_clicked_button(s16 x, s16 y, f32 depth) {
/**
* Grow from main menu, used by selecting files and menus.
*/
static void bhv_menu_button_growing_from_main_menu(struct Object *button) {
void bhv_menu_button_growing_from_main_menu(struct Object *button) {
if (button->oMenuButtonTimer < 16) {
button->oFaceAngleYaw += 0x800;
}
@@ -225,7 +239,7 @@ static void bhv_menu_button_growing_from_main_menu(struct Object *button) {
/**
* Shrink back to main menu, used to return back while inside menus.
*/
static void bhv_menu_button_shrinking_to_main_menu(struct Object *button) {
void bhv_menu_button_shrinking_to_main_menu(struct Object *button) {
if (button->oMenuButtonTimer < 16) {
button->oFaceAngleYaw -= 0x800;
}
@@ -252,7 +266,7 @@ static void bhv_menu_button_shrinking_to_main_menu(struct Object *button) {
/**
* Grow from submenu, used by selecting a file in the score menu.
*/
static void bhv_menu_button_growing_from_submenu(struct Object *button) {
void bhv_menu_button_growing_from_submenu(struct Object *button) {
if (button->oMenuButtonTimer < 16) {
button->oFaceAngleYaw += 0x800;
}
@@ -277,7 +291,7 @@ static void bhv_menu_button_growing_from_submenu(struct Object *button) {
/**
* Shrink back to submenu, used to return back while inside a score save menu.
*/
static void bhv_menu_button_shrinking_to_submenu(struct Object *button) {
void bhv_menu_button_shrinking_to_submenu(struct Object *button) {
if (button->oMenuButtonTimer < 16) {
button->oFaceAngleYaw -= 0x800;
}
@@ -305,7 +319,7 @@ static void bhv_menu_button_shrinking_to_submenu(struct Object *button) {
* A small increase and decrease in size.
* Used by failed copy/erase/score operations and sound mode select.
*/
static void bhv_menu_button_zoom_in_out(struct Object *button) {
void bhv_menu_button_zoom_in_out(struct Object *button) {
if (sCurrentMenuLevel == MENU_LAYER_MAIN) {
if (button->oMenuButtonTimer < 4) {
button->oParentRelativePosZ -= 20.0f;
@@ -332,7 +346,7 @@ static void bhv_menu_button_zoom_in_out(struct Object *button) {
* A small temporary increase in size.
* Used while selecting a target copy/erase file or yes/no erase confirmation prompt.
*/
static void bhv_menu_button_zoom_in(struct Object *button) {
void bhv_menu_button_zoom_in(struct Object *button) {
button->oMenuButtonScale += 0.0022;
button->oMenuButtonTimer++;
if (button->oMenuButtonTimer == 10) {
@@ -346,7 +360,7 @@ static void bhv_menu_button_zoom_in(struct Object *button) {
* Used after selecting a target copy/erase file or
* yes/no erase confirmation prompt to undo the zoom in.
*/
static void bhv_menu_button_zoom_out(struct Object *button) {
void bhv_menu_button_zoom_out(struct Object *button) {
button->oMenuButtonScale -= 0.0022;
button->oMenuButtonTimer++;
if (button->oMenuButtonTimer == 10) {
@@ -888,7 +902,11 @@ void check_erase_menu_clicked_buttons(struct Object *eraseButton) {
#undef ACTION_TIMER
#undef MAIN_RETURN_TIMER
#if MULTILANG
#define SOUND_BUTTON_Y 388
#else
#define SOUND_BUTTON_Y 0
#endif
/**
* Render buttons for the sound mode menu.
@@ -907,8 +925,28 @@ void render_sound_mode_menu_buttons(struct Object *soundModeButton) {
soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, -533, SOUND_BUTTON_Y, -100, 0, -0x8000, 0);
sMainMenuButtons[MENU_BUTTON_HEADSET]->oMenuButtonScale = 0.11111111f;
#if MULTILANG
// English option button
sMainMenuButtons[MENU_BUTTON_LANGUAGE_ENGLISH] = spawn_object_rel_with_rot(
soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 533, -111, -100, 0, -0x8000, 0);
sMainMenuButtons[MENU_BUTTON_LANGUAGE_ENGLISH]->oMenuButtonScale = 0.11111111f;
// French option button
sMainMenuButtons[MENU_BUTTON_LANGUAGE_FRENCH] = spawn_object_rel_with_rot(
soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 0, -111, -100, 0, -0x8000, 0);
sMainMenuButtons[MENU_BUTTON_LANGUAGE_FRENCH]->oMenuButtonScale = 0.11111111f;
// German option button
sMainMenuButtons[MENU_BUTTON_LANGUAGE_GERMAN] = spawn_object_rel_with_rot(
soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, -533, -111, -100, 0, -0x8000, 0);
sMainMenuButtons[MENU_BUTTON_LANGUAGE_GERMAN]->oMenuButtonScale = 0.11111111f;
// Return button
sMainMenuButtons[MENU_BUTTON_LANGUAGE_RETURN] = spawn_object_rel_with_rot(
soundModeButton, MODEL_MAIN_MENU_YELLOW_FILE_BUTTON, bhvMenuButton, 0, -533, -100, 0, -0x8000, 0);
sMainMenuButtons[MENU_BUTTON_LANGUAGE_RETURN]->oMenuButtonScale = 0.11111111f;
#else
// Zoom in current selection
sMainMenuButtons[MENU_BUTTON_OPTION_MIN + sSoundMode]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN;
#endif
}
#undef SOUND_BUTTON_Y
@@ -934,13 +972,33 @@ void check_sound_mode_menu_clicked_buttons(struct Object *soundModeButton) {
queue_rumble_data(5, 80);
#endif
sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT;
#if !MULTILANG
// Sound menu buttons don't return to Main Menu in EU
// because they don't have a case in bhv_menu_button_manager_loop
sSelectedButtonID = buttonID;
#endif
sSoundMode = buttonID - MENU_BUTTON_OPTION_MIN;
save_file_set_sound_mode(sSoundMode);
}
}
#if MULTILANG
// If language mode button clicked, select it and change language
if (buttonID == MENU_BUTTON_LANGUAGE_ENGLISH || buttonID == MENU_BUTTON_LANGUAGE_FRENCH
|| buttonID == MENU_BUTTON_LANGUAGE_GERMAN) {
if (soundModeButton->oMenuButtonActionPhase == SOUND_MODE_PHASE_MAIN) {
play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource);
sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT;
sLanguageMode = buttonID - MENU_BUTTON_LANGUAGE_MIN;
eu_set_language(sLanguageMode);
}
}
// If neither of the buttons above are pressed, return to main menu
if (buttonID == MENU_BUTTON_LANGUAGE_RETURN) {
play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource);
sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT;
sSelectedButtonID = buttonID;
}
#endif
sCurrentMenuLevel = MENU_LAYER_SUBMENU;
break;
@@ -1386,6 +1444,11 @@ void bhv_menu_button_manager_loop(void) {
check_sound_mode_menu_clicked_buttons(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]);
break;
#if MULTILANG
case MENU_BUTTON_LANGUAGE_RETURN:
return_to_main_menu(MENU_BUTTON_SOUND_MODE, sMainMenuButtons[MENU_BUTTON_LANGUAGE_RETURN]);
break;
#endif
// STEREO, MONO and HEADSET buttons are undefined so they can be selected without
// exiting the Options menu, as a result they added a return button
case MENU_BUTTON_STEREO:
@@ -1999,7 +2062,13 @@ void print_erase_menu_strings(void) {
gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end);
}
#define SOUND_HUD_X 88
#if MULTILANG
#define SOUND_HUD_X 96
#define SOUND_HUD_Y 141
#else
#define SOUND_HUD_X 47
#define SOUND_HUD_Y 87
#endif
/**
* Prints sound mode menu strings that shows on the purple background menu screen.
@@ -2008,33 +2077,49 @@ void print_erase_menu_strings(void) {
*/
void print_sound_mode_menu_strings(void) {
s32 mode;
s16 textX;
unsigned char textSoundSelect[] = { TEXT_SOUND_SELECT };
s32 textX;
// Print "SOUND SELECT" text
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha);
print_hud_lut_string(HUD_LUT_DIFF, SOUND_HUD_X, 35, textSoundSelect);
print_hud_lut_string(HUD_LUT_DIFF, SOUND_HUD_X, 32, LANGUAGE_ARRAY(textSoundSelect));
#if MULTILANG
print_hud_lut_string(HUD_LUT_DIFF, 47, 101, LANGUAGE_ARRAY(textLanguageSelect));
#endif
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
// Print sound mode names
for (mode = 0; mode < 3; mode++) {
for (mode = 0, textX = 90; mode < 3; textX += 70, mode++) {
if (mode == sSoundMode) {
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha);
} else {
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, sTextBaseAlpha);
}
// Mode names are centered correctly on US and Shindou
textX = get_str_x_pos_from_center(mode * 74 + 87, textSoundModes[mode], 10.0f);
print_generic_string(textX, 87, textSoundModes[mode]);
print_generic_string(
get_str_x_pos_from_center(textX, LANGUAGE_ARRAY(textSoundModes[mode]), 10.0f),
SOUND_HUD_Y, LANGUAGE_ARRAY(textSoundModes[mode]));
}
#if MULTILANG
// In EU, print language mode names
for (mode = 0, textX = 90; mode < 3; textX += 70, mode++) {
if (mode == LANGUAGE_FUNCTION) {
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha);
} else {
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, sTextBaseAlpha);
}
print_generic_string(
get_str_x_pos_from_center(textX, textLanguage[mode], 10.0f),
72, textLanguage[mode]);
}
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha);
print_generic_string(182, 29, LANGUAGE_ARRAY(textReturn));
#endif
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
}
@@ -2136,7 +2221,7 @@ void print_save_file_scores(s8 fileIndex) {
unsigned char textHiScore[] = { TEXT_HI_SCORE };
unsigned char textMyScore[] = { TEXT_MY_SCORE };
unsigned char textFileLetter[] = { TEXT_ZERO };
void **levelNameTable = segmented_to_virtual(seg2_course_name_table);
void **levelNameTable = segmented_to_virtual(languageTable[gInGameLanguage][1]);
textFileLetter[0] = fileIndex + ASCII_TO_DIALOG('A'); // get letter of file selected
@@ -2198,7 +2283,7 @@ void print_save_file_scores(s8 fileIndex) {
* Prints file select strings depending on the menu selected.
* Also checks if all saves exists and defines text and main menu timers.
*/
static void print_file_select_strings(void) {
void print_file_select_strings(void) {
UNUSED s32 unused1;
UNUSED s32 unused2;

View File

@@ -78,7 +78,7 @@ enum MenuButtonTypes {
MENU_BUTTON_MONO,
MENU_BUTTON_HEADSET,
#ifdef VERSION_EU
#if MULTILANG
// Language Menu
MENU_BUTTON_LANGUAGE_MIN,
MENU_BUTTON_LANGUAGE_ENGLISH = MENU_BUTTON_LANGUAGE_MIN,