The start of QOL_FIXES has finally arrived!

This commit is contained in:
Colton Rushton 2021-02-12 08:18:36 -04:00
parent fc5cb66f07
commit 84512c4335
59 changed files with 538 additions and 70 deletions

View File

@ -41,8 +41,8 @@ TARGET_BITS ?= 0
BETTERCAMERA ?= 0
# Disable no drawing distance by default
NODRAWINGDISTANCE ?= 0
# Disable texture fixes by default (helps with them purists)
TEXTURE_FIX ?= 0
# Disable QoL fixes by default (helps with them purists)
QOL_FIXES ?= 0
# Enable extended options menu by default
EXT_OPTIONS_MENU ?= 1
# Disable text-based save-files by default
@ -582,9 +582,9 @@ ifeq ($(DISCORDRPC),1)
endif
# Check for texture fix option
ifeq ($(TEXTURE_FIX),1)
CC_CHECK += -DTEXTURE_FIX
CFLAGS += -DTEXTURE_FIX
ifeq ($(QOL_FIXES),1)
CC_CHECK += -DQOL_FIXES
CFLAGS += -DQOL_FIXES
endif
# Check for extended options menu option

View File

@ -12,6 +12,8 @@ const GeoLayout boo_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -12,6 +12,8 @@ const GeoLayout boo_castle_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -24,6 +24,8 @@ const GeoLayout bookend_part_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -26,6 +26,8 @@ const GeoLayout bowser_key_cutscene_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -12,7 +12,7 @@ static const Vtx burn_smoke_seg4_vertex_040217C0[] = {
// as a transparent black burn smoke. Probably meant to show up as white-ish
// burn smoke, but mistakened for being intended as black smoke.
// Due to debate in the Koopa shorts PR surrounding the fix to a similar bug,
// said fix is on a compile-time variable. Use TEXTURE_FIX=1 at compile time
// said fix is on a compile-time variable. Use QOL_FIXES=1 at compile time
// to fix this.
// 0x04021800
ALIGNED8 static const u8 burn_smoke_seg4_texture_04021800[] = {
@ -47,7 +47,7 @@ const Gfx burn_smoke_seg4_dl_04022048[] = {
// 0x04022070 - 0x040220C8
const Gfx burn_smoke_seg4_dl_04022070[] = {
gsSPDisplayList(burn_smoke_seg4_dl_04022000),
#ifdef TEXTURE_FIX
#ifdef QOL_FIXES
gsDPLoadTextureBlock(burn_smoke_seg4_texture_04021800, G_IM_FMT_IA, G_IM_SIZ_16b, 32, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD),
#else
gsDPLoadTextureBlock(burn_smoke_seg4_texture_04021800, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD),

View File

@ -17,6 +17,8 @@ const GeoLayout chain_chomp_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -24,6 +24,8 @@ const GeoLayout haunted_chair_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -21,7 +21,9 @@ const GeoLayout castle_door_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};
@ -48,7 +50,9 @@ const GeoLayout cabin_door_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};
@ -75,7 +79,9 @@ const GeoLayout wooden_door_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};
@ -102,7 +108,9 @@ const GeoLayout wooden_door2_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};
@ -129,7 +137,9 @@ const GeoLayout metal_door_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};
@ -156,7 +166,9 @@ const GeoLayout hazy_maze_door_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};
@ -183,7 +195,9 @@ const GeoLayout haunted_door_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};
@ -216,7 +230,9 @@ const GeoLayout castle_door_0_star_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};
@ -249,7 +265,9 @@ const GeoLayout castle_door_1_star_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};
@ -282,7 +300,9 @@ const GeoLayout castle_door_3_stars_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};
@ -315,6 +335,8 @@ const GeoLayout key_door_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -49,6 +49,8 @@ const GeoLayout dorrie_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -57,6 +57,8 @@ const GeoLayout hoot_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -115,6 +115,8 @@ const GeoLayout king_bobomb_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -55,7 +55,7 @@ static const Lights1 koopa_seg6_lights_06002630 = gdSPDefLights1(
// the rest of its body. This is evident because once the mistake is corrected
// it turns back to being white like the other polygons.
// Due to debate in the PR surrounding the fix to this, said fix is on
// a compile-time variable. Use TEXTURE_FIX=1 at compile time to fix this.
// a compile-time variable. Use QOL_FIXES=1 at compile time to fix this.
// 0x06002648
ALIGNED8 static const u8 koopa_seg6_texture_06002648[] = {
#include "actors/koopa/koopa_shell_front.rgba16.inc.c"
@ -2079,7 +2079,7 @@ const Gfx koopa_seg6_dl_0600C498[] = {
gsSPVertex(koopa_seg6_vertex_0600B560, 9, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP1Triangle( 6, 7, 8, 0x0),
#ifdef TEXTURE_FIX
#ifdef QOL_FIXES
gsSPLight(&koopa_seg6_lights_06002630.l, 1),
gsSPLight(&koopa_seg6_lights_06002630.a, 2),
#else

View File

@ -16,6 +16,8 @@ const GeoLayout mad_piano_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -49,7 +49,9 @@ const GeoLayout mips_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -52,7 +52,9 @@ const GeoLayout moneybag_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -22,6 +22,8 @@ const GeoLayout snufit_geo[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -2171,8 +2171,8 @@ struct CD3DX12_RT_FORMAT_ARRAY : public D3D12_RT_FORMAT_ARRAY
struct DefaultSampleMask { operator UINT() { return UINT_MAX; } };
struct DefaultSampleDesc { operator DXGI_SAMPLE_DESC() { return DXGI_SAMPLE_DESC{1, 0}; } };
#pragma warning(push)
#pragma warning(disable : 4324)
//#pragma warning(push)
//#pragma warning(disable : 4324)
template <typename InnerStructType, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE Type, typename DefaultArg = InnerStructType>
class alignas(void*) CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT
{
@ -2188,7 +2188,7 @@ public:
InnerStructType* operator&() { return &_Inner; }
InnerStructType const* operator&() const { return &_Inner; }
};
#pragma warning(pop)
//#pragma warning(pop)
typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_PIPELINE_STATE_FLAGS, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS> CD3DX12_PIPELINE_STATE_STREAM_FLAGS;
typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK> CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK;
typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< ID3D12RootSignature*, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE> CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE;

View File

@ -291,7 +291,11 @@ struct MarioState
/*0x0C*/ u32 action;
/*0x10*/ u32 prevAction;
/*0x14*/ u32 terrainSoundAddend;
#ifdef QOL_FIXES
/*0x18*/ u32 actionState;
#else
/*0x18*/ u16 actionState;
#endif
/*0x1A*/ u16 actionTimer;
/*0x1C*/ u32 actionArg;
/*0x20*/ f32 intendedMag;
@ -329,10 +333,17 @@ struct MarioState
/*0x9C*/ struct Controller *controller;
/*0xA0*/ struct MarioAnimation *animation;
/*0xA4*/ u32 collidedObjInteractTypes;
#ifndef QOL_FIXES
/*0xA8*/ s16 numCoins;
/*0xAA*/ s16 numStars;
/*0xAC*/ s8 numKeys; // Unused key mechanic
/*0xAD*/ s8 numLives;
#else
/*0xA8*/ u64 numCoins;
/*0xAA*/ u64 numStars;
/*0xAC*/ u64 numKeys; // Unused key mechanic
/*0xAD*/ u64 numLives;
#endif
/*0xAE*/ s16 health;
/*0xB0*/ s16 unkB0;
/*0xB2*/ u8 hurtCounter;

View File

@ -22,6 +22,8 @@ const GeoLayout castle_grounds_geo_000660[] = {
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#ifndef QOL_FIXES
GEO_CLOSE_NODE(), //! more close than open nodes
#endif
GEO_END(),
};

View File

@ -27,7 +27,12 @@ const Trajectory ccm_seg7_trajectory_penguin_race[] = {
TRAJECTORY_POS(24, /*pos*/ 1333, 761, -1733),
TRAJECTORY_POS(25, /*pos*/ 2488, 562, -2944),
TRAJECTORY_POS(26, /*pos*/ 2977, 361, -4988),
#ifndef QOL_FIXES
//! missing ID
#else
//TODO: Find suitable coordinates for this
//TRAJECTORY_POS(27, /*pos*/ 0, 0, 0),
#endif
TRAJECTORY_POS(28, /*pos*/ 3754, 329, -5689),
TRAJECTORY_POS(29, /*pos*/ 5805, 86, -5980),
TRAJECTORY_POS(30, /*pos*/ 6566, -449, -4133),

View File

@ -7,6 +7,11 @@ const GeoLayout ttm_geo_000920[] = {
GEO_DISPLAY_LIST(LAYER_OPAQUE, ttm_seg7_dl_0700DF78),
GEO_OPEN_NODE(),
GEO_CLOSE_NODE(),
//! Too many open nodes. Unfortunately not exploitable
GEO_END(),
#ifndef QOL_FIXES
//! Too many open nodes. Unfortunately not exploitable
#else
GEO_CLOSE_NODE(),
GEO_CLOSE_NODE(),
#endif
GEO_END(),
};

View File

@ -19,7 +19,9 @@
static const LevelScript script_func_local_1[] = {
OBJECT(/*model*/ MODEL_VCUTM_SEESAW_PLATFORM, /*pos*/ 154, -1919, -6256, /*angle*/ 0, 270, 0, /*behParam*/ 0x00070000, /*beh*/ bhvSeesawPlatform),
OBJECT(/*model*/ MODEL_VCUTM_SEESAW_PLATFORM, /*pos*/ -2047, -3378, -2047, /*angle*/ 0, 0, 0, /*behParam*/ 0x00070000, /*beh*/ bhvSeesawPlatform),
#ifndef QOL_FIXES
//! @bug invalid model IDs - model ID 0x37 isn't loaded
#endif
OBJECT(/*model*/ MODEL_VCUTM_CHECKERBOARD_PLATFORM_SPAWNER, /*pos*/ 3251, -1082, -6256, /*angle*/ 0, 270, 0, /*behParam*/ 0x014B0000, /*beh*/ bhvCheckerboardElevatorGroup),
OBJECT(/*model*/ MODEL_VCUTM_CHECKERBOARD_PLATFORM_SPAWNER, /*pos*/ 2355, -1901, -6256, /*angle*/ 0, 270, 0, /*behParam*/ 0x014B0000, /*beh*/ bhvCheckerboardElevatorGroup),
OBJECT(/*model*/ MODEL_VCUTM_CHECKERBOARD_PLATFORM_SPAWNER, /*pos*/ 1459, -1594, -6256, /*angle*/ 0, 90, 0, /*behParam*/ 0x014B0000, /*beh*/ bhvCheckerboardElevatorGroup),

View File

@ -557,9 +557,14 @@ void func_eu_802e27e4_unused(f32 arg0, f32 arg1, u16 *arg2) {
tmp[9] = (f32) (((arg0 * arg0) + arg1) * 262159.0f);
for (i = 2; i < 8; i++) {
#ifndef QOL_FIXES
//! @bug they probably meant to store the value to tmp[i] and tmp[8 + i]
arg2[i] = arg1 * tmp[i - 2] + arg0 * tmp[i - 1];
arg2[8 + i] = arg1 * tmp[6 + i] + arg0 * tmp[7 + i];
#else
tmp[i] = arg1 * tmp[i - 2] + arg0 * tmp[i - 1];
tmp[8 + i] = arg1 * tmp[6 + i] + arg0 * tmp[7 + i];
#endif
}
for (i = 0; i < 16; i++) {

View File

@ -485,7 +485,7 @@ void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32
drum = PATCH(patched, mem);
mem->drums[i] = drum;
if (drum->loaded == 0) {
#ifndef VERSION_EU
#if !defined(VERSION_EU) || !defined(QOL_FIXES)
//! copt replaces drum with 'patched' for these two lines
PATCH_SOUND(&(*(struct Drum *)patched).sound, mem, offset);
patched = (*(struct Drum *)patched).envelope;

View File

@ -271,6 +271,7 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) {
case 0xc4: // layer_somethingon
case 0xc5: // layer_somethingoff
#ifndef QOL_FIXES
//! copt needs a ternary:
//layer->continuousNotes = (cmd == 0xc4) ? TRUE : FALSE;
if (cmd == 0xc4) {
@ -278,6 +279,9 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) {
} else {
temp8 = FALSE;
}
#else
temp8 = layer->continuousNotes = (cmd == 0xc4) ? TRUE : FALSE;
#endif
layer->continuousNotes = temp8;
seq_channel_layer_note_decay(layer);
break;
@ -427,6 +431,7 @@ l1090:
}
if (layer->portamento.mode != 0) {
#ifndef QOL_FIXES
//! copt needs a ternary:
//usedSemitone = (layer->portamentoTargetNote < SEMITONE) ? SEMITONE : layer->portamentoTargetNote;
if (layer->portamentoTargetNote < SEMITONE) {
@ -434,6 +439,9 @@ l1090:
} else {
USED_SEMITONE = layer->portamentoTargetNote;
}
#else
USED_SEMITONE = (layer->portamentoTargetNote < SEMITONE) ? SEMITONE : layer->portamentoTargetNote;
#endif
if (instrument != NULL) {
sound = (u8) USED_SEMITONE < instrument->normalRangeLo ? &instrument->lowNotesSound

View File

@ -12,17 +12,17 @@ Vec4s *gSplineKeyframe;
float gSplineKeyframeFraction;
int gSplineState;
// These functions have bogus return values.
// Disable the compiler warning.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wreturn-local-addr"
// These functions have bogus return values
// unless QOL_FIXES is set to 1.
/// Copy vector 'src' to 'dest'
void *vec3f_copy(Vec3f dest, Vec3f src) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Set vector 'dest' to (x, y, z)
@ -30,7 +30,9 @@ void *vec3f_set(Vec3f dest, f32 x, f32 y, f32 z) {
dest[0] = x;
dest[1] = y;
dest[2] = z;
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Add vector 'a' to 'dest'
@ -38,7 +40,9 @@ void *vec3f_add(Vec3f dest, Vec3f a) {
dest[0] += a[0];
dest[1] += a[1];
dest[2] += a[2];
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Make 'dest' the sum of vectors a and b.
@ -46,7 +50,9 @@ void *vec3f_sum(Vec3f dest, Vec3f a, Vec3f b) {
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
dest[2] = a[2] + b[2];
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Multiply vector 'dest' by a
@ -55,7 +61,9 @@ void *vec3f_mul(Vec3f dest, f32 a)
dest[0] *= a;
dest[1] *= a;
dest[2] *= a;
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Copy vector src to dest
@ -63,7 +71,9 @@ void *vec3s_copy(Vec3s dest, Vec3s src) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Set vector 'dest' to (x, y, z)
@ -71,7 +81,9 @@ void *vec3s_set(Vec3s dest, s16 x, s16 y, s16 z) {
dest[0] = x;
dest[1] = y;
dest[2] = z;
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Add vector a to 'dest'
@ -79,7 +91,9 @@ void *vec3s_add(Vec3s dest, Vec3s a) {
dest[0] += a[0];
dest[1] += a[1];
dest[2] += a[2];
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Make 'dest' the sum of vectors a and b.
@ -87,7 +101,9 @@ void *vec3s_sum(Vec3s dest, Vec3s a, Vec3s b) {
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
dest[2] = a[2] + b[2];
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Make 'dest' the difference of vectors a and b.
@ -95,7 +111,9 @@ void *vec3f_dif(Vec3f dest, Vec3f a, Vec3f b) {
dest[0] = a[0] - b[0];
dest[1] = a[1] - b[1];
dest[2] = a[2] - b[2];
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Convert short vector a to float vector 'dest'
@ -103,7 +121,9 @@ void *vec3s_to_vec3f(Vec3f dest, Vec3s a) {
dest[0] = a[0];
dest[1] = a[1];
dest[2] = a[2];
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/**
@ -115,7 +135,9 @@ void *vec3f_to_vec3s(Vec3s dest, Vec3f a) {
dest[0] = a[0] + ((a[0] > 0) ? 0.5f : -0.5f);
dest[1] = a[1] + ((a[1] > 0) ? 0.5f : -0.5f);
dest[2] = a[2] + ((a[2] > 0) ? 0.5f : -0.5f);
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/**
@ -127,7 +149,9 @@ void *find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c)
dest[0] = (b[1] - a[1]) * (c[2] - b[2]) - (c[1] - b[1]) * (b[2] - a[2]);
dest[1] = (b[2] - a[2]) * (c[0] - b[0]) - (c[2] - b[2]) * (b[0] - a[0]);
dest[2] = (b[0] - a[0]) * (c[1] - b[1]) - (c[0] - b[0]) * (b[1] - a[1]);
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Make vector 'dest' the cross product of vectors a and b.
@ -135,18 +159,31 @@ void *vec3f_cross(Vec3f dest, Vec3f a, Vec3f b) {
dest[0] = a[1] * b[2] - b[1] * a[2];
dest[1] = a[2] * b[0] - b[2] * a[0];
dest[2] = a[0] * b[1] - b[0] * a[1];
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Scale vector 'dest' so it has length 1
void *vec3f_normalize(Vec3f dest) {
//! Possible division by zero
f32 invsqrt = 1.0f / sqrtf(dest[0] * dest[0] + dest[1] * dest[1] + dest[2] * dest[2]);
#ifndef QOL_FIXES
//! Possible division by zero
f32 invsqrt = 1.0f / sqrtf(dest[0] * dest[0] + dest[1] * dest[1] + dest[2] * dest[2]);
#else
// Fix the division by zero warning by multiplying by 0 when the sqrtf equation happens to equal 0
if (sqrtf(dest[0] * dest[0] + dest[1] * dest[1] + dest[2] * dest[2]) != 0) {
f32 invsqrt = 1.0f / sqrtf(dest[0] * dest[0] + dest[1] * dest[1] + dest[2] * dest[2]);
} else {
f32 invsqrt = 1.0f * 0;
}
#endif
dest[0] *= invsqrt;
dest[1] *= invsqrt;
dest[2] *= invsqrt;
return &dest; //! warning: function returns address of local variable
#ifndef QOL_FIXES
return &dest; //! warning: function returns address of local variable
#endif
}
/// Get length of vector 'a'
@ -161,8 +198,6 @@ f32 vec3f_dot(Vec3f a, Vec3f b)
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
#pragma GCC diagnostic pop
/// Copy matrix 'src' to 'dest'
void mtxf_copy(Mat4 dest, Mat4 src) {
register s32 i;

View File

@ -313,7 +313,7 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
s16 x, y, z;
//! (Parallel Universes) Because position is casted to an s16, reaching higher
// float locations can return ceilings despite them not existing there.
// float locations can return ceilings despite them not existing there.
//(Dynamic ceilings will unload due to the range.)
x = (s16) posX;
y = (s16) posY;

View File

@ -112,7 +112,7 @@ void bhv_bowling_ball_initializeLoop(void) {
bowling_ball_set_waypoints();
//! Uninitialzed parameter, but the parameter is unused in the called function
//! Uninitialized parameter, but the parameter is unused in the called function
sp1c = cur_obj_follow_path(sp1c);
o->oMoveAngleYaw = o->oPathedTargetYaw;

View File

@ -121,8 +121,12 @@ void bully_act_back_up(void) {
// will be stuck in BULLY_ACT_BACK_UP forever until Mario hits it or its death
// conditions are activated. However because its angle is set to its facing angle,
// it will walk forward instead of backing up.
// A potential fix for this is used in QOL_FIXES.
#ifndef QOL_FIXES
if (o->oTimer == 15) {
#else
if (o->oTimer >= 15) {
#endif
o->oMoveAngleYaw = o->oFaceAngleYaw;
o->oFlags |= 0x8; /* bit 3 */
o->oAction = BULLY_ACT_PATROL;

View File

@ -26,7 +26,11 @@ void bhv_castle_floor_trap_open_detect(void) {
void bhv_castle_floor_trap_open(void) {
if (o->oTimer == 0)
cur_obj_play_sound_2(SOUND_GENERAL_CASTLE_TRAP_OPEN);
#ifndef QOL_FIXES
cur_obj_play_sound_2(SOUND_GENERAL_CASTLE_TRAP_OPEN);
#else
create_sound_spawner(SOUND_GENERAL_CASTLE_TRAP_OPEN);
#endif
o->oAngleVelRoll -= 0x100;
o->oFaceAngleRoll += o->oAngleVelRoll;
if (o->oFaceAngleRoll < -0x4000) {

View File

@ -6,9 +6,14 @@ void bhv_squishable_platform_loop(void) {
}
void bhv_bitfs_sinking_platform_loop(void) {
// remove the conversion entirely in QOL_FIXES
#ifndef QOL_FIXES
o->oPosY -=
sins(o->oPlatformTimer)
* 0.58; //! f32 double conversion error accumulates on Wii VC causing the platform to rise up
#else
o->oPosY -= sins(o->oPlatformTimer) * 0.58f;
#endif
o->oPlatformTimer += 0x100;
}

View File

@ -75,8 +75,14 @@ void bhv_pokey_body_part_update(void) {
//! If you kill a body part as it's expanding, the body part that
// was above it will instantly shrink and begin expanding in its
// place.
// Partially fixed for now (a full fix is planned) in QOL_FIXES
#ifndef QOL_FIXES
else if (o->parentObj->oPokeyBottomBodyPartSize < 1.0f
&& o->oBehParams2ndByte + 1 == o->parentObj->oPokeyNumAliveBodyParts) {
#else
if (o->parentObj->oPokeyBottomBodyPartSize < 1.0f
&& o->oBehParams2ndByte + 1 == o->parentObj->oPokeyNumAliveBodyParts) {
#endif
approach_f32_ptr(&o->parentObj->oPokeyBottomBodyPartSize, 1.0f, 0.1f);
cur_obj_scale(o->parentObj->oPokeyBottomBodyPartSize * 3.0f);
}

View File

@ -15,6 +15,10 @@ void bhv_seaweed_bundle_init(void) {
seaweed->header.gfx.scale[1] = 1.0;
seaweed->header.gfx.scale[2] = 1.0;
//! gfx.animFrame uninitialized
// fixed in QOL_FIXES
#ifdef QOL_FIXES
seaweed->header.gfx.unk38.animFrame = random_float() * 80.0f;
#endif
seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed);
seaweed->oFaceAngleYaw = 41800;

View File

@ -90,11 +90,16 @@ void bhv_tilting_inverted_pyramid_loop(void) {
linear_mtxf_mul_vec3f(*transform, posBeforeRotation, dist);
dx = gMarioObject->oPosX - o->oPosX;
#ifndef QOL_FIXES
dy = 500.0f;
#else
dy = gMarioObject->oPosY - o->oPosY;
#endif
dz = gMarioObject->oPosZ - o->oPosZ;
d = sqrtf(dx * dx + dy * dy + dz * dz);
//! Always true since dy = 500, making d >= 500.
// fixed above in QOL_FIXES
if (d != 0.0f) {
// Normalizing
d = 1.0 / d;

View File

@ -74,7 +74,12 @@ void tuxies_mother_act_1(void) {
// o->prevObj->oUnknownUnk88 &= ~INT_SUBTYPE_DROP_IMMEDIATELY
// which has no effect as o->prevObj->oUnknownUnk88 is always 0
// or 1, which is not affected by the bitwise AND.
// fix attempted in QOL_FIXES
#ifndef QOL_FIXES
o->prevObj->OBJECT_FIELD_S32(o->oInteractionSubtype) &= ~INT_SUBTYPE_DROP_IMMEDIATELY;
#else
o->prevObj->oInteractionSubtype &= ~INT_SUBTYPE_DROP_IMMEDIATELY;
#endif
obj_set_behavior(o->prevObj, bhvUnused20E0);
#ifndef VERSION_JP
cur_obj_spawn_star_at_y_offset(3167.0f, -4300.0f, 5108.0f, 200.0f);
@ -87,7 +92,12 @@ void tuxies_mother_act_1(void) {
case 2:
if (o->prevObj->oHeldState == HELD_FREE) {
//! Same bug as above
// fix attempted in QOL_FIXES
#ifndef QOL_FIXES
o->prevObj->OBJECT_FIELD_S32(o->oInteractionSubtype) &= ~INT_SUBTYPE_DROP_IMMEDIATELY;
#else
o->prevObj->oInteractionSubtype &= ~INT_SUBTYPE_DROP_IMMEDIATELY;
#endif
obj_set_behavior(o->prevObj, bhvPenguinBaby);
o->oAction = 2;
}

View File

@ -21,6 +21,7 @@ void water_ring_init(void) {
// This cause the ring's orientation for the purposes of collision to be
// different than the graphical orientation, which means that Mario won't
// necessarily collect a ring even if he appears to swim through it.
// This is documented, but more research is needed on the fix for QOL_FIXES
o->oWaterRingNormalX = coss(o->oFaceAnglePitch) * sins(o->oFaceAngleRoll) * -1.0f;
o->oWaterRingNormalY = coss(o->oFaceAnglePitch) * coss(o->oFaceAngleRoll);
o->oWaterRingNormalZ = sins(o->oFaceAnglePitch);

View File

@ -668,10 +668,16 @@ f32 calc_y_to_curr_floor(f32 *posOff, f32 posMul, f32 posBound, f32 *focOff, f32
UNUSED s32 filler;
if (!(sMarioCamState->action & ACT_FLAG_METAL_WATER)) {
#ifndef QOL_FIXES
//! @bug this should use sMarioGeometry.waterHeight
if (floorHeight < (waterHeight = find_water_level(sMarioCamState->pos[0], sMarioCamState->pos[2]))) {
floorHeight = waterHeight;
}
#else
if (floorHeight < (sMarioGeometry.waterHeight = find_water_level(sMarioCamState->pos[0], sMarioCamState->pos[2]))) {
floorHeight = sMarioGeometry.waterHeight;
}
#endif
}
if (sMarioCamState->action & ACT_FLAG_ON_POLE) {
@ -1578,9 +1584,11 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
}
focusDistance = calc_abs_dist(sMarioCamState->pos, secondFocus) * 1.6f;
#ifndef QOL_FIXES
if (focusDistance < 800.f) {
focusDistance = 800.f;
}
#endif
if (focusDistance > 5000.f) {
focusDistance = 5000.f;
}
@ -1609,9 +1617,18 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
switch (gCurrLevelArea) {
case AREA_BOB:
pos[1] += 125.f;
#ifndef QOL_FIXES
//! fall through, makes the BoB boss fight camera move up twice as high as it should
#else
break;
#endif
case AREA_WF:
pos[1] += 125.f;
// what if there's other bosses that have their boss fight cameras set here by mods?
// fix them with QOL_FIXES
#ifdef QOL_FIXES
break;
#endif
}
}
@ -1639,10 +1656,14 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
: -gMarioStates[0].angleVel[1]);
}
#ifdef QOL_FIXES
//! Unnecessary conditional, focusDistance is already bounded to 800
// Under QOL_FIXES, this conditional takes effect instead of the other conditional that sets
// focusDistance's minimum bound to 800
if (focusDistance < 400.f) {
focusDistance = 400.f;
}
#endif
// Set C-Down distance and pitch.
// C-Down will essentially double the distance from the center.
@ -1781,10 +1802,12 @@ s32 update_behind_mario_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
// Focus on Mario
vec3f_copy(focus, sMarioCamState->pos);
c->focus[1] += focYOff;
#ifndef QOL_FIXES
//! @bug unnecessary
dist = calc_abs_dist(focus, pos);
//! @bug unnecessary
pitch = calculate_pitch(focus, pos);
#endif
vec3f_get_dist_and_angle(focus, pos, &dist, &pitch, &yaw);
if (dist > maxDist) {
dist = maxDist;
@ -2195,12 +2218,16 @@ s16 update_default_camera(struct Camera *c) {
unusedFreeRoamWallYaw = avoidYaw;
sAvoidYawVel = yaw;
sStatusFlags |= CAM_FLAG_COLLIDED_WITH_WALL;
#ifndef QOL_FIXES
//! Does nothing
vec3f_get_dist_and_angle(sMarioCamState->pos, cPos, &xzDist, &tempPitch, &tempYaw);
#endif
// Rotate to avoid the wall
approach_s16_asymptotic_bool(&yaw, avoidYaw, 10);
#ifndef QOL_FIXES
//! Does nothing
vec3f_set_dist_and_angle(sMarioCamState->pos, cPos, xzDist, tempPitch, tempYaw);
#endif
sAvoidYawVel = (sAvoidYawVel - yaw) / 0x100;
} else {
if (gMarioStates[0].forwardVel == 0.f) {
@ -2455,8 +2482,10 @@ s32 update_spiral_stairs_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
}
focYaw += sSpiralStairsYawOffset;
posYaw = focYaw;
#ifndef QOL_FIXES
//! @bug unnecessary
camera_approach_s16_symmetric_bool(&posYaw, focYaw, 0x1000);
#endif
vec3f_set_dist_and_angle(sFixedModeBasePosition, cPos, 300.f, 0, posYaw);
@ -2924,14 +2953,17 @@ void update_lakitu(struct Camera *c) {
if (gCameraMovementFlags & CAM_MOVE_PAUSE_SCREEN) {
} else {
if (c->cutscene) {
#ifndef QOL_FIXES
}
if (TRUE) {
#endif
newYaw = next_lakitu_state(newPos, newFoc, c->pos, c->focus, sOldPosition, sOldFocus,
c->nextYaw);
set_or_approach_s16_symmetric(&c->yaw, newYaw, sYawSpeed);
sStatusFlags &= ~CAM_FLAG_UNUSED_CUTSCENE_ACTIVE;
} else {
//! dead code, moved to next_lakitu_state()
// no longer dead in QOL_FIXES
vec3f_copy(newPos, c->pos);
vec3f_copy(newFoc, c->focus);
}
@ -4819,13 +4851,22 @@ s32 offset_yaw_outward_radial(struct Camera *c, s16 areaYaw) {
}
// When the final yaw is out of [-60,60] degrees, approach yawGoal faster than dYaw will ever be,
// making the camera lock in one direction until yawGoal drops below 60 (or Mario presses a C button)
// QOL_FIXES makes an attempt to fix this
if (yaw < -DEGREES(60)) {
#ifndef QOL_FIXES
//! Maybe they meant to reverse yawGoal's sign?
camera_approach_s16_symmetric_bool(&yaw, -yawGoal, 0x200);
#else
camera_approach_s16_symmetric_bool(&yaw, yawGoal, 0x200);
#endif
}
if (yaw > DEGREES(60)) {
#ifndef QOL_FIXES
//! Maybe they meant to reverse yawGoal's sign?
camera_approach_s16_symmetric_bool(&yaw, yawGoal, 0x200);
#else
camera_approach_s16_symmetric_bool(&yaw, -yawGoal, 0x200);
#endif
}
return yaw;
}
@ -4897,7 +4938,11 @@ void play_sound_if_cam_switched_to_lakitu_or_mario(void) {
* Handles input for radial, outwards radial, parallel tracking, and 8 direction mode.
*/
s32 radial_camera_input(struct Camera *c, UNUSED f32 unused) {
#ifndef QOL_FIXES
s16 dummy;
#else
s16 dummy = 0;
#endif
if ((gCameraMovementFlags & CAM_MOVE_ENTERED_ROTATE_SURFACE) || !(gCameraMovementFlags & CAM_MOVE_ROTATE)) {
@ -4996,6 +5041,7 @@ s32 radial_camera_input(struct Camera *c, UNUSED f32 unused) {
}
//! returning uninitialized variable
// fixed in QOL_FIXES
return dummy;
}
@ -5386,8 +5432,12 @@ void offset_rotated(Vec3f dst, Vec3f from, Vec3f to, Vec3s rotation) {
vec3f_copy(unusedCopy, from);
// First rotate the direction by rotation's pitch
#ifndef QOL_FIXES
//! The Z axis is flipped here.
pitchRotated[2] = -(to[2] * coss(rotation[0]) - to[1] * sins(rotation[0]));
#else
pitchRotated[2] = to[2] * coss(rotation[0]) - to[1] * sins(rotation[0]);
#endif
pitchRotated[1] = to[2] * sins(rotation[0]) + to[1] * coss(rotation[0]);
pitchRotated[0] = to[0];
@ -6310,8 +6360,10 @@ struct CameraTrigger sCamCastle[] = {
{ 1, cam_castle_close_mode, -2304, -264, -4072, 140, 150, 140, 0 },
{ 1, cam_castle_close_mode, -2304, 145, -1344, 140, 150, 140, 0 },
{ 1, cam_castle_enter_lobby, -2304, 145, -802, 140, 150, 140, 0 },
#ifndef QOL_FIXES
//! Sets the camera mode when leaving secret aquarium
{ 1, cam_castle_close_mode, 2816, 1200, -256, 100, 100, 100, 0 },
#endif
{ 1, cam_castle_close_mode, 256, -161, -4226, 140, 150, 140, 0 },
{ 1, cam_castle_close_mode, 256, 145, -1344, 140, 150, 140, 0 },
{ 1, cam_castle_enter_lobby, 256, 145, -802, 140, 150, 140, 0 },
@ -6333,8 +6385,10 @@ struct CameraTrigger sCamCastle[] = {
{ 1, cam_castle_close_mode, -3393, 350, -793, 140, 150, 140, 0x4000 },
{ 1, cam_castle_enter_lobby, -2851, 350, -792, 140, 150, 140, 0x4000 },
{ 1, cam_castle_enter_lobby, 803, 350, -228, 140, 150, 140, -0x4000 },
#ifndef QOL_FIXES
//! Duplicate camera trigger outside JRB door
{ 1, cam_castle_enter_lobby, 803, 350, -228, 140, 150, 140, -0x4000 },
#endif
{ 1, cam_castle_close_mode, 1345, 350, -229, 140, 150, 140, 0x4000 },
{ 1, cam_castle_close_mode, -946, -929, 622, 300, 150, 300, 0 },
{ 2, cam_castle_look_upstairs, -205, 1456, 2508, 210, 928, 718, 0 },
@ -6590,6 +6644,7 @@ s16 camera_course_processing(struct Camera *c) {
sCameraTriggers[level][b].boundsY,
sCameraTriggers[level][b].boundsZ);
#ifndef QOL_FIXES
// Check if Mario is inside the bounds
if (is_pos_in_bounds(sMarioCamState->pos, center, bounds,
sCameraTriggers[level][b].boundsYaw) == TRUE) {
@ -6600,6 +6655,15 @@ s16 camera_course_processing(struct Camera *c) {
insideBounds = TRUE;
}
}
#else
if (!(sStatusFlags & CAM_FLAG_BLOCK_AREA_PROCESSING)) {
if (is_pos_in_bounds(sMarioCamState->pos, center, bounds,
sCameraTriggers[level][b].boundsYaw) == TRUE) {
sCameraTriggers[level][b].event(c);
insideBounds = TRUE;
}
}
#endif
}
if ((sCameraTriggers[level])[b].area == -1) {
@ -6705,8 +6769,13 @@ s16 camera_course_processing(struct Camera *c) {
break;
case AREA_DDD_WHIRLPOOL:
#ifndef QOL_FIXES
//! @bug this does nothing
gLakituState.defMode = CAMERA_MODE_OUTWARD_RADIAL;
#else
// maybe the above was supposed to be the following instead
set_mode_if_not_set_by_surface(c, CAMERA_MODE_OUTWARD_RADIAL);
#endif
break;
case AREA_DDD_SUB:
@ -6722,8 +6791,12 @@ s16 camera_course_processing(struct Camera *c) {
}
}
}
#ifndef QOL_FIXES
//! @bug this does nothing
gLakituState.defMode = CAMERA_MODE_FREE_ROAM;
#else
// maybe the above was supposed to be the following instead
set_mode_if_not_set_by_surface(c, CAMERA_MODE_FREE_ROAM);
break;
}
}
@ -7035,7 +7108,11 @@ void copy_spline_segment(struct CutsceneSplinePoint dst[], struct CutsceneSpline
init_spline_point(&dst[i], src[j].index, src[j].speed, src[j].point);
i += 1;
j += 1;
#ifndef QOL_FIXES
} while ((src[j].index != -1) && (src[j].index != -1)); //! same comparison performed twice
#else
} while ((src[j].index != -1));
#endif
} while (j > 16);
// Create the end of the spline by duplicating the last point
@ -7480,9 +7557,14 @@ BAD_RETURN(s32) cutscene_ending_kiss_here_we_go(struct Camera *c) {
set_fov_function(CAM_FOV_DEFAULT);
vec3f_set(foc, 233.f, 1068.f, -1298.f);
vec3f_set(pos, -250.f, 966.f, -1111.f);
#ifndef QOL_FIXES
//! another double typo
approach_vec3f_asymptotic(c->pos, pos, 0.2, 0.1f, 0.2f);
approach_vec3f_asymptotic(c->focus, foc, 0.2, 0.1f, 0.2f);
#else
approach_vec3f_asymptotic(c->pos, pos, 0.2f, 0.1f, 0.2f);
approach_vec3f_asymptotic(c->focus, foc, 0.2f, 0.1f, 0.2f);
#endif
}
/**
@ -9233,10 +9315,14 @@ BAD_RETURN(s32) cutscene_exit_bowser_succ_focus_left(UNUSED struct Camera *c) {
* The shake lasts 32 frames.
*/
BAD_RETURN(s32) cutscene_exit_bowser_key_toss_shake(struct Camera *c) {
#ifndef QOL_FIXES
//! Unnecessary check.
if (c->cutscene == CUTSCENE_EXIT_BOWSER_SUCC) {
set_camera_pitch_shake(0x800, 0x40, 0x800);
}
#else
set_camera_pitch_shake(0x800, 0x40, 0x800);
#endif
}
/**
@ -10347,7 +10433,12 @@ BAD_RETURN(s32) cutscene_door_fix_cam(struct Camera *c) {
*/
BAD_RETURN(s32) cutscene_door_loop(struct Camera *c) {
//! bitwise AND instead of boolean
// fixed with QOL_FIXES
#ifndef QOL_FIXES
if ((sMarioCamState->action != ACT_PULLING_DOOR) & (sMarioCamState->action != ACT_PUSHING_DOOR)) {
#else
if ((sMarioCamState->action != ACT_PULLING_DOOR) && (sMarioCamState->action != ACT_PUSHING_DOOR)) {
#endif
gCutsceneTimer = CUTSCENE_STOP;
c->cutscene = 0;
}
@ -10366,11 +10457,15 @@ BAD_RETURN(s32) cutscene_door_move_behind_mario(struct Camera *c) {
vec3s_set(sCutsceneVars[0].angle, 0, sMarioCamState->faceAngle[1] + doorRotation, 0);
vec3f_set(camOffset, 0.f, 125.f, 250.f);
#ifndef QOL_FIXES
if (doorRotation == 0) { //! useless code
camOffset[0] = 0.f;
} else {
camOffset[0] = 0.f;
}
#else
camOffset[0] = 0.f;
#endif
offset_rotated(c->pos, sMarioCamState->pos, camOffset, sCutsceneVars[0].angle);
}
@ -11306,9 +11401,15 @@ void play_cutscene(struct Camera *c) {
#undef CUTSCENE
if ((cutsceneDuration != 0) && !(gCutsceneTimer & CUTSCENE_STOP)) {
#ifndef QOL_FIXES
//! @bug This should check for 0x7FFF (CUTSCENE_LOOP)
//! instead, cutscenes that last longer than 0x3FFF frames will never end on their own
// fixed with QOL_FIXES
#ifndef QOL_FIXES
if (gCutsceneTimer < 0x3FFF) {
#else
if (gCutsceneTimer < CUTSCENE_LOOP) {
#endif
gCutsceneTimer += 1;
}
//! Because gCutsceneTimer is often set to 0x7FFF (CUTSCENE_LOOP), this conditional can only
@ -11533,6 +11634,11 @@ Gfx *geo_camera_fov(s32 callContext, struct GraphNode *g, UNUSED void *context)
approach_fov_60(marioState);
break;
//! No default case
// fixed by QOL_FIXES
#ifdef QOL_FIXES
default:
break;
#endif
}
}

View File

@ -180,10 +180,14 @@ void print_mapinfo(void) {
print_debug_top_down_normal("mapinfo", 0);
print_debug_top_down_mapinfo("area %x", area);
print_debug_top_down_mapinfo("wx %d", gCurrentObject->oPosX);
#ifndef QOL_FIXES
//! Fat finger: programmer hit tab instead of space. Japanese
// thumb shift keyboards had the tab key next to the spacebar,
// so this was likely the reason.
print_debug_top_down_mapinfo("wy\t %d", gCurrentObject->oPosY);
#else
print_debug_top_down_mapinfo("wy %d", gCurrentObject->oPosY);
#endif
print_debug_top_down_mapinfo("wz %d", gCurrentObject->oPosZ);
print_debug_top_down_mapinfo("bgY %d", bgY);
print_debug_top_down_mapinfo("angY %d", angY);

View File

@ -348,16 +348,18 @@ s32 envfx_init_bubble(s32 mode) {
bzero(gEnvFxBubbleConfig, sizeof(gEnvFxBubbleConfig));
if (mode == ENVFX_LAVA_BUBBLES) {
#ifndef QOL_FIXES
//! Dead code
if (0) {
}
#endif
for (i = 0; i < sBubbleParticleCount; i++) {
(gEnvFxBuffer + i)->animFrame = random_float() * 7.0f;
}
#ifndef QOL_FIXES
if (0) {
}
#endif
}
gEnvFxMode = mode;

View File

@ -414,7 +414,13 @@ void print_generic_string(s16 x, s16 y, const u8 *str) {
case DIALOG_CHAR_LOWER_A_UMLAUT:
render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('a'), str[strPos] & 0xF);
break;
#ifndef QOL_FIXES
case DIALOG_CHAR_UPPER_A_UMLAUT: // @bug grave and circumflex (0x64-0x65) are absent here
#else
case DIALOG_CHAR_UPPER_A_GRAVE:
case DIALOG_CHAR_UPPER_A_CIRCUMFLEX:
case DIALOG_CHAR_UPPER_A_UMLAUT:
#endif
render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('A'), str[strPos] & 0xF);
break;
case DIALOG_CHAR_LOWER_E_GRAVE:
@ -434,14 +440,25 @@ void print_generic_string(s16 x, s16 y, const u8 *str) {
case DIALOG_CHAR_LOWER_U_UMLAUT:
render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('u'), str[strPos] & 0xF);
break;
#ifndef QOL_FIXES
case DIALOG_CHAR_UPPER_U_UMLAUT: // @bug grave and circumflex (0x84-0x85) are absent here
#else
case DIALOG_CHAR_UPPER_U_GRAVE:
case DIALOG_CHAR_UPPER_U_CIRCUMFLEX:
case DIALOG_CHAR_UPPER_U_UMLAUT:
#endif
render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('U'), str[strPos] & 0xF);
break;
case DIALOG_CHAR_LOWER_O_CIRCUMFLEX:
case DIALOG_CHAR_LOWER_O_UMLAUT:
render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('o'), str[strPos] & 0xF);
break;
#ifndef QOL_FIXES
case DIALOG_CHAR_UPPER_O_UMLAUT: // @bug circumflex (0x95) is absent here
#else
case DIALOG_CHAR_UPPER_O_CIRCUMFLEX:
case DIALOG_CHAR_UPPER_O_UMLAUT:
#endif
render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('O'), str[strPos] & 0xF);
break;
case DIALOG_CHAR_LOWER_I_CIRCUMFLEX:
@ -587,7 +604,7 @@ void print_hud_lut_string(s8 hudLUT, s16 x, s16 y, const u8 *str) {
break;
default:
#endif
#if defined(VERSION_US) || defined(VERSION_SH)
#if defined(VERSION_US) || defined(VERSION_SH) || !defined(QOL_FIXES)
if (str[strPos] == GLOBAL_CHAR_SPACE) {
if (0) //! dead code
{
@ -751,13 +768,22 @@ void handle_menu_scrolling(s8 scrollDirection, s8 *currentIndex, s8 minIndex, s8
}
if (((index ^ gMenuHoldKeyIndex) & index) == 2) {
#ifndef QOL_FIXES
if (currentIndex[0] == maxIndex) {
//! Probably originally a >=, but later replaced with an == and an else statement.
// QOL_FIXES restores the original behavior of this if statement
currentIndex[0] = maxIndex;
} else {
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
currentIndex[0]++;
}
#else
// It makes more sense for this if statement to have > instead of >= here
if (currentIndex[0] > maxIndex) {
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
currentIndex[0]++;
}
#endif
}
if (((index ^ gMenuHoldKeyIndex) & index) == 1) {
@ -806,6 +832,7 @@ s16 get_str_x_pos_from_center_scale(s16 centerPos, u8 *str, f32 scale) {
f32 spacesWidth = 0.0f;
while (str[strPos] != DIALOG_CHAR_TERMINATOR) {
#if !defined(QOL_FIXES) && defined(VERSION_EU)
//! EU checks for dakuten and handakuten despite dialog code unable to handle it
if (str[strPos] == DIALOG_CHAR_SPACE) {
spacesWidth += 1.0;
@ -813,6 +840,7 @@ s16 get_str_x_pos_from_center_scale(s16 centerPos, u8 *str, f32 scale) {
&& str[strPos] != DIALOG_CHAR_PERIOD_OR_HANDAKUTEN) {
charsWidth += 1.0;
}
#endif
strPos++;
}
// return the x position of where the string starts as half the string's
@ -1551,12 +1579,16 @@ void handle_special_dialog_text(s16 dialogID) { // dialog ID tables, in order
// Red Switch, Green Switch, Blue Switch, 100 coins star, Bowser Red Coin Star
s16 dialogStarSound[] = { 10, 11, 12, 13, 14 };
// King Bob-omb (Start), Whomp (Defeated), King Bob-omb (Defeated, missing in JP), Eyerock (Defeated), Wiggler (Defeated)
#ifndef QOL_FIXES
#if BUGFIX_KING_BOB_OMB_FADE_MUSIC
s16 dialogBossStop[] = { 17, 115, 116, 118, 152 };
#else
//! @bug JP misses King Bob-omb defeated dialog "116", meaning that the boss music will still
//! play after King Bob-omb is defeated until BOB loads it's music after the star cutscene
s16 dialogBossStop[] = { 17, 115, 118, 152 };
#endif
#else
s16 dialogBossStop[] = { 17, 115, 116, 118, 152 };
#endif
s16 i;
@ -2780,8 +2812,11 @@ void print_hud_course_complete_coins(s16 x, s16 y) {
if ((gCourseDoneMenuTimer & 1) || gHudDisplay.coins > 70) {
gCourseCompleteCoins++;
play_sound(SOUND_MENU_YOSHI_GAIN_LIVES, gDefaultSoundArgs);
#ifndef QOL_FIXES
if (gCourseCompleteCoins == 50 || gCourseCompleteCoins == 100 || gCourseCompleteCoins == 150) {
#else
if (gCourseCompleteCoins % 50 == 0) {
#endif
play_sound(SOUND_GENERAL_COLLECT_1UP, gDefaultSoundArgs);
gMarioState[0].numLives++;
}
@ -3074,6 +3109,7 @@ s16 render_menus_and_dialogs() {
if (gMenuMode != -1) {
switch (gMenuMode) {
#ifndef QOL_FIXES
case 0:
mode = render_pause_courses_and_castle();
break;
@ -3086,6 +3122,16 @@ s16 render_menus_and_dialogs() {
case 3:
mode = render_course_complete_screen();
break;
#else
case 0:
case 1:
mode = render_pause_courses_and_castle();
break;
case 2:
case 3:
mode = render_course_complete_screen();
break;
#endif
}
gDialogColorFadeTimer = (s16) gDialogColorFadeTimer + 0x1000;

View File

@ -1507,7 +1507,7 @@ u32 interact_pole(struct MarioState *m, UNUSED u32 interactType, struct Object *
//! @bug Using m->forwardVel here is assumed to be 0.0f due to the set from earlier.
// This is fixed in the Shindou version.
#ifdef VERSION_SH
#if defined(VERSION_SH) || defined(QOL_FIXES)
marioObj->oMarioPoleYawVel = (s32)(velConv * 0x100 + 0x1000);
#else
marioObj->oMarioPoleYawVel = (s32)(m->forwardVel * 0x100 + 0x1000);

View File

@ -1,6 +1,8 @@
#include <ultra64.h>
#include <stdbool.h>
#ifdef QOL_FIXES
#include <limits.h>
#endif
#include "sm64.h"
#include "seq_ids.h"
#include "dialog_ids.h"
@ -907,7 +909,7 @@ void update_hud_values(void) {
play_sound(coinSound, gMarioState->marioObj->header.gfx.cameraToObject);
}
}
#ifndef QOL_FIXES
if (gMarioState->numLives > 100) {
gMarioState->numLives = 100;
}
@ -925,7 +927,21 @@ void update_hud_values(void) {
gMarioState->numLives = (s8) 999; //! Wrong variable
}
#endif
#else
if (gMarioState->numLives > ULLONG_MAX) {
gMarioState->numLives = ULLONG_MAX;
}
if (gMarioState->numKeys > ULLONG_MAX) {
gMarioState->numKeys = ULLONG_MAX;
}
if (gMarioState->numCoins > ULLONG_MAX) {
gMarioState->numCoins = ULLONG_MAX;
}
gHudDisplay.coins = gMarioState->numCoins;
#endif
gHudDisplay.stars = gMarioState->numStars;
gHudDisplay.lives = gMarioState->numLives;
gHudDisplay.keys = gMarioState->numKeys;
@ -1069,20 +1085,32 @@ void level_set_transition(s16 length, void (*updateFunction)(s16 *)) {
* Play the transition and then return to normal play mode.
*/
s32 play_mode_change_area(void) {
#ifndef QOL_FIXES
//! This maybe was supposed to be sTransitionTimer == -1? sTransitionUpdate
// is never set to -1.
if (sTransitionUpdate == (void (*)(s16 *)) - 1) {
#else
if (sTransitionUpdate == -1) {
#endif
update_camera(gCurrentArea->camera);
} else if (sTransitionUpdate != NULL) {
sTransitionUpdate(&sTransitionTimer);
}
#ifndef QOL_FIXES
if (sTransitionTimer > 0) {
#else
if (sTransitionTimer >= 0) {
#endif
sTransitionTimer -= 1;
}
#ifndef QOL_FIXES
//! If sTransitionTimer is -1, this will miss.
if (sTransitionTimer == 0) {
#else
if (sTransitionTimer <= 0) {
#endif
sTransitionUpdate = NULL;
set_play_mode(PLAY_MODE_NORMAL);
}
@ -1098,8 +1126,12 @@ s32 play_mode_change_level(void) {
sTransitionUpdate(&sTransitionTimer);
}
#ifndef QOL_FIXES
//! If sTransitionTimer is -1, this will miss.
if (--sTransitionTimer == -1) {
#else
if (sTransitionTimer <= -1) {
#endif
gHudDisplay.flags = HUD_DISPLAY_NONE;
sTransitionTimer = 0;
sTransitionUpdate = NULL;

View File

@ -109,13 +109,14 @@ void unknown_main_func(void) {
osSetTime(time);
osMapTLB(0, b, NULL, 0, 0, 0);
osUnmapTLBAll();
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnonnull"
#ifndef QOL_FIXES
sprintf(NULL, NULL);
#pragma GCC diagnostic pop
#else
sprintf("", "");
#endif
}
#ifndef QOL_FIXES
void stub_main_1(void) {
}
@ -124,6 +125,7 @@ void stub_main_2(void) {
void stub_main_3(void) {
}
#endif
void setup_mesg_queues(void) {
osCreateMesgQueue(&gDmaMesgQueue, gDmaMesgBuf, ARRAY_COUNT(gDmaMesgBuf));

View File

@ -68,18 +68,13 @@ s32 check_fall_damage(struct MarioState *m, u32 hardFallAction) {
fallHeight = m->peakHeight - m->pos[1];
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
//! Never true
//! Only true when QOL_FIXES is set to 1
if (m->actionState == ACT_GROUND_POUND) {
damageHeight = 600.0f;
} else {
damageHeight = 1150.0f;
}
#pragma GCC diagnostic pop
if (m->action != ACT_TWIRLING && m->floor->type != SURFACE_BURNING) {
if (m->vel[1] < -55.0f) {
if (fallHeight > 3000.0f) {
@ -160,7 +155,11 @@ s32 check_horizontal_wind(struct MarioState *m) {
if (speed > 48.0f) {
m->slideVelX = m->slideVelX * 48.0f / speed;
m->slideVelZ = m->slideVelZ * 48.0f / speed;
#ifndef QOL_FIXES
speed = 32.0f; //! This was meant to be 48?
#else
speed = 48.0f;
#endif
} else if (speed > 32.0f) {
speed = 32.0f;
}

View File

@ -1120,15 +1120,31 @@ s32 act_exit_land_save_dialog(struct MarioState *m) {
case -1:
spawn_obj_at_mario_rel_yaw(m, MODEL_BOWSER_KEY_CUTSCENE, bhvBowserKeyCourseExit, -32768);
//! fall through
// fixed with QOL_FIXES
#ifdef QOL_FIXES
break;
#endif
case 67:
play_sound(SOUND_ACTION_KEY_SWISH, m->marioObj->header.gfx.cameraToObject);
//! fall through
// fixed with QOL_FIXES
#ifdef QOL_FIXES
break;
#endif
case 83:
play_sound(SOUND_ACTION_PAT_BACK, m->marioObj->header.gfx.cameraToObject);
//! fall through
// fixed with QOL_FIXES
#ifdef QOL_FIXES
break;
#endif
case 111:
play_sound(SOUND_ACTION_UNKNOWN45C, m->marioObj->header.gfx.cameraToObject);
// no break
// fixed with QOL_FIXES
#ifdef QOL_FIXES
break;
#endif
}
handle_save_menu(m);
break;
@ -1965,10 +1981,16 @@ void generate_yellow_sparkles(s16 x, s16 y, s16 z, f32 radius) {
spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_NONE, bhvSparkleSpawn, x + offsetX, y + offsetY,
z + offsetZ, 0, 0, 0);
#ifndef QOL_FIXES
//! copy paste error
offsetX = offsetX * 4 / 3;
offsetX = offsetY * 4 / 3;
offsetX = offsetZ * 4 / 3;
#else
offsetX = offsetX * 4 / 3;
offsetY = offsetY * 4 / 3;
offsetZ = offsetZ * 4 / 3;
#endif
spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_NONE, bhvSparkleSpawn, x - offsetX, y - offsetY,
z - offsetZ, 0, 0, 0);

View File

@ -383,10 +383,18 @@ void update_shell_speed(struct MarioState *m) {
m->forwardVel -= 1.0f;
}
#ifndef QOL_FIXES
//! No backward speed cap (shell hyperspeed)
if (m->forwardVel > 64.0f) {
m->forwardVel = 64.0f;
}
#else
if (m->forwardVel > 64.0f) {
m->forwardVel = 64.0f;
} else if (m->forwardVel < -64.0f) {
m->forwardVel = -64.0f;
}
#endif
m->faceAngle[1] =
m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800);
@ -1298,6 +1306,10 @@ s32 act_crawling(struct MarioState *m) {
mario_set_forward_vel(m, 10.0f);
}
//! Possibly unintended missing break
// fixed in QOL_FIXES
#ifdef QOL_FIXES
break;
#endif
case GROUND_STEP_NONE:
align_with_floor(m);

View File

@ -57,6 +57,10 @@ int detect_object_hitbox_overlap(struct Object *a, struct Object *b) {
}
//! no return value
// fixed in QOL_FIXES
#ifdef QOL_FIXES
return 0;
#endif
}
int detect_object_hurtbox_overlap(struct Object *a, struct Object *b) {
@ -89,6 +93,10 @@ int detect_object_hurtbox_overlap(struct Object *a, struct Object *b) {
}
//! no return value
// fixed in QOL_FIXES
#ifdef QOL_FIXES
return 0;
#endif
}
void clear_object_collision(struct Object *a) {

View File

@ -460,7 +460,7 @@ void spawn_objects_from_info(UNUSED s32 unused, struct SpawnInfo *spawnInfo) {
//! (Spawning Displacement) On the Japanese version, Mario's platform object
// isn't cleared when transitioning between areas. This can cause Mario to
// receive displacement after spawning.
#ifndef VERSION_JP
#if !defined(VERSION_JP) || !defined(QOL_FIXES)
clear_mario_platform();
#endif
@ -562,8 +562,12 @@ void clear_objects(void) {
*/
void update_terrain_objects(void) {
gObjectCounter = update_objects_in_list(&gObjectLists[OBJ_LIST_SPAWNER]);
#ifndef QOL_FIXES
//! This was meant to be +=
gObjectCounter = update_objects_in_list(&gObjectLists[OBJ_LIST_SURFACE]);
#else
gObjectCounter += update_objects_in_list(&gObjectLists[OBJ_LIST_SURFACE]);
#endif
}
/**

View File

@ -578,7 +578,16 @@ void painting_update_ripple_state(struct Painting *painting) {
//! 16777216 (1 << 24), at which point it will freeze (due to floating-point
//! imprecision?) and the painting will stop rippling. This happens to HMC, DDD, and
//! CotMC. This happens on Wii VC. Untested on N64 and Wii U VC.
// Work around this in QOL_FIXES by wrapping the timer value itself (this value)
// around to 0 and back again whenever it hits 16777216 (1 << 24).
#ifndef QOL_FIXES
painting->rippleTimer += 1.0;
#else
if (painting->rippleTimer >= 16777216.0) {
painting->rippleTimer = 0.0;
} else {
painting->rippleTimer += 1.0;
}
}
if (painting->rippleTrigger == RIPPLE_TRIGGER_PROXIMITY) {
// if the painting is barely rippling, make it stop rippling

View File

@ -79,12 +79,22 @@ void draw_profiler_bar(OSTime clockBase, OSTime clockStart, OSTime clockEnd, s16
//! I believe this is supposed to cap rectX1 and rectX2 to 320, but the
// code seems to use the wrong variables... it's possible that the variable
// names were very similar within a single letter.
// We work based off this hunch in QOL_FIXES
#ifndef QOL_FIXES
if (rectX1 > 319) {
clockStart = 319;
}
if (rectX2 > 319) {
clockEnd = 319;
}
#else
if (rectX1 > 320) {
clockStart = 320;
}
if (rectX2 > 320) {
clockEnd = 320;
}
#endif
// perform the render if start is less than end. in most cases, it should be.
if (rectX1 < rectX2) {

View File

@ -760,8 +760,14 @@ static int obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) {
hScreenEdge *= GFX_DIMENSIONS_ASPECT_RATIO;
if (geo != NULL && geo->type == GRAPH_NODE_TYPE_CULLING_RADIUS) {
// I don't get it either, so removing the cast for QOL_FIXES
#ifndef QOL_FIXES
cullingRadius =
(f32)((struct GraphNodeCullingRadius *) geo)->cullingRadius; //! Why is there a f32 cast?
#else
cullingRadius =
((struct GraphNodeCullingRadius *) geo)->cullingRadius;
#endif
} else {
cullingRadius = 300;
}

View File

@ -488,10 +488,18 @@ void save_file_collect_star_or_key(s16 coinScore, s16 starIndex) {
if (courseIndex >= 0 && courseIndex < COURSE_STAGES_COUNT) {
//! Compares the coin score as a 16 bit value, but only writes the 8 bit
// truncation. This can allow a high score to decrease.
// Because the coin score value was increased to a u64 in QOL_FIXES, we
// must fix this a different way than we would otherwise
#ifndef QOL_FIXES
if (coinScore > ((u16) save_file_get_max_coin_score(courseIndex) & 0xFFFF)) {
sUnusedGotGlobalCoinHiScore = 1;
}
#else
if (coinScore > ((u64) save_file_get_max_coin_score(courseIndex) & 0xFFFFFFFFFFFFFFFFL)) {
sUnusedGotGlobalCoinHiScore = 1;
}
#endif
if (coinScore > save_file_get_course_coin_score(fileIndex, courseIndex)) {
gSaveBuffer.files[fileIndex][0].courseCoinScores[courseIndex] = coinScore;

View File

@ -190,6 +190,9 @@ f32 get_water_level_below_shadow(struct Shadow *s) {
}
//! @bug Missing return statement. This compiles to return `waterLevel`
//! incidentally.
#ifdef QOL_FIXES
return waterLevel;
#endif
}
/**
@ -211,11 +214,18 @@ s8 init_shadow(struct Shadow *s, f32 xPos, f32 yPos, f32 zPos, s16 shadowScale,
s->floorHeight = find_floor_height_and_data(s->parentX, s->parentY, s->parentZ, &floorGeometry);
// This can lead to waterLevel being undefined if gEnvironmentRegions is 0 or less,
// so this fix will be made for QOL_FIXES to compensate for this
#ifndef QOL_FIXES
if (gEnvironmentRegions != 0) {
waterLevel = get_water_level_below_shadow(s);
}
#else
waterLevel = get_water_level_below_shasow(s);
#endif
if (gShadowAboveWaterOrLava) {
//! @bug Use of potentially undefined variable `waterLevel`
// fixed when using QOL_FIXES
s->floorHeight = waterLevel;
// Assume that the water is flat.

View File

@ -139,7 +139,12 @@ f32 calculate_skybox_scaled_x(s8 player, f32 fov) {
f32 yaw = sSkyBoxInfo[player].yaw;
//! double literals are used instead of floats
// fixed in QOL_FIXES
#ifndef QOL_FIXES
f32 scaledX = SCREEN_WIDTH * 360.0 * yaw / (fov * 65536.0);
#else
f32 scaledX = SCREEN_WIDTH * 360.0f * yaw / (fov * 65536.0f);
#endif
if (scaledX > SKYBOX_WIDTH) {
scaledX -= (s32) scaledX / SKYBOX_WIDTH * SKYBOX_WIDTH;

View File

@ -664,6 +664,7 @@ struct GdObj *d_makeobj(enum DObjTypes type, DynId id) {
//! @bug When making a `D_LABEL`, the call to `make_label()`
//! compiles incorrectly due to Goddard only declaring
//! the functions, not prototyping the functions
// Fix is planned for QOL_FIXES
dobj = &make_label(NULL, NULL, 8, 0, 0, 0)->header;
break;
case D_VIEW:
@ -1023,6 +1024,7 @@ void chk_shapegen(struct ObjShape *shape) {
//! @bug Call to `make_face_with_colour()` compiles incorrectly
//! due to Goddard only declaring the functions,
//! not prototyping the functions
// Fix is planned for QOL_FIXES
face = make_face_with_colour(1.0, 1.0, 1.0);
face->mtlId = (s32) facedata->data[i][0];
add_3_vtx_to_face(face, vtxbuf[facedata->data[i][1]], vtxbuf[facedata->data[i][2]],
@ -2952,7 +2954,10 @@ void d_set_matrix(Mat4f *src) {
gd_copy_mat4f(src, &((struct ObjNet *) sDynListCurObj)->mat128);
//! @bug When setting an `ObjNet` matrix, the source is copied twice
//! due to a probable copy-paste line repeat error
// Fixed in QOL_FIXES
#ifndef QOL_FIXES
gd_copy_mat4f(src, &((struct ObjNet *) sDynListCurObj)->mat128);
#endif
break;
case OBJ_TYPE_JOINTS:
gd_copy_mat4f(src, &((struct ObjJoint *) sDynListCurObj)->matE8);

View File

@ -12,10 +12,7 @@
// forwarded to the other, but it is hard to tell in which direction.
#ifdef __GNUC__
#define printf(...) \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wunused-value\"") \
(__VA_ARGS__); \
_Pragma ("GCC diagnostic pop")
(__VA_ARGS__);
#else
#define printf
#endif

View File

@ -492,7 +492,7 @@ ALIGNED8 static u8 gd_texture_sparkle_4[] = {
//! No reference to this texture. Two DL's uses the same previous texture
// instead of using this texture.
// Fixed via setting TEXTURE_FIX to 1.
// Fixed via setting QOL_FIXES to 1.
ALIGNED8 static u8 gd_texture_sparkle_5[] = {
#include "textures/intro_raw/sparkle_5.rgba16.inc.c"
};
@ -569,7 +569,7 @@ static Gfx gd_dl_red_sparkle_4[] = {
gsSPBranchList(gd_dl_sparkle),
};
#ifndef TEXTURE_FIX
#ifndef QOL_FIXES
static Gfx gd_dl_red_sparkle_4_dup[] ={
gsDPPipeSync(),
gsSPDisplayList(gd_dl_sparkle_red_color),
@ -621,7 +621,7 @@ static Gfx gd_dl_silver_sparkle_4[] = {
gsSPBranchList(gd_dl_sparkle),
};
#ifndef TEXTURE_FIX
#ifndef QOL_FIXES
static Gfx gd_dl_silver_sparkle_4_dup[] = {
gsDPPipeSync(),
gsSPDisplayList(gd_dl_sparkle_white_color),
@ -649,7 +649,7 @@ static Gfx *gd_red_sparkle_dl_array[] = {
gd_dl_red_sparkle_1,
gd_dl_red_sparkle_0,
gd_dl_red_sparkle_0,
#ifndef TEXTURE_FIX
#ifndef QOL_FIXES
gd_dl_red_sparkle_4_dup,
gd_dl_red_sparkle_4_dup,
#else
@ -669,7 +669,7 @@ static Gfx *gd_silver_sparkle_dl_array[] = {
gd_dl_silver_sparkle_1,
gd_dl_silver_sparkle_0,
gd_dl_silver_sparkle_0,
#ifndef TEXTURE_FIX
#ifndef QOL_FIXES
gd_dl_silver_sparkle_4_dup,
gd_dl_silver_sparkle_4_dup,
#else
@ -931,7 +931,10 @@ void gd_printf(const char *format, ...) {
csr++;
*csr = '\0';
break;
// two breaks here? Why? QOL_FIXES removes this one
#ifndef QOL_FIXES
break; // needed to match
#endif
case 'f':
val.f = (f32) va_arg(args, double);
csr = sprint_val_withspecifiers(csr, val, spec);
@ -941,7 +944,12 @@ void gd_printf(const char *format, ...) {
break;
case 'c':
//! @bug formatter 'c' uses `s32` for va_arg instead of `char`
// Fixed in QOL_FIXES
#ifndef QOL_FIXES
*csr = va_arg(args, s32);
#else
*csr = va_arg(args, char);
#endif
csr++;
*csr = '\0';
break;
@ -1323,8 +1331,11 @@ void *gdm_gettestdl(s32 id) {
fatal_printf("gdm_gettestdl(): DL number %d undefined", id);
}
//! @bug Code treats `sYoshiSceneView` as group; not called in game though
// Potential fix in QOL_FIXES
#ifndef QOL_FIXES
apply_to_obj_types_in_group(OBJ_TYPE_VIEWS, (applyproc_t) update_view,
(struct ObjGroup *) sYoshiSceneView);
#endif
dobj = d_use_obj("yoshi_scene");
gddl = sGdDLArray[((struct ObjView *) dobj)->gdDlNum];
sUpdateYoshiScene = TRUE;
@ -1354,8 +1365,11 @@ void *gdm_gettestdl(s32 id) {
fatal_printf("gdm_gettestdl(): DL number %d undefined", id);
}
//! @bug Code treats `sCarSceneView` as group; not called in game though
// Potential fix in QOL_FIXES
#ifndef QOL_FIXES
apply_to_obj_types_in_group(OBJ_TYPE_VIEWS, (applyproc_t) update_view,
(struct ObjGroup *) sCarSceneView);
#endif
dobj = d_use_obj("car_scene");
gddl = sGdDLArray[((struct ObjView *) dobj)->gdDlNum];
sUpdateCarScene = TRUE;
@ -2781,6 +2795,10 @@ void func_801A43DC(UNUSED struct GdObj *obj) {
/* 252BC0 -> 252BE0 */
void *func_801A43F0(UNUSED const char *menufmt, ...) {
//! @bug no return; function was stubbed
// Add a return here for QOL_FIXES
#ifdef QOL_FIXES
return 0;
#endif
}
/* 252BE0 -> 252BF0 */

View File

@ -141,9 +141,12 @@ void bhv_act_selector_init(void) {
//! Useless, since sInitSelectedActNum has already been set in this
//! scenario by the code that shows the next uncollected star.
// Because of this, let that code do the work in QOL_FIXES instead
#ifndef QOL_FIXES
if (sObtainedStars == 0) {
sInitSelectedActNum = 1;
}
#endif
// Render star selector objects
for (i = 0; i < sVisibleStars; i++) {