From 29d38aa1d69c0c258670d969435316a098d9d384 Mon Sep 17 00:00:00 2001 From: TakaRikka <38417346+TakaRikka@users.noreply.github.com> Date: Wed, 26 Jun 2024 21:05:00 -0700 Subject: [PATCH] updates for 1.0 (#81) * first pass for collision viewer implementation * fix Cc collider viewer? * add capsule collider view * fix: freestanding lib * fix: wii compilation * trigger view menu initial setup * implement viewing a couple trigger types * make actor spawn menu state permanent * add option to change trigger opacity * simplify some file names to avoid corruption bug * collider opacity option * free cam collision view * add disable item timer cheat * fix stallord 2 save to work better * implement evt area view * fix: wii compilation * fix gorge void tool * add actor delete button to list menu * add button mash checker tool * add mash checker position setting * add freeze actor option * fix wii proc enum * improve event area trigger draw * better? evt area height calculation * fix stallord2 and timer tools * fix rupee cutscene flag toggle * Add Path View * Use correct loop check and small formatting fixes * update readme / docs to reflect changes * fix: modules documentation * fix path draw nullptr crash * fix wii actor struct size * add restart change trigger view * add sOldVcdVatCmd symbol for wii jp / pal * fix proc enum again * fix rollchecker * cleanup * add view plumm tags * sort warping menu type and room names * sort item wheel * proc name list WIP * actor list menu revamp * continue fixing actor viewer menu * more cleanup from testing * fix proc names issue * tools menu fast scroll, actor viewer negative wrap around * fix build * add actor transform block distance view * add plumm cs trigger view * fix any% bit save * fix hundo aeralfos save * update movelink, taka fixes for actor viewer * fix a couple more saves * fix movelink bug * fix minor bug in GZ_getButtonRepeat * add crrpos hook, fix another movelink bug * movelink -> moveactor, actor viewer improvements * add credits page, bump to 1.0.0 * move heart slightly * rm ferdi * add mist avoid draw * projection lines WIP * midna charge projection updates (WIP) * fix move actor event state * add basic attention viewer / flat terrain display * decouple poly draw into individual toggles * add polygon edge view * add collision range/raise options * add missing addrs for other versions * add menu options for lja and midna charge projection * split projection viewer out * trigger/collision menu sorting * fix most move actor issues * add new menu item descriptions * fix projection view linking / crash * fix any% save inaccuracies * fix no sand sink tool * better implementation of invincible cheat * fix hide hud toggle * fix wii daalink alignment * Adds transform indicator * updated tool menu order * refactored REL features management * made commands dynamic * made gz_flgas dynamic * extracted umd feature * extracted BiT * extracted corotd checker * extracted default position initialization * fix memory leak * extracted mash checker * extracted gorge checker * extracted rollcheck * updated deque * modified settings saving process * updated settings menu & tools for new save system * updated sprite offsets for new save system * updated scene items for new save system * fixed unloaded init function pointers * updated watches to use new save system * Added scrolling to watches menu & minor setting fixes * removed useless macro * fix bit command * minor tools menu fix * fixing tools not working when loading saved settings * fix move link tool speed for wii * fix teleport tool * optimized line rendering * Added indication of more lines to display * fixed actor spawner param offset * updated menu offsets for wii & added indicator for watches menu * fix top line indication y offset * minor line fix * Added text view for the memory editor * fixed checkbox sizing with non uniform fonts * removed transform indicator from menu * moved menu.h/.cpp to the `menus` dir * checkpoint * removed `addrs.h` * enable projection menu, fix actor viewer * Fixed projection not being enabling * fix crash on projection menu. * fix proj viewers, update more proc names * fix potential crash. * fix wii crash on capsule rendering * moved one time patch code to init module * future proofing module loading * optimised cursor movement & added memfile existence check * optimizations * display actor id * Adding kytag09 to wii GV checker * Add manual check for transform indicator * added user defined button combos * Changed description text to match custom combos * minor fixes * update command with new combos * updated settings funcion names * some small menu / free cam adjustments * fix plumm tag view * fix fast bonk * added reset option to item wheel menu * move spawning to preloop listener * fix last file reload * fix area reload * memory editor optimization * added expanded view for mem editor * optimisation + cosmetic change for mem edit * undo actor spawner changes, add more stored fields for projections * hook cleanup * removed unnecessary osreports --------- Co-authored-by: kipcode66 Co-authored-by: jdflyer Co-authored-by: Pheenoh --- .devcontainer/devcontainer.json | 4 +- .vscode/launch.json | 42 + BUILDING.md | 24 +- CMakeLists.txt | 8 +- CONTRIBUTING.md | 41 +- FEATURES.md | 193 ++ README.md | 173 +- RomHack.toml.in | 3 + common/rels/src/cxx.cpp | 11 +- docs/CreatingAnIso.md | 32 +- docs/DevOverview.md | 3 +- .../include/JSystem/J2DGraph/J2DPane.h | 1 - .../include/JSystem/J3DGraphBase/J3DPacket.h | 38 +- .../include/JSystem/J3DGraphBase/J3DStruct.h | 2 +- .../include/JSystem/J3DGraphBase/J3DSys.h | 13 +- .../include/JSystem/JKernel/JKRArchive.h | 1 - .../libtp_c/include/JSystem/JKernel/JKRHeap.h | 1 - .../include/JSystem/JMATrigonometric.h | 69 + external/libtp_c/include/JSystem/JMath.h | 8 + .../include/JSystem/JParticle/JPAParticle.h | 2 +- external/libtp_c/include/JSystem/JUtility.h | 2 +- .../include/JSystem/JUtility/JUTGamePad.h | 3 +- .../include/SSystem/SComponent/c_bg_s_chk.h | 22 +- .../include/SSystem/SComponent/c_cc_d.h | 29 +- .../include/SSystem/SComponent/c_counter.h | 1 - .../include/SSystem/SComponent/c_lib.h | 11 + .../include/SSystem/SComponent/c_m3d_g_aab.h | 5 +- .../include/SSystem/SComponent/c_m3d_g_cps.h | 15 +- .../include/SSystem/SComponent/c_m3d_g_cyl.h | 2 +- .../include/SSystem/SComponent/c_m3d_g_lin.h | 7 +- .../include/SSystem/SComponent/c_m3d_g_pla.h | 4 +- .../include/SSystem/SComponent/c_m3d_g_sph.h | 3 +- .../include/SSystem/SComponent/c_math.h | 11 +- .../include/SSystem/SComponent/c_sxyz.h | 4 - .../include/SSystem/SComponent/c_xyz.h | 72 +- external/libtp_c/include/addrs.h | 1401 ---------- external/libtp_c/include/d/a/d_a_alink.h | 523 ++-- external/libtp_c/include/d/a/d_a_npc.h | 9 + external/libtp_c/include/d/a/d_a_player.h | 5 +- external/libtp_c/include/d/bg/d_bg_s.h | 15 +- external/libtp_c/include/d/bg/d_bg_s_acch.h | 151 +- .../libtp_c/include/d/bg/d_bg_s_captpoly.h | 33 + external/libtp_c/include/d/bg/d_bg_s_chk.h | 2 + .../include/d/bg/d_bg_s_grp_pass_chk.h | 22 +- .../include/d/bg/d_bg_s_poly_pass_chk.h | 16 +- external/libtp_c/include/d/bg/d_bg_w.h | 115 +- external/libtp_c/include/d/cc/d_cc_d.h | 39 +- .../libtp_c/include/d/com/d_com_inf_game.h | 9 +- external/libtp_c/include/d/d_attention.h | 13 + external/libtp_c/include/d/d_item.h | 35 + external/libtp_c/include/d/d_path.h | 19 + external/libtp_c/include/d/d_procname.h | 1586 +++++------ external/libtp_c/include/d/d_stage.h | 22 +- external/libtp_c/include/d/kankyo/d_kankyo.h | 6 +- .../libtp_c/include/d/menu/d_menu_window.h | 142 +- .../libtp_c/include/d/meter/d_meter_HIO.h | 1 - external/libtp_c/include/defines.h | 3 + .../libtp_c/include/dolphin/gx/GXTexture.h | 21 - external/libtp_c/include/dolphin/gx/gx.h | 2478 ++++++++++++++++- external/libtp_c/include/dolphin/mtx/mtx.h | 18 + external/libtp_c/include/dolphin/mtx/vec.h | 13 + external/libtp_c/include/dolphin/os/OS.h | 3 + external/libtp_c/include/dolphin/os/OSCache.h | 2 +- external/libtp_c/include/dolphin/types.h | 1 + external/libtp_c/include/f_op/f_op_actor.h | 27 +- .../libtp_c/include/f_op/f_op_actor_mng.h | 16 + external/libtp_c/include/f_op/f_op_draw_tag.h | 1 - .../libtp_c/include/f_op/f_op_scene_req.h | 1 - external/libtp_c/include/m_Do/m_Do_audio.h | 1 - .../include/m_Do/m_Do_controller_pad.h | 1 - external/libtp_c/include/m_Do/m_Do_ext.h | 3 +- external/libtp_c/include/m_Do/m_Do_mtx.h | 63 +- .../include/m_Do/m_Re_controller_pad.h | 3 +- external/libtp_c/include/msl_c/math.h | 18 +- external/libtp_c/include/rel/d/a/b/d_a_b_ds.h | 23 + external/libtp_c/include/utils.h | 2 + external/libtp_c/src/utils.cpp | 9 + external/misc/ad.py | 4 +- external/misc/any.py | 8 + external/misc/generate_actor_bin.py | 826 ++++++ isos/.gitkeep | 0 modules/boot/include/boot.h | 4 +- modules/boot/include/cheats.h | 36 +- modules/boot/include/collision_view.h | 237 ++ modules/boot/include/commands.h | 61 +- modules/boot/include/controller.h | 3 + modules/boot/include/font.h | 5 +- modules/boot/include/global_data.h | 4 + modules/boot/include/gz_flags.h | 45 +- modules/boot/include/{ => menus}/menu.h | 10 +- modules/boot/include/menus/utils/menu_mgr.h | 2 +- modules/boot/include/modules.h | 31 + modules/boot/include/pos_settings.h | 13 +- modules/boot/include/practice.h | 2 +- modules/boot/include/save_manager.h | 60 +- modules/boot/include/save_specials.h | 3 +- modules/boot/include/scene.h | 7 +- modules/boot/include/settings.h | 136 +- modules/boot/include/tools.h | 3 + modules/boot/include/trigger_view.h | 25 + modules/boot/include/utils/card.h | 15 +- modules/boot/include/utils/containers/deque.h | 18 + modules/boot/include/utils/draw.h | 3 +- modules/boot/include/utils/hook.h | 1 + modules/boot/include/utils/lines.h | 4 +- modules/boot/include/utils/link.h | 37 +- modules/boot/include/utils/memory.h | 21 + modules/boot/include/utils/texture.h | 3 +- modules/boot/include/watches.h | 24 - modules/boot/src/GXDraw.cpp | 311 +++ modules/boot/src/cheats.cpp | 69 +- modules/boot/src/commands.cpp | 161 +- modules/boot/src/controller.cpp | 61 +- modules/boot/src/fifo_queue.cpp | 6 +- modules/boot/src/font.cpp | 16 + modules/boot/src/geometry_draw.cpp | 856 ++++++ modules/boot/src/global_data.cpp | 31 + modules/boot/src/gz_flags.cpp | 81 +- modules/boot/src/main.cpp | 48 +- modules/boot/src/{ => menus}/menu.cpp | 6 +- modules/boot/src/menus/utils/menu_mgr.cpp | 2 +- modules/boot/src/modules.cpp | 101 + modules/boot/src/pos_settings.cpp | 19 - modules/boot/src/practice.cpp | 4 +- modules/boot/src/rollcheck.cpp | 68 - modules/boot/src/save_manager.cpp | 6 +- modules/boot/src/save_specials.cpp | 60 +- modules/boot/src/scene.cpp | 27 +- modules/boot/src/settings.cpp | 69 +- modules/boot/src/timer.cpp | 169 +- modules/boot/src/tools.cpp | 161 +- modules/boot/src/utils/audio.cpp | 8 +- modules/boot/src/utils/card.cpp | 185 +- modules/boot/src/utils/cursor.cpp | 37 +- modules/boot/src/utils/draw.cpp | 8 +- modules/boot/src/utils/hook.cpp | 265 +- modules/boot/src/utils/lines.cpp | 71 +- modules/boot/src/utils/link.cpp | 66 +- modules/boot/src/utils/memory.cpp | 158 +- modules/boot/src/utils/texture.cpp | 10 +- modules/boot/src/watches.cpp | 3 - .../{movelink => actor_view}/CMakeLists.txt | 0 .../features/actor_view/include/actor_view.h | 5 + .../{movelink => actor_view}/include/main.h | 0 .../features/actor_view/src/actor_view.cpp | 52 + modules/features/actor_view/src/main.cpp | 14 + modules/features/bit/CMakeLists.txt | 5 + modules/{boot => features/bit}/include/bit.h | 0 modules/features/bit/include/main.h | 6 + modules/{boot => features/bit}/src/bit.cpp | 20 +- modules/features/bit/src/main.cpp | 28 + modules/features/corotd/CMakeLists.txt | 5 + .../corotd}/include/corotdcheck.h | 0 modules/features/corotd/include/main.h | 6 + .../corotd}/src/corotdcheck.cpp | 2 +- modules/features/corotd/src/main.cpp | 15 + modules/features/free_cam/src/free_cam.cpp | 5 +- modules/features/gorge/CMakeLists.txt | 5 + .../{boot => features/gorge}/include/gorge.h | 2 + modules/features/gorge/include/main.h | 6 + .../{boot => features/gorge}/src/gorge.cpp | 41 +- modules/features/gorge/src/main.cpp | 22 + .../input_viewer/src/input_viewer.cpp | 9 +- modules/features/mash_checker/CMakeLists.txt | 5 + modules/features/mash_checker/include/main.h | 6 + .../mash_checker/include/mash_checker.h | 4 + modules/features/mash_checker/src/main.cpp | 13 + .../mash_checker/src/mash_checker.cpp | 79 + modules/features/moon_jump/CMakeLists.txt | 5 + modules/features/moon_jump/include/main.h | 6 + modules/features/moon_jump/src/main.cpp | 26 + modules/features/moveactor/CMakeLists.txt | 5 + modules/features/moveactor/include/main.h | 6 + .../features/moveactor/include/moveactor.h | 8 + .../{movelink => moveactor}/src/main.cpp | 6 +- modules/features/moveactor/src/moveactor.cpp | 151 + modules/features/movelink/include/movelink.h | 7 - modules/features/movelink/src/movelink.cpp | 582 ---- .../features/projection_view/CMakeLists.txt | 5 + .../features/projection_view/include/main.h | 6 + .../projection_view/include/projection_view.h | 28 + modules/features/projection_view/src/main.cpp | 14 + .../projection_view/src/projection_view.cpp | 75 + modules/features/rollcheck/CMakeLists.txt | 5 + modules/features/rollcheck/include/main.h | 6 + .../rollcheck}/include/rollcheck.h | 0 modules/features/rollcheck/src/main.cpp | 15 + modules/features/rollcheck/src/rollcheck.cpp | 207 ++ .../transform_indicator/CMakeLists.txt | 5 + .../transform_indicator/include/main.h | 6 + .../include/transform_indicator.h | 9 + .../features/transform_indicator/src/main.cpp | 29 + .../src/transform_indicator.cpp | 47 + modules/features/trigger_view/CMakeLists.txt | 5 + modules/features/trigger_view/include/main.h | 6 + .../trigger_view/include/trigger_view.h | 5 + modules/features/trigger_view/src/main.cpp | 14 + .../trigger_view/src/trigger_view.cpp | 417 +++ modules/features/umd/CMakeLists.txt | 5 + modules/features/umd/include/main.h | 6 + modules/{boot => features/umd}/include/umd.h | 0 modules/features/umd/src/main.cpp | 15 + modules/{boot => features/umd}/src/umd.cpp | 4 +- modules/init/src/main.cpp | 107 +- .../menu_actor_list/include/actor_list_menu.h | 43 +- .../menu_actor_list/src/actor_list_menu.cpp | 367 ++- modules/menus/menu_actor_list/src/main.cpp | 1 + .../include/actor_spawn_menu.h | 35 +- .../menu_actor_spawn/src/actor_spawn_menu.cpp | 60 +- modules/menus/menu_actor_spawn/src/main.cpp | 14 +- .../menu_ad_saves/include/ad_saves_menu.h | 2 +- .../menus/menu_amounts/include/amounts_menu.h | 2 +- .../include/any_bite_saves_menu.h | 2 +- .../src/any_bite_saves_menu.cpp | 10 +- .../menu_any_saves/include/any_saves_menu.h | 2 +- .../menu_any_saves/src/any_saves_menu.cpp | 10 +- .../menus/menu_cheats/include/cheats_menu.h | 34 +- modules/menus/menu_cheats/src/cheat_menu.cpp | 71 +- .../menus/menu_collision_view/CMakeLists.txt | 5 + .../include/collision_view_menu.h | 13 + .../menus/menu_collision_view/include/main.h | 6 + .../src/collision_view_menu.cpp | 67 + .../menus/menu_collision_view/src/main.cpp | 50 + modules/menus/menu_combo/CMakeLists.txt | 5 + modules/menus/menu_combo/include/combo_menu.h | 48 + modules/menus/menu_combo/include/main.h | 6 + modules/menus/menu_combo/src/combo_menu.cpp | 157 ++ modules/menus/menu_combo/src/main.cpp | 64 + modules/menus/menu_credits/CMakeLists.txt | 5 + .../menus/menu_credits/include/credits_menu.h | 10 + modules/menus/menu_credits/include/main.h | 6 + .../menus/menu_credits/src/credits_menu.cpp | 56 + modules/menus/menu_credits/src/main.cpp | 50 + .../include/dungeon_flags_menu.h | 15 +- .../src/dungeon_flags_menu.cpp | 60 +- modules/menus/menu_dungeon_flags/src/main.cpp | 4 +- .../menu_flag_log/include/flag_log_menu.h | 2 +- .../menus/menu_flag_log/src/flag_log_menu.cpp | 2 +- .../include/flag_records_menu.h | 2 +- .../src/flag_records_menu.cpp | 2 +- modules/menus/menu_flags/include/flags_menu.h | 2 +- .../include/general_flags_menu.h | 18 +- .../src/general_flags_menu.cpp | 63 +- modules/menus/menu_general_flags/src/main.cpp | 4 +- .../include/menu_glitchless_saves.h | 2 +- .../include/hundo_saves_menu.h | 4 +- .../menu_hundo_saves/src/hundo_saves_menu.cpp | 2 - .../menu_inventory/include/inventory_menu.h | 2 +- .../menu_item_wheel/include/item_wheel_menu.h | 2 +- .../menu_item_wheel/src/item_wheel_menu.cpp | 153 +- modules/menus/menu_main/include/main_menu.h | 2 +- .../menu_memfiles/include/memfiles_menu.h | 2 +- .../menus/menu_memfiles/src/memfiles_menu.cpp | 23 +- .../menus/menu_memory/include/memory_menu.h | 2 +- .../include/memory_editor_menu.h | 4 +- .../src/memory_editor_menu.cpp | 127 +- .../menu_nosq_saves/include/nosq_saves_menu.h | 2 +- .../menu_nosq_saves/src/nosq_saves_menu.cpp | 6 +- modules/menus/menu_pause/include/pause_menu.h | 24 +- modules/menus/menu_pause/src/main.cpp | 4 +- modules/menus/menu_pause/src/pause_menu.cpp | 171 +- .../include/portal_flags_menu.h | 25 +- modules/menus/menu_portal_flags/src/main.cpp | 4 +- .../src/portal_flags_menu.cpp | 85 +- .../include/position_settings_menu.h | 2 +- .../src/position_settings_menu.cpp | 43 +- .../menu_practice/include/practice_menu.h | 2 +- .../menus/menu_projection_view/CMakeLists.txt | 5 + .../menus/menu_projection_view/include/main.h | 6 + .../include/projection_view_menu.h | 14 + .../menus/menu_projection_view/src/main.cpp | 50 + .../src/projection_view_menu.cpp | 39 + modules/menus/menu_scene/include/scene_menu.h | 4 +- modules/menus/menu_scene/src/scene_menu.cpp | 50 +- .../menu_settings/include/settings_menu.h | 10 +- .../menus/menu_settings/src/settings_menu.cpp | 77 +- modules/menus/menu_tools/include/tools_menu.h | 31 +- modules/menus/menu_tools/src/tools_menu.cpp | 393 +-- .../menus/menu_trigger_view/CMakeLists.txt | 5 + .../menus/menu_trigger_view/include/main.h | 6 + .../include/trigger_view_menu.h | 14 + modules/menus/menu_trigger_view/src/main.cpp | 50 + .../src/trigger_view_menu.cpp | 61 + .../menus/menu_warp/include/warping_menu.h | 2 +- modules/menus/menu_warp/src/warping_menu.cpp | 18 +- .../menus/menu_watches/include/watches_menu.h | 7 +- .../menus/menu_watches/src/watches_menu.cpp | 343 ++- res/icons/hand.png | Bin 0 -> 17341 bytes res/icons/wolf.png | Bin 0 -> 16271 bytes res/map/GCN_NTSCJ.lst | 5 + res/map/GCN_NTSCU.lst | 5 + res/map/GCN_PAL.lst | 5 + res/map/WII_NTSCJ.lst | 4 + res/map/WII_NTSCU_10.lst | 4 + res/map/WII_NTSCU_12.lst | 4 + res/map/WII_PAL.lst | 4 + res/proc_info/procs.bin | Bin 0 -> 25344 bytes res/save_files/ad.bin | Bin 3360 -> 3440 bytes res/save_files/any.bin | Bin 4080 -> 4080 bytes res/save_files/any/lakebed_1.bin | Bin 2700 -> 2700 bytes res/save_files/any/plumm_oob.bin | Bin 2700 -> 2700 bytes res/save_files/nosq/rupee_roll.bin | Bin 2700 -> 2700 bytes .../D_MN01/00/{spawns.bin => sp.bin} | Bin .../D_MN01/01/{spawns.bin => sp.bin} | Bin .../D_MN01/02/{spawns.bin => sp.bin} | Bin .../D_MN01/03/{spawns.bin => sp.bin} | Bin .../D_MN01/05/{spawns.bin => sp.bin} | Bin .../D_MN01/06/{spawns.bin => sp.bin} | Bin .../D_MN01/07/{spawns.bin => sp.bin} | Bin .../D_MN01/08/{spawns.bin => sp.bin} | Bin .../D_MN01/09/{spawns.bin => sp.bin} | Bin .../D_MN01/10/{spawns.bin => sp.bin} | Bin .../D_MN01/11/{spawns.bin => sp.bin} | Bin .../D_MN01/12/{spawns.bin => sp.bin} | Bin .../D_MN01/13/{spawns.bin => sp.bin} | Bin res/stage_info/D_MN01/rooms.bin | Bin 832 -> 832 bytes res/stage_info/D_MN01/rooms.bin.bak | Bin 0 -> 832 bytes .../D_MN01A/50/{spawns.bin => sp.bin} | Bin .../D_MN01B/51/{spawns.bin => sp.bin} | Bin .../D_MN04/01/{spawns.bin => sp.bin} | Bin .../D_MN04/03/{spawns.bin => sp.bin} | Bin .../D_MN04/04/{spawns.bin => sp.bin} | Bin .../D_MN04/05/{spawns.bin => sp.bin} | Bin .../D_MN04/06/{spawns.bin => sp.bin} | Bin .../D_MN04/07/{spawns.bin => sp.bin} | Bin .../D_MN04/09/{spawns.bin => sp.bin} | Bin .../D_MN04/11/{spawns.bin => sp.bin} | Bin .../D_MN04/12/{spawns.bin => sp.bin} | Bin .../D_MN04/13/{spawns.bin => sp.bin} | Bin .../D_MN04/14/{spawns.bin => sp.bin} | Bin .../D_MN04/16/{spawns.bin => sp.bin} | Bin .../D_MN04/17/{spawns.bin => sp.bin} | Bin res/stage_info/D_MN04/rooms.bin | Bin 832 -> 832 bytes .../D_MN04A/50/{spawns.bin => sp.bin} | Bin .../D_MN04B/51/{spawns.bin => sp.bin} | Bin .../D_MN05/00/{spawns.bin => sp.bin} | Bin .../D_MN05/01/{spawns.bin => sp.bin} | Bin .../D_MN05/02/{spawns.bin => sp.bin} | Bin .../D_MN05/03/{spawns.bin => sp.bin} | Bin .../D_MN05/04/{spawns.bin => sp.bin} | Bin .../D_MN05/05/{spawns.bin => sp.bin} | Bin .../D_MN05/07/{spawns.bin => sp.bin} | Bin .../D_MN05/09/{spawns.bin => sp.bin} | Bin .../D_MN05/10/{spawns.bin => sp.bin} | Bin .../D_MN05/11/{spawns.bin => sp.bin} | Bin .../D_MN05/12/{spawns.bin => sp.bin} | Bin .../D_MN05/19/{spawns.bin => sp.bin} | Bin .../D_MN05/22/{spawns.bin => sp.bin} | Bin res/stage_info/D_MN05/rooms.bin | Bin 832 -> 832 bytes .../D_MN05A/50/{spawns.bin => sp.bin} | Bin .../D_MN05B/51/{spawns.bin => sp.bin} | Bin .../D_MN06/00/{spawns.bin => sp.bin} | Bin .../D_MN06/01/{spawns.bin => sp.bin} | Bin .../D_MN06/02/{spawns.bin => sp.bin} | Bin .../D_MN06/03/{spawns.bin => sp.bin} | Bin .../D_MN06/04/{spawns.bin => sp.bin} | Bin .../D_MN06/05/{spawns.bin => sp.bin} | Bin .../D_MN06/06/{spawns.bin => sp.bin} | Bin .../D_MN06/07/{spawns.bin => sp.bin} | Bin .../D_MN06/08/{spawns.bin => sp.bin} | Bin res/stage_info/D_MN06/rooms.bin | Bin 576 -> 576 bytes .../D_MN06A/50/{spawns.bin => sp.bin} | Bin .../D_MN06B/51/{spawns.bin => sp.bin} | Bin .../D_MN07/00/{spawns.bin => sp.bin} | Bin .../D_MN07/01/{spawns.bin => sp.bin} | Bin .../D_MN07/02/{spawns.bin => sp.bin} | Bin .../D_MN07/03/{spawns.bin => sp.bin} | Bin .../D_MN07/04/{spawns.bin => sp.bin} | Bin .../D_MN07/05/{spawns.bin => sp.bin} | Bin .../D_MN07/06/{spawns.bin => sp.bin} | Bin .../D_MN07/07/{spawns.bin => sp.bin} | Bin .../D_MN07/08/{spawns.bin => sp.bin} | Bin .../D_MN07/10/{spawns.bin => sp.bin} | Bin .../D_MN07/11/{spawns.bin => sp.bin} | Bin .../D_MN07/12/{spawns.bin => sp.bin} | Bin .../D_MN07/13/{spawns.bin => sp.bin} | Bin .../D_MN07/14/{spawns.bin => sp.bin} | Bin .../D_MN07/15/{spawns.bin => sp.bin} | Bin .../D_MN07/16/{spawns.bin => sp.bin} | Bin res/stage_info/D_MN07/rooms.bin | Bin 1024 -> 1024 bytes .../D_MN07A/50/{spawns.bin => sp.bin} | Bin .../D_MN07B/51/{spawns.bin => sp.bin} | Bin .../D_MN08/00/{spawns.bin => sp.bin} | Bin .../D_MN08/01/{spawns.bin => sp.bin} | Bin .../D_MN08/02/{spawns.bin => sp.bin} | Bin .../D_MN08/04/{spawns.bin => sp.bin} | Bin .../D_MN08/05/{spawns.bin => sp.bin} | Bin .../D_MN08/07/{spawns.bin => sp.bin} | Bin .../D_MN08/08/{spawns.bin => sp.bin} | Bin .../D_MN08/09/{spawns.bin => sp.bin} | Bin .../D_MN08/10/{spawns.bin => sp.bin} | Bin .../D_MN08/11/{spawns.bin => sp.bin} | Bin res/stage_info/D_MN08/rooms.bin | Bin 640 -> 640 bytes .../D_MN08A/10/{spawns.bin => sp.bin} | Bin .../D_MN08B/51/{spawns.bin => sp.bin} | Bin .../D_MN08C/52/{spawns.bin => sp.bin} | Bin .../D_MN08D/50/{spawns.bin => sp.bin} | Bin .../D_MN08D/53/{spawns.bin => sp.bin} | Bin .../D_MN08D/54/{spawns.bin => sp.bin} | Bin .../D_MN08D/55/{spawns.bin => sp.bin} | Bin .../D_MN08D/56/{spawns.bin => sp.bin} | Bin .../D_MN08D/57/{spawns.bin => sp.bin} | Bin .../D_MN08D/60/{spawns.bin => sp.bin} | Bin res/stage_info/D_MN08D/rooms.bin | Bin 448 -> 448 bytes .../D_MN09/01/{spawns.bin => sp.bin} | Bin .../D_MN09/02/{spawns.bin => sp.bin} | Bin .../D_MN09/03/{spawns.bin => sp.bin} | Bin .../D_MN09/04/{spawns.bin => sp.bin} | Bin .../D_MN09/05/{spawns.bin => sp.bin} | Bin .../D_MN09/06/{spawns.bin => sp.bin} | Bin .../D_MN09/08/{spawns.bin => sp.bin} | Bin .../D_MN09/09/{spawns.bin => sp.bin} | Bin .../D_MN09/11/{spawns.bin => sp.bin} | Bin .../D_MN09/12/{spawns.bin => sp.bin} | Bin .../D_MN09/13/{spawns.bin => sp.bin} | Bin .../D_MN09/14/{spawns.bin => sp.bin} | Bin .../D_MN09/15/{spawns.bin => sp.bin} | Bin res/stage_info/D_MN09/rooms.bin | Bin 832 -> 832 bytes .../D_MN09A/50/{spawns.bin => sp.bin} | Bin .../D_MN09A/51/{spawns.bin => sp.bin} | Bin .../D_MN09B/00/{spawns.bin => sp.bin} | Bin .../D_MN09C/00/{spawns.bin => sp.bin} | Bin .../D_MN10/00/{spawns.bin => sp.bin} | Bin .../D_MN10/01/{spawns.bin => sp.bin} | Bin .../D_MN10/02/{spawns.bin => sp.bin} | Bin .../D_MN10/03/{spawns.bin => sp.bin} | Bin .../D_MN10/04/{spawns.bin => sp.bin} | Bin .../D_MN10/05/{spawns.bin => sp.bin} | Bin .../D_MN10/06/{spawns.bin => sp.bin} | Bin .../D_MN10/07/{spawns.bin => sp.bin} | Bin .../D_MN10/08/{spawns.bin => sp.bin} | Bin .../D_MN10/09/{spawns.bin => sp.bin} | Bin .../D_MN10/10/{spawns.bin => sp.bin} | Bin .../D_MN10/11/{spawns.bin => sp.bin} | Bin .../D_MN10/12/{spawns.bin => sp.bin} | Bin .../D_MN10/13/{spawns.bin => sp.bin} | Bin .../D_MN10/14/{spawns.bin => sp.bin} | Bin .../D_MN10/15/{spawns.bin => sp.bin} | Bin .../D_MN10/16/{spawns.bin => sp.bin} | Bin res/stage_info/D_MN10/rooms.bin | Bin 1088 -> 1088 bytes .../D_MN10A/50/{spawns.bin => sp.bin} | Bin .../D_MN10B/51/{spawns.bin => sp.bin} | Bin .../D_MN11/00/{spawns.bin => sp.bin} | Bin .../D_MN11/01/{spawns.bin => sp.bin} | Bin .../D_MN11/02/{spawns.bin => sp.bin} | Bin .../D_MN11/03/{spawns.bin => sp.bin} | Bin .../D_MN11/04/{spawns.bin => sp.bin} | Bin .../D_MN11/05/{spawns.bin => sp.bin} | Bin .../D_MN11/06/{spawns.bin => sp.bin} | Bin .../D_MN11/07/{spawns.bin => sp.bin} | Bin .../D_MN11/08/{spawns.bin => sp.bin} | Bin .../D_MN11/09/{spawns.bin => sp.bin} | Bin .../D_MN11/11/{spawns.bin => sp.bin} | Bin .../D_MN11/13/{spawns.bin => sp.bin} | Bin res/stage_info/D_MN11/rooms.bin | Bin 768 -> 768 bytes .../D_MN11A/50/{spawns.bin => sp.bin} | Bin .../D_MN11B/49/{spawns.bin => sp.bin} | Bin .../D_MN11B/51/{spawns.bin => sp.bin} | Bin .../D_SB00/00/{spawns.bin => sp.bin} | Bin .../D_SB01/00/{spawns.bin => sp.bin} | Bin .../D_SB01/01/{spawns.bin => sp.bin} | Bin .../D_SB01/02/{spawns.bin => sp.bin} | Bin .../D_SB01/03/{spawns.bin => sp.bin} | Bin .../D_SB01/04/{spawns.bin => sp.bin} | Bin .../D_SB01/05/{spawns.bin => sp.bin} | Bin .../D_SB01/06/{spawns.bin => sp.bin} | Bin .../D_SB01/07/{spawns.bin => sp.bin} | Bin .../D_SB01/08/{spawns.bin => sp.bin} | Bin .../D_SB01/09/{spawns.bin => sp.bin} | Bin .../D_SB01/10/{spawns.bin => sp.bin} | Bin .../D_SB01/11/{spawns.bin => sp.bin} | Bin .../D_SB01/12/{spawns.bin => sp.bin} | Bin .../D_SB01/13/{spawns.bin => sp.bin} | Bin .../D_SB01/14/{spawns.bin => sp.bin} | Bin .../D_SB01/15/{spawns.bin => sp.bin} | Bin .../D_SB01/16/{spawns.bin => sp.bin} | Bin .../D_SB01/17/{spawns.bin => sp.bin} | Bin .../D_SB01/18/{spawns.bin => sp.bin} | Bin .../D_SB01/19/{spawns.bin => sp.bin} | Bin .../D_SB01/20/{spawns.bin => sp.bin} | Bin .../D_SB01/21/{spawns.bin => sp.bin} | Bin .../D_SB01/22/{spawns.bin => sp.bin} | Bin .../D_SB01/23/{spawns.bin => sp.bin} | Bin .../D_SB01/24/{spawns.bin => sp.bin} | Bin .../D_SB01/25/{spawns.bin => sp.bin} | Bin .../D_SB01/26/{spawns.bin => sp.bin} | Bin .../D_SB01/27/{spawns.bin => sp.bin} | Bin .../D_SB01/28/{spawns.bin => sp.bin} | Bin .../D_SB01/29/{spawns.bin => sp.bin} | Bin .../D_SB01/30/{spawns.bin => sp.bin} | Bin .../D_SB01/31/{spawns.bin => sp.bin} | Bin .../D_SB01/32/{spawns.bin => sp.bin} | Bin .../D_SB01/33/{spawns.bin => sp.bin} | Bin .../D_SB01/34/{spawns.bin => sp.bin} | Bin .../D_SB01/35/{spawns.bin => sp.bin} | Bin .../D_SB01/36/{spawns.bin => sp.bin} | Bin .../D_SB01/37/{spawns.bin => sp.bin} | Bin .../D_SB01/38/{spawns.bin => sp.bin} | Bin .../D_SB01/39/{spawns.bin => sp.bin} | Bin .../D_SB01/40/{spawns.bin => sp.bin} | Bin .../D_SB01/41/{spawns.bin => sp.bin} | Bin .../D_SB01/42/{spawns.bin => sp.bin} | Bin .../D_SB01/43/{spawns.bin => sp.bin} | Bin .../D_SB01/44/{spawns.bin => sp.bin} | Bin .../D_SB01/45/{spawns.bin => sp.bin} | Bin .../D_SB01/46/{spawns.bin => sp.bin} | Bin .../D_SB01/47/{spawns.bin => sp.bin} | Bin .../D_SB01/48/{spawns.bin => sp.bin} | Bin .../D_SB01/49/{spawns.bin => sp.bin} | Bin .../D_SB02/00/{spawns.bin => sp.bin} | Bin .../D_SB03/00/{spawns.bin => sp.bin} | Bin .../D_SB04/10/{spawns.bin => sp.bin} | Bin .../D_SB05/00/{spawns.bin => sp.bin} | Bin .../D_SB06/01/{spawns.bin => sp.bin} | Bin .../D_SB07/02/{spawns.bin => sp.bin} | Bin .../D_SB08/03/{spawns.bin => sp.bin} | Bin .../D_SB09/04/{spawns.bin => sp.bin} | Bin .../D_SB10/00/{spawns.bin => sp.bin} | Bin .../F_SP00/00/{spawns.bin => sp.bin} | Bin .../F_SP102/00/{spawns.bin => sp.bin} | Bin .../F_SP103/00/{spawns.bin => sp.bin} | Bin .../F_SP103/01/{spawns.bin => sp.bin} | Bin .../F_SP104/01/{spawns.bin => sp.bin} | Bin .../F_SP108/00/{spawns.bin => sp.bin} | Bin .../F_SP108/01/{spawns.bin => sp.bin} | Bin .../F_SP108/02/{spawns.bin => sp.bin} | Bin .../F_SP108/03/{spawns.bin => sp.bin} | Bin .../F_SP108/04/{spawns.bin => sp.bin} | Bin .../F_SP108/05/{spawns.bin => sp.bin} | Bin .../F_SP108/06/{spawns.bin => sp.bin} | Bin .../F_SP108/08/{spawns.bin => sp.bin} | Bin .../F_SP108/11/{spawns.bin => sp.bin} | Bin .../F_SP108/14/{spawns.bin => sp.bin} | Bin res/stage_info/F_SP108/rooms.bin | Bin 640 -> 640 bytes .../F_SP109/00/{spawns.bin => sp.bin} | Bin .../F_SP110/00/{spawns.bin => sp.bin} | Bin .../F_SP110/01/{spawns.bin => sp.bin} | Bin .../F_SP110/02/{spawns.bin => sp.bin} | Bin .../F_SP110/03/{spawns.bin => sp.bin} | Bin .../F_SP111/00/{spawns.bin => sp.bin} | Bin .../F_SP112/01/{spawns.bin => sp.bin} | Bin .../F_SP113/00/{spawns.bin => sp.bin} | Bin .../F_SP113/01/{spawns.bin => sp.bin} | Bin .../F_SP114/00/{spawns.bin => sp.bin} | Bin .../F_SP114/01/{spawns.bin => sp.bin} | Bin .../F_SP114/02/{spawns.bin => sp.bin} | Bin .../F_SP115/00/{spawns.bin => sp.bin} | Bin .../F_SP115/01/{spawns.bin => sp.bin} | Bin res/stage_info/F_SP115/rooms.bin | Bin 128 -> 128 bytes .../F_SP116/00/{spawns.bin => sp.bin} | Bin .../F_SP116/01/{spawns.bin => sp.bin} | Bin .../F_SP116/02/{spawns.bin => sp.bin} | Bin .../F_SP116/03/{spawns.bin => sp.bin} | Bin .../F_SP116/04/{spawns.bin => sp.bin} | Bin res/stage_info/F_SP116/rooms.bin | Bin 320 -> 320 bytes .../F_SP117/01/{spawns.bin => sp.bin} | Bin .../F_SP117/02/{spawns.bin => sp.bin} | Bin .../F_SP117/03/{spawns.bin => sp.bin} | Bin res/stage_info/F_SP117/rooms.bin | Bin 192 -> 192 bytes .../F_SP118/01/{spawns.bin => sp.bin} | Bin .../F_SP118/02/{spawns.bin => sp.bin} | Bin .../F_SP118/03/{spawns.bin => sp.bin} | Bin res/stage_info/F_SP118/rooms.bin | Bin 192 -> 192 bytes .../F_SP121/00/{spawns.bin => sp.bin} | Bin .../F_SP121/01/{spawns.bin => sp.bin} | Bin .../F_SP121/02/{spawns.bin => sp.bin} | Bin .../F_SP121/03/{spawns.bin => sp.bin} | Bin .../F_SP121/04/{spawns.bin => sp.bin} | Bin .../F_SP121/05/{spawns.bin => sp.bin} | Bin .../F_SP121/06/{spawns.bin => sp.bin} | Bin .../F_SP121/07/{spawns.bin => sp.bin} | Bin .../F_SP121/09/{spawns.bin => sp.bin} | Bin .../F_SP121/10/{spawns.bin => sp.bin} | Bin .../F_SP121/11/{spawns.bin => sp.bin} | Bin .../F_SP121/12/{spawns.bin => sp.bin} | Bin .../F_SP121/13/{spawns.bin => sp.bin} | Bin .../F_SP121/14/{spawns.bin => sp.bin} | Bin .../F_SP121/15/{spawns.bin => sp.bin} | Bin res/stage_info/F_SP121/rooms.bin | Bin 960 -> 960 bytes .../F_SP122/08/{spawns.bin => sp.bin} | Bin .../F_SP122/16/{spawns.bin => sp.bin} | Bin .../F_SP122/17/{spawns.bin => sp.bin} | Bin res/stage_info/F_SP122/rooms.bin | Bin 192 -> 192 bytes .../F_SP123/13/{spawns.bin => sp.bin} | Bin .../F_SP124/00/{spawns.bin => sp.bin} | Bin .../F_SP125/04/{spawns.bin => sp.bin} | Bin .../F_SP126/00/{spawns.bin => sp.bin} | Bin .../F_SP127/00/{spawns.bin => sp.bin} | Bin .../F_SP128/00/{spawns.bin => sp.bin} | Bin .../F_SP200/00/{spawns.bin => sp.bin} | Bin .../R_SP01/00/{spawns.bin => sp.bin} | Bin .../R_SP01/01/{spawns.bin => sp.bin} | Bin .../R_SP01/02/{spawns.bin => sp.bin} | Bin .../R_SP01/04/{spawns.bin => sp.bin} | Bin .../R_SP01/05/{spawns.bin => sp.bin} | Bin .../R_SP01/07/{spawns.bin => sp.bin} | Bin res/stage_info/R_SP01/rooms.bin | Bin 384 -> 384 bytes .../R_SP107/00/{spawns.bin => sp.bin} | Bin .../R_SP107/01/{spawns.bin => sp.bin} | Bin .../R_SP107/02/{spawns.bin => sp.bin} | Bin .../R_SP107/03/{spawns.bin => sp.bin} | Bin res/stage_info/R_SP107/rooms.bin | Bin 256 -> 256 bytes .../R_SP108/00/{spawns.bin => sp.bin} | Bin .../R_SP109/00/{spawns.bin => sp.bin} | Bin .../R_SP109/01/{spawns.bin => sp.bin} | Bin .../R_SP109/02/{spawns.bin => sp.bin} | Bin .../R_SP109/03/{spawns.bin => sp.bin} | Bin .../R_SP109/04/{spawns.bin => sp.bin} | Bin .../R_SP109/05/{spawns.bin => sp.bin} | Bin .../R_SP109/06/{spawns.bin => sp.bin} | Bin res/stage_info/R_SP109/rooms.bin | Bin 448 -> 448 bytes .../R_SP110/00/{spawns.bin => sp.bin} | Bin .../R_SP116/05/{spawns.bin => sp.bin} | Bin .../R_SP116/06/{spawns.bin => sp.bin} | Bin res/stage_info/R_SP116/rooms.bin | Bin 128 -> 128 bytes .../R_SP127/00/{spawns.bin => sp.bin} | Bin .../R_SP128/00/{spawns.bin => sp.bin} | Bin .../R_SP160/00/{spawns.bin => sp.bin} | Bin .../R_SP160/01/{spawns.bin => sp.bin} | Bin .../R_SP160/02/{spawns.bin => sp.bin} | Bin .../R_SP160/03/{spawns.bin => sp.bin} | Bin .../R_SP160/04/{spawns.bin => sp.bin} | Bin .../R_SP160/05/{spawns.bin => sp.bin} | Bin res/stage_info/R_SP160/rooms.bin | Bin 384 -> 384 bytes .../R_SP161/07/{spawns.bin => sp.bin} | Bin .../R_SP209/07/{spawns.bin => sp.bin} | Bin .../R_SP300/00/{spawns.bin => sp.bin} | Bin .../R_SP301/00/{spawns.bin => sp.bin} | Bin .../S_MV000/00/{spawns.bin => sp.bin} | Bin res/tex/file.tex | Bin 1040 -> 0 bytes res/tex/folder_empty.tex | Bin 1040 -> 0 bytes res/tex/folder_full.tex | Bin 1040 -> 0 bytes res/tex/hand.tex | Bin 0 -> 1040 bytes res/tex/heart.tex | Bin 0 -> 262160 bytes res/tex/wolf.tex | Bin 0 -> 1040 bytes 635 files changed, 12843 insertions(+), 5164 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 FEATURES.md create mode 100644 external/libtp_c/include/JSystem/JMATrigonometric.h create mode 100644 external/libtp_c/include/JSystem/JMath.h create mode 100644 external/libtp_c/include/SSystem/SComponent/c_lib.h delete mode 100644 external/libtp_c/include/addrs.h create mode 100644 external/libtp_c/include/d/a/d_a_npc.h create mode 100644 external/libtp_c/include/d/bg/d_bg_s_captpoly.h create mode 100644 external/libtp_c/include/d/d_item.h create mode 100644 external/libtp_c/include/d/d_path.h create mode 100644 external/misc/generate_actor_bin.py create mode 100644 isos/.gitkeep create mode 100644 modules/boot/include/collision_view.h rename modules/boot/include/{ => menus}/menu.h (84%) create mode 100644 modules/boot/include/modules.h create mode 100644 modules/boot/include/trigger_view.h delete mode 100644 modules/boot/include/watches.h create mode 100644 modules/boot/src/GXDraw.cpp create mode 100644 modules/boot/src/geometry_draw.cpp rename modules/boot/src/{ => menus}/menu.cpp (80%) create mode 100644 modules/boot/src/modules.cpp delete mode 100644 modules/boot/src/pos_settings.cpp delete mode 100644 modules/boot/src/rollcheck.cpp delete mode 100644 modules/boot/src/watches.cpp rename modules/features/{movelink => actor_view}/CMakeLists.txt (100%) create mode 100644 modules/features/actor_view/include/actor_view.h rename modules/features/{movelink => actor_view}/include/main.h (100%) create mode 100644 modules/features/actor_view/src/actor_view.cpp create mode 100644 modules/features/actor_view/src/main.cpp create mode 100644 modules/features/bit/CMakeLists.txt rename modules/{boot => features/bit}/include/bit.h (100%) create mode 100644 modules/features/bit/include/main.h rename modules/{boot => features/bit}/src/bit.cpp (86%) create mode 100644 modules/features/bit/src/main.cpp create mode 100644 modules/features/corotd/CMakeLists.txt rename modules/{boot => features/corotd}/include/corotdcheck.h (100%) create mode 100644 modules/features/corotd/include/main.h rename modules/{boot => features/corotd}/src/corotdcheck.cpp (98%) create mode 100644 modules/features/corotd/src/main.cpp create mode 100644 modules/features/gorge/CMakeLists.txt rename modules/{boot => features/gorge}/include/gorge.h (82%) create mode 100644 modules/features/gorge/include/main.h rename modules/{boot => features/gorge}/src/gorge.cpp (76%) create mode 100644 modules/features/gorge/src/main.cpp create mode 100644 modules/features/mash_checker/CMakeLists.txt create mode 100644 modules/features/mash_checker/include/main.h create mode 100644 modules/features/mash_checker/include/mash_checker.h create mode 100644 modules/features/mash_checker/src/main.cpp create mode 100644 modules/features/mash_checker/src/mash_checker.cpp create mode 100644 modules/features/moon_jump/CMakeLists.txt create mode 100644 modules/features/moon_jump/include/main.h create mode 100644 modules/features/moon_jump/src/main.cpp create mode 100644 modules/features/moveactor/CMakeLists.txt create mode 100644 modules/features/moveactor/include/main.h create mode 100644 modules/features/moveactor/include/moveactor.h rename modules/features/{movelink => moveactor}/src/main.cpp (51%) create mode 100644 modules/features/moveactor/src/moveactor.cpp delete mode 100644 modules/features/movelink/include/movelink.h delete mode 100644 modules/features/movelink/src/movelink.cpp create mode 100644 modules/features/projection_view/CMakeLists.txt create mode 100644 modules/features/projection_view/include/main.h create mode 100644 modules/features/projection_view/include/projection_view.h create mode 100644 modules/features/projection_view/src/main.cpp create mode 100644 modules/features/projection_view/src/projection_view.cpp create mode 100644 modules/features/rollcheck/CMakeLists.txt create mode 100644 modules/features/rollcheck/include/main.h rename modules/{boot => features/rollcheck}/include/rollcheck.h (100%) create mode 100644 modules/features/rollcheck/src/main.cpp create mode 100644 modules/features/rollcheck/src/rollcheck.cpp create mode 100644 modules/features/transform_indicator/CMakeLists.txt create mode 100644 modules/features/transform_indicator/include/main.h create mode 100644 modules/features/transform_indicator/include/transform_indicator.h create mode 100644 modules/features/transform_indicator/src/main.cpp create mode 100644 modules/features/transform_indicator/src/transform_indicator.cpp create mode 100644 modules/features/trigger_view/CMakeLists.txt create mode 100644 modules/features/trigger_view/include/main.h create mode 100644 modules/features/trigger_view/include/trigger_view.h create mode 100644 modules/features/trigger_view/src/main.cpp create mode 100644 modules/features/trigger_view/src/trigger_view.cpp create mode 100644 modules/features/umd/CMakeLists.txt create mode 100644 modules/features/umd/include/main.h rename modules/{boot => features/umd}/include/umd.h (100%) create mode 100644 modules/features/umd/src/main.cpp rename modules/{boot => features/umd}/src/umd.cpp (98%) create mode 100644 modules/menus/menu_collision_view/CMakeLists.txt create mode 100644 modules/menus/menu_collision_view/include/collision_view_menu.h create mode 100644 modules/menus/menu_collision_view/include/main.h create mode 100644 modules/menus/menu_collision_view/src/collision_view_menu.cpp create mode 100644 modules/menus/menu_collision_view/src/main.cpp create mode 100644 modules/menus/menu_combo/CMakeLists.txt create mode 100644 modules/menus/menu_combo/include/combo_menu.h create mode 100644 modules/menus/menu_combo/include/main.h create mode 100644 modules/menus/menu_combo/src/combo_menu.cpp create mode 100644 modules/menus/menu_combo/src/main.cpp create mode 100644 modules/menus/menu_credits/CMakeLists.txt create mode 100644 modules/menus/menu_credits/include/credits_menu.h create mode 100644 modules/menus/menu_credits/include/main.h create mode 100644 modules/menus/menu_credits/src/credits_menu.cpp create mode 100644 modules/menus/menu_credits/src/main.cpp create mode 100644 modules/menus/menu_projection_view/CMakeLists.txt create mode 100644 modules/menus/menu_projection_view/include/main.h create mode 100644 modules/menus/menu_projection_view/include/projection_view_menu.h create mode 100644 modules/menus/menu_projection_view/src/main.cpp create mode 100644 modules/menus/menu_projection_view/src/projection_view_menu.cpp create mode 100644 modules/menus/menu_trigger_view/CMakeLists.txt create mode 100644 modules/menus/menu_trigger_view/include/main.h create mode 100644 modules/menus/menu_trigger_view/include/trigger_view_menu.h create mode 100644 modules/menus/menu_trigger_view/src/main.cpp create mode 100644 modules/menus/menu_trigger_view/src/trigger_view_menu.cpp create mode 100644 res/icons/hand.png create mode 100644 res/icons/wolf.png create mode 100644 res/proc_info/procs.bin rename res/stage_info/D_MN01/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01/06/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01/08/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01/09/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01/10/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01/11/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01/12/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01/13/{spawns.bin => sp.bin} (100%) create mode 100644 res/stage_info/D_MN01/rooms.bin.bak rename res/stage_info/D_MN01A/50/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN01B/51/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/06/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/09/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/11/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/12/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/13/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/14/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/16/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04/17/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04A/50/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN04B/51/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/09/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/10/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/11/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/12/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/19/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05/22/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05A/50/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN05B/51/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN06/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN06/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN06/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN06/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN06/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN06/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN06/06/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN06/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN06/08/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN06A/50/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN06B/51/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/06/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/08/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/10/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/11/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/12/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/13/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/14/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/15/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07/16/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07A/50/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN07B/51/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08/08/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08/09/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08/10/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08/11/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08A/10/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08B/51/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08C/52/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08D/50/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08D/53/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08D/54/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08D/55/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08D/56/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08D/57/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN08D/60/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/06/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/08/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/09/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/11/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/12/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/13/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/14/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09/15/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09A/50/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09A/51/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09B/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN09C/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/06/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/08/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/09/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/10/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/11/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/12/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/13/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/14/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/15/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10/16/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10A/50/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN10B/51/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11/06/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11/08/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11/09/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11/11/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11/13/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11A/50/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11B/49/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_MN11B/51/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB00/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/06/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/08/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/09/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/10/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/11/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/12/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/13/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/14/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/15/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/16/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/17/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/18/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/19/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/20/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/21/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/22/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/23/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/24/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/25/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/26/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/27/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/28/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/29/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/30/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/31/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/32/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/33/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/34/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/35/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/36/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/37/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/38/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/39/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/40/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/41/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/42/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/43/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/44/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/45/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/46/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/47/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/48/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB01/49/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB02/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB03/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB04/10/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB05/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB06/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB07/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB08/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB09/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/D_SB10/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP00/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP102/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP103/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP103/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP104/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP108/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP108/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP108/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP108/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP108/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP108/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP108/06/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP108/08/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP108/11/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP108/14/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP109/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP110/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP110/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP110/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP110/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP111/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP112/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP113/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP113/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP114/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP114/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP114/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP115/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP115/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP116/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP116/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP116/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP116/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP116/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP117/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP117/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP117/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP118/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP118/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP118/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/06/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/09/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/10/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/11/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/12/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/13/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/14/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP121/15/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP122/08/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP122/16/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP122/17/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP123/13/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP124/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP125/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP126/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP127/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP128/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/F_SP200/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP01/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP01/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP01/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP01/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP01/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP01/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP107/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP107/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP107/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP107/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP108/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP109/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP109/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP109/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP109/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP109/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP109/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP109/06/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP110/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP116/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP116/06/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP127/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP128/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP160/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP160/01/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP160/02/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP160/03/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP160/04/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP160/05/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP161/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP209/07/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP300/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/R_SP301/00/{spawns.bin => sp.bin} (100%) rename res/stage_info/S_MV000/00/{spawns.bin => sp.bin} (100%) delete mode 100644 res/tex/file.tex delete mode 100644 res/tex/folder_empty.tex delete mode 100644 res/tex/folder_full.tex create mode 100644 res/tex/hand.tex create mode 100644 res/tex/heart.tex create mode 100644 res/tex/wolf.tex diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 04a073e8..9bd539da 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -20,7 +20,9 @@ ], // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], + "runArgs": [ + "--network=host" + ], // Use 'postCreateCommand' to run commands after the container is created. // "postCreateCommand": "uname -a", diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..b6a0f6d2 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,42 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Attach", + "type": "cppdbg", + "request": "attach", + "MIMode": "gdb", + "miDebuggerServerAddress": "0.0.0.0:2159", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + }, + { + "type": "lldb", + "debugServer": 2159, + "request": "custom", + "name": "Custom launch", + "initCommands": [ + "target remote localhost:2159" + ], + "targetCreateCommands": [ + ], + "processCreateCommands": [ + // "settings set target.run-args value1 value2 value3", + // "process launch" + ] + } + ] +} \ No newline at end of file diff --git a/BUILDING.md b/BUILDING.md index b01953a3..af3adafd 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -14,7 +14,7 @@ git clone https://github.com/zsrtp/tpgz.git git submodule update --init --recursive ``` -3. Copy your Twilight Princess ISO into the root `tpgz` folder. You will need to rename the ISO based on which platform and region you're building for. +3. Copy your Twilight Princess ISO into the `isos` folder. You will need to rename the ISO based on which platform and region you're building for. | Game Version | ISO Name | |--------------|------------| @@ -33,29 +33,25 @@ git submodule update --init --recursive - This is used to add our compiled code into the ISO. - It is recommended that you add romhack.exe to your PATH. + - (For compiling the GameCube version, ensure you download the `-gc` version) -6. Set the **PLATFORM** and **REGION** environment variables to build your specific version of the game. - - Linux: - +6. Create a `build` directory and navigate to it ```bash - export PLATFORM="GCN" - export REGION="NTSCU" + mkdir build + cd build/ ``` - Windows (PowerShell): - - ```powershell - $env:PLATFORM = "GCN" - $env:REGION = "NTSCU" +7. Configure CMake from the `build` directory + ```bash + #Example: + cmake .. -D PLATFORM=GCN -D REGION=NTSCU ``` - Supported values for PLATFORM are `GCN` and `WII` - Supported values for REGION are `NTSCU`, `NTSCU_10`, `NTSCJ` and `PAL` - If you don't set these, the default values of `GCN` and `NTSCU` will be assumed when building. - -7. Run `make` in the root `tpgz` folder to compile the code. +8. Run `make` in the `build` directory to compile the code. 8. Run `romhack build --raw` to create a new ISO with our changes applied. diff --git a/CMakeLists.txt b/CMakeLists.txt index e56d324b..c24df3e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,10 @@ if(DEFINED PR_TEST) set(RUN_PR_TEST "-DPR_TEST=1") endif() +if(DEFINED DEBUG) + set(DEBUG "-DDEBUG=1") +endif() + # Start configuring the build directory message(STATUS "Configuring for ${PLATFORM}_${REGION}...") @@ -60,7 +64,7 @@ include(cmake/relmapper.cmake) include(cmake/fonts.cmake) project(TPGZ - VERSION 0.6.1 + VERSION 1.0.0 DESCRIPTION "Twilight Princess speedrunning practice and testing tool" HOMEPAGE_URL "tpgz.io" LANGUAGES C CXX ASM) @@ -70,7 +74,7 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) # Set compiler stuff include_directories(include external) -add_definitions(-D${PLATFORM}_${REGION} -D${PLATFORM}_PLATFORM -DGZ_VERSION=${CMAKE_PROJECT_VERSION} -D_PROJECT_NAME="${CMAKE_PROJECT_NAME}" -D_VERSION="${CMAKE_PROJECT_VERSION}" -D_VARIANT="public" -D_BUILDID="${CMAKE_PROJECT_VERSION}" ${RUN_PR_TEST}) +add_definitions(-D${PLATFORM}_${REGION} -D${PLATFORM}_PLATFORM -DGZ_VERSION=${CMAKE_PROJECT_VERSION} -D_PROJECT_NAME="${CMAKE_PROJECT_NAME}" -D_VERSION="${CMAKE_PROJECT_VERSION}" -D_VARIANT="public" -D_BUILDID="${CMAKE_PROJECT_VERSION}" ${DEBUG} ${RUN_PR_TEST}) add_compile_options(-fdiagnostics-color=always -fvisibility=hidden) include(cmake/tp_c.cmake) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dfb02b5d..c8de87a0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,6 +28,8 @@ Include the following in your request, with as much detail as possible: ## Development +We first recommend reading the [Dev Overview](./docs/DevOverview.md) to get an idea of how the project is setup. + Visit the [issue tracker](https://github.com/zsrtp/tpgz/issues) to find a list of open issues that need attention. Fork, then clone the repo: @@ -40,8 +42,15 @@ git clone https://github.com/your-username/tpgz.git ``` tpgz +├───.devcontainer // Docker container environment files ├───.github │ └───workflows // github action(s) used to test code compilation +├───bin // binaries used in the compilation process +│ ├───gcn // gcn specific binaries +│ └───wii // wii specific binaries +├───cmake // cmake build rule files +├───common // common files +├───docs // various documentation ├───external // external libraries and programs consumed by tpgz │ ├───fonts // small rust program to generate raw bytes and c code for utilizing true-type fonts in game │ │ ├───fonts // ttf files @@ -50,22 +59,34 @@ tpgz │ │ ├───include // header files for gcn_c │ │ └───src // source code for gcn_c │ ├───libtp_c // game bindings for twilight princess -│ | ├───.github -│ | │ └───workflows // github action(s) used to test code compilation │ | ├───include // header files for libtp_c │ | └───src // source code for libtp_c | └───misc // misc tools/scripts -├───include // header files for tpgz -│ ├───menus // menu header files -| └───utils // utility header files +├───isos // original game isos +├───modules // tpgz module source code +│ ├───boot // permanently loaded module source code +│ │ ├───include // module header files +│ │ └───src // module source code +│ ├───features // feature-specific modules source code +| | └───* // feature module +│ │ │ ├───include // feature header files +│ │ │ └───src // feature source code +│ ├───init // tpgz initialization source code +│ │ ├───include // initialization header files +│ │ └───src // initialization source code +│ └───menus // menu modules source code +| └───* // menu module +│ ├───include // menu header files +│ └───src // menu source code ├───res // external resources to be consumed +│ ├───bin // region specific binary data │ ├───fonts // raw font data +│ ├───icons // icon resources │ ├───save_files // practice file metadata and raw quest log bytes to be injected at compile time +│ ├───save_files_wii // wii specific practice file metadata | ├───stage_info // stage info data for warping menu -| └───tex // custom textures -├───src // source code for tpgz -| ├───menus // menu source code -| └───utils // utility source code +| └───tex // custom textures processed for tpgz +└───src // stub for compilation purposes ``` ### Building @@ -74,7 +95,7 @@ See [BUILDING.md](./BUILDING.md). ### Linting -Please format your files using the .clang-format file. Submodules should **not** be included when formatting, as these will have their own clang-format files. +Please format your files using the .clang-format file Example clang-format usage (Ubuntu): diff --git a/FEATURES.md b/FEATURES.md new file mode 100644 index 00000000..d24629ee --- /dev/null +++ b/FEATURES.md @@ -0,0 +1,193 @@ +# tpgz Feature List + +--- + +#### Cheats +- **Infinite Air** +- **Infinite Arrows** +- **Infinite Bombs** +- **Infinite Hearts** +- **Infinite Oil** +- **Infinite Rupees** +- **Infinite Slingshot Seeds** +- **Invincibility**: Intangibility +- **Invincible Enemies*** + - (May not work on every type of enemy) +- **Moon Jump** +- **Disable Walls**: Disables Link's wall collision +- **Super Clawshot**: Super fast, stick to anything +- **Unrestricted Items** +- **Transform Anywhere**: Disable Transform blocks + +###### Wii-specific +- **Gale LJA**: Unpatches Boomerang LJA + +--- + +#### Flags +##### - General Flags +- **Boss Flag**: Sets Early Boss Flag to max value +- **Rupee Flags**: Disables Rupee collection cutscenes +- **Epona Stolen**: Story flag for Epona being stolen +- **Epona Tamed**: Story flag for Epona being re-tamed +- **Map Warping**: Unlocks Map Warping ability +- **Midna Charge**: Unlocks Midna Charge ability +- **Midna Healed**: Story flag for Midna being healed by Zelda +- **Midna on back**: Midna rides on Link's back without Twilight +- **Midna Available**: Unlocks ability to call Midna with Z button +- **Wolf Sense**: Unlocks ability to use Wolf Senses + +##### - Dungeon Flags +- **Small Key Count** +- **Have Map** +- **Have Compass** +- **Have Boss Key** +- **Miniboss Defeated** +- **Boss Defeated** +- **Clear flags**: Resets stage flags for specified Dungeon + +##### - Portal Flags +- **Region Unlocked**: Unlocks specified Map Region +- **Portal Flags**: Unlocks specified portal + +##### - Flag Records +- **Stage**: Displays all Stage flags for the current Stage +- **Event**: Displays all Permanent Event flags +- **Minigame**: Displays all Minigame related flags +- **Dungeon**: Displays all temporary dungeon flags + +##### - Flag Log +- **Activate Flag Log*** + - (Experimental, may not work for all situations) + +--- + +#### Inventory +##### - Item Wheel +- **Item Slots**: Change the Item in the specified Slot + +##### - Pause Menu +- **Swords**: Modify Sword collection +- **Shields**: Modify Shield collection +- **Tunics**: Modify Tunic collection +- **Capacity**: Modify Bomb/Arrow/Wallet max capacity +- **Hidden Skills**: Unlock Hidden Skill abilities + +##### - Amounts +- **Health**: Change current health amount (by heart-quarters) +- **Hearts**: Change max heart count +- **Arrows**: Change current arrow count +- **Bomb Bags**: Change current bomb count within each Bomb Bag +- **Seeds**: Change slingshot seed count +- **Heart Pieces**: Change collected Heart Piece count +- **Poes**: Change collect Poe Soul amount +- **Rupees**: Change current Rupee amount + +--- + +#### Memory +- **Watches**: Display memory watches on screen +- **Memory Editor**: View and edit game memory +- **Mem Files**: Save and load "Memory Files", similar to a save state + +--- + +#### Practice +- **Any%**: Practice saves for Any% (Gorge No ZA- Early Lake Hylia route) +- **Any% BiTE**: Practice saves for Any% (BiTE No ZA route) +- **100%**: Practice saves for 100% +- **All Dungeons**: Practice saves for All Dungeons +- **No Save-Quit**: Practice saves for No Save-Quit +- **Glitchless**: Practice saves for Glitchless + +###### Wii-specific +- **Any% BiTE**: Practice saves for Any% (BiTE route) + +--- + +#### Scene +- **Disable BGM**: Disables Background Music +- **Disable SFX**: Disables Sound Effects +- **Freeze Actors**: Stops all actors from updating +- **Freeze Camera**: Locks the Camera position in place +- **Hide Actors**: Stops drawing all actors except Link +- **Hide HUD**: Hides the main UI elements +- **Freeze Time**: Freezes the Time of Day at its current value +- **Time (Hours)**: The current in-game Hour +- **Time (Minutes)**: The current in-game Minutes + +##### - Actor Spawner +- **Actor ID**: The ID of actor to be spawned +- **Actor Parameters**: The parameters of the actor to be spawned +- **Actor Subtype**: The subtype of the actor to be spawned +- **Spawn**: Spawns the specified actor + +##### - Actor List +- **Displays information about the specified actor in the actor queue** +- **Freeze**: Stops the specified actor from updating +- **Delete**: Deletes the specified actor + +##### - Collision Viewer +- **View Polygon Collision**: Draws BG Collision Geometry in-game +- **View Attack Colliders**: Draws *Attack*-type colliders in-game +- **View Target Colliders**: Draws *Target*-type colliders in-game +- **View Push Colliders**: Draws *Push*-type colliders in-game +- **Opacity**: Change the opacity of drawn Geometry + +##### - Shape Viewer +- **View Load Zones**: Draws Load Zone (`daScex_c`) triggers +- **View Midna Stops**: Draws Midna-stop (`daMidnaStop_c`) triggers +- **View Switch Areas**: Draws Switch (`daSwc00_c`) triggers +- **View Event Areas**: Draws Event (`daTag_EvtArea_c` / `daTag_Evt_c`) triggers +- **View Twilight Gates**: Draws Twilight Gate (`daTagTWGate_c`) triggers +- **View Paths**: Draws current Stage Path (`dPath`) data +- **View Plumm Triggers**: Draws Plumm (`d_a_tag_myna2`) triggers +- **Opacity**: Change the opacity of drawn Geometry + +--- + +#### Settings +- **Area Reload Behavior**: Changes the behavior of the `Area Reload` tool between reloading last practice save or reloading current area +- **Cursor Color**: Changes the color of the tpgz menu cursor +- **Font**: Changes the font used for the tpgz menu +- **Drop Shadows**: Toggle drop shadows for tpgz text +- **Swap Equips**: Swaps the X/Y button equips when a practice save is loaded +- **Save Card**: Saves settings and selected cheats/tools to the memory card +- **Load Card**: Loads settings and selected cheats/tools from the memory card +- **Delete Card**: Deletes settings file from the memory card +- **Sprite Positions**: Allows you to change on-screen positions of various tpgz UI elements + +--- + +#### Tools +- **Area Reload**: Reloads the last file or current area when a combo is inputted +- **Fast Bonk Recovery**: Speeds up Bonk animation drastically +- **Fast Movement**: Speeds up movement speed drastically +- **Gorge Checker**: Warps you to and displays frame info for Gorge Void +- **Coro TD Checker**: Displays frame info for Coro Text Displacement +- **Input Viewer**: Displays a input viewer on-screen +- **Link Debug Info**: Displays Link position, angle, and speed information +- **No Sinking in Sand**: Disables sinking in sand +- **Roll Checker**: Displays frame info for getting max speed rolls +- **Teleport**: Input a combo to save or load a custom position +- **Turbo mode**: Makes held inputs act like a turbo controller +- **Timer**: Displays a standard timer +- **Load Timer**: Displays a timer that increases during loads +- **IGT Timer**: Displays a timer that removes load times +- **Free Cam**: Move the Camera around freely +- **Move Link**: Move Link around freely like No Clip +- **Link Tunic Color**: Change the tunic color to custom colors + +###### Wii-specific +- **BiT checker**: Displays frame info for getting Home button Back in Time +--- + +#### Warping +- **Type**: Sets the category of Stages to warp to +- **Stage**: The specified Stage to warp to +- **Room**: The specified Room to warp to +- **Spawn**: The specified Spawn to warp to +- **Layer**: The specified Layer to warp to +- **Warp**: Warps to the specified location +- **Save**: Sets the savefile spawn location to the specified warp + - (Must be in the save menu to set properly) \ No newline at end of file diff --git a/README.md b/README.md index 19b0516e..967829a0 100644 --- a/README.md +++ b/README.md @@ -1,146 +1,51 @@ # tpgz -Twilight Princess ROM hack to practice speedrunning. +A *Twilight Princess* ROM hack for speedrun practice and research. -[tpgz.io](https://tpgz.io) - Patch your ISO using our web patcher -(For patching offline, follow this [guide](./docs/CreatingAnIso.md)) +--- + +## Download +### Web +Patch your TP (GameCube) rom on the web using our website [tpgz.io](https://tpgz.io). +- This uses a lot of memory, so it requires a decent computer. +- The Wii version is currently not supported for web patching. Please follow the offline patching guide. + +### Offline +To patch your rom offline, please follow our [guide](./docs/CreatingAnIso.md). -⚠️ tpgz is still in early development.
If you have questions or need help, ask in the [#tools-dev](https://discord.gg/m2vmcyT) channel of the [TP Speedrunning Discord](https://discord.gg/tp). -## Features - -Use L+R+dpadDown to open the main menu which contains the following options: - -``` -cheats menu: -- infinite air // Gives Link infinite air underwater -- infinite arrows // Gives Link 99 arrows -- infinite bombs // Gives Link 99 bombs in all bags -- infinite hearts // Link will always have full hearts -- infinite oil // Gives Link infinite lantern oil -- infinite rupees // Link will always have 1000 rupees -- infinite slingshot // Gives Link 99 slingshot pellets -- invincible // Makes Link invincible (no hurtbox, but can still take fall damage and drown) -- invincible enemies // Makes some enemies invincible (infinite health) -- moon jump // Hold R+A to moon jump -- disable walls // Can walk through most objects/walls -- super clawshot // Clawshot is long, fast, and can grab most things -- unrestricted items // Link can use any item anywhere -- transform anywhere // Link can transform into/from wolf anywhere -- super spinner (TBD) // Spinner is very fast and can hover (not implemented yet) -- gale LJA (Wii only) // Link can yeet everywhere - -flags menu: -- general flags // Toggle various general flags -- dungeon flags // Toggle various dungeon flags -- portal flags // Toggle warp portal flags -- temp flags // Toggle local temporary flags -- flag log // Toggle logging flag changes* - -general flags menu: -- boss flag // Set the boss flag value. Press A to lock the value -- epona stolen // Toggle flag for Epona being stolen -- epona tamed // Toggle flag for Epona being tamed -- map warping // Toggle flag for having map warping -- midna charge // Toggle flag for Midna charge -- midna healthy // Toggle flag for Midna being healthy/sick -- midna on back // Toggle flag for Midna appearing on Wolf Link's back -- midna on z // Toggle flag for being able to use Midna -- transform/warp // Toggle flag for transforming/warping -- wolf sense // Toggle flag for having wolf sense - -dungeon flags menu: -- have map // Toggle dungeon map for current dungeon -- have compass // Toggle compass for current dungeon -- have boss key // Toggle boss key for current dungeon -- have small keys // Toggle small keys for current dungeon -- miniboss dead // Toggle miniboss defeated state -- boss dead // Toggle boss defeated state -- clear flags // Clear all dungeon flags - -inventory menu: -- item wheel // Set the 24 item wheel slots to any item -- pause menu // Modify the pause menu collection -- amounts menu // Modify ammo / collectible amounts - -memory menu: -- watches // Add memory watches to the screen -- editor // Browse and edit the memory -- mem files // Basic custom save files. - -practice menu: -- Load practice files* (supports popular Any%, 100%, and All Dungeons locations) - -scene menu: -- disable bg music* // Disables background and enemy music -- disable sfx // Disables sound effects (item, weather, etc.) -- freeze actors // Freezes actors -- freeze camera // Locks the camera in place -- hide actors // Hides actors -- hide hud // Hides the heads-up display -- time (hrs) // The current in-game hour -- time (mins) // The current in-game minutes - -settings menu: -- area reload behavior // load area = Reload last area; load file = Reload last file -- cursor color // Changes the color of the cursor in TPGZ's menus (green, blue, red, orange, yellow, purple) -- font // Changes TPGZ menu font -- drop shadows // Adds shadows to all font letters -- menu position // Changes the position of various menus and tools from TPGZ -- save card // Save settings to memory card -- load card // Load settings from memory card -- delete card // Delete settings from memory card - -tools menu: -- area reload // Use L+R+Start+A to reload current area -- fast bonk recovery // Reduces bonk animation significantly -- fast movement // Link's movement is much faster -- gorge checker // Use L+Z to warp to Kakariko Gorge -- bit checker (Wii only) // Show when to press Home for BiT -- coro td checker // Show frame info when doing coro td -- input viewer // Show current inputs -- link debug info // Show Link's position, angle, and speed -- no sinking in sand // Link won't sink in sand -- roll checker // Frame counter for chaining rolls -- teleport // dpadUp to set, dpadDown to load -- turbo mode // Hold an input to continously trigger -- timer // Timer: Z+A to start/stop, Z+B to reset -- load timer // Loading timer: Z+B to reset -- igt timer // In-game Time frame timer: Z+A to start/stop, Z+B to reset -- free cam // Z+A+B to activate, Stick/L/R to move, C-stick to look, Z to speed-up -- move link* // L+R+Y to activate, Stick to move, C-stick to move/change angle, Z to speed-up -- link tunic color: // Changes Link's tunic color (green, blue, red, orange, yellow, white, or cycle) - -warping menu: -- type // Change stage sort type -- stage // Select stage to load -- room // Select room of stage to load -- spawn // Select Link spawnpoint ID -- layer // Select stage layer (leave as default unless necessary) -- warp // Load selected stage info -- save // Set savefile location to selected location (need to be in pause menu) -``` - -### Known Issues - -``` -- using move link tool, link is stuck to the ground unless entering a falling state -- some flags not logged by flag logger yet -``` - -### Planned Features - -``` -- frame advance -- collision viewer -- lag counter -``` +--- + +## Usage and Features + +To open the tpgz main menu, press `L + R + D-pad Down` (`Z + C + Minus` on Wii). + +#### General Controls +- Move the cursor with the `D-pad` +- Select an item with the `A` button +- Un-Select / Return with the `B` button + +### Features +tpgz features many useful tools for speedrun practice and reverse engineering such as: +- Quick-Access practice savefiles +- A collision / trigger viewer +- A warp menu to quickly warp anywhere in the game +- Cheats such as Moon Jump, infinite hearts, infinite enemy health, and more +- Tools such as Free Cam, No Clip, Frame Advance, a built in input viewer, and more +- A full inventory manager +- Memory watches and a memory editor +- and much more! + +#### See the full list of features [here](./FEATURES.md)! +--- ## Contributing -We'd love for you to help out on `tpgz`! See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to get started. +Interested in helping contribute? See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to get started. + +--- ## Building -Tired of waiting for the next release? See [BUILDING.md](./BUILDING.md) to learn how to create local builds. +See [BUILDING.md](./BUILDING.md) to learn how to build tpgz from source. diff --git a/RomHack.toml.in b/RomHack.toml.in index 92c93bad..b9aef676 100644 --- a/RomHack.toml.in +++ b/RomHack.toml.in @@ -49,6 +49,9 @@ libs = ["libtpgz.a"] "tpgz/save_files/glitchless.bin" = "../res/save_files/glitchless.bin" "tpgz/save_files/glitchless" = "../res/save_files/glitchless" +# actor info +"tpgz/procs.bin" = "../res/proc_info/procs.bin" + # warp info "tpgz/stage_info" = "../res/stage_info" diff --git a/common/rels/src/cxx.cpp b/common/rels/src/cxx.cpp index 3fbf735a..edffbc33 100644 --- a/common/rels/src/cxx.cpp +++ b/common/rels/src/cxx.cpp @@ -12,6 +12,7 @@ #include "libtp_c/include/dolphin/os/OSCache.h" #include "libtp_c/include/m_Do/m_Do_ext.h" #include "libtp_c/include/JSystem/JKernel/JKRHeap.h" +#include "libtp_c/include/defines.h" #ifdef WII_PLATFORM #include "libtp_c/include/dynamic_link.h" @@ -39,7 +40,7 @@ void* getHeapPtr(int32_t id) { }; // Make sure the id is valid - constexpr uint32_t heapPtrArraySize = sizeof(heapPtrArray) / sizeof(heapPtrArray[0]); + constexpr uint32_t heapPtrArraySize = ARRAY_COUNT(heapPtrArray); if ((id < 0) || (static_cast(id) >= heapPtrArraySize)) { // The id is invalid, so use the archive heap by default id = HEAP_ARCHIVE; @@ -110,14 +111,10 @@ void operator delete[](void* ptr) { return __dl_JKRHeap(ptr); } -void operator delete(void* ptr, std::size_t size) { - (void)size; - +void operator delete(void* ptr, [[maybe_unused]] std::size_t size) { return __dl_JKRHeap(ptr); } -void operator delete[](void* ptr, std::size_t size) { - (void)size; - +void operator delete[](void* ptr, [[maybe_unused]] std::size_t size) { return __dl_JKRHeap(ptr); } diff --git a/docs/CreatingAnIso.md b/docs/CreatingAnIso.md index 31942f37..43964e16 100644 --- a/docs/CreatingAnIso.md +++ b/docs/CreatingAnIso.md @@ -1,4 +1,4 @@ -# Creating an ISO +# Creating a tpgz ISO _These instructions are for Windows. Mac and Linux please see [BUILDING.md](../BUILDING.md)._ @@ -6,7 +6,7 @@ Mac and Linux please see [BUILDING.md](../BUILDING.md)._ ## Quick Overview tpgz takes a Twilight Princess ISO and generates a new ISO with features that help you practice. -Play the new ISO on [Dolphin](https://dolphin-emu.org/) or a homebrewed Wii. +You can play the new ISO on [Dolphin](https://dolphin-emu.org/) or a homebrewed GameCube/Wii. ``` + => @@ -19,20 +19,14 @@ You provide Provided Created The instructions are intentionally detailed to prevent confusion. If you are having trouble, please check [Troubleshooting](#troubleshooting). -**You will need a Twilight Princess ISO.** -_(Only supports Gamecube version for now.)_ +**You will need your own Twilight Princess ISO** -1. Download the latest release [here](https://github.com/zsrtp/tpgz/releases). - _(Feel free to follow the release page instructions instead of these.)_ +1. Download the latest tpgz patch release for your version and region [here](https://github.com/zsrtp/tpgz/releases). -2. Unzip the downloaded file to create a new folder, then open that folder.
- You should see something _similar_ to the following: +2. Download the latest romhack compiler [here](https://github.com/zsrtp/romhack-compiler/releases). + - If you're patching a GameCube ISO, download a version that ends with `-gc`. - - romhack.exe - - tpgz.patch - -3. Put a copy of your Twilight Princess ISO (GCN) in this folder. - The ISO's filename is not important.
+3. Place the tpgz patch file, the romhack compiler and a copy of your Twilight Princess ISO together in a folder. _Example:_ - romhack.exe @@ -84,22 +78,24 @@ _(Only supports Gamecube version for now.)_ - This will generate the new ISO. It may take a few minutes to complete. -8. Load the new ISO in - [Dolphin emulator](https://dolphin-emu.org/) or a Wii using a homebrew loader such as [Nintendont](https://github.com/FIX94/Nintendont). - -9. Use L+R+dpadDown to open the features menu in game. +8. Load the new ISO in [Dolphin emulator](https://dolphin-emu.org/) or a GameCube/Wii using a homebrew loader such as [Nintendont](https://github.com/FIX94/Nintendont). ## Troubleshooting ### How do I know my ISO is correct? -You need a **Gamecube ISO**. +Make sure you have a clean ISO dump. Correct MD5 hashes:
NTSC-U GCN: **41deff9b1fd2831f48fbfa2dd1054e4d** NTSC-J GCN: **b130d78bb78cd63b501ddff210fde498** PAL GCN: **798abb94d649f7d117514578b2abfae1** +NTSC-U WII (1.0) **25003a3e3666edf79c99080be9083b34** +NTSC-U WII (1.2) **70946e09da8f0bb218bb3b3542953d63** +JP WII: **4979793d525198ef13e19ef369311743** +PAL WII: **c46c133885383f96e7515c5cefd152d2** + Determine the MD5 hash of your ISO with the `md5sum` command. If your command returns anything other than the above value, you either have the wrong ISO or your ISO was somehow modified. diff --git a/docs/DevOverview.md b/docs/DevOverview.md index c804c648..cc3ad5e2 100644 --- a/docs/DevOverview.md +++ b/docs/DevOverview.md @@ -52,6 +52,7 @@ The repository structure is separated like so: - `/res/fonts/`: The fonts used to display text in **TPGZ**. They were made from TrueType fonts converted into a custom font format using the script found at `external/misc/font2fnt.py`. - `/res/icons/`: The original pictures that were used to generate the textures in `res/tex`. - `/res/map/`: The files that contain the mapping between the symbols name and their address in the game. They are used in the compilation pipeline to link the modules against the game. +- `/res/proc_info/`: Metadata containing information on friendly name mappings for Proc IDs. Used by the actor list menu. - `/res/save_files/`: The files that contains the data to load into the questlog of the game, as well as some metadata on how to load them. - `/res/save_files_wii/`: Wii specific save files. Although GC's questlog data and Wii's are intercompatible, Wii any% saves were made using a different route, requiring a different set of saves. - `/res/stage_info/`: Metadata containing the information on where it is possible to warp. @@ -212,7 +213,7 @@ Here, we list how some of the main components of **TPGZ** work. - Hooking into the game's code. - Holding global data that is access by all the sub modules. -- Providing [Lsiteners](#Listeners) for sub modules to hook into. +- Providing [Listeners](#Listeners) for sub modules to hook into. - Handling REL modules loading. > Currently, the main module also contains the majority of the code for the features. But in the long term, all the features that are not required to be in the main module will be extracted into sub modules. diff --git a/external/libtp_c/include/JSystem/J2DGraph/J2DPane.h b/external/libtp_c/include/JSystem/J2DGraph/J2DPane.h index 87907ff2..f9dd8261 100644 --- a/external/libtp_c/include/JSystem/J2DGraph/J2DPane.h +++ b/external/libtp_c/include/JSystem/J2DGraph/J2DPane.h @@ -5,7 +5,6 @@ #include "../JSupport/JSUList.h" #include "../JGeometry.h" #include "../../dolphin/mtx/mtx.h" -#include "../../addrs.h" struct J2DAnmTransform {}; diff --git a/external/libtp_c/include/JSystem/J3DGraphBase/J3DPacket.h b/external/libtp_c/include/JSystem/J3DGraphBase/J3DPacket.h index 0bc18eb7..35f8eae9 100644 --- a/external/libtp_c/include/JSystem/J3DGraphBase/J3DPacket.h +++ b/external/libtp_c/include/JSystem/J3DGraphBase/J3DPacket.h @@ -29,8 +29,15 @@ class J3DDrawBuffer { J3DPacket* mpCallBackPacket; }; -typedef void (*J3DDrawBuffer__entryImm_t)(J3DDrawBuffer*, J3DPacket* packet, u16); -#define J3DDrawBuffer__entryImm ((J3DDrawBuffer__entryImm_t)J3DDrawBuffer__entryImm_addr) +LIBTP_DEFINE_FUNC(entryImm__13J3DDrawBufferFP9J3DPacketUs, J3DDrawBuffer__entryImm_J3DPacket____unsigned_short_, + bool, J3DDrawBuffer__entryImm, (J3DDrawBuffer*, J3DPacket* packet, u16)) +#ifndef WII_PLATFORM +#define J3DPacket__entry entry__9J3DPacketFP13J3DDrawBuffer +#else +#define J3DPacket__entry J3DPacket__entry_J3DDrawBuffer___ +#endif + +extern "C" int J3DPacket__entry(J3DPacket*, J3DDrawBuffer*); class J3DDisplayListObj { public: @@ -39,23 +46,40 @@ class J3DDisplayListObj { u32 mCapacity; }; +struct J3DPacket__vtable_t { + void* rtti; + void* padding; + void* entry; + void* draw; + void* dtor; +}; + +#ifndef WII_PLATFORM +#define J3DPacket__vtable __vt__9J3DPacket +#else +#define J3DPacket__vtable J3DPacket____vt +#endif + +extern "C" J3DPacket__vtable_t J3DPacket__vtable; + class J3DPacket { public: J3DPacket() { - mpNextSibling = NULL; + vtable = &J3DPacket__vtable; + mpNextPacket = NULL; mpFirstChild = NULL; mpUserData = NULL; } void clear() { - mpNextSibling = NULL; + mpNextPacket = NULL; mpFirstChild = NULL; } - J3DPacket* getNextPacket() const { return mpNextSibling; } + J3DPacket* getNextPacket() const { return mpNextPacket; } - /* 0x00 */ void* vtable; - /* 0x04 */ J3DPacket* mpNextSibling; + /* 0x00 */ J3DPacket__vtable_t* vtable; + /* 0x04 */ J3DPacket* mpNextPacket; /* 0x08 */ J3DPacket* mpFirstChild; /* 0x0C */ void* mpUserData; }; diff --git a/external/libtp_c/include/JSystem/J3DGraphBase/J3DStruct.h b/external/libtp_c/include/JSystem/J3DGraphBase/J3DStruct.h index 0fdc29df..29fedacd 100644 --- a/external/libtp_c/include/JSystem/J3DGraphBase/J3DStruct.h +++ b/external/libtp_c/include/JSystem/J3DGraphBase/J3DStruct.h @@ -1,7 +1,7 @@ #ifndef J3DSTRUCT_H #define J3DSTRUCT_H -#include "../../dolphin/gx/GXTexture.h" +#include "../../dolphin/gx/gx.h" #include "../../dolphin/mtx/vec.h" class J3DLightInfo { diff --git a/external/libtp_c/include/JSystem/J3DGraphBase/J3DSys.h b/external/libtp_c/include/JSystem/J3DGraphBase/J3DSys.h index fcc14a17..7466519c 100644 --- a/external/libtp_c/include/JSystem/J3DGraphBase/J3DSys.h +++ b/external/libtp_c/include/JSystem/J3DGraphBase/J3DSys.h @@ -3,8 +3,7 @@ #include "../../dolphin/mtx/mtx.h" #include "../../dolphin/mtx/vec.h" -#include "../../dolphin/gx/GXTexture.h" -#include "libtp_c/include/addrs.h" +#include "../../dolphin/gx/gx.h" #include "J3DPacket.h" #include "../../dolphin/types.h" @@ -75,6 +74,14 @@ struct J3DSys { J3DDrawBuffer* getDrawBuffer(int type) { return mDrawBuffer[type]; } }; -#define j3dSys (*(J3DSys*)(j3dSys_addr)) +extern "C" J3DSys j3dSys; + +LIBTP_DEFINE_FUNC(reinitGX__6J3DSysFv, J3DSys__reinitGX_void_, + void, J3DSys__reinitGX, (J3DSys*)) + +extern "C" void* sOldVcdVatCmd__8J3DShape; +#define sOldVcdVatCmd sOldVcdVatCmd__8J3DShape + +inline void resetVcdVatCache() { sOldVcdVatCmd = NULL; } #endif /* J3DSYS_H */ diff --git a/external/libtp_c/include/JSystem/JKernel/JKRArchive.h b/external/libtp_c/include/JSystem/JKernel/JKRArchive.h index 6d682c87..2b5e6609 100644 --- a/external/libtp_c/include/JSystem/JKernel/JKRArchive.h +++ b/external/libtp_c/include/JSystem/JKernel/JKRArchive.h @@ -1,7 +1,6 @@ #ifndef JKRARCHIVE_H_ #define JKRARCHIVE_H_ -#include "../../addrs.h" #include "JKRFileLoader.h" #include "../../dolphin/types.h" diff --git a/external/libtp_c/include/JSystem/JKernel/JKRHeap.h b/external/libtp_c/include/JSystem/JKernel/JKRHeap.h index 977aa879..7092248a 100644 --- a/external/libtp_c/include/JSystem/JKernel/JKRHeap.h +++ b/external/libtp_c/include/JSystem/JKernel/JKRHeap.h @@ -4,7 +4,6 @@ #include "../../dolphin/os/OS.h" #include "../JSupport/JSUList.h" #include "JKRDisposer.h" -#include "../../addrs.h" class JKRHeap; typedef void (*JKRErrorHandler)(void*, u32, int); diff --git a/external/libtp_c/include/JSystem/JMATrigonometric.h b/external/libtp_c/include/JSystem/JMATrigonometric.h new file mode 100644 index 00000000..a6cf2ca1 --- /dev/null +++ b/external/libtp_c/include/JSystem/JMATrigonometric.h @@ -0,0 +1,69 @@ +#include "../dolphin/types.h" + +namespace std { +template +struct pair { + T1 first; + T2 second; + + pair() { + first = T1(); + second = T2(); + } +}; +} // namespace std + +template +struct TSinCosTable { + std::pair table[1 << N]; + + T sinShort(s16 v) const { return table[(u16)v >> (16U - N)].first; } + T cosShort(s16 v) const { return table[(u16)v >> (16U - N)].second; } + + // inline T sinLap(T v) { + // if (v < (T)0.0) { + // return -table[(u16)(-(T)(1 << N) * v) & ((1 << N) - 1)].first; + // } + // return table[(u16)((T)(1 << N) * v) & ((1 << N) - 1)].first; + // } + + // inline T sinDegree(T degree) { + // if (degree < (T)0.0) { + // return -table[(u16)(((T)(1 << N) / 360.0) * degree) & ((1 << N) - 1)].first; + // } + // return table[(u16)(((T)(1 << N) / 360.0) * degree) & ((1 << N) - 1)].first; + // } + + // inline T cosDegree(T degree) { + // if (degree < (T)0.0) { + // degree = -degree; + // } + // return table[(u16)(((T)(1 << N) / 360.0) * degree) & ((1 << N) - 1)].second; + // } + + // inline T sinRadian(T radian) { + // if (radian < (T)0.0) { + // return -table[(u16)(-(T)(1 << N) / TAngleConstant_::RADIAN_DEG360() * radian) & ((1 << N) - 1)].first; + // } + // return table[(u16)((T)(1 << N) / TAngleConstant_::RADIAN_DEG360() * radian) & ((1 << N) - 1)].first; + // } +}; + +#define tp_sincosTable_addr 0x80439A20 + +#define tp_sincosTable (*(TSinCosTable<13, f32>*)(tp_sincosTable_addr)) + +inline f32 JMASCosShort(s16 v) { + return tp_sincosTable.cosShort(v); +} +inline f32 JMASinShort(s16 v) { + return tp_sincosTable.sinShort(v); +} + +inline f32 JMASCos(s16 v) { + return JMASCosShort(v); +} +inline f32 JMASSin(s16 v) { + return JMASinShort(v); +} + diff --git a/external/libtp_c/include/JSystem/JMath.h b/external/libtp_c/include/JSystem/JMath.h new file mode 100644 index 00000000..49e0a9d6 --- /dev/null +++ b/external/libtp_c/include/JSystem/JMath.h @@ -0,0 +1,8 @@ +#ifndef JMATH_H +#define JMATH_H + +#include "../dolphin/types.h" + +LIBTP_DEFINE_FUNC(JMAFastSqrt__Ff, JMAFastSqrt_float_, f32, JMAFastSqrt, (f32)) + +#endif /* JUTILITY_H */ \ No newline at end of file diff --git a/external/libtp_c/include/JSystem/JParticle/JPAParticle.h b/external/libtp_c/include/JSystem/JParticle/JPAParticle.h index 3fad8af1..0219253a 100644 --- a/external/libtp_c/include/JSystem/JParticle/JPAParticle.h +++ b/external/libtp_c/include/JSystem/JParticle/JPAParticle.h @@ -2,9 +2,9 @@ #define JPAPARTICLE_H #include "../../dolphin/types.h" +#include "../../dolphin/gx/gx.h" class JPABaseParticle; -struct _GXTexMapID {}; struct JPABaseEmitter {}; diff --git a/external/libtp_c/include/JSystem/JUtility.h b/external/libtp_c/include/JSystem/JUtility.h index cbd70a50..2db56aff 100644 --- a/external/libtp_c/include/JSystem/JUtility.h +++ b/external/libtp_c/include/JSystem/JUtility.h @@ -1,7 +1,7 @@ #ifndef JUTILITY_H #define JUTILITY_H -#include "../dolphin/gx/GXTexture.h" +#include "../dolphin/gx/gx.h" namespace JUtility { diff --git a/external/libtp_c/include/JSystem/JUtility/JUTGamePad.h b/external/libtp_c/include/JSystem/JUtility/JUTGamePad.h index 5831c071..c0dbfdda 100644 --- a/external/libtp_c/include/JSystem/JUtility/JUTGamePad.h +++ b/external/libtp_c/include/JSystem/JUtility/JUTGamePad.h @@ -4,7 +4,6 @@ #include "../../dolphin/types.h" #include "../../dolphin/mtx/vec.h" #include "../../dolphin/pad/pad.h" -#include "../../addrs.h" #include "../../defines.h" #include "../JKernel/JKRDisposer.h" #include "../../SSystem/SComponent/c_API_controller_pad.h" @@ -13,7 +12,7 @@ typedef void (*callbackFn)(int, void*); #ifdef GCN_PLATFORM namespace CButton { -enum { +enum : uint16_t { DPAD_LEFT = 0x0001, DPAD_RIGHT = 0x0002, DPAD_DOWN = 0x0004, diff --git a/external/libtp_c/include/SSystem/SComponent/c_bg_s_chk.h b/external/libtp_c/include/SSystem/SComponent/c_bg_s_chk.h index fee319de..1b0884d1 100644 --- a/external/libtp_c/include/SSystem/SComponent/c_bg_s_chk.h +++ b/external/libtp_c/include/SSystem/SComponent/c_bg_s_chk.h @@ -3,13 +3,27 @@ #include "../../dolphin/types.h" +class cBgS_GrpPassChk { +public: + void* vtable; +}; + +class cBgS_PolyPassChk; + class cBgS_Chk { public: - /* 0x0 */ u32 mPolyPassChk; - /* 0x4 */ u32 mGrpPassChk; - /* 0x8 */ u32 mActorPid; - /* 0xC */ u8 unk_0x0C; + /* 0x00 */ cBgS_PolyPassChk* mPolyPassChk; + /* 0x04 */ cBgS_GrpPassChk* mGrpPassChk; + /* 0x08 */ u32 mActorPid; + /* 0x0C */ u8 unk_0x0C; /* 0x10 */ void* vtable; + + void setActorPid(u32 pid) { mActorPid = pid; } + u32 GetActorPid() const { return mActorPid; } + void SetPolyPassChk(cBgS_PolyPassChk* p_chk) { mPolyPassChk = p_chk; } + void SetGrpPassChk(cBgS_GrpPassChk* p_chk) { mGrpPassChk = p_chk; } }; +static_assert(sizeof(cBgS_Chk) == 0x14); + #endif /* C_BG_S_CHK_H */ diff --git a/external/libtp_c/include/SSystem/SComponent/c_cc_d.h b/external/libtp_c/include/SSystem/SComponent/c_cc_d.h index 8122079a..f7cf18f7 100644 --- a/external/libtp_c/include/SSystem/SComponent/c_cc_d.h +++ b/external/libtp_c/include/SSystem/SComponent/c_cc_d.h @@ -49,16 +49,22 @@ class cCcD_ShapeAttr { /* 0x1C */ void* vtable; }; -class cCcD_CpsAttr : public cCcD_ShapeAttr, public cM3dGCps { +class cCcD_CpsAttr { public: + cCcD_ShapeAttr shape_base; + cM3dGCps cps; }; -class cCcD_SphAttr : public cCcD_ShapeAttr, public cM3dGSph { +class cCcD_SphAttr { public: + cCcD_ShapeAttr shape_base; + cM3dGSph sph; }; // Size = 0x30 -class cCcD_CylAttr : public cCcD_ShapeAttr, public cM3dGCyl { +class cCcD_CylAttr { public: + cCcD_ShapeAttr shape_base; + cM3dGCyl cyl; }; // Size = 0x34 class cCcD_TriAttr {}; @@ -200,12 +206,27 @@ class cCcD_ObjCo : public cCcD_ObjCommonBase { static_assert(sizeof(cCcD_ObjCo) == 0x10); +typedef void (*cCcD_DrawFn)(void*, const GXColor&); +struct cCcD_GObjInf__vtbl_t { + /* 0x00 */ void* RTTI; + /* 0x04 */ void* pad; + /* 0x08 */ void* dtor; + /* 0x0C */ void* GetGObjInf_const; + /* 0x10 */ void* GetGObjInf; + /* 0x14 */ void* GetShapeAttr_const; + /* 0x18 */ void* GetShapeAttr; + /* 0x1C */ cCcD_DrawFn Draw; + /* 0x20 */ void* ClrAtHit; + /* 0x24 */ void* ClrTgHit; + /* 0x28 */ void* ClrCoHit; +}; + class cCcD_ObjHitInf { public: /* 0x000 */ cCcD_ObjAt mObjAt; /* 0x018 */ cCcD_ObjTg mObjTg; /* 0x02C */ cCcD_ObjCo mObjCo; - /* 0x03C */ void* vtable; + /* 0x03C */ cCcD_GObjInf__vtbl_t* vtable; cCcD_ObjAt& GetObjAt() { return mObjAt; } cCcD_ObjTg& GetObjTg() { return mObjTg; } diff --git a/external/libtp_c/include/SSystem/SComponent/c_counter.h b/external/libtp_c/include/SSystem/SComponent/c_counter.h index a1020135..59231c55 100644 --- a/external/libtp_c/include/SSystem/SComponent/c_counter.h +++ b/external/libtp_c/include/SSystem/SComponent/c_counter.h @@ -2,7 +2,6 @@ #define C_COUNTER_H #include "../../dolphin/types.h" -#include "../../addrs.h" struct cCounter { u32 game_counter; diff --git a/external/libtp_c/include/SSystem/SComponent/c_lib.h b/external/libtp_c/include/SSystem/SComponent/c_lib.h new file mode 100644 index 00000000..e74a7950 --- /dev/null +++ b/external/libtp_c/include/SSystem/SComponent/c_lib.h @@ -0,0 +1,11 @@ +#ifndef C_LIB_H_ +#define C_LIB_H_ + +#include "libtp_c/include/dolphin/types.h" +#include "libtp_c/include/defines.h" + +LIBTP_DEFINE_FUNC(cLib_chaseF__FPfff, cLib_chaseF_float____float__float_, int, cLib_chaseF, (f32*, f32, f32)) +LIBTP_DEFINE_FUNC(cLib_targetAngleY__FPC3VecPC3Vec, cLib_targetAngleY_Vec_const____Vec_const___, s16, cLib_targetAngleY, (const Vec*, const Vec*)) +LIBTP_DEFINE_FUNC(cLib_addCalc__FPfffff, cLib_addCalc_float____float__float__float__float_, f32, cLib_addCalc, (f32*,f32, f32,f32, f32)) + +#endif \ No newline at end of file diff --git a/external/libtp_c/include/SSystem/SComponent/c_m3d_g_aab.h b/external/libtp_c/include/SSystem/SComponent/c_m3d_g_aab.h index 9951f617..fd584e1b 100644 --- a/external/libtp_c/include/SSystem/SComponent/c_m3d_g_aab.h +++ b/external/libtp_c/include/SSystem/SComponent/c_m3d_g_aab.h @@ -5,12 +5,11 @@ // Axis aligned bounding box class cM3dGAab { -private: public: cXyz mMin; cXyz mMax; + void* vtable; - virtual ~cM3dGAab(); const cXyz& getMaxP(void) const { return mMax; } const cXyz& getMinP(void) const { return mMin; } const f32 GetMaxX(void) const { return mMax.x; } @@ -21,4 +20,6 @@ class cM3dGAab { const f32 GetMinZ(void) const { return mMin.z; } }; // Size = 0x1C +static_assert(sizeof(cM3dGAab) == 0x1C); + #endif /* C_M3D_G_AAB_H */ diff --git a/external/libtp_c/include/SSystem/SComponent/c_m3d_g_cps.h b/external/libtp_c/include/SSystem/SComponent/c_m3d_g_cps.h index a44f2960..7c4d2f6c 100644 --- a/external/libtp_c/include/SSystem/SComponent/c_m3d_g_cps.h +++ b/external/libtp_c/include/SSystem/SComponent/c_m3d_g_cps.h @@ -7,19 +7,16 @@ struct cM3dGCpsS { Vec mStart; Vec mEnd; - f32 unk_0x1c; + f32 mRadius; }; class cM3dGCps : public cM3dGLin { -private: - f32 unk_0x1c; - public: - cM3dGCps(void); - virtual ~cM3dGCps(void); - void Set(const cXyz&, const cXyz&, f32); - void Set(const cM3dGCpsS&); - void SetCps(const cM3dGCps&); + f32 mRadius; + + f32 GetR() const { return mRadius; } }; +static_assert(0x20 == sizeof(cM3dGCps)); + #endif /* C_M3D_G_CPS_H */ diff --git a/external/libtp_c/include/SSystem/SComponent/c_m3d_g_cyl.h b/external/libtp_c/include/SSystem/SComponent/c_m3d_g_cyl.h index 2acdd49c..519ed97a 100644 --- a/external/libtp_c/include/SSystem/SComponent/c_m3d_g_cyl.h +++ b/external/libtp_c/include/SSystem/SComponent/c_m3d_g_cyl.h @@ -13,7 +13,7 @@ class cM3dGSph; class cM3dGCyl : public cM3dGCylS { public: - virtual ~cM3dGCyl(); + void* vtable; const cXyz& GetCP(void) const { return mCenter; } f32 GetR(void) const { return mRadius; } f32 GetH(void) const { return mHeight; } diff --git a/external/libtp_c/include/SSystem/SComponent/c_m3d_g_lin.h b/external/libtp_c/include/SSystem/SComponent/c_m3d_g_lin.h index ad531ea5..da4b4594 100644 --- a/external/libtp_c/include/SSystem/SComponent/c_m3d_g_lin.h +++ b/external/libtp_c/include/SSystem/SComponent/c_m3d_g_lin.h @@ -10,12 +10,17 @@ class cM3dGLin { public: cXyz mStart; cXyz mEnd; + void* vtable; + + void CalcVec(Vec* pOut) const { PSVECSubtract(&this->mEnd, &this->mStart, pOut); } - virtual ~cM3dGLin() {} const cXyz& GetStartP(void) const { return mStart; } cXyz& GetStartP(void) { return mStart; } const cXyz& GetEndP(void) const { return mEnd; } cXyz& GetEndP(void) { return mEnd; } + f32 GetLen() const { return PSVECDistance(&mStart, &mEnd); } }; +static_assert(0x1C == sizeof(cM3dGLin)); + #endif /* C_M3D_G_LIN_H */ diff --git a/external/libtp_c/include/SSystem/SComponent/c_m3d_g_pla.h b/external/libtp_c/include/SSystem/SComponent/c_m3d_g_pla.h index 61e0d7d1..cab69cff 100644 --- a/external/libtp_c/include/SSystem/SComponent/c_m3d_g_pla.h +++ b/external/libtp_c/include/SSystem/SComponent/c_m3d_g_pla.h @@ -8,9 +8,7 @@ class cM3dGPla { public: cXyz mNormal; f32 mD; - cM3dGPla(); - cM3dGPla(const cXyz*, f32); - virtual ~cM3dGPla(); + void* vtable; const cXyz& GetNP() const { return mNormal; } f32 GetD() const { return mD; } diff --git a/external/libtp_c/include/SSystem/SComponent/c_m3d_g_sph.h b/external/libtp_c/include/SSystem/SComponent/c_m3d_g_sph.h index aebcc166..add0b7d7 100644 --- a/external/libtp_c/include/SSystem/SComponent/c_m3d_g_sph.h +++ b/external/libtp_c/include/SSystem/SComponent/c_m3d_g_sph.h @@ -14,9 +14,10 @@ class cM3dGSph { public: cXyz mCenter; f32 mRadius; + void* vtable; - virtual ~cM3dGSph(); const cXyz& GetC(void) const { return mCenter; } + const cXyz& GetCP(void) const { return mCenter; } const f32 GetR(void) const { return mRadius; } f32 GetCX(void) const { return mCenter.x; } f32 GetCY(void) const { return mCenter.y; } diff --git a/external/libtp_c/include/SSystem/SComponent/c_math.h b/external/libtp_c/include/SSystem/SComponent/c_math.h index 644b3aa0..fa7fcbe6 100644 --- a/external/libtp_c/include/SSystem/SComponent/c_math.h +++ b/external/libtp_c/include/SSystem/SComponent/c_math.h @@ -2,7 +2,8 @@ #define C_MATH_H #include "../../dolphin/types.h" -#include "addrs.h" +#include "libtp_c/include/defines.h" +#include "libtp_c/include/JSystem/JMATrigonometric.h" struct RNG { s32 r0; @@ -15,4 +16,12 @@ struct RNG { #define tp_rng (*(RNG*)(tp_rng_addr)) +inline f32 cM_ssin(s16 x) { + return JMASSin(x); +} + +inline f32 cM_scos(s16 x) { + return JMASCos(x); +} + #endif /* C_MATH_H */ diff --git a/external/libtp_c/include/SSystem/SComponent/c_sxyz.h b/external/libtp_c/include/SSystem/SComponent/c_sxyz.h index 4bab82e6..acbeea2d 100644 --- a/external/libtp_c/include/SSystem/SComponent/c_sxyz.h +++ b/external/libtp_c/include/SSystem/SComponent/c_sxyz.h @@ -17,10 +17,6 @@ class csXyz : public SVec { this->y = y; this->z = z; } - /* 80267404 */ csXyz operator+(csXyz&); - /* 8026745C */ void operator+=(csXyz&); - /* 80267490 */ csXyz operator-(csXyz&); - /* 802674E8 */ csXyz operator*(f32); }; #endif /* C_SXYZ_H */ diff --git a/external/libtp_c/include/SSystem/SComponent/c_xyz.h b/external/libtp_c/include/SSystem/SComponent/c_xyz.h index 494457ef..48e85d64 100644 --- a/external/libtp_c/include/SSystem/SComponent/c_xyz.h +++ b/external/libtp_c/include/SSystem/SComponent/c_xyz.h @@ -3,6 +3,7 @@ #include "../../dolphin/types.h" #include "../../dolphin/mtx/vec.h" +#include "../../msl_c/math.h" struct cXyz : Vec { ~cXyz() {} @@ -22,26 +23,74 @@ struct cXyz : Vec { this->y = vec.y; this->z = vec.z; } + void operator=(const Vec& vec) { this->x = vec.x; this->y = vec.y; this->z = vec.z; } + + cXyz operator+(Vec const& vec) const { + Vec ret; + PSVECAdd(this, &vec, &ret); + return cXyz(ret); + } + + cXyz operator-(Vec const& vec) const { + Vec ret; + PSVECSubtract(this, &vec, &ret); + return cXyz(ret); + } + + cXyz operator*(f32 scale) const { + Vec ret; + PSVECScale(this, &ret, scale); + return cXyz(ret); + } + + cXyz operator*(Vec const& vec) const { + cXyz ret; + ret.x = this->x * vec.x; + ret.y = this->y * vec.y; + ret.z = this->z * vec.z; + return cXyz(ret); + } + + cXyz operator/(f32 scale) const { + Vec ret; + PSVECScale(this, &ret, 1.0f / scale); + return cXyz(ret); + } + void operator+=(f32 f) { x += f; y += f; z += f; } + void operator-=(f32 f) { x -= f; y -= f; z -= f; } - void operator+=(const Vec& vec) { - x += vec.x; - y += vec.y; - z += vec.z; + + void operator*=(const Vec& other) { + x *= other.x; + y *= other.y; + z *= other.z; + } + + void operator-=(const Vec& other) { PSVECSubtract(this, &other, this); } + + cXyz* operator+=(const Vec& other) { + PSVECAdd(this, &other, this); + return this; } + + void operator*=(f32 scale) { PSVECScale(this, this, scale); } + + void operator/=(f32 scale) { PSVECScale(this, this, 1.0f / scale); } + void setAll(f32 f) { z = f; y = f; @@ -74,6 +123,21 @@ struct cXyz : Vec { z = other.z; } } + + float getSquareMag() const { return PSVECSquareMag(this); } + f32 getSquareDistance(const Vec& other) const { return PSVECSquareDistance(this, &other); } + + f32 abs2() const { return this->getSquareMag(); } + f32 abs2(const Vec& other) const { return this->getSquareDistance(other); } + + f32 abs() const { return (f32)sqrt(this->abs2()); } + f32 abs(const Vec& other) const { return (f32)sqrt(this->abs2(other)); } + + f32 abs2XZ() const { + cXyz tmp(this->x, 0, this->z); + return tmp.abs2(); + } + f32 absXZ() const { return sqrt(this->abs2XZ()); } }; #endif /* C_XYZ_H */ diff --git a/external/libtp_c/include/addrs.h b/external/libtp_c/include/addrs.h deleted file mode 100644 index 1b575efb..00000000 --- a/external/libtp_c/include/addrs.h +++ /dev/null @@ -1,1401 +0,0 @@ -#ifndef LIB_TP_ADDRS -#define LIB_TP_ADDRS - -#ifndef REL_MODULE -#ifdef GCN_NTSCU -// System -#define tp_memset_addr 0x8026f95c -#define tp_memalign_addr 0x80263228 -#define tp_free_addr 0x80263260 -#define tp_osReport_addr 0x80006ABC -#define tp_memcpy_addr 0x80003540 -#define tp_getLayerNo_addr 0x8002B434 -#define tp_getSave_addr 0x800350bc -#define tp_putSave_addr 0x800350f0 -#define tp_sprintf_addr 0x803664dc -#define tp_vsnprintf_addr 0x80366690 -#define tp_strcpy_addr 0x80368b2c -#define tp_strlen_addr 0x80368be4 -#define tp_strcmp_addr 0x80368994 -#ifdef PR_TEST -#define tp_myExceptionCallback_addr 0x8000b7c8 -#endif - -// Math -#define tp_atan_addr 0x8036bca4 -#define tp_ceil_addr 0x8036bebc -#define tp_copysign_addr 0x8036c000 -#define tp_cos_addr 0x8036c028 -#define tp_floor_addr 0x8036c0fc -#define tp_frexp_addr 0x8036c244 -#define tp_ldexp_addr 0x8036c2d0 -#define tp_modf_addr 0x8036c494 -#define tp_sin_addr 0x8036c590 -#define tp_tan_addr 0x8036c668 -#define tp_acos_addr 0x8036c6e0 -#define tp_asin_addr 0x8036c700 -#define tp_atan2_addr 0x8036c720 -#define tp_exp_addr 0x8036c740 -#define tp_fmod_addr 0x8036c760 -#define tp_pow_addr 0x8036c780 -#define tp_fastSqrt_addr 0x80182a24 -#define tp_sqrt_addr 0x8036ca54 - -// Controller -#define tp_mPadStatus_addr 0x804343F0 -#define tp_mPadButton_addr 0x80434420 -#define tp_mPadMStick_addr 0x804344E0 -#define tp_mPadSStick_addr 0x80434520 -#define tp_JUTGamePadRead_addr 0x802e08e4 -#define tp_cPadInfo_addr 0x803DD2E8 - -// TP -#define tp_globalCounters_addr 0x80430CD8 -#define tp_zelAudio_addr 0x803DBF4C -#define tp_gameInfo_addr 0x804061C0 -#define tp_sConsole_addr 0x80450C90 -#define tp_fopScnRq_addr 0x80450CE0 -#define tp_titleScreenPtr_addr 0x803A3A38 -#define tp_matrixPtr_addr 0x803F1E10 -#define tp_rng_addr 0x80451168 - -// Items -#define tp_clawshot_addr 0x8038E9C0 -#define tp_clawshot_checkbg_addr 0x801087b0 -#define tp_ironboots_addr 0x8038E7F4 -#define tp_spinner_addr 0x8038EA30 -#define tp_ball_and_chain_addr 0x8038EA70 -#define tp_bottle_addr 0x8038E90C - -// Actor -#define tp_actor_addr 0x80450610 -#define tp_actor_stopstatus_addr 0x80450CBC - -// Draw -#define tp_draw_addr 0x8042EBC8 - -// Link -#define tp_link_human_frontroll_addr 0x8038D7BC -#define tp_link_human_sidestep_addr 0x8038D864 -#define tp_link_human_backjump_addr 0x8038D82C -#define tp_link_human_slide_addr 0x8038D8CC -#define tp_link_human_swim_addr 0x8038ED2C -#define tp_link_wolf_general_addr 0x8038EE28 -#define tp_link_wolf_swim_addr 0x8038f8b4 - -// Inventory -#define tp_execItemGet_addr 0x80097E8C - -// Scene -#define tp_setTimePass_addr 0x80024DB0 - -// GX -#define GXSetBlendMode_addr 0x8035FBF0 -#define GXBegin_addr 0x8035C764 -#define GXSetVtxAttrFmt_addr 0x8035B5C4 -#define GXLoadPosMtxImm_addr 0x8036024C -#define GXSetNumIndStages_addr 0x8035F0D4 -#define GXSetTevDirect_addr 0x8035F0F8 -#define GXSetAlphaCompare_addr 0x8035F624 -#define GXSetZMode_addr 0x8035FC9C -#define GXSetTevOp_addr 0x8035F198 -#define GXSetNumChans_addr 0x8035DB30 -#define GXSetNumTevStages_addr 0x8035F890 -#define GXSetNumTexGens_addr 0x8035BDFC -#define GXSetTevOrder_addr 0x8035F6F4 -#define GXSetTevColorIn_addr 0x8035F224 -#define GXSetTevAlphaIn_addr 0x8035F268 -#define GXSetTevColorOp_addr 0x8035F2AC -#define GXSetTevAlphaOp_addr 0x8035F314 -#define GXSetCullMode_addr 0x8035C984 -#define GXLoadTexMtxImm_addr 0x80360320 -#define GXSetChanCtrl_addr 0x8035DB6C -#define GXSetCurrentMtx_addr 0x803602EC -#define GXSetTexCoordGen2_addr 0x8035BB7C -#define GXSetLineWidth_addr 0x8035C8BC -#define GXClearVtxDesc_addr 0x8035B58C -#define GXSetVtxDesc_addr 0x8035AEB8 -#define GXFlush_addr 0x8035becc -#define GXInitTexObj_addr 0x8035DE40 -#define GXLoadTexObj_addr 0x8035E414 -#define GXInvalidateTexAll_addr 0x8035E664 -#define GXSetProjection_addr 0x803600D4 -#define GXSetScissor_addr 0x803604D0 -#define GXGetScissor_addr 0x80360548 -#define wgPipe_addr 0xCC008000 - -// misc functions (sort later) -#define tp_cDyl_InitAsync_addr 0x80018764 -#define tp_fapGm_Execute_addr 0x80018a6c -#define tp_draw_console_addr 0x802e8384 -#define tp_PADRead_addr 0x8034eea0 -#define tp_setSpecialGravity_addr 0x800bb770 -#define tp_checkCastleTownUseItem_addr 0x800c0678 -#define tp_query042_addr 0x8024bfec -#define tp_cc_at_check_addr 0x80087c04 - -// d_save -#define dSv_player_item_c__setItem_addr 0x80032fb8 -#define dSv_player_item_c__getItem_addr 0x80033030 -#define dSv_player_item_record_c__setBombNum_addr 0x80033f6c -#define dSv_player_item_record_c__getBombNum_addr 0x80033f7c -#define dSv_player_status_a_c__getSelectItemIndex_addr 0x80032a5c -#define dSv_player_status_b_c__isTransformLV_addr 0x80032bec -#define dSv_player_status_b_c__onTransformLV_addr 0x80032bd0 -#define dSv_light_drop_c__setLightDropNum_addr 0x80034320 -#define dSv_light_drop_c__getLightDropNum_addr 0x80034340 -#define dSv_info_c__onSwitch_addr 0x80035200 -#define dSv_info_c__offSwitch_addr 0x800352b0 -#define dSv_memBit_c__isSwitch_addr 0x80034860 -#define dSv_memBit_c__onSwitch_addr 0x80034810 -#define dSv_memBit_c__offSwitch_addr 0x80034838 -#define dSv_memBit_c__isDungeonItem_addr 0x80034934 -#define dSv_memBit_c__onDungeonItem_addr 0x80034918 -#define dSv_player_get_item_c__onFirstBit_addr 0x80033e60 -#define dSv_player_get_item_c__offFirstBit_addr 0x80033e94 -#define dSv_event_c__isEventBit_addr 0x800349bc -#define dSv_event_c__offEventBit_addr 0x800349a4 -#define dSv_event_c__onEventBit_addr 0x8003498c -#define dSv_player_return_place_c__set_addr 0x80032d1c - -// d_meter2_info -#define g_meter2_info_addr 0x80430188 - -// d_com_inf_game -#define dComIfGs_setSelectItemIndex_addr 0x8002dcc4 -#define dComIfGs_getMixItemIndex_addr 0x8002ddc8 -#define dComIfGs_setMixItemIndex_addr 0x8002dd08 -#define dComIfGp_getEvent_addr 0x801412f8 -#define dComIfGp_getEventManager_addr 0x8014134c -#define dComIfGs_isItemFirstBit_addr 0x80141264 -#define dComIfGs_getRupee_addr 0x80141990 -#define dComIfGs_onZoneSwitch_addr 0x8002d94c -#define dComIfGs_onOneZoneSwitch_addr 0x8002da9c - -// d_stage -#define dStage_nextStage_c__set_addr 0x80023e28 - -// d_menu_window -#define dMw_c__isEventCheck_addr 0x801fcf84 - -// m_Do_audio -#define mDoAud_seStartLevel_addr 0x8014113c - -// JKernel -#define JKernel__operator_new_addr 0x802cec4c -#define JKernel__operator_delete_addr 0x802ced3c -#define JKRArchive__getResource2_addr 0x802d5c64 -#define tp_zeldaHeap_addr 0x80450c2c -#define tp_gameHeap_addr 0x80450c28 -#define tp_archiveHeap_addr 0x80450c34 -#define JKRExpHeap__getUsedSize_addr 0x802cfce8 -#define JKRHeap__getFreeSize_addr 0x802ce72c -#define JKRHeap__getTotalFreeSize_addr 0x802ce784 -#define JKRExpHeap__do_getTotalFreeSize_addr 0x802cfc84 -#define JKRHeap__alloc_addr 0x802ce474 - -// J3DSys -#define j3dSys_addr 0x80434ac8 - -// J3DPacket -#define J3DDrawBuffer__entryImm_addr 0x8032548c -#define J3DPacket__entry_addr 0x80312750 - -// J2DPicture -#define J2DPicture__J2DPicture4_addr 0x802fc708 -#define J2DPicture__draw_addr 0x802fdc70 - -// J2DPane -#define J2DPane__J2DPane1_addr 0x802f5bf8 - -// J2DTextBox -#define J2DTextBox__J2DTextBox1_addr 0x802ff660 -#define J2DTextBox__setFont_addr 0x80300278 -#define J2DTextBox__setString_addr 0x80300660 -#define J2DTextBox__draw2_addr 0x80300490 - -// d_a_alink -#define daAlink_c__checkStageName_addr 0x8009da60 - -// f_op_actor_mng -#define fopAcM_create_addr 0x80019D98 -#define g_fopAcTg_Queue_addr 0x803A35E0 - -// f_op_actor_iter -#define fopAcIt_Judge_addr 0x800197f8 - -// f_pc_searcher -#define fpcSch_JudgeForPName_addr 0x80023578 - -// d_kankyo -#define g_env_light_addr 0x8042ca54 - -// d_s_play -#define sPauseTimer_addr 0x80451125 - -// d_cc_s -#define dCcS__draw_addr 0x800872d0 - -// m_Do_graphic -#define dScnPly_BeforeOfPaint_addr 0x80008424 - -// m_Do_ext -#define mDoExt_getMesgFont_addr 0x800149f0 - -// m_Do_controller_pad -#define mDoCPd_c__m_gamePad_addr 0x803DD2D8 - -// m_Do_mtx -#define mDoMtx_stack_c__now_addr 0x803dd470 -#define mDoMtx_XYZrotM__addr 0x8000c164 -#define mDoMtx_stack_c__scaleM_addr 0x8000ce38 - -#endif - -#ifdef GCN_PAL -// System -#define tp_memset_addr 0x8027075c -#define tp_memalign_addr 0x80264028 -#define tp_free_addr 0x80264060 -#define tp_osReport_addr 0x80006ABC -#define tp_memcpy_addr 0x80003540 -#define tp_getLayerNo_addr 0x8002b4dc -#define tp_getSave_addr 0x800351ec -#define tp_putSave_addr 0x80035220 -#define tp_sprintf_addr 0x8036730c -#define tp_strcpy_addr 0x8036995c -#define tp_strlen_addr 0x80369a14 -#define tp_strcmp_addr 0x803697c4 - -// Math -#define tp_atan_addr 0x8036cad4 -#define tp_ceil_addr 0x8036ccec -#define tp_copysign_addr 0x8036ce30 -#define tp_cos_addr 0x8036ce58 -#define tp_floor_addr 0x8036cf2c -#define tp_frexp_addr 0x8036d074 -#define tp_ldexp_addr 0x8036d100 -#define tp_modf_addr 0x8036d2c4 -#define tp_sin_addr 0x8036d3c0 -#define tp_tan_addr 0x8036d498 -#define tp_acos_addr 0x8036d510 -#define tp_asin_addr 0x8036d530 -#define tp_atan2_addr 0x8036d550 -#define tp_exp_addr 0x8036d570 -#define tp_fmod_addr 0x8036d590 -#define tp_pow_addr 0x8036d5b0 -#define tp_fastSqrt_addr 0x80182c30 -#define tp_sqrt_addr 0x8036d884 - -// Controller -#define tp_mPadStatus_addr 0x804363b0 -#define tp_mPadButton_addr 0x804363e0 -#define tp_mPadMStick_addr 0x804364a0 -#define tp_mPadSStick_addr 0x804364e0 -#define tp_JUTGamePadRead_addr 0x802e16e4 -#define tp_cPadInfo_addr 0x803df288 - -// TP -#define tp_globalCounters_addr 0x80432c98 -#define tp_zelAudio_addr 0x803ddeec -#define tp_gameInfo_addr 0x80408160 -#define tp_sConsole_addr 0x80452c50 -#define tp_fopScnRq_addr 0x80452ca0 -#define tp_titleScreenPtr_addr 0x803a5718 -#define tp_matrixPtr_addr 0x803f3db0 -#define tp_rng_addr 0x80453130 - -// Items -#define tp_clawshot_addr 0x803901c0 -#define tp_clawshot_checkbg_addr 0x801089bc -#define tp_ironboots_addr 0x8038fff4 -#define tp_spinner_addr 0x80390230 -#define tp_ball_and_chain_addr 0x80390270 -#define tp_bottle_addr 0x8039010c - -// Actor -#define tp_actor_addr 0x804525d0 -#define tp_actor_stopstatus_addr 0x80452c7c - -// Draw -#define tp_draw_addr 0x80430b88 - -// Link -#define tp_link_human_frontroll_addr 0x8038efbc -#define tp_link_human_sidestep_addr 0x8038f064 -#define tp_link_human_backjump_addr 0x8038f02c -#define tp_link_human_slide_addr 0x8038f0cc -#define tp_link_human_swim_addr 0x8039052c -#define tp_link_wolf_general_addr 0x80390628 -#define tp_link_wolf_swim_addr 0x803910b4 - -// Inventory -#define tp_execItemGet_addr 0x80097fbc - -// Scene -#define tp_setTimePass_addr 0x80024e58 - -// GX -#define GXSetBlendMode_addr 0x80360a20 -#define GXBegin_addr 0x8035d594 -#define GXSetVtxAttrFmt_addr 0x8035c3f4 -#define GXLoadPosMtxImm_addr 0x8036107c -#define GXSetNumIndStages_addr 0x8035ff04 -#define GXSetTevDirect_addr 0x8035ff28 -#define GXSetAlphaCompare_addr 0x80360454 -#define GXSetZMode_addr 0x80360acc -#define GXSetTevOp_addr 0x8035ffc8 -#define GXSetNumChans_addr 0x8035e960 -#define GXSetNumTevStages_addr 0x803606c0 -#define GXSetNumTexGens_addr 0x8035cc2c -#define GXSetTevOrder_addr 0x80360524 -#define GXSetTevColorIn_addr 0x80360054 -#define GXSetTevAlphaIn_addr 0x80360098 -#define GXSetTevColorOp_addr 0x803600dc -#define GXSetTevAlphaOp_addr 0x80360144 -#define GXSetCullMode_addr 0x8035d7b4 -#define GXLoadTexMtxImm_addr 0x80361150 -#define GXSetChanCtrl_addr 0x8035e99c -#define GXSetCurrentMtx_addr 0x8036111c -#define GXSetTexCoordGen2_addr 0x8035c9ac -#define GXSetLineWidth_addr 0x8035d6ec -#define GXClearVtxDesc_addr 0x8035c3bc -#define GXSetVtxDesc_addr 0x8035bce8 -#define GXFlush_addr 0x8035ccfc -#define GXInitTexObj_addr 0x8035ec70 -#define GXLoadTexObj_addr 0x8035f244 -#define GXInvalidateTexAll_addr 0x8035f494 -#define GXSetProjection_addr 0x80360f04 -#define GXSetScissor_addr 0x80361300 -#define GXGetScissor_addr 0x80361378 -#define wgPipe_addr 0xCC008000 - -// function hooks (move to correct categories later) -#define tp_cDyl_InitAsync_addr 0x8001880c -#define tp_fapGm_Execute_addr 0x80018b14 -#define tp_draw_console_addr 0x802e9184 -#define tp_PADRead_addr 0x8034fcd0 -#define tp_setSpecialGravity_addr 0x800bb97c -#define tp_checkCastleTownUseItem_addr 0x800c0884 -#define tp_query042_addr 0x8024c690 -#define tp_cc_at_check_addr 0x80087d34 - -// d_save -#define dSv_player_item_c__setItem_addr 0x80033060 -#define dSv_player_item_c__getItem_addr 0x800330d8 -#define dSv_player_item_record_c__setBombNum_addr 0x80034014 -#define dSv_player_item_record_c__getBombNum_addr 0x80034024 -#define dSv_player_status_a_c__getSelectItemIndex_addr 0x80032b04 -#define dSv_player_status_b_c__isTransformLV_addr 0x80032c94 -#define dSv_player_status_b_c__onTransformLV_addr 0x80032c78 -#define dSv_light_drop_c__setLightDropNum_addr 0x800343c8 -#define dSv_light_drop_c__getLightDropNum_addr 0x800343e8 -#define dSv_info_c__onSwitch_addr 0x80035330 -#define dSv_info_c__offSwitch_addr 0x800353e0 -#define dSv_memBit_c__isSwitch_addr 0x80035490 -#define dSv_memBit_c__onSwitch_addr 0x80034940 -#define dSv_memBit_c__offSwitch_addr 0x80034968 -#define dSv_memBit_c__isDungeonItem_addr 0x80034a64 -#define dSv_memBit_c__onDungeonItem_addr 0x80034a48 -#define dSv_player_get_item_c__onFirstBit_addr 0x80033f08 -#define dSv_player_get_item_c__offFirstBit_addr 0x80033f3c -#define dSv_event_c__isEventBit_addr 0x80034aec -#define dSv_event_c__offEventBit_addr 0x80034ad4 -#define dSv_event_c__onEventBit_addr 0x80034abc -#define dSv_player_return_place_c__set_addr 0x80032dc4 - -// d_meter2_info -#define g_meter2_info_addr 0x80432148 - -// d_com_inf_game -#define dComIfGs_setSelectItemIndex_addr 0x8002dd6c -#define dComIfGs_getMixItemIndex_addr 0x8002de70 -#define dComIfGs_setMixItemIndex_addr 0x8002ddb0 -#define dComIfGp_getEvent_addr 0x80141504 -#define dComIfGp_getEventManager_addr 0x80141558 -#define dComIfGs_isItemFirstBit_addr 0x80141470 -#define dComIfGs_getRupee_addr 0x80141b9c -#define dComIfGs_onZoneSwitch_addr 0x8002d9f4 -#define dComIfGs_onOneZoneSwitch_addr 0x8002db44 - -// d_stage -#define dStage_nextStage_c__set_addr 0x80023ed0 - -// d_menu_window -#define dMw_c__isEventCheck_addr 0x801fd248 - -// m_Do_audio -#define mDoAud_seStartLevel_addr 0x80141348 - -// JKernel -#define JKernel__operator_new_addr 0x802cfa4c -#define JKernel__operator_delete_addr 0x802cfb3c -#define JKRArchive__getResource2_addr 0x802d6a64 -#define tp_zeldaHeap_addr 0x80452bec -#define tp_gameHeap_addr 0x80452be8 -#define tp_archiveHeap_addr 0x80452bf4 -#define JKRExpHeap__getUsedSize_addr 0x802d0ae8 -#define JKRHeap__getFreeSize_addr 0x802cf52c -#define JKRHeap__getTotalFreeSize_addr 0x802cf584 -#define JKRExpHeap__do_getTotalFreeSize_addr 0x802d0a84 -#define JKRHeap__alloc_addr 0x802cf274 - -// J3DSys -#define j3dSys_addr 0x80436a88 - -// J3DPacket -#define J3DDrawBuffer__entryImm_addr 0x8032628c -#define J3DPacket__entry_addr 0x80313550 - -// J2DPicture -#define J2DPicture__J2DPicture4_addr 0x802fd508 -#define J2DPicture__draw_addr 0x802fea70 - -// J2DPane -#define J2DPane__J2DPane1_addr 0x802f69f8 - -// J2DTextBox -#define J2DTextBox__J2DTextBox1_addr 0x80300460 -#define J2DTextBox__setFont_addr 0x80301078 -#define J2DTextBox__setString_addr 0x80301460 -#define J2DTextBox__draw2_addr 0x80301290 - -// d_a_alink -#define daAlink_c__checkStageName_addr 0x8009dc6c - -// f_op_actor_mng -#define fopAcM_create_addr 0x80019e40 -#define g_fopAcTg_Queue_addr 0x803a52c0 - -// f_op_actor_iter -#define fopAcIt_Judge_addr 0x800198a0 - -// f_pc_searcher -#define fpcSch_JudgeForPName_addr 0x80023620 - -// d_kankyo -#define g_env_light_addr 0x8042ea14 - -// d_s_play -#define sPauseTimer_addr 0x804530ED - -// m_Do_ext -#define mDoExt_getMesgFont_addr 0x800149a4 - -// m_Do_controller_pad -#define mDoCPd_c__m_gamePad_addr 0x803df278 - -// m_Do_mtx -#define mDoMtx_stack_c__now_addr 0x803df410 -#define mDoMtx_XYZrotM__addr 0x8000c118 -#define mDoMtx_stack_c__scaleM_addr 0x8000cdec - -#endif - -#ifdef GCN_NTSCJ -// System -#define tp_memset_addr 0x80271d8c -#define tp_memalign_addr 0x80265658 -#define tp_free_addr 0x80265690 -#define tp_osReport_addr 0x80006ABC -#define tp_memcpy_addr 0x80003540 -#define tp_getLayerNo_addr 0x8002c97c -#define tp_getSave_addr 0x800350bc -#define tp_putSave_addr 0x800350f0 -#define tp_sprintf_addr 0x80368978 -#define tp_strcpy_addr 0x8036afc8 -#define tp_strlen_addr 0x8036b080 -#define tp_strcmp_addr 0x8036ae30 - -// Math -#define tp_atan_addr 0x8036e140 -#define tp_ceil_addr 0x8036e358 -#define tp_copysign_addr 0x8036e49c -#define tp_cos_addr 0x8036e4c4 -#define tp_floor_addr 0x8036e598 -#define tp_frexp_addr 0x8036e6e0 -#define tp_ldexp_addr 0x8036e76c -#define tp_modf_addr 0x8036e930 -#define tp_sin_addr 0x8036ea2c -#define tp_tan_addr 0x8036eb04 -#define tp_acos_addr 0x8036eb7c -#define tp_asin_addr 0x8036eb9c -#define tp_atan2_addr 0x8036ebbc -#define tp_exp_addr 0x8036ebdc -#define tp_fmod_addr 0x8036ebfc -#define tp_pow_addr 0x8036ec1c -#define tp_fastSqrt_addr 0x80182a70 -#define tp_sqrt_addr 0x8036eef0 - -// Controller -#define tp_mPadStatus_addr 0x8042e530 -#define tp_mPadButton_addr 0x8042e560 -#define tp_mPadMStick_addr 0x8042e620 -#define tp_mPadSStick_addr 0x8042e660 -#define tp_JUTGamePadRead_addr 0x802e2d80 -#define tp_cPadInfo_addr 0x803d7428 - -// TP -#define tp_globalCounters_addr 0x8042ae18 -#define tp_zelAudio_addr 0x803d608c -#define tp_gameInfo_addr 0x80400300 -#define tp_sConsole_addr 0x8044add0 -#define tp_fopScnRq_addr 0x8044ae20 -#define tp_titleScreenPtr_addr 0x8039db98 -#define tp_matrixPtr_addr 0x803ebf50 -#define tp_rng_addr 0x8044b2a8 - -// Items -#define tp_clawshot_addr 0x80388a40 -#define tp_clawshot_checkbg_addr 0x801087e8 -#define tp_ironboots_addr 0x80388874 -#define tp_spinner_addr 0x80388ab0 -#define tp_ball_and_chain_addr 0x80388af0 -#define tp_bottle_addr 0x8038898c - -// Actor -#define tp_actor_addr 0x8044a750 -#define tp_actor_stopstatus_addr 0x8044adfc - -// Draw -#define tp_draw_addr 0x80428d08 - -// Link -#define tp_link_human_frontroll_addr 0x8038783c -#define tp_link_human_sidestep_addr 0x803878e4 -#define tp_link_human_backjump_addr 0x803878ac -#define tp_link_human_slide_addr 0x8038794c -#define tp_link_human_swim_addr 0x80388dac -#define tp_link_wolf_general_addr 0x80388ea8 -#define tp_link_wolf_swim_addr 0x80389934 - -// Inventory -#define tp_execItemGet_addr 0x80097ecc - -// Scene -#define tp_setTimePass_addr 0x80024db0 - -// GX -#define GXSetBlendMode_addr 0x8036208c -#define GXBegin_addr 0x8035ec00 -#define GXSetVtxAttrFmt_addr 0x8035da60 -#define GXLoadPosMtxImm_addr 0x803626e8 -#define GXSetNumIndStages_addr 0x80361570 -#define GXSetTevDirect_addr 0x80361594 -#define GXSetAlphaCompare_addr 0x80361ac0 -#define GXSetZMode_addr 0x80362138 -#define GXSetTevOp_addr 0x80361634 -#define GXSetNumChans_addr 0x8035ffcc -#define GXSetNumTevStages_addr 0x80361d2c -#define GXSetNumTexGens_addr 0x8035e298 -#define GXSetTevOrder_addr 0x80361b90 -#define GXSetTevColorIn_addr 0x803616c0 -#define GXSetTevAlphaIn_addr 0x80361704 -#define GXSetTevColorOp_addr 0x80361748 -#define GXSetTevAlphaOp_addr 0x803617b0 -#define GXSetCullMode_addr 0x8035ee20 -#define GXLoadTexMtxImm_addr 0x803627bc -#define GXSetChanCtrl_addr 0x80360008 -#define GXSetCurrentMtx_addr 0x80362788 -#define GXSetTexCoordGen2_addr 0x8035e018 -#define GXSetLineWidth_addr 0x8035ed58 -#define GXClearVtxDesc_addr 0x8035da28 -#define GXSetVtxDesc_addr 0x8035d354 -#define GXFlush_addr 0x8035e368 -#define GXInitTexObj_addr 0x803602dc -#define GXLoadTexObj_addr 0x803608b0 -#define GXInvalidateTexAll_addr 0x80360b00 -#define GXSetProjection_addr 0x80362570 -#define GXSetScissor_addr 0x8036296c -#define GXGetScissor_addr 0x803629e4 -#define wgPipe_addr 0xCC008000 - -// function hooks (move to correct categories later) -#define tp_cDyl_InitAsync_addr 0x80018764 -#define tp_fapGm_Execute_addr 0x80018a6c -#define tp_draw_console_addr 0x802ea820 -#define tp_PADRead_addr 0x8035133c -#define tp_setSpecialGravity_addr 0x800bb7a8 -#define tp_checkCastleTownUseItem_addr 0x800c06b0 -#define tp_query042_addr 0x8024d954 -#define tp_cc_at_check_addr 0x80087c44 - -// d_save -#define dSv_player_item_c__setItem_addr 0x80032fb8 -#define dSv_player_item_c__getItem_addr 0x80033030 -#define dSv_player_item_record_c__setBombNum_addr 0x80033f6c -#define dSv_player_item_record_c__getBombNum_addr 0x80033f7c -#define dSv_player_status_a_c__getSelectItemIndex_addr 0x80032a5c -#define dSv_player_status_b_c__isTransformLV_addr 0x80032bec -#define dSv_player_status_b_c__onTransformLV_addr 0x80032bd0 -#define dSv_light_drop_c__setLightDropNum_addr 0x80034320 -#define dSv_light_drop_c__getLightDropNum_addr 0x80034340 -#define dSv_info_c__onSwitch_addr 0x80035200 -#define dSv_info_c__offSwitch_addr 0x800352b0 -#define dSv_memBit_c__isSwitch_addr 0x80035360 -#define dSv_memBit_c__onSwitch_addr 0x80034810 -#define dSv_memBit_c__offSwitch_addr 0x80034838 -#define dSv_memBit_c__isDungeonItem_addr 0x80034934 -#define dSv_memBit_c__onDungeonItem_addr 0x80034918 -#define dSv_player_get_item_c__onFirstBit_addr 0x80033e60 -#define dSv_player_get_item_c__offFirstBit_addr 0x80033e94 -#define dSv_event_c__isEventBit_addr 0x800349bc -#define dSv_event_c__offEventBit_addr 0x800349a4 -#define dSv_event_c__onEventBit_addr 0x8003498c -#define dSv_player_return_place_c__set_addr 0x80032d1c - -// d_meter2_info -#define g_meter2_info_addr 0x8042a2c8 - -// d_com_inf_game -#define dComIfGs_setSelectItemIndex_addr 0x8002dcc4 -#define dComIfGs_getMixItemIndex_addr 0x8002ddc8 -#define dComIfGs_setMixItemIndex_addr 0x8002dd08 -#define dComIfGp_getEvent_addr 0x80141344 -#define dComIfGp_getEventManager_addr 0x80141398 -#define dComIfGs_isItemFirstBit_addr 0x801412b0 -#define dComIfGs_getRupee_addr 0x801419dc -#define dComIfGs_onZoneSwitch_addr 0x8002d94c -#define dComIfGs_onOneZoneSwitch_addr 0x8002da9c - -// d_stage -#define dStage_nextStage_c__set_addr 0x80023e28 - -// d_menu_window -#define dMw_c__isEventCheck_addr 0x801fd67c - -// m_Do_audio -#define mDoAud_seStartLevel_addr 0x80141188 - -// JKernel -#define JKernel__operator_new_addr 0x802d10e8 -#define JKernel__operator_delete_addr 0x802d11d8 -#define JKRArchive__getResource2_addr 0x802d8100 -#define tp_zeldaHeap_addr 0x8044ad6c -#define tp_gameHeap_addr 0x8044ad68 -#define tp_archiveHeap_addr 0x8044ad74 -#define JKRExpHeap__getUsedSize_addr 0x802d2184 -#define JKRHeap__getFreeSize_addr 0x802d0bc8 -#define JKRHeap__getTotalFreeSize_addr 0x802d0c20 -#define JKRExpHeap__do_getTotalFreeSize_addr 0x802d2120 -#define JKRHeap__alloc_addr 0x802d0910 - -// J3DSys -#define j3dSys_addr 0x8042ec08 - -// J3DPacket -#define J3DDrawBuffer__entryImm_addr 0x80327928 -#define J3DPacket__entry_addr 0x80314bec - -// J2DPicture -#define J2DPicture__J2DPicture4_addr 0x802feba4 -#define J2DPicture__draw_addr 0x8030010c - -// J2DPane -#define J2DPane__J2DPane1_addr 0x802f8094 - -// J2DTextBox -#define J2DTextBox__J2DTextBox1_addr 0x80301afc -#define J2DTextBox__setFont_addr 0x80302714 -#define J2DTextBox__setString_addr 0x80302afc -#define J2DTextBox__draw2_addr 0x8030292c - -// d_a_alink -#define daAlink_c__checkStageName_addr 0x8009da98 - -// f_op_actor_mng -#define fopAcM_create_addr 0x80019d98 -#define g_fopAcTg_Queue_addr 0x8039d740 - -// f_op_actor_iter -#define fopAcIt_Judge_addr 0x800197f8 - -// f_pc_searcher -#define fpcSch_JudgeForPName_addr 0x80023578 - -// d_kankyo -#define g_env_light_addr 0x80426b94 - -// d_s_play -#define sPauseTimer_addr 0x8044b265 - -// m_Do_ext -#define mDoExt_getMesgFont_addr 0x800149f0 - -// m_Do_controller_pad -#define mDoCPd_c__m_gamePad_addr 0x803d7418 - -// m_Do_mtx -#define mDoMtx_stack_c__now_addr 0x803d75b0 -#define mDoMtx_XYZrotM__addr 0x8000c164 -#define mDoMtx_stack_c__scaleM_addr 0x8000ce38 - -#endif - -#ifdef WII_NTSCU_10 -// System -#define tp_memset_addr 0x8000443c -#define tp_memalign_addr 0x8024df80 -#define tp_free_addr 0x8024dfa0 -#define tp_osReport_addr 0x800090a8 -#define tp_memcpy_addr 0x80004338 -#define tp_getLayerNo_addr 0x8002f640 -#define tp_getSave_addr 0x8003929c -#define tp_putSave_addr 0x800392cc -#define tp_sprintf_addr 0x803c32e4 -#define tp_strcpy_addr 0x803c34f4 -#define tp_strlen_addr 0x803bdb38 -#define tp_strcmp_addr 0x803c3624 - -// Math -#define tp_atan_addr 0x803c74e0 -#define tp_ceil_addr 0x803c7720 -#define tp_copysign_addr 0x803c7860 -#define tp_cos_addr 0x803c788c -#define tp_floor_addr 0x803c7960 -#define tp_frexp_addr 0x803c7aa4 -#define tp_ldexp_addr 0x803c7b2c -#define tp_sin_addr 0x803c7c98 -#define tp_tan_addr 0x803c7d70 -#define tp_acos_addr 0x803c7de8 -#define tp_asin_addr 0x803c7dec -#define tp_atan2_addr 0x803c7df0 -#define tp_exp_addr 0x803c7df4 -#define tp_fmod_addr 0x803c7df8 -#define tp_pow_addr 0x803c7dfc -#define tp_fastSqrt_addr 0x8025ca1c -#define tp_sqrt_addr 0x803c8048 - -// Controller -#define tp_mPadStatus_addr 0x804c2f08 -#define tp_mPadButton_addr 0x804c2f38 -#define tp_mPadMStick_addr 0x804c2ff8 -#define tp_mPadSStick_addr 0x804c3038 -#define tp_mPad_addr 0x8044bb60 -#define tp_JUTGamePadRead_addr 0x802f4364 -#define tp_cPadInfo_addr 0x8044ba60 - -// TP -#define tp_globalCounters_addr 0x804becb8 -#define tp_zelAudio_addr 0x8044a6ac -#define tp_gameInfo_addr 0x80492928 -#define tp_sConsole_addr 0x8053a8e0 -#define tp_fopScnRq_addr 0x8053a928 -#define tp_titleScreenPtr_addr 0x804813e0 -#define tp_matrixPtr_addr 0x8047e368 -#define tp_rng_addr 0x8053ae58 -#define tp_homeMenuSts_addr 0x8053A968 - -// Items -#define tp_clawshot_addr 0x803e4b5c -#define tp_clawshot_checkbg_addr 0x800fcdbc -#define tp_ironboots_addr 0x803e4990 -#define tp_spinner_addr 0x803e4bcc -#define tp_ball_and_chain_addr 0x803e4c0c -#define tp_bottle_addr 0x803e4aa8 - -// Actor -#define tp_actor_addr 0x8053a9c8 -#define tp_actor_stopstatus_addr 0x8053a90c - -// Draw -#define tp_draw_addr 0x804bb5d8 - -// Link -#define tp_link_human_frontroll_addr 0x803e3958 -#define tp_link_human_sidestep_addr 0x803e3a00 -#define tp_link_human_backjump_addr 0x803e39c8 -#define tp_link_human_slide_addr 0x803e3a68 -#define tp_link_human_swim_addr 0x803e4ec8 -#define tp_link_wolf_general_addr 0x803e4fc4 -#define tp_link_wolf_swim_addr 0x803e5a50 - -// Inventory -#define tp_execItemGet_addr 0x80091d6c - -// Scene -#define tp_setTimePass_addr 0x8002be74 - -// GX -#define GXSetBlendMode_addr 0x803602cc -#define GXBegin_addr 0x8035d1dc -#define GXSetVtxAttrFmt_addr 0x8035c064 -#define GXLoadPosMtxImm_addr 0x803608b0 -#define GXSetNumIndStages_addr 0x8035f83c -#define GXSetTevDirect_addr 0x8035f85c -#define GXSetAlphaCompare_addr 0x8035fd38 -#define GXSetZMode_addr 0x80360374 -#define GXSetTevOp_addr 0x8035f8fc -#define GXSetNumChans_addr 0x8035e4a4 -#define GXSetNumTevStages_addr 0x8035ff58 -#define GXSetNumTexGens_addr 0x8035c6c0 -#define GXSetTevOrder_addr 0x8035fdfc -#define GXSetTevColorIn_addr 0x8035f990 -#define GXSetTevAlphaIn_addr 0x8035f9d0 -#define GXSetTevColorOp_addr 0x8035fa10 -#define GXSetTevAlphaOp_addr 0x8035fa68 -#define GXSetCullMode_addr 0x8035d4a4 -#define GXLoadTexMtxImm_addr 0x80360978 -#define GXSetChanCtrl_addr 0x8035e4c8 -#define GXSetCurrentMtx_addr 0x80360958 -#define GXSetTexCoordGen2_addr 0x8035c498 -#define GXSetLineWidth_addr 0x8035d400 -#define GXClearVtxDesc_addr 0x8035c030 -#define GXSetVtxDesc_addr 0x8035b9e4 -#define GXFlush_addr 0x8035c770 -#define GXInitTexObj_addr 0x8035e750 -#define GXLoadTexObj_addr 0x8035ec94 -#define GXInvalidateTexAll_addr 0x8035ee78 -#define GXSetProjection_addr 0x803607c0 -#define GXSetScissor_addr 0x80360b08 -#define GXGetScissor_addr 0x80360b70 -#define wgPipe_addr 0xCC008000 - -// misc functions (sort later) -#define tp_cDyl_InitAsync_addr 0x8001e300 -#define tp_fapGm_Execute_addr 0x8001e6b0 -#define tp_draw_console_addr 0x802fb3ac -#define tp_PADRead_addr 0x8037a0d0 -#define tp_setSpecialGravity_addr 0x800b2898 -#define tp_checkCastleTownUseItem_addr 0x800b6d6c -#define tp_query042_addr 0x80238c6c -#define tp_cc_at_check_addr 0x800846b4 - -// d_save -#define dSv_player_item_c__setItem_addr 0x80037738 -#define dSv_player_item_c__getItem_addr 0x80039ee0 -#define dSv_player_item_record_c__setBombNum_addr 0x80038318 -#define dSv_player_item_record_c__getBombNum_addr 0x80038324 -#define dSv_player_status_a_c__getSelectItemIndex_addr 0x800372c8 -#define dSv_player_status_b_c__isTransformLV_addr 0x8003743c -#define dSv_player_status_b_c__onTransformLV_addr 0x80037420 -#define dSv_light_drop_c__setLightDropNum_addr 0x80038620 -#define dSv_light_drop_c__getLightDropNum_addr 0x80038638 -#define dSv_info_c__onSwitch_addr 0x800393f4 -#define dSv_info_c__offSwitch_addr 0x800394b4 -#define dSv_memBit_c__isSwitch_addr 0x80038ab8 -#define dSv_memBit_c__onSwitch_addr 0x80038a68 -#define dSv_memBit_c__offSwitch_addr 0x80038a90 -#define dSv_memBit_c__isDungeonItem_addr 0x80038b88 -#define dSv_memBit_c__onDungeonItem_addr 0x80038b6c -#define dSv_player_get_item_c__onFirstBit_addr 0x80038224 -#define dSv_player_get_item_c__offFirstBit_addr 0x80038250 -#define dSv_event_c__isEventBit_addr 0x80038bf4 -#define dSv_event_c__offEventBit_addr 0x80038bdc -#define dSv_event_c__onEventBit_addr 0x80038bc4 -#define dSv_player_get_item_c__isFirstBit_addr 0x8003827c -#define dSv_player_return_place_c__set_addr 0x800374b4 - -// d_meter2_info -#define g_meter2_info_addr 0x804bcb78 - -// d_com_inf_game -#define dComIfGs_setSelectItemIndex_addr 0x800323d4 -#define dComIfGs_getMixItemIndex_addr 0x800324c0 -#define dComIfGs_setMixItemIndex_addr 0x80032418 -#define dComIfGs_onZoneSwitch_addr 0x8003207c -#define dComIfGs_onOneZoneSwitch_addr 0x800321b0 - -// d_stage -#define dStage_nextStage_c__set_addr 0x8002897c - -// d_menu_window -#define dMw_c__isEventCheck_addr 0x801e3334 - -// JKernel -#define JKernel__operator_new_addr 0x802e2b2c -#define JKernel__operator_delete_addr 0x802e2b74 -#define JKRArchive__getResource2_addr 0x802e8cac -#define tp_zeldaHeap_addr 0x8053a884 -#define tp_gameHeap_addr 0x8053a880 -#define tp_archiveHeap_addr 0x8053a88c -#define JKRExpHeap__getUsedSize_addr 0x802e3ba4 -#define JKRHeap__getFreeSize_addr 0x802e2680 -#define JKRHeap__getTotalFreeSize_addr 0x802e2690 -#define JKRExpHeap__do_getTotalFreeSize_addr 0x802e3b40 -#define JKRHeap__alloc_addr 0x802e2468 - -// J3DSys -#define j3dSys_addr 0x804c3620 - -// J3DPacket -#define J3DDrawBuffer__entryImm_addr 0x8032f8f4 -#define J3DPacket__entry_addr 0x80322cf4 - -// J2DPicture -#define J2DPicture__J2DPicture4_addr 0x8030ef10 -#define J2DPicture__draw_addr 0x80310278 - -// J2DPane -#define J2DPane__J2DPane1_addr 0x80308834 - -// J2DTextBox -#define J2DTextBox__J2DTextBox1_addr 0x80311cf4 -#define J2DTextBox__setFont_addr 0x80312830 -#define J2DTextBox__setString_addr 0x80312bc8 -#define J2DTextBox__draw2_addr 0x80312a20 - -// d_a_alink -#define daAlink_c__checkStageName_addr 0x80096734 - -// f_op_actor_mng -#define fopAcM_create_addr 0x8001f868 -#define g_fopAcTg_Queue_addr 0x8047e138 - -// f_op_actor_iter -#define fopAcIt_Judge_addr 0x8001f460 - -// f_pc_searcher -#define fpcSch_JudgeForPName_addr 0x80028150 - -// d_kankyo -#define g_env_light_addr 0x804b944c - -// d_s_play -#define sPauseTimer_addr 0x8053ae1d - -// m_Do_ext -#define mDoExt_getMesgFont_addr 0x800198e4 - -// m_Do_controller_pad -#define mDoCPd_c__m_gamePad_addr 0x8044ba50 - -// m_Do_mtx -#define mDoMtx_stack_c__now_addr 0x80453500 -#define mDoMtx_XYZrotM__addr 0x8001283c -#define mDoMtx_stack_c__scaleM_addr 0x80013454 - -#endif - -#ifdef WII_PAL -// System -#define tp_memset_addr 0x8000443c -#define tp_memalign_addr 0x8024db10 -#define tp_free_addr 0x8024db30 -#define tp_osReport_addr 0x800091e0 -#define tp_memcpy_addr 0x80004338 -#define tp_getLayerNo_addr 0x8002f77c -#define tp_getSave_addr 0x80039518 -#define tp_putSave_addr 0x80039548 -#define tp_sprintf_addr 0x803ae1a0 -#define tp_strcpy_addr 0x803ae3b0 -#define tp_strlen_addr 0x803a89f4 -#define tp_strcmp_addr 0x803ae4e0 - -// Math -#define tp_atan_addr 0x803b239c -#define tp_ceil_addr 0x803b25dc -#define tp_copysign_addr 0x803b271c -#define tp_cos_addr 0x803b2748 -#define tp_floor_addr 0x803b281c -#define tp_frexp_addr 0x803b2960 -#define tp_ldexp_addr 0x803b29e8 -#define tp_sin_addr 0x803b2b54 -#define tp_tan_addr 0x803b2c2c -#define tp_acos_addr 0x803b2ca4 -#define tp_asin_addr 0x803b2ca8 -#define tp_atan2_addr 0x803b2cac -#define tp_exp_addr 0x803b2cb0 -#define tp_fmod_addr 0x803b2cb4 -#define tp_pow_addr 0x803b2cb8 -#define tp_fastSqrt_addr 0x8025c5ac -#define tp_sqrt_addr 0x803b2f04 - -// Controller -#define tp_mPadStatus_addr 0x804a9890 -#define tp_mPadButton_addr 0x804a98c0 -#define tp_mPadMStick_addr 0x804a9980 -#define tp_mPadSStick_addr 0x804a99c0 -#define tp_mPad_addr 0x80433a68 -#define tp_JUTGamePadRead_addr 0x802df164 -#define tp_cPadInfo_addr 0x80433968 - -// TP -#define tp_globalCounters_addr 0x804a5cf8 -#define tp_zelAudio_addr 0x804325ac -#define tp_gameInfo_addr 0x8047a828 -#define tp_sConsole_addr 0x805210a8 -#define tp_fopScnRq_addr 0x805210f0 -#define tp_titleScreenPtr_addr 0x804692e0 -#define tp_matrixPtr_addr 0x80466268 -#define tp_rng_addr 0x80521638 -#define tp_homeMenuSts_addr 0x80521130 - -// Items -#define tp_clawshot_addr 0x803d0b9c -#define tp_clawshot_checkbg_addr 0x800fd364 -#define tp_ironboots_addr 0x803d09d0 -#define tp_spinner_addr 0x803d0c0c -#define tp_ball_and_chain_addr 0x803d0c4c -#define tp_bottle_addr 0x803d0ae8 - -// Actor -#define tp_actor_addr 0x80521190 -#define tp_actor_stopstatus_addr 0x805210d4 - -// Draw -#define tp_draw_addr 0x804a34f8 - -// Link -#define tp_link_human_frontroll_addr 0x803cf998 -#define tp_link_human_sidestep_addr 0x803cfa40 -#define tp_link_human_backjump_addr 0x803cfa08 -#define tp_link_human_slide_addr 0x803cfaa8 -#define tp_link_human_swim_addr 0x803d0f08 -#define tp_link_wolf_general_addr 0x803d1004 -#define tp_link_wolf_swim_addr 0x803d1a90 - -// Inventory -#define tp_execItemGet_addr 0x800920d8 - -// Scene -#define tp_setTimePass_addr 0x8002bfb0 - -// GX -#define GXSetBlendMode_addr 0x8034b134 -#define GXBegin_addr 0x80348044 -#define GXSetVtxAttrFmt_addr 0x80346ecc -#define GXLoadPosMtxImm_addr 0x8034b718 -#define GXSetNumIndStages_addr 0x8034a6a4 -#define GXSetTevDirect_addr 0x8034a6c4 -#define GXSetAlphaCompare_addr 0x8034aba0 -#define GXSetZMode_addr 0x8034b1dc -#define GXSetTevOp_addr 0x8034a764 -#define GXSetNumChans_addr 0x8034930c -#define GXSetNumTevStages_addr 0x8034adc0 -#define GXSetNumTexGens_addr 0x80347528 -#define GXSetTevOrder_addr 0x8034ac64 -#define GXSetTevColorIn_addr 0x8034a7f8 -#define GXSetTevAlphaIn_addr 0x8034a838 -#define GXSetTevColorOp_addr 0x8034a878 -#define GXSetTevAlphaOp_addr 0x8034a8d0 -#define GXSetCullMode_addr 0x8034830c -#define GXLoadTexMtxImm_addr 0x8034b7e0 -#define GXSetChanCtrl_addr 0x80349330 -#define GXSetCurrentMtx_addr 0x8034b7c0 -#define GXSetTexCoordGen2_addr 0x80347300 -#define GXSetLineWidth_addr 0x80348268 -#define GXClearVtxDesc_addr 0x80346e98 -#define GXSetVtxDesc_addr 0x8034684c -#define GXFlush_addr 0x803475d8 -#define GXInitTexObj_addr 0x803495b8 -#define GXLoadTexObj_addr 0x80349afc -#define GXInvalidateTexAll_addr 0x80349ce0 -#define GXSetProjection_addr 0x8034b628 -#define GXSetScissor_addr 0x8034b970 -#define GXGetScissor_addr 0x8034b9d8 -#define wgPipe_addr 0xCC008000 - -// misc functions (sort later) -#define tp_cDyl_InitAsync_addr 0x8001e4b8 -#define tp_fapGm_Execute_addr 0x8001e868 -#define tp_draw_console_addr 0x802e61ac -#define tp_PADRead_addr 0x80364f8c -#define tp_setSpecialGravity_addr 0x800b2d2c -#define tp_checkCastleTownUseItem_addr 0x800b7210 -#define tp_query042_addr 0x802383bc -#define tp_cc_at_check_addr 0x80084a40 - -// d_save -#define dSv_player_item_c__setItem_addr 0x80037904 -#define dSv_player_item_c__getItem_addr 0x8003a15c -#define dSv_player_item_record_c__setBombNum_addr 0x800384e4 -#define dSv_player_item_record_c__getBombNum_addr 0x800384f0 -#define dSv_player_status_a_c__getSelectItemIndex_addr 0x80037494 -#define dSv_player_status_b_c__isTransformLV_addr 0x80037608 -#define dSv_player_status_b_c__onTransformLV_addr 0x800375ec -#define dSv_light_drop_c__setLightDropNum_addr 0x800387ec -#define dSv_light_drop_c__getLightDropNum_addr 0x80038804 -#define dSv_info_c__onSwitch_addr 0x80039670 -#define dSv_info_c__offSwitch_addr 0x80039730 -#define dSv_memBit_c__isSwitch_addr 0x80038d34 -#define dSv_memBit_c__onSwitch_addr 0x80038ce4 -#define dSv_memBit_c__offSwitch_addr 0x80038d0c -#define dSv_memBit_c__isDungeonItem_addr 0x80038e04 -#define dSv_memBit_c__onDungeonItem_addr 0x80038de8 -#define dSv_player_get_item_c__onFirstBit_addr 0x800383f0 -#define dSv_player_get_item_c__offFirstBit_addr 0x8003841c -#define dSv_event_c__isEventBit_addr 0x80038e70 -#define dSv_event_c__offEventBit_addr 0x80038e58 -#define dSv_event_c__onEventBit_addr 0x80038e40 -#define dSv_player_get_item_c__isFirstBit_addr 0x80038448 -#define dSv_player_return_place_c__set_addr 0x80037680 - -// d_meter2_info -#define g_meter2_info_addr 0x804a4ab8 - -// d_com_inf_game -#define dComIfGs_setSelectItemIndex_addr 0x80032590 -#define dComIfGs_getMixItemIndex_addr 0x8003267c -#define dComIfGs_setMixItemIndex_addr 0x800325d4 -#define dComIfGs_onZoneSwitch_addr 0x800338ac -#define dComIfGs_onOneZoneSwitch_addr 0x800339e0 - -// d_stage -#define dStage_nextStage_c__set_addr 0x80028b40 - -// d_menu_window -#define dMw_c__isEventCheck_addr 0x801e2760 - -// JKernel -#define JKernel__operator_new_addr 0x802cd92c -#define JKernel__operator_delete_addr 0x802cd974 -#define JKRArchive__getResource2_addr 0x802d49a0 -#define tp_zeldaHeap_addr 0x80521044 -#define tp_gameHeap_addr 0x80521040 -#define tp_archiveHeap_addr 0x8052104c -#define JKRExpHeap__getUsedSize_addr 0x802ce9a4 -#define JKRHeap__getFreeSize_addr 0x802cd480 -#define JKRHeap__getTotalFreeSize_addr 0x802cd490 -#define JKRExpHeap__do_getTotalFreeSize_addr 0x802ce940 -#define JKRHeap__alloc_addr 0x802cd268 - -// J3DSys -#define j3dSys_addr 0x804a9fc0 - -// J3DPacket -#define J3DDrawBuffer__entryImm_addr 0x8031a6f4 -#define J3DPacket__entry_addr 0x8030daf4 - -// J2DPicture -#define J2DPicture__J2DPicture4_addr 0x802f9d10 -#define J2DPicture__draw_addr 0x802fb078 - -// J2DPane -#define J2DPane__J2DPane1_addr 0x802f3634 - -// J2DTextBox -#define J2DTextBox__J2DTextBox1_addr 0x802fcaf4 -#define J2DTextBox__setFont_addr 0x802fd630 -#define J2DTextBox__setString_addr 0x802fd9c8 -#define J2DTextBox__draw2_addr 0x802fd820 - -// d_a_alink -#define daAlink_c__checkStageName_addr 0x80098268 - -// f_op_actor_mng -#define fopAcM_create_addr 0x80021024 -#define g_fopAcTg_Queue_addr 0x80466038 - -// f_op_actor_iter -#define fopAcIt_Judge_addr 0x80020c1c - -// f_pc_searcher -#define fpcSch_JudgeForPName_addr 0x80029944 - -// d_kankyo -#define g_env_light_addr 0x8047b274 - -// d_s_play -#define sPauseTimer_addr 0x805215f5 - -// m_Do_ext -#define mDoExt_getMesgFont_addr 0x8001998c - -// m_Do_controller_pad -#define mDoCPd_c__m_gamePad_addr 0x80433958 - -// m_Do_mtx -#define mDoMtx_stack_c__now_addr 0x8043b408 -#define mDoMtx_XYZrotM__addr 0x800128dc -#define mDoMtx_stack_c__scaleM_addr 0x800134f4 - -#endif - -#ifdef WII_NTSCU_12 -// System -#define tp_memset_addr 0x8000443c -#define tp_memalign_addr 0x8024d6a8 -#define tp_free_addr 0x8024d6c8 -#define tp_osReport_addr 0x80009218 -#define tp_memcpy_addr 0x80004338 -#define tp_getLayerNo_addr 0x8002f6c8 -#define tp_getSave_addr 0x8003944c -#define tp_putSave_addr 0x8003947c -#define tp_sprintf_addr 0x803add1c -#define tp_strcpy_addr 0x803adf2c -#define tp_strlen_addr 0x803a8570 -#define tp_strcmp_addr 0x803ae05c - -// Math -#define tp_atan_addr 0x803b1f18 -#define tp_ceil_addr 0x803b2158 -#define tp_copysign_addr 0x803b2298 -#define tp_cos_addr 0x803b22c4 -#define tp_floor_addr 0x803b2398 -#define tp_frexp_addr 0x803b24dc -#define tp_ldexp_addr 0x803b2564 -#define tp_sin_addr 0x803b26d0 -#define tp_tan_addr 0x803b27a8 -#define tp_acos_addr 0x803b2820 -#define tp_asin_addr 0x803b2824 -#define tp_atan2_addr 0x803b2828 -#define tp_exp_addr 0x803b282c -#define tp_fmod_addr 0x803b2830 -#define tp_pow_addr 0x803b2834 -#define tp_fastSqrt_addr 0x8025c144 -#define tp_sqrt_addr 0x803b2a80 - -// Controller -#define tp_mPadStatus_addr 0x804a8f70 -#define tp_mPadButton_addr 0x804a8fa0 -#define tp_mPadMStick_addr 0x804a9060 -#define tp_mPadSStick_addr 0x804a90a0 -#define tp_mPad_addr 0x80433168 -#define tp_JUTGamePadRead_addr 0x802ded34 -#define tp_cPadInfo_addr 0x80433068 - -// TP -#define tp_globalCounters_addr 0x804a53e0 -#define tp_zelAudio_addr 0x80431cac -#define tp_gameInfo_addr 0x80479f30 -#define tp_sConsole_addr 0x805208e8 -#define tp_fopScnRq_addr 0x80520930 -#define tp_titleScreenPtr_addr 0x804689e8 -#define tp_matrixPtr_addr 0x80465970 -#define tp_rng_addr 0x80520e78 -#define tp_homeMenuSts_addr 0x80520970 - -// Items -#define tp_clawshot_addr 0x803cfe5c -#define tp_clawshot_checkbg_addr 0x800fd338 -#define tp_ironboots_addr 0x803cfc90 -#define tp_spinner_addr 0x803cfecc -#define tp_ball_and_chain_addr 0x803cff0c -#define tp_bottle_addr 0x803cfda8 - -// Actor -#define tp_actor_addr 0x805209d0 -#define tp_actor_stopstatus_addr 0x80520914 - -// Draw -#define tp_draw_addr 0x804a2be0 - -// Link -#define tp_link_human_frontroll_addr 0x803cec58 -#define tp_link_human_sidestep_addr 0x803ced00 -#define tp_link_human_backjump_addr 0x803cecc8 -#define tp_link_human_slide_addr 0x803ced68 -#define tp_link_human_swim_addr 0x803d01c8 -#define tp_link_wolf_general_addr 0x803d02c4 -#define tp_link_wolf_swim_addr 0x803d0d50 - -// Inventory -#define tp_execItemGet_addr 0x80092070 - -// Scene -#define tp_setTimePass_addr 0x8002befc - -// GX -#define GXSetBlendMode_addr 0x8034ad04 -#define GXBegin_addr 0x80347c14 -#define GXSetVtxAttrFmt_addr 0x80346a9c -#define GXLoadPosMtxImm_addr 0x8034b2e8 -#define GXSetNumIndStages_addr 0x8034a274 -#define GXSetTevDirect_addr 0x8034a294 -#define GXSetAlphaCompare_addr 0x8034a770 -#define GXSetZMode_addr 0x8034adac -#define GXSetTevOp_addr 0x8034a334 -#define GXSetNumChans_addr 0x80348edc -#define GXSetNumTevStages_addr 0x8034a990 -#define GXSetNumTexGens_addr 0x803470f8 -#define GXSetTevOrder_addr 0x8034a834 -#define GXSetTevColorIn_addr 0x8034a3c8 -#define GXSetTevAlphaIn_addr 0x8034a408 -#define GXSetTevColorOp_addr 0x8034a448 -#define GXSetTevAlphaOp_addr 0x8034a4a0 -#define GXSetCullMode_addr 0x80347edc -#define GXLoadTexMtxImm_addr 0x8034b3b0 -#define GXSetChanCtrl_addr 0x80348f00 -#define GXSetCurrentMtx_addr 0x8034b390 -#define GXSetTexCoordGen2_addr 0x80346ed0 -#define GXSetLineWidth_addr 0x80347e38 -#define GXClearVtxDesc_addr 0x80346a68 -#define GXSetVtxDesc_addr 0x8034641c -#define GXFlush_addr 0x803471a8 -#define GXInitTexObj_addr 0x80349188 -#define GXLoadTexObj_addr 0x803496cc -#define GXInvalidateTexAll_addr 0x803498b0 -#define GXSetProjection_addr 0x8034b1f8 -#define GXSetScissor_addr 0x8034b540 -#define GXGetScissor_addr 0x8034b5a8 -#define wgPipe_addr 0xCC008000 - -// misc functions (sort later) -#define tp_cDyl_InitAsync_addr 0x8001e3ec -#define tp_fapGm_Execute_addr 0x8001e79c -#define tp_draw_console_addr 0x802e5d7c -#define tp_PADRead_addr 0x80364b08 -#define tp_setSpecialGravity_addr 0x800b2cf0 -#define tp_checkCastleTownUseItem_addr 0x800b71d4 -#define tp_query042_addr 0x80238468 -#define tp_cc_at_check_addr 0x800849d8 - -// d_save -#define dSv_player_item_c__setItem_addr 0x80037850 -#define dSv_player_item_c__getItem_addr 0x8003a090 -#define dSv_player_item_record_c__setBombNum_addr 0x80038430 -#define dSv_player_item_record_c__getBombNum_addr 0x8003843c -#define dSv_player_status_a_c__getSelectItemIndex_addr 0x800373e0 -#define dSv_player_status_b_c__isTransformLV_addr 0x80037554 -#define dSv_player_status_b_c__onTransformLV_addr 0x80037538 -#define dSv_light_drop_c__setLightDropNum_addr 0x80038738 -#define dSv_light_drop_c__getLightDropNum_addr 0x80038750 -#define dSv_info_c__onSwitch_addr 0x800395a4 -#define dSv_info_c__offSwitch_addr 0x80039664 -#define dSv_memBit_c__isSwitch_addr 0x80038c68 -#define dSv_memBit_c__onSwitch_addr 0x80038c18 -#define dSv_memBit_c__offSwitch_addr 0x80038c40 -#define dSv_memBit_c__isDungeonItem_addr 0x80038d38 -#define dSv_memBit_c__onDungeonItem_addr 0x80038d1c -#define dSv_player_get_item_c__onFirstBit_addr 0x8003833c -#define dSv_player_get_item_c__offFirstBit_addr 0x80038368 -#define dSv_event_c__isEventBit_addr 0x80038da4 -#define dSv_event_c__offEventBit_addr 0x80038d8c -#define dSv_event_c__onEventBit_addr 0x80038d74 -#define dSv_player_get_item_c__isFirstBit_addr 0x80038394 -#define dSv_player_return_place_c__set_addr 0x800375cc - -// d_meter2_info -#define g_meter2_info_addr 0x804a41a0 - -// d_com_inf_game -#define dComIfGs_setSelectItemIndex_addr 0x800324dc -#define dComIfGs_getMixItemIndex_addr 0x800325c8 -#define dComIfGs_setMixItemIndex_addr 0x80032520 -#define dComIfGs_onZoneSwitch_addr 0x80032184 -#define dComIfGs_onOneZoneSwitch_addr 0x800322b8 - -// d_stage -#define dStage_nextStage_c__set_addr 0x80028a8c - -// d_menu_window -#define dMw_c__isEventCheck_addr 0x801e2a58 - -// JKernel -#define JKernel__operator_new_addr 0x802cd4fc -#define JKRArchive__getResource2_addr 0x802d367c - -// J2DPicture -#define J2DPicture__J2DPicture4_addr 0x802f98e0 -#define J2DPicture__draw_addr 0x802fac48 - -// d_a_alink -#define daAlink_c__checkStageName_addr 0x80096b4c - -// f_op_actor_mng -#define fopAcM_create_addr 0x8001f954 - -// f_op_actor_iter -#define fopAcIt_Judge_addr 0x8001f54c - -// f_pc_searcher -#define fpcSch_JudgeForPName_addr 0x80028260 - -// d_kankyo -#define g_env_light_addr 0x804a0a54 - -#endif -#endif // !REL_MODULE - -#endif // LIB_TP_ADDRS \ No newline at end of file diff --git a/external/libtp_c/include/d/a/d_a_alink.h b/external/libtp_c/include/d/a/d_a_alink.h index 994ae937..5b855f38 100644 --- a/external/libtp_c/include/d/a/d_a_alink.h +++ b/external/libtp_c/include/d/a/d_a_alink.h @@ -82,6 +82,9 @@ class daAlink_footData_c { Mtx field_0x74; }; // Size = 0xA4 +class daAlink_c; +typedef int (daAlink_c::*daAlink_procFunc)(); + class daAlink_c : public daPy_py_c { public: enum daAlink_ANM { @@ -104,150 +107,358 @@ class daAlink_c : public daPy_py_c { }; enum daAlink_PROC { - PREACTION_UNEQUIP, - SERVICE_WAIT, - HUMAN_WAIT = 3, - HUMAN_SIDESTEP = 10, - HUMAN_SIDESTEP_LAND, - HUMAN_SLIDE, - FRONT_ROLL = 14, - FRONT_ROLL_CRASH, - HUMAN_KNOCKBACK, - SIDE_ROLL, - BACK_JUMP, - BACK_JUMP_LAND, - SLIP, - HUMAN_AUTOJUMP, - DIVE_JUMP, - ROLL_JUMP, - FALL, - LAND, - SMALL_JUMP, - STEP_MOVE, - GUARD_SLIP = 29, - GUARD_ATTACK, - GUARD_BREAK, - TURN_MOVE, - CUT_NORMAL, - CUT_FINISH, - CUT_FINISH_JUMP_UP, - CUT_FINISH_JUMP_UP_LAND, - CUT_REVERSE, - CUT_JUMP, - CUT_JUMP_LAND, - COMBO_CUT_TURN, - CUT_CHARGE, - CUT_TURN_MOVE, - CUT_DOWN, - CUT_DOWN_LAND, - CUT_HEAD, - CUT_HEAD_LAND, - CUT_LARGE_JUMP_CHARGE, - CUT_LARGE_JUMP, - CUT_LARGE_JUMP_LAND, - DAMAGE, - LAND_DAMAGE = 52, - CRAWL_START, - CRAWL_MOVE, - CRAWL_AUTOMOVE, - CRAWL_END, - PULL_MOVE, - HORSE_RIDE, - HORSE_GETOFF, - HORSE_TURN = 61, - HORSE_JUMP, - HORSE_LAND, - HORSE_SUBJECTIVITY, - HORSE_CUT, - HORSE_CUT_CHARGE_READY, - HORSE_CUT_TURN, - HORSE_DAMAGE, - RIDE_BOW_READY, - HORSE_BOTTLE_DRINK = 76, - HORSE_KANDELAAR_POUR = 78, - HORSE_RUN, - HORSE_HANG, - BOAR_RUN = 83, - HANG_START = 85, - HANG_FALL_START, - HANG_UP, - HANG_WAIT, - HANG_MOVE, - COPY_ROD_SWING = 101, - GRAB_READY = 108, - GRAB_UP, - GRAB_THROW = 111, - GRAB_DOWN, - GRAB_REBOUND = 114, - GRAB_STAND, - INSECT_CATCH, - PICK_UP, - PICK_PUT, - HUMAN_ST_ESCAPE, - CLIMB_MOVE_VERTICAL = 130, - CLIMB_MOVE_HORIZONTAL, - CANOE_RIDE = 140, - CANOE_JUMP_RIDE, - CANOE_GETOFF, - CANOE_ROW = 144, - CANOE_PADDLE_SHIFT, - CANOE_PADDLE_PUT, - CANOE_PADDLE_GRAB, - CANOE_ROD_GRAB, - CANOE_FISHING_REEL = 150, - CANOE_FISHING_GET, - CANOE_SUBJECTIVITY, - CANOE_BOTTLE_DRINK = 160, - CANOE_KANDELAAR_POUR, - FISHING_FOOD = 163, - BOARD_CUT_TURN = 173, - FM_CHAIN_UP, - BOTTLE_DRINK = 179, - EMPTY_BOTTLE_SWING = 181, - GRASS_WHISTLE = 186, - HAWK_WAIT = 188, - FLOOR_DOWN_REBOUND = 189, - GORON_RIDE_WAIT, - GOAT_THROW = 192, - GOAT_STROKE, - MAGNE_BOOTS_FLY = 204, - BOOTS_EQUIP, - SUMOU_PUSH = 207, - SUMOU_SIDE_MOVE, - SUMOU_ACTION, - SUMOU_STAGGER, - SUMOU_WIN_LOSE, - BOSS_ENEMY_HANG = 220, - SCREAM_WAIT = 222, - DUNGEON_WARP_READY = 234, - WOLF_HOWL = 237, - WOLF_WAIT = 241, - WOLF_DASH = 243, - WOLF_KNOCKBACK = 244, - WOLF_SIDESTEP = 247, - WOLF_AUTOJUMP = 252, - WOLF_RSIT = 255, - WOLF_DAMAGE = 263, - WOLF_SLIDE = 271, - WOLF_ROPE_HANG = 275, - WOLF_TAGLOCK_JUMP = 280, - WOLF_TAGLOCK_LAND, - WOLF_DOWNATTACK_PULLOUT = 291, - WOLF_JUMPATTACK = 284, - WOLF_ST_ESCAPE = 289, - WOLF_CHAIN = 305, - WOLF_DIG, - WOLF_ENEMY_HANG_BITE = 310, - SUBJECTIVITY = 318, - POLY_DAMAGE = 321, - ELEC_DAMAGE, - PUSH_PULL_WAIT, - PUSH_MOVE, - TRESURE_STAND = 328, - METAMORPHOSE = 333, - DEAD = 336, - LARGE_DAMAGE = 345, - LARGE_DAMAGE_WALL, + /* 0x000 */ PROC_PREACTION_UNEQUIP, + /* 0x001 */ PROC_SERVICE_WAIT, + /* 0x002 */ PROC_TIRED_WAIT, + /* 0x003 */ PROC_WAIT, + /* 0x004 */ PROC_MOVE, + /* 0x005 */ PROC_ATN_MOVE, + /* 0x006 */ PROC_ATN_ACTOR_WAIT, + /* 0x007 */ PROC_ATN_ACTOR_MOVE, + /* 0x008 */ PROC_WAIT_TURN, + /* 0x009 */ PROC_MOVE_TURN, + /* 0x00A */ PROC_SIDESTEP, + /* 0x00B */ PROC_SIDESTEP_LAND, + /* 0x00C */ PROC_SLIDE, + /* 0x00D */ PROC_SLIDE_LAND, + /* 0x00E */ PROC_FRONT_ROLL, + /* 0x00F */ PROC_FRONT_ROLL_CRASH, + /* 0x010 */ PROC_FRONT_ROLL_SUCCESS, + /* 0x011 */ PROC_SIDE_ROLL, + /* 0x012 */ PROC_BACK_JUMP, + /* 0x013 */ PROC_BACK_JUMP_LAND, + /* 0x014 */ PROC_SLIP, + /* 0x015 */ PROC_AUTO_JUMP, + /* 0x016 */ PROC_DIVE_JUMP, + /* 0x017 */ PROC_ROLL_JUMP, + /* 0x018 */ PROC_FALL, + /* 0x019 */ PROC_LAND, + /* 0x01A */ PROC_SMALL_JUMP, + /* 0x01B */ PROC_STEP_MOVE, + /* 0x01C */ PROC_CROUCH, + /* 0x01D */ PROC_GUARD_SLIP, + /* 0x01E */ PROC_GUARD_ATTACK, + /* 0x01F */ PROC_GUARD_BREAK, + /* 0x020 */ PROC_TURN_MOVE, + /* 0x021 */ PROC_CUT_NORMAL, + /* 0x022 */ PROC_CUT_FINISH, + /* 0x023 */ PROC_CUT_FINISH_JUMP_UP, + /* 0x024 */ PROC_CUT_FINISH_JUMP_UP_LAND, + /* 0x025 */ PROC_CUT_REVERSE, + /* 0x026 */ PROC_CUT_JUMP, + /* 0x027 */ PROC_CUT_JUMP_LAND, + /* 0x028 */ PROC_CUT_TURN, + /* 0x029 */ PROC_CUT_TURN_CHARGE, + /* 0x02A */ PROC_CUT_TURN_MOVE, + /* 0x02B */ PROC_CUT_DOWN, + /* 0x02C */ PROC_CUT_DOWN_LAND, + /* 0x02D */ PROC_CUT_HEAD, + /* 0x02E */ PROC_CUT_HEAD_LAND, + /* 0x02F */ PROC_CUT_LARGE_JUMP_CHARGE, + /* 0x030 */ PROC_CUT_LARGE_JUMP, + /* 0x031 */ PROC_CUT_LARGE_JUMP_LAND, + /* 0x032 */ PROC_DAMAGE, + /* 0x033 */ PROC_LARGE_DAMAGE_UP, + /* 0x034 */ PROC_LAND_DAMAGE, + /* 0x035 */ PROC_CRAWL_START, + /* 0x036 */ PROC_CRAWL_MOVE, + /* 0x037 */ PROC_CRAWL_AUTO_MOVE, + /* 0x038 */ PROC_CRAWL_END, + /* 0x039 */ PROC_PULL_MOVE, + /* 0x03A */ PROC_HORSE_RIDE, + /* 0x03B */ PROC_HORSE_GETOFF, + /* 0x03C */ PROC_HORSE_WAIT, + /* 0x03D */ PROC_HORSE_TURN, + /* 0x03E */ PROC_HORSE_JUMP, + /* 0x03F */ PROC_HORSE_LAND, + /* 0x040 */ PROC_HORSE_SUBJECTIVITY, + /* 0x041 */ PROC_HORSE_CUT, + /* 0x042 */ PROC_HORSE_CUT_CHARGE_READY, + /* 0x043 */ PROC_HORSE_CUT_TURN, + /* 0x044 */ PROC_HORSE_DAMAGE, + /* 0x045 */ PROC_HORSE_BOW_SUBJECT, + /* 0x046 */ PROC_HORSE_BOW_MOVE, + /* 0x047 */ PROC_HORSE_GRAB_MOVE, + /* 0x048 */ PROC_HORSE_BOOMERANG_SUBJECT, + /* 0x049 */ PROC_HORSE_BOOMERANG_MOVE, + /* 0x04A */ PROC_HORSE_HOOKSHOT_SUBJECT, + /* 0x04B */ PROC_HORSE_HOOKSHOT_MOVE, + /* 0x04C */ PROC_HORSE_BOTTLE_DRINK, + /* 0x04D */ PROC_HORSE_COMEBACK, + /* 0x04E */ PROC_HORSE_KANDELAAR_POUR, + /* 0x04F */ PROC_HORSE_RUN, + /* 0x050 */ PROC_HORSE_HANG, + /* 0x051 */ PROC_HORSE_GET_KEY, + /* 0x052 */ PROC_HORSE_LOOK_DOWN, + /* 0x053 */ PROC_BOAR_RUN, + /* 0x054 */ PROC_SWORD_UNEQUIP_SP, + /* 0x055 */ PROC_HANG_START, + /* 0x056 */ PROC_HANG_FALL_START, + /* 0x057 */ PROC_HANG_UP, + /* 0x058 */ PROC_HANG_WAIT, + /* 0x059 */ PROC_HANG_MOVE, + /* 0x05A */ PROC_HANG_CLIMB, + /* 0x05B */ PROC_HANG_WALL_CATCH, + /* 0x05C */ PROC_HANG_READY, + /* 0x05D */ PROC_HANG_LEVER_DOWN, + /* 0x05E */ PROC_BOW_SUBJECT, + /* 0x05F */ PROC_BOW_MOVE, + /* 0x060 */ PROC_BOOMERANG_SUBJECT, + /* 0x061 */ PROC_BOOMERANG_MOVE, + /* 0x062 */ PROC_BOOMERANG_CATCH, + /* 0x063 */ PROC_COPY_ROD_SUBJECT, + /* 0x064 */ PROC_COPY_ROD_MOVE, + /* 0x065 */ PROC_COPY_ROD_SWING, + /* 0x066 */ PROC_COPY_ROD_REVIVE, + /* 0x067 */ PROC_LADDER_UP_START, + /* 0x068 */ PROC_LADDER_UP_END, + /* 0x069 */ PROC_LADDER_DOWN_START, + /* 0x06A */ PROC_LADDER_DOWN_END, + /* 0x06B */ PROC_LADDER_MOVE, + /* 0x06C */ PROC_GRAB_READY, + /* 0x06D */ PROC_GRAB_UP, + /* 0x06E */ PROC_GRAB_MISS, + /* 0x06F */ PROC_GRAB_THROW, + /* 0x070 */ PROC_GRAB_PUT, + /* 0x071 */ PROC_GRAB_WAIT, + /* 0x072 */ PROC_GRAB_REBOUND, + /* 0x073 */ PROC_GRAB_STAND, + /* 0x074 */ PROC_INSECT_CATCH, + /* 0x075 */ PROC_PICK_UP, + /* 0x076 */ PROC_PICK_PUT, + /* 0x077 */ PROC_HUMAN_ST_ESCAPE, + /* 0x078 */ PROC_DK_CAUGHT, + /* 0x079 */ PROC_SWIM_UP, + /* 0x07A */ PROC_SWIM_WAIT, + /* 0x07B */ PROC_SWIM_MOVE, + /* 0x07C */ PROC_SWIM_DIVE, + /* 0x07D */ PROC_SWIM_HOOKSHOT_SUBJECT, + /* 0x07E */ PROC_SWIM_HOOKSHOT_MOVE, + /* 0x07F */ PROC_SWIM_DAMAGE, + /* 0x080 */ PROC_CLIMB_UP_START, + /* 0x081 */ PROC_CLIMB_DOWN_START, + /* 0x082 */ PROC_CLIMB_MOVE_UPDOWN, + /* 0x083 */ PROC_CLIMB_MOVE_SIDE, + /* 0x084 */ PROC_CLIMB_WAIT, + /* 0x085 */ PROC_CLIMB_TO_ROOF, + /* 0x086 */ PROC_ROOF_HANG_START, + /* 0x087 */ PROC_ROOF_HANG_WAIT, + /* 0x088 */ PROC_ROOF_HANG_FRONT_MOVE, + /* 0x089 */ PROC_ROOF_HANG_SIDE_MOVE, + /* 0x08A */ PROC_ROOF_HANG_TURN, + /* 0x08B */ PROC_ROOF_SWITCH_HANG, + /* 0x08C */ PROC_CANOE_RIDE, + /* 0x08D */ PROC_CANOE_JUMP_RIDE, + /* 0x08E */ PROC_CANOE_GETOFF, + /* 0x08F */ PROC_CANOE_WAIT, + /* 0x090 */ PROC_CANOE_ROW, + /* 0x091 */ PROC_CANOE_PADDLE_SHIFT, + /* 0x092 */ PROC_CANOE_PADDLE_PUT, + /* 0x093 */ PROC_CANOE_PADDLE_GRAB, + /* 0x094 */ PROC_CANOE_ROD_GRAB, + /* 0x095 */ PROC_CANOE_FISHING_WAIT, + /* 0x096 */ PROC_CANOE_FISHING_REEL, + /* 0x097 */ PROC_CANOE_FISHING_GET, + /* 0x098 */ PROC_CANOE_SUBJECTIVITY, + /* 0x099 */ PROC_CANOE_BOW_SUBJECT, + /* 0x09A */ PROC_CANOE_BOW_MOVE, + /* 0x09B */ PROC_CANOE_GRAB_MOVE, + /* 0x09C */ PROC_CANOE_BOOMERANG_SUBJECT, + /* 0x09D */ PROC_CANOE_BOOMERANG_MOVE, + /* 0x09E */ PROC_CANOE_HOOKSHOT_SUBJECT, + /* 0x09F */ PROC_CANOE_HOOKSHOT_MOVE, + /* 0x0A0 */ PROC_CANOE_BOTTLE_DRINK, + /* 0x0A1 */ PROC_CANOE_KANDELAAR_POUR, + /* 0x0A2 */ PROC_FISHING_CAST, + /* 0x0A3 */ PROC_FISHING_FOOD, + /* 0x0A4 */ PROC_SPINNER_READY, + /* 0x0A5 */ PROC_SPINNER_WAIT, + /* 0x0A6 */ PROC_BOARD_RIDE, + /* 0x0A7 */ PROC_BOARD_WAIT, + /* 0x0A8 */ PROC_BOARD_ROW, + /* 0x0A9 */ PROC_BOARD_TURN, + /* 0x0AA */ PROC_BOARD_JUMP, + /* 0x0AB */ PROC_BOARD_SUBJECTIVITY, + /* 0x0AC */ PROC_BOARD_CUT, + /* 0x0AD */ PROC_BOARD_CUT_TURN, + /* 0x0AE */ PROC_CHAIN_UP, + /* 0x0AF */ PROC_CHAIN_STRONG_PULL, + /* 0x0B0 */ PROC_DOOR_OPEN, + /* 0x0B1 */ PROC_MONKEY_MOVE, + /* 0x0B2 */ PROC_DEMO_BOOMERANG_CATCH, + /* 0x0B3 */ PROC_BOTTLE_DRINK, + /* 0x0B4 */ PROC_BOTTLE_OPEN, + /* 0x0B5 */ PROC_BOTTLE_SWING, + /* 0x0B6 */ PROC_BOTTLE_GET, + /* 0x0B7 */ PROC_KANDELAAR_SWING, + /* 0x0B8 */ PROC_KANDELAAR_POUR, + /* 0x0B9 */ PROC_GRASS_WHISTLE_GET, + /* 0x0BA */ PROC_GRASS_WHISTLE_WAIT, + /* 0x0BB */ PROC_HAWK_CATCH, + /* 0x0BC */ PROC_HAWK_SUBJECT, + /* 0x0BD */ PROC_FLOOR_DOWN_REBOUND, + /* 0x0BE */ PROC_GORON_RIDE_WAIT, + /* 0x0BF */ PROC_GOAT_MOVE, + /* 0x0C0 */ PROC_GOAT_CATCH, + /* 0x0C1 */ PROC_GOAT_STROKE, + /* 0x0C2 */ PROC_GORON_MOVE, + /* 0x0C3 */ PROC_BOSS_ATN_WAIT, + /* 0x0C4 */ PROC_HOOKSHOT_SUBJECT, + /* 0x0C5 */ PROC_HOOKSHOT_MOVE, + /* 0x0C6 */ PROC_HOOKSHOT_FLY, + /* 0x0C7 */ PROC_HOOKSHOT_ROOF_WAIT, + /* 0x0C8 */ PROC_HOOKSHOT_ROOF_SHOOT, + /* 0x0C9 */ PROC_HOOKSHOT_ROOF_BOOTS, + /* 0x0CA */ PROC_HOOKSHOT_WALL_WAIT, + /* 0x0CB */ PROC_HOOKSHOT_WALL_SHOOT, + /* 0x0CC */ PROC_MAGNE_BOOTS_FLY, + /* 0x0CD */ PROC_BOOTS_EQUIP, + /* 0x0CE */ PROC_SUMOU_READY, + /* 0x0CF */ PROC_SUMOU_MOVE, + /* 0x0D0 */ PROC_SUMOU_SIDE_MOVE, + /* 0x0D1 */ PROC_SUMOU_ACTION, + /* 0x0D2 */ PROC_SUMOU_STAGGER, + /* 0x0D3 */ PROC_SUMOU_WIN_LOSE, + /* 0x0D4 */ PROC_SUMOU_SHIKO, + /* 0x0D5 */ PROC_LOOK_UP, + /* 0x0D6 */ PROC_LOOK_UP_TO_GET_ITEM, + /* 0x0D7 */ PROC_HAND_PAT, + /* 0x0D8 */ PROC_IRON_BALL_SUBJECT, + /* 0x0D9 */ PROC_IRON_BALL_MOVE, + /* 0x0DA */ PROC_IRON_BALL_THROW, + /* 0x0DB */ PROC_IRON_BALL_RETURN, + /* 0x0DC */ PROC_BOSS_BODY_HANG, + /* 0x0DD */ PROC_OCTAIEAL_SPIT, + /* 0x0DE */ PROC_SCREAM_WAIT, + /* 0x0DF */ PROC_GOAT_STOP_READY, + /* 0x0E0 */ PROC_ZORA_MOVE, + /* 0x0E1 */ PROC_LOOK_AROUND_TURN, + /* 0x0E2 */ PROC_TRADE_ITEM_OUT, + /* 0x0E3 */ PROC_NOT_USE_ITEM, + /* 0x0E4 */ PROC_SWORD_READY, + /* 0x0E5 */ PROC_SWORD_PUSH, + /* 0x0E6 */ PROC_GANON_FINISH, + /* 0x0E7 */ PROC_CUT_FAST_READY, + /* 0x0E8 */ PROC_MASTER_SWORD_STICK, + /* 0x0E9 */ PROC_MASTER_SWORD_PULL, + /* 0x0EA */ PROC_DUNGEON_WARP_READY, + /* 0x0EB */ PROC_DUNGEON_WARP, + /* 0x0EC */ PROC_DUNGEON_WARP_SCN_START, + /* 0x0ED */ PROC_WOLF_HOWL_DEMO, + /* 0x0EE */ PROC_WOLF_SERVICE_WAIT, + /* 0x0EF */ PROC_WOLF_TIRED_WAIT, + /* 0x0F0 */ PROC_WOLF_MIDNA_RIDE_SHOCK, + /* 0x0F1 */ PROC_WOLF_WAIT, + /* 0x0F2 */ PROC_WOLF_MOVE, + /* 0x0F3 */ PROC_WOLF_DASH, + /* 0x0F4 */ PROC_WOLF_DASH_REVERSE, + /* 0x0F5 */ PROC_WOLF_WAIT_TURN, + /* 0x0F6 */ PROC_WOLF_ATN_AC_MOVE, + /* 0x0F7 */ PROC_WOLF_SIDESTEP, + /* 0x0F8 */ PROC_WOLF_SIDESTEP_LAND, + /* 0x0F9 */ PROC_WOLF_BACKJUMP, + /* 0x0FA */ PROC_WOLF_BACKJUMP_LAND, + /* 0x0FB */ PROC_WOLF_HOWL, + /* 0x0FC */ PROC_WOLF_AUTO_JUMP, + /* 0x0FD */ PROC_WOLF_FALL, + /* 0x0FE */ PROC_WOLF_LAND, + /* 0x0FF */ PROC_WOLF_SIT, + /* 0x100 */ PROC_WOLF_LIE_START, + /* 0x101 */ PROC_WOLF_LIE_MOVE, + /* 0x102 */ PROC_WOLF_LIE_AUTO_MOVE, + /* 0x103 */ PROC_WOLF_HANG_READY, + /* 0x104 */ PROC_WOLF_STEP_MOVE, + /* 0x105 */ PROC_WOLF_HANG_WALL_CATCH, + /* 0x106 */ PROC_WOLF_HANG_FALL_START, + /* 0x107 */ PROC_WOLF_DAMAGE, + /* 0x108 */ PROC_WOLF_LARGE_DAMAGE_UP, + /* 0x109 */ PROC_WOLF_LAND_DAMAGE, + /* 0x10A */ PROC_WOLF_SCREAM_WAIT, + /* 0x10B */ PROC_WOLF_SLIP, + /* 0x10C */ PROC_WOLF_SLIP_TURN, + /* 0x10D */ PROC_WOLF_SLIP_TURN_LAND, + /* 0x10E */ PROC_WOLF_SLIDE_READY, + /* 0x10F */ PROC_WOLF_SLIDE, + /* 0x110 */ PROC_WOLF_SLIDE_LAND, + /* 0x111 */ PROC_WOLF_WAIT_SLIP, + /* 0x112 */ PROC_WOLF_SLOPE_START, + /* 0x113 */ PROC_WOLF_ROPE_MOVE, + /* 0x114 */ PROC_WOLF_ROPE_HANG, + /* 0x115 */ PROC_WOLF_ROPE_TURN, + /* 0x116 */ PROC_WOLF_ROPE_STAGGER, + /* 0x117 */ PROC_WOLF_ROPE_SUBJECTIVITY, + /* 0x118 */ PROC_WOLF_TAG_JUMP, + /* 0x119 */ PROC_WOLF_TAG_JUMP_LAND, + /* 0x11A */ PROC_WOLF_ROLL_ATTACK_CHARGE, + /* 0x11B */ PROC_WOLF_ROLL_ATTACK_MOVE, + /* 0x11C */ PROC_WOLF_JUMP_ATTACK, + /* 0x11D */ PROC_WOLF_JUMP_AT_KICK, + /* 0x11E */ PROC_WOLF_JUMP_AT_SLIDE_LAND, + /* 0x11F */ PROC_WOLF_JUMP_AT_NORMAL_LAND, + /* 0x120 */ PROC_WOLF_WAIT_ATTACK, + /* 0x121 */ PROC_WOLF_ROLL_ATTACK, + /* 0x122 */ PROC_WOLF_DOWN_ATTACK, + /* 0x123 */ PROC_WOLF_DOWN_AT_LAND, + /* 0x124 */ PROC_WOLF_DOWN_AT_MISS_LAND, + /* 0x125 */ PROC_WOLF_LOCK_ATTACK, + /* 0x126 */ PROC_WOLF_LOCK_ATTACK_TURN, + /* 0x127 */ PROC_WOLF_SWIM_UP, + /* 0x128 */ PROC_WOLF_SWIM_WAIT, + /* 0x129 */ PROC_WOLF_SWIM_MOVE, + /* 0x12A */ PROC_WOLF_SWIM_END_WAIT, + /* 0x12B */ PROC_WOLF_GRAB_UP, + /* 0x12C */ PROC_WOLF_GRAB_PUT, + /* 0x12D */ PROC_WOLF_GRAB_THROW, + /* 0x12E */ PROC_WOLF_CHAIN_UP, + /* 0x12F */ PROC_WOLF_PUSH, + /* 0x130 */ PROC_WOLF_CHAIN_READY, + /* 0x131 */ PROC_WOLF_CHAIN_WAIT, + /* 0x132 */ PROC_WOLF_DIG, + /* 0x133 */ PROC_WOLF_DIG_THROUGH, + /* 0x134 */ PROC_WOLF_ATTACK_REVERSE, + /* 0x135 */ PROC_WOLF_ENEMY_THROW, + /* 0x136 */ PROC_WOLF_ENEMY_HANG_BITE, + /* 0x137 */ PROC_WOLF_GIANT_PUZZLE, + /* 0x138 */ PROC_WOLF_CARGO_CARRY, + /* 0x139 */ PROC_WOLF_GET_SMELL, + /* 0x13A */ PROC_WOLF_SMELL_WAIT, + /* 0x13B */ PROC_WOLF_SNOW_ESCAPE, + /* 0x13C */ PROC_WOLF_GANON_CATCH, + /* 0x13D */ PROC_TOOL_DEMO, + /* 0x13E */ PROC_SUBJECTIVITY, + /* 0x13F */ PROC_SWIM_SUBJECTIVITY, + /* 0x140 */ PROC_PEEP_SUBJECTIVITY, + /* 0x141 */ PROC_POLY_DAMAGE, + /* 0x142 */ PROC_ELEC_DAMAGE, + /* 0x143 */ PROC_PUSH_PULL_WAIT, + /* 0x144 */ PROC_PUSH_MOVE, + /* 0x145 */ PROC_TALK, + /* 0x146 */ PROC_OPEN_TREASURE, + /* 0x147 */ PROC_UNEQUIP, + /* 0x148 */ PROC_GET_ITEM, + /* 0x149 */ PROC_TURN_BACK, + /* 0x14A */ PROC_LOOK_WAIT, + /* 0x14B */ PROC_DEMO_PUSH_PULL_WAIT, + /* 0x14C */ PROC_DEMO_PUSH_MOVE, + /* 0x14D */ PROC_METAMORPHOSE, + /* 0x14E */ PROC_METAMORPHOSE_ONLY, + /* 0x14F */ PROC_WARP, + /* 0x150 */ PROC_DEAD, + /* 0x151 */ PROC_FOG_DEAD, + /* 0x152 */ PROC_LOOK_AROUND, + /* 0x153 */ PROC_CAUGHT, + /* 0x154 */ PROC_SAND_WALL_HIT, + /* 0x155 */ PROC_LAVA_RETURN, + /* 0x156 */ PROC_SWIM_FREEZE_RETURN, + /* 0x157 */ PROC_GET_READY_SIT, + /* 0x158 */ PROC_TW_GATE, + /* 0x159 */ PROC_LARGE_DAMAGE, + /* 0x15A */ PROC_LARGE_DAMAGE_WALL, + /* 0x15B */ PROC_NOD, + /* 0x15C */ PROC_EYE_AWAY, + /* 0x15D */ PROC_GLARE, + /* 0x15E */ PROC_HORSE_CALL_WAIT, + /* 0x15F */ PROC_QUAKE_WAIT, }; // this might be one of the above enums, but not clear yet @@ -268,7 +479,6 @@ class daAlink_c : public daPy_py_c { class hsChainShape_c {}; - // inlined version of checkModeFlg u32 checkModeFlg(u32 pFlag) const { return mModeFlg & pFlag; } bool checkUpperAnime(u16 pIdx) const { return mUpperAnime[UPPER_NOW].getIdx() == pIdx; } @@ -427,7 +637,7 @@ class daAlink_c : public daPy_py_c { /* 0x02B98 */ f32* field_0x2b9c; /* 0x02BA0 */ f32* field_0x2ba0; /* 0x02BA4 */ f32* field_0x2ba4; - /* 0x02BA8 */ f32* field_0x2ba8; + /* 0x02BA8 */ f32 field_0x2ba8; /* 0x02BAC */ cXyz field_0x2bac; /* 0x02BB8 */ Mtx mInvMtx; /* 0x02BE8 */ Mtx field_0x2be8; @@ -877,18 +1087,16 @@ class daAlink_c : public daPy_py_c { /* 0x03844 */ csXyz* mIronBallChainAngle; /* 0x03848 */ void* field_0x3848; /* 0x0384C */ f32* field_0x384c; - /* 0x03850 */ u32 field_0x3850; - /* 0x03854 */ u32 field_0x3854; - /* 0x03858 */ u32 field_0x3858; -}; + /* 0x03850 */ daAlink_procFunc mpProcFunc; +}; // Size: 0x385C struct daAlinkHIO_anm_c { - /* 0x00 */ s16 field_0x00; // end f? - /* 0x04 */ f32 field_0x04; // speed? - /* 0x08 */ f32 field_0x08; // start? - /* 0x0C */ f32 field_0x0c; // interpolation? - /* 0x10 */ f32 field_0x10; // CF? -}; // size = 0x14 + /* 0x00 */ s16 mEndFrame; + /* 0x04 */ f32 mSpeed; + /* 0x08 */ f32 mStartFrame; + /* 0x0C */ f32 mInterpolation; + /* 0x10 */ f32 mCheckFrame; // name maybe wrong +}; // size: 0x14 struct daAlinkHIO_basic_c1 { /* 0x00 */ bool mOneHitKill; @@ -2749,4 +2957,7 @@ extern daAlinkHIO_hookshot_c1 daAlinkHIO_hookshot; LIBTP_DEFINE_FUNC(checkStageName__9daAlink_cFPCc, daAlink_c__checkStageName_char_const___, int, daAlink_c__checkStageName, (const char*)) +LIBTP_DEFINE_FUNC(posMove__9daAlink_cFv, daAlink_c__posMove_void_, void, daAlink_c__posMove, (daAlink_c*)) +// LIBTP_DEFINE_FUNC(setSpecialGravity__9daAlink_cFffi, ) + #endif /* D_A_D_A_ALINK_H */ \ No newline at end of file diff --git a/external/libtp_c/include/d/a/d_a_npc.h b/external/libtp_c/include/d/a/d_a_npc.h new file mode 100644 index 00000000..0fc9c207 --- /dev/null +++ b/external/libtp_c/include/d/a/d_a_npc.h @@ -0,0 +1,9 @@ +#ifndef D_A_NPC_H +#define D_A_NPC_H + +#include "../../dolphin/types.h" + +LIBTP_DEFINE_FUNC(daNpcF_getDistTableIdx__Fii, daNpcF_getDistTableIdx_int__int_, + u8, daNpcF_getDistTableIdx, (int, int)) + +#endif /* D_A_NPC_H */ diff --git a/external/libtp_c/include/d/a/d_a_player.h b/external/libtp_c/include/d/a/d_a_player.h index 9677838c..229966bc 100644 --- a/external/libtp_c/include/d/a/d_a_player.h +++ b/external/libtp_c/include/d/a/d_a_player.h @@ -89,9 +89,6 @@ class daPy_py_c : public fopAc_ac_c { public: /* 0x0568 */ u8 mCutType; /* 0x0569 */ u8 mComboCutCount; -#ifdef WII_PLATFORM - u8 unk_field0[4]; // might be part of fopAc_ac_c, fix later -#endif /* 0x056A */ u8 mSpecialMode; // maybe needs better name /* 0x056B */ u8 field_0x56b; /* 0x056C */ s16 mDamageTimer; @@ -118,7 +115,7 @@ class daPy_py_c : public fopAc_ac_c { /* 0x05EC */ cXyz mRightFootPosP; /* 0x05F8 */ u8 field_0x5f8[0xC]; /* 0x0604 */ daPy_demo_c mDemo; - void* vtable; + /* 0x0628 */ void* vtable_base; public: enum daPy_FLG0 { diff --git a/external/libtp_c/include/d/bg/d_bg_s.h b/external/libtp_c/include/d/bg/d_bg_s.h index 1998e0ce..ccdac877 100644 --- a/external/libtp_c/include/d/bg/d_bg_s.h +++ b/external/libtp_c/include/d/bg/d_bg_s.h @@ -5,19 +5,24 @@ #include "../../SSystem/SComponent/c_bg_s_lin_chk.h" #include "../bg/d_bg_w.h" +class fopAc_ac_c; + class cBgS_ChkElm { - /* 0x00 */ dBgW_Base* bgw_base_pointer; - /* 0x04 */ u8 used; - /* 0x05 */ u8 padding[3]; +public: + /* 0x00 */ dBgW_Base* m_bgw_base_ptr; + /* 0x04 */ bool m_used; /* 0x08 */ u32 field_0x8; - /* 0x0C */ void* actor_pointer; + /* 0x0C */ fopAc_ac_c* m_actor_ptr; /* 0x10 */ void* vtable; + + bool ChkUsed() const { return m_used; } }; // Size = 0x14 static_assert(sizeof(cBgS_ChkElm) == 0x14); class cBgS { - /* 0x0000 */ cBgS_ChkElm cbgs_elements[256]; +public: + /* 0x0000 */ cBgS_ChkElm m_chk_element[256]; /* 0x1400 */ void* vtable; }; // Size = 0x1404 diff --git a/external/libtp_c/include/d/bg/d_bg_s_acch.h b/external/libtp_c/include/d/bg/d_bg_s_acch.h index 183c633b..2fb9cf74 100644 --- a/external/libtp_c/include/d/bg/d_bg_s_acch.h +++ b/external/libtp_c/include/d/bg/d_bg_s_acch.h @@ -13,61 +13,142 @@ class dBgS_AcchCir { public: + enum { + /* 0x2 */ WALL_HIT = 2, + /* 0x4 */ WALL_H_DIRECT = 4, + }; + + f32 GetWallH() { return m_wall_h; } + f32 GetWallR() { return m_wall_r; } + void SetWallH(f32 h) { m_wall_h = h; } + void ClrWallHDirect() { m_flags &= ~WALL_H_DIRECT; } + bool ChkWallHit() { return m_flags & WALL_HIT; } + s16 GetWallAngleY() { return m_wall_angle_y; } + /* 0x00 */ cBgS_PolyInfo mPolyInfo; - /* 0x10 */ int mWallHit; - /* 0x14 */ cM3dGCir m3DGCir; - /* 0x28 */ f32 mWallRR; + /* 0x10 */ u32 m_flags; + /* 0x14 */ cM3dGCir m_cir; + /* 0x28 */ f32 m_wall_rr; /* 0x2C */ f32 field_0x2c; - /* 0x30 */ f32 mWallH; - /* 0x34 */ f32 mWallR; - /* 0x38 */ f32 mWallHDirect; - /* 0x3C */ s16 mWallAngleY; - /* 0x3E */ u8 padding[2]; + /* 0x30 */ f32 m_wall_h; + /* 0x34 */ f32 m_wall_r; + /* 0x38 */ f32 m_wall_h_direct; + /* 0x3C */ s16 m_wall_angle_y; }; class dBgS_Acch { public: - f32 GetGroundH() const { return mGroundH; } - void OnLineCheckNone() { mHitParam |= 0x4000; } - void OffLineCheckNone() { mHitParam &= ~0x4000; } - void SetWallNone() { mHitParam |= 4; } - void OffWallNone() { mHitParam &= ~4; } + enum { + /* 0x000002 */ GRND_NONE = (1 << 1), + /* 0x000004 */ WALL_NONE = (1 << 2), + /* 0x000008 */ ROOF_NONE = (1 << 3), + /* 0x000010 */ WALL_HIT = (1 << 4), + /* 0x000020 */ GROUND_HIT = (1 << 5), + /* 0x000040 */ GROUND_FIND = (1 << 6), + /* 0x000080 */ GROUND_LANDING = (1 << 7), + /* 0x000100 */ GROUND_AWAY = (1 << 8), + /* 0x000200 */ ROOF_HIT = (1 << 9), + /* 0x000400 */ WATER_NONE = (1 << 10), + /* 0x000800 */ WATER_HIT = (1 << 11), + /* 0x001000 */ WATER_IN = (1 << 12), + /* 0x002000 */ LINE_CHECK = (1 << 13), + /* 0x004000 */ LINE_CHECK_NONE = (1 << 14), + /* 0x008000 */ CLR_SPEED_Y = (1 << 15), + /* 0x010000 */ LINE_CHECK_HIT = (1 << 16), + /* 0x100000 */ MOVE_BG_ONLY = (1 << 20), + /* 0x200000 */ GND_THIN_CELLING_OFF = (1 << 21), + /* 0x400000 */ WALL_SORT = (1 << 22), + /* 0x800000 */ LINE_DOWN = (1 << 23), + }; + + cXyz* GetPos() { return pm_pos; } + cXyz* GetOldPos() { return pm_old_pos; } + f32 GetGroundH() const { return m_ground_h; } + f32 GetRoofHeight() const { return m_roof_height; } + int GetTblSize() { return m_tbl_size; } + bool ChkGroundFind() { return m_flags & GROUND_FIND; } + bool ChkGroundHit() { return m_flags & GROUND_HIT; } + bool ChkGroundLanding() { return m_flags & GROUND_LANDING; } + void ClrGroundLanding() { m_flags &= ~GROUND_LANDING; } + void ClrGroundAway() { m_flags &= ~GROUND_AWAY; } + void ClrWallHit() { m_flags &= ~WALL_HIT; } + void SetRoofNone() { m_flags |= ROOF_NONE; } + void SetRoofHit() { m_flags |= ROOF_HIT; } + void SetWaterNone() { m_flags |= WATER_NONE; } + bool ChkWallHit() { return m_flags & WALL_HIT; } + void OffLineCheckHit() { m_flags &= ~LINE_CHECK_HIT; } + void OffLineCheck() { m_flags &= ~LINE_CHECK; } + bool ChkLineCheckNone() { return m_flags & LINE_CHECK_NONE; } + bool ChkLineCheck() { return m_flags & LINE_CHECK; } + void ClrRoofHit() { m_flags &= ~ROOF_HIT; } + void ClrWaterHit() { m_flags &= ~WATER_HIT; } + void SetWaterHit() { m_flags |= WATER_HIT; } + void ClrWaterIn() { m_flags &= ~WATER_IN; } + void SetWaterIn() { m_flags |= WATER_IN; } + const u32 MaskWaterIn() { return m_flags & WATER_IN; } + const bool ChkWaterIn() { return MaskWaterIn();} + void ClrGroundFind() { m_flags &= ~GROUND_FIND; } + u32 MaskRoofHit() { return m_flags & ROOF_HIT; } + bool ChkRoofHit() { return MaskRoofHit(); } + bool ChkClrSpeedY() { return !(m_flags & CLR_SPEED_Y); } + void SetGroundFind() { m_flags |= GROUND_FIND; } + void SetGroundHit() { m_flags |= GROUND_HIT; } + void SetGroundLanding() { m_flags |= GROUND_LANDING; } + void SetGroundAway() { m_flags |= GROUND_AWAY; } + const u32 MaskWaterHit() { return m_flags & WATER_HIT; } + const bool ChkWaterHit() { return MaskWaterHit(); } + void ClrWaterNone() { m_flags &= ~WATER_NONE; } + void SetWaterCheckOffset(f32 offset) { m_wtr_chk_offset = offset; } + void OnLineCheck() { m_flags |= LINE_CHECK; } + void ClrRoofNone() { m_flags &= ~ROOF_NONE; } + void SetRoofCrrHeight(f32 height) { m_roof_crr_height = height; } + void SetWtrChkMode(int mode) { m_wtr_mode = mode; } + void SetGrndNone() { m_flags |= GRND_NONE; } + void ClrGrndNone() { m_flags &= ~GRND_NONE; } + bool ChkMoveBGOnly() const { return m_flags & MOVE_BG_ONLY; } + void SetWallHit() { m_flags |= WALL_HIT; } + void ClrWallNone() { m_flags &= ~WALL_NONE; } + void OnLineCheckNone() { m_flags |= LINE_CHECK_NONE; } + void OffLineCheckNone() { m_flags &= ~LINE_CHECK_NONE; } + void SetWallNone() { m_flags |= WALL_NONE; } + void OnLineCheckHit() { m_flags |= LINE_CHECK_HIT; } + cM3dGCyl* GetWallBmdCylP() { return &m_wall_cyl; } /* 0x000 */ cBgS_Chk field_0x000; /* 0x014 */ dBgS_Chk field_0x014; - /* 0x02C */ u32 mHitParam; - /* 0x030 */ cXyz* mPos; - /* 0x034 */ cXyz* mOldPos; - /* 0x038 */ cXyz* mSpeed; - /* 0x03C */ csXyz* mAngle; - /* 0x040 */ csXyz* mShapeAngle; - /* 0x044 */ cM3dGLin field_0x44; - /* 0x060 */ cM3dGCyl mWallBmdCyl; - /* 0x078 */ int field_0x78; + /* 0x02C */ u32 m_flags; + /* 0x030 */ cXyz* pm_pos; + /* 0x034 */ cXyz* pm_old_pos; + /* 0x038 */ cXyz* pm_speed; + /* 0x03C */ csXyz* pm_angle; + /* 0x040 */ csXyz* pm_shape_angle; + /* 0x044 */ cM3dGLin m_lin; + /* 0x060 */ cM3dGCyl m_wall_cyl; + /* 0x078 */ int m_bg_index; /* 0x07C */ void* field_0x7c; /* 0x080 */ u32 field_0x80; - /* 0x084 */ fopAc_ac_c* mMyAc; + /* 0x084 */ fopAc_ac_c* m_my_ac; /* 0x088 */ int m_tbl_size; - /* 0x08C */ dBgS_AcchCir* field_0x8c; + /* 0x08C */ dBgS_AcchCir* pm_acch_cir; /* 0x090 */ f32 field_0x90; /* 0x094 */ f32 field_0x94; - /* 0x098 */ f32 mGroundH; + /* 0x098 */ f32 m_ground_h; /* 0x09C */ f32 field_0x9c; /* 0x0A0 */ cM3dGPla field_0xa0; - /* 0x0B4 */ u8 field_0xb4[4]; + /* 0x0B4 */ u8 field_0xb4; /* 0x0B8 */ f32 field_0xb8; /* 0x0BC */ f32 field_0xbc; - /* 0x0C0 */ u8 field_0xc0[4]; - /* 0x0C4 */ f32 mRoofHeight; - /* 0x0C8 */ f32 mRoofCrrHeight; + /* 0x0C0 */ u8 field_0xc0; + /* 0x0C4 */ f32 m_roof_height; + /* 0x0C8 */ f32 m_roof_crr_height; /* 0x0CC */ f32 field_0xcc; - /* 0x0D0 */ f32 mWaterCheckOffset; - /* 0x0D4 */ int field_0xd4; + /* 0x0D0 */ f32 m_wtr_chk_offset; + /* 0x0D4 */ cBgS_PolyInfo* pm_out_poly_info; /* 0x0D8 */ f32 field_0xd8; - /* 0x0DC */ dBgS_GndChk mGndChk; - /* 0x130 */ dBgS_RoofChk mRoofChk; - /* 0x180 */ dBgS_WtrChk mWtrChk; - /* 0x1D4 */ u8 mWtrChkMode; + /* 0x0DC */ dBgS_GndChk m_gnd; + /* 0x130 */ dBgS_RoofChk m_roof; + /* 0x180 */ dBgS_WtrChk m_wtr; + /* 0x1D4 */ u8 m_wtr_mode; }; class dBgS_LinkAcch : public dBgS_Acch {}; diff --git a/external/libtp_c/include/d/bg/d_bg_s_captpoly.h b/external/libtp_c/include/d/bg/d_bg_s_captpoly.h new file mode 100644 index 00000000..50baef5b --- /dev/null +++ b/external/libtp_c/include/d/bg/d_bg_s_captpoly.h @@ -0,0 +1,33 @@ +#ifndef D_BG_S_CAPTPOLY_H +#define D_BG_S_CAPTPOLY_H + +#include "d_bg_s_chk.h" +#include "d_bg_w.h" +#include "../../SSystem/SComponent/c_m3d_g_aab.h" +#include "../../SSystem/SComponent/c_bg_s_chk.h" + +class cM3dGPla; + +struct cBgD_Vtx_t { + Vec vertex; +}; + +typedef int (*dBgS_CaptCallback)(dBgS_CaptPoly*, cBgD_Vtx_t*, int, int, int, cM3dGPla*); + +class dBgS_CaptPoly { +public: + dBgS_CaptPoly() { + field_0x00.SetPolyPassChk(&field_0x14.mPolyPassChkInfo); + field_0x00.SetGrpPassChk(&field_0x14.mGrpPassChkInfo); + mpCallback = NULL; + } + + /* 0x00 */ cBgS_Chk field_0x00; + /* 0x14 */ dBgS_Chk field_0x14; + /* 0x2C */ cM3dGAab mAab; + /* 0x48 */ dBgS_CaptCallback mpCallback; +}; + +static_assert(sizeof(dBgS_CaptPoly) == 0x4C); + +#endif /* D_BG_S_CAPTPOLY_H */ diff --git a/external/libtp_c/include/d/bg/d_bg_s_chk.h b/external/libtp_c/include/d/bg/d_bg_s_chk.h index 7be8b38a..dad99401 100644 --- a/external/libtp_c/include/d/bg/d_bg_s_chk.h +++ b/external/libtp_c/include/d/bg/d_bg_s_chk.h @@ -10,4 +10,6 @@ class dBgS_Chk { /* 0x010 */ dBgS_GrpPassChk mGrpPassChkInfo; }; // Size = 0x18 +static_assert(sizeof(dBgS_Chk) == 0x18); + #endif /* D_BG_D_BG_S_CHK_H */ diff --git a/external/libtp_c/include/d/bg/d_bg_s_grp_pass_chk.h b/external/libtp_c/include/d/bg/d_bg_s_grp_pass_chk.h index 6656a0d4..c1a75928 100644 --- a/external/libtp_c/include/d/bg/d_bg_s_grp_pass_chk.h +++ b/external/libtp_c/include/d/bg/d_bg_s_grp_pass_chk.h @@ -2,14 +2,26 @@ #define D_BG_D_BG_S_GRP_PASS_CHK_H #include "../../dolphin/types.h" - -class cBgS_GrpPassChk { -public: - virtual ~cBgS_GrpPassChk() {} -}; +#include "../../SSystem/SComponent/c_bg_s_chk.h" class dBgS_GrpPassChk : public cBgS_GrpPassChk { public: + dBgS_GrpPassChk() { + mGrp = 1; + } + + enum { + /* 0x1 */ NORMAL_GRP = 1, + /* 0x2 */ WATER_GRP + }; + + void OnWaterGrp() { mGrp |= WATER_GRP; } + void OnSpl() { mGrp |= WATER_GRP; } + void OnNormalGrp() { mGrp |= NORMAL_GRP; } + void OffNormalGrp() { mGrp &= ~NORMAL_GRP; } + void OnFullGrp() { mGrp |= 3; } + +private: u32 mGrp; }; diff --git a/external/libtp_c/include/d/bg/d_bg_s_poly_pass_chk.h b/external/libtp_c/include/d/bg/d_bg_s_poly_pass_chk.h index 646da3cd..9834f59c 100644 --- a/external/libtp_c/include/d/bg/d_bg_s_poly_pass_chk.h +++ b/external/libtp_c/include/d/bg/d_bg_s_poly_pass_chk.h @@ -3,11 +3,25 @@ class cBgS_PolyPassChk { public: - virtual ~cBgS_PolyPassChk(); + void* vtable; }; class dBgS_PolyPassChk : public cBgS_PolyPassChk { public: + dBgS_PolyPassChk() { + mObject = false; + mCamera = false; + mLink = false; + mArrow = false; + mBomb = false; + mBoomerang = false; + mRope = false; + mUnderwaterRoof = false; + mHorse = false; + mStatue = false; + mIronBall = false; + } + bool ChkArrow() { return mArrow; } bool ChkBomb() { return mBomb; } bool ChkBoomerang() { return mBoomerang; } diff --git a/external/libtp_c/include/d/bg/d_bg_w.h b/external/libtp_c/include/d/bg/d_bg_w.h index bdd83e29..b1a9e820 100644 --- a/external/libtp_c/include/d/bg/d_bg_w.h +++ b/external/libtp_c/include/d/bg/d_bg_w.h @@ -3,19 +3,108 @@ #include "../../dolphin/types.h" -#pragma pack(push, 1) -class dBgW_Base { +class dBgS_CaptPoly; +class cBgS_PolyInfo; +class fopAc_ac_c; + +struct cBgW__vtable { + /* 0x00 */ void* RTTI; + /* 0x04 */ void* field_0x04; + /* 0x08 */ void* dtor; + /* 0x0C */ void* ChkMemoryError; + /* 0x10 */ void* ChkNotReady; + /* 0x14 */ void* ChkLock; + /* 0x18 */ void* ChkMoveBg; + /* 0x1C */ void* ChkMoveFlag; + /* 0x20 */ void* GetTriPla; + /* 0x24 */ void* GetTriPnt; + /* 0x28 */ void* GetBnd; + /* 0x2C */ void* GetGrpInf; + /* 0x30 */ void* OffMoveFlag; + /* 0x34 */ void* GetTopUnder; + /* 0x38 */ void* SetOldShapeAngleY; + /* 0x3C */ void* LineCheck; + /* 0x40 */ void* GroundCross; + /* 0x44 */ void* ShdwDraw; + /* 0x48 */ void (*CaptPoly)(void* i_this, dBgS_CaptPoly&); + /* 0x4C */ void* WallCorrect; + /* 0x50 */ void* WallCorrectSort; + /* 0x54 */ void* RoofChk; + /* 0x58 */ void* SplGrpChk; + /* 0x5C */ void* SphChk; + /* 0x60 */ void* GetGrpRoomIndex; + /* 0x64 */ int (*GetExitId)(void* i_this); + /* 0x68 */ void* GetPolyColor; + /* 0x6C */ void* GetHorseNoEntry; + /* 0x70 */ void* GetSpecialCode; + /* 0x74 */ void* GetSpecialCode2; + /* 0x78 */ void* GetMagnetCode; + /* 0x7C */ void* GetPolyObjThrough; + /* 0x80 */ void* GetPolyCamThrough; + /* 0x84 */ void* GetPolyLinkThrough; + /* 0x88 */ void* GetPolyArrowThrough; + /* 0x8C */ void* GetPolyHSStick; + /* 0x90 */ void* GetPolyBoomerangThrough; + /* 0x94 */ void* GetPolyRopeThrough; + /* 0x98 */ void* GetPolyBombThrough; + /* 0x9C */ void* GetShdwThrough; + /* 0xA0 */ void* GetUnderwaterRoofCode; + /* 0xA4 */ void* GetMonkeyBarsCode; + /* 0xA8 */ void* GetLinkNo; + /* 0xAC */ void* GetWallCode; + /* 0xB0 */ void* GetPolyAtt0; + /* 0xB4 */ void* GetPolyAtt1; + /* 0xB8 */ void* GetGroundCode; + /* 0xBC */ void* GetIronBallThrough; + /* 0xC0 */ void* GetAttackThrough; + /* 0xC4 */ void* GetCamMoveBG; + /* 0xC8 */ void* GetRoomCamId; + /* 0xCC */ void* GetRoomPathId; + /* 0xD0 */ void* GetRoomPathPntNo; + /* 0xD4 */ void* GetPolyGrpRoomInfId; + /* 0xD8 */ void* GetGrpSoundId; + /* 0xDC */ void* CrrPos; + /* 0xE0 */ void* TransPos; + /* 0xE4 */ void* MatrixCrrPos; + /* 0xE8 */ void* CallRideCallBack; + /* 0xEC */ void* CallArrowStickCallBack; +}; + +class cBgW_BgId { public: -private: - u16 field_0x0; - u8 field_0x2[2]; - void* field_0x4; - u8 field_0x8; - u8 field_0x9; - u8 field_0xa; - u8 field_0xb; - s16 field_0xc; - s16 field_0xe; + /* 0x0 */ u16 m_id; + /* 0x4 */ cBgW__vtable* vtable; + + cBgW_BgId() { Ct(); } + void Ct() { m_id = 0x100; } }; -#pragma pack(pop) + +class dBgW_Base : public cBgW_BgId { +public: + enum PushPullLabel {}; + + typedef s32 (*PushPull_CallBack)(cBgS_PolyInfo const&, fopAc_ac_c*, s16, + dBgW_Base::PushPullLabel); + + PushPull_CallBack GetPushPullCallback() const { return m_pushPull_Callback; } + s16 GetDiffShapeAngleY() { return m_diff_ShapeAngleY; } + u8 GetRoomId() { return m_roomId; } + bool chkStickWall() { return field_0xb & 1; } + bool chkStickRoof() { return field_0xb & 2; } + + /* 0x08 */ u8 m_priority; + /* 0x09 */ u8 m_roomId; + /* 0x0A */ u8 field_0xa; + /* 0x0B */ u8 field_0xb; + /* 0x0C */ s16 m_old_ShapeAngleY; + /* 0x0E */ s16 m_diff_ShapeAngleY; + /* 0x10 */ PushPull_CallBack m_pushPull_Callback; + /* 0x14 */ bool m_pushPull_Ok; +}; // Size: 0x18 + +static_assert(sizeof(dBgW_Base) == 0x18); + +LIBTP_DEFINE_FUNC(cBgW_CheckBGround__Ff, cBgW_CheckBGround_float_, bool, cBgW_CheckBGround, (f32)) +LIBTP_DEFINE_FUNC(cBgW_CheckBRoof__Ff, cBgW_CheckBRoof_float_, bool, cBgW_CheckBRoof, (f32)) + #endif /* D_BG_D_BG_W_H */ diff --git a/external/libtp_c/include/d/cc/d_cc_d.h b/external/libtp_c/include/d/cc/d_cc_d.h index 3750c114..1b6f5867 100644 --- a/external/libtp_c/include/d/cc/d_cc_d.h +++ b/external/libtp_c/include/d/cc/d_cc_d.h @@ -7,6 +7,9 @@ LIBTP_DEFINE_FUNC(ClrTgHit__12dCcD_GObjInfFv, dCcD_GObjInf__ClrTgHit_void_, void, dCcD_GObjInf__ClrTgHit, (void* addr)) +LIBTP_DEFINE_FUNC(ResetTgHit__12dCcD_GObjInfFv, dCcD_GObjInf__ResetTgHit_void_, + void, dCcD_GObjInf__ResetTgHit, (void* addr)) + enum dCcD_hitSe { /* 0 */ dCcD_SE_NONE, /* 1 */ dCcD_SE_SWORD, @@ -279,6 +282,10 @@ class dCcD_GObjInf : public cCcD_GObjInf { dCcD_GObjInf__ClrTgHit(this); } + void ResetTgHit() { + dCcD_GObjInf__ResetTgHit(this); + } + /* 0x058 */ dCcD_GObjAt mGObjAt; /* 0x09C */ dCcD_GObjTg mGObjTg; /* 0x0E8 */ dCcD_GObjCo mGObjCo; @@ -286,18 +293,46 @@ class dCcD_GObjInf : public cCcD_GObjInf { static_assert(sizeof(dCcD_GObjInf) == 0x104); +#ifndef WII_PLATFORM +#define dCcD_Cyl_vtable __vt__8dCcD_Cyl +#else +#define dCcD_Cyl_vtable dCcD_Cyl____vt +#endif + +extern "C" cCcD_GObjInf__vtbl_t dCcD_Cyl_vtable; + class dCcD_Cyl { public: dCcD_GObjInf mGObjInf; cCcD_CylAttr mCylAttr; }; // Size = 0x13C -class dCcD_Sph : public dCcD_GObjInf, public cCcD_SphAttr { +#ifndef WII_PLATFORM +#define dCcD_Sph_vtable __vt__8dCcD_Sph +#else +#define dCcD_Sph_vtable dCcD_Sph____vt +#endif + +extern "C" cCcD_GObjInf__vtbl_t dCcD_Sph_vtable; + +class dCcD_Sph { public: + dCcD_GObjInf mGObjInf; + cCcD_SphAttr mSphAttr; }; // Size = 0x138 -class dCcD_Cps : public dCcD_GObjInf, public cCcD_CpsAttr { +#ifndef WII_PLATFORM +#define dCcD_Cps_vtable __vt__8dCcD_Cps +#else +#define dCcD_Cps_vtable dCcD_Cps____vt +#endif + +extern "C" cCcD_GObjInf__vtbl_t dCcD_Cps_vtable; + +class dCcD_Cps { public: + dCcD_GObjInf mGObjInf; + cCcD_CpsAttr mCpsAttr; }; // Size = 0x144 class dCcD_Tri { diff --git a/external/libtp_c/include/d/com/d_com_inf_game.h b/external/libtp_c/include/d/com/d_com_inf_game.h index bbadd522..57e4c683 100644 --- a/external/libtp_c/include/d/com/d_com_inf_game.h +++ b/external/libtp_c/include/d/com/d_com_inf_game.h @@ -1,7 +1,6 @@ #ifndef D_COM_D_COM_INF_GAME_H #define D_COM_D_COM_INF_GAME_H -#include "../../addrs.h" #include "../save/d_save.h" #include "../bg/d_bg_s.h" #include "../cc/d_cc_s.h" @@ -345,6 +344,14 @@ extern TitleScreenInfo l_fpcNdRq_Queue; LIBTP_DEFINE_FUNC(getLayerNo_common_common__14dComIfG_play_cFPCcii, dComIfG_play_c__getLayerNo_common_common_char_const____int__int_, int, tp_getLayerNo, (const char* stageName, int roomId, int layerOverride)) +inline dBgS* dComIfG_Bgsp() { + return &g_dComIfG_gameInfo.play.mDBgS; +} + +inline dCcS* dComIfG_Ccsp() { + return &g_dComIfG_gameInfo.play.mDCcS; +} + // Inline Functions inline void dComIfGs_setItem(int slot_no, u8 item_no) { dSv_player_item_c__setItem(&g_dComIfG_gameInfo.info.getPlayer().getItem(), slot_no, item_no); diff --git a/external/libtp_c/include/d/d_attention.h b/external/libtp_c/include/d/d_attention.h index fa9b19b9..b3d11f4a 100644 --- a/external/libtp_c/include/d/d_attention.h +++ b/external/libtp_c/include/d/d_attention.h @@ -154,4 +154,17 @@ class dAttention_c { }; // Size = 0x51C static_assert(sizeof(dAttention_c) == 0x51C); +struct dAttention_dist_tbl { + f32 mDistXZMax; + f32 mDistXZMaxRelease; + f32 mDistXZAngleAdjust; + f32 mDeltaYMax; + f32 mDeltaYMin; + f32 mWeightDivisor; + int mFrontAngleCheckBits; +}; // Size: 0x1C + +LIBTP_DEFINE_FUNC(getDistTable__12dAttention_cFi, dAttention_c__getDistTable_int_, + dAttention_dist_tbl*, dAttention_c__getDistTable, (int)) + #endif /* D_D_ATTENTION_H */ diff --git a/external/libtp_c/include/d/d_item.h b/external/libtp_c/include/d/d_item.h new file mode 100644 index 00000000..c78ab05d --- /dev/null +++ b/external/libtp_c/include/d/d_item.h @@ -0,0 +1,35 @@ +#ifndef D_ITEM_H +#define D_ITEM_H + +#include "../dolphin/types.h" + +struct daItemBase_data { + /* 0x00 */ f32 mGravity; + /* 0x04 */ f32 field_0x4; + /* 0x08 */ f32 field_0x8; + /* 0x0C */ f32 field_0xc; + /* 0x10 */ f32 field_0x10; + /* 0x14 */ s16 field_0x14; + /* 0x16 */ s16 field_0x16; + /* 0x18 */ s16 field_0x18; + /* 0x1A */ s16 field_0x1a; + /* 0x1C */ s16 field_0x1c; + /* 0x20 */ f32 field_0x20; + /* 0x24 */ f32 field_0x24; + /* 0x28 */ s16 field_0x28; + /* 0x2A */ s16 field_0x2a; + /* 0x2C */ f32 field_0x2c; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ s16 field_0x34; + /* 0x36 */ s16 field_0x36; +}; + +#ifndef WII_PLATFORM +#define daItemBase__data m_data__12daItemBase_c +#else +#define daItemBase__data daItemBase_c__m_data +#endif + +extern "C" daItemBase_data daItemBase__data; + +#endif /* D_ITEM_H */ diff --git a/external/libtp_c/include/d/d_path.h b/external/libtp_c/include/d/d_path.h new file mode 100644 index 00000000..25622228 --- /dev/null +++ b/external/libtp_c/include/d/d_path.h @@ -0,0 +1,19 @@ +#ifndef D_D_PATH_H +#define D_D_PATH_H + +#include "../dolphin/types.h" + +struct dStage_dPnt_c; + +struct dPath { + /* 0x0 */ u16 m_num; + /* 0x2 */ u16 m_nextID; + /* 0x4 */ u8 field_0x4; + /* 0x5 */ u8 m_closed; + /* 0x6 */ u8 field_0x6; + /* 0x8 */ dStage_dPnt_c* m_points; +}; + +inline int dPath_ChkClose(dPath* i_path) { return (i_path->m_closed & 1); } + +#endif /* D_D_PATH_H */ diff --git a/external/libtp_c/include/d/d_procname.h b/external/libtp_c/include/d/d_procname.h index 21c6600c..a6563a37 100644 --- a/external/libtp_c/include/d/d_procname.h +++ b/external/libtp_c/include/d/d_procname.h @@ -2,798 +2,800 @@ #define D_PROCNAME_H enum { - PROC_OVERLAP0 = 0x0000, - PROC_OVERLAP1 = 0x0001, - PROC_OVERLAP3 = 0x0002, - PROC_OVERLAP6 = 0x0003, - PROC_OVERLAP7 = 0x0004, - PROC_OVERLAP8 = 0x0005, - PROC_OVERLAP9 = 0x0006, - PROC_OVERLAP10 = 0x0007, - PROC_OVERLAP11 = 0x0008, - PROC_LOGO_SCENE = 0x0009, - PROC_MENU_SCENE = 0x000A, - PROC_PLAY_SCENE = 0x000B, - PROC_OPENING_SCENE = 0x000C, - PROC_NAME_SCENE = 0x000D, - PROC_NAMEEX_SCENE = 0x000E, - PROC_WARNING_SCENE = 0x000F, - PROC_WARNING2_SCENE = 0x0010, - PROC_OVERLAP2 = 0x0011, - PROC_ROOM_SCENE = 0x0012, - PROC_KANKYO = 0x0013, - PROC_ALLDIE = 0x0014, - PROC_ENVSE = 0x0015, - PROC_Obj_Swpush = 0x0016, - PROC_Obj_Swpush2 = 0x0017, - PROC_Obj_Swpush5 = 0x0018, - PROC_Tag_Gstart = 0x0019, - PROC_NO_CHG_ROOM = 0x001A, - PROC_Obj_Lv6ElevtA = 0x001B, - PROC_OBJ_SO = 0x001C, - PROC_Obj_Movebox = 0x001D, - PROC_Obj_SwTurn = 0x001E, - PROC_Obj_Lv6SwTurn = 0x001F, - PROC_OBJ_SEKIZOA = 0x0020, - PROC_OBJ_GRA = 0x0021, - PROC_TAG_GRA = 0x0022, - PROC_TAG_YAMI = 0x0023, - PROC_Obj_Ladder = 0x0024, - PROC_OBJ_BEF = 0x0025, - PROC_OBJ_FMOBJ = 0x0026, - PROC_OBJ_LBOX = 0x0027, - PROC_OBJ_WEB0 = 0x0028, - PROC_OBJ_WEB1 = 0x0029, - PROC_OBJ_CB = 0x002A, - PROC_OBJ_MAKI = 0x002B, - PROC_OBJ_BRG = 0x002C, - PROC_OBJ_GB = 0x002D, - PROC_OBJ_GM = 0x002E, - PROC_OBJ_TOBY = 0x002F, - PROC_OBJ_TP = 0x0030, - PROC_TREESH = 0x0031, - PROC_Obj_ZDoor = 0x0032, - PROC_Obj_Pillar = 0x0033, - PROC_Obj_Cdoor = 0x0034, - PROC_GRDWATER = 0x0035, - PROC_Obj_RotBridge = 0x0036, - PROC_Obj_MagLift = 0x0037, - PROC_Obj_MagLiftRot = 0x0038, - PROC_Obj_Lv1Cdl00 = 0x0039, - PROC_Obj_Lv1Cdl01 = 0x003A, - PROC_Obj_TvCdlst = 0x003B, - PROC_Obj_HsTarget = 0x003C, - PROC_Obj_HeavySw = 0x003D, - PROC_Obj_GoGate = 0x003E, - PROC_Obj_TaFence = 0x003F, - PROC_Obj_Saidan = 0x0040, - PROC_Obj_SpinLift = 0x0041, - PROC_Obj_BmWindow = 0x0042, - PROC_Obj_RfHole = 0x0043, - PROC_Obj_WaterPillar = 0x0044, - PROC_Obj_SyRock = 0x0045, - PROC_Obj_BsGate = 0x0046, - PROC_Obj_AmiShutter = 0x0047, - PROC_Obj_WtGate = 0x0048, - PROC_Obj_Lv2Candle = 0x0049, - PROC_Obj_TogeTrap = 0x004A, - PROC_Obj_RotTrap = 0x004B, - PROC_Obj_SwallShutter = 0x004C, - PROC_Obj_IceWall = 0x004D, - PROC_Obj_Lv5SwIce = 0x004E, - PROC_Obj_Lv5FBoard = 0x004F, - PROC_Obj_Turara = 0x0050, - PROC_Obj_TwGate = 0x0051, - PROC_Obj_Digholl = 0x0052, - PROC_Obj_Digpl = 0x0053, - PROC_Obj_TestCube = 0x0054, - PROC_Obj_Kshutter = 0x0055, - PROC_NPC_COACH = 0x0056, - PROC_NPC_THEB = 0x0057, - PROC_COACH_FIRE = 0x0058, - PROC_COACH2D = 0x0059, - PROC_BALLOON2D = 0x005A, - PROC_SKIP2D = 0x005B, - PROC_Obj_MvStair = 0x005C, - PROC_Obj_Cowdoor = 0x005D, - PROC_Obj_Swpropeller = 0x005E, - PROC_Obj_BoomShutter = 0x005F, - PROC_NPC_KS = 0x0060, - PROC_Obj_Hfuta = 0x0061, - PROC_Obj_BkDoor = 0x0062, - PROC_Obj_Cboard = 0x0063, - PROC_Obj_MGate = 0x0064, - PROC_Obj_Ikada = 0x0065, - PROC_Obj_Ice_l = 0x0066, - PROC_Obj_Ice_s = 0x0067, - PROC_Obj_E_CREATE = 0x0068, - PROC_Obj_Bhbridge = 0x0069, - PROC_Obj_Kaisou = 0x006A, - PROC_Obj_HHASHI = 0x006B, - PROC_Obj_BHASHI = 0x006C, - PROC_OCTHASHI = 0x006D, - PROC_Obj_THASHI = 0x006E, - PROC_Obj_CRVGATE = 0x006F, - PROC_Obj_CRVFENCE = 0x0070, - PROC_Obj_CRVHAHEN = 0x0071, - PROC_Obj_CRVSTEEL = 0x0072, - PROC_Obj_CRVLH_UP = 0x0073, - PROC_Obj_CRVLH_DW = 0x0074, - PROC_Obj_RIVERROCK = 0x0075, - PROC_Obj_DUST = 0x0076, - PROC_Obj_ITA = 0x0077, - PROC_Obj_Window = 0x0078, - PROC_Obj_MetalBox = 0x0079, - PROC_Obj_BBox = 0x007A, - PROC_OBJ_MSIMA = 0x007B, - PROC_OBJ_MYOGAN = 0x007C, - PROC_B_ZANTS = 0x007D, - PROC_Obj_ChainBlock = 0x007E, - PROC_Obj_ChainWall = 0x007F, - PROC_Obj_KkrGate = 0x0080, - PROC_Obj_RiderGate = 0x0081, - PROC_Obj_Onsen = 0x0082, - PROC_Obj_Chest = 0x0083, - PROC_Obj_Bemos = 0x0084, - PROC_Obj_RopeBridge = 0x0085, - PROC_Obj_WellCover = 0x0086, - PROC_Obj_GraveStone = 0x0087, - PROC_Obj_ZraRock = 0x0088, - PROC_Obj_GraRock = 0x0089, - PROC_Obj_GrzRock = 0x008A, - PROC_GRA_WALL = 0x008B, - PROC_OBJ_ONSEN_FIRE = 0x008C, - PROC_Obj_Lv6bemos = 0x008D, - PROC_Obj_Lv6bemos2 = 0x008E, - PROC_Obj_BarDesk = 0x008F, - PROC_Obj_DigSnow = 0x0090, - PROC_Obj_Ytaihou = 0x0091, - PROC_Obj_Elevator = 0x0092, - PROC_Obj_Lv6TogeRoll = 0x0093, - PROC_Obj_Lv6TogeTrap = 0x0094, - PROC_Obj_Lv6Tenbin = 0x0095, - PROC_Obj_Lv6SwGate = 0x0096, - PROC_Obj_Lv6Lblock = 0x0097, - PROC_Obj_Lv6ChgGate = 0x0098, - PROC_Obj_Lv6FuriTrap = 0x0099, - PROC_Obj_Lv6SzGate = 0x009A, - PROC_Obj_Lv4EdShutter = 0x009B, - PROC_Obj_Lv4Gate = 0x009C, - PROC_Obj_Lv4PoGate = 0x009D, - PROC_Obj_Lv4SlideWall = 0x009E, - PROC_Obj_Lv4HsTarget = 0x009F, - PROC_Obj_Lv7PropY = 0x00A0, - PROC_Obj_Lv7BsGate = 0x00A1, - PROC_Obj_Lv8OptiLift = 0x00A2, - PROC_Obj_Lv8KekkaiTrap = 0x00A3, - PROC_Obj_Lv8Lift = 0x00A4, - PROC_Obj_Lv8UdFloor = 0x00A5, - PROC_Obj_Lv9SwShutter = 0x00A6, - PROC_Obj_TobyHouse = 0x00A7, - PROC_Obj_poCandle = 0x00A8, - PROC_Obj_Lv4DigSand = 0x00A9, - PROC_Obj_FallObj = 0x00AA, - PROC_Obj_SmgDoor = 0x00AB, - PROC_Obj_SwLight = 0x00AC, - PROC_Obj_Avalanche = 0x00AD, - PROC_Obj_MirrorScrew = 0x00AE, - PROC_Obj_MirrorSand = 0x00AF, - PROC_Obj_MirrorTable = 0x00B0, - PROC_Obj_MirrorChain = 0x00B1, - PROC_Obj_Mirror6Pole = 0x00B2, - PROC_Obj_SwSpinner = 0x00B3, - PROC_Obj_TDoor = 0x00B4, - PROC_Obj_Lv7Bridge = 0x00B5, - PROC_Obj_zrTurara = 0x00B6, - PROC_Obj_TakaraDai = 0x00B7, - PROC_Obj_Table = 0x00B8, - PROC_Obj_CatDoor = 0x00B9, - PROC_Obj_Gake = 0x00BA, - PROC_CSTAF = 0x00BB, - PROC_Obj_Lv4RailWall = 0x00BC, - PROC_Obj_Lv4Sand = 0x00BD, - PROC_Obj_PushDoor = 0x00BE, - PROC_PushDoor = 0x00BF, - PROC_Obj_GanonWall2 = 0x00C0, - PROC_Obj_Lv4Bridge = 0x00C1, - PROC_Obj_Lv4Floor = 0x00C2, - PROC_Tag_Spinner = 0x00C3, - PROC_Obj_SwHang = 0x00C4, - PROC_Obj_RotStair = 0x00C5, - PROC_Obj_MagneArm = 0x00C6, - PROC_Obj_KWheel00 = 0x00C7, - PROC_Obj_KWheel01 = 0x00C8, - PROC_Obj_Ychndlr = 0x00C9, - PROC_Obj_PRElvtr = 0x00CA, - PROC_Obj_MHasu = 0x00CB, - PROC_Obj_YIblltray = 0x00CC, - PROC_Obj_Lv6EGate = 0x00CD, - PROC_Obj_PDtile = 0x00CE, - PROC_Obj_PDwall = 0x00CF, - PROC_Obj_Lv4PRwall = 0x00D0, - PROC_Obj_KLift00 = 0x00D1, - PROC_B_OH = 0x00D2, - PROC_Obj_Lv4Chan = 0x00D3, - PROC_Obj_Lv3R10Saka = 0x00D4, - PROC_Obj_Lv3Water = 0x00D5, - PROC_Obj_Lv3Water2 = 0x00D6, - PROC_OBJ_LV3WATERB = 0x00D7, - PROC_Obj_HBombkoya = 0x00D8, - PROC_Obj_SZbridge = 0x00D9, - PROC_Obj_KakarikoBrg = 0x00DA, - PROC_Obj_OrdinBrg = 0x00DB, - PROC_Obj_BurnBox = 0x00DC, - PROC_Obj_KJgjs = 0x00DD, - PROC_OBJ_IHASI = 0x00DE, - PROC_Obj_IceBlock = 0x00DF, - PROC_Obj_VolcanicBall = 0x00E0, - PROC_Obj_VolcanicBomb = 0x00E1, - PROC_Obj_VolcGnd = 0x00E2, - PROC_Obj_KKanban = 0x00E3, - PROC_E_PH = 0x00E4, - PROC_NPC_ZRA = 0x00E5, - PROC_Obj_Chandelier = 0x00E6, - PROC_Obj_Stopper2 = 0x00E7, - PROC_DOOR20 = 0x00E8, - PROC_Tag_Hinit = 0x00E9, - PROC_Tag_Hjump = 0x00EA, - PROC_Tag_AJnot = 0x00EB, - PROC_Tag_Hstop = 0x00EC, - PROC_CANOE = 0x00ED, - PROC_HORSE = 0x00EE, - PROC_E_WB = 0x00EF, - PROC_OBJ_ITO = 0x00F0, - PROC_OBJ_SW = 0x00F1, - PROC_SPINNER = 0x00F2, - PROC_B_OB = 0x00F3, - PROC_KAGO = 0x00F4, - PROC_E_YC = 0x00F5, - PROC_B_DS = 0x00F6, - PROC_B_DR = 0x00F7, - PROC_B_ZANTZ = 0x00F8, - PROC_B_ZANT = 0x00F9, - PROC_B_ZANTM = 0x00FA, - PROC_TBOX = 0x00FB, - PROC_TBOX2 = 0x00FC, - PROC_ALINK = 0x00FD, - PROC_BOOMERANG = 0x00FE, - PROC_MIDNA = 0x00FF, - PROC_NPC_TK = 0x0100, - PROC_NPC_WORM = 0x0101, - PROC_PPolamp = 0x0102, - PROC_BkyRock = 0x0103, - PROC_HITOBJ = 0x0104, - PROC_EP = 0x0105, - PROC_COW = 0x0106, - PROC_PERU = 0x0107, - PROC_NI = 0x0108, - PROC_NPC_TKJ2 = 0x0109, - PROC_SQ = 0x010A, - PROC_NPC_SQ = 0x010B, - PROC_DO = 0x010C, - PROC_NPC_NE = 0x010D, - PROC_NPC_TR = 0x010E, - PROC_NPC_LF = 0x010F, - PROC_OBJ_FOOD = 0x0110, - PROC_OBJ_KI = 0x0111, - PROC_OBJ_KITA = 0x0112, - PROC_OBJ_KEY = 0x0113, - PROC_OBJ_KEYHOLE = 0x0114, - PROC_Obj_Lv5Key = 0x0115, - PROC_OBJ_LP = 0x0116, - PROC_OBJ_TATIGI = 0x0117, - PROC_OBJ_ROCK = 0x0118, - PROC_OBJ_WFLAG = 0x0119, - PROC_OBJ_KAGE = 0x011A, - PROC_OBJ_KANBAN2 = 0x011B, - PROC_OBJ_BALLOON = 0x011C, - PROC_OBJ_SUISYA = 0x011D, - PROC_OBJ_OILTUBO = 0x011E, - PROC_OBJ_ROTEN = 0x011F, - PROC_OBJ_SSDRINK = 0x0120, - PROC_OBJ_SSITEM = 0x0121, - PROC_TAG_SSDRINK = 0x0122, - PROC_TAG_BTLITM = 0x0123, - PROC_TAG_LV5SOUP = 0x0124, - PROC_TAG_MNLIGHT = 0x0125, - PROC_TAG_SHOPCAM = 0x0126, - PROC_TAG_SHOPITM = 0x0127, - PROC_OBJ_NDOOR = 0x0128, - PROC_OBJ_UDOOR = 0x0129, - PROC_OBJ_USAKU = 0x012A, - PROC_Obj_SM_DOOR = 0x012B, - PROC_OBJ_BED = 0x012C, - PROC_OBJ_BOUMATO = 0x012D, - PROC_OBJ_ITAMATO = 0x012E, - PROC_OBJ_NOUGU = 0x012F, - PROC_OBJ_STICK = 0x0130, - PROC_OBJ_MIE = 0x0131, - PROC_OBJ_SEKIDOOR = 0x0132, - PROC_OBJ_SEKIZO = 0x0133, - PROC_OBJ_SMTILE = 0x0134, - PROC_NPC_FISH = 0x0135, - PROC_MG_FISH = 0x0136, - PROC_FSHOP = 0x0137, - PROC_NPC_DU = 0x0138, - PROC_DISAPPEAR = 0x0139, - PROC_Obj_Mato = 0x013A, - PROC_Obj_Flag = 0x013B, - PROC_Obj_Flag2 = 0x013C, - PROC_Obj_Flag3 = 0x013D, - PROC_Obj_GOMIKABE = 0x013E, - PROC_Obj_Yousei = 0x013F, - PROC_Obj_Kabuto = 0x0140, - PROC_Obj_Cho = 0x0141, - PROC_Obj_Kuw = 0x0142, - PROC_Obj_Nan = 0x0143, - PROC_Obj_Dan = 0x0144, - PROC_Obj_Kam = 0x0145, - PROC_Obj_Ten = 0x0146, - PROC_Obj_Ari = 0x0147, - PROC_Obj_Kag = 0x0148, - PROC_Obj_Batta = 0x0149, - PROC_Obj_Tombo = 0x014A, - PROC_Obj_Kat = 0x014B, - PROC_Obj_H_Saku = 0x014C, - PROC_Obj_Yobikusa = 0x014D, - PROC_Obj_KazeNeko = 0x014E, - PROC_Obj_KznkArm = 0x014F, - PROC_Obj_NamePlate = 0x0150, - PROC_Obj_OnCloth = 0x0151, - PROC_Obj_LndRope = 0x0152, - PROC_Obj_ItaRope = 0x0153, - PROC_Obj_Sakuita = 0x0154, - PROC_Obj_Laundry = 0x0155, - PROC_WarpBug = 0x0156, - PROC_Izumi_Gate = 0x0157, - PROC_Obj_Fchain = 0x0158, - PROC_Obj_Wchain = 0x0159, - PROC_Tag_Attp = 0x015A, - PROC_Obj_Tornado = 0x015B, - PROC_Obj_Tornado2 = 0x015C, - PROC_Obj_FirePillar = 0x015D, - PROC_Obj_FirePillar2 = 0x015E, - PROC_Obj_InoBone = 0x015F, - PROC_Obj_Stopper = 0x0160, - PROC_Obj_MHole = 0x0161, - PROC_Tag_Magne = 0x0162, - PROC_Obj_BossWarp = 0x0163, - PROC_Obj_WoodPendulum = 0x0164, - PROC_Obj_WdStick = 0x0165, - PROC_Obj_StairBlock = 0x0166, - PROC_Obj_Geyser = 0x0167, - PROC_Tag_KtOnFire = 0x0168, - PROC_Obj_FireWood = 0x0169, - PROC_Obj_FireWood2 = 0x016A, - PROC_Obj_GpTaru = 0x016B, - PROC_Obj_OnsenTaru = 0x016C, - PROC_Obj_KiPot = 0x016D, - PROC_TBOX_SW = 0x016E, - PROC_Obj_SwChain = 0x016F, - PROC_Obj_WoodenSword = 0x0170, - PROC_Obj_StoneMark = 0x0171, - PROC_Obj_Lv3Candle = 0x0172, - PROC_Tag_Lv4Candle = 0x0173, - PROC_Tag_Lv4CandleDm = 0x0174, - PROC_Obj_DamCps = 0x0175, - PROC_Obj_Smoke = 0x0176, - PROC_Obj_WaterFall = 0x0177, - PROC_Obj_ZoraCloth = 0x0178, - PROC_Obj_poFire = 0x0179, - PROC_Tag_poFire = 0x017A, - PROC_Obj_glowSphere = 0x017B, - PROC_Tag_LightBall = 0x017C, - PROC_SwLBall = 0x017D, - PROC_SwBall = 0x017E, - PROC_Obj_WaterEff = 0x017F, - PROC_Tag_RiverBack = 0x0180, - PROC_Tag_KagoFall = 0x0181, - PROC_Tag_Lv2PrChk = 0x0182, - PROC_Obj_Lv4Gear = 0x0183, - PROC_Obj_MasterSword = 0x0184, - PROC_Obj_WoodStatue = 0x0185, - PROC_Obj_Fan = 0x0186, - PROC_Obj_IceLeaf = 0x0187, - PROC_Obj_zrTuraraRc = 0x0188, - PROC_Tag_RetRoom = 0x0189, - PROC_Obj_WindStone = 0x018A, - PROC_Tag_WaraHowl = 0x018B, - PROC_Obj_SCannon = 0x018C, - PROC_Obj_SmWStone = 0x018D, - PROC_Obj_SCannonCrs = 0x018E, - PROC_Tag_SnowEff = 0x018F, - PROC_Tag_CstaSw = 0x0190, - PROC_Tag_Lv6CstaSw = 0x0191, - PROC_Obj_awaPlar = 0x0192, - PROC_Obj_poTbox = 0x0193, - PROC_Obj_TimeFire = 0x0194, - PROC_Obj_TMoon = 0x0195, - PROC_Obj_GanonWall = 0x0196, - PROC_Obj_Prop = 0x0197, - PROC_CSTATUE = 0x0198, - PROC_Obj_SwBallA = 0x0199, - PROC_Obj_SwBallB = 0x019A, - PROC_Obj_SnowSoup = 0x019B, - PROC_Obj_Nagaisu = 0x019C, - PROC_Obj_RCircle = 0x019D, - PROC_Obj_Picture = 0x019E, - PROC_Tag_SetBall = 0x019F, - PROC_Tag_SmkEmt = 0x01A0, - PROC_SwTime = 0x01A1, - PROC_Obj_HFtr = 0x01A2, - PROC_Obj_HBarrel = 0x01A3, - PROC_Obj_Crystal = 0x01A4, - PROC_Obj_SCannonTen = 0x01A5, - PROC_Obj_SwBallC = 0x01A6, - PROC_SCENE_EXIT2 = 0x01A7, - PROC_Obj_Hata = 0x01A8, - PROC_Obj_ToaruMaki = 0x01A9, - PROC_Tag_AttackItem = 0x01AA, - PROC_Tag_RmbitSw = 0x01AB, - PROC_Obj_Sword = 0x01AC, - PROC_Tag_Spring = 0x01AD, - PROC_Tag_Statue = 0x01AE, - PROC_E_AI = 0x01AF, - PROC_E_GS = 0x01B0, - PROC_E_GOB = 0x01B1, - PROC_E_DD = 0x01B2, - PROC_E_DN = 0x01B3, - PROC_E_S1 = 0x01B4, - PROC_E_MF = 0x01B5, - PROC_E_SG = 0x01B6, - PROC_E_BS = 0x01B7, - PROC_E_SF = 0x01B8, - PROC_E_SH = 0x01B9, - PROC_E_DF = 0x01BA, - PROC_E_GM = 0x01BB, - PROC_E_MD = 0x01BC, - PROC_E_SM = 0x01BD, - PROC_E_SM2 = 0x01BE, - PROC_E_ST = 0x01BF, - PROC_E_ST_LINE = 0x01C0, - PROC_E_SB = 0x01C1, - PROC_E_TH = 0x01C2, - PROC_E_CR = 0x01C3, - PROC_E_CR_EGG = 0x01C4, - PROC_E_DB = 0x01C5, - PROC_E_DB_LEAF = 0x01C6, - PROC_E_GA = 0x01C7, - PROC_E_GB = 0x01C8, - PROC_E_HB = 0x01C9, - PROC_E_HB_LEAF = 0x01CA, - PROC_E_HZELDA = 0x01CB, - PROC_E_YD = 0x01CC, - PROC_E_YH = 0x01CD, - PROC_E_YD_LEAF = 0x01CE, - PROC_E_HM = 0x01CF, - PROC_E_TK = 0x01D0, - PROC_E_TK2 = 0x01D1, - PROC_E_TK_BALL = 0x01D2, - PROC_E_RB = 0x01D3, - PROC_E_RD = 0x01D4, - PROC_E_RDB = 0x01D5, - PROC_E_RDY = 0x01D6, - PROC_E_FM = 0x01D7, - PROC_E_FS = 0x01D8, - PROC_E_PM = 0x01D9, - PROC_E_PO = 0x01DA, - PROC_E_MB = 0x01DB, - PROC_E_MK = 0x01DC, - PROC_E_MM = 0x01DD, - PROC_E_FZ = 0x01DE, - PROC_E_ZS = 0x01DF, - PROC_E_KK = 0x01E0, - PROC_E_HP = 0x01E1, - PROC_E_ZH = 0x01E2, - PROC_E_ZM = 0x01E3, - PROC_E_PZ = 0x01E4, - PROC_E_FB = 0x01E5, - PROC_E_FK = 0x01E6, - PROC_E_MS = 0x01E7, - PROC_E_NEST = 0x01E8, - PROC_E_NZ = 0x01E9, - PROC_E_BA = 0x01EA, - PROC_E_BU = 0x01EB, - PROC_E_BUG = 0x01EC, - PROC_E_BEE = 0x01ED, - PROC_E_IS = 0x01EE, - PROC_E_KG = 0x01EF, - PROC_E_KR = 0x01F0, - PROC_E_SW = 0x01F1, - PROC_E_GE = 0x01F2, - PROC_Tag_WatchGe = 0x01F3, - PROC_E_YM = 0x01F4, - PROC_E_YM_TAG = 0x01F5, - PROC_E_YMB = 0x01F6, - PROC_Tag_FWall = 0x01F7, - PROC_Tag_WaterFall = 0x01F8, - PROC_E_YK = 0x01F9, - PROC_E_YR = 0x01FA, - PROC_E_YG = 0x01FB, - PROC_E_HZ = 0x01FC, - PROC_E_WS = 0x01FD, - PROC_E_OC = 0x01FE, - PROC_E_OT = 0x01FF, - PROC_E_DT = 0x0200, - PROC_E_BG = 0x0201, - PROC_E_OctBg = 0x0202, - PROC_DR = 0x0203, - PROC_L7lowDr = 0x0204, - PROC_L7ODR = 0x0205, - PROC_E_TT = 0x0206, - PROC_E_DK = 0x0207, - PROC_E_VT = 0x0208, - PROC_E_WW = 0x0209, - PROC_E_GI = 0x020A, - PROC_B_BH = 0x020B, - PROC_B_BQ = 0x020C, - PROC_B_GM = 0x020D, - PROC_B_GND = 0x020E, - PROC_B_GO = 0x020F, - PROC_B_OH2 = 0x0210, - PROC_B_YO = 0x0211, - PROC_B_YOI = 0x0212, - PROC_B_TN = 0x0213, - PROC_B_GG = 0x0214, - PROC_B_DRE = 0x0215, - PROC_B_MGN = 0x0216, - PROC_E_WAP = 0x0217, - PROC_ITEM = 0x0218, - PROC_Obj_SmallKey = 0x0219, - PROC_Obj_Kantera = 0x021A, - PROC_Obj_LifeContainer = 0x021B, - PROC_Obj_Shield = 0x021C, - PROC_Demo_Item = 0x021D, - PROC_ShopItem = 0x021E, - PROC_Obj_Drop = 0x021F, - PROC_OBJ_RW = 0x0220, - PROC_NBOMB = 0x0221, - PROC_TAG_CSW = 0x0222, - PROC_TAG_QS = 0x0223, - PROC_HOZELDA = 0x0224, - PROC_SWC00 = 0x0225, - PROC_KNOB20 = 0x0226, - PROC_DBDOOR = 0x0227, - PROC_BOSS_DOOR = 0x0228, - PROC_L1BOSS_DOOR = 0x0229, - PROC_L1MBOSS_DOOR = 0x022A, - PROC_L5BOSS_DOOR = 0x022B, - PROC_DSHUTTER = 0x022C, - PROC_SPIRAL_DOOR = 0x022D, - PROC_Tag_ChgRestart = 0x022E, - PROC_Tag_Restart = 0x022F, - PROC_ANDSW = 0x0230, - PROC_ANDSW2 = 0x0231, - PROC_MYNA = 0x0232, - PROC_NPC_GND = 0x0233, - PROC_NPC_GRA = 0x0234, - PROC_NPC_GRC = 0x0235, - PROC_NPC_GRD = 0x0236, - PROC_NPC_GRM = 0x0237, - PROC_NPC_GRMC = 0x0238, - PROC_NPC_GRO = 0x0239, - PROC_NPC_GRR = 0x023A, - PROC_NPC_GRS = 0x023B, - PROC_NPC_GRZ = 0x023C, - PROC_NPC_YAMID = 0x023D, - PROC_NPC_YAMIT = 0x023E, - PROC_NPC_YAMIS = 0x023F, - PROC_NPC_BLUENS = 0x0240, - PROC_NPC_KAKASHI = 0x0241, - PROC_NPC_KDK = 0x0242, - PROC_NPC_ARU = 0x0243, - PROC_NPC_BANS = 0x0244, - PROC_NPC_BESU = 0x0245, - PROC_NPC_BOU = 0x0246, - PROC_NPC_BOU_S = 0x0247, - PROC_NPC_CLERKA = 0x0248, - PROC_NPC_CLERKB = 0x0249, - PROC_NPC_CLERKT = 0x024A, - PROC_NPC_WRESTLER = 0x024B, - PROC_Tag_Arena = 0x024C, - PROC_Tag_Instruction = 0x024D, - PROC_NPC_DOC = 0x024E, - PROC_NPC_GWOLF = 0x024F, - PROC_NPC_LEN = 0x0250, - PROC_NPC_LUD = 0x0251, - PROC_NPC_FAIRY_SEIREI = 0x0252, - PROC_NPC_FAIRY = 0x0253, - PROC_NPC_HANJO = 0x0254, - PROC_NPC_HENNA = 0x0255, - PROC_NPC_HENNA0 = 0x0256, - PROC_NPC_HOZ = 0x0257, - PROC_NPC_JAGAR = 0x0258, - PROC_NPC_KKRI = 0x0259, - PROC_NPC_KN = 0x025A, - PROC_KN_BULLET = 0x025B, - PROC_NPC_KNJ = 0x025C, - PROC_NPC_KOLIN = 0x025D, - PROC_NPC_KOLINB = 0x025E, - PROC_NPC_KYURY = 0x025F, - PROC_NPC_MARO = 0x0260, - PROC_NPC_MIDP = 0x0261, - PROC_NPC_MOI = 0x0262, - PROC_NPC_RACA = 0x0263, - PROC_NPC_SARU = 0x0264, - PROC_NPC_SEIB = 0x0265, - PROC_NPC_SEIC = 0x0266, - PROC_NPC_SEID = 0x0267, - PROC_NPC_SEIRA = 0x0268, - PROC_NPC_SERA2 = 0x0269, - PROC_NPC_SEIREI = 0x026A, - PROC_NPC_SHAMAN = 0x026B, - PROC_NPC_SMARO = 0x026C, - PROC_NPC_SOLA = 0x026D, - PROC_NPC_TARO = 0x026E, - PROC_NPC_PACHI_BESU = 0x026F, - PROC_NPC_PACHI_TARO = 0x0270, - PROC_NPC_PACHI_MARO = 0x0271, - PROC_TAG_PATI = 0x0272, - PROC_NPC_THE = 0x0273, - PROC_NPC_TKJ = 0x0274, - PROC_NPC_TKS = 0x0275, - PROC_NPC_TKC = 0x0276, - PROC_OBJ_TKS = 0x0277, - PROC_NPC_TOBY = 0x0278, - PROC_NPC_URI = 0x0279, - PROC_NPC_YELIA = 0x027A, - PROC_NPC_YKM = 0x027B, - PROC_NPC_YKW = 0x027C, - PROC_NPC_ZANB = 0x027D, - PROC_NPC_ZANT = 0x027E, - PROC_NPC_ZELDA = 0x027F, - PROC_NPC_ZELR = 0x0280, - PROC_NPC_ZELRO = 0x0281, - PROC_OBJ_ZRAFREEZE = 0x0282, - PROC_NPC_ZRC = 0x0283, - PROC_NPC_ZRZ = 0x0284, - PROC_ZRA_MARK = 0x0285, - PROC_MYNA2 = 0x0286, - PROC_TAG_MYNA2 = 0x0287, - PROC_NPC_CD3 = 0x0288, - PROC_Tag_Schedule = 0x0289, - PROC_Tag_Escape = 0x028A, - PROC_NPC_CHAT = 0x028B, - PROC_NPC_SOLDIERa = 0x028C, - PROC_NPC_SOLDIERb = 0x028D, - PROC_PASSER_MNG = 0x028E, - PROC_NPC_PASSER = 0x028F, - PROC_NPC_PASSER2 = 0x0290, - PROC_NPC_POST = 0x0291, - PROC_NPC_POUYA = 0x0292, - PROC_FORMATION_MNG = 0x0293, - PROC_NPC_FGUARD = 0x0294, - PROC_GUARD_MNG = 0x0295, - PROC_TAG_GUARD = 0x0296, - PROC_NPC_GUARD = 0x0297, - PROC_NPC_ASH = 0x0298, - PROC_NPC_ASHB = 0x0299, - PROC_NPC_SHAD = 0x029A, - PROC_NPC_RAFREL = 0x029B, - PROC_NPC_MOIR = 0x029C, - PROC_NPC_IMPAL = 0x029D, - PROC_NPC_SHOE = 0x029E, - PROC_NPC_DOORBOY = 0x029F, - PROC_NPC_PRAYER = 0x02A0, - PROC_NPC_KASIHANA = 0x02A1, - PROC_NPC_KASIKYU = 0x02A2, - PROC_NPC_KASIMICH = 0x02A3, - PROC_NPC_DRSOL = 0x02A4, - PROC_NPC_CHIN = 0x02A5, - PROC_NPC_INS = 0x02A6, - PROC_NPC_SHOP0 = 0x02A7, - PROC_NPC_MK = 0x02A8, - PROC_NPC_P2 = 0x02A9, - PROC_KYTAG00 = 0x02AA, - PROC_KYTAG01 = 0x02AB, - PROC_KYTAG02 = 0x02AC, - PROC_KYTAG03 = 0x02AD, - PROC_KYTAG04 = 0x02AE, - PROC_KYTAG05 = 0x02AF, - PROC_KYTAG06 = 0x02B0, - PROC_KYTAG07 = 0x02B1, - PROC_KYTAG08 = 0x02B2, - PROC_KYTAG09 = 0x02B3, - PROC_KYTAG10 = 0x02B4, - PROC_KYTAG11 = 0x02B5, - PROC_KYTAG12 = 0x02B6, - PROC_KYTAG13 = 0x02B7, - PROC_KYTAG14 = 0x02B8, - PROC_KYTAG15 = 0x02B9, - PROC_KYTAG16 = 0x02BA, - PROC_KYTAG17 = 0x02BB, - PROC_Ykgr = 0x02BC, - PROC_TALK = 0x02BD, - PROC_Obj_Crope = 0x02BE, - PROC_Obj_Bombf = 0x02BF, - PROC_Obj_BkLeaf = 0x02C0, - PROC_Tag_Mhint = 0x02C1, - PROC_Tag_Mmsg = 0x02C2, - PROC_Tag_Mwait = 0x02C3, - PROC_Tag_Mstop = 0x02C4, - PROC_Tag_Stream = 0x02C5, - PROC_Tag_Sppath = 0x02C6, - PROC_Tag_Wljump = 0x02C7, - PROC_Tag_TWGate = 0x02C8, - PROC_Tag_Lv6Gate = 0x02C9, - PROC_Tag_Lv7Gate = 0x02CA, - PROC_Tag_Lv8Gate = 0x02CB, - PROC_Tag_TheBHint = 0x02CC, - PROC_Tag_Assist = 0x02CD, - PROC_DEMO00 = 0x02CE, - PROC_TAG_CAMERA = 0x02CF, - PROC_TAG_CHKPOINT = 0x02D0, - PROC_TAG_EVENT = 0x02D1, - PROC_TAG_EVT = 0x02D2, - PROC_TAG_TELOP = 0x02D3, - PROC_TAG_HOWL = 0x02D4, - PROC_TAG_MSG = 0x02D5, - PROC_TAG_LANTERN = 0x02D6, - PROC_Tag_Mist = 0x02D7, - PROC_DMIDNA = 0x02D8, - PROC_KY_THUNDER = 0x02D9, - PROC_VRBOX = 0x02DA, - PROC_VRBOX2 = 0x02DB, - PROC_BG = 0x02DC, - PROC_SET_BG_OBJ = 0x02DD, - PROC_BG_OBJ = 0x02DE, - PROC_MIRROR = 0x02DF, - PROC_MOVIE_PLAYER = 0x02E0, - PROC_TITLE = 0x02E1, - PROC_FR = 0x02E2, - PROC_ECONT = 0x02E3, - PROC_MG_ROD = 0x02E4, - PROC_E_ARROW = 0x02E5, - PROC_BULLET = 0x02E6, - PROC_SWHIT0 = 0x02E7, - PROC_E_TH_BALL = 0x02E8, - PROC_TAG_EVTAREA = 0x02E9, - PROC_TAG_EVTMSG = 0x02EA, - PROC_TAG_KMSG = 0x02EB, - PROC_TAG_PUSH = 0x02EC, - PROC_E_MK_BO = 0x02ED, - PROC_E_MM_MT = 0x02EE, - PROC_OBJ_KBOX = 0x02EF, - PROC_OBJ_FW = 0x02F0, - PROC_B_GOS = 0x02F1, - PROC_OBJ_YSTONE = 0x02F2, - PROC_MANT = 0x02F3, - PROC_CROD = 0x02F4, - PROC_OBJ_PLEAF = 0x02F5, - PROC_OBJ_KBACKET = 0x02F6, - PROC_OBJ_YBAG = 0x02F7, - PROC_OBJ_PUMPKIN = 0x02F8, - PROC_OBJ_AUTOMATA = 0x02F9, - PROC_OBJ_GADGET = 0x02FA, - PROC_OBJ_KAGO = 0x02FB, - PROC_Obj_Carry = 0x02FC, - PROC_Obj_Stone = 0x02FD, - PROC_OBJ_HB = 0x02FE, - PROC_NPC_INKO = 0x02FF, - PROC_BD = 0x0300, - PROC_Obj_Eff = 0x0301, - PROC_WPILLAR = 0x0302, - PROC_WMARK = 0x0303, - PROC_E_BI = 0x0304, - PROC_E_BI_LEAF = 0x0305, - PROC_START_AND_GOAL = 0x0306, - PROC_NPC_DF = 0x0307, - PROC_ARROW = 0x0308, - PROC_PATH_LINE = 0x0309, - PROC_TAG_ALLMATO = 0x030A, - PROC_Obj_Timer = 0x030B, - PROC_SCENE_EXIT = 0x030C, - PROC_CAMERA = 0x030D, - PROC_CAMERA2 = 0x030E, - PROC_SUSPEND = 0x030F, - PROC_GRASS = 0x0310, - PROC_KYEFF = 0x0311, - PROC_KYEFF2 = 0x0312, - PROC_MSG_OBJECT = 0x0313, - PROC_MENUWINDOW = 0x0314, - PROC_TIMER = 0x0315, - PROC_METER2 = 0x0316, - PROC_GAMEOVER = 0x0317, + PROC_OVERLAP0, + PROC_OVERLAP1, + PROC_OVERLAP3, + PROC_OVERLAP6, + PROC_OVERLAP7, + PROC_OVERLAP8, + PROC_OVERLAP9, + PROC_OVERLAP10, + PROC_OVERLAP11, + PROC_LOGO_SCENE, + PROC_MENU_SCENE, + PROC_PLAY_SCENE, + PROC_OPENING_SCENE, + PROC_NAME_SCENE, + PROC_NAMEEX_SCENE, +#ifndef WII_NTSCU_10 + PROC_WARNING_SCENE, + PROC_WARNING2_SCENE, +#endif + PROC_OVERLAP2, + PROC_ROOM_SCENE, + PROC_KANKYO, + PROC_ALLDIE, + PROC_ENVSE, + PROC_Obj_Swpush, + PROC_Obj_Swpush2, + PROC_Obj_Swpush5, + PROC_Tag_Gstart, + PROC_NO_CHG_ROOM, + PROC_Obj_Lv6ElevtA, + PROC_OBJ_SO, + PROC_Obj_Movebox, + PROC_Obj_SwTurn, + PROC_Obj_Lv6SwTurn, + PROC_OBJ_SEKIZOA, + PROC_OBJ_GRA, + PROC_TAG_GRA, + PROC_TAG_YAMI, + PROC_Obj_Ladder, + PROC_OBJ_BEF, + PROC_OBJ_FMOBJ, + PROC_OBJ_LBOX, + PROC_OBJ_WEB0, + PROC_OBJ_WEB1, + PROC_OBJ_CB, + PROC_OBJ_MAKI, + PROC_OBJ_BRG, + PROC_OBJ_GB, + PROC_OBJ_GM, + PROC_OBJ_TOBY, + PROC_OBJ_TP, + PROC_TREESH, + PROC_Obj_ZDoor, + PROC_Obj_Pillar, + PROC_Obj_Cdoor, + PROC_GRDWATER, + PROC_Obj_RotBridge, + PROC_Obj_MagLift, + PROC_Obj_MagLiftRot, + PROC_Obj_Lv1Cdl00, + PROC_Obj_Lv1Cdl01, + PROC_Obj_TvCdlst, + PROC_Obj_HsTarget, + PROC_Obj_HeavySw, + PROC_Obj_GoGate, + PROC_Obj_TaFence, + PROC_Obj_Saidan, + PROC_Obj_SpinLift, + PROC_Obj_BmWindow, + PROC_Obj_RfHole, + PROC_Obj_WaterPillar, + PROC_Obj_SyRock, + PROC_Obj_BsGate, + PROC_Obj_AmiShutter, + PROC_Obj_WtGate, + PROC_Obj_Lv2Candle, + PROC_Obj_TogeTrap, + PROC_Obj_RotTrap, + PROC_Obj_SwallShutter, + PROC_Obj_IceWall, + PROC_Obj_Lv5SwIce, + PROC_Obj_Lv5FBoard, + PROC_Obj_Turara, + PROC_Obj_TwGate, + PROC_Obj_Digholl, + PROC_Obj_Digpl, + PROC_Obj_TestCube, + PROC_Obj_Kshutter, + PROC_NPC_COACH, + PROC_NPC_THEB, + PROC_COACH_FIRE, + PROC_COACH2D, + PROC_BALLOON2D, + PROC_SKIP2D, + PROC_Obj_MvStair, + PROC_Obj_Cowdoor, + PROC_Obj_Swpropeller, + PROC_Obj_BoomShutter, + PROC_NPC_KS, + PROC_Obj_Hfuta, + PROC_Obj_BkDoor, + PROC_Obj_Cboard, + PROC_Obj_MGate, + PROC_Obj_Ikada, + PROC_Obj_Ice_l, + PROC_Obj_Ice_s, + PROC_Obj_E_CREATE, + PROC_Obj_Bhbridge, + PROC_Obj_Kaisou, + PROC_Obj_HHASHI, + PROC_Obj_BHASHI, + PROC_OCTHASHI, + PROC_Obj_THASHI, + PROC_Obj_CRVGATE, + PROC_Obj_CRVFENCE, + PROC_Obj_CRVHAHEN, + PROC_Obj_CRVSTEEL, + PROC_Obj_CRVLH_UP, + PROC_Obj_CRVLH_DW, + PROC_Obj_RIVERROCK, + PROC_Obj_DUST, + PROC_Obj_ITA, + PROC_Obj_Window, + PROC_Obj_MetalBox, + PROC_Obj_BBox, + PROC_OBJ_MSIMA, + PROC_OBJ_MYOGAN, + PROC_B_ZANTS, + PROC_Obj_ChainBlock, + PROC_Obj_ChainWall, + PROC_Obj_KkrGate, + PROC_Obj_RiderGate, + PROC_Obj_Onsen, + PROC_Obj_Chest, + PROC_Obj_Bemos, + PROC_Obj_RopeBridge, + PROC_Obj_WellCover, + PROC_Obj_GraveStone, + PROC_Obj_ZraRock, + PROC_Obj_GraRock, + PROC_Obj_GrzRock, + PROC_GRA_WALL, + PROC_OBJ_ONSEN_FIRE, + PROC_Obj_Lv6bemos, + PROC_Obj_Lv6bemos2, + PROC_Obj_BarDesk, + PROC_Obj_DigSnow, + PROC_Obj_Ytaihou, + PROC_Obj_Elevator, + PROC_Obj_Lv6TogeRoll, + PROC_Obj_Lv6TogeTrap, + PROC_Obj_Lv6Tenbin, + PROC_Obj_Lv6SwGate, + PROC_Obj_Lv6Lblock, + PROC_Obj_Lv6ChgGate, + PROC_Obj_Lv6FuriTrap, + PROC_Obj_Lv6SzGate, + PROC_Obj_Lv4EdShutter, + PROC_Obj_Lv4Gate, + PROC_Obj_Lv4PoGate, + PROC_Obj_Lv4SlideWall, + PROC_Obj_Lv4HsTarget, + PROC_Obj_Lv7PropY, + PROC_Obj_Lv7BsGate, + PROC_Obj_Lv8OptiLift, + PROC_Obj_Lv8KekkaiTrap, + PROC_Obj_Lv8Lift, + PROC_Obj_Lv8UdFloor, + PROC_Obj_Lv9SwShutter, + PROC_Obj_TobyHouse, + PROC_Obj_poCandle, + PROC_Obj_Lv4DigSand, + PROC_Obj_FallObj, + PROC_Obj_SmgDoor, + PROC_Obj_SwLight, + PROC_Obj_Avalanche, + PROC_Obj_MirrorScrew, + PROC_Obj_MirrorSand, + PROC_Obj_MirrorTable, + PROC_Obj_MirrorChain, + PROC_Obj_Mirror6Pole, + PROC_Obj_SwSpinner, + PROC_Obj_TDoor, + PROC_Obj_Lv7Bridge, + PROC_Obj_zrTurara, + PROC_Obj_TakaraDai, + PROC_Obj_Table, + PROC_Obj_CatDoor, + PROC_Obj_Gake, + PROC_CSTAF, + PROC_Obj_Lv4RailWall, + PROC_Obj_Lv4Sand, + PROC_Obj_PushDoor, + PROC_PushDoor, + PROC_Obj_GanonWall2, + PROC_Obj_Lv4Bridge, + PROC_Obj_Lv4Floor, + PROC_Tag_Spinner, + PROC_Obj_SwHang, + PROC_Obj_RotStair, + PROC_Obj_MagneArm, + PROC_Obj_KWheel00, + PROC_Obj_KWheel01, + PROC_Obj_Ychndlr, + PROC_Obj_PRElvtr, + PROC_Obj_MHasu, + PROC_Obj_YIblltray, + PROC_Obj_Lv6EGate, + PROC_Obj_PDtile, + PROC_Obj_PDwall, + PROC_Obj_Lv4PRwall, + PROC_Obj_KLift00, + PROC_B_OH, + PROC_Obj_Lv4Chan, + PROC_Obj_Lv3R10Saka, + PROC_Obj_Lv3Water, + PROC_Obj_Lv3Water2, + PROC_OBJ_LV3WATERB, + PROC_Obj_HBombkoya, + PROC_Obj_SZbridge, + PROC_Obj_KakarikoBrg, + PROC_Obj_OrdinBrg, + PROC_Obj_BurnBox, + PROC_Obj_KJgjs, + PROC_OBJ_IHASI, + PROC_Obj_IceBlock, + PROC_Obj_VolcanicBall, + PROC_Obj_VolcanicBomb, + PROC_Obj_VolcGnd, + PROC_Obj_KKanban, + PROC_E_PH, + PROC_NPC_ZRA, + PROC_Obj_Chandelier, + PROC_Obj_Stopper2, + PROC_DOOR20, + PROC_Tag_Hinit, + PROC_Tag_Hjump, + PROC_Tag_AJnot, + PROC_Tag_Hstop, + PROC_CANOE, + PROC_HORSE, + PROC_E_WB, + PROC_OBJ_ITO, + PROC_OBJ_SW, + PROC_SPINNER, + PROC_B_OB, + PROC_KAGO, + PROC_E_YC, + PROC_B_DS, + PROC_B_DR, + PROC_B_ZANTZ, + PROC_B_ZANT, + PROC_B_ZANTM, + PROC_TBOX, + PROC_TBOX2, + PROC_ALINK, + PROC_BOOMERANG, + PROC_MIDNA, + PROC_NPC_TK, + PROC_NPC_WORM, + PROC_PPolamp, + PROC_BkyRock, + PROC_HITOBJ, + PROC_EP, + PROC_COW, + PROC_PERU, + PROC_NI, + PROC_NPC_TKJ2, + PROC_SQ, + PROC_NPC_SQ, + PROC_DO, + PROC_NPC_NE, + PROC_NPC_TR, + PROC_NPC_LF, + PROC_OBJ_FOOD, + PROC_OBJ_KI, + PROC_OBJ_KITA, + PROC_OBJ_KEY, + PROC_OBJ_KEYHOLE, + PROC_Obj_Lv5Key, + PROC_OBJ_LP, + PROC_OBJ_TATIGI, + PROC_OBJ_ROCK, + PROC_OBJ_WFLAG, + PROC_OBJ_KAGE, + PROC_OBJ_KANBAN2, + PROC_OBJ_BALLOON, + PROC_OBJ_SUISYA, + PROC_OBJ_OILTUBO, + PROC_OBJ_ROTEN, + PROC_OBJ_SSDRINK, + PROC_OBJ_SSITEM, + PROC_TAG_SSDRINK, + PROC_TAG_BTLITM, + PROC_TAG_LV5SOUP, + PROC_TAG_MNLIGHT, + PROC_TAG_SHOPCAM, + PROC_TAG_SHOPITM, + PROC_OBJ_NDOOR, + PROC_OBJ_UDOOR, + PROC_OBJ_USAKU, + PROC_Obj_SM_DOOR, + PROC_OBJ_BED, + PROC_OBJ_BOUMATO, + PROC_OBJ_ITAMATO, + PROC_OBJ_NOUGU, + PROC_OBJ_STICK, + PROC_OBJ_MIE, + PROC_OBJ_SEKIDOOR, + PROC_OBJ_SEKIZO, + PROC_OBJ_SMTILE, + PROC_NPC_FISH, + PROC_MG_FISH, + PROC_FSHOP, + PROC_NPC_DU, + PROC_DISAPPEAR, + PROC_Obj_Mato, + PROC_Obj_Flag, + PROC_Obj_Flag2, + PROC_Obj_Flag3, + PROC_Obj_GOMIKABE, + PROC_Obj_Yousei, + PROC_Obj_Kabuto, + PROC_Obj_Cho, + PROC_Obj_Kuw, + PROC_Obj_Nan, + PROC_Obj_Dan, + PROC_Obj_Kam, + PROC_Obj_Ten, + PROC_Obj_Ari, + PROC_Obj_Kag, + PROC_Obj_Batta, + PROC_Obj_Tombo, + PROC_Obj_Kat, + PROC_Obj_H_Saku, + PROC_Obj_Yobikusa, + PROC_Obj_KazeNeko, + PROC_Obj_KznkArm, + PROC_Obj_NamePlate, + PROC_Obj_OnCloth, + PROC_Obj_LndRope, + PROC_Obj_ItaRope, + PROC_Obj_Sakuita, + PROC_Obj_Laundry, + PROC_WarpBug, + PROC_Izumi_Gate, + PROC_Obj_Fchain, + PROC_Obj_Wchain, + PROC_Tag_Attp, + PROC_Obj_Tornado, + PROC_Obj_Tornado2, + PROC_Obj_FirePillar, + PROC_Obj_FirePillar2, + PROC_Obj_InoBone, + PROC_Obj_Stopper, + PROC_Obj_MHole, + PROC_Tag_Magne, + PROC_Obj_BossWarp, + PROC_Obj_WoodPendulum, + PROC_Obj_WdStick, + PROC_Obj_StairBlock, + PROC_Obj_Geyser, + PROC_Tag_KtOnFire, + PROC_Obj_FireWood, + PROC_Obj_FireWood2, + PROC_Obj_GpTaru, + PROC_Obj_OnsenTaru, + PROC_Obj_KiPot, + PROC_TBOX_SW, + PROC_Obj_SwChain, + PROC_Obj_WoodenSword, + PROC_Obj_StoneMark, + PROC_Obj_Lv3Candle, + PROC_Tag_Lv4Candle, + PROC_Tag_Lv4CandleDm, + PROC_Obj_DamCps, + PROC_Obj_Smoke, + PROC_Obj_WaterFall, + PROC_Obj_ZoraCloth, + PROC_Obj_poFire, + PROC_Tag_poFire, + PROC_Obj_glowSphere, + PROC_Tag_LightBall, + PROC_SwLBall, + PROC_SwBall, + PROC_Obj_WaterEff, + PROC_Tag_RiverBack, + PROC_Tag_KagoFall, + PROC_Tag_Lv2PrChk, + PROC_Obj_Lv4Gear, + PROC_Obj_MasterSword, + PROC_Obj_WoodStatue, + PROC_Obj_Fan, + PROC_Obj_IceLeaf, + PROC_Obj_zrTuraraRc, + PROC_Tag_RetRoom, + PROC_Obj_WindStone, + PROC_Tag_WaraHowl, + PROC_Obj_SCannon, + PROC_Obj_SmWStone, + PROC_Obj_SCannonCrs, + PROC_Tag_SnowEff, + PROC_Tag_CstaSw, + PROC_Tag_Lv6CstaSw, + PROC_Obj_awaPlar, + PROC_Obj_poTbox, + PROC_Obj_TimeFire, + PROC_Obj_TMoon, + PROC_Obj_GanonWall, + PROC_Obj_Prop, + PROC_CSTATUE, + PROC_Obj_SwBallA, + PROC_Obj_SwBallB, + PROC_Obj_SnowSoup, + PROC_Obj_Nagaisu, + PROC_Obj_RCircle, + PROC_Obj_Picture, + PROC_Tag_SetBall, + PROC_Tag_SmkEmt, + PROC_SwTime, + PROC_Obj_HFtr, + PROC_Obj_HBarrel, + PROC_Obj_Crystal, + PROC_Obj_SCannonTen, + PROC_Obj_SwBallC, + PROC_SCENE_EXIT2, + PROC_Obj_Hata, + PROC_Obj_ToaruMaki, + PROC_Tag_AttackItem, + PROC_Tag_RmbitSw, + PROC_Obj_Sword, + PROC_Tag_Spring, + PROC_Tag_Statue, + PROC_E_AI, + PROC_E_GS, + PROC_E_GOB, + PROC_E_DD, + PROC_E_DN, + PROC_E_S1, + PROC_E_MF, + PROC_E_SG, + PROC_E_BS, + PROC_E_SF, + PROC_E_SH, + PROC_E_DF, + PROC_E_GM, + PROC_E_MD, + PROC_E_SM, + PROC_E_SM2, + PROC_E_ST, + PROC_E_ST_LINE, + PROC_E_SB, + PROC_E_TH, + PROC_E_CR, + PROC_E_CR_EGG, + PROC_E_DB, + PROC_E_DB_LEAF, + PROC_E_GA, + PROC_E_GB, + PROC_E_HB, + PROC_E_HB_LEAF, + PROC_E_HZELDA, + PROC_E_YD, + PROC_E_YH, + PROC_E_YD_LEAF, + PROC_E_HM, + PROC_E_TK, + PROC_E_TK2, + PROC_E_TK_BALL, + PROC_E_RB, + PROC_E_RD, + PROC_E_RDB, + PROC_E_RDY, + PROC_E_FM, + PROC_E_FS, + PROC_E_PM, + PROC_E_PO, + PROC_E_MB, + PROC_E_MK, + PROC_E_MM, + PROC_E_FZ, + PROC_E_ZS, + PROC_E_KK, + PROC_E_HP, + PROC_E_ZH, + PROC_E_ZM, + PROC_E_PZ, + PROC_E_FB, + PROC_E_FK, + PROC_E_MS, + PROC_E_NEST, + PROC_E_NZ, + PROC_E_BA, + PROC_E_BU, + PROC_E_BUG, + PROC_E_BEE, + PROC_E_IS, + PROC_E_KG, + PROC_E_KR, + PROC_E_SW, + PROC_E_GE, + PROC_Tag_WatchGe, + PROC_E_YM, + PROC_E_YM_TAG, + PROC_E_YMB, + PROC_Tag_FWall, + PROC_Tag_WaterFall, + PROC_E_YK, + PROC_E_YR, + PROC_E_YG, + PROC_E_HZ, + PROC_E_WS, + PROC_E_OC, + PROC_E_OT, + PROC_E_DT, + PROC_E_BG, + PROC_E_OctBg, + PROC_DR, + PROC_L7lowDr, + PROC_L7ODR, + PROC_E_TT, + PROC_E_DK, + PROC_E_VT, + PROC_E_WW, + PROC_E_GI, + PROC_B_BH, + PROC_B_BQ, + PROC_B_GM, + PROC_B_GND, + PROC_B_GO, + PROC_B_OH2, + PROC_B_YO, + PROC_B_YOI, + PROC_B_TN, + PROC_B_GG, + PROC_B_DRE, + PROC_B_MGN, + PROC_E_WAP, + PROC_ITEM, + PROC_Obj_SmallKey, + PROC_Obj_Kantera, + PROC_Obj_LifeContainer, + PROC_Obj_Shield, + PROC_Demo_Item, + PROC_ShopItem, + PROC_Obj_Drop, + PROC_OBJ_RW, + PROC_NBOMB, + PROC_TAG_CSW, + PROC_TAG_QS, + PROC_HOZELDA, + PROC_SWC00, + PROC_KNOB20, + PROC_DBDOOR, + PROC_BOSS_DOOR, + PROC_L1BOSS_DOOR, + PROC_L1MBOSS_DOOR, + PROC_L5BOSS_DOOR, + PROC_DSHUTTER, + PROC_SPIRAL_DOOR, + PROC_Tag_ChgRestart, + PROC_Tag_Restart, + PROC_ANDSW, + PROC_ANDSW2, + PROC_MYNA, + PROC_NPC_GND, + PROC_NPC_GRA, + PROC_NPC_GRC, + PROC_NPC_GRD, + PROC_NPC_GRM, + PROC_NPC_GRMC, + PROC_NPC_GRO, + PROC_NPC_GRR, + PROC_NPC_GRS, + PROC_NPC_GRZ, + PROC_NPC_YAMID, + PROC_NPC_YAMIT, + PROC_NPC_YAMIS, + PROC_NPC_BLUENS, + PROC_NPC_KAKASHI, + PROC_NPC_KDK, + PROC_NPC_ARU, + PROC_NPC_BANS, + PROC_NPC_BESU, + PROC_NPC_BOU, + PROC_NPC_BOU_S, + PROC_NPC_CLERKA, + PROC_NPC_CLERKB, + PROC_NPC_CLERKT, + PROC_NPC_WRESTLER, + PROC_Tag_Arena, + PROC_Tag_Instruction, + PROC_NPC_DOC, + PROC_NPC_GWOLF, + PROC_NPC_LEN, + PROC_NPC_LUD, + PROC_NPC_FAIRY_SEIREI, + PROC_NPC_FAIRY, + PROC_NPC_HANJO, + PROC_NPC_HENNA, + PROC_NPC_HENNA0, + PROC_NPC_HOZ, + PROC_NPC_JAGAR, + PROC_NPC_KKRI, + PROC_NPC_KN, + PROC_KN_BULLET, + PROC_NPC_KNJ, + PROC_NPC_KOLIN, + PROC_NPC_KOLINB, + PROC_NPC_KYURY, + PROC_NPC_MARO, + PROC_NPC_MIDP, + PROC_NPC_MOI, + PROC_NPC_RACA, + PROC_NPC_SARU, + PROC_NPC_SEIB, + PROC_NPC_SEIC, + PROC_NPC_SEID, + PROC_NPC_SEIRA, + PROC_NPC_SERA2, + PROC_NPC_SEIREI, + PROC_NPC_SHAMAN, + PROC_NPC_SMARO, + PROC_NPC_SOLA, + PROC_NPC_TARO, + PROC_NPC_PACHI_BESU, + PROC_NPC_PACHI_TARO, + PROC_NPC_PACHI_MARO, + PROC_TAG_PATI, + PROC_NPC_THE, + PROC_NPC_TKJ, + PROC_NPC_TKS, + PROC_NPC_TKC, + PROC_OBJ_TKS, + PROC_NPC_TOBY, + PROC_NPC_URI, + PROC_NPC_YELIA, + PROC_NPC_YKM, + PROC_NPC_YKW, + PROC_NPC_ZANB, + PROC_NPC_ZANT, + PROC_NPC_ZELDA, + PROC_NPC_ZELR, + PROC_NPC_ZELRO, + PROC_OBJ_ZRAFREEZE, + PROC_NPC_ZRC, + PROC_NPC_ZRZ, + PROC_ZRA_MARK, + PROC_MYNA2, + PROC_TAG_MYNA2, + PROC_NPC_CD3, + PROC_Tag_Schedule, + PROC_Tag_Escape, + PROC_NPC_CHAT, + PROC_NPC_SOLDIERa, + PROC_NPC_SOLDIERb, + PROC_PASSER_MNG, + PROC_NPC_PASSER, + PROC_NPC_PASSER2, + PROC_NPC_POST, + PROC_NPC_POUYA, + PROC_FORMATION_MNG, + PROC_NPC_FGUARD, + PROC_GUARD_MNG, + PROC_TAG_GUARD, + PROC_NPC_GUARD, + PROC_NPC_ASH, + PROC_NPC_ASHB, + PROC_NPC_SHAD, + PROC_NPC_RAFREL, + PROC_NPC_MOIR, + PROC_NPC_IMPAL, + PROC_NPC_SHOE, + PROC_NPC_DOORBOY, + PROC_NPC_PRAYER, + PROC_NPC_KASIHANA, + PROC_NPC_KASIKYU, + PROC_NPC_KASIMICH, + PROC_NPC_DRSOL, + PROC_NPC_CHIN, + PROC_NPC_INS, + PROC_NPC_SHOP0, + PROC_NPC_MK, + PROC_NPC_P2, + PROC_KYTAG00, + PROC_KYTAG01, + PROC_KYTAG02, + PROC_KYTAG03, + PROC_KYTAG04, + PROC_KYTAG05, + PROC_KYTAG06, + PROC_KYTAG07, + PROC_KYTAG08, + PROC_KYTAG09, + PROC_KYTAG10, + PROC_KYTAG11, + PROC_KYTAG12, + PROC_KYTAG13, + PROC_KYTAG14, + PROC_KYTAG15, + PROC_KYTAG16, + PROC_KYTAG17, + PROC_Ykgr, + PROC_TALK, + PROC_Obj_Crope, + PROC_Obj_Bombf, + PROC_Obj_BkLeaf, + PROC_Tag_Mhint, + PROC_Tag_Mmsg, + PROC_Tag_Mwait, + PROC_Tag_Mstop, + PROC_Tag_Stream, + PROC_Tag_Sppath, + PROC_Tag_Wljump, + PROC_Tag_TWGate, + PROC_Tag_Lv6Gate, + PROC_Tag_Lv7Gate, + PROC_Tag_Lv8Gate, + PROC_Tag_TheBHint, + PROC_Tag_Assist, + PROC_DEMO00, + PROC_TAG_CAMERA, + PROC_TAG_CHKPOINT, + PROC_TAG_EVENT, + PROC_TAG_EVT, + PROC_TAG_TELOP, + PROC_TAG_HOWL, + PROC_TAG_MSG, + PROC_TAG_LANTERN, + PROC_Tag_Mist, + PROC_DMIDNA, + PROC_KY_THUNDER, + PROC_VRBOX, + PROC_VRBOX2, + PROC_BG, + PROC_SET_BG_OBJ, + PROC_BG_OBJ, + PROC_MIRROR, + PROC_MOVIE_PLAYER, + PROC_TITLE, + PROC_FR, + PROC_ECONT, + PROC_MG_ROD, + PROC_E_ARROW, + PROC_BULLET, + PROC_SWHIT0, + PROC_E_TH_BALL, + PROC_TAG_EVTAREA, + PROC_TAG_EVTMSG, + PROC_TAG_KMSG, + PROC_TAG_PUSH, + PROC_E_MK_BO, + PROC_E_MM_MT, + PROC_OBJ_KBOX, + PROC_OBJ_FW, + PROC_B_GOS, + PROC_OBJ_YSTONE, + PROC_MANT, + PROC_CROD, + PROC_OBJ_PLEAF, + PROC_OBJ_KBACKET, + PROC_OBJ_YBAG, + PROC_OBJ_PUMPKIN, + PROC_OBJ_AUTOMATA, + PROC_OBJ_GADGET, + PROC_OBJ_KAGO, + PROC_Obj_Carry, + PROC_Obj_Stone, + PROC_OBJ_HB, + PROC_NPC_INKO, + PROC_BD, + PROC_Obj_Eff, + PROC_WPILLAR, + PROC_WMARK, + PROC_E_BI, + PROC_E_BI_LEAF, + PROC_START_AND_GOAL, + PROC_NPC_DF, + PROC_ARROW, + PROC_PATH_LINE, + PROC_TAG_ALLMATO, + PROC_Obj_Timer, + PROC_SCENE_EXIT, + PROC_CAMERA, + PROC_CAMERA2, + PROC_SUSPEND, + PROC_GRASS, + PROC_KYEFF, + PROC_KYEFF2, + PROC_MSG_OBJECT, + PROC_MENUWINDOW, + PROC_TIMER, + PROC_METER2, + PROC_GAMEOVER, }; #endif /* D_PROCNAME_H */ \ No newline at end of file diff --git a/external/libtp_c/include/d/d_stage.h b/external/libtp_c/include/d/d_stage.h index bf867757..915c55d3 100644 --- a/external/libtp_c/include/d/d_stage.h +++ b/external/libtp_c/include/d/d_stage.h @@ -1,10 +1,10 @@ #ifndef D_D_STAGE_H #define D_D_STAGE_H -#include "../addrs.h" #include "save/d_save.h" #include "../f_op/f_op_actor.h" #include "../defines.h" +#include "d_path.h" struct stage_vrboxcol_info_class {}; @@ -61,7 +61,10 @@ struct dStage_FileList2_dt_c {}; struct dStage_MemoryMap_c {}; -struct dStage_dPath_c {}; +struct dStage_dPath_c { + /* 0x0 */ int m_num; + /* 0x4 */ dPath* m_path; +}; struct dStage_Multi_c {}; @@ -69,7 +72,13 @@ struct dStage_SoundInfo_c {}; struct dStage_FileList_dt_c {}; -struct dStage_dPnt_c {}; +struct dStage_dPnt_c { + /* 0x0 */ u8 field_0x0; + /* 0x1 */ u8 field_0x1; + /* 0x2 */ u8 field_0x2; + /* 0x3 */ u8 field_0x3; + /* 0x4 */ Vec m_position; +}; // Size: 0x10 struct dStage_FloorInfo_c {}; @@ -206,7 +215,7 @@ class dStage_nextStage_c : public dStage_startStage_c { static_assert(sizeof(dStage_nextStage_c) == 0x12); #endif // WII_PLATFORM -class dStage_roomStatus_c : dStage_roomDt_c { +class dStage_roomStatus_c : public dStage_roomDt_c { public: /* 0x06C */ u8 mJ3DLightInfo[0xA0 - 0x6C]; /* 0x0A0 */ u8 unk_A0[0x3F7 - 0xA0]; @@ -242,4 +251,9 @@ typedef void (*dStage_nextStage_c__set_t)(void* addr, const char* stage, s8 room extern dStage_nextStage_c__set_t dStage_nextStage_c__set; #endif +#ifndef WII_PLATFORM +#define dStage_roomControl_c__mStatus mStatus__20dStage_roomControl_c +#endif +extern dStage_roomStatus_c dStage_roomControl_c__mStatus[64]; + #endif /* D_D_STAGE_H */ diff --git a/external/libtp_c/include/d/kankyo/d_kankyo.h b/external/libtp_c/include/d/kankyo/d_kankyo.h index 4f8fd86c..01b5c77a 100644 --- a/external/libtp_c/include/d/kankyo/d_kankyo.h +++ b/external/libtp_c/include/d/kankyo/d_kankyo.h @@ -2,7 +2,7 @@ #define D_KANKYO_D_KANKYO_H #include "../../SSystem/SComponent/c_xyz.h" -#include "../../dolphin/gx/GXTexture.h" +#include "../../dolphin/gx/gx.h" #include "../../JSystem/J3DGraphBase/J3DStruct.h" #include "../../JSystem/J3DGraphBase/J3DPacket.h" @@ -262,10 +262,6 @@ class dKankyo_evil_Packet : public J3DPacket { /* 0x18 */ EVIL_EFF field_0x18[2000]; }; -struct GXFogAdjTable { - u16 field_0x0[10]; -}; - class fopAc_ac_c; class dScnKy_env_light_c { diff --git a/external/libtp_c/include/d/menu/d_menu_window.h b/external/libtp_c/include/d/menu/d_menu_window.h index 7868ff9b..4f90d181 100644 --- a/external/libtp_c/include/d/menu/d_menu_window.h +++ b/external/libtp_c/include/d/menu/d_menu_window.h @@ -1,12 +1,150 @@ #ifndef D_MENU_D_MENU_WINDOW_H #define D_MENU_D_MENU_WINDOW_H -#include "../../addrs.h" #include "../../defines.h" -class dMw_c {}; +class msg_class : public leafdraw_class { +public: + /* 0xC0 */ int mMsgType; + /* 0xC4 */ create_tag_class draw_tag; + /* 0xD8 */ leafdraw_method_class* sub_method; + /* 0xDC */ fopAc_ac_c* mpActor; + /* 0xE0 */ cXyz mPos; + /* 0xEC */ u32 mMsgID; + /* 0xF0 */ u32 field_0xf0; + /* 0xF4 */ u32 field_0xf4; + /* 0xF8 */ u16 mMode; + /* 0xFA */ u8 mSelectedChoiceIdx; +}; // Size: 0xFC + +class dMenuRing_c {}; + +class dMw_c : public msg_class { +public: + enum dMw_Status { + /* 0x00 */ NO_MENU, + /* 0x01 */ RING_OPEN, + /* 0x02 */ RING_MOVE, + /* 0x03 */ RING_CLOSE, + /* 0x04 */ COLLECT_OPEN, + /* 0x05 */ COLLECT_MOVE, + /* 0x06 */ COLLECT_CLOSE, + /* 0x07 */ FMAP_OPEN, + /* 0x08 */ FMAP_MOVE, + /* 0x09 */ FMAP_CLOSE, + /* 0x0A */ DMAP_OPEN, + /* 0x0B */ DMAP_MOVE, + /* 0x0C */ DMAP_CLOSE, + /* 0x0D */ SAVE_OPEN, + /* 0x0E */ SAVE_MOVE, + /* 0x0F */ SAVE_CLOSE, + /* 0x10 */ OPTIONS_OPEN, + /* 0x11 */ OPTIONS_MOVE, + /* 0x12 */ OPTIONS_CLOSE, + /* 0x13 */ LETTER_OPEN, + /* 0x14 */ LETTER_MOVE, + /* 0x15 */ LETTER_CLOSE, + /* 0x16 */ FISHING_OPEN, + /* 0x17 */ FISHING_MOVE, + /* 0x18 */ FISHING_CLOSE, + /* 0x19 */ SKILL_OPEN, + /* 0x1A */ SKILL_MOVE, + /* 0x1B */ SKILL_CLOSE, + /* 0x1C */ INSECT_OPEN, + /* 0x1D */ INSECT_MOVE, + /* 0x1E */ INSECT_CLOSE, + /* 0x1F */ INSECT_AGITHA_OPEN1, + /* 0x20 */ INSECT_AGITHA_OPEN2, + /* 0x21 */ INSECT_AGITHA_MOVE, + /* 0x22 */ INSECT_AGITHA_CLOSE, + }; + + /* 801FA13C */ void key_wait_init(u8); + /* 801FBF60 */ bool dMw_ring_delete(); + +public: + /* 0x0FC */ int field_0xfc; + /* 0x100 */ JKRExpHeap* mpHeap; + /* 0x104 */ u8 field_0x104[0x110 - 0x104]; + /* 0x110 */ dMenuRing_c* mpMenuRing; + /* 0x114 */ u8 field_0x114[0x138 - 0x114]; + /* 0x138 */ s32 mMemSize; + /* 0x13C */ f32 field_0x13c; + /* 0x140 */ f32 field_0x140; + /* 0x144 */ u8 field_0x144; + /* 0x145 */ u8 mButtons; + /* 0x146 */ u8 mMenuStatus; + /* 0x147 */ u8 mShowFlag; + /* 0x148 */ s8 field_0x148; + /* 0x149 */ u8 field_0x149; + /* 0x14A */ u8 field_0x14A; + /* 0x14B */ u8 field_0x14B; + /* 0x14C */ u8 field_0x14C; + /* 0x14D */ u8 field_0x14D; + /* 0x14E */ u8 field_0x14E; + /* 0x14F */ u8 field_0x14F; + /* 0x150 */ u8 field_0x150; + /* 0x151 */ u8 field_0x151; + /* 0x152 */ u8 field_0x152; + /* 0x153 */ u8 field_0x153; + /* 0x154 */ bool mPauseWindow; +}; LIBTP_DEFINE_FUNC(isEventCheck__5dMw_cFv, dMw_c__isEventCheck_void_, bool, dMw_c__isEventCheck, (void* addr)) +LIBTP_DEFINE_FUNC(fopMsgM_SearchByID__FUi, fopMsgM_SearchByID_unsigned_int_, + msg_class*, fopMsgM_SearchByID, (u32 id)) + +LIBTP_DEFINE_FUNC(_delete__5dMw_cFv, dMw_c___delete_void_, void, + dMw_c__delete, (void* addr)) + +LIBTP_DEFINE_FUNC(dMw_ring_delete__5dMw_cFv, dMw_c__dMw_ring_delete_void_, bool, + dMw_c__ring_delete, (void* addr)) + +LIBTP_DEFINE_FUNC(key_wait_init__5dMw_cFUc, dMw_c__key_wait_init_unsigned_char_, + void, dMw_c__key_wait_init, (void* addr, u8 arg0)) + +LIBTP_DEFINE_FUNC(dMw_offMenuRing__Fv, dMw_offMenuRing_void_, + void, dMw_c__offMenuRing, (void)) + +LIBTP_DEFINE_FUNC(ring_open_proc__5dMw_cFv, dMw_c__ring_open_proc_void_, + void, dMw_c__ring_open_proc, (void* addr)) + +LIBTP_DEFINE_FUNC(ring_close_proc__5dMw_cFv, dMw_c__ring_close_proc_void_, + void, dMw_c__ring_close_proc, (void* addr)) + +LIBTP_DEFINE_FUNC(_execute__5dMw_cFv, dMw_c___execute_void_, void, + dMw_c__execute, (dMw_c* addr)) + +LIBTP_DEFINE_FUNC(collect_close_proc__5dMw_cFv, dMw_c__collect_close_proc_void_, + void, dMw_c__collect_close_proc, (void* addr)) + +LIBTP_DEFINE_FUNC(fmap_close_proc__5dMw_cFv, dMw_c__fmap_close_proc_void_, + void, dMw_c__fmap_close_proc, (void* addr)) + +LIBTP_DEFINE_FUNC(dmap_close_proc__5dMw_cFv, dMw_c__dmap_close_proc_void_, + void, dMw_c__dmap_close_proc, (void* addr)) + +LIBTP_DEFINE_FUNC(collect_save_close_proc__5dMw_cFv, dMw_c__collect_save_close_proc_void_, + void, dMw_c__collect_save_close_proc, (void* addr)) + +LIBTP_DEFINE_FUNC(collect_option_close_proc__5dMw_cFv, dMw_c__collect_option_close_proc_void_, + void, dMw_c__collect_option_close_proc, (void* addr)) + +LIBTP_DEFINE_FUNC(collect_letter_close_proc__5dMw_cFv, dMw_c__collect_letter_close_proc_void_, + void, dMw_c__collect_letter_close_proc, (void* addr)) + +LIBTP_DEFINE_FUNC(collect_fishing_close_proc__5dMw_cFv, dMw_c__collect_fishing_close_proc_void_, + void, dMw_c__collect_fishing_close_proc, (void* addr)) + +LIBTP_DEFINE_FUNC(collect_skill_close_proc__5dMw_cFv, dMw_c__collect_skill_close_proc_void_, + void, dMw_c__collect_skill_close_proc, (void* addr)) + +LIBTP_DEFINE_FUNC(collect_insect_close_proc__5dMw_cFv, dMw_c__collect_insect_close_proc_void_, + void, dMw_c__collect_insect_close_proc, (void* addr)) + +LIBTP_DEFINE_FUNC(insect_close_proc__5dMw_cFv, dMw_c__insect_close_proc_void_, + void, dMw_c__insect_close_proc, (void* addr)) + #endif /* D_MENU_D_MENU_WINDOW_H */ diff --git a/external/libtp_c/include/d/meter/d_meter_HIO.h b/external/libtp_c/include/d/meter/d_meter_HIO.h index aaf83bf5..6a10090a 100644 --- a/external/libtp_c/include/d/meter/d_meter_HIO.h +++ b/external/libtp_c/include/d/meter/d_meter_HIO.h @@ -2,7 +2,6 @@ #define D_METER_D_METER_HIO_H #include "../../dolphin/types.h" -#include "../../addrs.h" #include "../../JSystem/JUtility.h" class dMeter_menuHIO_c { diff --git a/external/libtp_c/include/defines.h b/external/libtp_c/include/defines.h index 255ae381..75d566d6 100644 --- a/external/libtp_c/include/defines.h +++ b/external/libtp_c/include/defines.h @@ -27,4 +27,7 @@ #define KEEP_FUNC __attribute__((used, visibility("default"))) #define KEEP_VAR __attribute__((visibility("default"))) +// Generic macro to get the size of an array +#define ARRAY_COUNT(list) (sizeof(list) / sizeof((list)[0])) + #endif // !LIBTP_C_DEFINES_H \ No newline at end of file diff --git a/external/libtp_c/include/dolphin/gx/GXTexture.h b/external/libtp_c/include/dolphin/gx/GXTexture.h index 007a0efa..dc426194 100644 --- a/external/libtp_c/include/dolphin/gx/GXTexture.h +++ b/external/libtp_c/include/dolphin/gx/GXTexture.h @@ -3,25 +3,4 @@ #include -struct _GXColor { - void operator=(const _GXColor& rhs) { - r = rhs.r; - g = rhs.g; - b = rhs.b; - a = rhs.a; - } - - u8 r; - u8 g; - u8 b; - u8 a; -}; - -struct _GXColorS10 { - s16 r; - s16 g; - s16 b; - s16 a; -}; - #endif /* GXTEXTURE_H */ diff --git a/external/libtp_c/include/dolphin/gx/gx.h b/external/libtp_c/include/dolphin/gx/gx.h index abc75af1..82a2101e 100644 --- a/external/libtp_c/include/dolphin/gx/gx.h +++ b/external/libtp_c/include/dolphin/gx/gx.h @@ -2,39 +2,2477 @@ #include #include "../mtx/mtx.h" -#include "gcn_c/include/gfx.h" +#include "../os/OS.h" extern "C" { -#define GFX_FIFO(T) (*(volatile T*)0xCC008000) +typedef enum _GXPrimitive { + /* 0x80 */ GX_QUADS = 0x80, + /* 0x90 */ GX_TRIANGLES = 0x90, + /* 0x98 */ GX_TRIANGLESTRIP = 0x98, + /* 0xA0 */ GX_TRIANGLEFAN = 0xA0, + /* 0xA8 */ GX_LINES = 0xA8, + /* 0xB0 */ GX_LINESTRIP = 0xB0, + /* 0xB8 */ GX_POINTS = 0xB8, +} GXPrimitive; -inline void GXPosition3float(f32 x, f32 y, f32 z) { - GFX_FIFO(f32) = x; - GFX_FIFO(f32) = y; - GFX_FIFO(f32) = z; +typedef enum _GXCullMode { + /* 0x0 */ GX_CULL_NONE, + /* 0x1 */ GX_CULL_FRONT, + /* 0x2 */ GX_CULL_BACK, + /* 0x3 */ GX_CULL_ALL +} GXCullMode; + +typedef u8 GXBool; + +#define GX_TRUE ((GXBool)1) +#define GX_FALSE ((GXBool)0) +#define GX_ENABLE ((GXBool)1) +#define GX_DISABLE ((GXBool)0) + +typedef enum _GXTexMapID { + /* 0x000 */ GX_TEXMAP0, + /* 0x001 */ GX_TEXMAP1, + /* 0x002 */ GX_TEXMAP2, + /* 0x003 */ GX_TEXMAP3, + /* 0x004 */ GX_TEXMAP4, + /* 0x005 */ GX_TEXMAP5, + /* 0x006 */ GX_TEXMAP6, + /* 0x007 */ GX_TEXMAP7, + /* 0x008 */ GX_MAX_TEXMAP, + /* 0x0FF */ GX_TEXMAP_NULL = 255, + /* 0x100 */ GX_TEXMAP_DISABLE, +} GXTexMapID; + +typedef enum _GXTevStageID { + /* 0x00 */ GX_TEVSTAGE0, + /* 0x01 */ GX_TEVSTAGE1, + /* 0x02 */ GX_TEVSTAGE2, + /* 0x03 */ GX_TEVSTAGE3, + /* 0x04 */ GX_TEVSTAGE4, + /* 0x05 */ GX_TEVSTAGE5, + /* 0x06 */ GX_TEVSTAGE6, + /* 0x07 */ GX_TEVSTAGE7, + /* 0x08 */ GX_TEVSTAGE8, + /* 0x09 */ GX_TEVSTAGE9, + /* 0x0A */ GX_TEVSTAGE10, + /* 0x0B */ GX_TEVSTAGE11, + /* 0x0C */ GX_TEVSTAGE12, + /* 0x0D */ GX_TEVSTAGE13, + /* 0x0E */ GX_TEVSTAGE14, + /* 0x0F */ GX_TEVSTAGE15, + /* 0x10 */ GX_MAX_TEVSTAGE, +} GXTevStageID; + +typedef enum _GXTexCoordID { + /* 0x00 */ GX_TEXCOORD0, + /* 0x01 */ GX_TEXCOORD1, + /* 0x02 */ GX_TEXCOORD2, + /* 0x03 */ GX_TEXCOORD3, + /* 0x04 */ GX_TEXCOORD4, + /* 0x05 */ GX_TEXCOORD5, + /* 0x06 */ GX_TEXCOORD6, + /* 0x07 */ GX_TEXCOORD7, + /* 0x08 */ GX_MAXCOORD, + /* 0xFF */ GX_TEXCOORD_NULL = 255, +} GXTexCoordID; + +typedef enum _GXChannelID { + /* 0x00 */ GX_COLOR0, + /* 0x01 */ GX_COLOR1, + /* 0x02 */ GX_ALPHA0, + /* 0x03 */ GX_ALPHA1, + /* 0x04 */ GX_COLOR0A0, + /* 0x05 */ GX_COLOR1A1, + /* 0x06 */ GX_COLOR_ZERO, + /* 0x07 */ GX_ALPHA_BUMP, + /* 0x08 */ GX_ALPHA_BUMPN, + /* 0xFF */ GX_COLOR_NULL = 255, +} GXChannelID; + +typedef enum _GXColorSrc { + /* 0x0 */ GX_SRC_REG, + /* 0x1 */ GX_SRC_VTX, +} GXColorSrc; + +typedef enum _GXLightID { + /* 0x000 */ GX_LIGHT_NULL = 0, + /* 0x001 */ GX_LIGHT0 = 1 << 0, + /* 0x002 */ GX_LIGHT1 = 1 << 1, + /* 0x004 */ GX_LIGHT2 = 1 << 2, + /* 0x008 */ GX_LIGHT3 = 1 << 3, + /* 0x010 */ GX_LIGHT4 = 1 << 4, + /* 0x020 */ GX_LIGHT5 = 1 << 5, + /* 0x040 */ GX_LIGHT6 = 1 << 6, + /* 0x080 */ GX_LIGHT7 = 1 << 7, + /* 0x100 */ GX_MAX_LIGHT = 1 << 8, +} GXLightID; + +typedef enum _GXDiffuseFn { + /* 0x0 */ GX_DF_NONE, + /* 0x1 */ GX_DF_SIGN, + /* 0x2 */ GX_DF_CLAMP, +} GXDiffuseFn; + +typedef enum _GXAttnFn { + /* 0x0 */ GX_AF_SPEC, + /* 0x1 */ GX_AF_SPOT, + /* 0x2 */ GX_AF_NONE, +} GXAttnFn; + +typedef enum _GXDistAttnFn { + /* 0x0 */ GX_DA_OFF, + /* 0x1 */ GX_DA_GENTLE, + /* 0x2 */ GX_DA_MEDIUM, + /* 0x3 */ GX_DA_STEEP +} GXDistAttnFn; + +typedef enum _GXSpotFn { + /* 0x0 */ GX_SP_OFF, + /* 0x1 */ GX_SP_FLAT, + /* 0x2 */ GX_SP_COS, + /* 0x3 */ GX_SP_COS2, + /* 0x4 */ GX_SP_SHARP, + /* 0x5 */ GX_SP_RING1, + /* 0x6 */ GX_SP_RING2 +} GXSpotFn; + +typedef enum _GXTevMode { + /* 0x0 */ GX_MODULATE, + /* 0x1 */ GX_DECAL, + /* 0x2 */ GX_BLEND, + /* 0x3 */ GX_REPLACE, + /* 0x4 */ GX_PASSCLR, +} GXTevMode; + +typedef enum _GXBlendMode { + /* 0x0 */ GX_BM_NONE, + /* 0x1 */ GX_BM_BLEND, + /* 0x2 */ GX_BM_LOGIC, + /* 0x3 */ GX_BM_SUBTRACT, + /* 0x4 */ GX_MAX_BLENDMODE, +} GXBlendMode; + +typedef enum _GXBlendFactor { + /* 0x0 */ GX_BL_ZERO, + /* 0x1 */ GX_BL_ONE, + /* 0x2 */ GX_BL_SRC_COLOR, + /* 0x2 */ GX_BL_DST_COLOR = 2, + /* 0x3 */ GX_BL_INV_SRC_COLOR, + /* 0x3 */ GX_BL_INV_DST_COLOR = 3, + /* 0x4 */ GX_BL_SRC_ALPHA, + /* 0x5 */ GX_BL_INV_SRC_ALPHA, + /* 0x6 */ GX_BL_DST_ALPHA, + /* 0x7 */ GX_BL_INV_DST_ALPHA, +} GXBlendFactor; + +typedef enum _GXLogicOp { + /* 0x0 */ GX_LO_CLEAR, + /* 0x1 */ GX_LO_AND, + /* 0x2 */ GX_LO_REV_AND, + /* 0x3 */ GX_LO_COPY, + /* 0x4 */ GX_LO_INV_AND, + /* 0x5 */ GX_LO_NOOP, + /* 0x6 */ GX_LO_XOR, + /* 0x7 */ GX_LO_OR, + /* 0x8 */ GX_LO_NOR, + /* 0x9 */ GX_LO_EQUIV, + /* 0xA */ GX_LO_INV, + /* 0xB */ GX_LO_REV_OR, + /* 0xC */ GX_LO_INV_COPY, + /* 0xD */ GX_LO_INV_OR, + /* 0xE */ GX_LO_NAND, + /* 0xF */ GX_LO_SET, +} GXLogicOp; + +typedef enum _GXVtxFmt { + /* 0x0 */ GX_VTXFMT0, + /* 0x1 */ GX_VTXFMT1, + /* 0x2 */ GX_VTXFMT2, + /* 0x3 */ GX_VTXFMT3, + /* 0x4 */ GX_VTXFMT4, + /* 0x5 */ GX_VTXFMT5, + /* 0x6 */ GX_VTXFMT6, + /* 0x7 */ GX_VTXFMT7, + /* 0x8 */ GX_MAX_VTXFMT, +} GXVtxFmt; + +typedef enum _GXAttr { + /* 0x00 */ GX_VA_PNMTXIDX, + /* 0x01 */ GX_VA_TEX0MTXIDX, + /* 0x02 */ GX_VA_TEX1MTXIDX, + /* 0x03 */ GX_VA_TEX2MTXIDX, + /* 0x04 */ GX_VA_TEX3MTXIDX, + /* 0x05 */ GX_VA_TEX4MTXIDX, + /* 0x06 */ GX_VA_TEX5MTXIDX, + /* 0x07 */ GX_VA_TEX6MTXIDX, + /* 0x08 */ GX_VA_TEX7MTXIDX, + /* 0x09 */ GX_VA_POS, + /* 0x0A */ GX_VA_NRM, + /* 0x0B */ GX_VA_CLR0, + /* 0x0C */ GX_VA_CLR1, + /* 0x0D */ GX_VA_TEX0, + /* 0x0E */ GX_VA_TEX1, + /* 0x0F */ GX_VA_TEX2, + /* 0x10 */ GX_VA_TEX3, + /* 0x11 */ GX_VA_TEX4, + /* 0x12 */ GX_VA_TEX5, + /* 0x13 */ GX_VA_TEX6, + /* 0x14 */ GX_VA_TEX7, + /* 0x15 */ GX_POS_MTX_ARRAY, + /* 0x16 */ GX_NRM_MTX_ARRAY, + /* 0x17 */ GX_TEX_MTX_ARRAY, + /* 0x18 */ GX_LIGHT_ARRAY, + /* 0x19 */ GX_VA_NBT, + /* 0x1A */ GX_VA_MAX_ATTR, + /* 0xFF */ GX_VA_NULL = 255, +} GXAttr; + +typedef enum _GXCompCnt { + GX_POS_XY = 0, // Position X, Y (two components). + GX_POS_XYZ = 1, // Position X, Y, Z (three components). + + GX_NRM_XYZ = 0, // Normal X, Y, Z (three components). + GX_NRM_NBT = 1, // Normal, binormal, tangent (three components). + GX_NRM_NBT3 = 2, // Normal, binormal, tangent (three components). Use when NBT + // normal is indexed independently. + + GX_CLR_RGB = 0, // RGB (three components). + GX_CLR_RGBA = 1, // RGBA (four components). + + GX_TEX_S = 0, // Texture coordinate S (one component). + GX_TEX_ST = 1, // Texture coordinates S, T (two components). + + GX_COMPCNT_NULL = 0, // Null count. +} GXCompCnt; + +typedef enum _GXCompType { + GX_U8 = 0, // Unsigned 8-bit. + GX_S8 = 1, // Signed 8-bit. + GX_U16 = 2, // Unsigned 16-bit. + GX_S16 = 3, // Signed 16-bit. + GX_F32 = 4, // Floating-point 32-bit. + + GX_RGB565 = 0, // RGB565 16-bit. + GX_RGB8 = 1, // RGB888 24-bit. + GX_RGBX8 = 2, // RGB888x 32-bit. + GX_RGBA4 = 3, // RGBA4444 16-bit. + GX_RGBA6 = 4, // RGBA6666 24-bit. + GX_RGBA8 = 5, // RGBA8888 32-bit. + + GX_COMP_NULL = 0, // Null type. +} GXCompType; + +typedef enum _GXAttrType { + /* 0x0 */ GX_NONE, + /* 0x1 */ GX_DIRECT, + /* 0x2 */ GX_INDEX8, + /* 0x3 */ GX_INDEX16, +} GXAttrType; + +typedef enum _GXTevOp { + /* 0x0 */ GX_TEV_ADD, + /* 0x1 */ GX_TEV_SUB, + /* 0x8 */ GX_TEV_COMP_R8_GT = 8, + /* 0x9 */ GX_TEV_COMP_R8_EQ, + /* 0xA */ GX_TEV_COMP_GR16_GT, + /* 0xB */ GX_TEV_COMP_GR16_EQ, + /* 0xC */ GX_TEV_COMP_BGR24_GT, + /* 0xD */ GX_TEV_COMP_BGR24_EQ, + /* 0xE */ GX_TEV_COMP_A8_GT, + /* 0xE */ GX_TEV_COMP_RGB8_GT = 14, + /* 0xF */ GX_TEV_COMP_RGB8_EQ, + /* 0xF */ GX_TEV_COMP_A8_EQ = 15, +} GXTevOp; + +typedef enum _GXTevBias { + /* 0x0 */ GX_TB_ZERO, + /* 0x1 */ GX_TB_ADDHALF, + /* 0x2 */ GX_TB_SUBHALF, + /* 0x3 */ GX_MAX_TEVBIAS, +} GXTevBias; + +typedef enum _GXTevColorArg { + /* 0x0 */ GX_CC_CPREV, + /* 0x1 */ GX_CC_APREV, + /* 0x2 */ GX_CC_C0, + /* 0x3 */ GX_CC_A0, + /* 0x4 */ GX_CC_C1, + /* 0x5 */ GX_CC_A1, + /* 0x6 */ GX_CC_C2, + /* 0x7 */ GX_CC_A2, + /* 0x8 */ GX_CC_TEXC, + /* 0x9 */ GX_CC_TEXA, + /* 0xA */ GX_CC_RASC, + /* 0xB */ GX_CC_RASA, + /* 0xC */ GX_CC_ONE, + /* 0xD */ GX_CC_HALF, + /* 0xE */ GX_CC_KONST, + /* 0xF */ GX_CC_ZERO, +} GXTevColorArg; + +typedef enum _GXTevColor { + /* 0x0 */ GX_CH_RED, + /* 0x1 */ GX_CH_GREEN, + /* 0x2 */ GX_CH_BLUE, + /* 0x3 */ GX_CH_ALPHA, +} GXTevColor; + +typedef enum _GXTevScale { + /* 0x0 */ GX_CS_SCALE_1, + /* 0x1 */ GX_CS_SCALE_2, + /* 0x2 */ GX_CS_SCALE_4, + /* 0x3 */ GX_CS_DIVIDE_2, + /* 0x4 */ GX_MAX_TEVSCALE +} GXTevScale; + +typedef enum _GXTevRegID { + /* 0x0 */ GX_TEVPREV, + /* 0x1 */ GX_TEVREG0, + /* 0x2 */ GX_TEVREG1, + /* 0x3 */ GX_TEVREG2, + /* 0x4 */ GX_MAX_TEVREG +} GXTevRegID; + +typedef enum _GXTevAlphaArg { + /* 0x0 */ GX_CA_APREV, + /* 0x1 */ GX_CA_A0, + /* 0x2 */ GX_CA_A1, + /* 0x3 */ GX_CA_A2, + /* 0x4 */ GX_CA_TEXA, + /* 0x5 */ GX_CA_RASA, + /* 0x6 */ GX_CA_KONST, + /* 0x7 */ GX_CA_ZERO, +} GXTevAlphaArg; + +/** + * RGB, RGBA, Intensity, Intensity/Alpha, Compressed, and Z texture format + * types. See GXCITexFmt for information on color index formats. The CTF format + * is used only by the GXSetTexCopyDst function to specify how data is copied + * out of the EFB into a texture in main memory. In order to actually use that + * texture, you must specify a non-copy format of matching size. For example, if + * copying using GX_CTF_RG8, you would apply the resulting texture using + * GX_TF_IA8. + */ +typedef enum _GXTexFmt { + // Intensities (I) and RGB/RGBA. + GX_TF_I4 = 0x0, // 4-bit I + GX_TF_I8 = 0x1, // 8-bit I + GX_TF_IA4 = 0x2, // 8-bit I + alpha (4+4). + GX_TF_IA8 = 0x3, // 16-bit I + alpha (8+8). + GX_TF_RGB565 = 0x4, // 16-bit RGB. + GX_TF_RGB5A3 = 0x5, // MSB=1, RGB555 (opaque). MSB=0, RGBA4443 (transparent). + GX_TF_RGBA8 = 0x6, // 32-bit RGB. + GX_TF_CI14 = 0x9, + GX_TF_CMPR = 0xE, // Compressed 4-bit texel. + + // Z-texture format. + GX_TF_Z8 = 0x11, // Unsigned 8-bit Z. For texture copies, specify the upper 8 bits of Z. + GX_TF_Z16 = 0x13, // Unsigned 16-bit Z. For texture copies, specify the upper 16 bits of Z. + GX_TF_Z24X8 = 0x16, // Unsigned 24-bit (32-bit texture) Z. For texture copies, copy the 24-bit + // Z and 0xff. + + // Copy-texture format. + GX_CTF_R4 = 0x20, // 4-bit red. For copying 4 bits from red. + GX_CTF_RA4 = 0x22, // 4-bit red + 4-bit alpha. For copying 4 bits from red, 4 bits from alpha. + GX_CTF_RA8 = 0x23, // 8-bit red + 8-bit alpha. For copying 8 bits from red, 8 bits from alpha. + GX_CTF_YUVA8 = 0x26, // 8-bit YUV + alpha. For copying 8 bits from YUV, 8 bits from alpha. + GX_CTF_A8 = 0x26, // 8-bit alpha. For copying 8 bits from alpha. + GX_CTF_R8 = 0x27, // 8-bit red. For copying 8 bits from red. + GX_CTF_G8 = 0x28, // 8-bit green. For copying 8 bits from green. + GX_CTF_B8 = 0x29, // 8-bit blue. For copying 8 bits from blue. + GX_CTF_RG8 = 0x2A, // 8-bit red +8-bit green. For copying 8 bits from red, 8 bits from green. + GX_CTF_GB8 = 0x2B, // 8-bit green +8-bit blue. For copying 8 bits from green, 8 bits from blue. + + // Copy-Z-texture format. + GX_CTF_Z4 = 0x30, // 4-bit Z. For copying the 4 upper bits from Z. + GX_CTF_Z8M = 0x39, // 8-bit Z (median byte). For copying the middle 8 bits of Z. + GX_CTF_Z8L = 0x3A, // 8-bit Z (lower byte). For copying the lower 8 bits of Z. + GX_CTF_Z16L = 0x3C, // 16-bit Z (lower portion). For copying the lower 16 bits of Z. +} GXTexFmt; + +typedef enum _GXGamma { + /* 0x0 */ GX_GM_1_0, + /* 0x0 */ GX_GM_1_7, + /* 0x0 */ GX_GM_2_2, +} GXGamma; + +typedef enum _GXTlutFmt { + /* 0x0 */ GX_TL_IA8, + /* 0x1 */ GX_TL_RGB565, + /* 0x2 */ GX_TL_RGB5A3, +} GXTlutFmt; + +typedef enum _GXTlut { + /* 0x00 */ GX_TLUT0, + /* 0x01 */ GX_TLUT1, + /* 0x02 */ GX_TLUT2, + /* 0x03 */ GX_TLUT3, + /* 0x04 */ GX_TLUT4, + /* 0x05 */ GX_TLUT5, + /* 0x06 */ GX_TLUT6, + /* 0x07 */ GX_TLUT7, + /* 0x08 */ GX_TLUT8, + /* 0x09 */ GX_TLUT9, + /* 0x0A */ GX_TLUT10, + /* 0x0B */ GX_TLUT11, + /* 0x0C */ GX_TLUT12, + /* 0x0D */ GX_TLUT13, + /* 0x0E */ GX_TLUT14, + /* 0x0F */ GX_TLUT15, + /* 0x10 */ GX_MAX_TLUT, + /* 0x10 */ GX_BIGTLUT0 = 0x10, + /* 0x11 */ GX_BIGTLUT1, + /* 0x12 */ GX_BIGTLUT2, + /* 0x13 */ GX_BIGTLUT3, + /* 0x13 */ GX_MAX_BIGTLUT = 4, + + GX_MAX_TLUT_ALL = GX_MAX_TLUT + GX_MAX_BIGTLUT, +} GXTlut; + +typedef enum _GXTexWrapMode { + /* 0x0 */ GX_CLAMP, + /* 0x1 */ GX_REPEAT, + /* 0x2 */ GX_MIRROR, + /* 0x3 */ GX_MAX_TEXWRAP_MODE, +} GXTexWrapMode; + +typedef enum _GXTexFilter { + /* 0x0 */ GX_NEAR, + /* 0x1 */ GX_LINEAR, + /* 0x2 */ GX_NEAR_MIP_NEAR, + /* 0x3 */ GX_LIN_MIP_NEAR, + /* 0x4 */ GX_NEAR_MIP_LIN, + /* 0x5 */ GX_LIN_MIP_LIN, +} GXTexFilter; + +typedef enum _GXAnisotropy { + /* 0x0 */ GX_ANISO_1, + /* 0x1 */ GX_ANISO_2, + /* 0x2 */ GX_ANISO_4, + /* 0x3 */ GX_MAX_ANISOTROPY, +} GXAnisotropy; + +typedef enum _GXCITexFmt { + /* 0x8 */ GX_TF_C4 = 8, + /* 0x8 */ GX_TF_C8, + /* 0xA */ GX_TF_C14X2 +} GXCITexFmt; + +typedef enum _GXTexMtxType { + /* 0x0 */ GX_MTX3x4, + /* 0x1 */ GX_MTX2x4 +} GXTexMtxType; + +typedef enum _GXCompare { + /* 0x0 */ GX_NEVER, + /* 0x1 */ GX_LESS, + /* 0x2 */ GX_EQUAL, + /* 0x3 */ GX_LEQUAL, + /* 0x4 */ GX_GREATER, + /* 0x5 */ GX_NEQUAL, + /* 0x6 */ GX_GEQUAL, + /* 0x7 */ GX_ALWAYS, +} GXCompare; + +typedef enum _GXAlphaOp { + /* 0x0 */ GX_AOP_AND, + /* 0x1 */ GX_AOP_OR, + /* 0x2 */ GX_AOP_XOR, + /* 0x3 */ GX_AOP_XNOR, + /* 0x4 */ GX_MAX_ALPHAOP +} GXAlphaOp; + +typedef enum _GXFogType { + /* 0x0 */ GX_FOG_NONE, + /* 0x2 */ GX_FOG_LIN = 2, + /* 0x2 */ GX_FOG_PERSP_LIN = 2, + /* 0x4 */ GX_FOG_EXP = 4, + /* 0x4 */ GX_FOG_PERSP_EXP = 4, + /* 0x5 */ GX_FOG_EXP2, + /* 0x5 */ GX_FOG_PERSP_EXP2 = 5, + /* 0x6 */ GX_FOG_REVEXP, + /* 0x6 */ GX_FOG_PERSP_REVEXP = 6, + /* 0x7 */ GX_FOG_REVEXP2, + /* 0x7 */ GX_FOG_PERSP_REVEXP2 = 7, + /* 0xA */ GX_FOG_ORTHO_LIN = 10, + /* 0xC */ GX_FOG_ORTHO_EXP = 12, + /* 0xD */ GX_FOG_ORTHO_EXP2, + /* 0xE */ GX_FOG_ORTHO_REVEXP, + /* 0xF */ GX_FOG_ORTHO_REVEXP2, +} GXFogType; + +typedef enum _GXProjectionType { + /* 0x0 */ GX_PERSPECTIVE, + /* 0x1 */ GX_ORTHOGRAPHIC +} GXProjectionType; + +typedef enum _GXTevKAlphaSel { + /* 0x00 */ GX_TEV_KASEL_1, + /* 0x01 */ GX_TEV_KASEL_7_8, + /* 0x02 */ GX_TEV_KASEL_3_4, + /* 0x03 */ GX_TEV_KASEL_5_8, + /* 0x04 */ GX_TEV_KASEL_1_2, + /* 0x05 */ GX_TEV_KASEL_3_8, + /* 0x06 */ GX_TEV_KASEL_1_4, + /* 0x07 */ GX_TEV_KASEL_1_8, + + /* 0x10 */ GX_TEV_KASEL_K0_R = 0x10, + /* 0x11 */ GX_TEV_KASEL_K1_R, + /* 0x12 */ GX_TEV_KASEL_K2_R, + /* 0x13 */ GX_TEV_KASEL_K3_R, + /* 0x14 */ GX_TEV_KASEL_K0_G, + /* 0x15 */ GX_TEV_KASEL_K1_G, + /* 0x16 */ GX_TEV_KASEL_K2_G, + /* 0x17 */ GX_TEV_KASEL_K3_G, + /* 0x18 */ GX_TEV_KASEL_K0_B, + /* 0x19 */ GX_TEV_KASEL_K1_B, + /* 0x1A */ GX_TEV_KASEL_K2_B, + /* 0x1B */ GX_TEV_KASEL_K3_B, + /* 0x1C */ GX_TEV_KASEL_K0_A, + /* 0x1D */ GX_TEV_KASEL_K1_A, + /* 0x1E */ GX_TEV_KASEL_K2_A, + /* 0x1F */ GX_TEV_KASEL_K3_A, +} GXTevKAlphaSel; + +typedef enum _GXTevKColorSel { + /* 0x00 */ GX_TEV_KCSEL_1, + /* 0x01 */ GX_TEV_KCSEL_7_8, + /* 0x02 */ GX_TEV_KCSEL_3_4, + /* 0x03 */ GX_TEV_KCSEL_5_8, + /* 0x04 */ GX_TEV_KCSEL_1_2, + /* 0x05 */ GX_TEV_KCSEL_3_8, + /* 0x06 */ GX_TEV_KCSEL_1_4, + /* 0x07 */ GX_TEV_KCSEL_1_8, + /* 0x0C */ GX_TEV_KCSEL_K0 = 0xC, + /* 0x0D */ GX_TEV_KCSEL_K1, + /* 0x0E */ GX_TEV_KCSEL_K2, + /* 0x0F */ GX_TEV_KCSEL_K3, + /* 0x10 */ GX_TEV_KCSEL_K0_R, + /* 0x11 */ GX_TEV_KCSEL_K1_R, + /* 0x12 */ GX_TEV_KCSEL_K2_R, + /* 0x13 */ GX_TEV_KCSEL_K3_R, + /* 0x14 */ GX_TEV_KCSEL_K0_G, + /* 0x15 */ GX_TEV_KCSEL_K1_G, + /* 0x16 */ GX_TEV_KCSEL_K2_G, + /* 0x17 */ GX_TEV_KCSEL_K3_G, + /* 0x18 */ GX_TEV_KCSEL_K0_B, + /* 0x19 */ GX_TEV_KCSEL_K1_B, + /* 0x1A */ GX_TEV_KCSEL_K2_B, + /* 0x1B */ GX_TEV_KCSEL_K3_B, + /* 0x1C */ GX_TEV_KCSEL_K0_A, + /* 0x1D */ GX_TEV_KCSEL_K1_A, + /* 0x1E */ GX_TEV_KCSEL_K2_A, + /* 0x1F */ GX_TEV_KCSEL_K3_A, +} GXTevKColorSel; + +typedef enum _GXTevSwapSel { + /* 0x0 */ GX_TEV_SWAP0, + /* 0x1 */ GX_TEV_SWAP1, + /* 0x2 */ GX_TEV_SWAP2, + /* 0x3 */ GX_TEV_SWAP3, + /* 0x4 */ GX_MAX_TEVSWAP, +} GXTevSwapSel; + +typedef enum _GXTexGenType { + /* 0x0 */ GX_TG_MTX3x4, + /* 0x1 */ GX_TG_MTX2x4, + /* 0x2 */ GX_TG_BUMP0, + /* 0x3 */ GX_TG_BUMP1, + /* 0x4 */ GX_TG_BUMP2, + /* 0x5 */ GX_TG_BUMP3, + /* 0x6 */ GX_TG_BUMP4, + /* 0x7 */ GX_TG_BUMP5, + /* 0x8 */ GX_TG_BUMP6, + /* 0x9 */ GX_TG_BUMP7, + /* 0xA */ GX_TG_SRTG, +} GXTexGenType; + +typedef enum _GXTexGenSrc { + /* 0x00 */ GX_TG_POS, + /* 0x01 */ GX_TG_NRM, + /* 0x02 */ GX_TG_BINRM, + /* 0x03 */ GX_TG_TANGENT, + /* 0x04 */ GX_TG_TEX0, + /* 0x05 */ GX_TG_TEX1, + /* 0x06 */ GX_TG_TEX2, + /* 0x07 */ GX_TG_TEX3, + /* 0x08 */ GX_TG_TEX4, + /* 0x09 */ GX_TG_TEX5, + /* 0x0A */ GX_TG_TEX6, + /* 0x0B */ GX_TG_TEX7, + /* 0x0C */ GX_TG_TEXCOORD0, + /* 0x0D */ GX_TG_TEXCOORD1, + /* 0x0E */ GX_TG_TEXCOORD2, + /* 0x0F */ GX_TG_TEXCOORD3, + /* 0x10 */ GX_TG_TEXCOORD4, + /* 0x11 */ GX_TG_TEXCOORD5, + /* 0x12 */ GX_TG_TEXCOORD6, + /* 0x13 */ GX_TG_COLOR0, + /* 0x14 */ GX_TG_COLOR1, +} GXTexGenSrc; + +typedef enum _GXZTexOp { + /* 0x0 */ GX_ZT_DISABLE, + /* 0x1 */ GX_ZT_ADD, + /* 0x2 */ GX_ZT_REPLACE, + /* 0x3 */ GX_MAX_ZTEXOP, +} GXZTexOp; + +typedef enum _GXIndTexStageID { + /* 0x0 */ GX_INDTEXSTAGE0, + /* 0x1 */ GX_INDTEXSTAGE1, + /* 0x2 */ GX_INDTEXSTAGE2, + /* 0x3 */ GX_INDTEXSTAGE3, + /* 0x4 */ GX_MAX_INDTEXSTAGE, +} GXIndTexStageID; + +typedef enum _GXIndTexScale { + /* 0x0 */ GX_ITS_1, + /* 0x1 */ GX_ITS_2, + /* 0x2 */ GX_ITS_4, + /* 0x3 */ GX_ITS_8, + /* 0x4 */ GX_ITS_16, + /* 0x5 */ GX_ITS_32, + /* 0x6 */ GX_ITS_64, + /* 0x7 */ GX_ITS_128, + /* 0x8 */ GX_ITS_256, + /* 0x9 */ GX_MAX_ITSCALE, +} GXIndTexScale; + +typedef enum _GXIndTexMtxID { + /* 0x0 */ GX_ITM_OFF, + /* 0x1 */ GX_ITM_0, + /* 0x2 */ GX_ITM_1, + /* 0x3 */ GX_ITM_2, + /* 0x4 */ GX_ITM_3, + /* 0x5 */ GX_ITM_S0 = 5, + /* 0x6 */ GX_ITM_S1, + /* 0x7 */ GX_ITM_S2, + /* 0x8 */ GX_ITM_S3, + /* 0x9 */ GX_ITM_T0 = 9, + /* 0xA */ GX_ITM_T1, + /* 0xB */ GX_ITM_T2, +} GXIndTexMtxID; + +typedef enum _GXIndTexFormat { + /* 0x0 */ GX_ITF_8, + /* 0x1 */ GX_ITF_5, + /* 0x2 */ GX_ITF_4, + /* 0x3 */ GX_ITF_3, +} GXIndTexFormat; + +typedef enum _GXIndTexBiasSel { + /* 0x0 */ GX_ITB_NONE, + /* 0x1 */ GX_ITB_S, + /* 0x2 */ GX_ITB_T, + /* 0x3 */ GX_ITB_ST, + /* 0x4 */ GX_ITB_U, + /* 0x5 */ GX_ITB_SU, + /* 0x6 */ GX_ITB_TU, + /* 0x7 */ GX_ITB_STU, +} GXIndTexBiasSel; + +typedef enum _GXIndTexAlphaSel { + /* 0x0 */ GX_ITBA_OFF, + /* 0x1 */ GX_ITBA_S, + /* 0x2 */ GX_ITBA_T, + /* 0x3 */ GX_ITBA_U, +} GXIndTexAlphaSel; + +typedef enum _GXIndTexWrap { + /* 0x0 */ GX_ITW_OFF, + /* 0x1 */ GX_ITW_256, + /* 0x2 */ GX_ITW_128, + /* 0x3 */ GX_ITW_64, + /* 0x4 */ GX_ITW_32, + /* 0x5 */ GX_ITW_16, + /* 0x6 */ GX_ITW_0, +} GXIndTexWrap; + +typedef enum _GXTexOffset { + /* 0x0 */ GX_TO_ZERO, + /* 0x1 */ GX_TO_SIXTEENTH, + /* 0x2 */ GX_TO_EIGHTH, + /* 0x3 */ GX_TO_FOURTH, + /* 0x4 */ GX_TO_HALF, + /* 0x5 */ GX_TO_ONE, + /* 0x6 */ GX_MAX_TEXOFFSET, +} GXTexOffset; + +typedef enum _GXTevKColorID { + /* 0x0 */ GX_KCOLOR0, + /* 0x1 */ GX_KCOLOR1, + /* 0x2 */ GX_KCOLOR2, + /* 0x3 */ GX_KCOLOR3, +} GXTevKColorID; + +typedef enum _GXTexCacheSize { + /* 0x0 */ GX_TEXCACHE_32K, + /* 0x1 */ GX_TEXCACHE_128K, + /* 0x2 */ GX_TEXCACHE_512K, + /* 0x3 */ GX_TEXCACHE_NONE, +} GXTexCacheSize; + +typedef enum _GXPosNrmMtx { + GX_PNMTX0 = 3 * 0, + GX_PNMTX1 = 3 * 1, + GX_PNMTX2 = 3 * 2, + GX_PNMTX3 = 3 * 3, + GX_PNMTX4 = 3 * 4, + GX_PNMTX5 = 3 * 5, + GX_PNMTX6 = 3 * 6, + GX_PNMTX7 = 3 * 7, + GX_PNMTX8 = 3 * 8, + GX_PNMTX9 = 3 * 9, +} GXPosNrmMtx; + +typedef enum _GXTexMtx { + GX_TEXMTX0 = 30 + 0 * 3, + GX_TEXMTX1 = 30 + 1 * 3, + GX_TEXMTX2 = 30 + 2 * 3, + GX_TEXMTX3 = 30 + 3 * 3, + GX_TEXMTX4 = 30 + 4 * 3, + GX_TEXMTX5 = 30 + 5 * 3, + GX_TEXMTX6 = 30 + 6 * 3, + GX_TEXMTX7 = 30 + 7 * 3, + GX_TEXMTX8 = 30 + 8 * 3, + GX_TEXMTX9 = 30 + 9 * 3, + GX_IDENTITY = 60, +} GXTexMtx; + +typedef enum _GXPTTexMtx { + GX_PTTEXMTX0 = 64 + 0 * 3, + GX_PTTEXMTX1 = 64 + 1 * 3, + GX_PTTEXMTX2 = 64 + 2 * 3, + GX_PTTEXMTX3 = 64 + 3 * 3, + GX_PTTEXMTX4 = 64 + 4 * 3, + GX_PTTEXMTX5 = 64 + 5 * 3, + GX_PTTEXMTX6 = 64 + 6 * 3, + GX_PTTEXMTX7 = 64 + 7 * 3, + GX_PTTEXMTX8 = 64 + 8 * 3, + GX_PTTEXMTX9 = 64 + 9 * 3, + GX_PTTEXMTX10 = 64 + 10 * 3, + GX_PTTEXMTX11 = 64 + 11 * 3, + GX_PTTEXMTX12 = 64 + 12 * 3, + GX_PTTEXMTX13 = 64 + 13 * 3, + GX_PTTEXMTX14 = 64 + 14 * 3, + GX_PTTEXMTX15 = 64 + 15 * 3, + GX_PTTEXMTX16 = 64 + 16 * 3, + GX_PTTEXMTX17 = 64 + 17 * 3, + GX_PTTEXMTX18 = 64 + 18 * 3, + GX_PTTEXMTX19 = 64 + 19 * 3, + GX_PTIDENTITY = 125, +} GXPTTexMtx; + +typedef enum _GXFBClamp { + /* 0x0 */ GX_CLAMP_NONE, + /* 0x1 */ GX_CLAMP_TOP, + /* 0x2 */ GX_CLAMP_BOTTOM, + GX_CLAMP_BOTH = GX_CLAMP_TOP | GX_CLAMP_BOTTOM, +} GXFBClamp; + +typedef enum _GXPixelFmt { + /* 0x0 */ GX_PF_RGB8_Z24, + /* 0x1 */ GX_PF_RGBA6_Z24, + /* 0x2 */ GX_PF_RGB565_Z16, + /* 0x3 */ GX_PF_Z24, + /* 0x4 */ GX_PF_Y8, + /* 0x5 */ GX_PF_U8, + /* 0x6 */ GX_PF_V8, + /* 0x7 */ GX_PF_YUV420, + /* 0x8 */ GX_PF_MAX, +} GXPixelFmt; + +typedef enum _GXZFmt16 { + /* 0x0 */ GX_ZC_LINEAR, + /* 0x1 */ GX_ZC_NEAR, + /* 0x2 */ GX_ZC_MID, + /* 0x3 */ GX_ZC_FAR, +} GXZFmt16; + +typedef enum _GXCommand { + GX_CMD_LOAD_INDX_A = 0x20, + GX_CMD_LOAD_INDX_B = 0x28, + GX_CMD_LOAD_INDX_C = 0x30, + GX_CMD_LOAD_INDX_D = 0x38, + + GX_CMD_LOAD_CP_REG = 0x08, + GX_CMD_LOAD_XF_REG = 0x10, +} GXCommand; + +typedef enum _GXClipMode { + /* 0x0 */ GX_CLIP_ENABLE, + /* 0x1 */ GX_CLIP_DISABLE, +} GXClipMode; + +typedef enum _GXCopyMode { + /* 0x0 */ GX_COPY_PROGRESSIVE, + /* 0x1 */ GX_COPY_INTLC_EVEN, + /* 0x2 */ GX_COPY_INTLC_ODD, +} GXCopyMode; + +typedef enum _GXAlphaReadMode { + /* 0x0 */ GX_READ_00, + /* 0x1 */ GX_READ_FF, + /* 0x2 */ GX_READ_NONE, +} GXAlphaReadMode; + +typedef enum _GXTlutSize { + /* 0x001 */ GX_TLUT_16 = 1, + /* 0x002 */ GX_TLUT_32 = 2, + /* 0x004 */ GX_TLUT_64 = 4, + /* 0x008 */ GX_TLUT_128 = 8, + /* 0x010 */ GX_TLUT_256 = 16, + /* 0x020 */ GX_TLUT_512 = 32, + /* 0x040 */ GX_TLUT_1K = 64, + /* 0x080 */ GX_TLUT_2K = 128, + /* 0x100 */ GX_TLUT_4K = 256, + /* 0x200 */ GX_TLUT_8K = 512, + /* 0x400 */ GX_TLUT_16K = 1024, +} GXTlutSize; + +typedef enum _GXDirtyFlag { + GX_DIRTY_SU_TEX = (1 << 0), + GX_DIRTY_BP_MASK = (1 << 1), + GX_DIRTY_GEN_MODE = (1 << 2), + GX_DIRTY_VCD = (1 << 3), + GX_DIRTY_VAT = (1 << 4), + GX_DIRTY_AMB_COLOR0 = (1 << 8), + GX_DIRTY_AMB_COLOR1 = (1 << 9), + GX_DIRTY_MAT_COLOR0 = (1 << 10), + GX_DIRTY_MAT_COLOR1 = (1 << 11), + GX_DIRTY_MTX_IDX = (1 << 26), + GX_DIRTY_PROJECTION = (1 << 27), + GX_DIRTY_VIEWPORT = (1 << 28), + + GX_DIRTY_VLIM = GX_DIRTY_VCD | GX_DIRTY_VAT, + + GX_AMB_MAT_MASK = + GX_DIRTY_AMB_COLOR0 | GX_DIRTY_AMB_COLOR1 | GX_DIRTY_MAT_COLOR0 | GX_DIRTY_MAT_COLOR1, + GX_LIGHT_CHAN_MASK = 0x100F000, + GX_TEX_GEN_MASK = 0x2FF0000, +} GXDirtyFlag; + +// CP locator for vertex descriptor (lo). +typedef enum _GXCPVCDLo { + // Position matrix idx [31] + GX_CP_VCD_LO_POSMTXIDX_ST = 31, + GX_CP_VCD_LO_POSMTXIDX_END = 31, + + // Tex 0 matrix idx [30] + GX_CP_VCD_LO_TEX0MTXIDX_ST = 30, + GX_CP_VCD_LO_TEX0MTXIDX_END = 30, + + // Tex 1 matrix idx [29] + GX_CP_VCD_LO_TEX1MTXIDX_ST = 29, + GX_CP_VCD_LO_TEX1MTXIDX_END = 29, + + // Tex 2 matrix idx [28] + GX_CP_VCD_LO_TEX2MTXIDX_ST = 28, + GX_CP_VCD_LO_TEX2MTXIDX_END = 28, + + // Tex 3 matrix idx [27] + GX_CP_VCD_LO_TEX3MTXIDX_ST = 27, + GX_CP_VCD_LO_TEX3MTXIDX_END = 27, + + // Tex 4 matrix idx [26] + GX_CP_VCD_LO_TEX4MTXIDX_ST = 26, + GX_CP_VCD_LO_TEX4MTXIDX_END = 26, + + // Tex 5 matrix idx [25] + GX_CP_VCD_LO_TEX5MTXIDX_ST = 25, + GX_CP_VCD_LO_TEX5MTXIDX_END = 25, + + // Tex 6 matrix idx [24] + GX_CP_VCD_LO_TEX6MTXIDX_ST = 24, + GX_CP_VCD_LO_TEX6MTXIDX_END = 24, + + // Tex 7 matrix idx [23] + GX_CP_VCD_LO_TEX7MTXIDX_ST = 23, + GX_CP_VCD_LO_TEX7MTXIDX_END = 23, + + // Position [21-22] + GX_CP_VCD_LO_POS_ST = 21, + GX_CP_VCD_LO_POS_END = 22, + + // Normal [19-20] + GX_CP_VCD_LO_NRM_ST = 19, + GX_CP_VCD_LO_NRM_END = 20, + + // Color diffused [17-18] + GX_CP_VCD_LO_CLRDIF_ST = 17, + GX_CP_VCD_LO_CLRDIF_END = 18, + + // Color specular [15-16] + GX_CP_VCD_LO_CLRSPEC_ST = 15, + GX_CP_VCD_LO_CLRSPEC_END = 16, +} GXCPVCDLo; + +// CP locators for vertex descriptor (hi). +typedef enum _GXCPVCDHi { + // Tex0 coordinates [30-31] + GX_CP_VCD_HI_TEX0COORD_ST = 30, + GX_CP_VCD_HI_TEX0COORD_END = 31, + + // Tex1 coordinates [28-29] + GX_CP_VCD_HI_TEX1COORD_ST = 28, + GX_CP_VCD_HI_TEX1COORD_END = 29, + + // Tex2 coordinates [26-27] + GX_CP_VCD_HI_TEX2COORD_ST = 26, + GX_CP_VCD_HI_TEX2COORD_END = 27, + + // Tex3 coordinates [24-25] + GX_CP_VCD_HI_TEX3COORD_ST = 24, + GX_CP_VCD_HI_TEX3COORD_END = 25, + + // Tex4 coordinates [22-23] + GX_CP_VCD_HI_TEX4COORD_ST = 22, + GX_CP_VCD_HI_TEX4COORD_END = 23, + + // Tex5 coordinates [20-21] + GX_CP_VCD_HI_TEX5COORD_ST = 20, + GX_CP_VCD_HI_TEX5COORD_END = 21, + + // Tex6 coordinates [18-19] + GX_CP_VCD_HI_TEX6COORD_ST = 18, + GX_CP_VCD_HI_TEX6COORD_END = 19, + + // Tex7 coordinates [16-17] + GX_CP_VCD_HI_TEX7COORD_ST = 16, + GX_CP_VCD_HI_TEX7COORD_END = 17, +} GXCPVCDHi; + +// Command processor registers. +typedef enum _GXCPRegs { + GX_CP_REG_MTXIDXA = 0x30, // Matrix index A + GX_CP_REG_MTXIDXB = 0x40, // Matrix index B + GX_CP_REG_VCD_LO = 0x50, // Vertex descriptor (lo) + GX_CP_REG_VCD_HI = 0x60, // Vertex descriptor (hi) + GX_CP_REG_VAT_GRP0 = 0x70, // Vertex attribute table (group 0) + GX_CP_REG_VAT_GRP1 = 0x80, // Vertex attribute table (group 1) + GX_CP_REG_VAT_GRP2 = 0x90, // Vertex attribute table (group 2) + GX_CP_REG_ARRAYBASE = 0xA0, // Vertex array start/base + GX_CP_REG_ARRAYSTRIDE = 0xB0, // Vertex array stride +} GXCPRegs; + +// Transform unit registers. +typedef enum _GXXFRegs { + GX_XF_REG_ERROR = 0x1000, + GX_XF_REG_DIAGNOSTICS = 0x1001, + GX_XF_REG_STATE0 = 0x1002, + GX_XF_REG_STATE1 = 0x1003, + GX_XF_REG_CLOCK = 0x1004, + GX_XF_REG_CLIPDISABLE = 0x1005, + GX_XF_REG_PERF0 = 0x1006, + GX_XF_REG_PERF1 = 0x1007, + GX_XF_REG_INVERTEXSPEC = 0x1008, + GX_XF_REG_NUMCOLORS = 0x1009, + GX_XF_REG_AMBIENT0 = 0x100A, + GX_XF_REG_AMBIENT1 = 0x100B, + GX_XF_REG_MATERIAL0 = 0x100C, + GX_XF_REG_MATERIAL1 = 0x100D, + GX_XF_REG_COLOR0CNTRL = 0x100E, + GX_XF_REG_COLOR1CNTRL = 0x100F, + GX_XF_REG_ALPHA0CNTRL = 0x1010, + GX_XF_REG_ALPHA1CNTRL = 0x1011, + GX_XF_REG_DUALTEXTRAN = 0x1012, + GX_XF_REG_MATRIXINDEX0 = 0x1018, + GX_XF_REG_MATRIXINDEX1 = 0x1019, + GX_XF_REG_SCALEX = 0x101A, + GX_XF_REG_SCALEY = 0x101B, + GX_XF_REG_SCALEZ = 0x101C, + GX_XF_REG_OFFSETX = 0x101D, + GX_XF_REG_OFFSETY = 0x101E, + GX_XF_REG_OFFSETZ = 0x101F, + GX_XF_REG_PROJECTIONA = 0x1020, + GX_XF_REG_PROJECTIONB = 0x1021, + GX_XF_REG_PROJECTIONC = 0x1022, + GX_XF_REG_PROJECTIOND = 0x1023, + GX_XF_REG_PROJECTIONE = 0x1024, + GX_XF_REG_PROJECTIONF = 0x1025, + GX_XF_REG_PROJECTORTHO = 0x1026, + GX_XF_REG_NUMTEX = 0x103F, + GX_XF_REG_TEX0 = 0x1040, + GX_XF_REG_TEX1 = 0x1041, + GX_XF_REG_TEX2 = 0x1042, + GX_XF_REG_TEX3 = 0x1043, + GX_XF_REG_TEX4 = 0x1044, + GX_XF_REG_TEX5 = 0x1045, + GX_XF_REG_TEX6 = 0x1046, + GX_XF_REG_TEX7 = 0x1047, + GX_XF_REG_DUALTEX0 = 0x1050, + GX_XF_REG_DUALTEX1 = 0x1051, + GX_XF_REG_DUALTEX2 = 0x1052, + GX_XF_REG_DUALTEX3 = 0x1053, + GX_XF_REG_DUALTEX4 = 0x1054, + GX_XF_REG_DUALTEX5 = 0x1055, + GX_XF_REG_DUALTEX6 = 0x1056, + GX_XF_REG_DUALTEX7 = 0x1057, +} GXXFRegs; + +// Commands for interacting with the GXFifo pipe. +typedef enum _GXFifoCmd { + GX_FIFO_CMD_NOOP = 0x00, // no operation + + GX_FIFO_CMD_LOAD_BP_REG = 0x61, // load blitting processor reg + GX_FIFO_CMD_LOAD_CP_REG = 0x08, // load command processor reg + GX_FIFO_CMD_LOAD_XF_REG = 0x10, // load transform unit reg + + GX_FIFO_CMD_LOAD_INDX_A = 0x20, // load index A + GX_FIFO_CMD_LOAD_INDX_B = 0x28, // load index B + GX_FIFO_CMD_LOAD_INDX_C = 0x30, // load index C + GX_FIFO_CMD_LOAD_INDX_D = 0x38, // load index D + + GX_FIFO_CMD_CALL_DL = 0x40, // call displaylist + GX_FIFO_CMD_INVAL_VTX = 0x48, // invalid vertex + +} GXFifoCmd; + +// CP locator for vertex attribute table (group 0). +typedef enum _GXCPVATGrp0 { + // Position count [31-31] + GX_CP_VAT_GRP0_POS_CNT_ST = 31, + GX_CP_VAT_GRP0_POS_CNT_END = 31, + + // Position type [28-30] + GX_CP_VAT_GRP0_POS_TYPE_ST = 28, + GX_CP_VAT_GRP0_POS_TYPE_END = 30, + + // Position shift [23-27] + GX_CP_VAT_GRP0_POS_SHIFT_ST = 23, + GX_CP_VAT_GRP0_POS_SHIFT_END = 27, + + // Normal count [22-22] + GX_CP_VAT_GRP0_NRM_CNT_ST = 22, + GX_CP_VAT_GRP0_NRM_CNT_END = 22, + + // Normal type [19-21] + GX_CP_VAT_GRP0_NRM_TYPE_ST = 19, + GX_CP_VAT_GRP0_NRM_TYPE_END = 21, + + // Color diffused count [18-18] + GX_CP_VAT_GRP0_CLRDIFF_CNT_ST = 18, + GX_CP_VAT_GRP0_CLRDIFF_CNT_END = 18, + + // Color diffused type [15-17] + GX_CP_VAT_GRP0_CLRDIFF_TYPE_ST = 15, + GX_CP_VAT_GRP0_CLRDIFF_TYPE_END = 17, + + // Color specular count [14-14] + GX_CP_VAT_GRP0_CLRSPEC_CNT_ST = 14, + GX_CP_VAT_GRP0_CLRSPEC_CNT_END = 14, + + // Color specular type [11-13] + GX_CP_VAT_GRP0_CLRSPEC_TYPE_ST = 11, + GX_CP_VAT_GRP0_CLRSPEC_TYPE_END = 13, + + // Tex0 coord count [10-10] + GX_CP_VAT_GRP0_TXC0_CNT_ST = 10, + GX_CP_VAT_GRP0_TXC0_CNT_END = 10, + + // Tex0 coord type [7-9] + GX_CP_VAT_GRP0_TXC0_TYPE_ST = 7, + GX_CP_VAT_GRP0_TXC0_TYPE_END = 9, + + // Tex0 coord shift [2-6] + GX_CP_VAT_GRP0_TXC0_SHIFT_ST = 2, + GX_CP_VAT_GRP0_TXC0_SHIFT_END = 6, + + // Byte dequantised [1-1] + GX_CP_VAT_GRP0_BYTEDEQ_ST = 1, + GX_CP_VAT_GRP0_BYTEDEQ_END = 1, + + // Normal index 3 [0-0] (Input will be treated as three staggered indices (one per triple biased + // by component size) into normal table)) + GX_CP_VAT_GRP0_NRMIDX3_ST = 0, + GX_CP_VAT_GRP0_NRMIDX3_END = 0, +} GXCPVATGrp0; + +// CP locators for vertex attribute table (group 1). +typedef enum _GXCPVATGrp1 { + // Tex1 coord count [31-31] + GX_CP_VAT_GRP1_TXC1_CNT_ST = 31, + GX_CP_VAT_GRP1_TXC1_CNT_END = 31, + + // Tex1 coord type [28-30] + GX_CP_VAT_GRP1_TXC1_TYPE_ST = 28, + GX_CP_VAT_GRP1_TXC1_TYPE_END = 30, + + // Tex1 coord shift [23-27] + GX_CP_VAT_GRP1_TXC1_SHIFT_ST = 23, + GX_CP_VAT_GRP1_TXC1_SHIFT_END = 27, + + // Tex2 coord count [22-22] + GX_CP_VAT_GRP1_TXC2_CNT_ST = 22, + GX_CP_VAT_GRP1_TXC2_CNT_END = 22, + + // Tex2 coord type [19-21] + GX_CP_VAT_GRP1_TXC2_TYPE_ST = 19, + GX_CP_VAT_GRP1_TXC2_TYPE_END = 21, + + // Tex2 coord shift [14-18] + GX_CP_VAT_GRP1_TXC2_SHIFT_ST = 14, + GX_CP_VAT_GRP1_TXC2_SHIFT_END = 18, + + // Tex3 coord count [13-13] + GX_CP_VAT_GRP1_TXC3_CNT_ST = 13, + GX_CP_VAT_GRP1_TXC3_CNT_END = 13, + + // Tex3 coord type [10-12] + GX_CP_VAT_GRP1_TXC3_TYPE_ST = 10, + GX_CP_VAT_GRP1_TXC3_TYPE_END = 12, + + // Tex3 coord shift [5-9] + GX_CP_VAT_GRP1_TXC3_SHIFT_ST = 5, + GX_CP_VAT_GRP1_TXC3_SHIFT_END = 9, + + // Tex4 coord count [4-4] + GX_CP_VAT_GRP1_TXC4_CNT_ST = 4, + GX_CP_VAT_GRP1_TXC4_CNT_END = 4, + + // Tex4 coord type [1-3] + GX_CP_VAT_GRP1_TXC4_TYPE_ST = 1, + GX_CP_VAT_GRP1_TXC4_TYPE_END = 3, + +} GXCPVATGrp1; + +// CP locators for vertex attribute table (group 2). +typedef enum _GXCPVATGrp2 { + // Tex4 coord shift [27-31] + GX_CP_VAT_GRP2_TXC4_SHIFT_ST = 27, + GX_CP_VAT_GRP2_TXC4_SHIFT_END = 31, + + // Tex5 coord count [26-26] + GX_CP_VAT_GRP2_TXC5_CNT_ST = 26, + GX_CP_VAT_GRP2_TXC5_CNT_END = 26, + + // Tex5 coord type [23-25] + GX_CP_VAT_GRP2_TXC5_TYPE_ST = 23, + GX_CP_VAT_GRP2_TXC5_TYPE_END = 25, + + // Tex5 coord shift [18-22] + GX_CP_VAT_GRP2_TXC5_SHIFT_ST = 18, + GX_CP_VAT_GRP2_TXC5_SHIFT_END = 22, + + // Tex6 coord count [17-17] + GX_CP_VAT_GRP2_TXC6_CNT_ST = 17, + GX_CP_VAT_GRP2_TXC6_CNT_END = 17, + + // Tex6 coord type [14-16] + GX_CP_VAT_GRP2_TXC6_TYPE_ST = 14, + GX_CP_VAT_GRP2_TXC6_TYPE_END = 16, + + // Tex6 coord shift [9-13] + GX_CP_VAT_GRP2_TXC6_SHIFT_ST = 9, + GX_CP_VAT_GRP2_TXC6_SHIFT_END = 13, + + // Tex7 coord count [8-8] + GX_CP_VAT_GRP2_TXC7_CNT_ST = 8, + GX_CP_VAT_GRP2_TXC7_CNT_END = 8, + + // Tex7 coord type [5-7] + GX_CP_VAT_GRP2_TXC7_TYPE_ST = 5, + GX_CP_VAT_GRP2_TXC7_TYPE_END = 7, + + // Tex7 coord shift [0-4] + GX_CP_VAT_GRP2_TXC7_SHIFT_ST = 0, + GX_CP_VAT_GRP2_TXC7_SHIFT_END = 4, +} GXCPVATGrp2; + +// BP GenMode locators. +typedef enum _GXBPGenMode { + // Active texture counts [28-31] + GX_BP_GENMODE_NUMTEX_ST = 28, + GX_BP_GENMODE_NUMTEX_END = 31, + + // Color/channel counts [25-27] + GX_BP_GENMODE_NUMCOLORS_ST = 25, + GX_BP_GENMODE_NUMCOLORS_END = 27, + + // Multisample mode [22-22] + GX_BP_GENMODE_MULTISAMPLE_ST = 22, + GX_BP_GENMODE_MULTISAMPLE_END = 22, + + // Cull mode [16-17] + GX_BP_GENMODE_CULLMODE_ST = 16, + GX_BP_GENMODE_CULLMODE_END = 17, + + // Indirect stage counts [13-15] + GX_BP_GENMODE_NUMINDSTAGES_ST = 13, + GX_BP_GENMODE_NUMINDSTAGES_END = 15, + + // Toggle co-planar/Z-freeze [12-12] + GX_BP_GENMODE_COPLANAR_ST = 12, + GX_BP_GENMODE_COPLANAR_END = 12, +} GXBPGenMode; + +// Texture register fields for XF (transform) unit. +typedef enum _GXXfTexReg { + GX_XF_TEX_PROJ_ST = 0, // (s,t) (2x4) + GX_XF_TEX_PROJ_STQ = 1, // (s,t,q) (3x4) + + GX_XF_TEX_FORM_AB11 = 0, // (A, B, 1.0f, 1.0f), used for regular tex src + GX_XF_TEX_FORM_ABC1 = 1, // (A, B, C, 1.0f), used for geometry/normal src +} GXXfTexReg; + +// XF locators for textures. +typedef enum _GXXFTex { + // Projection type [30-30] + GX_XF_TEX_PROJTYPE_ST = 30, + GX_XF_TEX_PROJTYPE_END = 30, + + // Input format [29-29] + GX_XF_TEX_INPUTFORM_ST = 29, + GX_XF_TEX_INPUTFORM_END = 29, + + // Texture gen type [25-27] + GX_XF_TEX_TEXGENTYPE_ST = 25, + GX_XF_TEX_TEXGENTYPE_END = 27, + + // Source row [20-24] + GX_XF_TEX_SRCROW_ST = 20, + GX_XF_TEX_SRCROW_END = 24, + + // Bump source texture [17-19] + GX_XF_TEX_BUMPSRCTEX_ST = 17, + GX_XF_TEX_BUMPSRCTEX_END = 19, + + // Bump source light [14-16] + GX_XF_TEX_BUMPSRCLIGHT_ST = 14, + GX_XF_TEX_BUMPSRCLIGHT_END = 16, +} GXXFTex; + +// XF locators for dual textures. +typedef enum _GXXFDualTex { + // Base row of the transform matrix [26-31] + GX_XF_DUALTEX_BASEROW_ST = 26, + GX_XF_DUALTEX_BASEROW_END = 31, + + // Normalise texcoord before sending transform [23-23] + GX_XF_DUALTEX_NORMALISE_ST = 23, + GX_XF_DUALTEX_NORMALISE_END = 23, +} GXXFDualTex; + +// General texture commands. +typedef enum _GXXfTexGen { + GX_XF_TG_REGULAR = 0, // Regular; transform incoming data. + GX_XF_TG_BUMP = 1, // Texgen bump mapping. + GX_XF_TG_CLR0 = 2, // Color texgen for color 0 (s,t) = (r, g:b) + GX_XF_TG_CLR1 = 3, // Color texgen for color 1 (s,t) = (r, g:b) +} GXXfTexGen; + +// XF locators for matrix index 0. +typedef enum _GXXFMtxIdx0 { + // Geometry [26-31] + GX_XF_MTXIDX0_GEOM_ST = 26, + GX_XF_MTXIDX0_GEOM_END = 31, + + // Tex 0 [20-25] + GX_XF_MTXIDX0_TEX0_ST = 20, + GX_XF_MTXIDX0_TEX0_END = 25, + + // Tex 1 [14-19] + GX_XF_MTXIDX0_TEX1_ST = 14, + GX_XF_MTXIDX0_TEX1_END = 19, + + // Tex 2 [8-13] + GX_XF_MTXIDX0_TEX2_ST = 8, + GX_XF_MTXIDX0_TEX2_END = 13, + + // Tex 3 [2-7] + GX_XF_MTXIDX0_TEX3_ST = 2, + GX_XF_MTXIDX0_TEX3_END = 7, +} GXXFMtxIdx0; + +// XF locators for matrix index 1. +typedef enum _GXXFMtxIdx1 { + // Tex 4 [26-31] + GX_XF_MTXIDX1_TEX4_ST = 26, + GX_XF_MTXIDX1_TEX4_END = 31, + + // Tex 5 [20-25] + GX_XF_MTXIDX1_TEX5_ST = 20, + GX_XF_MTXIDX1_TEX5_END = 25, + + // Tex 6 [14-19] + GX_XF_MTXIDX1_TEX6_ST = 14, + GX_XF_MTXIDX1_TEX6_END = 19, + + // Tex 7 [8-13] + GX_XF_MTXIDX1_TEX7_ST = 8, + GX_XF_MTXIDX1_TEX7_END = 13, +} GXXFMtxIdx1; + +// Blitting processor registers. +typedef enum _GXBPRegs { + // gen mode + GX_BP_REG_GENMODE = 0x0, // gen mode + + // display copy filters + GX_BP_REG_DISPCOPYFILTER0 = 0x1, // display copy filter 0 + GX_BP_REG_DISPCOPYFILTER1 = 0x2, // display copy filter 1 + GX_BP_REG_DISPCOPYFILTER2 = 0x3, // display copy filter 2 + GX_BP_REG_DISPCOPYFILTER3 = 0x4, // display copy filter 3 + + // indirect matrices + GX_BP_REG_INDMTX0A = 0x6, // indirect matrix 0A + GX_BP_REG_INDMTX0B = 0x7, // indirect matrix 0B + GX_BP_REG_INDMTX0C = 0x8, // indirect matrix 0C + GX_BP_REG_INDMTX1A = 0x9, // indirect matrix 1A + GX_BP_REG_INDMTX1B = 0xA, // indirect matrix 1B + GX_BP_REG_INDMTX1C = 0xB, // indirect matrix 1C + GX_BP_REG_INDMTX2A = 0xC, // indirect matrix 2A + GX_BP_REG_INDMTX2B = 0xD, // indirect matrix 2B + GX_BP_REG_INDMTX2C = 0xE, // indirect matrix 2C + GX_BP_REG_INDIMASK = 0xF, // indirect mask + + // indirect TEV stages + GX_BP_REG_INDTEVSTAGE0 = 0x10, // indirect TEV stage 0 + GX_BP_REG_INDTEVSTAGE1 = 0x11, // indirect TEV stage 1 + GX_BP_REG_INDTEVSTAGE2 = 0x12, // indirect TEV stage 2 + GX_BP_REG_INDTEVSTAGE3 = 0x13, // indirect TEV stage 3 + GX_BP_REG_INDTEVSTAGE4 = 0x14, // indirect TEV stage 4 + GX_BP_REG_INDTEVSTAGE5 = 0x15, // indirect TEV stage 5 + GX_BP_REG_INDTEVSTAGE6 = 0x16, // indirect TEV stage 6 + GX_BP_REG_INDTEVSTAGE7 = 0x17, // indirect TEV stage 7 + GX_BP_REG_INDTEVSTAGE8 = 0x18, // indirect TEV stage 8 + GX_BP_REG_INDTEVSTAGE9 = 0x19, // indirect TEV stage 9 + GX_BP_REG_INDTEVSTAGE10 = 0x1A, // indirect TEV stage 10 + GX_BP_REG_INDTEVSTAGE11 = 0x1B, // indirect TEV stage 11 + GX_BP_REG_INDTEVSTAGE12 = 0x1C, // indirect TEV stage 12 + GX_BP_REG_INDTEVSTAGE13 = 0x1D, // indirect TEV stage 13 + GX_BP_REG_INDTEVSTAGE14 = 0x1E, // indirect TEV stage 14 + GX_BP_REG_INDTEVSTAGE15 = 0x1F, // indirect TEV stage 15 + + // performance manips + GX_BP_REG_SCISSORTL = 0x20, // scissor top left + GX_BP_REG_SCISSORBR = 0x21, // scissor bottom right + GX_BP_REG_LINEPTWIDTH = 0x22, // line point width + GX_BP_REG_PERF0TRI = 0x23, // performance 0 (triangle) + GX_BP_REG_PERF0QUAD = 0x24, // performance 0 (quad) + + // rasters + GX_BP_REG_RAS1_SS0 = 0x25, + GX_BP_REG_RAS1_SS1 = 0x26, + GX_BP_REG_RAS1_IREF = 0x27, + GX_BP_REG_RAS1_TREF0 = 0x28, + GX_BP_REG_RAS1_TREF1 = 0x29, + GX_BP_REG_RAS1_TREF2 = 0x2A, + GX_BP_REG_RAS1_TREF3 = 0x2B, + GX_BP_REG_RAS1_TREF4 = 0x2C, + GX_BP_REG_RAS1_TREF5 = 0x2D, + GX_BP_REG_RAS1_TREF6 = 0x2E, + GX_BP_REG_RAS1_TREF7 = 0x2F, + + // setup sizes + GX_BP_REG_SU_SSIZE0 = 0x30, + GX_BP_REG_SU_TSIZE0 = 0x31, + GX_BP_REG_SU_SSIZE1 = 0x32, + GX_BP_REG_SU_TSIZE1 = 0x33, + GX_BP_REG_SU_SSIZE2 = 0x34, + GX_BP_REG_SU_TSIZE2 = 0x35, + GX_BP_REG_SU_SSIZE3 = 0x36, + GX_BP_REG_SU_TSIZE3 = 0x37, + GX_BP_REG_SU_SSIZE4 = 0x38, + GX_BP_REG_SU_TSIZE4 = 0x39, + GX_BP_REG_SU_SSIZE5 = 0x3A, + GX_BP_REG_SU_TSIZE5 = 0x3B, + GX_BP_REG_SU_SSIZE6 = 0x3C, + GX_BP_REG_SU_TSIZE6 = 0x3D, + GX_BP_REG_SU_SSIZE7 = 0x3E, + GX_BP_REG_SU_TSIZE7 = 0x3F, + + // Z and blend controls + GX_BP_REG_ZMODE = 0x40, + GX_BP_REG_BLENDMODE = 0x41, + GX_BP_REG_DSTALPHA = 0x42, + GX_BP_REG_ZCONTROL = 0x43, + GX_BP_REG_FIELDMASK = 0x44, + GX_BP_REG_DRAWDONE = 0x45, + GX_BP_REG_PETOKEN = 0x47, + GX_BP_REG_PETOKENINT = 0x48, + + // copying + GX_BP_REG_TEXCOPYSRCXY = 0x49, + GX_BP_REG_TEXCOPYSRCWH = 0x4A, + GX_BP_REG_TEXCOPYDST = 0x4B, + GX_BP_REG_DISPCOPYSTRIDE = 0x4D, + GX_BP_REG_DISPCOPYSCALEY = 0x4E, + GX_BP_REG_COPYCLEARAR = 0x4F, + GX_BP_REG_COPYCLEARGB = 0x50, + GX_BP_REG_COPYCLEARZ = 0x51, + GX_BP_REG_COPYFILTER0 = 0x53, + GX_BP_REG_COPYFILTER1 = 0x54, + + // + GX_BP_REG_BOUNDINGBOX0 = 0x55, + GX_BP_REG_BOUNDINGBOX1 = 0x56, + + GX_BP_REG_SCISSOROFFSET = 0x59, + + // texture memory + GX_BP_REG_TMEMPRELOADADDR = 0x60, + GX_BP_REG_TMEMPRELOADEVEN = 0x61, + GX_BP_REG_TMEMPRELOADODD = 0x62, + GX_BP_REG_TMEMPRELOADMODE = 0x63, + GX_BP_REG_TMEMTLUTSRC = 0x64, + GX_BP_REG_TMEMTLUTDST = 0x65, + GX_BP_REG_TMEMTEXINVALIDATE = 0x66, + + // performance 1 + GX_BP_REG_PERF1 = 0x67, + GX_BP_REG_FIELDMODE = 0x68, + + // set modes + GX_BP_REG_SETMODE0_TEX0 = 0x80, + GX_BP_REG_SETMODE0_TEX1 = 0x81, + GX_BP_REG_SETMODE0_TEX2 = 0x82, + GX_BP_REG_SETMODE0_TEX3 = 0x83, + GX_BP_REG_SETMODE1_TEX0 = 0x84, + GX_BP_REG_SETMODE1_TEX1 = 0x85, + GX_BP_REG_SETMODE1_TEX2 = 0x86, + GX_BP_REG_SETMODE1_TEX3 = 0x87, + + // set images + GX_BP_REG_SETIMAGE0_TEX0 = 0x88, + GX_BP_REG_SETIMAGE0_TEX1 = 0x89, + GX_BP_REG_SETIMAGE0_TEX2 = 0x8A, + GX_BP_REG_SETIMAGE0_TEX3 = 0x8B, + GX_BP_REG_SETIMAGE1_TEX0 = 0x8C, + GX_BP_REG_SETIMAGE1_TEX1 = 0x8D, + GX_BP_REG_SETIMAGE1_TEX2 = 0x8E, + GX_BP_REG_SETIMAGE1_TEX3 = 0x8F, + GX_BP_REG_SETIMAGE2_TEX0 = 0x90, + GX_BP_REG_SETIMAGE2_TEX1 = 0x91, + GX_BP_REG_SETIMAGE2_TEX2 = 0x92, + GX_BP_REG_SETIMAGE2_TEX3 = 0x93, + GX_BP_REG_SETIMAGE3_TEX0 = 0x94, + GX_BP_REG_SETIMAGE3_TEX1 = 0x95, + GX_BP_REG_SETIMAGE3_TEX2 = 0x96, + GX_BP_REG_SETIMAGE3_TEX3 = 0x97, + + // set texture lookups + GX_BP_REG_SETTLUT_TEX0 = 0x98, + GX_BP_REG_SETTLUT_TEX1 = 0x99, + GX_BP_REG_SETTLUT_TEX2 = 0x9A, + GX_BP_REG_SETTLUT_TEX3 = 0x9B, + + // set modes continued + GX_BP_REG_SETMODE0_TEX4 = 0xA0, + GX_BP_REG_SETMODE0_TEX5 = 0xA1, + GX_BP_REG_SETMODE0_TEX6 = 0xA2, + GX_BP_REG_SETMODE0_TEX7 = 0xA3, + GX_BP_REG_SETMODE1_TEX4 = 0xA4, + GX_BP_REG_SETMODE1_TEX5 = 0xA5, + GX_BP_REG_SETMODE1_TEX6 = 0xA6, + GX_BP_REG_SETMODE1_TEX7 = 0xA7, + + // set images continued + GX_BP_REG_SETIMAGE0_TEX4 = 0xA8, + GX_BP_REG_SETIMAGE0_TEX5 = 0xA9, + GX_BP_REG_SETIMAGE0_TEX6 = 0xAA, + GX_BP_REG_SETIMAGE0_TEX7 = 0xAB, + GX_BP_REG_SETIMAGE1_TEX4 = 0xAC, + GX_BP_REG_SETIMAGE1_TEX5 = 0xAD, + GX_BP_REG_SETIMAGE1_TEX6 = 0xAE, + GX_BP_REG_SETIMAGE1_TEX7 = 0xAF, + GX_BP_REG_SETIMAGE2_TEX4 = 0xB0, + GX_BP_REG_SETIMAGE2_TEX5 = 0xB1, + GX_BP_REG_SETIMAGE2_TEX6 = 0xB2, + GX_BP_REG_SETIMAGE2_TEX7 = 0xB3, + GX_BP_REG_SETIMAGE3_TEX4 = 0xB4, + GX_BP_REG_SETIMAGE3_TEX5 = 0xB5, + GX_BP_REG_SETIMAGE3_TEX6 = 0xB6, + GX_BP_REG_SETIMAGE3_TEX7 = 0xB7, + + // set texture lookups continued + GX_BP_REG_SETTLUT_TEX4 = 0xB8, + GX_BP_REG_SETTLUT_TEX5 = 0xB9, + GX_BP_REG_SETTLUT_TEX6 = 0xBA, + GX_BP_REG_SETTLUT_TEX7 = 0xBB, + + // TEV color manips + GX_BP_REG_TEVCOLORCOMBINER0 = 0xC0, + GX_BP_REG_TEVALPHACOMBINER0 = 0xC1, + GX_BP_REG_TEVCOLORCOMBINER1 = 0xC2, + GX_BP_REG_TEVALPHACOMBINER1 = 0xC3, + GX_BP_REG_TEVCOLORCOMBINER2 = 0xC4, + GX_BP_REG_TEVALPHACOMBINER2 = 0xC5, + GX_BP_REG_TEVCOLORCOMBINER3 = 0xC6, + GX_BP_REG_TEVALPHACOMBINER3 = 0xC7, + GX_BP_REG_TEVCOLORCOMBINER4 = 0xC8, + GX_BP_REG_TEVALPHACOMBINER4 = 0xC9, + GX_BP_REG_TEVCOLORCOMBINER5 = 0xCA, + GX_BP_REG_TEVALPHACOMBINER5 = 0xCB, + GX_BP_REG_TEVCOLORCOMBINER6 = 0xCC, + GX_BP_REG_TEVALPHACOMBINER6 = 0xCD, + GX_BP_REG_TEVCOLORCOMBINER7 = 0xCE, + GX_BP_REG_TEVALPHACOMBINER7 = 0xCF, + GX_BP_REG_TEVCOLORCOMBINER8 = 0xD0, + GX_BP_REG_TEVALPHACOMBINER8 = 0xD1, + GX_BP_REG_TEVCOLORCOMBINER9 = 0xD2, + GX_BP_REG_TEVALPHACOMBINER9 = 0xD3, + GX_BP_REG_TEVCOLORCOMBINER10 = 0xD4, + GX_BP_REG_TEVALPHACOMBINER10 = 0xD5, + GX_BP_REG_TEVCOLORCOMBINER11 = 0xD6, + GX_BP_REG_TEVALPHACOMBINER11 = 0xD7, + GX_BP_REG_TEVCOLORCOMBINER12 = 0xD8, + GX_BP_REG_TEVALPHACOMBINER12 = 0xD9, + GX_BP_REG_TEVCOLORCOMBINER13 = 0xDA, + GX_BP_REG_TEVALPHACOMBINER13 = 0xDB, + GX_BP_REG_TEVCOLORCOMBINER14 = 0xDC, + GX_BP_REG_TEVALPHACOMBINER14 = 0xDD, + GX_BP_REG_TEVCOLORCOMBINER15 = 0xDE, + GX_BP_REG_TEVALPHACOMBINER15 = 0xDF, + + // TEV registers + GX_BP_REG_TEVREG0LO = 0xE0, + GX_BP_REG_TEVREG0HI = 0xE1, + GX_BP_REG_TEVREG1LO = 0xE2, + GX_BP_REG_TEVREG1HI = 0xE3, + GX_BP_REG_TEVREG2LO = 0xE4, + GX_BP_REG_TEVREG2HI = 0xE5, + GX_BP_REG_TEVREG3LO = 0xE6, + GX_BP_REG_TEVREG3HI = 0xE7, + + // fog registers + GX_BP_REG_FOGRANGE = 0xE8, + GX_BP_REG_FOGRANGEK0 = 0xE9, + GX_BP_REG_FOGRANGEK1 = 0xEA, + GX_BP_REG_FOGRANGEK2 = 0xEB, + GX_BP_REG_FOGRANGEK3 = 0xEC, + GX_BP_REG_FOGRANGEK4 = 0xED, + GX_BP_REG_FOGPARAM0 = 0xEE, + GX_BP_REG_FOGPARAM1 = 0xEF, + GX_BP_REG_FOGPARAM2 = 0xF0, + GX_BP_REG_FOGPARAM3 = 0xF1, + GX_BP_REG_FOGCOLOR = 0xF2, + + // performance manip registers + GX_BP_REG_ALPHACOMPARE = 0xF3, + GX_BP_REG_ZTEXTURE0 = 0xF4, + GX_BP_REG_ZTEXTURE1 = 0xF5, + + // TEV K selectors + GX_BP_REG_TEVKSEL0 = 0xF6, + GX_BP_REG_TEVKSEL1 = 0xF7, + GX_BP_REG_TEVKSEL2 = 0xF8, + GX_BP_REG_TEVKSEL3 = 0xF9, + GX_BP_REG_TEVKSEL4 = 0xFA, + GX_BP_REG_TEVKSEL5 = 0xFB, + GX_BP_REG_TEVKSEL6 = 0xFC, + GX_BP_REG_TEVKSEL7 = 0xFD, + + // SS mask + GX_BP_REG_SSMASK = 0xFE, +} GXBPRegs; + +// BP locators for fog parameter 0. +typedef enum _GXBPFogParam0 { + // A mantissa [21-31] + GX_BP_FOGPARAM0_A_MANT_ST = 21, + GX_BP_FOGPARAM0_A_MANT_END = 31, + + // A exponent [13-20] + GX_BP_FOGPARAM0_A_EXP_ST = 13, + GX_BP_FOGPARAM0_A_EXP_END = 20, + + // A sign [12-12] + GX_BP_FOGPARAM0_A_SIGN_ST = 12, + GX_BP_FOGPARAM0_A_SIGN_END = 12, +} GXBPFogParam0; + +// BP locators for fog parameter 1. +typedef enum _GXBPFogParam1 { + // B magnitude [8-31] + GX_BP_FOGPARAM1_B_MAG_ST = 8, + GX_BP_FOGPARAM1_B_MAG_END = 31, +} GXBPFogParam1; + +// BP locators for fog parameter 2. +typedef enum _GXBPFogParam2 { + // B shift [27-31] + GX_BP_FOGPARAM2_B_SHIFT_ST = 27, + GX_BP_FOGPARAM2_B_SHIFT_END = 31, +} GXBPFogParam2; + +// BP locators for fog parameter 3. +typedef enum _GXBPFogParam3 { + // C mantissa [21-31] + GX_BP_FOGPARAM3_C_MANT_ST = 21, + GX_BP_FOGPARAM3_C_MANT_END = 31, + + // C exponent [13-20] + GX_BP_FOGPARAM3_C_EXP_ST = 13, + GX_BP_FOGPARAM3_C_EXP_END = 20, + + // C sign [12-12] + GX_BP_FOGPARAM3_C_SIGN_ST = 12, + GX_BP_FOGPARAM3_C_SIGN_END = 12, + + // Projection [11] + GX_BP_FOGPARAM3_PROJ_ST = 11, + GX_BP_FOGPARAM3_PROJ_END = 11, + + // F select [8-10] + GX_BP_FOGPARAM3_FSEL_ST = 8, + GX_BP_FOGPARAM3_FSEL_END = 10, +} GXBPFogParam3; + +// BP locators for fog color. +typedef enum _GXBPFogColor { + // RGB components of color [8-31] + GX_BP_FOGCOLOR_RGB_ST = 8, + GX_BP_FOGCOLOR_RGB_END = 31, +} GXBPFogColor; + +// BP locators for fog range. +typedef enum _GXBPFogRange { + // Center [22-31] + GX_BP_FOGRANGE_CENTER_ST = 22, + GX_BP_FOGRANGE_CENTER_END = 31, + + // Enabled [21-21] + GX_BP_FOGRANGE_ENABLED_ST = 21, + GX_BP_FOGRANGE_ENABLED_END = 21, +} GXBPFogRange; + +// BP locators for fog range K. +typedef enum _GXBPFogRangeK { + // Hi [20-31] + GX_BP_FOGRANGEK_HI_ST = 20, + GX_BP_FOGRANGEK_HI_END = 31, + + // Lo [8-19] + GX_BP_FOGRANGEK_LO_ST = 8, + GX_BP_FOGRANGEK_LO_END = 19, +} GXBPFogRangeK; + +// BP locators for blend mode. +typedef enum _GXBPBlendMode { + // Blend enable [31-31] + GX_BP_BLENDMODE_ENABLE_ST = 31, + GX_BP_BLENDMODE_ENABLE_END = 31, + + // Logic operation enable [30-30] + GX_BP_BLENDMODE_LOGIC_OP_ST = 30, + GX_BP_BLENDMODE_LOGIC_OP_END = 30, + + // Dither [29-29] + GX_BP_BLENDMODE_DITHER_ST = 29, + GX_BP_BLENDMODE_DITHER_END = 29, + + // Color update [28-28] + GX_BP_BLENDMODE_COLOR_UPDATE_ST = 28, + GX_BP_BLENDMODE_COLOR_UPDATE_END = 28, + + // Alpha update [27-27] + GX_BP_BLENDMODE_ALPHA_UPDATE_ST = 27, + GX_BP_BLENDMODE_ALPHA_UPDATE_END = 27, + + // Destination factor [24-26] + GX_BP_BLENDMODE_DSTFACTOR_ST = 24, + GX_BP_BLENDMODE_DSTFACTOR_END = 26, + + // Source factor [21-23] + GX_BP_BLENDMODE_SRCFACTOR_ST = 21, + GX_BP_BLENDMODE_SRCFACTOR_END = 23, + + // Subtract [20-20] + GX_BP_BLENDMODE_SUBTRACT_ST = 20, + GX_BP_BLENDMODE_SUBTRACT_END = 20, + + // Logic mode [16-19] + GX_BP_BLENDMODE_LOGICMODE_ST = 16, + GX_BP_BLENDMODE_LOGICMODE_END = 19, +} GXBPBlendMode; + +// BP locators for Z mode. +typedef enum _GXBPZMode { + // Test enable [31-31] + GX_BP_ZMODE_TEST_ENABLE_ST = 31, + GX_BP_ZMODE_TEST_ENABLE_END = 31, + + // Compare [28-30] + GX_BP_ZMODE_COMPARE_ST = 28, + GX_BP_ZMODE_COMPARE_END = 30, + + // Update enable [27-27] + GX_BP_ZMODE_UPDATE_ENABLE_ST = 27, + GX_BP_ZMODE_UPDATE_ENABLE_END = 27, +} GXBPZMode; + +// BP locators for Z control. +typedef enum _GXBPZControl { + // Pixel format [29-31] + GX_BP_ZCONTROL_PIXEL_FMT_ST = 29, + GX_BP_ZCONTROL_PIXEL_FMT_END = 31, + + // Z format [26-28] + GX_BP_ZCONTROL_Z_FMT_ST = 26, + GX_BP_ZCONTROL_Z_FMT_END = 28, + + // Whether to do Z-buffering before or after texturing [25-25] + GX_BP_ZCONTROL_BEFORE_TEX_ST = 25, + GX_BP_ZCONTROL_BEFORE_TEX_END = 25, +} GXBPZControl; + +// BP locators for destination alpha. +typedef enum _GXBPDstAlpha { + // Alpha [24-31] + GX_BP_DSTALPHA_ALPHA_ST = 24, + GX_BP_DSTALPHA_ALPHA_END = 31, + + // Enable [23-23] + GX_BP_DSTALPHA_ENABLE_ST = 23, + GX_BP_DSTALPHA_ENABLE_END = 23, + + // YUV format [21-22] + GX_BP_DSTALPHA_YUV_FMT_ST = 21, + GX_BP_DSTALPHA_YUV_FMT_END = 22, +} GXBPDstAlpha; + +// BP locators for field mask. +typedef enum _GXBPFieldMask { + // Whether to write odd fields to the EFB [31-31] + GX_BP_FIELDMASK_ODD_ST = 31, + GX_BP_FIELDMASK_ODD_END = 31, + + // Whether to write even fields to the EFB [30-30] + GX_BP_FIELDMASK_EVEN_ST = 30, + GX_BP_FIELDMASK_EVEN_END = 30, +} GXBPFieldMask; + +// BP locators for line and point settings. +typedef enum _GXBPLinePtWidth { + // Line size/width [24-31] + GX_BP_LINEPTWIDTH_LINESZ_ST = 24, + GX_BP_LINEPTWIDTH_LINESZ_END = 31, + + // Point size [16-23] + GX_BP_LINEPTWIDTH_POINTSZ_ST = 16, + GX_BP_LINEPTWIDTH_POINTSZ_END = 23, + + // Line offset [13-15] + GX_BP_LINEPTWIDTH_LINEOFS_ST = 13, + GX_BP_LINEPTWIDTH_LINEOFS_END = 15, + + // Point offset [10-12] + GX_BP_LINEPTWIDTH_POINTOFS_ST = 10, + GX_BP_LINEPTWIDTH_POINTOFS_END = 12, + + // Interlacing adjustment for aspect ratio [9-9] + GX_BP_LINEPTWIDTH_ADJUST_ST = 9, + GX_BP_LINEPTWIDTH_ADJUST_END = 9, +} GXBPLinePtWidth; + +// Miscellaneous token types. +typedef enum _GXMiscToken { + GX_MT_NULL = 0, + GX_MT_XF_FLUSH = 1, + GX_MT_DL_SAVE_CONTEXT = 2, + GX_MT_ABORT_WAIT_COPYOUT = 3, +} GXMiscToken; + +// Transform memory types. +typedef enum _GXXfMem { + GX_XF_MEM_POSMTX = 0x000, // position coord matrix + GX_XF_MEM_NRMMTX = 0x400, // normal coord matrix + GX_XF_MEM_DUALTEXMTX = 0x500, // dual texture matrix + GX_XF_MEM_LIGHTOBJ = 0x600, // light object +} GXXfMem; + +// BP locators for top-left scissor. +typedef enum _GXBPScissorTL { + // Top component [21-31] + GX_BP_SCISSORTL_TOP_ST = 21, + GX_BP_SCISSORTL_TOP_END = 31, + + // Left component [9-19] + GX_BP_SCISSORTL_LEFT_ST = 9, + GX_BP_SCISSORTL_LEFT_END = 19, +} GXBPScissorTL; + +// BP locators for bottom-right scissor. +typedef enum _GXBPScissorBR { + // Bottom component [21-31] + GX_BP_SCISSORBR_BOT_ST = 21, + GX_BP_SCISSORBR_BOT_END = 31, + + // Right component [9-19] + GX_BP_SCISSORBR_RIGHT_ST = 9, + GX_BP_SCISSORBR_RIGHT_END = 19, +} GXBPScissorBR; + +// BP locators for scissor offset. +typedef enum _GXBPScissorOffset { + // X offset [22-31] + GX_BP_SCISSOROFS_OX_ST = 22, + GX_BP_SCISSOROFS_OX_END = 31, + + // Y offset [12-21] + GX_BP_SCISSOROFS_OY_ST = 12, + GX_BP_SCISSOROFS_OY_END = 21, +} GXBPScissorOffset; + +// Perf-0 types. +typedef enum _GXPerf0 { + GX_PERF0_VERTICES = 0, + GX_PERF0_CLIP_VTX = 1, + GX_PERF0_CLIP_CLKS = 2, + GX_PERF0_XF_WAIT_IN = 3, + GX_PERF0_XF_WAIT_OUT = 4, + GX_PERF0_XF_XFRM_CLKS = 5, + GX_PERF0_XF_LIT_CLKS = 6, + GX_PERF0_XF_BOT_CLKS = 7, + GX_PERF0_XF_REGLD_CLKS = 8, + GX_PERF0_XF_REGRD_CLKS = 9, + GX_PERF0_CLIP_RATIO = 10, + + GX_PERF0_TRIANGLES = 11, + GX_PERF0_TRIANGLES_CULLED = 12, + GX_PERF0_TRIANGLES_PASSED = 13, + GX_PERF0_TRIANGLES_SCISSORED = 14, + GX_PERF0_TRIANGLES_0TEX = 15, + GX_PERF0_TRIANGLES_1TEX = 16, + GX_PERF0_TRIANGLES_2TEX = 17, + GX_PERF0_TRIANGLES_3TEX = 18, + GX_PERF0_TRIANGLES_4TEX = 19, + GX_PERF0_TRIANGLES_5TEX = 20, + GX_PERF0_TRIANGLES_6TEX = 21, + GX_PERF0_TRIANGLES_7TEX = 22, + GX_PERF0_TRIANGLES_8TEX = 23, + GX_PERF0_TRIANGLES_0CLR = 24, + GX_PERF0_TRIANGLES_1CLR = 25, + GX_PERF0_TRIANGLES_2CLR = 26, + + GX_PERF0_QUAD_0CVG = 27, + GX_PERF0_QUAD_NON0CVG = 28, + GX_PERF0_QUAD_1CVG = 29, + GX_PERF0_QUAD_2CVG = 30, + GX_PERF0_QUAD_3CVG = 31, + GX_PERF0_QUAD_4CVG = 32, + GX_PERF0_AVG_QUAD_CNT = 33, + + GX_PERF0_CLOCKS = 34, + GX_PERF0_NONE = 35, +} GXPerf0; + +// Perf-1 types. +typedef enum _GXPerf1 { + GX_PERF1_TEXELS = 0, + GX_PERF1_TX_IDLE = 1, + GX_PERF1_TX_REGS = 2, + GX_PERF1_TX_MEMSTALL = 3, + GX_PERF1_TC_CHECK1_2 = 4, + GX_PERF1_TC_CHECK3_4 = 5, + GX_PERF1_TC_CHECK5_6 = 6, + GX_PERF1_TC_CHECK7_8 = 7, + GX_PERF1_TC_MISS = 8, + + GX_PERF1_VC_ELEMQ_FULL = 9, + GX_PERF1_VC_MISSQ_FULL = 10, + GX_PERF1_VC_MEMREQ_FULL = 11, + GX_PERF1_VC_STATUS7 = 12, + GX_PERF1_VC_MISSREP_FULL = 13, + GX_PERF1_VC_STREAMBUF_LOW = 14, + GX_PERF1_VC_ALL_STALLS = 15, + GX_PERF1_VERTICES = 16, + + GX_PERF1_FIFO_REQ = 17, + GX_PERF1_CALL_REQ = 18, + GX_PERF1_VC_MISS_REQ = 19, + GX_PERF1_CP_ALL_REQ = 20, + + GX_PERF1_CLOCKS = 21, + GX_PERF1_NONE = 22, +} GXPerf1; + +// Vertex cache perf types. +typedef enum _GXVCachePerf { + GX_VC_POS = 0, + GX_VC_NRM = 1, + GX_VC_CLR0 = 2, + GX_VC_CLR1 = 3, + GX_VC_TEX0 = 4, + GX_VC_TEX1 = 5, + GX_VC_TEX2 = 6, + GX_VC_TEX3 = 7, + GX_VC_TEX4 = 8, + GX_VC_TEX5 = 9, + GX_VC_TEX6 = 10, + GX_VC_TEX7 = 11, + + GX_VC_ALL = 15 +} GXVCachePerf; + +// XF locators for Color 0 control. +typedef enum _GXXFClr0Ctrl { + // Matrix source [31-31] + GX_XF_CLR0CTRL_MTXSRC_ST = 31, + GX_XF_CLR0CTRL_MTXSRC_END = 31, + + // Light [30-30] + GX_XF_CLR0CTRL_LIGHT_ST = 30, + GX_XF_CLR0CTRL_LIGHT_END = 30, + + // Light mask (hi) [26-29] + GX_XF_CLR0CTRL_LMASKHI_ST = 26, + GX_XF_CLR0CTRL_LMASKHI_END = 29, + + // Ambient source [25-25] + GX_XF_CLR0CTRL_AMBSRC_ST = 25, + GX_XF_CLR0CTRL_AMBSRC_END = 25, + + // Diffuse attenuation [23-24] + GX_XF_CLR0CTRL_DIFATTN_ST = 23, + GX_XF_CLR0CTRL_DIFATTN_END = 24, + + // Enable attentuation [22-22] + GX_XF_CLR0CTRL_ATTNENABLE_ST = 22, + GX_XF_CLR0CTRL_ATTNENABLE_END = 22, + + // Select attentuation [21-21] + GX_XF_CLR0CTRL_ATTNSEL_ST = 21, + GX_XF_CLR0CTRL_ATTNSEL_END = 21, + + // Light mask (lo) [17-20] + GX_XF_CLR0CTRL_LMASKLO_ST = 17, + GX_XF_CLR0CTRL_LMASKLO_END = 20, +} GXXFClr0Ctrl; + + +typedef struct _GXVtxDescList { + /* 0x0 */ GXAttr attr; + /* 0x4 */ GXAttrType type; +} GXVtxDescList; // Size: 0x08 + +typedef struct _GXVtxAttrFmtList { + /* 0x00 */ GXAttr attr; + /* 0x04 */ GXCompCnt cnt; + /* 0x08 */ GXCompType type; + /* 0x0C */ u8 frac; +} GXVtxAttrFmtList; // Size: 0x10 + +typedef struct _GXColor { + /* 0x0 */ u8 r; + /* 0x1 */ u8 g; + /* 0x2 */ u8 b; + /* 0x3 */ u8 a; +} GXColor; + +typedef struct _GXColorS10 { + /* 0x0 */ s16 r; + /* 0x2 */ s16 g; + /* 0x4 */ s16 b; + /* 0x6 */ s16 a; +} GXColorS10; + +typedef struct _GXRenderModeObj { + /* 0x00 */ u32 vi_tv_mode; + /* 0x04 */ u16 fb_width; + /* 0x06 */ u16 efb_height; + /* 0x08 */ u16 xfb_height; + /* 0x0A */ u16 vi_x_origin; + /* 0x0C */ u16 vi_y_origin; + /* 0x0E */ u16 vi_width; + /* 0x10 */ u16 vi_height; + /* 0x14 */ u32 xfb_mode; + /* 0x18 */ u8 field_rendering; + /* 0x19 */ u8 antialiasing; + /* 0x1A */ u8 sample_pattern[12][2]; + /* 0x32 */ u8 vfilter[7]; +} GXRenderModeObj; + +typedef struct _GXTexObj { + /* 0x00 */ u32 texture_filter; + /* 0x04 */ u32 texture_lod; + /* 0x08 */ u32 texture_size; + /* 0x0C */ u32 texture_address; + /* 0x10 */ u32 user_data; + /* 0x14 */ u32 texture_format; + /* 0x18 */ u32 tlut_name; + /* 0x1C */ u16 texture_time_count; + /* 0x1E */ u8 texture_tile_type; + /* 0x1F */ u8 texture_flags; +} GXTexObj; + +typedef struct _GXTlutObj { + /* 0x0 */ u32 format; + /* 0x4 */ u32 address; + /* 0x8 */ u16 numEntries; +} GXTlutObj; + +typedef struct _GXLightObj { + /* 0x00 */ u8 field_0x0[0xc]; + /* 0x0C */ GXColor color; + /* 0x10 */ f32 a0; + /* 0x14 */ f32 a1; + /* 0x18 */ f32 a2; + /* 0x1C */ f32 k0; + /* 0x20 */ f32 k1; + /* 0x24 */ f32 k2; + /* 0x28 */ f32 posX; + /* 0x2C */ f32 posY; + /* 0x30 */ f32 posZ; + /* 0x34 */ f32 dirX; + /* 0x38 */ f32 dirY; + /* 0x3C */ f32 dirZ; +} GXLightObj; + +typedef struct _GXFogAdjTable { + /* 0x0 */ u16 fogVals[10]; +} GXFogAdjTable; + +typedef struct _GXFifoObj { + /* 0x00 */ void* base; + /* 0x04 */ void* end; + /* 0x08 */ u32 size; + /* 0x0C */ u32 high_wtrmark; + /* 0x10 */ u32 low_wtrmark; + /* 0x14 */ void* read_ptr; + /* 0x18 */ void* write_ptr; + /* 0x1C */ s32 rw_dst; + /* 0x20 */ u8 fifo_wrap; + /* 0x21 */ u8 cpu_fifo_ready; + /* 0x22 */ u8 gp_fifo_ready; + /* 0x23 */ u8 field_0x23[93]; +} GXFifoObj; // Size: 0x80 + +typedef struct _GXTexRegion { + u32 unk0; // _00 + u32 unk4; // _04 + u32 unk8; // _08 + u8 unkC; // _0C + u8 unkD; // _0D +} GXTexRegion; // Size: 0x10 + +typedef struct _GXTlutRegion { + /* 0x00 */ u32 unk0; + /* 0x04 */ GXTlutObj tlutObj; +} GXTlutRegion; // Size: 0x10 + +typedef void (*GXBreakPtCallback)(void); +typedef void (*GXDrawSyncCallback)(u16 token); +typedef void (*GXDrawDoneCallback)(void); +typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj* t_obj, GXTexMapID id); +typedef GXTlutRegion* (*GXTlutRegionCallback)(u32 idx); + +typedef struct _GXData { + // Bypass and vertex info + u16 vNumNot; // _000, !(# flush verts to send) + u16 bpSentNot; // _002, !(bypass reg sent last?) + u16 vNum; // _004, # flush verts to send + u16 vLim; // _006, max vert size + + // Command process (CP) regs + u32 cpEnable; // _008 + u32 cpStatus; // _00C + u32 cpClr; // _010 + u32 vcdLo; // _014 + u32 vcdHi; // _018 + u32 vatA[8]; // _01C + u32 vatB[8]; // _03C + u32 vatC[8]; // _05C + u32 lpSize; // _07C + u32 matIdxA; // _080 + u32 matIdxB; // _084 + + // Index loading base/stride regs (pos, nrm, tex, light) + u32 indexBase[4]; // _088 + u32 indexStride[4]; // _098 + + // Transform and lighting regs + u32 ambColor[2]; // _0A8 + u32 matColor[2]; // _0B0 + + // Setup regs + u32 suTs0[8]; // _0B8 + u32 suTs1[8]; // _0D8 + u32 suScis0; // _0F8 + u32 suScis1; // _0FC + + // Raster regs + u32 tref[8]; // _100 + u32 iref; // _120 + + // Bump/Indirect texture regs + u32 bpMask; // _124 + u32 IndTexScale0; // _128 + u32 IndTexScale1; // _12C + + // Tev regs + u32 tevc[16]; // _130 + u32 teva[16]; // _170 + u32 tevKsel[8]; // _1B0 + + // Performance regs + u32 cmode0; // _1D0 + u32 cmode1; // _1D4 + u32 zmode; // _1D8 + u32 peCtrl; // _1DC + + // Display copy regs + u32 cpDispSrc; // _1E0 + u32 cpDispSize; // _1E4 + u32 cpDispStride; // _1E8 + u32 cpDisp; // _1EC + + // Texture copy regs + u32 cpTexSrc; // _1F0 + u32 cpTexSize; // _1F4 + u32 cpTexStride; // _1F8 + u32 cpTex; // _1FC + GXBool cpTexZ; // _200 + + // General raster mode + u32 genMode; // _204 + + // Texture regions + GXTexRegion TexRegions0[GX_MAX_TEXMAP]; // _208 + GXTexRegion TexRegions1[GX_MAX_TEXMAP]; // _288 + GXTexRegion TexRegions2[GX_MAX_TEXMAP]; // _308 + + // Texture lookup table regions + GXTlutRegion TlutRegions[GX_MAX_TLUT_ALL]; // _388 + GXTexRegionCallback texRegionCallback; // _4C8 + GXTlutRegionCallback tlutRegionCallback; // _4CC + + // Command processor vars + GXAttrType nrmType; // _4D0 + GXBool hasNrms; // _4D4 + GXBool hasBiNrms; // _4D5 + u32 projType; // _4D8 + f32 projMtx[6]; // _4DC + + // Viewport parms + f32 vpLeft; // _4F4 + f32 vpTop; // _4F8 + f32 vpWd; // _4FC + f32 vpHt; // _500 + f32 vpNearz; // _504 + f32 vpFarz; // _508 + f32 zOffset; // _50C + f32 zScale; // _510 + + // Texture regs + u32 tImage0[8]; // _514 + u32 tMode0[8]; // _534 + u32 texmapId[16]; // _554 + u32 tcsManEnab; // _594 + u32 tevTcEnab; // _598 + + // Performance metrics + GXPerf0 perf0; // _59C + GXPerf1 perf1; // _5A0 + u32 perfSel; // _5A4 + + // Flags + GXBool inDispList; // _5A8 + GXBool dlSaveContext; // _5A9 + GXBool abtWaitPECopy; // _5AA + u8 dirtyVAT; // _5AB + u32 dirtyState; // _5AC +} GXData; // Size: 0x5B0 + +static_assert(sizeof(GXData) == 0x5B0); + +extern "C" GXData* gxData; +#define gx gxData + +void GXSetVtxDesc(GXAttr attr, GXAttrType type); +void GXSetVtxDescv(GXVtxDescList* list); +void __GXSetVCD(void); +void __GXCalculateVLim(void); +void GXClearVtxDesc(void); +void GXSetVtxAttrFmt(GXVtxFmt fmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u8); +void GXSetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList* list); +void __GXSetVAT(void); +void GXSetArray(GXAttr attr, void* base, u8); +void GXInvalidateVtxCache(void); +void GXSetTexCoordGen2(GXTexCoordID dst, GXTexGenType type, GXTexGenSrc src, u32 mtx, + GXBool renormalize, u32 pt_mtx); +void GXSetNumTexGens(u8 numTexGens); + +void GXGetVtxAttrFmtv(GXVtxFmt param_0, GXVtxAttrFmtList* param_1); +void GXGetVtxAttrFmt(GXVtxFmt param_0, GXAttr param_1, GXCompCnt* param_2, GXCompType* param_3, + u8* param_4); +void GXGetVtxDescv(GXVtxDescList* attrPtr); +void GXInitLightAttn(GXLightObj* obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2); +void GXInitLightSpot(GXLightObj* obj, f32 cutoff, GXSpotFn spot_fn); +void GXInitLightDistAttn(GXLightObj* obj, f32 dist, f32 brightness, GXDistAttnFn dist_fn); +void GXInitLightPos(GXLightObj* obj, f32 x, f32 y, f32 z); +void GXInitLightDir(GXLightObj* obj, f32 x, f32 y, f32 z); +void GXInitLightColor(GXLightObj* obj, GXColor color); +void GXLoadLightObjImm(GXLightObj* obj, GXLightID light); +void GXSetChanAmbColor(GXChannelID channel, GXColor color); +void GXSetChanMatColor(GXChannelID channel, GXColor color); +void GXSetNumChans(u8 chan_num); +void GXSetChanCtrl(GXChannelID channel, GXBool enable, GXColorSrc amb_src, GXColorSrc mat_src, u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn); +void GXSetTevIndirect(GXTevStageID tevStage, GXIndTexStageID texStage, GXIndTexFormat texFmt, + GXIndTexBiasSel biasSel, GXIndTexMtxID mtxID, GXIndTexWrap wrapS, + GXIndTexWrap wrapT, u8 addPrev, u8 utcLod, GXIndTexAlphaSel alphaSel); +void GXSetIndTexMtx(GXIndTexMtxID mtxID, f32 offset[6], s8 scale_exp); +void GXSetIndTexCoordScale(GXIndTexStageID texStage, GXIndTexScale scaleS, GXIndTexScale scaleT); +void GXSetIndTexOrder(GXIndTexStageID stage, GXTexCoordID coord, GXTexMapID map); +void GXSetNumIndStages(u8 num); +void GXSetTevDirect(GXTevStageID stage); +void GXBeginDisplayList(void* list, u32 capacity); +void GXEndDisplayList(void); +void GXCallDisplayList(void* list, u32 nbytes); +void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size); +void GXInitFifoPtrs(GXFifoObj* fifo, void* read_ptr, void* write_ptr); +void GXSetCPUFifo(GXFifoObj* fifo); +void GXSetGPFifo(GXFifoObj* fifo); +void GXSaveCPUFifo(GXFifoObj* fifo); +void __GXSaveCPUFifoAux(GXFifoObj* fifo); +void GXGetGPStatus(GXBool* overhi, GXBool* underlo, GXBool* read_idle, GXBool* cmd_idle, GXBool* breakpoint); +void* GXGetFifoBase(GXFifoObj* fifo); +u32 GXGetFifoSize(GXFifoObj* fifo); +GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb); +void __GXFifoInit(void); +void __GXFifoReadEnable(void); +void __GXFifoReadDisable(void); +void __GXFifoLink(u8); +void __GXWriteFifoIntEnable(u32, u32); +void __GXWriteFifoIntReset(u32, u32); +void __GXCleanGPFifo(void); +OSThread* GXSetCurrentGXThread(void); +OSThread* GXGetCurrentGXThread(void); +GXFifoObj* GXGetCPUFifo(void); +GXFifoObj* GXGetGPFifo(void); +void GXSetDispCopySrc(u16 left, u16 top, u16 width, u16 height); +void GXSetTexCopySrc(u16 left, u16 top, u16 width, u16 height); +void GXSetDispCopyDst(u16 arg0, u16 arg1); +void GXSetTexCopyDst(u16 width, u16 height, GXTexFmt format, GXBool useMIPmap); +void GXSetDispCopyFrame2Field(GXCopyMode mode); +void GXSetCopyClamp(GXFBClamp clamp); +u16 GXGetNumXfbLines(const u16 efbHeight, f32 yScale); +f32 GXGetYScaleFactor(u16 efb_height, u16 xfb_height); +u32 GXSetDispCopyYScale(f32 y_scale); +void GXSetCopyClear(GXColor color, u32 clear_z); +void GXSetCopyFilter(GXBool antialias, u8 pattern[12][2], GXBool vf, u8 vfilter[7]); +void GXSetDispCopyGamma(GXGamma gamma); +void GXCopyDisp(void* dst, GXBool clear); +void GXCopyTex(void* dst, GXBool clear); +void GXClearBoundingBox(void); +void __GXSetDirtyState(void); +void GXBegin(GXPrimitive type, GXVtxFmt fmt, u16 vert_num); +void __GXSendFlushPrim(void); +void GXSetLineWidth(u8 width, GXTexOffset offsets); +void GXSetPointSize(u8 size, GXTexOffset offsets); +void GXEnableTexOffsets(GXTexCoordID coord, GXBool line, GXBool point); +void GXSetCullMode(GXCullMode mode); +void GXSetCoPlanar(GXBool enable); +void __GXSetGenMode(void); +GXTexRegion* __GXDefaultTexRegionCallback(const GXTexObj* obj, GXTexMapID mapID); +GXTlutRegion* __GXDefaultTlutRegionCallback(u32 tlut); +BOOL __GXShutdown(BOOL); +void __GXInitRevisionBits(void); +GXFifoObj* GXInit(void* base, u32 size); +void __GXInitGX(void); +void GXSetMisc(GXMiscToken token, u32 val); +void GXFlush(void); +void __GXAbort(void); +void GXAbortFrame(void); +void GXSetDrawDone(void); +void GXDrawDone(void); +void GXPixModeSync(void); +void GXPokeAlphaMode(GXCompare comp, u8 threshold); +void GXPokeAlphaRead(GXAlphaReadMode mode); +void GXPokeAlphaUpdate(GXBool enable_update); +void GXPokeBlendMode(GXBlendMode mode, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp op); +void GXPokeColorUpdate(GXBool enable_update); +void GXPokeDstAlpha(GXBool enable, u8 alpha); +void GXPokeDither(GXBool enable); +void GXPokeZMode(GXBool enable_compare, GXCompare comp, GXBool update_enable); +void GXPeekZ(u16 x, u16 y, u32* z); +void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1); +void GXClearGPMetric(void); +void GXReadXfRasMetric(u32*, u32*, u32*, u32*); +void GXSetFog(GXFogType type, f32 startZ, f32 endZ, f32 nearZ, f32 farZ, GXColor color); +void GXSetFogRangeAdj(GXBool enable, u16 center, GXFogAdjTable* table); +void GXSetBlendMode(GXBlendMode mode, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp op); +void GXSetColorUpdate(GXBool enable_update); +void GXSetAlphaUpdate(GXBool enable_update); +void GXSetZMode(GXBool enable_compare, GXCompare comp, GXBool enable_update); +void GXSetZCompLoc(GXBool z_buf_before_tex); +void GXSetPixelFmt(GXPixelFmt pixel_fmt, GXZFmt16 z_fmt); +void GXSetDither(GXBool enable_dither); +void GXSetDstAlpha(GXBool enable, u8 alpha); +void GXSetFieldMask(GXBool odd_mask, GXBool even_mask); +void GXSetFieldMode(GXBool field_mode, GXBool half_aspect_ratio); +void GXSetTevOp(GXTevStageID id, GXTevMode mode); +void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, + GXTevColorArg d); +void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, + GXTevAlphaArg d); +void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, + GXTevRegID out_reg); +void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, + GXTevRegID out_reg); +void GXSetTevColor(GXTevRegID id, GXColor color); +void GXSetTevColorS10(GXTevRegID id, GXColorS10 color); +void GXSetTevKColor(GXTevKColorID id, GXColor color); +void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel color_sel); +void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel alpha_sel); +void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel ras_sel, GXTevSwapSel tex_sel); +void GXSetTevSwapModeTable(GXTevSwapSel select, GXTevColor r, GXTevColor g, GXTevColor b, + GXTevColor a); +void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1); +void GXSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias); +void GXSetTevOrder(GXTevStageID stage, GXTexCoordID coord, GXTexMapID map, GXChannelID color); +void GXSetNumTevStages(u8 num_stages); +u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod); +void __GetImageTileCount(GXTexFmt format, u16 width, u16 height, u32* a, u32* b, u32* c); +void GXInitTexObj(GXTexObj* obj, void* image, u16 width, u16 height, GXTexFmt fmt, + GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap); +void GXInitTexObjCI(GXTexObj* obj, void* image, u16 width, u16 height, GXCITexFmt format, + GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap, u32 tlut_name); +void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter min_filter, GXTexFilter max_filter, f32 min_lod, + f32 max_lod, f32 lod_bias, GXBool bias_clamp, GXBool edge_lod, + GXAnisotropy aniso); +u16 GXGetTexObjWidth(GXTexObj* obj); +u16 GXGetTexObjHeight(GXTexObj* obj); +GXTexFmt GXGetTexObjFmt(const GXTexObj* obj); +GXTexWrapMode GXGetTexObjWrapS(GXTexObj* obj); +GXTexWrapMode GXGetTexObjWrapT(GXTexObj* obj); +GXBool GXGetTexObjMipMap(const GXTexObj* obj); +u32 GXGetTexObjTlut(GXTexObj* obj); +void GXLoadTexObj(GXTexObj* obj, GXTexMapID id); +void GXInitTlutObj(GXTlutObj* obj, void* lut, GXTlutFmt fmt, u16 entry_num); +void GXLoadTlut(GXTlutObj* obj, u32 tlut_name); +void GXInitTexCacheRegion(GXTexRegion* region, GXBool is_32b_mipmap, u32 tmem_even, + GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd); +void GXInitTlutRegion(GXTlutRegion* region, u32 tmem_addr, GXTlutSize tlut_size); +void GXInvalidateTexAll(void); +GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback); +GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback callback); +void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 s_scale, u16 t_scale); +void __SetSURegs(); +void __GXSetSUTexRegs(); +void __GXSetTmemConfig(); +void GXProject(f32 model_x, f32 model_y, f32 model_z, Mtx model_mtx, f32* proj_mtx, f32* viewpoint, + f32* screen_x, f32* screen_y, f32* screen_z); +void GXSetProjection(const Mtx44 proj, GXProjectionType type); +void GXSetProjectionv(f32* p); +void GXGetProjectionv(f32* p); +void GXLoadPosMtxImm(Mtx mtx, u32 id); +void GXLoadNrmMtxImm(Mtx mtx, u32 id); +void GXSetCurrentMtx(u32 id); +void GXLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type); +void GXSetViewport(f32 x_orig, f32 y_orig, f32 width, f32 height, f32 near_z, f32 far_z); +void GXGetViewportv(f32* p); +void GXSetScissor(u32 left, u32 top, u32 width, u32 height); +void GXGetScissor(u32* left, u32* top, u32* width, u32* height); +void GXSetScissorBoxOffset(s32 x_offset, s32 y_offset); +void GXSetClipMode(GXClipMode mode); +void GXGetVtxDesc(GXAttr attr, GXAttrType* type); + +typedef union { + u8 u8; + u16 u16; + u32 u32; + u64 u64; + s8 s8; + s16 s16; + s32 s32; + s64 s64; + f32 f32; + f64 f64; +} PPCWGPipe; + +extern volatile PPCWGPipe wgPipe; +#define GXFifo wgPipe + +inline void GXPosition3f32(const f32 x, const f32 y, const f32 z) { + GXFifo.f32 = x; + GXFifo.f32 = y; + GXFifo.f32 = z; +} + +inline void GXNormal3f32(const f32 x, const f32 y, const f32 z) { + GXFifo.f32 = x; + GXFifo.f32 = y; + GXFifo.f32 = z; +} + +inline void GXPosition2f32(const f32 x, const f32 z) { + GXFifo.f32 = x; + GXFifo.f32 = z; +} + +inline void GXColor1u32(const u32 c) { + GXFifo.u32 = c; +} + +inline void GXTexCoord2f32(const f32 s, const f32 t) { + GXFifo.f32 = s; + GXFifo.f32 = t; +} + +inline void GXTexCoord2u8(const u8 s, const u8 t) { + GXFifo.u8 = s; + GXFifo.u8 = t; +} + +inline void GXTexCoord1x8(const u8 s) { + GXFifo.u8 = s; +} + +inline void GXPosition2u16(const u16 x, const u16 y) { + GXFifo.u16 = x; + GXFifo.u16 = y; +} + +inline void GXPosition1x16(const u16 x) { + GXFifo.u16 = x; +} + +inline void GXPosition1x8(const u8 x) { + GXFifo.u8 = x; } -inline void GXColor1uint32_t(u32 c) { - GFX_FIFO(u32) = c; +inline void GXPosition3s8(const s8 x, const s8 y, const s8 z) { + GXFifo.s8 = x; + GXFifo.s8 = y; + GXFifo.s8 = z; } -inline void GXTexCoord2float(f32 s, f32 t) { - GFX_FIFO(f32) = s; - GFX_FIFO(f32) = t; +inline void GXPosition2s8(const s8 x, const s8 y) { + GXFifo.s8 = x; + GXFifo.s8 = y; } -inline void GXTexCoord2uint8_t(u8 s, u8 t) { - GFX_FIFO(u8) = s; - GFX_FIFO(u8) = t; +inline void GXPosition2s16(const s16 x, const s16 y) { + GXFifo.s16 = x; + GXFifo.s16 = y; } -inline void GXPosition2uint16_t(u16 x, u16 y) { - GFX_FIFO(u16) = x; - GFX_FIFO(u16) = y; +inline void GXPosition3s16(const s16 x, const s16 y, const s16 z) { + GXFifo.s16 = x; + GXFifo.s16 = y; + GXFifo.s16 = z; } -inline void GXPosition1x8(u8 x) { - GFX_FIFO(u8) = x; +inline void GXTexCoord2s8(const s8 x, const s8 y) { + GXFifo.s8 = x; + GXFifo.s8 = y; } -inline void GXEnd() {} +inline void GXTexCoord2u16(const u16 x, const u16 y) { + GXFifo.u16 = x; + GXFifo.u16 = y; +} + +inline void GXTexCoord2s16(const s16 u, const s16 v) { + GXFifo.s16 = u; + GXFifo.s16 = v; +} + +inline void GXEnd(void) {} + +void GXDrawSphere(u8 numMajor, u8 numMinor); +void GXDrawCylinder(u8 numEdges); }; \ No newline at end of file diff --git a/external/libtp_c/include/dolphin/mtx/mtx.h b/external/libtp_c/include/dolphin/mtx/mtx.h index c1244cad..732e393a 100644 --- a/external/libtp_c/include/dolphin/mtx/mtx.h +++ b/external/libtp_c/include/dolphin/mtx/mtx.h @@ -2,8 +2,26 @@ #define MTX_H #include "../types.h" +#include "vec.h" typedef f32 Mtx[3][4]; +typedef f32 Mtx33[3][3]; +typedef f32 Mtx23[2][3]; +typedef f32 Mtx44[4][4]; typedef f32 (*MtxP)[4]; +extern "C" { +void PSMTXIdentity(Mtx m); +void PSMTXTrans(Mtx m, f32 x, f32 y, f32 z); +void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad); +void PSMTXConcat(const Mtx a, const Mtx b, Mtx ab); +void PSMTXScale(Mtx m, f32 x, f32 y, f32 z); +void PSMTXCopy(const Mtx src, Mtx dst); +u32 PSMTXInverse(const Mtx src, Mtx inv); +void PSMTXMultVec(const Mtx m, const Vec* src, Vec* dst); +void PSMTXMultVecSR(const Mtx m, const Vec* src, Vec* dst); +void PSMTXMultVecArray(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count); +void PSMTXMultVecArraySR(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count); +} + #endif /* MTX_H */ diff --git a/external/libtp_c/include/dolphin/mtx/vec.h b/external/libtp_c/include/dolphin/mtx/vec.h index cb94f39b..4302cd4f 100644 --- a/external/libtp_c/include/dolphin/mtx/vec.h +++ b/external/libtp_c/include/dolphin/mtx/vec.h @@ -16,4 +16,17 @@ struct CameraMatrix { Vec pos; }; +extern "C" { +f32 PSVECSquareMag(const Vec* v); +f32 PSVECSquareDistance(const Vec* a, const Vec* b); +void PSVECAdd(const Vec* a, const Vec* b, Vec* ab); +void PSVECScale(const Vec* src, Vec* dst, f32 scale); +void PSVECSubtract(const Vec* a, const Vec* b, Vec* a_b); +void PSVECNormalize(const Vec* src, Vec* unit); +void PSVECCrossProduct(const Vec* a, const Vec* b, Vec* axb); +f32 PSVECMag(const Vec* v); +f32 PSVECDotProduct(const Vec* a, const Vec* b); +f32 PSVECDistance(const Vec* a, const Vec* b); +} + #endif /* VEC_H */ diff --git a/external/libtp_c/include/dolphin/os/OS.h b/external/libtp_c/include/dolphin/os/OS.h index 7a366ec3..9851e0d9 100644 --- a/external/libtp_c/include/dolphin/os/OS.h +++ b/external/libtp_c/include/dolphin/os/OS.h @@ -161,6 +161,9 @@ bool OSUnlink(OSModuleInfo* module); bool OSDisableInterrupts(); bool OSRestoreInterrupts(bool enable); +OSTime OSGetTime(); +void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* ct); + extern OSModuleList osModuleList; } #endif \ No newline at end of file diff --git a/external/libtp_c/include/dolphin/os/OSCache.h b/external/libtp_c/include/dolphin/os/OSCache.h index 6c497e5c..6537c702 100644 --- a/external/libtp_c/include/dolphin/os/OSCache.h +++ b/external/libtp_c/include/dolphin/os/OSCache.h @@ -9,7 +9,7 @@ extern "C" { void DCFlushRange(void* startAddr, u32 nBytes); // DCStoreRange // DCFlushRangeNoSync -// DCStoreRangeNoSync +void DCStoreRangeNoSync(void* start, u32 nBytes); // DCZeroRange void ICInvalidateRange(void* startAddr, u32 nBytes); // ICFlashInvalidate diff --git a/external/libtp_c/include/dolphin/types.h b/external/libtp_c/include/dolphin/types.h index 9113ff3f..cff75d75 100644 --- a/external/libtp_c/include/dolphin/types.h +++ b/external/libtp_c/include/dolphin/types.h @@ -2,6 +2,7 @@ #define DOLPHIN_TYPES_H #include +#include "../defines.h" typedef int8_t s8; typedef int16_t s16; diff --git a/external/libtp_c/include/f_op/f_op_actor.h b/external/libtp_c/include/f_op/f_op_actor.h index 89e72937..e371a1ef 100644 --- a/external/libtp_c/include/f_op/f_op_actor.h +++ b/external/libtp_c/include/f_op/f_op_actor.h @@ -70,13 +70,26 @@ struct actor_place { /* 0x13 */ u8 field_0x13; }; -struct actor_attention_types { - void setFlag(u32 flags) { mFlags |= flags; } +enum fopAc_attention_type { + fopAc_attn_LOCK_e, + fopAc_attn_TALK_e, + fopAc_attn_BATTLE_e, + fopAc_attn_SPEAK_e, + fopAc_attn_CARRY_e, + fopAc_attn_DOOR_e, + fopAc_attn_JUEL_e, + fopAc_attn_ETC_e, + fopAc_attn_CHECK_e, +}; - /* 0x00 */ u8 field_0x0[9]; +struct actor_attention_types { + /* 0x00 */ u8 distances[9]; +#ifdef WII_PLATFORM + u8 unkdata[4]; +#endif /* 0x0A */ s16 field_0xa; - /* 0x0C */ cXyz mPosition; - /* 0x18 */ u32 mFlags; + /* 0x0C */ cXyz position; + /* 0x18 */ u32 flags; }; // Size = 0x1C class dJntCol_c; @@ -136,7 +149,9 @@ class fopAc_ac_c : public leafdraw_class { /* 0x567 */ s8 field_0x567; }; // Size: 0x568 +#ifndef WII_PLATFORM static_assert(sizeof(fopAc_ac_c) == 0x568); +#endif class J3DAnmTextureSRTKey; class J3DAnmTevRegKey; @@ -175,6 +190,8 @@ class fopEn_enemy_c : public fopAc_ac_c { /* 0x5A8 */ u8 field_0x5a8; }; // Size: 0x5AC +#ifndef WII_PLATFORM static_assert(sizeof(fopEn_enemy_c) == 0x5AC); +#endif #endif \ No newline at end of file diff --git a/external/libtp_c/include/f_op/f_op_actor_mng.h b/external/libtp_c/include/f_op/f_op_actor_mng.h index d1898df6..2c01efdf 100644 --- a/external/libtp_c/include/f_op/f_op_actor_mng.h +++ b/external/libtp_c/include/f_op/f_op_actor_mng.h @@ -260,8 +260,24 @@ inline u16 fopAcM_GetSetId(const fopAc_ac_c* p_actor) { LIBTP_DEFINE_FUNC(fopAcM_create__FsUlPC4cXyziPC5csXyzPC4cXyzSc, fopAcM_create_short__unsigned_long__cXyz_const____int__csXyz_const____cXyz_const____signed_char_, void, fopAcM_create, (s16, u32, const cXyz*, int, const csXyz*, const cXyz*, s8)) +LIBTP_DEFINE_FUNC(fopAcM_delete__FP10fopAc_ac_c, fopAcM_delete_fopAc_ac_c___, + void, fopAcM_delete, (fopAc_ac_c*)) + +LIBTP_DEFINE_FUNC(fopAcM_searchActorDistance__FPC10fopAc_ac_cPC10fopAc_ac_c, fopAcM_searchActorDistance_fopAc_ac_c_const____fopAc_ac_c_const___, + f32, fopAcM_searchActorDistance, (const fopAc_ac_c*, const fopAc_ac_c*)) + +LIBTP_DEFINE_FUNC(fopAcM_seenActorAngleY__FPC10fopAc_ac_cPC10fopAc_ac_c, fopAcM_seenActorAngleY_fopAc_ac_c_const____fopAc_ac_c_const___, + s16, fopAcM_seenActorAngleY, (const fopAc_ac_c*, const fopAc_ac_c*)) + +LIBTP_DEFINE_FUNC(gndCheck__11fopAcM_gc_cFPC4cXyz, fopAcM_gc_c__gndCheck_cXyz_const___, + bool, fopAcM_gc_c__gndCheck, (const cXyz*)) + +#define tp_fopAcM_gc_c__mGroundY_addr 0x80450cd0 +#define tp_fopAcM_gc_c__mGroundY (*(f32*)(tp_fopAcM_gc_c__mGroundY_addr)) + extern "C" { extern node_list_class g_fopAcTg_Queue; +extern f32 fopAcM_gc_c__mGroundY; } #endif diff --git a/external/libtp_c/include/f_op/f_op_draw_tag.h b/external/libtp_c/include/f_op/f_op_draw_tag.h index 4f9fa112..6c566487 100644 --- a/external/libtp_c/include/f_op/f_op_draw_tag.h +++ b/external/libtp_c/include/f_op/f_op_draw_tag.h @@ -3,7 +3,6 @@ #include "../dolphin/types.h" #include "../dolphin/mtx/vec.h" -#include "../addrs.h" // add lists$2216 later struct MatrixPtr { diff --git a/external/libtp_c/include/f_op/f_op_scene_req.h b/external/libtp_c/include/f_op/f_op_scene_req.h index c727f982..dadef47c 100644 --- a/external/libtp_c/include/f_op/f_op_scene_req.h +++ b/external/libtp_c/include/f_op/f_op_scene_req.h @@ -2,7 +2,6 @@ #define F_F_OP_SCENE_REQ_H_ #include "../dolphin/types.h" -#include "../addrs.h" struct LoadingInfo { u32 isLoading; // 80450CE0 diff --git a/external/libtp_c/include/m_Do/m_Do_audio.h b/external/libtp_c/include/m_Do/m_Do_audio.h index cfd9898a..90c680a8 100644 --- a/external/libtp_c/include/m_Do/m_Do_audio.h +++ b/external/libtp_c/include/m_Do/m_Do_audio.h @@ -2,7 +2,6 @@ #define M_DO_M_DO_AUDIO_H #include "../dolphin/types.h" -#include "../addrs.h" #include "../Z2AudioLib/Z2AudioMgr.h" class mDoAud_zelAudio_c { diff --git a/external/libtp_c/include/m_Do/m_Do_controller_pad.h b/external/libtp_c/include/m_Do/m_Do_controller_pad.h index 4badbdda..18b463e6 100644 --- a/external/libtp_c/include/m_Do/m_Do_controller_pad.h +++ b/external/libtp_c/include/m_Do/m_Do_controller_pad.h @@ -2,7 +2,6 @@ #define M_DO_M_DO_CONTROLLER_PAD_H #include "../JSystem/JUtility/JUTGamePad.h" -#include "../addrs.h" #define mDoCPd_c__m_gamePad ((JUTGamePad**)mDoCPd_c__m_gamePad_addr) diff --git a/external/libtp_c/include/m_Do/m_Do_ext.h b/external/libtp_c/include/m_Do/m_Do_ext.h index 266f7d2a..0bde14af 100644 --- a/external/libtp_c/include/m_Do/m_Do_ext.h +++ b/external/libtp_c/include/m_Do/m_Do_ext.h @@ -2,13 +2,12 @@ #define M_DO_M_DO_EXT_H #include "../dolphin/types.h" -#include "../dolphin/gx/GXTexture.h" +#include "../dolphin/gx/gx.h" #include "../JSystem/J3DGraphBase/J3DPacket.h" #include "../JSystem/J3DGraphBase/J3DSys.h" #include "../m_Do/m_Do_mtx.h" #include "../SSystem/SComponent/c_xyz.h" #include "../SSystem/SComponent/c_sxyz.h" -#include "gcn_c/include/gfx.h" #include "libtp_c/include/JSystem/JKernel/JKRExpHeap.h" struct J3DAnmTransform {}; diff --git a/external/libtp_c/include/m_Do/m_Do_mtx.h b/external/libtp_c/include/m_Do/m_Do_mtx.h index cc90e596..924dea34 100644 --- a/external/libtp_c/include/m_Do/m_Do_mtx.h +++ b/external/libtp_c/include/m_Do/m_Do_mtx.h @@ -5,21 +5,65 @@ #include "../dolphin/mtx/mtx.h" #include "../defines.h" -extern "C" void PSMTXConcat(const Mtx, const Mtx, Mtx); -extern "C" void PSMTXScale(Mtx, f32, f32, f32); -extern "C" void PSMTXTrans(Mtx matrix, f32 x_trans, f32 y_trans, f32 z_trans); +extern "C" { +void PSMTXConcat(const Mtx, const Mtx, Mtx); +void PSMTXScale(Mtx, f32, f32, f32); +void PSMTXTrans(Mtx matrix, f32 x_trans, f32 y_trans, f32 z_trans); +void PSMTXCopy(const Mtx src, Mtx dst); +} #ifndef WII_PLATFORM #define mDoMtx_stack_c__now now__14mDoMtx_stack_c #endif extern Mtx mDoMtx_stack_c__now; -LIBTP_DEFINE_FUNC(mDoMtx_XYZrotM__FPA4_fsss, mDoMtx_XYZrotM_float, +LIBTP_DEFINE_FUNC(mDoMtx_XYZrotM__FPA4_fsss, mDoMtx_XYZrotM_float_____4___short__short__short_, void, mDoMtx_XYZrotM, (Mtx, short, short, short)) -LIBTP_DEFINE_FUNC(scaleM__14mDoMtx_stack_cFfff, mDoMtx_stack_c__scaleM_float_, +LIBTP_DEFINE_FUNC(scaleM__14mDoMtx_stack_cFfff, mDoMtx_stack_c__scaleM_float__float__float_, void, mDoMtx_stack_c__scaleM, (f32, f32, f32)) +LIBTP_DEFINE_FUNC(transM__14mDoMtx_stack_cFfff, mDoMtx_stack_c__transM_float__float__float_, + void, mDoMtx_stack_c__transM, (f32, f32, f32)) + +LIBTP_DEFINE_FUNC(mDoMtx_inverseTranspose__FPA4_CfPA4_f, mDoMtx_inverseTranspose_float_const_____4___float_____4__, + bool, mDoMtx_inverseTranspose, (const Mtx, Mtx)) + +LIBTP_DEFINE_FUNC(mDoMtx_XrotM__FPA4_fs, mDoMtx_XrotM_float_____4___short_, + void, mDoMtx_XrotM, (Mtx, s16)) + +LIBTP_DEFINE_FUNC(mDoMtx_XrotS__FPA4_fs, mDoMtx_XrotS_float_____4___short_, + void, mDoMtx_XrotS, (Mtx, s16)) + +LIBTP_DEFINE_FUNC(mDoMtx_YrotS__FPA4_fs, mDoMtx_YrotS_float_____4___short_, + void, mDoMtx_YrotS, (Mtx, s16)) + +LIBTP_DEFINE_FUNC(mDoMtx_YrotM__FPA4_fs, mDoMtx_YrotM_float_____4___short_, + void, mDoMtx_YrotM, (Mtx, s16)) + +LIBTP_DEFINE_FUNC(mDoMtx_ZrotM__FPA4_fs, mDoMtx_ZrotM_float_____4___short_, + void, mDoMtx_ZrotM, (Mtx, s16)) + +inline void mDoMtx_trans(Mtx m, f32 x, f32 y, f32 z) { + PSMTXTrans(m, x, y, z); +} + +inline void mDoMtx_concat(const Mtx a, const Mtx b, Mtx c) { + PSMTXConcat(a, b, c); +} + +inline void mDoMtx_scale(Mtx m, f32 x, f32 y, f32 z) { + PSMTXScale(m, x, y, z); +} + +inline void mDoMtx_inverse(const Mtx a, Mtx b) { + PSMTXInverse(a, b); +} + +inline void mDoMtx_multVecArray(Mtx m, const Vec* src, Vec* dst, u32 count) { + PSMTXMultVecArray(m, src, dst, count); +} + class mDoMtx_stack_c { public: static MtxP get() { return mDoMtx_stack_c__now; } @@ -27,6 +71,15 @@ class mDoMtx_stack_c { static void scaleS(f32 x, f32 y, f32 z) { PSMTXScale(mDoMtx_stack_c__now, x, y, z); } static void XYZrotM(short x, short y, short z) { mDoMtx_XYZrotM(mDoMtx_stack_c__now, x, y, z); } static void revConcat(MtxP mtx) { PSMTXConcat(mtx, mDoMtx_stack_c__now, mDoMtx_stack_c__now); } + static void scaleM(f32 x, f32 y, f32 z) { mDoMtx_stack_c__scaleM(x, y, z); } + static void copy(const Mtx m) { PSMTXCopy(m, mDoMtx_stack_c__now); } + static void transM(f32 x, f32 y, f32 z) { mDoMtx_stack_c__transM(x, y, z); } + static void inverseTranspose() { mDoMtx_inverseTranspose(mDoMtx_stack_c__now, mDoMtx_stack_c__now); } + static void XrotM(s16 x) { mDoMtx_XrotM(mDoMtx_stack_c__now, x); } + static void YrotM(s16 y) { mDoMtx_YrotM(mDoMtx_stack_c__now, y); } + static void ZrotM(s16 z) { mDoMtx_ZrotM(mDoMtx_stack_c__now, z); } + static void YrotS(s16 y) { mDoMtx_YrotS(mDoMtx_stack_c__now, y); } + static void multVec(const Vec* a, Vec* b) { PSMTXMultVec(mDoMtx_stack_c__now, a, b); } }; #endif /* M_DO_M_DO_MTX_H */ diff --git a/external/libtp_c/include/m_Do/m_Re_controller_pad.h b/external/libtp_c/include/m_Do/m_Re_controller_pad.h index 01811bc1..9bde8baf 100644 --- a/external/libtp_c/include/m_Do/m_Re_controller_pad.h +++ b/external/libtp_c/include/m_Do/m_Re_controller_pad.h @@ -3,12 +3,11 @@ #include "../dolphin/mtx/vec.h" #include "../dolphin/mtx/mtx.h" -#include "../addrs.h" #include "../dolphin/types.h" #ifdef WII_PLATFORM namespace CButton { -enum { +enum : uint16_t { DPAD_LEFT = 0x1, DPAD_RIGHT = 0x2, DPAD_DOWN = 0x4, diff --git a/external/libtp_c/include/msl_c/math.h b/external/libtp_c/include/msl_c/math.h index 14d43dfe..d3c3b643 100644 --- a/external/libtp_c/include/msl_c/math.h +++ b/external/libtp_c/include/msl_c/math.h @@ -8,7 +8,7 @@ #include -#include "../addrs.h" +#include "../defines.h" extern "C" { double atan(double x); @@ -33,4 +33,20 @@ double fastSqrt(double x); double sqrt(double x); } +inline float fcos(float v) { + return (float)cos(v); +} + +inline float fsin(float v) { + return (float)sin(v); +} + +#ifdef WII_PLATFORM +inline float std__fabsf(float x) { + return (x < 0.0f) ? -x : x; +} +#else +LIBTP_DEFINE_FUNC(fabsf__3stdFf, fabsf, float, std__fabsf, (float)) +#endif + #endif // !LIB_TP_MATH diff --git a/external/libtp_c/include/rel/d/a/b/d_a_b_ds.h b/external/libtp_c/include/rel/d/a/b/d_a_b_ds.h index 84a5d31a..c266ff06 100644 --- a/external/libtp_c/include/rel/d/a/b/d_a_b_ds.h +++ b/external/libtp_c/include/rel/d/a/b/d_a_b_ds.h @@ -30,4 +30,27 @@ class daB_DS_c : public fopAc_ac_c { /* 0x0859 */ u8 mParam4; }; +// setup later +struct daObjSwSpinner_c : public fopAc_ac_c { + /* 0x568 */ u8 field_0x568[0x5B4 - 0x568]; + /* 0x5B4 */ Mtx mBgMtx; + /* 0x5E4 */ f32 mHeight; + /* 0x5E8 */ u8 field_0x5e8; + /* 0x5E9 */ u8 field_0x5e9; + /* 0x5EA */ u8 field_0x5ea; + /* 0x5EB */ u8 field_0x5eb; + /* 0x5EC */ s16 field_0x5ec; + /* 0x5EE */ s16 mRotSpeedY; + /* 0x5F0 */ s16 field_0x5f0; +}; + +struct daObjLv4Wall_c : public fopAc_ac_c { + /* 0x568 */ u8 field_0x568[0x94C - 0x568]; + /* 0x94C */ daObjSwSpinner_c* mpSpinnerSw; + /* 0x950 */ f32 mHeight; + /* 0x954 */ int field_0x954; + /* 0x958 */ u16 field_0x958; + /* 0x95A */ u8 mAction; +}; + #endif diff --git a/external/libtp_c/include/utils.h b/external/libtp_c/include/utils.h index 9995e22f..3fdcd332 100644 --- a/external/libtp_c/include/utils.h +++ b/external/libtp_c/include/utils.h @@ -15,4 +15,6 @@ void setNextStageLayer(s8 layer); void setNextStageRoom(s8 room); void setNextStagePoint(s16 point); +int popcount(uint32_t i); + #endif \ No newline at end of file diff --git a/external/libtp_c/src/utils.cpp b/external/libtp_c/src/utils.cpp index f8cbb914..6901da63 100644 --- a/external/libtp_c/src/utils.cpp +++ b/external/libtp_c/src/utils.cpp @@ -32,3 +32,12 @@ KEEP_FUNC void setNextStageRoom(s8 room) { KEEP_FUNC void setNextStagePoint(s16 point) { g_dComIfG_gameInfo.play.mNextStage.setPoint(point); } + +KEEP_FUNC int popcount(uint32_t i) +{ + i = i - ((i >> 1) & 0x55555555); // add pairs of bits + i = (i & 0x33333333) + ((i >> 2) & 0x33333333); // quads + i = (i + (i >> 4)) & 0x0F0F0F0F; // groups of 8 + i *= 0x01010101; // horizontal sum of bytes + return i >> 24; // return just that top byte (after truncating to 32-bit even when int is wider than uint32_t) +} diff --git a/external/misc/ad.py b/external/misc/ad.py index 294fcb68..93158807 100644 --- a/external/misc/ad.py +++ b/external/misc/ad.py @@ -55,10 +55,10 @@ "zant", "hc", "beast_ganon", - "horseback_ganon", + "horseback", ] -ad_p = [{**default_entry, "id": i, "filename": file_names[i]} for i in range(42)] +ad_p = [{**default_entry, "id": i, "filename": file_names[i]} for i in range(43)] ad_p[0]["requirements"] = REQ_POS | REQ_CAM ad_p[0]["pos"] = (827.450012, 216.490097, -4533.90625) diff --git a/external/misc/any.py b/external/misc/any.py index 70d4f544..294e39c1 100644 --- a/external/misc/any.py +++ b/external/misc/any.py @@ -171,6 +171,14 @@ def update_entry(filename, data): 'counter': 10 }) + if args.platform is Platform.GCN: + any_p[1]["requirements"] = Requirements.POS | Requirements.CAM + any_p[1]["pos"] = (466.622467, 319.770752, -11651.3867) + any_p[1]["angle"] = 52540 + any_p[1]["cam"]["pos"] = (735.525391, 524.418701, -11576.4746) + any_p[1]["cam"]["target"] = (465.674622, 421.052704, -11651.0684) + any_p[1]["counter"] = 10 + # back in time update_entry("bit", { 'requirements': Requirements.POS | Requirements.CAM, diff --git a/external/misc/generate_actor_bin.py b/external/misc/generate_actor_bin.py new file mode 100644 index 00000000..0e913691 --- /dev/null +++ b/external/misc/generate_actor_bin.py @@ -0,0 +1,826 @@ +procnames = { + "overlap 0": 0x0000, + "overlap 1": 0x0001, + "overlap 3": 0x0002, + "overlap 6": 0x0003, + "overlap 7": 0x0004, + "overlap 8": 0x0005, + "overlap 9": 0x0006, + "overlap 10": 0x0007, + "overlap 11": 0x0008, + "logo scene": 0x0009, + "menu scene": 0x000A, + "play scene": 0x000B, + "opening scene": 0x000C, + "name scene": 0x000D, + "name ex scene": 0x000E, + "warning scene": 0x000F, + "warning 2_scene": 0x0010, + "overlap 2": 0x0011, + "room scene": 0x0012, + "environment": 0x0013, + "all enemies dead": 0x0014, + "environment se": 0x0015, + "switch push": 0x0016, + "switch push 2": 0x0017, + "switch push 5": 0x0018, + "game start trigger": 0x0019, + "no change room trigger": 0x001A, + "lv6 elevator a": 0x001B, + "monkey cage": 0x001C, + "movebox": 0x001D, + "switch turn": 0x001E, + "lv6 switch turn": 0x001F, + "sekizoa": 0x0020, + "goron a": 0x0021, + "goron a trigger": 0x0022, + "twilight trigger": 0x0023, + "ladder": 0x0024, + "brake effect": 0x0025, + "fyrus": 0x0026, + "l-box": 0x0027, + "web 0": 0x0028, + "web 1": 0x0029, + "castle block": 0x002A, + "stick bundle": 0x002B, + "bridge": 0x002C, + "ganondorf barrier": 0x002D, + "gohma egg container": 0x002E, + "fyer": 0x002F, + "twilight pole": 0x0030, + "tree": 0x0031, + "steel door": 0x0032, + "forest totem pole": 0x0033, + "chain door": 0x0034, + "GRDWATER": 0x0035, + "RotBridge": 0x0036, + "MagLift": 0x0037, + "MagLiftRot": 0x0038, + "Lv1Cdl00": 0x0039, + "Lv1Cdl01": 0x003A, + "TvCdlst": 0x003B, + "HsTarget": 0x003C, + "HeavySw": 0x003D, + "GoGate": 0x003E, + "TaFence": 0x003F, + "Saidan": 0x0040, + "SpinLift": 0x0041, + "BmWindow": 0x0042, + "RfHole": 0x0043, + "WaterPillar": 0x0044, + "SyRock": 0x0045, + "BsGate": 0x0046, + "AmiShutter": 0x0047, + "WtGate": 0x0048, + "Lv2Candle": 0x0049, + "TogeTrap": 0x004A, + "RotTrap": 0x004B, + "SwallShutter": 0x004C, + "IceWall": 0x004D, + "Lv5SwIce": 0x004E, + "Lv5FBoard": 0x004F, + "Turara": 0x0050, + "TwGate": 0x0051, + "dig hole": 0x0052, + "dig place": 0x0053, + "TestCube": 0x0054, + "Kshutter": 0x0055, + "COACH": 0x0056, + "THEB": 0x0057, + "COACH_FIRE": 0x0058, + "COACH2D": 0x0059, + "BALLOON2D": 0x005A, + "SKIP2D": 0x005B, + "MvStair": 0x005C, + "Cowdoor": 0x005D, + "Swpropeller": 0x005E, + "BoomShutter": 0x005F, + "KS": 0x0060, + "Hfuta": 0x0061, + "BkDoor": 0x0062, + "Cboard": 0x0063, + "ordon spring gate": 0x0064, + "Ikada": 0x0065, + "Ice_l": 0x0066, + "Ice_s": 0x0067, + "E_CREATE": 0x0068, + "Bhbridge": 0x0069, + "Kaisou": 0x006A, + "HHASHI": 0x006B, + "BHASHI": 0x006C, + "OCTHASHI": 0x006D, + "THASHI": 0x006E, + "CRVGATE": 0x006F, + "CRVFENCE": 0x0070, + "CRVHAHEN": 0x0071, + "CRVSTEEL": 0x0072, + "CRVLH_UP": 0x0073, + "CRVLH_DW": 0x0074, + "RIVERROCK": 0x0075, + "DUST": 0x0076, + "ITA": 0x0077, + "Window": 0x0078, + "MetalBox": 0x0079, + "BBox": 0x007A, + "MSIMA": 0x007B, + "MYOGAN": 0x007C, + "B_ZANTS": 0x007D, + "ChainBlock": 0x007E, + "ChainWall": 0x007F, + "KkrGate": 0x0080, + "RiderGate": 0x0081, + "Onsen": 0x0082, + "Chest": 0x0083, + "Bemos": 0x0084, + "RopeBridge": 0x0085, + "WellCover": 0x0086, + "GraveStone": 0x0087, + "ZraRock": 0x0088, + "GraRock": 0x0089, + "GrzRock": 0x008A, + "GRA_WALL": 0x008B, + "ONSEN_FIRE": 0x008C, + "Lv6bemos": 0x008D, + "Lv6bemos2": 0x008E, + "BarDesk": 0x008F, + "DigSnow": 0x0090, + "Ytaihou": 0x0091, + "Elevator": 0x0092, + "Lv6TogeRoll": 0x0093, + "Lv6TogeTrap": 0x0094, + "Lv6Tenbin": 0x0095, + "Lv6SwGate": 0x0096, + "Lv6Lblock": 0x0097, + "Lv6ChgGate": 0x0098, + "Lv6FuriTrap": 0x0099, + "Lv6SzGate": 0x009A, + "Lv4EdShutter": 0x009B, + "Lv4Gate": 0x009C, + "Lv4PoGate": 0x009D, + "Lv4SlideWall": 0x009E, + "Lv4HsTarget": 0x009F, + "Lv7PropY": 0x00A0, + "Lv7BsGate": 0x00A1, + "Lv8OptiLift": 0x00A2, + "Lv8KekkaiTrap": 0x00A3, + "Lv8Lift": 0x00A4, + "Lv8UdFloor": 0x00A5, + "Lv9SwShutter": 0x00A6, + "TobyHouse": 0x00A7, + "poCandle": 0x00A8, + "Lv4DigSand": 0x00A9, + "FallObj": 0x00AA, + "SmgDoor": 0x00AB, + "SwLight": 0x00AC, + "Avalanche": 0x00AD, + "MirrorScrew": 0x00AE, + "MirrorSand": 0x00AF, + "MirrorTable": 0x00B0, + "MirrorChain": 0x00B1, + "Mirror6Pole": 0x00B2, + "SwSpinner": 0x00B3, + "TDoor": 0x00B4, + "Lv7Bridge": 0x00B5, + "zrTurara": 0x00B6, + "TakaraDai": 0x00B7, + "Table": 0x00B8, + "CatDoor": 0x00B9, + "Gake": 0x00BA, + "CSTAF": 0x00BB, + "Lv4RailWall": 0x00BC, + "Lv4Sand": 0x00BD, + "push door object": 0x00BE, + "push door": 0x00BF, + "GanonWall2": 0x00C0, + "Lv4Bridge": 0x00C1, + "Lv4Floor": 0x00C2, + "spinner trigger": 0x00C3, + "sw hang": 0x00C4, + "Rot stair": 0x00C5, + "Magne Arm": 0x00C6, + "KWheel 00": 0x00C7, + "KWheel 01": 0x00C8, + "Y chndlr": 0x00C9, + "PRE lvtr": 0x00CA, + "M Hasu": 0x00CB, + "YIblltray": 0x00CC, + "Lv6EGate": 0x00CD, + "PDtile": 0x00CE, + "PDwall": 0x00CF, + "Lv4PRwall": 0x00D0, + "KLift00": 0x00D1, + "B_OH": 0x00D2, + "Lv4Chan": 0x00D3, + "Lv3R10Saka": 0x00D4, + "Lv3Water": 0x00D5, + "Lv3Water2": 0x00D6, + "LV3WATERB": 0x00D7, + "HBombkoya": 0x00D8, + "SZbridge": 0x00D9, + "KakarikoBrg": 0x00DA, + "OrdinBrg": 0x00DB, + "BurnBox": 0x00DC, + "KJgjs": 0x00DD, + "IHASI": 0x00DE, + "IceBlock": 0x00DF, + "VolcanicBall": 0x00E0, + "VolcanicBomb": 0x00E1, + "VolcGnd": 0x00E2, + "KKanban": 0x00E3, + "E_PH": 0x00E4, + "ZRA": 0x00E5, + "Chandelier": 0x00E6, + "Stopper2": 0x00E7, + "DOOR20": 0x00E8, + "h-init trigger": 0x00E9, + "h-jump trigger": 0x00EA, + "ajnot trigger": 0x00EB, + "hstop trigger": 0x00EC, + "CANOE": 0x00ED, + "epona": 0x00EE, + "E_WB": 0x00EF, + "ITO": 0x00F0, + "SW": 0x00F1, + "SPINNER": 0x00F2, + "B_OB": 0x00F3, + "basket": 0x00F4, + "E_YC": 0x00F5, + "B_DS": 0x00F6, + "B_DR": 0x00F7, + "B_ZANTZ": 0x00F8, + "B_ZANT": 0x00F9, + "B_ZANTM": 0x00FA, + "TBOX": 0x00FB, + "TBOX2": 0x00FC, + "link": 0x00FD, + "BOOMERANG": 0x00FE, + "midna": 0x00FF, + "TK": 0x0100, + "WORM": 0x0101, + "PPolamp": 0x0102, + "BkyRock": 0x0103, + "HITOBJ": 0x0104, + "EP": 0x0105, + "COW": 0x0106, + "PERU": 0x0107, + "NI": 0x0108, + "TKJ2": 0x0109, + "squirrel": 0x010A, + "squirrel (npc)": 0x010B, + "DO": 0x010C, + "NE": 0x010D, + "TR": 0x010E, + "LF": 0x010F, + "FOOD": 0x0110, + "KI": 0x0111, + "KITA": 0x0112, + "KEY": 0x0113, + "KEYHOLE": 0x0114, + "Lv5Key": 0x0115, + "LP": 0x0116, + "TATIGI": 0x0117, + "ROCK": 0x0118, + "WFLAG": 0x0119, + "KAGE": 0x011A, + "KANBAN2": 0x011B, + "BALLOON": 0x011C, + "SUISYA": 0x011D, + "OILTUBO": 0x011E, + "ROTEN": 0x011F, + "SSDRINK": 0x0120, + "SSITEM": 0x0121, + "ssdrink trigger": 0x0122, + "btlitm trigger": 0x0123, + "lv5 soup trigger": 0x0124, + "mnlight trigger": 0x0125, + "shop cam trigger": 0x0126, + "shop item trigger": 0x0127, + "NDOOR": 0x0128, + "UDOOR": 0x0129, + "USAKU": 0x012A, + "SM_DOOR": 0x012B, + "BED": 0x012C, + "BOUMATO": 0x012D, + "ITAMATO": 0x012E, + "NOUGU": 0x012F, + "STICK": 0x0130, + "MIE": 0x0131, + "SEKIDOOR": 0x0132, + "SEKIZO": 0x0133, + "SMTILE": 0x0134, + "FISH": 0x0135, + "MG_FISH": 0x0136, + "FSHOP": 0x0137, + "DU": 0x0138, + "DISAPPEAR": 0x0139, + "Mato": 0x013A, + "Flag": 0x013B, + "Flag2": 0x013C, + "Flag3": 0x013D, + "GOMIKABE": 0x013E, + "Yousei": 0x013F, + "Kabuto": 0x0140, + "Cho": 0x0141, + "Kuw": 0x0142, + "Nan": 0x0143, + "Dan": 0x0144, + "Kam": 0x0145, + "Ten": 0x0146, + "Ari": 0x0147, + "Kag": 0x0148, + "Batta": 0x0149, + "Tombo": 0x014A, + "Kat": 0x014B, + "H_Saku": 0x014C, + "horse grass": 0x014D, + "KazeNeko": 0x014E, + "KznkArm": 0x014F, + "NamePlate": 0x0150, + "OnCloth": 0x0151, + "LndRope": 0x0152, + "ItaRope": 0x0153, + "Sakuita": 0x0154, + "Laundry": 0x0155, + "WarpBug": 0x0156, + "Izumi_Gate": 0x0157, + "Fchain": 0x0158, + "Wchain": 0x0159, + "attp trigger": 0x015A, + "Tornado": 0x015B, + "Tornado2": 0x015C, + "FirePillar": 0x015D, + "FirePillar2": 0x015E, + "InoBone": 0x015F, + "Stopper": 0x0160, + "MHole": 0x0161, + "magne trigger": 0x0162, + "boss warp": 0x0163, + "wooden pendulum": 0x0164, + "WdStick": 0x0165, + "stair block": 0x0166, + "geyser": 0x0167, + "kt on fire trigger": 0x0168, + "fire wood": 0x0169, + "fire wood 2": 0x016A, + "GpTaru": 0x016B, + "OnsenTaru": 0x016C, + "KiPot": 0x016D, + "TBOX_SW": 0x016E, + "SwChain": 0x016F, + "wooden sword": 0x0170, + "stone mark": 0x0171, + "Lv3Candle": 0x0172, + "lv4 candle trigger": 0x0173, + "lv4 candle dm trigger": 0x0174, + "DamCps": 0x0175, + "Smoke": 0x0176, + "WaterFall": 0x0177, + "ZoraCloth": 0x0178, + "poFire": 0x0179, + "poe fire trigger": 0x017A, + "glowSphere": 0x017B, + "light ball trigger": 0x017C, + "SwLBall": 0x017D, + "SwBall": 0x017E, + "WaterEff": 0x017F, + "river back trigger": 0x0180, + "kago fall trigger": 0x0181, + "lv2 pr check trigger": 0x0182, + "Lv4Gear": 0x0183, + "MasterSword": 0x0184, + "WoodStatue": 0x0185, + "Fan": 0x0186, + "IceLeaf": 0x0187, + "zrTuraraRc": 0x0188, + "ret room trigger": 0x0189, + "WindStone": 0x018A, + "wara howl trigger": 0x018B, + "SCannon": 0x018C, + "SmWStone": 0x018D, + "SCannonCrs": 0x018E, + "snow effect": 0x018F, + "csta sw trigger": 0x0190, + "lv6 csta sw trigger": 0x0191, + "awaPlar": 0x0192, + "poTbox": 0x0193, + "TimeFire": 0x0194, + "TMoon": 0x0195, + "GanonWall": 0x0196, + "Prop": 0x0197, + "CSTATUE": 0x0198, + "SwBallA": 0x0199, + "SwBallB": 0x019A, + "SnowSoup": 0x019B, + "Nagaisu": 0x019C, + "RCircle": 0x019D, + "Picture": 0x019E, + "set ball trigger": 0x019F, + "smoke emitter trigger": 0x01A0, + "SwTime": 0x01A1, + "HFtr": 0x01A2, + "HBarrel": 0x01A3, + "Crystal": 0x01A4, + "SCannonTen": 0x01A5, + "SwBallC": 0x01A6, + "scene exit 2": 0x01A7, + "Hata": 0x01A8, + "ToaruMaki": 0x01A9, + "attack item trigger": 0x01AA, + "rmbit sw trigger": 0x01AB, + "Sword": 0x01AC, + "spring trigger": 0x01AD, + "statue trigger": 0x01AE, + "E_AI": 0x01AF, + "E_GS": 0x01B0, + "E_GOB": 0x01B1, + "E_DD": 0x01B2, + "E_DN": 0x01B3, + "E_S1": 0x01B4, + "E_MF": 0x01B5, + "E_SG": 0x01B6, + "E_BS": 0x01B7, + "E_SF": 0x01B8, + "E_SH": 0x01B9, + "E_DF": 0x01BA, + "E_GM": 0x01BB, + "E_MD": 0x01BC, + "E_SM": 0x01BD, + "E_SM2": 0x01BE, + "E_ST": 0x01BF, + "E_ST_LINE": 0x01C0, + "E_SB": 0x01C1, + "E_TH": 0x01C2, + "E_CR": 0x01C3, + "E_CR_EGG": 0x01C4, + "E_DB": 0x01C5, + "E_DB_LEAF": 0x01C6, + "E_GA": 0x01C7, + "E_GB": 0x01C8, + "E_HB": 0x01C9, + "E_HB_LEAF": 0x01CA, + "E_HZELDA": 0x01CB, + "E_YD": 0x01CC, + "E_YH": 0x01CD, + "E_YD_LEAF": 0x01CE, + "E_HM": 0x01CF, + "E_TK": 0x01D0, + "E_TK2": 0x01D1, + "E_TK_BALL": 0x01D2, + "E_RB": 0x01D3, + "E_RD": 0x01D4, + "E_RDB": 0x01D5, + "E_RDY": 0x01D6, + "E_FM": 0x01D7, + "E_FS": 0x01D8, + "E_PM": 0x01D9, + "E_PO": 0x01DA, + "E_MB": 0x01DB, + "E_MK": 0x01DC, + "E_MM": 0x01DD, + "mini freezard": 0x01DE, + "E_ZS": 0x01DF, + "chillfos": 0x01E0, + "E_HP": 0x01E1, + "E_ZH": 0x01E2, + "E_ZM": 0x01E3, + "E_PZ": 0x01E4, + "E_FB": 0x01E5, + "E_FK": 0x01E6, + "E_MS": 0x01E7, + "E_NEST": 0x01E8, + "E_NZ": 0x01E9, + "E_BA": 0x01EA, + "E_BU": 0x01EB, + "E_BUG": 0x01EC, + "E_BEE": 0x01ED, + "E_IS": 0x01EE, + "E_KG": 0x01EF, + "E_KR": 0x01F0, + "E_SW": 0x01F1, + "E_GE": 0x01F2, + "watch ge trigger": 0x01F3, + "E_YM": 0x01F4, + "E_YM_TAG": 0x01F5, + "E_YMB": 0x01F6, + "fwall trigger": 0x01F7, + "waterfall trigger": 0x01F8, + "shadow keese": 0x01F9, + "E_YR": 0x01FA, + "E_YG": 0x01FB, + "E_HZ": 0x01FC, + "E_WS": 0x01FD, + "E_OC": 0x01FE, + "E_OT": 0x01FF, + "E_DT": 0x0200, + "E_BG": 0x0201, + "E_OctBg": 0x0202, + "DR": 0x0203, + "L7lowDr": 0x0204, + "L7ODR": 0x0205, + "E_TT": 0x0206, + "E_DK": 0x0207, + "E_VT": 0x0208, + "E_WW": 0x0209, + "E_GI": 0x020A, + "B_BH": 0x020B, + "B_BQ": 0x020C, + "B_GM": 0x020D, + "B_GND": 0x020E, + "B_GO": 0x020F, + "B_OH2": 0x0210, + "B_YO": 0x0211, + "B_YOI": 0x0212, + "B_TN": 0x0213, + "B_GG": 0x0214, + "B_DRE": 0x0215, + "B_MGN": 0x0216, + "warp portal": 0x0217, + "ITEM": 0x0218, + "SmallKey": 0x0219, + "Kantera": 0x021A, + "LifeContainer": 0x021B, + "Shield": 0x021C, + "demo item": 0x021D, + "shop item": 0x021E, + "drop": 0x021F, + "RW": 0x0220, + "NBOMB": 0x0221, + "csw trigger": 0x0222, + "qs trigger": 0x0223, + "horseback zelda": 0x0224, + "switch area": 0x0225, + "KNOB20": 0x0226, + "DBDOOR": 0x0227, + "boss door": 0x0228, + "forest boss door": 0x0229, + "forest mini boss door": 0x022A, + "snowpeak boss door": 0x022B, + "DSHUTTER": 0x022C, + "spiral door": 0x022D, + "change restart trigger": 0x022E, + "restart trigger": 0x022F, + "ANDSW": 0x0230, + "ANDSW2": 0x0231, + "MYNA": 0x0232, + "GND": 0x0233, + "GRA": 0x0234, + "GRC": 0x0235, + "GRD": 0x0236, + "GRM": 0x0237, + "GRMC": 0x0238, + "GRO": 0x0239, + "GRR": 0x023A, + "GRS": 0x023B, + "GRZ": 0x023C, + "YAMID": 0x023D, + "YAMIT": 0x023E, + "YAMIS": 0x023F, + "BLUENS": 0x0240, + "KAKASHI": 0x0241, + "KDK": 0x0242, + "ARU": 0x0243, + "BANS": 0x0244, + "BESU": 0x0245, + "BOU": 0x0246, + "BOU_S": 0x0247, + "CLERKA": 0x0248, + "CLERKB": 0x0249, + "CLERKT": 0x024A, + "WRESTLER": 0x024B, + "arena trigger": 0x024C, + "instruction trigger": 0x024D, + "DOC": 0x024E, + "GWOLF": 0x024F, + "LEN": 0x0250, + "LUD": 0x0251, + "fairy spirit": 0x0252, + "FAIRY": 0x0253, + "HANJO": 0x0254, + "HENNA": 0x0255, + "HENNA0": 0x0256, + "HOZ": 0x0257, + "JAGAR": 0x0258, + "KKRI": 0x0259, + "KN": 0x025A, + "KN_BULLET": 0x025B, + "KNJ": 0x025C, + "KOLIN": 0x025D, + "KOLINB": 0x025E, + "KYURY": 0x025F, + "MARO": 0x0260, + "MIDP": 0x0261, + "MOI": 0x0262, + "RACA": 0x0263, + "SARU": 0x0264, + "SEIB": 0x0265, + "SEIC": 0x0266, + "SEID": 0x0267, + "SEIRA": 0x0268, + "SERA2": 0x0269, + "SEIREI": 0x026A, + "SHAMAN": 0x026B, + "SMARO": 0x026C, + "SOLA": 0x026D, + "TARO": 0x026E, + "beth (slingshot)": 0x026F, + "talo (slingshot)": 0x0270, + "malo (slingshot)": 0x0271, + "pati trigger": 0x0272, + "THE": 0x0273, + "TKJ": 0x0274, + "oocca": 0x0275, + "TKC": 0x0276, + "oocca (object)": 0x0277, + "TOBY": 0x0278, + "URI": 0x0279, + "ilia": 0x027A, + "YKM": 0x027B, + "YKW": 0x027C, + "ZANB": 0x027D, + "ZANT": 0x027E, + "ZELDA": 0x027F, + "ZELR": 0x0280, + "ZELRO": 0x0281, + "ZRAFREEZE": 0x0282, + "ZRC": 0x0283, + "ZRZ": 0x0284, + "ZRA_MARK": 0x0285, + "MYNA2": 0x0286, + "plumm trigger": 0x0287, + "CD3": 0x0288, + "schedule trigger": 0x0289, + "escape trigger": 0x028A, + "CHAT": 0x028B, + "SOLDIERa": 0x028C, + "SOLDIERb": 0x028D, + "PASSER_MNG": 0x028E, + "PASSER": 0x028F, + "PASSER2": 0x0290, + "POST": 0x0291, + "POUYA": 0x0292, + "FORMATION_MNG": 0x0293, + "FGUARD": 0x0294, + "GUARD_MNG": 0x0295, + "guard trigger": 0x0296, + "GUARD": 0x0297, + "ASH": 0x0298, + "ASHB": 0x0299, + "SHAD": 0x029A, + "RAFREL": 0x029B, + "MOIR": 0x029C, + "IMPAL": 0x029D, + "SHOE": 0x029E, + "DOORBOY": 0x029F, + "PRAYER": 0x02A0, + "KASIHANA": 0x02A1, + "KASIKYU": 0x02A2, + "KASIMICH": 0x02A3, + "DRSOL": 0x02A4, + "CHIN": 0x02A5, + "INS": 0x02A6, + "SHOP0": 0x02A7, + "MK": 0x02A8, + "P2": 0x02A9, + "KYTAG00": 0x02AA, + "KYTAG01": 0x02AB, + "KYTAG02": 0x02AC, + "KYTAG03": 0x02AD, + "KYTAG04": 0x02AE, + "KYTAG05": 0x02AF, + "KYTAG06": 0x02B0, + "KYTAG07": 0x02B1, + "KYTAG08": 0x02B2, + "KYTAG09": 0x02B3, + "KYTAG10": 0x02B4, + "KYTAG11": 0x02B5, + "KYTAG12": 0x02B6, + "KYTAG13": 0x02B7, + "KYTAG14": 0x02B8, + "KYTAG15": 0x02B9, + "KYTAG16": 0x02BA, + "KYTAG17": 0x02BB, + "Ykgr": 0x02BC, + "TALK": 0x02BD, + "Crope": 0x02BE, + "Bombf": 0x02BF, + "BkLeaf": 0x02C0, + "midna hint trigger": 0x02C1, + "midna message trigger": 0x02C2, + "midna wait trigger": 0x02C3, + "midna stop trigger": 0x02C4, + "stream trigger": 0x02C5, + "sppath trigger": 0x02C6, + "wljump trigger": 0x02C7, + "twilight gate": 0x02C8, + "lv6 gate": 0x02C9, + "lv7 gate trigger": 0x02CA, + "lv8 gate trigger": 0x02CB, + "TheBHint trigger": 0x02CC, + "assist trigger": 0x02CD, + "demo00": 0x02CE, + "camera trigger": 0x02CF, + "checkpoint trigger": 0x02D0, + "event trigger": 0x02D1, + "evt trigger": 0x02D2, + "telop trigger": 0x02D3, + "howl trigger": 0x02D4, + "msg trigger": 0x02D5, + "lantern trigger": 0x02D6, + "mist trigger": 0x02D7, + "DMIDNA": 0x02D8, + "KY_THUNDER": 0x02D9, + "vr box": 0x02DA, + "vr box 2": 0x02DB, + "background": 0x02DC, + "SET_BG_OBJ": 0x02DD, + "BG_OBJ": 0x02DE, + "MIRROR": 0x02DF, + "MOVIE_PLAYER": 0x02E0, + "TITLE": 0x02E1, + "FR": 0x02E2, + "ECONT": 0x02E3, + "MG_ROD": 0x02E4, + "E_ARROW": 0x02E5, + "BULLET": 0x02E6, + "SWHIT0": 0x02E7, + "E_TH_BALL": 0x02E8, + "event area trigger": 0x02E9, + "event message trigger": 0x02EA, + "k message trigger": 0x02EB, + "push trigger": 0x02EC, + "E_MK_BO": 0x02ED, + "E_MM_MT": 0x02EE, + "KBOX": 0x02EF, + "FW": 0x02F0, + "B_GOS": 0x02F1, + "YSTONE": 0x02F2, + "MANT": 0x02F3, + "CROD": 0x02F4, + "PLEAF": 0x02F5, + "KBACKET": 0x02F6, + "YBAG": 0x02F7, + "PUMPKIN": 0x02F8, + "AUTOMATA": 0x02F9, + "GADGET": 0x02FA, + "basket object": 0x02FB, + "Carry": 0x02FC, + "stone": 0x02FD, + "HB": 0x02FE, + "INKO": 0x02FF, + "BD": 0x0300, + "Eff": 0x0301, + "WPILLAR": 0x0302, + "WMARK": 0x0303, + "E_BI": 0x0304, + "E_BI_LEAF": 0x0305, + "START_AND_GOAL": 0x0306, + "DF": 0x0307, + "arrow": 0x0308, + "path line": 0x0309, + "allmato trigger": 0x030A, + "timer": 0x030B, + "SCENE_EXIT": 0x030C, + "CAMERA": 0x030D, + "CAMERA2": 0x030E, + "SUSPEND": 0x030F, + "grass": 0x0310, + "KYEFF": 0x0311, + "KYEFF2": 0x0312, + "MSG_OBJECT": 0x0313, + "MENUWINDOW": 0x0314, + "TIMER": 0x0315, + "METER2": 0x0316, + "game over": 0x0317, +} + +import struct, sys + +def create_procs_bin(): + for name in procnames.keys(): + if len(name) > 30: + raise ValueError(f"Name '{name}' is too long (30 characters max)") + + procnames_values = list(procnames.values()) + for i in range(1, len(procnames_values)): # Start from 1 to avoid checking the first element + if procnames_values[i] - 1 != procnames_values[i - 1]: + raise ValueError(f"Value {procnames_values[i]} at index {i} is not sequential with previous value {procnames_values[i - 1]}") + + if len(procnames) != 792: + raise ValueError(f"Expected 792 procnames, but got {len(procnames)}") + + with open("procs.bin", "wb") as f: + for name, value in procnames.items(): + # Write the ID as a 16-bit signed integer in big-endian format + id_bytes = struct.pack('>h', value) + + # Write the name as a string, then pad with zeros + name_bytes = name.encode('utf-8').ljust(30, b'\0') + + # Write the bytes to the file + f.write(id_bytes) + f.write(name_bytes) + + print("procs.bin created successfully.") + +if __name__ == "__main__": + create_procs_bin() \ No newline at end of file diff --git a/isos/.gitkeep b/isos/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/boot/include/boot.h b/modules/boot/include/boot.h index fd1dedae..da8dcd96 100644 --- a/modules/boot/include/boot.h +++ b/modules/boot/include/boot.h @@ -1,5 +1,4 @@ #pragma once -#include "utils/rels.h" namespace tpgz::modules { /*********************************************************************************** @@ -18,8 +17,7 @@ void exit(); } // namespace tpgz::modules -extern tpgz::dyn::GZModule g_InputViewer_rel; -void GZ_handleTools(); +void GZ_drawPacketNumOverflow(); void GZ_handleMenu(); void GZ_handleCardLoad(); void GZ_handleSavingTmp(); diff --git a/modules/boot/include/cheats.h b/modules/boot/include/cheats.h index bd1a5a03..4c89b8bf 100644 --- a/modules/boot/include/cheats.h +++ b/modules/boot/include/cheats.h @@ -1,40 +1,12 @@ #ifndef LIB_TP_CHEATS #define LIB_TP_CHEATS -#ifdef WII_PLATFORM -#define CHEAT_AMNT 15 -#else -#define CHEAT_AMNT 14 -#endif - -enum CheatId { - InfiniteAir, - InfiniteArrows, - InfiniteBombs, - InfiniteHearts, - InfiniteOil, - InfiniteRupees, - InfiniteSlingshot, - Invincible, - InvincibleEnemies, - MoonJump, - DoorStorage, - SuperClawshot, - UnrestrictedItems, - TransformAnywhere, -#ifdef WII_PLATFORM - GaleLJA, -#endif - SuperSpinner, -}; - -struct Cheat { - enum CheatId id; - bool active; -}; +#include "settings.h" void GZ_applyCheats(); -extern Cheat g_cheats[CHEAT_AMNT]; +inline bool GZ_checkCheat(GZSettingID cheatIdx) { + return GZStng_getData(cheatIdx, false); +} #endif \ No newline at end of file diff --git a/modules/boot/include/collision_view.h b/modules/boot/include/collision_view.h new file mode 100644 index 00000000..4a59bf7d --- /dev/null +++ b/modules/boot/include/collision_view.h @@ -0,0 +1,237 @@ +#pragma once + +#include "libtp_c/include/dolphin/gx/gx.h" +#include "libtp_c/include/dolphin/os/OSCache.h" +#include "libtp_c/include/JSystem/J3DGraphBase/J3DPacket.h" +#include "libtp_c/include/SSystem/SComponent/c_xyz.h" +#include "libtp_c/include/SSystem/SComponent/c_sxyz.h" +#include "libtp_c/include/m_Do/m_Do_mtx.h" + +enum CollisionIndex { + VIEW_AT_CC, + VIEW_TG_CC, + VIEW_CO_CC, + VIEW_POLYGON_GROUND, + VIEW_POLYGON_ROOF, + VIEW_POLYGON_WALL, + VIEW_POLYGON_EDGES, + + VIEW_COLLISION_MAX, +}; + +struct CollisionItem { + enum CollisionIndex id; + bool active; +}; + +extern CollisionItem g_collisionFlags[VIEW_COLLISION_MAX]; +extern u8 g_geometryOpacity; +extern u16 g_collisionRange; +extern u8 g_collisionRaise; + +void dDbVw_deleteDrawPacketList(); + +class dCcS; +void GZ_drawPolygons(); +void GZ_drawCc(dCcS* i_this); + +namespace dCcS_Data { + extern u16 at_obj_count; + extern u16 tg_obj_count; + extern u16 co_obj_count; +} + +//---------------------------------------- +// DRAW PACKETS +//---------------------------------------- + +extern u32 l_drawPacketListNum; + +class mDoExt_cubePacket { +public: + mDoExt_cubePacket(cXyz& position, cXyz& size, csXyz& angle, const GXColor& color) { + mPosition = position; + mSize = size; + mAngle = angle; + mColor = color; + } + + ~mDoExt_cubePacket() {} + + /* 0x00 */ J3DPacket base; + /* 0x10 */ cXyz mPosition; + /* 0x1C */ cXyz mSize; + /* 0x28 */ csXyz mAngle; + /* 0x2E */ GXColor mColor; +}; + +void mDoExt_cubePacket__dtor(mDoExt_cubePacket* i_this); +void mDoExt_cubePacket__draw(mDoExt_cubePacket* i_this); + +class mDoExt_spherePacket { +public: + mDoExt_spherePacket(cXyz& position, f32 size, const GXColor& color, u8 param_3) { + mPosition = position; + mSize = size; + mColor = color; + _24 = param_3; + } + + ~mDoExt_spherePacket() {} + + /* 0x00 */ J3DPacket base; + /* 0x10 */ cXyz mPosition; + /* 0x1C */ f32 mSize; + /* 0x20 */ GXColor mColor; + /* 0x24 */ u8 _24; +}; + +void mDoExt_spherePacket__dtor(mDoExt_spherePacket* i_this); +void mDoExt_spherePacket__draw(mDoExt_spherePacket* i_this); + +class mDoExt_cylinderPacket { +public: + mDoExt_cylinderPacket(cXyz& position, f32 radius, f32 height, const GXColor& color, u8 param_4) { + mPosition = position; + mRadius = radius; + mHeight = height; + mColor = color; + _28 = param_4; + } + + ~mDoExt_cylinderPacket() {} + + /* 0x00 */ J3DPacket base; + /* 0x10 */ cXyz mPosition; + /* 0x1C */ f32 mRadius; + /* 0x20 */ f32 mHeight; + /* 0x24 */ GXColor mColor; + /* 0x28 */ u8 _28; +}; + +void mDoExt_cylinderPacket__dtor(mDoExt_cylinderPacket* i_this); +void mDoExt_cylinderPacket__draw(mDoExt_cylinderPacket* i_this); + +class mDoExt_cube8pPacket { +public: + mDoExt_cube8pPacket(cXyz* points, const GXColor& color) { + cXyz* pnt_array = points; + + for (int i = 0; i < 8; i++) { + mPoints[i] = *pnt_array; + pnt_array++; + } + + DCStoreRangeNoSync(mPoints, 0x60); + mColor = color; + } + + ~mDoExt_cube8pPacket() {} + + /* 0x00 */ J3DPacket base; + /* 0x10 */ cXyz mPoints[8]; + /* 0x70 */ GXColor mColor; +}; + +void mDoExt_cube8pPacket__dtor(mDoExt_cube8pPacket* i_this); +void mDoExt_cube8pPacket__draw(mDoExt_cube8pPacket* i_this); + +class mDoExt_trianglePacket { +public: + mDoExt_trianglePacket(cXyz* points, const GXColor& color, u8 param_2) { + cXyz* pnt_array = points; + + for (int i = 0; i < 3; i++) { + mPoints[i] = *pnt_array; + pnt_array++; + } + + DCStoreRangeNoSync(mPoints, 0x24); + mColor = color; + _38 = param_2; + } + + ~mDoExt_trianglePacket() {} + + /* 0x00 */ J3DPacket base; + /* 0x10 */ cXyz mPoints[3]; + /* 0x34 */ GXColor mColor; + /* 0x38 */ u8 _38; +}; + +void mDoExt_trianglePacket__dtor(mDoExt_trianglePacket* i_this); +void mDoExt_trianglePacket__draw(mDoExt_trianglePacket* i_this); + +class mDoExt_linePacket { +public: + mDoExt_linePacket(cXyz& pointA, cXyz& pointB, const GXColor& color, u8 param_3, u8 width) { + mPointA = pointA; + mPointB = pointB; + mColor = color; + _2C = param_3; + mWidth = width; + } + + ~mDoExt_linePacket() {} + + /* 0x00 */ J3DPacket base; + /* 0x10 */ cXyz mPointA; + /* 0x1C */ cXyz mPointB; + /* 0x28 */ GXColor mColor; + /* 0x2C */ u8 _2C; + /* 0x2D */ u8 mWidth; +}; + +void mDoExt_linePacket__dtor(mDoExt_linePacket* i_this); +void mDoExt_linePacket__draw(mDoExt_linePacket* i_this); + +class mDoExt_cylinderMPacket { +public: + mDoExt_cylinderMPacket(Mtx m, const GXColor& color, u8 param_2) { + PSMTXCopy(m, mMatrix); + mColor = color; + _44 = param_2; + } + + ~mDoExt_cylinderMPacket() {} + + /* 0x00 */ J3DPacket base; + /* 0x10 */ Mtx mMatrix; + /* 0x40 */ GXColor mColor; + /* 0x44 */ u8 _44; +}; + +void mDoExt_cylinderMPacket__dtor(mDoExt_cylinderMPacket* i_this); +void mDoExt_cylinderMPacket__draw(mDoExt_cylinderMPacket* i_this); + +class mDoExt_circlePacket { +public: + mDoExt_circlePacket(cXyz& i_position, f32 i_radius, const GXColor& i_color, u8 param_3, u8 i_lineWidth) { + m_position = i_position; + m_radius = i_radius; + m_color = i_color; + _24 = param_3; + m_lineWidth = i_lineWidth; + } + + ~mDoExt_circlePacket() {} + + /* 0x00 */ J3DPacket base; + /* 0x10 */ cXyz m_position; + /* 0x1C */ f32 m_radius; + /* 0x20 */ GXColor m_color; + /* 0x24 */ u8 _24; + /* 0x25 */ u8 m_lineWidth; +}; + +void mDoExt_circlePacket__dtor(mDoExt_circlePacket* i_this); +void mDoExt_circlePacket__draw(mDoExt_circlePacket* i_this); + +void dDbVw_drawCubeXlu(cXyz& pos, cXyz& size, csXyz& angle, const GXColor& color); +void dDbVw_drawSphereXlu(cXyz& position, f32 radius, const GXColor& color, u8 param_3); +void dDbVw_drawCylinderXlu(cXyz& position, f32 radius, f32 height, const GXColor& color, u8 param_4); +void dDbVw_drawCube8pXlu(cXyz* points, const GXColor& color); +void dDbVw_drawTriangleXlu(cXyz* points, const GXColor& color, u8 param_2); +void dDbVw_drawLineXlu(cXyz& pointA, cXyz& pointB, const GXColor& color, u8 param_3, u8 width); +void dDbVw_drawCylinderMXlu(Mtx m, const GXColor& color, u8 param_2); +void dDbVw_drawCircleXlu(cXyz& i_position, f32 i_radius, const GXColor& i_color, u8 param_3, u8 i_lineWidth); \ No newline at end of file diff --git a/modules/boot/include/commands.h b/modules/boot/include/commands.h index 401d94c5..c56a39e2 100644 --- a/modules/boot/include/commands.h +++ b/modules/boot/include/commands.h @@ -1,10 +1,11 @@ #pragma once #include +#include "libtp_c/include/JSystem/JUtility/JUTGamePad.h" #include "libtp_c/include/m_Do/m_Re_controller_pad.h" +#include "utils/containers/deque.h" #ifdef GCN_PLATFORM #define COMMANDS_AMNT 10 -#define GORGE_VOID_BUTTONS (CButton::L | CButton::Z) #define STORE_POSITION_BUTTONS (CButton::DPAD_UP | CButton::R) #define LOAD_POSITION_BUTTONS (CButton::DPAD_DOWN | CButton::R) #define MOON_JUMP_BUTTONS (CButton::R | CButton::A) @@ -14,22 +15,12 @@ #define FREE_CAM_BUTTONS (CButton::Z | CButton::B | CButton::A) #define MOVE_LINK_BUTTONS (CButton::L | CButton::R | CButton::Y) #define FRAME_PAUSE_BUTTONS (CButton::R | CButton::DPAD_UP) -#define FRAME_ADVANCE_BUTTONS (CButton::R | CButton::DPAD_RIGHT) -#define FRAME_ADVANCE_TEXT "R + D-Pad Up" -#define GORGE_VOID_TEXT "L+Z" -#define STORE_POSITION_TEXT "D-PAD up + R" -#define LOAD_POSITION_TEXT "D-PAD down + R" -#define MOON_JUMP_TEXT "R+A" -#define RELOAD_AREA_TEXT "L+R+A+Start" -#define TIMER_TOGGLE_TEXT "Z+A" -#define TIMER_RESET_TEXT "Z+B" -#define FREE_CAM_TEXT "Z+B+A" -#define MOVE_LINK_TEXT "L+R+Y" +#define FRAME_ADVANCE_BUTTONS (CButton::R) +#define GORGE_VOID_BUTTONS (CButton::L | CButton::Z) #endif #ifdef WII_PLATFORM #define COMMANDS_AMNT 11 -#define GORGE_VOID_BUTTONS (CButton::Z | CButton::C | CButton::A | CButton::ONE) #define BACK_IN_TIME_BUTTONS (CButton::Z | CButton::C | CButton::A | CButton::TWO) #define STORE_POSITION_BUTTONS (CButton::Z | CButton::C | CButton::ONE) #define LOAD_POSITION_BUTTONS (CButton::Z | CButton::C | CButton::TWO) @@ -41,23 +32,11 @@ #define MOVE_LINK_BUTTONS (CButton::Z | CButton::C | CButton::B | CButton::PLUS) #define FRAME_PAUSE_BUTTONS (CButton::Z | CButton::C | CButton::PLUS | CButton::MINUS) #define FRAME_ADVANCE_BUTTONS (CButton::TWO) -#define GORGE_VOID_TEXT "Z+C+A+1" -#define BACK_IN_TIME_TEXT "Z+C+A+2" -#define STORE_POSITION_TEXT "Z+C+1" -#define LOAD_POSITION_TEXT "Z+C+2" -#define MOON_JUMP_TEXT "Z+C+A" -#define RELOAD_AREA_TEXT "Z+C+B+2" -#define TIMER_TOGGLE_TEXT "Z+C+A+B" -#define TIMER_RESET_TEXT "Z+C+B+1" -#define FREE_CAM_TEXT "Z+C+B+Minus" -#define MOVE_LINK_TEXT "Z+C+B+Plus" -#define FRAME_ADVANCE_TEXT "Z+C+Plus+Minus (2 for trig)" +#define GORGE_VOID_BUTTONS (CButton::Z | CButton::C | CButton::A | CButton::ONE) #endif extern bool reload_area_flag; -extern bool g_commandStates[COMMANDS_AMNT]; - enum Commands { CMD_STORE_POSITION, CMD_LOAD_POSITION, @@ -75,13 +54,33 @@ enum Commands { }; struct Command { - bool& active; + Commands id; uint16_t buttons; void (*command)(); }; -void GZCmd_processInputs(); -void GZCmd_enable(int idx); -void GZCmd_disable(int idx); +extern tpgz::containers::deque g_commands; + +bool GZCmd_checkTrig(int combo); + +void GZCmd_storePosition(); +void GZCmd_loadPosition(); +void GZCmd_moonJump(); void GZCmd_reloadArea(); -void GZCmd_advanceFrame(); \ No newline at end of file +void GZCmd_toggleTimer(); +void GZCmd_resetTimer(); +#ifdef WII_PLATFORM +void GZCmd_bitPractice(); +#endif +void GZCmd_toggleFreeCam(); +void GZCmd_toggleMoveLink(); +void GZCmd_pauseFrame(); + +void GZCmd_addCmd(Command* cmd); +Command* GZCmd_removeCmd(Commands cmdId); +Command* GZCmd_getCmd(int id); + +void GZCmd_processInputs(); + +size_t GZCmd_getComboLen(uint16_t combo); +void GZCmd_comboToStr(uint16_t combo, char* str); \ No newline at end of file diff --git a/modules/boot/include/controller.h b/modules/boot/include/controller.h index 0f2a68f6..d59f91da 100644 --- a/modules/boot/include/controller.h +++ b/modules/boot/include/controller.h @@ -44,5 +44,8 @@ bool GZ_getButtonRepeat(int idx, uint16_t repeat_time); bool GZ_getButtonPressed(int idx); bool GZ_getButtonHold(int idx, int phase = 0); uint16_t GZ_getButtonStatus(); +uint16_t GZ_getButtonStatusSaved(); void GZ_readController(); bool GZ_getButtonTrig(int idx); +void GZ_getButtonPressCount(u8& i_pressCounter, int i_button, int i_gzButton); +bool GZ_getPadTrigAny(uint16_t pad); diff --git a/modules/boot/include/font.h b/modules/boot/include/font.h index a7c6ee0a..bc4640cb 100644 --- a/modules/boot/include/font.h +++ b/modules/boot/include/font.h @@ -2,10 +2,9 @@ #include #include +#include "libtp_c/include/dolphin/gx/gx.h" #include "libtp_c/include/dolphin/mtx/vec.h" -#include "libtp_c/include/addrs.h" #include "utils/texture.h" -#include "gcn_c/include/gfx.h" #define MAX_GLYPHS 94 #define DROP_SHADOWS_RGBA 0x000000FF @@ -77,6 +76,8 @@ class Font { static void GZ_drawStr(const char* str, float x, float y, uint32_t color, bool drop_shadows, float size = FONT_DEFAULT_SIZE); static float getCharWidth(char c, float size = FONT_DEFAULT_SIZE); + static float getMaxCharWidth(float size = FONT_DEFAULT_SIZE); + static float getMaxCharRangeWidth(char start, char end, float size = FONT_DEFAULT_SIZE); static float getStrWidth(const char* str, float size = FONT_DEFAULT_SIZE); }; diff --git a/modules/boot/include/global_data.h b/modules/boot/include/global_data.h index f148e8c4..ee2e56ba 100644 --- a/modules/boot/include/global_data.h +++ b/modules/boot/include/global_data.h @@ -1,4 +1,8 @@ #pragma once +#include "libtp_c/include/f_op/f_op_actor_mng.h" extern bool g_freeCamEnabled; extern bool g_moveLinkEnabled; +extern fopAc_ac_c* g_currentActor; +extern bool g_actorViewEnabled; +extern bool g_transformIndicatorEnabled; diff --git a/modules/boot/include/gz_flags.h b/modules/boot/include/gz_flags.h index 9706b997..4ba3e4a0 100644 --- a/modules/boot/include/gz_flags.h +++ b/modules/boot/include/gz_flags.h @@ -5,20 +5,38 @@ #include "save_manager.h" #include "settings.h" #include "fifo_queue.h" +#include "utils/containers/deque.h" +#include "libtp_c/include/m_Do/m_Re_controller_pad.h" #ifdef WII_PLATFORM -#define MAX_GZ_FLAGS 14 #define FRAME_ADVANCE_BTN GZPad::TWO #define FRAME_ADVANCE_PAD CButton::TWO #endif #ifdef GCN_PLATFORM -#define MAX_GZ_FLAGS 13 #define FRAME_ADVANCE_BTN GZPad::R #define FRAME_ADVANCE_PAD CButton::R #endif +enum GZFlags { + GZFLG_GORGE_VOID, +#ifdef WII_PLATFORM + GZFLG_BIT, +#endif + GZFLG_ROLL, + GZFLG_COROTD, + GZFLG_UMD, + GZFLG_FREEZE_ACTOR, + GZFLG_HIDE_ACTOR, + GZFLG_FREEZE_CAMERA, + GZFLG_HIDE_HUD, + GZFLG_FREEZE_TIME, + GZFLG_DISABLE_BGM, + GZFLG_DISABLE_SFX, +}; + struct GZFlag { - bool* mpFlag; + GZFlags id; + bool (*mpFlag)(); int mPhase; void (*mpActiveFunc)(); void (*mpDeactiveFunc)(); @@ -26,15 +44,12 @@ struct GZFlag { extern bool g_framePaused; -enum LoopPhase { GAME_LOOP, POST_GAME_LOOP }; +extern tpgz::containers::deque g_gzFlags; -inline bool GZ_checkCheat(int cheatIdx) { - return g_cheats[cheatIdx].active; -} +void GZFlg_addFlag(GZFlag* flag); +GZFlag* GZFlg_removeFlag(GZFlags flag_id); -inline bool GZ_checkDropShadows() { - return g_dropShadows; -} +enum LoopPhase { GAME_LOOP, POST_GAME_LOOP }; inline void GZ_setFifoVisible(bool visible) { g_fifoVisible = visible; @@ -44,4 +59,12 @@ void GZ_frameAdvance(); void GZ_execute(int phase); void GZ_drawFrameTex(Texture* pauseTex, Texture* playTex); -extern volatile uint8_t sPauseTimer; \ No newline at end of file +extern volatile uint8_t sPauseTimer; + +bool GZ_freezeActors_active(); +bool GZ_hideActors_active(); +bool GZ_freezeCamera_active(); +bool GZ_hideHUD_active(); +bool GZ_freezeTime_active(); +bool GZ_disableBgm_active(); +bool GZ_disableSFX_active(); \ No newline at end of file diff --git a/modules/boot/include/menu.h b/modules/boot/include/menus/menu.h similarity index 84% rename from modules/boot/include/menu.h rename to modules/boot/include/menus/menu.h index 40a2bd3e..f7e872a4 100644 --- a/modules/boot/include/menu.h +++ b/modules/boot/include/menus/menu.h @@ -4,6 +4,7 @@ #include "font.h" #include "libtp_c/include/JSystem/JUtility/JUTGamePad.h" #include "libtp_c/include/dolphin/mtx/vec.h" +#include "libtp_c/include/defines.h" #include "timer.h" #include "utils/cursor.h" #include "utils/lines.h" @@ -19,6 +20,7 @@ #define BACK_BUTTON (GZPad::B) #endif +// If you add a new menu to this list, you must also add the REL name to the g_menuPaths array in menu.cpp. enum MenuIndex { MN_NONE_INDEX = -1, MN_MAIN_MENU_INDEX = 0, @@ -56,8 +58,13 @@ enum MenuIndex { // Scene menu's sub menus MN_ACTOR_SPAWNER_INDEX, MN_ACTOR_LIST_INDEX, + MN_COLLISION_VIEW_INDEX, + MN_PROJECTION_VIEW_INDEX, + MN_TRIGGER_VIEW_INDEX, // Setting menu's sub menus MN_POS_SETTINGS_INDEX, + MN_CREDITS_INDEX, + MN_COMBO_INDEX, // This entry is used only to get a count of the number of valid entries. MN_COUNT @@ -65,8 +72,7 @@ enum MenuIndex { extern const char* g_menuPaths[MN_COUNT]; -#define LIST_COUNT(list) (sizeof(list) / sizeof((list)[0])) -#define MENU_LINE_NUM LIST_COUNT(lines) +#define MENU_LINE_NUM ARRAY_COUNT(lines) class Menu { public: diff --git a/modules/boot/include/menus/utils/menu_mgr.h b/modules/boot/include/menus/utils/menu_mgr.h index 5a6eba5b..d60a8a0c 100644 --- a/modules/boot/include/menus/utils/menu_mgr.h +++ b/modules/boot/include/menus/utils/menu_mgr.h @@ -5,7 +5,7 @@ #include #include "utils/rels.h" #include "utils/cursor.h" -#include "menu.h" +#include "menus/menu.h" // Namespace for internal classes. namespace menus { diff --git a/modules/boot/include/modules.h b/modules/boot/include/modules.h new file mode 100644 index 00000000..1c0f7b0e --- /dev/null +++ b/modules/boot/include/modules.h @@ -0,0 +1,31 @@ +#pragma once +#include "utils/rels.h" +#include "utils/containers/deque.h" + +struct Module { + bool (*active)(); + tpgz::dyn::GZModule rel; +}; + +extern tpgz::containers::deque g_modules; + +void GZ_handleModules(); +bool inputViewer_active(); +bool freeCam_active(); +bool moveLink_active(); +bool projectionView_active(); +bool triggerViewer_active(); +bool actorView_active(); +bool transformIndicator_active(); +bool umd_active(); +#ifdef WII_PLATFORM +bool bit_active(); +#endif +bool corotd_active(); +bool mash_checker_active(); +bool gorge_active(); +bool rollcheck_active(); +bool moon_jump_active(); +bool freeze_actor_active(); +bool hide_actor_active(); +bool freeze_camera_active(); diff --git a/modules/boot/include/pos_settings.h b/modules/boot/include/pos_settings.h index dd934dbe..d0b12069 100644 --- a/modules/boot/include/pos_settings.h +++ b/modules/boot/include/pos_settings.h @@ -1,8 +1,9 @@ #pragma once +#include "settings.h" #include "libtp_c/include/dolphin/mtx/vec.h" -#define SPRITES_AMNT 8 +#define SPRITES_AMNT 10 enum SpritesIndex { MENU_INDEX, VIEWER_INDEX, @@ -11,9 +12,11 @@ enum SpritesIndex { LOAD_TIMER_SPR_INDEX, IGT_TIMER_SPR_INDEX, FIFO_SPR_INDEX, - HEAP_INFO_INDEX + HEAP_INFO_INDEX, + MASH_INFO_INDEX, + TRANSFORM_IND_INDEX, }; -extern Vec2 g_spriteOffsets[SPRITES_AMNT]; - -void GZ_PosSettings_initDefaults(); +inline Vec2 GZ_getSpriteOffset(GZSettingID sprIdx) { + return GZStng_getData(sprIdx, Vec2{0.0f, 0.0f}); +} diff --git a/modules/boot/include/practice.h b/modules/boot/include/practice.h index 2453c9ac..d9a2e613 100644 --- a/modules/boot/include/practice.h +++ b/modules/boot/include/practice.h @@ -20,5 +20,5 @@ enum { extern int last_save_index; extern char last_category[5]; -extern special* last_special_ptr; +extern special last_special; extern int last_special_size; diff --git a/modules/boot/include/save_manager.h b/modules/boot/include/save_manager.h index b570b33f..0eec1fc9 100644 --- a/modules/boot/include/save_manager.h +++ b/modules/boot/include/save_manager.h @@ -1,17 +1,9 @@ #pragma once -#include "cheats.h" -#include "watches.h" -#include "pos_settings.h" -#include "scene.h" -#include "tools.h" -#include "commands.h" +#include "utils/containers/deque.h" #include "libtp_c/include/dolphin/mtx/vec.h" #include "libtp_c/include/d/com/d_com_inf_game.h" -#define GZ_SAVE_VERSION_NUMBER 0 -#define GZ_SAVE_ENTRIES_AMNT 10 - #ifdef GCN_NTSCU #define sTmpBuf 0x803ecf40 #endif @@ -44,6 +36,12 @@ typedef void (*LoadingCallback)(void); class special { public: + special() { + idx = 0; + CallbackDuring = nullptr; + CallbackAfter = nullptr; + } + special(int i_idx, LoadingCallback cb_during, LoadingCallback cb_after) { idx = i_idx; CallbackDuring = cb_during; @@ -117,46 +115,4 @@ class SaveManager { void setSaveAngle(int16_t angle) { mPracticeSaveInfo.angle = angle; } }; -extern SaveManager gSaveManager; - -// These numbers can only change when we change the GZ_SAVE_VERSION_NUMBER, -// otherwise, only new entries can be added. -enum GZSaveIndex { - SV_CHEATS_INDEX = 0, - SV_TOOLS_INDEX = 1, - SV_SCENE_INDEX = 2, - SV_WATCHES_INDEX = 3, - SV_SPRITES_INDEX = 4, - SV_DROP_SHADOW_INDEX = 5, - SV_AREA_RELOAD_INDEX = 6, - SV_CURSOR_COLOR_INDEX = 7, - SV_COMMANDS = 8, - SV_FONT_INDEX = 9, -}; - -struct GZSaveHeader { - uint32_t version; - uint32_t entries; - uint32_t offsetsLoc; - uint32_t sizesLoc; -}; - -struct GZSaveLayout { - Cheat mCheats[CHEAT_AMNT]; - Tool mTools[TOOLS_COUNT]; - SceneItem mSceneFlags[SCENE_AMNT]; - MemoryWatch mWatches[MAX_WATCHES]; - Vec2 mSpriteOffsets[SPRITES_AMNT]; - bool mCommandStates[COMMANDS_AMNT]; - bool mDropShadows; - int mReloadType; - int mCursorColType; - int mFontType; -}; - -struct GZSaveFile { - GZSaveHeader header; - uint32_t offsets[GZ_SAVE_ENTRIES_AMNT]; - uint32_t sizes[GZ_SAVE_ENTRIES_AMNT]; - GZSaveLayout data; -}; \ No newline at end of file +extern SaveManager gSaveManager; \ No newline at end of file diff --git a/modules/boot/include/save_specials.h b/modules/boot/include/save_specials.h index 26eec4f4..68f9caac 100644 --- a/modules/boot/include/save_specials.h +++ b/modules/boot/include/save_specials.h @@ -5,7 +5,6 @@ void SaveMngSpecial_OrdonRock(); void SaveMngSpecial_BossFlags(); void SaveMngSpecial_Goats1(); -void SaveMngSpecial_Goats2(); void SaveMngSpecial_Hugo(); void SaveMngSpecial_SpawnHugo(); @@ -29,6 +28,7 @@ void SaveMngSpecial_LakebedBKSkip(); void SaveMngSpecial_Morpheel(); void SaveMngSpecial_Iza1Skip(); +void SaveMngSpecial_AnyPlummOoB(); void SaveMngSpecial_Stallord(); void SaveMngSpecial_Stallord2(); @@ -39,7 +39,6 @@ void SaveMngSpecial_ToTEarlyHP(); void SaveMngSpecial_HugoArchery(); -void SaveMngSpecial_AeralfosSkip(); void SaveMngSpecial_CityPoeCycle(); void SaveMngSpecial_FanTower(); void SaveMngSpecial_Argorok(); diff --git a/modules/boot/include/scene.h b/modules/boot/include/scene.h index 40634abd..111e6bf0 100644 --- a/modules/boot/include/scene.h +++ b/modules/boot/include/scene.h @@ -14,6 +14,11 @@ enum SceneIndex { TIME_MINUTES_INDEX, ACTOR_MENU_INDEX, ACTOR_LIST_INDEX, + COLLISION_VIEW_INDEX, + PROJECTION_VIEW_INDEX, + TRIGGER_VIEW_INDEX, + + SCENE_MENU_MAX }; struct SceneItem { @@ -21,8 +26,6 @@ struct SceneItem { bool active; }; -extern SceneItem g_sceneFlags[SCENE_AMNT]; - void GZ_freezeTime(); void GZ_freezeCamera(); void GZ_unfreezeCamera(); diff --git a/modules/boot/include/settings.h b/modules/boot/include/settings.h index 6972ec21..9e344a38 100644 --- a/modules/boot/include/settings.h +++ b/modules/boot/include/settings.h @@ -2,20 +2,141 @@ #include #include "utils/lines.h" +#include "utils/containers/deque.h" #define CURSOR_RGBA g_cursorColor -#define FONT_OPTIONS_COUNT (sizeof(g_font_opt) / sizeof(g_font_opt[0])) +#define FONT_OPTIONS_COUNT ARRAY_COUNT(g_font_opt) #define LOAD_AREA 0 #define LOAD_FILE 1 -extern bool g_dropShadows; +#define ACTIVE_FUNC(id) []() { return GZStng_getData(id, false); } + extern bool g_swap_equips_flag; -extern uint32_t g_reloadType; -extern uint32_t g_fontType; -extern uint32_t g_cursorColorType; extern ListMember g_font_opt[7]; +// WARNING +// The order is important, DO NOT add entries in the middle of the enum. +// Add them at the end, even if it should be with an other group. +// Changes in the order is only allowed when the +// version number GZ_SAVE_VERSION_NUMBER is changed. +enum GZSettingID : uint32_t { + // Miscellaneous + STNG_DROP_SHADOWS, + STNG_AREA_RELOAD_BEHAVIOUR, + STNG_CURSOR_COLOR, + STNG_FONT, + // Cheats + STNG_CHEATS_INFINITE_AIR, + STNG_CHEATS_INFINITE_ARROWS, + STNG_CHEATS_INFINITE_BOMBS, + STNG_CHEATS_INFINITE_HEARTS, + STNG_CHEATS_INFINITE_OIL, + STNG_CHEATS_INFINITE_RUPEES, + STNG_CHEATS_INFINITE_SLINGSHOT, + STNG_CHEATS_INVINCIBLE, + STNG_CHEATS_INVINCIBLE_ENEMIES, + STNG_CHEATS_MOON_JUMP, + STNG_CHEATS_DOOR_STORAGE, + STNG_CHEATS_SUPER_CLAWSHOT, + STNG_CHEATS_UNRESTRICTED_ITEMS, + STNG_CHEATS_TRANSFORM_ANYWHERE, + STNG_CHEATS_DISABLE_ITEM_TIMER, + STNG_CHEATS_GALE_LJA, // Wii only, but we reserve the id anyway + // Tools + STNG_TOOLS_RELOAD_AREA, + STNG_TOOLS_FRAME_ADVANCE, + STNG_TOOLS_FAST_BONK, + STNG_TOOLS_FAST_MOVEMENT, + STNG_TOOLS_GORGE, + STNG_TOOLS_BIT, // Wii only, but we reserve the id anyway + STNG_TOOLS_COROTD, + STNG_TOOLS_UMD, + STNG_TOOLS_INPUT_VIEWER, + STNG_TOOLS_LINK_DEBUG, + STNG_TOOLS_HEAP_DEBUG, + STNG_TOOLS_SAND, + STNG_TOOLS_ROLL, + STNG_TOOLS_MASH_CHECKER, + STNG_TOOLS_TELEPORT, + STNG_TOOLS_TURBO_MODE, + STNG_TOOLS_TIMER, + STNG_TOOLS_LOAD_TIMER, + STNG_TOOLS_IGT_TIMER, + STNG_TOOLS_FREE_CAM, + STNG_TOOLS_MOVE_LINK, + STNG_TOOLS_TRANSFORM_INDICATOR, + // Scene + STNG_SCENE_FREEZE_ACTOR, + STNG_SCENE_HIDE_ACTOR, + STNG_SCENE_DISABLE_BG, + STNG_SCENE_DISABLE_SFX, + STNG_SCENE_FREEZE_CAMERA, + STNG_SCENE_HIDE_HUD, + STNG_SCENE_FREEZE_TIME, + // Watches + STNG_WATCHES, + // Sprites + STNG_SPRITES_INPUT_VIEWER, + STNG_SPRITES_MENU, + STNG_SPRITES_DEBUG_INFO, + STNG_SPRITES_TIMER_SPR, + STNG_SPRITES_LOAD_TIMER_SPR, + STNG_SPRITES_IGT_TIMER_SPR, + STNG_SPRITES_FIFO_SPR, + STNG_SPRITES_HEAP_INFO, + STNG_SPRITES_MASH_INFO, + STNG_SPRITES_TRANSFORM_IND, + // New Adds + STNG_SCENE_LJA_PROJECTION, + STNG_SCENE_MIDNA_CHARGE_PROJECTION, + // Combos + STNG_CMD_FRAME_PAUSE, + STNG_CMD_FRAME_ADVANCE, + STNG_CMD_TIMER_TOGGLE, + STNG_CMD_TIMER_RESET, + STNG_CMD_STORE_POSITION, + STNG_CMD_LOAD_POSITION, + STNG_CMD_RELOAD_AREA, + STNG_CMD_FREE_CAM, + STNG_CMD_MOVE_LINK, + STNG_CMD_BIT, // Wii only, but we reserve the id anyway + STNG_CMD_GORGE_VOID, + STNG_CMD_MOON_JUMP, +}; + +struct GZSettingEntry { + GZSettingID id; + size_t size; + void* data; +}; + +extern tpgz::containers::deque g_settings; + +/** + * If the setting is not yet in the list, adds it. + * Otherwise, deletes the old data, and replaces it by the provided one. + */ +void GZStng_add(GZSettingID id, void* data, size_t size); +/** + * Removes a setting from the list. + */ +void GZStng_remove(GZSettingID id); +/** + * Returns a setting entry if it is in the list. nullptr otherwise. + */ +GZSettingEntry* GZStng_get(GZSettingID id); +/** + * Returns a list of all the ids of the settings in the list. + */ +tpgz::containers::deque* GZStng_getList(); + +template +T GZStng_getData(GZSettingID id, T defaultValue) { + auto* stng = GZStng_get(id); + return stng ? *static_cast(stng->data) : defaultValue; +} + enum cursor_colors { CURSOR_GREEN, CURSOR_BLUE, @@ -26,3 +147,8 @@ enum cursor_colors { }; void GZ_initFont(); + +inline bool GZ_checkDropShadows() { + auto* stng = GZStng_get(STNG_DROP_SHADOWS); + return stng && *static_cast(stng->data); +} diff --git a/modules/boot/include/tools.h b/modules/boot/include/tools.h index 29beea2e..d4333a50 100644 --- a/modules/boot/include/tools.h +++ b/modules/boot/include/tools.h @@ -16,6 +16,7 @@ enum ToolsIndex { HEAP_DEBUG_INDEX, SAND_INDEX, ROLL_INDEX, + MASH_CHECKER_INDEX, TELEPORT_INDEX, TURBO_MODE_INDEX, TIMER_INDEX, @@ -47,3 +48,5 @@ extern TunicColor TunicColors[TUNIC_COLOR_AMNT]; extern Tool g_tools[TOOLS_COUNT]; extern int g_tunic_color; + +void GZ_handleTools(); diff --git a/modules/boot/include/trigger_view.h b/modules/boot/include/trigger_view.h new file mode 100644 index 00000000..e6da4840 --- /dev/null +++ b/modules/boot/include/trigger_view.h @@ -0,0 +1,25 @@ +#pragma once + +#include "libtp_c/include/dolphin/types.h" + +enum TriggerViewIndex { + VIEW_ATTN_DISTS, + VIEW_EVENT_AREAS, + VIEW_LOAD_ZONES, + VIEW_MIDNA_STOPS, + VIEW_PATHS, + VIEW_MIST_AVOID, + VIEW_CHG_RESTARTS, + VIEW_SWITCH_AREAS, + VIEW_TRANSFORM_DISTS, + VIEW_TW_GATES, + + TRIGGER_VIEW_MAX, +}; + +struct TriggerViewItem { + enum TriggerViewIndex id; + bool active; +}; + +extern TriggerViewItem g_triggerViewFlags[TRIGGER_VIEW_MAX]; \ No newline at end of file diff --git a/modules/boot/include/utils/card.h b/modules/boot/include/utils/card.h index 89d76b2b..16d6e9de 100644 --- a/modules/boot/include/utils/card.h +++ b/modules/boot/include/utils/card.h @@ -1,11 +1,23 @@ #include "font.h" #include "gcn_c/include/storage.h" -#include "menu.h" +#include "menus/menu.h" + +#define GZ_SAVE_VERSION_NUMBER 1 #ifdef WII_PLATFORM extern void* g_tmpBuf; #endif +struct GZSaveHeader { + uint32_t version; + size_t data_size; + uint32_t entries; +}; + +struct GZSaveFile { + GZSaveHeader header; +}; + int32_t GZ_storageWrite(Storage* info, void* data, int32_t size, int32_t offset, int32_t sector_size); int32_t GZ_storageRead(Storage* info, void* data, int32_t size, int32_t offset, @@ -16,4 +28,5 @@ void GZ_deleteMemCard(Storage& card); void GZ_deleteMemfile(Storage& card); void GZ_loadMemCard(Storage& card); void GZ_loadMemfile(Storage& card); +bool GZ_memfileExists(Storage& card); void GZ_loadGZSave(bool& card_load); \ No newline at end of file diff --git a/modules/boot/include/utils/containers/deque.h b/modules/boot/include/utils/containers/deque.h index dfd135a3..bc124014 100644 --- a/modules/boot/include/utils/containers/deque.h +++ b/modules/boot/include/utils/containers/deque.h @@ -190,6 +190,24 @@ class deque { } } + void resize(size_t new_size) { + while (_size > new_size) { + pop_back(); + } + while (_size < new_size) { + push_back(T()); + } + } + + void resize(size_t new_size, const T& value) { + while (_size > new_size) { + pop_back(); + } + while (_size < new_size) { + push_back(value); + } + } + iterator begin() { return iterator(head); } iterator end() { return iterator(nullptr); } diff --git a/modules/boot/include/utils/draw.h b/modules/boot/include/utils/draw.h index e08b6525..7ae9eed3 100644 --- a/modules/boot/include/utils/draw.h +++ b/modules/boot/include/utils/draw.h @@ -1,7 +1,6 @@ #pragma once -#include "libtp_c/include/addrs.h" -#include "gcn_c/include/gfx.h" +#include "libtp_c/include/dolphin/gx/gx.h" #include "libtp_c/include/dolphin/mtx/vec.h" #include "utils/texture.h" diff --git a/modules/boot/include/utils/hook.h b/modules/boot/include/utils/hook.h index 72de2fa4..56d32fd1 100644 --- a/modules/boot/include/utils/hook.h +++ b/modules/boot/include/utils/hook.h @@ -1,3 +1,4 @@ +#pragma once #define HOOK_AMNT 18 enum HookIndex { diff --git a/modules/boot/include/utils/lines.h b/modules/boot/include/utils/lines.h index adbaf3a2..0a9ae932 100644 --- a/modules/boot/include/utils/lines.h +++ b/modules/boot/include/utils/lines.h @@ -20,9 +20,10 @@ struct Line { const uint32_t idx; char description[MAX_DESCRIPTION_LENGTH]; bool toggleable = false; - bool* activation_flag; + bool (*active)(); uint8_t max_y_cursor_options; char value[sizeof(Line::line)] = {0}; + bool disabled = false; template inline int printf(const char* fmt, Args... args) { @@ -31,5 +32,6 @@ struct Line { }; float maxF(float a, float b); +float minF(float a, float b); void menu_anim(int idx); void GZ_drawMenuLines(Line input_lines[], uint32_t cursor, uint32_t LINES); \ No newline at end of file diff --git a/modules/boot/include/utils/link.h b/modules/boot/include/utils/link.h index 0d91ad29..29f6a440 100644 --- a/modules/boot/include/utils/link.h +++ b/modules/boot/include/utils/link.h @@ -1,41 +1,6 @@ #pragma once #include "font.h" -#include "libtp_c/include/dolphin/os/OSCache.h" void GZ_displayLinkInfo(); -void GZ_setTunicColor(); - -inline void GZ_patchLinkColor() { -#ifdef WII_PLATFORM -#ifdef WII_NTSCU_10 -#define SWORD_UP_RED_ADDR 0x801176B0 -#define SWORD_UP_GREEN_ADDR 0x801176C8 -#define SWORD_UP_BLUE_ADDR 0x801176E0 -#endif -#ifdef WII_NTSCU_12 -#define SWORD_UP_RED_ADDR 0x80117de0 -#define SWORD_UP_GREEN_ADDR 0x80117df8 -#define SWORD_UP_BLUE_ADDR 0x80117e10 -#endif -#ifdef WII_NTSCJ -#define SWORD_UP_RED_ADDR 0x80117bec -#define SWORD_UP_GREEN_ADDR 0x80117c04 -#define SWORD_UP_BLUE_ADDR 0x80117c1c -#endif -#ifdef WII_PAL -#define SWORD_UP_RED_ADDR 0x80117d64 -#define SWORD_UP_GREEN_ADDR 0x80117d7c -#define SWORD_UP_BLUE_ADDR 0x80117d94 -#endif - *reinterpret_cast(SWORD_UP_RED_ADDR) = 0x60000000; // nop - DCFlushRange((void*)(SWORD_UP_RED_ADDR), sizeof(uint32_t)); - ICInvalidateRange((void*)(SWORD_UP_RED_ADDR), sizeof(uint32_t)); - *reinterpret_cast(SWORD_UP_GREEN_ADDR) = 0x60000000; // nop - DCFlushRange((void*)(SWORD_UP_GREEN_ADDR), sizeof(uint32_t)); - ICInvalidateRange((void*)(SWORD_UP_GREEN_ADDR), sizeof(uint32_t)); - *reinterpret_cast(SWORD_UP_BLUE_ADDR) = 0x60000000; // nop - DCFlushRange((void*)(SWORD_UP_BLUE_ADDR), sizeof(uint32_t)); - ICInvalidateRange((void*)(SWORD_UP_BLUE_ADDR), sizeof(uint32_t)); -#endif // WII_PLATFORM -} \ No newline at end of file +void GZ_setTunicColor(); \ No newline at end of file diff --git a/modules/boot/include/utils/memory.h b/modules/boot/include/utils/memory.h index 614401dc..4edc153a 100644 --- a/modules/boot/include/utils/memory.h +++ b/modules/boot/include/utils/memory.h @@ -1,4 +1,25 @@ +#pragma once +#include + #include "font.h" +#include "utils/containers/deque.h" + +enum MemoryType { MEM_TYPE_U8, MEM_TYPE_S8, MEM_TYPE_U16, MEM_TYPE_S16, MEM_TYPE_U32, MEM_TYPE_S32, MEM_TYPE_F32, MEM_TYPE_STR }; + +enum MemoryColumns { WatchAddress, WatchX, WatchY, WatchHex, WatchType, WatchOffset }; + +struct MemoryWatch { + uint32_t address = 0x80000000; + float x = 400.0f; + float y = 100.0f; + bool hex = false; + uint8_t type = MEM_TYPE_STR; + uint16_t offset = 0x0000; + uint32_t value; + bool visible = false; + bool line_selected = false; + bool value_selected = false; +}; void GZ_drawWatches(); void GZ_drawHeapInfo(); \ No newline at end of file diff --git a/modules/boot/include/utils/texture.h b/modules/boot/include/utils/texture.h index 0bdb22a5..1b99cb83 100644 --- a/modules/boot/include/utils/texture.h +++ b/modules/boot/include/utils/texture.h @@ -1,8 +1,7 @@ #pragma once #include -#include "libtp_c/include/addrs.h" -#include "gcn_c/include/gfx.h" +#include "libtp_c/include/dolphin/gx/gx.h" enum TexCode { TEX_OK = 1, /*<@brief Texture loaded successfully */ diff --git a/modules/boot/include/watches.h b/modules/boot/include/watches.h deleted file mode 100644 index 8c8c3717..00000000 --- a/modules/boot/include/watches.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include - -#define MAX_WATCHES 10 - -enum MemoryType { MEM_TYPE_U8, MEM_TYPE_S8, MEM_TYPE_U16, MEM_TYPE_S16, MEM_TYPE_U32, MEM_TYPE_S32, MEM_TYPE_F32, MEM_TYPE_STR }; - -enum MemoryColumns { WatchAddress, WatchX, WatchY, WatchHex, WatchType, WatchOffset }; - -struct MemoryWatch { - uint32_t address = 0x80000000; - float x = 400.0f; - float y = 100.0f; - bool hex = false; - uint8_t type = MEM_TYPE_STR; - uint16_t offset = 0x0000; - uint32_t value; - bool visible = false; - bool line_selected = false; - bool value_selected = false; -}; - -extern MemoryWatch g_watches[MAX_WATCHES]; diff --git a/modules/boot/src/GXDraw.cpp b/modules/boot/src/GXDraw.cpp new file mode 100644 index 00000000..0e4d3ad7 --- /dev/null +++ b/modules/boot/src/GXDraw.cpp @@ -0,0 +1,311 @@ +/** + * This is decompiled dolphin SDK code from dolsdk decomp (https://github.com/doldecomp/dolsdk2001) + * These functions were stripped from retail tp, so we have to manually add them + */ + +#include "libtp_c/include/dolphin/gx/gx.h" +#include "libtp_c/include/dolphin/os/OS.h" +#include "libtp_c/include/m_Do/m_Do_printf.h" +#include "libtp_c/include/msl_c/math.h" + +extern "C" { + +static GXVtxDescList vcd[27]; +static GXVtxAttrFmtList vat[27]; + +static void GetVertState(void) { + // TODO: these cause the game to crash lol + // geometry still seems to draw fine though? are these necessary? + //GXGetVtxDescv(vcd); + //GXGetVtxAttrFmtv(GX_VTXFMT3, vat); + + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_NRM, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0); +} + +static void RestoreVertState(void) { + GXSetVtxDescv(vcd); + GXSetVtxAttrFmtv(GX_VTXFMT3, vat); +} + +#define GET_REG_FIELD(reg, size, shift) ((int)((reg) >> (shift)) & ((1 << (size)) - 1)) + +KEEP_FUNC void GXGetVtxDesc(GXAttr attr, GXAttrType* type) { + u32 cpType; + + switch (attr) { + case GX_VA_PNMTXIDX: + cpType = GET_REG_FIELD(gx->vcdLo, 1, 0); + break; + case GX_VA_TEX0MTXIDX: + cpType = GET_REG_FIELD(gx->vcdLo, 1, 1); + break; + case GX_VA_TEX1MTXIDX: + cpType = GET_REG_FIELD(gx->vcdLo, 1, 2); + break; + case GX_VA_TEX2MTXIDX: + cpType = GET_REG_FIELD(gx->vcdLo, 1, 3); + break; + case GX_VA_TEX3MTXIDX: + cpType = GET_REG_FIELD(gx->vcdLo, 1, 4); + break; + case GX_VA_TEX4MTXIDX: + cpType = GET_REG_FIELD(gx->vcdLo, 1, 5); + break; + case GX_VA_TEX5MTXIDX: + cpType = GET_REG_FIELD(gx->vcdLo, 1, 6); + break; + case GX_VA_TEX6MTXIDX: + cpType = GET_REG_FIELD(gx->vcdLo, 1, 7); + break; + case GX_VA_TEX7MTXIDX: + cpType = GET_REG_FIELD(gx->vcdLo, 1, 8); + break; + case GX_VA_POS: + cpType = GET_REG_FIELD(gx->vcdLo, 2, 9); + break; + case GX_VA_NRM: + cpType = gx->hasNrms ? GET_REG_FIELD(gx->vcdLo, 2, 11) : 0; + break; + case GX_VA_NBT: + cpType = gx->hasBiNrms ? GET_REG_FIELD(gx->vcdLo, 2, 11) : 0; + break; + case GX_VA_CLR0: + cpType = GET_REG_FIELD(gx->vcdLo, 2, 13); + break; + case GX_VA_CLR1: + cpType = GET_REG_FIELD(gx->vcdLo, 2, 15); + break; + case GX_VA_TEX0: + cpType = GET_REG_FIELD(gx->vcdHi, 2, 0); + break; + case GX_VA_TEX1: + cpType = GET_REG_FIELD(gx->vcdHi, 2, 2); + break; + case GX_VA_TEX2: + cpType = GET_REG_FIELD(gx->vcdHi, 2, 4); + break; + case GX_VA_TEX3: + cpType = GET_REG_FIELD(gx->vcdHi, 2, 6); + break; + case GX_VA_TEX4: + cpType = GET_REG_FIELD(gx->vcdHi, 2, 8); + break; + case GX_VA_TEX5: + cpType = GET_REG_FIELD(gx->vcdHi, 2, 10); + break; + case GX_VA_TEX6: + cpType = GET_REG_FIELD(gx->vcdHi, 2, 12); + break; + case GX_VA_TEX7: + cpType = GET_REG_FIELD(gx->vcdHi, 2, 14); + break; + default: + cpType = 0; + break; + } + + // OSReport("GXGetVtxDesc ERROR: %d\n", error); + *type = (GXAttrType)cpType; +} + +void GXGetVtxDescv(GXVtxDescList* vcd) { + int attr; + + for (attr = 0; attr < GX_VA_MAX_ATTR; attr++) { + vcd[attr].attr = (GXAttr)attr; + GXGetVtxDesc((GXAttr)attr, &vcd[attr].type); + } + vcd[attr].attr = (GXAttr)0xFF; +} + +void GXGetVtxAttrFmt(GXVtxFmt fmt, GXAttr attr, GXCompCnt* cnt, GXCompType* type, u8* frac) { + u32* va; + u32* vb; + u32* vc; + + va = &gx->vatA[fmt]; + vb = &gx->vatB[fmt]; + vc = &gx->vatC[fmt]; + switch (attr) { + case GX_VA_POS: + *cnt = (GXCompCnt)GET_REG_FIELD(*va, 1, 0); + *type = (GXCompType)GET_REG_FIELD(*va, 3, 1); + *frac = (u8)(*va >> 4) & 0x1F; // GET_REG_FIELD(*va, 5, 4) + return; + case GX_VA_NRM: + case GX_VA_NBT: + *cnt = (GXCompCnt)GET_REG_FIELD(*va, 1, 9); + if (*cnt == GX_TEX_ST && (u8)(*va >> 0x1F) != 0) { + *cnt = GX_NRM_NBT3; + } + *type = (GXCompType)GET_REG_FIELD(*va, 3, 10); + *frac = 0; + return; + case GX_VA_CLR0: + *cnt = (GXCompCnt)GET_REG_FIELD(*va, 1, 13); + *type = (GXCompType)GET_REG_FIELD(*va, 3, 14); + *frac = 0; + return; + case GX_VA_CLR1: + *cnt = (GXCompCnt)GET_REG_FIELD(*va, 1, 17); + *type = (GXCompType)GET_REG_FIELD(*va, 3, 18); + *frac = 0; + return; + case GX_VA_TEX0: + *cnt = (GXCompCnt)GET_REG_FIELD(*va, 1, 21); + *type = (GXCompType)GET_REG_FIELD(*va, 3, 22); + *frac = (u8)(*va >> 0x19U) & 0x1F; + return; + case GX_VA_TEX1: + *cnt = (GXCompCnt)GET_REG_FIELD(*vb, 1, 0); + *type = (GXCompType)GET_REG_FIELD(*vb, 3, 1); + *frac = (u8)(*vb >> 4U) & 0x1F; + return; + case GX_VA_TEX2: + *cnt = (GXCompCnt)GET_REG_FIELD(*vb, 1, 9); + *type = (GXCompType)GET_REG_FIELD(*vb, 3, 10); + *frac = (u8)(*vb >> 0xDU) & 0x1F; + return; + case GX_VA_TEX3: + *cnt = (GXCompCnt)GET_REG_FIELD(*vb, 1, 18); + *type = (GXCompType)GET_REG_FIELD(*vb, 3, 19); + *frac = (u8)(*vb >> 0x16U) & 0x1F; + return; + case GX_VA_TEX4: + *cnt = (GXCompCnt)GET_REG_FIELD(*vb, 1, 27); + *type = (GXCompType)GET_REG_FIELD(*vb, 3, 28); + *frac = GET_REG_FIELD(*vc, 5, 0); + return; + case GX_VA_TEX5: + *cnt = (GXCompCnt)GET_REG_FIELD(*vc, 1, 5); + *type = (GXCompType)GET_REG_FIELD(*vc, 3, 6); + *frac = (u8)(*vc >> 9U) & 0x1F; + return; + case GX_VA_TEX6: + *cnt = (GXCompCnt)GET_REG_FIELD(*vc, 1, 14); + *type = (GXCompType)GET_REG_FIELD(*vc, 3, 15); + *frac = (u8)(*vc >> 0x12) & 0x1F; + return; + case GX_VA_TEX7: + *cnt = (GXCompCnt)GET_REG_FIELD(*vc, 1, 23); + *type = (GXCompType)GET_REG_FIELD(*vc, 3, 24); + *frac = (int)(*vc >> 0x1BU); + return; + default: + *cnt = GX_TEX_ST; + *type = GX_RGB565; + *frac = 0; + return; + } +} + +void GXGetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList* vat) { + int attr; + + for (attr = GX_VA_POS; attr < GX_VA_MAX_ATTR; attr++) { + vat->attr = (GXAttr)attr; + GXGetVtxAttrFmt(fmt, (GXAttr)attr, &vat->cnt, &vat->type, &vat->frac); + vat++; + } + vat->attr = GX_VA_NULL; +} + +void GXDrawSphere(u8 numMajor, u8 numMinor) { + GXAttrType ttype = GX_DIRECT; + f32 radius = 1.0f; + f32 majorStep = 3.1415927f / numMajor; + f32 minorStep = 6.2831855f / numMinor; + s32 i, j; + f32 a, b; + f32 r0, r1; + f32 z0, z1; + f32 c; + f32 x, y; + + //GXGetVtxDesc(GX_VA_TEX0, &ttype); + GetVertState(); + if (ttype != GX_NONE) { + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_TEX0, GX_TEX_ST, GX_RGBA6, 0U); + } + for (i = 0; i < numMajor; i++) { + a = i * majorStep; + b = a + majorStep; + r0 = radius * (float)sin(a); + r1 = radius * (float)sin(b); + z0 = radius * (float)cos(a); + z1 = radius * (float)cos(b); + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT3, (numMinor + 1) * 2); + for (j = 0; j <= numMinor; j++) { + c = j * minorStep; + x = (float)cos(c); + y = (float)sin(c); + GXPosition3f32(x * r1, y * r1, z1); + GXNormal3f32((x * r1) / radius, (y * r1) / radius, z1 / radius); + if (ttype != GX_NONE) { + GXTexCoord2f32((f32)j / (f32)numMinor, (f32)(i + 1) / (f32)numMajor); + } + GXPosition3f32(x * r0, y * r0, z0); + GXNormal3f32((x * r0) / radius, (y * r0) / radius, z0 / radius); + if (ttype != GX_NONE) { + GXTexCoord2f32((f32)j / (f32)numMinor, (f32)i / (f32)numMajor); + } + } + GXEnd(); + } + RestoreVertState(); +} + +void GXDrawCylinder(u8 numEdges) { + s32 i; + f32 top; + f32 bottom; + f32 x[100]; + f32 y[100]; + f32 angle; + + top = 1.0f; + bottom = -top; + + GetVertState(); + + for (i = 0; i <= numEdges; i++) { + angle = (3.1415927f * (2.0f * i)) / numEdges; + x[i] = (float)cos(angle); + y[i] = (float)sin(angle); + } + + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT3, (numEdges + 1) * 2); + for (i = 0; i <= numEdges; i++) { + GXPosition3f32(x[i], y[i], bottom); + GXNormal3f32(x[i], y[i], 0.0f); + GXPosition3f32(x[i], y[i], top); + GXNormal3f32(x[i], y[i], 0.0f); + } + GXEnd(); + + GXBegin(GX_TRIANGLEFAN, GX_VTXFMT3, numEdges + 2); + GXPosition3f32(0.0f, 0.0f, top); + GXNormal3f32(0.0f, 0.0f, 1.0f); + for (i = 0; i <= numEdges; i++) { + GXPosition3f32(x[i], -y[i], top); + GXNormal3f32(0.0f, 0.0f, 1.0f); + } + GXEnd(); + + GXBegin(GX_TRIANGLEFAN, GX_VTXFMT3, numEdges + 2); + GXPosition3f32(0.0f, 0.0f, bottom); + GXNormal3f32(0.0f, 0.0f, -1.0f); + for (i = 0; i <= numEdges; i++) { + GXPosition3f32(x[i], y[i], bottom); + GXNormal3f32(0.0f, 0.0f, -1.0f); + } + GXEnd(); + + RestoreVertState(); +} +} \ No newline at end of file diff --git a/modules/boot/src/cheats.cpp b/modules/boot/src/cheats.cpp index 7dc149f2..f82c356d 100644 --- a/modules/boot/src/cheats.cpp +++ b/modules/boot/src/cheats.cpp @@ -5,6 +5,7 @@ #include "libtp_c/include/d/d_procname.h" #include "libtp_c/include/d/a/d_a_e_zs.h" #include "libtp_c/include/d/a/d_a_e_s1.h" +#include "libtp_c/include/d/d_item.h" #include "rels/include/patch.h" #include "libtp_c/include/defines.h" #include "gz_flags.h" @@ -25,27 +26,10 @@ extern "C" { void* cc_at_check(void*, void*); } -Cheat g_cheats[CHEAT_AMNT] = { - {InfiniteAir, false}, {InfiniteArrows, false}, {InfiniteBombs, false}, - {InfiniteHearts, false}, {InfiniteOil, false}, {InfiniteRupees, false}, - {InfiniteSlingshot, false}, {Invincible, false}, {InvincibleEnemies, false}, - {MoonJump, false}, {DoorStorage, false}, {SuperClawshot, false}, - {UnrestrictedItems, false}, {TransformAnywhere, false}, -#ifdef WII_PLATFORM - {GaleLJA, false}, -#endif -}; - bool l_doorCollision; void GZ_applyCheats() { - if (GZ_checkCheat(MoonJump)) { - GZCmd_enable(CMD_MOON_JUMP); - } else { - GZCmd_disable(CMD_MOON_JUMP); - } - - if (GZ_checkCheat(InvincibleEnemies)) { + if (GZ_checkCheat(STNG_CHEATS_INVINCIBLE_ENEMIES)) { /* Patch cc_at_check instruction to nop out health subtraction */ *reinterpret_cast((uint32_t)(&cc_at_check) + INVINCIBLE_ENEMIES_OFFSET) = 0x60000000; // nop @@ -60,7 +44,7 @@ void GZ_applyCheats() { if (node != NULL) { create_tag_class* tag = (create_tag_class*)node; fopEn_enemy_c* actor = (fopEn_enemy_c*)tag->mpTagData; - + if (actor != NULL) { switch (fopAcM_GetName(actor)) { case PROC_E_ZS: { @@ -68,12 +52,12 @@ void GZ_applyCheats() { // if action is damage action if (zs->mAction == 2) { - zs->mAction = 1; // set back to wait action, mode 0 + zs->mAction = 1; // set back to wait action, mode 0 zs->mMode = 0; zs->mCyl.mGObjInf.OnTgSetBit(); // turn back on hit collision zs->mCyl.mGObjInf.OnCoSetBit(); // turn back on push collision - zs->mHealth = 20; // reset health back to max + zs->mHealth = 20; // reset health back to max } break; } @@ -101,44 +85,53 @@ void GZ_applyCheats() { sizeof(uint32_t)); } - if (GZ_checkCheat(Invincible)) { - if (dComIfGp_getPlayer()) { - dComIfGp_getPlayer()->mDamageTimer = 5; + if (GZ_checkCheat(STNG_CHEATS_INVINCIBLE)) { + daAlink_c* player = dComIfGp_getPlayer(); + if (player != NULL) { + for (int i = 0; i < 3; i++) { + player->field_0x850[i].mGObjInf.OffTgSetBit(); + player->field_0x850[i].mGObjInf.ResetTgHit(); + } + + if (player->checkWolf()) { + player->field_0xFB8.mGObjInf.OffTgSetBit(); + player->field_0xFB8.mGObjInf.ResetTgHit(); + } } } - if (GZ_checkCheat(InfiniteHearts)) { + if (GZ_checkCheat(STNG_CHEATS_INFINITE_HEARTS)) { uint16_t max_life = dComIfGs_getMaxLife(); dComIfGs_setLife((max_life / 5) * 4); } - if (GZ_checkCheat(InfiniteAir)) { + if (GZ_checkCheat(STNG_CHEATS_INFINITE_AIR)) { dComIfGs_setOxygen(600); } - if (GZ_checkCheat(InfiniteOil)) { + if (GZ_checkCheat(STNG_CHEATS_INFINITE_OIL)) { dComIfGs_setOil(21600); } - if (GZ_checkCheat(InfiniteBombs)) { + if (GZ_checkCheat(STNG_CHEATS_INFINITE_BOMBS)) { dComIfGs_setBombNum(BOMB_BAG_1, 99); dComIfGs_setBombNum(BOMB_BAG_2, 99); dComIfGs_setBombNum(BOMB_BAG_3, 99); } - if (GZ_checkCheat(InfiniteRupees)) { + if (GZ_checkCheat(STNG_CHEATS_INFINITE_RUPEES)) { dComIfGs_setRupee(1000); } - if (GZ_checkCheat(InfiniteArrows)) { + if (GZ_checkCheat(STNG_CHEATS_INFINITE_ARROWS)) { dComIfGs_setArrowNum(99); } - if (GZ_checkCheat(InfiniteSlingshot)) { + if (GZ_checkCheat(STNG_CHEATS_INFINITE_SLINGSHOT)) { dComIfGs_setPachinkoNum(99); } - if (GZ_checkCheat(SuperClawshot)) { + if (GZ_checkCheat(STNG_CHEATS_SUPER_CLAWSHOT)) { daAlinkHIO_hookshot.mShootSpeed = 2870.0f; daAlinkHIO_hookshot.mMaxLength = 69420.0f; daAlinkHIO_hookshot.mReturnSpeed = 2870.0f; @@ -150,7 +143,7 @@ void GZ_applyCheats() { daAlinkHIO_hookshot.mClawReturnSpeed = 60.0f; } - if (GZ_checkCheat(DoorStorage)) { + if (GZ_checkCheat(STNG_CHEATS_DOOR_STORAGE)) { if (dComIfGp_getPlayer()) { dComIfGp_getPlayer()->mLinkAcch.SetWallNone(); dComIfGp_getPlayer()->mLinkAcch.OnLineCheckNone(); @@ -158,14 +151,20 @@ void GZ_applyCheats() { } } else { if (dComIfGp_getPlayer() && l_doorCollision) { - dComIfGp_getPlayer()->mLinkAcch.OffWallNone(); + dComIfGp_getPlayer()->mLinkAcch.ClrWallNone(); dComIfGp_getPlayer()->mLinkAcch.OffLineCheckNone(); l_doorCollision = false; } } + if (GZ_checkCheat(STNG_CHEATS_DISABLE_ITEM_TIMER)) { + daItemBase__data.field_0x16 = 0x7FFF; + } else { + daItemBase__data.field_0x16 = 240; + } + #ifdef WII_PLATFORM - if (GZ_checkCheat(GaleLJA)) { + if (GZ_checkCheat(STNG_CHEATS_GALE_LJA)) { if (dComIfGp_getPlayer() && dComIfGp_getPlayer()->mActionID == 0x60 && dComIfGp_getPlayer()->mEquipItem == NO_ITEM) { dComIfGp_getPlayer()->mEquipItem = 0x0103; diff --git a/modules/boot/src/commands.cpp b/modules/boot/src/commands.cpp index f6052119..d9fd1cc4 100644 --- a/modules/boot/src/commands.cpp +++ b/modules/boot/src/commands.cpp @@ -1,13 +1,13 @@ #include "commands.h" + +#include + #include "controller.h" #include "global_data.h" #include "fs.h" -#include "gorge.h" -#ifdef WII_PLATFORM -#include "bit.h" -#endif #include "boot.h" #include "libtp_c/include/JSystem/JUtility/JUTGamePad.h" +#include "libtp_c/include/utils.h" #include "practice.h" #include "settings.h" #include "libtp_c/include/d/com/d_com_inf_game.h" @@ -21,8 +21,6 @@ bool reload_area_flag = false; bool g_timerEnabled = false; bool g_resetTimer = false; -bool g_commandStates[COMMANDS_AMNT]; - static Vec sSavePlayerPos = {0.0f, 0.0f, 0.0f}; static int16_t sSavePlayerAngle = 0; static Vec sSaveCamPos = {0.0f, 0.0f, 0.0f}; @@ -31,20 +29,20 @@ static Vec sSaveCamTarget = {0.0f, 0.0f, 0.0f}; static int sLastInputs; static int sCurInputs; -bool GZCmd_checkTrig(int combo) { +KEEP_FUNC bool GZCmd_checkTrig(int combo) { if (sCurInputs == combo && sLastInputs != combo) { return true; } return false; } -void GZCmd_pauseFrame() { - if (GZCmd_checkTrig(FRAME_PAUSE_BUTTONS)) { +KEEP_FUNC void GZCmd_pauseFrame() { + if (GZCmd_checkTrig(GZStng_getData(STNG_CMD_FRAME_PAUSE, FRAME_PAUSE_BUTTONS))) { g_framePaused = !g_framePaused; } } -void GZCmd_storePosition() { +KEEP_FUNC void GZCmd_storePosition() { if (dComIfGp_getPlayer()) { sSavePlayerPos = dComIfGp_getPlayer()->current.pos; sSavePlayerAngle = dComIfGp_getPlayer()->shape_angle.y; @@ -56,7 +54,7 @@ void GZCmd_storePosition() { } } -void GZCmd_loadPosition() { +KEEP_FUNC void GZCmd_loadPosition() { if (dComIfGp_getPlayer()) { dComIfGp_getPlayer()->current.pos = sSavePlayerPos; dComIfGp_getPlayer()->shape_angle.y = sSavePlayerAngle; @@ -68,27 +66,21 @@ void GZCmd_loadPosition() { } } -void GZCmd_moonJump() { - if (dComIfGp_getPlayer()) { - dComIfGp_getPlayer()->speed.y = 56.0f; - } -} - -void GZCmd_toggleTimer() { - if (GZCmd_checkTrig(TIMER_TOGGLE_BUTTONS)) { +KEEP_FUNC void GZCmd_toggleTimer() { + if (GZCmd_checkTrig(GZStng_getData(STNG_CMD_TIMER_TOGGLE, TIMER_TOGGLE_BUTTONS))) { g_timerEnabled = !g_timerEnabled; } } -void GZCmd_resetTimer() { +KEEP_FUNC void GZCmd_resetTimer() { g_resetTimer = true; } -void GZCmd_reloadArea() { - g_dComIfG_gameInfo.play.mNextStage.enabled = true; - SaveManager::s_injectSave = true; +KEEP_FUNC void GZCmd_reloadArea() { + uint32_t reloadType = GZStng_getData(STNG_AREA_RELOAD_BEHAVIOUR, LOAD_AREA); + if (reloadType == LOAD_AREA) { + g_dComIfG_gameInfo.play.mNextStage.enabled = true; - if (g_reloadType == LOAD_AREA) { // restore last set of saved temp flags memcpy(&g_dComIfG_gameInfo.info.mMemory, gSaveManager.mAreaReloadOpts.temp_flags, sizeof(gSaveManager.mAreaReloadOpts.temp_flags)); @@ -103,67 +95,57 @@ void GZCmd_reloadArea() { gSaveManager.mPracticeFileOpts.inject_options_during_load = nullptr; gSaveManager.mPracticeFileOpts.inject_options_after_load = nullptr; } else { - SaveManager::loadSave(last_save_index, last_category, last_special_ptr, 0xFF); + if (last_save_index != -1) { + SaveManager::triggerLoad(last_save_index, last_category, &last_special, 1); + } } } -void GZCmd_loadGorgeVoid() { - if (GZCmd_checkTrig(GORGE_VOID_BUTTONS)) { - // TODO: maybe simplify this - special sp[] = { - special(8, GorgeVoidIndicator::warpToPosition, GorgeVoidIndicator::initState), - }; +KEEP_FUNC void GZCmd_toggleFreeCam() { + if (GZCmd_checkTrig(GZStng_getData(STNG_CMD_FREE_CAM, FREE_CAM_BUTTONS))) { + g_freeCamEnabled = !g_freeCamEnabled; + } +} - SaveManager::triggerLoad(8, "any", sp, 1); +KEEP_FUNC void GZCmd_toggleMoveLink() { + if (GZCmd_checkTrig(GZStng_getData(STNG_CMD_MOVE_LINK, MOVE_LINK_BUTTONS))) { + g_moveLinkEnabled = !g_moveLinkEnabled; } } -#ifdef WII_PLATFORM -void GZCmd_bitPractice() { - if (GZCmd_checkTrig(BACK_IN_TIME_BUTTONS)) { - // TODO: maybe simplify this - special sp[] = { - special(0, nullptr, BiTIndicator::setPosition), - }; +KEEP_VAR tpgz::containers::deque g_commands; - SaveManager::triggerLoad(0, "any", sp, 1); - } +KEEP_FUNC void GZCmd_addCmd(Command* cmd) { + g_commands.push_back(cmd); } -#endif -void GZCmd_toggleFreeCam() { - if (GZCmd_checkTrig(FREE_CAM_BUTTONS)) { - g_freeCamEnabled = !g_freeCamEnabled; +KEEP_FUNC Command* GZCmd_removeCmd(Commands cmdId) { + auto it = g_commands.begin(); + for (; it != g_commands.end(); ++it) { + if ((*it)->id == cmdId) { + break; + } } + auto* cmd = *it; + g_commands.erase(it); + return cmd; } -void GZCmd_toggleMoveLink() { - if (GZCmd_checkTrig(MOVE_LINK_BUTTONS)) { - g_moveLinkEnabled = !g_moveLinkEnabled; +KEEP_FUNC Command* GZCmd_getCmd(int id) { + auto it = g_commands.begin(); + for (; it != g_commands.end(); ++it) { + if ((*it)->id == id) { + return *it; + } } + return nullptr; } -static Command sCommands[COMMANDS_AMNT] = { - {g_commandStates[CMD_STORE_POSITION], STORE_POSITION_BUTTONS, GZCmd_storePosition}, - {g_commandStates[CMD_LOAD_POSITION], LOAD_POSITION_BUTTONS, GZCmd_loadPosition}, - {g_commandStates[CMD_MOON_JUMP], MOON_JUMP_BUTTONS, GZCmd_moonJump}, - {g_commandStates[CMD_RELOAD_AREA], RELOAD_AREA_BUTTONS, GZCmd_reloadArea}, - {g_commandStates[CMD_TIMER_TOGGLE], TIMER_TOGGLE_BUTTONS, GZCmd_toggleTimer}, - {g_commandStates[CMD_TIMER_RESET], TIMER_RESET_BUTTONS, GZCmd_resetTimer}, - {g_commandStates[CMD_GORGE_VOID], GORGE_VOID_BUTTONS, GZCmd_loadGorgeVoid}, -#ifdef WII_PLATFORM - {g_commandStates[CMD_BIT], BACK_IN_TIME_BUTTONS, GZCmd_bitPractice}, -#endif - {g_commandStates[CMD_FREE_CAM], FREE_CAM_BUTTONS, GZCmd_toggleFreeCam}, - {g_commandStates[CMD_MOVE_LINK], MOVE_LINK_BUTTONS, GZCmd_toggleMoveLink}, - {g_commandStates[CMD_FRAME_PAUSE], FRAME_PAUSE_BUTTONS, GZCmd_pauseFrame}, -}; - -void GZCmd_processInputs() { +KEEP_FUNC void GZCmd_processInputs() { sCurInputs = GZ_getButtonStatus(); - for (auto c : sCommands) { - if (c.active && GZ_getButtonStatus() == c.buttons) { - c.command(); + for (auto c : g_commands) { + if (sCurInputs == c->buttons) { + c->command(); setGamepadButtons(0x0); setGamepadTrig(0x0); mPadButton.mRepeat = 0x0; @@ -173,10 +155,45 @@ void GZCmd_processInputs() { sLastInputs = sCurInputs; } -void GZCmd_enable(int idx) { - sCommands[idx].active = true; +#ifdef WII_PLATFORM +char l_buttonMapping[16][11] = { + {"DPad Left"}, {"DPad Right"}, {"DPad Down"}, {"DPad Up"}, {"Plus"}, {""}, {""}, {""}, + {"2"}, {"1"}, {"B"}, {"A"}, {"Minus"}, {"Z"}, {"C"}, {"Home"}}; +#else +char l_buttonMapping[16][11] = { + {"DPad Left"}, {"DPad Right"}, {"DPad Down"}, {"DPad Up"}, {"Z"}, {"R"}, {"L"}, {""}, + {"A"}, {"B"}, {"X"}, {"Y"}, {"Start"}, {""}, {""}, {""}}; +#endif + +KEEP_FUNC size_t GZCmd_getComboLen(uint16_t combo) { + size_t len = 0; + for (uint32_t i = 0; i < 16; ++i) { + if (combo & (1 << i)) { + len += strlen(l_buttonMapping[i]) + 1; + } + } + if (popcount(combo) > 1) { + len -= 1; + } + return len; } -void GZCmd_disable(int idx) { - sCommands[idx].active = false; +/** + * @brief Converts a combo to a string + * @param combo The combo to convert + * @param str The string to write to. Must be preallocated to at least GZCmd_getComboLen(combo) + 1 + * bytes long. + */ +KEEP_FUNC void GZCmd_comboToStr(uint16_t combo, char* str) { + uint8_t count = popcount(combo); + str[0] = '\0'; + uint8_t accumulator = 0; + for (uint32_t i = 0; i < 16; ++i) { + if (combo & (1 << i)) { + strcat(str, l_buttonMapping[i]); + if (++accumulator < count) { + strcat(str, "+"); + } + } + } } \ No newline at end of file diff --git a/modules/boot/src/controller.cpp b/modules/boot/src/controller.cpp index 146e2f3e..586ffe71 100644 --- a/modules/boot/src/controller.cpp +++ b/modules/boot/src/controller.cpp @@ -4,10 +4,12 @@ #include "gz_flags.h" #include "controller.h" #include "libtp_c/include/SSystem/SComponent/c_counter.h" -#include "menu.h" +#include "menus/menu.h" #include "libtp_c/include/m_Do/m_Re_controller_pad.h" #include "rels/include/defines.h" #include "menus/utils/menu_mgr.h" +#include "libtp_c/include/m_Do/m_Do_printf.h" +#include "utils/containers/deque.h" #ifdef GCN_PLATFORM #define BUTTON_STATES 12 @@ -85,8 +87,10 @@ KEEP_FUNC void GZ_readController() { if (!g_cursorEnabled) { if (current_input & CButton::DPAD_UP) { g_cursorEnabled = true; +#ifdef GCN_PLATFORM } else if (current_input & (CButton::L | CButton::R)) { sCursorEnableDelay = 0; +#endif } else if (sCursorEnableDelay < 1) { sCursorEnableDelay = 1; } @@ -119,28 +123,36 @@ KEEP_FUNC void GZ_readController() { } } -bool GZ_getButtonPressed(int idx) { +KEEP_FUNC bool GZ_getButtonPressed(int idx) { return buttonStates[idx].is_down; } -bool GZ_getButtonRepeat(int idx, uint16_t repeat_time) { - auto delta = cCt_getFrameCount() - buttonStates[idx].pressed_frame; +KEEP_FUNC bool GZ_getButtonRepeat(int idx, uint16_t repeat_time) { + // Needs to be signed due to delta sometimes being negative + // which causes a subtle bug making held_down_long_enough + // true when it shouldn't be + s32 delta = cCt_getFrameCount() - buttonStates[idx].pressed_frame; + auto just_clicked = delta == 0; auto held_down_long_enough = delta > REPEAT_DELAY; - auto is_repeat_frame = held_down_long_enough && delta % repeat_time == 0; + auto is_repeat_frame = held_down_long_enough && (delta % repeat_time == 0); auto down = GZ_getButtonPressed(idx); return down && (just_clicked || is_repeat_frame); } -bool GZ_getButtonRepeat(int idx) { +KEEP_FUNC bool GZ_getButtonRepeat(int idx) { return GZ_getButtonRepeat(idx, REPEAT_TIME); } -uint16_t GZ_getButtonStatus() { +KEEP_FUNC uint16_t GZ_getButtonStatus() { return buttonStatus; } -bool GZ_getButtonTrig(int idx) { +KEEP_FUNC uint16_t GZ_getButtonStatusSaved() { + return sButtons; +} + +KEEP_FUNC bool GZ_getButtonTrig(int idx) { auto delta = cCt_getFrameCount() - buttonStates[idx].pressed_frame; auto just_clicked = delta == 0; @@ -148,17 +160,28 @@ bool GZ_getButtonTrig(int idx) { return down && just_clicked; } -bool GZ_getButtonHold(int idx, int phase) { - uint32_t delta; - if (phase == POST_GAME_LOOP) { - delta = cCt_getFrameCount() - buttonStates[idx].pressed_frame; - } else { - delta = cCt_getFrameCount() - buttonStates[idx].pressed_frame + 1; +KEEP_FUNC bool GZ_getButtonHold(int idx, int phase) { + uint32_t delta = cCt_getFrameCount() - buttonStates[idx].pressed_frame; + + if (phase != POST_GAME_LOOP) + delta++; + + return delta != 0 ? true : false; +} + +KEEP_FUNC void GZ_getButtonPressCount(u8& i_pressCounter, int i_button, int i_gzButton) { + if ((GZ_getButtonStatus() & i_button) && (buttonStates[i_gzButton].button & sButtonsPressed)) { + i_pressCounter++; } +} - if (delta != 0) { - return true; - } else { - return false; +KEEP_FUNC bool GZ_getPadTrigAny(uint16_t pad) { + for (uint8_t idx = 0; idx < BUTTON_STATES; idx++) { + if (pad & buttonStates[idx].button) { + if (GZ_getButtonTrig(idx) && (sButtons & pad) == pad) { + return true; + } + } } -} \ No newline at end of file + return false; +} diff --git a/modules/boot/src/fifo_queue.cpp b/modules/boot/src/fifo_queue.cpp index 2022c856..c2b0657e 100644 --- a/modules/boot/src/fifo_queue.cpp +++ b/modules/boot/src/fifo_queue.cpp @@ -1,5 +1,6 @@ #include "fifo_queue.h" #include "font.h" +#include "settings.h" #include "pos_settings.h" #include "rels/include/defines.h" @@ -19,8 +20,9 @@ void FIFOQueue::renderItems(_FIFOQueue& Queue) { } color |= alpha; if (g_fifoVisible) { - Font::renderChars(Queue.messages[i].msg, (g_spriteOffsets[FIFO_SPR_INDEX].x), - offset + (g_spriteOffsets[FIFO_SPR_INDEX].y), color); + Vec2 spriteOffset = GZ_getSpriteOffset(STNG_SPRITES_FIFO_SPR); + Font::renderChars(Queue.messages[i].msg, spriteOffset.x, offset + spriteOffset.y, + color); } } }; diff --git a/modules/boot/src/font.cpp b/modules/boot/src/font.cpp index fbc9045e..9f07a167 100644 --- a/modules/boot/src/font.cpp +++ b/modules/boot/src/font.cpp @@ -145,6 +145,22 @@ KEEP_FUNC float Font::getCharWidth(char c, float size) { } } +KEEP_FUNC float Font::getMaxCharRangeWidth(char start, char end, float size) { + float max_width = 0.f; + for (char c = start; c <= end; c++) { + max_width = MAX(max_width, getCharWidth(c, size)); + } + return max_width; +} + +KEEP_FUNC float Font::getMaxCharWidth(float size) { + float max_width = font.glyphs[' '].width; + for (size_t idx = 0; idx < font.header.glyph_count; ++idx) { + max_width = MAX(max_width, font.glyphs[idx].width); + } + return max_width * size / font.header.base_size * (isWidescreen ? 0.75f : 1.0f); +} + KEEP_FUNC float Font::getStrWidth(const char* str, float size) { int len = strlen(str); float str_size = 0.f; diff --git a/modules/boot/src/geometry_draw.cpp b/modules/boot/src/geometry_draw.cpp new file mode 100644 index 00000000..603d1b69 --- /dev/null +++ b/modules/boot/src/geometry_draw.cpp @@ -0,0 +1,856 @@ +#include "collision_view.h" +#include "global_data.h" +#include "libtp_c/include/d/com/d_com_inf_game.h" +#include "libtp_c/include/dolphin/gx/gx.h" +#include "libtp_c/include/JSystem/J3DGraphBase/J3DSys.h" +#include "libtp_c/include/m_Do/m_Do_printf.h" +#include "libtp_c/include/d/bg/d_bg_s_captpoly.h" +#include "libtp_c/include/msl_c/math.h" +#include "libtp_c/include/f_op/f_op_draw_tag.h" + +#include +//#include +#include "font.h" + +KEEP_VAR CollisionItem g_collisionFlags[VIEW_COLLISION_MAX] = { + {VIEW_POLYGON_GROUND, false}, + {VIEW_POLYGON_WALL, false}, + {VIEW_POLYGON_ROOF, false}, + {VIEW_POLYGON_EDGES, false}, + {VIEW_AT_CC, false}, + {VIEW_TG_CC, false}, + {VIEW_CO_CC, false}, +}; + +#define DRAW_PACKET_MAX 1000 // max amount of draw packets allowed to be drawn at a time + +u32 l_drawPacketListNum; +static J3DPacket* l_drawPacketList[DRAW_PACKET_MAX]; + +J3DPacket* dDbVw_setDrawPacketList(J3DPacket* p_packet, int buf_type) { + if (p_packet == NULL) { + p_packet = NULL; + } else { + if (l_drawPacketListNum >= DRAW_PACKET_MAX) { + delete p_packet; + p_packet = NULL; + } else { + l_drawPacketList[l_drawPacketListNum] = p_packet; + l_drawPacketListNum++; + J3DDrawBuffer__entryImm(j3dSys.getDrawBuffer(buf_type), p_packet, 0); + } + } + return p_packet; +} + +void dDbVw_deleteDrawPacketList() { + for (u32 i = 0; i < l_drawPacketListNum; i++) { + if (l_drawPacketList[i] != NULL) { + delete l_drawPacketList[i]; + l_drawPacketList[i] = NULL; + } + } + + l_drawPacketListNum = 0; +} + +//------------------------------------------------------- +// CUBE +//------------------------------------------------------- + +void drawCube(MtxP mtx, cXyz* array, const GXColor& color) { + GXSetArray(GX_VA_POS, array, sizeof(cXyz)); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetTevColor(GX_TEVREG0, color); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); + GXSetCullMode(GX_CULL_BACK); + GXSetClipMode(GX_CLIP_ENABLE); + GXLoadPosMtxImm(mtx, 0); + GXSetCurrentMtx(0); + + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, 14); + GXPosition1x8(4); + GXPosition1x8(6); + GXPosition1x8(5); + GXPosition1x8(7); + GXPosition1x8(3); + GXPosition1x8(6); + GXPosition1x8(2); + GXPosition1x8(4); + GXPosition1x8(0); + GXPosition1x8(5); + GXPosition1x8(1); + GXPosition1x8(3); + GXPosition1x8(0); + GXPosition1x8(2); + GXEnd(); +} + +static J3DPacket__vtable_t mDoExt_cubePacket__vtable { + (void*)nullptr, // RTTI + (void*)nullptr, // pad + (void*)&J3DPacket__entry, + (void*)&mDoExt_cubePacket__draw, + (void*)&mDoExt_cubePacket__dtor, +}; + +KEEP_FUNC void dDbVw_drawCubeXlu(cXyz& pos, cXyz& size, csXyz& angle, const GXColor& color) { + if (l_drawPacketListNum < DRAW_PACKET_MAX) { + mDoExt_cubePacket* cube = new mDoExt_cubePacket(pos, size, angle, color); + cube->base.vtable = &mDoExt_cubePacket__vtable; + + dDbVw_setDrawPacketList(&cube->base, 1); + } +} + +void mDoExt_cubePacket__dtor(mDoExt_cubePacket* i_this) { + i_this->~mDoExt_cubePacket(); + delete i_this; +} + +void mDoExt_cubePacket__draw(mDoExt_cubePacket* i_this) { + static Vec points[8] = { + {-1.0f, 1.0f, -1.0f}, + {1.0f, 1.0f, -1.0f}, + {-1.0f, 1.0f, 1.0f}, + {1.0f, 1.0f, 1.0f}, + {-1.0f, -1.0f, -1.0f}, + {1.0f, -1.0f, -1.0f}, + {-1.0f, -1.0f, 1.0f}, + {1.0f, -1.0f, 1.0f}, + }; + + mDoMtx_stack_c::transS(i_this->mPosition.x, i_this-> mPosition.y, i_this->mPosition.z); + mDoMtx_stack_c::XYZrotM(i_this->mAngle.x, i_this->mAngle.y, i_this->mAngle.z); + mDoMtx_stack_c::scaleM(i_this->mSize.x, i_this->mSize.y, i_this->mSize.z); + mDoMtx_stack_c::revConcat(j3dSys.getViewMtx()); + drawCube(mDoMtx_stack_c::get(), (cXyz*)points, i_this->mColor); +} + +//------------------------------------------------------- +// SPHERE +//------------------------------------------------------- + +static J3DPacket__vtable_t mDoExt_spherePacket__vtable { + (void*)nullptr, // RTTI + (void*)nullptr, // pad + (void*)&J3DPacket__entry, + (void*)&mDoExt_spherePacket__draw, + (void*)&mDoExt_spherePacket__dtor, +}; + +KEEP_FUNC void dDbVw_drawSphereXlu(cXyz& position, f32 radius, const GXColor& color, u8 param_3) { + if (l_drawPacketListNum < DRAW_PACKET_MAX) { + mDoExt_spherePacket* sph = new mDoExt_spherePacket(position, radius, color, param_3); + sph->base.vtable = &mDoExt_spherePacket__vtable; + + dDbVw_setDrawPacketList(&sph->base, 1); + } +} + +void mDoExt_spherePacket__dtor(mDoExt_spherePacket* i_this) { + i_this->~mDoExt_spherePacket(); + delete i_this; +} + +void mDoExt_spherePacket__draw(mDoExt_spherePacket* i_this) { + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT0, GX_DF_CLAMP, GX_AF_NONE); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetTevColor(GX_TEVREG0, i_this->mColor); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + + if (i_this->_24) { + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + } else { + GXSetZMode(GX_DISABLE, GX_LEQUAL, GX_DISABLE); + } + + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); + GXSetCullMode(GX_CULL_BACK); + GXSetClipMode(GX_CLIP_ENABLE); + + mDoMtx_stack_c::copy(j3dSys.getViewMtx()); + mDoMtx_stack_c::transM(i_this->mPosition.x, i_this->mPosition.y, i_this->mPosition.z); + mDoMtx_stack_c::scaleM(i_this->mSize, i_this->mSize, i_this->mSize); + + GXLoadPosMtxImm(mDoMtx_stack_c::get(), 0); + mDoMtx_stack_c::inverseTranspose(); + + GXLoadNrmMtxImm(mDoMtx_stack_c::get(), 0); + GXSetCurrentMtx(0); + + GXDrawSphere(8, 8); +} + +//------------------------------------------------------- +// CYLINDER +//------------------------------------------------------- + +static J3DPacket__vtable_t mDoExt_cylinderPacket__vtable { + (void*)nullptr, // RTTI + (void*)nullptr, // pad + (void*)&J3DPacket__entry, + (void*)&mDoExt_cylinderPacket__draw, + (void*)&mDoExt_cylinderPacket__dtor, +}; + +KEEP_FUNC void dDbVw_drawCylinderXlu(cXyz& position, f32 radius, f32 height, const GXColor& color, u8 param_4) { + if (l_drawPacketListNum < DRAW_PACKET_MAX) { + mDoExt_cylinderPacket* cyl = new mDoExt_cylinderPacket(position, radius, height, color, param_4); + cyl->base.vtable = &mDoExt_cylinderPacket__vtable; + + dDbVw_setDrawPacketList(&cyl->base, 1); + } +} + +void mDoExt_cylinderPacket__dtor(mDoExt_cylinderPacket* i_this) { + i_this->~mDoExt_cylinderPacket(); + delete i_this; +} + +void mDoExt_cylinderPacket__draw(mDoExt_cylinderPacket* i_this) { + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT0, GX_DF_CLAMP, GX_AF_NONE); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetTevColor(GX_TEVREG0, i_this->mColor); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + + if (i_this->_28) { + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + } else { + GXSetZMode(GX_DISABLE, GX_LEQUAL, GX_DISABLE); + } + + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); + GXSetCullMode(GX_CULL_BACK); + GXSetClipMode(GX_CLIP_ENABLE); + + f32 height = i_this->mHeight; + + mDoMtx_stack_c::copy(j3dSys.getViewMtx()); + mDoMtx_stack_c::transM(i_this->mPosition.x, i_this->mPosition.y + (height / 2), i_this->mPosition.z); + mDoMtx_stack_c::scaleM(i_this->mRadius, i_this->mRadius + (height / 2), i_this->mRadius); + mDoMtx_stack_c::XrotM(0x4000); + + GXLoadPosMtxImm(mDoMtx_stack_c::get(), 0); + mDoMtx_stack_c::inverseTranspose(); + + GXLoadNrmMtxImm(mDoMtx_stack_c::get(), 0); + GXSetCurrentMtx(0); + + GXDrawCylinder(8); +} + +//------------------------------------------------------- +// 8 Point Cube +//------------------------------------------------------- + +static J3DPacket__vtable_t mDoExt_cube8pPacket__vtable { + (void*)nullptr, // RTTI + (void*)nullptr, // pad + (void*)&J3DPacket__entry, + (void*)&mDoExt_cube8pPacket__draw, + (void*)&mDoExt_cube8pPacket__dtor, +}; + +KEEP_FUNC void dDbVw_drawCube8pXlu(cXyz* points, const GXColor& color) { + if (l_drawPacketListNum < DRAW_PACKET_MAX) { + mDoExt_cube8pPacket* cube = new mDoExt_cube8pPacket(points, color); + cube->base.vtable = &mDoExt_cube8pPacket__vtable; + + dDbVw_setDrawPacketList(&cube->base, 1); + } +} + +void mDoExt_cube8pPacket__dtor(mDoExt_cube8pPacket* i_this) { + i_this->~mDoExt_cube8pPacket(); + delete i_this; +} + +void mDoExt_cube8pPacket__draw(mDoExt_cube8pPacket* i_this) { + drawCube(j3dSys.getViewMtx(), i_this->mPoints, i_this->mColor); +} + +//------------------------------------------------------- +// Triangle +//------------------------------------------------------- + +static J3DPacket__vtable_t mDoExt_trianglePacket__vtable { + (void*)nullptr, // RTTI + (void*)nullptr, // pad + (void*)&J3DPacket__entry, + (void*)&mDoExt_trianglePacket__draw, + (void*)&mDoExt_trianglePacket__dtor, +}; + +KEEP_FUNC void dDbVw_drawTriangleXlu(cXyz* points, const GXColor& color, u8 param_2) { + if (l_drawPacketListNum < DRAW_PACKET_MAX) { + mDoExt_trianglePacket* tri = new mDoExt_trianglePacket(points, color, param_2); + tri->base.vtable = &mDoExt_trianglePacket__vtable; + + dDbVw_setDrawPacketList(&tri->base, 1); + } +} + +void mDoExt_trianglePacket__dtor(mDoExt_trianglePacket* i_this) { + i_this->~mDoExt_trianglePacket(); + delete i_this; +} + +void mDoExt_trianglePacket__draw(mDoExt_trianglePacket* i_this) { + J3DSys__reinitGX(&j3dSys); + + GXSetArray(GX_VA_POS, i_this->mPoints, sizeof(cXyz)); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXLoadPosMtxImm(j3dSys.getViewMtx(), 0); + GXSetCurrentMtx(0); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetTevColor(GX_TEVREG0, i_this->mColor); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + GXSetZCompLoc(GX_ENABLE); + + if (i_this->_38) { + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + } else { + GXSetZMode(GX_DISABLE, GX_LEQUAL, GX_DISABLE); + } + + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); + + GXColor clearColor = {0, 0, 0, 0}; + GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, clearColor); + GXSetFogRangeAdj(GX_DISABLE, 0, nullptr); + GXSetCullMode(GX_CULL_NONE); + GXSetDither(GX_ENABLE); + GXSetClipMode(GX_CLIP_ENABLE); + GXSetNumIndStages(0); + + GXBegin(GX_TRIANGLES, GX_VTXFMT0, 3); + GXPosition1x8(0); + GXPosition1x8(1); + GXPosition1x8(2); + GXEnd(); + + resetVcdVatCache(); +} + +//------------------------------------------------------- +// Line +//------------------------------------------------------- + +static J3DPacket__vtable_t mDoExt_linePacket__vtable { + (void*)nullptr, // RTTI + (void*)nullptr, // pad + (void*)&J3DPacket__entry, + (void*)&mDoExt_linePacket__draw, + (void*)&mDoExt_linePacket__dtor, +}; + +KEEP_FUNC void dDbVw_drawLineXlu(cXyz& pointA, cXyz& pointB, const GXColor& color, u8 param_3, u8 width) { + if (l_drawPacketListNum < DRAW_PACKET_MAX) { + mDoExt_linePacket* line = new mDoExt_linePacket(pointA, pointB, color, param_3, width); + line->base.vtable = &mDoExt_linePacket__vtable; + + dDbVw_setDrawPacketList(&line->base, 1); + } +} + +void mDoExt_linePacket__dtor(mDoExt_linePacket* i_this) { + i_this->~mDoExt_linePacket(); + delete i_this; +} + +void mDoExt_linePacket__draw(mDoExt_linePacket* i_this) { + J3DSys__reinitGX(&j3dSys); + + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXLoadPosMtxImm(j3dSys.getViewMtx(), 0); + GXSetCurrentMtx(0); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetTevColor(GX_TEVREG0, i_this->mColor); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + GXSetZCompLoc(GX_ENABLE); + + if (i_this->_2C) { + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + } else { + GXSetZMode(GX_DISABLE, GX_LEQUAL, GX_DISABLE); + } + + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); + + GXColor clearColor = {0, 0, 0, 0}; + GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, clearColor); + GXSetFogRangeAdj(GX_DISABLE, 0, nullptr); + GXSetCullMode(GX_CULL_NONE); + GXSetDither(GX_ENABLE); + GXSetClipMode(GX_CLIP_ENABLE); + GXSetNumIndStages(0); + GXSetLineWidth(i_this->mWidth, GX_TO_ZERO); + + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(i_this->mPointA.x, i_this->mPointA.y, i_this->mPointA.z); + GXPosition3f32(i_this->mPointB.x, i_this->mPointB.y, i_this->mPointB.z); + GXEnd(); + + resetVcdVatCache(); +} + +//------------------------------------------------------- +// Cylinder Matrix +//------------------------------------------------------- + +static J3DPacket__vtable_t mDoExt_cylinderMPacket__vtable { + (void*)nullptr, // RTTI + (void*)nullptr, // pad + (void*)&J3DPacket__entry, + (void*)&mDoExt_cylinderMPacket__draw, + (void*)&mDoExt_cylinderMPacket__dtor, +}; + +KEEP_FUNC void dDbVw_drawCylinderMXlu(Mtx m, const GXColor& color, u8 param_2) { + if (l_drawPacketListNum < DRAW_PACKET_MAX) { + mDoExt_cylinderMPacket* cylm = new mDoExt_cylinderMPacket(m, color, param_2); + cylm->base.vtable = &mDoExt_cylinderMPacket__vtable; + + dDbVw_setDrawPacketList(&cylm->base, 1); + } +} + +void mDoExt_cylinderMPacket__dtor(mDoExt_cylinderMPacket* i_this) { + i_this->~mDoExt_cylinderMPacket(); + delete i_this; +} + +void mDoExt_cylinderMPacket__draw(mDoExt_cylinderMPacket* i_this) { + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT0, GX_DF_CLAMP, GX_AF_NONE); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetTevColor(GX_TEVREG0, i_this->mColor); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + + if (i_this->_44) { + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + } else { + GXSetZMode(GX_DISABLE, GX_LEQUAL, GX_DISABLE); + } + + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); + GXSetCullMode(GX_CULL_BACK); + GXSetClipMode(GX_CLIP_ENABLE); + + PSMTXConcat(j3dSys.getViewMtx(), i_this->mMatrix, i_this->mMatrix); + + GXLoadPosMtxImm(i_this->mMatrix, 0); + mDoMtx_inverseTranspose(i_this->mMatrix, i_this->mMatrix); + + GXLoadNrmMtxImm(i_this->mMatrix, 0); + GXSetCurrentMtx(0); + + GXDrawCylinder(8); +} + +//------------------------------------------------------- +// Circle +//------------------------------------------------------- + +static J3DPacket__vtable_t mDoExt_circlePacket__vtable { + (void*)nullptr, // RTTI + (void*)nullptr, // pad + (void*)&J3DPacket__entry, + (void*)&mDoExt_circlePacket__draw, + (void*)&mDoExt_circlePacket__dtor, +}; + +KEEP_FUNC void dDbVw_drawCircleXlu(cXyz& i_position, f32 i_radius, const GXColor& i_color, u8 param_3, u8 i_lineWidth) { + if (l_drawPacketListNum < DRAW_PACKET_MAX) { + mDoExt_circlePacket* circle = new mDoExt_circlePacket(i_position, i_radius, i_color, param_3, i_lineWidth); + circle->base.vtable = &mDoExt_circlePacket__vtable; + + dDbVw_setDrawPacketList(&circle->base, 1); + } +} + +void mDoExt_circlePacket__dtor(mDoExt_circlePacket* i_this) { + i_this->~mDoExt_circlePacket(); + delete i_this; +} + +void mDoExt_circlePacket__draw(mDoExt_circlePacket* i_this) { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetTevColor(GX_TEVREG0, i_this->m_color); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); + + if (i_this->_24) { + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + } else { + GXSetZMode(GX_DISABLE, GX_LEQUAL, GX_DISABLE); + } + + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); + GXSetCullMode(GX_CULL_NONE); + GXSetClipMode(GX_CLIP_ENABLE); + GXSetLineWidth(i_this->m_lineWidth, GX_TO_ZERO); + GXLoadPosMtxImm(j3dSys.getViewMtx(), 0); + GXSetCurrentMtx(0); + + cXyz sp38; + cXyz sp44; + int numEdges = 36; + sp38.y = sp44.y = i_this->m_position.y; + + GXBegin(GX_LINES, GX_VTXFMT0, numEdges * 2); + for (int i = 0; i < numEdges; i++) { + sp38.x = fcos((i * 6.2831855f) / numEdges) * i_this->m_radius; + sp38.z = fsin((i * 6.2831855f) / numEdges) * i_this->m_radius; + + sp44.x = fcos(((i + 1) * 6.2831855f) / numEdges) * i_this->m_radius; + sp44.z = fsin(((i + 1) * 6.2831855f) / numEdges) * i_this->m_radius; + + sp38.x += i_this->m_position.x; + sp38.z += i_this->m_position.z; + sp44.x += i_this->m_position.x; + sp44.z += i_this->m_position.z; + GXPosition3f32(sp38.x, sp38.y, sp38.z); + GXPosition3f32(sp44.x, sp44.y, sp44.z); + } + GXEnd(); +} + +#define CM3D_F_ABS_MIN 0.0000038146973f +inline bool cM3d_IsZero(f32 f) { + return std__fabsf(f) < CM3D_F_ABS_MIN; +} + +int cM3d_UpMtx_Base(const Vec& param_0, const Vec& param_1, Mtx m) { + if (cM3d_IsZero(PSVECMag(¶m_1))) { + PSMTXIdentity(m); + return 0; + } + + Vec sp3C; + Vec sp48; + PSVECNormalize(¶m_1, &sp48); + PSVECCrossProduct(¶m_0, &sp48, &sp3C); + + if (cM3d_IsZero(PSVECMag(&sp3C))) { + sp3C.x = 1.0f; + sp3C.y = 0.0f; + sp3C.z = 0.0f; + } + + f32 var_f31 = PSVECDotProduct(¶m_0, &sp48); + if (var_f31 > 1.0f) { + var_f31 = 1.0f; + } else if (var_f31 < -1.0f) { + var_f31 = -1.0f; + } + + f32 var_f30 = (float)acos(var_f31); + PSMTXRotAxisRad(m, &sp3C, var_f30); + return 1; +} + +int cM3d_UpMtx(const Vec& param_0, Mtx m) { + static Vec base_y = {0.0f, 1.0f, 0.0f}; + + return cM3d_UpMtx_Base(base_y, param_0, m); +} + +#define MAX_DRAW_DIST 2000.0f + +KEEP_FUNC void dCcD_Cyl_Draw(dCcD_Cyl* i_this, const GXColor& i_color) { + if (dComIfGp_getPlayer()->current.pos.abs(i_this->mCylAttr.cyl.mCenter) < MAX_DRAW_DIST) { + dDbVw_drawCylinderXlu(i_this->mCylAttr.cyl.mCenter, i_this->mCylAttr.cyl.GetR(), i_this->mCylAttr.cyl.GetH(), i_color, 1); + } +} + +KEEP_FUNC void dCcD_Sph_Draw(dCcD_Sph* i_this, const GXColor& i_color) { + if (dComIfGp_getPlayer()->current.pos.abs(i_this->mSphAttr.sph.mCenter) < MAX_DRAW_DIST) { + dDbVw_drawSphereXlu(i_this->mSphAttr.sph.mCenter, i_this->mSphAttr.sph.GetR(), i_color, 1); + } +} + +KEEP_FUNC void dCcD_Cps_Draw(dCcD_Cps* i_this, const GXColor& i_color) { + if (dComIfGp_getPlayer()->current.pos.abs(i_this->mCpsAttr.cps.mStart) < MAX_DRAW_DIST) { + Mtx up_m; + Mtx sp98; + Mtx cyl_m; + PSMTXIdentity(cyl_m); + + cXyz spD8; + i_this->mCpsAttr.cps.CalcVec(&spD8); + + mDoMtx_trans(sp98, i_this->mCpsAttr.cps.GetStartP().x, i_this->mCpsAttr.cps.GetStartP().y, i_this->mCpsAttr.cps.GetStartP().z); + cM3d_UpMtx(spD8, up_m); + mDoMtx_concat(sp98, up_m, cyl_m); + + mDoMtx_scale(sp98, i_this->mCpsAttr.cps.GetR(), i_this->mCpsAttr.cps.GetLen() * 0.5f, i_this->mCpsAttr.cps.GetR()); + mDoMtx_concat(cyl_m, sp98, cyl_m); + mDoMtx_trans(sp98, 0.0f, 1.0f, 0.0f); + mDoMtx_concat(cyl_m, sp98, cyl_m); + mDoMtx_XrotS(sp98, 0x4000); + mDoMtx_concat(cyl_m, sp98, cyl_m); + + dDbVw_drawCylinderMXlu(cyl_m, i_color, 1); + dDbVw_drawSphereXlu(i_this->mCpsAttr.cps.GetStartP(), i_this->mCpsAttr.cps.GetR(), i_color, 1); + dDbVw_drawSphereXlu(i_this->mCpsAttr.cps.GetEndP(), i_this->mCpsAttr.cps.GetR(), i_color, 1); + } +} + +u16 dCcS_Data::at_obj_count = 0; +u16 dCcS_Data::tg_obj_count = 0; +u16 dCcS_Data::co_obj_count = 0; + +KEEP_FUNC void GZ_drawCc(dCcS* i_this) { + static bool init_vtables = false; + if (!init_vtables) { + // we patch the original vtables with our own functions so that + // we can replicate the debug rom functionality of each collider type + // having their own specific virtual draw function. + dCcD_Cyl_vtable.Draw = (cCcD_DrawFn)dCcD_Cyl_Draw; + dCcD_Sph_vtable.Draw = (cCcD_DrawFn)dCcD_Sph_Draw; + dCcD_Cps_vtable.Draw = (cCcD_DrawFn)dCcD_Cps_Draw; + init_vtables = true; + } + + daAlink_c* player = dComIfGp_getPlayer(); + if (player != NULL && init_vtables) { + if (g_collisionFlags[VIEW_AT_CC].active) { + //OSReport("At:%d\n", i_this->mObjAtCount); + + for (u16 i = 0; i < dCcS_Data::at_obj_count; i++) { + cCcD_Obj* obj = i_this->mpObjAt[i]; + if (obj != NULL) { + GXColor at_color = {0xFF, 0x00, 0x00, g_geometryOpacity}; + obj->vtable->Draw(obj, at_color); + } + } + } + + if (g_collisionFlags[VIEW_TG_CC].active) { + // OSReport("Tg:%d\n", dCcS_Data::tg_obj_count); + + for (u16 i = 0; i < dCcS_Data::tg_obj_count; i++) { + cCcD_Obj* obj = i_this->mpObjTg[i]; + if (obj != NULL) { + GXColor tg_color = {0x3A, 0x82, 0xF0, g_geometryOpacity}; + obj->vtable->Draw(obj, tg_color); + } + } + } + + if (g_collisionFlags[VIEW_CO_CC].active) { + //OSReport("Co:%d\n", i_this->mObjCoCount); + + for (u16 i = 0; i < dCcS_Data::co_obj_count; i++) { + cCcD_Obj* obj = i_this->mpObjCo[i]; + if (obj != NULL) { + GXColor co_color = {0xFF, 0xFF, 0xFF, g_geometryOpacity}; + obj->vtable->Draw(obj, co_color); + } + } + } + } +} + +//------------------------------------------------------- +// POLY DRAW +//------------------------------------------------------- + +int poly_draw(dBgS_CaptPoly* i_captpoly, cBgD_Vtx_t* i_vtx, int i_ia, int i_ib, int i_ic, cM3dGPla* i_plane) { + cXyz vertices[3]; + + GXColor ground_col = {0xFF, 0x00, 0x00, g_geometryOpacity}; + GXColor roof_col = {0x00, 0x00, 0xFF, g_geometryOpacity}; + GXColor wall_col = {0x00, 0xFF, 0x00, g_geometryOpacity}; + + GXColor flat_col = {0xFF, 0xC5, 0xC5, g_geometryOpacity}; + + cXyz raise; + PSVECScale(&i_plane->mNormal, &raise, (f32)g_collisionRaise); + + vertices[0] = i_vtx[i_ia].vertex; + vertices[1] = i_vtx[i_ib].vertex; + vertices[2] = i_vtx[i_ic].vertex; + + PSVECAdd(&vertices[0], &raise, &vertices[0]); + PSVECAdd(&vertices[1], &raise, &vertices[1]); + PSVECAdd(&vertices[2], &raise, &vertices[2]); + + if (cBgW_CheckBGround(i_plane->mNormal.y)) { + if (g_collisionFlags[VIEW_POLYGON_GROUND].active) { + if (i_plane->mNormal.y >= 1.0f) { + // draw special color for fully flat ground + dDbVw_drawTriangleXlu(vertices, flat_col, 1); + } else { + dDbVw_drawTriangleXlu(vertices, ground_col, 1); + } + } + } else if (cBgW_CheckBRoof(i_plane->mNormal.y)) { + if (g_collisionFlags[VIEW_POLYGON_ROOF].active) { + dDbVw_drawTriangleXlu(vertices, roof_col, 1); + } + } else if (g_collisionFlags[VIEW_POLYGON_WALL].active) { + dDbVw_drawTriangleXlu(vertices, wall_col, 1); + } + + return 0; +} + +int poly_edge_draw(dBgS_CaptPoly* i_captpoly, cBgD_Vtx_t* i_vtx, int i_ia, int i_ib, int i_ic, cM3dGPla* i_plane) { + if (cBgW_CheckBGround(i_plane->mNormal.y)) { + if (!g_collisionFlags[VIEW_POLYGON_GROUND].active) { + return 0; + } + } else if (cBgW_CheckBRoof(i_plane->mNormal.y)) { + if (!g_collisionFlags[VIEW_POLYGON_ROOF].active) { + return 0; + } + } else if (!g_collisionFlags[VIEW_POLYGON_WALL].active) { + return 0; + } + + GXColor color = {0xFF, 0xFF, 0xFF, 0xFF}; + + cXyz raise; + PSVECScale(&i_plane->mNormal, &raise, (f32)g_collisionRaise); + + cXyz start; + cXyz end; + + // A to B + start.set(i_vtx[i_ia].vertex.x, i_vtx[i_ia].vertex.y, i_vtx[i_ia].vertex.z); + end.set(i_vtx[i_ib].vertex.x, i_vtx[i_ib].vertex.y, i_vtx[i_ib].vertex.z); + PSVECAdd(&raise, &start, &start); + PSVECAdd(&raise, &end, &end); + dDbVw_drawLineXlu(start, end, color, 1, 12); + + // B to C + start.set(i_vtx[i_ib].vertex.x, i_vtx[i_ib].vertex.y, i_vtx[i_ib].vertex.z); + end.set(i_vtx[i_ic].vertex.x, i_vtx[i_ic].vertex.y, i_vtx[i_ic].vertex.z); + PSVECAdd(&raise, &start, &start); + PSVECAdd(&raise, &end, &end); + dDbVw_drawLineXlu(start, end, color, 1, 12); + + // C to A + start.set(i_vtx[i_ic].vertex.x, i_vtx[i_ic].vertex.y, i_vtx[i_ic].vertex.z); + end.set(i_vtx[i_ia].vertex.x, i_vtx[i_ia].vertex.y, i_vtx[i_ia].vertex.z); + PSVECAdd(&raise, &start, &start); + PSVECAdd(&raise, &end, &end); + dDbVw_drawLineXlu(start, end, color, 1, 12); + + return 0; +} + +void CaptPoly(dBgS_CaptPoly& i_captpoly) { + cBgS_ChkElm* poly_elm = dComIfG_Bgsp()->m_chk_element; + + for (int i = 0; i < 0x100; i++) { + if (poly_elm->ChkUsed()) { + poly_elm->m_bgw_base_ptr->vtable->CaptPoly(poly_elm->m_bgw_base_ptr, i_captpoly); + } + poly_elm++; + } +} + +KEEP_FUNC void GZ_drawPolygons() { + if (g_collisionFlags[VIEW_POLYGON_GROUND].active || g_collisionFlags[VIEW_POLYGON_WALL].active || g_collisionFlags[VIEW_POLYGON_ROOF].active) { + daAlink_c* player = dComIfGp_getPlayer(); + + if (player != NULL) { + Vec* base_pos = &player->current.pos; + if (g_freeCamEnabled) { + base_pos = &matrixInfo.matrix_info->pos; + } + + cM3dGAab aab; + cXyz min; + cXyz max; + + f32 range = (f32)g_collisionRange; + min.set(base_pos->x - range, base_pos->y - range, base_pos->z - range); + max.set(base_pos->x + range, base_pos->y + range, base_pos->z + range); + aab.mMin = min; + aab.mMax = max; + + dBgS_CaptPoly poly_capt; + poly_capt.field_0x14.mGrpPassChkInfo.OnFullGrp(); + poly_capt.mAab.mMin = aab.mMin; + poly_capt.mAab.mMax = aab.mMax; + + // draw edges + if (g_collisionFlags[VIEW_POLYGON_EDGES].active) { + poly_capt.mpCallback = poly_edge_draw; + CaptPoly(poly_capt); + } + + // draw poly + poly_capt.mpCallback = poly_draw; + CaptPoly(poly_capt); + } + } +} \ No newline at end of file diff --git a/modules/boot/src/global_data.cpp b/modules/boot/src/global_data.cpp index 773ce47d..51018a17 100644 --- a/modules/boot/src/global_data.cpp +++ b/modules/boot/src/global_data.cpp @@ -1,5 +1,36 @@ #include "global_data.h" +#include "trigger_view.h" +#include "features/projection_view/include/projection_view.h" #include "rels/include/defines.h" KEEP_VAR bool g_freeCamEnabled; KEEP_VAR bool g_moveLinkEnabled; +KEEP_VAR u8 g_geometryOpacity = 0x80; +KEEP_VAR u16 g_collisionRange = 100; +KEEP_VAR u8 g_collisionRaise = 1; + +KEEP_VAR fopAc_ac_c* g_currentActor; +KEEP_VAR bool g_actorViewEnabled; + +KEEP_VAR TriggerViewItem g_triggerViewFlags[TRIGGER_VIEW_MAX] = { + {VIEW_LOAD_ZONES, false}, + {VIEW_MIDNA_STOPS, false}, + {VIEW_SWITCH_AREAS, false}, + {VIEW_EVENT_AREAS, false}, + {VIEW_TW_GATES, false}, + {VIEW_PATHS, false}, + {VIEW_CHG_RESTARTS, false}, + {VIEW_TRANSFORM_DISTS, false}, + {VIEW_ATTN_DISTS, false}, + {VIEW_MIST_AVOID, false}, +}; + +KEEP_VAR ProjectionLine g_ljaProjectionLine; +KEEP_VAR ProjectionLine g_midnaChargeProjectionLine; + +KEEP_VAR ProjectionViewItem g_projectionViewFlags[PROJECTION_VIEW_MAX] = { + {VIEW_LJA_PROJECTION, false}, + {VIEW_MIDNA_CHARGE_PROJECTION, false}, +}; + +KEEP_VAR bool g_transformIndicatorEnabled; \ No newline at end of file diff --git a/modules/boot/src/gz_flags.cpp b/modules/boot/src/gz_flags.cpp index 44d5f4fd..3dc8228e 100644 --- a/modules/boot/src/gz_flags.cpp +++ b/modules/boot/src/gz_flags.cpp @@ -2,11 +2,8 @@ #include #include "controller.h" #include "fifo_queue.h" -#include "gorge.h" -#include "bit.h" #include "scene.h" #include "tools.h" -#include "rollcheck.h" #include "utils/audio.h" #include "utils/lines.h" #include "utils/link.h" @@ -14,31 +11,16 @@ #include "flaglog.h" #include "save_manager.h" #include "memfiles.h" -#include "corotdcheck.h" -#include "umd.h" #include "utils/draw.h" #include "libtp_c/include/JSystem/JUtility/JUTGamePad.h" +#include "libtp_c/include/m_Do/m_Re_controller_pad.h" #include "libtp_c/include/f_op/f_op_scene_req.h" #include "rels/include/defines.h" bool g_framePaused = false; -GZFlag g_gzFlags[MAX_GZ_FLAGS] = { - {&g_tools[GORGE_INDEX].active, GAME_LOOP, GorgeVoidIndicator::execute}, -#ifdef WII_PLATFORM - {&g_tools[BIT_INDEX].active, GAME_LOOP, BiTIndicator::execute}, -#endif - {&g_tools[ROLL_INDEX].active, GAME_LOOP, RollIndicator::execute}, - {&g_tools[COROTD_INDEX].active, GAME_LOOP, CoroTDChecker::execute}, - {&g_tools[UMD_INDEX].active, POST_GAME_LOOP, UMDIndicator::execute}, - {&g_sceneFlags[FREEZE_ACTOR_INDEX].active, GAME_LOOP, GZ_freezeActors, GZ_unfreezeActors}, - {&g_sceneFlags[HIDE_ACTOR_INDEX].active, GAME_LOOP, GZ_hideActors, GZ_showActors}, - {&g_sceneFlags[FREEZE_CAMERA_INDEX].active, GAME_LOOP, GZ_freezeCamera, GZ_unfreezeCamera}, - {&g_sceneFlags[HIDE_HUD_INDEX].active, GAME_LOOP, GZ_hideHUD, GZ_showHUD}, - {&g_sceneFlags[FREEZE_TIME_INDEX].active, GAME_LOOP, GZ_freezeTime}, - {&g_sceneFlags[DISABLE_BG_INDEX].active, GAME_LOOP, GZ_disableBGM, GZ_enableBGM}, - {&g_sceneFlags[DISABLE_SFX_INDEX].active, GAME_LOOP, GZ_disableSFX, GZ_enableSFX}, -}; +// Initialized in the "init" module +KEEP_VAR tpgz::containers::deque g_gzFlags; #ifdef GCN_PLATFORM #define HOLD_BTNS cPadInfo[0].mButtonFlags @@ -50,6 +32,24 @@ GZFlag g_gzFlags[MAX_GZ_FLAGS] = { #define TRIG_BTNS mPad.mTrigButton #endif +KEEP_FUNC void GZFlg_addFlag(GZFlag* flag) { + g_gzFlags.push_back(flag); +} + +KEEP_FUNC GZFlag* GZFlg_removeFlag(GZFlags flag_id) { + auto it = g_gzFlags.begin(); + for (;it != g_gzFlags.end(); ++it) { + if ((*it)->id == flag_id) { + break; + } + } + auto* flag = *it; + g_gzFlags.erase(it); + return flag; +} + + + KEEP_FUNC void GZ_frameAdvance() { if (!g_framePaused) { return; @@ -60,25 +60,27 @@ KEEP_FUNC void GZ_frameAdvance() { TRIG_BTNS = HOLD_BTNS & ~buttonsPrev; - if (HOLD_BTNS & FRAME_ADVANCE_PAD) { + uint16_t frameAdvancePad = GZStng_getData(STNG_CMD_FRAME_ADVANCE, FRAME_ADVANCE_PAD); + + if (HOLD_BTNS & frameAdvancePad) { holdCounter++; } else { holdCounter = 0; } - if (GZ_getButtonTrig(FRAME_ADVANCE_BTN)) { + if (GZ_getPadTrigAny(frameAdvancePad)) { // this sets pause timer to 0 for 1 frame, // which lets 1 frame pass before pausing again sPauseTimer = 0; buttonsPrev = HOLD_BTNS; - HOLD_BTNS &= ~FRAME_ADVANCE_PAD; + HOLD_BTNS &= ~frameAdvancePad; } // frames start passing at normal speed after holding for 30 frames if (holdCounter >= 30) { sPauseTimer = 0; buttonsPrev = HOLD_BTNS; - HOLD_BTNS &= ~FRAME_ADVANCE_PAD; + HOLD_BTNS &= ~frameAdvancePad; } } @@ -100,16 +102,22 @@ void GZ_drawFrameTex(Texture* pauseTex, Texture* playTex) { } void GZ_execute(int phase) { - for (int i = 0; i < MAX_GZ_FLAGS; i++) { - if (g_gzFlags[i].mPhase == phase && g_gzFlags[i].mpFlag != nullptr) { - if (*g_gzFlags[i].mpFlag && g_gzFlags[i].mpActiveFunc) { - g_gzFlags[i].mpActiveFunc(); - } else if (g_gzFlags[i].mpDeactiveFunc) { - g_gzFlags[i].mpDeactiveFunc(); + for (auto gzFlag : g_gzFlags) { + if (gzFlag->mPhase == phase && gzFlag->mpFlag != nullptr) { + if (gzFlag->mpFlag() && gzFlag->mpActiveFunc) { + gzFlag->mpActiveFunc(); + } else if (gzFlag->mpDeactiveFunc) { + gzFlag->mpDeactiveFunc(); } } } + if (GZStng_getData(STNG_TOOLS_SAND, false)) { + if (dComIfGp_getPlayer() != nullptr) { + dComIfGp_getPlayer()->field_0x2ba8 = 0.0f; + } + } + // Timer set after dScnPly__phase_4, delay until objects are fully loaded if (!fopScnRq.isLoading && SaveManager::s_applyAfterTimer > 0) { SaveManager::s_applyAfterTimer--; @@ -128,3 +136,14 @@ void GZ_execute(int phase) { dComIfGs_setMaxOxygen(600); } } + +#define ACTIVE_FLAG_FUNC(name, stngId) \ + KEEP_FUNC bool name() { return GZStng_getData(stngId, false); } + +ACTIVE_FLAG_FUNC(GZ_freezeActors_active, STNG_SCENE_FREEZE_ACTOR) +ACTIVE_FLAG_FUNC(GZ_hideActors_active, STNG_SCENE_HIDE_ACTOR) +ACTIVE_FLAG_FUNC(GZ_freezeCamera_active, STNG_SCENE_FREEZE_CAMERA) +ACTIVE_FLAG_FUNC(GZ_hideHUD_active, STNG_SCENE_HIDE_HUD) +ACTIVE_FLAG_FUNC(GZ_freezeTime_active, STNG_SCENE_FREEZE_TIME) +ACTIVE_FLAG_FUNC(GZ_disableBgm_active, STNG_SCENE_DISABLE_BG) +ACTIVE_FLAG_FUNC(GZ_disableSFX_active, STNG_SCENE_DISABLE_SFX) \ No newline at end of file diff --git a/modules/boot/src/main.cpp b/modules/boot/src/main.cpp index 9d4c9607..7cab3945 100644 --- a/modules/boot/src/main.cpp +++ b/modules/boot/src/main.cpp @@ -5,10 +5,13 @@ #include "global_data.h" #include "gz_flags.h" #include "libtp_c/include/m_Do/m_Do_printf.h" -#include "menu.h" +#include "menus/menu.h" #include "settings.h" #include "menus/utils/menu_mgr.h" #include "timer.h" +#include "pos_settings.h" +#include "trigger_view.h" +#include "collision_view.h" #include "utils/card.h" #include "utils/draw.h" #include "utils/link.h" @@ -34,9 +37,6 @@ _FIFOQueue Queue; bool l_loadCard = true; Texture l_gzIconTex; bool last_frame_was_loading = false; -tpgz::dyn::GZModule g_InputViewer_rel("/tpgz/rels/features/input_viewer.rel"); -tpgz::dyn::GZModule g_FreeCam_rel("/tpgz/rels/features/free_cam.rel"); -tpgz::dyn::GZModule g_MoveLink_rel("/tpgz/rels/features/movelink.rel"); #define Q(x) #x #define QUOTE(x) Q(x) @@ -107,34 +107,14 @@ KEEP_FUNC void draw() { } } -/** - * @brief Loads into memory the RELs for each tool which is active. - * - * @param id The ID of the tool (index in g_tools). - * @param rel The GZModule object used to load the REL. - */ -inline void handleModule(size_t id, tpgz::dyn::GZModule& rel) { - if (g_tools[id].active && !rel.isLoaded()) { - rel.loadFixed(true); +KEEP_FUNC void GZ_drawPacketNumOverflow() { + if (l_drawPacketListNum >= 1000) { + Font::GZ_drawStr("Draw Packet List full!", 35.0f, 430.0f, 0xFFFFFFFF, GZ_checkDropShadows()); } - if (!g_tools[id].active && rel.isLoaded()) { - rel.close(); - } -} - -/** - * @brief Handles when to load tools into memory. - * Registered to run before the main loop. - */ -KEEP_FUNC void GZ_handleTools() { - // Put modules that toggles with the state of g_tools - handleModule(INPUT_VIEWER_INDEX, g_InputViewer_rel); - handleModule(FREE_CAM_INDEX, g_FreeCam_rel); - handleModule(MOVE_LINK_INDEX, g_MoveLink_rel); } /** - * @brief Handles when to show/hid the menus. + * @brief Handles when to show/hide the menus. */ KEEP_FUNC void GZ_handleMenu() { if (BUTTONS == SHOW_MENU_BUTTONS && fopScnRq.isLoading != 1 && !g_moveLinkEnabled) { @@ -152,6 +132,7 @@ KEEP_FUNC void GZ_handleMenu() { if (fopScnRq.isLoading) { g_menuMgr->hide(); g_moveLinkEnabled = false; + g_actorViewEnabled = false; last_frame_was_loading = true; g_freeCamEnabled = false; } @@ -193,7 +174,7 @@ KEEP_FUNC void GZ_handleFlags_PostLoop() { } KEEP_FUNC void GZ_handleTurbo() { - if (g_tools[TURBO_MODE_INDEX].active) { + if (GZStng_getData(STNG_TOOLS_TURBO_MODE, false)) { #ifdef GCN_PLATFORM cPadInfo[0].mPressedButtonFlags = cPadInfo[0].mButtonFlags; #endif @@ -208,10 +189,11 @@ KEEP_FUNC void GZ_handleTurbo() { KEEP_FUNC void GZ_renderMenuTitle() { if (g_menuMgr->isOpen()) { - Font::GZ_drawStr("tpgz v" INTERNAL_GZ_VERSION, g_spriteOffsets[MENU_INDEX].x + 35.0f, 25.0f, - g_cursorColor, g_dropShadows); + Vec2 spriteOffset = GZ_getSpriteOffset(STNG_SPRITES_MENU); + Font::GZ_drawStr("tpgz v" INTERNAL_GZ_VERSION, spriteOffset.x + 35.0f, 25.0f, + g_cursorColor, GZ_checkDropShadows()); if (l_gzIconTex.loadCode == TexCode::TEX_OK) { - Draw::drawRect(0xFFFFFFFF, {g_spriteOffsets[MENU_INDEX].x, 5.0f}, + Draw::drawRect(0xFFFFFFFF, {spriteOffset.x, 5.0f}, {30 * (isWidescreen ? 0.75f : 1.0f), 30}, &l_gzIconTex._texObj); } } @@ -221,7 +203,7 @@ Texture l_framePauseTex; Texture l_framePlayTex; KEEP_FUNC void GZ_renderPlayPause() { - if (g_tools[FRAME_ADVANCE_INDEX].active) { + if (GZStng_getData(STNG_TOOLS_FRAME_ADVANCE, false)) { if (l_framePauseTex.loadCode == TexCode::TEX_UNLOADED) { load_texture("/tpgz/tex/framePause.tex", &l_framePauseTex); } diff --git a/modules/boot/src/menu.cpp b/modules/boot/src/menus/menu.cpp similarity index 80% rename from modules/boot/src/menu.cpp rename to modules/boot/src/menus/menu.cpp index 08c79514..0dcde5ed 100644 --- a/modules/boot/src/menu.cpp +++ b/modules/boot/src/menus/menu.cpp @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" #include "rels/include/defines.h" // This array must correspond to the order of the MenuIndex enum. @@ -12,7 +12,9 @@ const char* g_menuPaths[MN_COUNT] = { "watches", "memory_editor", "memfiles", "any_saves", "any_bite_saves", "hundo_saves", "ad_saves", "nosq_saves", "glitchless_saves", - "actor_spawn", "actor_list", "pos_settings", + "actor_spawn", "actor_list", "collision_view", + "projection_view", "trigger_view", "pos_settings", + "credits", "combo" }; KEEP_FUNC Menu::Menu(Cursor& cursor) : cursor(cursor) {} \ No newline at end of file diff --git a/modules/boot/src/menus/utils/menu_mgr.cpp b/modules/boot/src/menus/utils/menu_mgr.cpp index d622766d..b1681f37 100644 --- a/modules/boot/src/menus/utils/menu_mgr.cpp +++ b/modules/boot/src/menus/utils/menu_mgr.cpp @@ -1,7 +1,7 @@ #include "menus/utils/menu_mgr.h" #include #include -#include "menu.h" +#include "menus/menu.h" #include "gz_flags.h" #include "rels/include/defines.h" diff --git a/modules/boot/src/modules.cpp b/modules/boot/src/modules.cpp new file mode 100644 index 00000000..75f042b9 --- /dev/null +++ b/modules/boot/src/modules.cpp @@ -0,0 +1,101 @@ +#include "modules.h" +#include "libtp_c/include/defines.h" + +#include "commands.h" +#include "global_data.h" +#include "settings.h" +#include "tools.h" +#include "trigger_view.h" + +KEEP_VAR tpgz::containers::deque g_modules; + +/** + * @brief Handles when to load or unload REL modules. + * Registered to run before the main loop. + */ +KEEP_FUNC void GZ_handleModules() { + for (auto mod : g_modules) { + if (mod->active() && !mod->rel.isLoaded()) { + mod->rel.load(true); + } + if (!mod->active() && mod->rel.isLoaded()) { + mod->rel.close(); + } + } +} + +KEEP_FUNC bool inputViewer_active() { + return GZStng_getData(STNG_TOOLS_INPUT_VIEWER, false); +} + +KEEP_FUNC bool freeCam_active() { + return GZStng_getData(STNG_TOOLS_FREE_CAM, false); +} + +KEEP_FUNC bool moveLink_active() { + return g_actorViewEnabled ? true : GZStng_getData(STNG_TOOLS_MOVE_LINK, false); +} + +KEEP_FUNC bool projectionView_active() { + return GZStng_getData(STNG_SCENE_LJA_PROJECTION, false) || GZStng_getData(STNG_SCENE_MIDNA_CHARGE_PROJECTION, false); +} + +KEEP_FUNC bool triggerViewer_active() { + int active_flags = 0; + for (int i = 0; i < TRIGGER_VIEW_MAX; i++) { + if (g_triggerViewFlags[i].active) { + active_flags++; + } + } + return active_flags > 0; +} + +KEEP_FUNC bool actorView_active() { + return g_actorViewEnabled; +} + +KEEP_FUNC bool transformIndicator_active() { + return GZStng_getData(STNG_TOOLS_TRANSFORM_INDICATOR, false); +} + +KEEP_FUNC bool umd_active() { + return GZStng_getData(STNG_TOOLS_UMD, false); +} + +#ifdef WII_PLATFORM +KEEP_FUNC bool bit_active() { + return GZStng_getData(STNG_TOOLS_BIT, false); +} +#endif + +KEEP_FUNC bool corotd_active() { + return GZStng_getData(STNG_TOOLS_COROTD, false); +} + +KEEP_FUNC bool mash_checker_active() { + return GZStng_getData(STNG_TOOLS_MASH_CHECKER, false); +} + +KEEP_FUNC bool gorge_active() { + return GZStng_getData(STNG_TOOLS_GORGE, false); +} + +KEEP_FUNC bool rollcheck_active() { + return GZStng_getData(STNG_TOOLS_ROLL, false); +} + +KEEP_FUNC bool moon_jump_active() { + return GZStng_getData(STNG_CHEATS_MOON_JUMP, false); +} + +KEEP_FUNC bool freeze_actor_active() { + return GZStng_getData(STNG_SCENE_FREEZE_ACTOR, false); +} + +KEEP_FUNC bool hide_actor_active() { + return GZStng_getData(STNG_SCENE_HIDE_ACTOR, false); +} + +KEEP_FUNC bool freeze_camera_active() { + return GZStng_getData(STNG_SCENE_FREEZE_CAMERA, false); +} diff --git a/modules/boot/src/pos_settings.cpp b/modules/boot/src/pos_settings.cpp deleted file mode 100644 index aabec08e..00000000 --- a/modules/boot/src/pos_settings.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "pos_settings.h" -#include "rels/include/defines.h" - -KEEP_VAR Vec2 g_spriteOffsets[SPRITES_AMNT]; - -KEEP_FUNC void GZ_PosSettings_initDefaults() { -#ifdef GCN_PLATFORM - g_spriteOffsets[VIEWER_INDEX] = {220.f, 380.f}; -#elif defined(WII_PLATFORM) - g_spriteOffsets[VIEWER_INDEX] = {250.f, 360.f}; -#endif - g_spriteOffsets[MENU_INDEX] = {25.f, 60.f}; - g_spriteOffsets[DEBUG_INFO_INDEX] = {450.0f, 200.f}; - g_spriteOffsets[TIMER_SPR_INDEX] = {525.0f, 420.f}; - g_spriteOffsets[LOAD_TIMER_SPR_INDEX] = {525.0f, 30.f}; - g_spriteOffsets[IGT_TIMER_SPR_INDEX] = {35.0f, 30.f}; - g_spriteOffsets[FIFO_SPR_INDEX] = {5.0f, 440.f}; - g_spriteOffsets[HEAP_INFO_INDEX] = {145.0f, 25.0f}; -} diff --git a/modules/boot/src/practice.cpp b/modules/boot/src/practice.cpp index f6939d2c..7ed25010 100644 --- a/modules/boot/src/practice.cpp +++ b/modules/boot/src/practice.cpp @@ -1,6 +1,6 @@ #include "practice.h" char last_category[5]; -int last_save_index; +int last_save_index = -1; int last_special_size; -special* last_special_ptr; +special last_special; diff --git a/modules/boot/src/rollcheck.cpp b/modules/boot/src/rollcheck.cpp deleted file mode 100644 index a46fe0c2..00000000 --- a/modules/boot/src/rollcheck.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "rollcheck.h" -#include -#include "controller.h" -#include "fifo_queue.h" -#include "libtp_c/include/d/com/d_com_inf_game.h" -#include "libtp_c/include/SSystem/SComponent/c_counter.h" - -#define ROLL_FRAMES 19 - -static int current_counter = 0; -static int counter_difference = 0; -static int previous_counter = 0; -static int missed_counter = 0; -static char buf[20]; -static bool start_counter = false; -static bool missed_pressed_a = false; -uint16_t action_id = 0x0000; - -void RollIndicator::execute() { - // if normal human link gameplay - if (dComIfGp_getEvent().mHalt == false && dComIfGs_getTransformStatus() == STATUS_HUMAN) { - current_counter = cCt_getFrameCount(); - if (dComIfGp_getPlayer()) { - action_id = dComIfGp_getPlayer()->mActionID; - } - - if (start_counter) { - counter_difference += current_counter - previous_counter; - previous_counter = current_counter; - - if (counter_difference > 24 && action_id != daAlink_c::FRONT_ROLL) { - counter_difference = 0; - previous_counter = 0; - current_counter = 0; - missed_counter = 0; - start_counter = false; - } else if (counter_difference > 19 && action_id != daAlink_c::FRONT_ROLL) { - missed_pressed_a = false; - missed_counter = counter_difference - 19; - } - } - - if (action_id == daAlink_c::FRONT_ROLL) { - if (counter_difference > 20) { - counter_difference = 1; - } - if (!start_counter) { - start_counter = true; - previous_counter = current_counter; - counter_difference = 0; - } - - if (counter_difference > 15 && counter_difference < 19 && GZ_getButtonPressed(A) && - !GZ_getButtonHold(A)) { - snprintf(buf, sizeof(buf), "%df early", ROLL_FRAMES - counter_difference); - FIFOQueue::push(buf, Queue, 0x0000FF00); - } else if (counter_difference == 19 && GZ_getButtonPressed(A) && !GZ_getButtonHold(A)) { - FIFOQueue::push("<3", Queue, 0x00CC0000); - } else if (missed_counter > 0 && missed_pressed_a == false) { - snprintf(buf, sizeof(buf), "%df late", missed_counter); - FIFOQueue::push(buf, Queue, 0x99000000); - missed_counter = 0; - counter_difference = 0; - missed_pressed_a = true; - } - } - } -} \ No newline at end of file diff --git a/modules/boot/src/save_manager.cpp b/modules/boot/src/save_manager.cpp index 7cac7f3c..ca916304 100644 --- a/modules/boot/src/save_manager.cpp +++ b/modules/boot/src/save_manager.cpp @@ -6,7 +6,7 @@ #include "practice.h" #include "memfiles.h" #include "save_manager.h" -#include "menu.h" +#include "menus/menu.h" #include "utils/loading.h" #include "fifo_queue.h" #include "utils/card.h" @@ -87,6 +87,8 @@ void SaveManager::loadSave(uint32_t id, const char* category, special i_specials gSaveManager.mPracticeFileOpts.inject_options_after_load = i_specials[i].CallbackAfter; } + + last_special = i_specials[i]; break; } } @@ -95,8 +97,6 @@ void SaveManager::loadSave(uint32_t id, const char* category, special i_specials // Store all the info in case file reload is used last_save_index = id; strncpy(last_category, category, sizeof(last_category)); - last_special_ptr = i_specials; - last_special_size = size; } void SaveManager::loadSavefile(const char* l_filename) { diff --git a/modules/boot/src/save_specials.cpp b/modules/boot/src/save_specials.cpp index c2271071..f187bab1 100644 --- a/modules/boot/src/save_specials.cpp +++ b/modules/boot/src/save_specials.cpp @@ -6,6 +6,7 @@ #include "libtp_c/include/f_op/f_op_actor_iter.h" #include "libtp_c/include/rel/d/a/b/d_a_b_ds.h" #include "libtp_c/include/rel/d/a/obj/d_a_obj_lv4sand.h" +#include "libtp_c/include/d/d_procname.h" #include "rels/include/defines.h" typedef bool (*predicate_t)(fopAc_ac_c&); @@ -63,11 +64,6 @@ KEEP_FUNC void SaveMngSpecial_Goats1() { setNextStageLayer(5); } -KEEP_FUNC void SaveMngSpecial_Goats2() { - gSaveManager.injectDefault_during(); - setNextStageLayer(4); -} - KEEP_FUNC void SaveMngSpecial_Hugo() { gSaveManager.injectDefault_during(); dComIfGs_onSwitch(47, 0); // midna trigger off @@ -169,6 +165,16 @@ KEEP_FUNC void SaveMngSpecial_Iza1Skip() { setNextStageLayer(4); } +KEEP_FUNC void SaveMngSpecial_AnyPlummOoB() { + gSaveManager.injectDefault_during(); + g_dComIfG_gameInfo.info.mRestart.mLastMode = 0xA; // spawn on kargorok + setNextStageName("F_SP112"); // set stage to river + setNextStageRoom(1); + setNextStagePoint(0); + setNextStageLayer(4); + bossFlags = 0xFF; +} + KEEP_FUNC void SaveMngSpecial_Stallord() { gSaveManager.injectDefault_during(); g_dComIfG_gameInfo.info.mZone[0].mBit.mSwitch[0] |= 0x300000; // turn off intro cs, start fight @@ -178,31 +184,18 @@ KEEP_FUNC void SaveMngSpecial_Stallord() { KEEP_FUNC void SaveMngSpecial_Stallord2() { gSaveManager.mPracticeFileOpts.inject_options_after_counter = 20; - daB_DS_c* stallord = (daB_DS_c*)fopAcM_SearchByName(246); // stallord proc name - daObjLv4Sand_c* sand = (daObjLv4Sand_c*)fopAcM_SearchByName(189); // sand proc name - - if (stallord != NULL) { - stallord->mBase.mParameters |= 0x2; // make actor phase 2 version - stallord->mAttentionInfo.mFlags = 4; // makes stallord targetable when hit down - stallord->mActionMode1 = 1; // make stallord head active - stallord->mGravity = 0.0f; // change gravity to 0 - g_env_light.mWeatherPalette = 2; // set arena light - sand->speed.y = 1000.0f; // move sand out of the way - - dComIfGs_onOneZoneSwitch(6, stallord->current.roomNo); - dComIfGs_onZoneSwitch(7, stallord->current.roomNo); // sets arena to raised - - stallord->current.pos.x = -2097.20f; //-2397.22f; - stallord->current.pos.y = 1022.21f; // 1697.20f; - stallord->current.pos.z = -1246.87f; // 1131.33f; - - dComIfGp_getPlayer()->current.pos.x = 644.91f; - dComIfGp_getPlayer()->current.pos.y = 300.3158f; - dComIfGp_getPlayer()->current.pos.z = 2195.0237f; - dComIfGp_getPlayer()->shape_angle.y = 39350; - // matrixInfo.matrix_info->target = {865.203f, -1414.390f, 2496.8774f}; - // matrixInfo.matrix_info->pos = {644.438f, -1480.324f, 2194.693f}; - } + daB_DS_c* stallord = (daB_DS_c*)fopAcM_SearchByName(PROC_B_DS); + // create the phase 2 version of stallord + fopAcM_create(PROC_B_DS, fopAcM_GetParam(stallord) | 2, &stallord->current.pos, + fopAcM_GetRoomNo(stallord), nullptr, nullptr, -1); + fopAcM_delete(stallord); // delete phase 1 stallord + + daObjLv4Wall_c* rwall = (daObjLv4Wall_c*)fopAcM_SearchByName(PROC_Obj_Lv4RailWall); + daObjSwSpinner_c* spinnersw = (daObjSwSpinner_c*)fopAcM_SearchByName(PROC_Obj_SwSpinner); + + spinnersw->mRotSpeedY = 3000; // set arena spinner switch to max speed + rwall->field_0x954 = 101; // set spinner switch speed counter to threshold + rwall->mHeight = 3370.0f; // set arena height to max } KEEP_FUNC void SaveMngSpecial_Stallord2_init() { @@ -232,7 +225,7 @@ KEEP_FUNC void SaveMngSpecial_ToTEarlyHP() { gSaveManager.setSaveAngle(0); gSaveManager.setSavePosition(-6626.f, 5250.0f, -5587.f); gSaveManager.setLinkInfo(); - dComIfGs_onSwitch(224, 4); // gate moved to correct pos + dComIfGs_onSwitch(224, 4); // gate moved to correct pos } KEEP_FUNC void SaveMngSpecial_HugoArchery() { @@ -247,10 +240,6 @@ KEEP_FUNC void SaveMngSpecial_CityPoeCycle() { gSaveManager.setLinkInfo(); } -KEEP_FUNC void SaveMngSpecial_AeralfosSkip() { - dComIfGp_getPlayer()->mEquipItem = HOOKSHOT; // clawshot out -} - KEEP_FUNC void SaveMngSpecial_FanTower() { gSaveManager.injectDefault_during(); g_dComIfG_gameInfo.info.mDan.mSwitch[0] = 0; // reset city switches @@ -287,6 +276,7 @@ KEEP_FUNC void BeastGanonSpecial_setLayer() { KEEP_FUNC void SaveMngSpecial_emptyLake() { gSaveManager.injectDefault_during(); setNextStageLayer(4); + bossFlags = 0xFF; } KEEP_FUNC void SaveMngSpecial_NoSQAeralfos() { diff --git a/modules/boot/src/scene.cpp b/modules/boot/src/scene.cpp index ad2f35f2..20e1751b 100644 --- a/modules/boot/src/scene.cpp +++ b/modules/boot/src/scene.cpp @@ -1,26 +1,21 @@ #include "scene.h" +#include "settings.h" #include "libtp_c/include/d/com/d_com_inf_game.h" #include "libtp_c/include/d/meter/d_meter_HIO.h" -SceneItem g_sceneFlags[SCENE_AMNT] = { - {FREEZE_ACTOR_INDEX, false}, {HIDE_ACTOR_INDEX, false}, {DISABLE_BG_INDEX, false}, - {DISABLE_SFX_INDEX, false}, {FREEZE_CAMERA_INDEX, false}, {HIDE_HUD_INDEX, false}, - {FREEZE_TIME_INDEX, false}, -}; - -void GZ_freezeTime() { - if (g_sceneFlags[FREEZE_TIME_INDEX].active) { +KEEP_FUNC void GZ_freezeTime() { + if (GZStng_getData(STNG_SCENE_FREEZE_TIME, false)) { dStage_roomControl_c__setTimePass(TIME_STOP); } } bool l_initCamLock; -void GZ_freezeCamera() { +KEEP_FUNC void GZ_freezeCamera() { l_initCamLock = true; dComIfGp_getEventManager().mCameraPlay = 1; } -void GZ_unfreezeCamera() { +KEEP_FUNC void GZ_unfreezeCamera() { if (l_initCamLock) { dComIfGp_getEventManager().mCameraPlay = 0; l_initCamLock = false; @@ -28,12 +23,12 @@ void GZ_unfreezeCamera() { } bool l_initHide; -void GZ_hideHUD() { +KEEP_FUNC void GZ_hideHUD() { g_drawHIO.mHUDAlpha = 0.0f; l_initHide = true; } -void GZ_showHUD() { +KEEP_FUNC void GZ_showHUD() { if (l_initHide) { g_drawHIO.mHUDAlpha = 1.0f; l_initHide = false; @@ -41,12 +36,12 @@ void GZ_showHUD() { } bool l_initActorFreeze; -void GZ_freezeActors() { +KEEP_FUNC void GZ_freezeActors() { l_initActorFreeze = true; g_dComIfAc_gameInfo.freeze = true; } -void GZ_unfreezeActors() { +KEEP_FUNC void GZ_unfreezeActors() { if (l_initActorFreeze) { g_dComIfAc_gameInfo.freeze = false; l_initActorFreeze = false; @@ -54,12 +49,12 @@ void GZ_unfreezeActors() { } bool l_initActorHide; -void GZ_hideActors() { +KEEP_FUNC void GZ_hideActors() { l_initActorHide = true; fopAc_ac_c__stopStatus |= 0x100; } -void GZ_showActors() { +KEEP_FUNC void GZ_showActors() { if (l_initActorHide) { fopAc_ac_c__stopStatus &= ~0x100; l_initActorHide = false; diff --git a/modules/boot/src/settings.cpp b/modules/boot/src/settings.cpp index f2af183e..3c625ad3 100644 --- a/modules/boot/src/settings.cpp +++ b/modules/boot/src/settings.cpp @@ -1,19 +1,76 @@ #include "settings.h" #include +#include ListMember g_font_opt[] = {"consola", "calamity-bold", "lib-sans", "lib-sans-bold", "lib-serif", "lib-serif-bold", "press-start-2p"}; -bool g_dropShadows; bool g_swap_equips_flag; -uint32_t g_reloadType; -uint32_t g_fontType = 0; -uint32_t g_cursorColorType; + +tpgz::containers::deque g_settings; + +KEEP_FUNC void GZStng_add(GZSettingID id, void* data, size_t size) { + auto it = g_settings.begin(); + for (; it != g_settings.end(); ++it) { + if ((*it)->id == id) { + break; + } + } + if (it == g_settings.end()) { + GZSettingEntry* entry = new GZSettingEntry{id, size, data}; + g_settings.push_back(entry); + } else { + GZSettingEntry* entry = *it; + void* old_data = entry->data; + delete[] (uint8_t*)old_data; + entry->data = data; + entry->size = size; + } +} + +KEEP_FUNC void GZStng_remove(GZSettingID id) { + auto it = g_settings.begin(); + for (; it != g_settings.end(); ++it) { + if ((*it)->id == id) { + break; + } + } + if (it != g_settings.end()) { + auto* entry = *it; + void* data = entry->data; + delete[] (uint8_t*)data; + g_settings.erase(it); + delete entry; + } +} + +KEEP_FUNC GZSettingEntry* GZStng_get(GZSettingID id) { + auto it = g_settings.begin(); + for (; it != g_settings.end(); ++it) { + if ((*it)->id == id) { + break; + } + } + GZSettingEntry* entry = nullptr; + if (it != g_settings.end()) { + entry = *it; + } + return entry; +} + +KEEP_FUNC tpgz::containers::deque* GZStng_getList() { + auto list = new tpgz::containers::deque; + list->resize(g_settings.size()); + std::transform(g_settings.begin(), g_settings.end(), list->begin(), + [](GZSettingEntry* entry) { return entry->id; }); + return list; +} void GZ_initFont() { - if (g_fontType >= 0 && g_fontType < FONT_OPTIONS_COUNT) { + uint32_t fontType = GZStng_getData(STNG_FONT, 0); + if (fontType >= 0 && fontType < FONT_OPTIONS_COUNT) { char buf[40] = {0}; - snprintf(buf, sizeof(buf), "tpgz/fonts/%s.fnt", g_font_opt[g_fontType].member); + snprintf(buf, sizeof(buf), "tpgz/fonts/%s.fnt", g_font_opt[fontType].member); Font::loadFont(buf); } } \ No newline at end of file diff --git a/modules/boot/src/timer.cpp b/modules/boot/src/timer.cpp index 2c157de3..56cb63bd 100644 --- a/modules/boot/src/timer.cpp +++ b/modules/boot/src/timer.cpp @@ -8,101 +8,158 @@ #include "libtp_c/include/f_op/f_op_scene_req.h" #include "rels/include/defines.h" -#if defined(GCN_PAL) || defined(WII_PAL) -#define FRAME_RATE 25 -#else -#define FRAME_RATE 29.97 -#endif - KEEP_FUNC void Timer::drawTimer() { - if (!g_tools[TIMER_INDEX].active) { + static bool init_start_time = false; + static OSTime timer = 0; + static OSTime start_time = 0; + static int frame_timer = 0; + static OSCalendarTime ctime; + + if (!GZStng_getData(STNG_TOOLS_TIMER, false)) { + init_start_time = false; return; } - static int sTimer = 0; - static float sTimerSec = 0.0f; if (g_timerEnabled) { - sTimer++; - sTimerSec = sTimer / FRAME_RATE; + if (!init_start_time) { + start_time = OSGetTime(); + init_start_time = true; + } + + timer = (OSGetTime() - start_time); + OSTicksToCalendarTime(timer, &ctime); + frame_timer++; } if (g_resetTimer) { - sTimer = 0; - sTimerSec = 0.0f; + timer = 0; + start_time = 0; + frame_timer = 0; + init_start_time = false; g_resetTimer = false; g_timerEnabled = false; } char timerF[5] = {0}; - char timerS[8] = {0}; - snprintf(timerF, sizeof(timerF), "%d", sTimer); - snprintf(timerS, sizeof(timerS), "%.2f", sTimerSec); - - Font::GZ_drawStr(timerF, (g_spriteOffsets[TIMER_SPR_INDEX].x), - (g_spriteOffsets[TIMER_SPR_INDEX].y), 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr(timerS, (g_spriteOffsets[TIMER_SPR_INDEX].x), - 15.0f + (g_spriteOffsets[TIMER_SPR_INDEX].y), 0xFFFFFFFF, g_dropShadows); + char timerS[13] = {0}; + snprintf(timerF, sizeof(timerF), "%d", frame_timer); + snprintf(timerS, sizeof(timerS), "%02d:%02d:%02d.%03d", ctime.hours, ctime.minutes, + ctime.seconds, ctime.milliseconds); + + Vec2 spriteOffset = GZ_getSpriteOffset(STNG_SPRITES_TIMER_SPR); + Font::GZ_drawStr(timerF, spriteOffset.x, spriteOffset.y, 0xFFFFFFFF, GZ_checkDropShadows()); + Font::GZ_drawStr(timerS, spriteOffset.x, 15.0f + spriteOffset.y, 0xFFFFFFFF, + GZ_checkDropShadows()); } KEEP_FUNC void Timer::drawIGT() { - if (!g_tools[IGT_TIMER_INDEX].active) { + static bool init_start_time = false; + static bool init_load_starttime = false; + static OSTime timer = 0; + static OSTime start_time = 0; + + static OSTime load_start_time = 0; + static OSTime load_total_time = 0; + static OSTime load_timer = 0; + + static OSCalendarTime ctime; + static OSCalendarTime load_ctime; + + if (!GZStng_getData(STNG_TOOLS_IGT_TIMER, false)) { + init_start_time = false; return; } - static int sTimer = 0; - static int sTimerHour = 0; - static int sTimerMin = 0; - static float sTimerSec = 0.0f; - - if (g_timerEnabled && !fopScnRq.isLoading) { - sTimer++; - sTimerSec = sTimer / FRAME_RATE; - - if (sTimerSec >= 60.0f) { - sTimer = 0; - sTimerMin++; - - if (sTimerMin == 60) { - sTimerMin = 0; - sTimerHour++; + + if (g_timerEnabled) { + if (!init_start_time) { + start_time = OSGetTime(); + init_start_time = true; + } + + if (fopScnRq.isLoading) { + if (!init_load_starttime) { + load_start_time = OSGetTime(); + init_load_starttime = true; + } + + if (init_load_starttime) { + load_timer = OSGetTime() - load_start_time; } + + OSTicksToCalendarTime(load_timer, &load_ctime); + } else { + init_load_starttime = false; + load_total_time += load_timer; + load_timer = 0; + + timer = (OSGetTime() - start_time) - load_total_time; + OSTicksToCalendarTime(timer, &ctime); } } if (g_resetTimer) { - sTimer = 0; - sTimerHour = 0; - sTimerMin = 0; - sTimerSec = 0.0f; + timer = 0; + start_time = 0; + ctime.hours = 0; + ctime.minutes = 0; + ctime.seconds = 0; + ctime.milliseconds = 0; + load_total_time = 0; + init_start_time = false; g_resetTimer = false; g_timerEnabled = false; } char buf[16] = {0}; - snprintf(buf, sizeof(buf), "%02d:%02d:%05.2f", sTimerHour, sTimerMin, sTimerSec); - Font::GZ_drawStr(buf, g_spriteOffsets[IGT_TIMER_SPR_INDEX].x, - g_spriteOffsets[IGT_TIMER_SPR_INDEX].y, 0xFFFFFFFF, g_dropShadows); + snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%03d", ctime.hours, ctime.minutes, ctime.seconds, + ctime.milliseconds); + Vec2 spriteOffset = GZ_getSpriteOffset(STNG_SPRITES_IGT_TIMER_SPR); + Font::GZ_drawStr(buf, spriteOffset.x, spriteOffset.y, 0xFFFFFFFF, GZ_checkDropShadows()); } KEEP_FUNC void Timer::drawLoadTimer() { - if (!g_tools[LOAD_TIMER_INDEX].active) { + static bool init_load_starttime = false; + + static OSTime load_start_time = 0; + static OSTime load_total_time = 0; + static OSTime load_timer = 0; + + static OSCalendarTime load_ctime; + + if (!GZStng_getData(STNG_TOOLS_LOAD_TIMER, false)) { return; } - static int sTimer = 0; - static float sTimerSec = 0.0f; if (fopScnRq.isLoading) { - sTimer++; - sTimerSec = sTimer / FRAME_RATE; + if (!init_load_starttime) { + load_start_time = OSGetTime(); + init_load_starttime = true; + } + + if (init_load_starttime) { + load_timer = OSGetTime() - load_start_time; + } + } else { + init_load_starttime = false; + load_total_time += load_timer; + load_timer = 0; + + OSTicksToCalendarTime(load_total_time, &load_ctime); } if (g_resetTimer) { - sTimer = 0; - sTimerSec = 0.0f; + load_ctime.hours = 0; + load_ctime.minutes = 0; + load_ctime.seconds = 0; + load_ctime.milliseconds = 0; + load_total_time = 0; g_resetTimer = false; + g_timerEnabled = false; } - char buf[8] = {0}; - snprintf(buf, sizeof(buf), "%.2f", sTimerSec); - Font::GZ_drawStr(buf, g_spriteOffsets[LOAD_TIMER_SPR_INDEX].x, - g_spriteOffsets[LOAD_TIMER_SPR_INDEX].y, 0xFFFFFFFF, g_dropShadows); + char buf[16] = {0}; + snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%03d", load_ctime.hours, load_ctime.minutes, + load_ctime.seconds, load_ctime.milliseconds); + Vec2 spriteOffset = GZ_getSpriteOffset(STNG_SPRITES_LOAD_TIMER_SPR); + Font::GZ_drawStr(buf, spriteOffset.x, spriteOffset.y, 0xFFFFFFFF, GZ_checkDropShadows()); } \ No newline at end of file diff --git a/modules/boot/src/tools.cpp b/modules/boot/src/tools.cpp index 5469ecf8..b13dc23b 100644 --- a/modules/boot/src/tools.cpp +++ b/modules/boot/src/tools.cpp @@ -1,16 +1,153 @@ #include "tools.h" +#include "libtp_c/include/d/a/d_a_alink.h" +#include "libtp_c/include/defines.h" + +#include "commands.h" +#include "global_data.h" +#include "settings.h" int g_tunic_color; -Tool g_tools[TOOLS_COUNT] = { - {RELOAD_AREA_INDEX, false}, {FRAME_ADVANCE_INDEX, false}, {FAST_BONK_INDEX, false}, - {FAST_MOVEMENT_INDEX, false}, {GORGE_INDEX, false}, -#ifdef WII_PLATFORM - {BIT_INDEX, false}, -#endif - {COROTD_INDEX, false}, {UMD_INDEX, false}, {INPUT_VIEWER_INDEX, false}, - {LINK_DEBUG_INDEX, false}, {HEAP_DEBUG_INDEX, false}, {SAND_INDEX, false}, - {ROLL_INDEX, false}, {TELEPORT_INDEX, false}, {TURBO_MODE_INDEX, false}, - {TIMER_INDEX, false}, {LOAD_TIMER_INDEX, false}, {IGT_TIMER_INDEX, false}, - {FREE_CAM_INDEX, false}, {MOVE_LINK_INDEX, false}, -}; +KEEP_FUNC void GZ_handleTools() { + if (GZStng_getData(STNG_TOOLS_FRAME_ADVANCE, false) && !GZCmd_getCmd(CMD_FRAME_PAUSE)) { + GZCmd_addCmd( + new Command{CMD_FRAME_PAUSE, + GZStng_getData(STNG_CMD_FRAME_PAUSE, FRAME_PAUSE_BUTTONS), + GZCmd_pauseFrame}); + } else if (!GZStng_getData(STNG_TOOLS_FRAME_ADVANCE, false) && + GZCmd_getCmd(CMD_FRAME_PAUSE)) { + auto* cmd = GZCmd_removeCmd(CMD_FRAME_PAUSE); + delete cmd; + } + + if (!(GZStng_getData(STNG_TOOLS_TIMER, false) || + GZStng_getData(STNG_TOOLS_IGT_TIMER, false)) && + GZCmd_getCmd(CMD_TIMER_TOGGLE)) { + auto* cmd = GZCmd_removeCmd(CMD_TIMER_TOGGLE); + delete cmd; + } + + if (!(GZStng_getData(STNG_TOOLS_TIMER, false) || + GZStng_getData(STNG_TOOLS_IGT_TIMER, false) || + GZStng_getData(STNG_TOOLS_LOAD_TIMER, false)) && + GZCmd_getCmd(CMD_TIMER_RESET)) { + auto* cmd = GZCmd_removeCmd(CMD_TIMER_RESET); + delete cmd; + } + + if ((GZStng_getData(STNG_TOOLS_TIMER, false) || + GZStng_getData(STNG_TOOLS_IGT_TIMER, false)) && + !GZCmd_getCmd(CMD_TIMER_TOGGLE)) { + GZCmd_addCmd(new Command{ + CMD_TIMER_TOGGLE, + GZStng_getData(STNG_CMD_TIMER_TOGGLE, TIMER_TOGGLE_BUTTONS), + GZCmd_toggleTimer}); + } + + if ((GZStng_getData(STNG_TOOLS_TIMER, false) || + GZStng_getData(STNG_TOOLS_IGT_TIMER, false) || + GZStng_getData(STNG_TOOLS_LOAD_TIMER, false)) && + !GZCmd_getCmd(CMD_TIMER_RESET)) { + GZCmd_addCmd( + new Command{CMD_TIMER_RESET, + GZStng_getData(STNG_CMD_TIMER_RESET, TIMER_RESET_BUTTONS), + GZCmd_resetTimer}); + } + + if (GZStng_getData(STNG_TOOLS_TELEPORT, false) && !GZCmd_getCmd(CMD_STORE_POSITION)) { + GZCmd_addCmd(new Command{ + CMD_STORE_POSITION, + GZStng_getData(STNG_CMD_STORE_POSITION, STORE_POSITION_BUTTONS), + GZCmd_storePosition}); + } else if (!GZStng_getData(STNG_TOOLS_TELEPORT, false) && + GZCmd_getCmd(CMD_STORE_POSITION)) { + auto* cmd = GZCmd_removeCmd(CMD_STORE_POSITION); + delete cmd; + } + + if (GZStng_getData(STNG_TOOLS_TELEPORT, false) && !GZCmd_getCmd(CMD_LOAD_POSITION)) { + GZCmd_addCmd(new Command{ + CMD_LOAD_POSITION, + GZStng_getData(STNG_CMD_LOAD_POSITION, LOAD_POSITION_BUTTONS), + GZCmd_loadPosition}); + } else if (!GZStng_getData(STNG_TOOLS_TELEPORT, false) && + GZCmd_getCmd(CMD_LOAD_POSITION)) { + auto* cmd = GZCmd_removeCmd(CMD_LOAD_POSITION); + delete cmd; + } + + if (GZStng_getData(STNG_TOOLS_RELOAD_AREA, false) && !GZCmd_getCmd(CMD_RELOAD_AREA)) { + GZCmd_addCmd( + new Command{CMD_RELOAD_AREA, + GZStng_getData(STNG_CMD_RELOAD_AREA, RELOAD_AREA_BUTTONS), + GZCmd_reloadArea}); + } else if (!GZStng_getData(STNG_TOOLS_RELOAD_AREA, false) && + GZCmd_getCmd(CMD_RELOAD_AREA)) { + auto* cmd = GZCmd_removeCmd(CMD_RELOAD_AREA); + delete cmd; + } + + if (GZStng_getData(STNG_TOOLS_FREE_CAM, false) && !GZCmd_getCmd(CMD_FREE_CAM)) { + GZCmd_addCmd(new Command{ + CMD_FREE_CAM, GZStng_getData(STNG_CMD_FREE_CAM, FREE_CAM_BUTTONS), + GZCmd_toggleFreeCam}); + g_freeCamEnabled = false; + } else if (!GZStng_getData(STNG_TOOLS_FREE_CAM, false) && GZCmd_getCmd(CMD_FREE_CAM)) { + auto* cmd = GZCmd_removeCmd(CMD_FREE_CAM); + delete cmd; + g_freeCamEnabled = false; + } + + if (GZStng_getData(STNG_TOOLS_MOVE_LINK, false) && !GZCmd_getCmd(CMD_MOVE_LINK)) { + GZCmd_addCmd(new Command{ + CMD_MOVE_LINK, GZStng_getData(STNG_CMD_MOVE_LINK, MOVE_LINK_BUTTONS), + GZCmd_toggleMoveLink}); + g_moveLinkEnabled = false; + } else if (!GZStng_getData(STNG_TOOLS_MOVE_LINK, false) && GZCmd_getCmd(CMD_MOVE_LINK)) { + auto* cmd = GZCmd_removeCmd(CMD_MOVE_LINK); + delete cmd; + g_moveLinkEnabled = false; + } + + if (GZStng_getData(STNG_TOOLS_FAST_MOVEMENT, false)) { + daAlinkHIO_frontRoll.mSpeedRate = 3.0f; + daAlinkHIO_swim.mMaxUnderwaterSpeed = 50; + daAlinkHIO_swim.mMaxBackwardSpeed = 50; + daAlinkHIO_swim.mMaxStrafeSpeed = 50; + daAlinkHIO_swim.mDashMaxSpeed = 50; + daAlinkHIO_swim.mMaxForwardSpeed = 50; + daAlinkHIO_swim.mUnderwaterMaxSinkSpeed = 50; + daAlinkHIO_swim.mBootsMaxSinkSpeed = -50; + daAlinkHIO_swim.mBootsGravity = -50; + daAlinkHIO_wlMove.mDashInitSpeed = 100; + daAlinkHIO_wlMove.mDashMaxSpeed = 100; + daAlinkHIO_wlMove.mDashInitSpeedSlow = 70; + daAlinkHIO_wlMove.mDashMaxSpeedSlow = 70; + daAlinkHIO_wlSwim.mMaxSpeed = 50; + daAlinkHIO_wlSwim.mMaxSpeedWeak = 50; + } else { + daAlinkHIO_frontRoll.mSpeedRate = 1.3; + daAlinkHIO_swim.mMaxUnderwaterSpeed = 12; + daAlinkHIO_swim.mMaxForwardSpeed = 8; + daAlinkHIO_swim.mMaxBackwardSpeed = 6; + daAlinkHIO_swim.mMaxStrafeSpeed = 8; + daAlinkHIO_swim.mDashMaxSpeed = 13; + daAlinkHIO_swim.mUnderwaterMaxSinkSpeed = 8; + daAlinkHIO_swim.mBootsMaxSinkSpeed = -20; + daAlinkHIO_swim.mBootsGravity = -0.699999988; + daAlinkHIO_wlMove.mDashInitSpeed = 65; + daAlinkHIO_wlMove.mDashMaxSpeed = 45; + daAlinkHIO_wlMove.mDashInitSpeedSlow = 35; + daAlinkHIO_wlMove.mDashMaxSpeedSlow = 33; + daAlinkHIO_wlSwim.mMaxSpeed = 20; + daAlinkHIO_wlSwim.mMaxSpeedWeak = 9; + } + + if (GZStng_getData(STNG_TOOLS_FAST_BONK, false)) { + daAlinkHIO_frontRoll.mCrashAnm.mStartFrame = 50.0f; + daAlinkHIO_frontRoll.mCrashAnm.mSpeed = 0.0f; + } else { + daAlinkHIO_frontRoll.mCrashAnm.mStartFrame = 3.0f; + daAlinkHIO_frontRoll.mCrashAnm.mSpeed = 0.8f; + } +} \ No newline at end of file diff --git a/modules/boot/src/utils/audio.cpp b/modules/boot/src/utils/audio.cpp index ca79bd1d..2e9b4cd5 100644 --- a/modules/boot/src/utils/audio.cpp +++ b/modules/boot/src/utils/audio.cpp @@ -1,6 +1,6 @@ #include "utils/audio.h" -void GZ_enableBGM() { +KEEP_FUNC void GZ_enableBGM() { g_mDoAud_zelAudio.mAudioMgr.mSeqMgr.mHeightVol.mIntensity = 1.0f; // BG Audio #ifndef WII_PLATFORM g_mDoAud_zelAudio.mAudioMgr.mSoundMgr.mSeqMgr.mMove.mParams.mVolume = 1.0f; @@ -8,7 +8,7 @@ void GZ_enableBGM() { #endif } -void GZ_disableBGM() { +KEEP_FUNC void GZ_disableBGM() { g_mDoAud_zelAudio.mAudioMgr.mSeqMgr.mHeightVol.mIntensity = 0.0f; // BG Audio #ifndef WII_PLATFORM g_mDoAud_zelAudio.mAudioMgr.mSoundMgr.mSeqMgr.mMove.mParams.mVolume = 0.0f; @@ -16,7 +16,7 @@ void GZ_disableBGM() { #endif } -void GZ_disableSFX() { +KEEP_FUNC void GZ_disableSFX() { for (int i = 0; i < 16; i++) { g_mDoAud_zelAudio.mAudioMgr.mSoundMgr.mSeMgr.mCategoryMgrs[i].mParams.mParams.mVolume = 0.0f; @@ -25,7 +25,7 @@ void GZ_disableSFX() { g_mDoAud_zelAudio.mAudioMgr.mSoundMgr.mSeMgr.mParams.mParams.mVolume = 0.0f; } -void GZ_enableSFX() { +KEEP_FUNC void GZ_enableSFX() { for (int i = 0; i < 16; i++) { g_mDoAud_zelAudio.mAudioMgr.mSoundMgr.mSeMgr.mCategoryMgrs[i].mParams.mParams.mVolume = 1.0f; diff --git a/modules/boot/src/utils/card.cpp b/modules/boot/src/utils/card.cpp index 358c94ee..67da2e20 100644 --- a/modules/boot/src/utils/card.cpp +++ b/modules/boot/src/utils/card.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include "commands.h" #include "settings.h" #include "fifo_queue.h" @@ -17,6 +19,8 @@ #include "rels/include/cxx.h" #include "menus/utils/menu_mgr.h" #include "rels/include/defines.h" +#include "events/pre_loop_listener.h" +#include "boot.h" #ifdef WII_PLATFORM KEEP_VAR void* g_tmpBuf; @@ -73,30 +77,57 @@ int32_t GZ_storageRead(Storage* storage, void* data, int32_t size, int32_t offse return result; } -void GZ_storeSaveLayout(GZSaveLayout& save_layout) { - memcpy(save_layout.mCheats, g_cheats, sizeof(g_cheats)); - memcpy(save_layout.mTools, g_tools, sizeof(g_tools)); - memcpy(save_layout.mSceneFlags, g_sceneFlags, sizeof(g_sceneFlags)); - memcpy(save_layout.mWatches, g_watches, sizeof(g_watches)); - memcpy(save_layout.mSpriteOffsets, g_spriteOffsets, sizeof(g_spriteOffsets)); - memcpy(save_layout.mCommandStates, g_commandStates, sizeof(g_commandStates)); - save_layout.mDropShadows = g_dropShadows; - save_layout.mReloadType = g_reloadType; - save_layout.mCursorColType = g_cursorColorType; - save_layout.mFontType = g_fontType; +/** + * @brief Stores the settings in a new buffer. + * @param save_file The save file to fetch the metadata from. + * @return The buffer containing the settings. + */ +void GZ_storeSettings(GZSaveFile& save_file, void* data) { + if (save_file.header.data_size == 0) { + return; + } + uint32_t pos = 0; + for (auto& entry : g_settings) { + memcpy((void*)((uint32_t)data + pos), &entry->id, sizeof(GZSettingID)); + pos += sizeof(GZSettingID); + memcpy((void*)((uint32_t)data + pos), &entry->size, sizeof(size_t)); + pos += sizeof(size_t); + if (entry->size > 0 && entry->data) { + memcpy((void*)((uint32_t)data + pos), entry->data, entry->size); + } + pos += entry->size; + } } -void GZ_loadSaveLayout(GZSaveLayout& save_layout) { - memcpy(g_cheats, save_layout.mCheats, sizeof(g_cheats)); - memcpy(g_tools, save_layout.mTools, sizeof(g_tools)); - memcpy(g_sceneFlags, save_layout.mSceneFlags, sizeof(g_sceneFlags)); - memcpy(g_watches, save_layout.mWatches, sizeof(g_watches)); - memcpy(g_spriteOffsets, save_layout.mSpriteOffsets, sizeof(g_spriteOffsets)); - memcpy(g_commandStates, save_layout.mCommandStates, sizeof(g_commandStates)); - g_dropShadows = save_layout.mDropShadows; - g_reloadType = save_layout.mReloadType; - g_cursorColorType = save_layout.mCursorColType; - g_fontType = save_layout.mFontType; +/** + * @brief Loads the settings from a buffer. + * @param save_file The save file to fetch the metadata from. + * @param data The buffer containing the settings. + */ +void GZ_loadSettings(GZSaveFile save_file, void* data) { + uint32_t pos = 0; + for (uint32_t i = 0; i < save_file.header.entries; i++) { + GZSettingID id; + size_t size; + memcpy(&id, (void*)((uint32_t)data + pos), sizeof(GZSettingID)); + pos += sizeof(GZSettingID); + memcpy(&size, (void*)((uint32_t)data + pos), sizeof(size_t)); + pos += sizeof(size_t); + GZSettingEntry* entry = GZStng_get(id); + if (entry == nullptr) { + entry = new GZSettingEntry{id, size, size > 0 ? new uint8_t[size] : nullptr}; + g_settings.push_back(entry); + } else { + void* old_data = entry->data; + if (old_data) { + delete[] (uint8_t*)old_data; + } + entry->data = size > 0 ? new uint8_t[size] : nullptr; + entry->size = size; + } + memcpy(entry->data, (void*)((uint32_t)data + pos), size); + pos += size; + } } void GZ_loadPositionData(PositionData& pos_data) { @@ -106,26 +137,17 @@ void GZ_loadPositionData(PositionData& pos_data) { memfile_posdata.angle = pos_data.angle; } +/** + * @brief Setup the save file header. + * @param save_file The save file to setup. + */ void GZ_setupSaveFile(GZSaveFile& save_file) { save_file.header.version = GZ_SAVE_VERSION_NUMBER; - save_file.header.entries = GZ_SAVE_ENTRIES_AMNT; - save_file.header.offsetsLoc = offsetof(GZSaveFile, offsets); - save_file.header.sizesLoc = offsetof(GZSaveFile, sizes); -#define set_entry(idx, attr) \ - save_file.offsets[idx] = offsetof(GZSaveFile, data) + offsetof(GZSaveLayout, attr); \ - save_file.sizes[idx] = sizeof(save_file.data.attr) - - set_entry(SV_CHEATS_INDEX, mCheats); - set_entry(SV_TOOLS_INDEX, mTools); - set_entry(SV_SCENE_INDEX, mSceneFlags); - set_entry(SV_WATCHES_INDEX, mWatches); - set_entry(SV_SPRITES_INDEX, mSpriteOffsets); - set_entry(SV_COMMANDS, mCommandStates); - set_entry(SV_DROP_SHADOW_INDEX, mDropShadows); - set_entry(SV_AREA_RELOAD_INDEX, mReloadType); - set_entry(SV_CURSOR_COLOR_INDEX, mCursorColType); - set_entry(SV_FONT_INDEX, mFontType); -#undef set_entry + save_file.header.entries = g_settings.size(); + save_file.header.data_size = + std::transform_reduce(g_settings.begin(), g_settings.end(), (size_t)0, std::plus{}, + [](GZSettingEntry* entry) { return entry->size; }) + + (sizeof(GZSettingID) + sizeof(size_t)) * g_settings.size(); } int32_t GZ_readSaveFile(Storage* storage, GZSaveFile& save_file, int32_t sector_size) { @@ -142,35 +164,26 @@ int32_t GZ_readSaveFile(Storage* storage, GZSaveFile& save_file, int32_t sector_ if (save_file.header.version != GZ_SAVE_VERSION_NUMBER) { return -30; // Custom error code for "Version" (means a mismatch in the version number). } - assert_result(GZ_storageRead(storage, save_file.offsets, - save_file.header.entries * sizeof(save_file.offsets[0]), - save_file.header.offsetsLoc, sector_size)); - assert_result(GZ_storageRead(storage, save_file.sizes, - save_file.header.entries * sizeof(save_file.sizes[0]), - save_file.header.sizesLoc, sector_size)); - -#define assert_read_entry(idx, ptr, size) \ - if (idx < save_file.header.entries) { \ - assert_result(GZ_storageRead(storage, ptr, MIN(size, save_file.sizes[idx]), \ - save_file.offsets[idx], sector_size)); \ + uint8_t* data = nullptr; + if (save_file.header.data_size > 0) { + data = new uint8_t[save_file.header.data_size]; + assert_result(GZ_storageRead(storage, data, save_file.header.data_size, pos, sector_size)); + } + + // Clear the settings before loading the saved ones. + for (auto& entry : g_settings) { + delete[] (uint8_t*)entry->data; + delete entry; } - assert_read_entry(SV_CHEATS_INDEX, save_file.data.mCheats, sizeof(save_file.data.mCheats)); - assert_read_entry(SV_TOOLS_INDEX, save_file.data.mTools, sizeof(save_file.data.mTools)); - assert_read_entry(SV_SCENE_INDEX, save_file.data.mSceneFlags, - sizeof(save_file.data.mSceneFlags)); - assert_read_entry(SV_WATCHES_INDEX, save_file.data.mWatches, sizeof(save_file.data.mWatches)); - assert_read_entry(SV_SPRITES_INDEX, save_file.data.mSpriteOffsets, - sizeof(save_file.data.mSpriteOffsets)); - assert_read_entry(SV_COMMANDS, save_file.data.mCommandStates, - sizeof(save_file.data.mCommandStates)); - assert_read_entry(SV_DROP_SHADOW_INDEX, &save_file.data.mDropShadows, - sizeof(save_file.data.mDropShadows)); - assert_read_entry(SV_AREA_RELOAD_INDEX, &save_file.data.mReloadType, - sizeof(save_file.data.mReloadType)); - assert_read_entry(SV_CURSOR_COLOR_INDEX, &save_file.data.mCursorColType, - sizeof(save_file.data.mCursorColType)); - assert_read_entry(SV_FONT_INDEX, &save_file.data.mFontType, sizeof(save_file.data.mFontType)); -#undef assert_read_entry + + g_settings.clear(); + + GZ_loadSettings(save_file, data); + + if (data != nullptr) { + delete[] data; + } + #undef assert_result return result; @@ -195,16 +208,19 @@ KEEP_FUNC int32_t GZ_readMemfile(Storage* storage, PositionData& posData, int32_ KEEP_FUNC void GZ_storeMemCard(Storage& storage) { GZSaveFile save_file; GZ_setupSaveFile(save_file); - GZ_storeSaveLayout(save_file.data); - uint32_t file_size = (uint32_t)(ceil((double)sizeof(save_file) / (double)storage.sector_size) * - storage.sector_size); + uint32_t file_size = sizeof(save_file) + save_file.header.data_size; + uint8_t* data = new uint8_t[file_size]; + memcpy(data, &save_file.header, sizeof(save_file.header)); + GZ_storeSettings(save_file, &data[sizeof(save_file.header)]); + // Align the file size to the sector size. + file_size = (uint32_t)(ceil((double)sizeof(save_file) / (double)storage.sector_size) * + storage.sector_size); storage.result = StorageDelete(0, storage.file_name_buffer); storage.result = StorageCreate(0, storage.file_name_buffer, file_size, &storage.info); if (storage.result == Ready || storage.result == Exist) { storage.result = StorageOpen(0, storage.file_name_buffer, &storage.info, OPEN_MODE_RW); if (storage.result == Ready) { - storage.result = - GZ_storageWrite(&storage, &save_file, sizeof(save_file), 0, storage.sector_size); + storage.result = GZ_storageWrite(&storage, data, file_size, 0, storage.sector_size); if (storage.result == Ready) { OSReport("saved card!\n"); FIFOQueue::push("saved card!", Queue); @@ -217,6 +233,9 @@ KEEP_FUNC void GZ_storeMemCard(Storage& storage) { storage.result = StorageClose(&storage.info); } } + if (data != nullptr) { + delete[] (uint8_t*)data; + } } KEEP_FUNC void GZ_storeMemfile(Storage& storage) { @@ -281,11 +300,9 @@ KEEP_FUNC void GZ_loadMemCard(Storage& storage) { storage.result = StorageOpen(0, storage.file_name_buffer, &storage.info, OPEN_MODE_RW); if (storage.result == Ready) { GZSaveFile save_file; - GZ_storeSaveLayout(save_file.data); storage.result = GZ_readSaveFile(&storage, save_file, storage.sector_size); if (storage.result == Ready) { FIFOQueue::push("loaded card!", Queue); - GZ_loadSaveLayout(save_file.data); GZ_initFont(); } else { char buff[32]; @@ -296,6 +313,21 @@ KEEP_FUNC void GZ_loadMemCard(Storage& storage) { } } +KEEP_FUNC bool GZ_memfileExists(Storage& storage) { +#ifndef WII_PLATFORM + storage.result = CARDProbeEx(0, NULL, &storage.sector_size); + if (storage.result != Ready) { + return false; + } +#endif // WII_PLATFORM + storage.result = StorageOpen(0, storage.file_name_buffer, &storage.info, OPEN_MODE_READ); + if (storage.result == Ready) { + storage.result = StorageClose(&storage.info); + return true; + } + return false; +} + KEEP_FUNC void GZ_loadMemfile(Storage& storage) { storage.result = StorageOpen(0, storage.file_name_buffer, &storage.info, OPEN_MODE_RW); if (storage.result == Ready) { @@ -338,4 +370,7 @@ KEEP_FUNC void GZ_loadGZSave(bool& card_load) { card_load = false; } + if (frame_count > FRAME_COUNT) { + g_PreLoopListener->removeListener(GZ_handleCardLoad); + } } \ No newline at end of file diff --git a/modules/boot/src/utils/cursor.cpp b/modules/boot/src/utils/cursor.cpp index a6662d67..1baf0a64 100644 --- a/modules/boot/src/utils/cursor.cpp +++ b/modules/boot/src/utils/cursor.cpp @@ -16,7 +16,7 @@ KEEP_FUNC void Cursor::move(int max_x, int max_y) { } if (!lock_y) { - y > 0 ? y-- : y = max_y - 1; + --y; } } @@ -26,7 +26,7 @@ KEEP_FUNC void Cursor::move(int max_x, int max_y) { } if (!lock_y) { - y < max_y - 1 ? y++ : y = 0; + ++y; } } @@ -38,7 +38,7 @@ KEEP_FUNC void Cursor::move(int max_x, int max_y) { y = max_y - 1; } } else if (!lock_x) { - x < max_x - 1 ? x++ : x = 0; + ++x; } } @@ -50,9 +50,13 @@ KEEP_FUNC void Cursor::move(int max_x, int max_y) { y = 0; } } else if (!lock_x) { - x > 0 ? x-- : x = max_x - 1; + --x; } } + + // wrap around + x = (x + max_x) % max_x; + y = (y + max_y) % max_y; } KEEP_FUNC void Cursor::reset() { @@ -72,25 +76,12 @@ KEEP_FUNC void Cursor::setMode(uint8_t m) { mode = m; } +uint32_t l_cursorMapping[] = {0x00CC00FF, 0x0080FFFF, 0xCC0000FF, + 0xEE8000FF, 0xFFCC00FF, 0x6600CCFF}; + KEEP_FUNC void GZ_setCursorColor() { - switch (g_cursorColorType) { - case CURSOR_GREEN: - g_cursorColor = 0x00CC00FF; - break; - case CURSOR_BLUE: - g_cursorColor = 0x0080FFFF; - break; - case CURSOR_RED: - g_cursorColor = 0xCC0000FF; - break; - case CURSOR_ORANGE: - g_cursorColor = 0xEE8000FF; - break; - case CURSOR_YELLOW: - g_cursorColor = 0xFFCC00FF; - break; - case CURSOR_PURPLE: - g_cursorColor = 0x6600CCFF; - break; + uint32_t colorId = GZStng_getData(STNG_CURSOR_COLOR, 0); + if (colorId < ARRAY_COUNT(l_cursorMapping)) { + g_cursorColor = l_cursorMapping[colorId]; } } diff --git a/modules/boot/src/utils/draw.cpp b/modules/boot/src/utils/draw.cpp index 729fb233..d686f094 100644 --- a/modules/boot/src/utils/draw.cpp +++ b/modules/boot/src/utils/draw.cpp @@ -1,7 +1,5 @@ #include "utils/draw.h" -#include "libtp_c/include/addrs.h" #include "libtp_c/include/m_Do/m_Do_printf.h" -#include "gcn_c/include/gfx.h" #include "utils/texture.h" #include "rels/include/defines.h" @@ -30,8 +28,8 @@ KEEP_FUNC void begin(uint16_t n, GXTexObj* tex) { } KEEP_FUNC void begin(uint16_t n, uint8_t primitive, GXTexObj* tex) { - GXLoadTexObj(tex, (uint8_t)GX_TEXMAP0); - GXBegin(primitive, GX_VTXFMT0, n); + GXLoadTexObj(tex, GX_TEXMAP0); + GXBegin((GXPrimitive)primitive, GX_VTXFMT0, n); } KEEP_FUNC void begin_outline(uint16_t n) { @@ -39,7 +37,7 @@ KEEP_FUNC void begin_outline(uint16_t n) { } KEEP_FUNC void begin_outline(uint16_t n, uint8_t width) { - GXLoadTexObj(&blankTex._texObj, (uint8_t)GX_TEXMAP0); + GXLoadTexObj(&blankTex._texObj, GX_TEXMAP0); GXSetLineWidth(width, GX_TO_ZERO); GXBegin(GX_LINESTRIP, GX_VTXFMT0, n); } diff --git a/modules/boot/src/utils/hook.cpp b/modules/boot/src/utils/hook.cpp index 6c735f26..397ac53b 100644 --- a/modules/boot/src/utils/hook.cpp +++ b/modules/boot/src/utils/hook.cpp @@ -3,17 +3,21 @@ #include "cheats.h" #include "controller.h" #include "boot.h" -#include "libtp_c/include/addrs.h" #include "rels/include/patch.h" #include "flaglog.h" #include "fifo_queue.h" #include "libtp_c/include/d/com/d_com_inf_game.h" +#include "libtp_c/include/SSystem/SComponent/c_lib.h" #include "utils/card.h" #include "global_data.h" #include "memfiles.h" #include "rels/include/cxx.h" #include "rels/include/defines.h" #include "save_manager.h" +#include "settings.h" +#include "collision_view.h" +#include "features/projection_view/include/projection_view.h" +#include "libtp_c/include/m_Do/m_Do_printf.h" #define HOOK_DEF(rettype, name, params) \ typedef rettype(*tp_##name##_t) params; \ @@ -30,31 +34,11 @@ HOOK_DEF(void, draw, (void*)); #define PAD_READ_RETURN_OFFSET (0x2DC) #endif -#ifdef GCN_NTSCU -#define CRASH_ADDRESS (0x80450580) -#endif -#ifdef GCN_PAL -#define CRASH_ADDRESS (0x80452540) -#endif -#ifdef GCN_NTSCJ -#define CRASH_ADDRESS (0x8044A6C0) -#endif -#ifdef WII_NTSCU_10 -#define CRASH_ADDRESS (0x80537560) -#endif -#ifdef WII_NTSCU_12 -#define CRASH_ADDRESS (0x8051d5e0) -#endif -#ifdef WII_NTSCJ -#define CRASH_ADDRESS (0x8051b460) -#endif -#ifdef WII_PAL -#define CRASH_ADDRESS (0x8051DEE0) -#endif +extern volatile uint32_t gzCrashReport; HOOK_DEF(uint32_t, PADRead, (uint16_t*)); HOOK_DEF(uint32_t, checkHookshotStickBG, (void*, void*)); -HOOK_DEF(void, setSpecialGravity, (float, float, int)); +HOOK_DEF(void, setSpecialGravity, (daAlink_c*, float, float, int)); HOOK_DEF(uint32_t, checkCastleTownUseItem, (uint16_t)); HOOK_DEF(uint32_t, query042, (void*, void*, int)); @@ -63,12 +47,18 @@ HOOK_DEF(void, offEventBit, (void*, uint16_t)); HOOK_DEF(void, onSwitch, (void*, int, int)); HOOK_DEF(void, putSave, (void*, int)); -HOOK_DEF(void, dCcS__draw, (void)); +HOOK_DEF(void, dCcS__draw, (dCcS*)); HOOK_DEF(void, BeforeOfPaint, (void)); +HOOK_DEF(void, dCcS__MoveAfterCheck, (dCcS*)); + HOOK_DEF(int, dScnPly__phase_1, (void*)); HOOK_DEF(int, dScnPly__phase_4, (void*)); +HOOK_DEF(void, dBgS_Acch__CrrPos, (dBgS_Acch*, dBgS&)); +HOOK_DEF(void, daAlink_c__setCutJumpSpeed, (daAlink_c*, int)); +HOOK_DEF(void, daAlink_c__posMove, (daAlink_c*)); + namespace Hook { void gameLoopHook(void) { game_loop(); @@ -84,9 +74,9 @@ void drawHook(void* p1) { #ifdef PR_TEST void myExceptionCallbackHook(void) { ExceptionCallbackTrampoline(); - *reinterpret_cast(CRASH_ADDRESS) = 1; - DCFlushRange((void*)(CRASH_ADDRESS), sizeof(uint32_t)); - ICInvalidateRange((void*)(CRASH_ADDRESS), sizeof(uint32_t)); + gzCrashAddr = 1; + DCFlushRange((void*)(&gzCrashAddr), sizeof(gzCrashAddr)); + ICInvalidateRange((void*)(&gzCrashAddr), sizeof(gzCrashAddr)); } #endif // PR_TEST @@ -97,23 +87,23 @@ uint32_t readControllerHook(uint16_t* p1) { } uint32_t superClawshotHook(void* p1, void* p2) { - if (g_cheats[SuperClawshot].active) { + if (GZ_checkCheat(STNG_CHEATS_SUPER_CLAWSHOT)) { return 1; } else { return checkHookshotStickBGTrampoline(p1, p2); } } -void disableGravityHook(float p1, float p2, int p3) { - if (g_moveLinkEnabled) { - return setSpecialGravityTrampoline(0.0f, p2, p3); +void disableGravityHook(daAlink_c* i_this, float p1, float p2, int p3) { + if (g_moveLinkEnabled || g_actorViewEnabled) { + return setSpecialGravityTrampoline(i_this, 0.0f, p2, p3); } else { - return setSpecialGravityTrampoline(p1, p2, p3); + return setSpecialGravityTrampoline(i_this, p1, p2, p3); } } uint32_t unrestrictedItemsHook(uint16_t p1) { - if (g_cheats[UnrestrictedItems].active) { + if (GZ_checkCheat(STNG_CHEATS_UNRESTRICTED_ITEMS)) { return 1; } else { return checkCastleTownUseItemTrampoline(p1); @@ -121,7 +111,7 @@ uint32_t unrestrictedItemsHook(uint16_t p1) { } uint32_t transformAnywhereHook(void* p1, void* p2, int p3) { - if (g_cheats[TransformAnywhere].active) { + if (GZ_checkCheat(STNG_CHEATS_TRANSFORM_ANYWHERE)) { return 0; } else { return query042Trampoline(p1, p2, p3); @@ -200,7 +190,7 @@ int endSaveInjectHook(void* i_scene) { if (SaveManager::s_injectSave || SaveManager::s_injectMemfile) { if (gSaveManager.mPracticeFileOpts.inject_options_after_load) { - SaveManager::s_applyAfterTimer = 30; + SaveManager::s_applyAfterTimer = 5; } SaveManager::s_injectSave = false; @@ -210,6 +200,184 @@ int endSaveInjectHook(void* i_scene) { return rt; } +void dCcSDrawHook(dCcS* i_this) { + GZ_drawCc(i_this); + return dCcS__drawTrampoline(i_this); +} + +void beforeOfPaintHook() { + BeforeOfPaintTrampoline(); + dDbVw_deleteDrawPacketList(); +} + +void dCcSMoveAfterCheckHook(dCcS* i_this) { + dCcS_Data::at_obj_count = i_this->mObjAtCount; + dCcS_Data::tg_obj_count = i_this->mObjTgCount; + dCcS_Data::co_obj_count = i_this->mObjCoCount; + return dCcS__MoveAfterCheckTrampoline(i_this); +} + +void dBgS_AcchCrrPosHook(dBgS_Acch* i_this, dBgS& i_bgs) { + dBgS_Acch__CrrPosTrampoline(i_this, i_bgs); + if (g_actorViewEnabled/* || g_moveLinkEnabled */) { + i_this->m_flags = dBgS_Acch::GROUND_HIT; // sets actor to always be in "coliding with ground" state + } +} + +void daAlink_c__setCutJumpSpeedHook(daAlink_c* i_this, int i_air) { + daAlink_c__setCutJumpSpeedTrampoline(i_this, i_air); +} + +void setupLJAProjectionLine(daAlink_c* i_this) { + bool got_it = false; + + // if we haven't done the jump attack yet + if (i_this->mActionID == daAlink_c::PROC_ATN_ACTOR_WAIT) { + // lifted from procCutJumpInit + i_this->mNormalSpeed = 25.0f; + i_this->speed.y = 27.0f; + daAlink_c__setCutJumpSpeedTrampoline(i_this, 0); // Calculate jump speed (LJA set here) + i_this->current.angle.y = i_this->shape_angle.y; + } + + // store next 20 future projected positions + for (int i = 0; i < 40; i++) { + if (i_this->mNormalSpeed > 70.0f) { + got_it = true; + } + daAlink_c__posMoveTrampoline(i_this); + g_ljaProjectionLine.pos[i] = i_this->current.pos; + g_ljaProjectionLine.got_it = got_it; + } +} + +void setupMidnaChargeProjectionLine(daAlink_c* i_this) { + if (i_this->mActionID == daAlink_c::PROC_WOLF_ROLL_ATTACK_MOVE) { + // this is logic from procWolfLockAttackInit + fopAc_ac_c* lock_actor = i_this->mWolfLockAcKeep[0].getActor(); + if (lock_actor != NULL) { + i_this->field_0x37c8 = lock_actor->mEyePos; + } + i_this->shape_angle.y = cLib_targetAngleY(&i_this->current.pos,&i_this->field_0x37c8); + i_this->current.angle.y = i_this->shape_angle.y; + cXyz l_eyePosDelta = i_this->field_0x37c8 - i_this->mEyePos; + + if (l_eyePosDelta.y < 10.0f) { + l_eyePosDelta.y = 10.0f; + } else { + if (l_eyePosDelta.y > 700.0f) + l_eyePosDelta.y = 700.0f; + } + + f32 tmp_f = l_eyePosDelta.absXZ(); + + if (tmp_f > 1000.0f) { + f32 tmp = 1000.0f / tmp_f; + l_eyePosDelta.x *= tmp; + l_eyePosDelta.z *= tmp; + } + + f32 abs = l_eyePosDelta.abs() / 85.0f; + + if (abs < 1.0f) + abs = 1.0f; + + f32 check_frame = 85.0f / l_eyePosDelta.abs(); + i_this->mNormalSpeed = check_frame * l_eyePosDelta.absXZ(); + setSpecialGravityTrampoline(i_this,(l_eyePosDelta.y * -2.0f) / (abs * abs), i_this->mMaxFallSpeed, 0); + i_this->speed.y = -i_this->mGravity * abs; + + for (int i = 0; i < 40; i++) { + daAlink_c__posMoveTrampoline(i_this); + g_midnaChargeProjectionLine.pos[i] = i_this->current.pos; + + // this is logic from procWolfLockAttack (is this actually required?) + // if (i_this->field_0x3008 != 0) { + // i_this->field_0x3008--; + + // if (i_this->field_0x3008 == 0) { + // setSpecialGravityTrampoline(i_this,-9.0f, i_this->mMaxFallSpeed, 0); + // } + // } else if (i_this->mNormalSpeed > 30.0f) { + // cLib_addCalc(&i_this->mNormalSpeed, 30.0f, 0.3f, 5.0f, 1.0f); + // } + } + } else { + for (int i = 0; i < 40; i++) { + daAlink_c__posMoveTrampoline(i_this); + g_midnaChargeProjectionLine.pos[i] = i_this->current.pos; + } + } +} + +void daAlink_c__posMoveHook(daAlink_c* i_this) { + if (GZStng_getData(STNG_SCENE_LJA_PROJECTION, false) || GZStng_getData(STNG_SCENE_MIDNA_CHARGE_PROJECTION, false)) { + // store any variables that may be modified + f32 speed_y = i_this->speed.y; + cXyz link_pos = i_this->current.pos; + s16 shape_angle_y = i_this->shape_angle.y; + f32 m_normal_speed = i_this->mNormalSpeed; + s16 current_angle_y = i_this->current.angle.y; + cXyz eye_pos = i_this->mEyePos; + s16 field_3008 = i_this->field_0x3008; + f32 max_fall_speed = i_this->mMaxFallSpeed; + f32 gravity = i_this->mGravity; + cXyz field_0x37c8 = i_this->field_0x37c8; + int reset_flag_3 = i_this->mNoResetFlg3; + dCcD_Cyl mAtCyl = i_this->field_0x10F0; + f32 field_0x342c = i_this->field_0x342c; + f32 field_0x3430 = i_this->field_0x3430; + dBgS_LinkAcch m_link_acch = i_this->mLinkAcch; + + dCcD_Cyl field_0x850[3]; + dCcD_Cyl field_0xC04[3]; + + for (int i = 0; i < 3; i++) { + field_0x850[i] = i_this->field_0x850[i]; + field_0xC04[i] = i_this->field_0xC04[i]; + } + + if (i_this->mActionID == daAlink_c::PROC_ATN_ACTOR_WAIT || i_this->mActionID == daAlink_c::PROC_CUT_JUMP) { + if (GZStng_getData(STNG_SCENE_LJA_PROJECTION, false)) { + setupLJAProjectionLine(i_this); + } + } + + if (i_this->mActionID == daAlink_c::PROC_WOLF_ROLL_ATTACK_MOVE || i_this->mActionID == daAlink_c::PROC_WOLF_LOCK_ATTACK || i_this->mActionID == daAlink_c::PROC_WOLF_LOCK_ATTACK_TURN) { + if (GZStng_getData(STNG_SCENE_MIDNA_CHARGE_PROJECTION, false)) { + setupMidnaChargeProjectionLine(i_this); + } + } + + // restore variables + i_this->speed.y = speed_y; + i_this->current.pos = link_pos; + i_this->shape_angle.y = shape_angle_y; + i_this->mNormalSpeed = m_normal_speed; + i_this->current.angle.y = current_angle_y; + i_this->mEyePos = eye_pos; + i_this->field_0x3008 = field_3008; + i_this->mMaxFallSpeed = max_fall_speed; + i_this->mGravity = gravity; + i_this->field_0x37c8 = field_0x37c8; + i_this->mNoResetFlg3 = reset_flag_3; + i_this->field_0x10F0 = mAtCyl; + i_this->field_0x342c = field_0x342c; + i_this->field_0x3430 = field_0x3430; + i_this->mLinkAcch = m_link_acch; + + for (int i = 0; i < 3; i++) { + i_this->field_0x850[i] = field_0x850[i]; + i_this->field_0xC04[i] = field_0xC04[i]; + } + } + + // run the original posMove method if actor view is not enabled + if (!g_actorViewEnabled) { + return daAlink_c__posMoveTrampoline(i_this); + } +} + #ifdef WII_PLATFORM #define draw_console JUTConsoleManager__draw_void__const #define f_fapGm_Execute fapGm_Execute_void_ @@ -224,6 +392,12 @@ int endSaveInjectHook(void* i_scene) { #define f_myExceptionCallback myExceptionCallback_unsigned #define f_dScnPly__phase_1 phase_1_dScnPly_c___ #define f_dScnPly__phase_4 phase_4_dScnPly_c___ +#define f_dCcS__Draw dCcS__Draw_void_ +#define f_dScnPly_BeforeOfPaint mDoGph_BeforeOfDraw_void_ +#define f_dCcS__MoveAfterCheck dCcS__MoveAfterCheck_void_ +#define f_dBgS_Acch__CrrPos dBgS_Acch__CrrPos_dBgS___ +#define f_daAlink_c__setCutJumpSpeed daAlink_c__setCutJumpSpeed_int_ +#define f_daAlink_c__posMove daAlink_c__posMove_void_ #else #define draw_console draw__17JUTConsoleManagerCFv #define f_fapGm_Execute fapGm_Execute__Fv @@ -238,6 +412,12 @@ int endSaveInjectHook(void* i_scene) { #define f_myExceptionCallback myExceptionCallback__FUsP9OSContextUlUl #define f_dScnPly__phase_1 phase_1__FP9dScnPly_c #define f_dScnPly__phase_4 phase_4__FP9dScnPly_c +#define f_dCcS__Draw Draw__4dCcSFv +#define f_dScnPly_BeforeOfPaint dScnPly_BeforeOfPaint__Fv +#define f_dCcS__MoveAfterCheck MoveAfterCheck__4dCcSFv +#define f_dBgS_Acch__CrrPos CrrPos__9dBgS_AcchFR4dBgS +#define f_daAlink_c__setCutJumpSpeed setCutJumpSpeed__9daAlink_cFi +#define f_daAlink_c__posMove posMove__9daAlink_cFv #endif extern "C" { @@ -255,6 +435,12 @@ void f_putSave(void*, int); void f_myExceptionCallback(); int f_dScnPly__phase_1(void*); int f_dScnPly__phase_4(void*); +void f_dCcS__Draw(dCcS*); +void f_dScnPly_BeforeOfPaint(); +void f_dCcS__MoveAfterCheck(dCcS*); +void f_dBgS_Acch__CrrPos(dBgS_Acch*, dBgS&); +void f_daAlink_c__setCutJumpSpeed(daAlink_c*, int); +void f_daAlink_c__posMove(daAlink_c*); } KEEP_FUNC void applyHooks() { @@ -273,6 +459,15 @@ KEEP_FUNC void applyHooks() { APPLY_HOOK(putSave, &f_putSave, putSaveHook); APPLY_HOOK(dScnPly__phase_1, &f_dScnPly__phase_1, saveInjectHook); APPLY_HOOK(dScnPly__phase_4, &f_dScnPly__phase_4, endSaveInjectHook); + + APPLY_HOOK(dCcS__draw, &f_dCcS__Draw, dCcSDrawHook); + APPLY_HOOK(BeforeOfPaint, &f_dScnPly_BeforeOfPaint, beforeOfPaintHook); + APPLY_HOOK(dCcS__MoveAfterCheck, &f_dCcS__MoveAfterCheck, dCcSMoveAfterCheckHook); + + APPLY_HOOK(dBgS_Acch__CrrPos, &f_dBgS_Acch__CrrPos, dBgS_AcchCrrPosHook); + + APPLY_HOOK(daAlink_c__setCutJumpSpeed, &f_daAlink_c__setCutJumpSpeed, daAlink_c__setCutJumpSpeedHook); + APPLY_HOOK(daAlink_c__posMove, &f_daAlink_c__posMove, daAlink_c__posMoveHook); #ifdef PR_TEST APPLY_HOOK(ExceptionCallback, &f_myExceptionCallback, myExceptionCallbackHook); #endif diff --git a/modules/boot/src/utils/lines.cpp b/modules/boot/src/utils/lines.cpp index 88cddcb0..a2ae62b3 100644 --- a/modules/boot/src/utils/lines.cpp +++ b/modules/boot/src/utils/lines.cpp @@ -14,8 +14,13 @@ KEEP_FUNC float maxF(float a, float b) { return MAX(a, b); } +KEEP_FUNC float minF(float a, float b) { + return MIN(a, b); +} + KEEP_FUNC void GZ_drawMenuLines(Line input_lines[], uint32_t cursor, uint32_t LINES) { - float x_offset = g_spriteOffsets[MENU_INDEX].x; + Vec2 offset = GZ_getSpriteOffset(STNG_SPRITES_MENU); + float x_offset = offset.x; float y_offset = 0.0f; float max_line_width = 0.0f; @@ -25,56 +30,58 @@ KEEP_FUNC void GZ_drawMenuLines(Line input_lines[], uint32_t cursor, uint32_t LI if (LINES <= MAX_RENDER_LINES) { min_line = 0; - max_line = MAX_RENDER_LINES; + max_line = (MAX_RENDER_LINES - 1); } - for (uint32_t i = 0; i < LINES; i++) { - if (cursor > max_line) { - max_line = cursor; - min_line = max_line - MAX_RENDER_LINES; - } - if (cursor < min_line) { - min_line = cursor; - max_line = min_line + MAX_RENDER_LINES; - } + if (cursor > max_line) { + max_line = cursor; + min_line = max_line - (MAX_RENDER_LINES - 1); + } + if (cursor < min_line) { + min_line = cursor; + max_line = min_line + (MAX_RENDER_LINES - 1); + } - if (i > max_line || i < min_line) { - continue; - } - y_offset = (g_spriteOffsets[MENU_INDEX].y + (i - min_line) * 20.0f); + if (min_line > 0) { + Font::GZ_drawStr("^", offset.x, offset.y - 12.0f, 0xFFFFFFFF, GZ_checkDropShadows()); + } + + if (max_line < LINES - 1) { + Font::GZ_drawStr("v", offset.x, offset.y + 20.0f * MAX_RENDER_LINES - 2.f, 0xFFFFFFFF, GZ_checkDropShadows()); + } + + for (uint32_t i = min_line; i < MIN(max_line + 1, LINES); i++) { + y_offset = (offset.y + (i - min_line) * 20.0f); - uint32_t cursor_color = g_cursorColor; - uint32_t description_color = 0xFFFFFF00; - uint32_t description_alpha = 0xFF; + uint32_t cursor_color = input_lines[i].disabled ? 0x7F7F7FFF : 0xFFFFFFFF; // fade line/hide descriptions for lines the cursor isn't on - if (input_lines[i].idx != cursor) { - cursor_color = 0xFFFFFFFF; - description_alpha = 0x00; + if (input_lines[i].idx == cursor) { + cursor_color = g_cursorColor; } - description_color |= description_alpha; // logic for lines that are toggleable if (input_lines[i].toggleable) { - if (*input_lines[i].activation_flag) { + if (input_lines[i].active()) { Font::GZ_drawStr(" [X]", x_offset + max_line_width, y_offset, cursor_color, - g_dropShadows); + GZ_checkDropShadows()); } else { - Font::GZ_drawStr(" [ ]", x_offset + max_line_width, y_offset, cursor_color, - g_dropShadows); + Font::GZ_drawStr(" [", x_offset + max_line_width, y_offset, cursor_color, + GZ_checkDropShadows()); + Font::GZ_drawStr(" ]", x_offset + max_line_width + Font::getStrWidth("[X"), y_offset, cursor_color, + GZ_checkDropShadows()); } - Font::GZ_drawStr(input_lines[i].line, x_offset, y_offset, cursor_color, g_dropShadows); + Font::GZ_drawStr(input_lines[i].line, x_offset, y_offset, cursor_color, GZ_checkDropShadows()); } else { - Font::GZ_drawStr(input_lines[i].line, x_offset, y_offset, cursor_color, g_dropShadows); + Font::GZ_drawStr(input_lines[i].line, x_offset, y_offset, cursor_color, GZ_checkDropShadows()); Font::GZ_drawStr(input_lines[i].value, x_offset + max_line_width, y_offset, - cursor_color, g_dropShadows); + cursor_color, GZ_checkDropShadows()); } - // render line descriptions if (input_lines[i].idx == cursor) { - Font::GZ_drawStr(input_lines[i].description, x_offset, 440.f, 0x00000000, true); + // render line descriptions + Font::GZ_drawStr(input_lines[i].description, x_offset, 440.f, 0xFFFFFFFF, GZ_checkDropShadows()); } - Font::GZ_drawStr(input_lines[i].description, x_offset, 440.f, description_color, false); } } diff --git a/modules/boot/src/utils/link.cpp b/modules/boot/src/utils/link.cpp index dd941ef5..9b494596 100644 --- a/modules/boot/src/utils/link.cpp +++ b/modules/boot/src/utils/link.cpp @@ -8,14 +8,14 @@ #include "rels/include/defines.h" KEEP_FUNC void GZ_displayLinkInfo() { - if (!g_tools[LINK_DEBUG_INDEX].active) { + if (!GZStng_getData(STNG_TOOLS_LINK_DEBUG, false)) { return; } char time[14] = {0}; snprintf(time, sizeof(time), "time: %02d:%02d", g_mDoAud_zelAudio.mAudioMgr.mStatusMgr.mHour, g_mDoAud_zelAudio.mAudioMgr.mStatusMgr.mMinute); - Font::GZ_drawStr(time, g_spriteOffsets[DEBUG_INFO_INDEX].x, g_spriteOffsets[DEBUG_INFO_INDEX].y, - 0xFFFFFFFF, g_dropShadows); + Vec2 spriteOffset = GZ_getSpriteOffset(STNG_SPRITES_DEBUG_INFO); + Font::GZ_drawStr(time, spriteOffset.x, spriteOffset.y, 0xFFFFFFFF, GZ_checkDropShadows()); if (dComIfGp_getPlayer()) { char link_angle[22]; @@ -33,31 +33,43 @@ KEEP_FUNC void GZ_displayLinkInfo() { snprintf(link_y, sizeof(link_y), "y-pos: %.4f", dComIfGp_getPlayer()->current.pos.y); snprintf(link_z, sizeof(link_z), "z-pos: %.4f", dComIfGp_getPlayer()->current.pos.z); - Font::GZ_drawStr(link_angle, g_spriteOffsets[DEBUG_INFO_INDEX].x, - g_spriteOffsets[DEBUG_INFO_INDEX].y + 20.0f, 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr(y_angle, g_spriteOffsets[DEBUG_INFO_INDEX].x, - g_spriteOffsets[DEBUG_INFO_INDEX].y + 40.0f, 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr(link_speed, g_spriteOffsets[DEBUG_INFO_INDEX].x, - g_spriteOffsets[DEBUG_INFO_INDEX].y + 60.0f, 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr(link_x, g_spriteOffsets[DEBUG_INFO_INDEX].x, - g_spriteOffsets[DEBUG_INFO_INDEX].y + 80.0f, 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr(link_y, g_spriteOffsets[DEBUG_INFO_INDEX].x, - g_spriteOffsets[DEBUG_INFO_INDEX].y + 100.0f, 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr(link_z, g_spriteOffsets[DEBUG_INFO_INDEX].x, - g_spriteOffsets[DEBUG_INFO_INDEX].y + 120.0f, 0xFFFFFFFF, g_dropShadows); + Font::GZ_drawStr(link_angle, spriteOffset.x, + spriteOffset.y + 20.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); + Font::GZ_drawStr(y_angle, spriteOffset.x, + spriteOffset.y + 40.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); + Font::GZ_drawStr(link_speed, spriteOffset.x, + spriteOffset.y + 60.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); + Font::GZ_drawStr(link_x, spriteOffset.x, + spriteOffset.y + 80.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); + Font::GZ_drawStr(link_y, spriteOffset.x, + spriteOffset.y + 100.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); + Font::GZ_drawStr(link_z, spriteOffset.x, + spriteOffset.y + 120.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); } else { - Font::GZ_drawStr("angle: n/a", g_spriteOffsets[DEBUG_INFO_INDEX].x, - g_spriteOffsets[DEBUG_INFO_INDEX].y + 20.0f, 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr("y-angle: n/a", g_spriteOffsets[DEBUG_INFO_INDEX].x, - g_spriteOffsets[DEBUG_INFO_INDEX].y + 40.0f, 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr("speed: n/a", g_spriteOffsets[DEBUG_INFO_INDEX].x, - g_spriteOffsets[DEBUG_INFO_INDEX].y + 60.0f, 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr("x-pos: n/a", g_spriteOffsets[DEBUG_INFO_INDEX].x, - g_spriteOffsets[DEBUG_INFO_INDEX].y + 80.0f, 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr("y-pos: n/a", g_spriteOffsets[DEBUG_INFO_INDEX].x, - g_spriteOffsets[DEBUG_INFO_INDEX].y + 100.0f, 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr("z-pos: n/a", g_spriteOffsets[DEBUG_INFO_INDEX].x, - g_spriteOffsets[DEBUG_INFO_INDEX].y + 120.0f, 0xFFFFFFFF, g_dropShadows); + Font::GZ_drawStr("angle: n/a", spriteOffset.x, + spriteOffset.y + 20.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); + Font::GZ_drawStr("y-angle: n/a", spriteOffset.x, + spriteOffset.y + 40.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); + Font::GZ_drawStr("speed: n/a", spriteOffset.x, + spriteOffset.y + 60.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); + Font::GZ_drawStr("x-pos: n/a", spriteOffset.x, + spriteOffset.y + 80.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); + Font::GZ_drawStr("y-pos: n/a", spriteOffset.x, + spriteOffset.y + 100.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); + Font::GZ_drawStr("z-pos: n/a", spriteOffset.x, + spriteOffset.y + 120.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); } } diff --git a/modules/boot/src/utils/memory.cpp b/modules/boot/src/utils/memory.cpp index 2319d1ec..afa9da82 100644 --- a/modules/boot/src/utils/memory.cpp +++ b/modules/boot/src/utils/memory.cpp @@ -1,6 +1,5 @@ #include "utils/memory.h" #include -#include "watches.h" #include "pos_settings.h" #include "settings.h" #include "libtp_c/include/JSystem/JKernel/JKRExpHeap.h" @@ -8,112 +7,79 @@ #include "rels/include/defines.h" #include "tools.h" +char l_watchesFormats[][8][5] = {{ + "%u", + "%i", + "%u", + "%i", + "%u", + "%i", + "%.2f", + "%s", + }, + { + "%02X", + "%02X", + "%04X", + "%04X", + "%08X", + "%08X", + "%.2f", + "%s", + }}; + KEEP_FUNC void GZ_drawWatches() { - for (int i = 0; i < MAX_WATCHES; i++) { - if (g_watches[i].visible) { - char rendered_value[9]; - switch (g_watches[i].type) { - case MEM_TYPE_U32: - if (g_watches[i].offset > 0x0000 && *(uint32_t*)g_watches[i].address != 0) { - snprintf(rendered_value, sizeof(rendered_value), - g_watches[i].hex ? "%08X" : "%u", - *(uint32_t*)(*(uint32_t*)g_watches[i].address + g_watches[i].offset)); - } else { - snprintf(rendered_value, sizeof(rendered_value), - g_watches[i].hex ? "%08X" : "%u", *(uint32_t*)g_watches[i].address); - } - Font::GZ_drawStr(rendered_value, g_watches[i].x, g_watches[i].y, 0xFFFFFFFF, - g_dropShadows); - break; - case MEM_TYPE_U16: - if (g_watches[i].offset > 0x0000 && *(uint32_t*)g_watches[i].address != 0) { - snprintf(rendered_value, sizeof(rendered_value), - g_watches[i].hex ? "%04X" : "%u", - *(uint16_t*)(*(uint32_t*)g_watches[i].address + g_watches[i].offset)); - } else { - snprintf(rendered_value, sizeof(rendered_value), - g_watches[i].hex ? "%04X" : "%u", *(uint16_t*)g_watches[i].address); - } - Font::GZ_drawStr(rendered_value, g_watches[i].x, g_watches[i].y, 0xFFFFFFFF, - g_dropShadows); - break; + auto* stng = GZStng_get(STNG_WATCHES); + if (!stng) { + stng = new GZSettingEntry{STNG_WATCHES, 0, nullptr}; + g_settings.push_back(stng); + } + + MemoryWatch* watches = stng ? static_cast(stng->data) : nullptr; + size_t n_watches = stng ? stng->size / sizeof(MemoryWatch) : 0; + + for (size_t i = 0; i < n_watches; i++) { + if (watches[i].visible) { + char rendered_value[32]; + uint32_t address = watches[i].address; + char* format = l_watchesFormats[watches[i].hex][watches[i].type]; + if (watches[i].offset > 0x0000 && *(uint32_t*)watches[i].address != 0) { + address = (*(uint32_t*)watches[i].address + watches[i].offset); + } + switch (watches[i].type) { case MEM_TYPE_U8: - if (g_watches[i].offset > 0x0000 && *(uint32_t*)g_watches[i].address != 0) { - snprintf(rendered_value, sizeof(rendered_value), - g_watches[i].hex ? "%02X" : "%u", - *(uint8_t*)(*(uint32_t*)g_watches[i].address + g_watches[i].offset)); - } else { - snprintf(rendered_value, sizeof(rendered_value), - g_watches[i].hex ? "%02X" : "%u", *(uint8_t*)g_watches[i].address); - } - Font::GZ_drawStr(rendered_value, g_watches[i].x, g_watches[i].y, 0xFFFFFFFF, - g_dropShadows); + snprintf(rendered_value, sizeof(rendered_value), format, *(uint8_t*)address); break; - case MEM_TYPE_S32: - if (g_watches[i].offset > 0x0000 && *(uint32_t*)g_watches[i].address != 0) { - snprintf(rendered_value, sizeof(rendered_value), - g_watches[i].hex ? "%08X" : "%i", - *(int32_t*)(*(uint32_t*)g_watches[i].address + g_watches[i].offset)); - } else { - snprintf(rendered_value, sizeof(rendered_value), - g_watches[i].hex ? "%08X" : "%i", *(int32_t*)g_watches[i].address); - } - Font::GZ_drawStr(rendered_value, g_watches[i].x, g_watches[i].y, 0xFFFFFFFF, - g_dropShadows); + case MEM_TYPE_S8: + snprintf(rendered_value, sizeof(rendered_value), format, *(int8_t*)address); + break; + case MEM_TYPE_U16: + snprintf(rendered_value, sizeof(rendered_value), format, *(uint16_t*)address); break; case MEM_TYPE_S16: - if (g_watches[i].offset > 0x0000 && *(uint32_t*)g_watches[i].address != 0) { - snprintf(rendered_value, sizeof(rendered_value), - g_watches[i].hex ? "%04X" : "%i", - *(int16_t*)(*(uint32_t*)g_watches[i].address + g_watches[i].offset)); - } else { - snprintf(rendered_value, sizeof(rendered_value), - g_watches[i].hex ? "%04X" : "%i", *(int16_t*)g_watches[i].address); - } - Font::GZ_drawStr(rendered_value, g_watches[i].x, g_watches[i].y, 0xFFFFFFFF, - g_dropShadows); + snprintf(rendered_value, sizeof(rendered_value), format, *(int16_t*)address); break; - case MEM_TYPE_S8: - if (g_watches[i].offset > 0x0000 && *(uint32_t*)g_watches[i].address != 0) { - snprintf(rendered_value, sizeof(rendered_value), - g_watches[i].hex ? "%02X" : "%i", - *(int8_t*)(*(uint32_t*)g_watches[i].address + g_watches[i].offset)); - } else { - snprintf(rendered_value, sizeof(rendered_value), - g_watches[i].hex ? "%02X" : "%i", *(int8_t*)g_watches[i].address); - } - Font::GZ_drawStr(rendered_value, g_watches[i].x, g_watches[i].y, 0xFFFFFFFF, - g_dropShadows); + case MEM_TYPE_U32: + snprintf(rendered_value, sizeof(rendered_value), format, *(uint32_t*)address); + break; + case MEM_TYPE_S32: + snprintf(rendered_value, sizeof(rendered_value), format, *(int32_t*)address); break; case MEM_TYPE_F32: - if (g_watches[i].offset > 0x0000 && *(uint32_t*)g_watches[i].address != 0) { - snprintf(rendered_value, sizeof(rendered_value), "%.2f", - *(float*)(*(uint32_t*)g_watches[i].address + g_watches[i].offset)); - } else { - snprintf(rendered_value, sizeof(rendered_value), "%.2f", - *(float*)g_watches[i].address); - } - Font::GZ_drawStr(rendered_value, g_watches[i].x, g_watches[i].y, 0xFFFFFFFF, - g_dropShadows); + snprintf(rendered_value, sizeof(rendered_value), format, *(float*)address); break; case MEM_TYPE_STR: - if (g_watches[i].offset > 0x0000 && *(uint32_t*)g_watches[i].address != 0) { - snprintf(rendered_value, sizeof(rendered_value), "%s", - (char*)(*(uint32_t*)g_watches[i].address + g_watches[i].offset)); - } else { - snprintf(rendered_value, sizeof(rendered_value), "%s", - (char*)g_watches[i].address); - } - Font::GZ_drawStr(rendered_value, g_watches[i].x, g_watches[i].y, 0xFFFFFFFF, - g_dropShadows); + snprintf(rendered_value, sizeof(rendered_value), format, (char*)address); break; } + Font::GZ_drawStr(rendered_value, watches[i].x, watches[i].y, 0xFFFFFFFF, + GZ_checkDropShadows()); } } } KEEP_FUNC void GZ_drawHeapInfo() { - if (!g_tools[HEAP_DEBUG_INDEX].active) { + if (!GZStng_getData(STNG_TOOLS_HEAP_DEBUG, false)) { return; } if (m_Do_ext::zeldaHeap && m_Do_ext::gameHeap && m_Do_ext::archiveHeap) { @@ -124,12 +90,10 @@ KEEP_FUNC void GZ_drawHeapInfo() { uint32_t archiveFree = JKRHeap__getFreeSize(m_Do_ext::archiveHeap); uint32_t archiveTotal = JKRHeap__getTotalFreeSize(m_Do_ext::archiveHeap); - Vec2 pos = {0.f, 0.f}; - pos.x += g_spriteOffsets[HEAP_INFO_INDEX].x; - pos.y += g_spriteOffsets[HEAP_INFO_INDEX].y; + Vec2 pos = GZ_getSpriteOffset(STNG_SPRITES_HEAP_INFO); Font::GZ_drawStr("-- Heap Free / Total Free (KB) --", pos.x, pos.y, 0xFFFFFFFF, - g_dropShadows); + GZ_checkDropShadows()); char zelBuf[26]; snprintf(zelBuf, sizeof(zelBuf), " Zelda %5d / %5d", zeldaFree >> 10, zeldaTotal >> 10); char gameBuf[26]; @@ -138,8 +102,8 @@ KEEP_FUNC void GZ_drawHeapInfo() { snprintf(arcBuf, sizeof(arcBuf), "Archive %5d / %5d", archiveFree >> 10, archiveTotal >> 10); - Font::GZ_drawStr(zelBuf, pos.x + 55.0f, pos.y + 20.0f, 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr(gameBuf, pos.x + 55.0f, pos.y + 40.0f, 0xFFFFFFFF, g_dropShadows); - Font::GZ_drawStr(arcBuf, pos.x + 55.0f, pos.y + 60.0f, 0xFFFFFFFF, g_dropShadows); + Font::GZ_drawStr(zelBuf, pos.x + 55.0f, pos.y + 20.0f, 0xFFFFFFFF, GZ_checkDropShadows()); + Font::GZ_drawStr(gameBuf, pos.x + 55.0f, pos.y + 40.0f, 0xFFFFFFFF, GZ_checkDropShadows()); + Font::GZ_drawStr(arcBuf, pos.x + 55.0f, pos.y + 60.0f, 0xFFFFFFFF, GZ_checkDropShadows()); } } \ No newline at end of file diff --git a/modules/boot/src/utils/texture.cpp b/modules/boot/src/utils/texture.cpp index bc283308..de5c2159 100644 --- a/modules/boot/src/utils/texture.cpp +++ b/modules/boot/src/utils/texture.cpp @@ -1,10 +1,8 @@ #include "utils/texture.h" #include -#include "libtp_c/include/addrs.h" #include "libtp_c/include/msl_c/math.h" #include "utils/disc.h" #include "gcn_c/include/dvd.h" -#include "gcn_c/include/gfx.h" #include "rels/include/cxx.h" #include "libtp_c/include/m_Do/m_Do_printf.h" @@ -98,7 +96,7 @@ TexCode load_texture_offset(const char* path, Texture* tex, uint32_t offset) { DVDClose(&fileInfo); memset(&tex->_texObj, 0, sizeof(GXTexObj)); - GXInitTexObj(&tex->_texObj, tex->data, tex->header.width, tex->header.height, fmt, GX_CLAMP, + GXInitTexObj(&tex->_texObj, tex->data, tex->header.width, tex->header.height, (GXTexFmt)fmt, GX_CLAMP, GX_CLAMP, GX_FALSE); tex->loadCode = TexCode::TEX_OK; return tex->loadCode; @@ -115,7 +113,7 @@ void free_texture(Texture* tex) { } void setupRendering() { - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); GXClearVtxDesc(); GXSetVtxDesc(GX_VA_POS, GX_DIRECT); @@ -127,8 +125,8 @@ void setupRendering() { GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); GXSetNumTexGens(1); - GXSetTexCoordGen2((uint16_t)GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, - GX_DTTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, + GX_PTIDENTITY); GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_RASC, GX_CC_TEXC, GX_CC_ZERO); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_RASA, GX_CA_TEXA, GX_CA_ZERO); diff --git a/modules/boot/src/watches.cpp b/modules/boot/src/watches.cpp deleted file mode 100644 index 2f88a6eb..00000000 --- a/modules/boot/src/watches.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "watches.h" - -MemoryWatch g_watches[MAX_WATCHES] = {}; diff --git a/modules/features/movelink/CMakeLists.txt b/modules/features/actor_view/CMakeLists.txt similarity index 100% rename from modules/features/movelink/CMakeLists.txt rename to modules/features/actor_view/CMakeLists.txt diff --git a/modules/features/actor_view/include/actor_view.h b/modules/features/actor_view/include/actor_view.h new file mode 100644 index 00000000..b1184cb4 --- /dev/null +++ b/modules/features/actor_view/include/actor_view.h @@ -0,0 +1,5 @@ +#pragma once + +namespace ActorViewer { +void execute(); +} // namespace ActorViewer diff --git a/modules/features/movelink/include/main.h b/modules/features/actor_view/include/main.h similarity index 100% rename from modules/features/movelink/include/main.h rename to modules/features/actor_view/include/main.h diff --git a/modules/features/actor_view/src/actor_view.cpp b/modules/features/actor_view/src/actor_view.cpp new file mode 100644 index 00000000..55074bb9 --- /dev/null +++ b/modules/features/actor_view/src/actor_view.cpp @@ -0,0 +1,52 @@ +#include "features/actor_view/include/actor_view.h" +#include "menus/utils/menu_mgr.h" +#include "libtp_c/include/f_op/f_op_actor_mng.h" +#include "libtp_c/include/f_op/f_op_draw_tag.h" +#include "menus/menu_actor_list/include/actor_list_menu.h" +#include "collision_view.h" +#include "global_data.h" +#include "libtp_c/include/m_Do/m_Do_printf.h" + +namespace ActorViewer { +void drawGizmo(fopAc_ac_c* actor) { + // Gizmo cube size and angle + cXyz cube_size = {10.0f, 10.0f, 10.0f}; + csXyz cube_angle = {0, 0, 0}; + + // Colors for the gizmo's axis lines and cube + GXColor red = {255, 0, 0, 255}; + GXColor green = {0, 255, 0, 255}; + GXColor blue = {0, 0, 255, 255}; + GXColor white = {255, 255, 255, 255}; + + // length of the gizmo's axis grid lines to draw + f32 grid_line_length = 200.0f; + + // width of the gizmo's axis grid lines to draw + u8 line_width = 20; + + // Draw a cube at the position of the actor + dDbVw_drawCubeXlu(actor->current.pos, cube_size, cube_angle, white); + + // Gizmo axis line points + cXyz point_x_a = {actor->current.pos.x + grid_line_length, actor->current.pos.y, actor->current.pos.z}; + cXyz point_x_b = {actor->current.pos.x - grid_line_length, actor->current.pos.y, actor->current.pos.z}; + cXyz point_y_a = {actor->current.pos.x, actor->current.pos.y + grid_line_length, actor->current.pos.z}; + cXyz point_y_b = {actor->current.pos.x, actor->current.pos.y - grid_line_length, actor->current.pos.z}; + cXyz point_z_a = {actor->current.pos.x, actor->current.pos.y, actor->current.pos.z + grid_line_length}; + cXyz point_z_b = {actor->current.pos.x, actor->current.pos.y, actor->current.pos.z - grid_line_length}; + + + // Gizmo axis lines + dDbVw_drawLineXlu(point_x_a, point_x_b, red, 0, line_width); + dDbVw_drawLineXlu(point_y_a, point_y_b, green, 0, line_width); + dDbVw_drawLineXlu(point_z_a, point_z_b, blue, 0, line_width); +} + +KEEP_FUNC void execute() { + if (g_actorViewEnabled) { + if (g_currentActor != NULL) + drawGizmo(g_currentActor); + } +} +} // namespace ActorViewer \ No newline at end of file diff --git a/modules/features/actor_view/src/main.cpp b/modules/features/actor_view/src/main.cpp new file mode 100644 index 00000000..110e1952 --- /dev/null +++ b/modules/features/actor_view/src/main.cpp @@ -0,0 +1,14 @@ +#include +#include "features/actor_view/include/actor_view.h" +#include "rels/include/cxx.h" +#include "events/pre_loop_listener.h" + +namespace tpgz::modules { +void main() { + g_PreLoopListener->addListener(ActorViewer::execute); +} +void exit() { + g_PreLoopListener->removeListener(ActorViewer::execute); +} + +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/bit/CMakeLists.txt b/modules/features/bit/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/features/bit/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/boot/include/bit.h b/modules/features/bit/include/bit.h similarity index 100% rename from modules/boot/include/bit.h rename to modules/features/bit/include/bit.h diff --git a/modules/features/bit/include/main.h b/modules/features/bit/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/features/bit/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/boot/src/bit.cpp b/modules/features/bit/src/bit.cpp similarity index 86% rename from modules/boot/src/bit.cpp rename to modules/features/bit/src/bit.cpp index 5ecfab8e..c356edbd 100644 --- a/modules/boot/src/bit.cpp +++ b/modules/features/bit/src/bit.cpp @@ -8,9 +8,12 @@ #include "libtp_c/include/f_op/f_op_scene_req.h" #include "libtp_c/include/m_Do/m_Do_audio.h" #include "fifo_queue.h" +#include "commands.h" #include "controller.h" #include "fs.h" #include "font.h" +#include "save_manager.h" +#include "settings.h" #define VOID_HEIGHT -2098.58 #define NORMAL_ACC -3.4 @@ -21,16 +24,29 @@ #define LAST_Y_GROUND_POS (dComIfGp_getPlayer()->field_0x3404) +#ifdef WII_PLATFORM +KEEP_FUNC void GZCmd_bitPractice() { + if (GZCmd_checkTrig(GZStng_getData(STNG_CMD_BIT, BACK_IN_TIME_BUTTONS))) { + // TODO: maybe simplify this + special sp[] = { + special(0, nullptr, BiTIndicator::setPosition), + }; + + SaveManager::triggerLoad(0, "any", sp, 1); + } +} +#endif + static char buf[30]; -void BiTIndicator::setPosition() { +KEEP_FUNC void BiTIndicator::setPosition() { dComIfGp_getPlayer()->current.pos = (cXyz){466.622467f, 319.770752f, -11651.3867f}; dComIfGp_getPlayer()->shape_angle.y = 32000; matrixInfo.matrix_info->target = {465.674622f, 421.052704f, -11651.0684f}; matrixInfo.matrix_info->pos = {735.525391f, 524.418701f, -11576.4746f}; } -void BiTIndicator::execute() { +KEEP_FUNC void BiTIndicator::execute() { double dt = 0; if (dComIfGp_getPlayer()) { diff --git a/modules/features/bit/src/main.cpp b/modules/features/bit/src/main.cpp new file mode 100644 index 00000000..5e9bc45f --- /dev/null +++ b/modules/features/bit/src/main.cpp @@ -0,0 +1,28 @@ +#include +#ifdef WII_PLATFORM +#include "bit.h" +#endif +#include "gz_flags.h" +#include "commands.h" +#include "settings.h" + +namespace tpgz::modules { +void main() { +#ifdef WII_PLATFORM + GZCmd_addCmd(new Command{CMD_BIT, + GZStng_getData(STNG_CMD_BIT, BACK_IN_TIME_BUTTONS), + GZCmd_bitPractice}); + GZFlg_addFlag( + new GZFlag{GZFLG_BIT, ACTIVE_FUNC(STNG_TOOLS_BIT), GAME_LOOP, BiTIndicator::execute}); +#endif +} +void exit() { +#ifdef WII_PLATFORM + auto* flg = GZFlg_removeFlag(GZFLG_BIT); + delete flg; + auto* cmd = GZCmd_removeCmd(CMD_BIT); + delete cmd; +#endif +} + +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/corotd/CMakeLists.txt b/modules/features/corotd/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/features/corotd/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/boot/include/corotdcheck.h b/modules/features/corotd/include/corotdcheck.h similarity index 100% rename from modules/boot/include/corotdcheck.h rename to modules/features/corotd/include/corotdcheck.h diff --git a/modules/features/corotd/include/main.h b/modules/features/corotd/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/features/corotd/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/boot/src/corotdcheck.cpp b/modules/features/corotd/src/corotdcheck.cpp similarity index 98% rename from modules/boot/src/corotdcheck.cpp rename to modules/features/corotd/src/corotdcheck.cpp index d7bb6630..afe4312e 100644 --- a/modules/boot/src/corotdcheck.cpp +++ b/modules/features/corotd/src/corotdcheck.cpp @@ -22,7 +22,7 @@ #define PAD Mote #endif // WII_PLATFORM -void CoroTDChecker::execute() { +KEEP_FUNC void CoroTDChecker::execute() { static bool sTimerStarted = false; static bool sGoalHit = false; static uint32_t sFrameCount = 0; diff --git a/modules/features/corotd/src/main.cpp b/modules/features/corotd/src/main.cpp new file mode 100644 index 00000000..df62adff --- /dev/null +++ b/modules/features/corotd/src/main.cpp @@ -0,0 +1,15 @@ +#include +#include "corotdcheck.h" +#include "gz_flags.h" + +namespace tpgz::modules { +void main() { + GZFlg_addFlag(new GZFlag{GZFLG_COROTD, ACTIVE_FUNC(STNG_TOOLS_COROTD), GAME_LOOP, + CoroTDChecker::execute}); +} +void exit() { + auto* flg = GZFlg_removeFlag(GZFLG_COROTD); + delete flg; +} + +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/free_cam/src/free_cam.cpp b/modules/features/free_cam/src/free_cam.cpp index 6fbed5f0..ff7d0b47 100644 --- a/modules/features/free_cam/src/free_cam.cpp +++ b/modules/features/free_cam/src/free_cam.cpp @@ -2,7 +2,7 @@ #include "global_data.h" #include "libtp_c/include/JSystem/JUtility/JUTGamePad.h" #include "libtp_c/include/msl_c/math.h" -#include "menu.h" +#include "menus/menu.h" #include "libtp_c/include/d/com/d_com_inf_game.h" #include "libtp_c/include/f_op/f_op_draw_tag.h" #include "libtp_c/include/m_Do/m_Re_controller_pad.h" @@ -15,7 +15,8 @@ #ifdef GCN_PLATFORM #define CONTROL_Y (mPadStatus.stick_y) #define CONTROL_X (mPadStatus.stick_x) -#define VERTICAL_DISPLACEMENT (mPadStatus.trigger_left - mPadStatus.trigger_right) +#define TRIG_ADJUST(trig) (mPadStatus.trig >= 10 ? mPadStatus.trig : 0) // adjust sensitivity +#define VERTICAL_DISPLACEMENT (TRIG_ADJUST(trigger_left) - TRIG_ADJUST(trigger_right)) #define SPEED_PREDICATE (mPadButton.mButton & CButton::Z) #define PITCH_CONTROL (mPadStatus.substick_y) #define YAW_CONTROL (mPadStatus.substick_x) diff --git a/modules/features/gorge/CMakeLists.txt b/modules/features/gorge/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/features/gorge/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/boot/include/gorge.h b/modules/features/gorge/include/gorge.h similarity index 82% rename from modules/boot/include/gorge.h rename to modules/features/gorge/include/gorge.h index 57558c84..8a890256 100644 --- a/modules/boot/include/gorge.h +++ b/modules/features/gorge/include/gorge.h @@ -1,5 +1,7 @@ #pragma once +void GZCmd_loadGorgeVoid(); + namespace GorgeVoidIndicator { void execute(); void initState(); diff --git a/modules/features/gorge/include/main.h b/modules/features/gorge/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/features/gorge/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/boot/src/gorge.cpp b/modules/features/gorge/src/gorge.cpp similarity index 76% rename from modules/boot/src/gorge.cpp rename to modules/features/gorge/src/gorge.cpp index e9f920e8..d4d8b890 100644 --- a/modules/boot/src/gorge.cpp +++ b/modules/features/gorge/src/gorge.cpp @@ -1,23 +1,47 @@ #include #include "gorge.h" +#include "commands.h" #include "controller.h" #include "fifo_queue.h" #include "fs.h" +#include "save_manager.h" #include "libtp_c/include/JSystem/JUtility/JUTGamePad.h" #include "libtp_c/include/d/com/d_com_inf_game.h" #include "libtp_c/include/SSystem/SComponent/c_counter.h" #include "libtp_c/include/f_op/f_op_scene_req.h" +#include "libtp_c/include/f_op/f_op_actor_mng.h" #include "libtp_c/include/utils.h" +#include "settings.h" #ifdef WII_PLATFORM #define TARGET_BUTTON Z #define WARP_CS_FRAMES 132 #endif + #ifdef GCN_PLATFORM #define TARGET_BUTTON L #define WARP_CS_FRAMES 132 #endif +KEEP_FUNC void GZCmd_loadGorgeVoid() { + if (GZCmd_checkTrig(GZStng_getData(STNG_CMD_GORGE_VOID, GORGE_VOID_BUTTONS))) { + // TODO: maybe simplify this +#ifdef WII_PLATFORM + special sp[] = { + special(2, GorgeVoidIndicator::warpToPosition, GorgeVoidIndicator::initState), + }; + + SaveManager::triggerLoad(2, "any", sp, 1); +#else + special sp[] = { + special(8, GorgeVoidIndicator::warpToPosition, GorgeVoidIndicator::initState), + }; + + SaveManager::triggerLoad(8, "any", sp, 1); +#endif + } +} + namespace GorgeVoidIndicator { static bool start_timer = false; uint32_t previous_counter = 0; @@ -27,9 +51,24 @@ static int after_cs_val = 0; static bool got_it = false; static char buf[20]; +void actorFastCreateAtLink(short id, uint32_t parameters, int8_t subtype) { + fopAcM_create(id, parameters, &dComIfGp_getPlayer()->current.pos, + dComIfGp_getPlayer()->current.roomNo, &dComIfGp_getPlayer()->current.angle, + nullptr, subtype); +} + +#if defined(WII_NTSCU_10) || defined(WII_PAL) +#define KYTAG09_ACTOR_ID 0x2B1 +#else +#define KYTAG09_ACTOR_ID 0x2B3 +#endif + void initState() { dComIfGs_onSwitch(21, 3); // turn on portal flag dComIfGp_getEvent().mOrder[0].mEventId = 9; +#ifdef WII_PLATFORM + actorFastCreateAtLink(KYTAG09_ACTOR_ID, -1, -1); +#endif } void warpToPosition() { @@ -62,7 +101,7 @@ void warpToPosition() { g_dComIfG_gameInfo.info.mRestart.mRoomAngleY = 24169; } -void execute() { +KEEP_FUNC void execute() { // reset counters on load if (fopScnRq.isLoading == 1) { counter_difference = 0; diff --git a/modules/features/gorge/src/main.cpp b/modules/features/gorge/src/main.cpp new file mode 100644 index 00000000..49c2bfd0 --- /dev/null +++ b/modules/features/gorge/src/main.cpp @@ -0,0 +1,22 @@ +#include +#include "gz_flags.h" +#include "commands.h" +#include "gorge.h" +#include "settings.h" + +namespace tpgz::modules { +void main() { + GZCmd_addCmd(new Command{ + CMD_GORGE_VOID, GZStng_getData(STNG_CMD_GORGE_VOID, GORGE_VOID_BUTTONS), + GZCmd_loadGorgeVoid}); + GZFlg_addFlag(new GZFlag{GZFLG_GORGE_VOID, ACTIVE_FUNC(STNG_TOOLS_GORGE), GAME_LOOP, + GorgeVoidIndicator::execute}); +} +void exit() { + auto* flg = GZFlg_removeFlag(GZFLG_GORGE_VOID); + delete flg; + auto* cmd = GZCmd_removeCmd(CMD_GORGE_VOID); + delete cmd; +} + +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/input_viewer/src/input_viewer.cpp b/modules/features/input_viewer/src/input_viewer.cpp index 97fdad8e..6cfbbbbf 100644 --- a/modules/features/input_viewer/src/input_viewer.cpp +++ b/modules/features/input_viewer/src/input_viewer.cpp @@ -289,18 +289,13 @@ extern bool isWidescreen; #endif KEEP_FUNC void InputViewer::draw() { - if (!g_tools[INPUT_VIEWER_INDEX].active) { - return; - } - Vec2 pos = {0.f, 0.f}; - pos.x += g_spriteOffsets[VIEWER_INDEX].x; - pos.y += g_spriteOffsets[VIEWER_INDEX].y; + Vec2 pos = GZ_getSpriteOffset(STNG_SPRITES_INPUT_VIEWER); #ifdef GCN_PLATFORM float scale = 1.0f; #elif defined(WII_PLATFORM) float scale = 1.4f; #endif - if (g_dropShadows) + if (GZ_checkDropShadows()) drawViewer({pos.x + 1.f, pos.y + 1.f}, scale, true, IS_WIDESCREEN); drawViewer(pos, scale, false, IS_WIDESCREEN); } \ No newline at end of file diff --git a/modules/features/mash_checker/CMakeLists.txt b/modules/features/mash_checker/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/features/mash_checker/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/features/mash_checker/include/main.h b/modules/features/mash_checker/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/features/mash_checker/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/mash_checker/include/mash_checker.h b/modules/features/mash_checker/include/mash_checker.h new file mode 100644 index 00000000..8ce2ca63 --- /dev/null +++ b/modules/features/mash_checker/include/mash_checker.h @@ -0,0 +1,4 @@ +#pragma once +#include "font.h" + +void GZ_displayButtonMashInfo(); \ No newline at end of file diff --git a/modules/features/mash_checker/src/main.cpp b/modules/features/mash_checker/src/main.cpp new file mode 100644 index 00000000..3a9cf041 --- /dev/null +++ b/modules/features/mash_checker/src/main.cpp @@ -0,0 +1,13 @@ +#include +#include "events/draw_listener.h" +#include "mash_checker.h" + +namespace tpgz::modules { +void main() { + g_drawListener->addListener(GZ_displayButtonMashInfo); +} +void exit() { + g_drawListener->removeListener(GZ_displayButtonMashInfo); +} + +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/mash_checker/src/mash_checker.cpp b/modules/features/mash_checker/src/mash_checker.cpp new file mode 100644 index 00000000..93a30aba --- /dev/null +++ b/modules/features/mash_checker/src/mash_checker.cpp @@ -0,0 +1,79 @@ +#include +#include "mash_checker.h" +#include "tools.h" +#include "settings.h" +#include "controller.h" +#include "fifo_queue.h" +#include "pos_settings.h" +#include "libtp_c/include/d/com/d_com_inf_game.h" +#include "libtp_c/include/SSystem/SComponent/c_counter.h" +#include "libtp_c/include/m_Do/m_Re_controller_pad.h" +#include "rels/include/defines.h" + +u32 getSpeedTextColor(u8 i_bps) { + if (i_bps >= 11) { + return 0x00CC00FF; + } else if (i_bps >= 9) { + return 0xCCCC00FF; + } else if (i_bps > 0) { + return 0xCC0000FF; + } + + return 0xFFFFFFFF; +} + +KEEP_FUNC void GZ_displayButtonMashInfo() { + static OSTime start_time; + static bool init_start_time = false; + + static u8 abtn_presses = 0; + static u8 last_abtn_presses = 0; + static u8 a_bps = 0; + + static u8 bbtn_presses = 0; + static u8 last_bbtn_presses = 0; + static u8 b_bps = 0; + + if (!init_start_time) { + start_time = OSGetTime(); + + abtn_presses = 0; + last_abtn_presses = 0; + a_bps = 0; + + bbtn_presses = 0; + last_bbtn_presses = 0; + b_bps = 0; + + init_start_time = true; + } + + OSTime current_time = OSGetTime(); + OSTime time_diff = current_time - start_time; + OSCalendarTime ctime; + OSTicksToCalendarTime(time_diff, &ctime); + + if (ctime.seconds == 1) { + a_bps = abtn_presses - last_abtn_presses; + b_bps = bbtn_presses - last_bbtn_presses; + + last_abtn_presses = abtn_presses; + last_bbtn_presses = bbtn_presses; + + start_time = current_time; + } + + GZ_getButtonPressCount(abtn_presses, CButton::A, GZPad::A); + GZ_getButtonPressCount(bbtn_presses, CButton::B, GZPad::B); + + Vec2 pos = GZ_getSpriteOffset(STNG_SPRITES_MASH_INFO); + + char abtn_text[8] = {0}; + snprintf(abtn_text, sizeof(abtn_text), "A: %d", a_bps); + Font::GZ_drawStr(abtn_text, pos.x, pos.y, getSpeedTextColor(a_bps), GZ_checkDropShadows()); + + char bbtn_text[8] = {0}; + snprintf(bbtn_text, sizeof(bbtn_text), "B: %d", b_bps); + Font::GZ_drawStr(bbtn_text, pos.x, pos.y + 20.0f, getSpeedTextColor(b_bps), + GZ_checkDropShadows()); +} \ No newline at end of file diff --git a/modules/features/moon_jump/CMakeLists.txt b/modules/features/moon_jump/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/features/moon_jump/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/features/moon_jump/include/main.h b/modules/features/moon_jump/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/features/moon_jump/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/moon_jump/src/main.cpp b/modules/features/moon_jump/src/main.cpp new file mode 100644 index 00000000..cabbe21d --- /dev/null +++ b/modules/features/moon_jump/src/main.cpp @@ -0,0 +1,26 @@ +#include +#include "commands.h" +#include "settings.h" +#include "libtp_c/include/d/com/d_com_inf_game.h" +#include "libtp_c/include/JSystem/JUtility/JUTGamePad.h" + +KEEP_FUNC void GZCmd_moonJump() { + if (dComIfGp_getPlayer()) { + dComIfGp_getPlayer()->speed.y = 56.0f; + } +} + +KEEP_VAR bool active = false; + +namespace tpgz::modules { +void main() { + GZCmd_addCmd(new Command{CMD_MOON_JUMP, + GZStng_getData(STNG_CMD_MOON_JUMP, MOON_JUMP_BUTTONS), + GZCmd_moonJump}); +} +void exit() { + auto* cmd = GZCmd_removeCmd(CMD_MOON_JUMP); + delete cmd; +} + +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/moveactor/CMakeLists.txt b/modules/features/moveactor/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/features/moveactor/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/features/moveactor/include/main.h b/modules/features/moveactor/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/features/moveactor/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/moveactor/include/moveactor.h b/modules/features/moveactor/include/moveactor.h new file mode 100644 index 00000000..d66502d4 --- /dev/null +++ b/modules/features/moveactor/include/moveactor.h @@ -0,0 +1,8 @@ +#pragma once +#include "font.h" +#include "libtp_c/include/d/com/d_com_inf_game.h" + +namespace MoveActor { +void move(fopAc_ac_c* actor); +void execute(); +} // namespace MoveActor diff --git a/modules/features/movelink/src/main.cpp b/modules/features/moveactor/src/main.cpp similarity index 51% rename from modules/features/movelink/src/main.cpp rename to modules/features/moveactor/src/main.cpp index 92b69273..a1f1a16c 100644 --- a/modules/features/movelink/src/main.cpp +++ b/modules/features/moveactor/src/main.cpp @@ -1,14 +1,14 @@ #include -#include "features/movelink/include/movelink.h" +#include "features/moveactor/include/moveactor.h" #include "rels/include/cxx.h" #include "events/pre_loop_listener.h" namespace tpgz::modules { void main() { - g_PreLoopListener->addListener(MoveLink::execute); + g_PreLoopListener->addListener(MoveActor::execute); } void exit() { - g_PreLoopListener->removeListener(MoveLink::execute); + g_PreLoopListener->removeListener(MoveActor::execute); } } // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/moveactor/src/moveactor.cpp b/modules/features/moveactor/src/moveactor.cpp new file mode 100644 index 00000000..01dd9b99 --- /dev/null +++ b/modules/features/moveactor/src/moveactor.cpp @@ -0,0 +1,151 @@ +#include "features/moveactor/include/moveactor.h" +#include +#include "font.h" +#include "global_data.h" +#include "libtp_c/include/msl_c/math.h" +#include "settings.h" +#include "libtp_c/include/JSystem/JUtility/JUTGamePad.h" +#include "libtp_c/include/f_op/f_op_draw_tag.h" +#include "libtp_c/include/m_Do/m_Re_controller_pad.h" +#include "rels/include/defines.h" +#include "libtp_c/include/d/meter/d_meter_HIO.h" +#include "libtp_c/include/d/d_procname.h" + +#define ROTATION_SPEED (30) +#define ROTATION_FAST_SPEED (80) +#define ROTATION_VERY_FAST_SPEED (800) +#define CAM_SPEED (1.0) +#define CAM_FAST_SPEED (2.5) +#define CAM_VERY_FAST_SPEED (10.0) +#define DIST_FROM_ACTOR (600) + +#ifdef GCN_PLATFORM +#define CONTROL_Y (mPadStatus.stick_y) +#define CONTROL_X (mPadStatus.stick_x) +#define VERTICAL_DISPLACEMENT (mPadStatus.substick_y) +#define HORIZONTAL_DISPLACEMENT -(mPadStatus.substick_x) +#define SPEED_PREDICATE_1 (mPadButton.mButton & CButton::Z) +#define SPEED_PREDICATE_2 (mPadButton.mButton & CButton::R) +#define LOCK_CAMERA (mPadButton.mButton & CButton::L) +#endif + +#ifdef WII_PLATFORM +#define CONTROL_Y ((mPad.mHoldButton & CButton::C) == 0 ? mPad.stick.y * 72 : 0) +#define CONTROL_X ((mPad.mHoldButton & CButton::C) == 0 ? -mPad.stick.x * 72 : 0) +#define VERTICAL_DISPLACEMENT ((mPad.mHoldButton & CButton::C) != 0 ? mPad.stick.y * 59 : 0) +#define HORIZONTAL_DISPLACEMENT ((mPad.mHoldButton & CButton::C) != 0 ? -mPad.stick.x * 59 : 0) +#define SPEED_PREDICATE_1 (mPad.mHoldButton & CButton::Z) +#define SPEED_PREDICATE_2 (mPad.mHoldButton & CButton::MINUS) +#define LOCK_CAMERA (mPad.mHoldButton & CButton::A) +#endif + +#define WHITE_RGBA 0xFFFFFFFF +#define LINE_X_OFFSET 20.0f + +namespace MoveActor { + +double pitch = 0.0; +double yaw = 0.0; +float angle = 0.0f; +bool event_halt = false; + +void move(fopAc_ac_c* actor) { + // Fetch the camera position and target + Vec& cam_target = matrixInfo.matrix_info->target; + Vec& cam_pos = matrixInfo.matrix_info->pos; + + // Fetch the actor position and angles + cXyz& actor_pos = actor->current.pos; + s16& actor_horizontal_angle = actor->shape_angle.y; + s16& actor_verticle_angle = actor->shape_angle.x; + + // Set Link momentum to 0 + cXyz tmp(0.0f, 0.0f, 0.0f); + dComIfGp_getPlayer()->speed = tmp; + + if (!LOCK_CAMERA) { + angle = (float)actor_horizontal_angle / 65536.f * (2 * M_PI); + } + + // Fix Camera behind link + cam_target.x = actor_pos.x; + cam_target.y = actor_pos.y + 200.f; + cam_target.z = actor_pos.z; + cam_pos.z = actor_pos.z - DIST_FROM_ACTOR * cos(angle); + cam_pos.x = actor_pos.x - DIST_FROM_ACTOR * sin(angle); + cam_pos.y = actor_pos.y + 200.f; + + // Calculate the pitch and yaw + yaw = atan2(cam_target.z - cam_pos.z, cam_target.x - cam_pos.x); + double horizontal = sqrt((cam_target.x - cam_pos.x) * (cam_target.x - cam_pos.x) + + (cam_target.z - cam_pos.z) * (cam_target.z - cam_pos.z)); + pitch = atan2(cam_target.y - cam_pos.y, horizontal); + + // Calculate the translation + double dy = LOCK_CAMERA ? 0.0f : VERTICAL_DISPLACEMENT; + double dx = CONTROL_Y * cos(yaw) * cos(pitch) - CONTROL_X * sin(yaw); + double dz = CONTROL_Y * sin(yaw) * cos(pitch) + CONTROL_X * cos(yaw); + + auto move_speed = SPEED_PREDICATE_1 != 0 ? SPEED_PREDICATE_2 != 0 ? CAM_VERY_FAST_SPEED : CAM_FAST_SPEED : CAM_SPEED; + auto cam_speed = SPEED_PREDICATE_1 != 0 ? SPEED_PREDICATE_2 != 0 ? ROTATION_VERY_FAST_SPEED : ROTATION_FAST_SPEED : ROTATION_SPEED; + + // Apply the translation with a speed factor + actor_pos.x += move_speed * dx; + actor_pos.y += move_speed * dy; + actor_pos.z += move_speed * dz; + + // Change facing angle with c stick + if (LOCK_CAMERA) { + actor_verticle_angle -= -VERTICAL_DISPLACEMENT * cam_speed; + actor_horizontal_angle -= -HORIZONTAL_DISPLACEMENT * cam_speed; + } else { + actor_horizontal_angle -= HORIZONTAL_DISPLACEMENT * cam_speed; + } + +} + +KEEP_FUNC void execute() { + if (g_actorViewEnabled || g_moveLinkEnabled) { + // Hide HUD + g_drawHIO.mHUDAlpha = 0.0f; + + // Lock the camera to allow for its movement + dComIfGp_getEventManager().mCameraPlay = 1; + + // Special case for Link (this needs to be refactored to be more generic) + if (dComIfGp_getPlayer() && (g_moveLinkEnabled || g_currentActor->mBase.mProcName == PROC_ALINK )) { + dComIfGp_getPlayer()->mLinkAcch.SetGrndNone(); + dComIfGp_getPlayer()->mLinkAcch.SetWallNone(); + dComIfGp_getPlayer()->mLinkAcch.SetRoofNone(); + dComIfGp_getPlayer()->mLinkAcch.OnLineCheckNone(); + + dComIfGp_getEvent().mHalt = true; + event_halt = true; + + move(dComIfGp_getPlayer()); + } else { + dComIfGp_getEvent().mHalt = false; + event_halt = false; + + move(g_currentActor); + } + } else { + if (event_halt) { + if (dComIfGp_getPlayer()) { + dComIfGp_getPlayer()->mLinkAcch.ClrGrndNone(); + dComIfGp_getPlayer()->mLinkAcch.ClrWallNone(); + dComIfGp_getPlayer()->mLinkAcch.ClrRoofNone(); + dComIfGp_getPlayer()->mLinkAcch.OffLineCheckNone(); + } + + dComIfGp_getEvent().mHalt = false; + event_halt = false; + + dComIfGp_getEventManager().mCameraPlay = 0; + g_drawHIO.mHUDAlpha = 1.0f; + } + + + } +} +} // namespace MoveActor \ No newline at end of file diff --git a/modules/features/movelink/include/movelink.h b/modules/features/movelink/include/movelink.h deleted file mode 100644 index 0cc8d510..00000000 --- a/modules/features/movelink/include/movelink.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "font.h" - -namespace MoveLink { -void execute(); -// void render_info_input(); -} // namespace MoveLink diff --git a/modules/features/movelink/src/movelink.cpp b/modules/features/movelink/src/movelink.cpp deleted file mode 100644 index 1d458b27..00000000 --- a/modules/features/movelink/src/movelink.cpp +++ /dev/null @@ -1,582 +0,0 @@ -#include "features/movelink/include/movelink.h" -#include -#include "global_data.h" -#include "libtp_c/include/msl_c/math.h" -#include "settings.h" -#include "libtp_c/include/JSystem/JUtility/JUTGamePad.h" -#include "libtp_c/include/d/com/d_com_inf_game.h" -#include "libtp_c/include/f_op/f_op_draw_tag.h" -#include "libtp_c/include/m_Do/m_Re_controller_pad.h" -#include "rels/include/defines.h" - -#define ROTATION_SPEED (10) -#define CAM_FAST_SPEED (2.0) -#define CAM_SPEED (0.2) -#define DIST_FROM_LINK (600) - -#ifdef GCN_PLATFORM -#define CONTROL_Y (mPadStatus.stick_y) -#define CONTROL_X (mPadStatus.stick_x) -#define VERTICAL_DISPLACEMENT (mPadStatus.substick_y) -#define HORIZONTAL_DISPLACEMENT (mPadStatus.substick_x) -#define SPEED_PREDICATE (mPadButton.mButton & CButton::Z) -#endif - -#ifdef WII_PLATFORM -#define CONTROL_Y ((mPad.mHoldButton & CButton::C) == 0 ? mPad.stick.y * 72 : 0) -#define CONTROL_X ((mPad.mHoldButton & CButton::C) == 0 ? -mPad.stick.x * 72 : 0) -#define VERTICAL_DISPLACEMENT ((mPad.mHoldButton & CButton::C) != 0 ? mPad.stick.y * 59 : 0) -#define HORIZONTAL_DISPLACEMENT ((mPad.mHoldButton & CButton::C) != 0 ? -mPad.stick.x * 59 : 0) -#define SPEED_PREDICATE (mPad.mHoldButton & CButton::Z) -#endif - -#define WHITE_RGBA 0xFFFFFFFF -#define LINE_X_OFFSET 20.0f - -namespace MoveLink { -/* static Cursor cursor; - -bool link_angle_selected = false; -bool link_x_selected = false; -bool link_y_selected = false; -bool link_z_selected = false; */ - -bool init_once = false; - -double pitch = 0.0; -double yaw = 0.0; -float angle = 0.0f; - -KEEP_FUNC void execute() { - if (g_moveLinkEnabled) { - auto& cam_target = matrixInfo.matrix_info->target; - auto& cam_pos = matrixInfo.matrix_info->pos; - - cXyz& link_pos = dComIfGp_getPlayer()->current.pos; - int16_t& link_angle = dComIfGp_getPlayer()->shape_angle.y; - - // Freeze the game to prevent control stick inputs to move link - dComIfGp_getEvent().mHalt = true; - - // Lock the camera to allow for its movement - dComIfGp_getEventManager().mCameraPlay = 1; - - // Set Link momentum to 0 - cXyz tmp(0.0f, 0.0f, 0.0f); - dComIfGp_getPlayer()->speed = tmp; - - if (!init_once) { - angle = (float)link_angle / 65536.f * (2 * M_PI); - } - - // Fix Camera behind link - cam_target.x = link_pos.x; - cam_target.y = link_pos.y + 200.f; - cam_target.z = link_pos.z; - cam_pos.z = link_pos.z - DIST_FROM_LINK * cos(angle); - cam_pos.x = link_pos.x - DIST_FROM_LINK * sin(angle); - cam_pos.y = link_pos.y + 200.f; - - if (!init_once) { - // Initialize the pitch and yaw to the current angle of the camera - yaw = atan2(cam_target.z - cam_pos.z, cam_target.x - cam_pos.x); - double horizontal = sqrt((cam_target.x - cam_pos.x) * (cam_target.x - cam_pos.x) + - (cam_target.z - cam_pos.z) * (cam_target.z - cam_pos.z)); - pitch = atan2(cam_target.y - cam_pos.y, horizontal); - init_once = true; - } - - // Calculate the translation - double dy = VERTICAL_DISPLACEMENT; - double dx = CONTROL_Y * cos(yaw) * cos(pitch) - CONTROL_X * sin(yaw); - double dz = CONTROL_Y * sin(yaw) * cos(pitch) + CONTROL_X * cos(yaw); - - auto speed = SPEED_PREDICATE != 0 ? CAM_FAST_SPEED : CAM_SPEED; - - // Apply the translation with a speed factor - link_pos.x += speed * dx; - link_pos.y += speed * dy; - link_pos.z += speed * dz; - - // Change facing angle with c stick - link_angle -= HORIZONTAL_DISPLACEMENT * ROTATION_SPEED; - - } else { - if (init_once) { - dComIfGp_getEvent().mHalt = false; - dComIfGp_getEventManager().mCameraPlay = 0; - init_once = false; - } - } -} - -/* void render_info_input() { - char link_angle[20]; - char link_x[20]; - char link_y[20]; - char link_z[20]; - uint8_t cursor_x_max = 1; - - snprintf(link_angle, sizeof(link_angle), "angle: %05d", - (uint16_t)dComIfGp_getPlayer()->shape_angle.y); - snprintf(link_x, sizeof(link_x), "x-pos: % 010.2f", - dComIfGp_getPlayer()->current.pos.x); - snprintf(link_y, sizeof(link_y), "y-pos: % 010.2f", - dComIfGp_getPlayer()->current.pos.y); - snprintf(link_z, sizeof(link_z), "z-pos: % 010.2f", - dComIfGp_getPlayer()->current.pos.z); - - if (link_angle_selected) { - cursor_x_max = 5; - if (GZ_getButtonRepeat(GZPad::DPAD_UP)) { - switch (cursor.x) { - case 0: { - dComIfGp_getPlayer()->shape_angle.y += 10000; - break; - } - case 1: { - dComIfGp_getPlayer()->shape_angle.y += 1000; - break; - } - case 2: { - dComIfGp_getPlayer()->shape_angle.y += 100; - break; - } - case 3: { - dComIfGp_getPlayer()->shape_angle.y += 10; - break; - } - case 4: { - dComIfGp_getPlayer()->shape_angle.y += 1; - break; - } - } - } - if (GZ_getButtonRepeat(GZPad::DPAD_DOWN)) { - switch (cursor.x) { - case 0: { - dComIfGp_getPlayer()->shape_angle.y -= 10000; - break; - } - case 1: { - dComIfGp_getPlayer()->shape_angle.y -= 1000; - break; - } - case 2: { - dComIfGp_getPlayer()->shape_angle.y -= 100; - break; - } - case 3: { - dComIfGp_getPlayer()->shape_angle.y -= 10; - break; - } - case 4: { - dComIfGp_getPlayer()->shape_angle.y -= 1; - break; - } - } - } - - Font::GZ_drawChar(link_angle[0], LINE_X_OFFSET, 80.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_angle[1], LINE_X_OFFSET + 8.0f, 80.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_angle[2], LINE_X_OFFSET + 16.0f, 80.0f, WHITE_RGBA, - g_dropShadows); - Font::GZ_drawChar(link_angle[3], LINE_X_OFFSET + 26.0f, 80.0f, WHITE_RGBA, - g_dropShadows); - Font::GZ_drawChar(link_angle[4], LINE_X_OFFSET + 32.0f, 80.0f, WHITE_RGBA, - g_dropShadows); - Font::GZ_drawChar(link_angle[5], LINE_X_OFFSET + 40.0f, 80.0f, WHITE_RGBA, - g_dropShadows); - Font::GZ_drawChar(link_angle[6], LINE_X_OFFSET + 48.0f, 80.0f, WHITE_RGBA, - g_dropShadows); - - Font::GZ_drawChar(link_angle[7], LINE_X_OFFSET + 56.0f, 80.0f, - (cursor.x == 0 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_angle[8], LINE_X_OFFSET + 65.0f, 80.0f, - (cursor.x == 1 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_angle[9], LINE_X_OFFSET + 74.0f, 80.0f, - (cursor.x == 2 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_angle[10], LINE_X_OFFSET + 83.0f, 80.0f, - (cursor.x == 3 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_angle[11], LINE_X_OFFSET + 92.0f, 80.0f, - (cursor.x == 4 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - } else { - Font::GZ_drawStr(link_angle, LINE_X_OFFSET, 80.0f, - (cursor.y == 0 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - } - - if (link_x_selected) { - if (dComIfGp_getPlayer()->current.pos.x <= -999998.99f) { - dComIfGp_getPlayer()->current.pos.x = -999998.99f; - } else if (dComIfGp_getPlayer()->current.pos.x >= 999998.99f) { - dComIfGp_getPlayer()->current.pos.x = 999998.99f; - } - cursor_x_max = 9; - if (GZ_getButtonRepeat(GZPad::DPAD_UP)) { - switch (cursor.x) { - case 0: { - dComIfGp_getPlayer()->current.pos.x += 100000.0f; - break; - } - case 1: { - dComIfGp_getPlayer()->current.pos.x += 10000.0f; - break; - } - case 2: { - dComIfGp_getPlayer()->current.pos.x += 1000.0f; - break; - } - case 3: { - dComIfGp_getPlayer()->current.pos.x += 100.0f; - break; - } - case 4: { - dComIfGp_getPlayer()->current.pos.x += 10.0f; - break; - } - case 5: { - dComIfGp_getPlayer()->current.pos.x += 1.0f; - break; - } - case 7: { - dComIfGp_getPlayer()->current.pos.x += 0.10f; - break; - } - case 8: { - dComIfGp_getPlayer()->current.pos.x += 0.01f; - break; - } - } - } - if (GZ_getButtonRepeat(GZPad::DPAD_DOWN)) { - switch (cursor.x) { - case 0: { - dComIfGp_getPlayer()->current.pos.x -= 100000.0f; - break; - } - case 1: { - dComIfGp_getPlayer()->current.pos.x -= 10000.0f; - break; - } - case 2: { - dComIfGp_getPlayer()->current.pos.x -= 1000.0f; - break; - } - case 3: { - dComIfGp_getPlayer()->current.pos.x -= 100.0f; - break; - } - case 4: { - dComIfGp_getPlayer()->current.pos.x -= 10.0f; - break; - } - case 5: { - dComIfGp_getPlayer()->current.pos.x -= 1.0f; - break; - } - case 7: { - dComIfGp_getPlayer()->current.pos.x -= 0.10f; - break; - } - case 8: { - dComIfGp_getPlayer()->current.pos.x -= 0.01f; - break; - } - } - } - - Font::GZ_drawChar(link_x[0], LINE_X_OFFSET, 100.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_x[1], LINE_X_OFFSET + 10.0f, 100.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_x[2], LINE_X_OFFSET + 16.0f, 100.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_x[3], LINE_X_OFFSET + 24.0f, 100.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_x[4], LINE_X_OFFSET + 34.0f, 100.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_x[5], LINE_X_OFFSET + 44.0f, 100.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_x[6], LINE_X_OFFSET + 52.0f, 100.0f, WHITE_RGBA, g_dropShadows); - - Font::GZ_drawChar(link_x[7], LINE_X_OFFSET + 56.0f, 100.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_x[8], LINE_X_OFFSET + 66.0f, 100.0f, - (cursor.x == 0 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_x[9], LINE_X_OFFSET + 76.0f, 100.0f, - (cursor.x == 1 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_x[10], LINE_X_OFFSET + 86.0f, 100.0f, - (cursor.x == 2 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_x[11], LINE_X_OFFSET + 96.0f, 100.0f, - (cursor.x == 3 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_x[12], LINE_X_OFFSET + 106.0f, 100.0f, - (cursor.x == 4 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_x[13], LINE_X_OFFSET + 116.0f, 100.0f, - (cursor.x == 5 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_x[14], LINE_X_OFFSET + 126.0f, 100.0f, - (cursor.x == 6 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_x[15], LINE_X_OFFSET + 131.0f, 100.0f, - (cursor.x == 7 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_x[16], LINE_X_OFFSET + 141.0f, 100.0f, - (cursor.x == 8 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - } else { - Font::GZ_drawStr(link_x, LINE_X_OFFSET, 100.0f, - (cursor.y == 1 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - } - - if (link_y_selected) { - if (dComIfGp_getPlayer()->current.pos.y <= -999998.99f) { - dComIfGp_getPlayer()->current.pos.y = -999998.99f; - } else if (dComIfGp_getPlayer()->current.pos.y >= 999998.99f) { - dComIfGp_getPlayer()->current.pos.y = 999998.99f; - } - cursor_x_max = 9; - if (GZ_getButtonRepeat(GZPad::DPAD_UP)) { - switch (cursor.x) { - case 0: { - dComIfGp_getPlayer()->current.pos.y += 100000.0f; - break; - } - case 1: { - dComIfGp_getPlayer()->current.pos.y += 10000.0f; - break; - } - case 2: { - dComIfGp_getPlayer()->current.pos.y += 1000.0f; - break; - } - case 3: { - dComIfGp_getPlayer()->current.pos.y += 100.0f; - break; - } - case 4: { - dComIfGp_getPlayer()->current.pos.y += 10.0f; - break; - } - case 5: { - dComIfGp_getPlayer()->current.pos.y += 1.0f; - break; - } - case 7: { - dComIfGp_getPlayer()->current.pos.y += 0.10f; - break; - } - case 8: { - dComIfGp_getPlayer()->current.pos.y += 0.01f; - break; - } - } - } - if (GZ_getButtonRepeat(GZPad::DPAD_DOWN)) { - switch (cursor.x) { - case 0: { - dComIfGp_getPlayer()->current.pos.y -= 100000.0f; - break; - } - case 1: { - dComIfGp_getPlayer()->current.pos.y -= 10000.0f; - break; - } - case 2: { - dComIfGp_getPlayer()->current.pos.y -= 1000.0f; - break; - } - case 3: { - dComIfGp_getPlayer()->current.pos.y -= 100.0f; - break; - } - case 4: { - dComIfGp_getPlayer()->current.pos.y -= 10.0f; - break; - } - case 5: { - dComIfGp_getPlayer()->current.pos.y -= 1.0f; - break; - } - case 7: { - dComIfGp_getPlayer()->current.pos.y -= 0.10f; - break; - } - case 8: { - dComIfGp_getPlayer()->current.pos.y -= 0.01f; - break; - } - } - } - - Font::GZ_drawChar(link_y[0], LINE_X_OFFSET, 120.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_y[1], LINE_X_OFFSET + 10.0f, 120.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_y[2], LINE_X_OFFSET + 16.0f, 120.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_y[3], LINE_X_OFFSET + 24.0f, 120.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_y[4], LINE_X_OFFSET + 34.0f, 120.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_y[5], LINE_X_OFFSET + 44.0f, 120.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_y[6], LINE_X_OFFSET + 52.0f, 120.0f, WHITE_RGBA, g_dropShadows); - - Font::GZ_drawChar(link_y[7], LINE_X_OFFSET + 56.0f, 120.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_y[8], LINE_X_OFFSET + 66.0f, 120.0f, - (cursor.x == 0 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_y[9], LINE_X_OFFSET + 76.0f, 120.0f, - (cursor.x == 1 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_y[10], LINE_X_OFFSET + 86.0f, 120.0f, - (cursor.x == 2 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_y[11], LINE_X_OFFSET + 96.0f, 120.0f, - (cursor.x == 3 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_y[12], LINE_X_OFFSET + 106.0f, 120.0f, - (cursor.x == 4 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_y[13], LINE_X_OFFSET + 116.0f, 120.0f, - (cursor.x == 5 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_y[14], LINE_X_OFFSET + 126.0f, 120.0f, - (cursor.x == 6 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_y[15], LINE_X_OFFSET + 131.0f, 120.0f, - (cursor.x == 7 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_y[16], LINE_X_OFFSET + 141.0f, 120.0f, - (cursor.x == 8 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - } else { - Font::GZ_drawStr(link_y, LINE_X_OFFSET, 120.0f, - (cursor.y == 2 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - } - - if (link_z_selected) { - if (dComIfGp_getPlayer()->current.pos.z <= -999998.99f) { - dComIfGp_getPlayer()->current.pos.z = -999998.99f; - } else if (dComIfGp_getPlayer()->current.pos.z >= 999998.99f) { - dComIfGp_getPlayer()->current.pos.z = 999998.99f; - } - cursor_x_max = 9; - if (GZ_getButtonRepeat(GZPad::DPAD_UP)) { - switch (cursor.x) { - case 0: { - dComIfGp_getPlayer()->current.pos.z += 100000.0f; - break; - } - case 1: { - dComIfGp_getPlayer()->current.pos.z += 10000.0f; - break; - } - case 2: { - dComIfGp_getPlayer()->current.pos.z += 1000.0f; - break; - } - case 3: { - dComIfGp_getPlayer()->current.pos.z += 100.0f; - break; - } - case 4: { - dComIfGp_getPlayer()->current.pos.z += 10.0f; - break; - } - case 5: { - dComIfGp_getPlayer()->current.pos.z += 1.0f; - break; - } - case 7: { - dComIfGp_getPlayer()->current.pos.z += 0.10f; - break; - } - case 8: { - dComIfGp_getPlayer()->current.pos.z += 0.01f; - break; - } - } - } - if (GZ_getButtonRepeat(GZPad::DPAD_DOWN)) { - switch (cursor.x) { - case 0: { - dComIfGp_getPlayer()->current.pos.z -= 100000.0f; - break; - } - case 1: { - dComIfGp_getPlayer()->current.pos.z -= 10000.0f; - break; - } - case 2: { - dComIfGp_getPlayer()->current.pos.z -= 1000.0f; - break; - } - case 3: { - dComIfGp_getPlayer()->current.pos.z -= 100.0f; - break; - } - case 4: { - dComIfGp_getPlayer()->current.pos.z -= 10.0f; - break; - } - case 5: { - dComIfGp_getPlayer()->current.pos.z -= 1.0f; - break; - } - case 7: { - dComIfGp_getPlayer()->current.pos.z -= 0.10f; - break; - } - case 8: { - dComIfGp_getPlayer()->current.pos.z -= 0.01f; - break; - } - } - } - - Font::GZ_drawChar(link_z[0], LINE_X_OFFSET, 140.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_z[1], LINE_X_OFFSET + 10.0f, 140.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_z[2], LINE_X_OFFSET + 16.0f, 140.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_z[3], LINE_X_OFFSET + 24.0f, 140.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_z[4], LINE_X_OFFSET + 34.0f, 140.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_z[5], LINE_X_OFFSET + 44.0f, 140.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_z[6], LINE_X_OFFSET + 52.0f, 140.0f, WHITE_RGBA, g_dropShadows); - - Font::GZ_drawChar(link_z[7], LINE_X_OFFSET + 56.0f, 140.0f, WHITE_RGBA, g_dropShadows); - Font::GZ_drawChar(link_z[8], LINE_X_OFFSET + 66.0f, 140.0f, - (cursor.x == 0 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_z[9], LINE_X_OFFSET + 76.0f, 140.0f, - (cursor.x == 1 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_z[10], LINE_X_OFFSET + 86.0f, 140.0f, - (cursor.x == 2 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_z[11], LINE_X_OFFSET + 96.0f, 140.0f, - (cursor.x == 3 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_z[12], LINE_X_OFFSET + 106.0f, 140.0f, - (cursor.x == 4 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_z[13], LINE_X_OFFSET + 116.0f, 140.0f, - (cursor.x == 5 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_z[14], LINE_X_OFFSET + 126.0f, 140.0f, - (cursor.x == 6 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_z[15], LINE_X_OFFSET + 131.0f, 140.0f, - (cursor.x == 7 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - Font::GZ_drawChar(link_z[16], LINE_X_OFFSET + 141.0f, 140.0f, - (cursor.x == 8 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - } else { - Font::GZ_drawStr(link_z, LINE_X_OFFSET, 140.0f, - (cursor.y == 3 ? CURSOR_RGBA : WHITE_RGBA), g_dropShadows); - } - - if (GZ_getButtonRepeat(GZPad::B)) { - if (link_angle_selected) { - link_angle_selected = false; - } else if (link_x_selected) { - link_x_selected = false; - } else if (link_y_selected) { - link_y_selected = false; - } else if (link_z_selected) { - link_z_selected = false; - } - cursor_x_max = 1; - lock_cursor_y = false; - } - - if (GZ_getButtonRepeat(GZPad::A)) { - switch (cursor.y) { - case 0: { - link_angle_selected = true; - break; - } - case 1: { - link_x_selected = true; - break; - } - case 2: { - link_y_selected = true; - break; - } - case 3: { - link_z_selected = true; - break; - } - } - lock_cursor_y = true; - } - - move_cursor(cursor, 4, cursor_x_max, lock_cursor_x, lock_cursor_y, true); -}; */ -} // namespace MoveLink \ No newline at end of file diff --git a/modules/features/projection_view/CMakeLists.txt b/modules/features/projection_view/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/features/projection_view/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/features/projection_view/include/main.h b/modules/features/projection_view/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/features/projection_view/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/projection_view/include/projection_view.h b/modules/features/projection_view/include/projection_view.h new file mode 100644 index 00000000..1bb8357f --- /dev/null +++ b/modules/features/projection_view/include/projection_view.h @@ -0,0 +1,28 @@ +#pragma once + +#include "libtp_c/include/SSystem/SComponent/c_xyz.h" + +enum ProjectionViewIndex { + VIEW_LJA_PROJECTION, + VIEW_MIDNA_CHARGE_PROJECTION, + + PROJECTION_VIEW_MAX, +}; + +struct ProjectionViewItem { + enum ProjectionViewIndex id; + bool active; +}; + +struct ProjectionLine { + cXyz pos[40]; + bool got_it; // used for lja +}; + +namespace ProjectionViewer { +void execute(); +} // namespace ProjectionViewer + +extern ProjectionLine g_ljaProjectionLine; +extern ProjectionLine g_midnaChargeProjectionLine; +extern ProjectionViewItem g_projectionViewFlags[PROJECTION_VIEW_MAX]; diff --git a/modules/features/projection_view/src/main.cpp b/modules/features/projection_view/src/main.cpp new file mode 100644 index 00000000..ce654a1a --- /dev/null +++ b/modules/features/projection_view/src/main.cpp @@ -0,0 +1,14 @@ +#include +#include "features/projection_view/include/projection_view.h" +#include "rels/include/cxx.h" +#include "events/pre_loop_listener.h" + +namespace tpgz::modules { +void main() { + g_PreLoopListener->addListener(ProjectionViewer::execute); +} +void exit() { + g_PreLoopListener->removeListener(ProjectionViewer::execute); +} + +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/projection_view/src/projection_view.cpp b/modules/features/projection_view/src/projection_view.cpp new file mode 100644 index 00000000..06f8a50d --- /dev/null +++ b/modules/features/projection_view/src/projection_view.cpp @@ -0,0 +1,75 @@ +#include "features/projection_view/include/projection_view.h" +#include "libtp_c/include/d/a/d_a_alink.h" +#include "collision_view.h" +#include "projection_view.h" +#include "rels/include/defines.h" +#include "libtp_c/include/d/d_procname.h" +#include "global_data.h" +#include "settings.h" + +namespace ProjectionViewer { + +typedef void (*drawCallback)(fopAc_ac_c*); +void searchActorForCallback(s16 actorName, drawCallback callback) { + node_class* node = g_fopAcTg_Queue.mpHead; + fopAc_ac_c* actorData = NULL; + + for (int i = 0; i < g_fopAcTg_Queue.mSize; i++) { + if (node != NULL) { + create_tag_class* tag = (create_tag_class*)node; + actorData = (fopAc_ac_c*)tag->mpTagData; + + // special check to run the callback on all valid actors if name is -1 + bool check_all_actors = actorName == -1; + + if (actorData != NULL && (actorData->mBase.mProcName == actorName || check_all_actors) && callback != NULL) { + callback(actorData); + } + } + node = node->mpNextNode; + } +} + +void drawMidnaChargePositionProjection(fopAc_ac_c* actor) { + daAlink_c* alink = (daAlink_c*)actor; + + if (alink->mActionID == daAlink_c::PROC_WOLF_ROLL_ATTACK || alink->mActionID == daAlink_c::PROC_WOLF_ROLL_ATTACK_MOVE || alink->mActionID == daAlink_c::PROC_WOLF_LOCK_ATTACK || alink->mActionID == daAlink_c::PROC_WOLF_LOCK_ATTACK_TURN) { + GXColor red = {0xFF, 0x00, 0x00, g_geometryOpacity}; + dBgS_GndChk gnd_chk; + + for (int i = 0; i < 40; i++) { + if (i < 39) { + if (alink->mWolfLockNum != 0) + dDbVw_drawLineXlu(g_midnaChargeProjectionLine.pos[i], g_midnaChargeProjectionLine.pos[i+1], red, 1, 40); + } + } + } +} + +void drawJumpAttackPositionProjection(fopAc_ac_c* actor) { + daAlink_c* alink = (daAlink_c*)actor; + + if ((alink->mActionID == daAlink_c::PROC_ATN_ACTOR_WAIT || alink->mActionID == daAlink_c::PROC_CUT_JUMP) && alink->mTargetedActor) { + GXColor red = {0xFF, 0x00, 0x00, g_geometryOpacity}; + GXColor green = {0x00, 0xFF, 0x00, g_geometryOpacity}; + + for (int i = 0; i < 40; i++) { + if (i < 39) { + dDbVw_drawLineXlu(g_ljaProjectionLine.pos[i], g_ljaProjectionLine.pos[i+1], (g_ljaProjectionLine.got_it ? green : red), 1, 20); + } + } + } +} + +#include "libtp_c/include/m_Do/m_Do_printf.h" + +KEEP_FUNC void execute() { + if (GZStng_getData(STNG_SCENE_LJA_PROJECTION, false)) { + searchActorForCallback(PROC_ALINK, drawJumpAttackPositionProjection); + } + + if (GZStng_getData(STNG_SCENE_MIDNA_CHARGE_PROJECTION, false)) { + searchActorForCallback(PROC_ALINK, drawMidnaChargePositionProjection); + } +} +} // namespace ProjectionViewer \ No newline at end of file diff --git a/modules/features/rollcheck/CMakeLists.txt b/modules/features/rollcheck/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/features/rollcheck/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/features/rollcheck/include/main.h b/modules/features/rollcheck/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/features/rollcheck/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/boot/include/rollcheck.h b/modules/features/rollcheck/include/rollcheck.h similarity index 100% rename from modules/boot/include/rollcheck.h rename to modules/features/rollcheck/include/rollcheck.h diff --git a/modules/features/rollcheck/src/main.cpp b/modules/features/rollcheck/src/main.cpp new file mode 100644 index 00000000..ed092ef3 --- /dev/null +++ b/modules/features/rollcheck/src/main.cpp @@ -0,0 +1,15 @@ +#include +#include "gz_flags.h" +#include "rollcheck.h" + +namespace tpgz::modules { +void main() { + GZFlg_addFlag( + new GZFlag{GZFLG_ROLL, ACTIVE_FUNC(STNG_TOOLS_ROLL), GAME_LOOP, RollIndicator::execute}); +} +void exit() { + auto* flg = GZFlg_removeFlag(GZFLG_ROLL); + delete flg; +} + +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/rollcheck/src/rollcheck.cpp b/modules/features/rollcheck/src/rollcheck.cpp new file mode 100644 index 00000000..91057db6 --- /dev/null +++ b/modules/features/rollcheck/src/rollcheck.cpp @@ -0,0 +1,207 @@ +#include "rollcheck.h" +#include +#include "controller.h" +#include "fifo_queue.h" +#include "libtp_c/include/d/com/d_com_inf_game.h" +#include "libtp_c/include/d/menu/d_menu_window.h" +#include "libtp_c/include/SSystem/SComponent/c_counter.h" +#include "libtp_c/include/m_Do/m_Do_printf.h" + +s32 roll_start_frame; // The frame the roll started on. Dynamically updated based on game pausing +u8 current_frame_delta; // The current frame delta between the current frame and the roll start frame. +u8 roll_end_frame; // The frame the roll ends on. Dynamically updated based on the previous action +u8 roll_early_check_frame; // The earliest frame the early check should be performed on. Dynamically updated based on the previous action. +u8 roll_late_check_frame; // The latest frame the late check should be performed on. Dynamically updated based on the previous action. +u16 previous_action; // Tracks the previous action for adjusting the frame timing window, because some actions like land dive cut the beginning of the roll short +bool game_paused; // Whether the game is paused or not. Used to determine if the roll start frame should be incremented. +char msg_buffer[20]; // Buffer for the message to be printed. + +#if DEBUG +KEEP_FUNC void RollIndicator_debug() { + OSReport("roll start frame: %d\n", roll_start_frame); + OSReport("current frame: %d\n", cCt_getFrameCount()); + OSReport("current frame delta: %d\n", current_frame_delta); +} +#endif + +KEEP_FUNC void RollIndicator::execute() { + // Only run the flow if the game is not in an event, + // the player is in human form, + // and the player pointer is valid + if (dComIfGp_getEvent().mHalt == false && dComIfGs_getTransformStatus() == STATUS_HUMAN && dComIfGp_getPlayer()) { + #if DEBUG + OSReport("-------\n"); + OSReport("running!\n"); + OSReport("current action: %d\n", dComIfGp_getPlayer()->mActionID); + #endif + + switch (dComIfGp_getPlayer()->mActionID) { + case daAlink_c::PROC_FRONT_ROLL: + // this may need to be change to a switch in the future + // if more actions are found that cut the roll short + if (previous_action == daAlink_c::PROC_DIVE_JUMP) { + roll_end_frame = 13; + roll_early_check_frame = 7; + roll_late_check_frame = 18; + } else { + roll_end_frame = 18; + roll_early_check_frame = 12; + roll_late_check_frame = 23; + } + + #if DEBUG + OSReport("target roll end frame: %d\n", roll_end_frame); + OSReport("front roll!\n"); + #endif + + /* Got it check */ + if (current_frame_delta == roll_end_frame) { + #if DEBUG + OSReport("exactly %d frames!\n", roll_end_frame); + #endif + + if (g_dComIfG_gameInfo.play.mPauseFlag) { + #if DEBUG + OSReport("game paused, incrementing start frame!\n"); + #endif + + roll_start_frame += 1; + current_frame_delta = cCt_getFrameCount() - roll_start_frame; + game_paused = true; + } else { + if (game_paused) { + game_paused = false; + roll_start_frame++; + } + + if (GZ_getButtonPressed(A) && !GZ_getButtonHold(A)) { + FIFOQueue::push("<3", Queue, 0x00CC0000); + current_frame_delta = 0; + } else { + current_frame_delta = cCt_getFrameCount() - roll_start_frame; + #if DEBUG + RollIndicator_debug(); + #endif + } + } + + /* Early check */ + } else if (current_frame_delta > roll_early_check_frame && current_frame_delta < roll_end_frame) { + #if DEBUG + OSReport("between %d and %d frames!\n", roll_early_check_frame, roll_end_frame); + #endif + if (g_dComIfG_gameInfo.play.mPauseFlag) { + #if DEBUG + OSReport("game paused, incrementing start frame!\n"); + #endif + roll_start_frame += 1; + current_frame_delta = cCt_getFrameCount() - roll_start_frame; + #if DEBUG + RollIndicator_debug(); + #endif + game_paused = true; + } else { + if (game_paused) { + game_paused = false; + roll_start_frame++; + } + + if (GZ_getButtonPressed(A) && !GZ_getButtonHold(A)) { + snprintf(msg_buffer, sizeof(msg_buffer), "early by %d", (roll_end_frame - current_frame_delta)); + FIFOQueue::push(msg_buffer, Queue, 0x0000FF00); + current_frame_delta = cCt_getFrameCount() - roll_start_frame; + } else { + current_frame_delta = cCt_getFrameCount() - roll_start_frame; + #if DEBUG + RollIndicator_debug(); + #endif + } + } + + /* Lower bounds check */ + } else if (current_frame_delta > 0 && current_frame_delta <= roll_early_check_frame) { + #if DEBUG + OSReport("too low to print!\n"); + #endif + if (g_dComIfG_gameInfo.play.mPauseFlag) { + #if DEBUG + OSReport("game paused, incrementing start frame!\n"); + #endif + roll_start_frame += 1; + current_frame_delta = cCt_getFrameCount() - roll_start_frame; + #if DEBUG + RollIndicator_debug(); + #endif + game_paused = true; + } else { + if (game_paused) { + game_paused = false; + roll_start_frame++; + } + + current_frame_delta = cCt_getFrameCount() - roll_start_frame; + #if DEBUG + RollIndicator_debug(); + #endif + } + } else { + roll_start_frame = cCt_getFrameCount(); + current_frame_delta = cCt_getFrameCount()+1 - roll_start_frame; + #if DEBUG + RollIndicator_debug(); + #endif + } + + break; + default: + #if DEBUG + OSReport("Default!\n"); + #endif + /* Upper and lower bounds check */ + if (current_frame_delta > roll_late_check_frame || current_frame_delta <= roll_end_frame) { + roll_start_frame = 0; + current_frame_delta = 0; + + /* Late check */ + } else if (current_frame_delta > roll_end_frame) { + #if DEBUG + OSReport("Between %d and %d frames!\n", roll_end_frame, roll_late_check_frame); + #endif + + if (g_dComIfG_gameInfo.play.mPauseFlag) { + #if DEBUG + OSReport("game paused, incrementing start frame!\n"); + #endif + roll_start_frame += 1; + current_frame_delta = cCt_getFrameCount() - roll_start_frame; + game_paused = true; + #if DEBUG + RollIndicator_debug(); + #endif + } else { + if (game_paused) { + game_paused = false; + roll_start_frame++; + } + + if (GZ_getButtonPressed(A) && !GZ_getButtonHold(A)) { + snprintf(msg_buffer, sizeof(msg_buffer), "late by %d", (current_frame_delta - roll_end_frame)); + FIFOQueue::push(msg_buffer, Queue, 0x99000000); + current_frame_delta = 0; + } else { + current_frame_delta = cCt_getFrameCount() - roll_start_frame; + #if DEBUG + RollIndicator_debug(); + #endif + } + } + } + + // Update the previous action to the current action + previous_action = dComIfGp_getPlayer()->mActionID; + } + } else { + roll_start_frame = 0; + current_frame_delta = 0; + } +} \ No newline at end of file diff --git a/modules/features/transform_indicator/CMakeLists.txt b/modules/features/transform_indicator/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/features/transform_indicator/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/features/transform_indicator/include/main.h b/modules/features/transform_indicator/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/features/transform_indicator/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/transform_indicator/include/transform_indicator.h b/modules/features/transform_indicator/include/transform_indicator.h new file mode 100644 index 00000000..1e23b2fc --- /dev/null +++ b/modules/features/transform_indicator/include/transform_indicator.h @@ -0,0 +1,9 @@ +#pragma once +#include "utils/texture.h" + +namespace TransformIndicator { + extern Texture l_humanTex; + extern Texture l_wolfTex; + + void draw(); +} // namespace TransformIndicator \ No newline at end of file diff --git a/modules/features/transform_indicator/src/main.cpp b/modules/features/transform_indicator/src/main.cpp new file mode 100644 index 00000000..e60816ba --- /dev/null +++ b/modules/features/transform_indicator/src/main.cpp @@ -0,0 +1,29 @@ +#include +#include "transform_indicator.h" +#include "rels/include/cxx.h" +#include "events/draw_listener.h" +#include "utils/texture.h" + +namespace tpgz::modules { +void main() { + if (TransformIndicator::l_humanTex.loadCode == TexCode::TEX_UNLOADED) { + load_texture("/tpgz/tex/hand.tex", &TransformIndicator::l_humanTex); + } + if (TransformIndicator::l_wolfTex.loadCode == TexCode::TEX_UNLOADED) { + load_texture("/tpgz/tex/wolf.tex", &TransformIndicator::l_wolfTex); + } + + g_drawListener->addListener(TransformIndicator::draw); +} +void exit() { + g_drawListener->removeListener(TransformIndicator::draw); + + if (TransformIndicator::l_humanTex.loadCode == TexCode::TEX_OK) { + free_texture(&TransformIndicator::l_humanTex); + } + if (TransformIndicator::l_wolfTex.loadCode == TexCode::TEX_OK) { + free_texture(&TransformIndicator::l_wolfTex); + } +} + +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/transform_indicator/src/transform_indicator.cpp b/modules/features/transform_indicator/src/transform_indicator.cpp new file mode 100644 index 00000000..d16ea2e9 --- /dev/null +++ b/modules/features/transform_indicator/src/transform_indicator.cpp @@ -0,0 +1,47 @@ +#include "transform_indicator.h" +#include +#include "pos_settings.h" +#include "tools.h" +#include "rels/include/defines.h" +#include "utils/texture.h" +#include "utils/draw.h" +#include "settings.h" +#include "global_data.h" +#include "libtp_c/include/d/com/d_com_inf_game.h" +#include "libtp_c/include/f_op/f_op_actor_iter.h" +#include "libtp_c/include/d/a/d_a_alink.h" + +extern daMidna_c m_midnaActor; + +#ifdef WII_PLATFORM +extern bool isWidescreen; +#define IS_WIDESCREEN isWidescreen +#else +#define IS_WIDESCREEN (false) +#endif + +namespace TransformIndicator { +Texture l_humanTex; +Texture l_wolfTex; +} // namespace TransformIndicator + +void drawTexture(GXTexObj tex, bool greyed) { + Draw::drawRect(greyed ? 0x3f3f3f7f : 0xFFFFFFFF, GZ_getSpriteOffset(STNG_SPRITES_TRANSFORM_IND), + {30 * (IS_WIDESCREEN ? 0.75f : 1.0f), 30}, &tex); +} + +KEEP_FUNC void TransformIndicator::draw() { + bool cantTransform = !((*(uint8_t*)g_dComIfG_gameInfo.play.mPlayerPtr + 0x570) & 4) || + (g_env_light.field_0x1050 & 0x80) || + (dSv_event_c__isEventBit(&g_dComIfG_gameInfo.info.mSavedata.mEvent, 0xD04U) == 0); + // TODO Add a the implementation of fopAcIt_Judge and daMidna_searchNpc for the last check. + if (dComIfGs_getTransformStatus() == 0) { + if (l_wolfTex.loadCode == TexCode::TEX_OK) { + drawTexture(l_wolfTex._texObj, !cantTransform); + } + } else { + if (l_humanTex.loadCode == TexCode::TEX_OK) { + drawTexture(l_humanTex._texObj, !cantTransform); + } + } +} \ No newline at end of file diff --git a/modules/features/trigger_view/CMakeLists.txt b/modules/features/trigger_view/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/features/trigger_view/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/features/trigger_view/include/main.h b/modules/features/trigger_view/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/features/trigger_view/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/trigger_view/include/trigger_view.h b/modules/features/trigger_view/include/trigger_view.h new file mode 100644 index 00000000..68a09d64 --- /dev/null +++ b/modules/features/trigger_view/include/trigger_view.h @@ -0,0 +1,5 @@ +#pragma once + +namespace TriggerViewer { +void execute(); +} // namespace TriggerViewer diff --git a/modules/features/trigger_view/src/main.cpp b/modules/features/trigger_view/src/main.cpp new file mode 100644 index 00000000..5a353b7a --- /dev/null +++ b/modules/features/trigger_view/src/main.cpp @@ -0,0 +1,14 @@ +#include +#include "features/trigger_view/include/trigger_view.h" +#include "rels/include/cxx.h" +#include "events/pre_loop_listener.h" + +namespace tpgz::modules { +void main() { + g_PreLoopListener->addListener(TriggerViewer::execute); +} +void exit() { + g_PreLoopListener->removeListener(TriggerViewer::execute); +} + +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/features/trigger_view/src/trigger_view.cpp b/modules/features/trigger_view/src/trigger_view.cpp new file mode 100644 index 00000000..487e6d3f --- /dev/null +++ b/modules/features/trigger_view/src/trigger_view.cpp @@ -0,0 +1,417 @@ +#include "features/trigger_view/include/trigger_view.h" +#include "collision_view.h" +#include "trigger_view.h" +#include "libtp_c/include/msl_c/math.h" +#include "settings.h" +#include "libtp_c/include/d/com/d_com_inf_game.h" +#include "libtp_c/include/m_Do/m_Do_printf.h" +#include "libtp_c/include/d/d_procname.h" +#include "libtp_c/include/f_op/f_op_actor_mng.h" +#include "libtp_c/include/JSystem/JMath.h" +#include "rels/include/defines.h" +#include "global_data.h" + +namespace TriggerViewer { + +typedef void (*drawCallback)(fopAc_ac_c*); +void searchActorForCallback(s16 actorName, drawCallback callback) { + node_class* node = g_fopAcTg_Queue.mpHead; + fopAc_ac_c* actorData = NULL; + + for (int i = 0; i < g_fopAcTg_Queue.mSize; i++) { + if (node != NULL) { + create_tag_class* tag = (create_tag_class*)node; + actorData = (fopAc_ac_c*)tag->mpTagData; + + // special check to run the callback on all valid actors if name is -1 + bool check_all_actors = actorName == -1; + + if (actorData != NULL && (actorData->mBase.mProcName == actorName || check_all_actors) && callback != NULL) { + callback(actorData); + } + node = node->mpNextNode; + } + } +} + +void drawSceneExit(fopAc_ac_c* actor) { + struct daScex_c : public fopAc_ac_c { + /* 0x568 */ Mtx mMatrix; + }; + daScex_c* scex = (daScex_c*)actor; + + cXyz points[8]; + points[0].set(-actor->mScale.x, actor->mScale.y, -actor->mScale.z); + points[1].set(actor->mScale.x, actor->mScale.y, -actor->mScale.z); + points[2].set(-actor->mScale.x, actor->mScale.y, actor->mScale.z); + points[3].set(actor->mScale.x, actor->mScale.y, actor->mScale.z); + points[4].set(-actor->mScale.x, 0.0f, -actor->mScale.z); + points[5].set(actor->mScale.x, 0.0f, -actor->mScale.z); + points[6].set(-actor->mScale.x, 0.0f, actor->mScale.z); + points[7].set(actor->mScale.x, 0.0f, actor->mScale.z); + + mDoMtx_inverse(scex->mMatrix, mDoMtx_stack_c::get()); + mDoMtx_multVecArray(mDoMtx_stack_c::get(), points, points, 8); + + GXColor color = {0xFF, 0x00, 0xFF, g_geometryOpacity}; + dDbVw_drawCube8pXlu(points, color); +} + +// this one could probably be made more accurate +void drawMidnaStop(fopAc_ac_c* actor) { + struct daMidnaStop_c : public fopAc_ac_c { + /* 0x568 */ u8 data[0x5C0 - 0x568]; + /* 0x5C0 */ f32 mRangeXZ; + /* 0x5C4 */ f32 mRangeY; + }; + daMidnaStop_c* mstop = (daMidnaStop_c*)actor; + + GXColor color = {0x4A, 0x36, 0xBA, g_geometryOpacity}; + dDbVw_drawCylinderXlu(mstop->current.pos, mstop->mScale.x * 100.0f, mstop->mScale.y, color, 1); +} + +// used a large cylinder height to represent the xz check as accurately as possible +void drawPlumTag(fopAc_ac_c* actor) { + struct daTagMyna2_c : public fopAc_ac_c {}; + + daTagMyna2_c* plum_tag = (daTagMyna2_c*)actor; + + GXColor color = {0x00, 0xFF, 0x00, g_geometryOpacity}; + dDbVw_drawCylinderXlu(plum_tag->current.pos, plum_tag->mScale.x * 100.0f, 1000000.0f, color, 1); +} + +void drawPlummSearch(fopAc_ac_c* actor) { + struct daNpc_myna2_c : public fopAc_ac_c {}; + + GXColor color = {0xFF, 0x00, 0x00, g_geometryOpacity}; + const f32 search_dist = 500.0f; // this is normally from HIO data + dDbVw_drawCircleXlu(actor->mAttentionInfo.position, search_dist + 160.0f, color, 1, 12); +} + +// this one might need to be improved? it matches the debug rom tho so idk +void drawSwitchArea(fopAc_ac_c* actor) { + struct daSwc00_c : public fopAc_ac_c { + /* 0x568 */ cXyz mStart; + /* 0x574 */ cXyz mEnd; + /* 0x580 */ u16 mEventID; + /* 0x582 */ u8 mAction; + }; + daSwc00_c* swc = (daSwc00_c*)actor; + int shape_type = (fopAcM_GetParam(actor) >> 0x12) & 3; + + GXColor color = {0x00, 0x00, 0xFF, g_geometryOpacity}; + if (shape_type == 3) { + dDbVw_drawCylinderXlu(swc->current.pos, JMAFastSqrt(swc->mScale.x) - 30.0f, swc->mScale.y, + color, 1); + } else if (shape_type == 0) { + cXyz size = swc->mEnd - swc->mStart; // diameter + size *= 0.5f; // radius + + cXyz pos = swc->mStart + size; // base + radius = center point + csXyz angle(swc->current.angle.x, swc->current.angle.y, swc->current.angle.z); + dDbVw_drawCubeXlu(pos, size, angle, color); + } +} + +void drawEventArea(fopAc_ac_c* actor) { + struct daTag_EvtArea_c : public fopAc_ac_c { + /* 0x568 */ void* vtable; + /* 0x56C */ u8 field_0x56c; + }; + + u8 type = (actor->shape_angle.z & 0xFF); + if (type == 0xFF) { + type = 0; + } + + if (type == 15 || type == 16) { + GXColor color = {0xFF, 0xFF, 0x00, g_geometryOpacity}; + cXyz points[8]; + points[0].set(-actor->mScale.x, actor->mScale.y, -actor->mScale.z); + points[1].set(actor->mScale.x, actor->mScale.y, -actor->mScale.z); + points[2].set(-actor->mScale.x, actor->mScale.y, actor->mScale.z); + points[3].set(actor->mScale.x, actor->mScale.y, actor->mScale.z); + points[4].set(-actor->mScale.x, 0.0f, -actor->mScale.z); + points[5].set(actor->mScale.x, 0.0f, -actor->mScale.z); + points[6].set(-actor->mScale.x, 0.0f, actor->mScale.z); + points[7].set(actor->mScale.x, 0.0f, actor->mScale.z); + + mDoMtx_stack_c::transS(actor->orig.pos.x, actor->orig.pos.y, actor->orig.pos.z); + mDoMtx_stack_c::YrotS(actor->current.angle.y); + mDoMtx_multVecArray(mDoMtx_stack_c::get(), points, points, 8); + + dDbVw_drawCube8pXlu(points, color); + } else { + GXColor outer_color = {0xFF, 0x00, 0x00, g_geometryOpacity}; + GXColor inner_color = {0x00, 0xFF, 0x00, g_geometryOpacity}; + cXyz pos = actor->current.pos; + // no good way to draw on the ground, so just keep height around player level + if (pos.y < dComIfGp_getPlayer()->mLinkAcch.GetGroundH()) { + pos.y = dComIfGp_getPlayer()->mLinkAcch.GetGroundH() + 100.0f; + } + + // idk the exact way the inner check is handled, so this is a rough approximation + f32 inner_scale = 0.83f; +#ifdef WII_PLATFORM + inner_scale = 0.98f; +#endif + + dDbVw_drawCircleXlu(pos, actor->mScale.x * inner_scale, inner_color, 1, 20); + dDbVw_drawCircleXlu(pos, actor->mScale.x, outer_color, 1, 20); + } +} + +void drawEventTag(fopAc_ac_c* actor) { + GXColor color = {0x00, 0xC8, 0xFF, g_geometryOpacity}; + u16 area_type = actor->orig.angle.x & 0x8000; + + if (area_type == -0x8000) { + cXyz points[8]; + + cXyz start(actor->current.pos.x - (actor->mScale.x * 0.5f), actor->current.pos.y, + actor->current.pos.z - (actor->mScale.z * 0.5f)); + + cXyz end(actor->current.pos.x + (actor->mScale.x * 0.5f), + actor->current.pos.y + actor->mScale.y, + actor->current.pos.z + (actor->mScale.z * 0.5f)); + + points[0].set(start.x, start.y, start.z); + points[1].set(start.x, start.y, end.z); + points[2].set(end.x, start.y, end.z); + points[3].set(end.x, start.y, start.z); + points[4].set(start.x, end.y, start.z); + points[5].set(start.x, end.y, end.z); + points[6].set(end.x, end.y, end.z); + points[7].set(end.x, end.y, start.z); + + dDbVw_drawCube8pXlu(points, color); + } else { + cXyz pos = actor->current.pos; + pos.y -= actor->mScale.y; + + dDbVw_drawCylinderXlu(pos, actor->mScale.x, actor->mScale.y * 2, color, 1); + } +} + +void drawTWGate(fopAc_ac_c* actor) { + GXColor color = {0xFF, 0xFF, 0xFF, g_geometryOpacity}; + dDbVw_drawCylinderXlu(actor->current.pos, actor->mScale.x * 100.0f, actor->mScale.y * 100.0f, + color, 1); +} + +static uint8_t pathColorIndex = 0; + +void drawPaths(dStage_dPath_c* paths) { + static const GXColor colors[8] = { + {0xFF, 0xFF, 0xFF}, {0x00, 0x00, 0x00}, {0xFF, 0x00, 0x00}, {0x00, 0xFF, 0x00}, + {0x00, 0x00, 0xFF}, {0xFF, 0xFF, 0x00}, {0xFF, 0x00, 0xFF}, {0x00, 0xFF, 0xFF}, + }; + + cXyz cubeSize = {30.0f, 30.0f, 30.0f}; + csXyz cubeAngle = {0, 0, 0}; + + for (int i = 0; i < paths->m_num; i++) { + dPath* path = &paths->m_path[i]; + GXColor color = colors[(pathColorIndex++) & 7]; + color.a = g_geometryOpacity; + cXyz a, b; + + // Draw a line back to the beginning if the path loops + if (dPath_ChkClose(path) && path->m_num > 2) { + a = path->m_points[0].m_position; + b = path->m_points[path->m_num - 1].m_position; + dDbVw_drawLineXlu(a, b, color, 1, 10); + } + + // Iterate over all of the points of the path + for (int j = 0; j < path->m_num - 1; j++) { + a = path->m_points[j].m_position; + b = path->m_points[j + 1].m_position; + dDbVw_drawLineXlu(a, b, color, 1, 10); // Param 3 is if z is enabled or not + dDbVw_drawCubeXlu(a, cubeSize, cubeAngle, color); + } + dDbVw_drawCubeXlu(b, cubeSize, cubeAngle, color); // Draw the cube for the end of the path + } +} + +void drawStagePaths() { + dStage_dPath_c* stagePaths = g_dComIfG_gameInfo.play.mStageData.mPath2Info; + if (stagePaths) { + drawPaths(stagePaths); + } +} + +void drawCurrentRoomPaths() { + daAlink_c* player = dComIfGp_getPlayer(); + if (player == NULL) { + return; + } + + s32 roomNo = fopAcM_GetRoomNo(player); + if (roomNo < 0 || roomNo >= 64) { + return; + } + + dStage_dPath_c* roomPaths = dStage_roomControl_c__mStatus[roomNo].mPath2Info; + if (roomPaths) { + drawPaths(roomPaths); + } +} + +void drawCheckpointTag(fopAc_ac_c* actor) { + struct daTagChgRestart_c : public fopAc_ac_c { + /* 0x568 */ cXyz mVertices[4]; + }; + daTagChgRestart_c* chk = (daTagChgRestart_c*)actor; + + GXColor color = {0x29, 0xF0, 0xFF, g_geometryOpacity}; + cXyz points[8]; + + mDoMtx_stack_c::transS(actor->current.pos.x, actor->current.pos.y, actor->current.pos.z); + mDoMtx_stack_c::YrotM(actor->current.angle.y); + + points[0] = chk->mVertices[0]; + points[1] = chk->mVertices[1]; + points[2] = chk->mVertices[3]; + points[3] = chk->mVertices[2]; + points[4] = chk->mVertices[0]; + points[5] = chk->mVertices[1]; + points[6] = chk->mVertices[3]; + points[7] = chk->mVertices[2]; + + mDoMtx_multVecArray(mDoMtx_stack_c::get(), points, points, 8); + // actor only checks XZ axis', so copy player y to keep it more accurate + for (int i = 0; i < 8; i++) { + points[i].y = dComIfGp_getPlayer()->current.pos.y; + } + + for (int i = 0; i < 4; i++) { + points[i].y += 1000.0f; + } + + dDbVw_drawCube8pXlu(points, color); +} + +void drawTransformDists(fopAc_ac_c* actor) { + if (fopAcM_GetGroup(actor) == 4 && !fopAcM_checkStatus(actor, 0x8000000)) { + GXColor near_color = {0x00, 0xFF, 0x00, g_geometryOpacity}; + GXColor far_color = {0xFF, 0x00, 0x00, g_geometryOpacity}; + + const f32 near_dist = 400.0f; + const f32 far_dist = 5000.0f; + + dDbVw_drawCircleXlu(actor->mEyePos, near_dist, near_color, 1, 20); + dDbVw_drawCircleXlu(actor->mEyePos, far_dist, far_color, 1, 20); + + const s16 view_range = 0x4000; + + cXyz offset(0.0f, 0.0f, far_dist); // set line dist + cXyz endpos; + + // draw one view range edge + mDoMtx_stack_c::transS(actor->mEyePos.x, actor->mEyePos.y, actor->mEyePos.z); + mDoMtx_stack_c::YrotM(actor->shape_angle.y); + mDoMtx_stack_c::YrotM(-view_range); + mDoMtx_stack_c::multVec(&offset, &endpos); + dDbVw_drawLineXlu(actor->mEyePos, endpos, far_color, 1, 10); + + // draw other view range edge + mDoMtx_stack_c::transS(actor->mEyePos.x, actor->mEyePos.y, actor->mEyePos.z); + mDoMtx_stack_c::YrotM(actor->shape_angle.y); + mDoMtx_stack_c::YrotM(view_range); + mDoMtx_stack_c::multVec(&offset, &endpos); + dDbVw_drawLineXlu(actor->mEyePos, endpos, far_color, 1, 10); + + // draw facing direction + mDoMtx_stack_c::transS(actor->mEyePos.x, actor->mEyePos.y, actor->mEyePos.z); + mDoMtx_stack_c::YrotM(actor->shape_angle.y); + mDoMtx_stack_c::multVec(&offset, &endpos); + dDbVw_drawLineXlu(actor->mEyePos, endpos, far_color, 1, 10); + } +} + +void drawAttentionDists(fopAc_ac_c* actor) { + GXColor lock_color = {0x00, 0x00, 0xFF, g_geometryOpacity}; + GXColor talk_color = {0x00, 0xFF, 0x00, g_geometryOpacity}; + + dAttention_dist_tbl* lock_inf = dAttention_c__getDistTable(actor->mAttentionInfo.distances[fopAc_attn_LOCK_e]); + dAttention_dist_tbl* talk_inf = dAttention_c__getDistTable(actor->mAttentionInfo.distances[fopAc_attn_TALK_e]); + cXyz& pos = actor->mAttentionInfo.position; + + if (fopAcM_GetGroup(actor) == 4) { + dDbVw_drawCircleXlu(pos, lock_inf->mDistXZMax, lock_color, 1, 20); + dDbVw_drawCircleXlu(pos, talk_inf->mDistXZMax, talk_color, 1, 20); + } +} + +void drawPurpleMistAvoid(fopAc_ac_c* actor) { + struct kytag08_class : public fopAc_ac_c { + u8 data[0x5AC - 0x568]; + /* 0x5AC */ cXyz mSize; + /* 0x5B8 */ cXyz mAvoidPos; + /* 0x5C4 */ cXyz mTargetAvoidPos; + /* 0x5D0 */ f32 mSizeScale; + /* 0x5D4 */ int mSizeTimer; + /* 0x5D8 */ u8 field_0x5d8; + }; + kytag08_class* tag = (kytag08_class*)actor; + + GXColor avoidColor = {0x00, 0xFF, 0x00, g_geometryOpacity}; + GXColor targetColor = {0xFF, 0x00, 0xFF, g_geometryOpacity}; + + dDbVw_drawCircleXlu(tag->mAvoidPos, tag->mSize.x * 45.0f * tag->mSizeScale, avoidColor, 1, 20); + + cXyz cubeSize(10.0f, 10.0f, 10.0f); + csXyz cubeAngle(0, 0, 0); + + dDbVw_drawCubeXlu(tag->mAvoidPos, cubeSize, cubeAngle, avoidColor); + dDbVw_drawCubeXlu(tag->mTargetAvoidPos, cubeSize, cubeAngle, targetColor); +} + +KEEP_FUNC void execute() { + if (g_triggerViewFlags[VIEW_LOAD_ZONES].active) { + searchActorForCallback(PROC_SCENE_EXIT, drawSceneExit); + } + + if (g_triggerViewFlags[VIEW_MIDNA_STOPS].active) { + searchActorForCallback(PROC_Tag_Mstop, drawMidnaStop); + } + + if (g_triggerViewFlags[VIEW_SWITCH_AREAS].active) { + searchActorForCallback(PROC_SWC00, drawSwitchArea); + } + + if (g_triggerViewFlags[VIEW_EVENT_AREAS].active) { + searchActorForCallback(PROC_TAG_EVENT, drawEventTag); + searchActorForCallback(PROC_TAG_EVTAREA, drawEventArea); + searchActorForCallback(PROC_TAG_MYNA2, drawPlumTag); + searchActorForCallback(PROC_MYNA2, drawPlummSearch); + } + + if (g_triggerViewFlags[VIEW_TW_GATES].active) { + searchActorForCallback(PROC_Tag_TWGate, drawTWGate); + } + + if (g_triggerViewFlags[VIEW_PATHS].active) { + pathColorIndex = 0; + drawStagePaths(); + drawCurrentRoomPaths(); + } + + if (g_triggerViewFlags[VIEW_CHG_RESTARTS].active) { + searchActorForCallback(PROC_Tag_ChgRestart, drawCheckpointTag); + } + + if (g_triggerViewFlags[VIEW_TRANSFORM_DISTS].active) { + searchActorForCallback(-1, drawTransformDists); + } + + if (g_triggerViewFlags[VIEW_ATTN_DISTS].active) { + searchActorForCallback(-1, drawAttentionDists); + } + + if (g_triggerViewFlags[VIEW_MIST_AVOID].active) { + searchActorForCallback(PROC_KYTAG08, drawPurpleMistAvoid); + } +} +} // namespace TriggerViewer \ No newline at end of file diff --git a/modules/features/umd/CMakeLists.txt b/modules/features/umd/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/features/umd/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/features/umd/include/main.h b/modules/features/umd/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/features/umd/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/boot/include/umd.h b/modules/features/umd/include/umd.h similarity index 100% rename from modules/boot/include/umd.h rename to modules/features/umd/include/umd.h diff --git a/modules/features/umd/src/main.cpp b/modules/features/umd/src/main.cpp new file mode 100644 index 00000000..0d9a507b --- /dev/null +++ b/modules/features/umd/src/main.cpp @@ -0,0 +1,15 @@ +#include +#include "gz_flags.h" +#include "umd.h" + +namespace tpgz::modules { +void main() { + GZFlg_addFlag(new GZFlag{GZFLG_UMD, ACTIVE_FUNC(STNG_TOOLS_UMD), POST_GAME_LOOP, + UMDIndicator::execute}); +} +void exit() { + auto* flg = GZFlg_removeFlag(GZFLG_UMD); + delete flg; +} + +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/boot/src/umd.cpp b/modules/features/umd/src/umd.cpp similarity index 98% rename from modules/boot/src/umd.cpp rename to modules/features/umd/src/umd.cpp index 6a5ecfab..78d5edad 100644 --- a/modules/boot/src/umd.cpp +++ b/modules/features/umd/src/umd.cpp @@ -1,4 +1,4 @@ -#include "umd.h" +#include "umd.h" #include #include "controller.h" #include "gz_flags.h" @@ -29,7 +29,7 @@ static const char* getPressedButtonText() { return ""; } -void UMDIndicator::execute() { +KEEP_FUNC void UMDIndicator::execute() { // Reset everything if map is not active if (g_meter2_info.mMapStatus != 2 && g_meter2_info.mMapStatus != 3) { counter_difference = 0; diff --git a/modules/init/src/main.cpp b/modules/init/src/main.cpp index ba033ea2..fa0aa878 100644 --- a/modules/init/src/main.cpp +++ b/modules/init/src/main.cpp @@ -1,12 +1,17 @@ #include #include "boot.h" +#include "collision_view.h" #include "fifo_queue.h" #include "font.h" #include "gz_flags.h" -#include "menu.h" +#include "scene.h" +#include "menus/menu.h" #include "menus/utils/menu_mgr.h" +#include "modules.h" +#include "tools.h" #include "utils/memory.h" +#include "utils/audio.h" #include "utils/card.h" #include "utils/draw.h" #include "utils/link.h" @@ -15,6 +20,10 @@ #include "events/draw_listener.h" #include "events/pre_loop_listener.h" #include "events/post_loop_listener.h" +#include "libtp_c/include/dolphin/os/OSCache.h" + +void GZ_PosSettings_initDefaults(); +void GZ_patchLinkColor(); namespace tpgz::modules { void main() { @@ -40,26 +49,116 @@ void main() { g_drawListener->addListener(Timer::drawTimer); g_drawListener->addListener(Timer::drawLoadTimer); g_drawListener->addListener(Timer::drawIGT); - // g_drawListener->addListener(GZ_drawMenu); g_drawListener->addListener(GZ_drawWatches); g_drawListener->addListener(GZ_renderPlayPause); + g_drawListener->addListener(GZ_drawPacketNumOverflow); + + // Init the module list + g_modules.push_back(new Module{inputViewer_active, "/tpgz/rels/features/input_viewer.rel"}); + g_modules.push_back(new Module{freeCam_active, "/tpgz/rels/features/free_cam.rel"}); + g_modules.push_back(new Module{moveLink_active, "/tpgz/rels/features/moveactor.rel"}); + g_modules.push_back(new Module{projectionView_active, "/tpgz/rels/features/projection_view.rel"}); + g_modules.push_back(new Module{triggerViewer_active, "/tpgz/rels/features/trigger_view.rel"}); + g_modules.push_back(new Module{actorView_active, "/tpgz/rels/features/actor_view.rel"}); + g_modules.push_back( + new Module{transformIndicator_active, "/tpgz/rels/features/transform_indicator.rel"}); + g_modules.push_back(new Module{umd_active, "/tpgz/rels/features/umd.rel"}); +#ifdef WII_PLATFORM + g_modules.push_back(new Module{bit_active, "/tpgz/rels/features/bit.rel"}); +#endif + g_modules.push_back(new Module{corotd_active, "/tpgz/rels/features/corotd.rel"}); + g_modules.push_back(new Module{mash_checker_active, "/tpgz/rels/features/mash_checker.rel"}); + g_modules.push_back(new Module{gorge_active, "/tpgz/rels/features/gorge.rel"}); + g_modules.push_back(new Module{rollcheck_active, "/tpgz/rels/features/rollcheck.rel"}); + g_modules.push_back(new Module{moon_jump_active, "/tpgz/rels/features/moon_jump.rel"}); + // Init the pre-loop listener g_PreLoopListener = new PreLoopListener(); g_PreLoopListener->addListener(GZ_handleCardLoad); g_PreLoopListener->addListener(GZ_handleMenu); + g_PreLoopListener->addListener(GZ_handleTools); g_PreLoopListener->addListener(GZ_handleSavingTmp); g_PreLoopListener->addListener(GZ_handleFlags_PreLoop); g_PreLoopListener->addListener(GZ_handleTurbo); g_PreLoopListener->addListener(GZ_setCursorColor); g_PreLoopListener->addListener(GZ_setTunicColor); g_PreLoopListener->addListener(GZ_frameAdvance); - g_PreLoopListener->addListener(GZ_handleTools); + g_PreLoopListener->addListener(GZ_handleModules); + g_PreLoopListener->addListener(GZ_drawPolygons); + // Init the post-loop listener g_PostLoopListener = new PostLoopListener(); g_PostLoopListener->addListener(GZ_handleFlags_PostLoop); g_PostLoopListener->addListener(GZ_setCursorColor); g_PostLoopListener->addListener(GZ_setTunicColor); + + // Init the gz flags + GZFlg_addFlag(new GZFlag{GZFLG_FREEZE_ACTOR, GZ_freezeActors_active, + GAME_LOOP, GZ_freezeActors, GZ_unfreezeActors}); + GZFlg_addFlag(new GZFlag{GZFLG_HIDE_ACTOR, GZ_hideActors_active, GAME_LOOP, + GZ_hideActors, GZ_showActors}); + GZFlg_addFlag(new GZFlag{GZFLG_FREEZE_CAMERA, GZ_freezeCamera_active, + GAME_LOOP, GZ_freezeCamera, GZ_unfreezeCamera}); + GZFlg_addFlag(new GZFlag{GZFLG_HIDE_HUD, GZ_hideHUD_active, GAME_LOOP, + GZ_hideHUD, GZ_showHUD}); + GZFlg_addFlag(new GZFlag{GZFLG_FREEZE_TIME, GZ_freezeTime_active, GAME_LOOP, + GZ_freezeTime}); + GZFlg_addFlag(new GZFlag{GZFLG_DISABLE_BGM, GZ_disableBgm_active, GAME_LOOP, + GZ_disableBGM, GZ_enableBGM}); + GZFlg_addFlag(new GZFlag{GZFLG_DISABLE_SFX, GZ_disableSFX_active, GAME_LOOP, + GZ_disableSFX, GZ_enableSFX}); } void exit() {} -} // namespace tpgz::modules \ No newline at end of file +} // namespace tpgz::modules + +void GZ_PosSettings_initDefaults() { +#ifdef GCN_PLATFORM + GZStng_add(STNG_SPRITES_INPUT_VIEWER, new Vec2{220.f, 380.f}, sizeof(Vec2)); +#elif defined(WII_PLATFORM) + GZStng_add(STNG_SPRITES_INPUT_VIEWER, new Vec2{250.f, 360.f}, sizeof(Vec2)); +#endif + GZStng_add(STNG_SPRITES_MENU, new Vec2{25.f, 60.f}, sizeof(Vec2)); + GZStng_add(STNG_SPRITES_DEBUG_INFO, new Vec2{450.0f, 200.f}, sizeof(Vec2)); + GZStng_add(STNG_SPRITES_TIMER_SPR, new Vec2{450.0f, 420.f}, sizeof(Vec2)); + GZStng_add(STNG_SPRITES_LOAD_TIMER_SPR, new Vec2{450.0f, 30.f}, sizeof(Vec2)); + GZStng_add(STNG_SPRITES_IGT_TIMER_SPR, new Vec2{35.0f, 30.f}, sizeof(Vec2)); + GZStng_add(STNG_SPRITES_FIFO_SPR, new Vec2{5.0f, 440.f}, sizeof(Vec2)); + GZStng_add(STNG_SPRITES_HEAP_INFO, new Vec2{145.0f, 25.0f}, sizeof(Vec2)); + GZStng_add(STNG_SPRITES_MASH_INFO, new Vec2{450.0f, 400.0f}, sizeof(Vec2)); + GZStng_add(STNG_SPRITES_TRANSFORM_IND, new Vec2{465.0f, 30.0f}, sizeof(Vec2)); +} + +inline void GZ_patchLinkColor() { +#ifdef WII_PLATFORM +#ifdef WII_NTSCU_10 +#define SWORD_UP_RED_ADDR 0x801176B0 +#define SWORD_UP_GREEN_ADDR 0x801176C8 +#define SWORD_UP_BLUE_ADDR 0x801176E0 +#endif +#ifdef WII_NTSCU_12 +#define SWORD_UP_RED_ADDR 0x80117de0 +#define SWORD_UP_GREEN_ADDR 0x80117df8 +#define SWORD_UP_BLUE_ADDR 0x80117e10 +#endif +#ifdef WII_NTSCJ +#define SWORD_UP_RED_ADDR 0x80117bec +#define SWORD_UP_GREEN_ADDR 0x80117c04 +#define SWORD_UP_BLUE_ADDR 0x80117c1c +#endif +#ifdef WII_PAL +#define SWORD_UP_RED_ADDR 0x80117d64 +#define SWORD_UP_GREEN_ADDR 0x80117d7c +#define SWORD_UP_BLUE_ADDR 0x80117d94 +#endif + *reinterpret_cast(SWORD_UP_RED_ADDR) = 0x60000000; // nop + DCFlushRange((void*)(SWORD_UP_RED_ADDR), sizeof(uint32_t)); + ICInvalidateRange((void*)(SWORD_UP_RED_ADDR), sizeof(uint32_t)); + *reinterpret_cast(SWORD_UP_GREEN_ADDR) = 0x60000000; // nop + DCFlushRange((void*)(SWORD_UP_GREEN_ADDR), sizeof(uint32_t)); + ICInvalidateRange((void*)(SWORD_UP_GREEN_ADDR), sizeof(uint32_t)); + *reinterpret_cast(SWORD_UP_BLUE_ADDR) = 0x60000000; // nop + DCFlushRange((void*)(SWORD_UP_BLUE_ADDR), sizeof(uint32_t)); + ICInvalidateRange((void*)(SWORD_UP_BLUE_ADDR), sizeof(uint32_t)); +#endif // WII_PLATFORM +} diff --git a/modules/menus/menu_actor_list/include/actor_list_menu.h b/modules/menus/menu_actor_list/include/actor_list_menu.h index 253eece9..57c94b60 100644 --- a/modules/menus/menu_actor_list/include/actor_list_menu.h +++ b/modules/menus/menu_actor_list/include/actor_list_menu.h @@ -1,11 +1,30 @@ -#include "menu.h" +#include "menus/menu.h" +#include "libtp_c/include/f_op/f_op_actor_mng.h" struct ActorListData { uint16_t l_index; }; +/** + * @struct procBinData + * @brief Structure for entries in res/proc_info/procs.bin + */ +struct procBinData { + s16 procId; + char procName[30]; +}__attribute__((aligned(32))); + enum { - ACTOR_ID_INDEX, + ACTOR_NAME_INDEX, + ACTOR_POSITION_X_INDEX, + ACTOR_POSITION_Y_INDEX, + ACTOR_POSITION_Z_INDEX, + ACTOR_ANGLE_X_INDEX, + ACTOR_ANGLE_Y_INDEX, + ACTOR_ANGLE_Z_INDEX, + ACTOR_PARAMS_INDEX, + + ACTOR_LIST_LINE_COUNT, }; class ActorListMenu : public Menu { @@ -15,6 +34,20 @@ class ActorListMenu : public Menu { virtual void draw(); private: - uint16_t& l_index; - Line lines[1]; -}; + void updateActorData(); + template + void updateValue(T* value, f32 smallChange, f32 largeChange, bool increase, bool largeIncrement); + void loadActorName(); + void checkAndCloseMenu(); + void checkAndRestoreMenu(); + + u16& l_index; + + Line lines[ACTOR_LIST_LINE_COUNT]; + s32 l_cameraPlay; + bool l_halt; + u8 l_menuStatus; + u8 l_windowStatus; + cXyz l_cameraPos; + cXyz l_cameraTarget; +}; \ No newline at end of file diff --git a/modules/menus/menu_actor_list/src/actor_list_menu.cpp b/modules/menus/menu_actor_list/src/actor_list_menu.cpp index 7626abde..bf506391 100644 --- a/modules/menus/menu_actor_list/src/actor_list_menu.cpp +++ b/modules/menus/menu_actor_list/src/actor_list_menu.cpp @@ -3,102 +3,375 @@ #include "memory_editor.h" #include "settings.h" #include "libtp_c/include/d/com/d_com_inf_game.h" -#include "libtp_c/include/f_op/f_op_actor_mng.h" +#include "libtp_c/include/f_op/f_op_draw_tag.h" +#include "libtp_c/include/d/d_procname.h" +#include "libtp_c/include/d/menu/d_menu_window.h" #include "gz_flags.h" #include "rels/include/defines.h" #include "menus/utils/menu_mgr.h" +#include "fs.h" +#include "global_data.h" +#include "boot/include/collision_view.h" +#include "libtp_c/include/m_Do/m_Do_printf.h" +#include "libtp_c/include/m_Do/m_Re_controller_pad.h" +#include "libtp_c/include/d/meter/d_meter_HIO.h" #ifdef GCN_PLATFORM #define CONTROLLER_RIGHT GZPad::DPAD_RIGHT #define CONTROLLER_LEFT GZPad::DPAD_LEFT +#define CONTROLLER_Z GZPad::Z +#define CONTROLLER_A GZPad::A #define MEM_SWITCH_BTN GZPad::Y #define CONTROL_TEXT "Y" +#define DELETE_TEXT "START" +#define DELETE_BUTTON GZPad::START #endif #ifdef WII_PLATFORM #define CONTROLLER_RIGHT GZPad::DPAD_RIGHT #define CONTROLLER_LEFT GZPad::DPAD_LEFT +#define CONTROLLER_Z GZPad::Z +#define CONTROLLER_A GZPad::A #define MEM_SWITCH_BTN GZPad::C #define CONTROL_TEXT "C" +#define DELETE_TEXT "PLUS" +#define DELETE_BUTTON GZPad::PLUS #endif -KEEP_FUNC ActorListMenu::ActorListMenu(Cursor& cursor, ActorListData& data) - : Menu(cursor), - l_index(data.l_index), lines{ - {"index:", ACTOR_ID_INDEX, - "List Index (Dpad to scroll / " CONTROL_TEXT " to view memory)", - false}, - } {} +/** + * @brief Used for storing entries from procs.bin + */ +procBinData l_procData; -ActorListMenu::~ActorListMenu() {} +void ring_close_proc_wrapper(void* arg) { + dMw_c__ring_close_proc(arg); +} -void ActorListMenu::draw() { - cursor.setMode(Cursor::MODE_LIST); +void collect_close_proc_wrapper(void* arg) { + dMw_c__collect_close_proc(arg); +} - if (GZ_getButtonTrig(BACK_BUTTON)) { - g_menuMgr->pop(); - return; - } +void dmap_close_proc_wrapper(void* arg) { + dMw_c__dmap_close_proc(arg); +} - switch (cursor.y) { - case ACTOR_ID_INDEX: - if (GZ_getButtonRepeat(CONTROLLER_RIGHT) && l_index < g_fopAcTg_Queue.mSize) { - l_index++; - } else if (GZ_getButtonRepeat(CONTROLLER_LEFT) && l_index > 0) { - l_index--; +void fmap_close_proc_wrapper(void* arg) { + dMw_c__fmap_close_proc(arg); +} + +void collect_save_close_proc_wrapper(void* arg) { + dMw_c__collect_save_close_proc(arg); +} + +void collect_option_close_proc_wrapper(void* arg) { + dMw_c__collect_option_close_proc(arg); +} + +void collect_letter_close_proc_wrapper(void* arg) { + dMw_c__collect_letter_close_proc(arg); +} + +void collect_fishing_close_proc_wrapper(void* arg) { + dMw_c__collect_fishing_close_proc(arg); +} + +void collect_skill_close_proc_wrapper(void* arg) { + dMw_c__collect_skill_close_proc(arg); +} + +void collect_insect_close_proc_wrapper(void* arg) { + dMw_c__collect_insect_close_proc(arg); +} + +void insect_close_proc_wrapper(void* arg) { + dMw_c__insect_close_proc(arg); +} + +typedef void (*procFunc)(void*); +procFunc move_proc[] = { + NULL, + NULL, + ring_close_proc_wrapper, + NULL, + NULL, + collect_close_proc_wrapper, + NULL, + NULL, + fmap_close_proc_wrapper, + NULL, + NULL, + dmap_close_proc_wrapper, + NULL, + NULL, + collect_save_close_proc_wrapper, + NULL, + NULL, + collect_option_close_proc_wrapper, + NULL, + NULL, + collect_letter_close_proc_wrapper, + NULL, + NULL, + collect_fishing_close_proc_wrapper, + NULL, + NULL, + collect_skill_close_proc_wrapper, + NULL, + NULL, + collect_insect_close_proc_wrapper, + NULL, + NULL, + NULL, + insect_close_proc_wrapper +}; + +/** + * @brief Checks and closes any menu that's currently open. + * + * @details This function is used to close any menu that's currently open. + * It stores the current menu status and then closes the menu by setting the status to none and running the currently open menu's closer function via move_proc function table. + * + * @note Currently the function won't catch if the menu status is in opening or closing status (two statuses during menu transitions). It will only catch the "move" status. + * We may have to account for this later. + * + * @note The move_proc function table already exists in code. We can probably just map directly to it in the future instead of defining our own. + * + */ +void ActorListMenu::checkAndCloseMenu() { + if (g_meter2_info.mMenuWindowClass) { + switch (g_meter2_info.mMenuWindowClass->mMenuStatus) { + case dMw_c::NO_MENU: + g_dComIfG_gameInfo.play.mPauseFlag = false; + break; + case dMw_c::RING_MOVE: + case dMw_c::COLLECT_MOVE: + case dMw_c::DMAP_MOVE: + case dMw_c::FMAP_MOVE: + case dMw_c::SAVE_MOVE: + case dMw_c::OPTIONS_MOVE: + case dMw_c::LETTER_MOVE: + case dMw_c::FISHING_MOVE: + case dMw_c::SKILL_MOVE: + case dMw_c::INSECT_MOVE: + case dMw_c::INSECT_AGITHA_MOVE: + l_menuStatus = g_meter2_info.mMenuWindowClass->mMenuStatus; + l_windowStatus = g_meter2_info.mWindowStatus; + g_meter2_info.mWindowStatus = dMw_c::NO_MENU; + move_proc[g_meter2_info.mMenuWindowClass->mMenuStatus](g_meter2_info.mMenuWindowClass); + g_dComIfG_gameInfo.play.mPauseFlag = false; + } + } +} + +/** + * @brief Checks and restores any menu that was previously open. + * + * @details This function is used to restore any menu that was previously open. + * It restores the menu by setting the status to the stored status and setting the currently stored menu status's corresponding window status. + * + * @note There doesn't seem to be the need to run the opener function like there is with the checkAndCloseMenu function. + * Just restoring the menu status and window status seems to be enough. + * + */ +void ActorListMenu::checkAndRestoreMenu() { + if (l_menuStatus != dMw_c::NO_MENU) { + g_dComIfG_gameInfo.play.mPauseFlag = true; + + switch (l_menuStatus) { + case dMw_c::RING_MOVE: + case dMw_c::COLLECT_MOVE: + case dMw_c::FMAP_MOVE: + case dMw_c::SAVE_MOVE: + case dMw_c::OPTIONS_MOVE: + case dMw_c::LETTER_MOVE: + case dMw_c::FISHING_MOVE: + case dMw_c::SKILL_MOVE: + case dMw_c::INSECT_MOVE: + case dMw_c::INSECT_AGITHA_MOVE: + case dMw_c::DMAP_MOVE: + g_meter2_info.mWindowStatus = l_windowStatus; + g_meter2_info.mMenuWindowClass->mMenuStatus = l_menuStatus; + break; } - break; } +} + +KEEP_FUNC ActorListMenu::ActorListMenu(Cursor& cursor, ActorListData& data) + : Menu(cursor), + l_index(data.l_index), + lines{ + {"", ACTOR_NAME_INDEX, "Z+A: freeze actor, Z+" DELETE_TEXT ": delete actor, " CONTROL_TEXT " view memory", false}, + {"", ACTOR_POSITION_X_INDEX, "dpad: +/-10.0, Z+dpad: +/-100.0", false}, + {"", ACTOR_POSITION_Y_INDEX, "dpad: +/-10.0, Z+dpad: +/-100.0", false}, + {"", ACTOR_POSITION_Z_INDEX, "dpad: +/-10.0, Z+dpad: +/-100.0", false}, + {"", ACTOR_ANGLE_X_INDEX, "dpad: +/-10, Z+dpad: +/-100", false}, + {"", ACTOR_ANGLE_Y_INDEX, "dpad: +/-10, Z+dpad: +/-100", false}, + {"", ACTOR_ANGLE_Z_INDEX, "dpad: +/-10, Z+dpad: +/-100", false}, + {"", ACTOR_PARAMS_INDEX, "current actor parameters", false}, + } { + // store camera position and target + l_cameraPos = matrixInfo.matrix_info->pos; + l_cameraTarget = matrixInfo.matrix_info->target; + + // remove any currently open menus + checkAndCloseMenu(); + + // initial data load from procs.bin + updateActorData(); + loadActorName(); + } + +ActorListMenu::~ActorListMenu() { + // restore any previously open menu + checkAndRestoreMenu(); + + // restore camera position and target + matrixInfo.matrix_info->pos = l_cameraPos; + matrixInfo.matrix_info->target = l_cameraTarget; - if (l_index > g_fopAcTg_Queue.mSize - 1) { - l_index = g_fopAcTg_Queue.mSize - 1; + dComIfGp_getEventManager().mCameraPlay = 0; + g_drawHIO.mHUDAlpha = 1.0f; + +} + +template +void ActorListMenu::updateValue(T* value, f32 smallChange, f32 largeChange, bool increase, bool largeIncrement) { + if (value != NULL) { + *value += (increase ? 1 : -1) * (largeIncrement ? largeChange : smallChange); } +} +void ActorListMenu::updateActorData() { node_class* node = g_fopAcTg_Queue.mpHead; fopAc_ac_c* actorData = NULL; + for (int i = 0; i < g_fopAcTg_Queue.mSize; i++) { if (i == l_index && node != NULL) { create_tag_class* tag = (create_tag_class*)node; actorData = (fopAc_ac_c*)tag->mpTagData; break; } + node = node->mpNextNode; } - if (actorData != NULL) { - char addressBuf[18]; - snprintf(addressBuf, sizeof(addressBuf), "Address: %08X", (uint32_t)actorData); - GZ_drawText(addressBuf, 25.0f, 100.f, 0xFFFFFFFF, GZ_checkDropShadows()); + g_currentActor = actorData; +} + +void ActorListMenu::loadActorName() { + if (g_currentActor) { + int offset = (g_currentActor->mBase.mProcName*32); + loadFile("tpgz/procs.bin", &l_procData, sizeof(l_procData), offset); + } +} + +void ActorListMenu::draw() { + g_actorViewEnabled = true; + cursor.setMode(Cursor::MODE_LIST); + + if (GZ_getButtonTrig(BACK_BUTTON)) { + // disable gadget and close menu + g_actorViewEnabled = false; + g_menuMgr->pop(); + return; + } + + bool rightPressed = GZ_getButtonRepeat(CONTROLLER_RIGHT,1); + bool leftPressed = GZ_getButtonRepeat(CONTROLLER_LEFT,1); + bool zPressed = GZ_getButtonPressed(CONTROLLER_Z); - char nameBuf[16]; - snprintf(nameBuf, sizeof(nameBuf), "Proc ID: %d", actorData->mBase.mProcName); - GZ_drawText(nameBuf, 25.0f, 120.f, 0xFFFFFFFF, GZ_checkDropShadows()); + f32 smallPosChange = 10.0f, largePosChange = 100.0f; + int smallAngleChange = 100, largeAngleChange = 1000; - char paramBuf[17]; - snprintf(paramBuf, sizeof(paramBuf), "Params: %08X", actorData->mBase.mParameters); - GZ_drawText(paramBuf, 25.0f, 140.f, 0xFFFFFFFF, GZ_checkDropShadows()); + switch (cursor.y) { + case ACTOR_NAME_INDEX: + if (GZ_getButtonRepeat(CONTROLLER_RIGHT)) { + l_index++; + if (l_index > g_fopAcTg_Queue.mSize - 1) + l_index = 0; - char angleBuf[14]; - snprintf(angleBuf, sizeof(angleBuf), "Angle: %d", actorData->shape_angle.y); - GZ_drawText(angleBuf, 25.0f, 160.f, 0xFFFFFFFF, GZ_checkDropShadows()); + updateActorData(); + loadActorName(); + } + + if (GZ_getButtonRepeat(CONTROLLER_LEFT)) { + l_index--; + if (l_index > g_fopAcTg_Queue.mSize - 1) + l_index = g_fopAcTg_Queue.mSize - 1; - char posBuf[50]; - snprintf(posBuf, sizeof(posBuf), "Position: %.1f %.1f %.1f", - actorData->current.pos.x, actorData->current.pos.y, - actorData->current.pos.z); - GZ_drawText(posBuf, 25.0f, 180.f, 0xFFFFFFFF, GZ_checkDropShadows()); + updateActorData(); + loadActorName(); + } + + if (GZ_getButtonPressed(CONTROLLER_Z) && GZ_getButtonPressed(DELETE_BUTTON)) { + if (g_currentActor) { + if (g_currentActor->mBase.mProcName != PROC_ALINK) { + fopAcM_delete(g_currentActor); + } + } + } - lines[ACTOR_ID_INDEX].printf(" <%d / %d>", l_index, g_fopAcTg_Queue.mSize - 1); + if (GZ_getButtonPressed(CONTROLLER_Z) && GZ_getButtonPressed(CONTROLLER_A)) { + if (g_currentActor) { + g_currentActor->mBase.mPauseFlag = !g_currentActor->mBase.mPauseFlag; + } + } if (GZ_getButtonTrig(MEM_SWITCH_BTN)) { switch (cursor.y) { - case ACTOR_ID_INDEX: - g_memoryEditor_addressIndex = (uint32_t)actorData; + case ACTOR_NAME_INDEX: + g_memoryEditor_addressIndex = (uint32_t)g_currentActor; g_menuMgr->push(MN_MEMORY_EDITOR_INDEX); return; } } + + break; + case ACTOR_POSITION_X_INDEX: + if (rightPressed || leftPressed) { + updateValue(&g_currentActor->current.pos.x, smallPosChange, largePosChange, rightPressed, zPressed); + } + break; + case ACTOR_POSITION_Y_INDEX: + if (rightPressed || leftPressed) { + updateValue(&g_currentActor->current.pos.y, smallPosChange, largePosChange, rightPressed, zPressed); + } + break; + case ACTOR_POSITION_Z_INDEX: + if (rightPressed || leftPressed) { + updateValue(&g_currentActor->current.pos.z, smallPosChange, largePosChange, rightPressed, zPressed); + } + break; + case ACTOR_ANGLE_X_INDEX: + if (rightPressed || leftPressed) { + updateValue(&g_currentActor->shape_angle.x, smallAngleChange, largeAngleChange, rightPressed, zPressed); + } + break; + case ACTOR_ANGLE_Y_INDEX: + if (rightPressed || leftPressed) { + updateValue(&g_currentActor->shape_angle.y, smallAngleChange, largeAngleChange, rightPressed, zPressed); + } + break; + case ACTOR_ANGLE_Z_INDEX: + if (rightPressed || leftPressed) { + updateValue(&g_currentActor->shape_angle.z, smallAngleChange, largeAngleChange, rightPressed, zPressed); + } + break; + case ACTOR_PARAMS_INDEX: + // allowing arbitrary updates here causes frequent crashes. removing for now. + break; + } + + if (g_currentActor) { + lines[ACTOR_NAME_INDEX].printf("name: <%s>", l_procData.procName); + lines[ACTOR_POSITION_X_INDEX].printf("pos-x: <%.1f>", g_currentActor->current.pos.x); + lines[ACTOR_POSITION_Y_INDEX].printf("pos-y: <%.1f>", g_currentActor->current.pos.y); + lines[ACTOR_POSITION_Z_INDEX].printf("pos-z: <%.1f>", g_currentActor->current.pos.z); + lines[ACTOR_ANGLE_X_INDEX].printf("rot-x: <0x%04X>", static_cast(g_currentActor->shape_angle.x)); + lines[ACTOR_ANGLE_Y_INDEX].printf("rot-y: <0x%04X>", static_cast(g_currentActor->shape_angle.y)); + lines[ACTOR_ANGLE_Z_INDEX].printf("rot-z: <0x%04X>", static_cast(g_currentActor->shape_angle.z)); + lines[ACTOR_PARAMS_INDEX].printf("params: 0x%08X", g_currentActor->mBase.mParameters); } - cursor.move(0, MENU_LINE_NUM); - GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); + cursor.move(0, ACTOR_LIST_LINE_COUNT); + GZ_drawMenuLines(lines, cursor.y, ACTOR_LIST_LINE_COUNT); } diff --git a/modules/menus/menu_actor_list/src/main.cpp b/modules/menus/menu_actor_list/src/main.cpp index 9d952fdb..f83256dd 100644 --- a/modules/menus/menu_actor_list/src/main.cpp +++ b/modules/menus/menu_actor_list/src/main.cpp @@ -1,6 +1,7 @@ #include #include "menus/menu_actor_list/include/actor_list_menu.h" #include "events/draw_listener.h" +#include "events/pre_loop_listener.h" #include "menus/utils/menu_mgr.h" #include "utils/draw.h" diff --git a/modules/menus/menu_actor_spawn/include/actor_spawn_menu.h b/modules/menus/menu_actor_spawn/include/actor_spawn_menu.h index 9989a758..eb95ad0c 100644 --- a/modules/menus/menu_actor_spawn/include/actor_spawn_menu.h +++ b/modules/menus/menu_actor_spawn/include/actor_spawn_menu.h @@ -1,15 +1,32 @@ -#include "menu.h" +#include "menus/menu.h" + +#define MAX_ACTORS 10 + +/** + * @struct procBinData + * @brief Structure for entries in res/proc_info/procs.bin + */ +struct procBinData { + s16 procId; + char procName[30]; +}__attribute__((aligned(32))); struct ActorSpawnData { - uint16_t l_actorID; - uint32_t l_actorParams; + Cursor cursor; + s16 l_actorID; + uint32_t l_actorParams = 0xFFFFFFFF; int8_t l_actorType = -1; uint8_t l_paramIdx; - bool l_paramsSelected; +}; + +struct ActorSpawn { + s16 id; + uint32_t params; + int8_t type; }; enum { - ACTOR_ID_INDEX, + ACTOR_NAME_INDEX, ACTOR_PARAM_INDEX, ACTOR_SUBTYPE_INDEX, ACTOR_SPAWN_INDEX, @@ -17,16 +34,18 @@ enum { class ActorSpawnMenu : public Menu { public: - ActorSpawnMenu(Cursor&, ActorSpawnData&); + ActorSpawnMenu(ActorSpawnData&); virtual ~ActorSpawnMenu(); virtual void draw(); private: - uint16_t& l_actorID; + void loadActorName(s16&); + s16& l_actorID; uint32_t& l_actorParams; int8_t& l_actorType; uint8_t& l_paramIdx; - bool& l_paramsSelected; + bool l_paramsSelected; + ActorSpawn l_actorQueue[MAX_ACTORS]; Line lines[4]; }; diff --git a/modules/menus/menu_actor_spawn/src/actor_spawn_menu.cpp b/modules/menus/menu_actor_spawn/src/actor_spawn_menu.cpp index 98661497..dc1be7de 100644 --- a/modules/menus/menu_actor_spawn/src/actor_spawn_menu.cpp +++ b/modules/menus/menu_actor_spawn/src/actor_spawn_menu.cpp @@ -3,9 +3,13 @@ #include "settings.h" #include "libtp_c/include/d/com/d_com_inf_game.h" #include "libtp_c/include/f_op/f_op_actor_mng.h" +#include "libtp_c/include/m_Do/m_Do_printf.h" #include "gz_flags.h" +#include "pos_settings.h" #include "rels/include/defines.h" #include "menus/utils/menu_mgr.h" +#include "global_data.h" +#include "fs.h" #ifdef GCN_PLATFORM #define CONTROLLER_RIGHT GZPad::DPAD_RIGHT @@ -27,17 +31,29 @@ #define CONTROL_TEXT "1/2" #endif -KEEP_FUNC ActorSpawnMenu::ActorSpawnMenu(Cursor& cursor, ActorSpawnData& data) - : Menu(cursor), l_actorID(data.l_actorID), l_actorParams(data.l_actorParams), - l_actorType(data.l_actorType), l_paramIdx(data.l_paramIdx), - l_paramsSelected(data.l_paramsSelected), +/** + * @brief Used for storing entries from procs.bin + */ +procBinData l_procData; + +#ifdef WII_PLATFORM +extern bool isWidescreen; +#else +#define isWidescreen (false) +#endif + +KEEP_FUNC ActorSpawnMenu::ActorSpawnMenu(ActorSpawnData& data) + : Menu(data.cursor), l_actorID(data.l_actorID), l_actorParams(data.l_actorParams), + l_actorType(data.l_actorType), l_paramIdx(data.l_paramIdx), l_paramsSelected(false), lines{ - {"actor id:", ACTOR_ID_INDEX, "Actor ID (Dpad / " CONTROL_TEXT " to scroll)", false}, + {"actor name:", ACTOR_NAME_INDEX, "Actor Name (Dpad / " CONTROL_TEXT " to scroll)", false}, {"actor params:", ACTOR_PARAM_INDEX, "Actor Parameters (default: 0)", false}, {"actor subtype:", ACTOR_SUBTYPE_INDEX, "Actor subtype (default: -1) (Dpad / " CONTROL_TEXT " to scroll)", false}, {"spawn", ACTOR_SPAWN_INDEX, "Spawn actor at current position", false}, - } {} + } { + loadActorName(l_actorID); + } ActorSpawnMenu::~ActorSpawnMenu() {} @@ -47,6 +63,19 @@ void actorFastCreateAtLink(short id, uint32_t parameters, int8_t subtype) { nullptr, subtype); } +void ActorSpawnMenu::loadActorName(s16& i_procName) { + if (i_procName < 0) { + i_procName = 791; + } + + if (i_procName > 791) { + i_procName = 0; + } + + int offset = i_procName*32; + loadFile("tpgz/procs.bin", &l_procData, sizeof(l_procData), offset); +} + void ActorSpawnMenu::draw() { cursor.setMode(Cursor::MODE_UNRESTRICTED); @@ -73,15 +102,19 @@ void ActorSpawnMenu::draw() { } switch (cursor.y) { - case ACTOR_ID_INDEX: + case ACTOR_NAME_INDEX: if (GZ_getButtonRepeat(CONTROLLER_RIGHT)) { l_actorID++; + loadActorName(l_actorID); } else if (GZ_getButtonRepeat(CONTROLLER_LEFT)) { l_actorID--; + loadActorName(l_actorID); } else if (GZ_getButtonRepeat(CONTROLLER_SKIP_10)) { l_actorID += 10; + loadActorName(l_actorID); } else if (GZ_getButtonRepeat(CONTROLLER_SKIP_MINUS_10)) { l_actorID -= 10; + loadActorName(l_actorID); } break; case ACTOR_SUBTYPE_INDEX: @@ -97,6 +130,10 @@ void ActorSpawnMenu::draw() { break; } + auto menu_offset = GZ_getSpriteOffset(STNG_SPRITES_MENU); + float param_offset_x = menu_offset.x + Font::getStrWidth("actor params: "); + float param_offset_y = menu_offset.y + 20.0f * (float)(int)ACTOR_PARAM_INDEX; + char buf[9]; snprintf(buf, sizeof(buf), "%08X", l_actorParams); if (l_paramsSelected) { @@ -106,6 +143,7 @@ void ActorSpawnMenu::draw() { } else if (l_paramIdx >= 0 && l_paramIdx < 8) { l_paramIdx++; } + } if (GZ_getButtonRepeat(CONTROLLER_LEFT)) { if (l_paramIdx == 0) { @@ -120,16 +158,16 @@ void ActorSpawnMenu::draw() { if (GZ_getButtonRepeat(CONTROLLER_DOWN)) { l_actorParams -= (0x10000000 >> (l_paramIdx * 4)); } - GZ_drawSelectChar(buf, 170.0f, 80.0f, l_paramIdx, 7, 0xFFFFFFFF); + GZ_drawSelectChar(buf, param_offset_x, param_offset_y, l_paramIdx, 7, 0xFFFFFFFF); } else { - Font::GZ_drawStr(buf, 170.0f, 80.0f, + Font::GZ_drawStr(buf, param_offset_x, param_offset_y, (cursor.y == ACTOR_PARAM_INDEX ? CURSOR_RGBA : 0xFFFFFFFF), GZ_checkDropShadows()); } - lines[ACTOR_ID_INDEX].printf(" <%d>", l_actorID); + lines[ACTOR_NAME_INDEX].printf("[%04X] <%s>", l_actorID, l_procData.procName); lines[ACTOR_SUBTYPE_INDEX].printf(" <%d>", l_actorType); cursor.move(8, MENU_LINE_NUM); GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); -} +} \ No newline at end of file diff --git a/modules/menus/menu_actor_spawn/src/main.cpp b/modules/menus/menu_actor_spawn/src/main.cpp index d7b31f38..baccfe6e 100644 --- a/modules/menus/menu_actor_spawn/src/main.cpp +++ b/modules/menus/menu_actor_spawn/src/main.cpp @@ -28,15 +28,13 @@ void exit() { } // namespace tpgz::modules void onCreate() { - g_menuMgr->setPersistentData(new ActorSpawnData()); - if (!g_menuMgr->getPermanentData()) { - g_menuMgr->setPermanentData(new Cursor); + if (!g_menuMgr->getPermanentData()) { + g_menuMgr->setPermanentData(new ActorSpawnData); } } void onLoad() { - l_menu = new ActorSpawnMenu(*g_menuMgr->getPermanentData(), - *g_menuMgr->getPersistentData()); + l_menu = new ActorSpawnMenu(*g_menuMgr->getPermanentData()); g_drawListener->addListener(onDraw); } @@ -49,8 +47,4 @@ void onUnload() { delete l_menu; } -void onDelete() { - auto data = g_menuMgr->getPersistentData(); - delete data; - g_menuMgr->setPersistentData(nullptr); -} +void onDelete() {} diff --git a/modules/menus/menu_ad_saves/include/ad_saves_menu.h b/modules/menus/menu_ad_saves/include/ad_saves_menu.h index 64f26d04..10483c6e 100644 --- a/modules/menus/menu_ad_saves/include/ad_saves_menu.h +++ b/modules/menus/menu_ad_saves/include/ad_saves_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" #define AD_SPECIALS_AMNT 9 diff --git a/modules/menus/menu_amounts/include/amounts_menu.h b/modules/menus/menu_amounts/include/amounts_menu.h index 8c995e52..5d103a14 100644 --- a/modules/menus/menu_amounts/include/amounts_menu.h +++ b/modules/menus/menu_amounts/include/amounts_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" struct AmountsData { uint16_t l_healthNum; diff --git a/modules/menus/menu_any_bite_saves/include/any_bite_saves_menu.h b/modules/menus/menu_any_bite_saves/include/any_bite_saves_menu.h index ee7ee3b2..aecd0681 100644 --- a/modules/menus/menu_any_bite_saves/include/any_bite_saves_menu.h +++ b/modules/menus/menu_any_bite_saves/include/any_bite_saves_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" #define ANY_BITE_SPECIALS_AMNT 18 diff --git a/modules/menus/menu_any_bite_saves/src/any_bite_saves_menu.cpp b/modules/menus/menu_any_bite_saves/src/any_bite_saves_menu.cpp index 730966b6..50aee8c9 100644 --- a/modules/menus/menu_any_bite_saves/src/any_bite_saves_menu.cpp +++ b/modules/menus/menu_any_bite_saves/src/any_bite_saves_menu.cpp @@ -24,7 +24,8 @@ KEEP_FUNC AnyBiTESavesMenu::AnyBiTESavesMenu(Cursor& cursor) {"king bulblin", BITE_KB1_INDEX, "King Bulblin 1 fight"}, {"eldin twilight", BITE_ELDIN_TWILIGHT_INDEX, "Eldin Twilight tears"}, {"lanayru twilight", BITE_LANAYRU_TWILIGHT_INDEX, "Lanayru Twilight tears"}, - {"waterfall sidehop", BITE_WATERFALL_SIDEHOP_INDEX, "Waterfall sidehop after Rutela skip"}, + {"waterfall sidehop", BITE_WATERFALL_SIDEHOP_INDEX, + "Waterfall sidehop after Rutela skip"}, {"iza", BITE_IZA_INDEX, "Steal Iza's bomb bag"}, {"messenger skip", BITE_SPR_WARP_SKIP_INDEX, "LJA to skip the Snowpeak messengers"}, {"snowpeak", BITE_SPR_INDEX, "The Snowpeak Ruins segment"}, @@ -84,11 +85,10 @@ void AnyBiTESavesMenu::draw() { special(BITE_PALACE_2_INDEX, nullptr, SaveMngSpecial_Palace2), special(BITE_BEAST_GANON_INDEX, BeastGanonSpecial_setLayer, nullptr), }; - SaveManager::triggerLoad(cursor.y, "any_bite", AnySpecials, - sizeof(AnySpecials) / sizeof(AnySpecials[0])); + SaveManager::triggerLoad(cursor.y, "any_bite", AnySpecials, ARRAY_COUNT(AnySpecials)); g_menuMgr->hide(); } - cursor.move(0, sizeof(lines) / sizeof(lines[0])); - GZ_drawMenuLines(lines, cursor.y, sizeof(lines) / sizeof(lines[0])); + cursor.move(0, ARRAY_COUNT(lines)); + GZ_drawMenuLines(lines, cursor.y, ARRAY_COUNT(lines)); } \ No newline at end of file diff --git a/modules/menus/menu_any_saves/include/any_saves_menu.h b/modules/menus/menu_any_saves/include/any_saves_menu.h index 90e88ac6..38a85225 100644 --- a/modules/menus/menu_any_saves/include/any_saves_menu.h +++ b/modules/menus/menu_any_saves/include/any_saves_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" #ifdef GCN_PLATFORM #define ANY_SPECIALS_AMNT 21 diff --git a/modules/menus/menu_any_saves/src/any_saves_menu.cpp b/modules/menus/menu_any_saves/src/any_saves_menu.cpp index 0b4f293d..54792456 100644 --- a/modules/menus/menu_any_saves/src/any_saves_menu.cpp +++ b/modules/menus/menu_any_saves/src/any_saves_menu.cpp @@ -131,7 +131,7 @@ void AnySavesMenu::draw() { special(ORDON_GATE_CLIP_INDEX, nullptr, SaveMngSpecial_OrdonRock), special(HUGO_INDEX, SaveMngSpecial_Hugo, SaveMngSpecial_SpawnHugo), special(KARG_INDEX, SaveMngSpecial_KargOoB, nullptr), - special(PLUMM_OOB_INDEX, SaveMngSpecial_Iza1Skip, nullptr), + special(PLUMM_OOB_INDEX, SaveMngSpecial_AnyPlummOoB, nullptr), special(LAKEBED_BK_SKIP_INDEX, SaveMngSpecial_LakebedBKSkip, nullptr), special(ONEBOMB_INDEX, nullptr, SaveMngSpecial_Morpheel), special(STALLORD_INDEX, SaveMngSpecial_Stallord, nullptr), @@ -149,6 +149,7 @@ void AnySavesMenu::draw() { special(PALACE_2_INDEX, nullptr, SaveMngSpecial_Palace2), special(BEAST_GANON_INDEX, BeastGanonSpecial_setLayer, nullptr), special(ELH_INDEX, SaveMngSpecial_emptyLake, nullptr), + special(IZA_INDEX, SaveMngSpecial_BossFlags, nullptr), }; #endif #ifdef WII_PLATFORM @@ -168,11 +169,10 @@ void AnySavesMenu::draw() { special(BEAST_GANON_INDEX, BeastGanonSpecial_setLayer, nullptr), }; #endif - SaveManager::triggerLoad(cursor.y, "any", AnySpecials, - sizeof(AnySpecials) / sizeof(AnySpecials[0])); + SaveManager::triggerLoad(cursor.y, "any", AnySpecials, ARRAY_COUNT(AnySpecials)); g_menuMgr->hide(); } - cursor.move(0, sizeof(lines) / sizeof(lines[0])); - GZ_drawMenuLines(lines, cursor.y, sizeof(lines) / sizeof(lines[0])); + cursor.move(0, ARRAY_COUNT(lines)); + GZ_drawMenuLines(lines, cursor.y, ARRAY_COUNT(lines)); } \ No newline at end of file diff --git a/modules/menus/menu_cheats/include/cheats_menu.h b/modules/menus/menu_cheats/include/cheats_menu.h index e7f958f1..625f8fd1 100644 --- a/modules/menus/menu_cheats/include/cheats_menu.h +++ b/modules/menus/menu_cheats/include/cheats_menu.h @@ -1,8 +1,40 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" #include "cheats.h" +#ifdef GCN_PLATFORM +#define CHEAT_AMNT 15 +#define MOON_JUMP_TEXT "R+A" +#endif + +#ifdef WII_PLATFORM +#define CHEAT_AMNT 16 +#define MOON_JUMP_TEXT "Z+C+A" +#endif + +enum CheatId { + InfiniteAir, + InfiniteArrows, + InfiniteBombs, + InfiniteHearts, + InfiniteOil, + InfiniteRupees, + InfiniteSlingshot, + Invincible, + InvincibleEnemies, + MoonJump, + DoorStorage, + SuperClawshot, + UnrestrictedItems, + TransformAnywhere, + DisableItemTimer, +#ifdef WII_PLATFORM + GaleLJA, +#endif + SuperSpinner, +}; + class CheatsMenu : public Menu { public: CheatsMenu(Cursor&); diff --git a/modules/menus/menu_cheats/src/cheat_menu.cpp b/modules/menus/menu_cheats/src/cheat_menu.cpp index c30552a4..22287834 100644 --- a/modules/menus/menu_cheats/src/cheat_menu.cpp +++ b/modules/menus/menu_cheats/src/cheat_menu.cpp @@ -5,48 +5,72 @@ #include "rels/include/patch.h" #include "libtp_c/include/defines.h" #include "gz_flags.h" +#include "settings.h" #include "rels/include/defines.h" #include "menus/utils/menu_mgr.h" KEEP_FUNC CheatsMenu::CheatsMenu(Cursor& cursor) : Menu(cursor), lines{ {"infinite air", InfiniteAir, "Gives infinite air underwater", true, - &g_cheats[InfiniteAir].active}, + ACTIVE_FUNC(STNG_CHEATS_INFINITE_AIR)}, {"infinite arrows", InfiniteArrows, "Always have 99 arrows", true, - &g_cheats[InfiniteArrows].active}, + ACTIVE_FUNC(STNG_CHEATS_INFINITE_ARROWS)}, {"infinite bombs", InfiniteBombs, "Always have 99 bombs", true, - &g_cheats[InfiniteBombs].active}, + ACTIVE_FUNC(STNG_CHEATS_INFINITE_BOMBS)}, {"infinite hearts", InfiniteHearts, "Always have full hearts", true, - &g_cheats[InfiniteHearts].active}, + ACTIVE_FUNC(STNG_CHEATS_INFINITE_HEARTS)}, {"infinite oil", InfiniteOil, "Gives infinite lantern oil", true, - &g_cheats[InfiniteOil].active}, + ACTIVE_FUNC(STNG_CHEATS_INFINITE_OIL)}, {"infinite rupees", InfiniteRupees, "Always have 1000 rupees", true, - &g_cheats[InfiniteRupees].active}, + ACTIVE_FUNC(STNG_CHEATS_INFINITE_RUPEES)}, {"infinite slingshot", InfiniteSlingshot, "Always have 99 slingshot pellets", true, - &g_cheats[InfiniteSlingshot].active}, + ACTIVE_FUNC(STNG_CHEATS_INFINITE_SLINGSHOT)}, {"invincible", Invincible, "Disables Link's hurtbox", true, - &g_cheats[Invincible].active}, + ACTIVE_FUNC(STNG_CHEATS_INVINCIBLE)}, {"invincible enemies", InvincibleEnemies, "Make some enemies invincible", - true, &g_cheats[InvincibleEnemies].active}, + true, ACTIVE_FUNC(STNG_CHEATS_INVINCIBLE_ENEMIES)}, {"moon jump", MoonJump, "Hold " MOON_JUMP_TEXT " to moon jump", true, - &g_cheats[MoonJump].active}, + ACTIVE_FUNC(STNG_CHEATS_MOON_JUMP)}, {"disable walls", DoorStorage, "Disables most wall collision", true, - &g_cheats[DoorStorage].active}, + ACTIVE_FUNC(STNG_CHEATS_DOOR_STORAGE)}, {"super clawshot", SuperClawshot, "Super fast / long Clawshot", true, - &g_cheats[SuperClawshot].active}, + ACTIVE_FUNC(STNG_CHEATS_SUPER_CLAWSHOT)}, {"unrestricted items", UnrestrictedItems, "Disable item restrictions", true, - &g_cheats[UnrestrictedItems].active}, + ACTIVE_FUNC(STNG_CHEATS_UNRESTRICTED_ITEMS)}, {"transform anywhere", TransformAnywhere, "Transform at any location", true, - &g_cheats[TransformAnywhere].active}, + ACTIVE_FUNC(STNG_CHEATS_TRANSFORM_ANYWHERE)}, + {"disable item timer", DisableItemTimer, "Disable item delete timer", true, + ACTIVE_FUNC(STNG_CHEATS_DISABLE_ITEM_TIMER)}, #ifdef WII_PLATFORM - {"gale LJA", GaleLJA, "Yeet everywhere", true, &g_cheats[GaleLJA].active}, + {"gale LJA", GaleLJA, "Yeet everywhere", true, ACTIVE_FUNC(STNG_CHEATS_GALE_LJA)}, #endif } { } CheatsMenu::~CheatsMenu() {} +GZSettingID l_mapping[] = { + STNG_CHEATS_INFINITE_AIR, + STNG_CHEATS_INFINITE_ARROWS, + STNG_CHEATS_INFINITE_BOMBS, + STNG_CHEATS_INFINITE_HEARTS, + STNG_CHEATS_INFINITE_OIL, + STNG_CHEATS_INFINITE_RUPEES, + STNG_CHEATS_INFINITE_SLINGSHOT, + STNG_CHEATS_INVINCIBLE, + STNG_CHEATS_INVINCIBLE_ENEMIES, + STNG_CHEATS_MOON_JUMP, + STNG_CHEATS_DOOR_STORAGE, + STNG_CHEATS_SUPER_CLAWSHOT, + STNG_CHEATS_UNRESTRICTED_ITEMS, + STNG_CHEATS_TRANSFORM_ANYWHERE, + STNG_CHEATS_DISABLE_ITEM_TIMER, +#ifdef WII_PLATFORM + STNG_CHEATS_GALE_LJA, +#endif +}; + void CheatsMenu::draw() { cursor.move(0, MENU_LINE_NUM); @@ -56,7 +80,22 @@ void CheatsMenu::draw() { } if (GZ_getButtonTrig(SELECTION_BUTTON)) { - g_cheats[cursor.y].active = !g_cheats[cursor.y].active; + auto* stng = GZStng_get(l_mapping[cursor.y]); + if (stng) { + *(bool*)stng->data = !*(bool*)stng->data; + } else { + GZStng_add(l_mapping[cursor.y], new bool(true), sizeof(bool)); + } + } + + char buf[100]; + if (cursor.y == MoonJump) { + uint16_t combo = GZStng_getData(STNG_CMD_MOON_JUMP, MOON_JUMP_BUTTONS); + char* comboStr = new char[GZCmd_getComboLen(combo) + 1]; + GZCmd_comboToStr(combo, comboStr); + snprintf(buf, sizeof(buf), "Hold %s to moon jump", comboStr); + delete[] comboStr; + strncpy(lines[cursor.y].description, buf, sizeof(lines[cursor.y].description)); } GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); diff --git a/modules/menus/menu_collision_view/CMakeLists.txt b/modules/menus/menu_collision_view/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/menus/menu_collision_view/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/menus/menu_collision_view/include/collision_view_menu.h b/modules/menus/menu_collision_view/include/collision_view_menu.h new file mode 100644 index 00000000..4a24c303 --- /dev/null +++ b/modules/menus/menu_collision_view/include/collision_view_menu.h @@ -0,0 +1,13 @@ +#pragma once + +#include "menus/menu.h" + +class CollisionViewMenu : public Menu { +public: + CollisionViewMenu(Cursor&); + virtual ~CollisionViewMenu(); + virtual void draw(); + +private: + Line lines[10]; +}; diff --git a/modules/menus/menu_collision_view/include/main.h b/modules/menus/menu_collision_view/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/menus/menu_collision_view/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/menus/menu_collision_view/src/collision_view_menu.cpp b/modules/menus/menu_collision_view/src/collision_view_menu.cpp new file mode 100644 index 00000000..57890aa9 --- /dev/null +++ b/modules/menus/menu_collision_view/src/collision_view_menu.cpp @@ -0,0 +1,67 @@ +#include +#include "collision_view.h" +#include "menus/menu_collision_view/include/collision_view_menu.h" +#include "settings.h" +#include "libtp_c/include/d/com/d_com_inf_game.h" +#include "libtp_c/include/f_op/f_op_actor_mng.h" +#include "gz_flags.h" +#include "rels/include/defines.h" +#include "menus/utils/menu_mgr.h" + +KEEP_FUNC CollisionViewMenu::CollisionViewMenu(Cursor& cursor) + : Menu(cursor), lines{ + {"attack colliders", VIEW_AT_CC, "view hitbox colliders", true, + [](){return g_collisionFlags[VIEW_AT_CC].active;}}, + {"target colliders", VIEW_TG_CC, "view hurtbox colliders", true, + [](){return g_collisionFlags[VIEW_TG_CC].active;}}, + {"push colliders", VIEW_CO_CC, "view push colliders", true, + [](){return g_collisionFlags[VIEW_CO_CC].active;}}, + {"ground polys", VIEW_POLYGON_GROUND, "view ground polygons", true, + [](){return g_collisionFlags[VIEW_POLYGON_GROUND].active;}}, + {"roof polys", VIEW_POLYGON_ROOF, "view roof polygons", true, + [](){return g_collisionFlags[VIEW_POLYGON_ROOF].active;}}, + {"wall polys", VIEW_POLYGON_WALL, "view wall polygons", true, + [](){return g_collisionFlags[VIEW_POLYGON_WALL].active;}}, + {"poly edges", VIEW_POLYGON_EDGES, "view polygon edges", true, + [](){return g_collisionFlags[VIEW_POLYGON_EDGES].active;}}, + {"poly draw range:", 7, "max range for polygons to draw"}, + {"poly draw raise:", 8, "amount to raise the drawn polygon by"}, + {"opacity:", 9, "opacity of drawn geometry"}, + } {} + +CollisionViewMenu::~CollisionViewMenu() {} + +void CollisionViewMenu::draw() { + cursor.setMode(Cursor::MODE_LIST); + + if (GZ_getButtonTrig(BACK_BUTTON)) { + g_menuMgr->pop(); + return; + } + + if (GZ_getButtonTrig(SELECTION_BUTTON)) { + g_collisionFlags[cursor.y].active = !g_collisionFlags[cursor.y].active; + } + + switch (cursor.y) { + case 7: + Cursor::moveList(g_collisionRange); + break; + case 8: + Cursor::moveList(g_collisionRaise); + break; + case 9: + Cursor::moveList(g_geometryOpacity); + break; + } + + if (g_collisionRange > 1000) + g_collisionRange = 0; + + lines[7].printf(" <%d>", g_collisionRange); + lines[8].printf(" <%d>", g_collisionRaise); + lines[9].printf(" <%d>", g_geometryOpacity); + + cursor.move(0, MENU_LINE_NUM); + GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); +} diff --git a/modules/menus/menu_collision_view/src/main.cpp b/modules/menus/menu_collision_view/src/main.cpp new file mode 100644 index 00000000..654a6a5f --- /dev/null +++ b/modules/menus/menu_collision_view/src/main.cpp @@ -0,0 +1,50 @@ +#include +#include "menus/menu_collision_view/include/collision_view_menu.h" +#include "events/draw_listener.h" +#include "menus/utils/menu_mgr.h" +#include "utils/draw.h" + +void onCreate(); +void onLoad(); +void onDraw(); +void onUnload(); +void onDelete(); + +CollisionViewMenu* l_menu; + +namespace tpgz::modules { +void main() { + g_menuMgr->setCreateHook(onCreate); + g_menuMgr->setLoadHook(onLoad); + g_menuMgr->setUnloadHook(onUnload); + g_menuMgr->setDeleteHook(onDelete); +} +void exit() { + g_menuMgr->setCreateHook(nullptr); + g_menuMgr->setLoadHook(nullptr); + g_menuMgr->setUnloadHook(nullptr); + g_menuMgr->setDeleteHook(nullptr); +} +} // namespace tpgz::modules + +void onCreate() { + if (!g_menuMgr->getPermanentData()) { + g_menuMgr->setPermanentData(new Cursor); + } +} + +void onLoad() { + l_menu = new CollisionViewMenu(*g_menuMgr->getPermanentData()); + g_drawListener->addListener(onDraw); +} + +void onDraw() { + l_menu->draw(); +} + +void onUnload() { + g_drawListener->removeListener(onDraw); + delete l_menu; +} + +void onDelete() {} diff --git a/modules/menus/menu_combo/CMakeLists.txt b/modules/menus/menu_combo/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/menus/menu_combo/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/menus/menu_combo/include/combo_menu.h b/modules/menus/menu_combo/include/combo_menu.h new file mode 100644 index 00000000..e97674bb --- /dev/null +++ b/modules/menus/menu_combo/include/combo_menu.h @@ -0,0 +1,48 @@ +#pragma once + +#include "menus/menu.h" +#include "tools.h" + +/// 3 seconds of inactivity before going back from combo mode to normal mode +#define COMBO_MODE_INACTIVITY_TIMEOUT (90) + +struct ComboData { + uint8_t l_tunicCol_idx; +}; + +enum ComboId { + CMB_FRAME_PAUSE, + CMB_FRAME_ADVANCE, + CMB_TIMER_TOGGLE, + CMB_TIMER_RESET, + CMB_STORE_POSITION, + CMB_LOAD_POSITION, + CMB_RELOAD_AREA, + CMB_FREE_CAM, + CMB_MOVE_LINK, +#ifdef WII_PLATFORM + CMB_BIT, +#endif + CMB_GORGE_VOID, + CMB_MOON_JUMP, + + CMB_COUNT, +}; + +class ComboMenu : public Menu { +public: + ComboMenu(Cursor&, ComboData&); + virtual ~ComboMenu(); + virtual void draw(); + void execute(); + void renderLine(int i, uint16_t cmb); + +private: + bool m_inputMode = false; + bool m_selectBtnActive = false; + uint16_t m_buttons = 0; + uint16_t m_prevButtons = 0; + size_t m_keepInputModeCounter = 0; + + Line lines[CMB_COUNT]; +}; \ No newline at end of file diff --git a/modules/menus/menu_combo/include/main.h b/modules/menus/menu_combo/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/menus/menu_combo/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/menus/menu_combo/src/combo_menu.cpp b/modules/menus/menu_combo/src/combo_menu.cpp new file mode 100644 index 00000000..57cd5093 --- /dev/null +++ b/modules/menus/menu_combo/src/combo_menu.cpp @@ -0,0 +1,157 @@ +#include "menus/menu_combo/include/combo_menu.h" +#include +#include "commands.h" +#include "global_data.h" +#include "timer.h" +#include "libtp_c/include/d/com/d_com_inf_game.h" +#include "libtp_c/include/utils.h" +#include "gz_flags.h" +#include "rels/include/defines.h" +#include "rels/include/defines.h" +#include "menus/utils/menu_mgr.h" + +#ifdef GCN_PLATFORM +#define RESET_COMBO_TEXT "X" +#define RESET_COMBO_BUTTONS GZPad::X +#endif +#ifdef WII_PLATFORM +#define RESET_COMBO_TEXT "Minus" +#define RESET_COMBO_BUTTONS GZPad::MINUS +#endif + +KEEP_FUNC ComboMenu::ComboMenu(Cursor& cursor, ComboData& data) + : Menu(cursor), + lines{ + {"frame pause: ", CMB_FRAME_PAUSE, "[Reset: " RESET_COMBO_TEXT "] Combo to Pause the game"}, + {"frame advance: ", CMB_FRAME_ADVANCE, "[Reset: " RESET_COMBO_TEXT "] Combo to Advance the game by 1 frame"}, + {"timer toggle: ", CMB_TIMER_TOGGLE, "[Reset: " RESET_COMBO_TEXT "] Combo to Toggle the timer"}, + {"timer reset: ", CMB_TIMER_RESET, "[Reset: " RESET_COMBO_TEXT "] Combo to Reset the timer"}, + {"store position: ", CMB_STORE_POSITION, "[Reset: " RESET_COMBO_TEXT "] Combo to Store the player's position"}, + {"load position: ", CMB_LOAD_POSITION, "[Reset: " RESET_COMBO_TEXT "] Combo to Load the player's position"}, + {"reload area: ", CMB_RELOAD_AREA, "[Reset: " RESET_COMBO_TEXT "] Combo to Reload the area"}, + {"free cam: ", CMB_FREE_CAM, "[Reset: " RESET_COMBO_TEXT "] Combo to Toggle Free Cam"}, + {"move link: ", CMB_MOVE_LINK, "[Reset: " RESET_COMBO_TEXT "] Combo to Toggle Move Link"}, +#ifdef WII_PLATFORM + {"bit: ", CMB_BIT, "[Reset: " RESET_COMBO_TEXT "] Combo to load the BiT save file"}, +#endif + {"gorge void: ", CMB_GORGE_VOID, "[Reset: " RESET_COMBO_TEXT "] Combo to load the Gorge Void save file"}, + {"moon jump: ", CMB_MOON_JUMP, "[Reset: " RESET_COMBO_TEXT "] Combo to Moon Jump"}, + } {} + +ComboMenu::~ComboMenu() {} + +GZSettingID l_mapping[] = { + STNG_CMD_FRAME_PAUSE, + STNG_CMD_FRAME_ADVANCE, + STNG_CMD_TIMER_TOGGLE, + STNG_CMD_TIMER_RESET, + STNG_CMD_STORE_POSITION, + STNG_CMD_LOAD_POSITION, + STNG_CMD_RELOAD_AREA, + STNG_CMD_FREE_CAM, + STNG_CMD_MOVE_LINK, +#ifdef WII_PLATFORM + STNG_CMD_BIT, +#endif + STNG_CMD_GORGE_VOID, + STNG_CMD_MOON_JUMP, +}; + +int l_cmdMapping[] = { + CMD_FRAME_PAUSE, + -1, + CMD_TIMER_TOGGLE, + CMD_TIMER_RESET, + CMD_STORE_POSITION, + CMD_LOAD_POSITION, + CMD_RELOAD_AREA, + CMD_FREE_CAM, + CMD_MOVE_LINK, +#ifdef WII_PLATFORM + CMD_BIT, +#endif + CMD_GORGE_VOID, + CMD_MOON_JUMP, +}; + +void ComboMenu::execute() { + if (m_inputMode) { + if (!m_selectBtnActive) { + m_prevButtons = m_buttons; + m_buttons = GZ_getButtonStatusSaved(); + } + uint16_t released = ~m_buttons & m_prevButtons; + + if ((released != 0 && !m_selectBtnActive) || m_keepInputModeCounter == 0) { + if (released != 0 && !m_selectBtnActive) { + GZStng_add(l_mapping[cursor.y], new uint16_t(m_prevButtons), sizeof(uint16_t)); + if (l_cmdMapping[cursor.y] >= 0) { + auto* cmd = GZCmd_getCmd(l_cmdMapping[cursor.y]); + if (cmd) { + cmd->buttons = m_prevButtons; + } + } + } + m_inputMode = false; + m_keepInputModeCounter = 0; + m_buttons = 0; + m_prevButtons = 0; + m_selectBtnActive = false; + for (int i = 0; i < CMB_COUNT; i++) { + lines[i].disabled = false; + } + } + } +} + +void ComboMenu::renderLine(int i, uint16_t cmb) { + char* comboStr = new char[GZCmd_getComboLen(cmb) + 1]; + GZCmd_comboToStr(cmb, comboStr); + snprintf(lines[i].value, sizeof(lines[i].value), "[%s]", comboStr); + delete[] comboStr; +} + +void ComboMenu::draw() { + if (GZ_getButtonTrig(BACK_BUTTON) && !m_inputMode) { + g_menuMgr->pop(); + return; + } + + if (GZ_getButtonTrig(RESET_COMBO_BUTTONS) && !m_inputMode) { + GZStng_remove(l_mapping[cursor.y]); + } + + if (GZ_getButtonTrig(SELECTION_BUTTON) && !m_inputMode) { + m_inputMode = true; + m_selectBtnActive = true; + m_keepInputModeCounter = COMBO_MODE_INACTIVITY_TIMEOUT; + for (int i = 0; i < CMB_COUNT; i++) { + if (i != cursor.y) { + lines[i].disabled = true; + } + } + } + + if (m_selectBtnActive && !GZ_getButtonPressed(SELECTION_BUTTON)) { + m_selectBtnActive = false; + } + + for (int i = 0; i < CMB_COUNT; i++) { + uint16_t cmb = GZStng_getData(l_mapping[i], (uint16_t)0); + renderLine(i, cmb); + } + + if (m_inputMode) { + if (!m_selectBtnActive) { + renderLine(cursor.y, m_buttons); + } + } else { + cursor.move(0, MENU_LINE_NUM); + } + + if (m_keepInputModeCounter > 0) { + --m_keepInputModeCounter; + } + + GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); +} diff --git a/modules/menus/menu_combo/src/main.cpp b/modules/menus/menu_combo/src/main.cpp new file mode 100644 index 00000000..c5b0a062 --- /dev/null +++ b/modules/menus/menu_combo/src/main.cpp @@ -0,0 +1,64 @@ +#include +#include "menus/menu_combo/include/combo_menu.h" +#include "events/draw_listener.h" +#include "events/pre_loop_listener.h" +#include "menus/utils/menu_mgr.h" +#include "utils/draw.h" + +void onCreate(); +void onLoad(); +void onPreLoop(); +void onDraw(); +void onUnload(); +void onDelete(); + +ComboMenu* l_comboMenu; + +namespace tpgz::modules { +void main() { + g_menuMgr->setCreateHook(onCreate); + g_menuMgr->setLoadHook(onLoad); + g_menuMgr->setUnloadHook(onUnload); + g_menuMgr->setDeleteHook(onDelete); +} +void exit() { + g_menuMgr->setCreateHook(nullptr); + g_menuMgr->setLoadHook(nullptr); + g_menuMgr->setUnloadHook(nullptr); + g_menuMgr->setDeleteHook(nullptr); +} +} // namespace tpgz::modules + +void onCreate() { + g_menuMgr->setPersistentData(new ComboData()); + if (!g_menuMgr->getPermanentData()) { + g_menuMgr->setPermanentData(new Cursor); + } +} + +void onLoad() { + l_comboMenu = new ComboMenu(*g_menuMgr->getPermanentData(), + *g_menuMgr->getPersistentData()); + g_drawListener->addListener(onDraw); + g_PreLoopListener->addListener(onPreLoop); +} + +void onPreLoop() { + l_comboMenu->execute(); +} + +void onDraw() { + l_comboMenu->draw(); +} + +void onUnload() { + g_PreLoopListener->removeListener(onPreLoop); + g_drawListener->removeListener(onDraw); + delete l_comboMenu; +} + +void onDelete() { + auto data = g_menuMgr->getPersistentData(); + delete data; + g_menuMgr->setPersistentData(nullptr); +} diff --git a/modules/menus/menu_credits/CMakeLists.txt b/modules/menus/menu_credits/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/menus/menu_credits/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/menus/menu_credits/include/credits_menu.h b/modules/menus/menu_credits/include/credits_menu.h new file mode 100644 index 00000000..387e3012 --- /dev/null +++ b/modules/menus/menu_credits/include/credits_menu.h @@ -0,0 +1,10 @@ +#pragma once + +#include "menus/menu.h" + +class CreditsMenu : public Menu { +public: + CreditsMenu(Cursor& cursor); + virtual ~CreditsMenu(); + virtual void draw(); +}; \ No newline at end of file diff --git a/modules/menus/menu_credits/include/main.h b/modules/menus/menu_credits/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/menus/menu_credits/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/menus/menu_credits/src/credits_menu.cpp b/modules/menus/menu_credits/src/credits_menu.cpp new file mode 100644 index 00000000..e41ecd02 --- /dev/null +++ b/modules/menus/menu_credits/src/credits_menu.cpp @@ -0,0 +1,56 @@ +#include "menus/menu_credits/include/credits_menu.h" +#include +#include "libtp_c/include/d/com/d_com_inf_game.h" +#include "libtp_c/include/d/meter/d_meter_HIO.h" +#include "gz_flags.h" +#include "rels/include/defines.h" +#include "menus/utils/menu_mgr.h" +#include "utils/draw.h" + +#ifdef WII_PLATFORM +extern bool isWidescreen; +#else +#define isWidescreen (false) +#endif + +KEEP_FUNC CreditsMenu::CreditsMenu(Cursor& cursor) : Menu(cursor) {} + +CreditsMenu::~CreditsMenu() {} + +Texture l_creditsHeart; + +void CreditsMenu::draw() { + if (l_creditsHeart.loadCode == TexCode::TEX_UNLOADED) { + load_texture("/tpgz/tex/heart.tex", &l_creditsHeart); + } + + float scale = isWidescreen ? 0.75f : 1.0f; + float offset = isWidescreen ? 100.0f : 0.0f; + + if (l_creditsHeart.loadCode == TexCode::TEX_OK) { + Draw::drawRect(0xFFFFFFFF, {offset + 315.0f * scale, 65.0f},{30 * scale, 30}, &l_creditsHeart._texObj); + } + + if (GZ_getButtonTrig(BACK_BUTTON)) { + g_menuMgr->pop(); + return; + } + + Font::GZ_drawStr("tpgz - the twilight princess practice rom", offset + 25.0f * scale, 60.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 25.0f); + Font::GZ_drawStr("made with", offset + 175.0f * scale, 90.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 25.0f); + Font::GZ_drawStr("by", offset + 360.0f * scale, 90.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 25.0f); + + Font::GZ_drawStr("kipcode", offset + 135.0f * scale, 110.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 20.0f); + Font::GZ_drawStr("pheenoh", offset + 265.0f * scale, 110.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 20.0f); + Font::GZ_drawStr("taka", offset + 390.0f * scale, 110.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 20.0f); + + Font::GZ_drawStr("special thanks", offset + 175.0f * scale, 170.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 25.0f); + Font::GZ_drawStr("tp decomp team", offset + 85.0f * scale, 190.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 17.0f); + Font::GZ_drawStr("tp speedrun community", offset + 345.0f * scale, 190.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 17.0f); + Font::GZ_drawStr("c_midnight", offset + 85.0f * scale, 210.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 17.0f); + Font::GZ_drawStr("cryze", offset + 245.0f * scale, 210.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 17.0f); + Font::GZ_drawStr("jdflyer", offset + 345.0f * scale, 210.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 17.0f); + Font::GZ_drawStr("icogn", offset + 85.0f * scale, 230.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 17.0f); + Font::GZ_drawStr("lunarsoap", offset + 245.0f * scale, 230.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 17.0f); + Font::GZ_drawStr("zephiles", offset + 345.0f * scale, 230.0f, 0xFFFFFFFF, GZ_checkDropShadows(), 17.0f); +} diff --git a/modules/menus/menu_credits/src/main.cpp b/modules/menus/menu_credits/src/main.cpp new file mode 100644 index 00000000..a14ec858 --- /dev/null +++ b/modules/menus/menu_credits/src/main.cpp @@ -0,0 +1,50 @@ +#include +#include "menus/menu_credits/include/credits_menu.h" +#include "events/draw_listener.h" +#include "menus/utils/menu_mgr.h" +#include "utils/draw.h" + +void onCreate(); +void onLoad(); +void onDraw(); +void onUnload(); +void onDelete(); + +CreditsMenu* l_menu; + +namespace tpgz::modules { +void main() { + g_menuMgr->setCreateHook(onCreate); + g_menuMgr->setLoadHook(onLoad); + g_menuMgr->setUnloadHook(onUnload); + g_menuMgr->setDeleteHook(onDelete); +} +void exit() { + g_menuMgr->setCreateHook(nullptr); + g_menuMgr->setLoadHook(nullptr); + g_menuMgr->setUnloadHook(nullptr); + g_menuMgr->setDeleteHook(nullptr); +} +} // namespace tpgz::modules + +void onCreate() { + if (!g_menuMgr->getPermanentData()) { + g_menuMgr->setPermanentData(new Cursor); + } +} + +void onLoad() { + l_menu = new CreditsMenu(*g_menuMgr->getPermanentData()); + g_drawListener->addListener(onDraw); +} + +void onDraw() { + l_menu->draw(); +} + +void onUnload() { + g_drawListener->removeListener(onDraw); + delete l_menu; +} + +void onDelete() {} diff --git a/modules/menus/menu_dungeon_flags/include/dungeon_flags_menu.h b/modules/menus/menu_dungeon_flags/include/dungeon_flags_menu.h index 780311ba..5873df4d 100644 --- a/modules/menus/menu_dungeon_flags/include/dungeon_flags_menu.h +++ b/modules/menus/menu_dungeon_flags/include/dungeon_flags_menu.h @@ -1,5 +1,5 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" struct DungeonFlagsData { bool init_once = false; @@ -23,22 +23,15 @@ enum DungeonFlagsIndex { CLEAR_DUNGEON_FLAGS_INDEX }; +extern DungeonFlagsData* dungeonFlagsData; + class DungeonFlagsMenu : public Menu { public: - DungeonFlagsMenu(Cursor&, DungeonFlagsData&); + DungeonFlagsMenu(Cursor&); virtual ~DungeonFlagsMenu(); virtual void draw(); private: - bool& init_once; - - bool& l_mapFlag; - bool& l_compassFlag; - bool& l_bosskeyFlag; - bool& l_minibossFlag; - bool& l_bossFlag; - int& l_selDun; - uint8_t& l_keyNum; Line lines[8]; }; diff --git a/modules/menus/menu_dungeon_flags/src/dungeon_flags_menu.cpp b/modules/menus/menu_dungeon_flags/src/dungeon_flags_menu.cpp index a18366f9..ec48a652 100644 --- a/modules/menus/menu_dungeon_flags/src/dungeon_flags_menu.cpp +++ b/modules/menus/menu_dungeon_flags/src/dungeon_flags_menu.cpp @@ -7,24 +7,23 @@ #define MAX_DUNGEON_OPTIONS 9 -KEEP_FUNC DungeonFlagsMenu::DungeonFlagsMenu(Cursor& cursor, DungeonFlagsData& data) - : Menu(cursor), init_once(data.init_once), l_mapFlag(data.l_mapFlag), - l_compassFlag(data.l_compassFlag), l_bosskeyFlag(data.l_bosskeyFlag), - l_minibossFlag(data.l_minibossFlag), l_bossFlag(data.l_bossFlag), l_selDun(data.l_selDun), - l_keyNum(data.l_keyNum), +KEEP_VAR DungeonFlagsData* dungeonFlagsData = nullptr; + +KEEP_FUNC DungeonFlagsMenu::DungeonFlagsMenu(Cursor& cursor) + : Menu(cursor), lines{ {"dungeon:", SELECT_DUNGEON_INDEX, "Selected dungeon flags", false, nullptr, MAX_DUNGEON_OPTIONS}, {"small keys", SMALL_KEY_FLAG_INDEX, "Selected dungeon small keys", false, nullptr, 5}, - {"have map", MAP_FLAG_INDEX, "Give selected dungeon map", true, &l_mapFlag}, + {"have map", MAP_FLAG_INDEX, "Give selected dungeon map", true, [](){return dungeonFlagsData->l_mapFlag;}}, {"have compass", COMPASS_FLAG_INDEX, "Give selected dungeon compass", true, - &l_compassFlag}, + [](){return dungeonFlagsData->l_compassFlag;}}, {"have boss key", BOSS_KEY_FLAG_INDEX, "Give selected dungeon boss key", true, - &l_bosskeyFlag}, + [](){return dungeonFlagsData->l_bosskeyFlag;}}, {"miniboss dead", DEFEAT_MINIBOSS_FLAG_INDEX, "Selected dungeon miniboss is defeated", - true, &l_minibossFlag}, + true, [](){return dungeonFlagsData->l_minibossFlag;}}, {"boss dead", DEFEAT_BOSS_FLAG_INDEX, "Selected dungeon boss is defeated", true, - &l_bossFlag}, + [](){return dungeonFlagsData->l_bossFlag;}}, {"clear flags", CLEAR_DUNGEON_FLAGS_INDEX, "Clear all selected dungeon flags"}, } {} @@ -51,16 +50,19 @@ void setSaveDungeonKeys(int32_t stage, uint8_t num) { } void DungeonFlagsMenu::draw() { + if (!dungeonFlagsData) { + return; + } cursor.setMode(Cursor::MODE_LIST); if (GZ_getButtonTrig(BACK_BUTTON)) { - init_once = false; + dungeonFlagsData->init_once = false; g_menuMgr->pop(); return; } uint8_t area_id = 0; - switch (l_selDun) { + switch (dungeonFlagsData->l_selDun) { case 0: area_id = dSv_memory_c::FOREST_TEMPLE; break; @@ -90,28 +92,28 @@ void DungeonFlagsMenu::draw() { break; } - if (!init_once) { - l_keyNum = getSaveDungeonKeys(area_id); - init_once = true; + if (!dungeonFlagsData->init_once) { + dungeonFlagsData->l_keyNum = getSaveDungeonKeys(area_id); + dungeonFlagsData->init_once = true; } switch (cursor.y) { case SELECT_DUNGEON_INDEX: - cursor.x = l_selDun; + cursor.x = dungeonFlagsData->l_selDun; cursor.move(MAX_DUNGEON_OPTIONS, MENU_LINE_NUM); if (cursor.y == SELECT_DUNGEON_INDEX) { - l_selDun = cursor.x; + dungeonFlagsData->l_selDun = cursor.x; } - l_keyNum = getSaveDungeonKeys(area_id); + dungeonFlagsData->l_keyNum = getSaveDungeonKeys(area_id); break; case SMALL_KEY_FLAG_INDEX: - cursor.x = l_keyNum; + cursor.x = dungeonFlagsData->l_keyNum; cursor.move(6, MENU_LINE_NUM); if (cursor.y == SMALL_KEY_FLAG_INDEX) { - l_keyNum = cursor.x; - setSaveDungeonKeys(area_id, l_keyNum); + dungeonFlagsData->l_keyNum = cursor.x; + setSaveDungeonKeys(area_id, dungeonFlagsData->l_keyNum); dComIfGs_getSave(g_dComIfG_gameInfo.info.mDan.mStageNo); } break; @@ -121,11 +123,11 @@ void DungeonFlagsMenu::draw() { } // update flags - l_mapFlag = getSaveDungeonItem(area_id, dSv_memBit_c::MAP); - l_compassFlag = getSaveDungeonItem(area_id, dSv_memBit_c::COMPASS); - l_bosskeyFlag = getSaveDungeonItem(area_id, dSv_memBit_c::BOSS_KEY); - l_minibossFlag = getSaveDungeonItem(area_id, dSv_memBit_c::STAGE_BOSS_ENEMY_2); - l_bossFlag = getSaveDungeonItem(area_id, dSv_memBit_c::STAGE_BOSS_ENEMY); + dungeonFlagsData->l_mapFlag = getSaveDungeonItem(area_id, dSv_memBit_c::MAP); + dungeonFlagsData->l_compassFlag = getSaveDungeonItem(area_id, dSv_memBit_c::COMPASS); + dungeonFlagsData->l_bosskeyFlag = getSaveDungeonItem(area_id, dSv_memBit_c::BOSS_KEY); + dungeonFlagsData->l_minibossFlag = getSaveDungeonItem(area_id, dSv_memBit_c::STAGE_BOSS_ENEMY_2); + dungeonFlagsData->l_bossFlag = getSaveDungeonItem(area_id, dSv_memBit_c::STAGE_BOSS_ENEMY); if (GZ_getButtonTrig(SELECTION_BUTTON)) { switch (cursor.y) { @@ -146,7 +148,7 @@ void DungeonFlagsMenu::draw() { break; case CLEAR_DUNGEON_FLAGS_INDEX: memset(&dComIfGs_getSavedata().mSave[area_id].mBit, 0, sizeof(dSv_memBit_c)); - l_keyNum = 0; + dungeonFlagsData->l_keyNum = 0; break; } // copy current stage save flags over temp flags @@ -159,8 +161,8 @@ void DungeonFlagsMenu::draw() { "City in the Sky", "Palace of Twilight", "Hyrule Castle", }; - lines[SMALL_KEY_FLAG_INDEX].printf(" <%d>", l_keyNum); - lines[SELECT_DUNGEON_INDEX].printf(" <%s>", dun_opt[l_selDun].member); + lines[SMALL_KEY_FLAG_INDEX].printf(" <%d>", dungeonFlagsData->l_keyNum); + lines[SELECT_DUNGEON_INDEX].printf(" <%s>", dun_opt[dungeonFlagsData->l_selDun].member); GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); } diff --git a/modules/menus/menu_dungeon_flags/src/main.cpp b/modules/menus/menu_dungeon_flags/src/main.cpp index 1ecfa883..b80b4d33 100644 --- a/modules/menus/menu_dungeon_flags/src/main.cpp +++ b/modules/menus/menu_dungeon_flags/src/main.cpp @@ -35,8 +35,8 @@ void onCreate() { } void onLoad() { - l_menu = new DungeonFlagsMenu(*g_menuMgr->getPermanentData(), - *g_menuMgr->getPersistentData()); + dungeonFlagsData = g_menuMgr->getPersistentData(); + l_menu = new DungeonFlagsMenu(*g_menuMgr->getPermanentData()); g_drawListener->addListener(onDraw); } diff --git a/modules/menus/menu_flag_log/include/flag_log_menu.h b/modules/menus/menu_flag_log/include/flag_log_menu.h index ed6e5359..3d24695e 100644 --- a/modules/menus/menu_flag_log/include/flag_log_menu.h +++ b/modules/menus/menu_flag_log/include/flag_log_menu.h @@ -1,5 +1,5 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" class FlagLogMenu : public Menu { public: diff --git a/modules/menus/menu_flag_log/src/flag_log_menu.cpp b/modules/menus/menu_flag_log/src/flag_log_menu.cpp index 4db7a03f..2d0ac3fe 100644 --- a/modules/menus/menu_flag_log/src/flag_log_menu.cpp +++ b/modules/menus/menu_flag_log/src/flag_log_menu.cpp @@ -6,7 +6,7 @@ KEEP_FUNC FlagLogMenu::FlagLogMenu(Cursor& cursor) : Menu(cursor), lines{{"log activated", 0, "toggle flag logger on/off", true, - &g_flagLogEnabled}} {} + [](){return g_flagLogEnabled;}}} {} FlagLogMenu::~FlagLogMenu() {} diff --git a/modules/menus/menu_flag_records/include/flag_records_menu.h b/modules/menus/menu_flag_records/include/flag_records_menu.h index cc603eac..40ddae17 100644 --- a/modules/menus/menu_flag_records/include/flag_records_menu.h +++ b/modules/menus/menu_flag_records/include/flag_records_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" struct FlagRecordsData { uint8_t l_bitIdx; diff --git a/modules/menus/menu_flag_records/src/flag_records_menu.cpp b/modules/menus/menu_flag_records/src/flag_records_menu.cpp index 82b7b649..7807391f 100644 --- a/modules/menus/menu_flag_records/src/flag_records_menu.cpp +++ b/modules/menus/menu_flag_records/src/flag_records_menu.cpp @@ -159,7 +159,7 @@ void FlagRecordsMenu::draw() { cursor.move(0, max_flags + 1); } - ListMember rec_opt[MAX_RECORD_OPTIONS] = {"stage", "event", "minigame", "danbit"}; + ListMember rec_opt[MAX_RECORD_OPTIONS] = {"stage", "event", "minigame", "dungeon"}; char record_type[12]; snprintf(record_type, sizeof(record_type), " <%s>", rec_opt[l_recIdx].member); uint32_t color = cursor.y == 0 ? CURSOR_RGBA : WHITE_RGBA; diff --git a/modules/menus/menu_flags/include/flags_menu.h b/modules/menus/menu_flags/include/flags_menu.h index 7d3b612c..f80942f1 100644 --- a/modules/menus/menu_flags/include/flags_menu.h +++ b/modules/menus/menu_flags/include/flags_menu.h @@ -1,5 +1,5 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" enum FlagsIndex { GENERAL_FLAGS_INDEX, diff --git a/modules/menus/menu_general_flags/include/general_flags_menu.h b/modules/menus/menu_general_flags/include/general_flags_menu.h index f63bb1b4..0e3f3438 100644 --- a/modules/menus/menu_general_flags/include/general_flags_menu.h +++ b/modules/menus/menu_general_flags/include/general_flags_menu.h @@ -1,5 +1,5 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" struct GeneralFlagsData { bool l_bossFlag; @@ -29,24 +29,14 @@ enum GeneralFlagsIndex { WOLF_SENSE_INDEX }; +extern GeneralFlagsData* generalFlagsData; + class GeneralFlagsMenu : public Menu { public: - GeneralFlagsMenu(Cursor&, GeneralFlagsData&); + GeneralFlagsMenu(Cursor&); virtual ~GeneralFlagsMenu(); virtual void draw(); private: - bool& l_bossFlag; - bool& l_rupeeFlag; - bool& l_midnaCharge; - bool& l_transformWarp; - bool& l_midnaZ; - bool& l_eponaStolen; - bool& l_eponaTamed; - bool& l_mapWarping; - bool& l_midnaHealed; - bool& l_midnaRide; - bool& l_wolfSense; - Line lines[11]; }; diff --git a/modules/menus/menu_general_flags/src/general_flags_menu.cpp b/modules/menus/menu_general_flags/src/general_flags_menu.cpp index 32e00396..a54732da 100644 --- a/modules/menus/menu_general_flags/src/general_flags_menu.cpp +++ b/modules/menus/menu_general_flags/src/general_flags_menu.cpp @@ -5,52 +5,54 @@ #include "rels/include/defines.h" #include "menus/utils/menu_mgr.h" -KEEP_FUNC GeneralFlagsMenu::GeneralFlagsMenu(Cursor& cursor, GeneralFlagsData& data) - : Menu(cursor), l_bossFlag(data.l_bossFlag), l_rupeeFlag(data.l_rupeeFlag), - l_midnaCharge(data.l_midnaCharge), l_transformWarp(data.l_transformWarp), - l_midnaZ(data.l_midnaZ), l_eponaStolen(data.l_eponaStolen), l_eponaTamed(data.l_eponaTamed), - l_mapWarping(data.l_mapWarping), l_midnaHealed(data.l_midnaHealed), - l_midnaRide(data.l_midnaRide), l_wolfSense(data.l_wolfSense), +KEEP_VAR GeneralFlagsData* generalFlagsData; + +KEEP_FUNC GeneralFlagsMenu::GeneralFlagsMenu(Cursor& cursor) + : Menu(cursor), lines{ - {"boss flag", BOSS_FLAG_INDEX, "Sets the boss flag value", true, &l_bossFlag}, + {"boss flag", BOSS_FLAG_INDEX, "Sets the boss flag value", true, [](){return generalFlagsData->l_bossFlag;}}, {"rupee cutscenes", RUPEE_CS_FLAG_INDEX, "Toggle rupee cutscenes being enabled", true, - &l_rupeeFlag}, + [](){return generalFlagsData->l_rupeeFlag;}}, {"epona stolen", EPONA_STOLEN_INDEX, "Toggle flag for Epona being stolen", true, - &l_eponaStolen}, + [](){return generalFlagsData->l_eponaStolen;}}, {"epona tamed", EPONA_TAMED_INDEX, "Toggle flag for Epona being tamed", true, - &l_eponaTamed}, - {"map warping", MAP_WARPING_INDEX, "Toggle flag for map warping", true, &l_mapWarping}, + [](){return generalFlagsData->l_eponaTamed;}}, + {"map warping", MAP_WARPING_INDEX, "Toggle flag for map warping", true, [](){return generalFlagsData->l_mapWarping;}}, {"midna charge", MIDNA_CHARGE_INDEX, "Toggle flag for Midna charge", true, - &l_midnaCharge}, + [](){return generalFlagsData->l_midnaCharge;}}, {"midna healed", MIDNA_HEALTHY, "Toggle flag for Midna being healed", true, - &l_midnaHealed}, + [](){return generalFlagsData->l_midnaHealed;}}, {"midna on back", MIDNA_ON_BACK, "Toggle flag for Midna appearing on Wolf Link's back", - true, &l_midnaRide}, + true, [](){return generalFlagsData->l_midnaRide;}}, {"midna available", MIDNA_Z_INDEX, "Toggle flag for being able to call Midna", true, - &l_midnaZ}, + [](){return generalFlagsData->l_midnaZ;}}, {"transform/warp", TRANSFORM_WARP_INDEX, "Toggle flag for transforming/warping", true, - &l_transformWarp}, - {"wolf sense", WOLF_SENSE_INDEX, "Toggle flag for wolf sense", true, &l_wolfSense}, + [](){return generalFlagsData->l_transformWarp;}}, + {"wolf sense", WOLF_SENSE_INDEX, "Toggle flag for wolf sense", true, [](){return generalFlagsData->l_wolfSense;}}, } {} GeneralFlagsMenu::~GeneralFlagsMenu() {} void GeneralFlagsMenu::draw() { + if (!generalFlagsData) { + return; + } + // update flags - l_bossFlag = bossFlags > 0; - l_midnaCharge = dComIfGs_isEventBit(0x0501); - l_transformWarp = dComIfGs_isEventBit(0x0D04); - l_midnaZ = dComIfGs_isEventBit(0x0C10); - l_eponaStolen = dComIfGs_isEventBit(0x0580); - l_eponaTamed = dComIfGs_isEventBit(0x0601); - l_mapWarping = dComIfGs_isEventBit(0x0604); - l_midnaHealed = dComIfGs_isEventBit(0x1E08); - l_midnaRide = dComIfGs_isTransformLV(3); - l_wolfSense = dComIfGs_isEventBit(0x4308); + generalFlagsData->l_bossFlag = bossFlags > 0; + generalFlagsData->l_midnaCharge = dComIfGs_isEventBit(0x0501); + generalFlagsData->l_transformWarp = dComIfGs_isEventBit(0x0D04); + generalFlagsData->l_midnaZ = dComIfGs_isEventBit(0x0C10); + generalFlagsData->l_eponaStolen = dComIfGs_isEventBit(0x0580); + generalFlagsData->l_eponaTamed = dComIfGs_isEventBit(0x0601); + generalFlagsData->l_mapWarping = dComIfGs_isEventBit(0x0604); + generalFlagsData->l_midnaHealed = dComIfGs_isEventBit(0x1E08); + generalFlagsData->l_midnaRide = dComIfGs_isTransformLV(3); + generalFlagsData->l_wolfSense = dComIfGs_isEventBit(0x4308); for (int i = BLUE_RUPEE; i <= SILVER_RUPEE; i++) { if (dComIfGs_isItemFirstBit(i)) { - l_rupeeFlag = true; + generalFlagsData->l_rupeeFlag = true; break; } } @@ -63,17 +65,18 @@ void GeneralFlagsMenu::draw() { if (GZ_getButtonTrig(SELECTION_BUTTON)) { switch (cursor.y) { case BOSS_FLAG_INDEX: - if (l_bossFlag) { + if (generalFlagsData->l_bossFlag) { bossFlags = 0; } else { bossFlags = 255; } break; case RUPEE_CS_FLAG_INDEX: - if (l_rupeeFlag) { + if (generalFlagsData->l_rupeeFlag) { for (int i = BLUE_RUPEE; i <= SILVER_RUPEE; i++) { dComIfGs_offItemFirstBit(i); } + generalFlagsData->l_rupeeFlag = false; } else { for (int i = BLUE_RUPEE; i <= SILVER_RUPEE; i++) { dComIfGs_onItemFirstBit(i); diff --git a/modules/menus/menu_general_flags/src/main.cpp b/modules/menus/menu_general_flags/src/main.cpp index eceee874..eb51aa3c 100644 --- a/modules/menus/menu_general_flags/src/main.cpp +++ b/modules/menus/menu_general_flags/src/main.cpp @@ -35,8 +35,8 @@ void onCreate() { } void onLoad() { - l_menu = new GeneralFlagsMenu(*g_menuMgr->getPermanentData(), - *g_menuMgr->getPersistentData()); + generalFlagsData = g_menuMgr->getPersistentData(); + l_menu = new GeneralFlagsMenu(*g_menuMgr->getPermanentData()); g_drawListener->addListener(onDraw); } diff --git a/modules/menus/menu_glitchless_saves/include/menu_glitchless_saves.h b/modules/menus/menu_glitchless_saves/include/menu_glitchless_saves.h index 4ceb24b6..6a65342d 100644 --- a/modules/menus/menu_glitchless_saves/include/menu_glitchless_saves.h +++ b/modules/menus/menu_glitchless_saves/include/menu_glitchless_saves.h @@ -1,6 +1,6 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" #define GL_SPECIALS_AMNT 3 diff --git a/modules/menus/menu_hundo_saves/include/hundo_saves_menu.h b/modules/menus/menu_hundo_saves/include/hundo_saves_menu.h index 2aa344f5..f60a3e3b 100644 --- a/modules/menus/menu_hundo_saves/include/hundo_saves_menu.h +++ b/modules/menus/menu_hundo_saves/include/hundo_saves_menu.h @@ -1,8 +1,8 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" -#define HND_SPECIALS_AMNT 27 +#define HND_SPECIALS_AMNT 25 enum HundoPracticeIndex { HND_GOATS_1_INDEX, diff --git a/modules/menus/menu_hundo_saves/src/hundo_saves_menu.cpp b/modules/menus/menu_hundo_saves/src/hundo_saves_menu.cpp index 948a945a..5b7acee8 100644 --- a/modules/menus/menu_hundo_saves/src/hundo_saves_menu.cpp +++ b/modules/menus/menu_hundo_saves/src/hundo_saves_menu.cpp @@ -96,7 +96,6 @@ HundoSavesMenu::~HundoSavesMenu() {} void HundoSavesMenu::draw() { special HundoSpecials[HND_SPECIALS_AMNT] = { special(HND_GOATS_1_INDEX, SaveMngSpecial_Goats1, nullptr), - special(HND_GOATS_2_INDEX, SaveMngSpecial_Goats2, nullptr), special(HND_MIST_INDEX, SaveMngSpecial_PurpleMist, nullptr), special(HND_KARG_INDEX, SaveMngSpecial_KargOoB, nullptr), special(HND_KB_2_INDEX, SaveMngSpecial_KB2Skip, nullptr), @@ -111,7 +110,6 @@ void HundoSavesMenu::draw() { special(HND_SPR_BK_ROOM_INDEX, SaveMngSpecial_SPRBossKey, nullptr), special(HND_EARLY_POE_INDEX, nullptr, SaveMngSpecial_ToTEarlyPoe), special(HND_EARLY_HP_INDEX, nullptr, SaveMngSpecial_ToTEarlyHP), - special(HND_AERALFOS_INDEX, nullptr, SaveMngSpecial_AeralfosSkip), special(HND_POE_CYCLE_INDEX, nullptr, SaveMngSpecial_CityPoeCycle), special(HND_FAN_TOWER_INDEX, SaveMngSpecial_FanTower, nullptr), special(HND_ARGOROK_INDEX, nullptr, SaveMngSpecial_Argorok), diff --git a/modules/menus/menu_inventory/include/inventory_menu.h b/modules/menus/menu_inventory/include/inventory_menu.h index c231f9fb..0b949975 100644 --- a/modules/menus/menu_inventory/include/inventory_menu.h +++ b/modules/menus/menu_inventory/include/inventory_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" #define ITEM_WHEEL_INDEX 0 #define PAUSE_MENU_INDEX 1 diff --git a/modules/menus/menu_item_wheel/include/item_wheel_menu.h b/modules/menus/menu_item_wheel/include/item_wheel_menu.h index 226bf688..70d666d3 100644 --- a/modules/menus/menu_item_wheel/include/item_wheel_menu.h +++ b/modules/menus/menu_item_wheel/include/item_wheel_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" #include "libtp_c/include/d/save/d_save.h" #define ITEM_WHEEL_SLOTS 24 diff --git a/modules/menus/menu_item_wheel/src/item_wheel_menu.cpp b/modules/menus/menu_item_wheel/src/item_wheel_menu.cpp index 45077f98..febb8c10 100644 --- a/modules/menus/menu_item_wheel/src/item_wheel_menu.cpp +++ b/modules/menus/menu_item_wheel/src/item_wheel_menu.cpp @@ -13,11 +13,15 @@ #ifdef GCN_PLATFORM #define DEFAULT_BTN_TXT "Z" #define DEFAULT_BTN GZPad::Z +#define RESET_BTN_TXT "X" +#define RESET_BUTTON GZPad::X #endif #ifdef WII_PLATFORM #define DEFAULT_BTN_TXT "+" #define DEFAULT_BTN GZPad::PLUS +#define RESET_BTN_TXT "-" +#define RESET_BUTTON GZPad::MINUS #endif KEEP_FUNC ItemWheelMenu::ItemWheelMenu(Cursor& cursor, ItemWheelData& data) @@ -51,36 +55,35 @@ KEEP_FUNC ItemWheelMenu::ItemWheelMenu(Cursor& cursor, ItemWheelData& data) ItemWheelMenu::~ItemWheelMenu() {} const uint8_t l_validItems[] = { - DUNGEON_EXIT, DUNGEON_BACK, - TKS_LETTER, HAWK_EYE, - BOOMERANG, SPINNER, - IRONBALL, BOW, - HOOKSHOT, HVY_BOOTS, - COPY_ROD, W_HOOKSHOT, - KANTERA, MASTER_SWORD, - FISHING_ROD_1, PACHINKO, - BOMB_BAG_LV1, BEE_ROD, - JEWEL_ROD, WORM_ROD, - JEWEL_BEE_ROD, JEWEL_WORM_ROD, - EMPTY_BOTTLE, RED_BOTTLE, - GREEN_BOTTLE, BLUE_BOTTLE, - MILK_BOTTLE, HALF_MILK_BOTTLE, - OIL_BOTTLE, WATER_BOTTLE, - UGLY_SOUP, HOT_SPRING, - FAIRY, NORMAL_BOMB, - WATER_BOMB, POKE_BOMB, - FAIRY_DROP, WORM, - BEE_CHILD, CHUCHU_RARE, - CHUCHU_RED, CHUCHU_BLUE, - CHUCHU_GREEN, CHUCHU_YELLOW, - CHUCHU_PURPLE, LV1_SOUP, - LV2_SOUP, LV3_SOUP, - LETTER, BILL, - WOOD_STATUE, IRIAS_PENDANT, - HORSE_FLUTE, RAFRELS_MEMO, - ASHS_SCRIBBLING, ANCIENT_DOCUMENT, - AIR_LETTER, ANCIENT_DOCUMENT2, - NO_ITEM, + NO_ITEM, ANCIENT_DOCUMENT, + ANCIENT_DOCUMENT2, AIR_LETTER, + ASHS_SCRIBBLING, RAFRELS_MEMO, + IRONBALL, BEE_CHILD, + CHUCHU_BLUE, BLUE_BOTTLE, + POKE_BOMB, HOOKSHOT, + COPY_ROD, W_HOOKSHOT, + BOMB_BAG_LV1, EMPTY_BOTTLE, + FAIRY, FAIRY_DROP, + FISHING_ROD_1, BEE_ROD, + JEWEL_ROD, JEWEL_BEE_ROD, + JEWEL_WORM_ROD, WORM_ROD, + BOOMERANG, LV2_SOUP, + CHUCHU_GREEN, HALF_MILK_BOTTLE, + HAWK_EYE, BOW, + HORSE_FLUTE, HOT_SPRING, + IRIAS_PENDANT, BILL, + HVY_BOOTS, KANTERA, + OIL_BOTTLE, GREEN_BOTTLE, + MILK_BOTTLE, UGLY_SOUP, + DUNGEON_BACK, DUNGEON_EXIT, + TKS_LETTER, CHUCHU_PURPLE, + CHUCHU_RARE, CHUCHU_RED, + RED_BOTTLE, NORMAL_BOMB, + LETTER, LV1_SOUP, + PACHINKO, SPINNER, + LV3_SOUP, WATER_BOTTLE, + WATER_BOMB, WOOD_STATUE, + WORM, CHUCHU_YELLOW }; const uint8_t l_defaultItems[ITEM_WHEEL_SLOTS] = { @@ -92,64 +95,64 @@ const uint8_t l_defaultItems[ITEM_WHEEL_SLOTS] = { }; const ItemLookup l_lookupTbl[MAX_ITEMS] = { - {DUNGEON_EXIT, "Ooccoo Sr."}, - {DUNGEON_BACK, "Ooccoo Jr."}, - {TKS_LETTER, "Ooccoo's note"}, - {HAWK_EYE, "hawkeye"}, - {BOOMERANG, "gale boomerang"}, - {SPINNER, "spinner"}, + {NO_ITEM, "n/a"}, + {ANCIENT_DOCUMENT, "ancient sky book (empty)"}, + {ANCIENT_DOCUMENT2, "ancient sky book (filled)"}, + {AIR_LETTER, "ancient sky book (partial)"}, + {ASHS_SCRIBBLING, "ashei's sketch"}, + {RAFRELS_MEMO, "auru's memo"}, {IRONBALL, "ball and chain"}, - {BOW, "hero's bow"}, + {BEE_CHILD, "bee larva"}, + {CHUCHU_BLUE, "blue chu"}, + {BLUE_BOTTLE, "blue potion"}, + {POKE_BOMB, "bomblings"}, {HOOKSHOT, "clawshot"}, - {HVY_BOOTS, "iron boots"}, {COPY_ROD, "dominion rod"}, {W_HOOKSHOT, "double clawshot"}, - {KANTERA, "lantern"}, - {PACHINKO, "slingshot"}, - {FISHING_ROD_1, "fishing rod"}, {BOMB_BAG_LV1, "empty bomb bag"}, + {EMPTY_BOTTLE, "empty bottle"}, + {FAIRY, "fairy"}, + {FAIRY_DROP, "fairy tears"}, + {FISHING_ROD_1, "fishing rod"}, {BEE_ROD, "fishing rod (bee larva)"}, {JEWEL_ROD, "fishing rod (coral earring)"}, - {WORM_ROD, "fishing rod (worm)"}, {JEWEL_BEE_ROD, "fishing rod (coral earring/bee larva)"}, {JEWEL_WORM_ROD, "fishing rod (coral earring/worm)"}, - {EMPTY_BOTTLE, "empty bottle"}, - {RED_BOTTLE, "red potion"}, - {GREEN_BOTTLE, "magic potion"}, - {BLUE_BOTTLE, "blue potion"}, - {MILK_BOTTLE, "milk"}, + {WORM_ROD, "fishing rod (worm)"}, + {BOOMERANG, "gale boomerang"}, + {LV2_SOUP, "good soup"}, + {CHUCHU_GREEN, "green chu"}, {HALF_MILK_BOTTLE, "half milk"}, + {HAWK_EYE, "hawkeye"}, + {BOW, "hero's bow"}, + {HORSE_FLUTE, "horse call"}, + {HOT_SPRING, "hot spring water"}, + {IRIAS_PENDANT, "Ilia's charm"}, + {BILL, "invoice"}, + {HVY_BOOTS, "iron boots"}, + {KANTERA, "lantern"}, {OIL_BOTTLE, "lantern oil"}, - {WATER_BOTTLE, "water"}, + {GREEN_BOTTLE, "magic potion"}, + {MILK_BOTTLE, "milk"}, {UGLY_SOUP, "nasty soup"}, - {HOT_SPRING, "hot spring water"}, - {FAIRY, "fairy"}, - {NORMAL_BOMB, "regular bombs"}, - {WATER_BOMB, "water bombs"}, - {POKE_BOMB, "bomblings"}, - {FAIRY_DROP, "fairy tears"}, - {WORM, "worm"}, - {BEE_CHILD, "bee larva"}, + {DUNGEON_BACK, "ooccoo Jr."}, + {DUNGEON_EXIT, "ooccoo Sr."}, + {TKS_LETTER, "ooccoo's note"}, + {CHUCHU_PURPLE, "purple chu"}, {CHUCHU_RARE, "rare chu"}, {CHUCHU_RED, "red chu"}, - {CHUCHU_BLUE, "blue chu"}, - {CHUCHU_GREEN, "green chu"}, - {CHUCHU_YELLOW, "yellow chu"}, - {CHUCHU_PURPLE, "purple chu"}, + {RED_BOTTLE, "red potion"}, + {NORMAL_BOMB, "regular bombs"}, + {LETTER, "renado's letter"}, {LV1_SOUP, "simple soup"}, - {LV2_SOUP, "good soup"}, + {PACHINKO, "slingshot"}, + {SPINNER, "spinner"}, {LV3_SOUP, "superb soup"}, - {LETTER, "Renado's letter"}, - {BILL, "invoice"}, + {WATER_BOTTLE, "water"}, + {WATER_BOMB, "water bombs"}, {WOOD_STATUE, "wooden statue"}, - {IRIAS_PENDANT, "Ilia's charm"}, - {HORSE_FLUTE, "horse call"}, - {RAFRELS_MEMO, "Auru's memo"}, - {ASHS_SCRIBBLING, "Ashei's sketch"}, - {ANCIENT_DOCUMENT, "ancient sky book (empty)"}, - {AIR_LETTER, "ancient sky book (partial)"}, - {ANCIENT_DOCUMENT2, "ancient sky book (filled)"}, - {NO_ITEM, "no item"}, + {WORM, "worm"}, + {CHUCHU_YELLOW, "yellow chu"} }; void ItemWheelMenu::updateListIdx() { @@ -192,12 +195,12 @@ void ItemWheelMenu::draw() { for (int j = 0; j < MAX_ITEMS; j++) { if (l_lookupTbl[j].item_id == item_id) { - lines[slot_no].printf(" <%s>", item_id != NO_ITEM ? l_lookupTbl[j].name : "none"); + lines[slot_no].printf(" <%s>", item_id != NO_ITEM ? l_lookupTbl[j].name : "n/a"); } if (l_lookupTbl[j].item_id == l_defaultItems[slot_no]) { snprintf(lines[slot_no].description, sizeof(lines[slot_no].description), - "Slot %d default: %s. Press " DEFAULT_BTN_TXT " to set to default", + "Slot %d default: %s. Press " DEFAULT_BTN_TXT " to set to default; " RESET_BTN_TXT " to reset.", slot_no, l_lookupTbl[j].name); } else { continue; @@ -231,6 +234,10 @@ void ItemWheelMenu::draw() { dComIfGs_setItem(cursor.y, l_defaultItems[cursor.y]); } + if (GZ_getButtonTrig(RESET_BUTTON)) { + dComIfGs_setItem(cursor.y, NO_ITEM); + } + cursor.move(0, MENU_LINE_NUM); GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); } diff --git a/modules/menus/menu_main/include/main_menu.h b/modules/menus/menu_main/include/main_menu.h index 07ea51a7..32c21639 100644 --- a/modules/menus/menu_main/include/main_menu.h +++ b/modules/menus/menu_main/include/main_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" enum MainMenuIndex { CHEAT_INDEX, diff --git a/modules/menus/menu_memfiles/include/memfiles_menu.h b/modules/menus/menu_memfiles/include/memfiles_menu.h index f6326557..c5f269d1 100644 --- a/modules/menus/menu_memfiles/include/memfiles_menu.h +++ b/modules/menus/menu_memfiles/include/memfiles_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" #include "libtp_c/include/dolphin/mtx/vec.h" #include "libtp_c/include/d/com/d_com_inf_game.h" diff --git a/modules/menus/menu_memfiles/src/memfiles_menu.cpp b/modules/menus/menu_memfiles/src/memfiles_menu.cpp index 73052ace..11711e94 100644 --- a/modules/menus/menu_memfiles/src/memfiles_menu.cpp +++ b/modules/menus/menu_memfiles/src/memfiles_menu.cpp @@ -45,13 +45,15 @@ void MemfilesMenu::draw() { static Storage card; char fileBuf[10]; + + snprintf(fileBuf, sizeof(fileBuf), "tpgz_s%d", l_fileNo); + card.file_name = fileBuf; + card.sector_size = SECTOR_SIZE; + snprintf(card.file_name_buffer, sizeof(card.file_name_buffer), card.file_name); + if (GZ_getButtonTrig(SELECTION_BUTTON)) { switch (cursor.y) { case MEMFILE_SAVE_INDEX: - snprintf(fileBuf, sizeof(fileBuf), "tpgz_s%d", l_fileNo); - card.file_name = fileBuf; - card.sector_size = SECTOR_SIZE; - snprintf(card.file_name_buffer, sizeof(card.file_name_buffer), card.file_name); #ifndef WII_PLATFORM card.result = CARDProbeEx(0, nullptr, &card.sector_size); if (card.result == Ready) { @@ -62,10 +64,6 @@ void MemfilesMenu::draw() { #endif // WII_PLATFORM break; case MEMFILE_LOAD_INDEX: - snprintf(fileBuf, sizeof(fileBuf), "tpgz_s%d", l_fileNo); - card.file_name = fileBuf; - card.sector_size = SECTOR_SIZE; - snprintf(card.file_name_buffer, sizeof(card.file_name_buffer), card.file_name); #ifndef WII_PLATFORM card.result = CARDProbeEx(0, NULL, &card.sector_size); if (card.result == Ready) { @@ -76,10 +74,6 @@ void MemfilesMenu::draw() { #endif // WII_PLATFORM break; case MEMFILE_DELETE_INDEX: - snprintf(fileBuf, sizeof(fileBuf), "tpgz_s%d", l_fileNo); - card.file_name = fileBuf; - card.sector_size = SECTOR_SIZE; - snprintf(card.file_name_buffer, sizeof(card.file_name_buffer), card.file_name); #ifndef WII_PLATFORM card.result = CARDProbeEx(0, nullptr, &card.sector_size); if (card.result == Ready) { @@ -92,8 +86,11 @@ void MemfilesMenu::draw() { } } + bool exists = GZ_memfileExists(card); + lines[MEMFILE_LOAD_INDEX].disabled = !exists; + lines[MEMFILE_DELETE_INDEX].disabled = !exists; lines[MEMFILE_SLOT_INDEX].printf(" <%d>", l_fileNo); - cursor.move(0, MENU_LINE_NUM); + cursor.move(0, MENU_LINE_NUM - (exists ? 0 : 2)); GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); } diff --git a/modules/menus/menu_memory/include/memory_menu.h b/modules/menus/menu_memory/include/memory_menu.h index 506877e7..332339be 100644 --- a/modules/menus/menu_memory/include/memory_menu.h +++ b/modules/menus/menu_memory/include/memory_menu.h @@ -1,5 +1,5 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" class MemoryMenu : public Menu { public: diff --git a/modules/menus/menu_memory_editor/include/memory_editor_menu.h b/modules/menus/menu_memory_editor/include/memory_editor_menu.h index 139ba4bd..55b6e333 100644 --- a/modules/menus/menu_memory_editor/include/memory_editor_menu.h +++ b/modules/menus/menu_memory_editor/include/memory_editor_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" class MemoryEditorMenu : public Menu { public: @@ -7,5 +7,7 @@ class MemoryEditorMenu : public Menu { virtual void draw(); private: + uint8_t line_length = 8; + void drawMemEditor(); }; diff --git a/modules/menus/menu_memory_editor/src/memory_editor_menu.cpp b/modules/menus/menu_memory_editor/src/memory_editor_menu.cpp index c71cfd7c..2316df50 100644 --- a/modules/menus/menu_memory_editor/src/memory_editor_menu.cpp +++ b/modules/menus/menu_memory_editor/src/memory_editor_menu.cpp @@ -7,11 +7,20 @@ #include "menus/utils/menu_mgr.h" #define MAX_DISPLAY_LINES 15 +#define MAX_ADDRESS (0x81800000 - MAX_DISPLAY_LINES * line_length) #define WHITE_RGBA 0xFFFFFFFF #define ADDRESS_RGBA 0xBABABAFF #define LINE_X_OFFSET 20.0f #define LINE_BYTE_OFFSET 100.0f +#ifdef GCN_PLATFORM +#define LINE_SIZE_BTN (GZPad::Y) +#define LINE_SIZE_TEXT "Y" +#else +#define LINE_SIZE_BTN (GZPad::MINUS) +#define LINE_SIZE_TEXT "-" +#endif + MemoryEditorMenu::MemoryEditorMenu(Cursor& cursor) : Menu(cursor) {} MemoryEditorMenu::~MemoryEditorMenu() {} @@ -29,27 +38,27 @@ void MemoryEditorMenu::drawMemEditor() { if (l_idxSelected) { if (GZ_getButtonRepeat(GZPad::DPAD_RIGHT)) { - if (l_idxPlace == 7) { + if (l_idxPlace == line_length - 1) { l_idxPlace = 0; - } else if (l_idxPlace >= 0 && l_idxPlace < 8) { + } else if (l_idxPlace >= 0 && l_idxPlace < line_length) { l_idxPlace++; } } if (GZ_getButtonRepeat(GZPad::DPAD_LEFT)) { if (l_idxPlace == 0) { - l_idxPlace = 7; - } else if (l_idxPlace >= 0 && l_idxPlace < 8) { + l_idxPlace = line_length - 1; + } else if (l_idxPlace >= 0 && l_idxPlace < line_length) { l_idxPlace--; } } if (GZ_getButtonRepeat(GZPad::DPAD_UP)) { if (l_idxPlace == 0) { - g_memoryEditor_addressIndex = 0x817FFF88; + g_memoryEditor_addressIndex = MAX_ADDRESS; } else { g_memoryEditor_addressIndex += (0x10000000 >> (l_idxPlace * 4)); } - if (g_memoryEditor_addressIndex > 0x817FFF88) { - g_memoryEditor_addressIndex = 0x817FFF88; + if (g_memoryEditor_addressIndex > MAX_ADDRESS) { + g_memoryEditor_addressIndex = MAX_ADDRESS; } } if (GZ_getButtonRepeat(GZPad::DPAD_DOWN)) { @@ -67,58 +76,59 @@ void MemoryEditorMenu::drawMemEditor() { if (cursor.y > 0 && !cursor.lock_x) { if (GZ_getButtonRepeat(GZPad::DPAD_LEFT)) { if (l_byteIdx == 0) { - l_byteIdx = 7; - } else if (l_byteIdx >= 0 && l_byteIdx < 8) { + l_byteIdx = line_length - 1; + } else if (l_byteIdx >= 0 && l_byteIdx < line_length) { l_byteIdx--; } } if (GZ_getButtonRepeat(GZPad::DPAD_RIGHT)) { - if (l_byteIdx == 7) { + if (l_byteIdx == line_length - 1) { l_byteIdx = 0; - } else if (l_byteIdx >= 0 && l_byteIdx < 8) { + } else if (l_byteIdx >= 0 && l_byteIdx < line_length) { l_byteIdx++; } } } + float address_offset = Font::getStrWidth("80000000") + LINE_X_OFFSET + Font::getCharWidth(' '); + float b_offset = Font::getStrWidth("00") + (line_length == 8 ? Font::getCharWidth(' ') : 0.0f); + float chars_offset = address_offset + b_offset * line_length + Font::getStrWidth(" "); + float c_offset = Font::getMaxCharRangeWidth('A', 'Z'); + + for (uint8_t k = 0; k < line_length; ++k) { + float middle_offset = k < line_length / 2 ? 0.0f : Font::getCharWidth(' '); + char b[3]; + snprintf(b, sizeof(b), "%2X", k); + GZ_drawText(b, address_offset + b_offset * k + middle_offset, 80.0f, + (l_byteIdx == k ? CURSOR_RGBA : WHITE_RGBA), GZ_checkDropShadows()); + } + for (uint8_t i = 0; i < MAX_DISPLAY_LINES; i++) { float y_offset; y_offset = ((100.0f) + (i * 20.0f)); char address[10]; - char b0[3]; - char b1[3]; - char b2[3]; - char b3[3]; - char b4[3]; - char b5[3]; - char b6[3]; - char b7[3]; - - snprintf(address, sizeof(address), "%08X ", g_memoryEditor_addressIndex + (i * 8)); - snprintf(b0, sizeof(b0), "%02X", *(uint8_t*)(g_memoryEditor_addressIndex + (i * 8))); - snprintf(b1, sizeof(b1), "%02X", *(uint8_t*)((g_memoryEditor_addressIndex + (i * 8)) + 1)); - snprintf(b2, sizeof(b2), "%02X", *(uint8_t*)((g_memoryEditor_addressIndex + (i * 8)) + 2)); - snprintf(b3, sizeof(b3), "%02X", *(uint8_t*)((g_memoryEditor_addressIndex + (i * 8)) + 3)); - snprintf(b4, sizeof(b4), "%02X", *(uint8_t*)((g_memoryEditor_addressIndex + (i * 8)) + 4)); - snprintf(b5, sizeof(b5), "%02X", *(uint8_t*)((g_memoryEditor_addressIndex + (i * 8)) + 5)); - snprintf(b6, sizeof(b6), "%02X", *(uint8_t*)((g_memoryEditor_addressIndex + (i * 8)) + 6)); - snprintf(b7, sizeof(b7), "%02X", *(uint8_t*)((g_memoryEditor_addressIndex + (i * 8)) + 7)); - - float address_offset = Font::getStrWidth(address) + LINE_X_OFFSET; - float b_offset = Font::getStrWidth(" 00"); + char b[line_length][3]; + char c[line_length][3]; + + snprintf(address, sizeof(address), "%08X ", g_memoryEditor_addressIndex + (i * line_length)); + for (uint8_t k = 0; k < line_length; ++k) { + snprintf(b[k], sizeof(b[k]), "%02X", *(uint8_t*)(g_memoryEditor_addressIndex + (i * line_length) + k)); + snprintf(c[k], sizeof(c[k]), "%c", *(uint8_t*)(g_memoryEditor_addressIndex + (i * line_length) + k)); + } + if (cursor.y == (i + 1) && cursor.lock_x && cursor.lock_y) { if (GZ_getButtonRepeat(GZPad::DPAD_UP)) { - *(uint8_t*)((g_memoryEditor_addressIndex + (i * 8)) + l_byteIdx) += 0x1; + *(uint8_t*)((g_memoryEditor_addressIndex + (i * line_length)) + l_byteIdx) += 0x1; } if (GZ_getButtonRepeat(GZPad::DPAD_DOWN)) { - *(uint8_t*)((g_memoryEditor_addressIndex + (i * 8)) + l_byteIdx) -= 0x1; + *(uint8_t*)((g_memoryEditor_addressIndex + (i * line_length)) + l_byteIdx) -= 0x1; } if (GZ_getButtonRepeat(GZPad::DPAD_RIGHT)) { - *(uint8_t*)((g_memoryEditor_addressIndex + (i * 8)) + l_byteIdx) += 0x10; + *(uint8_t*)((g_memoryEditor_addressIndex + (i * line_length)) + l_byteIdx) += 0x10; } if (GZ_getButtonRepeat(GZPad::DPAD_LEFT)) { - *(uint8_t*)((g_memoryEditor_addressIndex + (i * 8)) + l_byteIdx) -= 0x10; + *(uint8_t*)((g_memoryEditor_addressIndex + (i * line_length)) + l_byteIdx) -= 0x10; } } @@ -145,30 +155,16 @@ void MemoryEditorMenu::drawMemEditor() { GZ_drawText(address, LINE_X_OFFSET, y_offset, (cursor.y == (i + 1) ? CURSOR_RGBA : ADDRESS_RGBA), GZ_checkDropShadows()); - GZ_drawText(b0, address_offset, y_offset, - (l_byteIdx == 0 && cursor.y == (i + 1) ? mem_cursor_color : WHITE_RGBA), - GZ_checkDropShadows()); - GZ_drawText(b1, address_offset + b_offset * 1, y_offset, - (l_byteIdx == 1 && cursor.y == (i + 1) ? mem_cursor_color : WHITE_RGBA), - GZ_checkDropShadows()); - GZ_drawText(b2, address_offset + b_offset * 2, y_offset, - (l_byteIdx == 2 && cursor.y == (i + 1) ? mem_cursor_color : WHITE_RGBA), - GZ_checkDropShadows()); - GZ_drawText(b3, address_offset + b_offset * 3, y_offset, - (l_byteIdx == 3 && cursor.y == (i + 1) ? mem_cursor_color : WHITE_RGBA), - GZ_checkDropShadows()); - GZ_drawText(b4, address_offset + b_offset * 4, y_offset, - (l_byteIdx == 4 && cursor.y == (i + 1) ? mem_cursor_color : WHITE_RGBA), - GZ_checkDropShadows()); - GZ_drawText(b5, address_offset + b_offset * 5, y_offset, - (l_byteIdx == 5 && cursor.y == (i + 1) ? mem_cursor_color : WHITE_RGBA), - GZ_checkDropShadows()); - GZ_drawText(b6, address_offset + b_offset * 6, y_offset, - (l_byteIdx == 6 && cursor.y == (i + 1) ? mem_cursor_color : WHITE_RGBA), - GZ_checkDropShadows()); - GZ_drawText(b7, address_offset + b_offset * 7, y_offset, - (l_byteIdx == 7 && cursor.y == (i + 1) ? mem_cursor_color : WHITE_RGBA), - GZ_checkDropShadows()); + for (uint8_t k = 0; k < line_length; ++k) { + float middle_offset = k < line_length / 2 ? 0.0f : Font::getCharWidth(' '); + GZ_drawText(b[k], address_offset + b_offset * k + middle_offset, y_offset, + (l_byteIdx == k && cursor.y == (i + 1) ? mem_cursor_color : WHITE_RGBA), + GZ_checkDropShadows()); + // The text version of it + GZ_drawText(c[k], chars_offset + c_offset * k + middle_offset, y_offset, + (l_byteIdx == k && cursor.y == (i + 1) ? mem_cursor_color : WHITE_RGBA), + GZ_checkDropShadows()); + } } } @@ -188,6 +184,13 @@ void MemoryEditorMenu::draw() { } } + if (GZ_getButtonTrig(LINE_SIZE_BTN)) { + line_length = line_length == 8 ? 16 : 8; + if (g_memoryEditor_addressIndex > MAX_ADDRESS) { + g_memoryEditor_addressIndex = MAX_ADDRESS; + } + } + if (GZ_getButtonTrig(SELECTION_BUTTON)) { switch (cursor.y) { case 0: @@ -202,8 +205,8 @@ void MemoryEditorMenu::draw() { } } - cursor.move(8, 1 + MAX_DISPLAY_LINES); - GZ_drawText("DPad to move/modify value, A/B to (de)select value", 25.0f, 440.f, WHITE_RGBA, + cursor.move(line_length, 1 + MAX_DISPLAY_LINES); + GZ_drawText("DPad to move/modify value, A/B to (de)select value;" LINE_SIZE_TEXT " toggle line size", 25.0f, 440.f, WHITE_RGBA, GZ_checkDropShadows()); drawMemEditor(); } \ No newline at end of file diff --git a/modules/menus/menu_nosq_saves/include/nosq_saves_menu.h b/modules/menus/menu_nosq_saves/include/nosq_saves_menu.h index 48bc42b4..c2f455f1 100644 --- a/modules/menus/menu_nosq_saves/include/nosq_saves_menu.h +++ b/modules/menus/menu_nosq_saves/include/nosq_saves_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" #define NOSQ_SPECIALS_AMNT 18 diff --git a/modules/menus/menu_nosq_saves/src/nosq_saves_menu.cpp b/modules/menus/menu_nosq_saves/src/nosq_saves_menu.cpp index 23bab3ca..a6ca371b 100644 --- a/modules/menus/menu_nosq_saves/src/nosq_saves_menu.cpp +++ b/modules/menus/menu_nosq_saves/src/nosq_saves_menu.cpp @@ -86,10 +86,10 @@ void NoSQSavesMenu::draw() { }; SaveManager::triggerLoad(cursor.y, "nosq", NoSQSpecials, - sizeof(NoSQSpecials) / sizeof(NoSQSpecials[0])); + ARRAY_COUNT(NoSQSpecials)); g_menuMgr->hide(); } - cursor.move(0, sizeof(lines) / sizeof(lines[0])); - GZ_drawMenuLines(lines, cursor.y, sizeof(lines) / sizeof(lines[0])); + cursor.move(0, ARRAY_COUNT(lines)); + GZ_drawMenuLines(lines, cursor.y, ARRAY_COUNT(lines)); } \ No newline at end of file diff --git a/modules/menus/menu_pause/include/pause_menu.h b/modules/menus/menu_pause/include/pause_menu.h index a89d2e07..1d6543fc 100644 --- a/modules/menus/menu_pause/include/pause_menu.h +++ b/modules/menus/menu_pause/include/pause_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" struct PauseData { uint8_t l_ordonSword_idx; @@ -40,31 +40,15 @@ enum PauseIndex { GREAT_SPIN_INDEX }; +extern PauseData* pauseData; + class PauseMenu : public Menu { public: - PauseMenu(Cursor&, PauseData&); + PauseMenu(Cursor&); virtual ~PauseMenu(); virtual void draw(); private: - uint8_t& l_ordonSword_idx; - uint8_t& l_masterSword_idx; - uint8_t& l_woodShield_idx; - uint8_t& l_hyShield_idx; - uint8_t& l_tunic_idx; - uint8_t& l_zoraArmor_idx; - uint8_t& l_magicArmor_idx; - uint8_t& l_bombCap_idx; - uint8_t& l_wallet_idx; - uint8_t& l_arrowCap_idx; - bool& l_ebFlag; - bool& l_sbFlag; - bool& l_bsFlag; - bool& l_hsFlag; - bool& l_mdFlag; - bool& l_jsFlag; - bool& l_gsFlag; - Line lines[17]; void resetIndex(); diff --git a/modules/menus/menu_pause/src/main.cpp b/modules/menus/menu_pause/src/main.cpp index 136dcc9b..dde48af0 100644 --- a/modules/menus/menu_pause/src/main.cpp +++ b/modules/menus/menu_pause/src/main.cpp @@ -35,8 +35,8 @@ void onCreate() { } void onLoad() { - l_menu = new PauseMenu(*g_menuMgr->getPermanentData(), - *g_menuMgr->getPersistentData()); + pauseData = g_menuMgr->getPersistentData(); + l_menu = new PauseMenu(*g_menuMgr->getPermanentData()); g_drawListener->addListener(onDraw); } diff --git a/modules/menus/menu_pause/src/pause_menu.cpp b/modules/menus/menu_pause/src/pause_menu.cpp index 403e096f..4f04ef9d 100644 --- a/modules/menus/menu_pause/src/pause_menu.cpp +++ b/modules/menus/menu_pause/src/pause_menu.cpp @@ -18,15 +18,10 @@ #define MAX_ARROW_CAPACITY_OPT 3 #define MAX_HIDDEN_SKILL_OPT 2 -KEEP_FUNC PauseMenu::PauseMenu(Cursor& cursor, PauseData& data) - : Menu(cursor), l_ordonSword_idx(data.l_ordonSword_idx), - l_masterSword_idx(data.l_masterSword_idx), l_woodShield_idx(data.l_woodShield_idx), - l_hyShield_idx(data.l_hyShield_idx), l_tunic_idx(data.l_tunic_idx), - l_zoraArmor_idx(data.l_zoraArmor_idx), l_magicArmor_idx(data.l_magicArmor_idx), - l_bombCap_idx(data.l_bombCap_idx), l_wallet_idx(data.l_wallet_idx), - l_arrowCap_idx(data.l_arrowCap_idx), l_ebFlag(data.l_ebFlag), l_sbFlag(data.l_sbFlag), - l_bsFlag(data.l_bsFlag), l_hsFlag(data.l_hsFlag), l_mdFlag(data.l_mdFlag), - l_jsFlag(data.l_jsFlag), l_gsFlag(data.l_gsFlag), +KEEP_VAR PauseData* pauseData; + +KEEP_FUNC PauseMenu::PauseMenu(Cursor& cursor) + : Menu(cursor), lines{{"ordon sword:", ORDON_SWORD_INDEX, "Wooden Sword / Ordon Sword", false, nullptr, MAX_ORDON_SWORD_OPT}, {"master sword:", MASTER_SWORD_INDEX, "Master Sword / Light Sword", false, nullptr, @@ -43,86 +38,86 @@ KEEP_FUNC PauseMenu::PauseMenu(Cursor& cursor, PauseData& data) {"wallet upgrade:", WALLET_INDEX, "Wallet Capacity", false, nullptr, MAX_WALLET_OPT}, {"arrow capacity:", ARROW_CAPACITY_INDEX, "Arrow Quiver Capacity", false, nullptr, MAX_ARROW_CAPACITY_OPT}, - {"ending blow:", ENDING_BLOW_INDEX, "Ending Blow", true, &l_ebFlag}, - {"shield bash:", SHIELD_BASH_INDEX, "Shield Bash", true, &l_sbFlag}, - {"backslice:", BACKSLICE_INDEX, "Backslice", true, &l_bsFlag}, - {"helm splitter:", HELM_SPLITTER_INDEX, "Helm Splitter", true, &l_hsFlag}, - {"mortal draw:", MORTAL_DRAW_INDEX, "Mortal Draw", true, &l_mdFlag}, - {"jump strike:", JUMP_STRIKE_INDEX, "Jump Strike", true, &l_jsFlag}, - {"greatspin:", GREAT_SPIN_INDEX, "Greatspin", true, &l_gsFlag}} {} + {"ending blow:", ENDING_BLOW_INDEX, "Ending Blow", true, [](){return pauseData->l_ebFlag;}}, + {"shield bash:", SHIELD_BASH_INDEX, "Shield Bash", true, [](){return pauseData->l_sbFlag;}}, + {"backslice:", BACKSLICE_INDEX, "Backslice", true, [](){return pauseData->l_bsFlag;}}, + {"helm splitter:", HELM_SPLITTER_INDEX, "Helm Splitter", true, [](){return pauseData->l_hsFlag;}}, + {"mortal draw:", MORTAL_DRAW_INDEX, "Mortal Draw", true, [](){return pauseData->l_mdFlag;}}, + {"jump strike:", JUMP_STRIKE_INDEX, "Jump Strike", true, [](){return pauseData->l_jsFlag;}}, + {"greatspin:", GREAT_SPIN_INDEX, "Greatspin", true, [](){return pauseData->l_gsFlag;}}} {} PauseMenu::~PauseMenu() {} void PauseMenu::resetIndex() { - l_ordonSword_idx = 0; - l_masterSword_idx = 0; - l_woodShield_idx = 0; - l_hyShield_idx = 0; - l_tunic_idx = 0; - l_zoraArmor_idx = 0; - l_magicArmor_idx = 0; - l_bombCap_idx = 0; - l_wallet_idx = 0; - l_arrowCap_idx = 0; + pauseData->l_ordonSword_idx = 0; + pauseData->l_masterSword_idx = 0; + pauseData->l_woodShield_idx = 0; + pauseData->l_hyShield_idx = 0; + pauseData->l_tunic_idx = 0; + pauseData->l_zoraArmor_idx = 0; + pauseData->l_magicArmor_idx = 0; + pauseData->l_bombCap_idx = 0; + pauseData->l_wallet_idx = 0; + pauseData->l_arrowCap_idx = 0; } void PauseMenu::getEquipment() { if (dComIfGs_isItemFirstBit(SWORD)) { - l_ordonSword_idx = 2; + pauseData->l_ordonSword_idx = 2; } else if (dComIfGs_isItemFirstBit(WOOD_STICK)) { - l_ordonSword_idx = 1; + pauseData->l_ordonSword_idx = 1; } if (dComIfGs_isItemFirstBit(LIGHT_SWORD)) { - l_masterSword_idx = 2; + pauseData->l_masterSword_idx = 2; } else if (dComIfGs_isItemFirstBit(MASTER_SWORD)) { - l_masterSword_idx = 1; + pauseData->l_masterSword_idx = 1; } if (dComIfGs_isItemFirstBit(SHIELD)) { - l_woodShield_idx = 2; + pauseData->l_woodShield_idx = 2; } else if (dComIfGs_isItemFirstBit(WOOD_SHIELD)) { - l_woodShield_idx = 1; + pauseData->l_woodShield_idx = 1; } if (dComIfGs_isItemFirstBit(HYLIA_SHIELD)) { - l_hyShield_idx = 1; + pauseData->l_hyShield_idx = 1; } if (dComIfGs_isItemFirstBit(WEAR_KOKIRI)) { - l_tunic_idx = 1; + pauseData->l_tunic_idx = 1; } if (dComIfGs_isItemFirstBit(WEAR_ZORA)) { - l_zoraArmor_idx = 1; + pauseData->l_zoraArmor_idx = 1; } if (dComIfGs_isItemFirstBit(ARMOR)) { - l_magicArmor_idx = 1; + pauseData->l_magicArmor_idx = 1; } if (dComIfGs_isItemFirstBit(BOMB_BAG_LV2)) { - l_bombCap_idx = 1; + pauseData->l_bombCap_idx = 1; } switch (dComIfGs_getWalletSize()) { case 1: - l_wallet_idx = 1; + pauseData->l_wallet_idx = 1; break; case 2: - l_wallet_idx = 2; + pauseData->l_wallet_idx = 2; break; } if (dComIfGs_getArrowMax() == 100) { - l_arrowCap_idx = 2; + pauseData->l_arrowCap_idx = 2; } else if (dComIfGs_getArrowMax() == 60) { - l_arrowCap_idx = 1; + pauseData->l_arrowCap_idx = 1; } } void PauseMenu::setEquipment() { - switch (l_ordonSword_idx) { + switch (pauseData->l_ordonSword_idx) { case 0: dComIfGs_offItemFirstBit(WOOD_STICK); dComIfGs_offItemFirstBit(SWORD); @@ -137,7 +132,7 @@ void PauseMenu::setEquipment() { break; } - switch (l_masterSword_idx) { + switch (pauseData->l_masterSword_idx) { case 0: dComIfGs_offItemFirstBit(MASTER_SWORD); dComIfGs_offItemFirstBit(LIGHT_SWORD); @@ -151,7 +146,7 @@ void PauseMenu::setEquipment() { break; } - switch (l_woodShield_idx) { + switch (pauseData->l_woodShield_idx) { case 0: dComIfGs_offItemFirstBit(SHIELD); dComIfGs_offItemFirstBit(WOOD_SHIELD); @@ -164,7 +159,7 @@ void PauseMenu::setEquipment() { break; } - switch (l_hyShield_idx) { + switch (pauseData->l_hyShield_idx) { case 0: dComIfGs_offItemFirstBit(HYLIA_SHIELD); break; @@ -173,7 +168,7 @@ void PauseMenu::setEquipment() { break; } - switch (l_tunic_idx) { + switch (pauseData->l_tunic_idx) { case 0: dComIfGs_offItemFirstBit(WEAR_KOKIRI); break; @@ -182,7 +177,7 @@ void PauseMenu::setEquipment() { break; } - switch (l_zoraArmor_idx) { + switch (pauseData->l_zoraArmor_idx) { case 0: dComIfGs_offItemFirstBit(WEAR_ZORA); break; @@ -191,7 +186,7 @@ void PauseMenu::setEquipment() { break; } - switch (l_magicArmor_idx) { + switch (pauseData->l_magicArmor_idx) { case 0: dComIfGs_offItemFirstBit(ARMOR); break; @@ -200,7 +195,7 @@ void PauseMenu::setEquipment() { break; } - switch (l_bombCap_idx) { + switch (pauseData->l_bombCap_idx) { case 0: dComIfGs_offItemFirstBit(BOMB_BAG_LV2); break; @@ -209,7 +204,7 @@ void PauseMenu::setEquipment() { break; } - switch (l_wallet_idx) { + switch (pauseData->l_wallet_idx) { case 0: dComIfGs_setWalletSize(WALLET); break; @@ -221,7 +216,7 @@ void PauseMenu::setEquipment() { break; } - switch (l_arrowCap_idx) { + switch (pauseData->l_arrowCap_idx) { case 0: dComIfGs_setArrowMax(30); break; @@ -251,13 +246,13 @@ void PauseMenu::draw() { } // update hidden skill flags - l_ebFlag = dComIfGs_isEventBit(0x2904); - l_sbFlag = dComIfGs_isEventBit(0x2908); - l_bsFlag = dComIfGs_isEventBit(0x2902); - l_hsFlag = dComIfGs_isEventBit(0x2901); - l_mdFlag = dComIfGs_isEventBit(0x2A80); - l_jsFlag = dComIfGs_isEventBit(0x2A40); - l_gsFlag = dComIfGs_isEventBit(0x2A20); + pauseData->l_ebFlag = dComIfGs_isEventBit(0x2904); + pauseData->l_sbFlag = dComIfGs_isEventBit(0x2908); + pauseData->l_bsFlag = dComIfGs_isEventBit(0x2902); + pauseData->l_hsFlag = dComIfGs_isEventBit(0x2901); + pauseData->l_mdFlag = dComIfGs_isEventBit(0x2A80); + pauseData->l_jsFlag = dComIfGs_isEventBit(0x2A40); + pauseData->l_gsFlag = dComIfGs_isEventBit(0x2A20); ListMember ordonSword_opt[3] = {"none", "wooden sword", "ordon sword"}; ListMember masterSword_opt[3] = {"none", "master sword", "light sword"}; @@ -272,83 +267,83 @@ void PauseMenu::draw() { switch (cursor.y) { case ORDON_SWORD_INDEX: - cursor.x = l_ordonSword_idx; + cursor.x = pauseData->l_ordonSword_idx; cursor.move(MAX_ORDON_SWORD_OPT, MENU_LINE_NUM); if (cursor.y == ORDON_SWORD_INDEX) { - l_ordonSword_idx = cursor.x; + pauseData->l_ordonSword_idx = cursor.x; } break; case MASTER_SWORD_INDEX: - cursor.x = l_masterSword_idx; + cursor.x = pauseData->l_masterSword_idx; cursor.move(MAX_MASTER_SWORD_OPT, MENU_LINE_NUM); if (cursor.y == MASTER_SWORD_INDEX) { - l_masterSword_idx = cursor.x; + pauseData->l_masterSword_idx = cursor.x; } break; case WOOD_SHIELD_INDEX: - cursor.x = l_woodShield_idx; + cursor.x = pauseData->l_woodShield_idx; cursor.move(MAX_WOOD_SHIELD_OPT, MENU_LINE_NUM); if (cursor.y == WOOD_SHIELD_INDEX) { - l_woodShield_idx = cursor.x; + pauseData->l_woodShield_idx = cursor.x; } break; case HYLIAN_SHIELD_INDEX: - cursor.x = l_hyShield_idx; + cursor.x = pauseData->l_hyShield_idx; cursor.move(MAX_HYLIAN_SHIELD_OPT, MENU_LINE_NUM); if (cursor.y == HYLIAN_SHIELD_INDEX) { - l_hyShield_idx = cursor.x; + pauseData->l_hyShield_idx = cursor.x; } break; case HERO_TUNIC_INDEX: - cursor.x = l_tunic_idx; + cursor.x = pauseData->l_tunic_idx; cursor.move(MAX_HERO_TUNIC_OPT, MENU_LINE_NUM); if (cursor.y == HERO_TUNIC_INDEX) { - l_tunic_idx = cursor.x; + pauseData->l_tunic_idx = cursor.x; } break; case ZORA_ARMOR_INDEX: - cursor.x = l_zoraArmor_idx; + cursor.x = pauseData->l_zoraArmor_idx; cursor.move(MAX_ZORA_ARMOR_OPT, MENU_LINE_NUM); if (cursor.y == ZORA_ARMOR_INDEX) { - l_zoraArmor_idx = cursor.x; + pauseData->l_zoraArmor_idx = cursor.x; } break; case MAGIC_ARMOR_INDEX: - cursor.x = l_magicArmor_idx; + cursor.x = pauseData->l_magicArmor_idx; cursor.move(MAX_MAGIC_ARMOR_OPT, MENU_LINE_NUM); if (cursor.y == MAGIC_ARMOR_INDEX) { - l_magicArmor_idx = cursor.x; + pauseData->l_magicArmor_idx = cursor.x; } break; case BOMB_CAPACITY_INDEX: - cursor.x = l_bombCap_idx; + cursor.x = pauseData->l_bombCap_idx; cursor.move(MAX_BOMB_CAPACITY_OPT, MENU_LINE_NUM); if (cursor.y == BOMB_CAPACITY_INDEX) { - l_bombCap_idx = cursor.x; + pauseData->l_bombCap_idx = cursor.x; } break; case WALLET_INDEX: - cursor.x = l_wallet_idx; + cursor.x = pauseData->l_wallet_idx; cursor.move(MAX_WALLET_OPT, MENU_LINE_NUM); if (cursor.y == WALLET_INDEX) { - l_wallet_idx = cursor.x; + pauseData->l_wallet_idx = cursor.x; } break; case ARROW_CAPACITY_INDEX: - cursor.x = l_arrowCap_idx; + cursor.x = pauseData->l_arrowCap_idx; cursor.move(MAX_ARROW_CAPACITY_OPT, MENU_LINE_NUM); if (cursor.y == ARROW_CAPACITY_INDEX) { - l_arrowCap_idx = cursor.x; + pauseData->l_arrowCap_idx = cursor.x; } break; default: @@ -384,16 +379,16 @@ void PauseMenu::draw() { setEquipment(); - lines[ORDON_SWORD_INDEX].printf(" <%s>", ordonSword_opt[l_ordonSword_idx].member); - lines[MASTER_SWORD_INDEX].printf(" <%s>", masterSword_opt[l_masterSword_idx].member); - lines[WOOD_SHIELD_INDEX].printf(" <%s>", woodShield_opt[l_woodShield_idx].member); - lines[HYLIAN_SHIELD_INDEX].printf(" <%s>", hyShield_opt[l_hyShield_idx].member); - lines[HERO_TUNIC_INDEX].printf(" <%s>", tunic_opt[l_tunic_idx].member); - lines[ZORA_ARMOR_INDEX].printf(" <%s>", zoraArmor_opt[l_zoraArmor_idx].member); - lines[MAGIC_ARMOR_INDEX].printf(" <%s>", magicArmor_opt[l_magicArmor_idx].member); - lines[BOMB_CAPACITY_INDEX].printf(" <%s>", bombCap_opt[l_bombCap_idx].member); - lines[WALLET_INDEX].printf(" <%s>", wallet_opt[l_wallet_idx].member); - lines[ARROW_CAPACITY_INDEX].printf(" <%s>", arrowCap_opt[l_arrowCap_idx].member); + lines[ORDON_SWORD_INDEX].printf(" <%s>", ordonSword_opt[pauseData->l_ordonSword_idx].member); + lines[MASTER_SWORD_INDEX].printf(" <%s>", masterSword_opt[pauseData->l_masterSword_idx].member); + lines[WOOD_SHIELD_INDEX].printf(" <%s>", woodShield_opt[pauseData->l_woodShield_idx].member); + lines[HYLIAN_SHIELD_INDEX].printf(" <%s>", hyShield_opt[pauseData->l_hyShield_idx].member); + lines[HERO_TUNIC_INDEX].printf(" <%s>", tunic_opt[pauseData->l_tunic_idx].member); + lines[ZORA_ARMOR_INDEX].printf(" <%s>", zoraArmor_opt[pauseData->l_zoraArmor_idx].member); + lines[MAGIC_ARMOR_INDEX].printf(" <%s>", magicArmor_opt[pauseData->l_magicArmor_idx].member); + lines[BOMB_CAPACITY_INDEX].printf(" <%s>", bombCap_opt[pauseData->l_bombCap_idx].member); + lines[WALLET_INDEX].printf(" <%s>", wallet_opt[pauseData->l_wallet_idx].member); + lines[ARROW_CAPACITY_INDEX].printf(" <%s>", arrowCap_opt[pauseData->l_arrowCap_idx].member); GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); } diff --git a/modules/menus/menu_portal_flags/include/portal_flags_menu.h b/modules/menus/menu_portal_flags/include/portal_flags_menu.h index a0173394..9581ff25 100644 --- a/modules/menus/menu_portal_flags/include/portal_flags_menu.h +++ b/modules/menus/menu_portal_flags/include/portal_flags_menu.h @@ -1,5 +1,5 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" struct PortalFlagsData { bool l_mapRegion; @@ -41,31 +41,14 @@ enum PortalFlagsIndex { MIRROR_WARP_INDEX }; +extern PortalFlagsData* portalFlagsData; + class PortalFlagsMenu : public Menu { public: - PortalFlagsMenu(Cursor&, PortalFlagsData&); + PortalFlagsMenu(Cursor&); virtual ~PortalFlagsMenu(); virtual void draw(); private: - bool& l_mapRegion; - uint8_t& l_selRegion; - - bool& l_springWarp; - bool& l_sfaronWarp; - bool& l_nfaronWarp; - bool& l_groveWarp; - bool& l_gorgeWarp; - bool& l_kakWarp; - bool& l_mountainWarp; - bool& l_bridgeWarp; - bool& l_ctWarp; - bool& l_lakeWarp; - bool& l_domainWarp; - bool& l_uzrWarp; - bool& l_snowpeakWarp; - bool& l_mesaWarp; - bool& l_mirrorWarp; - Line lines[17]; }; diff --git a/modules/menus/menu_portal_flags/src/main.cpp b/modules/menus/menu_portal_flags/src/main.cpp index e535cc1d..71943a77 100644 --- a/modules/menus/menu_portal_flags/src/main.cpp +++ b/modules/menus/menu_portal_flags/src/main.cpp @@ -35,8 +35,8 @@ void onCreate() { } void onLoad() { - l_menu = new PortalFlagsMenu(*g_menuMgr->getPermanentData(), - *g_menuMgr->getPersistentData()); + portalFlagsData = g_menuMgr->getPersistentData(); + l_menu = new PortalFlagsMenu(*g_menuMgr->getPermanentData()); g_drawListener->addListener(onDraw); } diff --git a/modules/menus/menu_portal_flags/src/portal_flags_menu.cpp b/modules/menus/menu_portal_flags/src/portal_flags_menu.cpp index 013620b5..48987b93 100644 --- a/modules/menus/menu_portal_flags/src/portal_flags_menu.cpp +++ b/modules/menus/menu_portal_flags/src/portal_flags_menu.cpp @@ -8,35 +8,30 @@ #define MAX_REGION_OPTIONS 6 -KEEP_FUNC PortalFlagsMenu::PortalFlagsMenu(Cursor& cursor, PortalFlagsData& data) - : Menu(cursor), l_mapRegion(data.l_mapRegion), l_selRegion(data.l_selRegion), - l_springWarp(data.l_springWarp), l_sfaronWarp(data.l_sfaronWarp), - l_nfaronWarp(data.l_nfaronWarp), l_groveWarp(data.l_groveWarp), l_gorgeWarp(data.l_gorgeWarp), - l_kakWarp(data.l_kakWarp), l_mountainWarp(data.l_mountainWarp), - l_bridgeWarp(data.l_bridgeWarp), l_ctWarp(data.l_ctWarp), l_lakeWarp(data.l_lakeWarp), - l_domainWarp(data.l_domainWarp), l_uzrWarp(data.l_uzrWarp), - l_snowpeakWarp(data.l_snowpeakWarp), l_mesaWarp(data.l_mesaWarp), - l_mirrorWarp(data.l_mirrorWarp), +KEEP_VAR PortalFlagsData* portalFlagsData; + +KEEP_FUNC PortalFlagsMenu::PortalFlagsMenu(Cursor& cursor) + : Menu(cursor), lines{ {"region:", SELECT_REGION_INDEX, "Select region flag", false, nullptr, MAX_REGION_OPTIONS}, - {"region unlocked", REGION_FLAG_INDEX, "Unlock selected map region", true, &l_mapRegion}, - {"ordon spring", SPRING_WARP_INDEX, "Ordon Spring warp portal", true, &l_springWarp}, - {"south faron", S_FARON_WARP_INDEX, "South Faron warp portal", true, &l_sfaronWarp}, - {"north faron", N_FARON_WARP_INDEX, "North Faron warp portal", true, &l_nfaronWarp}, - {"sacred grove", GROVE_WARP_INDEX, "Sacred Grove warp portal", true, &l_groveWarp}, - {"eldin gorge", GORGE_WARP_INDEX, "Eldin Gorge warp portal", true, &l_gorgeWarp}, - {"kak village", KAKARIKO_WARP_INDEX, "Kakariko Village warp portal", true, &l_kakWarp}, + {"region unlocked", REGION_FLAG_INDEX, "Unlock selected map region", true, [](){return portalFlagsData->l_mapRegion;}}, + {"ordon spring", SPRING_WARP_INDEX, "Ordon Spring warp portal", true, [](){return portalFlagsData->l_springWarp;}}, + {"south faron", S_FARON_WARP_INDEX, "South Faron warp portal", true, [](){return portalFlagsData->l_sfaronWarp;}}, + {"north faron", N_FARON_WARP_INDEX, "North Faron warp portal", true, [](){return portalFlagsData->l_nfaronWarp;}}, + {"sacred grove", GROVE_WARP_INDEX, "Sacred Grove warp portal", true, [](){return portalFlagsData->l_groveWarp;}}, + {"eldin gorge", GORGE_WARP_INDEX, "Eldin Gorge warp portal", true, [](){return portalFlagsData->l_gorgeWarp;}}, + {"kak village", KAKARIKO_WARP_INDEX, "Kakariko Village warp portal", true, [](){return portalFlagsData->l_kakWarp;}}, {"death mountain", MOUNTAIN_WARP_INDEX, "Death Mountain warp portal", true, - &l_mountainWarp}, - {"eldin bridge", BRIDGE_WARP_INDEX, "Bridge of Eldin warp portal", true, &l_bridgeWarp}, - {"castle town", TOWN_WARP_INDEX, "Castle Town warp portal", true, &l_ctWarp}, - {"lake hylia", LAKE_WARP_INDEX, "Lake Hylia warp portal", true, &l_lakeWarp}, - {"zora's domain", DOMAIN_WARP_INDEX, "Zora's Domain warp portal", true, &l_domainWarp}, - {"upper river", UZR_WARP_INDEX, "Upper Zora's River warp portal", true, &l_uzrWarp}, - {"snowpeak", SNOWPEAK_WARP_INDEX, "Snowpeak warp portal", true, &l_snowpeakWarp}, - {"gerudo mesa", MESA_WARP_INDEX, "Gerudo Mesa warp portal", true, &l_mesaWarp}, - {"mirror chamber", MIRROR_WARP_INDEX, "Mirror Chamber warp portal", true, &l_mirrorWarp}, + [](){return portalFlagsData->l_mountainWarp;}}, + {"eldin bridge", BRIDGE_WARP_INDEX, "Bridge of Eldin warp portal", true, [](){return portalFlagsData->l_bridgeWarp;}}, + {"castle town", TOWN_WARP_INDEX, "Castle Town warp portal", true, [](){return portalFlagsData->l_ctWarp;}}, + {"lake hylia", LAKE_WARP_INDEX, "Lake Hylia warp portal", true, [](){return portalFlagsData->l_lakeWarp;}}, + {"zora's domain", DOMAIN_WARP_INDEX, "Zora's Domain warp portal", true, [](){return portalFlagsData->l_domainWarp;}}, + {"upper river", UZR_WARP_INDEX, "Upper Zora's River warp portal", true, [](){return portalFlagsData->l_uzrWarp;}}, + {"snowpeak", SNOWPEAK_WARP_INDEX, "Snowpeak warp portal", true, [](){return portalFlagsData->l_snowpeakWarp;}}, + {"gerudo mesa", MESA_WARP_INDEX, "Gerudo Mesa warp portal", true, [](){return portalFlagsData->l_mesaWarp;}}, + {"mirror chamber", MIRROR_WARP_INDEX, "Mirror Chamber warp portal", true, [](){return portalFlagsData->l_mirrorWarp;}}, } {} PortalFlagsMenu::~PortalFlagsMenu() {} @@ -64,22 +59,22 @@ inline bool getRegionFlag(int regionBit) { void PortalFlagsMenu::draw() { cursor.setMode(Cursor::MODE_LIST); - l_mapRegion = getRegionFlag(l_selRegion + 1); - l_springWarp = getSaveSwitch(dSv_memory_c::ORDON, 52); - l_sfaronWarp = getSaveSwitch(dSv_memory_c::FARON, 71); - l_nfaronWarp = getSaveSwitch(dSv_memory_c::FARON, 2); - l_groveWarp = getSaveSwitch(dSv_memory_c::GROVE, 100); - l_gorgeWarp = getSaveSwitch(dSv_memory_c::FIELD, 21); - l_kakWarp = getSaveSwitch(dSv_memory_c::ELDIN, 31); - l_mountainWarp = getSaveSwitch(dSv_memory_c::ELDIN, 21); - l_bridgeWarp = getSaveSwitch(dSv_memory_c::FIELD, 99); - l_ctWarp = getSaveSwitch(dSv_memory_c::FIELD, 3); - l_lakeWarp = getSaveSwitch(dSv_memory_c::LANAYRU, 10); - l_domainWarp = getSaveSwitch(dSv_memory_c::LANAYRU, 2); - l_uzrWarp = getSaveSwitch(dSv_memory_c::LANAYRU, 21); - l_snowpeakWarp = getSaveSwitch(dSv_memory_c::SNOWPEAK, 21); - l_mesaWarp = getSaveSwitch(dSv_memory_c::DESERT, 21); - l_mirrorWarp = getSaveSwitch(dSv_memory_c::DESERT, 40); + portalFlagsData->l_mapRegion = getRegionFlag(portalFlagsData->l_selRegion + 1); + portalFlagsData->l_springWarp = getSaveSwitch(dSv_memory_c::ORDON, 52); + portalFlagsData->l_sfaronWarp = getSaveSwitch(dSv_memory_c::FARON, 71); + portalFlagsData->l_nfaronWarp = getSaveSwitch(dSv_memory_c::FARON, 2); + portalFlagsData->l_groveWarp = getSaveSwitch(dSv_memory_c::GROVE, 100); + portalFlagsData->l_gorgeWarp = getSaveSwitch(dSv_memory_c::FIELD, 21); + portalFlagsData->l_kakWarp = getSaveSwitch(dSv_memory_c::ELDIN, 31); + portalFlagsData->l_mountainWarp = getSaveSwitch(dSv_memory_c::ELDIN, 21); + portalFlagsData->l_bridgeWarp = getSaveSwitch(dSv_memory_c::FIELD, 99); + portalFlagsData->l_ctWarp = getSaveSwitch(dSv_memory_c::FIELD, 3); + portalFlagsData->l_lakeWarp = getSaveSwitch(dSv_memory_c::LANAYRU, 10); + portalFlagsData->l_domainWarp = getSaveSwitch(dSv_memory_c::LANAYRU, 2); + portalFlagsData->l_uzrWarp = getSaveSwitch(dSv_memory_c::LANAYRU, 21); + portalFlagsData->l_snowpeakWarp = getSaveSwitch(dSv_memory_c::SNOWPEAK, 21); + portalFlagsData->l_mesaWarp = getSaveSwitch(dSv_memory_c::DESERT, 21); + portalFlagsData->l_mirrorWarp = getSaveSwitch(dSv_memory_c::DESERT, 40); if (GZ_getButtonTrig(BACK_BUTTON)) { g_menuMgr->pop(); @@ -89,7 +84,7 @@ void PortalFlagsMenu::draw() { if (GZ_getButtonTrig(SELECTION_BUTTON)) { switch (cursor.y) { case REGION_FLAG_INDEX: - setRegionFlag(l_selRegion + 1); + setRegionFlag(portalFlagsData->l_selRegion + 1); break; case SPRING_WARP_INDEX: setSaveSwitch(dSv_memory_c::ORDON, 52); @@ -143,11 +138,11 @@ void PortalFlagsMenu::draw() { switch (cursor.y) { case SELECT_REGION_INDEX: - cursor.x = l_selRegion; + cursor.x = portalFlagsData->l_selRegion; cursor.move(MAX_REGION_OPTIONS, MENU_LINE_NUM); if (cursor.y == SELECT_REGION_INDEX) { - l_selRegion = cursor.x; + portalFlagsData->l_selRegion = cursor.x; } break; default: @@ -159,7 +154,7 @@ void PortalFlagsMenu::draw() { "ordon", "faron", "eldin", "lanayru", "desert", "snowpeak", }; - lines[SELECT_REGION_INDEX].printf(" <%s>", region_opt[l_selRegion].member); + lines[SELECT_REGION_INDEX].printf(" <%s>", region_opt[portalFlagsData->l_selRegion].member); GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); } diff --git a/modules/menus/menu_pos_settings/include/position_settings_menu.h b/modules/menus/menu_pos_settings/include/position_settings_menu.h index d23b08ef..08d07131 100644 --- a/modules/menus/menu_pos_settings/include/position_settings_menu.h +++ b/modules/menus/menu_pos_settings/include/position_settings_menu.h @@ -1,6 +1,6 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" #include "pos_settings.h" #define POSITION_SETTINGS_NO_SELECTION ((uint8_t)-1) diff --git a/modules/menus/menu_pos_settings/src/position_settings_menu.cpp b/modules/menus/menu_pos_settings/src/position_settings_menu.cpp index 25d941fc..f942aaa0 100644 --- a/modules/menus/menu_pos_settings/src/position_settings_menu.cpp +++ b/modules/menus/menu_pos_settings/src/position_settings_menu.cpp @@ -22,20 +22,41 @@ KEEP_FUNC PosSettingsMenu::PosSettingsMenu(Cursor& cursor, PosSettingsData& data {"load timer", SpritesIndex::LOAD_TIMER_SPR_INDEX, "Change load timer position", false}, {"igt timer", SpritesIndex::IGT_TIMER_SPR_INDEX, "Change IGT timer position", false}, {"fifo queue", SpritesIndex::FIFO_SPR_INDEX, "Change fifo queue position", false}, - {"heap info", SpritesIndex::HEAP_INFO_INDEX, "Change Heap info position", false}} {} + {"heap info", SpritesIndex::HEAP_INFO_INDEX, "Change Heap info position", false}, + {"mash checker", SpritesIndex::MASH_INFO_INDEX, "Change Mash Checker position", false}, + {"transform indicator", SpritesIndex::TRANSFORM_IND_INDEX, "Change Transform Indicator position", false}} {} PosSettingsMenu::~PosSettingsMenu() {} +#ifdef WII_PLATFORM +extern bool isWidescreen; +#else +#define isWidescreen (false) +#endif + void drawCursor(Vec2 pos) { bool cycle = (cCt_getFrameCount() / 8) % 2; if (GZ_checkDropShadows()) { - Draw::drawRectOutline(DROP_SHADOWS_RGBA, {pos.x - 10 + 1, pos.y + 1}, {20, 0}, 0xA); + Draw::drawRectOutline(DROP_SHADOWS_RGBA, {pos.x - 10 * (isWidescreen ? 0.75f : 1.0f) + 1, pos.y + 1}, {20 * (isWidescreen ? 0.75f : 1.0f), 0}, 0xA); Draw::drawRectOutline(DROP_SHADOWS_RGBA, {pos.x + 1, pos.y - 10 + 1}, {0, 20}, 0xA); } - Draw::drawRectOutline(cycle ? g_cursorColor : 0xFFFFFFFF, {pos.x - 10, pos.y}, {20, 0}, 0xA); + Draw::drawRectOutline(cycle ? g_cursorColor : 0xFFFFFFFF, {pos.x - 10 * (isWidescreen ? 0.75f : 1.0f), pos.y}, {20 * (isWidescreen ? 0.75f : 1.0f), 0}, 0xA); Draw::drawRectOutline(cycle ? g_cursorColor : 0xFFFFFFFF, {pos.x, pos.y - 10}, {0, 20}, 0xA); } +GZSettingID l_mapping[] = { + STNG_SPRITES_MENU, + STNG_SPRITES_INPUT_VIEWER, + STNG_SPRITES_DEBUG_INFO, + STNG_SPRITES_TIMER_SPR, + STNG_SPRITES_LOAD_TIMER_SPR, + STNG_SPRITES_IGT_TIMER_SPR, + STNG_SPRITES_FIFO_SPR, + STNG_SPRITES_HEAP_INFO, + STNG_SPRITES_MASH_INFO, + STNG_SPRITES_TRANSFORM_IND, +}; + void PosSettingsMenu::draw() { cursor.setMode(Cursor::MODE_UNRESTRICTED); @@ -60,22 +81,28 @@ void PosSettingsMenu::draw() { } } + auto* stng = GZStng_get(l_mapping[l_selItem]); + if (!stng) { + stng = new GZSettingEntry{l_mapping[l_selItem], sizeof(Vec2), new Vec2{0.0f, 0.0f}}; + g_settings.push_back(stng); + } + Vec2* pos = static_cast(stng->data); if (l_selItem != POSITION_SETTINGS_NO_SELECTION && l_selItem < SPRITES_AMNT) { if (GZ_getButtonRepeat(GZPad::DPAD_RIGHT, 3)) { - g_spriteOffsets[l_selItem].x += l_cursorSpeed; + pos->x += l_cursorSpeed; } if (GZ_getButtonRepeat(GZPad::DPAD_LEFT, 3)) { - g_spriteOffsets[l_selItem].x -= l_cursorSpeed; + pos->x -= l_cursorSpeed; } if (GZ_getButtonRepeat(GZPad::DPAD_UP, 3)) { - g_spriteOffsets[l_selItem].y -= l_cursorSpeed; + pos->y -= l_cursorSpeed; } if (GZ_getButtonRepeat(GZPad::DPAD_DOWN, 3)) { - g_spriteOffsets[l_selItem].y += l_cursorSpeed; + pos->y += l_cursorSpeed; } // Draw visual cursor - drawCursor(g_spriteOffsets[l_selItem]); + drawCursor(*pos); } if (GZ_getButtonPressed(GZPad::DPAD_RIGHT) || GZ_getButtonPressed(GZPad::DPAD_LEFT) || diff --git a/modules/menus/menu_practice/include/practice_menu.h b/modules/menus/menu_practice/include/practice_menu.h index 50ec3dc5..c66a8f65 100644 --- a/modules/menus/menu_practice/include/practice_menu.h +++ b/modules/menus/menu_practice/include/practice_menu.h @@ -1,5 +1,5 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" #include "practice.h" #include "gz_flags.h" diff --git a/modules/menus/menu_projection_view/CMakeLists.txt b/modules/menus/menu_projection_view/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/menus/menu_projection_view/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/menus/menu_projection_view/include/main.h b/modules/menus/menu_projection_view/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/menus/menu_projection_view/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/menus/menu_projection_view/include/projection_view_menu.h b/modules/menus/menu_projection_view/include/projection_view_menu.h new file mode 100644 index 00000000..033939e5 --- /dev/null +++ b/modules/menus/menu_projection_view/include/projection_view_menu.h @@ -0,0 +1,14 @@ +#pragma once + +#include "menus/menu.h" +#include "features/projection_view/include/projection_view.h" + +class ProjectionViewMenu : public Menu { +public: + ProjectionViewMenu(Cursor&); + virtual ~ProjectionViewMenu(); + virtual void draw(); + +private: + Line lines[PROJECTION_VIEW_MAX]; +}; \ No newline at end of file diff --git a/modules/menus/menu_projection_view/src/main.cpp b/modules/menus/menu_projection_view/src/main.cpp new file mode 100644 index 00000000..f0c94a83 --- /dev/null +++ b/modules/menus/menu_projection_view/src/main.cpp @@ -0,0 +1,50 @@ +#include +#include "menus/menu_projection_view/include/projection_view_menu.h" +#include "events/draw_listener.h" +#include "menus/utils/menu_mgr.h" +#include "utils/draw.h" + +void onCreate(); +void onLoad(); +void onDraw(); +void onUnload(); +void onDelete(); + +ProjectionViewMenu* l_menu; + +namespace tpgz::modules { +void main() { + g_menuMgr->setCreateHook(onCreate); + g_menuMgr->setLoadHook(onLoad); + g_menuMgr->setUnloadHook(onUnload); + g_menuMgr->setDeleteHook(onDelete); +} +void exit() { + g_menuMgr->setCreateHook(nullptr); + g_menuMgr->setLoadHook(nullptr); + g_menuMgr->setUnloadHook(nullptr); + g_menuMgr->setDeleteHook(nullptr); +} +} // namespace tpgz::modules + +void onCreate() { + if (!g_menuMgr->getPermanentData()) { + g_menuMgr->setPermanentData(new Cursor); + } +} + +void onLoad() { + l_menu = new ProjectionViewMenu(*g_menuMgr->getPermanentData()); + g_drawListener->addListener(onDraw); +} + +void onDraw() { + l_menu->draw(); +} + +void onUnload() { + g_drawListener->removeListener(onDraw); + delete l_menu; +} + +void onDelete() {} diff --git a/modules/menus/menu_projection_view/src/projection_view_menu.cpp b/modules/menus/menu_projection_view/src/projection_view_menu.cpp new file mode 100644 index 00000000..97c02550 --- /dev/null +++ b/modules/menus/menu_projection_view/src/projection_view_menu.cpp @@ -0,0 +1,39 @@ +#include +#include "menus/menu_projection_view/include/projection_view_menu.h" +#include "rels/include/defines.h" +#include "menus/utils/menu_mgr.h" +#include "collision_view.h" +#include "settings.h" + +KEEP_FUNC ProjectionViewMenu::ProjectionViewMenu(Cursor& cursor) + : Menu(cursor), lines{ + {"lja", VIEW_LJA_PROJECTION, "display projected path taken of an LJA", true, + ACTIVE_FUNC(STNG_SCENE_LJA_PROJECTION)}, + {"midna charge", VIEW_MIDNA_CHARGE_PROJECTION, "display projected path taken by a super jump", true, + ACTIVE_FUNC(STNG_SCENE_MIDNA_CHARGE_PROJECTION)}, + } {} + +ProjectionViewMenu::~ProjectionViewMenu() {} + +GZSettingID l_mapping[] = {STNG_SCENE_LJA_PROJECTION, STNG_SCENE_MIDNA_CHARGE_PROJECTION}; + +void ProjectionViewMenu::draw() { + cursor.setMode(Cursor::MODE_LIST); + + if (GZ_getButtonTrig(BACK_BUTTON)) { + g_menuMgr->pop(); + return; + } + + if (GZ_getButtonTrig(SELECTION_BUTTON)) { + auto* stng [[maybe_unused]] = GZStng_get(l_mapping[cursor.y]); + if (!stng) { + stng = new GZSettingEntry{l_mapping[cursor.y], sizeof(bool), new bool}; + g_settings.push_back(stng); + } + *static_cast(stng->data) = !*static_cast(stng->data); + } + + cursor.move(0, MENU_LINE_NUM); + GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); +} diff --git a/modules/menus/menu_scene/include/scene_menu.h b/modules/menus/menu_scene/include/scene_menu.h index c215c816..b067cd01 100644 --- a/modules/menus/menu_scene/include/scene_menu.h +++ b/modules/menus/menu_scene/include/scene_menu.h @@ -1,6 +1,6 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" #include "scene.h" class SceneMenu : public Menu { @@ -10,5 +10,5 @@ class SceneMenu : public Menu { virtual void draw(); private: - Line lines[11]; + Line lines[SCENE_MENU_MAX]; }; \ No newline at end of file diff --git a/modules/menus/menu_scene/src/scene_menu.cpp b/modules/menus/menu_scene/src/scene_menu.cpp index f25183a6..9f7fc36c 100644 --- a/modules/menus/menu_scene/src/scene_menu.cpp +++ b/modules/menus/menu_scene/src/scene_menu.cpp @@ -3,35 +3,53 @@ #include "libtp_c/include/d/com/d_com_inf_game.h" #include "libtp_c/include/d/meter/d_meter_HIO.h" #include "gz_flags.h" +#include "settings.h" #include "rels/include/defines.h" #include "menus/utils/menu_mgr.h" +KEEP_FUNC bool is_active(GZSettingID id) { + return GZStng_getData(id, false); +} + KEEP_FUNC SceneMenu::SceneMenu(Cursor& cursor) : Menu(cursor), lines{ {"disable bg music", DISABLE_BG_INDEX, "Disables background and enemy music", true, - &g_sceneFlags[DISABLE_BG_INDEX].active}, + ACTIVE_FUNC(STNG_SCENE_DISABLE_BG)}, {"disable sfx", DISABLE_SFX_INDEX, "Disables sound effects", true, - &g_sceneFlags[DISABLE_SFX_INDEX].active}, + ACTIVE_FUNC(STNG_SCENE_DISABLE_SFX)}, {"freeze actors", FREEZE_ACTOR_INDEX, "Freezes actors", true, - &g_sceneFlags[FREEZE_ACTOR_INDEX].active}, + ACTIVE_FUNC(STNG_SCENE_FREEZE_ACTOR)}, {"freeze camera", FREEZE_CAMERA_INDEX, "Locks the camera in place", true, - &g_sceneFlags[FREEZE_CAMERA_INDEX].active}, + ACTIVE_FUNC(STNG_SCENE_FREEZE_CAMERA)}, {"hide actors", HIDE_ACTOR_INDEX, "Hides actors", true, - &g_sceneFlags[HIDE_ACTOR_INDEX].active}, + ACTIVE_FUNC(STNG_SCENE_HIDE_ACTOR)}, {"hide hud", HIDE_HUD_INDEX, "Hides the heads-up display", true, - &g_sceneFlags[HIDE_HUD_INDEX].active}, + ACTIVE_FUNC(STNG_SCENE_HIDE_HUD)}, {"freeze time", FREEZE_TIME_INDEX, "Freezes ingame time", true, - &g_sceneFlags[FREEZE_TIME_INDEX].active}, + ACTIVE_FUNC(STNG_SCENE_FREEZE_TIME)}, {"time (hrs):", TIME_HOURS_INDEX, "The current in-game hour", false}, {"time (mins):", TIME_MINUTES_INDEX, "The current in-game minutes", false}, {"actor spawner", ACTOR_MENU_INDEX, "Spawn Actors at current position", false}, {"actor list", ACTOR_LIST_INDEX, "Display info from the actor list", false}, + {"collision viewer", COLLISION_VIEW_INDEX, "Change Collision Viewer settings", false}, + {"projection viewer", PROJECTION_VIEW_INDEX, "Change Projection Viewer settings", false}, + {"trigger viewer", TRIGGER_VIEW_INDEX, "Change Trigger Viewer settings", false}, } {} SceneMenu::~SceneMenu() {} +KEEP_VAR GZSettingID l_mapping[] = { + STNG_SCENE_DISABLE_BG, + STNG_SCENE_DISABLE_SFX, + STNG_SCENE_FREEZE_ACTOR, + STNG_SCENE_FREEZE_CAMERA, + STNG_SCENE_HIDE_ACTOR, + STNG_SCENE_HIDE_HUD, + STNG_SCENE_FREEZE_TIME, +}; + void SceneMenu::draw() { cursor.setMode(Cursor::MODE_LIST); @@ -52,7 +70,14 @@ void SceneMenu::draw() { lines[TIME_MINUTES_INDEX].printf(" <%d>", current_minute); if (GZ_getButtonTrig(SELECTION_BUTTON)) { - g_sceneFlags[cursor.y].active = !g_sceneFlags[cursor.y].active; + if (cursor.y < TIME_HOURS_INDEX) { + auto* stng = GZStng_get(l_mapping[cursor.y]); + if (!stng) { + stng = new GZSettingEntry{l_mapping[cursor.y], sizeof(bool), new bool(false)}; + g_settings.push_back(stng); + } + *static_cast(stng->data) = !*static_cast(stng->data); + } switch (cursor.y) { case ACTOR_MENU_INDEX: @@ -61,6 +86,15 @@ void SceneMenu::draw() { case ACTOR_LIST_INDEX: g_menuMgr->push(MN_ACTOR_LIST_INDEX); return; + case COLLISION_VIEW_INDEX: + g_menuMgr->push(MN_COLLISION_VIEW_INDEX); + return; + case PROJECTION_VIEW_INDEX: + g_menuMgr->push(MN_PROJECTION_VIEW_INDEX); + return; + case TRIGGER_VIEW_INDEX: + g_menuMgr->push(MN_TRIGGER_VIEW_INDEX); + return; } } diff --git a/modules/menus/menu_settings/include/settings_menu.h b/modules/menus/menu_settings/include/settings_menu.h index 68416907..423f55dd 100644 --- a/modules/menus/menu_settings/include/settings_menu.h +++ b/modules/menus/menu_settings/include/settings_menu.h @@ -1,6 +1,6 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" #include "settings.h" enum SettingsIndex { @@ -12,7 +12,11 @@ enum SettingsIndex { SAVE_CARD_INDEX, LOAD_CARD_INDEX, DELETE_CARD_INDEX, - POS_SETTINGS_MENU_INDEX + COMBO_INDEX, + POS_SETTINGS_MENU_INDEX, + CREDITS_INDEX, + + SETTINGS_COUNT }; class SettingsMenu : public Menu { @@ -22,5 +26,5 @@ class SettingsMenu : public Menu { virtual void draw(); private: - Line lines[9]; + Line lines[SETTINGS_COUNT]; }; \ No newline at end of file diff --git a/modules/menus/menu_settings/src/settings_menu.cpp b/modules/menus/menu_settings/src/settings_menu.cpp index f4ff9201..7e7e40cd 100644 --- a/modules/menus/menu_settings/src/settings_menu.cpp +++ b/modules/menus/menu_settings/src/settings_menu.cpp @@ -3,6 +3,7 @@ #include "utils/card.h" #include "gz_flags.h" #include "fifo_queue.h" +#include "settings.h" #include "rels/include/defines.h" #include "menus/utils/menu_mgr.h" @@ -18,15 +19,17 @@ KEEP_FUNC SettingsMenu::SettingsMenu(Cursor& cursor) MAX_CURSOR_COLOR_OPTIONS}, {"font:", FONT_INDEX, "Change font", false, nullptr, FONT_OPTIONS_COUNT}, {"drop shadows", DROP_SHADOWS_INDEX, "Adds shadows to all font letters", - true, &g_dropShadows}, + true, GZ_checkDropShadows}, {"swap equips", SWAP_EQUIPS_INDEX, - "Swap equips when loading practice files", true, &g_swap_equips_flag}, + "Swap equips when loading practice files", true, [](){return g_swap_equips_flag;}}, {"save card", SAVE_CARD_INDEX, "Save settings to memory card"}, {"load card", LOAD_CARD_INDEX, "Load settings from memory card"}, {"delete card", DELETE_CARD_INDEX, "Delete settings from memory card"}, + {"command combos", COMBO_INDEX, "view command combinations menu", false}, {"menu positions", POS_SETTINGS_MENU_INDEX, "Change menu object positions (A to toggle selection, DPad to move)", false}, + {"credits", CREDITS_INDEX, "view credits", false}, } {} SettingsMenu::~SettingsMenu() {} @@ -39,15 +42,27 @@ void SettingsMenu::draw() { return; } + GZSettingEntry* stng = nullptr; // static Storage storage; if (GZ_getButtonTrig(SELECTION_BUTTON)) { switch (cursor.y) { case DROP_SHADOWS_INDEX: - g_dropShadows = !g_dropShadows; + stng = GZStng_get(STNG_DROP_SHADOWS); + if (!stng) { + stng = new GZSettingEntry{STNG_DROP_SHADOWS, sizeof(bool), new bool{false}}; + g_settings.push_back(stng); + } + *static_cast(stng->data) = !*static_cast(stng->data); break; case POS_SETTINGS_MENU_INDEX: g_menuMgr->push(MN_POS_SETTINGS_INDEX); return; + case CREDITS_INDEX: + g_menuMgr->push(MN_CREDITS_INDEX); + return; + case COMBO_INDEX: + g_menuMgr->push(MN_COMBO_INDEX); + return; case SAVE_CARD_INDEX: { static Storage storage; storage.file_name = "tpgz01"; @@ -104,36 +119,66 @@ void SettingsMenu::draw() { ListMember cursorCol_opt[MAX_CURSOR_COLOR_OPTIONS] = {"green", "blue", "red", "orange", "yellow", "purple"}; + stng = nullptr; + auto prev_x = cursor.x; // handle list rendering switch (cursor.y) { case AREA_RELOAD_BEHAVIOR_INDEX: - cursor.x = g_reloadType; + stng = GZStng_get(STNG_AREA_RELOAD_BEHAVIOUR); + cursor.x = stng ? *static_cast(stng->data) : 0; + prev_x = cursor.x; cursor.move(MAX_RELOAD_OPTIONS, MENU_LINE_NUM); if (cursor.y == AREA_RELOAD_BEHAVIOR_INDEX) { - g_reloadType = cursor.x; + if (cursor.x != prev_x) { + if (!stng) { + stng = new GZSettingEntry{STNG_AREA_RELOAD_BEHAVIOUR, sizeof(uint32_t), new uint32_t(cursor.x)}; + g_settings.push_back(stng); + } else { + *static_cast(stng->data) = cursor.x; + } + } } break; case CURSOR_COLOR_INDEX: - cursor.x = g_cursorColorType; + stng = GZStng_get(STNG_CURSOR_COLOR); + cursor.x = stng ? *static_cast(stng->data) : 0; + prev_x = cursor.x; cursor.move(MAX_CURSOR_COLOR_OPTIONS, MENU_LINE_NUM); if (cursor.y == CURSOR_COLOR_INDEX) { - g_cursorColorType = cursor.x; + if (cursor.x != prev_x) { + if (!stng) { + stng = new GZSettingEntry{STNG_CURSOR_COLOR, sizeof(uint32_t), new uint32_t(cursor.x)}; + g_settings.push_back(stng); + } else { + *static_cast(stng->data) = cursor.x; + } + } } break; case FONT_INDEX: { - cursor.x = g_fontType; - uint32_t old_font = g_fontType; + stng = GZStng_get(STNG_FONT); + cursor.x = stng ? *static_cast(stng->data) : 0; + prev_x = cursor.x; + int old_font = cursor.x; cursor.move(FONT_OPTIONS_COUNT, MENU_LINE_NUM); if (cursor.y == FONT_INDEX) { - g_fontType = cursor.x; + if (prev_x != cursor.x) { + if (!stng) { + stng = new GZSettingEntry{STNG_FONT, sizeof(uint32_t), new uint32_t(cursor.x)}; + g_settings.push_back(stng); + } else { + *static_cast(stng->data) = cursor.x; + } + } } - if (old_font != g_fontType) { - if (g_fontType >= 0 && g_fontType < FONT_OPTIONS_COUNT) { + if (old_font != cursor.x) { + uint32_t fontType = stng ? *static_cast(stng->data) : 0; + if (fontType >= 0 && fontType < FONT_OPTIONS_COUNT) { char buf[40]; - snprintf(buf, sizeof(buf), "tpgz/fonts/%s.fnt", g_font_opt[g_fontType].member); + snprintf(buf, sizeof(buf), "tpgz/fonts/%s.fnt", g_font_opt[fontType].member); Font::loadFont(buf); } } @@ -144,9 +189,9 @@ void SettingsMenu::draw() { break; } - lines[AREA_RELOAD_BEHAVIOR_INDEX].printf(" <%s>", reload_opt[g_reloadType].member); - lines[CURSOR_COLOR_INDEX].printf(" <%s>", cursorCol_opt[g_cursorColorType].member); - lines[FONT_INDEX].printf(" <%s>", g_font_opt[g_fontType].member); + lines[AREA_RELOAD_BEHAVIOR_INDEX].printf(" <%s>", reload_opt[GZStng_getData(STNG_AREA_RELOAD_BEHAVIOUR, 0)].member); + lines[CURSOR_COLOR_INDEX].printf(" <%s>", cursorCol_opt[GZStng_getData(STNG_CURSOR_COLOR, 0)].member); + lines[FONT_INDEX].printf(" <%s>", g_font_opt[GZStng_getData(STNG_FONT, 0)].member); GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); } diff --git a/modules/menus/menu_tools/include/tools_menu.h b/modules/menus/menu_tools/include/tools_menu.h index 0fa64bd7..2043c905 100644 --- a/modules/menus/menu_tools/include/tools_menu.h +++ b/modules/menus/menu_tools/include/tools_menu.h @@ -1,14 +1,39 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" #include "tools.h" +#ifdef GCN_PLATFORM +#define FRAME_ADVANCE_TEXT "R + D-Pad Up" +#define FRAME_PAUSE_TEXT "R" +#define GORGE_VOID_TEXT "L+Z" +#define STORE_POSITION_TEXT "D-PAD up + R" +#define LOAD_POSITION_TEXT "D-PAD down + R" +#define RELOAD_AREA_TEXT "L+R+A+Start" +#define TIMER_TOGGLE_TEXT "Z+A" +#define TIMER_RESET_TEXT "Z+B" +#define FREE_CAM_TEXT "Z+B+A" +#define MOVE_LINK_TEXT "L+R+Y" +#endif + +#ifdef WII_PLATFORM +#define FRAME_ADVANCE_TEXT "Z+C+Plus+Minus" +#define FRAME_PAUSE_TEXT "2" +#define GORGE_VOID_TEXT "Z+C+A+1" +#define BACK_IN_TIME_TEXT "Z+C+A+2" +#define STORE_POSITION_TEXT "Z+C+1" +#define LOAD_POSITION_TEXT "Z+C+2" +#define RELOAD_AREA_TEXT "Z+C+B+2" +#define TIMER_TOGGLE_TEXT "Z+C+A+B" +#define TIMER_RESET_TEXT "Z+C+B+1" +#define FREE_CAM_TEXT "Z+C+B+Minus" +#define MOVE_LINK_TEXT "Z+C+B+Plus" +#endif + struct ToolsData { uint8_t l_tunicCol_idx; }; -void GZ_applyCheats(); - class ToolsMenu : public Menu { public: ToolsMenu(Cursor&, ToolsData&); diff --git a/modules/menus/menu_tools/src/tools_menu.cpp b/modules/menus/menu_tools/src/tools_menu.cpp index db973861..51f77ff0 100644 --- a/modules/menus/menu_tools/src/tools_menu.cpp +++ b/modules/menus/menu_tools/src/tools_menu.cpp @@ -2,14 +2,8 @@ #include #include "commands.h" #include "global_data.h" -#include "gorge.h" -#ifdef WII_PLATFORM -#include "bit.h" -#endif -#include "rollcheck.h" #include "timer.h" #include "libtp_c/include/d/com/d_com_inf_game.h" -#include "umd.h" #include "gz_flags.h" #include "rels/include/defines.h" #include "rels/include/defines.h" @@ -20,82 +14,137 @@ #define FREE_CAM_VIEW_TEXT "C-stick" #define MOVE_LINK_MOVEMENT_TEXT "Stick/C" #define MOVE_LINK_ANGLE_TEXT "C-left/right" +#define PREVIOUS_TUNIC_COLOR GZPad::Y +#define PREVIOUS_TUNIC_COLOR_TEXT "Y" +#define NEXT_TUNIC_COLOR GZPad::X +#define NEXT_TUNIC_COLOR_TEXT "X" #endif #ifdef WII_PLATFORM #define FREE_CAM_MOVEMENT_TEXT "Stick+DPad" #define FREE_CAM_VIEW_TEXT "C+Stick" #define MOVE_LINK_MOVEMENT_TEXT "Stick" #define MOVE_LINK_ANGLE_TEXT "C+Stick" +#define PREVIOUS_TUNIC_COLOR GZPad::TWO +#define PREVIOUS_TUNIC_COLOR_TEXT "TWO" +#define NEXT_TUNIC_COLOR GZPad::ONE +#define NEXT_TUNIC_COLOR_TEXT "ONE" #endif -#ifdef GCN_PLATFORM -#endif +#define MAX_TUNIC_COLORS 7 + +const char l_descTemplates[TOOLS_COUNT][100] = { + "use %s to reload current area", + "use %s to pause, %s to frame advance", + "reduces bonk animation significantly", + "link's movement is much faster", + "use %s to warp to kakariko gorge", #ifdef WII_PLATFORM + "use %s to warp to ordon bridge", #endif - -#define MAX_TUNIC_COLORS 7 + "show frame info when doing coro td", + "practice snowpeak universal map delay timing", + "show current inputs", + "show Link's position, angle, and speed", + "show Heap size info", + "link won't sink in sand", + "frame counter for chaining rolls", + "display A/B button mashing speeds", + "%s to set, %s to load", + "simulates turbo controller inputs", + "frame timer: %s to start/stop, %s to reset", + "loading zone timer: %s to reset", + "In-game time timer: %s to start/stop, %s to reset", + FREE_CAM_TEXT " to activate, " FREE_CAM_MOVEMENT_TEXT " to move, " FREE_CAM_VIEW_TEXT + " to view, Z to speed", + MOVE_LINK_TEXT " to activate. " MOVE_LINK_MOVEMENT_TEXT " to move, " MOVE_LINK_ANGLE_TEXT + " to change angle", + "changes link's tunic color. " NEXT_TUNIC_COLOR_TEXT "/" PREVIOUS_TUNIC_COLOR_TEXT + " to cycle through colors", +}; KEEP_FUNC ToolsMenu::ToolsMenu(Cursor& cursor, ToolsData& data) : Menu(cursor), l_tunicCol_idx(data.l_tunicCol_idx), - lines{{"area reload", RELOAD_AREA_INDEX, "Use " RELOAD_AREA_TEXT " to reload current area", - true, &g_tools[RELOAD_AREA_INDEX].active}, - {"frame advance", FRAME_ADVANCE_INDEX, "Use " FRAME_ADVANCE_TEXT " to frame advance", - true, &g_tools[FRAME_ADVANCE_INDEX].active}, - {"fast bonk recovery", FAST_BONK_INDEX, "Reduces bonk animation significantly", true, - &g_tools[FAST_BONK_INDEX].active}, - {"fast movement", FAST_MOVEMENT_INDEX, "Link's movement is much faster", true, - &g_tools[FAST_MOVEMENT_INDEX].active}, - {"gorge checker", GORGE_INDEX, "Use " GORGE_VOID_TEXT " to warp to Kakariko Gorge", - true, &g_tools[GORGE_INDEX].active}, + lines{{"area reload", RELOAD_AREA_INDEX, "use " RELOAD_AREA_TEXT " to reload current area", + true, ACTIVE_FUNC(STNG_TOOLS_RELOAD_AREA)}, + {"frame advance", FRAME_ADVANCE_INDEX, "use " FRAME_ADVANCE_TEXT " to pause, " FRAME_PAUSE_TEXT " to frame advance", + true, ACTIVE_FUNC(STNG_TOOLS_FRAME_ADVANCE)}, + {"fast bonk recovery", FAST_BONK_INDEX, "reduces bonk animation significantly", true, + ACTIVE_FUNC(STNG_TOOLS_FAST_BONK)}, + {"fast movement", FAST_MOVEMENT_INDEX, "link's movement is much faster", true, + ACTIVE_FUNC(STNG_TOOLS_FAST_MOVEMENT)}, + {"gorge checker", GORGE_INDEX, "use " GORGE_VOID_TEXT " to warp to kakariko gorge", + true, ACTIVE_FUNC(STNG_TOOLS_GORGE)}, #ifdef WII_PLATFORM - {"bit checker", BIT_INDEX, "Use " BACK_IN_TIME_TEXT " to warp to Ordon Bridge", true, - &g_tools[BIT_INDEX].active}, + {"bit checker", BIT_INDEX, "use " BACK_IN_TIME_TEXT " to warp to ordon bridge", true, + ACTIVE_FUNC(STNG_TOOLS_BIT)}, #endif - {"coro td checker", COROTD_INDEX, "Show frame info when doing coro td", true, - &g_tools[COROTD_INDEX].active}, - {"umd checker", UMD_INDEX, "Practice Snowpeak UMD timing", true, - &g_tools[UMD_INDEX].active}, - {"input viewer", INPUT_VIEWER_INDEX, "Show current inputs", true, - &g_tools[INPUT_VIEWER_INDEX].active}, - {"link debug info", LINK_DEBUG_INDEX, "Show Link's position, angle, and speed", true, - &g_tools[LINK_DEBUG_INDEX].active}, - {"heap debug info", HEAP_DEBUG_INDEX, "Show Heap size info", true, - &g_tools[HEAP_DEBUG_INDEX].active}, - {"no sinking in sand", SAND_INDEX, "Link won't sink in sand", true, - &g_tools[SAND_INDEX].active}, - {"roll checker", ROLL_INDEX, "Frame counter for chaining rolls", true, - &g_tools[ROLL_INDEX].active}, + {"coro td checker", COROTD_INDEX, "show frame info when doing coro td", true, + ACTIVE_FUNC(STNG_TOOLS_COROTD)}, + {"umd checker", UMD_INDEX, "practice snowpeak universal map delay timing", true, + ACTIVE_FUNC(STNG_TOOLS_UMD)}, + {"input viewer", INPUT_VIEWER_INDEX, "show current inputs", true, + ACTIVE_FUNC(STNG_TOOLS_INPUT_VIEWER)}, + {"link debug info", LINK_DEBUG_INDEX, "show Link's position, angle, and speed", true, + ACTIVE_FUNC(STNG_TOOLS_LINK_DEBUG)}, + {"heap debug info", HEAP_DEBUG_INDEX, "show Heap size info", true, + ACTIVE_FUNC(STNG_TOOLS_HEAP_DEBUG)}, + {"no sinking in sand", SAND_INDEX, "link won't sink in sand", true, + ACTIVE_FUNC(STNG_TOOLS_SAND)}, + {"roll checker", ROLL_INDEX, "frame counter for chaining rolls", true, + ACTIVE_FUNC(STNG_TOOLS_ROLL)}, + {"mash checker", MASH_CHECKER_INDEX, "display A/B button mashing speeds", true, + ACTIVE_FUNC(STNG_TOOLS_MASH_CHECKER)}, {"teleport", TELEPORT_INDEX, STORE_POSITION_TEXT " to set, " LOAD_POSITION_TEXT " to load", true, - &g_tools[TELEPORT_INDEX].active}, - {"turbo mode", TURBO_MODE_INDEX, "Simulates turbo controller inputs", true, - &g_tools[TURBO_MODE_INDEX].active}, + ACTIVE_FUNC(STNG_TOOLS_TELEPORT)}, + {"turbo mode", TURBO_MODE_INDEX, "simulates turbo controller inputs", true, + ACTIVE_FUNC(STNG_TOOLS_TURBO_MODE)}, {"timer", TIMER_INDEX, - "Frame timer: " TIMER_TOGGLE_TEXT " to start/stop, " TIMER_RESET_TEXT " to reset", - true, &g_tools[TIMER_INDEX].active}, - {"load timer", LOAD_TIMER_INDEX, "Loading zone timer: " TIMER_RESET_TEXT " to reset", - true, &g_tools[LOAD_TIMER_INDEX].active}, + "frame timer: " TIMER_TOGGLE_TEXT " to start/stop, " TIMER_RESET_TEXT " to reset", + true, ACTIVE_FUNC(STNG_TOOLS_TIMER)}, + {"load timer", LOAD_TIMER_INDEX, "loading zone timer: " TIMER_RESET_TEXT " to reset", + true, ACTIVE_FUNC(STNG_TOOLS_LOAD_TIMER)}, {"igt timer", IGT_TIMER_INDEX, "In-game time timer: " TIMER_TOGGLE_TEXT " to start/stop, " TIMER_RESET_TEXT " to reset", - true, &g_tools[IGT_TIMER_INDEX].active}, + true, ACTIVE_FUNC(STNG_TOOLS_IGT_TIMER)}, {"free cam", FREE_CAM_INDEX, FREE_CAM_TEXT " to activate, " FREE_CAM_MOVEMENT_TEXT " to move, " FREE_CAM_VIEW_TEXT " to view, Z to speed", - true, &g_tools[FREE_CAM_INDEX].active}, + true, ACTIVE_FUNC(STNG_TOOLS_FREE_CAM)}, {"move link", MOVE_LINK_INDEX, MOVE_LINK_TEXT " to activate. " MOVE_LINK_MOVEMENT_TEXT " to move, " MOVE_LINK_ANGLE_TEXT " to change angle", - true, &g_tools[MOVE_LINK_INDEX].active}, - {"link tunic color:", TUNIC_COLOR_INDEX, "Changes Link's tunic color", false, nullptr, - MAX_TUNIC_COLORS}} { + true, ACTIVE_FUNC(STNG_TOOLS_MOVE_LINK)}, + {"link tunic color:", TUNIC_COLOR_INDEX, + "changes link's tunic color. " NEXT_TUNIC_COLOR_TEXT "/" PREVIOUS_TUNIC_COLOR_TEXT + " to cycle through colors", + false, nullptr, MAX_TUNIC_COLORS}} { } ToolsMenu::~ToolsMenu() {} -void ToolsMenu::draw() { - cursor.setMode(Cursor::MODE_LIST); +GZSettingID l_mapping[] = { + STNG_TOOLS_RELOAD_AREA, STNG_TOOLS_FRAME_ADVANCE, STNG_TOOLS_FAST_BONK, + STNG_TOOLS_FAST_MOVEMENT, STNG_TOOLS_GORGE, +#ifdef WII_PLATFORM + STNG_TOOLS_BIT, +#endif + STNG_TOOLS_COROTD, STNG_TOOLS_UMD, STNG_TOOLS_INPUT_VIEWER, + STNG_TOOLS_LINK_DEBUG, STNG_TOOLS_HEAP_DEBUG, STNG_TOOLS_SAND, + STNG_TOOLS_ROLL, STNG_TOOLS_MASH_CHECKER, STNG_TOOLS_TELEPORT, + STNG_TOOLS_TURBO_MODE, STNG_TOOLS_TIMER, STNG_TOOLS_LOAD_TIMER, + STNG_TOOLS_IGT_TIMER, STNG_TOOLS_FREE_CAM, STNG_TOOLS_MOVE_LINK, +}; + +#define set_active(id, status) \ + ({ \ + auto* stng = GZStng_get(id); \ + if (stng) \ + *(bool*)stng->data = status; \ + }) +void ToolsMenu::draw() { l_tunicCol_idx = g_tunic_color; if (GZ_getButtonTrig(BACK_BUTTON)) { @@ -110,140 +159,140 @@ void ToolsMenu::draw() { cursor.x = l_tunicCol_idx; cursor.move(MAX_TUNIC_COLORS, MENU_LINE_NUM); - if (cursor.y == TUNIC_COLOR_INDEX) { - l_tunicCol_idx = cursor.x; + if (GZ_getButtonRepeat(NEXT_TUNIC_COLOR)) { + l_tunicCol_idx++; + + if (l_tunicCol_idx >= MAX_TUNIC_COLORS) + l_tunicCol_idx = 0; } + + if (GZ_getButtonRepeat(PREVIOUS_TUNIC_COLOR)) { + l_tunicCol_idx--; + + if (l_tunicCol_idx >= MAX_TUNIC_COLORS) + l_tunicCol_idx = MAX_TUNIC_COLORS - 1; + } + g_tunic_color = l_tunicCol_idx; } else { cursor.move(0, MENU_LINE_NUM); } if (GZ_getButtonTrig(SELECTION_BUTTON)) { - g_tools[cursor.y].active = !g_tools[cursor.y].active; - if (g_tools[cursor.y].active) { - switch (cursor.y) { - case FRAME_ADVANCE_INDEX: - GZCmd_enable(Commands::CMD_FRAME_PAUSE); - break; - case TIMER_INDEX: - g_tools[LOAD_TIMER_INDEX].active = false; - g_tools[IGT_TIMER_INDEX].active = false; - GZCmd_enable(Commands::CMD_TIMER_TOGGLE); - GZCmd_enable(Commands::CMD_TIMER_RESET); - break; - case LOAD_TIMER_INDEX: - g_tools[TIMER_INDEX].active = false; - g_tools[IGT_TIMER_INDEX].active = false; - GZCmd_enable(Commands::CMD_TIMER_RESET); - break; - case IGT_TIMER_INDEX: - g_tools[TIMER_INDEX].active = false; - g_tools[LOAD_TIMER_INDEX].active = false; - GZCmd_enable(Commands::CMD_TIMER_TOGGLE); - GZCmd_enable(Commands::CMD_TIMER_RESET); - break; - case GORGE_INDEX: - GZCmd_enable(Commands::CMD_GORGE_VOID); - break; -#ifdef WII_PLATFORM - case BIT_INDEX: - GZCmd_enable(Commands::CMD_BIT); - break; -#endif - case TELEPORT_INDEX: - GZCmd_enable(Commands::CMD_STORE_POSITION); - GZCmd_enable(Commands::CMD_LOAD_POSITION); - break; - case RELOAD_AREA_INDEX: - GZCmd_enable(Commands::CMD_RELOAD_AREA); - break; - case FAST_MOVEMENT_INDEX: - daAlinkHIO_frontRoll.mSpeedRate = 3.0f; - daAlinkHIO_swim.mMaxUnderwaterSpeed = 50; - daAlinkHIO_swim.mMaxBackwardSpeed = 50; - daAlinkHIO_swim.mMaxStrafeSpeed = 50; - daAlinkHIO_swim.mDashMaxSpeed = 50; - daAlinkHIO_swim.mMaxForwardSpeed = 50; - daAlinkHIO_swim.mUnderwaterMaxSinkSpeed = 50; - daAlinkHIO_swim.mBootsMaxSinkSpeed = -50; - daAlinkHIO_swim.mBootsGravity = -50; - daAlinkHIO_wlMove.mDashInitSpeed = 100; - daAlinkHIO_wlMove.mDashMaxSpeed = 100; - daAlinkHIO_wlMove.mDashInitSpeedSlow = 70; - daAlinkHIO_wlMove.mDashMaxSpeedSlow = 70; - daAlinkHIO_wlSwim.mMaxSpeed = 50; - daAlinkHIO_wlSwim.mMaxSpeedWeak = 50; - break; - case FAST_BONK_INDEX: - daAlinkHIO_frontRoll.mCrashAnm.field_0x04 = 50.0f; - daAlinkHIO_frontRoll.mCrashAnm.field_0x08 = 0.0f; - break; - case SAND_INDEX: - if (dComIfGp_getPlayer() != nullptr) { - dComIfGp_getPlayer()->field_0x2ba8 = 0; + GZSettingEntry* stng = nullptr; + if (cursor.y < TOOLS_COUNT && cursor.y != TUNIC_COLOR_INDEX) { + stng = GZStng_get(l_mapping[cursor.y]); + if (!stng) { + stng = new GZSettingEntry{l_mapping[cursor.y], sizeof(bool), new bool}; + g_settings.push_back(stng); + } + } + if (stng) { + *(bool*)stng->data = !*(bool*)stng->data; + if (*(bool*)stng->data) { + switch (cursor.y) { + case TIMER_INDEX: + set_active(STNG_TOOLS_LOAD_TIMER, false); + set_active(STNG_TOOLS_IGT_TIMER, false); + break; + case LOAD_TIMER_INDEX: + set_active(STNG_TOOLS_TIMER, false); + set_active(STNG_TOOLS_IGT_TIMER, false); + break; + case IGT_TIMER_INDEX: + set_active(STNG_TOOLS_TIMER, false); + set_active(STNG_TOOLS_LOAD_TIMER, false); + break; } - break; - case FREE_CAM_INDEX: - GZCmd_enable(Commands::CMD_FREE_CAM); - g_freeCamEnabled = false; - break; - case MOVE_LINK_INDEX: - GZCmd_enable(Commands::CMD_MOVE_LINK); - g_moveLinkEnabled = false; - break; } - } else { - switch (cursor.y) { - case FRAME_ADVANCE_INDEX: - GZCmd_disable(Commands::CMD_FRAME_PAUSE); - break; - case TELEPORT_INDEX: - GZCmd_disable(Commands::CMD_STORE_POSITION); - GZCmd_disable(Commands::CMD_LOAD_POSITION); - break; - case RELOAD_AREA_INDEX: - GZCmd_disable(Commands::CMD_RELOAD_AREA); - break; - case FAST_MOVEMENT_INDEX: - daAlinkHIO_frontRoll.mSpeedRate = 1.3; - daAlinkHIO_swim.mMaxUnderwaterSpeed = 12; - daAlinkHIO_swim.mMaxForwardSpeed = 8; - daAlinkHIO_swim.mMaxBackwardSpeed = 6; - daAlinkHIO_swim.mMaxStrafeSpeed = 8; - daAlinkHIO_swim.mDashMaxSpeed = 13; - daAlinkHIO_swim.mUnderwaterMaxSinkSpeed = 8; - daAlinkHIO_swim.mBootsMaxSinkSpeed = -20; - daAlinkHIO_swim.mBootsGravity = -0.699999988; - daAlinkHIO_wlMove.mDashInitSpeed = 65; - daAlinkHIO_wlMove.mDashMaxSpeed = 45; - daAlinkHIO_wlMove.mDashInitSpeedSlow = 35; - daAlinkHIO_wlMove.mDashMaxSpeedSlow = 33; - daAlinkHIO_wlSwim.mMaxSpeed = 20; - daAlinkHIO_wlSwim.mMaxSpeedWeak = 9; - break; - case FAST_BONK_INDEX: - daAlinkHIO_frontRoll.mCrashAnm.field_0x04 = 3.0f; - daAlinkHIO_frontRoll.mCrashAnm.field_0x08 = 0.800000012f; - break; - case FREE_CAM_INDEX: - GZCmd_disable(Commands::CMD_FREE_CAM); - g_freeCamEnabled = false; - break; - case MOVE_LINK_INDEX: - GZCmd_disable(Commands::CMD_MOVE_LINK); - g_moveLinkEnabled = false; - break; - case GORGE_INDEX: - GZCmd_disable(Commands::CMD_GORGE_VOID); - break; + } + } + + char buf[100]; + switch (cursor.y) { + case RELOAD_AREA_INDEX: { + uint16_t combo = GZStng_getData(STNG_CMD_RELOAD_AREA, RELOAD_AREA_BUTTONS); + char* comboStr = new char[GZCmd_getComboLen(combo) + 1]; + GZCmd_comboToStr(combo, comboStr); + snprintf(buf, sizeof(buf), l_descTemplates[cursor.y], comboStr); + delete[] comboStr; + break; + } + case FRAME_ADVANCE_INDEX: { + uint16_t comboPause = + GZStng_getData(STNG_CMD_FRAME_PAUSE, FRAME_PAUSE_BUTTONS); + char* comboPauseStr = new char[GZCmd_getComboLen(comboPause) + 1]; + GZCmd_comboToStr(comboPause, comboPauseStr); + uint16_t comboAdvance = + GZStng_getData(STNG_CMD_FRAME_ADVANCE, FRAME_ADVANCE_BUTTONS); + char* comboAdvanceStr = new char[GZCmd_getComboLen(comboAdvance) + 1]; + GZCmd_comboToStr(comboAdvance, comboAdvanceStr); + snprintf(buf, sizeof(buf), l_descTemplates[cursor.y], comboPauseStr, comboAdvanceStr); + delete[] comboAdvanceStr; + delete[] comboPauseStr; + break; + } + case GORGE_INDEX: { + uint16_t combo = GZStng_getData(STNG_CMD_GORGE_VOID, GORGE_VOID_BUTTONS); + char* comboStr = new char[GZCmd_getComboLen(combo) + 1]; + GZCmd_comboToStr(combo, comboStr); + snprintf(buf, sizeof(buf), l_descTemplates[cursor.y], comboStr); + delete[] comboStr; + break; + } #ifdef WII_PLATFORM - case BIT_INDEX: - GZCmd_disable(Commands::CMD_BIT); - break; + case BIT_INDEX: { + uint16_t combo = GZStng_getData(STNG_CMD_BIT, BACK_IN_TIME_BUTTONS); + char* comboStr = new char[GZCmd_getComboLen(combo) + 1]; + GZCmd_comboToStr(combo, comboStr); + snprintf(buf, sizeof(buf), l_descTemplates[cursor.y], comboStr); + delete[] comboStr; + break; + } #endif - } - } + case TELEPORT_INDEX: { + uint16_t comboPause = + GZStng_getData(STNG_CMD_STORE_POSITION, STORE_POSITION_BUTTONS); + char* comboPauseStr = new char[GZCmd_getComboLen(comboPause) + 1]; + GZCmd_comboToStr(comboPause, comboPauseStr); + uint16_t comboAdvance = + GZStng_getData(STNG_CMD_LOAD_POSITION, LOAD_POSITION_BUTTONS); + char* comboAdvanceStr = new char[GZCmd_getComboLen(comboAdvance) + 1]; + GZCmd_comboToStr(comboAdvance, comboAdvanceStr); + snprintf(buf, sizeof(buf), l_descTemplates[cursor.y], comboPauseStr, comboAdvanceStr); + delete[] comboAdvanceStr; + delete[] comboPauseStr; + break; + } + case IGT_TIMER_INDEX: // fallthrough + case TIMER_INDEX: { + uint16_t comboPause = + GZStng_getData(STNG_CMD_TIMER_TOGGLE, TIMER_TOGGLE_BUTTONS); + char* comboPauseStr = new char[GZCmd_getComboLen(comboPause) + 1]; + GZCmd_comboToStr(comboPause, comboPauseStr); + uint16_t comboAdvance = + GZStng_getData(STNG_CMD_TIMER_RESET, TIMER_RESET_BUTTONS); + char* comboAdvanceStr = new char[GZCmd_getComboLen(comboAdvance) + 1]; + GZCmd_comboToStr(comboAdvance, comboAdvanceStr); + snprintf(buf, sizeof(buf), l_descTemplates[cursor.y], comboPauseStr, comboAdvanceStr); + delete[] comboAdvanceStr; + delete[] comboPauseStr; + break; + } + case LOAD_TIMER_INDEX: { + uint16_t combo = GZStng_getData(STNG_CMD_TIMER_RESET, TIMER_RESET_BUTTONS); + char* comboStr = new char[GZCmd_getComboLen(combo) + 1]; + GZCmd_comboToStr(combo, comboStr); + snprintf(buf, sizeof(buf), l_descTemplates[cursor.y], comboStr); + delete[] comboStr; + break; + } + default: { + snprintf(buf, sizeof(buf), l_descTemplates[cursor.y]); + break; + } } + strncpy(lines[cursor.y].description, buf, sizeof(lines[cursor.y].description)); lines[TUNIC_COLOR_INDEX].printf(" <%s>", tunicCol_opt[l_tunicCol_idx].member); GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); diff --git a/modules/menus/menu_trigger_view/CMakeLists.txt b/modules/menus/menu_trigger_view/CMakeLists.txt new file mode 100644 index 00000000..24e35f3c --- /dev/null +++ b/modules/menus/menu_trigger_view/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB_RECURSE srcs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE asms CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.s") +list(APPEND srcs ${asms}) +get_filename_component(rel_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) +tpgz_add_module(${rel_name} "${srcs}" "${CMAKE_CURRENT_SOURCE_DIR}/include") \ No newline at end of file diff --git a/modules/menus/menu_trigger_view/include/main.h b/modules/menus/menu_trigger_view/include/main.h new file mode 100644 index 00000000..1935f7ae --- /dev/null +++ b/modules/menus/menu_trigger_view/include/main.h @@ -0,0 +1,6 @@ +#pragma once + +namespace tpgz::modules { +void main(); +void exit(); +} // namespace tpgz::modules \ No newline at end of file diff --git a/modules/menus/menu_trigger_view/include/trigger_view_menu.h b/modules/menus/menu_trigger_view/include/trigger_view_menu.h new file mode 100644 index 00000000..6d553194 --- /dev/null +++ b/modules/menus/menu_trigger_view/include/trigger_view_menu.h @@ -0,0 +1,14 @@ +#pragma once + +#include "menus/menu.h" +#include "trigger_view.h" + +class TriggerViewMenu : public Menu { +public: + TriggerViewMenu(Cursor&); + virtual ~TriggerViewMenu(); + virtual void draw(); + +private: + Line lines[TRIGGER_VIEW_MAX + 1]; +}; diff --git a/modules/menus/menu_trigger_view/src/main.cpp b/modules/menus/menu_trigger_view/src/main.cpp new file mode 100644 index 00000000..2d4e9352 --- /dev/null +++ b/modules/menus/menu_trigger_view/src/main.cpp @@ -0,0 +1,50 @@ +#include +#include "menus/menu_trigger_view/include/trigger_view_menu.h" +#include "events/draw_listener.h" +#include "menus/utils/menu_mgr.h" +#include "utils/draw.h" + +void onCreate(); +void onLoad(); +void onDraw(); +void onUnload(); +void onDelete(); + +TriggerViewMenu* l_menu; + +namespace tpgz::modules { +void main() { + g_menuMgr->setCreateHook(onCreate); + g_menuMgr->setLoadHook(onLoad); + g_menuMgr->setUnloadHook(onUnload); + g_menuMgr->setDeleteHook(onDelete); +} +void exit() { + g_menuMgr->setCreateHook(nullptr); + g_menuMgr->setLoadHook(nullptr); + g_menuMgr->setUnloadHook(nullptr); + g_menuMgr->setDeleteHook(nullptr); +} +} // namespace tpgz::modules + +void onCreate() { + if (!g_menuMgr->getPermanentData()) { + g_menuMgr->setPermanentData(new Cursor); + } +} + +void onLoad() { + l_menu = new TriggerViewMenu(*g_menuMgr->getPermanentData()); + g_drawListener->addListener(onDraw); +} + +void onDraw() { + l_menu->draw(); +} + +void onUnload() { + g_drawListener->removeListener(onDraw); + delete l_menu; +} + +void onDelete() {} diff --git a/modules/menus/menu_trigger_view/src/trigger_view_menu.cpp b/modules/menus/menu_trigger_view/src/trigger_view_menu.cpp new file mode 100644 index 00000000..f9a36d51 --- /dev/null +++ b/modules/menus/menu_trigger_view/src/trigger_view_menu.cpp @@ -0,0 +1,61 @@ +#include +#include "collision_view.h" +#include "trigger_view.h" +#include "menus/menu_trigger_view/include/trigger_view_menu.h" +#include "settings.h" +#include "libtp_c/include/d/com/d_com_inf_game.h" +#include "libtp_c/include/f_op/f_op_actor_mng.h" +#include "gz_flags.h" +#include "rels/include/defines.h" +#include "menus/utils/menu_mgr.h" + +KEEP_FUNC TriggerViewMenu::TriggerViewMenu(Cursor& cursor) + : Menu(cursor), lines{ + {"attention distances", VIEW_ATTN_DISTS, "view actor attention ranges", true, + [](){return g_triggerViewFlags[VIEW_ATTN_DISTS].active;}}, + {"event areas", VIEW_EVENT_AREAS, "view event triggers", true, + [](){return g_triggerViewFlags[VIEW_EVENT_AREAS].active;}}, + {"load zones", VIEW_LOAD_ZONES, "view load triggers", true, + [](){return g_triggerViewFlags[VIEW_LOAD_ZONES].active;}}, + {"midna stops", VIEW_MIDNA_STOPS, "view midna talk triggers", true, + [](){return g_triggerViewFlags[VIEW_MIDNA_STOPS].active;}}, + {"paths", VIEW_PATHS, "view all stage/room paths", true, + [](){return g_triggerViewFlags[VIEW_PATHS].active;}}, + {"purple mist avoid", VIEW_MIST_AVOID, "view purple mist safe area", true, + [](){return g_triggerViewFlags[VIEW_MIST_AVOID].active;}}, + {"restart changes", VIEW_CHG_RESTARTS, "view spawn location update triggers", true, + [](){return g_triggerViewFlags[VIEW_CHG_RESTARTS].active;}}, + {"switch areas", VIEW_SWITCH_AREAS, "view switch activation triggers", true, + [](){return g_triggerViewFlags[VIEW_SWITCH_AREAS].active;}}, + {"transform distances", VIEW_TRANSFORM_DISTS, "view actor transform blocking distances", true, + [](){return g_triggerViewFlags[VIEW_TRANSFORM_DISTS].active;}}, + {"twilight gates", VIEW_TW_GATES, "view twilight gate triggers", true, + [](){return g_triggerViewFlags[VIEW_TW_GATES].active;}}, + {"opacity:", TRIGGER_VIEW_MAX, "the opacity of drawn geometry"}, + } {} + +TriggerViewMenu::~TriggerViewMenu() {} + +void TriggerViewMenu::draw() { + cursor.setMode(Cursor::MODE_LIST); + + if (GZ_getButtonTrig(BACK_BUTTON)) { + g_menuMgr->pop(); + return; + } + + if (GZ_getButtonTrig(SELECTION_BUTTON)) { + g_triggerViewFlags[cursor.y].active = !g_triggerViewFlags[cursor.y].active; + } + + switch (cursor.y) { + case TRIGGER_VIEW_MAX: + Cursor::moveList(g_geometryOpacity); + break; + } + + lines[TRIGGER_VIEW_MAX].printf(" <%d>", g_geometryOpacity); + + cursor.move(0, MENU_LINE_NUM); + GZ_drawMenuLines(lines, cursor.y, MENU_LINE_NUM); +} diff --git a/modules/menus/menu_warp/include/warping_menu.h b/modules/menus/menu_warp/include/warping_menu.h index bc8f6171..80684f16 100644 --- a/modules/menus/menu_warp/include/warping_menu.h +++ b/modules/menus/menu_warp/include/warping_menu.h @@ -1,4 +1,4 @@ -#include "menu.h" +#include "menus/menu.h" enum WarpingIndex { WARP_TYPE_INDEX, diff --git a/modules/menus/menu_warp/src/warping_menu.cpp b/modules/menus/menu_warp/src/warping_menu.cpp index 832636a2..9816bedd 100644 --- a/modules/menus/menu_warp/src/warping_menu.cpp +++ b/modules/menus/menu_warp/src/warping_menu.cpp @@ -31,9 +31,9 @@ KEEP_FUNC WarpingMenu::WarpingMenu(WarpingData& data) WarpingMenu::~WarpingMenu() {} -enum { DUNGEON, OVERWORLD, INTERIOR, CAVE, SPECIAL }; +enum { CAVE, DUNGEON, INTERIOR, OVERWORLD, SPECIAL }; -char stage_types[5][10] = {"dungeon", "overworld", "interior", "cave", "special"}; +char stage_types[5][10] = {"cave", "dungeon", "interior", "overworld", "special"}; void WarpingMenu::loadPrevInfo(void* buffer, signed long& counter, signed long length, char max_num, int offset) { @@ -53,17 +53,17 @@ void WarpingMenu::loadNextInfo(void* buffer, signed long& counter, signed long l void WarpingMenu::setStagePath(int current_stage_type) { switch (current_stage_type) { + case CAVE: + strcpy(l_filePath, "tpgz/stage_info/cave.bin"); + break; case DUNGEON: strcpy(l_filePath, "tpgz/stage_info/dungeon.bin"); break; - case OVERWORLD: - strcpy(l_filePath, "tpgz/stage_info/overworld.bin"); - break; case INTERIOR: strcpy(l_filePath, "tpgz/stage_info/interior.bin"); break; - case CAVE: - strcpy(l_filePath, "tpgz/stage_info/cave.bin"); + case OVERWORLD: + strcpy(l_filePath, "tpgz/stage_info/overworld.bin"); break; case SPECIAL: strcpy(l_filePath, "tpgz/stage_info/special.bin"); @@ -102,7 +102,7 @@ void WarpingMenu::loadNextRoomInfo() { } void WarpingMenu::loadNextSpawnInfo() { - snprintf(l_filePath, sizeof(l_filePath), "tpgz/stage_info/%s/%02d/spawns.bin", + snprintf(l_filePath, sizeof(l_filePath), "tpgz/stage_info/%s/%02d/sp.bin", l_warpInfo.stage_info.stage_id, (int)l_warpInfo.room_info.room_id[0]); l_spawnIdx += SPAWN_OFFSET; WarpingMenu::loadNextInfo(&l_warpInfo.spawn_info, l_spawnIdx, SPAWN_READ_LENGTH, @@ -110,7 +110,7 @@ void WarpingMenu::loadNextSpawnInfo() { } void WarpingMenu::loadPrevSpawnInfo() { - snprintf(l_filePath, sizeof(l_filePath), "tpgz/stage_info/%s/%02d/spawns.bin", + snprintf(l_filePath, sizeof(l_filePath), "tpgz/stage_info/%s/%02d/sp.bin", l_warpInfo.stage_info.stage_id, (int)l_warpInfo.room_info.room_id[0]); l_spawnIdx -= SPAWN_OFFSET; WarpingMenu::loadPrevInfo(&l_warpInfo.spawn_info, l_spawnIdx, SPAWN_READ_LENGTH, diff --git a/modules/menus/menu_watches/include/watches_menu.h b/modules/menus/menu_watches/include/watches_menu.h index 302ac370..372fe0e4 100644 --- a/modules/menus/menu_watches/include/watches_menu.h +++ b/modules/menus/menu_watches/include/watches_menu.h @@ -1,5 +1,8 @@ #pragma once -#include "menu.h" +#include "menus/menu.h" +#include "utils/memory.h" + +#define MAX_WATCHES 50 struct WatchesData { uint8_t button_held_counter = 0; @@ -13,7 +16,7 @@ class WatchesMenu : public Menu { WatchesMenu(Cursor&, WatchesData&); virtual ~WatchesMenu(); virtual void draw(); - void drawMemoryLines(); + void drawMemoryLines(MemoryWatch*, size_t); private: uint8_t& button_held_counter; diff --git a/modules/menus/menu_watches/src/watches_menu.cpp b/modules/menus/menu_watches/src/watches_menu.cpp index 9c5a3052..f962f9db 100644 --- a/modules/menus/menu_watches/src/watches_menu.cpp +++ b/modules/menus/menu_watches/src/watches_menu.cpp @@ -1,7 +1,8 @@ #include "menus/menu_watches/include/watches_menu.h" #include -#include "watches.h" +#include "settings.h" #include "utils/lines.h" +#include "utils/memory.h" #include "memory_editor.h" #include "gz_flags.h" #include "rels/include/defines.h" @@ -15,10 +16,24 @@ #ifdef GCN_PLATFORM #define MEMORY_BUTTON (GZPad::Y) #define MEMORY_TEXT "Y" +#define ADD_WATCH_BUTTON (GZPad::R) +#define ADD_WATCH_TEXT "R" +#define REMOVE_WATCH_BUTTON (GZPad::L) +#define REMOVE_WATCH_TEXT "L" #endif #ifdef WII_PLATFORM #define MEMORY_BUTTON (GZPad::ONE) #define MEMORY_TEXT "1" +#define ADD_WATCH_BUTTON (GZPad::PLUS) +#define ADD_WATCH_TEXT "(+)" +#define REMOVE_WATCH_BUTTON (GZPad::MINUS) +#define REMOVE_WATCH_TEXT "(-)" +#endif + +#ifdef WII_PLATFORM +extern bool isWidescreen; +#else +#define isWidescreen (false) #endif WatchesMenu::WatchesMenu(Cursor& cursor, WatchesData& data) @@ -27,10 +42,14 @@ WatchesMenu::WatchesMenu(Cursor& cursor, WatchesData& data) WatchesMenu::~WatchesMenu() {} -void WatchesMenu::drawMemoryLines() { +void WatchesMenu::drawMemoryLines(MemoryWatch* watches, size_t n_watches) { + static size_t l_firstLine = 0; + + const float scale = isWidescreen ? 0.75f : 1.0f; + const float watch_x_pos_x_offset = - WATCH_ADDRESS_X_OFFSET + maxF(GZ_getTextWidth("Address"), GZ_getTextWidth("0x80000000")) + - 5.0f; + WATCH_ADDRESS_X_OFFSET * scale + + maxF(GZ_getTextWidth("Address"), GZ_getTextWidth("0x80000000")) + 5.0f * scale; const float watch_y_pos_x_offset = watch_x_pos_x_offset + maxF(GZ_getTextWidth("X"), GZ_getTextWidth("<000>")) + 5.0f; const float watch_hex_x_offset = @@ -42,7 +61,8 @@ void WatchesMenu::drawMemoryLines() { const float watch_visible_x_offset = watch_offset_x_offset + maxF(GZ_getTextWidth("Offset"), GZ_getTextWidth("0x0000")) + 5.0f; - GZ_drawText("Address", WATCH_ADDRESS_X_OFFSET, 60.0f, WHITE_RGBA, GZ_checkDropShadows()); + GZ_drawText("Address", WATCH_ADDRESS_X_OFFSET * scale, 60.0f, WHITE_RGBA, + GZ_checkDropShadows()); GZ_drawText("X", watch_x_pos_x_offset, 60.0f, WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText("Y", watch_y_pos_x_offset, 60.0f, WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText("Hex", watch_hex_x_offset, 60.0f, WHITE_RGBA, GZ_checkDropShadows()); @@ -50,8 +70,27 @@ void WatchesMenu::drawMemoryLines() { GZ_drawText("Offset", watch_offset_x_offset, 60.0f, WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText("Visible", watch_visible_x_offset, 60.0f, WHITE_RGBA, GZ_checkDropShadows()); - for (int i = 0; i < MAX_WATCHES; i++) { - const float line_y_offset = (80.0f + (i * 20.0f)); + if (cursor.y < (int)l_firstLine) { + l_firstLine = cursor.y; + } + if (cursor.y > (int)l_firstLine + MAX_RENDER_LINES - 1) { + l_firstLine = cursor.y - MAX_RENDER_LINES + 1; + } + + if (l_firstLine > 0) { + Font::GZ_drawStr("^", WATCH_ADDRESS_X_OFFSET * scale, 80.0f - 8.0f, 0xFFFFFFFF, + GZ_checkDropShadows()); + } + + if (l_firstLine + MAX_RENDER_LINES - 1 < n_watches - 1) { + Font::GZ_drawStr("v", WATCH_ADDRESS_X_OFFSET * scale, + 80.0f + 20.0f * MAX_RENDER_LINES - 10.f, 0xFFFFFFFF, + GZ_checkDropShadows()); + } + + for (int i = MAX(0, l_firstLine); i < (int)MIN(l_firstLine + MAX_RENDER_LINES, n_watches); + i++) { + const float line_y_offset = (80.0f + ((i - l_firstLine) * 20.0f)); char watch_address[11]; char watch_x[8]; char watch_y[8]; @@ -60,12 +99,12 @@ void WatchesMenu::drawMemoryLines() { char watch_offset[7]; char watch_visible[4]; - snprintf(watch_address, sizeof(watch_address), "0x%08X", g_watches[i].address); - snprintf(watch_x, sizeof(watch_x), "%.0f", g_watches[i].x); - snprintf(watch_y, sizeof(watch_y), "%.0f", g_watches[i].y); - snprintf(watch_hex, sizeof(watch_hex), "%s", g_watches[i].hex ? "true" : "false"); + snprintf(watch_address, sizeof(watch_address), "0x%08X", watches[i].address); + snprintf(watch_x, sizeof(watch_x), "%.0f", watches[i].x); + snprintf(watch_y, sizeof(watch_y), "%.0f", watches[i].y); + snprintf(watch_hex, sizeof(watch_hex), "%s", watches[i].hex ? "true" : "false"); - switch (g_watches[i].type) { + switch (watches[i].type) { case MEM_TYPE_U8: snprintf(watch_type, sizeof(watch_type), "u8"); break; @@ -91,13 +130,13 @@ void WatchesMenu::drawMemoryLines() { snprintf(watch_type, sizeof(watch_type), "str"); break; } - snprintf(watch_offset, sizeof(watch_offset), "0x%04X", g_watches[i].offset); - snprintf(watch_visible, sizeof(watch_visible), "%s", g_watches[i].visible ? "[X]" : "[ ]"); + snprintf(watch_offset, sizeof(watch_offset), "0x%04X", watches[i].offset); + snprintf(watch_visible, sizeof(watch_visible), "%s", watches[i].visible ? "[X]" : "[ ]"); - if (g_watches[i].line_selected) { + if (watches[i].line_selected) { switch (cursor.x) { case WatchAddress: - if (g_watches[i].value_selected) { + if (watches[i].value_selected) { if (GZ_getButtonRepeat(GZPad::DPAD_RIGHT)) { if (l_addrIdx == 9) { l_addrIdx = 3; @@ -113,29 +152,29 @@ void WatchesMenu::drawMemoryLines() { } } if (GZ_getButtonRepeat(GZPad::DPAD_UP)) { - if (l_addrIdx == 3 && g_watches[i].address >= 0x81000000) { - g_watches[i].address = 0x817FFFFF; + if (l_addrIdx == 3 && watches[i].address >= 0x81000000) { + watches[i].address = 0x817FFFFF; } else if (l_addrIdx <= 9 && l_addrIdx >= 3) { - g_watches[i].address += 1 << ((9 - l_addrIdx) * 4); + watches[i].address += 1 << ((9 - l_addrIdx) * 4); } - if (g_watches[i].address > 0x817FFFFF) { - g_watches[i].address = 0x817FFFFF; + if (watches[i].address > 0x817FFFFF) { + watches[i].address = 0x817FFFFF; } } if (GZ_getButtonRepeat(GZPad::DPAD_DOWN)) { if (l_addrIdx <= 9 && l_addrIdx >= 3) { - g_watches[i].address -= 1 << ((9 - l_addrIdx) * 4); + watches[i].address -= 1 << ((9 - l_addrIdx) * 4); } - if (g_watches[i].address < 0x80000000) { - g_watches[i].address = 0x80000000; + if (watches[i].address < 0x80000000) { + watches[i].address = 0x80000000; } } - GZ_drawSelectChar(watch_address, WATCH_ADDRESS_X_OFFSET, line_y_offset, + GZ_drawSelectChar(watch_address, WATCH_ADDRESS_X_OFFSET * scale, line_y_offset, l_addrIdx, 9, WHITE_RGBA); } else { - GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET, line_y_offset, CURSOR_RGBA, - GZ_checkDropShadows()); + GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET * scale, line_y_offset, + CURSOR_RGBA, GZ_checkDropShadows()); } GZ_drawText(watch_x, watch_x_pos_x_offset, line_y_offset, WHITE_RGBA, GZ_checkDropShadows()); @@ -151,32 +190,32 @@ void WatchesMenu::drawMemoryLines() { GZ_checkDropShadows()); break; case WatchX: - if (g_watches[i].value_selected) { + if (watches[i].value_selected) { if (GZ_getButtonRepeat(GZPad::DPAD_RIGHT)) { - if (g_watches[i].x >= 0.0f && g_watches[i].x < 600.0f) { - g_watches[i].x += l_scrollSpeed; + if (watches[i].x >= 0.0f && watches[i].x < 600.0f) { + watches[i].x += l_scrollSpeed * scale; } } if (GZ_getButtonRepeat(GZPad::DPAD_LEFT)) { - if (g_watches[i].x > 0.0f && g_watches[i].x <= 600.0f) { - g_watches[i].x -= l_scrollSpeed; + if (watches[i].x > 0.0f && watches[i].x <= 600.0f) { + watches[i].x -= l_scrollSpeed * scale; } } - if (g_watches[i].x < 0) { - g_watches[i].x = 0; + if (watches[i].x < 0) { + watches[i].x = 0; } - if (g_watches[i].x > 600) { - g_watches[i].x = 600; + if (watches[i].x > 600) { + watches[i].x = 600; } - snprintf(watch_x, sizeof(watch_x), "<%.0f>", g_watches[i].x); - GZ_drawText(watch_x, watch_x_pos_x_offset - 8.0f, line_y_offset, CURSOR_RGBA, - GZ_checkDropShadows()); + snprintf(watch_x, sizeof(watch_x), "<%.0f>", watches[i].x); + GZ_drawText(watch_x, watch_x_pos_x_offset - 8.0f * scale, line_y_offset, + CURSOR_RGBA, GZ_checkDropShadows()); } else { GZ_drawText(watch_x, watch_x_pos_x_offset, line_y_offset, CURSOR_RGBA, GZ_checkDropShadows()); } - GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET, line_y_offset, WHITE_RGBA, - GZ_checkDropShadows()); + GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET * scale, line_y_offset, + WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText(watch_y, watch_y_pos_x_offset, line_y_offset, WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText(watch_hex, watch_hex_x_offset, line_y_offset, WHITE_RGBA, @@ -189,32 +228,32 @@ void WatchesMenu::drawMemoryLines() { GZ_checkDropShadows()); break; case WatchY: - if (g_watches[i].value_selected) { + if (watches[i].value_selected) { if (GZ_getButtonRepeat(GZPad::DPAD_RIGHT)) { - if (g_watches[i].y >= 0.0f && g_watches[i].y < 500.0f) { - g_watches[i].y += l_scrollSpeed; + if (watches[i].y >= 0.0f && watches[i].y < 500.0f) { + watches[i].y += l_scrollSpeed; } } if (GZ_getButtonRepeat(GZPad::DPAD_LEFT)) { - if (g_watches[i].y > 0.0f && g_watches[i].y <= 500.0f) { - g_watches[i].y -= l_scrollSpeed; + if (watches[i].y > 0.0f && watches[i].y <= 500.0f) { + watches[i].y -= l_scrollSpeed; } } - if (g_watches[i].y < 0) { - g_watches[i].y = 0; + if (watches[i].y < 0) { + watches[i].y = 0; } - if (g_watches[i].y > 500) { - g_watches[i].y = 500; + if (watches[i].y > 500) { + watches[i].y = 500; } - snprintf(watch_y, sizeof(watch_y), "<%.0f>", g_watches[i].y); - GZ_drawText(watch_y, watch_y_pos_x_offset - 8.0f, line_y_offset, CURSOR_RGBA, - GZ_checkDropShadows()); + snprintf(watch_y, sizeof(watch_y), "<%.0f>", watches[i].y); + GZ_drawText(watch_y, watch_y_pos_x_offset - 8.0f * scale, line_y_offset, + CURSOR_RGBA, GZ_checkDropShadows()); } else { GZ_drawText(watch_y, watch_y_pos_x_offset, line_y_offset, CURSOR_RGBA, GZ_checkDropShadows()); } - GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET, line_y_offset, WHITE_RGBA, - GZ_checkDropShadows()); + GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET * scale, line_y_offset, + WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText(watch_x, watch_x_pos_x_offset, line_y_offset, WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText(watch_hex, watch_hex_x_offset, line_y_offset, WHITE_RGBA, @@ -228,23 +267,23 @@ void WatchesMenu::drawMemoryLines() { break; case WatchHex: - if (g_watches[i].value_selected) { + if (watches[i].value_selected) { if (GZ_getButtonRepeat(GZPad::DPAD_RIGHT)) { - g_watches[i].hex = !g_watches[i].hex; + watches[i].hex = !watches[i].hex; } if (GZ_getButtonRepeat(GZPad::DPAD_LEFT)) { - g_watches[i].hex = !g_watches[i].hex; + watches[i].hex = !watches[i].hex; } snprintf(watch_hex, sizeof(watch_hex), "<%s>", - g_watches[i].hex ? "true" : "false"); - GZ_drawText(watch_hex, watch_hex_x_offset - 8.0f, line_y_offset, CURSOR_RGBA, - GZ_checkDropShadows()); + watches[i].hex ? "true" : "false"); + GZ_drawText(watch_hex, watch_hex_x_offset - 8.0f * scale, line_y_offset, + CURSOR_RGBA, GZ_checkDropShadows()); } else { GZ_drawText(watch_hex, watch_hex_x_offset, line_y_offset, CURSOR_RGBA, GZ_checkDropShadows()); } - GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET, line_y_offset, WHITE_RGBA, - GZ_checkDropShadows()); + GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET * scale, line_y_offset, + WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText(watch_x, watch_x_pos_x_offset, line_y_offset, WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText(watch_y, watch_y_pos_x_offset, line_y_offset, WHITE_RGBA, @@ -257,22 +296,24 @@ void WatchesMenu::drawMemoryLines() { GZ_checkDropShadows()); break; case WatchType: - if (g_watches[i].value_selected) { + if (watches[i].value_selected) { if (GZ_getButtonRepeat(GZPad::DPAD_RIGHT)) { - if (g_watches[i].type == MEM_TYPE_STR) { - g_watches[i].type = MEM_TYPE_U8; - } else if (g_watches[i].type >= MEM_TYPE_U8 && g_watches[i].type < MEM_TYPE_STR) { - g_watches[i].type++; + if (watches[i].type == MEM_TYPE_STR) { + watches[i].type = MEM_TYPE_U8; + } else if (watches[i].type >= MEM_TYPE_U8 && + watches[i].type < MEM_TYPE_STR) { + watches[i].type++; } } if (GZ_getButtonRepeat(GZPad::DPAD_LEFT)) { - if (g_watches[i].type == MEM_TYPE_U8) { - g_watches[i].type = MEM_TYPE_STR; - } else if (g_watches[i].type > MEM_TYPE_U8 && g_watches[i].type <= MEM_TYPE_STR) { - g_watches[i].type--; + if (watches[i].type == MEM_TYPE_U8) { + watches[i].type = MEM_TYPE_STR; + } else if (watches[i].type > MEM_TYPE_U8 && + watches[i].type <= MEM_TYPE_STR) { + watches[i].type--; } } - switch (g_watches[i].type) { + switch (watches[i].type) { case MEM_TYPE_U8: snprintf(watch_type, sizeof(watch_type), ""); break; @@ -297,14 +338,14 @@ void WatchesMenu::drawMemoryLines() { case MEM_TYPE_STR: snprintf(watch_type, sizeof(watch_type), ""); } - GZ_drawText(watch_type, watch_type_x_offset - 8.0f, line_y_offset, CURSOR_RGBA, - GZ_checkDropShadows()); + GZ_drawText(watch_type, watch_type_x_offset - 8.0f * scale, line_y_offset, + CURSOR_RGBA, GZ_checkDropShadows()); } else { GZ_drawText(watch_type, watch_type_x_offset, line_y_offset, CURSOR_RGBA, GZ_checkDropShadows()); } - GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET, line_y_offset, WHITE_RGBA, - GZ_checkDropShadows()); + GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET * scale, line_y_offset, + WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText(watch_x, watch_x_pos_x_offset, line_y_offset, WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText(watch_y, watch_y_pos_x_offset, line_y_offset, WHITE_RGBA, @@ -317,7 +358,7 @@ void WatchesMenu::drawMemoryLines() { GZ_checkDropShadows()); break; case WatchOffset: - if (g_watches[i].value_selected) { + if (watches[i].value_selected) { if (GZ_getButtonRepeat(GZPad::DPAD_RIGHT)) { if (l_offsetIdx == 5) { l_offsetIdx = 2; @@ -333,15 +374,15 @@ void WatchesMenu::drawMemoryLines() { } } if (GZ_getButtonRepeat(GZPad::DPAD_UP)) { - g_watches[i].offset += (0x100000 >> (l_offsetIdx * 4)); - if (g_watches[i].offset > 0xFFFF) { - g_watches[i].offset = 0xFFFF; + watches[i].offset += (0x100000 >> (l_offsetIdx * 4)); + if (watches[i].offset > 0xFFFF) { + watches[i].offset = 0xFFFF; } } if (GZ_getButtonRepeat(GZPad::DPAD_DOWN)) { - g_watches[i].offset -= (0x100000 >> (l_offsetIdx * 4)); - if (g_watches[i].offset < 0x0000) { - g_watches[i].offset = 0x0000; + watches[i].offset -= (0x100000 >> (l_offsetIdx * 4)); + if (watches[i].offset < 0x0000) { + watches[i].offset = 0x0000; } } GZ_drawSelectChar(watch_offset, watch_offset_x_offset, line_y_offset, @@ -350,8 +391,8 @@ void WatchesMenu::drawMemoryLines() { GZ_drawText(watch_offset, watch_offset_x_offset, line_y_offset, CURSOR_RGBA, GZ_checkDropShadows()); } - GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET, line_y_offset, WHITE_RGBA, - GZ_checkDropShadows()); + GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET * scale, line_y_offset, + WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText(watch_x, watch_x_pos_x_offset, line_y_offset, WHITE_RGBA, GZ_checkDropShadows()); GZ_drawText(watch_y, watch_y_pos_x_offset, line_y_offset, WHITE_RGBA, @@ -366,7 +407,7 @@ void WatchesMenu::drawMemoryLines() { } } else { int y = cursor.y; - GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET, line_y_offset, + GZ_drawText(watch_address, WATCH_ADDRESS_X_OFFSET * scale, line_y_offset, (y == i ? CURSOR_RGBA : WHITE_RGBA), GZ_checkDropShadows()); GZ_drawText(watch_x, watch_x_pos_x_offset, line_y_offset, (y == i ? CURSOR_RGBA : WHITE_RGBA), GZ_checkDropShadows()); @@ -384,20 +425,20 @@ void WatchesMenu::drawMemoryLines() { } } -bool checkMemLineSelected() { +bool checkMemLineSelected(MemoryWatch* watches, size_t n_watches) { bool return_value = false; - for (int i = 0; i < MAX_WATCHES; i++) { - if (g_watches[i].line_selected) { + for (int i = 0; i < (int)n_watches; i++) { + if (watches[i].line_selected) { return_value = true; } } return return_value; } -bool checkLineValSelected() { +bool checkLineValSelected(MemoryWatch* watches, size_t n_watches) { bool return_value = false; - for (int i = 0; i < MAX_WATCHES; i++) { - if (g_watches[i].value_selected) { + for (int i = 0; i < (int)n_watches; i++) { + if (watches[i].value_selected) { return_value = true; } } @@ -408,18 +449,29 @@ bool checkLineValSelected() { void WatchesMenu::draw() { cursor.setMode(Cursor::MODE_UNRESTRICTED); + const float scale = isWidescreen ? 0.75f : 1.0f; + + auto* stng = GZStng_get(STNG_WATCHES); + if (!stng) { + stng = new GZSettingEntry{STNG_WATCHES, 0, nullptr}; + g_settings.push_back(stng); + } + + MemoryWatch* watches = static_cast(stng->data); + size_t n_watches = stng->size / sizeof(MemoryWatch); + if (GZ_getButtonTrig(BACK_BUTTON)) { - if (checkLineValSelected()) { - for (int i = 0; i < MAX_WATCHES; i++) { - g_watches[i].value_selected = false; + if (checkLineValSelected(watches, n_watches)) { + for (int i = 0; i < (int)n_watches; i++) { + watches[i].value_selected = false; } - g_watches[cursor.y].value_selected = false; + watches[cursor.y].value_selected = false; cursor.lock_x = false; - } else if (checkMemLineSelected()) { - for (int i = 0; i < MAX_WATCHES; i++) { - g_watches[i].line_selected = false; + } else if (checkMemLineSelected(watches, n_watches)) { + for (int i = 0; i < (int)n_watches; i++) { + watches[i].line_selected = false; } - g_watches[cursor.y].line_selected = false; + watches[cursor.y].line_selected = false; cursor.lock_y = false; } else { g_menuMgr->pop(); @@ -427,33 +479,77 @@ void WatchesMenu::draw() { } } - if (GZ_getButtonTrig(SELECTION_BUTTON)) { - if (g_watches[cursor.y].value_selected) { - g_watches[cursor.y].value_selected = false; + if (GZ_getButtonTrig(SELECTION_BUTTON) && watches) { + if (watches[cursor.y].value_selected) { + watches[cursor.y].value_selected = false; cursor.lock_x = false; - } else if (g_watches[cursor.y].line_selected) { - g_watches[cursor.y].value_selected = true; + } else if (watches[cursor.y].line_selected) { + watches[cursor.y].value_selected = true; cursor.lock_x = true; } else { - g_watches[cursor.y].line_selected = true; + watches[cursor.y].line_selected = true; cursor.lock_y = true; } } - if (GZ_getButtonTrig(GZPad::Z)) { - g_watches[cursor.y].visible = !g_watches[cursor.y].visible; + if (GZ_getButtonTrig(GZPad::Z) && watches) { + watches[cursor.y].visible = !watches[cursor.y].visible; } - if (GZ_getButtonTrig(MEMORY_BUTTON)) { - if (g_watches[cursor.y].offset > 0 && *(uint32_t*)g_watches[cursor.y].address != 0) { + if (GZ_getButtonTrig(MEMORY_BUTTON) && watches) { + if (watches[cursor.y].offset > 0 && *(uint32_t*)watches[cursor.y].address != 0) { g_memoryEditor_addressIndex = - *(uint32_t*)g_watches[cursor.y].address + g_watches[cursor.y].offset; + *(uint32_t*)watches[cursor.y].address + watches[cursor.y].offset; } else { - g_memoryEditor_addressIndex = g_watches[cursor.y].address; + g_memoryEditor_addressIndex = watches[cursor.y].address; } g_menuMgr->push(MN_MEMORY_EDITOR_INDEX); } + if (GZ_getButtonRepeat(ADD_WATCH_BUTTON) && !checkMemLineSelected(watches, n_watches)) { + if (n_watches < MAX_WATCHES) { + MemoryWatch* new_watches = new MemoryWatch[n_watches + 1]; + if (watches) { + if (n_watches > 0) { + for (int i = 0; i < (int)cursor.y + 1; ++i) { + new_watches[i] = watches[i]; + } + for (int i = n_watches - 1; i >= cursor.y; --i) { + new_watches[i + 1] = watches[i]; + } + } + delete[] watches; + } + stng->data = new_watches; + stng->size = (n_watches + 1) * sizeof(MemoryWatch); + watches = new_watches; + ++n_watches; + } + } + + if (GZ_getButtonRepeat(REMOVE_WATCH_BUTTON) && !checkMemLineSelected(watches, n_watches)) { + if (watches && n_watches > 0) { + MemoryWatch* new_watches = nullptr; + if (n_watches > 1) { + new_watches = new MemoryWatch[n_watches - 1]; + for (int i = 0; i < (int)cursor.y; i++) { + new_watches[i] = watches[i]; + } + for (int i = cursor.y; i < (int)n_watches - 1; i++) { + new_watches[i] = watches[i + 1]; + } + } + if (cursor.y > 0 && cursor.y == (int)n_watches - 1) { + cursor.y -= 1; + } + delete[] watches; + stng->data = new_watches; + stng->size = (n_watches - 1) * sizeof(MemoryWatch); + --n_watches; + watches = new_watches; + } + } + if (GZ_getButtonPressed(GZPad::DPAD_RIGHT) || GZ_getButtonPressed(GZPad::DPAD_LEFT)) { if (l_scrollSpeed < 20.0f) { l_scrollSpeed += 1.0f; @@ -465,8 +561,21 @@ void WatchesMenu::draw() { l_scrollSpeed = 1.0f; } - cursor.move(WATCH_COLUMNS, MAX_WATCHES); - GZ_drawText("Press Z to enable/disable watch. " MEMORY_TEXT " to jump to editor address", 25.0f, - 440.f, WHITE_RGBA, GZ_checkDropShadows()); - drawMemoryLines(); + if (checkMemLineSelected(watches, n_watches) && watches) { + cursor.setMode(Cursor::MODE_UNRESTRICTED); + cursor.move(WATCH_COLUMNS, n_watches); + GZ_drawText("Z: enable/disable watch; " MEMORY_TEXT ": go to address in editor", + 20.0f * scale, 440.f, WHITE_RGBA, GZ_checkDropShadows()); + } else { + cursor.setMode(Cursor::MODE_SINGLE_COLUMN); + cursor.move(0, n_watches); + GZ_drawText("Z: enable/disable watch; " MEMORY_TEXT ": go to address; " ADD_WATCH_TEXT + "/" REMOVE_WATCH_TEXT ": add/remove watch", + 20.0f * scale, 440.f, WHITE_RGBA, GZ_checkDropShadows()); + } + if (watches) { + drawMemoryLines(watches, n_watches); + } else { + GZ_drawText("No watches", 25.0f * scale, 60.0f, WHITE_RGBA, GZ_checkDropShadows()); + } } \ No newline at end of file diff --git a/res/icons/hand.png b/res/icons/hand.png new file mode 100644 index 0000000000000000000000000000000000000000..45185f1d011cc8d2eaae08706bbd2458273fa16d GIT binary patch literal 17341 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℞JCH5+4sGH3RPjT|- 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 HScU%&J|nb+ literal 0 HcmV?d00001 diff --git a/res/icons/wolf.png b/res/icons/wolf.png new file mode 100644 index 0000000000000000000000000000000000000000..21286dc82850b0451f25f9da384a62680e7eb54d GIT binary patch literal 16271 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

MN9K;&c9w&9t=x->1o6W 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 O-T(Q~`}@iFL;ep5qS2B7 literal 0 HcmV?d00001 diff --git a/res/save_files/ad.bin b/res/save_files/ad.bin index e0fa02fe10665d4d405c68cb7ce0abc4a02660ae..b3c1c8c32e550381ea33f3092380032919031865 100644 GIT binary patch delta 23 fcmZ1=^+9Tb0`J5HI-D8#Ma8K}iOJa$CrSeVY_JIT delta 7 Ocmew$wLofv0xtj!7y_aI diff --git a/res/save_files/any.bin b/res/save_files/any.bin index 34dad94160b280de51c2c12a711644f108334754..23f969894154360f934c7676b60ee500dd40558f 100644 GIT binary patch delta 28 kcmew$|3Q925Z_rF=a>F#o##JVamL!{5X#f_&z Hv3Ph7ZO<94 diff --git a/res/save_files/any/lakebed_1.bin b/res/save_files/any/lakebed_1.bin index d19b4eaffaee6eba691014d1fbf6e0df925a48e4..ea255313edd2342feac7cc6f4138b95092c6aeb2 100644 GIT binary patch delta 13 UcmeAX?Ga^R;Ai03$kM?D028hPsQ>@~ delta 13 UcmeAX?Ga^R;Addk$kM?D026!yp8x;= diff --git a/res/save_files/any/plumm_oob.bin b/res/save_files/any/plumm_oob.bin index 5ee341d0dd615365458a89a1c5dc5f56e4fbc3b8..d920375ef61ba0d961a34e6993e3f714c7de9b15 100644 GIT binary patch delta 13 UcmeAX?Ga^R;Addj$kM?D0277+p#T5? delta 13 UcmeAX?Ga^R;Ai03$kM?D028hPsQ>@~ diff --git a/res/save_files/nosq/rupee_roll.bin b/res/save_files/nosq/rupee_roll.bin index 0ca97978b775d770271305656feb007b89320078..326bf170ab80da89fff1d323f9bbdb442c5bb4c2 100644 GIT binary patch delta 13 UcmeAX?Gc@jz{JG7F-eOH02_P*fdBvi delta 13 UcmeAX?Gc@jz{JS3F-eOH02^@we*gdg diff --git a/res/stage_info/D_MN01/00/spawns.bin b/res/stage_info/D_MN01/00/sp.bin similarity index 100% rename from res/stage_info/D_MN01/00/spawns.bin rename to res/stage_info/D_MN01/00/sp.bin diff --git a/res/stage_info/D_MN01/01/spawns.bin b/res/stage_info/D_MN01/01/sp.bin similarity index 100% rename from res/stage_info/D_MN01/01/spawns.bin rename to res/stage_info/D_MN01/01/sp.bin diff --git a/res/stage_info/D_MN01/02/spawns.bin b/res/stage_info/D_MN01/02/sp.bin similarity index 100% rename from res/stage_info/D_MN01/02/spawns.bin rename to res/stage_info/D_MN01/02/sp.bin diff --git a/res/stage_info/D_MN01/03/spawns.bin b/res/stage_info/D_MN01/03/sp.bin similarity index 100% rename from res/stage_info/D_MN01/03/spawns.bin rename to res/stage_info/D_MN01/03/sp.bin diff --git a/res/stage_info/D_MN01/05/spawns.bin b/res/stage_info/D_MN01/05/sp.bin similarity index 100% rename from res/stage_info/D_MN01/05/spawns.bin rename to res/stage_info/D_MN01/05/sp.bin diff --git a/res/stage_info/D_MN01/06/spawns.bin b/res/stage_info/D_MN01/06/sp.bin similarity index 100% rename from res/stage_info/D_MN01/06/spawns.bin rename to res/stage_info/D_MN01/06/sp.bin diff --git a/res/stage_info/D_MN01/07/spawns.bin b/res/stage_info/D_MN01/07/sp.bin similarity index 100% rename from res/stage_info/D_MN01/07/spawns.bin rename to res/stage_info/D_MN01/07/sp.bin diff --git a/res/stage_info/D_MN01/08/spawns.bin b/res/stage_info/D_MN01/08/sp.bin similarity index 100% rename from res/stage_info/D_MN01/08/spawns.bin rename to res/stage_info/D_MN01/08/sp.bin diff --git a/res/stage_info/D_MN01/09/spawns.bin b/res/stage_info/D_MN01/09/sp.bin similarity index 100% rename from res/stage_info/D_MN01/09/spawns.bin rename to res/stage_info/D_MN01/09/sp.bin diff --git a/res/stage_info/D_MN01/10/spawns.bin b/res/stage_info/D_MN01/10/sp.bin similarity index 100% rename from res/stage_info/D_MN01/10/spawns.bin rename to res/stage_info/D_MN01/10/sp.bin diff --git a/res/stage_info/D_MN01/11/spawns.bin b/res/stage_info/D_MN01/11/sp.bin similarity index 100% rename from res/stage_info/D_MN01/11/spawns.bin rename to res/stage_info/D_MN01/11/sp.bin diff --git a/res/stage_info/D_MN01/12/spawns.bin b/res/stage_info/D_MN01/12/sp.bin similarity index 100% rename from res/stage_info/D_MN01/12/spawns.bin rename to res/stage_info/D_MN01/12/sp.bin diff --git a/res/stage_info/D_MN01/13/spawns.bin b/res/stage_info/D_MN01/13/sp.bin similarity index 100% rename from res/stage_info/D_MN01/13/spawns.bin rename to res/stage_info/D_MN01/13/sp.bin diff --git a/res/stage_info/D_MN01/rooms.bin b/res/stage_info/D_MN01/rooms.bin index f7e97f9c2004e80f5b3fc948efaa0260c7150bb2..50071d0600ec4c0a9a4787c186e48ff01f51efca 100644 GIT binary patch delta 55 zcmX@Wc7SaXqvK>oCWpz6j1ChII!tVIn9Rg1H&I?`@t(+fP0KRMf}_RK(;k H(a|0N^IZ{( delta 51 zcmWN_(Fp)B2m?`K!L^K|IfBhXb+h_$@VMvCMWk@zB74|i7ga{3v6GtRVAlqV558~^ A)c^nh diff --git a/res/stage_info/D_MN01/rooms.bin.bak b/res/stage_info/D_MN01/rooms.bin.bak new file mode 100644 index 0000000000000000000000000000000000000000..f7e97f9c2004e80f5b3fc948efaa0260c7150bb2 GIT binary patch literal 832 zcmaKo*$#p*5Jger?)*c)#pOv76VUM7z<@-g4U`!F-VIZxE%3xWb5EE7yy53is*0B} z_O)QtH~H~U@q))HSI7b(?p7Jb79wDWp9PAq%ubD}^MvdI6H>QA*SCgm08TO= zkZna>vm-wBpnZdxg$U>s|NflRtq|ndRk0{9Gj@>@E3*I#lhEApeerPkOWHS6d;cD9 z4Lb{-m~&W}gyzooBd)MwVIyUs|0Aqv-%LKHL+5+2F%6ov?>yfFpnWrG-?_f`0^grX A{{R30 literal 0 HcmV?d00001 diff --git a/res/stage_info/D_MN01A/50/spawns.bin b/res/stage_info/D_MN01A/50/sp.bin similarity index 100% rename from res/stage_info/D_MN01A/50/spawns.bin rename to res/stage_info/D_MN01A/50/sp.bin diff --git a/res/stage_info/D_MN01B/51/spawns.bin b/res/stage_info/D_MN01B/51/sp.bin similarity index 100% rename from res/stage_info/D_MN01B/51/spawns.bin rename to res/stage_info/D_MN01B/51/sp.bin diff --git a/res/stage_info/D_MN04/01/spawns.bin b/res/stage_info/D_MN04/01/sp.bin similarity index 100% rename from res/stage_info/D_MN04/01/spawns.bin rename to res/stage_info/D_MN04/01/sp.bin diff --git a/res/stage_info/D_MN04/03/spawns.bin b/res/stage_info/D_MN04/03/sp.bin similarity index 100% rename from res/stage_info/D_MN04/03/spawns.bin rename to res/stage_info/D_MN04/03/sp.bin diff --git a/res/stage_info/D_MN04/04/spawns.bin b/res/stage_info/D_MN04/04/sp.bin similarity index 100% rename from res/stage_info/D_MN04/04/spawns.bin rename to res/stage_info/D_MN04/04/sp.bin diff --git a/res/stage_info/D_MN04/05/spawns.bin b/res/stage_info/D_MN04/05/sp.bin similarity index 100% rename from res/stage_info/D_MN04/05/spawns.bin rename to res/stage_info/D_MN04/05/sp.bin diff --git a/res/stage_info/D_MN04/06/spawns.bin b/res/stage_info/D_MN04/06/sp.bin similarity index 100% rename from res/stage_info/D_MN04/06/spawns.bin rename to res/stage_info/D_MN04/06/sp.bin diff --git a/res/stage_info/D_MN04/07/spawns.bin b/res/stage_info/D_MN04/07/sp.bin similarity index 100% rename from res/stage_info/D_MN04/07/spawns.bin rename to res/stage_info/D_MN04/07/sp.bin diff --git a/res/stage_info/D_MN04/09/spawns.bin b/res/stage_info/D_MN04/09/sp.bin similarity index 100% rename from res/stage_info/D_MN04/09/spawns.bin rename to res/stage_info/D_MN04/09/sp.bin diff --git a/res/stage_info/D_MN04/11/spawns.bin b/res/stage_info/D_MN04/11/sp.bin similarity index 100% rename from res/stage_info/D_MN04/11/spawns.bin rename to res/stage_info/D_MN04/11/sp.bin diff --git a/res/stage_info/D_MN04/12/spawns.bin b/res/stage_info/D_MN04/12/sp.bin similarity index 100% rename from res/stage_info/D_MN04/12/spawns.bin rename to res/stage_info/D_MN04/12/sp.bin diff --git a/res/stage_info/D_MN04/13/spawns.bin b/res/stage_info/D_MN04/13/sp.bin similarity index 100% rename from res/stage_info/D_MN04/13/spawns.bin rename to res/stage_info/D_MN04/13/sp.bin diff --git a/res/stage_info/D_MN04/14/spawns.bin b/res/stage_info/D_MN04/14/sp.bin similarity index 100% rename from res/stage_info/D_MN04/14/spawns.bin rename to res/stage_info/D_MN04/14/sp.bin diff --git a/res/stage_info/D_MN04/16/spawns.bin b/res/stage_info/D_MN04/16/sp.bin similarity index 100% rename from res/stage_info/D_MN04/16/spawns.bin rename to res/stage_info/D_MN04/16/sp.bin diff --git a/res/stage_info/D_MN04/17/spawns.bin b/res/stage_info/D_MN04/17/sp.bin similarity index 100% rename from res/stage_info/D_MN04/17/spawns.bin rename to res/stage_info/D_MN04/17/sp.bin diff --git a/res/stage_info/D_MN04/rooms.bin b/res/stage_info/D_MN04/rooms.bin index 8ca30359b7e59bc2ea6f8ef1c100ea162b6687a3..4c15a9f3eab37faf60c4a13399e8d7a75332c961 100644 GIT binary patch delta 49 xcmWN?!3_XF1O&jWOSFZ~C_%O%Iy>{3(NU%Z@r)zU>nu1S&b{LXypfEn>;s@15Ci}K delta 48 ucmWN=0SN#=2m?UogSDK|j36td&0e@09~Z5J7d;mYP1Icv=9p> delta 33 ocmX@Wa)4!GL*rydCi}?^jE<8X8674wGCE9jbeMb)NHN+20KnS{rvLx| diff --git a/res/stage_info/D_MN06A/50/spawns.bin b/res/stage_info/D_MN06A/50/sp.bin similarity index 100% rename from res/stage_info/D_MN06A/50/spawns.bin rename to res/stage_info/D_MN06A/50/sp.bin diff --git a/res/stage_info/D_MN06B/51/spawns.bin b/res/stage_info/D_MN06B/51/sp.bin similarity index 100% rename from res/stage_info/D_MN06B/51/spawns.bin rename to res/stage_info/D_MN06B/51/sp.bin diff --git a/res/stage_info/D_MN07/00/spawns.bin b/res/stage_info/D_MN07/00/sp.bin similarity index 100% rename from res/stage_info/D_MN07/00/spawns.bin rename to res/stage_info/D_MN07/00/sp.bin diff --git a/res/stage_info/D_MN07/01/spawns.bin b/res/stage_info/D_MN07/01/sp.bin similarity index 100% rename from res/stage_info/D_MN07/01/spawns.bin rename to res/stage_info/D_MN07/01/sp.bin diff --git a/res/stage_info/D_MN07/02/spawns.bin b/res/stage_info/D_MN07/02/sp.bin similarity index 100% rename from res/stage_info/D_MN07/02/spawns.bin rename to res/stage_info/D_MN07/02/sp.bin diff --git a/res/stage_info/D_MN07/03/spawns.bin b/res/stage_info/D_MN07/03/sp.bin similarity index 100% rename from res/stage_info/D_MN07/03/spawns.bin rename to res/stage_info/D_MN07/03/sp.bin diff --git a/res/stage_info/D_MN07/04/spawns.bin b/res/stage_info/D_MN07/04/sp.bin similarity index 100% rename from res/stage_info/D_MN07/04/spawns.bin rename to res/stage_info/D_MN07/04/sp.bin diff --git a/res/stage_info/D_MN07/05/spawns.bin b/res/stage_info/D_MN07/05/sp.bin similarity index 100% rename from res/stage_info/D_MN07/05/spawns.bin rename to res/stage_info/D_MN07/05/sp.bin diff --git a/res/stage_info/D_MN07/06/spawns.bin b/res/stage_info/D_MN07/06/sp.bin similarity index 100% rename from res/stage_info/D_MN07/06/spawns.bin rename to res/stage_info/D_MN07/06/sp.bin diff --git a/res/stage_info/D_MN07/07/spawns.bin b/res/stage_info/D_MN07/07/sp.bin similarity index 100% rename from res/stage_info/D_MN07/07/spawns.bin rename to res/stage_info/D_MN07/07/sp.bin diff --git a/res/stage_info/D_MN07/08/spawns.bin b/res/stage_info/D_MN07/08/sp.bin similarity index 100% rename from res/stage_info/D_MN07/08/spawns.bin rename to res/stage_info/D_MN07/08/sp.bin diff --git a/res/stage_info/D_MN07/10/spawns.bin b/res/stage_info/D_MN07/10/sp.bin similarity index 100% rename from res/stage_info/D_MN07/10/spawns.bin rename to res/stage_info/D_MN07/10/sp.bin diff --git a/res/stage_info/D_MN07/11/spawns.bin b/res/stage_info/D_MN07/11/sp.bin similarity index 100% rename from res/stage_info/D_MN07/11/spawns.bin rename to res/stage_info/D_MN07/11/sp.bin diff --git a/res/stage_info/D_MN07/12/spawns.bin b/res/stage_info/D_MN07/12/sp.bin similarity index 100% rename from res/stage_info/D_MN07/12/spawns.bin rename to res/stage_info/D_MN07/12/sp.bin diff --git a/res/stage_info/D_MN07/13/spawns.bin b/res/stage_info/D_MN07/13/sp.bin similarity index 100% rename from res/stage_info/D_MN07/13/spawns.bin rename to res/stage_info/D_MN07/13/sp.bin diff --git a/res/stage_info/D_MN07/14/spawns.bin b/res/stage_info/D_MN07/14/sp.bin similarity index 100% rename from res/stage_info/D_MN07/14/spawns.bin rename to res/stage_info/D_MN07/14/sp.bin diff --git a/res/stage_info/D_MN07/15/spawns.bin b/res/stage_info/D_MN07/15/sp.bin similarity index 100% rename from res/stage_info/D_MN07/15/spawns.bin rename to res/stage_info/D_MN07/15/sp.bin diff --git a/res/stage_info/D_MN07/16/spawns.bin b/res/stage_info/D_MN07/16/sp.bin similarity index 100% rename from res/stage_info/D_MN07/16/spawns.bin rename to res/stage_info/D_MN07/16/sp.bin diff --git a/res/stage_info/D_MN07/rooms.bin b/res/stage_info/D_MN07/rooms.bin index c018494757492b06aca5bc0855b970f64b3910a1..35a652783f90c388ee51eb7b0b2204756ad8d95c 100644 GIT binary patch delta 63 zcmWN@!3}^g3od69VRl?0{~He2dn@9 diff --git a/res/stage_info/D_MN08A/10/spawns.bin b/res/stage_info/D_MN08A/10/sp.bin similarity index 100% rename from res/stage_info/D_MN08A/10/spawns.bin rename to res/stage_info/D_MN08A/10/sp.bin diff --git a/res/stage_info/D_MN08B/51/spawns.bin b/res/stage_info/D_MN08B/51/sp.bin similarity index 100% rename from res/stage_info/D_MN08B/51/spawns.bin rename to res/stage_info/D_MN08B/51/sp.bin diff --git a/res/stage_info/D_MN08C/52/spawns.bin b/res/stage_info/D_MN08C/52/sp.bin similarity index 100% rename from res/stage_info/D_MN08C/52/spawns.bin rename to res/stage_info/D_MN08C/52/sp.bin diff --git a/res/stage_info/D_MN08D/50/spawns.bin b/res/stage_info/D_MN08D/50/sp.bin similarity index 100% rename from res/stage_info/D_MN08D/50/spawns.bin rename to res/stage_info/D_MN08D/50/sp.bin diff --git a/res/stage_info/D_MN08D/53/spawns.bin b/res/stage_info/D_MN08D/53/sp.bin similarity index 100% rename from res/stage_info/D_MN08D/53/spawns.bin rename to res/stage_info/D_MN08D/53/sp.bin diff --git a/res/stage_info/D_MN08D/54/spawns.bin b/res/stage_info/D_MN08D/54/sp.bin similarity index 100% rename from res/stage_info/D_MN08D/54/spawns.bin rename to res/stage_info/D_MN08D/54/sp.bin diff --git a/res/stage_info/D_MN08D/55/spawns.bin b/res/stage_info/D_MN08D/55/sp.bin similarity index 100% rename from res/stage_info/D_MN08D/55/spawns.bin rename to res/stage_info/D_MN08D/55/sp.bin diff --git a/res/stage_info/D_MN08D/56/spawns.bin b/res/stage_info/D_MN08D/56/sp.bin similarity index 100% rename from res/stage_info/D_MN08D/56/spawns.bin rename to res/stage_info/D_MN08D/56/sp.bin diff --git a/res/stage_info/D_MN08D/57/spawns.bin b/res/stage_info/D_MN08D/57/sp.bin similarity index 100% rename from res/stage_info/D_MN08D/57/spawns.bin rename to res/stage_info/D_MN08D/57/sp.bin diff --git a/res/stage_info/D_MN08D/60/spawns.bin b/res/stage_info/D_MN08D/60/sp.bin similarity index 100% rename from res/stage_info/D_MN08D/60/spawns.bin rename to res/stage_info/D_MN08D/60/sp.bin diff --git a/res/stage_info/D_MN08D/rooms.bin b/res/stage_info/D_MN08D/rooms.bin index e7f4599fc959cca73bd648c51f0244d0e5f862c0..d99aea7261df7d0ccb28f3042dbab1ec5a694055 100644 GIT binary patch delta 24 gcmX@We1Lhf1Eb?aM~BIcjP?^7949h5OgvZ*0Baox_W%F@ delta 22 ecmX@We1LfpqvJ$JhlvLrCOb0LPjH;rXb%8jQwVhc diff --git a/res/stage_info/D_MN09/01/spawns.bin b/res/stage_info/D_MN09/01/sp.bin similarity index 100% rename from res/stage_info/D_MN09/01/spawns.bin rename to res/stage_info/D_MN09/01/sp.bin diff --git a/res/stage_info/D_MN09/02/spawns.bin b/res/stage_info/D_MN09/02/sp.bin similarity index 100% rename from res/stage_info/D_MN09/02/spawns.bin rename to res/stage_info/D_MN09/02/sp.bin diff --git a/res/stage_info/D_MN09/03/spawns.bin b/res/stage_info/D_MN09/03/sp.bin similarity index 100% rename from res/stage_info/D_MN09/03/spawns.bin rename to res/stage_info/D_MN09/03/sp.bin diff --git a/res/stage_info/D_MN09/04/spawns.bin b/res/stage_info/D_MN09/04/sp.bin similarity index 100% rename from res/stage_info/D_MN09/04/spawns.bin rename to res/stage_info/D_MN09/04/sp.bin diff --git a/res/stage_info/D_MN09/05/spawns.bin b/res/stage_info/D_MN09/05/sp.bin similarity index 100% rename from res/stage_info/D_MN09/05/spawns.bin rename to res/stage_info/D_MN09/05/sp.bin diff --git a/res/stage_info/D_MN09/06/spawns.bin b/res/stage_info/D_MN09/06/sp.bin similarity index 100% rename from res/stage_info/D_MN09/06/spawns.bin rename to res/stage_info/D_MN09/06/sp.bin diff --git a/res/stage_info/D_MN09/08/spawns.bin b/res/stage_info/D_MN09/08/sp.bin similarity index 100% rename from res/stage_info/D_MN09/08/spawns.bin rename to res/stage_info/D_MN09/08/sp.bin diff --git a/res/stage_info/D_MN09/09/spawns.bin b/res/stage_info/D_MN09/09/sp.bin similarity index 100% rename from res/stage_info/D_MN09/09/spawns.bin rename to res/stage_info/D_MN09/09/sp.bin diff --git a/res/stage_info/D_MN09/11/spawns.bin b/res/stage_info/D_MN09/11/sp.bin similarity index 100% rename from res/stage_info/D_MN09/11/spawns.bin rename to res/stage_info/D_MN09/11/sp.bin diff --git a/res/stage_info/D_MN09/12/spawns.bin b/res/stage_info/D_MN09/12/sp.bin similarity index 100% rename from res/stage_info/D_MN09/12/spawns.bin rename to res/stage_info/D_MN09/12/sp.bin diff --git a/res/stage_info/D_MN09/13/spawns.bin b/res/stage_info/D_MN09/13/sp.bin similarity index 100% rename from res/stage_info/D_MN09/13/spawns.bin rename to res/stage_info/D_MN09/13/sp.bin diff --git a/res/stage_info/D_MN09/14/spawns.bin b/res/stage_info/D_MN09/14/sp.bin similarity index 100% rename from res/stage_info/D_MN09/14/spawns.bin rename to res/stage_info/D_MN09/14/sp.bin diff --git a/res/stage_info/D_MN09/15/spawns.bin b/res/stage_info/D_MN09/15/sp.bin similarity index 100% rename from res/stage_info/D_MN09/15/spawns.bin rename to res/stage_info/D_MN09/15/sp.bin diff --git a/res/stage_info/D_MN09/rooms.bin b/res/stage_info/D_MN09/rooms.bin index ab44705e0459cd60073bc3ada3604a63d4c914bd..f57d82c86c4ecdfc05cf500a7dca87a401bbee9e 100644 GIT binary patch delta 40 tcmV~$0Sy2!2m`Q;C)i>*0||VFxU;wG>(^2boTSn?T>}az;e^Usjrbl54OjpG delta 40 ucmWN=fe8RG2m>(cz_+ZQ=?T(@+-F-L>+34yGzFCIj}yZja4ywWN{a_63=S0l diff --git a/res/stage_info/D_MN09A/50/spawns.bin b/res/stage_info/D_MN09A/50/sp.bin similarity index 100% rename from res/stage_info/D_MN09A/50/spawns.bin rename to res/stage_info/D_MN09A/50/sp.bin diff --git a/res/stage_info/D_MN09A/51/spawns.bin b/res/stage_info/D_MN09A/51/sp.bin similarity index 100% rename from res/stage_info/D_MN09A/51/spawns.bin rename to res/stage_info/D_MN09A/51/sp.bin diff --git a/res/stage_info/D_MN09B/00/spawns.bin b/res/stage_info/D_MN09B/00/sp.bin similarity index 100% rename from res/stage_info/D_MN09B/00/spawns.bin rename to res/stage_info/D_MN09B/00/sp.bin diff --git a/res/stage_info/D_MN09C/00/spawns.bin b/res/stage_info/D_MN09C/00/sp.bin similarity index 100% rename from res/stage_info/D_MN09C/00/spawns.bin rename to res/stage_info/D_MN09C/00/sp.bin diff --git a/res/stage_info/D_MN10/00/spawns.bin b/res/stage_info/D_MN10/00/sp.bin similarity index 100% rename from res/stage_info/D_MN10/00/spawns.bin rename to res/stage_info/D_MN10/00/sp.bin diff --git a/res/stage_info/D_MN10/01/spawns.bin b/res/stage_info/D_MN10/01/sp.bin similarity index 100% rename from res/stage_info/D_MN10/01/spawns.bin rename to res/stage_info/D_MN10/01/sp.bin diff --git a/res/stage_info/D_MN10/02/spawns.bin b/res/stage_info/D_MN10/02/sp.bin similarity index 100% rename from res/stage_info/D_MN10/02/spawns.bin rename to res/stage_info/D_MN10/02/sp.bin diff --git a/res/stage_info/D_MN10/03/spawns.bin b/res/stage_info/D_MN10/03/sp.bin similarity index 100% rename from res/stage_info/D_MN10/03/spawns.bin rename to res/stage_info/D_MN10/03/sp.bin diff --git a/res/stage_info/D_MN10/04/spawns.bin b/res/stage_info/D_MN10/04/sp.bin similarity index 100% rename from res/stage_info/D_MN10/04/spawns.bin rename to res/stage_info/D_MN10/04/sp.bin diff --git a/res/stage_info/D_MN10/05/spawns.bin b/res/stage_info/D_MN10/05/sp.bin similarity index 100% rename from res/stage_info/D_MN10/05/spawns.bin rename to res/stage_info/D_MN10/05/sp.bin diff --git a/res/stage_info/D_MN10/06/spawns.bin b/res/stage_info/D_MN10/06/sp.bin similarity index 100% rename from res/stage_info/D_MN10/06/spawns.bin rename to res/stage_info/D_MN10/06/sp.bin diff --git a/res/stage_info/D_MN10/07/spawns.bin b/res/stage_info/D_MN10/07/sp.bin similarity index 100% rename from res/stage_info/D_MN10/07/spawns.bin rename to res/stage_info/D_MN10/07/sp.bin diff --git a/res/stage_info/D_MN10/08/spawns.bin b/res/stage_info/D_MN10/08/sp.bin similarity index 100% rename from res/stage_info/D_MN10/08/spawns.bin rename to res/stage_info/D_MN10/08/sp.bin diff --git a/res/stage_info/D_MN10/09/spawns.bin b/res/stage_info/D_MN10/09/sp.bin similarity index 100% rename from res/stage_info/D_MN10/09/spawns.bin rename to res/stage_info/D_MN10/09/sp.bin diff --git a/res/stage_info/D_MN10/10/spawns.bin b/res/stage_info/D_MN10/10/sp.bin similarity index 100% rename from res/stage_info/D_MN10/10/spawns.bin rename to res/stage_info/D_MN10/10/sp.bin diff --git a/res/stage_info/D_MN10/11/spawns.bin b/res/stage_info/D_MN10/11/sp.bin similarity index 100% rename from res/stage_info/D_MN10/11/spawns.bin rename to res/stage_info/D_MN10/11/sp.bin diff --git a/res/stage_info/D_MN10/12/spawns.bin b/res/stage_info/D_MN10/12/sp.bin similarity index 100% rename from res/stage_info/D_MN10/12/spawns.bin rename to res/stage_info/D_MN10/12/sp.bin diff --git a/res/stage_info/D_MN10/13/spawns.bin b/res/stage_info/D_MN10/13/sp.bin similarity index 100% rename from res/stage_info/D_MN10/13/spawns.bin rename to res/stage_info/D_MN10/13/sp.bin diff --git a/res/stage_info/D_MN10/14/spawns.bin b/res/stage_info/D_MN10/14/sp.bin similarity index 100% rename from res/stage_info/D_MN10/14/spawns.bin rename to res/stage_info/D_MN10/14/sp.bin diff --git a/res/stage_info/D_MN10/15/spawns.bin b/res/stage_info/D_MN10/15/sp.bin similarity index 100% rename from res/stage_info/D_MN10/15/spawns.bin rename to res/stage_info/D_MN10/15/sp.bin diff --git a/res/stage_info/D_MN10/16/spawns.bin b/res/stage_info/D_MN10/16/sp.bin similarity index 100% rename from res/stage_info/D_MN10/16/spawns.bin rename to res/stage_info/D_MN10/16/sp.bin diff --git a/res/stage_info/D_MN10/rooms.bin b/res/stage_info/D_MN10/rooms.bin index e5832b933b9cd98f7c0631644d25d828e886ccd3..7f381e893261add028eeb55942d3822804f6b7cc 100644 GIT binary patch delta 64 zcmWlP!3_W)2*d*Ta4WgZWCX%Ou$kwpP1D}Jvr!N)QLixaJ2~nJ>N@3$WCd%;%^*0B Fod=Yy6k-4X delta 63 zcmWN`!4Uu;2m`?ZeAtztGc5trkaT7qH}}{#-{kgW8+ZbxnW0jPT?b4DJA{%{?WmTH GbsZn9uN2<^ diff --git a/res/stage_info/D_MN10A/50/spawns.bin b/res/stage_info/D_MN10A/50/sp.bin similarity index 100% rename from res/stage_info/D_MN10A/50/spawns.bin rename to res/stage_info/D_MN10A/50/sp.bin diff --git a/res/stage_info/D_MN10B/51/spawns.bin b/res/stage_info/D_MN10B/51/sp.bin similarity index 100% rename from res/stage_info/D_MN10B/51/spawns.bin rename to res/stage_info/D_MN10B/51/sp.bin diff --git a/res/stage_info/D_MN11/00/spawns.bin b/res/stage_info/D_MN11/00/sp.bin similarity index 100% rename from res/stage_info/D_MN11/00/spawns.bin rename to res/stage_info/D_MN11/00/sp.bin diff --git a/res/stage_info/D_MN11/01/spawns.bin b/res/stage_info/D_MN11/01/sp.bin similarity index 100% rename from res/stage_info/D_MN11/01/spawns.bin rename to res/stage_info/D_MN11/01/sp.bin diff --git a/res/stage_info/D_MN11/02/spawns.bin b/res/stage_info/D_MN11/02/sp.bin similarity index 100% rename from res/stage_info/D_MN11/02/spawns.bin rename to res/stage_info/D_MN11/02/sp.bin diff --git a/res/stage_info/D_MN11/03/spawns.bin b/res/stage_info/D_MN11/03/sp.bin similarity index 100% rename from res/stage_info/D_MN11/03/spawns.bin rename to res/stage_info/D_MN11/03/sp.bin diff --git a/res/stage_info/D_MN11/04/spawns.bin b/res/stage_info/D_MN11/04/sp.bin similarity index 100% rename from res/stage_info/D_MN11/04/spawns.bin rename to res/stage_info/D_MN11/04/sp.bin diff --git a/res/stage_info/D_MN11/05/spawns.bin b/res/stage_info/D_MN11/05/sp.bin similarity index 100% rename from res/stage_info/D_MN11/05/spawns.bin rename to res/stage_info/D_MN11/05/sp.bin diff --git a/res/stage_info/D_MN11/06/spawns.bin b/res/stage_info/D_MN11/06/sp.bin similarity index 100% rename from res/stage_info/D_MN11/06/spawns.bin rename to res/stage_info/D_MN11/06/sp.bin diff --git a/res/stage_info/D_MN11/07/spawns.bin b/res/stage_info/D_MN11/07/sp.bin similarity index 100% rename from res/stage_info/D_MN11/07/spawns.bin rename to res/stage_info/D_MN11/07/sp.bin diff --git a/res/stage_info/D_MN11/08/spawns.bin b/res/stage_info/D_MN11/08/sp.bin similarity index 100% rename from res/stage_info/D_MN11/08/spawns.bin rename to res/stage_info/D_MN11/08/sp.bin diff --git a/res/stage_info/D_MN11/09/spawns.bin b/res/stage_info/D_MN11/09/sp.bin similarity index 100% rename from res/stage_info/D_MN11/09/spawns.bin rename to res/stage_info/D_MN11/09/sp.bin diff --git a/res/stage_info/D_MN11/11/spawns.bin b/res/stage_info/D_MN11/11/sp.bin similarity index 100% rename from res/stage_info/D_MN11/11/spawns.bin rename to res/stage_info/D_MN11/11/sp.bin diff --git a/res/stage_info/D_MN11/13/spawns.bin b/res/stage_info/D_MN11/13/sp.bin similarity index 100% rename from res/stage_info/D_MN11/13/spawns.bin rename to res/stage_info/D_MN11/13/sp.bin diff --git a/res/stage_info/D_MN11/rooms.bin b/res/stage_info/D_MN11/rooms.bin index b6dfbfdd8fcec3561504781f9642eaaef04d780e..fe1fa94ebc8d8e1ce70ae606b9c783655fd273bd 100644 GIT binary patch delta 37 pcmZo*YhasvfXQKU1C!%qMn;Fp2N@eC0x3r(hlvM)6p-gw4*=?j48i~a delta 36 scmZo*Yhat~!00%+k*R+20Y=A(jSiC;nHnY@Y?$20=rGaIVIreF0OecIGTH+G diff --git a/res/stage_info/F_SP109/00/spawns.bin b/res/stage_info/F_SP109/00/sp.bin similarity index 100% rename from res/stage_info/F_SP109/00/spawns.bin rename to res/stage_info/F_SP109/00/sp.bin diff --git a/res/stage_info/F_SP110/00/spawns.bin b/res/stage_info/F_SP110/00/sp.bin similarity index 100% rename from res/stage_info/F_SP110/00/spawns.bin rename to res/stage_info/F_SP110/00/sp.bin diff --git a/res/stage_info/F_SP110/01/spawns.bin b/res/stage_info/F_SP110/01/sp.bin similarity index 100% rename from res/stage_info/F_SP110/01/spawns.bin rename to res/stage_info/F_SP110/01/sp.bin diff --git a/res/stage_info/F_SP110/02/spawns.bin b/res/stage_info/F_SP110/02/sp.bin similarity index 100% rename from res/stage_info/F_SP110/02/spawns.bin rename to res/stage_info/F_SP110/02/sp.bin diff --git a/res/stage_info/F_SP110/03/spawns.bin b/res/stage_info/F_SP110/03/sp.bin similarity index 100% rename from res/stage_info/F_SP110/03/spawns.bin rename to res/stage_info/F_SP110/03/sp.bin diff --git a/res/stage_info/F_SP111/00/spawns.bin b/res/stage_info/F_SP111/00/sp.bin similarity index 100% rename from res/stage_info/F_SP111/00/spawns.bin rename to res/stage_info/F_SP111/00/sp.bin diff --git a/res/stage_info/F_SP112/01/spawns.bin b/res/stage_info/F_SP112/01/sp.bin similarity index 100% rename from res/stage_info/F_SP112/01/spawns.bin rename to res/stage_info/F_SP112/01/sp.bin diff --git a/res/stage_info/F_SP113/00/spawns.bin b/res/stage_info/F_SP113/00/sp.bin similarity index 100% rename from res/stage_info/F_SP113/00/spawns.bin rename to res/stage_info/F_SP113/00/sp.bin diff --git a/res/stage_info/F_SP113/01/spawns.bin b/res/stage_info/F_SP113/01/sp.bin similarity index 100% rename from res/stage_info/F_SP113/01/spawns.bin rename to res/stage_info/F_SP113/01/sp.bin diff --git a/res/stage_info/F_SP114/00/spawns.bin b/res/stage_info/F_SP114/00/sp.bin similarity index 100% rename from res/stage_info/F_SP114/00/spawns.bin rename to res/stage_info/F_SP114/00/sp.bin diff --git a/res/stage_info/F_SP114/01/spawns.bin b/res/stage_info/F_SP114/01/sp.bin similarity index 100% rename from res/stage_info/F_SP114/01/spawns.bin rename to res/stage_info/F_SP114/01/sp.bin diff --git a/res/stage_info/F_SP114/02/spawns.bin b/res/stage_info/F_SP114/02/sp.bin similarity index 100% rename from res/stage_info/F_SP114/02/spawns.bin rename to res/stage_info/F_SP114/02/sp.bin diff --git a/res/stage_info/F_SP115/00/spawns.bin b/res/stage_info/F_SP115/00/sp.bin similarity index 100% rename from res/stage_info/F_SP115/00/spawns.bin rename to res/stage_info/F_SP115/00/sp.bin diff --git a/res/stage_info/F_SP115/01/spawns.bin b/res/stage_info/F_SP115/01/sp.bin similarity index 100% rename from res/stage_info/F_SP115/01/spawns.bin rename to res/stage_info/F_SP115/01/sp.bin diff --git a/res/stage_info/F_SP115/rooms.bin b/res/stage_info/F_SP115/rooms.bin index fd062689a5d7c1dad9290b183ebd1e620f8c1f46..f2685937efcfc79fb6dc87181259e03dcba7a41e 100644 GIT binary patch delta 9 QcmZo*Y+#(|;4r}f01gZS;r10&<)CT6*b@=B8rGCE9dWOSJ52&9-vqvPa*j1CJK87DU~I!ty1;zlNi$&AeVCm&#Poa_iHaGwPS=0x% diff --git a/res/stage_info/R_SP107/00/spawns.bin b/res/stage_info/R_SP107/00/sp.bin similarity index 100% rename from res/stage_info/R_SP107/00/spawns.bin rename to res/stage_info/R_SP107/00/sp.bin diff --git a/res/stage_info/R_SP107/01/spawns.bin b/res/stage_info/R_SP107/01/sp.bin similarity index 100% rename from res/stage_info/R_SP107/01/spawns.bin rename to res/stage_info/R_SP107/01/sp.bin diff --git a/res/stage_info/R_SP107/02/spawns.bin b/res/stage_info/R_SP107/02/sp.bin similarity index 100% rename from res/stage_info/R_SP107/02/spawns.bin rename to res/stage_info/R_SP107/02/sp.bin diff --git a/res/stage_info/R_SP107/03/spawns.bin b/res/stage_info/R_SP107/03/sp.bin similarity index 100% rename from res/stage_info/R_SP107/03/spawns.bin rename to res/stage_info/R_SP107/03/sp.bin diff --git a/res/stage_info/R_SP107/rooms.bin b/res/stage_info/R_SP107/rooms.bin index ddfab4a8ed9bf9cb51ca9be325ba4fd031197f9d..7d81febe7bc15e92a912cf5a1bd01084eb9fec31 100644 GIT binary patch delta 15 WcmZo*YG9h+II+=TqNBsagZ2O_{RPVa delta 15 WcmZo*YG9h+II+=TqNBsagZ2O_{RPVa diff --git a/res/stage_info/R_SP108/00/spawns.bin b/res/stage_info/R_SP108/00/sp.bin similarity index 100% rename from res/stage_info/R_SP108/00/spawns.bin rename to res/stage_info/R_SP108/00/sp.bin diff --git a/res/stage_info/R_SP109/00/spawns.bin b/res/stage_info/R_SP109/00/sp.bin similarity index 100% rename from res/stage_info/R_SP109/00/spawns.bin rename to res/stage_info/R_SP109/00/sp.bin diff --git a/res/stage_info/R_SP109/01/spawns.bin b/res/stage_info/R_SP109/01/sp.bin similarity index 100% rename from res/stage_info/R_SP109/01/spawns.bin rename to res/stage_info/R_SP109/01/sp.bin diff --git a/res/stage_info/R_SP109/02/spawns.bin b/res/stage_info/R_SP109/02/sp.bin similarity index 100% rename from res/stage_info/R_SP109/02/spawns.bin rename to res/stage_info/R_SP109/02/sp.bin diff --git a/res/stage_info/R_SP109/03/spawns.bin b/res/stage_info/R_SP109/03/sp.bin similarity index 100% rename from res/stage_info/R_SP109/03/spawns.bin rename to res/stage_info/R_SP109/03/sp.bin diff --git a/res/stage_info/R_SP109/04/spawns.bin b/res/stage_info/R_SP109/04/sp.bin similarity index 100% rename from res/stage_info/R_SP109/04/spawns.bin rename to res/stage_info/R_SP109/04/sp.bin diff --git a/res/stage_info/R_SP109/05/spawns.bin b/res/stage_info/R_SP109/05/sp.bin similarity index 100% rename from res/stage_info/R_SP109/05/spawns.bin rename to res/stage_info/R_SP109/05/sp.bin diff --git a/res/stage_info/R_SP109/06/spawns.bin b/res/stage_info/R_SP109/06/sp.bin similarity index 100% rename from res/stage_info/R_SP109/06/spawns.bin rename to res/stage_info/R_SP109/06/sp.bin diff --git a/res/stage_info/R_SP109/rooms.bin b/res/stage_info/R_SP109/rooms.bin index 4baaf2cd89fc7b172da0abe88d457f16c9c127b3..cc53421d4738c3856045dec076c525f360808f7f 100644 GIT binary patch delta 21 dcmX@We1LhPgX3gJ#`=j3jT0FiCNnbH0{~Xe2PFUi delta 21 dcmX@We1Lhf1Eb?aMu&+98zwh0+D~+70031&2ju_& diff --git a/res/stage_info/R_SP110/00/spawns.bin b/res/stage_info/R_SP110/00/sp.bin similarity index 100% rename from res/stage_info/R_SP110/00/spawns.bin rename to res/stage_info/R_SP110/00/sp.bin diff --git a/res/stage_info/R_SP116/05/spawns.bin b/res/stage_info/R_SP116/05/sp.bin similarity index 100% rename from res/stage_info/R_SP116/05/spawns.bin rename to res/stage_info/R_SP116/05/sp.bin diff --git a/res/stage_info/R_SP116/06/spawns.bin b/res/stage_info/R_SP116/06/sp.bin similarity index 100% rename from res/stage_info/R_SP116/06/spawns.bin rename to res/stage_info/R_SP116/06/sp.bin diff --git a/res/stage_info/R_SP116/rooms.bin b/res/stage_info/R_SP116/rooms.bin index f8aad746c41becc137b972e449e10fe7f1df766a..9d601b11835ab2b6a5b5e6d50f58ea4adc1a207a 100644 GIT binary patch delta 9 QcmZo*Y+#(|;4r}f01gZS!*>Ji5bfCMPJ~*yXq9Q+7`l8TW)B}{>9fMwFPcC5AFTYi?S5w8VUUV^bA@7j zXG`q=&AhWSW?gFg-kDlVPc!Jt*)&X<=?jQBD4>|XXs8GKu=kOBcA|CN^f8GRR>#{X* zJDZve?`pAKj+a{2L?g$SCl9)Mt~dJ_6`-bf>&A7eR)BHsYW$;mJ%eUeu7;BKc+uUu zC9MQWsPmwUCy(grZP&taz7q3{#igp_6o?jCX+-|cv?h^}b*^--w*IX+&R1fdvABQE ze~uif?|HA<@492|d)_PS?0t(nWbfO%VztO}?R)`+X9q0!$b$@tkMo1~R}C(1ai&E+ D%J-XtE+P-8s+B70-3l$`60W_YCN-+BKk^M&o&& zU&cpS3ApZd%N@TSF diff --git a/res/tex/hand.tex b/res/tex/hand.tex new file mode 100644 index 0000000000000000000000000000000000000000..76d186318730a38a283d49ce3f18cf955e0bb64f GIT binary patch literal 1040 zcmbu8%_~Gv7{-6pAPXPK!apF%L`?Py3pG1snvIQYBpYh%?5rtkJ85=o6bmx!Y?Pub zgl46DMbwPObIzQr$zooU_jd2^z4tuNd){+ScXBK>Ksnk3cmFfujQR@O+|i+IpJ#f- z9bV`*Yj3h4O`JS?)N#%er?m6V11BUXnf|Vz$OJA2&WN3=SbM~1@}_w%8UBNPoi7HZ zTU58>;(|CUPKo!X|CSunQr>XnE95!T&b{)fZzV2Ff091!TB|x;c9V1e^6{kHvbaL)Jx-5TLSNPFKzKE8;z?PSkmoaIpM{ZxMN3_o0%yOvzC|ljE(IP`$bFKMYtoSFi1X}n8;@)%2 literal 0 HcmV?d00001 diff --git a/res/tex/heart.tex b/res/tex/heart.tex new file mode 100644 index 0000000000000000000000000000000000000000..38be8e49a8c62a48502b4406a6fcf0a8229201e1 GIT binary patch literal 262160 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%0Do)_U^zD1^g-kNs_?6aPI-b>u= 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 B_%8qe literal 0 HcmV?d00001 diff --git a/res/tex/wolf.tex b/res/tex/wolf.tex new file mode 100644 index 0000000000000000000000000000000000000000..2ffa6e4d9b8edeb8e4faf7cb158b83f5466684c9 GIT binary patch literal 1040 zcmaizy)Oh&6vcllE7=gS(P#)lBP+2I1)T<=(GXiHd?XrM5fKGZZ$jb^pwMllMxop& zB-T<0;v-Qg*idW`CJMX=j$>CHIcf=)_$1<8MwQ?yzgTfVh zBo1)L0d?Ht$XqLvEHOf-SKZK<=7~Y3RR3tv*-Op#vR|F2R`3W{)Jq)aogAyQa;p7z zd|nVRyL33y)gjNTq6`yUau{~JVtV8$b6(ui_(h{sURVxl>*uEhMVXU{+(UtW*16z= zUG;hJc|l-Pc|Y=|CyI>Al1z7W1j+n-w{)+ejUi$j^C|g7^-1&Q`T5kUpoNI^PEaH( z4x_4>6;E@j*YsA^R3^Wbnbq}%E;4M>UP%bWG4?45YfL>LDZ6k~l_LE7-24B(7CD#Q r@5!#Bq1|0&NqZZ7>!COc@*n($>I=*$$KhGOVDl};B$KBvRBH%--pYN} literal 0 HcmV?d00001