mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-28 23:13:02 +00:00
custom level fixes and fixes from other pr (#483)
clean up custom level code fixed a bug where custom level course numbers weren't used by dynos warps removed a bunch of unused dynos code fix demos triggering incorrectly allowed the right Ctrl key to be used when opening the in game console fixed a softlock that was possible to experience when talking to the snowman in CCM fixed the bug where you can permanently lose your cap (bug created by my own PR from beta 32) fix the moderator feature I made a while back; I am amazed it even worked at all before fixed dynos warp initial actions being skipped (read ec8aabc for explanation) completely changed the way star names and course names work
This commit is contained in:
parent
2df5456793
commit
c9e4efdb31
68 changed files with 1262 additions and 2866 deletions
|
@ -166,7 +166,7 @@ def process_define(filename, line):
|
||||||
continue
|
continue
|
||||||
p = re.sub(r'0x[a-fA-F0-9]+', '', p)
|
p = re.sub(r'0x[a-fA-F0-9]+', '', p)
|
||||||
if re.search('[a-z]', p) != None and 'VERSION_TEXT' not in line:
|
if re.search('[a-z]', p) != None and 'VERSION_TEXT' not in line:
|
||||||
if 'gCurrentObject' not in line:
|
if 'gCurrentObject' not in line and 'gNetworkType' not in line:
|
||||||
print('UNRECOGNIZED DEFINE: ' + line)
|
print('UNRECOGNIZED DEFINE: ' + line)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -102,12 +102,14 @@ override_disallowed_functions = {
|
||||||
"src/game/obj_behaviors.c": [ "debug_" ],
|
"src/game/obj_behaviors.c": [ "debug_" ],
|
||||||
"src/game/obj_behaviors_2.c": [ "wiggler_jumped_on_attack_handler", "huge_goomba_weakly_attacked" ],
|
"src/game/obj_behaviors_2.c": [ "wiggler_jumped_on_attack_handler", "huge_goomba_weakly_attacked" ],
|
||||||
"src/game/spawn_sound.c": [ "spawner" ],
|
"src/game/spawn_sound.c": [ "spawner" ],
|
||||||
|
"src/game/level_info.h": [ "_name_table" ],
|
||||||
"src/pc/lua/utils/smlua_obj_utils.h": [ "spawn_object_remember_field", "set_exclamation_box_new_contents", "get_exclamation_box_new_contents_pointer", "get_exclamation_box_new_contents_size" ],
|
"src/pc/lua/utils/smlua_obj_utils.h": [ "spawn_object_remember_field", "set_exclamation_box_new_contents", "get_exclamation_box_new_contents_pointer", "get_exclamation_box_new_contents_size" ],
|
||||||
"src/game/camera.h": [ "update_camera", "init_camera", "stub_camera", "^reset_camera", "move_point_along_spline" ],
|
"src/game/camera.h": [ "update_camera", "init_camera", "stub_camera", "^reset_camera", "move_point_along_spline" ],
|
||||||
"src/game/behavior_actions.h": [ "bhv_dust_smoke_loop", "bhv_init_room" ],
|
"src/game/behavior_actions.h": [ "bhv_dust_smoke_loop", "bhv_init_room" ],
|
||||||
"src/pc/lua/utils/smlua_audio_utils.h": [ "smlua_audio_utils_override", "audio_custom_shutdown"],
|
"src/pc/lua/utils/smlua_audio_utils.h": [ "smlua_audio_utils_override", "audio_custom_shutdown"],
|
||||||
"src/pc/djui/djui_hud_utils.h": [ "djui_hud_render_texture", "djui_hud_render_texture_raw", "djui_hud_render_texture_tile", "djui_hud_render_texture_tile_raw" ],
|
"src/pc/djui/djui_hud_utils.h": [ "djui_hud_render_texture", "djui_hud_render_texture_raw", "djui_hud_render_texture_tile", "djui_hud_render_texture_tile_raw" ],
|
||||||
"src/pc/lua/utils/smlua_level_utils.h": [ "smlua_level_util_reset" ],
|
"src/pc/lua/utils/smlua_level_utils.h": [ "smlua_level_util_reset" ],
|
||||||
|
"src/pc/lua/utils/smlua_text_utils.h": [ "smlua_text_utils_reset_all" ],
|
||||||
"src/pc/lua/utils/smlua_anim_utils.h": [ "smlua_anim_util_reset", "smlua_anim_util_register_animation" ],
|
"src/pc/lua/utils/smlua_anim_utils.h": [ "smlua_anim_util_reset", "smlua_anim_util_register_animation" ],
|
||||||
"src/pc/network/lag_compensation.h": [ "lag_compensation_clear", "lag_compensation_store" ]
|
"src/pc/network/lag_compensation.h": [ "lag_compensation_clear", "lag_compensation_store" ]
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ override_field_mutable = {
|
||||||
override_field_invisible = {
|
override_field_invisible = {
|
||||||
"Mod": [ "files" ],
|
"Mod": [ "files" ],
|
||||||
"MarioState": [ "visibleToEnemies" ],
|
"MarioState": [ "visibleToEnemies" ],
|
||||||
"NetworkPlayer": [ "gag"],
|
"NetworkPlayer": [ "gag", "moderator"],
|
||||||
"GraphNode": [ "_guard1", "_guard2" ],
|
"GraphNode": [ "_guard1", "_guard2" ],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8190,6 +8190,22 @@ function smlua_audio_utils_reset_all()
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param x number
|
||||||
|
--- @param y number
|
||||||
|
--- @param z number
|
||||||
|
--- @return Surface
|
||||||
|
function collision_find_ceil(x, y, z)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param x number
|
||||||
|
--- @param y number
|
||||||
|
--- @param z number
|
||||||
|
--- @return Surface
|
||||||
|
function collision_find_floor(x, y, z)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param startX number
|
--- @param startX number
|
||||||
--- @param startY number
|
--- @param startY number
|
||||||
--- @param startZ number
|
--- @param startZ number
|
||||||
|
@ -8254,6 +8270,12 @@ function smlua_level_util_get_info(levelNum)
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param courseNum integer
|
||||||
|
--- @return CustomLevelInfo
|
||||||
|
function smlua_level_util_get_info_from_course_num(courseNum)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param shortName string
|
--- @param shortName string
|
||||||
--- @return CustomLevelInfo
|
--- @return CustomLevelInfo
|
||||||
function smlua_level_util_get_info_from_short_name(shortName)
|
function smlua_level_util_get_info_from_short_name(shortName)
|
||||||
|
@ -9096,6 +9118,35 @@ function spawn_sync_object(behaviorId, modelId, x, y, z, objSetupFunction)
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param courseNum integer
|
||||||
|
--- @param actNum integer
|
||||||
|
--- @return string
|
||||||
|
function smlua_text_utils_act_name_get(courseNum, actNum)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param courseNum integer
|
||||||
|
--- @param actNum integer
|
||||||
|
--- @return boolean
|
||||||
|
function smlua_text_utils_act_name_is_modified(courseNum, actNum)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param courseNum integer
|
||||||
|
--- @param actNum integer
|
||||||
|
--- @param name string
|
||||||
|
--- @return nil
|
||||||
|
function smlua_text_utils_act_name_replace(courseNum, actNum, name)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param courseNum integer
|
||||||
|
--- @param actNum integer
|
||||||
|
--- @return nil
|
||||||
|
function smlua_text_utils_act_name_reset(courseNum, actNum)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param name string
|
--- @param name string
|
||||||
--- @return nil
|
--- @return nil
|
||||||
function smlua_text_utils_castle_secret_stars_replace(name)
|
function smlua_text_utils_castle_secret_stars_replace(name)
|
||||||
|
@ -9115,6 +9166,31 @@ function smlua_text_utils_course_acts_replace(courseNum, courseName, act1, act2,
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param courseNum integer
|
||||||
|
--- @return string
|
||||||
|
function smlua_text_utils_course_name_get(courseNum)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param courseNum integer
|
||||||
|
--- @return integer
|
||||||
|
function smlua_text_utils_course_name_mod_index(courseNum)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param courseNum integer
|
||||||
|
--- @param name string
|
||||||
|
--- @return nil
|
||||||
|
function smlua_text_utils_course_name_replace(courseNum, name)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param courseNum integer
|
||||||
|
--- @return nil
|
||||||
|
function smlua_text_utils_course_name_reset(courseNum)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param dialogId DialogId
|
--- @param dialogId DialogId
|
||||||
--- @param unused integer
|
--- @param unused integer
|
||||||
--- @param linesPerBox integer
|
--- @param linesPerBox integer
|
||||||
|
@ -9138,11 +9214,6 @@ function smlua_text_utils_get_language()
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @return nil
|
|
||||||
function smlua_text_utils_reset_all()
|
|
||||||
-- ...
|
|
||||||
end
|
|
||||||
|
|
||||||
--- @param courseNum integer
|
--- @param courseNum integer
|
||||||
--- @param courseName string
|
--- @param courseName string
|
||||||
--- @return nil
|
--- @return nil
|
||||||
|
|
|
@ -12,7 +12,6 @@ void *dynos_swap_cmd(void *cmd);
|
||||||
// -- built in -- //
|
// -- built in -- //
|
||||||
void *dynos_update_cmd(void *cmd);
|
void *dynos_update_cmd(void *cmd);
|
||||||
void dynos_update_gfx();
|
void dynos_update_gfx();
|
||||||
void dynos_update_opt(void *pad);
|
|
||||||
s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize);
|
s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize);
|
||||||
void dynos_gfx_swap_animations(void *ptr);
|
void dynos_gfx_swap_animations(void *ptr);
|
||||||
|
|
||||||
|
@ -59,7 +58,7 @@ const char* dynos_level_get_token(u32 index);
|
||||||
Trajectory* dynos_level_get_trajectory(const char* name);
|
Trajectory* dynos_level_get_trajectory(const char* name);
|
||||||
void dynos_level_load_background(void *ptr);
|
void dynos_level_load_background(void *ptr);
|
||||||
u64 dynos_level_cmd_get(void *cmd, u64 offset);
|
u64 dynos_level_cmd_get(void *cmd, u64 offset);
|
||||||
void dynos_level_cmd_next(void *cmd, u64 cmdsize);
|
void dynos_level_cmd_next(void *cmd);
|
||||||
void dynos_level_parse_script(const void *script, s32 (*aPreprocessFunction)(u8, void *));
|
void dynos_level_parse_script(const void *script, s32 (*aPreprocessFunction)(u8, void *));
|
||||||
void* dynos_level_get_script(s32 level);
|
void* dynos_level_get_script(s32 level);
|
||||||
s32 dynos_level_get_mod_index(s32 level);
|
s32 dynos_level_get_mod_index(s32 level);
|
||||||
|
|
|
@ -656,6 +656,11 @@ struct BuiltinTexInfo {
|
||||||
s32 bitSize;
|
s32 bitSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LvlCmd {
|
||||||
|
u8 mType;
|
||||||
|
u8 mSize;
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Utils
|
// Utils
|
||||||
//
|
//
|
||||||
|
@ -783,23 +788,6 @@ void DynOS_Mod_Update();
|
||||||
void DynOS_Mod_Shutdown();
|
void DynOS_Mod_Shutdown();
|
||||||
void DynOS_ReturnToMainMenu();
|
void DynOS_ReturnToMainMenu();
|
||||||
|
|
||||||
//
|
|
||||||
// Opt
|
|
||||||
//
|
|
||||||
|
|
||||||
s32 DynOS_Opt_GetValue(const String &aName);
|
|
||||||
void DynOS_Opt_SetValue(const String &aName, s32 aValue);
|
|
||||||
void DynOS_Opt_AddAction(const String &aFuncName, bool (*aFuncPtr)(const char *), bool aOverwrite);
|
|
||||||
void DynOS_Opt_Init();
|
|
||||||
void DynOS_Opt_InitVanilla(DynosOption *&aOptionsMenu);
|
|
||||||
void DynOS_Opt_Update(OSContPad *aPad);
|
|
||||||
bool DynOS_Opt_ControllerUpdate(DynosOption *aOpt, void *aData);
|
|
||||||
s32 DynOS_Opt_ControllerGetKeyPressed();
|
|
||||||
void DynOS_Opt_LoadConfig(DynosOption *aMenu);
|
|
||||||
void DynOS_Opt_SaveConfig(DynosOption *aMenu);
|
|
||||||
void DynOS_Opt_DrawMenu(DynosOption *aCurrentOption, DynosOption *aCurrentMenu, DynosOption *aOptionsMenu, DynosOption *aDynosMenu);
|
|
||||||
void DynOS_Opt_DrawPrompt(DynosOption *aCurrentMenu, DynosOption *aOptionsMenu, DynosOption *aDynosMenu);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Gfx
|
// Gfx
|
||||||
//
|
//
|
||||||
|
@ -826,22 +814,18 @@ s32 DynOS_String_Width(const u8 *aStr64);
|
||||||
// Levels
|
// Levels
|
||||||
//
|
//
|
||||||
|
|
||||||
s32 DynOS_Level_GetCount();
|
void DynOS_Level_Init();
|
||||||
const s32 *DynOS_Level_GetList();
|
s8 DynOS_Level_GetCourse(s32 aLevel);
|
||||||
s32 DynOS_Level_GetCourse(s32 aLevel);
|
|
||||||
void DynOS_Level_Override(void* originalScript, void* newScript, s32 modIndex);
|
void DynOS_Level_Override(void* originalScript, void* newScript, s32 modIndex);
|
||||||
void DynOS_Level_Unoverride();
|
void DynOS_Level_Unoverride();
|
||||||
const void *DynOS_Level_GetScript(s32 aLevel);
|
const void *DynOS_Level_GetScript(s32 aLevel);
|
||||||
s32 DynOS_Level_GetModIndex(s32 aLevel);
|
s32 DynOS_Level_GetModIndex(s32 aLevel);
|
||||||
bool DynOS_Level_IsVanillaLevel(s32 aLevel);
|
bool DynOS_Level_IsVanillaLevel(s32 aLevel);
|
||||||
const u8 *DynOS_Level_GetName(s32 aLevel, bool aDecaps, bool aAddCourseNumber);
|
|
||||||
const u8 *DynOS_Level_GetActName(s32 aLevel, s32 aAct, bool aDecaps, bool aAddStarNumber);
|
|
||||||
const u8 *DynOS_Level_GetAreaName(s32 aLevel, s32 aArea, bool aDecaps);
|
|
||||||
s16 *DynOS_Level_GetWarp(s32 aLevel, s32 aArea, u8 aWarpId);
|
s16 *DynOS_Level_GetWarp(s32 aLevel, s32 aArea, u8 aWarpId);
|
||||||
s16 *DynOS_Level_GetWarpEntry(s32 aLevel, s32 aArea);
|
s16 *DynOS_Level_GetWarpEntry(s32 aLevel, s32 aArea);
|
||||||
s16 *DynOS_Level_GetWarpDeath(s32 aLevel, s32 aArea);
|
s16 *DynOS_Level_GetWarpDeath(s32 aLevel, s32 aArea);
|
||||||
u64 DynOS_Level_CmdGet(void *aCmd, u64 aOffset);
|
u64 DynOS_Level_CmdGet(void *aCmd, u64 aOffset);
|
||||||
void *DynOS_Level_CmdNext(void *aCmd, u64 aCmdSize);
|
LvlCmd *DynOS_Level_CmdNext(LvlCmd *aCmd);
|
||||||
void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8, void *));
|
void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8, void *));
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -854,8 +838,6 @@ bool DynOS_Warp_ToLevel(s32 aLevel, s32 aArea, s32 aAct);
|
||||||
bool DynOS_Warp_RestartLevel();
|
bool DynOS_Warp_RestartLevel();
|
||||||
bool DynOS_Warp_ExitLevel(s32 aDelay);
|
bool DynOS_Warp_ExitLevel(s32 aDelay);
|
||||||
bool DynOS_Warp_ToCastle(s32 aLevel);
|
bool DynOS_Warp_ToCastle(s32 aLevel);
|
||||||
void DynOS_Warp_SetParam(s32 aLevel, s32 aIndex);
|
|
||||||
const char *DynOS_Warp_GetParamName(s32 aLevel, s32 aIndex);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Builtin
|
// Builtin
|
||||||
|
@ -988,7 +970,6 @@ u32 DynOS_Model_GetIdFromAsset(void* asset);
|
||||||
u32 DynOS_Model_GetIdFromGraphNode(struct GraphNode* aNode);
|
u32 DynOS_Model_GetIdFromGraphNode(struct GraphNode* aNode);
|
||||||
void DynOS_Model_OverwriteSlot(u32 srcSlot, u32 dstSlot);
|
void DynOS_Model_OverwriteSlot(u32 srcSlot, u32 dstSlot);
|
||||||
void DynOS_Model_ClearPool(enum ModelPool aModelPool);
|
void DynOS_Model_ClearPool(enum ModelPool aModelPool);
|
||||||
void DynOS_Model_Update();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bin
|
// Bin
|
||||||
|
|
|
@ -14,14 +14,9 @@ void *dynos_update_cmd(void *cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void dynos_update_gfx() {
|
void dynos_update_gfx() {
|
||||||
DynOS_Model_Update();
|
|
||||||
return DynOS_UpdateGfx();
|
return DynOS_UpdateGfx();
|
||||||
}
|
}
|
||||||
|
|
||||||
void dynos_update_opt(void *pad) {
|
|
||||||
return DynOS_UpdateOpt(pad);
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize) {
|
s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize) {
|
||||||
return DynOS_Tex_Import(output, ptr, tile, grapi, hashmap, pool, (u32 *) poolpos, (u32) poolsize);
|
return DynOS_Tex_Import(output, ptr, tile, grapi, hashmap, pool, (u32 *) poolpos, (u32) poolsize);
|
||||||
}
|
}
|
||||||
|
@ -185,8 +180,8 @@ u64 dynos_level_cmd_get(void *cmd, u64 offset) {
|
||||||
return DynOS_Level_CmdGet(cmd, offset);
|
return DynOS_Level_CmdGet(cmd, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dynos_level_cmd_next(void *cmd, u64 cmdsize) {
|
void dynos_level_cmd_next(void *cmd) {
|
||||||
DynOS_Level_CmdNext(cmd, cmdsize);
|
DynOS_Level_CmdNext((LvlCmd*) cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dynos_level_parse_script(const void *script, s32 (*aPreprocessFunction)(u8, void *)) {
|
void dynos_level_parse_script(const void *script, s32 (*aPreprocessFunction)(u8, void *)) {
|
||||||
|
|
|
@ -5,10 +5,6 @@ extern "C" {
|
||||||
#include "levels/scripts.h"
|
#include "levels/scripts.h"
|
||||||
#include "pc/lua/utils/smlua_level_utils.h"
|
#include "pc/lua/utils/smlua_level_utils.h"
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
|
||||||
#include "eu_translation.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -20,20 +16,6 @@ extern const BehaviorScript *sWarpBhvSpawnTable[];
|
||||||
#include "engine/level_script.h"
|
#include "engine/level_script.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DYNOS_LEVEL_TEXT_EMPTY ""
|
|
||||||
#define DYNOS_LEVEL_TEXT_CASTLE "CASTLE"
|
|
||||||
#define DYNOS_LEVEL_TEXT_BOWSER_1 "BOWSER 1"
|
|
||||||
#define DYNOS_LEVEL_TEXT_BOWSER_2 "BOWSER 2"
|
|
||||||
#define DYNOS_LEVEL_TEXT_BOWSER_3 "BOWSER 3"
|
|
||||||
#define DYNOS_LEVEL_TEXT_100_COINS_STAR "100 COINS STAR"
|
|
||||||
#define DYNOS_LEVEL_TEXT_RED_COINS_STAR "RED COINS STAR"
|
|
||||||
#define DYNOS_LEVEL_TEXT_ONE_SECRET_STAR "ONE OF THE CASTLE'S SECRET STARS!"
|
|
||||||
|
|
||||||
static void SetConvertedTextToBuffer(u8 *aBuffer, const char *aText) {
|
|
||||||
u8 *_ConvertedText = DynOS_String_Convert(aText, false);
|
|
||||||
memcpy(aBuffer, _ConvertedText, DynOS_String_Length(_ConvertedText) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Data
|
// Data
|
||||||
//
|
//
|
||||||
|
@ -59,18 +41,18 @@ struct DynosLevelScript {
|
||||||
#define DYNOS_LEVEL_MOD_INDEX_VANILLA (-1)
|
#define DYNOS_LEVEL_MOD_INDEX_VANILLA (-1)
|
||||||
|
|
||||||
static DynosLevelScript sDynosLevelScripts[LEVEL_COUNT] = { { NULL, DYNOS_LEVEL_MOD_INDEX_VANILLA } };
|
static DynosLevelScript sDynosLevelScripts[LEVEL_COUNT] = { { NULL, DYNOS_LEVEL_MOD_INDEX_VANILLA } };
|
||||||
static void *sDynosLevelScriptsOriginal[LEVEL_COUNT] = { NULL };
|
extern void *gDynosLevelScriptsOriginal[LEVEL_COUNT];
|
||||||
static Array<DynosWarp> sDynosLevelWarps[LEVEL_COUNT] = { Array<DynosWarp>() };
|
static Array<DynosWarp> sDynosLevelWarps[LEVEL_COUNT] = { Array<DynosWarp>() };
|
||||||
static Array<s32> sDynosLevelList = Array<s32>(); // Ordered by Course Id, COURSE_NONE excluded
|
|
||||||
|
|
||||||
u64 DynOS_Level_CmdGet(void *aCmd, u64 aOffset) {
|
u64 DynOS_Level_CmdGet(void *aCmd, u64 aOffset) {
|
||||||
u64 _Offset = (((aOffset) & 3llu) | (((aOffset) & ~3llu) << (sizeof(void *) >> 3llu)));
|
u64 _Offset = (((aOffset) & 3llu) | (((aOffset) & ~3llu) << (sizeof(void *) >> 3llu)));
|
||||||
return *((u64 *) (u64(aCmd) + _Offset));
|
return *((u64 *) (u64(aCmd) + _Offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *DynOS_Level_CmdNext(void *aCmd, u64 aCmdSize) {
|
LvlCmd *DynOS_Level_CmdNext(LvlCmd *aCmd) {
|
||||||
|
u64 aCmdSize = aCmd->mSize;
|
||||||
u64 _Offset = (((aCmdSize) & 3llu) | (((aCmdSize) & ~3llu) << (sizeof(void *) >> 3llu)));
|
u64 _Offset = (((aCmdSize) & 3llu) | (((aCmdSize) & ~3llu) << (sizeof(void *) >> 3llu)));
|
||||||
return (void *) (u64(aCmd) + _Offset);
|
return (LvlCmd*) (u64(aCmd) + _Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8, void *));
|
void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8, void *));
|
||||||
|
@ -83,15 +65,7 @@ static s32 DynOS_Level_PreprocessMasterScript(u8 aType, void *aCmd) {
|
||||||
static bool sDynosScriptExecLevelTable = false;
|
static bool sDynosScriptExecLevelTable = false;
|
||||||
static s32 sDynosLevelNum = -1;
|
static s32 sDynosLevelNum = -1;
|
||||||
|
|
||||||
if (!sDynosScriptExecLevelTable) {
|
if (sDynosScriptExecLevelTable) {
|
||||||
|
|
||||||
// JUMP_LINK
|
|
||||||
if (aType == 0x06) {
|
|
||||||
sDynosScriptExecLevelTable = true;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// JUMP_IF
|
// JUMP_IF
|
||||||
if (aType == 0x0C) {
|
if (aType == 0x0C) {
|
||||||
|
@ -105,21 +79,19 @@ static s32 DynOS_Level_PreprocessMasterScript(u8 aType, void *aCmd) {
|
||||||
if (sDynosLevelNum >= 0 && sDynosLevelNum < LEVEL_COUNT && !sDynosLevelScripts[sDynosLevelNum].mLevelScript) {
|
if (sDynosLevelNum >= 0 && sDynosLevelNum < LEVEL_COUNT && !sDynosLevelScripts[sDynosLevelNum].mLevelScript) {
|
||||||
sDynosLevelScripts[sDynosLevelNum].mLevelScript = _Script;
|
sDynosLevelScripts[sDynosLevelNum].mLevelScript = _Script;
|
||||||
sDynosLevelScripts[sDynosLevelNum].mModIndex = DYNOS_LEVEL_MOD_INDEX_VANILLA;
|
sDynosLevelScripts[sDynosLevelNum].mModIndex = DYNOS_LEVEL_MOD_INDEX_VANILLA;
|
||||||
sDynosLevelScriptsOriginal[sDynosLevelNum] = _Script;
|
gDynosLevelScriptsOriginal[sDynosLevelNum] = _Script;
|
||||||
}
|
}
|
||||||
sDynosLevelNum = -1;
|
sDynosLevelNum = -1;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXIT
|
// EXIT or SLEEP
|
||||||
if (aType == 0x02) {
|
if (aType == 0x02 || aType == 0x03) {
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SLEEP
|
|
||||||
if (aType == 0x03) {
|
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
} else if (aType == 0x06) { // JUMP_LINK
|
||||||
|
sDynosScriptExecLevelTable = true;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -184,8 +156,7 @@ static s32 DynOS_Level_PreprocessScript(u8 aType, void *aCmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SLEEP
|
// SLEEP or SLEEP_BEFORE_EXIT
|
||||||
// SLEEP_BEFORE_EXIT
|
|
||||||
else if (aType == 0x03 || aType == 0x04) {
|
else if (aType == 0x03 || aType == 0x04) {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
@ -194,30 +165,19 @@ static s32 DynOS_Level_PreprocessScript(u8 aType, void *aCmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runs only once
|
// Runs only once
|
||||||
static void DynOS_Level_Init() {
|
void DynOS_Level_Init() {
|
||||||
static bool sInited = false;
|
static bool sInited = false;
|
||||||
if (!sInited) {
|
if (!sInited) {
|
||||||
|
|
||||||
// Level scripts
|
|
||||||
DynOS_Level_ParseScript(level_main_scripts_entry, DynOS_Level_PreprocessMasterScript);
|
|
||||||
|
|
||||||
// Level warps
|
// Level warps
|
||||||
for (sDynosCurrentLevelNum = 0; sDynosCurrentLevelNum != LEVEL_COUNT; ++sDynosCurrentLevelNum) {
|
for (sDynosCurrentLevelNum = 0; sDynosCurrentLevelNum != LEVEL_COUNT; ++sDynosCurrentLevelNum) {
|
||||||
|
sDynosLevelScripts[sDynosCurrentLevelNum].mLevelScript = gDynosLevelScriptsOriginal[sDynosCurrentLevelNum];
|
||||||
|
sDynosLevelScripts[sDynosCurrentLevelNum].mModIndex = DYNOS_LEVEL_MOD_INDEX_VANILLA;
|
||||||
if (sDynosLevelScripts[sDynosCurrentLevelNum].mLevelScript) {
|
if (sDynosLevelScripts[sDynosCurrentLevelNum].mLevelScript) {
|
||||||
DynOS_Level_ParseScript(sDynosLevelScripts[sDynosCurrentLevelNum].mLevelScript, DynOS_Level_PreprocessScript);
|
DynOS_Level_ParseScript(sDynosLevelScripts[sDynosCurrentLevelNum].mLevelScript, DynOS_Level_PreprocessScript);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Level list ordered by course id
|
|
||||||
for (s32 i = COURSE_MIN; i <= COURSE_MAX; ++i) {
|
|
||||||
if (i == COURSE_CAKE_END) continue;
|
|
||||||
for (s32 j = 1; j != LEVEL_COUNT; ++j) {
|
|
||||||
if (get_level_course_num(j - 1) == i) {
|
|
||||||
sDynosLevelList.Add(j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
sInited = true;
|
sInited = true;
|
||||||
}
|
}
|
||||||
|
@ -227,20 +187,8 @@ static void DynOS_Level_Init() {
|
||||||
// Common
|
// Common
|
||||||
//
|
//
|
||||||
|
|
||||||
s32 DynOS_Level_GetCount() {
|
s8 DynOS_Level_GetCourse(s32 aLevel) {
|
||||||
DynOS_Level_Init();
|
return get_level_course_num(aLevel);
|
||||||
return sDynosLevelList.Count();
|
|
||||||
}
|
|
||||||
|
|
||||||
const s32 *DynOS_Level_GetList() {
|
|
||||||
DynOS_Level_Init();
|
|
||||||
return sDynosLevelList.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 DynOS_Level_GetCourse(s32 aLevel) {
|
|
||||||
u32 index = aLevel - 1;
|
|
||||||
if (index >= LEVEL_COUNT) { return COURSE_NONE; }
|
|
||||||
return (s32) gLevelToCourseNumTable[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynOS_Level_Override(void* originalScript, void* newScript, s32 modIndex) {
|
void DynOS_Level_Override(void* originalScript, void* newScript, s32 modIndex) {
|
||||||
|
@ -260,7 +208,7 @@ void DynOS_Level_Unoverride() {
|
||||||
for (s32 i = 0; i < LEVEL_COUNT; i++) {
|
for (s32 i = 0; i < LEVEL_COUNT; i++) {
|
||||||
sDynosCurrentLevelNum = i;
|
sDynosCurrentLevelNum = i;
|
||||||
sDynosLevelWarps[i].Clear();
|
sDynosLevelWarps[i].Clear();
|
||||||
sDynosLevelScripts[i].mLevelScript = sDynosLevelScriptsOriginal[i];
|
sDynosLevelScripts[i].mLevelScript = gDynosLevelScriptsOriginal[i];
|
||||||
sDynosLevelScripts[i].mModIndex = DYNOS_LEVEL_MOD_INDEX_VANILLA;
|
sDynosLevelScripts[i].mModIndex = DYNOS_LEVEL_MOD_INDEX_VANILLA;
|
||||||
DynOS_Level_ParseScript(sDynosLevelScripts[i].mLevelScript, DynOS_Level_PreprocessScript);
|
DynOS_Level_ParseScript(sDynosLevelScripts[i].mLevelScript, DynOS_Level_PreprocessScript);
|
||||||
}
|
}
|
||||||
|
@ -289,205 +237,21 @@ s32 DynOS_Level_GetModIndex(s32 aLevel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynOS_Level_IsVanillaLevel(s32 aLevel) {
|
bool DynOS_Level_IsVanillaLevel(s32 aLevel) {
|
||||||
if (aLevel >= 0 && aLevel < LEVEL_COUNT) {
|
DynOS_Level_Init();
|
||||||
return sDynosLevelScripts[aLevel].mLevelScript == sDynosLevelScriptsOriginal[aLevel];
|
|
||||||
|
if (aLevel >= LEVEL_MIN && aLevel < LEVEL_COUNT) {
|
||||||
|
return sDynosLevelScripts[aLevel].mLevelScript == gDynosLevelScriptsOriginal[aLevel];
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Course name
|
|
||||||
//
|
|
||||||
|
|
||||||
const u8 *DynOS_Level_GetName(s32 aLevel, bool aDecaps, bool aAddCourseNumber) {
|
|
||||||
DynOS_Level_Init();
|
|
||||||
static u8 sBuffer[256];
|
|
||||||
memset(sBuffer, 0xFF, 256);
|
|
||||||
s32 _Course = DynOS_Level_GetCourse(aLevel);
|
|
||||||
|
|
||||||
// Level name
|
|
||||||
if (aLevel == LEVEL_BOWSER_1) {
|
|
||||||
SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_BOWSER_1);
|
|
||||||
} else if (aLevel == LEVEL_BOWSER_2) {
|
|
||||||
SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_BOWSER_2);
|
|
||||||
} else if (aLevel == LEVEL_BOWSER_3) {
|
|
||||||
SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_BOWSER_3);
|
|
||||||
} else if (_Course < COURSE_BOB) {
|
|
||||||
SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_CASTLE);
|
|
||||||
} else if (_Course >= COURSE_CAKE_END) {
|
|
||||||
SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_CASTLE);
|
|
||||||
} else {
|
|
||||||
#ifdef VERSION_EU
|
|
||||||
const u8 *_CourseName = ((const u8 **) course_name_table_eu_en)[_Course - COURSE_BOB] + 3;
|
|
||||||
#else
|
|
||||||
const u8 *_CourseName = ((const u8 **) seg2_course_name_table)[_Course - COURSE_BOB] + 3;
|
|
||||||
#endif
|
|
||||||
memcpy(sBuffer, _CourseName, DynOS_String_Length(_CourseName));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decaps
|
|
||||||
if (aDecaps) {
|
|
||||||
DynOS_String_Decapitalize(sBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Course number
|
|
||||||
if (aAddCourseNumber && (_Course >= COURSE_BOB) && (_Course <= COURSE_STAGES_MAX)) {
|
|
||||||
memmove(sBuffer + 5, sBuffer, DynOS_String_Length(sBuffer));
|
|
||||||
sBuffer[0] = ((_Course / 10) == 0 ? 158 : (_Course / 10));
|
|
||||||
sBuffer[1] = (_Course % 10);
|
|
||||||
sBuffer[2] = 158;
|
|
||||||
sBuffer[3] = 159;
|
|
||||||
sBuffer[4] = 158;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Act/Star name
|
|
||||||
//
|
|
||||||
|
|
||||||
const u8 *DynOS_Level_GetActName(s32 aLevel, s32 aAct, bool aDecaps, bool aAddStarNumber) {
|
|
||||||
DynOS_Level_Init();
|
|
||||||
static u8 sBuffer[256];
|
|
||||||
memset(sBuffer, 0xFF, 256);
|
|
||||||
s32 _Course = DynOS_Level_GetCourse(aLevel);
|
|
||||||
|
|
||||||
// Star name
|
|
||||||
if (_Course < COURSE_BOB) {
|
|
||||||
SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_ONE_SECRET_STAR);
|
|
||||||
} else if (aLevel == LEVEL_BITDW) {
|
|
||||||
SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_RED_COINS_STAR);
|
|
||||||
} else if (aLevel == LEVEL_BITFS) {
|
|
||||||
SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_RED_COINS_STAR);
|
|
||||||
} else if (aLevel == LEVEL_BITS) {
|
|
||||||
SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_RED_COINS_STAR);
|
|
||||||
} else if (_Course > COURSE_STAGES_MAX) {
|
|
||||||
SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_EMPTY);
|
|
||||||
} else if (aAct >= 7) {
|
|
||||||
SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_100_COINS_STAR);
|
|
||||||
} else {
|
|
||||||
#ifdef VERSION_EU
|
|
||||||
const u8 *_ActName = ((const u8 **) act_name_table_eu_en)[(_Course - COURSE_BOB) * 6 + (aAct - 1)];
|
|
||||||
#else
|
|
||||||
const u8 *_ActName = ((const u8 **) seg2_act_name_table)[(_Course - COURSE_BOB) * 6 + (aAct - 1)];
|
|
||||||
#endif
|
|
||||||
memcpy(sBuffer, _ActName, DynOS_String_Length(_ActName));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decaps
|
|
||||||
if (aDecaps) {
|
|
||||||
DynOS_String_Decapitalize(sBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Star number
|
|
||||||
if (aAddStarNumber && (_Course >= COURSE_BOB) && (_Course <= COURSE_STAGES_MAX)) {
|
|
||||||
memmove(sBuffer + 5, sBuffer, DynOS_String_Length(sBuffer));
|
|
||||||
sBuffer[0] = ((aAct / 10) == 0 ? 158 : (aAct / 10));
|
|
||||||
sBuffer[1] = (aAct % 10);
|
|
||||||
sBuffer[2] = 158;
|
|
||||||
sBuffer[3] = 159;
|
|
||||||
sBuffer[4] = 158;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
const u8 *DynOS_Level_GetAreaName(s32 aLevel, s32 aArea, bool aDecaps) {
|
|
||||||
DynOS_Level_Init();
|
|
||||||
static const char *sAreaNamesPerLevel[][4] = {
|
|
||||||
{ "", "", "", "" },
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* BoB */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* WF */
|
|
||||||
{ "MAIN AREA", "SUNKEN SHIP", "NOT AVAILABLE", "NOT AVAILABLE" }, /* JRB */
|
|
||||||
{ "MAIN AREA", "COTTAGE SLIDE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* CCM */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* BBH */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* HMC */
|
|
||||||
{ "MAIN AREA", "VOLCANO", "NOT AVAILABLE", "NOT AVAILABLE" }, /* LLL */
|
|
||||||
{ "MAIN AREA", "PYRAMID", "EYEROCK'S ROOM", "NOT AVAILABLE" }, /* SSL */
|
|
||||||
{ "MAIN AREA", "DOCKS", "NOT AVAILABLE", "NOT AVAILABLE" }, /* DDD */
|
|
||||||
{ "MAIN AREA", "IGLOO", "NOT AVAILABLE", "NOT AVAILABLE" }, /* SL */
|
|
||||||
{ "MAIN AREA", "DOWNTOWN", "NOT AVAILABLE", "NOT AVAILABLE" }, /* WDW */
|
|
||||||
{ "MAIN AREA", "SECRET SLIDE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* TTM */
|
|
||||||
{ "HUGE ISLAND", "TINY ISLAND", "WIGGLER'S ROOM", "NOT AVAILABLE" }, /* THI */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* TTC */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* RR */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* BITDW */
|
|
||||||
{ "BOWSER BATTLE", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* Bowser 1 */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* BITFS */
|
|
||||||
{ "BOWSER BATTLE", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* Bowser 2 */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* BITS */
|
|
||||||
{ "BOWSER BATTLE", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* Bowser 3 */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* PSS */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* TOTWC */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* COTMC */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* VCUTM */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* WMOTR */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* SA */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* Castle grounds */
|
|
||||||
{ "FIRST FLOOR", "SECOND FLOOR", "BASEMENT", "NOT AVAILABLE" }, /* Castle inside */
|
|
||||||
{ "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* Castle courtyard */
|
|
||||||
{ "ENDING", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* Ending */
|
|
||||||
};
|
|
||||||
static u8 sBuffer[256];
|
|
||||||
memset(sBuffer, 0xFF, 256);
|
|
||||||
|
|
||||||
// Area name
|
|
||||||
switch (aLevel) {
|
|
||||||
case LEVEL_BOB: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[1][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_WF: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[2][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_JRB: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[3][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_CCM: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[4][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_BBH: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[5][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_HMC: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[6][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_LLL: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[7][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_SSL: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[8][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_DDD: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[9][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_SL: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[10][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_WDW: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[11][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_TTM: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[12][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_THI: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[13][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_TTC: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[14][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_RR: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[15][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_BITDW: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[16][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_BOWSER_1: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[17][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_BITFS: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[18][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_BOWSER_2: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[19][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_BITS: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[20][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_BOWSER_3: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[21][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_PSS: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[22][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_TOTWC: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[23][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_COTMC: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[24][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_VCUTM: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[25][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_WMOTR: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[26][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_SA: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[27][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_CASTLE_GROUNDS: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[28][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_CASTLE: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[29][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_CASTLE_COURTYARD: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[30][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
case LEVEL_ENDING: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[31][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
default: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[0][MIN(MAX(aArea - 1, 0), 3)]); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decaps
|
|
||||||
if (aDecaps) {
|
|
||||||
DynOS_String_Decapitalize(sBuffer);
|
|
||||||
}
|
|
||||||
return sBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Level Script Preprocessing
|
// Level Script Preprocessing
|
||||||
// By default,
|
|
||||||
// - Ifs are always true
|
// - Ifs are always true
|
||||||
// - Skips are always false
|
// - Skips are always false
|
||||||
// - Loops break after the first loop
|
// - Loops break after the first loop
|
||||||
//
|
//
|
||||||
|
|
||||||
struct LvlCmd {
|
|
||||||
u8 mType;
|
|
||||||
u8 mSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Stack {
|
struct Stack {
|
||||||
u64 mData[32];
|
u64 mData[32];
|
||||||
s32 mBaseIndex;
|
s32 mBaseIndex;
|
||||||
|
@ -512,7 +276,7 @@ static T StackPop(Stack& aStack) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdExecute(Stack &aStack, LvlCmd *aCmd) {
|
static LvlCmd *DynOS_Level_CmdExecute(Stack &aStack, LvlCmd *aCmd) {
|
||||||
StackPush(aStack, DynOS_Level_CmdNext(aCmd, aCmd->mSize));
|
StackPush(aStack, DynOS_Level_CmdNext(aCmd));
|
||||||
StackPush(aStack, aStack.mBaseIndex);
|
StackPush(aStack, aStack.mBaseIndex);
|
||||||
aStack.mBaseIndex = aStack.mTopIndex;
|
aStack.mBaseIndex = aStack.mTopIndex;
|
||||||
return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 12);
|
return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 12);
|
||||||
|
@ -529,20 +293,12 @@ static LvlCmd *DynOS_Level_CmdExit(Stack &aStack, LvlCmd *aCmd) {
|
||||||
return StackPop<LvlCmd *>(aStack);
|
return StackPop<LvlCmd *>(aStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSleep(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSleepBeforeExit(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdJump(Stack &aStack, LvlCmd *aCmd) {
|
static LvlCmd *DynOS_Level_CmdJump(Stack &aStack, LvlCmd *aCmd) {
|
||||||
return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 4);
|
return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdJumpLink(Stack &aStack, LvlCmd *aCmd) {
|
static LvlCmd *DynOS_Level_CmdJumpLink(Stack &aStack, LvlCmd *aCmd) {
|
||||||
StackPush(aStack, DynOS_Level_CmdNext(aCmd, aCmd->mSize));
|
StackPush(aStack, DynOS_Level_CmdNext(aCmd));
|
||||||
return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 4);
|
return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,248 +307,40 @@ static LvlCmd *DynOS_Level_CmdReturn(Stack &aStack, UNUSED LvlCmd *aCmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdJumpLinkPushArg(Stack &aStack, LvlCmd *aCmd) {
|
static LvlCmd *DynOS_Level_CmdJumpLinkPushArg(Stack &aStack, LvlCmd *aCmd) {
|
||||||
StackPush(aStack, DynOS_Level_CmdNext(aCmd, aCmd->mSize));
|
StackPush(aStack, DynOS_Level_CmdNext(aCmd));
|
||||||
StackPush(aStack, DynOS_Level_CmdGet(aCmd, 2));
|
StackPush(aStack, DynOS_Level_CmdGet(aCmd, 2));
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
return DynOS_Level_CmdNext(aCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdJumpRepeat(Stack &aStack, LvlCmd *aCmd) {
|
static LvlCmd *DynOS_Level_CmdJumpRepeat(Stack &aStack, LvlCmd *aCmd) {
|
||||||
aStack.mTopIndex -= 2;
|
aStack.mTopIndex -= 2;
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
return DynOS_Level_CmdNext(aCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdLoopBegin(Stack &aStack, LvlCmd *aCmd) {
|
static LvlCmd *DynOS_Level_CmdLoopBegin(Stack &aStack, LvlCmd *aCmd) {
|
||||||
StackPush(aStack, DynOS_Level_CmdNext(aCmd, aCmd->mSize));
|
StackPush(aStack, DynOS_Level_CmdNext(aCmd));
|
||||||
StackPush(aStack, 0);
|
StackPush(aStack, 0);
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
return DynOS_Level_CmdNext(aCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdLoopUntil(Stack &aStack, LvlCmd *aCmd) {
|
static LvlCmd *DynOS_Level_CmdLoopUntil(Stack &aStack, LvlCmd *aCmd) {
|
||||||
aStack.mTopIndex -= 2;
|
aStack.mTopIndex -= 2;
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
return DynOS_Level_CmdNext(aCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdJumpIf(Stack &aStack, LvlCmd *aCmd) {
|
static LvlCmd *DynOS_Level_CmdJumpIf(Stack &aStack, LvlCmd *aCmd) {
|
||||||
StackPush(aStack, DynOS_Level_CmdNext(aCmd, aCmd->mSize)); /* Not an error, that's intentional */
|
StackPush(aStack, DynOS_Level_CmdNext(aCmd)); /* Not an error, that's intentional */
|
||||||
return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 8);
|
return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdJumpLinkIf(Stack &aStack, LvlCmd *aCmd) {
|
static LvlCmd *DynOS_Level_CmdJumpLinkIf(Stack &aStack, LvlCmd *aCmd) {
|
||||||
StackPush(aStack, DynOS_Level_CmdNext(aCmd, aCmd->mSize));
|
StackPush(aStack, DynOS_Level_CmdNext(aCmd));
|
||||||
return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 8);
|
return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSkipIf(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSkip(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSkipNop(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdCall(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdCallLoop(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSetRegister(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdPushPool(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdPopPool(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdLoadFixed(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdLoadRaw(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdLoadMIO0(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdLoadMarioHead(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdLoadMIO0Texture(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdInitLevel(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdClearLevel(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdAllocLevelPool(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdFreeLevelPool(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdBeginArea(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdEndArea(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdLoadModelFromDL(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdLoadModelFromGeo(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_Cmd23(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdMario(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdObject(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdWarpNode(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdInstantWarp(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSetTerrainType(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdPaintingWarpNode(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_Cmd3A(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSetWhirlpool(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSetBlackout(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSetGamma(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSetTerrain(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSetRooms(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdMacroObjects(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdLoadArea(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdUnloadArea(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSetMarioStartPos(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_Cmd2C(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_Cmd2D(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSetTransition(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdNop(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdShowDialog(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSetBackgroundMusic(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdSetMenuMusic(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdStopMusic(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdGetOrSet(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdAdvanceDemo(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdClearDemoPointer(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdPlaceObjectExt(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdPlaceObjectExt2(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdLoadModelFromGeoExt(Stack &aStack, LvlCmd *aCmd) {
|
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static LvlCmd *DynOS_Level_CmdJumpArea(Stack &aStack, LvlCmd *aCmd, s32 (*aPreprocessFunction)(u8, void *)) {
|
static LvlCmd *DynOS_Level_CmdJumpArea(Stack &aStack, LvlCmd *aCmd, s32 (*aPreprocessFunction)(u8, void *)) {
|
||||||
DynOS_Level_ParseScript((const void *) DynOS_Level_CmdGet(aCmd, 8), aPreprocessFunction);
|
DynOS_Level_ParseScript((const void *) DynOS_Level_CmdGet(aCmd, 8), aPreprocessFunction);
|
||||||
return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize);
|
return DynOS_Level_CmdNext(aCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8, void *)) {
|
void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8, void *)) {
|
||||||
|
@ -808,8 +356,6 @@ void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8,
|
||||||
case 0x00: _Cmd = DynOS_Level_CmdExecute(_Stack, _Cmd); break;
|
case 0x00: _Cmd = DynOS_Level_CmdExecute(_Stack, _Cmd); break;
|
||||||
case 0x01: _Cmd = DynOS_Level_CmdExitAndExecute(_Stack, _Cmd); break;
|
case 0x01: _Cmd = DynOS_Level_CmdExitAndExecute(_Stack, _Cmd); break;
|
||||||
case 0x02: _Cmd = DynOS_Level_CmdExit(_Stack, _Cmd); break;
|
case 0x02: _Cmd = DynOS_Level_CmdExit(_Stack, _Cmd); break;
|
||||||
case 0x03: _Cmd = DynOS_Level_CmdSleep(_Stack, _Cmd); break;
|
|
||||||
case 0x04: _Cmd = DynOS_Level_CmdSleepBeforeExit(_Stack, _Cmd); break;
|
|
||||||
case 0x05: _Cmd = DynOS_Level_CmdJump(_Stack, _Cmd); break;
|
case 0x05: _Cmd = DynOS_Level_CmdJump(_Stack, _Cmd); break;
|
||||||
case 0x06: _Cmd = DynOS_Level_CmdJumpLink(_Stack, _Cmd); break;
|
case 0x06: _Cmd = DynOS_Level_CmdJumpLink(_Stack, _Cmd); break;
|
||||||
case 0x07: _Cmd = DynOS_Level_CmdReturn(_Stack, _Cmd); break;
|
case 0x07: _Cmd = DynOS_Level_CmdReturn(_Stack, _Cmd); break;
|
||||||
|
@ -819,64 +365,15 @@ void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8,
|
||||||
case 0x0B: _Cmd = DynOS_Level_CmdLoopUntil(_Stack, _Cmd); break;
|
case 0x0B: _Cmd = DynOS_Level_CmdLoopUntil(_Stack, _Cmd); break;
|
||||||
case 0x0C: _Cmd = DynOS_Level_CmdJumpIf(_Stack, _Cmd); break;
|
case 0x0C: _Cmd = DynOS_Level_CmdJumpIf(_Stack, _Cmd); break;
|
||||||
case 0x0D: _Cmd = DynOS_Level_CmdJumpLinkIf(_Stack, _Cmd); break;
|
case 0x0D: _Cmd = DynOS_Level_CmdJumpLinkIf(_Stack, _Cmd); break;
|
||||||
case 0x0E: _Cmd = DynOS_Level_CmdSkipIf(_Stack, _Cmd); break;
|
|
||||||
case 0x0F: _Cmd = DynOS_Level_CmdSkip(_Stack, _Cmd); break;
|
|
||||||
case 0x10: _Cmd = DynOS_Level_CmdSkipNop(_Stack, _Cmd); break;
|
|
||||||
case 0x11: _Cmd = DynOS_Level_CmdCall(_Stack, _Cmd); break;
|
|
||||||
case 0x12: _Cmd = DynOS_Level_CmdCallLoop(_Stack, _Cmd); break;
|
|
||||||
case 0x13: _Cmd = DynOS_Level_CmdSetRegister(_Stack, _Cmd); break;
|
|
||||||
case 0x14: _Cmd = DynOS_Level_CmdPushPool(_Stack, _Cmd); break;
|
|
||||||
case 0x15: _Cmd = DynOS_Level_CmdPopPool(_Stack, _Cmd); break;
|
|
||||||
case 0x16: _Cmd = DynOS_Level_CmdLoadFixed(_Stack, _Cmd); break;
|
|
||||||
case 0x17: _Cmd = DynOS_Level_CmdLoadRaw(_Stack, _Cmd); break;
|
|
||||||
case 0x18: _Cmd = DynOS_Level_CmdLoadMIO0(_Stack, _Cmd); break;
|
|
||||||
case 0x19: _Cmd = DynOS_Level_CmdLoadMarioHead(_Stack, _Cmd); break;
|
|
||||||
case 0x1A: _Cmd = DynOS_Level_CmdLoadMIO0Texture(_Stack, _Cmd); break;
|
|
||||||
case 0x1B: _Cmd = DynOS_Level_CmdInitLevel(_Stack, _Cmd); break;
|
|
||||||
case 0x1C: _Cmd = DynOS_Level_CmdClearLevel(_Stack, _Cmd); break;
|
|
||||||
case 0x1D: _Cmd = DynOS_Level_CmdAllocLevelPool(_Stack, _Cmd); break;
|
|
||||||
case 0x1E: _Cmd = DynOS_Level_CmdFreeLevelPool(_Stack, _Cmd); break;
|
|
||||||
case 0x1F: _Cmd = DynOS_Level_CmdBeginArea(_Stack, _Cmd); break;
|
|
||||||
case 0x20: _Cmd = DynOS_Level_CmdEndArea(_Stack, _Cmd); break;
|
|
||||||
case 0x21: _Cmd = DynOS_Level_CmdLoadModelFromDL(_Stack, _Cmd); break;
|
|
||||||
case 0x22: _Cmd = DynOS_Level_CmdLoadModelFromGeo(_Stack, _Cmd); break;
|
|
||||||
case 0x23: _Cmd = DynOS_Level_Cmd23(_Stack, _Cmd); break;
|
|
||||||
case 0x24: _Cmd = DynOS_Level_CmdObject(_Stack, _Cmd); break;
|
|
||||||
case 0x25: _Cmd = DynOS_Level_CmdMario(_Stack, _Cmd); break;
|
|
||||||
case 0x26: _Cmd = DynOS_Level_CmdWarpNode(_Stack, _Cmd); break;
|
|
||||||
case 0x27: _Cmd = DynOS_Level_CmdPaintingWarpNode(_Stack, _Cmd); break;
|
|
||||||
case 0x28: _Cmd = DynOS_Level_CmdInstantWarp(_Stack, _Cmd); break;
|
|
||||||
case 0x29: _Cmd = DynOS_Level_CmdLoadArea(_Stack, _Cmd); break;
|
|
||||||
case 0x2A: _Cmd = DynOS_Level_CmdUnloadArea(_Stack, _Cmd); break;
|
|
||||||
case 0x2B: _Cmd = DynOS_Level_CmdSetMarioStartPos(_Stack, _Cmd); break;
|
|
||||||
case 0x2C: _Cmd = DynOS_Level_Cmd2C(_Stack, _Cmd); break;
|
|
||||||
case 0x2D: _Cmd = DynOS_Level_Cmd2D(_Stack, _Cmd); break;
|
|
||||||
case 0x2E: _Cmd = DynOS_Level_CmdSetTerrain(_Stack, _Cmd); break;
|
|
||||||
case 0x2F: _Cmd = DynOS_Level_CmdSetRooms(_Stack, _Cmd); break;
|
|
||||||
case 0x30: _Cmd = DynOS_Level_CmdShowDialog(_Stack, _Cmd); break;
|
|
||||||
case 0x31: _Cmd = DynOS_Level_CmdSetTerrainType(_Stack, _Cmd); break;
|
|
||||||
case 0x32: _Cmd = DynOS_Level_CmdNop(_Stack, _Cmd); break;
|
|
||||||
case 0x33: _Cmd = DynOS_Level_CmdSetTransition(_Stack, _Cmd); break;
|
|
||||||
case 0x34: _Cmd = DynOS_Level_CmdSetBlackout(_Stack, _Cmd); break;
|
|
||||||
case 0x35: _Cmd = DynOS_Level_CmdSetGamma(_Stack, _Cmd); break;
|
|
||||||
case 0x36: _Cmd = DynOS_Level_CmdSetBackgroundMusic(_Stack, _Cmd); break;
|
|
||||||
case 0x37: _Cmd = DynOS_Level_CmdSetMenuMusic(_Stack, _Cmd); break;
|
|
||||||
case 0x38: _Cmd = DynOS_Level_CmdStopMusic(_Stack, _Cmd); break;
|
|
||||||
case 0x39: _Cmd = DynOS_Level_CmdMacroObjects(_Stack, _Cmd); break;
|
|
||||||
case 0x3A: _Cmd = DynOS_Level_Cmd3A(_Stack, _Cmd); break;
|
|
||||||
case 0x3B: _Cmd = DynOS_Level_CmdSetWhirlpool(_Stack, _Cmd); break;
|
|
||||||
case 0x3C: _Cmd = DynOS_Level_CmdGetOrSet(_Stack, _Cmd); break;
|
|
||||||
case 0x3D: _Cmd = DynOS_Level_CmdAdvanceDemo(_Stack, _Cmd); break;
|
|
||||||
case 0x3E: _Cmd = DynOS_Level_CmdClearDemoPointer(_Stack, _Cmd); break;
|
|
||||||
// coop
|
// coop
|
||||||
case 0x3F: _Cmd = DynOS_Level_CmdPlaceObjectExt(_Stack, _Cmd); break;
|
|
||||||
case 0x40: _Cmd = DynOS_Level_CmdPlaceObjectExt2(_Stack, _Cmd); break;
|
|
||||||
case 0x41: _Cmd = DynOS_Level_CmdLoadModelFromGeoExt(_Stack, _Cmd); break;
|
|
||||||
case 0x42: _Cmd = DynOS_Level_CmdJumpArea(_Stack, _Cmd, aPreprocessFunction); break;
|
case 0x42: _Cmd = DynOS_Level_CmdJumpArea(_Stack, _Cmd, aPreprocessFunction); break;
|
||||||
|
|
||||||
|
default: _Cmd = DynOS_Level_CmdNext(_Cmd); break;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
_Cmd = (LvlCmd *) DynOS_Level_CmdNext(_Cmd, _Cmd->mSize);
|
_Cmd = DynOS_Level_CmdNext(_Cmd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -900,31 +397,26 @@ s16 *DynOS_Level_GetWarp(s32 aLevel, s32 aArea, u8 aWarpId) {
|
||||||
sDynosCurrentLevelNum = 1;
|
sDynosCurrentLevelNum = 1;
|
||||||
DynOS_Level_ParseScript(info->script, DynOS_Level_PreprocessScript);
|
DynOS_Level_ParseScript(info->script, DynOS_Level_PreprocessScript);
|
||||||
for (const auto &_Warp : sDynosLevelWarps[1]) {
|
for (const auto &_Warp : sDynosLevelWarps[1]) {
|
||||||
if (_Warp.mArea == aArea) {
|
if (_Warp.mArea == aArea && _Warp.mId == aWarpId) {
|
||||||
if (_Warp.mId == aWarpId) {
|
|
||||||
return (s16 *) &_Warp;
|
return (s16 *) &_Warp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DynOS_Level_Init();
|
DynOS_Level_Init();
|
||||||
if (aLevel >= 0 && aLevel < LEVEL_COUNT) {
|
if (aLevel >= 0 && aLevel < LEVEL_COUNT) {
|
||||||
for (const auto &_Warp : sDynosLevelWarps[aLevel]) {
|
for (const auto &_Warp : sDynosLevelWarps[aLevel]) {
|
||||||
if (_Warp.mArea == aArea) {
|
if (_Warp.mArea == aArea && _Warp.mId == aWarpId) {
|
||||||
if (_Warp.mId == aWarpId) {
|
|
||||||
return (s16 *) &_Warp;
|
return (s16 *) &_Warp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
s16 *DynOS_Level_GetWarpEntry(s32 aLevel, s32 aArea) {
|
s16 *DynOS_Level_GetWarpEntry(s32 aLevel, s32 aArea) {
|
||||||
DynOS_Level_Init();
|
DynOS_Level_Init();
|
||||||
if (aLevel == LEVEL_TTM && aArea > 2) return NULL;
|
|
||||||
|
|
||||||
// override vanilla castle warps
|
// override vanilla castle warps
|
||||||
if (DynOS_Level_GetCourse(aLevel) == COURSE_NONE && aLevel >= 0 && aLevel < LEVEL_COUNT) {
|
if (DynOS_Level_GetCourse(aLevel) == COURSE_NONE && aLevel >= 0 && aLevel < LEVEL_COUNT) {
|
||||||
|
|
|
@ -3,7 +3,6 @@ extern "C" {
|
||||||
#include "sm64.h"
|
#include "sm64.h"
|
||||||
#include "level_commands.h"
|
#include "level_commands.h"
|
||||||
#include "game/level_update.h"
|
#include "game/level_update.h"
|
||||||
#include "game/options_menu.h"
|
|
||||||
#include "game/object_list_processor.h"
|
#include "game/object_list_processor.h"
|
||||||
extern s16 gMenuMode;
|
extern s16 gMenuMode;
|
||||||
extern s8 gDialogBoxState;
|
extern s8 gDialogBoxState;
|
||||||
|
@ -17,38 +16,17 @@ extern void omm_opt_init();
|
||||||
//
|
//
|
||||||
|
|
||||||
void DynOS_ReturnToMainMenu() {
|
void DynOS_ReturnToMainMenu() {
|
||||||
optmenu_toggle();
|
|
||||||
level_set_transition(0, NULL);
|
level_set_transition(0, NULL);
|
||||||
gDialogBoxState = 0;
|
gDialogBoxState = 0;
|
||||||
gMenuMode = -1;
|
gMenuMode = -1;
|
||||||
fade_into_special_warp(-2, 0);
|
fade_into_special_warp(-2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Init
|
|
||||||
//
|
|
||||||
|
|
||||||
DYNOS_AT_STARTUP void DynOS_Init() {
|
|
||||||
#ifdef OMM_DEFINES_H
|
|
||||||
omm_opt_init();
|
|
||||||
#endif
|
|
||||||
DynOS_Opt_Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Update
|
// Update
|
||||||
//
|
//
|
||||||
|
|
||||||
static bool sDynosIsLevelEntry = false;
|
static bool sDynosIsLevelEntry = false;
|
||||||
void DynOS_UpdateOpt(void *aPad) {
|
|
||||||
if (sDynosIsLevelEntry) {
|
|
||||||
DynOS_Warp_SetParam(gCurrLevelNum, -1);
|
|
||||||
sDynosIsLevelEntry = false;
|
|
||||||
}
|
|
||||||
DynOS_Opt_Update((OSContPad *) aPad);
|
|
||||||
gPrevFrameObjectCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *DynOS_SwapCmd(void *aCmd) {
|
void *DynOS_SwapCmd(void *aCmd) {
|
||||||
return DynOS_Lvl_Override(aCmd);
|
return DynOS_Lvl_Override(aCmd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ void DynOS_Anim_Swap(void *aPtr) {
|
||||||
static Animation *pDefaultAnimation = NULL;
|
static Animation *pDefaultAnimation = NULL;
|
||||||
static Animation sGfxDataAnimation;
|
static Animation sGfxDataAnimation;
|
||||||
|
|
||||||
// Does the object has a model?
|
// Does the object have a model?
|
||||||
struct Object *_Object = (struct Object *) aPtr;
|
struct Object *_Object = (struct Object *) aPtr;
|
||||||
if (!_Object->header.gfx.sharedChild) {
|
if (!_Object->header.gfx.sharedChild) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -183,6 +183,48 @@ static const void* sDynosBuiltinScriptPtrs[] = {
|
||||||
define_builtin(level_main_menu_entry_1),
|
define_builtin(level_main_menu_entry_1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define define_level_original(lvl, script) (void*) script
|
||||||
|
|
||||||
|
void* gDynosLevelScriptsOriginal[LEVEL_COUNT] = {
|
||||||
|
define_level_original(0, NULL),
|
||||||
|
define_level_original(LEVEL_UNKNOWN_1, NULL),
|
||||||
|
define_level_original(LEVEL_UNKNOWN_2, NULL),
|
||||||
|
define_level_original(LEVEL_UNKNOWN_3, NULL),
|
||||||
|
define_level_original(LEVEL_BBH, level_bbh_entry),
|
||||||
|
define_level_original(LEVEL_CCM, level_ccm_entry),
|
||||||
|
define_level_original(LEVEL_CASTLE, level_castle_inside_entry),
|
||||||
|
define_level_original(LEVEL_HMC, level_hmc_entry),
|
||||||
|
define_level_original(LEVEL_SSL, level_ssl_entry),
|
||||||
|
define_level_original(LEVEL_BOB, level_bob_entry),
|
||||||
|
define_level_original(LEVEL_SL, level_sl_entry),
|
||||||
|
define_level_original(LEVEL_WDW, level_wdw_entry),
|
||||||
|
define_level_original(LEVEL_JRB, level_jrb_entry),
|
||||||
|
define_level_original(LEVEL_THI, level_thi_entry),
|
||||||
|
define_level_original(LEVEL_TTC, level_ttc_entry),
|
||||||
|
define_level_original(LEVEL_RR, level_rr_entry),
|
||||||
|
define_level_original(LEVEL_CASTLE_GROUNDS, level_castle_grounds_entry),
|
||||||
|
define_level_original(LEVEL_BITDW, level_bitdw_entry),
|
||||||
|
define_level_original(LEVEL_VCUTM, level_vcutm_entry),
|
||||||
|
define_level_original(LEVEL_BITFS, level_bitfs_entry),
|
||||||
|
define_level_original(LEVEL_SA, level_sa_entry),
|
||||||
|
define_level_original(LEVEL_BITS, level_bits_entry),
|
||||||
|
define_level_original(LEVEL_LLL, level_lll_entry),
|
||||||
|
define_level_original(LEVEL_DDD, level_ddd_entry),
|
||||||
|
define_level_original(LEVEL_WF, level_wf_entry),
|
||||||
|
define_level_original(LEVEL_ENDING, level_ending_entry),
|
||||||
|
define_level_original(LEVEL_CASTLE_COURTYARD, level_castle_courtyard_entry),
|
||||||
|
define_level_original(LEVEL_PSS, level_pss_entry),
|
||||||
|
define_level_original(LEVEL_COTMC, level_cotmc_entry),
|
||||||
|
define_level_original(LEVEL_TOTWC, level_totwc_entry),
|
||||||
|
define_level_original(LEVEL_BOWSER_1, level_bowser_1_entry),
|
||||||
|
define_level_original(LEVEL_WMOTR, level_wmotr_entry),
|
||||||
|
define_level_original(LEVEL_UNKNOWN_32, NULL),
|
||||||
|
define_level_original(LEVEL_BOWSER_2, level_bowser_2_entry),
|
||||||
|
define_level_original(LEVEL_BOWSER_3, level_bowser_3_entry),
|
||||||
|
define_level_original(LEVEL_UNKNOWN_35, NULL),
|
||||||
|
define_level_original(LEVEL_TTM, level_ttm_entry),
|
||||||
|
};
|
||||||
|
|
||||||
const void* DynOS_Builtin_ScriptPtr_GetFromName(const char* aDataName) {
|
const void* DynOS_Builtin_ScriptPtr_GetFromName(const char* aDataName) {
|
||||||
MGR_FIND_DATA(sDynosBuiltinScriptPtrs, (const void*));
|
MGR_FIND_DATA(sDynosBuiltinScriptPtrs, (const void*));
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLev
|
||||||
auto& _OverrideLevelScripts = DynosOverrideLevelScripts();
|
auto& _OverrideLevelScripts = DynosOverrideLevelScripts();
|
||||||
|
|
||||||
// make sure vanilla levels were parsed
|
// make sure vanilla levels were parsed
|
||||||
DynOS_Level_GetCount();
|
DynOS_Level_Init();
|
||||||
|
|
||||||
// check for duplicates
|
// check for duplicates
|
||||||
for (s32 i = 0; i < _CustomLevelScripts.Count(); ++i) {
|
for (s32 i = 0; i < _CustomLevelScripts.Count(); ++i) {
|
||||||
|
|
|
@ -234,7 +234,3 @@ void DynOS_Model_ClearPool(enum ModelPool aModelPool) {
|
||||||
|
|
||||||
assetMap.clear();
|
assetMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynOS_Model_Update() {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,749 +0,0 @@
|
||||||
#include "dynos.cpp.h"
|
|
||||||
extern "C" {
|
|
||||||
#include "pc/configfile.h"
|
|
||||||
#include "audio/external.h"
|
|
||||||
#include "game/game_init.h"
|
|
||||||
#include "pc/controller/controller_keyboard.h"
|
|
||||||
#ifdef BETTERCAMERA
|
|
||||||
#include "game/bettercamera.h"
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Data
|
|
||||||
//
|
|
||||||
|
|
||||||
static DynosOption *sPrevOpt = NULL;
|
|
||||||
static DynosOption *sDynosMenu = NULL;
|
|
||||||
static DynosOption *sOptionsMenu = NULL;
|
|
||||||
static DynosOption *sCurrentMenu = NULL;
|
|
||||||
static DynosOption *sCurrentOpt = NULL;
|
|
||||||
extern s32 sBindingState;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Action list
|
|
||||||
//
|
|
||||||
|
|
||||||
typedef bool (*DynosActionFunction)(const char *);
|
|
||||||
struct DynosAction : NoCopy {
|
|
||||||
String mFuncName;
|
|
||||||
DynosActionFunction mAction;
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC_STORAGE(Array<DynosAction *>, DynosActions);
|
|
||||||
#define sDynosActions __DynosActions()
|
|
||||||
|
|
||||||
static DynosActionFunction DynOS_Opt_GetAction(const String& aFuncName) {
|
|
||||||
for (auto &_DynosAction : sDynosActions) {
|
|
||||||
if (_DynosAction->mFuncName == aFuncName) {
|
|
||||||
return _DynosAction->mAction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DynOS_Opt_AddAction(const String& aFuncName, bool (*aFuncPtr)(const char *), bool aOverwrite) {
|
|
||||||
for (auto &_DynosAction : sDynosActions) {
|
|
||||||
if (_DynosAction->mFuncName == aFuncName) {
|
|
||||||
if (aOverwrite) {
|
|
||||||
_DynosAction->mAction = aFuncPtr;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DynosAction *_DynosAction = New<DynosAction>();
|
|
||||||
_DynosAction->mFuncName = aFuncName;
|
|
||||||
_DynosAction->mAction = aFuncPtr;
|
|
||||||
sDynosActions.Add(_DynosAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Constructors
|
|
||||||
//
|
|
||||||
|
|
||||||
static DynosOption *DynOS_Opt_GetExistingOption(DynosOption *aOpt, const String &aName) {
|
|
||||||
while (aOpt) {
|
|
||||||
if (aOpt->mName == aName) {
|
|
||||||
return aOpt;
|
|
||||||
}
|
|
||||||
if (aOpt->mType == DOPT_SUBMENU) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_GetExistingOption(aOpt->mSubMenu.mChild, aName);
|
|
||||||
if (_Opt) {
|
|
||||||
return _Opt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
aOpt = aOpt->mNext;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DynosOption *DynOS_Opt_NewOption(const String &aName, const String &aConfigName, const String &aLabel, const String &aTitle) {
|
|
||||||
|
|
||||||
// Check if the option already exists
|
|
||||||
static DynosOption sDummyOpt;
|
|
||||||
if (DynOS_Opt_GetExistingOption(sDynosMenu, aName)) {
|
|
||||||
return &sDummyOpt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new option
|
|
||||||
DynosOption *_Opt = New<DynosOption>();
|
|
||||||
_Opt->mName = aName;
|
|
||||||
_Opt->mConfigName = aConfigName;
|
|
||||||
_Opt->mLabel = { aLabel, NULL };
|
|
||||||
_Opt->mTitle = { aTitle, NULL };
|
|
||||||
_Opt->mDynos = true;
|
|
||||||
if (sPrevOpt == NULL) { // The very first option
|
|
||||||
_Opt->mPrev = NULL;
|
|
||||||
_Opt->mNext = NULL;
|
|
||||||
_Opt->mParent = NULL;
|
|
||||||
sDynosMenu = _Opt;
|
|
||||||
} else {
|
|
||||||
if (sPrevOpt->mType == DOPT_SUBMENU && sPrevOpt->mSubMenu.mEmpty) { // First option of a sub-menu
|
|
||||||
_Opt->mPrev = NULL;
|
|
||||||
_Opt->mNext = NULL;
|
|
||||||
_Opt->mParent = sPrevOpt;
|
|
||||||
sPrevOpt->mSubMenu.mChild = _Opt;
|
|
||||||
sPrevOpt->mSubMenu.mEmpty = false;
|
|
||||||
} else {
|
|
||||||
_Opt->mPrev = sPrevOpt;
|
|
||||||
_Opt->mNext = NULL;
|
|
||||||
_Opt->mParent = sPrevOpt->mParent;
|
|
||||||
sPrevOpt->mNext = _Opt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sPrevOpt = _Opt;
|
|
||||||
return _Opt;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_EndSubMenu() {
|
|
||||||
if (sPrevOpt && sPrevOpt->mParent) {
|
|
||||||
if (sPrevOpt->mType == DOPT_SUBMENU && sPrevOpt->mSubMenu.mEmpty) { // ENDMENU command following a SUBMENU command
|
|
||||||
sPrevOpt->mSubMenu.mEmpty = false;
|
|
||||||
} else {
|
|
||||||
sPrevOpt = sPrevOpt->mParent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_CreateSubMenu(const String &aName, const String &aLabel, const String &aTitle) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_NewOption(aName, "", aLabel, aTitle);
|
|
||||||
_Opt->mType = DOPT_SUBMENU;
|
|
||||||
_Opt->mSubMenu.mChild = NULL;
|
|
||||||
_Opt->mSubMenu.mEmpty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_CreateToggle(const String &aName, const String &aConfigName, const String &aLabel, s32 aValue) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_NewOption(aName, aConfigName, aLabel, aLabel);
|
|
||||||
_Opt->mType = DOPT_TOGGLE;
|
|
||||||
_Opt->mToggle.mTog = New<bool>();
|
|
||||||
*_Opt->mToggle.mTog = (bool) aValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_CreateScroll(const String &aName, const String &aConfigName, const String &aLabel, s32 aMin, s32 aMax, s32 aStep, s32 aValue) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_NewOption(aName, aConfigName, aLabel, aLabel);
|
|
||||||
_Opt->mType = DOPT_SCROLL;
|
|
||||||
_Opt->mScroll.mMin = aMin;
|
|
||||||
_Opt->mScroll.mMax = aMax;
|
|
||||||
_Opt->mScroll.mStep = aStep;
|
|
||||||
_Opt->mScroll.mValue = New<s32>();
|
|
||||||
*_Opt->mScroll.mValue = aValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_CreateChoice(const String &aName, const String &aConfigName, const String &aLabel, const Array<String>& aChoices, s32 aValue) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_NewOption(aName, aConfigName, aLabel, aLabel);
|
|
||||||
_Opt->mType = DOPT_CHOICE;
|
|
||||||
_Opt->mChoice.mIndex = New<s32>();
|
|
||||||
*_Opt->mChoice.mIndex = aValue;
|
|
||||||
for (const auto &_Choice : aChoices) {
|
|
||||||
_Opt->mChoice.mChoices.Add({ _Choice, NULL });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_CreateButton(const String &aName, const String &aLabel, const String& aFuncName) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_NewOption(aName, "", aLabel, aLabel);
|
|
||||||
_Opt->mType = DOPT_BUTTON;
|
|
||||||
_Opt->mButton.mFuncName = aFuncName;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_CreateBind(const String &aName, const String &aConfigName, const String &aLabel, u32 aMask, u32 aBind0, u32 aBind1, u32 aBind2) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_NewOption(aName, aConfigName, aLabel, aLabel);
|
|
||||||
_Opt->mType = DOPT_BIND;
|
|
||||||
_Opt->mBind.mMask = aMask;
|
|
||||||
_Opt->mBind.mBinds = New<u32>(3);
|
|
||||||
_Opt->mBind.mBinds[0] = aBind0;
|
|
||||||
_Opt->mBind.mBinds[1] = aBind1;
|
|
||||||
_Opt->mBind.mBinds[2] = aBind2;
|
|
||||||
_Opt->mBind.mIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Loop through DynosOptions
|
|
||||||
//
|
|
||||||
|
|
||||||
DynosOption *DynOS_Opt_Loop(DynosOption *aOpt, DynosLoopFunc aFunc, void *aData) {
|
|
||||||
while (aOpt) {
|
|
||||||
if (aFunc(aOpt, aData)) {
|
|
||||||
return aOpt;
|
|
||||||
} else if (aOpt->mType == DOPT_SUBMENU) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_Loop(aOpt->mSubMenu.mChild, aFunc, aData);
|
|
||||||
if (_Opt) {
|
|
||||||
return _Opt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
aOpt = aOpt->mNext;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get/Set values
|
|
||||||
//
|
|
||||||
|
|
||||||
static bool DynOS_Opt_Get(DynosOption *aOpt, void *aData) {
|
|
||||||
return aOpt->mName == (const char *) aData;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 DynOS_Opt_GetValue(const String &aName) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_Loop(sDynosMenu, DynOS_Opt_Get, (void *) aName.begin());
|
|
||||||
if (_Opt) {
|
|
||||||
switch (_Opt->mType) {
|
|
||||||
case DOPT_TOGGLE: return *_Opt->mToggle.mTog;
|
|
||||||
case DOPT_CHOICE: return *_Opt->mChoice.mIndex;
|
|
||||||
case DOPT_CHOICELEVEL: return *_Opt->mChoice.mIndex;
|
|
||||||
case DOPT_CHOICEAREA: return *_Opt->mChoice.mIndex;
|
|
||||||
case DOPT_CHOICESTAR: return *_Opt->mChoice.mIndex;
|
|
||||||
case DOPT_CHOICEPARAM: return *_Opt->mChoice.mIndex;
|
|
||||||
case DOPT_SCROLL: return *_Opt->mScroll.mValue;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DynOS_Opt_SetValue(const String &aName, s32 aValue) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_Loop(sDynosMenu, DynOS_Opt_Get, (void *) aName.begin());
|
|
||||||
if (_Opt) {
|
|
||||||
switch (_Opt->mType) {
|
|
||||||
case DOPT_TOGGLE: *_Opt->mToggle.mTog = aValue; break;
|
|
||||||
case DOPT_CHOICE: *_Opt->mChoice.mIndex = aValue; break;
|
|
||||||
case DOPT_CHOICELEVEL: *_Opt->mChoice.mIndex = aValue; break;
|
|
||||||
case DOPT_CHOICEAREA: *_Opt->mChoice.mIndex = aValue; break;
|
|
||||||
case DOPT_CHOICESTAR: *_Opt->mChoice.mIndex = aValue; break;
|
|
||||||
case DOPT_CHOICEPARAM: *_Opt->mChoice.mIndex = aValue; break;
|
|
||||||
case DOPT_SCROLL: *_Opt->mScroll.mValue = aValue; break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Processing
|
|
||||||
//
|
|
||||||
|
|
||||||
#define SOUND_DYNOS_SAVED (SOUND_MENU_MARIO_CASTLE_WARP2 | (0xFF << 8))
|
|
||||||
#define SOUND_DYNOS_SELECT (SOUND_MENU_CHANGE_SELECT | (0xF8 << 8))
|
|
||||||
#define SOUND_DYNOS_OK (SOUND_MENU_CHANGE_SELECT | (0xF8 << 8))
|
|
||||||
#define SOUND_DYNOS_CANCEL (SOUND_MENU_CAMERA_BUZZ | (0xFC << 8))
|
|
||||||
|
|
||||||
enum {
|
|
||||||
INPUT_LEFT,
|
|
||||||
INPUT_RIGHT,
|
|
||||||
INPUT_A,
|
|
||||||
INPUT_Z
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
RESULT_NONE,
|
|
||||||
RESULT_OK,
|
|
||||||
RESULT_CANCEL
|
|
||||||
};
|
|
||||||
|
|
||||||
static s32 DynOS_Opt_ProcessInput(DynosOption *aOpt, s32 input) {
|
|
||||||
switch (aOpt->mType) {
|
|
||||||
case DOPT_TOGGLE:
|
|
||||||
if (input == INPUT_LEFT) {
|
|
||||||
*aOpt->mToggle.mTog = false;
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
if (input == INPUT_RIGHT) {
|
|
||||||
*aOpt->mToggle.mTog = true;
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
if (input == INPUT_A) {
|
|
||||||
*aOpt->mToggle.mTog = !(*aOpt->mToggle.mTog);
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DOPT_CHOICE:
|
|
||||||
if (input == INPUT_LEFT) {
|
|
||||||
*aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + aOpt->mChoice.mChoices.Count() - 1) % (aOpt->mChoice.mChoices.Count());
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
if (input == INPUT_RIGHT || input == INPUT_A) {
|
|
||||||
*aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 1) % (aOpt->mChoice.mChoices.Count());
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DOPT_CHOICELEVEL:
|
|
||||||
if (input == INPUT_LEFT) {
|
|
||||||
*aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + DynOS_Level_GetCount() - 1) % (DynOS_Level_GetCount());
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
if (input == INPUT_RIGHT || input == INPUT_A) {
|
|
||||||
*aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 1) % (DynOS_Level_GetCount());
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DOPT_CHOICEAREA:
|
|
||||||
if (input == INPUT_LEFT) {
|
|
||||||
*aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 3) % (4);
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
if (input == INPUT_RIGHT || input == INPUT_A) {
|
|
||||||
*aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 1) % (4);
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DOPT_CHOICESTAR:
|
|
||||||
if (input == INPUT_LEFT) {
|
|
||||||
*aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 5) % (6);
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
if (input == INPUT_RIGHT || input == INPUT_A) {
|
|
||||||
*aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 1) % (6);
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DOPT_CHOICEPARAM:
|
|
||||||
if (input == INPUT_LEFT) {
|
|
||||||
*aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 4) % (5);
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
if (input == INPUT_RIGHT || input == INPUT_A) {
|
|
||||||
*aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 1) % (5);
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DOPT_SCROLL:
|
|
||||||
if (input == INPUT_LEFT) {
|
|
||||||
*aOpt->mScroll.mValue = MAX(aOpt->mScroll.mMin, *aOpt->mScroll.mValue - aOpt->mScroll.mStep * (gPlayer1Controller->buttonDown & A_BUTTON ? 5 : 1));
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
if (input == INPUT_RIGHT) {
|
|
||||||
*aOpt->mScroll.mValue = MIN(aOpt->mScroll.mMax, *aOpt->mScroll.mValue + aOpt->mScroll.mStep * (gPlayer1Controller->buttonDown & A_BUTTON ? 5 : 1));
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DOPT_BIND:
|
|
||||||
if (input == INPUT_LEFT) {
|
|
||||||
aOpt->mBind.mIndex = MAX(0, aOpt->mBind.mIndex - 1);
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
if (input == INPUT_RIGHT) {
|
|
||||||
aOpt->mBind.mIndex = MIN(2, aOpt->mBind.mIndex + 1);
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
if (input == INPUT_Z) {
|
|
||||||
aOpt->mBind.mBinds[aOpt->mBind.mIndex] = VK_INVALID;
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
if (input == INPUT_A) {
|
|
||||||
aOpt->mBind.mBinds[aOpt->mBind.mIndex] = VK_INVALID;
|
|
||||||
sBindingState = 1;
|
|
||||||
controller_get_raw_key();
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DOPT_BUTTON:
|
|
||||||
if (input == INPUT_A) {
|
|
||||||
DynosActionFunction _Action = DynOS_Opt_GetAction(aOpt->mButton.mFuncName);
|
|
||||||
if (_Action != NULL && _Action(aOpt->mName.begin())) {
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
return RESULT_CANCEL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DOPT_SUBMENU:
|
|
||||||
if (input == INPUT_A) {
|
|
||||||
if (aOpt->mSubMenu.mChild != NULL) {
|
|
||||||
sCurrentOpt = aOpt->mSubMenu.mChild;
|
|
||||||
return RESULT_OK;
|
|
||||||
}
|
|
||||||
return RESULT_CANCEL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return RESULT_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_Open(DynosOption *aMenu) {
|
|
||||||
play_sound(SOUND_DYNOS_SELECT, gGlobalSoundSource);
|
|
||||||
sCurrentMenu = aMenu;
|
|
||||||
sCurrentOpt = aMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_Close(bool aPlaySavedSfx) {
|
|
||||||
if (sCurrentMenu != NULL) {
|
|
||||||
if (aPlaySavedSfx) {
|
|
||||||
play_sound(SOUND_DYNOS_SAVED, gGlobalSoundSource);
|
|
||||||
}
|
|
||||||
#ifdef BETTERCAMERA
|
|
||||||
newcam_init_settings();
|
|
||||||
#endif
|
|
||||||
controller_reconfigure();
|
|
||||||
configfile_save(configfile_name());
|
|
||||||
DynOS_Opt_SaveConfig(sDynosMenu);
|
|
||||||
sCurrentMenu = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_ProcessInputs() {
|
|
||||||
static s32 sStickTimer = 0;
|
|
||||||
static bool sPrevStick = 0;
|
|
||||||
|
|
||||||
// Stick values
|
|
||||||
f32 _StickX = gPlayer1Controller->stickX;
|
|
||||||
f32 _StickY = gPlayer1Controller->stickY;
|
|
||||||
if (absx(_StickX) > 60 || absx(_StickY) > 60) {
|
|
||||||
if (sStickTimer == 0) {
|
|
||||||
sStickTimer = (sPrevStick ? 2 : 9);
|
|
||||||
} else {
|
|
||||||
_StickX = 0;
|
|
||||||
_StickY = 0;
|
|
||||||
sStickTimer--;
|
|
||||||
}
|
|
||||||
sPrevStick = true;
|
|
||||||
} else {
|
|
||||||
sStickTimer = 0;
|
|
||||||
sPrevStick = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Key binding
|
|
||||||
if (sBindingState != 0) {
|
|
||||||
u32 _Key = (sCurrentOpt->mDynos ? (u32) DynOS_Opt_ControllerGetKeyPressed() : controller_get_raw_key());
|
|
||||||
if (_Key != VK_INVALID) {
|
|
||||||
play_sound(SOUND_DYNOS_SELECT, gGlobalSoundSource);
|
|
||||||
sCurrentOpt->mBind.mBinds[sCurrentOpt->mBind.mIndex] = _Key;
|
|
||||||
sBindingState = false;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sCurrentMenu != NULL) {
|
|
||||||
|
|
||||||
// Up
|
|
||||||
if (_StickY > +60) {
|
|
||||||
if (sCurrentOpt->mPrev != NULL) {
|
|
||||||
sCurrentOpt = sCurrentOpt->mPrev;
|
|
||||||
} else {
|
|
||||||
while (sCurrentOpt->mNext) sCurrentOpt = sCurrentOpt->mNext;
|
|
||||||
}
|
|
||||||
play_sound(SOUND_DYNOS_SELECT, gGlobalSoundSource);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Down
|
|
||||||
if (_StickY < -60) {
|
|
||||||
if (sCurrentOpt->mNext != NULL) {
|
|
||||||
sCurrentOpt = sCurrentOpt->mNext;
|
|
||||||
} else {
|
|
||||||
while (sCurrentOpt->mPrev) sCurrentOpt = sCurrentOpt->mPrev;
|
|
||||||
}
|
|
||||||
play_sound(SOUND_DYNOS_SELECT, gGlobalSoundSource);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Left
|
|
||||||
if (_StickX < -60) {
|
|
||||||
switch (DynOS_Opt_ProcessInput(sCurrentOpt, INPUT_LEFT)) {
|
|
||||||
case RESULT_OK: play_sound(SOUND_DYNOS_OK, gGlobalSoundSource); break;
|
|
||||||
case RESULT_CANCEL: play_sound(SOUND_DYNOS_CANCEL, gGlobalSoundSource); break;
|
|
||||||
case RESULT_NONE: break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Right
|
|
||||||
if (_StickX > +60) {
|
|
||||||
switch (DynOS_Opt_ProcessInput(sCurrentOpt, INPUT_RIGHT)) {
|
|
||||||
case RESULT_OK: play_sound(SOUND_DYNOS_OK, gGlobalSoundSource); break;
|
|
||||||
case RESULT_CANCEL: play_sound(SOUND_DYNOS_CANCEL, gGlobalSoundSource); break;
|
|
||||||
case RESULT_NONE: break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A
|
|
||||||
if (gPlayer1Controller->buttonPressed & A_BUTTON) {
|
|
||||||
switch (DynOS_Opt_ProcessInput(sCurrentOpt, INPUT_A)) {
|
|
||||||
case RESULT_OK: play_sound(SOUND_DYNOS_OK, gGlobalSoundSource); break;
|
|
||||||
case RESULT_CANCEL: play_sound(SOUND_DYNOS_CANCEL, gGlobalSoundSource); break;
|
|
||||||
case RESULT_NONE: break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// B
|
|
||||||
if (gPlayer1Controller->buttonPressed & B_BUTTON) {
|
|
||||||
if (sCurrentOpt->mParent != NULL) {
|
|
||||||
sCurrentOpt = sCurrentOpt->mParent;
|
|
||||||
play_sound(SOUND_DYNOS_SELECT, gGlobalSoundSource);
|
|
||||||
} else {
|
|
||||||
DynOS_Opt_Close(true);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Z
|
|
||||||
if (gPlayer1Controller->buttonPressed & Z_TRIG) {
|
|
||||||
switch (DynOS_Opt_ProcessInput(sCurrentOpt, INPUT_Z)) {
|
|
||||||
case RESULT_OK: play_sound(SOUND_DYNOS_OK, gGlobalSoundSource); break;
|
|
||||||
case RESULT_CANCEL: play_sound(SOUND_DYNOS_CANCEL, gGlobalSoundSource); break;
|
|
||||||
case RESULT_NONE:
|
|
||||||
if (sCurrentMenu == sDynosMenu) {
|
|
||||||
DynOS_Opt_Close(true);
|
|
||||||
} else {
|
|
||||||
DynOS_Opt_Open(sDynosMenu);
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// R
|
|
||||||
if (gPlayer1Controller->buttonPressed & R_TRIG) {
|
|
||||||
if (sCurrentMenu == sOptionsMenu) {
|
|
||||||
DynOS_Opt_Close(true);
|
|
||||||
} else {
|
|
||||||
DynOS_Opt_Open(sOptionsMenu);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start
|
|
||||||
if (gPlayer1Controller->buttonPressed & START_BUTTON) {
|
|
||||||
DynOS_Opt_Close(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (gPlayer1Controller->buttonPressed & R_TRIG) {
|
|
||||||
DynOS_Opt_Open(sOptionsMenu);
|
|
||||||
} else if (gPlayer1Controller->buttonPressed & Z_TRIG) {
|
|
||||||
DynOS_Opt_Open(sDynosMenu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Init
|
|
||||||
//
|
|
||||||
|
|
||||||
static void DynOS_Opt_CreateWarpToLevelSubMenu() {
|
|
||||||
DynOS_Opt_CreateSubMenu("dynos_warp_to_level_submenu", "Warp to Level", "WARP TO LEUEL");
|
|
||||||
|
|
||||||
// Level select
|
|
||||||
{
|
|
||||||
DynosOption *aOpt = DynOS_Opt_NewOption("dynos_warp_level", "", "Level Select", "");
|
|
||||||
aOpt->mType = DOPT_CHOICELEVEL;
|
|
||||||
aOpt->mChoice.mIndex = New<s32>();
|
|
||||||
*aOpt->mChoice.mIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Area select
|
|
||||||
{
|
|
||||||
DynosOption *aOpt = DynOS_Opt_NewOption("dynos_warp_area", "", "Area Select", "");
|
|
||||||
aOpt->mType = DOPT_CHOICEAREA;
|
|
||||||
aOpt->mChoice.mIndex = New<s32>();
|
|
||||||
*aOpt->mChoice.mIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Star select
|
|
||||||
{
|
|
||||||
DynosOption *aOpt = DynOS_Opt_NewOption("dynos_warp_act", "", "Star Select", "");
|
|
||||||
aOpt->mType = DOPT_CHOICESTAR;
|
|
||||||
aOpt->mChoice.mIndex = New<s32>();
|
|
||||||
*aOpt->mChoice.mIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param select
|
|
||||||
{
|
|
||||||
DynosOption *aOpt = DynOS_Opt_NewOption("dynos_warp_param", "", "Param Select", "");
|
|
||||||
aOpt->mType = DOPT_CHOICEPARAM;
|
|
||||||
aOpt->mChoice.mIndex = New<s32>();
|
|
||||||
*aOpt->mChoice.mIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynOS_Opt_CreateButton("dynos_warp_to_level", "Warp", "DynOS_Opt_WarpToLevel");
|
|
||||||
DynOS_Opt_EndSubMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_CreateWarpToCastleSubMenu() {
|
|
||||||
DynOS_Opt_CreateSubMenu("dynos_warp_to_castle_submenu", "Warp to Castle", "WARP TO CASTLE");
|
|
||||||
|
|
||||||
// Level select
|
|
||||||
{
|
|
||||||
DynosOption *aOpt = DynOS_Opt_NewOption("dynos_warp_castle", "", "Level Exit", "");
|
|
||||||
aOpt->mType = DOPT_CHOICELEVEL;
|
|
||||||
aOpt->mChoice.mIndex = New<s32>();
|
|
||||||
*aOpt->mChoice.mIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynOS_Opt_CreateButton("dynos_warp_to_castle", "Warp", "DynOS_Opt_WarpToCastle");
|
|
||||||
DynOS_Opt_EndSubMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 DynOS_Opt_GetHash(const String& aStr) {
|
|
||||||
u32 _Hash = 5381u;
|
|
||||||
for (char c : aStr) { _Hash += c + (_Hash << 5); }
|
|
||||||
return _Hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_CreateModelPacksSubMenu() {
|
|
||||||
/*Array<String> _Packs = DynOS_Gfx_Init();
|
|
||||||
if (_Packs.Count() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynOS_Opt_CreateSubMenu("dynos_model_loader_submenu", "Model Packs", "MODEL PACKS");
|
|
||||||
for (s32 i = 0; i != _Packs.Count(); ++i) {
|
|
||||||
DynOS_Opt_CreateToggle(String("dynos_pack_%d", i), String("dynos_pack_%08X", DynOS_Opt_GetHash(_Packs[i])), _Packs[i], false);
|
|
||||||
}
|
|
||||||
DynOS_Opt_CreateButton("dynos_packs_disable_all", "Disable all packs", "DynOS_Opt_DisableAllPacks");
|
|
||||||
DynOS_Opt_EndSubMenu();*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void DynOS_Opt_Init() {
|
|
||||||
|
|
||||||
#ifdef COOP
|
|
||||||
#else
|
|
||||||
// Convert options menu
|
|
||||||
DynOS_Opt_InitVanilla(sOptionsMenu);
|
|
||||||
|
|
||||||
// Warp to level
|
|
||||||
DynOS_Opt_CreateWarpToLevelSubMenu();
|
|
||||||
|
|
||||||
// Warp to castle
|
|
||||||
DynOS_Opt_CreateWarpToCastleSubMenu();
|
|
||||||
|
|
||||||
// Restart level
|
|
||||||
DynOS_Opt_CreateButton("dynos_restart_level", "Restart Level", "DynOS_Opt_RestartLevel");
|
|
||||||
|
|
||||||
// Exit level
|
|
||||||
DynOS_Opt_CreateButton("dynos_exit_level", "Exit Level", "DynOS_Opt_ExitLevel");
|
|
||||||
|
|
||||||
// Return to main menu
|
|
||||||
DynOS_Opt_CreateButton("dynos_return_to_main_menu", "Return to Main Menu", "DynOS_Opt_ReturnToMainMenu");
|
|
||||||
|
|
||||||
// Model loader
|
|
||||||
DynOS_Opt_CreateModelPacksSubMenu();
|
|
||||||
|
|
||||||
// Init config
|
|
||||||
DynOS_Opt_LoadConfig(sDynosMenu);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Update
|
|
||||||
//
|
|
||||||
|
|
||||||
void DynOS_Opt_Update(OSContPad *aPad) {
|
|
||||||
DynOS_Opt_Loop(sDynosMenu, DynOS_Opt_ControllerUpdate, (void *) aPad);
|
|
||||||
#ifndef COOP
|
|
||||||
if (DynOS_IsTransitionActive()) {
|
|
||||||
aPad->button = 0;
|
|
||||||
aPad->stick_x = 0;
|
|
||||||
aPad->stick_y = 0;
|
|
||||||
aPad->ext_stick_x = 0;
|
|
||||||
aPad->ext_stick_y = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Hijack
|
|
||||||
// This is C code
|
|
||||||
//
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
u8 optmenu_open = 0;
|
|
||||||
|
|
||||||
void optmenu_toggle(void) {
|
|
||||||
DynOS_Opt_Close(false);
|
|
||||||
optmenu_open = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void optmenu_draw(void) {
|
|
||||||
DynOS_Opt_DrawMenu(sCurrentOpt, sCurrentMenu, sOptionsMenu, sDynosMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
void optmenu_draw_prompt(void) {
|
|
||||||
DynOS_Opt_DrawPrompt(sCurrentMenu, sOptionsMenu, sDynosMenu);
|
|
||||||
DynOS_Opt_ProcessInputs();
|
|
||||||
optmenu_open = (sCurrentMenu != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void optmenu_check_buttons(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Built-in options
|
|
||||||
//
|
|
||||||
|
|
||||||
#define DYNOS_DEFINE_ACTION(func) \
|
|
||||||
DYNOS_AT_STARTUP static void DynOS_Opt_AddAction_##func() { \
|
|
||||||
DynOS_Opt_AddAction(#func, func, false); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef COOP
|
|
||||||
|
|
||||||
static bool DynOS_Opt_ReturnToMainMenu(UNUSED const char *optName) {
|
|
||||||
DynOS_ReturnToMainMenu();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
DYNOS_DEFINE_ACTION(DynOS_Opt_ReturnToMainMenu);
|
|
||||||
|
|
||||||
static bool DynOS_Opt_WarpToLevel(UNUSED const char *optName) {
|
|
||||||
s32 _Level = DynOS_Level_GetList()[DynOS_Opt_GetValue("dynos_warp_level")];
|
|
||||||
s32 _Area = DynOS_Opt_GetValue("dynos_warp_area") + 1;
|
|
||||||
s32 _Act = DynOS_Opt_GetValue("dynos_warp_act") + 1;
|
|
||||||
return DynOS_Warp_ToLevel(_Level, _Area, _Act);
|
|
||||||
}
|
|
||||||
DYNOS_DEFINE_ACTION(DynOS_Opt_WarpToLevel);
|
|
||||||
|
|
||||||
static bool DynOS_Opt_WarpToCastle(UNUSED const char *optName) {
|
|
||||||
s32 _Level = DynOS_Level_GetList()[DynOS_Opt_GetValue("dynos_warp_castle")];
|
|
||||||
return DynOS_Warp_ToCastle(_Level);
|
|
||||||
}
|
|
||||||
DYNOS_DEFINE_ACTION(DynOS_Opt_WarpToCastle);
|
|
||||||
|
|
||||||
static bool DynOS_Opt_RestartLevel(UNUSED const char *optName) {
|
|
||||||
return DynOS_Warp_RestartLevel();
|
|
||||||
}
|
|
||||||
DYNOS_DEFINE_ACTION(DynOS_Opt_RestartLevel);
|
|
||||||
|
|
||||||
static bool DynOS_Opt_ExitLevel(UNUSED const char *optName) {
|
|
||||||
return DynOS_Warp_ExitLevel(30);
|
|
||||||
}
|
|
||||||
DYNOS_DEFINE_ACTION(DynOS_Opt_ExitLevel);
|
|
||||||
|
|
||||||
static bool DynOS_Opt_DisableAllPacks(UNUSED const char *optName) {
|
|
||||||
const Array<PackData *> &pDynosPacks = DynOS_Gfx_GetPacks();
|
|
||||||
for (s32 i = 0; i != pDynosPacks.Count(); ++i) {
|
|
||||||
DynOS_Opt_SetValue(String("dynos_pack_%d", i), false);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
DYNOS_DEFINE_ACTION(DynOS_Opt_DisableAllPacks);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef DYNOS_DEFINE_ACTION
|
|
|
@ -1,67 +0,0 @@
|
||||||
#include "dynos.cpp.h"
|
|
||||||
|
|
||||||
extern DynosOption *DynOS_Opt_Loop(DynosOption *aOpt, DynosLoopFunc aFunc, void *aData);
|
|
||||||
|
|
||||||
static bool DynOS_Opt_ReadConfig(DynosOption *aOpt, void *aData) {
|
|
||||||
return (aOpt->mConfigName == (const char *) aData);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DynOS_Opt_LoadConfig(DynosOption *aMenu) {
|
|
||||||
SysPath _Filename = fstring("%s/%s", DYNOS_USER_FOLDER, DYNOS_CONFIG_FILENAME);
|
|
||||||
FILE *_File = fopen(_Filename.c_str(), "r");
|
|
||||||
if (_File) {
|
|
||||||
char _Buffer[1024];
|
|
||||||
while (fgets(_Buffer, 1024, _File)) {
|
|
||||||
|
|
||||||
// Option strings
|
|
||||||
char *_NameBegin = _Buffer;
|
|
||||||
char *_DataBegin = strchr(_NameBegin, '=');
|
|
||||||
if (_NameBegin && _DataBegin) {
|
|
||||||
*(_DataBegin++) = 0;
|
|
||||||
|
|
||||||
// Option name
|
|
||||||
String _OptName = String(_NameBegin);
|
|
||||||
DynosOption *_Opt = DynOS_Opt_Loop(aMenu, DynOS_Opt_ReadConfig, (void *) _OptName.begin());
|
|
||||||
if (_Opt) {
|
|
||||||
|
|
||||||
// Option values
|
|
||||||
switch (_Opt->mType) {
|
|
||||||
case DOPT_TOGGLE: {
|
|
||||||
unsigned char boolValue = 0;
|
|
||||||
sscanf(_DataBegin, "%hhu\n", &boolValue);
|
|
||||||
_Opt->mToggle.mTog[0] = boolValue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DOPT_CHOICE: sscanf(_DataBegin, "%d\n", &_Opt->mChoice.mIndex[0]); break;
|
|
||||||
case DOPT_SCROLL: sscanf(_DataBegin, "%d\n", &_Opt->mScroll.mValue[0]); break;
|
|
||||||
case DOPT_BIND: sscanf(_DataBegin, "%04X;%04X;%04X\n", &_Opt->mBind.mBinds[0], &_Opt->mBind.mBinds[1], &_Opt->mBind.mBinds[2]); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(_File);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool DynOS_Opt_WriteConfig(DynosOption *aOpt, void *aData) {
|
|
||||||
if (aOpt->mConfigName.Length() != 0 &&
|
|
||||||
aOpt->mConfigName != "null" &&
|
|
||||||
aOpt->mConfigName != "NULL") {
|
|
||||||
switch (aOpt->mType) {
|
|
||||||
case DOPT_TOGGLE: fprintf((FILE *) aData, "%s=%hhu\n", aOpt->mConfigName.begin(), aOpt->mToggle.mTog[0]); break;
|
|
||||||
case DOPT_CHOICE: fprintf((FILE *) aData, "%s=%d\n", aOpt->mConfigName.begin(), aOpt->mChoice.mIndex[0]); break;
|
|
||||||
case DOPT_SCROLL: fprintf((FILE *) aData, "%s=%d\n", aOpt->mConfigName.begin(), aOpt->mScroll.mValue[0]); break;
|
|
||||||
case DOPT_BIND: fprintf((FILE *) aData, "%s=%04X;%04X;%04X\n", aOpt->mConfigName.begin(), aOpt->mBind.mBinds[0], aOpt->mBind.mBinds[1], aOpt->mBind.mBinds[2]); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DynOS_Opt_SaveConfig(DynosOption *aMenu) {
|
|
||||||
SysPath _Filename = fstring("%s/%s", DYNOS_USER_FOLDER, DYNOS_CONFIG_FILENAME);
|
|
||||||
FILE *_File = fopen(_Filename.c_str(), "w");
|
|
||||||
if (_File) {
|
|
||||||
DynOS_Opt_Loop(aMenu, DynOS_Opt_WriteConfig, (void *) _File);
|
|
||||||
fclose(_File);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
#include "dynos.cpp.h"
|
|
||||||
extern "C" {
|
|
||||||
#include "pc/controller/controller_api.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool DynOS_Opt_ControllerIsKeyDown(s32 aCont, s32 aKey) {
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
// Keyboard
|
|
||||||
if (aCont == 0 && aKey >= 0 && aKey < SDL_NUM_SCANCODES) {
|
|
||||||
return SDL_GetKeyboardState(NULL)[aKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Game Controller
|
|
||||||
else if (aKey >= 0x1000) {
|
|
||||||
|
|
||||||
// Button
|
|
||||||
s32 _Button = (aKey - 0x1000);
|
|
||||||
if (_Button < SDL_CONTROLLER_BUTTON_MAX) {
|
|
||||||
return SDL_GameControllerGetButton(SDL_GameControllerOpen(aCont - 1), SDL_GameControllerButton(_Button));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Axis
|
|
||||||
s32 _Axis = (aKey - 0x1000 - SDL_CONTROLLER_BUTTON_MAX);
|
|
||||||
if (_Axis < SDL_CONTROLLER_AXIS_MAX * 2) {
|
|
||||||
s32 _AxisValue = SDL_GameControllerGetAxis(SDL_GameControllerOpen(aCont - 1), SDL_GameControllerAxis(_Axis / 2));
|
|
||||||
if (_Axis & 1) return (_AxisValue < (SHRT_MIN / 2));
|
|
||||||
else return (_AxisValue > (SHRT_MAX / 2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Invalid
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_CONTS 8
|
|
||||||
bool DynOS_Opt_ControllerUpdate(DynosOption *aOpt, void *aData) {
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
if (aOpt->mType == DOPT_BIND) {
|
|
||||||
OSContPad *pad = (OSContPad *) aData;
|
|
||||||
for (s32 _Cont = 0; _Cont < MAX_CONTS; ++_Cont)
|
|
||||||
for (s32 _Bind = 0; _Bind < 3; ++_Bind) {
|
|
||||||
pad->button |= aOpt->mBind.mMask * DynOS_Opt_ControllerIsKeyDown(_Cont, aOpt->mBind.mBinds[_Bind]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_GKEYS (SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_AXIS_MAX * 2)
|
|
||||||
s32 sBindingState = 0; // 0 = No bind, 1 = Wait for all keys released, 2 = Return first pressed key
|
|
||||||
s32 DynOS_Opt_ControllerGetKeyPressed() {
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
|
|
||||||
// Keyboard
|
|
||||||
for (s32 _Key = 0; _Key < SDL_NUM_SCANCODES; ++_Key) {
|
|
||||||
if (DynOS_Opt_ControllerIsKeyDown(0, _Key)) {
|
|
||||||
if (sBindingState == 1) return VK_INVALID;
|
|
||||||
return _Key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Game Controller
|
|
||||||
for (s32 _Cont = 1; _Cont < MAX_CONTS; ++_Cont)
|
|
||||||
for (s32 _Key = 0; _Key < MAX_GKEYS; ++_Key) {
|
|
||||||
if (DynOS_Opt_ControllerIsKeyDown(_Cont, _Key + 0x1000)) {
|
|
||||||
if (sBindingState == 1) return VK_INVALID;
|
|
||||||
return _Key + 0x1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No key
|
|
||||||
sBindingState = 2;
|
|
||||||
#endif
|
|
||||||
return VK_INVALID;
|
|
||||||
}
|
|
|
@ -1,309 +0,0 @@
|
||||||
#include "dynos.cpp.h"
|
|
||||||
extern "C" {
|
|
||||||
#include "course_table.h"
|
|
||||||
#include "game/game_init.h"
|
|
||||||
#include "game/ingame_menu.h"
|
|
||||||
#include "game/segment2.h"
|
|
||||||
#include "pc/controller/controller_api.h"
|
|
||||||
#include "gfx_dimensions.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
extern s32 sBindingState;
|
|
||||||
|
|
||||||
#define DYNOS_TEXT_DYNOS_MENU { "DYNOS MENU", NULL }
|
|
||||||
#define DYNOS_TEXT_A { "([A]) >", NULL }
|
|
||||||
#define DYNOS_TEXT_OPEN_LEFT { "[Z] DynOS", NULL }
|
|
||||||
#define DYNOS_TEXT_CLOSE_LEFT { "[Z] Return", NULL }
|
|
||||||
#define DYNOS_TEXT_OPTIONS_MENU { "OPTIONS", NULL }
|
|
||||||
#define DYNOS_TEXT_DISABLED { "Disabled", NULL }
|
|
||||||
#define DYNOS_TEXT_ENABLED { "Enabled", NULL }
|
|
||||||
#define DYNOS_TEXT_NONE { "NONE", NULL }
|
|
||||||
#define DYNOS_TEXT_DOT_DOT_DOT { "...", NULL }
|
|
||||||
#define DYNOS_TEXT_OPEN_RIGHT { "[R] Options", NULL }
|
|
||||||
#define DYNOS_TEXT_CLOSE_RIGHT { "[R] Return", NULL }
|
|
||||||
|
|
||||||
static void RenderString(const u8 *aStr64, s32 aX, s32 aY) {
|
|
||||||
create_dl_translation_matrix(MENU_MTX_PUSH, aX, aY, 0);
|
|
||||||
for (; *aStr64 != DIALOG_CHAR_TERMINATOR; ++aStr64) {
|
|
||||||
if (*aStr64 != DIALOG_CHAR_SPACE) {
|
|
||||||
void **fontLUT = (void **) segmented_to_virtual(main_font_lut);
|
|
||||||
void *packedTexture = segmented_to_virtual(fontLUT[*aStr64]);
|
|
||||||
gDPPipeSync(gDisplayListHead++);
|
|
||||||
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, VIRTUAL_TO_PHYSICAL(packedTexture));
|
|
||||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings);
|
|
||||||
}
|
|
||||||
create_dl_translation_matrix(MENU_MTX_NOPUSH, DynOS_String_WidthChar64(*aStr64), 0, 0);
|
|
||||||
}
|
|
||||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void PrintString(const Label& aLabel, s32 aX, s32 aY, u32 aFrontColorRGBA, u32 aBackColorRGBA, bool aAlignLeft) {
|
|
||||||
const u8 *_Str64 = (aLabel.second ? aLabel.second : DynOS_String_Convert(aLabel.first.begin(), false));
|
|
||||||
|
|
||||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
|
||||||
if ((aBackColorRGBA & 0xFF) != 0) {
|
|
||||||
gDPSetEnvColor(gDisplayListHead++, ((aBackColorRGBA >> 24) & 0xFF), ((aBackColorRGBA >> 16) & 0xFF), ((aBackColorRGBA >> 8) & 0xFF), ((aBackColorRGBA >> 0) & 0xFF));
|
|
||||||
if (aAlignLeft) {
|
|
||||||
RenderString(_Str64, GFX_DIMENSIONS_FROM_LEFT_EDGE(aX) + 1, aY - 1);
|
|
||||||
} else {
|
|
||||||
RenderString(_Str64, GFX_DIMENSIONS_FROM_RIGHT_EDGE(aX + DynOS_String_Width(_Str64) - 1), aY - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((aFrontColorRGBA & 0xFF) != 0) {
|
|
||||||
gDPSetEnvColor(gDisplayListHead++, ((aFrontColorRGBA >> 24) & 0xFF), ((aFrontColorRGBA >> 16) & 0xFF), ((aFrontColorRGBA >> 8) & 0xFF), ((aFrontColorRGBA >> 0) & 0xFF));
|
|
||||||
if (aAlignLeft) {
|
|
||||||
RenderString(_Str64, GFX_DIMENSIONS_FROM_LEFT_EDGE(aX), aY);
|
|
||||||
} else {
|
|
||||||
RenderString(_Str64, GFX_DIMENSIONS_FROM_RIGHT_EDGE(aX + DynOS_String_Width(_Str64)), aY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
|
||||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void PrintBox(s32 aX, s32 aY, s32 aWidth, s32 aHeight, u32 aColorRGBA, bool aAlignLeft) {
|
|
||||||
if ((aColorRGBA & 0xFF) != 0) {
|
|
||||||
Mtx *_Matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
|
||||||
if (!_Matrix) return;
|
|
||||||
if (aAlignLeft) {
|
|
||||||
create_dl_translation_matrix(MENU_MTX_PUSH, GFX_DIMENSIONS_FROM_LEFT_EDGE(aX), aY + aHeight, 0);
|
|
||||||
} else {
|
|
||||||
create_dl_translation_matrix(MENU_MTX_PUSH, GFX_DIMENSIONS_FROM_RIGHT_EDGE(aX + aWidth), aY + aHeight, 0);
|
|
||||||
}
|
|
||||||
guScale(_Matrix, (f32) aWidth / 130.f, (f32) aHeight / 80.f, 1.f);
|
|
||||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(_Matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
|
||||||
gDPSetEnvColor(gDisplayListHead++, ((aColorRGBA >> 24) & 0xFF), ((aColorRGBA >> 16) & 0xFF), ((aColorRGBA >> 8) & 0xFF), ((aColorRGBA >> 0) & 0xFF));
|
|
||||||
gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box);
|
|
||||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
|
||||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *IntToString(const char *fmt, s32 x) {
|
|
||||||
static char sBuffer[16];
|
|
||||||
snprintf(sBuffer, 16, fmt, x);
|
|
||||||
return sBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define get_label(opt) (opt->mLabel)
|
|
||||||
#define get_title(opt) (opt->mTitle)
|
|
||||||
#define get_choice(opt) (opt->mChoice.mChoices[*opt->mChoice.mIndex])
|
|
||||||
#define get_dec_number(n) { "", DynOS_String_Convert(IntToString("%d", n), false) }
|
|
||||||
#define get_hex_number(n) { "", DynOS_String_Convert(IntToString("%04X", n), false) }
|
|
||||||
#define get_level(opt) { "", DynOS_Level_GetName(DynOS_Level_GetList()[*opt->mChoice.mIndex], true, true) }
|
|
||||||
#define get_star(opt) { "", DynOS_Level_GetActName(DynOS_Level_GetList()[DynOS_Opt_GetValue("dynos_warp_level")], *opt->mChoice.mIndex + 1, true, true) }
|
|
||||||
#define get_param(opt) { DynOS_Warp_GetParamName(DynOS_Level_GetList()[DynOS_Opt_GetValue("dynos_warp_level")], *opt->mChoice.mIndex), NULL }
|
|
||||||
|
|
||||||
static s32 GetCurrentOptionCount(DynosOption *aCurrentOpt) {
|
|
||||||
s32 _Count = 0;
|
|
||||||
while (aCurrentOpt->mPrev) { aCurrentOpt = aCurrentOpt->mPrev; }
|
|
||||||
while (aCurrentOpt) { aCurrentOpt = aCurrentOpt->mNext; _Count++; }
|
|
||||||
return _Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static s32 GetCurrentOptionIndex(DynosOption *aCurrentOpt) {
|
|
||||||
s32 _Index = 0;
|
|
||||||
while (aCurrentOpt->mPrev) { aCurrentOpt = aCurrentOpt->mPrev; _Index++; }
|
|
||||||
return _Index;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PREV(opt) (opt == NULL ? NULL : opt->mPrev)
|
|
||||||
#define NEXT(opt) (opt == NULL ? NULL : opt->mNext)
|
|
||||||
static DynosOption **GetCurrentOptions(DynosOption *aCurrentOpt) {
|
|
||||||
static DynosOption *sOptionList[13];
|
|
||||||
|
|
||||||
sOptionList[6] = aCurrentOpt;
|
|
||||||
sOptionList[5] = PREV(sOptionList[6]);
|
|
||||||
sOptionList[4] = PREV(sOptionList[5]);
|
|
||||||
sOptionList[3] = PREV(sOptionList[4]);
|
|
||||||
sOptionList[2] = PREV(sOptionList[3]);
|
|
||||||
sOptionList[1] = PREV(sOptionList[2]);
|
|
||||||
sOptionList[0] = PREV(sOptionList[1]);
|
|
||||||
sOptionList[7] = NEXT(sOptionList[6]);
|
|
||||||
sOptionList[8] = NEXT(sOptionList[7]);
|
|
||||||
sOptionList[9] = NEXT(sOptionList[8]);
|
|
||||||
sOptionList[10] = NEXT(sOptionList[9]);
|
|
||||||
sOptionList[11] = NEXT(sOptionList[10]);
|
|
||||||
sOptionList[12] = NEXT(sOptionList[11]);
|
|
||||||
|
|
||||||
s32 _StartIndex = 12, _EndIndex = 0;
|
|
||||||
for (s32 i = 0; i != 13; ++i) {
|
|
||||||
if (sOptionList[i] != NULL) {
|
|
||||||
_StartIndex = MIN(_StartIndex, i);
|
|
||||||
_EndIndex = MAX(_EndIndex, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_EndIndex - _StartIndex < 7) {
|
|
||||||
return &sOptionList[_StartIndex];
|
|
||||||
}
|
|
||||||
if (_EndIndex <= 9) {
|
|
||||||
return &sOptionList[_EndIndex - 6];
|
|
||||||
}
|
|
||||||
if (_StartIndex >= 3) {
|
|
||||||
return &sOptionList[_StartIndex];
|
|
||||||
}
|
|
||||||
return &sOptionList[3];
|
|
||||||
}
|
|
||||||
#undef PREV
|
|
||||||
#undef NEXT
|
|
||||||
|
|
||||||
#define COLOR_WHITE 0xFFFFFFFF
|
|
||||||
#define COLOR_BLACK 0x000000FF
|
|
||||||
#define COLOR_GRAY 0xA0A0A0FF
|
|
||||||
#define COLOR_DARK_GRAY 0x808080FF
|
|
||||||
#define COLOR_SELECT 0x80E0FFFF
|
|
||||||
#define COLOR_SELECT_BOX 0x00FFFF20
|
|
||||||
#define COLOR_ENABLED 0x20E020FF
|
|
||||||
#define COLOR_DISABLED 0xFF2020FF
|
|
||||||
#define OFFSET_FROM_LEFT_EDGE (20.f * sqr(GFX_DIMENSIONS_ASPECT_RATIO))
|
|
||||||
#define OFFSET_FROM_RIGHT_EDGE (20.f * sqr(GFX_DIMENSIONS_ASPECT_RATIO))
|
|
||||||
#define SCROLL_BAR_SIZE ((s32) (45.f * GFX_DIMENSIONS_ASPECT_RATIO))
|
|
||||||
|
|
||||||
static void DynOS_Opt_DrawOption(DynosOption *aOpt, DynosOption *aCurrentOpt, s32 aY) {
|
|
||||||
if (aOpt == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Selected box
|
|
||||||
if (aOpt == aCurrentOpt) {
|
|
||||||
u8 _Alpha = (u8) ((coss(gGlobalTimer * 0x800) + 1.f) * 0x20);
|
|
||||||
PrintBox(OFFSET_FROM_LEFT_EDGE - 4, aY - 2, GFX_DIMENSIONS_FROM_RIGHT_EDGE(OFFSET_FROM_RIGHT_EDGE) - GFX_DIMENSIONS_FROM_LEFT_EDGE(OFFSET_FROM_LEFT_EDGE) + 8, 20, COLOR_SELECT_BOX + _Alpha, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Label
|
|
||||||
if (aOpt == aCurrentOpt) {
|
|
||||||
PrintString(get_label(aOpt), OFFSET_FROM_LEFT_EDGE, aY, COLOR_SELECT, COLOR_BLACK, 1);
|
|
||||||
} else {
|
|
||||||
PrintString(get_label(aOpt), OFFSET_FROM_LEFT_EDGE, aY, COLOR_WHITE, COLOR_BLACK, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Values
|
|
||||||
switch (aOpt->mType) {
|
|
||||||
case DOPT_TOGGLE: {
|
|
||||||
if (*aOpt->mToggle.mTog) {
|
|
||||||
PrintString(DYNOS_TEXT_ENABLED, OFFSET_FROM_RIGHT_EDGE, aY, COLOR_ENABLED, COLOR_BLACK, 0);
|
|
||||||
} else {
|
|
||||||
PrintString(DYNOS_TEXT_DISABLED, OFFSET_FROM_RIGHT_EDGE, aY, COLOR_DISABLED, COLOR_BLACK, 0);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DOPT_CHOICE: {
|
|
||||||
PrintString(get_choice(aOpt), OFFSET_FROM_RIGHT_EDGE, aY, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, COLOR_BLACK, 0);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DOPT_CHOICELEVEL: {
|
|
||||||
PrintString(get_level(aOpt), OFFSET_FROM_RIGHT_EDGE, aY, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, COLOR_BLACK, 0);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DOPT_CHOICEAREA: {
|
|
||||||
s32 _Level = DynOS_Level_GetList()[DynOS_Opt_GetValue("dynos_warp_level")];
|
|
||||||
s32 _Area = *aOpt->mChoice.mIndex + 1;
|
|
||||||
const u8 *_Name = DynOS_Level_GetAreaName(_Level, _Area, true);
|
|
||||||
if (DynOS_Level_GetWarpEntry(_Level, _Area)) {
|
|
||||||
PrintString({ "", _Name }, OFFSET_FROM_RIGHT_EDGE, aY, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, COLOR_BLACK, 0);
|
|
||||||
} else {
|
|
||||||
PrintString({ "", _Name }, OFFSET_FROM_RIGHT_EDGE, aY, COLOR_GRAY, COLOR_BLACK, 0);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DOPT_CHOICESTAR: {
|
|
||||||
s32 _Course = DynOS_Level_GetCourse(DynOS_Level_GetList()[DynOS_Opt_GetValue("dynos_warp_level")]);
|
|
||||||
if (_Course >= COURSE_MIN && _Course <= COURSE_STAGES_MAX) {
|
|
||||||
PrintString(get_star(aOpt), OFFSET_FROM_RIGHT_EDGE, aY, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, COLOR_BLACK, 0);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DOPT_CHOICEPARAM: {
|
|
||||||
PrintString(get_param(aOpt), OFFSET_FROM_RIGHT_EDGE, aY, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, COLOR_BLACK, 0);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DOPT_SCROLL: {
|
|
||||||
s32 _Width = (s32) (SCROLL_BAR_SIZE * (f32) (*aOpt->mScroll.mValue - aOpt->mScroll.mMin) / (f32) (aOpt->mScroll.mMax - aOpt->mScroll.mMin));
|
|
||||||
PrintString(get_dec_number(*aOpt->mScroll.mValue), OFFSET_FROM_RIGHT_EDGE, aY, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, COLOR_BLACK, 0);
|
|
||||||
PrintBox(OFFSET_FROM_RIGHT_EDGE + 28, aY + 4, SCROLL_BAR_SIZE + 2, 8, COLOR_DARK_GRAY, 0);
|
|
||||||
PrintBox(OFFSET_FROM_RIGHT_EDGE + 29 + SCROLL_BAR_SIZE - _Width, aY + 5, _Width, 6, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, 0);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DOPT_BIND: {
|
|
||||||
for (s32 i = 0; i != 3; ++i) {
|
|
||||||
u32 _Bind = aOpt->mBind.mBinds[i];
|
|
||||||
if (aOpt == aCurrentOpt && i == aOpt->mBind.mIndex) {
|
|
||||||
if (sBindingState != 0) {
|
|
||||||
PrintString(DYNOS_TEXT_DOT_DOT_DOT, OFFSET_FROM_RIGHT_EDGE + (2 - i) * 36, aY, COLOR_SELECT, COLOR_BLACK, 0);
|
|
||||||
} else if (_Bind == VK_INVALID) {
|
|
||||||
PrintString(DYNOS_TEXT_NONE, OFFSET_FROM_RIGHT_EDGE + (2 - i) * 36, aY, COLOR_SELECT, COLOR_BLACK, 0);
|
|
||||||
} else {
|
|
||||||
PrintString(get_hex_number(_Bind), OFFSET_FROM_RIGHT_EDGE + (2 - i) * 36, aY, COLOR_SELECT, COLOR_BLACK, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (_Bind == VK_INVALID) {
|
|
||||||
PrintString(DYNOS_TEXT_NONE, OFFSET_FROM_RIGHT_EDGE + (2 - i) * 36, aY, COLOR_GRAY, COLOR_BLACK, 0);
|
|
||||||
} else {
|
|
||||||
PrintString(get_hex_number(_Bind), OFFSET_FROM_RIGHT_EDGE + (2 - i) * 36, aY, COLOR_WHITE, COLOR_BLACK, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DOPT_BUTTON: {
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DOPT_SUBMENU: {
|
|
||||||
if (aOpt == aCurrentOpt) {
|
|
||||||
PrintString(DYNOS_TEXT_A, OFFSET_FROM_RIGHT_EDGE, aY, COLOR_SELECT, COLOR_BLACK, 0);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DynOS_Opt_DrawMenu(DynosOption *aCurrentOption, DynosOption *aCurrentMenu, DynosOption *aOptionsMenu, DynosOption *aDynosMenu) {
|
|
||||||
if (aCurrentMenu == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Colorful label
|
|
||||||
Label _Title;
|
|
||||||
if (aCurrentOption->mParent) {
|
|
||||||
_Title = get_title(aCurrentOption->mParent);
|
|
||||||
} else if (aCurrentMenu == aDynosMenu) {
|
|
||||||
_Title = DYNOS_TEXT_DYNOS_MENU;
|
|
||||||
} else if (aCurrentMenu == aOptionsMenu) {
|
|
||||||
_Title = DYNOS_TEXT_OPTIONS_MENU;
|
|
||||||
}
|
|
||||||
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
|
||||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
|
||||||
if (!_Title.second) _Title.second = DynOS_String_Convert(_Title.first.begin(), false);
|
|
||||||
print_hud_lut_string(HUD_LUT_GLOBAL, (SCREEN_WIDTH / 2 - DynOS_String_Length(_Title.second) * 6), 40, _Title.second);
|
|
||||||
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
|
|
||||||
|
|
||||||
// Display options
|
|
||||||
DynosOption **_Options = GetCurrentOptions(aCurrentOption);
|
|
||||||
for (s32 i = 0; i != 7; ++i) {
|
|
||||||
DynOS_Opt_DrawOption(_Options[i], aCurrentOption, 156 - 20 * i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scroll bar
|
|
||||||
s32 _OptCount = GetCurrentOptionCount(aCurrentOption);
|
|
||||||
s32 _OptIndex = GetCurrentOptionIndex(aCurrentOption);
|
|
||||||
if (_OptCount > 7) {
|
|
||||||
s32 _Height = (s32) (134.f * sqrtf(1.f / (_OptCount - 6)));
|
|
||||||
s32 _Y = 37 + (134 - _Height) * (1.f - MAX(0.f, MIN(1.f, (f32)(_OptIndex - 3) / (f32)(_OptCount - 6))));
|
|
||||||
PrintBox(OFFSET_FROM_RIGHT_EDGE - 16, 36, 8, 136, COLOR_DARK_GRAY, 0);
|
|
||||||
PrintBox(OFFSET_FROM_RIGHT_EDGE - 15, _Y, 6, _Height, COLOR_WHITE, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PROMPT_OFFSET (56.25f * GFX_DIMENSIONS_ASPECT_RATIO)
|
|
||||||
void DynOS_Opt_DrawPrompt(DynosOption *aCurrentMenu, DynosOption *aOptionsMenu, DynosOption *aDynosMenu) {
|
|
||||||
if (aCurrentMenu == aOptionsMenu) {
|
|
||||||
PrintString(DYNOS_TEXT_OPEN_LEFT, PROMPT_OFFSET, 212, COLOR_WHITE, COLOR_BLACK, 1);
|
|
||||||
PrintString(DYNOS_TEXT_CLOSE_RIGHT, PROMPT_OFFSET, 212, COLOR_WHITE, COLOR_BLACK, 0);
|
|
||||||
} else if (aCurrentMenu == aDynosMenu) {
|
|
||||||
PrintString(DYNOS_TEXT_CLOSE_LEFT, PROMPT_OFFSET, 212, COLOR_WHITE, COLOR_BLACK, 1);
|
|
||||||
PrintString(DYNOS_TEXT_OPEN_RIGHT, PROMPT_OFFSET, 212, COLOR_WHITE, COLOR_BLACK, 0);
|
|
||||||
} else {
|
|
||||||
PrintString(DYNOS_TEXT_OPEN_LEFT, PROMPT_OFFSET, 212, COLOR_WHITE, COLOR_BLACK, 1);
|
|
||||||
PrintString(DYNOS_TEXT_OPEN_RIGHT, PROMPT_OFFSET, 212, COLOR_WHITE, COLOR_BLACK, 0);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,159 +0,0 @@
|
||||||
#include "dynos.cpp.h"
|
|
||||||
|
|
||||||
static DynosOption *sPrevOpt = NULL;
|
|
||||||
static DynosOption *sOptionsMenu = NULL;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Vanilla actions
|
|
||||||
//
|
|
||||||
|
|
||||||
typedef void (*VanillaActionFunction)(struct Option *, s32);
|
|
||||||
typedef struct VanillaAction {
|
|
||||||
String mFuncName;
|
|
||||||
VanillaActionFunction mAction;
|
|
||||||
} VanillaAction;
|
|
||||||
|
|
||||||
STATIC_STORAGE(Array<VanillaAction *>, VanillaActions);
|
|
||||||
#define sVanillaActions __VanillaActions()
|
|
||||||
|
|
||||||
static VanillaActionFunction DynOS_Opt_GetVanillaAction(const String& aFuncName) {
|
|
||||||
for (auto &_DynosAction : sVanillaActions) {
|
|
||||||
if (_DynosAction->mFuncName == aFuncName) {
|
|
||||||
return _DynosAction->mAction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_AddVanillaAction(const String& aFuncName, void (*aFuncPtr)(struct Option *, s32)) {
|
|
||||||
for (auto &_DynosAction : sVanillaActions) {
|
|
||||||
if (_DynosAction->mFuncName == aFuncName) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
VanillaAction *_DynosAction = New<VanillaAction>();
|
|
||||||
_DynosAction->mFuncName = aFuncName;
|
|
||||||
_DynosAction->mAction = aFuncPtr;
|
|
||||||
sVanillaActions.Add(_DynosAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool DynOS_Opt_CallVanillaAction(const char *aOptName) {
|
|
||||||
VanillaActionFunction _Func = DynOS_Opt_GetVanillaAction(aOptName);
|
|
||||||
if (_Func) {
|
|
||||||
_Func(NULL, 0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Convert classic options menu into DynOS menu
|
|
||||||
//
|
|
||||||
|
|
||||||
static DynosOption *DynOS_Opt_ConvertOption(const u8 *aLabel, const u8 *aTitle) {
|
|
||||||
static u32 sOptIdx = 0;
|
|
||||||
DynosOption *_Opt = New<DynosOption>();
|
|
||||||
_Opt->mName = String("vanilla_opt_%08X", sOptIdx++);
|
|
||||||
_Opt->mConfigName = "";
|
|
||||||
_Opt->mLabel = { "", aLabel };
|
|
||||||
_Opt->mTitle = { "", aTitle };
|
|
||||||
_Opt->mDynos = false;
|
|
||||||
if (sPrevOpt == NULL) { // The very first option
|
|
||||||
_Opt->mPrev = NULL;
|
|
||||||
_Opt->mNext = NULL;
|
|
||||||
_Opt->mParent = NULL;
|
|
||||||
sOptionsMenu = _Opt;
|
|
||||||
} else {
|
|
||||||
if (sPrevOpt->mType == DOPT_SUBMENU && sPrevOpt->mSubMenu.mEmpty) { // First option of a sub-menu
|
|
||||||
_Opt->mPrev = NULL;
|
|
||||||
_Opt->mNext = NULL;
|
|
||||||
_Opt->mParent = sPrevOpt;
|
|
||||||
sPrevOpt->mSubMenu.mChild = _Opt;
|
|
||||||
sPrevOpt->mSubMenu.mEmpty = false;
|
|
||||||
} else {
|
|
||||||
_Opt->mPrev = sPrevOpt;
|
|
||||||
_Opt->mNext = NULL;
|
|
||||||
_Opt->mParent = sPrevOpt->mParent;
|
|
||||||
sPrevOpt->mNext = _Opt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sPrevOpt = _Opt;
|
|
||||||
return _Opt;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_EndSubMenu() {
|
|
||||||
if (sPrevOpt) {
|
|
||||||
if (sPrevOpt->mType == DOPT_SUBMENU && sPrevOpt->mSubMenu.mEmpty) { // ENDMENU command following a SUBMENU command
|
|
||||||
sPrevOpt->mSubMenu.mEmpty = false;
|
|
||||||
} else {
|
|
||||||
sPrevOpt = sPrevOpt->mParent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_ConvertSubMenu(const u8 *aLabel, const u8 *aTitle) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_ConvertOption(aLabel, aTitle);
|
|
||||||
_Opt->mType = DOPT_SUBMENU;
|
|
||||||
_Opt->mSubMenu.mChild = NULL;
|
|
||||||
_Opt->mSubMenu.mEmpty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_ConvertToggle(const u8 *aLabel, bool *pValue) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_ConvertOption(aLabel, aLabel);
|
|
||||||
_Opt->mType = DOPT_TOGGLE;
|
|
||||||
_Opt->mToggle.mTog = (bool *) pValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_ConvertScroll(const u8 *aLabel, s32 aMin, s32 aMax, s32 aStep, u32 *pValue) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_ConvertOption(aLabel, aLabel);
|
|
||||||
_Opt->mType = DOPT_SCROLL;
|
|
||||||
_Opt->mScroll.mMin = aMin;
|
|
||||||
_Opt->mScroll.mMax = aMax;
|
|
||||||
_Opt->mScroll.mStep = aStep;
|
|
||||||
_Opt->mScroll.mValue = (s32 *) pValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_ConvertChoice(const u8 *aLabel, const u8 **aChoices, s32 aCount, u32 *pValue) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_ConvertOption(aLabel, aLabel);
|
|
||||||
_Opt->mType = DOPT_CHOICE;
|
|
||||||
_Opt->mChoice.mIndex = (s32 *) pValue;
|
|
||||||
for (s32 i = 0; i != aCount; ++i) {
|
|
||||||
_Opt->mChoice.mChoices.Add({ "", aChoices[i] });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_ConvertButton(const u8 *aLabel, VanillaActionFunction aAction) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_ConvertOption(aLabel, aLabel);
|
|
||||||
_Opt->mType = DOPT_BUTTON;
|
|
||||||
_Opt->mButton.mFuncName = "DynOS_Opt_CallVanillaAction";
|
|
||||||
DynOS_Opt_AddVanillaAction(_Opt->mName, aAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DynOS_Opt_ConvertBind(const u8 *aLabel, u32 *pBinds) {
|
|
||||||
DynosOption *_Opt = DynOS_Opt_ConvertOption(aLabel, aLabel);
|
|
||||||
_Opt->mType = DOPT_BIND;
|
|
||||||
_Opt->mBind.mMask = 0;
|
|
||||||
_Opt->mBind.mBinds = pBinds;
|
|
||||||
_Opt->mBind.mIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef COOP
|
|
||||||
extern "C" {
|
|
||||||
extern void dynos_opt_convert_vanilla_main_menu();
|
|
||||||
void dynos_opt_end_submenu() { return DynOS_Opt_EndSubMenu(); }
|
|
||||||
void dynos_opt_convert_submenu(const u8 *label, const u8 *title) { return DynOS_Opt_ConvertSubMenu(label, title); }
|
|
||||||
void dynos_opt_convert_toggle(const u8 *label, bool *bval) { return DynOS_Opt_ConvertToggle(label, bval); }
|
|
||||||
void dynos_opt_convert_scroll(const u8 *label, s32 min, s32 max, s32 step, u32 *uval) { return DynOS_Opt_ConvertScroll(label, min, max, step, uval); }
|
|
||||||
void dynos_opt_convert_choice(const u8 *label, const u8 **choices, s32 numChoices, u32 *uval) { return DynOS_Opt_ConvertChoice(label, choices, numChoices, uval); }
|
|
||||||
void dynos_opt_convert_button(const u8 *label, void *action) { return DynOS_Opt_ConvertButton(label, (VanillaActionFunction) action); }
|
|
||||||
void dynos_opt_convert_bind(const u8 *label, u32 *uval) { return DynOS_Opt_ConvertBind(label, uval); }
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
void DynOS_Opt_InitVanilla(DynosOption *&aOptionsMenu) {
|
|
||||||
sPrevOpt = NULL;
|
|
||||||
#ifndef COOP
|
|
||||||
dynos_opt_convert_vanilla_main_menu();
|
|
||||||
#endif
|
|
||||||
DynOS_Opt_AddAction("DynOS_Opt_CallVanillaAction", DynOS_Opt_CallVanillaAction, true);
|
|
||||||
aOptionsMenu = sOptionsMenu;
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
|
|
||||||
#ifndef COOP
|
|
||||||
// Not my problem
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wsizeof-pointer-div"
|
|
||||||
#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
|
|
||||||
#pragma GCC diagnostic ignored "-Wpointer-sign"
|
|
||||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
|
||||||
#define optmenu_toggle optmenu_toggle_unused
|
|
||||||
#define optmenu_draw optmenu_draw_unused
|
|
||||||
#define optmenu_draw_prompt optmenu_draw_prompt_unused
|
|
||||||
#define optmenu_check_buttons optmenu_check_buttons_unused
|
|
||||||
#define optmenu_open optmenu_open_unused
|
|
||||||
#define DYNOS_INL
|
|
||||||
#include "game/options_menu.c"
|
|
||||||
#undef DYNOS_INL
|
|
||||||
#undef optmenu_toggle
|
|
||||||
#undef optmenu_draw
|
|
||||||
#undef optmenu_draw_prompt
|
|
||||||
#undef optmenu_check_buttons
|
|
||||||
#undef optmenu_open
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
// Now, that's my problem
|
|
||||||
|
|
||||||
extern void dynos_opt_end_submenu();
|
|
||||||
extern void dynos_opt_convert_submenu(const u8 *label, const u8 *title);
|
|
||||||
extern void dynos_opt_convert_toggle(const u8 *label, bool *bval);
|
|
||||||
extern void dynos_opt_convert_scroll(const u8 *label, s32 min, s32 max, s32 step, u32 *uval);
|
|
||||||
extern void dynos_opt_convert_choice(const u8 *label, const u8 **choices, s32 numChoices, u32 *uval);
|
|
||||||
extern void dynos_opt_convert_button(const u8 *label, void *action);
|
|
||||||
extern void dynos_opt_convert_bind(const u8 *label, u32 *uval);
|
|
||||||
|
|
||||||
static void dynos_opt_convert_menu(struct SubMenu *submenu) {
|
|
||||||
for (s32 i = 0; i != submenu->numOpts; ++i) {
|
|
||||||
struct Option *opt = &submenu->opts[i];
|
|
||||||
switch (opt->type) {
|
|
||||||
case OPT_TOGGLE:
|
|
||||||
dynos_opt_convert_toggle(opt->label, opt->bval);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPT_CHOICE:
|
|
||||||
dynos_opt_convert_choice(opt->label, opt->choices, opt->numChoices, opt->uval);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPT_SCROLL:
|
|
||||||
dynos_opt_convert_scroll(opt->label, opt->scrMin, opt->scrMax, opt->scrStep, opt->uval);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPT_SUBMENU:
|
|
||||||
dynos_opt_convert_submenu(opt->label, opt->nextMenu->label);
|
|
||||||
dynos_opt_convert_menu(opt->nextMenu);
|
|
||||||
dynos_opt_end_submenu();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPT_BIND:
|
|
||||||
dynos_opt_convert_bind(opt->label, opt->uval);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPT_BUTTON:
|
|
||||||
dynos_opt_convert_button(opt->label, opt->actionFn);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dynos_opt_convert_vanilla_main_menu() {
|
|
||||||
dynos_opt_convert_menu(&menuMain);
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -10,7 +10,6 @@ extern "C" {
|
||||||
#include "game/level_update.h"
|
#include "game/level_update.h"
|
||||||
#include "game/sound_init.h"
|
#include "game/sound_init.h"
|
||||||
#include "game/object_list_processor.h"
|
#include "game/object_list_processor.h"
|
||||||
#include "game/options_menu.h"
|
|
||||||
#include "pc/network/packets/packet.h"
|
#include "pc/network/packets/packet.h"
|
||||||
#include "pc/lua/smlua_hooks.h"
|
#include "pc/lua/smlua_hooks.h"
|
||||||
extern s8 gDialogBoxState;
|
extern s8 gDialogBoxState;
|
||||||
|
@ -82,12 +81,11 @@ bool DynOS_Warp_RestartLevel() {
|
||||||
//
|
//
|
||||||
|
|
||||||
bool DynOS_Warp_ExitLevel(s32 aDelay) {
|
bool DynOS_Warp_ExitLevel(s32 aDelay) {
|
||||||
if (DynOS_Level_GetCourse(gCurrLevelNum) == COURSE_NONE) {
|
if (DynOS_Level_GetCourse(gCurrLevelNum) == COURSE_NONE || !DynOS_Level_GetWarpDeath(gCurrLevelNum, gCurrAreaIndex)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the pause menu if it was open
|
// Close the pause menu if it was open
|
||||||
optmenu_toggle();
|
|
||||||
level_set_transition(0, NULL);
|
level_set_transition(0, NULL);
|
||||||
gDialogBoxState = 0;
|
gDialogBoxState = 0;
|
||||||
gMenuMode = -1;
|
gMenuMode = -1;
|
||||||
|
@ -106,7 +104,7 @@ bool DynOS_Warp_ExitLevel(s32 aDelay) {
|
||||||
// Play Mario head transition, and change play mode to avoid getting stuck on the pause menu
|
// Play Mario head transition, and change play mode to avoid getting stuck on the pause menu
|
||||||
aDelay = MAX(1, aDelay);
|
aDelay = MAX(1, aDelay);
|
||||||
gMarioState->invincTimer = -1;
|
gMarioState->invincTimer = -1;
|
||||||
play_transition(WARP_TRANSITION_FADE_INTO_MARIO, aDelay, 0x00, 0x00, 0x00);
|
play_transition(WARP_TRANSITION_FADE_INTO_COLOR, aDelay, 0x00, 0x00, 0x00);
|
||||||
set_play_mode(0);
|
set_play_mode(0);
|
||||||
sDynosExitLevelNum = gCurrLevelNum;
|
sDynosExitLevelNum = gCurrLevelNum;
|
||||||
sDynosExitAreaNum = gCurrAreaIndex;
|
sDynosExitAreaNum = gCurrAreaIndex;
|
||||||
|
@ -114,12 +112,11 @@ bool DynOS_Warp_ExitLevel(s32 aDelay) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynOS_Warp_ToCastle(s32 aLevel) {
|
bool DynOS_Warp_ToCastle(s32 aLevel) {
|
||||||
if (DynOS_Level_GetCourse(aLevel) == COURSE_NONE) {
|
if (DynOS_Level_GetCourse(aLevel) == COURSE_NONE || !DynOS_Level_GetWarpDeath(aLevel, 1)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the pause menu if it was open
|
// Close the pause menu if it was open
|
||||||
optmenu_toggle();
|
|
||||||
level_set_transition(0, NULL);
|
level_set_transition(0, NULL);
|
||||||
gDialogBoxState = 0;
|
gDialogBoxState = 0;
|
||||||
gMenuMode = -1;
|
gMenuMode = -1;
|
||||||
|
@ -142,79 +139,6 @@ bool DynOS_Warp_ToCastle(s32 aLevel) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Params
|
|
||||||
//
|
|
||||||
|
|
||||||
const char *DynOS_Warp_GetParamName(s32 aLevel, s32 aIndex) {
|
|
||||||
static const char *sLevelParams[][5] = {
|
|
||||||
{ "", "", "", "", "" },
|
|
||||||
{ "None", "No Submarine, No Poles", "Submarine Only", "Poles Only", "Submarine And Poles" },
|
|
||||||
{ "None", "Water Level: Lowest", "Water Level: Low", "Water Level: High", "Water Level: Highest" },
|
|
||||||
{ "None", "Top Flooded", "Top Drained", "Top Flooded", "Top Drained" },
|
|
||||||
{ "None", "Clock Speed: Stopped", "Clock Speed: Slow", "Clock Speed: Fast", "Clock Speed: Random" },
|
|
||||||
};
|
|
||||||
switch (aLevel) {
|
|
||||||
case LEVEL_DDD: return sLevelParams[1][MIN(4, aIndex)];
|
|
||||||
case LEVEL_WDW: return sLevelParams[2][MIN(4, aIndex)];
|
|
||||||
case LEVEL_THI: return sLevelParams[3][MIN(4, aIndex)];
|
|
||||||
case LEVEL_TTC: return sLevelParams[4][MIN(4, aIndex)];
|
|
||||||
}
|
|
||||||
return sLevelParams[0][MIN(4, aIndex)];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called thrice
|
|
||||||
// Pass -1 to use the previous value (only once)
|
|
||||||
void DynOS_Warp_SetParam(s32 aLevel, s32 aIndex) {
|
|
||||||
static s32 sDynosWarpPrevParamIndex = -1;
|
|
||||||
if (aIndex == -1) {
|
|
||||||
aIndex = sDynosWarpPrevParamIndex;
|
|
||||||
sDynosWarpPrevParamIndex = -1;
|
|
||||||
} else {
|
|
||||||
sDynosWarpPrevParamIndex = aIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (aLevel) {
|
|
||||||
case LEVEL_DDD:
|
|
||||||
switch (aIndex) {
|
|
||||||
case 1: gDDDBowsersSub = 0; gDDDPoles = 0; break;
|
|
||||||
case 2: gDDDBowsersSub = 1; gDDDPoles = 0; break;
|
|
||||||
case 3: gDDDBowsersSub = 0; gDDDPoles = 1; break;
|
|
||||||
case 4: gDDDBowsersSub = 1; gDDDPoles = 1; break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LEVEL_WDW:
|
|
||||||
if (gEnvironmentRegions && gEnvironmentRegionsLength > 6) {
|
|
||||||
switch (aIndex) {
|
|
||||||
case 1: gEnvironmentRegions[6] = *gEnvironmentLevels = 31; gWdwWaterLevelSet = 1; break;
|
|
||||||
case 2: gEnvironmentRegions[6] = *gEnvironmentLevels = 1024; gWdwWaterLevelSet = 1; break;
|
|
||||||
case 3: gEnvironmentRegions[6] = *gEnvironmentLevels = 1792; gWdwWaterLevelSet = 1; break;
|
|
||||||
case 4: gEnvironmentRegions[6] = *gEnvironmentLevels = 2816; gWdwWaterLevelSet = 1; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LEVEL_THI:
|
|
||||||
switch (aIndex) {
|
|
||||||
case 1: gTHIWaterDrained = 0; break;
|
|
||||||
case 2: gTHIWaterDrained = 1; break;
|
|
||||||
case 3: gTHIWaterDrained = 0; break;
|
|
||||||
case 4: gTHIWaterDrained = 1; break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LEVEL_TTC:
|
|
||||||
switch (aIndex) {
|
|
||||||
case 1: gTTCSpeedSetting = TTC_SPEED_STOPPED; break;
|
|
||||||
case 2: gTTCSpeedSetting = TTC_SPEED_SLOW; break;
|
|
||||||
case 3: gTTCSpeedSetting = TTC_SPEED_FAST; break;
|
|
||||||
case 4: gTTCSpeedSetting = TTC_SPEED_RANDOM; break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Update
|
// Update
|
||||||
//
|
//
|
||||||
|
@ -226,7 +150,6 @@ static void *DynOS_Warp_UpdateWarp(void *aCmd, bool aIsLevelInitDone) {
|
||||||
if (sDynosWarpTargetArea == -1) {
|
if (sDynosWarpTargetArea == -1) {
|
||||||
|
|
||||||
// Close the pause menu if it was open
|
// Close the pause menu if it was open
|
||||||
optmenu_toggle();
|
|
||||||
level_set_transition(0, NULL);
|
level_set_transition(0, NULL);
|
||||||
gDialogBoxState = 0;
|
gDialogBoxState = 0;
|
||||||
gMenuMode = -1;
|
gMenuMode = -1;
|
||||||
|
@ -259,13 +182,10 @@ static void *DynOS_Warp_UpdateWarp(void *aCmd, bool aIsLevelInitDone) {
|
||||||
gCurrLevelNum = sDynosWarpLevelNum;
|
gCurrLevelNum = sDynosWarpLevelNum;
|
||||||
gCurrCourseNum = DynOS_Level_GetCourse(gCurrLevelNum);
|
gCurrCourseNum = DynOS_Level_GetCourse(gCurrLevelNum);
|
||||||
gSavedCourseNum = gCurrCourseNum;
|
gSavedCourseNum = gCurrCourseNum;
|
||||||
gCurrActNum = MAX(1, sDynosWarpActNum * (gCurrCourseNum <= COURSE_STAGES_MAX));
|
gCurrActNum = MAX(0, sDynosWarpActNum * (gCurrCourseNum <= COURSE_STAGES_MAX));
|
||||||
gDialogCourseActNum = gCurrActNum;
|
gDialogCourseActNum = gCurrActNum;
|
||||||
gCurrAreaIndex = sDynosWarpAreaNum;
|
gCurrAreaIndex = sDynosWarpAreaNum;
|
||||||
gCurrActStarNum = sDynosWarpActNum;
|
gCurrActStarNum = sDynosWarpActNum;
|
||||||
#ifndef COOP
|
|
||||||
DynOS_Warp_SetParam(gCurrLevelNum, DynOS_Opt_GetValue("dynos_warp_param"));
|
|
||||||
#endif
|
|
||||||
sDynosWarpTargetArea = gCurrAreaIndex;
|
sDynosWarpTargetArea = gCurrAreaIndex;
|
||||||
|
|
||||||
// Set up new level script
|
// Set up new level script
|
||||||
|
@ -285,7 +205,7 @@ static void *DynOS_Warp_UpdateWarp(void *aCmd, bool aIsLevelInitDone) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase 3 - End level initialization
|
// Phase 3 - End level initialization
|
||||||
if (aIsLevelInitDone) {
|
if (aIsLevelInitDone && gMarioObjects[0]) {
|
||||||
|
|
||||||
// Get Warp
|
// Get Warp
|
||||||
s16 *_Warp;
|
s16 *_Warp;
|
||||||
|
@ -306,9 +226,6 @@ static void *DynOS_Warp_UpdateWarp(void *aCmd, bool aIsLevelInitDone) {
|
||||||
gMarioSpawnInfo->areaIndex = gCurrAreaIndex;
|
gMarioSpawnInfo->areaIndex = gCurrAreaIndex;
|
||||||
init_mario();
|
init_mario();
|
||||||
set_mario_initial_action(gMarioState, sDynosWarpSpawnType, 0);
|
set_mario_initial_action(gMarioState, sDynosWarpSpawnType, 0);
|
||||||
#ifndef COOP
|
|
||||||
DynOS_Warp_SetParam(gCurrLevelNum, DynOS_Opt_GetValue("dynos_warp_param"));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Init transition
|
// Init transition
|
||||||
if (gCurrentArea != NULL) {
|
if (gCurrentArea != NULL) {
|
||||||
|
@ -447,7 +364,7 @@ static void *DynOS_Warp_UpdateExit(void *aCmd, bool aIsLevelInitDone) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase 3 - End level initialization
|
// Phase 3 - End level initialization
|
||||||
if (sDynosExitTargetWarp && aIsLevelInitDone) {
|
if (sDynosExitTargetWarp && aIsLevelInitDone && gMarioObjects[0]) {
|
||||||
|
|
||||||
// Find target position
|
// Find target position
|
||||||
// Because of course, every hack has its own warp distances and orientations...
|
// Because of course, every hack has its own warp distances and orientations...
|
||||||
|
@ -471,14 +388,18 @@ static void *DynOS_Warp_UpdateExit(void *aCmd, bool aIsLevelInitDone) {
|
||||||
set_mario_initial_action(gMarioState, MARIO_SPAWN_UNKNOWN_02, 0);
|
set_mario_initial_action(gMarioState, MARIO_SPAWN_UNKNOWN_02, 0);
|
||||||
|
|
||||||
// Init transition
|
// Init transition
|
||||||
|
if (gCurrentArea != NULL) {
|
||||||
reset_camera(gCurrentArea->camera);
|
reset_camera(gCurrentArea->camera);
|
||||||
init_camera(gCurrentArea->camera);
|
init_camera(gCurrentArea->camera);
|
||||||
|
}
|
||||||
sDelayedWarpOp = WARP_OP_NONE;
|
sDelayedWarpOp = WARP_OP_NONE;
|
||||||
play_transition(WARP_TRANSITION_FADE_FROM_STAR, 15, 0x00, 0x00, 0x00);
|
play_transition(WARP_TRANSITION_FADE_FROM_STAR, 15, 0x00, 0x00, 0x00);
|
||||||
play_sound(SOUND_MENU_MARIO_CASTLE_WARP, gGlobalSoundSource);
|
play_sound(SOUND_MENU_MARIO_CASTLE_WARP, gGlobalSoundSource);
|
||||||
|
|
||||||
// Set music
|
// Set music
|
||||||
|
if (gCurrentArea != NULL) {
|
||||||
set_background_music(gCurrentArea->musicParam, gCurrentArea->musicParam2, 0);
|
set_background_music(gCurrentArea->musicParam, gCurrentArea->musicParam2, 0);
|
||||||
|
}
|
||||||
sDynosExitTargetWarp = NULL;
|
sDynosExitTargetWarp = NULL;
|
||||||
|
|
||||||
// lua hooks
|
// lua hooks
|
||||||
|
|
|
@ -7384,6 +7384,50 @@
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
|
||||||
|
## [collision_find_ceil](#collision_find_ceil)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local SurfaceValue = collision_find_ceil(x, y, z)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| x | `number` |
|
||||||
|
| y | `number` |
|
||||||
|
| z | `number` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
[Surface](structs.md#Surface)
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`struct Surface* collision_find_ceil(f32 x, f32 y, f32 z);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [collision_find_floor](#collision_find_floor)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local SurfaceValue = collision_find_floor(x, y, z)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| x | `number` |
|
||||||
|
| y | `number` |
|
||||||
|
| z | `number` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
[Surface](structs.md#Surface)
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`struct Surface* collision_find_floor(f32 x, f32 y, f32 z);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [collision_find_surface_on_ray](#collision_find_surface_on_ray)
|
## [collision_find_surface_on_ray](#collision_find_surface_on_ray)
|
||||||
|
|
||||||
### Lua Example
|
### Lua Example
|
||||||
|
@ -7564,6 +7608,26 @@
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
## [smlua_level_util_get_info_from_course_num](#smlua_level_util_get_info_from_course_num)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local CustomLevelInfoValue = smlua_level_util_get_info_from_course_num(courseNum)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| courseNum | `integer` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
[CustomLevelInfo](structs.md#CustomLevelInfo)
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`struct CustomLevelInfo* smlua_level_util_get_info_from_course_num(u8 courseNum);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [smlua_level_util_get_info_from_short_name](#smlua_level_util_get_info_from_short_name)
|
## [smlua_level_util_get_info_from_short_name](#smlua_level_util_get_info_from_short_name)
|
||||||
|
|
||||||
### Lua Example
|
### Lua Example
|
||||||
|
|
|
@ -2384,6 +2384,91 @@
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
|
||||||
|
## [smlua_text_utils_act_name_get](#smlua_text_utils_act_name_get)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local stringValue = smlua_text_utils_act_name_get(courseNum, actNum)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| courseNum | `integer` |
|
||||||
|
| actNum | `integer` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- `string`
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`const char* smlua_text_utils_act_name_get(s16 courseNum, u8 actNum);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [smlua_text_utils_act_name_is_modified](#smlua_text_utils_act_name_is_modified)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local booleanValue = smlua_text_utils_act_name_is_modified(courseNum, actNum)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| courseNum | `integer` |
|
||||||
|
| actNum | `integer` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- `boolean`
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`bool smlua_text_utils_act_name_is_modified(s16 courseNum, u8 actNum);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [smlua_text_utils_act_name_replace](#smlua_text_utils_act_name_replace)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`smlua_text_utils_act_name_replace(courseNum, actNum, name)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| courseNum | `integer` |
|
||||||
|
| actNum | `integer` |
|
||||||
|
| name | `string` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- None
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`void smlua_text_utils_act_name_replace(s16 courseNum, u8 actNum, const char* name);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [smlua_text_utils_act_name_reset](#smlua_text_utils_act_name_reset)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`smlua_text_utils_act_name_reset(courseNum, actNum)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| courseNum | `integer` |
|
||||||
|
| actNum | `integer` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- None
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`void smlua_text_utils_act_name_reset(s16 courseNum, u8 actNum);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [smlua_text_utils_castle_secret_stars_replace](#smlua_text_utils_castle_secret_stars_replace)
|
## [smlua_text_utils_castle_secret_stars_replace](#smlua_text_utils_castle_secret_stars_replace)
|
||||||
|
|
||||||
### Lua Example
|
### Lua Example
|
||||||
|
@ -2431,6 +2516,87 @@
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
## [smlua_text_utils_course_name_get](#smlua_text_utils_course_name_get)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local stringValue = smlua_text_utils_course_name_get(courseNum)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| courseNum | `integer` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- `string`
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`const char* smlua_text_utils_course_name_get(s16 courseNum);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [smlua_text_utils_course_name_mod_index](#smlua_text_utils_course_name_mod_index)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local integerValue = smlua_text_utils_course_name_mod_index(courseNum)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| courseNum | `integer` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- `integer`
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`s32 smlua_text_utils_course_name_mod_index(s16 courseNum);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [smlua_text_utils_course_name_replace](#smlua_text_utils_course_name_replace)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`smlua_text_utils_course_name_replace(courseNum, name)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| courseNum | `integer` |
|
||||||
|
| name | `string` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- None
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`void smlua_text_utils_course_name_replace(s16 courseNum, const char* name);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [smlua_text_utils_course_name_reset](#smlua_text_utils_course_name_reset)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`smlua_text_utils_course_name_reset(courseNum)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| courseNum | `integer` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- None
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`void smlua_text_utils_course_name_reset(s16 courseNum);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [smlua_text_utils_dialog_replace](#smlua_text_utils_dialog_replace)
|
## [smlua_text_utils_dialog_replace](#smlua_text_utils_dialog_replace)
|
||||||
|
|
||||||
### Lua Example
|
### Lua Example
|
||||||
|
@ -2495,24 +2661,6 @@
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
## [smlua_text_utils_reset_all](#smlua_text_utils_reset_all)
|
|
||||||
|
|
||||||
### Lua Example
|
|
||||||
`smlua_text_utils_reset_all()`
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
- None
|
|
||||||
|
|
||||||
### Returns
|
|
||||||
- None
|
|
||||||
|
|
||||||
### C Prototype
|
|
||||||
`void smlua_text_utils_reset_all(void);`
|
|
||||||
|
|
||||||
[:arrow_up_small:](#)
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
## [smlua_text_utils_secret_star_replace](#smlua_text_utils_secret_star_replace)
|
## [smlua_text_utils_secret_star_replace](#smlua_text_utils_secret_star_replace)
|
||||||
|
|
||||||
### Lua Example
|
### Lua Example
|
||||||
|
|
|
@ -1521,6 +1521,8 @@
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
- smlua_collision_utils.h
|
- smlua_collision_utils.h
|
||||||
|
- [collision_find_ceil](functions-4.md#collision_find_ceil)
|
||||||
|
- [collision_find_floor](functions-4.md#collision_find_floor)
|
||||||
- [collision_find_surface_on_ray](functions-4.md#collision_find_surface_on_ray)
|
- [collision_find_surface_on_ray](functions-4.md#collision_find_surface_on_ray)
|
||||||
- [collision_get_temp_wall_collision_data](functions-4.md#collision_get_temp_wall_collision_data)
|
- [collision_get_temp_wall_collision_data](functions-4.md#collision_get_temp_wall_collision_data)
|
||||||
- [get_water_surface_pseudo_floor](functions-4.md#get_water_surface_pseudo_floor)
|
- [get_water_surface_pseudo_floor](functions-4.md#get_water_surface_pseudo_floor)
|
||||||
|
@ -1537,6 +1539,7 @@
|
||||||
- [level_register](functions-4.md#level_register)
|
- [level_register](functions-4.md#level_register)
|
||||||
- [smlua_level_util_change_area](functions-4.md#smlua_level_util_change_area)
|
- [smlua_level_util_change_area](functions-4.md#smlua_level_util_change_area)
|
||||||
- [smlua_level_util_get_info](functions-4.md#smlua_level_util_get_info)
|
- [smlua_level_util_get_info](functions-4.md#smlua_level_util_get_info)
|
||||||
|
- [smlua_level_util_get_info_from_course_num](functions-4.md#smlua_level_util_get_info_from_course_num)
|
||||||
- [smlua_level_util_get_info_from_short_name](functions-4.md#smlua_level_util_get_info_from_short_name)
|
- [smlua_level_util_get_info_from_short_name](functions-4.md#smlua_level_util_get_info_from_short_name)
|
||||||
- [warp_exit_level](functions-4.md#warp_exit_level)
|
- [warp_exit_level](functions-4.md#warp_exit_level)
|
||||||
- [warp_restart_level](functions-4.md#warp_restart_level)
|
- [warp_restart_level](functions-4.md#warp_restart_level)
|
||||||
|
@ -1690,12 +1693,19 @@
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
- smlua_text_utils.h
|
- smlua_text_utils.h
|
||||||
|
- [smlua_text_utils_act_name_get](functions-5.md#smlua_text_utils_act_name_get)
|
||||||
|
- [smlua_text_utils_act_name_is_modified](functions-5.md#smlua_text_utils_act_name_is_modified)
|
||||||
|
- [smlua_text_utils_act_name_replace](functions-5.md#smlua_text_utils_act_name_replace)
|
||||||
|
- [smlua_text_utils_act_name_reset](functions-5.md#smlua_text_utils_act_name_reset)
|
||||||
- [smlua_text_utils_castle_secret_stars_replace](functions-5.md#smlua_text_utils_castle_secret_stars_replace)
|
- [smlua_text_utils_castle_secret_stars_replace](functions-5.md#smlua_text_utils_castle_secret_stars_replace)
|
||||||
- [smlua_text_utils_course_acts_replace](functions-5.md#smlua_text_utils_course_acts_replace)
|
- [smlua_text_utils_course_acts_replace](functions-5.md#smlua_text_utils_course_acts_replace)
|
||||||
|
- [smlua_text_utils_course_name_get](functions-5.md#smlua_text_utils_course_name_get)
|
||||||
|
- [smlua_text_utils_course_name_mod_index](functions-5.md#smlua_text_utils_course_name_mod_index)
|
||||||
|
- [smlua_text_utils_course_name_replace](functions-5.md#smlua_text_utils_course_name_replace)
|
||||||
|
- [smlua_text_utils_course_name_reset](functions-5.md#smlua_text_utils_course_name_reset)
|
||||||
- [smlua_text_utils_dialog_replace](functions-5.md#smlua_text_utils_dialog_replace)
|
- [smlua_text_utils_dialog_replace](functions-5.md#smlua_text_utils_dialog_replace)
|
||||||
- [smlua_text_utils_extra_text_replace](functions-5.md#smlua_text_utils_extra_text_replace)
|
- [smlua_text_utils_extra_text_replace](functions-5.md#smlua_text_utils_extra_text_replace)
|
||||||
- [smlua_text_utils_get_language](functions-5.md#smlua_text_utils_get_language)
|
- [smlua_text_utils_get_language](functions-5.md#smlua_text_utils_get_language)
|
||||||
- [smlua_text_utils_reset_all](functions-5.md#smlua_text_utils_reset_all)
|
|
||||||
- [smlua_text_utils_secret_star_replace](functions-5.md#smlua_text_utils_secret_star_replace)
|
- [smlua_text_utils_secret_star_replace](functions-5.md#smlua_text_utils_secret_star_replace)
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -154,32 +154,14 @@ static void add_surface_to_cell(s16 dynamic, s16 cellX, s16 cellZ, struct Surfac
|
||||||
/**
|
/**
|
||||||
* Returns the lowest of three values.
|
* Returns the lowest of three values.
|
||||||
*/
|
*/
|
||||||
static s16 min_3(s16 a0, s16 a1, s16 a2) {
|
|
||||||
if (a1 < a0) {
|
|
||||||
a0 = a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a2 < a0) {
|
#define min_3(a0, a1, a2) MIN(MIN(a0, a1), a2)
|
||||||
a0 = a2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the highest of three values.
|
* Returns the highest of three values.
|
||||||
*/
|
*/
|
||||||
static s16 max_3(s16 a0, s16 a1, s16 a2) {
|
|
||||||
if (a1 > a0) {
|
|
||||||
a0 = a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a2 > a0) {
|
#define max_3(a0, a1, a2) MAX(MAX(a0, a1), a2)
|
||||||
a0 = a2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every level is split into 16 * 16 cells of surfaces (to limit computing
|
* Every level is split into 16 * 16 cells of surfaces (to limit computing
|
||||||
|
@ -378,48 +360,25 @@ static struct Surface *read_surface_data(s16 *vertexData, s16 **vertexIndices) {
|
||||||
* Returns whether a surface has exertion/moves Mario
|
* Returns whether a surface has exertion/moves Mario
|
||||||
* based on the surface type.
|
* based on the surface type.
|
||||||
*/
|
*/
|
||||||
static s32 surface_has_force(s16 surfaceType) {
|
static bool surface_has_force(s16 surfaceType) {
|
||||||
s32 hasForce = FALSE;
|
return surfaceType == SURFACE_0004 ||
|
||||||
|
surfaceType == SURFACE_FLOWING_WATER ||
|
||||||
switch (surfaceType) {
|
surfaceType == SURFACE_HORIZONTAL_WIND ||
|
||||||
case SURFACE_0004: // Unused
|
surfaceType == SURFACE_MOVING_QUICKSAND ||
|
||||||
case SURFACE_FLOWING_WATER:
|
surfaceType == SURFACE_DEEP_MOVING_QUICKSAND ||
|
||||||
case SURFACE_DEEP_MOVING_QUICKSAND:
|
surfaceType == SURFACE_SHALLOW_MOVING_QUICKSAND ||
|
||||||
case SURFACE_SHALLOW_MOVING_QUICKSAND:
|
surfaceType == SURFACE_INSTANT_MOVING_QUICKSAND;
|
||||||
case SURFACE_MOVING_QUICKSAND:
|
|
||||||
case SURFACE_HORIZONTAL_WIND:
|
|
||||||
case SURFACE_INSTANT_MOVING_QUICKSAND:
|
|
||||||
hasForce = TRUE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return hasForce;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether a surface should have the
|
* Returns whether a surface should have the
|
||||||
* SURFACE_FLAG_NO_CAM_COLLISION flag.
|
* SURFACE_FLAG_NO_CAM_COLLISION flag.
|
||||||
*/
|
*/
|
||||||
static s32 surf_has_no_cam_collision(s16 surfaceType) {
|
static bool surf_has_no_cam_collision(s16 surfaceType) {
|
||||||
s32 flags = 0;
|
return surfaceType == SURFACE_SWITCH ||
|
||||||
|
surfaceType == SURFACE_NO_CAM_COLLISION ||
|
||||||
switch (surfaceType) {
|
surfaceType == SURFACE_NO_CAM_COLLISION_77 ||
|
||||||
case SURFACE_RAYCAST:
|
surfaceType == SURFACE_NO_CAM_COL_VERY_SLIPPERY;
|
||||||
case SURFACE_NO_CAM_COLLISION:
|
|
||||||
case SURFACE_NO_CAM_COLLISION_77: // Unused
|
|
||||||
case SURFACE_NO_CAM_COL_VERY_SLIPPERY:
|
|
||||||
case SURFACE_VANISH_CAP_WALLS:
|
|
||||||
case SURFACE_SWITCH:
|
|
||||||
flags = SURFACE_FLAG_NO_CAM_COLLISION;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -427,17 +386,16 @@ static s32 surf_has_no_cam_collision(s16 surfaceType) {
|
||||||
* exertion, and room.
|
* exertion, and room.
|
||||||
*/
|
*/
|
||||||
static void load_static_surfaces(s16 **data, s16 *vertexData, s16 surfaceType, s8 **surfaceRooms) {
|
static void load_static_surfaces(s16 **data, s16 *vertexData, s16 surfaceType, s8 **surfaceRooms) {
|
||||||
s32 i;
|
|
||||||
s32 numSurfaces;
|
s32 numSurfaces;
|
||||||
struct Surface *surface;
|
struct Surface *surface;
|
||||||
s8 room = 0;
|
s8 room = 0;
|
||||||
s16 hasForce = surface_has_force(surfaceType);
|
bool hasForce = surface_has_force(surfaceType);
|
||||||
s16 flags = surf_has_no_cam_collision(surfaceType);
|
bool flags = surf_has_no_cam_collision(surfaceType);
|
||||||
|
|
||||||
numSurfaces = *(*data);
|
numSurfaces = *(*data);
|
||||||
*data += 1;
|
*data += 1;
|
||||||
|
|
||||||
for (i = 0; i < numSurfaces; i++) {
|
for (s32 i = 0; i < numSurfaces; i++) {
|
||||||
if (*surfaceRooms != NULL) {
|
if (*surfaceRooms != NULL) {
|
||||||
room = *(*surfaceRooms);
|
room = *(*surfaceRooms);
|
||||||
*surfaceRooms += 1;
|
*surfaceRooms += 1;
|
||||||
|
@ -486,7 +444,6 @@ static s16 *read_vertex_data(s16 **data) {
|
||||||
*/
|
*/
|
||||||
static void load_environmental_regions(s16 **data) {
|
static void load_environmental_regions(s16 **data) {
|
||||||
s32 numRegions;
|
s32 numRegions;
|
||||||
s32 i;
|
|
||||||
|
|
||||||
gEnvironmentRegionsLength = 0;
|
gEnvironmentRegionsLength = 0;
|
||||||
gEnvironmentRegions = *data;
|
gEnvironmentRegions = *data;
|
||||||
|
@ -497,7 +454,7 @@ static void load_environmental_regions(s16 **data) {
|
||||||
numRegions = 20;
|
numRegions = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < numRegions; i++) {
|
for (s32 i = 0; i < numRegions; i++) {
|
||||||
UNUSED s16 val, loX, loZ, hiX, hiZ;
|
UNUSED s16 val, loX, loZ, hiX, hiZ;
|
||||||
s16 height;
|
s16 height;
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ static void bhv_camera_lakitu_on_received_post(u8 localIndex) {
|
||||||
void bhv_camera_lakitu_init(void) {
|
void bhv_camera_lakitu_init(void) {
|
||||||
if (o->oBehParams2ndByte != CAMERA_LAKITU_BP_FOLLOW_CAMERA) {
|
if (o->oBehParams2ndByte != CAMERA_LAKITU_BP_FOLLOW_CAMERA) {
|
||||||
// Despawn unless this is the very beginning of the game
|
// Despawn unless this is the very beginning of the game
|
||||||
if (gNeverEnteredCastle != TRUE) {
|
if (!gNeverEnteredCastle) {
|
||||||
obj_mark_for_deletion(o);
|
obj_mark_for_deletion(o);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,24 +131,21 @@ static u8 bhv_snowmans_bottom_loop_continue_dialog(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void bhv_snowmans_bottom_loop(void) {
|
void bhv_snowmans_bottom_loop(void) {
|
||||||
s16 sp1E;
|
|
||||||
|
|
||||||
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
||||||
|
|
||||||
switch (o->oAction) {
|
switch (o->oAction) {
|
||||||
case 0:
|
case 0:
|
||||||
if (marioState
|
if (marioState
|
||||||
|
&& marioState->playerIndex == 0
|
||||||
&& should_start_or_continue_dialog(marioState, o)
|
&& should_start_or_continue_dialog(marioState, o)
|
||||||
&& (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 400) == 1)
|
&& (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 400) == 1)
|
||||||
&& set_mario_npc_dialog(&gMarioStates[0], 1, bhv_snowmans_bottom_loop_continue_dialog) == 2) {
|
&& set_mario_npc_dialog(&gMarioStates[0], 1, bhv_snowmans_bottom_loop_continue_dialog)
|
||||||
sp1E = cutscene_object_with_dialog(CUTSCENE_DIALOG, o, gBehaviorValues.dialogs.SnowmanHeadBodyDialog);
|
&& cutscene_object_with_dialog(CUTSCENE_DIALOG, o, gBehaviorValues.dialogs.SnowmanHeadBodyDialog)) {
|
||||||
if (sp1E) {
|
|
||||||
o->oForwardVel = 10.0f;
|
o->oForwardVel = 10.0f;
|
||||||
o->oAction = 1;
|
o->oAction = 1;
|
||||||
set_mario_npc_dialog(&gMarioStates[0], 0, NULL);
|
set_mario_npc_dialog(&gMarioStates[0], 0, NULL);
|
||||||
network_send_object(o);
|
network_send_object(o);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
|
|
@ -59,10 +59,10 @@ static struct ObjectHitbox sCollectStarHitbox = {
|
||||||
};
|
};
|
||||||
|
|
||||||
void bhv_collect_star_init(void) {
|
void bhv_collect_star_init(void) {
|
||||||
s8 starId;
|
s16 starId;
|
||||||
u8 currentLevelStarFlags;
|
u8 currentLevelStarFlags;
|
||||||
|
|
||||||
starId = (o->oBehParams >> 24) & 0xFF;
|
starId = o->oBehParams >> 24;
|
||||||
currentLevelStarFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1);
|
currentLevelStarFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1);
|
||||||
if (currentLevelStarFlags & (1 << starId)) {
|
if (currentLevelStarFlags & (1 << starId)) {
|
||||||
cur_obj_set_model(MODEL_TRANSPARENT_STAR);
|
cur_obj_set_model(MODEL_TRANSPARENT_STAR);
|
||||||
|
|
|
@ -3112,10 +3112,12 @@ void update_lakitu(struct Camera *c) {
|
||||||
gLakituState.defMode = c->defMode;
|
gLakituState.defMode = c->defMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern bool gIsDemoActive;
|
||||||
static void update_romhack_camera_override(struct Camera *c) {
|
static void update_romhack_camera_override(struct Camera *c) {
|
||||||
if (gOverrideRomhackCamera == RCO_NONE) { return; }
|
if (gOverrideRomhackCamera == RCO_NONE) { return; }
|
||||||
if (c->mode == CAMERA_MODE_ROM_HACK) { return; }
|
if (c->mode == CAMERA_MODE_ROM_HACK) { return; }
|
||||||
if (dynos_level_is_vanilla_level(gCurrLevelNum)) { return; }
|
if (dynos_level_is_vanilla_level(gCurrLevelNum)) { return; }
|
||||||
|
if (gIsDemoActive) { return; }
|
||||||
|
|
||||||
if (gOverrideRomhackCamera == RCO_ALL_EXCEPT_BOWSER) {
|
if (gOverrideRomhackCamera == RCO_ALL_EXCEPT_BOWSER) {
|
||||||
if (gCurrLevelNum == LEVEL_BOWSER_1 || gCurrLevelNum == LEVEL_BOWSER_2 || gCurrLevelNum == LEVEL_BOWSER_3) {
|
if (gCurrLevelNum == LEVEL_BOWSER_1 || gCurrLevelNum == LEVEL_BOWSER_2 || gCurrLevelNum == LEVEL_BOWSER_3) {
|
||||||
|
|
|
@ -468,7 +468,6 @@ void read_controller_inputs(void) {
|
||||||
if (gControllerBits) {
|
if (gControllerBits) {
|
||||||
osRecvMesg(&gSIEventMesgQueue, &D_80339BEC, OS_MESG_BLOCK);
|
osRecvMesg(&gSIEventMesgQueue, &D_80339BEC, OS_MESG_BLOCK);
|
||||||
osContGetReadData(gInteractableOverridePad ? &gInteractablePad : &gControllerPads[0]);
|
osContGetReadData(gInteractableOverridePad ? &gInteractablePad : &gControllerPads[0]);
|
||||||
dynos_update_opt((void *) &gControllerPads[0]);
|
|
||||||
}
|
}
|
||||||
run_demo_inputs();
|
run_demo_inputs();
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include "levels/wf/header.h"
|
#include "levels/wf/header.h"
|
||||||
#include "levels/wmotr/header.h"
|
#include "levels/wmotr/header.h"
|
||||||
|
|
||||||
|
#include "src/pc/pc_main.h"
|
||||||
|
|
||||||
extern Trajectory sThiHugeMetalBallTraj[];
|
extern Trajectory sThiHugeMetalBallTraj[];
|
||||||
extern Trajectory sThiTinyMetalBallTraj[];
|
extern Trajectory sThiTinyMetalBallTraj[];
|
||||||
|
|
||||||
|
@ -308,8 +310,7 @@ struct PaintingValues gPaintingValues = { 0 };
|
||||||
// functions //
|
// functions //
|
||||||
///////////////
|
///////////////
|
||||||
|
|
||||||
__attribute__((constructor))
|
AT_STARTUP void hardcoded_reset_default_values(void) {
|
||||||
void hardcoded_reset_default_values(void) {
|
|
||||||
gLevelValues = gDefaultLevelValues;
|
gLevelValues = gDefaultLevelValues;
|
||||||
gBehaviorValues = gDefaultBehaviorValues;
|
gBehaviorValues = gDefaultBehaviorValues;
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#ifdef BETTERCAMERA
|
#ifdef BETTERCAMERA
|
||||||
#include "bettercamera.h"
|
#include "bettercamera.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "level_info.h"
|
||||||
|
|
||||||
u16 gDialogColorFadeTimer;
|
u16 gDialogColorFadeTimer;
|
||||||
s8 gLastDialogLineNum;
|
s8 gLastDialogLineNum;
|
||||||
|
@ -2515,38 +2516,13 @@ void render_pause_my_score_coins(void) {
|
||||||
u8 textUnfilledStar[] = { TEXT_UNFILLED_STAR };
|
u8 textUnfilledStar[] = { TEXT_UNFILLED_STAR };
|
||||||
|
|
||||||
u8 strCourseNum[4];
|
u8 strCourseNum[4];
|
||||||
void **courseNameTbl;
|
u8 courseIndex = gCurrCourseNum - 1;
|
||||||
u8 *courseName;
|
u8 *courseName = (u8*) get_level_name_sm64(gCurrCourseNum, gCurrLevelNum, gCurrAreaIndex, 1);
|
||||||
void **actNameTbl;
|
u8 *actName = (u8*) get_star_name_sm64(gCurrCourseNum, gDialogCourseActNum, 1);
|
||||||
u8 *actName = NULL;
|
|
||||||
u8 courseIndex;
|
|
||||||
u8 starFlags;
|
u8 starFlags;
|
||||||
|
|
||||||
#ifndef VERSION_EU
|
|
||||||
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
|
||||||
actNameTbl = segmented_to_virtual(seg2_act_name_table);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
courseIndex = gCurrCourseNum - 1;
|
|
||||||
starFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1);
|
starFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1);
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
|
||||||
switch (gInGameLanguage) {
|
|
||||||
case LANGUAGE_ENGLISH:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_en);
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_FRENCH:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_fr);
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_GERMAN:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_de);
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
||||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
||||||
|
|
||||||
|
@ -2564,8 +2540,6 @@ void render_pause_my_score_coins(void) {
|
||||||
print_generic_string(MYSCORE_X, 121, textMyScore);
|
print_generic_string(MYSCORE_X, 121, textMyScore);
|
||||||
}
|
}
|
||||||
|
|
||||||
courseName = segmented_to_virtual(courseNameTbl[courseIndex]);
|
|
||||||
|
|
||||||
if (courseIndex < COURSE_STAGES_COUNT) {
|
if (courseIndex < COURSE_STAGES_COUNT) {
|
||||||
#ifdef VERSION_EU
|
#ifdef VERSION_EU
|
||||||
print_generic_string(48, 157, gTextCourseArr[gInGameLanguage]);
|
print_generic_string(48, 157, gTextCourseArr[gInGameLanguage]);
|
||||||
|
@ -2579,10 +2553,6 @@ void render_pause_my_score_coins(void) {
|
||||||
print_generic_string(CRS_NUM_X1, 157, strCourseNum);
|
print_generic_string(CRS_NUM_X1, 157, strCourseNum);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gDialogCourseActNum >= 1 && gDialogCourseActNum <= 6) {
|
|
||||||
actName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + gDialogCourseActNum - 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (starFlags & (1 << (gDialogCourseActNum - 1))) {
|
if (starFlags & (1 << (gDialogCourseActNum - 1))) {
|
||||||
print_generic_string(TXT_STAR_X, 140, textStar);
|
print_generic_string(TXT_STAR_X, 140, textStar);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2838,11 +2808,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 render_pause_castle_main_strings(s16 x, s16 y) {
|
||||||
#ifdef VERSION_EU
|
void **courseNameTbl = get_course_name_table();
|
||||||
void **courseNameTbl;
|
|
||||||
#else
|
|
||||||
void **courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
#ifdef VERSION_EU
|
||||||
u8 textCoin[] = { TEXT_COIN };
|
u8 textCoin[] = { TEXT_COIN };
|
||||||
|
@ -2856,20 +2822,6 @@ void render_pause_castle_main_strings(s16 x, s16 y) {
|
||||||
u8 strVal[8];
|
u8 strVal[8];
|
||||||
s16 starNum = gDialogLineNum;
|
s16 starNum = gDialogLineNum;
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
|
||||||
switch (gInGameLanguage) {
|
|
||||||
case LANGUAGE_ENGLISH:
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_FRENCH:
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_GERMAN:
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
handle_menu_scrolling(MENU_SCROLL_VERTICAL, &gDialogLineNum, -1, COURSE_STAGES_COUNT + 1);
|
handle_menu_scrolling(MENU_SCROLL_VERTICAL, &gDialogLineNum, -1, COURSE_STAGES_COUNT + 1);
|
||||||
|
|
||||||
if (gDialogLineNum == COURSE_STAGES_COUNT + 1) {
|
if (gDialogLineNum == COURSE_STAGES_COUNT + 1) {
|
||||||
|
@ -2936,7 +2888,7 @@ void render_pause_castle_main_strings(s16 x, s16 y) {
|
||||||
static u32 pause_castle_get_stars(s32 index) {
|
static u32 pause_castle_get_stars(s32 index) {
|
||||||
|
|
||||||
// Main courses (0-14), Secret courses (15-24)
|
// Main courses (0-14), Secret courses (15-24)
|
||||||
if (index >= 0 && index < INDEX_CASTLE_STARS) {
|
if (COURSE_IS_VALID_COURSE(index)) {
|
||||||
return save_file_get_star_flags(gCurrSaveFileNum - 1, index);
|
return save_file_get_star_flags(gCurrSaveFileNum - 1, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3062,23 +3014,7 @@ void render_pause_castle_main_strings_extended(s16 x, s16 y) {
|
||||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
||||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
||||||
|
|
||||||
void **courseNameTbl = NULL;
|
void **courseNameTbl = get_course_name_table();
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
|
||||||
switch (gInGameLanguage) {
|
|
||||||
case LANGUAGE_ENGLISH:
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_FRENCH:
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_GERMAN:
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Main courses (0-14)
|
// Main courses (0-14)
|
||||||
if (gDialogLineNum < COURSE_STAGES_COUNT) {
|
if (gDialogLineNum < COURSE_STAGES_COUNT) {
|
||||||
|
@ -3150,7 +3086,7 @@ s16 render_pause_courses_and_castle(void) {
|
||||||
play_sound(SOUND_MENU_PAUSE_HIGHPRIO, gGlobalSoundSource);
|
play_sound(SOUND_MENU_PAUSE_HIGHPRIO, gGlobalSoundSource);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gCurrCourseNum >= COURSE_MIN && gCurrCourseNum <= COURSE_MAX) {
|
if (COURSE_IS_VALID_COURSE(gCurrCourseNum)) {
|
||||||
change_dialog_camera_angle();
|
change_dialog_camera_angle();
|
||||||
gDialogBoxState = DIALOG_STATE_VERTICAL;
|
gDialogBoxState = DIALOG_STATE_VERTICAL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3227,14 +3163,9 @@ s16 render_pause_courses_and_castle(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gDjuiPanelPauseCreated) { shade_screen(); }
|
if (gDjuiPanelPauseCreated) { shade_screen(); }
|
||||||
if (gPlayer1Controller->buttonPressed & R_TRIG)
|
if (gPlayer1Controller->buttonPressed & R_TRIG) {
|
||||||
djui_panel_pause_create(NULL);
|
djui_panel_pause_create(NULL);
|
||||||
|
}
|
||||||
#ifndef COOP
|
|
||||||
// call into DynOS's menu system
|
|
||||||
optmenu_draw();
|
|
||||||
optmenu_draw_prompt();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3384,33 +3315,12 @@ void render_course_complete_lvl_info_and_hud_str(void) {
|
||||||
u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE };
|
u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void **actNameTbl;
|
void **actNameTbl = get_act_name_table();
|
||||||
void **courseNameTbl;
|
void **courseNameTbl = get_course_name_table();
|
||||||
u8 *name;
|
u8 *name;
|
||||||
|
|
||||||
u8 strCourseNum[4];
|
u8 strCourseNum[4];
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
|
||||||
s16 centerX;
|
|
||||||
switch (gInGameLanguage) {
|
|
||||||
case LANGUAGE_ENGLISH:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_en);
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_FRENCH:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_fr);
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_GERMAN:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_de);
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
actNameTbl = segmented_to_virtual(seg2_act_name_table);
|
|
||||||
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (gLastCompletedCourseNum <= COURSE_STAGES_MAX) {
|
if (gLastCompletedCourseNum <= COURSE_STAGES_MAX) {
|
||||||
print_hud_course_complete_coins(118, 103);
|
print_hud_course_complete_coins(118, 103);
|
||||||
play_star_fanfare_and_flash_hud(1, 1 << (gLastCompletedStarNum - 1));
|
play_star_fanfare_and_flash_hud(1, 1 << (gLastCompletedStarNum - 1));
|
||||||
|
@ -3435,7 +3345,7 @@ void render_course_complete_lvl_info_and_hud_str(void) {
|
||||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
||||||
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha);
|
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha);
|
||||||
#ifdef VERSION_EU
|
#ifdef VERSION_EU
|
||||||
centerX = get_str_x_pos_from_center(153, name, 12.0f);
|
s16 centerX = get_str_x_pos_from_center(153, name, 12.0f);
|
||||||
#endif
|
#endif
|
||||||
print_generic_string(TXT_NAME_X1, 130, name);
|
print_generic_string(TXT_NAME_X1, 130, name);
|
||||||
#ifndef VERSION_EU
|
#ifndef VERSION_EU
|
||||||
|
|
|
@ -923,12 +923,7 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O
|
||||||
|
|
||||||
u8 stayInLevelCommon = !(gCurrLevelNum == LEVEL_BOWSER_1 || gCurrLevelNum == LEVEL_BOWSER_2 || gCurrLevelNum == LEVEL_BOWSER_3);
|
u8 stayInLevelCommon = !(gCurrLevelNum == LEVEL_BOWSER_1 || gCurrLevelNum == LEVEL_BOWSER_2 || gCurrLevelNum == LEVEL_BOWSER_3);
|
||||||
if (stayInLevelCommon && gServerSettings.stayInLevelAfterStar) { noExit = TRUE; }
|
if (stayInLevelCommon && gServerSettings.stayInLevelAfterStar) { noExit = TRUE; }
|
||||||
|
gLastCollectedStarOrKey = o->behavior == bhvBowserKey;
|
||||||
if (o->behavior == bhvBowserKey) {
|
|
||||||
gLastCollectedStarOrKey = 1;
|
|
||||||
} else {
|
|
||||||
gLastCollectedStarOrKey = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m->health >= 0x100) {
|
if (m->health >= 0x100) {
|
||||||
|
|
||||||
|
@ -981,7 +976,7 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O
|
||||||
m->interactObj = o;
|
m->interactObj = o;
|
||||||
m->usedObj = o;
|
m->usedObj = o;
|
||||||
|
|
||||||
starIndex = (o->oBehParams >> 24) & 0x1F;
|
starIndex = o->oBehParams >> 24;
|
||||||
|
|
||||||
if (m == &gMarioStates[0]) {
|
if (m == &gMarioStates[0]) {
|
||||||
// sync the star collection
|
// sync the star collection
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "save_file.h"
|
#include "save_file.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "pc/lua/utils/smlua_level_utils.h"
|
#include "pc/lua/utils/smlua_level_utils.h"
|
||||||
|
#include "pc/lua/utils/smlua_text_utils.h"
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
#ifdef VERSION_EU
|
||||||
extern s32 gInGameLanguage;
|
extern s32 gInGameLanguage;
|
||||||
|
@ -107,7 +108,7 @@ static void convert_string_ascii_to_sm64(u8 *str64, const char *strAscii) {
|
||||||
*str64 = 0xFF;
|
*str64 = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void convert_string_sm64_to_ascii(char *strAscii, const u8 *str64) {
|
void convert_string_sm64_to_ascii(char *strAscii, const u8 *str64) {
|
||||||
for (; *str64 != 0xFF; str64++) {
|
for (; *str64 != 0xFF; str64++) {
|
||||||
strAscii = sm64_to_ascii_char(strAscii, str64);
|
strAscii = sm64_to_ascii_char(strAscii, str64);
|
||||||
}
|
}
|
||||||
|
@ -158,12 +159,40 @@ static void decapitalize_string_sm64(u8 *str64) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *get_course_name_table() {
|
||||||
|
void **courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
||||||
|
|
||||||
|
#ifdef VERSION_EU
|
||||||
|
switch (gInGameLanguage) {
|
||||||
|
case LANGUAGE_ENGLISH: courseNameTbl = segmented_to_virtual(course_name_table_eu_en); break;
|
||||||
|
case LANGUAGE_FRENCH: courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); break;
|
||||||
|
case LANGUAGE_GERMAN: courseNameTbl = segmented_to_virtual(course_name_table_eu_de); break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return courseNameTbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *get_act_name_table() {
|
||||||
|
void **actNameTbl = segmented_to_virtual(seg2_act_name_table);
|
||||||
|
|
||||||
|
#ifdef VERSION_EU
|
||||||
|
switch (gInGameLanguage) {
|
||||||
|
case LANGUAGE_ENGLISH: actNameTbl = segmented_to_virtual(act_name_table_eu_en); break;
|
||||||
|
case LANGUAGE_FRENCH: actNameTbl = segmented_to_virtual(act_name_table_eu_fr); break;
|
||||||
|
case LANGUAGE_GERMAN: actNameTbl = segmented_to_virtual(act_name_table_eu_de); break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return actNameTbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern struct CourseName *gReplacedActNameTable[];
|
||||||
|
|
||||||
const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase) {
|
const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase) {
|
||||||
static char output[256];
|
static char output[256];
|
||||||
|
|
||||||
// Valid course: BOB to RR, Bowser stages and Secret courses
|
// Custom course
|
||||||
// There is no course name for Cake Ending, make it defaults to "Peach's Castle"
|
|
||||||
|
|
||||||
bool hasCustomName = false;
|
bool hasCustomName = false;
|
||||||
if (levelNum >= CUSTOM_LEVEL_NUM_START) {
|
if (levelNum >= CUSTOM_LEVEL_NUM_START) {
|
||||||
struct CustomLevelInfo* info = smlua_level_util_get_info(levelNum);
|
struct CustomLevelInfo* info = smlua_level_util_get_info(levelNum);
|
||||||
|
@ -173,23 +202,20 @@ const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasCustomName && courseNum >= COURSE_MIN && courseNum < COURSE_MAX) {
|
if (gReplacedActNameTable[courseNum]->modIndex != -1) {
|
||||||
void **courseNameTbl = NULL;
|
snprintf(output, 256, "%s", gReplacedActNameTable[courseNum]->name);
|
||||||
#ifdef VERSION_EU
|
|
||||||
switch (gInGameLanguage) {
|
|
||||||
case LANGUAGE_ENGLISH: courseNameTbl = segmented_to_virtual(course_name_table_eu_en); break;
|
|
||||||
case LANGUAGE_FRENCH: courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); break;
|
|
||||||
case LANGUAGE_GERMAN: courseNameTbl = segmented_to_virtual(course_name_table_eu_de); break;
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
else if (!hasCustomName) {
|
||||||
#endif
|
if (COURSE_IS_VALID_COURSE(courseNum)) {
|
||||||
|
void **courseNameTbl = get_course_name_table();
|
||||||
const u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum - COURSE_BOB]);
|
const u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum - COURSE_BOB]);
|
||||||
convert_string_sm64_to_ascii(output, courseName + 3);
|
convert_string_sm64_to_ascii(output, courseName + 3);
|
||||||
|
charCase = MIN(charCase, 0); // Don't need to capitalize vanilla course names
|
||||||
}
|
}
|
||||||
|
|
||||||
// Castle level
|
// Castle level
|
||||||
else if (!hasCustomName && courseNum == COURSE_NONE) {
|
else if (courseNum == COURSE_NONE) {
|
||||||
switch (levelNum) {
|
switch (levelNum) {
|
||||||
case LEVEL_CASTLE: {
|
case LEVEL_CASTLE: {
|
||||||
switch (areaIndex) {
|
switch (areaIndex) {
|
||||||
|
@ -206,9 +232,10 @@ const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default
|
// Default
|
||||||
else if (!hasCustomName) {
|
else {
|
||||||
snprintf(output, 256, "Peach's Castle");
|
snprintf(output, 256, "Peach's Castle");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Capitalize or decapitalize text
|
// Capitalize or decapitalize text
|
||||||
if (charCase == -1) {
|
if (charCase == -1) {
|
||||||
|
@ -221,7 +248,8 @@ const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16
|
||||||
|
|
||||||
const u8 *get_level_name_sm64(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase) {
|
const u8 *get_level_name_sm64(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase) {
|
||||||
static u8 output[256];
|
static u8 output[256];
|
||||||
const char *levelName = get_level_name_ascii(courseNum, levelNum, areaIndex, charCase);
|
char levelName[256];
|
||||||
|
snprintf(levelName, 256, " %d %s", courseNum, (char*) get_level_name_ascii(courseNum, levelNum, areaIndex, charCase));
|
||||||
convert_string_ascii_to_sm64(output, levelName);
|
convert_string_ascii_to_sm64(output, levelName);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -233,23 +261,19 @@ const char *get_level_name(s16 courseNum, s16 levelNum, s16 areaIndex) {
|
||||||
const char *get_star_name_ascii(s16 courseNum, s16 starNum, s16 charCase) {
|
const char *get_star_name_ascii(s16 courseNum, s16 starNum, s16 charCase) {
|
||||||
static char output[256];
|
static char output[256];
|
||||||
|
|
||||||
// Main courses: BOB to RR
|
if (gReplacedActNameTable[courseNum]->actName && gReplacedActNameTable[courseNum]->actName[starNum - 1].isModified) {
|
||||||
if (COURSE_IS_MAIN_COURSE(courseNum)) {
|
snprintf(output, 256, "%s", gReplacedActNameTable[courseNum]->actName[starNum - 1].name);
|
||||||
if (starNum >= 1 && starNum <= 6) {
|
|
||||||
void **actNameTable = NULL;
|
|
||||||
#ifdef VERSION_EU
|
|
||||||
switch (gInGameLanguage) {
|
|
||||||
case LANGUAGE_ENGLISH: actNameTable = segmented_to_virtual(act_name_table_eu_en); break;
|
|
||||||
case LANGUAGE_FRENCH: actNameTable = segmented_to_virtual(act_name_table_eu_fr); break;
|
|
||||||
case LANGUAGE_GERMAN: actNameTable = segmented_to_virtual(act_name_table_eu_de); break;
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
actNameTable = segmented_to_virtual(seg2_act_name_table);
|
// Main courses: BOB to RR
|
||||||
#endif
|
else if (COURSE_IS_MAIN_COURSE(courseNum)) {
|
||||||
|
if (starNum >= 1 && starNum <= 6) {
|
||||||
|
void **actNameTable = get_act_name_table();
|
||||||
const u8 *starName = segmented_to_virtual(actNameTable[(courseNum - COURSE_BOB) * 6 + (starNum - 1)]);
|
const u8 *starName = segmented_to_virtual(actNameTable[(courseNum - COURSE_BOB) * 6 + (starNum - 1)]);
|
||||||
convert_string_sm64_to_ascii(output, starName);
|
convert_string_sm64_to_ascii(output, starName);
|
||||||
|
charCase = MIN(charCase, 0); // Don't need to capitalize vanilla act names
|
||||||
} else if (starNum == 7) {
|
} else if (starNum == 7) {
|
||||||
snprintf(output, 256, "%d Coins Star", (s32) gLevelValues.coinsRequiredForCoinStar);
|
snprintf(output, 256, "%d Coins Star", gLevelValues.coinsRequiredForCoinStar);
|
||||||
} else {
|
} else {
|
||||||
snprintf(output, 256, "A Secret Star!");
|
snprintf(output, 256, "A Secret Star!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <PR/ultratypes.h>
|
#include <PR/ultratypes.h>
|
||||||
|
|
||||||
|
void *get_course_name_table();
|
||||||
|
void *get_act_name_table();
|
||||||
const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase);
|
const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase);
|
||||||
const u8 *get_level_name_sm64(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase);
|
const u8 *get_level_name_sm64(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase);
|
||||||
const char *get_level_name(s16 courseNum, s16 levelNum, s16 areaIndex);
|
const char *get_level_name(s16 courseNum, s16 levelNum, s16 areaIndex);
|
||||||
|
|
|
@ -69,7 +69,7 @@ s16 gChangeLevelTransition = -1;
|
||||||
s16 gChangeActNum = -1;
|
s16 gChangeActNum = -1;
|
||||||
|
|
||||||
static bool sFirstCastleGroundsMenu = true;
|
static bool sFirstCastleGroundsMenu = true;
|
||||||
static bool sIsDemoActive = false;
|
bool gIsDemoActive = false;
|
||||||
bool gInPlayerMenu = false;
|
bool gInPlayerMenu = false;
|
||||||
static u16 gDemoCountdown = 0;
|
static u16 gDemoCountdown = 0;
|
||||||
static int sDemoNumber = -1;
|
static int sDemoNumber = -1;
|
||||||
|
@ -201,7 +201,7 @@ s32 sDelayedWarpArg;
|
||||||
s16 unusedEULevelUpdateBss1;
|
s16 unusedEULevelUpdateBss1;
|
||||||
#endif
|
#endif
|
||||||
s8 sTimerRunning;
|
s8 sTimerRunning;
|
||||||
s8 gNeverEnteredCastle;
|
bool gNeverEnteredCastle;
|
||||||
|
|
||||||
struct MarioState *gMarioState = &gMarioStates[0];
|
struct MarioState *gMarioState = &gMarioStates[0];
|
||||||
u8 unused1[4] = { 0 };
|
u8 unused1[4] = { 0 };
|
||||||
|
@ -1158,10 +1158,10 @@ bool find_demo_number(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_demo(void) {
|
static void start_demo(void) {
|
||||||
if (sIsDemoActive) {
|
if (gIsDemoActive) {
|
||||||
sIsDemoActive = false;
|
gIsDemoActive = false;
|
||||||
} else {
|
} else {
|
||||||
sIsDemoActive = true;
|
gIsDemoActive = true;
|
||||||
|
|
||||||
if (find_demo_number()) {
|
if (find_demo_number()) {
|
||||||
gChangeLevel = gCurrLevelNum;
|
gChangeLevel = gCurrLevelNum;
|
||||||
|
@ -1173,14 +1173,14 @@ static void start_demo(void) {
|
||||||
load_patchable_table(&gDemo, sDemoNumber);
|
load_patchable_table(&gDemo, sDemoNumber);
|
||||||
gCurrDemoInput = ((struct DemoInput *) gDemo.targetAnim);
|
gCurrDemoInput = ((struct DemoInput *) gDemo.targetAnim);
|
||||||
} else {
|
} else {
|
||||||
sIsDemoActive = false;
|
gIsDemoActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_demo(UNUSED struct DjuiBase* caller) {
|
void stop_demo(UNUSED struct DjuiBase* caller) {
|
||||||
if (sIsDemoActive) {
|
if (gIsDemoActive) {
|
||||||
sIsDemoActive = false;
|
gIsDemoActive = false;
|
||||||
gCurrDemoInput = NULL;
|
gCurrDemoInput = NULL;
|
||||||
gChangeLevel = gCurrLevelNum;
|
gChangeLevel = gCurrLevelNum;
|
||||||
gDemoCountdown = 0;
|
gDemoCountdown = 0;
|
||||||
|
@ -1197,22 +1197,26 @@ s32 play_mode_normal(void) {
|
||||||
if (gCurrDemoInput != NULL) {
|
if (gCurrDemoInput != NULL) {
|
||||||
print_intro_text();
|
print_intro_text();
|
||||||
if (gPlayer1Controller->buttonPressed & END_DEMO) {
|
if (gPlayer1Controller->buttonPressed & END_DEMO) {
|
||||||
level_trigger_warp(gMarioState,
|
level_trigger_warp(gMarioState, gCurrLevelNum == LEVEL_PSS ? WARP_OP_DEMO_END : WARP_OP_DEMO_NEXT);
|
||||||
gCurrLevelNum == LEVEL_PSS ? WARP_OP_DEMO_END : WARP_OP_DEMO_NEXT);
|
} else if (!gWarpTransition.isActive && sDelayedWarpOp == WARP_OP_NONE && (gPlayer1Controller->buttonPressed & START_BUTTON)) {
|
||||||
} else if (!gWarpTransition.isActive && sDelayedWarpOp == WARP_OP_NONE
|
|
||||||
&& (gPlayer1Controller->buttonPressed & START_BUTTON)) {
|
|
||||||
gPressedStart = 1;
|
gPressedStart = 1;
|
||||||
level_trigger_warp(gMarioState, WARP_OP_DEMO_NEXT);
|
level_trigger_warp(gMarioState, WARP_OP_DEMO_NEXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (gDjuiInMainMenu && gCurrDemoInput == NULL && configMenuDemos && !gInPlayerMenu) {
|
if (gDjuiInMainMenu &&
|
||||||
if ((++gDemoCountdown) == PRESS_START_DEMO_TIMER && (find_demo_number() && (sDemoNumber <= 6 && sDemoNumber > -1))) {
|
gCurrDemoInput == NULL &&
|
||||||
|
configMenuDemos &&
|
||||||
|
!gInPlayerMenu &&
|
||||||
|
(++gDemoCountdown) == PRESS_START_DEMO_TIMER &&
|
||||||
|
(find_demo_number() && (sDemoNumber <= 6 && sDemoNumber > -1)) &&
|
||||||
|
gNetworkType == NT_NONE) {
|
||||||
start_demo();
|
start_demo();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (((gCurrDemoInput != NULL) && (gPlayer1Controller->buttonPressed & END_DEMO || !sIsDemoActive || !gDjuiInMainMenu || gNetworkType != NT_NONE || gInPlayerMenu)) || (gCurrDemoInput == NULL && sIsDemoActive)) {
|
if (((gCurrDemoInput != NULL) &&
|
||||||
|
(gPlayer1Controller->buttonPressed & END_DEMO || !gIsDemoActive || !gDjuiInMainMenu || gNetworkType != NT_NONE || gInPlayerMenu)) ||
|
||||||
|
(gCurrDemoInput == NULL && gIsDemoActive)) {
|
||||||
gPlayer1Controller->buttonPressed &= ~END_DEMO;
|
gPlayer1Controller->buttonPressed &= ~END_DEMO;
|
||||||
stop_demo(NULL);
|
stop_demo(NULL);
|
||||||
}
|
}
|
||||||
|
@ -1442,7 +1446,7 @@ void update_menu_level(void) {
|
||||||
|
|
||||||
// warp to level, this feels buggy
|
// warp to level, this feels buggy
|
||||||
if (gCurrLevelNum != curLevel) {
|
if (gCurrLevelNum != curLevel) {
|
||||||
if (sIsDemoActive) {
|
if (gIsDemoActive) {
|
||||||
stop_demo(NULL);
|
stop_demo(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1450,7 +1454,7 @@ void update_menu_level(void) {
|
||||||
gChangeActNum = 6;
|
gChangeActNum = 6;
|
||||||
gDemoCountdown = 0;
|
gDemoCountdown = 0;
|
||||||
}
|
}
|
||||||
if (sIsDemoActive) {
|
if (gIsDemoActive) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1837,7 +1841,7 @@ s32 lvl_set_current_level(UNUSED s16 arg0, s32 levelNum) {
|
||||||
|
|
||||||
sWarpCheckpointActive = FALSE;
|
sWarpCheckpointActive = FALSE;
|
||||||
gCurrLevelNum = levelNum;
|
gCurrLevelNum = levelNum;
|
||||||
gCurrCourseNum = get_level_course_num(levelNum - 1);
|
gCurrCourseNum = get_level_course_num(levelNum);
|
||||||
|
|
||||||
bool foundHook = false;
|
bool foundHook = false;
|
||||||
bool hookUseActSelect = false;
|
bool hookUseActSelect = false;
|
||||||
|
|
|
@ -124,7 +124,7 @@ struct HudDisplay {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct HudDisplay gHudDisplay;
|
extern struct HudDisplay gHudDisplay;
|
||||||
extern s8 gNeverEnteredCastle;
|
extern bool gNeverEnteredCastle;
|
||||||
|
|
||||||
extern u32 gControlTimerStartNat;
|
extern u32 gControlTimerStartNat;
|
||||||
extern u32 gControlTimerStopNat;
|
extern u32 gControlTimerStopNat;
|
||||||
|
|
|
@ -1577,6 +1577,7 @@ copyPlayerGoto:;
|
||||||
if (m == m2) { continue; }
|
if (m == m2) { continue; }
|
||||||
find_floor(m2->pos[0], m2->pos[1], m2->pos[2], &floor2);
|
find_floor(m2->pos[0], m2->pos[1], m2->pos[2], &floor2);
|
||||||
if (floor2 == NULL) { continue; }
|
if (floor2 == NULL) { continue; }
|
||||||
|
LOG_INFO("OOB! teleporting to player with local index %d", i);
|
||||||
vec3f_copy(m->pos, m2->pos);
|
vec3f_copy(m->pos, m2->pos);
|
||||||
copiedPlayer = TRUE;
|
copiedPlayer = TRUE;
|
||||||
goto copyPlayerGoto;
|
goto copyPlayerGoto;
|
||||||
|
|
|
@ -349,6 +349,7 @@ void cutscene_put_cap_on(struct MarioState *m) {
|
||||||
m->flags &= ~MARIO_CAP_IN_HAND;
|
m->flags &= ~MARIO_CAP_IN_HAND;
|
||||||
m->flags |= MARIO_CAP_ON_HEAD;
|
m->flags |= MARIO_CAP_ON_HEAD;
|
||||||
play_sound(SOUND_ACTION_UNKNOWN43E, m->marioObj->header.gfx.cameraToObject);
|
play_sound(SOUND_ACTION_UNKNOWN43E, m->marioObj->header.gfx.cameraToObject);
|
||||||
|
m->cap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -556,7 +557,7 @@ s32 act_reading_automatic_dialog(struct MarioState *m) {
|
||||||
} else if (m->actionState == 25) { // finished action
|
} else if (m->actionState == 25) { // finished action
|
||||||
disable_time_stop();
|
disable_time_stop();
|
||||||
if (gNeverEnteredCastle) {
|
if (gNeverEnteredCastle) {
|
||||||
gNeverEnteredCastle = FALSE;
|
gNeverEnteredCastle = false;
|
||||||
play_cutscene_music(SEQUENCE_ARGS(0, SEQ_LEVEL_INSIDE_CASTLE));
|
play_cutscene_music(SEQUENCE_ARGS(0, SEQ_LEVEL_INSIDE_CASTLE));
|
||||||
}
|
}
|
||||||
if (m->prevAction == ACT_STAR_DANCE_WATER) {
|
if (m->prevAction == ACT_STAR_DANCE_WATER) {
|
||||||
|
@ -632,7 +633,7 @@ s32 act_debug_free_move(struct MarioState *m) {
|
||||||
u32 action = ACT_IDLE;
|
u32 action = ACT_IDLE;
|
||||||
|
|
||||||
#ifndef DEVELOPMENT
|
#ifndef DEVELOPMENT
|
||||||
if (gNetworkType == NT_SERVER && gServerSettings.enableCheats == 0 && m->action == ACT_DEBUG_FREE_MOVE) {
|
if (gServerSettings.enableCheats == 0) {
|
||||||
if (m->pos[1] <= m->waterLevel - 100) {
|
if (m->pos[1] <= m->waterLevel - 100) {
|
||||||
action = ACT_WATER_IDLE;
|
action = ACT_WATER_IDLE;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1149,7 +1150,7 @@ s32 act_warp_door_spawn(struct MarioState *m) {
|
||||||
}
|
}
|
||||||
} else if (m->usedObj == NULL || (m->usedObj->oAction == 0 || m->usedObj->oAction == 100)) {
|
} else if (m->usedObj == NULL || (m->usedObj->oAction == 0 || m->usedObj->oAction == 100)) {
|
||||||
if (m->playerIndex == 0) {
|
if (m->playerIndex == 0) {
|
||||||
if (gNeverEnteredCastle == TRUE && gCurrLevelNum == LEVEL_CASTLE) {
|
if (gNeverEnteredCastle && gCurrLevelNum == LEVEL_CASTLE) {
|
||||||
set_mario_action(m, ACT_READING_AUTOMATIC_DIALOG, gBehaviorValues.dialogs.CastleEnterDialog);
|
set_mario_action(m, ACT_READING_AUTOMATIC_DIALOG, gBehaviorValues.dialogs.CastleEnterDialog);
|
||||||
} else {
|
} else {
|
||||||
set_mario_action(m, ACT_IDLE, 0);
|
set_mario_action(m, ACT_IDLE, 0);
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#ifndef OPTIONS_MENU_H
|
|
||||||
#define OPTIONS_MENU_H
|
|
||||||
|
|
||||||
void optmenu_draw(void);
|
|
||||||
void optmenu_draw_prompt(void);
|
|
||||||
void optmenu_toggle(void);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -916,7 +916,7 @@ void painting_update_floors(struct Painting *painting) {
|
||||||
if (!consider) {
|
if (!consider) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// floorEntered is true iff currFloor is true and lastFloor is false
|
// floorEntered is true if currFloor is true and lastFloor is false
|
||||||
// (Mario just entered the floor on this frame)
|
// (Mario just entered the floor on this frame)
|
||||||
s8 entered = (painting->ripples.lastFloors[i] ^ painting->ripples.currFloors[i]) & painting->ripples.currFloors[i];
|
s8 entered = (painting->ripples.lastFloors[i] ^ painting->ripples.currFloors[i]) & painting->ripples.currFloors[i];
|
||||||
if (entered) {
|
if (entered) {
|
||||||
|
|
|
@ -63,6 +63,8 @@ s8 get_level_course_num(s16 levelNum) {
|
||||||
return (info ? info->courseNum : COURSE_NONE);
|
return (info ? info->courseNum : COURSE_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
levelNum = levelNum - 1;
|
||||||
|
|
||||||
if (INVALID_LEVEL_NUM(levelNum)) {
|
if (INVALID_LEVEL_NUM(levelNum)) {
|
||||||
return COURSE_NONE;
|
return COURSE_NONE;
|
||||||
}
|
}
|
||||||
|
@ -818,7 +820,7 @@ void check_if_should_set_warp_checkpoint(struct WarpNode *warpNode) {
|
||||||
*/
|
*/
|
||||||
s32 check_warp_checkpoint(struct WarpNode *warpNode) {
|
s32 check_warp_checkpoint(struct WarpNode *warpNode) {
|
||||||
s16 warpCheckpointActive = FALSE;
|
s16 warpCheckpointActive = FALSE;
|
||||||
s16 currCourseNum = get_level_course_num((warpNode->destLevel & 0x7F) - 1);
|
s16 currCourseNum = get_level_course_num(warpNode->destLevel & 0x7F);
|
||||||
|
|
||||||
// gSavedCourseNum is only used in this function.
|
// gSavedCourseNum is only used in this function.
|
||||||
if (gWarpCheckpoint.courseNum != COURSE_NONE && gSavedCourseNum == currCourseNum
|
if (gWarpCheckpoint.courseNum != COURSE_NONE && gSavedCourseNum == currCourseNum
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "pc/network/network.h"
|
#include "pc/network/network.h"
|
||||||
#include "engine/math_util.h"
|
#include "engine/math_util.h"
|
||||||
#include "game/print.h"
|
#include "game/print.h"
|
||||||
|
#include "game/level_info.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file star_select.c
|
* @file star_select.c
|
||||||
|
@ -278,15 +279,9 @@ void print_act_selector_strings(void) {
|
||||||
#endif
|
#endif
|
||||||
unsigned char starNumbers[] = { TEXT_ZERO };
|
unsigned char starNumbers[] = { TEXT_ZERO };
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
u8 **levelNameTbl = get_course_name_table();
|
||||||
u8 **levelNameTbl;
|
|
||||||
u8 *currLevelName;
|
|
||||||
u8 **actNameTbl;
|
|
||||||
#else
|
|
||||||
u8 **levelNameTbl = segmented_to_virtual(seg2_course_name_table);
|
|
||||||
u8 *currLevelName = segmented_to_virtual(levelNameTbl[gCurrCourseNum - 1]);
|
u8 *currLevelName = segmented_to_virtual(levelNameTbl[gCurrCourseNum - 1]);
|
||||||
u8 **actNameTbl = segmented_to_virtual(seg2_act_name_table);
|
u8 **actNameTbl = get_act_name_table();
|
||||||
#endif
|
|
||||||
u8 *selectedActName;
|
u8 *selectedActName;
|
||||||
#ifndef VERSION_EU
|
#ifndef VERSION_EU
|
||||||
s16 lvlNameX;
|
s16 lvlNameX;
|
||||||
|
@ -299,24 +294,6 @@ void print_act_selector_strings(void) {
|
||||||
|
|
||||||
create_dl_ortho_matrix();
|
create_dl_ortho_matrix();
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
|
||||||
switch (language) {
|
|
||||||
case LANGUAGE_ENGLISH:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_en);
|
|
||||||
levelNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_FRENCH:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_fr);
|
|
||||||
levelNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_GERMAN:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_de);
|
|
||||||
levelNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
currLevelName = segmented_to_virtual(levelNameTbl[gCurrCourseNum - 1]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Print the coin highscore.
|
// Print the coin highscore.
|
||||||
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
||||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "dev/chat.h"
|
#include "dev/chat.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern bool gIsModerator;
|
|
||||||
static enum ChatConfirmCommand sConfirming = CCC_NONE;
|
static enum ChatConfirmCommand sConfirming = CCC_NONE;
|
||||||
static u8 sConfirmPlayerIndex = 0;
|
static u8 sConfirmPlayerIndex = 0;
|
||||||
|
|
||||||
|
@ -55,14 +54,15 @@ static void chat_construct_player_message(struct NetworkPlayer* np, char* msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exec_chat_command(char* command) {
|
bool exec_chat_command(char* command) {
|
||||||
|
struct NetworkPlayer* npl = &gNetworkPlayers[0];
|
||||||
enum ChatConfirmCommand ccc = sConfirming;
|
enum ChatConfirmCommand ccc = sConfirming;
|
||||||
sConfirming = CCC_NONE;
|
sConfirming = CCC_NONE;
|
||||||
|
|
||||||
if (ccc != CCC_NONE && strcmp("/confirm", command) == 0) {
|
if (ccc != CCC_NONE && strcmp("/confirm", command) == 0) {
|
||||||
if (gNetworkType == NT_SERVER || gIsModerator) {
|
|
||||||
if (ccc == CCC_KICK) {
|
|
||||||
struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex];
|
struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex];
|
||||||
if (!np->connected) { return true; }
|
if (!np->connected) return true;
|
||||||
|
if (gNetworkType == NT_SERVER || npl->moderator) {
|
||||||
|
if (ccc == CCC_KICK) {
|
||||||
chat_construct_player_message(np, DLANG(CHAT, KICKING));
|
chat_construct_player_message(np, DLANG(CHAT, KICKING));
|
||||||
if (gNetworkType == NT_SERVER) {
|
if (gNetworkType == NT_SERVER) {
|
||||||
network_send_kick(np->localIndex, EKT_KICKED);
|
network_send_kick(np->localIndex, EKT_KICKED);
|
||||||
|
@ -73,10 +73,8 @@ bool exec_chat_command(char* command) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gNetworkType == NT_SERVER || gIsModerator) {
|
if (gNetworkType == NT_SERVER || npl->moderator) {
|
||||||
if (ccc == CCC_BAN) {
|
if (ccc == CCC_BAN) {
|
||||||
struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex];
|
|
||||||
if (!np->connected) { return true; }
|
|
||||||
chat_construct_player_message(np, DLANG(CHAT, BANNING));
|
chat_construct_player_message(np, DLANG(CHAT, BANNING));
|
||||||
if (gNetworkType == NT_SERVER) {
|
if (gNetworkType == NT_SERVER) {
|
||||||
network_send_kick(np->localIndex, EKT_BANNED);
|
network_send_kick(np->localIndex, EKT_BANNED);
|
||||||
|
@ -89,8 +87,6 @@ bool exec_chat_command(char* command) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gNetworkType == NT_SERVER && ccc == CCC_PERMBAN) {
|
if (gNetworkType == NT_SERVER && ccc == CCC_PERMBAN) {
|
||||||
struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex];
|
|
||||||
if (!np->connected) { return true; }
|
|
||||||
chat_construct_player_message(np, DLANG(CHAT, PERM_BANNING));
|
chat_construct_player_message(np, DLANG(CHAT, PERM_BANNING));
|
||||||
network_send_kick(np->localIndex, EKT_BANNED);
|
network_send_kick(np->localIndex, EKT_BANNED);
|
||||||
ban_list_add(gNetworkSystem->get_id_str(np->localIndex), true);
|
ban_list_add(gNetworkSystem->get_id_str(np->localIndex), true);
|
||||||
|
@ -98,9 +94,8 @@ bool exec_chat_command(char* command) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (gNetworkType == NT_SERVER && ccc == CCC_MODERATOR) {
|
if (gNetworkType == NT_SERVER && ccc == CCC_MODERATOR) {
|
||||||
struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex];
|
|
||||||
if (!np->connected) { return true; }
|
|
||||||
chat_construct_player_message(np, DLANG(CHAT, ADD_MODERATOR));
|
chat_construct_player_message(np, DLANG(CHAT, ADD_MODERATOR));
|
||||||
|
np->moderator = true;
|
||||||
network_send_moderator(np->localIndex);
|
network_send_moderator(np->localIndex);
|
||||||
moderator_list_add(gNetworkSystem->get_id_str(np->localIndex), true);
|
moderator_list_add(gNetworkSystem->get_id_str(np->localIndex), true);
|
||||||
return true;
|
return true;
|
||||||
|
@ -125,7 +120,7 @@ bool exec_chat_command(char* command) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str_starts_with("/kick ", command)) {
|
if (str_starts_with("/kick ", command)) {
|
||||||
if (gNetworkType != NT_SERVER && !gIsModerator) {
|
if (gNetworkType != NT_SERVER && !npl->moderator) {
|
||||||
djui_chat_message_create(DLANG(CHAT, NO_PERMS));
|
djui_chat_message_create(DLANG(CHAT, NO_PERMS));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +143,7 @@ bool exec_chat_command(char* command) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str_starts_with("/ban ", command)) {
|
if (str_starts_with("/ban ", command)) {
|
||||||
if (gNetworkType != NT_SERVER && !gIsModerator) {
|
if (gNetworkType != NT_SERVER && !npl->moderator) {
|
||||||
djui_chat_message_create(DLANG(CHAT, NO_PERMS));
|
djui_chat_message_create(DLANG(CHAT, NO_PERMS));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +166,7 @@ bool exec_chat_command(char* command) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str_starts_with("/permban ", command)) {
|
if (str_starts_with("/permban ", command)) {
|
||||||
if (gNetworkType != NT_SERVER && !gIsModerator) {
|
if (gNetworkType != NT_SERVER && !npl->moderator) {
|
||||||
djui_chat_message_create(DLANG(CHAT, NO_PERMS));
|
djui_chat_message_create(DLANG(CHAT, NO_PERMS));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -226,12 +221,15 @@ bool exec_chat_command(char* command) {
|
||||||
|
|
||||||
void display_chat_commands(void) {
|
void display_chat_commands(void) {
|
||||||
djui_chat_message_create(DLANG(CHAT, PLAYERS_DESC));
|
djui_chat_message_create(DLANG(CHAT, PLAYERS_DESC));
|
||||||
if (gNetworkType == NT_SERVER || gIsModerator) {
|
if (gNetworkType == NT_SERVER || gNetworkPlayers[0].moderator) {
|
||||||
djui_chat_message_create(DLANG(CHAT, KICK_DESC));
|
djui_chat_message_create(DLANG(CHAT, KICK_DESC));
|
||||||
djui_chat_message_create(DLANG(CHAT, BAN_DESC));
|
djui_chat_message_create(DLANG(CHAT, BAN_DESC));
|
||||||
|
|
||||||
|
if (gNetworkType == NT_SERVER) {
|
||||||
djui_chat_message_create(DLANG(CHAT, PERM_BAN_DESC));
|
djui_chat_message_create(DLANG(CHAT, PERM_BAN_DESC));
|
||||||
djui_chat_message_create(DLANG(CHAT, MOD_DESC));
|
djui_chat_message_create(DLANG(CHAT, MOD_DESC));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#if defined(DEVELOPMENT)
|
#if defined(DEVELOPMENT)
|
||||||
dev_display_chat_commands();
|
dev_display_chat_commands();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -43,7 +43,7 @@ static inline int arg_uint(UNUSED const char *name, const char *value, unsigned
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_cli_opts(int argc, char* argv[]) {
|
inline void parse_cli_opts(int argc, char* argv[]) {
|
||||||
// Initialize options with false values.
|
// Initialize options with false values.
|
||||||
memset(&gCLIOpts, 0, sizeof(gCLIOpts));
|
memset(&gCLIOpts, 0, sizeof(gCLIOpts));
|
||||||
|
|
||||||
|
|
|
@ -113,8 +113,8 @@ unsigned int configCameraPan = 0;
|
||||||
unsigned int configCameraDegrade = 50; // 0 - 100%
|
unsigned int configCameraDegrade = 50; // 0 - 100%
|
||||||
bool configCameraInvertX = false;
|
bool configCameraInvertX = false;
|
||||||
bool configCameraInvertY = true;
|
bool configCameraInvertY = true;
|
||||||
bool configEnableCamera = true;
|
bool configEnableCamera = false;
|
||||||
bool configCameraAnalog = true;
|
bool configCameraAnalog = false;
|
||||||
bool configCameraMouse = false;
|
bool configCameraMouse = false;
|
||||||
#endif
|
#endif
|
||||||
bool configSkipIntro = 0;
|
bool configSkipIntro = 0;
|
||||||
|
|
|
@ -27,6 +27,7 @@ char gLastRemoteBhv[256] = "";
|
||||||
#include "pc/gfx/gfx_rendering_api.h"
|
#include "pc/gfx/gfx_rendering_api.h"
|
||||||
#include "pc/mods/mods.h"
|
#include "pc/mods/mods.h"
|
||||||
#include "pc/debuglog.h"
|
#include "pc/debuglog.h"
|
||||||
|
#include "pc/pc_main.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
s32 x, y;
|
s32 x, y;
|
||||||
|
@ -659,16 +660,12 @@ static void crash_handler(const int signalNum, siginfo_t *info, ucontext_t *cont
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
while (true) {
|
while (true) {
|
||||||
#if defined(WAPI_SDL1) || defined(WAPI_SDL2)
|
WAPI.main_loop(crash_handler_produce_one_frame);
|
||||||
gfx_sdl.main_loop(crash_handler_produce_one_frame);
|
|
||||||
#elif defined(WAPI_DXGI)
|
|
||||||
gfx_dxgi.main_loop(crash_handler_produce_one_frame);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((constructor)) static void init_crash_handler() {
|
AT_STARTUP static void init_crash_handler() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Windows
|
// Windows
|
||||||
SetUnhandledExceptionFilter(crash_handler);
|
SetUnhandledExceptionFilter(crash_handler);
|
||||||
|
|
|
@ -136,18 +136,18 @@ void discord_activity_update(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void discord_activity_update_check(void) {
|
void discord_activity_update_check(void) {
|
||||||
|
#ifdef COOPNET
|
||||||
if (sQueuedLobby > 0) {
|
if (sQueuedLobby > 0) {
|
||||||
if (--sQueuedLobby == 0) {
|
if (--sQueuedLobby == 0) {
|
||||||
#ifdef COOPNET
|
|
||||||
gCoopNetDesiredLobby = sQueuedLobbyId;
|
gCoopNetDesiredLobby = sQueuedLobbyId;
|
||||||
snprintf(gCoopNetPassword, 64, "%s", sQueuedLobbyPassword);
|
snprintf(gCoopNetPassword, 64, "%s", sQueuedLobbyPassword);
|
||||||
network_reset_reconnect_and_rehost();
|
network_reset_reconnect_and_rehost();
|
||||||
network_set_system(NS_COOPNET);
|
network_set_system(NS_COOPNET);
|
||||||
network_init(NT_CLIENT, false);
|
network_init(NT_CLIENT, false);
|
||||||
djui_panel_join_message_create(NULL);
|
djui_panel_join_message_create(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gNetworkType == NT_NONE) { return; }
|
if (gNetworkType == NT_NONE) { return; }
|
||||||
bool shouldUpdate = false;
|
bool shouldUpdate = false;
|
||||||
|
|
|
@ -3,11 +3,13 @@
|
||||||
|
|
||||||
#define DJUI_DEFAULT_PANEL_WIDTH (500.0f + (16 * 2.0f))
|
#define DJUI_DEFAULT_PANEL_WIDTH (500.0f + (16 * 2.0f))
|
||||||
#define DJUI_PANEL_HEADER_OFFSET (-16)
|
#define DJUI_PANEL_HEADER_OFFSET (-16)
|
||||||
|
#define DJUI_PANEL_MOVE_MAX 1.0f
|
||||||
|
|
||||||
struct DjuiPanel {
|
struct DjuiPanel {
|
||||||
struct DjuiBase* base;
|
struct DjuiBase* base;
|
||||||
struct DjuiPanel* parent;
|
struct DjuiPanel* parent;
|
||||||
struct DjuiBase* defaultElementBase;
|
struct DjuiBase* defaultElementBase;
|
||||||
|
bool temporary;
|
||||||
void (*on_panel_destroy)(struct DjuiBase*);
|
void (*on_panel_destroy)(struct DjuiBase*);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27294,6 +27294,48 @@ int smlua_func_smlua_audio_utils_reset_all(UNUSED lua_State* L) {
|
||||||
// smlua_collision_utils.h //
|
// smlua_collision_utils.h //
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
|
|
||||||
|
int smlua_func_collision_find_ceil(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 3) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "collision_find_ceil", 3, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 x = smlua_to_number(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "collision_find_ceil"); return 0; }
|
||||||
|
f32 y = smlua_to_number(L, 2);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "collision_find_ceil"); return 0; }
|
||||||
|
f32 z = smlua_to_number(L, 3);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "collision_find_ceil"); return 0; }
|
||||||
|
|
||||||
|
smlua_push_object(L, LOT_SURFACE, collision_find_ceil(x, y, z));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smlua_func_collision_find_floor(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 3) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "collision_find_floor", 3, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 x = smlua_to_number(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "collision_find_floor"); return 0; }
|
||||||
|
f32 y = smlua_to_number(L, 2);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "collision_find_floor"); return 0; }
|
||||||
|
f32 z = smlua_to_number(L, 3);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "collision_find_floor"); return 0; }
|
||||||
|
|
||||||
|
smlua_push_object(L, LOT_SURFACE, collision_find_floor(x, y, z));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int smlua_func_collision_find_surface_on_ray(lua_State* L) {
|
int smlua_func_collision_find_surface_on_ray(lua_State* L) {
|
||||||
if (L == NULL) { return 0; }
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
@ -27475,6 +27517,23 @@ int smlua_func_smlua_level_util_get_info(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smlua_func_smlua_level_util_get_info_from_course_num(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 1) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_level_util_get_info_from_course_num", 1, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 courseNum = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_level_util_get_info_from_course_num"); return 0; }
|
||||||
|
|
||||||
|
smlua_push_object(L, LOT_CUSTOMLEVELINFO, smlua_level_util_get_info_from_course_num(courseNum));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int smlua_func_smlua_level_util_get_info_from_short_name(lua_State* L) {
|
int smlua_func_smlua_level_util_get_info_from_short_name(lua_State* L) {
|
||||||
if (L == NULL) { return 0; }
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
@ -29844,6 +29903,84 @@ int smlua_func_spawn_sync_object(lua_State* L) {
|
||||||
// smlua_text_utils.h //
|
// smlua_text_utils.h //
|
||||||
////////////////////////
|
////////////////////////
|
||||||
|
|
||||||
|
int smlua_func_smlua_text_utils_act_name_get(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 2) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_act_name_get", 2, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s16 courseNum = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_act_name_get"); return 0; }
|
||||||
|
u8 actNum = smlua_to_integer(L, 2);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "smlua_text_utils_act_name_get"); return 0; }
|
||||||
|
|
||||||
|
lua_pushstring(L, smlua_text_utils_act_name_get(courseNum, actNum));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smlua_func_smlua_text_utils_act_name_is_modified(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 2) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_act_name_is_modified", 2, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s16 courseNum = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_act_name_is_modified"); return 0; }
|
||||||
|
u8 actNum = smlua_to_integer(L, 2);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "smlua_text_utils_act_name_is_modified"); return 0; }
|
||||||
|
|
||||||
|
lua_pushboolean(L, smlua_text_utils_act_name_is_modified(courseNum, actNum));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smlua_func_smlua_text_utils_act_name_replace(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 3) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_act_name_replace", 3, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s16 courseNum = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_act_name_replace"); return 0; }
|
||||||
|
u8 actNum = smlua_to_integer(L, 2);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "smlua_text_utils_act_name_replace"); return 0; }
|
||||||
|
const char* name = smlua_to_string(L, 3);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "smlua_text_utils_act_name_replace"); return 0; }
|
||||||
|
|
||||||
|
smlua_text_utils_act_name_replace(courseNum, actNum, name);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smlua_func_smlua_text_utils_act_name_reset(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 2) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_act_name_reset", 2, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s16 courseNum = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_act_name_reset"); return 0; }
|
||||||
|
u8 actNum = smlua_to_integer(L, 2);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "smlua_text_utils_act_name_reset"); return 0; }
|
||||||
|
|
||||||
|
smlua_text_utils_act_name_reset(courseNum, actNum);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int smlua_func_smlua_text_utils_castle_secret_stars_replace(lua_State* L) {
|
int smlua_func_smlua_text_utils_castle_secret_stars_replace(lua_State* L) {
|
||||||
if (L == NULL) { return 0; }
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
@ -29892,6 +30029,76 @@ int smlua_func_smlua_text_utils_course_acts_replace(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smlua_func_smlua_text_utils_course_name_get(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 1) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_course_name_get", 1, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s16 courseNum = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_course_name_get"); return 0; }
|
||||||
|
|
||||||
|
lua_pushstring(L, smlua_text_utils_course_name_get(courseNum));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smlua_func_smlua_text_utils_course_name_mod_index(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 1) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_course_name_mod_index", 1, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s16 courseNum = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_course_name_mod_index"); return 0; }
|
||||||
|
|
||||||
|
lua_pushinteger(L, smlua_text_utils_course_name_mod_index(courseNum));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smlua_func_smlua_text_utils_course_name_replace(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 2) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_course_name_replace", 2, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s16 courseNum = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_course_name_replace"); return 0; }
|
||||||
|
const char* name = smlua_to_string(L, 2);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "smlua_text_utils_course_name_replace"); return 0; }
|
||||||
|
|
||||||
|
smlua_text_utils_course_name_replace(courseNum, name);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smlua_func_smlua_text_utils_course_name_reset(lua_State* L) {
|
||||||
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if (top != 1) {
|
||||||
|
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_course_name_reset", 1, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s16 courseNum = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_course_name_reset"); return 0; }
|
||||||
|
|
||||||
|
smlua_text_utils_course_name_reset(courseNum);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int smlua_func_smlua_text_utils_dialog_replace(lua_State* L) {
|
int smlua_func_smlua_text_utils_dialog_replace(lua_State* L) {
|
||||||
if (L == NULL) { return 0; }
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
@ -29953,21 +30160,6 @@ int smlua_func_smlua_text_utils_get_language(UNUSED lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int smlua_func_smlua_text_utils_reset_all(UNUSED lua_State* L) {
|
|
||||||
if (L == NULL) { return 0; }
|
|
||||||
|
|
||||||
int top = lua_gettop(L);
|
|
||||||
if (top != 0) {
|
|
||||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_reset_all", 0, top);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
smlua_text_utils_reset_all();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int smlua_func_smlua_text_utils_secret_star_replace(lua_State* L) {
|
int smlua_func_smlua_text_utils_secret_star_replace(lua_State* L) {
|
||||||
if (L == NULL) { return 0; }
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
@ -32135,6 +32327,8 @@ void smlua_bind_functions_autogen(void) {
|
||||||
smlua_bind_function(L, "smlua_audio_utils_reset_all", smlua_func_smlua_audio_utils_reset_all);
|
smlua_bind_function(L, "smlua_audio_utils_reset_all", smlua_func_smlua_audio_utils_reset_all);
|
||||||
|
|
||||||
// smlua_collision_utils.h
|
// smlua_collision_utils.h
|
||||||
|
smlua_bind_function(L, "collision_find_ceil", smlua_func_collision_find_ceil);
|
||||||
|
smlua_bind_function(L, "collision_find_floor", smlua_func_collision_find_floor);
|
||||||
smlua_bind_function(L, "collision_find_surface_on_ray", smlua_func_collision_find_surface_on_ray);
|
smlua_bind_function(L, "collision_find_surface_on_ray", smlua_func_collision_find_surface_on_ray);
|
||||||
smlua_bind_function(L, "collision_get_temp_wall_collision_data", smlua_func_collision_get_temp_wall_collision_data);
|
smlua_bind_function(L, "collision_get_temp_wall_collision_data", smlua_func_collision_get_temp_wall_collision_data);
|
||||||
smlua_bind_function(L, "get_water_surface_pseudo_floor", smlua_func_get_water_surface_pseudo_floor);
|
smlua_bind_function(L, "get_water_surface_pseudo_floor", smlua_func_get_water_surface_pseudo_floor);
|
||||||
|
@ -32148,6 +32342,7 @@ void smlua_bind_functions_autogen(void) {
|
||||||
smlua_bind_function(L, "level_register", smlua_func_level_register);
|
smlua_bind_function(L, "level_register", smlua_func_level_register);
|
||||||
smlua_bind_function(L, "smlua_level_util_change_area", smlua_func_smlua_level_util_change_area);
|
smlua_bind_function(L, "smlua_level_util_change_area", smlua_func_smlua_level_util_change_area);
|
||||||
smlua_bind_function(L, "smlua_level_util_get_info", smlua_func_smlua_level_util_get_info);
|
smlua_bind_function(L, "smlua_level_util_get_info", smlua_func_smlua_level_util_get_info);
|
||||||
|
smlua_bind_function(L, "smlua_level_util_get_info_from_course_num", smlua_func_smlua_level_util_get_info_from_course_num);
|
||||||
smlua_bind_function(L, "smlua_level_util_get_info_from_short_name", smlua_func_smlua_level_util_get_info_from_short_name);
|
smlua_bind_function(L, "smlua_level_util_get_info_from_short_name", smlua_func_smlua_level_util_get_info_from_short_name);
|
||||||
smlua_bind_function(L, "warp_exit_level", smlua_func_warp_exit_level);
|
smlua_bind_function(L, "warp_exit_level", smlua_func_warp_exit_level);
|
||||||
smlua_bind_function(L, "warp_restart_level", smlua_func_warp_restart_level);
|
smlua_bind_function(L, "warp_restart_level", smlua_func_warp_restart_level);
|
||||||
|
@ -32291,12 +32486,19 @@ void smlua_bind_functions_autogen(void) {
|
||||||
smlua_bind_function(L, "spawn_sync_object", smlua_func_spawn_sync_object);
|
smlua_bind_function(L, "spawn_sync_object", smlua_func_spawn_sync_object);
|
||||||
|
|
||||||
// smlua_text_utils.h
|
// smlua_text_utils.h
|
||||||
|
smlua_bind_function(L, "smlua_text_utils_act_name_get", smlua_func_smlua_text_utils_act_name_get);
|
||||||
|
smlua_bind_function(L, "smlua_text_utils_act_name_is_modified", smlua_func_smlua_text_utils_act_name_is_modified);
|
||||||
|
smlua_bind_function(L, "smlua_text_utils_act_name_replace", smlua_func_smlua_text_utils_act_name_replace);
|
||||||
|
smlua_bind_function(L, "smlua_text_utils_act_name_reset", smlua_func_smlua_text_utils_act_name_reset);
|
||||||
smlua_bind_function(L, "smlua_text_utils_castle_secret_stars_replace", smlua_func_smlua_text_utils_castle_secret_stars_replace);
|
smlua_bind_function(L, "smlua_text_utils_castle_secret_stars_replace", smlua_func_smlua_text_utils_castle_secret_stars_replace);
|
||||||
smlua_bind_function(L, "smlua_text_utils_course_acts_replace", smlua_func_smlua_text_utils_course_acts_replace);
|
smlua_bind_function(L, "smlua_text_utils_course_acts_replace", smlua_func_smlua_text_utils_course_acts_replace);
|
||||||
|
smlua_bind_function(L, "smlua_text_utils_course_name_get", smlua_func_smlua_text_utils_course_name_get);
|
||||||
|
smlua_bind_function(L, "smlua_text_utils_course_name_mod_index", smlua_func_smlua_text_utils_course_name_mod_index);
|
||||||
|
smlua_bind_function(L, "smlua_text_utils_course_name_replace", smlua_func_smlua_text_utils_course_name_replace);
|
||||||
|
smlua_bind_function(L, "smlua_text_utils_course_name_reset", smlua_func_smlua_text_utils_course_name_reset);
|
||||||
smlua_bind_function(L, "smlua_text_utils_dialog_replace", smlua_func_smlua_text_utils_dialog_replace);
|
smlua_bind_function(L, "smlua_text_utils_dialog_replace", smlua_func_smlua_text_utils_dialog_replace);
|
||||||
smlua_bind_function(L, "smlua_text_utils_extra_text_replace", smlua_func_smlua_text_utils_extra_text_replace);
|
smlua_bind_function(L, "smlua_text_utils_extra_text_replace", smlua_func_smlua_text_utils_extra_text_replace);
|
||||||
smlua_bind_function(L, "smlua_text_utils_get_language", smlua_func_smlua_text_utils_get_language);
|
smlua_bind_function(L, "smlua_text_utils_get_language", smlua_func_smlua_text_utils_get_language);
|
||||||
smlua_bind_function(L, "smlua_text_utils_reset_all", smlua_func_smlua_text_utils_reset_all);
|
|
||||||
smlua_bind_function(L, "smlua_text_utils_secret_star_replace", smlua_func_smlua_text_utils_secret_star_replace);
|
smlua_bind_function(L, "smlua_text_utils_secret_star_replace", smlua_func_smlua_text_utils_secret_star_replace);
|
||||||
|
|
||||||
// sound_init.h
|
// sound_init.h
|
||||||
|
|
|
@ -417,13 +417,15 @@ void smlua_push_object(lua_State* L, u16 lot, void* p) {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
u64 pointer = (uintptr_t) p;
|
||||||
|
|
||||||
// add to allowlist
|
// add to allowlist
|
||||||
smlua_cobject_allowlist_add(lot, (u64)(intptr_t)p);
|
smlua_cobject_allowlist_add(lot, pointer);
|
||||||
|
|
||||||
// get a cobject from a function
|
// get a cobject from a function
|
||||||
lua_getglobal(L, "_NewCObject"); // Get the function by its global name
|
lua_getglobal(L, "_NewCObject"); // Get the function by its global name
|
||||||
lua_pushinteger(L, lot);
|
lua_pushinteger(L, lot);
|
||||||
lua_pushinteger(L, (u64)(intptr_t)p);
|
lua_pushinteger(L, pointer);
|
||||||
|
|
||||||
if (lua_pcall(L, 2, 1, 0) != LUA_OK) {
|
if (lua_pcall(L, 2, 1, 0) != LUA_OK) {
|
||||||
LOG_ERROR("Error calling Lua function: %s\n", lua_tostring(L, -1));
|
LOG_ERROR("Error calling Lua function: %s\n", lua_tostring(L, -1));
|
||||||
|
@ -436,12 +438,13 @@ void smlua_push_pointer(lua_State* L, u16 lvt, void* p) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
smlua_cpointer_allowlist_add(lvt, (u64)(intptr_t)p);
|
u64 pointer = (uintptr_t) p;
|
||||||
|
smlua_cpointer_allowlist_add(lvt, pointer);
|
||||||
|
|
||||||
// get a cpointer from a function
|
// get a cpointer from a function
|
||||||
lua_getglobal(L, "_NewCPointer"); // Get the function by its global name
|
lua_getglobal(L, "_NewCPointer"); // Get the function by its global name
|
||||||
lua_pushinteger(L, lvt);
|
lua_pushinteger(L, lvt);
|
||||||
lua_pushinteger(L, (u64)(intptr_t)p);
|
lua_pushinteger(L, pointer);
|
||||||
if (lua_pcall(L, 2, 1, 0) != LUA_OK) {
|
if (lua_pcall(L, 2, 1, 0) != LUA_OK) {
|
||||||
LOG_ERROR("Error calling Lua function: %s\n", lua_tostring(L, -1));
|
LOG_ERROR("Error calling Lua function: %s\n", lua_tostring(L, -1));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#include "src/engine/surface_collision.h"
|
#include "src/engine/surface_collision.h"
|
||||||
|
#include "include/surface_terrains.h"
|
||||||
#include "game/mario_step.h"
|
#include "game/mario_step.h"
|
||||||
|
|
||||||
#include "pc/lua/smlua.h"
|
#include "pc/lua/smlua.h"
|
||||||
|
@ -164,6 +165,18 @@ struct RayIntersectionInfo* collision_find_surface_on_ray(f32 startX, f32 startY
|
||||||
return &info;
|
return &info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Surface* collision_find_floor(f32 x, f32 y, f32 z) {
|
||||||
|
static struct Surface *surface;
|
||||||
|
find_floor(x, y, z, &surface);
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Surface* collision_find_ceil(f32 x, f32 y, f32 z) {
|
||||||
|
static struct Surface *surface;
|
||||||
|
find_ceil(x, y, z, &surface);
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
struct Surface* get_water_surface_pseudo_floor(void) {
|
struct Surface* get_water_surface_pseudo_floor(void) {
|
||||||
return &gWaterSurfacePseudoFloor;
|
return &gWaterSurfacePseudoFloor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,6 +116,10 @@ extern struct GlobalObjectCollisionData gGlobalObjectCollisionData;
|
||||||
|
|
||||||
struct RayIntersectionInfo* collision_find_surface_on_ray(f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ);
|
struct RayIntersectionInfo* collision_find_surface_on_ray(f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ);
|
||||||
|
|
||||||
|
struct Surface* collision_find_floor(f32 x, f32 y, f32 z);
|
||||||
|
|
||||||
|
struct Surface* collision_find_ceil(f32 x, f32 y, f32 z);
|
||||||
|
|
||||||
struct Surface* get_water_surface_pseudo_floor(void);
|
struct Surface* get_water_surface_pseudo_floor(void);
|
||||||
|
|
||||||
Collision* smlua_collision_util_get(const char* name);
|
Collision* smlua_collision_util_get(const char* name);
|
||||||
|
|
|
@ -73,6 +73,17 @@ static struct CustomLevelInfo* smlua_level_util_get_info_from_script(char* scrip
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CustomLevelInfo* smlua_level_util_get_info_from_course_num(u8 courseNum) {
|
||||||
|
struct CustomLevelInfo* node = sCustomLevelHead;
|
||||||
|
while (node != NULL) {
|
||||||
|
if (node->courseNum == courseNum) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3) {
|
s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3) {
|
||||||
// validate params
|
// validate params
|
||||||
if (scriptEntryName == NULL) {
|
if (scriptEntryName == NULL) {
|
||||||
|
|
|
@ -21,7 +21,8 @@ struct CustomLevelInfo {
|
||||||
void smlua_level_util_reset(void);
|
void smlua_level_util_reset(void);
|
||||||
void smlua_level_util_change_area(s32 areaIndex);
|
void smlua_level_util_change_area(s32 areaIndex);
|
||||||
struct CustomLevelInfo* smlua_level_util_get_info(s16 levelNum);
|
struct CustomLevelInfo* smlua_level_util_get_info(s16 levelNum);
|
||||||
struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(const char* shortName);
|
struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(char* shortName);
|
||||||
|
struct CustomLevelInfo* smlua_level_util_get_info_from_course_num(u8 courseNum);
|
||||||
s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3);
|
s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3);
|
||||||
bool level_is_vanilla_level(s16 levelNum);
|
bool level_is_vanilla_level(s16 levelNum);
|
||||||
bool warp_to_warpnode(s32 aLevel, s32 aArea, s32 aAct, s32 aWarpId);
|
bool warp_to_warpnode(s32 aLevel, s32 aArea, s32 aAct, s32 aWarpId);
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
#include "game/ingame_menu.h"
|
#include "game/ingame_menu.h"
|
||||||
#include "game/save_file.h"
|
#include "game/save_file.h"
|
||||||
#include "game/segment2.h"
|
#include "game/segment2.h"
|
||||||
|
#include "game/level_info.h"
|
||||||
|
#include "pc/pc_main.h"
|
||||||
|
#include "../smlua.h"
|
||||||
|
#include "smlua_level_utils.h"
|
||||||
|
#include "smlua_text_utils.h"
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
#ifdef VERSION_EU
|
||||||
extern s32 gInGameLanguage;
|
extern s32 gInGameLanguage;
|
||||||
|
@ -15,6 +20,42 @@ static bool sReplacedDialog[DIALOG_COUNT] = { 0 };
|
||||||
static bool sReplacedCourseName[COURSE_COUNT+2] = { 0 };
|
static bool sReplacedCourseName[COURSE_COUNT+2] = { 0 };
|
||||||
static bool sReplacedActName[(COURSE_RR+2)*6] = { 0 };
|
static bool sReplacedActName[(COURSE_RR+2)*6] = { 0 };
|
||||||
|
|
||||||
|
#define INVALID_COURSE_NUM(courseNum) (smlua_level_util_get_info_from_course_num(courseNum) == NULL && !COURSE_IS_VALID_COURSE(courseNum))
|
||||||
|
|
||||||
|
void convert_string_sm64_to_ascii(char *strAscii, const u8 *str64);
|
||||||
|
|
||||||
|
struct CourseName *gReplacedActNameTable[COURSE_COUNT];
|
||||||
|
|
||||||
|
// Save all vanilla act names and course names
|
||||||
|
AT_STARTUP static void smlua_text_utils_init() {
|
||||||
|
void **actNameTbl = get_act_name_table();
|
||||||
|
void **courseNameTbl = get_course_name_table();
|
||||||
|
char courseBuffer[50];
|
||||||
|
char actBuffer[50];
|
||||||
|
|
||||||
|
for (s16 courseNum = 0; courseNum < COURSE_COUNT; courseNum++) {
|
||||||
|
const u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum]);
|
||||||
|
convert_string_sm64_to_ascii(courseBuffer, courseName);
|
||||||
|
gReplacedActNameTable[courseNum] = malloc(sizeof(struct CourseName));
|
||||||
|
struct CourseName* courseActNames = gReplacedActNameTable[courseNum];
|
||||||
|
snprintf(courseActNames->name, 50, "%s", courseBuffer);
|
||||||
|
snprintf(courseActNames->orig, 50, "%s", courseBuffer);
|
||||||
|
courseActNames->modIndex = -1;
|
||||||
|
|
||||||
|
// Individual acts
|
||||||
|
if (COURSE_IS_MAIN_COURSE(courseNum)) {
|
||||||
|
courseActNames->actName = calloc(6, sizeof(struct ActName));
|
||||||
|
for (s16 actNum = 0; actNum < 6; actNum++) {
|
||||||
|
const u8 *starName = segmented_to_virtual(actNameTbl[courseNum * 6 + actNum]);
|
||||||
|
convert_string_sm64_to_ascii(actBuffer, starName);
|
||||||
|
snprintf(courseActNames->actName[actNum].name, 50, "%s", actBuffer);
|
||||||
|
snprintf(courseActNames->actName[actNum].orig, 50, "%s", actBuffer);
|
||||||
|
courseActNames->actName[actNum].isModified = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static u8* smlua_text_utils_convert(const char* str) {
|
static u8* smlua_text_utils_convert(const char* str) {
|
||||||
s32 len = strlen(str);
|
s32 len = strlen(str);
|
||||||
u8* dialogStr = calloc(len + 2, sizeof(u8));
|
u8* dialogStr = calloc(len + 2, sizeof(u8));
|
||||||
|
@ -87,6 +128,20 @@ void smlua_text_utils_reset_all(void) {
|
||||||
actNameTbl[i] = segmented_to_virtual(actNameTblOrg[i]);
|
actNameTbl[i] = segmented_to_virtual(actNameTblOrg[i]);
|
||||||
sReplacedActName[i] = false;
|
sReplacedActName[i] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (s32 courseNum = 0; courseNum < COURSE_COUNT; courseNum++) {
|
||||||
|
struct CourseName* courseActNames = gReplacedActNameTable[courseNum];
|
||||||
|
snprintf(courseActNames->name, 50, "%s", courseActNames->orig);
|
||||||
|
courseActNames->modIndex = -1;
|
||||||
|
|
||||||
|
// Individual acts
|
||||||
|
if (COURSE_IS_MAIN_COURSE(courseNum)) {
|
||||||
|
for (s16 actNum = 0; actNum < 6; actNum++) {
|
||||||
|
snprintf(courseActNames->actName[actNum].name, 50, "%s", courseActNames->actName[actNum].orig);
|
||||||
|
courseActNames->actName[actNum].isModified = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void smlua_text_utils_dialog_replace(enum DialogId dialogId, UNUSED u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str) {
|
void smlua_text_utils_dialog_replace(enum DialogId dialogId, UNUSED u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str) {
|
||||||
|
@ -124,75 +179,88 @@ void smlua_text_utils_dialog_replace(enum DialogId dialogId, UNUSED u32 unused,
|
||||||
sReplacedDialog[dialogId] = true;
|
sReplacedDialog[dialogId] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define REPLACE_ACT_NAME(i) \
|
||||||
|
snprintf(courseActNames->actName[i-1].name, 256, "%s", act##i); \
|
||||||
|
courseActNames->actName[i-1].isModified = true; \
|
||||||
|
|
||||||
void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6) {
|
void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6) {
|
||||||
if (courseNum <= 0 || courseNum > COURSE_RR) { return; }
|
if (courseNum <= 0 || courseNum > COURSE_RR) { return; }
|
||||||
s16 courseOffset = courseNum - 1;
|
struct CourseName* courseActNames = gReplacedActNameTable[courseNum];
|
||||||
|
snprintf(courseActNames->name, 256, "%s", courseName + 3);
|
||||||
|
courseActNames->modIndex = gLuaActiveMod->index;
|
||||||
|
|
||||||
void **actNameTbl = NULL;
|
REPLACE_ACT_NAME(1);
|
||||||
void **courseNameTbl = NULL;
|
REPLACE_ACT_NAME(2);
|
||||||
|
REPLACE_ACT_NAME(3);
|
||||||
|
REPLACE_ACT_NAME(4);
|
||||||
|
REPLACE_ACT_NAME(5);
|
||||||
|
REPLACE_ACT_NAME(6);
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
LOG_INFO("%d (%s) replacing act names 1-6 of course %d, (%s), act 1: %s", courseActNames->modIndex, gLuaActiveMod->name, courseNum, courseName, act1);
|
||||||
switch (gInGameLanguage) {
|
}
|
||||||
case LANGUAGE_ENGLISH:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_en);
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_FRENCH:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_fr);
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_GERMAN:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_de);
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
actNameTbl = segmented_to_virtual(seg2_act_name_table);
|
|
||||||
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// replace course name
|
void smlua_text_utils_course_name_replace(s16 courseNum, const char* name) {
|
||||||
if (sReplacedCourseName[courseOffset]) {
|
if (INVALID_COURSE_NUM(courseNum)) { return; }
|
||||||
free(courseNameTbl[courseOffset]);
|
|
||||||
}
|
|
||||||
courseNameTbl[courseOffset] = smlua_text_utils_convert(courseName);
|
|
||||||
sReplacedCourseName[courseOffset] = true;
|
|
||||||
|
|
||||||
// replace act names
|
struct CourseName* courseActNames = gReplacedActNameTable[courseNum];
|
||||||
const char* newActs[] = { act1, act2, act3, act4, act5, act6 };
|
snprintf(courseActNames->name, 256, "%s", name);
|
||||||
for (s32 i = 0; i < 6; i++) {
|
courseActNames->modIndex = gLuaActiveMod->index;
|
||||||
s32 index = (courseOffset * 6 + i);
|
}
|
||||||
|
|
||||||
if (sReplacedActName[index]) {
|
const char* smlua_text_utils_course_name_get(s16 courseNum) {
|
||||||
free(actNameTbl[index]);
|
if (INVALID_COURSE_NUM(courseNum)) { return NULL; }
|
||||||
}
|
|
||||||
|
|
||||||
actNameTbl[index] = smlua_text_utils_convert(newActs[i]);
|
return gReplacedActNameTable[courseNum]->name;
|
||||||
sReplacedActName[index] = true;
|
}
|
||||||
}
|
|
||||||
|
s32 smlua_text_utils_course_name_mod_index(s16 courseNum) {
|
||||||
|
if (INVALID_COURSE_NUM(courseNum)) { return -1; }
|
||||||
|
|
||||||
|
return gReplacedActNameTable[courseNum]->modIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void smlua_text_utils_course_name_reset(s16 courseNum) {
|
||||||
|
if (INVALID_COURSE_NUM(courseNum)) { return; }
|
||||||
|
|
||||||
|
struct CourseName* courseActNames = gReplacedActNameTable[courseNum];
|
||||||
|
snprintf(courseActNames->name, 50, "%s", courseActNames->orig);
|
||||||
|
courseActNames->modIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void smlua_text_utils_act_name_replace(s16 courseNum, u8 actNum, const char* name) {
|
||||||
|
if (INVALID_COURSE_NUM(courseNum) || actNum > 7) { return; }
|
||||||
|
|
||||||
|
struct CourseName* courseActNames = gReplacedActNameTable[courseNum];
|
||||||
|
|
||||||
|
snprintf(courseActNames->actName[actNum].name, 256, "%s", name);
|
||||||
|
courseActNames->actName[actNum].isModified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* smlua_text_utils_act_name_get(s16 courseNum, u8 actNum) {
|
||||||
|
if (INVALID_COURSE_NUM(courseNum) || actNum > 7) { return NULL; }
|
||||||
|
|
||||||
|
return gReplacedActNameTable[courseNum]->actName[actNum].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool smlua_text_utils_act_name_is_modified(s16 courseNum, u8 actNum) {
|
||||||
|
if (INVALID_COURSE_NUM(courseNum) || actNum > 7) { return false; }
|
||||||
|
|
||||||
|
return gReplacedActNameTable[courseNum]->actName[actNum].isModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
void smlua_text_utils_act_name_reset(s16 courseNum, u8 actNum) {
|
||||||
|
if (INVALID_COURSE_NUM(courseNum) || actNum > 7) { return; }
|
||||||
|
|
||||||
|
struct CourseName* courseActNames = gReplacedActNameTable[courseNum];
|
||||||
|
snprintf(courseActNames->actName[actNum].name, 50, "%s", courseActNames->actName[actNum].orig);
|
||||||
|
courseActNames->actName[actNum].isModified = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smlua_text_utils_secret_star_replace(s16 courseNum, const char* courseName) {
|
void smlua_text_utils_secret_star_replace(s16 courseNum, const char* courseName) {
|
||||||
if (courseNum <= COURSE_RR || courseNum > COURSE_COUNT) { return; }
|
if (courseNum <= COURSE_RR || courseNum > COURSE_COUNT) { return; }
|
||||||
s16 courseOffset = courseNum - 1;
|
s16 courseOffset = courseNum - 1;
|
||||||
|
|
||||||
void **courseNameTbl = NULL;
|
void **courseNameTbl = get_course_name_table();
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
|
||||||
switch (gInGameLanguage) {
|
|
||||||
case LANGUAGE_ENGLISH:
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_FRENCH:
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_GERMAN:
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (sReplacedCourseName[courseOffset]) {
|
if (sReplacedCourseName[courseOffset]) {
|
||||||
free(courseNameTbl[courseOffset]);
|
free(courseNameTbl[courseOffset]);
|
||||||
|
@ -205,23 +273,7 @@ void smlua_text_utils_secret_star_replace(s16 courseNum, const char* courseName)
|
||||||
void smlua_text_utils_castle_secret_stars_replace(const char* name) {
|
void smlua_text_utils_castle_secret_stars_replace(const char* name) {
|
||||||
s16 courseOffset = COURSE_COUNT;
|
s16 courseOffset = COURSE_COUNT;
|
||||||
|
|
||||||
void **courseNameTbl = NULL;
|
void **courseNameTbl = get_course_name_table();
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
|
||||||
switch (gInGameLanguage) {
|
|
||||||
case LANGUAGE_ENGLISH:
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_FRENCH:
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_GERMAN:
|
|
||||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (sReplacedCourseName[courseOffset]) {
|
if (sReplacedCourseName[courseOffset]) {
|
||||||
free(courseNameTbl[courseOffset]);
|
free(courseNameTbl[courseOffset]);
|
||||||
|
@ -235,23 +287,7 @@ void smlua_text_utils_extra_text_replace(s16 index, const char* text) {
|
||||||
if (index < 0 || index > 6) { return; }
|
if (index < 0 || index > 6) { return; }
|
||||||
index = (COURSE_RR * 6 + index);
|
index = (COURSE_RR * 6 + index);
|
||||||
|
|
||||||
void **actNameTbl = NULL;
|
void **actNameTbl = get_act_name_table();
|
||||||
|
|
||||||
#ifdef VERSION_EU
|
|
||||||
switch (gInGameLanguage) {
|
|
||||||
case LANGUAGE_ENGLISH:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_en);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_FRENCH:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_fr);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_GERMAN:
|
|
||||||
actNameTbl = segmented_to_virtual(act_name_table_eu_de);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
actNameTbl = segmented_to_virtual(seg2_act_name_table);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (sReplacedActName[index]) {
|
if (sReplacedActName[index]) {
|
||||||
free(actNameTbl[index]);
|
free(actNameTbl[index]);
|
||||||
|
|
|
@ -4,10 +4,31 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "dialog_ids.h"
|
#include "dialog_ids.h"
|
||||||
|
|
||||||
|
struct ActName {
|
||||||
|
char name[256];
|
||||||
|
char orig[256];
|
||||||
|
bool isModified;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CourseName {
|
||||||
|
struct ActName *actName;
|
||||||
|
char name[256];
|
||||||
|
char orig[256];
|
||||||
|
s32 modIndex;
|
||||||
|
};
|
||||||
|
|
||||||
void smlua_text_utils_reset_all(void);
|
void smlua_text_utils_reset_all(void);
|
||||||
void smlua_text_utils_dialog_replace(enum DialogId dialogId, u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str);
|
void smlua_text_utils_dialog_replace(enum DialogId dialogId, u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str);
|
||||||
void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6);
|
void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6);
|
||||||
void smlua_text_utils_secret_star_replace(s16 courseNum, const char* courseName);
|
void smlua_text_utils_secret_star_replace(s16 courseNum, const char* courseName);
|
||||||
|
void smlua_text_utils_course_name_replace(s16 courseNum, const char* name);
|
||||||
|
const char* smlua_text_utils_course_name_get(s16 courseNum);
|
||||||
|
s32 smlua_text_utils_course_name_mod_index(s16 courseNum);
|
||||||
|
void smlua_text_utils_course_name_reset(s16 courseNum);
|
||||||
|
void smlua_text_utils_act_name_replace(s16 courseNum, u8 actNum, const char* name);
|
||||||
|
const char* smlua_text_utils_act_name_get(s16 courseNum, u8 actNum);
|
||||||
|
bool smlua_text_utils_act_name_is_modified(s16 courseNum, u8 actNum);
|
||||||
|
void smlua_text_utils_act_name_reset(s16 courseNum, u8 actNum);
|
||||||
void smlua_text_utils_castle_secret_stars_replace(const char* name);
|
void smlua_text_utils_castle_secret_stars_replace(const char* name);
|
||||||
void smlua_text_utils_extra_text_replace(s16 index, const char* text);
|
void smlua_text_utils_extra_text_replace(s16 index, const char* text);
|
||||||
const char* smlua_text_utils_get_language(void);
|
const char* smlua_text_utils_get_language(void);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "mod_cache.h"
|
#include "mod_cache.h"
|
||||||
#include "data/dynos.c.h"
|
#include "data/dynos.c.h"
|
||||||
#include "pc/debuglog.h"
|
#include "pc/debuglog.h"
|
||||||
|
#include "pc/pc_main.h"
|
||||||
|
|
||||||
#define MAX_SESSION_CHARS 7
|
#define MAX_SESSION_CHARS 7
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,7 @@ void moderator_list_add(char* address, bool perm) {
|
||||||
gModerator = malloc(sizeof(bool) * gModeratorCount);
|
gModerator = malloc(sizeof(bool) * gModeratorCount);
|
||||||
} else {
|
} else {
|
||||||
gModeratorAddresses = realloc(gModeratorAddresses, sizeof(char*) * gModeratorCount);
|
gModeratorAddresses = realloc(gModeratorAddresses, sizeof(char*) * gModeratorCount);
|
||||||
assert(gModeratorAddresses != NULL);
|
|
||||||
gModerator = realloc(gModerator, sizeof(bool) * gModeratorCount);
|
gModerator = realloc(gModerator, sizeof(bool) * gModeratorCount);
|
||||||
assert(gModerator != NULL);
|
|
||||||
}
|
}
|
||||||
if (gModeratorAddresses == NULL) {
|
if (gModeratorAddresses == NULL) {
|
||||||
LOG_ERROR("Failed to allocate gModeratorAddresses");
|
LOG_ERROR("Failed to allocate gModeratorAddresses");
|
||||||
|
|
|
@ -373,6 +373,7 @@ void network_send(struct Packet* p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void network_receive(u8 localIndex, void* addr, u8* data, u16 dataLength) {
|
void network_receive(u8 localIndex, void* addr, u8* data, u16 dataLength) {
|
||||||
|
|
||||||
// receive packet
|
// receive packet
|
||||||
struct Packet p = {
|
struct Packet p = {
|
||||||
.localIndex = localIndex,
|
.localIndex = localIndex,
|
||||||
|
@ -681,9 +682,6 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect
|
||||||
extern s16 gMenuMode;
|
extern s16 gMenuMode;
|
||||||
gMenuMode = -1;
|
gMenuMode = -1;
|
||||||
|
|
||||||
extern bool gIsModerator;
|
|
||||||
gIsModerator = false;
|
|
||||||
|
|
||||||
djui_panel_shutdown();
|
djui_panel_shutdown();
|
||||||
extern bool gDjuiInMainMenu;
|
extern bool gDjuiInMainMenu;
|
||||||
if (!gDjuiInMainMenu) {
|
if (!gDjuiInMainMenu) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct NetworkPlayer {
|
||||||
u8 type;
|
u8 type;
|
||||||
u8 localIndex;
|
u8 localIndex;
|
||||||
u8 globalIndex;
|
u8 globalIndex;
|
||||||
|
bool moderator;
|
||||||
f32 lastReceived;
|
f32 lastReceived;
|
||||||
f32 lastSent;
|
f32 lastSent;
|
||||||
f32 lastPingSent;
|
f32 lastPingSent;
|
||||||
|
|
|
@ -27,8 +27,7 @@ bool network_is_server(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool network_is_moderator(void) {
|
bool network_is_moderator(void) {
|
||||||
extern bool gIsModerator;
|
return gNetworkPlayers[0].moderator;
|
||||||
return gIsModerator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* network_get_player_text_color(u8 localIndex) {
|
u8* network_get_player_text_color(u8 localIndex) {
|
||||||
|
|
|
@ -100,7 +100,7 @@ void network_receive_chat(struct Packet* p) {
|
||||||
// add the message
|
// add the message
|
||||||
djui_chat_message_create_from(globalIndex, remoteMessage);
|
djui_chat_message_create_from(globalIndex, remoteMessage);
|
||||||
|
|
||||||
if (gNetworkSystem && gNetworkSystem->get_id_str && np) {
|
if (gNetworkSystem && gNetworkSystem->get_id_str && np->connected && strlen(np->name) > 0) {
|
||||||
LOG_CONSOLE("[%s] %s: %s", gNetworkSystem->get_id_str(np->localIndex), np->name, remoteMessage);
|
LOG_CONSOLE("[%s] %s: %s", gNetworkSystem->get_id_str(np->localIndex), np->name, remoteMessage);
|
||||||
LOG_INFO("[%s] %s: %s", gNetworkSystem->get_id_str(np->localIndex), np->name, remoteMessage);
|
LOG_INFO("[%s] %s: %s", gNetworkSystem->get_id_str(np->localIndex), np->name, remoteMessage);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -4,53 +4,55 @@
|
||||||
#include "pc/djui/djui_chat_message.h"
|
#include "pc/djui/djui_chat_message.h"
|
||||||
#include "pc/network/ban_list.h"
|
#include "pc/network/ban_list.h"
|
||||||
#include "pc/network/moderator_list.h"
|
#include "pc/network/moderator_list.h"
|
||||||
|
#include "pc/debuglog.h"
|
||||||
bool gIsModerator = false;
|
|
||||||
|
|
||||||
void network_send_chat_command(u8 globalIndex, enum ChatConfirmCommand ccc) {
|
void network_send_chat_command(u8 globalIndex, enum ChatConfirmCommand ccc) {
|
||||||
if (gIsModerator) {
|
if (!gNetworkPlayers[0].moderator) return;
|
||||||
u8 cccType = ccc;
|
|
||||||
struct Packet p = { 0 };
|
u8 cccType = ccc; struct Packet p = { 0 };
|
||||||
|
LOG_INFO("sending chat command to host with type: %d", cccType);
|
||||||
packet_init(&p, PACKET_COMMAND, false, PLMT_NONE);
|
packet_init(&p, PACKET_COMMAND, false, PLMT_NONE);
|
||||||
packet_write(&p, &globalIndex, sizeof(u8));
|
packet_write(&p, &globalIndex, sizeof(u8));
|
||||||
packet_write(&p, &cccType, sizeof(u8));
|
packet_write(&p, &cccType, sizeof(u8));
|
||||||
network_send_to(gNetworkPlayerServer->localIndex, &p);
|
network_send_to(gNetworkPlayerServer->localIndex, &p);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void network_receive_chat_command(struct Packet *p) {
|
void network_receive_chat_command(struct Packet *p) {
|
||||||
if (!moderator_list_contains(gNetworkSystem->get_id_str(p->localIndex))) {
|
if (gNetworkType != NT_SERVER) {
|
||||||
|
LOG_ERROR("recieved chat command as non server");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
enum ChatConfirmCommand CCC;
|
|
||||||
u8 player;
|
if (!moderator_list_contains(gNetworkSystem->get_id_str(p->localIndex))) {
|
||||||
|
LOG_ERROR("recieved moderator command from non moderator");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
u8 CCC; u8 player;
|
||||||
packet_read(p, &player, sizeof(u8));
|
packet_read(p, &player, sizeof(u8));
|
||||||
packet_read(p, &CCC, sizeof(u8));
|
packet_read(p, &CCC, sizeof(u8));
|
||||||
if (gNetworkType == NT_SERVER && CCC == CCC_KICK) {
|
|
||||||
struct NetworkPlayer *np = &gNetworkPlayers[player];
|
if (CCC != CCC_KICK && CCC != CCC_BAN) {
|
||||||
if (!np->connected) {
|
LOG_ERROR("recieved an invalid chat command: %d", CCC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NetworkPlayer *np = &gNetworkPlayers[player];
|
||||||
|
if (!np->connected) {
|
||||||
|
LOG_ERROR("recieved player that isn't connected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
network_send_kick(np->localIndex, EKT_KICKED);
|
|
||||||
network_player_disconnected(np->localIndex);
|
|
||||||
char message[256] = { 0 };
|
char message[256] = { 0 };
|
||||||
snprintf(message, 256, "\\#fff982\\Kicked '%s%s\\#fff982\\'!",
|
if (CCC == CCC_KICK) {
|
||||||
network_get_player_text_color_string(np->localIndex), np->name);
|
network_send_kick(np->localIndex, EKT_KICKED);
|
||||||
djui_chat_message_create(message);
|
snprintf(message, 256, "\\#fff982\\Kicked '%s%s\\#fff982\\'!", network_get_player_text_color_string(np->localIndex), np->name);
|
||||||
}
|
|
||||||
if (gNetworkType == NT_SERVER && CCC == CCC_BAN) {
|
|
||||||
struct NetworkPlayer *np = &gNetworkPlayers[player];
|
|
||||||
if (!np->connected) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if (CCC == CCC_BAN) {
|
||||||
network_send_kick(np->localIndex, EKT_BANNED);
|
network_send_kick(np->localIndex, EKT_BANNED);
|
||||||
ban_list_add(gNetworkSystem->get_id_str(np->localIndex), false);
|
ban_list_add(gNetworkSystem->get_id_str(np->localIndex), false);
|
||||||
network_player_disconnected(np->localIndex);
|
snprintf(message, 256, "\\#fff982\\Banned '%s%s\\#fff982\\'!", network_get_player_text_color_string(np->localIndex), np->name);
|
||||||
char message[256] = { 0 };
|
|
||||||
snprintf(message, 256, "\\#fff982\\Banned '%s%s\\#fff982\\'!",
|
|
||||||
network_get_player_text_color_string(np->localIndex), np->name);
|
|
||||||
djui_chat_message_create(message);
|
|
||||||
}
|
}
|
||||||
|
network_player_disconnected(np->localIndex);
|
||||||
|
djui_chat_message_create(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void network_send_moderator(u8 localIndex) {
|
void network_send_moderator(u8 localIndex) {
|
||||||
|
@ -60,10 +62,7 @@ void network_send_moderator(u8 localIndex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void network_receive_moderator(struct Packet *p) {
|
void network_receive_moderator(struct Packet *p) {
|
||||||
if ((gIsModerator) || (network_player_any_connected() && gNetworkPlayers[p->localIndex].type != NPT_SERVER)) {
|
if (gNetworkPlayers[0].moderator || (network_player_any_connected() && gNetworkPlayers[p->localIndex].type != NPT_SERVER)) return;
|
||||||
return;
|
gNetworkPlayers[0].moderator = true;
|
||||||
}
|
|
||||||
|
|
||||||
gIsModerator = true;
|
|
||||||
djui_chat_message_create(DLANG(CHAT, MOD_GRANTED));
|
djui_chat_message_create(DLANG(CHAT, MOD_GRANTED));
|
||||||
}
|
}
|
|
@ -468,7 +468,9 @@ void network_update_objects(void) {
|
||||||
|
|
||||||
// check for stale sync object
|
// check for stale sync object
|
||||||
if (so->o->oSyncID != so->id) {
|
if (so->o->oSyncID != so->id) {
|
||||||
LOG_ERROR("sync id mismatch: %d vs %d (behavior %d)", so->o->oSyncID, so->id, get_id_from_behavior(so->o->behavior));
|
enum BehaviorId bhvId = get_id_from_behavior(so->o->behavior);
|
||||||
|
const char* bhvName = get_behavior_name_from_id(bhvId);
|
||||||
|
LOG_ERROR("sync id mismatch: %d vs %d (behavior %s, %d)", so->o->oSyncID, so->id, bhvName != NULL ? bhvName : "NULL", bhvId);
|
||||||
sync_object_forget(so->id);
|
sync_object_forget(so->id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
223
src/pc/pc_main.c
223
src/pc/pc_main.c
|
@ -12,16 +12,6 @@
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "lua/smlua.h"
|
#include "lua/smlua.h"
|
||||||
|
|
||||||
#include "gfx/gfx_pc.h"
|
|
||||||
|
|
||||||
#include "gfx/gfx_opengl.h"
|
|
||||||
#include "gfx/gfx_direct3d11.h"
|
|
||||||
#include "gfx/gfx_direct3d12.h"
|
|
||||||
|
|
||||||
#include "gfx/gfx_dxgi.h"
|
|
||||||
#include "gfx/gfx_sdl.h"
|
|
||||||
#include "gfx/gfx_dummy.h"
|
|
||||||
|
|
||||||
#include "audio/audio_api.h"
|
#include "audio/audio_api.h"
|
||||||
#include "audio/audio_sdl.h"
|
#include "audio/audio_sdl.h"
|
||||||
#include "audio/audio_null.h"
|
#include "audio/audio_null.h"
|
||||||
|
@ -87,25 +77,22 @@ static f64 sLastFrameTimeStart;
|
||||||
static f32 sAvgFrames = 1;
|
static f32 sAvgFrames = 1;
|
||||||
static f32 sAvgFps = 0;
|
static f32 sAvgFps = 0;
|
||||||
|
|
||||||
|
bool gGameInited = false;
|
||||||
|
bool gGfxInited = false;
|
||||||
|
|
||||||
static struct AudioAPI *audio_api;
|
static struct AudioAPI *audio_api;
|
||||||
struct GfxWindowManagerAPI *wm_api;
|
struct GfxWindowManagerAPI *wm_api = &WAPI;
|
||||||
static struct GfxRenderingAPI *rendering_api;
|
|
||||||
|
|
||||||
extern void gfx_run(Gfx *commands);
|
extern void gfx_run(Gfx *commands);
|
||||||
extern void thread5_game_loop(void *arg);
|
extern void thread5_game_loop(void *arg);
|
||||||
extern void create_next_audio_buffer(s16 *samples, u32 num_samples);
|
extern void create_next_audio_buffer(s16 *samples, u32 num_samples);
|
||||||
void game_loop_one_iteration(void);
|
void game_loop_one_iteration(void);
|
||||||
|
|
||||||
void dispatch_audio_sptask(UNUSED struct SPTask *spTask) {
|
void dispatch_audio_sptask(UNUSED struct SPTask *spTask) {}
|
||||||
}
|
void set_vblank_handler(UNUSED s32 index, UNUSED struct VblankHandler *handler, UNUSED OSMesgQueue *queue, UNUSED OSMesg *msg) {}
|
||||||
|
|
||||||
void set_vblank_handler(UNUSED s32 index, UNUSED struct VblankHandler *handler, UNUSED OSMesgQueue *queue, UNUSED OSMesg *msg) {
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool inited = false;
|
|
||||||
|
|
||||||
void send_display_list(struct SPTask *spTask) {
|
void send_display_list(struct SPTask *spTask) {
|
||||||
if (!inited) return;
|
if (!gGameInited) { return; }
|
||||||
gfx_run((Gfx *)spTask->task.t.data_ptr);
|
gfx_run((Gfx *)spTask->task.t.data_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,17 +104,29 @@ void send_display_list(struct SPTask *spTask) {
|
||||||
#define SAMPLES_LOW 528
|
#define SAMPLES_LOW 528
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern void patch_mtx_before(void);
|
||||||
|
extern void patch_screen_transition_before(void);
|
||||||
|
extern void patch_title_screen_before(void);
|
||||||
|
extern void patch_dialog_before(void);
|
||||||
|
extern void patch_hud_before(void);
|
||||||
|
extern void patch_paintings_before(void);
|
||||||
|
extern void patch_bubble_particles_before(void);
|
||||||
|
extern void patch_snow_particles_before(void);
|
||||||
|
extern void patch_djui_before(void);
|
||||||
|
extern void patch_djui_hud_before(void);
|
||||||
|
|
||||||
|
extern void patch_mtx_interpolated(f32 delta);
|
||||||
|
extern void patch_screen_transition_interpolated(f32 delta);
|
||||||
|
extern void patch_title_screen_interpolated(f32 delta);
|
||||||
|
extern void patch_dialog_interpolated(f32 delta);
|
||||||
|
extern void patch_hud_interpolated(f32 delta);
|
||||||
|
extern void patch_paintings_interpolated(f32 delta);
|
||||||
|
extern void patch_bubble_particles_interpolated(f32 delta);
|
||||||
|
extern void patch_snow_particles_interpolated(f32 delta);
|
||||||
|
extern void patch_djui_interpolated(f32 delta);
|
||||||
|
extern void patch_djui_hud(f32 delta);
|
||||||
|
|
||||||
static void patch_interpolations_before(void) {
|
static void patch_interpolations_before(void) {
|
||||||
extern void patch_mtx_before(void);
|
|
||||||
extern void patch_screen_transition_before(void);
|
|
||||||
extern void patch_title_screen_before(void);
|
|
||||||
extern void patch_dialog_before(void);
|
|
||||||
extern void patch_hud_before(void);
|
|
||||||
extern void patch_paintings_before(void);
|
|
||||||
extern void patch_bubble_particles_before(void);
|
|
||||||
extern void patch_snow_particles_before(void);
|
|
||||||
extern void patch_djui_before(void);
|
|
||||||
extern void patch_djui_hud_before(void);
|
|
||||||
patch_mtx_before();
|
patch_mtx_before();
|
||||||
patch_screen_transition_before();
|
patch_screen_transition_before();
|
||||||
patch_title_screen_before();
|
patch_title_screen_before();
|
||||||
|
@ -141,16 +140,6 @@ static void patch_interpolations_before(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void patch_interpolations(f32 delta) {
|
static inline void patch_interpolations(f32 delta) {
|
||||||
extern void patch_mtx_interpolated(f32 delta);
|
|
||||||
extern void patch_screen_transition_interpolated(f32 delta);
|
|
||||||
extern void patch_title_screen_interpolated(f32 delta);
|
|
||||||
extern void patch_dialog_interpolated(f32 delta);
|
|
||||||
extern void patch_hud_interpolated(f32 delta);
|
|
||||||
extern void patch_paintings_interpolated(f32 delta);
|
|
||||||
extern void patch_bubble_particles_interpolated(f32 delta);
|
|
||||||
extern void patch_snow_particles_interpolated(f32 delta);
|
|
||||||
extern void patch_djui_interpolated(f32 delta);
|
|
||||||
extern void patch_djui_hud(f32 delta);
|
|
||||||
patch_mtx_interpolated(delta);
|
patch_mtx_interpolated(delta);
|
||||||
patch_screen_transition_interpolated(delta);
|
patch_screen_transition_interpolated(delta);
|
||||||
patch_title_screen_interpolated(delta);
|
patch_title_screen_interpolated(delta);
|
||||||
|
@ -163,19 +152,17 @@ static inline void patch_interpolations(f32 delta) {
|
||||||
patch_djui_hud(delta);
|
patch_djui_hud(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void produce_interpolation_frames_and_delay(void) {
|
void produce_interpolation_frames_and_delay(void) {
|
||||||
|
u64 frames = 0;
|
||||||
|
f64 curTime = clock_elapsed_f64();
|
||||||
|
|
||||||
gRenderingInterpolated = true;
|
gRenderingInterpolated = true;
|
||||||
|
|
||||||
// sanity check target time to deal with hangs and such
|
// sanity check target time to deal with hangs and such
|
||||||
f64 curTime = clock_elapsed_f64();
|
if (fabs(sFrameTargetTime - curTime) > 1) { sFrameTargetTime = curTime - 0.01f; }
|
||||||
if (fabs(sFrameTargetTime - curTime) > 1) {
|
|
||||||
sFrameTargetTime = curTime - 0.01f;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 frames = 0;
|
|
||||||
while ((curTime = clock_elapsed_f64()) < sFrameTargetTime) {
|
|
||||||
// interpolate and render
|
// interpolate and render
|
||||||
|
while ((curTime = clock_elapsed_f64()) < sFrameTargetTime) {
|
||||||
gfx_start_frame();
|
gfx_start_frame();
|
||||||
f32 delta = MIN((curTime - sFrameTimeStart) / (sFrameTargetTime - sFrameTimeStart), 1);
|
f32 delta = MIN((curTime - sFrameTimeStart) / (sFrameTargetTime - sFrameTimeStart), 1);
|
||||||
gRenderingDelta = delta;
|
gRenderingDelta = delta;
|
||||||
|
@ -185,12 +172,12 @@ void produce_interpolation_frames_and_delay(void) {
|
||||||
|
|
||||||
// delay
|
// delay
|
||||||
if (!configUncappedFramerate) {
|
if (!configUncappedFramerate) {
|
||||||
f64 targetDelta = 1.0 / (f64)configFrameLimit;
|
f64 targetDelta = 1.0 / (f64) configFrameLimit;
|
||||||
f64 now = clock_elapsed_f64();
|
f64 now = clock_elapsed_f64();
|
||||||
f64 actualDelta = now - curTime;
|
f64 actualDelta = now - curTime;
|
||||||
if (actualDelta < targetDelta) {
|
if (actualDelta < targetDelta) {
|
||||||
f64 delay = ((targetDelta - actualDelta) * 1000.0);
|
f64 delay = ((targetDelta - actualDelta) * 1000.0);
|
||||||
wm_api->delay((u32)delay);
|
WAPI.delay((u32) delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,50 +194,35 @@ void produce_interpolation_frames_and_delay(void) {
|
||||||
//printf(">>> fpt: %llu, fps: %f :: %f\n", frames, sAvgFps, fps);
|
//printf(">>> fpt: %llu, fps: %f :: %f\n", frames, sAvgFps, fps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void produce_one_frame(void) {
|
inline static void buffer_audio(void) {
|
||||||
CTX_BEGIN(CTX_NETWORK);
|
int samples_left = audio_api->buffered();
|
||||||
network_update();
|
u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? SAMPLES_HIGH : SAMPLES_LOW;
|
||||||
CTX_END(CTX_NETWORK);
|
s16 audio_buffer[SAMPLES_HIGH * 2 * 2];
|
||||||
|
for (s32 i = 0; i < 2; i++) {
|
||||||
|
create_next_audio_buffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples);
|
||||||
|
}
|
||||||
|
audio_api->play((u8 *)audio_buffer, 2 * num_audio_samples * 4);
|
||||||
|
}
|
||||||
|
|
||||||
CTX_BEGIN(CTX_INTERP);
|
void produce_one_frame(void) {
|
||||||
patch_interpolations_before();
|
CTX_EXTENT(CTX_NETWORK, network_update);
|
||||||
CTX_END(CTX_INTERP);
|
|
||||||
|
CTX_EXTENT(CTX_INTERP, patch_interpolations_before);
|
||||||
|
|
||||||
const f32 master_mod = (f32)configMasterVolume / 127.0f;
|
const f32 master_mod = (f32)configMasterVolume / 127.0f;
|
||||||
set_sequence_player_volume(SEQ_PLAYER_LEVEL, (f32)configMusicVolume / 127.0f * master_mod);
|
set_sequence_player_volume(SEQ_PLAYER_LEVEL, (f32)configMusicVolume / 127.0f * master_mod);
|
||||||
set_sequence_player_volume(SEQ_PLAYER_SFX, (f32)configSfxVolume / 127.0f * master_mod);
|
set_sequence_player_volume(SEQ_PLAYER_SFX, (f32)configSfxVolume / 127.0f * master_mod);
|
||||||
set_sequence_player_volume(SEQ_PLAYER_ENV, (f32)configEnvVolume / 127.0f * master_mod);
|
set_sequence_player_volume(SEQ_PLAYER_ENV, (f32)configEnvVolume / 127.0f * master_mod);
|
||||||
|
|
||||||
CTX_BEGIN(CTX_GAME_LOOP);
|
CTX_EXTENT(CTX_GAME_LOOP, game_loop_one_iteration);
|
||||||
game_loop_one_iteration();
|
|
||||||
CTX_END(CTX_GAME_LOOP);
|
|
||||||
|
|
||||||
CTX_BEGIN(CTX_SMLUA);
|
CTX_EXTENT(CTX_SMLUA, smlua_update);
|
||||||
smlua_update();
|
|
||||||
CTX_END(CTX_SMLUA);
|
|
||||||
|
|
||||||
thread6_rumble_loop(NULL);
|
thread6_rumble_loop(NULL);
|
||||||
|
|
||||||
CTX_BEGIN(CTX_AUDIO);
|
CTX_EXTENT(CTX_AUDIO, buffer_audio);
|
||||||
int samples_left = audio_api->buffered();
|
|
||||||
u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? SAMPLES_HIGH : SAMPLES_LOW;
|
|
||||||
//printf("Audio samples: %d %u\n", samples_left, num_audio_samples);
|
|
||||||
s16 audio_buffer[SAMPLES_HIGH * 2 * 2];
|
|
||||||
for (s32 i = 0; i < 2; i++) {
|
|
||||||
/*if (audio_cnt-- == 0) {
|
|
||||||
audio_cnt = 2;
|
|
||||||
}
|
|
||||||
u32 num_audio_samples = audio_cnt < 2 ? 528 : 544;*/
|
|
||||||
create_next_audio_buffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples);
|
|
||||||
}
|
|
||||||
//printf("Audio samples before submitting: %d\n", audio_api->buffered());
|
|
||||||
|
|
||||||
audio_api->play((u8 *)audio_buffer, 2 * num_audio_samples * 4);
|
CTX_EXTENT(CTX_RENDER, produce_interpolation_frames_and_delay);
|
||||||
CTX_END(CTX_AUDIO);
|
|
||||||
|
|
||||||
CTX_BEGIN(CTX_RENDER);
|
|
||||||
produce_interpolation_frames_and_delay();
|
|
||||||
CTX_END(CTX_RENDER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio_shutdown(void) {
|
void audio_shutdown(void) {
|
||||||
|
@ -270,7 +242,7 @@ void game_deinit(void) {
|
||||||
network_shutdown(true, true, false, false);
|
network_shutdown(true, true, false, false);
|
||||||
smlua_shutdown();
|
smlua_shutdown();
|
||||||
mods_shutdown();
|
mods_shutdown();
|
||||||
inited = false;
|
gGameInited = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_exit(void) {
|
void game_exit(void) {
|
||||||
|
@ -279,10 +251,6 @@ void game_exit(void) {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void inthand(UNUSED int signum) {
|
|
||||||
game_exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void main_func(void) {
|
void main_func(void) {
|
||||||
const char *gamedir = gCLIOpts.GameDir[0] ? gCLIOpts.GameDir : FS_BASEDIR;
|
const char *gamedir = gCLIOpts.GameDir[0] ? gCLIOpts.GameDir : FS_BASEDIR;
|
||||||
const char *userpath = gCLIOpts.SavePath[0] ? gCLIOpts.SavePath : sys_user_path();
|
const char *userpath = gCLIOpts.SavePath[0] ? gCLIOpts.SavePath : sys_user_path();
|
||||||
|
@ -315,62 +283,30 @@ void main_func(void) {
|
||||||
|
|
||||||
if (configPlayerModel >= CT_MAX) { configPlayerModel = 0; }
|
if (configPlayerModel >= CT_MAX) { configPlayerModel = 0; }
|
||||||
|
|
||||||
if (gCLIOpts.FullScreen == 1)
|
if (gCLIOpts.FullScreen == 1) { configWindow.fullscreen = true; }
|
||||||
configWindow.fullscreen = true;
|
else if (gCLIOpts.FullScreen == 2) { configWindow.fullscreen = false; }
|
||||||
else if (gCLIOpts.FullScreen == 2)
|
|
||||||
configWindow.fullscreen = false;
|
|
||||||
|
|
||||||
#if defined(WAPI_SDL1) || defined(WAPI_SDL2)
|
// incase the loading screen failed, or is disabled
|
||||||
wm_api = &gfx_sdl;
|
if (!gGfxInited) {
|
||||||
#elif defined(WAPI_DXGI)
|
gfx_init(&WAPI, &RAPI, TITLE);
|
||||||
wm_api = &gfx_dxgi;
|
WAPI.set_keyboard_callbacks(keyboard_on_key_down, keyboard_on_key_up, keyboard_on_all_keys_up, keyboard_on_text_input);
|
||||||
#elif defined(WAPI_DUMMY)
|
|
||||||
wm_api = &gfx_dummy_wm_api;
|
|
||||||
#else
|
|
||||||
#error No window API!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(RAPI_D3D11)
|
|
||||||
rendering_api = &gfx_direct3d11_api;
|
|
||||||
# define RAPI_NAME "DirectX 11"
|
|
||||||
#elif defined(RAPI_D3D12)
|
|
||||||
rendering_api = &gfx_direct3d12_api;
|
|
||||||
# define RAPI_NAME "DirectX 12"
|
|
||||||
#elif defined(RAPI_GL) || defined(RAPI_GL_LEGACY)
|
|
||||||
rendering_api = &gfx_opengl_api;
|
|
||||||
# ifdef USE_GLES
|
|
||||||
# define RAPI_NAME "OpenGL ES"
|
|
||||||
# else
|
|
||||||
# define RAPI_NAME "OpenGL"
|
|
||||||
# endif
|
|
||||||
#elif defined(RAPI_DUMMY)
|
|
||||||
rendering_api = &gfx_dummy_renderer_api;
|
|
||||||
#else
|
|
||||||
#error No rendering API!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char* version = get_version_local();
|
|
||||||
char window_title[96] = { 0 };
|
|
||||||
#ifdef GIT_HASH
|
|
||||||
snprintf(window_title, 96, "sm64ex-coop: %s [%s]", version, GIT_HASH);
|
|
||||||
#else
|
|
||||||
snprintf(window_title, 96, "sm64ex-coop: %s", version);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gfx_init(wm_api, rendering_api, window_title);
|
|
||||||
wm_api->set_keyboard_callbacks(keyboard_on_key_down, keyboard_on_key_up, keyboard_on_all_keys_up, keyboard_on_text_input);
|
|
||||||
|
|
||||||
#if defined(AAPI_SDL1) || defined(AAPI_SDL2)
|
|
||||||
if (audio_api == NULL && audio_sdl.init())
|
|
||||||
audio_api = &audio_sdl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (audio_api == NULL) {
|
|
||||||
audio_api = &audio_null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(AAPI_SDL1) || defined(AAPI_SDL2)
|
||||||
|
if (audio_api == NULL && audio_sdl.init()) { audio_api = &audio_sdl; }
|
||||||
|
#endif
|
||||||
|
if (audio_api == NULL) { audio_api = &audio_null; }
|
||||||
|
|
||||||
|
audio_init();
|
||||||
|
sound_init();
|
||||||
|
bassh_init();
|
||||||
|
network_player_init();
|
||||||
|
|
||||||
|
thread5_game_loop(NULL);
|
||||||
|
|
||||||
djui_init_late();
|
djui_init_late();
|
||||||
|
|
||||||
|
// init network
|
||||||
if (gCLIOpts.Network == NT_CLIENT) {
|
if (gCLIOpts.Network == NT_CLIENT) {
|
||||||
network_set_system(NS_SOCKET);
|
network_set_system(NS_SOCKET);
|
||||||
snprintf(gGetHostName, MAX_CONFIG_STRING, "%s", gCLIOpts.JoinIp);
|
snprintf(gGetHostName, MAX_CONFIG_STRING, "%s", gCLIOpts.JoinIp);
|
||||||
|
@ -387,15 +323,6 @@ void main_func(void) {
|
||||||
network_init(NT_NONE, false);
|
network_init(NT_NONE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
audio_init();
|
|
||||||
sound_init();
|
|
||||||
bassh_init();
|
|
||||||
network_player_init();
|
|
||||||
|
|
||||||
thread5_game_loop(NULL);
|
|
||||||
|
|
||||||
inited = true;
|
|
||||||
|
|
||||||
#ifdef EXTERNAL_DATA
|
#ifdef EXTERNAL_DATA
|
||||||
// precache data if needed
|
// precache data if needed
|
||||||
if (configPrecacheRes) {
|
if (configPrecacheRes) {
|
||||||
|
@ -405,10 +332,12 @@ void main_func(void) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
gGameInited = true;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
debug_context_reset();
|
debug_context_reset();
|
||||||
CTX_BEGIN(CTX_FRAME);
|
CTX_BEGIN(CTX_FRAME);
|
||||||
wm_api->main_loop(produce_one_frame);
|
WAPI.main_loop(produce_one_frame);
|
||||||
#ifdef DISCORD_SDK
|
#ifdef DISCORD_SDK
|
||||||
discord_update();
|
discord_update();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,6 +5,66 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "gfx/gfx_pc.h"
|
||||||
|
|
||||||
|
#include "gfx/gfx_opengl.h"
|
||||||
|
#include "gfx/gfx_direct3d11.h"
|
||||||
|
#include "gfx/gfx_direct3d12.h"
|
||||||
|
|
||||||
|
#include "gfx/gfx_dxgi.h"
|
||||||
|
#include "gfx/gfx_sdl.h"
|
||||||
|
#include "gfx/gfx_dummy.h"
|
||||||
|
|
||||||
|
#if defined(WAPI_SDL1) || defined(WAPI_SDL2)
|
||||||
|
# define WAPI gfx_sdl
|
||||||
|
#elif defined(WAPI_DXGI)
|
||||||
|
# define WAPI gfx_dxgi
|
||||||
|
#elif defined(WAPI_DUMMY)
|
||||||
|
# define WAPI gfx_dummy_wm_api
|
||||||
|
#else
|
||||||
|
# error No window API!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(RAPI_D3D11)
|
||||||
|
# define RAPI gfx_direct3d11_api
|
||||||
|
# define RAPI_NAME "DirectX 11"
|
||||||
|
#elif defined(RAPI_D3D12)
|
||||||
|
# define RAPI gfx_direct3d12_api
|
||||||
|
# define RAPI_NAME "DirectX 12"
|
||||||
|
#elif defined(RAPI_GL) || defined(RAPI_GL_LEGACY)
|
||||||
|
# define RAPI gfx_opengl_api
|
||||||
|
# ifdef USE_GLES
|
||||||
|
# define RAPI_NAME "OpenGL ES"
|
||||||
|
# else
|
||||||
|
# define RAPI_NAME "OpenGL"
|
||||||
|
# endif
|
||||||
|
#elif defined(RAPI_DUMMY)
|
||||||
|
# define RAPI gfx_dummy_renderer_api
|
||||||
|
#else
|
||||||
|
# error No rendering API!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// For IDEs with syntax highlighting
|
||||||
|
#ifndef WAPI
|
||||||
|
#define WAPI gfx_dummy_wm_api
|
||||||
|
#endif
|
||||||
|
#ifndef RAPI
|
||||||
|
#define RAPI gfx_dummy_renderer_api
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GIT_HASH
|
||||||
|
#define TITLE ({ char title[96] = ""; snprintf(title, 96, "sm64ex-coop: %s [%s]", get_version_local(), GIT_HASH); title; })
|
||||||
|
#else
|
||||||
|
#define TITLE ({ char title[96] = ""; snprintf(title, 96, "sm64ex-coop: %s", get_version_local()); title; })
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LOAD_STEPS 6
|
||||||
|
|
||||||
|
#define AT_STARTUP __attribute__((constructor))
|
||||||
|
|
||||||
|
extern bool gGameInited;
|
||||||
|
extern bool gGfxInited;
|
||||||
|
|
||||||
extern struct GfxWindowManagerAPI* wm_api;
|
extern struct GfxWindowManagerAPI* wm_api;
|
||||||
void game_deinit(void);
|
void game_deinit(void);
|
||||||
void game_exit(void);
|
void game_exit(void);
|
||||||
|
|
|
@ -168,17 +168,6 @@ void delta_interpolate_rgba(u8* res, u8* a, u8* b, f32 delta) {
|
||||||
res[3] = ((a[3] * antiDelta) + (b[3] * delta));
|
res[3] = ((a[3] * antiDelta) + (b[3] * delta));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void delta_interpolate_mtx(Mtx* out, Mtx* a, Mtx* b, f32 delta) {
|
|
||||||
f32 antiDelta = 1.0f - delta;
|
|
||||||
for (s32 i = 0; i < 4; i++) {
|
|
||||||
for (s32 j = 0; j < 4; j++) {
|
|
||||||
out->m[i][j] = (a->m[i][j] * antiDelta) + (b->m[i][j] * delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static f32 get_quat_compo_abs(f32 xPiece, f32 yPiece, f32 zPiece) {
|
static f32 get_quat_compo_abs(f32 xPiece, f32 yPiece, f32 zPiece) {
|
||||||
return sqrt((1.0f + xPiece + yPiece + zPiece) * 0.25f);
|
return sqrt((1.0f + xPiece + yPiece + zPiece) * 0.25f);
|
||||||
}
|
}
|
||||||
|
@ -308,7 +297,7 @@ static void rot_quat_slerp(Vec4f out, Vec4f a, Vec4f b, f32 t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// removes scaling from the shear value
|
// removes scaling from the shear value
|
||||||
static f32 unmat_unscale_shear(f32 shear, f32 scale) {
|
inline static f32 unmat_unscale_shear(f32 shear, f32 scale) {
|
||||||
if (scale == 0.0f) {
|
if (scale == 0.0f) {
|
||||||
// assume no shear
|
// assume no shear
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
@ -325,14 +314,14 @@ static f32 unmat_unscale_shear(f32 shear, f32 scale) {
|
||||||
//
|
//
|
||||||
// matrix perspective is not used in SM64, so those indices are stripped from the output parameter
|
// matrix perspective is not used in SM64, so those indices are stripped from the output parameter
|
||||||
// return value was related to if matrix was non-singular, which was necessary for perspective
|
// return value was related to if matrix was non-singular, which was necessary for perspective
|
||||||
// since perspective is not used, the return value is also strippped
|
// since perspective is not used, the return value is also stripped
|
||||||
//
|
//
|
||||||
// additionally, rotation is not converted to euler angles
|
// additionally, rotation is not converted to euler angles
|
||||||
// instead, it is converted to a quaternion to avoid gimbal lock
|
// instead, it is converted to a quaternion to avoid gimbal lock
|
||||||
//
|
//
|
||||||
// tranfs is returned as follows:
|
// tranfs is returned as follows:
|
||||||
// scale(x, y, z), shear(xy, xz, zy), rotation(a, b, c, d), translation(x, y, z)
|
// scale(x, y, z), shear(xy, xz, zy), rotation(a, b, c, d), translation(x, y, z)
|
||||||
static void unmatrix(Mtx * mat, f32 tranfs[13]) {
|
OPTIMIZE_O3 static void unmatrix(Mtx * mat, f32 tranfs[13]) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
Vec3f axisVecs[3] = { 0 };
|
Vec3f axisVecs[3] = { 0 };
|
||||||
Vec3f yzCross = { 0 };
|
Vec3f yzCross = { 0 };
|
||||||
|
@ -433,7 +422,7 @@ static void unmatrix(Mtx * mat, f32 tranfs[13]) {
|
||||||
|
|
||||||
// builds a transformation matrix from a decomposed sequence from unmatrix
|
// builds a transformation matrix from a decomposed sequence from unmatrix
|
||||||
// see unmatrix for what tranfs means
|
// see unmatrix for what tranfs means
|
||||||
static void rematrix(Mtx * mat, f32 tranfs[13]) {
|
OPTIMIZE_O3 static void rematrix(Mtx * mat, f32 tranfs[13]) {
|
||||||
int i;
|
int i;
|
||||||
Vec3f rotAxes[3] = { 0 };
|
Vec3f rotAxes[3] = { 0 };
|
||||||
Mat4 rotMat = { 0 };
|
Mat4 rotMat = { 0 };
|
||||||
|
@ -479,7 +468,7 @@ static void rematrix(Mtx * mat, f32 tranfs[13]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void delta_interpolate_mtx_accurate(Mtx* out, Mtx* a, Mtx* b, f32 delta) {
|
OPTIMIZE_O3 inline static void delta_interpolate_mtx_accurate(Mtx* out, Mtx* a, Mtx* b, f32 delta) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
f32 matTranfsA[13] = { 0 };
|
f32 matTranfsA[13] = { 0 };
|
||||||
f32 matTranfsB[13] = { 0 };
|
f32 matTranfsB[13] = { 0 };
|
||||||
|
@ -502,7 +491,7 @@ void delta_interpolate_mtx_accurate(Mtx* out, Mtx* a, Mtx* b, f32 delta) {
|
||||||
rematrix(out, matTranfsB);
|
rematrix(out, matTranfsB);
|
||||||
}
|
}
|
||||||
|
|
||||||
void delta_interpolate_mtx(Mtx* out, Mtx* a, Mtx* b, f32 delta) {
|
OPTIMIZE_O3 void delta_interpolate_mtx(Mtx* out, Mtx* a, Mtx* b, f32 delta) {
|
||||||
// HACK: Limit accurate interpolation to 64-bit builds
|
// HACK: Limit accurate interpolation to 64-bit builds
|
||||||
if (sizeof(void*) > 4) {
|
if (sizeof(void*) > 4) {
|
||||||
if (configInterpolationMode) {
|
if (configInterpolationMode) {
|
||||||
|
|
Loading…
Reference in a new issue