diff --git a/.clang-format b/.clang-format index 5681a5dd..105a790f 100644 --- a/.clang-format +++ b/.clang-format @@ -44,13 +44,16 @@ BreakBeforeBinaryOperators: None BreakBeforeTernaryOperators: False BreakStringLiterals: True ColumnLimit: 120 +ConstructorInitializerAllOnOneLineOrOnePerLine: true ContinuationIndentWidth: 4 +FixNamespaceComments: true IncludeBlocks: Regroup IndentAccessModifiers: False IndentCaseLabels: True IndentGotoLabels: True IndentWidth: 4 InsertBraces: True +InsertNewlineAtEOF: true KeepEmptyLinesAtTheStartOfBlocks: False MaxEmptyLinesToKeep: 1 Language: Cpp @@ -74,3 +77,37 @@ SpacesInLineCommentPrefix: SpacesInParentheses: False SpacesInSquareBrackets: False UseTab: Never +WhitespaceSensitiveMacros: [ + NW4R_UT_LINKLIST_FOREACH, + NW4R_UT_LINKLIST_FOREACH_SAFE, + NW4R_UT_LIST_FOREACH, + NW4R_UT_LIST_FOREACH_SAFE, + NW4R_EF_LIST_FOREACH, + NW4R_EF_LIST_FOREACH_SAFE +] +AttributeMacros: [DECOMP_INLINE, DECOMP_DONT_INLINE] + +# Taken from ogws :) +IncludeCategories: + - Regex: '^<(nw4r|egg|Pack)?(\/)?types' # "Types" headers + Priority: 0 + CaseSensitive: true + + - Regex: '' # EGG public headers + Priority: 2 + CaseSensitive: true + + - Regex: '' # NW4R public headers + Priority: 3 + CaseSensitive: true + + - Regex: '^' # RVL SDK public headers + Priority: 4 + CaseSensitive: true + + - Regex: '<[[:alnum:].]+>' # STL headers + Priority: 5 # Priority 0 is header mapped to src file + CaseSensitive: true + + - Regex: '.*' # All other headers + Priority: 1 diff --git a/.clangd b/.clangd index 69c978c9..50035fb5 100644 --- a/.clangd +++ b/.clangd @@ -4,5 +4,24 @@ CompileFlags: "-Wno-c++11-compat-deprecated-writable-strings", "-Wno-trigraphs", "-fno-trigraphs", - "-Wno-c++11-extensions" + "-Wno-c++11-extensions", + "-Wno-shadow", + "-Wno-register" + ] + +--- +# Fragment for suppressing some warning generated in rvl +If: + PathMatch: [ + ".*/rvl/.*", + ".*/g3d/platform/.*", + ".*/math/.*", + ] + +Diagnostics: + Suppress: [ + "unknown_typename", + "expected_unqualified_id", + "expected_semi_declaration", + "undeclared_var_use", ] diff --git a/include/d/a/d_a_player.h b/include/d/a/d_a_player.h index 9aebf254..133b09f3 100644 --- a/include/d/a/d_a_player.h +++ b/include/d/a/d_a_player.h @@ -5,7 +5,7 @@ #include "m/m_angle.h" #include "m/m_mtx.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" class dAcPy_c : public dAcObjBase_c { // See Below for some info diff --git a/include/d/a/obj/d_a_obj_appear_bridge.h b/include/d/a/obj/d_a_obj_appear_bridge.h index 69278e8b..ee8d986d 100644 --- a/include/d/a/obj/d_a_obj_appear_bridge.h +++ b/include/d/a/obj/d_a_obj_appear_bridge.h @@ -6,7 +6,7 @@ #include "m/m3d/m_anmmatclr.h" #include "m/m3d/m_anmtexsrt.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "toBeSorted/actor_event.h" #include "toBeSorted/stage_render_stuff.h" diff --git a/include/d/a/obj/d_a_obj_arrow.h b/include/d/a/obj/d_a_obj_arrow.h index 2cfb6b47..8bedda03 100644 --- a/include/d/a/obj/d_a_obj_arrow.h +++ b/include/d/a/obj/d_a_obj_arrow.h @@ -6,7 +6,7 @@ #include "d/col/c/c_cc_d.h" #include "d/col/cc/d_cc_d.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateID.hpp" #include "toBeSorted/effects_struct.h" diff --git a/include/d/a/obj/d_a_obj_bamboo_island.h b/include/d/a/obj/d_a_obj_bamboo_island.h index 959063b9..1c77a7e1 100644 --- a/include/d/a/obj/d_a_obj_bamboo_island.h +++ b/include/d/a/obj/d_a_obj_bamboo_island.h @@ -4,7 +4,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "d/col/bg/d_bg_w.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" class dAcObambooIsland_c : public dAcObjBase_c { public: diff --git a/include/d/a/obj/d_a_obj_bomb.h b/include/d/a/obj/d_a_obj_bomb.h index ce545e52..e82b3743 100644 --- a/include/d/a/obj/d_a_obj_bomb.h +++ b/include/d/a/obj/d_a_obj_bomb.h @@ -10,7 +10,7 @@ #include "d/d_shadow.h" #include "m/m3d/m_smdl.h" #include "m/m_mtx.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateID.hpp" #include "toBeSorted/effects_struct.h" diff --git a/include/d/a/obj/d_a_obj_island_nusi.h b/include/d/a/obj/d_a_obj_island_nusi.h index 29b139f7..8cb26c77 100644 --- a/include/d/a/obj/d_a_obj_island_nusi.h +++ b/include/d/a/obj/d_a_obj_island_nusi.h @@ -4,7 +4,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "d/col/bg/d_bg_w.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateMgr.hpp" diff --git a/include/d/a/obj/d_a_obj_junk_repairing.h b/include/d/a/obj/d_a_obj_junk_repairing.h index 9ae52e53..44bb607b 100644 --- a/include/d/a/obj/d_a_obj_junk_repairing.h +++ b/include/d/a/obj/d_a_obj_junk_repairing.h @@ -4,7 +4,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "m/m3d/m_shadow.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" class dMyShadowCircle_c : public m3d::mShadowCircle_c {}; diff --git a/include/d/a/obj/d_a_obj_lava_F200.h b/include/d/a/obj/d_a_obj_lava_F200.h index 40ea3ece..60c6cbf1 100644 --- a/include/d/a/obj/d_a_obj_lava_F200.h +++ b/include/d/a/obj/d_a_obj_lava_F200.h @@ -5,7 +5,7 @@ #include "m/m3d/m_anmmatclr.h" #include "m/m3d/m_anmtexsrt.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" class dAcOlavaF200_c : public dAcObjBase_c { public: diff --git a/include/d/a/obj/d_a_obj_megami_island.h b/include/d/a/obj/d_a_obj_megami_island.h index 6fd85f53..e5cadf70 100644 --- a/include/d/a/obj/d_a_obj_megami_island.h +++ b/include/d/a/obj/d_a_obj_megami_island.h @@ -5,7 +5,7 @@ #include "d/col/bg/d_bg_w.h" #include "m/m3d/m_anmtexsrt.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" class dAcOmegamiIsland_c : public dAcObjBase_c { public: diff --git a/include/d/a/obj/d_a_obj_mole_soil.h b/include/d/a/obj/d_a_obj_mole_soil.h index 41ce6361..f52fb85c 100644 --- a/include/d/a/obj/d_a_obj_mole_soil.h +++ b/include/d/a/obj/d_a_obj_mole_soil.h @@ -3,7 +3,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" class dAcOmoleSoil_c : public dAcObjBase_c { diff --git a/include/d/a/obj/d_a_obj_pool_cock.h b/include/d/a/obj/d_a_obj_pool_cock.h index 941cdfa3..51639126 100644 --- a/include/d/a/obj/d_a_obj_pool_cock.h +++ b/include/d/a/obj/d_a_obj_pool_cock.h @@ -3,7 +3,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" class dAcOPoolCock_c : public dAcObjBase_c { diff --git a/include/d/a/obj/d_a_obj_pumpkin_leaf.h b/include/d/a/obj/d_a_obj_pumpkin_leaf.h index f22c2e44..5f96099a 100644 --- a/include/d/a/obj/d_a_obj_pumpkin_leaf.h +++ b/include/d/a/obj/d_a_obj_pumpkin_leaf.h @@ -3,7 +3,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" class dAcOPumpkinLeaf_c : public dAcObjBase_c { diff --git a/include/d/a/obj/d_a_obj_seat_sword.h b/include/d/a/obj/d_a_obj_seat_sword.h index a4650f03..ec74ab45 100644 --- a/include/d/a/obj/d_a_obj_seat_sword.h +++ b/include/d/a/obj/d_a_obj_seat_sword.h @@ -10,7 +10,7 @@ #include "m/m3d/m_smdl.h" #include "m/m_mtx.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "nw4r/math/math_types.h" #include "rvl/MTX/mtx.h" #include "s/s_State.hpp" diff --git a/include/d/a/obj/d_a_obj_smoke.h b/include/d/a/obj/d_a_obj_smoke.h index 9cd943c6..cb833878 100644 --- a/include/d/a/obj/d_a_obj_smoke.h +++ b/include/d/a/obj/d_a_obj_smoke.h @@ -4,7 +4,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "m/m3d/m_anmtexsrt.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" class dAcOsmoke_c : public dAcObjBase_c { diff --git a/include/d/a/obj/d_a_obj_spike.h b/include/d/a/obj/d_a_obj_spike.h index 2dace343..783152ab 100644 --- a/include/d/a/obj/d_a_obj_spike.h +++ b/include/d/a/obj/d_a_obj_spike.h @@ -5,7 +5,7 @@ #include "d/col/cc/d_cc_d.h" #include "m/m3d/m_smdl.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateID.hpp" diff --git a/include/d/a/obj/d_a_obj_stage_cover.h b/include/d/a/obj/d_a_obj_stage_cover.h index 086c4e26..e7c07e82 100644 --- a/include/d/a/obj/d_a_obj_stage_cover.h +++ b/include/d/a/obj/d_a_obj_stage_cover.h @@ -3,7 +3,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" class dAcOstageCover_c : public dAcObjBase_c { diff --git a/include/d/a/obj/d_a_obj_sun_light.h b/include/d/a/obj/d_a_obj_sun_light.h index c3c0c8e5..7c0b52ef 100644 --- a/include/d/a/obj/d_a_obj_sun_light.h +++ b/include/d/a/obj/d_a_obj_sun_light.h @@ -4,7 +4,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "m/m3d/m_anmtexsrt.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" class dAcOsunLight_c : public dAcObjBase_c { diff --git a/include/d/a/obj/d_a_obj_time_stage_bg.h b/include/d/a/obj/d_a_obj_time_stage_bg.h index 2a63d002..7f7afeb5 100644 --- a/include/d/a/obj/d_a_obj_time_stage_bg.h +++ b/include/d/a/obj/d_a_obj_time_stage_bg.h @@ -5,7 +5,7 @@ #include "m/m3d/m_anmmatclr.h" #include "m/m3d/m_smdl.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateMgr.hpp" #include "toBeSorted/stage_render_stuff.h" diff --git a/include/d/a/obj/d_a_obj_toD3_stone_figure.h b/include/d/a/obj/d_a_obj_toD3_stone_figure.h index c796b92e..9c7e1819 100644 --- a/include/d/a/obj/d_a_obj_toD3_stone_figure.h +++ b/include/d/a/obj/d_a_obj_toD3_stone_figure.h @@ -5,7 +5,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "d/col/cc/d_cc_d.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateMgr.hpp" diff --git a/include/d/a/obj/d_a_obj_tower_gearD101.h b/include/d/a/obj/d_a_obj_tower_gearD101.h index 83383c4c..d77b665a 100644 --- a/include/d/a/obj/d_a_obj_tower_gearD101.h +++ b/include/d/a/obj/d_a_obj_tower_gearD101.h @@ -7,7 +7,7 @@ #include "m/m_angle.h" #include "m/m_mtx.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "toBeSorted/effects_struct.h" @@ -31,8 +31,10 @@ public: class dAcOTowerGearD101_c : public dAcObjBase_c { public: dAcOTowerGearD101_c() - : mStateMgr(*this, sStateID::null), field_0x3A0(mVec3_c::Zero.x, mVec3_c::Zero.y, mVec3_c::Zero.z), - field_0x3AC(mVec3_c::Zero.x, mVec3_c::Zero.y, mVec3_c::Zero.z), field_0x3B8(mAng3_c::Zero) {} + : mStateMgr(*this, sStateID::null), + field_0x3A0(mVec3_c::Zero.x, mVec3_c::Zero.y, mVec3_c::Zero.z), + field_0x3AC(mVec3_c::Zero.x, mVec3_c::Zero.y, mVec3_c::Zero.z), + field_0x3B8(mAng3_c::Zero) {} virtual ~dAcOTowerGearD101_c() {} STATE_FUNC_DECLARE(dAcOTowerGearD101_c, Wait); diff --git a/include/d/a/obj/d_a_obj_trap_rock_1.h b/include/d/a/obj/d_a_obj_trap_rock_1.h index c0da852e..1a25d6de 100644 --- a/include/d/a/obj/d_a_obj_trap_rock_1.h +++ b/include/d/a/obj/d_a_obj_trap_rock_1.h @@ -4,7 +4,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "d/col/bg/d_bg_w.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateMgr.hpp" diff --git a/include/d/a/obj/d_a_obj_triforce.h b/include/d/a/obj/d_a_obj_triforce.h index eab787bb..ac134bef 100644 --- a/include/d/a/obj/d_a_obj_triforce.h +++ b/include/d/a/obj/d_a_obj_triforce.h @@ -7,7 +7,7 @@ #include "m/m3d/m_anmtexsrt.h" #include "m/m3d/m_smdl.h" #include "m/m_angle.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "toBeSorted/effects_struct.h" class dAcOtriforce_c : public dAcObjBase_c { diff --git a/include/d/a/obj/d_a_obj_tubo.h b/include/d/a/obj/d_a_obj_tubo.h index fc027e78..582886e2 100644 --- a/include/d/a/obj/d_a_obj_tubo.h +++ b/include/d/a/obj/d_a_obj_tubo.h @@ -13,7 +13,7 @@ #include "m/m3d/m_smdl.h" #include "m/m_quat.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "toBeSorted/effects_struct.h" diff --git a/include/d/a/obj/d_a_obj_tumble_weed.h b/include/d/a/obj/d_a_obj_tumble_weed.h index 21cefe41..5e7d5ccd 100644 --- a/include/d/a/obj/d_a_obj_tumble_weed.h +++ b/include/d/a/obj/d_a_obj_tumble_weed.h @@ -10,7 +10,7 @@ #include "m/m_mtx.h" #include "m/m_quat.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "toBeSorted/dowsing_target.h" #include "toBeSorted/time_area_mgr.h" diff --git a/include/d/a/obj/d_a_obj_underground_switch.h b/include/d/a/obj/d_a_obj_underground_switch.h index a52084b7..ab55c4a7 100644 --- a/include/d/a/obj/d_a_obj_underground_switch.h +++ b/include/d/a/obj/d_a_obj_underground_switch.h @@ -4,8 +4,8 @@ #include "d/a/obj/d_a_obj_base.h" #include "m/m3d/m_anmmatclr.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" #include "s/s_State.hpp" class dAcOUgSwitch_c : public dAcObjBase_c { diff --git a/include/d/a/obj/d_a_obj_uta_demo_pedest.h b/include/d/a/obj/d_a_obj_uta_demo_pedest.h index 596b2bad..1987f78e 100644 --- a/include/d/a/obj/d_a_obj_uta_demo_pedest.h +++ b/include/d/a/obj/d_a_obj_uta_demo_pedest.h @@ -3,7 +3,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" class dAcOutaDemoPedest_c : public dAcObjBase_c { public: diff --git a/include/d/a/obj/d_a_obj_utajima.h b/include/d/a/obj/d_a_obj_utajima.h index b21b1e9a..0374cc12 100644 --- a/include/d/a/obj/d_a_obj_utajima.h +++ b/include/d/a/obj/d_a_obj_utajima.h @@ -5,7 +5,7 @@ #include "d/col/bg/d_bg_w.h" #include "m/m3d/m_smdl.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" class dAcOutajima_c : public dAcObjBase_c { public: @@ -19,7 +19,6 @@ public: virtual int draw() override; private: - static void rideCallback(dBgW *, dAcObjBase_c *, dAcObjBase_c *); m3d::smdl_c mMdls[2]; diff --git a/include/d/a/obj/d_a_obj_utajima_island.h b/include/d/a/obj/d_a_obj_utajima_island.h index d4222b48..604bdbd9 100644 --- a/include/d/a/obj/d_a_obj_utajima_island.h +++ b/include/d/a/obj/d_a_obj_utajima_island.h @@ -8,7 +8,7 @@ #include "m/m3d/m_smdl.h" #include "m/m_angle.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateMgr.hpp" diff --git a/include/d/a/obj/d_a_obj_utajima_lv2.h b/include/d/a/obj/d_a_obj_utajima_lv2.h index 3bfc8ee4..b5212341 100644 --- a/include/d/a/obj/d_a_obj_utajima_lv2.h +++ b/include/d/a/obj/d_a_obj_utajima_lv2.h @@ -4,7 +4,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "d/col/bg/d_bg_w.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" class dAcOutajimaLv2_c : public dAcObjBase_c { public: diff --git a/include/d/a/obj/d_a_obj_water_shield.h b/include/d/a/obj/d_a_obj_water_shield.h index fe5780a2..f47d093d 100644 --- a/include/d/a/obj/d_a_obj_water_shield.h +++ b/include/d/a/obj/d_a_obj_water_shield.h @@ -6,7 +6,7 @@ #include "m/m3d/m_anmmatclr.h" #include "m/m3d/m_anmtexsrt.h" #include "m/m3d/m_smdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "toBeSorted/stage_render_stuff.h" class dAcOwaterShield_c : public dAcObjBase_c { diff --git a/include/d/a/obj/d_a_obj_water_spout.h b/include/d/a/obj/d_a_obj_water_spout.h index c0faf6e8..345e1325 100644 --- a/include/d/a/obj/d_a_obj_water_spout.h +++ b/include/d/a/obj/d_a_obj_water_spout.h @@ -5,7 +5,7 @@ #include "m/m3d/m_anmmatclr.h" #include "m/m3d/m_anmmdl.h" #include "m/m3d/m_anmtexsrt.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateMgr.hpp" diff --git a/include/m/m3d/m_anmchr.h b/include/m/m3d/m_anmchr.h index 0c7e7361..49444ea6 100644 --- a/include/m/m3d/m_anmchr.h +++ b/include/m/m3d/m_anmchr.h @@ -3,7 +3,7 @@ #include "m/m3d/m_bmdl.h" #include "m/m3d/m_fanm.h" -#include "nw4r/g3d/g3d_resanmchr.h" +#include "nw4r/g3d/res/g3d_resanmchr.h" namespace m3d { diff --git a/include/m/m3d/m_anmmdl.h b/include/m/m3d/m_anmmdl.h index cf81f560..6029234d 100644 --- a/include/m/m3d/m_anmmdl.h +++ b/include/m/m3d/m_anmmdl.h @@ -3,7 +3,7 @@ #include "m/m3d/m_anmchr.h" #include "m/m3d/m_mdl.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" namespace m3d { diff --git a/include/m/m3d/m_anmshp.h b/include/m/m3d/m_anmshp.h index e7c45ee0..2a201399 100644 --- a/include/m/m3d/m_anmshp.h +++ b/include/m/m3d/m_anmshp.h @@ -4,7 +4,7 @@ #include "common.h" #include "m/m3d/m_bmdl.h" #include "m/m3d/m_fanm.h" -#include "nw4r/g3d/g3d_resanmshp.h" +#include "nw4r/g3d/res/g3d_resanmshp.h" namespace m3d { diff --git a/include/m/m3d/m_mdl.h b/include/m/m3d/m_mdl.h index 646966f3..b2585738 100644 --- a/include/m/m3d/m_mdl.h +++ b/include/m/m3d/m_mdl.h @@ -6,7 +6,7 @@ #include "m/m3d/m_smdl.h" #include "nw4r/g3d/g3d_anmchr.h" #include "nw4r/g3d/g3d_calcworld.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resmdl.h" namespace m3d { diff --git a/include/m/m3d/m_smdl.h b/include/m/m3d/m_smdl.h index f4854389..3d9f9741 100644 --- a/include/m/m3d/m_smdl.h +++ b/include/m/m3d/m_smdl.h @@ -3,7 +3,7 @@ #include "m/m3d/m_bmdl.h" #include "m/m3d/m_scnleaf.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d.h" // IWYU pragma: export class UnkClass2 {}; diff --git a/include/nw4r/g3d.h b/include/nw4r/g3d.h new file mode 100644 index 00000000..16df4b85 --- /dev/null +++ b/include/nw4r/g3d.h @@ -0,0 +1,81 @@ +#ifndef NW4R_PUBLIC_G3D_H +#define NW4R_PUBLIC_G3D_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/****************************************************************************** + * + * Resources + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/****************************************************************************** + * + * Platform-specific + * + ******************************************************************************/ + +#include +#include +#include +#include + +#endif diff --git a/include/nw4r/g3d/g3d_3dsmax.h b/include/nw4r/g3d/g3d_3dsmax.h index 220e4d09..2affb665 100644 --- a/include/nw4r/g3d/g3d_3dsmax.h +++ b/include/nw4r/g3d/g3d_3dsmax.h @@ -1,15 +1,17 @@ #ifndef NW4R_G3D_3DSMAX_H #define NW4R_G3D_3DSMAX_H -#include "common.h" -#include "nw4r/g3d/g3d_anmtexsrt.h" -#include "nw4r/math.h" +#include + +#include namespace nw4r { namespace g3d { namespace detail { namespace dcc { -bool CalcTexMtx_3dsmax(math::MTX34 *, bool, const TexSrt &, TexSrt::Flag); -} + +bool CalcTexMtx_3dsmax(math::MTX34 *pMtx, bool set, const TexSrt &rSrt, TexSrt::Flag flag); + +} // namespace dcc } // namespace detail } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_anmchr.h b/include/nw4r/g3d/g3d_anmchr.h index 49cc40c8..c322f8be 100644 --- a/include/nw4r/g3d/g3d_anmchr.h +++ b/include/nw4r/g3d/g3d_anmchr.h @@ -1,90 +1,208 @@ -#ifndef NW4R_G3D_ANMCHR_H -#define NW4R_G3D_ANMCHR_H -#include "common.h" -#include "nw4r/g3d/g3d_anmobj.h" -#include "nw4r/math/math_types.h" +#ifndef NW4R_G3D_ANM_CHR_H +#define NW4R_G3D_ANM_CHR_H +#include + +#include +#include namespace nw4r { namespace g3d { -struct ChrAnmResult { - u32 mFlags; // at 0x0 - math::VEC3 VEC3_0x4; - math::VEC3 VEC3_0x10; - math::MTX34 mMtx; // at 0x1C -}; +/****************************************************************************** + * + * AnmObjChr + * + ******************************************************************************/ +// Forward declarations class AnmObjChrRes; class AnmObjChr : public AnmObj { public: + enum BindOption { + BIND_ONE, + BIND_PARTIAL, + NUM_OF_BIND_OPTION + }; - enum BindOption {}; +public: + AnmObjChr(MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding); + virtual void G3dProc(u32 task, u32 param, void *pInfo) = 0; // at 0xC + virtual ~AnmObjChr() {} // at 0x10 - static const TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); + virtual void SetFrame(f32 frame) = 0; // at 0x1C + virtual f32 GetFrame() const = 0; // at 0x20 + virtual void UpdateFrame() = 0; // at 0x24 + + virtual void SetUpdateRate(f32 rate) = 0; // at 0x28 + virtual f32 GetUpdateRate() const = 0; // at 0x2C + + virtual bool Bind(const ResMdl mdl) = 0; // at 0x30 + virtual void Release(); // at 0x34 + + virtual const ChrAnmResult *GetResult(ChrAnmResult *pResult, + u32 idx) = 0; // at 0x38 + + virtual AnmObjChrRes *Attach(int idx, AnmObjChrRes *pRes); // at 0x3C + virtual AnmObjChrRes *Detach(int idx); // at 0x40 + virtual void DetachAll(); // at 0x44 + + virtual void SetWeight(int idx, f32 weight); // at 0x48 + virtual f32 GetWeight(int idx) const; // at 0x4C + + virtual bool Bind(const ResMdl mdl, u32 target, + BindOption option) = 0; // at 0x50 + virtual void Release(const ResMdl mdl, u32 target, + BindOption option) = 0; // at 0x54 + + bool TestExistence(u32 idx) const; + bool TestDefined(u32 idx) const; + + void UseQuaternionBlend(bool enable) { + SetAnmFlag(FLAG_USE_QUATERNION_ROTATION_BLEND, enable); } - virtual ChrAnmResult *GetResult(ChrAnmResult *, u32); // at 0x38 - virtual void Attach(int, AnmObjChrRes*); // at 0x3C - virtual void Detach(int); // at 0x40 - virtual void DetachAll(); // at 0x44 - virtual void SetWeight(int, f32); // at 0x48 - virtual f32 GetWeight(int) const; // at 0x4C - virtual void Bind(ResMdl, u32, BindOption) = 0; // at 0x50 - virtual void Release(ResMdl, u32, BindOption) = 0; // at 0x54 - -private: - UNKWORD field_0x10; - UNKWORD field_0x14; + void UseAccurateScaleBlend(bool enable) { + SetAnmFlag(FLAG_USE_ACCURATE_SCALE_BLEND, enable); + } protected: - NW4R_G3D_TYPE_OBJ_DECL(AnmObjChr); + enum BindingFlag { + BINDING_ID_MASK = (1 << 14) - 1, + BINDING_INVALID = (1 << 14), + BINDING_UNDEFINED = (1 << 15), + }; + +protected: + static const int DEFAULT_MAX_CHILDREN = 4; + +protected: + int mNumBinding; // at 0x10 + u16 *const mpBinding; // at 0x14 + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjChr, AnmObj); }; +/****************************************************************************** + * + * AnmObjChrNode + * + ******************************************************************************/ class AnmObjChrNode : public AnmObjChr { public: - static const TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } + AnmObjChrNode( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjChrRes **ppChildrenBuf, int numChildren + ); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~AnmObjChrNode(); // at 0x10 + + virtual void SetFrame(f32 frame); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 + + virtual void SetUpdateRate(f32 rate); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C + + virtual bool Bind(const ResMdl mdl); // at 0x30 + virtual void Release(); // at 0x34 + + virtual AnmObjChrRes *Attach(int idx, AnmObjChrRes *pRes); // at 0x3C + virtual AnmObjChrRes *Detach(int idx); // at 0x40 + virtual void DetachAll(); // at 0x44 + + virtual bool Bind(const ResMdl mdl, u32 target, + BindOption option); // at 0x50 + virtual void Release(const ResMdl mdl, u32 target, + BindOption option); // at 0x54 inline int Size() { - return mNodeArraySize; + return mChildrenArraySize; } AnmObjChrRes *GetNode(int i) { - return mpNodes[i]; + return mpChildrenArray[i]; + } + +protected: + int mChildrenArraySize; // at 0x18 + AnmObjChrRes **mpChildrenArray; // at 0x1C + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjChrNode, AnmObjChr); +}; + +/****************************************************************************** + * + * AnmObjChrBlend + * + ******************************************************************************/ +class AnmObjChrBlend : public AnmObjChrNode { +public: + static AnmObjChrBlend *Construct(MEMAllocator *pAllocator, u32 *pSize, ResMdl mdl, int numChildren); + + AnmObjChrBlend( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjChrRes **ppChildrenBuf, int numChildren, + f32 *pWeightBuf + ); + + virtual ~AnmObjChrBlend() {} // at 0x10 + + virtual const ChrAnmResult *GetResult(ChrAnmResult *pResult, + u32 idx); // at 0x38 + + virtual void SetWeight(int idx, f32 weight); // at 0x48 + virtual f32 GetWeight(int idx) const; // at 0x4C + +private: + f32 *mpWeightArray; // at 0x20 + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjChrBlend, AnmObjChrNode); +}; + +/****************************************************************************** + * + * AnmObjChrRes + * + ******************************************************************************/ +class AnmObjChrRes : public AnmObjChr, protected FrameCtrl { +public: + static AnmObjChrRes *Construct(MEMAllocator *pAllocator, u32 *pSize, ResAnmChr chr, ResMdl mdl, bool cache); + + AnmObjChrRes(MEMAllocator *pAllocator, ResAnmChr chr, u16 *pBindingBuf, int numBinding, ChrAnmResult *pCacheBuf); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~AnmObjChrRes() {} // at 0x10 + + virtual void SetFrame(f32 frame); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 + + virtual void SetUpdateRate(f32 rate); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C + + virtual bool Bind(const ResMdl mdl); // at 0x30 + using AnmObjChr::Release; // at 0x40 + + virtual const ChrAnmResult *GetResult(ChrAnmResult *pResult, + u32 idx); // at 0x38 + + virtual bool Bind(const ResMdl mdl, u32 target, + BindOption option); // at 0x50 + virtual void Release(const ResMdl mdl, u32 target, + BindOption option); // at 0x54 + + void UpdateCache(); + + ResAnmChr GetResAnm() { + return mRes; + } + + void SetPlayPolicy(PlayPolicyFunc pFunc) { + FrameCtrl::SetPlayPolicy(pFunc); } private: - int mNodeArraySize; - AnmObjChrRes **mpNodes; + ResAnmChr mRes; // at 0x2C + ChrAnmResult *const mpResultCache; // at 0x30 -protected: - NW4R_G3D_TYPE_OBJ_DECL(AnmObjChrNode); -}; - -class AnmObjChrBlend : public AnmObjChrNode { -public: - static const TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } - - static AnmObjChrBlend *Construct(MEMAllocator*, u32*, ResMdl, int); - -protected: - NW4R_G3D_TYPE_OBJ_DECL(AnmObjChrBlend); -}; - -class AnmObjChrRes : public AnmObjChr, public FrameCtrl { -public: - static const TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } - - static AnmObjChrRes *Construct(MEMAllocator*, u32*, ResAnmChr, ResMdl, bool); - -protected: - NW4R_G3D_TYPE_OBJ_DECL(AnmObjChrRes); + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjChrRes, AnmObjChr); }; } // namespace g3d diff --git a/include/nw4r/g3d/g3d_anmclr.h b/include/nw4r/g3d/g3d_anmclr.h index 892abe70..b1fc9a6d 100644 --- a/include/nw4r/g3d/g3d_anmclr.h +++ b/include/nw4r/g3d/g3d_anmclr.h @@ -1,83 +1,167 @@ -#ifndef NW4R_G3D_ANMCLR_H -#define NW4R_G3D_ANMCLR_H -#include "common.h" -#include "nw4r/g3d/g3d_anmobj.h" -#include "nw4r/g3d/g3d_resanmclr.h" +#ifndef NW4R_G3D_ANM_CLR_H +#define NW4R_G3D_ANM_CLR_H +#include + +#include +#include +#include namespace nw4r { namespace g3d { -struct ClrAnmResult { - enum { ANM_COUNT = 11 }; - u32 mFlags; // at 0x0 - u32 COLORS_0x4[ANM_COUNT]; - UNKWORD WORDS_0x30[ANM_COUNT]; -}; +void ApplyClrAnmResult(ResMatChan chan, ResMatTevColor tev, const ClrAnmResult *pResult); +/****************************************************************************** + * + * AnmObjMatClr + * + ******************************************************************************/ +// Forward declarations class AnmObjMatClrRes; class AnmObjMatClr : public AnmObj { public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } + AnmObjMatClr(MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding); + virtual void G3dProc(u32 task, u32 param, void *pInfo) = 0; // at 0xC + virtual ~AnmObjMatClr() {} // at 0x10 - virtual ClrAnmResult *GetResult(); // at 0x38 - virtual void Attach(s32, AnmObjMatClrRes *res); // at 0x3C - virtual void Detach(s32); // at 0x40 + virtual void SetFrame(f32 frame) = 0; // at 0x1C + virtual f32 GetFrame() const = 0; // at 0x20 + virtual void UpdateFrame() = 0; // at 0x24 -private: - int mChildrenArraySize; - u16 *mpChildrenArray; + virtual void SetUpdateRate(f32 rate) = 0; // at 0x28 + virtual f32 GetUpdateRate() const = 0; // at 0x2C - NW4R_G3D_TYPE_OBJ_DECL(AnmObjMatClr); + virtual bool Bind(const ResMdl mdl) = 0; // at 0x30 + virtual void Release(); // at 0x34 + + virtual const ClrAnmResult *GetResult(ClrAnmResult *pResult, + u32 idx) = 0; // at 0x38 + + virtual AnmObjMatClrRes *Attach(int idx, AnmObjMatClrRes *pRes); // at 0x3C + virtual AnmObjMatClrRes *Detach(int idx); // at 0x40 + virtual void DetachAll(); // at 0x44 + + bool TestExistence(u32 idx) const; + bool TestDefined(u32 idx) const; + +protected: + enum BindingFlag { + BINDING_ID_MASK = (1 << 14) - 1, + BINDING_INVALID = (1 << 14), + BINDING_UNDEFINED = (1 << 15), + }; + +protected: + static const int DEFAULT_MAX_CHILDREN = 4; + +protected: + int mNumBinding; // at 0x10 + u16 *const mpBinding; // at 0x14 + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjMatClr, AnmObj); }; +/****************************************************************************** + * + * AnmObjMatClrNode + * + ******************************************************************************/ class AnmObjMatClrNode : public AnmObjMatClr { public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); + AnmObjMatClrNode( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjMatClrRes **ppChildrenBuf, int numChildren + ); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~AnmObjMatClrNode(); // at 0x10 + + virtual void SetFrame(f32 frame); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 + + virtual void SetUpdateRate(f32 rate); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C + + virtual bool Bind(const ResMdl mdl); // at 0x30 + virtual void Release(); // at 0x34 + + virtual AnmObjMatClrRes *Attach(int idx, AnmObjMatClrRes *pRes); // at 0x3C + virtual AnmObjMatClrRes *Detach(int idx); // at 0x40 + virtual void DetachAll(); // at 0x44 + + int Size() const { + return mChildrenArraySize; } - inline int Size() { - return mNodeArraySize; - } +protected: + int mChildrenArraySize; // at 0x18 + AnmObjMatClrRes **mpChildrenArray; // at 0x1C - AnmObjMatClrRes *GetNode(int i) { - return mpNodes[i]; - } - -private: - int mNodeArraySize; - AnmObjMatClrRes **mpNodes; - - NW4R_G3D_TYPE_OBJ_DECL(AnmObjMatClrNode); -}; - -class AnmObjMatClrRes : public AnmObjMatClr, public FrameCtrl { -public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } - - static AnmObjMatClrRes *Construct(MEMAllocator *, u32 *, ResAnmClr, ResMdl, bool); - -private: - ResAnmClr mRes; - TexSrtAnmResult *mpResultCache; - - NW4R_G3D_TYPE_OBJ_DECL(AnmObjMatClrRes); + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjMatClrNode, AnmObjMatClr); }; +/****************************************************************************** + * + * AnmObjMatClrOverride + * + ******************************************************************************/ class AnmObjMatClrOverride : public AnmObjMatClrNode { public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); + static AnmObjMatClrOverride *Construct(MEMAllocator *pAllocator, u32 *pSize, ResMdl mdl, int numChildren); + + AnmObjMatClrOverride( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjMatClrRes **ppChildrenBuf, int numChildren + ) + : AnmObjMatClrNode(pAllocator, pBindingBuf, numBinding, ppChildrenBuf, numChildren) {} + + virtual ~AnmObjMatClrOverride() {} // at 0x10 + + virtual const ClrAnmResult *GetResult(ClrAnmResult *pResult, + u32 idx); // at 0x38 + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjMatClrOverride, AnmObjMatClrNode); +}; + +/****************************************************************************** + * + * AnmObjMatClrRes + * + ******************************************************************************/ +class AnmObjMatClrRes : public AnmObjMatClr, protected FrameCtrl { +public: + static AnmObjMatClrRes *Construct(MEMAllocator *pAllocator, u32 *pSize, ResAnmClr clr, ResMdl mdl, bool cache); + + AnmObjMatClrRes(MEMAllocator *pAllocator, ResAnmClr clr, u16 *pBindingBuf, int numBinding, ClrAnmResult *pCacheBuf); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~AnmObjMatClrRes() {} // at 0x10 + + virtual void SetFrame(f32 frame); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 + + virtual void SetUpdateRate(f32 rate); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C + + virtual bool Bind(const ResMdl mdl); // at 0x30 + + virtual const ClrAnmResult *GetResult(ClrAnmResult *pResult, + u32 idx); // at 0x38 + + void UpdateCache(); + + ResAnmClr GetResAnm() { + return mRes; } - static AnmObjMatClrOverride *Construct(MEMAllocator *, u32 *, ResMdl, int); + void SetPlayPolicy(PlayPolicyFunc pFunc) { + FrameCtrl::SetPlayPolicy(pFunc); + } - NW4R_G3D_TYPE_OBJ_DECL(AnmObjMatClrOverride); +private: + ResAnmClr mRes; // at 0x2C + ClrAnmResult *const mpResultCache; // at 0x30 + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjMatClrRes, AnmObjMatClr); }; } // namespace g3d diff --git a/include/nw4r/g3d/g3d_anmobj.h b/include/nw4r/g3d/g3d_anmobj.h index 7fb62f1e..9020c6c4 100644 --- a/include/nw4r/g3d/g3d_anmobj.h +++ b/include/nw4r/g3d/g3d_anmobj.h @@ -1,102 +1,113 @@ -#ifndef NW4R_G3D_ANMOBJ_H -#define NW4R_G3D_ANMOBJ_H -#include "common.h" -#include "nw4r/g3d/g3d_obj.h" -#include "nw4r/g3d/g3d_rescommon.h" -#include "nw4r/g3d/g3d_resmdl.h" +#ifndef NW4R_G3D_ANM_OBJ_H +#define NW4R_G3D_ANM_OBJ_H +#include + +#include +#include namespace nw4r { namespace g3d { -enum AnmPolicy { ANM_POLICY_ONETIME, ANM_POLICY_LOOP, ANM_POLICY_MAX }; -typedef f32 (*PlayPolicyFunc)(f32, f32, f32); -f32 PlayPolicy_Onetime(f32, f32, f32); -f32 PlayPolicy_Loop(f32, f32, f32); +/****************************************************************************** + * + * AnmObj + * + ******************************************************************************/ +class AnmObj : public G3dObj { + NW4R_G3D_RTTI_DECL_DERIVED(AnmObj, G3dObj); + +public: + enum AnmFlag { + FLAG_NEED_UPDATE = (1 << 0), + FLAG_CACHE_OBSOLETE = (1 << 1), + FLAG_ANM_BOUND = (1 << 2), + FLAG_USE_QUATERNION_ROTATION_BLEND = (1 << 3), + FLAG_USE_ACCURATE_SCALE_BLEND = (1 << 4) + }; + +public: + AnmObj(MEMAllocator *pAllocator, G3dObj *pParent) : G3dObj(pAllocator, pParent), mFlags(0) {} + + virtual void G3dProc(u32 task, u32 param, void *pInfo) = 0; // at 0xC + virtual ~AnmObj() {} // at 0x10 + + virtual void SetFrame(f32 frame) = 0; // at 0x1C + virtual f32 GetFrame() const = 0; // at 0x20 + virtual void UpdateFrame() = 0; // at 0x24 + + virtual void SetUpdateRate(f32 rate) = 0; // at 0x28 + virtual f32 GetUpdateRate() const = 0; // at 0x2C + + virtual bool Bind(const ResMdl mdl) = 0; // at 0x30 + virtual void Release(); // at 0x34 + + void SetAnmFlag(AnmFlag flag, bool value); + bool TestAnmFlag(AnmFlag flag) const; + + bool IsBound() const { + return TestAnmFlag(FLAG_ANM_BOUND); + } + +private: + u32 mFlags; // at 0xC +}; + +/****************************************************************************** + * + * PlayPolicy + * + ******************************************************************************/ +f32 PlayPolicy_Onetime(f32 start, f32 end, f32 frame); +f32 PlayPolicy_Loop(f32 start, f32 end, f32 frame); + +typedef f32 (*PlayPolicyFunc)(f32 start, f32 end, f32 frame); inline PlayPolicyFunc GetAnmPlayPolicy(AnmPolicy policy) { static PlayPolicyFunc policyTable[ANM_POLICY_MAX] = {PlayPolicy_Onetime, PlayPolicy_Loop}; return policyTable[policy]; } -struct FrameCtrl { - FrameCtrl(f32 f1, f32 f2, PlayPolicyFunc policy) - : mFrame(0.0f), mRate(1.0f), FLOAT_0x8(f1), mEndFrame(f2), mPolicy(policy) {} +/****************************************************************************** + * + * FrameCtrl + * + ******************************************************************************/ +class FrameCtrl { +public: + FrameCtrl(f32 start, f32 end, PlayPolicyFunc pPolicy) + : mFrame(0.0f), mUpdateRate(1.0f), mStartFrame(start), mEndFrame(end), mpPlayPolicy(pPolicy) {} f32 GetFrm() const { return mFrame; } + void SetFrm(f32 frame) { + mFrame = mpPlayPolicy(mStartFrame, mEndFrame, frame); + } + void UpdateFrm() { + SetFrm(mUpdateRate * smBaseUpdateRate + mFrame); + } f32 GetRate() const { - return mRate; + return mUpdateRate; } - - void SetFrm(f32 frm) { - f32 newFrm = mPolicy(FLOAT_0x8, mEndFrame, frm); - mFrame = newFrm; - } - void SetRate(f32 rate) { - mRate = rate; + mUpdateRate = rate; } - void SetPolicy(PlayPolicyFunc func) { - mPolicy = func; + void SetPlayPolicy(PlayPolicyFunc func) { + mpPlayPolicy = func; } - void UpdateFrm() { - SetFrm(mFrame + mRate * smBaseUpdateRate); - } - - f32 mFrame; // at 0x0 - f32 mRate; // at 0x4 - f32 FLOAT_0x8; - f32 mEndFrame; - PlayPolicyFunc mPolicy; // at 0x10 +private: + f32 mFrame; // at 0x0 + f32 mUpdateRate; // at 0x4 + f32 mStartFrame; // at 0x8 + f32 mEndFrame; // at 0xC + PlayPolicyFunc mpPlayPolicy; // at 0x10 static f32 smBaseUpdateRate; }; -class AnmObj : public G3dObj { -public: - enum AnmFlag { ANMFLAG_2 = 0x2, ANMFLAG_ISBOUND = 0x4 }; - -public: - AnmObj(MEMAllocator *pAllocator, G3dObj *pParent) : G3dObj(pAllocator, pParent), mFlags(0) {} - - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return (other == GetTypeObjStatic()) ? true : G3dObj::IsDerivedFrom(other); - } - virtual void G3dProc(u32, u32, void *) = 0; // at 0xC - virtual ~AnmObj() {} // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } - virtual void SetFrame(f32) = 0; // at 0x1C - virtual f32 GetFrame() const = 0; // at 0x20 - virtual void UpdateFrame() = 0; // at 0x24 - virtual void SetUpdateRate(f32) = 0; // at 0x28 - virtual f32 GetUpdateRate() const = 0; // at 0x2C - virtual bool Bind(ResMdl) = 0; // at 0x30 - virtual void Release(); // at 0x34 - - static const TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } - - void SetAnmFlag(AnmFlag, bool); - bool TestAnmFlag(AnmFlag) const; - -private: - u32 mFlags; // at 0x4 - - NW4R_G3D_TYPE_OBJ_DECL(AnmObj); -}; } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_anmscn.h b/include/nw4r/g3d/g3d_anmscn.h index 050c64eb..afe445a3 100644 --- a/include/nw4r/g3d/g3d_anmscn.h +++ b/include/nw4r/g3d/g3d_anmscn.h @@ -1,55 +1,72 @@ -#ifndef NW4R_G3D_ANMSCN_H -#define NW4R_G3D_ANMSCN_H -#include "common.h" -#include "nw4r/g3d/g3d_camera.h" -#include "nw4r/g3d/g3d_fog.h" -#include "nw4r/g3d/g3d_light.h" -#include "nw4r/g3d/g3d_obj.h" +#ifndef NW4R_G3D_ANM_SCN_H +#define NW4R_G3D_ANM_SCN_H +#include + +#include +#include +#include +#include +#include namespace nw4r { namespace g3d { -class AnmScnRes // : public AnmScn -{}; -class AnmScn : G3dObj { +// Forward declarations +class AnmScnRes; + +class AnmScn : public G3dObj { public: - AnmScn(MEMAllocator *); - virtual bool IsDerivedFrom(TypeObj other) const; // at 0x8 - virtual ~AnmScn(); // at 0x10 - virtual const TypeObj GetTypeObj() const; // at 0x14 - virtual const char *GetTypeName() const; // at 0x18 - virtual void SetFrame(f32) = 0; // at 0x1C - virtual f32 GetFrame() const = 0; // at 0x20 - virtual void SetUpdateRate(f32) = 0; // at 0x24 - virtual f32 GetUpdateRate() const = 0; // at 0x28 - virtual void UpdateFrame() = 0; // at 0x2C - virtual void Attach(int, AnmScnRes); // at 0x30 - virtual void Detach(); // at 0x34 - virtual int GetNumLightSet() const = 0; // at 0x38 - virtual int GetNumAmbLight() const = 0; // at 0x3C - virtual int GetNumDiffuseLight() const = 0; // at 0x40 - virtual int GetNumSpecularLight() const = 0; // at 0x44 - virtual int GetNumFog() const = 0; // at 0x48 - virtual int GetNumCamera() const = 0; // at 0x4C - virtual int GetLightSetMaxRefNumber() const = 0; // at 0x50 - virtual int GetAmbLightMaxRefNumber() const = 0; // at 0x54 - virtual int GetDiffuseLightMaxRefNumber() const = 0; // at 0x58 - virtual int GetFogMaxRefNumber() const = 0; // at 0x5C - virtual int GetCameraMaxRefNumber() const = 0; // at 0x60 - virtual void GetLightSet(LightSet, u32) = 0; // at 0x64 - virtual ut::Color GetAmbLightColor(u32) = 0; // at 0x68 - virtual void GetLight(LightObj *, LightObj *, u32) = 0; // at 0x6C - virtual void GetFog(Fog, u32) = 0; // at 0x70 - virtual void GetCamera(Camera, u32) = 0; // at 0x74 - virtual int GetSpecularLightID(u32) const = 0; // at 0x78 - virtual bool HasSpecularLight(u32) const = 0; // at 0x7C - virtual void GetAmbLightResult(AmbLightAnmResult *, u32) = 0; // at 0x80 - virtual void GetLightResult(LightAnmResult *, u32) = 0; // at 0x84 - virtual void GetFogResult(FogAnmResult *, u32) = 0; // at 0x88 - virtual void GetFogResult(CameraAnmResult *, u32) = 0; // at 0x8C + explicit AnmScn(MEMAllocator *pAllocator); + virtual ~AnmScn(); // at 0x10 - void GetLightSetting(LightSetting *); + virtual void SetFrame(f32 frame) = 0; // at 0x1C + virtual f32 GetFrame() const = 0; // at 0x20 + + virtual void SetUpdateRate(f32 rate) = 0; // at 0x24 + virtual f32 GetUpdateRate() const = 0; // at 0x28 + virtual void UpdateFrame() = 0; // at 0x2C + + virtual AnmScnRes *Attach(int idx, AnmScnRes *pRes); // at 0x30 + virtual AnmScnRes *Detach(); // at 0x34 + + virtual u32 GetNumLightSet() const = 0; // at 0x38 + virtual u32 GetNumAmbLight() const = 0; // at 0x3C + virtual u32 GetNumDiffuseLight() const = 0; // at 0x40 + virtual u32 GetNumSpecularLight() const = 0; // at 0x44 + virtual u32 GetNumFog() const = 0; // at 0x48 + virtual u32 GetNumCamera() const = 0; // at 0x4C + + virtual u32 GetLightSetMaxRefNumber() const = 0; // at 0x50 + virtual u32 GetAmbLightMaxRefNumber() const = 0; // at 0x54 + virtual u32 GetDiffuseLightMaxRefNumber() const = 0; // at 0x58 + virtual u32 GetFogMaxRefNumber() const = 0; // at 0x5C + virtual u32 GetCameraMaxRefNumber() const = 0; // at 0x60 + + virtual bool GetLightSet(LightSet set, u32 refNumber) = 0; // at 0x64 + virtual ut::Color GetAmbLightColor(u32 refNumber) = 0; // at 0x68 + virtual void GetLight(LightObj *pDiff, LightObj *pSpec, + u32 refNumber) = 0; // at 0x6C + virtual void GetFog(Fog fog, u32 refNumber) = 0; // at 0x70 + virtual bool GetCamera(Camera camera, u32 refNumber) = 0; // at 0x74 + + virtual u32 GetSpecularLightID(u32 refNumber) const = 0; // at 0x78 + virtual bool HasSpecularLight(u32 refNumber) const = 0; // at 0x7C + + virtual AmbLightAnmResult *GetAmbLightResult(AmbLightAnmResult *pResult, + u32 refNumber) = 0; // at 0x80 + virtual LightAnmResult *GetLightResult(LightAnmResult *pResult, + u32 refNumber) = 0; // at 0x84 + virtual FogAnmResult *GetFogResult(FogAnmResult *pResult, + u32 refNumber) = 0; // at 0x88 + virtual CameraAnmResult *GetCameraResult(CameraAnmResult *pResult, + u32 refNumber) = 0; // at 0x8C + + void GetLightSetting(LightSetting *pSetting); + +private: + NW4R_G3D_RTTI_DECL_DERIVED(AnmScn, G3dObj); }; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_anmshp.h b/include/nw4r/g3d/g3d_anmshp.h index abc2bc09..95355f24 100644 --- a/include/nw4r/g3d/g3d_anmshp.h +++ b/include/nw4r/g3d/g3d_anmshp.h @@ -1,98 +1,174 @@ -#ifndef NW4R_G3D_ANMSHP_H -#define NW4R_G3D_ANMSHP_H -#include "common.h" -#include "nw4r/g3d/g3d_anmobj.h" -#include "nw4r/g3d/g3d_resanmshp.h" +#ifndef NW4R_G3D_ANM_SHP_H +#define NW4R_G3D_ANM_SHP_H +#include -// This header is based on the SS ghidra, the TypeNames in the binary, -// and an assumed symmetry to AnmObjVis. Everything about it could be wrong. +#include +#include namespace nw4r { namespace g3d { +/****************************************************************************** + * + * AnmObjShp + * + ******************************************************************************/ +// Forward declarations class AnmObjShpRes; class AnmObjShp : public AnmObj { public: - AnmObjShp(MEMAllocator *, u16 *, int); - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return (other == GetTypeObjStatic()) ? true : AnmObj::IsDerivedFrom(other); - } - virtual void G3dProc(u32, u32, void *); // at 0xC - virtual ~AnmObjShp() {} // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } - virtual void SetFrame(f32) = 0; // at 0x1C - virtual f32 GetFrame() const = 0; // at 0x20 - virtual void UpdateFrame() = 0; // at 0x24 - virtual void SetUpdateRate(f32) = 0; // at 0x28 - virtual f32 GetUpdateRate() const = 0; // at 0x2C - virtual bool Bind(ResMdl) = 0; // at 0x30 - virtual void Release(); // at 0x34 - virtual bool GetResult(u32) = 0; // at 0x38 - virtual AnmObjShpRes *Attach(int, AnmObjShpRes *); // at 0x3C - virtual AnmObjShpRes *Detach(int); // at 0x40 + AnmObjShp(MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding); + virtual void G3dProc(u32 task, u32 param, void *pInfo) = 0; // at 0xC + virtual ~AnmObjShp() {} // at 0x10 - static const TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } + virtual void SetFrame(f32 frame) = 0; // at 0x1C + virtual f32 GetFrame() const = 0; // at 0x20 + virtual void UpdateFrame() = 0; // at 0x24 + + virtual void SetUpdateRate(f32 rate) = 0; // at 0x28 + virtual f32 GetUpdateRate() const = 0; // at 0x2C + + virtual bool Bind(const ResMdl mdl) = 0; // at 0x30 + virtual void Release(); // at 0x34 + + virtual const ShpAnmResult *GetResult(ShpAnmResult *pResult, + u32 idx) = 0; // at 0x38 + + virtual AnmObjShpRes *Attach(int idx, AnmObjShpRes *pRes); // at 0x3C + virtual AnmObjShpRes *Detach(int idx); // at 0x40 + virtual void DetachAll(); // at 0x44 + + virtual void SetWeight(int idx, f32 weight); // at 0x48 + virtual f32 GetWeight(int idx) const; // at 0x4C - bool TestDefined(u32 idx) const; bool TestExistence(u32 idx) const; - void DetachAll(); + bool TestDefined(u32 idx) const; protected: - static const int MAX_RESOURCES = 4; + enum BindingFlag { + BINDING_ID_MASK = (1 << 14) - 1, + BINDING_INVALID = (1 << 14), + BINDING_UNDEFINED = (1 << 15), + }; - int mNumBinds; // at 0x10 - u16 *mBinds; // at 0x14 +protected: + static const int DEFAULT_MAX_CHILDREN = 4; - NW4R_G3D_TYPE_OBJ_DECL(AnmObjShp); +protected: + int mNumBinding; // at 0x10 + u16 *const mpBinding; // at 0x14 + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjShp, AnmObj); }; -class AnmObjShpRes : public AnmObjShp, public FrameCtrl { +/****************************************************************************** + * + * AnmObjShpNode + * + ******************************************************************************/ +class AnmObjShpNode : public AnmObjShp { public: - AnmObjShpRes(MEMAllocator *, ResAnmShp, u16 *, int); + AnmObjShpNode( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjShpRes **ppChildrenBuf, int numChildren + ); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~AnmObjShpNode(); // at 0x10 - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return (other == GetTypeObjStatic()) ? true : AnmObjShp::IsDerivedFrom(other); - } - virtual ~AnmObjShpRes() {} // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } - virtual void SetFrame(f32); // at 0x1C - virtual f32 GetFrame() const; // at 0x20 - virtual void UpdateFrame(); // at 0x24 - virtual void SetUpdateRate(f32); // at 0x28 - virtual f32 GetUpdateRate() const; // at 0x2C - virtual bool Bind(ResMdl); // at 0x30 - virtual bool GetResult(u32); // at 0x38 + virtual void SetFrame(f32 frame); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 - static const TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } + virtual void SetUpdateRate(f32 rate); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C - static AnmObjShpRes *Construct(MEMAllocator *, u32 *, ResAnmShp, ResMdl, bool); + virtual bool Bind(const ResMdl mdl); // at 0x30 + virtual void Release(); // at 0x34 + + virtual AnmObjShpRes *Attach(int idx, AnmObjShpRes *pRes); // at 0x3C + virtual AnmObjShpRes *Detach(int idx); // at 0x40 + virtual void DetachAll(); // at 0x44 + +protected: + int mChildrenArraySize; // at 0x18 + AnmObjShpRes **mpChildrenArray; // at 0x1C + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjShpNode, AnmObjShp); +}; + +/****************************************************************************** + * + * AnmObjShpBlend + * + ******************************************************************************/ +class AnmObjShpBlend : public AnmObjShpNode { + static AnmObjShpBlend *Construct(MEMAllocator *pAllocator, u32 *pSize, ResMdl mdl, int numChildren); + + AnmObjShpBlend( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjShpRes **ppChildrenBuf, int numChildren, + f32 *pWeightBuf + ); + + virtual ~AnmObjShpBlend() {} // at 0x10 + + virtual const ShpAnmResult *GetResult(ShpAnmResult *pResult, + u32 idx); // at 0x38 + + virtual void SetWeight(int idx, f32 weight); // at 0x48 + virtual f32 GetWeight(int idx) const; // at 0x4C private: - ResAnmShp mResAnmShp; // at 0x2C + f32 *mpWeightArray; // at 0x20 - NW4R_G3D_TYPE_OBJ_DECL(AnmObjShpRes); + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjShpBlend, AnmObjShpNode); }; + +/****************************************************************************** + * + * AnmObjShpRes + * + ******************************************************************************/ +class AnmObjShpRes : public AnmObjShp, protected FrameCtrl { +public: + static AnmObjShpRes *Construct(MEMAllocator *pAllocator, u32 *pSize, ResAnmShp shp, ResMdl mdl, bool cache); + + AnmObjShpRes( + MEMAllocator *pAllocator, ResAnmShp shp, u16 *pBindingBuf, ShpAnmVtxSet *pVtxSetBuf, int numBinding, + ShpAnmResult *pCacheBuf + ); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~AnmObjShpRes() {} // at 0x10 + + virtual void SetFrame(f32 frame); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 + + virtual void SetUpdateRate(f32 rate); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C + + virtual bool Bind(const ResMdl mdl); // at 0x30 + + virtual const ShpAnmResult *GetResult(ShpAnmResult *pResult, + u32 idx); // at 0x38 + + void UpdateCache(); + + ResAnmShp GetResAnm() { + return mRes; + } + + void SetPlayPolicy(PlayPolicyFunc pFunc) { + FrameCtrl::SetPlayPolicy(pFunc); + } + +private: + ResAnmShp mRes; // at 0x2C + ShpAnmVtxSet *const mpVtxSetArray; // at 0x30 + ShpAnmResult *const mpResultCache; // at 0x34 + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjShpRes, AnmObjShp); +}; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_anmtexpat.h b/include/nw4r/g3d/g3d_anmtexpat.h index 9506d745..be0de680 100644 --- a/include/nw4r/g3d/g3d_anmtexpat.h +++ b/include/nw4r/g3d/g3d_anmtexpat.h @@ -1,94 +1,175 @@ -#ifndef NW4R_G3D_ANMTEXPAT_H -#define NW4R_G3D_ANMTEXPAT_H -#include "nw4r/g3d/g3d_anmobj.h" -#include "nw4r/g3d/g3d_restex.h" -#include "nw4r/g3d/g3d_resanmtexpat.h" +#ifndef NW4R_G3D_ANM_TEX_PAT_H +#define NW4R_G3D_ANM_TEX_PAT_H +#include -namespace nw4r -{ - namespace g3d - { - struct TexPatAnmResult - { - enum - { - ANM_COUNT = 8 - }; - - u8 mTexFlags; // at 0x0 - u8 mPlttFlags; // at 0x1 - ResTex mTexs[ANM_COUNT]; // at 0x4 - ResPltt mPltts[ANM_COUNT]; // at 0x24 - }; +#include +#include - class AnmObjTexPatRes; +namespace nw4r { +namespace g3d { - class AnmObjTexPat : public AnmObj { - public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } +void ApplyTexPatAnmResult(ResTexObj texObj, ResTlutObj tlutObj, const TexPatAnmResult *pResult); - virtual TexPatAnmResult *GetResult(); // at 0x38 - virtual void Attach(s32, AnmObjTexPatRes *res); // at 0x3C - virtual void Detach(s32); // at 0x40 +/****************************************************************************** + * + * AnmObjTexPat + * + ******************************************************************************/ +// Forward declarations +class AnmObjTexPatRes; - private: - int mChildrenArraySize; - u16 *mpChildrenArray; +class AnmObjTexPat : public AnmObj { +public: + AnmObjTexPat(MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding); + virtual void G3dProc(u32 task, u32 param, void *pInfo) = 0; // at 0xC + virtual ~AnmObjTexPat() {} // at 0x10 - NW4R_G3D_TYPE_OBJ_DECL(AnmObjTexPat); - }; + virtual void SetFrame(f32 frame) = 0; // at 0x1C + virtual f32 GetFrame() const = 0; // at 0x20 + virtual void UpdateFrame() = 0; // at 0x24 - class AnmObjTexPatNode : public AnmObjTexPat { - public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } + virtual void SetUpdateRate(f32 rate) = 0; // at 0x28 + virtual f32 GetUpdateRate() const = 0; // at 0x2C + virtual bool Bind(const ResMdl mdl) = 0; // at 0x30 + virtual void Release(); // at 0x34 - inline int Size() { - return mNodeArraySize; - } + virtual const TexPatAnmResult *GetResult(TexPatAnmResult *pResult, + u32 idx) = 0; // at 0x38 - AnmObjTexPatRes *GetNode(int i) { - return mpNodes[i]; - } + virtual AnmObjTexPatRes *Attach(int idx, AnmObjTexPatRes *pRes); // at 0x3C + virtual AnmObjTexPatRes *Detach(int idx); // at 0x40 + virtual void DetachAll(); // at 0x44 - private: - int mNodeArraySize; - AnmObjTexPatRes **mpNodes; + bool TestExistence(u32 idx) const; + bool TestDefined(u32 idx) const; - NW4R_G3D_TYPE_OBJ_DECL(AnmObjTexPatNode); - }; +protected: + enum BindingFlag { + BINDING_ID_MASK = (1 << 14) - 1, + BINDING_INVALID = (1 << 14), + BINDING_UNDEFINED = (1 << 15), + }; - class AnmObjTexPatRes : public AnmObjTexPat, public FrameCtrl { - public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } +protected: + static const int MAX_CHILD = 4; +protected: + int mNumBinding; // at 0x10 + u16 *const mpBinding; // at 0x14 - static AnmObjTexPatRes *Construct(MEMAllocator*, u32*, ResAnmTexPat, ResMdl, bool); - private: - ResAnmTexPat mRes; - TexPatAnmResult *mpResultCache; + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjTexPat, AnmObj); +}; - NW4R_G3D_TYPE_OBJ_DECL(AnmObjTexPatRes); - }; +/****************************************************************************** + * + * AnmObjTexPatNode + * + ******************************************************************************/ +class AnmObjTexPatNode : public AnmObjTexPat { +public: + AnmObjTexPatNode( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjTexPatRes **ppChildrenBuf, int numChildren + ); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~AnmObjTexPatNode(); // at 0x10 - class AnmObjTexPatOverride : public AnmObjTexPatNode { - public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } + virtual void SetFrame(f32 frame); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 - static AnmObjTexPatOverride *Construct(MEMAllocator*, u32*, ResMdl, int); + virtual void SetUpdateRate(f32 rate); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C - NW4R_G3D_TYPE_OBJ_DECL(AnmObjTexPatOverride); - }; + virtual bool Bind(const ResMdl mdl); // at 0x30 + virtual void Release(); // at 0x34 - } -} + virtual AnmObjTexPatRes *Attach(int idx, AnmObjTexPatRes *pRes); // at 0x3C + virtual AnmObjTexPatRes *Detach(int idx); // at 0x40 + virtual void DetachAll(); // at 0x44 + + inline int Size() { + return mChildrenArraySize; + } + + AnmObjTexPatRes *GetNode(int i) { + return mpChildrenArray[i]; + } + +protected: + int mChildrenArraySize; // at 0x18 + AnmObjTexPatRes **mpChildrenArray; // at 0x1C + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjTexPatNode, AnmObjTexPat); +}; + +/****************************************************************************** + * + * AnmObjTexPatOverride + * + ******************************************************************************/ +class AnmObjTexPatOverride : public AnmObjTexPatNode { +public: + static AnmObjTexPatOverride *Construct(MEMAllocator *pAllocator, u32 *pSize, ResMdl mdl, int numChildren); + + AnmObjTexPatOverride( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjTexPatRes **ppChildrenBuf, int numChildren + ) + : AnmObjTexPatNode(pAllocator, pBindingBuf, numBinding, ppChildrenBuf, numChildren) {} + + virtual ~AnmObjTexPatOverride() {} // at 0x10 + + virtual const TexPatAnmResult *GetResult(TexPatAnmResult *pResult, + u32 idx); // at 0x38 + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjTexPatOverride, AnmObjTexPatNode); +}; + +/****************************************************************************** + * + * AnmObjTexPatRes + * + ******************************************************************************/ +class AnmObjTexPatRes : public AnmObjTexPat, protected FrameCtrl { +public: + static AnmObjTexPatRes *Construct(MEMAllocator *pAllocator, u32 *pSize, ResAnmTexPat pat, ResMdl mdl, bool cache); + + AnmObjTexPatRes( + MEMAllocator *pAllocator, ResAnmTexPat pat, u16 *pBindingBuf, int numBinding, TexPatAnmResult *pCacheBuf + ); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~AnmObjTexPatRes() {} // at 0x10 + + virtual void SetFrame(f32 frame); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 + + virtual void SetUpdateRate(f32 rate); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C + + virtual bool Bind(const ResMdl mdl); // at 0x30 + + virtual const TexPatAnmResult *GetResult(TexPatAnmResult *pResult, + u32 idx); // at 0x38 + + void UpdateCache(); + + ResAnmTexPat GetResAnm() { + return mRes; + } + + void SetPlayPolicy(PlayPolicyFunc pFunc) { + FrameCtrl::SetPlayPolicy(pFunc); + } + +private: + ResAnmTexPat mRes; // at 0x2C + TexPatAnmResult *const mpResultCache; // at 0x30 + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjTexPatRes, AnmObjTexPat); +}; + +} // namespace g3d +} // namespace nw4r #endif diff --git a/include/nw4r/g3d/g3d_anmtexsrt.h b/include/nw4r/g3d/g3d_anmtexsrt.h index 21576b6a..e2f60b20 100644 --- a/include/nw4r/g3d/g3d_anmtexsrt.h +++ b/include/nw4r/g3d/g3d_anmtexsrt.h @@ -1,117 +1,173 @@ -#ifndef NW4R_G3D_ANMTEXSRT_H -#define NW4R_G3D_ANMTEXSRT_H -#include "nw4r/g3d/g3d_restex.h" -#include "nw4r/g3d/g3d_resanmtexsrt.h" +#ifndef NW4R_G3D_ANM_TEX_SRT_H +#define NW4R_G3D_ANM_TEX_SRT_H +#include -namespace nw4r -{ - namespace g3d - { +#include +#include +#include - class AnmObjTexSrtRes; - struct TexSrtAnmResult; +namespace nw4r { +namespace g3d { - class AnmObjTexSrt : public AnmObj { - public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } +void ApplyTexSrtAnmResult(ResTexSrt srt, const TexSrtAnmResult *pResult); +void ApplyTexSrtAnmResult(ResTexSrt srt, ResMatIndMtxAndScale ind, const TexSrtAnmResult *pResult); - virtual TexSrtAnmResult *GetResult(); // at 0x38 - virtual void Attach(s32, AnmObjTexSrtRes *res); // at 0x3C - virtual void Detach(s32); // at 0x40 +/****************************************************************************** + * + * AnmObjTexSrt + * + ******************************************************************************/ +// Forward declarations +class AnmObjTexSrtRes; - private: - int mChildrenArraySize; - u16 *mpChildrenArray; +class AnmObjTexSrt : public AnmObj { +public: + AnmObjTexSrt(MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding); + virtual void G3dProc(u32 task, u32 param, void *pInfo) = 0; // at 0xC + virtual ~AnmObjTexSrt() {} // at 0x10 - NW4R_G3D_TYPE_OBJ_DECL(AnmObjTexSrt); - }; + virtual void SetFrame(f32 frame) = 0; // at 0x1C + virtual f32 GetFrame() const = 0; // at 0x20 + virtual void UpdateFrame() = 0; // at 0x24 - class AnmObjTexSrtNode : public AnmObjTexSrt { - public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } + virtual void SetUpdateRate(f32 rate) = 0; // at 0x28 + virtual f32 GetUpdateRate() const = 0; // at 0x2C + virtual bool Bind(const ResMdl mdl) = 0; // at 0x30 + virtual void Release(); // at 0x34 - inline int Size() { - return mNodeArraySize; - } + virtual const TexSrtAnmResult *GetResult(TexSrtAnmResult *pResult, + u32 idx) = 0; // at 0x38 - AnmObjTexSrtRes *GetNode(int i) { - return mpNodes[i]; - } + virtual AnmObjTexSrtRes *Attach(int idx, AnmObjTexSrtRes *pRes); // at 0x3C + virtual AnmObjTexSrtRes *Detach(int idx); // at 0x40 + virtual void DetachAll(); // at 0x44 - private: - int mNodeArraySize; - AnmObjTexSrtRes **mpNodes; + bool TestExistence(u32 idx) const; + bool TestDefined(u32 idx) const; - NW4R_G3D_TYPE_OBJ_DECL(AnmObjTexSrtNode); - }; +protected: + enum BindingFlag { + BINDING_ID_MASK = (1 << 14) - 1, + BINDING_INVALID = (1 << 14), + BINDING_UNDEFINED = (1 << 15), + }; - class AnmObjTexSrtRes : public AnmObjTexSrt, public FrameCtrl { - public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } +protected: + static const int MAX_CHILD = 4; +protected: + int mNumBinding; // at 0x10 + u16 *const mpBinding; // at 0x14 - static AnmObjTexSrtRes *Construct(MEMAllocator*, u32*, ResAnmTexSrt, ResMdl, bool); - private: - ResAnmTexSrt mRes; - TexSrtAnmResult *mpResultCache; + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjTexSrt, AnmObj); +}; - NW4R_G3D_TYPE_OBJ_DECL(AnmObjTexSrtRes); - }; +/****************************************************************************** + * + * AnmObjTexSrtNode + * + ******************************************************************************/ +class AnmObjTexSrtNode : public AnmObjTexSrt { +public: + AnmObjTexSrtNode( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjTexSrtRes **ppChildrenBuf, int numChildren + ); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~AnmObjTexSrtNode(); // at 0x10 - class AnmObjTexSrtOverride : public AnmObjTexSrtNode { - public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } + virtual void SetFrame(f32 frame); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 - static AnmObjTexSrtOverride *Construct(MEMAllocator*, u32*, ResMdl, int); + virtual void SetUpdateRate(f32 rate); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C - NW4R_G3D_TYPE_OBJ_DECL(AnmObjTexSrtOverride); - }; + virtual bool Bind(const ResMdl mdl); // at 0x30 + virtual void Release(); // at 0x34 - struct TexSrtTypedef - { - enum TexMatrixMode - { - TEX_MTX_MAYA, - TEX_MTX_XSI, - TEX_MTX_3DSMAX - }; - }; + virtual AnmObjTexSrtRes *Attach(int idx, AnmObjTexSrtRes *pRes); // at 0x3C + virtual AnmObjTexSrtRes *Detach(int idx); // at 0x40 + virtual void DetachAll(); // at 0x44 - struct TexSrt - { - enum Flag - { - FLAG_ANM_EXISTS, - }; + int Size() const { + return mChildrenArraySize; + } - float mScaleX; // at 0x0 - float mScaleY; // at 0x4 - float mRotation; // at 0x8 - float mTranslationX; // at 0xc - float mTranslationY; // at 0x10 - }; - - struct TexSrtAnmResult - { - enum - { - ANM_COUNT = 8 - }; - - UNKWORD FLAGS_0x0; - UNKWORD FLAGS_0x4; - TexSrt mSrts[ANM_COUNT * 2]; // at 0x8 - }; - } -} +protected: + int mChildrenArraySize; // at 0x18 + AnmObjTexSrtRes **mpChildrenArray; // at 0x1C + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjTexSrtNode, AnmObjTexSrt); +}; + +/****************************************************************************** + * + * AnmObjTexSrtOverride + * + ******************************************************************************/ +class AnmObjTexSrtOverride : public AnmObjTexSrtNode { +public: + static AnmObjTexSrtOverride *Construct(MEMAllocator *pAllocator, u32 *pSize, ResMdl mdl, int numChildren); + + AnmObjTexSrtOverride( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjTexSrtRes **ppChildrenBuf, int numChildren + ) + : AnmObjTexSrtNode(pAllocator, pBindingBuf, numBinding, ppChildrenBuf, numChildren) {} + + virtual ~AnmObjTexSrtOverride() {} // at 0x10 + + virtual const TexSrtAnmResult *GetResult(TexSrtAnmResult *pResult, + u32 idx); // at 0x38 + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjTexSrtOverride, AnmObjTexSrtNode); +}; + +/****************************************************************************** + * + * AnmObjTexSrtRes + * + ******************************************************************************/ +class AnmObjTexSrtRes : public AnmObjTexSrt, protected FrameCtrl { +public: + static AnmObjTexSrtRes *Construct(MEMAllocator *pAllocator, u32 *pSize, ResAnmTexSrt srt, ResMdl mdl, bool cache); + + AnmObjTexSrtRes( + MEMAllocator *pAllocator, ResAnmTexSrt srt, u16 *pBindingBuf, int numBinding, TexSrtAnmResult *pCacheBuf + ); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~AnmObjTexSrtRes() {} // at 0x10 + + virtual void SetFrame(f32 frame); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 + + virtual void SetUpdateRate(f32 rate); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C + + virtual bool Bind(const ResMdl mdl); // at 0x30 + + virtual const TexSrtAnmResult *GetResult(TexSrtAnmResult *pResult, + u32 idx); // at 0x38 + + void UpdateCache(); + + ResAnmTexSrt GetResAnm() { + return mRes; + } + + void SetPlayPolicy(PlayPolicyFunc pFunc) { + FrameCtrl::SetPlayPolicy(pFunc); + } + +private: + ResAnmTexSrt mRes; // at 0x2C + TexSrtAnmResult *const mpResultCache; // at 0x30 + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjTexSrtRes, AnmObjTexSrt); +}; + +} // namespace g3d +} // namespace nw4r #endif diff --git a/include/nw4r/g3d/g3d_anmvis.h b/include/nw4r/g3d/g3d_anmvis.h index 54d54e34..ae756d9a 100644 --- a/include/nw4r/g3d/g3d_anmvis.h +++ b/include/nw4r/g3d/g3d_anmvis.h @@ -1,169 +1,154 @@ -#ifndef NW4R_G3D_ANMVIS_H -#define NW4R_G3D_ANMVIS_H -#include "common.h" -#include "nw4r/g3d/g3d_anmobj.h" -#include "nw4r/g3d/g3d_resanmvis.h" +#ifndef NW4R_G3D_ANM_VIS_H +#define NW4R_G3D_ANM_VIS_H +#include + +#include +#include namespace nw4r { namespace g3d { -void ApplyVisAnmResult(ResMdl, AnmObjVis *); -void ApplyVisAnmResult(u8 *, ResMdl, AnmObjVis *); + +void ApplyVisAnmResult(ResMdl mdl, AnmObjVis *pObj); +void ApplyVisAnmResult(u8 *pByteVec, ResMdl mdl, AnmObjVis *pObj); + +/****************************************************************************** + * + * AnmObjVis + * + ******************************************************************************/ +// Forward declarations +class AnmObjVisRes; class AnmObjVis : public AnmObj { public: - AnmObjVis(MEMAllocator *, u16 *, int); - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return (other == GetTypeObjStatic()) ? true : AnmObj::IsDerivedFrom(other); - } - virtual void G3dProc(u32, u32, void *); // at 0xC - virtual ~AnmObjVis() {} // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } - virtual void SetFrame(f32) = 0; // at 0x1C - virtual f32 GetFrame() const = 0; // at 0x20 - virtual void UpdateFrame() = 0; // at 0x24 - virtual void SetUpdateRate(f32) = 0; // at 0x28 - virtual f32 GetUpdateRate() const = 0; // at 0x2C - virtual bool Bind(ResMdl) = 0; // at 0x30 - virtual void Release(); // at 0x34 - virtual bool GetResult(u32) = 0; // at 0x38 - virtual AnmObjVisRes *Attach(int, AnmObjVisRes *); // at 0x3C - virtual AnmObjVisRes *Detach(int); // at 0x40 + AnmObjVis(MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~AnmObjVis() {} // at 0x10 - static const TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } + virtual void SetFrame(f32 frame) = 0; // at 0x1C + virtual f32 GetFrame() const = 0; // at 0x20 + virtual void UpdateFrame() = 0; // at 0x24 - bool TestDefined(u32 idx) const; - bool TestExistence(u32 idx) const; + virtual void SetUpdateRate(f32 rate) = 0; // at 0x28 + virtual f32 GetUpdateRate() const = 0; // at 0x2C + + virtual bool Bind(const ResMdl mdl) = 0; // at 0x30 + virtual void Release(); // at 0x34 + + virtual bool GetResult(u32 idx) = 0; // at 0x38 + + virtual AnmObjVisRes *Attach(int idx, AnmObjVisRes *pRes); // at 0x3C + virtual AnmObjVisRes *Detach(int idx); // at 0x40 void DetachAll(); + bool TestExistence(u32 idx) const; + bool TestDefined(u32 idx) const; + protected: - static const int MAX_RESOURCES = 4; + enum BindingFlag { + BINDING_ID_MASK = (1 << 14) - 1, + BINDING_INVALID = (1 << 14), + BINDING_UNDEFINED = (1 << 15), + }; - int mNumBinds; // at 0x10 - u16 *mBinds; // at 0x14 +protected: + static const int MAX_CHILD = 4; - NW4R_G3D_TYPE_OBJ_DECL(AnmObjVis); +protected: + int mNumBinding; // at 0x10 + u16 *const mpBinding; // at 0x14 + + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjVis, AnmObj); }; +/****************************************************************************** + * + * AnmObjVisNode + * + ******************************************************************************/ class AnmObjVisNode : public AnmObjVis { public: - AnmObjVisNode(MEMAllocator *allocator, u16 *bindBuffer, int numBinds) : AnmObjVis(allocator, bindBuffer, numBinds) { - mResources[0] = NULL; - mResources[1] = NULL; - mResources[2] = NULL; - mResources[3] = NULL; - } + AnmObjVisNode(MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~AnmObjVisNode(); // at 0x10 - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return (other == GetTypeObjStatic()) ? true : AnmObjVis::IsDerivedFrom(other); - } - virtual void G3dProc(u32, u32, void *); // at 0xC - virtual ~AnmObjVisNode(); // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } - virtual void SetFrame(f32); // at 0x1C - virtual f32 GetFrame() const; // at 0x20 - virtual void UpdateFrame(); // at 0x24 - virtual void SetUpdateRate(f32); // at 0x28 - virtual f32 GetUpdateRate() const; // at 0x2C - virtual bool Bind(ResMdl); // at 0x30 - virtual void Release(); // at 0x34 - virtual bool GetResult(u32) = 0; // at 0x38 - virtual AnmObjVisRes *Attach(int, AnmObjVisRes *); // at 0x3C - virtual AnmObjVisRes *Detach(int); // at 0x40 + virtual void SetFrame(f32 frame); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 - static const TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } + virtual void SetUpdateRate(f32 rate); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C + + virtual bool Bind(const ResMdl mdl); // at 0x30 + virtual void Release(); // at 0x34 + + virtual bool GetResult(u32 idx) = 0; // at 0x38 + + virtual AnmObjVisRes *Attach(int idx, AnmObjVisRes *pRes); // at 0x3C + virtual AnmObjVisRes *Detach(int idx); // at 0x40 protected: - AnmObjVisRes *mResources[MAX_RESOURCES]; // at 0x18 + AnmObjVisRes *mpChildren[MAX_CHILD]; // at 0x18 - NW4R_G3D_TYPE_OBJ_DECL(AnmObjVisNode); + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjVisNode, AnmObjVis); }; +/****************************************************************************** + * + * AnmObjVisOR + * + ******************************************************************************/ class AnmObjVisOR : public AnmObjVisNode { public: - AnmObjVisOR(MEMAllocator *allocator, u16 *bindBuffer, int numBinds) - : AnmObjVisNode(allocator, bindBuffer, numBinds) {} + static AnmObjVisOR *Construct(MEMAllocator *pAllocator, u32 *pSize, ResMdl mdl); - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return (other == GetTypeObjStatic()) ? true : AnmObjVisNode::IsDerivedFrom(other); - } - virtual ~AnmObjVisOR() {} // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } - virtual bool GetResult(u32); // at 0x38 + AnmObjVisOR(MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding) + : AnmObjVisNode(pAllocator, pBindingBuf, numBinding) {} - static const TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } + virtual ~AnmObjVisOR() {} // at 0x10 - static AnmObjVisOR *Construct(MEMAllocator *, u32 *, ResMdl); + virtual bool GetResult(u32 idx); // at 0x38 -private: - NW4R_G3D_TYPE_OBJ_DECL(AnmObjVisOR); + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjVisOR, AnmObjVisNode); }; -class AnmObjVisRes : public AnmObjVis, public FrameCtrl { +/****************************************************************************** + * + * AnmObjVisRes + * + ******************************************************************************/ +class AnmObjVisRes : public AnmObjVis, protected FrameCtrl { public: - AnmObjVisRes(MEMAllocator *, ResAnmVis, u16 *, int); + static AnmObjVisRes *Construct(MEMAllocator *pAllocator, u32 *pSize, ResAnmVis vis, ResMdl mdl); - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return (other == GetTypeObjStatic()) ? true : AnmObjVis::IsDerivedFrom(other); - } - virtual ~AnmObjVisRes() {} // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } - virtual void SetFrame(f32); // at 0x1C - virtual f32 GetFrame() const; // at 0x20 - virtual void UpdateFrame(); // at 0x24 - virtual void SetUpdateRate(f32); // at 0x28 - virtual f32 GetUpdateRate() const; // at 0x2C - virtual bool Bind(ResMdl); // at 0x30 - virtual bool GetResult(u32); // at 0x38 + AnmObjVisRes(MEMAllocator *pAllocator, ResAnmVis vis, u16 *pBindingBuf, int numBinding); + virtual ~AnmObjVisRes() {} // at 0x10 - static const TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); + virtual void SetFrame(f32 frame); // at 0x1C + virtual f32 GetFrame() const; // at 0x20 + virtual void UpdateFrame(); // at 0x24 + + virtual void SetUpdateRate(f32 rate); // at 0x28 + virtual f32 GetUpdateRate() const; // at 0x2C + + virtual bool Bind(const ResMdl mdl); // at 0x30 + + virtual bool GetResult(u32 idx); // at 0x38 + + ResAnmVis GetResAnm() { + return mRes; } - static AnmObjVisRes *Construct(MEMAllocator *, u32 *, ResAnmVis, ResMdl); + void SetPlayPolicy(PlayPolicyFunc pFunc) { + FrameCtrl::SetPlayPolicy(pFunc); + } private: - ResAnmVis mResAnmVis; // at 0x2C + ResAnmVis mRes; // at 0x2C - NW4R_G3D_TYPE_OBJ_DECL(AnmObjVisRes); + NW4R_G3D_RTTI_DECL_DERIVED(AnmObjVisRes, AnmObjVis); }; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_basic.h b/include/nw4r/g3d/g3d_basic.h index 672796d9..0762296a 100644 --- a/include/nw4r/g3d/g3d_basic.h +++ b/include/nw4r/g3d/g3d_basic.h @@ -1,48 +1,26 @@ #ifndef NW4R_G3D_BASIC_H #define NW4R_G3D_BASIC_H -#include "nw4r/math/math_types.h" -#include "nw4r/g3d/g3d_anmchr.h" +#include -namespace nw4r -{ - namespace g3d - { - namespace detail - { - namespace WorldMtxAttr - { - inline bool IsScaleOne(u32 flags) - { - return (flags & 0x40000000); - } +#include - inline u32 AnmScaleOne(u32 flags) - { - return (flags | 0x40000000); - } +namespace nw4r { +namespace g3d { - inline u32 AnmNotScaleOne(u32 flags) - { - return (flags & 0x3fffffff); - } +// Forward declarations +struct ChrAnmResult; - inline u32 AnmScaleUniform(u32 flags) - { - return (flags | 0x10000000); - } +namespace detail { +namespace dcc { - inline u32 AnmNotScaleUniform(u32 flags) - { - return (flags & 0x0fffffff); - } - } +u32 CalcWorldMtx_Basic( + math::MTX34 *pW, math::VEC3 *pS, const math::MTX34 *pW1, const math::VEC3 *pS1, u32 attr, + const ChrAnmResult *pResult +); - namespace dcc - { - u32 CalcWorldMtx_Basic(math::MTX34 *, math::VEC3 *, const math::MTX34 *, const math::VEC3 *, u32, const ChrAnmResult *); - } - } - } -} +} // namespace dcc +} // namespace detail +} // namespace g3d +} // namespace nw4r #endif diff --git a/include/nw4r/g3d/g3d_calcmaterial.h b/include/nw4r/g3d/g3d_calcmaterial.h new file mode 100644 index 00000000..18776f3a --- /dev/null +++ b/include/nw4r/g3d/g3d_calcmaterial.h @@ -0,0 +1,20 @@ +#ifndef NW4R_G3D_CALC_MATERIAL_H +#define NW4R_G3D_CALC_MATERIAL_H +#include + +#include + +namespace nw4r { +namespace g3d { + +// Forward declarations +class AnmObjTexPat; +class AnmObjTexSrt; +class AnmObjMatClr; + +void CalcMaterialDirectly(ResMdl mdl, AnmObjTexPat *pAnmTexPat, AnmObjTexSrt *pAnmTexSrt, AnmObjMatClr *pAnmMatClr); + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_calcview.h b/include/nw4r/g3d/g3d_calcview.h index e79a18d4..4a623c10 100644 --- a/include/nw4r/g3d/g3d_calcview.h +++ b/include/nw4r/g3d/g3d_calcview.h @@ -1,14 +1,49 @@ #ifndef NW4R_G3D_CALC_VIEW_H #define NW4R_G3D_CALC_VIEW_H -#include "common.h" -#include "nw4r/math.h" +#include + +#include namespace nw4r { namespace g3d { -void CalcView(math::MTX34 *pViewPosArray, math::MTX33 *pViewNrmArray, const math::MTX34 *pModelMtxArray, - const u32 *pModelMtxAttribArray, u32 numMtx, const math::MTX34 *pView, ResMdl resMdl, - math::MTX34 *pVewTexMtxArray); -} +namespace detail { + +/** + * Locked cache memory layout + */ +struct MtxCacheMap { + u8 currDmaArray[32 * sizeof(math::MTX44)]; // at 0x0 + u8 currViewArray[32 * sizeof(math::MTX44)]; // at 0x800 + u8 currNrmArray[32 * sizeof(math::MTX44)]; // at 0x1000 + u8 currTexArray[32 * sizeof(math::MTX44)]; // at 0x1800 + + u8 prevDmaArray[32 * sizeof(math::MTX44)]; // at 0x2000 + u8 prevViewArray[32 * sizeof(math::MTX44)]; // at 0x2800 + u8 prevNrmArray[32 * sizeof(math::MTX44)]; // at 0x3000 + u8 prevTexArray[32 * sizeof(math::MTX44)]; // at 0x3800 +}; + +} // namespace detail + +void CalcView( + math::MTX34 *pViewPosArray, math::MTX33 *pViewNrmArray, const math::MTX34 *pModelMtxArray, + const u32 *pModelMtxAttribArray, u32 numMtx, const math::MTX34 *pViewMtx, const ResMdl mdl, + math::MTX34 *pViewTexMtxArray +); + +void CalcView_LC( + math::MTX34 *pViewPosArray, math::MTX33 *pViewNrmArray, const math::MTX34 *pModelMtxArray, + const u32 *pModelMtxAttribArray, u32 numMtx, const math::MTX34 *pViewMtx, const ResMdl mdl, + math::MTX34 *pViewTexMtxArray +); + +void CalcView_LC_DMA_ModelMtx( + math::MTX34 *pViewPosArray, math::MTX33 *pViewNrmArray, const math::MTX34 *pModelMtxArray, + const u32 *pModelMtxAttribArray, u32 numMtx, const math::MTX34 *pViewMtx, const ResMdl mdl, + math::MTX34 *pViewTexMtxArray +); + +} // namespace g3d } // namespace nw4r #endif diff --git a/include/nw4r/g3d/g3d_calcvtx.h b/include/nw4r/g3d/g3d_calcvtx.h new file mode 100644 index 00000000..63aaaac8 --- /dev/null +++ b/include/nw4r/g3d/g3d_calcvtx.h @@ -0,0 +1,24 @@ +#ifndef NW4R_G3D_CALC_VTX_H +#define NW4R_G3D_CALC_VTX_H +#include + +#include + +namespace nw4r { +namespace g3d { + +// Forward declarations +class AnmObjShp; +struct ResVtxPosData; +struct ResVtxNrmData; +struct ResVtxClrData; + +void CalcVtx( + ResMdl mdl, AnmObjShp *pAnmShp, ResVtxPosData **ppVtxPosTable, ResVtxNrmData **ppVtxNrmTable, + ResVtxClrData **ppVtxClrTable +); + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/g3d_calcworld.h b/include/nw4r/g3d/g3d_calcworld.h index b3d2973e..d50605ac 100644 --- a/include/nw4r/g3d/g3d_calcworld.h +++ b/include/nw4r/g3d/g3d_calcworld.h @@ -1,28 +1,67 @@ #ifndef NW4R_G3D_CALC_WORLD_H #define NW4R_G3D_CALC_WORLD_H -#include "common.h" -#include "nw4r/math.h" +#include + +#include +#include + +#include namespace nw4r { namespace g3d { -struct FuncObjCalcWorld { -private: - u8 UNK_0x00[0x06]; - /** 0x06 */ u16 mNodeId; +// Forward declarations +class AnmObjChr; +struct ChrAnmResult; +class FuncObjCalcWorld; +class WorldMtxManip; +/****************************************************************************** + * + * Functions + * + ******************************************************************************/ +void CalcWorld( + math::MTX34 *pModelMtxArray, u32 *pModelMtxAttribArray, const u8 *pByteCode, const math::MTX34 *pBaseMtx, + ResMdl mdl, AnmObjChr *pAnmChr, FuncObjCalcWorld *pFuncObj, u32 rootAttrib +); + +void CalcWorld( + math::MTX34 *pModelMtxArray, u32 *pModelMtxAttribArray, const u8 *pByteCode, const math::MTX34 *pBaseMtx, + ResMdl mdl, AnmObjChr *pAnmChr, FuncObjCalcWorld *pFuncObj +); + +void CalcSkinning(math::MTX34 *pModelMtxArray, u32 *pModelMtxAttribArray, const ResMdl mdl, const u8 *pByteCode); + +/****************************************************************************** + * + * ICalcWorldCallback + * + ******************************************************************************/ +class ICalcWorldCallback { public: - u32 GetNodeId() const { - return mNodeId; - } + virtual ~ICalcWorldCallback(){}; // at 0x8 - void SetNodeId(u32 n) { - mNodeId = n; - } + virtual void ExecCallbackA(ChrAnmResult *pResult, ResMdl mdl, + FuncObjCalcWorld *pFuncObj) = 0; // at 0xC + + virtual void ExecCallbackB(WorldMtxManip *pManip, ResMdl mdl, + FuncObjCalcWorld *pFuncObj) = 0; // at 0x10 + + virtual void ExecCallbackC(math::MTX34 *pMtxArray, ResMdl mdl, + FuncObjCalcWorld *pFuncObj) = 0; // at 0x14 }; +/****************************************************************************** + * + * WorldMtxManip + * + ******************************************************************************/ class WorldMtxManip { public: + WorldMtxManip(math::MTX34 *pM, math::VEC3 *pS, u32 *pWMAttr) : mpM(pM), mpS(pS), mpWMAttr(pWMAttr) {} + + void SetScale(f32, f32, f32); void GetMtx(nw4r::math::MTX34 *out) { if (out != nullptr) { PSMTXCopy(*mpM, *out); @@ -38,27 +77,57 @@ public: } private: - nw4r::math::MTX34 *mpM; - nw4r::math::VEC3 *mpS; - u32 *mpWMAttr; + math::MTX34 *mpM; // at 0x0 + math::VEC3 *mpS; // at 0x4 + u32 *mpWMAttr; // at 0x8 }; -// Name from ketteiban -class ICalcWorldCallback { +/****************************************************************************** + * + * FuncObjCalcWorld + * + ******************************************************************************/ +class FuncObjCalcWorld { public: - virtual ~ICalcWorldCallback() {} + FuncObjCalcWorld(ICalcWorldCallback *pCallback, u32 timing, u32 nodeID) + : mpCallback(pCallback), mTiming(timing), mNodeID(nodeID) {} - virtual void ExecCallbackA(nw4r::g3d::ChrAnmResult *, nw4r::g3d::ResMdl, nw4r::g3d::FuncObjCalcWorld *) {} - virtual void ExecCallbackB(nw4r::g3d::WorldMtxManip *, nw4r::g3d::ResMdl, nw4r::g3d::FuncObjCalcWorld *) {} - virtual void ExecCallbackC(nw4r::math::MTX34 *, nw4r::g3d::ResMdl, nw4r::g3d::FuncObjCalcWorld *) {} + ~FuncObjCalcWorld() {} + + u16 GetCallbackNodeID() const { + return mNodeID; + } + + void SetCallbackNodeID(u16 id) { + mNodeID = id; + } + + void CheckCallbackA(u32 nodeID, ChrAnmResult *pResult, ResMdl mdl) { + if (nodeID == mNodeID && (mTiming & ScnObj::CALLBACK_TIMING_A)) { + mpCallback->ExecCallbackA(pResult, mdl, this); + } + } + + void CheckCallbackB(u32 nodeID, math::MTX34 *pM, math::VEC3 *pS, u32 *pWMAttr, ResMdl mdl) { + if (nodeID == mNodeID && (mTiming & ScnObj::CALLBACK_TIMING_B)) { + WorldMtxManip manip(pM, pS, pWMAttr); + mpCallback->ExecCallbackB(&manip, mdl, this); + } + } + + void CheckCallbackC(math::MTX34 *pMtxArray, ResMdl mdl) { + if (mTiming & ScnObj::CALLBACK_TIMING_C) { + mpCallback->ExecCallbackC(pMtxArray, mdl, this); + } + } + +private: + ICalcWorldCallback *mpCallback; // at 0x0 + u8 mTiming; // at 0x4 + u8 PADDING_0x5; // at 0x5 + u16 mNodeID; // at 0x6 }; - -void CalcWorld(math::MTX34 *, u32 *, const u8 *, const math::MTX34 *, ResMdl, AnmObjChr *, FuncObjCalcWorld *, u32); - -void CalcWorld(math::MTX34 *, u32 *, const u8 *, const math::MTX34 *, ResMdl, AnmObjChr *, FuncObjCalcWorld *); - -void CalcSkinning(math::MTX34 *, u32 *, ResMdl, const u8 *); } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_camera.h b/include/nw4r/g3d/g3d_camera.h index da13cb0c..b9cd2a17 100644 --- a/include/nw4r/g3d/g3d_camera.h +++ b/include/nw4r/g3d/g3d_camera.h @@ -1,111 +1,121 @@ #ifndef NW4R_G3D_CAMERA_H #define NW4R_G3D_CAMERA_H -#include "common.h" -#include "nw4r/g3d/g3d_rescommon.h" -#include "nw4r/math/math_types.h" -#include "rvl/MTX.h" // IWYU pragma: export +#include + +#include + +#include + +#include namespace nw4r { namespace g3d { -struct CameraData { - math::MTX34 mCamMtx; // at 0x0 - math::MTX44 mProjMtx; // at 0x30 - u32 mFlags; - math::VEC3 mPos; // at 0x74 - math::VEC3 VEC3_0x80; - math::VEC3 VEC3_0x8C; - math::VEC3 VEC3_0x98; - f32 FLOAT_0xA4; - u32 INT_0xA8; - f32 FLOAT_0xAC; - f32 FLOAT_0xB0; - f32 FLOAT_0xB4; - f32 FLOAT_0xB8; - f32 FLOAT_0xBC; - f32 FLOAT_0xC0; - f32 FLOAT_0xC4; - f32 FLOAT_0xC8; - f32 FLOAT_0xCC; - f32 FLOAT_0xD0; - f32 FLOAT_0xD4; - f32 FLOAT_0xD8; - f32 FLOAT_0xDC; - f32 FLOAT_0xE0; - f32 FLOAT_0xE4; - f32 FLOAT_0xE8; - f32 FLOAT_0xEC; - f32 FLOAT_0xF0; - u32 INT_0xF4; - u32 INT_0xF8; - u32 INT_0xFC; - u32 INT_0x100; - u32 INT_0x104; - u32 INT_0x108; -}; -struct Camera { - struct PostureInfo { - u32 INT_0x0; - math::VEC3 VEC3_0x04; - math::VEC3 VEC3_0x10; - math::VEC3 VEC3_0x1C; - f32 FLOAT_0x28; - // . . . +struct CameraData { + enum Flag { + FLAG_CAM_LOOKAT = (1 << 0), + FLAG_CAM_ROTATE = (1 << 1), + FLAG_CAM_AIM = (1 << 2), + FLAG_CAM_MTX_READY = (1 << 3), + + FLAG_PROJ_FRUSTUM = (1 << 4), + FLAG_PROJ_PERSP = (1 << 5), + FLAG_PROJ_ORTHO = (1 << 6), + FLAG_PROJ_MTX_READY = (1 << 7), + + FLAG_VI_ODD_FIELD = (1 << 8), }; - ResCommon mCamData; + math::MTX34 cameraMtx; // at 0x0 + math::MTX44 projMtx; // at 0x30 + u32 flags; // at 0x70 + math::VEC3 cameraPos; // at 0x74 + math::VEC3 cameraUp; // at 0x80 + math::VEC3 cameraTarget; // at 0x8C + math::VEC3 cameraRotate; // at 0x98 + f32 cameraTwist; // at 0xA4 + GXProjectionType projType; // at 0xA8 + f32 projFovy; // at 0xAC + f32 projAspect; // at 0xB0 + f32 projNear; // at 0xB4 + f32 projFar; // at 0xB8 + f32 projTop; // at 0xBC + f32 projBottom; // at 0xC0 + f32 projLeft; // at 0xC4 + f32 projRight; // at 0xC8 + f32 lightScaleS; // at 0xCC + f32 lightScaleT; // at 0xD0 + f32 lightTransS; // at 0xD4 + f32 lightTransT; // at 0xD8 + math::VEC2 viewportOrigin; // at 0xDC + math::VEC2 viewportSize; // at 0xE4 + f32 viewportNear; // at 0xEC + f32 viewportFar; // at 0xF0 + u32 scissorX; // at 0xF4 + u32 scissorY; // at 0xF8 + u32 scissorWidth; // at 0xFC + u32 scissorHeight; // at 0x100 + s32 scissorOffsetX; // at 0x104 + s32 scissorOffsetY; // at 0x108 +}; - inline Camera(void *vptr) : mCamData(vptr) {} - inline void UpdateProjectionMtx() const { - CameraData &rCamData = mCamData.ref(); +class Camera : public ResCommon { +public: + enum PostureType { + POSTURE_LOOKAT, + POSTURE_ROTATE, + POSTURE_AIM + }; - if (rCamData.mFlags & 0x40) { - C_MTXOrtho( - rCamData.mProjMtx, rCamData.FLOAT_0xBC, rCamData.FLOAT_0xC0, rCamData.FLOAT_0xC4, rCamData.FLOAT_0xC8, - rCamData.FLOAT_0xB4, rCamData.FLOAT_0xB8 - ); - } else { - if (rCamData.mFlags & 0x10) { - C_MTXFrustum( - rCamData.mProjMtx, rCamData.FLOAT_0xBC, rCamData.FLOAT_0xC0, rCamData.FLOAT_0xC4, - rCamData.FLOAT_0xC8, rCamData.FLOAT_0xB4, rCamData.FLOAT_0xB8 - ); - } else { - C_MTXPerspective( - rCamData.mProjMtx, rCamData.FLOAT_0xAC, rCamData.FLOAT_0xB0, rCamData.FLOAT_0xB4, - rCamData.FLOAT_0xB8 - ); - } - } + struct PostureInfo { + PostureType tp; // at 0x0 + math::VEC3 cameraUp; // at 0x4 + math::VEC3 cameraTarget; // at 0x10 + math::VEC3 cameraRotate; // at 0x1C + f32 cameraTwist; // at 0x28 + }; - rCamData.mFlags |= 0x80; - } +public: + explicit Camera(CameraData *pData); - Camera(CameraData *); void Init(); - void Init(u16, u16, u16, u16, u16, u16); - void SetPosition(f32, f32, f32); - void SetPosition(const math::VEC3 &); - void SetPosture(const PostureInfo &); - void SetCameraMtxDirectly(const math::MTX34 &); - void SetPerspective(f32, f32, f32, f32); - void SetOrtho(f32, f32, f32, f32, f32, f32); - void SetProjectionMtxDirectly(const math::MTX44 *); - void SetScissor(u32, u32, u32, u32); - void SetScissorBoxOffset(s32, s32); - void SetViewport(f32, f32, f32, f32); - void SetViewportZRange(f32, f32); - void GetViewport(f32 *, f32 *, f32 *, f32 *, f32 *, f32 *) const; - void GetCameraMtx(math::MTX34 *) const; - void GetProjectionMtx(math::MTX44 *) const; - void GetProjectionTexMtx(math::MTX34 *) const; - void GetEnvironmentTexMtx(math::MTX34 *) const; + void Init(u16 efbWidth, u16 efbHeight, u16 xfbWidth, u16 xfbHeight, u16 viWidth, u16 viHeight); + + void SetPosition(f32 x, f32 y, f32 z); + void SetPosition(const math::VEC3 &rPos); + + void SetPosture(const PostureInfo &rInfo); + void SetCameraMtxDirectly(const math::MTX34 &rMtx); + void SetPerspective(f32 fovy, f32 aspect, f32 near, f32 far); + void SetOrtho(f32 top, f32 bottom, f32 left, f32 right, f32 near, f32 far); + void SetProjectionMtxDirectly(const math::MTX44 *pMtx); + + void SetScissor(u32 x, u32 y, u32 width, u32 height); + void SetScissorBoxOffset(s32 ox, s32 oy); + + void SetViewport(f32 x, f32 y, f32 width, f32 height); + void SetViewportZRange(f32 near, f32 far); + void GetViewport(f32 *pX, f32 *pY, f32 *pWidth, f32 *pHeight, f32 *pNear, f32 *pFar) const; + + void GetCameraMtx(math::MTX34 *pMtx) const; + void GetProjectionMtx(math::MTX44 *pMtx) const; + void GetProjectionTexMtx(math::MTX34 *pMtx) const; + void GetEnvironmentTexMtx(math::MTX34 *pMtx) const; + void GXSetViewport() const; void GXSetProjection() const; void GXSetScissor() const; void GXSetScissorBoxOffset() const; + + GXProjectionType GetProjectionType() const { + return ref().projType; + } + +private: void UpdateCameraMtx() const; + void UpdateProjectionMtx() const; }; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_cpu.h b/include/nw4r/g3d/g3d_cpu.h deleted file mode 100644 index 07599a08..00000000 --- a/include/nw4r/g3d/g3d_cpu.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef NW4R_G3D_CPU_H -#define NW4R_G3D_CPU_H -#include "common.h" - -namespace nw4r { -namespace g3d { -namespace detail { -void Copy32ByteBlocks(void *, const void *, u32); -void ZeroMemory32ByteBlocks(void *, u32); -} // namespace detail -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_dcc.h b/include/nw4r/g3d/g3d_dcc.h index 0c83c1f0..5a728b3a 100644 --- a/include/nw4r/g3d/g3d_dcc.h +++ b/include/nw4r/g3d/g3d_dcc.h @@ -1,13 +1,94 @@ #ifndef NW4R_G3D_DCC_H #define NW4R_G3D_DCC_H -#include "common.h" -#include "nw4r/math.h" -#include "nw4r/g3d/g3d_anmtexsrt.h" +#include + +#include +#include namespace nw4r { namespace g3d { -void CalcTexMtx(math::MTX34 *, bool, const TexSrt &, TexSrt::Flag, TexSrtTypedef::TexMatrixMode); -} + +void CalcTexMtx(math::MTX34 *pMtx, bool set, const TexSrt &rSrt, TexSrt::Flag flag, TexSrtTypedef::TexMatrixMode mode); + +namespace detail { + +class WorldMtxAttr { +public: + enum Attr { + ATTR_BILLBOARD_MASK = (1 << 8) - 1, + + ATTR_T_IGNORE = (1 << 27), + ATTR_S_UNIFORM = (1 << 28), + ATTR_ALL_S_UNIFORM = (1 << 29), + ATTR_S_ONE = (1 << 30), + ATTR_ALL_S_ONE = (1 << 31), + }; + +public: + static ResNodeData::Billboard GetBillboard(u32 attr) { + return static_cast(attr & ATTR_BILLBOARD_MASK); + } + static u32 SetBillboard(u32 attr, ResNodeData::Billboard billboard) { + return (attr & ~ATTR_BILLBOARD_MASK) | billboard; + } + + static bool IsIgnoreTrans(u32 attr) { + return (attr & ATTR_T_IGNORE) ? true : false; + } + static u32 AnmIgnoreTrans(u32 attr) { + return attr | ATTR_T_IGNORE; + } + static u32 AnmNotIgnoreTrans(u32 attr) { + return attr & ~ATTR_T_IGNORE; + } + + static bool IsScaleUniform(u32 attr) { + return (attr & ATTR_S_UNIFORM) ? true : false; + } + static u32 AnmScaleUniform(u32 attr) { + return attr | ATTR_S_UNIFORM; + } + static u32 AnmNotScaleUniform(u32 attr) { + return attr & ~(ATTR_S_UNIFORM | ATTR_ALL_S_UNIFORM | ATTR_S_ONE | ATTR_ALL_S_ONE); + } + + static bool IsAllScaleUniform(u32 attr) { + return (attr & ATTR_ALL_S_UNIFORM) ? true : false; + } + static u32 AnmAllScaleUniform(u32 attr) { + return attr | ATTR_ALL_S_UNIFORM; + } + static u32 AnmNotAllScaleUniform(u32 attr) { + return attr & ~(ATTR_ALL_S_UNIFORM | ATTR_ALL_S_ONE); + } + + static bool IsScaleOne(u32 attr) { + return (attr & ATTR_S_ONE) ? true : false; + } + static u32 AnmScaleOne(u32 attr) { + return attr | ATTR_S_ONE; + } + static u32 AnmNotScaleOne(u32 attr) { + return attr & ~(ATTR_S_ONE | ATTR_ALL_S_ONE); + } + + static bool IsAllScaleOne(u32 attr) { + return (attr & ATTR_ALL_S_ONE) ? true : false; + } + static u32 AnmAllScaleOne(u32 attr) { + return attr | ATTR_ALL_S_ONE; + } + static u32 AnmNotAllScaleOne(u32 attr) { + return attr & ~ATTR_ALL_S_ONE; + } + + static u32 GetRootMtxAttr() { + return ATTR_S_UNIFORM | ATTR_ALL_S_UNIFORM | ATTR_S_ONE | ATTR_ALL_S_ONE; + } +}; + +} // namespace detail +} // namespace g3d } // namespace nw4r #endif diff --git a/include/nw4r/g3d/g3d_draw.h b/include/nw4r/g3d/g3d_draw.h index 8a1a7585..c571e477 100644 --- a/include/nw4r/g3d/g3d_draw.h +++ b/include/nw4r/g3d/g3d_draw.h @@ -1,14 +1,52 @@ #ifndef NW4R_G3D_DRAW_H #define NW4R_G3D_DRAW_H -#include "common.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include + +#include +#include +#include +#include + +#include namespace nw4r { namespace g3d { -struct DrawResMdlReplacement {}; -void DrawResMdlDirectly(ResMdl mdl, const math::MTX34 *pViewPos, const math::MTX33 *pViewNrm, - const math::MTX34 *pViewEnv, const u8 *pOpa, const u8 *pXlu, DrawResMdlReplacement *pRep, u32 resMdlDrawMode); +// Forward declarations +namespace G3DState { +class IndMtxOp; +} + +namespace detail { + +G3DState::IndMtxOp *GetIndMtxOp(ResMat mat, ResNode node, ResShp shp); + +} // namespace detail + +struct DrawResMdlReplacement { + u8 *visArray; // at 0x0 + ResTexObjData *texObjDataArray; // at 0x4 + ResTlutObjData *tlutObjDataArray; // at 0x8 + ResTexSrtData *texSrtDataArray; // at 0xC + ResChanData *chanDataArray; // at 0x10 + ResGenModeData *genModeDataArray; // at 0x14 + ResMatMiscData *matMiscDataArray; // at 0x18 + ResPixDL *pixDLArray; // at 0x1C + ResTevColorDL *tevColorDLArray; // at 0x20 + ResIndMtxAndScaleDL *indMtxAndScaleDLArray; // at 0x24 + ResTexCoordGenDL *texCoordGenDLArray; // at 0x28 + ResTevData *tevDataArray; // at 0x2C + ResVtxPosData **vtxPosTable; // at 0x30 + ResVtxNrmData **vtxNrmTable; // at 0x34 + ResVtxClrData **vtxClrTable; // at 0x38 +}; + +void DrawResMdlDirectly( + const ResMdl mdl, const math::MTX34 *pViewPosMtxArray, const math::MTX33 *pViewNrmMtxArray, + const math::MTX34 *pViewEnvMtxArray, const u8 *pByteCodeOpa, const u8 *pByteCodeXlu, + DrawResMdlReplacement *pReplacement, u32 drawMode +); + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_draw1mat1shp.h b/include/nw4r/g3d/g3d_draw1mat1shp.h index 694b8974..956222bb 100644 --- a/include/nw4r/g3d/g3d_draw1mat1shp.h +++ b/include/nw4r/g3d/g3d_draw1mat1shp.h @@ -1,15 +1,51 @@ -#ifndef NW4R_G3D_DRAW1_MAT1_SHP_H -#define NW4R_G3D_DRAW1_MAT1_SHP_H -#include "common.h" -#include "nw4r/g3d/g3d_resmat.h" -#include "nw4r/g3d/g3d_resshp.h" +#ifndef NW4R_G3D_DRAW_1MAT_1SHP_H +#define NW4R_G3D_DRAW_1MAT_1SHP_H +#include + +#include +#include + +#include namespace nw4r { namespace g3d { -struct Draw1Mat1ShpSwap {}; -void Draw1Mat1ShpDirectly(ResMat, ResShp, const math::MTX34 *, const math::MTX34 *, u32, Draw1Mat1ShpSwap *, - G3DState::IndMtxOp *); +// Forward declarations +namespace G3DState { +class IndMtxOp; +} + +enum Draw1Mat1ShpCtrl { + DRAW1MAT1SHP_CTRL_NOPPCSYNC = (1 << 0), + DRAW1MAT1SHP_CTRL_NOSWAPSHP = (1 << 1), + DRAW1MAT1SHP_CTRL_CULL_FRONT = (1 << 2), + DRAW1MAT1SHP_CTRL_FORCE_LIGHTOFF = (1 << 3), +}; + +struct Draw1Mat1ShpSwap { + ResTexObj texObj; // at 0x0 + ResTlutObj tlutObj; // at 0x4 + ResGenMode genMode; // at 0x8 + ResTev tev; // at 0xC + ResMatPix pix; // at 0x10 + ResMatTevColor tevColor; // at 0x14 + ResMatIndMtxAndScale indMtxAndScale; // at 0x18 + ResMatChan chan; // at 0x1C + ResMatTexCoordGen texCoordGen; // at 0x20 + ResMatMisc misc; // at 0x24 + ResTexSrt texSrt; // at 0x28 + ResVtxPosData **vtxPosTable; // at 0x2C + ResVtxNrmData **vtxNrmTable; // at 0x30 + ResVtxClrData **vtxClrTable; // at 0x34 + + Draw1Mat1ShpSwap() : vtxPosTable(NULL), vtxNrmTable(NULL), vtxClrTable(NULL) {} +}; + +void Draw1Mat1ShpDirectly( + ResMat mat, ResShp shp, const math::MTX34 *pViewPos, const math::MTX34 *pViewNrm, u32 ctrl, Draw1Mat1ShpSwap *pSwap, + G3DState::IndMtxOp *pIndMtxOp +); + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_fog.h b/include/nw4r/g3d/g3d_fog.h index ebbea9a2..03e41cf6 100644 --- a/include/nw4r/g3d/g3d_fog.h +++ b/include/nw4r/g3d/g3d_fog.h @@ -1,72 +1,83 @@ #ifndef NW4R_G3D_FOG_H #define NW4R_G3D_FOG_H -#include "common.h" -#include "nw4r/g3d/g3d_rescommon.h" -#include "nw4r/math/math_types.h" -#include "rvl/GX.h" // IWYU pragma: export +#include + +#include + +#include +#include + +#include namespace nw4r { namespace g3d { + struct FogData { - GXFogType mFogType; // at 0x0 - f32 mStartZ; // at 0x4 - f32 mEndZ; // at 0x8 - f32 mNear; // at 0xC - f32 mFar; // at 0x10 - GXColor mColor; // at 0x14 - u8 mFogRangeAdjEnable; // at 0x18 - u8 BYTE_0x19; - u16 mAdjTableWidth; // at 0x1A - GXFogAdjTable mAdjTable; // at 0x1C + GXFogType type; // at 0x0 + f32 startz; // at 0x4 + f32 endz; // at 0x8 + f32 nearz; // at 0xC + f32 farz; // at 0x10 + GXColor color; // at 0x14 + GXBool adjEnable; // at 0x18 + u8 PADDING_0x19; // at 0x19 + u16 adjCenter; // at 0x1A + GXFogAdjTable adjTable; // at 0x1C }; -struct Fog { - ResCommon mFogData; +class Fog : public ResCommon { +public: + explicit Fog(FogData *pData); - inline Fog(void *vptr) : mFogData(vptr) {} - - Fog(FogData *); void Init(); - void *CopyTo(void *) const; - void SetFogRangeAdjParam(u16, u16, const math::MTX44 &); + Fog CopyTo(void *pDst) const; + + void SetFogRangeAdjParam(u16 width, u16 center, const math::MTX44 &rProjMtx); void SetGP() const; - bool IsValid() const { - return mFogData.IsValid(); + void SetFogType(GXFogType type) { + if (!IsValid()) { + return; + } + + ref().type = type; + } + + void SetZ(f32 startZ, f32 endZ) { + if (!IsValid()) { + return; + } + + FogData &r = ref(); + + r.startz = startZ; + r.endz = endZ; + } + + void SetNearFar(f32 nearZ, f32 farZ) { + if (!IsValid()) { + return; + } + + FogData &r = ref(); + + r.nearz = nearZ; + r.farz = farZ; + } + + void SetFogColor(GXColor color) { + if (!IsValid()) { + return; + } + + ref().color = color; } bool IsFogRangeAdjEnable() const { - return (IsValid() && mFogData.ref().mFogRangeAdjEnable != 1) ? true : false; - } - - void SetFogColor(GXColor c) { - if (IsValid()) { - mFogData.ref().mColor = c; - } - } - - void SetFogType(GXFogType fog) { - if (IsValid()) { - mFogData.ref().mFogType = fog; - } - } - - void SetNearFar(f32 near, f32 far) { - if (IsValid()) { - FogData &ref = mFogData.ref(); - ref.mNear = near; - ref.mFar = far; - } - } - - void SetZ(f32 start, f32 end) { - if (IsValid()) { - FogData &ref = mFogData.ref(); - ref.mStartZ = start; - ref.mEndZ = end; - } + return IsValid() && ref().adjEnable == TRUE; } }; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_gpu.h b/include/nw4r/g3d/g3d_gpu.h deleted file mode 100644 index e71584e2..00000000 --- a/include/nw4r/g3d/g3d_gpu.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef NW4R_G3D_GPU_H -#define NW4R_G3D_GPU_H -#include "common.h" -#include "nw4r/g3d/g3d_rescommon.h" -#include "nw4r/math/math_types.h" -#include "rvl/GX.h" - -namespace nw4r { -namespace g3d { -namespace fifo { -const u8 cm2hw[] = {0x00, 0x02, 0x01, 0x03}; - -inline void LoadXFCmd(u16 us, u32 ul) { - GXCmd1u8(FIFO_ACCESS_XF); - GXCmd1u16(0); - GXCmd1u16(us); - GXCmd1u32(ul); -} - -inline void LoadBPCmd(u32 ul) { - GXCmd1u8(FIFO_ACCESS_BP); - GXCmd1u32(ul); -} - -inline void LoadXFCmdHdr(u16 us, u8 uc) { - GXCmd1u8(FIFO_ACCESS_XF); - GXCmd1u16((u16)(uc - 1)); - GXCmd1u16(us); -} - -inline void LoadCPCmd(u8 uc, u32 ul) { - GXCmd1u8(FIFO_ACCESS_CP); - GXCmd1u8(uc); - GXCmd1u32(ul); -} - -void GDSetGenMode2(u8, u8, u8, u8, GXCullMode); -void GDSetCullMode(GXCullMode); -void GDSetTexCoordScale2(GXTexCoordID, u16, u8, u8, u16, u8, u8); -void GDSetIndTexMtx(u32, const math::MTX34 &); -void GDResetCurrentMtx(); -void GDSetCurrentMtx(const u32 *); -void GDLoadTexMtxImm3x3(const math::MTX33 &, u32); -} // namespace fifo -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_init.h b/include/nw4r/g3d/g3d_init.h index 7e3874f1..6cf6ed9e 100644 --- a/include/nw4r/g3d/g3d_init.h +++ b/include/nw4r/g3d/g3d_init.h @@ -1,10 +1,15 @@ #ifndef NW4R_G3D_INIT_H #define NW4R_G3D_INIT_H +#include + +#include namespace nw4r { namespace g3d { -void G3dInit(bool); + +void G3dInit(bool enableLockedCache); void G3dReset(); + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_light.h b/include/nw4r/g3d/g3d_light.h index 623a2e68..8fe540d3 100644 --- a/include/nw4r/g3d/g3d_light.h +++ b/include/nw4r/g3d/g3d_light.h @@ -1,150 +1,183 @@ #ifndef NW4R_G3D_LIGHT_H #define NW4R_G3D_LIGHT_H -#include "common.h" -#include "nw4r/g3d/g3d_rescommon.h" // IWYU pragma: export -#include "nw4r/math.h" // IWYU pragma: export -#include "rvl/GX.h" // IWYU pragma: export +#include + +#include +#include + +#include namespace nw4r { namespace g3d { -struct LightSetData { - static const int NUM_LIGHTS = 8; - - s8 mLights[NUM_LIGHTS]; // at 0x0 - s8 mAmbient; // at 0x8 - char UNK_0x8[3]; // at 0x9 -}; - -struct AmbLightObj { - u8 r, g, b, a; -}; - -struct AmbLightAnmResult {}; +/****************************************************************************** + * + * LightObj + * + ******************************************************************************/ class LightObj { -private: - enum LightObjFlag { - SPOT_LIGHT = 0x1, - SPECULAR_LIGHT = 0x2, - ENABLED = 0x4, - SPECULAR_DIR = 0x8, - COLOR_ENABLE = 0x10, - ALPHA_ENABLE = 0x20 - }; - public: - LightObj() : mFlags() {} + LightObj() : mFlag(0) {} + ~LightObj() {} + + LightObj &operator=(const LightObj &rOther); operator GXLightObj *() { - return &mLightObj; + return &mObj; } operator const GXLightObj *() const { - return &mLightObj; + return &mObj; } - LightObj &operator=(const LightObj &rhs); + void Clear(); + + void InitLightColor(GXColor color); + void InitLightPos(f32 x, f32 y, f32 z); + void InitLightDir(f32 nx, f32 ny, f32 nz); + void InitSpecularDir(f32 nx, f32 ny, f32 nz); + void InitLightSpot(f32 cutoff, GXSpotFn spotFn); + void InitLightAttnA(f32 aa, f32 ab, f32 ac); + void InitLightDistAttn(f32 distance, f32 brightness, GXDistAttnFn distAttnFn); + void InitLightAttnK(f32 ka, f32 kb, f32 kc); + void InitLightShininess(f32 shininess); + + void GetLightPos(math::VEC3 *pPos) const; + void GetLightDir(math::VEC3 *pDir) const; + + void ApplyViewMtx(const math::MTX34 &rCamera); + + void Enable() { + mFlag |= FLAG_ENABLE_LIGHT; + } + void Disable() { + mFlag &= ~FLAG_ENABLE_LIGHT; + } + + bool IsEnable() const { + return (mFlag & FLAG_ENABLE_LIGHT) ? true : false; + } bool IsSpotLight() const { - return mFlags & SPOT_LIGHT; + return (mFlag & FLAG_SPOT) ? true : false; } bool IsSpecularLight() const { - return mFlags & SPECULAR_LIGHT; - } - bool IsEnable() const { - return mFlags & ENABLED; + return (mFlag & FLAG_SPECULAR) ? true : false; } bool IsSpecularDir() const { - return mFlags & SPECULAR_DIR; + return (mFlag & FLAG_SPECULAR_DIR) ? true : false; } + bool IsColorEnable() const { - return mFlags & COLOR_ENABLE; + return !(mFlag & FLAG_DISABLE_COLOR); } + void DisableColor() { + mFlag |= FLAG_DISABLE_COLOR; + } + bool IsAlphaEnable() const { - return mFlags & ALPHA_ENABLE; + return !(mFlag & FLAG_DISABLE_ALPHA); } + void DisableAlpha() { + mFlag |= FLAG_DISABLE_ALPHA; + } + bool IsDiffuseLight() const { return !IsSpotLight() && !IsSpecularLight(); } - void Enable() { - mFlags |= ENABLED; - } - void Disable() { - mFlags &= ~ENABLED; - } - - void Clear(); - void InitLightColor(GXColor); - void InitLightPos(f32, f32, f32); - void InitLightDir(f32, f32, f32); - void InitSpecularDir(f32, f32, f32); - void InitLightSpot(f32, GXSpotFn); - void InitLightAttnA(f32, f32, f32); - void InitLightDistAttn(f32, f32, GXDistAttnFn); - void InitLightAttnK(f32, f32, f32); - void InitLightShininess(f32); - void GetLightPos(math::VEC3 *) const; - void GetLightDir(math::VEC3 *) const; - void ApplyViewMtx(const math::MTX34 &rMtx); +private: + enum LightObjFlag { + FLAG_SPOT = (1 << 0), + FLAG_SPECULAR = (1 << 1), + FLAG_ENABLE_LIGHT = (1 << 2), + FLAG_SPECULAR_DIR = (1 << 3), + FLAG_DISABLE_COLOR = (1 << 4), + FLAG_DISABLE_ALPHA = (1 << 5) + }; private: - u32 mFlags; // at 0x0 - GXLightObj mLightObj; // at 0x4 + u32 mFlag; // at 0x0 + GXLightObj mObj; // at 0x4 }; -struct LightAnmResult {}; +/****************************************************************************** + * + * LightSet + * + ******************************************************************************/ +struct LightSetData { + s8 idxLight[G3DState::NUM_LIGHT_IN_LIGHT_SET]; // at 0x0 + s8 idxAmbLight; // at 0x8 + u8 PADDING_0x9[0xC - 0X9]; // at 0x9 +}; -struct LightSet { - LightSet(LightSetting *setting, LightSetData *data) : mSetting(setting), mLightSetData(data) {} +class LightSet { +public: + LightSet(LightSetting *pSetting, LightSetData *pData) : mpSetting(pSetting), mpLightSetData(pData) {} + ~LightSet() {} bool IsValid() const { - return mSetting != NULL && mLightSetData != NULL; + return mpSetting != NULL && mpLightSetData != NULL; } - bool SelectLightObj(u32, int); - bool SelectAmbLightObj(int); + bool SelectLightObj(u32 lightIdx, int lightObjIdx); + bool SelectAmbLightObj(int lightObjIdx); - LightSetting *mSetting; // at 0x0 - LightSetData *mLightSetData; // at 0x4 +private: + LightSetting *mpSetting; // at 0x0 + LightSetData *mpLightSetData; // at 0x4 +}; + +/****************************************************************************** + * + * LightSetting + * + ******************************************************************************/ +struct AmbLightObj { + u8 r, g, b, a; }; class LightSetting { public: - LightSetting(LightObj *, AmbLightObj *, u32, LightSetData *, u32); - bool Import(const LightSetting &); - void ApplyViewMtx(const math::MTX34 &, u32); + LightSetting( + LightObj *pLightObjArray, AmbLightObj *pAmbLightObjArray, u32 numLight, LightSetData *pLightSetDataArray, + u32 numLightSet + ); + ~LightSetting() {} - u16 GetNumLightObj() const { - return mNumLightObj; + bool Import(const LightSetting &rSetting); + void ApplyViewMtx(const math::MTX34 &rCamera, u32 numLight); + + u32 GetNumLightObj() const { + return mNumLight; } - u16 GetNumLightSet() const { + u32 GetNumLightSet() const { return mNumLightSet; } + LightObj *GetLightObjArray() const { - return mLightObjArray; + return mpLightObjArray; } AmbLightObj *GetAmbLightObjArray() const { - return mAmbLightObjArray; - } - LightSetData *GetLightSetDataArray() const { - return mLightSetDataArray; + return mpAmbLightObjArray; } - LightSet GetLightSet(int i) { - if (i < mNumLightSet && i > 0) { - return LightSet(this, &mLightSetDataArray[i]); + LightSet GetLightSet(int idx) { + if (idx < mNumLightSet && idx >= 0) { + return LightSet(this, &mpLightSetDataArray[idx]); } return LightSet(this, NULL); } private: - u16 mNumLightObj; // at 0x0 - u16 mNumLightSet; // at 0x2 - LightObj *mLightObjArray; // at 0x4 - AmbLightObj *mAmbLightObjArray; // at 0x8 - LightSetData *mLightSetDataArray; // at 0xC + u16 mNumLight; // at 0x0 + u16 mNumLightSet; // at 0x2 + LightObj *mpLightObjArray; // at 0x4 + AmbLightObj *mpAmbLightObjArray; // at 0x8 + LightSetData *mpLightSetDataArray; // at 0xC }; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_maya.h b/include/nw4r/g3d/g3d_maya.h index 4e344bb9..f890eda6 100644 --- a/include/nw4r/g3d/g3d_maya.h +++ b/include/nw4r/g3d/g3d_maya.h @@ -1,15 +1,22 @@ #ifndef NW4R_G3D_MAYA_H #define NW4R_G3D_MAYA_H -#include "common.h" -#include "nw4r/g3d/g3d_anmtexsrt.h" -#include "nw4r/math.h" +#include + +#include namespace nw4r { namespace g3d { namespace detail { namespace dcc { -bool CalcTexMtx_Maya(math::MTX34 *, bool, const TexSrt &, TexSrt::Flag); -} + +bool CalcTexMtx_Maya(math::MTX34 *pMtx, bool set, const TexSrt &rSrt, TexSrt::Flag flag); + +u32 CalcWorldMtx_Maya_SSC_Apply( + math::MTX34 *pW, math::VEC3 *pS, const math::MTX34 *pW1, const math::VEC3 *pS1, u32 attr, + const ChrAnmResult *pResult +); + +} // namespace dcc } // namespace detail } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_obj.h b/include/nw4r/g3d/g3d_obj.h index f4782073..5991c458 100644 --- a/include/nw4r/g3d/g3d_obj.h +++ b/include/nw4r/g3d/g3d_obj.h @@ -1,133 +1,148 @@ -#ifndef NW4R_G3D_G3DOBJ_H -#define NW4R_G3D_G3DOBJ_H -#include "common.h" -#include "rvl/MEM/mem_allocator.h" +#ifndef NW4R_G3D_OBJ_H +#define NW4R_G3D_OBJ_H +#include -#define NW4R_G3D_TYPE_OBJ_DECL(VAL) static const nw4r::g3d::G3dObj::ResNameDataT TYPE_NAME -#define NW4R_G3D_TYPE_OBJ_DEF(VAL) \ - const nw4r::g3d::G3dObj::ResNameDataT VAL::TYPE_NAME = {sizeof(#VAL), #VAL} +#include +#include namespace nw4r { namespace g3d { -namespace detail { -inline void *AllocFromAllocator(MEMAllocator *pAllocator, u32 size) { - return MEMAllocFromAllocator(pAllocator, size); +namespace { + +/****************************************************************************** + * + * Alignment + * + ******************************************************************************/ +inline u32 align4(u32 x) { + return ROUND_UP(x, 4); +} +inline u32 align32(u32 x) { + return ROUND_UP(x, 32); } -inline void FreeToAllocator(MEMAllocator *pAllocator, void *pBlock) { - return MEMFreeToAllocator(pAllocator, pBlock); -} -} // namespace detail +} // namespace +/****************************************************************************** + * + * G3dObj + * + ******************************************************************************/ class G3dObj { public: + template + struct ResNameDataT { + u32 len; // at 0x0 + // @bug 'N' already includes the null terminator + char str[ROUND_UP(N + 1, 4)]; // at 0x4 + }; + + class TypeObj { + public: + struct ResNameDataPT { + u32 len; // at 0x0 + char str[4]; // at 0x4 + }; + + public: + template + explicit TypeObj(const ResNameDataT &rName) : mName(reinterpret_cast(&rName)) {} + + u32 GetTypeID() const { + // @note Address is used for comparing TypeObjs + return reinterpret_cast(mName); + } + + const char *GetTypeName() const { + return mName->str; + } + + bool operator==(const TypeObj &rOther) const { + return GetTypeID() == rOther.GetTypeID(); + } + + private: + const ResNameDataPT *mName; // at 0x0 + }; + enum G3dProcTask { - G3DPROC_CALC_WORLD = 0x1, - G3DPROC_CALC_MAT = 0x2, - G3DPROC_CALC_VTX = 0x3, - G3DPROC_CALC_VIEW = 0x4, - G3DPROC_GATHER_SCNOBJ = 0x5, - G3DPROC_DRAW_OPA = 0x6, - G3DPROC_DRAW_XLU = 0x7, - G3DPROC_UPDATEFRAME = 0x8, + G3DPROC_NONE = 0x00000, + + G3DPROC_CALC_WORLD = 0x00001, + G3DPROC_CALC_MAT = 0x00002, + G3DPROC_CALC_VTX = 0x00003, + G3DPROC_CALC_VIEW = 0x00004, + G3DPROC_GATHER_SCNOBJ = 0x00005, + G3DPROC_DRAW_OPA = 0x00006, + G3DPROC_DRAW_XLU = 0x00007, + G3DPROC_UPDATEFRAME = 0x00008, + + // Tasks below cannot be disabled + __G3DPROC_OPTIONAL_END, G3DPROC_CHILD_DETACHED = 0x10001, G3DPROC_ATTACH_PARENT = 0x10002, G3DPROC_DETACH_PARENT = 0x10003, - G3DPROC_0x10004 = 0x10004 - }; - - template - struct ResNameDataT { - u32 mLength; - // Bug? +1 seemingly for null terminator, - // but size N already includes it - char mName[N + 1 + 3 & ~3]; - }; - - struct TypeObj { - struct TypeObjData { - u32 mLength; // at 0x0 - char mName[]; // at 0x4 - }; - - template - TypeObj(const ResNameDataT &pRes) : mData((const TypeObjData *)&pRes) {} - - u32 GetTypeID() const { - return (u32)mData; - } - - const char *GetTypeName() const { - return mData->mName; - } - - bool operator==(const TypeObj &rhs) const { - return GetTypeID() == rhs.GetTypeID(); - } - - const TypeObjData *mData; // at 0x0 + G3DPROC_ZSORT = 0x10004 }; public: - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { + virtual bool IsDerivedFrom(TypeObj other) const { return other == GetTypeObjStatic(); - } - virtual void G3dProc(u32, u32, void *) = 0; // at 0xC - virtual ~G3dObj(); // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } + } // at 0x8 + virtual void G3dProc(u32 task, u32 param, void *pInfo) = 0; // at 0xC + virtual ~G3dObj(); // at 0x10 + + virtual const TypeObj GetTypeObj() const { + return TypeObj(TYPE_NAME); + } // at 0x14 static const G3dObj::TypeObj GetTypeObjStatic() { return TypeObj(TYPE_NAME); } + virtual const char *GetTypeName() const { + return GetTypeObj().GetTypeName(); + } // at 0x18 + + G3dObj(MEMAllocator *pAllocator, G3dObj *pParent) : mpHeap(pAllocator), mpParent(pParent) {} + + G3dObj *GetParent() const { + return mpParent; + } + void SetParent(G3dObj *pParent) { + mpParent = pParent; + } void Destroy(); void DetachFromParent(); - G3dObj(MEMAllocator *pAllocator, G3dObj *pParent) : mAllocator(pAllocator), mParent(pParent) {} - - G3dObj *GetParent() const { - return mParent; - } - void SetParent(G3dObj *parent) { - mParent = parent; - } - static void *Alloc(MEMAllocator *pAllocator, u32 size) { return detail::AllocFromAllocator(pAllocator, size); } - static void Dealloc(MEMAllocator *pAllocator, void *pBlock) { detail::FreeToAllocator(pAllocator, pBlock); } - static inline void *operator new(size_t size, void *pBlock) { + static inline void *operator new(size_t /* size */, void *pBlock) { return pBlock; } - static inline void operator delete(void *pBlock) {} + static inline void operator delete(void * /* pBlock */) {} - template - static T *DynamicCast(G3dObj *obj) { - if (obj != nullptr && obj->IsDerivedFrom(T::GetTypeObjStatic())) { - return static_cast(obj); + template + static TTo *DynamicCast(G3dObj *pObj) { + if (pObj != NULL && pObj->IsDerivedFrom(TTo::GetTypeObjStatic())) { + return static_cast(pObj); } return nullptr; } private: - G3dObj *mParent; // at 0x4 - MEMAllocator *mAllocator; // at 0x8 + G3dObj *mpParent; // at 0x4 + MEMAllocator *mpHeap; // at 0x8 - NW4R_G3D_TYPE_OBJ_DECL(G3dObj); + __NW4R_G3D_TYPEOBJ_DECL(G3dObj); }; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_resanm.h b/include/nw4r/g3d/g3d_resanm.h deleted file mode 100644 index f4c0335e..00000000 --- a/include/nw4r/g3d/g3d_resanm.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef NW4R_G3D_RESANM_H -#define NW4R_G3D_RESANM_H -#include "common.h" - -namespace nw4r { -namespace g3d { -struct ResKeyFrameAnmFramesData { - float mTime; // at 0x0 - float mValue; // at 0x4 - float mDerivative; // at 0x8 -}; - -struct ResKeyFrameAnmData { - u16 mCount; // at 0x0 - float FLOAT_0x4; - ResKeyFrameAnmFramesData mFrames[]; // at 0x8 -}; - -struct ResColorAnmFramesData { - u32 mColor; // at 0x0 -}; - -union ResColorAnmData { - u32 mColor; - s32 mOffset; -}; - -struct ResBoolAnmFramesData { - u32 mFlags; // at 0x0 -}; - -union ResAnmData { - float mValue; - s32 mOffset; -}; - -namespace detail { -float GetResKeyFrameAnmResult(const ResKeyFrameAnmData *, float); - -u32 GetResColorAnmResult(const ResColorAnmFramesData *, float); - -inline u32 GetResColorAnmResult(const ResColorAnmData *pData, float time, bool b) { - if (b) { - return pData->mColor; - } - - return GetResColorAnmResult((const ResColorAnmFramesData *)((u8 *)pData + pData->mOffset), time); -} - -inline bool GetResBoolAnmFramesResult(const ResBoolAnmFramesData *pData, int i) { - u32 index = i; - - u32 mask = 0x80000000 >> (index % 32); - u32 flags = pData[index / 32].mFlags; - - return flags & mask; -} - -template -inline float ClipFrame(T &info, float time) { - if (time <= 0.0f) { - return 0.0f; - } - - if (info.mNumFrames <= time) { - return info.mNumFrames; - } - - return time; -} - -inline float GetResAnmResult(const ResAnmData *pData, float time, bool b) { - if (b) { - return pData->mValue; - } - - return GetResKeyFrameAnmResult((const ResKeyFrameAnmData *)((u8 *)pData + pData->mOffset), time); -} -} // namespace detail -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resanmcamera.h b/include/nw4r/g3d/g3d_resanmcamera.h deleted file mode 100644 index 3dc8a33b..00000000 --- a/include/nw4r/g3d/g3d_resanmcamera.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef NW4R_G3D_RESANMCAMERA_H -#define NW4R_G3D_RESANMCAMERA_H -#include "common.h" -#include "nw4r/g3d/g3d_anmcamera.h" -#include "nw4r/g3d/g3d_rescommon.h" - -namespace nw4r { -namespace g3d { -struct ResAnmCameraData { - char UNK_0x0[0xC]; - u32 mID; // at 0xC -}; - -struct ResAnmCamera { - ResCommon mAnmCamera; - - inline ResAnmCamera(void *vptr) : mAnmCamera(vptr) {} - - bool IsValid() const { - return mAnmCamera.IsValid(); - } - - void GetAnmResult(CameraAnmResult *, f32) const; -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resanmchr.h b/include/nw4r/g3d/g3d_resanmchr.h deleted file mode 100644 index 76e08a34..00000000 --- a/include/nw4r/g3d/g3d_resanmchr.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef NW4R_G3D_RESANMCHR_H -#define NW4R_G3D_RESANMCHR_H -#include "common.h" -#include "nw4r/g3d/g3d_rescommon.h" - -namespace nw4r { -namespace g3d { -struct ResAnmChrData { - char UNK_0x0[0x8]; - u32 mRevision; // at 0x8 - char UNK_0xC[0x4]; - s32 mMatDictOffset; // at 0x10 - char UNK_0x14[0x0C]; - u16 mNumFrames; // at 0x20 - AnmPolicy mAnmPolicy; // at 0x24 -}; - -struct ResAnmChr { - enum { REVISION = 4 }; - - ResCommon mAnmChr; - - inline ResAnmChr(void *vptr) : mAnmChr(vptr) {} - - inline bool CheckRevision() const { - return mAnmChr.ref().mRevision == REVISION; - } - - AnmPolicy GetAnmPolicy() const - { - return mAnmChr.ref().mAnmPolicy; - } - - int GetNumFrame() const - { - return mAnmChr.ref().mNumFrames; - } -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resanmclr.h b/include/nw4r/g3d/g3d_resanmclr.h deleted file mode 100644 index 78feba26..00000000 --- a/include/nw4r/g3d/g3d_resanmclr.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef NW4R_G3D_RESANMCLR_H -#define NW4R_G3D_RESANMCLR_H -#include "nw4r/g3d/g3d_resdict.h" -#include "nw4r/g3d/g3d_resanm.h" -#include "nw4r/g3d/g3d_anmclr.h" - -namespace nw4r -{ - namespace g3d - { - struct ResAnmClrInfoData - { - char UNK_0x0[0x8]; - u16 mNumFrames; - }; - - struct ResAnmClrMatData - { - char UNK_0x0[0x4]; - u32 mFlags; // at 0x4 - - struct AnmData - { - UNKWORD WORD_0x0; - ResColorAnmData mColor; // at 0x4 - } mAnms[]; // at 0x8 - }; - - struct ResAnmClrData - { - char UNK_0x0[0x8]; - u32 mRevision; // at 0x8 - char UNK_0xC[0x4]; - s32 mMatDictOffset; // at 0x10 - ResAnmClrInfoData mInfo; // at 0x14 - char UNK_0x1E[0x2]; - u16 mNumFrames; // at 0x20 - AnmPolicy mAnmPolicy; // at 0x24 - }; - - struct ResAnmClr - { - enum - { - REVISION = 3 - }; - - ResCommon mAnmClr; - - inline ResAnmClr(void * vptr) : mAnmClr(vptr) {} - - inline ResAnmClrData & ref() const - { - return mAnmClr.ref(); - } - - inline bool CheckRevision() const - { - return ref().mRevision == REVISION; - } - - AnmPolicy GetAnmPolicy() const - { - return ref().mAnmPolicy; - } - - int GetNumFrame() const - { - return ref().mNumFrames; - } - - inline const ResAnmClrMatData * GetMatAnm(u32 i) const - { - return static_cast(mAnmClr.ofs_to_obj(ref().mMatDictOffset)[i]); - } - - void GetAnmResult(ClrAnmResult *, u32, float) const; - }; - } -} - -#endif diff --git a/include/nw4r/g3d/g3d_resanmfog.h b/include/nw4r/g3d/g3d_resanmfog.h deleted file mode 100644 index 77443159..00000000 --- a/include/nw4r/g3d/g3d_resanmfog.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef NW4R_G3D_RESANMFOG_H -#define NW4R_G3D_RESANMFOG_H -#include "common.h" -#include "nw4r/g3d/g3d_anmfog.h" -#include "nw4r/g3d/g3d_rescommon.h" - -namespace nw4r { -namespace g3d { -struct ResAnmFogData { - char UNK_0x0[0xC]; - u32 mID; // at 0xC -}; - -struct ResAnmFog { - ResCommon mAnmFog; - - inline ResAnmFog(void *vptr) : mAnmFog(vptr) {} - - void GetAnmResult(FogAnmResult *, f32) const; - - bool IsValid() const { - return mAnmFog.IsValid(); - } -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resanmscn.h b/include/nw4r/g3d/g3d_resanmscn.h deleted file mode 100644 index 3f7af493..00000000 --- a/include/nw4r/g3d/g3d_resanmscn.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef NW4R_G3D_RESANMSCN_H -#define NW4R_G3D_RESANMSCN_H -#include "common.h" -#include "nw4r/g3d/g3d_resanmcamera.h" -#include "nw4r/g3d/g3d_resanmfog.h" -#include "nw4r/g3d/g3d_rescommon.h" - -namespace nw4r { -namespace g3d { -struct ResAnmScnData { - char UNK_0x0[0x8]; - u32 mRevision; // at 0x8 - char UNK_0xC[0x3E - 0xC]; - u16 mFogMaxRefNum; // at 0x3E -}; - -struct ResAnmScn { - enum { REVISION = 4 }; - - ResCommon mAnmScn; - - ResAnmFog GetResAnmFogByRefNumber(u32) const; - ResAnmCamera GetResAnmCameraByRefNumber(u32) const; - - inline ResAnmScn(void *vptr) : mAnmScn(vptr) {} - - inline bool IsValid() const { - return mAnmScn.IsValid(); - } - inline bool CheckRevision() const { - return mAnmScn.ref().mRevision == REVISION; - } - - u16 GetResAnmFogMaxRefNumber() const { - return mAnmScn.ref().mFogMaxRefNum; - } -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resanmshp.h b/include/nw4r/g3d/g3d_resanmshp.h deleted file mode 100644 index 332065da..00000000 --- a/include/nw4r/g3d/g3d_resanmshp.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef NW4R_G3D_RESANMSHP_H -#define NW4R_G3D_RESANMSHP_H -#include "common.h" -#include "nw4r/g3d/g3d_anmobj.h" -#include "nw4r/g3d/g3d_rescommon.h" - -namespace nw4r { -namespace g3d { -struct ResAnmShpData { - char UNK_0x0[0x8]; - u32 mRevision; // at 0x8 - char UNK_0xC[0x24 - 0xC]; - u16 mNumFrames; // at 0x24 - AnmPolicy mAnmPolicy; // at 0x28 -}; - -struct ResAnmShp { - enum { REVISION = 3 }; - - ResCommon mAnmShp; - - inline ResAnmShp(void *vptr) : mAnmShp(vptr) {} - - inline bool CheckRevision() const { - return mAnmShp.ref().mRevision == REVISION; - } - - AnmPolicy GetAnmPolicy() const { - return mAnmShp.ref().mAnmPolicy; - } - - int GetNumFrame() const { - return mAnmShp.ref().mNumFrames; - } -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resanmtexpat.h b/include/nw4r/g3d/g3d_resanmtexpat.h deleted file mode 100644 index d7fac863..00000000 --- a/include/nw4r/g3d/g3d_resanmtexpat.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef NW4R_G3D_RESANMTEXPAT_H -#define NW4R_G3D_RESANMTEXPAT_H -#include "nw4r/g3d/g3d_resdict.h" -#include "nw4r/g3d/g3d_resfile.h" -#include "nw4r/g3d/g3d_resanm.h" - -namespace nw4r -{ - namespace g3d - { - struct ResAnmTexPatAnmFramesData - { - float mTime; // at 0x0 - u16 mTexIndex; // at 0x4 - u16 mPlttIndex; // at 0x6 - }; - - struct ResAnmTexPatAnmData - { - u16 mCount; // at 0x0 - float FLOAT_0x4; - ResAnmTexPatAnmFramesData mFrames[]; // at 0x8 - }; - - struct ResAnmTexPatMatData - { - char UNK_0x0[0x4]; - u32 mFlags; // at 0x4 - - union AnmData - { - struct - { - u16 mTexIndex; // at 0x0 - u16 mPlttIndex; // at 0x2 - }; - - s32 mOffset; - } mAnms[]; // at 0x8 - }; - - struct ResAnmTexPatData - { - char UNK_0x0[0x8]; - u32 mRevision; // at 0x8 - char UNK_0xC[0x4]; - s32 mMatDictOffset; // at 0x10 - s32 mTexNameArrayOffset; // at 0x14 - s32 mPlttNameArrayOffset; // at 0x18 - s32 mTexArrayOffset; // at 0x1c - s32 mPlttArrayOffset; // at 0x20 - char UNK_0x24[0xC]; - u16 mTexCount; // at 0x30 - u16 mPlttCount; // at 0x32 - char UNK_0x34[0x4]; - AnmPolicy mAnmPolicy; // at 0x38 - }; - - struct ResAnmTexPat - { - enum - { - REVISION = 3 - }; - - ResCommon mAnmTexPat; - - inline ResAnmTexPat(void * vptr) : mAnmTexPat(vptr) {} - - inline ResAnmTexPatData & ref() const - { - return mAnmTexPat.ref(); - } - - inline bool CheckRevision() const - { - return ref().mRevision == REVISION; - } - - inline const ResAnmTexPatMatData * GetMatAnm(u32 i) const - { - return static_cast(mAnmTexPat.ofs_to_obj(ref().mMatDictOffset)[i]); - } - - AnmPolicy GetAnmPolicy() const - { - return ref().mAnmPolicy; - } - - int GetNumFrame() const - { - return ref().mTexCount; - } - - void GetAnmResult(TexPatAnmResult *, u32, float) const; - - bool Bind(ResFile); - void Release(); - }; - } -} - -#endif diff --git a/include/nw4r/g3d/g3d_resanmtexsrt.h b/include/nw4r/g3d/g3d_resanmtexsrt.h deleted file mode 100644 index e8a4e9f6..00000000 --- a/include/nw4r/g3d/g3d_resanmtexsrt.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef NW4R_G3D_RESANMTEXSRT_H -#define NW4R_G3D_RESANMTEXSRT_H -#include "nw4r/g3d/g3d_resanm.h" -#include "nw4r/g3d/g3d_resdict.h" -#include "nw4r/g3d/g3d_anmtexsrt.h" - -namespace nw4r -{ - namespace g3d - { - struct ResAnmTexSrtTexData - { - u32 mFlags; // at 0x0 - ResAnmData mAnms[]; // at 0x4 - }; - - struct ResAnmTexSrtMatData - { - char UNK_0x0[0x4]; - UNKWORD FLAGS_0x4; - UNKWORD FLAGS_0x8; - s32 mTexOffsets[]; // at 0xc - }; - - struct ResAnmTexSrtData - { - char UNK_0x0[0x8]; - u32 mRevision; // at 0x8 - char UNK_0xC[0x4]; - s32 mMatDictOffset; // at 0x10 - char UNK_0x14[0x0C]; - u16 mNumFrames; // at 0x20 - UNKWORD UNK_0x24; - AnmPolicy mAnmPolicy; // at 0x28 - }; - - struct ResAnmTexSrt - { - enum - { - REVISION = 4 - }; - - ResCommon mAnmTexSrt; - - inline ResAnmTexSrt(void * vptr) : mAnmTexSrt(vptr) {} - - inline ResAnmTexSrtData & ref() const - { - return mAnmTexSrt.ref(); - } - - inline bool CheckRevision() const - { - return mAnmTexSrt.ref().mRevision == REVISION; - } - - inline const ResAnmTexSrtMatData * GetMatAnm(u32 i) const - { - return static_cast(mAnmTexSrt.ofs_to_obj(ref().mMatDictOffset)[i]); - } - - AnmPolicy GetAnmPolicy() const - { - return ref().mAnmPolicy; - } - - int GetNumFrame() const - { - return ref().mNumFrames; - } - - void GetAnmResult(TexSrtAnmResult *, u32, float) const; - }; - } -} - -#endif diff --git a/include/nw4r/g3d/g3d_resanmvis.h b/include/nw4r/g3d/g3d_resanmvis.h deleted file mode 100644 index 89bbbd44..00000000 --- a/include/nw4r/g3d/g3d_resanmvis.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef NW4R_G3D_RESANMVIS_H -#define NW4R_G3D_RESANMVIS_H -#include "nw4r/g3d/g3d_resdict.h" -#include "nw4r/g3d/g3d_resanm.h" -#include "nw4r/g3d/g3d_anmobj.h" - -namespace nw4r -{ - namespace g3d - { - struct ResAnmVisInfoData - { - char UNK_0x0[0xC]; - u16 mNumFrames; // at 0x20 - u16 mNumNodes; - AnmPolicy mAnmPolicy; // at 0x24 - }; - - struct ResAnmVisNodeData - { - UNKWORD WORD_0x0; - u32 mFlags; // at 0x4 - ResBoolAnmFramesData mBoolFrames[]; // at 0x8 - }; - - struct ResAnmVisData - { - char UNK_0x0[0x8]; - u32 mRevision; // at 0x8 - char UNK_0xC[0x4]; - s32 mNodeDictOffset; // at 0x10 - ResAnmVisInfoData mInfo; // at 0x14 - }; - - struct ResAnmVis - { - enum - { - REVISION = 3 - }; - - ResCommon mAnmVis; - - inline ResAnmVis(void * vptr) : mAnmVis(vptr) {} - bool IsValid() const { return mAnmVis.IsValid(); } - - inline ResAnmVisData & ref() const - { - return mAnmVis.ref(); - } - - inline bool CheckRevision() const - { - return ref().mRevision == REVISION; - } - - inline const ResAnmVisNodeData * GetNodeAnm(u32 i) const - { - return static_cast(mAnmVis.ofs_to_obj(ref().mNodeDictOffset)[i]); - } - - AnmPolicy GetAnmPolicy() const - { - return ref().mInfo.mAnmPolicy; - } - - int GetNumFrame() const - { - return ref().mInfo.mNumFrames; - } - - int GetNumNode() const - { - return ref().mInfo.mNumNodes; - } - - bool GetAnmResult(u32, float) const; - }; - } -} - -#endif diff --git a/include/nw4r/g3d/g3d_rescommon.h b/include/nw4r/g3d/g3d_rescommon.h deleted file mode 100644 index 5ff29ff7..00000000 --- a/include/nw4r/g3d/g3d_rescommon.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef NW4R_G3D_RESCOMMON_H -#define NW4R_G3D_RESCOMMON_H -#include "common.h" - -#define NW4R_G3D_CREATE_RES_NAME_DATA(VAR, VAL) ResNameData ResNameData_##VAR = {sizeof(VAL) - 1, VAL} - -#define FIFO_ACCESS_BP 0x61 -#define FIFO_ACCESS_CP 0x8 -#define FIFO_ACCESS_XF 0x10 - -namespace nw4r { -namespace g3d { -template -class ResCommon { - T *mPtr; - -public: - inline ResCommon(void *vptr) : mPtr(static_cast(vptr)) {} - inline ResCommon(const void *vptr) : mPtr(static_cast(vptr)) {} - - inline T &ref() const { - return *mPtr; - } - inline T *ptr() const { - return mPtr; - } - inline bool IsValid() const { - return mPtr != NULL; - } - - template - inline const TPtr *ofs_to_ptr_raw(s32 ofs) const { - return (const TPtr *)((u8 *)mPtr + ofs); - } - - template - inline TPtr *ofs_to_ptr(s32 ofs) { - if (ofs) { - return (TPtr *)((u8 *)mPtr + ofs); - } - - return NULL; - } - - template - inline const TPtr *ofs_to_ptr(s32 ofs) const { - if (ofs) { - return (const TPtr *)((u8 *)mPtr + ofs); - } - - return NULL; - } - - template - inline TObj ofs_to_obj(s32 ofs) const { - if (ofs) { - return (u8 *)mPtr + ofs; - } - - return NULL; - } -}; - -struct ResNameData { - u32 mLength; - char mName[0x1C]; -}; - -struct ResName { - ResCommon mRes; - - inline ResName(const void *vptr) : mRes(vptr) {} - - inline u32 GetLength() const { - return mRes.ref().mLength; - } - - inline const char *GetName() const { - return mRes.ref().mName; - } - - bool operator==(ResName) const; -}; - -namespace detail { -typedef u8 CPCmd[6]; -typedef u8 BPCmd[5]; - -inline void ResWrite_u8(u8 *res, u8 arg) { - *res = arg; -} - -inline void ResWrite_u16(u8 *res, u16 arg) { - ResWrite_u8(res + 0, arg >> 8); - ResWrite_u8(res + 1, arg >> 0); -} - -inline void ResWrite_u32(u8 *res, u32 arg) { - ResWrite_u8(res + 0, arg >> 24); - ResWrite_u8(res + 1, arg >> 16); - ResWrite_u8(res + 2, arg >> 8); - ResWrite_u8(res + 3, arg >> 0); -} - -inline u8 ResRead_u8(const u8 *res) { - return *res; -} - -inline u32 ResRead_u32(const u8 *res) { - int ret = ResRead_u8(res) << 24; - ret |= ResRead_u8(res + 1) << 16; - ret |= ResRead_u8(res + 2) << 8; - ret |= ResRead_u8(res + 3); - return ret; -} - -inline void ResReadBPCmd(const u8 *res, u32 *out) { - *out = ResRead_u32(res + 1); -} - -inline void ResReadCPCmd(const u8 *res, u32 *out) { - *out = ResRead_u32(res + 2); -} - -void ResWriteBPCmd(u8 *, u32); -void ResWriteBPCmd(u8 *, u32, u32); -void ResWriteCPCmd(u8 *, u8, u32); -void ResWriteXFCmd(u8 *, u16, u32); -void ResWriteSSMask(u8 *, u32); -} // namespace detail -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resdict.h b/include/nw4r/g3d/g3d_resdict.h deleted file mode 100644 index c0ef62e8..00000000 --- a/include/nw4r/g3d/g3d_resdict.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef NW4R_G3D_RESDICT_H -#define NW4R_G3D_RESDICT_H -#include "common.h" -#include "nw4r/g3d/g3d_rescommon.h" -#include "string.h" - -namespace nw4r { -namespace g3d { -struct ResDicNodeData { - u16 ref; // at 0x0 - u16 flag; // at 0x2 - u16 idxLeft; // at 0x4 - u16 idxRight; // at 0x6 - u32 ofsString; // at 0x8 - u32 ofsData; // at 0xC -}; - -struct ResDicData { - u32 size; // at 0x0 - u32 numData; // at 0x4 - ResDicNodeData data[1]; // 0x8 -}; - -struct ResDic { - ResCommon mDict; - - ResDicNodeData *Get(ResName) const; - ResDicNodeData *Get(const char *, u32) const; - void *operator[](const char *) const; - void *operator[](ResName) const; - s32 GetIndex(ResName) const; - - inline ResDic(void *vptr) : mDict(vptr) {} - - inline void *operator[](int i) const { - if (mDict.IsValid()) { - return (void *)mDict.ofs_to_ptr(mDict.ref().data[i + 1].ofsData); - } - - return NULL; - } - - inline u32 GetNumData() const { - if (mDict.IsValid()) { - return mDict.ref().numData; - } - - return 0; - } -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resfile.h b/include/nw4r/g3d/g3d_resfile.h deleted file mode 100644 index f6375cf7..00000000 --- a/include/nw4r/g3d/g3d_resfile.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef NW4R_G3D_RESFILE_H -#define NW4R_G3D_RESFILE_H -#include "common.h" -#include "nw4r/g3d/g3d_rescommon.h" -#include "nw4r/g3d/g3d_resdict.h" -#include "nw4r/ut/ut_binaryFileFormat.h" - -namespace nw4r { -namespace g3d { - -struct ResFileData { - ut::BinaryFileHeader mHeader; // at 0x0 - - ut::BinaryBlockHeader mRootHeader; // at 0x10 - ResDicData mRootData; // at 0x18 -}; - -struct ResFile { - ResCommon mFile; // at 0x0 - - ResFile() : mFile((void *)nullptr) {} - ResFile(void *ptr) : mFile(ptr) {} - - inline ResFileData &ref() const { - return mFile.ref(); - } - - ResMdl GetResMdl(const char *) const; - ResMdl GetResMdl(int) const; - ResMdl GetResMdl(u32) const; // inlined - - ResPltt GetResPltt(const char *) const; - ResPltt GetResPltt(ResName) const; - ResPltt GetResPltt(int) const; - ResPltt GetResPltt(u32) const; // inlined - - ResTex GetResTex(const char *) const; - ResTex GetResTex(ResName) const; - ResTex GetResTex(int) const; - ResTex GetResTex(u32) const; // inlined - - ResAnmChr GetResAnmChr(const char *) const; - ResAnmChr GetResAnmChr(int) const; - ResAnmChr GetResAnmChr(u32) const; // inlined - - ResAnmVis GetResAnmVis(const char *) const; - ResAnmVis GetResAnmVis(int) const; - ResAnmVis GetResAnmVis(u32) const; // inlined - - ResAnmClr GetResAnmClr(const char *) const; - ResAnmClr GetResAnmClr(int) const; - ResAnmClr GetResAnmClr(u32) const; // inlined - - ResAnmTexPat GetResAnmTexPat(const char *) const; - ResAnmTexPat GetResAnmTexPat(int) const; - ResAnmTexPat GetResAnmTexPat(u32) const; // inlined - - ResAnmTexSrt GetResAnmTexSrt(const char *) const; - ResAnmTexSrt GetResAnmTexSrt(int) const; - ResAnmTexSrt GetResAnmTexSrt(u32) const; // inlined - - ResAnmShp GetResAnmShp(const char *) const; - ResAnmShp GetResAnmShp(int) const; - ResAnmShp GetResAnmShp(u32) const; // inlined - - ResAnmScn GetResAnmScn(const char *) const; - ResAnmScn GetResAnmScn(int) const; - ResAnmScn GetResAnmScn(u32) const; // inlined - - u32 GetResMdlNumEntries() const; // inlined - u32 GetResPlttNumEntries() const; // inlined - u32 GetResTexNumEntries() const; // inlined - u32 GetResAnmChrNumEntries() const; // inlined - u32 GetResAnmVisNumEntries() const; // inlined - u32 GetResAnmClrNumEntries() const; // inlined - u32 GetResAnmTexPatNumEntries() const; // inlined - u32 GetResAnmTexSrtNumEntries() const; // inlined - u32 GetResAnmShpNumEntries() const; // inlined - u32 GetResAnmScnNumEntries() const; - - bool Bind(ResFile); - bool Bind() { - return Bind(*this); - } - void Release(); - void Init(); - void Terminate(); - bool CheckRevision() const; -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resmat.h b/include/nw4r/g3d/g3d_resmat.h deleted file mode 100644 index dab824c8..00000000 --- a/include/nw4r/g3d/g3d_resmat.h +++ /dev/null @@ -1,193 +0,0 @@ -#ifndef NW4R_G3D_RESMAT_H -#define NW4R_G3D_RESMAT_H -#include "common.h" -#include "nw4r/g3d/g3d_rescommon.h" -#include "nw4r/math/math_types.h" // IWYU pragma: export -#include "rvl/GX.h" // IWYU pragma: export - -namespace nw4r { -namespace g3d { - -struct ResTevColorDL { - union { - struct { - u8 tevColor[3][20]; // offset 0x0, size 0x3C - u8 _0[4]; // offset 0x3C, size 0x4 - u8 tevKColor[4][10]; // offset 0x40, size 0x28 - u8 _1[24]; // offset 0x68, size 0x18 - } dl; - u8 data[128]; - }; -}; - -struct ResMatTevColor : public ResCommon { - ResMatTevColor(void *vptr) : ResCommon(vptr) {} - void DCStore(bool sync); - void CallDisplayList(bool bSync) const; - ResMatTevColor CopyTo(void *p) const; - void GXGetTevColor(GXTevRegID id, GXColor *color); - void GXSetTevColor(GXTevRegID id, GXColor color); - void GXSetTevKColor(GXTevKColorID id, GXColor color); -}; - -struct ResPixDL { - union { - struct { - unsigned char alphaCompare[5]; // offset 0x0, size 0x5 - unsigned char zMode[5]; // offset 0x5, size 0x5 - unsigned char blendMode[10]; // offset 0xA, size 0xA - unsigned char setDstAlpha[5]; // offset 0x14, size 0x5 - unsigned char _[7]; // offset 0x19, size 0x7 - } dl; // offset 0x0, size 0x20 - unsigned char data[32]; // offset 0x0, size 0x20 - }; -}; - -struct ResMatPix : public ResCommon { - ResMatPix(void *vptr) : ResCommon(vptr) {} - void DCStore(bool sync); - void GXGetDstAlpha(u8 *, u8 *) const; - void GXSetDstAlpha(u8, u8); - void CallDisplayList(bool bSync) const; - ResMatPix CopyTo(void *p) const; - - void GXSetBlendMode(GXBlendMode, GXBlendFactor, GXBlendFactor, GXLogicOp); -}; - -struct ResTexCoordGenDL {}; - -struct ResMatTexCoordGen : public ResCommon { - inline ResMatTexCoordGen(void *vptr) : ResCommon(vptr) {} - bool IsValid() const { - return ResCommon::IsValid(); - } - - bool GXGetTexCoordGen2(GXTexCoordID, GXTexGenType *, GXTexGenSrc *, u8 *, u32 *); - void GXSetTexCoordGen2(GXTexCoordID, GXTexGenType, GXTexGenSrc, u8, u32); - void DCStore(bool); -}; - -struct ResTexSrtData { - union { - struct { - unsigned char texCoordGen[8][18]; // offset 0x0, size 0x90 - unsigned char _[16]; // offset 0x90, size 0x10 - } dl; // offset 0x0, size 0xA0 - unsigned char data[160]; // offset 0x0, size 0xA0 - }; -}; - -struct ResTexSrt : public ResCommon { - inline ResTexSrt(void *vptr) : ResCommon(vptr) {} - - void SetMapMode(u32, u32, int, int); -}; - -struct ResTexPlttInfoData { - u32 mNumOffsets; // at 0x0 - - struct InfoOffset { - u32 mResOffset; // at 0x0 - u32 mTexOffset; // at 0x4 - } mOffsets[]; // at 0x4 -}; - -struct ResTexPlttInfo { - ResCommon mInfo; - - inline ResTexPlttInfo(void *vptr) : mInfo(vptr) {} -}; - -struct ResMatDLData { - ResPixDL dlPix; // offset 0x0, size 0x20 - ResTevColorDL dlTevColor; // offset 0x20, size 0x80 - /* ResIndMtxAndScaleDL */ u8 dlIndMtxAndScale[0x40]; // offset 0xA0, size 0x40 - ResTexCoordGenDL dlTexCoordGen; // offset 0xE0, size 0xA0 -}; - -struct ResGenModeData { - u8 nTexGens; // offset 0x0, size 0x1 - u8 nChans; // offset 0x1, size 0x1 - u8 nTevs; // offset 0x2, size 0x1 - u8 nInds; // offset 0x3, size 0x1 - GXCullMode cullMode; // offset 0x4, size 0x4 -}; - -struct ResGenMode : public ResCommon { - ResGenMode(void *vptr) : ResCommon(vptr) {} - void DCStore(bool sync); - ResGenMode CopyTo(void *p) const; - GXCullMode GXGetCullMode(); - u8 GXGetNumIndStages() const; - u8 GXGetNumTevStages() const; - u8 GXGetNumChans() const; - u8 GXGetNumTexGens() const; - void GXSetCullMode(GXCullMode); -}; - -struct ResTexObjData {}; - -struct ResTexObj { - ResCommon mTexObj; - inline ResTexObj(void *vptr) : mTexObj(vptr) {} - - GXTexObj *GetTexObj(GXTexMapID); -}; - -struct ResMatData { - u32 size; // offset 0x0, size 0x4 - s32 toResMdlData; // offset 0x4, size 0x4 - s32 name; // offset 0x8, size 0x4 - u32 id; // offset 0xC, size 0x4 - u32 flag; // offset 0x10, size 0x - ResGenModeData genMode; // offset 0x14, size 0x8 - /* ResMatMiscData */ u8 misc[0xC]; // offset 0x1C, size 0xC - s32 toResTevData; // offset 0x28, size 0x4 - u32 numResTexPlttInfo; // offset 0x2C, size 0x4 - s32 toResTexPlttInfo; // offset 0x30, size 0x4 - s32 toResMatFurData; // offset 0x34, size 0x4 - u32 toResUserData; // offset 0x38, size 0x4 - u32 toResMatDLData; // offset 0x3C, size 0x4 - /* ResTexObjData */ u8 texObjData[0x104]; // offset 0x40, size 0x104 - /* ResTlutObjData */ u8 tlutObjData[0x64]; // offset 0x144, size 0x64 - ResTexSrtData texSrtData; // offset 0x1A8, size 0x248 - /* ResChanData */ u8 chan[0x20]; // offset 0x3F0, size 0x28 -}; - -struct ResMat : public ResCommon { - ResMat(void *ptr) : ResCommon(ptr) {} - - ResMatTevColor GetResMatTevColor() { - return ResMatTevColor(&ofs_to_ptr(ref().toResMatDLData)->dlTevColor); - } - - ResMatPix GetResMatPix() { - return ResMatPix(&ofs_to_ptr(ref().toResMatDLData)->dlPix); - } - - ResGenMode GetResGenMode() { - return ResGenMode(&ref().genMode); - } - - ResTexSrt GetResTexSrt() { - return ResTexSrt(&ref().texSrtData); - } - - ResTexObj GetResTexObj() { - return ResTexObj(&ref().texObjData); - } - - ResMatTexCoordGen GetResMatTexCoordGen() { - return ResMatTexCoordGen(&ofs_to_ptr(ref().toResMatDLData)->dlTexCoordGen); - } - - bool IsOpaque() const; - - bool Bind(ResFile); - UNKTYPE Release(); - UNKTYPE Init(); -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resmdl.h b/include/nw4r/g3d/g3d_resmdl.h deleted file mode 100644 index 5cf68da7..00000000 --- a/include/nw4r/g3d/g3d_resmdl.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef NW4R_G3D_RESMDL_H -#define NW4R_G3D_RESMDL_H -#include "common.h" -#include "nw4r/g3d/g3d_rescommon.h" -#include "nw4r/g3d/g3d_resdict.h" -#include "nw4r/g3d/g3d_resnode.h" - -namespace nw4r { -namespace g3d { - -enum ResMdlDrawMode { - RESMDL_DRAWMODE_SORT_OPA_NONE = 0, - RESMDL_DRAWMODE_SORT_OPA_Z = 1, - RESMDL_DRAWMODE_SORT_XLU_NONE = 0, - RESMDL_DRAWMODE_SORT_XLU_Z = 2, - RESMDL_DRAWMODE_IGNORE_MATERIAL = 4, - RESMDL_DRAWMODE_FORCE_LIGHTOFF = 8, - RESMDL_DRAWMODE_NOPPCSYNC = 16, - RESMDL_DRAWMODE_DEFAULT = 2, - REDMDL_DRAWMODE_SORT_NONE = 0, - RESMDL_DRAWMODE_SORT_Z = 3, -}; - -struct ResMdlData { - char mMagic[4]; // "MDL0" - u32 INT_0x4; - u32 mRevision; // at 0x8 - s32 INT_0xC; - u32 mByteCodeDictOfs; // at 0x10 - u32 mNodeDictOfs; // at 0x14 - u32 mVtxPosDictOfs; // at 0x18 - u32 mVtxNrmDictOfs; // at 0x1C - u32 mVtxClrDictOfs; // at 0x20 - u32 mVtxTexCoordDictOfs; // at 0x24 - u32 mMatDictOfs; // at 0x28 - u32 mTevDictOfs; // at 0x2C - u32 mShpDictOfs; // at 0x30 - u32 mPlttTexInfoOfs; // at 0x34 -}; - -struct ResMdl { - enum { REVISION = 9 }; - - ResCommon mMdl; - - inline ResMdl(void *vptr) : mMdl(vptr) {} - bool IsValid() const { - return mMdl.IsValid(); - } - - u8 *GetResByteCode(const char *) const; - - ResNode GetResNode(const char *) const; - ResNode GetResNode(ResName) const; - ResNode GetResNode(int) const; - ResNode GetResNode(u32) const; - u32 GetResNodeNumEntries() const; - - ResVtxPos GetResVtxPos(ResName) const; - ResVtxPos GetResVtxPos(int) const; - ResVtxPos GetResVtxPos(u32) const; - u32 GetResVtxPosNumEntries() const; - - ResVtxNrm GetResVtxNrm(ResName) const; - ResVtxNrm GetResVtxNrm(int) const; - ResVtxNrm GetResVtxNrm(u32) const; - u32 GetResVtxNrmNumEntries() const; - - ResVtxClr GetResVtxClr(ResName) const; - ResVtxClr GetResVtxClr(int) const; - ResVtxClr GetResVtxClr(u32) const; - u32 GetResVtxClrNumEntries() const; - - ResVtxTexCoord GetResVtxTexCoord(int) const; - - ResMat GetResMat(const char *) const; - ResMat GetResMat(ResName) const; - ResMat GetResMat(int) const; - ResMat GetResMat(u32) const; - u32 GetResMatNumEntries() const; - - ResShp GetResShp(const char *) const; - ResShp GetResShp(int) const; - ResShp GetResShp(u32) const; - u32 GetResShpNumEntries() const; - - ResTexPlttInfo GetResTexPlttInfoOffsetFromTexName(int) const; - u32 GetResTexPlttInfoOffsetFromTexNameNumEntries() const; - - bool Bind(ResFile); - void Release(); - void Init(); - void Terminate(); - - inline bool CheckRevision() const { - return mMdl.ref().mRevision == REVISION; - } - - inline u32 GetResVtxTexCoordNumEntries() const { - ResMdlData &ref = mMdl.ref(); - return mMdl.ofs_to_obj(ref.mVtxTexCoordDictOfs).GetNumData(); - } -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resnode.h b/include/nw4r/g3d/g3d_resnode.h deleted file mode 100644 index c571c50f..00000000 --- a/include/nw4r/g3d/g3d_resnode.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef NW4R_G3D_RESNODE_H -#define NW4R_G3D_RESNODE_H -#include "common.h" -#include "nw4r/g3d/g3d_rescommon.h" -#include "nw4r/math/math_types.h" - -namespace nw4r { -namespace g3d { - -class ChrAnmResult; - -struct ResNodeData { - u32 INT_0x0; - s32 INT_0x4; - u16 SHORT_0x8; - u16 SHORT_0xA; - UNKWORD WORD_0xC; - UNKWORD WORD_0x10; - u32 mFlags; // at 0x14 - UNKWORD WORD_0x18; - UNKWORD WORD_0x1C; - math::VEC3 VEC3_0x20; - math::VEC3 VEC3_0x2C; - f32 FLOAT_0x38; - f32 FLOAT_0x3C; - f32 FLOAT_0x40; - math::VEC3 VEC3_0x44; - math::VEC3 VEC3_0x50; -}; - -struct ResNode { - enum ResNodeFlags { NODE_IS_VISIBLE = 0x100 }; - - ResCommon mNode; - - inline ResNode(void *vptr) : mNode(vptr) {} - - bool IsValid() const { - return mNode.IsValid(); - } - - UNKWORD GetID() const { - if (IsValid()) { - return mNode.ptr()->WORD_0xC; - } - return 0; - } - - void SetVisibility(bool visible) { - if (IsValid()) { - if (visible) { - mNode.ptr()->mFlags |= NODE_IS_VISIBLE; - } else { - mNode.ptr()->mFlags &= ~NODE_IS_VISIBLE; - } - } - } - - void PatchChrAnmResult(ChrAnmResult *) const; - void CalcChrAnmResult(ChrAnmResult *) const; -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resshp.h b/include/nw4r/g3d/g3d_resshp.h deleted file mode 100644 index d0bd199b..00000000 --- a/include/nw4r/g3d/g3d_resshp.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef NW4R_G3D_RESSHP_H -#define NW4R_G3D_RESSHP_H -#include "common.h" -#include "nw4r/g3d/g3d_rescommon.h" -#include "nw4r/g3d/g3d_resmdl.h" -#include "nw4r/g3d/g3d_resvtx.h" -#include "rvl/GX.h" // IWYU pragma: export - -namespace nw4r { -namespace g3d { -struct ResTagDLData { - u32 mBufSize; // at 0x0 - u32 mCmdSize; // at 0x4 - u32 mOffset; // at 0x8 -}; - -struct ResPrePrimDL { - char UNK_0x0[0xA]; - detail::CPCmd CP_CMD_0xA; - detail::CPCmd CP_CMD_0x10; - char UNK_0x16[0xA]; - detail::CPCmd CP_CMD_0x20; - detail::CPCmd CP_CMD_0x26; - detail::CPCmd CP_CMD_0x2C; - detail::CPCmd CP_CMD_PAIRS_0x32[GX_POS_MTX_ARRAY - GX_VA_POS][2]; - char UNK_0xC2[0x1E]; -}; - -struct ResShpData { - char UNK_0x0[0x4]; - u32 mParentOffset; // at 0x4 - char UNK_0x8[0x10]; - ResTagDLData mPrePrimDLTag; // at 0x18 - ResTagDLData mPrimDLTag; // at 0x24 - char UNK_0x30[0x18]; - - s16 mVtxPosIndex; // at 0x48 - s16 mVtxNrmIndex; // at 0x4a - s16 mVtxClrIndices[GX_VA_TEX0 - GX_VA_CLR0]; // at 0x4c - s16 mVtxTexCoordIndices[GX_POS_MTX_ARRAY - GX_VA_TEX0]; // at 0x50 -}; - -struct ResTagDL { - ResCommon mData; - - inline ResTagDL(void *vptr) : mData(vptr) {} - - inline u8 *GetDL() const { - return const_cast(mData.ofs_to_ptr(mData.ref().mOffset)); - } - - inline u32 GetBufSize() const { - return mData.ref().mBufSize; - } - - inline u32 GetCmdSize() const { - return mData.ref().mCmdSize; - } -}; - -struct ResShpPrePrim { - ResCommon mDL; - - inline ResShpPrePrim(void *vptr) : mDL(vptr) {} - - inline ResPrePrimDL &ref() const { - return mDL.ref(); - } -}; - -struct ResShp { - ResCommon mShp; - inline ResShp() : mShp((void *)nullptr) {} - inline ResShp(void *vptr) : mShp(vptr) {} - bool IsValid() const { - return mShp.IsValid(); - } - - inline ResShpData &ref() const { - return mShp.ref(); - } - - inline ResShpPrePrim GetResShpPrePrim() const { - return ResTagDL(&ref().mPrePrimDLTag).GetDL(); - } - - bool GXGetVtxDescv(GXVtxDescList *) const; - bool GXGetVtxAttrFmtv(GXVtxAttrFmtList *) const; - - ResMdl GetParent() const; // inlined - - ResVtxPos GetResVtxPos() const; - ResVtxNrm GetResVtxNrm() const; - ResVtxClr GetResVtxClr(u32) const; - ResVtxTexCoord GetResVtxTexCoord(u32) const; // inlined - - void GXSetArray(GXAttr, const void *, u8); // inlined - - void Init(); - - void DisableSetArray(GXAttr); // inlined - void Terminate(); - - void CallPrePrimitiveDisplayList(bool, bool) const; - void CallPrimitiveDisplayList(bool) const; -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_restev.h b/include/nw4r/g3d/g3d_restev.h deleted file mode 100644 index 9c2f26b5..00000000 --- a/include/nw4r/g3d/g3d_restev.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef NW4R_G3D_RESTEV_H -#define NW4R_G3D_RESTEV_H -#include "GXTev.h" -#include "GXTexture.h" -#include "nw4r/g3d/g3d_cpu.h" -#include "nw4r/g3d/g3d_rescommon.h" - -namespace nw4r { -namespace g3d { -struct ResTevData { - u32 SIZE_0x0; - u32 INT_0x4; - char UNK_0x8[0x4]; - u8 BYTE_0xC; - char UNK_0xD[0x13]; - - detail::BPCmd mSwapSelCmds[GX_MAX_TEVSWAP][4]; - - char UNK_0x70[0x10]; - - struct { - detail::BPCmd BP_CMD_0x0; - detail::BPCmd BP_CMD_0x5; - detail::BPCmd BP_CMD_0xA; - detail::BPCmd BP_CMD_PAIR_0xF[2]; - char UNK_0x19[0x17]; - } mStageCmds[]; //[GX_TEV_STAGE_COUNT]; -}; - -struct ResTev { - ResCommon mTev; - - inline ResTev(void *vptr) : mTev(vptr) {} - - inline ResTevData &ref() const { - return mTev.ref(); - } - - bool - GXGetTevSwapModeTable(GXTevSwapSel, GXTevColorChan *, GXTevColorChan *, GXTevColorChan *, GXTevColorChan *) const; - void GXSetTevSwapModeTable(GXTevSwapSel, GXTevColorChan, GXTevColorChan, GXTevColorChan, GXTevColorChan); - - bool GXGetTevOrder(GXTevStageID, GXTexCoordID *, GXTexMapID *, GXChannelID *) const; - - void GXSetTevColorIn(GXTevStageID, GXTevColorArg, GXTevColorArg, GXTevColorArg, GXTevColorArg); - - void CallDisplayList(bool) const; - - void *CopyTo(void *); - - UNKTYPE DCStore(bool); -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_restex.h b/include/nw4r/g3d/g3d_restex.h deleted file mode 100644 index 99b19ac7..00000000 --- a/include/nw4r/g3d/g3d_restex.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef NW4R_G3D_RESTEX_H -#define NW4R_G3D_RESTEX_H -#include "common.h" -#include "nw4r/g3d/g3d_rescommon.h" -#include "rvl/GX.h" // IWYU pragma: export - -namespace nw4r { -namespace g3d { -struct ResTexData { - char mMagic[4]; // "TEX0"; at 0x0 - u32 mLength; // at 0x4 - u32 mRevision; // at 0x8 - s16 SHORT_0xC; - u16 SHORT_0xE; - u32 INT_0x10; - UNKWORD WORD_0x14; - u32 mFlags; // at 0x18 - u16 SHORT_0x1C; - u16 SHORT_0x1E; - union // at 0x20 - { - GXTexFmt mFormat; - GXCITexFmt mCiFormat; - }; - u32 WORD_0x24; - f32 FLOAT_0x28; - f32 FLOAT_0x2C; -}; - -struct ResPlttData { - char mMagic[4]; // "PLT0"; at 0x0 - u32 mLength; // at 0x4 - u32 mRevision; // at 0x8 -}; - -struct ResTex { - enum { - REVISION = 1 - }; - - ResCommon mTex; // at 0x0 - - inline ResTex(void *vptr) : mTex(vptr) {} - - inline bool CheckRevision() const { - return mTex.ref().mRevision == REVISION; - } - - bool GetTexObjParam(void **, u16 *, u16 *, GXTexFmt *, f32 *, f32 *, u8 *) const; - bool GetTexObjCIParam(void **, u16 *, u16 *, GXCITexFmt *, f32 *, f32 *, u8 *) const; - void Init(); - - bool IsValid() const { - return mTex.IsValid(); - } -}; - -struct ResPltt { - enum { - REVISION = 1 - }; - - ResCommon mPltt; // at 0x0 - - inline ResPltt(void *vptr) : mPltt(vptr) {} - - inline bool CheckRevision() const { - return mPltt.ref().mRevision == REVISION; - } - - void DCStore(bool); -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_resvtx.h b/include/nw4r/g3d/g3d_resvtx.h deleted file mode 100644 index cd15a484..00000000 --- a/include/nw4r/g3d/g3d_resvtx.h +++ /dev/null @@ -1,136 +0,0 @@ -#ifndef NW4R_G3D_RESVTX_H -#define NW4R_G3D_RESVTX_H -#include "nw4r/g3d/g3d_rescommon.h" -#include "rvl/GX.h" // IWYU pragma: export - -namespace nw4r { -namespace g3d { -struct ResVtxPosData { - u32 SIZE_0x0; - char UNK_0x4[0x4]; - u32 mDataOffset; // at 0x8 - char UNK_0xC[0x11]; - u8 BYTE_0x1D; -}; - -struct ResVtxNrmData { - u32 SIZE_0x0; - char UNK_0x4[0x4]; - u32 mDataOffset; // at 0x8 - char UNK_0xC[0x11]; - u8 BYTE_0x1D; -}; - -struct ResVtxClrData { - u32 SIZE_0x0; - char UNK_0x4[0x4]; - u32 mDataOffset; // at 0x8 - char UNK_0xC[0x10]; - u8 BYTE_0x1C; -}; - -struct ResVtxTexCoordData { - u32 SIZE_0x0; - char UNK_0x4[0x4]; - u32 mDataOffset; // at 0x8 - char UNK_0xC[0x11]; - u8 BYTE_0x1D; -}; - -struct ResVtxPos { - ResCommon mPos; - - inline ResVtxPos(void *vptr) : mPos(vptr) {} - - inline ResVtxPosData &ref() const { - return mPos.ref(); - } - - inline const void *GetData() const { - return mPos.ofs_to_ptr(ref().mDataOffset); - } - - inline UNKTYPE Init() { - DCStore(false); - } - - void SetArray(); - void GetArray(const void **, u8 *) const; - UNKTYPE CopyTo(void *) const; - - UNKTYPE DCStore(bool); -}; - -struct ResVtxNrm { - ResCommon mNrm; - - inline ResVtxNrm(void *vptr) : mNrm(vptr) {} - - inline ResVtxNrmData &ref() const { - return mNrm.ref(); - } - - inline const void *GetData() const { - return mNrm.ofs_to_ptr(ref().mDataOffset); - } - - inline UNKTYPE Init() { - DCStore(false); - } - - void SetArray(); - void GetArray(const void **, u8 *) const; - UNKTYPE CopyTo(void *) const; - - UNKTYPE DCStore(bool); -}; - -struct ResVtxClr { - ResCommon mClr; - - inline ResVtxClr(void *vptr) : mClr(vptr) {} - - inline ResVtxClrData &ref() const { - return mClr.ref(); - } - - inline const void *GetData() const { - return mClr.ofs_to_ptr(ref().mDataOffset); - } - - inline UNKTYPE Init() { - DCStore(false); - } - - void SetArray(GXAttr); - void GetArray(const void **, u8 *) const; - UNKTYPE CopyTo(void *) const; - - UNKTYPE DCStore(bool); -}; - -struct ResVtxTexCoord { - ResCommon mTexCoord; - - inline ResVtxTexCoord(void *vptr) : mTexCoord(vptr) {} - - inline ResVtxTexCoordData &ref() const { - return mTexCoord.ref(); - } - - inline const void *GetData() const { - return mTexCoord.ofs_to_ptr(ref().mDataOffset); - } - - inline UNKTYPE Init() { - DCStore(false); - } - - void GetArray(const void **, u8 *) const; - - UNKTYPE DCStore(bool); -}; -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_rtti.h b/include/nw4r/g3d/g3d_rtti.h new file mode 100644 index 00000000..14980423 --- /dev/null +++ b/include/nw4r/g3d/g3d_rtti.h @@ -0,0 +1,56 @@ +#ifndef NW4R_G3D_RTTI_H +#define NW4R_G3D_RTTI_H + +/** + * (Internal) Declare TypeObj for an object class. + */ +#define __NW4R_G3D_TYPEOBJ_DECL(T) static const nw4r::g3d::G3dObj::ResNameDataT TYPE_NAME; + +/** + * (Internal) Declare data and methods common between base and derived types. + */ +#define __NW4R_G3D_RTTI_DECL(T) \ +public: \ + virtual const TypeObj GetTypeObj() const { \ + return nw4r::g3d::G3dObj::TypeObj(TYPE_NAME); \ + } /* at 0x14 */ \ + \ + static const G3dObj::TypeObj GetTypeObjStatic() { \ + return nw4r::g3d::G3dObj::TypeObj(TYPE_NAME); \ + } \ + \ + virtual const char *GetTypeName() const { \ + return GetTypeObj().GetTypeName(); \ + } /* at 0x18 */ \ + \ +private: \ + __NW4R_G3D_TYPEOBJ_DECL(T); + +/** + * Declare data and methods common between base and derived types. + */ +#define NW4R_G3D_RTTI_DEF(T) const nw4r::g3d::G3dObj::ResNameDataT T::TYPE_NAME = {sizeof(#T), #T} + +/** + * Define type RTTI (base type). + */ +#define NW4R_G3D_RTTI_DECL_BASE(T) \ + __NW4R_G3D_RTTI_DECL(T); \ + \ +public: \ + virtual bool IsDerivedFrom(nw4r::g3d::G3dObj::TypeObj other) const { \ + return other == GetTypeObjStatic(); \ + } /* at 0x8 */ + +/** + * Define type RTTI (derived type). + */ +#define NW4R_G3D_RTTI_DECL_DERIVED(T, BASE) \ + __NW4R_G3D_RTTI_DECL(T); \ + \ +public: \ + virtual bool IsDerivedFrom(nw4r::g3d::G3dObj::TypeObj other) const { \ + return other == GetTypeObjStatic() ? true : BASE::IsDerivedFrom(other); \ + } /* at 0x8 */ + +#endif diff --git a/include/nw4r/g3d/g3d_scnmdl.h b/include/nw4r/g3d/g3d_scnmdl.h index f81dde0d..e7d7e586 100644 --- a/include/nw4r/g3d/g3d_scnmdl.h +++ b/include/nw4r/g3d/g3d_scnmdl.h @@ -1,54 +1,162 @@ #ifndef NW4R_G3D_SCN_MDL_H #define NW4R_G3D_SCN_MDL_H -#include "common.h" -#include "nw4r/g3d/g3d_draw.h" -#include "nw4r/g3d/g3d_resmat.h" -#include "nw4r/g3d/g3d_scnmdlsmpl.h" + +#include + +#include +#include +#include namespace nw4r { namespace g3d { + +// Forward declarations +class AnmObjShp; + class ScnMdl : public ScnMdlSimple { public: class CopiedMatAccess { public: - CopiedMatAccess(ScnMdl *, u32); - ResTexSrt GetResTexSrtEx(bool); - ResMatPix GetResMatPix(bool); - ResMatTevColor GetResMatTevColor(bool); - ResGenMode GetResGenMode(bool); + CopiedMatAccess(ScnMdl *pScnMdl, u32 id); + + ResTexObj GetResTexObj(bool markDirty); + ResTexSrt GetResTexSrt(bool markDirty); + ResMatChan GetResMatChan(bool markDirty); + ResGenMode GetResGenMode(bool markDirty); + ResMatPix GetResMatPix(bool markDirty); + ResMatTevColor GetResMatTevColor(bool markDirty); + ResTev GetResTev(bool markDirty); + + ResTexSrt GetResTexSrtEx(); private: - char UNK_0x0[0x34]; + ScnMdl *mpScnMdl; // at 0x0 + u32 mMatID; // at 0x4 + ResTexObj mTexObj; // at 0x8 + ResTlutObj mTlutObj; // at 0xC + ResTexSrt mTexSrt; // at 0x10 + ResMatChan mChan; // at 0x14 + ResGenMode mGenMode; // at 0x18 + ResMatMisc mMatMisc; // at 0x1C + ResMatPix mPix; // at 0x20 + ResMatTevColor mTevColor; // at 0x24 + ResMatIndMtxAndScale mIndMtxAndScale; // at 0x28 + ResMatTexCoordGen mTexCoordGen; // at 0x2C + ResTev mTev; // at 0x30 }; class CopiedVisAccess { public: - CopiedVisAccess(ScnMdl *, u32); - void SetVisibility(bool); + CopiedVisAccess(ScnMdl *pScnMdl, u32 id); + + bool IsVisible() const; + bool SetVisibility(bool visible); + bool SetVisibilityEx(bool visible); + private: - // TODO - char UNK_0x0[0x10]; + ScnMdl *mpScnMdl; // at 0x0 + u32 mNodeID; // at 0x4 + u8 *mpVis; // at 0x8 }; +#define OPT(KEY, VALUE) OPTION_##KEY = (0x30000 | (VALUE)) + enum ScnMdlOption { + OPT(NONE, 0), + OPT(VISBUFFER_REFRESH_NEEDED, 1), + }; +#undef OPT + public: - virtual bool SetAnmObj(AnmObj *p, AnmObjType type) override; + static ScnMdl *Construct(MEMAllocator *pAllocator, u32 *pSize, ResMdl mdl, u32 bufferOption, int numView); - static ScnMdl *Construct(MEMAllocator *, unsigned long *, nw4r::g3d::ResMdl, u32 bufferOption, int); + ScnMdl( + MEMAllocator *pAllocator, ResMdl mdl, math::MTX34 *pWorldMtxArray, u32 *pWorldMtxAttribArray, + math::MTX34 *pViewPosMtxArray, math::MTX33 *pViewNrmMtxArray, math::MTX34 *pViewTexMtxArray, int numView, + int numViewMtx, DrawResMdlReplacement *pReplacement, u32 *pMatBufferDirtyFlag + ); - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~ScnMdl(); // at 0x10 + + virtual bool SetScnObjOption(u32 option, u32 value); // at 0x20 + virtual bool GetScnObjOption(u32 option, u32 *pValue) const; // at 0x24 + + virtual bool SetAnmObj(AnmObj *pObj, AnmObjType type); // at 0x34 + virtual bool RemoveAnmObj(AnmObj *pObj); // at 0x38 + virtual AnmObj *RemoveAnmObj(AnmObjType type); // at 0x3C + virtual AnmObj *GetAnmObj(AnmObjType type); // at 0x40 + virtual const AnmObj *GetAnmObj(AnmObjType type) const; // at 0x44 + + void InitBuffer(); + void CleanMatBuffer(u32 idx, u32 option); + void CleanVisBuffer(); + + AnmObjShp *GetAnmObjShp() { + return mpAnmObjShp; } - DrawResMdlReplacement *GetDrawResMdlReplacement() { - return &mDrawMdlReplace; + DrawResMdlReplacement &GetDrawResMdlReplacement() { + return mReplacement; + } + +protected: + void ScnMdl_G3DPROC_CALC_WORLD(u32 param, const math::MTX34 *pParent); + void ScnMdl_G3DPROC_CALC_MAT(u32 param, void *pInfo); + void ScnMdl_G3DPROC_CALC_VTX(u32 param, void *pInfo); + void ScnMdl_G3DPROC_DRAW_OPA(u32 param, void *pInfo); + void ScnMdl_G3DPROC_DRAW_XLU(u32 param, void *pInfo); + +private: + enum VisBufferFlag { + VISBUFFER_DIRTY = (1 << 0), + VISBUFFER_NOT_REFRESH_NEEDED = (1 << 1), + }; + + enum MatBufferOption { + BUFOPTION_TEXOBJ = (1 << 0), + BUFOPTION_TLUTOBJ = (1 << 1), + BUFOPTION_TEXSRT = (1 << 2), + BUFOPTION_MATCHAN = (1 << 3), + BUFOPTION_GENMODE = (1 << 4), + BUFOPTION_MATMISC = (1 << 5), + BUFOPTION_VIS = (1 << 6), + BUFOPTION_MATPIX = (1 << 7), + BUFOPTION_MATTEVCOLOR = (1 << 8), + BUFOPTION_MATINDMTXSCALE = (1 << 9), + BUFOPTION_MATTEXCOORDGEN = (1 << 10), + BUFOPTION_TEV = (1 << 11), + BUFOPTION_VTXPOS = (1 << 12), + BUFOPTION_VTXNRM = (1 << 13), + BUFOPTION_VTXCLR = (1 << 14), + }; + +private: + bool IsVisBufferDirty() const { + return mFlagVisBuffer & VISBUFFER_DIRTY; + } + bool IsVisBufferRefreshNeeded() const { + return !(mFlagVisBuffer & VISBUFFER_NOT_REFRESH_NEEDED); + } + void VisBufferDirty() { + mFlagVisBuffer |= VISBUFFER_DIRTY; + } + + bool IsMatBufferDirty(u32 idx, u32 option) const { + return option & mpMatBufferDirtyFlag[idx]; + } + void MatBufferDirty(u32 idx, u32 option) { + mpMatBufferDirtyFlag[idx] |= option; } private: - char UNK_0x120[0x144 - 0x120]; - DrawResMdlReplacement mDrawMdlReplace; // at 0x144 + AnmObjShp *mpAnmObjShp; // at 0x138 + u32 mFlagVisBuffer; // at 0x13C + u32 *mpMatBufferDirtyFlag; // at 0x140 + DrawResMdlReplacement mReplacement; // at 0x144 - NW4R_G3D_TYPE_OBJ_DECL(ScnMdl); + NW4R_G3D_RTTI_DECL_DERIVED(ScnMdl, ScnMdlSimple); }; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_scnmdl1mat1shp.h b/include/nw4r/g3d/g3d_scnmdl1mat1shp.h index ddbf561e..1131c1bb 100644 --- a/include/nw4r/g3d/g3d_scnmdl1mat1shp.h +++ b/include/nw4r/g3d/g3d_scnmdl1mat1shp.h @@ -1,18 +1,16 @@ -#ifndef NW4R_G3D_SCN_MDL1_MAT1_SHP_H -#define NW4R_G3D_SCN_MDL1_MAT1_SHP_H -#include "common.h" -#include "nw4r/g3d/g3d_resmat.h" -#include "nw4r/g3d/g3d_resshp.h" -#include "nw4r/g3d/g3d_scnobj.h" +#ifndef NW4R_G3D_SCN_MDL_1MAT_1SHP_H +#define NW4R_G3D_SCN_MDL_1MAT_1SHP_H +#include + +#include +#include +#include namespace nw4r { namespace g3d { + class ScnMdl1Mat1Shp : public ScnLeaf { public: - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } - ResMat GetResMat() { return mResMat; } @@ -24,8 +22,9 @@ private: ResMat mResMat; // at 0xE8 ResShp mResShp; // at 0xEC - NW4R_G3D_TYPE_OBJ_DECL(ScnMdl1Mat1Shp); + NW4R_G3D_RTTI_DECL_DERIVED(ScnMdl1Mat1Shp, ScnLeaf); }; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_scnmdlsmpl.h b/include/nw4r/g3d/g3d_scnmdlsmpl.h index 342845da..c41c9bcb 100644 --- a/include/nw4r/g3d/g3d_scnmdlsmpl.h +++ b/include/nw4r/g3d/g3d_scnmdlsmpl.h @@ -1,15 +1,39 @@ -#ifndef NW4R_G3D_SCN_MDL_SIMPLE_H -#define NW4R_G3D_SCN_MDL_SIMPLE_H -#include "common.h" -#include "nw4r/g3d/g3d_calcworld.h" -#include "nw4r/g3d/g3d_resmdl.h" -#include "nw4r/g3d/g3d_scnobj.h" -#include "nw4r/math/math_types.h" +#ifndef NW4R_G3D_SCN_MDL_SMPL_H +#define NW4R_G3D_SCN_MDL_SMPL_H +#include + +#include +#include +#include + +#include namespace nw4r { namespace g3d { + +// Forward declarations +class AnmObj; +class AnmObjChr; +class AnmObjVis; +class AnmObjMatClr; +class AnmObjTexPat; +class AnmObjTexSrt; +class ICalcWorldCallback; + class ScnMdlSimple : public ScnLeaf { public: + enum AnmObjType { + ANMOBJTYPE_CHR, + ANMOBJTYPE_VIS, + ANMOBJTYPE_MATCLR, + ANMOBJTYPE_TEXPAT, + ANMOBJTYPE_TEXSRT, + ANMOBJTYPE_SHP, + ANMOBJTYPE_NOT_SPECIFIED, + + ANMOBJTYPE_VTX = ANMOBJTYPE_SHP + }; + enum ByteCodeType { BYTE_CODE_CALC, BYTE_CODE_MIX, @@ -17,93 +41,177 @@ public: BYTE_CODE_DRAW_XLU, }; - enum AnmObjType { - ANMOBJTYPE_CHR = 0, - ANMOBJTYPE_VIS = 1, - ANMOBJTYPE_MATCLR = 2, - ANMOBJTYPE_TEXPAT = 3, - ANMOBJTYPE_TEXSRT = 4, - ANMOBJTYPE_SHP = 5, - ANMOBJTYPE_NOT_SPECIFIED = 6, - ANMOBJTYPE_VTX = 5, +#define OPT(KEY, VALUE) OPTION_##KEY = (0x20000 | (VALUE)) + enum ScnMdlSimpleOption { + OPT(NONE, 0), + OPT(IGNORE_ANMCHR_TRANS, 1), }; +#undef OPT public: - ScnMdlSimple(MEMAllocator *, ResMdl, math::MTX34 *, u32 *, math::MTX34 *, math::MTX33 *, math::MTX34 *, int, int); + static ScnMdlSimple *Construct(MEMAllocator *pAllocator, u32 *pSize, ResMdl mdl, int numView); - static ScnMdlSimple *Construct(MEMAllocator *, unsigned long *, nw4r::g3d::ResMdl, int); + ScnMdlSimple( + MEMAllocator *pAllocator, ResMdl mdl, math::MTX34 *pWorldMtxArray, u32 *pWorldMtxAttribArray, + math::MTX34 *pViewPosMtxArray, math::MTX33 *pViewNrmMtxArray, math::MTX34 *pViewTexMtxArray, int numView, + int numViewMtx + ); - bool GetScnMtxPos(math::MTX34 *pOut, ScnObjMtxType tp, u32 nodeID) const; + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~ScnMdlSimple(); // at 0x10 - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return (other == GetTypeObjStatic()) ? true : ScnLeaf::IsDerivedFrom(other); - } - static const TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } - virtual void G3dProc(u32, u32, void *); // at 0xC - virtual ~ScnMdlSimple(); // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } + virtual bool SetScnObjOption(u32 option, u32 value); // at 0x20 + virtual bool GetScnObjOption(u32 option, u32 *pValue) const; // at 0x24 - virtual bool SetAnmObj(AnmObj *p, AnmObjType type); - virtual bool RemoveAnmObj(AnmObj *p); - virtual bool RemoveAnmObj(AnmObjType type); - virtual AnmObj *GetAnmObj(AnmObjType type); - virtual AnmObj *GetAnmObj(AnmObjType type) const; + virtual bool SetAnmObj(AnmObj *pObj, AnmObjType type); // at 0x34 + virtual bool RemoveAnmObj(AnmObj *pObj); // at 0x38 + virtual AnmObj *RemoveAnmObj(AnmObjType type); // at 0x3C + virtual AnmObj *GetAnmObj(AnmObjType type); // at 0x40 + virtual const AnmObj *GetAnmObj(AnmObjType type) const; // at 0x44 - const u8 *GetByteCode(ByteCodeType) const; - void EnableScnMdlCallbackTiming(Timing); + bool GetScnMtxPos(math::MTX34 *pMtx, ScnObjMtxType type, u32 idx) const; - const ResMdl GetResMdl() const { + void UpdateFrame(); + + void EnableScnMdlCallbackTiming(Timing timing); + void DisableScnMdlCallbackTiming(Timing timing); + + math::MTX34 *GetViewPosMtxArray(); + const math::MTX34 *GetViewPosMtxArray() const; + + math::MTX33 *GetViewNrmMtxArray(); + const math::MTX33 *GetViewNrmMtxArray() const; + + math::MTX34 *GetViewTexMtxArray(); + const math::MTX34 *GetViewTexMtxArray() const; + + const u8 *GetByteCode(ByteCodeType type) const; + + ResMdl GetResMdl() { return mResMdl; } - ResMdl GetResMdl() { + const ResMdl GetResMdl() const { return mResMdl; } math::MTX34 *GetWldMtxArray() { - return mWldMatrixArray; + return mpWorldMtxArray; } u32 *GetWldMtxAttribArray() { - return mWldMtxAttribArray; + return mpWorldMtxAttribArray; } - u16 GetNumViewMtx() const { + u32 GetNumViewMtx() const { return mNumViewMtx; } - void SetCalcWorldCallback(ICalcWorldCallback *cb) { - mpCalcWorldCallback = cb; + const u8 *GetByteCodeCalc() { + return mpByteCodeCalc; + } + const u8 *GetByteCodeMix() { + return mpByteCodeMix; + } + const u8 *GetByteCodeDrawOpa() { + return mpByteCodeDrawOpa; + } + const u8 *GetByteCodeDrawXlu() { + return mpByteCodeDrawXlu; + } + + ResMdlDrawMode GetDrawMode() const { + return mDrawMode; + } + + void SetScnMdlCallback(ICalcWorldCallback *pCallback) { + mpCalcWorldCallback = pCallback; + } + ICalcWorldCallback *GetScnMdlCallback() { + return mpCalcWorldCallback; + } + + u8 GetScnMdlCallbackTiming() const { + return mCwcbTiming; + } + + void SetScnMdlCallbackNodeID(u32 id) { + mCwcbNodeID = id; + } + u32 GetScnMdlCallbackNodeID() const { + return mCwcbNodeID; + } + + AnmObjChr *GetAnmObjChr() { + return mpAnmObjChr; + } + AnmObjVis *GetAnmObjVis() { + return mpAnmObjVis; + } + AnmObjMatClr *GetAnmObjMatClr() { + return mpAnmObjMatClr; + } + AnmObjTexPat *GetAnmObjTexPat() { + return mpAnmObjTexPat; + } + AnmObjTexSrt *GetAnmObjTexSrt() { + return mpAnmObjTexSrt; + } + +protected: + enum ScnMdlSmplFlag { + SCNMDLSMPLFLAG_LC_DMA = (1 << 0), + }; + + static const int VIEW_MAX = 16; + + static const int MTX_CACHE_MIN = 8; + static const int MTX_CACHE_MAX = sizeof(detail::MtxCacheMap) / sizeof(math::MTX34) + 1; + +protected: + void ScnMdlSmpl_CalcPosture(u32 param, const math::MTX34 *pParent); + + void ScnMdlSmpl_G3DPROC_GATHER_SCNOBJ(u32 param, IScnObjGather *pCollection); + void ScnMdlSmpl_G3DPROC_CALC_WORLD(u32 param, const math::MTX34 *pParent); + void ScnMdlSmpl_G3DPROC_CALC_MAT(u32 param, void *pInfo); + void ScnMdlSmpl_G3DPROC_CALC_VIEW(u32 param, const math::MTX34 *pCamera); + void ScnMdlSmpl_G3DPROC_DRAW_OPA(u32 param, void *pInfo); + void ScnMdlSmpl_G3DPROC_DRAW_XLU(u32 param, void *pInfo); + + void ScnMdlSmpl_G3DPROC_UPDATEFRAME(u32 /* param */, void * /* pInfo */) { + UpdateFrame(); } private: - ResMdl mResMdl; // at 0xE8 - math::MTX34 *mWldMatrixArray; // at 0xEC - u32 *mWldMtxAttribArray; // at 0xF0 - math::MTX34 *PTR_0xF4; - math::MTX33 *PTR_0xF8; - math::MTX34 *PTR_0xFC; - u8 BYTE_0x100; - u8 BYTE_0x101; - u16 mNumViewMtx; // at 0x102 - UNKWORD WORD_0x104; - void *mByteCodeCalc; // at 0x108 - void *mByteCodeMix; // at 0x10C - void *mByteCodeDrawOpa; // at 0x110 - void *mByteCodeDrawXlu; // at 0x114 - UNKWORD WORD_0x118; - ICalcWorldCallback *mpCalcWorldCallback; // at 0x11C + ResMdl mResMdl; // at 0xE8 + math::MTX34 *mpWorldMtxArray; // at 0xEC + u32 *mpWorldMtxAttribArray; // at 0xF0 + math::MTX34 *mpViewPosMtxArray; // at 0xF4 + math::MTX33 *mpViewNrmMtxArray; // at 0xF8 + math::MTX34 *mpViewTexMtxArray; // at 0xFC + u8 mNumView; // at 0x100 + u8 mCurView; // at 0x101 + u16 mNumViewMtx; // at 0x102 + u32 mFlagScnMdlSimple; // at 0x104 - NW4R_G3D_TYPE_OBJ_DECL(ScnMdlSimple); + const u8 *mpByteCodeCalc; // at 0x108 + const u8 *mpByteCodeMix; // at 0x10C + const u8 *mpByteCodeDrawOpa; // at 0x110 + const u8 *mpByteCodeDrawXlu; // at 0x114 + ResMdlDrawMode mDrawMode; // at 0x118 + + ICalcWorldCallback *mpCalcWorldCallback; // at 0x11C + u8 mCwcbTiming; // at 0x120 + u8 mCwcbDeleteOption; // at 0x121 + u16 mCwcbNodeID; // at 0x122 + + AnmObjChr *mpAnmObjChr; // at 0x124 + AnmObjVis *mpAnmObjVis; // at 0x128 + AnmObjMatClr *mpAnmObjMatClr; // at 0x12C + AnmObjTexPat *mpAnmObjTexPat; // at 0x130 + AnmObjTexSrt *mpAnmObjTexSrt; // at 0x134 + + NW4R_G3D_RTTI_DECL_DERIVED(ScnMdlSimple, ScnLeaf); }; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_scnobj.h b/include/nw4r/g3d/g3d_scnobj.h index 61cd03d8..84bb0c54 100644 --- a/include/nw4r/g3d/g3d_scnobj.h +++ b/include/nw4r/g3d/g3d_scnobj.h @@ -1,215 +1,346 @@ -#ifndef NW4R_G3D_SCNOBJ_H -#define NW4R_G3D_SCNOBJ_H -#include "common.h" -#include "nw4r/g3d/g3d_obj.h" -#include "nw4r/math/math_geometry.h" -#include "nw4r/math/math_types.h" +#ifndef NW4R_G3D_SCN_OBJ_H +#define NW4R_G3D_SCN_OBJ_H +#include + +#include + +#include namespace nw4r { namespace g3d { -namespace { -static inline u32 align4(u32 x) { - return x + 3 & ~3; -} -} // namespace -struct IScnObjGather { - virtual ~IScnObjGather(); - virtual UNKWORD Add(ScnObj *, bool, bool) = 0; +extern const math::FRUSTUM *gpCullingFrustum; + +enum ResMdlDrawMode { + RESMDL_DRAWMODE_SORT_OPA_NONE = 0, + RESMDL_DRAWMODE_SORT_OPA_Z = (1 << 0), + + RESMDL_DRAWMODE_SORT_XLU_NONE = 0, + RESMDL_DRAWMODE_SORT_XLU_Z = (1 << 1), + + RESMDL_DRAWMODE_IGNORE_MATERIAL = (1 << 2), + RESMDL_DRAWMODE_FORCE_LIGHTOFF = (1 << 3), + RESMDL_DRAWMODE_NOPPCSYNC = (1 << 4), + + RESMDL_DRAWMODE_DEFAULT = RESMDL_DRAWMODE_SORT_XLU_Z, + REDMDL_DRAWMODE_SORT_NONE = 0, + RESMDL_DRAWMODE_SORT_Z = RESMDL_DRAWMODE_SORT_OPA_Z | RESMDL_DRAWMODE_SORT_XLU_Z, }; +/****************************************************************************** + * + * ScnObj + * + ******************************************************************************/ +// Forward declarations +class IScnObjCallback; + class ScnObj : public G3dObj { public: - enum ForEachResult { FOREACH_RESULT_0, FOREACH_RESULT_1 }; - - enum ScnObjFlag { - SCNOBJFLAG_DISABLE_CALC_WORLD = 1, - SCNOBJFLAG_DISABLE_CALC_MAT = 2, - SCNOBJFLAG_DISABLE_CALC_VTX = 4, - SCNOBJFLAG_DISABLE_CALC_VIEW = 8, - SCNOBJFLAG_DISABLE_GATHER_SCNOBJ = 16, - SCNOBJFLAG_DISABLE_DRAW_OPA = 32, - SCNOBJFLAG_DISABLE_DRAW_XLU = 64, - SCNOBJFLAG_DISABLE_UPDATEFRAME = 128, - SCNOBJFLAG_IGNORE_ANMCHR_TRANS = 256, - SCNOBJFLAG_ENABLE_CULLING = 268435456, - SCNOBJFLAG_NOT_GATHER_DRAW_OPA = 536870912, - SCNOBJFLAG_NOT_GATHER_DRAW_XLU = 1073741824, - SCNOBJFLAG_MTX_LOCAL_IDENTITY = -2147483648, - SCNOBJFLAG_DISABLE_DRAW = 96, + enum ForEachResult { + FOREACHRESULT_OK, + FOREACHRESULT_CONTINUE, + FOREACHRESULT_RETURN, + FOREACHRESULT_GOBACK }; - enum ScnObjMtxType { MTX_TYPE_LOCAL, MTX_TYPE_WORLD, MTX_TYPE_VIEW, MTX_TYPE_MAX }; + typedef ForEachResult (*ForEachFunc)(ScnObj *pParent, void *pInfo); - enum Timing { TIMING_1 = 0x1, TIMING_2 = 0x2, TIMING_4 = 0x4, TIMING_ALL = 0x7 }; + enum ScnObjMtxType { + MTX_LOCAL, + MTX_WORLD, + MTX_VIEW, + MTX_TYPE_MAX + }; - enum ExecOp { EXEC_OP_1 = 0x1, EXEC_OP_2 = 0x2, EXEC_OP_4 = 0x4 }; + enum ScnObjBoundingVolumeType { + BOUNDINGVOLUME_AABB_LOCAL, + BOUNDINGVOLUME_AABB_WORLD, + BOUNDINGVOLUME_MAX + }; - enum ScnObjBoundingVolumeType { BOUNDING_0, BOUNDING_1, BOUNDING_MAX }; +#define OPT(KEY, VALUE) OPTION_##KEY = (0x00000 | (VALUE)) + enum ScnObjOption { + OPT(NONE, 0), + OPT(DISABLE_GATHER_SCNOBJ, 1), + OPT(DISABLE_CALC_WORLD, 2), + OPT(DISABLE_CALC_MAT, 3), + OPT(DISABLE_CALC_VTX, 4), + OPT(DISABLE_CALC_VIEW, 5), + OPT(DISABLE_DRAW_OPA, 6), + OPT(DISABLE_DRAW_XLU, 7), + OPT(DISABLE_UPDATEFRAME, 8), + OPT(ENABLE_CULLING, 9), + }; +#undef OPT - enum ScnObjOption { OPTION_VISIBLE = (1 << 0) }; + enum Timing { + CALLBACK_TIMING_A = (1 << 0), + CALLBACK_TIMING_B = (1 << 1), + CALLBACK_TIMING_C = (1 << 2) + }; - typedef ForEachResult (*ForEachAction)(ScnObj *, void *); + enum ExecOp { + EXECOP_CALC_WORLD = (1 << 0), + EXECOP_CALC_MAT = (1 << 1), + EXECOP_CALC_VIEW = (1 << 2), + EXECOP_DRAW_OPA = (1 << 4), + EXECOP_DRAW_XLU = (1 << 5) + }; public: - ScnObj(MEMAllocator *); + explicit ScnObj(MEMAllocator *pAllocator); - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return (other == GetTypeObjStatic()) ? true : G3dObj::IsDerivedFrom(other); - } - virtual void G3dProc(u32, u32, void *) = 0; // at 0xC - virtual ~ScnObj(); // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } - virtual ForEachResult ForEach(ForEachAction, void *, bool) = 0; // at 0x1C - virtual bool SetScnObjOption(u32, u32); // at 0x20 - virtual bool GetScnObjOption(u32, u32 *) const; // at 0x24 - virtual f32 GetValueForSortOpa() const; // at 0x28 - virtual f32 GetValueForSortXlu() const; // at 0x2C - virtual void CalcWorldMtx(const math::MTX34 *, u32 *); // at 0x30 + virtual void G3dProc(u32 task, u32 param, void *pInfo) = 0; // at 0xC + virtual ~ScnObj(); // at 0x10 - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); + virtual ForEachResult ForEach(ForEachFunc pFunc, void *pInfo, + bool postOrder) = 0; // at 0x1C + + virtual bool SetScnObjOption(u32 option, u32 value); // at 0x20 + virtual bool GetScnObjOption(u32 option, u32 *pValue) const; // at 0x24 + + virtual f32 GetValueForSortOpa() const; // at 0x28 + virtual f32 GetValueForSortXlu() const; // at 0x2C + + virtual void CalcWorldMtx(const math::MTX34 *pParent, + u32 *pParam); // at 0x30 + + void CalcViewMtx(const math::MTX34 *pCamera); + + bool SetMtx(ScnObjMtxType type, const math::MTX34 *pMtx); + bool GetMtx(ScnObjMtxType type, math::MTX34 *pMtx) const; + const math::MTX34 *GetMtxPtr(ScnObjMtxType type) const { + return &mMtxArray[type]; + } + + void SetPriorityDrawOpa(int prio); + int GetPriorityDrawOpa() const { + return mPriorityDrawOpa; + } + + void SetPriorityDrawXlu(int prio); + int GetPriorityDrawXlu() const { + return mPriorityDrawXlu; + } + + void EnableScnObjCallbackTiming(Timing timing); + void EnableScnObjCallbackExecOp(ExecOp op); + + bool SetBoundingVolume(ScnObjBoundingVolumeType type, const math::AABB *pAABB); + bool GetBoundingVolume(ScnObjBoundingVolumeType type, math::AABB *pAABB) const; + + bool SetBoundingVolume(const math::AABB *pAABB) { + return SetBoundingVolume(BOUNDINGVOLUME_AABB_LOCAL, pAABB); } - void CalcViewMtx(const math::MTX34 *); - bool SetMtx(ScnObjMtxType, const math::MTX34 *); - bool GetMtx(ScnObjMtxType, math::MTX34 *) const; - void SetPriorityDrawOpa(int); - void SetPriorityDrawXlu(int); - void EnableScnObjCallbackTiming(Timing); - void EnableScnObjCallbackExecOp(ExecOp); - bool SetBoundingVolume(ScnObjBoundingVolumeType, const math::AABB *); - bool GetBoundingVolume(ScnObjBoundingVolumeType, math::AABB *) const; void SetCallback(IScnObjCallback *cb) { - mCallback = cb; + mpFuncObjExec = cb; } IScnObjCallback *GetScnObjCallback() { - return mCallback; - } - - const math::MTX34 *GetMtxPtr(ScnObjMtxType type) const { - return &mMatrices[type]; - } - - void SetScnObjFlag(ScnObjFlag f, u32 set) { - if (set) { - mFlags |= f; - } else { - mFlags &= ~f; - } - } - bool TestScnObjFlag(ScnObjFlag f) const { - return mFlags & f; - } - - inline void CheckCallback_CALC_VIEW(Timing timing, u32 r5, void *r6); - inline void CheckCallback_CALC_MAT(Timing timing, u32 r5, void *r6); - inline void CheckCallback_CALC_WORLD(Timing timing, u32 r5, void *r6); - - bool IsG3dProcDisabled(u32 task) const { - if ((task < 9) && (1 << (task - 1) & mFlags)) { - return true; - } - return false; + return mpFuncObjExec; } protected: - math::MTX34 mMatrices[MTX_TYPE_MAX]; // at 0xC - math::AABB mBounds[BOUNDING_MAX]; // at 0x9C + enum ScnObjFlag { + SCNOBJFLAG_DISABLE_CALC_WORLD = (1 << 0), + SCNOBJFLAG_DISABLE_CALC_MAT = (1 << 1), + SCNOBJFLAG_DISABLE_CALC_VTX = (1 << 2), + SCNOBJFLAG_DISABLE_CALC_VIEW = (1 << 3), + SCNOBJFLAG_DISABLE_GATHER_SCNOBJ = (1 << 4), + SCNOBJFLAG_DISABLE_DRAW_OPA = (1 << 5), + SCNOBJFLAG_DISABLE_DRAW_XLU = (1 << 6), + SCNOBJFLAG_DISABLE_UPDATEFRAME = (1 << 7), + SCNOBJFLAG_IGNORE_ANMCHR_TRANS = (1 << 8), - u32 mFlags; // at 0xCC - u8 mPriorityDrawOpa; // at 0xD0 - u8 mPriorityDrawXlu; // at 0xD1 - u8 BYTE_0xD2; - u8 BYTE_0xD3; - IScnObjCallback *mCallback; // at 0xD4 - u8 mTiming; // at 0xD8 - u8 BYTE_0xD9; - u16 mExecOp; // at 0xDA + SCNOBJFLAG_ENABLE_CULLING = (1 << 28), + SCNOBJFLAG_NOT_GATHER_DRAW_OPA = (1 << 29), + SCNOBJFLAG_NOT_GATHER_DRAW_XLU = (1 << 30), + SCNOBJFLAG_MTX_LOCAL_IDENTITY = (1 << 31), - NW4R_G3D_TYPE_OBJ_DECL(ScnObj); + SCNOBJFLAG_DISABLE_DRAW = SCNOBJFLAG_DISABLE_DRAW_OPA | SCNOBJFLAG_DISABLE_DRAW_XLU + }; + +protected: + void SetScnObjFlag(ScnObjFlag flag, u32 on) { + if (on) { + mScnObjFlags |= flag; + } else { + mScnObjFlags &= ~flag; + } + } + u32 TestScnObjFlag(ScnObjFlag flag) const { + return (mScnObjFlags & flag) != 0; + } + + bool IsG3dProcDisabled(u32 task) const { + if (task < __G3DPROC_OPTIONAL_END && ((1 << task - 1) & mScnObjFlags)) { + return true; + } + + return false; + } + + /** + * Defined elsewhere to resolve circular dependency with IScnObjCallback + */ + inline void CheckCallback_CALC_VIEW(Timing timing, u32 param, void *pInfo); + inline void CheckCallback_CALC_MAT(Timing timing, u32 param, void *pInfo); + inline void CheckCallback_CALC_WORLD(Timing timing, u32 param, void *pInfo); + inline void CheckCallback_DRAW_OPA(Timing timing, u32 param, void *pInfo); + inline void CheckCallback_DRAW_XLU(Timing timing, u32 param, void *pInfo); + +protected: + math::MTX34 mMtxArray[MTX_TYPE_MAX]; // at 0xC + math::AABB mAABB[BOUNDINGVOLUME_MAX]; // at 0x9C + +private: + u32 mScnObjFlags; // at 0xCC + u8 mPriorityDrawOpa; // at 0xD0 + u8 mPriorityDrawXlu; // at 0xD1 + u8 PADDING_0xD2; // at 0xD2 + u8 PADDING_0xD3; // at 0xD3 + IScnObjCallback *mpFuncObjExec; // at 0xD4 + u8 mCallbackTiming; // at 0xD8 + u8 mCallbackDeleteOption; // at 0xD9 + u16 mCallbackExecOpMask; // at 0xDA + + NW4R_G3D_RTTI_DECL_DERIVED(ScnObj, G3dObj); }; -struct IScnObjCallback { - virtual ~IScnObjCallback() {} // at 0x8 - virtual void ExecCallback_CALC_WORLD(ScnObj::Timing, ScnObj *, u32, void *) {} // at 0xC - virtual void ExecCallback_CALC_MAT(ScnObj::Timing, ScnObj *, u32, void *) {} // at 0x10 - virtual void ExecCallback_CALC_VIEW(ScnObj::Timing, ScnObj *, u32, void *) {} // at 0x14 - virtual void ExecCallback_DRAW_OPA(ScnObj::Timing, ScnObj *, u32, void *) {} // at 0x18 - virtual void ExecCallback_DRAW_XLU(ScnObj::Timing, ScnObj *, u32, void *) {} // at 0x1C -}; - -// Is there a better way of resolving this dependency? -void ScnObj::CheckCallback_CALC_VIEW(Timing timing, u32 r5, void *r6) { - if (mCallback != NULL) { - if ((mExecOp & EXEC_OP_4) && (mTiming & timing)) { - mCallback->ExecCallback_CALC_VIEW(timing, this, r5, r6); - } - } -} - -void ScnObj::CheckCallback_CALC_MAT(Timing timing, u32 r5, void *r6) { - if (mCallback != NULL) { - if ((mExecOp & EXEC_OP_2) && (mTiming & timing)) { - mCallback->ExecCallback_CALC_MAT(timing, this, r5, r6); - } - } -} - -void ScnObj::CheckCallback_CALC_WORLD(Timing timing, u32 r5, void *r6) { - if (mCallback != NULL) { - if ((mExecOp & EXEC_OP_1) && (mTiming & timing)) { - mCallback->ExecCallback_CALC_WORLD(timing, this, r5, r6); - } - } -} - -class ScnLeaf : public ScnObj { +/****************************************************************************** + * + * IScnObjGather + * + ******************************************************************************/ +class IScnObjGather { public: - // Unofficial name, however GetScaleProperty needs to return an enum to match - enum ScaleProperty { - SCALE_PROPERTY_0, - SCALE_PROPERTY_1, - SCALE_PROPERTY_2, + typedef bool (*LessThanFunc)(const ScnObj *pLhs, const ScnObj *pRhs); + + enum CullingStatus { + CULLINGSTATUS_INTERSECT, + CULLINGSTATUS_INSIDE, + CULLINGSTATUS_OUTSIDE, + CULLINGSTATUS_NOTEST }; public: - ScnLeaf(MEMAllocator *allocator) : ScnObj(allocator), mScale(1.0f, 1.0f, 1.0f) {} + virtual ~IScnObjGather() {} // at 0x8 - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return (other == GetTypeObjStatic()) ? true : ScnObj::IsDerivedFrom(other); - } - virtual void G3dProc(u32, u32, void *) = 0; // at 0xC - virtual ~ScnLeaf() {} // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } - virtual ForEachResult ForEach(ForEachAction, void *, bool); // at 0x1C - virtual bool SetScnObjOption(u32, u32); // at 0x20 - virtual bool GetScnObjOption(u32, u32 *) const; // at 0x24 - virtual void CalcWorldMtx(const math::MTX34 *, u32 *); // at 0x30 + virtual CullingStatus Add(ScnObj *pObj, bool opa, bool xlu) = 0; // at 0xC + virtual void Clear() = 0; // at 0x10 + virtual void ZSort() = 0; // at 0x14 - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); + virtual void Sort() = 0; // at 0x18 + virtual void Sort(LessThanFunc pOpaFunc, + LessThanFunc pXluFunc) = 0; // at 0x1C + + virtual void DrawOpa(ResMdlDrawMode *pForceMode) = 0; // at 0x20 + virtual void DrawXlu(ResMdlDrawMode *pForceMode) = 0; // at 0x24 +}; + +/****************************************************************************** + * + * IScnObjCallback + * + ******************************************************************************/ +class IScnObjCallback { +public: + virtual ~IScnObjCallback() {} // at 0x8 + + virtual void + ExecCallback_CALC_WORLD(ScnObj::Timing /* timing */, ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */) { + } // at 0xC + + virtual void + ExecCallback_CALC_MAT(ScnObj::Timing /* timing */, ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */) { + } // at 0x10 + + virtual void + ExecCallback_CALC_VIEW(ScnObj::Timing /* timing */, ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */) { + } // at 0x14 + + virtual void + ExecCallback_DRAW_OPA(ScnObj::Timing /* timing */, ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */) { + } // at 0x18 + + virtual void + ExecCallback_DRAW_XLU(ScnObj::Timing /* timing */, ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */) { + } // at 0x1C +}; + +/****************************************************************************** + * + * ScnObj implementation + * + ******************************************************************************/ +void ScnObj::CheckCallback_CALC_VIEW(Timing timing, u32 param, void *pInfo) { + if (mpFuncObjExec != NULL && (mCallbackExecOpMask & EXECOP_CALC_VIEW) && (mCallbackTiming & timing)) { + mpFuncObjExec->ExecCallback_CALC_VIEW(timing, this, param, pInfo); } +} + +void ScnObj::CheckCallback_CALC_MAT(Timing timing, u32 param, void *pInfo) { + if (mpFuncObjExec != NULL && (mCallbackExecOpMask & EXECOP_CALC_MAT) && (mCallbackTiming & timing)) { + mpFuncObjExec->ExecCallback_CALC_MAT(timing, this, param, pInfo); + } +} + +void ScnObj::CheckCallback_CALC_WORLD(Timing timing, u32 param, void *pInfo) { + if (mpFuncObjExec != NULL && (mCallbackExecOpMask & EXECOP_CALC_WORLD) && (mCallbackTiming & timing)) { + mpFuncObjExec->ExecCallback_CALC_WORLD(timing, this, param, pInfo); + } +} + +void ScnObj::CheckCallback_DRAW_OPA(Timing timing, u32 param, void *pInfo) { + if (mpFuncObjExec != NULL && (mCallbackExecOpMask & EXECOP_DRAW_OPA) && (mCallbackTiming & timing)) { + mpFuncObjExec->ExecCallback_DRAW_OPA(timing, this, param, pInfo); + } +} + +void ScnObj::CheckCallback_DRAW_XLU(Timing timing, u32 param, void *pInfo) { + if (mpFuncObjExec != NULL && (mCallbackExecOpMask & EXECOP_DRAW_XLU) && (mCallbackTiming & timing)) { + mpFuncObjExec->ExecCallback_DRAW_XLU(timing, this, param, pInfo); + } +} + +/****************************************************************************** + * + * ScnLeaf + * + ******************************************************************************/ +class ScnLeaf : public ScnObj { +public: + enum ScaleProperty { + NOT_SCALED, + UNIFORM_SCALED, + NONUNIFORM_SCALED, + }; + +#define OPT(KEY, VALUE) OPTION_##KEY = (0x10000 | (VALUE)) + enum ScnLeafOption { + OPT(NONE, 0), + OPT(DISABLE_DRAW_ALL, 1), + }; +#undef OPT + +public: + explicit ScnLeaf(MEMAllocator *pAllocator) : ScnObj(pAllocator), mScale(1.0f, 1.0f, 1.0f) {} + + virtual void G3dProc(u32 task, u32 param, void *pInfo) = 0; // at 0xC + virtual ~ScnLeaf() {} // at 0x10 + + virtual ForEachResult ForEach(ForEachFunc pFunc, void *pInfo, + bool postOrder); // at 0x1C + + virtual bool SetScnObjOption(u32 option, u32 value); // at 0x20 + virtual bool GetScnObjOption(u32 option, u32 *pValue) const; // at 0x24 + + virtual void CalcWorldMtx(const math::MTX34 *pParent, + u32 *pParam); // at 0x30 ScaleProperty GetScaleProperty() const; - void DefG3dProcScnLeaf(u32, u32, void *); inline void SetScale(f32 x, f32 y, f32 z) { mScale.x = x; @@ -227,51 +358,55 @@ public: } } -private: - math::VEC3 mScale; +protected: + void DefG3dProcScnLeaf(u32 task, u32 param, void *pInfo); - NW4R_G3D_TYPE_OBJ_DECL(ScnLeaf); +private: + math::VEC3 mScale; // at 0xDC + + NW4R_G3D_RTTI_DECL_DERIVED(ScnLeaf, ScnObj); }; +/****************************************************************************** + * + * ScnGroup + * + ******************************************************************************/ class ScnGroup : public ScnObj { public: - ScnGroup(MEMAllocator *, ScnObj **, u32); + ScnGroup(MEMAllocator *pAllocator, ScnObj **ppObj, u32 capacity); - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return (other == GetTypeObjStatic()) ? true : ScnObj::IsDerivedFrom(other); - } - virtual void G3dProc(u32, u32, void *); // at 0xC - virtual ~ScnGroup(); // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } - virtual ForEachResult ForEach(ForEachAction, void *, bool); // at 0x1C - virtual bool Insert(u32, ScnObj *); // at 0x34 - virtual ScnObj *Remove(u32); // at 0x38 - virtual bool Remove(ScnObj *); // at 0x3C + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~ScnGroup(); // at 0x10 - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); + virtual ForEachResult ForEach(ForEachFunc pFunc, void *pInfo, + bool postOrder); // at 0x1C + + virtual bool Insert(u32 idx, ScnObj *pObj); // at 0x34 + virtual ScnObj *Remove(u32 idx); // at 0x38 + virtual bool Remove(ScnObj *pObj); // at 0x3C + + ScnObj **Begin() { + return mpScnObjArray; + } + ScnObj **End() { + return mpScnObjArray + mNumScnObj; } - bool PushBack(ScnObj *obj) { - return Insert(Size(), obj); - } - - bool Empty() const { - return mSize == 0; + ScnObj *operator[](u32 idx) { + return mpScnObjArray[idx]; } u32 Size() const { - return mSize; + return mNumScnObj; + } + bool Empty() const { + return mNumScnObj == 0; } + bool PushBack(ScnObj *pObj) { + return Insert(mNumScnObj, pObj); + } ScnObj *PopBack() { if (!Empty()) { return Remove(Size() - 1); @@ -286,19 +421,23 @@ public: } } - void ScnGroup_G3DPROC_GATHER_SCNOBJ(u32, IScnObjGather *); - void ScnGroup_G3DPROC_CALC_WORLD(u32, const math::MTX34 *); - void ScnGroup_G3DPROC_CALC_MAT(u32, void *); - void ScnGroup_G3DPROC_CALC_VIEW(u32, const math::MTX34 *); - void DefG3dProcScnGroup(u32, u32, void *); - - ScnObj **mObjects; // at 0xDC - u32 mCapacity; // at 0xE0 - u32 mSize; // at 0xE4 +protected: + void DefG3dProcScnGroup(u32 task, u32 param, void *pInfo); private: - NW4R_G3D_TYPE_OBJ_DECL(ScnGroup); + void ScnGroup_G3DPROC_GATHER_SCNOBJ(u32 param, IScnObjGather *pCollection); + void ScnGroup_G3DPROC_CALC_WORLD(u32 param, const math::MTX34 *pParent); + void ScnGroup_G3DPROC_CALC_MAT(u32 param, void *pInfo); + void ScnGroup_G3DPROC_CALC_VIEW(u32 param, const math::MTX34 *pCamera); + +private: + ScnObj **mpScnObjArray; // at 0xDC + u32 mSizeScnObj; // at 0xE0 + u32 mNumScnObj; // at 0xE4 + + NW4R_G3D_RTTI_DECL_DERIVED(ScnGroup, ScnObj); }; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_scnproc.h b/include/nw4r/g3d/g3d_scnproc.h index c9d75a1d..66df4a83 100644 --- a/include/nw4r/g3d/g3d_scnproc.h +++ b/include/nw4r/g3d/g3d_scnproc.h @@ -1,75 +1,70 @@ -#ifndef NW4R_G3D_SCNPROC_H -#define NW4R_G3D_SCNPROC_H -#include "common.h" -#include "nw4r/g3d/g3d_scnobj.h" +#ifndef NW4R_G3D_SCN_PROC_H +#define NW4R_G3D_SCN_PROC_H +#include + +#include namespace nw4r { namespace g3d { + class ScnProc : public ScnLeaf { public: - typedef void (*DrawProc)(ScnProc *, bool opa); + typedef void (*DrawProc)(ScnProc *pProc, bool opa); - ScnProc(MEMAllocator *allocator, DrawProc proc, void *userdata, bool set1, bool set2) - : ScnLeaf(allocator), mFlags(0), mDrawProc(proc), mUserData(userdata) { - if (set1) { - mFlags |= 0x1; +public: + static ScnProc *Construct(MEMAllocator *pAllocator, u32 *pSize, DrawProc pProc, bool opa, bool xlu, u32 userData); + + ScnProc(MEMAllocator *pAllocator, DrawProc pProc, void *pUserData, bool opa, bool xlu) + : ScnLeaf(pAllocator), mFlag(0), mpDrawProc(pProc), mpUserData(pUserData) { + if (opa) { + mFlag |= SCNPROCFLAG_DRAW_OPA; } - if (set2) { - mFlags |= 0x2; + + if (xlu) { + mFlag |= SCNPROCFLAG_DRAW_XLU; } } - static ScnProc *Construct(MEMAllocator *, u32 *, DrawProc, bool, bool, u32); + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~ScnProc() {} // at 0x10 - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return other == GetTypeObjStatic() ? true : ScnLeaf::IsDerivedFrom(other); - }; - virtual void G3dProc(u32, u32, void *); // at 0xC - virtual ~ScnProc() {} // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); + void SetDrawProc(DrawProc pProc, bool opa, bool xlu) { + mpDrawProc = pProc; + + if (opa) { + mFlag |= SCNPROCFLAG_DRAW_OPA; + } else { + mFlag &= ~SCNPROCFLAG_DRAW_OPA; + } + + if (xlu) { + mFlag |= SCNPROCFLAG_DRAW_XLU; + } else { + mFlag &= ~SCNPROCFLAG_DRAW_XLU; + } } - static const G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); + void SetUserData(void *pData) { + mpUserData = pData; } - void *GetUserData() { - return mUserData; - } - void SetUserData(void *data) { - mUserData = data; - } - - void SetDrawProc(DrawProc proc, bool r5, bool r6) { - mDrawProc = proc; - - if (r5) { - mFlags |= 0x1; - } else { - mFlags &= ~0x1; - } - - if (r6) { - mFlags |= 0x2; - } else { - mFlags &= ~0x2; - } + return mpUserData; } private: - u32 mFlags; // at 0xE8 - DrawProc mDrawProc; // at 0xEC - void *mUserData; // at 0xF0 + enum ScnProcFlag { + SCNPROCFLAG_DRAW_OPA = (1 << 0), + SCNPROCFLAG_DRAW_XLU = (1 << 1) + }; - NW4R_G3D_TYPE_OBJ_DECL(ScnProc); +private: + u32 mFlag; // at 0xE8 + DrawProc mpDrawProc; // at 0xEC + void *mpUserData; // at 0xF0 + + NW4R_G3D_RTTI_DECL_DERIVED(ScnProc, ScnLeaf); }; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_scnrfl.h b/include/nw4r/g3d/g3d_scnrfl.h index 67a898bf..2a64dabb 100644 --- a/include/nw4r/g3d/g3d_scnrfl.h +++ b/include/nw4r/g3d/g3d_scnrfl.h @@ -1,52 +1,51 @@ -#ifndef NW4R_G3D_SCNRFL_H -#define NW4R_G3D_SCNRFL_H -#include "RFL/RFL_MiddleDatabase.h" -#include "RFL/RFL_Model.h" -#include "common.h" -#include "nw4r/g3d/g3d_scnobj.h" +// #ifndef NW4R_G3D_SCNRFL_H +// #define NW4R_G3D_SCNRFL_H +// #include "RFL/RFL_MiddleDatabase.h" +// #include "RFL/RFL_Model.h" +// #include "common.h" +// #include "nw4r/g3d/g3d_scnobj.h" +// namespace nw4r { +// namespace g3d { +// class ScnRfl : public ScnLeaf { +// public: +// struct RflData { +// bool SetupCharModel(RFLDataSource, u16, RFLMiddleDB *); +// }; -namespace nw4r { -namespace g3d { -class ScnRfl : public ScnLeaf { -public: - struct RflData { - bool SetupCharModel(RFLDataSource, u16, RFLMiddleDB *); - }; +// public: +// static ScnRfl *Construct(MEMAllocator *, u32 *, RFLResolution, u32, u32); +// ScnRfl(MEMAllocator *, ScnRfl *, RflData *, void *, u32); -public: - static ScnRfl *Construct(MEMAllocator *, u32 *, RFLResolution, u32, u32); - ScnRfl(MEMAllocator *, ScnRfl *, RflData *, void *, u32); +// virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 +// { +// return (other == GetTypeObjStatic()); +// } +// virtual void G3dProc(u32, u32, void *); // at 0xC +// virtual ~ScnRfl(); // at 0x10 +// virtual const TypeObj GetTypeObj() const // at 0x14 +// { +// return TypeObj(TYPE_NAME); +// } +// virtual const char *GetTypeName() const // at 0x18 +// { +// return GetTypeObj().GetTypeName(); +// } - virtual bool IsDerivedFrom(TypeObj other) const // at 0x8 - { - return (other == GetTypeObjStatic()); - } - virtual void G3dProc(u32, u32, void *); // at 0xC - virtual ~ScnRfl(); // at 0x10 - virtual const TypeObj GetTypeObj() const // at 0x14 - { - return TypeObj(TYPE_NAME); - } - virtual const char *GetTypeName() const // at 0x18 - { - return GetTypeObj().GetTypeName(); - } +// bool GetExpression(RFLExpression *); +// bool SetExpression(RFLExpression); - bool GetExpression(RFLExpression *); - bool SetExpression(RFLExpression); +// void SetFogIdx(int); +// void SetLightSetIdx(int); - void SetFogIdx(int); - void SetLightSetIdx(int); +// static const nw4r::g3d::G3dObj::TypeObj GetTypeObjStatic() { +// return TypeObj(TYPE_NAME); +// } - static const nw4r::g3d::G3dObj::TypeObj GetTypeObjStatic() { - return TypeObj(TYPE_NAME); - } +// private: +// NW4R_G3D_TYPE_OBJ_DECL(ScnRfl); +// }; +// } // namespace g3d +// } // namespace nw4r -private: - NW4R_G3D_TYPE_OBJ_DECL(ScnRfl); -}; -} // namespace g3d -} // namespace nw4r - -#endif +// #endif diff --git a/include/nw4r/g3d/g3d_scnroot.h b/include/nw4r/g3d/g3d_scnroot.h index c1e14298..600ca308 100644 --- a/include/nw4r/g3d/g3d_scnroot.h +++ b/include/nw4r/g3d/g3d_scnroot.h @@ -1,49 +1,135 @@ -#ifndef NW4R_G3D_SCNROOT_H -#define NW4R_G3D_SCNROOT_H -#include "common.h" -#include "nw4r/g3d/g3d_camera.h" -#include "nw4r/g3d/g3d_fog.h" -#include "nw4r/g3d/g3d_light.h" -#include "nw4r/g3d/g3d_scnobj.h" +#ifndef NW4R_G3D_SCN_ROOT_H +#define NW4R_G3D_SCN_ROOT_H +#include + +#include +#include +#include +#include +#include namespace nw4r { namespace g3d { + +// Forward declarations +class AnmScn; + +/****************************************************************************** + * + * ScnRoot + * + ******************************************************************************/ class ScnRoot : public ScnGroup { public: - Camera GetCamera(int); - Camera GetCurrentCamera(); - void SetCurrentCamera(int); - Fog GetFog(int); + enum ScnRootFlag { + SCNROOTFLAG_FORCE_RESMDLDRAWMODE = (1 << 0) + }; - static ScnRoot *Construct(MEMAllocator *pHeap, u32 *pSize, u32 maxNumChildren, u32 maxNumScnObj, u32 numLightObj, - u32 numLightSet); +public: + static ScnRoot * + Construct(MEMAllocator *pAllocator, u32 *pSize, u32 maxChildren, u32 maxScnObj, u32 numLightObj, u32 numLightSet); + + static ScnRoot *Construct(MEMAllocator *pAllocator, u32 *pSize, u32 maxChildren, u32 maxScnObj) { + return Construct(pAllocator, pSize, maxChildren, maxScnObj, G3DState::NUM_LIGHT, G3DState::NUM_LIGHT_SET); + } + + ScnRoot( + MEMAllocator *pAllocator, IScnObjGather *pGather, ScnObj **ppChildrenBuf, u32 maxChildren, u32 numLight, + u32 numLightSet, LightObj *pLightObjBuf, AmbLightObj *pAmbObjBuf, LightSetData *pLightSetBuf + ); + + virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC + virtual ~ScnRoot(); // at 0x10 + + Camera GetCamera(int idx); + Camera GetCurrentCamera(); + void SetCurrentCamera(int idx); + + Fog GetFog(int idx); + LightSet GetLightSet(int idx); void UpdateFrame(); + void SetGlbSettings(); + + void CalcAnmScn(); void CalcWorld(); void CalcMaterial(); void CalcVtx(); void CalcView(); + void GatherDrawScnObj(); void ZSort(); void DrawOpa(); void DrawXlu(); - u8 GetCurrentCameraID() const { - return mCameraId; + u32 TestScnRootFlag(ScnRootFlag flag) const { + return (mScnRootFlags & flag) != 0; + } + void SetScnRootFlag(ScnRootFlag flag, u32 on) { + if (on) { + mScnRootFlags |= flag; + } else { + mScnRootFlags &= ~flag; + } } - inline LightSetting *getLightSetting() { - return &mLightSetting; + int GetCurrentCameraID() const { + return mCurrentCameraID; + } + + LightSetting &GetLightSetting() { + return mLightSetting; } private: - UNKWORD WORD_0xE8; - UNKWORD WORD_0xEC; - UNKWORD WORD_0xF0; - /* 0x00F4 */ u8 mCameraId; - u8 unk1[0x2878 - 0x00F8]; - /* 0x2878 */ LightSetting mLightSetting; + IScnObjGather *mpCollection; // at 0xE8 + ResMdlDrawMode mDrawMode; // at 0xEC + u32 mScnRootFlags; // at 0xF0 + u8 mCurrentCameraID; // at 0xF4 + u8 PADDING_0xF5; // at 0xF5 + u8 PADDING_0xF6; // at 0xF6 + u8 PADDING_0xF7; // at 0xF7 + CameraData mCamera[G3DState::NUM_CAMERA]; // at 0xF8 + FogData mFog[G3DState::NUM_FOG]; // at 0x2278 + LightSetting mLightSetting; // at 0x2878 + AnmScn *mpAnmScn; // at 0x2888 + + NW4R_G3D_RTTI_DECL_DERIVED(ScnRoot, ScnGroup); }; + +/****************************************************************************** + * + * ScnObjGather + * + ******************************************************************************/ +class ScnObjGather : public IScnObjGather { +public: + ScnObjGather(ScnObj **ppBufOpa, ScnObj **ppBufXlu, u32 capacity); + + virtual ~ScnObjGather() {} // at 0x8 + + virtual CullingStatus Add(ScnObj *pObj, bool opa, bool xlu); // at 0xC + virtual void Clear() { + mNumScnObjOpa = mNumScnObjXlu = 0; + } // at 0x10 + + virtual void ZSort(); // at 0x14 + + virtual void Sort(); // at 0x18 + virtual void Sort(LessThanFunc pOpaFunc, + LessThanFunc pXluFunc); // at 0x1C + + virtual void DrawOpa(ResMdlDrawMode *pForceMode); // at 0x20 + virtual void DrawXlu(ResMdlDrawMode *pForceMode); // at 0x24 + +protected: + ScnObj **mpArrayOpa; // at 0x4 + ScnObj **mpArrayXlu; // at 0x8 + u32 mSizeScnObj; // at 0xC + u32 mNumScnObjOpa; // at 0x10 + u32 mNumScnObjXlu; // at 0x14 +}; + } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_state.h b/include/nw4r/g3d/g3d_state.h index a257b84b..aa696a22 100644 --- a/include/nw4r/g3d/g3d_state.h +++ b/include/nw4r/g3d/g3d_state.h @@ -1,24 +1,197 @@ #ifndef NW4R_G3D_STATE_H #define NW4R_G3D_STATE_H -#include "common.h" -#include "nw4r/math.h" // IWYU pragma: export -#include "rvl/GX.h" // IWYU pragma: export +#include + +#include +#include +#include + +#include + +#include namespace nw4r { namespace g3d { +namespace detail { + +/****************************************************************************** + * + * ScnDependentMtxFunc + * + ******************************************************************************/ +namespace ScnDependentMtxFunc { + +void EnvironmentMapping(math::MTX34 *pMtx, s8 camRef, s8 lightRef); +void ProjectionMapping(math::MTX34 *pMtx, s8 camRef, s8 lightRef); +void EnvironmentSpecularMapping(math::MTX34 *pMtx, s8 camRef, s8 lightRef); +void DefaultMapping(math::MTX34 *pMtx, s8 camRef, s8 lightRef); + +} // namespace ScnDependentMtxFunc +} // namespace detail + +/****************************************************************************** + * + * G3DState + * + ******************************************************************************/ namespace G3DState { -struct IndMtxOp {}; -void SetViewPosNrmMtxArray(const math::MTX34 *, const math::MTX33 *, const math::MTX34 *); +static const int NUM_LIGHT = 128; +static const int NUM_LIGHT_SET = 128; -void SetRenderModeObj(const GXRenderModeObj &); -GXRenderModeObj &GetRenderModeObj(); -void LoadLightSet( - int idx_lightset, u32 *mask_diff_color /* r1+0xC */, u32 *mask_diff_alpha, u32 *mask_spec_color, - u32 *mask_spec_alpha, AmbLightObj *amb +static const int NUM_LIGHT_IN_LIGHT_SET = 8; + +static const int NUM_CAMERA = 32; +static const int NUM_FOG = 32; + +static const int NUM_SCNDEPENDENT_TEXMTX_FUNCTYPE = 256; + +enum InvalidateFlag { + INVALIDATE_TEX = (1 << 0), + INVALIDATE_TLUT = (1 << 1), + INVALIDATE_TEV = (1 << 2), + INVALIDATE_GENMODE = (1 << 3), + INVALIDATE_SHP = (1 << 4), + INVALIDATE_CURRMTX = (1 << 5), + INVALIDATE_TEXMTX = (1 << 6), + INVALIDATE_MISC = (1 << 7), + INVALIDATE_FOG = (1 << 8), + INVALIDATE_LIGHT = (1 << 9), + INVALIDATE_POSMTX = (1 << 10), + + INVALIDATE_ALL = INVALIDATE_TEX | INVALIDATE_TLUT | INVALIDATE_TEV | INVALIDATE_GENMODE | INVALIDATE_SHP | + INVALIDATE_CURRMTX | INVALIDATE_TEXMTX | INVALIDATE_MISC | INVALIDATE_FOG | INVALIDATE_LIGHT | + INVALIDATE_POSMTX +}; + +enum ScnDependentTexMtxFuncType { + SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_TEXCOORD, + SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_NRM, + SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_POS, + SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_COLOR, + + MAX_SCNDEPENDENT_TEXMTX_FUNCTYPE, + + SCNDEPENDENT_TEXMTX_FUNCTYPE_TEXMTX_NOT_EXIST = SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_TEXCOORD, +}; + +typedef void (*ScnDependentTexMtxFuncPtr)(math::MTX34 *pMtx, s8 camRef, s8 lightRef); + +/****************************************************************************** + * + * IndTexMtxInfo + * + ******************************************************************************/ +struct IndTexMtxInfo { + u32 flag; // at 0x0 + math::MTX34 offset_mtx[GX_ITM_2 - GX_ITM_0 + 1]; // at 0x4 + + IndTexMtxInfo() : flag(0) {} + explicit IndTexMtxInfo(const ResMatIndMtxAndScale ind); + + void FifoSend() const; + void SetMtx(GXIndTexMtxID id, const math::MTX34 &rMtx); +}; + +/****************************************************************************** + * + * IndMtxOp + * + ******************************************************************************/ +class IndMtxOp { +public: + virtual void operator()(IndTexMtxInfo *pInfo) = 0; // at 0x8 + + virtual ~IndMtxOp() {} // at 0xC + virtual void Reset() = 0; // at 0x10 + + virtual void SetNrmMapMtx( + GXIndTexMtxID id, const math::VEC3 *pLightVec, const math::MTX34 *pNrmMtx, + ResMatMiscData::IndirectMethod method + ) = 0; // at 0x14 +}; + +/****************************************************************************** + * + * IndMtxOpStd + * + ******************************************************************************/ +class IndMtxOpStd : public IndMtxOp { +public: + IndMtxOpStd(); + + virtual void operator()(IndTexMtxInfo *pInfo); // at 0x8 + + virtual ~IndMtxOpStd() {} // at 0xC + virtual void Reset(); // at 0x10 + + virtual void SetNrmMapMtx( + GXIndTexMtxID id, const math::VEC3 *pLightVec, const math::MTX34 *pNrmMtx, + ResMatMiscData::IndirectMethod method + ); // at 0x14 + +private: + bool mIsValidMtx[GX_ITM_2 - GX_ITM_0 + 1]; // at 0x4 + u8 PADDING_0x7; // at 0x7 + math::MTX34 mIndMtx[GX_ITM_2 - GX_ITM_0 + 1]; // at 0x8 +}; + +/****************************************************************************** + * + * Functions + * + ******************************************************************************/ +void LoadResMatMisc(const ResMatMisc misc); +void LoadResTexObj(const ResTexObj texObj); +void LoadResTlutObj(const ResTlutObj tlutObj); +void LoadResGenMode(const ResGenMode mode); +void LoadResTev(const ResTev tev); +void LoadResMatPix(const ResMatPix pix); +void LoadResMatTevColor(const ResMatTevColor color); +void LoadResMatIndMtxAndScale(const ResMatIndMtxAndScale ind); +void LoadResMatIndMtxAndScale(const ResMatIndMtxAndScale ind, IndMtxOp &rOp); +void LoadResMatChan( + const ResMatChan chan, u32 maskDiffColor, u32 maskDiffAlpha, u32 maskSpecColor, u32 maskSpecAlpha, GXColor amb, + bool lightOff ); +void LoadResMatTexCoordGen(const ResMatTexCoordGen gen); +void LoadResTexSrt(const ResTexSrt srt); +void LoadResShpPrePrimitive(const ResShp shp); +void LoadResShpPrimitive(const ResShp shp, const math::MTX34 *pViewPos, const math::MTX34 *pViewNrm); + +void SetViewPosNrmMtxArray( + const math::MTX34 *pViewPosMtxArray, const math::MTX33 *pViewNrmMtxArray, const math::MTX34 *pViewEnvTexMtxArray +); +const math::MTX33 *GetViewNrmMtxPtr(u32 id); + +void SetScnDependentTexMtxFunc(u32 id, ScnDependentTexMtxFuncPtr func, ScnDependentTexMtxFuncType type); +bool GetScnDependentTexMtxFunc(u32 id, ScnDependentTexMtxFuncPtr *pFunc, ScnDependentTexMtxFuncType *pType); + +IndMtxOp *GetIndMtxOp(); + +void SetFog(const Fog fog, int id); +void LoadFog(int id); + +void SetLightSetting(const LightSetting &rSetting); +const LightObj *GetLightObj(int id); +void LoadLightSet( + int id, u32 *pDiffColorMask, u32 *pDiffAlphaMask, u32 *pSpecColorMask, u32 *pSpecAlphaMask, AmbLightObj *pAmb +); +void LoadLightSet(int id, u32 *pDiffMask, u32 *pSpecMask, AmbLightObj *pAmb); + +void SetCameraProjMtx(const Camera &rCam, int id, bool view); +const math::MTX34 *GetCameraMtxPtr(); +const math::MTX34 *GetInvCameraMtxPtr(); +const math::MTX34 *GetCameraMtxPtr(int id); +const math::MTX34 *GetProjectionTexMtxPtr(); +const math::MTX34 *GetProjectionTexMtxPtr(int id); +const math::MTX34 *GetEnvironmentTexMtxPtr(); + +void SetRenderModeObj(const GXRenderModeObj &rObj); +const GXRenderModeObj *GetRenderModeObj(); + +void Invalidate(u32 flag = INVALIDATE_ALL); -void Invalidate(u32); } // namespace G3DState } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/g3d_tmem.h b/include/nw4r/g3d/g3d_tmem.h deleted file mode 100644 index 6ab71c9b..00000000 --- a/include/nw4r/g3d/g3d_tmem.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef NW4R_G3D_TMEM_H -#define NW4R_G3D_TMEM_H -#include "common.h" - -namespace nw4r { -namespace g3d { -namespace tmem { -enum TMemLayout { TMEM_LAYOUT_0, TMEM_LAYOUT_1 }; - -void SetTMemLayout(TMemLayout); -} // namespace tmem -} // namespace g3d -} // namespace nw4r - -#endif diff --git a/include/nw4r/g3d/g3d_workmem.h b/include/nw4r/g3d/g3d_workmem.h index 0a03d1f2..e30f6f37 100644 --- a/include/nw4r/g3d/g3d_workmem.h +++ b/include/nw4r/g3d/g3d_workmem.h @@ -1,19 +1,67 @@ -#ifndef NW4R_G3D_WORKMEM_H -#define NW4R_G3D_WORKMEM_H -#include "common.h" +#ifndef NW4R_G3D_WORK_MEM_H +#define NW4R_G3D_WORK_MEM_H +#include -#define G3D_WORKMEM_SIZE 0x18000 +#include + +#include namespace nw4r { namespace g3d { namespace detail { namespace workmem { -void *GetScaleTemporary(); -void *GetMtxIDTemporary(); -void *GetMdlZTemporary(); -void *GetSkinningMtxTemporary(); -void *GetBillboardMtxTemporary(); -void *GetShpAnmResultBufTemporary(); + +/****************************************************************************** + * + * MdlZ + * + ******************************************************************************/ +struct MdlZ { + f32 Z; // at 0x0 + u16 priority; // at 0x4 + u16 nodeID; // at 0x6 + u16 matID; // at 0x8 + u16 shpID; // at 0xA +}; + +/****************************************************************************** + * + * ShpAnmResultBuf + * + ******************************************************************************/ +struct ShpAnmResultBuf { + ShpAnmResult resultBuf; // at 0x0 + const ShpAnmResult *pResult; // at 0x218 + f32 weight; // at 0x21C +}; + +/****************************************************************************** + * + * Work memory size constants + * + ******************************************************************************/ +static const int WORKMEM_SIZE = 0x18000; + +static const int WORKMEM_NUMTMPSCALE = 2048; +static const int WORKMEM_NUMMTXID = 2048; +static const int WORKMEM_NUMBYTECODE = WORKMEM_SIZE; +static const int WORKMEM_NUMMDLZ = 2048; +static const int WORKMEM_NUMSKINNINGMTX = 2048; +static const int WORKMEM_NUMBBMTX = 2048; +static const int WORKMEM_NUMSHPANMRESULT = WORKMEM_SIZE / sizeof(ShpAnmResultBuf); + +/****************************************************************************** + * + * Work memory accessor functions + * + ******************************************************************************/ +math::VEC3 *GetScaleTemporary(); +u32 *GetMtxIDTemporary(); +MdlZ *GetMdlZTemporary(); +math::MTX34 *GetSkinningMtxTemporary(); +math::MTX34 *GetBillboardMtxTemporary(); +ShpAnmResultBuf *GetShpAnmResultBufTemporary(); + } // namespace workmem } // namespace detail } // namespace g3d diff --git a/include/nw4r/g3d/g3d_xsi.h b/include/nw4r/g3d/g3d_xsi.h index a993df96..818e243f 100644 --- a/include/nw4r/g3d/g3d_xsi.h +++ b/include/nw4r/g3d/g3d_xsi.h @@ -1,15 +1,22 @@ #ifndef NW4R_G3D_XSI_H #define NW4R_G3D_XSI_H -#include "common.h" -#include "nw4r/math.h" -#include "nw4r/g3d/g3d_anmtexsrt.h" +#include + +#include namespace nw4r { namespace g3d { namespace detail { namespace dcc { -bool CalcTexMtx_Xsi(math::MTX34 *, bool, const TexSrt &, TexSrt::Flag); -} + +bool CalcTexMtx_Xsi(math::MTX34 *pMtx, bool set, const TexSrt &rSrt, TexSrt::Flag flag); + +u32 CalcWorldMtx_Xsi( + math::MTX34 *pW, math::VEC3 *pS, const math::MTX34 *pW1, const math::VEC3 *pS1, u32 attr, + const g3d::ChrAnmResult *pResult +); + +} // namespace dcc } // namespace detail } // namespace g3d } // namespace nw4r diff --git a/include/nw4r/g3d/platform/g3d_allocator.h b/include/nw4r/g3d/platform/g3d_allocator.h new file mode 100644 index 00000000..2f76bc0e --- /dev/null +++ b/include/nw4r/g3d/platform/g3d_allocator.h @@ -0,0 +1,22 @@ +#ifndef NW4R_G3D_PLATFORM_ALLOCATOR_H +#define NW4R_G3D_PLATFORM_ALLOCATOR_H +#include + +#include + +namespace nw4r { +namespace g3d { +namespace detail { + +inline void *AllocFromAllocator(MEMAllocator *pAllocator, u32 size) { + return MEMAllocFromAllocator(pAllocator, size); +} +inline void FreeToAllocator(MEMAllocator *pAllocator, void *pBlock) { + return MEMFreeToAllocator(pAllocator, pBlock); +} + +} // namespace detail +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/platform/g3d_cpu.h b/include/nw4r/g3d/platform/g3d_cpu.h new file mode 100644 index 00000000..ba3ebdea --- /dev/null +++ b/include/nw4r/g3d/platform/g3d_cpu.h @@ -0,0 +1,169 @@ +#ifndef NW4R_G3D_PLATFORM_CPU_H +#define NW4R_G3D_PLATFORM_CPU_H +#include + +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * Fastcast + * + ******************************************************************************/ +namespace fastcast { + +/****************************************************************************** + * + * Convert from U8 + * + ******************************************************************************/ +inline f32 U8_0ToF32(const u8 *pPtr) { + f32 x; + OSu8tof32(const_cast(pPtr), &x); + return x; +} + +/****************************************************************************** + * + * Convert from U16 + * + ******************************************************************************/ +inline f32 U16_0ToF32(const u16 *pPtr) { + f32 x; + OSu16tof32(const_cast(pPtr), &x); + return x; +} + +/****************************************************************************** + * + * Convert from S16 + * + ******************************************************************************/ +inline f32 S7_8ToF32(register const s16 *pPtr) { + register f32 f; + + // clang-format off + asm { + psq_l f, 0(pPtr), 1, 7 + } + // clang-format on + + return f; +} + +inline f32 S10_5ToF32(register const s16 *pPtr) { + register f32 f; + + // clang-format off + asm { + psq_l f, 0(pPtr), 1, 6 + } + // clang-format on + + return f; +} + +/****************************************************************************** + * + * Convert from F32 + * + ******************************************************************************/ +inline u8 F32ToU8_0(f32 f) { + u8 x; + OSf32tou8(&f, &x); + return x; +} + +inline s16 F32ToS10_5(register f32 f) { + s16 x; + register s16 *pPtr = &x; + + // clang-format off + asm { + psq_st f, 0(pPtr), 1, 6 + } + // clang-format on + + return x; +} + +/****************************************************************************** + * + * GQR + * + ******************************************************************************/ +inline void SetGQR6_S10_5() { + OSSetGQR6(OS_GQR_TYPE_S16, 5); +} +inline void SetGQR7_S7_8() { + OSSetGQR7(OS_GQR_TYPE_S16, 8); +} + +/****************************************************************************** + * + * Initialization + * + ******************************************************************************/ +namespace detail { + +inline void Init() { + OSInitFastCast(); + SetGQR6_S10_5(); + SetGQR7_S7_8(); +} + +} // namespace detail +} // namespace fastcast + +/****************************************************************************** + * + * Cache + * + ******************************************************************************/ +namespace DC { + +inline void StoreRange(void *pBase, u32 size) { + DCStoreRange(pBase, size); +} + +inline void StoreRangeNoSync(void *pBase, u32 size) { + DCStoreRangeNoSync(pBase, size); +} + +inline void FlushRangeNoSync(void *pBase, u32 size) { + DCFlushRangeNoSync(pBase, size); +} + +inline void InvalidateRange(void *pBase, u32 size) { + DCInvalidateRange(pBase, size); +} + +} // namespace DC + +/****************************************************************************** + * + * Memory + * + ******************************************************************************/ +namespace detail { + +void Copy32ByteBlocks(void *pDst, const void *pSrc, u32 size); +void ZeroMemory32ByteBlocks(void *pDst, u32 size); + +} // namespace detail + +/****************************************************************************** + * + * Initialize fastcast + * + ******************************************************************************/ +inline void InitFastCast() { + fastcast::detail::Init(); +} + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/platform/g3d_gpu.h b/include/nw4r/g3d/platform/g3d_gpu.h new file mode 100644 index 00000000..b2e824ec --- /dev/null +++ b/include/nw4r/g3d/platform/g3d_gpu.h @@ -0,0 +1,109 @@ +#ifndef NW4R_G3D_PLATFORM_GPU_H +#define NW4R_G3D_PLATFORM_GPU_H +#include + +#include + +#include + +#include + +namespace nw4r { +namespace g3d { +namespace fifo { + +// Swap bits to get hardware representation +static const u8 cm2hw[] = {0b0000, 0b0010, 0b0001, 0b0011}; + +inline void LoadBPCmd(u32 reg) { + GXCmd1u8(GX_FIFO_CMD_LOAD_BP_REG); + GXCmd1u32(reg); +} + +inline void LoadCPCmd(u8 addr, u32 value) { + GXCmd1u8(GX_FIFO_CMD_LOAD_CP_REG); + GXCmd1u8(addr); + GXCmd1u32(value); +} + +inline void LoadXFCmd(u16 addr, u32 value) { + GXCmd1u8(GX_FIFO_CMD_LOAD_XF_REG); + GXCmd1u16(0); // No size (single write) + GXCmd1u16(addr); + GXCmd1u32(value); +} + +inline void LoadXFCmdHdr(u16 addr, u8 len) { + GXCmd1u8(GX_FIFO_CMD_LOAD_XF_REG); + GXCmd1u16(len - 1); + GXCmd1u16(addr); +} + +void GDSetGenMode2(u8 numTexGens, u8 numChans, u8 numTevs, u8 numInds, GXCullMode cullMode); + +inline void GDSetGenMode2Ex_BP(u8 numTexGens, u8 numChans, u8 numTevs, u8 numInds, GXCullMode cullMode) { + // clang-format off + // @note NUMCOLORS is actually three bits + LoadBPCmd(GX_BP_REG_SSMASK << GX_BP_OPCODE_SHIFT | + GX_BP_GENMODE_NUMTEX_MASK | + 0b11 << GX_BP_GENMODE_NUMCOLORS_SHIFT | + GX_BP_GENMODE_NUMTEVSTAGES_MASK | + GX_BP_GENMODE_CULLMODE_MASK | + GX_BP_GENMODE_NUMINDSTAGES_MASK); + // clang-format on + + // clang-format off + LoadBPCmd( + numTexGens << GX_BP_GENMODE_NUMTEX_SHIFT | + numChans << GX_BP_GENMODE_NUMCOLORS_SHIFT | + numTevs - 1 << GX_BP_GENMODE_NUMTEVSTAGES_SHIFT | + cm2hw[cullMode] << GX_BP_GENMODE_CULLMODE_SHIFT | + numInds << GX_BP_GENMODE_NUMINDSTAGES_SHIFT | + GX_BP_REG_GENMODE << GX_BP_OPCODE_SHIFT); + // clang-format on +} + +void GDSetCullMode(GXCullMode cullMode); + +void GDSetTexCoordScale2( + GXTexCoordID coord, u16 scaleS, GXBool biasS, GXBool wrapS, u16 scaleT, GXBool biasT, GXBool wrapT +); + +void GDSetIndTexMtx(u32 id, const math::MTX34 &rMtx); + +void GDResetCurrentMtx(); +void GDSetCurrentMtx(const u32 *pIdArray); + +void GDLoadTexMtxImm3x3(const math::MTX33 &rMtx, u32 id); + +inline void GDSetChanCtrl(GXChannelID chan, u32 param, u32 lightMask) { + param &= ~(GX_XF_COLOR0CNTRL_LMASKLO_MASK | GX_XF_COLOR0CNTRL_LMASKHI_MASK); + + param |= (lightMask & 0b1111) << GX_XF_COLOR0CNTRL_LMASKLO_SHIFT | ((lightMask >> 4) & 0b1111) + << GX_XF_COLOR0CNTRL_LMASKHI_SHIFT; + + LoadXFCmd(GX_XF_REG_COLOR0CNTRL + (chan & 3), param); +} + +inline void GDSetChanCtrlLightOff(GXChannelID chan, u32 param, u32 lightMask) { + param &= ~(GX_XF_COLOR0CNTRL_LMASKLO_MASK | GX_XF_COLOR0CNTRL_LMASKHI_MASK | GX_XF_COLOR0CNTRL_LIGHT_MASK); + + param |= (lightMask & 0b1111) << GX_XF_COLOR0CNTRL_LMASKLO_SHIFT | ((lightMask >> 4) & 0b1111) + << GX_XF_COLOR0CNTRL_LMASKHI_SHIFT; + + LoadXFCmd(GX_XF_REG_COLOR0CNTRL + (chan & 3), param); +} + +inline void GDSetChanAmbColor(GXChannelID chan, GXColor color) { + LoadXFCmd(GX_XF_REG_AMBIENT0 + chan, *reinterpret_cast(&color)); +} + +inline void GDSetChanMatColor(GXChannelID chan, GXColor color) { + LoadXFCmd(GX_XF_REG_MATERIAL0 + chan, *reinterpret_cast(&color)); +} + +} // namespace fifo +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/platform/g3d_tmem.h b/include/nw4r/g3d/platform/g3d_tmem.h new file mode 100644 index 00000000..fc524c26 --- /dev/null +++ b/include/nw4r/g3d/platform/g3d_tmem.h @@ -0,0 +1,23 @@ +#ifndef NW4R_G3D_PLATFORM_TMEM_H +#define NW4R_G3D_PLATFORM_TMEM_H +#include + +namespace nw4r { +namespace g3d { +namespace tmem { + +// TODO: Naming +enum TMemLayout { + TMEM_LAYOUT_NONE, + TMEM_LAYOUT_1, + TMEM_LAYOUT_2, + TMEM_LAYOUT_3 +}; + +void SetTMemLayout(TMemLayout layout); + +} // namespace tmem +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resanm.h b/include/nw4r/g3d/res/g3d_resanm.h new file mode 100644 index 00000000..5bc7c68e --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resanm.h @@ -0,0 +1,148 @@ +#ifndef NW4R_G3D_RESANM_H +#define NW4R_G3D_RESANM_H +#include "common.h" + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * ResKeyFrame + * + ******************************************************************************/ +struct ResKeyFrameData { + f32 frame; // at 0x0 + f32 value; // at 0x4 + f32 slope; // at 0x8 +}; + +struct ResKeyFrameAnmData { + u16 numKeyFrame; // at 0x0 + u8 PADDING_0x2[0x4 - 0x2]; // at 0x2 + f32 invKeyFrameRange; // at 0x4 + ResKeyFrameData keyFrames[1]; // at 0x8 +}; + +namespace detail { + +f32 GetResKeyFrameAnmResult(const ResKeyFrameAnmData *pData, f32 frame); + +} // namespace detail + +/****************************************************************************** + * + * ResAnm + * + ******************************************************************************/ +enum AnmPolicy { + ANM_POLICY_ONETIME, + ANM_POLICY_LOOP, + ANM_POLICY_MAX +}; + +union ResAnmData { + f32 constValue; // at 0x0 + s32 toResKeyFrameAnmData; // at 0x0 +}; + +namespace detail { + +inline f32 GetResAnmResult(const ResAnmData *pData, f32 frame, bool constant) { + if (constant) { + return pData->constValue; + } + + const ResKeyFrameAnmData *pFrameData = reinterpret_cast( + reinterpret_cast(pData) + pData->toResKeyFrameAnmData + ); + + return GetResKeyFrameAnmResult(pFrameData, frame); +} + +template +inline f32 ClipFrame(const T &rInfo, f32 frame) { + if (frame <= 0.0f) { + return 0.0f; + } + + if (rInfo.numFrame <= frame) { + return rInfo.numFrame; + } + + return frame; +} + +} // namespace detail + +/****************************************************************************** + * + * ResColorAnm + * + ******************************************************************************/ +union ResColorAnmData { + u32 constValue; // at 0x0 + s32 toResColorAnmFramesData; // at 0x0 +}; +struct ResColorAnmFramesData { + u32 frameColors[1]; // at 0x0 +}; + +namespace detail { + +u32 GetResColorAnmResult(const ResColorAnmFramesData *pData, f32 frame); + +inline u32 GetResColorAnmResult(const ResColorAnmData *pData, f32 frame, bool constant) { + if (constant) { + return pData->constValue; + } + + const ResColorAnmFramesData *pFrameData = reinterpret_cast( + reinterpret_cast(pData) + pData->toResColorAnmFramesData + ); + + return GetResColorAnmResult(pFrameData, frame); +} + +} // namespace detail + +/****************************************************************************** + * + * ResBoolAnm + * + ******************************************************************************/ +union ResBoolAnmData { + s32 toResBoolAnmFramesData; // at 0x0 +}; +struct ResBoolAnmFramesData { + u32 boolBits[1]; // at 0x0 +}; + +namespace detail { + +inline bool GetResBoolAnmFramesResult(const ResBoolAnmFramesData *pData, int frame) { + const u32 *pBits = pData->boolBits; + u32 index = static_cast(frame); + + u32 wordIdx = index / 32; + u32 bitIdx = index % 32; + + u32 targetBit = (1U << 31) >> bitIdx; + u32 bitWord = pBits[wordIdx]; + + return bitWord & targetBit; +} + +inline bool GetResBoolAnmResult(const ResBoolAnmData *pData, int frame) { + const ResBoolAnmFramesData *pFrameData = reinterpret_cast( + reinterpret_cast(pData) + pData->toResBoolAnmFramesData + ); + + return GetResBoolAnmFramesResult(pFrameData, frame); +} + +} // namespace detail + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resanmamblight.h b/include/nw4r/g3d/res/g3d_resanmamblight.h new file mode 100644 index 00000000..c9e2a48c --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resanmamblight.h @@ -0,0 +1,66 @@ +#ifndef NW4R_G3D_RES_RES_ANM_AMB_LIGHT_H +#define NW4R_G3D_RES_RES_ANM_AMB_LIGHT_H +#include + +#include "nw4r/g3d/res/g3d_resanm.h" +#include "nw4r/g3d/res/g3d_rescommon.h" + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * AmbLightResult + * + ******************************************************************************/ +struct AmbLightAnmResult { + enum Flag { + FLAG_COLOR_ENABLE = (1 << 0), + FLAG_ALPHA_ENABLE = (1 << 1), + }; + + u32 flags; // at 0x0 + u32 color; // at 0x4 +}; + +/****************************************************************************** + * + * ResAnmAmbLight + * + ******************************************************************************/ +struct ResAnmAmbLightData { + enum Flag { + FLAG_COLOR_ENABLE = (1 << 0), + FLAG_ALPHA_ENABLE = (1 << 1), + + FLAG_CONST = (1 << 31) + }; + + u32 size; // at 0x0 + s32 toResAnmScnData; // at 0x4 + s32 name; // at 0x8 + u32 id; // at 0xC + u32 refNumber; // at 0x10 + u32 flags; // at 0x14 + ResColorAnmData color; // at 0x18 +}; + +class ResAnmAmbLight : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResAnmAmbLight); + + void GetAnmResult(AmbLightAnmResult *pResult, f32 frame) const; + + u32 GetID() const { + return ref().id; + } + + u32 GetRefNumber() const { + return ref().refNumber; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resanmcamera.h b/include/nw4r/g3d/res/g3d_resanmcamera.h new file mode 100644 index 00000000..5bc6e976 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resanmcamera.h @@ -0,0 +1,134 @@ +#ifndef NW4R_G3D_RES_RES_ANM_CAMERA_H +#define NW4R_G3D_RES_RES_ANM_CAMERA_H +#include + +#include +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * Common types + * + ******************************************************************************/ +struct ResAnmCameraDataTypedef { + enum CameraType { + CAMERATYPE_ROTATE, + CAMERATYPE_AIM, + + CAMERATYPE_MAX + }; +}; + +/****************************************************************************** + * + * CameraAnmResult + * + ******************************************************************************/ +struct CameraAnmResult : ResAnmCameraDataTypedef { + enum Flag { + FLAG_CAMERA_TYPE_MASK = (1 << 0), + FLAG_ANM_EXISTS = (1 << 1) + }; + + u32 flags; // at 0x0 + GXProjectionType projType; // at 0x4 + math::VEC3 pos; // at 0x8 + f32 aspect; // at 0x14 + f32 near; // at 0x18 + f32 far; // at 0x1C + + union { + struct { + math::_VEC3 rot; // at 0x20 + } rotate; + + struct { + math::_VEC3 aim; // at 0x20 + f32 twist; // at 0x2C + } aim; + }; + + union { + f32 perspFovy; // at 0x30 + f32 orthoHeight; // at 0x30 + }; +}; + +/****************************************************************************** + * + * ResAnmCamera + * + ******************************************************************************/ +struct ResAnmCameraData : ResAnmCameraDataTypedef { + enum Flag { + FLAG_CAMERA_TYPE_MASK = (1 << 0), + FLAG_ANM_EXISTS = (1 << 1), + + FLAG_POS_X_CONST = (1 << 17), + FLAG_POS_Y_CONST = (1 << 18), + FLAG_POS_Z_CONST = (1 << 19), + + FLAG_ASPECT_CONST = (1 << 20), + FLAG_NEAR_CONST = (1 << 21), + FLAG_FAR_CONST = (1 << 22), + + FLAG_PERSP_FOVY_CONST = (1 << 23), + FLAG_ORTHO_HEIGHT_CONST = (1 << 24), + + FLAG_AIM_X_CONST = (1 << 25), + FLAG_AIM_Y_CONST = (1 << 26), + FLAG_AIM_Z_CONST = (1 << 27), + FLAG_TWIST_CONST = (1 << 28), + + FLAG_ROT_X_CONST = (1 << 29), + FLAG_ROT_Y_CONST = (1 << 30), + FLAG_ROT_Z_CONST = (1 << 31) + }; + + u32 size; // at 0x0 + s32 toResAnmScnData; // at 0x4 + s32 name; // at 0x8 + u32 id; // at 0xC + u32 refNumber; // at 0x10 + GXProjectionType projType; // at 0x14 + u32 flags; // at 0x18 + s32 toResUserData; // at 0x1C + ResAnmData posX; // at 0x20 + ResAnmData posY; // at 0x24 + ResAnmData posZ; // at 0x28 + ResAnmData aspect; // at 0x2C + ResAnmData near; // at 0x30 + ResAnmData far; // at 0x34 + ResAnmData rotX; // at 0x38 + ResAnmData rotY; // at 0x3C + ResAnmData rotZ; // at 0x40 + ResAnmData aimX; // at 0x44 + ResAnmData aimY; // at 0x48 + ResAnmData aimZ; // at 0x4C + ResAnmData twist; // at 0x50 + ResAnmData perspFovy; // at 0x54 + ResAnmData orthoHeight; // at 0x58 +}; + +class ResAnmCamera : public ResCommon, public ResAnmCameraDataTypedef { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResAnmCamera); + + void GetAnmResult(CameraAnmResult *pResult, f32 frame) const; + + u32 GetID() const { + return ref().id; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resanmchr.h b/include/nw4r/g3d/res/g3d_resanmchr.h new file mode 100644 index 00000000..a2989b89 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resanmchr.h @@ -0,0 +1,287 @@ +#ifndef NW4R_G3D_RES_RES_ANM_CHR_H +#define NW4R_G3D_RES_RES_ANM_CHR_H + +/** NOTICE: Revision change from 4->5. Structures, Enums, and/or Functions may have changed and not yet done so + * (Zeldex72, Feb 1, 2025) */ + +#include + +#include +#include +#include + +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * ChrAnmResult + * + ******************************************************************************/ +struct ChrAnmResult { + enum Flag { + FLAG_ANM_EXISTS = (1 << 0), + FLAG_MTX_IDENT = (1 << 1), + FLAG_ROT_TRANS_ZERO = (1 << 2), + FLAG_SCALE_ONE = (1 << 3), + FLAG_SCALE_UNIFORM = (1 << 4), + FLAG_ROT_ZERO = (1 << 5), + FLAG_TRANS_ZERO = (1 << 6), + FLAG_PATCH_SCALE = (1 << 7), + FLAG_PATCH_ROT = (1 << 8), + FLAG_PATCH_TRANS = (1 << 9), + + // Maya Scale Compensation + FLAG_SSC_APPLY = (1 << 10), + FLAG_SSC_PARENT = (1 << 11), + + // Softimage Hierarchical Scaling + FLAG_XSI_SCALING = (1 << 12), + + FLAG_ROT_RAW_FMT = (1 << 31) + }; + + u32 flags; // at 0x0 + math::VEC3 s; // at 0x4 + math::VEC3 rawR; // at 0x10 + math::MTX34 rt; // at 0x1C + + void GetScale(math::VEC3 *pScale) const; + bool GetRotateDeg(math::VEC3 *pRotate) const; + void GetTranslate(math::VEC3 *pTrans) const; + void GetRotTrans(math::MTX34 *pRotTrans) const; + + void SetScale(const math::VEC3 *pScale); + void SetRotTrans(const math::MTX34 *pRotTrans); +}; + +/****************************************************************************** + * + * Frame values (FVS) animation data + * + ******************************************************************************/ +struct ResAnmChrFrm32Data { + union { + u32 fvsU32; // at 0x0 + + struct { + u8 frame; // at 0x0 + u8 vs[3]; // at 0x1 + } fvs; + }; +}; +struct ResAnmChrFVS32Data { + f32 scale; // at 0x0 + f32 offset; // at 0x4 + ResAnmChrFrm32Data frameValues[1]; // at 0x8 +}; + +struct ResAnmChrFrm48Data { + s16 frame; // at 0x0 + u16 value; // at 0x2 + s16 slope; // at 0x4 +}; +struct ResAnmChrFVS48Data { + f32 scale; // at 0x0 + f32 offset; // at 0x4 + ResAnmChrFrm48Data frameValues[1]; // at 0x8 +}; + +struct ResAnmChrFrm96Data { + f32 frame; // at 0x0 + f32 value; // at 0x4 + f32 slope; // at 0x8 +}; +struct ResAnmChrFVS96Data { + ResAnmChrFrm96Data frameValues[1]; // at 0x0 +}; + +struct ResAnmChrFVSData { + u16 numFrameValues; // at 0x0 + u8 PADDING_0x2[0x4 - 0x2]; // at 0x2 + f32 invKeyFrameRange; // at 0x4 + + union { + ResAnmChrFVS32Data fvs32; // at 0x8 + ResAnmChrFVS48Data fvs48; // at 0x8 + ResAnmChrFVS96Data fvs96; // at 0x8 + }; +}; + +/****************************************************************************** + * + * Const value (CV) animation data + * + ******************************************************************************/ +struct ResAnmChrCV8Data { + f32 scale; // at 0x0 + f32 offset; // at 0x4 + u8 values[1]; // at 0x8 +}; +struct ResAnmChrCV16Data { + f32 scale; // at 0x0 + f32 offset; // at 0x4 + u16 values[1]; // at 0x8 +}; +struct ResAnmChrCV32Data { + f32 values[1]; // at 0x0 +}; + +struct ResAnmChrCVData { + union { + ResAnmChrCV8Data cv8; // at 0x0 + ResAnmChrCV16Data cv16; // at 0x0 + ResAnmChrCV32Data cv32; // at 0x0 + }; +}; + +/****************************************************************************** + * + * ResAnmChr + * + ******************************************************************************/ +struct ResAnmChrAnmData { + union { + ResAnmChrFVSData fvs; // at 0x0 + ResAnmChrCVData cv; // at 0x0 + }; +}; + +struct ResAnmChrNodeData { + enum Flag { + FLAG_ANM_EXISTS = (1 << 0), + FLAG_MTX_IDENT = (1 << 1), + FLAG_ROT_TRANS_ZERO = (1 << 2), + FLAG_SCALE_ONE = (1 << 3), + FLAG_SCALE_UNIFORM = (1 << 4), + FLAG_ROT_ZERO = (1 << 5), + FLAG_TRANS_ZERO = (1 << 6), + FLAG_PATCH_SCALE = (1 << 7), + FLAG_PATCH_ROT = (1 << 8), + FLAG_PATCH_TRANS = (1 << 9), + + // Maya Scale Compensation + FLAG_SSC_APPLY = (1 << 10), + FLAG_SSC_PARENT = (1 << 11), + + // Softimage Hierarchical Scaling + FLAG_XSI_SCALING = (1 << 12), + + FLAG_SCALE_X_CONST = (1 << 13), + FLAG_SCALE_Y_CONST = (1 << 14), + FLAG_SCALE_Z_CONST = (1 << 15), + + FLAG_ROT_X_CONST = (1 << 16), + FLAG_ROT_Y_CONST = (1 << 17), + FLAG_ROT_Z_CONST = (1 << 18), + + FLAG_TRANS_X_CONST = (1 << 19), + FLAG_TRANS_Y_CONST = (1 << 20), + FLAG_TRANS_Z_CONST = (1 << 21), + + FLAG_HAS_SCALE = (1 << 22), + FLAG_HAS_ROT = (1 << 23), + FLAG_HAS_TRANS = (1 << 24), + + FLAG_SCALE_FVS32_FMT = (1 << 25), + FLAG_SCALE_FVS48_FMT = (1 << 26), + FLAG_SCALE_FVS96_FMT = FLAG_SCALE_FVS32_FMT | FLAG_SCALE_FVS48_FMT, + + FLAG_ROT_FVS32_FMT = (1 << 27), + FLAG_ROT_FVS48_FMT = (1 << 28), + FLAG_ROT_FVS96_FMT = FLAG_ROT_FVS32_FMT | FLAG_ROT_FVS48_FMT, + + FLAG_ROT_CV8_FMT = (1 << 29), + FLAG_ROT_CV16_FMT = (1 << 27) | (1 << 29), + FLAG_ROT_CV32_FMT = (1 << 28) | (1 << 29), + + FLAG_TRANS_FVS32_FMT = (1 << 30), + FLAG_TRANS_FVS48_FMT = (1 << 31), + FLAG_TRANS_FVS96_FMT = FLAG_TRANS_FVS32_FMT | FLAG_TRANS_FVS48_FMT, + + FLAG_HAS_SRT_MASK = FLAG_HAS_SCALE | FLAG_HAS_ROT | FLAG_HAS_TRANS, + + FLAG_SCALE_FMT_MASK = FLAG_SCALE_FVS32_FMT | FLAG_SCALE_FVS48_FMT | FLAG_SCALE_FVS96_FMT, + + FLAG_ROT_FMT_MASK = FLAG_ROT_FVS32_FMT | FLAG_ROT_FVS48_FMT | FLAG_ROT_FVS96_FMT | FLAG_ROT_CV8_FMT | + FLAG_ROT_CV16_FMT | FLAG_ROT_CV32_FMT, + + FLAG_TRANS_FMT_MASK = FLAG_TRANS_FVS32_FMT | FLAG_TRANS_FVS48_FMT | FLAG_TRANS_FVS96_FMT + }; + + union AnmData { + s32 toResAnmChrAnmData; // at 0x0 + f32 constValue; // at 0x0 + }; + + s32 name; // at 0x0 + u32 flags; // at 0x4 + AnmData anms[1]; // at 0x8 +}; + +struct ResAnmChrInfoData { + u16 numFrame; // at 0x0 + u16 numNode; // at 0x2 + AnmPolicy policy; // at 0x4 + ScalingRule scalingRule; // at 0x8 +}; + +struct ResAnmChrData { + ResBlockHeaderData header; // at 0x0 + u32 revision; // at 0x8 + s32 toResFileData; // at 0xC + s32 toChrDataDic; // at 0x10 + s32 toResUserData; // at 0x14 + s32 name; // at 0x18 + s32 original_path; // at 0x1C + ResAnmChrInfoData info; // at 0x20 +}; + +class ResAnmChr : public ResCommon { +public: + static const u32 SIGNATURE = 'CHR0'; + static const int REVISION = 5; + +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResAnmChr); + + u32 GetRevision() const { + return ref().revision; + } + + bool CheckRevision() const { + return GetRevision() == REVISION; + } + + void GetAnmResult(ChrAnmResult *pResult, u32 idx, f32 frame) const; + + const ResAnmChrNodeData *GetNodeAnm(int idx) const { + return static_cast(ofs_to_obj(ref().toChrDataDic)[idx]); + } + const ResAnmChrNodeData *GetNodeAnm(u32 idx) const { + return static_cast(ofs_to_obj(ref().toChrDataDic)[idx]); + } + + s32 GetNodeAnmIndex(const ResName name) const { + return ofs_to_obj(ref().toChrDataDic).GetIndex(name); + } + + int GetNumFrame() const { + return ref().info.numFrame; + } + + int GetNumNode() const { + return ref().info.numNode; + } + + AnmPolicy GetAnmPolicy() const { + return ref().info.policy; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resanmclr.h b/include/nw4r/g3d/res/g3d_resanmclr.h new file mode 100644 index 00000000..52577dcf --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resanmclr.h @@ -0,0 +1,127 @@ +#ifndef NW4R_G3D_RES_RES_ANM_CLR_H +#define NW4R_G3D_RES_RES_ANM_CLR_H + +/** NOTICE: Revision change from 3->4. Structures, Enums, and/or Functions may have changed and not yet done so + * (Zeldex72, Feb 1, 2025) */ + +#include + +#include +#include +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * ClrAnmResult + * + ******************************************************************************/ +struct ClrAnmResult { + enum ColorAnim { + CLA_CLR0, + CLA_CLR1, + CLA_AMB0, + CLA_AMB1, + + CLA_TEV0, + CLA_TEV1, + CLA_TEV2, + + CLA_TEVK0, + CLA_TEVK1, + CLA_TEVK2, + CLA_TEVK3, + + CLA_MAX + }; + + u32 bRgbaExist; // at 0x0 + u32 rgba[CLA_MAX]; // at 0x4 + u32 rgbaMask[CLA_MAX]; // at 0x30 +}; + +/****************************************************************************** + * + * ResAnmClr + * + ******************************************************************************/ +struct ResAnmClrAnmData { + u32 mask; // at 0x0 + ResColorAnmData color; // at 0x4 +}; + +struct ResAnmClrMatData { + enum Flag { + FLAG_ANM_EXISTS = (1 << 0), + FLAG_ANM_CONSTANT = (1 << 1), + + // Two bits in 'flags' for each animation + NUM_OF_FLAGS = 2 + }; + + s32 name; // at 0x0 + u32 flags; // at 0x4 + ResAnmClrAnmData anms[1]; // at 0x8 +}; + +struct ResAnmClrInfoData { + u16 numFrame; // at 0x0 + u16 numMaterial; // at 0x2 + AnmPolicy policy; // at 0x4 +}; + +struct ResAnmClrData { + ResBlockHeaderData header; // at 0x0 + u32 revision; // at 0x8 + s32 toResFileData; // at 0xC + s32 toClrDataDic; // at 0x10 + s32 toResUserData; // at 0x14 + s32 name; // at 0x18 + s32 original_path; // at 0x1C + ResAnmClrInfoData info; // at 0x20 +}; + +class ResAnmClr : public ResCommon { +public: + static const u32 SIGNATURE = 'CLR0'; + static const int REVISION = 4; + +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResAnmClr); + + u32 GetRevision() const { + return ref().revision; + } + + bool CheckRevision() const { + return GetRevision() == REVISION; + } + + void GetAnmResult(ClrAnmResult *pResult, u32 idx, f32 frame) const; + + const ResAnmClrMatData *GetMatAnm(int idx) const { + return static_cast(ofs_to_obj(ref().toClrDataDic)[idx]); + } + const ResAnmClrMatData *GetMatAnm(u32 idx) const { + return static_cast(ofs_to_obj(ref().toClrDataDic)[idx]); + } + + int GetNumFrame() const { + return ref().info.numFrame; + } + + int GetNumMaterial() const { + return ref().info.numMaterial; + } + + AnmPolicy GetAnmPolicy() const { + return ref().info.policy; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resanmfog.h b/include/nw4r/g3d/res/g3d_resanmfog.h new file mode 100644 index 00000000..afcca2b5 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resanmfog.h @@ -0,0 +1,65 @@ +#ifndef NW4R_G3D_RES_RES_ANM_FOG_H +#define NW4R_G3D_RES_RES_ANM_FOG_H +#include + +#include +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * FogAnmResult + * + ******************************************************************************/ +struct FogAnmResult { + GXFogType type; // at 0x0 + f32 startz; // at 0x4 + f32 endz; // at 0x8 + ut::Color color; // at 0xC +}; + +/****************************************************************************** + * + * ResAnmFog + * + ******************************************************************************/ +struct ResAnmFogData { + enum Flag { + FLAG_START_CONST = (1 << 29), + FLAG_END_CONST = (1 << 30), + FLAG_COLOR_CONST = (1 << 31) + }; + + u32 size; // at 0x0 + s32 toResAnmScnData; // at 0x4 + s32 name; // at 0x8 + u32 id; // at 0xC + u32 refNumber; // at 0x10 + u32 flags; // at 0x14 + GXFogType type; // at 0x18 + ResAnmData startz; // at 0x1C + ResAnmData endz; // at 0x20 + ResColorAnmData color; // at 0x24 +}; + +class ResAnmFog : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResAnmFog); + + void GetAnmResult(FogAnmResult *pResult, f32 frame) const; + + u32 GetID() const { + return ref().id; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resanmlight.h b/include/nw4r/g3d/res/g3d_resanmlight.h new file mode 100644 index 00000000..304927fa --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resanmlight.h @@ -0,0 +1,144 @@ +#ifndef NW4R_G3D_RES_RES_ANM_LIGHT_H +#define NW4R_G3D_RES_RES_ANM_LIGHT_H +#include + +#include +#include + +#include +#include + +#include + +namespace nw4r { +namespace g3d { + +// Forward declarations +struct LightAnmResult; + +/****************************************************************************** + * + * Common types + * + ******************************************************************************/ +struct ResAnmLightDataTypedef { + enum LightType { + LIGHTTYPE_POINT, + LIGHTTYPE_DIRECTIONAL, + LIGHTTYPE_SPOT, + + LIGHTTYPE_MAX + }; +}; + +/****************************************************************************** + * + * LightAnmResult + * + ******************************************************************************/ +struct LightAnmResult : ResAnmLightDataTypedef { + enum Flag { + FLAG_LIGHT_TYPE_MASK = (1 << 0) | (1 << 1), + FLAG_LIGHT_ENABLE = (1 << 2), + FLAG_SPECULAR_ENABLE = (1 << 3), + FLAG_COLOR_ENABLE = (1 << 4), + FLAG_ALPHA_ENABLE = (1 << 5) + }; + + u32 specIdx; // at 0x0 + u32 flags; // at 0x4 + math::VEC3 pos; // at 0x8 + math::VEC3 aim; // at 0x14 + ut::Color color; // at 0x20 + GXDistAttnFn distFunc; // at 0x24 + f32 refDistance; // at 0x28 + f32 refBrightness; // at 0x2C + GXSpotFn spotFunc; // at 0x30 + f32 cutoff; // at 0x34 + ut::Color specColor; // at 0x38 + f32 shininess; // at 0x3C +}; + +/****************************************************************************** + * + * ResAnmLight + * + ******************************************************************************/ +struct ResAnmLightData : ResAnmLightDataTypedef { + enum Flag { + FLAG_LIGHT_TYPE_MASK = (1 << 0) | (1 << 1), + FLAG_LIGHT_ENABLE = (1 << 2), + FLAG_SPECULAR_ENABLE = (1 << 3), + FLAG_COLOR_ENABLE = (1 << 4), + FLAG_ALPHA_ENABLE = (1 << 5), + + FLAG_POS_X_CONST = (1 << 19), + FLAG_POS_Y_CONST = (1 << 20), + FLAG_POS_Z_CONST = (1 << 21), + + FLAG_COLOR_CONST = (1 << 22), + FLAG_ENABLE_CONST = (1 << 23), + + FLAG_AIM_X_CONST = (1 << 24), + FLAG_AIM_Y_CONST = (1 << 25), + FLAG_AIM_Z_CONST = (1 << 26), + + FLAG_CUTOFF_CONST = (1 << 27), + FLAG_REF_DISTANCE_CONST = (1 << 28), + FLAG_REF_BRIGHTNESS_CONST = (1 << 29), + FLAG_SPEC_COLOR_CONST = (1 << 30), + FLAG_SHININESS_CONST = (1 << 31) + }; + + u32 size; // at 0x0 + s32 toResAnmScnData; // at 0x4 + s32 name; // at 0x8 + u32 id; // at 0xC + u32 refNumber; // at 0x10 + u32 specLightObjIdx; // at 0x14 + s32 toResUserData; // at 0x18 + u32 flags; // at 0x1C + ResBoolAnmData enable; // at 0x20 + ResAnmData posX; // at 0x24 + ResAnmData posY; // at 0x28 + ResAnmData posZ; // at 0x2C + ResColorAnmData color; // at 0x30 + ResAnmData aimX; // at 0x34 + ResAnmData aimY; // at 0x38 + ResAnmData aimZ; // at 0x3C + GXDistAttnFn distFunc; // at 0x40 + ResAnmData refDistance; // at 0x44 + ResAnmData refBrightness; // at 0x48 + GXSpotFn spotFunc; // at 0x4C + ResAnmData cutoff; // at 0x50 + ResColorAnmData specColor; // at 0x54 + ResAnmData shininess; // at 0x58 +}; + +class ResAnmLight : public ResCommon, public ResAnmLightDataTypedef { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResAnmLight); + + void GetAnmResult(LightAnmResult *pResult, f32 frame) const; + + u32 GetID() const { + return ref().id; + } + + u32 GetRefNumber() const { + return ref().refNumber; + } + + u32 GetSpecularLightIdx() const { + return ref().specLightObjIdx; + } + + bool HasSpecularLight() const { + return ref().flags & ResAnmLightData::FLAG_SPECULAR_ENABLE; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resanmscn.h b/include/nw4r/g3d/res/g3d_resanmscn.h new file mode 100644 index 00000000..a7663547 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resanmscn.h @@ -0,0 +1,99 @@ +#ifndef NW4R_G3D_RES_RES_ANM_SCN_H +#define NW4R_G3D_RES_RES_ANM_SCN_H + +/** NOTICE: Revision change from 4->5. Structures, Enums, and/or Functions may have changed and not yet done so + * (Zeldex72, Feb 1, 2025) */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace nw4r { +namespace g3d { + +struct ResAnmScnInfoData { + u16 numFrame; // at 0x0 + u16 numSpecularLight; // at 0x2 + AnmPolicy policy; // at 0x4 + u16 numResLightSetData; // at 0x8 + u16 numResAnmAmbLightData; // at 0xA + u16 numResAnmLightData; // at 0xC + u16 numResAnmFogData; // at 0xE + u16 numResAnmCameraData; // at 0x10 + u8 PADDING_0x12[0x14 - 0x12]; // at 0x12 +}; + +struct ResAnmScnData { + ResBlockHeaderData header; // at 0x0 + u32 revision; // at 0x8 + s32 toResFileData; // at 0xC + s32 toScnTopLevelDic; // at 0x10 + s32 toResLightSetDataArray; // at 0x14 + s32 toResAnmAmbLightDataArray; // at 0x18 + s32 toResAnmLightDataArray; // at 0x1C + s32 toResAnmFogDataArray; // at 0x20 + s32 toResAnmCameraDataArray; // at 0x24 + s32 toResUserData; // at 0x28 + s32 name; // at 0x2C + s32 original_path; // at 0x30 + ResAnmScnInfoData info; // at 0x34 +}; + +class ResAnmScn : public ResCommon { +public: + static const u32 SIGNATURE = 'SCN0'; + static const int REVISION = 5; + +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResAnmScn); + + bool Bind(const ResAnmScn scene); + + bool Bind() { + return Bind(*this); + } + + u32 GetRevision() const { + return ref().revision; + } + + bool CheckRevision() const { + return GetRevision() == REVISION; + } + + bool HasResAnmAmbLight() const; + bool HasResAnmLight() const; + + ResLightSet GetResLightSet(int idx) const; + ResLightSet GetResLightSet(u32 idx) const; + u32 GetResLightSetNumEntries() const; + + ResAnmAmbLight GetResAnmAmbLight(const ResName name) const; + ResAnmAmbLight GetResAnmAmbLight(int idx) const; + ResAnmAmbLight GetResAnmAmbLight(u32 idx) const; + + ResAnmLight GetResAnmLight(const ResName name) const; + ResAnmLight GetResAnmLight(int idx) const; + ResAnmLight GetResAnmLight(u32 idx) const; + + ResLightSet GetResLightSetByRefNumber(u32 refNumber) const; + ResAnmAmbLight GetResAnmAmbLightByRefNumber(u32 refNumber) const; + ResAnmLight GetResAnmLightByRefNumber(u32 refNumber) const; + ResAnmFog GetResAnmFogByRefNumber(u32 refNumber) const; + ResAnmCamera GetResAnmCameraByRefNumber(u32 refNumber) const; + + u16 GetResAnmFogMaxRefNumber() const { + return ref().info.numResAnmFogData; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resanmshp.h b/include/nw4r/g3d/res/g3d_resanmshp.h new file mode 100644 index 00000000..627835e0 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resanmshp.h @@ -0,0 +1,150 @@ +#ifndef NW4R_G3D_RES_RES_ANM_SHP_H +#define NW4R_G3D_RES_RES_ANM_SHP_H + +/** NOTICE: Revision change from 3->4. Structures, Enums, and/or Functions may have changed and not yet done so + * (Zeldex72, Feb 1, 2025) */ + +#include + +#include +#include +#include +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * BlendVtx + * + ******************************************************************************/ +struct ShpAnmVtxSet { + ResVtxPos resVtxPos; // at 0x0 + ResVtxNrm resVtxNrm; // at 0x4 + ResVtxClr resVtxClr; // at 0x8 + + friend bool operator==(const ShpAnmVtxSet &rLhs, const ShpAnmVtxSet &rRhs); +}; + +inline bool operator==(const ShpAnmVtxSet &rLhs, const ShpAnmVtxSet &rRhs) { + return rLhs.resVtxPos == rRhs.resVtxPos && rLhs.resVtxNrm == rRhs.resVtxNrm && rLhs.resVtxClr == rRhs.resVtxClr; +} + +struct BlendVtx { + ShpAnmVtxSet vtxSet; // at 0x0 + f32 weight; // at 0xC +}; + +/****************************************************************************** + * + * ShpAnmResult + * + ******************************************************************************/ +struct ShpAnmResult { + enum Flag { + FLAG_ANM_EXISTS = (1 << 0), + FLAG_ANM_VTXPOS = (1 << 1), + FLAG_ANM_VTXNRM = (1 << 2), + FLAG_ANM_VTXCLR = (1 << 3), + }; + + static const int MAX_KEY_SHAPE = 32; + + u32 flags; // at 0x0 + u32 numKeyShape; // at 0x4 + ShpAnmVtxSet baseShapeVtxSet; // at 0x8 + f32 baseShapeWeight; // at 0x14 + BlendVtx keyShape[MAX_KEY_SHAPE]; // at 0x18 +}; + +/****************************************************************************** + * + * ResAnmShp + * + ******************************************************************************/ +struct ResAnmShpAnmData { + enum Flag { + FLAG_ANM_EXISTS = (1 << 0), + FLAG_ANM_VTXPOS = (1 << 1), + FLAG_ANM_VTXNRM = (1 << 2), + FLAG_ANM_VTXCLR = (1 << 3), + }; + + u32 flags; // at 0x0 + s32 name; // at 0x4 + u16 baseShapeVtxIdx; // at 0x8 + u16 numKeyShape; // at 0xA + u32 constFlags; // at 0xC + s32 toAnmIdxToVtxIdxTable; // at 0x10 + ResAnmData anms[1]; // at 0x14 +}; + +struct ResAnmShpInfoData { + u16 numFrame; // at 0x0 + u16 numVtxName; // at 0x2 + AnmPolicy policy; // at 0x4 +}; + +struct ResAnmShpData { + ResBlockHeaderData header; // at 0x0 + u32 revision; // at 0x8 + s32 toResFileData; // at 0xC + s32 toShpDataDic; // at 0x10 + s32 toVtxNameArray; // at 0x14 + s32 toResUserData; // at 0x18 + s32 name; // at 0x1C + s32 original_path; // at 0x20 + ResAnmShpInfoData info; // at 0x24 +}; + +class ResAnmShp : public ResCommon { +public: + static const u32 SIGNATURE = 'SHP0'; + static const int REVISION = 4; + +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResAnmShp); + + u32 GetRevision() const { + return ref().revision; + } + + bool CheckRevision() const { + return GetRevision() == REVISION; + } + + void GetAnmResult(ShpAnmResult *pResult, u32 idx, f32 frame, const ShpAnmVtxSet *pShapeArray) const; + + const ResAnmShpAnmData *GetShapeAnm(int idx) const { + return static_cast(ofs_to_obj(ref().toShpDataDic)[idx]); + } + const ResAnmShpAnmData *GetShapeAnm(u32 idx) const { + return static_cast(ofs_to_obj(ref().toShpDataDic)[idx]); + } + + u32 GetShapeAnmNumEntries() const { + return ofs_to_obj(ref().toShpDataDic).GetNumData(); + } + + const s32 *GetVtxNameArray() const { + return ofs_to_ptr(ref().toVtxNameArray); + } + + int GetNumFrame() const { + return ref().info.numFrame; + } + + int GetNumVtxNames() const { + return ref().info.numVtxName; + } + + AnmPolicy GetAnmPolicy() const { + return ref().info.policy; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resanmtexpat.h b/include/nw4r/g3d/res/g3d_resanmtexpat.h new file mode 100644 index 00000000..bd1c651d --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resanmtexpat.h @@ -0,0 +1,146 @@ +#ifndef NW4R_G3D_RES_RES_ANM_TEX_PAT_H +#define NW4R_G3D_RES_RES_ANM_TEX_PAT_H + +/** NOTICE: Revision change from 3->4. Structures, Enums, and/or Functions may have changed and not yet done so + * (Zeldex72, Feb 1, 2025) */ + +#include + +#include +#include +#include +#include +#include +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * TexPatAnmResult + * + ******************************************************************************/ +struct TexPatAnmResult { + static const int NUM_OF_ANMS = 8; + + u8 bTexExist; // at 0x0 + u8 bPlttExist; // at 0x1 + u8 PADDING_0x2[0x4 - 0x2]; // at 0x2 + ResTex tex[NUM_OF_ANMS]; // at 0x4 + ResPltt pltt[NUM_OF_ANMS]; // at 0x24 +}; + +/****************************************************************************** + * + * ResAnmTexPat + * + ******************************************************************************/ +struct ResAnmTexPatFrmData { + f32 frame; // at 0x0 + u16 texIndex; // at 0x4 + u16 plttIndex; // at 0x6 +}; + +struct ResAnmTexPatAnmData { + u16 numFrameValues; // at 0x0 + u8 PADDING_0x2[0x4 - 0x2]; // at 0x2 + f32 invKeyFrameRange; // at 0x4 + ResAnmTexPatFrmData frameValues[1]; // at 0x8 +}; + +struct ResAnmTexPatMatData { + enum Flag { + FLAG_ANM_EXISTS = (1 << 0), + FLAG_ANM_CONST = (1 << 1), + FLAG_ANM_TEX = (1 << 2), + FLAG_ANM_PLTT = (1 << 3), + + // Four bits in 'flags' for each animation + NUM_OF_FLAGS = 4 + }; + + union AnmData { + s32 toResAnmTexPatAnmData; // at 0x0 + + struct { + u16 texIndex; // at 0x0 + u16 plttIndex; // at 0x2 + } constValue; + }; + + s32 name; // at 0x0 + u32 flags; // at 0x4 + AnmData anms[1]; // at 0x8 +}; + +struct ResAnmTexPatInfoData { + u16 numFrame; // at 0x0 + u16 numMaterial; // at 0x2 + u16 numTexture; // at 0x4 + u16 numPalette; // at 0x6 + AnmPolicy policy; // at 0x8 +}; + +struct ResAnmTexPatData { + ResBlockHeaderData header; // at 0x0 + u32 revision; // at 0x8 + s32 toResFileData; // at 0xC + s32 toTexPatDataDic; // at 0x10 + s32 toTexNameArray; // at 0x14 + s32 toPlttNameArray; // at 0x18 + s32 toResTexArray; // at 0x1C + s32 toResPlttArray; // at 0x20 + s32 toResUserData; // at 0x24 + s32 name; // at 0x28 + s32 original_path; // at 0x2C + ResAnmTexPatInfoData info; // at 0x30 +}; + +class ResAnmTexPat : public ResCommon { +public: + static const u32 SIGNATURE = 'PAT0'; + static const int REVISION = 4; + +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResAnmTexPat); + + bool Bind(const ResFile file); + void Release(); + + ResFile GetParent() const; + + u32 GetRevision() const { + return ref().revision; + } + + bool CheckRevision() const { + return GetRevision() == REVISION; + } + + void GetAnmResult(TexPatAnmResult *pResult, u32 idx, f32 frame) const; + + const ResAnmTexPatMatData *GetMatAnm(int idx) const { + return static_cast(ofs_to_obj(ref().toTexPatDataDic)[idx]); + } + const ResAnmTexPatMatData *GetMatAnm(u32 idx) const { + return static_cast(ofs_to_obj(ref().toTexPatDataDic)[idx]); + } + + int GetNumFrame() const { + return ref().info.numFrame; + } + + int GetNumMaterial() const { + return ref().info.numMaterial; + } + + AnmPolicy GetAnmPolicy() const { + return ref().info.policy; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resanmtexsrt.h b/include/nw4r/g3d/res/g3d_resanmtexsrt.h new file mode 100644 index 00000000..0a4f093a --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resanmtexsrt.h @@ -0,0 +1,172 @@ +#ifndef NW4R_G3D_RES_RES_ANM_TEX_SRT_H +#define NW4R_G3D_RES_RES_ANM_TEX_SRT_H + +/** NOTICE: Revision change from 4->5. Structures, Enums, and/or Functions may have changed and not yet done so + * (Zeldex72, Feb 1, 2025) */ + +#include + +#include +#include +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * Common types + * + ******************************************************************************/ +struct ResAnmTexSrtDataTypedef { + static const int NUM_OF_MAT_TEX_MTX = 8; + static const int NUM_OF_IND_TEX_MTX = 3; + static const int NUM_OF_TEX_MTX = NUM_OF_MAT_TEX_MTX + NUM_OF_IND_TEX_MTX; +}; + +struct TexSrtTypedef { + enum TexMatrixMode { + TEXMATRIXMODE_MAYA, + TEXMATRIXMODE_XSI, + TEXMATRIXMODE_3DSMAX + }; +}; + +/****************************************************************************** + * + * TexSrtAnmResult + * + ******************************************************************************/ +struct TexSrt : TexSrtTypedef { + enum Flag { + FLAG_ANM_EXISTS = (1 << 0), + FLAG_SCALE_ONE = (1 << 1), + FLAG_ROT_ZERO = (1 << 2), + FLAG_TRANS_ZERO = (1 << 3), + + FLAGSET_IDENTITY = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3), + NUM_OF_FLAGS = 4 + }; + + f32 Su; // at 0x0 + f32 Sv; // at 0x4 + f32 R; // at 0x8 + f32 Tu; // at 0xc + f32 Tv; // at 0x10 +}; + +struct TexSrtAnmResult : ResAnmTexSrtDataTypedef, TexSrtTypedef { + enum Flag { + FLAG_ANM_EXISTS = (1 << 0), + FLAG_SCALE_ONE = (1 << 1), + FLAG_ROT_ZERO = (1 << 2), + FLAG_TRANS_ZERO = (1 << 3), + + // Four bits in 'flags' for each animation + NUM_OF_FLAGS = 4 + }; + + u32 flags; // at 0x0 + u32 indFlags; // at 0x4 + TexMatrixMode texMtxMode; // at 0x8 + TexSrt srt[NUM_OF_TEX_MTX]; // at 0xC +}; + +/****************************************************************************** + * + * ResAnmTexSrt + * + ******************************************************************************/ +struct ResAnmTexSrtTexData { + enum Flag { + FLAG_ANM_EXISTS = (1 << 0), + FLAG_SCALE_ONE = (1 << 1), + FLAG_ROT_ZERO = (1 << 2), + FLAG_TRANS_ZERO = (1 << 3), + + FLAG_SCALE_UNIFORM = (1 << 4), + FLAG_SCALE_U_CONST = (1 << 5), + FLAG_SCALE_V_CONST = (1 << 6), + + FLAG_ROT_CONST = (1 << 7), + FLAG_TRANS_U_CONST = (1 << 8), + FLAG_TRANS_V_CONST = (1 << 9), + }; + + u32 flags; // at 0x0 + ResAnmData anms[1]; // at 0x4 +}; + +struct ResAnmTexSrtMatData : ResAnmTexSrtDataTypedef { + enum Flag { + FLAG_ANM_EXISTS = (1 << 0), + + NUM_OF_FLAGS = 1 + }; + + s32 name; // at 0x0 + u32 flags; // at 0x4 + u32 indFlags; // at 0x8 + s32 toResAnmTexSrtTexData[1]; // at 0xC +}; + +struct ResAnmTexSrtInfoData : TexSrtTypedef { + u16 numFrame; // at 0x0 + u16 numMaterial; // at 0x2 + TexMatrixMode texMtxMode; // at 0x4 + AnmPolicy policy; // at 0x8 +}; + +struct ResAnmTexSrtData { + ResBlockHeaderData header; // at 0x0 + u32 revision; // at 0x8 + s32 toResFileData; // at 0xC + s32 toTexSrtDataDic; // at 0x10 + s32 toResUserData; // at 0x14 + s32 name; // at 0x18 + s32 original_path; // at 0x1C + ResAnmTexSrtInfoData info; // at 0x20 +}; + +class ResAnmTexSrt : public ResCommon { +public: + static const u32 SIGNATURE = 'SRT0'; + static const int REVISION = 5; + +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResAnmTexSrt); + + u32 GetRevision() const { + return ref().revision; + } + + bool CheckRevision() const { + return GetRevision() == REVISION; + } + + void GetAnmResult(TexSrtAnmResult *pResult, u32 idx, f32 frame) const; + + const ResAnmTexSrtMatData *GetMatAnm(int idx) const { + return static_cast(ofs_to_obj(ref().toTexSrtDataDic)[idx]); + } + const ResAnmTexSrtMatData *GetMatAnm(u32 idx) const { + return static_cast(ofs_to_obj(ref().toTexSrtDataDic)[idx]); + } + + int GetNumFrame() const { + return ref().info.numFrame; + } + + int GetNumMaterial() const { + return ref().info.numMaterial; + } + + AnmPolicy GetAnmPolicy() const { + return ref().info.policy; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resanmvis.h b/include/nw4r/g3d/res/g3d_resanmvis.h new file mode 100644 index 00000000..fc32bdb0 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resanmvis.h @@ -0,0 +1,85 @@ +#ifndef NW4R_G3D_RES_RES_ANM_VIS_H +#define NW4R_G3D_RES_RES_ANM_VIS_H + +/** NOTICE: Revision change from 3->4. Structures, Enums, and/or Functions may have changed and not yet done so + * (Zeldex72, Feb 1, 2025) */ + +#include + +#include +#include +#include + +namespace nw4r { +namespace g3d { + +struct ResAnmVisAnmData { + enum Flag { + FLAG_ENABLE = (1 << 0), + FLAG_CONST = (1 << 1) + }; + + s32 name; // at 0x0 + u32 flags; // at 0x4 + ResBoolAnmFramesData visibility; // at 0x8 +}; + +struct ResAnmVisInfoData { + u16 numFrame; // at 0x0 + u16 numNode; // at 0x2 + AnmPolicy policy; // at 0x4 +}; + +struct ResAnmVisData { + ResBlockHeaderData header; // at 0x0 + u32 revision; // at 0x8 + s32 toResFileData; // at 0xC + s32 toVisDataDic; // at 0x10 + s32 toResUserData; // at 0x14 + s32 name; // at 0x18 + s32 original_path; // at 0x1C + ResAnmVisInfoData info; // at 0x20 +}; + +class ResAnmVis : public ResCommon { +public: + static const u32 SIGNATURE = 'VIS0'; + static const int REVISION = 3; + +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResAnmVis); + + u32 GetRevision() const { + return ref().revision; + } + + bool CheckRevision() const { + return GetRevision() == REVISION; + } + + bool GetAnmResult(u32 idx, f32 frame) const; + + const ResAnmVisAnmData *GetNodeAnm(int idx) const { + return static_cast(ofs_to_obj(ref().toVisDataDic)[idx]); + } + const ResAnmVisAnmData *GetNodeAnm(u32 idx) const { + return static_cast(ofs_to_obj(ref().toVisDataDic)[idx]); + } + + int GetNumFrame() const { + return ref().info.numFrame; + } + + int GetNumNode() const { + return ref().info.numNode; + } + + AnmPolicy GetAnmPolicy() const { + return ref().info.policy; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_rescommon.h b/include/nw4r/g3d/res/g3d_rescommon.h new file mode 100644 index 00000000..19513c3e --- /dev/null +++ b/include/nw4r/g3d/res/g3d_rescommon.h @@ -0,0 +1,376 @@ +#ifndef NW4R_G3D_RESCOMMON_H +#define NW4R_G3D_RESCOMMON_H +#include "common.h" + +#include +/****************************************************************************** + * + * Macros + * + ******************************************************************************/ + +/** + * Define ResName pascal string for file resource groups. + */ +#define NW4R_G3D_RESFILE_NAME_DEF(VAR, STR) \ + nw4r::g3d::ResNameData27 ResNameData_##VAR ALIGN_DECL(32) = {sizeof(STR) - 1, STR} + +/** + * Similar to "ofs_to_obj" but accounting for the additional -4 offset. + * Debug builds show this behavior was not achieved through a function. + */ +#define NW4R_G3D_OFS_TO_RESNAME(BASE, OFS) nw4r::g3d::ResName((char *)(BASE) + (OFS) - sizeof(u32)) + +/** + * Define common functions for resource classes. + * @note Hides ResCommon::ref, why did they do this??? + */ +#define NW4R_G3D_RESOURCE_FUNC_DEF(T) NW4R_G3D_RESOURCE_FUNC_DEF_IMPL(T, T##Data) +#define NW4R_G3D_RESOURCE_FUNC_DEF_EX(TCLS, TDATA) NW4R_G3D_RESOURCE_FUNC_DEF_IMPL(TCLS, TDATA) + +#define NW4R_G3D_RESOURCE_FUNC_DEF_IMPL(TCLS, TDATA) \ + explicit TCLS(void *pData = NULL) : nw4r::g3d::ResCommon(pData) {} \ + \ + TDATA &ref() { \ + return *ptr(); \ + } \ + \ + const TDATA &ref() const { \ + return *ptr(); \ + } \ + \ + bool operator==(const TCLS &rOther) const { \ + return ptr() == rOther.ptr(); \ + } \ + \ + bool operator!=(const TCLS &rOther) const { \ + return ptr() != rOther.ptr(); \ + } + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * Common resource wrapper + * + ******************************************************************************/ +template +class ResCommon { +public: + explicit ResCommon(void *pData) : mpData(static_cast(pData)) {} + + explicit ResCommon(const void *pData) : mpData(static_cast(pData)) {} + + bool IsValid() const { + return mpData != NULL; + } + + T *ptr() { + return mpData; + } + const T *ptr() const { + return mpData; + } + + T &ref() { + return *mpData; + } + const T &ref() const { + return *mpData; + } + + template + PTR_T *ofs_to_ptr_raw(s32 ofs) { + return reinterpret_cast((char *)mpData + ofs); + } + template + const PTR_T *ofs_to_ptr_raw(s32 ofs) const { + return reinterpret_cast((char *)mpData + ofs); + } + + template + PTR_T *ofs_to_ptr(s32 ofs) { + u8 *pPtr = reinterpret_cast(mpData); + + if (ofs != 0) { + return reinterpret_cast(pPtr + ofs); + } + + return NULL; + } + template + const PTR_T *ofs_to_ptr(s32 ofs) const { + const u8 *pPtr = reinterpret_cast(mpData); + + if (ofs != 0) { + return reinterpret_cast(pPtr + ofs); + } + + return NULL; + } + + template + OBJ_T ofs_to_obj(s32 ofs) { + u8 *pPtr = reinterpret_cast(mpData); + + if (ofs != 0) { + return OBJ_T(pPtr + ofs); + } + + return OBJ_T(NULL); + } + template + const OBJ_T ofs_to_obj(s32 ofs) const { + const u8 *pPtr = reinterpret_cast(mpData); + + if (ofs != 0) { + return OBJ_T(const_cast(pPtr + ofs)); + } + + return OBJ_T(NULL); + } + +private: + T *mpData; +}; + +/** + * Header for resource data structures. + */ +struct ResBlockHeaderData { + char kind[4]; // at 0x0 + u32 size; // at 0x4 +}; + +/** + * Name for file resource groups. + */ +struct ResNameData27 { + u32 len; // at 0x0 + char str[32 - sizeof(u32)]; // at 0x4 +}; + +/****************************************************************************** + * + * Named resource + * + ******************************************************************************/ +struct ResNameData { + u32 len; // at 0x0 + char str[4]; // at 0x4 +}; + +class ResName : public ResCommon { +public: + explicit ResName(const void *pData) : ResCommon(pData) {} + + u32 GetLength() const { + return ref().len; + } + + const char *GetName() const { + return ref().str; + } + + bool operator==(const ResName rhs) const; +}; + +/****************************************************************************** + * + * Generic display list + * + ******************************************************************************/ +struct ResTagDLData { + u32 bufSize; // at 0x0 + u32 cmdSize; // at 0x4 + s32 toDL; // at 0x8 +}; + +class ResTagDL : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResTagDL); + + u32 GetBufSize() const { + return ref().bufSize; + } + + u32 GetCmdSize() const { + return ref().cmdSize; + } + + u8 *GetDL() { + return const_cast(ofs_to_ptr(ref().toDL)); + } + const u8 *GetDL() const { + return ofs_to_ptr(ref().toDL); + } +}; + +/****************************************************************************** + * + * Model bytecode + * + ******************************************************************************/ +namespace ResByteCodeData { + +enum OpCode { + NOOP, // No operation + END, // End of bytecode + CALC, // Calculate matrix + WEIGHT, // Apply weighting + DRAW, // Draw polygon + EVPMTX, // Envelope matrix + MTXDUP // Duplicate matrix +}; + +// CALC opcode layout +struct CalcParams { + u8 opcode; // at 0x0 + u8 nodeIdHi; // at 0x1 + u8 nodeIdLo; // at 0x2 + u8 parentMtxIdHi; // at 0x1 + u8 parentMtxIdLo; // at 0x2 +}; + +// WEIGHT opcode layout +struct WeightParams { + u8 opcode; // at 0x0 + u8 tgtIdHi; // at 0x1 + u8 tgtIdLo; // at 0x2 + u8 numBlendMtx; // at 0x3 +}; +// WEIGHT opcode layout - weighting entry +struct WeightEntry { + u8 mtxIdHi; // at 0x0 + u8 mtxIdLo; // at 0x1 + u8 fWeight0; // at 0x2 + u8 fWeight1; // at 0x3 + u8 fWeight2; // at 0x4 + u8 fWeight3; // at 0x5 +}; + +// DRAW opcode layout +struct DrawParams { + u8 opcode; // at 0x0 + u8 matIdHi; // at 0x3 + u8 matIdLo; // at 0x4 + u8 shpIdHi; // at 0x1 + u8 shpIdLo; // at 0x2 + u8 nodeIdHi; // at 0x5 + u8 nodeIdLo; // at 0x6 + u8 priority; // at 0x7 +}; + +// EVPMTX opcode layout +struct EvpMtxParams { + u8 opcode; // at 0x0 + u8 mtxIdHi; // at 0x1 + u8 mtxIdLo; // at 0x2 + u8 nodeIdHi; // at 0x1 + u8 nodeIdLo; // at 0x2 +}; + +// MTXDUP opcode layout +struct MtxDupParams { + u8 opcode; // at 0x0 + u8 toMtxIdHi; // at 0x1 + u8 toMtxIdLo; // at 0x2 + u8 fromMtxIdHi; // at 0x1 + u8 fromMtxIdLo; // at 0x2 +}; + +} // namespace ResByteCodeData + +namespace detail { +typedef u8 CPCmd[6]; +typedef u8 BPCmd[5]; + +/****************************************************************************** + * + * Primitive read/write + * + ******************************************************************************/ +inline u8 ResRead_u8(const u8 *pPtr) { + return *pPtr; +} + +inline u32 ResRead_u32(const u8 *pPtr) { + u32 value = ResRead_u8(pPtr++) << 24; + value |= ResRead_u8(pPtr++) << 16; + value |= ResRead_u8(pPtr++) << 8; + value |= ResRead_u8(pPtr++) << 0; + return value; +} + +inline void ResWrite_u8(u8 *pPtr, u8 data) { + *pPtr = data; +} + +inline void ResWrite_u16(u8 *pPtr, u16 data) { + ResWrite_u8(pPtr++, data >> 8); + ResWrite_u8(pPtr++, data >> 0); +} + +inline void ResWrite_u32(u8 *pPtr, u32 data) { + ResWrite_u8(pPtr++, data >> 24); + ResWrite_u8(pPtr++, data >> 16); + ResWrite_u8(pPtr++, data >> 8); + ResWrite_u8(pPtr++, data >> 0); +} + +/****************************************************************************** + * + * GX Blitting Processor (BP) + * + ******************************************************************************/ +inline void ResReadBPCmd(const u8 *pPtr, u32 *pOut) { + // Skip over FIFO command byte + *pOut = ResRead_u32(pPtr + 1); +} + +void ResWriteBPCmd(u8 *pPtr, u32 reg); +void ResWriteBPCmd(u8 *pPtr, u32 reg, u32 mask); +void ResWriteSSMask(u8 *pPtr, u32 value); + +/****************************************************************************** + * + * GX Command Processor (CP) + * + ******************************************************************************/ +inline void ResReadCPCmd(const u8 *pPtr, u32 *pOut) { + // Skip over FIFO command byte + addr byte + *pOut = ResRead_u32(pPtr + 2); +} + +void ResWriteCPCmd(u8 *pPtr, u8 addr, u32 value); + +/****************************************************************************** + * + * GX Transform Unit (XF) + * + ******************************************************************************/ +inline void ResReadXFCmd(const u8 *pPtr, u32 *pOut) { + // Skip over FIFO command byte + size short + addr short + *pOut = ResRead_u32(pPtr + 5); +} + +void ResWriteXFCmd(u8 *pPtr, u16 addr, u32 value); + +/****************************************************************************** + * + * Utility functions + * + ******************************************************************************/ +inline GXColor GetRGBA(u8 r, u8 g, u8 b, u8 a) { + return (GXColor){r, g, b, a}; +} +inline GXColorS10 GetRGBAS10(s16 r, s16 g, s16 b, s16 a) { + return (GXColorS10){r, g, b, a}; +} + +} // namespace detail +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resdict.h b/include/nw4r/g3d/res/g3d_resdict.h new file mode 100644 index 00000000..cb757e47 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resdict.h @@ -0,0 +1,60 @@ +#ifndef NW4R_G3D_RES_RES_DICT_H +#define NW4R_G3D_RES_RES_DICT_H +#include + +#include + +namespace nw4r { +namespace g3d { + +struct ResDicNodeData { + u16 ref; // at 0x0 + u16 flag; // at 0x2 + u16 idxLeft; // at 0x4 + u16 idxRight; // at 0x6 + s32 ofsString; // at 0x8 + s32 ofsData; // at 0xC +}; + +struct ResDicData { + u32 size; // at 0x0 + u32 numData; // at 0x4 + ResDicNodeData data[1]; // at 0x8 +}; + +class ResDic : public ResCommon { +public: + static const s32 NOT_FOUND = -1; + +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResDic); + + void *operator[](const char *pName) const; + void *operator[](const ResName name) const; + void *operator[](int idx) const { + if (IsValid()) { + return const_cast(ofs_to_ptr(ref().data[idx + 1].ofsData)); + } + + return NULL; + } + + s32 GetIndex(const ResName name) const; + + u32 GetNumData() const { + if (IsValid()) { + return ptr()->numData; + } + + return 0; + } + +private: + ResDicNodeData *Get(const ResName name) const; + ResDicNodeData *Get(const char *pName, u32 len) const; +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resfile.h b/include/nw4r/g3d/res/g3d_resfile.h new file mode 100644 index 00000000..6426f74b --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resfile.h @@ -0,0 +1,104 @@ +#ifndef NW4R_G3D_RES_RES_FILE_H +#define NW4R_G3D_RES_RES_FILE_H +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace nw4r { +namespace g3d { + +struct ResTopLevelDictData { + ut::BinaryBlockHeader header; // at 0x0 + ResDicData topLevel; // at 0x8 +}; + +struct ResFileData { + ut::BinaryFileHeader fileHeader; // at 0x0 + ResTopLevelDictData dict; // at 0x10 +}; + +class ResFile : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResFile); + + void Init(); + void Terminate(); + bool CheckRevision() const; + + bool Bind(const ResFile file); + void Release(); + + bool Bind() { + return Bind(*this); + } + + ResMdl GetResMdl(const char *pName) const; + ResMdl GetResMdl(int idx) const; + ResMdl GetResMdl(u32 idx) const; + + ResPltt GetResPltt(const char *pName) const; + ResPltt GetResPltt(const ResName name) const; + ResPltt GetResPltt(int idx) const; + ResPltt GetResPltt(u32 idx) const; + + ResTex GetResTex(const char *pName) const; + ResTex GetResTex(const ResName name) const; + ResTex GetResTex(int idx) const; + ResTex GetResTex(u32 idx) const; + + ResAnmChr GetResAnmChr(const char *pName) const; + ResAnmChr GetResAnmChr(int idx) const; + ResAnmChr GetResAnmChr(u32 idx) const; + + ResAnmVis GetResAnmVis(const char *pName) const; + ResAnmVis GetResAnmVis(int idx) const; + ResAnmVis GetResAnmVis(u32 idx) const; + + ResAnmClr GetResAnmClr(const char *pName) const; + ResAnmClr GetResAnmClr(int idx) const; + ResAnmClr GetResAnmClr(u32 idx) const; + + ResAnmTexPat GetResAnmTexPat(const char *pName) const; + ResAnmTexPat GetResAnmTexPat(int idx) const; + ResAnmTexPat GetResAnmTexPat(u32 idx) const; + + ResAnmTexSrt GetResAnmTexSrt(const char *pName) const; + ResAnmTexSrt GetResAnmTexSrt(int idx) const; + ResAnmTexSrt GetResAnmTexSrt(u32 idx) const; + + ResAnmShp GetResAnmShp(const char *pName) const; + ResAnmShp GetResAnmShp(int idx) const; + ResAnmShp GetResAnmShp(u32 idx) const; + + ResAnmScn GetResAnmScn(const char *pName) const; + ResAnmScn GetResAnmScn(int idx) const; + ResAnmScn GetResAnmScn(u32 idx) const; + + u32 GetResMdlNumEntries() const; + u32 GetResPlttNumEntries() const; + u32 GetResTexNumEntries() const; + u32 GetResAnmChrNumEntries() const; + u32 GetResAnmVisNumEntries() const; + u32 GetResAnmClrNumEntries() const; + u32 GetResAnmTexPatNumEntries() const; + u32 GetResAnmTexSrtNumEntries() const; + u32 GetResAnmShpNumEntries() const; + u32 GetResAnmScnNumEntries() const; +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_reslightset.h b/include/nw4r/g3d/res/g3d_reslightset.h new file mode 100644 index 00000000..6f467811 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_reslightset.h @@ -0,0 +1,71 @@ +#ifndef NW4R_G3D_RES_RES_LIGHT_SET_H +#define NW4R_G3D_RES_RES_LIGHT_SET_H +#include + +#include +// #include +#include + +namespace nw4r { +namespace g3d { + +struct ResLightSetData { + static const u32 INVALID_ID = 0xFFFF; + + u32 size; // at 0x0 + s32 toResAnmScnData; // at 0x4 + s32 name; // at 0x8 + u32 id; // at 0xC + u32 refNumber; // at 0x10 + s32 ambLightName; // at 0x14 + u16 ambLightId; // at 0x18 + u8 numLight; // at 0x1A + u8 PADDING_0x1B[0x1C - 0x1B]; // at 0x1B + s32 lightNames[G3DState::NUM_LIGHT_IN_LIGHT_SET]; // at 0x1C + u16 lightId[G3DState::NUM_LIGHT_IN_LIGHT_SET]; // at 0x3C +}; + +class ResLightSet : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResLightSet); + + bool Bind(const ResAnmScn scene); + + bool HasAmbLight() const { + return ref().ambLightName != 0; + } + + ResName GetAmbLightResName() const { + const ResLightSetData &r = ref(); + + if (r.ambLightName != 0) { + return NW4R_G3D_OFS_TO_RESNAME(&r, r.ambLightName); + } + + return ResName(NULL); + } + + u32 GetAmbLightID() const { + return ref().ambLightId; + } + + u32 GetNumLight() const { + return ref().numLight; + } + + bool IsAmbLightBound() const { + return !HasAmbLight() || GetAmbLightID() != ResLightSetData::INVALID_ID; + } + + ResName GetLightResName(u32 idx) const { + const ResLightSetData &r = ref(); + + const s32 *pNames = r.lightNames; + return NW4R_G3D_OFS_TO_RESNAME(pNames, pNames[idx]); + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resmat.h b/include/nw4r/g3d/res/g3d_resmat.h new file mode 100644 index 00000000..dba3bf4e --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resmat.h @@ -0,0 +1,608 @@ +#ifndef NW4R_G3D_RES_RES_MAT_H +#define NW4R_G3D_RES_RES_MAT_H +#include + +#include +#include +#include +#include +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * ResGenMode + * + ******************************************************************************/ +struct ResGenModeData { + u8 nTexGens; // at 0x0 + u8 nChans; // at 0x1 + u8 nTevs; // at 0x2 + u8 nInds; // at 0x3 + GXCullMode cullMode; // at 0x4 +}; + +class ResGenMode : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResGenMode); + + ResGenMode CopyTo(void *pDst) const; + + void GXSetNumTexGens(u8 num); + void GXSetNumChans(u8 num); + void GXSetNumTevStages(u8 num); + void GXSetNumIndStages(u8 num); + void GXSetCullMode(GXCullMode mode); + + u8 GXGetNumTexGens() const { + return IsValid() ? ptr()->nTexGens : 0; + } + + u8 GXGetNumChans() const { + return IsValid() ? ptr()->nChans : 0; + } + + u8 GXGetNumTevStages() const { + return IsValid() ? ptr()->nTevs : 0; + } + + u8 GXGetNumIndStages() const { + return IsValid() ? ptr()->nInds : 0; + } + + GXCullMode GXGetCullMode() const { + return IsValid() ? ptr()->cullMode : GX_CULL_ALL; + } + + void EndEdit() {} +}; + +/****************************************************************************** + * + * ResMatMisc + * + ******************************************************************************/ +struct ResMatMiscData { + enum IndirectMethod { + WARP, + NORMAL_MAP, + NORMAL_MAP_SPECULAR, + FUR, + + _RESERVED0, + _RESERVED1, + + USER0, + USER1, + + NUM_OF_INDIRECT_METHOD, + }; + + GXBool zCompLoc; // at 0x0 + s8 light_set_idx; // at 0x1 + s8 fog_idx; // at 0x2 + u8 PADDING_0x3; // at 0x3 + u8 indirect_method[GX_ITM_2 + 1]; // at 0x4 + s8 normal_map_ref_light[GX_ITM_2 + 1]; // at 0x8 +}; + +class ResMatMisc : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResMatMisc); + + ResMatMisc CopyTo(void *pDst) const; + + GXBool GXGetZCompLoc() const; + int GetLightSetIdx() const; + int GetFogIdx() const; + + void GetIndirectTexMtxCalcMethod(GXIndTexMtxID id, ResMatMiscData::IndirectMethod *pMethod, s8 *pLightRef); + + void EndEdit() {} +}; + +/****************************************************************************** + * + * ResMatTexCoordGen + * + ******************************************************************************/ +struct ResTexCoordGenDL { + union { + struct { + u8 texCoordGen[GX_MAX_TEXCOORD][GX_XF_CMD_SZ * 2]; // at 0x0 + u8 PADDING_0x90[0xA0 - 0x90]; // at 0x90 + } dl; + + u8 data[0xA0]; + }; +}; + +class ResMatTexCoordGen : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF_EX(ResMatTexCoordGen, ResTexCoordGenDL); + + void DCStore(bool sync); + ResMatTexCoordGen CopyTo(void *pDst) const; + + void CallDisplayList(u8 numGens, bool sync) const; + + bool GXGetTexCoordGen2(GXTexCoordID id, GXTexGenType *pFunc, GXTexGenSrc *pParam, GXBool *pNormalize, u32 *pPostMtx) + const; + void GXSetTexCoordGen2(GXTexCoordID id, GXTexGenType func, GXTexGenSrc param, GXBool normalize, u32 postMtx); + + void EndEdit() { + DCStore(false); + } +}; + +/****************************************************************************** + * + * ResTexObj + * + ******************************************************************************/ +struct ResTexObjData { + u32 flagUsedTexMapID; // at 0x0 + GXTexObj texObj[GX_MAX_TEXMAP]; // at 0x4 +}; + +class ResTexObj : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResTexObj); + + ResTexObj CopyTo(void *pDst) const; + + const GXTexObj *GetTexObj(GXTexMapID id) const; + GXTexObj *GetTexObj(GXTexMapID id); + + bool IsValidTexObj(GXTexMapID id) const; + + void Validate(GXTexMapID id); + void Invalidate(GXTexMapID id); + + void EndEdit() {} +}; + +/****************************************************************************** + * + * ResTlutObj + * + ******************************************************************************/ +struct ResTlutObjData { + u32 flagUsedTlutID; // at 0x0 + GXTlutObj tlutObj[GX_TLUT8 - GX_TLUT0]; // at 0x4 +}; + +class ResTlutObj : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResTlutObj); + + ResTlutObj CopyTo(void *pDst) const; + + const GXTlutObj *GetTlut(GXTlut tlut) const; + GXTlutObj *GetTlut(GXTlut tlut); + + bool IsValidTlut(GXTlut tlut) const; + + void Validate(GXTlut tlut); + void Invalidate(GXTlut tlut); + + void EndEdit() {} +}; + +/****************************************************************************** + * + * ResTexSrt + * + ******************************************************************************/ +struct TexMtxEffect : TexSrtTypedef { + enum Flag { + FLAG_IDENT = (1 << 0), + }; + + s8 ref_camera; // at 0x0 + s8 ref_light; // at 0x1 + u8 map_mode; // at 0x2 + u8 misc_flag; // at 0x3 + math::_MTX34 effectMtx; // at 0x4 +}; + +struct ResTexSrtData : TexSrtTypedef { + static const int NUM_OF_TEXTURE = 8; + + u32 flag; // at 0x0 + TexMatrixMode texMtxMode; // at 0x4 + TexSrt texSrt[NUM_OF_TEXTURE]; // at 0x8 + TexMtxEffect effect[NUM_OF_TEXTURE]; // at 0xA8 +}; + +class ResTexSrt : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResTexSrt); + + ResTexSrt CopyTo(void *pDst) const; + + bool GetEffectMtx(u32 id, math::MTX34 *pMtx) const; + bool SetEffectMtx(u32 id, const math::MTX34 *pMtx); + + bool GetMapMode(u32 id, u32 *pMode, int *pCamRef, int *pLightRef) const; + bool SetMapMode(u32 id, u32 mode, int camRef, int lightRef); + + TexSrt::Flag GetTexSrtFlag(u32 id) const { + return static_cast( + (ref().flag >> id * TexSrt::NUM_OF_FLAGS) & + (TexSrt::FLAG_ANM_EXISTS | TexSrt::FLAG_SCALE_ONE | TexSrt::FLAG_ROT_ZERO | TexSrt::FLAG_TRANS_ZERO) + ); + } + + bool IsExist(u32 id) const { + if (IsValid()) { + return ptr()->flag & (1 << id * TexSrt::NUM_OF_FLAGS); + } else { + return false; + } + } + + bool IsIdentity(u32 id) const { + return (((ref().flag >> id * TexSrt::NUM_OF_FLAGS) & TexSrt::FLAGSET_IDENTITY) == TexSrt::FLAGSET_IDENTITY) && + (ref().effect[id].misc_flag & TexMtxEffect::FLAG_IDENT); + } + + TexSrtTypedef::TexMatrixMode GetTexMtxMode() const { + return ref().texMtxMode; + } + + void EndEdit() {} +}; + +/****************************************************************************** + * + * ResMatChan + * + ******************************************************************************/ +struct Chan { + enum Flag { + FLAG_MAT_COLOR_ENABLE = (1 << 0), + FLAG_MAT_ALPHA_ENABLE = (1 << 1), + + FLAG_AMB_COLOR_ENABLE = (1 << 2), + FLAG_AMB_ALPHA_ENABLE = (1 << 3), + + FLAG_CTRL_COLOR_ENABLE = (1 << 4), + FLAG_CTRL_ALPHA_ENABLE = (1 << 5), + }; + + u32 flag; // at 0x0 + GXColor matColor; // at 0x4 + GXColor ambColor; // at 0x8 + u32 paramChanCtrlC; // at 0xC + u32 paramChanCtrlA; // at 0x10 +}; + +struct ResChanData { + Chan chan[2]; // at 0x0 +}; + +class ResMatChan : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF_EX(ResMatChan, ResChanData); + + ResMatChan CopyTo(void *pDst) const; + + bool GXGetChanMatColor(GXChannelID id, GXColor *pColor) const; + void GXSetChanMatColor(GXChannelID id, GXColor color); + + bool GXGetChanAmbColor(GXChannelID id, GXColor *pColor) const; + void GXSetChanAmbColor(GXChannelID id, GXColor color); + + bool GXGetChanCtrl( + GXChannelID id, GXBool *pEnable, GXColorSrc *pAmbSrc, GXColorSrc *pMatSrc, GXLightID *pLightMask, + GXDiffuseFn *pDiffuseFn, GXAttnFn *pAttnFn + ) const; + void GXSetChanCtrl( + GXChannelID id, GXBool enable, GXColorSrc ambSrc, GXColorSrc matSrc, GXLightID lightMask, GXDiffuseFn diffuseFn, + GXAttnFn attnFn + ); + + void EndEdit() {} +}; + +/****************************************************************************** + * + * ResMatPix + * + ******************************************************************************/ +struct ResPixDL { + union { + struct { + u8 alphaCompare[GX_BP_CMD_SZ]; // at 0x0 + u8 zMode[GX_BP_CMD_SZ]; // at 0x5 + u8 blendMode[GX_BP_CMD_SZ * 2]; // at 0xA + u8 setDstAlpha[GX_BP_CMD_SZ]; // at 0x14 + u8 PADDING_0x19[32 - 0x19]; // at 0x19 + } dl; + + u8 data[32]; // at 0x0 + }; +}; + +class ResMatPix : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF_EX(ResMatPix, ResPixDL); + + void DCStore(bool sync); + ResMatPix CopyTo(void *pDst) const; + + void CallDisplayList(bool sync) const; + + bool GXGetAlphaCompare(GXCompare *pComp0, u8 *pRef0, GXAlphaOp *pLogic, GXCompare *pComp1, u8 *pRef1) const; + void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp logic, GXCompare comp1, u8 ref1); + + bool GXGetZMode(GXBool *pTest, GXCompare *pCompare, GXBool *pUpdate) const; + void GXSetZMode(GXBool test, GXCompare compare, GXBool update); + + bool + GXGetBlendMode(GXBlendMode *pMode, GXBlendFactor *pSrcFactor, GXBlendFactor *pDstFactor, GXLogicOp *pLogic) const; + void GXSetBlendMode(GXBlendMode mode, GXBlendFactor srcFactor, GXBlendFactor dstFactor, GXLogicOp logic); + + bool GXGetDstAlpha(GXBool *pEnable, u8 *pAlpha) const; + void GXSetDstAlpha(GXBool enable, u8 alpha); + + void EndEdit() { + DCStore(false); + } +}; + +/****************************************************************************** + * + * ResMatTevColor + * + ******************************************************************************/ +struct ResTevColorDL { + union { + struct { + u8 tevColor[GX_MAX_TEVREG - GX_TEVREG0][GX_BP_CMD_SZ * 4]; // at 0x0 + u8 PADDING_0x3C[64 - 0x3C]; // at 0x3C + u8 tevKColor[GX_MAX_KCOLOR][GX_BP_CMD_SZ * 2]; // at 0x40 + u8 PADDING_0x68[128 - 0x68]; // at 0x68 + } dl; + + u8 data[128]; + }; +}; + +class ResMatTevColor : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF_EX(ResMatTevColor, ResTevColorDL); + + void DCStore(bool sync); + ResMatTevColor CopyTo(void *pDst) const; + + void CallDisplayList(bool sync) const; + + bool GXGetTevColor(GXTevRegID id, GXColor *pColor) const; + void GXSetTevColor(GXTevRegID id, GXColor color); + + bool GXGetTevColorS10(GXTevRegID id, GXColorS10 *pColor) const; + void GXSetTevColorS10(GXTevRegID id, GXColorS10 color); + + bool GXGetTevKColor(GXTevKColorID id, GXColor *pColor) const; + void GXSetTevKColor(GXTevKColorID id, GXColor color); + + void EndEdit() { + DCStore(false); + } +}; + +/****************************************************************************** + * + * ResMatIndMtxAndScale + * + ******************************************************************************/ +struct ResIndMtxAndScaleDL { + union { + struct { + u8 indTexCoordScale[2][GX_BP_CMD_SZ]; // at 0x0 + u8 indTexMtx0[GX_BP_CMD_SZ * 3]; // at 0xA + u8 PADDING_0x19[32 - 0x19]; // at 0x19 + u8 indTexMtx1[GX_BP_CMD_SZ * 3]; // at 0x20 + u8 indTexMtx2[GX_BP_CMD_SZ * 3]; // at 0x2F + u8 PADDING_0x3E[64 - 0x3E]; // at 0x3E + } dl; + + u8 data[64]; // at 0x0 + }; +}; + +class ResMatIndMtxAndScale : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF_EX(ResMatIndMtxAndScale, ResIndMtxAndScaleDL); + + void DCStore(bool sync); + ResMatIndMtxAndScale CopyTo(void *pDst) const; + + void CallDisplayList(u8 indNum, bool sync) const; + + bool GXGetIndTexMtx(GXIndTexMtxID id, math::MTX34 *pMtx) const; + void GXSetIndTexMtx(GXIndTexMtxID id, const math::MTX34 &rMtx, s8 scaleExp); + + void EndEdit() { + DCStore(false); + } +}; + +/****************************************************************************** + * + * ResTexPlttInfo + * + ******************************************************************************/ +struct ResTexPlttInfoData { + s32 nameTex; // at 0x0 + s32 namePltt; // at 0x4 + ResTexData *pTexData; // at 0x8 + ResPlttData *pPlttData; // at 0xC + GXTexMapID mapID; // at 0x10 + GXTlut tlutID; // at 0x14 + GXTexWrapMode wrap_s; // at 0x18 + GXTexWrapMode wrap_t; // at 0x1C + GXTexFilter min_filt; // at 0x20 + GXTexFilter mag_filt; // at 0x24 + f32 lod_bias; // at 0x28 + GXAnisotropy max_aniso; // at 0x2C + bool bias_clamp; // at 0x30 + bool do_edge_lod; // at 0x31 + u8 PADDING_0x32; // at 0x32 + u8 PADDING_0x33; // at 0x33 +}; + +class ResTexPlttInfo : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResTexPlttInfo); + + bool Bind(const ResFile file, ResTexObj texObj, ResTlutObj tlutObj); + void Release(ResTexObj texObj, ResTlutObj tlutObj); + + ResName GetTexResName() const { + const ResTexPlttInfoData &r = ref(); + + if (r.nameTex != 0) { + return NW4R_G3D_OFS_TO_RESNAME(&r, r.nameTex); + } + + return ResName(NULL); + } + + ResName GetPlttResName() const { + const ResTexPlttInfoData &r = ref(); + + if (r.namePltt != 0) { + return NW4R_G3D_OFS_TO_RESNAME(&r, r.namePltt); + } + + return ResName(NULL); + } + + bool IsCIFmt() const { + return ref().namePltt != 0; + } + +private: + void BindTex_(const ResTex tex, ResTexObj texObj); + void BindPltt_(const ResPltt pltt, ResTlutObj tlutObj); +}; + +/****************************************************************************** + * + * ResMat + * + ******************************************************************************/ +struct ResMatDLData { + ResPixDL dlPix; // at 0x0 + ResTevColorDL dlTevColor; // at 0x20 + ResIndMtxAndScaleDL dlIndMtxAndScale; // at 0xA0 + ResTexCoordGenDL dlTexCoordGen; // at 0xE0 +}; + +struct ResMatData { + u32 size; // at 0x0 + s32 toResMdlData; // at 0x4 + s32 name; // at 0x8 + u32 id; // at 0xC + u32 flag; // at 0x10 + ResGenModeData genMode; // at 0x14 + ResMatMiscData misc; // at 0x1C + s32 toResTevData; // at 0x28 + u32 numResTexPlttInfo; // at 0x2C + s32 toResTexPlttInfo; // at 0x30 + s32 toResMatFurData; // at 0x34 + s32 toResUserData; // at 0x38 + s32 toResMatDLData; // at 0x40 + ResTexObjData texObjData; // at 0x44 + ResTlutObjData tlutObjData; // at 0x144 + ResTexSrtData texSrtData; // at 0x1A8 + ResChanData chan; // at 0x3F0 +}; + +class ResMat : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResMat); + + void Init(); + + bool Bind(const ResFile file); + void Release(); + + bool IsOpaque() const; + ResMdl GetParent(); + + u32 GetID() const { + return ref().id; + } + + ResGenMode GetResGenMode() { + return ResGenMode(&ref().genMode); + } + + ResMatMisc GetResMatMisc() { + return ResMatMisc(&ref().misc); + } + + ResTev GetResTev(); + ResTev GetResTev() const; + + u32 GetNumResTexPlttInfo() const { + return ref().numResTexPlttInfo; + } + + ResTexPlttInfo GetResTexPlttInfo(u32 id) { + ResTexPlttInfoData *pData = ofs_to_ptr(ref().toResTexPlttInfo); + + return ResTexPlttInfo(&pData[id]); + } + + ResMatDLData *GetResMatDLData() { + return ofs_to_ptr(ref().toResMatDLData); + } + + ResMatPix GetResMatPix() { + return ResMatPix(&GetResMatDLData()->dlPix); + } + + ResMatTevColor GetResMatTevColor() { + return ResMatTevColor(&GetResMatDLData()->dlTevColor); + } + + ResMatIndMtxAndScale GetResMatIndMtxAndScale() { + return ResMatIndMtxAndScale(&GetResMatDLData()->dlIndMtxAndScale); + } + + ResMatTexCoordGen GetResMatTexCoordGen() { + return ResMatTexCoordGen(&GetResMatDLData()->dlTexCoordGen); + } + + ResTlutObj GetResTlutObj() { + return ResTlutObj(&ref().tlutObjData); + } + + ResTexObj GetResTexObj() { + return ResTexObj(&ref().texObjData); + } + + ResTexSrt GetResTexSrt() { + return ResTexSrt(&ref().texSrtData); + } + + ResMatChan GetResMatChan() { + return ResMatChan(&ref().chan); + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resmdl.h b/include/nw4r/g3d/res/g3d_resmdl.h new file mode 100644 index 00000000..428bdff6 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resmdl.h @@ -0,0 +1,202 @@ +#ifndef NW4R_G3D_RES_RES_MDL_H +#define NW4R_G3D_RES_RES_MDL_H + +/** NOTICE: Revision change from 9->11. Structures, Enums, and/or Functions may have changed and not yet done so + * (Zeldex72, Feb 1, 2025) */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * ResMdlInfo + * + ******************************************************************************/ +struct ResMdlInfoDataTypedef { + enum TexMatrixMode { + TEXMATRIXMODE_MAYA, + TEXMATRIXMODE_XSI, + TEXMATRIXMODE_3DSMAX + }; + + enum EnvelopeMatrixMode { + EVPMATRIXMODE_NORMAL, + EVPMATRIXMODE_APPROX, + EVPMATRIXMODE_EXACT + }; +}; + +enum ScalingRule { + SCALINGRULE_STANDARD, + SCALINGRULE_SOFTIMAGE, + SCALINGRULE_MAYA +}; + +struct ResMtxIDToNodeIDData { + u32 numMtxID; // at 0x0 +}; + +struct ResMdlInfoData : ResMdlInfoDataTypedef { + u32 size; // at 0x0 + s32 toResMdlData; // at 0x4 + ScalingRule scaling_rule; // at 0x8 + TexMatrixMode tex_mtx_mode; // at 0xC + s32 vertex_size; // at 0x10 + s32 triangle_size; // at 0x14 + s32 original_path; // at 0x18 + u32 numViewMtx; // at 0x1C + bool need_nrm_mtx_array; // at 0x20 + bool need_tex_mtx_array; // at 0x21 + bool is_valid_volume; // at 0x22 + u8 envelope_mtx_mode; // at 0x23 + s32 toMtxIDToNodeID; // at 0x24 + math::_VEC3 volume_min; // at 0x28 + math::_VEC3 volume_max; // at 0x34 +}; + +class ResMdlInfo : public ResCommon, public ResMdlInfoDataTypedef { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResMdlInfo); + + ScalingRule GetScalingRule() const { + return ref().scaling_rule; + } + + u32 GetNumViewMtx() const { + return ref().numViewMtx; + } + + EnvelopeMatrixMode GetEnvelopeMatrixMode() const { + return static_cast(ref().envelope_mtx_mode); + } + + u32 GetNumPosNrmMtx() const { + const ResMtxIDToNodeIDData *pData = reinterpret_cast( + reinterpret_cast(&ref()) + ref().toMtxIDToNodeID + ); + + return pData->numMtxID; + } + + s32 GetNodeIDFromMtxID(u32 id) const { + const s32 *pArray = reinterpret_cast( + reinterpret_cast(&ref()) + ref().toMtxIDToNodeID + sizeof(ResMtxIDToNodeIDData) + ); + + return pArray[id]; + } +}; + +/****************************************************************************** + * + * ResMdl + * + ******************************************************************************/ +struct ResMdlData { + ResBlockHeaderData header; // at 0x0 + u32 revision; // at 0x8 + s32 toResFileData; // at 0xC + s32 toResByteCodeDic; // at 0x10 + s32 toResNodeDic; // at 0x14 + s32 toResVtxPosDic; // at 0x18 + s32 toResVtxNrmDic; // at 0x1C + s32 toResVtxClrDic; // at 0x20 + s32 toResVtxTexCoordDic; // at 0x24 + s32 toResVtxFurVecDic; // at 0x28 + s32 toResVtxFurPosDic; // at 0x2C + s32 toResMatDic; // at 0x30 + s32 toResTevDic; // at 0x34 + s32 toResShpDic; // at 0x38 + s32 toResTexNameToTexPlttInfoDic; // at 0x3C + s32 toResPlttNameToTexPlttInfoDic; // at 0x40 + s32 toResUserData; // at 0x44 + s32 name; // at 0x48 + ResMdlInfoData info; // at 0x4C +}; + +class ResMdl : public ResCommon { +public: + static const u32 SIGNATURE = 'MDL0'; + static const int REVISION = 11; + +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResMdl); + + void Init(); + void Terminate(); + + bool Bind(const ResFile file); + void Release(); + + bool IsOpaque() const; + u32 GetRevision() const { + return ref().revision; + } + + bool CheckRevision() const { + return GetRevision() == REVISION; + } + + const u8 *GetResByteCode(const char *pName) const; + + ResNode GetResNode(const char *pName) const; + ResNode GetResNode(const ResName name) const; + ResNode GetResNode(int idx) const; + ResNode GetResNode(u32 idx) const; + u32 GetResNodeNumEntries() const; + + ResVtxPos GetResVtxPos(const ResName name) const; + ResVtxPos GetResVtxPos(int idx) const; + ResVtxPos GetResVtxPos(u32 idx) const; + u32 GetResVtxPosNumEntries() const; + + ResVtxNrm GetResVtxNrm(const ResName name) const; + ResVtxNrm GetResVtxNrm(int idx) const; + ResVtxNrm GetResVtxNrm(u32 idx) const; + u32 GetResVtxNrmNumEntries() const; + + ResVtxClr GetResVtxClr(const ResName name) const; + ResVtxClr GetResVtxClr(int idx) const; + ResVtxClr GetResVtxClr(u32 idx) const; + u32 GetResVtxClrNumEntries() const; + + ResVtxTexCoord GetResVtxTexCoord(int idx) const; + u32 GetResVtxTexCoordNumEntries() const; + + ResMat GetResMat(const char *pName) const; + ResMat GetResMat(const ResName name) const; + ResMat GetResMat(int idx) const; + ResMat GetResMat(u32 idx) const; + u32 GetResMatNumEntries() const; + + ResShp GetResShp(const char *pName) const; + ResShp GetResShp(int idx) const; + ResShp GetResShp(u32 idx) const; + u32 GetResShpNumEntries() const; + + ResTexPlttInfo GetResTexPlttInfoOffsetFromTexName(int idx) const; + u32 GetResTexPlttInfoOffsetFromTexNameNumEntries() const; + + ResMdlInfo GetResMdlInfo() { + return ResMdlInfo(&ref().info); + } + ResMdlInfo GetResMdlInfo() const { + return ResMdlInfo(const_cast(&ref().info)); + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resnode.h b/include/nw4r/g3d/res/g3d_resnode.h new file mode 100644 index 00000000..1fa0244c --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resnode.h @@ -0,0 +1,180 @@ +#ifndef NW4R_G3D_RES_RES_NODE_H +#define NW4R_G3D_RES_RES_NODE_H +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +// Forward declarations +struct ChrAnmResult; + +/****************************************************************************** + * + * Common types + * + ******************************************************************************/ +struct ResNodeDataTypedef { + enum Billboard { + BILLBOARD_OFF, + BILLBOARD_STD, + BILLBOARD_PERSP_STD, + BILLBOARD_ROT, + BILLBOARD_PERSP_ROT, + BILLBOARD_Y_OFF, + BILLBOARD_PERSP_Y, + + NUM_BILLBOARD, + }; +}; + +/****************************************************************************** + * + * ResNode + * + ******************************************************************************/ +struct ResNodeData : ResNodeDataTypedef { + enum Flag { + FLAG_IDENTITY = (1 << 0), + FLAG_TRANS_ZERO = (1 << 1), + FLAG_ROT_ZERO = (1 << 2), + FLAG_SCALE_ONE = (1 << 3), + FLAG_SCALE_UNIFORM = (1 << 4), + + // Maya Scale Compensation + FLAG_SSC_APPLY = (1 << 5), + FLAG_SSC_PARENT = (1 << 6), + + // Softimage Hierarchical Scaling + FLAG_XSI_SCALING = (1 << 7), + + FLAG_VISIBLE = (1 << 8), + FLAG_GEOMETRY = (1 << 9), + FLAG_BILLBOARD_PARENT = (1 << 10) + }; + + u32 size; // at 0x0 + s32 toResMdlData; // at 0x4 + s32 name; // at 0x8 + u32 id; // at 0xC + u32 mtxID; // at 0x10 + u32 flags; // at 0x14 + Billboard bbmode; // at 0x18 + u32 bbref_nodeid; // at 0x1C + math::_VEC3 scale; // at 0x20 + math::_VEC3 rot; // at 0x2C + math::_VEC3 translate; // at 0x38 + math::VEC3 volume_min; // at 0x44 + math::VEC3 volume_max; // at 0x50 + s32 toParentNode; // at 0x5C + s32 toChildNode; // at 0x60 + s32 toNextSibling; // at 0x64 + s32 toPrevSibling; // at 0x68 + s32 toResUserData; // at 0x6C + math::_MTX34 modelMtx; // at 0x70 + math::_MTX34 invModelMtx; // at 0xA0 +}; + +class ResNode : public ResCommon, public ResNodeDataTypedef { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResNode); + + void PatchChrAnmResult(ChrAnmResult *pResult) const; + void CalcChrAnmResult(ChrAnmResult *pResult) const; + + ResName GetResName() const { + const ResNodeData &r = ref(); + + if (r.name != 0) { + return NW4R_G3D_OFS_TO_RESNAME(&r, r.name); + } + + return ResName(NULL); + } + + u32 GetID() const { + if (IsValid()) { + return ptr()->id; + } + + return 0; + } + + u32 GetMtxID() const { + if (IsValid()) { + return ptr()->mtxID; + } + + return 0; + } + + bool IsVisible() const { + if (IsValid()) { + return ptr()->flags & ResNodeData::FLAG_VISIBLE; + } + + return false; + } + + void SetVisibility(bool visible) { + if (!IsValid()) { + return; + } + + if (visible) { + ptr()->flags |= ResNodeData::FLAG_VISIBLE; + } else { + ptr()->flags &= ~ResNodeData::FLAG_VISIBLE; + } + } + + Billboard GetBillboardMode() const { + if (IsValid()) { + return ptr()->bbmode; + } + + return BILLBOARD_OFF; + } + + const math::VEC3 &GetTranslate() const { + return ref().translate; + } + + ResNode GetParentNode() { + return ofs_to_obj(ref().toParentNode); + } + ResNode GetParentNode() const { + return ofs_to_obj(ref().toParentNode); + } + + ResNode GetChildNode() { + return ofs_to_obj(ref().toChildNode); + } + ResNode GetChildNode() const { + return ofs_to_obj(ref().toChildNode); + } + + ResNode GetNextSibling() { + return ofs_to_obj(ref().toNextSibling); + } + ResNode GetNextSibling() const { + return ofs_to_obj(ref().toNextSibling); + } + + ResNode GetPrevSibling() { + return ofs_to_obj(ref().toPrevSibling); + } + ResNode GetPrevSibling() const { + return ofs_to_obj(ref().toPrevSibling); + } + + void EndEdit() {} +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_respltt.h b/include/nw4r/g3d/res/g3d_respltt.h new file mode 100644 index 00000000..0ba3ab33 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_respltt.h @@ -0,0 +1,82 @@ +#ifndef NW4R_G3D_RES_RES_PLTT_H +#define NW4R_G3D_RES_RES_PLTT_H +#include + +/** NOTICE: Revision change from 1->??. Structures, Enums, and/or Functions may have changed and not yet done so + * (Zeldex72, Feb 1, 2025) */ + +#include + +#include + +namespace nw4r { +namespace g3d { + +struct ResPlttData { + ResBlockHeaderData header; // at 0x0 + u32 revision; // at 0x8 + s32 toResFileData; // at 0xC + s32 toPlttData; // at 0x10 + s32 name; // at 0x14 + GXTlutFmt fmt; // at 0x18 + u16 numEntries; // at 0x1C + u16 PADDING_0x1E; // at 0x1E + s32 original_path; // at 0x20 + s32 toResUserData; // at 0x24 +}; + +class ResPltt : public ResCommon { +public: + static const u32 SIGNATURE = 'PLT0'; + static const int REVISION = 1; + +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResPltt); + + void Init() { + DCStore(false); + } + + u32 GetRevision() const { + return ref().revision; + } + + bool CheckRevision() const { + return GetRevision() == REVISION; + } + + void DCStore(bool sync); + + u16 *GetPlttData() { + ResPlttData &r = ref(); + + // clang-format off + return r.toPlttData != 0 + ? reinterpret_cast(reinterpret_cast(&r) + r.toPlttData) + : NULL; + // clang-format on + } + + const u16 *GetPlttData() const { + const ResPlttData &r = ref(); + + // clang-format off + return r.toPlttData != 0 + ? reinterpret_cast(reinterpret_cast(&r) + r.toPlttData) + : NULL; + // clang-format on + } + + GXTlutFmt GetFmt() const { + return ref().fmt; + } + + u32 GetNumEntries() const { + return ref().numEntries; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resshp.h b/include/nw4r/g3d/res/g3d_resshp.h new file mode 100644 index 00000000..b3f74228 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resshp.h @@ -0,0 +1,151 @@ +#ifndef NW4R_G3D_RES_RES_SHP_H +#define NW4R_G3D_RES_RES_SHP_H + +#include + +#include +// #include +#include + +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * ResShpPrePrim + * + ******************************************************************************/ +struct ResPrePrimDL { + union { + struct { + u8 cullMode[10]; // at 0x0 + u8 vtxDescv[21]; // at 0xA + u8 PADDING_0x1F; // at 0x1F + u8 vtxFmtv[GX_CP_CMD_SZ * 3]; // at 0x20 + u8 array[GX_POS_MTX_ARRAY - GX_VA_POS][GX_CP_CMD_SZ * 2]; // at 0x32 + u8 PADDING_0xC2[0xE0 - 0xC2]; // at 0xC2 + } dl; + + u8 data[0xE0]; // at 0x0 + }; +}; + +class ResShpPrePrim : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF_EX(ResShpPrePrim, ResPrePrimDL); + + void DCStore(bool sync); +}; + +/****************************************************************************** + * + * ResShp + * + ******************************************************************************/ +struct ResCacheVtxDescv { + union { + u32 data_u32[0xC / sizeof(u32)]; + u8 data[0xC / sizeof(u8)]; + }; // at 0x0 + + void Clear() { + data_u32[0] = data_u32[1] = data_u32[2] = 0; + } + + bool operator==(const ResCacheVtxDescv &rRhs) const { + return data_u32[0] == rRhs.data_u32[0] && data_u32[1] == rRhs.data_u32[1] && data_u32[2] == rRhs.data_u32[2]; + } +}; + +struct ResMtxSetUsed { + u32 numMtxID; // at 0x0 + u16 vecMtxID[2]; // at 0x4 +}; + +struct ResShpData { + enum IDFlag { + ID_FLAG_ENVELOPE = (1 << 31), + }; + + enum Flag { + FLAG_INVISIBLE = (1 << 1), + }; + + u32 size; // at 0x0 + s32 toResMdlData; // at 0x4 + s32 curMtxIdx; // at 0x8 + ResCacheVtxDescv cache; // at 0xC + ResTagDLData tagPrePrimDL; // at 0x18 + ResTagDLData tagPrimDL; // at 0x24 + u32 vcdBitmap; // at 0x30 + u32 flag; // at 0x34 + s32 name; // at 0x38 + u32 id; // at 0x3C + u32 numVtx; // at 0x40 + u32 numPolygon; // at 0x44 + s16 idVtxPosition; // at 0x48 + s16 idVtxNormal; // at 0x4A + s16 idVtxColor[GX_VA_TEX0 - GX_VA_CLR0]; // at 0x4C + s16 idVtxTexCoord[GX_POS_MTX_ARRAY - GX_VA_TEX0]; // at 0x50 + s32 toMtxSetUsed; // at 0x60 + ResMtxSetUsed msu; // at 0x64 +}; + +class ResShp : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResShp); + + void Init(); + void Terminate(); + + ResMdl GetParent() const; + + bool GXGetVtxDescv(GXVtxDescList *pList) const; + bool GXGetVtxAttrFmtv(GXVtxAttrFmtList *pList) const; + void GXSetArray(GXAttr attr, const void *pBase, u8 stride); + void DisableSetArray(GXAttr attr); + + ResVtxPos GetResVtxPos() const; + ResVtxNrm GetResVtxNrm() const; + ResVtxClr GetResVtxClr(u32 idx) const; + ResVtxTexCoord GetResVtxTexCoord(u32 idx) const; + + void CallPrePrimitiveDisplayList(bool sync, bool cacheIsSame) const; + void CallPrimitiveDisplayList(bool sync) const; + + ResTagDL GetPrePrimDLTag() { + return ResTagDL(&ref().tagPrePrimDL); + } + ResTagDL GetPrePrimDLTag() const { + return ResTagDL(const_cast(&ref().tagPrePrimDL)); + } + + ResTagDL GetPrimDLTag() { + return ResTagDL(&ref().tagPrimDL); + } + ResTagDL GetPrimDLTag() const { + return ResTagDL(const_cast(&ref().tagPrimDL)); + } + + ResShpPrePrim GetResShpPrePrim() { + return ResShpPrePrim(GetPrePrimDLTag().GetDL()); + } + ResShpPrePrim GetResShpPrePrim() const { + return ResShpPrePrim(GetPrePrimDLTag().GetDL()); + } + + bool ExistVtxDesc(GXAttr attr) const { + return ref().vcdBitmap & (1 << attr); + } + + bool IsVisible() const { + return !(ref().flag & ResShpData::FLAG_INVISIBLE); + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_restev.h b/include/nw4r/g3d/res/g3d_restev.h new file mode 100644 index 00000000..3237030b --- /dev/null +++ b/include/nw4r/g3d/res/g3d_restev.h @@ -0,0 +1,96 @@ +#ifndef NW4R_G3D_RES_RES_TEV_H +#define NW4R_G3D_RES_RES_TEV_H +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +// TODO: Why? +static const int TEV_STAGES_PER_DL = 2; + +struct ResTevCommonDL { + union { + struct { + u8 swapModeTable[GX_MAX_TEVSWAP][GX_BP_CMD_SZ * 4]; // at 0x0 + u8 indTexOrder[1][GX_BP_CMD_SZ]; // at 0x50 + u8 PADDING_0x55[0x60 - 0x55]; // at 0x55 + } dl; + + u8 data[0x60]; // at 0x0 + }; +}; + +struct ResTevVariableDL { + union { + struct { + u8 tevKonstantSel[GX_BP_CMD_SZ * 2]; // at 0x0 + u8 tevOrder[GX_BP_CMD_SZ]; // at 0xA + u8 tevColorCalc[TEV_STAGES_PER_DL][GX_BP_CMD_SZ]; // at 0xF + u8 alphaCalcAndSwap[TEV_STAGES_PER_DL][GX_BP_CMD_SZ]; // at 0x19 + u8 tevIndirect[TEV_STAGES_PER_DL][GX_BP_CMD_SZ]; // at 0x23 + u8 PADDING_0x2D[0x30 - 0x2D]; // at 0x2D + } dl; + + u8 data[0x30]; // at 0x0 + }; +}; + +struct ResTevDL { + union { + struct { + ResTevCommonDL common; // at 0x0 + ResTevVariableDL var[GX_MAX_TEVSTAGE / TEV_STAGES_PER_DL]; // at 0x60 + } dl; + + u8 data[0x1E0]; // at 0x0 + }; +}; + +struct ResTevData { + u32 size; // at 0x0 + s32 toResMdlData; // at 0x4 + u32 id; // at 0x8 + u8 nStages; // at 0xC + u8 PADDING_0xD[0x10 - 0xD]; // at 0xD + u8 texCoordToTexMapID[GX_MAX_TEXCOORD]; // at 0x10 + u8 PADDING_0x18[0x20 - 0x18]; // at 0x18 + ResTevDL dl; // at 0x20 +}; + +class ResTev : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResTev); + + bool GXGetTevSwapModeTable( + GXTevSwapSel swap, GXTevColorChan *pR, GXTevColorChan *pG, GXTevColorChan *pB, GXTevColorChan *pA + ) const; + void + GXSetTevSwapModeTable(GXTevSwapSel swap, GXTevColorChan r, GXTevColorChan g, GXTevColorChan b, GXTevColorChan a); + + bool GXGetTevOrder(GXTevStageID stage, GXTexCoordID *pCoord, GXTexMapID *pMap, GXChannelID *pChannel) const; + + void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d); + + void CallDisplayList(bool sync) const; + + ResTev CopyTo(void *pDst); + + void DCStore(bool sync); + + u8 GetNumTevStages() const { + return ref().nStages; + } + + void EndEdit() { + DCStore(false); + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_restex.h b/include/nw4r/g3d/res/g3d_restex.h new file mode 100644 index 00000000..07044718 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_restex.h @@ -0,0 +1,81 @@ +#ifndef NW4R_G3D_RES_RES_TEX_H +#define NW4R_G3D_RES_RES_TEX_H +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +struct ResTexData { + enum Flag { + FLAG_CIFMT = (1 << 0), + }; + + ResBlockHeaderData header; // at 0x0 + u32 revision; // at 0x8 + s32 toResFileData; // at 0xC + s32 toTexData; // at 0x10 + s32 name; // at 0x14 + u32 flag; // at 0x18 + u16 width; // at 0x1C + u16 height; // at 0x1E + union { + GXTexFmt fmt; + GXCITexFmt cifmt; + }; // at 0x20 + u32 mipmap_level; // at 0x24 + f32 min_lod; // at 0x28 + f32 max_lod; // at 0x2C + s32 original_path; // at 0x30 + s32 toResUserData; // at 0x34 +}; + +class ResTex : public ResCommon { +public: + static const u32 SIGNATURE = 'TEX0'; + static const int REVISION = 1; + +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResTex); + + void Init(); + + u32 GetRevision() const { + return ref().revision; + } + + bool CheckRevision() const { + return GetRevision() == REVISION; + } + + bool GetTexObjParam( + void **ppTexData, u16 *pWidth, u16 *pHeight, GXTexFmt *pFormat, f32 *pMinLod, f32 *pMaxLod, GXBool *pMipMap + ) const; + + bool GetTexObjCIParam( + void **ppTexData, u16 *pWidth, u16 *pHeight, GXCITexFmt *pFormatCI, f32 *pMinLod, f32 *pMaxLod, GXBool *pMipMap + ) const; + + bool IsCIFmt() const { + return ref().flag & ResTexData::FLAG_CIFMT; + } + + u16 GetWidth() const { + return ref().width; + } + u16 GetHeight() const { + return ref().height; + } + + const void *GetTexData() const { + return ofs_to_ptr(ref().toTexData); + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/g3d/res/g3d_resvtx.h b/include/nw4r/g3d/res/g3d_resvtx.h new file mode 100644 index 00000000..6d4184e3 --- /dev/null +++ b/include/nw4r/g3d/res/g3d_resvtx.h @@ -0,0 +1,226 @@ +#ifndef NW4R_G3D_RES_RES_VTX_H +#define NW4R_G3D_RES_RES_VTX_H +#include + +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * ResVtxPos + * + ******************************************************************************/ +struct ResVtxPosData { + u32 size; // at 0x0 + s32 toResMdlData; // at 0x4 + s32 toVtxPosArray; // at 0x8 + s32 name; // at 0xC + u32 id; // at 0x10 + GXCompCnt cmpcnt; // at 0x14 + GXCompType tp; // at 0x18 + u8 frac; // at 0x1C + u8 stride; // at 0x1D + u16 numPos; // at 0x1E + math::_VEC3 min; // at 0x20 + math::_VEC3 max; // at 0x2C +}; + +class ResVtxPos : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResVtxPos); + + void Init() { + DCStore(false); + } + + void SetArray(); + void GetArray(const void **ppBase, u8 *pStride) const; + + void CopyTo(void *pDst) const; + void DCStore(bool sync); + + u32 GetSize() const { + return ref().size; + } + + void *GetData() { + return ofs_to_ptr(ref().toVtxPosArray); + } + const void *GetData() const { + return ofs_to_ptr(ref().toVtxPosArray); + } + + u32 GetID() const { + return ref().id; + } + + u16 GetNumVtxPos() const { + return ref().numPos; + } +}; + +/****************************************************************************** + * + * ResVtxNrm + * + ******************************************************************************/ +struct ResVtxNrmData { + u32 size; // at 0x0 + s32 toResMdlData; // at 0x4 + s32 toVtxNrmArray; // at 0x8 + s32 name; // at 0xC + u32 id; // at 0x10 + GXCompCnt cmpcnt; // at 0x14 + GXCompType tp; // at 0x18 + u8 frac; // at 0x1C + u8 stride; // at 0x1D + u16 numNrm; // at 0x1E +}; + +class ResVtxNrm : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResVtxNrm); + + void Init() { + DCStore(false); + } + + void SetArray(); + void GetArray(const void **ppBase, u8 *pStride) const; + + void CopyTo(void *pDst) const; + void DCStore(bool); + + u32 GetSize() const { + return ref().size; + } + + void *GetData() { + return ofs_to_ptr(ref().toVtxNrmArray); + } + const void *GetData() const { + return ofs_to_ptr(ref().toVtxNrmArray); + } + + u32 GetID() const { + return ref().id; + } + + u16 GetNumVtxNrm() const { + return ref().numNrm; + } +}; + +/****************************************************************************** + * + * ResVtxClr + * + ******************************************************************************/ +struct ResVtxClrData { + u32 size; // at 0x0 + s32 toResMdlData; // at 0x4 + s32 toVtxClrArray; // at 0x8 + s32 name; // at 0xC + u32 id; // at 0x10 + GXCompCnt cmpcnt; // at 0x14 + GXCompType tp; // at 0x18 + u8 stride; // at 0x1C + u8 PADDING_0x1D; // at 0x1D + u16 numClr; // at 0x1E +}; + +class ResVtxClr : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResVtxClr); + + void Init() { + DCStore(false); + } + + void SetArray(GXAttr attr); + void GetArray(const void **ppBase, u8 *pStride) const; + + void CopyTo(void *pDst) const; + void DCStore(bool sync); + + u32 GetSize() const { + return ref().size; + } + + void *GetData() { + return ofs_to_ptr(ref().toVtxClrArray); + } + const void *GetData() const { + return ofs_to_ptr(ref().toVtxClrArray); + } + + u32 GetID() const { + return ref().id; + } + + u16 GetNumVtxClr() const { + return ref().numClr; + } +}; + +/****************************************************************************** + * + * ResVtxTexCoord + * + ******************************************************************************/ +struct ResVtxTexCoordData { + u32 size; // at 0x0 + s32 toResMdlData; // at 0x4 + s32 toTexCoordArray; // at 0x8 + s32 name; // at 0xC + u32 id; // at 0x10 + GXCompCnt cmpcnt; // at 0x14 + GXCompType tp; // at 0x18 + u8 frac; // at 0x1C + u8 stride; // at 0x1D + u16 numTexCoord; // at 0x1E + math::_VEC2 min; // at 0x20 + math::_VEC2 max; // at 0x2C +}; + +class ResVtxTexCoord : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResVtxTexCoord); + + void Init() { + DCStore(false); + } + + void GetArray(const void **ppBase, u8 *pStride) const; + void DCStore(bool sync); + + u32 GetSize() const { + return ref().size; + } + + void *GetData() { + return ofs_to_ptr(ref().toTexCoordArray); + } + const void *GetData() const { + return ofs_to_ptr(ref().toTexCoordArray); + } + + u32 GetID() const { + return ref().id; + } + + u16 GetNumTexCoord() const { + return ref().numTexCoord; + } +}; + +} // namespace g3d +} // namespace nw4r + +#endif diff --git a/include/nw4r/math.h b/include/nw4r/math.h index 0ce30568..ea99d35f 100644 --- a/include/nw4r/math.h +++ b/include/nw4r/math.h @@ -1,9 +1,9 @@ #ifndef NW4R_PUBLIC_MATH_H #define NW4R_PUBLIC_MATH_H -#include "nw4r/math/math_arithmetic.h" -#include "nw4r/math/math_geometry.h" -#include "nw4r/math/math_triangular.h" -#include "nw4r/math/math_types.h" +#include +#include +#include +#include #endif diff --git a/include/nw4r/math/math_arithmetic.h b/include/nw4r/math/math_arithmetic.h index b18941f2..b532cd41 100644 --- a/include/nw4r/math/math_arithmetic.h +++ b/include/nw4r/math/math_arithmetic.h @@ -76,7 +76,7 @@ inline f32 FSqrt(f32 x) { } inline f32 FLog(f32 x) { - if (x >= 0.0f) { + if (x > 0.0f) { return detail::FLog(x); } diff --git a/include/nw4r/math/math_types.h b/include/nw4r/math/math_types.h index 7e2e8798..5ed34ad3 100644 --- a/include/nw4r/math/math_types.h +++ b/include/nw4r/math/math_types.h @@ -80,15 +80,20 @@ struct VEC3 : _VEC3 { y = fy; z = fz; } - VEC3(const Vec &vec) { - x = vec.x; - y = vec.y; - z = vec.z; + VEC3(const _VEC3 &rVec) { + x = rVec.x; + y = rVec.y; + z = rVec.z; } - VEC3(const f32 *p) { - x = p[0]; - y = p[1]; - z = p[2]; + VEC3(const Vec &rVec) { + x = rVec.x; + y = rVec.y; + z = rVec.z; + } + VEC3(const f32 *pData) { + x = pData[0]; + y = pData[1]; + z = pData[2]; } operator Vec *() { @@ -401,7 +406,7 @@ inline VEC3 *VEC3Scale(register VEC3 *out, register const VEC3 *in, register f32 ps_muls0 work1, work0, scale psq_st work1, VEC3.x(out), 0, 0 - // Scale Z + // Scale Z psq_l work0, VEC3.z(in), 1, 0 ps_muls0 work1, work0, scale psq_st work1, VEC3.z(out), 1, 0 @@ -491,9 +496,12 @@ inline MTX34 *MTX34Identity(MTX34 *mtx) { return mtx; } -inline MTX34 *MTX34Inv(MTX34 *out, const MTX34 *in) { - PSMTXInverse(*in, *out); - return out; +inline u32 MTX34Inv(MTX34 *out, const MTX34 *in) { + return PSMTXInverse(*in, *out); +} + +inline u32 MTX34InvTranspose(MTX34 *pOut, const MTX34 *pIn) { + return PSMTXInvXpose(*pIn, *pOut); } inline MTX34 *MTX34LookAt(MTX34 *mtx, const VEC3 *pos, const VEC3 *up, const VEC3 *target) { diff --git a/include/nw4r/snd.h b/include/nw4r/snd.h index 09fea867..321e51ff 100644 --- a/include/nw4r/snd.h +++ b/include/nw4r/snd.h @@ -1,78 +1,78 @@ #ifndef NW4R_PUBLIC_SND_H #define NW4R_PUBLIC_SND_H -#include "nw4r/snd/snd_AxManager.h" -#include "nw4r/snd/snd_AxVoice.h" -#include "nw4r/snd/snd_AxVoiceManager.h" -#include "nw4r/snd/snd_AxfxImpl.h" -#include "nw4r/snd/snd_Bank.h" -#include "nw4r/snd/snd_BankFile.h" -#include "nw4r/snd/snd_BasicPlayer.h" -#include "nw4r/snd/snd_BasicSound.h" -#include "nw4r/snd/snd_Channel.h" -#include "nw4r/snd/snd_ChannelManager.h" -#include "nw4r/snd/snd_Common.h" -#include "nw4r/snd/snd_DisposeCallback.h" -#include "nw4r/snd/snd_DisposeCallbackManager.h" -#include "nw4r/snd/snd_DvdSoundArchive.h" -#include "nw4r/snd/snd_EnvGenerator.h" -#include "nw4r/snd/snd_ExternalSoundPlayer.h" -#include "nw4r/snd/snd_FrameHeap.h" -#include "nw4r/snd/snd_FxBase.h" -#include "nw4r/snd/snd_FxChorus.h" -#include "nw4r/snd/snd_FxDelay.h" -#include "nw4r/snd/snd_FxReverbHi.h" -#include "nw4r/snd/snd_FxReverbHiDpl2.h" -#include "nw4r/snd/snd_InstancePool.h" -#include "nw4r/snd/snd_Lfo.h" -#include "nw4r/snd/snd_MemorySoundArchive.h" -#include "nw4r/snd/snd_MmlParser.h" -#include "nw4r/snd/snd_MmlSeqTrack.h" -#include "nw4r/snd/snd_MmlSeqTrackAllocator.h" -#include "nw4r/snd/snd_MoveValue.h" -#include "nw4r/snd/snd_NandSoundArchive.h" -#include "nw4r/snd/snd_NoteOnCallback.h" -#include "nw4r/snd/snd_PlayerHeap.h" -#include "nw4r/snd/snd_RemoteSpeaker.h" -#include "nw4r/snd/snd_RemoteSpeakerManager.h" -#include "nw4r/snd/snd_SeqFile.h" -#include "nw4r/snd/snd_SeqPlayer.h" -#include "nw4r/snd/snd_SeqSound.h" -#include "nw4r/snd/snd_SeqSoundHandle.h" -#include "nw4r/snd/snd_SeqTrack.h" -#include "nw4r/snd/snd_SeqTrackAllocator.h" -#include "nw4r/snd/snd_Sound3DActor.h" -#include "nw4r/snd/snd_Sound3DListener.h" -#include "nw4r/snd/snd_Sound3DManager.h" -#include "nw4r/snd/snd_SoundActor.h" -#include "nw4r/snd/snd_SoundArchive.h" -#include "nw4r/snd/snd_SoundArchiveFile.h" -#include "nw4r/snd/snd_SoundArchiveLoader.h" -#include "nw4r/snd/snd_SoundArchivePlayer.h" -#include "nw4r/snd/snd_SoundHandle.h" -#include "nw4r/snd/snd_SoundHeap.h" -#include "nw4r/snd/snd_SoundInstanceManager.h" -#include "nw4r/snd/snd_SoundMemoryAllocatable.h" -#include "nw4r/snd/snd_SoundPlayer.h" -#include "nw4r/snd/snd_SoundStartable.h" -#include "nw4r/snd/snd_SoundSystem.h" -#include "nw4r/snd/snd_SoundThread.h" -#include "nw4r/snd/snd_StrmChannel.h" -#include "nw4r/snd/snd_StrmFile.h" -#include "nw4r/snd/snd_StrmPlayer.h" -#include "nw4r/snd/snd_StrmSound.h" -#include "nw4r/snd/snd_StrmSoundHandle.h" -#include "nw4r/snd/snd_Task.h" -#include "nw4r/snd/snd_TaskManager.h" -#include "nw4r/snd/snd_TaskThread.h" -#include "nw4r/snd/snd_Util.h" -#include "nw4r/snd/snd_Voice.h" -#include "nw4r/snd/snd_VoiceManager.h" -#include "nw4r/snd/snd_WaveFile.h" -#include "nw4r/snd/snd_WaveSound.h" -#include "nw4r/snd/snd_WaveSoundHandle.h" -#include "nw4r/snd/snd_WsdFile.h" -#include "nw4r/snd/snd_WsdPlayer.h" -#include "nw4r/snd/snd_adpcm.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif diff --git a/include/nw4r/types_nw4r.h b/include/nw4r/types_nw4r.h index 4123a7f3..7a6ff652 100644 --- a/include/nw4r/types_nw4r.h +++ b/include/nw4r/types_nw4r.h @@ -1,13 +1,22 @@ #ifndef NW4R_TYPES_H #define NW4R_TYPES_H - -#include "common.h" +#include #define NW4R_BYTEORDER_BIG 0xFEFF #define NW4R_BYTEORDER_LITTLE 0xFFFE #define NW4R_VERSION(major, minor) ((major & 0xFF) << 8 | minor & 0xFF) +#ifdef NW4R_LITTLE_ENDIAN +#define NW4R_BYTEORDER_NATIVE NW4R_BYTEORDER_LITTLE +#else +#define NW4R_BYTEORDER_NATIVE NW4R_BYTEORDER_BIG +#endif + +#define NW4R_LIB_VERSION(NAME, ORIGINAL_DATE, ORIGINAL_TIME, ORIGINAL_CWCC) \ + const char *NW4R_##NAME##_Version_ = \ + "<< NW4R - " #NAME " \tfinal build: " ORIGINAL_DATE " " ORIGINAL_TIME " (" ORIGINAL_CWCC ") >>" + namespace nw4r { namespace ut { namespace detail { @@ -141,6 +150,7 @@ struct FuncObjCalcWorld; struct AnmScn; struct AnmScnRes; struct CameraAnmResult; +struct ChrAnmResult; struct Draw1Mat1ShpSwap; struct DrawResMdlReplacement; struct FogAnmResult; diff --git a/include/nw4r/ut.h b/include/nw4r/ut.h index 428eb4d4..0b8309fc 100644 --- a/include/nw4r/ut.h +++ b/include/nw4r/ut.h @@ -1,28 +1,28 @@ #ifndef NW4R_PUBLIC_UT_H #define NW4R_PUBLIC_UT_H -#include "nw4r/ut/ut_CharStrmReader.h" -#include "nw4r/ut/ut_CharWriter.h" -#include "nw4r/ut/ut_Color.h" -#include "nw4r/ut/ut_DvdFileStream.h" -#include "nw4r/ut/ut_DvdLockedFileStream.h" -#include "nw4r/ut/ut_FileStream.h" -#include "nw4r/ut/ut_Font.h" -#include "nw4r/ut/ut_IOStream.h" -#include "nw4r/ut/ut_LinkList.h" -#include "nw4r/ut/ut_LockedCache.h" -#include "nw4r/ut/ut_NandFileStream.h" -#include "nw4r/ut/ut_NonCopyable.h" -#include "nw4r/ut/ut_Rect.h" -#include "nw4r/ut/ut_ResFont.h" -#include "nw4r/ut/ut_ResFontBase.h" -#include "nw4r/ut/ut_RomFont.h" -#include "nw4r/ut/ut_RuntimeTypeInfo.h" -#include "nw4r/ut/ut_TagProcessorBase.h" -#include "nw4r/ut/ut_TextWriterBase.h" -#include "nw4r/ut/ut_algorithm.h" -#include "nw4r/ut/ut_binaryFileFormat.h" -#include "nw4r/ut/ut_list.h" -#include "nw4r/ut/ut_lock.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif diff --git a/include/nw4r/ut/ut_Color.h b/include/nw4r/ut/ut_Color.h index f6e8349e..cbff07fe 100644 --- a/include/nw4r/ut/ut_Color.h +++ b/include/nw4r/ut/ut_Color.h @@ -61,6 +61,19 @@ public: operator u32() const { return ToU32ref(); } + // clang-format off + static const u32 RED = 0xFF0000FF; + static const u32 GREEN = 0x00FF00FF; + static const u32 BLUE = 0x0000FFFF; + + static const u32 CYAN = 0x00FFFFFF; + static const u32 MAGENTA = 0xFF00FFFF; + static const u32 YELLOW = 0xFFFF00FF; + + static const u32 BLACK = 0x000000FF; + static const u32 GRAY = 0x808080FF; + static const u32 WHITE = 0xFFFFFFFF; + // clang-format on } ALIGN_DECL(4); } // namespace ut diff --git a/include/rvl/AI/ai_hardware.h b/include/rvl/AI/ai_hardware.h index e7bce5f2..e8e07586 100644 --- a/include/rvl/AI/ai_hardware.h +++ b/include/rvl/AI/ai_hardware.h @@ -9,7 +9,7 @@ extern "C" { * AI Hardware Registers * https://www.gc-forever.com/yagcd/chap5.html#sec5.10 */ -volatile u32 AI_HW_REGS[] : 0xCD006C00; +volatile u32 AI_HW_REGS[8] AT_ADDRESS(0xCD006C00); /** * Hardware register indexes diff --git a/include/rvl/GX/GXAttr.h b/include/rvl/GX/GXAttr.h index 2733c512..a67ff6c6 100644 --- a/include/rvl/GX/GXAttr.h +++ b/include/rvl/GX/GXAttr.h @@ -35,7 +35,7 @@ void GXSetVtxAttrFmtv(GXVtxFmt fmt, const GXVtxAttrFmtList *list); void GXGetVtxAttrFmt(GXVtxFmt fmt, GXAttr attr, GXCompCnt *compCnt, GXCompType *compType, u8 *shift); void GXGetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList *list); -void GXSetArray(GXAttr attr, u32 base, u8 stride); +void GXSetArray(GXAttr attr, const void *base, u8 stride); void GXInvalidateVtxCache(void); void GXSetTexCoordGen2( GXTexCoordID id, GXTexGenType type, GXTexGenSrc src, u32 texMtxIdx, GXBool normalize, u32 dualTexMtxIdx diff --git a/include/rvl/GX/GXHardware.h b/include/rvl/GX/GXHardware.h index b15d4b0e..99de19a9 100644 --- a/include/rvl/GX/GXHardware.h +++ b/include/rvl/GX/GXHardware.h @@ -1,15 +1,5 @@ -#ifndef RVL_SDK_GX_HARDWARE_H -#define RVL_SDK_GX_HARDWARE_H -#include "common.h" -#include "rvl/GX/GXTypes.h" - - -#ifdef __cplusplus -extern "C" { -#endif - /** - * Documentation from: + * For more details, see: * https://www.gc-forever.com/yagcd/chap8.html#sec8 * https://www.gc-forever.com/yagcd/chap5.html#sec5 * https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/VideoCommon/BPMemory.h @@ -21,6 +11,16 @@ extern "C" { * https://patents.google.com/patent/US6697074 */ +#ifndef RVL_SDK_GX_HARDWARE_H +#define RVL_SDK_GX_HARDWARE_H +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + /************************************************************ * * @@ -107,6 +107,9 @@ typedef enum { */ #define GX_BP_SET_OPCODE(cmd, opcode) (cmd) = GX_BITSET(cmd, 0, 8, (opcode)) +#define GX_BP_OPCODE_SHIFT 24 +#define GX_BP_CMD_SZ (sizeof(u8) + sizeof(u32)) + /************************************************************ * * @@ -123,6 +126,8 @@ typedef enum { WGPIPE.c = (addr); \ WGPIPE.i = (data); +#define GX_CP_CMD_SZ (sizeof(u8) + sizeof(u8) + sizeof(u32)) + /************************************************************ * * @@ -155,6 +160,8 @@ typedef enum { GX_XF_LOAD_REG_HDR(addr); \ WGPIPE.i = (data); +#define GX_XF_CMD_SZ (sizeof(u8) + sizeof(u32) + sizeof(u32)) + /** * Load immediate values into multiple XF registers */ @@ -170,24 +177,44 @@ typedef enum { * Enums for Tex0-Tex7 register fields */ typedef enum { - GX_XF_TEX_PROJ_ST, //! (s,t): texmul is 2x4 - GX_XF_TEX_PROJ_STQ //! (s,t,q): texmul is 3x4 + GX_XF_TEX_PROJ_ST, // (s,t): texmul is 2x4 + GX_XF_TEX_PROJ_STQ // (s,t,q): texmul is 3x4 } GXXfTexProj; typedef enum { - GX_XF_TEX_FORM_AB11, //! (A, B, 1.0, 1.0) (used for regular texture source) - GX_XF_TEX_FORM_ABC1 //! (A, B, C, 1.0) (used for geometry or normal source) + GX_XF_TEX_FORM_AB11, // (A, B, 1.0, 1.0) (used for regular texture source) + GX_XF_TEX_FORM_ABC1 // (A, B, C, 1.0) (used for geometry or normal source) } GXXfTexForm; typedef enum { - GX_XF_TG_REGULAR, //! Regular transformation (transform incoming data) - GX_XF_TG_BUMP, //! Texgen bump mapping - GX_XF_TG_CLR0, //! Color texgen: (s,t)=(r,g:b) (g and b are concatenated), - //! color0 - GX_XF_TG_CLR1 //! Color texgen: (s,t)=(r,g:b) (g and b are concatenated), - //! color 1 + GX_XF_TG_REGULAR, // Regular transformation (transform incoming data) + GX_XF_TG_BUMP, // Texgen bump mapping + + GX_XF_TG_CLR0, // Color texgen: (s,t)=(r,g:b) (g and b are concatenated), + // color0 + + GX_XF_TG_CLR1 // Color texgen: (s,t)=(r,g:b) (g and b are concatenated), + // color1 } GXXfTexGen; +/** + * Misc. hardware enums + */ +typedef enum { + GX_RAS_COLOR0A0, + GX_RAS_COLOR1A1, + GX_RAS_ALPHA_BUMP = 5, + GX_RAS_ALPHA_BUMPN, + GX_RAS_COLOR_ZERO, + + GX_RAS_MAX_CHANNEL +} GXRasChannelID; + +typedef enum { + GX_TEVREG_COLOR, + GX_TEVREG_KONST, +} GXTevRegType; + #ifdef __cplusplus } #endif diff --git a/include/rvl/GX/GXHardwareBP.h b/include/rvl/GX/GXHardwareBP.h index c11c5375..2e117738 100644 --- a/include/rvl/GX/GXHardwareBP.h +++ b/include/rvl/GX/GXHardwareBP.h @@ -1,7 +1,8 @@ #ifndef RVL_SDK_GX_HARDWARE_BP_H #define RVL_SDK_GX_HARDWARE_BP_H -#include "common.h" -#include "rvl/GX/GXTypes.h" +#include + +#include #ifdef __cplusplus extern "C" { @@ -233,743 +234,1640 @@ typedef enum { GX_BP_REG_SSMASK = 0xFE, } GX_BP_REG; -/** +/****************************************************************************** * BP register 0x0 - GenMode - */ + *****************************************************************************/ // NUMTEX [28:31] (4) - Active texture count -#define GX_BP_GENMODE_NUMTEX_ST 28 -#define GX_BP_GENMODE_NUMTEX_END 31 -#define GX_BP_GENMODE_NUMTEX_SZ 4 -#define GX_BP_GENMODE_NUMTEX_MASK (((1 << 4) - 1) << 31 - 31) -#define GX_BP_GET_GENMODE_NUMTEX(reg) GX_BITGET(reg, 28, 4) -#define GX_BP_SET_GENMODE_NUMTEX(reg, x) ((reg) = GX_BITSET(reg, 28, 4, x)) +/* start bit */ #define GX_BP_GENMODE_NUMTEX_B 28 +/* end bit */ #define GX_BP_GENMODE_NUMTEX_E 31 +/* bit size */ #define GX_BP_GENMODE_NUMTEX_SZ 4 + +/* raw mask */ #define GX_BP_GENMODE_NUMTEX_MASK (((1 << 4) - 1) << 31 - 31) +/* local mask */ #define GX_BP_GENMODE_NUMTEX_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_GENMODE_NUMTEX_SHIFT 0 + +/* get value */ #define GX_BP_GET_GENMODE_NUMTEX(reg) GX_BITGET((reg), 28, 4) +/* set value */ #define GX_BP_SET_GENMODE_NUMTEX(reg, x) ((reg) = GX_BITSET((reg), 28, 4, x)) + // NUMCOLORS [25:27] (3) - Color/channel count -#define GX_BP_GENMODE_NUMCOLORS_ST 25 -#define GX_BP_GENMODE_NUMCOLORS_END 27 -#define GX_BP_GENMODE_NUMCOLORS_SZ 3 -#define GX_BP_GENMODE_NUMCOLORS_MASK (((1 << 3) - 1) << 31 - 27) -#define GX_BP_GET_GENMODE_NUMCOLORS(reg) GX_BITGET(reg, 25, 3) -#define GX_BP_SET_GENMODE_NUMCOLORS(reg, x) ((reg) = GX_BITSET(reg, 25, 3, x)) +/* start bit */ #define GX_BP_GENMODE_NUMCOLORS_B 25 +/* end bit */ #define GX_BP_GENMODE_NUMCOLORS_E 27 +/* bit size */ #define GX_BP_GENMODE_NUMCOLORS_SZ 3 + +/* raw mask */ #define GX_BP_GENMODE_NUMCOLORS_MASK (((1 << 3) - 1) << 31 - 27) +/* local mask */ #define GX_BP_GENMODE_NUMCOLORS_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_GENMODE_NUMCOLORS_SHIFT 4 + +/* get value */ #define GX_BP_GET_GENMODE_NUMCOLORS(reg) GX_BITGET((reg), 25, 3) +/* set value */ #define GX_BP_SET_GENMODE_NUMCOLORS(reg, x) ((reg) = GX_BITSET((reg), 25, 3, x)) + // MULTISAMPLE [22:22] (1) -#define GX_BP_GENMODE_MULTISAMPLE_ST 22 -#define GX_BP_GENMODE_MULTISAMPLE_END 22 -#define GX_BP_GENMODE_MULTISAMPLE_SZ 1 -#define GX_BP_GENMODE_MULTISAMPLE_MASK (((1 << 1) - 1) << 31 - 22) -#define GX_BP_GET_GENMODE_MULTISAMPLE(reg) GX_BITGET(reg, 22, 1) -#define GX_BP_SET_GENMODE_MULTISAMPLE(reg, x) ((reg) = GX_BITSET(reg, 22, 1, x)) +/* start bit */ #define GX_BP_GENMODE_MULTISAMPLE_B 22 +/* end bit */ #define GX_BP_GENMODE_MULTISAMPLE_E 22 +/* bit size */ #define GX_BP_GENMODE_MULTISAMPLE_SZ 1 + +/* raw mask */ #define GX_BP_GENMODE_MULTISAMPLE_MASK (((1 << 1) - 1) << 31 - 22) +/* local mask */ #define GX_BP_GENMODE_MULTISAMPLE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_GENMODE_MULTISAMPLE_SHIFT 9 + +/* get value */ #define GX_BP_GET_GENMODE_MULTISAMPLE(reg) GX_BITGET((reg), 22, 1) +/* set value */ #define GX_BP_SET_GENMODE_MULTISAMPLE(reg, x) ((reg) = GX_BITSET((reg), 22, 1, x)) + +// NUMTEVSTAGES [18:21] (4) +/* start bit */ #define GX_BP_GENMODE_NUMTEVSTAGES_B 18 +/* end bit */ #define GX_BP_GENMODE_NUMTEVSTAGES_E 21 +/* bit size */ #define GX_BP_GENMODE_NUMTEVSTAGES_SZ 4 + +/* raw mask */ #define GX_BP_GENMODE_NUMTEVSTAGES_MASK (((1 << 4) - 1) << 31 - 21) +/* local mask */ #define GX_BP_GENMODE_NUMTEVSTAGES_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_GENMODE_NUMTEVSTAGES_SHIFT 10 + +/* get value */ #define GX_BP_GET_GENMODE_NUMTEVSTAGES(reg) GX_BITGET((reg), 18, 4) +/* set value */ #define GX_BP_SET_GENMODE_NUMTEVSTAGES(reg, x) ((reg) = GX_BITSET((reg), 18, 4, x)) + // CULLMODE [16:17] (2) -#define GX_BP_GENMODE_CULLMODE_ST 16 -#define GX_BP_GENMODE_CULLMODE_END 17 -#define GX_BP_GENMODE_CULLMODE_SZ 2 -#define GX_BP_GENMODE_CULLMODE_MASK (((1 << 2) - 1) << 31 - 17) -#define GX_BP_GET_GENMODE_CULLMODE(reg) GX_BITGET(reg, 16, 2) -#define GX_BP_SET_GENMODE_CULLMODE(reg, x) ((reg) = GX_BITSET(reg, 16, 2, x)) +/* start bit */ #define GX_BP_GENMODE_CULLMODE_B 16 +/* end bit */ #define GX_BP_GENMODE_CULLMODE_E 17 +/* bit size */ #define GX_BP_GENMODE_CULLMODE_SZ 2 + +/* raw mask */ #define GX_BP_GENMODE_CULLMODE_MASK (((1 << 2) - 1) << 31 - 17) +/* local mask */ #define GX_BP_GENMODE_CULLMODE_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_GENMODE_CULLMODE_SHIFT 14 + +/* get value */ #define GX_BP_GET_GENMODE_CULLMODE(reg) GX_BITGET((reg), 16, 2) +/* set value */ #define GX_BP_SET_GENMODE_CULLMODE(reg, x) ((reg) = GX_BITSET((reg), 16, 2, x)) + // NUMINDSTAGES [13:15] (3) -#define GX_BP_GENMODE_NUMINDSTAGES_ST 13 -#define GX_BP_GENMODE_NUMINDSTAGES_END 15 -#define GX_BP_GENMODE_NUMINDSTAGES_SZ 3 -#define GX_BP_GENMODE_NUMINDSTAGES_MASK (((1 << 3) - 1) << 31 - 15) -#define GX_BP_GET_GENMODE_NUMINDSTAGES(reg) GX_BITGET(reg, 13, 3) -#define GX_BP_SET_GENMODE_NUMINDSTAGES(reg, x) ((reg) = GX_BITSET(reg, 13, 3, x)) +/* start bit */ #define GX_BP_GENMODE_NUMINDSTAGES_B 13 +/* end bit */ #define GX_BP_GENMODE_NUMINDSTAGES_E 15 +/* bit size */ #define GX_BP_GENMODE_NUMINDSTAGES_SZ 3 + +/* raw mask */ #define GX_BP_GENMODE_NUMINDSTAGES_MASK (((1 << 3) - 1) << 31 - 15) +/* local mask */ #define GX_BP_GENMODE_NUMINDSTAGES_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_GENMODE_NUMINDSTAGES_SHIFT 16 + +/* get value */ #define GX_BP_GET_GENMODE_NUMINDSTAGES(reg) GX_BITGET((reg), 13, 3) +/* set value */ #define GX_BP_SET_GENMODE_NUMINDSTAGES(reg, x) ((reg) = GX_BITSET((reg), 13, 3, x)) + // COPLANAR [12:12] (1) - Toggle co-planar ("Z freeze" according to Dolphin) -#define GX_BP_GENMODE_COPLANAR_ST 12 -#define GX_BP_GENMODE_COPLANAR_END 12 -#define GX_BP_GENMODE_COPLANAR_SZ 1 -#define GX_BP_GENMODE_COPLANAR_MASK (((1 << 1) - 1) << 31 - 12) -#define GX_BP_GET_GENMODE_COPLANAR(reg) GX_BITGET(reg, 12, 1) -#define GX_BP_SET_GENMODE_COPLANAR(reg, x) ((reg) = GX_BITSET(reg, 12, 1, x)) +/* start bit */ #define GX_BP_GENMODE_COPLANAR_B 12 +/* end bit */ #define GX_BP_GENMODE_COPLANAR_E 12 +/* bit size */ #define GX_BP_GENMODE_COPLANAR_SZ 1 -/** +/* raw mask */ #define GX_BP_GENMODE_COPLANAR_MASK (((1 << 1) - 1) << 31 - 12) +/* local mask */ #define GX_BP_GENMODE_COPLANAR_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_GENMODE_COPLANAR_SHIFT 19 + +/* get value */ #define GX_BP_GET_GENMODE_COPLANAR(reg) GX_BITGET((reg), 12, 1) +/* set value */ #define GX_BP_SET_GENMODE_COPLANAR(reg, x) ((reg) = GX_BITSET((reg), 12, 1, x)) + +/****************************************************************************** * BP structure - IndMtxA - */ + *****************************************************************************/ // M00 [21:31] (11) - Texture offset matrix #0 [0][0] -#define GX_BP_INDMTXA_M00_ST 21 -#define GX_BP_INDMTXA_M00_END 31 -#define GX_BP_INDMTXA_M00_SZ 11 -#define GX_BP_INDMTXA_M00_MASK (((1 << 11) - 1) << 31 - 31) -#define GX_BP_GET_INDMTXA_M00(reg) GX_BITGET(reg, 21, 11) -#define GX_BP_SET_INDMTXA_M00(reg, x) ((reg) = GX_BITSET(reg, 21, 11, x)) +/* start bit */ #define GX_BP_INDMTXA_M00_B 21 +/* end bit */ #define GX_BP_INDMTXA_M00_E 31 +/* bit size */ #define GX_BP_INDMTXA_M00_SZ 11 + +/* raw mask */ #define GX_BP_INDMTXA_M00_MASK (((1 << 11) - 1) << 31 - 31) +/* local mask */ #define GX_BP_INDMTXA_M00_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_INDMTXA_M00_SHIFT 0 + +/* get value */ #define GX_BP_GET_INDMTXA_M00(reg) GX_BITGET((reg), 21, 11) +/* set value */ #define GX_BP_SET_INDMTXA_M00(reg, x) ((reg) = GX_BITSET((reg), 21, 11, x)) + // M10 [10:20] (11) - Texture offset matrix #0 [1][0] -#define GX_BP_INDMTXA_M10_ST 10 -#define GX_BP_INDMTXA_M10_END 20 -#define GX_BP_INDMTXA_M10_SZ 11 -#define GX_BP_INDMTXA_M10_MASK (((1 << 11) - 1) << 31 - 20) -#define GX_BP_GET_INDMTXA_M10(reg) GX_BITGET(reg, 10, 11) -#define GX_BP_SET_INDMTXA_M10(reg, x) ((reg) = GX_BITSET(reg, 10, 11, x)) +/* start bit */ #define GX_BP_INDMTXA_M10_B 10 +/* end bit */ #define GX_BP_INDMTXA_M10_E 20 +/* bit size */ #define GX_BP_INDMTXA_M10_SZ 11 + +/* raw mask */ #define GX_BP_INDMTXA_M10_MASK (((1 << 11) - 1) << 31 - 20) +/* local mask */ #define GX_BP_INDMTXA_M10_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_INDMTXA_M10_SHIFT 11 + +/* get value */ #define GX_BP_GET_INDMTXA_M10(reg) GX_BITGET((reg), 10, 11) +/* set value */ #define GX_BP_SET_INDMTXA_M10(reg, x) ((reg) = GX_BITSET((reg), 10, 11, x)) + // EXP [8:9] (2) - Bits 0-1 of scaling exponent #0 (2^x) -#define GX_BP_INDMTXA_EXP_ST 8 -#define GX_BP_INDMTXA_EXP_END 9 -#define GX_BP_INDMTXA_EXP_SZ 2 -#define GX_BP_INDMTXA_EXP_MASK (((1 << 2) - 1) << 31 - 9) -#define GX_BP_GET_INDMTXA_EXP(reg) GX_BITGET(reg, 8, 2) -#define GX_BP_SET_INDMTXA_EXP(reg, x) ((reg) = GX_BITSET(reg, 8, 2, x)) +/* start bit */ #define GX_BP_INDMTXA_EXP_B 8 +/* end bit */ #define GX_BP_INDMTXA_EXP_E 9 +/* bit size */ #define GX_BP_INDMTXA_EXP_SZ 2 -/** +/* raw mask */ #define GX_BP_INDMTXA_EXP_MASK (((1 << 2) - 1) << 31 - 9) +/* local mask */ #define GX_BP_INDMTXA_EXP_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_INDMTXA_EXP_SHIFT 22 + +/* get value */ #define GX_BP_GET_INDMTXA_EXP(reg) GX_BITGET((reg), 8, 2) +/* set value */ #define GX_BP_SET_INDMTXA_EXP(reg, x) ((reg) = GX_BITSET((reg), 8, 2, x)) + +/****************************************************************************** * BP structure - IndMtxB - */ + *****************************************************************************/ // M01 [21:31] (11) - Texture offset matrix #0 [0][1] -#define GX_BP_INDMTXB_M01_ST 21 -#define GX_BP_INDMTXB_M01_END 31 -#define GX_BP_INDMTXB_M01_SZ 11 -#define GX_BP_INDMTXB_M01_MASK (((1 << 11) - 1) << 31 - 31) -#define GX_BP_GET_INDMTXB_M01(reg) GX_BITGET(reg, 21, 11) -#define GX_BP_SET_INDMTXB_M01(reg, x) ((reg) = GX_BITSET(reg, 21, 11, x)) +/* start bit */ #define GX_BP_INDMTXB_M01_B 21 +/* end bit */ #define GX_BP_INDMTXB_M01_E 31 +/* bit size */ #define GX_BP_INDMTXB_M01_SZ 11 + +/* raw mask */ #define GX_BP_INDMTXB_M01_MASK (((1 << 11) - 1) << 31 - 31) +/* local mask */ #define GX_BP_INDMTXB_M01_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_INDMTXB_M01_SHIFT 0 + +/* get value */ #define GX_BP_GET_INDMTXB_M01(reg) GX_BITGET((reg), 21, 11) +/* set value */ #define GX_BP_SET_INDMTXB_M01(reg, x) ((reg) = GX_BITSET((reg), 21, 11, x)) + // M11 [10:20] (11) - Texture offset matrix #0 [1][1] -#define GX_BP_INDMTXB_M11_ST 10 -#define GX_BP_INDMTXB_M11_END 20 -#define GX_BP_INDMTXB_M11_SZ 11 -#define GX_BP_INDMTXB_M11_MASK (((1 << 11) - 1) << 31 - 20) -#define GX_BP_GET_INDMTXB_M11(reg) GX_BITGET(reg, 10, 11) -#define GX_BP_SET_INDMTXB_M11(reg, x) ((reg) = GX_BITSET(reg, 10, 11, x)) +/* start bit */ #define GX_BP_INDMTXB_M11_B 10 +/* end bit */ #define GX_BP_INDMTXB_M11_E 20 +/* bit size */ #define GX_BP_INDMTXB_M11_SZ 11 + +/* raw mask */ #define GX_BP_INDMTXB_M11_MASK (((1 << 11) - 1) << 31 - 20) +/* local mask */ #define GX_BP_INDMTXB_M11_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_INDMTXB_M11_SHIFT 11 + +/* get value */ #define GX_BP_GET_INDMTXB_M11(reg) GX_BITGET((reg), 10, 11) +/* set value */ #define GX_BP_SET_INDMTXB_M11(reg, x) ((reg) = GX_BITSET((reg), 10, 11, x)) + // EXP [8:9] (2) - Bits 2-3 of scaling exponent #0 (2^x) -#define GX_BP_INDMTXB_EXP_ST 8 -#define GX_BP_INDMTXB_EXP_END 9 -#define GX_BP_INDMTXB_EXP_SZ 2 -#define GX_BP_INDMTXB_EXP_MASK (((1 << 2) - 1) << 31 - 9) -#define GX_BP_GET_INDMTXB_EXP(reg) GX_BITGET(reg, 8, 2) -#define GX_BP_SET_INDMTXB_EXP(reg, x) ((reg) = GX_BITSET(reg, 8, 2, x)) +/* start bit */ #define GX_BP_INDMTXB_EXP_B 8 +/* end bit */ #define GX_BP_INDMTXB_EXP_E 9 +/* bit size */ #define GX_BP_INDMTXB_EXP_SZ 2 -/** +/* raw mask */ #define GX_BP_INDMTXB_EXP_MASK (((1 << 2) - 1) << 31 - 9) +/* local mask */ #define GX_BP_INDMTXB_EXP_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_INDMTXB_EXP_SHIFT 22 + +/* get value */ #define GX_BP_GET_INDMTXB_EXP(reg) GX_BITGET((reg), 8, 2) +/* set value */ #define GX_BP_SET_INDMTXB_EXP(reg, x) ((reg) = GX_BITSET((reg), 8, 2, x)) + +/****************************************************************************** * BP structure - IndMtxC - */ + *****************************************************************************/ // M02 [21:31] (11) - Texture offset matrix #0 [0][2] -#define GX_BP_INDMTXC_M02_ST 21 -#define GX_BP_INDMTXC_M02_END 31 -#define GX_BP_INDMTXC_M02_SZ 11 -#define GX_BP_INDMTXC_M02_MASK (((1 << 11) - 1) << 31 - 31) -#define GX_BP_GET_INDMTXC_M02(reg) GX_BITGET(reg, 21, 11) -#define GX_BP_SET_INDMTXC_M02(reg, x) ((reg) = GX_BITSET(reg, 21, 11, x)) +/* start bit */ #define GX_BP_INDMTXC_M02_B 21 +/* end bit */ #define GX_BP_INDMTXC_M02_E 31 +/* bit size */ #define GX_BP_INDMTXC_M02_SZ 11 + +/* raw mask */ #define GX_BP_INDMTXC_M02_MASK (((1 << 11) - 1) << 31 - 31) +/* local mask */ #define GX_BP_INDMTXC_M02_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_INDMTXC_M02_SHIFT 0 + +/* get value */ #define GX_BP_GET_INDMTXC_M02(reg) GX_BITGET((reg), 21, 11) +/* set value */ #define GX_BP_SET_INDMTXC_M02(reg, x) ((reg) = GX_BITSET((reg), 21, 11, x)) + // M12 [10:20] (11) - Texture offset matrix #0 [1][2] -#define GX_BP_INDMTXC_M12_ST 10 -#define GX_BP_INDMTXC_M12_END 20 -#define GX_BP_INDMTXC_M12_SZ 11 -#define GX_BP_INDMTXC_M12_MASK (((1 << 11) - 1) << 31 - 20) -#define GX_BP_GET_INDMTXC_M12(reg) GX_BITGET(reg, 10, 11) -#define GX_BP_SET_INDMTXC_M12(reg, x) ((reg) = GX_BITSET(reg, 10, 11, x)) +/* start bit */ #define GX_BP_INDMTXC_M12_B 10 +/* end bit */ #define GX_BP_INDMTXC_M12_E 20 +/* bit size */ #define GX_BP_INDMTXC_M12_SZ 11 + +/* raw mask */ #define GX_BP_INDMTXC_M12_MASK (((1 << 11) - 1) << 31 - 20) +/* local mask */ #define GX_BP_INDMTXC_M12_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_INDMTXC_M12_SHIFT 11 + +/* get value */ #define GX_BP_GET_INDMTXC_M12(reg) GX_BITGET((reg), 10, 11) +/* set value */ #define GX_BP_SET_INDMTXC_M12(reg, x) ((reg) = GX_BITSET((reg), 10, 11, x)) + // EXP [8:9] (2) - Bit 4 of scaling exponent #0 (2^x) -#define GX_BP_INDMTXC_EXP_ST 8 -#define GX_BP_INDMTXC_EXP_END 9 -#define GX_BP_INDMTXC_EXP_SZ 2 -#define GX_BP_INDMTXC_EXP_MASK (((1 << 2) - 1) << 31 - 9) -#define GX_BP_GET_INDMTXC_EXP(reg) GX_BITGET(reg, 8, 2) -#define GX_BP_SET_INDMTXC_EXP(reg, x) ((reg) = GX_BITSET(reg, 8, 2, x)) +/* start bit */ #define GX_BP_INDMTXC_EXP_B 8 +/* end bit */ #define GX_BP_INDMTXC_EXP_E 9 +/* bit size */ #define GX_BP_INDMTXC_EXP_SZ 2 -/** +/* raw mask */ #define GX_BP_INDMTXC_EXP_MASK (((1 << 2) - 1) << 31 - 9) +/* local mask */ #define GX_BP_INDMTXC_EXP_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_INDMTXC_EXP_SHIFT 22 + +/* get value */ #define GX_BP_GET_INDMTXC_EXP(reg) GX_BITGET((reg), 8, 2) +/* set value */ #define GX_BP_SET_INDMTXC_EXP(reg, x) ((reg) = GX_BITSET((reg), 8, 2, x)) + +/****************************************************************************** * BP register 0xF - IndIMask - */ + *****************************************************************************/ // IMASK [24:31] (8) - Indirect mask for textures -#define GX_BP_INDIMASK_IMASK_ST 24 -#define GX_BP_INDIMASK_IMASK_END 31 -#define GX_BP_INDIMASK_IMASK_SZ 8 -#define GX_BP_INDIMASK_IMASK_MASK (((1 << 8) - 1) << 31 - 31) -#define GX_BP_GET_INDIMASK_IMASK(reg) GX_BITGET(reg, 24, 8) -#define GX_BP_SET_INDIMASK_IMASK(reg, x) ((reg) = GX_BITSET(reg, 24, 8, x)) +/* start bit */ #define GX_BP_INDIMASK_IMASK_B 24 +/* end bit */ #define GX_BP_INDIMASK_IMASK_E 31 +/* bit size */ #define GX_BP_INDIMASK_IMASK_SZ 8 -/** +/* raw mask */ #define GX_BP_INDIMASK_IMASK_MASK (((1 << 8) - 1) << 31 - 31) +/* local mask */ #define GX_BP_INDIMASK_IMASK_LMASK ((1 << 8) - 1) +/* bit shift */ #define GX_BP_INDIMASK_IMASK_SHIFT 0 + +/* get value */ #define GX_BP_GET_INDIMASK_IMASK(reg) GX_BITGET((reg), 24, 8) +/* set value */ #define GX_BP_SET_INDIMASK_IMASK(reg, x) ((reg) = GX_BITSET((reg), 24, 8, x)) + +/****************************************************************************** * BP structure - IndTevStage - */ + *****************************************************************************/ // STAGE [30:31] (2) - Indirect texture stage ID -#define GX_BP_INDTEVSTAGE_STAGE_ST 30 -#define GX_BP_INDTEVSTAGE_STAGE_END 31 -#define GX_BP_INDTEVSTAGE_STAGE_SZ 2 -#define GX_BP_INDTEVSTAGE_STAGE_MASK (((1 << 2) - 1) << 31 - 31) -#define GX_BP_GET_INDTEVSTAGE_STAGE(reg) GX_BITGET(reg, 30, 2) -#define GX_BP_SET_INDTEVSTAGE_STAGE(reg, x) ((reg) = GX_BITSET(reg, 30, 2, x)) +/* start bit */ #define GX_BP_INDTEVSTAGE_STAGE_B 30 +/* end bit */ #define GX_BP_INDTEVSTAGE_STAGE_E 31 +/* bit size */ #define GX_BP_INDTEVSTAGE_STAGE_SZ 2 + +/* raw mask */ #define GX_BP_INDTEVSTAGE_STAGE_MASK (((1 << 2) - 1) << 31 - 31) +/* local mask */ #define GX_BP_INDTEVSTAGE_STAGE_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_INDTEVSTAGE_STAGE_SHIFT 0 + +/* get value */ #define GX_BP_GET_INDTEVSTAGE_STAGE(reg) GX_BITGET((reg), 30, 2) +/* set value */ #define GX_BP_SET_INDTEVSTAGE_STAGE(reg, x) ((reg) = GX_BITSET((reg), 30, 2, x)) + // FORMAT [28:29] (2) - Indirect texture format -#define GX_BP_INDTEVSTAGE_FORMAT_ST 28 -#define GX_BP_INDTEVSTAGE_FORMAT_END 29 -#define GX_BP_INDTEVSTAGE_FORMAT_SZ 2 -#define GX_BP_INDTEVSTAGE_FORMAT_MASK (((1 << 2) - 1) << 31 - 29) -#define GX_BP_GET_INDTEVSTAGE_FORMAT(reg) GX_BITGET(reg, 28, 2) -#define GX_BP_SET_INDTEVSTAGE_FORMAT(reg, x) ((reg) = GX_BITSET(reg, 28, 2, x)) +/* start bit */ #define GX_BP_INDTEVSTAGE_FORMAT_B 28 +/* end bit */ #define GX_BP_INDTEVSTAGE_FORMAT_E 29 +/* bit size */ #define GX_BP_INDTEVSTAGE_FORMAT_SZ 2 + +/* raw mask */ #define GX_BP_INDTEVSTAGE_FORMAT_MASK (((1 << 2) - 1) << 31 - 29) +/* local mask */ #define GX_BP_INDTEVSTAGE_FORMAT_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_INDTEVSTAGE_FORMAT_SHIFT 2 + +/* get value */ #define GX_BP_GET_INDTEVSTAGE_FORMAT(reg) GX_BITGET((reg), 28, 2) +/* set value */ #define GX_BP_SET_INDTEVSTAGE_FORMAT(reg, x) ((reg) = GX_BITSET((reg), 28, 2, x)) + // BIAS [25:27] (3) - Indirect texture bias -#define GX_BP_INDTEVSTAGE_BIAS_ST 25 -#define GX_BP_INDTEVSTAGE_BIAS_END 27 -#define GX_BP_INDTEVSTAGE_BIAS_SZ 3 -#define GX_BP_INDTEVSTAGE_BIAS_MASK (((1 << 3) - 1) << 31 - 27) -#define GX_BP_GET_INDTEVSTAGE_BIAS(reg) GX_BITGET(reg, 25, 3) -#define GX_BP_SET_INDTEVSTAGE_BIAS(reg, x) ((reg) = GX_BITSET(reg, 25, 3, x)) +/* start bit */ #define GX_BP_INDTEVSTAGE_BIAS_B 25 +/* end bit */ #define GX_BP_INDTEVSTAGE_BIAS_E 27 +/* bit size */ #define GX_BP_INDTEVSTAGE_BIAS_SZ 3 + +/* raw mask */ #define GX_BP_INDTEVSTAGE_BIAS_MASK (((1 << 3) - 1) << 31 - 27) +/* local mask */ #define GX_BP_INDTEVSTAGE_BIAS_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_INDTEVSTAGE_BIAS_SHIFT 4 + +/* get value */ #define GX_BP_GET_INDTEVSTAGE_BIAS(reg) GX_BITGET((reg), 25, 3) +/* set value */ #define GX_BP_SET_INDTEVSTAGE_BIAS(reg, x) ((reg) = GX_BITSET((reg), 25, 3, x)) + // ALPHA [23:24] (2) - Indirect texture alpha -#define GX_BP_INDTEVSTAGE_ALPHA_ST 23 -#define GX_BP_INDTEVSTAGE_ALPHA_END 24 -#define GX_BP_INDTEVSTAGE_ALPHA_SZ 2 -#define GX_BP_INDTEVSTAGE_ALPHA_MASK (((1 << 2) - 1) << 31 - 24) -#define GX_BP_GET_INDTEVSTAGE_ALPHA(reg) GX_BITGET(reg, 23, 2) -#define GX_BP_SET_INDTEVSTAGE_ALPHA(reg, x) ((reg) = GX_BITSET(reg, 23, 2, x)) +/* start bit */ #define GX_BP_INDTEVSTAGE_ALPHA_B 23 +/* end bit */ #define GX_BP_INDTEVSTAGE_ALPHA_E 24 +/* bit size */ #define GX_BP_INDTEVSTAGE_ALPHA_SZ 2 + +/* raw mask */ #define GX_BP_INDTEVSTAGE_ALPHA_MASK (((1 << 2) - 1) << 31 - 24) +/* local mask */ #define GX_BP_INDTEVSTAGE_ALPHA_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_INDTEVSTAGE_ALPHA_SHIFT 7 + +/* get value */ #define GX_BP_GET_INDTEVSTAGE_ALPHA(reg) GX_BITGET((reg), 23, 2) +/* set value */ #define GX_BP_SET_INDTEVSTAGE_ALPHA(reg, x) ((reg) = GX_BITSET((reg), 23, 2, x)) + // MTX [19:22] (4) - Indirect texture matrix -#define GX_BP_INDTEVSTAGE_MTX_ST 19 -#define GX_BP_INDTEVSTAGE_MTX_END 22 -#define GX_BP_INDTEVSTAGE_MTX_SZ 4 -#define GX_BP_INDTEVSTAGE_MTX_MASK (((1 << 4) - 1) << 31 - 22) -#define GX_BP_GET_INDTEVSTAGE_MTX(reg) GX_BITGET(reg, 19, 4) -#define GX_BP_SET_INDTEVSTAGE_MTX(reg, x) ((reg) = GX_BITSET(reg, 19, 4, x)) +/* start bit */ #define GX_BP_INDTEVSTAGE_MTX_B 19 +/* end bit */ #define GX_BP_INDTEVSTAGE_MTX_E 22 +/* bit size */ #define GX_BP_INDTEVSTAGE_MTX_SZ 4 + +/* raw mask */ #define GX_BP_INDTEVSTAGE_MTX_MASK (((1 << 4) - 1) << 31 - 22) +/* local mask */ #define GX_BP_INDTEVSTAGE_MTX_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_INDTEVSTAGE_MTX_SHIFT 9 + +/* get value */ #define GX_BP_GET_INDTEVSTAGE_MTX(reg) GX_BITGET((reg), 19, 4) +/* set value */ #define GX_BP_SET_INDTEVSTAGE_MTX(reg, x) ((reg) = GX_BITSET((reg), 19, 4, x)) + // WRAPS [16:18] (3) - S component wrap factor -#define GX_BP_INDTEVSTAGE_WRAPS_ST 16 -#define GX_BP_INDTEVSTAGE_WRAPS_END 18 -#define GX_BP_INDTEVSTAGE_WRAPS_SZ 3 -#define GX_BP_INDTEVSTAGE_WRAPS_MASK (((1 << 3) - 1) << 31 - 18) -#define GX_BP_GET_INDTEVSTAGE_WRAPS(reg) GX_BITGET(reg, 16, 3) -#define GX_BP_SET_INDTEVSTAGE_WRAPS(reg, x) ((reg) = GX_BITSET(reg, 16, 3, x)) +/* start bit */ #define GX_BP_INDTEVSTAGE_WRAPS_B 16 +/* end bit */ #define GX_BP_INDTEVSTAGE_WRAPS_E 18 +/* bit size */ #define GX_BP_INDTEVSTAGE_WRAPS_SZ 3 + +/* raw mask */ #define GX_BP_INDTEVSTAGE_WRAPS_MASK (((1 << 3) - 1) << 31 - 18) +/* local mask */ #define GX_BP_INDTEVSTAGE_WRAPS_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_INDTEVSTAGE_WRAPS_SHIFT 13 + +/* get value */ #define GX_BP_GET_INDTEVSTAGE_WRAPS(reg) GX_BITGET((reg), 16, 3) +/* set value */ #define GX_BP_SET_INDTEVSTAGE_WRAPS(reg, x) ((reg) = GX_BITSET((reg), 16, 3, x)) + // WRAPT [13:15] (3) - T component wrap factor -#define GX_BP_INDTEVSTAGE_WRAPT_ST 13 -#define GX_BP_INDTEVSTAGE_WRAPT_END 15 -#define GX_BP_INDTEVSTAGE_WRAPT_SZ 3 -#define GX_BP_INDTEVSTAGE_WRAPT_MASK (((1 << 3) - 1) << 31 - 15) -#define GX_BP_GET_INDTEVSTAGE_WRAPT(reg) GX_BITGET(reg, 13, 3) -#define GX_BP_SET_INDTEVSTAGE_WRAPT(reg, x) ((reg) = GX_BITSET(reg, 13, 3, x)) +/* start bit */ #define GX_BP_INDTEVSTAGE_WRAPT_B 13 +/* end bit */ #define GX_BP_INDTEVSTAGE_WRAPT_E 15 +/* bit size */ #define GX_BP_INDTEVSTAGE_WRAPT_SZ 3 + +/* raw mask */ #define GX_BP_INDTEVSTAGE_WRAPT_MASK (((1 << 3) - 1) << 31 - 15) +/* local mask */ #define GX_BP_INDTEVSTAGE_WRAPT_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_INDTEVSTAGE_WRAPT_SHIFT 16 + +/* get value */ #define GX_BP_GET_INDTEVSTAGE_WRAPT(reg) GX_BITGET((reg), 13, 3) +/* set value */ #define GX_BP_SET_INDTEVSTAGE_WRAPT(reg, x) ((reg) = GX_BITSET((reg), 13, 3, x)) + // UTCLOD [12:12] (1) - Whether to use unmodified texcoords for mipmaps -#define GX_BP_INDTEVSTAGE_UTCLOD_ST 12 -#define GX_BP_INDTEVSTAGE_UTCLOD_END 12 -#define GX_BP_INDTEVSTAGE_UTCLOD_SZ 1 -#define GX_BP_INDTEVSTAGE_UTCLOD_MASK (((1 << 1) - 1) << 31 - 12) -#define GX_BP_GET_INDTEVSTAGE_UTCLOD(reg) GX_BITGET(reg, 12, 1) -#define GX_BP_SET_INDTEVSTAGE_UTCLOD(reg, x) ((reg) = GX_BITSET(reg, 12, 1, x)) +/* start bit */ #define GX_BP_INDTEVSTAGE_UTCLOD_B 12 +/* end bit */ #define GX_BP_INDTEVSTAGE_UTCLOD_E 12 +/* bit size */ #define GX_BP_INDTEVSTAGE_UTCLOD_SZ 1 + +/* raw mask */ #define GX_BP_INDTEVSTAGE_UTCLOD_MASK (((1 << 1) - 1) << 31 - 12) +/* local mask */ #define GX_BP_INDTEVSTAGE_UTCLOD_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_INDTEVSTAGE_UTCLOD_SHIFT 19 + +/* get value */ #define GX_BP_GET_INDTEVSTAGE_UTCLOD(reg) GX_BITGET((reg), 12, 1) +/* set value */ #define GX_BP_SET_INDTEVSTAGE_UTCLOD(reg, x) ((reg) = GX_BITSET((reg), 12, 1, x)) + // ADDPREV [11:11] (1) - Whether to add in results from previous tev stage -#define GX_BP_INDTEVSTAGE_ADDPREV_ST 11 -#define GX_BP_INDTEVSTAGE_ADDPREV_END 11 -#define GX_BP_INDTEVSTAGE_ADDPREV_SZ 1 -#define GX_BP_INDTEVSTAGE_ADDPREV_MASK (((1 << 1) - 1) << 31 - 11) -#define GX_BP_GET_INDTEVSTAGE_ADDPREV(reg) GX_BITGET(reg, 11, 1) -#define GX_BP_SET_INDTEVSTAGE_ADDPREV(reg, x) ((reg) = GX_BITSET(reg, 11, 1, x)) +/* start bit */ #define GX_BP_INDTEVSTAGE_ADDPREV_B 11 +/* end bit */ #define GX_BP_INDTEVSTAGE_ADDPREV_E 11 +/* bit size */ #define GX_BP_INDTEVSTAGE_ADDPREV_SZ 1 -/** +/* raw mask */ #define GX_BP_INDTEVSTAGE_ADDPREV_MASK (((1 << 1) - 1) << 31 - 11) +/* local mask */ #define GX_BP_INDTEVSTAGE_ADDPREV_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_INDTEVSTAGE_ADDPREV_SHIFT 20 + +/* get value */ #define GX_BP_GET_INDTEVSTAGE_ADDPREV(reg) GX_BITGET((reg), 11, 1) +/* set value */ #define GX_BP_SET_INDTEVSTAGE_ADDPREV(reg, x) ((reg) = GX_BITSET((reg), 11, 1, x)) + +/****************************************************************************** * BP register 0x20 - scissorTL - */ + *****************************************************************************/ // TOP [21:31] (11) - Top component -#define GX_BP_SCISSORTL_TOP_ST 21 -#define GX_BP_SCISSORTL_TOP_END 31 -#define GX_BP_SCISSORTL_TOP_SZ 11 -#define GX_BP_SCISSORTL_TOP_MASK (((1 << 11) - 1) << 31 - 31) -#define GX_BP_GET_SCISSORTL_TOP(reg) GX_BITGET(reg, 21, 11) -#define GX_BP_SET_SCISSORTL_TOP(reg, x) ((reg) = GX_BITSET(reg, 21, 11, x)) +/* start bit */ #define GX_BP_SCISSORTL_TOP_B 21 +/* end bit */ #define GX_BP_SCISSORTL_TOP_E 31 +/* bit size */ #define GX_BP_SCISSORTL_TOP_SZ 11 + +/* raw mask */ #define GX_BP_SCISSORTL_TOP_MASK (((1 << 11) - 1) << 31 - 31) +/* local mask */ #define GX_BP_SCISSORTL_TOP_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_SCISSORTL_TOP_SHIFT 0 + +/* get value */ #define GX_BP_GET_SCISSORTL_TOP(reg) GX_BITGET((reg), 21, 11) +/* set value */ #define GX_BP_SET_SCISSORTL_TOP(reg, x) ((reg) = GX_BITSET((reg), 21, 11, x)) + // LEFT [9:19] (11) - Left component -#define GX_BP_SCISSORTL_LEFT_ST 9 -#define GX_BP_SCISSORTL_LEFT_END 19 -#define GX_BP_SCISSORTL_LEFT_SZ 11 -#define GX_BP_SCISSORTL_LEFT_MASK (((1 << 11) - 1) << 31 - 19) -#define GX_BP_GET_SCISSORTL_LEFT(reg) GX_BITGET(reg, 9, 11) -#define GX_BP_SET_SCISSORTL_LEFT(reg, x) ((reg) = GX_BITSET(reg, 9, 11, x)) +/* start bit */ #define GX_BP_SCISSORTL_LEFT_B 9 +/* end bit */ #define GX_BP_SCISSORTL_LEFT_E 19 +/* bit size */ #define GX_BP_SCISSORTL_LEFT_SZ 11 -/** +/* raw mask */ #define GX_BP_SCISSORTL_LEFT_MASK (((1 << 11) - 1) << 31 - 19) +/* local mask */ #define GX_BP_SCISSORTL_LEFT_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_SCISSORTL_LEFT_SHIFT 12 + +/* get value */ #define GX_BP_GET_SCISSORTL_LEFT(reg) GX_BITGET((reg), 9, 11) +/* set value */ #define GX_BP_SET_SCISSORTL_LEFT(reg, x) ((reg) = GX_BITSET((reg), 9, 11, x)) + +/****************************************************************************** * BP register 0x21 - scissorBR - */ + *****************************************************************************/ // BOT [21:31] (11) - Bottom component -#define GX_BP_SCISSORBR_BOT_ST 21 -#define GX_BP_SCISSORBR_BOT_END 31 -#define GX_BP_SCISSORBR_BOT_SZ 11 -#define GX_BP_SCISSORBR_BOT_MASK (((1 << 11) - 1) << 31 - 31) -#define GX_BP_GET_SCISSORBR_BOT(reg) GX_BITGET(reg, 21, 11) -#define GX_BP_SET_SCISSORBR_BOT(reg, x) ((reg) = GX_BITSET(reg, 21, 11, x)) +/* start bit */ #define GX_BP_SCISSORBR_BOT_B 21 +/* end bit */ #define GX_BP_SCISSORBR_BOT_E 31 +/* bit size */ #define GX_BP_SCISSORBR_BOT_SZ 11 + +/* raw mask */ #define GX_BP_SCISSORBR_BOT_MASK (((1 << 11) - 1) << 31 - 31) +/* local mask */ #define GX_BP_SCISSORBR_BOT_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_SCISSORBR_BOT_SHIFT 0 + +/* get value */ #define GX_BP_GET_SCISSORBR_BOT(reg) GX_BITGET((reg), 21, 11) +/* set value */ #define GX_BP_SET_SCISSORBR_BOT(reg, x) ((reg) = GX_BITSET((reg), 21, 11, x)) + // RIGHT [9:19] (11) - Right component -#define GX_BP_SCISSORBR_RIGHT_ST 9 -#define GX_BP_SCISSORBR_RIGHT_END 19 -#define GX_BP_SCISSORBR_RIGHT_SZ 11 -#define GX_BP_SCISSORBR_RIGHT_MASK (((1 << 11) - 1) << 31 - 19) -#define GX_BP_GET_SCISSORBR_RIGHT(reg) GX_BITGET(reg, 9, 11) -#define GX_BP_SET_SCISSORBR_RIGHT(reg, x) ((reg) = GX_BITSET(reg, 9, 11, x)) +/* start bit */ #define GX_BP_SCISSORBR_RIGHT_B 9 +/* end bit */ #define GX_BP_SCISSORBR_RIGHT_E 19 +/* bit size */ #define GX_BP_SCISSORBR_RIGHT_SZ 11 -/** +/* raw mask */ #define GX_BP_SCISSORBR_RIGHT_MASK (((1 << 11) - 1) << 31 - 19) +/* local mask */ #define GX_BP_SCISSORBR_RIGHT_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_SCISSORBR_RIGHT_SHIFT 12 + +/* get value */ #define GX_BP_GET_SCISSORBR_RIGHT(reg) GX_BITGET((reg), 9, 11) +/* set value */ #define GX_BP_SET_SCISSORBR_RIGHT(reg, x) ((reg) = GX_BITSET((reg), 9, 11, x)) + +/****************************************************************************** * BP register 0x22 - linePtWidth - */ + *****************************************************************************/ // LINESZ [24:31] (8) - Line size/width -#define GX_BP_LINEPTWIDTH_LINESZ_ST 24 -#define GX_BP_LINEPTWIDTH_LINESZ_END 31 -#define GX_BP_LINEPTWIDTH_LINESZ_SZ 8 -#define GX_BP_LINEPTWIDTH_LINESZ_MASK (((1 << 8) - 1) << 31 - 31) -#define GX_BP_GET_LINEPTWIDTH_LINESZ(reg) GX_BITGET(reg, 24, 8) -#define GX_BP_SET_LINEPTWIDTH_LINESZ(reg, x) ((reg) = GX_BITSET(reg, 24, 8, x)) +/* start bit */ #define GX_BP_LINEPTWIDTH_LINESZ_B 24 +/* end bit */ #define GX_BP_LINEPTWIDTH_LINESZ_E 31 +/* bit size */ #define GX_BP_LINEPTWIDTH_LINESZ_SZ 8 + +/* raw mask */ #define GX_BP_LINEPTWIDTH_LINESZ_MASK (((1 << 8) - 1) << 31 - 31) +/* local mask */ #define GX_BP_LINEPTWIDTH_LINESZ_LMASK ((1 << 8) - 1) +/* bit shift */ #define GX_BP_LINEPTWIDTH_LINESZ_SHIFT 0 + +/* get value */ #define GX_BP_GET_LINEPTWIDTH_LINESZ(reg) GX_BITGET((reg), 24, 8) +/* set value */ #define GX_BP_SET_LINEPTWIDTH_LINESZ(reg, x) ((reg) = GX_BITSET((reg), 24, 8, x)) + // POINTSZ [16:23] (8) - Point size -#define GX_BP_LINEPTWIDTH_POINTSZ_ST 16 -#define GX_BP_LINEPTWIDTH_POINTSZ_END 23 -#define GX_BP_LINEPTWIDTH_POINTSZ_SZ 8 -#define GX_BP_LINEPTWIDTH_POINTSZ_MASK (((1 << 8) - 1) << 31 - 23) -#define GX_BP_GET_LINEPTWIDTH_POINTSZ(reg) GX_BITGET(reg, 16, 8) -#define GX_BP_SET_LINEPTWIDTH_POINTSZ(reg, x) ((reg) = GX_BITSET(reg, 16, 8, x)) +/* start bit */ #define GX_BP_LINEPTWIDTH_POINTSZ_B 16 +/* end bit */ #define GX_BP_LINEPTWIDTH_POINTSZ_E 23 +/* bit size */ #define GX_BP_LINEPTWIDTH_POINTSZ_SZ 8 + +/* raw mask */ #define GX_BP_LINEPTWIDTH_POINTSZ_MASK (((1 << 8) - 1) << 31 - 23) +/* local mask */ #define GX_BP_LINEPTWIDTH_POINTSZ_LMASK ((1 << 8) - 1) +/* bit shift */ #define GX_BP_LINEPTWIDTH_POINTSZ_SHIFT 8 + +/* get value */ #define GX_BP_GET_LINEPTWIDTH_POINTSZ(reg) GX_BITGET((reg), 16, 8) +/* set value */ #define GX_BP_SET_LINEPTWIDTH_POINTSZ(reg, x) ((reg) = GX_BITSET((reg), 16, 8, x)) + // LINEOFS [13:15] (3) - Line offset -#define GX_BP_LINEPTWIDTH_LINEOFS_ST 13 -#define GX_BP_LINEPTWIDTH_LINEOFS_END 15 -#define GX_BP_LINEPTWIDTH_LINEOFS_SZ 3 -#define GX_BP_LINEPTWIDTH_LINEOFS_MASK (((1 << 3) - 1) << 31 - 15) -#define GX_BP_GET_LINEPTWIDTH_LINEOFS(reg) GX_BITGET(reg, 13, 3) -#define GX_BP_SET_LINEPTWIDTH_LINEOFS(reg, x) ((reg) = GX_BITSET(reg, 13, 3, x)) +/* start bit */ #define GX_BP_LINEPTWIDTH_LINEOFS_B 13 +/* end bit */ #define GX_BP_LINEPTWIDTH_LINEOFS_E 15 +/* bit size */ #define GX_BP_LINEPTWIDTH_LINEOFS_SZ 3 + +/* raw mask */ #define GX_BP_LINEPTWIDTH_LINEOFS_MASK (((1 << 3) - 1) << 31 - 15) +/* local mask */ #define GX_BP_LINEPTWIDTH_LINEOFS_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_LINEPTWIDTH_LINEOFS_SHIFT 16 + +/* get value */ #define GX_BP_GET_LINEPTWIDTH_LINEOFS(reg) GX_BITGET((reg), 13, 3) +/* set value */ #define GX_BP_SET_LINEPTWIDTH_LINEOFS(reg, x) ((reg) = GX_BITSET((reg), 13, 3, x)) + // POINTOFS [10:12] (3) - Point offset -#define GX_BP_LINEPTWIDTH_POINTOFS_ST 10 -#define GX_BP_LINEPTWIDTH_POINTOFS_END 12 -#define GX_BP_LINEPTWIDTH_POINTOFS_SZ 3 -#define GX_BP_LINEPTWIDTH_POINTOFS_MASK (((1 << 3) - 1) << 31 - 12) -#define GX_BP_GET_LINEPTWIDTH_POINTOFS(reg) GX_BITGET(reg, 10, 3) -#define GX_BP_SET_LINEPTWIDTH_POINTOFS(reg, x) ((reg) = GX_BITSET(reg, 10, 3, x)) +/* start bit */ #define GX_BP_LINEPTWIDTH_POINTOFS_B 10 +/* end bit */ #define GX_BP_LINEPTWIDTH_POINTOFS_E 12 +/* bit size */ #define GX_BP_LINEPTWIDTH_POINTOFS_SZ 3 + +/* raw mask */ #define GX_BP_LINEPTWIDTH_POINTOFS_MASK (((1 << 3) - 1) << 31 - 12) +/* local mask */ #define GX_BP_LINEPTWIDTH_POINTOFS_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_LINEPTWIDTH_POINTOFS_SHIFT 19 + +/* get value */ #define GX_BP_GET_LINEPTWIDTH_POINTOFS(reg) GX_BITGET((reg), 10, 3) +/* set value */ #define GX_BP_SET_LINEPTWIDTH_POINTOFS(reg, x) ((reg) = GX_BITSET((reg), 10, 3, x)) + // ADJUST_AR [9:9] (1) - Interlacing: adjust for pixels having aspect ratio of 1/2 -#define GX_BP_LINEPTWIDTH_ADJUST_AR_ST 9 -#define GX_BP_LINEPTWIDTH_ADJUST_AR_END 9 -#define GX_BP_LINEPTWIDTH_ADJUST_AR_SZ 1 -#define GX_BP_LINEPTWIDTH_ADJUST_AR_MASK (((1 << 1) - 1) << 31 - 9) -#define GX_BP_GET_LINEPTWIDTH_ADJUST_AR(reg) GX_BITGET(reg, 9, 1) -#define GX_BP_SET_LINEPTWIDTH_ADJUST_AR(reg, x) ((reg) = GX_BITSET(reg, 9, 1, x)) +/* start bit */ #define GX_BP_LINEPTWIDTH_ADJUST_AR_B 9 +/* end bit */ #define GX_BP_LINEPTWIDTH_ADJUST_AR_E 9 +/* bit size */ #define GX_BP_LINEPTWIDTH_ADJUST_AR_SZ 1 -/** +/* raw mask */ #define GX_BP_LINEPTWIDTH_ADJUST_AR_MASK (((1 << 1) - 1) << 31 - 9) +/* local mask */ #define GX_BP_LINEPTWIDTH_ADJUST_AR_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_LINEPTWIDTH_ADJUST_AR_SHIFT 22 + +/* get value */ #define GX_BP_GET_LINEPTWIDTH_ADJUST_AR(reg) GX_BITGET((reg), 9, 1) +/* set value */ #define GX_BP_SET_LINEPTWIDTH_ADJUST_AR(reg, x) ((reg) = GX_BITSET((reg), 9, 1, x)) + +/****************************************************************************** * BP register 0x25 - ras1_ss0 - */ + *****************************************************************************/ // S0 [28:31] (4) - S-component scale (stage 0) -#define GX_BP_RAS1_SS0_S0_ST 28 -#define GX_BP_RAS1_SS0_S0_END 31 -#define GX_BP_RAS1_SS0_S0_SZ 4 -#define GX_BP_RAS1_SS0_S0_MASK (((1 << 4) - 1) << 31 - 31) -#define GX_BP_GET_RAS1_SS0_S0(reg) GX_BITGET(reg, 28, 4) -#define GX_BP_SET_RAS1_SS0_S0(reg, x) ((reg) = GX_BITSET(reg, 28, 4, x)) +/* start bit */ #define GX_BP_RAS1_SS0_S0_B 28 +/* end bit */ #define GX_BP_RAS1_SS0_S0_E 31 +/* bit size */ #define GX_BP_RAS1_SS0_S0_SZ 4 + +/* raw mask */ #define GX_BP_RAS1_SS0_S0_MASK (((1 << 4) - 1) << 31 - 31) +/* local mask */ #define GX_BP_RAS1_SS0_S0_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_RAS1_SS0_S0_SHIFT 0 + +/* get value */ #define GX_BP_GET_RAS1_SS0_S0(reg) GX_BITGET((reg), 28, 4) +/* set value */ #define GX_BP_SET_RAS1_SS0_S0(reg, x) ((reg) = GX_BITSET((reg), 28, 4, x)) + // T0 [24:27] (4) - T-component scale (stage 0) -#define GX_BP_RAS1_SS0_T0_ST 24 -#define GX_BP_RAS1_SS0_T0_END 27 -#define GX_BP_RAS1_SS0_T0_SZ 4 -#define GX_BP_RAS1_SS0_T0_MASK (((1 << 4) - 1) << 31 - 27) -#define GX_BP_GET_RAS1_SS0_T0(reg) GX_BITGET(reg, 24, 4) -#define GX_BP_SET_RAS1_SS0_T0(reg, x) ((reg) = GX_BITSET(reg, 24, 4, x)) +/* start bit */ #define GX_BP_RAS1_SS0_T0_B 24 +/* end bit */ #define GX_BP_RAS1_SS0_T0_E 27 +/* bit size */ #define GX_BP_RAS1_SS0_T0_SZ 4 + +/* raw mask */ #define GX_BP_RAS1_SS0_T0_MASK (((1 << 4) - 1) << 31 - 27) +/* local mask */ #define GX_BP_RAS1_SS0_T0_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_RAS1_SS0_T0_SHIFT 4 + +/* get value */ #define GX_BP_GET_RAS1_SS0_T0(reg) GX_BITGET((reg), 24, 4) +/* set value */ #define GX_BP_SET_RAS1_SS0_T0(reg, x) ((reg) = GX_BITSET((reg), 24, 4, x)) + // S1 [20:23] (4) - S-component scale (stage 1) -#define GX_BP_RAS1_SS0_S1_ST 20 -#define GX_BP_RAS1_SS0_S1_END 23 -#define GX_BP_RAS1_SS0_S1_SZ 4 -#define GX_BP_RAS1_SS0_S1_MASK (((1 << 4) - 1) << 31 - 23) -#define GX_BP_GET_RAS1_SS0_S1(reg) GX_BITGET(reg, 20, 4) -#define GX_BP_SET_RAS1_SS0_S1(reg, x) ((reg) = GX_BITSET(reg, 20, 4, x)) +/* start bit */ #define GX_BP_RAS1_SS0_S1_B 20 +/* end bit */ #define GX_BP_RAS1_SS0_S1_E 23 +/* bit size */ #define GX_BP_RAS1_SS0_S1_SZ 4 + +/* raw mask */ #define GX_BP_RAS1_SS0_S1_MASK (((1 << 4) - 1) << 31 - 23) +/* local mask */ #define GX_BP_RAS1_SS0_S1_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_RAS1_SS0_S1_SHIFT 8 + +/* get value */ #define GX_BP_GET_RAS1_SS0_S1(reg) GX_BITGET((reg), 20, 4) +/* set value */ #define GX_BP_SET_RAS1_SS0_S1(reg, x) ((reg) = GX_BITSET((reg), 20, 4, x)) + // T1 [16:19] (4) - T-component scale (stage 1) -#define GX_BP_RAS1_SS0_T1_ST 16 -#define GX_BP_RAS1_SS0_T1_END 19 -#define GX_BP_RAS1_SS0_T1_SZ 4 -#define GX_BP_RAS1_SS0_T1_MASK (((1 << 4) - 1) << 31 - 19) -#define GX_BP_GET_RAS1_SS0_T1(reg) GX_BITGET(reg, 16, 4) -#define GX_BP_SET_RAS1_SS0_T1(reg, x) ((reg) = GX_BITSET(reg, 16, 4, x)) +/* start bit */ #define GX_BP_RAS1_SS0_T1_B 16 +/* end bit */ #define GX_BP_RAS1_SS0_T1_E 19 +/* bit size */ #define GX_BP_RAS1_SS0_T1_SZ 4 -/** +/* raw mask */ #define GX_BP_RAS1_SS0_T1_MASK (((1 << 4) - 1) << 31 - 19) +/* local mask */ #define GX_BP_RAS1_SS0_T1_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_RAS1_SS0_T1_SHIFT 12 + +/* get value */ #define GX_BP_GET_RAS1_SS0_T1(reg) GX_BITGET((reg), 16, 4) +/* set value */ #define GX_BP_SET_RAS1_SS0_T1(reg, x) ((reg) = GX_BITSET((reg), 16, 4, x)) + +/****************************************************************************** * BP register 0x26 - ras1_ss1 - */ + *****************************************************************************/ // S2 [28:31] (4) - S-component scale (stage 2) -#define GX_BP_RAS1_SS1_S2_ST 28 -#define GX_BP_RAS1_SS1_S2_END 31 -#define GX_BP_RAS1_SS1_S2_SZ 4 -#define GX_BP_RAS1_SS1_S2_MASK (((1 << 4) - 1) << 31 - 31) -#define GX_BP_GET_RAS1_SS1_S2(reg) GX_BITGET(reg, 28, 4) -#define GX_BP_SET_RAS1_SS1_S2(reg, x) ((reg) = GX_BITSET(reg, 28, 4, x)) +/* start bit */ #define GX_BP_RAS1_SS1_S2_B 28 +/* end bit */ #define GX_BP_RAS1_SS1_S2_E 31 +/* bit size */ #define GX_BP_RAS1_SS1_S2_SZ 4 + +/* raw mask */ #define GX_BP_RAS1_SS1_S2_MASK (((1 << 4) - 1) << 31 - 31) +/* local mask */ #define GX_BP_RAS1_SS1_S2_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_RAS1_SS1_S2_SHIFT 0 + +/* get value */ #define GX_BP_GET_RAS1_SS1_S2(reg) GX_BITGET((reg), 28, 4) +/* set value */ #define GX_BP_SET_RAS1_SS1_S2(reg, x) ((reg) = GX_BITSET((reg), 28, 4, x)) + // T2 [24:27] (4) - T-component scale (stage 2) -#define GX_BP_RAS1_SS1_T2_ST 24 -#define GX_BP_RAS1_SS1_T2_END 27 -#define GX_BP_RAS1_SS1_T2_SZ 4 -#define GX_BP_RAS1_SS1_T2_MASK (((1 << 4) - 1) << 31 - 27) -#define GX_BP_GET_RAS1_SS1_T2(reg) GX_BITGET(reg, 24, 4) -#define GX_BP_SET_RAS1_SS1_T2(reg, x) ((reg) = GX_BITSET(reg, 24, 4, x)) +/* start bit */ #define GX_BP_RAS1_SS1_T2_B 24 +/* end bit */ #define GX_BP_RAS1_SS1_T2_E 27 +/* bit size */ #define GX_BP_RAS1_SS1_T2_SZ 4 + +/* raw mask */ #define GX_BP_RAS1_SS1_T2_MASK (((1 << 4) - 1) << 31 - 27) +/* local mask */ #define GX_BP_RAS1_SS1_T2_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_RAS1_SS1_T2_SHIFT 4 + +/* get value */ #define GX_BP_GET_RAS1_SS1_T2(reg) GX_BITGET((reg), 24, 4) +/* set value */ #define GX_BP_SET_RAS1_SS1_T2(reg, x) ((reg) = GX_BITSET((reg), 24, 4, x)) + // S3 [20:23] (4) - S-component scale (stage 3) -#define GX_BP_RAS1_SS1_S3_ST 20 -#define GX_BP_RAS1_SS1_S3_END 23 -#define GX_BP_RAS1_SS1_S3_SZ 4 -#define GX_BP_RAS1_SS1_S3_MASK (((1 << 4) - 1) << 31 - 23) -#define GX_BP_GET_RAS1_SS1_S3(reg) GX_BITGET(reg, 20, 4) -#define GX_BP_SET_RAS1_SS1_S3(reg, x) ((reg) = GX_BITSET(reg, 20, 4, x)) +/* start bit */ #define GX_BP_RAS1_SS1_S3_B 20 +/* end bit */ #define GX_BP_RAS1_SS1_S3_E 23 +/* bit size */ #define GX_BP_RAS1_SS1_S3_SZ 4 + +/* raw mask */ #define GX_BP_RAS1_SS1_S3_MASK (((1 << 4) - 1) << 31 - 23) +/* local mask */ #define GX_BP_RAS1_SS1_S3_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_RAS1_SS1_S3_SHIFT 8 + +/* get value */ #define GX_BP_GET_RAS1_SS1_S3(reg) GX_BITGET((reg), 20, 4) +/* set value */ #define GX_BP_SET_RAS1_SS1_S3(reg, x) ((reg) = GX_BITSET((reg), 20, 4, x)) + // T3 [16:19] (4) - T-component scale (stage 3) -#define GX_BP_RAS1_SS1_T3_ST 16 -#define GX_BP_RAS1_SS1_T3_END 19 -#define GX_BP_RAS1_SS1_T3_SZ 4 -#define GX_BP_RAS1_SS1_T3_MASK (((1 << 4) - 1) << 31 - 19) -#define GX_BP_GET_RAS1_SS1_T3(reg) GX_BITGET(reg, 16, 4) -#define GX_BP_SET_RAS1_SS1_T3(reg, x) ((reg) = GX_BITSET(reg, 16, 4, x)) +/* start bit */ #define GX_BP_RAS1_SS1_T3_B 16 +/* end bit */ #define GX_BP_RAS1_SS1_T3_E 19 +/* bit size */ #define GX_BP_RAS1_SS1_T3_SZ 4 -/** +/* raw mask */ #define GX_BP_RAS1_SS1_T3_MASK (((1 << 4) - 1) << 31 - 19) +/* local mask */ #define GX_BP_RAS1_SS1_T3_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_RAS1_SS1_T3_SHIFT 12 + +/* get value */ #define GX_BP_GET_RAS1_SS1_T3(reg) GX_BITGET((reg), 16, 4) +/* set value */ #define GX_BP_SET_RAS1_SS1_T3(reg, x) ((reg) = GX_BITSET((reg), 16, 4, x)) + +/****************************************************************************** * BP register 0x27 - ras1_iref - */ + *****************************************************************************/ // MAP0 [29:31] (3) - Texmap id (stage 0) -#define GX_BP_RAS1_IREF_MAP0_ST 29 -#define GX_BP_RAS1_IREF_MAP0_END 31 -#define GX_BP_RAS1_IREF_MAP0_SZ 3 -#define GX_BP_RAS1_IREF_MAP0_MASK (((1 << 3) - 1) << 31 - 31) -#define GX_BP_GET_RAS1_IREF_MAP0(reg) GX_BITGET(reg, 29, 3) -#define GX_BP_SET_RAS1_IREF_MAP0(reg, x) ((reg) = GX_BITSET(reg, 29, 3, x)) +/* start bit */ #define GX_BP_RAS1_IREF_MAP0_B 29 +/* end bit */ #define GX_BP_RAS1_IREF_MAP0_E 31 +/* bit size */ #define GX_BP_RAS1_IREF_MAP0_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_IREF_MAP0_MASK (((1 << 3) - 1) << 31 - 31) +/* local mask */ #define GX_BP_RAS1_IREF_MAP0_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_IREF_MAP0_SHIFT 0 + +/* get value */ #define GX_BP_GET_RAS1_IREF_MAP0(reg) GX_BITGET((reg), 29, 3) +/* set value */ #define GX_BP_SET_RAS1_IREF_MAP0(reg, x) ((reg) = GX_BITSET((reg), 29, 3, x)) + // TXC0 [26:28] (3) - Texcoord ID (stage 0) -#define GX_BP_RAS1_IREF_TXC0_ST 26 -#define GX_BP_RAS1_IREF_TXC0_END 28 -#define GX_BP_RAS1_IREF_TXC0_SZ 3 -#define GX_BP_RAS1_IREF_TXC0_MASK (((1 << 3) - 1) << 31 - 28) -#define GX_BP_GET_RAS1_IREF_TXC0(reg) GX_BITGET(reg, 26, 3) -#define GX_BP_SET_RAS1_IREF_TXC0(reg, x) ((reg) = GX_BITSET(reg, 26, 3, x)) +/* start bit */ #define GX_BP_RAS1_IREF_TXC0_B 26 +/* end bit */ #define GX_BP_RAS1_IREF_TXC0_E 28 +/* bit size */ #define GX_BP_RAS1_IREF_TXC0_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_IREF_TXC0_MASK (((1 << 3) - 1) << 31 - 28) +/* local mask */ #define GX_BP_RAS1_IREF_TXC0_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_IREF_TXC0_SHIFT 3 + +/* get value */ #define GX_BP_GET_RAS1_IREF_TXC0(reg) GX_BITGET((reg), 26, 3) +/* set value */ #define GX_BP_SET_RAS1_IREF_TXC0(reg, x) ((reg) = GX_BITSET((reg), 26, 3, x)) + // MAP1 [23:25] (3) - Texmap id (stage 1) -#define GX_BP_RAS1_IREF_MAP1_ST 23 -#define GX_BP_RAS1_IREF_MAP1_END 25 -#define GX_BP_RAS1_IREF_MAP1_SZ 3 -#define GX_BP_RAS1_IREF_MAP1_MASK (((1 << 3) - 1) << 31 - 25) -#define GX_BP_GET_RAS1_IREF_MAP1(reg) GX_BITGET(reg, 23, 3) -#define GX_BP_SET_RAS1_IREF_MAP1(reg, x) ((reg) = GX_BITSET(reg, 23, 3, x)) +/* start bit */ #define GX_BP_RAS1_IREF_MAP1_B 23 +/* end bit */ #define GX_BP_RAS1_IREF_MAP1_E 25 +/* bit size */ #define GX_BP_RAS1_IREF_MAP1_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_IREF_MAP1_MASK (((1 << 3) - 1) << 31 - 25) +/* local mask */ #define GX_BP_RAS1_IREF_MAP1_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_IREF_MAP1_SHIFT 6 + +/* get value */ #define GX_BP_GET_RAS1_IREF_MAP1(reg) GX_BITGET((reg), 23, 3) +/* set value */ #define GX_BP_SET_RAS1_IREF_MAP1(reg, x) ((reg) = GX_BITSET((reg), 23, 3, x)) + // TXC1 [20:22] (3) - Texcoord ID (stage 1) -#define GX_BP_RAS1_IREF_TXC1_ST 20 -#define GX_BP_RAS1_IREF_TXC1_END 22 -#define GX_BP_RAS1_IREF_TXC1_SZ 3 -#define GX_BP_RAS1_IREF_TXC1_MASK (((1 << 3) - 1) << 31 - 22) -#define GX_BP_GET_RAS1_IREF_TXC1(reg) GX_BITGET(reg, 20, 3) -#define GX_BP_SET_RAS1_IREF_TXC1(reg, x) ((reg) = GX_BITSET(reg, 20, 3, x)) +/* start bit */ #define GX_BP_RAS1_IREF_TXC1_B 20 +/* end bit */ #define GX_BP_RAS1_IREF_TXC1_E 22 +/* bit size */ #define GX_BP_RAS1_IREF_TXC1_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_IREF_TXC1_MASK (((1 << 3) - 1) << 31 - 22) +/* local mask */ #define GX_BP_RAS1_IREF_TXC1_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_IREF_TXC1_SHIFT 9 + +/* get value */ #define GX_BP_GET_RAS1_IREF_TXC1(reg) GX_BITGET((reg), 20, 3) +/* set value */ #define GX_BP_SET_RAS1_IREF_TXC1(reg, x) ((reg) = GX_BITSET((reg), 20, 3, x)) + // MAP2 [17:19] (3) - Texmap id (stage 2) -#define GX_BP_RAS1_IREF_MAP2_ST 17 -#define GX_BP_RAS1_IREF_MAP2_END 19 -#define GX_BP_RAS1_IREF_MAP2_SZ 3 -#define GX_BP_RAS1_IREF_MAP2_MASK (((1 << 3) - 1) << 31 - 19) -#define GX_BP_GET_RAS1_IREF_MAP2(reg) GX_BITGET(reg, 17, 3) -#define GX_BP_SET_RAS1_IREF_MAP2(reg, x) ((reg) = GX_BITSET(reg, 17, 3, x)) +/* start bit */ #define GX_BP_RAS1_IREF_MAP2_B 17 +/* end bit */ #define GX_BP_RAS1_IREF_MAP2_E 19 +/* bit size */ #define GX_BP_RAS1_IREF_MAP2_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_IREF_MAP2_MASK (((1 << 3) - 1) << 31 - 19) +/* local mask */ #define GX_BP_RAS1_IREF_MAP2_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_IREF_MAP2_SHIFT 12 + +/* get value */ #define GX_BP_GET_RAS1_IREF_MAP2(reg) GX_BITGET((reg), 17, 3) +/* set value */ #define GX_BP_SET_RAS1_IREF_MAP2(reg, x) ((reg) = GX_BITSET((reg), 17, 3, x)) + // TXC2 [14:16] (3) - Texcoord ID (stage 2) -#define GX_BP_RAS1_IREF_TXC2_ST 14 -#define GX_BP_RAS1_IREF_TXC2_END 16 -#define GX_BP_RAS1_IREF_TXC2_SZ 3 -#define GX_BP_RAS1_IREF_TXC2_MASK (((1 << 3) - 1) << 31 - 16) -#define GX_BP_GET_RAS1_IREF_TXC2(reg) GX_BITGET(reg, 14, 3) -#define GX_BP_SET_RAS1_IREF_TXC2(reg, x) ((reg) = GX_BITSET(reg, 14, 3, x)) +/* start bit */ #define GX_BP_RAS1_IREF_TXC2_B 14 +/* end bit */ #define GX_BP_RAS1_IREF_TXC2_E 16 +/* bit size */ #define GX_BP_RAS1_IREF_TXC2_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_IREF_TXC2_MASK (((1 << 3) - 1) << 31 - 16) +/* local mask */ #define GX_BP_RAS1_IREF_TXC2_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_IREF_TXC2_SHIFT 15 + +/* get value */ #define GX_BP_GET_RAS1_IREF_TXC2(reg) GX_BITGET((reg), 14, 3) +/* set value */ #define GX_BP_SET_RAS1_IREF_TXC2(reg, x) ((reg) = GX_BITSET((reg), 14, 3, x)) + // MAP3 [11:13] (3) - Texmap id (stage 3) -#define GX_BP_RAS1_IREF_MAP3_ST 11 -#define GX_BP_RAS1_IREF_MAP3_END 13 -#define GX_BP_RAS1_IREF_MAP3_SZ 3 -#define GX_BP_RAS1_IREF_MAP3_MASK (((1 << 3) - 1) << 31 - 13) -#define GX_BP_GET_RAS1_IREF_MAP3(reg) GX_BITGET(reg, 11, 3) -#define GX_BP_SET_RAS1_IREF_MAP3(reg, x) ((reg) = GX_BITSET(reg, 11, 3, x)) +/* start bit */ #define GX_BP_RAS1_IREF_MAP3_B 11 +/* end bit */ #define GX_BP_RAS1_IREF_MAP3_E 13 +/* bit size */ #define GX_BP_RAS1_IREF_MAP3_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_IREF_MAP3_MASK (((1 << 3) - 1) << 31 - 13) +/* local mask */ #define GX_BP_RAS1_IREF_MAP3_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_IREF_MAP3_SHIFT 18 + +/* get value */ #define GX_BP_GET_RAS1_IREF_MAP3(reg) GX_BITGET((reg), 11, 3) +/* set value */ #define GX_BP_SET_RAS1_IREF_MAP3(reg, x) ((reg) = GX_BITSET((reg), 11, 3, x)) + // TXC3 [8:10] (3) - Texcoord ID (stage 3) -#define GX_BP_RAS1_IREF_TXC3_ST 8 -#define GX_BP_RAS1_IREF_TXC3_END 10 -#define GX_BP_RAS1_IREF_TXC3_SZ 3 -#define GX_BP_RAS1_IREF_TXC3_MASK (((1 << 3) - 1) << 31 - 10) -#define GX_BP_GET_RAS1_IREF_TXC3(reg) GX_BITGET(reg, 8, 3) -#define GX_BP_SET_RAS1_IREF_TXC3(reg, x) ((reg) = GX_BITSET(reg, 8, 3, x)) +/* start bit */ #define GX_BP_RAS1_IREF_TXC3_B 8 +/* end bit */ #define GX_BP_RAS1_IREF_TXC3_E 10 +/* bit size */ #define GX_BP_RAS1_IREF_TXC3_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_IREF_TXC3_MASK (((1 << 3) - 1) << 31 - 10) +/* local mask */ #define GX_BP_RAS1_IREF_TXC3_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_IREF_TXC3_SHIFT 21 + +/* get value */ #define GX_BP_GET_RAS1_IREF_TXC3(reg) GX_BITGET((reg), 8, 3) +/* set value */ #define GX_BP_SET_RAS1_IREF_TXC3(reg, x) ((reg) = GX_BITSET((reg), 8, 3, x)) + +/****************************************************************************** + * BP structure - ras1_tref + *****************************************************************************/ +// TEXMAP_EVEN [29:31] (3) +/* start bit */ #define GX_BP_RAS1_TREF_TEXMAP_EVEN_B 29 +/* end bit */ #define GX_BP_RAS1_TREF_TEXMAP_EVEN_E 31 +/* bit size */ #define GX_BP_RAS1_TREF_TEXMAP_EVEN_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_TREF_TEXMAP_EVEN_MASK (((1 << 3) - 1) << 31 - 31) +/* local mask */ #define GX_BP_RAS1_TREF_TEXMAP_EVEN_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_TREF_TEXMAP_EVEN_SHIFT 0 + +/* get value */ #define GX_BP_GET_RAS1_TREF_TEXMAP_EVEN(reg) GX_BITGET((reg), 29, 3) +/* set value */ #define GX_BP_SET_RAS1_TREF_TEXMAP_EVEN(reg, x) ((reg) = GX_BITSET((reg), 29, 3, x)) + +// TEXCOORD_EVEN [26:28] (3) +/* start bit */ #define GX_BP_RAS1_TREF_TEXCOORD_EVEN_B 26 +/* end bit */ #define GX_BP_RAS1_TREF_TEXCOORD_EVEN_E 28 +/* bit size */ #define GX_BP_RAS1_TREF_TEXCOORD_EVEN_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_TREF_TEXCOORD_EVEN_MASK (((1 << 3) - 1) << 31 - 28) +/* local mask */ #define GX_BP_RAS1_TREF_TEXCOORD_EVEN_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_TREF_TEXCOORD_EVEN_SHIFT 3 + +/* get value */ #define GX_BP_GET_RAS1_TREF_TEXCOORD_EVEN(reg) GX_BITGET((reg), 26, 3) +/* set value */ #define GX_BP_SET_RAS1_TREF_TEXCOORD_EVEN(reg, x) ((reg) = GX_BITSET((reg), 26, 3, x)) + +// ENABLE_TEX_EVEN [25:25] (1) +/* start bit */ #define GX_BP_RAS1_TREF_ENABLE_TEX_EVEN_B 25 +/* end bit */ #define GX_BP_RAS1_TREF_ENABLE_TEX_EVEN_E 25 +/* bit size */ #define GX_BP_RAS1_TREF_ENABLE_TEX_EVEN_SZ 1 + +/* raw mask */ #define GX_BP_RAS1_TREF_ENABLE_TEX_EVEN_MASK (((1 << 1) - 1) << 31 - 25) +/* local mask */ #define GX_BP_RAS1_TREF_ENABLE_TEX_EVEN_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_RAS1_TREF_ENABLE_TEX_EVEN_SHIFT 6 + +/* get value */ #define GX_BP_GET_RAS1_TREF_ENABLE_TEX_EVEN(reg) GX_BITGET((reg), 25, 1) +/* set value */ #define GX_BP_SET_RAS1_TREF_ENABLE_TEX_EVEN(reg, x) ((reg) = GX_BITSET((reg), 25, 1, x)) + +// COLORCHAN_EVEN [22:24] (3) +/* start bit */ #define GX_BP_RAS1_TREF_COLORCHAN_EVEN_B 22 +/* end bit */ #define GX_BP_RAS1_TREF_COLORCHAN_EVEN_E 24 +/* bit size */ #define GX_BP_RAS1_TREF_COLORCHAN_EVEN_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_TREF_COLORCHAN_EVEN_MASK (((1 << 3) - 1) << 31 - 24) +/* local mask */ #define GX_BP_RAS1_TREF_COLORCHAN_EVEN_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_TREF_COLORCHAN_EVEN_SHIFT 7 + +/* get value */ #define GX_BP_GET_RAS1_TREF_COLORCHAN_EVEN(reg) GX_BITGET((reg), 22, 3) +/* set value */ #define GX_BP_SET_RAS1_TREF_COLORCHAN_EVEN(reg, x) ((reg) = GX_BITSET((reg), 22, 3, x)) + +// TEXMAP_ODD [17:19] (3) +/* start bit */ #define GX_BP_RAS1_TREF_TEXMAP_ODD_B 17 +/* end bit */ #define GX_BP_RAS1_TREF_TEXMAP_ODD_E 19 +/* bit size */ #define GX_BP_RAS1_TREF_TEXMAP_ODD_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_TREF_TEXMAP_ODD_MASK (((1 << 3) - 1) << 31 - 19) +/* local mask */ #define GX_BP_RAS1_TREF_TEXMAP_ODD_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_TREF_TEXMAP_ODD_SHIFT 12 + +/* get value */ #define GX_BP_GET_RAS1_TREF_TEXMAP_ODD(reg) GX_BITGET((reg), 17, 3) +/* set value */ #define GX_BP_SET_RAS1_TREF_TEXMAP_ODD(reg, x) ((reg) = GX_BITSET((reg), 17, 3, x)) + +// TEXCOORD_ODD [14:16] (3) +/* start bit */ #define GX_BP_RAS1_TREF_TEXCOORD_ODD_B 14 +/* end bit */ #define GX_BP_RAS1_TREF_TEXCOORD_ODD_E 16 +/* bit size */ #define GX_BP_RAS1_TREF_TEXCOORD_ODD_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_TREF_TEXCOORD_ODD_MASK (((1 << 3) - 1) << 31 - 16) +/* local mask */ #define GX_BP_RAS1_TREF_TEXCOORD_ODD_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_TREF_TEXCOORD_ODD_SHIFT 15 + +/* get value */ #define GX_BP_GET_RAS1_TREF_TEXCOORD_ODD(reg) GX_BITGET((reg), 14, 3) +/* set value */ #define GX_BP_SET_RAS1_TREF_TEXCOORD_ODD(reg, x) ((reg) = GX_BITSET((reg), 14, 3, x)) + +// ENABLE_TEX_ODD [13:13] (1) +/* start bit */ #define GX_BP_RAS1_TREF_ENABLE_TEX_ODD_B 13 +/* end bit */ #define GX_BP_RAS1_TREF_ENABLE_TEX_ODD_E 13 +/* bit size */ #define GX_BP_RAS1_TREF_ENABLE_TEX_ODD_SZ 1 + +/* raw mask */ #define GX_BP_RAS1_TREF_ENABLE_TEX_ODD_MASK (((1 << 1) - 1) << 31 - 13) +/* local mask */ #define GX_BP_RAS1_TREF_ENABLE_TEX_ODD_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_RAS1_TREF_ENABLE_TEX_ODD_SHIFT 18 + +/* get value */ #define GX_BP_GET_RAS1_TREF_ENABLE_TEX_ODD(reg) GX_BITGET((reg), 13, 1) +/* set value */ #define GX_BP_SET_RAS1_TREF_ENABLE_TEX_ODD(reg, x) ((reg) = GX_BITSET((reg), 13, 1, x)) + +// COLORCHAN_ODD [10:12] (3) +/* start bit */ #define GX_BP_RAS1_TREF_COLORCHAN_ODD_B 10 +/* end bit */ #define GX_BP_RAS1_TREF_COLORCHAN_ODD_E 12 +/* bit size */ #define GX_BP_RAS1_TREF_COLORCHAN_ODD_SZ 3 + +/* raw mask */ #define GX_BP_RAS1_TREF_COLORCHAN_ODD_MASK (((1 << 3) - 1) << 31 - 12) +/* local mask */ #define GX_BP_RAS1_TREF_COLORCHAN_ODD_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_RAS1_TREF_COLORCHAN_ODD_SHIFT 19 + +/* get value */ #define GX_BP_GET_RAS1_TREF_COLORCHAN_ODD(reg) GX_BITGET((reg), 10, 3) +/* set value */ #define GX_BP_SET_RAS1_TREF_COLORCHAN_ODD(reg, x) ((reg) = GX_BITSET((reg), 10, 3, x)) + +/****************************************************************************** + * BP structure - su_size + *****************************************************************************/ +// SCALE [16:31] (16) +/* start bit */ #define GX_BP_SU_SIZE_SCALE_B 16 +/* end bit */ #define GX_BP_SU_SIZE_SCALE_E 31 +/* bit size */ #define GX_BP_SU_SIZE_SCALE_SZ 16 + +/* raw mask */ #define GX_BP_SU_SIZE_SCALE_MASK (((1 << 16) - 1) << 31 - 31) +/* local mask */ #define GX_BP_SU_SIZE_SCALE_LMASK ((1 << 16) - 1) +/* bit shift */ #define GX_BP_SU_SIZE_SCALE_SHIFT 0 + +/* get value */ #define GX_BP_GET_SU_SIZE_SCALE(reg) GX_BITGET((reg), 16, 16) +/* set value */ #define GX_BP_SET_SU_SIZE_SCALE(reg, x) ((reg) = GX_BITSET((reg), 16, 16, x)) + +// RANGEBIAS [15:15] (1) +/* start bit */ #define GX_BP_SU_SIZE_RANGEBIAS_B 15 +/* end bit */ #define GX_BP_SU_SIZE_RANGEBIAS_E 15 +/* bit size */ #define GX_BP_SU_SIZE_RANGEBIAS_SZ 1 + +/* raw mask */ #define GX_BP_SU_SIZE_RANGEBIAS_MASK (((1 << 1) - 1) << 31 - 15) +/* local mask */ #define GX_BP_SU_SIZE_RANGEBIAS_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_SU_SIZE_RANGEBIAS_SHIFT 16 + +/* get value */ #define GX_BP_GET_SU_SIZE_RANGEBIAS(reg) GX_BITGET((reg), 15, 1) +/* set value */ #define GX_BP_SET_SU_SIZE_RANGEBIAS(reg, x) ((reg) = GX_BITSET((reg), 15, 1, x)) + +// CYLINDRICWRAP [14:14] (1) +/* start bit */ #define GX_BP_SU_SIZE_CYLINDRICWRAP_B 14 +/* end bit */ #define GX_BP_SU_SIZE_CYLINDRICWRAP_E 14 +/* bit size */ #define GX_BP_SU_SIZE_CYLINDRICWRAP_SZ 1 + +/* raw mask */ #define GX_BP_SU_SIZE_CYLINDRICWRAP_MASK (((1 << 1) - 1) << 31 - 14) +/* local mask */ #define GX_BP_SU_SIZE_CYLINDRICWRAP_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_SU_SIZE_CYLINDRICWRAP_SHIFT 17 + +/* get value */ #define GX_BP_GET_SU_SIZE_CYLINDRICWRAP(reg) GX_BITGET((reg), 14, 1) +/* set value */ #define GX_BP_SET_SU_SIZE_CYLINDRICWRAP(reg, x) ((reg) = GX_BITSET((reg), 14, 1, x)) -/** - * BP structure - su_ssize - */ // USELINEOFS [13:13] (1) -#define GX_BP_SU_SSIZE_USELINEOFS_ST 13 -#define GX_BP_SU_SSIZE_USELINEOFS_END 13 -#define GX_BP_SU_SSIZE_USELINEOFS_SZ 1 -#define GX_BP_SU_SSIZE_USELINEOFS_MASK (((1 << 1) - 1) << 31 - 13) -#define GX_BP_GET_SU_SSIZE_USELINEOFS(reg) GX_BITGET(reg, 13, 1) -#define GX_BP_SET_SU_SSIZE_USELINEOFS(reg, x) ((reg) = GX_BITSET(reg, 13, 1, x)) +/* start bit */ #define GX_BP_SU_SIZE_USELINEOFS_B 13 +/* end bit */ #define GX_BP_SU_SIZE_USELINEOFS_E 13 +/* bit size */ #define GX_BP_SU_SIZE_USELINEOFS_SZ 1 + +/* raw mask */ #define GX_BP_SU_SIZE_USELINEOFS_MASK (((1 << 1) - 1) << 31 - 13) +/* local mask */ #define GX_BP_SU_SIZE_USELINEOFS_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_SU_SIZE_USELINEOFS_SHIFT 18 + +/* get value */ #define GX_BP_GET_SU_SIZE_USELINEOFS(reg) GX_BITGET((reg), 13, 1) +/* set value */ #define GX_BP_SET_SU_SIZE_USELINEOFS(reg, x) ((reg) = GX_BITSET((reg), 13, 1, x)) + // USEPOINTOFS [12:12] (1) -#define GX_BP_SU_SSIZE_USEPOINTOFS_ST 12 -#define GX_BP_SU_SSIZE_USEPOINTOFS_END 12 -#define GX_BP_SU_SSIZE_USEPOINTOFS_SZ 1 -#define GX_BP_SU_SSIZE_USEPOINTOFS_MASK (((1 << 1) - 1) << 31 - 12) -#define GX_BP_GET_SU_SSIZE_USEPOINTOFS(reg) GX_BITGET(reg, 12, 1) -#define GX_BP_SET_SU_SSIZE_USEPOINTOFS(reg, x) ((reg) = GX_BITSET(reg, 12, 1, x)) +/* start bit */ #define GX_BP_SU_SIZE_USEPOINTOFS_B 12 +/* end bit */ #define GX_BP_SU_SIZE_USEPOINTOFS_E 12 +/* bit size */ #define GX_BP_SU_SIZE_USEPOINTOFS_SZ 1 -/** +/* raw mask */ #define GX_BP_SU_SIZE_USEPOINTOFS_MASK (((1 << 1) - 1) << 31 - 12) +/* local mask */ #define GX_BP_SU_SIZE_USEPOINTOFS_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_SU_SIZE_USEPOINTOFS_SHIFT 19 + +/* get value */ #define GX_BP_GET_SU_SIZE_USEPOINTOFS(reg) GX_BITGET((reg), 12, 1) +/* set value */ #define GX_BP_SET_SU_SIZE_USEPOINTOFS(reg, x) ((reg) = GX_BITSET((reg), 12, 1, x)) + +/****************************************************************************** * BP register 0x40 - ZMode - */ + *****************************************************************************/ // TEST_ENABLE [31:31] (1) -#define GX_BP_ZMODE_TEST_ENABLE_ST 31 -#define GX_BP_ZMODE_TEST_ENABLE_END 31 -#define GX_BP_ZMODE_TEST_ENABLE_SZ 1 -#define GX_BP_ZMODE_TEST_ENABLE_MASK (((1 << 1) - 1) << 31 - 31) -#define GX_BP_GET_ZMODE_TEST_ENABLE(reg) GX_BITGET(reg, 31, 1) -#define GX_BP_SET_ZMODE_TEST_ENABLE(reg, x) ((reg) = GX_BITSET(reg, 31, 1, x)) +/* start bit */ #define GX_BP_ZMODE_TEST_ENABLE_B 31 +/* end bit */ #define GX_BP_ZMODE_TEST_ENABLE_E 31 +/* bit size */ #define GX_BP_ZMODE_TEST_ENABLE_SZ 1 + +/* raw mask */ #define GX_BP_ZMODE_TEST_ENABLE_MASK (((1 << 1) - 1) << 31 - 31) +/* local mask */ #define GX_BP_ZMODE_TEST_ENABLE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_ZMODE_TEST_ENABLE_SHIFT 0 + +/* get value */ #define GX_BP_GET_ZMODE_TEST_ENABLE(reg) GX_BITGET((reg), 31, 1) +/* set value */ #define GX_BP_SET_ZMODE_TEST_ENABLE(reg, x) ((reg) = GX_BITSET((reg), 31, 1, x)) + // COMPARE [28:30] (3) -#define GX_BP_ZMODE_COMPARE_ST 28 -#define GX_BP_ZMODE_COMPARE_END 30 -#define GX_BP_ZMODE_COMPARE_SZ 3 -#define GX_BP_ZMODE_COMPARE_MASK (((1 << 3) - 1) << 31 - 30) -#define GX_BP_GET_ZMODE_COMPARE(reg) GX_BITGET(reg, 28, 3) -#define GX_BP_SET_ZMODE_COMPARE(reg, x) ((reg) = GX_BITSET(reg, 28, 3, x)) +/* start bit */ #define GX_BP_ZMODE_COMPARE_B 28 +/* end bit */ #define GX_BP_ZMODE_COMPARE_E 30 +/* bit size */ #define GX_BP_ZMODE_COMPARE_SZ 3 + +/* raw mask */ #define GX_BP_ZMODE_COMPARE_MASK (((1 << 3) - 1) << 31 - 30) +/* local mask */ #define GX_BP_ZMODE_COMPARE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_ZMODE_COMPARE_SHIFT 1 + +/* get value */ #define GX_BP_GET_ZMODE_COMPARE(reg) GX_BITGET((reg), 28, 3) +/* set value */ #define GX_BP_SET_ZMODE_COMPARE(reg, x) ((reg) = GX_BITSET((reg), 28, 3, x)) + // UPDATE_ENABLE [27:27] (1) -#define GX_BP_ZMODE_UPDATE_ENABLE_ST 27 -#define GX_BP_ZMODE_UPDATE_ENABLE_END 27 -#define GX_BP_ZMODE_UPDATE_ENABLE_SZ 1 -#define GX_BP_ZMODE_UPDATE_ENABLE_MASK (((1 << 1) - 1) << 31 - 27) -#define GX_BP_GET_ZMODE_UPDATE_ENABLE(reg) GX_BITGET(reg, 27, 1) -#define GX_BP_SET_ZMODE_UPDATE_ENABLE(reg, x) ((reg) = GX_BITSET(reg, 27, 1, x)) +/* start bit */ #define GX_BP_ZMODE_UPDATE_ENABLE_B 27 +/* end bit */ #define GX_BP_ZMODE_UPDATE_ENABLE_E 27 +/* bit size */ #define GX_BP_ZMODE_UPDATE_ENABLE_SZ 1 -/** +/* raw mask */ #define GX_BP_ZMODE_UPDATE_ENABLE_MASK (((1 << 1) - 1) << 31 - 27) +/* local mask */ #define GX_BP_ZMODE_UPDATE_ENABLE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_ZMODE_UPDATE_ENABLE_SHIFT 4 + +/* get value */ #define GX_BP_GET_ZMODE_UPDATE_ENABLE(reg) GX_BITGET((reg), 27, 1) +/* set value */ #define GX_BP_SET_ZMODE_UPDATE_ENABLE(reg, x) ((reg) = GX_BITSET((reg), 27, 1, x)) + +/****************************************************************************** * BP register 0x41 - BlendMode - */ + *****************************************************************************/ // BLEND_ENABLE [31:31] (1) -#define GX_BP_BLENDMODE_BLEND_ENABLE_ST 31 -#define GX_BP_BLENDMODE_BLEND_ENABLE_END 31 -#define GX_BP_BLENDMODE_BLEND_ENABLE_SZ 1 -#define GX_BP_BLENDMODE_BLEND_ENABLE_MASK (((1 << 1) - 1) << 31 - 31) -#define GX_BP_GET_BLENDMODE_BLEND_ENABLE(reg) GX_BITGET(reg, 31, 1) -#define GX_BP_SET_BLENDMODE_BLEND_ENABLE(reg, x) ((reg) = GX_BITSET(reg, 31, 1, x)) +/* start bit */ #define GX_BP_BLENDMODE_BLEND_ENABLE_B 31 +/* end bit */ #define GX_BP_BLENDMODE_BLEND_ENABLE_E 31 +/* bit size */ #define GX_BP_BLENDMODE_BLEND_ENABLE_SZ 1 + +/* raw mask */ #define GX_BP_BLENDMODE_BLEND_ENABLE_MASK (((1 << 1) - 1) << 31 - 31) +/* local mask */ #define GX_BP_BLENDMODE_BLEND_ENABLE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_BLENDMODE_BLEND_ENABLE_SHIFT 0 + +/* get value */ #define GX_BP_GET_BLENDMODE_BLEND_ENABLE(reg) GX_BITGET((reg), 31, 1) +/* set value */ #define GX_BP_SET_BLENDMODE_BLEND_ENABLE(reg, x) ((reg) = GX_BITSET((reg), 31, 1, x)) + // LOGIC_OP_ENABLE [30:30] (1) -#define GX_BP_BLENDMODE_LOGIC_OP_ENABLE_ST 30 -#define GX_BP_BLENDMODE_LOGIC_OP_ENABLE_END 30 -#define GX_BP_BLENDMODE_LOGIC_OP_ENABLE_SZ 1 -#define GX_BP_BLENDMODE_LOGIC_OP_ENABLE_MASK (((1 << 1) - 1) << 31 - 30) -#define GX_BP_GET_BLENDMODE_LOGIC_OP_ENABLE(reg) GX_BITGET(reg, 30, 1) -#define GX_BP_SET_BLENDMODE_LOGIC_OP_ENABLE(reg, x) ((reg) = GX_BITSET(reg, 30, 1, x)) +/* start bit */ #define GX_BP_BLENDMODE_LOGIC_OP_ENABLE_B 30 +/* end bit */ #define GX_BP_BLENDMODE_LOGIC_OP_ENABLE_E 30 +/* bit size */ #define GX_BP_BLENDMODE_LOGIC_OP_ENABLE_SZ 1 + +/* raw mask */ #define GX_BP_BLENDMODE_LOGIC_OP_ENABLE_MASK (((1 << 1) - 1) << 31 - 30) +/* local mask */ #define GX_BP_BLENDMODE_LOGIC_OP_ENABLE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_BLENDMODE_LOGIC_OP_ENABLE_SHIFT 1 + +/* get value */ #define GX_BP_GET_BLENDMODE_LOGIC_OP_ENABLE(reg) GX_BITGET((reg), 30, 1) +/* set value */ #define GX_BP_SET_BLENDMODE_LOGIC_OP_ENABLE(reg, x) ((reg) = GX_BITSET((reg), 30, 1, x)) + // DITHER [29:29] (1) -#define GX_BP_BLENDMODE_DITHER_ST 29 -#define GX_BP_BLENDMODE_DITHER_END 29 -#define GX_BP_BLENDMODE_DITHER_SZ 1 -#define GX_BP_BLENDMODE_DITHER_MASK (((1 << 1) - 1) << 31 - 29) -#define GX_BP_GET_BLENDMODE_DITHER(reg) GX_BITGET(reg, 29, 1) -#define GX_BP_SET_BLENDMODE_DITHER(reg, x) ((reg) = GX_BITSET(reg, 29, 1, x)) +/* start bit */ #define GX_BP_BLENDMODE_DITHER_B 29 +/* end bit */ #define GX_BP_BLENDMODE_DITHER_E 29 +/* bit size */ #define GX_BP_BLENDMODE_DITHER_SZ 1 + +/* raw mask */ #define GX_BP_BLENDMODE_DITHER_MASK (((1 << 1) - 1) << 31 - 29) +/* local mask */ #define GX_BP_BLENDMODE_DITHER_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_BLENDMODE_DITHER_SHIFT 2 + +/* get value */ #define GX_BP_GET_BLENDMODE_DITHER(reg) GX_BITGET((reg), 29, 1) +/* set value */ #define GX_BP_SET_BLENDMODE_DITHER(reg, x) ((reg) = GX_BITSET((reg), 29, 1, x)) + // COLOR_UPDATE [28:28] (1) -#define GX_BP_BLENDMODE_COLOR_UPDATE_ST 28 -#define GX_BP_BLENDMODE_COLOR_UPDATE_END 28 -#define GX_BP_BLENDMODE_COLOR_UPDATE_SZ 1 -#define GX_BP_BLENDMODE_COLOR_UPDATE_MASK (((1 << 1) - 1) << 31 - 28) -#define GX_BP_GET_BLENDMODE_COLOR_UPDATE(reg) GX_BITGET(reg, 28, 1) -#define GX_BP_SET_BLENDMODE_COLOR_UPDATE(reg, x) ((reg) = GX_BITSET(reg, 28, 1, x)) +/* start bit */ #define GX_BP_BLENDMODE_COLOR_UPDATE_B 28 +/* end bit */ #define GX_BP_BLENDMODE_COLOR_UPDATE_E 28 +/* bit size */ #define GX_BP_BLENDMODE_COLOR_UPDATE_SZ 1 + +/* raw mask */ #define GX_BP_BLENDMODE_COLOR_UPDATE_MASK (((1 << 1) - 1) << 31 - 28) +/* local mask */ #define GX_BP_BLENDMODE_COLOR_UPDATE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_BLENDMODE_COLOR_UPDATE_SHIFT 3 + +/* get value */ #define GX_BP_GET_BLENDMODE_COLOR_UPDATE(reg) GX_BITGET((reg), 28, 1) +/* set value */ #define GX_BP_SET_BLENDMODE_COLOR_UPDATE(reg, x) ((reg) = GX_BITSET((reg), 28, 1, x)) + // ALPHA_UPDATE [27:27] (1) -#define GX_BP_BLENDMODE_ALPHA_UPDATE_ST 27 -#define GX_BP_BLENDMODE_ALPHA_UPDATE_END 27 -#define GX_BP_BLENDMODE_ALPHA_UPDATE_SZ 1 -#define GX_BP_BLENDMODE_ALPHA_UPDATE_MASK (((1 << 1) - 1) << 31 - 27) -#define GX_BP_GET_BLENDMODE_ALPHA_UPDATE(reg) GX_BITGET(reg, 27, 1) -#define GX_BP_SET_BLENDMODE_ALPHA_UPDATE(reg, x) ((reg) = GX_BITSET(reg, 27, 1, x)) +/* start bit */ #define GX_BP_BLENDMODE_ALPHA_UPDATE_B 27 +/* end bit */ #define GX_BP_BLENDMODE_ALPHA_UPDATE_E 27 +/* bit size */ #define GX_BP_BLENDMODE_ALPHA_UPDATE_SZ 1 + +/* raw mask */ #define GX_BP_BLENDMODE_ALPHA_UPDATE_MASK (((1 << 1) - 1) << 31 - 27) +/* local mask */ #define GX_BP_BLENDMODE_ALPHA_UPDATE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_BLENDMODE_ALPHA_UPDATE_SHIFT 4 + +/* get value */ #define GX_BP_GET_BLENDMODE_ALPHA_UPDATE(reg) GX_BITGET((reg), 27, 1) +/* set value */ #define GX_BP_SET_BLENDMODE_ALPHA_UPDATE(reg, x) ((reg) = GX_BITSET((reg), 27, 1, x)) + // DST_FACTOR [24:26] (3) -#define GX_BP_BLENDMODE_DST_FACTOR_ST 24 -#define GX_BP_BLENDMODE_DST_FACTOR_END 26 -#define GX_BP_BLENDMODE_DST_FACTOR_SZ 3 -#define GX_BP_BLENDMODE_DST_FACTOR_MASK (((1 << 3) - 1) << 31 - 26) -#define GX_BP_GET_BLENDMODE_DST_FACTOR(reg) GX_BITGET(reg, 24, 3) -#define GX_BP_SET_BLENDMODE_DST_FACTOR(reg, x) ((reg) = GX_BITSET(reg, 24, 3, x)) +/* start bit */ #define GX_BP_BLENDMODE_DST_FACTOR_B 24 +/* end bit */ #define GX_BP_BLENDMODE_DST_FACTOR_E 26 +/* bit size */ #define GX_BP_BLENDMODE_DST_FACTOR_SZ 3 + +/* raw mask */ #define GX_BP_BLENDMODE_DST_FACTOR_MASK (((1 << 3) - 1) << 31 - 26) +/* local mask */ #define GX_BP_BLENDMODE_DST_FACTOR_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_BLENDMODE_DST_FACTOR_SHIFT 5 + +/* get value */ #define GX_BP_GET_BLENDMODE_DST_FACTOR(reg) GX_BITGET((reg), 24, 3) +/* set value */ #define GX_BP_SET_BLENDMODE_DST_FACTOR(reg, x) ((reg) = GX_BITSET((reg), 24, 3, x)) + // SRC_FACTOR [21:23] (3) -#define GX_BP_BLENDMODE_SRC_FACTOR_ST 21 -#define GX_BP_BLENDMODE_SRC_FACTOR_END 23 -#define GX_BP_BLENDMODE_SRC_FACTOR_SZ 3 -#define GX_BP_BLENDMODE_SRC_FACTOR_MASK (((1 << 3) - 1) << 31 - 23) -#define GX_BP_GET_BLENDMODE_SRC_FACTOR(reg) GX_BITGET(reg, 21, 3) -#define GX_BP_SET_BLENDMODE_SRC_FACTOR(reg, x) ((reg) = GX_BITSET(reg, 21, 3, x)) +/* start bit */ #define GX_BP_BLENDMODE_SRC_FACTOR_B 21 +/* end bit */ #define GX_BP_BLENDMODE_SRC_FACTOR_E 23 +/* bit size */ #define GX_BP_BLENDMODE_SRC_FACTOR_SZ 3 + +/* raw mask */ #define GX_BP_BLENDMODE_SRC_FACTOR_MASK (((1 << 3) - 1) << 31 - 23) +/* local mask */ #define GX_BP_BLENDMODE_SRC_FACTOR_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_BLENDMODE_SRC_FACTOR_SHIFT 8 + +/* get value */ #define GX_BP_GET_BLENDMODE_SRC_FACTOR(reg) GX_BITGET((reg), 21, 3) +/* set value */ #define GX_BP_SET_BLENDMODE_SRC_FACTOR(reg, x) ((reg) = GX_BITSET((reg), 21, 3, x)) + // SUBTRACT [20:20] (1) -#define GX_BP_BLENDMODE_SUBTRACT_ST 20 -#define GX_BP_BLENDMODE_SUBTRACT_END 20 -#define GX_BP_BLENDMODE_SUBTRACT_SZ 1 -#define GX_BP_BLENDMODE_SUBTRACT_MASK (((1 << 1) - 1) << 31 - 20) -#define GX_BP_GET_BLENDMODE_SUBTRACT(reg) GX_BITGET(reg, 20, 1) -#define GX_BP_SET_BLENDMODE_SUBTRACT(reg, x) ((reg) = GX_BITSET(reg, 20, 1, x)) +/* start bit */ #define GX_BP_BLENDMODE_SUBTRACT_B 20 +/* end bit */ #define GX_BP_BLENDMODE_SUBTRACT_E 20 +/* bit size */ #define GX_BP_BLENDMODE_SUBTRACT_SZ 1 + +/* raw mask */ #define GX_BP_BLENDMODE_SUBTRACT_MASK (((1 << 1) - 1) << 31 - 20) +/* local mask */ #define GX_BP_BLENDMODE_SUBTRACT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_BLENDMODE_SUBTRACT_SHIFT 11 + +/* get value */ #define GX_BP_GET_BLENDMODE_SUBTRACT(reg) GX_BITGET((reg), 20, 1) +/* set value */ #define GX_BP_SET_BLENDMODE_SUBTRACT(reg, x) ((reg) = GX_BITSET((reg), 20, 1, x)) + // LOGIC_MODE [16:19] (4) -#define GX_BP_BLENDMODE_LOGIC_MODE_ST 16 -#define GX_BP_BLENDMODE_LOGIC_MODE_END 19 -#define GX_BP_BLENDMODE_LOGIC_MODE_SZ 4 -#define GX_BP_BLENDMODE_LOGIC_MODE_MASK (((1 << 4) - 1) << 31 - 19) -#define GX_BP_GET_BLENDMODE_LOGIC_MODE(reg) GX_BITGET(reg, 16, 4) -#define GX_BP_SET_BLENDMODE_LOGIC_MODE(reg, x) ((reg) = GX_BITSET(reg, 16, 4, x)) +/* start bit */ #define GX_BP_BLENDMODE_LOGIC_MODE_B 16 +/* end bit */ #define GX_BP_BLENDMODE_LOGIC_MODE_E 19 +/* bit size */ #define GX_BP_BLENDMODE_LOGIC_MODE_SZ 4 -/** +/* raw mask */ #define GX_BP_BLENDMODE_LOGIC_MODE_MASK (((1 << 4) - 1) << 31 - 19) +/* local mask */ #define GX_BP_BLENDMODE_LOGIC_MODE_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_BLENDMODE_LOGIC_MODE_SHIFT 12 + +/* get value */ #define GX_BP_GET_BLENDMODE_LOGIC_MODE(reg) GX_BITGET((reg), 16, 4) +/* set value */ #define GX_BP_SET_BLENDMODE_LOGIC_MODE(reg, x) ((reg) = GX_BITSET((reg), 16, 4, x)) + +/****************************************************************************** * BP register 0x42 - DstAlpha - */ + *****************************************************************************/ // ALPHA [24:31] (8) -#define GX_BP_DSTALPHA_ALPHA_ST 24 -#define GX_BP_DSTALPHA_ALPHA_END 31 -#define GX_BP_DSTALPHA_ALPHA_SZ 8 -#define GX_BP_DSTALPHA_ALPHA_MASK (((1 << 8) - 1) << 31 - 31) -#define GX_BP_GET_DSTALPHA_ALPHA(reg) GX_BITGET(reg, 24, 8) -#define GX_BP_SET_DSTALPHA_ALPHA(reg, x) ((reg) = GX_BITSET(reg, 24, 8, x)) +/* start bit */ #define GX_BP_DSTALPHA_ALPHA_B 24 +/* end bit */ #define GX_BP_DSTALPHA_ALPHA_E 31 +/* bit size */ #define GX_BP_DSTALPHA_ALPHA_SZ 8 + +/* raw mask */ #define GX_BP_DSTALPHA_ALPHA_MASK (((1 << 8) - 1) << 31 - 31) +/* local mask */ #define GX_BP_DSTALPHA_ALPHA_LMASK ((1 << 8) - 1) +/* bit shift */ #define GX_BP_DSTALPHA_ALPHA_SHIFT 0 + +/* get value */ #define GX_BP_GET_DSTALPHA_ALPHA(reg) GX_BITGET((reg), 24, 8) +/* set value */ #define GX_BP_SET_DSTALPHA_ALPHA(reg, x) ((reg) = GX_BITSET((reg), 24, 8, x)) + // ENABLE [23:23] (1) -#define GX_BP_DSTALPHA_ENABLE_ST 23 -#define GX_BP_DSTALPHA_ENABLE_END 23 -#define GX_BP_DSTALPHA_ENABLE_SZ 1 -#define GX_BP_DSTALPHA_ENABLE_MASK (((1 << 1) - 1) << 31 - 23) -#define GX_BP_GET_DSTALPHA_ENABLE(reg) GX_BITGET(reg, 23, 1) -#define GX_BP_SET_DSTALPHA_ENABLE(reg, x) ((reg) = GX_BITSET(reg, 23, 1, x)) +/* start bit */ #define GX_BP_DSTALPHA_ENABLE_B 23 +/* end bit */ #define GX_BP_DSTALPHA_ENABLE_E 23 +/* bit size */ #define GX_BP_DSTALPHA_ENABLE_SZ 1 + +/* raw mask */ #define GX_BP_DSTALPHA_ENABLE_MASK (((1 << 1) - 1) << 31 - 23) +/* local mask */ #define GX_BP_DSTALPHA_ENABLE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_DSTALPHA_ENABLE_SHIFT 8 + +/* get value */ #define GX_BP_GET_DSTALPHA_ENABLE(reg) GX_BITGET((reg), 23, 1) +/* set value */ #define GX_BP_SET_DSTALPHA_ENABLE(reg, x) ((reg) = GX_BITSET((reg), 23, 1, x)) + // YUV_FMT [21:22] (2) -#define GX_BP_DSTALPHA_YUV_FMT_ST 21 -#define GX_BP_DSTALPHA_YUV_FMT_END 22 -#define GX_BP_DSTALPHA_YUV_FMT_SZ 2 -#define GX_BP_DSTALPHA_YUV_FMT_MASK (((1 << 2) - 1) << 31 - 22) -#define GX_BP_GET_DSTALPHA_YUV_FMT(reg) GX_BITGET(reg, 21, 2) -#define GX_BP_SET_DSTALPHA_YUV_FMT(reg, x) ((reg) = GX_BITSET(reg, 21, 2, x)) +/* start bit */ #define GX_BP_DSTALPHA_YUV_FMT_B 21 +/* end bit */ #define GX_BP_DSTALPHA_YUV_FMT_E 22 +/* bit size */ #define GX_BP_DSTALPHA_YUV_FMT_SZ 2 -/** +/* raw mask */ #define GX_BP_DSTALPHA_YUV_FMT_MASK (((1 << 2) - 1) << 31 - 22) +/* local mask */ #define GX_BP_DSTALPHA_YUV_FMT_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_DSTALPHA_YUV_FMT_SHIFT 9 + +/* get value */ #define GX_BP_GET_DSTALPHA_YUV_FMT(reg) GX_BITGET((reg), 21, 2) +/* set value */ #define GX_BP_SET_DSTALPHA_YUV_FMT(reg, x) ((reg) = GX_BITSET((reg), 21, 2, x)) + +/****************************************************************************** * BP register 0x43 - ZControl - */ + *****************************************************************************/ // PIXEL_FMT [29:31] (3) -#define GX_BP_ZCONTROL_PIXEL_FMT_ST 29 -#define GX_BP_ZCONTROL_PIXEL_FMT_END 31 -#define GX_BP_ZCONTROL_PIXEL_FMT_SZ 3 -#define GX_BP_ZCONTROL_PIXEL_FMT_MASK (((1 << 3) - 1) << 31 - 31) -#define GX_BP_GET_ZCONTROL_PIXEL_FMT(reg) GX_BITGET(reg, 29, 3) -#define GX_BP_SET_ZCONTROL_PIXEL_FMT(reg, x) ((reg) = GX_BITSET(reg, 29, 3, x)) +/* start bit */ #define GX_BP_ZCONTROL_PIXEL_FMT_B 29 +/* end bit */ #define GX_BP_ZCONTROL_PIXEL_FMT_E 31 +/* bit size */ #define GX_BP_ZCONTROL_PIXEL_FMT_SZ 3 + +/* raw mask */ #define GX_BP_ZCONTROL_PIXEL_FMT_MASK (((1 << 3) - 1) << 31 - 31) +/* local mask */ #define GX_BP_ZCONTROL_PIXEL_FMT_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_ZCONTROL_PIXEL_FMT_SHIFT 0 + +/* get value */ #define GX_BP_GET_ZCONTROL_PIXEL_FMT(reg) GX_BITGET((reg), 29, 3) +/* set value */ #define GX_BP_SET_ZCONTROL_PIXEL_FMT(reg, x) ((reg) = GX_BITSET((reg), 29, 3, x)) + // Z_FMT [26:28] (3) -#define GX_BP_ZCONTROL_Z_FMT_ST 26 -#define GX_BP_ZCONTROL_Z_FMT_END 28 -#define GX_BP_ZCONTROL_Z_FMT_SZ 3 -#define GX_BP_ZCONTROL_Z_FMT_MASK (((1 << 3) - 1) << 31 - 28) -#define GX_BP_GET_ZCONTROL_Z_FMT(reg) GX_BITGET(reg, 26, 3) -#define GX_BP_SET_ZCONTROL_Z_FMT(reg, x) ((reg) = GX_BITSET(reg, 26, 3, x)) +/* start bit */ #define GX_BP_ZCONTROL_Z_FMT_B 26 +/* end bit */ #define GX_BP_ZCONTROL_Z_FMT_E 28 +/* bit size */ #define GX_BP_ZCONTROL_Z_FMT_SZ 3 + +/* raw mask */ #define GX_BP_ZCONTROL_Z_FMT_MASK (((1 << 3) - 1) << 31 - 28) +/* local mask */ #define GX_BP_ZCONTROL_Z_FMT_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_ZCONTROL_Z_FMT_SHIFT 3 + +/* get value */ #define GX_BP_GET_ZCONTROL_Z_FMT(reg) GX_BITGET((reg), 26, 3) +/* set value */ #define GX_BP_SET_ZCONTROL_Z_FMT(reg, x) ((reg) = GX_BITSET((reg), 26, 3, x)) + // BEFORE_TEX [25:25] (1) - Determines whether Z-buffering occurs before or after texturing -#define GX_BP_ZCONTROL_BEFORE_TEX_ST 25 -#define GX_BP_ZCONTROL_BEFORE_TEX_END 25 -#define GX_BP_ZCONTROL_BEFORE_TEX_SZ 1 -#define GX_BP_ZCONTROL_BEFORE_TEX_MASK (((1 << 1) - 1) << 31 - 25) -#define GX_BP_GET_ZCONTROL_BEFORE_TEX(reg) GX_BITGET(reg, 25, 1) -#define GX_BP_SET_ZCONTROL_BEFORE_TEX(reg, x) ((reg) = GX_BITSET(reg, 25, 1, x)) +/* start bit */ #define GX_BP_ZCONTROL_BEFORE_TEX_B 25 +/* end bit */ #define GX_BP_ZCONTROL_BEFORE_TEX_E 25 +/* bit size */ #define GX_BP_ZCONTROL_BEFORE_TEX_SZ 1 -/** +/* raw mask */ #define GX_BP_ZCONTROL_BEFORE_TEX_MASK (((1 << 1) - 1) << 31 - 25) +/* local mask */ #define GX_BP_ZCONTROL_BEFORE_TEX_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_ZCONTROL_BEFORE_TEX_SHIFT 6 + +/* get value */ #define GX_BP_GET_ZCONTROL_BEFORE_TEX(reg) GX_BITGET((reg), 25, 1) +/* set value */ #define GX_BP_SET_ZCONTROL_BEFORE_TEX(reg, x) ((reg) = GX_BITSET((reg), 25, 1, x)) + +/****************************************************************************** * BP register 0x44 - FieldMask - */ + *****************************************************************************/ // ODD [31:31] (1) - Whether to write odd fields to the EFB -#define GX_BP_FIELDMASK_ODD_ST 31 -#define GX_BP_FIELDMASK_ODD_END 31 -#define GX_BP_FIELDMASK_ODD_SZ 1 -#define GX_BP_FIELDMASK_ODD_MASK (((1 << 1) - 1) << 31 - 31) -#define GX_BP_GET_FIELDMASK_ODD(reg) GX_BITGET(reg, 31, 1) -#define GX_BP_SET_FIELDMASK_ODD(reg, x) ((reg) = GX_BITSET(reg, 31, 1, x)) +/* start bit */ #define GX_BP_FIELDMASK_ODD_B 31 +/* end bit */ #define GX_BP_FIELDMASK_ODD_E 31 +/* bit size */ #define GX_BP_FIELDMASK_ODD_SZ 1 + +/* raw mask */ #define GX_BP_FIELDMASK_ODD_MASK (((1 << 1) - 1) << 31 - 31) +/* local mask */ #define GX_BP_FIELDMASK_ODD_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_FIELDMASK_ODD_SHIFT 0 + +/* get value */ #define GX_BP_GET_FIELDMASK_ODD(reg) GX_BITGET((reg), 31, 1) +/* set value */ #define GX_BP_SET_FIELDMASK_ODD(reg, x) ((reg) = GX_BITSET((reg), 31, 1, x)) + // EVEN [30:30] (1) - Whether to write even fields to the EFB -#define GX_BP_FIELDMASK_EVEN_ST 30 -#define GX_BP_FIELDMASK_EVEN_END 30 -#define GX_BP_FIELDMASK_EVEN_SZ 1 -#define GX_BP_FIELDMASK_EVEN_MASK (((1 << 1) - 1) << 31 - 30) -#define GX_BP_GET_FIELDMASK_EVEN(reg) GX_BITGET(reg, 30, 1) -#define GX_BP_SET_FIELDMASK_EVEN(reg, x) ((reg) = GX_BITSET(reg, 30, 1, x)) +/* start bit */ #define GX_BP_FIELDMASK_EVEN_B 30 +/* end bit */ #define GX_BP_FIELDMASK_EVEN_E 30 +/* bit size */ #define GX_BP_FIELDMASK_EVEN_SZ 1 -/** +/* raw mask */ #define GX_BP_FIELDMASK_EVEN_MASK (((1 << 1) - 1) << 31 - 30) +/* local mask */ #define GX_BP_FIELDMASK_EVEN_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_FIELDMASK_EVEN_SHIFT 1 + +/* get value */ #define GX_BP_GET_FIELDMASK_EVEN(reg) GX_BITGET((reg), 30, 1) +/* set value */ #define GX_BP_SET_FIELDMASK_EVEN(reg, x) ((reg) = GX_BITSET((reg), 30, 1, x)) + +/****************************************************************************** * BP register 0x59 - ScissorOffset - */ + *****************************************************************************/ // OX [22:31] (10) -#define GX_BP_SCISSOROFFSET_OX_ST 22 -#define GX_BP_SCISSOROFFSET_OX_END 31 -#define GX_BP_SCISSOROFFSET_OX_SZ 10 -#define GX_BP_SCISSOROFFSET_OX_MASK (((1 << 10) - 1) << 31 - 31) -#define GX_BP_GET_SCISSOROFFSET_OX(reg) GX_BITGET(reg, 22, 10) -#define GX_BP_SET_SCISSOROFFSET_OX(reg, x) ((reg) = GX_BITSET(reg, 22, 10, x)) +/* start bit */ #define GX_BP_SCISSOROFFSET_OX_B 22 +/* end bit */ #define GX_BP_SCISSOROFFSET_OX_E 31 +/* bit size */ #define GX_BP_SCISSOROFFSET_OX_SZ 10 + +/* raw mask */ #define GX_BP_SCISSOROFFSET_OX_MASK (((1 << 10) - 1) << 31 - 31) +/* local mask */ #define GX_BP_SCISSOROFFSET_OX_LMASK ((1 << 10) - 1) +/* bit shift */ #define GX_BP_SCISSOROFFSET_OX_SHIFT 0 + +/* get value */ #define GX_BP_GET_SCISSOROFFSET_OX(reg) GX_BITGET((reg), 22, 10) +/* set value */ #define GX_BP_SET_SCISSOROFFSET_OX(reg, x) ((reg) = GX_BITSET((reg), 22, 10, x)) + // OY [12:21] (10) -#define GX_BP_SCISSOROFFSET_OY_ST 12 -#define GX_BP_SCISSOROFFSET_OY_END 21 -#define GX_BP_SCISSOROFFSET_OY_SZ 10 -#define GX_BP_SCISSOROFFSET_OY_MASK (((1 << 10) - 1) << 31 - 21) -#define GX_BP_GET_SCISSOROFFSET_OY(reg) GX_BITGET(reg, 12, 10) -#define GX_BP_SET_SCISSOROFFSET_OY(reg, x) ((reg) = GX_BITSET(reg, 12, 10, x)) +/* start bit */ #define GX_BP_SCISSOROFFSET_OY_B 12 +/* end bit */ #define GX_BP_SCISSOROFFSET_OY_E 21 +/* bit size */ #define GX_BP_SCISSOROFFSET_OY_SZ 10 -/** +/* raw mask */ #define GX_BP_SCISSOROFFSET_OY_MASK (((1 << 10) - 1) << 31 - 21) +/* local mask */ #define GX_BP_SCISSOROFFSET_OY_LMASK ((1 << 10) - 1) +/* bit shift */ #define GX_BP_SCISSOROFFSET_OY_SHIFT 10 + +/* get value */ #define GX_BP_GET_SCISSOROFFSET_OY(reg) GX_BITGET((reg), 12, 10) +/* set value */ #define GX_BP_SET_SCISSOROFFSET_OY(reg, x) ((reg) = GX_BITSET((reg), 12, 10, x)) + +/****************************************************************************** * BP register 0x68 - FieldMode - */ + *****************************************************************************/ // TEX_LOD [31:31] (1) - Adjust vertex tex LOD computation to account for interlacing -#define GX_BP_FIELDMODE_TEX_LOD_ST 31 -#define GX_BP_FIELDMODE_TEX_LOD_END 31 -#define GX_BP_FIELDMODE_TEX_LOD_SZ 1 -#define GX_BP_FIELDMODE_TEX_LOD_MASK (((1 << 1) - 1) << 31 - 31) -#define GX_BP_GET_FIELDMODE_TEX_LOD(reg) GX_BITGET(reg, 31, 1) -#define GX_BP_SET_FIELDMODE_TEX_LOD(reg, x) ((reg) = GX_BITSET(reg, 31, 1, x)) +/* start bit */ #define GX_BP_FIELDMODE_TEX_LOD_B 31 +/* end bit */ #define GX_BP_FIELDMODE_TEX_LOD_E 31 +/* bit size */ #define GX_BP_FIELDMODE_TEX_LOD_SZ 1 -/** +/* raw mask */ #define GX_BP_FIELDMODE_TEX_LOD_MASK (((1 << 1) - 1) << 31 - 31) +/* local mask */ #define GX_BP_FIELDMODE_TEX_LOD_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_FIELDMODE_TEX_LOD_SHIFT 0 + +/* get value */ #define GX_BP_GET_FIELDMODE_TEX_LOD(reg) GX_BITGET((reg), 31, 1) +/* set value */ #define GX_BP_SET_FIELDMODE_TEX_LOD(reg, x) ((reg) = GX_BITSET((reg), 31, 1, x)) + +/****************************************************************************** + * BP structure - TevColorCombiner + *****************************************************************************/ +// D [28:31] (4) +/* start bit */ #define GX_BP_TEVCOLORCOMBINER_D_B 28 +/* end bit */ #define GX_BP_TEVCOLORCOMBINER_D_E 31 +/* bit size */ #define GX_BP_TEVCOLORCOMBINER_D_SZ 4 + +/* raw mask */ #define GX_BP_TEVCOLORCOMBINER_D_MASK (((1 << 4) - 1) << 31 - 31) +/* local mask */ #define GX_BP_TEVCOLORCOMBINER_D_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_TEVCOLORCOMBINER_D_SHIFT 0 + +/* get value */ #define GX_BP_GET_TEVCOLORCOMBINER_D(reg) GX_BITGET((reg), 28, 4) +/* set value */ #define GX_BP_SET_TEVCOLORCOMBINER_D(reg, x) ((reg) = GX_BITSET((reg), 28, 4, x)) + +// C [24:27] (4) +/* start bit */ #define GX_BP_TEVCOLORCOMBINER_C_B 24 +/* end bit */ #define GX_BP_TEVCOLORCOMBINER_C_E 27 +/* bit size */ #define GX_BP_TEVCOLORCOMBINER_C_SZ 4 + +/* raw mask */ #define GX_BP_TEVCOLORCOMBINER_C_MASK (((1 << 4) - 1) << 31 - 27) +/* local mask */ #define GX_BP_TEVCOLORCOMBINER_C_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_TEVCOLORCOMBINER_C_SHIFT 4 + +/* get value */ #define GX_BP_GET_TEVCOLORCOMBINER_C(reg) GX_BITGET((reg), 24, 4) +/* set value */ #define GX_BP_SET_TEVCOLORCOMBINER_C(reg, x) ((reg) = GX_BITSET((reg), 24, 4, x)) + +// B [20:23] (4) +/* start bit */ #define GX_BP_TEVCOLORCOMBINER_B_B 20 +/* end bit */ #define GX_BP_TEVCOLORCOMBINER_B_E 23 +/* bit size */ #define GX_BP_TEVCOLORCOMBINER_B_SZ 4 + +/* raw mask */ #define GX_BP_TEVCOLORCOMBINER_B_MASK (((1 << 4) - 1) << 31 - 23) +/* local mask */ #define GX_BP_TEVCOLORCOMBINER_B_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_TEVCOLORCOMBINER_B_SHIFT 8 + +/* get value */ #define GX_BP_GET_TEVCOLORCOMBINER_B(reg) GX_BITGET((reg), 20, 4) +/* set value */ #define GX_BP_SET_TEVCOLORCOMBINER_B(reg, x) ((reg) = GX_BITSET((reg), 20, 4, x)) + +// A [16:19] (4) +/* start bit */ #define GX_BP_TEVCOLORCOMBINER_A_B 16 +/* end bit */ #define GX_BP_TEVCOLORCOMBINER_A_E 19 +/* bit size */ #define GX_BP_TEVCOLORCOMBINER_A_SZ 4 + +/* raw mask */ #define GX_BP_TEVCOLORCOMBINER_A_MASK (((1 << 4) - 1) << 31 - 19) +/* local mask */ #define GX_BP_TEVCOLORCOMBINER_A_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_BP_TEVCOLORCOMBINER_A_SHIFT 12 + +/* get value */ #define GX_BP_GET_TEVCOLORCOMBINER_A(reg) GX_BITGET((reg), 16, 4) +/* set value */ #define GX_BP_SET_TEVCOLORCOMBINER_A(reg, x) ((reg) = GX_BITSET((reg), 16, 4, x)) + +// BIAS [14:15] (2) +/* start bit */ #define GX_BP_TEVCOLORCOMBINER_BIAS_B 14 +/* end bit */ #define GX_BP_TEVCOLORCOMBINER_BIAS_E 15 +/* bit size */ #define GX_BP_TEVCOLORCOMBINER_BIAS_SZ 2 + +/* raw mask */ #define GX_BP_TEVCOLORCOMBINER_BIAS_MASK (((1 << 2) - 1) << 31 - 15) +/* local mask */ #define GX_BP_TEVCOLORCOMBINER_BIAS_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_TEVCOLORCOMBINER_BIAS_SHIFT 16 + +/* get value */ #define GX_BP_GET_TEVCOLORCOMBINER_BIAS(reg) GX_BITGET((reg), 14, 2) +/* set value */ #define GX_BP_SET_TEVCOLORCOMBINER_BIAS(reg, x) ((reg) = GX_BITSET((reg), 14, 2, x)) + +// OP_OR_COMPARISON [13:13] (1) +/* start bit */ #define GX_BP_TEVCOLORCOMBINER_OP_OR_COMPARISON_B 13 +/* end bit */ #define GX_BP_TEVCOLORCOMBINER_OP_OR_COMPARISON_E 13 +/* bit size */ #define GX_BP_TEVCOLORCOMBINER_OP_OR_COMPARISON_SZ 1 + +/* raw mask */ #define GX_BP_TEVCOLORCOMBINER_OP_OR_COMPARISON_MASK (((1 << 1) - 1) << 31 - 13) +/* local mask */ #define GX_BP_TEVCOLORCOMBINER_OP_OR_COMPARISON_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_TEVCOLORCOMBINER_OP_OR_COMPARISON_SHIFT 18 + +/* get value */ #define GX_BP_GET_TEVCOLORCOMBINER_OP_OR_COMPARISON(reg) GX_BITGET((reg), 13, 1) +/* set value */ #define GX_BP_SET_TEVCOLORCOMBINER_OP_OR_COMPARISON(reg, x) ((reg) = GX_BITSET((reg), 13, 1, x)) + +// CLAMP [12:12] (1) +/* start bit */ #define GX_BP_TEVCOLORCOMBINER_CLAMP_B 12 +/* end bit */ #define GX_BP_TEVCOLORCOMBINER_CLAMP_E 12 +/* bit size */ #define GX_BP_TEVCOLORCOMBINER_CLAMP_SZ 1 + +/* raw mask */ #define GX_BP_TEVCOLORCOMBINER_CLAMP_MASK (((1 << 1) - 1) << 31 - 12) +/* local mask */ #define GX_BP_TEVCOLORCOMBINER_CLAMP_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_TEVCOLORCOMBINER_CLAMP_SHIFT 19 + +/* get value */ #define GX_BP_GET_TEVCOLORCOMBINER_CLAMP(reg) GX_BITGET((reg), 12, 1) +/* set value */ #define GX_BP_SET_TEVCOLORCOMBINER_CLAMP(reg, x) ((reg) = GX_BITSET((reg), 12, 1, x)) + +// SCALE_OR_COMPARE_MODE [10:11] (2) +/* start bit */ #define GX_BP_TEVCOLORCOMBINER_SCALE_OR_COMPARE_MODE_B 10 +/* end bit */ #define GX_BP_TEVCOLORCOMBINER_SCALE_OR_COMPARE_MODE_E 11 +/* bit size */ #define GX_BP_TEVCOLORCOMBINER_SCALE_OR_COMPARE_MODE_SZ 2 + +/* raw mask */ #define GX_BP_TEVCOLORCOMBINER_SCALE_OR_COMPARE_MODE_MASK (((1 << 2) - 1) << 31 - 11) +/* local mask */ #define GX_BP_TEVCOLORCOMBINER_SCALE_OR_COMPARE_MODE_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_TEVCOLORCOMBINER_SCALE_OR_COMPARE_MODE_SHIFT 20 + +/* get value */ #define GX_BP_GET_TEVCOLORCOMBINER_SCALE_OR_COMPARE_MODE(reg) GX_BITGET((reg), 10, 2) +/* set value */ #define GX_BP_SET_TEVCOLORCOMBINER_SCALE_OR_COMPARE_MODE(reg, x) ((reg) = GX_BITSET((reg), 10, 2, x)) + +// DEST [8:9] (2) +/* start bit */ #define GX_BP_TEVCOLORCOMBINER_DEST_B 8 +/* end bit */ #define GX_BP_TEVCOLORCOMBINER_DEST_E 9 +/* bit size */ #define GX_BP_TEVCOLORCOMBINER_DEST_SZ 2 + +/* raw mask */ #define GX_BP_TEVCOLORCOMBINER_DEST_MASK (((1 << 2) - 1) << 31 - 9) +/* local mask */ #define GX_BP_TEVCOLORCOMBINER_DEST_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_TEVCOLORCOMBINER_DEST_SHIFT 22 + +/* get value */ #define GX_BP_GET_TEVCOLORCOMBINER_DEST(reg) GX_BITGET((reg), 8, 2) +/* set value */ #define GX_BP_SET_TEVCOLORCOMBINER_DEST(reg, x) ((reg) = GX_BITSET((reg), 8, 2, x)) + +/****************************************************************************** + * BP structure - TevRegLo + *****************************************************************************/ +// RED [21:31] (11) +/* start bit */ #define GX_BP_TEVREGLO_RED_B 21 +/* end bit */ #define GX_BP_TEVREGLO_RED_E 31 +/* bit size */ #define GX_BP_TEVREGLO_RED_SZ 11 + +/* raw mask */ #define GX_BP_TEVREGLO_RED_MASK (((1 << 11) - 1) << 31 - 31) +/* local mask */ #define GX_BP_TEVREGLO_RED_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_TEVREGLO_RED_SHIFT 0 + +/* get value */ #define GX_BP_GET_TEVREGLO_RED(reg) GX_BITGET((reg), 21, 11) +/* set value */ #define GX_BP_SET_TEVREGLO_RED(reg, x) ((reg) = GX_BITSET((reg), 21, 11, x)) + +// ALPHA [9:19] (11) +/* start bit */ #define GX_BP_TEVREGLO_ALPHA_B 9 +/* end bit */ #define GX_BP_TEVREGLO_ALPHA_E 19 +/* bit size */ #define GX_BP_TEVREGLO_ALPHA_SZ 11 + +/* raw mask */ #define GX_BP_TEVREGLO_ALPHA_MASK (((1 << 11) - 1) << 31 - 19) +/* local mask */ #define GX_BP_TEVREGLO_ALPHA_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_TEVREGLO_ALPHA_SHIFT 12 + +/* get value */ #define GX_BP_GET_TEVREGLO_ALPHA(reg) GX_BITGET((reg), 9, 11) +/* set value */ #define GX_BP_SET_TEVREGLO_ALPHA(reg, x) ((reg) = GX_BITSET((reg), 9, 11, x)) + +// TYPE [8:8] (1) +/* start bit */ #define GX_BP_TEVREGLO_TYPE_B 8 +/* end bit */ #define GX_BP_TEVREGLO_TYPE_E 8 +/* bit size */ #define GX_BP_TEVREGLO_TYPE_SZ 1 + +/* raw mask */ #define GX_BP_TEVREGLO_TYPE_MASK (((1 << 1) - 1) << 31 - 8) +/* local mask */ #define GX_BP_TEVREGLO_TYPE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_TEVREGLO_TYPE_SHIFT 23 + +/* get value */ #define GX_BP_GET_TEVREGLO_TYPE(reg) GX_BITGET((reg), 8, 1) +/* set value */ #define GX_BP_SET_TEVREGLO_TYPE(reg, x) ((reg) = GX_BITSET((reg), 8, 1, x)) + +/****************************************************************************** + * BP structure - TevRegHi + *****************************************************************************/ +// BLUE [21:31] (11) +/* start bit */ #define GX_BP_TEVREGHI_BLUE_B 21 +/* end bit */ #define GX_BP_TEVREGHI_BLUE_E 31 +/* bit size */ #define GX_BP_TEVREGHI_BLUE_SZ 11 + +/* raw mask */ #define GX_BP_TEVREGHI_BLUE_MASK (((1 << 11) - 1) << 31 - 31) +/* local mask */ #define GX_BP_TEVREGHI_BLUE_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_TEVREGHI_BLUE_SHIFT 0 + +/* get value */ #define GX_BP_GET_TEVREGHI_BLUE(reg) GX_BITGET((reg), 21, 11) +/* set value */ #define GX_BP_SET_TEVREGHI_BLUE(reg, x) ((reg) = GX_BITSET((reg), 21, 11, x)) + +// GREEN [9:19] (11) +/* start bit */ #define GX_BP_TEVREGHI_GREEN_B 9 +/* end bit */ #define GX_BP_TEVREGHI_GREEN_E 19 +/* bit size */ #define GX_BP_TEVREGHI_GREEN_SZ 11 + +/* raw mask */ #define GX_BP_TEVREGHI_GREEN_MASK (((1 << 11) - 1) << 31 - 19) +/* local mask */ #define GX_BP_TEVREGHI_GREEN_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_TEVREGHI_GREEN_SHIFT 12 + +/* get value */ #define GX_BP_GET_TEVREGHI_GREEN(reg) GX_BITGET((reg), 9, 11) +/* set value */ #define GX_BP_SET_TEVREGHI_GREEN(reg, x) ((reg) = GX_BITSET((reg), 9, 11, x)) + +// TYPE [8:8] (1) +/* start bit */ #define GX_BP_TEVREGHI_TYPE_B 8 +/* end bit */ #define GX_BP_TEVREGHI_TYPE_E 8 +/* bit size */ #define GX_BP_TEVREGHI_TYPE_SZ 1 + +/* raw mask */ #define GX_BP_TEVREGHI_TYPE_MASK (((1 << 1) - 1) << 31 - 8) +/* local mask */ #define GX_BP_TEVREGHI_TYPE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_TEVREGHI_TYPE_SHIFT 23 + +/* get value */ #define GX_BP_GET_TEVREGHI_TYPE(reg) GX_BITGET((reg), 8, 1) +/* set value */ #define GX_BP_SET_TEVREGHI_TYPE(reg, x) ((reg) = GX_BITSET((reg), 8, 1, x)) + +/****************************************************************************** * BP register 0xE8 - FogRange - */ + *****************************************************************************/ // CENTER [22:31] (10) -#define GX_BP_FOGRANGE_CENTER_ST 22 -#define GX_BP_FOGRANGE_CENTER_END 31 -#define GX_BP_FOGRANGE_CENTER_SZ 10 -#define GX_BP_FOGRANGE_CENTER_MASK (((1 << 10) - 1) << 31 - 31) -#define GX_BP_GET_FOGRANGE_CENTER(reg) GX_BITGET(reg, 22, 10) -#define GX_BP_SET_FOGRANGE_CENTER(reg, x) ((reg) = GX_BITSET(reg, 22, 10, x)) +/* start bit */ #define GX_BP_FOGRANGE_CENTER_B 22 +/* end bit */ #define GX_BP_FOGRANGE_CENTER_E 31 +/* bit size */ #define GX_BP_FOGRANGE_CENTER_SZ 10 + +/* raw mask */ #define GX_BP_FOGRANGE_CENTER_MASK (((1 << 10) - 1) << 31 - 31) +/* local mask */ #define GX_BP_FOGRANGE_CENTER_LMASK ((1 << 10) - 1) +/* bit shift */ #define GX_BP_FOGRANGE_CENTER_SHIFT 0 + +/* get value */ #define GX_BP_GET_FOGRANGE_CENTER(reg) GX_BITGET((reg), 22, 10) +/* set value */ #define GX_BP_SET_FOGRANGE_CENTER(reg, x) ((reg) = GX_BITSET((reg), 22, 10, x)) + // ENABLED [21:21] (1) -#define GX_BP_FOGRANGE_ENABLED_ST 21 -#define GX_BP_FOGRANGE_ENABLED_END 21 -#define GX_BP_FOGRANGE_ENABLED_SZ 1 -#define GX_BP_FOGRANGE_ENABLED_MASK (((1 << 1) - 1) << 31 - 21) -#define GX_BP_GET_FOGRANGE_ENABLED(reg) GX_BITGET(reg, 21, 1) -#define GX_BP_SET_FOGRANGE_ENABLED(reg, x) ((reg) = GX_BITSET(reg, 21, 1, x)) +/* start bit */ #define GX_BP_FOGRANGE_ENABLED_B 21 +/* end bit */ #define GX_BP_FOGRANGE_ENABLED_E 21 +/* bit size */ #define GX_BP_FOGRANGE_ENABLED_SZ 1 -/** +/* raw mask */ #define GX_BP_FOGRANGE_ENABLED_MASK (((1 << 1) - 1) << 31 - 21) +/* local mask */ #define GX_BP_FOGRANGE_ENABLED_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_FOGRANGE_ENABLED_SHIFT 10 + +/* get value */ #define GX_BP_GET_FOGRANGE_ENABLED(reg) GX_BITGET((reg), 21, 1) +/* set value */ #define GX_BP_SET_FOGRANGE_ENABLED(reg, x) ((reg) = GX_BITSET((reg), 21, 1, x)) + +/****************************************************************************** * BP structure - FogRangeK - */ + *****************************************************************************/ // HI [20:31] (12) -#define GX_BP_FOGRANGEK_HI_ST 20 -#define GX_BP_FOGRANGEK_HI_END 31 -#define GX_BP_FOGRANGEK_HI_SZ 12 -#define GX_BP_FOGRANGEK_HI_MASK (((1 << 12) - 1) << 31 - 31) -#define GX_BP_GET_FOGRANGEK_HI(reg) GX_BITGET(reg, 20, 12) -#define GX_BP_SET_FOGRANGEK_HI(reg, x) ((reg) = GX_BITSET(reg, 20, 12, x)) +/* start bit */ #define GX_BP_FOGRANGEK_HI_B 20 +/* end bit */ #define GX_BP_FOGRANGEK_HI_E 31 +/* bit size */ #define GX_BP_FOGRANGEK_HI_SZ 12 + +/* raw mask */ #define GX_BP_FOGRANGEK_HI_MASK (((1 << 12) - 1) << 31 - 31) +/* local mask */ #define GX_BP_FOGRANGEK_HI_LMASK ((1 << 12) - 1) +/* bit shift */ #define GX_BP_FOGRANGEK_HI_SHIFT 0 + +/* get value */ #define GX_BP_GET_FOGRANGEK_HI(reg) GX_BITGET((reg), 20, 12) +/* set value */ #define GX_BP_SET_FOGRANGEK_HI(reg, x) ((reg) = GX_BITSET((reg), 20, 12, x)) + // LO [8:19] (12) -#define GX_BP_FOGRANGEK_LO_ST 8 -#define GX_BP_FOGRANGEK_LO_END 19 -#define GX_BP_FOGRANGEK_LO_SZ 12 -#define GX_BP_FOGRANGEK_LO_MASK (((1 << 12) - 1) << 31 - 19) -#define GX_BP_GET_FOGRANGEK_LO(reg) GX_BITGET(reg, 8, 12) -#define GX_BP_SET_FOGRANGEK_LO(reg, x) ((reg) = GX_BITSET(reg, 8, 12, x)) +/* start bit */ #define GX_BP_FOGRANGEK_LO_B 8 +/* end bit */ #define GX_BP_FOGRANGEK_LO_E 19 +/* bit size */ #define GX_BP_FOGRANGEK_LO_SZ 12 -/** +/* raw mask */ #define GX_BP_FOGRANGEK_LO_MASK (((1 << 12) - 1) << 31 - 19) +/* local mask */ #define GX_BP_FOGRANGEK_LO_LMASK ((1 << 12) - 1) +/* bit shift */ #define GX_BP_FOGRANGEK_LO_SHIFT 12 + +/* get value */ #define GX_BP_GET_FOGRANGEK_LO(reg) GX_BITGET((reg), 8, 12) +/* set value */ #define GX_BP_SET_FOGRANGEK_LO(reg, x) ((reg) = GX_BITSET((reg), 8, 12, x)) + +/****************************************************************************** * BP register 0xEE - FogParam0 - */ + *****************************************************************************/ // A_MANT [21:31] (11) -#define GX_BP_FOGPARAM0_A_MANT_ST 21 -#define GX_BP_FOGPARAM0_A_MANT_END 31 -#define GX_BP_FOGPARAM0_A_MANT_SZ 11 -#define GX_BP_FOGPARAM0_A_MANT_MASK (((1 << 11) - 1) << 31 - 31) -#define GX_BP_GET_FOGPARAM0_A_MANT(reg) GX_BITGET(reg, 21, 11) -#define GX_BP_SET_FOGPARAM0_A_MANT(reg, x) ((reg) = GX_BITSET(reg, 21, 11, x)) +/* start bit */ #define GX_BP_FOGPARAM0_A_MANT_B 21 +/* end bit */ #define GX_BP_FOGPARAM0_A_MANT_E 31 +/* bit size */ #define GX_BP_FOGPARAM0_A_MANT_SZ 11 + +/* raw mask */ #define GX_BP_FOGPARAM0_A_MANT_MASK (((1 << 11) - 1) << 31 - 31) +/* local mask */ #define GX_BP_FOGPARAM0_A_MANT_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_FOGPARAM0_A_MANT_SHIFT 0 + +/* get value */ #define GX_BP_GET_FOGPARAM0_A_MANT(reg) GX_BITGET((reg), 21, 11) +/* set value */ #define GX_BP_SET_FOGPARAM0_A_MANT(reg, x) ((reg) = GX_BITSET((reg), 21, 11, x)) + // A_EXP [13:20] (8) -#define GX_BP_FOGPARAM0_A_EXP_ST 13 -#define GX_BP_FOGPARAM0_A_EXP_END 20 -#define GX_BP_FOGPARAM0_A_EXP_SZ 8 -#define GX_BP_FOGPARAM0_A_EXP_MASK (((1 << 8) - 1) << 31 - 20) -#define GX_BP_GET_FOGPARAM0_A_EXP(reg) GX_BITGET(reg, 13, 8) -#define GX_BP_SET_FOGPARAM0_A_EXP(reg, x) ((reg) = GX_BITSET(reg, 13, 8, x)) +/* start bit */ #define GX_BP_FOGPARAM0_A_EXP_B 13 +/* end bit */ #define GX_BP_FOGPARAM0_A_EXP_E 20 +/* bit size */ #define GX_BP_FOGPARAM0_A_EXP_SZ 8 + +/* raw mask */ #define GX_BP_FOGPARAM0_A_EXP_MASK (((1 << 8) - 1) << 31 - 20) +/* local mask */ #define GX_BP_FOGPARAM0_A_EXP_LMASK ((1 << 8) - 1) +/* bit shift */ #define GX_BP_FOGPARAM0_A_EXP_SHIFT 11 + +/* get value */ #define GX_BP_GET_FOGPARAM0_A_EXP(reg) GX_BITGET((reg), 13, 8) +/* set value */ #define GX_BP_SET_FOGPARAM0_A_EXP(reg, x) ((reg) = GX_BITSET((reg), 13, 8, x)) + // A_SIGN [12:12] (1) -#define GX_BP_FOGPARAM0_A_SIGN_ST 12 -#define GX_BP_FOGPARAM0_A_SIGN_END 12 -#define GX_BP_FOGPARAM0_A_SIGN_SZ 1 -#define GX_BP_FOGPARAM0_A_SIGN_MASK (((1 << 1) - 1) << 31 - 12) -#define GX_BP_GET_FOGPARAM0_A_SIGN(reg) GX_BITGET(reg, 12, 1) -#define GX_BP_SET_FOGPARAM0_A_SIGN(reg, x) ((reg) = GX_BITSET(reg, 12, 1, x)) +/* start bit */ #define GX_BP_FOGPARAM0_A_SIGN_B 12 +/* end bit */ #define GX_BP_FOGPARAM0_A_SIGN_E 12 +/* bit size */ #define GX_BP_FOGPARAM0_A_SIGN_SZ 1 -/** +/* raw mask */ #define GX_BP_FOGPARAM0_A_SIGN_MASK (((1 << 1) - 1) << 31 - 12) +/* local mask */ #define GX_BP_FOGPARAM0_A_SIGN_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_FOGPARAM0_A_SIGN_SHIFT 19 + +/* get value */ #define GX_BP_GET_FOGPARAM0_A_SIGN(reg) GX_BITGET((reg), 12, 1) +/* set value */ #define GX_BP_SET_FOGPARAM0_A_SIGN(reg, x) ((reg) = GX_BITSET((reg), 12, 1, x)) + +/****************************************************************************** * BP register 0xEF - FogParam1 - */ + *****************************************************************************/ // B_MAG [8:31] (24) -#define GX_BP_FOGPARAM1_B_MAG_ST 8 -#define GX_BP_FOGPARAM1_B_MAG_END 31 -#define GX_BP_FOGPARAM1_B_MAG_SZ 24 -#define GX_BP_FOGPARAM1_B_MAG_MASK (((1 << 24) - 1) << 31 - 31) -#define GX_BP_GET_FOGPARAM1_B_MAG(reg) GX_BITGET(reg, 8, 24) -#define GX_BP_SET_FOGPARAM1_B_MAG(reg, x) ((reg) = GX_BITSET(reg, 8, 24, x)) +/* start bit */ #define GX_BP_FOGPARAM1_B_MAG_B 8 +/* end bit */ #define GX_BP_FOGPARAM1_B_MAG_E 31 +/* bit size */ #define GX_BP_FOGPARAM1_B_MAG_SZ 24 -/** +/* raw mask */ #define GX_BP_FOGPARAM1_B_MAG_MASK (((1 << 24) - 1) << 31 - 31) +/* local mask */ #define GX_BP_FOGPARAM1_B_MAG_LMASK ((1 << 24) - 1) +/* bit shift */ #define GX_BP_FOGPARAM1_B_MAG_SHIFT 0 + +/* get value */ #define GX_BP_GET_FOGPARAM1_B_MAG(reg) GX_BITGET((reg), 8, 24) +/* set value */ #define GX_BP_SET_FOGPARAM1_B_MAG(reg, x) ((reg) = GX_BITSET((reg), 8, 24, x)) + +/****************************************************************************** * BP register 0xF0 - FogParam2 - */ + *****************************************************************************/ // B_SHIFT [27:31] (5) -#define GX_BP_FOGPARAM2_B_SHIFT_ST 27 -#define GX_BP_FOGPARAM2_B_SHIFT_END 31 -#define GX_BP_FOGPARAM2_B_SHIFT_SZ 5 -#define GX_BP_FOGPARAM2_B_SHIFT_MASK (((1 << 5) - 1) << 31 - 31) -#define GX_BP_GET_FOGPARAM2_B_SHIFT(reg) GX_BITGET(reg, 27, 5) -#define GX_BP_SET_FOGPARAM2_B_SHIFT(reg, x) ((reg) = GX_BITSET(reg, 27, 5, x)) +/* start bit */ #define GX_BP_FOGPARAM2_B_SHIFT_B 27 +/* end bit */ #define GX_BP_FOGPARAM2_B_SHIFT_E 31 +/* bit size */ #define GX_BP_FOGPARAM2_B_SHIFT_SZ 5 -/** +/* raw mask */ #define GX_BP_FOGPARAM2_B_SHIFT_MASK (((1 << 5) - 1) << 31 - 31) +/* local mask */ #define GX_BP_FOGPARAM2_B_SHIFT_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_BP_FOGPARAM2_B_SHIFT_SHIFT 0 + +/* get value */ #define GX_BP_GET_FOGPARAM2_B_SHIFT(reg) GX_BITGET((reg), 27, 5) +/* set value */ #define GX_BP_SET_FOGPARAM2_B_SHIFT(reg, x) ((reg) = GX_BITSET((reg), 27, 5, x)) + +/****************************************************************************** * BP register 0xF1 - FogParam3 - */ + *****************************************************************************/ // C_MANT [21:31] (11) -#define GX_BP_FOGPARAM3_C_MANT_ST 21 -#define GX_BP_FOGPARAM3_C_MANT_END 31 -#define GX_BP_FOGPARAM3_C_MANT_SZ 11 -#define GX_BP_FOGPARAM3_C_MANT_MASK (((1 << 11) - 1) << 31 - 31) -#define GX_BP_GET_FOGPARAM3_C_MANT(reg) GX_BITGET(reg, 21, 11) -#define GX_BP_SET_FOGPARAM3_C_MANT(reg, x) ((reg) = GX_BITSET(reg, 21, 11, x)) -// C_EXP [13:20] (8) -#define GX_BP_FOGPARAM3_C_EXP_ST 13 -#define GX_BP_FOGPARAM3_C_EXP_END 20 -#define GX_BP_FOGPARAM3_C_EXP_SZ 8 -#define GX_BP_FOGPARAM3_C_EXP_MASK (((1 << 8) - 1) << 31 - 20) -#define GX_BP_GET_FOGPARAM3_C_EXP(reg) GX_BITGET(reg, 13, 8) -#define GX_BP_SET_FOGPARAM3_C_EXP(reg, x) ((reg) = GX_BITSET(reg, 13, 8, x)) -// C_SIGN [12:12] (1) -#define GX_BP_FOGPARAM3_C_SIGN_ST 12 -#define GX_BP_FOGPARAM3_C_SIGN_END 12 -#define GX_BP_FOGPARAM3_C_SIGN_SZ 1 -#define GX_BP_FOGPARAM3_C_SIGN_MASK (((1 << 1) - 1) << 31 - 12) -#define GX_BP_GET_FOGPARAM3_C_SIGN(reg) GX_BITGET(reg, 12, 1) -#define GX_BP_SET_FOGPARAM3_C_SIGN(reg, x) ((reg) = GX_BITSET(reg, 12, 1, x)) -// PROJ [11:11] (1) -#define GX_BP_FOGPARAM3_PROJ_ST 11 -#define GX_BP_FOGPARAM3_PROJ_END 11 -#define GX_BP_FOGPARAM3_PROJ_SZ 1 -#define GX_BP_FOGPARAM3_PROJ_MASK (((1 << 1) - 1) << 31 - 11) -#define GX_BP_GET_FOGPARAM3_PROJ(reg) GX_BITGET(reg, 11, 1) -#define GX_BP_SET_FOGPARAM3_PROJ(reg, x) ((reg) = GX_BITSET(reg, 11, 1, x)) -// FSEL [8:10] (3) -#define GX_BP_FOGPARAM3_FSEL_ST 8 -#define GX_BP_FOGPARAM3_FSEL_END 10 -#define GX_BP_FOGPARAM3_FSEL_SZ 3 -#define GX_BP_FOGPARAM3_FSEL_MASK (((1 << 3) - 1) << 31 - 10) -#define GX_BP_GET_FOGPARAM3_FSEL(reg) GX_BITGET(reg, 8, 3) -#define GX_BP_SET_FOGPARAM3_FSEL(reg, x) ((reg) = GX_BITSET(reg, 8, 3, x)) +/* start bit */ #define GX_BP_FOGPARAM3_C_MANT_B 21 +/* end bit */ #define GX_BP_FOGPARAM3_C_MANT_E 31 +/* bit size */ #define GX_BP_FOGPARAM3_C_MANT_SZ 11 -/** +/* raw mask */ #define GX_BP_FOGPARAM3_C_MANT_MASK (((1 << 11) - 1) << 31 - 31) +/* local mask */ #define GX_BP_FOGPARAM3_C_MANT_LMASK ((1 << 11) - 1) +/* bit shift */ #define GX_BP_FOGPARAM3_C_MANT_SHIFT 0 + +/* get value */ #define GX_BP_GET_FOGPARAM3_C_MANT(reg) GX_BITGET((reg), 21, 11) +/* set value */ #define GX_BP_SET_FOGPARAM3_C_MANT(reg, x) ((reg) = GX_BITSET((reg), 21, 11, x)) + +// C_EXP [13:20] (8) +/* start bit */ #define GX_BP_FOGPARAM3_C_EXP_B 13 +/* end bit */ #define GX_BP_FOGPARAM3_C_EXP_E 20 +/* bit size */ #define GX_BP_FOGPARAM3_C_EXP_SZ 8 + +/* raw mask */ #define GX_BP_FOGPARAM3_C_EXP_MASK (((1 << 8) - 1) << 31 - 20) +/* local mask */ #define GX_BP_FOGPARAM3_C_EXP_LMASK ((1 << 8) - 1) +/* bit shift */ #define GX_BP_FOGPARAM3_C_EXP_SHIFT 11 + +/* get value */ #define GX_BP_GET_FOGPARAM3_C_EXP(reg) GX_BITGET((reg), 13, 8) +/* set value */ #define GX_BP_SET_FOGPARAM3_C_EXP(reg, x) ((reg) = GX_BITSET((reg), 13, 8, x)) + +// C_SIGN [12:12] (1) +/* start bit */ #define GX_BP_FOGPARAM3_C_SIGN_B 12 +/* end bit */ #define GX_BP_FOGPARAM3_C_SIGN_E 12 +/* bit size */ #define GX_BP_FOGPARAM3_C_SIGN_SZ 1 + +/* raw mask */ #define GX_BP_FOGPARAM3_C_SIGN_MASK (((1 << 1) - 1) << 31 - 12) +/* local mask */ #define GX_BP_FOGPARAM3_C_SIGN_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_FOGPARAM3_C_SIGN_SHIFT 19 + +/* get value */ #define GX_BP_GET_FOGPARAM3_C_SIGN(reg) GX_BITGET((reg), 12, 1) +/* set value */ #define GX_BP_SET_FOGPARAM3_C_SIGN(reg, x) ((reg) = GX_BITSET((reg), 12, 1, x)) + +// PROJ [11:11] (1) +/* start bit */ #define GX_BP_FOGPARAM3_PROJ_B 11 +/* end bit */ #define GX_BP_FOGPARAM3_PROJ_E 11 +/* bit size */ #define GX_BP_FOGPARAM3_PROJ_SZ 1 + +/* raw mask */ #define GX_BP_FOGPARAM3_PROJ_MASK (((1 << 1) - 1) << 31 - 11) +/* local mask */ #define GX_BP_FOGPARAM3_PROJ_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_BP_FOGPARAM3_PROJ_SHIFT 20 + +/* get value */ #define GX_BP_GET_FOGPARAM3_PROJ(reg) GX_BITGET((reg), 11, 1) +/* set value */ #define GX_BP_SET_FOGPARAM3_PROJ(reg, x) ((reg) = GX_BITSET((reg), 11, 1, x)) + +// FSEL [8:10] (3) +/* start bit */ #define GX_BP_FOGPARAM3_FSEL_B 8 +/* end bit */ #define GX_BP_FOGPARAM3_FSEL_E 10 +/* bit size */ #define GX_BP_FOGPARAM3_FSEL_SZ 3 + +/* raw mask */ #define GX_BP_FOGPARAM3_FSEL_MASK (((1 << 3) - 1) << 31 - 10) +/* local mask */ #define GX_BP_FOGPARAM3_FSEL_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_FOGPARAM3_FSEL_SHIFT 21 + +/* get value */ #define GX_BP_GET_FOGPARAM3_FSEL(reg) GX_BITGET((reg), 8, 3) +/* set value */ #define GX_BP_SET_FOGPARAM3_FSEL(reg, x) ((reg) = GX_BITSET((reg), 8, 3, x)) + +/****************************************************************************** * BP register 0xF2 - FogColor - */ + *****************************************************************************/ // RGB [8:31] (24) -#define GX_BP_FOGCOLOR_RGB_ST 8 -#define GX_BP_FOGCOLOR_RGB_END 31 -#define GX_BP_FOGCOLOR_RGB_SZ 24 -#define GX_BP_FOGCOLOR_RGB_MASK (((1 << 24) - 1) << 31 - 31) -#define GX_BP_GET_FOGCOLOR_RGB(reg) GX_BITGET(reg, 8, 24) -#define GX_BP_SET_FOGCOLOR_RGB(reg, x) ((reg) = GX_BITSET(reg, 8, 24, x)) +/* start bit */ #define GX_BP_FOGCOLOR_RGB_B 8 +/* end bit */ #define GX_BP_FOGCOLOR_RGB_E 31 +/* bit size */ #define GX_BP_FOGCOLOR_RGB_SZ 24 + +/* raw mask */ #define GX_BP_FOGCOLOR_RGB_MASK (((1 << 24) - 1) << 31 - 31) +/* local mask */ #define GX_BP_FOGCOLOR_RGB_LMASK ((1 << 24) - 1) +/* bit shift */ #define GX_BP_FOGCOLOR_RGB_SHIFT 0 + +/* get value */ #define GX_BP_GET_FOGCOLOR_RGB(reg) GX_BITGET((reg), 8, 24) +/* set value */ #define GX_BP_SET_FOGCOLOR_RGB(reg, x) ((reg) = GX_BITSET((reg), 8, 24, x)) + +/****************************************************************************** + * BP register 0xF3 - AlphaCompare + *****************************************************************************/ +// REF0 [24:31] (8) +/* start bit */ #define GX_BP_ALPHACOMPARE_REF0_B 24 +/* end bit */ #define GX_BP_ALPHACOMPARE_REF0_E 31 +/* bit size */ #define GX_BP_ALPHACOMPARE_REF0_SZ 8 + +/* raw mask */ #define GX_BP_ALPHACOMPARE_REF0_MASK (((1 << 8) - 1) << 31 - 31) +/* local mask */ #define GX_BP_ALPHACOMPARE_REF0_LMASK ((1 << 8) - 1) +/* bit shift */ #define GX_BP_ALPHACOMPARE_REF0_SHIFT 0 + +/* get value */ #define GX_BP_GET_ALPHACOMPARE_REF0(reg) GX_BITGET((reg), 24, 8) +/* set value */ #define GX_BP_SET_ALPHACOMPARE_REF0(reg, x) ((reg) = GX_BITSET((reg), 24, 8, x)) + +// REF1 [16:23] (8) +/* start bit */ #define GX_BP_ALPHACOMPARE_REF1_B 16 +/* end bit */ #define GX_BP_ALPHACOMPARE_REF1_E 23 +/* bit size */ #define GX_BP_ALPHACOMPARE_REF1_SZ 8 + +/* raw mask */ #define GX_BP_ALPHACOMPARE_REF1_MASK (((1 << 8) - 1) << 31 - 23) +/* local mask */ #define GX_BP_ALPHACOMPARE_REF1_LMASK ((1 << 8) - 1) +/* bit shift */ #define GX_BP_ALPHACOMPARE_REF1_SHIFT 8 + +/* get value */ #define GX_BP_GET_ALPHACOMPARE_REF1(reg) GX_BITGET((reg), 16, 8) +/* set value */ #define GX_BP_SET_ALPHACOMPARE_REF1(reg, x) ((reg) = GX_BITSET((reg), 16, 8, x)) + +// COMP0 [13:15] (3) +/* start bit */ #define GX_BP_ALPHACOMPARE_COMP0_B 13 +/* end bit */ #define GX_BP_ALPHACOMPARE_COMP0_E 15 +/* bit size */ #define GX_BP_ALPHACOMPARE_COMP0_SZ 3 + +/* raw mask */ #define GX_BP_ALPHACOMPARE_COMP0_MASK (((1 << 3) - 1) << 31 - 15) +/* local mask */ #define GX_BP_ALPHACOMPARE_COMP0_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_ALPHACOMPARE_COMP0_SHIFT 16 + +/* get value */ #define GX_BP_GET_ALPHACOMPARE_COMP0(reg) GX_BITGET((reg), 13, 3) +/* set value */ #define GX_BP_SET_ALPHACOMPARE_COMP0(reg, x) ((reg) = GX_BITSET((reg), 13, 3, x)) + +// COMP1 [10:12] (3) +/* start bit */ #define GX_BP_ALPHACOMPARE_COMP1_B 10 +/* end bit */ #define GX_BP_ALPHACOMPARE_COMP1_E 12 +/* bit size */ #define GX_BP_ALPHACOMPARE_COMP1_SZ 3 + +/* raw mask */ #define GX_BP_ALPHACOMPARE_COMP1_MASK (((1 << 3) - 1) << 31 - 12) +/* local mask */ #define GX_BP_ALPHACOMPARE_COMP1_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_BP_ALPHACOMPARE_COMP1_SHIFT 19 + +/* get value */ #define GX_BP_GET_ALPHACOMPARE_COMP1(reg) GX_BITGET((reg), 10, 3) +/* set value */ #define GX_BP_SET_ALPHACOMPARE_COMP1(reg, x) ((reg) = GX_BITSET((reg), 10, 3, x)) + +// LOGIC [8:9] (2) +/* start bit */ #define GX_BP_ALPHACOMPARE_LOGIC_B 8 +/* end bit */ #define GX_BP_ALPHACOMPARE_LOGIC_E 9 +/* bit size */ #define GX_BP_ALPHACOMPARE_LOGIC_SZ 2 + +/* raw mask */ #define GX_BP_ALPHACOMPARE_LOGIC_MASK (((1 << 2) - 1) << 31 - 9) +/* local mask */ #define GX_BP_ALPHACOMPARE_LOGIC_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_ALPHACOMPARE_LOGIC_SHIFT 22 + +/* get value */ #define GX_BP_GET_ALPHACOMPARE_LOGIC(reg) GX_BITGET((reg), 8, 2) +/* set value */ #define GX_BP_SET_ALPHACOMPARE_LOGIC(reg, x) ((reg) = GX_BITSET((reg), 8, 2, x)) + +/****************************************************************************** + * BP structure - TevKSel + *****************************************************************************/ +// SWAP_RB [30:31] (2) - Odd ksel number: red; even: blue +/* start bit */ #define GX_BP_TEVKSEL_SWAP_RB_B 30 +/* end bit */ #define GX_BP_TEVKSEL_SWAP_RB_E 31 +/* bit size */ #define GX_BP_TEVKSEL_SWAP_RB_SZ 2 + +/* raw mask */ #define GX_BP_TEVKSEL_SWAP_RB_MASK (((1 << 2) - 1) << 31 - 31) +/* local mask */ #define GX_BP_TEVKSEL_SWAP_RB_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_TEVKSEL_SWAP_RB_SHIFT 0 + +/* get value */ #define GX_BP_GET_TEVKSEL_SWAP_RB(reg) GX_BITGET((reg), 30, 2) +/* set value */ #define GX_BP_SET_TEVKSEL_SWAP_RB(reg, x) ((reg) = GX_BITSET((reg), 30, 2, x)) + +// SWAP_GA [28:29] (2) - Odd ksel number: green; even: alpha +/* start bit */ #define GX_BP_TEVKSEL_SWAP_GA_B 28 +/* end bit */ #define GX_BP_TEVKSEL_SWAP_GA_E 29 +/* bit size */ #define GX_BP_TEVKSEL_SWAP_GA_SZ 2 + +/* raw mask */ #define GX_BP_TEVKSEL_SWAP_GA_MASK (((1 << 2) - 1) << 31 - 29) +/* local mask */ #define GX_BP_TEVKSEL_SWAP_GA_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_BP_TEVKSEL_SWAP_GA_SHIFT 2 + +/* get value */ #define GX_BP_GET_TEVKSEL_SWAP_GA(reg) GX_BITGET((reg), 28, 2) +/* set value */ #define GX_BP_SET_TEVKSEL_SWAP_GA(reg, x) ((reg) = GX_BITSET((reg), 28, 2, x)) + +// KCSEL_EVEN [23:27] (5) +/* start bit */ #define GX_BP_TEVKSEL_KCSEL_EVEN_B 23 +/* end bit */ #define GX_BP_TEVKSEL_KCSEL_EVEN_E 27 +/* bit size */ #define GX_BP_TEVKSEL_KCSEL_EVEN_SZ 5 + +/* raw mask */ #define GX_BP_TEVKSEL_KCSEL_EVEN_MASK (((1 << 5) - 1) << 31 - 27) +/* local mask */ #define GX_BP_TEVKSEL_KCSEL_EVEN_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_BP_TEVKSEL_KCSEL_EVEN_SHIFT 4 + +/* get value */ #define GX_BP_GET_TEVKSEL_KCSEL_EVEN(reg) GX_BITGET((reg), 23, 5) +/* set value */ #define GX_BP_SET_TEVKSEL_KCSEL_EVEN(reg, x) ((reg) = GX_BITSET((reg), 23, 5, x)) + +// KASEL_EVEN [18:22] (5) +/* start bit */ #define GX_BP_TEVKSEL_KASEL_EVEN_B 18 +/* end bit */ #define GX_BP_TEVKSEL_KASEL_EVEN_E 22 +/* bit size */ #define GX_BP_TEVKSEL_KASEL_EVEN_SZ 5 + +/* raw mask */ #define GX_BP_TEVKSEL_KASEL_EVEN_MASK (((1 << 5) - 1) << 31 - 22) +/* local mask */ #define GX_BP_TEVKSEL_KASEL_EVEN_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_BP_TEVKSEL_KASEL_EVEN_SHIFT 9 + +/* get value */ #define GX_BP_GET_TEVKSEL_KASEL_EVEN(reg) GX_BITGET((reg), 18, 5) +/* set value */ #define GX_BP_SET_TEVKSEL_KASEL_EVEN(reg, x) ((reg) = GX_BITSET((reg), 18, 5, x)) + +// KCSEL_ODD [13:17] (5) +/* start bit */ #define GX_BP_TEVKSEL_KCSEL_ODD_B 13 +/* end bit */ #define GX_BP_TEVKSEL_KCSEL_ODD_E 17 +/* bit size */ #define GX_BP_TEVKSEL_KCSEL_ODD_SZ 5 + +/* raw mask */ #define GX_BP_TEVKSEL_KCSEL_ODD_MASK (((1 << 5) - 1) << 31 - 17) +/* local mask */ #define GX_BP_TEVKSEL_KCSEL_ODD_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_BP_TEVKSEL_KCSEL_ODD_SHIFT 14 + +/* get value */ #define GX_BP_GET_TEVKSEL_KCSEL_ODD(reg) GX_BITGET((reg), 13, 5) +/* set value */ #define GX_BP_SET_TEVKSEL_KCSEL_ODD(reg, x) ((reg) = GX_BITSET((reg), 13, 5, x)) + +// KASEL_ODD [8:12] (5) +/* start bit */ #define GX_BP_TEVKSEL_KASEL_ODD_B 8 +/* end bit */ #define GX_BP_TEVKSEL_KASEL_ODD_E 12 +/* bit size */ #define GX_BP_TEVKSEL_KASEL_ODD_SZ 5 + +/* raw mask */ #define GX_BP_TEVKSEL_KASEL_ODD_MASK (((1 << 5) - 1) << 31 - 12) +/* local mask */ #define GX_BP_TEVKSEL_KASEL_ODD_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_BP_TEVKSEL_KASEL_ODD_SHIFT 19 + +/* get value */ #define GX_BP_GET_TEVKSEL_KASEL_ODD(reg) GX_BITGET((reg), 8, 5) +/* set value */ #define GX_BP_SET_TEVKSEL_KASEL_ODD(reg, x) ((reg) = GX_BITSET((reg), 8, 5, x)) #ifdef __cplusplus } diff --git a/include/rvl/GX/GXHardwareCP.h b/include/rvl/GX/GXHardwareCP.h index 362def52..aa77d6dd 100644 --- a/include/rvl/GX/GXHardwareCP.h +++ b/include/rvl/GX/GXHardwareCP.h @@ -1,7 +1,9 @@ #ifndef RVL_SDK_GX_HARDWARE_CP_H #define RVL_SDK_GX_HARDWARE_CP_H -#include "common.h" -#include "rvl/GX/GXTypes.h" +#include + +#include + #ifdef __cplusplus extern "C" { @@ -30,511 +32,837 @@ typedef enum { GX_CP_REG_ARRAYSTRIDE = 0xB0, } GX_CP_REG; -/** +/****************************************************************************** * CP register 0x30 - MatrixIndexA - */ -// GEOM [26:31] (6) -#define GX_CP_MATRIXINDEXA_GEOM_ST 26 -#define GX_CP_MATRIXINDEXA_GEOM_END 31 -#define GX_CP_MATRIXINDEXA_GEOM_SZ 6 -#define GX_CP_MATRIXINDEXA_GEOM_MASK (((1 << 6) - 1) << 31 - 31) -#define GX_CP_GET_MATRIXINDEXA_GEOM(reg) GX_BITGET(reg, 26, 6) -#define GX_CP_SET_MATRIXINDEXA_GEOM(reg, x) ((reg) = GX_BITSET(reg, 26, 6, x)) -// TEX0 [20:25] (6) -#define GX_CP_MATRIXINDEXA_TEX0_ST 20 -#define GX_CP_MATRIXINDEXA_TEX0_END 25 -#define GX_CP_MATRIXINDEXA_TEX0_SZ 6 -#define GX_CP_MATRIXINDEXA_TEX0_MASK (((1 << 6) - 1) << 31 - 25) -#define GX_CP_GET_MATRIXINDEXA_TEX0(reg) GX_BITGET(reg, 20, 6) -#define GX_CP_SET_MATRIXINDEXA_TEX0(reg, x) ((reg) = GX_BITSET(reg, 20, 6, x)) -// TEX1 [14:19] (6) -#define GX_CP_MATRIXINDEXA_TEX1_ST 14 -#define GX_CP_MATRIXINDEXA_TEX1_END 19 -#define GX_CP_MATRIXINDEXA_TEX1_SZ 6 -#define GX_CP_MATRIXINDEXA_TEX1_MASK (((1 << 6) - 1) << 31 - 19) -#define GX_CP_GET_MATRIXINDEXA_TEX1(reg) GX_BITGET(reg, 14, 6) -#define GX_CP_SET_MATRIXINDEXA_TEX1(reg, x) ((reg) = GX_BITSET(reg, 14, 6, x)) -// TEX2 [8:13] (6) -#define GX_CP_MATRIXINDEXA_TEX2_ST 8 -#define GX_CP_MATRIXINDEXA_TEX2_END 13 -#define GX_CP_MATRIXINDEXA_TEX2_SZ 6 -#define GX_CP_MATRIXINDEXA_TEX2_MASK (((1 << 6) - 1) << 31 - 13) -#define GX_CP_GET_MATRIXINDEXA_TEX2(reg) GX_BITGET(reg, 8, 6) -#define GX_CP_SET_MATRIXINDEXA_TEX2(reg, x) ((reg) = GX_BITSET(reg, 8, 6, x)) + *****************************************************************************/ // TEX3 [2:7] (6) -#define GX_CP_MATRIXINDEXA_TEX3_ST 2 -#define GX_CP_MATRIXINDEXA_TEX3_END 7 -#define GX_CP_MATRIXINDEXA_TEX3_SZ 6 -#define GX_CP_MATRIXINDEXA_TEX3_MASK (((1 << 6) - 1) << 31 - 7) -#define GX_CP_GET_MATRIXINDEXA_TEX3(reg) GX_BITGET(reg, 2, 6) -#define GX_CP_SET_MATRIXINDEXA_TEX3(reg, x) ((reg) = GX_BITSET(reg, 2, 6, x)) +/* start bit */ #define GX_CP_MATRIXINDEXA_TEX3_B 2 +/* end bit */ #define GX_CP_MATRIXINDEXA_TEX3_E 7 +/* bit size */ #define GX_CP_MATRIXINDEXA_TEX3_SZ 6 -/** +/* raw mask */ #define GX_CP_MATRIXINDEXA_TEX3_MASK (((1 << 6) - 1) << 31 - 7) +/* local mask */ #define GX_CP_MATRIXINDEXA_TEX3_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_CP_MATRIXINDEXA_TEX3_SHIFT 24 + +/* get value */ #define GX_CP_GET_MATRIXINDEXA_TEX3(reg) GX_BITGET((reg), 2, 6) +/* set value */ #define GX_CP_SET_MATRIXINDEXA_TEX3(reg, x) ((reg) = GX_BITSET((reg), 2, 6, x)) + +// TEX2 [8:13] (6) +/* start bit */ #define GX_CP_MATRIXINDEXA_TEX2_B 8 +/* end bit */ #define GX_CP_MATRIXINDEXA_TEX2_E 13 +/* bit size */ #define GX_CP_MATRIXINDEXA_TEX2_SZ 6 + +/* raw mask */ #define GX_CP_MATRIXINDEXA_TEX2_MASK (((1 << 6) - 1) << 31 - 13) +/* local mask */ #define GX_CP_MATRIXINDEXA_TEX2_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_CP_MATRIXINDEXA_TEX2_SHIFT 18 + +/* get value */ #define GX_CP_GET_MATRIXINDEXA_TEX2(reg) GX_BITGET((reg), 8, 6) +/* set value */ #define GX_CP_SET_MATRIXINDEXA_TEX2(reg, x) ((reg) = GX_BITSET((reg), 8, 6, x)) + +// TEX1 [14:19] (6) +/* start bit */ #define GX_CP_MATRIXINDEXA_TEX1_B 14 +/* end bit */ #define GX_CP_MATRIXINDEXA_TEX1_E 19 +/* bit size */ #define GX_CP_MATRIXINDEXA_TEX1_SZ 6 + +/* raw mask */ #define GX_CP_MATRIXINDEXA_TEX1_MASK (((1 << 6) - 1) << 31 - 19) +/* local mask */ #define GX_CP_MATRIXINDEXA_TEX1_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_CP_MATRIXINDEXA_TEX1_SHIFT 12 + +/* get value */ #define GX_CP_GET_MATRIXINDEXA_TEX1(reg) GX_BITGET((reg), 14, 6) +/* set value */ #define GX_CP_SET_MATRIXINDEXA_TEX1(reg, x) ((reg) = GX_BITSET((reg), 14, 6, x)) + +// TEX0 [20:25] (6) +/* start bit */ #define GX_CP_MATRIXINDEXA_TEX0_B 20 +/* end bit */ #define GX_CP_MATRIXINDEXA_TEX0_E 25 +/* bit size */ #define GX_CP_MATRIXINDEXA_TEX0_SZ 6 + +/* raw mask */ #define GX_CP_MATRIXINDEXA_TEX0_MASK (((1 << 6) - 1) << 31 - 25) +/* local mask */ #define GX_CP_MATRIXINDEXA_TEX0_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_CP_MATRIXINDEXA_TEX0_SHIFT 6 + +/* get value */ #define GX_CP_GET_MATRIXINDEXA_TEX0(reg) GX_BITGET((reg), 20, 6) +/* set value */ #define GX_CP_SET_MATRIXINDEXA_TEX0(reg, x) ((reg) = GX_BITSET((reg), 20, 6, x)) + +// POSNRM [26:31] (6) +/* start bit */ #define GX_CP_MATRIXINDEXA_POSNRM_B 26 +/* end bit */ #define GX_CP_MATRIXINDEXA_POSNRM_E 31 +/* bit size */ #define GX_CP_MATRIXINDEXA_POSNRM_SZ 6 + +/* raw mask */ #define GX_CP_MATRIXINDEXA_POSNRM_MASK (((1 << 6) - 1) << 31 - 31) +/* local mask */ #define GX_CP_MATRIXINDEXA_POSNRM_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_CP_MATRIXINDEXA_POSNRM_SHIFT 0 + +/* get value */ #define GX_CP_GET_MATRIXINDEXA_POSNRM(reg) GX_BITGET((reg), 26, 6) +/* set value */ #define GX_CP_SET_MATRIXINDEXA_POSNRM(reg, x) ((reg) = GX_BITSET((reg), 26, 6, x)) + +/****************************************************************************** * CP register 0x40 - MatrixIndexB - */ -// TEX4 [26:31] (6) -#define GX_CP_MATRIXINDEXB_TEX4_ST 26 -#define GX_CP_MATRIXINDEXB_TEX4_END 31 -#define GX_CP_MATRIXINDEXB_TEX4_SZ 6 -#define GX_CP_MATRIXINDEXB_TEX4_MASK (((1 << 6) - 1) << 31 - 31) -#define GX_CP_GET_MATRIXINDEXB_TEX4(reg) GX_BITGET(reg, 26, 6) -#define GX_CP_SET_MATRIXINDEXB_TEX4(reg, x) ((reg) = GX_BITSET(reg, 26, 6, x)) -// TEX5 [20:25] (6) -#define GX_CP_MATRIXINDEXB_TEX5_ST 20 -#define GX_CP_MATRIXINDEXB_TEX5_END 25 -#define GX_CP_MATRIXINDEXB_TEX5_SZ 6 -#define GX_CP_MATRIXINDEXB_TEX5_MASK (((1 << 6) - 1) << 31 - 25) -#define GX_CP_GET_MATRIXINDEXB_TEX5(reg) GX_BITGET(reg, 20, 6) -#define GX_CP_SET_MATRIXINDEXB_TEX5(reg, x) ((reg) = GX_BITSET(reg, 20, 6, x)) -// TEX6 [14:19] (6) -#define GX_CP_MATRIXINDEXB_TEX6_ST 14 -#define GX_CP_MATRIXINDEXB_TEX6_END 19 -#define GX_CP_MATRIXINDEXB_TEX6_SZ 6 -#define GX_CP_MATRIXINDEXB_TEX6_MASK (((1 << 6) - 1) << 31 - 19) -#define GX_CP_GET_MATRIXINDEXB_TEX6(reg) GX_BITGET(reg, 14, 6) -#define GX_CP_SET_MATRIXINDEXB_TEX6(reg, x) ((reg) = GX_BITSET(reg, 14, 6, x)) + *****************************************************************************/ // TEX7 [8:13] (6) -#define GX_CP_MATRIXINDEXB_TEX7_ST 8 -#define GX_CP_MATRIXINDEXB_TEX7_END 13 -#define GX_CP_MATRIXINDEXB_TEX7_SZ 6 -#define GX_CP_MATRIXINDEXB_TEX7_MASK (((1 << 6) - 1) << 31 - 13) -#define GX_CP_GET_MATRIXINDEXB_TEX7(reg) GX_BITGET(reg, 8, 6) -#define GX_CP_SET_MATRIXINDEXB_TEX7(reg, x) ((reg) = GX_BITSET(reg, 8, 6, x)) +/* start bit */ #define GX_CP_MATRIXINDEXB_TEX7_B 8 +/* end bit */ #define GX_CP_MATRIXINDEXB_TEX7_E 13 +/* bit size */ #define GX_CP_MATRIXINDEXB_TEX7_SZ 6 -/** +/* raw mask */ #define GX_CP_MATRIXINDEXB_TEX7_MASK (((1 << 6) - 1) << 31 - 13) +/* local mask */ #define GX_CP_MATRIXINDEXB_TEX7_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_CP_MATRIXINDEXB_TEX7_SHIFT 18 + +/* get value */ #define GX_CP_GET_MATRIXINDEXB_TEX7(reg) GX_BITGET((reg), 8, 6) +/* set value */ #define GX_CP_SET_MATRIXINDEXB_TEX7(reg, x) ((reg) = GX_BITSET((reg), 8, 6, x)) + +// TEX6 [14:19] (6) +/* start bit */ #define GX_CP_MATRIXINDEXB_TEX6_B 14 +/* end bit */ #define GX_CP_MATRIXINDEXB_TEX6_E 19 +/* bit size */ #define GX_CP_MATRIXINDEXB_TEX6_SZ 6 + +/* raw mask */ #define GX_CP_MATRIXINDEXB_TEX6_MASK (((1 << 6) - 1) << 31 - 19) +/* local mask */ #define GX_CP_MATRIXINDEXB_TEX6_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_CP_MATRIXINDEXB_TEX6_SHIFT 12 + +/* get value */ #define GX_CP_GET_MATRIXINDEXB_TEX6(reg) GX_BITGET((reg), 14, 6) +/* set value */ #define GX_CP_SET_MATRIXINDEXB_TEX6(reg, x) ((reg) = GX_BITSET((reg), 14, 6, x)) + +// TEX5 [20:25] (6) +/* start bit */ #define GX_CP_MATRIXINDEXB_TEX5_B 20 +/* end bit */ #define GX_CP_MATRIXINDEXB_TEX5_E 25 +/* bit size */ #define GX_CP_MATRIXINDEXB_TEX5_SZ 6 + +/* raw mask */ #define GX_CP_MATRIXINDEXB_TEX5_MASK (((1 << 6) - 1) << 31 - 25) +/* local mask */ #define GX_CP_MATRIXINDEXB_TEX5_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_CP_MATRIXINDEXB_TEX5_SHIFT 6 + +/* get value */ #define GX_CP_GET_MATRIXINDEXB_TEX5(reg) GX_BITGET((reg), 20, 6) +/* set value */ #define GX_CP_SET_MATRIXINDEXB_TEX5(reg, x) ((reg) = GX_BITSET((reg), 20, 6, x)) + +// TEX4 [26:31] (6) +/* start bit */ #define GX_CP_MATRIXINDEXB_TEX4_B 26 +/* end bit */ #define GX_CP_MATRIXINDEXB_TEX4_E 31 +/* bit size */ #define GX_CP_MATRIXINDEXB_TEX4_SZ 6 + +/* raw mask */ #define GX_CP_MATRIXINDEXB_TEX4_MASK (((1 << 6) - 1) << 31 - 31) +/* local mask */ #define GX_CP_MATRIXINDEXB_TEX4_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_CP_MATRIXINDEXB_TEX4_SHIFT 0 + +/* get value */ #define GX_CP_GET_MATRIXINDEXB_TEX4(reg) GX_BITGET((reg), 26, 6) +/* set value */ #define GX_CP_SET_MATRIXINDEXB_TEX4(reg, x) ((reg) = GX_BITSET((reg), 26, 6, x)) + +/****************************************************************************** * CP register 0x50 - VCD_Lo - */ + *****************************************************************************/ // POSMATIDX [31:31] (1) -#define GX_CP_VCD_LO_POSMATIDX_ST 31 -#define GX_CP_VCD_LO_POSMATIDX_END 31 -#define GX_CP_VCD_LO_POSMATIDX_SZ 1 -#define GX_CP_VCD_LO_POSMATIDX_MASK (((1 << 1) - 1) << 31 - 31) -#define GX_CP_GET_VCD_LO_POSMATIDX(reg) GX_BITGET(reg, 31, 1) -#define GX_CP_SET_VCD_LO_POSMATIDX(reg, x) ((reg) = GX_BITSET(reg, 31, 1, x)) +/* start bit */ #define GX_CP_VCD_LO_POSMATIDX_B 31 +/* end bit */ #define GX_CP_VCD_LO_POSMATIDX_E 31 +/* bit size */ #define GX_CP_VCD_LO_POSMATIDX_SZ 1 + +/* raw mask */ #define GX_CP_VCD_LO_POSMATIDX_MASK (((1 << 1) - 1) << 31 - 31) +/* local mask */ #define GX_CP_VCD_LO_POSMATIDX_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VCD_LO_POSMATIDX_SHIFT 0 + +/* get value */ #define GX_CP_GET_VCD_LO_POSMATIDX(reg) GX_BITGET((reg), 31, 1) +/* set value */ #define GX_CP_SET_VCD_LO_POSMATIDX(reg, x) ((reg) = GX_BITSET((reg), 31, 1, x)) + // TEX0MATIDX [30:30] (1) -#define GX_CP_VCD_LO_TEX0MATIDX_ST 30 -#define GX_CP_VCD_LO_TEX0MATIDX_END 30 -#define GX_CP_VCD_LO_TEX0MATIDX_SZ 1 -#define GX_CP_VCD_LO_TEX0MATIDX_MASK (((1 << 1) - 1) << 31 - 30) -#define GX_CP_GET_VCD_LO_TEX0MATIDX(reg) GX_BITGET(reg, 30, 1) -#define GX_CP_SET_VCD_LO_TEX0MATIDX(reg, x) ((reg) = GX_BITSET(reg, 30, 1, x)) +/* start bit */ #define GX_CP_VCD_LO_TEX0MATIDX_B 30 +/* end bit */ #define GX_CP_VCD_LO_TEX0MATIDX_E 30 +/* bit size */ #define GX_CP_VCD_LO_TEX0MATIDX_SZ 1 + +/* raw mask */ #define GX_CP_VCD_LO_TEX0MATIDX_MASK (((1 << 1) - 1) << 31 - 30) +/* local mask */ #define GX_CP_VCD_LO_TEX0MATIDX_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VCD_LO_TEX0MATIDX_SHIFT 1 + +/* get value */ #define GX_CP_GET_VCD_LO_TEX0MATIDX(reg) GX_BITGET((reg), 30, 1) +/* set value */ #define GX_CP_SET_VCD_LO_TEX0MATIDX(reg, x) ((reg) = GX_BITSET((reg), 30, 1, x)) + // TEX1MATIDX [29:29] (1) -#define GX_CP_VCD_LO_TEX1MATIDX_ST 29 -#define GX_CP_VCD_LO_TEX1MATIDX_END 29 -#define GX_CP_VCD_LO_TEX1MATIDX_SZ 1 -#define GX_CP_VCD_LO_TEX1MATIDX_MASK (((1 << 1) - 1) << 31 - 29) -#define GX_CP_GET_VCD_LO_TEX1MATIDX(reg) GX_BITGET(reg, 29, 1) -#define GX_CP_SET_VCD_LO_TEX1MATIDX(reg, x) ((reg) = GX_BITSET(reg, 29, 1, x)) +/* start bit */ #define GX_CP_VCD_LO_TEX1MATIDX_B 29 +/* end bit */ #define GX_CP_VCD_LO_TEX1MATIDX_E 29 +/* bit size */ #define GX_CP_VCD_LO_TEX1MATIDX_SZ 1 + +/* raw mask */ #define GX_CP_VCD_LO_TEX1MATIDX_MASK (((1 << 1) - 1) << 31 - 29) +/* local mask */ #define GX_CP_VCD_LO_TEX1MATIDX_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VCD_LO_TEX1MATIDX_SHIFT 2 + +/* get value */ #define GX_CP_GET_VCD_LO_TEX1MATIDX(reg) GX_BITGET((reg), 29, 1) +/* set value */ #define GX_CP_SET_VCD_LO_TEX1MATIDX(reg, x) ((reg) = GX_BITSET((reg), 29, 1, x)) + // TEX2MATIDX [28:28] (1) -#define GX_CP_VCD_LO_TEX2MATIDX_ST 28 -#define GX_CP_VCD_LO_TEX2MATIDX_END 28 -#define GX_CP_VCD_LO_TEX2MATIDX_SZ 1 -#define GX_CP_VCD_LO_TEX2MATIDX_MASK (((1 << 1) - 1) << 31 - 28) -#define GX_CP_GET_VCD_LO_TEX2MATIDX(reg) GX_BITGET(reg, 28, 1) -#define GX_CP_SET_VCD_LO_TEX2MATIDX(reg, x) ((reg) = GX_BITSET(reg, 28, 1, x)) +/* start bit */ #define GX_CP_VCD_LO_TEX2MATIDX_B 28 +/* end bit */ #define GX_CP_VCD_LO_TEX2MATIDX_E 28 +/* bit size */ #define GX_CP_VCD_LO_TEX2MATIDX_SZ 1 + +/* raw mask */ #define GX_CP_VCD_LO_TEX2MATIDX_MASK (((1 << 1) - 1) << 31 - 28) +/* local mask */ #define GX_CP_VCD_LO_TEX2MATIDX_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VCD_LO_TEX2MATIDX_SHIFT 3 + +/* get value */ #define GX_CP_GET_VCD_LO_TEX2MATIDX(reg) GX_BITGET((reg), 28, 1) +/* set value */ #define GX_CP_SET_VCD_LO_TEX2MATIDX(reg, x) ((reg) = GX_BITSET((reg), 28, 1, x)) + // TEX3MATIDX [27:27] (1) -#define GX_CP_VCD_LO_TEX3MATIDX_ST 27 -#define GX_CP_VCD_LO_TEX3MATIDX_END 27 -#define GX_CP_VCD_LO_TEX3MATIDX_SZ 1 -#define GX_CP_VCD_LO_TEX3MATIDX_MASK (((1 << 1) - 1) << 31 - 27) -#define GX_CP_GET_VCD_LO_TEX3MATIDX(reg) GX_BITGET(reg, 27, 1) -#define GX_CP_SET_VCD_LO_TEX3MATIDX(reg, x) ((reg) = GX_BITSET(reg, 27, 1, x)) +/* start bit */ #define GX_CP_VCD_LO_TEX3MATIDX_B 27 +/* end bit */ #define GX_CP_VCD_LO_TEX3MATIDX_E 27 +/* bit size */ #define GX_CP_VCD_LO_TEX3MATIDX_SZ 1 + +/* raw mask */ #define GX_CP_VCD_LO_TEX3MATIDX_MASK (((1 << 1) - 1) << 31 - 27) +/* local mask */ #define GX_CP_VCD_LO_TEX3MATIDX_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VCD_LO_TEX3MATIDX_SHIFT 4 + +/* get value */ #define GX_CP_GET_VCD_LO_TEX3MATIDX(reg) GX_BITGET((reg), 27, 1) +/* set value */ #define GX_CP_SET_VCD_LO_TEX3MATIDX(reg, x) ((reg) = GX_BITSET((reg), 27, 1, x)) + // TEX4MATIDX [26:26] (1) -#define GX_CP_VCD_LO_TEX4MATIDX_ST 26 -#define GX_CP_VCD_LO_TEX4MATIDX_END 26 -#define GX_CP_VCD_LO_TEX4MATIDX_SZ 1 -#define GX_CP_VCD_LO_TEX4MATIDX_MASK (((1 << 1) - 1) << 31 - 26) -#define GX_CP_GET_VCD_LO_TEX4MATIDX(reg) GX_BITGET(reg, 26, 1) -#define GX_CP_SET_VCD_LO_TEX4MATIDX(reg, x) ((reg) = GX_BITSET(reg, 26, 1, x)) +/* start bit */ #define GX_CP_VCD_LO_TEX4MATIDX_B 26 +/* end bit */ #define GX_CP_VCD_LO_TEX4MATIDX_E 26 +/* bit size */ #define GX_CP_VCD_LO_TEX4MATIDX_SZ 1 + +/* raw mask */ #define GX_CP_VCD_LO_TEX4MATIDX_MASK (((1 << 1) - 1) << 31 - 26) +/* local mask */ #define GX_CP_VCD_LO_TEX4MATIDX_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VCD_LO_TEX4MATIDX_SHIFT 5 + +/* get value */ #define GX_CP_GET_VCD_LO_TEX4MATIDX(reg) GX_BITGET((reg), 26, 1) +/* set value */ #define GX_CP_SET_VCD_LO_TEX4MATIDX(reg, x) ((reg) = GX_BITSET((reg), 26, 1, x)) + // TEX5MATIDX [25:25] (1) -#define GX_CP_VCD_LO_TEX5MATIDX_ST 25 -#define GX_CP_VCD_LO_TEX5MATIDX_END 25 -#define GX_CP_VCD_LO_TEX5MATIDX_SZ 1 -#define GX_CP_VCD_LO_TEX5MATIDX_MASK (((1 << 1) - 1) << 31 - 25) -#define GX_CP_GET_VCD_LO_TEX5MATIDX(reg) GX_BITGET(reg, 25, 1) -#define GX_CP_SET_VCD_LO_TEX5MATIDX(reg, x) ((reg) = GX_BITSET(reg, 25, 1, x)) +/* start bit */ #define GX_CP_VCD_LO_TEX5MATIDX_B 25 +/* end bit */ #define GX_CP_VCD_LO_TEX5MATIDX_E 25 +/* bit size */ #define GX_CP_VCD_LO_TEX5MATIDX_SZ 1 + +/* raw mask */ #define GX_CP_VCD_LO_TEX5MATIDX_MASK (((1 << 1) - 1) << 31 - 25) +/* local mask */ #define GX_CP_VCD_LO_TEX5MATIDX_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VCD_LO_TEX5MATIDX_SHIFT 6 + +/* get value */ #define GX_CP_GET_VCD_LO_TEX5MATIDX(reg) GX_BITGET((reg), 25, 1) +/* set value */ #define GX_CP_SET_VCD_LO_TEX5MATIDX(reg, x) ((reg) = GX_BITSET((reg), 25, 1, x)) + // TEX6MATIDX [24:24] (1) -#define GX_CP_VCD_LO_TEX6MATIDX_ST 24 -#define GX_CP_VCD_LO_TEX6MATIDX_END 24 -#define GX_CP_VCD_LO_TEX6MATIDX_SZ 1 -#define GX_CP_VCD_LO_TEX6MATIDX_MASK (((1 << 1) - 1) << 31 - 24) -#define GX_CP_GET_VCD_LO_TEX6MATIDX(reg) GX_BITGET(reg, 24, 1) -#define GX_CP_SET_VCD_LO_TEX6MATIDX(reg, x) ((reg) = GX_BITSET(reg, 24, 1, x)) +/* start bit */ #define GX_CP_VCD_LO_TEX6MATIDX_B 24 +/* end bit */ #define GX_CP_VCD_LO_TEX6MATIDX_E 24 +/* bit size */ #define GX_CP_VCD_LO_TEX6MATIDX_SZ 1 + +/* raw mask */ #define GX_CP_VCD_LO_TEX6MATIDX_MASK (((1 << 1) - 1) << 31 - 24) +/* local mask */ #define GX_CP_VCD_LO_TEX6MATIDX_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VCD_LO_TEX6MATIDX_SHIFT 7 + +/* get value */ #define GX_CP_GET_VCD_LO_TEX6MATIDX(reg) GX_BITGET((reg), 24, 1) +/* set value */ #define GX_CP_SET_VCD_LO_TEX6MATIDX(reg, x) ((reg) = GX_BITSET((reg), 24, 1, x)) + // TEX7MATIDX [23:23] (1) -#define GX_CP_VCD_LO_TEX7MATIDX_ST 23 -#define GX_CP_VCD_LO_TEX7MATIDX_END 23 -#define GX_CP_VCD_LO_TEX7MATIDX_SZ 1 -#define GX_CP_VCD_LO_TEX7MATIDX_MASK (((1 << 1) - 1) << 31 - 23) -#define GX_CP_GET_VCD_LO_TEX7MATIDX(reg) GX_BITGET(reg, 23, 1) -#define GX_CP_SET_VCD_LO_TEX7MATIDX(reg, x) ((reg) = GX_BITSET(reg, 23, 1, x)) +/* start bit */ #define GX_CP_VCD_LO_TEX7MATIDX_B 23 +/* end bit */ #define GX_CP_VCD_LO_TEX7MATIDX_E 23 +/* bit size */ #define GX_CP_VCD_LO_TEX7MATIDX_SZ 1 + +/* raw mask */ #define GX_CP_VCD_LO_TEX7MATIDX_MASK (((1 << 1) - 1) << 31 - 23) +/* local mask */ #define GX_CP_VCD_LO_TEX7MATIDX_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VCD_LO_TEX7MATIDX_SHIFT 8 + +/* get value */ #define GX_CP_GET_VCD_LO_TEX7MATIDX(reg) GX_BITGET((reg), 23, 1) +/* set value */ #define GX_CP_SET_VCD_LO_TEX7MATIDX(reg, x) ((reg) = GX_BITSET((reg), 23, 1, x)) + // POSITION [21:22] (2) -#define GX_CP_VCD_LO_POSITION_ST 21 -#define GX_CP_VCD_LO_POSITION_END 22 -#define GX_CP_VCD_LO_POSITION_SZ 2 -#define GX_CP_VCD_LO_POSITION_MASK (((1 << 2) - 1) << 31 - 22) -#define GX_CP_GET_VCD_LO_POSITION(reg) GX_BITGET(reg, 21, 2) -#define GX_CP_SET_VCD_LO_POSITION(reg, x) ((reg) = GX_BITSET(reg, 21, 2, x)) +/* start bit */ #define GX_CP_VCD_LO_POSITION_B 21 +/* end bit */ #define GX_CP_VCD_LO_POSITION_E 22 +/* bit size */ #define GX_CP_VCD_LO_POSITION_SZ 2 + +/* raw mask */ #define GX_CP_VCD_LO_POSITION_MASK (((1 << 2) - 1) << 31 - 22) +/* local mask */ #define GX_CP_VCD_LO_POSITION_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_CP_VCD_LO_POSITION_SHIFT 9 + +/* get value */ #define GX_CP_GET_VCD_LO_POSITION(reg) GX_BITGET((reg), 21, 2) +/* set value */ #define GX_CP_SET_VCD_LO_POSITION(reg, x) ((reg) = GX_BITSET((reg), 21, 2, x)) + // NORMAL [19:20] (2) -#define GX_CP_VCD_LO_NORMAL_ST 19 -#define GX_CP_VCD_LO_NORMAL_END 20 -#define GX_CP_VCD_LO_NORMAL_SZ 2 -#define GX_CP_VCD_LO_NORMAL_MASK (((1 << 2) - 1) << 31 - 20) -#define GX_CP_GET_VCD_LO_NORMAL(reg) GX_BITGET(reg, 19, 2) -#define GX_CP_SET_VCD_LO_NORMAL(reg, x) ((reg) = GX_BITSET(reg, 19, 2, x)) +/* start bit */ #define GX_CP_VCD_LO_NORMAL_B 19 +/* end bit */ #define GX_CP_VCD_LO_NORMAL_E 20 +/* bit size */ #define GX_CP_VCD_LO_NORMAL_SZ 2 + +/* raw mask */ #define GX_CP_VCD_LO_NORMAL_MASK (((1 << 2) - 1) << 31 - 20) +/* local mask */ #define GX_CP_VCD_LO_NORMAL_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_CP_VCD_LO_NORMAL_SHIFT 11 + +/* get value */ #define GX_CP_GET_VCD_LO_NORMAL(reg) GX_BITGET((reg), 19, 2) +/* set value */ #define GX_CP_SET_VCD_LO_NORMAL(reg, x) ((reg) = GX_BITSET((reg), 19, 2, x)) + // COLORDIFFUSED [17:18] (2) -#define GX_CP_VCD_LO_COLORDIFFUSED_ST 17 -#define GX_CP_VCD_LO_COLORDIFFUSED_END 18 -#define GX_CP_VCD_LO_COLORDIFFUSED_SZ 2 -#define GX_CP_VCD_LO_COLORDIFFUSED_MASK (((1 << 2) - 1) << 31 - 18) -#define GX_CP_GET_VCD_LO_COLORDIFFUSED(reg) GX_BITGET(reg, 17, 2) -#define GX_CP_SET_VCD_LO_COLORDIFFUSED(reg, x) ((reg) = GX_BITSET(reg, 17, 2, x)) +/* start bit */ #define GX_CP_VCD_LO_COLORDIFFUSED_B 17 +/* end bit */ #define GX_CP_VCD_LO_COLORDIFFUSED_E 18 +/* bit size */ #define GX_CP_VCD_LO_COLORDIFFUSED_SZ 2 + +/* raw mask */ #define GX_CP_VCD_LO_COLORDIFFUSED_MASK (((1 << 2) - 1) << 31 - 18) +/* local mask */ #define GX_CP_VCD_LO_COLORDIFFUSED_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_CP_VCD_LO_COLORDIFFUSED_SHIFT 13 + +/* get value */ #define GX_CP_GET_VCD_LO_COLORDIFFUSED(reg) GX_BITGET((reg), 17, 2) +/* set value */ #define GX_CP_SET_VCD_LO_COLORDIFFUSED(reg, x) ((reg) = GX_BITSET((reg), 17, 2, x)) + // COLORSPECULAR [15:16] (2) -#define GX_CP_VCD_LO_COLORSPECULAR_ST 15 -#define GX_CP_VCD_LO_COLORSPECULAR_END 16 -#define GX_CP_VCD_LO_COLORSPECULAR_SZ 2 -#define GX_CP_VCD_LO_COLORSPECULAR_MASK (((1 << 2) - 1) << 31 - 16) -#define GX_CP_GET_VCD_LO_COLORSPECULAR(reg) GX_BITGET(reg, 15, 2) -#define GX_CP_SET_VCD_LO_COLORSPECULAR(reg, x) ((reg) = GX_BITSET(reg, 15, 2, x)) +/* start bit */ #define GX_CP_VCD_LO_COLORSPECULAR_B 15 +/* end bit */ #define GX_CP_VCD_LO_COLORSPECULAR_E 16 +/* bit size */ #define GX_CP_VCD_LO_COLORSPECULAR_SZ 2 -/** +/* raw mask */ #define GX_CP_VCD_LO_COLORSPECULAR_MASK (((1 << 2) - 1) << 31 - 16) +/* local mask */ #define GX_CP_VCD_LO_COLORSPECULAR_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_CP_VCD_LO_COLORSPECULAR_SHIFT 15 + +/* get value */ #define GX_CP_GET_VCD_LO_COLORSPECULAR(reg) GX_BITGET((reg), 15, 2) +/* set value */ #define GX_CP_SET_VCD_LO_COLORSPECULAR(reg, x) ((reg) = GX_BITSET((reg), 15, 2, x)) + +/****************************************************************************** * CP register 0x60 - VCD_Hi - */ + *****************************************************************************/ // TEX0COORD [30:31] (2) -#define GX_CP_VCD_HI_TEX0COORD_ST 30 -#define GX_CP_VCD_HI_TEX0COORD_END 31 -#define GX_CP_VCD_HI_TEX0COORD_SZ 2 -#define GX_CP_VCD_HI_TEX0COORD_MASK (((1 << 2) - 1) << 31 - 31) -#define GX_CP_GET_VCD_HI_TEX0COORD(reg) GX_BITGET(reg, 30, 2) -#define GX_CP_SET_VCD_HI_TEX0COORD(reg, x) ((reg) = GX_BITSET(reg, 30, 2, x)) -// TEX1COORD [28:29] (2) -#define GX_CP_VCD_HI_TEX1COORD_ST 28 -#define GX_CP_VCD_HI_TEX1COORD_END 29 -#define GX_CP_VCD_HI_TEX1COORD_SZ 2 -#define GX_CP_VCD_HI_TEX1COORD_MASK (((1 << 2) - 1) << 31 - 29) -#define GX_CP_GET_VCD_HI_TEX1COORD(reg) GX_BITGET(reg, 28, 2) -#define GX_CP_SET_VCD_HI_TEX1COORD(reg, x) ((reg) = GX_BITSET(reg, 28, 2, x)) -// TEX2COORD [26:27] (2) -#define GX_CP_VCD_HI_TEX2COORD_ST 26 -#define GX_CP_VCD_HI_TEX2COORD_END 27 -#define GX_CP_VCD_HI_TEX2COORD_SZ 2 -#define GX_CP_VCD_HI_TEX2COORD_MASK (((1 << 2) - 1) << 31 - 27) -#define GX_CP_GET_VCD_HI_TEX2COORD(reg) GX_BITGET(reg, 26, 2) -#define GX_CP_SET_VCD_HI_TEX2COORD(reg, x) ((reg) = GX_BITSET(reg, 26, 2, x)) -// TEX3COORD [24:25] (2) -#define GX_CP_VCD_HI_TEX3COORD_ST 24 -#define GX_CP_VCD_HI_TEX3COORD_END 25 -#define GX_CP_VCD_HI_TEX3COORD_SZ 2 -#define GX_CP_VCD_HI_TEX3COORD_MASK (((1 << 2) - 1) << 31 - 25) -#define GX_CP_GET_VCD_HI_TEX3COORD(reg) GX_BITGET(reg, 24, 2) -#define GX_CP_SET_VCD_HI_TEX3COORD(reg, x) ((reg) = GX_BITSET(reg, 24, 2, x)) -// TEX4COORD [22:23] (2) -#define GX_CP_VCD_HI_TEX4COORD_ST 22 -#define GX_CP_VCD_HI_TEX4COORD_END 23 -#define GX_CP_VCD_HI_TEX4COORD_SZ 2 -#define GX_CP_VCD_HI_TEX4COORD_MASK (((1 << 2) - 1) << 31 - 23) -#define GX_CP_GET_VCD_HI_TEX4COORD(reg) GX_BITGET(reg, 22, 2) -#define GX_CP_SET_VCD_HI_TEX4COORD(reg, x) ((reg) = GX_BITSET(reg, 22, 2, x)) -// TEX5COORD [20:21] (2) -#define GX_CP_VCD_HI_TEX5COORD_ST 20 -#define GX_CP_VCD_HI_TEX5COORD_END 21 -#define GX_CP_VCD_HI_TEX5COORD_SZ 2 -#define GX_CP_VCD_HI_TEX5COORD_MASK (((1 << 2) - 1) << 31 - 21) -#define GX_CP_GET_VCD_HI_TEX5COORD(reg) GX_BITGET(reg, 20, 2) -#define GX_CP_SET_VCD_HI_TEX5COORD(reg, x) ((reg) = GX_BITSET(reg, 20, 2, x)) -// TEX6COORD [18:19] (2) -#define GX_CP_VCD_HI_TEX6COORD_ST 18 -#define GX_CP_VCD_HI_TEX6COORD_END 19 -#define GX_CP_VCD_HI_TEX6COORD_SZ 2 -#define GX_CP_VCD_HI_TEX6COORD_MASK (((1 << 2) - 1) << 31 - 19) -#define GX_CP_GET_VCD_HI_TEX6COORD(reg) GX_BITGET(reg, 18, 2) -#define GX_CP_SET_VCD_HI_TEX6COORD(reg, x) ((reg) = GX_BITSET(reg, 18, 2, x)) -// TEX7COORD [16:17] (2) -#define GX_CP_VCD_HI_TEX7COORD_ST 16 -#define GX_CP_VCD_HI_TEX7COORD_END 17 -#define GX_CP_VCD_HI_TEX7COORD_SZ 2 -#define GX_CP_VCD_HI_TEX7COORD_MASK (((1 << 2) - 1) << 31 - 17) -#define GX_CP_GET_VCD_HI_TEX7COORD(reg) GX_BITGET(reg, 16, 2) -#define GX_CP_SET_VCD_HI_TEX7COORD(reg, x) ((reg) = GX_BITSET(reg, 16, 2, x)) +/* start bit */ #define GX_CP_VCD_HI_TEX0COORD_B 30 +/* end bit */ #define GX_CP_VCD_HI_TEX0COORD_E 31 +/* bit size */ #define GX_CP_VCD_HI_TEX0COORD_SZ 2 -/** +/* raw mask */ #define GX_CP_VCD_HI_TEX0COORD_MASK (((1 << 2) - 1) << 31 - 31) +/* local mask */ #define GX_CP_VCD_HI_TEX0COORD_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_CP_VCD_HI_TEX0COORD_SHIFT 0 + +/* get value */ #define GX_CP_GET_VCD_HI_TEX0COORD(reg) GX_BITGET((reg), 30, 2) +/* set value */ #define GX_CP_SET_VCD_HI_TEX0COORD(reg, x) ((reg) = GX_BITSET((reg), 30, 2, x)) + +// TEX1COORD [28:29] (2) +/* start bit */ #define GX_CP_VCD_HI_TEX1COORD_B 28 +/* end bit */ #define GX_CP_VCD_HI_TEX1COORD_E 29 +/* bit size */ #define GX_CP_VCD_HI_TEX1COORD_SZ 2 + +/* raw mask */ #define GX_CP_VCD_HI_TEX1COORD_MASK (((1 << 2) - 1) << 31 - 29) +/* local mask */ #define GX_CP_VCD_HI_TEX1COORD_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_CP_VCD_HI_TEX1COORD_SHIFT 2 + +/* get value */ #define GX_CP_GET_VCD_HI_TEX1COORD(reg) GX_BITGET((reg), 28, 2) +/* set value */ #define GX_CP_SET_VCD_HI_TEX1COORD(reg, x) ((reg) = GX_BITSET((reg), 28, 2, x)) + +// TEX2COORD [26:27] (2) +/* start bit */ #define GX_CP_VCD_HI_TEX2COORD_B 26 +/* end bit */ #define GX_CP_VCD_HI_TEX2COORD_E 27 +/* bit size */ #define GX_CP_VCD_HI_TEX2COORD_SZ 2 + +/* raw mask */ #define GX_CP_VCD_HI_TEX2COORD_MASK (((1 << 2) - 1) << 31 - 27) +/* local mask */ #define GX_CP_VCD_HI_TEX2COORD_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_CP_VCD_HI_TEX2COORD_SHIFT 4 + +/* get value */ #define GX_CP_GET_VCD_HI_TEX2COORD(reg) GX_BITGET((reg), 26, 2) +/* set value */ #define GX_CP_SET_VCD_HI_TEX2COORD(reg, x) ((reg) = GX_BITSET((reg), 26, 2, x)) + +// TEX3COORD [24:25] (2) +/* start bit */ #define GX_CP_VCD_HI_TEX3COORD_B 24 +/* end bit */ #define GX_CP_VCD_HI_TEX3COORD_E 25 +/* bit size */ #define GX_CP_VCD_HI_TEX3COORD_SZ 2 + +/* raw mask */ #define GX_CP_VCD_HI_TEX3COORD_MASK (((1 << 2) - 1) << 31 - 25) +/* local mask */ #define GX_CP_VCD_HI_TEX3COORD_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_CP_VCD_HI_TEX3COORD_SHIFT 6 + +/* get value */ #define GX_CP_GET_VCD_HI_TEX3COORD(reg) GX_BITGET((reg), 24, 2) +/* set value */ #define GX_CP_SET_VCD_HI_TEX3COORD(reg, x) ((reg) = GX_BITSET((reg), 24, 2, x)) + +// TEX4COORD [22:23] (2) +/* start bit */ #define GX_CP_VCD_HI_TEX4COORD_B 22 +/* end bit */ #define GX_CP_VCD_HI_TEX4COORD_E 23 +/* bit size */ #define GX_CP_VCD_HI_TEX4COORD_SZ 2 + +/* raw mask */ #define GX_CP_VCD_HI_TEX4COORD_MASK (((1 << 2) - 1) << 31 - 23) +/* local mask */ #define GX_CP_VCD_HI_TEX4COORD_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_CP_VCD_HI_TEX4COORD_SHIFT 8 + +/* get value */ #define GX_CP_GET_VCD_HI_TEX4COORD(reg) GX_BITGET((reg), 22, 2) +/* set value */ #define GX_CP_SET_VCD_HI_TEX4COORD(reg, x) ((reg) = GX_BITSET((reg), 22, 2, x)) + +// TEX5COORD [20:21] (2) +/* start bit */ #define GX_CP_VCD_HI_TEX5COORD_B 20 +/* end bit */ #define GX_CP_VCD_HI_TEX5COORD_E 21 +/* bit size */ #define GX_CP_VCD_HI_TEX5COORD_SZ 2 + +/* raw mask */ #define GX_CP_VCD_HI_TEX5COORD_MASK (((1 << 2) - 1) << 31 - 21) +/* local mask */ #define GX_CP_VCD_HI_TEX5COORD_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_CP_VCD_HI_TEX5COORD_SHIFT 10 + +/* get value */ #define GX_CP_GET_VCD_HI_TEX5COORD(reg) GX_BITGET((reg), 20, 2) +/* set value */ #define GX_CP_SET_VCD_HI_TEX5COORD(reg, x) ((reg) = GX_BITSET((reg), 20, 2, x)) + +// TEX6COORD [18:19] (2) +/* start bit */ #define GX_CP_VCD_HI_TEX6COORD_B 18 +/* end bit */ #define GX_CP_VCD_HI_TEX6COORD_E 19 +/* bit size */ #define GX_CP_VCD_HI_TEX6COORD_SZ 2 + +/* raw mask */ #define GX_CP_VCD_HI_TEX6COORD_MASK (((1 << 2) - 1) << 31 - 19) +/* local mask */ #define GX_CP_VCD_HI_TEX6COORD_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_CP_VCD_HI_TEX6COORD_SHIFT 12 + +/* get value */ #define GX_CP_GET_VCD_HI_TEX6COORD(reg) GX_BITGET((reg), 18, 2) +/* set value */ #define GX_CP_SET_VCD_HI_TEX6COORD(reg, x) ((reg) = GX_BITSET((reg), 18, 2, x)) + +// TEX7COORD [16:17] (2) +/* start bit */ #define GX_CP_VCD_HI_TEX7COORD_B 16 +/* end bit */ #define GX_CP_VCD_HI_TEX7COORD_E 17 +/* bit size */ #define GX_CP_VCD_HI_TEX7COORD_SZ 2 + +/* raw mask */ #define GX_CP_VCD_HI_TEX7COORD_MASK (((1 << 2) - 1) << 31 - 17) +/* local mask */ #define GX_CP_VCD_HI_TEX7COORD_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_CP_VCD_HI_TEX7COORD_SHIFT 14 + +/* get value */ #define GX_CP_GET_VCD_HI_TEX7COORD(reg) GX_BITGET((reg), 16, 2) +/* set value */ #define GX_CP_SET_VCD_HI_TEX7COORD(reg, x) ((reg) = GX_BITSET((reg), 16, 2, x)) + +/****************************************************************************** * CP register 0x70 - VAT_group0 - */ + *****************************************************************************/ // POS_CNT [31:31] (1) -#define GX_CP_VAT_GROUP0_POS_CNT_ST 31 -#define GX_CP_VAT_GROUP0_POS_CNT_END 31 -#define GX_CP_VAT_GROUP0_POS_CNT_SZ 1 -#define GX_CP_VAT_GROUP0_POS_CNT_MASK (((1 << 1) - 1) << 31 - 31) -#define GX_CP_GET_VAT_GROUP0_POS_CNT(reg) GX_BITGET(reg, 31, 1) -#define GX_CP_SET_VAT_GROUP0_POS_CNT(reg, x) ((reg) = GX_BITSET(reg, 31, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_POS_CNT_B 31 +/* end bit */ #define GX_CP_VAT_GROUP0_POS_CNT_E 31 +/* bit size */ #define GX_CP_VAT_GROUP0_POS_CNT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP0_POS_CNT_MASK (((1 << 1) - 1) << 31 - 31) +/* local mask */ #define GX_CP_VAT_GROUP0_POS_CNT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_POS_CNT_SHIFT 0 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_POS_CNT(reg) GX_BITGET((reg), 31, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP0_POS_CNT(reg, x) ((reg) = GX_BITSET((reg), 31, 1, x)) + // POS_TYPE [28:30] (3) -#define GX_CP_VAT_GROUP0_POS_TYPE_ST 28 -#define GX_CP_VAT_GROUP0_POS_TYPE_END 30 -#define GX_CP_VAT_GROUP0_POS_TYPE_SZ 3 -#define GX_CP_VAT_GROUP0_POS_TYPE_MASK (((1 << 3) - 1) << 31 - 30) -#define GX_CP_GET_VAT_GROUP0_POS_TYPE(reg) GX_BITGET(reg, 28, 3) -#define GX_CP_SET_VAT_GROUP0_POS_TYPE(reg, x) ((reg) = GX_BITSET(reg, 28, 3, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_POS_TYPE_B 28 +/* end bit */ #define GX_CP_VAT_GROUP0_POS_TYPE_E 30 +/* bit size */ #define GX_CP_VAT_GROUP0_POS_TYPE_SZ 3 + +/* raw mask */ #define GX_CP_VAT_GROUP0_POS_TYPE_MASK (((1 << 3) - 1) << 31 - 30) +/* local mask */ #define GX_CP_VAT_GROUP0_POS_TYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_POS_TYPE_SHIFT 1 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_POS_TYPE(reg) GX_BITGET((reg), 28, 3) +/* set value */ #define GX_CP_SET_VAT_GROUP0_POS_TYPE(reg, x) ((reg) = GX_BITSET((reg), 28, 3, x)) + // POS_SHIFT [23:27] (5) -#define GX_CP_VAT_GROUP0_POS_SHIFT_ST 23 -#define GX_CP_VAT_GROUP0_POS_SHIFT_END 27 -#define GX_CP_VAT_GROUP0_POS_SHIFT_SZ 5 -#define GX_CP_VAT_GROUP0_POS_SHIFT_MASK (((1 << 5) - 1) << 31 - 27) -#define GX_CP_GET_VAT_GROUP0_POS_SHIFT(reg) GX_BITGET(reg, 23, 5) -#define GX_CP_SET_VAT_GROUP0_POS_SHIFT(reg, x) ((reg) = GX_BITSET(reg, 23, 5, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_POS_SHIFT_B 23 +/* end bit */ #define GX_CP_VAT_GROUP0_POS_SHIFT_E 27 +/* bit size */ #define GX_CP_VAT_GROUP0_POS_SHIFT_SZ 5 + +/* raw mask */ #define GX_CP_VAT_GROUP0_POS_SHIFT_MASK (((1 << 5) - 1) << 31 - 27) +/* local mask */ #define GX_CP_VAT_GROUP0_POS_SHIFT_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_POS_SHIFT_SHIFT 4 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_POS_SHIFT(reg) GX_BITGET((reg), 23, 5) +/* set value */ #define GX_CP_SET_VAT_GROUP0_POS_SHIFT(reg, x) ((reg) = GX_BITSET((reg), 23, 5, x)) + // NRM_CNT [22:22] (1) -#define GX_CP_VAT_GROUP0_NRM_CNT_ST 22 -#define GX_CP_VAT_GROUP0_NRM_CNT_END 22 -#define GX_CP_VAT_GROUP0_NRM_CNT_SZ 1 -#define GX_CP_VAT_GROUP0_NRM_CNT_MASK (((1 << 1) - 1) << 31 - 22) -#define GX_CP_GET_VAT_GROUP0_NRM_CNT(reg) GX_BITGET(reg, 22, 1) -#define GX_CP_SET_VAT_GROUP0_NRM_CNT(reg, x) ((reg) = GX_BITSET(reg, 22, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_NRM_CNT_B 22 +/* end bit */ #define GX_CP_VAT_GROUP0_NRM_CNT_E 22 +/* bit size */ #define GX_CP_VAT_GROUP0_NRM_CNT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP0_NRM_CNT_MASK (((1 << 1) - 1) << 31 - 22) +/* local mask */ #define GX_CP_VAT_GROUP0_NRM_CNT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_NRM_CNT_SHIFT 9 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_NRM_CNT(reg) GX_BITGET((reg), 22, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP0_NRM_CNT(reg, x) ((reg) = GX_BITSET((reg), 22, 1, x)) + // NRM_TYPE [19:21] (3) -#define GX_CP_VAT_GROUP0_NRM_TYPE_ST 19 -#define GX_CP_VAT_GROUP0_NRM_TYPE_END 21 -#define GX_CP_VAT_GROUP0_NRM_TYPE_SZ 3 -#define GX_CP_VAT_GROUP0_NRM_TYPE_MASK (((1 << 3) - 1) << 31 - 21) -#define GX_CP_GET_VAT_GROUP0_NRM_TYPE(reg) GX_BITGET(reg, 19, 3) -#define GX_CP_SET_VAT_GROUP0_NRM_TYPE(reg, x) ((reg) = GX_BITSET(reg, 19, 3, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_NRM_TYPE_B 19 +/* end bit */ #define GX_CP_VAT_GROUP0_NRM_TYPE_E 21 +/* bit size */ #define GX_CP_VAT_GROUP0_NRM_TYPE_SZ 3 + +/* raw mask */ #define GX_CP_VAT_GROUP0_NRM_TYPE_MASK (((1 << 3) - 1) << 31 - 21) +/* local mask */ #define GX_CP_VAT_GROUP0_NRM_TYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_NRM_TYPE_SHIFT 10 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_NRM_TYPE(reg) GX_BITGET((reg), 19, 3) +/* set value */ #define GX_CP_SET_VAT_GROUP0_NRM_TYPE(reg, x) ((reg) = GX_BITSET((reg), 19, 3, x)) + // COLORDIFF_CNT [18:18] (1) -#define GX_CP_VAT_GROUP0_COLORDIFF_CNT_ST 18 -#define GX_CP_VAT_GROUP0_COLORDIFF_CNT_END 18 -#define GX_CP_VAT_GROUP0_COLORDIFF_CNT_SZ 1 -#define GX_CP_VAT_GROUP0_COLORDIFF_CNT_MASK (((1 << 1) - 1) << 31 - 18) -#define GX_CP_GET_VAT_GROUP0_COLORDIFF_CNT(reg) GX_BITGET(reg, 18, 1) -#define GX_CP_SET_VAT_GROUP0_COLORDIFF_CNT(reg, x) ((reg) = GX_BITSET(reg, 18, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_COLORDIFF_CNT_B 18 +/* end bit */ #define GX_CP_VAT_GROUP0_COLORDIFF_CNT_E 18 +/* bit size */ #define GX_CP_VAT_GROUP0_COLORDIFF_CNT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP0_COLORDIFF_CNT_MASK (((1 << 1) - 1) << 31 - 18) +/* local mask */ #define GX_CP_VAT_GROUP0_COLORDIFF_CNT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_COLORDIFF_CNT_SHIFT 13 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_COLORDIFF_CNT(reg) GX_BITGET((reg), 18, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP0_COLORDIFF_CNT(reg, x) ((reg) = GX_BITSET((reg), 18, 1, x)) + // COLORDIFF_TYPE [15:17] (3) -#define GX_CP_VAT_GROUP0_COLORDIFF_TYPE_ST 15 -#define GX_CP_VAT_GROUP0_COLORDIFF_TYPE_END 17 -#define GX_CP_VAT_GROUP0_COLORDIFF_TYPE_SZ 3 -#define GX_CP_VAT_GROUP0_COLORDIFF_TYPE_MASK (((1 << 3) - 1) << 31 - 17) -#define GX_CP_GET_VAT_GROUP0_COLORDIFF_TYPE(reg) GX_BITGET(reg, 15, 3) -#define GX_CP_SET_VAT_GROUP0_COLORDIFF_TYPE(reg, x) ((reg) = GX_BITSET(reg, 15, 3, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_COLORDIFF_TYPE_B 15 +/* end bit */ #define GX_CP_VAT_GROUP0_COLORDIFF_TYPE_E 17 +/* bit size */ #define GX_CP_VAT_GROUP0_COLORDIFF_TYPE_SZ 3 + +/* raw mask */ #define GX_CP_VAT_GROUP0_COLORDIFF_TYPE_MASK (((1 << 3) - 1) << 31 - 17) +/* local mask */ #define GX_CP_VAT_GROUP0_COLORDIFF_TYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_COLORDIFF_TYPE_SHIFT 14 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_COLORDIFF_TYPE(reg) GX_BITGET((reg), 15, 3) +/* set value */ #define GX_CP_SET_VAT_GROUP0_COLORDIFF_TYPE(reg, x) ((reg) = GX_BITSET((reg), 15, 3, x)) + // COLORSPEC_CNT [14:14] (1) -#define GX_CP_VAT_GROUP0_COLORSPEC_CNT_ST 14 -#define GX_CP_VAT_GROUP0_COLORSPEC_CNT_END 14 -#define GX_CP_VAT_GROUP0_COLORSPEC_CNT_SZ 1 -#define GX_CP_VAT_GROUP0_COLORSPEC_CNT_MASK (((1 << 1) - 1) << 31 - 14) -#define GX_CP_GET_VAT_GROUP0_COLORSPEC_CNT(reg) GX_BITGET(reg, 14, 1) -#define GX_CP_SET_VAT_GROUP0_COLORSPEC_CNT(reg, x) ((reg) = GX_BITSET(reg, 14, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_COLORSPEC_CNT_B 14 +/* end bit */ #define GX_CP_VAT_GROUP0_COLORSPEC_CNT_E 14 +/* bit size */ #define GX_CP_VAT_GROUP0_COLORSPEC_CNT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP0_COLORSPEC_CNT_MASK (((1 << 1) - 1) << 31 - 14) +/* local mask */ #define GX_CP_VAT_GROUP0_COLORSPEC_CNT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_COLORSPEC_CNT_SHIFT 17 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_COLORSPEC_CNT(reg) GX_BITGET((reg), 14, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP0_COLORSPEC_CNT(reg, x) ((reg) = GX_BITSET((reg), 14, 1, x)) + // COLORSPEC_TYPE [11:13] (3) -#define GX_CP_VAT_GROUP0_COLORSPEC_TYPE_ST 11 -#define GX_CP_VAT_GROUP0_COLORSPEC_TYPE_END 13 -#define GX_CP_VAT_GROUP0_COLORSPEC_TYPE_SZ 3 -#define GX_CP_VAT_GROUP0_COLORSPEC_TYPE_MASK (((1 << 3) - 1) << 31 - 13) -#define GX_CP_GET_VAT_GROUP0_COLORSPEC_TYPE(reg) GX_BITGET(reg, 11, 3) -#define GX_CP_SET_VAT_GROUP0_COLORSPEC_TYPE(reg, x) ((reg) = GX_BITSET(reg, 11, 3, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_COLORSPEC_TYPE_B 11 +/* end bit */ #define GX_CP_VAT_GROUP0_COLORSPEC_TYPE_E 13 +/* bit size */ #define GX_CP_VAT_GROUP0_COLORSPEC_TYPE_SZ 3 + +/* raw mask */ #define GX_CP_VAT_GROUP0_COLORSPEC_TYPE_MASK (((1 << 3) - 1) << 31 - 13) +/* local mask */ #define GX_CP_VAT_GROUP0_COLORSPEC_TYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_COLORSPEC_TYPE_SHIFT 18 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_COLORSPEC_TYPE(reg) GX_BITGET((reg), 11, 3) +/* set value */ #define GX_CP_SET_VAT_GROUP0_COLORSPEC_TYPE(reg, x) ((reg) = GX_BITSET((reg), 11, 3, x)) + // TXC0_CNT [10:10] (1) -#define GX_CP_VAT_GROUP0_TXC0_CNT_ST 10 -#define GX_CP_VAT_GROUP0_TXC0_CNT_END 10 -#define GX_CP_VAT_GROUP0_TXC0_CNT_SZ 1 -#define GX_CP_VAT_GROUP0_TXC0_CNT_MASK (((1 << 1) - 1) << 31 - 10) -#define GX_CP_GET_VAT_GROUP0_TXC0_CNT(reg) GX_BITGET(reg, 10, 1) -#define GX_CP_SET_VAT_GROUP0_TXC0_CNT(reg, x) ((reg) = GX_BITSET(reg, 10, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_TXC0_CNT_B 10 +/* end bit */ #define GX_CP_VAT_GROUP0_TXC0_CNT_E 10 +/* bit size */ #define GX_CP_VAT_GROUP0_TXC0_CNT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP0_TXC0_CNT_MASK (((1 << 1) - 1) << 31 - 10) +/* local mask */ #define GX_CP_VAT_GROUP0_TXC0_CNT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_TXC0_CNT_SHIFT 21 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_TXC0_CNT(reg) GX_BITGET((reg), 10, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP0_TXC0_CNT(reg, x) ((reg) = GX_BITSET((reg), 10, 1, x)) + // TXC0_TYPE [7:9] (3) -#define GX_CP_VAT_GROUP0_TXC0_TYPE_ST 7 -#define GX_CP_VAT_GROUP0_TXC0_TYPE_END 9 -#define GX_CP_VAT_GROUP0_TXC0_TYPE_SZ 3 -#define GX_CP_VAT_GROUP0_TXC0_TYPE_MASK (((1 << 3) - 1) << 31 - 9) -#define GX_CP_GET_VAT_GROUP0_TXC0_TYPE(reg) GX_BITGET(reg, 7, 3) -#define GX_CP_SET_VAT_GROUP0_TXC0_TYPE(reg, x) ((reg) = GX_BITSET(reg, 7, 3, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_TXC0_TYPE_B 7 +/* end bit */ #define GX_CP_VAT_GROUP0_TXC0_TYPE_E 9 +/* bit size */ #define GX_CP_VAT_GROUP0_TXC0_TYPE_SZ 3 + +/* raw mask */ #define GX_CP_VAT_GROUP0_TXC0_TYPE_MASK (((1 << 3) - 1) << 31 - 9) +/* local mask */ #define GX_CP_VAT_GROUP0_TXC0_TYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_TXC0_TYPE_SHIFT 22 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_TXC0_TYPE(reg) GX_BITGET((reg), 7, 3) +/* set value */ #define GX_CP_SET_VAT_GROUP0_TXC0_TYPE(reg, x) ((reg) = GX_BITSET((reg), 7, 3, x)) + // TXC0_SHIFT [2:6] (5) -#define GX_CP_VAT_GROUP0_TXC0_SHIFT_ST 2 -#define GX_CP_VAT_GROUP0_TXC0_SHIFT_END 6 -#define GX_CP_VAT_GROUP0_TXC0_SHIFT_SZ 5 -#define GX_CP_VAT_GROUP0_TXC0_SHIFT_MASK (((1 << 5) - 1) << 31 - 6) -#define GX_CP_GET_VAT_GROUP0_TXC0_SHIFT(reg) GX_BITGET(reg, 2, 5) -#define GX_CP_SET_VAT_GROUP0_TXC0_SHIFT(reg, x) ((reg) = GX_BITSET(reg, 2, 5, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_TXC0_SHIFT_B 2 +/* end bit */ #define GX_CP_VAT_GROUP0_TXC0_SHIFT_E 6 +/* bit size */ #define GX_CP_VAT_GROUP0_TXC0_SHIFT_SZ 5 + +/* raw mask */ #define GX_CP_VAT_GROUP0_TXC0_SHIFT_MASK (((1 << 5) - 1) << 31 - 6) +/* local mask */ #define GX_CP_VAT_GROUP0_TXC0_SHIFT_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_TXC0_SHIFT_SHIFT 25 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_TXC0_SHIFT(reg) GX_BITGET((reg), 2, 5) +/* set value */ #define GX_CP_SET_VAT_GROUP0_TXC0_SHIFT(reg, x) ((reg) = GX_BITSET((reg), 2, 5, x)) + // BYTEDEQUANT [1:1] (1) -#define GX_CP_VAT_GROUP0_BYTEDEQUANT_ST 1 -#define GX_CP_VAT_GROUP0_BYTEDEQUANT_END 1 -#define GX_CP_VAT_GROUP0_BYTEDEQUANT_SZ 1 -#define GX_CP_VAT_GROUP0_BYTEDEQUANT_MASK (((1 << 1) - 1) << 31 - 1) -#define GX_CP_GET_VAT_GROUP0_BYTEDEQUANT(reg) GX_BITGET(reg, 1, 1) -#define GX_CP_SET_VAT_GROUP0_BYTEDEQUANT(reg, x) ((reg) = GX_BITSET(reg, 1, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_BYTEDEQUANT_B 1 +/* end bit */ #define GX_CP_VAT_GROUP0_BYTEDEQUANT_E 1 +/* bit size */ #define GX_CP_VAT_GROUP0_BYTEDEQUANT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP0_BYTEDEQUANT_MASK (((1 << 1) - 1) << 31 - 1) +/* local mask */ #define GX_CP_VAT_GROUP0_BYTEDEQUANT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_BYTEDEQUANT_SHIFT 30 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_BYTEDEQUANT(reg) GX_BITGET((reg), 1, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP0_BYTEDEQUANT(reg, x) ((reg) = GX_BITSET((reg), 1, 1, x)) + // NORMALINDEX3 [0:0] (1) - Input will be treated as three staggered indices (one per triple biased by component size) // into normal table -#define GX_CP_VAT_GROUP0_NORMALINDEX3_ST 0 -#define GX_CP_VAT_GROUP0_NORMALINDEX3_END 0 -#define GX_CP_VAT_GROUP0_NORMALINDEX3_SZ 1 -#define GX_CP_VAT_GROUP0_NORMALINDEX3_MASK (((1 << 1) - 1) << 31 - 0) -#define GX_CP_GET_VAT_GROUP0_NORMALINDEX3(reg) GX_BITGET(reg, 0, 1) -#define GX_CP_SET_VAT_GROUP0_NORMALINDEX3(reg, x) ((reg) = GX_BITSET(reg, 0, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP0_NORMALINDEX3_B 0 +/* end bit */ #define GX_CP_VAT_GROUP0_NORMALINDEX3_E 0 +/* bit size */ #define GX_CP_VAT_GROUP0_NORMALINDEX3_SZ 1 -/** +/* raw mask */ #define GX_CP_VAT_GROUP0_NORMALINDEX3_MASK (((1 << 1) - 1) << 31 - 0) +/* local mask */ #define GX_CP_VAT_GROUP0_NORMALINDEX3_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP0_NORMALINDEX3_SHIFT 31 + +/* get value */ #define GX_CP_GET_VAT_GROUP0_NORMALINDEX3(reg) GX_BITGET((reg), 0, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP0_NORMALINDEX3(reg, x) ((reg) = GX_BITSET((reg), 0, 1, x)) + +/****************************************************************************** * CP register 0x80 - VAT_group1 - */ + *****************************************************************************/ // TXC1_CNT [31:31] (1) -#define GX_CP_VAT_GROUP1_TXC1_CNT_ST 31 -#define GX_CP_VAT_GROUP1_TXC1_CNT_END 31 -#define GX_CP_VAT_GROUP1_TXC1_CNT_SZ 1 -#define GX_CP_VAT_GROUP1_TXC1_CNT_MASK (((1 << 1) - 1) << 31 - 31) -#define GX_CP_GET_VAT_GROUP1_TXC1_CNT(reg) GX_BITGET(reg, 31, 1) -#define GX_CP_SET_VAT_GROUP1_TXC1_CNT(reg, x) ((reg) = GX_BITSET(reg, 31, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP1_TXC1_CNT_B 31 +/* end bit */ #define GX_CP_VAT_GROUP1_TXC1_CNT_E 31 +/* bit size */ #define GX_CP_VAT_GROUP1_TXC1_CNT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP1_TXC1_CNT_MASK (((1 << 1) - 1) << 31 - 31) +/* local mask */ #define GX_CP_VAT_GROUP1_TXC1_CNT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP1_TXC1_CNT_SHIFT 0 + +/* get value */ #define GX_CP_GET_VAT_GROUP1_TXC1_CNT(reg) GX_BITGET((reg), 31, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP1_TXC1_CNT(reg, x) ((reg) = GX_BITSET((reg), 31, 1, x)) + // TXC1_TYPE [28:30] (3) -#define GX_CP_VAT_GROUP1_TXC1_TYPE_ST 28 -#define GX_CP_VAT_GROUP1_TXC1_TYPE_END 30 -#define GX_CP_VAT_GROUP1_TXC1_TYPE_SZ 3 -#define GX_CP_VAT_GROUP1_TXC1_TYPE_MASK (((1 << 3) - 1) << 31 - 30) -#define GX_CP_GET_VAT_GROUP1_TXC1_TYPE(reg) GX_BITGET(reg, 28, 3) -#define GX_CP_SET_VAT_GROUP1_TXC1_TYPE(reg, x) ((reg) = GX_BITSET(reg, 28, 3, x)) +/* start bit */ #define GX_CP_VAT_GROUP1_TXC1_TYPE_B 28 +/* end bit */ #define GX_CP_VAT_GROUP1_TXC1_TYPE_E 30 +/* bit size */ #define GX_CP_VAT_GROUP1_TXC1_TYPE_SZ 3 + +/* raw mask */ #define GX_CP_VAT_GROUP1_TXC1_TYPE_MASK (((1 << 3) - 1) << 31 - 30) +/* local mask */ #define GX_CP_VAT_GROUP1_TXC1_TYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP1_TXC1_TYPE_SHIFT 1 + +/* get value */ #define GX_CP_GET_VAT_GROUP1_TXC1_TYPE(reg) GX_BITGET((reg), 28, 3) +/* set value */ #define GX_CP_SET_VAT_GROUP1_TXC1_TYPE(reg, x) ((reg) = GX_BITSET((reg), 28, 3, x)) + // TXC1_SHIFT [23:27] (5) -#define GX_CP_VAT_GROUP1_TXC1_SHIFT_ST 23 -#define GX_CP_VAT_GROUP1_TXC1_SHIFT_END 27 -#define GX_CP_VAT_GROUP1_TXC1_SHIFT_SZ 5 -#define GX_CP_VAT_GROUP1_TXC1_SHIFT_MASK (((1 << 5) - 1) << 31 - 27) -#define GX_CP_GET_VAT_GROUP1_TXC1_SHIFT(reg) GX_BITGET(reg, 23, 5) -#define GX_CP_SET_VAT_GROUP1_TXC1_SHIFT(reg, x) ((reg) = GX_BITSET(reg, 23, 5, x)) +/* start bit */ #define GX_CP_VAT_GROUP1_TXC1_SHIFT_B 23 +/* end bit */ #define GX_CP_VAT_GROUP1_TXC1_SHIFT_E 27 +/* bit size */ #define GX_CP_VAT_GROUP1_TXC1_SHIFT_SZ 5 + +/* raw mask */ #define GX_CP_VAT_GROUP1_TXC1_SHIFT_MASK (((1 << 5) - 1) << 31 - 27) +/* local mask */ #define GX_CP_VAT_GROUP1_TXC1_SHIFT_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP1_TXC1_SHIFT_SHIFT 4 + +/* get value */ #define GX_CP_GET_VAT_GROUP1_TXC1_SHIFT(reg) GX_BITGET((reg), 23, 5) +/* set value */ #define GX_CP_SET_VAT_GROUP1_TXC1_SHIFT(reg, x) ((reg) = GX_BITSET((reg), 23, 5, x)) + // TXC2_CNT [22:22] (1) -#define GX_CP_VAT_GROUP1_TXC2_CNT_ST 22 -#define GX_CP_VAT_GROUP1_TXC2_CNT_END 22 -#define GX_CP_VAT_GROUP1_TXC2_CNT_SZ 1 -#define GX_CP_VAT_GROUP1_TXC2_CNT_MASK (((1 << 1) - 1) << 31 - 22) -#define GX_CP_GET_VAT_GROUP1_TXC2_CNT(reg) GX_BITGET(reg, 22, 1) -#define GX_CP_SET_VAT_GROUP1_TXC2_CNT(reg, x) ((reg) = GX_BITSET(reg, 22, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP1_TXC2_CNT_B 22 +/* end bit */ #define GX_CP_VAT_GROUP1_TXC2_CNT_E 22 +/* bit size */ #define GX_CP_VAT_GROUP1_TXC2_CNT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP1_TXC2_CNT_MASK (((1 << 1) - 1) << 31 - 22) +/* local mask */ #define GX_CP_VAT_GROUP1_TXC2_CNT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP1_TXC2_CNT_SHIFT 9 + +/* get value */ #define GX_CP_GET_VAT_GROUP1_TXC2_CNT(reg) GX_BITGET((reg), 22, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP1_TXC2_CNT(reg, x) ((reg) = GX_BITSET((reg), 22, 1, x)) + // TXC2_TYPE [19:21] (3) -#define GX_CP_VAT_GROUP1_TXC2_TYPE_ST 19 -#define GX_CP_VAT_GROUP1_TXC2_TYPE_END 21 -#define GX_CP_VAT_GROUP1_TXC2_TYPE_SZ 3 -#define GX_CP_VAT_GROUP1_TXC2_TYPE_MASK (((1 << 3) - 1) << 31 - 21) -#define GX_CP_GET_VAT_GROUP1_TXC2_TYPE(reg) GX_BITGET(reg, 19, 3) -#define GX_CP_SET_VAT_GROUP1_TXC2_TYPE(reg, x) ((reg) = GX_BITSET(reg, 19, 3, x)) +/* start bit */ #define GX_CP_VAT_GROUP1_TXC2_TYPE_B 19 +/* end bit */ #define GX_CP_VAT_GROUP1_TXC2_TYPE_E 21 +/* bit size */ #define GX_CP_VAT_GROUP1_TXC2_TYPE_SZ 3 + +/* raw mask */ #define GX_CP_VAT_GROUP1_TXC2_TYPE_MASK (((1 << 3) - 1) << 31 - 21) +/* local mask */ #define GX_CP_VAT_GROUP1_TXC2_TYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP1_TXC2_TYPE_SHIFT 10 + +/* get value */ #define GX_CP_GET_VAT_GROUP1_TXC2_TYPE(reg) GX_BITGET((reg), 19, 3) +/* set value */ #define GX_CP_SET_VAT_GROUP1_TXC2_TYPE(reg, x) ((reg) = GX_BITSET((reg), 19, 3, x)) + // TXC2_SHIFT [14:18] (5) -#define GX_CP_VAT_GROUP1_TXC2_SHIFT_ST 14 -#define GX_CP_VAT_GROUP1_TXC2_SHIFT_END 18 -#define GX_CP_VAT_GROUP1_TXC2_SHIFT_SZ 5 -#define GX_CP_VAT_GROUP1_TXC2_SHIFT_MASK (((1 << 5) - 1) << 31 - 18) -#define GX_CP_GET_VAT_GROUP1_TXC2_SHIFT(reg) GX_BITGET(reg, 14, 5) -#define GX_CP_SET_VAT_GROUP1_TXC2_SHIFT(reg, x) ((reg) = GX_BITSET(reg, 14, 5, x)) +/* start bit */ #define GX_CP_VAT_GROUP1_TXC2_SHIFT_B 14 +/* end bit */ #define GX_CP_VAT_GROUP1_TXC2_SHIFT_E 18 +/* bit size */ #define GX_CP_VAT_GROUP1_TXC2_SHIFT_SZ 5 + +/* raw mask */ #define GX_CP_VAT_GROUP1_TXC2_SHIFT_MASK (((1 << 5) - 1) << 31 - 18) +/* local mask */ #define GX_CP_VAT_GROUP1_TXC2_SHIFT_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP1_TXC2_SHIFT_SHIFT 13 + +/* get value */ #define GX_CP_GET_VAT_GROUP1_TXC2_SHIFT(reg) GX_BITGET((reg), 14, 5) +/* set value */ #define GX_CP_SET_VAT_GROUP1_TXC2_SHIFT(reg, x) ((reg) = GX_BITSET((reg), 14, 5, x)) + // TXC3_CNT [13:13] (1) -#define GX_CP_VAT_GROUP1_TXC3_CNT_ST 13 -#define GX_CP_VAT_GROUP1_TXC3_CNT_END 13 -#define GX_CP_VAT_GROUP1_TXC3_CNT_SZ 1 -#define GX_CP_VAT_GROUP1_TXC3_CNT_MASK (((1 << 1) - 1) << 31 - 13) -#define GX_CP_GET_VAT_GROUP1_TXC3_CNT(reg) GX_BITGET(reg, 13, 1) -#define GX_CP_SET_VAT_GROUP1_TXC3_CNT(reg, x) ((reg) = GX_BITSET(reg, 13, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP1_TXC3_CNT_B 13 +/* end bit */ #define GX_CP_VAT_GROUP1_TXC3_CNT_E 13 +/* bit size */ #define GX_CP_VAT_GROUP1_TXC3_CNT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP1_TXC3_CNT_MASK (((1 << 1) - 1) << 31 - 13) +/* local mask */ #define GX_CP_VAT_GROUP1_TXC3_CNT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP1_TXC3_CNT_SHIFT 18 + +/* get value */ #define GX_CP_GET_VAT_GROUP1_TXC3_CNT(reg) GX_BITGET((reg), 13, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP1_TXC3_CNT(reg, x) ((reg) = GX_BITSET((reg), 13, 1, x)) + // TXC3_TYPE [10:12] (3) -#define GX_CP_VAT_GROUP1_TXC3_TYPE_ST 10 -#define GX_CP_VAT_GROUP1_TXC3_TYPE_END 12 -#define GX_CP_VAT_GROUP1_TXC3_TYPE_SZ 3 -#define GX_CP_VAT_GROUP1_TXC3_TYPE_MASK (((1 << 3) - 1) << 31 - 12) -#define GX_CP_GET_VAT_GROUP1_TXC3_TYPE(reg) GX_BITGET(reg, 10, 3) -#define GX_CP_SET_VAT_GROUP1_TXC3_TYPE(reg, x) ((reg) = GX_BITSET(reg, 10, 3, x)) +/* start bit */ #define GX_CP_VAT_GROUP1_TXC3_TYPE_B 10 +/* end bit */ #define GX_CP_VAT_GROUP1_TXC3_TYPE_E 12 +/* bit size */ #define GX_CP_VAT_GROUP1_TXC3_TYPE_SZ 3 + +/* raw mask */ #define GX_CP_VAT_GROUP1_TXC3_TYPE_MASK (((1 << 3) - 1) << 31 - 12) +/* local mask */ #define GX_CP_VAT_GROUP1_TXC3_TYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP1_TXC3_TYPE_SHIFT 19 + +/* get value */ #define GX_CP_GET_VAT_GROUP1_TXC3_TYPE(reg) GX_BITGET((reg), 10, 3) +/* set value */ #define GX_CP_SET_VAT_GROUP1_TXC3_TYPE(reg, x) ((reg) = GX_BITSET((reg), 10, 3, x)) + // TXC3_SHIFT [5:9] (5) -#define GX_CP_VAT_GROUP1_TXC3_SHIFT_ST 5 -#define GX_CP_VAT_GROUP1_TXC3_SHIFT_END 9 -#define GX_CP_VAT_GROUP1_TXC3_SHIFT_SZ 5 -#define GX_CP_VAT_GROUP1_TXC3_SHIFT_MASK (((1 << 5) - 1) << 31 - 9) -#define GX_CP_GET_VAT_GROUP1_TXC3_SHIFT(reg) GX_BITGET(reg, 5, 5) -#define GX_CP_SET_VAT_GROUP1_TXC3_SHIFT(reg, x) ((reg) = GX_BITSET(reg, 5, 5, x)) +/* start bit */ #define GX_CP_VAT_GROUP1_TXC3_SHIFT_B 5 +/* end bit */ #define GX_CP_VAT_GROUP1_TXC3_SHIFT_E 9 +/* bit size */ #define GX_CP_VAT_GROUP1_TXC3_SHIFT_SZ 5 + +/* raw mask */ #define GX_CP_VAT_GROUP1_TXC3_SHIFT_MASK (((1 << 5) - 1) << 31 - 9) +/* local mask */ #define GX_CP_VAT_GROUP1_TXC3_SHIFT_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP1_TXC3_SHIFT_SHIFT 22 + +/* get value */ #define GX_CP_GET_VAT_GROUP1_TXC3_SHIFT(reg) GX_BITGET((reg), 5, 5) +/* set value */ #define GX_CP_SET_VAT_GROUP1_TXC3_SHIFT(reg, x) ((reg) = GX_BITSET((reg), 5, 5, x)) + // TXC4_CNT [4:4] (1) -#define GX_CP_VAT_GROUP1_TXC4_CNT_ST 4 -#define GX_CP_VAT_GROUP1_TXC4_CNT_END 4 -#define GX_CP_VAT_GROUP1_TXC4_CNT_SZ 1 -#define GX_CP_VAT_GROUP1_TXC4_CNT_MASK (((1 << 1) - 1) << 31 - 4) -#define GX_CP_GET_VAT_GROUP1_TXC4_CNT(reg) GX_BITGET(reg, 4, 1) -#define GX_CP_SET_VAT_GROUP1_TXC4_CNT(reg, x) ((reg) = GX_BITSET(reg, 4, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP1_TXC4_CNT_B 4 +/* end bit */ #define GX_CP_VAT_GROUP1_TXC4_CNT_E 4 +/* bit size */ #define GX_CP_VAT_GROUP1_TXC4_CNT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP1_TXC4_CNT_MASK (((1 << 1) - 1) << 31 - 4) +/* local mask */ #define GX_CP_VAT_GROUP1_TXC4_CNT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP1_TXC4_CNT_SHIFT 27 + +/* get value */ #define GX_CP_GET_VAT_GROUP1_TXC4_CNT(reg) GX_BITGET((reg), 4, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP1_TXC4_CNT(reg, x) ((reg) = GX_BITSET((reg), 4, 1, x)) + // TXC4_TYPE [1:3] (3) -#define GX_CP_VAT_GROUP1_TXC4_TYPE_ST 1 -#define GX_CP_VAT_GROUP1_TXC4_TYPE_END 3 -#define GX_CP_VAT_GROUP1_TXC4_TYPE_SZ 3 -#define GX_CP_VAT_GROUP1_TXC4_TYPE_MASK (((1 << 3) - 1) << 31 - 3) -#define GX_CP_GET_VAT_GROUP1_TXC4_TYPE(reg) GX_BITGET(reg, 1, 3) -#define GX_CP_SET_VAT_GROUP1_TXC4_TYPE(reg, x) ((reg) = GX_BITSET(reg, 1, 3, x)) +/* start bit */ #define GX_CP_VAT_GROUP1_TXC4_TYPE_B 1 +/* end bit */ #define GX_CP_VAT_GROUP1_TXC4_TYPE_E 3 +/* bit size */ #define GX_CP_VAT_GROUP1_TXC4_TYPE_SZ 3 -/** +/* raw mask */ #define GX_CP_VAT_GROUP1_TXC4_TYPE_MASK (((1 << 3) - 1) << 31 - 3) +/* local mask */ #define GX_CP_VAT_GROUP1_TXC4_TYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP1_TXC4_TYPE_SHIFT 28 + +/* get value */ #define GX_CP_GET_VAT_GROUP1_TXC4_TYPE(reg) GX_BITGET((reg), 1, 3) +/* set value */ #define GX_CP_SET_VAT_GROUP1_TXC4_TYPE(reg, x) ((reg) = GX_BITSET((reg), 1, 3, x)) + +/****************************************************************************** * CP register 0x90 - VAT_group2 - */ + *****************************************************************************/ // TXC4_SHIFT [27:31] (5) -#define GX_CP_VAT_GROUP2_TXC4_SHIFT_ST 27 -#define GX_CP_VAT_GROUP2_TXC4_SHIFT_END 31 -#define GX_CP_VAT_GROUP2_TXC4_SHIFT_SZ 5 -#define GX_CP_VAT_GROUP2_TXC4_SHIFT_MASK (((1 << 5) - 1) << 31 - 31) -#define GX_CP_GET_VAT_GROUP2_TXC4_SHIFT(reg) GX_BITGET(reg, 27, 5) -#define GX_CP_SET_VAT_GROUP2_TXC4_SHIFT(reg, x) ((reg) = GX_BITSET(reg, 27, 5, x)) +/* start bit */ #define GX_CP_VAT_GROUP2_TXC4_SHIFT_B 27 +/* end bit */ #define GX_CP_VAT_GROUP2_TXC4_SHIFT_E 31 +/* bit size */ #define GX_CP_VAT_GROUP2_TXC4_SHIFT_SZ 5 + +/* raw mask */ #define GX_CP_VAT_GROUP2_TXC4_SHIFT_MASK (((1 << 5) - 1) << 31 - 31) +/* local mask */ #define GX_CP_VAT_GROUP2_TXC4_SHIFT_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP2_TXC4_SHIFT_SHIFT 0 + +/* get value */ #define GX_CP_GET_VAT_GROUP2_TXC4_SHIFT(reg) GX_BITGET((reg), 27, 5) +/* set value */ #define GX_CP_SET_VAT_GROUP2_TXC4_SHIFT(reg, x) ((reg) = GX_BITSET((reg), 27, 5, x)) + // TXC5_CNT [26:26] (1) -#define GX_CP_VAT_GROUP2_TXC5_CNT_ST 26 -#define GX_CP_VAT_GROUP2_TXC5_CNT_END 26 -#define GX_CP_VAT_GROUP2_TXC5_CNT_SZ 1 -#define GX_CP_VAT_GROUP2_TXC5_CNT_MASK (((1 << 1) - 1) << 31 - 26) -#define GX_CP_GET_VAT_GROUP2_TXC5_CNT(reg) GX_BITGET(reg, 26, 1) -#define GX_CP_SET_VAT_GROUP2_TXC5_CNT(reg, x) ((reg) = GX_BITSET(reg, 26, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP2_TXC5_CNT_B 26 +/* end bit */ #define GX_CP_VAT_GROUP2_TXC5_CNT_E 26 +/* bit size */ #define GX_CP_VAT_GROUP2_TXC5_CNT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP2_TXC5_CNT_MASK (((1 << 1) - 1) << 31 - 26) +/* local mask */ #define GX_CP_VAT_GROUP2_TXC5_CNT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP2_TXC5_CNT_SHIFT 5 + +/* get value */ #define GX_CP_GET_VAT_GROUP2_TXC5_CNT(reg) GX_BITGET((reg), 26, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP2_TXC5_CNT(reg, x) ((reg) = GX_BITSET((reg), 26, 1, x)) + // TXC5_TYPE [23:25] (3) -#define GX_CP_VAT_GROUP2_TXC5_TYPE_ST 23 -#define GX_CP_VAT_GROUP2_TXC5_TYPE_END 25 -#define GX_CP_VAT_GROUP2_TXC5_TYPE_SZ 3 -#define GX_CP_VAT_GROUP2_TXC5_TYPE_MASK (((1 << 3) - 1) << 31 - 25) -#define GX_CP_GET_VAT_GROUP2_TXC5_TYPE(reg) GX_BITGET(reg, 23, 3) -#define GX_CP_SET_VAT_GROUP2_TXC5_TYPE(reg, x) ((reg) = GX_BITSET(reg, 23, 3, x)) +/* start bit */ #define GX_CP_VAT_GROUP2_TXC5_TYPE_B 23 +/* end bit */ #define GX_CP_VAT_GROUP2_TXC5_TYPE_E 25 +/* bit size */ #define GX_CP_VAT_GROUP2_TXC5_TYPE_SZ 3 + +/* raw mask */ #define GX_CP_VAT_GROUP2_TXC5_TYPE_MASK (((1 << 3) - 1) << 31 - 25) +/* local mask */ #define GX_CP_VAT_GROUP2_TXC5_TYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP2_TXC5_TYPE_SHIFT 6 + +/* get value */ #define GX_CP_GET_VAT_GROUP2_TXC5_TYPE(reg) GX_BITGET((reg), 23, 3) +/* set value */ #define GX_CP_SET_VAT_GROUP2_TXC5_TYPE(reg, x) ((reg) = GX_BITSET((reg), 23, 3, x)) + // TXC5_SHIFT [18:22] (5) -#define GX_CP_VAT_GROUP2_TXC5_SHIFT_ST 18 -#define GX_CP_VAT_GROUP2_TXC5_SHIFT_END 22 -#define GX_CP_VAT_GROUP2_TXC5_SHIFT_SZ 5 -#define GX_CP_VAT_GROUP2_TXC5_SHIFT_MASK (((1 << 5) - 1) << 31 - 22) -#define GX_CP_GET_VAT_GROUP2_TXC5_SHIFT(reg) GX_BITGET(reg, 18, 5) -#define GX_CP_SET_VAT_GROUP2_TXC5_SHIFT(reg, x) ((reg) = GX_BITSET(reg, 18, 5, x)) +/* start bit */ #define GX_CP_VAT_GROUP2_TXC5_SHIFT_B 18 +/* end bit */ #define GX_CP_VAT_GROUP2_TXC5_SHIFT_E 22 +/* bit size */ #define GX_CP_VAT_GROUP2_TXC5_SHIFT_SZ 5 + +/* raw mask */ #define GX_CP_VAT_GROUP2_TXC5_SHIFT_MASK (((1 << 5) - 1) << 31 - 22) +/* local mask */ #define GX_CP_VAT_GROUP2_TXC5_SHIFT_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP2_TXC5_SHIFT_SHIFT 9 + +/* get value */ #define GX_CP_GET_VAT_GROUP2_TXC5_SHIFT(reg) GX_BITGET((reg), 18, 5) +/* set value */ #define GX_CP_SET_VAT_GROUP2_TXC5_SHIFT(reg, x) ((reg) = GX_BITSET((reg), 18, 5, x)) + // TXC6_CNT [17:17] (1) -#define GX_CP_VAT_GROUP2_TXC6_CNT_ST 17 -#define GX_CP_VAT_GROUP2_TXC6_CNT_END 17 -#define GX_CP_VAT_GROUP2_TXC6_CNT_SZ 1 -#define GX_CP_VAT_GROUP2_TXC6_CNT_MASK (((1 << 1) - 1) << 31 - 17) -#define GX_CP_GET_VAT_GROUP2_TXC6_CNT(reg) GX_BITGET(reg, 17, 1) -#define GX_CP_SET_VAT_GROUP2_TXC6_CNT(reg, x) ((reg) = GX_BITSET(reg, 17, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP2_TXC6_CNT_B 17 +/* end bit */ #define GX_CP_VAT_GROUP2_TXC6_CNT_E 17 +/* bit size */ #define GX_CP_VAT_GROUP2_TXC6_CNT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP2_TXC6_CNT_MASK (((1 << 1) - 1) << 31 - 17) +/* local mask */ #define GX_CP_VAT_GROUP2_TXC6_CNT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP2_TXC6_CNT_SHIFT 14 + +/* get value */ #define GX_CP_GET_VAT_GROUP2_TXC6_CNT(reg) GX_BITGET((reg), 17, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP2_TXC6_CNT(reg, x) ((reg) = GX_BITSET((reg), 17, 1, x)) + // TXC6_TYPE [14:16] (3) -#define GX_CP_VAT_GROUP2_TXC6_TYPE_ST 14 -#define GX_CP_VAT_GROUP2_TXC6_TYPE_END 16 -#define GX_CP_VAT_GROUP2_TXC6_TYPE_SZ 3 -#define GX_CP_VAT_GROUP2_TXC6_TYPE_MASK (((1 << 3) - 1) << 31 - 16) -#define GX_CP_GET_VAT_GROUP2_TXC6_TYPE(reg) GX_BITGET(reg, 14, 3) -#define GX_CP_SET_VAT_GROUP2_TXC6_TYPE(reg, x) ((reg) = GX_BITSET(reg, 14, 3, x)) +/* start bit */ #define GX_CP_VAT_GROUP2_TXC6_TYPE_B 14 +/* end bit */ #define GX_CP_VAT_GROUP2_TXC6_TYPE_E 16 +/* bit size */ #define GX_CP_VAT_GROUP2_TXC6_TYPE_SZ 3 + +/* raw mask */ #define GX_CP_VAT_GROUP2_TXC6_TYPE_MASK (((1 << 3) - 1) << 31 - 16) +/* local mask */ #define GX_CP_VAT_GROUP2_TXC6_TYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP2_TXC6_TYPE_SHIFT 15 + +/* get value */ #define GX_CP_GET_VAT_GROUP2_TXC6_TYPE(reg) GX_BITGET((reg), 14, 3) +/* set value */ #define GX_CP_SET_VAT_GROUP2_TXC6_TYPE(reg, x) ((reg) = GX_BITSET((reg), 14, 3, x)) + // TXC6_SHIFT [9:13] (5) -#define GX_CP_VAT_GROUP2_TXC6_SHIFT_ST 9 -#define GX_CP_VAT_GROUP2_TXC6_SHIFT_END 13 -#define GX_CP_VAT_GROUP2_TXC6_SHIFT_SZ 5 -#define GX_CP_VAT_GROUP2_TXC6_SHIFT_MASK (((1 << 5) - 1) << 31 - 13) -#define GX_CP_GET_VAT_GROUP2_TXC6_SHIFT(reg) GX_BITGET(reg, 9, 5) -#define GX_CP_SET_VAT_GROUP2_TXC6_SHIFT(reg, x) ((reg) = GX_BITSET(reg, 9, 5, x)) +/* start bit */ #define GX_CP_VAT_GROUP2_TXC6_SHIFT_B 9 +/* end bit */ #define GX_CP_VAT_GROUP2_TXC6_SHIFT_E 13 +/* bit size */ #define GX_CP_VAT_GROUP2_TXC6_SHIFT_SZ 5 + +/* raw mask */ #define GX_CP_VAT_GROUP2_TXC6_SHIFT_MASK (((1 << 5) - 1) << 31 - 13) +/* local mask */ #define GX_CP_VAT_GROUP2_TXC6_SHIFT_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP2_TXC6_SHIFT_SHIFT 18 + +/* get value */ #define GX_CP_GET_VAT_GROUP2_TXC6_SHIFT(reg) GX_BITGET((reg), 9, 5) +/* set value */ #define GX_CP_SET_VAT_GROUP2_TXC6_SHIFT(reg, x) ((reg) = GX_BITSET((reg), 9, 5, x)) + // TXC7_CNT [8:8] (1) -#define GX_CP_VAT_GROUP2_TXC7_CNT_ST 8 -#define GX_CP_VAT_GROUP2_TXC7_CNT_END 8 -#define GX_CP_VAT_GROUP2_TXC7_CNT_SZ 1 -#define GX_CP_VAT_GROUP2_TXC7_CNT_MASK (((1 << 1) - 1) << 31 - 8) -#define GX_CP_GET_VAT_GROUP2_TXC7_CNT(reg) GX_BITGET(reg, 8, 1) -#define GX_CP_SET_VAT_GROUP2_TXC7_CNT(reg, x) ((reg) = GX_BITSET(reg, 8, 1, x)) +/* start bit */ #define GX_CP_VAT_GROUP2_TXC7_CNT_B 8 +/* end bit */ #define GX_CP_VAT_GROUP2_TXC7_CNT_E 8 +/* bit size */ #define GX_CP_VAT_GROUP2_TXC7_CNT_SZ 1 + +/* raw mask */ #define GX_CP_VAT_GROUP2_TXC7_CNT_MASK (((1 << 1) - 1) << 31 - 8) +/* local mask */ #define GX_CP_VAT_GROUP2_TXC7_CNT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP2_TXC7_CNT_SHIFT 23 + +/* get value */ #define GX_CP_GET_VAT_GROUP2_TXC7_CNT(reg) GX_BITGET((reg), 8, 1) +/* set value */ #define GX_CP_SET_VAT_GROUP2_TXC7_CNT(reg, x) ((reg) = GX_BITSET((reg), 8, 1, x)) + // TXC7_TYPE [5:7] (3) -#define GX_CP_VAT_GROUP2_TXC7_TYPE_ST 5 -#define GX_CP_VAT_GROUP2_TXC7_TYPE_END 7 -#define GX_CP_VAT_GROUP2_TXC7_TYPE_SZ 3 -#define GX_CP_VAT_GROUP2_TXC7_TYPE_MASK (((1 << 3) - 1) << 31 - 7) -#define GX_CP_GET_VAT_GROUP2_TXC7_TYPE(reg) GX_BITGET(reg, 5, 3) -#define GX_CP_SET_VAT_GROUP2_TXC7_TYPE(reg, x) ((reg) = GX_BITSET(reg, 5, 3, x)) +/* start bit */ #define GX_CP_VAT_GROUP2_TXC7_TYPE_B 5 +/* end bit */ #define GX_CP_VAT_GROUP2_TXC7_TYPE_E 7 +/* bit size */ #define GX_CP_VAT_GROUP2_TXC7_TYPE_SZ 3 + +/* raw mask */ #define GX_CP_VAT_GROUP2_TXC7_TYPE_MASK (((1 << 3) - 1) << 31 - 7) +/* local mask */ #define GX_CP_VAT_GROUP2_TXC7_TYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP2_TXC7_TYPE_SHIFT 24 + +/* get value */ #define GX_CP_GET_VAT_GROUP2_TXC7_TYPE(reg) GX_BITGET((reg), 5, 3) +/* set value */ #define GX_CP_SET_VAT_GROUP2_TXC7_TYPE(reg, x) ((reg) = GX_BITSET((reg), 5, 3, x)) + // TXC7_SHIFT [0:4] (5) -#define GX_CP_VAT_GROUP2_TXC7_SHIFT_ST 0 -#define GX_CP_VAT_GROUP2_TXC7_SHIFT_END 4 -#define GX_CP_VAT_GROUP2_TXC7_SHIFT_SZ 5 -#define GX_CP_VAT_GROUP2_TXC7_SHIFT_MASK (((1 << 5) - 1) << 31 - 4) -#define GX_CP_GET_VAT_GROUP2_TXC7_SHIFT(reg) GX_BITGET(reg, 0, 5) -#define GX_CP_SET_VAT_GROUP2_TXC7_SHIFT(reg, x) ((reg) = GX_BITSET(reg, 0, 5, x)) +/* start bit */ #define GX_CP_VAT_GROUP2_TXC7_SHIFT_B 0 +/* end bit */ #define GX_CP_VAT_GROUP2_TXC7_SHIFT_E 4 +/* bit size */ #define GX_CP_VAT_GROUP2_TXC7_SHIFT_SZ 5 -/** +/* raw mask */ #define GX_CP_VAT_GROUP2_TXC7_SHIFT_MASK (((1 << 5) - 1) << 31 - 4) +/* local mask */ #define GX_CP_VAT_GROUP2_TXC7_SHIFT_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_CP_VAT_GROUP2_TXC7_SHIFT_SHIFT 27 + +/* get value */ #define GX_CP_GET_VAT_GROUP2_TXC7_SHIFT(reg) GX_BITGET((reg), 0, 5) +/* set value */ #define GX_CP_SET_VAT_GROUP2_TXC7_SHIFT(reg, x) ((reg) = GX_BITSET((reg), 0, 5, x)) + +/****************************************************************************** * CP register 0xA0 - ArrayBase - */ + *****************************************************************************/ // BASE [6:31] (26) -#define GX_CP_ARRAYBASE_BASE_ST 6 -#define GX_CP_ARRAYBASE_BASE_END 31 -#define GX_CP_ARRAYBASE_BASE_SZ 26 -#define GX_CP_ARRAYBASE_BASE_MASK (((1 << 26) - 1) << 31 - 31) -#define GX_CP_GET_ARRAYBASE_BASE(reg) GX_BITGET(reg, 6, 26) -#define GX_CP_SET_ARRAYBASE_BASE(reg, x) ((reg) = GX_BITSET(reg, 6, 26, x)) +/* start bit */ #define GX_CP_ARRAYBASE_BASE_B 6 +/* end bit */ #define GX_CP_ARRAYBASE_BASE_E 31 +/* bit size */ #define GX_CP_ARRAYBASE_BASE_SZ 26 -/** +/* raw mask */ #define GX_CP_ARRAYBASE_BASE_MASK (((1 << 26) - 1) << 31 - 31) +/* local mask */ #define GX_CP_ARRAYBASE_BASE_LMASK ((1 << 26) - 1) +/* bit shift */ #define GX_CP_ARRAYBASE_BASE_SHIFT 0 + +/* get value */ #define GX_CP_GET_ARRAYBASE_BASE(reg) GX_BITGET((reg), 6, 26) +/* set value */ #define GX_CP_SET_ARRAYBASE_BASE(reg, x) ((reg) = GX_BITSET((reg), 6, 26, x)) + +/****************************************************************************** * CP register 0xB0 - ArrayStride - */ + *****************************************************************************/ // STRIDE [24:31] (8) -#define GX_CP_ARRAYSTRIDE_STRIDE_ST 24 -#define GX_CP_ARRAYSTRIDE_STRIDE_END 31 -#define GX_CP_ARRAYSTRIDE_STRIDE_SZ 8 -#define GX_CP_ARRAYSTRIDE_STRIDE_MASK (((1 << 8) - 1) << 31 - 31) -#define GX_CP_GET_ARRAYSTRIDE_STRIDE(reg) GX_BITGET(reg, 24, 8) -#define GX_CP_SET_ARRAYSTRIDE_STRIDE(reg, x) ((reg) = GX_BITSET(reg, 24, 8, x)) +/* start bit */ #define GX_CP_ARRAYSTRIDE_STRIDE_B 24 +/* end bit */ #define GX_CP_ARRAYSTRIDE_STRIDE_E 31 +/* bit size */ #define GX_CP_ARRAYSTRIDE_STRIDE_SZ 8 + +/* raw mask */ #define GX_CP_ARRAYSTRIDE_STRIDE_MASK (((1 << 8) - 1) << 31 - 31) +/* local mask */ #define GX_CP_ARRAYSTRIDE_STRIDE_LMASK ((1 << 8) - 1) +/* bit shift */ #define GX_CP_ARRAYSTRIDE_STRIDE_SHIFT 0 + +/* get value */ #define GX_CP_GET_ARRAYSTRIDE_STRIDE(reg) GX_BITGET((reg), 24, 8) +/* set value */ #define GX_CP_SET_ARRAYSTRIDE_STRIDE(reg, x) ((reg) = GX_BITSET((reg), 24, 8, x)) #ifdef __cplusplus } diff --git a/include/rvl/GX/GXHardwareXF.h b/include/rvl/GX/GXHardwareXF.h index 232d6096..0719745c 100644 --- a/include/rvl/GX/GXHardwareXF.h +++ b/include/rvl/GX/GXHardwareXF.h @@ -1,7 +1,9 @@ #ifndef RVL_SDK_GX_HARDWARE_XF_H #define RVL_SDK_GX_HARDWARE_XF_H -#include "common.h" -#include "rvl/GX/GXTypes.h" +#include + +#include + #ifdef __cplusplus extern "C" { @@ -72,261 +74,413 @@ typedef enum { GX_XF_REG_DUALTEX7 = 0x1057, } GX_XF_REG; -/** +/****************************************************************************** * XF register 0x1005 - ClipDisable - */ + *****************************************************************************/ // DETECT [31:31] (1) - Disable clipping detection -#define GX_XF_CLIPDISABLE_DETECT_ST 31 -#define GX_XF_CLIPDISABLE_DETECT_END 31 -#define GX_XF_CLIPDISABLE_DETECT_SZ 1 -#define GX_XF_CLIPDISABLE_DETECT_MASK (((1 << 1) - 1) << 31 - 31) -#define GX_XF_GET_CLIPDISABLE_DETECT(reg) GX_BITGET(reg, 31, 1) -#define GX_XF_SET_CLIPDISABLE_DETECT(reg, x) ((reg) = GX_BITSET(reg, 31, 1, x)) +/* start bit */ #define GX_XF_CLIPDISABLE_DETECT_B 31 +/* end bit */ #define GX_XF_CLIPDISABLE_DETECT_E 31 +/* bit size */ #define GX_XF_CLIPDISABLE_DETECT_SZ 1 + +/* raw mask */ #define GX_XF_CLIPDISABLE_DETECT_MASK (((1 << 1) - 1) << 31 - 31) +/* local mask */ #define GX_XF_CLIPDISABLE_DETECT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_XF_CLIPDISABLE_DETECT_SHIFT 0 + +/* get value */ #define GX_XF_GET_CLIPDISABLE_DETECT(reg) GX_BITGET((reg), 31, 1) +/* set value */ #define GX_XF_SET_CLIPDISABLE_DETECT(reg, x) ((reg) = GX_BITSET((reg), 31, 1, x)) + // REJECT [30:30] (1) - Disable trivial rejection -#define GX_XF_CLIPDISABLE_REJECT_ST 30 -#define GX_XF_CLIPDISABLE_REJECT_END 30 -#define GX_XF_CLIPDISABLE_REJECT_SZ 1 -#define GX_XF_CLIPDISABLE_REJECT_MASK (((1 << 1) - 1) << 31 - 30) -#define GX_XF_GET_CLIPDISABLE_REJECT(reg) GX_BITGET(reg, 30, 1) -#define GX_XF_SET_CLIPDISABLE_REJECT(reg, x) ((reg) = GX_BITSET(reg, 30, 1, x)) +/* start bit */ #define GX_XF_CLIPDISABLE_REJECT_B 30 +/* end bit */ #define GX_XF_CLIPDISABLE_REJECT_E 30 +/* bit size */ #define GX_XF_CLIPDISABLE_REJECT_SZ 1 + +/* raw mask */ #define GX_XF_CLIPDISABLE_REJECT_MASK (((1 << 1) - 1) << 31 - 30) +/* local mask */ #define GX_XF_CLIPDISABLE_REJECT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_XF_CLIPDISABLE_REJECT_SHIFT 1 + +/* get value */ #define GX_XF_GET_CLIPDISABLE_REJECT(reg) GX_BITGET((reg), 30, 1) +/* set value */ #define GX_XF_SET_CLIPDISABLE_REJECT(reg, x) ((reg) = GX_BITSET((reg), 30, 1, x)) + // ACCEL [29:29] (1) - Disable cpoly clipping acceleration -#define GX_XF_CLIPDISABLE_ACCEL_ST 29 -#define GX_XF_CLIPDISABLE_ACCEL_END 29 -#define GX_XF_CLIPDISABLE_ACCEL_SZ 1 -#define GX_XF_CLIPDISABLE_ACCEL_MASK (((1 << 1) - 1) << 31 - 29) -#define GX_XF_GET_CLIPDISABLE_ACCEL(reg) GX_BITGET(reg, 29, 1) -#define GX_XF_SET_CLIPDISABLE_ACCEL(reg, x) ((reg) = GX_BITSET(reg, 29, 1, x)) +/* start bit */ #define GX_XF_CLIPDISABLE_ACCEL_B 29 +/* end bit */ #define GX_XF_CLIPDISABLE_ACCEL_E 29 +/* bit size */ #define GX_XF_CLIPDISABLE_ACCEL_SZ 1 -/** +/* raw mask */ #define GX_XF_CLIPDISABLE_ACCEL_MASK (((1 << 1) - 1) << 31 - 29) +/* local mask */ #define GX_XF_CLIPDISABLE_ACCEL_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_XF_CLIPDISABLE_ACCEL_SHIFT 2 + +/* get value */ #define GX_XF_GET_CLIPDISABLE_ACCEL(reg) GX_BITGET((reg), 29, 1) +/* set value */ #define GX_XF_SET_CLIPDISABLE_ACCEL(reg, x) ((reg) = GX_BITSET((reg), 29, 1, x)) + +/****************************************************************************** * XF register 0x1007 - Perf1 - */ + *****************************************************************************/ // TARGET [25:31] (7) - Target performance (Cycles/vertex) -#define GX_XF_PERF1_TARGET_ST 25 -#define GX_XF_PERF1_TARGET_END 31 -#define GX_XF_PERF1_TARGET_SZ 7 -#define GX_XF_PERF1_TARGET_MASK (((1 << 7) - 1) << 31 - 31) -#define GX_XF_GET_PERF1_TARGET(reg) GX_BITGET(reg, 25, 7) -#define GX_XF_SET_PERF1_TARGET(reg, x) ((reg) = GX_BITSET(reg, 25, 7, x)) +/* start bit */ #define GX_XF_PERF1_TARGET_B 25 +/* end bit */ #define GX_XF_PERF1_TARGET_E 31 +/* bit size */ #define GX_XF_PERF1_TARGET_SZ 7 -/** +/* raw mask */ #define GX_XF_PERF1_TARGET_MASK (((1 << 7) - 1) << 31 - 31) +/* local mask */ #define GX_XF_PERF1_TARGET_LMASK ((1 << 7) - 1) +/* bit shift */ #define GX_XF_PERF1_TARGET_SHIFT 0 + +/* get value */ #define GX_XF_GET_PERF1_TARGET(reg) GX_BITGET((reg), 25, 7) +/* set value */ #define GX_XF_SET_PERF1_TARGET(reg, x) ((reg) = GX_BITSET((reg), 25, 7, x)) + +/****************************************************************************** * XF register 0x1008 - InVertexSpec - */ + *****************************************************************************/ // CLR [30:31] (2) -#define GX_XF_INVERTEXSPEC_CLR_ST 30 -#define GX_XF_INVERTEXSPEC_CLR_END 31 -#define GX_XF_INVERTEXSPEC_CLR_SZ 2 -#define GX_XF_INVERTEXSPEC_CLR_MASK (((1 << 2) - 1) << 31 - 31) -#define GX_XF_GET_INVERTEXSPEC_CLR(reg) GX_BITGET(reg, 30, 2) -#define GX_XF_SET_INVERTEXSPEC_CLR(reg, x) ((reg) = GX_BITSET(reg, 30, 2, x)) +/* start bit */ #define GX_XF_INVERTEXSPEC_CLR_B 30 +/* end bit */ #define GX_XF_INVERTEXSPEC_CLR_E 31 +/* bit size */ #define GX_XF_INVERTEXSPEC_CLR_SZ 2 + +/* raw mask */ #define GX_XF_INVERTEXSPEC_CLR_MASK (((1 << 2) - 1) << 31 - 31) +/* local mask */ #define GX_XF_INVERTEXSPEC_CLR_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_XF_INVERTEXSPEC_CLR_SHIFT 0 + +/* get value */ #define GX_XF_GET_INVERTEXSPEC_CLR(reg) GX_BITGET((reg), 30, 2) +/* set value */ #define GX_XF_SET_INVERTEXSPEC_CLR(reg, x) ((reg) = GX_BITSET((reg), 30, 2, x)) + // NRM [28:29] (2) -#define GX_XF_INVERTEXSPEC_NRM_ST 28 -#define GX_XF_INVERTEXSPEC_NRM_END 29 -#define GX_XF_INVERTEXSPEC_NRM_SZ 2 -#define GX_XF_INVERTEXSPEC_NRM_MASK (((1 << 2) - 1) << 31 - 29) -#define GX_XF_GET_INVERTEXSPEC_NRM(reg) GX_BITGET(reg, 28, 2) -#define GX_XF_SET_INVERTEXSPEC_NRM(reg, x) ((reg) = GX_BITSET(reg, 28, 2, x)) +/* start bit */ #define GX_XF_INVERTEXSPEC_NRM_B 28 +/* end bit */ #define GX_XF_INVERTEXSPEC_NRM_E 29 +/* bit size */ #define GX_XF_INVERTEXSPEC_NRM_SZ 2 + +/* raw mask */ #define GX_XF_INVERTEXSPEC_NRM_MASK (((1 << 2) - 1) << 31 - 29) +/* local mask */ #define GX_XF_INVERTEXSPEC_NRM_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_XF_INVERTEXSPEC_NRM_SHIFT 2 + +/* get value */ #define GX_XF_GET_INVERTEXSPEC_NRM(reg) GX_BITGET((reg), 28, 2) +/* set value */ #define GX_XF_SET_INVERTEXSPEC_NRM(reg, x) ((reg) = GX_BITSET((reg), 28, 2, x)) + // TXC [24:27] (4) -#define GX_XF_INVERTEXSPEC_TXC_ST 24 -#define GX_XF_INVERTEXSPEC_TXC_END 27 -#define GX_XF_INVERTEXSPEC_TXC_SZ 4 -#define GX_XF_INVERTEXSPEC_TXC_MASK (((1 << 4) - 1) << 31 - 27) -#define GX_XF_GET_INVERTEXSPEC_TXC(reg) GX_BITGET(reg, 24, 4) -#define GX_XF_SET_INVERTEXSPEC_TXC(reg, x) ((reg) = GX_BITSET(reg, 24, 4, x)) +/* start bit */ #define GX_XF_INVERTEXSPEC_TXC_B 24 +/* end bit */ #define GX_XF_INVERTEXSPEC_TXC_E 27 +/* bit size */ #define GX_XF_INVERTEXSPEC_TXC_SZ 4 -/** +/* raw mask */ #define GX_XF_INVERTEXSPEC_TXC_MASK (((1 << 4) - 1) << 31 - 27) +/* local mask */ #define GX_XF_INVERTEXSPEC_TXC_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_XF_INVERTEXSPEC_TXC_SHIFT 4 + +/* get value */ #define GX_XF_GET_INVERTEXSPEC_TXC(reg) GX_BITGET((reg), 24, 4) +/* set value */ #define GX_XF_SET_INVERTEXSPEC_TXC(reg, x) ((reg) = GX_BITSET((reg), 24, 4, x)) + +/****************************************************************************** * XF register 0x100E - Color0Cntrl - */ + *****************************************************************************/ // MATSRC [31:31] (1) -#define GX_XF_COLOR0CNTRL_MATSRC_ST 31 -#define GX_XF_COLOR0CNTRL_MATSRC_END 31 -#define GX_XF_COLOR0CNTRL_MATSRC_SZ 1 -#define GX_XF_COLOR0CNTRL_MATSRC_MASK (((1 << 1) - 1) << 31 - 31) -#define GX_XF_GET_COLOR0CNTRL_MATSRC(reg) GX_BITGET(reg, 31, 1) -#define GX_XF_SET_COLOR0CNTRL_MATSRC(reg, x) ((reg) = GX_BITSET(reg, 31, 1, x)) +/* start bit */ #define GX_XF_COLOR0CNTRL_MATSRC_B 31 +/* end bit */ #define GX_XF_COLOR0CNTRL_MATSRC_E 31 +/* bit size */ #define GX_XF_COLOR0CNTRL_MATSRC_SZ 1 + +/* raw mask */ #define GX_XF_COLOR0CNTRL_MATSRC_MASK (((1 << 1) - 1) << 31 - 31) +/* local mask */ #define GX_XF_COLOR0CNTRL_MATSRC_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_XF_COLOR0CNTRL_MATSRC_SHIFT 0 + +/* get value */ #define GX_XF_GET_COLOR0CNTRL_MATSRC(reg) GX_BITGET((reg), 31, 1) +/* set value */ #define GX_XF_SET_COLOR0CNTRL_MATSRC(reg, x) ((reg) = GX_BITSET((reg), 31, 1, x)) + // LIGHT [30:30] (1) -#define GX_XF_COLOR0CNTRL_LIGHT_ST 30 -#define GX_XF_COLOR0CNTRL_LIGHT_END 30 -#define GX_XF_COLOR0CNTRL_LIGHT_SZ 1 -#define GX_XF_COLOR0CNTRL_LIGHT_MASK (((1 << 1) - 1) << 31 - 30) -#define GX_XF_GET_COLOR0CNTRL_LIGHT(reg) GX_BITGET(reg, 30, 1) -#define GX_XF_SET_COLOR0CNTRL_LIGHT(reg, x) ((reg) = GX_BITSET(reg, 30, 1, x)) -// LMASKHI [26:29] (4) -#define GX_XF_COLOR0CNTRL_LMASKHI_ST 26 -#define GX_XF_COLOR0CNTRL_LMASKHI_END 29 -#define GX_XF_COLOR0CNTRL_LMASKHI_SZ 4 -#define GX_XF_COLOR0CNTRL_LMASKHI_MASK (((1 << 4) - 1) << 31 - 29) -#define GX_XF_GET_COLOR0CNTRL_LMASKHI(reg) GX_BITGET(reg, 26, 4) -#define GX_XF_SET_COLOR0CNTRL_LMASKHI(reg, x) ((reg) = GX_BITSET(reg, 26, 4, x)) +/* start bit */ #define GX_XF_COLOR0CNTRL_LIGHT_B 30 +/* end bit */ #define GX_XF_COLOR0CNTRL_LIGHT_E 30 +/* bit size */ #define GX_XF_COLOR0CNTRL_LIGHT_SZ 1 + +/* raw mask */ #define GX_XF_COLOR0CNTRL_LIGHT_MASK (((1 << 1) - 1) << 31 - 30) +/* local mask */ #define GX_XF_COLOR0CNTRL_LIGHT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_XF_COLOR0CNTRL_LIGHT_SHIFT 1 + +/* get value */ #define GX_XF_GET_COLOR0CNTRL_LIGHT(reg) GX_BITGET((reg), 30, 1) +/* set value */ #define GX_XF_SET_COLOR0CNTRL_LIGHT(reg, x) ((reg) = GX_BITSET((reg), 30, 1, x)) + +// LMASKLO [26:29] (4) +/* start bit */ #define GX_XF_COLOR0CNTRL_LMASKLO_B 26 +/* end bit */ #define GX_XF_COLOR0CNTRL_LMASKLO_E 29 +/* bit size */ #define GX_XF_COLOR0CNTRL_LMASKLO_SZ 4 + +/* raw mask */ #define GX_XF_COLOR0CNTRL_LMASKLO_MASK (((1 << 4) - 1) << 31 - 29) +/* local mask */ #define GX_XF_COLOR0CNTRL_LMASKLO_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_XF_COLOR0CNTRL_LMASKLO_SHIFT 2 + +/* get value */ #define GX_XF_GET_COLOR0CNTRL_LMASKLO(reg) GX_BITGET((reg), 26, 4) +/* set value */ #define GX_XF_SET_COLOR0CNTRL_LMASKLO(reg, x) ((reg) = GX_BITSET((reg), 26, 4, x)) + // AMBSRC [25:25] (1) -#define GX_XF_COLOR0CNTRL_AMBSRC_ST 25 -#define GX_XF_COLOR0CNTRL_AMBSRC_END 25 -#define GX_XF_COLOR0CNTRL_AMBSRC_SZ 1 -#define GX_XF_COLOR0CNTRL_AMBSRC_MASK (((1 << 1) - 1) << 31 - 25) -#define GX_XF_GET_COLOR0CNTRL_AMBSRC(reg) GX_BITGET(reg, 25, 1) -#define GX_XF_SET_COLOR0CNTRL_AMBSRC(reg, x) ((reg) = GX_BITSET(reg, 25, 1, x)) +/* start bit */ #define GX_XF_COLOR0CNTRL_AMBSRC_B 25 +/* end bit */ #define GX_XF_COLOR0CNTRL_AMBSRC_E 25 +/* bit size */ #define GX_XF_COLOR0CNTRL_AMBSRC_SZ 1 + +/* raw mask */ #define GX_XF_COLOR0CNTRL_AMBSRC_MASK (((1 << 1) - 1) << 31 - 25) +/* local mask */ #define GX_XF_COLOR0CNTRL_AMBSRC_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_XF_COLOR0CNTRL_AMBSRC_SHIFT 6 + +/* get value */ #define GX_XF_GET_COLOR0CNTRL_AMBSRC(reg) GX_BITGET((reg), 25, 1) +/* set value */ #define GX_XF_SET_COLOR0CNTRL_AMBSRC(reg, x) ((reg) = GX_BITSET((reg), 25, 1, x)) + // DIFFUSEATTN [23:24] (2) -#define GX_XF_COLOR0CNTRL_DIFFUSEATTN_ST 23 -#define GX_XF_COLOR0CNTRL_DIFFUSEATTN_END 24 -#define GX_XF_COLOR0CNTRL_DIFFUSEATTN_SZ 2 -#define GX_XF_COLOR0CNTRL_DIFFUSEATTN_MASK (((1 << 2) - 1) << 31 - 24) -#define GX_XF_GET_COLOR0CNTRL_DIFFUSEATTN(reg) GX_BITGET(reg, 23, 2) -#define GX_XF_SET_COLOR0CNTRL_DIFFUSEATTN(reg, x) ((reg) = GX_BITSET(reg, 23, 2, x)) +/* start bit */ #define GX_XF_COLOR0CNTRL_DIFFUSEATTN_B 23 +/* end bit */ #define GX_XF_COLOR0CNTRL_DIFFUSEATTN_E 24 +/* bit size */ #define GX_XF_COLOR0CNTRL_DIFFUSEATTN_SZ 2 + +/* raw mask */ #define GX_XF_COLOR0CNTRL_DIFFUSEATTN_MASK (((1 << 2) - 1) << 31 - 24) +/* local mask */ #define GX_XF_COLOR0CNTRL_DIFFUSEATTN_LMASK ((1 << 2) - 1) +/* bit shift */ #define GX_XF_COLOR0CNTRL_DIFFUSEATTN_SHIFT 7 + +/* get value */ #define GX_XF_GET_COLOR0CNTRL_DIFFUSEATTN(reg) GX_BITGET((reg), 23, 2) +/* set value */ #define GX_XF_SET_COLOR0CNTRL_DIFFUSEATTN(reg, x) ((reg) = GX_BITSET((reg), 23, 2, x)) + // ATTNENABLE [22:22] (1) -#define GX_XF_COLOR0CNTRL_ATTNENABLE_ST 22 -#define GX_XF_COLOR0CNTRL_ATTNENABLE_END 22 -#define GX_XF_COLOR0CNTRL_ATTNENABLE_SZ 1 -#define GX_XF_COLOR0CNTRL_ATTNENABLE_MASK (((1 << 1) - 1) << 31 - 22) -#define GX_XF_GET_COLOR0CNTRL_ATTNENABLE(reg) GX_BITGET(reg, 22, 1) -#define GX_XF_SET_COLOR0CNTRL_ATTNENABLE(reg, x) ((reg) = GX_BITSET(reg, 22, 1, x)) +/* start bit */ #define GX_XF_COLOR0CNTRL_ATTNENABLE_B 22 +/* end bit */ #define GX_XF_COLOR0CNTRL_ATTNENABLE_E 22 +/* bit size */ #define GX_XF_COLOR0CNTRL_ATTNENABLE_SZ 1 + +/* raw mask */ #define GX_XF_COLOR0CNTRL_ATTNENABLE_MASK (((1 << 1) - 1) << 31 - 22) +/* local mask */ #define GX_XF_COLOR0CNTRL_ATTNENABLE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_XF_COLOR0CNTRL_ATTNENABLE_SHIFT 9 + +/* get value */ #define GX_XF_GET_COLOR0CNTRL_ATTNENABLE(reg) GX_BITGET((reg), 22, 1) +/* set value */ #define GX_XF_SET_COLOR0CNTRL_ATTNENABLE(reg, x) ((reg) = GX_BITSET((reg), 22, 1, x)) + // ATTNSELECT [21:21] (1) -#define GX_XF_COLOR0CNTRL_ATTNSELECT_ST 21 -#define GX_XF_COLOR0CNTRL_ATTNSELECT_END 21 -#define GX_XF_COLOR0CNTRL_ATTNSELECT_SZ 1 -#define GX_XF_COLOR0CNTRL_ATTNSELECT_MASK (((1 << 1) - 1) << 31 - 21) -#define GX_XF_GET_COLOR0CNTRL_ATTNSELECT(reg) GX_BITGET(reg, 21, 1) -#define GX_XF_SET_COLOR0CNTRL_ATTNSELECT(reg, x) ((reg) = GX_BITSET(reg, 21, 1, x)) -// LMASKLO [17:20] (4) -#define GX_XF_COLOR0CNTRL_LMASKLO_ST 17 -#define GX_XF_COLOR0CNTRL_LMASKLO_END 20 -#define GX_XF_COLOR0CNTRL_LMASKLO_SZ 4 -#define GX_XF_COLOR0CNTRL_LMASKLO_MASK (((1 << 4) - 1) << 31 - 20) -#define GX_XF_GET_COLOR0CNTRL_LMASKLO(reg) GX_BITGET(reg, 17, 4) -#define GX_XF_SET_COLOR0CNTRL_LMASKLO(reg, x) ((reg) = GX_BITSET(reg, 17, 4, x)) +/* start bit */ #define GX_XF_COLOR0CNTRL_ATTNSELECT_B 21 +/* end bit */ #define GX_XF_COLOR0CNTRL_ATTNSELECT_E 21 +/* bit size */ #define GX_XF_COLOR0CNTRL_ATTNSELECT_SZ 1 -/** +/* raw mask */ #define GX_XF_COLOR0CNTRL_ATTNSELECT_MASK (((1 << 1) - 1) << 31 - 21) +/* local mask */ #define GX_XF_COLOR0CNTRL_ATTNSELECT_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_XF_COLOR0CNTRL_ATTNSELECT_SHIFT 10 + +/* get value */ #define GX_XF_GET_COLOR0CNTRL_ATTNSELECT(reg) GX_BITGET((reg), 21, 1) +/* set value */ #define GX_XF_SET_COLOR0CNTRL_ATTNSELECT(reg, x) ((reg) = GX_BITSET((reg), 21, 1, x)) + +// LMASKHI [17:20] (4) +/* start bit */ #define GX_XF_COLOR0CNTRL_LMASKHI_B 17 +/* end bit */ #define GX_XF_COLOR0CNTRL_LMASKHI_E 20 +/* bit size */ #define GX_XF_COLOR0CNTRL_LMASKHI_SZ 4 + +/* raw mask */ #define GX_XF_COLOR0CNTRL_LMASKHI_MASK (((1 << 4) - 1) << 31 - 20) +/* local mask */ #define GX_XF_COLOR0CNTRL_LMASKHI_LMASK ((1 << 4) - 1) +/* bit shift */ #define GX_XF_COLOR0CNTRL_LMASKHI_SHIFT 11 + +/* get value */ #define GX_XF_GET_COLOR0CNTRL_LMASKHI(reg) GX_BITGET((reg), 17, 4) +/* set value */ #define GX_XF_SET_COLOR0CNTRL_LMASKHI(reg, x) ((reg) = GX_BITSET((reg), 17, 4, x)) + +/****************************************************************************** * XF register 0x1018 - MatrixIndex0 - */ + *****************************************************************************/ // GEOM [26:31] (6) -#define GX_XF_MATRIXINDEX0_GEOM_ST 26 -#define GX_XF_MATRIXINDEX0_GEOM_END 31 -#define GX_XF_MATRIXINDEX0_GEOM_SZ 6 -#define GX_XF_MATRIXINDEX0_GEOM_MASK (((1 << 6) - 1) << 31 - 31) -#define GX_XF_GET_MATRIXINDEX0_GEOM(reg) GX_BITGET(reg, 26, 6) -#define GX_XF_SET_MATRIXINDEX0_GEOM(reg, x) ((reg) = GX_BITSET(reg, 26, 6, x)) +/* start bit */ #define GX_XF_MATRIXINDEX0_GEOM_B 26 +/* end bit */ #define GX_XF_MATRIXINDEX0_GEOM_E 31 +/* bit size */ #define GX_XF_MATRIXINDEX0_GEOM_SZ 6 + +/* raw mask */ #define GX_XF_MATRIXINDEX0_GEOM_MASK (((1 << 6) - 1) << 31 - 31) +/* local mask */ #define GX_XF_MATRIXINDEX0_GEOM_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_XF_MATRIXINDEX0_GEOM_SHIFT 0 + +/* get value */ #define GX_XF_GET_MATRIXINDEX0_GEOM(reg) GX_BITGET((reg), 26, 6) +/* set value */ #define GX_XF_SET_MATRIXINDEX0_GEOM(reg, x) ((reg) = GX_BITSET((reg), 26, 6, x)) + // TEX0 [20:25] (6) -#define GX_XF_MATRIXINDEX0_TEX0_ST 20 -#define GX_XF_MATRIXINDEX0_TEX0_END 25 -#define GX_XF_MATRIXINDEX0_TEX0_SZ 6 -#define GX_XF_MATRIXINDEX0_TEX0_MASK (((1 << 6) - 1) << 31 - 25) -#define GX_XF_GET_MATRIXINDEX0_TEX0(reg) GX_BITGET(reg, 20, 6) -#define GX_XF_SET_MATRIXINDEX0_TEX0(reg, x) ((reg) = GX_BITSET(reg, 20, 6, x)) +/* start bit */ #define GX_XF_MATRIXINDEX0_TEX0_B 20 +/* end bit */ #define GX_XF_MATRIXINDEX0_TEX0_E 25 +/* bit size */ #define GX_XF_MATRIXINDEX0_TEX0_SZ 6 + +/* raw mask */ #define GX_XF_MATRIXINDEX0_TEX0_MASK (((1 << 6) - 1) << 31 - 25) +/* local mask */ #define GX_XF_MATRIXINDEX0_TEX0_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_XF_MATRIXINDEX0_TEX0_SHIFT 6 + +/* get value */ #define GX_XF_GET_MATRIXINDEX0_TEX0(reg) GX_BITGET((reg), 20, 6) +/* set value */ #define GX_XF_SET_MATRIXINDEX0_TEX0(reg, x) ((reg) = GX_BITSET((reg), 20, 6, x)) + // TEX1 [14:19] (6) -#define GX_XF_MATRIXINDEX0_TEX1_ST 14 -#define GX_XF_MATRIXINDEX0_TEX1_END 19 -#define GX_XF_MATRIXINDEX0_TEX1_SZ 6 -#define GX_XF_MATRIXINDEX0_TEX1_MASK (((1 << 6) - 1) << 31 - 19) -#define GX_XF_GET_MATRIXINDEX0_TEX1(reg) GX_BITGET(reg, 14, 6) -#define GX_XF_SET_MATRIXINDEX0_TEX1(reg, x) ((reg) = GX_BITSET(reg, 14, 6, x)) +/* start bit */ #define GX_XF_MATRIXINDEX0_TEX1_B 14 +/* end bit */ #define GX_XF_MATRIXINDEX0_TEX1_E 19 +/* bit size */ #define GX_XF_MATRIXINDEX0_TEX1_SZ 6 + +/* raw mask */ #define GX_XF_MATRIXINDEX0_TEX1_MASK (((1 << 6) - 1) << 31 - 19) +/* local mask */ #define GX_XF_MATRIXINDEX0_TEX1_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_XF_MATRIXINDEX0_TEX1_SHIFT 12 + +/* get value */ #define GX_XF_GET_MATRIXINDEX0_TEX1(reg) GX_BITGET((reg), 14, 6) +/* set value */ #define GX_XF_SET_MATRIXINDEX0_TEX1(reg, x) ((reg) = GX_BITSET((reg), 14, 6, x)) + // TEX2 [8:13] (6) -#define GX_XF_MATRIXINDEX0_TEX2_ST 8 -#define GX_XF_MATRIXINDEX0_TEX2_END 13 -#define GX_XF_MATRIXINDEX0_TEX2_SZ 6 -#define GX_XF_MATRIXINDEX0_TEX2_MASK (((1 << 6) - 1) << 31 - 13) -#define GX_XF_GET_MATRIXINDEX0_TEX2(reg) GX_BITGET(reg, 8, 6) -#define GX_XF_SET_MATRIXINDEX0_TEX2(reg, x) ((reg) = GX_BITSET(reg, 8, 6, x)) +/* start bit */ #define GX_XF_MATRIXINDEX0_TEX2_B 8 +/* end bit */ #define GX_XF_MATRIXINDEX0_TEX2_E 13 +/* bit size */ #define GX_XF_MATRIXINDEX0_TEX2_SZ 6 + +/* raw mask */ #define GX_XF_MATRIXINDEX0_TEX2_MASK (((1 << 6) - 1) << 31 - 13) +/* local mask */ #define GX_XF_MATRIXINDEX0_TEX2_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_XF_MATRIXINDEX0_TEX2_SHIFT 18 + +/* get value */ #define GX_XF_GET_MATRIXINDEX0_TEX2(reg) GX_BITGET((reg), 8, 6) +/* set value */ #define GX_XF_SET_MATRIXINDEX0_TEX2(reg, x) ((reg) = GX_BITSET((reg), 8, 6, x)) + // TEX3 [2:7] (6) -#define GX_XF_MATRIXINDEX0_TEX3_ST 2 -#define GX_XF_MATRIXINDEX0_TEX3_END 7 -#define GX_XF_MATRIXINDEX0_TEX3_SZ 6 -#define GX_XF_MATRIXINDEX0_TEX3_MASK (((1 << 6) - 1) << 31 - 7) -#define GX_XF_GET_MATRIXINDEX0_TEX3(reg) GX_BITGET(reg, 2, 6) -#define GX_XF_SET_MATRIXINDEX0_TEX3(reg, x) ((reg) = GX_BITSET(reg, 2, 6, x)) +/* start bit */ #define GX_XF_MATRIXINDEX0_TEX3_B 2 +/* end bit */ #define GX_XF_MATRIXINDEX0_TEX3_E 7 +/* bit size */ #define GX_XF_MATRIXINDEX0_TEX3_SZ 6 -/** +/* raw mask */ #define GX_XF_MATRIXINDEX0_TEX3_MASK (((1 << 6) - 1) << 31 - 7) +/* local mask */ #define GX_XF_MATRIXINDEX0_TEX3_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_XF_MATRIXINDEX0_TEX3_SHIFT 24 + +/* get value */ #define GX_XF_GET_MATRIXINDEX0_TEX3(reg) GX_BITGET((reg), 2, 6) +/* set value */ #define GX_XF_SET_MATRIXINDEX0_TEX3(reg, x) ((reg) = GX_BITSET((reg), 2, 6, x)) + +/****************************************************************************** * XF register 0x1019 - MatrixIndex1 - */ + *****************************************************************************/ // TEX4 [26:31] (6) -#define GX_XF_MATRIXINDEX1_TEX4_ST 26 -#define GX_XF_MATRIXINDEX1_TEX4_END 31 -#define GX_XF_MATRIXINDEX1_TEX4_SZ 6 -#define GX_XF_MATRIXINDEX1_TEX4_MASK (((1 << 6) - 1) << 31 - 31) -#define GX_XF_GET_MATRIXINDEX1_TEX4(reg) GX_BITGET(reg, 26, 6) -#define GX_XF_SET_MATRIXINDEX1_TEX4(reg, x) ((reg) = GX_BITSET(reg, 26, 6, x)) +/* start bit */ #define GX_XF_MATRIXINDEX1_TEX4_B 26 +/* end bit */ #define GX_XF_MATRIXINDEX1_TEX4_E 31 +/* bit size */ #define GX_XF_MATRIXINDEX1_TEX4_SZ 6 + +/* raw mask */ #define GX_XF_MATRIXINDEX1_TEX4_MASK (((1 << 6) - 1) << 31 - 31) +/* local mask */ #define GX_XF_MATRIXINDEX1_TEX4_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_XF_MATRIXINDEX1_TEX4_SHIFT 0 + +/* get value */ #define GX_XF_GET_MATRIXINDEX1_TEX4(reg) GX_BITGET((reg), 26, 6) +/* set value */ #define GX_XF_SET_MATRIXINDEX1_TEX4(reg, x) ((reg) = GX_BITSET((reg), 26, 6, x)) + // TEX5 [20:25] (6) -#define GX_XF_MATRIXINDEX1_TEX5_ST 20 -#define GX_XF_MATRIXINDEX1_TEX5_END 25 -#define GX_XF_MATRIXINDEX1_TEX5_SZ 6 -#define GX_XF_MATRIXINDEX1_TEX5_MASK (((1 << 6) - 1) << 31 - 25) -#define GX_XF_GET_MATRIXINDEX1_TEX5(reg) GX_BITGET(reg, 20, 6) -#define GX_XF_SET_MATRIXINDEX1_TEX5(reg, x) ((reg) = GX_BITSET(reg, 20, 6, x)) +/* start bit */ #define GX_XF_MATRIXINDEX1_TEX5_B 20 +/* end bit */ #define GX_XF_MATRIXINDEX1_TEX5_E 25 +/* bit size */ #define GX_XF_MATRIXINDEX1_TEX5_SZ 6 + +/* raw mask */ #define GX_XF_MATRIXINDEX1_TEX5_MASK (((1 << 6) - 1) << 31 - 25) +/* local mask */ #define GX_XF_MATRIXINDEX1_TEX5_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_XF_MATRIXINDEX1_TEX5_SHIFT 6 + +/* get value */ #define GX_XF_GET_MATRIXINDEX1_TEX5(reg) GX_BITGET((reg), 20, 6) +/* set value */ #define GX_XF_SET_MATRIXINDEX1_TEX5(reg, x) ((reg) = GX_BITSET((reg), 20, 6, x)) + // TEX6 [14:19] (6) -#define GX_XF_MATRIXINDEX1_TEX6_ST 14 -#define GX_XF_MATRIXINDEX1_TEX6_END 19 -#define GX_XF_MATRIXINDEX1_TEX6_SZ 6 -#define GX_XF_MATRIXINDEX1_TEX6_MASK (((1 << 6) - 1) << 31 - 19) -#define GX_XF_GET_MATRIXINDEX1_TEX6(reg) GX_BITGET(reg, 14, 6) -#define GX_XF_SET_MATRIXINDEX1_TEX6(reg, x) ((reg) = GX_BITSET(reg, 14, 6, x)) +/* start bit */ #define GX_XF_MATRIXINDEX1_TEX6_B 14 +/* end bit */ #define GX_XF_MATRIXINDEX1_TEX6_E 19 +/* bit size */ #define GX_XF_MATRIXINDEX1_TEX6_SZ 6 + +/* raw mask */ #define GX_XF_MATRIXINDEX1_TEX6_MASK (((1 << 6) - 1) << 31 - 19) +/* local mask */ #define GX_XF_MATRIXINDEX1_TEX6_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_XF_MATRIXINDEX1_TEX6_SHIFT 12 + +/* get value */ #define GX_XF_GET_MATRIXINDEX1_TEX6(reg) GX_BITGET((reg), 14, 6) +/* set value */ #define GX_XF_SET_MATRIXINDEX1_TEX6(reg, x) ((reg) = GX_BITSET((reg), 14, 6, x)) + // TEX7 [8:13] (6) -#define GX_XF_MATRIXINDEX1_TEX7_ST 8 -#define GX_XF_MATRIXINDEX1_TEX7_END 13 -#define GX_XF_MATRIXINDEX1_TEX7_SZ 6 -#define GX_XF_MATRIXINDEX1_TEX7_MASK (((1 << 6) - 1) << 31 - 13) -#define GX_XF_GET_MATRIXINDEX1_TEX7(reg) GX_BITGET(reg, 8, 6) -#define GX_XF_SET_MATRIXINDEX1_TEX7(reg, x) ((reg) = GX_BITSET(reg, 8, 6, x)) +/* start bit */ #define GX_XF_MATRIXINDEX1_TEX7_B 8 +/* end bit */ #define GX_XF_MATRIXINDEX1_TEX7_E 13 +/* bit size */ #define GX_XF_MATRIXINDEX1_TEX7_SZ 6 -/** +/* raw mask */ #define GX_XF_MATRIXINDEX1_TEX7_MASK (((1 << 6) - 1) << 31 - 13) +/* local mask */ #define GX_XF_MATRIXINDEX1_TEX7_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_XF_MATRIXINDEX1_TEX7_SHIFT 18 + +/* get value */ #define GX_XF_GET_MATRIXINDEX1_TEX7(reg) GX_BITGET((reg), 8, 6) +/* set value */ #define GX_XF_SET_MATRIXINDEX1_TEX7(reg, x) ((reg) = GX_BITSET((reg), 8, 6, x)) + +/****************************************************************************** * XF structure - Tex - */ + *****************************************************************************/ // PROJTYPE [30:30] (1) -#define GX_XF_TEX_PROJTYPE_ST 30 -#define GX_XF_TEX_PROJTYPE_END 30 -#define GX_XF_TEX_PROJTYPE_SZ 1 -#define GX_XF_TEX_PROJTYPE_MASK (((1 << 1) - 1) << 31 - 30) -#define GX_XF_GET_TEX_PROJTYPE(reg) GX_BITGET(reg, 30, 1) -#define GX_XF_SET_TEX_PROJTYPE(reg, x) ((reg) = GX_BITSET(reg, 30, 1, x)) -// INPUTFORM [29:29] (1) -#define GX_XF_TEX_INPUTFORM_ST 29 -#define GX_XF_TEX_INPUTFORM_END 29 -#define GX_XF_TEX_INPUTFORM_SZ 1 -#define GX_XF_TEX_INPUTFORM_MASK (((1 << 1) - 1) << 31 - 29) -#define GX_XF_GET_TEX_INPUTFORM(reg) GX_BITGET(reg, 29, 1) -#define GX_XF_SET_TEX_INPUTFORM(reg, x) ((reg) = GX_BITSET(reg, 29, 1, x)) -// TEXGENTYPE [25:27] (3) -#define GX_XF_TEX_TEXGENTYPE_ST 25 -#define GX_XF_TEX_TEXGENTYPE_END 27 -#define GX_XF_TEX_TEXGENTYPE_SZ 3 -#define GX_XF_TEX_TEXGENTYPE_MASK (((1 << 3) - 1) << 31 - 27) -#define GX_XF_GET_TEX_TEXGENTYPE(reg) GX_BITGET(reg, 25, 3) -#define GX_XF_SET_TEX_TEXGENTYPE(reg, x) ((reg) = GX_BITSET(reg, 25, 3, x)) -// SRCROW [20:24] (5) -#define GX_XF_TEX_SRCROW_ST 20 -#define GX_XF_TEX_SRCROW_END 24 -#define GX_XF_TEX_SRCROW_SZ 5 -#define GX_XF_TEX_SRCROW_MASK (((1 << 5) - 1) << 31 - 24) -#define GX_XF_GET_TEX_SRCROW(reg) GX_BITGET(reg, 20, 5) -#define GX_XF_SET_TEX_SRCROW(reg, x) ((reg) = GX_BITSET(reg, 20, 5, x)) -// BUMPSRCTEX [17:19] (3) -#define GX_XF_TEX_BUMPSRCTEX_ST 17 -#define GX_XF_TEX_BUMPSRCTEX_END 19 -#define GX_XF_TEX_BUMPSRCTEX_SZ 3 -#define GX_XF_TEX_BUMPSRCTEX_MASK (((1 << 3) - 1) << 31 - 19) -#define GX_XF_GET_TEX_BUMPSRCTEX(reg) GX_BITGET(reg, 17, 3) -#define GX_XF_SET_TEX_BUMPSRCTEX(reg, x) ((reg) = GX_BITSET(reg, 17, 3, x)) -// BUMPSRCLIGHT [14:16] (3) -#define GX_XF_TEX_BUMPSRCLIGHT_ST 14 -#define GX_XF_TEX_BUMPSRCLIGHT_END 16 -#define GX_XF_TEX_BUMPSRCLIGHT_SZ 3 -#define GX_XF_TEX_BUMPSRCLIGHT_MASK (((1 << 3) - 1) << 31 - 16) -#define GX_XF_GET_TEX_BUMPSRCLIGHT(reg) GX_BITGET(reg, 14, 3) -#define GX_XF_SET_TEX_BUMPSRCLIGHT(reg, x) ((reg) = GX_BITSET(reg, 14, 3, x)) +/* start bit */ #define GX_XF_TEX_PROJTYPE_B 30 +/* end bit */ #define GX_XF_TEX_PROJTYPE_E 30 +/* bit size */ #define GX_XF_TEX_PROJTYPE_SZ 1 -/** +/* raw mask */ #define GX_XF_TEX_PROJTYPE_MASK (((1 << 1) - 1) << 31 - 30) +/* local mask */ #define GX_XF_TEX_PROJTYPE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_XF_TEX_PROJTYPE_SHIFT 1 + +/* get value */ #define GX_XF_GET_TEX_PROJTYPE(reg) GX_BITGET((reg), 30, 1) +/* set value */ #define GX_XF_SET_TEX_PROJTYPE(reg, x) ((reg) = GX_BITSET((reg), 30, 1, x)) + +// INPUTFORM [29:29] (1) +/* start bit */ #define GX_XF_TEX_INPUTFORM_B 29 +/* end bit */ #define GX_XF_TEX_INPUTFORM_E 29 +/* bit size */ #define GX_XF_TEX_INPUTFORM_SZ 1 + +/* raw mask */ #define GX_XF_TEX_INPUTFORM_MASK (((1 << 1) - 1) << 31 - 29) +/* local mask */ #define GX_XF_TEX_INPUTFORM_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_XF_TEX_INPUTFORM_SHIFT 2 + +/* get value */ #define GX_XF_GET_TEX_INPUTFORM(reg) GX_BITGET((reg), 29, 1) +/* set value */ #define GX_XF_SET_TEX_INPUTFORM(reg, x) ((reg) = GX_BITSET((reg), 29, 1, x)) + +// TEXGENTYPE [25:27] (3) +/* start bit */ #define GX_XF_TEX_TEXGENTYPE_B 25 +/* end bit */ #define GX_XF_TEX_TEXGENTYPE_E 27 +/* bit size */ #define GX_XF_TEX_TEXGENTYPE_SZ 3 + +/* raw mask */ #define GX_XF_TEX_TEXGENTYPE_MASK (((1 << 3) - 1) << 31 - 27) +/* local mask */ #define GX_XF_TEX_TEXGENTYPE_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_XF_TEX_TEXGENTYPE_SHIFT 4 + +/* get value */ #define GX_XF_GET_TEX_TEXGENTYPE(reg) GX_BITGET((reg), 25, 3) +/* set value */ #define GX_XF_SET_TEX_TEXGENTYPE(reg, x) ((reg) = GX_BITSET((reg), 25, 3, x)) + +// SRCROW [20:24] (5) +/* start bit */ #define GX_XF_TEX_SRCROW_B 20 +/* end bit */ #define GX_XF_TEX_SRCROW_E 24 +/* bit size */ #define GX_XF_TEX_SRCROW_SZ 5 + +/* raw mask */ #define GX_XF_TEX_SRCROW_MASK (((1 << 5) - 1) << 31 - 24) +/* local mask */ #define GX_XF_TEX_SRCROW_LMASK ((1 << 5) - 1) +/* bit shift */ #define GX_XF_TEX_SRCROW_SHIFT 7 + +/* get value */ #define GX_XF_GET_TEX_SRCROW(reg) GX_BITGET((reg), 20, 5) +/* set value */ #define GX_XF_SET_TEX_SRCROW(reg, x) ((reg) = GX_BITSET((reg), 20, 5, x)) + +// BUMPSRCTEX [17:19] (3) +/* start bit */ #define GX_XF_TEX_BUMPSRCTEX_B 17 +/* end bit */ #define GX_XF_TEX_BUMPSRCTEX_E 19 +/* bit size */ #define GX_XF_TEX_BUMPSRCTEX_SZ 3 + +/* raw mask */ #define GX_XF_TEX_BUMPSRCTEX_MASK (((1 << 3) - 1) << 31 - 19) +/* local mask */ #define GX_XF_TEX_BUMPSRCTEX_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_XF_TEX_BUMPSRCTEX_SHIFT 12 + +/* get value */ #define GX_XF_GET_TEX_BUMPSRCTEX(reg) GX_BITGET((reg), 17, 3) +/* set value */ #define GX_XF_SET_TEX_BUMPSRCTEX(reg, x) ((reg) = GX_BITSET((reg), 17, 3, x)) + +// BUMPSRCLIGHT [14:16] (3) +/* start bit */ #define GX_XF_TEX_BUMPSRCLIGHT_B 14 +/* end bit */ #define GX_XF_TEX_BUMPSRCLIGHT_E 16 +/* bit size */ #define GX_XF_TEX_BUMPSRCLIGHT_SZ 3 + +/* raw mask */ #define GX_XF_TEX_BUMPSRCLIGHT_MASK (((1 << 3) - 1) << 31 - 16) +/* local mask */ #define GX_XF_TEX_BUMPSRCLIGHT_LMASK ((1 << 3) - 1) +/* bit shift */ #define GX_XF_TEX_BUMPSRCLIGHT_SHIFT 15 + +/* get value */ #define GX_XF_GET_TEX_BUMPSRCLIGHT(reg) GX_BITGET((reg), 14, 3) +/* set value */ #define GX_XF_SET_TEX_BUMPSRCLIGHT(reg, x) ((reg) = GX_BITSET((reg), 14, 3, x)) + +/****************************************************************************** * XF structure - DualTex - */ + *****************************************************************************/ // BASEROW [26:31] (6) - Indicates which is the base row of the transform matrix -#define GX_XF_DUALTEX_BASEROW_ST 26 -#define GX_XF_DUALTEX_BASEROW_END 31 -#define GX_XF_DUALTEX_BASEROW_SZ 6 -#define GX_XF_DUALTEX_BASEROW_MASK (((1 << 6) - 1) << 31 - 31) -#define GX_XF_GET_DUALTEX_BASEROW(reg) GX_BITGET(reg, 26, 6) -#define GX_XF_SET_DUALTEX_BASEROW(reg, x) ((reg) = GX_BITSET(reg, 26, 6, x)) +/* start bit */ #define GX_XF_DUALTEX_BASEROW_B 26 +/* end bit */ #define GX_XF_DUALTEX_BASEROW_E 31 +/* bit size */ #define GX_XF_DUALTEX_BASEROW_SZ 6 + +/* raw mask */ #define GX_XF_DUALTEX_BASEROW_MASK (((1 << 6) - 1) << 31 - 31) +/* local mask */ #define GX_XF_DUALTEX_BASEROW_LMASK ((1 << 6) - 1) +/* bit shift */ #define GX_XF_DUALTEX_BASEROW_SHIFT 0 + +/* get value */ #define GX_XF_GET_DUALTEX_BASEROW(reg) GX_BITGET((reg), 26, 6) +/* set value */ #define GX_XF_SET_DUALTEX_BASEROW(reg, x) ((reg) = GX_BITSET((reg), 26, 6, x)) + // NORMALIZE [23:23] (1) - Normalize texcoord before sending transform -#define GX_XF_DUALTEX_NORMALIZE_ST 23 -#define GX_XF_DUALTEX_NORMALIZE_END 23 -#define GX_XF_DUALTEX_NORMALIZE_SZ 1 -#define GX_XF_DUALTEX_NORMALIZE_MASK (((1 << 1) - 1) << 31 - 23) -#define GX_XF_GET_DUALTEX_NORMALIZE(reg) GX_BITGET(reg, 23, 1) -#define GX_XF_SET_DUALTEX_NORMALIZE(reg, x) ((reg) = GX_BITSET(reg, 23, 1, x)) +/* start bit */ #define GX_XF_DUALTEX_NORMALIZE_B 23 +/* end bit */ #define GX_XF_DUALTEX_NORMALIZE_E 23 +/* bit size */ #define GX_XF_DUALTEX_NORMALIZE_SZ 1 + +/* raw mask */ #define GX_XF_DUALTEX_NORMALIZE_MASK (((1 << 1) - 1) << 31 - 23) +/* local mask */ #define GX_XF_DUALTEX_NORMALIZE_LMASK ((1 << 1) - 1) +/* bit shift */ #define GX_XF_DUALTEX_NORMALIZE_SHIFT 8 + +/* get value */ #define GX_XF_GET_DUALTEX_NORMALIZE(reg) GX_BITGET((reg), 23, 1) +/* set value */ #define GX_XF_SET_DUALTEX_NORMALIZE(reg, x) ((reg) = GX_BITSET((reg), 23, 1, x)) #ifdef __cplusplus } diff --git a/include/rvl/GX/GXInternal.h b/include/rvl/GX/GXInternal.h index 7d361174..59a05e01 100644 --- a/include/rvl/GX/GXInternal.h +++ b/include/rvl/GX/GXInternal.h @@ -84,6 +84,14 @@ typedef struct _GXTlutObjImpl { u8 todo[0xC]; } GXTlutObjImpl; +typedef struct _GXTexRegionImpl { + u8 todo; +} GXTexRegionImpl; + +typedef struct _GXTlutRegionImpl { + u8 todo; +} GXTlutRegionImpl; + #ifdef __cplusplus } #endif diff --git a/include/rvl/GX/GXPixel.h b/include/rvl/GX/GXPixel.h index 905da97f..044aa9a6 100644 --- a/include/rvl/GX/GXPixel.h +++ b/include/rvl/GX/GXPixel.h @@ -4,13 +4,13 @@ #include "rvl/GX/GXTypes.h" #include "rvl/MTX.h" // IWYU pragma: export - #ifdef __cplusplus extern "C" { #endif +#define GX_FOG_ADJ_TABLE_SZ 10 typedef struct _GXFogAdjTable { - u16 r[10]; // at 0x0 + u16 r[GX_FOG_ADJ_TABLE_SZ]; // at 0x0 } GXFogAdjTable; void GXSetFog(GXFogType type, GXColor color, f32 start, f32 end, f32 near, f32 far); diff --git a/include/rvl/GX/GXTexture.h b/include/rvl/GX/GXTexture.h index 5fdd28f7..9fbbdace 100644 --- a/include/rvl/GX/GXTexture.h +++ b/include/rvl/GX/GXTexture.h @@ -4,7 +4,6 @@ #include "rvl/GX/GXInternal.h" #include "rvl/GX/GXTypes.h" - #ifdef __cplusplus extern "C" { #endif @@ -12,6 +11,13 @@ extern "C" { GX_DECL_PUBLIC_STRUCT(GXTexObj, 32); GX_DECL_PUBLIC_STRUCT(GXTlutObj, 12); +GX_DECL_PUBLIC_STRUCT(GXTexRegion, 16); +GX_DECL_PUBLIC_STRUCT(GXTlutRegion, 16); + +typedef GXTexRegion *(*GXTexRegionCallback)(const GXTexObj *pObj, GXTexMapID map); + +typedef GXTlutRegion *(*GXTlutRegionCallback)(u32 id); + void __GXSetSUTexRegs(void); void GXInitTexObj( @@ -27,7 +33,7 @@ void GXInitTexObjCI(GXTexObj *, void *, u16, u16, GXTexFmt, GXTexWrapMode, GXTex void GXInitTlutObj(GXTlutObj *, void *, GXTlutFmt, u16); void GXLoadTlut(GXTlutObj *, u32); -void GXLoadTexObj(GXTexObj *, GXTexMapID); +void GXLoadTexObj(const GXTexObj *, GXTexMapID); void GXGetTexObjAll( const GXTexObj *pTexObj, void **pImage, u16 *width, u16 *height, GXTexFmt *format, GXTexWrapMode *wrapS, @@ -37,10 +43,26 @@ void GXGetTexObjLODAll( const GXTexObj *pTexObj, GXTexFilter *minFilter, GXTexFilter *magFilter, f32 *minLOD, f32 *maxLOD, f32 *LODBias, u8 *biasClampEnable, u8 *edgeLODEnable, GXAnisotropy *anisotropy ); + +u16 GXGetTexObjWidth(const GXTexObj *obj); +u16 GXGetTexObjHeight(const GXTexObj *obj); +GXTexFmt GXGetTexObjFormat(const GXTexObj *obj); +GXBool GXGetTexObjMipMap(const GXTexObj *obj); +GXTexWrapMode GXGetTexObjWrapS(GXTexObj *obj); u32 GXGetTexObjTlut(GXTexObj *); +GXTexWrapMode GXGetTexObjWrapT(GXTexObj *obj); u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool arg3, u8 arg4); + void GXInvalidateTexAll(); +void GXInitTexCacheRegion( + GXTexRegion *pRegion, GXBool r4, u32 addrTMemEven, u32 sizeTMemEven, u32 addrTMemOdd, u32 sizeTMemOdd +); + +void GXInitTlutRegion(GXTlutRegion *pRegion, u32 addrTMem, u32 sizeTMem); +GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback); +GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback callback); + #ifdef __cplusplus } #endif diff --git a/include/rvl/GX/GXTransform.h b/include/rvl/GX/GXTransform.h index 7911636a..349556b5 100644 --- a/include/rvl/GX/GXTransform.h +++ b/include/rvl/GX/GXTransform.h @@ -8,6 +8,11 @@ extern "C" { #endif +typedef enum { + GX_FIELD_EVEN, + GX_FIELD_ODD, +} GXInterlaceField; + void GXSetProjection(const Mtx44 proj, GXProjectionType type); void GXSetProjectionv(const f32 proj[7]); void GXGetProjectionv(f32 proj[7]); @@ -30,6 +35,10 @@ void __GXSetProjection(void); void __GXSetViewport(void); void __GXSetMatrixIndex(GXAttr index); +static void GXSetViewportv(const f32 *vp) { + GXSetViewport(vp[0], vp[1], vp[2], vp[3], vp[4], vp[5]); +} + #ifdef __cplusplus } #endif diff --git a/include/rvl/MTX/mtx.h b/include/rvl/MTX/mtx.h index 6ae07eb2..f29af69b 100644 --- a/include/rvl/MTX/mtx.h +++ b/include/rvl/MTX/mtx.h @@ -21,8 +21,8 @@ void PSMTXCopy(const Mtx, Mtx); void PSMTXConcat(const Mtx, const Mtx, Mtx); void PSMTXConcatArray(const Mtx, const Mtx, Mtx, u32); void PSMTXTranspose(const Mtx, Mtx); -bool PSMTXInverse(const Mtx, Mtx); -void PSMTXInvXpose(const Mtx, Mtx); +u32 PSMTXInverse(const Mtx, Mtx); +u32 PSMTXInvXpose(const Mtx, Mtx); void PSMTXRotRad(Mtx, f32, char); void PSMTXRotTrig(Mtx, f32, f32, char); void PSMTXRotAxisRad(Mtx, const Vec *, f32); diff --git a/include/rvl/OS/OSFastCast.h b/include/rvl/OS/OSFastCast.h index 3f7aace6..9f86bac7 100644 --- a/include/rvl/OS/OSFastCast.h +++ b/include/rvl/OS/OSFastCast.h @@ -1,11 +1,16 @@ #ifndef RVL_SDK_OS_FAST_CAST_H #define RVL_SDK_OS_FAST_CAST_H -#include "common.h" +#include #ifdef __cplusplus extern "C" { #endif -static inline void OSInitFastCast(void) { +#define OS_GQR_TYPE_U8 4 +#define OS_GQR_TYPE_U16 5 +#define OS_GQR_TYPE_S8 6 +#define OS_GQR_TYPE_S16 7 + +static void OSInitFastCast(void) { // clang-format off asm { li r3, 4 @@ -27,7 +32,53 @@ static inline void OSInitFastCast(void) { // clang-format on } -static inline f32 __OSu16tof32(register const u16 *arg) { +static void OSSetGQR6(register u32 type, register u32 scale) { + register u32 val = ((scale << 8 | type) << 16) | ((scale << 8) | type); + + // clang-format off + asm { + mtspr 0x396, val + } + // clang-format on +} + +static void OSSetGQR7(register u32 type, register u32 scale) { + register u32 val = ((scale << 8 | type) << 16) | ((scale << 8) | type); + + // clang-format off + asm { + mtspr 0x397, val + } + // clang-format on +} + +/****************************************************************************** + * + * Convert from U8 + * + ******************************************************************************/ +static inline f32 __OSu8tof32(register u8 *in) { + register f32 ret; + + // clang-format off + asm { + psq_l ret, 0(in), 1, 2 + } + // clang-format on + + return ret; +} + +static inline void OSu8tof32(u8 *in, volatile f32 *out) { + *out = __OSu8tof32(in); +} + +/****************************************************************************** + * + * Convert from U16 + * + ******************************************************************************/ +static inline f32 __OSu16tof32(register u16 *arg) { register f32 ret; // clang-format off @@ -39,10 +90,55 @@ static inline f32 __OSu16tof32(register const u16 *arg) { return ret; } -static inline void OSu16tof32(const u16 *in, f32 *out) { +static inline void OSu16tof32(u16 *in, volatile f32 *out) { *out = __OSu16tof32(in); } +/****************************************************************************** + * + * Convert from S16 + * + ******************************************************************************/ +static inline f32 __OSs16tof32(register s16 *arg) { + register f32 ret; + + // clang-format off + asm { + psq_l ret, 0(arg), 1, 5 + } + // clang-format on + + return ret; +} + +static inline void OSs16tof32(s16 *in, volatile f32 *out) { + *out = __OSs16tof32(in); +} + +/****************************************************************************** + * + * Convert from F32 + * + ******************************************************************************/ +static inline u8 __OSf32tou8(register f32 arg) { + f32 a; + register f32 *ptr = &a; + u8 r; + + // clang-format off + asm { + psq_st arg, 0(ptr), 1, 2 + } + // clang-format on + + r = *(u8 *)ptr; + return r; +} + +static inline void OSf32tou8(f32 *in, volatile u8 *out) { + *out = __OSf32tou8(*in); +} + static inline u16 __OSf32tou16(register f32 arg) { f32 a; register f32 *ptr = &a; @@ -57,43 +153,11 @@ static inline u16 __OSf32tou16(register f32 arg) { r = *(u16 *)ptr; return r; } -static inline u8 __OSf32tou8(register f32 arg) { - f32 a; - register f32 *ptr = &a; - register u8 r; - // clang-format off - asm { - psq_st arg, 0(ptr), 1, 2 - lbz r, 0(ptr) - } - // clang-format on - - return r; -} -static inline void OSf32tou16(const f32 *in, volatile u16 *out) { +static inline void OSf32tou16(f32 *in, volatile u16 *out) { *out = __OSf32tou16(*in); } -static inline void OSf32tou8(const f32 *in, volatile u8 *out) { - *out = __OSf32tou8(*in); -} -static inline f32 __OSs16tof32(register const s16 *arg) { - register f32 ret; - - // clang-format off - asm { - psq_l ret, 0(arg), 1, 5 - } - // clang-format on - - return ret; -} - -static inline void OSs16tof32(const s16 *in, f32 *out) { - *out = __OSs16tof32(in); -} - static inline s16 __OSf32tos16(register f32 arg) { f32 a; register f32 *ptr = &a; @@ -109,7 +173,7 @@ static inline s16 __OSf32tos16(register f32 arg) { return r; } -static inline void OSf32tos16(const f32 *in, volatile s16 *out) { +static inline void OSf32tos16(f32 *in, volatile s16 *out) { *out = __OSf32tos16(*in); } diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/algorithm b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/algorithm new file mode 100644 index 00000000..aa6ec1d2 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/algorithm @@ -0,0 +1,220 @@ +#ifndef MSL_CPP_ALGORITHM_H +#define MSL_CPP_ALGORITHM_H +#include + +namespace std { + +template inline const T& max(const T& a, const T& b) { + return (a < b) ? b : a; +} + +template inline const T& min(const T& a, const T& b) { + return (b < a) ? b : a; +} + +template +inline TPtr find(TPtr first, TPtr last, const T& value) { + while (first != last && *first != value) { + ++first; + } + + return first; +} + +template inline long distance(TPtr first, TPtr last) { + random_access_iterator_tag tag; + return __distance(first, last, tag); +} + +template +inline long __distance(TPtr first, TPtr last, + random_access_iterator_tag /* tag */) { + return static_cast(last - first); +} + +template inline T& move(T& x) { + return x; +} + +template inline void swap(T& a, T& b) { + T tmp = move(a); + a = move(b); + b = move(tmp); +} + +template +inline TIt min_element(TIt first, TIt last, TCompare compare) { + TIt it = first; + + if (first != last) { + for (++first; first != last; ++first) { + if (compare(*first, *it)) { + it = first; + } + } + } + + return it; +} + +template +inline void __selection_sort(TIt first, TIt last, TCompare compare) { + if (first == last) { + return; + } + + TIt j = last; + for (--j; first != j; ++first) { + TIt i = min_element(first, last, compare); + + if (i != first) { + swap(*i, *first); + } + } +} + +template +void __sort132(TIt a1, TIt a2, TIt a3, TCompare compare) + __attribute__((never_inline)) { + bool b1 = !compare(*a3, *a1); + bool b2 = !compare(*a2, *a3); + + if (!b1 || !b2) { + if (!b1 && !b2) { + swap(*a1, *a2); + return; + } + + if (compare(*a2, *a1)) { + swap(*a1, *a2); + } + + if (b1) { + swap(*a2, *a3); + return; + } + + swap(*a1, *a3); + } +} + +template +void sort(TIt first, TIt last, TCompare compare) { + static const int SHUFFLE_MIN = -4; + static const int SHUFFLE_MAX = 5; + static const int SELECTION_SORT_MIN = 20; + + while (true) { + long len = static_cast(last - first); + if (len <= 1) { + return; + } + + if (len <= SELECTION_SORT_MIN) { + __selection_sort(first, last, compare); + return; + } + + static int shuffle = -4; + TIt m = first + + (len / static_cast(sizeof(TIt)) + shuffle % SHUFFLE_MAX); + + if (++shuffle >= SHUFFLE_MAX) { + shuffle = SHUFFLE_MIN; + } + + TIt i1 = first + (len * static_cast(sizeof(TIt) - 1) / + static_cast(sizeof(TIt)) + + shuffle % SHUFFLE_MAX); + + if (++shuffle >= SHUFFLE_MAX) { + shuffle = SHUFFLE_MIN; + } + + TIt j = last - 1; + __sort132(m, i1, j, compare); + + m = first; + i1 = j; + while (compare(*m, *j)) { + m++; + } + + do { + i1--; + + if (m == i1) { + break; + } + } while (!compare(*i1, *j)); + + if (m < i1) { + swap(*m, *i1); + m++; + + while (true) { + while (compare(*m, *j)) { + m++; + } + + while (!compare(*--i1, *j)) { + ; + } + + if (m < i1) { + swap(*m, *i1); + m++; + } else { + break; + } + } + } + + if (m == first) { + swap(*m, *j); + m++; + + i1 = last; + if (!compare(*first, *--i1)) { + while (m != last && !compare(*first, *m)) { + m++; + } + + if (m < i1) { + swap(*m, *i1); + } + } + + if (m < i1) { + while (true) { + while (!compare(*first, *m)) { + m++; + } + + while (compare(*first, *--i1)) { + ; + } + + if (m < i1) { + swap(*m, *i1); + m++; + } else { + break; + } + } + } + + first = m; + } else if (m - first < last - m) { + sort(first, m, compare); + first = m; + } else { + sort(m, last, compare); + last = m; + } + } +} + +} // namespace std + +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cctype b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cctype new file mode 100644 index 00000000..a4fa1ede --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cctype @@ -0,0 +1,12 @@ +#ifndef MSL_CPP_CCTYPE_H +#define MSL_CPP_CCTYPE_H +#include +#ifdef __cplusplus + +namespace std { +using ::tolower; +using ::toupper; +} // namespace std + +#endif +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cerrno b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cerrno new file mode 100644 index 00000000..f371e9b9 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cerrno @@ -0,0 +1,4 @@ +#ifndef MSL_CPP_CERRNO_H +#define MSL_CPP_CERRNO_H +#include +#endif \ No newline at end of file diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/climits b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/climits new file mode 100644 index 00000000..0740fc20 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/climits @@ -0,0 +1,4 @@ +#ifndef MSL_CPP_CLIMITS_H +#define MSL_CPP_CLIMITS_H +#include +#endif \ No newline at end of file diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath new file mode 100644 index 00000000..7517fae0 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath @@ -0,0 +1,58 @@ +#ifndef MSL_CPP_CMATH_H +#define MSL_CPP_CMATH_H +#include +#ifdef __cplusplus + +// Remove C macro +#undef fabs + +namespace std { +using ::acos; +using ::acosf; +using ::asin; +// using ::asinf; +using ::atan; +using ::atan2; +using ::atan2f; +using ::ceil; +using ::ceilf; +using ::copysign; +using ::cos; +using ::cosf; +using ::fabsf; +using ::floor; +using ::floorf; +using ::fmod; +using ::fmodf; +using ::frexp; +using ::ldexp; +// using ::ldexpf; +using ::modf; +using ::modff; +// using ::nan; +using ::pow; +using ::scalbn; +using ::sin; +using ::sinf; +using ::sqrt; +using ::sqrtf; +using ::tan; +using ::tanf; + +inline float sqrt(float x) { + return ::sqrtf(x); +} + +// TODO: Very fake! +// inline double fabs_wrapper(double x) { +// return __fabs(x); +// } + +// inline float fabs(float x) { +// return fabs_wrapper(x); +// } + +} // namespace std + +#endif +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstddef b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstddef new file mode 100644 index 00000000..c853dd85 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstddef @@ -0,0 +1,14 @@ +#ifndef MSL_CPP_CSTDDEF_H +#define MSL_CPP_CSTDDEF_H +#include +#ifdef __cplusplus + +namespace std { +using ::intptr_t; +using ::ptrdiff_t; +using ::size_t; +using ::uintptr_t; +} // namespace std + +#endif +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdio b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdio new file mode 100644 index 00000000..4c995a0d --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdio @@ -0,0 +1,21 @@ +#ifndef MSL_CPP_CSTDIO_H +#define MSL_CPP_CSTDIO_H +#include +#ifdef __cplusplus + +namespace std { +using ::fclose; +using ::fflush; +using ::FILE; +// using ::ftell; +// using ::fwide; +using ::snprintf; +using ::sprintf; +// using ::sscanf; +using ::vprintf; +using ::vsnprintf; +// using ::vsprintf; +} // namespace std + +#endif +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdlib b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdlib new file mode 100644 index 00000000..8ee47976 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdlib @@ -0,0 +1,17 @@ +#ifndef MSL_CPP_CSTDLIB_H +#define MSL_CPP_CSTDLIB_H +#include +#ifdef __cplusplus + +// TODO: Fillout impls +namespace std { +// using ::abs; +// using ::atof; +// using ::mbstowcs; +// using ::mbtowc; +// using ::rand; +// using ::wcstombs; +} // namespace std + +#endif +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring new file mode 100644 index 00000000..8b388ec0 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring @@ -0,0 +1,26 @@ +#ifndef MSL_CPP_CSTRING_H +#define MSL_CPP_CSTRING_H +#include +#ifdef __cplusplus + +namespace std { +using ::__memrchr; +using ::memchr; +using ::memcmp; +using ::memcpy; +using ::memmove; +using ::memset; +using ::strcat; +using ::strchr; +using ::strcmp; +using ::strcpy; +// using ::stricmp; +using ::strlen; +using ::strncat; +using ::strncmp; +using ::strncpy; +// using ::strstr; +} // namespace std + +#endif +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring.h index c8497d85..e7bdf55e 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring.h @@ -4,13 +4,13 @@ #include "string.h" namespace std { -inline size_t strlen(const char* str) { +inline size_t strlen(const char *str) { return ::strlen(str); } -inline char* strcpy(char* dest, const char* src) { +inline char *strcpy(char *dest, const char *src) { return ::strcpy(dest, src); } -} // namespace std +} // namespace std -#endif \ No newline at end of file +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cwchar b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cwchar new file mode 100644 index 00000000..7191d7a0 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cwchar @@ -0,0 +1,21 @@ +#ifndef MSL_CPP_CWCHAR_H +#define MSL_CPP_CWCHAR_H +#include +#ifdef __cplusplus + +namespace std { +using ::mbstowcs; +using ::mbtowc; +using ::swprintf; +using ::vswprintf; +using ::wcscat; +using ::wcschr; +using ::wcscmp; +using ::wcscpy; +using ::wcslen; +using ::wcsncpy; +using ::wcstombs; +} // namespace std + +#endif +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/iterator b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/iterator new file mode 100644 index 00000000..cc303806 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/iterator @@ -0,0 +1,10 @@ +#ifndef MSL_CPP_ITERATOR_H +#define MSL_CPP_ITERATOR_H + +namespace std { + +struct random_access_iterator_tag {}; + +} // namespace std + +#endif \ No newline at end of file diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/new b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/new new file mode 100644 index 00000000..2372b4b2 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/new @@ -0,0 +1,17 @@ +#ifndef MSL_CPP_NEW_H +#define MSL_CPP_NEW_H +#include +#ifdef __cplusplus + +inline void* operator new(size_t size, void* ptr) { +#pragma unused(size) + return ptr; +} + +inline void* operator new[](size_t size, void* ptr) { +#pragma unused(size) + return ptr; +} + +#endif +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h index 121e4ac6..7a6f3f76 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h @@ -13,6 +13,9 @@ typedef unsigned long size_t; typedef long ptrdiff_t; #endif +typedef signed long intptr_t; +typedef unsigned long uintptr_t; + #ifdef __MWERKS__ #define offsetof(type, member) ((size_t) & (((type *)0)->member)) #else diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h index 4f8b1eb6..86c421b3 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h @@ -17,6 +17,7 @@ char *strrchr(const char *str, int c); char *strchr(const char *str, int c); int strncmp(const char *str1, const char *str2, size_t n); int strcmp(const char *str1, const char *str2); +char *strncat(char *dst, const char *src, size_t n); char *strcat(char *dst, const char *src); char *strncpy(char *dst, const char *src, size_t n); char *strcpy(char *dst, const char *src); diff --git a/src/REL/d/a/d_a_bombf.cpp b/src/REL/d/a/d_a_bombf.cpp index 609c3eef..78dd2b8e 100644 --- a/src/REL/d/a/d_a_bombf.cpp +++ b/src/REL/d/a/d_a_bombf.cpp @@ -14,7 +14,7 @@ SPECIAL_ACTOR_PROFILE(BOMBF, dAcBombf_c, fProfile::BOMBF, 0x129, 0, 4099); STATE_DEFINE(dAcBombf_c, Wait); bool dAcBombf_c::createHeap() { - nw4r::g3d::ResFile resFile = getOarcResFile("FlowerBomb"); + nw4r::g3d::ResFile resFile(getOarcResFile("FlowerBomb")); nw4r::g3d::ResMdl resMdl = resFile.GetResMdl("LeafBomb"); return mModel.create(resMdl, &heap_allocator, 0x120, 1, nullptr); } diff --git a/src/REL/d/a/e/d_a_e_hb_leaf.cpp b/src/REL/d/a/e/d_a_e_hb_leaf.cpp index 1c9856fa..27780659 100644 --- a/src/REL/d/a/e/d_a_e_hb_leaf.cpp +++ b/src/REL/d/a/e/d_a_e_hb_leaf.cpp @@ -10,7 +10,7 @@ bool dAcEhb_leaf_c::createHeap() { // but only ever a single pointer. void *fp = getOarcResFile("Degubaba"); TRY_CREATE(mModel.create(fp, "degubaba_leaf", "shake2", &heap_allocator, 0x123)); - nw4r::g3d::ResFile f = fp; + nw4r::g3d::ResFile f(fp); nw4r::g3d::ResMdl mdl = f.GetResMdl("degubaba_leaf"); nw4r::g3d::ResAnmTexPat anm = f.GetResAnmTexPat("degubaba_leaf"); TRY_CREATE(mAnm.create(mdl, anm, &heap_allocator, nullptr, 1)); diff --git a/src/REL/d/a/obj/d_a_obj_appear_bridge.cpp b/src/REL/d/a/obj/d_a_obj_appear_bridge.cpp index f7c6c176..dc0e8296 100644 --- a/src/REL/d/a/obj/d_a_obj_appear_bridge.cpp +++ b/src/REL/d/a/obj/d_a_obj_appear_bridge.cpp @@ -2,6 +2,7 @@ #include "d/a/d_a_player.h" #include "d/col/bg/d_bg_s.h" +#include "nw4r/types_nw4r.h" #include "toBeSorted/area_utils.h" #include "toBeSorted/room_manager.h" @@ -16,7 +17,7 @@ STATE_DEFINE(dAcOappearBridge_c, Appear); STATE_DEFINE(dAcOappearBridge_c, Disappear); bool dAcOappearBridge_c::createHeap() { - mResFile = getOarcResFile("TongueStage"); + mResFile = nw4r::g3d::ResFile(getOarcResFile("TongueStage")); RoomManager::bindStageResToFile(&mResFile); nw4r::g3d::ResMdl mdl = mResFile.GetResMdl("TongueStage"); TRY_CREATE(mModel.create(mdl, &heap_allocator, 0x128)); diff --git a/src/REL/d/a/obj/d_a_obj_bamboo_island.cpp b/src/REL/d/a/obj/d_a_obj_bamboo_island.cpp index 1a89d00e..1b727ce1 100644 --- a/src/REL/d/a/obj/d_a_obj_bamboo_island.cpp +++ b/src/REL/d/a/obj/d_a_obj_bamboo_island.cpp @@ -2,6 +2,7 @@ #include "d/col/bg/d_bg_s.h" #include "d/flag/storyflag_manager.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "toBeSorted/room_manager.h" const f32 dAcObambooIsland_c::unusedFloat1 = 100000.0f; @@ -21,7 +22,7 @@ void dAcObambooIsland_c::rideCallback(dBgW *unknown, dAcObjBase_c *actor, dAcObj } bool dAcObambooIsland_c::createHeap() { - mBrres = getOarcResFile("IslBamb"); + mBrres = nw4r::g3d::ResFile(getOarcResFile("IslBamb")); RoomManager::bindStageResToFile(&mBrres); RoomManager::bindSkyCmnToResFile(&mBrres); for (int i = 0; i < 2; i++) { diff --git a/src/REL/d/a/obj/d_a_obj_flying_clawshot_target.cpp b/src/REL/d/a/obj/d_a_obj_flying_clawshot_target.cpp index ce4fbf31..3153cc67 100644 --- a/src/REL/d/a/obj/d_a_obj_flying_clawshot_target.cpp +++ b/src/REL/d/a/obj/d_a_obj_flying_clawshot_target.cpp @@ -10,8 +10,8 @@ #include "m/m_mtx.h" #include "m/m_quat.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" #include "rvl/MTX/mtxvec.h" SPECIAL_ACTOR_PROFILE( @@ -25,8 +25,8 @@ bool dAcOFlyingClawshotTarget_c::createHeap() { return false; } - nw4r::g3d::ResFile file = data; - if (!file.mFile.IsValid()) { + nw4r::g3d::ResFile file(data); + if (!file.IsValid()) { return false; } nw4r::g3d::ResMdl mdl = file.GetResMdl("BirdObjD3_S"); diff --git a/src/REL/d/a/obj/d_a_obj_fruit_guts_leaf.cpp b/src/REL/d/a/obj/d_a_obj_fruit_guts_leaf.cpp index 8129b0e1..80747044 100644 --- a/src/REL/d/a/obj/d_a_obj_fruit_guts_leaf.cpp +++ b/src/REL/d/a/obj/d_a_obj_fruit_guts_leaf.cpp @@ -4,8 +4,8 @@ #include "d/a/obj/d_a_obj_base.h" #include "f/f_base.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" #include "s/s_Math.h" #include "toBeSorted/time_area_mgr.h" @@ -22,14 +22,14 @@ bool dAcOFruitGutsLeaf_c::createHeap() { if (data == nullptr) { return false; } - nw4r::g3d::ResFile f = data; - if (!f.mFile.IsValid()) { + nw4r::g3d::ResFile f(data); + if (!f.IsValid()) { return false; } nw4r::g3d::ResMdl m = f.GetResMdl(mdlName); - if (!m.mMdl.IsValid()) { + if (!m.IsValid()) { return false; } diff --git a/src/REL/d/a/obj/d_a_obj_island_nusi.cpp b/src/REL/d/a/obj/d_a_obj_island_nusi.cpp index dc50ca9d..c4ee7b25 100644 --- a/src/REL/d/a/obj/d_a_obj_island_nusi.cpp +++ b/src/REL/d/a/obj/d_a_obj_island_nusi.cpp @@ -2,13 +2,14 @@ #include "d/a/obj/d_a_obj_base.h" #include "d/col/bg/d_bg_s.h" +#include "d/flag/storyflag_manager.h" #include "f/f_base.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resmdl.h" -#include "nw4r/g3d/g3d_resnode.h" #include "nw4r/g3d/g3d_scnmdl.h" #include "nw4r/g3d/g3d_scnobj.h" -#include "d/flag/storyflag_manager.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resnode.h" #include "toBeSorted/room_manager.h" const f32 dAcOislandNusi_c::someFloat = 100000.0f; @@ -24,7 +25,7 @@ STATE_DEFINE(dAcOislandNusi_c, Wait); STATE_DEFINE(dAcOislandNusi_c, NusiFight); bool dAcOislandNusi_c::createHeap() { - mRes = getOarcResFile("IslNusi"); + mRes = nw4r::g3d::ResFile(getOarcResFile("IslNusi")); RoomManager::bindStageResToFile(&mRes); RoomManager::bindSkyCmnToResFile(&mRes); for (int i = 0; i < 2; i++) { diff --git a/src/REL/d/a/obj/d_a_obj_junk_repairing.cpp b/src/REL/d/a/obj/d_a_obj_junk_repairing.cpp index a997f32d..14215fdc 100644 --- a/src/REL/d/a/obj/d_a_obj_junk_repairing.cpp +++ b/src/REL/d/a/obj/d_a_obj_junk_repairing.cpp @@ -1,7 +1,7 @@ #include "d/a/obj/d_a_obj_junk_repairing.h" #include "d/flag/storyflag_manager.h" - +#include "nw4r/g3d/res/g3d_resfile.h" SPECIAL_ACTOR_PROFILE(OBJ_JUNK_REPAIR, dAcOJunkRep_c, fProfile::OBJ_JUNK_REPAIR, 0x027B, 0, 3); @@ -19,7 +19,7 @@ bool dAcOJunkRep_c::getState() { } bool dAcOJunkRep_c::createHeap() { - mResFile = getOarcResFile("Junk"); + mResFile = nw4r::g3d::ResFile(getOarcResFile("Junk")); if (!loadMdl(mModel1, getMdlName1())) { return false; } diff --git a/src/REL/d/a/obj/d_a_obj_lava_F200.cpp b/src/REL/d/a/obj/d_a_obj_lava_F200.cpp index 8d5d5b40..068fd747 100644 --- a/src/REL/d/a/obj/d_a_obj_lava_F200.cpp +++ b/src/REL/d/a/obj/d_a_obj_lava_F200.cpp @@ -1,12 +1,12 @@ #include "d/a/obj/d_a_obj_lava_F200.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "toBeSorted/room_manager.h" - SPECIAL_ACTOR_PROFILE(OBJ_LAVA_F200, dAcOlavaF200_c, fProfile::OBJ_LAVA_F200, 0x0214, 0, 0); bool dAcOlavaF200_c::createHeap() { - mBrres = getOarcResFile("LavaF200"); + mBrres = nw4r::g3d::ResFile(getOarcResFile("LavaF200")); RoomManager::bindStageResToFile(&mBrres); nw4r::g3d::ResMdl mdl0 = mBrres.GetResMdl("LavaF200"); diff --git a/src/REL/d/a/obj/d_a_obj_megami_island.cpp b/src/REL/d/a/obj/d_a_obj_megami_island.cpp index 7dab639d..e8df429f 100644 --- a/src/REL/d/a/obj/d_a_obj_megami_island.cpp +++ b/src/REL/d/a/obj/d_a_obj_megami_island.cpp @@ -6,8 +6,8 @@ #include "d/flag/storyflag_manager.h" #include "f/f_base.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resanmtexsrt.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resanmtexsrt.h" +#include "nw4r/g3d/res/g3d_resmdl.h" #include "toBeSorted/room_manager.h" static const char *const sResFiles[] = { @@ -45,7 +45,7 @@ SPECIAL_ACTOR_PROFILE(OBJ_MEGAMI_ISLAND, dAcOmegamiIsland_c, fProfile::OBJ_MEGAM bool dAcOmegamiIsland_c::createHeap() { mVariant = getVariant(); - mRes = getOarcResFile(sResFiles[mVariant]); + mRes = nw4r::g3d::ResFile(getOarcResFile(sResFiles[mVariant])); RoomManager::bindStageResToFile(&mRes); RoomManager::bindSkyCmnToResFile(&mRes); diff --git a/src/REL/d/a/obj/d_a_obj_mole_soil.cpp b/src/REL/d/a/obj/d_a_obj_mole_soil.cpp index 0999c06a..84c6a73e 100644 --- a/src/REL/d/a/obj/d_a_obj_mole_soil.cpp +++ b/src/REL/d/a/obj/d_a_obj_mole_soil.cpp @@ -12,8 +12,8 @@ const f32 dAcOmoleSoil_c::sHalfScale = 0.5f; const f32 dAcOmoleSoil_c::sFullScale = 1.0f; bool dAcOmoleSoil_c::createHeap() { - nw4r::g3d::ResFile file = getOarcResFile("MogumaMud"); - if (!file.mFile.IsValid()) { + nw4r::g3d::ResFile file(getOarcResFile("MogumaMud")); + if (!file.IsValid()) { return false; } mBrres = file; diff --git a/src/REL/d/a/obj/d_a_obj_pool_cock.cpp b/src/REL/d/a/obj/d_a_obj_pool_cock.cpp index 78a11035..3c786404 100644 --- a/src/REL/d/a/obj/d_a_obj_pool_cock.cpp +++ b/src/REL/d/a/obj/d_a_obj_pool_cock.cpp @@ -1,16 +1,16 @@ #include "d/a/obj/d_a_obj_pool_cock.h" #include "d/a/obj/d_a_obj_vortex.h" +#include "d/flag/sceneflag_manager.h" #include "s/s_Math.h" #include "toBeSorted/room_manager.h" -#include "d/flag/sceneflag_manager.h" SPECIAL_ACTOR_PROFILE(OBJ_POOL_COCK, dAcOPoolCock_c, fProfile::OBJ_POOL_COCK, 0x024D, 0, 7); STATE_DEFINE(dAcOPoolCock_c, Wait); bool dAcOPoolCock_c::createHeap() { - mBrres = getOarcResFile("WaterD101"); + mBrres = nw4r::g3d::ResFile(getOarcResFile("WaterD101")); RoomManager::bindStageResToFile(&mBrres); nw4r::g3d::ResMdl mdl = mBrres.GetResMdl("PoolCockD101"); for (int i = 0; i < 2; i++) { diff --git a/src/REL/d/a/obj/d_a_obj_pumpkin_leaf.cpp b/src/REL/d/a/obj/d_a_obj_pumpkin_leaf.cpp index 1fe3a384..cada2f95 100644 --- a/src/REL/d/a/obj/d_a_obj_pumpkin_leaf.cpp +++ b/src/REL/d/a/obj/d_a_obj_pumpkin_leaf.cpp @@ -1,14 +1,14 @@ #include "d/a/obj/d_a_obj_pumpkin_leaf.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_Math.h" - SPECIAL_ACTOR_PROFILE(OBJ_PUMPKIN_LEAF, dAcOPumpkinLeaf_c, fProfile::OBJ_PUMPKIN_LEAF, 0x0135, 0, 3); STATE_DEFINE(dAcOPumpkinLeaf_c, Wait); bool dAcOPumpkinLeaf_c::createHeap() { - mBrres = getOarcResFile("Pumpkin"); + mBrres = nw4r::g3d::ResFile(getOarcResFile("Pumpkin")); nw4r::g3d::ResMdl mdl = mBrres.GetResMdl("Leaf"); TRY_CREATE(mModel.create(mdl, &heap_allocator, 0x120, 1, nullptr)); return true; diff --git a/src/REL/d/a/obj/d_a_obj_ring.cpp b/src/REL/d/a/obj/d_a_obj_ring.cpp index 18b8ca1b..554a9d35 100644 --- a/src/REL/d/a/obj/d_a_obj_ring.cpp +++ b/src/REL/d/a/obj/d_a_obj_ring.cpp @@ -1,14 +1,14 @@ #include "d/a/obj/d_a_obj_ring.h" #include "d/a/d_a_player.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" SPECIAL_ACTOR_PROFILE(OBJ_RING, dAcOring_c, fProfile::OBJ_RING, 0x00f2, 0, 0x103); STATE_DEFINE(dAcOring_c, Move); bool dAcOring_c::createHeap() { - nw4r::g3d::ResFile f = getOarcResFile("PRing"); + nw4r::g3d::ResFile f(getOarcResFile("PRing")); nw4r::g3d::ResMdl mdl = f.GetResMdl("PeehatRing"); // This matches but in a really weird way. Maybe an inline function? TRY_CREATE(mModel.create(mdl, &heap_allocator, 0x20, 1, nullptr)); diff --git a/src/REL/d/a/obj/d_a_obj_seat_sword.cpp b/src/REL/d/a/obj/d_a_obj_seat_sword.cpp index f6489fe9..71aa5918 100644 --- a/src/REL/d/a/obj/d_a_obj_seat_sword.cpp +++ b/src/REL/d/a/obj/d_a_obj_seat_sword.cpp @@ -11,7 +11,7 @@ #include "m/m_angle.h" #include "m/m_mtx.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "rvl/MTX/mtx.h" #include "s/s_Math.h" #include "toBeSorted/attention.h" @@ -55,7 +55,7 @@ bool dAcOSeatSword_c::createHeap() { TRY_CREATE(mSwordMdl.create(mRes.GetResMdl(sword_name), &heap_allocator, 0x120, 1, nullptr)); } - nw4r::g3d::ResFile mPedRes = getOarcResFile(SwordSeatNames[mSubtype]); + nw4r::g3d::ResFile mPedRes(getOarcResFile(SwordSeatNames[mSubtype])); TRY_CREATE(mPedestalMdl.create(mPedRes.GetResMdl(SwordSeatNames[mSubtype]), &heap_allocator, 0x120, 1, nullptr)); void *dzb = getOarcDZB(SwordSeatNames[mSubtype], SwordSeatNames[mSubtype]); void *plc = getOarcPLC(SwordSeatNames[mSubtype], SwordSeatNames[mSubtype]); diff --git a/src/REL/d/a/obj/d_a_obj_smoke.cpp b/src/REL/d/a/obj/d_a_obj_smoke.cpp index d97b3dad..fb90fd9b 100644 --- a/src/REL/d/a/obj/d_a_obj_smoke.cpp +++ b/src/REL/d/a/obj/d_a_obj_smoke.cpp @@ -16,7 +16,7 @@ STATE_DEFINE(dAcOsmoke_c, Wait); bool dAcOsmoke_c::createHeap() { mType = params & 3; - mBrres = getOarcResFile(sSmokeNames1[mType]); + mBrres = nw4r::g3d::ResFile(getOarcResFile(sSmokeNames1[mType])); nw4r::g3d::ResMdl mdl = mBrres.GetResMdl(sSmokeNames2[mType]); TRY_CREATE(mModel.create(mdl, &heap_allocator, 0x324)); nw4r::g3d::ResAnmTexSrt srt = mBrres.GetResAnmTexSrt(sSmokeNames1[mType]); diff --git a/src/REL/d/a/obj/d_a_obj_spike.cpp b/src/REL/d/a/obj/d_a_obj_spike.cpp index 49499a3b..1847604a 100644 --- a/src/REL/d/a/obj/d_a_obj_spike.cpp +++ b/src/REL/d/a/obj/d_a_obj_spike.cpp @@ -18,7 +18,7 @@ const mVec3_c dAcOspike_c::sVec2 = mVec3_c(73.0f, 255.0f, 482.0f); STATE_DEFINE(dAcOspike_c, Wait); bool dAcOspike_c::createHeap() { - mResFile = getOarcResFile("SpikeD101"); + mResFile = nw4r::g3d::ResFile(getOarcResFile("SpikeD101")); nw4r::g3d::ResMdl mdl = mResFile.GetResMdl("SpikeD101"); TRY_CREATE(mMdl.create(mdl, &heap_allocator, 0x120)); return true; diff --git a/src/REL/d/a/obj/d_a_obj_stage_cover.cpp b/src/REL/d/a/obj/d_a_obj_stage_cover.cpp index 11df641b..c240bba9 100644 --- a/src/REL/d/a/obj/d_a_obj_stage_cover.cpp +++ b/src/REL/d/a/obj/d_a_obj_stage_cover.cpp @@ -1,14 +1,14 @@ #include "d/a/obj/d_a_obj_stage_cover.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "toBeSorted/arc_managers/current_stage_arc_manager.h" - SPECIAL_ACTOR_PROFILE(OBJ_STAGE_COVER, dAcOstageCover_c, fProfile::OBJ_STAGE_COVER, 0x01E1, 0, 0); STATE_DEFINE(dAcOstageCover_c, Wait); bool dAcOstageCover_c::createHeap() { - mBrres = CurrentStageArcManager::sInstance->getData("g3d/stage.brres"); + mBrres = nw4r::g3d::ResFile(CurrentStageArcManager::sInstance->getData("g3d/stage.brres")); nw4r::g3d::ResMdl mdl = mBrres.GetResMdl("StageCover"); TRY_CREATE(mModel.create(mdl, &heap_allocator, 0x120)); return true; diff --git a/src/REL/d/a/obj/d_a_obj_sun_light.cpp b/src/REL/d/a/obj/d_a_obj_sun_light.cpp index 816a9200..8922d5f0 100644 --- a/src/REL/d/a/obj/d_a_obj_sun_light.cpp +++ b/src/REL/d/a/obj/d_a_obj_sun_light.cpp @@ -1,16 +1,16 @@ #include "d/a/obj/d_a_obj_sun_light.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "toBeSorted/arc_managers/current_stage_arc_manager.h" #include "toBeSorted/room_manager.h" #include "toBeSorted/scgame.h" - SPECIAL_ACTOR_PROFILE(OBJ_SUN_LIGHT, dAcOsunLight_c, fProfile::OBJ_SUN_LIGHT, 0x0219, 0, 3); STATE_DEFINE(dAcOsunLight_c, Wait); bool dAcOsunLight_c::createHeap() { - mBrres = CurrentStageArcManager::sInstance->getData("g3d/stage.brres"); + mBrres = nw4r::g3d::ResFile(CurrentStageArcManager::sInstance->getData("g3d/stage.brres")); RoomManager::bindStageResToFile(&mBrres); RoomManager::bindSkyCmnToResFile(&mBrres); nw4r::g3d::ResMdl mdl = mBrres.GetResMdl("StageF000Light"); diff --git a/src/REL/d/a/obj/d_a_obj_time_stage_bg.cpp b/src/REL/d/a/obj/d_a_obj_time_stage_bg.cpp index a3d29a4d..3176ceba 100644 --- a/src/REL/d/a/obj/d_a_obj_time_stage_bg.cpp +++ b/src/REL/d/a/obj/d_a_obj_time_stage_bg.cpp @@ -4,9 +4,10 @@ #include "d/a/obj/d_a_obj_base.h" #include "m/m_color.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resanmclr.h" -#include "nw4r/g3d/g3d_resmdl.h" -#include "nw4r/g3d/g3d_resnode.h" +#include "nw4r/g3d/res/g3d_resanmclr.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resnode.h" #include "nw4r/math/math_types.h" #include "rvl/GX/GXTypes.h" #include "s/s_Math.h" @@ -26,12 +27,12 @@ static const char *sMdl2Names[] = { STATE_DEFINE(dAcOTimeStageBg_c, Wait); bool dAcOTimeStageBg_c::createHeap() { - mRes = CurrentStageArcManager::sInstance->getData("g3d/stage.brres"); + mRes = nw4r::g3d::ResFile(CurrentStageArcManager::sInstance->getData("g3d/stage.brres")); nw4r::g3d::ResMdl mdl = mRes.GetResMdl(sMdlNames[mSubType]); TRY_CREATE(mMdl1.create(mdl, &heap_allocator, 0x128)); nw4r::g3d::ResNode nd = mdl.GetResNode(sMdlNames[mSubType]); - field_0x3EC.copyFrom((nd.mNode.ref().VEC3_0x44 + nd.mNode.ref().VEC3_0x50) * 0.5f); + field_0x3EC.copyFrom((nd.ref().volume_min + nd.ref().volume_max) * 0.5f); if (mSubType == 4) { nw4r::g3d::ResAnmClr a = mRes.GetResAnmClr("Teniobj_0"); TRY_CREATE(mAnm.create(mdl, a, &heap_allocator, nullptr, 1)); diff --git a/src/REL/d/a/obj/d_a_obj_toD3_stone_figure.cpp b/src/REL/d/a/obj/d_a_obj_toD3_stone_figure.cpp index 2779d032..618eaf3b 100644 --- a/src/REL/d/a/obj/d_a_obj_toD3_stone_figure.cpp +++ b/src/REL/d/a/obj/d_a_obj_toD3_stone_figure.cpp @@ -57,7 +57,7 @@ dCcD_SrcCyl dAcOtoD3StoneFigure_c::sCcSrc = { bool dAcOtoD3StoneFigure_c::createHeap() { const char *modelName = getModelName(); - mResFile = getOarcResFile("BirdObjD3"); + mResFile = nw4r::g3d::ResFile(getOarcResFile("BirdObjD3")); nw4r::g3d::ResMdl mdl = mResFile.GetResMdl(modelName); TRY_CREATE(mMdl.create(mdl, &heap_allocator, 0x120)); return true; diff --git a/src/REL/d/a/obj/d_a_obj_tower_gearD101.cpp b/src/REL/d/a/obj/d_a_obj_tower_gearD101.cpp index 32695a6c..06411982 100644 --- a/src/REL/d/a/obj/d_a_obj_tower_gearD101.cpp +++ b/src/REL/d/a/obj/d_a_obj_tower_gearD101.cpp @@ -8,7 +8,7 @@ #include "f/f_manager.h" #include "f/f_profile_name.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resmdl.h" #include "toBeSorted/room_manager.h" SPECIAL_ACTOR_PROFILE(OBJ_TOWER_GEAR_D101, dAcOTowerGearD101_c, fProfile::OBJ_TOWER_GEAR_D101, 0x17E, 0, 7); @@ -19,7 +19,7 @@ extern "C" void fn_80067340(mVec3_c &, nw4r::g3d::ResMdl *, const char *); bool dAcOTowerGearD101_c::createHeap() { const char *name = "TowerGearD101"; - mRes = getOarcResFile(name); + mRes = nw4r::g3d::ResFile(getOarcResFile(name)); RoomManager::bindStageResToFile(&mRes); nw4r::g3d::ResMdl mdl = mRes.GetResMdl(name); if (!mMdl.create(mdl, &heap_allocator, 0x120, 1, nullptr)) { diff --git a/src/REL/d/a/obj/d_a_obj_tower_hand_D101.cpp b/src/REL/d/a/obj/d_a_obj_tower_hand_D101.cpp index b061e4dc..ddd7498a 100644 --- a/src/REL/d/a/obj/d_a_obj_tower_hand_D101.cpp +++ b/src/REL/d/a/obj/d_a_obj_tower_hand_D101.cpp @@ -11,7 +11,7 @@ #include "m/m_angle.h" #include "m/m_mtx.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "rvl/MTX/mtx.h" #include "rvl/MTX/vec.h" #include "s/s_Math.h" @@ -104,8 +104,8 @@ bool dAcOTowerHandD101_c::createHeap() { if (!isValidDirectionParam(direction)) { return false; } - nw4r::g3d::ResFile res = resP; - if (!res.mFile.IsValid()) { + nw4r::g3d::ResFile res(resP); + if (!res.IsValid()) { return false; } RoomManager::bindStageResToFile(&res); diff --git a/src/REL/d/a/obj/d_a_obj_trap_rock_1.cpp b/src/REL/d/a/obj/d_a_obj_trap_rock_1.cpp index 91edc841..efcdaf44 100644 --- a/src/REL/d/a/obj/d_a_obj_trap_rock_1.cpp +++ b/src/REL/d/a/obj/d_a_obj_trap_rock_1.cpp @@ -13,7 +13,7 @@ STATE_DEFINE(dAcOtrapRock1_c, TrapAction); STATE_DEFINE(dAcOtrapRock1_c, TrapReturn); bool dAcOtrapRock1_c::createHeap() { - mResFile = getOarcResFile("TrapRockRoll"); + mResFile = nw4r::g3d::ResFile(getOarcResFile("TrapRockRoll")); nw4r::g3d::ResMdl m = mResFile.GetResMdl("TrapRockRoll"); TRY_CREATE(mMdl.create(m, &heap_allocator, 0x120)); @@ -97,8 +97,7 @@ void dAcOtrapRock1_c::executeState_TrapAction() { } if (ratio > 1.0f) { ratio = 1.0f; - } - else if (ratio < 0.1f) { + } else if (ratio < 0.1f) { ratio = 0.1f; } s16 newAng = field_0x5A5 * (1.0f - ratio) * field_0x5A2; diff --git a/src/REL/d/a/obj/d_a_obj_triforce.cpp b/src/REL/d/a/obj/d_a_obj_triforce.cpp index 3acc60ee..5046cccf 100644 --- a/src/REL/d/a/obj/d_a_obj_triforce.cpp +++ b/src/REL/d/a/obj/d_a_obj_triforce.cpp @@ -3,6 +3,7 @@ #include "c/c_math.h" #include "d/col/cc/d_cc_s.h" #include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" SPECIAL_ACTOR_PROFILE(OBJ_TRIFORCE, dAcOtriforce_c, fProfile::OBJ_TRIFORCE, 0x15D, 0, 4); @@ -21,7 +22,7 @@ const u32 dAcOtriforce_c::sStartingOffsetRange = 0x10000; // const f32 dAcOtriforce_c::sAmpPos = 23.0f; bool dAcOtriforce_c::createHeap() { - mResFile = getOarcResFile("TriForce"); + mResFile = nw4r::g3d::ResFile(getOarcResFile("TriForce")); nw4r::g3d::ResMdl mdl = mResFile.GetResMdl("TriForce"); TRY_CREATE(mMdl.create(mdl, &heap_allocator, 0x324)); nw4r::g3d::ResAnmTexSrt anm = mResFile.GetResAnmTexSrt("TriForce"); diff --git a/src/REL/d/a/obj/d_a_obj_tubo.cpp b/src/REL/d/a/obj/d_a_obj_tubo.cpp index e037eccb..81c0d2b3 100644 --- a/src/REL/d/a/obj/d_a_obj_tubo.cpp +++ b/src/REL/d/a/obj/d_a_obj_tubo.cpp @@ -60,7 +60,7 @@ dCcD_SrcSph dAcOtubo_c::sSphSrc = { }; bool dAcOtubo_c::createHeap() { - mRes = getOarcResFile("Tubo"); + mRes = nw4r::g3d::ResFile(getOarcResFile("Tubo")); const char *subtype = getSubtype() == 0 ? "Tubo00" : "Tubo01"; TRY_CREATE(mMdl.create(mRes.GetResMdl(subtype), &heap_allocator, 0x120, 1, nullptr)); return true; diff --git a/src/REL/d/a/obj/d_a_obj_tumble_weed.cpp b/src/REL/d/a/obj/d_a_obj_tumble_weed.cpp index 45129dd7..89581a19 100644 --- a/src/REL/d/a/obj/d_a_obj_tumble_weed.cpp +++ b/src/REL/d/a/obj/d_a_obj_tumble_weed.cpp @@ -40,7 +40,7 @@ dCcD_SrcSph dAcOTumbleWeed_c::sSphSrc = { }; bool dAcOTumbleWeed_c::createHeap() { - mResFile = getOarcResFile("GrassRollDry"); + mResFile = nw4r::g3d::ResFile(getOarcResFile("GrassRollDry")); TRY_CREATE(mMdl.create(mResFile.GetResMdl("GrassRollDry"), &heap_allocator, 0x120, 1, nullptr)); return true; } @@ -92,7 +92,6 @@ int dAcOTumbleWeed_c::doDelete() { return SUCCEEDED; } - int dAcOTumbleWeed_c::actorExecute() { if (!mField_0x98C && !isStopped()) { mField_0x968 = velocity; diff --git a/src/REL/d/a/obj/d_a_obj_underground_switch.cpp b/src/REL/d/a/obj/d_a_obj_underground_switch.cpp index 04ab2bf6..d8ef1e7f 100644 --- a/src/REL/d/a/obj/d_a_obj_underground_switch.cpp +++ b/src/REL/d/a/obj/d_a_obj_underground_switch.cpp @@ -5,8 +5,8 @@ #include "d/a/obj/d_a_obj_base.h" #include "d/flag/sceneflag_manager.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resanmclr.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resanmclr.h" +#include "nw4r/g3d/res/g3d_resmdl.h" #include "toBeSorted/event_manager.h" SPECIAL_ACTOR_PROFILE(OBJ_UG_SWITCH, dAcOUgSwitch_c, fProfile::OBJ_UG_SWITCH, 0x15A, 0, 3); @@ -22,11 +22,11 @@ bool dAcOUgSwitch_c::createHeap() { // Why. Regswap... void *data = getOarcResFile("SwitchPass"); - mRes = data; + mRes = nw4r::g3d::ResFile(data); nw4r::g3d::ResMdl mdl = mRes.GetResMdl("SwitchPass"); TRY_CREATE(mMdl.create(mdl, &heap_allocator, 0x120)); - mRes = data; + mRes = nw4r::g3d::ResFile(data); mdl = mRes.GetResMdl("SwitchPass"); nw4r::g3d::ResAnmClr clr = mRes.GetResAnmClr("SwitchPass_Light"); TRY_CREATE(mAnmClr.create(mdl, clr, &heap_allocator, nullptr, 1)); diff --git a/src/REL/d/a/obj/d_a_obj_uta_demo_pedest.cpp b/src/REL/d/a/obj/d_a_obj_uta_demo_pedest.cpp index 4d52eb79..3545cb7f 100644 --- a/src/REL/d/a/obj/d_a_obj_uta_demo_pedest.cpp +++ b/src/REL/d/a/obj/d_a_obj_uta_demo_pedest.cpp @@ -3,7 +3,8 @@ #include "d/a/obj/d_a_obj_base.h" #include "f/f_base.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" #include "toBeSorted/arc_managers/current_stage_arc_manager.h" #include "toBeSorted/room_manager.h" @@ -23,7 +24,7 @@ bool dAcOutaDemoPedest_c::createHeap() { mModelType = 0; } - mRes = CurrentStageArcManager::sInstance->getData("g3d/stage.brres"); + mRes = nw4r::g3d::ResFile(CurrentStageArcManager::sInstance->getData("g3d/stage.brres")); RoomManager::bindStageResToFile(&mRes); RoomManager::bindSkyCmnToResFile(&mRes); nw4r::g3d::ResMdl mdl = mRes.GetResMdl(sMdlNames[mModelType]); diff --git a/src/REL/d/a/obj/d_a_obj_utajima.cpp b/src/REL/d/a/obj/d_a_obj_utajima.cpp index d3248393..09df9cfa 100644 --- a/src/REL/d/a/obj/d_a_obj_utajima.cpp +++ b/src/REL/d/a/obj/d_a_obj_utajima.cpp @@ -23,11 +23,11 @@ void dAcOutajima_c::rideCallback(dBgW *bg, dAcObjBase_c *o1, dAcObjBase_c *o2) { } bool dAcOutajima_c::createHeap() { - mRes = getOarcResFile("IslSon"); + mRes = nw4r::g3d::ResFile(getOarcResFile("IslSon")); RoomManager::bindStageResToFile(&mRes); RoomManager::bindSkyCmnToResFile(&mRes); - nw4r::g3d::ResMdl m = nullptr; + nw4r::g3d::ResMdl m(nullptr); for (int i = 0; i < 2; i++) { m = mRes.GetResMdl(mMdlNames[i]); diff --git a/src/REL/d/a/obj/d_a_obj_utajima_island.cpp b/src/REL/d/a/obj/d_a_obj_utajima_island.cpp index f2d41c08..a85dfd6f 100644 --- a/src/REL/d/a/obj/d_a_obj_utajima_island.cpp +++ b/src/REL/d/a/obj/d_a_obj_utajima_island.cpp @@ -8,7 +8,7 @@ #include "f/f_manager.h" #include "f/f_profile_name.h" #include "m/m_angle.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resmdl.h" #include "s/s_Math.h" #include "toBeSorted/room_manager.h" @@ -24,7 +24,7 @@ const f32 dAcOutajimaIsland_c::floats[] = { }; bool dAcOutajimaIsland_c::createHeap() { - mRes = getOarcResFile("IslPuzIslet00"); + mRes = nw4r::g3d::ResFile(getOarcResFile("IslPuzIslet00")); RoomManager::bindStageResToFile(&mRes); RoomManager::bindSkyCmnToResFile(&mRes); nw4r::g3d::ResMdl m = mRes.GetResMdl("IslPuzIslet00"); diff --git a/src/REL/d/a/obj/d_a_obj_utajima_lv2.cpp b/src/REL/d/a/obj/d_a_obj_utajima_lv2.cpp index 6f99a94a..2c68945a 100644 --- a/src/REL/d/a/obj/d_a_obj_utajima_lv2.cpp +++ b/src/REL/d/a/obj/d_a_obj_utajima_lv2.cpp @@ -10,7 +10,7 @@ SPECIAL_ACTOR_PROFILE(OBJ_UTAJIMA_LV2, dAcOutajimaLv2_c, fProfile::OBJ_UTAJIMA_L const f32 dAcOutajimaLv2_c::someFloat = 100000.0f; bool dAcOutajimaLv2_c::createHeap() { - mRes = getOarcResFile("IslCave"); + mRes = nw4r::g3d::ResFile(getOarcResFile("IslCave")); RoomManager::bindStageResToFile(&mRes); RoomManager::bindSkyCmnToResFile(&mRes); nw4r::g3d::ResMdl mdl = mRes.GetResMdl("IslCave"); diff --git a/src/REL/d/a/obj/d_a_obj_water_shield.cpp b/src/REL/d/a/obj/d_a_obj_water_shield.cpp index c9cbd950..026b627b 100644 --- a/src/REL/d/a/obj/d_a_obj_water_shield.cpp +++ b/src/REL/d/a/obj/d_a_obj_water_shield.cpp @@ -1,11 +1,12 @@ #include "d/a/obj/d_a_obj_water_shield.h" #include "d/col/bg/d_bg_s.h" +#include "nw4r/types_nw4r.h" SPECIAL_ACTOR_PROFILE(OBJ_WATER_SHIELD, dAcOwaterShield_c, fProfile::OBJ_WATER_SHIELD, 0x218, 0, 0); bool dAcOwaterShield_c::createHeap() { - mRes = getOarcResFile("WaterWallF103"); + mRes = nw4r::g3d::ResFile(getOarcResFile("WaterWallF103")); nw4r::g3d::ResMdl mdl = mRes.GetResMdl("WaterWallF103"); TRY_CREATE(mMdl.create(mdl, &heap_allocator, 0x32C)); nw4r::g3d::ResAnmClr clr = mRes.GetResAnmClr("WaterWallF103"); diff --git a/src/d/a/obj/d_a_obj_arrow.cpp b/src/d/a/obj/d_a_obj_arrow.cpp index 0cf14a1c..b44643e6 100644 --- a/src/d/a/obj/d_a_obj_arrow.cpp +++ b/src/d/a/obj/d_a_obj_arrow.cpp @@ -3,6 +3,7 @@ #include "c/c_math.h" #include "d/a/d_a_player.h" #include "d/col/c/c_cc_d.h" +#include "nw4r/types_nw4r.h" SPECIAL_ACTOR_PROFILE(ARROW, dAcArrow_c, fProfile::ARROW, 0x126, 0, 0x80); @@ -44,7 +45,7 @@ bool hitCallback(dAcObjBase_c *i_actorA, cCcD_Obj *i_objInfA, dAcObjBase_c *i_ac } bool dAcArrow_c::createHeap() { - mResFile = getOarcResFile("Alink"); + mResFile = nw4r::g3d::ResFile(getOarcResFile("Alink")); nw4r::g3d::ResMdl mdl(nullptr); if ((mSubType & 0x10) != 0) { mdl = mResFile.GetResMdl("EquipPachinkoBullet"); diff --git a/src/d/a/obj/d_a_obj_switch.cpp b/src/d/a/obj/d_a_obj_switch.cpp index 23052b7f..43546938 100644 --- a/src/d/a/obj/d_a_obj_switch.cpp +++ b/src/d/a/obj/d_a_obj_switch.cpp @@ -4,7 +4,7 @@ #include "d/col/bg/d_bg_s.h" #include "d/col/bg/d_bg_w.h" #include "d/flag/sceneflag_manager.h" -#include "nw4r/g3d/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_Math.h" SPECIAL_ACTOR_PROFILE(OBJ_SW, dAcOsw_c, fProfile::OBJ_SW, 0x12B, 0, 0x1002); @@ -63,12 +63,12 @@ void dAcOsw_c::rideCallback(dBgW *unknown, dAcObjBase_c *actor, dAcObjBase_c *in } bool dAcOsw_c::createHeap() { - nw4r::g3d::ResFile resFile = getOarcResFile(SWITCH_TYPES[mSwitchType]); - nw4r::g3d::ResMdl resMdl = resFile.GetResMdl(SWITCH_TYPES[mSwitchType]); + nw4r::g3d::ResFile resFile(getOarcResFile(SWITCH_TYPES[mSwitchType])); + nw4r::g3d::ResMdl resMdl(resFile.GetResMdl(SWITCH_TYPES[mSwitchType])); TRY_CREATE(mModel.create(resMdl, &heap_allocator, 0x20, 1, nullptr)); - field_0x5E8 = mScale.x * (resMdl.GetResNode("base").mNode.ref().VEC3_0x50.x - - resMdl.GetResNode("base").mNode.ref().VEC3_0x44.x); + field_0x5E8 = + mScale.x * (resMdl.GetResNode("base").ref().volume_max.x - resMdl.GetResNode("base").ref().volume_min.x); cBgD_t *dbzData = (cBgD_t *)getOarcDZB(SWITCH_TYPES[mSwitchType], SWITCH_TYPES[mSwitchType]); PLC *plcData = (PLC *)getOarcPLC(SWITCH_TYPES[mSwitchType], SWITCH_TYPES[mSwitchType]); mScale.set(1.0f, 0.8f, 1.0f); diff --git a/src/d/a/obj/d_a_obj_tbox.cpp b/src/d/a/obj/d_a_obj_tbox.cpp index 78ccd4d4..d62b1169 100644 --- a/src/d/a/obj/d_a_obj_tbox.cpp +++ b/src/d/a/obj/d_a_obj_tbox.cpp @@ -18,11 +18,11 @@ #include "m/m3d/m_scnleaf.h" #include "m/m_mtx.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resanmchr.h" -#include "nw4r/g3d/g3d_resanmtexpat.h" -#include "nw4r/g3d/g3d_resanmtexsrt.h" -#include "nw4r/g3d/g3d_resfile.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resanmchr.h" +#include "nw4r/g3d/res/g3d_resanmtexpat.h" +#include "nw4r/g3d/res/g3d_resanmtexsrt.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" #include "rvl/MTX/mtxvec.h" #include "s/s_Math.h" #include "toBeSorted/arc_managers/oarc_manager.h" @@ -811,8 +811,12 @@ bool dAcTbox_c::isBelowGroundAtPos(f32 height, const mVec3_c &pos) { } dAcTbox_c::dAcTbox_c() - : mStateMgr(*this, sStateID::null), mScnCallback(this), mEvent(*this, nullptr), mTboxListNode(this), - mDowsingTarget(this, DowsingTarget::SLOT_NONE), mGoddessDowsingTarget(this, DowsingTarget::SLOT_NONE) { + : mStateMgr(*this, sStateID::null), + mScnCallback(this), + mEvent(*this, nullptr), + mTboxListNode(this), + mDowsingTarget(this, DowsingTarget::SLOT_NONE), + mGoddessDowsingTarget(this, DowsingTarget::SLOT_NONE) { field_0x120B = 0; field_0x120E = 0; mDoObstructedCheck = false; @@ -842,8 +846,8 @@ bool dAcTbox_c::createHeap() { } if (mVariant == GODDESS) { - nw4r::g3d::ResFile res = data; - if (!res.mFile.IsValid()) { + nw4r::g3d::ResFile res(data); + if (!res.IsValid()) { return false; } nw4r::g3d::ResMdl mdl = mMdl1.getModel().getResMdl(); @@ -851,7 +855,7 @@ bool dAcTbox_c::createHeap() { return false; } nw4r::g3d::ResAnmTexPat anmTexPat = res.GetResAnmTexPat("GoddessTBox"); - if (!anmTexPat.mAnmTexPat.IsValid()) { + if (!anmTexPat.IsValid()) { return false; } if (!mAnmGoddessPat.create(mdl, anmTexPat, &heap_allocator, nullptr, 1)) { @@ -861,7 +865,7 @@ bool dAcTbox_c::createHeap() { u16 goddessTBoxActive = getParams2Lower(); if (StoryflagManager::sInstance->getCounterOrFlag(goddessTBoxActive) && !mHasBeenOpened) { nw4r::g3d::ResAnmTexSrt anmTexSrt = res.GetResAnmTexSrt("GoddessTBox"); - if (!anmTexSrt.mAnmTexSrt.IsValid()) { + if (!anmTexSrt.IsValid()) { return false; } if (!mAnmGoddessTexSrt.create(mdl, anmTexSrt, &heap_allocator, nullptr, 1)) { @@ -870,12 +874,12 @@ bool dAcTbox_c::createHeap() { mMdl1.getModel().setAnm(mAnmGoddessTexSrt); } } else if (mVariant == NORMAL) { - nw4r::g3d::ResFile res = data; - if (!res.mFile.IsValid()) { + nw4r::g3d::ResFile res(data); + if (!res.IsValid()) { return false; } nw4r::g3d::ResAnmClr anmClr = res.GetResAnmClr("TBoxNormalTAppear"); - if (!anmClr.mAnmClr.IsValid()) { + if (!anmClr.IsValid()) { return false; } nw4r::g3d::ResMdl mdl = mMdl1.getModel().getResMdl(); @@ -894,8 +898,8 @@ bool dAcTbox_c::createHeap() { if (fxData == nullptr) { return false; } - nw4r::g3d::ResFile fxRes = fxData; - if (!fxRes.mFile.IsValid()) { + nw4r::g3d::ResFile fxRes(fxData); + if (!fxRes.IsValid()) { return false; } @@ -909,7 +913,7 @@ bool dAcTbox_c::createHeap() { mOpenFxMdl.setPriorityDraw(0x7F, 0x86); nw4r::g3d::ResAnmChr openAnm = fxRes.GetResAnmChr(sOpenAnmChrName); - if (!openAnm.mAnmChr.IsValid()) { + if (!openAnm.IsValid()) { return false; } if (!mAnmChr.create(openMdl, openAnm, &heap_allocator, nullptr)) { @@ -918,7 +922,7 @@ bool dAcTbox_c::createHeap() { mOpenFxMdl.setAnm(mAnmChr); nw4r::g3d::ResAnmTexSrt anmTexSrt = fxRes.GetResAnmTexSrt(sOpenAnmTexSrtName); - if (!anmTexSrt.mAnmTexSrt.IsValid()) { + if (!anmTexSrt.IsValid()) { return false; } if (!mAnmTexSrt1.create(openMdl, anmTexSrt, &heap_allocator, nullptr, 1)) { @@ -927,7 +931,7 @@ bool dAcTbox_c::createHeap() { mOpenFxMdl.setAnm(mAnmTexSrt1); nw4r::g3d::ResAnmClr anmClr = fxRes.GetResAnmClr(sOpenAnmClrName); - if (!anmClr.mAnmClr.IsValid()) { + if (!anmClr.IsValid()) { return false; } if (!mAnmMatClr2.create(openMdl, anmClr, &heap_allocator, nullptr, 1)) { diff --git a/src/d/a/obj/d_a_obj_water_spout.cpp b/src/d/a/obj/d_a_obj_water_spout.cpp index 981d3a86..78c223e0 100644 --- a/src/d/a/obj/d_a_obj_water_spout.cpp +++ b/src/d/a/obj/d_a_obj_water_spout.cpp @@ -4,19 +4,19 @@ #include "d/a/obj/d_a_obj_base.h" #include "m/m3d/m_fanm.h" #include "m/m_vec.h" -#include "nw4r/g3d/g3d_resanmclr.h" -#include "nw4r/g3d/g3d_resanmtexsrt.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resanmclr.h" +#include "nw4r/g3d/res/g3d_resanmtexsrt.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" #include "s/s_State.hpp" - SPECIAL_ACTOR_PROFILE(OBJ_WATER_SPOUT, dAcOwaterSpout_c, fProfile::OBJ_WATER_SPOUT, 0x1DA, 0, 6); STATE_DEFINE(dAcOwaterSpout_c, Wait); bool dAcOwaterSpout_c::createHeap() { void *data = getOarcResFile("FX_WaterColumn"); - mResFile = data; + mResFile = nw4r::g3d::ResFile(data); nw4r::g3d::ResMdl mdl = mResFile.GetResMdl("FX_WaterColumn"); TRY_CREATE(mMdl.create(data, "FX_WaterColumn", "FX_WaterColumn", &heap_allocator, 0x32C)); nw4r::g3d::ResAnmTexSrt anmSrt = mResFile.GetResAnmTexSrt("FX_WaterColumn"); diff --git a/src/m/m3d/m3d.cpp b/src/m/m3d/m3d.cpp index dde2e070..688be98d 100644 --- a/src/m/m3d/m3d.cpp +++ b/src/m/m3d/m3d.cpp @@ -8,9 +8,9 @@ #include "m/m_video.h" #include "nw4r/g3d/g3d_camera.h" #include "nw4r/g3d/g3d_init.h" -#include "nw4r/g3d/g3d_resmat.h" -#include "nw4r/g3d/g3d_resmdl.h" #include "nw4r/g3d/g3d_state.h" +#include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/g3d/res/g3d_resmdl.h" #include "rvl/GX.h" // IWYU pragma: export namespace m3d { @@ -164,7 +164,7 @@ void setCurrentCamera(int id) { } nw4r::g3d::LightSetting *getLightSettingP() { - return internal::l_scnRoot_p->getLightSetting(); + return &internal::l_scnRoot_p->GetLightSetting(); } EGG::LightManager *getLightMgr(int idx) { diff --git a/src/m/m3d/m_anmchr.cpp b/src/m/m3d/m_anmchr.cpp index ea1bd169..b6f112d7 100644 --- a/src/m/m3d/m_anmchr.cpp +++ b/src/m/m3d/m_anmchr.cpp @@ -2,8 +2,7 @@ #include "m/m3d/m3d.h" #include "nw4r/g3d/g3d_anmchr.h" -#include "nw4r/g3d/g3d_resanmchr.h" - +#include "nw4r/g3d/res/g3d_resanmchr.h" namespace m3d { diff --git a/src/m/m3d/m_anmchrblend.cpp b/src/m/m3d/m_anmchrblend.cpp index ff77ac91..8fa48f2e 100644 --- a/src/m/m3d/m_anmchrblend.cpp +++ b/src/m/m3d/m_anmchrblend.cpp @@ -2,8 +2,7 @@ #include "m/m3d/m3d.h" #include "nw4r/g3d/g3d_anmchr.h" -#include "nw4r/g3d/g3d_resanmchr.h" - +#include "nw4r/g3d/res/g3d_resanmchr.h" namespace m3d { diff --git a/src/m/m3d/m_anmmatclr.cpp b/src/m/m3d/m_anmmatclr.cpp index 467d2fde..ef6c8fc8 100644 --- a/src/m/m3d/m_anmmatclr.cpp +++ b/src/m/m3d/m_anmmatclr.cpp @@ -4,7 +4,6 @@ #include "m/m3d/m3d.h" #include "m/m_heap.h" - namespace m3d { anmMatClr_c::child_c::~child_c() {} diff --git a/src/m/m3d/m_anmmdl.cpp b/src/m/m3d/m_anmmdl.cpp index c19887a1..a9e35cff 100644 --- a/src/m/m3d/m_anmmdl.cpp +++ b/src/m/m3d/m_anmmdl.cpp @@ -1,5 +1,7 @@ #include "m/m3d/m_anmmdl.h" +#include "nw4r/g3d/res/g3d_resfile.h" + namespace m3d { mdlAnmChr::~mdlAnmChr() {} @@ -38,8 +40,8 @@ bool mdlAnmChr::create( void *mdlFile, void *anmFile, const char *mdlName, const char *anmName, mdl_c::mdlCallback_c *callback, mAllocator_c *alloc, u32 bufferOption, int nView, u32 *pSize ) { - mMdlFile = mdlFile; - mAnmFile = anmFile; + mMdlFile = nw4r::g3d::ResFile(mdlFile); + mAnmFile = nw4r::g3d::ResFile(anmFile); nw4r::g3d::ResMdl resMdl = mMdlFile.GetResMdl(mdlName); if (!mMdl.create(resMdl, callback, alloc, bufferOption, nView, pSize)) { @@ -47,7 +49,7 @@ bool mdlAnmChr::create( } nw4r::g3d::ResAnmChr resAnm = mAnmFile.GetResAnmChr(anmName); - if (!resAnm.mAnmChr.IsValid()) { + if (!resAnm.IsValid()) { resAnm = mMdlFile.GetResAnmChr(anmName); } u32 oldSize; @@ -75,7 +77,7 @@ bool mdlAnmChr::create( void mdlAnmChr::setAnm(const char *name, playMode_e mode, f32 blend) { nw4r::g3d::ResAnmChr anm = mAnmFile.GetResAnmChr(name); - if (!anm.mAnmChr.IsValid()) { + if (!anm.IsValid()) { anm = mMdlFile.GetResAnmChr(name); } mAnm.setAnm(mMdl, anm, mode); diff --git a/src/m/m3d/m_anmtexpat.cpp b/src/m/m3d/m_anmtexpat.cpp index 088739a9..47665166 100644 --- a/src/m/m3d/m_anmtexpat.cpp +++ b/src/m/m3d/m_anmtexpat.cpp @@ -4,7 +4,6 @@ #include "m/m3d/m3d.h" #include "m/m_heap.h" - namespace m3d { int anmTexPat_c::child_c::getType() const { diff --git a/src/m/m3d/m_anmvis.cpp b/src/m/m3d/m_anmvis.cpp index 39602dcc..a4971388 100644 --- a/src/m/m3d/m_anmvis.cpp +++ b/src/m/m3d/m_anmvis.cpp @@ -2,9 +2,8 @@ #include "m/m3d/m3d.h" #include "nw4r/g3d/g3d_anmvis.h" -#include "nw4r/g3d/g3d_resanmvis.h" -#include "nw4r/g3d/g3d_resmdl.h" - +#include "nw4r/g3d/res/g3d_resanmvis.h" +#include "nw4r/g3d/res/g3d_resmdl.h" namespace m3d { diff --git a/src/m/m3d/m_banm.cpp b/src/m/m3d/m_banm.cpp index 3204f0a1..047e5972 100644 --- a/src/m/m3d/m_banm.cpp +++ b/src/m/m3d/m_banm.cpp @@ -3,7 +3,6 @@ #include "m/m3d/m3d.h" #include "m/m_heap.h" - namespace m3d { banm_c::~banm_c() { banm_c::remove(); @@ -40,7 +39,7 @@ bool banm_c::IsBound() const { if (mpAnmObj == nullptr) { return false; } - return mpAnmObj->TestAnmFlag(nw4r::g3d::AnmObj::ANMFLAG_ISBOUND); + return mpAnmObj->TestAnmFlag(nw4r::g3d::AnmObj::FLAG_ANM_BOUND); } void banm_c::play() {} diff --git a/src/m/m3d/m_bmdl.cpp b/src/m/m3d/m_bmdl.cpp index 9b51d8f6..1eec02e8 100644 --- a/src/m/m3d/m_bmdl.cpp +++ b/src/m/m3d/m_bmdl.cpp @@ -3,7 +3,6 @@ #include "m/m3d/m3d.h" #include "nw4r/g3d/g3d_scnmdl.h" - namespace m3d { bmdl_c::~bmdl_c() { @@ -24,7 +23,7 @@ int bmdl_c::getNodeID(const char *name) const { bool bmdl_c::getNodeWorldMtx(u32 p1, nw4r::math::MTX34 *out) const { return nw4r::g3d::G3dObj::DynamicCast(mpScnLeaf)->GetScnMtxPos( - out, nw4r::g3d::ScnObj::MTX_TYPE_WORLD, p1 + out, nw4r::g3d::ScnObj::MTX_WORLD, p1 ); } diff --git a/src/m/m3d/m_mdl.cpp b/src/m/m3d/m_mdl.cpp index d66c4d65..ddc72f13 100644 --- a/src/m/m3d/m_mdl.cpp +++ b/src/m/m3d/m_mdl.cpp @@ -2,7 +2,7 @@ #include "m/m3d/m3d.h" #include "nw4r/g3d/g3d_scnmdlsmpl.h" - +#include "nw4r/g3d/g3d_scnobj.h" namespace m3d { @@ -17,34 +17,34 @@ mdl_c::mdlCallback_c::~mdlCallback_c() {} void mdl_c::mdlCallback_c::ExecCallbackA( nw4r::g3d::ChrAnmResult *result, nw4r::g3d::ResMdl mdl, nw4r::g3d::FuncObjCalcWorld *o ) { - u16 nodeId = o->GetNodeId(); + u16 nodeId = o->GetCallbackNodeID(); nw4r::g3d::ChrAnmResult *resPtr = &mpNodes[nodeId]; if (mCalcRatio.is0x18() && !mCalcRatio.isEnd()) { if (!mCalcRatio.is0x19()) { *result = *resPtr; } else { - u32 flags = result->mFlags; + u32 flags = result->flags; f32 f2 = mCalcRatio.get0x10(); f32 f1 = mCalcRatio.get0x14(); // TODO clean up this code, what does it even do, why do operators // break if ((flags & 8) == 0) { - result->VEC3_0x4.x = (result->VEC3_0x4.x * f1 + resPtr->VEC3_0x4.x * f2); - result->VEC3_0x4.y = (result->VEC3_0x4.y * f1 + resPtr->VEC3_0x4.y * f2); - result->VEC3_0x4.z = (result->VEC3_0x4.z * f1 + resPtr->VEC3_0x4.z * f2); + result->s.x = (result->s.x * f1 + resPtr->s.x * f2); + result->s.y = (result->s.y * f1 + resPtr->s.y * f2); + result->s.z = (result->s.z * f1 + resPtr->s.z * f2); } else { - result->VEC3_0x4.x = (f1 + resPtr->VEC3_0x4.x * f2); - result->VEC3_0x4.y = (f1 + resPtr->VEC3_0x4.y * f2); - result->VEC3_0x4.z = (f1 + resPtr->VEC3_0x4.z * f2); + result->s.x = (f1 + resPtr->s.x * f2); + result->s.y = (f1 + resPtr->s.y * f2); + result->s.z = (f1 + resPtr->s.z * f2); } nw4r::math::QUAT q1; nw4r::math::QUAT q2; - C_QUATMtx(q1, resPtr->mMtx); + C_QUATMtx(q1, resPtr->rt); if ((flags & 0x20) == 0) { - C_QUATMtx(q2, result->mMtx); + C_QUATMtx(q2, result->rt); } else { q2.x = 0.0f; q2.y = 0.0f; @@ -54,22 +54,22 @@ void mdl_c::mdlCallback_c::ExecCallbackA( C_QUATSlerp(q1, q2, q1, f1); nw4r::math::VEC3 tmp; - tmp.x = result->mMtx._03; - tmp.y = result->mMtx._13; - tmp.z = result->mMtx._23; - PSMTXQuat(result->mMtx, q1); - result->mMtx._03 = tmp.x; - result->mMtx._13 = tmp.y; - result->mMtx._23 = tmp.z; + tmp.x = result->rt._03; + tmp.y = result->rt._13; + tmp.z = result->rt._23; + PSMTXQuat(result->rt, q1); + result->rt._03 = tmp.x; + result->rt._13 = tmp.y; + result->rt._23 = tmp.z; if ((flags & 0x40) == 0) { - result->mMtx._03 = tmp.x * f1; - result->mMtx._13 = tmp.y * f1; - result->mMtx._23 = tmp.z * f1; + result->rt._03 = tmp.x * f1; + result->rt._13 = tmp.y * f1; + result->rt._23 = tmp.z * f1; } - result->mMtx._03 += resPtr->mMtx._03 * f2; - result->mMtx._13 += resPtr->mMtx._13 * f2; - result->mMtx._23 += resPtr->mMtx._23 * f2; - result->mFlags = result->mFlags & ~(0x80000000 | 0x00000040 | 0x00000020 | 0x00000008); + result->rt._03 += resPtr->rt._03 * f2; + result->rt._13 += resPtr->rt._13 * f2; + result->rt._23 += resPtr->rt._23 * f2; + result->flags = result->flags & ~(0x80000000 | 0x00000040 | 0x00000020 | 0x00000008); *resPtr = *result; } } else { @@ -84,11 +84,11 @@ void mdl_c::mdlCallback_c::ExecCallbackA( void mdl_c::mdlCallback_c::ExecCallbackB( nw4r::g3d::WorldMtxManip *m, nw4r::g3d::ResMdl mdl, nw4r::g3d::FuncObjCalcWorld *o ) { - u16 nodeId = o->GetNodeId(); + u16 nodeId = o->GetCallbackNodeID(); if (mpBaseCallback != nullptr) { mpBaseCallback->timingB(nodeId, m, mdl); } - o->SetNodeId((nodeId + 1) % mdl.GetResNodeNumEntries()); + o->SetCallbackNodeID((nodeId + 1) % mdl.GetResNodeNumEntries()); } void mdl_c::mdlCallback_c::ExecCallbackC(nw4r::math::MTX34 *mat, nw4r::g3d::ResMdl mdl, nw4r::g3d::FuncObjCalcWorld *) { @@ -118,10 +118,10 @@ bool mdl_c::mdlCallback_c::create(nw4r::g3d::ResMdl mdl, mAllocator_c *alloc, u3 *pSize = ROUND_UP(bufSize + ROUND_UP(*pSize, 0x04), 0x04); nw4r::g3d::ChrAnmResult *node = mpNodes; for (int i = 0; i < mNumNode; i++) { - node->VEC3_0x4.x = 1.0f; - node->VEC3_0x4.y = 1.0f; - node->VEC3_0x4.z = 1.0f; - PSMTXIdentity(node->mMtx); + node->s.x = 1.0f; + node->s.y = 1.0f; + node->s.z = 1.0f; + PSMTXIdentity(node->rt); node++; } @@ -199,8 +199,8 @@ bool mdl_c::create( } nw4r::g3d::ScnMdlSimple *sMdl; sMdl = nw4r::g3d::G3dObj::DynamicCast(mpScnLeaf); - sMdl->SetCalcWorldCallback(mpCallback); - sMdl->EnableScnMdlCallbackTiming(nw4r::g3d::ScnObj::TIMING_ALL); + sMdl->SetScnMdlCallback(mpCallback); + sMdl->EnableScnMdlCallbackTiming(nw4r::g3d::ScnObj::Timing(0x7)); setCallback(nullptr); return true; } diff --git a/src/m/m3d/m_scnleaf.cpp b/src/m/m3d/m_scnleaf.cpp index d2a36eae..1f0d5721 100644 --- a/src/m/m3d/m_scnleaf.cpp +++ b/src/m/m3d/m_scnleaf.cpp @@ -2,7 +2,6 @@ #include "m/m3d/m3d.h" - namespace m3d { scnLeaf_c::scnLeaf_c() : mpScnLeaf(nullptr) {} @@ -39,23 +38,23 @@ void scnLeaf_c::getScale(nw4r::math::VEC3 *vec) const { } void scnLeaf_c::setLocalMtx(const nw4r::math::MTX34 *mtx) { - mpScnLeaf->SetMtx(nw4r::g3d::ScnObj::MTX_TYPE_LOCAL, mtx); + mpScnLeaf->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, mtx); } void scnLeaf_c::getLocalMtx(nw4r::math::MTX34 *mtx) const { - mpScnLeaf->GetMtx(nw4r::g3d::ScnObj::MTX_TYPE_LOCAL, mtx); + mpScnLeaf->GetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, mtx); } const nw4r::math::MTX34 *scnLeaf_c::getLocalMtx() const { - return mpScnLeaf->GetMtxPtr(nw4r::g3d::ScnObj::MTX_TYPE_LOCAL); + return mpScnLeaf->GetMtxPtr(nw4r::g3d::ScnObj::MTX_LOCAL); } void scnLeaf_c::getWorldMtx(nw4r::math::MTX34 *mtx) const { - mpScnLeaf->GetMtx(nw4r::g3d::ScnObj::MTX_TYPE_WORLD, mtx); + mpScnLeaf->GetMtx(nw4r::g3d::ScnObj::MTX_WORLD, mtx); } void scnLeaf_c::getViewMtx(nw4r::math::MTX34 *mtx) const { - mpScnLeaf->GetMtx(nw4r::g3d::ScnObj::MTX_TYPE_VIEW, mtx); + mpScnLeaf->GetMtx(nw4r::g3d::ScnObj::MTX_VIEW, mtx); } // unofficial diff --git a/src/m/m3d/m_shadow.cpp b/src/m/m3d/m_shadow.cpp index a5a0b010..9a11455c 100644 --- a/src/m/m3d/m_shadow.cpp +++ b/src/m/m3d/m_shadow.cpp @@ -3,12 +3,12 @@ #include "nw4r/g3d/g3d_calcview.h" #include "nw4r/g3d/g3d_draw.h" #include "nw4r/g3d/g3d_draw1mat1shp.h" -#include "nw4r/g3d/g3d_resmat.h" -#include "nw4r/g3d/g3d_resmdl.h" -#include "nw4r/g3d/g3d_resshp.h" #include "nw4r/g3d/g3d_scnmdl.h" #include "nw4r/g3d/g3d_scnmdlsmpl.h" #include "nw4r/g3d/g3d_state.h" +#include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resshp.h" // All of this is completely made up, as we don't have symbols for this TU // (contrary to the rest of m3d and most of nw4r::g3d) @@ -548,7 +548,7 @@ void mShadowChild_c::drawMdl() { g3d::ScnMdl *mdl2 = g3d::G3dObj::DynamicCast(lf->getG3dObject()); - g3d::DrawResMdlReplacement *pRep = mdl2 ? mdl2->GetDrawResMdlReplacement() : nullptr; + g3d::DrawResMdlReplacement *pRep = mdl2 ? &mdl2->GetDrawResMdlReplacement() : nullptr; g3d::DrawResMdlDirectly( mdl->GetResMdl(), viewPosArray, nullptr, nullptr, diff --git a/src/nw4r/g3d/g3d_3dsmax.cpp b/src/nw4r/g3d/g3d_3dsmax.cpp new file mode 100644 index 00000000..3aca9cc6 --- /dev/null +++ b/src/nw4r/g3d/g3d_3dsmax.cpp @@ -0,0 +1,313 @@ +#include + +namespace nw4r { +namespace g3d { +namespace detail { +namespace dcc { +namespace { + +void MakeTexSrtMtx_S(math::MTX34 *pMtx, const TexSrt &rSrt) { + pMtx->_00 = rSrt.Su; + pMtx->_01 = 0.0f; + pMtx->_02 = 0.0f; + pMtx->_03 = 0.5f * (1.0f - rSrt.Su); + + pMtx->_10 = 0.0f; + pMtx->_11 = rSrt.Sv; + pMtx->_12 = 0.0f; + pMtx->_13 = 0.5f * (1.0f - rSrt.Sv); +} + +void MakeTexSrtMtx_R(math::MTX34 *pMtx, const TexSrt &rSrt) { + f32 sinR, cosR; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + pMtx->_00 = cosR; + pMtx->_01 = sinR; + pMtx->_02 = 0.0f; + pMtx->_03 = -0.5f * (cosR + sinR - 1.0f); + + pMtx->_10 = -sinR; + pMtx->_11 = cosR; + pMtx->_12 = 0.0f; + pMtx->_13 = -0.5f * (-sinR + cosR - 1.0f); +} + +void MakeTexSrtMtx_T(math::MTX34 *pMtx, const TexSrt &rSrt) { + pMtx->_00 = 1.0f; + pMtx->_01 = 0.0f; + pMtx->_02 = 0.0f; + pMtx->_03 = -rSrt.Tu; + + pMtx->_10 = 0.0f; + pMtx->_11 = 1.0f; + pMtx->_12 = 0.0f; + pMtx->_13 = rSrt.Tv; +} + +void MakeTexSrtMtx_SR(math::MTX34 *pMtx, const TexSrt &rSrt) { + f32 sinR, cosR; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sucr = rSrt.Su * cosR; + f32 susr = rSrt.Su * sinR; + f32 svcr = rSrt.Sv * cosR; + f32 svsr = rSrt.Sv * sinR; + + pMtx->_00 = sucr; + pMtx->_01 = susr; + pMtx->_02 = 0.0f; + pMtx->_03 = -0.5f * (sucr + susr - 1.0f); + + pMtx->_10 = -svsr; + pMtx->_11 = svcr; + pMtx->_12 = 0.0f; + pMtx->_13 = -0.5f * (-svsr + svcr - 1.0f); +} + +void MakeTexSrtMtx_RT(math::MTX34 *pMtx, const TexSrt &rSrt) { + f32 sinR, cosR; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + pMtx->_00 = cosR; + pMtx->_01 = sinR; + pMtx->_02 = 0.0f; + pMtx->_03 = -cosR * (0.5f + rSrt.Tu) + sinR * (rSrt.Tv - 0.5f) + 0.5f; + + pMtx->_10 = -sinR; + pMtx->_11 = cosR; + pMtx->_12 = 0.0f; + pMtx->_13 = sinR * (0.5f + rSrt.Tu) + cosR * (rSrt.Tv - 0.5f) + 0.5f; +} + +void MakeTexSrtMtx_ST(math::MTX34 *pMtx, const TexSrt &rSrt) { + pMtx->_00 = rSrt.Su; + pMtx->_01 = 0.0f; + pMtx->_02 = 0.0f; + pMtx->_03 = -rSrt.Su * (0.5f + rSrt.Tu) + 0.5f; + + pMtx->_10 = 0.0f; + pMtx->_11 = rSrt.Sv; + pMtx->_12 = 0.0f; + pMtx->_13 = rSrt.Sv * (rSrt.Tv - 0.5f) + 0.5f; +} + +void MakeTexSrtMtx_SRT(math::MTX34 *pMtx, const TexSrt &rSrt) { + f32 sinR, cosR; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sucr = rSrt.Su * cosR; + f32 susr = rSrt.Su * sinR; + f32 svcr = rSrt.Sv * cosR; + f32 svsr = rSrt.Sv * sinR; + + pMtx->_00 = sucr; + pMtx->_01 = susr; + pMtx->_02 = 0.0f; + pMtx->_03 = -sucr * (0.5f + rSrt.Tu) + susr * (rSrt.Tv - 0.5f) + 0.5f; + + pMtx->_10 = -svsr; + pMtx->_11 = svcr; + pMtx->_12 = 0.0f; + pMtx->_13 = svsr * (0.5f + rSrt.Tu) + svcr * (rSrt.Tv - 0.5f) + 0.5f; +} + +void ProductTexSrtMtx_S(math::MTX34 *pMtx, const TexSrt &rSrt) { + pMtx->_00 *= rSrt.Su; + pMtx->_01 *= rSrt.Su; + pMtx->_02 *= rSrt.Su; + pMtx->_03 = rSrt.Su * (pMtx->_03 - 0.5f) + 0.5f; + + pMtx->_10 *= rSrt.Sv; + pMtx->_11 *= rSrt.Sv; + pMtx->_12 *= rSrt.Sv; + pMtx->_13 = rSrt.Sv * (pMtx->_13 - 0.5f) + 0.5f; +} + +void ProductTexSrtMtx_R(math::MTX34 *pMtx, const TexSrt &rSrt) { + f32 sinR, cosR; + f32 _0x, _1x; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + _0x = cosR * pMtx->_00 + sinR * pMtx->_10; + _1x = -sinR * pMtx->_00 + cosR * pMtx->_10; + pMtx->_00 = _0x; + pMtx->_10 = _1x; + + _0x = cosR * pMtx->_01 + sinR * pMtx->_11; + _1x = -sinR * pMtx->_01 + cosR * pMtx->_11; + pMtx->_01 = _0x; + pMtx->_11 = _1x; + + _0x = cosR * pMtx->_02 + sinR * pMtx->_12; + _1x = -sinR * pMtx->_02 + cosR * pMtx->_12; + pMtx->_02 = _0x; + pMtx->_12 = _1x; + + _0x = cosR * (pMtx->_03 - 0.5f) + sinR * (pMtx->_13 - 0.5f) + 0.5f; + _1x = -sinR * (pMtx->_03 - 0.5f) + cosR * (pMtx->_13 - 0.5f) + 0.5f; + pMtx->_03 = _0x; + pMtx->_13 = _1x; +} + +void ProductTexSrtMtx_T(math::MTX34 *pMtx, const TexSrt &rSrt) { + pMtx->_03 -= rSrt.Tu; + pMtx->_13 += rSrt.Tv; +} + +void ProductTexSrtMtx_SR(math::MTX34 *pMtx, const TexSrt &rSrt) { + f32 sinR, cosR; + f32 _0x, _1x; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sucr = rSrt.Su * cosR; + f32 susr = rSrt.Su * sinR; + f32 svcr = rSrt.Sv * cosR; + f32 svsr = rSrt.Sv * sinR; + + _0x = sucr * pMtx->_00 + susr * pMtx->_10; + _1x = -svsr * pMtx->_00 + svcr * pMtx->_10; + pMtx->_00 = _0x; + pMtx->_10 = _1x; + + _0x = sucr * pMtx->_01 + susr * pMtx->_11; + _1x = -svsr * pMtx->_01 + svcr * pMtx->_11; + pMtx->_01 = _0x; + pMtx->_11 = _1x; + + _0x = sucr * pMtx->_02 + susr * pMtx->_12; + _1x = -svsr * pMtx->_02 + svcr * pMtx->_12; + pMtx->_02 = _0x; + pMtx->_12 = _1x; + + _0x = sucr * (pMtx->_03 - 0.5f) + susr * (pMtx->_13 - 0.5f) + 0.5f; + _1x = -svsr * (pMtx->_03 - 0.5f) + svcr * (pMtx->_13 - 0.5f) + 0.5f; + + pMtx->_03 = _0x; + pMtx->_13 = _1x; +} + +void ProductTexSrtMtx_RT(math::MTX34 *pMtx, const TexSrt &rSrt) { + f32 sinR, cosR; + f32 _0x, _1x; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + _0x = cosR * pMtx->_00 + sinR * pMtx->_10; + _1x = -sinR * pMtx->_00 + cosR * pMtx->_10; + pMtx->_00 = _0x; + pMtx->_10 = _1x; + + _0x = cosR * pMtx->_01 + sinR * pMtx->_11; + _1x = -sinR * pMtx->_01 + cosR * pMtx->_11; + pMtx->_01 = _0x; + pMtx->_11 = _1x; + + _0x = cosR * pMtx->_02 + sinR * pMtx->_12; + _1x = -sinR * pMtx->_02 + cosR * pMtx->_12; + pMtx->_02 = _0x; + pMtx->_12 = _1x; + + _0x = cosR * (pMtx->_03 - rSrt.Tu - 0.5f) + sinR * (pMtx->_13 + rSrt.Tv - 0.5f) + 0.5f; + + _1x = -sinR * (pMtx->_03 - rSrt.Tu - 0.5f) + cosR * (pMtx->_13 + rSrt.Tv - 0.5f) + 0.5f; + + pMtx->_03 = _0x; + pMtx->_13 = _1x; +} + +void ProductTexSrtMtx_ST(math::MTX34 *pMtx, const TexSrt &rSrt) { + pMtx->_00 *= rSrt.Su; + pMtx->_01 *= rSrt.Su; + pMtx->_02 *= rSrt.Su; + pMtx->_03 = rSrt.Su * (pMtx->_03 - rSrt.Tu - 0.5f) + 0.5f; + + pMtx->_10 *= rSrt.Sv; + pMtx->_11 *= rSrt.Sv; + pMtx->_12 *= rSrt.Sv; + pMtx->_13 *= rSrt.Sv * (pMtx->_13 + rSrt.Tv - 0.5f) + 0.5f; +} + +void ProductTexSrtMtx_SRT(math::MTX34 *pMtx, const TexSrt &rSrt) { + f32 sinR, cosR; + f32 _0x, _1x; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sucr = rSrt.Su * cosR; + f32 susr = rSrt.Su * sinR; + f32 svcr = rSrt.Sv * cosR; + f32 svsr = rSrt.Sv * sinR; + + _0x = sucr * pMtx->_00 + susr * pMtx->_10; + _1x = -svsr * pMtx->_00 + svcr * pMtx->_10; + pMtx->_00 = _0x; + pMtx->_10 = _1x; + + _0x = sucr * pMtx->_01 + susr * pMtx->_11; + _1x = -svsr * pMtx->_01 + svcr * pMtx->_11; + pMtx->_01 = _0x; + pMtx->_11 = _1x; + + _0x = sucr * pMtx->_02 + susr * pMtx->_12; + _1x = -svsr * pMtx->_02 + svcr * pMtx->_12; + pMtx->_02 = _0x; + pMtx->_12 = _1x; + + _0x = sucr * (pMtx->_03 - rSrt.Tu - 0.5f) + susr * (pMtx->_13 + rSrt.Tv - 0.5f) + 0.5f; + + _1x = -svsr * (pMtx->_03 - rSrt.Tu - 0.5f) + svcr * (pMtx->_13 + rSrt.Tv - 0.5f) + 0.5f; + + pMtx->_03 = _0x; + pMtx->_13 = _1x; +} + +} // namespace + +typedef void (*CalcTexMtxFunc)(math::MTX34 *pMtx, const TexSrt &rSrt); + +bool CalcTexMtx_3dsmax(math::MTX34 *pMtx, bool set, const TexSrt &rSrt, TexSrt::Flag flag) { + // Extract S/R/T flags + u32 index = flag >> 1 & 0b111; + + // Scale-one, no rotate/trans + if (index == 0b111) { + return false; + } + + if (set) { + static const CalcTexMtxFunc funcTable[] = { + MakeTexSrtMtx_SRT, // 0 0 0 + MakeTexSrtMtx_RT, // 0 0 1 + MakeTexSrtMtx_ST, // 0 1 0 + MakeTexSrtMtx_T, // 0 1 1 + MakeTexSrtMtx_SR, // 1 0 0 + MakeTexSrtMtx_R, // 1 0 1 + MakeTexSrtMtx_S // 1 1 0 + }; + + funcTable[index](pMtx, rSrt); + } else { + static const CalcTexMtxFunc funcTable[] = { + ProductTexSrtMtx_SRT, // 0 0 0 + ProductTexSrtMtx_RT, // 0 0 1 + ProductTexSrtMtx_ST, // 0 1 0 + ProductTexSrtMtx_T, // 0 1 1 + ProductTexSrtMtx_SR, // 1 0 0 + ProductTexSrtMtx_R, // 1 0 1 + ProductTexSrtMtx_S // 1 1 0 + }; + + funcTable[index](pMtx, rSrt); + } + + pMtx->_20 = 0.0f; + pMtx->_21 = 0.0f; + pMtx->_22 = 1.0f; + pMtx->_23 = 0.0f; + + return true; +} + +} // namespace dcc +} // namespace detail +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_anmchr.cpp b/src/nw4r/g3d/g3d_anmchr.cpp new file mode 100644 index 00000000..82d64f82 --- /dev/null +++ b/src/nw4r/g3d/g3d_anmchr.cpp @@ -0,0 +1,764 @@ +#include + +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(AnmObjChr); +NW4R_G3D_RTTI_DEF(AnmObjChrNode); +NW4R_G3D_RTTI_DEF(AnmObjChrBlend); +NW4R_G3D_RTTI_DEF(AnmObjChrRes); + +namespace { + +u32 GetPartialNodeEndId(const ResMdl mdl, u32 target) { + ResNode targetNode = mdl.GetResNode(target); + ResNode node = targetNode; + + ResNode endNode = node.GetNextSibling(); + while (!endNode.IsValid()) { + node = node.GetParentNode(); + if (!node.IsValid()) { + break; + } + + endNode = node.GetNextSibling(); + } + + if (endNode.IsValid()) { + return endNode.GetID(); + } + + return mdl.GetResNodeNumEntries(); +} + +} // namespace + +/****************************************************************************** + * + * AnmObjChr + * + ******************************************************************************/ +AnmObjChr::AnmObjChr(MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding) + : AnmObj(pAllocator, NULL), mNumBinding(numBinding), mpBinding(pBindingBuf) { + Release(); +} + +bool AnmObjChr::TestExistence(u32 idx) const { + return !(mpBinding[idx] & (BINDING_UNDEFINED | BINDING_INVALID)); +} + +bool AnmObjChr::TestDefined(u32 idx) const { + return !(mpBinding[idx] & BINDING_UNDEFINED); +} + +void AnmObjChr::Release() { + for (int i = 0; i < mNumBinding; i++) { + mpBinding[i] = BINDING_UNDEFINED; + } + + SetAnmFlag(FLAG_ANM_BOUND, false); +} + +AnmObjChrRes *AnmObjChr::Attach(int idx, AnmObjChrRes *pRes) { +#pragma unused(idx) +#pragma unused(pRes) + + return NULL; +} + +AnmObjChrRes *AnmObjChr::Detach(int idx) { +#pragma unused(idx) + + return NULL; +} + +void AnmObjChr::SetWeight(int idx, f32 weight){ +#pragma unused(idx) +#pragma unused(weight) +} + +f32 AnmObjChr::GetWeight(int idx) const { +#pragma unused(idx) + + return 0.0f; +} + +void AnmObjChr::DetachAll() {} + +/****************************************************************************** + * + * AnmObjChrNode + * + ******************************************************************************/ +AnmObjChrNode::AnmObjChrNode( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjChrRes **ppChildrenBuf, int numChildren +) + : AnmObjChr(pAllocator, pBindingBuf, numBinding), mChildrenArraySize(numChildren), mpChildrenArray(ppChildrenBuf) { + for (int i = 0; i < mChildrenArraySize; i++) { + mpChildrenArray[i] = NULL; + } +} + +AnmObjChrNode::~AnmObjChrNode() { + DetachAll(); +} + +AnmObjChrRes *AnmObjChrNode::Attach(int idx, AnmObjChrRes *pRes) { + AnmObjChrRes *pOld = Detach(idx); + bool hasAnm = false; + + for (u32 i = 0; i < mNumBinding; i++) { + if (!pRes->TestDefined(i)) { + continue; + } + + hasAnm = true; + mpBinding[i] = 0; + } + + if (hasAnm) { + SetAnmFlag(FLAG_ANM_BOUND, true); + } + + mpChildrenArray[idx] = pRes; + pRes->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + return pOld; +} + +AnmObjChrRes *AnmObjChrNode::Detach(int idx) { + AnmObjChrRes *pOld = mpChildrenArray[idx]; + + if (pOld != NULL) { + pOld->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpChildrenArray[idx] = NULL; + + bool hasAnm = false; + for (u32 i = 0; i < mNumBinding; i++) { + u16 binding = BINDING_UNDEFINED; + + for (int j = 0; j < mChildrenArraySize; j++) { + AnmObjChrRes *pChild = mpChildrenArray[j]; + + if (pChild == NULL || !pChild->TestDefined(i)) { + continue; + } + + hasAnm = true; + binding = 0; + break; + } + + mpBinding[i] = binding; + } + + if (!hasAnm) { + SetAnmFlag(FLAG_ANM_BOUND, false); + } + } + + return pOld; +} + +void AnmObjChrNode::DetachAll() { + for (int i = 0; i < mChildrenArraySize; i++) { + Detach(i); + } +} + +void AnmObjChrNode::UpdateFrame() { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->UpdateFrame(); + } + } +} + +void AnmObjChrNode::SetFrame(f32 frame) { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->SetFrame(frame); + } + } +} + +f32 AnmObjChrNode::GetFrame() const { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + return mpChildrenArray[i]->GetFrame(); + } + } + + return 0.0f; +} + +void AnmObjChrNode::SetUpdateRate(f32 rate) { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->SetUpdateRate(rate); + } + } +} + +f32 AnmObjChrNode::GetUpdateRate() const { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + return mpChildrenArray[i]->GetUpdateRate(); + } + } + + return 1.0f; +} + +bool AnmObjChrNode::Bind(const ResMdl mdl) { + bool success = false; + + for (int i = 0; i < mChildrenArraySize; i++) { + AnmObjChrRes *pChild = mpChildrenArray[i]; + if (pChild == NULL) { + continue; + } + + bool childSuccess = pChild->Bind(mdl); + success = success || childSuccess; + + for (u32 j = 0; j < mNumBinding; j++) { + if (pChild->TestDefined(j)) { + mpBinding[j] = 0; + } + } + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +bool AnmObjChrNode::Bind(const ResMdl mdl, u32 target, BindOption option) { + bool success = false; + + for (int i = 0; i < mChildrenArraySize; i++) { + AnmObjChrRes *pChild = mpChildrenArray[i]; + if (pChild == NULL) { + continue; + } + + bool childSuccess = pChild->Bind(mdl, target, option); + success = success || childSuccess; + + for (u32 j = 0; j < mNumBinding; j++) { + if (pChild->TestDefined(j)) { + mpBinding[j] = 0; + } + } + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +void AnmObjChrNode::Release() { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->Release(); + } + } + + AnmObjChr::Release(); +} + +void AnmObjChrNode::Release(const ResMdl mdl, u32 target, BindOption option) { + for (int i = 0; i < mChildrenArraySize; i++) { + AnmObjChrRes *pChild = mpChildrenArray[i]; + + if (pChild != NULL) { + pChild->Release(mdl, target, option); + } + } + + AnmObjChr::Release(); + + for (int i = 0; i < mChildrenArraySize; i++) { + AnmObjChrRes *pChild = mpChildrenArray[i]; + if (pChild == NULL) { + continue; + } + + for (u32 j = 0; j < mNumBinding; j++) { + if (pChild->TestDefined(j)) { + mpBinding[j] = 0; + } + } + } +} + +void AnmObjChrNode::G3dProc(u32 task, u32 param, void *pInfo) { +#pragma unused(param) + + switch (task) { + case G3DPROC_CHILD_DETACHED: { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] == pInfo) { + Detach(i); + return; + } + } + + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + } +} + +/****************************************************************************** + * + * AnmObjChrBlend + * + ******************************************************************************/ +AnmObjChrBlend *AnmObjChrBlend::Construct(MEMAllocator *pAllocator, u32 *pSize, ResMdl mdl, int numChildren) { + if (!mdl.IsValid()) { + return NULL; + } + + int bindNum = mdl.GetResNodeNumEntries(); + + u32 bindSize = bindNum * sizeof(u16); + u32 childrenSize = numChildren * sizeof(AnmObjChrRes *); + u32 weightSize = numChildren * sizeof(f32); + + u32 bindOfs = ut::RoundUp(sizeof(AnmObjChrBlend), 4); + u32 childrenOfs = ut::RoundUp(bindOfs + bindSize, 4); + u32 weightOfs = ut::RoundUp(childrenOfs + childrenSize, 4); + + u32 size = ut::RoundUp(weightOfs + weightSize, 4); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator == NULL) { + return NULL; + } + + u8 *pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + // clang-format off + return new (pBuffer) AnmObjChrBlend( + pAllocator, + reinterpret_cast(pBuffer + bindOfs), + bindNum, + reinterpret_cast(pBuffer + childrenOfs), + numChildren, + reinterpret_cast(pBuffer + weightOfs)); + // clang-format on +} + +AnmObjChrBlend::AnmObjChrBlend( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjChrRes **ppChildrenBuf, int numChildren, + f32 *pWeightBuf +) + : AnmObjChrNode(pAllocator, pBindingBuf, numBinding, ppChildrenBuf, numChildren), mpWeightArray(pWeightBuf) { + for (int i = 0; i < mChildrenArraySize; i++) { + mpWeightArray[i] = 1.0f; + } +} + +const ChrAnmResult *AnmObjChrBlend::GetResult(ChrAnmResult *pResult, u32 idx) { + AnmObjChrRes *pFirstChild = NULL; + int blendNum = 0; + f32 weightSum = 0.0f; + + for (u32 i = 0; static_cast(i) < mChildrenArraySize; i++) { + f32 weight = mpWeightArray[i]; + AnmObjChrRes *pChild = mpChildrenArray[i]; + + if (pChild == NULL) { + continue; + } + + if (weight == 0.0f || !pChild->TestExistence(idx)) { + continue; + } + + blendNum++; + weightSum += weight; + + if (pFirstChild == NULL) { + pFirstChild = pChild; + } + } + + if (blendNum == 0) { + pResult->flags = 0; + return pResult; + } + + if (blendNum == 1) { + return pFirstChild->GetResult(pResult, idx); + } + + bool useQuat = TestAnmFlag(FLAG_USE_QUATERNION_ROTATION_BLEND); + bool useAccScale = TestAnmFlag(FLAG_USE_ACCURATE_SCALE_BLEND); + + f32 esx = 0.0f; + f32 esy = 0.0f; + f32 esz = 0.0f; + math::QUAT rot(0.0f, 0.0f, 0.0f, 1.0f); + + f32 addedWeight = 0.0f; + math::MTX33 firstRot; + f32 invWeightSum = math::FInv(weightSum); + + pResult->flags = 0xFFFFFFFF; + pResult->s.x = 0.0f; + pResult->s.y = 0.0f; + pResult->s.z = 0.0f; + math::MTX34Zero(&pResult->rt); + + for (int i = 0; i < mChildrenArraySize; i++) { + ChrAnmResult resultBuf; + + AnmObjChrRes *pChild = mpChildrenArray[i]; + f32 weight = mpWeightArray[i]; + + if (pChild == NULL || weight == 0.0f || !pChild->TestExistence(idx)) { + continue; + } + + const ChrAnmResult *pMyResult = pChild->GetResult(&resultBuf, idx); + + f32 ratio = weight * invWeightSum; + u32 flags = pMyResult->flags; + + if (useAccScale) { + if (!(flags & ChrAnmResult::FLAG_SCALE_ONE)) { + esx += ratio * math::FLog(pMyResult->s.x); + esy += ratio * math::FLog(pMyResult->s.y); + esz += ratio * math::FLog(pMyResult->s.z); + } + } else if (!(flags & ChrAnmResult::FLAG_SCALE_ONE)) { + pResult->s.x += pMyResult->s.x * ratio; + pResult->s.y += pMyResult->s.y * ratio; + pResult->s.z += pMyResult->s.z * ratio; + } else { + pResult->s.x += ratio; + pResult->s.y += ratio; + pResult->s.z += ratio; + } + + if (useQuat) { + math::QUAT q; + + if (!(flags & ChrAnmResult::FLAG_ROT_ZERO)) { + math::MTX34ToQUAT(&q, &pMyResult->rt); + } else { + q.x = 0.0f; + q.y = 0.0f; + q.z = 0.0f; + q.w = 1.0f; + } + + addedWeight += weight; + f32 invAddedWeight = math::FInv(addedWeight); + + f32 t = weight * invAddedWeight; + math::C_QUATSlerp(&rot, &rot, &q, t); + } else if (!(flags & ChrAnmResult::FLAG_ROT_ZERO)) { + pResult->rt._00 += pMyResult->rt._00 * ratio; + pResult->rt._01 += pMyResult->rt._01 * ratio; + pResult->rt._02 += pMyResult->rt._02 * ratio; + + pResult->rt._10 += pMyResult->rt._10 * ratio; + pResult->rt._11 += pMyResult->rt._11 * ratio; + pResult->rt._12 += pMyResult->rt._12 * ratio; + } else { + pResult->rt._00 += ratio; + pResult->rt._11 += ratio; + } + + if (!(flags & ChrAnmResult::FLAG_TRANS_ZERO)) { + pResult->rt._03 += pMyResult->rt._03 * ratio; + pResult->rt._13 += pMyResult->rt._13 * ratio; + pResult->rt._23 += pMyResult->rt._23 * ratio; + } + + pResult->flags &= flags; + } + + if (useAccScale) { + pResult->s.x = math::FExp(esx); + pResult->s.y = math::FExp(esy); + pResult->s.z = math::FExp(esz); + } + + if (useQuat) { + Vec t; + t.x = pResult->rt._03; + t.y = pResult->rt._13; + t.z = pResult->rt._23; + + math::QUATToMTX34(&pResult->rt, &rot); + + pResult->rt._03 = t.x; + pResult->rt._13 = t.y; + pResult->rt._23 = t.z; + } else { + math::VEC3 *pV0 = reinterpret_cast(&pResult->rt._00); + math::VEC3 *pV1 = reinterpret_cast(&pResult->rt._10); + math::VEC3 *pV2 = reinterpret_cast(&pResult->rt._20); + math::VEC3Cross(pV2, pV0, pV1); + + math::VEC3Normalize(pV0, pV0); + math::VEC3Normalize(pV2, pV2); + math::VEC3Cross(pV1, pV2, pV0); + } + + pResult->flags &= ~ChrAnmResult::FLAG_ROT_RAW_FMT; + return pResult; +} + +void AnmObjChrBlend::SetWeight(int idx, f32 weight) { + mpWeightArray[idx] = weight; +} + +f32 AnmObjChrBlend::GetWeight(int idx) const { + return mpWeightArray[idx]; +} + +/****************************************************************************** + * + * AnmObjChrRes + * + ******************************************************************************/ +AnmObjChrRes *AnmObjChrRes::Construct(MEMAllocator *pAllocator, u32 *pSize, ResAnmChr chr, ResMdl mdl, bool cache) { + if (!chr.IsValid() || !mdl.IsValid()) { + return NULL; + } + + int numAnim = chr.GetNumNode(); + int numMat = mdl.GetResNodeNumEntries(); + + int bindNum = numMat; + int cacheNum = cache ? numAnim : 0; + + u32 bindSize = bindNum * sizeof(u16); + u32 cacheSize = cacheNum * sizeof(ChrAnmResult); + + u32 size = bindSize + cacheSize + sizeof(AnmObjChrRes); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator == NULL) { + return NULL; + } + + u8 *pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + ChrAnmResult *pCacheBuf = cache ? reinterpret_cast(pBuffer + sizeof(AnmObjChrRes)) : NULL; + + u16 *pBindingBuf = reinterpret_cast(cacheSize + (pBuffer + sizeof(AnmObjChrRes))); + + return new (pBuffer) AnmObjChrRes(pAllocator, chr, pBindingBuf, bindNum, pCacheBuf); +} + +AnmObjChrRes::AnmObjChrRes( + MEMAllocator *pAllocator, ResAnmChr chr, u16 *pBindingBuf, int numBinding, ChrAnmResult *pCacheBuf +) + : AnmObjChr(pAllocator, pBindingBuf, numBinding), + FrameCtrl(0.0f, chr.GetNumFrame(), GetAnmPlayPolicy(chr.GetAnmPolicy())), + mRes(chr), + mpResultCache(pCacheBuf) { + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +void AnmObjChrRes::SetFrame(f32 frame) { + SetFrm(frame); + + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +f32 AnmObjChrRes::GetFrame() const { + return GetFrm(); +} + +void AnmObjChrRes::SetUpdateRate(f32 rate) { + SetRate(rate); +} + +f32 AnmObjChrRes::GetUpdateRate() const { + return GetRate(); +} + +void AnmObjChrRes::UpdateFrame() { + UpdateFrm(); + + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +bool AnmObjChrRes::Bind(const ResMdl mdl) { + int numAnim = mRes.GetNumNode(); + bool success = false; + + for (u16 i = 0; i < numAnim; i++) { + const ResAnmChrNodeData *pData = mRes.GetNodeAnm(i); + + // Seek back from name string to start of ResName + ResName name(ut::AddOffsetToPtr(pData, pData->name - 4)); + + ResNode node = mdl.GetResNode(name); + if (!node.IsValid()) { + continue; + } + + mpBinding[node.GetID()] = i; + success = true; + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +bool AnmObjChrRes::Bind(const ResMdl mdl, u32 target, BindOption option) { + bool success = false; + + switch (option) { + case BIND_PARTIAL: { + u32 bindBegin = target; + u32 bindEnd = GetPartialNodeEndId(mdl, bindBegin); + + for (u32 i = bindBegin; i < bindEnd; i++) { + ResNode node = mdl.GetResNode(i); + ResName name = node.GetResName(); + + int id = mRes.GetNodeAnmIndex(name); + if (id != ResDic::NOT_FOUND) { + mpBinding[i] = static_cast(id); + success = true; + } + } + + break; + } + + case BIND_ONE: { + ResNode node = mdl.GetResNode(target); + ResName name = node.GetResName(); + + int id = mRes.GetNodeAnmIndex(name); + if (id != ResDic::NOT_FOUND) { + mpBinding[target] = static_cast(id); + success = true; + } + break; + } + + default: { + break; + } + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +void AnmObjChrRes::Release(const ResMdl mdl, u32 target, BindOption option) { + switch (option) { + case BIND_PARTIAL: { + u32 bindBegin = target; + u32 bindEnd = GetPartialNodeEndId(mdl, bindBegin); + + for (u32 i = bindBegin; i < bindEnd; i++) { + mpBinding[i] = BINDING_UNDEFINED; + } + + break; + } + + case BIND_ONE: { + mpBinding[target] = BINDING_UNDEFINED; + break; + } + + default: { + break; + } + } +} + +const ChrAnmResult *AnmObjChrRes::GetResult(ChrAnmResult *pResult, u32 idx) { + u32 id = mpBinding[idx]; + + if (id & (BINDING_UNDEFINED | BINDING_INVALID)) { + pResult->flags = 0; + return pResult; + } + + if (mpResultCache != NULL) { + return &mpResultCache[id]; + } + + mRes.GetAnmResult(pResult, id, GetFrm()); + return pResult; +} + +void AnmObjChrRes::UpdateCache() { + f32 frame = GetFrm(); + + for (u32 i = 0; i < mNumBinding; i++) { + u16 bind = mpBinding[i]; + + if (!(bind & BINDING_UNDEFINED)) { + u32 id = bind & BINDING_ID_MASK; + mRes.GetAnmResult(&mpResultCache[id], id, frame); + } + } +} + +void AnmObjChrRes::G3dProc(u32 task, u32 param, void *pInfo) { +#pragma unused(param) + + switch (task) { + case G3DPROC_UPDATEFRAME: { + UpdateFrame(); + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_anmclr.cpp b/src/nw4r/g3d/g3d_anmclr.cpp new file mode 100644 index 00000000..8a7585c8 --- /dev/null +++ b/src/nw4r/g3d/g3d_anmclr.cpp @@ -0,0 +1,600 @@ +#include + +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(AnmObjMatClr); +NW4R_G3D_RTTI_DEF(AnmObjMatClrNode); +NW4R_G3D_RTTI_DEF(AnmObjMatClrOverride); +NW4R_G3D_RTTI_DEF(AnmObjMatClrRes); + +/****************************************************************************** + * + * AnmObjMatClr + * + ******************************************************************************/ +AnmObjMatClr::AnmObjMatClr(MEMAllocator* pAllocator, u16* pBindingBuf, + int numBinding) + : AnmObj(pAllocator, NULL), + mNumBinding(numBinding), + mpBinding(pBindingBuf) { + + Release(); +} + +bool AnmObjMatClr::TestExistence(u32 idx) const { + return !(mpBinding[idx] & (BINDING_UNDEFINED | BINDING_INVALID)); +} + +bool AnmObjMatClr::TestDefined(u32 idx) const { + return !(mpBinding[idx] & BINDING_UNDEFINED); +} + +void AnmObjMatClr::Release() { + for (int i = 0; i < mNumBinding; i++) { + mpBinding[i] = BINDING_UNDEFINED; + } + + SetAnmFlag(FLAG_ANM_BOUND, false); +} + +AnmObjMatClrRes* AnmObjMatClr::Attach(int idx, AnmObjMatClrRes* pRes) { +#pragma unused(idx) +#pragma unused(pRes) + + return NULL; +} + +AnmObjMatClrRes* AnmObjMatClr::Detach(int idx) { +#pragma unused(idx) + + return NULL; +} + +void AnmObjMatClr::DetachAll() {} + +/****************************************************************************** + * + * AnmObjMatClrNode + * + ******************************************************************************/ +AnmObjMatClrNode::AnmObjMatClrNode(MEMAllocator* pAllocator, u16* pBindingBuf, + int numBinding, + AnmObjMatClrRes** ppChildrenBuf, + int numChildren) + : AnmObjMatClr(pAllocator, pBindingBuf, numBinding), + mChildrenArraySize(numChildren), + mpChildrenArray(ppChildrenBuf) { + + for (int i = 0; i < mChildrenArraySize; i++) { + mpChildrenArray[i] = NULL; + } +} + +AnmObjMatClrNode::~AnmObjMatClrNode() { + DetachAll(); +} + +AnmObjMatClrRes* AnmObjMatClrNode::Attach(int idx, AnmObjMatClrRes* pRes) { + AnmObjMatClrRes* pOld = Detach(idx); + bool hasAnm = false; + + for (u32 i = 0; i < mNumBinding; i++) { + if (!pRes->TestDefined(i)) { + continue; + } + + hasAnm = true; + mpBinding[i] = 0; + } + + if (hasAnm) { + SetAnmFlag(FLAG_ANM_BOUND, true); + } + + mpChildrenArray[idx] = pRes; + pRes->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + return pOld; +} + +AnmObjMatClrRes* AnmObjMatClrNode::Detach(int idx) { + AnmObjMatClrRes* pOld = mpChildrenArray[idx]; + + if (pOld != NULL) { + pOld->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpChildrenArray[idx] = NULL; + + bool hasAnm = false; + for (u32 i = 0; i < mNumBinding; i++) { + u16 binding = BINDING_UNDEFINED; + + for (int j = 0; j < mChildrenArraySize; j++) { + AnmObjMatClrRes* pChild = mpChildrenArray[j]; + + if (pChild == NULL || !pChild->TestDefined(i)) { + continue; + } + + hasAnm = true; + binding = 0; + break; + } + + mpBinding[i] = binding; + } + + if (!hasAnm) { + SetAnmFlag(FLAG_ANM_BOUND, false); + } + } + + return pOld; +} + +void AnmObjMatClrNode::DetachAll() { + for (int i = 0; i < mChildrenArraySize; i++) { + Detach(i); + } +} + +void AnmObjMatClrNode::UpdateFrame() { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->UpdateFrame(); + } + } +} + +void AnmObjMatClrNode::SetFrame(f32 frame) { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->SetFrame(frame); + } + } +} + +f32 AnmObjMatClrNode::GetFrame() const { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + return mpChildrenArray[i]->GetFrame(); + } + } + + return 0.0f; +} + +void AnmObjMatClrNode::SetUpdateRate(f32 rate) { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->SetUpdateRate(rate); + } + } +} + +f32 AnmObjMatClrNode::GetUpdateRate() const { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + return mpChildrenArray[i]->GetUpdateRate(); + } + } + + return 1.0f; +} + +bool AnmObjMatClrNode::Bind(const ResMdl mdl) { + bool success = false; + + for (int i = 0; i < mChildrenArraySize; i++) { + AnmObjMatClrRes* pChild = mpChildrenArray[i]; + if (pChild == NULL) { + continue; + } + + bool childSuccess = pChild->Bind(mdl); + success = success || childSuccess; + + for (u32 j = 0; j < mNumBinding; j++) { + if (pChild->TestDefined(j)) { + mpBinding[j] = 0; + } + } + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +void AnmObjMatClrNode::Release() { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->Release(); + } + } + + AnmObjMatClr::Release(); +} + +void AnmObjMatClrNode::G3dProc(u32 task, u32 param, void* pInfo) { +#pragma unused(param) + + switch (task) { + case G3DPROC_CHILD_DETACHED: { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] == pInfo) { + Detach(i); + return; + } + } + + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + } +} + +/****************************************************************************** + * + * AnmObjMatClrOverride + * + ******************************************************************************/ +AnmObjMatClrOverride* AnmObjMatClrOverride::Construct(MEMAllocator* pAllocator, + u32* pSize, ResMdl mdl, + int numChildren) { + if (!mdl.IsValid()) { + return NULL; + } + + int numAnim = mdl.GetResMatNumEntries(); + int bindNum = numAnim; + + u32 objSize = sizeof(AnmObjMatClrOverride); + u32 bindSize = bindNum * sizeof(u16); + u32 childrenSize = numChildren * sizeof(AnmObjMatClrRes*); + + u32 bindOfs = align4(objSize); + u32 childrenOfs = align4(bindOfs + bindSize); + + u32 size = align4(childrenOfs + childrenSize); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator == NULL) { + return NULL; + } + + u8* pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + // clang-format off + return new (pBuffer) AnmObjMatClrOverride( + pAllocator, + reinterpret_cast(pBuffer + bindOfs), + bindNum, + reinterpret_cast(pBuffer + childrenOfs), + numChildren); + // clang-format on +} + +const ClrAnmResult* AnmObjMatClrOverride::GetResult(ClrAnmResult* pResult, + u32 idx) { + for (int i = mChildrenArraySize - 1; i >= 0; i--) { + AnmObjMatClrRes* pChild = mpChildrenArray[i]; + + if (pChild == NULL || !pChild->TestExistence(idx)) { + continue; + } + + const ClrAnmResult* pChildResult = pChild->GetResult(pResult, idx); + + if (pChildResult->bRgbaExist != 0) { + return pChildResult; + } + } + + pResult->bRgbaExist = 0; + return pResult; +} + +/****************************************************************************** + * + * AnmObjMatClrRes + * + ******************************************************************************/ +AnmObjMatClrRes* AnmObjMatClrRes::Construct(MEMAllocator* pAllocator, + u32* pSize, ResAnmClr clr, + ResMdl mdl, bool cache) { + if (!clr.IsValid() || !mdl.IsValid()) { + return NULL; + } + + int numAnim = clr.GetNumMaterial(); + int numMat = mdl.GetResMatNumEntries(); + + int bindNum = numMat; + int cacheNum = cache ? numAnim : 0; + + u32 bindSize = bindNum * sizeof(u16); + u32 cacheSize = cacheNum * sizeof(ClrAnmResult); + + u32 size = bindSize + cacheSize + sizeof(AnmObjMatClrRes); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator == NULL) { + return NULL; + } + + u8* pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + ClrAnmResult* pCacheBuf = + cache + ? reinterpret_cast(pBuffer + sizeof(AnmObjMatClrRes)) + : NULL; + + u16* pBindingBuf = + reinterpret_cast(cacheSize + (pBuffer + sizeof(AnmObjMatClrRes))); + + return new (pBuffer) + AnmObjMatClrRes(pAllocator, clr, pBindingBuf, bindNum, pCacheBuf); +} + +AnmObjMatClrRes::AnmObjMatClrRes(MEMAllocator* pAllocator, ResAnmClr clr, + u16* pBindingBuf, int numBinding, + ClrAnmResult* pCacheBuf) + : AnmObjMatClr(pAllocator, pBindingBuf, numBinding), + FrameCtrl(0.0f, clr.GetNumFrame(), GetAnmPlayPolicy(clr.GetAnmPolicy())), + mRes(clr), + mpResultCache(pCacheBuf) { + + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +void AnmObjMatClrRes::SetFrame(f32 frame) { + SetFrm(frame); + + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +f32 AnmObjMatClrRes::GetFrame() const { + return GetFrm(); +} + +void AnmObjMatClrRes::SetUpdateRate(f32 rate) { + SetRate(rate); +} + +f32 AnmObjMatClrRes::GetUpdateRate() const { + return GetRate(); +} + +void AnmObjMatClrRes::UpdateFrame() { + UpdateFrm(); + + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +bool AnmObjMatClrRes::Bind(const ResMdl mdl) { + int numAnim = mRes.GetNumMaterial(); + bool success = false; + + for (u16 i = 0; i < numAnim; i++) { + const ResAnmClrMatData* pData = mRes.GetMatAnm(i); + + // Seek back from name string to start of ResName + ResName name(ut::AddOffsetToPtr(pData, pData->name - 4)); + + ResMat mat = mdl.GetResMat(name); + if (!mat.IsValid()) { + continue; + } + + mpBinding[mat.GetID()] = i; + success = true; + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +const ClrAnmResult* AnmObjMatClrRes::GetResult(ClrAnmResult* pResult, u32 idx) { + u32 id = mpBinding[idx]; + + if (id & (BINDING_UNDEFINED | BINDING_INVALID)) { + pResult->bRgbaExist = 0; + return pResult; + } + + if (mpResultCache != NULL) { + return &mpResultCache[id]; + } + + mRes.GetAnmResult(pResult, id, GetFrm()); + return pResult; +} + +void AnmObjMatClrRes::UpdateCache() { + f32 frame = GetFrm(); + + for (u32 i = 0; i < mNumBinding; i++) { + u16 bind = mpBinding[i]; + + if (!(bind & BINDING_UNDEFINED)) { + u32 id = bind & BINDING_ID_MASK; + mRes.GetAnmResult(&mpResultCache[id], id, frame); + } + } +} + +void AnmObjMatClrRes::G3dProc(u32 task, u32 param, void* pInfo) { +#pragma unused(param) + + switch (task) { + case G3DPROC_UPDATEFRAME: { + UpdateFrame(); + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + } +} + +/****************************************************************************** + * + * ApplyClrAnmResult + * + ******************************************************************************/ +void ApplyClrAnmResult(ResMatChan chan, ResMatTevColor tev, + const ClrAnmResult* pResult) { + ut::Color c; + + if (pResult->bRgbaExist & + (1 << ClrAnmResult::CLA_CLR0 | 1 << ClrAnmResult::CLA_CLR1 | + 1 << ClrAnmResult::CLA_AMB0 | 1 << ClrAnmResult::CLA_AMB1)) { + + if (pResult->bRgbaExist & (1 << ClrAnmResult::CLA_CLR0)) { + GXColor& rMatColor = chan.ref().chan[0].matColor; + c = rMatColor; + + rMatColor = (c & pResult->rgbaMask[ClrAnmResult::CLA_CLR0]) | + pResult->rgba[ClrAnmResult::CLA_CLR0]; + } + + if (pResult->bRgbaExist & (1 << ClrAnmResult::CLA_AMB0)) { + GXColor& rMatColor = chan.ref().chan[0].ambColor; + c = rMatColor; + + rMatColor = (c & pResult->rgbaMask[ClrAnmResult::CLA_AMB0]) | + pResult->rgba[ClrAnmResult::CLA_AMB0]; + } + + if (pResult->bRgbaExist & (1 << ClrAnmResult::CLA_CLR1)) { + GXColor& rMatColor = chan.ref().chan[1].matColor; + c = rMatColor; + + rMatColor = (c & pResult->rgbaMask[ClrAnmResult::CLA_CLR1]) | + pResult->rgba[ClrAnmResult::CLA_CLR1]; + } + + if (pResult->bRgbaExist & (1 << ClrAnmResult::CLA_AMB1)) { + GXColor& rMatColor = chan.ref().chan[1].ambColor; + c = rMatColor; + + rMatColor = (c & pResult->rgbaMask[ClrAnmResult::CLA_AMB1]) | + pResult->rgba[ClrAnmResult::CLA_AMB1]; + } + } + + if (pResult->bRgbaExist & + (1 << ClrAnmResult::CLA_TEV0 | 1 << ClrAnmResult::CLA_TEV1 | + 1 << ClrAnmResult::CLA_TEV2 | 1 << ClrAnmResult::CLA_TEVK0 | + 1 << ClrAnmResult::CLA_TEVK1 | 1 << ClrAnmResult::CLA_TEVK2 | + 1 << ClrAnmResult::CLA_TEVK3)) { + + if (pResult->bRgbaExist & (1 << ClrAnmResult::CLA_TEV0)) { + if (!tev.GXGetTevColor(GX_TEVREG0, &c)) { + c = ut::Color::BLACK; + } + + tev.GXSetTevColor(GX_TEVREG0, + c & pResult->rgbaMask[ClrAnmResult::CLA_TEV0] | + pResult->rgba[ClrAnmResult::CLA_TEV0]); + } + + if (pResult->bRgbaExist & (1 << ClrAnmResult::CLA_TEV1)) { + if (!tev.GXGetTevColor(GX_TEVREG1, &c)) { + c = ut::Color::BLACK; + } + + tev.GXSetTevColor(GX_TEVREG1, + c & pResult->rgbaMask[ClrAnmResult::CLA_TEV1] | + pResult->rgba[ClrAnmResult::CLA_TEV1]); + } + + if (pResult->bRgbaExist & (1 << ClrAnmResult::CLA_TEV2)) { + if (!tev.GXGetTevColor(GX_TEVREG2, &c)) { + c = ut::Color::BLACK; + } + + tev.GXSetTevColor(GX_TEVREG2, + c & pResult->rgbaMask[ClrAnmResult::CLA_TEV2] | + pResult->rgba[ClrAnmResult::CLA_TEV2]); + } + + if (pResult->bRgbaExist & (1 << ClrAnmResult::CLA_TEVK0)) { + if (!tev.GXGetTevKColor(GX_KCOLOR0, &c)) { + c = ut::Color::BLACK; + } + + tev.GXSetTevKColor(GX_KCOLOR0, + c & pResult->rgbaMask[ClrAnmResult::CLA_TEVK0] | + pResult->rgba[ClrAnmResult::CLA_TEVK0]); + } + + if (pResult->bRgbaExist & (1 << ClrAnmResult::CLA_TEVK1)) { + if (!tev.GXGetTevKColor(GX_KCOLOR1, &c)) { + c = ut::Color::BLACK; + } + + tev.GXSetTevKColor(GX_KCOLOR1, + c & pResult->rgbaMask[ClrAnmResult::CLA_TEVK1] | + pResult->rgba[ClrAnmResult::CLA_TEVK1]); + } + + if (pResult->bRgbaExist & (1 << ClrAnmResult::CLA_TEVK2)) { + if (!tev.GXGetTevKColor(GX_KCOLOR2, &c)) { + c = ut::Color::BLACK; + } + + tev.GXSetTevKColor(GX_KCOLOR2, + c & pResult->rgbaMask[ClrAnmResult::CLA_TEVK2] | + pResult->rgba[ClrAnmResult::CLA_TEVK2]); + } + + if (pResult->bRgbaExist & (1 << ClrAnmResult::CLA_TEVK3)) { + if (!tev.GXGetTevKColor(GX_KCOLOR3, &c)) { + c = ut::Color::BLACK; + } + + tev.GXSetTevKColor(GX_KCOLOR3, + c & pResult->rgbaMask[ClrAnmResult::CLA_TEVK3] | + pResult->rgba[ClrAnmResult::CLA_TEVK3]); + } + + tev.DCStore(false); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_anmobj.cpp b/src/nw4r/g3d/g3d_anmobj.cpp new file mode 100644 index 00000000..ac34e1b5 --- /dev/null +++ b/src/nw4r/g3d/g3d_anmobj.cpp @@ -0,0 +1,43 @@ +#include + +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(AnmObj); + +f32 FrameCtrl::smBaseUpdateRate = 1.0f; + +f32 PlayPolicy_Onetime(f32 start, f32 end, f32 frame) { +#pragma unused(start) +#pragma unused(end) + + return frame; +} + +f32 PlayPolicy_Loop(f32 start, f32 end, f32 frame) { + f32 length = end - start; + + if (frame >= 0.0f) { + return math::FMod(frame, length); + } + + f32 offset = math::FMod(frame + length, length); + return offset + math::FSelect(offset, 0.0f, length); +} + +void AnmObj::SetAnmFlag(AnmFlag flag, bool value) { + if (value) { + mFlags |= flag; + } else { + mFlags &= ~flag; + } +} + +bool AnmObj::TestAnmFlag(AnmFlag flag) const { + return mFlags & flag; +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_anmscn.cpp b/src/nw4r/g3d/g3d_anmscn.cpp new file mode 100644 index 00000000..ec8520e5 --- /dev/null +++ b/src/nw4r/g3d/g3d_anmscn.cpp @@ -0,0 +1,69 @@ +#include + +#include + +namespace nw4r { +namespace g3d { + +void AnmScn::GetLightSetting(LightSetting* pSetting) { + const u32 numLightSet = GetLightSetMaxRefNumber(); + const u32 numAmbLight = GetAmbLightMaxRefNumber(); + const u32 numDiffLight = GetDiffuseLightMaxRefNumber(); + + if (numLightSet > 0) { + const u32 numLightSetObj = pSetting->GetNumLightSet(); + const u32 numLoadableSet = std::min(numLightSet, numLightSetObj); + + for (u32 i = 0; i < numLoadableSet; i++) { + LightSet set = pSetting->GetLightSet(i); + GetLightSet(set, i); + } + } + + if (numAmbLight > 0) { + AmbLightObj* pAmbObjArray = pSetting->GetAmbLightObjArray(); + const u32 numAmbObj = pSetting->GetNumLightObj(); + const u32 numLoadableAmb = std::min(numAmbLight, numAmbObj); + + for (u32 i = 0; i < numLoadableAmb; i++) { + AmbLightObj* pAmbObj = &pAmbObjArray[i]; + *reinterpret_cast(&pAmbObj->r) = GetAmbLightColor(i); + } + } + + if (numDiffLight > 0) { + LightObj* pLightObjArray = pSetting->GetLightObjArray(); + const u32 numLightObj = pSetting->GetNumLightObj(); + const u32 numSpecLight = GetNumSpecularLight(); + + const u32 numLight = numDiffLight + numSpecLight; + const u32 numLoadableDiffLight = std::min(numDiffLight, numLightObj); + const u32 numLoadableLight = std::min(numLight, numLightObj); + + for (u32 i = 0; i < numLoadableDiffLight; i++) { + LightObj* pObj = &pLightObjArray[i]; + pObj->Disable(); + } + + for (u32 i = 0; i < numLoadableDiffLight; i++) { + LightObj* pDiffObj = &pLightObjArray[i]; + LightObj* pSpecObj = NULL; + + if (pDiffObj->IsEnable()) { + continue; + } + + if (HasSpecularLight(i)) { + const u32 specId = GetSpecularLightID(i); + if (specId < numLoadableLight) { + pSpecObj = &pLightObjArray[specId]; + } + } + + GetLight(pDiffObj, pSpecObj, i); + } + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_anmshp.cpp b/src/nw4r/g3d/g3d_anmshp.cpp new file mode 100644 index 00000000..271c5b85 --- /dev/null +++ b/src/nw4r/g3d/g3d_anmshp.cpp @@ -0,0 +1,591 @@ +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(AnmObjShp); +NW4R_G3D_RTTI_DEF(AnmObjShpNode); +NW4R_G3D_RTTI_DEF(AnmObjShpBlend); +NW4R_G3D_RTTI_DEF(AnmObjShpRes); + +/****************************************************************************** + * + * AnmObjShp + * + ******************************************************************************/ +AnmObjShp::AnmObjShp(MEMAllocator* pAllocator, u16* pBindingBuf, int numBinding) + : AnmObj(pAllocator, NULL), + mNumBinding(numBinding), + mpBinding(pBindingBuf) { + + Release(); +} + +bool AnmObjShp::TestExistence(u32 idx) const { + return !(mpBinding[idx] & (BINDING_UNDEFINED | BINDING_INVALID)); +} + +bool AnmObjShp::TestDefined(u32 idx) const { + return !(mpBinding[idx] & BINDING_UNDEFINED); +} + +void AnmObjShp::Release() { + for (int i = 0; i < mNumBinding; i++) { + mpBinding[i] = BINDING_UNDEFINED; + } + + SetAnmFlag(FLAG_ANM_BOUND, false); +} + +AnmObjShpRes* AnmObjShp::Attach(int idx, AnmObjShpRes* pRes) { +#pragma unused(idx) +#pragma unused(pRes) + + return NULL; +} + +AnmObjShpRes* AnmObjShp::Detach(int idx) { +#pragma unused(idx) + + return NULL; +} + +void AnmObjShp::SetWeight(int idx, f32 weight) { +#pragma unused(idx) +#pragma unused(weight) +} + +f32 AnmObjShp::GetWeight(int idx) const { +#pragma unused(idx) + + return 0.0f; +} + +void AnmObjShp::DetachAll() {} + +/****************************************************************************** + * + * AnmObjShpNode + * + ******************************************************************************/ +AnmObjShpNode::AnmObjShpNode(MEMAllocator* pAllocator, u16* pBindingBuf, + int numBinding, AnmObjShpRes** ppChildrenBuf, + int numChildren) + : AnmObjShp(pAllocator, pBindingBuf, numBinding), + mChildrenArraySize(numChildren), + mpChildrenArray(ppChildrenBuf) { + + for (int i = 0; i < mChildrenArraySize; i++) { + mpChildrenArray[i] = NULL; + } +} + +AnmObjShpNode::~AnmObjShpNode() { + DetachAll(); +} + +AnmObjShpRes* AnmObjShpNode::Attach(int idx, AnmObjShpRes* pRes) { + AnmObjShpRes* pOld = Detach(idx); + bool hasAnm = false; + + for (u32 i = 0; i < mNumBinding; i++) { + if (!pRes->TestDefined(i)) { + continue; + } + + hasAnm = true; + mpBinding[i] = 0; + } + + if (hasAnm) { + SetAnmFlag(FLAG_ANM_BOUND, true); + } + + mpChildrenArray[idx] = pRes; + pRes->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + return pOld; +} + +AnmObjShpRes* AnmObjShpNode::Detach(int idx) { + AnmObjShpRes* pOld = mpChildrenArray[idx]; + + if (pOld != NULL) { + pOld->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpChildrenArray[idx] = NULL; + + bool hasAnm = false; + for (u32 i = 0; i < mNumBinding; i++) { + u16 binding = BINDING_UNDEFINED; + + for (int j = 0; j < mChildrenArraySize; j++) { + AnmObjShpRes* pChild = mpChildrenArray[j]; + + if (pChild == NULL || !pChild->TestDefined(i)) { + continue; + } + + hasAnm = true; + binding = 0; + break; + } + + mpBinding[i] = binding; + } + + if (!hasAnm) { + SetAnmFlag(FLAG_ANM_BOUND, false); + } + } + + return pOld; +} + +void AnmObjShpNode::DetachAll() { + for (int i = 0; i < mChildrenArraySize; i++) { + Detach(i); + } +} + +void AnmObjShpNode::UpdateFrame() { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->UpdateFrame(); + } + } +} + +void AnmObjShpNode::SetFrame(f32 frame) { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->SetFrame(frame); + } + } +} + +f32 AnmObjShpNode::GetFrame() const { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + return mpChildrenArray[i]->GetFrame(); + } + } + + return 0.0f; +} + +void AnmObjShpNode::SetUpdateRate(f32 rate) { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->SetUpdateRate(rate); + } + } +} + +f32 AnmObjShpNode::GetUpdateRate() const { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + return mpChildrenArray[i]->GetUpdateRate(); + } + } + + return 1.0f; +} + +bool AnmObjShpNode::Bind(const ResMdl mdl) { + bool success = false; + + for (int i = 0; i < mChildrenArraySize; i++) { + AnmObjShpRes* pChild = mpChildrenArray[i]; + if (pChild == NULL) { + continue; + } + + bool childSuccess = pChild->Bind(mdl); + success = success || childSuccess; + + for (u32 j = 0; j < mNumBinding; j++) { + if (pChild->TestDefined(j)) { + mpBinding[j] = 0; + } + } + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +void AnmObjShpNode::Release() { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->Release(); + } + } + + AnmObjShp::Release(); +} + +void AnmObjShpNode::G3dProc(u32 task, u32 param, void* pInfo) { +#pragma unused(param) + + switch (task) { + case G3DPROC_CHILD_DETACHED: { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] == pInfo) { + Detach(i); + return; + } + } + + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + } +} + +/****************************************************************************** + * + * AnmObjShpBlend + * + ******************************************************************************/ +AnmObjShpBlend* AnmObjShpBlend::Construct(MEMAllocator* pAllocator, u32* pSize, + ResMdl mdl, int numChildren) { + if (!mdl.IsValid()) { + return NULL; + } + + int bindNum = mdl.GetResVtxPosNumEntries(); + + u32 bindSize = bindNum * sizeof(u16); + u32 childrenSize = numChildren * sizeof(AnmObjShpRes*); + u32 weightSize = numChildren * sizeof(f32); + + u32 bindOfs = ut::RoundUp(sizeof(AnmObjShpBlend), 4); + u32 childrenOfs = ut::RoundUp(bindOfs + bindSize, 4); + u32 weightOfs = ut::RoundUp(childrenOfs + childrenSize, 4); + + u32 size = ut::RoundUp(weightOfs + weightSize, 4); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator == NULL) { + return NULL; + } + + u8* pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + // clang-format off + return new (pBuffer) AnmObjShpBlend( + pAllocator, + reinterpret_cast(pBuffer + bindOfs), + bindNum, + reinterpret_cast(pBuffer + childrenOfs), + numChildren, + reinterpret_cast(pBuffer + weightOfs)); + // clang-format on +} + +AnmObjShpBlend::AnmObjShpBlend(MEMAllocator* pAllocator, u16* pBindingBuf, + int numBinding, AnmObjShpRes** ppChildrenBuf, + int numChildren, f32* pWeightBuf) + : AnmObjShpNode(pAllocator, pBindingBuf, numBinding, ppChildrenBuf, + numChildren), + mpWeightArray(pWeightBuf) { + + for (int i = 0; i < mChildrenArraySize; i++) { + mpWeightArray[i] = 1.0f; + } +} + +const ShpAnmResult* AnmObjShpBlend::GetResult(ShpAnmResult* pResult, u32 idx) { + detail::workmem::ShpAnmResultBuf* pWorkBuffer = + detail::workmem::GetShpAnmResultBufTemporary(); + + int blendNum = 0; + f32 weightSum = 0.0f; + + for (int i = 0; i < mChildrenArraySize; i++) { + f32 weight = mpWeightArray[i]; + AnmObjShpRes* pChild = mpChildrenArray[i]; + + // @note Bitwise AND + if (!(pChild != NULL & weight != 0.0f)) { + continue; + } + + if (!pChild->TestExistence(idx)) { + continue; + } + + detail::workmem::ShpAnmResultBuf& rAnmBuf = pWorkBuffer[blendNum]; + + const ShpAnmResult* pMyResult = + pChild->GetResult(&rAnmBuf.resultBuf, idx); + + if (!(pMyResult->flags & 1)) { + continue; + } + + rAnmBuf.pResult = pMyResult; + rAnmBuf.weight = weight; + + blendNum++; + weightSum += weight; + } + + if (blendNum == 0) { + pResult->flags = 0; + return pResult; + } + + if (blendNum == 1) { + detail::workmem::ShpAnmResultBuf& rAnmBuf = *pWorkBuffer; + + if (rAnmBuf.pResult == &rAnmBuf.resultBuf) { + *pResult = *rAnmBuf.pResult; + return pResult; + } else { + return rAnmBuf.pResult; + } + } + + f32 invWeightSum = math::FInv(weightSum); + + pResult->flags = pWorkBuffer->pResult->flags; + pResult->numKeyShape = 0; + pResult->baseShapeVtxSet = pWorkBuffer->pResult->baseShapeVtxSet; + pResult->baseShapeWeight = 0.0f; + + for (int i = 0; i < blendNum; i++) { + const ShpAnmResult* pMyResult = pWorkBuffer[i].pResult; + f32 weight = pWorkBuffer[i].weight; + f32 ratio = weight * invWeightSum; + + pResult->baseShapeWeight += pMyResult->baseShapeWeight * ratio; + + for (u32 myKey = 0; myKey < pMyResult->numKeyShape; myKey++) { + const BlendVtx& rMyKeyShape = pMyResult->keyShape[myKey]; + + u32 otherKey; + for (otherKey = 0; otherKey < pResult->numKeyShape; otherKey++) { + if (rMyKeyShape.vtxSet == pResult->keyShape[otherKey].vtxSet) { + break; + } + } + + if (otherKey == pResult->numKeyShape) { + pResult->keyShape[otherKey].vtxSet = rMyKeyShape.vtxSet; + pResult->keyShape[otherKey].weight = 0.0f; + pResult->numKeyShape++; + } + + pResult->keyShape[otherKey].weight += rMyKeyShape.weight * ratio; + } + } + + return pResult; +} + +void AnmObjShpBlend::SetWeight(int idx, f32 weight) { + mpWeightArray[idx] = weight; +} + +f32 AnmObjShpBlend::GetWeight(int idx) const { + return mpWeightArray[idx]; +} + +/****************************************************************************** + * + * AnmObjShpRes + * + ******************************************************************************/ +AnmObjShpRes* AnmObjShpRes::Construct(MEMAllocator* pAllocator, u32* pSize, + ResAnmShp shp, ResMdl mdl, bool cache) { + if (!shp.IsValid() || !mdl.IsValid()) { + return NULL; + } + + int animNum = shp.GetShapeAnmNumEntries(); + int vtxNum = mdl.GetResVtxPosNumEntries(); + int bindNum = vtxNum; + int vtxSetNum = shp.GetNumVtxNames(); + int cacheNum = cache ? animNum : 0; + + u32 bindSize = bindNum * sizeof(u16); + u32 vtxSetSize = vtxSetNum * sizeof(ShpAnmVtxSet); + u32 cacheSize = cacheNum * sizeof(ShpAnmResult); + + u32 bindOfs = ut::RoundUp(sizeof(AnmObjShpRes), 2); + u32 vtxSetOfs = ut::RoundUp(bindOfs + bindSize, 4); + u32 cacheOfs = ut::RoundUp(vtxSetOfs + vtxSetSize, 4); + + u32 size = ut::RoundUp(cacheOfs + cacheSize, 4); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator == NULL) { + return NULL; + } + + u8* pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + u16* const pBindingBuf = reinterpret_cast(pBuffer + bindOfs); + + ShpAnmVtxSet* const pVtxSetBuf = + reinterpret_cast(pBuffer + vtxSetOfs); + + ShpAnmResult* const pCacheBuf = + reinterpret_cast(pBuffer + cacheOfs); + + return new (pBuffer) + AnmObjShpRes(pAllocator, shp, pBindingBuf, pVtxSetBuf, bindNum, + cacheSize != 0 ? pCacheBuf : NULL); +} + +AnmObjShpRes::AnmObjShpRes(MEMAllocator* pAllocator, ResAnmShp shp, + u16* pBindingBuf, ShpAnmVtxSet* pVtxSetBuf, + int numBinding, ShpAnmResult* pCacheBuf) + : AnmObjShp(pAllocator, pBindingBuf, numBinding), + FrameCtrl(0.0f, shp.GetNumFrame(), GetAnmPlayPolicy(shp.GetAnmPolicy())), + mRes(shp), + mpVtxSetArray(pVtxSetBuf), + mpResultCache(pCacheBuf) { + + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +void AnmObjShpRes::SetFrame(f32 frame) { + SetFrm(frame); + + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +f32 AnmObjShpRes::GetFrame() const { + return GetFrm(); +} + +void AnmObjShpRes::SetUpdateRate(f32 rate) { + SetRate(rate); +} + +f32 AnmObjShpRes::GetUpdateRate() const { + return GetRate(); +} + +void AnmObjShpRes::UpdateFrame() { + UpdateFrm(); + + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +bool AnmObjShpRes::Bind(const ResMdl mdl) { + bool success = false; + u32 numAnim = mRes.GetShapeAnmNumEntries(); + + for (u16 i = 0; i < numAnim; i++) { + const ResAnmShpAnmData* pData = mRes.GetShapeAnm(i); + + // Seek back from name string to start of ResName + ResName name(ut::AddOffsetToPtr(pData, pData->name - 4)); + + ResVtxPos pos = mdl.GetResVtxPos(name); + if (!pos.IsValid()) { + continue; + } + + mpBinding[pos.GetID()] = i; + success = true; + } + + int nameNum = mRes.GetNumVtxNames(); + const s32* pVtxNameArray = mRes.GetVtxNameArray(); + + for (int i = 0; i < nameNum; i++) { + ShpAnmVtxSet& rSet = mpVtxSetArray[i]; + s32 offset = pVtxNameArray[i]; + + // Seek back from name string to start of ResName + ResName name = NW4R_G3D_OFS_TO_RESNAME(pVtxNameArray, offset); + + rSet.resVtxPos = mdl.GetResVtxPos(name); + rSet.resVtxNrm = mdl.GetResVtxNrm(name); + rSet.resVtxClr = mdl.GetResVtxClr(name); + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +const ShpAnmResult* AnmObjShpRes::GetResult(ShpAnmResult* pResult, u32 idx) { + u32 id = mpBinding[idx]; + + if (id & (BINDING_UNDEFINED | BINDING_INVALID)) { + pResult->flags = 0; + return pResult; + } + + if (mpResultCache != NULL) { + return &mpResultCache[id]; + } + + mRes.GetAnmResult(pResult, id, GetFrm(), mpVtxSetArray); + return pResult; +} + +void AnmObjShpRes::UpdateCache() { + f32 frame = GetFrm(); + + for (u32 i = 0; i < mNumBinding; i++) { + u16 bind = mpBinding[i]; + + if (!(bind & BINDING_UNDEFINED)) { + u32 id = bind & BINDING_ID_MASK; + mRes.GetAnmResult(&mpResultCache[id], id, frame, mpVtxSetArray); + } + } +} + +void AnmObjShpRes::G3dProc(u32 task, u32 param, void* pInfo) { +#pragma unused(param) + + switch (task) { + case G3DPROC_UPDATEFRAME: { + UpdateFrame(); + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_anmtexpat.cpp b/src/nw4r/g3d/g3d_anmtexpat.cpp new file mode 100644 index 00000000..b3c24c84 --- /dev/null +++ b/src/nw4r/g3d/g3d_anmtexpat.cpp @@ -0,0 +1,529 @@ +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(AnmObjTexPat); +NW4R_G3D_RTTI_DEF(AnmObjTexPatNode); +NW4R_G3D_RTTI_DEF(AnmObjTexPatOverride); +NW4R_G3D_RTTI_DEF(AnmObjTexPatRes); + +/****************************************************************************** + * + * AnmObjTexPat + * + ******************************************************************************/ +AnmObjTexPat::AnmObjTexPat(MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding) + : AnmObj(pAllocator, NULL), mNumBinding(numBinding), mpBinding(pBindingBuf) { + Release(); +} + +bool AnmObjTexPat::TestExistence(u32 idx) const { + return !(mpBinding[idx] & (BINDING_UNDEFINED | BINDING_INVALID)); +} + +bool AnmObjTexPat::TestDefined(u32 idx) const { + return !(mpBinding[idx] & BINDING_UNDEFINED); +} + +void AnmObjTexPat::Release() { + for (int i = 0; i < mNumBinding; i++) { + mpBinding[i] = BINDING_UNDEFINED; + } + + SetAnmFlag(FLAG_ANM_BOUND, false); +} + +AnmObjTexPatRes *AnmObjTexPat::Attach(int idx, AnmObjTexPatRes *pRes) { +#pragma unused(idx) +#pragma unused(pRes) + + return NULL; +} + +AnmObjTexPatRes *AnmObjTexPat::Detach(int idx) { +#pragma unused(idx) + + return NULL; +} + +void AnmObjTexPat::DetachAll() {} + +/****************************************************************************** + * + * AnmObjTexPatNode + * + ******************************************************************************/ +AnmObjTexPatNode::AnmObjTexPatNode( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjTexPatRes **ppChildrenBuf, int numChildren +) + : AnmObjTexPat(pAllocator, pBindingBuf, numBinding), + mChildrenArraySize(numChildren), + mpChildrenArray(ppChildrenBuf) { + for (int i = 0; i < mChildrenArraySize; i++) { + mpChildrenArray[i] = NULL; + } +} + +AnmObjTexPatNode::~AnmObjTexPatNode() { + DetachAll(); +} + +AnmObjTexPatRes *AnmObjTexPatNode::Attach(int idx, AnmObjTexPatRes *pRes) { + AnmObjTexPatRes *pOld = Detach(idx); + bool hasAnm = false; + + for (u32 i = 0; i < mNumBinding; i++) { + if (!pRes->TestDefined(i)) { + continue; + } + + hasAnm = true; + mpBinding[i] = 0; + } + + if (hasAnm) { + SetAnmFlag(FLAG_ANM_BOUND, true); + } + + mpChildrenArray[idx] = pRes; + pRes->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + return pOld; +} + +AnmObjTexPatRes *AnmObjTexPatNode::Detach(int idx) { + AnmObjTexPatRes *pOld = mpChildrenArray[idx]; + + if (pOld != NULL) { + pOld->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpChildrenArray[idx] = NULL; + + bool hasAnm = false; + for (u32 i = 0; i < mNumBinding; i++) { + u16 binding = BINDING_UNDEFINED; + + for (int j = 0; j < mChildrenArraySize; j++) { + AnmObjTexPatRes *pChild = mpChildrenArray[j]; + + if (pChild == NULL || !pChild->TestDefined(i)) { + continue; + } + + hasAnm = true; + binding = 0; + break; + } + + mpBinding[i] = binding; + } + + if (!hasAnm) { + SetAnmFlag(FLAG_ANM_BOUND, false); + } + } + + return pOld; +} + +void AnmObjTexPatNode::DetachAll() { + for (int i = 0; i < mChildrenArraySize; i++) { + Detach(i); + } +} + +void AnmObjTexPatNode::UpdateFrame() { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->UpdateFrame(); + } + } +} + +void AnmObjTexPatNode::SetFrame(f32 frame) { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->SetFrame(frame); + } + } +} + +f32 AnmObjTexPatNode::GetFrame() const { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + return mpChildrenArray[i]->GetFrame(); + } + } + + return 0.0f; +} + +void AnmObjTexPatNode::SetUpdateRate(f32 rate) { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->SetUpdateRate(rate); + } + } +} + +f32 AnmObjTexPatNode::GetUpdateRate() const { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + return mpChildrenArray[i]->GetUpdateRate(); + } + } + + return 1.0f; +} + +bool AnmObjTexPatNode::Bind(const ResMdl mdl) { + bool success = false; + + for (int i = 0; i < mChildrenArraySize; i++) { + AnmObjTexPatRes *pChild = mpChildrenArray[i]; + if (pChild == NULL) { + continue; + } + + bool childSuccess = pChild->Bind(mdl); + success = success || childSuccess; + + for (u32 j = 0; j < mNumBinding; j++) { + if (pChild->TestDefined(j)) { + mpBinding[j] = 0; + } + } + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +void AnmObjTexPatNode::Release() { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->Release(); + } + } + + AnmObjTexPat::Release(); +} + +void AnmObjTexPatNode::G3dProc(u32 task, u32 param, void *pInfo) { +#pragma unused(param) + + switch (task) { + case G3DPROC_CHILD_DETACHED: { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] == pInfo) { + Detach(i); + return; + } + } + + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + } +} + +/****************************************************************************** + * + * AnmObjTexPatOverride + * + ******************************************************************************/ +AnmObjTexPatOverride * +AnmObjTexPatOverride::Construct(MEMAllocator *pAllocator, u32 *pSize, ResMdl mdl, int numChildren) { + if (!mdl.IsValid()) { + return NULL; + } + + int numAnim = mdl.GetResMatNumEntries(); + int bindNum = numAnim; + + u32 objSize = sizeof(AnmObjTexPatOverride); + u32 bindSize = bindNum * sizeof(u16); + u32 childrenSize = numChildren * sizeof(AnmObjTexPatRes *); + + u32 bindOfs = align4(objSize); + u32 childrenOfs = align4(bindOfs + bindSize); + + u32 size = align4(childrenOfs + childrenSize); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator == NULL) { + return NULL; + } + + u8 *pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + // clang-format off + return new (pBuffer) AnmObjTexPatOverride( + pAllocator, + reinterpret_cast(pBuffer + bindOfs), + bindNum, + reinterpret_cast(pBuffer + childrenOfs), + numChildren); + // clang-format on +} + +const TexPatAnmResult *AnmObjTexPatOverride::GetResult(TexPatAnmResult *pResult, u32 idx) { + for (int i = mChildrenArraySize - 1; i >= 0; i--) { + AnmObjTexPatRes *pChild = mpChildrenArray[i]; + + if (pChild == NULL || !pChild->TestExistence(idx)) { + continue; + } + + const TexPatAnmResult *pChildResult = pChild->GetResult(pResult, idx); + + if (pChildResult->bTexExist != 0 || pChildResult->bPlttExist) { + return pChildResult; + } + } + + pResult->bTexExist = 0; + pResult->bPlttExist = 0; + return pResult; +} + +/****************************************************************************** + * + * AnmObjTexPatRes + * + ******************************************************************************/ +AnmObjTexPatRes * +AnmObjTexPatRes::Construct(MEMAllocator *pAllocator, u32 *pSize, ResAnmTexPat pat, ResMdl mdl, bool cache) { + if (!pat.IsValid() || !mdl.IsValid()) { + return NULL; + } + + int numAnim = pat.GetNumMaterial(); + int numMat = mdl.GetResMatNumEntries(); + + int bindNum = numMat; + int cacheNum = cache ? numAnim : 0; + + u32 bindSize = bindNum * sizeof(u16); + u32 cacheSize = cacheNum * sizeof(TexPatAnmResult); + + u32 size = bindSize + cacheSize + sizeof(AnmObjTexPatRes); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator == NULL) { + return NULL; + } + + u8 *pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + TexPatAnmResult *pCacheBuf = cache ? reinterpret_cast(pBuffer + sizeof(AnmObjTexPatRes)) : NULL; + + u16 *pBindingBuf = reinterpret_cast(cacheSize + (pBuffer + sizeof(AnmObjTexPatRes))); + + return new (pBuffer) AnmObjTexPatRes(pAllocator, pat, pBindingBuf, bindNum, pCacheBuf); +} + +AnmObjTexPatRes::AnmObjTexPatRes( + MEMAllocator *pAllocator, ResAnmTexPat pat, u16 *pBindingBuf, int numBinding, TexPatAnmResult *pCacheBuf +) + : AnmObjTexPat(pAllocator, pBindingBuf, numBinding), + FrameCtrl(0.0f, pat.GetNumFrame(), GetAnmPlayPolicy(pat.GetAnmPolicy())), + mRes(pat), + mpResultCache(pCacheBuf) { + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +void AnmObjTexPatRes::SetFrame(f32 frame) { + SetFrm(frame); + + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +f32 AnmObjTexPatRes::GetFrame() const { + return GetFrm(); +} + +void AnmObjTexPatRes::SetUpdateRate(f32 rate) { + SetRate(rate); +} + +f32 AnmObjTexPatRes::GetUpdateRate() const { + return GetRate(); +} + +void AnmObjTexPatRes::UpdateFrame() { + UpdateFrm(); + + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +bool AnmObjTexPatRes::Bind(const ResMdl mdl) { + int numAnim = mRes.GetNumMaterial(); + bool success = false; + + for (u16 i = 0; i < numAnim; i++) { + const ResAnmTexPatMatData *pData = mRes.GetMatAnm(i); + + // Seek back from name string to start of ResName + ResName name(ut::AddOffsetToPtr(pData, pData->name - 4)); + + ResMat mat = mdl.GetResMat(name); + if (!mat.IsValid()) { + continue; + } + + mpBinding[mat.GetID()] = i; + success = true; + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +const TexPatAnmResult *AnmObjTexPatRes::GetResult(TexPatAnmResult *pResult, u32 i) { + u32 id = mpBinding[i]; + + if (id & (BINDING_UNDEFINED | BINDING_INVALID)) { + pResult->bTexExist = 0; + pResult->bPlttExist = 0; + return pResult; + } + + if (mpResultCache != NULL) { + return &mpResultCache[id]; + } + + mRes.GetAnmResult(pResult, id, GetFrm()); + return pResult; +} + +void AnmObjTexPatRes::UpdateCache() { + f32 frame = GetFrm(); + + for (u32 i = 0; i < mNumBinding; i++) { + u16 bind = mpBinding[i]; + + if (!(bind & BINDING_UNDEFINED)) { + u32 id = bind & BINDING_ID_MASK; + mRes.GetAnmResult(&mpResultCache[id], id, frame); + } + } +} + +void AnmObjTexPatRes::G3dProc(u32 task, u32 param, void *pInfo) { +#pragma unused(param) + + switch (task) { + case G3DPROC_UPDATEFRAME: { + UpdateFrame(); + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + } +} + +/****************************************************************************** + * + * ApplyTexPatAnmResult + * + ******************************************************************************/ +void ApplyTexPatAnmResult(ResTexObj texObj, ResTlutObj tlutObj, const TexPatAnmResult *pResult) { + u32 texExist = pResult->bTexExist; + u32 i; + + for (i = 0; texExist != 0; texExist >>= 1, i++) { + if (!(texExist & 1)) { + continue; + } + + ResTex tex = pResult->tex[i]; + GXTexObj *pGXObj = texObj.GetTexObj(static_cast(i)); + + GXTexFilter minFilt, magFilt; + f32 minLod, maxLod, lodBias; + GXBool biasClamp, edgeLod, mipmap; + GXAnisotropy maxAniso; + + void *pTexData; + u16 width, height; + GXTexFmt fmt; + GXCITexFmt cifmt; + + GXGetTexObjLODAll(pGXObj, &minFilt, &magFilt, &minLod, &maxLod, &lodBias, &biasClamp, &edgeLod, &maxAniso); + + GXTexWrapMode wrapS = GXGetTexObjWrapS(pGXObj); + GXTexWrapMode wrapT = GXGetTexObjWrapT(pGXObj); + + if (tex.IsCIFmt()) { + tex.GetTexObjCIParam(&pTexData, &width, &height, &cifmt, &minLod, &maxLod, &mipmap); + + GXInitTexObjCI( + pGXObj, pTexData, width, height, static_cast(cifmt), wrapS, wrapT, mipmap, + static_cast(i) + ); + } else { + tex.GetTexObjParam(&pTexData, &width, &height, &fmt, &minLod, &maxLod, &mipmap); + + GXInitTexObj(pGXObj, pTexData, width, height, fmt, wrapS, wrapT, mipmap); + } + + GXInitTexObjLOD(pGXObj, minFilt, magFilt, minLod, maxLod, lodBias, biasClamp, edgeLod, maxAniso); + } + + u32 plttExist = pResult->bPlttExist; + + for (i = 0; plttExist != 0; plttExist >>= 1, i++) { + if (!(plttExist & 1)) { + continue; + } + + ResPltt pltt = pResult->pltt[i]; + + void *pLUT = pltt.GetPlttData(); + GXTlutFmt fmt = pltt.GetFmt(); + u16 numEntries = pltt.GetNumEntries(); + GXTlutObj *pGXObj = tlutObj.GetTlut(static_cast(i)); + + GXInitTlutObj(pGXObj, pLUT, fmt, numEntries); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_anmtexsrt.cpp b/src/nw4r/g3d/g3d_anmtexsrt.cpp new file mode 100644 index 00000000..2d6df293 --- /dev/null +++ b/src/nw4r/g3d/g3d_anmtexsrt.cpp @@ -0,0 +1,528 @@ +#include + +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(AnmObjTexSrt); +NW4R_G3D_RTTI_DEF(AnmObjTexSrtNode); +NW4R_G3D_RTTI_DEF(AnmObjTexSrtOverride); +NW4R_G3D_RTTI_DEF(AnmObjTexSrtRes); + +/****************************************************************************** + * + * AnmObjTexSrt + * + ******************************************************************************/ +AnmObjTexSrt::AnmObjTexSrt(MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding) + : AnmObj(pAllocator, NULL), mNumBinding(numBinding), mpBinding(pBindingBuf) { + Release(); +} + +bool AnmObjTexSrt::TestExistence(u32 idx) const { + return !(mpBinding[idx] & (BINDING_UNDEFINED | BINDING_INVALID)); +} + +bool AnmObjTexSrt::TestDefined(u32 idx) const { + return !(mpBinding[idx] & BINDING_UNDEFINED); +} + +void AnmObjTexSrt::Release() { + for (int i = 0; i < mNumBinding; i++) { + mpBinding[i] = BINDING_UNDEFINED; + } + + SetAnmFlag(FLAG_ANM_BOUND, false); +} + +AnmObjTexSrtRes *AnmObjTexSrt::Attach(int idx, AnmObjTexSrtRes *pRes) { +#pragma unused(idx) +#pragma unused(pRes) + + return NULL; +} + +AnmObjTexSrtRes *AnmObjTexSrt::Detach(int idx) { +#pragma unused(idx) + + return NULL; +} + +void AnmObjTexSrt::DetachAll() {} + +/****************************************************************************** + * + * AnmObjTexSrtNode + * + ******************************************************************************/ +AnmObjTexSrtNode::AnmObjTexSrtNode( + MEMAllocator *pAllocator, u16 *pBindingBuf, int numBinding, AnmObjTexSrtRes **ppChildrenBuf, int numChildren +) + : AnmObjTexSrt(pAllocator, pBindingBuf, numBinding), + mChildrenArraySize(numChildren), + mpChildrenArray(ppChildrenBuf) { + for (int i = 0; i < mChildrenArraySize; i++) { + mpChildrenArray[i] = NULL; + } +} + +AnmObjTexSrtNode::~AnmObjTexSrtNode() { + DetachAll(); +} + +AnmObjTexSrtRes *AnmObjTexSrtNode::Attach(int idx, AnmObjTexSrtRes *pRes) { + AnmObjTexSrtRes *pOld = Detach(idx); + bool hasAnm = false; + + for (u32 i = 0; i < mNumBinding; i++) { + if (!pRes->TestDefined(i)) { + continue; + } + + hasAnm = true; + mpBinding[i] = 0; + } + + if (hasAnm) { + SetAnmFlag(FLAG_ANM_BOUND, true); + } + + mpChildrenArray[idx] = pRes; + pRes->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + return pOld; +} + +AnmObjTexSrtRes *AnmObjTexSrtNode::Detach(int idx) { + AnmObjTexSrtRes *pOld = mpChildrenArray[idx]; + + if (pOld != NULL) { + pOld->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpChildrenArray[idx] = NULL; + + bool hasAnm = false; + for (u32 i = 0; i < mNumBinding; i++) { + u16 binding = BINDING_UNDEFINED; + + for (int j = 0; j < mChildrenArraySize; j++) { + AnmObjTexSrtRes *pChild = mpChildrenArray[j]; + + if (pChild == NULL || !pChild->TestDefined(i)) { + continue; + } + + hasAnm = true; + binding = 0; + break; + } + + mpBinding[i] = binding; + } + + if (!hasAnm) { + SetAnmFlag(FLAG_ANM_BOUND, false); + } + } + + return pOld; +} + +void AnmObjTexSrtNode::DetachAll() { + for (int i = 0; i < mChildrenArraySize; i++) { + Detach(i); + } +} + +void AnmObjTexSrtNode::UpdateFrame() { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->UpdateFrame(); + } + } +} + +void AnmObjTexSrtNode::SetFrame(f32 frame) { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->SetFrame(frame); + } + } +} + +f32 AnmObjTexSrtNode::GetFrame() const { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + return mpChildrenArray[i]->GetFrame(); + } + } + + return 0.0f; +} + +void AnmObjTexSrtNode::SetUpdateRate(f32 rate) { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->SetUpdateRate(rate); + } + } +} + +f32 AnmObjTexSrtNode::GetUpdateRate() const { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + return mpChildrenArray[i]->GetUpdateRate(); + } + } + + return 1.0f; +} + +bool AnmObjTexSrtNode::Bind(const ResMdl mdl) { + bool success = false; + + for (int i = 0; i < mChildrenArraySize; i++) { + AnmObjTexSrtRes *pChild = mpChildrenArray[i]; + if (pChild == NULL) { + continue; + } + + bool childSuccess = pChild->Bind(mdl); + success = success || childSuccess; + + for (u32 j = 0; j < mNumBinding; j++) { + if (pChild->TestDefined(j)) { + mpBinding[j] = 0; + } + } + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +void AnmObjTexSrtNode::Release() { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] != NULL) { + mpChildrenArray[i]->Release(); + } + } + + AnmObjTexSrt::Release(); +} + +void AnmObjTexSrtNode::G3dProc(u32 task, u32 param, void *pInfo) { +#pragma unused(param) + + switch (task) { + case G3DPROC_CHILD_DETACHED: { + for (int i = 0; i < mChildrenArraySize; i++) { + if (mpChildrenArray[i] == pInfo) { + Detach(i); + return; + } + } + + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + } +} + +/****************************************************************************** + * + * AnmObjTexSrtOverride + * + ******************************************************************************/ +AnmObjTexSrtOverride * +AnmObjTexSrtOverride::Construct(MEMAllocator *pAllocator, u32 *pSize, ResMdl mdl, int numChildren) { + if (!mdl.IsValid()) { + return NULL; + } + + int numAnim = mdl.GetResMatNumEntries(); + int bindNum = numAnim; + + u32 objSize = sizeof(AnmObjTexSrtOverride); + u32 bindSize = bindNum * sizeof(u16); + u32 childrenSize = numChildren * sizeof(AnmObjTexSrtRes *); + + u32 bindOfs = align4(objSize); + u32 childrenOfs = align4(bindOfs + bindSize); + + u32 size = align4(childrenOfs + childrenSize); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator == NULL) { + return NULL; + } + + u8 *pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + // clang-format off + return new (pBuffer) AnmObjTexSrtOverride( + pAllocator, + reinterpret_cast(pBuffer + bindOfs), + bindNum, + reinterpret_cast(pBuffer + childrenOfs), + numChildren); + // clang-format on +} + +const TexSrtAnmResult *AnmObjTexSrtOverride::GetResult(TexSrtAnmResult *pResult, u32 idx) { + for (int i = mChildrenArraySize - 1; i >= 0; i--) { + AnmObjTexSrtRes *pChild = mpChildrenArray[i]; + + if (pChild == NULL || !pChild->TestExistence(idx)) { + continue; + } + + const TexSrtAnmResult *pChildResult = pChild->GetResult(pResult, idx); + + if (pChildResult->flags != 0) { + return pChildResult; + } + } + + pResult->flags = 0; + return pResult; +} + +/****************************************************************************** + * + * AnmObjTexSrtRes + * + ******************************************************************************/ +AnmObjTexSrtRes * +AnmObjTexSrtRes::Construct(MEMAllocator *pAllocator, u32 *pSize, ResAnmTexSrt srt, ResMdl mdl, bool cache) { + if (!srt.IsValid() || !mdl.IsValid()) { + return NULL; + } + + int numAnim = srt.GetNumMaterial(); + int numMat = mdl.GetResMatNumEntries(); + + int bindNum = numMat; + int cacheNum = cache ? numAnim : 0; + + u32 bindSize = bindNum * sizeof(u16); + u32 cacheSize = cacheNum * sizeof(TexSrtAnmResult); + + u32 size = bindSize + cacheSize + sizeof(AnmObjTexSrtRes); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator == NULL) { + return NULL; + } + + u8 *pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + TexSrtAnmResult *pCacheBuf = cache ? reinterpret_cast(pBuffer + sizeof(AnmObjTexSrtRes)) : NULL; + + u16 *pBindingBuf = reinterpret_cast(cacheSize + (pBuffer + sizeof(AnmObjTexSrtRes))); + + return new (pBuffer) AnmObjTexSrtRes(pAllocator, srt, pBindingBuf, bindNum, pCacheBuf); +} + +AnmObjTexSrtRes::AnmObjTexSrtRes( + MEMAllocator *pAllocator, ResAnmTexSrt srt, u16 *pBindingBuf, int numBinding, TexSrtAnmResult *pCacheBuf +) + : AnmObjTexSrt(pAllocator, pBindingBuf, numBinding), + FrameCtrl(0.0f, srt.GetNumFrame(), GetAnmPlayPolicy(srt.GetAnmPolicy())), + mRes(srt), + mpResultCache(pCacheBuf) { + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +void AnmObjTexSrtRes::SetFrame(f32 frame) { + SetFrm(frame); + + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +f32 AnmObjTexSrtRes::GetFrame() const { + return GetFrm(); +} + +void AnmObjTexSrtRes::SetUpdateRate(f32 rate) { + SetRate(rate); +} + +f32 AnmObjTexSrtRes::GetUpdateRate() const { + return GetRate(); +} + +void AnmObjTexSrtRes::UpdateFrame() { + UpdateFrm(); + + if (mpResultCache != NULL) { + UpdateCache(); + } +} + +bool AnmObjTexSrtRes::Bind(const ResMdl mdl) { + int numAnim = mRes.GetNumMaterial(); + bool success = false; + + for (u16 i = 0; i < numAnim; i++) { + const ResAnmTexSrtMatData *pData = mRes.GetMatAnm(i); + + // Seek back from name string to start of ResName + ResName name(ut::AddOffsetToPtr(pData, pData->name - 4)); + + ResMat mat = mdl.GetResMat(name); + if (!mat.IsValid()) { + continue; + } + + mpBinding[mat.GetID()] = i; + success = true; + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +const TexSrtAnmResult *AnmObjTexSrtRes::GetResult(TexSrtAnmResult *pResult, u32 idx) { + u32 id = mpBinding[idx]; + + if (id & (BINDING_UNDEFINED | BINDING_INVALID)) { + pResult->flags = 0; + return pResult; + } + + if (mpResultCache != NULL) { + return &mpResultCache[id]; + } + + mRes.GetAnmResult(pResult, id, GetFrm()); + return pResult; +} + +void AnmObjTexSrtRes::UpdateCache() { + f32 frame = GetFrm(); + + for (u32 i = 0; i < mNumBinding; i++) { + u16 bind = mpBinding[i]; + + if (!(bind & BINDING_UNDEFINED)) { + u32 id = bind & BINDING_ID_MASK; + mRes.GetAnmResult(&mpResultCache[id], id, frame); + } + } +} + +void AnmObjTexSrtRes::G3dProc(u32 task, u32 param, void *pInfo) { +#pragma unused(param) + + switch (task) { + case G3DPROC_UPDATEFRAME: { + UpdateFrame(); + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + } +} + +/****************************************************************************** + * + * ApplyTexSrtAnmResult + * + ******************************************************************************/ +void ApplyTexSrtAnmResult(ResTexSrt srt, const TexSrtAnmResult *pResult) { + ResTexSrtData &r = srt.ref(); + + u32 flags = pResult->flags; + u32 mask = 0x0F; + + for (int i = 0; flags != 0; flags >>= TexSrt::NUM_OF_FLAGS, mask <<= 4, i++) { + if (!(flags & 1)) { + continue; + } + + r.texMtxMode = pResult->texMtxMode; + r.texSrt[i] = pResult->srt[i]; + r.flag = (r.flag & ~mask) | (pResult->flags & mask); + } +} + +void ApplyTexSrtAnmResult(ResTexSrt srt, ResMatIndMtxAndScale ind, const TexSrtAnmResult *pResult) { + ApplyTexSrtAnmResult(srt, pResult); + + u32 flags = pResult->indFlags; + + for (int i = TexSrtAnmResult::NUM_OF_MAT_TEX_MTX; flags != 0; i++, flags >>= TexSrt::NUM_OF_FLAGS) { + if (!(flags & 1)) { + continue; + } + + math::MTX34 mtx; + + CalcTexMtx( + &mtx, true, pResult->srt[i], static_cast(flags & TexSrt::FLAGSET_IDENTITY), + TexSrtTypedef::TEXMATRIXMODE_MAYA + ); + + s8 scaleExp; + + f32 maxElem = 0.000000000000000001f; + maxElem = ut::Max(maxElem, math::FAbs(mtx._00)); + maxElem = ut::Max(maxElem, math::FAbs(mtx._01)); + maxElem = ut::Max(maxElem, math::FAbs(mtx._03)); + maxElem = ut::Max(maxElem, math::FAbs(mtx._10)); + maxElem = ut::Max(maxElem, math::FAbs(mtx._11)); + maxElem = ut::Max(maxElem, math::FAbs(mtx._13)); + + scaleExp = static_cast(math::FGetExpPart(maxElem) + 1); + f32 invScale = 0.f; // TODO: ldexpf(1.0f, -scaleExp); + + mtx._00 *= invScale; + mtx._01 *= invScale; + mtx._02 = mtx._03 * invScale; + mtx._10 *= invScale; + mtx._11 *= invScale; + mtx._12 = mtx._13 * invScale; + + GXIndTexMtxID id = static_cast(i - TexSrtAnmResult::NUM_OF_MAT_TEX_MTX + 1); + + ind.GXSetIndTexMtx(id, mtx, scaleExp); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_anmvis.cpp b/src/nw4r/g3d/g3d_anmvis.cpp new file mode 100644 index 00000000..cec0f644 --- /dev/null +++ b/src/nw4r/g3d/g3d_anmvis.cpp @@ -0,0 +1,444 @@ +#include + +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(AnmObjVis); +NW4R_G3D_RTTI_DEF(AnmObjVisNode); +NW4R_G3D_RTTI_DEF(AnmObjVisOR); +NW4R_G3D_RTTI_DEF(AnmObjVisRes); + +/****************************************************************************** + * + * AnmObjVis + * + ******************************************************************************/ +AnmObjVis::AnmObjVis(MEMAllocator* pAllocator, u16* pBindingBuf, int numBinding) + : AnmObj(pAllocator, NULL), + mpBinding(pBindingBuf), + mNumBinding(numBinding) { + + Release(); +} + +bool AnmObjVis::TestExistence(u32 idx) const { + return !(mpBinding[idx] & (BINDING_UNDEFINED | BINDING_INVALID)); +} + +bool AnmObjVis::TestDefined(u32 idx) const { + return !(mpBinding[idx] & BINDING_UNDEFINED); +} + +void AnmObjVis::Release() { + for (int i = 0; i < mNumBinding; i++) { + mpBinding[i] = BINDING_UNDEFINED; + } + + SetAnmFlag(FLAG_ANM_BOUND, false); +} + +AnmObjVisRes* AnmObjVis::Attach(int idx, AnmObjVisRes* pRes) { +#pragma unused(idx) +#pragma unused(pRes) + + return NULL; +} + +AnmObjVisRes* AnmObjVis::Detach(int idx) { +#pragma unused(idx) + + return NULL; +} + +void AnmObjVis::DetachAll() { + for (int i = 0; i < MAX_CHILD; i++) { + Detach(i); + } +} + +void AnmObjVis::G3dProc(u32 task, u32 param, void* pInfo) { +#pragma unused(param) + + switch (task) { + case G3DPROC_UPDATEFRAME: { + SetAnmFlag(FLAG_CACHE_OBSOLETE, true); + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + } +} + +/****************************************************************************** + * + * AnmObjVisNode + * + ******************************************************************************/ +AnmObjVisNode::AnmObjVisNode(MEMAllocator* pAllocator, u16* pBindingBuf, + int numBinding) + : AnmObjVis(pAllocator, pBindingBuf, numBinding) { + + for (int i = 0; i < MAX_CHILD; i++) { + mpChildren[i] = NULL; + } +} + +AnmObjVisNode::~AnmObjVisNode() { + DetachAll(); +} + +AnmObjVisRes* AnmObjVisNode::Attach(int idx, AnmObjVisRes* pRes) { + AnmObjVisRes* pOld = Detach(idx); + bool hasAnm = false; + + for (u32 i = 0; i < mNumBinding; i++) { + if (!pRes->TestDefined(i)) { + continue; + } + + hasAnm = true; + mpBinding[i] = 0; + } + + if (hasAnm) { + SetAnmFlag(FLAG_ANM_BOUND, true); + } + + mpChildren[idx] = pRes; + pRes->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + return pOld; +} + +AnmObjVisRes* AnmObjVisNode::Detach(int idx) { + AnmObjVisRes* pOld = mpChildren[idx]; + + if (pOld != NULL) { + pOld->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpChildren[idx] = NULL; + + bool hasAnm = false; + for (u32 i = 0; i < mNumBinding; i++) { + u16 binding = BINDING_UNDEFINED; + + for (int j = 0; j < MAX_CHILD; j++) { + AnmObjVisRes* pChild = mpChildren[j]; + + if (pChild == NULL || !pChild->TestDefined(i)) { + continue; + } + + hasAnm = true; + binding = 0; + break; + } + + mpBinding[i] = binding; + } + + if (!hasAnm) { + SetAnmFlag(FLAG_ANM_BOUND, false); + } + } + + return pOld; +} + +void AnmObjVisNode::UpdateFrame() { + for (int i = 0; i < MAX_CHILD; i++) { + if (mpChildren[i] != NULL) { + mpChildren[i]->UpdateFrame(); + } + } +} + +void AnmObjVisNode::SetFrame(f32 frame) { + for (int i = 0; i < MAX_CHILD; i++) { + if (mpChildren[i] != NULL) { + mpChildren[i]->SetFrame(frame); + } + } +} + +f32 AnmObjVisNode::GetFrame() const { + for (int i = 0; i < MAX_CHILD; i++) { + if (mpChildren[i] != NULL) { + return mpChildren[i]->GetFrame(); + } + } + + return 0.0f; +} + +void AnmObjVisNode::SetUpdateRate(f32 rate) { + for (int i = 0; i < MAX_CHILD; i++) { + if (mpChildren[i] != NULL) { + mpChildren[i]->SetUpdateRate(rate); + } + } +} + +f32 AnmObjVisNode::GetUpdateRate() const { + for (int i = 0; i < MAX_CHILD; i++) { + if (mpChildren[i] != NULL) { + return mpChildren[i]->GetUpdateRate(); + } + } + + return 1.0f; +} + +bool AnmObjVisNode::Bind(ResMdl mdl) { + bool success = false; + + for (int i = 0; i < MAX_CHILD; i++) { + AnmObjVisRes* pChild = mpChildren[i]; + if (pChild == NULL) { + continue; + } + + bool childSuccess = pChild->Bind(mdl); + success = success || childSuccess; + + for (u32 j = 0; j < mNumBinding; j++) { + if (pChild->TestDefined(j)) { + mpBinding[j] = 0; + } + } + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +void AnmObjVisNode::Release() { + for (int i = 0; i < MAX_CHILD; i++) { + if (mpChildren[i] != NULL) { + mpChildren[i]->Release(); + } + } + + AnmObjVis::Release(); +} + +void AnmObjVisNode::G3dProc(u32 task, u32 param, void* pInfo) { +#pragma unused(param) + + switch (task) { + case G3DPROC_CHILD_DETACHED: { + for (int i = 0; i < MAX_CHILD; i++) { + if (mpChildren[i] == pInfo) { + Detach(i); + return; + } + } + + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + } +} + +/****************************************************************************** + * + * AnmObjVisOR + * + ******************************************************************************/ +AnmObjVisOR* AnmObjVisOR::Construct(MEMAllocator* pAllocator, u32* pSize, + ResMdl mdl) { + if (!mdl.IsValid()) { + return NULL; + } + + u32 numAnim = mdl.GetResNodeNumEntries(); + + int bindNum = numAnim; + u32 bindSize = bindNum * sizeof(u16); + + u32 size = bindSize + sizeof(AnmObjVisOR); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator == NULL) { + return NULL; + } + + u8* pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + u16* pBindingBuf = reinterpret_cast(pBuffer + sizeof(AnmObjVisOR)); + + AnmObjVisOR* pObjVis = + new (pBuffer) AnmObjVisOR(pAllocator, pBindingBuf, bindNum); + + return pObjVis; +} + +bool AnmObjVisOR::GetResult(u32 idx) { + for (int i = 0; i < MAX_CHILD; i++) { + AnmObjVisRes* pChild = mpChildren[i]; + + if (pChild == NULL || !pChild->TestExistence(idx)) { + continue; + } + + if (!pChild->GetResult(idx)) { + return false; + } + } + + return true; +} + +/****************************************************************************** + * + * AnmObjVisRes + * + ******************************************************************************/ +AnmObjVisRes* AnmObjVisRes::Construct(MEMAllocator* pAllocator, u32* pSize, + ResAnmVis vis, ResMdl mdl) { + if (!vis.IsValid() || !mdl.IsValid()) { + return NULL; + } + + u32 numAnim = mdl.GetResNodeNumEntries(); + + int bindNum = numAnim; + u32 bindSize = bindNum * sizeof(u16); + + u32 size = bindSize + sizeof(AnmObjVisRes); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator == NULL) { + return NULL; + } + + u8* pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + u16* pBindingBuf = reinterpret_cast(pBuffer + sizeof(AnmObjVisRes)); + + AnmObjVisRes* pObjVis = + new (pBuffer) AnmObjVisRes(pAllocator, vis, pBindingBuf, bindNum); + + return pObjVis; +} + +AnmObjVisRes::AnmObjVisRes(MEMAllocator* pAllocator, ResAnmVis vis, + u16* pBindingBuf, int numBinding) + : AnmObjVis(pAllocator, pBindingBuf, numBinding), + FrameCtrl(0.0f, vis.GetNumFrame(), GetAnmPlayPolicy(vis.GetAnmPolicy())), + mRes(vis) {} + +void AnmObjVisRes::SetFrame(f32 frame) { + SetFrm(frame); + G3dProc(G3DPROC_UPDATEFRAME, 0, NULL); +} + +f32 AnmObjVisRes::GetFrame() const { + return GetFrm(); +} + +void AnmObjVisRes::SetUpdateRate(f32 rate) { + SetRate(rate); +} + +f32 AnmObjVisRes::GetUpdateRate() const { + return GetRate(); +} + +void AnmObjVisRes::UpdateFrame() { + UpdateFrm(); + G3dProc(G3DPROC_UPDATEFRAME, 0, NULL); +} + +bool AnmObjVisRes::Bind(ResMdl mdl) { + int numAnim = mRes.GetNumNode(); + bool success = false; + + for (u16 i = 0; i < numAnim; i++) { + const ResAnmVisAnmData* pData = mRes.GetNodeAnm(i); + + // Seek back from name string to start of ResName + ResName name(ut::AddOffsetToPtr(pData, pData->name - 4)); + + ResNode node = mdl.GetResNode(name); + if (!node.IsValid()) { + continue; + } + + mpBinding[node.GetID()] = i; + success = true; + } + + SetAnmFlag(FLAG_ANM_BOUND, true); + return success; +} + +bool AnmObjVisRes::GetResult(u32 idx) { + u32 id = mpBinding[idx]; + + if ((id & BINDING_INVALID) || (id & BINDING_UNDEFINED)) { + return true; + } + + return mRes.GetAnmResult(id, GetFrm()); +} + +/****************************************************************************** + * + * ApplyVisAnmResult + * + ******************************************************************************/ +void ApplyVisAnmResult(ResMdl mdl, AnmObjVis* pObj) { + u32 numNode = mdl.GetResNodeNumEntries(); + + for (u32 i = 0; i < numNode; i++) { + if (!pObj->TestExistence(i)) { + continue; + } + + ResNode node = mdl.GetResNode(i); + node.SetVisibility(pObj->GetResult(i)); + } +} + +void ApplyVisAnmResult(u8* byteVec, ResMdl mdl, AnmObjVis* pObj) { + u32 numNode = mdl.GetResNodeNumEntries(); + + for (u32 i = 0; i < numNode; i++) { + if (!pObj->TestExistence(i)) { + continue; + } + + byteVec[i] = pObj->GetResult(i); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_basic.cpp b/src/nw4r/g3d/g3d_basic.cpp new file mode 100644 index 00000000..293f6362 --- /dev/null +++ b/src/nw4r/g3d/g3d_basic.cpp @@ -0,0 +1,61 @@ +#include + +namespace nw4r { +namespace g3d { +namespace detail { +namespace dcc { + +u32 CalcWorldMtx_Basic(math::MTX34* pW, math::VEC3* pS, const math::MTX34* pW1, + const math::VEC3* pS1, u32 attr, + const ChrAnmResult* pResult) { + + u32 flag = pResult->flags; + u32 newAttr = attr; + + if (flag & ChrAnmResult::FLAG_SCALE_ONE) { + newAttr = detail::WorldMtxAttr::AnmScaleOne(newAttr); + pS->x = pS->y = pS->z = 1.0f; + } else { + newAttr = detail::WorldMtxAttr::AnmNotScaleOne(newAttr); + *pS = pResult->s; + } + + if ((flag & ChrAnmResult::FLAG_MTX_IDENT) || + (flag & ChrAnmResult::FLAG_ROT_TRANS_ZERO)) { + + if (detail::WorldMtxAttr::IsScaleOne(attr)) { + math::MTX34Copy(pW, pW1); + } else { + math::MTX34Scale(pW, pW1, pS1); + } + } else if (flag & ChrAnmResult::FLAG_ROT_ZERO) { + if (detail::WorldMtxAttr::IsScaleOne(attr)) { + math::VEC3 trans(pResult->rt._03, pResult->rt._13, pResult->rt._23); + + math::MTX34Trans(pW, pW1, &trans); + } else { + math::MTX34 temp; + + math::MTX34Scale(&temp, pS1, &pResult->rt); + math::MTX34Mult(pW, pW1, &temp); + } + } else if (detail::WorldMtxAttr::IsScaleOne(attr)) { + math::MTX34Mult(pW, pW1, &pResult->rt); + } else { + math::MTX34Scale(pW, pW1, pS1); + math::MTX34Mult(pW, pW, &pResult->rt); + } + + if (flag & ChrAnmResult::FLAG_SCALE_UNIFORM) { + newAttr = detail::WorldMtxAttr::AnmScaleUniform(newAttr); + } else { + newAttr = detail::WorldMtxAttr::AnmNotScaleUniform(newAttr); + } + + return newAttr; +} + +} // namespace dcc +} // namespace detail +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_calcmaterial.cpp b/src/nw4r/g3d/g3d_calcmaterial.cpp new file mode 100644 index 00000000..38392db3 --- /dev/null +++ b/src/nw4r/g3d/g3d_calcmaterial.cpp @@ -0,0 +1,61 @@ +#include + +namespace nw4r { +namespace g3d { + +void CalcMaterialDirectly(ResMdl mdl, AnmObjTexPat* pAnmTexPat, + AnmObjTexSrt* pAnmTexSrt, AnmObjMatClr* pAnmMatClr) { + + u32 i; + u32 numMatID = mdl.GetResMatNumEntries(); + + for (i = 0; i < numMatID; i++) { + ResMat mat = mdl.GetResMat(i); + + if (pAnmTexPat != NULL && pAnmTexPat->TestExistence(i)) { + TexPatAnmResult result; + const TexPatAnmResult* pResult; + + pResult = pAnmTexPat->GetResult(&result, i); + + ApplyTexPatAnmResult(mat.GetResTexObj(), mat.GetResTlutObj(), + pResult); + + mat.GetResTexObj().EndEdit(); + mat.GetResTlutObj().EndEdit(); + } + + if (pAnmTexSrt != NULL && pAnmTexSrt->TestExistence(i)) { + TexSrtAnmResult result; + const TexSrtAnmResult* pResult; + + ResTexSrt srt = mat.GetResTexSrt(); + ResMatIndMtxAndScale ind = mat.GetResMatIndMtxAndScale(); + + pResult = pAnmTexSrt->GetResult(&result, i); + + ApplyTexSrtAnmResult(srt, ind, pResult); + + ind.EndEdit(); + srt.EndEdit(); + } + + if (pAnmMatClr != NULL && pAnmMatClr->TestExistence(i)) { + ClrAnmResult result; + const ClrAnmResult* pResult; + + ResMatTevColor tevColor = mat.GetResMatTevColor(); + ResMatChan chan = mat.GetResMatChan(); + + pResult = pAnmMatClr->GetResult(&result, i); + + ApplyClrAnmResult(chan, tevColor, pResult); + + chan.EndEdit(); + tevColor.EndEdit(); + } + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_calcview.cpp b/src/nw4r/g3d/g3d_calcview.cpp new file mode 100644 index 00000000..5dd076a0 --- /dev/null +++ b/src/nw4r/g3d/g3d_calcview.cpp @@ -0,0 +1,963 @@ +#include + +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * Paired-single math implementation + * + ******************************************************************************/ +namespace { + +// Allows struct offsets inside assembly +using nw4r::math::MTX34; +using nw4r::math::VEC3; + +asm void GetModelLocalAxisY2(register math::VEC3* pVec, + register const math::MTX34* pModelMtx, + register const math::MTX34* pParentModelMtx) { + // clang-format off + nofralloc + + psq_l f2, MTX34._10(pParentModelMtx), 1, 0 + psq_l f3, MTX34._11(pParentModelMtx), 0, 0 + psq_l f0, MTX34._00(pParentModelMtx), 1, 0 + psq_l f1, MTX34._01(pParentModelMtx), 0, 0 + ps_merge10 f7, f3, f2 + psq_l f5, MTX34._21(pParentModelMtx), 0, 0 + psq_l f4, MTX34._20(pParentModelMtx), 1, 0 + ps_merge10 f6, f1, f0 + ps_mul f12, f5, f7 + ps_merge10 f8, f5, f4 + ps_mul f10, f3, f6 + ps_mul f9, f0, f5 + ps_mul f11, f1, f8 + ps_msub f12, f3, f8, f12 + ps_msub f10, f1, f7, f10 + ps_msub f11, f5, f6, f11 + ps_mul f7, f0, f12 + ps_sub f6, f6, f6 + ps_msub f9, f1, f4, f9 + ps_madd f7, f2, f11, f7 + stfs f6, VEC3.z(pVec) + ps_madd f7, f4, f10, f7 + ps_cmpo0 cr0, f7, f6 + bne _lbl_80068168 + psq_st f6, VEC3.x(pVec), 0, 0 + + blr + +_lbl_80068168: + fres f0, f7 + psq_l f1, MTX34._10(pModelMtx), 0, 0 + psq_l f2, MTX34._02(pModelMtx), 1, 0 + psq_l f3, MTX34._12(pModelMtx), 1, 0 + ps_add f6, f0, f0 + ps_mul f5, f0, f0 + ps_nmsub f0, f7, f5, f6 + ps_merge00 f6, f2, f3 + ps_muls0 f11, f11, f0 + ps_muls0 f9, f9, f0 + psq_l f0, MTX34._00(pModelMtx), 0, 0 + ps_merge00 f4, f0, f1 + ps_merge11 f5, f0, f1 + ps_muls0 f0, f4, f11 + ps_madds1 f0, f5, f11, f0 + ps_madds0 f0, f6, f9, f0 + psq_st f0, VEC3.x(pVec), 0, 0 + + blr + // clang-format on +} + +asm void GetModelLocalAxisY3(register math::VEC3* pVec, + register const math::MTX34* pModelMtx, + register const math::MTX34* pParentModelMtx) { + // clang-format off + nofralloc + + psq_l f2, MTX34._10(pParentModelMtx), 1, 0 + psq_l f3, MTX34._11(pParentModelMtx), 0, 0 + psq_l f0, MTX34._00(pParentModelMtx), 1, 0 + psq_l f1, MTX34._01(pParentModelMtx), 0, 0 + ps_merge10 f7, f3, f2 + psq_l f5, MTX34._21(pParentModelMtx), 0, 0 + psq_l f4, MTX34._20(pParentModelMtx), 1, 0 + ps_merge10 f6, f1, f0 + ps_mul f12, f5, f7 + ps_merge10 f8, f5, f4 + ps_mul f10, f3, f6 + ps_mul f9, f0, f5 + ps_mul f11, f1, f8 + ps_msub f12, f3, f8, f12 + ps_msub f10, f1, f7, f10 + ps_msub f11, f5, f6, f11 + ps_mul f7, f0, f12 + ps_sub f6, f6, f6 + ps_msub f9, f1, f4, f9 + ps_madd f7, f2, f11, f7 + ps_madd f7, f4, f10, f7 + ps_cmpo0 cr0, f7, f6 + bne _lbl_80068218 + psq_st f6, VEC3.x(pVec), 0, 0 + stfs f6, VEC3.z(pVec) + + blr + +_lbl_80068218: + fres f0, f7 + psq_l f1, MTX34._10(pModelMtx), 0, 0 + psq_l f2, MTX34._02(pModelMtx), 1, 0 + psq_l f3, MTX34._12(pModelMtx), 1, 0 + ps_add f6, f0, f0 + ps_mul f5, f0, f0 + ps_nmsub f0, f7, f5, f6 + ps_merge00 f6, f2, f3 + psq_l f2, MTX34._22(pModelMtx), 1, 0 + ps_muls0 f11, f11, f0 + ps_muls0 f9, f9, f0 + psq_l f0, MTX34._00(pModelMtx), 0, 0 + ps_merge00 f4, f0, f1 + ps_merge11 f5, f0, f1 + psq_l f1, MTX34._20(pModelMtx), 0, 0 + ps_muls0 f0, f4, f11 + ps_mul f1, f1, f9 + ps_madds1 f0, f5, f11, f0 + ps_sum0 f1, f1, f1, f1 + ps_madds0 f0, f6, f9, f0 + fmadds f1, f2, f9, f1 + psq_st f0, VEC3.x(pVec), 0, 0 + psq_st f1, VEC3.z(pVec), 1, 0 + + blr + // clang-format on +} + +inline void SetMdlViewMtxSR(register math::MTX34* pViewPos, + register const math::VEC3& rRY, register f32 s) { + register f32 work0, work1; + register f32 c_zero = 0.0f; + + // clang-format off + asm { + psq_l work0, VEC3.x(rRY), 0, 0 + ps_muls0 work0, work0, s + ps_merge10 work1, work0, work0 + psq_st work1, MTX34._00(pViewPos), 0, 0 + ps_neg work1, work0 + ps_merge01 work1, work1, work0 + psq_st work1, MTX34._10(pViewPos), 0, 0 + stfs c_zero, MTX34._02(pViewPos) + stfs c_zero, MTX34._12(pViewPos) + psq_st c_zero, MTX34._20(pViewPos), 0, 0 + stfs s, MTX34._22(pViewPos) + } + // clang-format on +} + +inline void SetMdlViewMtxSR(register math::MTX34* pViewPos, + register const math::VEC3& rRY, register f32 sx, + register f32 sy, register f32 sz) { + + register f32 work0, work1, work2, work3; + register f32 c_zero = 0.0f; + + // clang-format off + asm { + ps_merge00 work0, sx, sy + psq_l work1, VEC3.x(rRY), 0, 0 + ps_merge10 work3, work1, work1 + ps_mul work3, work3, work0 + psq_st work3, MTX34._00(pViewPos), 0, 0 + ps_neg work2, work1 + ps_merge01 work3, work2, work1 + ps_mul work3, work3, work0 + psq_st work3, MTX34._10(pViewPos), 0, 0 + stfs c_zero, MTX34._02(pViewPos) + stfs c_zero, MTX34._12(pViewPos) + psq_st c_zero, MTX34._20(pViewPos), 0, 0 + stfs sz, MTX34._22(pViewPos) + } + // clang-format on +} + +inline void SetMdlViewMtxSR(register math::MTX34* pViewPos, + register const math::VEC3& rRX, + register const math::VEC3& rRY, + register const math::VEC3& rRZ, register f32 sx, + register f32 sy, register f32 sz) { + + register f32 work0, work1, work2, work3; + + // clang-format off + asm { + psq_l work0, VEC3.x(rRX), 0, 0 + psq_l work1, VEC3.x(rRY), 0, 0 + ps_muls0 work0, work0, sx + ps_muls0 work1, work1, sy + ps_merge00 work2, work0, work1 + ps_merge11 work3, work0, work1 + psq_st work2, MTX34._00(pViewPos), 0, 0 + psq_st work3, MTX34._10(pViewPos), 0, 0 + psq_l work0, VEC3.x(rRZ), 0, 0 + ps_muls0 work0, work0, sz + stfs work0, MTX34._02(pViewPos) + ps_merge11 work0, work0, work0 + stfs work0, MTX34._12(pViewPos) + lfs work0, VEC3.z(rRX) + fmuls work0, work0, sx + stfs work0, MTX34._20(pViewPos) + lfs work0, VEC3.z(rRY) + fmuls work0, work0, sy + stfs work0, MTX34._21(pViewPos) + lfs work0, VEC3.z(rRZ) + fmuls work0, work0, sz + stfs work0, MTX34._22(pViewPos) + } + // clang-format on +} + +} // namespace + +/****************************************************************************** + * + * Billboard implementation + * + ******************************************************************************/ +namespace { + +inline f32 GetMtx34Scale(const math::MTX34& rMtx, int col) { + return math::FSqrt(rMtx.m[0][col] * rMtx.m[0][col] + + rMtx.m[1][col] * rMtx.m[1][col] + + rMtx.m[2][col] * rMtx.m[2][col]); +} + +void Calc_BILLBOARD_STD(math::MTX34* pViewPos, + const math::MTX34* pModelMtxArray, bool uniformScale, + const math::MTX34* pViewMtx, const ResMdl mdl, + const u32 id) { + +#pragma unused(pViewMtx) +#pragma unused(mdl) + + math::VEC3 vy(pViewPos->_01, pViewPos->_11, 0.0f); + math::VEC3Normalize(&vy, &vy); + + if (uniformScale) { + f32 s = GetMtx34Scale(pModelMtxArray[id], 0); + SetMdlViewMtxSR(pViewPos, vy, s); + } else { + f32 sx = GetMtx34Scale(pModelMtxArray[id], 0); + f32 sy = GetMtx34Scale(pModelMtxArray[id], 1); + f32 sz = GetMtx34Scale(pModelMtxArray[id], 2); + SetMdlViewMtxSR(pViewPos, vy, sx, sy, sz); + } +} + +void Calc_BILLBOARD_PERSP_STD(math::MTX34* pViewPos, + const math::MTX34* pModelMtxArray, + bool uniformScale, const math::MTX34* pViewMtx, + const ResMdl mdl, const u32 id) { + +#pragma unused(pViewMtx) +#pragma unused(mdl) + + math::VEC3 vx; + math::VEC3 vy(pViewPos->_01, pViewPos->_11, pViewPos->_21); + math::VEC3 vz(-pViewPos->_03, -pViewPos->_13, -pViewPos->_23); + + math::VEC3Normalize(&vz, &vz); + math::VEC3Cross(&vx, &vy, &vz); + + math::VEC3Normalize(&vx, &vx); + math::VEC3Cross(&vy, &vz, &vx); + + if (uniformScale) { + f32 s = GetMtx34Scale(pModelMtxArray[id], 0); + SetMdlViewMtxSR(pViewPos, vx, vy, vz, s, s, s); + } else { + f32 sx = GetMtx34Scale(pModelMtxArray[id], 0); + f32 sy = GetMtx34Scale(pModelMtxArray[id], 1); + f32 sz = GetMtx34Scale(pModelMtxArray[id], 2); + SetMdlViewMtxSR(pViewPos, vx, vy, vz, sx, sy, sz); + } +} + +void Calc_BILLBOARD_ROT(math::MTX34* pViewPos, + const math::MTX34* pModelMtxArray, bool uniformScale, + const math::MTX34* pViewMtx, const ResMdl mdl, + const u32 id) { + +#pragma unused(pViewMtx) + + math::VEC3 vy; + + int nodeID = mdl.GetResMdlInfo().GetNodeIDFromMtxID(id); + + if (nodeID >= 0) { + ResNode node = mdl.GetResNode(nodeID); + ResNode parent = node.GetParentNode(); + + if (parent.IsValid()) { + u32 parentMtxID = parent.GetMtxID(); + GetModelLocalAxisY2(&vy, &pModelMtxArray[id], + &pModelMtxArray[parentMtxID]); + } else { + vy.x = pModelMtxArray[id]._01; + vy.y = pModelMtxArray[id]._11; + vy.z = 0.0f; + } + } else { + vy.x = pModelMtxArray[id]._01; + vy.y = pModelMtxArray[id]._11; + vy.z = 0.0f; + } + + math::VEC3Normalize(&vy, &vy); + + if (uniformScale) { + f32 s = GetMtx34Scale(pModelMtxArray[id], 0); + SetMdlViewMtxSR(pViewPos, vy, s); + } else { + f32 sx = GetMtx34Scale(pModelMtxArray[id], 0); + f32 sy = GetMtx34Scale(pModelMtxArray[id], 1); + f32 sz = GetMtx34Scale(pModelMtxArray[id], 2); + SetMdlViewMtxSR(pViewPos, vy, sx, sy, sz); + } +} + +void Calc_BILLBOARD_PERSP_ROT(math::MTX34* pViewPos, + const math::MTX34* pModelMtxArray, + bool uniformScale, const math::MTX34* pViewMtx, + const ResMdl mdl, const u32 id) { + +#pragma unused(pViewMtx) + + math::VEC3 vx; + math::VEC3 vy; + math::VEC3 vz(-pViewPos->_03, -pViewPos->_13, -pViewPos->_23); + + int nodeID = mdl.GetResMdlInfo().GetNodeIDFromMtxID(id); + + if (nodeID >= 0) { + ResNode node = mdl.GetResNode(nodeID); + ResNode parent = node.GetParentNode(); + + if (parent.IsValid()) { + u32 parentMtxID = parent.GetMtxID(); + GetModelLocalAxisY3(&vy, &pModelMtxArray[id], + &pModelMtxArray[parentMtxID]); + } else { + vy.x = pModelMtxArray[id]._01; + vy.y = pModelMtxArray[id]._11; + vy.z = pModelMtxArray[id]._21; + } + } else { + vy.x = pModelMtxArray[id]._01; + vy.y = pModelMtxArray[id]._11; + vy.z = pModelMtxArray[id]._21; + } + + math::VEC3Normalize(&vz, &vz); + math::VEC3Cross(&vx, &vy, &vz); + + math::VEC3Normalize(&vx, &vx); + math::VEC3Cross(&vy, &vz, &vx); + + if (uniformScale) { + f32 s = GetMtx34Scale(pModelMtxArray[id], 0); + SetMdlViewMtxSR(pViewPos, vx, vy, vz, s, s, s); + } else { + f32 sx = GetMtx34Scale(pModelMtxArray[id], 0); + f32 sy = GetMtx34Scale(pModelMtxArray[id], 1); + f32 sz = GetMtx34Scale(pModelMtxArray[id], 2); + SetMdlViewMtxSR(pViewPos, vx, vy, vz, sx, sy, sz); + } +} + +void Calc_BILLBOARD_Y(math::MTX34* pViewPos, const math::MTX34* pModelMtxArray, + bool uniformScale, const math::MTX34* pViewMtx, + const ResMdl mdl, const u32 id) { + +#pragma unused(pViewMtx) +#pragma unused(mdl) + + math::VEC3 vz; + math::VEC3 vy(pViewPos->_01, pViewPos->_11, pViewPos->_21); + math::VEC3 vx(vy.y, -vy.x, 0.0f); + + f32 sy = GetMtx34Scale(pModelMtxArray[id], 1); + f32 invSY = math::FInv(sy); + + vy *= invSY; + + math::VEC3Normalize(&vx, &vx); + math::VEC3Cross(&vz, &vx, &vy); + + if (uniformScale) { + SetMdlViewMtxSR(pViewPos, vx, vy, vz, sy, sy, sy); + } else { + f32 sx = GetMtx34Scale(pModelMtxArray[id], 0); + f32 sz = GetMtx34Scale(pModelMtxArray[id], 2); + SetMdlViewMtxSR(pViewPos, vx, vy, vz, sx, sy, sz); + } +} + +void Calc_BILLBOARD_PERSP_Y(math::MTX34* pViewPos, + const math::MTX34* pModelMtxArray, + bool uniformScale, const math::MTX34* pViewMtx, + const ResMdl mdl, const u32 id) { + +#pragma unused(pViewMtx) +#pragma unused(mdl) + + math::VEC3 vx; + math::VEC3 vy(pViewPos->_01, pViewPos->_11, pViewPos->_21); + math::VEC3 vz(-pViewPos->_03, -pViewPos->_13, -pViewPos->_23); + + f32 sy = GetMtx34Scale(pModelMtxArray[id], 1); + f32 invSY = math::FInv(sy); + + vy *= invSY; + math::VEC3Cross(&vx, &vy, &vz); + + math::VEC3Normalize(&vx, &vx); + math::VEC3Cross(&vz, &vx, &vy); + + if (uniformScale) { + SetMdlViewMtxSR(pViewPos, vx, vy, vz, sy, sy, sy); + } else { + f32 sx = GetMtx34Scale(pModelMtxArray[id], 0); + f32 sz = GetMtx34Scale(pModelMtxArray[id], 2); + SetMdlViewMtxSR(pViewPos, vx, vy, vz, sx, sy, sz); + } +} + +typedef void (*BillBoardFunc)(math::MTX34* pViewPos, + const math::MTX34* pModelMtxArray, + bool uniformScale, const math::MTX34* pViewMtx, + const ResMdl mdl, const u32 id); + +const BillBoardFunc bbFunc[ResNodeData::NUM_BILLBOARD] = { + NULL, // BILLBOARD_OFF is ignored + + Calc_BILLBOARD_STD, // + Calc_BILLBOARD_PERSP_STD, // + + Calc_BILLBOARD_ROT, // + Calc_BILLBOARD_PERSP_ROT, // + + Calc_BILLBOARD_Y, // + Calc_BILLBOARD_PERSP_Y // +}; + +} // namespace + +/****************************************************************************** + * + * CalcView + * + ******************************************************************************/ +void CalcView(math::MTX34* pViewPosArray, math::MTX33* pViewNrmArray, + const math::MTX34* pModelMtxArray, + const u32* pModelMtxAttribArray, u32 numMtx, + const math::MTX34* pViewMtx, const ResMdl mdl, + math::MTX34* pViewTexMtxArray) { + + if (numMtx <= 0) { + return; + } + + math::MTX34* pVArray; + math::MTX33* pNArray; + math::MTX34* pCurTArray; + + u32 sizeVArray = align32(numMtx * sizeof(math::MTX34)); + u32 sizeNArray = align32(numMtx * sizeof(math::MTX33)); + u32 sizeTArray = align32(numMtx * sizeof(math::MTX34)); + + pVArray = pViewPosArray; + + if (numMtx > 1) { + math::MTX34MultArray(pVArray, pViewMtx, pModelMtxArray, numMtx); + } else { + math::MTX34Mult(pVArray, pViewMtx, pModelMtxArray); + } + + math::MTX34* pBbMtxArray = detail::workmem::GetBillboardMtxTemporary(); + + for (u32 i = 0; i < numMtx; i++) { + u32 attr = pModelMtxAttribArray[i]; + + ResNodeData::Billboard bbType = + detail::WorldMtxAttr::GetBillboard(attr); + + if (bbType != ResNodeData::BILLBOARD_OFF) { + math::MTX34& rVMtx = pVArray[i]; + + bbFunc[bbType](&rVMtx, pModelMtxArray, + detail::WorldMtxAttr::IsAllScaleUniform(attr), + pViewMtx, mdl, i); + + s32 nodeID = mdl.GetResMdlInfo().GetNodeIDFromMtxID(i); + ResNode node = mdl.GetResNode(static_cast(nodeID)); + + if (node.IsValid() && node.GetChildNode().IsValid()) { + math::MTX34 invWorld; + + u32 ret = math::MTX34Inv(&invWorld, &pModelMtxArray[i]); + if (ret == TRUE) { + math::MTX34Mult(&pBbMtxArray[i], &pVArray[i], &invWorld); + } else { + math::MTX34Identity(&pBbMtxArray[i]); + } + } + } else { + s32 nodeID = mdl.GetResMdlInfo().GetNodeIDFromMtxID(i); + if (nodeID < 0) { + continue; + } + + ResNode node = mdl.GetResNode(static_cast(nodeID)); + if (!node.IsValid()) { + continue; + } + + if (!(node.ref().flags & ResNodeData::FLAG_BILLBOARD_PARENT)) { + continue; + } + + u32 bbMtxID = mdl.GetResNode(node.ref().bbref_nodeid).GetMtxID(); + + math::MTX34Mult(&pVArray[i], &pBbMtxArray[bbMtxID], + &pModelMtxArray[i]); + } + } + + pNArray = pViewNrmArray; + pCurTArray = pViewTexMtxArray; + + if (pNArray != NULL) { + for (u32 i = 0; i < numMtx; i++) { + math::MTX34& rVMtx = pVArray[i]; + math::MTX33& rNMtx = pNArray[i]; + u32 attr = pModelMtxAttribArray[i]; + + if (detail::WorldMtxAttr::IsAllScaleUniform(attr)) { + if (pCurTArray != NULL) { + math::MTX34Copy(&pCurTArray[i], &rVMtx); + pCurTArray[i]._03 = pCurTArray[i]._13 = pCurTArray[i]._23 = + 0.0f; + } + + math::MTX34ToMTX33(&rNMtx, &rVMtx); + } else { + if (pCurTArray != NULL) { + math::MTX34InvTranspose(&pCurTArray[i], &rVMtx); + math::MTX34ToMTX33(&rNMtx, &pCurTArray[i]); + } else { + math::MTX34InvTranspose(&rNMtx, &rVMtx); + } + } + } + } + + DC::FlushRangeNoSync(pVArray, sizeVArray); + + if (pNArray != NULL) { + DC::FlushRangeNoSync(pViewNrmArray, sizeNArray); + + if (pCurTArray != NULL) { + DC::FlushRangeNoSync(pViewTexMtxArray, sizeTArray); + } + } +} + +void CalcView_LC(math::MTX34* pViewPosArray, math::MTX33* pViewNrmArray, + const math::MTX34* pModelMtxArray, + const u32* pModelMtxAttribArray, u32 numMtx, + const math::MTX34* pViewMtx, const ResMdl mdl, + math::MTX34* pViewTexMtxArray) { + + if (numMtx <= 0) { + return; + } + + detail::MtxCacheMap* pMtxCache = + static_cast(ut::LC::GetBase()); + + math::MTX34* pCurVArray = + reinterpret_cast(pMtxCache->currViewArray); + math::MTX33* pCurNArray = + reinterpret_cast(pMtxCache->currNrmArray); + math::MTX34* pCurTArray = + reinterpret_cast(pMtxCache->currTexArray); + + math::MTX34* pPrevVArray = + reinterpret_cast(pMtxCache->prevViewArray); + math::MTX33* pPrevNArray = + reinterpret_cast(pMtxCache->prevNrmArray); + math::MTX34* pPrevTArray = + reinterpret_cast(pMtxCache->prevTexArray); + + u32 sizeVArray = align32(numMtx * sizeof(math::MTX34)); + DC::InvalidateRange(pViewPosArray, sizeVArray); + + u32 queueLen = 1; + u32 sizeNArray, sizeTArray; + + if (pViewNrmArray != NULL) { + queueLen++; + + sizeNArray = align32(numMtx * sizeof(math::MTX33)); + DC::InvalidateRange(pViewNrmArray, sizeNArray); + + if (pViewTexMtxArray != NULL) { + queueLen++; + + sizeTArray = align32(numMtx * sizeof(math::MTX34)); + DC::InvalidateRange(pViewTexMtxArray, sizeTArray); + } + } + + math::MTX34* pBbMtxArray = detail::workmem::GetBillboardMtxTemporary(); + + ut::LC::QueueWait(0); + + u32 baseMtx; + for (baseMtx = 0; baseMtx < numMtx; baseMtx += 40) { + u32 remain = numMtx - baseMtx; + + u32 numBlocks, numBlocksNrm; + if (remain > 40) { + remain = 40; + numBlocks = 60; + numBlocksNrm = 45; + } else { + numBlocks = align32(remain * sizeof(math::MTX34)) / 32; + numBlocksNrm = align32(remain * sizeof(math::MTX33)) / 32; + } + + ut::LC::QueueWait(queueLen); + + if (remain > 1) { + math::MTX34MultArray(pCurVArray, pViewMtx, &pModelMtxArray[baseMtx], + remain); + } else { + math::MTX34Mult(pCurVArray, pViewMtx, &pModelMtxArray[baseMtx]); + } + + for (u32 i = 0; i < remain; i++) { + u32 attr = pModelMtxAttribArray[baseMtx + i]; + + ResNodeData::Billboard bbType = + detail::WorldMtxAttr::GetBillboard(attr); + + if (bbType != ResNodeData::BILLBOARD_OFF) { + math::MTX34& rVMtx = pCurVArray[i]; + + bbFunc[bbType](&rVMtx, pModelMtxArray, + detail::WorldMtxAttr::IsAllScaleUniform(attr), + pViewMtx, mdl, baseMtx + i); + + s32 nodeID = + mdl.GetResMdlInfo().GetNodeIDFromMtxID(baseMtx + i); + + ResNode node = mdl.GetResNode(static_cast(nodeID)); + + if (node.IsValid() && node.GetChildNode().IsValid()) { + math::MTX34 invWorld; + + u32 ret = + math::MTX34Inv(&invWorld, &pModelMtxArray[baseMtx + i]); + + if (ret == TRUE) { + math::MTX34Mult(&pBbMtxArray[baseMtx + i], + &pCurVArray[i], &invWorld); + } else { + math::MTX34Identity(&pBbMtxArray[baseMtx + i]); + } + } + } else { + s32 nodeID = + mdl.GetResMdlInfo().GetNodeIDFromMtxID(baseMtx + i); + if (nodeID < 0) { + continue; + } + + ResNode node = mdl.GetResNode(static_cast(nodeID)); + if (!node.IsValid()) { + continue; + } + + if (!(node.ref().flags & ResNodeData::FLAG_BILLBOARD_PARENT)) { + continue; + } + + u32 bbMtxID = + mdl.GetResNode(node.ref().bbref_nodeid).GetMtxID(); + + math::MTX34Mult(&pCurVArray[i], &pBbMtxArray[bbMtxID], + &pModelMtxArray[baseMtx + i]); + } + } + + ut::LC::StoreBlocks(&pViewPosArray[baseMtx], pCurVArray, numBlocks); + + if (pViewNrmArray != NULL) { + for (u32 i = 0; i < remain; i++) { + math::MTX34& rVMtx = pCurVArray[i]; + math::MTX33& rNMtx = pCurNArray[i]; + u32 attr = pModelMtxAttribArray[baseMtx + i]; + + if (detail::WorldMtxAttr::IsAllScaleUniform(attr)) { + if (pViewTexMtxArray != NULL) { + math::MTX34Copy(&pCurTArray[i], &rVMtx); + + pCurTArray[i]._03 = pCurTArray[i]._13 = + pCurTArray[i]._23 = 0.0f; + } + + math::MTX34ToMTX33(&rNMtx, &rVMtx); + } else { + if (pViewTexMtxArray != NULL) { + math::MTX34InvTranspose(&pCurTArray[i], &rVMtx); + math::MTX34ToMTX33(&rNMtx, &pCurTArray[i]); + } else { + math::MTX34InvTranspose(&rNMtx, &rVMtx); + } + } + } + } + + if (pViewNrmArray != NULL) { + ut::LC::StoreBlocks(&pViewNrmArray[baseMtx], pCurNArray, + numBlocksNrm); + + if (pViewTexMtxArray != NULL) { + ut::LC::StoreBlocks(&pViewTexMtxArray[baseMtx], pCurTArray, + numBlocks); + } + } + + std::swap(pCurVArray, pPrevVArray); + std::swap(pCurNArray, pPrevNArray); + std::swap(pCurTArray, pPrevTArray); + } +} + +void CalcView_LC_DMA_ModelMtx(math::MTX34* pViewPosArray, + math::MTX33* pViewNrmArray, + const math::MTX34* pModelMtxArray, + const u32* pModelMtxAttribArray, u32 numMtx, + const math::MTX34* pViewMtx, const ResMdl mdl, + math::MTX34* pViewTexMtxArray) { + + if (numMtx <= 0) { + return; + } + + detail::MtxCacheMap* pMtxCache = + static_cast(ut::LC::GetBase()); + + math::MTX34* pCurMArray = + reinterpret_cast(pMtxCache->currDmaArray); + math::MTX34* pCurVArray = + reinterpret_cast(pMtxCache->currViewArray); + math::MTX33* pCurNArray = + reinterpret_cast(pMtxCache->currNrmArray); + math::MTX34* pCurTArray = + reinterpret_cast(pMtxCache->currTexArray); + + math::MTX34* pPrevMArray = + reinterpret_cast(pMtxCache->prevDmaArray); + math::MTX34* pPrevVArray = + reinterpret_cast(pMtxCache->prevViewArray); + math::MTX33* pPrevNArray = + reinterpret_cast(pMtxCache->prevNrmArray); + math::MTX34* pPrevTArray = + reinterpret_cast(pMtxCache->prevTexArray); + + u32 sizeVArray = align32(numMtx * sizeof(math::MTX34)); + DC::InvalidateRange(pViewPosArray, sizeVArray); + + u32 queueLen = 1; + u32 sizeNArray, sizeTArray; + + if (pViewNrmArray != NULL) { + queueLen++; + + sizeNArray = align32(numMtx * sizeof(math::MTX33)); + DC::InvalidateRange(pViewNrmArray, sizeNArray); + + if (pViewTexMtxArray != NULL) { + queueLen++; + + sizeTArray = align32(numMtx * sizeof(math::MTX34)); + DC::InvalidateRange(pViewTexMtxArray, sizeTArray); + } + } + + math::MTX34* pBbMtxArray = detail::workmem::GetBillboardMtxTemporary(); + + ut::LC::QueueWait(0); + + u32 numBlocks; + if (numMtx > 40) { + numBlocks = 60; + } else { + numBlocks = align32(numMtx * sizeof(math::MTX34)) / 32; + } + + ut::LC::LoadBlocks(pCurMArray, const_cast(pModelMtxArray), + numBlocks); + + if (numMtx > 20) { + ut::LC::QueueWaitEx(0); + } else { + ut::LC::QueueWait(0); + } + + u32 baseMtx; + for (baseMtx = 0; baseMtx < numMtx; baseMtx += 40) { + u32 remain = numMtx - baseMtx; + + u32 numBlocks, numBlocksNrm; + if (remain > 40) { + remain = 40; + numBlocks = 60; + numBlocksNrm = 45; + } else { + numBlocks = align32(remain * sizeof(math::MTX34)) / 32; + numBlocksNrm = align32(remain * sizeof(math::MTX33)) / 32; + } + + ut::LC::QueueWait(queueLen); + + if (baseMtx + 40 < numMtx) { + u32 n = numMtx - baseMtx - 40; + + u32 blocks; + if (n > 40) { + blocks = 60; + } else { + blocks = align32(n * sizeof(math::MTX34)) / 32; + } + + ut::LC::LoadBlocks( + pPrevMArray, + const_cast(&pModelMtxArray[baseMtx + 40]), + blocks); + } + + if (remain > 1) { + math::MTX34MultArray(pCurVArray, pViewMtx, pCurMArray, remain); + } else { + math::MTX34Mult(pCurVArray, pViewMtx, pCurMArray); + } + + for (u32 i = 0; i < remain; i++) { + u32 attr = pModelMtxAttribArray[baseMtx + i]; + + ResNodeData::Billboard bbType = + detail::WorldMtxAttr::GetBillboard(attr); + + if (bbType != ResNodeData::BILLBOARD_OFF) { + math::MTX34& rVMtx = pCurVArray[i]; + + bbFunc[bbType](&rVMtx, pModelMtxArray, + detail::WorldMtxAttr::IsAllScaleUniform(attr), + pViewMtx, mdl, baseMtx + i); + + s32 nodeID = + mdl.GetResMdlInfo().GetNodeIDFromMtxID(baseMtx + i); + + ResNode node = mdl.GetResNode(static_cast(nodeID)); + + if (node.IsValid() && node.GetChildNode().IsValid()) { + math::MTX34 invWorld; + + u32 ret = + math::MTX34Inv(&invWorld, &pModelMtxArray[baseMtx + i]); + + if (ret == TRUE) { + math::MTX34Mult(&pBbMtxArray[baseMtx + i], + &pCurVArray[i], &invWorld); + } else { + math::MTX34Identity(&pBbMtxArray[baseMtx + i]); + } + } + } else { + s32 nodeID = + mdl.GetResMdlInfo().GetNodeIDFromMtxID(baseMtx + i); + if (nodeID < 0) { + continue; + } + + ResNode node = mdl.GetResNode(static_cast(nodeID)); + if (!node.IsValid()) { + continue; + } + + if (!(node.ref().flags & ResNodeData::FLAG_BILLBOARD_PARENT)) { + continue; + } + + u32 bbMtxID = + mdl.GetResNode(node.ref().bbref_nodeid).GetMtxID(); + + math::MTX34Mult(&pCurVArray[i], &pBbMtxArray[bbMtxID], + &pModelMtxArray[baseMtx + i]); + } + } + + ut::LC::StoreBlocks(&pViewPosArray[baseMtx], pCurVArray, numBlocks); + + if (pViewNrmArray != NULL) { + for (u32 i = 0; i < remain; i++) { + math::MTX34& rVMtx = pCurVArray[i]; + math::MTX33& rNMtx = pCurNArray[i]; + u32 attr = pModelMtxAttribArray[baseMtx + i]; + + if (detail::WorldMtxAttr::IsAllScaleUniform(attr)) { + if (pViewTexMtxArray != NULL) { + math::MTX34Copy(&pCurTArray[i], &rVMtx); + + pCurTArray[i]._03 = pCurTArray[i]._13 = + pCurTArray[i]._23 = 0.0f; + } + + math::MTX34ToMTX33(&rNMtx, &rVMtx); + } else { + if (pViewTexMtxArray != NULL) { + math::MTX34InvTranspose(&pCurTArray[i], &rVMtx); + math::MTX34ToMTX33(&rNMtx, &pCurTArray[i]); + } else { + math::MTX34InvTranspose(&rNMtx, &rVMtx); + } + } + } + } + + if (pViewNrmArray != NULL) { + ut::LC::StoreBlocks(&pViewNrmArray[baseMtx], pCurNArray, + numBlocksNrm); + + if (pViewTexMtxArray != NULL) { + ut::LC::StoreBlocks(&pViewTexMtxArray[baseMtx], pCurTArray, + numBlocks); + } + } + + std::swap(pCurMArray, pPrevMArray); + std::swap(pCurVArray, pPrevVArray); + std::swap(pCurNArray, pPrevNArray); + std::swap(pCurTArray, pPrevTArray); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_calcvtx.cpp b/src/nw4r/g3d/g3d_calcvtx.cpp new file mode 100644 index 00000000..2eda30f2 --- /dev/null +++ b/src/nw4r/g3d/g3d_calcvtx.cpp @@ -0,0 +1,345 @@ +#include + +#include + +namespace nw4r { +namespace g3d { + +void CalcVtx(ResMdl mdl, AnmObjShp* pAnmShp, ResVtxPosData** ppVtxPosTable, + ResVtxNrmData** ppVtxNrmTable, ResVtxClrData** ppVtxClrTable) { + + // Allows struct offsets inside assembly + using nw4r::math::VEC3; + using nw4r::ut::Color; + + u32 numVtxPos = mdl.GetResVtxPosNumEntries(); + + for (u32 id = 0; id < numVtxPos; id++) { + if (!pAnmShp->TestExistence(id)) { + continue; + } + + ShpAnmResult result; + const ShpAnmResult* pResult = pAnmShp->GetResult(&result, id); + + if (!(pResult->flags & ShpAnmResult::FLAG_ANM_EXISTS)) { + continue; + } + + if (pResult->flags & ShpAnmResult::FLAG_ANM_VTXPOS) { + struct KeyShape { + const math::VEC3* pVtx; // at 0x0 + f32 weight; // at 0x4 + }; + + ResVtxPos basePos = pResult->baseShapeVtxSet.resVtxPos; + + KeyShape keyShape[ShpAnmResult::MAX_KEY_SHAPE + 1]; + int numKeyShape = 0; + + ResVtxPos vtxPos(ppVtxPosTable[id]); + math::VEC3* pVtxPosBuf = static_cast(vtxPos.GetData()); + + if (pResult->baseShapeWeight != 0.0f) { + const math::VEC3* pBase; + u8 stride; + + basePos.GetArray(reinterpret_cast(&pBase), + &stride); + + keyShape[numKeyShape].pVtx = pBase; + keyShape[numKeyShape].weight = pResult->baseShapeWeight; + numKeyShape++; + } + + for (int i = 0; i < static_cast(pResult->numKeyShape); i++) { + if (pResult->keyShape[i].weight == 0.0f) { + continue; + } + + ResVtxPos key(pResult->keyShape[i].vtxSet.resVtxPos); + const void* pData = key.GetData(); + + keyShape[numKeyShape].pVtx = + static_cast(pData); + keyShape[numKeyShape].weight = pResult->keyShape[i].weight; + numKeyShape++; + } + + u32 numVtx = basePos.GetNumVtxPos(); + + // clang-format off + const math::VEC3* const pVtxPosBufEnd = reinterpret_cast( + reinterpret_cast(pVtxPosBuf) + numVtx * sizeof(math::VEC3)); + // clang-format on + + const KeyShape* const pKeyEnd = keyShape + numKeyShape; + + for (; pVtxPosBuf < pVtxPosBufEnd; pVtxPosBuf++) { + register f32 xy, z_; + + KeyShape& rFirst = keyShape[0]; + register f32 firstWeight = rFirst.weight; + register const void* pVtx = rFirst.pVtx; + + // clang-format off + asm { + psq_l xy, VEC3.x(pVtx), 0, 0 + psq_l z_, VEC3.z(pVtx), 1, 0 + ps_mul xy, xy, firstWeight + ps_mul z_, z_, firstWeight + } + // clang-format on + + // clang-format off + rFirst.pVtx = reinterpret_cast( + reinterpret_cast(rFirst.pVtx) + sizeof(math::VEC3)); + // clang-format on + + for (KeyShape* pKey = &keyShape[1]; pKey < pKeyEnd; pKey++) { + register f32 keyWeight = pKey->weight; + register const void* pKeyVtx = pKey->pVtx; + register f32 key_xy, key_z_; + + // clang-format off + asm { + psq_l key_xy, VEC3.x(pKeyVtx), 0, 0 + psq_l key_z_, VEC3.z(pKeyVtx), 1, 0 + ps_madd xy, key_xy, keyWeight, xy + ps_madd z_, key_z_, keyWeight, z_ + } + // clang-format on + + // clang-format off + pKey->pVtx = reinterpret_cast( + reinterpret_cast(pKey->pVtx) + sizeof(math::VEC3)); + // clang-format on + } + + register void* pDst = pVtxPosBuf; + + // clang-format off + asm { + psq_st xy, VEC3.x(pDst), 0, 0 + psq_st z_, VEC3.z(pDst), 1, 0 + } + // clang-format on + } + + DC::StoreRange(vtxPos.GetData(), numVtx * sizeof(math::VEC3)); + } + + if ((pResult->flags & ShpAnmResult::FLAG_ANM_VTXNRM) && + ppVtxNrmTable != NULL) { + + struct KeyShape { + const math::VEC3* pVtx; // at 0x0 + f32 weight; // at 0x4 + }; + + ResVtxNrm baseNrm = pResult->baseShapeVtxSet.resVtxNrm; + + KeyShape keyShape[ShpAnmResult::MAX_KEY_SHAPE + 1]; + int numKeyShape = 0; + + ResVtxNrm vtxNrm(ppVtxNrmTable[baseNrm.GetID()]); + math::VEC3* pVtxNrmBuf = static_cast(vtxNrm.GetData()); + + if (pResult->baseShapeWeight != 0.0f) { + const math::VEC3* pBase; + u8 stride; + + baseNrm.GetArray(reinterpret_cast(&pBase), + &stride); + + keyShape[numKeyShape].pVtx = pBase; + keyShape[numKeyShape].weight = pResult->baseShapeWeight; + numKeyShape++; + } + + for (int i = 0; i < static_cast(pResult->numKeyShape); i++) { + if (pResult->keyShape[i].weight == 0.0f) { + continue; + } + + ResVtxNrm key(pResult->keyShape[i].vtxSet.resVtxNrm); + const void* pData = key.GetData(); + + keyShape[numKeyShape].pVtx = + static_cast(pData); + keyShape[numKeyShape].weight = pResult->keyShape[i].weight; + numKeyShape++; + } + + u32 numVtx = baseNrm.GetNumVtxNrm(); + + // clang-format off + const math::VEC3* const pVtxNrmBufEnd = reinterpret_cast( + reinterpret_cast(pVtxNrmBuf) + numVtx * sizeof(math::VEC3)); + // clang-format on + + const KeyShape* const pKeyEnd = keyShape + numKeyShape; + + for (; pVtxNrmBuf < pVtxNrmBufEnd; pVtxNrmBuf++) { + register f32 xy, z_; + + KeyShape& rFirst = keyShape[0]; + register f32 firstWeight = rFirst.weight; + register const void* pVtx = rFirst.pVtx; + + // clang-format off + asm { + psq_l xy, VEC3.x(pVtx), 0, 0 + psq_l z_, VEC3.z(pVtx), 1, 0 + ps_mul xy, xy, firstWeight + ps_mul z_, z_, firstWeight + } + // clang-format on + + // clang-format off + rFirst.pVtx = reinterpret_cast( + reinterpret_cast(rFirst.pVtx) + sizeof(math::VEC3)); + // clang-format on + + for (KeyShape* pKey = &keyShape[1]; pKey < pKeyEnd; pKey++) { + register f32 keyWeight = pKey->weight; + register const void* pKeyVtx = pKey->pVtx; + register f32 key_xy, key_z_; + + // clang-format off + asm { + psq_l key_xy, VEC3.x(pKeyVtx), 0, 0 + psq_l key_z_, VEC3.z(pKeyVtx), 1, 0 + ps_madd xy, key_xy, keyWeight, xy + ps_madd z_, key_z_, keyWeight, z_ + } + // clang-format on + + // clang-format off + pKey->pVtx = reinterpret_cast( + reinterpret_cast(pKey->pVtx) + sizeof(math::VEC3)); + // clang-format on + } + + register void* pDst = pVtxNrmBuf; + + // clang-format off + asm { + psq_st xy, VEC3.x(pDst), 0, 0 + psq_st z_, VEC3.z(pDst), 1, 0 + } + // clang-format on + } + + DC::StoreRange(vtxNrm.GetData(), numVtx * sizeof(math::VEC3)); + } + + if ((pResult->flags & ShpAnmResult::FLAG_ANM_VTXCLR) && + ppVtxClrTable != NULL) { + + struct KeyShape { + const ut::Color* pVtx; // at 0x0 + f32 weight; // at 0x4 + }; + + ResVtxClr baseClr = pResult->baseShapeVtxSet.resVtxClr; + + KeyShape keyShape[ShpAnmResult::MAX_KEY_SHAPE + 1]; + int numKeyShape = 0; + + ResVtxClr vtxClr(ppVtxClrTable[baseClr.GetID()]); + ut::Color* pVtxClrBuf = static_cast(vtxClr.GetData()); + + if (pResult->baseShapeWeight != 0.0f) { + const ut::Color* pBase; + u8 stride; + + baseClr.GetArray(reinterpret_cast(&pBase), + &stride); + + keyShape[numKeyShape].pVtx = pBase; + keyShape[numKeyShape].weight = pResult->baseShapeWeight; + numKeyShape++; + } + + for (int i = 0; i < static_cast(pResult->numKeyShape); i++) { + if (pResult->keyShape[i].weight == 0.0f) { + continue; + } + + ResVtxClr key(pResult->keyShape[i].vtxSet.resVtxClr); + const void* pData = key.GetData(); + + keyShape[numKeyShape].pVtx = + static_cast(pData); + keyShape[numKeyShape].weight = pResult->keyShape[i].weight; + numKeyShape++; + } + + u32 numVtx = baseClr.GetNumVtxClr(); + + // clang-format off + const ut::Color* const pVtxClrBufEnd = reinterpret_cast( + reinterpret_cast(pVtxClrBuf) + numVtx * sizeof(ut::Color)); + // clang-format on + + const KeyShape* const pKeyEnd = keyShape + numKeyShape; + + for (; pVtxClrBuf < pVtxClrBufEnd; pVtxClrBuf++) { + register f32 rg, ba; + + KeyShape& rFirst = keyShape[0]; + register f32 firstWeight = rFirst.weight; + register const void* pVtx = rFirst.pVtx; + + // clang-format off + asm { + psq_l rg, Color.r(pVtx), 0, 2 + psq_l ba, Color.b(pVtx), 0, 2 + ps_mul rg, rg, firstWeight + ps_mul ba, ba, firstWeight + } + // clang-format on + + // clang-format off + rFirst.pVtx = reinterpret_cast( + reinterpret_cast(rFirst.pVtx) + sizeof(ut::Color)); + // clang-format on + + for (KeyShape* pKey = &keyShape[1]; pKey < pKeyEnd; pKey++) { + register f32 keyWeight = pKey->weight; + register const void* pKeyVtx = pKey->pVtx; + register f32 key_rg, key_ba; + + // clang-format off + asm { + psq_l key_rg, Color.r(pKeyVtx), 0, 2 + psq_l key_ba, Color.b(pKeyVtx), 0, 2 + ps_madd rg, key_rg, keyWeight, rg + ps_madd ba, key_ba, keyWeight, ba + } + // clang-format on + + // clang-format off + pKey->pVtx = reinterpret_cast( + reinterpret_cast(pKey->pVtx) + sizeof(ut::Color)); + // clang-format on + } + + register void* pDst = pVtxClrBuf; + + // clang-format off + asm { + psq_st rg, Color.r(pDst), 0, 2 + psq_st ba, Color.b(pDst), 0, 2 + } + // clang-format on + } + + DC::StoreRange(vtxClr.GetData(), numVtx * sizeof(ut::Color)); + } + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_calcworld.cpp b/src/nw4r/g3d/g3d_calcworld.cpp new file mode 100644 index 00000000..bc1fd749 --- /dev/null +++ b/src/nw4r/g3d/g3d_calcworld.cpp @@ -0,0 +1,284 @@ +#include + +namespace nw4r { +namespace g3d { + +void CalcWorld(math::MTX34* pModelMtxArray, u32* pModelMtxAttribArray, + const u8* pByteCode, const math::MTX34* pBaseMtx, ResMdl mdl, + AnmObjChr* pAnmChr, FuncObjCalcWorld* pFuncObj, u32 rootAttrib) { + +#define pCalcCmd reinterpret_cast(pByteCode) +#define pMtxDupCmd \ + reinterpret_cast(pByteCode) + + u8 c; + + ChrAnmResult result; + const ChrAnmResult* pResult = NULL; + + if (pByteCode == NULL) { + pByteCode = mdl.GetResByteCode("NodeTree"); + + if (pByteCode == NULL) { + return; + } + } + + bool xsi = mdl.GetResMdlInfo().GetScalingRule() == SCALINGRULE_SOFTIMAGE; + + bool ignoreTrans = detail::WorldMtxAttr::IsIgnoreTrans(rootAttrib); + + math::VEC3* pScaleArray = detail::workmem::GetScaleTemporary(); + pScaleArray[0].x = pScaleArray[0].y = pScaleArray[0].z = 1.0f; + + math::MTX34Copy(pModelMtxArray, pBaseMtx); + + u32* pMtxIDArray = detail::workmem::GetMtxIDTemporary(); + u32 numMtxID = 0; + + pModelMtxAttribArray[0] = rootAttrib; + + while ((c = *pByteCode) != ResByteCodeData::END) { + if (c == ResByteCodeData::CALC) { + u32 nodeID = (pCalcCmd->nodeIdHi << 8) + pCalcCmd->nodeIdLo; + + u32 parentMtxID = + (pCalcCmd->parentMtxIdHi << 8) + pCalcCmd->parentMtxIdLo; + + ResNode node = mdl.GetResNode(nodeID); + + u32 mtxID = node.GetMtxID(); + pMtxIDArray[numMtxID++] = mtxID; + + math::MTX34* pModelMtx = &pModelMtxArray[mtxID]; + math::VEC3* pScale = &pScaleArray[mtxID]; + + math::MTX34* pParentModelMtx = &pModelMtxArray[parentMtxID]; + math::VEC3* pParentScale = &pScaleArray[parentMtxID]; + + u32 parentAttr = pModelMtxAttribArray[parentMtxID]; + + if (pAnmChr != NULL) { + pResult = pAnmChr->GetResult(&result, node.GetID()); + } + + if (pAnmChr == NULL || pResult->flags == 0) { + node.CalcChrAnmResult(&result); + pResult = &result; + } + + if (nodeID != 0 && ignoreTrans) { + if (pResult != &result) { + result = *pResult; + pResult = &result; + } + + result.flags |= ChrAnmResult::FLAG_PATCH_TRANS; + node.PatchChrAnmResult(&result); + } + + if (pFuncObj != NULL) { + if (pResult != &result) { + result = *pResult; + pResult = &result; + } + + pFuncObj->CheckCallbackA(nodeID, &result, mdl); + } + + if (xsi) { + pModelMtxAttribArray[mtxID] = detail::dcc::CalcWorldMtx_Xsi( + pModelMtx, pScale, pParentModelMtx, pParentScale, + parentAttr, pResult); + } else if (pResult->flags & ChrAnmResult::FLAG_SSC_APPLY) { + pModelMtxAttribArray[mtxID] = + detail::dcc::CalcWorldMtx_Maya_SSC_Apply( + pModelMtx, pScale, pParentModelMtx, pParentScale, + parentAttr, pResult); + } else { + pModelMtxAttribArray[mtxID] = detail::dcc::CalcWorldMtx_Basic( + pModelMtx, pScale, pParentModelMtx, pParentScale, + parentAttr, pResult); + } + + pModelMtxAttribArray[mtxID] = detail::WorldMtxAttr::SetBillboard( + pModelMtxAttribArray[mtxID], node.GetBillboardMode()); + + if (pFuncObj != NULL) { + pFuncObj->CheckCallbackB(nodeID, pModelMtx, pScale, + &pModelMtxAttribArray[mtxID], mdl); + } + + pByteCode += sizeof(ResByteCodeData::CalcParams); + + } else /* Assume MTXDUP */ { + u32 toMtxID = (pMtxDupCmd->toMtxIdHi << 8) + pMtxDupCmd->toMtxIdLo; + + u32 fromMtxID = + (pMtxDupCmd->fromMtxIdHi << 8) + pMtxDupCmd->fromMtxIdLo; + + pMtxIDArray[numMtxID++] = toMtxID; + pModelMtxAttribArray[toMtxID] = pModelMtxAttribArray[fromMtxID]; + + math::MTX34Copy(&pModelMtxArray[toMtxID], + &pModelMtxArray[fromMtxID]); + + pScaleArray[toMtxID] = pScaleArray[fromMtxID]; + + pByteCode += sizeof(ResByteCodeData::MtxDupParams); + } + } + + for (u32 i = 0; i < numMtxID; i++) { + u32 mtxID = pMtxIDArray[i]; + + if (pScaleArray[mtxID].x == 1.0f && pScaleArray[mtxID].y == 1.0f && + pScaleArray[mtxID].z == 1.0f) { + continue; + } + + math::MTX34Scale(&pModelMtxArray[mtxID], &pModelMtxArray[mtxID], + &pScaleArray[mtxID]); + } + + if (pFuncObj != NULL) { + pFuncObj->CheckCallbackC(pModelMtxArray, mdl); + } + +#undef pCalcCmd +#undef pMtxDupCmd +} + +void CalcWorld(math::MTX34* pModelMtxArray, u32* pModelMtxAttribArray, + const u8* pByteCode, const math::MTX34* pBaseMtx, ResMdl mdl, + AnmObjChr* pAnmChr, FuncObjCalcWorld* pFuncObj) { + + CalcWorld(pModelMtxArray, pModelMtxAttribArray, pByteCode, pBaseMtx, mdl, + pAnmChr, pFuncObj, detail::WorldMtxAttr::GetRootMtxAttr()); +} + +void CalcSkinning(math::MTX34* pModelMtxArray, u32* pModelMtxAttribArray, + const ResMdl mdl, const u8* pByteCode) { + + // Allows struct offsets inside assembly + using nw4r::math::MTX34; + +#define pWeightCmd \ + reinterpret_cast(pByteCode) +#define pWeightEntry \ + reinterpret_cast(pByteCode) +#define pEvpMtxCmd \ + reinterpret_cast(pByteCode) + + u8 c; + + if (pByteCode == NULL) { + pByteCode = mdl.GetResByteCode("NodeMix"); + + if (pByteCode == NULL) { + return; + } + } + + math::MTX34* pSkinMtxArray = detail::workmem::GetSkinningMtxTemporary(); + + while ((c = *pByteCode) != ResByteCodeData::END) { + if (c == ResByteCodeData::WEIGHT) { + u32 targetMtxID = (pWeightCmd->tgtIdHi << 8) + pWeightCmd->tgtIdLo; + u32 numBlendMtx = pWeightCmd->numBlendMtx; + + pModelMtxAttribArray[targetMtxID] = + detail::WorldMtxAttr::GetRootMtxAttr(); + + pByteCode += sizeof(ResByteCodeData::WeightParams); + + register f32 M00, M02; + register f32 M10, M12; + register f32 M20, M22; + + M00 = 0.0f; + + // clang-format off + asm { + ps_merge00 M00, M00, M00 + ps_merge00 M02, M00, M00 + ps_merge00 M10, M00, M00 + ps_merge00 M12, M00, M00 + ps_merge00 M20, M00, M00 + ps_merge00 M22, M00, M00 + } + // clang-format on + + for (u32 i = 0; i < numBlendMtx; i++) { + u32 mtxID = + (pWeightEntry->mtxIdHi << 8) + pWeightEntry->mtxIdLo; + + u32 iraito = pWeightEntry->fWeight0 << 24 | + pWeightEntry->fWeight1 << 16 | + pWeightEntry->fWeight2 << 8 | + pWeightEntry->fWeight3; + + register f32 R = *reinterpret_cast(&iraito); + + register f32 T00, T02; + register f32 T10, T12; + register f32 T20, T22; + + register math::MTX34* pT = &pSkinMtxArray[mtxID]; + + // clang-format off + asm { + psq_l T00, MTX34._00(pT), 0, 0 + psq_l T02, MTX34._02(pT), 0, 0 + psq_l T10, MTX34._10(pT), 0, 0 + psq_l T12, MTX34._12(pT), 0, 0 + psq_l T20, MTX34._20(pT), 0, 0 + psq_l T22, MTX34._22(pT), 0, 0 + + ps_madds0 M00, T00, R, M00 + ps_madds0 M02, T02, R, M02 + ps_madds0 M10, T10, R, M10 + ps_madds0 M12, T12, R, M12 + ps_madds0 M20, T20, R, M20 + ps_madds0 M22, T22, R, M22 + } + // clang-format on + + pModelMtxAttribArray[targetMtxID] &= + pModelMtxAttribArray[mtxID]; + + pByteCode += sizeof(ResByteCodeData::WeightEntry); + } + + register math::MTX34* pTargetMtx = &pModelMtxArray[targetMtxID]; + + // clang-format off + asm { + psq_st M00, MTX34._00(pTargetMtx), 0, 0 + psq_st M02, MTX34._02(pTargetMtx), 0, 0 + psq_st M10, MTX34._10(pTargetMtx), 0, 0 + psq_st M12, MTX34._12(pTargetMtx), 0, 0 + psq_st M20, MTX34._20(pTargetMtx), 0, 0 + psq_st M22, MTX34._22(pTargetMtx), 0, 0 + } + // clang-format on + + } else /* Assume EVPMTX */ { + u32 mtxID = (pEvpMtxCmd->mtxIdHi << 8) + pEvpMtxCmd->mtxIdLo; + u32 nodeID = (pEvpMtxCmd->nodeIdHi << 8) + pEvpMtxCmd->nodeIdLo; + + math::MTX34Mult(&pSkinMtxArray[mtxID], &pModelMtxArray[mtxID], + static_cast( + &mdl.GetResNode(nodeID).ref().invModelMtx)); + + pByteCode += sizeof(ResByteCodeData::EvpMtxParams); + } + } + +#undef pWeightCmd +#undef pWeightEntry +#undef pEvpMtxCmd +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_camera.cpp b/src/nw4r/g3d/g3d_camera.cpp new file mode 100644 index 00000000..618d624e --- /dev/null +++ b/src/nw4r/g3d/g3d_camera.cpp @@ -0,0 +1,544 @@ +#include + +#include + +#include +#include + +namespace nw4r { +namespace g3d { + +Camera::Camera(CameraData *pData) : ResCommon(pData) {} + +void Camera::Init() { + const GXRenderModeObj *pObj = G3DState::GetRenderModeObj(); + + Init(pObj->fbWidth, pObj->efbHeight, pObj->fbWidth, pObj->xfbHeight, pObj->viWidth, pObj->viHeight); +} + +void Camera::Init(u16 efbWidth, u16 efbHeight, u16 xfbWidth, u16 xfbHeight, u16 viWidth, u16 viHeight) { + if (!IsValid()) { + return; + } + + CameraData &r = ref(); + + r.flags = CameraData::FLAG_CAM_LOOKAT | CameraData::FLAG_PROJ_PERSP; + + r.cameraPos.x = 0.0f; + r.cameraPos.y = 0.0f; + r.cameraPos.z = 15.0f; + r.cameraUp.x = 0.0f; + r.cameraUp.y = 1.0f; + r.cameraUp.z = 0.0f; + r.cameraTarget.x = 0.0f; + r.cameraTarget.y = 0.0f; + r.cameraTarget.z = 0.0f; + r.cameraRotate.x = 0.0f; + r.cameraRotate.y = 0.0f; + r.cameraRotate.z = 0.0f; + r.cameraTwist = 0.0f; + + r.projType = GX_PERSPECTIVE; + r.projFovy = 60.0f; + r.projAspect = 4.0f / 3.0f; + r.projNear = 0.1f; + r.projFar = 1000.f; + r.projTop = 0.0f; + r.projBottom = static_cast(viHeight); + r.projLeft = 0.0f; + r.projRight = static_cast(viWidth); + + r.lightScaleS = 0.5f; + r.lightScaleT = 0.5f; + r.lightTransS = 0.5f; + r.lightTransT = 0.5f; + + r.viewportOrigin.x = 0.0f; + r.viewportOrigin.y = 0.0f; + r.viewportSize.x = static_cast(xfbWidth); + r.viewportSize.y = static_cast(xfbHeight); + r.viewportNear = 0.0f; + r.viewportFar = 1.0f; + + r.scissorX = 0; + r.scissorY = 0; + r.scissorWidth = efbWidth; + r.scissorHeight = efbHeight; + r.scissorOffsetX = 0; + r.scissorOffsetY = 0; +} + +void Camera::SetPosition(f32 x, f32 y, f32 z) { + if (!IsValid()) { + return; + } + + CameraData &r = ref(); + + r.cameraPos.x = x; + r.cameraPos.y = y; + r.cameraPos.z = z; + r.flags &= ~CameraData::FLAG_CAM_MTX_READY; +} + +void Camera::SetPosition(const math::VEC3 &rPos) { + if (!IsValid()) { + return; + } + + CameraData &r = ref(); + + r.cameraPos = rPos; + r.flags &= ~CameraData::FLAG_CAM_MTX_READY; +} + +void Camera::SetPosture(const PostureInfo &rInfo) { + if (!IsValid()) { + return; + } + + CameraData &r = ref(); + + switch (rInfo.tp) { + case POSTURE_LOOKAT: { + if (r.flags & CameraData::FLAG_CAM_LOOKAT) { + if (!(rInfo.cameraUp != r.cameraUp) && !(rInfo.cameraTarget != r.cameraTarget)) { + return; + } + } + + r.flags &= ~(CameraData::FLAG_CAM_LOOKAT | CameraData::FLAG_CAM_ROTATE | CameraData::FLAG_CAM_AIM); + + r.flags |= CameraData::FLAG_CAM_LOOKAT; + + r.cameraUp = rInfo.cameraUp; + r.cameraTarget = rInfo.cameraTarget; + + r.flags &= ~CameraData::FLAG_CAM_MTX_READY; + break; + } + + case POSTURE_ROTATE: { + if (r.flags & CameraData::FLAG_CAM_ROTATE) { + if (!(rInfo.cameraRotate != r.cameraRotate)) { + return; + } + } + + r.flags &= ~(CameraData::FLAG_CAM_LOOKAT | CameraData::FLAG_CAM_ROTATE | CameraData::FLAG_CAM_AIM); + + r.flags |= CameraData::FLAG_CAM_ROTATE; + + r.cameraRotate = rInfo.cameraRotate; + + r.flags &= ~CameraData::FLAG_CAM_MTX_READY; + break; + } + + case POSTURE_AIM: { + if (r.flags & CameraData::FLAG_CAM_AIM) { + if (!(rInfo.cameraTarget != r.cameraTarget) && rInfo.cameraTwist == r.cameraTwist) { + return; + } + } + + r.flags &= ~(CameraData::FLAG_CAM_LOOKAT | CameraData::FLAG_CAM_ROTATE | CameraData::FLAG_CAM_AIM); + + r.flags |= CameraData::FLAG_CAM_AIM; + + r.cameraTarget = rInfo.cameraTarget; + r.cameraTwist = rInfo.cameraTwist; + + r.flags &= ~CameraData::FLAG_CAM_MTX_READY; + break; + } + + default: { + break; + } + } +} + +void Camera::SetCameraMtxDirectly(const math::MTX34 &rMtx) { + if (!IsValid()) { + return; + } + + CameraData &r = ref(); + + math::MTX34Copy(&r.cameraMtx, &rMtx); + r.flags |= CameraData::FLAG_CAM_MTX_READY; +} + +void Camera::SetPerspective(f32 fovy, f32 aspect, f32 near, f32 far) { + if (!IsValid()) { + return; + } + + CameraData &r = ref(); + + r.projType = GX_PERSPECTIVE; + + r.projFovy = fovy; + r.projAspect = aspect; + r.projNear = near; + r.projFar = far; + + r.flags &= + ~(CameraData::FLAG_PROJ_FRUSTUM | CameraData::FLAG_PROJ_PERSP | CameraData::FLAG_PROJ_ORTHO | + CameraData::FLAG_PROJ_MTX_READY); + + r.flags |= CameraData::FLAG_PROJ_PERSP; +} + +void Camera::SetOrtho(f32 top, f32 bottom, f32 left, f32 right, f32 near, f32 far) { + if (!IsValid()) { + return; + } + + CameraData &r = ref(); + + r.projType = GX_ORTHOGRAPHIC; + + r.projTop = top; + r.projBottom = bottom; + r.projLeft = left; + r.projRight = right; + r.projNear = near; + r.projFar = far; + + r.flags &= + ~(CameraData::FLAG_PROJ_FRUSTUM | CameraData::FLAG_PROJ_PERSP | CameraData::FLAG_PROJ_ORTHO | + CameraData::FLAG_PROJ_MTX_READY); + + r.flags |= CameraData::FLAG_PROJ_ORTHO; +} + +void Camera::SetProjectionMtxDirectly(const math::MTX44 *pMtx) { + if (pMtx != NULL && IsValid()) { + CameraData &r = ref(); + + math::MTX44Copy(&r.projMtx, pMtx); + r.flags |= CameraData::FLAG_PROJ_MTX_READY; + } +} + +void Camera::SetScissor(u32 x, u32 y, u32 width, u32 height) { + if (!IsValid()) { + return; + } + + CameraData &r = ref(); + + r.scissorX = x; + r.scissorY = y; + r.scissorWidth = width; + r.scissorHeight = height; +} + +void Camera::SetScissorBoxOffset(s32 ox, s32 oy) { + if (!IsValid()) { + return; + } + + CameraData &r = ref(); + + r.scissorOffsetX = ox; + r.scissorOffsetY = oy; +} + +void Camera::SetViewport(f32 x, f32 y, f32 width, f32 height) { + if (!IsValid()) { + return; + } + + CameraData &r = ref(); + + r.viewportOrigin.x = x; + r.viewportOrigin.y = y; + r.viewportSize.x = width; + r.viewportSize.y = height; + + SetScissor(static_cast(x), static_cast(y), static_cast(width), static_cast(height)); +} + +void Camera::SetViewportZRange(f32 near, f32 far) { + if (!IsValid()) { + return; + } + + CameraData &r = ref(); + + r.viewportNear = near; + r.viewportFar = far; +} + +void Camera::GetViewport(f32 *pX, f32 *pY, f32 *pWidth, f32 *pHeight, f32 *pNear, f32 *pFar) const { + if (!IsValid()) { + return; + } + + const CameraData &r = ref(); + + if (pX != NULL) { + *pX = r.viewportOrigin.x; + } + if (pY != NULL) { + *pY = r.viewportOrigin.y; + } + + if (pWidth != NULL) { + *pWidth = r.viewportSize.x; + } + if (pHeight != NULL) { + *pHeight = r.viewportSize.y; + } + + if (pNear != NULL) { + *pNear = r.viewportNear; + } + if (pFar != NULL) { + *pFar = r.viewportFar; + } +} + +void Camera::GetCameraMtx(math::MTX34 *pMtx) const { + if (pMtx != NULL && IsValid()) { + const CameraData &r = ref(); + + if (!(r.flags & CameraData::FLAG_CAM_MTX_READY)) { + UpdateCameraMtx(); + } + + math::MTX34Copy(pMtx, &r.cameraMtx); + } +} + +void Camera::GetProjectionMtx(math::MTX44 *pMtx) const { + if (pMtx != NULL && IsValid()) { + const CameraData &r = ref(); + + if (!(r.flags & CameraData::FLAG_PROJ_MTX_READY)) { + UpdateProjectionMtx(); + } + + math::MTX44Copy(pMtx, &r.projMtx); + } +} + +void Camera::GetProjectionTexMtx(math::MTX34 *pMtx) const { + if (pMtx != NULL && IsValid()) { + const CameraData &r = ref(); + + if (r.flags & CameraData::FLAG_PROJ_ORTHO) { + C_MTXLightOrtho( + *pMtx, r.projTop, r.projBottom, r.projLeft, r.projRight, r.lightScaleS, -r.lightScaleT, r.lightTransS, + r.lightTransT + ); + } else if (r.flags & CameraData::FLAG_PROJ_FRUSTUM) { + C_MTXLightFrustum( + *pMtx, r.projTop, r.projBottom, r.projLeft, r.projRight, r.projNear, r.lightScaleS, -r.lightScaleT, + r.lightTransS, r.lightTransT + ); + } else /* FLAG_PROJ_PERSP */ { + C_MTXLightPerspective( + *pMtx, r.projFovy, r.projAspect, r.lightScaleS, -r.lightScaleT, r.lightTransS, r.lightTransT + ); + } + } +} + +void Camera::GetEnvironmentTexMtx(math::MTX34 *pMtx) const { + if (pMtx != NULL && IsValid()) { + const CameraData &r = ref(); + + math::MTX34Identity(pMtx); + pMtx->_00 = r.lightScaleS; + pMtx->_03 = r.lightTransS; + pMtx->_11 = -r.lightScaleT; + pMtx->_13 = r.lightTransT; + pMtx->_22 = 0.0f; + pMtx->_23 = 1.0f; + } +} + +void Camera::GXSetViewport() const { + if (!IsValid()) { + return; + } + + const CameraData &r = ref(); + const GXRenderModeObj *pObj = G3DState::GetRenderModeObj(); + + if (pObj->field_rendering) { + ::GXSetViewportJitter( + r.viewportOrigin.x, r.viewportOrigin.y, r.viewportSize.x, r.viewportSize.y, r.viewportNear, r.viewportFar, + r.flags & CameraData::FLAG_VI_ODD_FIELD ? GX_FIELD_ODD : GX_FIELD_EVEN + ); + } else { + ::GXSetViewport( + r.viewportOrigin.x, r.viewportOrigin.y, r.viewportSize.x, r.viewportSize.y, r.viewportNear, r.viewportFar + ); + } +} + +void Camera::GXSetProjection() const { + if (!IsValid()) { + return; + } + + const CameraData &r = ref(); + + if (!(r.flags & CameraData::FLAG_PROJ_MTX_READY)) { + UpdateProjectionMtx(); + } + + ::GXSetProjection(r.projMtx, r.projType); +} + +void Camera::GXSetScissor() const { + if (!IsValid()) { + return; + } + + const CameraData &r = ref(); + ::GXSetScissor(r.scissorX, r.scissorY, r.scissorWidth, r.scissorHeight); +} + +void Camera::GXSetScissorBoxOffset() const { + if (!IsValid()) { + return; + } + + const CameraData &r = ref(); + ::GXSetScissorBoxOffset(r.scissorOffsetX, r.scissorOffsetY); +} + +void Camera::UpdateCameraMtx() const { + CameraData &r = const_cast(ref()); + + if (r.flags & CameraData::FLAG_CAM_LOOKAT) { + C_MTXLookAt(r.cameraMtx, r.cameraPos, r.cameraUp, r.cameraTarget); + } else if (r.flags & CameraData::FLAG_CAM_AIM) { + math::MTX34 &rMtx = r.cameraMtx; + math::VEC3 &rPos = r.cameraPos; + math::VEC3 &rTarget = r.cameraTarget; + + math::VEC3 back(rPos.x - rTarget.x, rPos.y - rTarget.y, rPos.z - rTarget.z); + + if (back.x == 0.0f && back.z == 0.0f) { + rMtx._00 = 1.0f; + rMtx._01 = 0.0f; + rMtx._02 = 0.0f; + rMtx._03 = -rPos.x; + + rMtx._10 = 0.0f; + rMtx._11 = 0.0f; + rMtx._20 = 0.0f; + rMtx._22 = 0.0f; + + if (back.y <= 0.0f) { + rMtx._12 = 1.0f; + rMtx._13 = -rPos.z; + rMtx._21 = -1.0f; + rMtx._23 = rPos.y; + } else { + rMtx._12 = -1.0f; + rMtx._13 = rPos.z; + rMtx._21 = 1.0f; + rMtx._23 = -rPos.y; + } + } else { + math::VEC3 _r(back.z, 0.0f, -back.x); + + math::VEC3 u; + math::VEC3Normalize(&back, &back); + math::VEC3Normalize(&_r, &_r); + math::VEC3Cross(&u, &back, &_r); + + f32 st, ct; + math::SinCosDeg(&st, &ct, r.cameraTwist); + + math::VEC3 right, up; + right.x = st * u.x + ct * _r.x; + right.y = st * u.y; + right.z = st * u.z + ct * _r.z; + + up.x = ct * u.x - st * _r.x; + up.y = ct * u.y; + up.z = ct * u.z - st * _r.z; + + rMtx._00 = right.x; + rMtx._01 = right.y; + rMtx._02 = right.z; + rMtx._03 = -math::VEC3Dot(&rPos, &right); + + rMtx._10 = up.x; + rMtx._11 = up.y; + rMtx._12 = up.z; + rMtx._13 = -math::VEC3Dot(&rPos, &up); + + rMtx._20 = back.x; + rMtx._21 = back.y; + rMtx._22 = back.z; + rMtx._23 = -math::VEC3Dot(&rPos, &back); + } + } else /* FLAG_CAM_ROTATE */ { + math::MTX34 &rMtx = r.cameraMtx; + math::VEC3 &rPos = r.cameraPos; + + f32 sx, sy, sz, cx, cy, cz; + math::SinCosDeg(&sx, &cx, r.cameraRotate.x); + math::SinCosDeg(&sy, &cy, r.cameraRotate.y); + math::SinCosDeg(&sz, &cz, r.cameraRotate.z); + + math::VEC3 right, up, back; + + right.x = sx * sy * sz + cy * cz; + right.y = cx * sz; + right.z = sx * cy * sz - sy * cz; + + up.x = sx * sy * cz - cy * sz; + up.y = cx * cz; + up.z = sx * cy * cz + sy * sz; + + back.x = cx * sy; + back.y = -sx; + back.z = cx * cy; + + rMtx._00 = right.x; + rMtx._01 = right.y; + rMtx._02 = right.z; + rMtx._03 = -math::VEC3Dot(&rPos, &right); + + rMtx._10 = up.x; + rMtx._11 = up.y; + rMtx._12 = up.z; + rMtx._13 = -math::VEC3Dot(&rPos, &up); + + rMtx._20 = back.x; + rMtx._21 = back.y; + rMtx._22 = back.z; + rMtx._23 = -math::VEC3Dot(&rPos, &back); + } + + r.flags |= CameraData::FLAG_CAM_MTX_READY; +} + +void Camera::UpdateProjectionMtx() const { + CameraData &r = const_cast(ref()); + + if (r.flags & CameraData::FLAG_PROJ_ORTHO) { + C_MTXOrtho(r.projMtx, r.projTop, r.projBottom, r.projLeft, r.projRight, r.projNear, r.projFar); + } else if (r.flags & CameraData::FLAG_PROJ_FRUSTUM) { + C_MTXFrustum(r.projMtx, r.projTop, r.projBottom, r.projLeft, r.projRight, r.projNear, r.projFar); + } else /* FLAG_PROJ_PERSP */ { + C_MTXPerspective(r.projMtx, r.projFovy, r.projAspect, r.projNear, r.projFar); + } + + r.flags |= CameraData::FLAG_PROJ_MTX_READY; +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_dcc.cpp b/src/nw4r/g3d/g3d_dcc.cpp new file mode 100644 index 00000000..4cbf928d --- /dev/null +++ b/src/nw4r/g3d/g3d_dcc.cpp @@ -0,0 +1,26 @@ +#include + +#include + +namespace nw4r { +namespace g3d { + +void CalcTexMtx(math::MTX34* pMtx, bool set, const TexSrt& rSrt, + TexSrt::Flag flag, TexSrtTypedef::TexMatrixMode mode) { + bool ident = true; + + if (mode == TexSrtTypedef::TEXMATRIXMODE_MAYA) { + ident = !detail::dcc::CalcTexMtx_Maya(pMtx, set, rSrt, flag); + } else if (mode == TexSrtTypedef::TEXMATRIXMODE_XSI) { + ident = !detail::dcc::CalcTexMtx_Xsi(pMtx, set, rSrt, flag); + } else /* TEXMATRIXMODE_3DSMAX */ { + ident = !detail::dcc::CalcTexMtx_3dsmax(pMtx, set, rSrt, flag); + } + + if (ident && set) { + math::MTX34Identity(pMtx); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_draw.cpp b/src/nw4r/g3d/g3d_draw.cpp new file mode 100644 index 00000000..9c5e8841 --- /dev/null +++ b/src/nw4r/g3d/g3d_draw.cpp @@ -0,0 +1,531 @@ +#include + +#include + +#include + +#include + +namespace nw4r { +namespace g3d { +namespace detail { + +G3DState::IndMtxOp *GetIndMtxOp(ResMat mat, ResNode node, ResShp shp) { + if (!mat.IsValid() || !shp.IsValid()) { + return NULL; + } + + ResMatMisc misc = mat.GetResMatMisc(); + + ResMatMiscData::IndirectMethod method[GX_ITM_2 - GX_ITM_0 + 1]; + s8 lightRef[GX_ITM_2 - GX_ITM_0 + 1]; + + misc.GetIndirectTexMtxCalcMethod(GX_ITM_0, &method[GX_ITM_0 - 1], &lightRef[GX_ITM_0 - 1]); + + misc.GetIndirectTexMtxCalcMethod(GX_ITM_1, &method[GX_ITM_1 - 1], &lightRef[GX_ITM_1 - 1]); + + misc.GetIndirectTexMtxCalcMethod(GX_ITM_2, &method[GX_ITM_2 - 1], &lightRef[GX_ITM_2 - 1]); + + if (method[GX_ITM_0 - 1] == ResMatMiscData::WARP && method[GX_ITM_1 - 1] == ResMatMiscData::WARP && + method[GX_ITM_2 - 1] == ResMatMiscData::WARP) { + return NULL; + } + + bool nrmMtxInit = false; + math::MTX34 nrmMtx; + + u32 i; + + G3DState::IndMtxOp &rOp = *G3DState::GetIndMtxOp(); + rOp.Reset(); + + for (i = 0; i < GX_ITM_2 - GX_ITM_0 + 1; i++) { + GXIndTexMtxID id = static_cast(i + 1); + + if (method[i] == ResMatMiscData::WARP) { + continue; + } + + if (!nrmMtxInit) { + nrmMtxInit = true; + + if (shp.ptr()->curMtxIdx >= 0) { + if (shp.ptr()->curMtxIdx == node.GetMtxID()) { + const math::MTX33 *pViewNrm = G3DState::GetViewNrmMtxPtr(shp.ptr()->curMtxIdx); + + nrmMtx._00 = pViewNrm->_00; + nrmMtx._01 = pViewNrm->_01; + nrmMtx._02 = pViewNrm->_02; + + nrmMtx._10 = pViewNrm->_10; + nrmMtx._11 = pViewNrm->_11; + nrmMtx._12 = pViewNrm->_12; + + nrmMtx._20 = pViewNrm->_20; + nrmMtx._21 = pViewNrm->_21; + nrmMtx._22 = pViewNrm->_22; + } else { + ResMdl mdl = mat.GetParent(); + + int shpNodeID = mdl.GetResMdlInfo().GetNodeIDFromMtxID(shp.ptr()->curMtxIdx); + + ResNode shpNode = mdl.GetResNode(shpNodeID); + + math::MTX34Mult( + &nrmMtx, static_cast(&shpNode.ref().invModelMtx), + static_cast(&node.ref().modelMtx) + ); + + const math::MTX33 *pViewNrm = G3DState::GetViewNrmMtxPtr(shp.ptr()->curMtxIdx); + + // clang-format off + math::MTX34 viewNrm34( + pViewNrm->_00, pViewNrm->_01, pViewNrm->_02, 0.0f, + pViewNrm->_10, pViewNrm->_11, pViewNrm->_12, 0.0f, + pViewNrm->_20, pViewNrm->_21, pViewNrm->_22, 0.0f); + // clang-format on + + math::MTX34Mult(&nrmMtx, &viewNrm34, &nrmMtx); + } + + nrmMtx._03 = nrmMtx._13 = nrmMtx._23 = 0.0f; + + math::VEC3 col0(nrmMtx._00, nrmMtx._10, nrmMtx._20); + math::VEC3Normalize(&col0, &col0); + nrmMtx._00 = col0.x; + nrmMtx._10 = col0.y; + nrmMtx._20 = col0.z; + + math::VEC3 col1(nrmMtx._01, nrmMtx._11, nrmMtx._21); + math::VEC3Normalize(&col1, &col1); + nrmMtx._01 = col1.x; + nrmMtx._11 = col1.y; + nrmMtx._21 = col1.z; + + math::VEC3 col2(nrmMtx._02, nrmMtx._12, nrmMtx._22); + math::VEC3Normalize(&col2, &col2); + nrmMtx._02 = col2.x; + nrmMtx._12 = col2.y; + nrmMtx._22 = col2.z; + + } else { + math::MTX34Copy(&nrmMtx, G3DState::GetCameraMtxPtr()); + } + } + + const LightObj *pLight = G3DState::GetLightObj(lightRef[i]); + + if (pLight != NULL && pLight->IsEnable()) { + math::VEC3 lightVec; + + if (pLight->IsSpotLight()) { + pLight->GetLightDir(&lightVec); + + if (lightVec.x == 0.0f && lightVec.y == 0.0f && lightVec.z == 0.0f) { + pLight->GetLightPos(&lightVec); + lightVec = -lightVec; + math::VEC3Normalize(&lightVec, &lightVec); + } + } else if (pLight->IsDiffuseLight()) { + pLight->GetLightPos(&lightVec); + lightVec = -lightVec; + math::VEC3Normalize(&lightVec, &lightVec); + } else { + math::VEC3 H; + pLight->GetLightDir(&H); + + lightVec.x = -2.0f * H.z * H.x; + lightVec.y = -2.0f * H.z * H.y; + lightVec.z = -2.0f * H.z * H.z + 1.0f; + math::VEC3Normalize(&lightVec, &lightVec); + } + + rOp.SetNrmMapMtx(id, &lightVec, &nrmMtx, method[i]); + } else { + rOp.SetNrmMapMtx(id, NULL, &nrmMtx, method[i]); + } + } + + return &rOp; +} + +} // namespace detail + +namespace { + +void SetupDraw1Mat1ShpSwap(Draw1Mat1ShpSwap *pSwap, DrawResMdlReplacement *pReplacement, u32 id) { + if (pReplacement->texObjDataArray != NULL) { + pSwap->texObj = ResTexObj(&pReplacement->texObjDataArray[id]); + } else { + pSwap->texObj = ResTexObj(NULL); + } + + if (pReplacement->tlutObjDataArray != NULL) { + pSwap->tlutObj = ResTlutObj(&pReplacement->tlutObjDataArray[id]); + } else { + pSwap->tlutObj = ResTlutObj(NULL); + } + + if (pReplacement->texSrtDataArray != NULL) { + pSwap->texSrt = ResTexSrt(&pReplacement->texSrtDataArray[id]); + } else { + pSwap->texSrt = ResTexSrt(NULL); + } + + if (pReplacement->chanDataArray != NULL) { + pSwap->chan = ResMatChan(&pReplacement->chanDataArray[id]); + } else { + pSwap->chan = ResMatChan(NULL); + } + + if (pReplacement->genModeDataArray != NULL) { + pSwap->genMode = ResGenMode(&pReplacement->genModeDataArray[id]); + } else { + pSwap->genMode = ResGenMode(NULL); + } + + if (pReplacement->matMiscDataArray != NULL) { + pSwap->misc = ResMatMisc(&pReplacement->matMiscDataArray[id]); + } else { + pSwap->misc = ResMatMisc(NULL); + } + + if (pReplacement->pixDLArray != NULL) { + pSwap->pix = ResMatPix(&pReplacement->pixDLArray[id]); + } else { + pSwap->pix = ResMatPix(NULL); + } + + if (pReplacement->tevColorDLArray != NULL) { + pSwap->tevColor = ResMatTevColor(&pReplacement->tevColorDLArray[id]); + } else { + pSwap->tevColor = ResMatTevColor(NULL); + } + + if (pReplacement->indMtxAndScaleDLArray != NULL) { + pSwap->indMtxAndScale = ResMatIndMtxAndScale(&pReplacement->indMtxAndScaleDLArray[id]); + } else { + pSwap->indMtxAndScale = ResMatIndMtxAndScale(NULL); + } + + if (pReplacement->texCoordGenDLArray != NULL) { + pSwap->texCoordGen = ResMatTexCoordGen(&pReplacement->texCoordGenDLArray[id]); + } else { + pSwap->texCoordGen = ResMatTexCoordGen(NULL); + } + + if (pReplacement->tevDataArray != NULL) { + pSwap->tev = ResTev(&pReplacement->tevDataArray[id]); + } else { + pSwap->tev = ResTev(NULL); + } + + pSwap->vtxPosTable = pReplacement->vtxPosTable; + pSwap->vtxNrmTable = pReplacement->vtxNrmTable; + pSwap->vtxClrTable = pReplacement->vtxClrTable; +} + +inline bool FrontToBack(const detail::workmem::MdlZ &rLhs, const detail::workmem::MdlZ &rRhs) { + if (rLhs.priority < rRhs.priority) { + return true; + } + + if (rLhs.priority > rRhs.priority) { + return false; + } + + if (rLhs.Z > rRhs.Z) { + return true; + } + + return false; +} + +inline bool BackToFront(const detail::workmem::MdlZ &rLhs, const detail::workmem::MdlZ &rRhs) { + if (rLhs.priority < rRhs.priority) { + return true; + } + + if (rLhs.priority > rRhs.priority) { + return false; + } + + if (rLhs.Z < rRhs.Z) { + return true; + } + + if (rLhs.Z == rRhs.Z && rLhs.matID < rRhs.matID) { + return true; + } + + return false; +} + +void DrawResMdlLoop(const ResMdl mdl, const u8 *pByteCode, u32 drawMode) { +#define pDrawCmd reinterpret_cast(pByteCode) + + u8 c; + + ResMat mat; + ResMat prevMat; + + ResShp shp; + ResNode node; + + bool ignoreMat = (drawMode & RESMDL_DRAWMODE_IGNORE_MATERIAL); + u32 ctrl = DRAW1MAT1SHP_CTRL_NOPPCSYNC; + + if (drawMode & RESMDL_DRAWMODE_FORCE_LIGHTOFF) { + ctrl |= DRAW1MAT1SHP_CTRL_FORCE_LIGHTOFF; + } + + for (; (c = *pByteCode) != ResByteCodeData::END; pByteCode += sizeof(ResByteCodeData::DrawParams)) { + node = mdl.GetResNode(pDrawCmd->nodeIdHi << 8 | pDrawCmd->nodeIdLo); + if (!node.IsVisible()) { + continue; + } + + mat = mdl.GetResMat(pDrawCmd->matIdHi << 8 | pDrawCmd->matIdLo); + shp = mdl.GetResShp(pDrawCmd->shpIdHi << 8 | pDrawCmd->shpIdLo); + + Draw1Mat1ShpDirectly( + ignoreMat || mat == prevMat ? ResMat(NULL) : mat, shp, NULL, NULL, ctrl, NULL, + detail::GetIndMtxOp(mat, node, shp) + ); + + prevMat = mat; + } + +#undef pDrawCmd +} + +void DrawResMdlLoop(const ResMdl mdl, const u8 *pByteCode, DrawResMdlReplacement *pReplacement, u32 drawMode) { +#define pDrawCmd reinterpret_cast(pByteCode) + + u8 c; + + ResMat mat; + ResMat prevMat; + + ResShp shp; + ResNode node; + + Draw1Mat1ShpSwap swap; + + bool ignoreMat = (drawMode & RESMDL_DRAWMODE_IGNORE_MATERIAL); + u32 ctrl = DRAW1MAT1SHP_CTRL_NOPPCSYNC; + + if (drawMode & RESMDL_DRAWMODE_FORCE_LIGHTOFF) { + ctrl |= DRAW1MAT1SHP_CTRL_FORCE_LIGHTOFF; + } + + for (; (c = *pByteCode) != ResByteCodeData::END; pByteCode += sizeof(ResByteCodeData::DrawParams)) { + node = mdl.GetResNode(pDrawCmd->nodeIdHi << 8 | pDrawCmd->nodeIdLo); + + bool visible; + // @bug Replacement pointer not validated + if (pReplacement->visArray != NULL) { + visible = pReplacement->visArray[node.GetID()] != 0; + } else { + visible = node.IsVisible(); + } + + if (!visible) { + continue; + } + + mat = mdl.GetResMat(pDrawCmd->matIdHi << 8 | pDrawCmd->matIdLo); + shp = mdl.GetResShp(pDrawCmd->shpIdHi << 8 | pDrawCmd->shpIdLo); + + SetupDraw1Mat1ShpSwap(&swap, pReplacement, mat.GetID()); + + Draw1Mat1ShpDirectly( + ignoreMat || mat == prevMat ? ResMat(NULL) : mat, shp, NULL, NULL, ctrl, &swap, + detail::GetIndMtxOp(mat, node, shp) + ); + + prevMat = mat; + } + +#undef pDrawCmd +} + +void DrawResMdlLoop(const ResMdl mdl, const detail::workmem::MdlZ *pMdlZArray, u32 numMdlZ, u32 drawMode) { + u32 i; + + ResMat mat; + ResMat prevMat; + + ResShp shp; + ResNode node; + + bool ignoreMat = (drawMode & RESMDL_DRAWMODE_IGNORE_MATERIAL); + u32 ctrl = DRAW1MAT1SHP_CTRL_NOPPCSYNC; + + if (drawMode & RESMDL_DRAWMODE_FORCE_LIGHTOFF) { + ctrl |= DRAW1MAT1SHP_CTRL_FORCE_LIGHTOFF; + } + + for (i = 0; i < numMdlZ; i++) { + const detail::workmem::MdlZ &rMdlZ = pMdlZArray[i]; + + mat = mdl.GetResMat(rMdlZ.matID); + shp = mdl.GetResShp(rMdlZ.shpID); + node = mdl.GetResNode(rMdlZ.nodeID); + + Draw1Mat1ShpDirectly( + ignoreMat || mat == prevMat ? ResMat(NULL) : mat, shp, NULL, NULL, ctrl, NULL, + detail::GetIndMtxOp(mat, node, shp) + ); + + prevMat = mat; + } +} + +void DrawResMdlLoop( + const ResMdl mdl, const detail::workmem::MdlZ *pMdlZArray, u32 numMdlZ, DrawResMdlReplacement *pReplacement, + u32 drawMode +) { + u32 i; + + ResMat mat; + ResMat prevMat; + + ResShp shp; + ResNode node; + + Draw1Mat1ShpSwap swap; + + bool ignoreMat = (drawMode & RESMDL_DRAWMODE_IGNORE_MATERIAL); + u32 ctrl = DRAW1MAT1SHP_CTRL_NOPPCSYNC; + + if (drawMode & RESMDL_DRAWMODE_FORCE_LIGHTOFF) { + ctrl |= DRAW1MAT1SHP_CTRL_FORCE_LIGHTOFF; + } + + for (i = 0; i < numMdlZ; i++) { + const detail::workmem::MdlZ &rMdlZ = pMdlZArray[i]; + + mat = mdl.GetResMat(rMdlZ.matID); + shp = mdl.GetResShp(rMdlZ.shpID); + node = mdl.GetResNode(rMdlZ.nodeID); + + SetupDraw1Mat1ShpSwap(&swap, pReplacement, mat.GetID()); + + Draw1Mat1ShpDirectly( + ignoreMat || mat == prevMat ? ResMat(NULL) : mat, shp, NULL, NULL, ctrl, &swap, + detail::GetIndMtxOp(mat, node, shp) + ); + + prevMat = mat; + } +} + +detail::workmem::MdlZ *SetUpMdlZ( + u32 *pNumMdlZ, const ResMdl mdl, const math::MTX34 *pViewPosMtxArray, const u8 *pByteCode, + DrawResMdlReplacement *pReplacement +) { +#define pDrawCmd reinterpret_cast(pByteCode) + + u16 nodeID; + u8 c; + u32 mdlZNum = 0; + ResNode node; + u32 mtxID; + + u32 viewMtxNum = mdl.GetResMdlInfo().GetNumViewMtx(); + detail::workmem::MdlZ *pMdlZArray = detail::workmem::GetMdlZTemporary(); + + for (; (c = *pByteCode) != ResByteCodeData::END; pByteCode += sizeof(ResByteCodeData::DrawParams)) { + nodeID = pDrawCmd->nodeIdHi << 8 | pDrawCmd->nodeIdLo; + node = mdl.GetResNode(nodeID); + + bool visible; + if (pReplacement == NULL || pReplacement->visArray == NULL) { + visible = node.IsVisible(); + } else { + visible = pReplacement->visArray[node.GetID()] != 0; + } + + if (!visible) { + continue; + } + + detail::workmem::MdlZ &rMdlZ = pMdlZArray[mdlZNum]; + + rMdlZ.nodeID = nodeID; + rMdlZ.matID = pDrawCmd->matIdHi << 8 | pDrawCmd->matIdLo; + rMdlZ.shpID = pDrawCmd->shpIdHi << 8 | pDrawCmd->shpIdLo; + + // @bug Matrix ID not validated + mtxID = node.GetMtxID(); + rMdlZ.Z = pViewPosMtxArray[mtxID]._23; + + rMdlZ.priority = pDrawCmd->priority; + + mdlZNum++; + } + + *pNumMdlZ = mdlZNum; + return pMdlZArray; + +#undef pDrawCmd +} + +} // namespace + +void DrawResMdlDirectly( + const ResMdl mdl, const math::MTX34 *pViewPosMtxArray, const math::MTX33 *pViewNrmMtxArray, + const math::MTX34 *pViewEnvMtxArray, const u8 *pByteCodeOpa, const u8 *pByteCodeXlu, + DrawResMdlReplacement *pReplacement, u32 drawMode +) { + G3DState::SetViewPosNrmMtxArray(pViewPosMtxArray, pViewNrmMtxArray, pViewEnvMtxArray); + + if (!(drawMode & RESMDL_DRAWMODE_NOPPCSYNC)) { + ut::LC::QueueWait(0); + PPCSync(); + } + + if (pByteCodeOpa != NULL) { + if (drawMode & RESMDL_DRAWMODE_SORT_OPA_Z) { + u32 numMdlZ; + detail::workmem::MdlZ *pMdlZArray = SetUpMdlZ(&numMdlZ, mdl, pViewPosMtxArray, pByteCodeOpa, pReplacement); + + std::sort(pMdlZArray, pMdlZArray + numMdlZ, FrontToBack); + + if (pReplacement != NULL) { + DrawResMdlLoop(mdl, pMdlZArray, numMdlZ, pReplacement, drawMode); + } else { + DrawResMdlLoop(mdl, pMdlZArray, numMdlZ, drawMode); + } + } else if (pReplacement != NULL) { + DrawResMdlLoop(mdl, pByteCodeOpa, pReplacement, drawMode); + } else { + DrawResMdlLoop(mdl, pByteCodeOpa, drawMode); + } + } + + if (pByteCodeXlu != NULL) { + if (drawMode & RESMDL_DRAWMODE_SORT_XLU_Z) { + u32 numMdlZ; + detail::workmem::MdlZ *pMdlZArray = SetUpMdlZ(&numMdlZ, mdl, pViewPosMtxArray, pByteCodeXlu, pReplacement); + + std::sort(pMdlZArray, pMdlZArray + numMdlZ, BackToFront); + + if (pReplacement != NULL) { + DrawResMdlLoop(mdl, pMdlZArray, numMdlZ, pReplacement, drawMode); + } else { + DrawResMdlLoop(mdl, pMdlZArray, numMdlZ, drawMode); + } + } else if (pReplacement != NULL) { + DrawResMdlLoop(mdl, pByteCodeXlu, pReplacement, drawMode); + } else { + DrawResMdlLoop(mdl, pByteCodeXlu, drawMode); + } + } + + G3DState::SetViewPosNrmMtxArray(NULL, NULL, NULL); +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_draw1mat1shp.cpp b/src/nw4r/g3d/g3d_draw1mat1shp.cpp new file mode 100644 index 00000000..61c36bb2 --- /dev/null +++ b/src/nw4r/g3d/g3d_draw1mat1shp.cpp @@ -0,0 +1,175 @@ +#include + +#include + +#include +#include + +namespace nw4r { +namespace g3d { + +void Draw1Mat1ShpDirectly( + ResMat mat, ResShp shp, const math::MTX34 *pViewPos, const math::MTX34 *pViewNrm, u32 ctrl, Draw1Mat1ShpSwap *pSwap, + G3DState::IndMtxOp *pIndMtxOp +) { + if (!(ctrl & DRAW1MAT1SHP_CTRL_NOPPCSYNC)) { + ut::LC::QueueWait(0); + PPCSync(); + } + + if (mat.IsValid()) { + ResMatMisc misc; + + if (pSwap == NULL || !pSwap->misc.IsValid()) { + misc = mat.GetResMatMisc(); + } else { + misc = pSwap->misc; + } + + int fogID = misc.GetFogIdx(); + G3DState::LoadFog(fogID); + G3DState::LoadResMatMisc(misc); + + if (pSwap == NULL || !pSwap->tlutObj.IsValid()) { + G3DState::LoadResTlutObj(mat.GetResTlutObj()); + } else { + G3DState::LoadResTlutObj(pSwap->tlutObj); + } + + if (pSwap == NULL || !pSwap->texObj.IsValid()) { + G3DState::LoadResTexObj(mat.GetResTexObj()); + } else { + G3DState::LoadResTexObj(pSwap->texObj); + } + + if (pSwap == NULL || !pSwap->genMode.IsValid()) { + G3DState::LoadResGenMode(mat.GetResGenMode()); + } else { + G3DState::LoadResGenMode(pSwap->genMode); + } + + if (pSwap == NULL || !pSwap->tev.IsValid()) { + G3DState::LoadResTev(mat.GetResTev()); + } else { + G3DState::LoadResTev(pSwap->tev); + } + + if (pSwap == NULL || !pSwap->pix.IsValid()) { + G3DState::LoadResMatPix(mat.GetResMatPix()); + } else { + G3DState::LoadResMatPix(pSwap->pix); + } + + if (pSwap == NULL || !pSwap->tevColor.IsValid()) { + G3DState::LoadResMatTevColor(mat.GetResMatTevColor()); + } else { + G3DState::LoadResMatTevColor(pSwap->tevColor); + } + + if (pSwap == NULL || !pSwap->indMtxAndScale.IsValid()) { + if (pIndMtxOp != NULL) { + G3DState::LoadResMatIndMtxAndScale(mat.GetResMatIndMtxAndScale(), *pIndMtxOp); + } else { + G3DState::LoadResMatIndMtxAndScale(mat.GetResMatIndMtxAndScale()); + } + } else { + if (pIndMtxOp != NULL) { + G3DState::LoadResMatIndMtxAndScale(pSwap->indMtxAndScale, *pIndMtxOp); + } else { + G3DState::LoadResMatIndMtxAndScale(pSwap->indMtxAndScale); + } + } + + u32 diffColorMask, diffAlphaMask; + u32 specColorMask, specAlphaMask; + + GXColor ambColor; + AmbLightObj ambLight; + + G3DState::LoadLightSet( + misc.GetLightSetIdx(), &diffColorMask, &diffAlphaMask, &specColorMask, &specAlphaMask, &ambLight + ); + + ambColor.r = ambLight.r; + ambColor.g = ambLight.g; + ambColor.b = ambLight.b; + ambColor.a = ambLight.a; + + if (pSwap == NULL || !pSwap->chan.IsValid()) { + G3DState::LoadResMatChan( + mat.GetResMatChan(), diffColorMask, diffAlphaMask, specColorMask, specAlphaMask, ambColor, + (ctrl & DRAW1MAT1SHP_CTRL_FORCE_LIGHTOFF) ? true : false + ); + } else { + G3DState::LoadResMatChan( + pSwap->chan, diffColorMask, diffAlphaMask, specColorMask, specAlphaMask, ambColor, + (ctrl & DRAW1MAT1SHP_CTRL_FORCE_LIGHTOFF) ? true : false + ); + } + + if (pSwap == NULL || !pSwap->texCoordGen.IsValid()) { + G3DState::LoadResMatTexCoordGen(mat.GetResMatTexCoordGen()); + } else { + G3DState::LoadResMatTexCoordGen(pSwap->texCoordGen); + } + + if (pSwap == NULL || !pSwap->texSrt.IsValid()) { + G3DState::LoadResTexSrt(mat.GetResTexSrt()); + } else { + G3DState::LoadResTexSrt(pSwap->texSrt); + } + + } else if (pIndMtxOp != NULL) { + if (pSwap == NULL || !pSwap->indMtxAndScale.IsValid()) { + G3DState::IndTexMtxInfo info; + (*pIndMtxOp)(&info); + info.FifoSend(); + } else { + G3DState::LoadResMatIndMtxAndScale(pSwap->indMtxAndScale, *pIndMtxOp); + } + } + + if (shp.IsValid() && shp.IsVisible()) { + if (!(ctrl & DRAW1MAT1SHP_CTRL_NOSWAPSHP)) { + G3DState::LoadResShpPrePrimitive(shp); + + if (pSwap != NULL) { + if (pSwap->vtxPosTable != NULL) { + ResVtxPos(pSwap->vtxPosTable[shp.ref().idVtxPosition]).SetArray(); + } + + if (pSwap->vtxNrmTable != NULL) { + int nrmID = shp.ref().idVtxNormal; + + if (nrmID >= 0) { + ResVtxNrm(pSwap->vtxNrmTable[nrmID]).SetArray(); + } + } + + if (pSwap->vtxClrTable != NULL) { + int clrID = shp.ref().idVtxColor[0]; + + if (clrID >= 0) { + ResVtxClr(pSwap->vtxClrTable[clrID]).SetArray(GX_VA_CLR0); + } + + clrID = shp.ref().idVtxColor[1]; + + if (clrID >= 0) { + ResVtxClr(pSwap->vtxClrTable[clrID]).SetArray(GX_VA_CLR1); + } + } + } + } + + if (ctrl & DRAW1MAT1SHP_CTRL_CULL_FRONT) { + fifo::GDSetCullMode(GX_CULL_FRONT); + G3DState::Invalidate(G3DState::INVALIDATE_SHP); + } + + G3DState::LoadResShpPrimitive(shp, pViewPos, pViewNrm); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_fog.cpp b/src/nw4r/g3d/g3d_fog.cpp new file mode 100644 index 00000000..ac1ed594 --- /dev/null +++ b/src/nw4r/g3d/g3d_fog.cpp @@ -0,0 +1,94 @@ +#include + +#include + +namespace nw4r { +namespace g3d { + +Fog::Fog(FogData *pData) : ResCommon(pData) {} + +void Fog::Init() { + if (!IsValid()) { + return; + } + + FogData &r = ref(); + + r.type = GX_FOG_NONE; + + r.startz = 0.0f; + r.endz = 0.0f; + r.nearz = 0.0f; + r.farz = 0.0f; + + r.color.r = r.color.g = r.color.b = r.color.a = 0; + + r.adjEnable = FALSE; + r.PADDING_0x19 = 0; + + r.adjCenter = 0; + for (int i = 0; i < GX_FOG_ADJ_TABLE_SZ; i++) { + r.adjTable.r[i] = 0; + } +} + +Fog Fog::CopyTo(register void *pDst) const { + if (pDst != NULL && IsValid()) { + register const FogData *pSrc = ptr(); + register f64 work0, work1, work2, work3, work4, work5; + + // clang-format off + asm { + lfd work0, 0(pSrc) + stfd work0, 0(pDst) + + lfd work1, 8(pSrc) + stfd work1, 8(pDst) + + lfd work2, 16(pSrc) + stfd work2, 16(pDst) + + lfd work3, 24(pSrc) + stfd work3, 24(pDst) + + lfd work4, 32(pSrc) + stfd work4, 32(pDst) + + lfd work5, 40(pSrc) + stfd work5, 40(pDst) + } + // clang-format on + + return Fog(static_cast(pDst)); + } + + return Fog(NULL); +} + +void Fog::SetFogRangeAdjParam(u16 width, u16 center, const math::MTX44 &rProjMtx) { + if (!IsValid()) { + return; + } + + FogData &r = ref(); + + r.adjCenter = center; + GXInitFogAdjTable(&r.adjTable, width, rProjMtx); +} + +void Fog::SetGP() const { + if (!IsValid()) { + return; + } + + const FogData &r = ref(); + + if (r.type != GX_FOG_NONE) { + GXSetFogRangeAdj(r.adjEnable, r.adjCenter, &r.adjTable); + } + + GXSetFog(r.type, r.color, r.startz, r.endz, r.nearz, r.farz); +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_init.cpp b/src/nw4r/g3d/g3d_init.cpp new file mode 100644 index 00000000..5fba25ad --- /dev/null +++ b/src/nw4r/g3d/g3d_init.cpp @@ -0,0 +1,65 @@ +#include + +#include + +#include +#include +#include + +namespace { + +NW4R_LIB_VERSION(G3D, "Jun 8 2007", "11:16:25", "0x4199_60831"); + +} // namespace + +namespace nw4r { +namespace g3d { + +void G3dInit(bool enableLockedCache) { + OSRegisterVersion(NW4R_G3D_Version_); + + if (enableLockedCache) { + ut::LC::Enable(); + } else { + ut::LC::Disable(); + } + + InitFastCast(); + + GXRenderModeObj *pMode; + switch (VIGetTvFormat()) { + case VI_TV_FMT_NTSC: { + pMode = &GXNtsc480IntDf; + break; + } + + case VI_TV_FMT_PAL: { + pMode = &GXPal528IntDf; + break; + } + + case VI_TV_FMT_EURGB60: { + pMode = &GXEurgb60Hz480IntDf; + break; + } + + case VI_TV_FMT_MPAL: { + pMode = &GXMpal480IntDf; + break; + } + + default: { + pMode = &GXNtsc480IntDf; + break; + } + } + + G3DState::SetRenderModeObj(*pMode); +} + +void G3dReset() { + G3DState::Invalidate(); +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_light.cpp b/src/nw4r/g3d/g3d_light.cpp new file mode 100644 index 00000000..6af986b4 --- /dev/null +++ b/src/nw4r/g3d/g3d_light.cpp @@ -0,0 +1,262 @@ +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * LightObj + * + ******************************************************************************/ +LightObj& LightObj::operator=(const LightObj& rOther) { + if (this != &rOther) { + mFlag = rOther.mFlag; + detail::Copy32ByteBlocks(&mObj, &rOther.mObj, sizeof(GXLightObj)); + } + + return *this; +} + +void LightObj::Clear() { + mFlag = 0; + detail::ZeroMemory32ByteBlocks(&mObj, sizeof(GXLightObj)); +} + +void LightObj::InitLightColor(GXColor color) { + GXInitLightColor(&mObj, color); +} + +void LightObj::InitLightPos(f32 x, f32 y, f32 z) { + GXInitLightPos(&mObj, x, y, z); + mFlag &= ~FLAG_SPECULAR; +} + +void LightObj::InitLightDir(f32 nx, f32 ny, f32 nz) { + GXInitLightDir(&mObj, nx, ny, nz); + mFlag &= ~FLAG_SPECULAR; + mFlag |= FLAG_SPOT; +} + +void LightObj::InitSpecularDir(f32 nx, f32 ny, f32 nz) { + GXInitLightDir(&mObj, nx, ny, nz); + mFlag &= ~FLAG_SPOT; + mFlag |= FLAG_SPECULAR; + mFlag |= FLAG_SPECULAR_DIR; +} + +void LightObj::InitLightSpot(f32 cutoff, GXSpotFn spotFn) { + GXInitLightSpot(&mObj, cutoff, spotFn); + mFlag &= ~FLAG_SPECULAR; + mFlag |= FLAG_SPOT; +} + +void LightObj::InitLightAttnA(f32 aa, f32 ab, f32 ac) { + GXInitLightAttnA(&mObj, aa, ab, ac); + mFlag &= ~FLAG_SPECULAR; + mFlag |= FLAG_SPOT; +} + +void LightObj::InitLightDistAttn(f32 distance, f32 brightness, + GXDistAttnFn distAttnFn) { + GXInitLightDistAttn(&mObj, distance, brightness, distAttnFn); + mFlag &= ~FLAG_SPECULAR; + mFlag |= FLAG_SPOT; +} + +void LightObj::InitLightAttnK(f32 ka, f32 kb, f32 kc) { + GXInitLightAttnK(&mObj, ka, kb, kc); + mFlag &= ~FLAG_SPECULAR; + mFlag |= FLAG_SPOT; +} + +void LightObj::InitLightShininess(f32 shininess) { + GXInitLightAttn(&mObj, 0.0f, 0.0f, 1.0f, shininess / 2.0f, 0.0f, + 1.0f - shininess / 2.0f); + mFlag &= ~FLAG_SPOT; + mFlag |= FLAG_SPECULAR; +} + +void LightObj::GetLightPos(math::VEC3* pPos) const { + if (!pPos) { + return; + } + + GXGetLightPos(&mObj, &pPos->x, &pPos->y, &pPos->z); +} + +void LightObj::GetLightDir(math::VEC3* pDir) const { + if (!pDir) { + return; + } + + GXGetLightDir(&mObj, &pDir->x, &pDir->y, &pDir->z); +} + +void LightObj::ApplyViewMtx(const math::MTX34& rCamera) { + math::VEC3 dir; + GetLightDir(&dir); + math::VEC3TransformNormal(&dir, &rCamera, &dir); + + if (IsSpecularDir()) { + GXInitSpecularDir(&mObj, dir.x, dir.y, dir.z); + } else { + math::VEC3 pos; + GetLightPos(&pos); + math::VEC3Transform(&pos, &rCamera, &pos); + + GXInitLightPos(&mObj, pos.x, pos.y, pos.z); + GXInitLightDir(&mObj, dir.x, dir.y, dir.z); + } +} + +/****************************************************************************** + * + * LightSetting + * + ******************************************************************************/ +LightSetting::LightSetting(LightObj* pLightObjArray, + AmbLightObj* pAmbLightObjArray, u32 numLight, + LightSetData* pLightSetDataArray, u32 numLightSet) + : mNumLight(numLight), + mNumLightSet(numLightSet), + mpLightObjArray(pLightObjArray), + mpAmbLightObjArray(pAmbLightObjArray), + mpLightSetDataArray(pLightSetDataArray) { + + for (u32 i = 0; i < mNumLightSet; i++) { + LightSetData& rData = mpLightSetDataArray[i]; + rData.idxAmbLight = -1; + + for (u32 j = 0; j < G3DState::NUM_LIGHT_IN_LIGHT_SET; j++) { + rData.idxLight[j] = -1; + } + } + + mpLightSetDataArray[0].idxLight[0] = 0; + mpLightSetDataArray[0].idxLight[1] = 2; + mpLightSetDataArray[0].idxAmbLight = -1; + + GXColor white = {255, 255, 255, 255}; + AmbLightObj ambWhite = {255, 255, 255, 255}; + + LightObj lobj0, lobj1, lobj2, lobj3; + + lobj0.Clear(); + lobj1.Clear(); + lobj2.Clear(); + lobj3.Clear(); + + lobj0.InitLightColor(white); + lobj0.InitLightPos(4000000.0f, 4000000.0f, 4000000.0f); + lobj0.InitLightDir(0.0f, -1.0f, 0.0f); + lobj0.InitLightSpot(90.0f, GX_SP_OFF); + lobj0.InitLightDistAttn(10.0f, 0.5f, GX_DA_OFF); + lobj0.Enable(); + + lobj1.InitLightColor(white); + lobj1.InitLightPos(4000000.0f, 4000000.0f, 4000000.0f); + lobj1.Enable(); + + lobj2.InitLightColor(white); + lobj2.InitLightPos(4000000.0f, 4000000.0f, 4000000.0f); + lobj2.InitSpecularDir(0.0f, -1.0f, 0.0f); + lobj2.InitLightShininess(16.0f); + lobj2.Enable(); + + lobj3.Disable(); + + if (mNumLight > 0) { + mpLightObjArray[0] = lobj0; + mpAmbLightObjArray[0] = ambWhite; + } + if (mNumLight > 1) { + mpLightObjArray[1] = lobj1; + mpAmbLightObjArray[1] = ambWhite; + } + if (mNumLight > 2) { + mpLightObjArray[2] = lobj2; + mpAmbLightObjArray[2] = ambWhite; + } + + for (u32 i = 3; i < mNumLight; i++) { + mpLightObjArray[i] = lobj3; + mpAmbLightObjArray[i] = ambWhite; + } +} + +bool LightSetting::Import(const LightSetting& rSetting) { + if (mNumLight < rSetting.mNumLight || + mNumLightSet < rSetting.mNumLightSet) { + return false; + } + + for (u32 i = 0; i < rSetting.mNumLight; i++) { + if (rSetting.mpLightObjArray[i].IsEnable()) { + mpLightObjArray[i] = rSetting.mpLightObjArray[i]; + } else { + mpLightObjArray[i].Disable(); + } + + mpAmbLightObjArray[i] = rSetting.mpAmbLightObjArray[i]; + } + + for (u32 i = 0; i < rSetting.mNumLightSet; i++) { + mpLightSetDataArray[i] = rSetting.mpLightSetDataArray[i]; + } + + return true; +} + +void LightSetting::ApplyViewMtx(const math::MTX34& rCamera, u32 numLight) { + numLight = std::max(numLight, mNumLight); + + for (u32 i = 0; i < numLight; i++) { + if (mpLightObjArray[i].IsEnable()) { + mpLightObjArray[i].ApplyViewMtx(rCamera); + } + } +} + +/****************************************************************************** + * + * LightSet + * + ******************************************************************************/ +bool LightSet::SelectLightObj(u32 lightIdx, int lightObjIdx) { + if (IsValid() && lightIdx < G3DState::NUM_LIGHT_IN_LIGHT_SET) { + if (lightObjIdx < 0) { + mpLightSetData->idxLight[lightIdx] = -1; + return true; + } + + if (lightObjIdx < static_cast(mpSetting->GetNumLightObj())) { + mpLightSetData->idxLight[lightIdx] = lightObjIdx; + return true; + } + } + + return false; +} + +bool LightSet::SelectAmbLightObj(int lightObjIdx) { + if (IsValid()) { + if (lightObjIdx < 0) { + mpLightSetData->idxAmbLight = -1; + return true; + } + + if (lightObjIdx < static_cast(mpSetting->GetNumLightObj())) { + mpLightSetData->idxAmbLight = lightObjIdx; + return true; + } + } + + return false; +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_maya.cpp b/src/nw4r/g3d/g3d_maya.cpp new file mode 100644 index 00000000..ad54068b --- /dev/null +++ b/src/nw4r/g3d/g3d_maya.cpp @@ -0,0 +1,382 @@ +#include + +namespace nw4r { +namespace g3d { +namespace detail { +namespace dcc { +namespace { + +void MakeTexSrtMtx_S(math::MTX34* pMtx, const TexSrt& rSrt) { + pMtx->_00 = rSrt.Su; + pMtx->_01 = 0.0f; + pMtx->_02 = 0.0f; + pMtx->_03 = 0.0f; + + pMtx->_10 = 0.0f; + pMtx->_11 = rSrt.Sv; + pMtx->_12 = 0.0f; + pMtx->_13 = 1.0f - rSrt.Sv; +} + +void MakeTexSrtMtx_R(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sinPart = 0.5f * sinR; + f32 cosPart = 0.5f - 0.5f * cosR; + + pMtx->_00 = cosR; + pMtx->_01 = sinR; + pMtx->_02 = 0.0f; + pMtx->_03 = cosPart - sinPart; + + pMtx->_10 = -sinR; + pMtx->_11 = cosR; + pMtx->_12 = 0.0f; + pMtx->_13 = cosPart + sinPart; +} + +void MakeTexSrtMtx_T(math::MTX34* pMtx, const TexSrt& rSrt) { + pMtx->_00 = 1.0f; + pMtx->_01 = 0.0f; + pMtx->_02 = 0.0f; + pMtx->_03 = -rSrt.Tu; + + pMtx->_10 = 0.0f; + pMtx->_11 = 1.0f; + pMtx->_12 = 0.0f; + pMtx->_13 = rSrt.Tv; +} + +void MakeTexSrtMtx_SR(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sucr = rSrt.Su * cosR; + f32 susr = rSrt.Su * sinR; + f32 svcr = rSrt.Sv * cosR; + f32 svsr = rSrt.Sv * sinR; + + pMtx->_00 = sucr; + pMtx->_01 = susr; + pMtx->_02 = 0.0f; + pMtx->_03 = -0.5f * (susr + sucr - rSrt.Su); + + pMtx->_10 = -svsr; + pMtx->_11 = svcr; + pMtx->_12 = 0.0f; + pMtx->_13 = 0.5f * (svsr - svcr - rSrt.Sv) + 1.0f; +} + +void MakeTexSrtMtx_RT(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sinPart = 0.5f * sinR; + f32 cosPart = 0.5f - 0.5f * cosR; + + pMtx->_00 = cosR; + pMtx->_01 = sinR; + pMtx->_02 = 0.0f; + pMtx->_03 = cosPart - sinPart - rSrt.Tu; + + pMtx->_10 = -sinR; + pMtx->_11 = cosR; + pMtx->_12 = 0.0f; + pMtx->_13 = cosPart + sinPart + rSrt.Tv; +} + +void MakeTexSrtMtx_ST(math::MTX34* pMtx, const TexSrt& rSrt) { + pMtx->_00 = rSrt.Su; + pMtx->_01 = 0.0f; + pMtx->_02 = 0.0f; + pMtx->_03 = -rSrt.Su * rSrt.Tu; + + pMtx->_10 = 0.0f; + pMtx->_11 = rSrt.Sv; + pMtx->_12 = 0.0f; + pMtx->_13 = rSrt.Sv * (rSrt.Tv - 1.0f) + 1.0f; +} + +void MakeTexSrtMtx_SRT(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sinPart = 0.5f * sinR - 0.5f; + f32 cosPart = -0.5f * cosR; + + pMtx->_00 = rSrt.Su * cosR; + pMtx->_01 = rSrt.Su * sinR; + pMtx->_02 = 0.0f; + pMtx->_03 = rSrt.Su * (cosPart - sinPart - rSrt.Tu); + + pMtx->_10 = -rSrt.Sv * sinR; + pMtx->_11 = rSrt.Sv * cosR; + pMtx->_12 = 0.0f; + pMtx->_13 = rSrt.Sv * (cosPart + sinPart + rSrt.Tv) + 1.0f; +} + +void ProductTexSrtMtx_S(math::MTX34* pMtx, const TexSrt& rSrt) { + pMtx->_00 *= rSrt.Su; + pMtx->_01 *= rSrt.Su; + pMtx->_02 *= rSrt.Su; + pMtx->_03 *= rSrt.Su; + + pMtx->_10 *= rSrt.Sv; + pMtx->_11 *= rSrt.Sv; + pMtx->_12 *= rSrt.Sv; + pMtx->_13 = 1.0f + pMtx->_13 * rSrt.Sv - rSrt.Sv; +} + +void ProductTexSrtMtx_R(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + f32 _0x, _1x; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sinPart = 0.5f * sinR; + f32 cosPart = 0.5f - 0.5f * cosR; + + _0x = cosR * pMtx->_00 + sinR * pMtx->_10; + _1x = -sinR * pMtx->_00 + cosR * pMtx->_10; + pMtx->_00 = _0x; + pMtx->_10 = _1x; + + _0x = cosR * pMtx->_01 + sinR * pMtx->_11; + _1x = -sinR * pMtx->_01 + cosR * pMtx->_11; + pMtx->_01 = _0x; + pMtx->_11 = _1x; + + _0x = cosR * pMtx->_02 + sinR * pMtx->_12; + _1x = -sinR * pMtx->_02 + cosR * pMtx->_12; + pMtx->_02 = _0x; + pMtx->_12 = _1x; + + _0x = cosR * pMtx->_03 + sinR * pMtx->_13 + cosPart - sinPart; + _1x = -sinR * pMtx->_03 + cosR * pMtx->_13 + cosPart + sinPart; + pMtx->_03 = _0x; + pMtx->_13 = _1x; +} + +void ProductTexSrtMtx_T(math::MTX34* pMtx, const TexSrt& rSrt) { + pMtx->_03 += -rSrt.Tu; + pMtx->_13 += rSrt.Tv; +} + +void ProductTexSrtMtx_SR(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + f32 _0x, _1x; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sucr = rSrt.Su * cosR; + f32 susr = rSrt.Su * sinR; + f32 svcr = rSrt.Sv * cosR; + f32 svsr = rSrt.Sv * sinR; + + _0x = sucr * pMtx->_00 + susr * pMtx->_10; + _1x = -svsr * pMtx->_00 + svcr * pMtx->_10; + pMtx->_00 = _0x; + pMtx->_10 = _1x; + + _0x = sucr * pMtx->_01 + susr * pMtx->_11; + _1x = -svsr * pMtx->_01 + svcr * pMtx->_11; + pMtx->_01 = _0x; + pMtx->_11 = _1x; + + _0x = sucr * pMtx->_02 + susr * pMtx->_12; + _1x = -svsr * pMtx->_02 + svcr * pMtx->_12; + pMtx->_02 = _0x; + pMtx->_12 = _1x; + + // clang-format off + _0x = sucr * (pMtx->_03 - 0.5f) + + susr * (pMtx->_13 - 0.5f) + + 0.5f * rSrt.Su; + + _1x = -svsr * (pMtx->_03 - 0.5f) + + svcr * (pMtx->_13 - 0.5f) + - 0.5f * rSrt.Sv + 1.0f; + // clang-format on + + pMtx->_03 = _0x; + pMtx->_13 = _1x; +} + +void ProductTexSrtMtx_RT(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + f32 _0x, _1x; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sinPart = 0.5f * sinR - 0.5f; + f32 cosPart = -0.5f * cosR; + + _0x = cosR * pMtx->_00 + sinR * pMtx->_10; + _1x = -sinR * pMtx->_00 + cosR * pMtx->_10; + pMtx->_00 = _0x; + pMtx->_10 = _1x; + + _0x = cosR * pMtx->_01 + sinR * pMtx->_11; + _1x = -sinR * pMtx->_01 + cosR * pMtx->_11; + pMtx->_01 = _0x; + pMtx->_11 = _1x; + + _0x = cosR * pMtx->_02 + sinR * pMtx->_12; + _1x = -sinR * pMtx->_02 + cosR * pMtx->_12; + pMtx->_02 = _0x; + pMtx->_12 = _1x; + + _0x = cosR * pMtx->_03 + sinR * pMtx->_13 + cosPart - sinPart - rSrt.Tu; + _1x = -sinR * pMtx->_03 + cosR * pMtx->_13 + cosPart + sinPart + rSrt.Tv; + pMtx->_03 = _0x; + pMtx->_13 = _1x; +} + +void ProductTexSrtMtx_ST(math::MTX34* pMtx, const TexSrt& rSrt) { + pMtx->_00 *= rSrt.Su; + pMtx->_01 *= rSrt.Su; + pMtx->_02 *= rSrt.Su; + pMtx->_03 = rSrt.Su * (pMtx->_03 - rSrt.Tu); + + pMtx->_10 *= rSrt.Sv; + pMtx->_11 *= rSrt.Sv; + pMtx->_12 *= rSrt.Sv; + pMtx->_13 = rSrt.Sv * (pMtx->_13 + rSrt.Tv - 1.0f) + 1.0f; +} + +void ProductTexSrtMtx_SRT(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + f32 _0x, _1x; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sucr = rSrt.Su * cosR; + f32 susr = rSrt.Su * sinR; + f32 svcr = rSrt.Sv * cosR; + f32 svsr = rSrt.Sv * sinR; + + _0x = sucr * pMtx->_00 + susr * pMtx->_10; + _1x = -svsr * pMtx->_00 + svcr * pMtx->_10; + pMtx->_00 = _0x; + pMtx->_10 = _1x; + + _0x = sucr * pMtx->_01 + susr * pMtx->_11; + _1x = -svsr * pMtx->_01 + svcr * pMtx->_11; + pMtx->_01 = _0x; + pMtx->_11 = _1x; + + _0x = sucr * pMtx->_02 + susr * pMtx->_12; + _1x = -svsr * pMtx->_02 + svcr * pMtx->_12; + pMtx->_02 = _0x; + pMtx->_12 = _1x; + + _0x = sucr * (pMtx->_03 - 0.5f) + susr * (pMtx->_13 - 0.5f) + + (0.5f - rSrt.Tu) * rSrt.Su; + + _1x = -svsr * (0.5f + pMtx->_03) + svcr * (pMtx->_13 - 0.5f) - + (0.5f - rSrt.Tv) * rSrt.Sv + 1.0f; + + pMtx->_03 = _0x; + pMtx->_13 = _1x; +} + +} // namespace + +typedef void (*CalcTexMtxFunc)(math::MTX34* pMtx, const TexSrt& rSrt); + +bool CalcTexMtx_Maya(math::MTX34* pMtx, bool set, const TexSrt& rSrt, + TexSrt::Flag flag) { + // Extract S/R/T flags + u32 index = flag >> 1 & 0b111; + + // Scale-one, no rotate/trans + if (index == 0b111) { + return false; + } + + if (set) { + static const CalcTexMtxFunc funcTable[] = { + MakeTexSrtMtx_SRT, // 0 0 0 + MakeTexSrtMtx_RT, // 0 0 1 + MakeTexSrtMtx_ST, // 0 1 0 + MakeTexSrtMtx_T, // 0 1 1 + MakeTexSrtMtx_SR, // 1 0 0 + MakeTexSrtMtx_R, // 1 0 1 + MakeTexSrtMtx_S // 1 1 0 + }; + + funcTable[index](pMtx, rSrt); + } else { + static const CalcTexMtxFunc funcTable[] = { + ProductTexSrtMtx_SRT, // 0 0 0 + ProductTexSrtMtx_RT, // 0 0 1 + ProductTexSrtMtx_ST, // 0 1 0 + ProductTexSrtMtx_T, // 0 1 1 + ProductTexSrtMtx_SR, // 1 0 0 + ProductTexSrtMtx_R, // 1 0 1 + ProductTexSrtMtx_S // 1 1 0 + }; + + funcTable[index](pMtx, rSrt); + } + + pMtx->_20 = 0.0f; + pMtx->_21 = 0.0f; + pMtx->_22 = 1.0f; + pMtx->_23 = 0.0f; + + return true; +} + +u32 CalcWorldMtx_Maya_SSC_Apply(math::MTX34* pW, math::VEC3* pS, + const math::MTX34* pW1, const math::VEC3* pS1, + u32 attr, const ChrAnmResult* pResult) { + u32 flag = pResult->flags; + u32 newAttr = attr; + + if (flag & ChrAnmResult::FLAG_SCALE_ONE) { + newAttr = detail::WorldMtxAttr::AnmScaleOne(newAttr); + pS->x = pS->y = pS->z = 1.0f; + } else { + newAttr = detail::WorldMtxAttr::AnmNotScaleOne(newAttr); + *pS = pResult->s; + } + + if ((flag & ChrAnmResult::FLAG_MTX_IDENT) || + (flag & ChrAnmResult::FLAG_ROT_TRANS_ZERO)) { + + math::MTX34Copy(pW, pW1); + } else if (flag & ChrAnmResult::FLAG_ROT_ZERO) { + + if (detail::WorldMtxAttr::IsScaleOne(attr)) { + math::VEC3 trans(pResult->rt._03, pResult->rt._13, pResult->rt._23); + + math::MTX34Trans(pW, pW1, &trans); + } else { + math::VEC3 trans(pS1->x * pResult->rt._03, pS1->y * pResult->rt._13, + pS1->z * pResult->rt._23); + + math::MTX34Trans(pW, pW1, &trans); + } + } else if (detail::WorldMtxAttr::IsScaleOne(attr)) { + math::MTX34Mult(pW, pW1, &pResult->rt); + } else { + math::MTX34Copy(pW, &pResult->rt); + + pW->_03 *= pS1->x; + pW->_13 *= pS1->y; + pW->_23 *= pS1->z; + + math::MTX34Mult(pW, pW1, pW); + } + + if (flag & ChrAnmResult::FLAG_SCALE_UNIFORM) { + newAttr = detail::WorldMtxAttr::AnmScaleUniform(newAttr); + } else { + newAttr = detail::WorldMtxAttr::AnmNotScaleUniform(newAttr); + } + + return newAttr; +} + +} // namespace dcc +} // namespace detail +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_obj.cpp b/src/nw4r/g3d/g3d_obj.cpp new file mode 100644 index 00000000..ffd92ca9 --- /dev/null +++ b/src/nw4r/g3d/g3d_obj.cpp @@ -0,0 +1,28 @@ +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(G3dObj); + +G3dObj::~G3dObj() { + Dealloc(mpHeap, this); +} + +void G3dObj::Destroy() { + G3dObj* pParent = GetParent(); + + if (pParent != NULL) { + pParent->G3dProc(G3DPROC_CHILD_DETACHED, 0, this); + } + + delete this; +} + +// clang-format off +DECOMP_FORCEACTIVE(g3d_obj_cpp, + G3dObj::IsDerivedFrom); +// clang-format on + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_scnmdl.cpp b/src/nw4r/g3d/g3d_scnmdl.cpp new file mode 100644 index 00000000..2b536b44 --- /dev/null +++ b/src/nw4r/g3d/g3d_scnmdl.cpp @@ -0,0 +1,1142 @@ +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(ScnMdl); + +/****************************************************************************** + * + * CopiedMatAccess + * + ******************************************************************************/ +ResTexObj ScnMdl::CopiedMatAccess::GetResTexObj(bool markDirty) { + if (mpScnMdl != NULL && mTexObj.IsValid()) { + if (markDirty) { + mpScnMdl->MatBufferDirty(mMatID, ScnMdl::BUFOPTION_TEXOBJ); + } + + return mTexObj; + } + + return ResTexObj(NULL); +} + +ResTexSrt ScnMdl::CopiedMatAccess::GetResTexSrt(bool markDirty) { + if (mpScnMdl != NULL && mTexSrt.IsValid()) { + if (markDirty) { + mpScnMdl->MatBufferDirty(mMatID, ScnMdl::BUFOPTION_TEXSRT); + } + + return mTexSrt; + } + + return ResTexSrt(NULL); +} + +ResMatChan ScnMdl::CopiedMatAccess::GetResMatChan(bool markDirty) { + if (mpScnMdl != NULL && mChan.IsValid()) { + if (markDirty) { + mpScnMdl->MatBufferDirty(mMatID, ScnMdl::BUFOPTION_MATCHAN); + } + + return mChan; + } + + return ResMatChan(NULL); +} + +ResGenMode ScnMdl::CopiedMatAccess::GetResGenMode(bool markDirty) { + if (mpScnMdl != NULL && mGenMode.IsValid()) { + if (markDirty) { + mpScnMdl->MatBufferDirty(mMatID, ScnMdl::BUFOPTION_GENMODE); + } + + return mGenMode; + } + + return ResGenMode(NULL); +} + +ResMatPix ScnMdl::CopiedMatAccess::GetResMatPix(bool markDirty) { + if (mpScnMdl != NULL && mPix.IsValid()) { + if (markDirty) { + mpScnMdl->MatBufferDirty(mMatID, ScnMdl::BUFOPTION_MATPIX); + } + + return mPix; + } + + return ResMatPix(NULL); +} + +ResMatTevColor ScnMdl::CopiedMatAccess::GetResMatTevColor(bool markDirty) { + if (mpScnMdl != NULL && mTevColor.IsValid()) { + if (markDirty) { + mpScnMdl->MatBufferDirty(mMatID, ScnMdl::BUFOPTION_MATTEVCOLOR); + } + + return mTevColor; + } + + return ResMatTevColor(NULL); +} + +ResTev ScnMdl::CopiedMatAccess::GetResTev(bool markDirty) { + if (mpScnMdl != NULL && mTev.IsValid()) { + if (markDirty) { + mpScnMdl->MatBufferDirty(mMatID, ScnMdl::BUFOPTION_TEV); + } + + return mTev; + } + + return ResTev(NULL); +} + +ResTexSrt ScnMdl::CopiedMatAccess::GetResTexSrtEx() { + if (mpScnMdl != NULL) { + if (mTexSrt.IsValid()) { + return mTexSrt; + } + + return mpScnMdl->GetResMdl().GetResMat(mMatID).GetResTexSrt(); + } + + return ResTexSrt(NULL); +} + +ScnMdl::CopiedMatAccess::CopiedMatAccess(ScnMdl* pScnMdl, u32 id) + : mTexObj(NULL), + mTlutObj(NULL), + mTexSrt(NULL), + mChan(NULL), + mGenMode(NULL), + mMatMisc(NULL), + mPix(NULL), + mTevColor(NULL), + mIndMtxAndScale(NULL), + mTexCoordGen(NULL), + mTev(NULL) { + + if (pScnMdl != NULL && pScnMdl->GetResMdl().GetResMat(id).IsValid()) { + mpScnMdl = pScnMdl; + mMatID = id; + + DrawResMdlReplacement& rReplacement = pScnMdl->mReplacement; + + if (rReplacement.texObjDataArray != NULL) { + mTexObj = ResTexObj(&rReplacement.texObjDataArray[id]); + } else { + mTexObj = ResTexObj(NULL); + } + + if (rReplacement.tlutObjDataArray != NULL) { + mTlutObj = ResTlutObj(&rReplacement.tlutObjDataArray[id]); + } else { + mTlutObj = ResTlutObj(NULL); + } + + if (rReplacement.texSrtDataArray != NULL) { + mTexSrt = ResTexSrt(&rReplacement.texSrtDataArray[id]); + } else { + mTexSrt = ResTexSrt(NULL); + } + + if (rReplacement.chanDataArray != NULL) { + mChan = ResMatChan(&rReplacement.chanDataArray[id]); + } else { + mChan = ResMatChan(NULL); + } + + if (rReplacement.genModeDataArray != NULL) { + mGenMode = ResGenMode(&rReplacement.genModeDataArray[id]); + } else { + mGenMode = ResGenMode(NULL); + } + + if (rReplacement.matMiscDataArray != NULL) { + mMatMisc = ResMatMisc(&rReplacement.matMiscDataArray[id]); + } else { + mMatMisc = ResMatMisc(NULL); + } + + if (rReplacement.pixDLArray != NULL) { + mPix = ResMatPix(&rReplacement.pixDLArray[id]); + } else { + mPix = ResMatPix(NULL); + } + + if (rReplacement.tevColorDLArray != NULL) { + mTevColor = ResMatTevColor(&rReplacement.tevColorDLArray[id]); + } else { + mTevColor = ResMatTevColor(NULL); + } + + if (rReplacement.indMtxAndScaleDLArray != NULL) { + mIndMtxAndScale = + ResMatIndMtxAndScale(&rReplacement.indMtxAndScaleDLArray[id]); + } else { + mIndMtxAndScale = ResMatIndMtxAndScale(NULL); + } + + if (rReplacement.texCoordGenDLArray != NULL) { + mTexCoordGen = + ResMatTexCoordGen(&rReplacement.texCoordGenDLArray[id]); + } else { + mTexCoordGen = ResMatTexCoordGen(NULL); + } + + if (rReplacement.tevDataArray != NULL) { + mTev = ResTev(&rReplacement.tevDataArray[id]); + } else { + mTev = ResTev(NULL); + } + + } else { + mpScnMdl = NULL; + mMatID = id; + + mTexObj = ResTexObj(NULL); + mTlutObj = ResTlutObj(NULL); + mTexSrt = ResTexSrt(NULL); + mChan = ResMatChan(NULL); + mGenMode = ResGenMode(NULL); + mMatMisc = ResMatMisc(NULL); + mPix = ResMatPix(NULL); + mTevColor = ResMatTevColor(NULL); + mIndMtxAndScale = ResMatIndMtxAndScale(NULL); + mTexCoordGen = ResMatTexCoordGen(NULL); + mTev = ResTev(NULL); + } +} + +/****************************************************************************** + * + * CopiedVisAccess + * + ******************************************************************************/ +bool ScnMdl::CopiedVisAccess::IsVisible() const { + if (mpScnMdl != NULL) { + if (mpVis != NULL) { + return *mpVis != 0; + } + + return mpScnMdl->GetResMdl().GetResNode(mNodeID).IsVisible(); + } + + return false; +} + +bool ScnMdl::CopiedVisAccess::SetVisibilityEx(bool visible) { + if (mpScnMdl != NULL) { + if (mpVis != NULL) { + if (visible && *mpVis == 0 || !visible && *mpVis != 0) { + mpScnMdl->VisBufferDirty(); + } + + *mpVis = visible; + } else { + mpScnMdl->GetResMdl().GetResNode(mNodeID).SetVisibility(visible); + } + + return true; + } + + return false; +} + +ScnMdl::CopiedVisAccess::CopiedVisAccess(ScnMdl* pScnMdl, u32 id) { + if (pScnMdl != NULL && pScnMdl->GetResMdl().GetResNode(id).IsValid()) { + mpScnMdl = pScnMdl; + mNodeID = id; + + if (pScnMdl->mReplacement.visArray != NULL) { + mpVis = &pScnMdl->mReplacement.visArray[id]; + } else { + mpVis = NULL; + } + } else { + mpScnMdl = NULL; + mNodeID = id; + mpVis = NULL; + } +} + +/****************************************************************************** + * + * ScnMdl + * + ******************************************************************************/ +ScnMdl* ScnMdl::Construct(MEMAllocator* pAllocator, u32* pSize, ResMdl mdl, + u32 bufferOption, int numView) { + + if (!mdl.IsValid()) { + return NULL; + } + + if (numView == 0) { + numView = 1; + } else if (numView > VIEW_MAX) { + numView = VIEW_MAX; + } + + ScnMdl* pScnMdl = NULL; + + u32 worldMtxNum = mdl.GetResMdlInfo().GetNumPosNrmMtx(); + u32 viewMtxNum = mdl.GetResMdlInfo().GetNumViewMtx(); + u32 matNum = mdl.GetResMatNumEntries(); + u32 nodeNum = mdl.GetResNodeNumEntries(); + + u32 scnMdlSize = sizeof(ScnMdl); + u32 worldMtxArraySize = worldMtxNum * sizeof(math::MTX34); + u32 worldMtxAttribArraySize = worldMtxNum * sizeof(u32); + + u32 viewPosMtxArrayUnitSize = viewMtxNum * sizeof(math::MTX34); + u32 viewPosMtxArraySize = numView * align32(viewPosMtxArrayUnitSize); + + u32 viewNrmMtxArrayUnitSize = viewMtxNum * sizeof(math::MTX33); + u32 viewNrmMtxArraySize = mdl.GetResMdlInfo().ref().need_nrm_mtx_array + ? numView * align32(viewNrmMtxArrayUnitSize) + : 0; + + u32 viewTexMtxArrayUnitSize = viewPosMtxArrayUnitSize; + + // TODO: Fakematch + u32 viewTexMtxArraySize = mdl.ref().info.need_tex_mtx_array + ? numView * align32(viewTexMtxArrayUnitSize) + : 0; + + u32 matBufferDirtyFlagSize = matNum * sizeof(u32); + + // clang-format off + u32 resTexObjSize = (bufferOption & BUFOPTION_TEXOBJ) ? matNum * sizeof(ResTexObjData) : 0; + u32 resTlutObjSize = (bufferOption & BUFOPTION_TLUTOBJ) ? matNum * sizeof(ResTlutObjData) : 0; + u32 resTexSrtSize = (bufferOption & BUFOPTION_TEXSRT) ? matNum * sizeof(ResTexSrtData) : 0; + u32 resChanSize = (bufferOption & BUFOPTION_MATCHAN) ? matNum * sizeof(ResChanData) : 0; + u32 resGenModeSize = (bufferOption & BUFOPTION_GENMODE) ? matNum * sizeof(ResGenModeData) : 0; + u32 resMatMiscSize = (bufferOption & BUFOPTION_MATMISC) ? matNum * sizeof(ResMatMiscData) : 0; + u32 visSize = (bufferOption & BUFOPTION_VIS) ? nodeNum * sizeof(u8) : 0; + u32 resPixSize = (bufferOption & BUFOPTION_MATPIX) ? matNum * sizeof(ResPixDL) : 0; + u32 resTevColorSize = (bufferOption & BUFOPTION_MATTEVCOLOR) ? matNum * sizeof(ResTevColorDL) : 0; + u32 resIndMtxAndScaleSize = (bufferOption & BUFOPTION_MATINDMTXSCALE) ? matNum * sizeof(ResIndMtxAndScaleDL) : 0; + u32 resTexCoordGenSize = (bufferOption & BUFOPTION_MATTEXCOORDGEN) ? matNum * sizeof(ResTexCoordGenDL) : 0; + u32 resTevSize = (bufferOption & BUFOPTION_TEV) ? matNum * sizeof(ResTevData) : 0; + // clang-format on + + u32 vtxPosTableSize = 0; + u32 vtxPosBufferSize = 0; + + if (bufferOption & BUFOPTION_VTXPOS) { + u32 vtxPosNum = mdl.GetResVtxPosNumEntries(); + u32 shpNum = mdl.GetResShpNumEntries(); + + vtxPosTableSize = vtxPosNum * sizeof(ResVtxPosData*); + + for (u32 i = 0; i < vtxPosNum; i++) { + u32 j; + ResVtxPos pos = mdl.GetResVtxPos(i); + + for (j = 0; j < shpNum; j++) { + ResShp shp = mdl.GetResShp(j); + + if (pos.ptr() == shp.GetResVtxPos().ptr()) { + break; + } + } + + if (j != shpNum) { + vtxPosBufferSize += align32(pos.GetSize()); + } + } + } + + u32 vtxNrmTableSize = 0; + u32 vtxNrmBufferSize = 0; + + if (bufferOption & BUFOPTION_VTXNRM) { + u32 vtxNrmNum = mdl.GetResVtxNrmNumEntries(); + u32 shpNum = mdl.GetResShpNumEntries(); + + vtxNrmTableSize = vtxNrmNum * sizeof(ResVtxNrmData*); + + for (u32 i = 0; i < vtxNrmNum; i++) { + u32 j; + ResVtxNrm nrm = mdl.GetResVtxNrm(i); + + for (j = 0; j < shpNum; j++) { + ResShp shp = mdl.GetResShp(j); + + if (nrm.ptr() == shp.GetResVtxNrm().ptr()) { + break; + } + } + + if (j != shpNum) { + vtxNrmBufferSize += align32(nrm.GetSize()); + } + } + } + + u32 vtxClrTableSize = 0; + u32 vtxClrBufferSize = 0; + + if (bufferOption & BUFOPTION_VTXCLR) { + u32 vtxClrNum = mdl.GetResVtxClrNumEntries(); + u32 shpNum = mdl.GetResShpNumEntries(); + + vtxClrTableSize = vtxClrNum * sizeof(ResVtxClrData*); + + for (u32 i = 0; i < vtxClrNum; i++) { + u32 j; + ResVtxClr clr = mdl.GetResVtxClr(i); + + for (j = 0; j < shpNum; j++) { + ResShp shp = mdl.GetResShp(j); + + if (clr.ptr() == shp.GetResVtxClr(0).ptr() || + clr.ptr() == shp.GetResVtxClr(1).ptr()) { + break; + } + } + + if (j != shpNum) { + vtxClrBufferSize += align32(clr.GetSize()); + } + } + } + + // clang-format off + u32 worldMtxArrayOfs = align32(scnMdlSize); + u32 worldMtxAttribArrayOfs = align32(worldMtxArrayOfs + worldMtxArraySize); + u32 viewPosMtxArrayOfs = align32(worldMtxAttribArrayOfs + worldMtxAttribArraySize); + u32 viewNrmMtxArrayOfs = align32(viewPosMtxArrayOfs + viewPosMtxArraySize); + u32 viewTexMtxArrayOfs = align32(viewNrmMtxArrayOfs + viewNrmMtxArraySize); + u32 matBufferDirtyFlagOfs = align4(viewTexMtxArrayOfs + viewTexMtxArraySize); + u32 resTexObjOfs = align32(matBufferDirtyFlagOfs + matBufferDirtyFlagSize); + u32 resTlutObjOfs = align4(resTexObjOfs + resTexObjSize); + u32 resTexSrtOfs = align4(resTlutObjOfs + resTlutObjSize); + u32 resChanOfs = align4(resTexSrtOfs + resTexSrtSize); + u32 resGenModeOfs = align4(resChanOfs + resChanSize); + u32 resMatMiscOfs = align4(resGenModeOfs + resGenModeSize); + u32 visOfs = align4(resMatMiscOfs + resMatMiscSize); + u32 resPixOfs = align32(visOfs + visSize); + u32 resTevColorOfs = align32(resPixOfs + resPixSize); + u32 resIndMtxAndScaleOfs = align32(resTevColorOfs + resTevColorSize); + u32 resTexCoordGenOfs = align32(resIndMtxAndScaleOfs + resIndMtxAndScaleSize); + u32 resTevOfs = align32(resTexCoordGenOfs + resTexCoordGenSize); + // clang-format on + + u32 vtxPosTableOfs = align32(resTevOfs + resTevSize); + u32 vtxNrmTableOfs = vtxPosTableOfs + vtxPosTableSize; + u32 vtxClrTableOfs = vtxNrmTableOfs + vtxNrmTableSize; + + u32 vtxPosBufferOfs = align32(vtxClrTableOfs + vtxClrTableSize); + u32 vtxNrmBufferOfs = align32(vtxPosBufferOfs + vtxPosBufferSize); + u32 vtxClrBufferOfs = align32(vtxNrmBufferOfs + vtxNrmBufferSize); + + u32 size = align32(vtxClrBufferOfs + vtxClrBufferSize); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator != NULL) { + u8* pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + // clang-format off + DrawResMdlReplacement replacement; + + replacement.visArray = visSize != 0 ? reinterpret_cast(pBuffer + visOfs) : NULL; + replacement.texObjDataArray = resTexObjSize != 0 ? reinterpret_cast(pBuffer + resTexObjOfs) : NULL; + replacement.tlutObjDataArray = resTlutObjSize != 0 ? reinterpret_cast(pBuffer + resTlutObjOfs) : NULL; + replacement.texSrtDataArray = resTexSrtSize != 0 ? reinterpret_cast(pBuffer + resTexSrtOfs) : NULL; + replacement.chanDataArray = resChanSize != 0 ? reinterpret_cast(pBuffer + resChanOfs) : NULL; + replacement.genModeDataArray = resGenModeSize != 0 ? reinterpret_cast(pBuffer + resGenModeOfs) : NULL; + replacement.matMiscDataArray = resMatMiscSize != 0 ? reinterpret_cast(pBuffer + resMatMiscOfs) : NULL; + replacement.pixDLArray = resPixSize != 0 ? reinterpret_cast(pBuffer + resPixOfs) : NULL; + replacement.tevColorDLArray = resTevColorSize != 0 ? reinterpret_cast(pBuffer + resTevColorOfs) : NULL; + replacement.indMtxAndScaleDLArray = resIndMtxAndScaleSize != 0 ? reinterpret_cast(pBuffer + resIndMtxAndScaleOfs) : NULL; + replacement.texCoordGenDLArray = resTexCoordGenSize != 0 ? reinterpret_cast(pBuffer + resTexCoordGenOfs) : NULL; + replacement.tevDataArray = resTevSize != 0 ? reinterpret_cast(pBuffer + resTevOfs) : NULL; + + replacement.vtxPosTable = vtxPosTableSize != 0 ? reinterpret_cast(pBuffer + vtxPosTableOfs) : NULL; + replacement.vtxNrmTable = vtxNrmTableSize != 0 ? reinterpret_cast(pBuffer + vtxNrmTableOfs) : NULL; + replacement.vtxClrTable = vtxClrTableSize != 0 ? reinterpret_cast(pBuffer + vtxClrTableOfs) : NULL; + // clang-format on + + if (replacement.vtxPosTable != NULL) { + u32 vtxPosNum = mdl.GetResVtxPosNumEntries(); + u32 shpNum = mdl.GetResShpNumEntries(); + + u32 ofs = vtxPosBufferOfs; + + for (u32 i = 0; i < vtxPosNum; i++) { + u32 j; + ResVtxPos pos = mdl.GetResVtxPos(i); + + for (j = 0; j < shpNum; j++) { + ResShp shp = mdl.GetResShp(j); + + if (pos.ptr() == shp.GetResVtxPos().ptr()) { + break; + } + } + + if (j != shpNum) { + replacement.vtxPosTable[i] = + reinterpret_cast(pBuffer + ofs); + + ofs += align32(pos.GetSize()); + pos.CopyTo(replacement.vtxPosTable[i]); + } else { + replacement.vtxPosTable[i] = pos.ptr(); + } + } + } + + if (replacement.vtxNrmTable != NULL) { + u32 vtxNrmNum = mdl.GetResVtxNrmNumEntries(); + u32 shpNum = mdl.GetResShpNumEntries(); + + u32 ofs = vtxNrmBufferOfs; + + for (u32 i = 0; i < vtxNrmNum; i++) { + u32 j; + ResVtxNrm nrm = mdl.GetResVtxNrm(i); + + for (j = 0; j < shpNum; j++) { + ResShp shp = mdl.GetResShp(j); + + if (nrm.ptr() == shp.GetResVtxNrm().ptr()) { + break; + } + } + + if (j != shpNum) { + replacement.vtxNrmTable[i] = + reinterpret_cast(pBuffer + ofs); + + ofs += align32(nrm.GetSize()); + nrm.CopyTo(replacement.vtxNrmTable[i]); + } else { + replacement.vtxNrmTable[i] = nrm.ptr(); + } + } + } + + if (replacement.vtxClrTable != NULL) { + u32 vtxClrNum = mdl.GetResVtxClrNumEntries(); + u32 shpNum = mdl.GetResShpNumEntries(); + + u32 ofs = vtxClrBufferOfs; + + for (u32 i = 0; i < vtxClrNum; i++) { + u32 j; + ResVtxClr clr = mdl.GetResVtxClr(i); + + for (j = 0; j < shpNum; j++) { + ResShp shp = mdl.GetResShp(j); + + if (clr.ptr() == shp.GetResVtxClr(0).ptr() || + clr.ptr() == shp.GetResVtxClr(1).ptr()) { + break; + } + } + + if (j != shpNum) { + replacement.vtxClrTable[i] = + reinterpret_cast(pBuffer + ofs); + + ofs += align32(clr.GetSize()); + clr.CopyTo(replacement.vtxClrTable[i]); + } else { + replacement.vtxClrTable[i] = clr.ptr(); + } + } + } + + // clang-format off + pScnMdl = new (pBuffer) ScnMdl( + pAllocator, + mdl, + reinterpret_cast(pBuffer + worldMtxArrayOfs), + reinterpret_cast(pBuffer + worldMtxAttribArrayOfs), + reinterpret_cast(pBuffer + viewPosMtxArrayOfs), + viewNrmMtxArraySize != 0 ? reinterpret_cast(pBuffer + viewNrmMtxArrayOfs) : NULL, + viewTexMtxArraySize != 0 ? reinterpret_cast(pBuffer + viewTexMtxArrayOfs) : NULL, + numView, + viewMtxNum, + &replacement, + reinterpret_cast(pBuffer + matBufferDirtyFlagOfs)); + // clang-format off + + pScnMdl->InitBuffer(); + } + + return pScnMdl; +} + +void ScnMdl::ScnMdl_G3DPROC_CALC_WORLD(u32 param, const math::MTX34* pParent) { + ScnMdlSmpl_CalcPosture(param, pParent); + + if (IsVisBufferRefreshNeeded() && IsVisBufferDirty()) { + CleanVisBuffer(); + } + + if (GetAnmObjVis() != NULL) { + if (mReplacement.visArray != NULL) { + ApplyVisAnmResult(mReplacement.visArray, GetResMdl(), + GetAnmObjVis()); + VisBufferDirty(); + } else { + ApplyVisAnmResult(GetResMdl(), GetAnmObjVis()); + } + } + + CheckCallback_CALC_WORLD(CALLBACK_TIMING_C, param, + const_cast(pParent)); +} + +void ScnMdl::ScnMdl_G3DPROC_CALC_MAT(u32 param, void* pInfo) { + CheckCallback_CALC_MAT(CALLBACK_TIMING_A, param, pInfo); + + ResMdl mdl = GetResMdl(); + u32 matNum = mdl.GetResMatNumEntries(); + + for (u32 i = 0; i < matNum; i++) { + ResMat mat = mdl.GetResMat(i); + + if (IsMatBufferDirty(i, BUFOPTION_TEXOBJ)) { + CleanMatBuffer(i, BUFOPTION_TEXOBJ); + } + + if (IsMatBufferDirty(i, BUFOPTION_TLUTOBJ)) { + CleanMatBuffer(i, BUFOPTION_TLUTOBJ); + } + + if (IsMatBufferDirty(i, BUFOPTION_MATINDMTXSCALE)) { + CleanMatBuffer(i, BUFOPTION_MATINDMTXSCALE); + } + + if (IsMatBufferDirty(i, BUFOPTION_TEXSRT)) { + CleanMatBuffer(i, BUFOPTION_TEXSRT); + } + + if (IsMatBufferDirty(i, BUFOPTION_MATCHAN)) { + CleanMatBuffer(i, BUFOPTION_MATCHAN); + } + + if (IsMatBufferDirty(i, BUFOPTION_MATTEVCOLOR)) { + CleanMatBuffer(i, BUFOPTION_MATTEVCOLOR); + } + + if (GetAnmObjTexPat() != NULL && GetAnmObjTexPat()->TestExistence(i)) { + TexPatAnmResult resultBuf; + + const TexPatAnmResult* pResult = + GetAnmObjTexPat()->GetResult(&resultBuf, i); + + ResTexObj texObj = mReplacement.texObjDataArray != NULL + ? ResTexObj(&mReplacement.texObjDataArray[i]) + : mat.GetResTexObj(); + + ResTlutObj tlutObj = + mReplacement.tlutObjDataArray != NULL + ? ResTlutObj(&mReplacement.tlutObjDataArray[i]) + : mat.GetResTlutObj(); + + ApplyTexPatAnmResult(texObj, tlutObj, pResult); + + texObj.EndEdit(); + tlutObj.EndEdit(); + + MatBufferDirty(i, BUFOPTION_TEXOBJ | BUFOPTION_TLUTOBJ); + } + + if (GetAnmObjTexSrt() != NULL && GetAnmObjTexSrt()->TestExistence(i)) { + TexSrtAnmResult resultBuf; + + const TexSrtAnmResult* pResult = + GetAnmObjTexSrt()->GetResult(&resultBuf, i); + + ResTexSrt srt = mReplacement.texSrtDataArray != NULL + ? ResTexSrt(&mReplacement.texSrtDataArray[i]) + : mat.GetResTexSrt(); + + ResMatIndMtxAndScale ind = + mReplacement.indMtxAndScaleDLArray != NULL + ? ResMatIndMtxAndScale( + &mReplacement.indMtxAndScaleDLArray[i]) + : mat.GetResMatIndMtxAndScale(); + + ApplyTexSrtAnmResult(srt, ind, pResult); + + ind.EndEdit(); + srt.EndEdit(); + + MatBufferDirty(i, BUFOPTION_TEXSRT | BUFOPTION_MATINDMTXSCALE); + } + + if (GetAnmObjMatClr() != NULL && GetAnmObjMatClr()->TestExistence(i)) { + ClrAnmResult resultBuf; + + ResMatTevColor tevColor = + mReplacement.tevColorDLArray != NULL + ? ResMatTevColor(&mReplacement.tevColorDLArray[i]) + : mat.GetResMatTevColor(); + + ResMatChan chan = mReplacement.chanDataArray != NULL + ? ResMatChan(&mReplacement.chanDataArray[i]) + : mat.GetResMatChan(); + + const ClrAnmResult* pResult = + GetAnmObjMatClr()->GetResult(&resultBuf, i); + + ApplyClrAnmResult(chan, tevColor, pResult); + + chan.EndEdit(); + tevColor.EndEdit(); + + MatBufferDirty(i, BUFOPTION_MATTEVCOLOR | BUFOPTION_MATCHAN); + } + } + + CheckCallback_CALC_MAT(CALLBACK_TIMING_C, param, pInfo); +} + +void ScnMdl::ScnMdl_G3DPROC_DRAW_OPA(u32 param, void* pInfo) { + CheckCallback_DRAW_OPA(CALLBACK_TIMING_A, param, pInfo); + + u32 drawMode = pInfo != NULL ? *static_cast(pInfo) : GetDrawMode(); + + DrawResMdlDirectly(GetResMdl(), GetViewPosMtxArray(), GetViewNrmMtxArray(), + GetViewTexMtxArray(), GetByteCodeDrawOpa(), NULL, + &mReplacement, drawMode); + + CheckCallback_DRAW_OPA(CALLBACK_TIMING_C, param, pInfo); +} + +void ScnMdl::ScnMdl_G3DPROC_DRAW_XLU(u32 param, void* pInfo) { + CheckCallback_DRAW_XLU(CALLBACK_TIMING_A, param, pInfo); + + u32 drawMode = pInfo != NULL ? *static_cast(pInfo) : GetDrawMode(); + + DrawResMdlDirectly(GetResMdl(), GetViewPosMtxArray(), GetViewNrmMtxArray(), + GetViewTexMtxArray(), NULL, GetByteCodeDrawXlu(), + &mReplacement, drawMode); + + CheckCallback_DRAW_XLU(CALLBACK_TIMING_C, param, pInfo); +} + +void ScnMdl::ScnMdl_G3DPROC_CALC_VTX(u32 param, void* pInfo) { +#pragma unused(param) +#pragma unused(pInfo) + + if (GetAnmObjShp() == NULL) { + return; + } + + CalcVtx(GetResMdl(), GetAnmObjShp(), mReplacement.vtxPosTable, + mReplacement.vtxNrmTable, mReplacement.vtxClrTable); +} + +void ScnMdl::G3dProc(u32 task, u32 param, void* pInfo) { + if (IsG3dProcDisabled(task)) { + return; + } + + switch (task) { + case G3DPROC_GATHER_SCNOBJ: { + ScnMdlSmpl_G3DPROC_GATHER_SCNOBJ(param, + static_cast(pInfo)); + break; + } + + case G3DPROC_CALC_WORLD: { + ScnMdl_G3DPROC_CALC_WORLD(param, static_cast(pInfo)); + break; + } + + case G3DPROC_CALC_MAT: { + ScnMdl_G3DPROC_CALC_MAT(param, pInfo); + break; + } + + case G3DPROC_CALC_VIEW: { + ScnMdlSmpl_G3DPROC_CALC_VIEW(param, static_cast(pInfo)); + break; + } + + case G3DPROC_DRAW_OPA: { + ScnMdl_G3DPROC_DRAW_OPA(param, pInfo); + break; + } + + case G3DPROC_DRAW_XLU: { + ScnMdl_G3DPROC_DRAW_XLU(param, pInfo); + break; + } + + case G3DPROC_UPDATEFRAME: { + ScnMdlSmpl_G3DPROC_UPDATEFRAME(param, pInfo); + + if (mpAnmObjShp != NULL) { + mpAnmObjShp->UpdateFrame(); + } + break; + } + + case G3DPROC_CHILD_DETACHED: { + RemoveAnmObj(static_cast(pInfo)); + break; + } + + case G3DPROC_CALC_VTX: { + ScnMdl_G3DPROC_CALC_VTX(param, pInfo); + break; + } + + default: { + DefG3dProcScnLeaf(task, param, pInfo); + break; + } + } +} + +bool ScnMdl::SetScnObjOption(u32 option, u32 value) { + switch (option) { + case OPTION_VISBUFFER_REFRESH_NEEDED: { + if (value) { + mFlagVisBuffer &= ~VISBUFFER_NOT_REFRESH_NEEDED; + } else { + mFlagVisBuffer |= VISBUFFER_NOT_REFRESH_NEEDED; + } + break; + } + + default: { + return ScnMdlSimple::SetScnObjOption(option, value); + } + } + + return true; +} + +bool ScnMdl::GetScnObjOption(u32 option, u32* pValue) const { + if (pValue == NULL) { + return false; + } + + switch (option) { + case OPTION_VISBUFFER_REFRESH_NEEDED: { + *pValue = !(mFlagVisBuffer & VISBUFFER_NOT_REFRESH_NEEDED); + break; + } + + default: { + return ScnMdlSimple::GetScnObjOption(option, pValue); + } + } + + return true; +} + +void ScnMdl::InitBuffer() { + ResMdl mdl = GetResMdl(); + + u32 matNum = mdl.GetResMatNumEntries(); + u32 nodeNum = mdl.GetResNodeNumEntries(); + + u32 i; + + if (mReplacement.visArray != NULL) { + for (i = 0; i < nodeNum; i++) { + if (mdl.GetResNode(i).IsVisible()) { + mReplacement.visArray[i] = true; + } else { + mReplacement.visArray[i] = false; + } + } + } + + for (i = 0; i < matNum; i++) { + ResMat mat = mdl.GetResMat(i); + mpMatBufferDirtyFlag[i] = 0; + + if (mReplacement.texObjDataArray != NULL) { + mat.GetResTexObj() + .CopyTo(&mReplacement.texObjDataArray[i]) + .EndEdit(); + } + + if (mReplacement.tlutObjDataArray != NULL) { + mat.GetResTlutObj() + .CopyTo(&mReplacement.tlutObjDataArray[i]) + .EndEdit(); + } + + if (mReplacement.texSrtDataArray != NULL) { + mat.GetResTexSrt() + .CopyTo(&mReplacement.texSrtDataArray[i]) + .EndEdit(); + } + + if (mReplacement.chanDataArray != NULL) { + mat.GetResMatChan() + .CopyTo(&mReplacement.chanDataArray[i]) + .EndEdit(); + } + + if (mReplacement.genModeDataArray != NULL) { + mat.GetResGenMode() + .CopyTo(&mReplacement.genModeDataArray[i]) + .EndEdit(); + } + + if (mReplacement.matMiscDataArray != NULL) { + mat.GetResMatMisc() + .CopyTo(&mReplacement.matMiscDataArray[i]) + .EndEdit(); + } + + if (mReplacement.pixDLArray != NULL) { + mat.GetResMatPix().CopyTo(&mReplacement.pixDLArray[i]).EndEdit(); + } + + if (mReplacement.tevColorDLArray != NULL) { + mat.GetResMatTevColor() + .CopyTo(&mReplacement.tevColorDLArray[i]) + .EndEdit(); + } + + if (mReplacement.indMtxAndScaleDLArray != NULL) { + mat.GetResMatIndMtxAndScale() + .CopyTo(&mReplacement.indMtxAndScaleDLArray[i]) + .EndEdit(); + } + + if (mReplacement.texCoordGenDLArray != NULL) { + mat.GetResMatTexCoordGen() + .CopyTo(&mReplacement.texCoordGenDLArray[i]) + .EndEdit(); + } + + if (mReplacement.tevDataArray != NULL) { + mat.GetResTev().CopyTo(&mReplacement.tevDataArray[i]).EndEdit(); + } + } +} + +void ScnMdl::CleanMatBuffer(u32 idx, u32 option) { + ResMat mat = GetResMdl().GetResMat(idx); + + if ((option & BUFOPTION_TEXOBJ) && mReplacement.texObjDataArray != NULL) { + mat.GetResTexObj().CopyTo(&mReplacement.texObjDataArray[idx]).EndEdit(); + } + + if ((option & BUFOPTION_TLUTOBJ) && mReplacement.tlutObjDataArray != NULL) { + mat.GetResTlutObj().CopyTo(&mReplacement.tlutObjDataArray[idx]).EndEdit(); + } + + if ((option & BUFOPTION_TEXSRT) && mReplacement.texSrtDataArray != NULL) { + mat.GetResTexSrt().CopyTo(&mReplacement.texSrtDataArray[idx]).EndEdit(); + } + + if ((option & BUFOPTION_MATCHAN) && mReplacement.chanDataArray != NULL) { + mat.GetResMatChan().CopyTo(&mReplacement.chanDataArray[idx]).EndEdit(); + } + + if ((option & BUFOPTION_GENMODE) && mReplacement.genModeDataArray != NULL) { + mat.GetResGenMode().CopyTo(&mReplacement.genModeDataArray[idx]).EndEdit(); + } + + if ((option & BUFOPTION_MATMISC) && mReplacement.matMiscDataArray != NULL) { + mat.GetResMatMisc().CopyTo(&mReplacement.matMiscDataArray[idx]).EndEdit(); + } + + if ((option & BUFOPTION_MATPIX) && mReplacement.pixDLArray != NULL) { + mat.GetResMatPix().CopyTo(&mReplacement.pixDLArray[idx]).EndEdit(); + } + + if ((option & BUFOPTION_MATTEVCOLOR) && + mReplacement.tevColorDLArray != NULL) { + + mat.GetResMatTevColor() + .CopyTo(&mReplacement.tevColorDLArray[idx]) + .EndEdit(); + } + + if ((option & BUFOPTION_MATINDMTXSCALE) && + mReplacement.indMtxAndScaleDLArray != NULL) { + + mat.GetResMatIndMtxAndScale() + .CopyTo(&mReplacement.indMtxAndScaleDLArray[idx]) + .EndEdit(); + } + + if ((option & BUFOPTION_MATTEXCOORDGEN) && + mReplacement.texCoordGenDLArray != NULL) { + + mat.GetResMatTexCoordGen() + .CopyTo(&mReplacement.texCoordGenDLArray[idx]) + .EndEdit(); + } + + if ((option & BUFOPTION_TEV) && mReplacement.tevDataArray != NULL) { + mat.GetResTev().CopyTo(&mReplacement.tevDataArray[idx]).EndEdit(); + } + + mpMatBufferDirtyFlag[idx] = mpMatBufferDirtyFlag[idx] & ~option; +} + +void ScnMdl::CleanVisBuffer() { + ResMdl mdl = GetResMdl(); + u32 nodeNum = mdl.GetResNodeNumEntries(); + + if (mReplacement.visArray != NULL) { + for (u32 i = 0; i < nodeNum; i++) { + if (mdl.GetResNode(i).IsVisible()) { + mReplacement.visArray[i] = true; + } else { + mReplacement.visArray[i] = false; + } + } + } + + mFlagVisBuffer &= ~VISBUFFER_DIRTY; +} + +bool ScnMdl::SetAnmObj(AnmObj* pObj, AnmObjType type) { + if (pObj != NULL && pObj->GetParent() == NULL) { + if (type == ANMOBJTYPE_SHP || type == ANMOBJTYPE_NOT_SPECIFIED) { + AnmObjShp* pShp = DynamicCast(pObj); + + if (pShp != NULL) { + if (!pShp->IsBound()) { + return false; + } + + if (mpAnmObjShp != NULL) { + RemoveAnmObj(mpAnmObjShp); + } + + mpAnmObjShp = pShp; + pShp->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + + return true; + } else { + if (type == ANMOBJTYPE_NOT_SPECIFIED) { + return ScnMdlSimple::SetAnmObj(pObj, type); + } + + return false; + } + } else { + return ScnMdlSimple::SetAnmObj(pObj, type); + } + } + + return false; +} + +bool ScnMdl::RemoveAnmObj(AnmObj* pObj) { + if (pObj == NULL) { + return NULL; + } + + if (pObj == mpAnmObjShp) { + mpAnmObjShp->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpAnmObjShp = NULL; + + if (mReplacement.vtxPosTable != NULL) { + u32 vtxPosNum = GetResMdl().GetResVtxPosNumEntries(); + + for (u32 i = 0; i < vtxPosNum; i++) { + ResVtxPos pos = GetResMdl().GetResVtxPos(i); + + if (pos.ptr() != mReplacement.vtxPosTable[i]) { + pos.CopyTo(mReplacement.vtxPosTable[i]); + } + } + } + + if (mReplacement.vtxNrmTable != NULL) { + u32 vtxNrmNum = GetResMdl().GetResVtxNrmNumEntries(); + + for (u32 i = 0; i < vtxNrmNum; i++) { + ResVtxNrm nrm = GetResMdl().GetResVtxNrm(i); + + if (nrm.ptr() != mReplacement.vtxNrmTable[i]) { + nrm.CopyTo(mReplacement.vtxNrmTable[i]); + } + } + } + + if (mReplacement.vtxClrTable != NULL) { + u32 vtxClrNum = GetResMdl().GetResVtxClrNumEntries(); + + for (u32 i = 0; i < vtxClrNum; i++) { + ResVtxClr clr = GetResMdl().GetResVtxClr(i); + + if (clr.ptr() != mReplacement.vtxClrTable[i]) { + clr.CopyTo(mReplacement.vtxClrTable[i]); + } + } + } + + return true; + } + + return ScnMdlSimple::RemoveAnmObj(pObj); +} + +AnmObj* ScnMdl::RemoveAnmObj(AnmObjType type) { + if (type == ANMOBJTYPE_SHP) { + AnmObj* pOld = mpAnmObjShp; + RemoveAnmObj(mpAnmObjShp); + return pOld; + } + + return ScnMdlSimple::RemoveAnmObj(type); +} + +AnmObj* ScnMdl::GetAnmObj(AnmObjType type) { + if (type == ANMOBJTYPE_SHP) { + return mpAnmObjShp; + } + + return ScnMdlSimple::GetAnmObj(type); +} + +const AnmObj* ScnMdl::GetAnmObj(AnmObjType type) const { + if (type == ANMOBJTYPE_SHP) { + return mpAnmObjShp; + } + + return ScnMdlSimple::GetAnmObj(type); +} + +ScnMdl::ScnMdl(MEMAllocator* pAllocator, ResMdl mdl, + math::MTX34* pWorldMtxArray, u32* pWorldMtxAttribArray, + math::MTX34* pViewPosMtxArray, math::MTX33* pViewNrmMtxArray, + math::MTX34* pViewTexMtxArray, int numView, int numViewMtx, + DrawResMdlReplacement* pReplacement, u32* pMatBufferDirtyFlag) + : ScnMdlSimple(pAllocator, mdl, pWorldMtxArray, pWorldMtxAttribArray, + pViewPosMtxArray, pViewNrmMtxArray, pViewTexMtxArray, + numView, numViewMtx), + mpAnmObjShp(NULL), + mFlagVisBuffer(NULL), + mpMatBufferDirtyFlag(pMatBufferDirtyFlag), + mReplacement(*pReplacement) {} + +ScnMdl::~ScnMdl() { + if (mpAnmObjShp != NULL) { + RemoveAnmObj(mpAnmObjShp); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_scnmdl1mat1shp.cpp b/src/nw4r/g3d/g3d_scnmdl1mat1shp.cpp new file mode 100644 index 00000000..225f9a01 --- /dev/null +++ b/src/nw4r/g3d/g3d_scnmdl1mat1shp.cpp @@ -0,0 +1,9 @@ +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(ScnMdl1Mat1Shp); + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_scnmdlsmpl.cpp b/src/nw4r/g3d/g3d_scnmdlsmpl.cpp new file mode 100644 index 00000000..105825b9 --- /dev/null +++ b/src/nw4r/g3d/g3d_scnmdlsmpl.cpp @@ -0,0 +1,897 @@ +#include + +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(ScnMdlSimple); + +ScnMdlSimple* ScnMdlSimple::Construct(MEMAllocator* pAllocator, u32* pSize, + ResMdl mdl, int numView) { + if (!mdl.IsValid()) { + return NULL; + } + + if (numView == 0) { + numView = 1; + } else if (numView > VIEW_MAX) { + numView = VIEW_MAX; + } + + ScnMdlSimple* pSimple = NULL; + u32 simpleSize = sizeof(ScnMdlSimple); + + u32 posNrmMtxNum = mdl.GetResMdlInfo().GetNumPosNrmMtx(); + u32 viewMtxNum = mdl.GetResMdlInfo().GetNumViewMtx(); + + u32 worldMtxSize = posNrmMtxNum * sizeof(math::MTX34); + u32 worldAttrSize = posNrmMtxNum * sizeof(u32); + + u32 viewPosTexMtxSizeUnit = viewMtxNum * (sizeof(math::MTX34)); + u32 viewNrmMtxSizeUnit = viewMtxNum * (sizeof(math::MTX33)); + + u32 viewPosMtxSize = numView * align32(viewPosTexMtxSizeUnit); + + u32 viewNrmMtxSize = mdl.GetResMdlInfo().ref().need_nrm_mtx_array + ? numView * align32(viewNrmMtxSizeUnit) + : 0; + + // TODO: Fakematch + u32 viewTexMtxSize = mdl.ref().info.need_tex_mtx_array + ? numView * align32(viewPosTexMtxSizeUnit) + : 0; + + u32 worldMtxOfs = align32(simpleSize); + u32 worldAttrOfs = align32(worldMtxOfs + worldMtxSize); + u32 viewPosMtxOfs = align32(worldAttrOfs + worldAttrSize); + u32 viewNrmMtxOfs = align32(viewPosMtxOfs + viewPosMtxSize); + u32 viewTexMtxOfs = align32(viewNrmMtxOfs + viewNrmMtxSize); + + u32 size = align32(viewTexMtxOfs + viewTexMtxSize); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator != NULL) { + u8* pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + // clang-format off + pSimple = new (pBuffer) ScnMdlSimple( + pAllocator, + mdl, + reinterpret_cast(pBuffer + worldMtxOfs), + reinterpret_cast(pBuffer + worldAttrOfs), + reinterpret_cast(pBuffer + viewPosMtxOfs), + viewNrmMtxSize != 0 ? reinterpret_cast(pBuffer + viewNrmMtxOfs) : NULL, + viewTexMtxSize != 0 ? reinterpret_cast(pBuffer + viewTexMtxOfs) : NULL, + numView, + viewMtxNum); + // clang-format on + } + + return pSimple; +} + +void ScnMdlSimple::ScnMdlSmpl_CalcPosture(u32 param, + const math::MTX34* pParent) { + CheckCallback_CALC_WORLD(CALLBACK_TIMING_A, param, + const_cast(pParent)); + + CalcWorldMtx(pParent, ¶m); + + CheckCallback_CALC_WORLD(CALLBACK_TIMING_B, param, + const_cast(pParent)); + + u32 mtxNum = GetResMdl().GetResMdlInfo().GetNumPosNrmMtx(); + math::MTX34* pWorldMtxArray; + bool locked = false; + + if (mtxNum > MTX_CACHE_MIN && mtxNum < MTX_CACHE_MAX && + (locked = ut::LC::Lock()) == true) { + + mFlagScnMdlSimple |= SCNMDLSMPLFLAG_LC_DMA; + DC::InvalidateRange(GetWldMtxArray(), mtxNum * sizeof(math::MTX34)); + pWorldMtxArray = static_cast(ut::LC::GetBase()); + } else { + mFlagScnMdlSimple &= ~SCNMDLSMPLFLAG_LC_DMA; + pWorldMtxArray = GetWldMtxArray(); + } + + ScaleProperty property = GetScaleProperty(); + u32 rootAttr = detail::WorldMtxAttr::GetRootMtxAttr(); + + u32 ignoreTrans; + GetScnObjOption(OPTION_IGNORE_ANMCHR_TRANS, &ignoreTrans); + + if (property == UNIFORM_SCALED) { + rootAttr = detail::WorldMtxAttr::AnmNotScaleOne(rootAttr); + } else if (property == NONUNIFORM_SCALED) { + rootAttr = detail::WorldMtxAttr::AnmNotScaleUniform(rootAttr); + } + + if (ignoreTrans) { + rootAttr = detail::WorldMtxAttr::AnmIgnoreTrans(rootAttr); + } + + if (GetScnMdlCallback() != NULL) { + FuncObjCalcWorld funcObj(GetScnMdlCallback(), GetScnMdlCallbackTiming(), + GetScnMdlCallbackNodeID()); + + CalcWorld(pWorldMtxArray, GetWldMtxAttribArray(), GetByteCodeCalc(), + GetMtxPtr(MTX_WORLD), GetResMdl(), GetAnmObjChr(), &funcObj, + rootAttr); + } else { + CalcWorld(pWorldMtxArray, GetWldMtxAttribArray(), GetByteCodeCalc(), + GetMtxPtr(MTX_WORLD), GetResMdl(), GetAnmObjChr(), NULL, + rootAttr); + } + + if (GetByteCodeMix() != NULL) { + CalcSkinning(pWorldMtxArray, GetWldMtxAttribArray(), GetResMdl(), + GetByteCodeMix()); + } + + if (locked) { + ut::LC::StoreData(GetWldMtxArray(), ut::LC::GetBase(), + mtxNum * sizeof(math::MTX34)); + + ut::LC::Unlock(); + } +} + +void ScnMdlSimple::ScnMdlSmpl_G3DPROC_GATHER_SCNOBJ( + u32 param, IScnObjGather* pCollection) { +#pragma unused(param) + + pCollection->Add(this, !TestScnObjFlag(SCNOBJFLAG_NOT_GATHER_DRAW_OPA), + !TestScnObjFlag(SCNOBJFLAG_NOT_GATHER_DRAW_XLU)); +} + +void ScnMdlSimple::ScnMdlSmpl_G3DPROC_CALC_WORLD(u32 param, + const math::MTX34* pParent) { + ScnMdlSmpl_CalcPosture(param, pParent); + + if (GetAnmObjVis() != NULL) { + ApplyVisAnmResult(GetResMdl(), GetAnmObjVis()); + } + + CheckCallback_CALC_WORLD(CALLBACK_TIMING_C, param, + const_cast(pParent)); +} + +void ScnMdlSimple::ScnMdlSmpl_G3DPROC_CALC_MAT(u32 param, void* pInfo) { + CheckCallback_CALC_MAT(CALLBACK_TIMING_A, param, pInfo); + + if (GetAnmObjTexPat() != NULL || GetAnmObjTexSrt() != NULL || + GetAnmObjMatClr() != NULL) { + + CalcMaterialDirectly(GetResMdl(), GetAnmObjTexPat(), GetAnmObjTexSrt(), + GetAnmObjMatClr()); + } + + CheckCallback_CALC_MAT(CALLBACK_TIMING_C, param, pInfo); +} + +void ScnMdlSimple::ScnMdlSmpl_G3DPROC_CALC_VIEW(u32 param, + const math::MTX34* pCamera) { + mCurView = (mCurView + 1) % mNumView; + + CheckCallback_CALC_VIEW(CALLBACK_TIMING_A, param, + const_cast(pCamera)); + + CalcViewMtx(pCamera); + + CheckCallback_CALC_VIEW(CALLBACK_TIMING_B, param, + const_cast(pCamera)); + + if (ut::LC::Lock()) { + if (mFlagScnMdlSimple & SCNMDLSMPLFLAG_LC_DMA) { + DC::StoreRange(GetWldMtxArray(), + GetNumViewMtx() * sizeof(math::MTX34)); + + CalcView_LC_DMA_ModelMtx(GetViewPosMtxArray(), GetViewNrmMtxArray(), + GetWldMtxArray(), GetWldMtxAttribArray(), + GetNumViewMtx(), pCamera, GetResMdl(), + GetViewTexMtxArray()); + } else { + CalcView_LC(GetViewPosMtxArray(), GetViewNrmMtxArray(), + GetWldMtxArray(), GetWldMtxAttribArray(), + GetNumViewMtx(), pCamera, GetResMdl(), + GetViewTexMtxArray()); + } + + ut::LC::Unlock(); + } else { + CalcView(GetViewPosMtxArray(), GetViewNrmMtxArray(), GetWldMtxArray(), + GetWldMtxAttribArray(), GetNumViewMtx(), pCamera, GetResMdl(), + GetViewTexMtxArray()); + } + + CheckCallback_CALC_VIEW(CALLBACK_TIMING_C, param, + const_cast(pCamera)); +} + +void ScnMdlSimple::ScnMdlSmpl_G3DPROC_DRAW_OPA(u32 param, void* pInfo) { + CheckCallback_DRAW_OPA(CALLBACK_TIMING_A, param, pInfo); + + u32 drawMode = pInfo != NULL ? *static_cast(pInfo) : GetDrawMode(); + + DrawResMdlDirectly(GetResMdl(), GetViewPosMtxArray(), GetViewNrmMtxArray(), + GetViewTexMtxArray(), GetByteCodeDrawOpa(), NULL, NULL, + drawMode); + + CheckCallback_DRAW_OPA(CALLBACK_TIMING_C, param, pInfo); +} + +void ScnMdlSimple::ScnMdlSmpl_G3DPROC_DRAW_XLU(u32 param, void* pInfo) { + CheckCallback_DRAW_XLU(CALLBACK_TIMING_A, param, pInfo); + + u32 drawMode = pInfo != NULL ? *static_cast(pInfo) : GetDrawMode(); + + DrawResMdlDirectly(GetResMdl(), GetViewPosMtxArray(), GetViewNrmMtxArray(), + GetViewTexMtxArray(), NULL, GetByteCodeDrawXlu(), NULL, + drawMode); + + CheckCallback_DRAW_XLU(CALLBACK_TIMING_C, param, pInfo); +} + +void ScnMdlSimple::G3dProc(u32 task, u32 param, void* pInfo) { + if (IsG3dProcDisabled(task)) { + return; + } + + switch (task) { + case G3DPROC_GATHER_SCNOBJ: { + ScnMdlSmpl_G3DPROC_GATHER_SCNOBJ(param, + static_cast(pInfo)); + break; + } + + case G3DPROC_CALC_WORLD: { + ScnMdlSmpl_G3DPROC_CALC_WORLD(param, static_cast(pInfo)); + break; + } + + case G3DPROC_CALC_MAT: { + ScnMdlSmpl_G3DPROC_CALC_MAT(param, pInfo); + break; + } + + case G3DPROC_CALC_VIEW: { + ScnMdlSmpl_G3DPROC_CALC_VIEW(param, static_cast(pInfo)); + break; + } + + case G3DPROC_DRAW_OPA: { + ScnMdlSmpl_G3DPROC_DRAW_OPA(param, pInfo); + break; + } + + case G3DPROC_DRAW_XLU: { + ScnMdlSmpl_G3DPROC_DRAW_XLU(param, pInfo); + break; + } + + case G3DPROC_UPDATEFRAME: { + ScnMdlSmpl_G3DPROC_UPDATEFRAME(param, pInfo); + break; + } + + case G3DPROC_CHILD_DETACHED: { + RemoveAnmObj(static_cast(pInfo)); + break; + } + + default: { + DefG3dProcScnLeaf(task, param, pInfo); + break; + } + } +} + +bool ScnMdlSimple::SetScnObjOption(u32 option, u32 value) { + switch (option) { + case OPTION_IGNORE_ANMCHR_TRANS: { + SetScnObjFlag(SCNOBJFLAG_IGNORE_ANMCHR_TRANS, value); + break; + } + + default: { + return ScnLeaf::SetScnObjOption(option, value); + } + } + + return true; +} + +bool ScnMdlSimple::GetScnObjOption(u32 option, u32* pValue) const { + if (pValue == NULL) { + return false; + } + + switch (option) { + case OPTION_IGNORE_ANMCHR_TRANS: { + *pValue = TestScnObjFlag(SCNOBJFLAG_IGNORE_ANMCHR_TRANS); + break; + } + + default: { + return ScnLeaf::GetScnObjOption(option, pValue); + } + } + + return true; +} + +bool ScnMdlSimple::GetScnMtxPos(math::MTX34* pMtx, ScnObjMtxType type, + u32 idx) const { + if (pMtx != NULL) { + ResNode node = GetResMdl().GetResNode(idx); + + if (node.IsValid()) { + s32 id = node.GetMtxID(); + + switch (type) { + case MTX_WORLD: { + math::MTX34Copy(pMtx, &mpWorldMtxArray[id]); + return true; + } + + case MTX_VIEW: { + if (id < GetResMdl().GetResMdlInfo().GetNumViewMtx()) { + math::MTX34Copy(pMtx, &GetViewPosMtxArray()[id]); + return true; + } + + const math::MTX34* pWorld = GetMtxPtr(MTX_WORLD); + const math::MTX34* pView = GetMtxPtr(MTX_VIEW); + + math::MTX34 work0; + math::MTX34 work1; + + if (math::MTX34Inv(&work0, pWorld) != FALSE) { + math::MTX34Mult(&work1, pView, &work0); + math::MTX34Mult(pMtx, &work1, &mpWorldMtxArray[id]); + return true; + } + } + + default: { + break; + } + } + } + } + + return false; +} + +bool ScnMdlSimple::SetAnmObj(AnmObj* pObj, AnmObjType type) { + if (pObj == NULL || pObj->GetParent() != NULL) { + return false; + } + + AnmObjChr* pChr = NULL; + AnmObjVis* pVis = NULL; + AnmObjMatClr* pClr = NULL; + AnmObjTexPat* pPat = NULL; + AnmObjTexSrt* pSrt = NULL; + + switch (type) { + case ANMOBJTYPE_CHR: { + if ((pChr = DynamicCast(pObj)) != NULL) { + goto _type_chr; + } + + goto _bad_cast; + } + + case ANMOBJTYPE_VIS: { + if ((pVis = DynamicCast(pObj)) != NULL) { + goto _type_vis; + } + + goto _bad_cast; + } + + case ANMOBJTYPE_MATCLR: { + if ((pClr = DynamicCast(pObj)) != NULL) { + goto _type_clr; + } + + goto _bad_cast; + } + + case ANMOBJTYPE_TEXPAT: { + if ((pPat = DynamicCast(pObj)) != NULL) { + goto _type_pat; + } + + goto _bad_cast; + } + + case ANMOBJTYPE_TEXSRT: { + if ((pSrt = DynamicCast(pObj)) != NULL) { + goto _type_srt; + } + + goto _bad_cast; + } + + case ANMOBJTYPE_NOT_SPECIFIED: { + if ((pChr = DynamicCast(pObj)) != NULL) { + goto _type_chr; + } + if ((pVis = DynamicCast(pObj)) != NULL) { + goto _type_vis; + } + if ((pClr = DynamicCast(pObj)) != NULL) { + goto _type_clr; + } + if ((pPat = DynamicCast(pObj)) != NULL) { + goto _type_pat; + } + if ((pSrt = DynamicCast(pObj)) != NULL) { + goto _type_srt; + } + + // FALLTHROUGH + } + + _bad_cast: + case ANMOBJTYPE_SHP: + default: { + return false; + } + } + +_type_chr: + if (!pChr->IsBound()) { + return false; + } + + if (mpAnmObjChr != NULL) { + RemoveAnmObj(mpAnmObjChr); + } + + mpAnmObjChr = pChr; + pChr->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + return true; + +_type_vis: + if (!pVis->IsBound()) { + return false; + } + + if (mpAnmObjVis != NULL) { + RemoveAnmObj(mpAnmObjVis); + } + + mpAnmObjVis = pVis; + pVis->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + return true; + +_type_clr: + if (!pClr->IsBound()) { + return false; + } + + if (mpAnmObjMatClr != NULL) { + RemoveAnmObj(mpAnmObjMatClr); + } + + mpAnmObjMatClr = pClr; + pClr->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + return true; + +_type_pat: + if (!pPat->IsBound()) { + return false; + } + + if (mpAnmObjTexPat != NULL) { + RemoveAnmObj(mpAnmObjTexPat); + } + + mpAnmObjTexPat = pPat; + pPat->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + return true; + +_type_srt: + if (!pSrt->IsBound()) { + return false; + } + + if (mpAnmObjTexSrt != NULL) { + RemoveAnmObj(mpAnmObjTexSrt); + } + + mpAnmObjTexSrt = pSrt; + pSrt->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + return true; +} + +bool ScnMdlSimple::RemoveAnmObj(AnmObj* pObj) { + if (pObj == NULL) { + return false; + } + + if (pObj == mpAnmObjChr) { + mpAnmObjChr->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpAnmObjChr = NULL; + return true; + } + + if (pObj == mpAnmObjVis) { + mpAnmObjVis->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpAnmObjVis = NULL; + return true; + } + + if (pObj == mpAnmObjMatClr) { + mpAnmObjMatClr->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpAnmObjMatClr = NULL; + return true; + } + + if (pObj == mpAnmObjTexPat) { + mpAnmObjTexPat->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpAnmObjTexPat = NULL; + return true; + } + + if (pObj == mpAnmObjTexSrt) { + mpAnmObjTexSrt->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpAnmObjTexSrt = NULL; + return true; + } + + return false; +} + +AnmObj* ScnMdlSimple::RemoveAnmObj(AnmObjType type) { + AnmObj* pObj = NULL; + + switch (type) { + case ANMOBJTYPE_CHR: { + pObj = mpAnmObjChr; + RemoveAnmObj(mpAnmObjChr); + break; + } + + case ANMOBJTYPE_VIS: { + pObj = mpAnmObjVis; + RemoveAnmObj(mpAnmObjVis); + break; + } + + case ANMOBJTYPE_MATCLR: { + pObj = mpAnmObjMatClr; + RemoveAnmObj(mpAnmObjMatClr); + break; + } + + case ANMOBJTYPE_TEXPAT: { + pObj = mpAnmObjTexPat; + RemoveAnmObj(mpAnmObjTexPat); + break; + } + + case ANMOBJTYPE_TEXSRT: { + pObj = mpAnmObjTexSrt; + RemoveAnmObj(mpAnmObjTexSrt); + break; + } + + case ANMOBJTYPE_SHP: + case ANMOBJTYPE_NOT_SPECIFIED: + default: { + break; + } + } + + return pObj; +} + +AnmObj* ScnMdlSimple::GetAnmObj(AnmObjType type) { + switch (type) { + case ANMOBJTYPE_CHR: { + return mpAnmObjChr; + } + + case ANMOBJTYPE_VIS: { + return mpAnmObjVis; + } + + case ANMOBJTYPE_MATCLR: { + return mpAnmObjMatClr; + } + + case ANMOBJTYPE_TEXPAT: { + return mpAnmObjTexPat; + } + + case ANMOBJTYPE_TEXSRT: { + return mpAnmObjTexSrt; + } + + case ANMOBJTYPE_SHP: + case ANMOBJTYPE_NOT_SPECIFIED: + default: { + return NULL; + } + } +} + +const AnmObj* ScnMdlSimple::GetAnmObj(AnmObjType type) const { + switch (type) { + case ANMOBJTYPE_CHR: { + return mpAnmObjChr; + } + + case ANMOBJTYPE_VIS: { + return mpAnmObjVis; + } + + case ANMOBJTYPE_MATCLR: { + return mpAnmObjMatClr; + } + + case ANMOBJTYPE_TEXPAT: { + return mpAnmObjTexPat; + } + + case ANMOBJTYPE_TEXSRT: { + return mpAnmObjTexSrt; + } + + case ANMOBJTYPE_SHP: + case ANMOBJTYPE_NOT_SPECIFIED: + default: { + return NULL; + } + } +} + +void ScnMdlSimple::UpdateFrame() { + if (mpAnmObjChr != NULL) { + mpAnmObjChr->UpdateFrame(); + } + + if (mpAnmObjVis != NULL) { + mpAnmObjVis->UpdateFrame(); + } + + if (mpAnmObjMatClr != NULL) { + mpAnmObjMatClr->UpdateFrame(); + } + + if (mpAnmObjTexPat != NULL) { + mpAnmObjTexPat->UpdateFrame(); + } + + if (mpAnmObjTexSrt != NULL) { + mpAnmObjTexSrt->UpdateFrame(); + } +} + +void ScnMdlSimple::EnableScnMdlCallbackTiming(Timing timing) { + if (timing & CALLBACK_TIMING_A) { + mCwcbTiming |= CALLBACK_TIMING_A; + } + + if (timing & CALLBACK_TIMING_B) { + mCwcbTiming |= CALLBACK_TIMING_B; + } + + if (timing & CALLBACK_TIMING_C) { + mCwcbTiming |= CALLBACK_TIMING_C; + } +} + +void ScnMdlSimple::DisableScnMdlCallbackTiming(Timing timing) { + if (timing & CALLBACK_TIMING_A) { + mCwcbTiming &= ~CALLBACK_TIMING_A; + } + + if (timing & CALLBACK_TIMING_B) { + mCwcbTiming &= ~CALLBACK_TIMING_B; + } + + if (timing & CALLBACK_TIMING_C) { + mCwcbTiming &= ~CALLBACK_TIMING_C; + } +} + +math::MTX34* ScnMdlSimple::GetViewPosMtxArray() { + u8* pBase = reinterpret_cast(mpViewPosMtxArray); + + return reinterpret_cast( + pBase + mCurView * align32(mNumViewMtx * sizeof(math::MTX34))); +} + +const math::MTX34* ScnMdlSimple::GetViewPosMtxArray() const { + u8* pBase = reinterpret_cast(mpViewPosMtxArray); + + return reinterpret_cast( + pBase + mCurView * align32(mNumViewMtx * sizeof(math::MTX34))); +} + +math::MTX33* ScnMdlSimple::GetViewNrmMtxArray() { + if (mpViewNrmMtxArray != NULL) { + u8* pBase = reinterpret_cast(mpViewNrmMtxArray); + + return reinterpret_cast( + pBase + mCurView * align32(mNumViewMtx * sizeof(math::MTX33))); + } + + return NULL; +} + +const math::MTX33* ScnMdlSimple::GetViewNrmMtxArray() const { + if (mpViewNrmMtxArray != NULL) { + u8* pBase = reinterpret_cast(mpViewNrmMtxArray); + + return reinterpret_cast( + pBase + mCurView * align32(mNumViewMtx * sizeof(math::MTX33))); + } + + return NULL; +} + +math::MTX34* ScnMdlSimple::GetViewTexMtxArray() { + if (mpViewTexMtxArray != NULL) { + u8* pBase = reinterpret_cast(mpViewTexMtxArray); + + return reinterpret_cast( + pBase + mCurView * align32(mNumViewMtx * sizeof(math::MTX34))); + } + + return NULL; +} + +const math::MTX34* ScnMdlSimple::GetViewTexMtxArray() const { + if (mpViewTexMtxArray != NULL) { + u8* pBase = reinterpret_cast(mpViewTexMtxArray); + + return reinterpret_cast( + pBase + mCurView * align32(mNumViewMtx * sizeof(math::MTX34))); + } + + return NULL; +} + +const u8* ScnMdlSimple::GetByteCode(ByteCodeType type) const { + switch (type) { + case BYTE_CODE_CALC: { + return mpByteCodeCalc; + } + + case BYTE_CODE_MIX: { + return mpByteCodeMix; + } + + case BYTE_CODE_DRAW_OPA: { + return mpByteCodeDrawOpa; + } + + case BYTE_CODE_DRAW_XLU: { + return mpByteCodeDrawXlu; + } + + default: { + return NULL; + } + } +} + +ScnMdlSimple::ScnMdlSimple(MEMAllocator* pAllocator, ResMdl mdl, + math::MTX34* pWorldMtxArray, + u32* pWorldMtxAttribArray, + math::MTX34* pViewPosMtxArray, + math::MTX33* pViewNrmMtxArray, + math::MTX34* pViewTexMtxArray, int numView, + int numViewMtx) + : ScnLeaf(pAllocator), + mResMdl(mdl), + mpWorldMtxArray(pWorldMtxArray), + mpWorldMtxAttribArray(pWorldMtxAttribArray), + mpViewPosMtxArray(pViewPosMtxArray), + mpViewNrmMtxArray(pViewNrmMtxArray), + mpViewTexMtxArray(pViewTexMtxArray), + mNumView(numView), + mCurView(0), + mNumViewMtx(numViewMtx), + mFlagScnMdlSimple(0), + mpByteCodeCalc(mdl.GetResByteCode("NodeTree")), + mpByteCodeMix(mdl.GetResByteCode("NodeMix")), + mpByteCodeDrawOpa(mdl.GetResByteCode("DrawOpa")), + mpByteCodeDrawXlu(mdl.GetResByteCode("DrawXlu")), + mDrawMode(RESMDL_DRAWMODE_DEFAULT), + mpCalcWorldCallback(NULL), + mCwcbTiming(0), + mCwcbDeleteOption(FALSE), + mCwcbNodeID(0), + mpAnmObjChr(NULL), + mpAnmObjVis(NULL), + mpAnmObjMatClr(NULL), + mpAnmObjTexPat(NULL), + mpAnmObjTexSrt(NULL) { + + if (mpByteCodeDrawOpa != NULL) { + SetScnObjFlag(SCNOBJFLAG_NOT_GATHER_DRAW_OPA, false); + } else { + SetScnObjFlag(SCNOBJFLAG_NOT_GATHER_DRAW_OPA, true); + } + + if (mpByteCodeDrawXlu != NULL) { + SetScnObjFlag(SCNOBJFLAG_NOT_GATHER_DRAW_XLU, false); + } else { + SetScnObjFlag(SCNOBJFLAG_NOT_GATHER_DRAW_XLU, true); + } + + if (mpViewPosMtxArray != NULL) { + DC::InvalidateRange(mpViewPosMtxArray, + numView * + align32(numViewMtx * sizeof(math::MTX34))); + } + + if (mpViewNrmMtxArray != NULL) { + DC::InvalidateRange(mpViewNrmMtxArray, + numView * + align32(numViewMtx * sizeof(math::MTX33))); + } + + if (mpViewTexMtxArray != NULL) { + DC::InvalidateRange(mpViewTexMtxArray, + numView * + align32(numViewMtx * sizeof(math::MTX34))); + } + + if (mdl.GetResMdlInfo().ref().is_valid_volume) { + const math::_VEC3& rMin = mdl.GetResMdlInfo().ref().volume_min; + const math::_VEC3& rMax = mdl.GetResMdlInfo().ref().volume_max; + + math::AABB box; + box.min = static_cast(rMin); + box.max = static_cast(rMax); + + SetBoundingVolume(&box); + } +} + +ScnMdlSimple::~ScnMdlSimple() { + switch (mCwcbDeleteOption) { + case TRUE: { + delete mpCalcWorldCallback; + break; + } + } + + if (mpAnmObjChr != NULL) { + RemoveAnmObj(mpAnmObjChr); + } + + if (mpAnmObjVis != NULL) { + RemoveAnmObj(mpAnmObjVis); + } + + if (mpAnmObjMatClr != NULL) { + RemoveAnmObj(mpAnmObjMatClr); + } + + if (mpAnmObjTexPat != NULL) { + RemoveAnmObj(mpAnmObjTexPat); + } + + if (mpAnmObjTexSrt != NULL) { + RemoveAnmObj(mpAnmObjTexSrt); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_scnobj.cpp b/src/nw4r/g3d/g3d_scnobj.cpp new file mode 100644 index 00000000..f2a15ad2 --- /dev/null +++ b/src/nw4r/g3d/g3d_scnobj.cpp @@ -0,0 +1,666 @@ +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(ScnObj); +NW4R_G3D_RTTI_DEF(ScnLeaf); +NW4R_G3D_RTTI_DEF(ScnGroup); + +const math::FRUSTUM* gpCullingFrustum = NULL; + +/****************************************************************************** + * + * ScnObj + * + ******************************************************************************/ +void ScnObj::CalcWorldMtx(const math::MTX34* pParent, u32* pParam) { + if (pParam != NULL && (*pParam & SCNOBJFLAG_DISABLE_CALC_WORLD)) { + *pParam &= ~SCNOBJFLAG_DISABLE_CALC_WORLD; + return; + } + + if (pParent != NULL) { + if (TestScnObjFlag(SCNOBJFLAG_MTX_LOCAL_IDENTITY)) { + math::MTX34Copy(&mMtxArray[MTX_WORLD], pParent); + } else { + math::MTX34Mult(&mMtxArray[MTX_WORLD], pParent, + &mMtxArray[MTX_LOCAL]); + } + } else { + math::MTX34Copy(&mMtxArray[MTX_WORLD], &mMtxArray[MTX_LOCAL]); + } + + if (TestScnObjFlag(SCNOBJFLAG_ENABLE_CULLING)) { + mAABB[BOUNDINGVOLUME_AABB_WORLD].Set(&mAABB[BOUNDINGVOLUME_AABB_LOCAL], + &mMtxArray[MTX_WORLD]); + } +} + +void ScnObj::CalcViewMtx(const math::MTX34* pCamera) { + math::MTX34Mult(&mMtxArray[MTX_VIEW], pCamera, &mMtxArray[MTX_WORLD]); +} + +ScnObj::ScnObj(MEMAllocator* pAllocator) + : G3dObj(pAllocator, NULL), + mScnObjFlags(0), + mPriorityDrawOpa(128), + mPriorityDrawXlu(128), + PADDING_0xD2(0), + PADDING_0xD3(0), + mpFuncObjExec(NULL), + mCallbackTiming(0), + mCallbackDeleteOption(FALSE), + mCallbackExecOpMask(0) { + + SetScnObjFlag(SCNOBJFLAG_MTX_LOCAL_IDENTITY, TRUE); + + math::MTX34Identity(&mMtxArray[MTX_LOCAL]); + math::MTX34Identity(&mMtxArray[MTX_WORLD]); + math::MTX34Identity(&mMtxArray[MTX_VIEW]); + + mAABB[BOUNDINGVOLUME_AABB_LOCAL].min = math::VEC3(0.0f, 0.0f, 0.0f); + mAABB[BOUNDINGVOLUME_AABB_LOCAL].max = math::VEC3(0.0f, 0.0f, 0.0f); + mAABB[BOUNDINGVOLUME_AABB_WORLD].min = math::VEC3(0.0f, 0.0f, 0.0f); + mAABB[BOUNDINGVOLUME_AABB_WORLD].max = math::VEC3(0.0f, 0.0f, 0.0f); +} + +ScnObj::~ScnObj() { + if (mpFuncObjExec == NULL) { + return; + } + + switch (mCallbackDeleteOption) { + case TRUE: { + delete mpFuncObjExec; + break; + } + } +} + +bool ScnObj::SetScnObjOption(u32 option, u32 value) { + switch (option) { + case OPTION_DISABLE_GATHER_SCNOBJ: { + SetScnObjFlag(SCNOBJFLAG_DISABLE_GATHER_SCNOBJ, value); + break; + } + + case OPTION_DISABLE_CALC_WORLD: { + SetScnObjFlag(SCNOBJFLAG_DISABLE_CALC_WORLD, value); + break; + } + + case OPTION_DISABLE_CALC_MAT: { + SetScnObjFlag(SCNOBJFLAG_DISABLE_CALC_MAT, value); + break; + } + + case OPTION_DISABLE_CALC_VTX: { + SetScnObjFlag(SCNOBJFLAG_DISABLE_CALC_VTX, value); + break; + } + + case OPTION_DISABLE_CALC_VIEW: { + SetScnObjFlag(SCNOBJFLAG_DISABLE_CALC_VIEW, value); + break; + } + + case OPTION_DISABLE_DRAW_OPA: { + SetScnObjFlag(SCNOBJFLAG_DISABLE_DRAW_OPA, value); + break; + } + + case OPTION_DISABLE_DRAW_XLU: { + SetScnObjFlag(SCNOBJFLAG_DISABLE_DRAW_XLU, value); + break; + } + + case OPTION_DISABLE_UPDATEFRAME: { + SetScnObjFlag(SCNOBJFLAG_DISABLE_UPDATEFRAME, value); + break; + } + + case OPTION_ENABLE_CULLING: { + SetScnObjFlag(SCNOBJFLAG_ENABLE_CULLING, value); + break; + } + + default: { + return false; + } + } + + return true; +} + +bool ScnObj::GetScnObjOption(u32 option, u32* pValue) const { + if (pValue == NULL) { + return false; + } + + switch (option) { + case OPTION_DISABLE_GATHER_SCNOBJ: { + *pValue = TestScnObjFlag(SCNOBJFLAG_DISABLE_GATHER_SCNOBJ); + break; + } + + case OPTION_DISABLE_CALC_WORLD: { + *pValue = TestScnObjFlag(SCNOBJFLAG_DISABLE_CALC_WORLD); + break; + } + + case OPTION_DISABLE_CALC_MAT: { + *pValue = TestScnObjFlag(SCNOBJFLAG_DISABLE_CALC_MAT); + break; + } + + case OPTION_DISABLE_CALC_VTX: { + *pValue = TestScnObjFlag(SCNOBJFLAG_DISABLE_CALC_VTX); + break; + } + + case OPTION_DISABLE_CALC_VIEW: { + *pValue = TestScnObjFlag(SCNOBJFLAG_DISABLE_CALC_VIEW); + break; + } + + case OPTION_DISABLE_DRAW_OPA: { + *pValue = TestScnObjFlag(SCNOBJFLAG_DISABLE_DRAW_OPA); + break; + } + + case OPTION_DISABLE_DRAW_XLU: { + *pValue = TestScnObjFlag(SCNOBJFLAG_DISABLE_DRAW_XLU); + break; + } + + case OPTION_DISABLE_UPDATEFRAME: { + *pValue = TestScnObjFlag(SCNOBJFLAG_DISABLE_UPDATEFRAME); + break; + } + + case OPTION_ENABLE_CULLING: { + *pValue = TestScnObjFlag(SCNOBJFLAG_ENABLE_CULLING); + break; + } + + default: { + return false; + } + } + + return true; +} + +bool ScnObj::SetMtx(ScnObjMtxType type, const math::MTX34* pMtx) { + if (static_cast(type) < MTX_TYPE_MAX) { + if (pMtx != NULL) { + if (type == MTX_LOCAL) { + SetScnObjFlag(SCNOBJFLAG_MTX_LOCAL_IDENTITY, FALSE); + } + + math::MTX34Copy(&mMtxArray[type], pMtx); + } else { + if (type == MTX_LOCAL) { + SetScnObjFlag(SCNOBJFLAG_MTX_LOCAL_IDENTITY, TRUE); + } + + math::MTX34Identity(&mMtxArray[type]); + } + + return true; + } + + return false; +} + +bool ScnObj::GetMtx(ScnObjMtxType type, math::MTX34* pMtx) const { + if (pMtx != NULL && static_cast(type) < MTX_TYPE_MAX) { + math::MTX34Copy(pMtx, &mMtxArray[type]); + return true; + } + + return false; +} + +f32 ScnObj::GetValueForSortOpa() const { + return -mMtxArray[MTX_VIEW]._23; +} + +f32 ScnObj::GetValueForSortXlu() const { + return mMtxArray[MTX_VIEW]._23; +} + +void ScnObj::SetPriorityDrawOpa(int prio) { + if (prio < 0) { + prio = 0; + } else if (prio > 255) { + prio = 255; + } + + mPriorityDrawOpa = prio; +} + +void ScnObj::SetPriorityDrawXlu(int prio) { + if (prio < 0) { + prio = 0; + } else if (prio > 255) { + prio = 255; + } + + mPriorityDrawXlu = prio; +} + +void ScnObj::EnableScnObjCallbackTiming(Timing timing) { + if (timing & CALLBACK_TIMING_A) { + mCallbackTiming |= CALLBACK_TIMING_A; + } + + if (timing & CALLBACK_TIMING_B) { + mCallbackTiming |= CALLBACK_TIMING_B; + } + + if (timing & CALLBACK_TIMING_C) { + mCallbackTiming |= CALLBACK_TIMING_C; + } +} + +void ScnObj::EnableScnObjCallbackExecOp(ExecOp op) { + mCallbackExecOpMask |= static_cast(op); +} + +bool ScnObj::SetBoundingVolume(ScnObjBoundingVolumeType type, + const math::AABB* pAABB) { + if (pAABB != NULL) { + if (type < BOUNDINGVOLUME_MAX) { + mAABB[type] = *pAABB; + return SetScnObjOption(OPTION_ENABLE_CULLING, TRUE); + } + + return false; + } + + return SetScnObjOption(OPTION_ENABLE_CULLING, FALSE); +} + +bool ScnObj::GetBoundingVolume(ScnObjBoundingVolumeType type, + math::AABB* pAABB) const { + if (pAABB != NULL) { + if (type < BOUNDINGVOLUME_MAX) { + *pAABB = mAABB[type]; + return true; + } + + return false; + } + + return false; +} + +/****************************************************************************** + * + * ScnLeaf + * + ******************************************************************************/ +ScnObj::ForEachResult ScnLeaf::ForEach(ForEachFunc pFunc, void* pInfo, + bool postOrder) { +#pragma unused(postOrder) + + return pFunc(this, pInfo) != FOREACHRESULT_CONTINUE + ? FOREACHRESULT_OK + : FOREACHRESULT_CONTINUE; +} + +bool ScnLeaf::SetScnObjOption(u32 option, u32 value) { + switch (option) { + case OPTION_DISABLE_DRAW_ALL: { + SetScnObjFlag(SCNOBJFLAG_DISABLE_DRAW, value); + break; + } + + default: { + return ScnObj::SetScnObjOption(option, value); + } + } + + return true; +} + +bool ScnLeaf::GetScnObjOption(u32 option, u32* pValue) const { + if (pValue == NULL) { + return false; + } + + switch (option) { + case OPTION_DISABLE_DRAW_ALL: { + *pValue = TestScnObjFlag(SCNOBJFLAG_DISABLE_DRAW); + break; + } + + default: { + return ScnObj::GetScnObjOption(option, pValue); + } + } + + return true; +} + +void ScnLeaf::CalcWorldMtx(const math::MTX34* pParent, u32* pParam) { + if (pParam != NULL && (*pParam & SCNOBJFLAG_DISABLE_CALC_WORLD)) { + *pParam &= ~SCNOBJFLAG_DISABLE_CALC_WORLD; + return; + } + + ScnObj::CalcWorldMtx(pParent, pParam); + math::MTX34Scale(&mMtxArray[MTX_WORLD], &mMtxArray[MTX_WORLD], &mScale); + + if (TestScnObjFlag(SCNOBJFLAG_ENABLE_CULLING)) { + mAABB[BOUNDINGVOLUME_AABB_WORLD].Set(&mAABB[BOUNDINGVOLUME_AABB_LOCAL], + &mMtxArray[MTX_WORLD]); + } +} + +ScnLeaf::ScaleProperty ScnLeaf::GetScaleProperty() const { + if (mScale.x == mScale.y) { + if (mScale.y == mScale.z) { + if (mScale.x == 1.0f) { + return NOT_SCALED; + } + + return UNIFORM_SCALED; + } + } + + return NONUNIFORM_SCALED; +} + +void ScnLeaf::DefG3dProcScnLeaf(u32 task, u32 param, void* pInfo) { + switch (task) { + case G3DPROC_CALC_WORLD: { + CheckCallback_CALC_WORLD(CALLBACK_TIMING_A, param, pInfo); + CalcWorldMtx(static_cast(pInfo), ¶m); + CheckCallback_CALC_WORLD(CALLBACK_TIMING_B, param, pInfo); + CheckCallback_CALC_WORLD(CALLBACK_TIMING_C, param, pInfo); + break; + } + + case G3DPROC_CALC_MAT: { + CheckCallback_CALC_MAT(CALLBACK_TIMING_A, param, pInfo); + CheckCallback_CALC_MAT(CALLBACK_TIMING_C, param, pInfo); + break; + } + + case G3DPROC_CALC_VIEW: { + CheckCallback_CALC_VIEW(CALLBACK_TIMING_A, param, pInfo); + CalcViewMtx(static_cast(pInfo)); + CheckCallback_CALC_VIEW(CALLBACK_TIMING_B, param, pInfo); + CheckCallback_CALC_VIEW(CALLBACK_TIMING_C, param, pInfo); + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + + case G3DPROC_GATHER_SCNOBJ: + case G3DPROC_DRAW_OPA: + case G3DPROC_DRAW_XLU: + case G3DPROC_UPDATEFRAME: + case G3DPROC_CHILD_DETACHED: + case G3DPROC_ZSORT: { + break; + } + } +} + +/****************************************************************************** + * + * ScnGroup + * + ******************************************************************************/ +ScnObj::ForEachResult ScnGroup::ForEach(ForEachFunc pFunc, void* pInfo, + bool postOrder) { + ForEachResult result; + + if (postOrder) { + for (u32 i = 0; i < Size(); i++) { + result = mpScnObjArray[i]->ForEach(pFunc, pInfo, false); + + if (result == FOREACHRESULT_CONTINUE) { + return FOREACHRESULT_CONTINUE; + } + } + + result = pFunc(this, pInfo); + return result == FOREACHRESULT_CONTINUE ? FOREACHRESULT_CONTINUE + : FOREACHRESULT_OK; + } else { + result = pFunc(this, pInfo); + + if (result == FOREACHRESULT_OK) { + for (u32 i = 0; i < Size(); i++) { + result = mpScnObjArray[i]->ForEach(pFunc, pInfo, false); + + if (result == FOREACHRESULT_CONTINUE) { + return FOREACHRESULT_CONTINUE; + } + } + + return FOREACHRESULT_OK; + } + + return result == FOREACHRESULT_CONTINUE ? FOREACHRESULT_CONTINUE + : FOREACHRESULT_OK; + } +} + +void ScnGroup::ScnGroup_G3DPROC_GATHER_SCNOBJ(u32 param, + IScnObjGather* pCollection) { + IScnObjGather::CullingStatus status = + pCollection->Add(this, !TestScnObjFlag(SCNOBJFLAG_NOT_GATHER_DRAW_OPA), + !TestScnObjFlag(SCNOBJFLAG_NOT_GATHER_DRAW_XLU)); + + if (status == IScnObjGather::CULLINGSTATUS_INTERSECT) { + for (u32 i = 0; i < mNumScnObj; i++) { + mpScnObjArray[i]->G3dProc(G3DPROC_GATHER_SCNOBJ, param, + pCollection); + } + } else if (status == IScnObjGather::CULLINGSTATUS_INSIDE) { + const math::FRUSTUM* pTemp = gpCullingFrustum; + gpCullingFrustum = NULL; + { + for (u32 i = 0; i < mNumScnObj; i++) { + mpScnObjArray[i]->G3dProc(G3DPROC_GATHER_SCNOBJ, param, + pCollection); + } + } + gpCullingFrustum = pTemp; + } +} + +void ScnGroup::ScnGroup_G3DPROC_CALC_WORLD(u32 param, + const math::MTX34* pParent) { + CheckCallback_CALC_WORLD(CALLBACK_TIMING_A, param, + const_cast(pParent)); + + CalcWorldMtx(pParent, ¶m); + + CheckCallback_CALC_WORLD(CALLBACK_TIMING_B, param, + const_cast(pParent)); + + math::MTX34* pWorldMtx = const_cast(GetMtxPtr(MTX_WORLD)); + + for (u32 i = 0; i < mNumScnObj; i++) { + mpScnObjArray[i]->G3dProc(G3DPROC_CALC_WORLD, param, pWorldMtx); + } + + CheckCallback_CALC_WORLD(CALLBACK_TIMING_C, param, + const_cast(pParent)); +} + +void ScnGroup::ScnGroup_G3DPROC_CALC_MAT(u32 param, void* pInfo) { + CheckCallback_CALC_MAT(CALLBACK_TIMING_A, param, pInfo); + + for (u32 i = 0; i < mNumScnObj; i++) { + mpScnObjArray[i]->G3dProc(G3DPROC_CALC_MAT, param, pInfo); + } + + CheckCallback_CALC_MAT(CALLBACK_TIMING_C, param, pInfo); +} + +void ScnGroup::ScnGroup_G3DPROC_CALC_VIEW(u32 param, + const math::MTX34* pCamera) { + CheckCallback_CALC_VIEW(CALLBACK_TIMING_A, param, + const_cast(pCamera)); + + CalcViewMtx(pCamera); + + CheckCallback_CALC_VIEW(CALLBACK_TIMING_B, param, + const_cast(pCamera)); + + for (u32 i = 0; i < mNumScnObj; i++) { + mpScnObjArray[i]->G3dProc(G3DPROC_CALC_VIEW, param, + const_cast(pCamera)); + } + + CheckCallback_CALC_VIEW(CALLBACK_TIMING_C, param, + const_cast(pCamera)); +} + +void ScnGroup::G3dProc(u32 task, u32 param, void* pInfo) { + if (IsG3dProcDisabled(task)) { + return; + } + + DefG3dProcScnGroup(task, param, pInfo); +} + +void ScnGroup::DefG3dProcScnGroup(u32 task, u32 param, void* pInfo) { + switch (task) { + case G3DPROC_GATHER_SCNOBJ: { + ScnGroup_G3DPROC_GATHER_SCNOBJ(param, + static_cast(pInfo)); + break; + } + + case G3DPROC_CALC_WORLD: { + ScnGroup_G3DPROC_CALC_WORLD(param, static_cast(pInfo)); + break; + } + + case G3DPROC_CALC_MAT: { + ScnGroup_G3DPROC_CALC_MAT(param, pInfo); + break; + } + + case G3DPROC_CALC_VIEW: { + ScnGroup_G3DPROC_CALC_VIEW(param, static_cast(pInfo)); + break; + } + + case G3DPROC_DRAW_OPA: + case G3DPROC_DRAW_XLU: { + return; + } + + case G3DPROC_CHILD_DETACHED: { + Remove(static_cast(pInfo)); + break; + } + + case G3DPROC_DETACH_PARENT: { + SetParent(NULL); + break; + } + + case G3DPROC_ATTACH_PARENT: { + SetParent(static_cast(pInfo)); + break; + } + + case G3DPROC_UPDATEFRAME: + case G3DPROC_ZSORT: + default: { + for (u32 i = 0; i < mNumScnObj; i++) { + mpScnObjArray[i]->G3dProc(task, param, pInfo); + } + break; + } + } +} + +bool ScnGroup::Insert(u32 idx, ScnObj* pObj) { + if (idx <= mNumScnObj && mNumScnObj < mSizeScnObj && pObj != NULL && + pObj->GetParent() == NULL) { + + ScnObj** ppObj = + std::find(mpScnObjArray, mpScnObjArray + mNumScnObj, pObj); + + if (ppObj == mpScnObjArray + mNumScnObj) { + for (u32 i = mNumScnObj; i > idx; i--) { + mpScnObjArray[i] = mpScnObjArray[i - 1]; + } + + mpScnObjArray[idx] = pObj; + pObj->G3dProc(G3DPROC_ATTACH_PARENT, 0, this); + + mNumScnObj++; + return true; + } + } + + return false; +} + +ScnObj* ScnGroup::Remove(u32 idx) { + if (idx < mNumScnObj) { + ScnObj* pObj = mpScnObjArray[idx]; + pObj->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + + for (u32 i = idx; i < mNumScnObj - 1; i++) { + mpScnObjArray[i] = mpScnObjArray[i + 1]; + } + + mNumScnObj--; + return pObj; + } + + return NULL; +} + +bool ScnGroup::Remove(ScnObj* pObj) { + ScnObj** ppObj = std::find(mpScnObjArray, mpScnObjArray + mNumScnObj, pObj); + + if (ppObj != mpScnObjArray + mNumScnObj) { + return Remove(std::distance(mpScnObjArray, ppObj)) != NULL; + } + + return false; +} + +ScnGroup::ScnGroup(MEMAllocator* pAllocator, ScnObj** ppObj, u32 capacity) + : ScnObj(pAllocator), + mpScnObjArray(ppObj), + mSizeScnObj(capacity), + mNumScnObj(0) { + + SetScnObjFlag(SCNOBJFLAG_NOT_GATHER_DRAW_OPA, TRUE); + SetScnObjFlag(SCNOBJFLAG_NOT_GATHER_DRAW_XLU, TRUE); +} + +ScnGroup::~ScnGroup() { + Clear(); +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_scnproc.cpp b/src/nw4r/g3d/g3d_scnproc.cpp new file mode 100644 index 00000000..9a3a675d --- /dev/null +++ b/src/nw4r/g3d/g3d_scnproc.cpp @@ -0,0 +1,72 @@ +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(ScnProc); + +ScnProc* ScnProc::Construct(MEMAllocator* pAllocator, u32* pSize, + DrawProc pProc, bool opa, bool xlu, + u32 userDataSize) { + ScnProc* pScnProc = NULL; + u32 scnProcSize = sizeof(ScnProc); + + userDataSize = align4(userDataSize); + u32 userDataOfs = align4(scnProcSize); + + u32 size = align4(userDataOfs + userDataSize); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator != NULL) { + u8* pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + + if (pBuffer != NULL) { + void* pUserData = userDataSize != 0 ? pBuffer + userDataOfs : NULL; + + pScnProc = + new (pBuffer) ScnProc(pAllocator, pProc, pUserData, opa, xlu); + } + } + + return pScnProc; +} + +void ScnProc::G3dProc(u32 task, u32 param, void* pInfo) { + if (IsG3dProcDisabled(task)) { + return; + } + + switch (task) { + case G3DPROC_GATHER_SCNOBJ: { + IScnObjGather* pCollection = static_cast(pInfo); + pCollection->Add(this, (mFlag & SCNPROCFLAG_DRAW_OPA) ? true : false, + (mFlag & SCNPROCFLAG_DRAW_XLU) ? true : false); + break; + } + + case G3DPROC_DRAW_OPA: { + if (mpDrawProc != NULL) { + G3DState::Invalidate(); + mpDrawProc(this, true); + } + break; + } + + case G3DPROC_DRAW_XLU: { + if (mpDrawProc != NULL) { + G3DState::Invalidate(); + mpDrawProc(this, false); + } + break; + } + + default: { + DefG3dProcScnLeaf(task, param, pInfo); + } + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_scnrfl.cpp b/src/nw4r/g3d/g3d_scnrfl.cpp new file mode 100644 index 00000000..47de6bba --- /dev/null +++ b/src/nw4r/g3d/g3d_scnrfl.cpp @@ -0,0 +1,237 @@ +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(ScnRfl); + +void ScnRfl::SetLightSetIdx(int idx) { + if (idx < 0 || idx > G3DState::NUM_LIGHT_SET - 1) { + mIdxLightSet = -1; + return; + } + + mIdxLightSet = idx; +} + +void ScnRfl::SetFogIdx(int idx) { + // @bug G3DState only allows 32 fog entries + if (idx < 0 || idx > 127) { + mIdxFog = -1; + return; + } + + mIdxFog = idx; +} + +bool ScnRfl::SetExpression(RFLExpression expression) { + if (IsCharModelReady()) { + RFLSetExpression(&mCharModel, expression); + return true; + } + + return false; +} + +bool ScnRfl::GetExpression(RFLExpression* pExpression) { + if (pExpression != NULL && IsCharModelReady()) { + *pExpression = RFLGetExpression(&mCharModel); + return true; + } + + return false; +} + +bool ScnRfl::SetupCharModel(RFLDataSource src, u16 index, + RFLMiddleDB* pMiddleDB) { + ReleaseCharModel(); + + mRFLErrCode = RFLInitCharModel(&mCharModel, src, pMiddleDB, index, + mpNglBuffer, mResolution, mExpressionFlag); + + if (mRFLErrCode != RFLErrcode_Success) { + return false; + } + + mCharModelReady = TRUE; + return true; +} + +void ScnRfl::ReleaseCharModel() { + if (IsCharModelReady()) { + mCharModelReady = FALSE; + } +} + +ScnRfl* ScnRfl::Construct(MEMAllocator* pAllocator, u32* pSize, + RFLResolution resolution, u32 exprFlags, + u32 userDataSize) { + ScnRfl* pScnRfl = NULL; + + u32 scnRflSize = sizeof(ScnRfl); + u32 nglSize = RFLGetModelBufferSize(resolution, exprFlags); + + u32 userOffset = align4(scnRflSize); + u32 nglOffset = align32(userOffset + userDataSize); + + u32 size = align32(nglOffset + nglSize); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator != NULL) { + u8* pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + // clang-format off + pScnRfl = new (pBuffer) ScnRfl( + pAllocator, + pBuffer + nglOffset, + userDataSize != 0 ? pBuffer + userOffset : NULL, + resolution, + exprFlags); + // clang-format on + } + + return pScnRfl; +} + +void ScnRfl::G3dProc(u32 task, u32 param, void* pInfo) { + if (IsG3dProcDisabled(task)) { + return; + } + + switch (task) { + case G3DPROC_GATHER_SCNOBJ: { + IScnObjGather* pCollection = static_cast(pInfo); + pCollection->Add(this, true, true); + break; + } + + case G3DPROC_CALC_WORLD: { + CheckCallback_CALC_WORLD(CALLBACK_TIMING_A, param, pInfo); + CalcWorldMtx(static_cast(pInfo), ¶m); + CheckCallback_CALC_WORLD(CALLBACK_TIMING_B, param, pInfo); + CheckCallback_CALC_WORLD(CALLBACK_TIMING_C, param, pInfo); + break; + } + + case G3DPROC_CALC_VIEW: { + CheckCallback_CALC_VIEW(CALLBACK_TIMING_A, param, pInfo); + CalcViewMtx(static_cast(pInfo)); + CheckCallback_CALC_VIEW(CALLBACK_TIMING_B, param, pInfo); + + math::MTX34 viewMtx; + GetMtx(MTX_VIEW, &viewMtx); + RFLSetMtx(&mCharModel, viewMtx); + + CheckCallback_CALC_VIEW(CALLBACK_TIMING_C, param, pInfo); + break; + } + + case G3DPROC_DRAW_OPA: { + if (!IsCharModelReady()) { + break; + } + + if (mpDrawProc == NULL) { + LoadDrawSetting(); + RFLDrawOpa(&mCharModel); + } else { + CallDrawProc(true); + } + break; + } + + case G3DPROC_DRAW_XLU: { + if (!IsCharModelReady()) { + break; + } + + if (mpDrawProc == NULL) { + LoadDrawSetting(); + RFLDrawXlu(&mCharModel); + } else { + CallDrawProc(false); + } + break; + } + + default: { + DefG3dProcScnLeaf(task, param, pInfo); + break; + } + } +} + +void ScnRfl::CallDrawProc(bool opa) { + G3DState::LoadFog(GetFogIdx()); + + u32 diffMask, specMask; + AmbLightObj lobj; + G3DState::LoadLightSet(GetLightSetIdx(), &diffMask, &specMask, &lobj); + + GXColor ambColor; + ambColor.r = 0.5f + (lobj.r * mAmbientColor.r) * (1.0f / 255.0f); + ambColor.g = 0.5f + (lobj.g * mAmbientColor.g) * (1.0f / 255.0f); + ambColor.b = 0.5f + (lobj.b * mAmbientColor.b) * (1.0f / 255.0f); + ambColor.a = 0.5f + (lobj.a * mAmbientColor.a) * (1.0f / 255.0f); + + G3DState::Invalidate( + G3DState::INVALIDATE_ALL & + ~(G3DState::INVALIDATE_FOG | G3DState::INVALIDATE_LIGHT)); + + mpDrawProc(this, &mCharModel, diffMask, specMask, ambColor, opa); +} + +void ScnRfl::LoadDrawSetting() { + RFLDrawSetting setting; + + G3DState::LoadFog(GetFogIdx()); + + u32 diffMask, specMask; + AmbLightObj lobj; + G3DState::LoadLightSet(GetLightSetIdx(), &diffMask, &specMask, &lobj); + + setting.lightEnable = GetLightSetIdx() >= 0 ? TRUE : FALSE; + setting.lightMask = static_cast(diffMask); + setting.diffuse = GetDiffuseFunc(); + setting.attn = GetAttnFunc(); + setting.compLoc = GXGetZCompLoc(); + + setting.ambColor.r = 0.5f + ((lobj.r * mAmbientColor.r) * (1.0f / 255.0f)); + setting.ambColor.g = 0.5f + ((lobj.g * mAmbientColor.g) * (1.0f / 255.0f)); + setting.ambColor.b = 0.5f + ((lobj.b * mAmbientColor.b) * (1.0f / 255.0f)); + setting.ambColor.a = 0.5f + ((lobj.a * mAmbientColor.a) * (1.0f / 255.0f)); + + G3DState::Invalidate( + G3DState::INVALIDATE_ALL & + ~(G3DState::INVALIDATE_FOG | G3DState::INVALIDATE_LIGHT)); + + RFLLoadDrawSetting(&setting); +} + +ScnRfl::ScnRfl(MEMAllocator* pAllocator, void* pNglBuffer, void* pUserData, + RFLResolution resolution, u32 exprFlag) + : ScnLeaf(pAllocator), + mResolution(resolution), + mExpressionFlag(exprFlag), + mIdxLightSet(-1), + mIdxFog(-1), + mZCompLoc(TRUE), + mCharModelReady(FALSE), + mDiffuseFn(GX_DF_CLAMP), + mAttnFn(GX_AF_SPOT), + mpNglBuffer(pNglBuffer), + mRFLErrCode(RFLErrcode_Success), + mpDrawProc(NULL), + mpUserData(pUserData) { + + mAmbientColor.r = mAmbientColor.g = mAmbientColor.b = 64; + mAmbientColor.a = 255; +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_scnroot.cpp b/src/nw4r/g3d/g3d_scnroot.cpp new file mode 100644 index 00000000..692ebd3a --- /dev/null +++ b/src/nw4r/g3d/g3d_scnroot.cpp @@ -0,0 +1,453 @@ +#include + +#include + +#include +#include + +namespace nw4r { +namespace g3d { + +NW4R_G3D_RTTI_DEF(ScnRoot); + +/****************************************************************************** + * + * ScnRoot + * + ******************************************************************************/ +ScnRoot *ScnRoot::Construct( + MEMAllocator *pAllocator, u32 *pSize, u32 maxChildren, u32 maxScnObj, u32 numLightObj, u32 numLightSet +) { + ScnRoot *pScnRoot = NULL; + u32 scnRootSize = sizeof(ScnRoot); + u32 scnObjGatherSize = sizeof(ScnObjGather); + + u32 childrenSize = maxChildren * sizeof(ScnObj *); + u32 scnObjBufSize = maxScnObj * sizeof(ScnObj *) + maxScnObj * sizeof(ScnObj *); + + u32 lightObjSize = numLightObj * sizeof(LightObj); + u32 ambLightObjSize = numLightObj * sizeof(AmbLightObj); + u32 lightSetDataSize = numLightSet * sizeof(LightSetData); + + u32 scnObjGatherOfs = align4(scnRootSize); + u32 childrenOfs = align4(scnObjGatherOfs + scnObjGatherSize); + u32 scnObjBufOfs = align4(childrenOfs + childrenSize); + u32 lightObjOfs = align4(scnObjBufOfs + scnObjBufSize); + u32 ambLightOfs = align4(lightObjOfs + lightObjSize); + u32 lightSetDataOfs = align4(ambLightOfs + ambLightObjSize); + + u32 size = align4(lightSetDataOfs + lightSetDataSize); + if (pSize != NULL) { + *pSize = size; + } + + if (pAllocator != NULL) { + u8 *pBuffer = reinterpret_cast(Alloc(pAllocator, size)); + if (pBuffer == NULL) { + return NULL; + } + + ScnObj **ppScnObjBuf = reinterpret_cast(pBuffer + scnObjBufOfs); + + IScnObjGather *pGather = + new (pBuffer + scnObjGatherOfs) ScnObjGather(ppScnObjBuf, ppScnObjBuf + maxScnObj, maxScnObj); + + LightObj *pLightObjBuf = reinterpret_cast(pBuffer + lightObjOfs); + + AmbLightObj *pAmbObjBuf = reinterpret_cast(pBuffer + ambLightOfs); + + LightSetData *pLightSetBuf = reinterpret_cast(pBuffer + lightSetDataOfs); + + // clang-format off + pScnRoot = new (pBuffer) ScnRoot( + pAllocator, + pGather, + reinterpret_cast(pBuffer + childrenOfs), + maxChildren, + numLightObj, + numLightSet, + pLightObjBuf, + pAmbObjBuf, + pLightSetBuf); + // clang-format on + } + + return pScnRoot; +} + +void ScnRoot::G3dProc(u32 task, u32 param, void *pInfo) { + if (IsG3dProcDisabled(task)) { + return; + } + + switch (task) { + case G3DPROC_CHILD_DETACHED: { + if (mpAnmScn == pInfo) { + mpAnmScn->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + mpAnmScn = NULL; + break; + } + + // FALLTHROUGH, detach may be for ScnGroup + } + + default: { + DefG3dProcScnGroup(task, param, pInfo); + break; + } + } +} + +Camera ScnRoot::GetCamera(int idx) { + if (idx >= 0 && idx < G3DState::NUM_CAMERA) { + return Camera(&mCamera[idx]); + } + + return Camera(NULL); +} + +Camera ScnRoot::GetCurrentCamera() { + return Camera(&mCamera[mCurrentCameraID]); +} + +void ScnRoot::SetCurrentCamera(int idx) { + mCurrentCameraID = static_cast(idx); +} + +Fog ScnRoot::GetFog(int idx) { + if (idx >= 0 && idx < G3DState::NUM_FOG) { + return Fog(&mFog[idx]); + } + + return Fog(NULL); +} + +LightSet ScnRoot::GetLightSet(int idx) { + return mLightSetting.GetLightSet(idx); +} + +void ScnRoot::UpdateFrame() { + if (mpAnmScn != NULL) { + mpAnmScn->UpdateFrame(); + } + + G3dProc(G3DPROC_UPDATEFRAME, 0, NULL); +} + +void ScnRoot::SetGlbSettings() { + int i; + + Camera cam = GetCurrentCamera(); + cam.GXSetViewport(); + cam.GXSetProjection(); + cam.GXSetScissor(); + cam.GXSetScissorBoxOffset(); + + for (i = 0; i < G3DState::NUM_CAMERA; i++) { + G3DState::SetCameraProjMtx(Camera(&mCamera[i]), i, i == mCurrentCameraID); + } + + bool persp = cam.GetProjectionType() != GX_ORTHOGRAPHIC; + u32 projOrthoBit = persp ? 0 : GX_ORTHOGRAPHIC << 3; + + f32 near = cam.ref().projNear; + f32 far = cam.ref().projFar; + + u16 width = 0; + u16 center = 0; + + math::MTX44 proj; + bool fogRangeAdj = false; + + for (i = 0; i < G3DState::NUM_FOG; i++) { + Fog fog(&mFog[i]); + fog.SetNearFar(near, far); + + if (fog.ref().type != GX_PERSPECTIVE) { + fog.ref().type = static_cast((fog.ref().type & ~(GX_ORTHOGRAPHIC << 3)) | projOrthoBit); + } + + if (fog.IsFogRangeAdjEnable()) { + if (!fogRangeAdj) { + cam.GetProjectionMtx(&proj); + + f32 f_width, x; + cam.GetViewport(&x, NULL, &f_width, NULL, NULL, NULL); + + width = math::F32ToU16(f_width); + center = math::F32ToU16(x + f_width * 0.5f); + fogRangeAdj = true; + } + + fog.SetFogRangeAdjParam(width, center, proj); + } + + G3DState::SetFog(fog, i); + } + + G3DState::SetLightSetting(mLightSetting); +} + +void ScnRoot::CalcAnmScn() { + if (mpAnmScn == NULL) { + return; + } + + const u32 numLightSet = mpAnmScn->GetLightSetMaxRefNumber(); + const u32 numFog = mpAnmScn->GetFogMaxRefNumber(); + const u32 numCamera = mpAnmScn->GetCameraMaxRefNumber(); + + if (numLightSet > 0) { + mpAnmScn->GetLightSetting(&mLightSetting); + } + + if (numFog > 0) { + const u32 numLoadableFog = std::min(G3DState::NUM_FOG, numFog); + + for (u32 i = 0; i < numLoadableFog; i++) { + Fog fog(&mFog[i]); + mpAnmScn->GetFog(fog, i); + } + } + + if (numCamera > 0) { + const u32 numLoadableCamera = std::min(G3DState::NUM_CAMERA, numCamera); + + for (u32 i = 0; i < numLoadableCamera; i++) { + Camera cam(&mCamera[i]); + mpAnmScn->GetCamera(cam, i); + } + } +} + +void ScnRoot::CalcWorld() { + CalcAnmScn(); + G3dProc(G3DPROC_CALC_WORLD, 0, NULL); +} + +void ScnRoot::CalcMaterial() { + G3dProc(G3DPROC_CALC_MAT, 0, NULL); +} + +void ScnRoot::CalcVtx() { + G3dProc(G3DPROC_CALC_VTX, 0, NULL); +} + +void ScnRoot::CalcView() { + math::MTX34 cam; + GXInvalidateVtxCache(); + GetCurrentCamera().GetCameraMtx(&cam); + G3dProc(G3DPROC_CALC_VIEW, 0, &cam); +} + +void ScnRoot::GatherDrawScnObj() { + mpCollection->Clear(); + + math::FRUSTUM frustum; + Camera cam = GetCurrentCamera(); + + math::MTX34 mtx; + cam.GetCameraMtx(&mtx); + + if (cam.ref().flags & CameraData::FLAG_PROJ_PERSP) { + frustum.Set(cam.ref().projFovy, cam.ref().projAspect, cam.ref().projNear, cam.ref().projFar, mtx); + } else { + frustum.Set( + cam.ref().projTop, cam.ref().projBottom, cam.ref().projLeft, cam.ref().projRight, cam.ref().projNear, + cam.ref().projFar, mtx + ); + } + + gpCullingFrustum = &frustum; + G3dProc(G3DPROC_GATHER_SCNOBJ, 0, mpCollection); + gpCullingFrustum = NULL; +} + +void ScnRoot::ZSort() { + mpCollection->ZSort(); + G3dProc(G3DPROC_ZSORT, 0, mpCollection); +} + +void ScnRoot::DrawOpa() { + SetGlbSettings(); + + if (TestScnRootFlag(SCNROOTFLAG_FORCE_RESMDLDRAWMODE)) { + mpCollection->DrawOpa(&mDrawMode); + } else { + mpCollection->DrawOpa(NULL); + } + + G3DState::Invalidate(G3DState::INVALIDATE_TEV); +} + +void ScnRoot::DrawXlu() { + SetGlbSettings(); + + if (TestScnRootFlag(SCNROOTFLAG_FORCE_RESMDLDRAWMODE)) { + mpCollection->DrawXlu(&mDrawMode); + } else { + mpCollection->DrawXlu(NULL); + } + + G3DState::Invalidate(G3DState::INVALIDATE_TEV); +} + +ScnRoot::ScnRoot( + MEMAllocator *pAllocator, IScnObjGather *pGather, ScnObj **ppChildrenBuf, u32 maxChildren, u32 numLight, + u32 numLightSet, LightObj *pLightObjBuf, AmbLightObj *pAmbObjBuf, LightSetData *pLightSetBuf +) + : ScnGroup(pAllocator, ppChildrenBuf, maxChildren), + mpCollection(pGather), + mDrawMode(RESMDL_DRAWMODE_DEFAULT), + mScnRootFlags(0), + mCurrentCameraID(0), + mLightSetting(pLightObjBuf, pAmbObjBuf, numLight, pLightSetBuf, numLightSet), + mpAnmScn(NULL) { + for (u32 i = 0; i < G3DState::NUM_CAMERA; i++) { + Camera res(&mCamera[i]); + res.Init(); + } + + for (u32 i = 0; i < G3DState::NUM_FOG; i++) { + Fog res(&mFog[i]); + res.Init(); + } +} + +ScnRoot::~ScnRoot() { + if (mpAnmScn != NULL) { + mpAnmScn->G3dProc(G3DPROC_DETACH_PARENT, 0, this); + } +} + +/****************************************************************************** + * + * Sorting functions + * + ******************************************************************************/ +namespace { + +inline bool LessZSortOpa(const ScnObj *pLhs, const ScnObj *pRhs) { + int lhsPrio = pLhs->GetPriorityDrawOpa(); + int rhsPrio = pRhs->GetPriorityDrawOpa(); + + if (lhsPrio == rhsPrio) { + return pLhs->GetMtxPtr(ScnObj::MTX_VIEW)->_23 > pRhs->GetMtxPtr(ScnObj::MTX_VIEW)->_23; + } + + return lhsPrio < rhsPrio; +} + +inline bool LessZSortXlu(const ScnObj *pLhs, const ScnObj *pRhs) { + int lhsPrio = pLhs->GetPriorityDrawXlu(); + int rhsPrio = pRhs->GetPriorityDrawXlu(); + + if (lhsPrio == rhsPrio) { + return pLhs->GetMtxPtr(ScnObj::MTX_VIEW)->_23 < pRhs->GetMtxPtr(ScnObj::MTX_VIEW)->_23; + } + + return lhsPrio < rhsPrio; +} + +inline bool LessByGetValueForSortOpa(const ScnObj *pLhs, const ScnObj *pRhs) { + int lhsPrio = pLhs->GetPriorityDrawOpa(); + int rhsPrio = pRhs->GetPriorityDrawOpa(); + + if (lhsPrio == rhsPrio) { + return pLhs->GetValueForSortOpa() < pRhs->GetValueForSortOpa(); + } + + return lhsPrio < rhsPrio; +} + +inline bool LessByGetValueForSortXlu(const ScnObj *pLhs, const ScnObj *pRhs) { + int lhsPrio = pLhs->GetPriorityDrawXlu(); + int rhsPrio = pRhs->GetPriorityDrawXlu(); + + if (lhsPrio == rhsPrio) { + return pLhs->GetValueForSortXlu() < pRhs->GetValueForSortXlu(); + } + + return lhsPrio < rhsPrio; +} + +} // namespace + +/****************************************************************************** + * + * ScnObjGather + * + ******************************************************************************/ +IScnObjGather::CullingStatus ScnObjGather::Add(ScnObj *pObj, bool opa, bool xlu) { + IScnObjGather::CullingStatus status = IScnObjGather::CULLINGSTATUS_INTERSECT; + + math::IntersectionResult ixResult = math::INTERSECTION_INTERSECT; + + if (gpCullingFrustum != NULL) { + u32 value; + pObj->GetScnObjOption(ScnObj::OPTION_ENABLE_CULLING, &value); + + if (value) { + math::AABB aabb; + pObj->GetBoundingVolume(ScnObj::BOUNDINGVOLUME_AABB_WORLD, &aabb); + ixResult = gpCullingFrustum->IntersectAABB_Ex(&aabb); + + if (ixResult == math::INTERSECTION_NONE) { + return IScnObjGather::CULLINGSTATUS_OUTSIDE; + } else if (ixResult == math::INTERSECTION_INSIDE) { + status = IScnObjGather::CULLINGSTATUS_INSIDE; + } + } + } + + if (opa) { + if (mNumScnObjOpa < mSizeScnObj) { + mpArrayOpa[mNumScnObjOpa++] = pObj; + } else { + return status; + } + } + + if (xlu) { + if (mNumScnObjXlu < mSizeScnObj) { + mpArrayXlu[mNumScnObjXlu++] = pObj; + } else { + return status; + } + } + + return status; +} + +void ScnObjGather::ZSort() { + std::sort(mpArrayOpa, mpArrayOpa + mNumScnObjOpa, LessZSortOpa); + std::sort(mpArrayXlu, mpArrayXlu + mNumScnObjXlu, LessZSortXlu); +} + +void ScnObjGather::Sort() { + std::sort(mpArrayOpa, mpArrayOpa + mNumScnObjOpa, LessByGetValueForSortOpa); + std::sort(mpArrayXlu, mpArrayXlu + mNumScnObjXlu, LessByGetValueForSortXlu); +} + +void ScnObjGather::Sort(LessThanFunc pOpaFunc, LessThanFunc pXluFunc) { + std::sort(mpArrayOpa, mpArrayOpa + mNumScnObjOpa, pOpaFunc); + std::sort(mpArrayXlu, mpArrayXlu + mNumScnObjXlu, pXluFunc); +} + +void ScnObjGather::DrawOpa(ResMdlDrawMode *pForceMode) { + for (u32 i = 0; i != mNumScnObjOpa;) { + mpArrayOpa[i++]->G3dProc(G3dObj::G3DPROC_DRAW_OPA, 0, pForceMode); + } +} + +void ScnObjGather::DrawXlu(ResMdlDrawMode *pForceMode) { + for (u32 i = 0; i != mNumScnObjXlu;) { + mpArrayXlu[i++]->G3dProc(G3dObj::G3DPROC_DRAW_XLU, 0, pForceMode); + } +} + +ScnObjGather::ScnObjGather(ScnObj **ppBufOpa, ScnObj **ppBufXlu, u32 capacity) + : mpArrayOpa(ppBufOpa), mpArrayXlu(ppBufXlu), mSizeScnObj(capacity), mNumScnObjOpa(0), mNumScnObjXlu(0) {} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_state.cpp b/src/nw4r/g3d/g3d_state.cpp new file mode 100644 index 00000000..b2d5c354 --- /dev/null +++ b/src/nw4r/g3d/g3d_state.cpp @@ -0,0 +1,1946 @@ +#include "common.h" +#include + +#include +#include + +namespace nw4r { +namespace g3d { +namespace detail { +namespace ScnDependentMtxFunc { +/****************************************************************************** + * + * ScnDependentMtxFunc + * + ******************************************************************************/ +void EnvironmentMapping(math::MTX34 *pMtx, s8 camRef, s8 lightRef) { + if (pMtx == NULL) { + return; + } + + if (camRef >= 0 && camRef < G3DState::NUM_CAMERA) { + math::MTX34Mult(pMtx, G3DState::GetCameraMtxPtr(camRef), G3DState::GetInvCameraMtxPtr()); + + pMtx->_03 = pMtx->_13 = pMtx->_23 = 0.0f; + + math::MTX34Mult(pMtx, G3DState::GetEnvironmentTexMtxPtr(), pMtx); + return; + } + + if (lightRef >= 0 && lightRef < G3DState::NUM_LIGHT && G3DState::GetLightObj(lightRef)->IsEnable()) { + math::VEC3 look, camUp, right, up; + + const LightObj *pLight = G3DState::GetLightObj(lightRef); + pLight->GetLightDir(&look); + + const math::MTX34 *pInvCamMtx = G3DState::GetInvCameraMtxPtr(); + + if (pLight->IsDiffuseLight() || (look.x == 0.0f && look.y == 0.0f && look.z == 0.0f)) { + pLight->GetLightPos(&look); + math::VEC3TransformNormal(&look, pInvCamMtx, &look); + + look = -look; + + if (look.x == 0.0f && look.y == 0.0f && look.z == 0.0f) { + look.y = -1.0f; + } + } else { + math::VEC3TransformNormal(&look, pInvCamMtx, &look); + } + + math::VEC3Normalize(&look, &look); + + if (math::FAbs(look.x) < 0.000001f && math::FAbs(look.z) < 0.000001f) { + camUp.x = camUp.y = 0.0f; + + if (look.y <= 0.0f) { + camUp.z = -1.0f; + } else { + camUp.z = 1.0f; + } + } else { + camUp.x = camUp.z = 0.0f; + camUp.y = 1.0f; + } + + math::VEC3Cross(&right, &look, &camUp); + math::VEC3Normalize(&right, &right); + math::VEC3Cross(&up, &right, &look); + + pMtx->_00 = right.x; + pMtx->_01 = right.y; + pMtx->_02 = right.z; + + pMtx->_10 = up.x; + pMtx->_11 = up.y; + pMtx->_12 = up.z; + + pMtx->_20 = -look.x; + pMtx->_21 = -look.y; + pMtx->_22 = -look.z; + + math::MTX34Mult(pMtx, pMtx, pInvCamMtx); + pMtx->_03 = pMtx->_13 = pMtx->_23 = 0.0f; + + static const math::_MTX34 envMtx = { + // clang-format off + 0.5f, 0.0f, 0.0f, 0.5f, + 0.0f, -0.5f, 0.0f, 0.5f, + 0.0f, 0.0f, 0.0f, 1.0f + // clang-format on + }; + + math::MTX34Mult(pMtx, static_cast(&envMtx), pMtx); + return; + } + + math::MTX34Copy(pMtx, G3DState::GetEnvironmentTexMtxPtr()); +} + +void ProjectionMapping(math::MTX34 *pMtx, s8 camRef, s8 lightRef) { +#pragma unused(lightRef) + + if (pMtx == NULL) { + return; + } + + if (camRef >= 0 && camRef < G3DState::NUM_CAMERA) { + math::MTX34Mult(pMtx, G3DState::GetCameraMtxPtr(camRef), G3DState::GetInvCameraMtxPtr()); + + math::MTX34Mult(pMtx, G3DState::GetProjectionTexMtxPtr(camRef), pMtx); + } else { + math::MTX34Copy(pMtx, G3DState::GetProjectionTexMtxPtr()); + } +} + +void EnvironmentSpecularMapping(math::MTX34 *pMtx, s8 camRef, s8 lightRef) { + if (pMtx == NULL) { + return; + } + + math::VEC3 look, camUp, camLook; + + const math::MTX34 *pCamMtx = G3DState::GetCameraMtxPtr(); + camLook.x = -pCamMtx->_20; + camLook.y = -pCamMtx->_21; + camLook.z = -pCamMtx->_22; + + const math::MTX34 *pInvCamMtx = G3DState::GetInvCameraMtxPtr(); + + if (lightRef >= 0 && lightRef < G3DState::NUM_LIGHT && G3DState::GetLightObj(lightRef)->IsEnable()) { + math::VEC3 lightLook; + + const LightObj *pLight = G3DState::GetLightObj(lightRef); + pLight->GetLightDir(&lightLook); + + if (pLight->IsDiffuseLight() || (lightLook.x == 0.0f && lightLook.y == 0.0f && lightLook.z == 0.0f)) { + pLight->GetLightPos(&lightLook); + math::VEC3TransformNormal(&lightLook, pInvCamMtx, &lightLook); + + lightLook = -lightLook; + + if (lightLook.x == 0.0f && lightLook.y == 0.0f && lightLook.z == 0.0f) { + lightLook.y = -1.0f; + } + } else { + math::VEC3TransformNormal(&lightLook, pInvCamMtx, &lightLook); + } + + if (!pLight->IsSpecularLight()) { + C_VECHalfAngle(camLook, lightLook, look); + } else { + look = -lightLook; + } + + if (math::FAbs(look.x) < 0.000001f && math::FAbs(look.z) < 0.000001f) { + camUp.x = camUp.y = 0.0f; + + if (look.y <= 0.0f) { + camUp.z = -1.0f; + } else { + camUp.z = 1.0f; + } + } else { + camUp.x = camUp.z = 0.0f; + camUp.y = 1.0f; + } + + } else if (camRef >= 0 && camRef < G3DState::NUM_CAMERA) { + const math::MTX34 *pLightCamMtx = G3DState::GetCameraMtxPtr(camRef); + camUp.x = pLightCamMtx->_10; + camUp.y = pLightCamMtx->_11; + camUp.z = pLightCamMtx->_12; + + math::VEC3 lightLook(-pLightCamMtx->_20, -pLightCamMtx->_21, -pLightCamMtx->_22); + + C_VECHalfAngle(camLook, lightLook, look); + } else { + math::MTX34Copy(pMtx, G3DState::GetEnvironmentTexMtxPtr()); + return; + } + + math::VEC3Normalize(&look, &look); + + math::VEC3 right, up; + + math::VEC3Cross(&right, &camUp, &look); + math::VEC3Normalize(&right, &right); + + math::VEC3Cross(&up, &look, &right); + + pMtx->_00 = right.x; + pMtx->_01 = right.y; + pMtx->_02 = right.z; + + pMtx->_10 = up.x; + pMtx->_11 = up.y; + pMtx->_12 = up.z; + + pMtx->_20 = look.x; + pMtx->_21 = look.y; + pMtx->_22 = look.z; + + math::MTX34Mult(pMtx, pMtx, pInvCamMtx); + pMtx->_03 = pMtx->_13 = pMtx->_23 = 0.0f; + + math::MTX34Mult(pMtx, G3DState::GetEnvironmentTexMtxPtr(), pMtx); +} + +void DefaultMapping(math::MTX34 *pMtx, s8 camRef, s8 lightRef) { +#pragma unused(camRef) +#pragma unused(lightRef) + + if (pMtx == NULL) { + return; + } + + math::MTX34Identity(pMtx); +} + +} // namespace ScnDependentMtxFunc +} // namespace detail + +namespace G3DState { +namespace { +/****************************************************************************** + * + * Utility functions + * + ******************************************************************************/ +inline bool IsEqualTexObj(const GXTexObj &rLhs, const GXTexObj &rRhs) { + return rLhs.dummy[0] == rRhs.dummy[0] && rLhs.dummy[1] == rRhs.dummy[1] && rLhs.dummy[2] == rRhs.dummy[2] && + rLhs.dummy[3] == rRhs.dummy[3] && rLhs.dummy[4] == rRhs.dummy[4] && rLhs.dummy[5] == rRhs.dummy[5] && + rLhs.dummy[6] == rRhs.dummy[6] && rLhs.dummy[7] == rRhs.dummy[7]; +} + +inline bool IsEqualTlutObj(const GXTlutObj &rLhs, const GXTlutObj &rRhs) { + return rLhs.dummy[0] == rRhs.dummy[0] && rLhs.dummy[1] == rRhs.dummy[1] && rLhs.dummy[2] == rRhs.dummy[2]; +} + +} // namespace + +/****************************************************************************** + * + * IndMtxTexInfo + * + ******************************************************************************/ +IndTexMtxInfo::IndTexMtxInfo(const ResMatIndMtxAndScale ind) : flag(0) { + if (ind.GXGetIndTexMtx(GX_ITM_0, &offset_mtx[GX_ITM_0 - 1])) { + flag |= 1 << GX_ITM_0 - 1; + } + + if (ind.GXGetIndTexMtx(GX_ITM_1, &offset_mtx[GX_ITM_1 - 1])) { + flag |= 1 << GX_ITM_1 - 1; + } + + if (ind.GXGetIndTexMtx(GX_ITM_2, &offset_mtx[GX_ITM_2 - 1])) { + flag |= 1 << GX_ITM_2 - 1; + } +} + +void IndTexMtxInfo::FifoSend() const { + if (flag & (1 << GX_ITM_0 - 1)) { + fifo::GDSetIndTexMtx(GX_PNMTX0, offset_mtx[GX_ITM_0 - 1]); + } + + if (flag & (1 << GX_ITM_1 - 1)) { + fifo::GDSetIndTexMtx(GX_PNMTX1, offset_mtx[GX_ITM_1 - 1]); + } + + if (flag & (1 << GX_ITM_2 - 1)) { + fifo::GDSetIndTexMtx(GX_PNMTX2, offset_mtx[GX_ITM_2 - 1]); + } +} + +void IndTexMtxInfo::SetMtx(GXIndTexMtxID id, const math::MTX34 &rMtx) { + if (id == GX_ITM_0) { + offset_mtx[GX_ITM_0 - 1] = rMtx; + flag |= 1 << GX_ITM_0 - 1; + + } else if (id == GX_ITM_1) { + offset_mtx[GX_ITM_1 - 1] = rMtx; + flag |= 1 << GX_ITM_1 - 1; + + } else if (id == GX_ITM_2) { + offset_mtx[GX_ITM_2 - 1] = rMtx; + flag |= 1 << GX_ITM_2 - 1; + } +} + +namespace { +/****************************************************************************** + * + * SyncGX + * + ******************************************************************************/ + +class SyncGX { +public: + SyncGX() : bNeedSync(true) {} + + void Set(); + void Unset() { + bNeedSync = false; + } + + bool Get() { + bool result = bNeedSync; + Unset(); + return result; + } + + void Invalidate() { + bNeedSync = true; + } + +private: + bool bNeedSync; // at 0x0 +}; + +SyncGX sSyncGX; + +void SyncGX::Set() { + bNeedSync = true; +} + +/****************************************************************************** + * + * GenMode2 + * + ******************************************************************************/ +class GenMode2 { +public: + GenMode2() : mNumTexGens(1), mNumChans(0), mNumTevs(1), mNumInds(0), mCullMode(GX_CULL_BACK), flag(0) {} + + void Invalidate() { + mNumTexGens = 1; + mNumChans = 0; + mNumTevs = 1; + mNumInds = 0; + mCullMode = GX_CULL_BACK; + flag = 0; + } + + void LoadBP() { + if ((flag & FLAG_FIRST_SET) && (flag & FLAG_ALL_LOADED) == FLAG_XF_LOADED) { + fifo::GDSetGenMode2Ex_BP(mNumTexGens, mNumChans, mNumTevs, mNumInds, mCullMode); + + flag |= FLAG_BP_LOADED; + } + } + + void LoadXF() { + if ((flag & FLAG_FIRST_SET) && (flag & FLAG_ALL_LOADED) != FLAG_ALL_LOADED) { + fifo::GDSetGenMode2(mNumTexGens, mNumChans, mNumTevs, mNumInds, mCullMode); + + flag |= FLAG_BP_LOADED | FLAG_XF_LOADED; + } + } + + void SetResGenMode(const ResGenMode res) { + if (mNumTexGens != res.GXGetNumTexGens()) { + mNumTexGens = res.GXGetNumTexGens(); + flag &= ~FLAG_ALL_LOADED; + } + + if (mNumChans != res.GXGetNumChans()) { + mNumChans = res.GXGetNumChans(); + flag &= ~FLAG_ALL_LOADED; + } + + if (mNumTevs != res.GXGetNumTevStages()) { + mNumTevs = res.GXGetNumTevStages(); + flag &= ~FLAG_BP_LOADED; + } + + if (mNumInds != res.GXGetNumIndStages()) { + mNumInds = res.GXGetNumIndStages(); + flag &= ~FLAG_BP_LOADED; + } + + if (mCullMode != res.GXGetCullMode()) { + mCullMode = res.GXGetCullMode(); + flag &= ~FLAG_BP_LOADED; + } + + if (!(flag & FLAG_FIRST_SET)) { + flag &= ~FLAG_ALL_LOADED; + flag |= FLAG_FIRST_SET; + } + } + + u8 GXGetNumTexGens() const { + return mNumTexGens; + } + + u8 GXGetNumChans() const { + return mNumChans; + } + + u8 GXGetNumIndStages() const { + return mNumInds; + } + +private: + enum Flag { + FLAG_BP_LOADED = (1 << 0), + FLAG_XF_LOADED = (1 << 1), + FLAG_FIRST_SET = (1 << 2), + + FLAG_ALL_LOADED = FLAG_BP_LOADED | FLAG_XF_LOADED + }; + +private: + u8 mNumTexGens; // at 0x0 + u8 mNumChans; // at 0x1 + u8 mNumTevs; // at 0x2 + u8 mNumInds; // at 0x3 + GXCullMode mCullMode; // at 0x4 + u32 flag; // at 0x8 +}; + +GenMode2 sGenMode2; + +/****************************************************************************** + * + * TexCoordScaleState + * + ******************************************************************************/ +struct TexMapSize { + u16 width; // at 0x0 + u16 height; // at 0x2 +}; + +struct TexCoordScale { + u16 width; // at 0x0 + u16 height; // at 0x2 + u32 opt; // at 0x4 +}; + +class TexCoordScaleState { +public: + TexCoordScaleState() { + std::memset(this, 0, sizeof(TexCoordScaleState)); + } + + void Invalidate() { + mUpToDate = 0; + } + + void UpdateTexMapSize(GXTexMapID map, u16 width, u16 height) { + wh[map].width = width; + wh[map].height = height; + + mUpToDate |= FLAG_TEXMAP; + mUpToDate &= ~FLAG_TEXCOORD; + } + + void UpdateTable(const ResTev tev) { + const u32 *pTable = reinterpret_cast(tev.ref().texCoordToTexMapID); + + if (!(mUpToDate & FLAG_TEXMAP) || pTable[0] != table_data[0] || pTable[1] != table_data[1]) { + table_data[0] = pTable[0]; + table_data[1] = pTable[1]; + + mUpToDate |= FLAG_TEXMAP; + mUpToDate &= ~FLAG_TEXCOORD; + } + } + + void LoadTexCoordScale(u8 texGens) { + if ((mUpToDate & FLAG_TEXMAP) && !(mUpToDate & FLAG_TEXCOORD) && texGens != 0) { + LoadTexCoordScale_(texGens); + } + } + +private: + enum UpToDateFlag { + FLAG_TEXCOORD = (1 << 0), + FLAG_TEXMAP = (1 << 1), + }; + +private: + void LoadTexCoordScale_(u8 texGens); + +private: + u32 mUpToDate; // at 0x0 + TexMapSize wh[GX_MAX_TEXMAP]; // at 0x4 + TexCoordScale scale[GX_MAX_TEXCOORD]; // at 0x24 + + union { + u8 table[GX_MAX_TEXCOORD]; + u32 table_data[GX_MAX_TEXCOORD / sizeof(u32)]; + }; // at 0x64 +}; + +TexCoordScaleState sTexCoordScale; + +void TexCoordScaleState::LoadTexCoordScale_(u8 texGens) { + for (u8 i = 0; i < texGens; i++) { + if (table[i] == GX_TEXMAP_NULL) { + continue; + } + + scale[i].width = wh[table[i]].width; + scale[i].height = wh[table[i]].height; + + fifo::GDSetTexCoordScale2( + static_cast(i), scale[i].width, false, false, scale[i].height, false, false + ); + } + + mUpToDate |= FLAG_TEXCOORD; +} + +/****************************************************************************** + * + * TexState + * + ******************************************************************************/ +class TexState { +public: + TexState() : mValidFlag(0) {} + + void Invalidate() { + mValidFlag = 0; + } + + void Invalidate(GXTexMapID map) { + mValidFlag &= ~(1 << map); + } + + void LoadResTexObj(const ResTexObj texObj) { + for (u32 i = 0; i < GX_MAX_TEXMAP; i++) { + if (!texObj.IsValidTexObj(static_cast(i))) { + continue; + } + + GXTexMapID id = static_cast(i); + const GXTexObj *pGXObj = texObj.GetTexObj(id); + + u8 mask = 1 << id; + + if (!(mValidFlag & mask) || !IsEqualTexObj(*pGXObj, mTexObj[id])) { + mValidFlag |= mask; + mTexObj[id] = *pGXObj; + + GXLoadTexObj(pGXObj, id); + + sTexCoordScale.UpdateTexMapSize(id, GXGetTexObjWidth(pGXObj), GXGetTexObjHeight(pGXObj)); + } + } + } + +private: + GXTexObj mTexObj[GX_MAX_TEXMAP]; // at 0x0 + u8 mValidFlag; // at 0x100 + u8 PADDING_0x101; // at 0x101 + u8 PADDING_0x102; // at 0x102 + u8 PADDING_0x103; // at 0x103 +}; + +TexState sTex ALIGN_DECL(32); + +/****************************************************************************** + * + * TlutState + * + ******************************************************************************/ +class TlutState { +public: + TlutState() : mFlag(0) {} + + void Invalidate() { + mFlag = 0; + } + + void LoadResTlutObj(const ResTlutObj tlutObj) { + for (u32 i = 0; i < GX_TLUT8; i++) { + if (!tlutObj.IsValidTlut(static_cast(i))) { + continue; + } + + GXTlut id = static_cast(i); + const GXTlutObj *pGXObj = tlutObj.GetTlut(id); + + u16 mask = 1 << id; + + if (!(mFlag & mask) || !IsEqualTlutObj(*pGXObj, mTlutObj[id])) { + mFlag |= mask; + mTlutObj[id] = *pGXObj; + + GXLoadTlut(const_cast(pGXObj), id); + sTex.Invalidate(static_cast(id)); + } + } + } + +private: + GXTlutObj mTlutObj[GX_TLUT7 - GX_TLUT0 + 1]; // at 0x0 + u16 mFlag; // at 0x60 + u16 PADDING_0x62; // at 0x62 +}; + +TlutState sTlut ALIGN_DECL(32); + +/****************************************************************************** + * + * ShpState + * + ******************************************************************************/ +class ShpState { +public: + ShpState() { + mCache.Clear(); + } + + void Invalidate() { + mCache.Clear(); + } + + bool IsCacheEqual(const ResCacheVtxDescv &rOther) { + if (rOther == mCache) { + return true; + } + + mCache = rOther; + return false; + } + +private: + ResCacheVtxDescv mCache; // at 0x0 +}; + +ShpState sShp; + +/****************************************************************************** + * + * CurrMtxState + * + ******************************************************************************/ +class CurrMtxState { +public: + CurrMtxState() : mIsUpToDate(false) {} + + void Invalidate() { + mIsUpToDate = false; + } + + void SetCurrMtx() { + if (mIsUpToDate) { + return; + } + + fifo::GDResetCurrentMtx(); + mIsUpToDate = true; + } + +private: + bool mIsUpToDate; // at 0x0 +}; + +CurrMtxState sCurrMtx; + +/****************************************************************************** + * + * PostTexMtxState + * + ******************************************************************************/ +class PostTexMtxState { +public: + PostTexMtxState() : mFlagIdentity(0) {} + + void Invalidate() { + mFlagIdentity = 0; + } + + bool IsIdentity(u32 id) const { + return mFlagIdentity & (1 << id); + } + + void SetIdentity(u32 id) { + mFlagIdentity |= (1 << id); + } + + void ResetIdentity(u32 id) { + mFlagIdentity &= ~(1 << id); + } + +private: + u32 mFlagIdentity; // at 0x0 +}; + +PostTexMtxState sPostTexMtx; + +/****************************************************************************** + * + * PreTexMtxState + * + ******************************************************************************/ +class PreTexMtxState { +public: + PreTexMtxState() { + Invalidate(); + } + + void Invalidate() { + mType[0] = mType[1] = mType[2] = mType[3] = mType[4] = mType[5] = mType[6] = mType[7] = + SCNDEPENDENT_TEXMTX_FUNCTYPE_TEXMTX_NOT_EXIST; + } + + void SetFuncType(u32 id, ScnDependentTexMtxFuncType type) { + mType[id] = type; + } + + void SetCurrentMtx(int id) const { + bool allIdent = true; + u32 idArray[NUM_TEX_MTX]; + + if (id < 0) { + return; + } + + for (u32 i = 0; i < NUM_TEX_MTX; i++) { + if (mType[i] == SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_NRM) { + idArray[i] = i * 3 + GX_TEXMTX0; + fifo::GDLoadTexMtxImm3x3(*GetViewNrmMtxPtr(static_cast(id)), idArray[i]); + allIdent = false; + } else if (mType[i] == SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_POS) { + idArray[i] = GX_PNMTX0; + allIdent = false; + } else { + idArray[i] = GX_TEXMTX_IDENT; + } + } + + if (allIdent) { + sCurrMtx.SetCurrMtx(); + } else { + fifo::GDSetCurrentMtx(idArray); + sCurrMtx.Invalidate(); + } + } + +private: + static const int NUM_TEX_MTX = (GX_TEXMTX8 - GX_TEXMTX0) / 3; + +private: + ScnDependentTexMtxFuncType mType[NUM_TEX_MTX]; // at 0x0 +}; + +PreTexMtxState sPreTexMtxState; + +/****************************************************************************** + * + * TevState + * + ******************************************************************************/ +class TevState { +public: + TevState() : mpTevData(NULL) {} + + void Invalidate() { + mpTevData = NULL; + } + + bool IsTevEqual(const ResTev tev) { + if (tev.ptr() == mpTevData) { + return true; + } + + mpTevData = tev.ptr(); + return false; + } + +private: + const ResTevData *mpTevData; // at 0x0 +}; + +TevState sTev; + +/****************************************************************************** + * + * PosNrmMtxArrayState + * + ******************************************************************************/ +class PosNrmMtxArrayState { +public: + PosNrmMtxArrayState() : mpViewPosMtxArray(NULL), mpViewNrmMtxArray(NULL), mpViewEnvTexMtxArray(NULL) {} + + void Invalidate() { + mpViewPosMtxArray = NULL; + mpViewNrmMtxArray = NULL; + mpViewEnvTexMtxArray = NULL; + } + + bool IsValid() const { + return mpViewPosMtxArray != NULL; + } + + void SetViewPosNrmMtxArray( + const math::MTX34 *pViewPosMtxArray, const math::MTX33 *pViewNrmMtxArray, const math::MTX34 *pViewEnvTexMtxArray + ) { + mpViewPosMtxArray = pViewPosMtxArray; + mpViewNrmMtxArray = pViewNrmMtxArray; + mpViewEnvTexMtxArray = pViewEnvTexMtxArray; + + if (mpViewPosMtxArray != NULL) { + GXSetArray(GX_POS_MTX_ARRAY, mpViewPosMtxArray, sizeof(math::MTX34)); + } + + if (mpViewNrmMtxArray != NULL) { + GXSetArray(GX_NRM_MTX_ARRAY, mpViewNrmMtxArray, sizeof(math::MTX33)); + } + + if (mpViewEnvTexMtxArray != NULL) { + GXSetArray(GX_TEX_MTX_ARRAY, mpViewEnvTexMtxArray, sizeof(math::MTX34)); + } + } + + const math::MTX34 *GetViewPosMtxPtr(u32 id) const { + if (mpViewPosMtxArray != NULL) { + return &mpViewPosMtxArray[id]; + } + + return NULL; + } + + const math::MTX33 *GetViewNrmMtxPtr(u32 id) const { + if (mpViewNrmMtxArray != NULL) { + return &mpViewNrmMtxArray[id]; + } + + static math::MTX33 m; + + if (!math::MTX34InvTranspose(&m, GetViewPosMtxPtr(id))) { + m._00 = m._11 = m._22 = 1.0f; + m._20 = m._21 = 0.0f; + m._10 = m._12 = 0.0f; + m._01 = m._02 = 0.0f; + } + + return &m; + } + +private: + const math::MTX34 *mpViewPosMtxArray; // at 0x0 + const math::MTX33 *mpViewNrmMtxArray; // at 0x4 + const math::MTX34 *mpViewEnvTexMtxArray; // at 0x8 +}; + +PosNrmMtxArrayState sPosNrmArrayState; + +/****************************************************************************** + * + * ScnDependentTexMtxFuncTable + * + ******************************************************************************/ +class ScnDependentTexMtxFuncTable { +public: + ScnDependentTexMtxFuncTable() { + mTable[0].func = detail::ScnDependentMtxFunc::DefaultMapping; + mTable[0].type = SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_TEXCOORD; + + mTable[1].func = detail::ScnDependentMtxFunc::EnvironmentMapping; + mTable[1].type = SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_NRM; + + mTable[2].func = detail::ScnDependentMtxFunc::ProjectionMapping; + mTable[2].type = SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_POS; + + mTable[3].func = detail::ScnDependentMtxFunc::EnvironmentMapping; + mTable[3].type = SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_NRM; + + mTable[4].func = detail::ScnDependentMtxFunc::EnvironmentSpecularMapping; + mTable[4].type = SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_NRM; + + for (u32 i = 5; i < NUM_SCNDEPENDENT_TEXMTX_FUNCTYPE; i++) { + mTable[i].func = detail::ScnDependentMtxFunc::DefaultMapping; + mTable[i].type = SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_TEXCOORD; + } + } + + void SetFunc(u32 id, ScnDependentTexMtxFuncPtr func, ScnDependentTexMtxFuncType type) { + if (id <= 4 || id >= NUM_SCNDEPENDENT_TEXMTX_FUNCTYPE) { + return; + } + + if (func != NULL) { + if (type >= MAX_SCNDEPENDENT_TEXMTX_FUNCTYPE) { + type = SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_TEXCOORD; + } + + mTable[id].func = func; + mTable[id].type = type; + } else { + mTable[id].func = detail::ScnDependentMtxFunc::DefaultMapping; + mTable[id].type = SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_TEXCOORD; + } + } + + bool GetFunc(u32 id, ScnDependentTexMtxFuncPtr *pFunc, ScnDependentTexMtxFuncType *pType) { + if (id < NUM_SCNDEPENDENT_TEXMTX_FUNCTYPE) { + if (pFunc != NULL) { + *pFunc = mTable[id].func; + } + + if (pType != NULL) { + *pType = mTable[id].type; + } + + return true; + } + + return false; + } + + ScnDependentTexMtxFuncType GetFuncType(u32 id) { + if (id >= NUM_SCNDEPENDENT_TEXMTX_FUNCTYPE) { + id = 0; + } + + return mTable[id].type; + } + + void Calc(u32 id, math::MTX34 *pMtx, s8 camRef, s8 lightRef) { + if (id >= NUM_SCNDEPENDENT_TEXMTX_FUNCTYPE) { + id = 0; + } + + if (camRef >= NUM_CAMERA) { + camRef = -1; + } + + if (lightRef >= NUM_LIGHT) { + lightRef = -1; + } + + mTable[id].func(pMtx, camRef, lightRef); + } + +private: + struct { + ScnDependentTexMtxFuncPtr func; // at 0x0 + ScnDependentTexMtxFuncType type; // at 0x4 + } mTable[NUM_SCNDEPENDENT_TEXMTX_FUNCTYPE]; // at 0x0 +}; + +ScnDependentTexMtxFuncTable sScnDependentTexMtxFuncTable; + +/****************************************************************************** + * + * FogState + * + ******************************************************************************/ +class FogState { +public: + FogState() : mFlag(0), mCurrentFogIdx(-1) { + for (u32 i = 0; i < NUM_FOG; i++) { + Fog(&mFogData[i]).Init(); + } + } + + void Invalidate() { + mFlag = 0; + } + + void SetFog(const Fog fog, int id) { + if (id < 0 || id >= NUM_FOG || !fog.IsValid()) { + return; + } + + if (mCurrentFogIdx == id) { + if (std::memcmp(&fog.ref(), &mFogData[id], sizeof(FogData)) == 0) { + return; + } + + Invalidate(); + } + + fog.CopyTo(&mFogData[id]); + } + + void LoadFog(int id) { + if (!(mFlag & FLAG_0) || !(mFlag & FLAG_1) || id != mCurrentFogIdx) { + if (id < 0 || id >= NUM_FOG) { + GXColor color = {0, 0, 0, 0}; + GXSetFog(GX_FOG_NONE, color, 0.0f, 0.0f, 0.0f, 0.0f); + } else { + Fog(&mFogData[id]).SetGP(); + } + + mFlag |= FLAG_0 | FLAG_1; + mCurrentFogIdx = id; + } + } + +private: + enum Flag { + FLAG_0 = (1 << 0), + FLAG_1 = (1 << 1), + }; + +private: + u32 mFlag; // at 0x0 + int mCurrentFogIdx; // at 0x4 + FogData mFogData[NUM_FOG]; // at 0x8 +}; + +FogState sFogState; + +/****************************************************************************** + * + * LightState + * + ******************************************************************************/ +class LightState { +public: + LightState(); + + void Invalidate(); + + void SetLightSetting(const LightSetting &rSetting); + const LightObj *GetLightObj(int id) const; + void LoadLightSet( + int id, u32 *pDiffColorMask, u32 *pDiffAlphaMask, u32 *pSpecColorMask, u32 *pSpecAlphaMask, AmbLightObj *pAmb + ); + +private: + LightSetting mLightSetting; // at 0x0 + int mCurrentLightSetIdx; // at 0x10 + u32 mCurrentMaskDiffColor; // at 0x14 + u32 mCurrentMaskDiffAlpha; // at 0x18 + u32 mCurrentMaskSpecColor; // at 0x1C + u32 mCurrentMaskSpecAlpha; // at 0x20 + s8 mLoadedLightIdx[NUM_LIGHT_IN_LIGHT_SET]; // at 0x24 + LightObj mLightObj[NUM_LIGHT]; // at 0x2C + AmbLightObj mAmbLightObj[NUM_LIGHT]; // at 0x222C + LightSetData mLightSetData[NUM_LIGHT_SET]; // at 0x242C +}; + +LightState sLightState; + +LightState::LightState() : mLightSetting(mLightObj, mAmbLightObj, NUM_LIGHT, mLightSetData, NUM_LIGHT_SET) { + Invalidate(); +} + +void LightState::Invalidate() { + mCurrentLightSetIdx = -1; + + mCurrentMaskDiffColor = 0; + mCurrentMaskDiffAlpha = 0; + + mCurrentMaskSpecColor = 0; + mCurrentMaskSpecAlpha = 0; + + mLoadedLightIdx[0] = mLoadedLightIdx[1] = mLoadedLightIdx[2] = mLoadedLightIdx[3] = mLoadedLightIdx[4] = + mLoadedLightIdx[5] = mLoadedLightIdx[6] = mLoadedLightIdx[7] = -1; +} + +void LightState::SetLightSetting(const LightSetting &rSetting) { + mLightSetting.Import(rSetting); + + const math::MTX34 *pCamMtx = GetCameraMtxPtr(); + mLightSetting.ApplyViewMtx(*pCamMtx, rSetting.GetNumLightObj()); + Invalidate(); + + u32 lightNum = mLightSetting.GetNumLightObj(); + + u32 i = 0; + u32 idx = 0; + + for (; i < G3DState::NUM_LIGHT_IN_LIGHT_SET && idx < lightNum; idx++) { + const LightObj &rLight = mLightSetting.GetLightObjArray()[idx]; + if (!rLight.IsEnable()) { + continue; + } + + mLoadedLightIdx[i] = idx; + + GXLightID id = static_cast(1 << i); + GXLoadLightObjImm(rLight, id); + + i++; + } +} + +const LightObj *LightState::GetLightObj(int id) const { + if (id >= 0 && id < NUM_LIGHT) { + return &mLightObj[id]; + } + + return NULL; +} + +void LightState::LoadLightSet( + int id, u32 *pDiffColorMask, u32 *pDiffAlphaMask, u32 *pSpecColorMask, u32 *pSpecAlphaMask, AmbLightObj *pAmb +) { + if (id < 0 || id >= NUM_LIGHT_SET) { + if (pDiffColorMask != NULL) { + *pDiffColorMask = 0; + } + + if (pDiffAlphaMask != NULL) { + *pDiffAlphaMask = 0; + } + + if (pSpecColorMask != NULL) { + *pSpecColorMask = 0; + } + + if (pSpecAlphaMask != NULL) { + *pSpecAlphaMask = 0; + } + + if (pAmb != NULL) { + pAmb->r = pAmb->g = pAmb->b = pAmb->a = 255; + } + + return; + } + + if (pAmb != NULL) { + int ambId = mLightSetData[id].idxAmbLight; + + if (ambId < 0) { + pAmb->r = pAmb->g = pAmb->b = pAmb->a = 255; + } else { + *pAmb = mAmbLightObj[ambId]; + } + } + + if (mCurrentLightSetIdx == id) { + if (pDiffColorMask != NULL) { + *pDiffColorMask = mCurrentMaskDiffColor; + } + + if (pDiffAlphaMask != NULL) { + *pDiffAlphaMask = mCurrentMaskDiffAlpha; + } + + if (pSpecColorMask != NULL) { + *pSpecColorMask = mCurrentMaskSpecColor; + } + + if (pSpecAlphaMask != NULL) { + *pSpecAlphaMask = mCurrentMaskSpecAlpha; + } + + return; + } + + LightSetData &rData = mLightSetData[id]; + + mCurrentMaskDiffColor = 0; + mCurrentMaskDiffAlpha = 0; + + mCurrentMaskSpecColor = 0; + mCurrentMaskSpecAlpha = 0; + + mCurrentLightSetIdx = id; + + for (u32 i = 0; i < NUM_LIGHT_IN_LIGHT_SET; i++) { + s8 lightId = rData.idxLight[i]; + if (lightId < 0) { + continue; + } + + if (!mLightObj[lightId].IsEnable()) { + continue; + } + + s8 *pLoaded = std::find(mLoadedLightIdx, mLoadedLightIdx + NUM_LIGHT_IN_LIGHT_SET, lightId); + + GXLightID idFlag; + + if (pLoaded == mLoadedLightIdx + NUM_LIGHT_IN_LIGHT_SET) { + pLoaded = std::find(mLoadedLightIdx, mLoadedLightIdx + NUM_LIGHT_IN_LIGHT_SET, -1); + + if (pLoaded != mLoadedLightIdx + NUM_LIGHT_IN_LIGHT_SET) { + idFlag = static_cast(1 << std::distance(mLoadedLightIdx, pLoaded)); + + GXLoadLightObjImm(mLightObj[lightId], idFlag); + *pLoaded = lightId; + } else { + u32 j; + + for (j = 0; j < NUM_LIGHT_IN_LIGHT_SET; j++) { + s8 *pResult = + std::find(rData.idxLight, rData.idxLight + NUM_LIGHT_IN_LIGHT_SET, mLoadedLightIdx[j]); + + if (pResult == rData.idxLight + NUM_LIGHT_IN_LIGHT_SET) { + break; + } + } + + idFlag = static_cast(1 << j); + + GXLoadLightObjImm(mLightObj[lightId], idFlag); + mLoadedLightIdx[j] = lightId; + } + + } else { + idFlag = static_cast(1 << std::distance(mLoadedLightIdx, pLoaded)); + } + + if (mLightObj[lightId].IsSpecularLight()) { + if (mLightObj[lightId].IsColorEnable()) { + mCurrentMaskSpecColor |= idFlag; + } + + if (mLightObj[lightId].IsAlphaEnable()) { + mCurrentMaskSpecAlpha |= idFlag; + } + } else { + if (mLightObj[lightId].IsColorEnable()) { + mCurrentMaskDiffColor |= idFlag; + } + + if (mLightObj[lightId].IsAlphaEnable()) { + mCurrentMaskDiffAlpha |= idFlag; + } + } + } + + if (pDiffColorMask != NULL) { + *pDiffColorMask = mCurrentMaskDiffColor; + } + + if (pDiffAlphaMask != NULL) { + *pDiffAlphaMask = mCurrentMaskDiffAlpha; + } + + if (pSpecColorMask != NULL) { + *pSpecColorMask = mCurrentMaskSpecColor; + } + + if (pSpecAlphaMask != NULL) { + *pSpecAlphaMask = mCurrentMaskSpecAlpha; + } +} + +/****************************************************************************** + * + * CameraMtxState + * + ******************************************************************************/ +class CameraMtxState { +public: + CameraMtxState(); + + void SetCameraProjMtx(const Camera &rCam, int id, bool view); + + const math::MTX34 *GetInvCameraMtxPtr() const { + if (!(mFlag & FLAG_INV_MTX_READY)) { + math::MTX34Inv(&mInvCurrentCameraMtx, GetCameraMtxPtr()); + mFlag |= FLAG_INV_MTX_READY; + } + + return &mInvCurrentCameraMtx; + } + + const math::MTX34 *GetCameraMtxPtr() const { + return &mCameraMtx[mViewIdx]; + } + const math::MTX34 *GetCameraMtxPtr(int id) const { + if (id < NUM_CAMERA && id >= 0) { + return &mCameraMtx[id]; + } + + return NULL; + } + + const math::MTX44 *GetProjectionMtxPtr() const { + return &mProjMtx[mViewIdx]; + } + const math::MTX44 *GetProjectionMtxPtr(int id) const { + if (id < NUM_CAMERA && id >= 0) { + return &mProjMtx[id]; + } + + return NULL; + } + + const math::MTX34 *GetProjectionTexMtxPtr() const { + return &mProjTexMtx[mViewIdx]; + } + const math::MTX34 *GetProjectionTexMtxPtr(int id) const { + if (id < NUM_CAMERA && id >= 0) { + return &mProjTexMtx[id]; + } + + return NULL; + } + + const math::MTX34 *GetEnvironmentTexMtxPtr() const { + return &mEnvTexMtx[mViewIdx]; + } + +private: + enum Flag { + FLAG_INV_MTX_READY = (1 << 0), + }; + +private: + mutable u16 mFlag; // at 0x0 + u16 mViewIdx; // at 0x2 + mutable math::MTX34 mInvCurrentCameraMtx; // at 0x4 + math::MTX34 mCameraMtx[NUM_CAMERA]; // at 0x34 + math::MTX44 mProjMtx[NUM_CAMERA]; // at 0x634 + math::MTX34 mProjTexMtx[NUM_CAMERA]; // at 0xE34 + math::MTX34 mEnvTexMtx[NUM_CAMERA]; // at 0x1434 +}; + +CameraMtxState sCameraMtxState; + +CameraMtxState::CameraMtxState() : mFlag(0), mViewIdx(0) { + math::MTX34Identity(&mInvCurrentCameraMtx); + + for (u32 i = 0; i < NUM_CAMERA; i++) { + math::MTX34Identity(&mCameraMtx[i]); + math::MTX44Identity(&mProjMtx[i]); + math::MTX34Identity(&mProjTexMtx[i]); + math::MTX34Identity(&mEnvTexMtx[i]); + } +} + +void CameraMtxState::SetCameraProjMtx(const Camera &rCam, int id, bool view) { + if (id >= NUM_CAMERA || id < 0) { + return; + } + + rCam.GetCameraMtx(&mCameraMtx[id]); + rCam.GetProjectionMtx(&mProjMtx[id]); + rCam.GetProjectionTexMtx(&mProjTexMtx[id]); + rCam.GetEnvironmentTexMtx(&mEnvTexMtx[id]); + + if (view) { + mViewIdx = static_cast(id); + mFlag &= ~FLAG_INV_MTX_READY; + } +} + +/****************************************************************************** + * + * Render mode + * + ******************************************************************************/ +GXRenderModeObj sRenderMode; + +/****************************************************************************** + * + * Misc + * + ******************************************************************************/ +class Misc { +public: + Misc() : mValidFlag(0), mbZCompLoc(FALSE) {} + + void Invalidate() { + InvalidateZCompLoc(); + } + + void InvalidateZCompLoc() { + mValidFlag &= ~FLAG_ZCOMPLOC; + } + + void GXSetZCompLoc(GXBool beforeTex) { + if (!(mValidFlag & FLAG_ZCOMPLOC) || mbZCompLoc != beforeTex) { + mValidFlag |= FLAG_ZCOMPLOC; + mbZCompLoc = beforeTex; + + ::GXSetZCompLoc(beforeTex); + sSyncGX.Set(); + } + } + +private: + enum ValidFlag { + FLAG_ZCOMPLOC = (1 << 0), + }; + +private: + u32 mValidFlag; // at 0x0 + GXBool mbZCompLoc; // at 0x4 +}; + +Misc sMisc; + +} // namespace + +/****************************************************************************** + * + * G3DState + * + ******************************************************************************/ +namespace { + +IndMtxOpStd IndMtxOpDefault; +IndMtxOp *pG3DStateIndMtxOp = &IndMtxOpDefault; + +} // namespace + +void LoadResMatMisc(const ResMatMisc misc) { + if (!misc.IsValid()) { + return; + } + + sMisc.GXSetZCompLoc(misc.GXGetZCompLoc()); +} + +void LoadResTexObj(const ResTexObj texObj) { + if (!texObj.IsValid()) { + return; + } + + sTex.LoadResTexObj(texObj); + sSyncGX.Set(); +} + +void LoadResTlutObj(const ResTlutObj tlutObj) { + if (!tlutObj.IsValid()) { + return; + } + + sTlut.LoadResTlutObj(tlutObj); + sSyncGX.Set(); +} + +void LoadResGenMode(const ResGenMode mode) { + if (!mode.IsValid()) { + return; + } + + sGenMode2.SetResGenMode(mode); +} + +void LoadResTev(const ResTev tev) { + if (!tev.IsValid()) { + return; + } + + if (sTev.IsTevEqual(tev)) { + return; + } + + sGenMode2.LoadBP(); + tev.CallDisplayList(sSyncGX.Get()); + + sTexCoordScale.UpdateTable(tev); + sTexCoordScale.LoadTexCoordScale(sGenMode2.GXGetNumTexGens()); +} + +void LoadResMatPix(const ResMatPix pix) { + if (!pix.IsValid()) { + return; + } + + sGenMode2.LoadBP(); + pix.CallDisplayList(sSyncGX.Get()); +} + +void LoadResMatTevColor(const ResMatTevColor color) { + if (!color.IsValid()) { + return; + } + + sGenMode2.LoadBP(); + color.CallDisplayList(sSyncGX.Get()); +} + +void LoadResMatIndMtxAndScale(const ResMatIndMtxAndScale ind) { + if (!ind.IsValid()) { + return; + } + + sGenMode2.LoadBP(); + ind.CallDisplayList(sGenMode2.GXGetNumIndStages(), sSyncGX.Get()); +} + +void LoadResMatIndMtxAndScale(const ResMatIndMtxAndScale ind, IndMtxOp &rOp) { + if (!ind.IsValid()) { + return; + } + + LoadResMatIndMtxAndScale(ind); + + IndTexMtxInfo info(ind); + rOp(&info); + info.FifoSend(); +} + +void LoadResMatChan( + const ResMatChan chan, u32 maskDiffColor, u32 maskDiffAlpha, u32 maskSpecColor, u32 maskSpecAlpha, GXColor amb, + bool lightOff +) { + if (!chan.IsValid()) { + return; + } + + { + const Chan &r = chan.ref().chan[0]; + + if (r.flag & Chan::FLAG_MAT_COLOR_ENABLE) { + if (r.flag & Chan::FLAG_MAT_ALPHA_ENABLE) { + // @bug Color+Alpha channel is GX_COLOR0A0 + fifo::GDSetChanMatColor(GX_COLOR0, r.matColor); + } else { + fifo::GDSetChanMatColor(GX_COLOR0, r.matColor); + } + } else if (r.flag & Chan::FLAG_MAT_ALPHA_ENABLE) { + // @bug Alpha channel is GX_ALPHA0 + fifo::GDSetChanMatColor(GX_COLOR0, r.matColor); + } + + GXColor ambColor; + ambColor.r = 0.5f + (amb.r * r.ambColor.r) * (1.0f / 255.0f); + ambColor.g = 0.5f + (amb.g * r.ambColor.g) * (1.0f / 255.0f); + ambColor.b = 0.5f + (amb.b * r.ambColor.b) * (1.0f / 255.0f); + ambColor.a = 0.5f + (amb.a * r.ambColor.a) * (1.0f / 255.0f); + + if (r.flag & Chan::FLAG_AMB_COLOR_ENABLE) { + if (r.flag & Chan::FLAG_AMB_ALPHA_ENABLE) { + // @bug Color+Alpha channel is GX_COLOR0A0 + fifo::GDSetChanAmbColor(GX_COLOR0, ambColor); + } else { + fifo::GDSetChanAmbColor(GX_COLOR0, ambColor); + } + } else if (r.flag & Chan::FLAG_AMB_ALPHA_ENABLE) { + // @bug Alpha channel is GX_ALPHA0 + fifo::GDSetChanAmbColor(GX_COLOR0, ambColor); + } + + if (lightOff) { + if (r.flag & Chan::FLAG_CTRL_COLOR_ENABLE) { + fifo::GDSetChanCtrlLightOff(GX_COLOR0, r.paramChanCtrlC, maskDiffColor); + } + + if (r.flag & Chan::FLAG_CTRL_ALPHA_ENABLE) { + fifo::GDSetChanCtrlLightOff(GX_ALPHA0, r.paramChanCtrlA, maskDiffAlpha); + } + } else { + if (r.flag & Chan::FLAG_CTRL_COLOR_ENABLE) { + fifo::GDSetChanCtrl(GX_COLOR0, r.paramChanCtrlC, maskDiffColor); + } + + if (r.flag & Chan::FLAG_CTRL_ALPHA_ENABLE) { + fifo::GDSetChanCtrl(GX_ALPHA0, r.paramChanCtrlA, maskDiffAlpha); + } + } + } + + { + if (sGenMode2.GXGetNumChans() == 2) { + const Chan &r = chan.ref().chan[1]; + + if (r.flag & Chan::FLAG_MAT_COLOR_ENABLE) { + if (r.flag & Chan::FLAG_MAT_ALPHA_ENABLE) { + // @bug Color+Alpha channel is GX_COLOR1A1 + fifo::GDSetChanMatColor(GX_COLOR1, r.matColor); + } else { + fifo::GDSetChanMatColor(GX_COLOR1, r.matColor); + } + } else if (r.flag & Chan::FLAG_MAT_ALPHA_ENABLE) { + // @bug Alpha channel is GX_ALPHA1 + fifo::GDSetChanMatColor(GX_COLOR1, r.matColor); + } + + if (r.flag & Chan::FLAG_AMB_COLOR_ENABLE) { + if (r.flag & Chan::FLAG_AMB_ALPHA_ENABLE) { + // @bug Color+Alpha channel is GX_COLOR1A1 + fifo::GDSetChanAmbColor(GX_COLOR1, r.ambColor); + } else { + fifo::GDSetChanAmbColor(GX_COLOR1, r.ambColor); + } + } else if (r.flag & Chan::FLAG_AMB_ALPHA_ENABLE) { + // @bug Alpha channel is GX_ALPHA1 + fifo::GDSetChanAmbColor(GX_COLOR1, r.ambColor); + } + + if (lightOff) { + if (r.flag & Chan::FLAG_CTRL_COLOR_ENABLE) { + fifo::GDSetChanCtrlLightOff(GX_COLOR1, r.paramChanCtrlC, maskSpecColor); + } + + if (r.flag & Chan::FLAG_CTRL_ALPHA_ENABLE) { + fifo::GDSetChanCtrlLightOff(GX_ALPHA1, r.paramChanCtrlA, maskSpecAlpha); + } + } else { + if (r.flag & Chan::FLAG_CTRL_COLOR_ENABLE) { + fifo::GDSetChanCtrl(GX_COLOR1, r.paramChanCtrlC, maskSpecColor); + } + + if (r.flag & Chan::FLAG_CTRL_ALPHA_ENABLE) { + fifo::GDSetChanCtrl(GX_ALPHA1, r.paramChanCtrlA, maskSpecAlpha); + } + } + } else { + fifo::GDSetChanCtrl(GX_COLOR1, 0, 0); + fifo::GDSetChanCtrl(GX_ALPHA1, 0, 0); + } + } + + sGenMode2.LoadXF(); +} + +void LoadResMatTexCoordGen(const ResMatTexCoordGen gen) { + if (!gen.IsValid()) { + return; + } + + gen.CallDisplayList(sGenMode2.GXGetNumTexGens(), sSyncGX.Get()); + sGenMode2.LoadXF(); +} + +void LoadResTexSrt(const ResTexSrt srt) { + math::MTX34 mtx; + + for (u32 i = 0; i < ResTexSrtData::NUM_OF_TEXTURE; i++) { + if (srt.IsExist(i)) { + bool ident = true; + const TexMtxEffect &rEffect = srt.ref().effect[i]; + + math::MTX34Identity(&mtx); + + if (rEffect.map_mode != 0) { + sScnDependentTexMtxFuncTable.Calc(rEffect.map_mode, &mtx, rEffect.ref_camera, rEffect.ref_light); + + sPreTexMtxState.SetFuncType(i, sScnDependentTexMtxFuncTable.GetFuncType(rEffect.map_mode)); + + ident = false; + } else { + sPreTexMtxState.SetFuncType(i, SCNDEPENDENT_TEXMTX_FUNCTYPE_TEXMTX_NOT_EXIST); + } + + if (!srt.IsIdentity(i)) { + if (ident) { + if (!(rEffect.misc_flag & TexMtxEffect::FLAG_IDENT)) { + ident = false; + + math::MTX34Copy(&mtx, static_cast(&rEffect.effectMtx)); + } + } else { + math::MTX34Mult(&mtx, static_cast(&rEffect.effectMtx), &mtx); + } + + if (rEffect.map_mode == 0) { + CalcTexMtx(&mtx, ident, srt.ref().texSrt[i], srt.GetTexSrtFlag(i), srt.GetTexMtxMode()); + } else { + math::MTX34 srtMtx; + CalcTexMtx(&srtMtx, true, srt.ref().texSrt[i], srt.GetTexSrtFlag(i), srt.GetTexMtxMode()); + + std::swap(srtMtx._02, srtMtx._03); + std::swap(srtMtx._12, srtMtx._13); + + math::MTX34Mult(&mtx, &srtMtx, &mtx); + } + + ident = false; + } + + if (ident) { + if (!sPostTexMtx.IsIdentity(i)) { + math::MTX34 identMtx; + + sPostTexMtx.SetIdentity(i); + math::MTX34Identity(&identMtx); + + GXLoadTexMtxImm(identMtx, i * 3 + GX_DUALMTX0, GX_MTX_3x4); + } + } else { + sPostTexMtx.ResetIdentity(i); + GXLoadTexMtxImm(mtx, i * 3 + GX_DUALMTX0, GX_MTX_3x4); + } + + } else { + sPreTexMtxState.SetFuncType(i, SCNDEPENDENT_TEXMTX_FUNCTYPE_TEXMTX_NOT_EXIST); + } + } +} + +void LoadResShpPrePrimitive(const ResShp shp) { + if (!shp.IsValid()) { + return; + } + + sTexCoordScale.LoadTexCoordScale(sGenMode2.GXGetNumTexGens()); + sGenMode2.LoadXF(); + shp.CallPrePrimitiveDisplayList(sSyncGX.Get(), sShp.IsCacheEqual(shp.ref().cache)); +} + +void LoadResShpPrimitive(const ResShp shp, const math::MTX34 *pViewPos, const math::MTX34 *pViewNrm) { + if (!shp.IsValid()) { + return; + } + + sTexCoordScale.LoadTexCoordScale(sGenMode2.GXGetNumTexGens()); + + int id = shp.ref().curMtxIdx; + bool envelope = (id & ResShpData::ID_FLAG_ENVELOPE) != 0; + + if (!envelope) { + if (pViewPos != NULL) { + GXLoadPosMtxImm(*pViewPos, GX_PNMTX0); + + if (shp.ExistVtxDesc(GX_VA_NRM)) { + if (pViewNrm != NULL) { + GXLoadNrmMtxImm(*pViewNrm, GX_PNMTX0); + } else { + GXLoadNrmMtxImm(*pViewPos, GX_PNMTX0); + } + } + } else { + GXLoadPosMtxIndx(id, GX_PNMTX0); + + if (shp.ExistVtxDesc(GX_VA_NRM)) { + GXLoadNrmMtxIndx3x3(id, GX_PNMTX0); + } + } + + sPreTexMtxState.SetCurrentMtx(id); + } else { + sCurrMtx.SetCurrMtx(); + } + + sGenMode2.LoadXF(); + shp.CallPrimitiveDisplayList(sSyncGX.Get()); + + if (envelope) { + sCurrMtx.Invalidate(); + } +} + +void SetViewPosNrmMtxArray( + const math::MTX34 *pViewPosMtxArray, const math::MTX33 *pViewNrmMtxArray, const math::MTX34 *pViewEnvTexMtxArray +) { + sPosNrmArrayState.SetViewPosNrmMtxArray(pViewPosMtxArray, pViewNrmMtxArray, pViewEnvTexMtxArray); +} + +const math::MTX33 *GetViewNrmMtxPtr(u32 id) { + return sPosNrmArrayState.GetViewNrmMtxPtr(id); +} + +void SetScnDependentTexMtxFunc(u32 id, ScnDependentTexMtxFuncPtr func, ScnDependentTexMtxFuncType type) { + sScnDependentTexMtxFuncTable.SetFunc(id, func, type); +} + +bool GetScnDependentTexMtxFunc(u32 id, ScnDependentTexMtxFuncPtr *pFunc, ScnDependentTexMtxFuncType *pType) { + return sScnDependentTexMtxFuncTable.GetFunc(id, pFunc, pType); +} + +IndMtxOp *GetIndMtxOp() { + return pG3DStateIndMtxOp; +} + +void SetFog(const Fog fog, int id) { + sFogState.SetFog(fog, id); +} + +void LoadFog(int id) { + sFogState.LoadFog(id); +} + +void SetLightSetting(const LightSetting &rSetting) { + sLightState.SetLightSetting(rSetting); +} + +const LightObj *GetLightObj(int id) { + return sLightState.GetLightObj(id); +} + +void LoadLightSet( + int id, u32 *pDiffColorMask, u32 *pDiffAlphaMask, u32 *pSpecColorMask, u32 *pSpecAlphaMask, AmbLightObj *pAmb +) { + sLightState.LoadLightSet(id, pDiffColorMask, pDiffAlphaMask, pSpecColorMask, pSpecAlphaMask, pAmb); +} + +void LoadLightSet(int id, u32 *pDiffMask, u32 *pSpecMask, AmbLightObj *pAmb) { + u32 diffAlphaMask, specAlphaMask; + + sLightState.LoadLightSet(id, pDiffMask, &diffAlphaMask, pSpecMask, &specAlphaMask, pAmb); + + if (pDiffMask != NULL) { + *pDiffMask |= diffAlphaMask; + } + + if (pSpecMask != NULL) { + *pSpecMask |= specAlphaMask; + } +} + +void SetCameraProjMtx(const Camera &rCam, int id, bool view) { + sCameraMtxState.SetCameraProjMtx(rCam, id, view); +} + +const math::MTX34 *GetCameraMtxPtr() { + return sCameraMtxState.GetCameraMtxPtr(); +} + +const math::MTX34 *GetInvCameraMtxPtr() { + return sCameraMtxState.GetInvCameraMtxPtr(); +} + +const math::MTX34 *GetCameraMtxPtr(int id) { + return sCameraMtxState.GetCameraMtxPtr(id); +} + +const math::MTX34 *GetProjectionTexMtxPtr() { + return sCameraMtxState.GetProjectionTexMtxPtr(); +} + +const math::MTX34 *GetProjectionTexMtxPtr(int id) { + return sCameraMtxState.GetProjectionTexMtxPtr(id); +} + +const math::MTX34 *GetEnvironmentTexMtxPtr() { + return sCameraMtxState.GetEnvironmentTexMtxPtr(); +} + +void SetRenderModeObj(const GXRenderModeObj &rObj) { + sRenderMode = rObj; +} + +const GXRenderModeObj *GetRenderModeObj() { + return &sRenderMode; +} + +void Invalidate(u32 flag) { + if (flag & INVALIDATE_TEX) { + sTex.Invalidate(); + sTexCoordScale.Invalidate(); + } + + if (flag & INVALIDATE_TLUT) { + sTlut.Invalidate(); + } + + if (flag & INVALIDATE_TEV) { + sTexCoordScale.Invalidate(); + sTev.Invalidate(); + } + + if (flag & INVALIDATE_GENMODE) { + sGenMode2.Invalidate(); + } + + if (flag & INVALIDATE_SHP) { + sShp.Invalidate(); + } + + if (flag & INVALIDATE_CURRMTX) { + sCurrMtx.Invalidate(); + } + + if (flag & INVALIDATE_TEXMTX) { + // @bug Missing PreTexMtxState::Invalidate + sPostTexMtx.Invalidate(); + } + + if (flag & INVALIDATE_MISC) { + sMisc.Invalidate(); + } + + if (flag & INVALIDATE_FOG) { + sFogState.Invalidate(); + } + + if (flag & INVALIDATE_LIGHT) { + sLightState.Invalidate(); + } + + if (flag & INVALIDATE_POSMTX) { + sPosNrmArrayState.Invalidate(); + } + + sSyncGX.Invalidate(); +} + +/****************************************************************************** + * + * IndMtxOpStd + * + ******************************************************************************/ +IndMtxOpStd::IndMtxOpStd() { + math::MTX34Identity(&mIndMtx[GX_ITM_0 - 1]); + math::MTX34Identity(&mIndMtx[GX_ITM_1 - 1]); + math::MTX34Identity(&mIndMtx[GX_ITM_2 - 1]); + + mIsValidMtx[GX_ITM_0 - 1] = mIsValidMtx[GX_ITM_1 - 1] = mIsValidMtx[GX_ITM_2 - 1] = false; + + PADDING_0x7 = 0; +} + +void IndMtxOpStd::SetNrmMapMtx( + GXIndTexMtxID id, const math::VEC3 *pLightVec, const math::MTX34 *pNrmMtx, ResMatMiscData::IndirectMethod method +) { + if (id >= GX_ITM_0 && id <= GX_ITM_2 && method != ResMatMiscData::WARP) { + u32 i = id - GX_ITM_0; + mIsValidMtx[i] = true; + + if (pLightVec != NULL) { + mIndMtx[i]._00 = 0.5f * -pLightVec->x; + mIndMtx[i]._01 = 0.5f * -pLightVec->y; + mIndMtx[i]._02 = 0.5f * -pLightVec->z; + + if (method == ResMatMiscData::NORMAL_MAP_SPECULAR) { + math::VEC3 H(pLightVec->x, pLightVec->y, pLightVec->z - 1.0f); + math::VEC3Normalize(&H, &H); + + mIndMtx[i]._10 = 0.5f * -H.x; + mIndMtx[i]._11 = 0.5f * -H.y; + mIndMtx[i]._12 = 0.5f * -H.z; + } else { + mIndMtx[i]._10 = mIndMtx[i]._11 = mIndMtx[i]._12 = 0.0f; + } + + math::MTX34Mult(&mIndMtx[i], &mIndMtx[i], pNrmMtx); + } else { + math::MTX34Zero(&mIndMtx[i]); + } + } +} + +void IndMtxOpStd::Reset() { + math::MTX34Identity(&mIndMtx[GX_ITM_0 - 1]); + math::MTX34Identity(&mIndMtx[GX_ITM_1 - 1]); + math::MTX34Identity(&mIndMtx[GX_ITM_2 - 1]); + + mIsValidMtx[GX_ITM_0 - 1] = mIsValidMtx[GX_ITM_1 - 1] = mIsValidMtx[GX_ITM_2 - 1] = false; +} + +void IndMtxOpStd::operator()(IndTexMtxInfo *pInfo) { + if (mIsValidMtx[GX_ITM_0 - 1]) { + pInfo->SetMtx(GX_ITM_0, mIndMtx[GX_ITM_0 - 1]); + } + + if (mIsValidMtx[GX_ITM_1 - 1]) { + pInfo->SetMtx(GX_ITM_1, mIndMtx[GX_ITM_1 - 1]); + } + + if (mIsValidMtx[GX_ITM_2 - 1]) { + pInfo->SetMtx(GX_ITM_2, mIndMtx[GX_ITM_2 - 1]); + } +} + +} // namespace G3DState +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_workmem.cpp b/src/nw4r/g3d/g3d_workmem.cpp new file mode 100644 index 00000000..b23539dd --- /dev/null +++ b/src/nw4r/g3d/g3d_workmem.cpp @@ -0,0 +1,51 @@ +#include + +namespace nw4r { +namespace g3d { +namespace detail { +namespace workmem { +namespace { + +union { + u8 mem[WORKMEM_SIZE]; // at 0x0 + struct { + math::_VEC3 tmpScale[WORKMEM_NUMTMPSCALE]; // at 0x0 + u32 mtxID[WORKMEM_NUMMTXID]; // at 0x6000 + }; + u8 byteCode[WORKMEM_NUMBYTECODE]; // at 0x0 + MdlZ mdlZ[WORKMEM_NUMMDLZ]; // at 0x0 + math::_MTX34 skinningMtx[WORKMEM_NUMSKINNINGMTX]; // at 0x0 + math::_MTX34 bbMtx[WORKMEM_NUMBBMTX]; // at 0x0 + u8 shpAnmResultBuf[WORKMEM_NUMSHPANMRESULT]; // at 0x0 +} sTemp ALIGN_DECL(128); + +} // namespace + +math::VEC3 *GetScaleTemporary() { + return static_cast(sTemp.tmpScale); +} + +u32 *GetMtxIDTemporary() { + return sTemp.mtxID; +} + +MdlZ *GetMdlZTemporary() { + return sTemp.mdlZ; +} + +math::MTX34 *GetSkinningMtxTemporary() { + return static_cast(sTemp.skinningMtx); +} + +math::MTX34 *GetBillboardMtxTemporary() { + return static_cast(sTemp.bbMtx); +} + +ShpAnmResultBuf *GetShpAnmResultBufTemporary() { + return reinterpret_cast(sTemp.shpAnmResultBuf); +} + +} // namespace workmem +} // namespace detail +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/g3d_xsi.cpp b/src/nw4r/g3d/g3d_xsi.cpp new file mode 100644 index 00000000..3847e62f --- /dev/null +++ b/src/nw4r/g3d/g3d_xsi.cpp @@ -0,0 +1,379 @@ +#include + +namespace nw4r { +namespace g3d { +namespace detail { +namespace dcc { +namespace { + +void MakeTexSrtMtx_S(math::MTX34* pMtx, const TexSrt& rSrt) { + pMtx->_00 = rSrt.Su; + pMtx->_01 = 0.0f; + pMtx->_02 = 0.0f; + pMtx->_03 = 0.0f; + + pMtx->_10 = 0.0f; + pMtx->_11 = rSrt.Sv; + pMtx->_12 = 0.0f; + pMtx->_13 = 1.0f - rSrt.Sv; +} + +void MakeTexSrtMtx_R(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + pMtx->_00 = cosR; + pMtx->_01 = -sinR; + pMtx->_02 = 0.0f; + pMtx->_03 = sinR; + + pMtx->_10 = sinR; + pMtx->_11 = cosR; + pMtx->_12 = 0.0f; + pMtx->_13 = 1.0f - cosR; +} + +void MakeTexSrtMtx_T(math::MTX34* pMtx, const TexSrt& rSrt) { + pMtx->_00 = 1.0f; + pMtx->_01 = 0.0f; + pMtx->_02 = 0.0f; + pMtx->_03 = -rSrt.Tu; + + pMtx->_10 = 0.0f; + pMtx->_11 = 1.0f; + pMtx->_12 = 0.0f; + pMtx->_13 = rSrt.Tv; +} + +void MakeTexSrtMtx_SR(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sucr = rSrt.Su * cosR; + f32 susr = rSrt.Su * sinR; + f32 svcr = rSrt.Sv * cosR; + f32 svsr = rSrt.Sv * sinR; + + pMtx->_00 = sucr; + pMtx->_01 = -susr; + pMtx->_02 = 0.0f; + pMtx->_03 = susr; + + pMtx->_10 = svsr; + pMtx->_11 = svcr; + pMtx->_12 = 0.0f; + pMtx->_13 = -svcr + 1.0f; +} + +void MakeTexSrtMtx_RT(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + pMtx->_00 = cosR; + pMtx->_01 = -sinR; + pMtx->_02 = 0.0f; + pMtx->_03 = (sinR - cosR * rSrt.Tu) - sinR * rSrt.Tv; + + pMtx->_10 = sinR; + pMtx->_11 = cosR; + pMtx->_12 = 0.0f; + pMtx->_13 = (-cosR - sinR * rSrt.Tu) + cosR * rSrt.Tv + 1.0f; +} + +void MakeTexSrtMtx_ST(math::MTX34* pMtx, const TexSrt& rSrt) { + pMtx->_00 = rSrt.Su; + pMtx->_01 = 0.0f; + pMtx->_02 = 0.0f; + pMtx->_03 = -rSrt.Su * rSrt.Tu; + + pMtx->_10 = 0.0f; + pMtx->_11 = rSrt.Sv; + pMtx->_12 = 0.0f; + pMtx->_13 = rSrt.Sv * (rSrt.Tv - 1.0f) + 1.0f; +} + +void MakeTexSrtMtx_SRT(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sucr = rSrt.Su * cosR; + f32 susr = rSrt.Su * sinR; + f32 svcr = rSrt.Sv * cosR; + f32 svsr = rSrt.Sv * sinR; + + pMtx->_00 = sucr; + pMtx->_01 = -susr; + pMtx->_02 = 0.0f; + pMtx->_03 = (susr - sucr * rSrt.Tu) - susr * rSrt.Tv; + + pMtx->_10 = svsr; + pMtx->_11 = svcr; + pMtx->_12 = 0.0f; + pMtx->_13 = (-svcr - svsr * rSrt.Tu) + svcr * rSrt.Tv + 1.0f; +} + +void ProductTexSrtMtx_S(math::MTX34* pMtx, const TexSrt& rSrt) { + pMtx->_00 *= rSrt.Su; + pMtx->_01 *= rSrt.Su; + pMtx->_02 *= rSrt.Su; + pMtx->_03 *= rSrt.Su; + + pMtx->_10 *= rSrt.Sv; + pMtx->_11 *= rSrt.Sv; + pMtx->_12 *= rSrt.Sv; + pMtx->_13 = rSrt.Sv * (pMtx->_13 - 1.0f) + 1.0f; +} + +void ProductTexSrtMtx_R(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + f32 _0x, _1x; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + _0x = cosR * pMtx->_00 - sinR * pMtx->_10; + _1x = sinR * pMtx->_00 + cosR * pMtx->_10; + pMtx->_00 = _0x; + pMtx->_10 = _1x; + + _0x = cosR * pMtx->_01 - sinR * pMtx->_11; + _1x = sinR * pMtx->_01 + cosR * pMtx->_11; + pMtx->_01 = _0x; + pMtx->_11 = _1x; + + _0x = cosR * pMtx->_02 - sinR * pMtx->_12; + _1x = sinR * pMtx->_02 + cosR * pMtx->_12; + pMtx->_02 = _0x; + pMtx->_12 = _1x; + + _0x = cosR * pMtx->_03 - sinR * pMtx->_13 + sinR; + _1x = sinR * pMtx->_03 + cosR * pMtx->_13 - cosR + 1.0f; + pMtx->_03 = _0x; + pMtx->_13 = _1x; +} + +void ProductTexSrtMtx_T(math::MTX34* pMtx, const TexSrt& rSrt) { + pMtx->_03 -= rSrt.Tu; + pMtx->_13 += rSrt.Tv; +} + +void ProductTexSrtMtx_SR(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + f32 _0x, _1x; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sucr = rSrt.Su * cosR; + f32 susr = rSrt.Su * sinR; + f32 svcr = rSrt.Sv * cosR; + f32 svsr = rSrt.Sv * sinR; + + _0x = sucr * pMtx->_00 - susr * pMtx->_10; + _1x = svsr * pMtx->_00 + svcr * pMtx->_10; + pMtx->_00 = _0x; + pMtx->_10 = _1x; + + _0x = sucr * pMtx->_01 - susr * pMtx->_11; + _1x = svsr * pMtx->_01 + svcr * pMtx->_11; + pMtx->_01 = _0x; + pMtx->_11 = _1x; + + _0x = sucr * pMtx->_02 - susr * pMtx->_12; + _1x = svsr * pMtx->_02 + svcr * pMtx->_12; + pMtx->_02 = _0x; + pMtx->_12 = _1x; + + _0x = sucr * pMtx->_03 - susr * pMtx->_13 + susr; + _1x = svsr * pMtx->_03 + svcr * pMtx->_13 - svcr + 1.0f; + + pMtx->_03 = _0x; + pMtx->_13 = _1x; +} + +void ProductTexSrtMtx_RT(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + f32 _0x, _1x; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + _0x = cosR * pMtx->_00 - sinR * pMtx->_10; + _1x = sinR * pMtx->_00 + cosR * pMtx->_10; + pMtx->_00 = _0x; + pMtx->_10 = _1x; + + _0x = cosR * pMtx->_01 - sinR * pMtx->_11; + _1x = sinR * pMtx->_01 + cosR * pMtx->_11; + pMtx->_01 = _0x; + pMtx->_11 = _1x; + + _0x = cosR * pMtx->_02 - sinR * pMtx->_12; + _1x = sinR * pMtx->_02 + cosR * pMtx->_12; + pMtx->_02 = _0x; + pMtx->_12 = _1x; + + // clang-format off + _0x = cosR * (pMtx->_03 - rSrt.Tu) + - sinR * (pMtx->_13 + rSrt.Tv) + + sinR; + + _1x = sinR * (pMtx->_03 - rSrt.Tu) + + cosR * (pMtx->_13 + rSrt.Tv) + - cosR + 1.0f; + // clang-format on + + pMtx->_03 = _0x; + pMtx->_13 = _1x; +} + +void ProductTexSrtMtx_ST(math::MTX34* pMtx, const TexSrt& rSrt) { + pMtx->_00 *= rSrt.Su; + pMtx->_01 *= rSrt.Su; + pMtx->_02 *= rSrt.Su; + pMtx->_03 = (pMtx->_03 - rSrt.Tu) * rSrt.Su; + + pMtx->_10 *= rSrt.Sv; + pMtx->_11 *= rSrt.Sv; + pMtx->_12 *= rSrt.Sv; + pMtx->_13 = (pMtx->_13 + rSrt.Tv - 1.0f) * rSrt.Sv + 1.0f; +} + +void ProductTexSrtMtx_SRT(math::MTX34* pMtx, const TexSrt& rSrt) { + f32 sinR, cosR; + f32 _0x, _1x; + math::SinCosDeg(&sinR, &cosR, rSrt.R); + + f32 sucr = rSrt.Su * cosR; + f32 susr = rSrt.Su * sinR; + f32 svcr = rSrt.Sv * cosR; + f32 svsr = rSrt.Sv * sinR; + + _0x = sucr * pMtx->_00 - susr * pMtx->_10; + _1x = svsr * pMtx->_00 + svcr * pMtx->_10; + pMtx->_00 = _0x; + pMtx->_10 = _1x; + + _0x = sucr * pMtx->_01 - susr * pMtx->_11; + _1x = svsr * pMtx->_01 + svcr * pMtx->_11; + pMtx->_01 = _0x; + pMtx->_11 = _1x; + + _0x = sucr * pMtx->_02 - susr * pMtx->_12; + _1x = svsr * pMtx->_02 + svcr * pMtx->_12; + pMtx->_02 = _0x; + pMtx->_12 = _1x; + + // clang-format off + _0x = sucr * (pMtx->_03 - rSrt.Tu) + - susr * (pMtx->_13 + rSrt.Tv) + + susr; + + _1x = svsr * (pMtx->_03 - rSrt.Tu) + + svcr * (pMtx->_13 + rSrt.Tv) + - svcr + 1.0f; + // clang-format on + + pMtx->_03 = _0x; + pMtx->_13 = _1x; +} + +} // namespace + +typedef void (*CalcTexMtxFunc)(math::MTX34* pMtx, const TexSrt& rSrt); + +bool CalcTexMtx_Xsi(math::MTX34* pMtx, bool set, const TexSrt& rSrt, + TexSrt::Flag flag) { + // Extract S/R/T flags + u32 index = flag >> 1 & 0b111; + + // Scale-one, no rotate/trans + if (index == 0b111) { + return false; + } + + if (set) { + static const CalcTexMtxFunc funcTable[] = { + MakeTexSrtMtx_SRT, // 0 0 0 + MakeTexSrtMtx_RT, // 0 0 1 + MakeTexSrtMtx_ST, // 0 1 0 + MakeTexSrtMtx_T, // 0 1 1 + MakeTexSrtMtx_SR, // 1 0 0 + MakeTexSrtMtx_R, // 1 0 1 + MakeTexSrtMtx_S // 1 1 0 + }; + + funcTable[index](pMtx, rSrt); + } else { + static const CalcTexMtxFunc funcTable[] = { + ProductTexSrtMtx_SRT, // 0 0 0 + ProductTexSrtMtx_RT, // 0 0 1 + ProductTexSrtMtx_ST, // 0 1 0 + ProductTexSrtMtx_T, // 0 1 1 + ProductTexSrtMtx_SR, // 1 0 0 + ProductTexSrtMtx_R, // 1 0 1 + ProductTexSrtMtx_S // 1 1 0 + }; + + funcTable[index](pMtx, rSrt); + } + + pMtx->_20 = 0.0f; + pMtx->_21 = 0.0f; + pMtx->_22 = 1.0f; + pMtx->_23 = 0.0f; + + return true; +} + +u32 CalcWorldMtx_Xsi(math::MTX34* pW, math::VEC3* pS, const math::MTX34* pW1, + const math::VEC3* pS1, u32 attr, + const ChrAnmResult* pResult) { + u32 flag = pResult->flags; + u32 newAttr = attr; + + if (flag & ChrAnmResult::FLAG_SCALE_ONE) { + newAttr = detail::WorldMtxAttr::AnmScaleOne(newAttr); + *pS = *pS1; + } else { + newAttr = detail::WorldMtxAttr::AnmNotScaleOne(newAttr); + pS->x = pS1->x * pResult->s.x; + pS->y = pS1->y * pResult->s.y; + pS->z = pS1->z * pResult->s.z; + } + + if ((flag & ChrAnmResult::FLAG_MTX_IDENT) || + (flag & ChrAnmResult::FLAG_ROT_TRANS_ZERO)) { + + math::MTX34Copy(pW, pW1); + } else if (flag & ChrAnmResult::FLAG_ROT_ZERO) { + + if (detail::WorldMtxAttr::IsAllScaleOne(attr)) { + math::VEC3 trans(pResult->rt._03, pResult->rt._13, pResult->rt._23); + + math::MTX34Trans(pW, pW1, &trans); + } else { + math::VEC3 trans(pS1->x * pResult->rt._03, pS1->y * pResult->rt._13, + pS1->z * pResult->rt._23); + + math::MTX34Trans(pW, pW1, &trans); + } + } else if (detail::WorldMtxAttr::IsAllScaleOne(attr)) { + math::MTX34Mult(pW, pW1, &pResult->rt); + } else { + math::MTX34Copy(pW, &pResult->rt); + + pW->_03 *= pS1->x; + pW->_13 *= pS1->y; + pW->_23 *= pS1->z; + + math::MTX34Mult(pW, pW1, pW); + } + + if (flag & ChrAnmResult::FLAG_SCALE_UNIFORM) { + newAttr = detail::WorldMtxAttr::AnmScaleUniform(newAttr); + } else { + newAttr = detail::WorldMtxAttr::AnmNotScaleUniform(newAttr); + } + + return newAttr; +} + +} // namespace dcc +} // namespace detail +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/platform/g3d_cpu.cpp b/src/nw4r/g3d/platform/g3d_cpu.cpp new file mode 100644 index 00000000..011c113b --- /dev/null +++ b/src/nw4r/g3d/platform/g3d_cpu.cpp @@ -0,0 +1,51 @@ +#include + +namespace nw4r { +namespace g3d { +namespace detail { + +void Copy32ByteBlocks(register void *pDst, register const void *pSrc, register u32 size) { + register f32 work0, work1, work2, work3; + + for (size /= 32; size > 0; size--) { + // clang-format off + asm { + lfd work0, 0(pSrc) + stfd work0, 0(pDst) + + lfd work1, 8(pSrc) + stfd work1, 8(pDst) + + lfd work2, 16(pSrc) + stfd work2, 16(pDst) + + lfd work3, 24(pSrc) + stfd work3, 24(pDst) + } + // clang-format on + + pDst = static_cast(pDst) + 32; + pSrc = static_cast(pSrc) + 32; + } +} + +void ZeroMemory32ByteBlocks(register void *pDst, register u32 size) { + register f32 zero = 0.0f; + + for (size /= 32; size > 0; size--) { + // clang-format off + asm { + psq_st zero, 0(pDst), 0, 0 + psq_st zero, 8(pDst), 0, 0 + psq_st zero, 16(pDst), 0, 0 + psq_st zero, 24(pDst), 0, 0 + } + // clang-format on + + pDst = static_cast(pDst) + 32; + } +} + +} // namespace detail +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/platform/g3d_gpu.cpp b/src/nw4r/g3d/platform/g3d_gpu.cpp new file mode 100644 index 00000000..fb4788e9 --- /dev/null +++ b/src/nw4r/g3d/platform/g3d_gpu.cpp @@ -0,0 +1,212 @@ +#include + +namespace nw4r { +namespace g3d { +namespace fifo { + +void GDSetGenMode2(u8 numTexGens, u8 numChans, u8 numTevs, u8 numInds, GXCullMode cullMode) { + // clang-format off + // @note NUMCOLORS is actually three bits + LoadBPCmd(GX_BP_REG_SSMASK << GX_BP_OPCODE_SHIFT | + GX_BP_GENMODE_NUMTEX_MASK | + 0b11 << GX_BP_GENMODE_NUMCOLORS_SHIFT | + GX_BP_GENMODE_NUMTEVSTAGES_MASK | + GX_BP_GENMODE_CULLMODE_MASK | + GX_BP_GENMODE_NUMINDSTAGES_MASK); + // clang-format on + + // clang-format off + LoadBPCmd( + numTexGens << GX_BP_GENMODE_NUMTEX_SHIFT | + numChans << GX_BP_GENMODE_NUMCOLORS_SHIFT | + numTevs - 1 << GX_BP_GENMODE_NUMTEVSTAGES_SHIFT | + cm2hw[cullMode] << GX_BP_GENMODE_CULLMODE_SHIFT | + numInds << GX_BP_GENMODE_NUMINDSTAGES_SHIFT | + GX_BP_REG_GENMODE << GX_BP_OPCODE_SHIFT); + // clang-format on + + LoadXFCmd(GX_XF_REG_NUMCOLORS, numChans); + LoadXFCmd(GX_XF_REG_NUMTEX, numTexGens); +} + +void GDSetCullMode(GXCullMode cullMode) { + // clang-format off + LoadBPCmd(GX_BP_REG_SSMASK << GX_BP_OPCODE_SHIFT | + GX_BP_GENMODE_CULLMODE_MASK); + // clang-format on + + LoadBPCmd(cm2hw[cullMode] << GX_BP_GENMODE_CULLMODE_SHIFT); +} + +void GDSetTexCoordScale2( + GXTexCoordID coord, u16 scaleS, GXBool biasS, GXBool wrapS, u16 scaleT, GXBool biasT, GXBool wrapT +) { + // clang-format off + LoadBPCmd(GX_BP_REG_SSMASK << GX_BP_OPCODE_SHIFT | + GX_BP_SU_SIZE_SCALE_MASK | + GX_BP_SU_SIZE_RANGEBIAS_MASK | + GX_BP_SU_SIZE_CYLINDRICWRAP_MASK); + // clang-format on + + // clang-format off + LoadBPCmd( + scaleS - 1 << GX_BP_SU_SIZE_SCALE_SHIFT | + biasS << GX_BP_SU_SIZE_RANGEBIAS_SHIFT | + wrapS << GX_BP_SU_SIZE_CYLINDRICWRAP_SHIFT | + GX_BP_REG_SU_SSIZE0 + coord * 2 << GX_BP_OPCODE_SHIFT); + // clang-format on + + // clang-format off + LoadBPCmd( + scaleT - 1 << GX_BP_SU_SIZE_SCALE_SHIFT | + biasT << GX_BP_SU_SIZE_RANGEBIAS_SHIFT | + wrapT << GX_BP_SU_SIZE_CYLINDRICWRAP_SHIFT | + GX_BP_REG_SU_TSIZE0 + coord * 2 << GX_BP_OPCODE_SHIFT); + // clang-format on +} + +void GDSetIndTexMtx(u32 id, const math::MTX34 &rMtx) { + f32 m00, m01, m02, m10, m11, m12; + f32 a00, a01, a02, a10, a11, a12; + + s8 scaleExp = 0; + + m00 = rMtx._00; + m01 = rMtx._01; + m02 = rMtx._02; + m10 = rMtx._10; + m11 = rMtx._11; + m12 = rMtx._12; + + a00 = math::FAbs(m00); + a01 = math::FAbs(m01); + a02 = math::FAbs(m02); + a10 = math::FAbs(m10); + a11 = math::FAbs(m11); + a12 = math::FAbs(m12); + + if (a00 >= 1.0f || a01 >= 1.0f || a02 >= 1.0f || a10 >= 1.0f || a11 >= 1.0f || a12 >= 1.0f) { + do { + if (scaleExp >= 46) { + break; + } + + scaleExp++; + + m00 /= 2.0f; + m01 /= 2.0f; + m02 /= 2.0f; + m10 /= 2.0f; + m11 /= 2.0f; + m12 /= 2.0f; + + a00 /= 2.0f; + a01 /= 2.0f; + a02 /= 2.0f; + a10 /= 2.0f; + a11 /= 2.0f; + a12 /= 2.0f; + } while (a00 >= 1.0f || a01 >= 1.0f || a02 >= 1.0f || a10 >= 1.0f || a11 >= 1.0f || a12 >= 1.0f); + + } else if (a00 < 0.5f && a01 < 0.5f && a02 < 0.5f && a10 < 0.5f && a11 < 0.5f && a12 < 0.5f) { + do { + scaleExp--; + + m00 *= 2.0f; + m01 *= 2.0f; + m02 *= 2.0f; + m10 *= 2.0f; + m11 *= 2.0f; + m12 *= 2.0f; + + a00 *= 2.0f; + a01 *= 2.0f; + a02 *= 2.0f; + a10 *= 2.0f; + a11 *= 2.0f; + a12 *= 2.0f; + + if (!(a00 < 0.5f) || !(a01 < 0.5f) || !(a02 < 0.5f) || !(a10 < 0.5f) || !(a11 < 0.5f) || !(a12 < 0.5f)) { + break; + } + + } while (scaleExp > -17); + } + + // Hardware stores as -17 + scaleExp += 17; + + // clang-format off + LoadBPCmd( + static_cast((static_cast(1024.0f * m00) & GX_BP_INDMTXA_M00_LMASK) << GX_BP_INDMTXA_M00_SHIFT) | + static_cast((static_cast(1024.0f * m10) & GX_BP_INDMTXA_M10_LMASK) << GX_BP_INDMTXA_M10_SHIFT) | + static_cast((scaleExp >> 0 & GX_BP_INDMTXA_EXP_LMASK) << GX_BP_INDMTXA_EXP_SHIFT) | + static_cast(id + GX_BP_REG_INDMTX0A << GX_BP_OPCODE_SHIFT)); + + LoadBPCmd( + static_cast((static_cast(1024.0f * m01) & GX_BP_INDMTXB_M01_LMASK) << GX_BP_INDMTXB_M01_SHIFT) | + static_cast((static_cast(1024.0f * m11) & GX_BP_INDMTXB_M11_LMASK) << GX_BP_INDMTXB_M11_SHIFT) | + static_cast((scaleExp >> 2 & GX_BP_INDMTXB_EXP_LMASK) << GX_BP_INDMTXB_EXP_SHIFT) | + static_cast((id + GX_BP_REG_INDMTX0B << GX_BP_OPCODE_SHIFT))); + + LoadBPCmd( + static_cast((static_cast(1024.0f * m02) & GX_BP_INDMTXC_M02_LMASK) << GX_BP_INDMTXC_M02_SHIFT) | + static_cast((static_cast(1024.0f * m12) & GX_BP_INDMTXC_M12_LMASK) << GX_BP_INDMTXC_M12_SHIFT) | + static_cast((scaleExp >> 4 & GX_BP_INDMTXC_EXP_LMASK) << GX_BP_INDMTXC_EXP_SHIFT) | + static_cast(id + GX_BP_REG_INDMTX0C << GX_BP_OPCODE_SHIFT)); + // clang-format on +} + +void GDResetCurrentMtx() { + u32 regA = GX_PNMTX0 << GX_CP_MATRIXINDEXA_POSNRM_SHIFT | GX_TEXMTX_IDENT << GX_CP_MATRIXINDEXA_TEX0_SHIFT | + GX_TEXMTX_IDENT << GX_CP_MATRIXINDEXA_TEX1_SHIFT | GX_TEXMTX_IDENT << GX_CP_MATRIXINDEXA_TEX2_SHIFT | + GX_TEXMTX_IDENT << GX_CP_MATRIXINDEXA_TEX3_SHIFT; + + u32 regB = GX_TEXMTX_IDENT << GX_CP_MATRIXINDEXB_TEX4_SHIFT | GX_TEXMTX_IDENT << GX_CP_MATRIXINDEXB_TEX5_SHIFT | + GX_TEXMTX_IDENT << GX_CP_MATRIXINDEXB_TEX6_SHIFT | GX_TEXMTX_IDENT << GX_CP_MATRIXINDEXB_TEX7_SHIFT; + + LoadCPCmd(GX_CP_REG_MATRIXINDEXA, regA); + LoadCPCmd(GX_CP_REG_MATRIXINDEXB, regB); + + LoadXFCmdHdr(GX_XF_REG_MATRIXINDEX0, 2); + GXCmd1u32(regA); + GXCmd1u32(regB); +} + +void GDSetCurrentMtx(const u32 *pIdArray) { + u32 regA = pIdArray[0] << GX_CP_MATRIXINDEXA_TEX0_SHIFT | pIdArray[1] << GX_CP_MATRIXINDEXA_TEX1_SHIFT | + pIdArray[2] << GX_CP_MATRIXINDEXA_TEX2_SHIFT | pIdArray[3] << GX_CP_MATRIXINDEXA_TEX3_SHIFT; + + u32 regB = pIdArray[4] << GX_CP_MATRIXINDEXB_TEX4_SHIFT | pIdArray[5] << GX_CP_MATRIXINDEXB_TEX5_SHIFT | + pIdArray[6] << GX_CP_MATRIXINDEXB_TEX6_SHIFT | pIdArray[7] << GX_CP_MATRIXINDEXB_TEX7_SHIFT; + + LoadXFCmdHdr(GX_XF_REG_MATRIXINDEX0, 2); + GXCmd1u32(regA); + GXCmd1u32(regB); +} + +void GDLoadTexMtxImm3x3(const math::MTX33 &rMtx, u32 id) { + math::MTX34 mtx; + const math::MTX33 *pMtx = &rMtx; + + mtx._00 = pMtx->_00; + mtx._01 = pMtx->_01; + mtx._02 = pMtx->_02; + mtx._03 = 0.0f; + + mtx._10 = pMtx->_10; + mtx._11 = pMtx->_11; + mtx._12 = pMtx->_12; + mtx._13 = 0.0f; + + mtx._20 = pMtx->_20; + mtx._21 = pMtx->_21; + mtx._22 = pMtx->_22; + mtx._23 = 0.0f; + + GXLoadTexMtxImm(mtx, id, GX_MTX_3x4); +} + +} // namespace fifo +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/platform/g3d_tmem.cpp b/src/nw4r/g3d/platform/g3d_tmem.cpp new file mode 100644 index 00000000..f3d2662b --- /dev/null +++ b/src/nw4r/g3d/platform/g3d_tmem.cpp @@ -0,0 +1,305 @@ +#include + +// TODO: Naming +enum TMemCachePlan { + TMEM_CACHE_NONE, + + TMEM_CACHE_PLAN_0, + TMEM_CACHE_PLAN_1, + TMEM_CACHE_PLAN_2, + + TMEM_CACHE_MAX +}; + +enum TexRegionID { + TEX_REGION_DEFAULT, + TEX_REGION_DEFAULT_MIPMAP, + + TEX_REGION_CI, + TEX_REGION_CI_MIPMAP, + + TEX_REGION_RGBA8, + TEX_REGION_RGBA8_MIPMAP, + + TEX_REGION_MAX +}; + +struct TexRegionAddr { + u32 addrDefaultEven[GX_MAX_TEXMAP]; // at 0x0 + u32 addrDefaultMipMapEven[GX_MAX_TEXMAP]; // at 0x20 + u32 addrDefaultMipMapOdd[GX_MAX_TEXMAP]; // at 0x40 + + u32 addrCiEven[GX_MAX_TEXMAP]; // at 0x60 + u32 addrCiMipMapEven[GX_MAX_TEXMAP]; // at 0x80 + u32 addrCiMipMapOdd[GX_MAX_TEXMAP]; // at 0xA0 + + u32 addrRgba8Even[GX_MAX_TEXMAP]; // at 0xC0 + u32 addrRgba8Odd[GX_MAX_TEXMAP]; // at 0xE0 + u32 addrRgba8MipMapEven[GX_MAX_TEXMAP]; // at 0x100 + u32 addrRgba8MipMapOdd[GX_MAX_TEXMAP]; // at 0x120 +}; + +struct TexRegionSize { + u32 sizeDefaultEven[GX_MAX_TEXMAP]; // at 0x0 + u32 sizeDefaultMipMapEven[GX_MAX_TEXMAP]; // at 0x20 + u32 sizeDefaultMipMapOdd[GX_MAX_TEXMAP]; // at 0x40 + + u32 sizeCiEven[GX_MAX_TEXMAP]; // at 0x60 + u32 sizeCiMipMapEven[GX_MAX_TEXMAP]; // at 0x80 + u32 sizeCiMipMapOdd[GX_MAX_TEXMAP]; // at 0xA0 + + u32 sizeRgba8Even[GX_MAX_TEXMAP]; // at 0xC0 + u32 sizeRgba8Odd[GX_MAX_TEXMAP]; // at 0xE0 + u32 sizeRgba8MipMapEven[GX_MAX_TEXMAP]; // at 0x100 + u32 sizeRgba8MipMapOdd[GX_MAX_TEXMAP]; // at 0x120 +}; + +static GXTexRegion saaTexRegion[TEX_REGION_MAX][GX_MAX_TEXMAP]; +static GXTlutRegion saaTlutRegion[GX_BIGTLUT3 + 1]; + +static TMemCachePlan sTMemCachePlan = TMEM_CACHE_NONE; +static u32 sTlutRegionNum = 0; + +static GXTexRegionCallback sfpDefaultTexRegionCallback = NULL; +static GXTlutRegionCallback sfpDefaultTlutRegionCallback = NULL; + +// clang-format off +static const TexRegionAddr scaaaTexRegionAddr[TMEM_CACHE_MAX - 1] = { + // TMEM_CACHE_PLAN_0 + { + {0x00000, 0x40000, 0x50000, 0x60000, 0x70000, 0x30000, 0x20000, 0x10000}, // addrDefaultEven + {0x00000, 0xB0000, 0x50000, 0x90000, 0x70000, 0xB0000, 0x20000, 0x90000}, // addrDefaultMipMapEven + {0x80000, 0x40000, 0xA0000, 0x60000, 0x80000, 0x30000, 0xA0000, 0x10000}, // addrDefaultMipMapOdd + {0x00000, 0x40000, 0x50000, 0x60000, 0x70000, 0x30000, 0x20000, 0x10000}, // addrCiEven + {0x00000, 0x40000, 0x50000, 0x60000, 0x70000, 0x30000, 0x20000, 0x10000}, // addrCiMipMapEven + {0x20000, 0x48000, 0x58000, 0x68000, 0x78000, 0x38000, 0x28000, 0x18000}, // addrCiMipMapOdd + {0x00000, 0xB0000, 0x50000, 0x90000, 0x70000, 0xB0000, 0x20000, 0x90000}, // addrRgba8Even + {0x80000, 0x40000, 0xA0000, 0x60000, 0x80000, 0x30000, 0xA0000, 0x10000}, // addrRgba8Odd + {0x00000, 0xB0000, 0x50000, 0x90000, 0x70000, 0xB0000, 0x20000, 0x90000}, // addrRgba8MipMapEven + {0x80000, 0x40000, 0xA0000, 0x60000, 0x80000, 0x30000, 0xA0000, 0x10000}, // addrRgba8MipMapOdd + }, + // TMEM_CACHE_PLAN_1 + { + {0x00000, 0x40000, 0x50000, 0x60000, 0x70000, 0x78000, 0x68000, 0x58000}, // addrDefaultEven + {0x00000, 0xC0000, 0x50000, 0xE0000, 0x70000, 0xD8000, 0x68000, 0xB8000}, // addrDefaultMipMapEven + {0x80000, 0x40000, 0xA0000, 0x60000, 0x80000, 0x30000, 0xA0000, 0x10000}, // addrDefaultMipMapOdd + {0x00000, 0x40000, 0x50000, 0x60000, 0x70000, 0x78000, 0x68000, 0x58000}, // addrCiEven + {0x00000, 0x40000, 0x50000, 0x60000, 0x70000, 0x70000, 0x60000, 0x50000}, // addrCiMipMapEven + {0x20000, 0x48000, 0x58000, 0x68000, 0x78000, 0x78000, 0x68000, 0x58000}, // addrCiMipMapOdd + {0x00000, 0xC0000, 0x50000, 0xE0000, 0x70000, 0xD8000, 0x68000, 0xB8000}, // addrRgba8Even + {0x80000, 0x40000, 0xD0000, 0x60000, 0xE8000, 0x78000, 0xC8000, 0x58000}, // addrRgba8Odd + {0x00000, 0xC0000, 0x50000, 0xE0000, 0x70000, 0xD0000, 0x60000, 0xB0000}, // addrRgba8MipMapEven + {0x80000, 0x40000, 0xD0000, 0x60000, 0xE0000, 0x70000, 0xC0000, 0x50000}, // addrRgba8MipMapOdd + }, + // TMEM_CACHE_PLAN_2 + { + {0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000}, // addrDefaultEven + {0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000}, // addrDefaultMipMapEven + {0x80000, 0xC0000, 0xC8000, 0xD0000, 0xD0000, 0xC8000, 0xC0000, 0xB0000}, // addrDefaultMipMapOdd + {0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000}, // addrCiEven + {0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000}, // addrCiMipMapEven + {0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000}, // addrCiMipMapOdd + {0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000}, // addrRgba8Even + {0x80000, 0xC0000, 0xC8000, 0xD0000, 0xD0000, 0xC8000, 0xC0000, 0xB0000}, // addrRgba8Odd + {0x00000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x00000}, // addrRgba8MipMapEven + {0x80000, 0xC0000, 0xD0000, 0xE0000, 0xE0000, 0xD0000, 0xC0000, 0xB0000}, // addrRgba8MipMapOdd + }, +}; +// clang-format on + +// clang-format off +static const TexRegionSize scaaaTexRegionSize[TMEM_CACHE_MAX - 1] = { + // TMEM_CACHE_PLAN_0 + { + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeDefaultEven + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeDefaultMipMapEven + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeDefaultMipMapOdd + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeCiEven + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeCiMipMapEven + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeCiMipMapOdd + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8Even + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8Odd + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8MipMapEven + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8MipMapOdd + }, + // TMEM_CACHE_PLAN_1 + { + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeDefaultEven + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeDefaultMipMapEven + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeDefaultMipMapOdd + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeCiEven + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeCiMipMapEven + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeCiMipMapOdd + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8Even + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8Odd + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8MipMapEven + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8MipMapOdd + }, + // TMEM_CACHE_PLAN_2 + { + {2, 2, 2, 2, 2, 2, 2, 2}, // sizeDefaultEven + {2, 2, 2, 2, 2, 2, 2, 2}, // sizeDefaultMipMapEven + {1, 1, 1, 1, 1, 1, 0, 0}, // sizeDefaultMipMapOdd + {2, 2, 2, 2, 2, 2, 2, 2}, // sizeCiEven + {2, 2, 2, 2, 2, 2, 2, 2}, // sizeCiMipMapEven + {1, 1, 1, 1, 1, 1, 0, 0}, // sizeCiMipMapOdd + {2, 2, 2, 2, 2, 2, 2, 2}, // sizeRgba8Even + {1, 1, 1, 1, 1, 1, 0, 0}, // sizeRgba8Odd + {1, 1, 1, 1, 1, 1, 1, 1}, // sizeRgba8MipMapEven + {1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8MipMapOdd + }, +}; +// clang-format on + +// Forward declarations +static GXTexRegion *TexRegionCallback(const GXTexObj *pObj, GXTexMapID map); +static GXTlutRegion *TlutRegionCallback(u32 id); +static void setTexRegion_(TMemCachePlan plan) __attribute__((never_inline)); + +namespace nw4r { +namespace g3d { +namespace tmem { + +void SetTMemLayout(TMemLayout layout) { + if (sfpDefaultTexRegionCallback == NULL) { + // clang-format off + sfpDefaultTexRegionCallback = GXSetTexRegionCallback(TexRegionCallback); + GXSetTexRegionCallback(sfpDefaultTexRegionCallback); + + sfpDefaultTlutRegionCallback = GXSetTlutRegionCallback(TlutRegionCallback); + GXSetTlutRegionCallback(sfpDefaultTlutRegionCallback); + // clang-format on + } + + if (sfpDefaultTexRegionCallback == NULL) { + return; + } + + sTMemCachePlan = static_cast(layout); + setTexRegion_(sTMemCachePlan); + + switch (layout) { + case TMEM_LAYOUT_NONE: + case TMEM_LAYOUT_1: { + GXSetTlutRegionCallback(sfpDefaultTlutRegionCallback); + break; + } + + case TMEM_LAYOUT_2: { + int i; + u32 num = 0; + + u32 addr; + GXTlutRegion *pRegion = saaTlutRegion; + + for (i = 0, addr = 0xF0000; i < GX_MAX_TEXMAP; i++, pRegion++, num++, addr += 0x2000) { + GXInitTlutRegion(pRegion, addr, 16); + } + + sTlutRegionNum = num; + GXSetTlutRegionCallback(TlutRegionCallback); + break; + } + + // TODO: Seems to imply no TMEM_LAYOUT_3 exists. Then why the [plan - 1]? + default: { + break; + } + } +} + +} // namespace tmem +} // namespace g3d +} // namespace nw4r + +static GXTexRegion *TexRegionCallback(const GXTexObj *pObj, GXTexMapID map) { + GXTexFmt fmt = GXGetTexObjFormat(pObj); + GXBool mipmap = GXGetTexObjMipMap(pObj); + + switch (fmt) { + case GX_TF_RGBA8: { + return mipmap ? &saaTexRegion[TEX_REGION_RGBA8_MIPMAP][map] : &saaTexRegion[TEX_REGION_RGBA8][map]; + } + + case GX_TF_C4: + case GX_TF_C8: + case GX_TF_C14X2: { + return mipmap ? &saaTexRegion[TEX_REGION_CI_MIPMAP][map] : &saaTexRegion[TEX_REGION_CI][map]; + } + + default: { + return mipmap ? &saaTexRegion[TEX_REGION_DEFAULT_MIPMAP][map] : &saaTexRegion[TEX_REGION_DEFAULT][map]; + } + } +} + +static GXTlutRegion *TlutRegionCallback(u32 id) { + GXTlutRegion *pRegion = NULL; + + if (id < sTlutRegionNum) { + pRegion = &saaTlutRegion[id]; + } + + return pRegion; +} + +static void setTexRegion_(TMemCachePlan plan) { + if (plan == TMEM_CACHE_NONE) { + GXSetTexRegionCallback(sfpDefaultTexRegionCallback); + return; + } + + for (int i = 0; i < GX_MAX_TEXMAP; i++) { + // clang-format off + GXInitTexCacheRegion( + &saaTexRegion[TEX_REGION_DEFAULT][i], + FALSE, + scaaaTexRegionAddr[plan - 1].addrDefaultEven[i], + scaaaTexRegionSize[plan - 1].sizeDefaultEven[i], + NULL, + 3); + + GXInitTexCacheRegion( + &saaTexRegion[TEX_REGION_DEFAULT_MIPMAP][i], + FALSE, + scaaaTexRegionAddr[plan - 1].addrDefaultMipMapEven[i], + scaaaTexRegionSize[plan - 1].sizeDefaultMipMapEven[i], + scaaaTexRegionAddr[plan - 1].addrDefaultMipMapOdd[i], + scaaaTexRegionSize[plan - 1].sizeDefaultMipMapOdd[i]); + + GXInitTexCacheRegion( + &saaTexRegion[TEX_REGION_CI][i], + FALSE, + scaaaTexRegionAddr[plan - 1].addrCiEven[i], + scaaaTexRegionSize[plan - 1].sizeCiEven[i], + NULL, + 3); + + GXInitTexCacheRegion( + &saaTexRegion[TEX_REGION_CI_MIPMAP][i], + FALSE, + scaaaTexRegionAddr[plan - 1].addrCiMipMapEven[i], + scaaaTexRegionSize[plan - 1].sizeCiMipMapEven[i], + scaaaTexRegionAddr[plan - 1].addrCiMipMapOdd[i], + scaaaTexRegionSize[plan - 1].sizeCiMipMapOdd[i]); + + GXInitTexCacheRegion( + &saaTexRegion[TEX_REGION_RGBA8][i], + FALSE, + scaaaTexRegionAddr[plan - 1].addrRgba8Even[i], + scaaaTexRegionSize[plan - 1].sizeRgba8Even[i], + scaaaTexRegionAddr[plan - 1].addrRgba8Odd[i], + scaaaTexRegionSize[plan - 1].sizeRgba8Odd[i]); + + GXInitTexCacheRegion( + &saaTexRegion[TEX_REGION_RGBA8_MIPMAP][i], + FALSE, + scaaaTexRegionAddr[plan - 1].addrRgba8MipMapEven[i], + scaaaTexRegionSize[plan - 1].sizeRgba8MipMapEven[i], + scaaaTexRegionAddr[plan - 1].addrRgba8MipMapOdd[i], + scaaaTexRegionSize[plan - 1].sizeRgba8MipMapOdd[i]); + // clang-format on + } + + GXSetTexRegionCallback(TexRegionCallback); +} diff --git a/src/nw4r/g3d/res/g3d_resanm.cpp b/src/nw4r/g3d/res/g3d_resanm.cpp new file mode 100644 index 00000000..1d454cc8 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resanm.cpp @@ -0,0 +1,113 @@ +#include + +#include +#include + +namespace nw4r { +namespace g3d { +namespace detail { +namespace { + +/** + * The Hermite interpolating polynomial f satisfies the following conditions: + * f(0) = v0 + * f(d) = v1 + * f'(0) = t0 + * f'(d) = t1 + * + * The value returned is f(p). + */ +inline f32 HermiteInterpolation(f32 v0, f32 t0, f32 v1, f32 t1, f32 p, f32 d) { + f32 invd = math::FInv(d); + + // Linear factors + f32 s = p * invd; // p / d + f32 s_1 = s - 1.0f; // (p - d) / d + + return v0 + s * (s * ((2.0f * s - 3.0f) * (v0 - v1))) + + p * s_1 * (s_1 * t0 + s * t1); +} + +/** + * The linear interpolating function f satisfies the following conditions: + * f(0) = a + * f(0x8000) = b + * + * The value returned is f(ratio). + */ +inline u8 LinearInterpColorElem(u8 a, u8 b, s16 ratio) { + return a + ((b - a) * ratio >> 15); +} + +} // namespace + +f32 GetResKeyFrameAnmResult(const ResKeyFrameAnmData* pData, f32 frame) { + const ResKeyFrameData& rFirst = pData->keyFrames[0]; + const ResKeyFrameData& rLast = pData->keyFrames[pData->numKeyFrame - 1]; + + if (frame <= rFirst.frame) { + return rFirst.value; + } + + if (rLast.frame <= frame) { + return rLast.value; + } + + f32 frameOffset = frame - rFirst.frame; + f32 numKeyFrame = math::U16ToF32(pData->numKeyFrame); + + f32 fEstimate = frameOffset * numKeyFrame * pData->invKeyFrameRange; + u16 iEstimate = math::F32ToU16(fEstimate); + + const ResKeyFrameData* pLeft = &pData->keyFrames[iEstimate]; + + if (frame < pLeft->frame) { + do { + pLeft--; + } while (frame < pLeft->frame); + } else { + do { + pLeft++; + } while (pLeft->frame <= frame); + + pLeft--; + } + + if (pLeft->frame == frame) { + return pLeft->value; + } + + const ResKeyFrameData* pRight = pLeft + 1; + f32 curFrameDelta = frame - pLeft->frame; + f32 keyFrameDelta = pRight->frame - pLeft->frame; + + return HermiteInterpolation(pLeft->value, pLeft->slope, pRight->value, + pRight->slope, curFrameDelta, keyFrameDelta); +} + +u32 GetResColorAnmResult(const ResColorAnmFramesData* pData, f32 frame) { + const u32* pColorArray = pData->frameColors; + + f32 intPart; + f32 fracPart = math::FModf(frame, &intPart); + int intFrame = static_cast(intPart); + + if (fracPart == 0.0f) { + return pColorArray[intFrame]; + } + + ut::Color left(pColorArray[intFrame]); + ut::Color right(pColorArray[intFrame + 1]); + + f32 biasedRatio = 32768 * fracPart; + s16 fpRatio = math::F32ToS16(biasedRatio); + + return ut::Color(LinearInterpColorElem(left.r, right.r, fpRatio), + LinearInterpColorElem(left.g, right.g, fpRatio), + LinearInterpColorElem(left.b, right.b, fpRatio), + LinearInterpColorElem(left.a, right.a, fpRatio)); +} + +} // namespace detail +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resanmamblight.cpp b/src/nw4r/g3d/res/g3d_resanmamblight.cpp new file mode 100644 index 00000000..071560f3 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resanmamblight.cpp @@ -0,0 +1,25 @@ +#include + +namespace nw4r { +namespace g3d { + +void ResAnmAmbLight::GetAnmResult(AmbLightAnmResult* pResult, f32 frame) const { + const ResAnmAmbLightData& r = ref(); + + u32 flags = r.flags; + bool constant = (flags & ResAnmAmbLightData::FLAG_CONST) != 0; + + const ResAnmScnInfoData& rInfoData = + ofs_to_ptr(r.toResAnmScnData)->info; + + f32 clippedFrame = detail::ClipFrame(rInfoData, frame); + + pResult->flags = flags & (AmbLightAnmResult::FLAG_COLOR_ENABLE | + AmbLightAnmResult::FLAG_ALPHA_ENABLE); + + pResult->color = + detail::GetResColorAnmResult(&r.color, clippedFrame, constant); +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resanmcamera.cpp b/src/nw4r/g3d/res/g3d_resanmcamera.cpp new file mode 100644 index 00000000..0c3cd46c --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resanmcamera.cpp @@ -0,0 +1,97 @@ +#include + +namespace nw4r { +namespace g3d { + +void ResAnmCamera::GetAnmResult(CameraAnmResult* pResult, f32 frame) const { + const ResAnmCameraData& r = ref(); + u32 flags = r.flags; + + bool constantPosX = (flags & ResAnmCameraData::FLAG_POS_X_CONST) != 0; + bool constantPosY = (flags & ResAnmCameraData::FLAG_POS_Y_CONST) != 0; + bool constantPosZ = (flags & ResAnmCameraData::FLAG_POS_Z_CONST) != 0; + + bool constantAspect = (flags & ResAnmCameraData::FLAG_ASPECT_CONST) != 0; + bool constantNear = (flags & ResAnmCameraData::FLAG_NEAR_CONST) != 0; + bool constantFar = (flags & ResAnmCameraData::FLAG_FAR_CONST) != 0; + + CameraType type = static_cast( + flags & ResAnmCameraData::FLAG_CAMERA_TYPE_MASK); + + pResult->flags = flags & (CameraAnmResult::FLAG_CAMERA_TYPE_MASK | + CameraAnmResult::FLAG_ANM_EXISTS); + + pResult->projType = r.projType; + + pResult->pos.x = detail::GetResAnmResult(&r.posX, frame, constantPosX); + pResult->pos.y = detail::GetResAnmResult(&r.posY, frame, constantPosY); + pResult->pos.z = detail::GetResAnmResult(&r.posZ, frame, constantPosZ); + + pResult->aspect = detail::GetResAnmResult(&r.aspect, frame, constantAspect); + pResult->near = detail::GetResAnmResult(&r.near, frame, constantNear); + pResult->far = detail::GetResAnmResult(&r.far, frame, constantFar); + + switch (type) { + case CAMERATYPE_ROTATE: { + bool constantRotX = (flags & ResAnmCameraData::FLAG_ROT_X_CONST) != 0; + bool constantRotY = (flags & ResAnmCameraData::FLAG_ROT_Y_CONST) != 0; + bool constantRotZ = (flags & ResAnmCameraData::FLAG_ROT_Z_CONST) != 0; + + pResult->rotate.rot.x = + detail::GetResAnmResult(&r.rotX, frame, constantRotX); + pResult->rotate.rot.y = + detail::GetResAnmResult(&r.rotY, frame, constantRotY); + pResult->rotate.rot.z = + detail::GetResAnmResult(&r.rotZ, frame, constantRotZ); + break; + } + + case CAMERATYPE_AIM: { + bool constantAimX = (flags & ResAnmCameraData::FLAG_AIM_X_CONST) != 0; + bool constantAimY = (flags & ResAnmCameraData::FLAG_AIM_Y_CONST) != 0; + bool constantAimZ = (flags & ResAnmCameraData::FLAG_AIM_Z_CONST) != 0; + bool constantTwist = (flags & ResAnmCameraData::FLAG_TWIST_CONST) != 0; + + pResult->aim.aim.x = + detail::GetResAnmResult(&r.aimX, frame, constantAimX); + pResult->aim.aim.y = + detail::GetResAnmResult(&r.aimY, frame, constantAimY); + pResult->aim.aim.z = + detail::GetResAnmResult(&r.aimZ, frame, constantAimZ); + pResult->aim.twist = + detail::GetResAnmResult(&r.twist, frame, constantTwist); + break; + } + + default: { + break; + } + } + + switch (r.projType) { + case GX_PERSPECTIVE: { + bool constantFovy = + (flags & ResAnmCameraData::FLAG_PERSP_FOVY_CONST) != 0; + + pResult->perspFovy = + detail::GetResAnmResult(&r.perspFovy, frame, constantFovy); + break; + } + + case GX_ORTHOGRAPHIC: { + bool constantHeight = + (flags & ResAnmCameraData::FLAG_ORTHO_HEIGHT_CONST) != 0; + + pResult->orthoHeight = + detail::GetResAnmResult(&r.orthoHeight, frame, constantHeight); + break; + } + + default: { + break; + } + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resanmchr.cpp b/src/nw4r/g3d/res/g3d_resanmchr.cpp new file mode 100644 index 00000000..6d155630 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resanmchr.cpp @@ -0,0 +1,953 @@ +#pragma fp_contract on + +#include + +namespace nw4r { +namespace g3d { +namespace { + +/****************************************************************************** + * + * Utility functions + * + ******************************************************************************/ +inline f32 HermiteInterpolation(f32 v0, f32 t0, f32 v1, f32 t1, f32 s, f32 d) { + f32 s_1 = s - 1.0f; + + return v0 + s * (s * ((2.0f * s - 3.0f) * (v0 - v1))) + + d * s_1 * (s_1 * t0 + s * t1); +} + +/****************************************************************************** + * + * Animation keyframe + * + ******************************************************************************/ +template class CResAnmChrFrmBase { +protected: + const TData* mPtr; + +public: + CResAnmChrFrmBase(const TData* pPtr) : mPtr(pPtr) {} + + void operator++(int) { + mPtr++; + } + void operator--(int) { + mPtr--; + } + + TDerived operator+(int n) { + return TDerived(mPtr + n); + } +}; + +template +class CResAnmChrFrm : public CResAnmChrFrmBase > {}; + +template <> +class CResAnmChrFrm + : public CResAnmChrFrmBase > { +public: + CResAnmChrFrm(const ResAnmChrFrm32Data* pPtr) : CResAnmChrFrmBase(pPtr) {} + + u8 GetFrame() const { + return mPtr->fvs.frame; + } + + f32 GetFrameF32() const { + return fastcast::U8_0ToF32(&mPtr->fvs.frame); + } + + f32 GetValue(const ResAnmChrFVSData* pFVSData) const { + u16 value = (mPtr->fvsU32 & 0x00FFF000) >> 12; + return pFVSData->fvs32.scale * fastcast::U16_0ToF32(&value) + + pFVSData->fvs48.offset; + } + + f32 GetSlope() const { + s16 slope = static_cast((mPtr->fvsU32 & 0x00000FFF) << 20) >> 20; + return fastcast::S10_5ToF32(&slope); + } +}; + +template <> +class CResAnmChrFrm + : public CResAnmChrFrmBase > { +public: + CResAnmChrFrm(const ResAnmChrFrm48Data* pPtr) : CResAnmChrFrmBase(pPtr) {} + + s16 GetFrame() const { + return mPtr->frame; + } + + f32 GetFrameF32() const { + return fastcast::S10_5ToF32(&mPtr->frame); + } + + f32 GetValue(const ResAnmChrFVSData* pFVSData) const { + return pFVSData->fvs48.scale * fastcast::U16_0ToF32(&mPtr->value) + + pFVSData->fvs48.offset; + } + + f32 GetSlope() const { + return fastcast::S7_8ToF32(&mPtr->slope); + } +}; + +template <> +class CResAnmChrFrm + : public CResAnmChrFrmBase > { +public: + CResAnmChrFrm(const ResAnmChrFrm96Data* pPtr) : CResAnmChrFrmBase(pPtr) {} + + f32 GetFrame() const { + return mPtr->frame; + } + + f32 GetFrameF32() const { + return mPtr->frame; + } + + f32 GetValue(const ResAnmChrFVSData* /* pFVSData */) const { + return mPtr->value; + } + + f32 GetSlope() const { + return mPtr->slope; + } +}; + +/****************************************************************************** + * + * Animation traits + * + ******************************************************************************/ +template class CAnmFmtTraits {}; + +template <> class CAnmFmtTraits { +public: + typedef ResAnmChrFrm32Data TFrmData; + typedef u8 TFrame; + +public: + static CResAnmChrFrm GetKeyFrame(const ResAnmChrFVSData* pFVSData, + int index) { + return CResAnmChrFrm(&pFVSData->fvs32.frameValues[index]); + } + + static TFrame QuantizeFrame(f32 frame) { + return fastcast::F32ToU8_0(frame); + } +}; + +template <> class CAnmFmtTraits { +public: + typedef ResAnmChrFrm48Data TFrmData; + typedef s16 TFrame; + +public: + static CResAnmChrFrm GetKeyFrame(const ResAnmChrFVSData* pFVSData, + int index) { + return CResAnmChrFrm(&pFVSData->fvs48.frameValues[index]); + } + + static TFrame QuantizeFrame(f32 frame) { + return fastcast::F32ToS10_5(frame); + } +}; + +template <> class CAnmFmtTraits { +public: + typedef ResAnmChrFrm96Data TFrmData; + typedef f32 TFrame; + +public: + static CResAnmChrFrm GetKeyFrame(const ResAnmChrFVSData* pFVSData, + int index) { + return CResAnmChrFrm(&pFVSData->fvs96.frameValues[index]); + } + + static TFrame QuantizeFrame(f32 frame) { + return frame; + } +}; + +template <> class CAnmFmtTraits { +public: + static f32 GetAt(const ResAnmChrCVData* pCVData, u16 idx) { + const ResAnmChrCV8Data& rCV8 = pCVData->cv8; + return rCV8.values[idx] * rCV8.scale + rCV8.offset; + } +}; + +template <> class CAnmFmtTraits { +public: + static f32 GetAt(const ResAnmChrCVData* pCVData, u16 idx) { + const ResAnmChrCV16Data& rCV16 = pCVData->cv16; + return rCV16.values[idx] * rCV16.scale + rCV16.offset; + } +}; + +template <> class CAnmFmtTraits { +public: + static f32 GetAt(const ResAnmChrCVData* pCVData, u16 idx) { + const ResAnmChrCV32Data& rCV32 = pCVData->cv32; + return rCV32.values[idx]; + } +}; + +/****************************************************************************** + * + * Frame values (FVS) implementation + * + ******************************************************************************/ +template +f32 CalcAnimationFVS(const ResAnmChrFVSData* pFVSData, f32 frame) { + CResAnmChrFrm first = TTraits::GetKeyFrame(pFVSData, 0); + CResAnmChrFrm last = + TTraits::GetKeyFrame(pFVSData, pFVSData->numFrameValues - 1); + + if (frame <= first.GetFrameF32()) { + return first.GetValue(pFVSData); + } + + if (last.GetFrameF32() <= frame) { + return last.GetValue(pFVSData); + } + + f32 frameOffset = frame - first.GetFrameF32(); + f32 numKeyFrame = math::U16ToF32(pFVSData->numFrameValues); + + f32 f_estimatePos = frameOffset * numKeyFrame * pFVSData->invKeyFrameRange; + u16 i_estimatePos = math::F32ToU16(f_estimatePos); + + CResAnmChrFrm left = + TTraits::GetKeyFrame(pFVSData, i_estimatePos); + + const TTraits::TFrame quantized = TTraits::QuantizeFrame(frame); + + if (quantized < left.GetFrame()) { + while (true) { + left--; + + if (!(quantized < left.GetFrame())) { + break; + } + } + } else { + while (true) { + left++; + + if (!(left.GetFrame() <= quantized)) { + break; + } + } + + left--; + } + + if (frame == left.GetFrameF32()) { + return left.GetValue(pFVSData); + } + + CResAnmChrFrm right = left + 1; + + f32 v0 = left.GetValue(pFVSData); + f32 t0 = left.GetSlope(); + f32 v1 = right.GetValue(pFVSData); + f32 t1 = right.GetSlope(); + + f32 f0 = left.GetFrameF32(); + f32 f1 = right.GetFrameF32(); + + f32 frameDelta = frame - f0; + f32 keyFrameDelta = f1 - f0; + f32 keyFrameDeltaInv = math::FInv(keyFrameDelta); + + return HermiteInterpolation(v0, t0, v1, t1, frameDelta * keyFrameDeltaInv, + frameDelta); +} + +/****************************************************************************** + * + * Const value (CV) implementation + * + ******************************************************************************/ +template +f32 CalcAnimationCV(const ResAnmChrCVData* pCVData, u16 numFrame, f32 frame) { + u16 frame_i = math::F32ToU16(frame); + + if (frame <= 0.0f) { + return TTraits::GetAt(pCVData, 0); + } + + if (numFrame <= frame_i) { + return TTraits::GetAt(pCVData, numFrame); + } + + f32 r = frame - static_cast(frame_i); + + f32 v0 = TTraits::GetAt(pCVData, frame_i); + if (r == 0.0f) { + return v0; + } + + f32 v1 = TTraits::GetAt(pCVData, frame_i + 1); + return r * (v1 - v0) + v0; +} + +/****************************************************************************** + * + * Calculate frame values (FVS) result + * + ******************************************************************************/ +template +f32 CalcResultFVS(const ResAnmChrNodeData* pNodeData, + const ResAnmChrNodeData::AnmData* pAnmData, f32 frame, + bool constant) { + if (constant) { + return pAnmData->constValue; + } + + const ResAnmChrAnmData* pFVSAnmData = + reinterpret_cast( + ut::AddOffsetToPtr(pNodeData, pAnmData->toResAnmChrAnmData)); + + return CalcAnimationFVS >(&pFVSAnmData->fvs, frame); +} + +inline f32 CalcResult32(const ResAnmChrNodeData* pNodeData, + const ResAnmChrNodeData::AnmData* pAnmData, f32 frame, + bool constant) { + return CalcResultFVS(pNodeData, pAnmData, frame, + constant); +} +inline f32 CalcResult48(const ResAnmChrNodeData* pNodeData, + const ResAnmChrNodeData::AnmData* pAnmData, f32 frame, + bool constant) { + return CalcResultFVS(pNodeData, pAnmData, frame, + constant); +} +inline f32 CalcResult96(const ResAnmChrNodeData* pNodeData, + const ResAnmChrNodeData::AnmData* pAnmData, f32 frame, + bool constant) { + return CalcResultFVS(pNodeData, pAnmData, frame, + constant); +} + +/****************************************************************************** + * + * Calculate const value (CV) result + * + ******************************************************************************/ +template +f32 CalcResultCV(const ResAnmChrNodeData* pNodeData, + const ResAnmChrNodeData::AnmData* pAnmData, u16 numFrame, + f32 frame, bool constant) { + + if (constant) { + return pAnmData->constValue; + } + + const ResAnmChrAnmData* pCVAnmData = + reinterpret_cast( + ut::AddOffsetToPtr(pNodeData, pAnmData->toResAnmChrAnmData)); + + return CalcAnimationCV >(&pCVAnmData->cv, numFrame, frame); +} + +inline f32 CalcResultFrm8(const ResAnmChrNodeData* pNodeData, + const ResAnmChrNodeData::AnmData* pAnmData, + u16 numFrame, f32 frame, bool constant) { + return CalcResultCV(pNodeData, pAnmData, numFrame, frame, + constant); +} +inline f32 CalcResultFrm16(const ResAnmChrNodeData* pNodeData, + const ResAnmChrNodeData::AnmData* pAnmData, + u16 numFrame, f32 frame, bool constant) { + return CalcResultCV(pNodeData, pAnmData, numFrame, frame, + constant); +} +inline f32 CalcResultFrm32(const ResAnmChrNodeData* pNodeData, + const ResAnmChrNodeData::AnmData* pAnmData, + u16 numFrame, f32 frame, bool constant) { + return CalcResultCV(pNodeData, pAnmData, numFrame, frame, + constant); +} + +/****************************************************************************** + * + * Get animation component + * + ******************************************************************************/ +const ResAnmChrNodeData::AnmData* +GetAnmScale(math::VEC3* pResult, const ResAnmChrNodeData* pNodeData, + const ResAnmChrNodeData::AnmData* pAnmData, f32 frame) { + + u32 flags = pNodeData->flags; + f32 x, y, z; + + switch (flags & ResAnmChrNodeData::FLAG_SCALE_FMT_MASK) { + case 0: { + x = pAnmData++->constValue; + + if (flags & ResAnmChrNodeData::FLAG_SCALE_UNIFORM) { + y = x; + z = x; + } else { + y = pAnmData++->constValue; + z = pAnmData++->constValue; + } + + break; + } + + case ResAnmChrNodeData::FLAG_SCALE_FVS32_FMT: { + x = CalcResult32(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_SCALE_X_CONST); + + if (flags & ResAnmChrNodeData::FLAG_SCALE_UNIFORM) { + y = x; + z = x; + } else { + y = CalcResult32(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_SCALE_Y_CONST); + z = CalcResult32(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_SCALE_Z_CONST); + } + + break; + } + + case ResAnmChrNodeData::FLAG_SCALE_FVS48_FMT: { + x = CalcResult48(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_SCALE_X_CONST); + + if (flags & ResAnmChrNodeData::FLAG_SCALE_UNIFORM) { + y = x; + z = x; + } else { + y = CalcResult48(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_SCALE_Y_CONST); + z = CalcResult48(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_SCALE_Z_CONST); + } + + break; + } + + case ResAnmChrNodeData::FLAG_SCALE_FVS96_FMT: { + x = CalcResult96(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_SCALE_X_CONST); + + if (flags & ResAnmChrNodeData::FLAG_SCALE_UNIFORM) { + y = x; + z = x; + } else { + y = CalcResult96(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_SCALE_Y_CONST); + z = CalcResult96(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_SCALE_Z_CONST); + } + + break; + } + + default: { + x = 0.0f; + y = 0.0f; + z = 0.0f; + break; + } + } + + pResult->x = x; + pResult->y = y; + pResult->z = z; + + return pAnmData; +} + +const ResAnmChrNodeData::AnmData* +GetAnmRotation(math::MTX34* pResult, math::VEC3* pRawResult, + const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, + const ResAnmChrNodeData::AnmData* pAnmData, f32 frame) { + + u32 flags = pNodeData->flags; + f32 x, y, z; + + switch (flags & ResAnmChrNodeData::FLAG_ROT_FMT_MASK) { + case 0: { + x = pAnmData++->constValue; + y = pAnmData++->constValue; + z = pAnmData++->constValue; + break; + } + + case ResAnmChrNodeData::FLAG_ROT_FVS32_FMT: { + x = CalcResult32(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_ROT_X_CONST); + y = CalcResult32(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_ROT_Y_CONST); + z = CalcResult32(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_ROT_Z_CONST); + break; + } + + case ResAnmChrNodeData::FLAG_ROT_FVS48_FMT: { + x = CalcResult48(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_ROT_X_CONST); + y = CalcResult48(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_ROT_Y_CONST); + z = CalcResult48(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_ROT_Z_CONST); + break; + } + + case ResAnmChrNodeData::FLAG_ROT_FVS96_FMT: { + x = CalcResult96(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_ROT_X_CONST); + y = CalcResult96(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_ROT_Y_CONST); + z = CalcResult96(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_ROT_Z_CONST); + break; + } + + case ResAnmChrNodeData::FLAG_ROT_CV8_FMT: { + x = CalcResultFrm8(pNodeData, pAnmData++, rInfoData.numFrame, frame, + flags & ResAnmChrNodeData::FLAG_ROT_X_CONST); + y = CalcResultFrm8(pNodeData, pAnmData++, rInfoData.numFrame, frame, + flags & ResAnmChrNodeData::FLAG_ROT_Y_CONST); + z = CalcResultFrm8(pNodeData, pAnmData++, rInfoData.numFrame, frame, + flags & ResAnmChrNodeData::FLAG_ROT_Z_CONST); + break; + } + + case ResAnmChrNodeData::FLAG_ROT_CV16_FMT: { + x = CalcResultFrm16(pNodeData, pAnmData++, rInfoData.numFrame, frame, + flags & ResAnmChrNodeData::FLAG_ROT_X_CONST); + y = CalcResultFrm16(pNodeData, pAnmData++, rInfoData.numFrame, frame, + flags & ResAnmChrNodeData::FLAG_ROT_Y_CONST); + z = CalcResultFrm16(pNodeData, pAnmData++, rInfoData.numFrame, frame, + flags & ResAnmChrNodeData::FLAG_ROT_Z_CONST); + break; + } + + case ResAnmChrNodeData::FLAG_ROT_CV32_FMT: { + x = CalcResultFrm32(pNodeData, pAnmData++, rInfoData.numFrame, frame, + flags & ResAnmChrNodeData::FLAG_ROT_X_CONST); + y = CalcResultFrm32(pNodeData, pAnmData++, rInfoData.numFrame, frame, + flags & ResAnmChrNodeData::FLAG_ROT_Y_CONST); + z = CalcResultFrm32(pNodeData, pAnmData++, rInfoData.numFrame, frame, + flags & ResAnmChrNodeData::FLAG_ROT_Z_CONST); + break; + } + + default: { + x = 0.0f; + y = 0.0f; + z = 0.0f; + } + } + + math::MTX34RotXYZDeg(pResult, x, y, z); + + pRawResult->x = x; + pRawResult->y = y; + pRawResult->z = z; + + return pAnmData; +} + +const ResAnmChrNodeData::AnmData* +GetAnmTranslation(math::VEC3* pTrans, const ResAnmChrNodeData* pNodeData, + const ResAnmChrNodeData::AnmData* pAnmData, f32 frame) { + + u32 flags = pNodeData->flags; + f32 x, y, z; + + switch (flags & ResAnmChrNodeData::FLAG_TRANS_FMT_MASK) { + case 0: { + x = pAnmData++->constValue; + y = pAnmData++->constValue; + z = pAnmData++->constValue; + break; + } + + case ResAnmChrNodeData::FLAG_TRANS_FVS32_FMT: { + x = CalcResult32(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_TRANS_X_CONST); + y = CalcResult32(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_TRANS_Y_CONST); + z = CalcResult32(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_TRANS_Z_CONST); + break; + } + + case ResAnmChrNodeData::FLAG_TRANS_FVS48_FMT: { + x = CalcResult48(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_TRANS_X_CONST); + y = CalcResult48(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_TRANS_Y_CONST); + z = CalcResult48(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_TRANS_Z_CONST); + break; + } + + case ResAnmChrNodeData::FLAG_TRANS_FVS96_FMT: { + x = CalcResult96(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_TRANS_X_CONST); + y = CalcResult96(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_TRANS_Y_CONST); + z = CalcResult96(pNodeData, pAnmData++, frame, + flags & ResAnmChrNodeData::FLAG_TRANS_Z_CONST); + break; + } + + default: { + x = 0.0f; + y = 0.0f; + z = 0.0f; + } + } + + pTrans->x = x; + pTrans->y = y; + pTrans->z = z; + + return pAnmData; +} + +/****************************************************************************** + * + * Get animation result + * + ******************************************************************************/ +void GetAnmResult_(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame); +void GetAnmResult_S(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame); +void GetAnmResult_R(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame); +void GetAnmResult_SR(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame); +void GetAnmResult_T(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame); +void GetAnmResult_ST(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame); +void GetAnmResult_RT(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame); +void GetAnmResult_SRT(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame); + +typedef void (*GetAnmResultFunc)(ChrAnmResult* pResult, + const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame); + +const GetAnmResultFunc gGetAnmResultTable[] = { + GetAnmResult_, // 0 0 0 + GetAnmResult_S, // 0 0 1 + GetAnmResult_R, // 0 1 0 + GetAnmResult_SR, // 0 1 1 + GetAnmResult_T, // 1 0 0 + GetAnmResult_ST, // 1 0 1 + GetAnmResult_RT, // 1 1 0 + GetAnmResult_SRT // 1 1 1 +}; + +void GetAnmResult_(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame) { +#pragma unused(rInfoData) +#pragma unused(pNodeData) +#pragma unused(frame) + + pResult->s.x = 1.0f; + pResult->s.y = 1.0f; + pResult->s.z = 1.0f; + math::MTX34Identity(&pResult->rt); +} + +void GetAnmResult_T(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame) { +#pragma unused(rInfoData) + + const ResAnmChrNodeData::AnmData* pAnmData = pNodeData->anms; + math::VEC3 t; + + pResult->s.x = 1.0f; + pResult->s.y = 1.0f; + pResult->s.z = 1.0f; + math::MTX34Identity(&pResult->rt); + + GetAnmTranslation(&t, pNodeData, pAnmData, frame); + pResult->rt._03 = t.x; + pResult->rt._13 = t.y; + pResult->rt._23 = t.z; +} + +void GetAnmResult_R(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame) { + + const ResAnmChrNodeData::AnmData* pAnmData = pNodeData->anms; + + pResult->s.x = 1.0f; + pResult->s.y = 1.0f; + pResult->s.z = 1.0f; + + GetAnmRotation(&pResult->rt, &pResult->rawR, rInfoData, pNodeData, pAnmData, + frame); + + pResult->flags |= ChrAnmResult::FLAG_ROT_RAW_FMT; + + pResult->rt._03 = 0.0f; + pResult->rt._13 = 0.0f; + pResult->rt._23 = 0.0f; +} + +void GetAnmResult_S(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame) { +#pragma unused(rInfoData) + + const ResAnmChrNodeData::AnmData* pAnmData = pNodeData->anms; + + GetAnmScale(&pResult->s, pNodeData, pAnmData, frame); + math::MTX34Identity(&pResult->rt); +} + +void GetAnmResult_RT(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame) { + + const ResAnmChrNodeData::AnmData* pAnmData = pNodeData->anms; + math::VEC3 t; + + pResult->s.x = 1.0f; + pResult->s.y = 1.0f; + pResult->s.z = 1.0f; + + pAnmData = GetAnmRotation(&pResult->rt, &pResult->rawR, rInfoData, + pNodeData, pAnmData, frame); + + pResult->flags |= ChrAnmResult::FLAG_ROT_RAW_FMT; + + GetAnmTranslation(&t, pNodeData, pAnmData, frame); + pResult->rt._03 = t.x; + pResult->rt._13 = t.y; + pResult->rt._23 = t.z; +} + +void GetAnmResult_SR(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame) { + + const ResAnmChrNodeData::AnmData* pAnmData = pNodeData->anms; + + pAnmData = GetAnmScale(&pResult->s, pNodeData, pAnmData, frame); + + GetAnmRotation(&pResult->rt, &pResult->rawR, rInfoData, pNodeData, pAnmData, + frame); + + pResult->flags |= ChrAnmResult::FLAG_ROT_RAW_FMT; + + pResult->rt._03 = 0.0f; + pResult->rt._13 = 0.0f; + pResult->rt._23 = 0.0f; +} + +void GetAnmResult_ST(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame) { +#pragma unused(rInfoData) + + const ResAnmChrNodeData::AnmData* pAnmData = pNodeData->anms; + math::VEC3 t; + + pAnmData = GetAnmScale(&pResult->s, pNodeData, pAnmData, frame); + math::MTX34Identity(&pResult->rt); + + GetAnmTranslation(&t, pNodeData, pAnmData, frame); + pResult->rt._03 = t.x; + pResult->rt._13 = t.y; + pResult->rt._23 = t.z; +} + +void GetAnmResult_SRT(ChrAnmResult* pResult, const ResAnmChrInfoData& rInfoData, + const ResAnmChrNodeData* pNodeData, f32 frame) { + + const ResAnmChrNodeData::AnmData* pAnmData = pNodeData->anms; + math::VEC3 t; + + pAnmData = GetAnmScale(&pResult->s, pNodeData, pAnmData, frame); + pAnmData = GetAnmRotation(&pResult->rt, &pResult->rawR, rInfoData, + pNodeData, pAnmData, frame); + pAnmData = GetAnmTranslation(&t, pNodeData, pAnmData, frame); + + pResult->flags |= ChrAnmResult::FLAG_ROT_RAW_FMT; + + pResult->rt._03 = t.x; + pResult->rt._13 = t.y; + pResult->rt._23 = t.z; +} + +} // namespace + +/****************************************************************************** + * + * ResAnmChr + * + ******************************************************************************/ +void ResAnmChr::GetAnmResult(ChrAnmResult* pResult, u32 idx, f32 frame) const { + const ResAnmChrNodeData* pNodeData = GetNodeAnm(idx); + + u32 flags = pNodeData->flags; + + pResult->flags = + flags & + (ChrAnmResult::FLAG_ANM_EXISTS | ChrAnmResult::FLAG_MTX_IDENT | + ChrAnmResult::FLAG_ROT_TRANS_ZERO | ChrAnmResult::FLAG_SCALE_ONE | + ChrAnmResult::FLAG_SCALE_UNIFORM | ChrAnmResult::FLAG_ROT_ZERO | + ChrAnmResult::FLAG_TRANS_ZERO | ChrAnmResult::FLAG_PATCH_SCALE | + ChrAnmResult::FLAG_PATCH_ROT | ChrAnmResult::FLAG_PATCH_TRANS | + ChrAnmResult::FLAG_SSC_APPLY | ChrAnmResult::FLAG_SSC_PARENT | + ChrAnmResult::FLAG_XSI_SCALING); + + u32 index = (flags & ResAnmChrNodeData::FLAG_HAS_SRT_MASK) >> 22; + gGetAnmResultTable[index](pResult, ref().info, pNodeData, frame); +} + +/****************************************************************************** + * + * ChrAnmResult + * + ******************************************************************************/ +void ChrAnmResult::GetScale(math::VEC3* pScale) const { + if (flags & FLAG_SCALE_ONE) { + pScale->x = 1.0f; + pScale->y = 1.0f; + pScale->z = 1.0f; + } else { + pScale->x = s.x; + pScale->y = s.y; + pScale->z = s.z; + } +} + +bool ChrAnmResult::GetRotateDeg(math::VEC3* pRotate) const { + if (flags & FLAG_ROT_ZERO) { + pRotate->x = 0.0f; + pRotate->y = 0.0f; + pRotate->z = 0.0f; + return true; + } + + if (flags & FLAG_ROT_RAW_FMT) { + pRotate->x = rawR.x; + pRotate->y = rawR.y; + pRotate->z = rawR.z; + return true; + } + + // FSqrt returns 0 when -sin(y) <= -1 or -sin(y) >= 1 + f32 y = math::FSqrt(-(rt._20 * rt._20 - 1.0f)); + + if (y == 0.0f) { + pRotate->x = math::Atan2Deg(rt._02 + rt._11, rt._12 + rt._01); + pRotate->y = math::FSelect(rt._20, -90, 90); + pRotate->z = math::Atan2Deg(rt._02 + rt._11, rt._12 - rt._01); + } else { + pRotate->x = math::Atan2Deg(rt._21, rt._22); + pRotate->y = math::Atan2Deg(-rt._20, y); + pRotate->z = math::Atan2Deg(rt._10, rt._00); + } + + return false; +} + +void ChrAnmResult::GetTranslate(math::VEC3* pTrans) const { + if (flags & FLAG_TRANS_ZERO) { + pTrans->x = 0.0f; + pTrans->y = 0.0f; + pTrans->z = 0.0f; + } else { + pTrans->x = rt._03; + pTrans->y = rt._13; + pTrans->z = rt._23; + } +} + +void ChrAnmResult::GetRotTrans(math::MTX34* pRotTrans) const { + if (flags & FLAG_ROT_ZERO) { + if (flags & FLAG_TRANS_ZERO) { + math::MTX34Identity(pRotTrans); + } else { + math::MTX34Identity(pRotTrans); + pRotTrans->_03 = rt._03; + pRotTrans->_13 = rt._13; + pRotTrans->_23 = rt._23; + } + } else if (flags & FLAG_TRANS_ZERO) { + math::MTX34Copy(pRotTrans, &rt); + pRotTrans->_03 = 0.0f; + pRotTrans->_13 = 0.0f; + pRotTrans->_23 = 0.0f; + } else { + math::MTX34Copy(pRotTrans, &rt); + } +} + +void ChrAnmResult::SetScale(const math::VEC3* pScale) { + if (pScale->x == 1.0f && pScale->y == 1.0f && pScale->z == 1.0f) { + flags |= FLAG_SCALE_ONE | FLAG_SCALE_UNIFORM; + + if (flags & FLAG_ROT_TRANS_ZERO) { + flags |= FLAG_MTX_IDENT; + } + } else { + flags &= ~(FLAG_MTX_IDENT | FLAG_SCALE_ONE | FLAG_SCALE_UNIFORM); + + if (pScale->x == pScale->y && pScale->y == pScale->z) { + flags |= FLAG_SCALE_UNIFORM; + } + } + + s = *pScale; +} + +void ChrAnmResult::SetRotTrans(const math::MTX34* pRotTrans) { + bool rotZero = pRotTrans->_00 == 1.0f && pRotTrans->_01 == 0.0f && + pRotTrans->_02 == 0.0f && pRotTrans->_10 == 0.0f && + pRotTrans->_11 == 1.0f && pRotTrans->_12 == 0.0f && + pRotTrans->_20 == 0.0f && pRotTrans->_21 == 0.0f && + pRotTrans->_22 == 1.0f; + + bool transZero = pRotTrans->_03 == 0.0f && pRotTrans->_13 == 0.0f && + pRotTrans->_23 == 0.0f; + + if (rotZero) { + if (transZero) { + flags |= FLAG_ROT_TRANS_ZERO | FLAG_ROT_ZERO | FLAG_TRANS_ZERO; + + if (flags & FLAG_SCALE_ONE) { + flags |= FLAG_MTX_IDENT; + } + } else { + flags |= FLAG_ROT_ZERO; + flags &= ~(FLAG_MTX_IDENT | FLAG_ROT_TRANS_ZERO | FLAG_TRANS_ZERO); + } + } else if (transZero) { + flags |= FLAG_TRANS_ZERO; + flags &= ~(FLAG_MTX_IDENT | FLAG_ROT_TRANS_ZERO | FLAG_ROT_ZERO); + } else { + flags &= ~(FLAG_MTX_IDENT | FLAG_ROT_TRANS_ZERO | FLAG_ROT_ZERO | + FLAG_TRANS_ZERO); + } + + math::MTX34Copy(&rt, pRotTrans); + flags &= ~FLAG_ROT_RAW_FMT; +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resanmclr.cpp b/src/nw4r/g3d/res/g3d_resanmclr.cpp new file mode 100644 index 00000000..174199da --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resanmclr.cpp @@ -0,0 +1,39 @@ +#include + +namespace nw4r { +namespace g3d { + +void ResAnmClr::GetAnmResult(ClrAnmResult* pResult, u32 idx, f32 frame) const { + const ResAnmClrMatData* pMatData = GetMatAnm(idx); + const ResAnmClrAnmData* pAnmData = pMatData->anms; + const ResAnmClrInfoData& rInfoData = ref().info; + + u32 flags = pMatData->flags; + pResult->bRgbaExist = 0; + + if (flags == 0) { + return; + } + + f32 clippedFrame = detail::ClipFrame(rInfoData, frame); + + for (int i = 0; i < ClrAnmResult::CLA_MAX; + flags >>= ResAnmClrMatData::NUM_OF_FLAGS, i++) { + + if (!(flags & ResAnmClrMatData::FLAG_ANM_EXISTS)) { + continue; + } + + bool constant = flags & ResAnmClrMatData::FLAG_ANM_CONSTANT; + + pResult->bRgbaExist |= 1 << i; + pResult->rgbaMask[i] = pAnmData->mask; + pResult->rgba[i] = detail::GetResColorAnmResult(&pAnmData->color, + clippedFrame, constant); + + pAnmData++; + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resanmfog.cpp b/src/nw4r/g3d/res/g3d_resanmfog.cpp new file mode 100644 index 00000000..72ee5568 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resanmfog.cpp @@ -0,0 +1,27 @@ +#include + +namespace nw4r { +namespace g3d { + +void ResAnmFog::GetAnmResult(FogAnmResult* pResult, f32 frame) const { + const ResAnmFogData& r = ref(); + u32 flags = r.flags; + + const ResAnmScnInfoData& rInfoData = + ofs_to_ptr(r.toResAnmScnData)->info; + + f32 clippedFrame = detail::ClipFrame(rInfoData, frame); + + bool startZConstant = (flags & ResAnmFogData::FLAG_START_CONST) != 0; + bool endZConstant = (flags & ResAnmFogData::FLAG_END_CONST) != 0; + bool colorConstant = (flags & ResAnmFogData::FLAG_COLOR_CONST) != 0; + + pResult->type = r.type; + pResult->startz = detail::GetResAnmResult(&r.startz, frame, startZConstant); + pResult->endz = detail::GetResAnmResult(&r.endz, frame, endZConstant); + pResult->color = + detail::GetResColorAnmResult(&r.color, clippedFrame, colorConstant); +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resanmlight.cpp b/src/nw4r/g3d/res/g3d_resanmlight.cpp new file mode 100644 index 00000000..e8bd6828 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resanmlight.cpp @@ -0,0 +1,127 @@ +#include + +namespace nw4r { +namespace g3d { + +void ResAnmLight::GetAnmResult(LightAnmResult* pResult, f32 frame) const { + const ResAnmLightData& r = ref(); + u32 flags = r.flags; + + const ResAnmScnInfoData& rInfoData = + ofs_to_ptr(r.toResAnmScnData)->info; + + f32 clippedFrame = detail::ClipFrame(rInfoData, frame); + + pResult->flags = flags & (LightAnmResult::FLAG_LIGHT_TYPE_MASK | + LightAnmResult::FLAG_LIGHT_ENABLE | + LightAnmResult::FLAG_SPECULAR_ENABLE | + LightAnmResult::FLAG_COLOR_ENABLE | + LightAnmResult::FLAG_ALPHA_ENABLE); + + bool enableConstant = (flags & ResAnmLightData::FLAG_ENABLE_CONST) != 0; + if (!enableConstant) { + int iClippedFrame = static_cast(math::FFloor(clippedFrame)); + + bool enable = detail::GetResBoolAnmResult(&r.enable, iClippedFrame); + if (enable) { + pResult->flags |= ResAnmLightData::FLAG_LIGHT_ENABLE; + } + } + + if (pResult->flags & ResAnmLightData::FLAG_LIGHT_ENABLE) { + LightType type = static_cast( + flags & ResAnmLightData::FLAG_LIGHT_TYPE_MASK); + + bool hasSpecular = (flags & ResAnmLightData::FLAG_SPECULAR_ENABLE) != 0; + bool hasAim = type != LIGHTTYPE_POINT || hasSpecular; + + bool constantPosX = (flags & ResAnmLightData::FLAG_POS_X_CONST) != 0; + bool constantPosY = (flags & ResAnmLightData::FLAG_POS_Y_CONST) != 0; + bool constantPosZ = (flags & ResAnmLightData::FLAG_POS_Z_CONST) != 0; + bool constantColor = (flags & ResAnmLightData::FLAG_COLOR_CONST) != 0; + + pResult->pos.x = detail::GetResAnmResult(&r.posX, frame, constantPosX); + pResult->pos.y = detail::GetResAnmResult(&r.posY, frame, constantPosY); + pResult->pos.z = detail::GetResAnmResult(&r.posZ, frame, constantPosZ); + pResult->color = + detail::GetResColorAnmResult(&r.color, clippedFrame, constantColor); + + if (hasAim) { + bool constantAimX = + (flags & ResAnmLightData::FLAG_AIM_X_CONST) != 0; + bool constantAimY = + (flags & ResAnmLightData::FLAG_AIM_Y_CONST) != 0; + bool constantAimZ = + (flags & ResAnmLightData::FLAG_AIM_Z_CONST) != 0; + + pResult->aim.x = + detail::GetResAnmResult(&r.aimX, frame, constantAimX); + pResult->aim.y = + detail::GetResAnmResult(&r.aimY, frame, constantAimY); + pResult->aim.z = + detail::GetResAnmResult(&r.aimZ, frame, constantAimZ); + } + + switch (type) { + case LIGHTTYPE_POINT: { + bool refDistanceConstant = + (flags & ResAnmLightData::FLAG_REF_DISTANCE_CONST) != 0; + bool refBrightnessConstant = + (flags & ResAnmLightData::FLAG_REF_BRIGHTNESS_CONST) != 0; + + pResult->distFunc = r.distFunc; + + pResult->refDistance = detail::GetResAnmResult( + &r.refDistance, frame, refDistanceConstant); + + pResult->refBrightness = detail::GetResAnmResult( + &r.refBrightness, frame, refBrightnessConstant); + break; + } + + case LIGHTTYPE_DIRECTIONAL: { + break; + } + + case LIGHTTYPE_SPOT: { + bool cutoffConstant = + (flags & ResAnmLightData::FLAG_CUTOFF_CONST) != 0; + bool refDistanceConstant = + (flags & ResAnmLightData::FLAG_REF_DISTANCE_CONST) != 0; + bool refBrightnessConstant = + (flags & ResAnmLightData::FLAG_REF_BRIGHTNESS_CONST) != 0; + + pResult->distFunc = r.distFunc; + pResult->spotFunc = r.spotFunc; + + pResult->cutoff = + detail::GetResAnmResult(&r.cutoff, frame, cutoffConstant); + + pResult->refDistance = detail::GetResAnmResult( + &r.refDistance, frame, refDistanceConstant); + + pResult->refBrightness = detail::GetResAnmResult( + &r.refBrightness, frame, refBrightnessConstant); + break; + } + } + + if (hasSpecular) { + bool specColorConstant = + (flags & ResAnmLightData::FLAG_SPEC_COLOR_CONST) != 0; + bool shininessConstant = + (flags & ResAnmLightData::FLAG_SHININESS_CONST) != 0; + + pResult->specColor = detail::GetResColorAnmResult( + &r.specColor, clippedFrame, specColorConstant); + + pResult->shininess = + detail::GetResAnmResult(&r.shininess, frame, shininessConstant); + + pResult->specIdx = r.specLightObjIdx; + } + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resanmscn.cpp b/src/nw4r/g3d/res/g3d_resanmscn.cpp new file mode 100644 index 00000000..aaa69c56 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resanmscn.cpp @@ -0,0 +1,196 @@ +#include + +namespace nw4r { +namespace g3d { +namespace { + +NW4R_G3D_RESFILE_NAME_DEF(LightSet, "LightSet(NW4R)"); +NW4R_G3D_RESFILE_NAME_DEF(AmbLights, "AmbLights(NW4R)"); +NW4R_G3D_RESFILE_NAME_DEF(Lights, "Lights(NW4R)"); + +} // namespace + +bool ResAnmScn::HasResAnmAmbLight() const { + return ResDic(ofs_to_obj( + ref().toScnTopLevelDic))[ResName(&ResNameData_AmbLights)] != + NULL; +} + +bool ResAnmScn::HasResAnmLight() const { + return ResDic(ofs_to_obj( + ref().toScnTopLevelDic))[ResName(&ResNameData_Lights)] != NULL; +} + +ResLightSet ResAnmScn::GetResLightSet(int idx) const { + void* pResLightSetDicData = ResDic(ofs_to_obj( + ref().toScnTopLevelDic))[ResName(&ResNameData_LightSet)]; + + if (pResLightSetDicData != NULL) { + return ResLightSet(ResDic(pResLightSetDicData)[idx]); + } + + return ResLightSet(NULL); +} + +ResLightSet ResAnmScn::GetResLightSet(u32 idx) const { + return GetResLightSet(static_cast(idx)); +} + +u32 ResAnmScn::GetResLightSetNumEntries() const { + void* pResLightSetDicData = ResDic(ofs_to_obj( + ref().toScnTopLevelDic))[ResName(&ResNameData_LightSet)]; + + if (pResLightSetDicData != NULL) { + return ResDic(pResLightSetDicData).GetNumData(); + } + + return 0; +} + +ResAnmAmbLight ResAnmScn::GetResAnmAmbLight(const ResName name) const { + void* pResAnmAmbLightDicData = ResDic(ofs_to_obj( + ref().toScnTopLevelDic))[ResName(&ResNameData_AmbLights)]; + + if (pResAnmAmbLightDicData != NULL) { + return ResAnmAmbLight(ResDic(pResAnmAmbLightDicData)[name]); + } + + return ResAnmAmbLight(NULL); +} + +ResAnmAmbLight ResAnmScn::GetResAnmAmbLight(int idx) const { + void* pResAnmAmbLightDicData = ResDic(ofs_to_obj( + ref().toScnTopLevelDic))[ResName(&ResNameData_AmbLights)]; + + if (pResAnmAmbLightDicData != NULL) { + return ResAnmAmbLight(ResDic(pResAnmAmbLightDicData)[idx]); + } + + return ResAnmAmbLight(NULL); +} + +ResAnmAmbLight ResAnmScn::GetResAnmAmbLight(u32 idx) const { + return GetResAnmAmbLight(static_cast(idx)); +} + +ResAnmLight ResAnmScn::GetResAnmLight(const ResName name) const { + void* pResAnmLightDicData = ResDic(ofs_to_obj( + ref().toScnTopLevelDic))[ResName(&ResNameData_Lights)]; + + if (pResAnmLightDicData != NULL) { + return ResAnmLight(ResDic(pResAnmLightDicData)[name]); + } + + return ResAnmLight(NULL); +} + +ResAnmLight ResAnmScn::GetResAnmLight(int idx) const { + void* pResAnmLightDicData = ResDic(ofs_to_obj( + ref().toScnTopLevelDic))[ResName(&ResNameData_Lights)]; + + if (pResAnmLightDicData != NULL) { + return ResAnmLight(ResDic(pResAnmLightDicData)[idx]); + } + + return ResAnmLight(NULL); +} + +ResAnmLight ResAnmScn::GetResAnmLight(u32 idx) const { + return GetResAnmLight(static_cast(idx)); +} + +ResLightSet ResAnmScn::GetResLightSetByRefNumber(u32 refNumber) const { + const ResAnmScnInfoData& rInfoData = ref().info; + + if (rInfoData.numResLightSetData <= refNumber) { + return ResLightSet(NULL); + } + + const ResLightSetData* pArray = + ofs_to_ptr(ref().toResLightSetDataArray); + + ResLightSetData* pTarget = const_cast(&pArray[refNumber]); + + return ResLightSet(pTarget->id < rInfoData.numResLightSetData ? pTarget + : NULL); +} + +ResAnmAmbLight ResAnmScn::GetResAnmAmbLightByRefNumber(u32 refNumber) const { + const ResAnmScnInfoData& rInfoData = ref().info; + + if (rInfoData.numResAnmAmbLightData <= refNumber) { + return ResAnmAmbLight(NULL); + } + + const ResAnmAmbLightData* pArray = + ofs_to_ptr(ref().toResAnmAmbLightDataArray); + + ResAnmAmbLightData* pTarget = + const_cast(&pArray[refNumber]); + + return ResAnmAmbLight( + pTarget->id < rInfoData.numResAnmAmbLightData ? pTarget : NULL); +} + +ResAnmLight ResAnmScn::GetResAnmLightByRefNumber(u32 refNumber) const { + const ResAnmScnInfoData& rInfoData = ref().info; + + if (rInfoData.numResAnmLightData <= refNumber) { + return ResAnmLight(NULL); + } + + const ResAnmLightData* pArray = + ofs_to_ptr(ref().toResAnmLightDataArray); + + ResAnmLightData* pTarget = const_cast(&pArray[refNumber]); + + return ResAnmLight(pTarget->id < rInfoData.numResAnmLightData ? pTarget + : NULL); +} + +ResAnmFog ResAnmScn::GetResAnmFogByRefNumber(u32 refNumber) const { + const ResAnmScnInfoData& rInfoData = ref().info; + + if (rInfoData.numResAnmFogData <= refNumber) { + return ResAnmFog(NULL); + } + + const ResAnmFogData* pArray = + ofs_to_ptr(ref().toResAnmFogDataArray); + + ResAnmFogData* pTarget = const_cast(&pArray[refNumber]); + + return ResAnmFog(pTarget->id < rInfoData.numResAnmFogData ? pTarget : NULL); +} + +ResAnmCamera ResAnmScn::GetResAnmCameraByRefNumber(u32 refNumber) const { + const ResAnmScnInfoData& rInfoData = ref().info; + + if (rInfoData.numResAnmCameraData <= refNumber) { + return ResAnmCamera(NULL); + } + + const ResAnmCameraData* pArray = + ofs_to_ptr(ref().toResAnmCameraDataArray); + + ResAnmCameraData* pTarget = + const_cast(&pArray[refNumber]); + + return ResAnmCamera(pTarget->id < rInfoData.numResAnmCameraData ? pTarget + : NULL); +} + +bool ResAnmScn::Bind(const ResAnmScn scene) { + u32 lightSetNum = GetResLightSetNumEntries(); + bool success = true; + + for (u32 i = 0; i < lightSetNum; i++) { + ResLightSet set = GetResLightSet(i); + success = set.Bind(scene) && success; + } + + return success; +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resanmshp.cpp b/src/nw4r/g3d/res/g3d_resanmshp.cpp new file mode 100644 index 00000000..bff70576 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resanmshp.cpp @@ -0,0 +1,38 @@ +#include + +namespace nw4r { +namespace g3d { + +void ResAnmShp::GetAnmResult(ShpAnmResult* pResult, u32 idx, f32 frame, + const ShpAnmVtxSet* pShapeArray) const { + const ResAnmShpAnmData* pAnmData = GetShapeAnm(idx); + + const u16* pAnmIdxToVtxIdxTable = static_cast( + ut::AddOffsetToPtr(pAnmData, pAnmData->toAnmIdxToVtxIdxTable)); + + u32 flags = pAnmData->flags; + u32 constFlags = pAnmData->constFlags; + + pResult->flags = flags; + pResult->numKeyShape = pAnmData->numKeyShape; + pResult->baseShapeVtxSet = pShapeArray[pAnmData->baseShapeVtxIdx]; + pResult->baseShapeWeight = 1.0f; + + for (int i = 0; i < pAnmData->numKeyShape; constFlags >>= 1, i++) { + BlendVtx& rShape = pResult->keyShape[i]; + + bool constant = (constFlags & 1) != 0; + int vtxIdx = pAnmIdxToVtxIdxTable[i]; + + f32 weight = + detail::GetResAnmResult(&pAnmData->anms[i], frame, constant); + + rShape.vtxSet = pShapeArray[vtxIdx]; + rShape.weight = weight; + + pResult->baseShapeWeight -= weight; + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resanmtexpat.cpp b/src/nw4r/g3d/res/g3d_resanmtexpat.cpp new file mode 100644 index 00000000..3cae607c --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resanmtexpat.cpp @@ -0,0 +1,185 @@ +#include + +#include +#include + +namespace nw4r { +namespace g3d { + +ResFile ResAnmTexPat::GetParent() const { + return ofs_to_obj(ref().toResFileData); +} + +namespace { + +const ResAnmTexPatFrmData* SearchFrame(const ResAnmTexPatAnmData* pAnmData, + f32 frame) { + const ResAnmTexPatFrmData& rFirst = pAnmData->frameValues[0]; + const ResAnmTexPatFrmData& rLast = + pAnmData->frameValues[pAnmData->numFrameValues - 1]; + + if (frame <= rFirst.frame) { + return &rFirst; + } + + if (rLast.frame <= frame) { + return &rLast; + } + + f32 frameOffset = frame - rFirst.frame; + f32 numKeyFrame = math::U16ToF32(pAnmData->numFrameValues); + + f32 fEstimate = frameOffset * numKeyFrame * pAnmData->invKeyFrameRange; + u16 iEstimate = math::F32ToU16(fEstimate); + + const ResAnmTexPatFrmData* pFrmData = &pAnmData->frameValues[iEstimate]; + + if (frame < pFrmData->frame) { + do { + pFrmData--; + } while (frame < pFrmData->frame); + } else { + do { + pFrmData++; + } while (pFrmData->frame <= frame); + + pFrmData--; + } + + return pFrmData; +} + +inline ResName GetResNameFromOffsetArray(s32* pStringArray, int idx) { + s32 offset = pStringArray[idx]; + return NW4R_G3D_OFS_TO_RESNAME(pStringArray, offset); +} + +} // namespace + +void ResAnmTexPat::GetAnmResult(TexPatAnmResult* pResult, u32 idx, + f32 frame) const { + (void)GetParent(); // unused + + const ResAnmTexPatMatData* pMatData = GetMatAnm(idx); + const ResAnmTexPatMatData::AnmData* pAnmDataImpl = pMatData->anms; + u32 flags = pMatData->flags; + + const ResAnmTexPatData& r = ref(); + const ResTex* pResTexArray = ofs_to_ptr(r.toResTexArray); + const ResPltt* pResPlttArray = ofs_to_ptr(r.toResPlttArray); + + pResult->bTexExist = 0; + pResult->bPlttExist = 0; + + for (int i = 0; i < TexPatAnmResult::NUM_OF_ANMS; + flags >>= ResAnmTexPatMatData::NUM_OF_FLAGS, i++) { + + if (!(flags & ResAnmTexPatMatData::FLAG_ANM_EXISTS)) { + continue; + } + + int texIndex, plttIndex; + if (flags & ResAnmTexPatMatData::FLAG_ANM_CONST) { + texIndex = pAnmDataImpl->constValue.texIndex; + plttIndex = pAnmDataImpl->constValue.plttIndex; + } else { + const ResAnmTexPatAnmData* pAnmData = + static_cast(ut::AddOffsetToPtr( + pMatData, pAnmDataImpl->toResAnmTexPatAnmData)); + + const ResAnmTexPatFrmData* pFrmData = SearchFrame(pAnmData, frame); + texIndex = pFrmData->texIndex; + plttIndex = pFrmData->plttIndex; + } + + u32 targetBit = 1 << i; + + if (flags & ResAnmTexPatMatData::FLAG_ANM_TEX) { + ResTex tex(pResTexArray[texIndex]); + + if (tex.IsValid()) { + pResult->tex[i] = tex; + pResult->bTexExist |= targetBit; + } + } + + if (flags & ResAnmTexPatMatData::FLAG_ANM_PLTT) { + ResPltt pltt(pResPlttArray[plttIndex]); + + if (pltt.IsValid()) { + pResult->pltt[i] = pltt; + pResult->bPlttExist |= targetBit; + } + } + + pAnmDataImpl++; + } +} + +bool ResAnmTexPat::Bind(const ResFile file) { + const ResAnmTexPatInfoData& rInfoData = ref().info; + int numTexture = rInfoData.numTexture; + int numPalette = rInfoData.numPalette; + + s32* pTexNameArray = ofs_to_ptr(ref().toTexNameArray); + s32* pPlttNameArray = ofs_to_ptr(ref().toPlttNameArray); + + ResTex* pResTexArray = ofs_to_ptr(ref().toResTexArray); + ResPltt* pResPlttArray = ofs_to_ptr(ref().toResPlttArray); + + int numBound = 0; + + for (int i = 0; i < numTexture; i++) { + ResTex tex(pResTexArray[i]); + + if (tex.IsValid()) { + numBound++; + } else { + ResTex found = + file.GetResTex(GetResNameFromOffsetArray(pTexNameArray, i)); + + if (found.IsValid()) { + pResTexArray[i] = found; + numBound++; + } + } + } + + for (int i = 0; i < numPalette; i++) { + ResPltt pltt(pResPlttArray[i]); + + if (pltt.IsValid()) { + numBound++; + } else { + ResPltt found = + file.GetResPltt(GetResNameFromOffsetArray(pPlttNameArray, i)); + + if (found.IsValid()) { + pResPlttArray[i] = found; + numBound++; + } + } + } + + return numBound == numTexture + numPalette; +} + +void ResAnmTexPat::Release() { + const ResAnmTexPatInfoData& rInfoData = ref().info; + int numTexture = rInfoData.numTexture; + int numPalette = rInfoData.numPalette; + + ResTex* pResTexArray = ofs_to_ptr(ref().toResTexArray); + ResPltt* pResPlttArray = ofs_to_ptr(ref().toResPlttArray); + + for (int i = 0; i < numTexture; i++) { + pResTexArray[i] = ResTex(NULL); + } + + for (int i = 0; i < numPalette; i++) { + pResPlttArray[i] = ResPltt(NULL); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resanmtexsrt.cpp b/src/nw4r/g3d/res/g3d_resanmtexsrt.cpp new file mode 100644 index 00000000..a05c8ce2 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resanmtexsrt.cpp @@ -0,0 +1,114 @@ +#include + +#include +#include + +namespace nw4r { +namespace g3d { +namespace { + +inline u32 MakeResult(TexSrt* pSrt, const ResAnmTexSrtTexData* pTexData, + f32 frame) { + int anmIdx = 0; + u32 flags = pTexData->flags; + TexSrt& rSrt = *pSrt; + + if (!(flags & ResAnmTexSrtTexData::FLAG_SCALE_ONE)) { + bool suConstant = flags & ResAnmTexSrtTexData::FLAG_SCALE_U_CONST; + + rSrt.Su = detail::GetResAnmResult(&pTexData->anms[anmIdx++], frame, + suConstant); + + if (flags & ResAnmTexSrtTexData::FLAG_SCALE_UNIFORM) { + rSrt.Sv = rSrt.Su; + } else { + bool svConstant = flags & ResAnmTexSrtTexData::FLAG_SCALE_V_CONST; + + rSrt.Sv = detail::GetResAnmResult(&pTexData->anms[anmIdx++], frame, + svConstant); + } + } else { + rSrt.Su = 1.0f; + rSrt.Sv = 1.0f; + } + + if (!(flags & ResAnmTexSrtTexData::FLAG_ROT_ZERO)) { + bool rConstant = flags & ResAnmTexSrtTexData::FLAG_ROT_CONST; + + rSrt.R = detail::GetResAnmResult(&pTexData->anms[anmIdx++], frame, + rConstant); + } else { + rSrt.R = 0.0f; + } + + if (!(flags & ResAnmTexSrtTexData::FLAG_TRANS_ZERO)) { + bool tuConstant = flags & ResAnmTexSrtTexData::FLAG_TRANS_U_CONST; + bool tvConstant = flags & ResAnmTexSrtTexData::FLAG_TRANS_V_CONST; + + rSrt.Tu = detail::GetResAnmResult(&pTexData->anms[anmIdx++], frame, + tuConstant); + rSrt.Tv = detail::GetResAnmResult(&pTexData->anms[anmIdx++], frame, + tvConstant); + } else { + rSrt.Tu = 0.0f; + rSrt.Tv = 0.0f; + } + + return flags & (ResAnmTexSrtTexData::FLAG_ANM_EXISTS | + ResAnmTexSrtTexData::FLAG_SCALE_ONE | + ResAnmTexSrtTexData::FLAG_ROT_ZERO | + ResAnmTexSrtTexData::FLAG_TRANS_ZERO); +} + +} // namespace + +void ResAnmTexSrt::GetAnmResult(TexSrtAnmResult* pResult, u32 idx, + f32 frame) const { + const ResAnmTexSrtMatData* pMatData = GetMatAnm(idx); + const s32* pToTexData = pMatData->toResAnmTexSrtTexData; + u32 flags = pMatData->flags; + u32 indFlags = pMatData->indFlags; + + pResult->flags = 0; + pResult->indFlags = 0; + pResult->texMtxMode = ref().info.texMtxMode; + + int index; + + for (index = 0; flags != 0; + flags >>= ResAnmTexSrtMatData::NUM_OF_FLAGS, index++) { + + if (!(flags & ResAnmTexSrtMatData::FLAG_ANM_EXISTS)) { + continue; + } + + int srtIndex = index; + + const ResAnmTexSrtTexData* pTexData = + reinterpret_cast( + ut::AddOffsetToPtr(pMatData, *pToTexData++)); + + u32 result = MakeResult(&pResult->srt[srtIndex], pTexData, frame); + pResult->flags |= result << (index * TexSrtAnmResult::NUM_OF_FLAGS); + } + + for (index = 0; indFlags != 0; + indFlags >>= ResAnmTexSrtMatData::NUM_OF_FLAGS, index++) { + + if (!(indFlags & ResAnmTexSrtMatData::FLAG_ANM_EXISTS)) { + continue; + } + + int srtIndex = index + TexSrtAnmResult::NUM_OF_MAT_TEX_MTX; + + const ResAnmTexSrtTexData* pTexData = + reinterpret_cast( + ut::AddOffsetToPtr(pMatData, *pToTexData++)); + + u32 result = MakeResult(&pResult->srt[srtIndex], pTexData, frame); + pResult->indFlags |= result << (index * TexSrtAnmResult::NUM_OF_FLAGS); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resanmvis.cpp b/src/nw4r/g3d/res/g3d_resanmvis.cpp new file mode 100644 index 00000000..671b6fe7 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resanmvis.cpp @@ -0,0 +1,22 @@ +#include + +namespace nw4r { +namespace g3d { + +bool ResAnmVis::GetAnmResult(u32 idx, f32 frame) const { + const ResAnmVisAnmData* pAnmData = GetNodeAnm(idx); + const ResAnmVisInfoData& rInfoData = ref().info; + + if (pAnmData->flags & ResAnmVisAnmData::FLAG_CONST) { + return pAnmData->flags & ResAnmVisAnmData::FLAG_ENABLE; + } + + f32 fClippedFrame = detail::ClipFrame(rInfoData, frame); + int iClippedFrame = static_cast(math::FFloor(fClippedFrame)); + + return detail::GetResBoolAnmFramesResult(&pAnmData->visibility, + iClippedFrame); +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_rescommon.cpp b/src/nw4r/g3d/res/g3d_rescommon.cpp new file mode 100644 index 00000000..4554f3e9 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_rescommon.cpp @@ -0,0 +1,63 @@ +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +bool ResName::operator==(const ResName rhs) const { + if (GetLength() == rhs.GetLength()) { + return std::strcmp(GetName(), rhs.GetName()) == 0; + } + + return false; +} + +namespace detail { + +void ResWriteBPCmd(u8 *pPtr, u32 reg) { + ResWrite_u8(pPtr + 0, GX_FIFO_CMD_LOAD_BP_REG); + ResWrite_u32(pPtr + 1, reg); +} + +void ResWriteBPCmd(u8 *pPtr, u32 reg, u32 mask) { + ResWrite_u8(pPtr + 0, GX_FIFO_CMD_LOAD_BP_REG); + + u32 orig; + ResReadBPCmd(pPtr + 0, &orig); + + // Insert register value into the original command using the mask + orig &= ~mask; + reg &= mask; + + ResWrite_u32(pPtr + 1, reg | orig); +} + +void ResWriteCPCmd(u8 *pPtr, u8 addr, u32 value) { + ResWrite_u8(pPtr + 0, GX_FIFO_CMD_LOAD_CP_REG); + ResWrite_u8(pPtr + 1, addr); + ResWrite_u32(pPtr + 2, value); +} + +void ResWriteXFCmd(u8 *pPtr, u16 addr, u32 value) { + ResWrite_u8(pPtr + 0, GX_FIFO_CMD_LOAD_XF_REG); + ResWrite_u16(pPtr + 1, 0x0000); // No size (single write) + ResWrite_u16(pPtr + 3, addr); + ResWrite_u32(pPtr + 5, value); +} + +void ResWriteSSMask(u8 *pPtr, u32 value) { + u32 orig = ResRead_u32(pPtr + 1); + + // Overwrite BP register ID + orig |= value; + orig |= GX_BP_REG_SSMASK << GX_BP_OPCODE_SHIFT; + + ResWriteBPCmd(pPtr + 0, orig); +} + +} // namespace detail +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resdict.cpp b/src/nw4r/g3d/res/g3d_resdict.cpp new file mode 100644 index 00000000..49b157b6 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resdict.cpp @@ -0,0 +1,100 @@ +#include + +#include + +namespace nw4r { +namespace g3d { + +ResDicNodeData* ResDic::Get(const ResName name) const { + u32 len = name.GetLength(); + const char* pName = name.GetName(); + const ResDicData& r = ref(); + + const ResDicNodeData* c = &r.data[0]; + const ResDicNodeData* x = &r.data[c->idxLeft]; + + while (c->ref > x->ref) { + c = x; + + u32 wd = x->ref >> 3; + u32 pos = x->ref & 7; + + if (wd < len && (pName[wd] >> pos) & 1) { + x = &r.data[x->idxRight]; + } else { + x = &r.data[x->idxLeft]; + } + } + + if (name == NW4R_G3D_OFS_TO_RESNAME(&r, x->ofsString)) { + return const_cast(x); + } + + return NULL; +} + +ResDicNodeData* ResDic::Get(const char* pName, u32 len) const { + const ResDicData& r = ref(); + + const ResDicNodeData* c = &r.data[0]; + const ResDicNodeData* x = &r.data[c->idxLeft]; + + while (c->ref > x->ref) { + c = x; + + u32 wd = x->ref >> 3; + u32 pos = x->ref & 7; + + if (wd < len && (pName[wd] >> pos) & 1) { + x = &r.data[x->idxRight]; + } else { + x = &r.data[x->idxLeft]; + } + } + + if (x->ofsString != 0 && + std::strcmp(pName, ofs_to_ptr(x->ofsString)) == 0) { + return const_cast(x); + } + + return NULL; +} + +void* ResDic::operator[](const char* pName) const { + if (IsValid() && pName != NULL) { + ResDicNodeData* pNode = Get(pName, std::strlen(pName)); + + if (pNode != NULL) { + return const_cast(ofs_to_ptr_raw(pNode->ofsData)); + } + } + + return NULL; +} + +void* ResDic::operator[](const ResName name) const { + if (IsValid() && name.IsValid()) { + ResDicNodeData* pNode = Get(name); + + if (pNode != NULL) { + return const_cast(ofs_to_ptr_raw(pNode->ofsData)); + } + } + + return NULL; +} + +s32 ResDic::GetIndex(const ResName name) const { + if (IsValid() && name.IsValid()) { + ResDicNodeData* pNode = Get(name); + + if (pNode != NULL) { + return pNode - (ref().data + 1); + } + } + + return NOT_FOUND; +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resfile.cpp b/src/nw4r/g3d/res/g3d_resfile.cpp new file mode 100644 index 00000000..a597bab4 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resfile.cpp @@ -0,0 +1,584 @@ +#include + +namespace nw4r { +namespace g3d { +namespace { + +NW4R_G3D_RESFILE_NAME_DEF(Models, "3DModels(NW4R)"); +NW4R_G3D_RESFILE_NAME_DEF(Pltts, "Palettes(NW4R)"); +NW4R_G3D_RESFILE_NAME_DEF(Textures, "Textures(NW4R)"); +NW4R_G3D_RESFILE_NAME_DEF(AnmChr, "AnmChr(NW4R)"); +NW4R_G3D_RESFILE_NAME_DEF(AnmVis, "AnmVis(NW4R)"); +NW4R_G3D_RESFILE_NAME_DEF(AnmClr, "AnmClr(NW4R)"); +NW4R_G3D_RESFILE_NAME_DEF(AnmTexPat, "AnmTexPat(NW4R)"); +NW4R_G3D_RESFILE_NAME_DEF(AnmTexSrt, "AnmTexSrt(NW4R)"); +NW4R_G3D_RESFILE_NAME_DEF(AnmShp, "AnmShp(NW4R)"); +NW4R_G3D_RESFILE_NAME_DEF(AnmScn, "AnmScn(NW4R)"); +NW4R_G3D_RESFILE_NAME_DEF(Ext, "External"); + +} // namespace + +/****************************************************************************** + * + * ResMdl + * + ******************************************************************************/ +ResMdl ResFile::GetResMdl(const char *pName) const { + void *pResMdlDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_Models)]; + + if (pResMdlDicData != NULL) { + return ResMdl(ResDic(pResMdlDicData)[pName]); + } + + return ResMdl(NULL); +} + +ResMdl ResFile::GetResMdl(int idx) const { + void *pResMdlDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_Models)]; + + if (pResMdlDicData != NULL) { + return ResMdl(ResDic(pResMdlDicData)[idx]); + } + + return ResMdl(NULL); +} + +ResMdl ResFile::GetResMdl(u32 idx) const { + return GetResMdl(static_cast(idx)); +} + +/****************************************************************************** + * + * ResPltt + * + ******************************************************************************/ +ResPltt ResFile::GetResPltt(const char *pName) const { + void *pResPlttDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_Pltts)]; + + if (pResPlttDicData != NULL) { + return ResPltt(ResDic(pResPlttDicData)[pName]); + } + + return ResPltt(NULL); +} + +ResPltt ResFile::GetResPltt(const ResName name) const { + void *pResPlttDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_Pltts)]; + + if (pResPlttDicData != NULL) { + return ResPltt(ResDic(pResPlttDicData)[name]); + } + + return ResPltt(NULL); +} + +ResPltt ResFile::GetResPltt(int idx) const { + void *pResPlttDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_Pltts)]; + + if (pResPlttDicData != NULL) { + return ResPltt(ResDic(pResPlttDicData)[idx]); + } + + return ResPltt(NULL); +} + +ResPltt ResFile::GetResPltt(u32 idx) const { + return GetResPltt(static_cast(idx)); +} + +/****************************************************************************** + * + * ResTex + * + ******************************************************************************/ +ResTex ResFile::GetResTex(const char *pName) const { + void *pResTexDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_Textures)]; + + if (pResTexDicData != NULL) { + return ResTex(ResDic(pResTexDicData)[pName]); + } + + return ResTex(NULL); +} + +ResTex ResFile::GetResTex(const ResName name) const { + void *pResTexDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_Textures)]; + + if (pResTexDicData != NULL) { + return ResTex(ResDic(pResTexDicData)[name]); + } + + return ResTex(NULL); +} + +ResTex ResFile::GetResTex(int idx) const { + void *pResTexDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_Textures)]; + + if (pResTexDicData != NULL) { + return ResTex(ResDic(pResTexDicData)[idx]); + } + + return ResTex(NULL); +} + +ResTex ResFile::GetResTex(u32 idx) const { + return GetResTex(static_cast(idx)); +} + +/****************************************************************************** + * + * ResAnmChr + * + ******************************************************************************/ +ResAnmChr ResFile::GetResAnmChr(const char *pName) const { + void *pResAnmChrDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmChr)]; + + if (pResAnmChrDicData != NULL) { + return ResAnmChr(ResDic(pResAnmChrDicData)[pName]); + } + + return ResAnmChr(NULL); +} + +ResAnmChr ResFile::GetResAnmChr(int idx) const { + void *pResAnmChrDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmChr)]; + + if (pResAnmChrDicData != NULL) { + return ResAnmChr(ResDic(pResAnmChrDicData)[idx]); + } + + return ResAnmChr(NULL); +} + +ResAnmChr ResFile::GetResAnmChr(u32 idx) const { + return GetResAnmChr(static_cast(idx)); +} + +/****************************************************************************** + * + * ResAnmVis + * + ******************************************************************************/ +ResAnmVis ResFile::GetResAnmVis(const char *pName) const { + void *pResAnmVisDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmVis)]; + + if (pResAnmVisDicData != NULL) { + return ResAnmVis(ResDic(pResAnmVisDicData)[pName]); + } + + return ResAnmVis(NULL); +} + +ResAnmVis ResFile::GetResAnmVis(int idx) const { + void *pResAnmVisDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmVis)]; + + if (pResAnmVisDicData != NULL) { + return ResAnmVis(ResDic(pResAnmVisDicData)[idx]); + } + + return ResAnmVis(NULL); +} + +ResAnmVis ResFile::GetResAnmVis(u32 idx) const { + return GetResAnmVis(static_cast(idx)); +} + +/****************************************************************************** + * + * ResAnmClr + * + ******************************************************************************/ +ResAnmClr ResFile::GetResAnmClr(const char *pName) const { + void *pResAnmClrDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmClr)]; + + if (pResAnmClrDicData != NULL) { + return ResAnmClr(ResDic(pResAnmClrDicData)[pName]); + } + + return ResAnmClr(NULL); +} + +ResAnmClr ResFile::GetResAnmClr(int idx) const { + void *pResAnmClrDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmClr)]; + + if (pResAnmClrDicData != NULL) { + return ResAnmClr(ResDic(pResAnmClrDicData)[idx]); + } + + return ResAnmClr(NULL); +} + +ResAnmClr ResFile::GetResAnmClr(u32 idx) const { + return GetResAnmClr(static_cast(idx)); +} + +/****************************************************************************** + * + * ResAnmTexPat + * + ******************************************************************************/ +ResAnmTexPat ResFile::GetResAnmTexPat(const char *pName) const { + void *pResAnmTexPatDicData = + ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmTexPat)]; + + if (pResAnmTexPatDicData != NULL) { + return ResAnmTexPat(ResDic(pResAnmTexPatDicData)[pName]); + } + + return ResAnmTexPat(NULL); +} + +ResAnmTexPat ResFile::GetResAnmTexPat(int idx) const { + void *pResAnmTexPatDicData = + ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmTexPat)]; + + if (pResAnmTexPatDicData != NULL) { + return ResAnmTexPat(ResDic(pResAnmTexPatDicData)[idx]); + } + + return ResAnmTexPat(NULL); +} + +ResAnmTexPat ResFile::GetResAnmTexPat(u32 idx) const { + return GetResAnmTexPat(static_cast(idx)); +} + +/****************************************************************************** + * + * ResAnmTexSrt + * + ******************************************************************************/ +ResAnmTexSrt ResFile::GetResAnmTexSrt(const char *pName) const { + void *pResAnmTexSrtDicData = + ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmTexSrt)]; + + if (pResAnmTexSrtDicData != NULL) { + return ResAnmTexSrt(ResDic(pResAnmTexSrtDicData)[pName]); + } + + return ResAnmTexSrt(NULL); +} + +ResAnmTexSrt ResFile::GetResAnmTexSrt(int idx) const { + void *pResAnmTexSrtDicData = + ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmTexSrt)]; + + if (pResAnmTexSrtDicData != NULL) { + return ResAnmTexSrt(ResDic(pResAnmTexSrtDicData)[idx]); + } + + return ResAnmTexSrt(NULL); +} + +ResAnmTexSrt ResFile::GetResAnmTexSrt(u32 idx) const { + return GetResAnmTexSrt(static_cast(idx)); +} + +/****************************************************************************** + * + * ResAnmShp + * + ******************************************************************************/ +ResAnmShp ResFile::GetResAnmShp(const char *pName) const { + void *pResAnmShpDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmShp)]; + + if (pResAnmShpDicData != NULL) { + return ResAnmShp(ResDic(pResAnmShpDicData)[pName]); + } + + return ResAnmShp(NULL); +} + +ResAnmShp ResFile::GetResAnmShp(int idx) const { + void *pResAnmShpDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmShp)]; + + if (pResAnmShpDicData != NULL) { + return ResAnmShp(ResDic(pResAnmShpDicData)[idx]); + } + + return ResAnmShp(NULL); +} + +ResAnmShp ResFile::GetResAnmShp(u32 idx) const { + return GetResAnmShp(static_cast(idx)); +} + +/****************************************************************************** + * + * ResAnmScn + * + ******************************************************************************/ +ResAnmScn ResFile::GetResAnmScn(const char *pName) const { + void *pResAnmScnDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmScn)]; + + if (pResAnmScnDicData != NULL) { + return ResAnmScn(ResDic(pResAnmScnDicData)[pName]); + } + + return ResAnmScn(NULL); +} + +ResAnmScn ResFile::GetResAnmScn(int idx) const { + void *pResAnmScnDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmScn)]; + + if (pResAnmScnDicData != NULL) { + return ResAnmScn(ResDic(pResAnmScnDicData)[idx]); + } + + return ResAnmScn(NULL); +} + +ResAnmScn ResFile::GetResAnmScn(u32 idx) const { + return GetResAnmScn(static_cast(idx)); +} + +/****************************************************************************** + * + * Miscellaneous + * + ******************************************************************************/ +u32 ResFile::GetResMdlNumEntries() const { + void *pResMdlDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_Models)]; + + if (pResMdlDicData != NULL) { + return ResDic(pResMdlDicData).GetNumData(); + } + + return 0; +} + +u32 ResFile::GetResPlttNumEntries() const { + void *pResPlttDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_Pltts)]; + + if (pResPlttDicData != NULL) { + return ResDic(pResPlttDicData).GetNumData(); + } + + return 0; +} + +u32 ResFile::GetResTexNumEntries() const { + void *pResTexDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_Textures)]; + + if (pResTexDicData != NULL) { + return ResDic(pResTexDicData).GetNumData(); + } + + return 0; +} + +u32 ResFile::GetResAnmChrNumEntries() const { + void *pResAnmChrDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmChr)]; + + if (pResAnmChrDicData != NULL) { + return ResDic(pResAnmChrDicData).GetNumData(); + } + + return 0; +} + +u32 ResFile::GetResAnmVisNumEntries() const { + void *pResAnmVisDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmVis)]; + + if (pResAnmVisDicData != NULL) { + return ResDic(pResAnmVisDicData).GetNumData(); + } + + return 0; +} + +u32 ResFile::GetResAnmClrNumEntries() const { + void *pResAnmClrDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmClr)]; + + if (pResAnmClrDicData != NULL) { + return ResDic(pResAnmClrDicData).GetNumData(); + } + + return 0; +} + +u32 ResFile::GetResAnmTexPatNumEntries() const { + void *pResAnmTexPatDicData = + ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmTexPat)]; + + if (pResAnmTexPatDicData != NULL) { + return ResDic(pResAnmTexPatDicData).GetNumData(); + } + + return 0; +} + +u32 ResFile::GetResAnmTexSrtNumEntries() const { + void *pResAnmTexSrtDicData = + ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmTexSrt)]; + + if (pResAnmTexSrtDicData != NULL) { + return ResDic(pResAnmTexSrtDicData).GetNumData(); + } + + return 0; +} + +u32 ResFile::GetResAnmShpNumEntries() const { + void *pResAnmShpDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmShp)]; + + if (pResAnmShpDicData != NULL) { + return ResDic(pResAnmShpDicData).GetNumData(); + } + + return 0; +} + +u32 ResFile::GetResAnmScnNumEntries() const { + void *pResAnmScnDicData = ResDic(const_cast(&ref().dict.topLevel))[ResName(&ResNameData_AnmScn)]; + + if (pResAnmScnDicData != NULL) { + return ResDic(pResAnmScnDicData).GetNumData(); + } + + return 0; +} + +bool ResFile::Bind(const ResFile file) { + u32 i; + bool success = true; + + u32 mdlNum = GetResMdlNumEntries(); + for (i = 0; i < mdlNum; i++) { + success = GetResMdl(i).Bind(file) && success; + } + + u32 anmTexPatNum = GetResAnmTexPatNumEntries(); + for (i = 0; i < anmTexPatNum; i++) { + // @bug Success value clobbered by most recent result + success = GetResAnmTexPat(i).Bind(file); + } + + return success; +} + +void ResFile::Release() { + u32 i; + + u32 mdlNum = GetResMdlNumEntries(); + for (i = 0; i < mdlNum; i++) { + GetResMdl(i).Release(); + } + + u32 anmTexPatNum = GetResAnmTexPatNumEntries(); + for (i = 0; i < anmTexPatNum; i++) { + GetResAnmTexPat(i).Release(); + } +} + +void ResFile::Init() { + u32 i; + + u32 mdlNum = GetResMdlNumEntries(); + for (i = 0; i < mdlNum; i++) { + GetResMdl(i).Init(); + } + + u32 texNum = GetResTexNumEntries(); + for (i = 0; i < texNum; i++) { + GetResTex(i).Init(); + } + + u32 plttNum = GetResPlttNumEntries(); + for (i = 0; i < plttNum; i++) { + GetResPltt(i).Init(); + } +} + +void ResFile::Terminate() { + u32 i; + + u32 mdlNum = GetResMdlNumEntries(); + for (i = 0; i < mdlNum; i++) { + GetResMdl(i).Terminate(); + } +} + +bool ResFile::CheckRevision() const { + u32 i; + + u32 mdlNum = GetResMdlNumEntries(); + for (i = 0; i < mdlNum; i++) { + if (!GetResMdl(i).CheckRevision()) { + return false; + } + } + + u32 texNum = GetResTexNumEntries(); + for (i = 0; i < texNum; i++) { + if (!GetResTex(i).CheckRevision()) { + return false; + } + } + + u32 plttNum = GetResPlttNumEntries(); + for (i = 0; i < plttNum; i++) { + if (!GetResPltt(i).CheckRevision()) { + return false; + } + } + + u32 anmChrNum = GetResAnmChrNumEntries(); + for (i = 0; i < anmChrNum; i++) { + if (!GetResAnmChr(i).CheckRevision()) { + return false; + } + } + + u32 anmVisNum = GetResAnmVisNumEntries(); + for (i = 0; i < anmVisNum; i++) { + if (!GetResAnmVis(i).CheckRevision()) { + return false; + } + } + + u32 anmClrNum = GetResAnmClrNumEntries(); + for (i = 0; i < anmClrNum; i++) { + if (!GetResAnmClr(i).CheckRevision()) { + return false; + } + } + + u32 anmTexPatNum = GetResAnmTexPatNumEntries(); + for (i = 0; i < anmTexPatNum; i++) { + if (!GetResAnmTexPat(i).CheckRevision()) { + return false; + } + } + + u32 anmTexSrtNum = GetResAnmTexSrtNumEntries(); + for (i = 0; i < anmTexSrtNum; i++) { + if (!GetResAnmTexSrt(i).CheckRevision()) { + return false; + } + } + + u32 anmShpNum = GetResAnmShpNumEntries(); + for (i = 0; i < anmShpNum; i++) { + if (!GetResAnmShp(i).CheckRevision()) { + return false; + } + } + + u32 anmScnNum = GetResAnmScnNumEntries(); + for (i = 0; i < anmScnNum; i++) { + if (!GetResAnmScn(i).CheckRevision()) { + return false; + } + } + + return true; +} + +} // namespace g3d +} // namespace nw4r + +// clang-format off +DECOMP_FORCEACTIVE(g3d_resfile_cpp, + nw4r::g3d::ResNameData_Ext); +// clang-format on diff --git a/src/nw4r/g3d/res/g3d_reslightset.cpp b/src/nw4r/g3d/res/g3d_reslightset.cpp new file mode 100644 index 00000000..2647bfeb --- /dev/null +++ b/src/nw4r/g3d/res/g3d_reslightset.cpp @@ -0,0 +1,65 @@ +#include + +namespace nw4r { +namespace g3d { +namespace { + +inline void SetBind(u16* pId, u32 id) { + *pId = id; +} + +inline bool IsBound(const u16* pId) { + return *pId != ResLightSetData::INVALID_ID; +} + +} // namespace + +bool ResLightSet::Bind(const ResAnmScn scene) { + ResLightSetData& r = ref(); + + int numAllLight = 0; + int numBound = 0; + + if (HasAmbLight() && scene.HasResAnmAmbLight()) { + numAllLight++; + + if (!IsAmbLightBound()) { + ResName name = GetAmbLightResName(); + ResAnmAmbLight light = scene.GetResAnmAmbLight(name); + + if (light.IsValid()) { + SetBind(&r.ambLightId, light.GetID()); + numBound++; + } + } else { + numBound++; + } + } + + if (scene.HasResAnmLight()) { + u32 numLight = GetNumLight(); + numAllLight += numLight; + + for (u32 i = 0; i < numLight; i++) { + u16* pId = &r.lightId[i]; + + if (IsBound(pId)) { + numBound++; + continue; + } + + ResName name = GetLightResName(i); + ResAnmLight light = scene.GetResAnmLight(name); + + if (light.IsValid()) { + SetBind(pId, light.GetID()); + numBound++; + } + } + } + + return numBound == numAllLight; +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resmat.cpp b/src/nw4r/g3d/res/g3d_resmat.cpp new file mode 100644 index 00000000..023fdb8c --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resmat.cpp @@ -0,0 +1,1519 @@ +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * GetParent + * + ******************************************************************************/ +ResMdl ResMat::GetParent() { + return ofs_to_obj(ref().toResMdlData); +} + +/****************************************************************************** + * + * DCStore + * + ******************************************************************************/ +void ResMatPix::DCStore(bool sync) { + ResPixDL &r = ref(); + + if (sync) { + DC::StoreRange(&r, sizeof(ResPixDL)); + } else { + DC::StoreRangeNoSync(&r, sizeof(ResPixDL)); + } +} + +void ResMatTevColor::DCStore(bool sync) { + ResTevColorDL &r = ref(); + + if (sync) { + DC::StoreRange(&r, sizeof(ResTevColorDL)); + } else { + DC::StoreRangeNoSync(&r, sizeof(ResTevColorDL)); + } +} + +void ResMatIndMtxAndScale::DCStore(bool sync) { + ResIndMtxAndScaleDL &r = ref(); + + if (sync) { + DC::StoreRange(&r, sizeof(ResIndMtxAndScaleDL)); + } else { + DC::StoreRangeNoSync(&r, sizeof(ResIndMtxAndScaleDL)); + } +} + +void ResMatTexCoordGen::DCStore(bool sync) { + ResTexCoordGenDL &r = ref(); + + if (sync) { + DC::StoreRange(&r, sizeof(ResTexCoordGenDL)); + } else { + DC::StoreRangeNoSync(&r, sizeof(ResTexCoordGenDL)); + } +} + +/****************************************************************************** + * + * CallDisplayList + * + ******************************************************************************/ +void ResMatPix::CallDisplayList(bool sync) const { + const ResPixDL &r = ref(); + + if (sync) { + GXCallDisplayList(const_cast(&r), sizeof(ResPixDL)); + } else { + GXFastCallDisplayList(const_cast(&r), sizeof(ResPixDL)); + } +} + +void ResMatTevColor::CallDisplayList(bool sync) const { + const ResTevColorDL &r = ref(); + + if (sync) { + GXCallDisplayList(const_cast(&r), sizeof(ResTevColorDL)); + } else { + GXFastCallDisplayList(const_cast(&r), sizeof(ResTevColorDL)); + } +} + +/****************************************************************************** + * + * CopyTo + * + ******************************************************************************/ +ResMatPix ResMatPix::CopyTo(void *pDst) const { + detail::Copy32ByteBlocks(pDst, ptr(), sizeof(ResPixDL)); + return ResMatPix(pDst); +} + +ResMatTevColor ResMatTevColor::CopyTo(void *pDst) const { + detail::Copy32ByteBlocks(pDst, ptr(), sizeof(ResTevColorDL)); + return ResMatTevColor(pDst); +} + +ResMatIndMtxAndScale ResMatIndMtxAndScale::CopyTo(void *pDst) const { + detail::Copy32ByteBlocks(pDst, ptr(), sizeof(ResIndMtxAndScaleDL)); + return ResMatIndMtxAndScale(pDst); +} + +ResMatTexCoordGen ResMatTexCoordGen::CopyTo(void *pDst) const { + detail::Copy32ByteBlocks(pDst, ptr(), sizeof(ResTexCoordGenDL)); + return ResMatTexCoordGen(pDst); +} + +/****************************************************************************** + * + * ResTexObj + * + ******************************************************************************/ +const GXTexObj *ResTexObj::GetTexObj(GXTexMapID id) const { + if (IsValid() && id >= GX_TEXMAP0 && id <= GX_TEXMAP7) { + return &ptr()->texObj[id]; + } + + return NULL; +} + +GXTexObj *ResTexObj::GetTexObj(GXTexMapID id) { + if (IsValid() && id >= GX_TEXMAP0 && id <= GX_TEXMAP7) { + return &ptr()->texObj[id]; + } + + return NULL; +} + +bool ResTexObj::IsValidTexObj(GXTexMapID id) const { + if (IsValid() && id >= GX_TEXMAP0 && id <= GX_TEXMAP7) { + return ptr()->flagUsedTexMapID & (1 << id); + } + + return false; +} + +void ResTexObj::Validate(GXTexMapID id) { + if (IsValid() && id >= GX_TEXMAP0 && id <= GX_TEXMAP7) { + ptr()->flagUsedTexMapID |= (1 << id); + } +} + +void ResTexObj::Invalidate(GXTexMapID id) { + if (IsValid() && id >= GX_TEXMAP0 && id <= GX_TEXMAP7) { + ptr()->flagUsedTexMapID &= ~(1 << id); + } +} + +ResTexObj ResTexObj::CopyTo(void *pDst) const { + ResTexObjData *pData = static_cast(pDst); + const ResTexObjData &rSrc = ref(); + + u32 i = 0; + + u32 flag = rSrc.flagUsedTexMapID; + pData->flagUsedTexMapID = flag; + + for (; flag != 0; flag >>= 1, i++) { + if (!(flag & 1)) { + continue; + } + + detail::Copy32ByteBlocks(&pData->texObj[i], &rSrc.texObj[i], sizeof(GXTexObj)); + } + + return ResTexObj(pData); +} + +/****************************************************************************** + * + * ResTlutObj + * + ******************************************************************************/ +const GXTlutObj *ResTlutObj::GetTlut(GXTlut tlut) const { + if (IsValid() && tlut >= GX_TLUT0 && tlut <= GX_TLUT7) { + return &ptr()->tlutObj[tlut]; + } + + return NULL; +} + +GXTlutObj *ResTlutObj::GetTlut(GXTlut tlut) { + if (IsValid() && tlut >= GX_TLUT0 && tlut <= GX_TLUT7) { + return &ptr()->tlutObj[tlut]; + } + + return NULL; +} + +bool ResTlutObj::IsValidTlut(GXTlut tlut) const { + if (IsValid() && tlut >= GX_TLUT0 && tlut <= GX_TLUT7) { + return ptr()->flagUsedTlutID & (1 << tlut); + } + + return false; +} + +void ResTlutObj::Validate(GXTlut tlut) { + if (IsValid() && tlut >= GX_TLUT0 && tlut <= GX_TLUT7) { + ptr()->flagUsedTlutID |= (1 << tlut); + } +} + +void ResTlutObj::Invalidate(GXTlut tlut) { + if (IsValid() && tlut >= GX_TLUT0 && tlut <= GX_TLUT7) { + ptr()->flagUsedTlutID &= ~(1 << tlut); + } +} + +ResTlutObj ResTlutObj::CopyTo(void *pDst) const { + ResTlutObjData *pData = static_cast(pDst); + const ResTlutObjData &rSrc = ref(); + + u32 flag = rSrc.flagUsedTlutID; + pData->flagUsedTlutID = flag; + + if (flag != 0) { + if (!(flag & static_cast(~(1 << GX_TLUT0 | 1 << GX_TLUT1)))) { + // At most two tlut objects can fit into 64 bytes + detail::Copy32ByteBlocks(&pData->tlutObj, &rSrc.tlutObj, 32); + + } else if (!(flag & + static_cast(~(1 << GX_TLUT0 | 1 << GX_TLUT1 | 1 << GX_TLUT2 | 1 << GX_TLUT3 | 1 << GX_TLUT4)) + )) { + // At most five tlut objects can fit into 64 bytes + detail::Copy32ByteBlocks(&pData->tlutObj, &rSrc.tlutObj, 64); + + } else { + // Full copy is divisible by 32 + detail::Copy32ByteBlocks(&pData->tlutObj, &rSrc.tlutObj, sizeof(GXTlutObj) * (GX_TLUT7 + 1)); + } + } + + return ResTlutObj(pData); +} + +/****************************************************************************** + * + * ResTexSrt + * + ******************************************************************************/ +ResTexSrt ResTexSrt::CopyTo(void *pDst) const { + ResTexSrtData *pData = static_cast(pDst); + const ResTexSrtData &r = ref(); + + u32 flag = r.flag; + pData->flag = flag; + pData->texMtxMode = r.texMtxMode; + + for (u32 i = 0; flag != 0; flag >>= TexSrt::NUM_OF_FLAGS, i++) { + if (!(flag & TexSrt::FLAGSET_IDENTITY)) { + continue; + } + + const TexSrt &rFrom = r.texSrt[i]; + const TexMtxEffect &rFromEffect = r.effect[i]; + + TexSrt &rTo = pData->texSrt[i]; + TexMtxEffect &rToEffect = pData->effect[i]; + + rTo.Su = rFrom.Su; + rTo.Sv = rFrom.Sv; + rTo.R = rFrom.R; + rTo.Tu = rFrom.Tu; + rTo.Tv = rFrom.Tv; + + rToEffect.ref_camera = rFromEffect.ref_camera; + rToEffect.ref_light = rFromEffect.ref_light; + rToEffect.map_mode = rFromEffect.map_mode; + rToEffect.misc_flag = rFromEffect.misc_flag; + + math::MTX34Copy( + static_cast(&rToEffect.effectMtx), static_cast(&rFromEffect.effectMtx) + ); + } + + return ResTexSrt(pData); +} + +bool ResTexSrt::SetEffectMtx(u32 id, const math::MTX34 *pMtx) { + if (id < ResTexSrtData::NUM_OF_TEXTURE) { + TexMtxEffect &rEffect = ref().effect[id]; + + if (pMtx != NULL) { + math::MTX34Copy(static_cast(&rEffect.effectMtx), pMtx); + + rEffect.misc_flag &= ~TexMtxEffect::FLAG_IDENT; + + } else { + math::MTX34Identity(static_cast(&rEffect.effectMtx)); + + rEffect.misc_flag |= TexMtxEffect::FLAG_IDENT; + } + + return true; + } + + return false; +} + +bool ResTexSrt::GetEffectMtx(u32 id, math::MTX34 *pMtx) const { + if (pMtx != NULL && id < ResTexSrtData::NUM_OF_TEXTURE) { + const TexMtxEffect &rEffect = ref().effect[id]; + + math::MTX34Copy(pMtx, static_cast(&rEffect.effectMtx)); + + return true; + } + + return false; +} + +bool ResTexSrt::SetMapMode(u32 id, u32 mode, int camRef, int lightRef) { + if (id < ResTexSrtData::NUM_OF_TEXTURE && mode < G3DState::NUM_SCNDEPENDENT_TEXMTX_FUNCTYPE) { + ResTexSrtData &r = ref(); + TexMtxEffect &rEffect = r.effect[id]; + + rEffect.map_mode = mode; + + rEffect.ref_camera = camRef >= 0 && camRef < G3DState::NUM_CAMERA ? static_cast(camRef) : -1; + + rEffect.ref_light = lightRef >= 0 && lightRef < G3DState::NUM_LIGHT ? static_cast(lightRef) : -1; + + return true; + } + + return false; +} + +bool ResTexSrt::GetMapMode(u32 id, u32 *pMode, int *pCamRef, int *pLightRef) const { + if (id < ResTexSrtData::NUM_OF_TEXTURE) { + const ResTexSrtData &r = ref(); + const TexMtxEffect &rEffect = r.effect[id]; + + if (pMode != NULL) { + *pMode = rEffect.map_mode; + } + + if (pCamRef != NULL) { + *pCamRef = rEffect.ref_camera; + } + + if (pLightRef != NULL) { + *pLightRef = rEffect.ref_light; + } + + return true; + } + + return false; +} + +/****************************************************************************** + * + * ResGenMode + * + ******************************************************************************/ +void ResGenMode::GXSetNumTexGens(u8 num) { + if (IsValid()) { + ref().nTexGens = num; + } +} + +void ResGenMode::GXSetNumChans(u8 num) { + if (IsValid()) { + ref().nChans = num; + } +} + +void ResGenMode::GXSetNumTevStages(u8 num) { + if (IsValid()) { + ref().nTevs = num; + } +} + +void ResGenMode::GXSetNumIndStages(u8 num) { + if (IsValid()) { + ref().nInds = num; + } +} + +void ResGenMode::GXSetCullMode(GXCullMode mode) { + if (IsValid()) { + ref().cullMode = mode; + } +} + +ResGenMode ResGenMode::CopyTo(void *pDst) const { + ResGenModeData *pData = static_cast(pDst); + const ResGenModeData &r = ref(); + + *pData = r; + return ResGenMode(pData); +} + +/****************************************************************************** + * + * ResMatMisc + * + ******************************************************************************/ +GXBool ResMatMisc::GXGetZCompLoc() const { + if (IsValid()) { + return ptr()->zCompLoc; + } + + return FALSE; +} + +int ResMatMisc::GetLightSetIdx() const { + if (IsValid()) { + return ptr()->light_set_idx; + } + + return -1; +} + +int ResMatMisc::GetFogIdx() const { + if (IsValid()) { + return ptr()->fog_idx; + } + + return -1; +} + +void ResMatMisc::GetIndirectTexMtxCalcMethod(GXIndTexMtxID id, ResMatMiscData::IndirectMethod *pMethod, s8 *pLightRef) { + if (IsValid() && id >= GX_ITM_0 && id <= GX_ITM_2) { + ResMatMiscData &r = *ptr(); + + if (pMethod != NULL) { + *pMethod = static_cast(r.indirect_method[id - GX_ITM_0]); + } + + if (pLightRef != NULL) { + *pLightRef = r.normal_map_ref_light[id - GX_ITM_0]; + } + } +} + +ResMatMisc ResMatMisc::CopyTo(void *pDst) const { + ResMatMiscData *pData = static_cast(pDst); + const ResMatMiscData &r = ref(); + + *pData = r; + return ResMatMisc(pData); +} + +/****************************************************************************** + * + * ResMatPix + * + ******************************************************************************/ +bool ResMatPix::GXGetAlphaCompare(GXCompare *pComp0, u8 *pRef0, GXAlphaOp *pLogic, GXCompare *pComp1, u8 *pRef1) const { + const u8 *pCmd = ref().dl.alphaCompare; + if (pCmd[0] == 0) { + return false; + } + + u32 reg; + detail::ResReadBPCmd(pCmd, ®); + + if (pRef0 != NULL) { + *pRef0 = reg >> GX_BP_ALPHACOMPARE_REF0_SHIFT & GX_BP_ALPHACOMPARE_REF0_LMASK; + } + + if (pRef1 != NULL) { + *pRef1 = reg >> GX_BP_ALPHACOMPARE_REF1_SHIFT & GX_BP_ALPHACOMPARE_REF1_LMASK; + } + + if (pComp0 != NULL) { + *pComp0 = static_cast(reg >> GX_BP_ALPHACOMPARE_COMP0_SHIFT & GX_BP_ALPHACOMPARE_COMP0_LMASK); + } + + if (pComp1 != NULL) { + *pComp1 = static_cast(reg >> GX_BP_ALPHACOMPARE_COMP1_SHIFT & GX_BP_ALPHACOMPARE_COMP1_LMASK); + } + + if (pLogic != NULL) { + *pLogic = static_cast(reg >> GX_BP_ALPHACOMPARE_LOGIC_SHIFT & GX_BP_ALPHACOMPARE_LOGIC_LMASK); + } + + return true; +} + +void ResMatPix::GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp logic, GXCompare comp1, u8 ref1) { + u8 *pCmd = ref().dl.alphaCompare; + + u32 reg = ref0 << GX_BP_ALPHACOMPARE_REF0_SHIFT | ref1 << GX_BP_ALPHACOMPARE_REF1_SHIFT | + comp0 << GX_BP_ALPHACOMPARE_COMP0_SHIFT | comp1 << GX_BP_ALPHACOMPARE_COMP1_SHIFT | + logic << GX_BP_ALPHACOMPARE_LOGIC_SHIFT | GX_BP_REG_ALPHACOMPARE << GX_BP_OPCODE_SHIFT; + + detail::ResWriteBPCmd(pCmd, reg); +} + +bool ResMatPix::GXGetZMode(GXBool *pTest, GXCompare *pCompare, GXBool *pUpdate) const { + const u8 *pCmd = ref().dl.zMode; + if (pCmd[0] == 0) { + return false; + } + + u32 reg; + detail::ResReadBPCmd(pCmd, ®); + + if (pTest != NULL) { + *pTest = reg >> GX_BP_ZMODE_TEST_ENABLE_SHIFT & GX_BP_ZMODE_TEST_ENABLE_LMASK; + } + + if (pCompare != NULL) { + *pCompare = static_cast(reg >> GX_BP_ZMODE_COMPARE_SHIFT & GX_BP_ZMODE_COMPARE_LMASK); + } + + if (pUpdate != NULL) { + // @note Update enable is only one bit + *pUpdate = reg >> GX_BP_ZMODE_UPDATE_ENABLE_SHIFT & 0xFF; + } + + return true; +} + +void ResMatPix::GXSetZMode(GXBool test, GXCompare compare, GXBool update) { + u8 *pCmd = ref().dl.zMode; + + u32 reg = test << GX_BP_ZMODE_TEST_ENABLE_SHIFT | compare << GX_BP_ZMODE_COMPARE_SHIFT | + update << GX_BP_ZMODE_UPDATE_ENABLE_SHIFT | GX_BP_REG_ZMODE << GX_BP_OPCODE_SHIFT; + + detail::ResWriteBPCmd(pCmd, reg); +} + +bool ResMatPix::GXGetBlendMode( + GXBlendMode *pMode, GXBlendFactor *pSrcFactor, GXBlendFactor *pDstFactor, GXLogicOp *pLogic +) const { + const u8 *pCmd = ref().dl.blendMode; + if (pCmd[0] == 0) { + return false; + } + + u32 reg; + detail::ResReadBPCmd(&pCmd[GX_BP_CMD_SZ * 1], ®); + + GXBlendMode mode; + if (reg >> GX_BP_BLENDMODE_LOGIC_OP_ENABLE_SHIFT & GX_BP_BLENDMODE_LOGIC_OP_ENABLE_LMASK) { + mode = GX_BM_LOGIC; + } else if (reg >> GX_BP_BLENDMODE_SUBTRACT_SHIFT & GX_BP_BLENDMODE_SUBTRACT_LMASK) { + mode = GX_BM_SUBTRACT; + } else if (reg >> GX_BP_BLENDMODE_BLEND_ENABLE_SHIFT & GX_BP_BLENDMODE_BLEND_ENABLE_LMASK) { + mode = GX_BM_BLEND; + } else { + mode = GX_BM_NONE; + } + + if (pMode != NULL) { + *pMode = mode; + } + + if (pSrcFactor != NULL) { + *pSrcFactor = + static_cast(reg >> GX_BP_BLENDMODE_SRC_FACTOR_SHIFT & GX_BP_BLENDMODE_SRC_FACTOR_LMASK); + } + + if (pDstFactor != NULL) { + *pDstFactor = + static_cast(reg >> GX_BP_BLENDMODE_DST_FACTOR_SHIFT & GX_BP_BLENDMODE_DST_FACTOR_LMASK); + } + + if (pLogic != NULL) { + *pLogic = static_cast( + // @note Logic mode is only four bits + reg >> GX_BP_BLENDMODE_LOGIC_MODE_SHIFT & 0xFFF + ); + } + + return true; +} + +void ResMatPix::GXSetBlendMode(GXBlendMode mode, GXBlendFactor srcFactor, GXBlendFactor dstFactor, GXLogicOp logic) { + u8 *pCmd = ref().dl.blendMode; + + // clang-format off + detail::ResWriteSSMask(&pCmd[GX_BP_CMD_SZ * 0], + GX_BP_BLENDMODE_BLEND_ENABLE_MASK | GX_BP_BLENDMODE_LOGIC_OP_ENABLE_MASK | + GX_BP_BLENDMODE_DST_FACTOR_MASK | GX_BP_BLENDMODE_SRC_FACTOR_MASK | + GX_BP_BLENDMODE_SUBTRACT_MASK | GX_BP_BLENDMODE_LOGIC_MODE_MASK); + + u32 reg = static_cast(mode == GX_BM_BLEND || mode == GX_BM_SUBTRACT) << GX_BP_BLENDMODE_BLEND_ENABLE_SHIFT | + static_cast(mode == GX_BM_LOGIC) << GX_BP_BLENDMODE_LOGIC_OP_ENABLE_SHIFT | + static_cast(dstFactor) << GX_BP_BLENDMODE_DST_FACTOR_SHIFT | + static_cast(srcFactor) << GX_BP_BLENDMODE_SRC_FACTOR_SHIFT | + static_cast(mode == GX_BM_SUBTRACT) << GX_BP_BLENDMODE_SUBTRACT_SHIFT | + static_cast(logic) << GX_BP_BLENDMODE_LOGIC_MODE_SHIFT | + static_cast(GX_BP_REG_BLENDMODE) << GX_BP_OPCODE_SHIFT; + // clang-format on + + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 1], reg); +} + +bool ResMatPix::GXGetDstAlpha(GXBool *pEnable, u8 *pAlpha) const { + const u8 *pCmd = ref().dl.setDstAlpha; + if (pCmd[0] == 0) { + return false; + } + + u32 reg; + detail::ResReadBPCmd(pCmd, ®); + + if (pEnable != NULL) { + if (reg & GX_BP_DSTALPHA_ENABLE_MASK) { + *pEnable = TRUE; + } else { + *pEnable = FALSE; + } + } + + if (pAlpha != NULL) { + *pAlpha = reg >> GX_BP_DSTALPHA_ALPHA_SHIFT & GX_BP_DSTALPHA_ALPHA_LMASK; + } + + return true; +} + +void ResMatPix::GXSetDstAlpha(GXBool enable, u8 alpha) { + u8 *pCmd = ref().dl.setDstAlpha; + + u32 reg = alpha << GX_BP_DSTALPHA_ALPHA_SHIFT | enable << GX_BP_DSTALPHA_ENABLE_SHIFT | + GX_BP_REG_DSTALPHA << GX_BP_OPCODE_SHIFT; + + detail::ResWriteBPCmd(pCmd, reg); +} + +/****************************************************************************** + * + * ResMatTevColor + * + ******************************************************************************/ +bool ResMatTevColor::GXGetTevColor(GXTevRegID id, GXColor *pColor) const { + const u8 *pCmd = ref().dl.tevColor[id - 1]; + if (pCmd[0] == 0) { + return false; + } + + u32 regRA; + detail::ResReadBPCmd(&pCmd[GX_BP_CMD_SZ * 0], ®RA); + + u32 regBG; + detail::ResReadBPCmd(&pCmd[GX_BP_CMD_SZ * 1], ®BG); + + *pColor = detail::GetRGBA( + regRA >> GX_BP_TEVREGLO_RED_SHIFT & GX_BP_TEVREGLO_RED_LMASK, + regBG >> GX_BP_TEVREGLO_ALPHA_SHIFT & GX_BP_TEVREGLO_ALPHA_LMASK, + regBG >> GX_BP_TEVREGHI_BLUE_SHIFT & GX_BP_TEVREGHI_BLUE_LMASK, + regRA >> GX_BP_TEVREGHI_GREEN_SHIFT & GX_BP_TEVREGHI_GREEN_LMASK + ); + + return true; +} + +void ResMatTevColor::GXSetTevColor(GXTevRegID id, GXColor color) { + u8 *pCmd = ref().dl.tevColor[id - 1]; + + u32 regRA = color.r << GX_BP_TEVREGLO_RED_SHIFT | color.a << GX_BP_TEVREGLO_ALPHA_SHIFT | + GX_TEVREG_COLOR << GX_BP_TEVREGLO_TYPE_SHIFT | (id * 2 + GX_BP_REG_TEVREG0LO) << GX_BP_OPCODE_SHIFT; + + u32 regBG = color.b << GX_BP_TEVREGHI_BLUE_SHIFT | color.g << GX_BP_TEVREGHI_GREEN_SHIFT | + GX_TEVREG_COLOR << GX_BP_TEVREGHI_TYPE_SHIFT | (id * 2 + GX_BP_REG_TEVREG0HI) << GX_BP_OPCODE_SHIFT; + + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 0], regRA); + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 1], regBG); + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 2], regBG); + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 3], regBG); +} + +bool ResMatTevColor::GXGetTevColorS10(GXTevRegID id, GXColorS10 *pColor) const { + const u8 *pCmd = ref().dl.tevColor[id - 1]; + if (pCmd[0] == 0) { + return false; + } + + u32 regRA; + detail::ResReadBPCmd(&pCmd[GX_BP_CMD_SZ * 0], ®RA); + + u32 regBG; + detail::ResReadBPCmd(&pCmd[GX_BP_CMD_SZ * 1], ®BG); + + s16 r = regRA >> GX_BP_TEVREGLO_RED_SHIFT & GX_BP_TEVREGLO_RED_LMASK; + s16 g = regBG >> GX_BP_TEVREGHI_GREEN_SHIFT & GX_BP_TEVREGHI_GREEN_LMASK; + s16 b = regBG >> GX_BP_TEVREGHI_BLUE_SHIFT & GX_BP_TEVREGHI_BLUE_LMASK; + s16 a = regRA >> GX_BP_TEVREGLO_ALPHA_SHIFT & GX_BP_TEVREGLO_ALPHA_LMASK; + + // clang-format off + *pColor = detail::GetRGBAS10( + (r << (32 - GX_BP_TEVREGLO_RED_SZ)) >> (32 - GX_BP_TEVREGLO_RED_SZ), + (g << (32 - GX_BP_TEVREGHI_GREEN_SZ)) >> (32 - GX_BP_TEVREGHI_GREEN_SZ), + (b << (32 - GX_BP_TEVREGHI_BLUE_SZ)) >> (32 - GX_BP_TEVREGHI_BLUE_SZ), + (a << (32 - GX_BP_TEVREGLO_ALPHA_SZ)) >> (32 - GX_BP_TEVREGLO_ALPHA_SZ)); + // clang-format on + + return true; +} + +void ResMatTevColor::GXSetTevColorS10(GXTevRegID id, GXColorS10 color) { + u8 *pCmd = ref().dl.tevColor[id - 1]; + + u32 mask = GX_BP_TEVREGLO_RED_LMASK; + + u32 regRA = (color.r & mask) << GX_BP_TEVREGLO_RED_SHIFT | (color.a & mask) << GX_BP_TEVREGLO_ALPHA_SHIFT | + (id * 2 + GX_BP_REG_TEVREG0LO) << GX_BP_OPCODE_SHIFT | GX_TEVREG_COLOR << GX_BP_TEVREGLO_TYPE_SHIFT; + + u32 regBG = (color.b & mask) << GX_BP_TEVREGHI_BLUE_SHIFT | (color.g & mask) << GX_BP_TEVREGHI_GREEN_SHIFT | + (id * 2 + GX_BP_REG_TEVREG0HI) << GX_BP_OPCODE_SHIFT | GX_TEVREG_COLOR << GX_BP_TEVREGHI_TYPE_SHIFT; + + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 0], regRA); + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 1], regBG); + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 2], regBG); + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 3], regBG); +} + +bool ResMatTevColor::GXGetTevKColor(GXTevKColorID id, GXColor *pColor) const { + const u8 *pCmd = ref().dl.tevKColor[id]; + if (pCmd[0] == 0) { + return false; + } + + u32 regRA; + detail::ResReadBPCmd(&pCmd[GX_BP_CMD_SZ * 0], ®RA); + + u32 regBG; + detail::ResReadBPCmd(&pCmd[GX_BP_CMD_SZ * 1], ®BG); + + *pColor = detail::GetRGBA( + regRA >> GX_BP_TEVREGLO_RED_SHIFT & GX_BP_TEVREGLO_RED_LMASK, + regBG >> GX_BP_TEVREGLO_ALPHA_SHIFT & GX_BP_TEVREGLO_ALPHA_LMASK, + regBG >> GX_BP_TEVREGHI_BLUE_SHIFT & GX_BP_TEVREGHI_BLUE_LMASK, + regRA >> GX_BP_TEVREGHI_GREEN_SHIFT & GX_BP_TEVREGHI_GREEN_LMASK + ); + + return true; +} + +void ResMatTevColor::GXSetTevKColor(GXTevKColorID id, GXColor color) { + u8 *pCmd = ref().dl.tevKColor[id]; + + u32 regRA = color.r << GX_BP_TEVREGLO_RED_SHIFT | color.a << GX_BP_TEVREGLO_ALPHA_SHIFT | + GX_TEVREG_KONST << GX_BP_TEVREGLO_TYPE_SHIFT | (id * 2 + GX_BP_REG_TEVREG0LO) << GX_BP_OPCODE_SHIFT; + + u32 regBG = color.b << GX_BP_TEVREGHI_BLUE_SHIFT | color.g << GX_BP_TEVREGHI_GREEN_SHIFT | + GX_TEVREG_KONST << GX_BP_TEVREGHI_TYPE_SHIFT | (id * 2 + GX_BP_REG_TEVREG0HI) << GX_BP_OPCODE_SHIFT; + + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 0], regRA); + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 1], regBG); +} + +/****************************************************************************** + * + * ResMatIndMtxAndScale + * + ******************************************************************************/ +void ResMatIndMtxAndScale::CallDisplayList(u8 indNum, bool sync) const { + if (indNum == 0) { + return; + } + + const ResIndMtxAndScaleDL &r = ref(); + + if (sync) { + GXCallDisplayList(const_cast(&r), sizeof(ResIndMtxAndScaleDL)); + } else { + GXFastCallDisplayList(const_cast(&r), sizeof(ResIndMtxAndScaleDL)); + } +} + +bool ResMatIndMtxAndScale::GXGetIndTexMtx(GXIndTexMtxID id, math::MTX34 *pMtx) const { + s8 scaleExp; + const u8 *pCmd; + const ResIndMtxAndScaleDL &r = ref(); + + switch (id) { + case GX_ITM_0: { + pCmd = r.dl.indTexMtx0; + break; + } + + case GX_ITM_1: { + pCmd = r.dl.indTexMtx1; + break; + } + + case GX_ITM_2: { + pCmd = r.dl.indTexMtx2; + break; + } + + default: { + return false; + } + } + + if (pCmd[0] == 0) { + return false; + } + + u32 regA; + detail::ResReadBPCmd(&pCmd[GX_BP_CMD_SZ * 0], ®A); + + u32 regB; + detail::ResReadBPCmd(&pCmd[GX_BP_CMD_SZ * 1], ®B); + + u32 regC; + detail::ResReadBPCmd(&pCmd[GX_BP_CMD_SZ * 2], ®C); + + u32 scaleExpReg = (regA >> GX_BP_INDMTXA_EXP_SHIFT & GX_BP_INDMTXA_EXP_LMASK) << 0 | + (regB >> GX_BP_INDMTXB_EXP_SHIFT & GX_BP_INDMTXB_EXP_LMASK) << 2 | + (regC >> GX_BP_INDMTXC_EXP_SHIFT & GX_BP_INDMTXC_EXP_LMASK) << 4; + + // Hardware stores as -17 + scaleExp = static_cast(scaleExpReg - 17); + + // Exponent to value + f32 scale = 1.0f; + if (scaleExp > 0) { + while (scaleExp != 0) { + scaleExp--; + scale *= 2.0f; + } + } else if (scaleExp < 0) { + while (scaleExp != 0) { + scaleExp++; + scale /= 2.0f; + } + } + + if (pMtx != NULL) { + // clang-format off + pMtx->_00 = scale * static_cast(static_cast((regA >> GX_BP_INDMTXA_M00_SHIFT & GX_BP_INDMTXA_M00_LMASK) << (32 - GX_BP_INDMTXA_M00_SZ)) >> (32 - GX_BP_INDMTXA_M00_SZ)) * (1.0f / 1024.0f); + pMtx->_01 = scale * static_cast(static_cast((regB >> GX_BP_INDMTXB_M01_SHIFT & GX_BP_INDMTXB_M01_LMASK) << (32 - GX_BP_INDMTXB_M01_SZ)) >> (32 - GX_BP_INDMTXB_M01_SZ)) * (1.0f / 1024.0f); + pMtx->_02 = scale * static_cast(static_cast((regC >> GX_BP_INDMTXC_M02_SHIFT & GX_BP_INDMTXC_M02_LMASK) << (32 - GX_BP_INDMTXC_M02_SZ)) >> (32 - GX_BP_INDMTXC_M02_SZ)) * (1.0f / 1024.0f); + pMtx->_03 = 0.0f; + + pMtx->_10 = scale * static_cast(static_cast((regA >> GX_BP_INDMTXA_M10_SHIFT & GX_BP_INDMTXA_M10_LMASK) << (32 - GX_BP_INDMTXA_M10_SZ)) >> (32 - GX_BP_INDMTXA_M00_SZ)) * (1.0f / 1024.0f); + pMtx->_11 = scale * static_cast(static_cast((regB >> GX_BP_INDMTXB_M11_SHIFT & GX_BP_INDMTXB_M11_LMASK) << (32 - GX_BP_INDMTXB_M11_SZ)) >> (32 - GX_BP_INDMTXB_M11_SZ)) * (1.0f / 1024.0f); + pMtx->_12 = scale * static_cast(static_cast((regC >> GX_BP_INDMTXC_M12_SHIFT & GX_BP_INDMTXC_M12_LMASK) << (32 - GX_BP_INDMTXC_M12_SZ)) >> (32 - GX_BP_INDMTXC_M12_SZ)) * (1.0f / 1024.0f); + pMtx->_13 = 0.0f; + + pMtx->_20 = 0.0f; + pMtx->_21 = 0.0f; + pMtx->_22 = 1.0f; + pMtx->_23 = 0.0f; + // clang-format on + } + + return true; +} + +void ResMatIndMtxAndScale::GXSetIndTexMtx(GXIndTexMtxID id, const math::MTX34 &rMtx, s8 scaleExp) { + u32 offset; + u8 *pCmd; + ResIndMtxAndScaleDL &r = ref(); + + switch (id) { + case GX_ITM_0: { + pCmd = r.dl.indTexMtx0; + offset = GX_BP_REG_INDMTX0A - GX_BP_REG_INDMTX0A; + break; + } + + case GX_ITM_1: { + pCmd = r.dl.indTexMtx1; + offset = GX_BP_REG_INDMTX1A - GX_BP_REG_INDMTX0A; + break; + } + + case GX_ITM_2: { + pCmd = r.dl.indTexMtx2; + offset = GX_BP_REG_INDMTX2A - GX_BP_REG_INDMTX0A; + break; + } + + default: { + return; + } + } + + // Hardware stores as -17 + scaleExp += static_cast(17); + + // clang-format off + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 0], + static_cast((static_cast(1024.0f * rMtx._00) & GX_BP_INDMTXA_M00_LMASK) << GX_BP_INDMTXA_M00_SHIFT) | + static_cast((static_cast(1024.0f * rMtx._10) & GX_BP_INDMTXA_M10_LMASK) << GX_BP_INDMTXA_M10_SHIFT) | + static_cast((scaleExp >> 0 & GX_BP_INDMTXA_EXP_LMASK) << GX_BP_INDMTXA_EXP_SHIFT) | + static_cast(offset + GX_BP_REG_INDMTX0A << GX_BP_OPCODE_SHIFT)); + + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 1], + static_cast((static_cast(1024.0f * rMtx._01) & GX_BP_INDMTXB_M01_LMASK) << GX_BP_INDMTXB_M01_SHIFT) | + static_cast((static_cast(1024.0f * rMtx._11) & GX_BP_INDMTXB_M11_LMASK) << GX_BP_INDMTXB_M11_SHIFT) | + static_cast((scaleExp >> 2 & GX_BP_INDMTXB_EXP_LMASK) << GX_BP_INDMTXB_EXP_SHIFT) | + static_cast((offset + GX_BP_REG_INDMTX0B << GX_BP_OPCODE_SHIFT))); + + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 2], + static_cast((static_cast(1024.0f * rMtx._02) & GX_BP_INDMTXC_M02_LMASK) << GX_BP_INDMTXC_M02_SHIFT) | + static_cast((static_cast(1024.0f * rMtx._12) & GX_BP_INDMTXC_M12_LMASK) << GX_BP_INDMTXC_M12_SHIFT) | + static_cast((scaleExp >> 4 & GX_BP_INDMTXC_EXP_LMASK) << GX_BP_INDMTXC_EXP_SHIFT) | + static_cast(offset + GX_BP_REG_INDMTX0C << GX_BP_OPCODE_SHIFT)); + // clang-format on +} + +/****************************************************************************** + * + * ResMatChan + * + ******************************************************************************/ +void ResMatChan::GXSetChanMatColor(GXChannelID id, GXColor color) { + GXColor &rMatColor = ref().chan[id & 1].matColor; + + if ((id & 2) == 0) { + rMatColor.r = color.r; + rMatColor.g = color.g; + rMatColor.b = color.b; + + if (id == GX_COLOR0A0 || id == GX_COLOR1A1) { + rMatColor.a = color.a; + } + } else { + rMatColor.a = color.a; + } +} + +void ResMatChan::GXSetChanAmbColor(GXChannelID id, GXColor color) { + GXColor &rAmbColor = ref().chan[id & 1].ambColor; + + if ((id & 2) == 0) { + rAmbColor.r = color.r; + rAmbColor.g = color.g; + rAmbColor.b = color.b; + + if (id == GX_COLOR0A0 || id == GX_COLOR1A1) { + rAmbColor.a = color.a; + } + } else { + rAmbColor.a = color.a; + } +} + +void ResMatChan::GXSetChanCtrl( + GXChannelID id, GXBool enable, GXColorSrc ambSrc, GXColorSrc matSrc, GXLightID lightMask, GXDiffuseFn diffuseFn, + GXAttnFn attnFn +) { + Chan &rChan = ref().chan[id & 1]; + + u32 *pCtrl; + if ((id & 2) == 0) { + pCtrl = &rChan.paramChanCtrlC; + } else { + pCtrl = &rChan.paramChanCtrlA; + } + + // clang-format off + u32 mask = (matSrc) << GX_XF_COLOR0CNTRL_MATSRC_SHIFT | + (enable) << GX_XF_COLOR0CNTRL_LIGHT_SHIFT | + (lightMask & 0b1111) << GX_XF_COLOR0CNTRL_LMASKLO_SHIFT | + (ambSrc) << GX_XF_COLOR0CNTRL_AMBSRC_SHIFT | + (attnFn == GX_AF_SPEC ? GX_DF_NONE : diffuseFn) << GX_XF_COLOR0CNTRL_DIFFUSEATTN_SHIFT | + (attnFn != GX_AF_NONE) << GX_XF_COLOR0CNTRL_ATTNENABLE_SHIFT | + (attnFn != GX_AF_SPEC) << GX_XF_COLOR0CNTRL_ATTNSELECT_SHIFT | + ((lightMask >> 4) & 0b1111) << GX_XF_COLOR0CNTRL_LMASKHI_SHIFT; + // clang-format on + + *pCtrl = mask; + + if (id == GX_COLOR0A0 || id == GX_COLOR1A1) { + rChan.paramChanCtrlA = mask; + } +} + +bool ResMatChan::GXGetChanMatColor(GXChannelID id, GXColor *pColor) const { + *pColor = ref().chan[id & 1].matColor; + return true; +} + +bool ResMatChan::GXGetChanAmbColor(GXChannelID id, GXColor *pColor) const { + *pColor = ref().chan[id & 1].ambColor; + return true; +} + +bool ResMatChan::GXGetChanCtrl( + GXChannelID id, GXBool *pEnable, GXColorSrc *pAmbSrc, GXColorSrc *pMatSrc, GXLightID *pLightMask, + GXDiffuseFn *pDiffuseFn, GXAttnFn *pAttnFn +) const { + const Chan &rChan = ref().chan[id & 1]; + + u32 ctrl; + if ((id & 2) == 0) { + ctrl = rChan.paramChanCtrlC; + } else { + ctrl = rChan.paramChanCtrlA; + } + + if (pEnable != NULL) { + *pEnable = ctrl >> GX_XF_COLOR0CNTRL_LIGHT_SHIFT & GX_XF_COLOR0CNTRL_LIGHT_LMASK; + } + + if (pAmbSrc != NULL) { + *pAmbSrc = static_cast(ctrl >> GX_XF_COLOR0CNTRL_AMBSRC_SHIFT & GX_XF_COLOR0CNTRL_AMBSRC_LMASK); + } + + if (pMatSrc != NULL) { + *pMatSrc = static_cast(ctrl >> GX_XF_COLOR0CNTRL_MATSRC_SHIFT & GX_XF_COLOR0CNTRL_MATSRC_LMASK); + } + + u32 lightMaskLo = ctrl >> GX_XF_COLOR0CNTRL_LMASKLO_SHIFT & GX_XF_COLOR0CNTRL_LMASKLO_LMASK; + + u32 lightMaskHi = ctrl >> GX_XF_COLOR0CNTRL_LMASKHI_SHIFT & GX_XF_COLOR0CNTRL_LMASKHI_LMASK; + + if (pLightMask != NULL) { + *pLightMask = static_cast(lightMaskLo | lightMaskHi << 4); + } + + GXDiffuseFn diff; + GXAttnFn attn; + + if (!(ctrl >> GX_XF_COLOR0CNTRL_ATTNSELECT_SHIFT & GX_XF_COLOR0CNTRL_ATTNSELECT_LMASK)) { + attn = GX_AF_SPEC; + diff = GX_DF_NONE; + + } else if (!(ctrl >> GX_XF_COLOR0CNTRL_ATTNENABLE_SHIFT & GX_XF_COLOR0CNTRL_ATTNENABLE_LMASK)) { + attn = GX_AF_NONE; + diff = + static_cast(ctrl >> GX_XF_COLOR0CNTRL_DIFFUSEATTN_SHIFT & GX_XF_COLOR0CNTRL_DIFFUSEATTN_LMASK); + + } else { + attn = GX_AF_SPOT; + diff = + static_cast(ctrl >> GX_XF_COLOR0CNTRL_DIFFUSEATTN_SHIFT & GX_XF_COLOR0CNTRL_DIFFUSEATTN_LMASK); + } + + if (pDiffuseFn != NULL) { + *pDiffuseFn = diff; + } + + if (pAttnFn != NULL) { + *pAttnFn = attn; + } + + return true; +} + +ResMatChan ResMatChan::CopyTo(void *pDst) const { + ResChanData *pData = static_cast(pDst); + const ResChanData &r = ref(); + + *pData = r; + return ResMatChan(pData); +} + +/****************************************************************************** + * + * ResMatTexCoordGen + * + ******************************************************************************/ +void ResMatTexCoordGen::CallDisplayList(u8 numGens, bool sync) const { + if (numGens == 0) { + return; + } + + const ResTexCoordGenDL &r = ref(); + + if (sync) { + if (numGens < 2) { + GXCallDisplayList(const_cast(&r), 32); + } else if (numGens < 4) { + GXCallDisplayList(const_cast(&r), 64); + } else if (numGens < 8) { + GXCallDisplayList(const_cast(&r), 128); + } else { + GXCallDisplayList(const_cast(&r), sizeof(ResTexCoordGenDL)); + } + } else { + if (numGens < 2) { + GXFastCallDisplayList(const_cast(&r), 32); + } else if (numGens < 4) { + GXFastCallDisplayList(const_cast(&r), 64); + } else if (numGens < 8) { + GXFastCallDisplayList(const_cast(&r), 128); + } else { + GXFastCallDisplayList(const_cast(&r), sizeof(ResTexCoordGenDL)); + } + } +} + +bool ResMatTexCoordGen::GXGetTexCoordGen2( + GXTexCoordID id, GXTexGenType *pFunc, GXTexGenSrc *pParam, GXBool *pNormalize, u32 *pPostMtx +) const { + const u8 *pCmd = ref().dl.texCoordGen[id]; + if (pCmd[0] == 0) { + return false; + } + + u32 regTex; + detail::ResReadXFCmd(&pCmd[GX_XF_CMD_SZ * 0], ®Tex); + + u32 regDualTex; + detail::ResReadXFCmd(&pCmd[GX_XF_CMD_SZ * 1], ®DualTex); + + if (pNormalize != NULL) { + *pNormalize = regDualTex >> GX_XF_DUALTEX_NORMALIZE_SHIFT & GX_XF_DUALTEX_NORMALIZE_LMASK; + } + + if (pPostMtx != NULL) { + // @note BASEROW is actually only six bits + *pPostMtx = (regDualTex >> GX_XF_DUALTEX_BASEROW_SHIFT & 0xFF) + GX_DUALMTX0; + } + + u32 row; + u32 tgType; + + tgType = regTex >> GX_XF_TEX_TEXGENTYPE_SHIFT & GX_XF_TEX_TEXGENTYPE_LMASK; + row = regTex >> GX_XF_TEX_SRCROW_SHIFT & GX_XF_TEX_SRCROW_LMASK; + + if (tgType == GX_XF_TG_REGULAR) { + // clang-format off + GXTexGenType type = static_cast( + (regTex >> GX_XF_TEX_PROJTYPE_SHIFT & GX_XF_TEX_PROJTYPE_LMASK) ^ 1); + // clang-format on + + GXTexGenSrc param; + + switch (row) { + case 0: { + param = GX_TG_POS; + break; + } + + case 1: { + param = GX_TG_NRM; + break; + } + + case 3: { + param = GX_TG_BINRM; + break; + } + + case 4: { + param = GX_TG_TANGENT; + break; + } + + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: { + param = static_cast(row - 1); + break; + } + + case 2: + default: { + return false; + } + } + + if (pFunc != NULL) { + *pFunc = type; + } + + if (pParam != NULL) { + *pParam = param; + } + + return true; + } else if (row == 2) { + if (pFunc != NULL) { + *pFunc = GX_TG_SRTG; + } + + if (pParam != NULL) { + *pParam = tgType == GX_XF_TG_CLR0 ? GX_TG_COLOR0 : GX_TG_COLOR1; + } + + return true; + } else if (tgType == GX_XF_TG_BUMP) { + if (pFunc != NULL) { + // @note Assumes BUMPSRCLIGHT is the leftmost field + *pFunc = static_cast((regTex >> GX_XF_TEX_BUMPSRCLIGHT_SHIFT) + GX_TG_BUMP0); + } + + if (pParam != NULL) { + *pParam = static_cast( + (regTex >> GX_XF_TEX_BUMPSRCTEX_SHIFT & GX_XF_TEX_BUMPSRCTEX_LMASK) + GX_TG_TEXCOORD0 + ); + } + + return true; + } else { + return false; + } + + return false; +} + +void ResMatTexCoordGen::GXSetTexCoordGen2( + GXTexCoordID id, GXTexGenType func, GXTexGenSrc param, GXBool normalize, u32 postMtx +) { + u8 *pCmd = ref().dl.texCoordGen[id]; + + u32 form = GX_XF_TEX_FORM_AB11; + u32 tgType; + u32 proj = GX_XF_TEX_PROJ_ST; + + u32 row = 5; + u32 embossRow = 5; + u32 embossLit = 0; + + switch (param) { + case GX_TG_POS: { + row = 0; + form = GX_XF_TEX_FORM_ABC1; + break; + } + + case GX_TG_NRM: { + row = 1; + form = GX_XF_TEX_FORM_ABC1; + break; + } + + case GX_TG_BINRM: { + row = 3; + form = GX_XF_TEX_FORM_ABC1; + break; + } + + case GX_TG_TANGENT: { + row = 4; + form = GX_XF_TEX_FORM_ABC1; + break; + } + + case GX_TG_COLOR0: { + row = 2; + break; + } + + case GX_TG_COLOR1: { + row = 2; + break; + } + + case GX_TG_TEX0: { + row = 5; + break; + } + + case GX_TG_TEX1: { + row = 6; + break; + } + + case GX_TG_TEX2: { + row = 7; + break; + } + + case GX_TG_TEX3: { + row = 8; + break; + } + + case GX_TG_TEX4: { + row = 9; + break; + } + + case GX_TG_TEX5: { + row = 10; + break; + } + + case GX_TG_TEX6: { + row = 11; + break; + } + + case GX_TG_TEX7: { + row = 12; + break; + } + + case GX_TG_TEXCOORD0: { + embossRow = 0; + break; + } + + case GX_TG_TEXCOORD1: { + embossRow = 1; + break; + } + + case GX_TG_TEXCOORD2: { + embossRow = 2; + break; + } + + case GX_TG_TEXCOORD3: { + embossRow = 3; + break; + } + + case GX_TG_TEXCOORD4: { + embossRow = 4; + break; + } + + case GX_TG_TEXCOORD5: { + embossRow = 5; + break; + } + + case GX_TG_TEXCOORD6: { + embossRow = 6; + break; + } + + default: { + break; + } + } + + switch (func) { + case GX_TG_MTX2x4: { + tgType = GX_XF_TG_REGULAR; + break; + } + + case GX_TG_MTX3x4: { + tgType = GX_XF_TG_REGULAR; + proj = GX_XF_TEX_PROJ_STQ; + break; + } + + case GX_TG_BUMP0: + case GX_TG_BUMP1: + case GX_TG_BUMP2: + case GX_TG_BUMP3: + case GX_TG_BUMP4: + case GX_TG_BUMP5: + case GX_TG_BUMP6: + case GX_TG_BUMP7: { + tgType = GX_XF_TG_BUMP; + embossLit = func - GX_TG_BUMP0; + break; + } + + case GX_TG_SRTG: { + if (param == GX_TG_COLOR0) { + tgType = GX_XF_TG_CLR0; + } else /* GX_TG_COLOR1 */ { + tgType = GX_XF_TG_CLR1; + } + break; + } + + default: { + return; + } + } + + // clang-format off + detail::ResWriteXFCmd(&pCmd[GX_XF_CMD_SZ * 0], id + GX_XF_REG_TEX0, + proj << GX_XF_TEX_PROJTYPE_SHIFT | + form << GX_XF_TEX_INPUTFORM_SHIFT | + tgType << GX_XF_TEX_TEXGENTYPE_SHIFT | + row << GX_XF_TEX_SRCROW_SHIFT | + embossRow << GX_XF_TEX_BUMPSRCTEX_SHIFT | + embossLit << GX_XF_TEX_BUMPSRCLIGHT_SHIFT); + + detail::ResWriteXFCmd(&pCmd[GX_XF_CMD_SZ * 1], id + GX_XF_REG_DUALTEX0, + postMtx - GX_DUALMTX0 << GX_XF_DUALTEX_BASEROW_SHIFT | + normalize << GX_XF_DUALTEX_NORMALIZE_SHIFT); + // clang-format on +} + +/****************************************************************************** + * + * ResMat + * + ******************************************************************************/ +bool ResMat::Bind(const ResFile file) { + u32 i; + u32 bindNum = 0; + + u32 texPlttInfoNum = GetNumResTexPlttInfo(); + for (i = 0; i < texPlttInfoNum; i++) { + if (GetResTexPlttInfo(i).Bind(file, GetResTexObj(), GetResTlutObj())) { + bindNum++; + } + } + + return bindNum == texPlttInfoNum; +} + +void ResMat::Release() { + u32 i; + + u32 texPlttInfoNum = GetNumResTexPlttInfo(); + for (i = 0; i < texPlttInfoNum; i++) { + GetResTexPlttInfo(i).Release(GetResTexObj(), GetResTlutObj()); + } +} + +void ResMat::Init() { + DC::StoreRangeNoSync(GetResMatDLData(), sizeof(ResMatDLData)); +} + +ResTev ResMat::GetResTev() { + return ofs_to_obj(ref().toResTevData); +} + +ResTev ResMat::GetResTev() const { + return ofs_to_obj(ref().toResTevData); +} + +/****************************************************************************** + * + * ResTexPlttInfo + * + ******************************************************************************/ +void ResTexPlttInfo::BindTex_(const ResTex tex, ResTexObj texObj) { + ResTexPlttInfoData &r = ref(); + r.pTexData = const_cast(&tex.ref()); + + void *pTexData; + u16 width, height; + f32 minLod, maxLod; + GXBool mipmap; + + GXTexObj *pGXObj = texObj.GetTexObj(r.mapID); + + if (IsCIFmt()) { + GXCITexFmt fmtCi; + tex.GetTexObjCIParam(&pTexData, &width, &height, &fmtCi, &minLod, &maxLod, &mipmap); + + GXInitTexObjCI( + pGXObj, pTexData, width, height, static_cast(fmtCi), r.wrap_s, r.wrap_t, mipmap, r.tlutID + ); + } else { + GXTexFmt fmt; + tex.GetTexObjParam(&pTexData, &width, &height, &fmt, &minLod, &maxLod, &mipmap); + + GXInitTexObj(pGXObj, pTexData, width, height, fmt, r.wrap_s, r.wrap_t, mipmap); + } + + GXInitTexObjLOD( + pGXObj, r.min_filt, r.mag_filt, minLod, maxLod, r.lod_bias, r.bias_clamp, r.do_edge_lod, r.max_aniso + ); + + texObj.Validate(r.mapID); +} + +void ResTexPlttInfo::BindPltt_(const ResPltt pltt, ResTlutObj tlutObj) { + ResTexPlttInfoData &r = ref(); + r.pPlttData = const_cast(&pltt.ref()); + + // @bug Shouldn't this be the TLUT id? + GXTlutObj *pGXObj = tlutObj.GetTlut(static_cast(r.mapID)); + + GXInitTlutObj(pGXObj, const_cast(pltt.GetPlttData()), pltt.GetFmt(), pltt.GetNumEntries()); + + // @bug Shouldn't this be the TLUT id? + tlutObj.Validate(static_cast(r.mapID)); +} + +bool ResTexPlttInfo::Bind(const ResFile file, ResTexObj texObj, ResTlutObj tlutObj) { + bool success = true; + ResName texName = GetTexResName(); + + if (ref().pTexData == NULL) { + ResTex tex = file.GetResTex(texName); + + if (tex.IsValid() && (!IsCIFmt() || tex.IsCIFmt())) { + BindTex_(tex, texObj); + } else { + success = false; + } + } + + if (ref().pPlttData == NULL) { + ResName plttName = GetPlttResName(); + + if (plttName.IsValid()) { + ResPltt pltt = file.GetResPltt(plttName); + + if (pltt.IsValid()) { + BindPltt_(pltt, tlutObj); + } else { + success = false; + } + } + } + + return success; +} + +void ResTexPlttInfo::Release(ResTexObj texObj, ResTlutObj tlutObj) { + ResTexPlttInfoData &r = ref(); + + r.pTexData = NULL; + r.pPlttData = NULL; + + texObj.Invalidate(r.mapID); + // @bug Shouldn't this be the TLUT id? + tlutObj.Invalidate(static_cast(r.mapID)); +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resmdl.cpp b/src/nw4r/g3d/res/g3d_resmdl.cpp new file mode 100644 index 00000000..125583f1 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resmdl.cpp @@ -0,0 +1,246 @@ +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * ResByteCode + * + ******************************************************************************/ +const u8* ResMdl::GetResByteCode(const char* pName) const { + return static_cast(ofs_to_obj(ref().toResByteCodeDic)[pName]); +} + +/****************************************************************************** + * + * ResNode + * + ******************************************************************************/ +ResNode ResMdl::GetResNode(const char* pName) const { + return ResNode(ofs_to_obj(ref().toResNodeDic)[pName]); +} + +ResNode ResMdl::GetResNode(const ResName name) const { + return ResNode(ofs_to_obj(ref().toResNodeDic)[name]); +} + +ResNode ResMdl::GetResNode(int idx) const { + return ResNode(ofs_to_obj(ref().toResNodeDic)[idx]); +} + +ResNode ResMdl::GetResNode(u32 idx) const { + return ResNode(ofs_to_obj(ref().toResNodeDic)[idx]); +} + +u32 ResMdl::GetResNodeNumEntries() const { + return ofs_to_obj(ref().toResNodeDic).GetNumData(); +} + +/****************************************************************************** + * + * RexVtxPos + * + ******************************************************************************/ +ResVtxPos ResMdl::GetResVtxPos(const ResName name) const { + return ResVtxPos(ofs_to_obj(ref().toResVtxPosDic)[name]); +} + +ResVtxPos ResMdl::GetResVtxPos(int idx) const { + return ResVtxPos(ofs_to_obj(ref().toResVtxPosDic)[idx]); +} + +ResVtxPos ResMdl::GetResVtxPos(u32 idx) const { + return ResVtxPos(ofs_to_obj(ref().toResVtxPosDic)[idx]); +} + +u32 ResMdl::GetResVtxPosNumEntries() const { + return ofs_to_obj(ref().toResVtxPosDic).GetNumData(); +} + +/****************************************************************************** + * + * ResVtxNrm + * + ******************************************************************************/ +ResVtxNrm ResMdl::GetResVtxNrm(const ResName name) const { + return ResVtxNrm(ofs_to_obj(ref().toResVtxNrmDic)[name]); +} + +ResVtxNrm ResMdl::GetResVtxNrm(int idx) const { + return ResVtxNrm(ofs_to_obj(ref().toResVtxNrmDic)[idx]); +} + +ResVtxNrm ResMdl::GetResVtxNrm(u32 idx) const { + return ResVtxNrm(ofs_to_obj(ref().toResVtxNrmDic)[idx]); +} + +u32 ResMdl::GetResVtxNrmNumEntries() const { + return ofs_to_obj(ref().toResVtxNrmDic).GetNumData(); +} + +/****************************************************************************** + * + * ResVtxClr + * + ******************************************************************************/ +ResVtxClr ResMdl::GetResVtxClr(const ResName name) const { + return ResVtxClr(ofs_to_obj(ref().toResVtxClrDic)[name]); +} + +ResVtxClr ResMdl::GetResVtxClr(int idx) const { + return ResVtxClr(ofs_to_obj(ref().toResVtxClrDic)[idx]); +} + +ResVtxClr ResMdl::GetResVtxClr(u32 idx) const { + return ResVtxClr(ofs_to_obj(ref().toResVtxClrDic)[idx]); +} + +u32 ResMdl::GetResVtxClrNumEntries() const { + return ofs_to_obj(ref().toResVtxClrDic).GetNumData(); +} + +/****************************************************************************** + * + * ResVtxTexCoord + * + ******************************************************************************/ +ResVtxTexCoord ResMdl::GetResVtxTexCoord(int idx) const { + return ResVtxTexCoord(ofs_to_obj(ref().toResVtxTexCoordDic)[idx]); +} + +u32 ResMdl::GetResVtxTexCoordNumEntries() const { + return ofs_to_obj(ref().toResVtxTexCoordDic).GetNumData(); +} + +/****************************************************************************** + * + * ResMat + * + ******************************************************************************/ +ResMat ResMdl::GetResMat(const char* pName) const { + return ResMat(ofs_to_obj(ref().toResMatDic)[pName]); +} + +ResMat ResMdl::GetResMat(const ResName name) const { + return ResMat(ofs_to_obj(ref().toResMatDic)[name]); +} + +ResMat ResMdl::GetResMat(int idx) const { + return ResMat(ofs_to_obj(ref().toResMatDic)[idx]); +} + +ResMat ResMdl::GetResMat(u32 idx) const { + return ResMat(ofs_to_obj(ref().toResMatDic)[idx]); +} + +u32 ResMdl::GetResMatNumEntries() const { + return ofs_to_obj(ref().toResMatDic).GetNumData(); +} + +/****************************************************************************** + * + * ResShp + * + ******************************************************************************/ +ResShp ResMdl::GetResShp(const char* pName) const { + return ResShp(ofs_to_obj(ref().toResShpDic)[pName]); +} + +ResShp ResMdl::GetResShp(int idx) const { + return ResShp(ofs_to_obj(ref().toResShpDic)[idx]); +} + +ResShp ResMdl::GetResShp(u32 idx) const { + return ResShp(ofs_to_obj(ref().toResShpDic)[idx]); +} + +u32 ResMdl::GetResShpNumEntries() const { + return ofs_to_obj(ref().toResShpDic).GetNumData(); +} + +/****************************************************************************** + * + * ResTexPlttInfo + * + ******************************************************************************/ +ResTexPlttInfo ResMdl::GetResTexPlttInfoOffsetFromTexName(int idx) const { + return ResTexPlttInfo( + ofs_to_obj(ref().toResTexNameToTexPlttInfoDic)[idx]); +} + +u32 ResMdl::GetResTexPlttInfoOffsetFromTexNameNumEntries() const { + return ofs_to_obj(ref().toResTexNameToTexPlttInfoDic).GetNumData(); +} + +/****************************************************************************** + * + * ResMdl + * + ******************************************************************************/ +bool ResMdl::Bind(const ResFile file) { + u32 i; + bool success = true; + + u32 matNum = GetResMatNumEntries(); + for (i = 0; i < matNum; i++) { + success = GetResMat(i).Bind(file) && success; + } + + return success; +} + +void ResMdl::Release() { + u32 i; + + u32 matNum = GetResMatNumEntries(); + for (i = 0; i < matNum; i++) { + GetResMat(i).Release(); + } +} + +void ResMdl::Init() { + u32 i; + + u32 matNum = GetResMatNumEntries(); + for (i = 0; i < matNum; i++) { + GetResMat(i).Init(); + } + + u32 shpNum = GetResShpNumEntries(); + for (i = 0; i < shpNum; i++) { + GetResShp(i).Init(); + } + + u32 vtxPosNum = GetResVtxPosNumEntries(); + for (i = 0; i < vtxPosNum; i++) { + GetResVtxPos(i).Init(); + } + + u32 vtxNrmNum = GetResVtxNrmNumEntries(); + for (i = 0; i < vtxNrmNum; i++) { + GetResVtxNrm(i).Init(); + } + + u32 vtxClrNum = GetResVtxClrNumEntries(); + for (i = 0; i < vtxClrNum; i++) { + GetResVtxClr(i).Init(); + } + + u32 texCoordNum = GetResVtxTexCoordNumEntries(); + for (i = 0; i < texCoordNum; i++) { + GetResVtxTexCoord(i).Init(); + } +} + +void ResMdl::Terminate() { + u32 i; + + u32 shpNum = GetResShpNumEntries(); + for (i = 0; i < shpNum; i++) { + GetResShp(i).Terminate(); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resnode.cpp b/src/nw4r/g3d/res/g3d_resnode.cpp new file mode 100644 index 00000000..6a0af023 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resnode.cpp @@ -0,0 +1,130 @@ +#include + +#include + +namespace nw4r { +namespace g3d { + +void ResNode::PatchChrAnmResult(ChrAnmResult* pResult) const { + if (!IsValid()) { + return; + } + + const ResNodeData& r = ref(); + u32 flags = pResult->flags; + + if (flags & ChrAnmResult::FLAG_PATCH_SCALE) { + if (r.flags & ResNodeData::FLAG_SCALE_ONE) { + flags |= + ChrAnmResult::FLAG_SCALE_ONE | ChrAnmResult::FLAG_SCALE_UNIFORM; + } else { + if (r.flags & ResNodeData::FLAG_SCALE_UNIFORM) { + flags |= ChrAnmResult::FLAG_SCALE_UNIFORM; + } + + pResult->s = static_cast(r.scale); + } + } + + if (flags & ChrAnmResult::FLAG_PATCH_ROT) { + if (r.flags & ResNodeData::FLAG_ROT_ZERO) { + flags |= ChrAnmResult::FLAG_ROT_ZERO; + } else { + math::MTX34RotXYZDeg(&pResult->rt, r.rot.x, r.rot.y, r.rot.z); + flags &= ~ChrAnmResult::FLAG_ROT_ZERO; + } + + flags |= ChrAnmResult::FLAG_ROT_RAW_FMT; + } + + if (flags & ChrAnmResult::FLAG_PATCH_TRANS) { + if (r.flags & ResNodeData::FLAG_TRANS_ZERO) { + flags |= ChrAnmResult::FLAG_TRANS_ZERO; + } else { + flags &= ~ChrAnmResult::FLAG_TRANS_ZERO; + + pResult->rt._03 = r.translate.x; + pResult->rt._13 = r.translate.y; + pResult->rt._23 = r.translate.z; + } + } + + if ((flags & ChrAnmResult::FLAG_ROT_ZERO) && + (flags & ChrAnmResult::FLAG_TRANS_ZERO)) { + flags |= ChrAnmResult::FLAG_ROT_TRANS_ZERO; + + if (flags & ChrAnmResult::FLAG_SCALE_ONE) { + flags |= ChrAnmResult::FLAG_MTX_IDENT; + } + } + + pResult->flags = flags & ~(ChrAnmResult::FLAG_PATCH_SCALE | + ChrAnmResult::FLAG_PATCH_ROT | + ChrAnmResult::FLAG_PATCH_TRANS); +} + +void ResNode::CalcChrAnmResult(ChrAnmResult* pResult) const { + if (!IsValid()) { + return; + } + + const ResNodeData& r = ref(); + u32 flags = 0; + + if (r.flags & ResNodeData::FLAG_SCALE_ONE) { + flags |= + ChrAnmResult::FLAG_SCALE_ONE | ChrAnmResult::FLAG_SCALE_UNIFORM; + + pResult->s.z = 1.0f; + pResult->s.y = 1.0f; + pResult->s.x = 1.0f; + } else { + if (r.flags & ResNodeData::FLAG_SCALE_UNIFORM) { + flags |= ChrAnmResult::FLAG_SCALE_UNIFORM; + } + + pResult->s = static_cast(r.scale); + } + + if (r.flags & ResNodeData::FLAG_ROT_ZERO) { + PSMTXIdentity(pResult->rt); + flags |= ChrAnmResult::FLAG_ROT_ZERO; + } else { + pResult->rawR = math::VEC3(r.rot); + math::MTX34RotXYZDeg(&pResult->rt, r.rot.x, r.rot.y, r.rot.z); + } + + if (r.flags & ResNodeData::FLAG_TRANS_ZERO) { + flags |= ChrAnmResult::FLAG_TRANS_ZERO; + } else { + pResult->rt._03 = r.translate.x; + pResult->rt._13 = r.translate.y; + pResult->rt._23 = r.translate.z; + } + + if (flags & ChrAnmResult::FLAG_ROT_ZERO) { + if (flags & ChrAnmResult::FLAG_TRANS_ZERO) { + flags |= ChrAnmResult::FLAG_ROT_TRANS_ZERO; + + if (flags & ChrAnmResult::FLAG_SCALE_ONE) { + flags |= ChrAnmResult::FLAG_MTX_IDENT; + } + } + } + + flags |= ChrAnmResult::FLAG_ROT_RAW_FMT; + flags |= ChrAnmResult::FLAG_ANM_EXISTS; + + if (r.flags & ResNodeData::FLAG_SSC_APPLY) { + flags |= ChrAnmResult::FLAG_SSC_APPLY; + } + + if (r.flags & ResNodeData::FLAG_SSC_PARENT) { + flags |= ChrAnmResult::FLAG_SSC_PARENT; + } + + pResult->flags = flags; +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resshp.cpp b/src/nw4r/g3d/res/g3d_resshp.cpp new file mode 100644 index 00000000..27ec86ca --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resshp.cpp @@ -0,0 +1,297 @@ +#include + +#include + +#include + +namespace nw4r { +namespace g3d { + +ResMdl ResShp::GetParent() const { + return ofs_to_obj(ref().toResMdlData); +} + +bool ResShp::GXGetVtxDescv(GXVtxDescList *pList) const { + ResShpPrePrim prim = GetResShpPrePrim(); + + if (prim.ref().dl.vtxDescv[GX_CP_CMD_SZ * 0] == 0) { + return false; + } + + u32 vcdLo; + detail::ResReadCPCmd(&prim.ref().dl.vtxDescv[GX_CP_CMD_SZ * 0], &vcdLo); + + u32 vcdHi; + detail::ResReadCPCmd(&prim.ref().dl.vtxDescv[GX_CP_CMD_SZ * 1], &vcdHi); + + for (int i = 0; i <= GX_VA_TEX7; i++) { + pList[i].attr = static_cast(i); + } + + pList[GX_VA_TEX7 + 1].attr = GX_VA_NULL; + + // clang-format off + // Matrix indices + pList[GX_VA_PNMTXIDX].type = static_cast(vcdLo >> GX_CP_VCD_LO_POSMATIDX_SHIFT & GX_CP_VCD_LO_POSMATIDX_LMASK); + pList[GX_VA_TEX0MTXIDX].type = static_cast(vcdLo >> GX_CP_VCD_LO_TEX0MATIDX_SHIFT & GX_CP_VCD_LO_TEX0MATIDX_LMASK); + pList[GX_VA_TEX1MTXIDX].type = static_cast(vcdLo >> GX_CP_VCD_LO_TEX1MATIDX_SHIFT & GX_CP_VCD_LO_TEX1MATIDX_LMASK); + pList[GX_VA_TEX2MTXIDX].type = static_cast(vcdLo >> GX_CP_VCD_LO_TEX2MATIDX_SHIFT & GX_CP_VCD_LO_TEX2MATIDX_LMASK); + pList[GX_VA_TEX3MTXIDX].type = static_cast(vcdLo >> GX_CP_VCD_LO_TEX3MATIDX_SHIFT & GX_CP_VCD_LO_TEX3MATIDX_LMASK); + pList[GX_VA_TEX4MTXIDX].type = static_cast(vcdLo >> GX_CP_VCD_LO_TEX4MATIDX_SHIFT & GX_CP_VCD_LO_TEX4MATIDX_LMASK); + pList[GX_VA_TEX5MTXIDX].type = static_cast(vcdLo >> GX_CP_VCD_LO_TEX5MATIDX_SHIFT & GX_CP_VCD_LO_TEX5MATIDX_LMASK); + pList[GX_VA_TEX6MTXIDX].type = static_cast(vcdLo >> GX_CP_VCD_LO_TEX6MATIDX_SHIFT & GX_CP_VCD_LO_TEX6MATIDX_LMASK); + pList[GX_VA_TEX7MTXIDX].type = static_cast(vcdLo >> GX_CP_VCD_LO_TEX7MATIDX_SHIFT & GX_CP_VCD_LO_TEX7MATIDX_LMASK); + + // Position/normal + pList[GX_VA_POS].type = static_cast(vcdLo >> GX_CP_VCD_LO_POSITION_SHIFT & GX_CP_VCD_LO_POSITION_LMASK); + pList[GX_VA_NRM].type = static_cast(vcdLo >> GX_CP_VCD_LO_NORMAL_SHIFT & GX_CP_VCD_LO_NORMAL_LMASK); + + // Color attributes + pList[GX_VA_CLR0].type = static_cast(vcdLo >> GX_CP_VCD_LO_COLORDIFFUSED_SHIFT & GX_CP_VCD_LO_COLORDIFFUSED_LMASK); + pList[GX_VA_CLR1].type = static_cast(vcdLo >> GX_CP_VCD_LO_COLORSPECULAR_SHIFT & GX_CP_VCD_LO_COLORSPECULAR_LMASK); + + // Texcoord attributes + pList[GX_VA_TEX0].type = static_cast(vcdHi >> GX_CP_VCD_HI_TEX0COORD_SHIFT & GX_CP_VCD_HI_TEX0COORD_LMASK); + pList[GX_VA_TEX1].type = static_cast(vcdHi >> GX_CP_VCD_HI_TEX1COORD_SHIFT & GX_CP_VCD_HI_TEX1COORD_LMASK); + pList[GX_VA_TEX2].type = static_cast(vcdHi >> GX_CP_VCD_HI_TEX2COORD_SHIFT & GX_CP_VCD_HI_TEX2COORD_LMASK); + pList[GX_VA_TEX3].type = static_cast(vcdHi >> GX_CP_VCD_HI_TEX3COORD_SHIFT & GX_CP_VCD_HI_TEX3COORD_LMASK); + pList[GX_VA_TEX4].type = static_cast(vcdHi >> GX_CP_VCD_HI_TEX4COORD_SHIFT & GX_CP_VCD_HI_TEX4COORD_LMASK); + pList[GX_VA_TEX5].type = static_cast(vcdHi >> GX_CP_VCD_HI_TEX5COORD_SHIFT & GX_CP_VCD_HI_TEX5COORD_LMASK); + pList[GX_VA_TEX6].type = static_cast(vcdHi >> GX_CP_VCD_HI_TEX6COORD_SHIFT & GX_CP_VCD_HI_TEX6COORD_LMASK); + pList[GX_VA_TEX7].type = static_cast(vcdHi >> GX_CP_VCD_HI_TEX7COORD_SHIFT & GX_CP_VCD_HI_TEX7COORD_LMASK); + // clang-format on + + return true; +} + +bool ResShp::GXGetVtxAttrFmtv(GXVtxAttrFmtList *pList) const { + ResShpPrePrim prim = GetResShpPrePrim(); + + if (prim.ref().dl.vtxFmtv[GX_CP_CMD_SZ * 0] == 0) { + return false; + } + + u32 vat0; + detail::ResReadCPCmd(&prim.ref().dl.vtxFmtv[GX_CP_CMD_SZ * 0], &vat0); + + u32 vat1; + detail::ResReadCPCmd(&prim.ref().dl.vtxFmtv[GX_CP_CMD_SZ * 1], &vat1); + + u32 vat2; + detail::ResReadCPCmd(&prim.ref().dl.vtxFmtv[GX_CP_CMD_SZ * 2], &vat2); + + int i; + for (i = 0; i <= GX_VA_TEX7 - GX_VA_POS; i++) { + pList[i].attr = static_cast(GX_VA_POS + i); + } + + // clang-format off + // Position/normal + pList[GX_VA_POS - GX_VA_POS].compType = static_cast(vat0 >> GX_CP_VAT_GROUP0_POS_TYPE_SHIFT & GX_CP_VAT_GROUP0_POS_TYPE_LMASK); + pList[GX_VA_POS - GX_VA_POS].compCnt = static_cast(vat0 >> GX_CP_VAT_GROUP0_POS_CNT_SHIFT & GX_CP_VAT_GROUP0_POS_CNT_LMASK); + pList[GX_VA_POS - GX_VA_POS].shift = vat0 >> GX_CP_VAT_GROUP0_POS_SHIFT_SHIFT & GX_CP_VAT_GROUP0_POS_SHIFT_LMASK; + + pList[GX_VA_NRM - GX_VA_POS].compType = static_cast(vat0 >> GX_CP_VAT_GROUP0_NRM_TYPE_SHIFT & GX_CP_VAT_GROUP0_NRM_TYPE_LMASK); + + pList[GX_VA_NRM - GX_VA_POS].compCnt = static_cast(vat0 >> GX_CP_VAT_GROUP0_NORMALINDEX3_SHIFT & GX_CP_VAT_GROUP0_NORMALINDEX3_LMASK + ? i - GX_VA_NRM + : vat0 >> GX_CP_VAT_GROUP0_NRM_CNT_SHIFT & GX_CP_VAT_GROUP0_NRM_CNT_LMASK); + + pList[GX_VA_NRM - GX_VA_POS].shift = pList[GX_VA_NRM - GX_VA_POS].compType == GX_S8 ? 6 : 14; + + // Color attributes + pList[GX_VA_CLR0 - GX_VA_POS].compType = static_cast(vat0 >> GX_CP_VAT_GROUP0_COLORDIFF_TYPE_SHIFT & GX_CP_VAT_GROUP0_COLORDIFF_TYPE_LMASK); + pList[GX_VA_CLR0 - GX_VA_POS].compCnt = static_cast(vat0 >> GX_CP_VAT_GROUP0_COLORDIFF_CNT_SHIFT & GX_CP_VAT_GROUP0_COLORDIFF_CNT_LMASK); + + pList[GX_VA_CLR1 - GX_VA_POS].compType = static_cast(vat0 >> GX_CP_VAT_GROUP0_COLORSPEC_TYPE_SHIFT & GX_CP_VAT_GROUP0_COLORSPEC_TYPE_LMASK); + pList[GX_VA_CLR1 - GX_VA_POS].compCnt = static_cast(vat0 >> GX_CP_VAT_GROUP0_COLORSPEC_CNT_SHIFT & GX_CP_VAT_GROUP0_COLORSPEC_CNT_LMASK); + + // Texcoord attributes + pList[GX_VA_TEX0 - GX_VA_POS].compType = static_cast(vat0 >> GX_CP_VAT_GROUP0_TXC0_TYPE_SHIFT & GX_CP_VAT_GROUP0_TXC0_TYPE_LMASK); + pList[GX_VA_TEX0 - GX_VA_POS].compCnt = static_cast(vat0 >> GX_CP_VAT_GROUP0_TXC0_CNT_SHIFT & GX_CP_VAT_GROUP0_TXC0_CNT_LMASK); + pList[GX_VA_TEX0 - GX_VA_POS].shift = vat0 >> GX_CP_VAT_GROUP0_TXC0_SHIFT_SHIFT & GX_CP_VAT_GROUP0_TXC0_SHIFT_LMASK; + + pList[GX_VA_TEX1 - GX_VA_POS].compType = static_cast(vat1 >> GX_CP_VAT_GROUP1_TXC1_TYPE_SHIFT & GX_CP_VAT_GROUP1_TXC1_TYPE_LMASK); + pList[GX_VA_TEX1 - GX_VA_POS].compCnt = static_cast(vat1 >> GX_CP_VAT_GROUP1_TXC1_CNT_SHIFT & GX_CP_VAT_GROUP1_TXC1_CNT_LMASK); + pList[GX_VA_TEX1 - GX_VA_POS].shift = vat1 >> GX_CP_VAT_GROUP1_TXC1_SHIFT_SHIFT & GX_CP_VAT_GROUP1_TXC1_SHIFT_LMASK; + + pList[GX_VA_TEX2 - GX_VA_POS].compType = static_cast(vat1 >> GX_CP_VAT_GROUP1_TXC2_TYPE_SHIFT & GX_CP_VAT_GROUP1_TXC2_TYPE_LMASK); + pList[GX_VA_TEX2 - GX_VA_POS].compCnt = static_cast(vat1 >> GX_CP_VAT_GROUP1_TXC2_CNT_SHIFT & GX_CP_VAT_GROUP1_TXC2_CNT_LMASK); + pList[GX_VA_TEX2 - GX_VA_POS].shift = vat1 >> GX_CP_VAT_GROUP1_TXC2_SHIFT_SHIFT & GX_CP_VAT_GROUP1_TXC2_SHIFT_LMASK; + + pList[GX_VA_TEX3 - GX_VA_POS].compType = static_cast(vat1 >> GX_CP_VAT_GROUP1_TXC3_TYPE_SHIFT & GX_CP_VAT_GROUP1_TXC3_TYPE_LMASK); + pList[GX_VA_TEX3 - GX_VA_POS].compCnt = static_cast(vat1 >> GX_CP_VAT_GROUP1_TXC3_CNT_SHIFT & GX_CP_VAT_GROUP1_TXC3_CNT_LMASK); + pList[GX_VA_TEX3 - GX_VA_POS].shift = vat1 >> GX_CP_VAT_GROUP1_TXC3_SHIFT_SHIFT & GX_CP_VAT_GROUP1_TXC3_SHIFT_LMASK; + + pList[GX_VA_TEX4 - GX_VA_POS].compType = static_cast(vat1 >> GX_CP_VAT_GROUP1_TXC4_TYPE_SHIFT & GX_CP_VAT_GROUP1_TXC4_TYPE_LMASK); + pList[GX_VA_TEX4 - GX_VA_POS].compCnt = static_cast(vat1 >> GX_CP_VAT_GROUP1_TXC4_CNT_SHIFT & GX_CP_VAT_GROUP1_TXC4_CNT_LMASK); + pList[GX_VA_TEX4 - GX_VA_POS].shift = vat2 >> GX_CP_VAT_GROUP2_TXC4_SHIFT_SHIFT & GX_CP_VAT_GROUP2_TXC4_SHIFT_LMASK; + + pList[GX_VA_TEX5 - GX_VA_POS].compType = static_cast(vat2 >> GX_CP_VAT_GROUP2_TXC5_TYPE_SHIFT & GX_CP_VAT_GROUP2_TXC5_TYPE_LMASK); + pList[GX_VA_TEX5 - GX_VA_POS].compCnt = static_cast(vat2 >> GX_CP_VAT_GROUP2_TXC5_CNT_SHIFT & GX_CP_VAT_GROUP2_TXC5_CNT_LMASK); + pList[GX_VA_TEX5 - GX_VA_POS].shift = vat2 >> GX_CP_VAT_GROUP2_TXC5_SHIFT_SHIFT & GX_CP_VAT_GROUP2_TXC5_SHIFT_LMASK; + + pList[GX_VA_TEX6 - GX_VA_POS].compType = static_cast(vat2 >> GX_CP_VAT_GROUP2_TXC6_TYPE_SHIFT & GX_CP_VAT_GROUP2_TXC6_TYPE_LMASK); + pList[GX_VA_TEX6 - GX_VA_POS].compCnt = static_cast(vat2 >> GX_CP_VAT_GROUP2_TXC6_CNT_SHIFT & GX_CP_VAT_GROUP2_TXC6_CNT_LMASK); + pList[GX_VA_TEX6 - GX_VA_POS].shift = vat2 >> GX_CP_VAT_GROUP2_TXC6_SHIFT_SHIFT & GX_CP_VAT_GROUP2_TXC6_SHIFT_LMASK; + + pList[GX_VA_TEX7 - GX_VA_POS].compType = static_cast(vat2 >> GX_CP_VAT_GROUP2_TXC7_TYPE_SHIFT & GX_CP_VAT_GROUP2_TXC7_TYPE_LMASK); + pList[GX_VA_TEX7 - GX_VA_POS].compCnt = static_cast(vat2 >> GX_CP_VAT_GROUP2_TXC7_CNT_SHIFT & GX_CP_VAT_GROUP2_TXC7_CNT_LMASK); + pList[GX_VA_TEX7 - GX_VA_POS].shift = vat2 >> GX_CP_VAT_GROUP2_TXC7_SHIFT_SHIFT & GX_CP_VAT_GROUP2_TXC7_SHIFT_LMASK; + // clang-format on + + return true; +} + +void ResShp::GXSetArray(GXAttr attr, const void *pBase, u8 stride) { + u8 *pCmd = GetResShpPrePrim().ref().dl.array[attr - GX_VA_POS]; + u32 cpAttr = attr != GX_VA_NBT ? attr - GX_VA_POS : 1; + + detail::ResWriteCPCmd( + &pCmd[GX_CP_CMD_SZ * 0], cpAttr + GX_CP_REG_ARRAYBASE, reinterpret_cast(OSCachedToPhysical(pBase)) + ); + + detail::ResWriteCPCmd(&pCmd[GX_CP_CMD_SZ * 1], cpAttr + GX_CP_REG_ARRAYSTRIDE, stride); +} + +void ResShp::DisableSetArray(GXAttr attr) { + u8 *pCmd = GetResShpPrePrim().ref().dl.array[attr - GX_VA_POS]; + std::memset(pCmd, 0, GX_CP_CMD_SZ * 2); +} + +ResVtxPos ResShp::GetResVtxPos() const { + return GetParent().GetResVtxPos(ref().idVtxPosition); +} + +ResVtxNrm ResShp::GetResVtxNrm() const { + const ResShpData &r = ref(); + + if (r.idVtxNormal != -1) { + return GetParent().GetResVtxNrm(r.idVtxNormal); + } + + return ResVtxNrm(NULL); +} + +ResVtxClr ResShp::GetResVtxClr(u32 idx) const { + const ResShpData &r = ref(); + + if (r.idVtxColor[idx] != -1) { + return GetParent().GetResVtxClr(r.idVtxColor[idx]); + } + + return ResVtxClr(NULL); +} + +ResVtxTexCoord ResShp::GetResVtxTexCoord(u32 idx) const { + const ResShpData &r = ref(); + + if (r.idVtxTexCoord[idx] != -1) { + return GetParent().GetResVtxTexCoord(r.idVtxTexCoord[idx]); + } + + return ResVtxTexCoord(NULL); +} + +void ResShp::Init() { + const void *pBase; + u8 stride; + + GetResVtxPos().GetArray(&pBase, &stride); + GXSetArray(GX_VA_POS, pBase, stride); + + ResVtxNrm nrm = GetResVtxNrm(); + if (nrm.IsValid()) { + nrm.GetArray(&pBase, &stride); + GXSetArray(GX_VA_NRM, pBase, stride); + } + + u32 i; + + for (i = 0; i < GX_VA_TEX0 - GX_VA_CLR0; i++) { + ResVtxClr clr = GetResVtxClr(i); + + if (clr.IsValid()) { + clr.GetArray(&pBase, &stride); + GXSetArray(static_cast(GX_VA_CLR0 + i), pBase, stride); + } + } + + for (i = 0; i < GX_POS_MTX_ARRAY - GX_VA_TEX0; i++) { + ResVtxTexCoord txc = GetResVtxTexCoord(i); + + if (txc.IsValid()) { + txc.GetArray(&pBase, &stride); + GXSetArray(static_cast(GX_VA_TEX0 + i), pBase, stride); + } + } + + GetResShpPrePrim().DCStore(false); + + // TODO: Fakematch + ResShpData &r = ref(); + DC::StoreRangeNoSync(GetPrimDLTag().GetDL(), r.tagPrimDL.bufSize); +} + +void ResShp::Terminate() { + DisableSetArray(GX_VA_POS); + DisableSetArray(GX_VA_NRM); + + DisableSetArray(GX_VA_CLR0); + DisableSetArray(GX_VA_CLR1); + + DisableSetArray(GX_VA_TEX0); + DisableSetArray(GX_VA_TEX1); + DisableSetArray(GX_VA_TEX2); + DisableSetArray(GX_VA_TEX3); + DisableSetArray(GX_VA_TEX4); + DisableSetArray(GX_VA_TEX5); + DisableSetArray(GX_VA_TEX6); + DisableSetArray(GX_VA_TEX7); +} + +void ResShp::CallPrePrimitiveDisplayList(bool sync, bool cacheIsSame) const { + // TODO: Should be non-const, and initialized by value + const ResTagDL &rTag = GetPrePrimDLTag(); + + if (cacheIsSame) { + if (sync) { + GXCallDisplayList(const_cast(rTag.GetDL() + 32), rTag.GetCmdSize() - 32); + } else { + GXFastCallDisplayList(const_cast(rTag.GetDL() + 32), rTag.GetCmdSize() - 32); + } + + return; + } + + if (sync) { + GXCallDisplayList(const_cast(rTag.GetDL()), rTag.GetCmdSize()); + } else { + GXFastCallDisplayList(const_cast(rTag.GetDL()), rTag.GetCmdSize()); + } +} + +void ResShp::CallPrimitiveDisplayList(bool sync) const { + // TODO: Should be non-const, and initialized by value + const ResTagDL &rTag = GetPrimDLTag(); + + if (sync) { + GXCallDisplayList(const_cast(rTag.GetDL()), rTag.GetCmdSize()); + } else { + GXFastCallDisplayList(const_cast(rTag.GetDL()), rTag.GetCmdSize()); + } +} + +void ResShpPrePrim::DCStore(bool sync) { + ResPrePrimDL &r = ref(); + u32 size = sizeof(ResPrePrimDL); + + if (sync) { + DC::StoreRange(&r, size); + } else { + DC::StoreRangeNoSync(&r, size); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_restev.cpp b/src/nw4r/g3d/res/g3d_restev.cpp new file mode 100644 index 00000000..a990e6c1 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_restev.cpp @@ -0,0 +1,202 @@ +#include + +#include +#include + +namespace nw4r { +namespace g3d { + +bool ResTev::GXGetTevSwapModeTable( + GXTevSwapSel swap, GXTevColorChan *pR, GXTevColorChan *pG, GXTevColorChan *pB, GXTevColorChan *pA +) const { + const u8 *pCmd = ref().dl.dl.common.dl.swapModeTable[swap]; + u32 cmd; + + if (pCmd[0] == 0) { + return false; + } + + detail::ResReadBPCmd(&pCmd[GX_BP_CMD_SZ * 1], &cmd); + + if (pR != NULL) { + *pR = static_cast(cmd >> GX_BP_TEVKSEL_SWAP_RB_SHIFT & GX_BP_TEVKSEL_SWAP_RB_LMASK); + } + if (pG != NULL) { + *pG = static_cast(cmd >> GX_BP_TEVKSEL_SWAP_GA_SHIFT & GX_BP_TEVKSEL_SWAP_GA_LMASK); + } + + detail::ResReadBPCmd(&pCmd[GX_BP_CMD_SZ * 3], &cmd); + + if (pB != NULL) { + *pB = static_cast(cmd >> GX_BP_TEVKSEL_SWAP_RB_SHIFT & GX_BP_TEVKSEL_SWAP_RB_LMASK); + } + if (pA != NULL) { + *pA = static_cast(cmd >> GX_BP_TEVKSEL_SWAP_GA_SHIFT & GX_BP_TEVKSEL_SWAP_GA_LMASK); + } + + return true; +} + +void ResTev::GXSetTevSwapModeTable( + GXTevSwapSel swap, GXTevColorChan r, GXTevColorChan g, GXTevColorChan b, GXTevColorChan a +) { + u8 *pCmd = ref().dl.dl.common.dl.swapModeTable[swap]; + u32 cmd; + + // clang-format off + detail::ResWriteSSMask(&pCmd[GX_BP_CMD_SZ * 0], + GX_BP_TEVKSEL_SWAP_RB_MASK | GX_BP_TEVKSEL_SWAP_GA_MASK); + + cmd = 0; + cmd |= r << GX_BP_TEVKSEL_SWAP_RB_SHIFT; + cmd |= g << GX_BP_TEVKSEL_SWAP_GA_SHIFT; + cmd |= (swap * 2 + GX_BP_REG_TEVKSEL0) << GX_BP_OPCODE_SHIFT; + + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 1], cmd, + ~(GX_BP_TEVKSEL_KASEL_ODD_MASK | GX_BP_TEVKSEL_KCSEL_ODD_MASK | + GX_BP_TEVKSEL_KASEL_EVEN_MASK | GX_BP_TEVKSEL_KCSEL_EVEN_MASK)); + + detail::ResWriteSSMask(&pCmd[GX_BP_CMD_SZ * 2], + GX_BP_TEVKSEL_SWAP_RB_MASK | GX_BP_TEVKSEL_SWAP_GA_MASK); + + cmd = 0; + cmd |= b << GX_BP_TEVKSEL_SWAP_RB_SHIFT; + cmd |= a << GX_BP_TEVKSEL_SWAP_GA_SHIFT; + cmd |= (swap * 2 + GX_BP_REG_TEVKSEL1) << GX_BP_OPCODE_SHIFT; + + detail::ResWriteBPCmd(&pCmd[GX_BP_CMD_SZ * 3], cmd, + ~(GX_BP_TEVKSEL_KASEL_ODD_MASK | GX_BP_TEVKSEL_KCSEL_ODD_MASK | + GX_BP_TEVKSEL_KASEL_EVEN_MASK | GX_BP_TEVKSEL_KCSEL_EVEN_MASK)); + // clang-format on +} + +bool ResTev::GXGetTevOrder(GXTevStageID stage, GXTexCoordID *pCoord, GXTexMapID *pMap, GXChannelID *pChannel) const { + // Convert RAS channel ID to GX channel ID + static const GXChannelID r2c[GX_RAS_MAX_CHANNEL] = {GX_COLOR0A0, GX_COLOR1A1, GX_COLOR_NULL, GX_COLOR_NULL, + GX_COLOR_NULL, GX_ALPHA_BUMP, GX_ALPHA_BUMPN, GX_COLOR_ZERO}; + + const u8 *pCmd = ref().dl.dl.var[stage / TEV_STAGES_PER_DL].dl.tevOrder; + + if (pCmd[0] == 0) { + return false; + } + + u32 cmd; + detail::ResReadBPCmd(pCmd, &cmd); + + bool enabled; + GXTexCoordID coord; + GXTexMapID map; + GXChannelID channel; + + if (stage & 1) { + channel = r2c[cmd >> GX_BP_RAS1_TREF_COLORCHAN_ODD_SHIFT & GX_BP_RAS1_TREF_COLORCHAN_ODD_LMASK]; + + coord = + static_cast(cmd >> GX_BP_RAS1_TREF_TEXCOORD_ODD_SHIFT & GX_BP_RAS1_TREF_TEXCOORD_ODD_LMASK); + + enabled = cmd >> GX_BP_RAS1_TREF_ENABLE_TEX_ODD_SHIFT & GX_BP_RAS1_TREF_ENABLE_TEX_ODD_LMASK; + + map = static_cast(cmd >> GX_BP_RAS1_TREF_TEXMAP_ODD_SHIFT & GX_BP_RAS1_TREF_TEXMAP_ODD_LMASK); + } else { + channel = r2c[cmd >> GX_BP_RAS1_TREF_COLORCHAN_EVEN_SHIFT & GX_BP_RAS1_TREF_COLORCHAN_EVEN_LMASK]; + + coord = + static_cast(cmd >> GX_BP_RAS1_TREF_TEXCOORD_EVEN_SHIFT & GX_BP_RAS1_TREF_TEXCOORD_EVEN_LMASK); + + enabled = cmd >> GX_BP_RAS1_TREF_ENABLE_TEX_EVEN_SHIFT & GX_BP_RAS1_TREF_ENABLE_TEX_EVEN_LMASK; + + map = static_cast(cmd >> GX_BP_RAS1_TREF_TEXMAP_EVEN_SHIFT & GX_BP_RAS1_TREF_TEXMAP_EVEN_LMASK); + } + + if (pCoord != NULL) { + *pCoord = coord; + } + + if (pChannel != NULL) { + *pChannel = channel; + } + + if (!enabled) { + map = GX_TEXMAP_NULL; + } + + if (pMap) { + *pMap = map; + } + + return true; +} + +void ResTev::GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d) { + u8 *pCmd = ref().dl.dl.var[stage / TEV_STAGES_PER_DL].dl.tevColorCalc[stage % TEV_STAGES_PER_DL]; + + // clang-format off + detail::ResWriteBPCmd(pCmd, + (d << GX_BP_TEVCOLORCOMBINER_D_SHIFT) | + (c << GX_BP_TEVCOLORCOMBINER_C_SHIFT) | + (b << GX_BP_TEVCOLORCOMBINER_B_SHIFT) | + (a << GX_BP_TEVCOLORCOMBINER_A_SHIFT) | + ((GX_BP_REG_TEVCOLORCOMBINER0 + stage * 2) + << GX_BP_OPCODE_SHIFT), + + ~(GX_BP_TEVCOLORCOMBINER_DEST_MASK | + GX_BP_TEVCOLORCOMBINER_SCALE_OR_COMPARE_MODE_MASK | + GX_BP_TEVCOLORCOMBINER_CLAMP_MASK | + GX_BP_TEVCOLORCOMBINER_OP_OR_COMPARISON_MASK | + GX_BP_TEVCOLORCOMBINER_BIAS_MASK)); + // clang-format on +} + +void ResTev::CallDisplayList(bool sync) const { + // Variable DL holds data for two GX tev stages + static const u32 dlsize[GX_MAX_TEVSTAGE] = { + ROUND_UP(sizeof(ResTevCommonDL) + 1 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 1 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 2 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 2 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 3 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 3 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 4 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 4 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 5 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 5 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 6 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 6 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 7 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 7 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 8 * sizeof(ResTevVariableDL), 32), + ROUND_UP(sizeof(ResTevCommonDL) + 8 * sizeof(ResTevVariableDL), 32) + }; + + if (sync) { + PPCSync(); + } + + GXCallDisplayList(const_cast(&ref().dl), dlsize[GetNumTevStages() - 1]); +} + +ResTev ResTev::CopyTo(void *pDst) { + const ResTevData *pSrc = &ref(); + detail::Copy32ByteBlocks(pDst, pSrc, sizeof(ResTevData)); + + ResTev tev(pDst); + tev.ref().toResMdlData -= reinterpret_cast(pDst) - reinterpret_cast(pSrc); + + tev.DCStore(false); + return tev; +} + +void ResTev::DCStore(bool sync) { + void *pBase = &ref(); + u32 size = ref().size; + + if (sync) { + DC::StoreRange(pBase, size); + } else { + DC::StoreRangeNoSync(pBase, size); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_restex.cpp b/src/nw4r/g3d/res/g3d_restex.cpp new file mode 100644 index 00000000..716c6167 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_restex.cpp @@ -0,0 +1,103 @@ +#include + +namespace nw4r { +namespace g3d { + +void ResPltt::DCStore(bool sync) { + void* pBase = &ref(); + u32 size = ref().header.size; + + if (sync) { + DC::StoreRange(pBase, size); + } else { + DC::StoreRangeNoSync(pBase, size); + } +} + +bool ResTex::GetTexObjParam(void** ppTexData, u16* pWidth, u16* pHeight, + GXTexFmt* pFormat, f32* pMinLod, f32* pMaxLod, + GXBool* pMipMap) const { + const ResTexData& r = ref(); + + if (IsCIFmt()) { + return false; + } + + if (ppTexData != NULL) { + *ppTexData = const_cast(GetTexData()); + } + + if (pWidth != NULL) { + *pWidth = GetWidth(); + } + + if (pHeight != NULL) { + *pHeight = GetHeight(); + } + + if (pFormat != NULL) { + *pFormat = r.fmt; + } + + if (pMinLod != NULL) { + *pMinLod = r.min_lod; + } + + if (pMaxLod != NULL) { + *pMaxLod = r.max_lod; + } + + if (pMipMap != NULL) { + *pMipMap = r.mipmap_level > 1; + } + + return true; +} + +bool ResTex::GetTexObjCIParam(void** ppTexData, u16* pWidth, u16* pHeight, + GXCITexFmt* pFormatCI, f32* pMinLod, f32* pMaxLod, + GXBool* pMipMap) const { + const ResTexData& r = ref(); + + if (!IsCIFmt()) { + return false; + } + + if (ppTexData != NULL) { + *ppTexData = const_cast(GetTexData()); + } + + if (pWidth != NULL) { + *pWidth = GetWidth(); + } + + if (pHeight != NULL) { + *pHeight = GetHeight(); + } + + if (pFormatCI != NULL) { + *pFormatCI = r.cifmt; + } + + if (pMinLod != NULL) { + *pMinLod = r.min_lod; + } + + if (pMaxLod != NULL) { + *pMaxLod = r.max_lod; + } + + if (pMipMap != NULL) { + *pMipMap = r.mipmap_level > 1; + } + + return true; +} + +void ResTex::Init() { + ResTexData& r = ref(); + DC::FlushRangeNoSync(&r, r.header.size); +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/nw4r/g3d/res/g3d_resvtx.cpp b/src/nw4r/g3d/res/g3d_resvtx.cpp new file mode 100644 index 00000000..70c78472 --- /dev/null +++ b/src/nw4r/g3d/res/g3d_resvtx.cpp @@ -0,0 +1,164 @@ +#include + +namespace nw4r { +namespace g3d { + +/****************************************************************************** + * + * ResVtxPos + * + ******************************************************************************/ +void ResVtxPos::SetArray() { + if (IsValid()) { + GXSetArray(GX_VA_POS, GetData(), ref().stride); + } +} + +void ResVtxPos::GetArray(const void** ppBase, u8* pStride) const { + if (ppBase != NULL) { + *ppBase = GetData(); + } + + if (pStride) { + *pStride = ref().stride; + } +} + +void ResVtxPos::CopyTo(void* pDst) const { + if (!IsValid()) { + return; + } + + u32 size = GetSize(); + detail::Copy32ByteBlocks(pDst, ptr(), size); + DCStoreRange(pDst, size); +} + +/****************************************************************************** + * + * ResVtxNrm + * + ******************************************************************************/ +void ResVtxNrm::SetArray() { + if (IsValid()) { + GXSetArray(GX_VA_NRM, GetData(), ref().stride); + } +} + +void ResVtxNrm::GetArray(const void** ppBase, u8* pStride) const { + if (ppBase != NULL) { + *ppBase = GetData(); + } + + if (pStride) { + *pStride = ref().stride; + } +} + +void ResVtxNrm::CopyTo(void* pDst) const { + if (!IsValid()) { + return; + } + + u32 size = GetSize(); + detail::Copy32ByteBlocks(pDst, ptr(), size); + DCStoreRange(pDst, size); +} + +/****************************************************************************** + * + * ResVtxClr + * + ******************************************************************************/ +void ResVtxClr::SetArray(GXAttr attr) { + if (IsValid() && (attr == GX_VA_CLR0 || attr == GX_VA_CLR1)) { + GXSetArray(attr, GetData(), ref().stride); + } +} + +void ResVtxClr::GetArray(const void** ppBase, u8* pStride) const { + if (ppBase != NULL) { + *ppBase = GetData(); + } + + if (pStride) { + *pStride = ref().stride; + } +} + +void ResVtxClr::CopyTo(void* pDst) const { + if (!IsValid()) { + return; + } + + u32 size = GetSize(); + detail::Copy32ByteBlocks(pDst, ptr(), size); + DCStoreRange(pDst, size); +} + +/****************************************************************************** + * + * ResVtxTexCoord + * + ******************************************************************************/ +void ResVtxTexCoord::GetArray(const void** ppBase, u8* pStride) const { + if (ppBase != NULL) { + *ppBase = GetData(); + } + + if (pStride) { + *pStride = ref().stride; + } +} + +/****************************************************************************** + * + * DCStore + * + ******************************************************************************/ +void ResVtxPos::DCStore(bool sync) { + void* pBase = &ref(); + u32 size = GetSize(); + + if (sync) { + DC::StoreRange(pBase, size); + } else { + DC::StoreRangeNoSync(pBase, size); + } +} + +void ResVtxNrm::DCStore(bool sync) { + void* pBase = &ref(); + u32 size = GetSize(); + + if (sync) { + DC::StoreRange(pBase, size); + } else { + DC::StoreRangeNoSync(pBase, size); + } +} + +void ResVtxClr::DCStore(bool sync) { + void* pBase = &ref(); + u32 size = GetSize(); + + if (sync) { + DC::StoreRange(pBase, size); + } else { + DC::StoreRangeNoSync(pBase, size); + } +} + +void ResVtxTexCoord::DCStore(bool sync) { + void* pBase = &ref(); + u32 size = GetSize(); + + if (sync) { + DC::StoreRange(pBase, size); + } else { + DC::StoreRangeNoSync(pBase, size); + } +} + +} // namespace g3d +} // namespace nw4r diff --git a/src/toBeSorted/arc_callback_handler.cpp b/src/toBeSorted/arc_callback_handler.cpp index 8439aec8..4112fcfd 100644 --- a/src/toBeSorted/arc_callback_handler.cpp +++ b/src/toBeSorted/arc_callback_handler.cpp @@ -3,9 +3,7 @@ #include "d/d_rawarchive.h" #include "egg/gfx/eggLight.h" #include "m/m3d/m3d.h" -#include "nw4r/g3d/g3d_resfile.h" -#include "nw4r/g3d/g3d_resmat.h" -#include "nw4r/g3d/g3d_resmdl.h" +#include "nw4r/g3d.h" // IWYU pragma: export #include "toBeSorted/arc_managers/current_stage_arc_manager.h" #include "toBeSorted/arc_managers/oarc_manager.h" @@ -20,8 +18,8 @@ ArcCallbackHandler ArcCallbackHandler::sInstance; extern "C" void FUN_804a7260(nw4r::g3d::ResMdl, const char *prefix); void BindSystemModelsAndLighting(nw4r::g3d::ResFile file) { - nw4r::g3d::ResFile sysFile = OarcManager::sInstance->getMdlFromArc2("System"); - if (sysFile.mFile.IsValid()) { + nw4r::g3d::ResFile sysFile(OarcManager::sInstance->getMdlFromArc2("System")); + if (sysFile.IsValid()) { file.Bind(sysFile); } @@ -51,7 +49,7 @@ void BindSystemModelsAndLighting(nw4r::g3d::ResFile file) { void ArcCallbackHandlerBase::CreateArcEntry(void *data, const char *path) { if (mPrefix == NAME_G3D) { - nw4r::g3d::ResFile file = data; + nw4r::g3d::ResFile file(data); file.Init(); file.Bind(); BindSystemModelsAndLighting(file); diff --git a/src/toBeSorted/arc_managers/oarc_manager.cpp b/src/toBeSorted/arc_managers/oarc_manager.cpp index 1f858b41..117981b5 100644 --- a/src/toBeSorted/arc_managers/oarc_manager.cpp +++ b/src/toBeSorted/arc_managers/oarc_manager.cpp @@ -2,7 +2,6 @@ #include "d/d_heap.h" - OarcManager *OarcManager::sInstance; OarcManager::OarcManager() { diff --git a/src/toBeSorted/attention.cpp b/src/toBeSorted/attention.cpp index b81dff54..b7a5b448 100644 --- a/src/toBeSorted/attention.cpp +++ b/src/toBeSorted/attention.cpp @@ -4,6 +4,7 @@ #include "d/a/d_a_player.h" #include "d/d_heap.h" #include "d/d_pad.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "toBeSorted/arc_managers/oarc_manager.h" #include "toBeSorted/event_manager.h" @@ -36,7 +37,12 @@ void UnkAttnClass::init() {} void UnkAttnClass::remove() {} UnkAttnClass::UnkAttnClass() - : field_0x00(0), field_0x08(field_0x00 | 8), field_0x0A(300), field_0x0C(30), field_0x10(30), field_0x12(10), + : field_0x00(0), + field_0x08(field_0x00 | 8), + field_0x0A(300), + field_0x0C(30), + field_0x10(30), + field_0x12(10), field_0x14(1.0f) {} UnkAttnClass attnClass; @@ -93,7 +99,7 @@ static const CursorStruct s_Cursors[2] = { }; bool AttentionManager::createHeap() { - mModels.mResFile = OarcManager::sInstance->getMdlFromArc2("UI_Data"); + mModels.mResFile = nw4r::g3d::ResFile(OarcManager::sInstance->getMdlFromArc2("UI_Data")); for (int i = 0; i < 2; i++) { InteractionMdl *iMdl = &mModels.mMdls[i];