From 3d08d079c92a775b6414e017723ff6caf9e7f27e Mon Sep 17 00:00:00 2001 From: Hat Kid <6624576+Hat-Kid@users.noreply.github.com> Date: Mon, 23 Jan 2023 00:07:46 +0100 Subject: [PATCH] jak2: `ocean` renderer (#2142) Initial implementation of the `ocean-mid`, `ocean-far` and `ocean-near` renderers for Jak 2. There's still a few things to sort out, mainly: - [x] ~Backwards compatibility with Jak 1. The only thing that currently stands in the way of that is figuring out a clean way to "un-hardcode" the texture base pointer in C++ without creating a completely separate `OceanTexture` class for Jak 2. One thing I thought of would be modifying `BucketRenderer`'s virtual `init_textures` method to also pass the `GameVersion`, but I'm not sure if there's a better way.~ - [x] ~The sudden transition from `ocean-near` to `ocean-mid`. Not sure why it's happening or how to fix it.~ - [x] The ocean has two new methods in Jak 2, `ocean::89` and `ocean::79`, one of which seems to be related to time of day sky colors. ~Even without them implemented, the end result looks quite close, so we may be able to skip them?~ `ocean::89` generates `ocean-mid` envmap textures, so it will likely be required, but will not be handled right now. Reverted the VU prologue removals because it made the tests fail. --- decompiler/config/jak2/all-types.gc | 4 +- .../opengl_renderer/BucketRenderer.cpp | 4 +- .../graphics/opengl_renderer/BucketRenderer.h | 4 +- game/graphics/opengl_renderer/EyeRenderer.cpp | 2 +- game/graphics/opengl_renderer/EyeRenderer.h | 2 +- .../opengl_renderer/OpenGLRenderer.cpp | 10 +- .../ocean/CommonOceanRenderer.cpp | 21 +- .../opengl_renderer/ocean/OceanMid.cpp | 121 ++ .../graphics/opengl_renderer/ocean/OceanMid.h | 6 + .../opengl_renderer/ocean/OceanMidAndFar.cpp | 104 +- .../opengl_renderer/ocean/OceanMidAndFar.h | 10 +- .../opengl_renderer/ocean/OceanMid_PS2.cpp | 1661 +++++++++++++++++ .../opengl_renderer/ocean/OceanNear.cpp | 101 +- .../opengl_renderer/ocean/OceanNear.h | 9 +- .../opengl_renderer/ocean/OceanNear_PS2.cpp | 1483 +++++++++++++++ .../opengl_renderer/ocean/OceanTexture.cpp | 185 +- .../opengl_renderer/ocean/OceanTexture.h | 15 +- .../opengl_renderer/ocean/OceanTexture_PC.cpp | 234 +++ .../opengl_renderer/shaders/ocean_common.vert | 2 +- goal_src/jak2/engine/gfx/ocean/ocean-mid.gc | 2 +- goal_src/jak2/engine/gfx/ocean/ocean-near.gc | 2 +- .../jak2/engine/gfx/ocean/ocean-texture.gc | 6 +- goal_src/jak2/engine/gfx/ocean/ocean.gc | 15 +- goal_src/jak2/engine/gfx/vu1-user-h.gc | 4 +- .../jak2/engine/gfx/ocean/ocean_REF.gc | 8 +- 25 files changed, 3961 insertions(+), 54 deletions(-) diff --git a/decompiler/config/jak2/all-types.gc b/decompiler/config/jak2/all-types.gc index e151a2d1d5..57bcb50ee9 100644 --- a/decompiler/config/jak2/all-types.gc +++ b/decompiler/config/jak2/all-types.gc @@ -2724,7 +2724,7 @@ (bucket-3 3) ;; blit displays (tex-lcom-sky-pre 4) ;; tex (sky-draw 5) ;; sky - (bucket-6 6) ;; ocean + (ocean-mid-far 6) ;; ocean ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; All levels with tfrag tpage @@ -3080,7 +3080,7 @@ (tex-lcom-sky-post 309) - (bucket-310 310) ;; ocean + (ocean-near 310) ;; ocean (bucket-311 311) ;; depth-cue (tex-all-sprite 312) diff --git a/game/graphics/opengl_renderer/BucketRenderer.cpp b/game/graphics/opengl_renderer/BucketRenderer.cpp index e14717f598..464e462d28 100644 --- a/game/graphics/opengl_renderer/BucketRenderer.cpp +++ b/game/graphics/opengl_renderer/BucketRenderer.cpp @@ -99,9 +99,9 @@ void RenderMux::draw_debug_window() { m_renderers[m_render_idx]->draw_debug_window(); } -void RenderMux::init_textures(TexturePool& tp) { +void RenderMux::init_textures(TexturePool& tp, GameVersion version) { for (auto& rend : m_renderers) { - rend->init_textures(tp); + rend->init_textures(tp, version); } } diff --git a/game/graphics/opengl_renderer/BucketRenderer.h b/game/graphics/opengl_renderer/BucketRenderer.h index 4e09832036..3db73783be 100644 --- a/game/graphics/opengl_renderer/BucketRenderer.h +++ b/game/graphics/opengl_renderer/BucketRenderer.h @@ -95,7 +95,7 @@ class BucketRenderer { virtual bool empty() const { return false; } virtual void draw_debug_window() = 0; virtual void init_shaders(ShaderLibrary&) {} - virtual void init_textures(TexturePool&) {} + virtual void init_textures(TexturePool&, GameVersion) {} protected: std::string m_name; @@ -111,7 +111,7 @@ class RenderMux : public BucketRenderer { void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override; void draw_debug_window() override; void init_shaders(ShaderLibrary&) override; - void init_textures(TexturePool&) override; + void init_textures(TexturePool&, GameVersion) override; void set_idx(u32 i) { m_render_idx = i; }; private: diff --git a/game/graphics/opengl_renderer/EyeRenderer.cpp b/game/graphics/opengl_renderer/EyeRenderer.cpp index b5767cd4af..ef0a9fc018 100644 --- a/game/graphics/opengl_renderer/EyeRenderer.cpp +++ b/game/graphics/opengl_renderer/EyeRenderer.cpp @@ -11,7 +11,7 @@ ///////////////////////// EyeRenderer::EyeRenderer(const std::string& name, int id) : BucketRenderer(name, id) {} -void EyeRenderer::init_textures(TexturePool& texture_pool) { +void EyeRenderer::init_textures(TexturePool& texture_pool, GameVersion) { // set up eyes for (int pair_idx = 0; pair_idx < NUM_EYE_PAIRS; pair_idx++) { for (int lr = 0; lr < 2; lr++) { diff --git a/game/graphics/opengl_renderer/EyeRenderer.h b/game/graphics/opengl_renderer/EyeRenderer.h index e9e3119420..47deaeae9c 100644 --- a/game/graphics/opengl_renderer/EyeRenderer.h +++ b/game/graphics/opengl_renderer/EyeRenderer.h @@ -16,7 +16,7 @@ class EyeRenderer : public BucketRenderer { ~EyeRenderer(); void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override; void draw_debug_window() override; - void init_textures(TexturePool& texture_pool) override; + void init_textures(TexturePool& texture_pool, GameVersion) override; void handle_eye_dma2(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof); diff --git a/game/graphics/opengl_renderer/OpenGLRenderer.cpp b/game/graphics/opengl_renderer/OpenGLRenderer.cpp index e35bf8b6a2..b0f9edcc39 100644 --- a/game/graphics/opengl_renderer/OpenGLRenderer.cpp +++ b/game/graphics/opengl_renderer/OpenGLRenderer.cpp @@ -93,8 +93,8 @@ void OpenGLRenderer::init_bucket_renderers_jak2() { init_bucket_renderer("tex-lcom-sky-pre", BucketCategory::TEX, BucketId::TEX_LCOM_SKY_PRE); init_bucket_renderer("sky-draw", BucketCategory::OTHER, BucketId::SKY_DRAW, 1024); - init_bucket_renderer("ocean-mid-far", BucketCategory::OCEAN, - BucketId::OCEAN_MID_FAR); + init_bucket_renderer("ocean-mid-far", BucketCategory::OCEAN, + BucketId::OCEAN_MID_FAR); init_bucket_renderer("tex-l0-tfrag", BucketCategory::TEX, BucketId::TEX_L0_TFRAG); init_bucket_renderer("tfrag-l0-tfrag", BucketCategory::TFRAG, BucketId::TFRAG_L0_TFRAG, @@ -279,7 +279,7 @@ void OpenGLRenderer::init_bucket_renderers_jak2() { init_bucket_renderer("tex-lcom-sky-post", BucketCategory::TEX, BucketId::TEX_LCOM_SKY_POST); // 310 - init_bucket_renderer("bucket-310", BucketCategory::OCEAN, BucketId::OCEAN_NEAR); + init_bucket_renderer("ocean-near", BucketCategory::OCEAN, BucketId::OCEAN_NEAR); init_bucket_renderer("tex-all-sprite", BucketCategory::TEX, BucketId::TEX_ALL_SPRITE); init_bucket_renderer("particles", BucketCategory::SPRITE, BucketId::PARTICLES); @@ -309,7 +309,7 @@ void OpenGLRenderer::init_bucket_renderers_jak2() { } m_bucket_renderers[i]->init_shaders(m_render_state.shaders); - m_bucket_renderers[i]->init_textures(*m_render_state.texture_pool); + m_bucket_renderers[i]->init_textures(*m_render_state.texture_pool, GameVersion::Jak2); } m_render_state.loader->load_common(*m_render_state.texture_pool, "GAME"); } @@ -534,7 +534,7 @@ void OpenGLRenderer::init_bucket_renderers_jak1() { } m_bucket_renderers[i]->init_shaders(m_render_state.shaders); - m_bucket_renderers[i]->init_textures(*m_render_state.texture_pool); + m_bucket_renderers[i]->init_textures(*m_render_state.texture_pool, GameVersion::Jak1); } sky_cpu_blender->init_textures(*m_render_state.texture_pool); sky_gpu_blender->init_textures(*m_render_state.texture_pool); diff --git a/game/graphics/opengl_renderer/ocean/CommonOceanRenderer.cpp b/game/graphics/opengl_renderer/ocean/CommonOceanRenderer.cpp index ea3c4fc2a0..59136892e0 100644 --- a/game/graphics/opengl_renderer/ocean/CommonOceanRenderer.cpp +++ b/game/graphics/opengl_renderer/ocean/CommonOceanRenderer.cpp @@ -2,6 +2,9 @@ #include "common/log/log.h" +constexpr int OCEAN_TEX_TBP_JAK1 = 8160; // todo +constexpr int OCEAN_TEX_TBP_JAK2 = 672; + CommonOceanRenderer::CommonOceanRenderer() { m_vertices.resize(4096 * 10); // todo decrease for (auto& buf : m_indices) { @@ -244,8 +247,14 @@ void CommonOceanRenderer::handle_near_adgif(const u8* data, u32 offset, u32 coun most_recent_tbp = reg.tbp0(); } break; case GsRegisterAddress::ALPHA_1: { - // ignore, we've hardcoded alphas. + GsAlpha reg(value); + if (reg.a_mode() == GsAlpha::BlendMode::SOURCE && + reg.b_mode() == GsAlpha::BlendMode::ZERO_OR_FIXED && + reg.c_mode() == GsAlpha::BlendMode::DEST && reg.d_mode() == GsAlpha::BlendMode::DEST) { + m_current_bucket = VertexBucket::ENV_MAP; + } } break; + case GsRegisterAddress::FRAME_1: { u32 mask = value >> 32; if (mask) { @@ -290,7 +299,9 @@ void CommonOceanRenderer::flush_near(SharedRenderState* render_state, ScopedProf case 0: { glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); glBlendEquation(GL_FUNC_ADD); - auto tex = render_state->texture_pool->lookup(8160); + auto tbp = + render_state->version == GameVersion::Jak1 ? OCEAN_TEX_TBP_JAK1 : OCEAN_TEX_TBP_JAK2; + auto tex = render_state->texture_pool->lookup(tbp); if (!tex) { tex = render_state->texture_pool->get_placeholder_texture(); } @@ -419,7 +430,7 @@ void CommonOceanRenderer::handle_mid_adgif(const u8* data, u32 offset) { } } - if (most_recent_tbp != 8160) { + if (most_recent_tbp != OCEAN_TEX_TBP_JAK2) { m_envmap_tex = most_recent_tbp; } @@ -482,7 +493,9 @@ void CommonOceanRenderer::flush_mid(SharedRenderState* render_state, ScopedProfi for (int bucket = 0; bucket < 2; bucket++) { switch (bucket) { case 0: { - auto tex = render_state->texture_pool->lookup(8160); + auto tbp = + render_state->version == GameVersion::Jak1 ? OCEAN_TEX_TBP_JAK1 : OCEAN_TEX_TBP_JAK2; + auto tex = render_state->texture_pool->lookup(tbp); if (!tex) { tex = render_state->texture_pool->get_placeholder_texture(); } diff --git a/game/graphics/opengl_renderer/ocean/OceanMid.cpp b/game/graphics/opengl_renderer/ocean/OceanMid.cpp index 07237aace9..bb3dc1ca3a 100644 --- a/game/graphics/opengl_renderer/ocean/OceanMid.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanMid.cpp @@ -133,6 +133,127 @@ void OceanMid::run(DmaFollower& dma, SharedRenderState* render_state, ScopedProf m_common_ocean_renderer.flush_mid(render_state, prof); } +void OceanMid::run_jak2(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof) { + m_common_ocean_renderer.init_for_mid(); + // first is setting base and offset + { + auto base_offset_tag = dma.read_and_advance(); + ASSERT(base_offset_tag.size_bytes == 0); + auto base = base_offset_tag.vifcode0(); + ASSERT(base.kind == VifCode::Kind::BASE); + ASSERT(base.immediate == VU1_INPUT_BUFFER_BASE); + auto offset = base_offset_tag.vifcode1(); + ASSERT(offset.kind == VifCode::Kind::OFFSET); + ASSERT(offset.immediate == VU1_INPUT_BUFFER_OFFSET); + } + + // next is constants + { + auto constants = dma.read_and_advance(); + ASSERT(constants.size_bytes == sizeof(Constants)); + ASSERT(constants.vifcode0().kind == VifCode::Kind::STCYCL); // for whatever reason they do this + auto unpack = constants.vifcode1(); + ASSERT(VifCodeUnpack(unpack).addr_qw == Vu1Data::CONSTANTS); + memcpy(&m_constants, constants.data, sizeof(Constants)); + memcpy(m_vu_data + Vu1Data::CONSTANTS, &m_constants, sizeof(Constants)); + } + + // next is call 0 + { + auto call0 = dma.read_and_advance(); + ASSERT(call0.vifcode0().kind == VifCode::Kind::STCYCL); + auto c = call0.vifcode1(); + ASSERT(c.kind == VifCode::Kind::MSCALF); + ASSERT(c.immediate == 0); + run_call0(); + } + + while (!is_end_tag(dma.current_tag(), dma.current_tag_vif0(), dma.current_tag_vif1())) { + auto data = dma.read_and_advance(); + auto v0 = data.vifcode0(); + auto v1 = data.vifcode1(); + if (v0.kind == VifCode::Kind::STCYCL && v0.immediate == 0x404 && + v1.kind == VifCode::Kind::UNPACK_V4_32) { + auto up = VifCodeUnpack(v1); + // ASSERT(up.use_tops_flag); + u16 addr = up.addr_qw + (up.use_tops_flag ? get_upload_buffer() : 0); + ASSERT(addr + v1.num <= 1024); + memcpy(m_vu_data + addr, data.data, 16 * v1.num); + ASSERT(16 * v1.num == data.size_bytes); + } else if (v0.kind == VifCode::Kind::STCYCL && v0.immediate == 0x404 && + v1.kind == VifCode::Kind::UNPACK_V4_8) { + auto up = VifCodeUnpack(v1); + ASSERT(up.use_tops_flag); + ASSERT(up.is_unsigned); + u16 addr = up.addr_qw + get_upload_buffer(); + ASSERT(addr + v1.num <= 1024); + + u32 temp[4]; + for (u32 i = 0; i < v1.num; i++) { + for (u32 j = 0; j < 4; j++) { + temp[j] = data.data[4 * i + j]; + } + memcpy(m_vu_data + addr + i, temp, 16); + } + ASSERT(4 * v1.num == data.size_bytes); + + } else if (v0.kind == VifCode::Kind::STCYCL && v0.immediate == 0x204 && + v1.kind == VifCode::Kind::UNPACK_V4_8) { + auto up = VifCodeUnpack(v1); + ASSERT(up.use_tops_flag); + ASSERT(up.is_unsigned); + u16 addr = up.addr_qw + get_upload_buffer(); + ASSERT(addr + v1.num <= 1024); + + u32 temp[4]; + for (u32 i = 0; i < v1.num; i++) { + for (u32 j = 0; j < 4; j++) { + temp[j] = data.data[4 * i + j]; + } + // cl = 4 + // wl = 2 + u32 addr_off = 4 * (i / 2) + i % 2; + memcpy(m_vu_data + addr + addr_off, temp, 16); + } + ASSERT(8 * v1.num == data.size_bytes); + } else if (v0.kind == VifCode::Kind::STCYCL && v0.immediate == 0x404 && + v1.kind == VifCode::Kind::MSCALF) { + switch (v1.immediate) { + case 46: + run_call46_vu2c(); + break; + case 73: + run_call73_vu2c_jak2(); + break; + case 107: + run_call107_vu2c_jak2(); + break; + case 275: + run_call275_vu2c_jak2(); + break; + default: + lg::warn("unknown call1: {}", v1.immediate); + } + } else if (v0.kind == VifCode::Kind::MSCALF && v1.kind == VifCode::Kind::FLUSHA) { + switch (v0.immediate) { + case 41: + run_call41_vu2c(); + break; + case 43: + run_call43_vu2c(); + break; + default: + ASSERT_MSG(false, fmt::format("unknown call2: {}", v0.immediate)); + } + } else { + ASSERT_MSG(false, fmt::format("{} {}", data.vifcode0().print(), data.vifcode1().print())); + } + } + m_common_ocean_renderer.flush_mid(render_state, prof); +} + void OceanMid::run_call0() { run_call0_vu2c(); } diff --git a/game/graphics/opengl_renderer/ocean/OceanMid.h b/game/graphics/opengl_renderer/ocean/OceanMid.h index cae1932d28..fbf20fa412 100644 --- a/game/graphics/opengl_renderer/ocean/OceanMid.h +++ b/game/graphics/opengl_renderer/ocean/OceanMid.h @@ -9,6 +9,7 @@ class OceanMid { public: OceanMid(); void run(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof); + void run_jak2(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof); private: void run_call0(); @@ -17,13 +18,18 @@ class OceanMid { void run_call43_vu2c(); void run_call46_vu2c(); void run_call73_vu2c(); + void run_call73_vu2c_jak2(); void run_call107_vu2c(); + void run_call107_vu2c_jak2(); void run_call275_vu2c(); + void run_call275_vu2c_jak2(); void xgkick(u16 addr); void run_L26_vu2c(); void run_L32_vu2c(); + void run_L32_vu2c_jak2(); void run_L38_vu2c(); + void run_L38_vu2c_jak2(); void run_L43_vu2c(); void run_L45_vu2c(); diff --git a/game/graphics/opengl_renderer/ocean/OceanMidAndFar.cpp b/game/graphics/opengl_renderer/ocean/OceanMidAndFar.cpp index 05fc4be5f4..1c57e239db 100644 --- a/game/graphics/opengl_renderer/ocean/OceanMidAndFar.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanMidAndFar.cpp @@ -10,8 +10,8 @@ void OceanMidAndFar::draw_debug_window() { m_direct.draw_debug_window(); } -void OceanMidAndFar::init_textures(TexturePool& pool) { - m_texture_renderer.init_textures(pool); +void OceanMidAndFar::init_textures(TexturePool& pool, GameVersion version) { + m_texture_renderer.init_textures(pool, version); } void OceanMidAndFar::render(DmaFollower& dma, @@ -25,6 +25,19 @@ void OceanMidAndFar::render(DmaFollower& dma, return; } + switch (render_state->version) { + case GameVersion::Jak1: + render_jak1(dma, render_state, prof); + break; + case GameVersion::Jak2: + render_jak2(dma, render_state, prof); + break; + } +} + +void OceanMidAndFar::render_jak1(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof) { // jump to bucket auto data0 = dma.read_and_advance(); ASSERT(data0.vif1() == 0); @@ -44,7 +57,7 @@ void OceanMidAndFar::render(DmaFollower& dma, { auto p = prof.make_scoped_child("texture"); - m_texture_renderer.handle_ocean_texture(dma, render_state, p); + m_texture_renderer.handle_ocean_texture_jak1(dma, render_state, p); } handle_ocean_far(dma, render_state, prof); @@ -65,6 +78,73 @@ void OceanMidAndFar::render(DmaFollower& dma, m_direct.set_mipmap(false); } +void advance_and_print_dma(DmaFollower& dma) { + auto data = dma.read_and_advance(); + printf( + "dma transfer:\n%ssize: %d\nvif0: %s, data: %d\nvif1: %s, data: %d, imm: " + "%d\n\n", + dma.current_tag().print().c_str(), data.size_bytes, data.vifcode0().print().c_str(), + data.vif0(), data.vifcode1().print().c_str(), data.vifcode1().num, data.vifcode1().immediate); +} + +void OceanMidAndFar::render_jak2(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof) { + // jump to bucket + auto data0 = dma.read_and_advance(); + ASSERT(data0.vif1() == 0 || data0.vifcode1().kind == VifCode::Kind::NOP); + ASSERT(data0.vif0() == 0 || data0.vifcode0().kind == VifCode::Kind::MARK); + ASSERT(data0.size_bytes == 0); + + // see if bucket is empty or not + if (dma.current_tag_offset() == render_state->next_bucket) { + // fmt::print("ocean-mid-far: early exit!\n"); + return; + } + m_direct.reset_state(); + + // TODO handle ocean::89 and ocean::79 + // handle_ocean_89_jak2(dma, render_state, prof); + + { + auto p = prof.make_scoped_child("texture"); + m_texture_renderer.handle_ocean_texture_jak2(dma, render_state, p); + } + + // handle_ocean_79_jak2(dma, render_state, prof); + handle_ocean_far(dma, render_state, prof); + m_direct.flush_pending(render_state, prof); + + m_direct.set_mipmap(true); + handle_ocean_mid(dma, render_state, prof); + + auto final_next = dma.read_and_advance(); + ASSERT(final_next.vifcode0().kind == VifCode::Kind::NOP && + final_next.vifcode1().kind == VifCode::Kind::NOP && final_next.size_bytes == 0); + for (int i = 0; i < 2; i++) { + dma.read_and_advance(); + } + ASSERT(dma.current_tag_offset() == render_state->next_bucket); + + // auto transfers = 0; + // // print the entire chain + // printf("START OCEAN MID FAR DMA!!!!!!!\n"); + // while (dma.current_tag_offset() != render_state->next_bucket) { + // auto data = dma.read_and_advance(); + // printf( + // "dma transfer %d:\n%ssize: %d\nvif0: %s, data: %d\nvif1: %s, data: %d, imm: " + // "%d\n\n", + // transfers, dma.current_tag().print().c_str(), data.size_bytes, + // data.vifcode0().print().c_str(), data.vif0(), data.vifcode1().print().c_str(), + // data.vifcode1().num, data.vifcode1().immediate); + // transfers++; + // } + // printf("transfers: %d\n\n", transfers); + + m_direct.flush_pending(render_state, prof); + m_direct.set_mipmap(false); +} + void OceanMidAndFar::handle_ocean_far(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) { @@ -98,7 +178,13 @@ void OceanMidAndFar::handle_ocean_mid(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) { if (dma.current_tag_vifcode0().kind == VifCode::Kind::BASE) { - m_mid_renderer.run(dma, render_state, prof); + switch (render_state->version) { + case GameVersion::Jak1: + m_mid_renderer.run(dma, render_state, prof); + break; + case GameVersion::Jak2: + m_mid_renderer.run_jak2(dma, render_state, prof); + } } else { // not drawing return; @@ -107,4 +193,12 @@ void OceanMidAndFar::handle_ocean_mid(DmaFollower& dma, while (!is_end_tag(dma.current_tag(), dma.current_tag_vifcode0(), dma.current_tag_vifcode1())) { dma.read_and_advance(); } -} \ No newline at end of file +} + +void handle_ocean_89_jak2(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof) {} + +void handle_ocean_79_jak2(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof) {} \ No newline at end of file diff --git a/game/graphics/opengl_renderer/ocean/OceanMidAndFar.h b/game/graphics/opengl_renderer/ocean/OceanMidAndFar.h index 586bb98283..52046e97ac 100644 --- a/game/graphics/opengl_renderer/ocean/OceanMidAndFar.h +++ b/game/graphics/opengl_renderer/ocean/OceanMidAndFar.h @@ -17,8 +17,10 @@ class OceanMidAndFar : public BucketRenderer { public: OceanMidAndFar(const std::string& name, int my_id); void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override; + void render_jak1(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof); + void render_jak2(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof); void draw_debug_window() override; - void init_textures(TexturePool& pool) override; + void init_textures(TexturePool& pool, GameVersion version) override; private: void handle_ocean_far(DmaFollower& dma, @@ -27,6 +29,12 @@ class OceanMidAndFar : public BucketRenderer { void handle_ocean_mid(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof); + void handle_ocean_89_jak2(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof); + void handle_ocean_79_jak2(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof); DirectRenderer m_direct; OceanTexture m_texture_renderer; diff --git a/game/graphics/opengl_renderer/ocean/OceanMid_PS2.cpp b/game/graphics/opengl_renderer/ocean/OceanMid_PS2.cpp index 0bfb3da323..ec17bbf1a4 100644 --- a/game/graphics/opengl_renderer/ocean/OceanMid_PS2.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanMid_PS2.cpp @@ -387,6 +387,110 @@ L15: return; } +void OceanMid::run_call73_vu2c_jak2() { + bool bc; + // xtop vi02 | nop 73 + vu.vi02 = xtop(); + // lq.xyzw vf07, 747(vi00) | nop 74 + lq_buffer(Mask::xyzw, vu.vf07, 747); + // lq.xyzw vf08, 0(vi02) | nop 75 + lq_buffer(Mask::xyzw, vu.vf08, vu.vi02); + // lq.xyzw vf09, 1(vi02) | nop 76 + lq_buffer(Mask::xyzw, vu.vf09, vu.vi02 + 1); + // lq.xyzw vf10, 2(vi02) | nop 77 + lq_buffer(Mask::xyzw, vu.vf10, vu.vi02 + 2); + // lq.xyzw vf11, 3(vi02) | nop 78 + lq_buffer(Mask::xyzw, vu.vf11, vu.vi02 + 3); + // lq.xyzw vf12, 4(vi02) | nop 79 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi02 + 4); + // lq.xyzw vf13, 5(vi02) | nop 80 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi02 + 5); + // lq.xyzw vf14, 6(vi02) | nop 81 + lq_buffer(Mask::xyzw, vu.vf14, vu.vi02 + 6); + // lq.xyzw vf15, 7(vi02) | nop 82 + lq_buffer(Mask::xyzw, vu.vf15, vu.vi02 + 7); + // sq.xyzw vf07, 341(vi00) | nop 83 + sq_buffer(Mask::xyzw, vu.vf07, 341); + // sq.xyzw vf07, 463(vi00) | nop 84 + sq_buffer(Mask::xyzw, vu.vf07, 463); + // iaddi vi07, vi00, 0x7 | nop 85 + vu.vi07 = 7; + // lq.xyzw vf04, 116(vi02) | nop 86 + lq_buffer(Mask::xyzw, vu.vf04, vu.vi02 + 116); +L13: + // iaddi vi01, vi07, -0x4 | nop 87 + vu.vi01 = vu.vi07 + -4; + // mtir vi10, vf04.x | nop 88 + vu.vi10 = vu.vf04.x_as_u16(); + // iaddiu vi11, vi00, 0xff | nop 89 + vu.vi11 = 0xff; /* 255 */ + // BRANCH! + // ibne vi00, vi01, L14 | nop 90 + bc = (vu.vi01 != 0); + // mr32.xyzw vf04, vf04 | nop 91 + vu.vf04.mr32(Mask::xyzw, vu.vf04); + if (bc) { + goto L14; + } + + // lq.xyzw vf04, 117(vi02) | nop 92 + lq_buffer(Mask::xyzw, vu.vf04, vu.vi02 + 117); +L14: + // BRANCH! + // ibeq vi11, vi10, L15 | nop 93 + bc = (vu.vi11 == vu.vi10); + // iaddi vi08, vi09, 0x7 | nop 94 + vu.vi08 = vu.vi09 + 7; + if (bc) { + goto L15; + } + + // BRANCH! + // bal vi15, L32 | nop 95 + // ASSERT(false); + // nop | nop 96 + + // if (bc) { goto L32; } + run_L32_vu2c_jak2(); + + // iaddiu vi01, vi00, 0x318 | nop 97 + vu.vi01 = 0x318; /* 792 */ + // xgkick vi09 | nop 98 + xgkick(vu.vi09); // draws envmapped ocean + // BRANCH! + // ibeq vi00, vi14, L15 | nop 99 + bc = (vu.vi14 == 0); + // isub vi09, vi01, vi09 | nop 100 + vu.vi09 = vu.vi01 - vu.vi09; + if (bc) { + goto L15; + } + + // BRANCH! + // bal vi15, L38 | nop 101 + // ASSERT(false); + // nop | nop 102 + + // if (bc) { goto L38; } + run_L38_vu2c_jak2(); + +L15: + // BRANCH! + // ibgtz vi07, L13 | nop 103 + bc = ((s16)vu.vi07) > 0; + // iaddi vi07, vi07, -0x1 | nop 104 + vu.vi07 = vu.vi07 + -1; + if (bc) { + goto L13; + } + + // nop | nop :e 105 + + // nop | nop 106 + + return; +} + void OceanMid::run_call107_vu2c() { bool bc; // xtop vi02 | nop 107 @@ -800,6 +904,419 @@ L21: return; } +void OceanMid::run_call107_vu2c_jak2() { + bool bc; + // xtop vi02 | nop 107 + vu.vi02 = xtop(); + // xtop vi03 | nop 108 + vu.vi03 = vu.vi02; // xtop(); + // ior vi04, vi00, vi00 | nop 109 + vu.vi04 = 0; + // ilw.x vi05, 8(vi02) | nop 110 + ilw_buffer(Mask::x, vu.vi05, vu.vi02 + 8); + // lq.xyzw vf08, 0(vi02) | nop 111 + lq_buffer(Mask::xyzw, vu.vf08, vu.vi02); + // lq.xyzw vf09, 1(vi02) | nop 112 + lq_buffer(Mask::xyzw, vu.vf09, vu.vi02 + 1); + // lq.xyzw vf10, 2(vi02) | nop 113 + lq_buffer(Mask::xyzw, vu.vf10, vu.vi02 + 2); + // lq.xyzw vf11, 3(vi02) | nop 114 + lq_buffer(Mask::xyzw, vu.vf11, vu.vi02 + 3); + // lq.xyzw vf12, 4(vi02) | nop 115 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi02 + 4); + // lq.xyzw vf13, 5(vi02) | nop 116 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi02 + 5); + // lq.xyzw vf14, 6(vi02) | nop 117 + lq_buffer(Mask::xyzw, vu.vf14, vu.vi02 + 6); + // lq.xyzw vf15, 7(vi02) | nop 118 + lq_buffer(Mask::xyzw, vu.vf15, vu.vi02 + 7); +L17: + // lq.xyzw vf16, 17(vi03) | nop 119 + lq_buffer(Mask::xyzw, vu.vf16, vu.vi03 + 17); + // lq.xyzw vf28, 765(vi00) | nop 120 + lq_buffer(Mask::xyzw, vu.vf28, 765); + // lq.xyzw vf29, 766(vi00) | nop 121 + lq_buffer(Mask::xyzw, vu.vf29, 766); + // lq.xyzw vf30, 767(vi00) | nop 122 + lq_buffer(Mask::xyzw, vu.vf30, 767); + // lq.xyzw vf31, 768(vi00) | nop 123 + lq_buffer(Mask::xyzw, vu.vf31, 768); + // lq.xyzw vf24, 9(vi02) | mulax.xyzw ACC, vf28, vf16 124 + vu.acc.mula(Mask::xyzw, vu.vf28, vu.vf16.x()); + lq_buffer(Mask::xyzw, vu.vf24, vu.vi02 + 9); + // lq.xyzw vf25, 10(vi02) | madday.xyzw ACC, vf29, vf16 125 + vu.acc.madda(Mask::xyzw, vu.vf29, vu.vf16.y()); + lq_buffer(Mask::xyzw, vu.vf25, vu.vi02 + 10); + // lq.xyzw vf26, 11(vi02) | maddaz.xyzw ACC, vf30, vf16 126 + vu.acc.madda(Mask::xyzw, vu.vf30, vu.vf16.z()); + lq_buffer(Mask::xyzw, vu.vf26, vu.vi02 + 11); + // lq.xyzw vf27, 12(vi02) | maddw.xyzw vf28, vf31, vf16 127 + vu.acc.madd(Mask::xyzw, vu.vf28, vu.vf31, vu.vf16.w()); + lq_buffer(Mask::xyzw, vu.vf27, vu.vi02 + 12); + // lq.xyzw vf22, 13(vi02) | mulax.xyzw ACC, vf24, vf16 128 + vu.acc.mula(Mask::xyzw, vu.vf24, vu.vf16.x()); + lq_buffer(Mask::xyzw, vu.vf22, vu.vi02 + 13); + // lq.xyzw vf23, 14(vi02) | madday.xyzw ACC, vf25, vf16 129 + vu.acc.madda(Mask::xyzw, vu.vf25, vu.vf16.y()); + lq_buffer(Mask::xyzw, vu.vf23, vu.vi02 + 14); + // lq.xyzw vf18, 15(vi02) | maddaz.xyzw ACC, vf26, vf16 130 + vu.acc.madda(Mask::xyzw, vu.vf26, vu.vf16.z()); + lq_buffer(Mask::xyzw, vu.vf18, vu.vi02 + 15); + // lq.xyzw vf19, 16(vi02) | maddw.xyzw vf20, vf27, vf16 131 + vu.acc.madd(Mask::xyzw, vu.vf20, vu.vf27, vu.vf16.w()); + lq_buffer(Mask::xyzw, vu.vf19, vu.vi02 + 16); + // iaddi vi05, vi05, -0x1 | mulax.xyzw ACC, vf08, vf28 132 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf28.x()); + vu.vi05 = vu.vi05 + -1; + // nop | madday.xyzw ACC, vf09, vf28 133 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf28.y()); + // nop | maddaz.xyzw ACC, vf10, vf28 134 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf28.z()); + // nop | maddw.xyzw vf24, vf11, vf00 135 + vu.acc.madd(Mask::xyzw, vu.vf24, vu.vf11, vu.vf00.w()); + // nop | mulax.xyzw ACC, vf12, vf28 136 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf28.x()); + // nop | madday.xyzw ACC, vf13, vf28 137 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf28.y()); + // nop | maddaz.xyzw ACC, vf14, vf28 138 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf28.z()); + // erleng.xyz P, vf24 | maddw.xyzw vf28, vf15, vf00 139 + vu.acc.madd(Mask::xyzw, vu.vf28, vu.vf15, vu.vf00.w()); + vu.P = erleng(vu.vf24); + // waitp | nop 140 + + // nop | mul.xyzw vf28, vf28, vf01 141 + vu.vf28.mul(Mask::xyzw, vu.vf28, vu.vf01); + // mfp.w vf24, P | mulax.xyzw ACC, vf22, vf16 142 + vu.acc.mula(Mask::xyzw, vu.vf22, vu.vf16.x()); + vu.vf24.mfp(Mask::w, vu.P); + // iaddi vi03, vi03, 0x1 | madday.xyzw ACC, vf23, vf16 143 + vu.acc.madda(Mask::xyzw, vu.vf23, vu.vf16.y()); + vu.vi03 = vu.vi03 + 1; + // nop | maddaz.xyzw ACC, vf18, vf16 144 + vu.acc.madda(Mask::xyzw, vu.vf18, vu.vf16.z()); + // sq.xyzw vf20, 791(vi04) | maddw.xyzw vf22, vf19, vf16 145 + vu.acc.madd(Mask::xyzw, vu.vf22, vu.vf19, vu.vf16.w()); + sq_buffer(Mask::xyzw, vu.vf20, vu.vi04 + 791); + // sq.xyzw vf28, 793(vi04) | mulw.xy vf24, vf24, vf24 146 + vu.vf24.mul(Mask::xy, vu.vf24, vu.vf24.w()); + sq_buffer(Mask::xyzw, vu.vf28, vu.vi04 + 793); + // sq.xyzw vf22, 792(vi04) | mula.xyzw ACC, vf24, vf05 147 + vu.acc.mula(Mask::xyzw, vu.vf24, vu.vf05); + sq_buffer(Mask::xyzw, vu.vf22, vu.vi04 + 792); + // iaddi vi04, vi04, 0x4 | maddw.xyzw vf24, vf06, vf00 148 + vu.acc.madd(Mask::xyzw, vu.vf24, vu.vf06, vu.vf00.w()); + vu.vi04 = vu.vi04 + 4; + // BRANCH! + // ibgtz vi05, L17 | nop 149 + bc = ((s16)vu.vi05) > 0; + // sq.xyzw vf24, 790(vi04) | nop 150 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi04 + 790); + if (bc) { + goto L17; + } + + // ior vi14, vi00, vi00 | nop 151 + vu.vi14 = 0; + // lq.xyzw vf31, 734(vi00) | nop 152 + lq_buffer(Mask::xyzw, vu.vf31, 734); + // ilw.x vi11, 8(vi02) | nop 153 + ilw_buffer(Mask::x, vu.vi11, vu.vi02 + 8); + // ilw.y vi07, 8(vi02) | nop 154 + ilw_buffer(Mask::y, vu.vi07, vu.vi02 + 8); + // iaddi vi15, vi00, 0x1 | nop 155 + vu.vi15 = 1; + // lq.xyzw vf28, 741(vi00) | nop 156 + lq_buffer(Mask::xyzw, vu.vf28, 741); + // lq.xyzw vf29, 742(vi00) | nop 157 + lq_buffer(Mask::xyzw, vu.vf29, 742); + // lq.xyzw vf30, 743(vi00) | nop 158 + lq_buffer(Mask::xyzw, vu.vf30, 743); + // lq.xyzw vf24, 744(vi00) | nop 159 + lq_buffer(Mask::xyzw, vu.vf24, 744); + // lq.xyzw vf25, 745(vi00) | nop 160 + lq_buffer(Mask::xyzw, vu.vf25, 745); + // lq.xyzw vf26, 746(vi00) | nop 161 + lq_buffer(Mask::xyzw, vu.vf26, 746); + // lq.xyzw vf07, 739(vi00) | nop 162 + lq_buffer(Mask::xyzw, vu.vf07, 739); + // sq.xyzw vf28, 579(vi00) | nop 163 + sq_buffer(Mask::xyzw, vu.vf28, 579); + // sq.xyzw vf29, 580(vi00) | nop 164 + sq_buffer(Mask::xyzw, vu.vf29, 580); + // sq.xyzw vf30, 581(vi00) | nop 165 + sq_buffer(Mask::xyzw, vu.vf30, 581); + // sq.xyzw vf24, 582(vi00) | nop 166 + sq_buffer(Mask::xyzw, vu.vf24, 582); + // sq.xyzw vf25, 583(vi00) | nop 167 + sq_buffer(Mask::xyzw, vu.vf25, 583); + // sq.xyzw vf26, 584(vi00) | nop 168 + sq_buffer(Mask::xyzw, vu.vf26, 584); + // sq.xyzw vf28, 656(vi00) | nop 169 + sq_buffer(Mask::xyzw, vu.vf28, 656); + // sq.xyzw vf29, 657(vi00) | nop 170 + sq_buffer(Mask::xyzw, vu.vf29, 657); + // sq.xyzw vf30, 658(vi00) | nop 171 + sq_buffer(Mask::xyzw, vu.vf30, 658); + // sq.xyzw vf24, 659(vi00) | nop 172 + sq_buffer(Mask::xyzw, vu.vf24, 659); + // sq.xyzw vf25, 660(vi00) | nop 173 + sq_buffer(Mask::xyzw, vu.vf25, 660); + // sq.xyzw vf26, 661(vi00) | nop 174 + sq_buffer(Mask::xyzw, vu.vf26, 661); + // iaddi vi11, vi11, -0x2 | nop 175 + vu.vi11 = vu.vi11 + -2; +L18: + // iand vi01, vi07, vi15 | nop 176 + vu.vi01 = vu.vi07 & vu.vi15; + // iaddi vi11, vi11, -0x2 | nop 177 + vu.vi11 = vu.vi11 + -2; + // BRANCH! + // ibne vi00, vi01, L19 | nop 178 + bc = (vu.vi01 != 0); + // iadd vi15, vi15, vi15 | nop 179 + vu.vi15 = vu.vi15 + vu.vi15; + if (bc) { + goto L19; + } + + // iaddi vi08, vi10, 0x7 | nop 180 + vu.vi08 = vu.vi10 + 7; + // iaddi vi03, vi10, 0x7 | nop 181 + vu.vi03 = vu.vi10 + 7; + // iaddi vi05, vi00, 0x4 | nop 182 + vu.vi05 = 4; + // lq.xyzw vf20, 791(vi14) | nop 183 + lq_buffer(Mask::xyzw, vu.vf20, vu.vi14 + 791); + // lq.xyzw vf22, 792(vi14) | nop 184 + lq_buffer(Mask::xyzw, vu.vf22, vu.vi14 + 792); + // lq.xyzw vf28, 793(vi14) | nop 185 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi14 + 793); + // lq.xyzw vf21, 795(vi14) | nop 186 + lq_buffer(Mask::xyzw, vu.vf21, vu.vi14 + 795); + // lq.xyzw vf23, 796(vi14) | nop 187 + lq_buffer(Mask::xyzw, vu.vf23, vu.vi14 + 796); + // lq.xyzw vf29, 797(vi14) | nop 188 + lq_buffer(Mask::xyzw, vu.vf29, vu.vi14 + 797); + // sq.xyzw vf20, 0(vi08) | nop 189 + sq_buffer(Mask::xyzw, vu.vf20, vu.vi08); + // sq.xyzw vf22, 1(vi08) | nop 190 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 1); + // sq.xyzw vf28, 2(vi08) | nop 191 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 2); + // sq.xyzw vf21, 3(vi08) | nop 192 + sq_buffer(Mask::xyzw, vu.vf21, vu.vi08 + 3); + // sq.xyzw vf23, 4(vi08) | nop 193 + sq_buffer(Mask::xyzw, vu.vf23, vu.vi08 + 4); + // sq.xyzw vf29, 5(vi08) | nop 194 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi08 + 5); + // sq.xyzw vf20, 12(vi08) | nop 195 + sq_buffer(Mask::xyzw, vu.vf20, vu.vi08 + 12); + // sq.xyzw vf22, 13(vi08) | nop 196 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 13); + // sq.xyzw vf28, 14(vi08) | nop 197 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 14); + // lq.xyzw vf20, 803(vi14) | nop 198 + lq_buffer(Mask::xyzw, vu.vf20, vu.vi14 + 803); + // lq.xyzw vf22, 804(vi14) | nop 199 + lq_buffer(Mask::xyzw, vu.vf22, vu.vi14 + 804); + // lq.xyzw vf28, 805(vi14) | nop 200 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi14 + 805); + // lq.xyzw vf21, 799(vi14) | nop 201 + lq_buffer(Mask::xyzw, vu.vf21, vu.vi14 + 799); + // lq.xyzw vf23, 800(vi14) | nop 202 + lq_buffer(Mask::xyzw, vu.vf23, vu.vi14 + 800); + // lq.xyzw vf29, 801(vi14) | nop 203 + lq_buffer(Mask::xyzw, vu.vf29, vu.vi14 + 801); + // sq.xyzw vf20, 6(vi08) | nop 204 + sq_buffer(Mask::xyzw, vu.vf20, vu.vi08 + 6); + // sq.xyzw vf22, 7(vi08) | nop 205 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 7); + // sq.xyzw vf28, 8(vi08) | nop 206 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 8); + // sq.xyzw vf21, 9(vi08) | nop 207 + sq_buffer(Mask::xyzw, vu.vf21, vu.vi08 + 9); + // sq.xyzw vf23, 10(vi08) | nop 208 + sq_buffer(Mask::xyzw, vu.vf23, vu.vi08 + 10); + // BRANCH! + // bal vi13, L45 | nop 209 + // ASSERT(false); + // sq.xyzw vf29, 11(vi08) | nop 210 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi08 + 11); + // if (bc) { goto L45; } + run_L45_vu2c(); + + // BRANCH! + // ibeq vi00, vi05, L19 | nop 211 + bc = (vu.vi05 == 0); + // iaddiu vi06, vi05, 0x4000 | nop 212 + vu.vi06 = vu.vi05 + 0x4000; /* 16384 */ + if (bc) { + goto L19; + } + + // BRANCH! + // bal vi13, L43 | nop 213 + // ASSERT(false); + // iaddiu vi06, vi06, 0x4000 | nop 214 + vu.vi06 = vu.vi06 + 0x4000; /* 16384 */ + // if (bc) { goto L43; } + run_L43_vu2c(); + +L19: + // BRANCH! + // ibgtz vi11, L18 | nop 215 + bc = ((s16)vu.vi11) > 0; + // iaddi vi14, vi14, 0x8 | nop 216 + vu.vi14 = vu.vi14 + 8; + if (bc) { + goto L18; + } + + // ior vi14, vi00, vi00 | nop 217 + vu.vi14 = 0; + // ilw.x vi11, 8(vi02) | nop 218 + ilw_buffer(Mask::x, vu.vi11, vu.vi02 + 8); + // ilw.y vi07, 8(vi02) | nop 219 + ilw_buffer(Mask::y, vu.vi07, vu.vi02 + 8); + // iaddi vi15, vi00, 0x1 | nop 220 + vu.vi15 = 1; + // lq.xyzw vf07, 740(vi00) | nop 221 + lq_buffer(Mask::xyzw, vu.vf07, 740); + // iaddi vi11, vi11, -0x2 | nop 222 + vu.vi11 = vu.vi11 + -2; +L20: + // iand vi01, vi07, vi15 | nop 223 + vu.vi01 = vu.vi07 & vu.vi15; + // iaddi vi11, vi11, -0x2 | nop 224 + vu.vi11 = vu.vi11 + -2; + // BRANCH! + // ibne vi00, vi01, L21 | nop 225 + bc = (vu.vi01 != 0); + // iadd vi15, vi15, vi15 | nop 226 + vu.vi15 = vu.vi15 + vu.vi15; + if (bc) { + goto L21; + } + + // iaddi vi08, vi10, 0x7 | nop 227 + vu.vi08 = vu.vi10 + 7; + // iaddi vi03, vi10, 0x7 | nop 228 + vu.vi03 = vu.vi10 + 7; + // iaddi vi05, vi00, 0x4 | nop 229 + vu.vi05 = 4; + // lq.xyzw vf24, 794(vi14) | nop 230 + lq_buffer(Mask::xyzw, vu.vf24, vu.vi14 + 794); + // lq.xyzw vf22, 756(vi00) | nop 231 + lq_buffer(Mask::xyzw, vu.vf22, 756); + // lq.xyzw vf28, 793(vi14) | nop 232 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi14 + 793); + // lq.xyzw vf25, 798(vi14) | nop 233 + lq_buffer(Mask::xyzw, vu.vf25, vu.vi14 + 798); + // lq.xyzw vf29, 797(vi14) | nop 234 + lq_buffer(Mask::xyzw, vu.vf29, vu.vi14 + 797); + // sq.xyzw vf24, 0(vi08) | nop 235 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi08); + // sq.xyzw vf22, 1(vi08) | nop 236 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 1); + // sq.xyzw vf28, 2(vi08) | nop 237 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 2); + // sq.xyzw vf25, 3(vi08) | nop 238 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi08 + 3); + // sq.xyzw vf22, 4(vi08) | nop 239 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 4); + // sq.xyzw vf29, 5(vi08) | nop 240 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi08 + 5); + // sq.xyzw vf24, 12(vi08) | nop 241 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi08 + 12); + // sq.xyzw vf22, 13(vi08) | nop 242 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 13); + // sq.xyzw vf28, 14(vi08) | nop 243 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 14); + // lq.xyzw vf24, 806(vi14) | nop 244 + lq_buffer(Mask::xyzw, vu.vf24, vu.vi14 + 806); + // lq.xyzw vf28, 805(vi14) | nop 245 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi14 + 805); + // lq.xyzw vf25, 802(vi14) | nop 246 + lq_buffer(Mask::xyzw, vu.vf25, vu.vi14 + 802); + // lq.xyzw vf29, 801(vi14) | nop 247 + lq_buffer(Mask::xyzw, vu.vf29, vu.vi14 + 801); + // sq.xyzw vf24, 6(vi08) | nop 248 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi08 + 6); + // sq.xyzw vf22, 7(vi08) | nop 249 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 7); + // sq.xyzw vf28, 8(vi08) | nop 250 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 8); + // sq.xyzw vf25, 9(vi08) | nop 251 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi08 + 9); + // sq.xyzw vf22, 10(vi08) | nop 252 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 10); + // BRANCH! + // bal vi13, L45 | nop 253 + // ASSERT(false); + // sq.xyzw vf29, 11(vi08) | nop 254 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi08 + 11); + // if (bc) { goto L45; } + run_L45_vu2c(); + + // lq.xyzw vf28, 749(vi00) | nop 255 + lq_buffer(Mask::xyzw, vu.vf28, 749); + // BRANCH! + // ibeq vi00, vi05, L21 | nop 256 + bc = (vu.vi05 == 0); + // lq.xyzw vf29, 750(vi00) | nop 257 + lq_buffer(Mask::xyzw, vu.vf29, 750); + if (bc) { + goto L21; + } + + // lq.xyzw vf30, 751(vi00) | nop 258 + lq_buffer(Mask::xyzw, vu.vf30, 751); + // lq.xyzw vf24, 752(vi00) | nop 259 + lq_buffer(Mask::xyzw, vu.vf24, 752); + // lq.xyzw vf25, 753(vi00) | nop 260 + lq_buffer(Mask::xyzw, vu.vf25, 753); + // lq.xyzw vf26, 754(vi00) | nop 261 + lq_buffer(Mask::xyzw, vu.vf26, 754); + // sq.xyzw vf28, 0(vi10) | nop 262 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi10); + // sq.xyzw vf29, 1(vi10) | nop 263 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi10 + 1); + // sq.xyzw vf30, 2(vi10) | nop 264 + sq_buffer(Mask::xyzw, vu.vf30, vu.vi10 + 2); + // sq.xyzw vf24, 3(vi10) | nop 265 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi10 + 3); + // sq.xyzw vf25, 4(vi10) | nop 266 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi10 + 4); + // sq.xyzw vf26, 5(vi10) | nop 267 + sq_buffer(Mask::xyzw, vu.vf26, vu.vi10 + 5); + // iaddiu vi06, vi05, 0x4000 | nop 268 + vu.vi06 = vu.vi05 + 0x4000; /* 16384 */ + // BRANCH! + // bal vi13, L43 | nop 269 + // ASSERT(false); + // iaddiu vi06, vi06, 0x4000 | nop 270 + vu.vi06 = vu.vi06 + 0x4000; /* 16384 */ + // if (bc) { goto L43; } + run_L43_vu2c(); + +L21: + // BRANCH! + // ibgtz vi11, L20 | nop 271 + bc = ((s16)vu.vi11) > 0; + // iaddi vi14, vi14, 0x8 | nop 272 + vu.vi14 = vu.vi14 + 8; + if (bc) { + goto L20; + } + + // nop | nop :e 273 + + // nop | nop 274 + + return; +} + void OceanMid::run_call275_vu2c() { bool bc; // fmt::print("call 275\n"); @@ -1096,6 +1613,302 @@ L25: return; } +void OceanMid::run_call275_vu2c_jak2() { + bool bc; + // fmt::print("call 275\n"); + // xtop vi02 | nop 275 + vu.vi02 = xtop(); + // xtop vi03 | nop 276 + vu.vi03 = vu.vi02; // xtop(); + // ior vi04, vi00, vi00 | nop 277 + vu.vi04 = 0; + // iaddi vi08, vi10, 0x7 | nop 278 + vu.vi08 = vu.vi10 + 7; + // ilw.x vi05, 8(vi02) | nop 279 + ilw_buffer(Mask::x, vu.vi05, vu.vi02 + 8); + // lq.xyzw vf08, 0(vi02) | nop 280 + lq_buffer(Mask::xyzw, vu.vf08, vu.vi02); + // lq.xyzw vf09, 1(vi02) | nop 281 + lq_buffer(Mask::xyzw, vu.vf09, vu.vi02 + 1); + // lq.xyzw vf10, 2(vi02) | nop 282 + lq_buffer(Mask::xyzw, vu.vf10, vu.vi02 + 2); + // lq.xyzw vf11, 3(vi02) | nop 283 + lq_buffer(Mask::xyzw, vu.vf11, vu.vi02 + 3); + // lq.xyzw vf12, 4(vi02) | nop 284 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi02 + 4); + // lq.xyzw vf13, 5(vi02) | nop 285 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi02 + 5); + // lq.xyzw vf14, 6(vi02) | nop 286 + lq_buffer(Mask::xyzw, vu.vf14, vu.vi02 + 6); + // lq.xyzw vf15, 7(vi02) | nop 287 + lq_buffer(Mask::xyzw, vu.vf15, vu.vi02 + 7); +L23: + // lq.xyzw vf16, 17(vi03) | nop 288 + lq_buffer(Mask::xyzw, vu.vf16, vu.vi03 + 17); + // lq.xyzw vf28, 765(vi00) | nop 289 + lq_buffer(Mask::xyzw, vu.vf28, 765); + // lq.xyzw vf29, 766(vi00) | nop 290 + lq_buffer(Mask::xyzw, vu.vf29, 766); + // lq.xyzw vf30, 767(vi00) | nop 291 + lq_buffer(Mask::xyzw, vu.vf30, 767); + // lq.xyzw vf31, 768(vi00) | nop 292 + lq_buffer(Mask::xyzw, vu.vf31, 768); + // lq.xyzw vf24, 9(vi02) | mulax.xyzw ACC, vf28, vf16 293 + vu.acc.mula(Mask::xyzw, vu.vf28, vu.vf16.x()); + lq_buffer(Mask::xyzw, vu.vf24, vu.vi02 + 9); + // lq.xyzw vf25, 10(vi02) | madday.xyzw ACC, vf29, vf16 294 + vu.acc.madda(Mask::xyzw, vu.vf29, vu.vf16.y()); + lq_buffer(Mask::xyzw, vu.vf25, vu.vi02 + 10); + // lq.xyzw vf26, 11(vi02) | maddaz.xyzw ACC, vf30, vf16 295 + vu.acc.madda(Mask::xyzw, vu.vf30, vu.vf16.z()); + lq_buffer(Mask::xyzw, vu.vf26, vu.vi02 + 11); + // lq.xyzw vf27, 12(vi02) | maddw.xyzw vf28, vf31, vf16 296 + vu.acc.madd(Mask::xyzw, vu.vf28, vu.vf31, vu.vf16.w()); + lq_buffer(Mask::xyzw, vu.vf27, vu.vi02 + 12); + // lq.xyzw vf22, 13(vi02) | mulax.xyzw ACC, vf24, vf16 297 + vu.acc.mula(Mask::xyzw, vu.vf24, vu.vf16.x()); + lq_buffer(Mask::xyzw, vu.vf22, vu.vi02 + 13); + // lq.xyzw vf23, 14(vi02) | madday.xyzw ACC, vf25, vf16 298 + vu.acc.madda(Mask::xyzw, vu.vf25, vu.vf16.y()); + lq_buffer(Mask::xyzw, vu.vf23, vu.vi02 + 14); + // lq.xyzw vf18, 15(vi02) | maddaz.xyzw ACC, vf26, vf16 299 + vu.acc.madda(Mask::xyzw, vu.vf26, vu.vf16.z()); + lq_buffer(Mask::xyzw, vu.vf18, vu.vi02 + 15); + // lq.xyzw vf19, 16(vi02) | maddw.xyzw vf20, vf27, vf16 300 + vu.acc.madd(Mask::xyzw, vu.vf20, vu.vf27, vu.vf16.w()); + lq_buffer(Mask::xyzw, vu.vf19, vu.vi02 + 16); + // iaddi vi05, vi05, -0x1 | mulax.xyzw ACC, vf08, vf28 301 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf28.x()); + vu.vi05 = vu.vi05 + -1; + // nop | madday.xyzw ACC, vf09, vf28 302 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf28.y()); + // nop | maddaz.xyzw ACC, vf10, vf28 303 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf28.z()); + // nop | maddw.xyzw vf24, vf11, vf00 304 + vu.acc.madd(Mask::xyzw, vu.vf24, vu.vf11, vu.vf00.w()); + // nop | mulax.xyzw ACC, vf12, vf28 305 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf28.x()); + // nop | madday.xyzw ACC, vf13, vf28 306 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf28.y()); + // nop | maddaz.xyzw ACC, vf14, vf28 307 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf28.z()); + // erleng.xyz P, vf24 | maddw.xyzw vf28, vf15, vf00 308 + vu.acc.madd(Mask::xyzw, vu.vf28, vu.vf15, vu.vf00.w()); + vu.P = erleng(vu.vf24); + // waitp | nop 309 + + // nop | mul.xyzw vf28, vf28, vf01 310 + vu.vf28.mul(Mask::xyzw, vu.vf28, vu.vf01); + // mfp.w vf24, P | mulax.xyzw ACC, vf22, vf16 311 + vu.acc.mula(Mask::xyzw, vu.vf22, vu.vf16.x()); + vu.vf24.mfp(Mask::w, vu.P); + // iaddi vi03, vi03, 0x1 | madday.xyzw ACC, vf23, vf16 312 + vu.acc.madda(Mask::xyzw, vu.vf23, vu.vf16.y()); + vu.vi03 = vu.vi03 + 1; + // nop | maddaz.xyzw ACC, vf18, vf16 313 + vu.acc.madda(Mask::xyzw, vu.vf18, vu.vf16.z()); + // sq.xyzw vf20, 0(vi08) | maddw.xyzw vf22, vf19, vf16 314 + vu.acc.madd(Mask::xyzw, vu.vf22, vu.vf19, vu.vf16.w()); + sq_buffer(Mask::xyzw, vu.vf20, vu.vi08); + // sq.xyzw vf28, 2(vi08) | mulw.xy vf24, vf24, vf24 315 + vu.vf24.mul(Mask::xy, vu.vf24, vu.vf24.w()); + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 2); + // sq.xyzw vf28, 792(vi04) | nop 316 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi04 + 792); + // sq.xyzw vf22, 1(vi08) | mula.xyzw ACC, vf24, vf05 317 + vu.acc.mula(Mask::xyzw, vu.vf24, vu.vf05); + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 1); + // iaddi vi04, vi04, 0x2 | maddw.xyzw vf24, vf06, vf00 318 + vu.acc.madd(Mask::xyzw, vu.vf24, vu.vf06, vu.vf00.w()); + vu.vi04 = vu.vi04 + 2; + // iaddi vi08, vi08, 0x3 | nop 319 + vu.vi08 = vu.vi08 + 3; + // BRANCH! + // ibgtz vi05, L23 | nop 320 + bc = ((s16)vu.vi05) > 0; + // sq.xyzw vf24, 789(vi04) | nop 321 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi04 + 789); + if (bc) { + goto L23; + } + + // lq.xyzw vf31, 734(vi00) | nop 322 + lq_buffer(Mask::xyzw, vu.vf31, 734); + // ilw.x vi05, 8(vi02) | nop 323 + ilw_buffer(Mask::x, vu.vi05, vu.vi02 + 8); + // fmt::print("loaded vi05: {}\n", vu.vi05); + // lq.xyzw vf20, 7(vi10) | nop 324 + lq_buffer(Mask::xyzw, vu.vf20, vu.vi10 + 7); + // lq.xyzw vf22, 8(vi10) | nop 325 + lq_buffer(Mask::xyzw, vu.vf22, vu.vi10 + 8); + // lq.xyzw vf28, 9(vi10) | nop 326 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi10 + 9); + // sq.xyzw vf20, 0(vi08) | nop 327 + sq_buffer(Mask::xyzw, vu.vf20, vu.vi08); + // sq.xyzw vf22, 1(vi08) | nop 328 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 1); + // sq.xyzw vf28, 2(vi08) | nop 329 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 2); + // iaddi vi08, vi10, 0x7 | nop 330 + vu.vi08 = vu.vi10 + 7; + // BRANCH! + // bal vi13, L45 | nop 331 + // ASSERT(false); + // iaddi vi03, vi10, 0x7 | nop 332 + vu.vi03 = vu.vi10 + 7; + // if (bc) { goto L45; } + run_L45_vu2c(); + + // lq.xyzw vf28, 741(vi00) | nop 333 + lq_buffer(Mask::xyzw, vu.vf28, 741); + // BRANCH! + // ibeq vi00, vi05, L25 | nop 334 + // fmt::print("vu.vi05 = {}\n", vu.vi05); + bc = (vu.vi05 == 0); + // lq.xyzw vf29, 742(vi00) | nop 335 + lq_buffer(Mask::xyzw, vu.vf29, 742); + if (bc) { + goto L25; + } + + // lq.xyzw vf30, 743(vi00) | nop 336 + lq_buffer(Mask::xyzw, vu.vf30, 743); + // lq.xyzw vf24, 744(vi00) | nop 337 + lq_buffer(Mask::xyzw, vu.vf24, 744); + // lq.xyzw vf25, 745(vi00) | nop 338 + lq_buffer(Mask::xyzw, vu.vf25, 745); + // lq.xyzw vf26, 746(vi00) | nop 339 + lq_buffer(Mask::xyzw, vu.vf26, 746); + // lq.xyzw vf07, 739(vi00) | nop 340 + lq_buffer(Mask::xyzw, vu.vf07, 739); + // sq.xyzw vf28, 0(vi10) | nop 341 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi10); + // sq.xyzw vf29, 1(vi10) | nop 342 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi10 + 1); + // sq.xyzw vf30, 2(vi10) | nop 343 + sq_buffer(Mask::xyzw, vu.vf30, vu.vi10 + 2); + // sq.xyzw vf24, 3(vi10) | nop 344 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi10 + 3); + // sq.xyzw vf25, 4(vi10) | nop 345 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi10 + 4); + // sq.xyzw vf26, 5(vi10) | nop 346 + sq_buffer(Mask::xyzw, vu.vf26, vu.vi10 + 5); + // iaddiu vi06, vi05, 0x4000 | nop 347 + vu.vi06 = vu.vi05 + 0x4000; /* 16384 */ + // BRANCH! + // bal vi13, L43 | nop 348 + // ASSERT(false); + // iaddiu vi06, vi06, 0x4000 | nop 349 + vu.vi06 = vu.vi06 + 0x4000; /* 16384 */ + // if (bc) { + // goto L43; + // } + run_L43_vu2c(); + + // ior vi03, vi00, vi00 | nop 350 + vu.vi03 = 0; + // lq.xyzw vf22, 756(vi00) | nop 351 + lq_buffer(Mask::xyzw, vu.vf22, 756); + // ilw.x vi05, 8(vi02) | nop 352 + ilw_buffer(Mask::x, vu.vi05, vu.vi02 + 8); + // iaddi vi08, vi10, 0x7 | nop 353 + vu.vi08 = vu.vi10 + 7; +L24: + // lq.xyzw vf28, 792(vi03) | nop 354 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi03 + 792); + // lq.xyzw vf24, 791(vi03) | nop 355 + lq_buffer(Mask::xyzw, vu.vf24, vu.vi03 + 791); + // iaddi vi03, vi03, 0x2 | nop 356 + vu.vi03 = vu.vi03 + 2; + // iaddi vi05, vi05, -0x1 | nop 357 + vu.vi05 = vu.vi05 + -1; + // sq.xyzw vf22, 1(vi08) | nop 358 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 1); + // sq.xyzw vf28, 2(vi08) | nop 359 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 2); + // sq.xyzw vf24, 0(vi08) | nop 360 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi08); + // BRANCH! + // ibgtz vi05, L24 | nop 361 + bc = ((s16)vu.vi05) > 0; + // iaddi vi08, vi08, 0x3 | nop 362 + vu.vi08 = vu.vi08 + 3; + if (bc) { + goto L24; + } + + // ilw.x vi05, 8(vi02) | nop 363 + ilw_buffer(Mask::x, vu.vi05, vu.vi02 + 8); + // lq.xyzw vf20, 7(vi10) | nop 364 + lq_buffer(Mask::xyzw, vu.vf20, vu.vi10 + 7); + // lq.xyzw vf22, 8(vi10) | nop 365 + lq_buffer(Mask::xyzw, vu.vf22, vu.vi10 + 8); + // lq.xyzw vf24, 9(vi10) | nop 366 + lq_buffer(Mask::xyzw, vu.vf24, vu.vi10 + 9); + // sq.xyzw vf24, 0(vi08) | nop 367 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi08); + // sq.xyzw vf22, 1(vi08) | nop 368 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 1); + // sq.xyzw vf28, 2(vi08) | nop 369 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 2); + // iaddi vi08, vi10, 0x7 | nop 370 + vu.vi08 = vu.vi10 + 7; + // BRANCH! + // bal vi13, L45 | nop 371 + // ASSERT(false); + // iaddi vi03, vi10, 0x7 | nop 372 + vu.vi03 = vu.vi10 + 7; + // if (bc) { + // goto L45; + // } + run_L45_vu2c(); + + // lq.xyzw vf28, 749(vi00) | nop 373 + lq_buffer(Mask::xyzw, vu.vf28, 749); + // lq.xyzw vf29, 750(vi00) | nop 374 + lq_buffer(Mask::xyzw, vu.vf29, 750); + // lq.xyzw vf30, 751(vi00) | nop 375 + lq_buffer(Mask::xyzw, vu.vf30, 751); + // lq.xyzw vf24, 752(vi00) | nop 376 + lq_buffer(Mask::xyzw, vu.vf24, 752); + // lq.xyzw vf25, 753(vi00) | nop 377 + lq_buffer(Mask::xyzw, vu.vf25, 753); + // lq.xyzw vf26, 754(vi00) | nop 378 + lq_buffer(Mask::xyzw, vu.vf26, 754); + // lq.xyzw vf07, 740(vi00) | nop 379 + lq_buffer(Mask::xyzw, vu.vf07, 740); + // sq.xyzw vf28, 0(vi10) | nop 380 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi10); + // sq.xyzw vf29, 1(vi10) | nop 381 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi10 + 1); + // sq.xyzw vf30, 2(vi10) | nop 382 + sq_buffer(Mask::xyzw, vu.vf30, vu.vi10 + 2); + // sq.xyzw vf24, 3(vi10) | nop 383 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi10 + 3); + // sq.xyzw vf25, 4(vi10) | nop 384 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi10 + 4); + // sq.xyzw vf26, 5(vi10) | nop 385 + sq_buffer(Mask::xyzw, vu.vf26, vu.vi10 + 5); + // iaddiu vi06, vi05, 0x4000 | nop 386 + vu.vi06 = vu.vi05 + 0x4000; /* 16384 */ + // BRANCH! + // bal vi13, L43 | nop 387 + // ASSERT(false); + // iaddiu vi06, vi06, 0x4000 | nop 388 + vu.vi06 = vu.vi06 + 0x4000; /* 16384 */ + // if (bc) { + // goto L43; + // } + run_L43_vu2c(); + +L25: + // nop | nop :e 389 + + // nop | nop 390 + + return; +} + void OceanMid::run_L26_vu2c() { bool bc = false; u32 cf = 0; @@ -1833,6 +2646,518 @@ L37: // nop | nop 613 } +void OceanMid::run_L32_vu2c_jak2() { + bool bc = false; + u32 cf = 0; + // ilw.x vi05, 757(vi07) | nop 459 + ilw_buffer(Mask::x, vu.vi05, vu.vi07 + 757); + // ilw.y vi04, 757(vi07) | nop 460 + ilw_buffer(Mask::y, vu.vi04, vu.vi07 + 757); + // iaddi vi03, vi00, 0x0 | nop 461 + vu.vi03 = 0; + // iadd vi04, vi04, vi02 | nop 462 + vu.vi04 = vu.vi04 + vu.vi02; + // iaddi vi06, vi00, 0x8 | nop 463 + vu.vi06 = 8; + // lq.xyzw vf28, 236(vi05) | nop 464 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi05 + 236); + // lq.xyzw vf29, 245(vi05) | mulax.xyzw ACC, vf12, vf28 465 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf28.x()); + lq_buffer(Mask::xyzw, vu.vf29, vu.vi05 + 245); + // iaddi vi05, vi05, 0x1 | madday.xyzw ACC, vf13, vf28 466 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf28.y()); + vu.vi05 = vu.vi05 + 1; + // fcset 0x0 | maddaz.xyzw ACC, vf14, vf28 467 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf28.z()); + cf = 0x0; + + // nop | maddw.xyzw vf30, vf15, vf00 468 + vu.acc.madd(Mask::xyzw, vu.vf30, vu.vf15, vu.vf00.w()); + // nop | mulax.xyzw ACC, vf08, vf28 469 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf28.x()); + // nop | madday.xyzw ACC, vf09, vf28 470 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf28.y()); + // nop | maddaz.xyzw ACC, vf10, vf28 471 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf28.z()); + // nop | maddw.xyzw vf26, vf11, vf00 472 + vu.acc.madd(Mask::xyzw, vu.vf26, vu.vf11, vu.vf00.w()); + // lq.xyzw vf20, 317(vi03) | mulax.xyzw ACC, vf12, vf29 473 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf29.x()); + lq_buffer(Mask::xyzw, vu.vf20, vu.vi03 + 317); + // lq.xyzw vf22, 8(vi04) | madday.xyzw ACC, vf13, vf29 474 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf29.y()); + lq_buffer(Mask::xyzw, vu.vf22, vu.vi04 + 8); + // div Q, vf03.x, vf30.w | maddaz.xyzw ACC, vf14, vf29 475 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf29.z()); + vu.Q = vu.vf03.x() / vu.vf30.w(); + // erleng.xyz P, vf26 | maddw.xyzw vf31, vf15, vf00 476 + vu.acc.madd(Mask::xyzw, vu.vf31, vu.vf15, vu.vf00.w()); + vu.P = erleng(vu.vf26); + // nop | mulax.xyzw ACC, vf08, vf29 477 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf29.x()); + // nop | madday.xyzw ACC, vf09, vf29 478 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf29.y()); + // lq.xyzw vf28, 236(vi05) | maddaz.xyzw ACC, vf10, vf29 479 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf29.z()); + lq_buffer(Mask::xyzw, vu.vf28, vu.vi05 + 236); + // lq.xyzw vf29, 245(vi05) | maddw.xyzw vf27, vf11, vf00 480 + vu.acc.madd(Mask::xyzw, vu.vf27, vu.vf11, vu.vf00.w()); + lq_buffer(Mask::xyzw, vu.vf29, vu.vi05 + 245); + // nop | mul.xyzw vf18, vf30, vf01 481 + vu.vf18.mul(Mask::xyzw, vu.vf30, vu.vf01); + // nop | mul.xyzw vf19, vf31, vf01 482 + vu.vf19.mul(Mask::xyzw, vu.vf31, vu.vf01); + // nop | mulaw.w ACC, vf30, vf00 483 + vu.acc.mula(Mask::w, vu.vf30, vu.vf00.w()); + // nop | mula.xyz ACC, vf30, Q 484 + vu.acc.mula(Mask::xyz, vu.vf30, vu.Q); + // nop | maddw.xyzw vf16, vf02, vf00 485 + vu.acc.madd(Mask::xyzw, vu.vf16, vu.vf02, vu.vf00.w()); + // div Q, vf03.x, vf31.w | mul.xyzw vf20, vf20, Q 486 + vu.vf20.mul(Mask::xyzw, vu.vf20, vu.Q); + vu.Q = vu.vf03.x() / vu.vf31.w(); + // waitp | maxy.w vf16, vf16, vf03 488 + vu.vf16.max(Mask::w, vu.vf16, vu.vf03.y()); // fog amx + // mfp.w vf26, P | mulax.xyzw ACC, vf12, vf28 489 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf28.x()); + vu.vf26.mfp(Mask::w, vu.P); + // erleng.xyz P, vf27 | madday.xyzw ACC, vf13, vf28 490 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf28.y()); + vu.P = erleng(vu.vf27); + // iaddi vi12, vi00, 0x1 | maddaz.xyzw ACC, vf14, vf28 491 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf28.z()); + vu.vi12 = 1; + // iaddi vi01, vi00, 0x0 | maddw.xyzw vf30, vf15, vf00 492 + vu.acc.madd(Mask::xyzw, vu.vf30, vu.vf15, vu.vf00.w()); + vu.vi01 = 0; + // iaddi vi13, vi00, 0x0 | mulw.xy vf24, vf26, vf26 493 + vu.vf24.mul(Mask::xy, vu.vf26, vu.vf26.w()); + vu.vi13 = 0; + // iaddi vi11, vi00, 0x0 | miniz.w vf16, vf16, vf03 494 + vu.vf16.mini(Mask::w, vu.vf16, vu.vf03.z()); + vu.vi11 = 0; + // iaddi vi14, vi00, 0x0 | mulax.xyzw ACC, vf08, vf28 495 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf28.x()); + vu.vi14 = 0; + // nop | madday.xyzw ACC, vf09, vf28 496 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf28.y()); + // nop | maddaz.xyzw ACC, vf10, vf28 497 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf28.z()); + // nop | maddw.xyzw vf26, vf11, vf00 498 + vu.acc.madd(Mask::xyzw, vu.vf26, vu.vf11, vu.vf00.w()); + // nop | clipw.xyz vf18, vf18 499 + cf = clip(vu.vf18, vu.vf18.w(), cf); + // waitp | clipw.xyz vf19, vf19 500 + cf = clip(vu.vf19, vu.vf19.w(), cf); + // BRANCH! + // b L35 | mula.xyzw ACC, vf24, vf05 501 + vu.acc.mula(Mask::xyzw, vu.vf24, vu.vf05); + bc = true; + // iaddi vi05, vi05, 0x1 | maddw.xyzw vf24, vf06, vf00 502 + vu.acc.madd(Mask::xyzw, vu.vf24, vu.vf06, vu.vf00.w()); + vu.vi05 = vu.vi05 + 1; + if (bc) { + goto L35; + } + +L33: + // BRANCH! + // ibeq vi00, vi01, L34 | mulaw.w ACC, vf30, vf00 504 + vu.acc.mula(Mask::w, vu.vf30, vu.vf00.w()); + bc = (vu.vi01 == 0); + // lq.xyzw vf20, 317(vi03) | mula.xyz ACC, vf30, Q 505 + vu.acc.mula(Mask::xyz, vu.vf30, vu.Q); + lq_buffer(Mask::xyzw, vu.vf20, vu.vi03 + 317); + if (bc) { + goto L34; + } + + // BRANCH! + // ibne vi00, vi13, L34 | addw.w vf17, vf17, vf03 506 + vu.vf17.add(Mask::w, vu.vf17, vu.vf03.w()); + bc = (vu.vi13 != 0); + // fcor vi01, 0x7df7ff | nop 507 + fcor(vu.vi01, 0x7df7ff, cf); + + if (bc) { + goto L34; + } + + // isw.x vi12, 775(vi14) | nop 508 + isw_buffer(Mask::x, vu.vi12, vu.vi14 + 775); + // BRANCH! + // ibne vi00, vi01, L34 | nop 509 + bc = (vu.vi01 != 0); + // fcor vi01, 0xdf7dff | nop 510 + fcor(vu.vi01, 0xdf7dff, cf); + + if (bc) { + goto L34; + } + + // isw.y vi05, 775(vi14) | nop 511 + isw_buffer(Mask::y, vu.vi05, vu.vi14 + 775); + // BRANCH! + // ibne vi00, vi01, L34 | nop 512 + bc = (vu.vi01 != 0); + // fcor vi01, 0xefbeff | nop 513 + fcor(vu.vi01, 0xefbeff, cf); + if (bc) { + goto L34; + } + + // ilw.z vi11, 757(vi07) | nop 514 + ilw_buffer(Mask::z, vu.vi11, vu.vi07 + 757); + // BRANCH! + // ibne vi00, vi01, L34 | nop 515 + bc = (vu.vi01 != 0); + // fcor vi01, 0xf7df7f | nop 516 + fcor(vu.vi01, 0xf7df7f, cf); + + if (bc) { + goto L34; + } + + // isw.z vi04, 775(vi14) | nop 517 + isw_buffer(Mask::z, vu.vi04, vu.vi14 + 775); + // BRANCH! + // ibne vi00, vi01, L34 | nop 518 + bc = (vu.vi01 != 0); + // fcor vi01, 0xfbefbf | nop 519 + fcor(vu.vi01, 0xfbefbf, cf); + + if (bc) { + goto L34; + } + + // isub vi11, vi05, vi11 | nop 520 + vu.vi11 = vu.vi05 - vu.vi11; + // BRANCH! + // ibne vi00, vi01, L34 | nop 521 + bc = (vu.vi01 != 0); + // nop | nop 522 + + if (bc) { + goto L34; + } + + // BRANCH! + // ibltz vi11, L34 | nop 523 + bc = ((s16)vu.vi11) < 0; + // nop | nop 524 + + if (bc) { + goto L34; + } + + // iaddi vi14, vi14, 0x1 | nop 525 + vu.vi14 = vu.vi14 + 1; +L34: + // lq.xyzw vf22, 8(vi04) | maddw.xyzw vf16, vf02, vf00 526 + vu.acc.madd(Mask::xyzw, vu.vf16, vu.vf02, vu.vf00.w()); + lq_buffer(Mask::xyzw, vu.vf22, vu.vi04 + 8); + // div Q, vf03.x, vf31.w | mul.xyzw vf20, vf20, Q 527 + vu.vf20.mul(Mask::xyzw, vu.vf20, vu.Q); + vu.Q = vu.vf03.x() / vu.vf31.w(); + // fcand vi01, 0x3ffff | mul.xyzw vf19, vf31, vf01 528 + vu.vf19.mul(Mask::xyzw, vu.vf31, vu.vf01); + fcand(vu.vi01, 0x3ffff, cf); + + // waitp | ftoi4.xyzw vf17, vf17 529 + vu.vf17.ftoi4(Mask::xyzw, vu.vf17); + // vu.vf17.fill(0); + // mfp.w vf26, P | maxy.w vf16, vf16, vf03 530 + vu.vf16.max(Mask::w, vu.vf16, vu.vf03.y()); + vu.vf26.mfp(Mask::w, vu.P); + // erleng.xyz P, vf27 | clipw.xyz vf19, vf19 531 + cf = clip(vu.vf19, vu.vf19.w(), cf); + vu.P = erleng(vu.vf27); + // sq.xyzw vf21, 3(vi08) | mulz.xyzw vf25, vf25, vf21 533 + vu.vf25.z() = 1; // TODO hack + vu.vf25.mul(Mask::xyzw, vu.vf25, vu.vf21.z()); + sq_buffer(Mask::xyzw, vu.vf21, vu.vi08 + 3); + // sq.xyzw vf23, 4(vi08) | mulw.xy vf24, vf26, vf26 534 + vu.vf24.mul(Mask::xy, vu.vf26, vu.vf26.w()); + sq_buffer(Mask::xyzw, vu.vf23, vu.vi08 + 4); + // sq.xyzw vf17, 5(vi08) | mulax.xyzw ACC, vf12, vf28 535 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf28.x()); + sq_buffer(Mask::xyzw, vu.vf17, vu.vi08 + 5); + // sq.xyzw vf17, 66(vi08) | madday.xyzw ACC, vf13, vf28 536 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf28.y()); + sq_buffer(Mask::xyzw, vu.vf17, vu.vi08 + 66); + // sq.xyzw vf25, 64(vi08) | maddaz.xyzw ACC, vf14, vf28 537 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf28.z()); + sq_buffer(Mask::xyzw, vu.vf25, vu.vi08 + 64); + // iaddi vi08, vi08, 0x6 | maddw.xyzw vf30, vf15, vf00 538 + vu.acc.madd(Mask::xyzw, vu.vf30, vu.vf15, vu.vf00.w()); + vu.vi08 = vu.vi08 + 6; + // iand vi13, vi10, vi12 | mulax.xyzw ACC, vf08, vf28 539 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf28.x()); + vu.vi13 = vu.vi10 & vu.vi12; + // iadd vi12, vi12, vi12 | madday.xyzw ACC, vf09, vf28 540 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf28.y()); + vu.vi12 = vu.vi12 + vu.vi12; + // ior vi01, vi01, vi13 | maddaz.xyzw ACC, vf10, vf28 541 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf28.z()); + vu.vi01 = vu.vi01 | vu.vi13; + // nop | maddw.xyzw vf26, vf11, vf00 542 + vu.acc.madd(Mask::xyzw, vu.vf26, vu.vf11, vu.vf00.w()); + // lq.xyzw vf29, 245(vi05) | miniz.w vf16, vf16, vf03 543 + vu.vf16.mini(Mask::w, vu.vf16, vu.vf03.z()); + lq_buffer(Mask::xyzw, vu.vf29, vu.vi05 + 245); + // iaddi vi05, vi05, 0x1 | mula.xyzw ACC, vf24, vf05 544 + vu.acc.mula(Mask::xyzw, vu.vf24, vu.vf05); + vu.vi05 = vu.vi05 + 1; + // nop | maddw.xyzw vf24, vf06, vf00 545 + vu.acc.madd(Mask::xyzw, vu.vf24, vu.vf06, vu.vf00.w()); +L35: + // BRANCH! + // ibeq vi00, vi01, L36 | mulaw.w ACC, vf31, vf00 546 + vu.acc.mula(Mask::w, vu.vf31, vu.vf00.w()); + bc = (vu.vi01 == 0); + // lq.xyzw vf21, 318(vi03) | mula.xyz ACC, vf31, Q 547 + vu.acc.mula(Mask::xyz, vu.vf31, vu.Q); + lq_buffer(Mask::xyzw, vu.vf21, vu.vi03 + 318); + if (bc) { + goto L36; + } + + // BRANCH! + // ibne vi00, vi13, L36 | addw.w vf16, vf16, vf03 548 + vu.vf16.add(Mask::w, vu.vf16, vu.vf03.w()); + bc = (vu.vi13 != 0); + // fcor vi01, 0x7df7ff | nop 549 + fcor(vu.vi01, 0x7df7ff, cf); + + if (bc) { + goto L36; + } + + // isw.x vi00, 775(vi14) | nop 550 + isw_buffer(Mask::x, 0, vu.vi14 + 775); + // BRANCH! + // ibne vi00, vi01, L36 | nop 551 + bc = (vu.vi01 != 0); + // fcor vi01, 0xdf7dff | nop 552 + fcor(vu.vi01, 0xdf7dff, cf); + + if (bc) { + goto L36; + } + + // isw.y vi05, 775(vi14) | nop 553 + isw_buffer(Mask::y, vu.vi05, vu.vi14 + 775); + // BRANCH! + // ibne vi00, vi01, L36 | nop 554 + bc = (vu.vi01 != 0); + // fcor vi01, 0xefbeff | nop 555 + fcor(vu.vi01, 0xefbeff, cf); + + if (bc) { + goto L36; + } + + // isw.z vi04, 775(vi14) | nop 556 + isw_buffer(Mask::z, vu.vi04, vu.vi14 + 775); + // BRANCH! + // ibne vi00, vi01, L36 | nop 557 + bc = (vu.vi01 != 0); + // fcor vi01, 0xf7df7f | nop 558 + fcor(vu.vi01, 0xf7df7f, cf); + + if (bc) { + goto L36; + } + + // nop | nop 559 + + // BRANCH! + // ibne vi00, vi01, L36 | nop 560 + bc = (vu.vi01 != 0); + // fcor vi01, 0xfbefbf | nop 561 + fcor(vu.vi01, 0xfbefbf, cf); + + if (bc) { + goto L36; + } + + // nop | nop 562 + + // BRANCH! + // ibne vi00, vi01, L36 | nop 563 + bc = (vu.vi01 != 0); + // nop | nop 564 + + if (bc) { + goto L36; + } + + // iaddi vi14, vi14, 0x1 | nop 565 + vu.vi14 = vu.vi14 + 1; +L36: + // lq.xyzw vf23, 20(vi04) | maddw.xyzw vf17, vf02, vf00 566 + vu.acc.madd(Mask::xyzw, vu.vf17, vu.vf02, vu.vf00.w()); + lq_buffer(Mask::xyzw, vu.vf23, vu.vi04 + 20); + // div Q, vf03.x, vf30.w | mul.xyzw vf21, vf21, Q 567 + vu.vf21.mul(Mask::xyzw, vu.vf21, vu.Q); + vu.Q = vu.vf03.x() / vu.vf30.w(); + // fcand vi01, 0x3ffff | mul.xyzw vf18, vf30, vf01 568 + vu.vf18.mul(Mask::xyzw, vu.vf30, vu.vf01); + fcand(vu.vi01, 0x3ffff, cf); + + // waitp | ftoi4.xyzw vf16, vf16 569 + vu.vf16.ftoi4(Mask::xyzw, vu.vf16); // possible 1 + // vu.vf16.fill(0); + // mfp.w vf27, P | maxy.w vf17, vf17, vf03 570 + vu.vf17.max(Mask::w, vu.vf17, vu.vf03.y()); + vu.vf27.mfp(Mask::w, vu.P); + // erleng.xyz P, vf26 | clipw.xyz vf18, vf18 571 + cf = clip(vu.vf18, vu.vf18.w(), cf); + vu.P = erleng(vu.vf26); + // sq.xyzw vf20, 0(vi08) | mulz.xyzw vf24, vf24, vf20 573 + // todo hack + vu.vf24.z() = 1; + vu.vf24.mul(Mask::xyzw, vu.vf24, vu.vf20.z()); + sq_buffer(Mask::xyzw, vu.vf20, vu.vi08); + // sq.xyzw vf22, 1(vi08) | mulw.xy vf25, vf27, vf27 574 + vu.vf25.mul(Mask::xy, vu.vf27, vu.vf27.w()); + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 1); + // sq.xyzw vf16, 2(vi08) | mulax.xyzw ACC, vf12, vf29 575 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf29.x()); + sq_buffer(Mask::xyzw, vu.vf16, vu.vi08 + 2); + // sq.xyzw vf16, 63(vi08) | madday.xyzw ACC, vf13, vf29 576 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf29.y()); + sq_buffer(Mask::xyzw, vu.vf16, vu.vi08 + 63); + // sq.xyzw vf24, 61(vi08) | maddaz.xyzw ACC, vf14, vf29 577 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf29.z()); + sq_buffer(Mask::xyzw, vu.vf24, vu.vi08 + 61); + // iaddi vi04, vi04, 0x1 | maddw.xyzw vf31, vf15, vf00 578 + vu.acc.madd(Mask::xyzw, vu.vf31, vu.vf15, vu.vf00.w()); + vu.vi04 = vu.vi04 + 1; + // iaddi vi03, vi03, 0x2 | mulax.xyzw ACC, vf08, vf29 579 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf29.x()); + vu.vi03 = vu.vi03 + 2; + // ior vi01, vi01, vi13 | madday.xyzw ACC, vf09, vf29 580 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf29.y()); + vu.vi01 = vu.vi01 | vu.vi13; + // nop | maddaz.xyzw ACC, vf10, vf29 581 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf29.z()); + // nop | maddw.xyzw vf27, vf11, vf00 582 + vu.acc.madd(Mask::xyzw, vu.vf27, vu.vf11, vu.vf00.w()); + // lq.xyzw vf28, 236(vi05) | miniz.w vf17, vf17, vf03 583 + vu.vf17.mini(Mask::w, vu.vf17, vu.vf03.z()); + lq_buffer(Mask::xyzw, vu.vf28, vu.vi05 + 236); + // BRANCH! + // ibgtz vi06, L33 | mula.xyzw ACC, vf25, vf05 584 + vu.acc.mula(Mask::xyzw, vu.vf25, vu.vf05); + bc = ((s16)vu.vi06) > 0; + // iaddi vi06, vi06, -0x1 | maddw.xyzw vf25, vf06, vf00 585 + vu.acc.madd(Mask::xyzw, vu.vf25, vu.vf06, vu.vf00.w()); + vu.vi06 = vu.vi06 + -1; + if (bc) { + goto L33; + } + + // BRANCH! + // ibeq vi00, vi01, L37 | nop 586 + bc = (vu.vi01 == 0); + // nop | nop 587 + + if (bc) { + goto L37; + } + + // BRANCH! + // ibne vi00, vi13, L37 | addw.w vf17, vf17, vf03 588 + vu.vf17.add(Mask::w, vu.vf17, vu.vf03.w()); + bc = (vu.vi13 != 0); + // fcor vi01, 0x7df7ff | nop 589 + fcor(vu.vi01, 0x7df7ff, cf); + + if (bc) { + goto L37; + } + + // isw.x vi12, 775(vi14) | nop 590 + isw_buffer(Mask::x, vu.vi12, vu.vi14 + 775); + // BRANCH! + // ibne vi00, vi01, L37 | nop 591 + bc = (vu.vi01 != 0); + // fcor vi01, 0xdf7dff | nop 592 + fcor(vu.vi01, 0xdf7dff, cf); + + if (bc) { + goto L37; + } + + // isw.y vi05, 775(vi14) | nop 593 + isw_buffer(Mask::y, vu.vi05, vu.vi14 + 775); + // BRANCH! + // ibne vi00, vi01, L37 | nop 594 + bc = (vu.vi01 != 0); + // fcor vi01, 0xefbeff | nop 595 + fcor(vu.vi01, 0xefbeff, cf); + + if (bc) { + goto L37; + } + + // isw.z vi04, 775(vi14) | nop 596 + isw_buffer(Mask::z, vu.vi04, vu.vi14 + 775); + // BRANCH! + // ibne vi00, vi01, L37 | nop 597 + bc = (vu.vi01 != 0); + // fcor vi01, 0xf7df7f | nop 598 + fcor(vu.vi01, 0xf7df7f, cf); + + if (bc) { + goto L37; + } + + // nop | nop 599 + + // BRANCH! + // ibne vi00, vi01, L37 | nop 600 + bc = (vu.vi01 != 0); + // fcor vi01, 0xfbefbf | nop 601 + fcor(vu.vi01, 0xfbefbf, cf); + + if (bc) { + goto L37; + } + + // nop | nop 602 + + // BRANCH! + // ibne vi00, vi01, L37 | nop 603 + bc = (vu.vi01 != 0); + // nop | nop 604 + + if (bc) { + goto L37; + } + + // iaddi vi14, vi14, 0x1 | nop 605 + vu.vi14 = vu.vi14 + 1; +L37: + // nop | ftoi4.xyzw vf17, vf17 606 + vu.vf17.ftoi4(Mask::xyzw, vu.vf17); + // vu.vf17.fill(0); + // sq.xyzw vf21, 3(vi08) | mulz.xyzw vf25, vf25, vf21 607 + vu.vf25.mul(Mask::xyzw, vu.vf25, vu.vf21.z()); + sq_buffer(Mask::xyzw, vu.vf21, vu.vi08 + 3); + // sq.xyzw vf23, 4(vi08) | nop 608 + sq_buffer(Mask::xyzw, vu.vf23, vu.vi08 + 4); + // sq.xyzw vf17, 5(vi08) | nop 609 + sq_buffer(Mask::xyzw, vu.vf17, vu.vi08 + 5); + // sq.xyzw vf17, 66(vi08) | nop 610 + sq_buffer(Mask::xyzw, vu.vf17, vu.vi08 + 66); + // sq.xyzw vf25, 64(vi08) | nop 611 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi08 + 64); + // jr vi15 | nop 612 + // nop | nop 613 +} + void OceanMid::run_L38_vu2c() { bool bc; @@ -2173,6 +3498,342 @@ L42: // jr vi15 | nop 747 // nop | nop 748 } + +void OceanMid::run_L38_vu2c_jak2() { + bool bc; + + // lq.xyzw vf31, 734(vi00) | nop 614 + lq_buffer(Mask::xyzw, vu.vf31, 734); + // iaddiu vi10, vi00, 0x243 | nop 615 + vu.vi10 = 0x243; /* 579 */ +L39: + // iaddi vi14, vi14, -0x1 | nop 616 + vu.vi14 = vu.vi14 + -1; + // iaddi vi08, vi10, 0x7 | nop 617 + vu.vi08 = vu.vi10 + 7; + // ilw.x vi12, 775(vi14) | nop 618 + ilw_buffer(Mask::x, vu.vi12, vu.vi14 + 775); + // ilw.y vi05, 775(vi14) | nop 619 + ilw_buffer(Mask::y, vu.vi05, vu.vi14 + 775); + // ilw.z vi04, 775(vi14) | nop 620 + ilw_buffer(Mask::z, vu.vi04, vu.vi14 + 775); + // BRANCH! + // ibne vi00, vi12, L40 | nop 621 + bc = (vu.vi12 != 0); + // nop | nop 622 + + if (bc) { + goto L40; + } + + // lq.xyzw vf28, 233(vi05) | nop 623 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi05 + 233); + // lq.xyzw vf29, 242(vi05) | nop 624 + lq_buffer(Mask::xyzw, vu.vf29, vu.vi05 + 242); + // lq.xyzw vf30, 234(vi05) | nop 625 + lq_buffer(Mask::xyzw, vu.vf30, vu.vi05 + 234); + // lq.xyzw vf22, 7(vi04) | nop 626 + lq_buffer(Mask::xyzw, vu.vf22, vu.vi04 + 7); + // lq.xyzw vf23, 19(vi04) | mulax.xyzw ACC, vf08, vf28 627 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf28.x()); + lq_buffer(Mask::xyzw, vu.vf23, vu.vi04 + 19); + // lq.xyzw vf16, 8(vi04) | madday.xyzw ACC, vf09, vf28 628 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf28.y()); + lq_buffer(Mask::xyzw, vu.vf16, vu.vi04 + 8); + // lq.xyzw vf20, 317(vi00) | maddaz.xyzw ACC, vf10, vf28 629 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf28.z()); + lq_buffer(Mask::xyzw, vu.vf20, 317); + // lq.xyzw vf21, 318(vi00) | maddw.xyzw vf24, vf11, vf00 630 + vu.acc.madd(Mask::xyzw, vu.vf24, vu.vf11, vu.vf00.w()); + lq_buffer(Mask::xyzw, vu.vf21, 318); + // BRANCH! + // b L41 | mulax.xyzw ACC, vf12, vf28 631 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf28.x()); + bc = true; + // lq.xyzw vf07, 319(vi00) | madday.xyzw ACC, vf13, vf28 632 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf28.y()); + lq_buffer(Mask::xyzw, vu.vf07, 319); + if (bc) { + goto L41; + } + +L40: + // lq.xyzw vf28, 242(vi05) | nop 633 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi05 + 242); + // lq.xyzw vf29, 234(vi05) | nop 634 + lq_buffer(Mask::xyzw, vu.vf29, vu.vi05 + 234); + // lq.xyzw vf30, 243(vi05) | nop 635 + lq_buffer(Mask::xyzw, vu.vf30, vu.vi05 + 243); + // lq.xyzw vf22, 18(vi04) | nop 636 + lq_buffer(Mask::xyzw, vu.vf22, vu.vi04 + 18); + // lq.xyzw vf23, 7(vi04) | mulax.xyzw ACC, vf08, vf28 637 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf28.x()); + lq_buffer(Mask::xyzw, vu.vf23, vu.vi04 + 7); + // lq.xyzw vf16, 19(vi04) | madday.xyzw ACC, vf09, vf28 638 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf28.y()); + lq_buffer(Mask::xyzw, vu.vf16, vu.vi04 + 19); + // lq.xyzw vf20, 318(vi00) | maddaz.xyzw ACC, vf10, vf28 639 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf28.z()); + lq_buffer(Mask::xyzw, vu.vf20, 318); + // lq.xyzw vf21, 319(vi00) | maddw.xyzw vf24, vf11, vf00 640 + vu.acc.madd(Mask::xyzw, vu.vf24, vu.vf11, vu.vf00.w()); + lq_buffer(Mask::xyzw, vu.vf21, 319); + // nop | mulax.xyzw ACC, vf12, vf28 641 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf28.x()); + // lq.xyzw vf07, 320(vi00) | madday.xyzw ACC, vf13, vf28 642 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf28.y()); + lq_buffer(Mask::xyzw, vu.vf07, 320); +L41: + // nop | maddaz.xyzw ACC, vf14, vf28 643 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf28.z()); + // erleng.xyz P, vf24 | maddw.xyzw vf28, vf15, vf00 644 + vu.acc.madd(Mask::xyzw, vu.vf28, vu.vf15, vu.vf00.w()); + vu.P = erleng(vu.vf24); + // nop | itof0.xyzw vf22, vf22 646 + vu.vf22.itof0(Mask::xyzw, vu.vf22); + // nop | itof0.xyzw vf23, vf23 647 + vu.vf23.itof0(Mask::xyzw, vu.vf23); + // nop | itof0.xyzw vf16, vf16 648 + vu.vf16.itof0(Mask::xyzw, vu.vf16); + // sq.xyzw vf20, 0(vi08) | mulax.xyzw ACC, vf08, vf29 649 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf29.x()); + sq_buffer(Mask::xyzw, vu.vf20, vu.vi08); + // sq.xyzw vf22, 1(vi08) | madday.xyzw ACC, vf09, vf29 650 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf29.y()); + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 1); + // sq.xyzw vf21, 3(vi08) | maddaz.xyzw ACC, vf10, vf29 651 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf29.z()); + sq_buffer(Mask::xyzw, vu.vf21, vu.vi08 + 3); + // sq.xyzw vf23, 4(vi08) | maddw.xyzw vf25, vf11, vf00 652 + vu.acc.madd(Mask::xyzw, vu.vf25, vu.vf11, vu.vf00.w()); + sq_buffer(Mask::xyzw, vu.vf23, vu.vi08 + 4); + // sq.xyzw vf07, 6(vi08) | mulax.xyzw ACC, vf12, vf29 653 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf29.x()); + sq_buffer(Mask::xyzw, vu.vf07, vu.vi08 + 6); + // sq.xyzw vf16, 7(vi08) | madday.xyzw ACC, vf13, vf29 654 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf29.y()); + sq_buffer(Mask::xyzw, vu.vf16, vu.vi08 + 7); + // sq.xyzw vf20, 9(vi08) | maddaz.xyzw ACC, vf14, vf29 655 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf29.z()); + sq_buffer(Mask::xyzw, vu.vf20, vu.vi08 + 9); + // sq.xyzw vf22, 10(vi08) | maddw.xyzw vf29, vf15, vf00 656 + vu.acc.madd(Mask::xyzw, vu.vf29, vu.vf15, vu.vf00.w()); + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 10); + // waitp | mul.xyzw vf28, vf28, vf01 657 + vu.vf28.mul(Mask::xyzw, vu.vf28, vu.vf01); + // mfp.w vf24, P | nop 658 + vu.vf24.mfp(Mask::w, vu.P); + // erleng.xyz P, vf25 | nop 659 + vu.P = erleng(vu.vf25); + // sq.xyzw vf28, 2(vi08) | mulax.xyzw ACC, vf08, vf30 661 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf30.x()); + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 2); + // sq.xyzw vf28, 11(vi08) | mulw.xy vf24, vf24, vf24 662 + vu.vf24.mul(Mask::xy, vu.vf24, vu.vf24.w()); + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 11); + // sq.xyzw vf28, 772(vi00) | madday.xyzw ACC, vf09, vf30 663 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf30.y()); + sq_buffer(Mask::xyzw, vu.vf28, 772); + // nop | maddaz.xyzw ACC, vf10, vf30 664 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf30.z()); + // nop | maddw.xyzw vf26, vf11, vf00 665 + vu.acc.madd(Mask::xyzw, vu.vf26, vu.vf11, vu.vf00.w()); + // nop | mula.xyzw ACC, vf24, vf05 666 + vu.acc.mula(Mask::xyzw, vu.vf24, vu.vf05); + // nop | maddw.xyzw vf24, vf06, vf00 667 + vu.acc.madd(Mask::xyzw, vu.vf24, vu.vf06, vu.vf00.w()); + // nop | mulax.xyzw ACC, vf12, vf30 668 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf30.x()); + // nop | madday.xyzw ACC, vf13, vf30 669 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf30.y()); + // nop | maddaz.xyzw ACC, vf14, vf30 670 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf30.z()); + // sq.xyzw vf24, 769(vi00) | maddw.xyzw vf30, vf15, vf00 671 + vu.acc.madd(Mask::xyzw, vu.vf30, vu.vf15, vu.vf00.w()); + sq_buffer(Mask::xyzw, vu.vf24, 769); + // waitp | mul.xyzw vf29, vf29, vf01 672 + vu.vf29.mul(Mask::xyzw, vu.vf29, vu.vf01); + // mfp.w vf25, P | nop 673 + vu.vf25.mfp(Mask::w, vu.P); + // erleng.xyz P, vf26 | nop 674 + vu.P = erleng(vu.vf26); + // sq.xyzw vf29, 5(vi08) | nop 676 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi08 + 5); + // sq.xyzw vf29, 773(vi00) | mulw.xy vf25, vf25, vf25 677 + vu.vf25.mul(Mask::xy, vu.vf25, vu.vf25.w()); + sq_buffer(Mask::xyzw, vu.vf29, 773); + // nop | mula.xyzw ACC, vf25, vf05 678 + vu.acc.mula(Mask::xyzw, vu.vf25, vu.vf05); + // nop | maddw.xyzw vf25, vf06, vf00 679 + vu.acc.madd(Mask::xyzw, vu.vf25, vu.vf06, vu.vf00.w()); + // waitp | mul.xyzw vf30, vf30, vf01 680 + vu.vf30.mul(Mask::xyzw, vu.vf30, vu.vf01); + // mfp.w vf26, P | nop 681 + vu.vf26.mfp(Mask::w, vu.P); + // sq.xyzw vf30, 8(vi08) | nop 682 + sq_buffer(Mask::xyzw, vu.vf30, vu.vi08 + 8); + // sq.xyzw vf30, 774(vi00) | mulw.xy vf26, vf26, vf26 683 + vu.vf26.mul(Mask::xy, vu.vf26, vu.vf26.w()); + sq_buffer(Mask::xyzw, vu.vf30, 774); + // sq.xyzw vf25, 770(vi00) | mula.xyzw ACC, vf26, vf05 684 + vu.acc.mula(Mask::xyzw, vu.vf26, vu.vf05); + sq_buffer(Mask::xyzw, vu.vf25, 770); + // lq.xyzw vf07, 739(vi00) | maddw.xyzw vf26, vf06, vf00 685 + vu.acc.madd(Mask::xyzw, vu.vf26, vu.vf06, vu.vf00.w()); + lq_buffer(Mask::xyzw, vu.vf07, 739); + // ior vi03, vi08, vi00 | nop 686 + vu.vi03 = vu.vi08; + // iaddi vi05, vi00, 0x3 | nop 687 + vu.vi05 = 3; + // BRANCH! + // bal vi13, L45 | nop 688 + + // sq.xyzw vf26, 771(vi00) | nop 689 + sq_buffer(Mask::xyzw, vu.vf26, 771); + // if (bc) { goto L45; } + run_L45_vu2c(); + + // lq.xyzw vf28, 741(vi00) | nop 690 + lq_buffer(Mask::xyzw, vu.vf28, 741); + // BRANCH! + // ibeq vi00, vi05, L42 | nop 691 + bc = (vu.vi05 == 0); + // lq.xyzw vf29, 742(vi00) | nop 692 + lq_buffer(Mask::xyzw, vu.vf29, 742); + if (bc) { + goto L42; + } + + // lq.xyzw vf30, 743(vi00) | nop 693 + lq_buffer(Mask::xyzw, vu.vf30, 743); + // lq.xyzw vf24, 744(vi00) | nop 694 + lq_buffer(Mask::xyzw, vu.vf24, 744); + // lq.xyzw vf25, 745(vi00) | nop 695 + lq_buffer(Mask::xyzw, vu.vf25, 745); + // lq.xyzw vf26, 746(vi00) | nop 696 + lq_buffer(Mask::xyzw, vu.vf26, 746); + // sq.xyzw vf28, 0(vi10) | nop 697 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi10); + // sq.xyzw vf29, 1(vi10) | nop 698 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi10 + 1); + // sq.xyzw vf30, 2(vi10) | nop 699 + sq_buffer(Mask::xyzw, vu.vf30, vu.vi10 + 2); + // sq.xyzw vf24, 3(vi10) | nop 700 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi10 + 3); + // sq.xyzw vf25, 4(vi10) | nop 701 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi10 + 4); + // sq.xyzw vf26, 5(vi10) | nop 702 + sq_buffer(Mask::xyzw, vu.vf26, vu.vi10 + 5); + // iaddiu vi06, vi05, 0x4000 | nop 703 + vu.vi06 = vu.vi05 + 0x4000; /* 16384 */ + // BRANCH! + // bal vi13, L43 | nop 704 + // ASSERT(false); + // iaddiu vi06, vi06, 0x4000 | nop 705 + vu.vi06 = vu.vi06 + 0x4000; /* 16384 */ + // if (bc) { goto L43; } + run_L43_vu2c(); + + // iaddi vi08, vi10, 0x7 | nop 706 + vu.vi08 = vu.vi10 + 7; + // lq.xyzw vf24, 769(vi00) | nop 707 + lq_buffer(Mask::xyzw, vu.vf24, 769); + // lq.xyzw vf25, 770(vi00) | nop 708 + lq_buffer(Mask::xyzw, vu.vf25, 770); + // lq.xyzw vf26, 771(vi00) | nop 709 + lq_buffer(Mask::xyzw, vu.vf26, 771); + // lq.xyzw vf22, 756(vi00) | nop 710 + lq_buffer(Mask::xyzw, vu.vf22, 756); + // lq.xyzw vf28, 772(vi00) | nop 711 + lq_buffer(Mask::xyzw, vu.vf28, 772); + // lq.xyzw vf29, 773(vi00) | nop 712 + lq_buffer(Mask::xyzw, vu.vf29, 773); + // lq.xyzw vf30, 774(vi00) | nop 713 + lq_buffer(Mask::xyzw, vu.vf30, 774); + // sq.xyzw vf24, 0(vi08) | nop 714 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi08); + // sq.xyzw vf22, 1(vi08) | nop 715 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 1); + // sq.xyzw vf28, 2(vi08) | nop 716 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 2); + // sq.xyzw vf25, 3(vi08) | nop 717 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi08 + 3); + // sq.xyzw vf22, 4(vi08) | nop 718 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 4); + // sq.xyzw vf29, 5(vi08) | nop 719 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi08 + 5); + // sq.xyzw vf26, 6(vi08) | nop 720 + sq_buffer(Mask::xyzw, vu.vf26, vu.vi08 + 6); + // sq.xyzw vf22, 7(vi08) | nop 721 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 7); + // sq.xyzw vf30, 8(vi08) | nop 722 + sq_buffer(Mask::xyzw, vu.vf30, vu.vi08 + 8); + // sq.xyzw vf24, 9(vi08) | nop 723 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi08 + 9); + // sq.xyzw vf22, 10(vi08) | nop 724 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 10); + // sq.xyzw vf28, 11(vi08) | nop 725 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 11); + // ior vi03, vi08, vi00 | nop 726 + vu.vi03 = vu.vi08; + // iaddi vi05, vi00, 0x3 | nop 727 + vu.vi05 = 3; + // BRANCH! + // bal vi13, L45 | nop 728 + // ASSERT(false); + // lq.xyzw vf07, 740(vi00) | nop 729 + lq_buffer(Mask::xyzw, vu.vf07, 740); + // if (bc) { goto L45; } + run_L45_vu2c(); + + // lq.xyzw vf28, 749(vi00) | nop 730 + lq_buffer(Mask::xyzw, vu.vf28, 749); + // lq.xyzw vf29, 750(vi00) | nop 731 + lq_buffer(Mask::xyzw, vu.vf29, 750); + // lq.xyzw vf30, 751(vi00) | nop 732 + lq_buffer(Mask::xyzw, vu.vf30, 751); + // lq.xyzw vf24, 752(vi00) | nop 733 + lq_buffer(Mask::xyzw, vu.vf24, 752); + // lq.xyzw vf25, 753(vi00) | nop 734 + lq_buffer(Mask::xyzw, vu.vf25, 753); + // lq.xyzw vf26, 754(vi00) | nop 735 + lq_buffer(Mask::xyzw, vu.vf26, 754); + // sq.xyzw vf28, 0(vi10) | nop 736 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi10); + // sq.xyzw vf29, 1(vi10) | nop 737 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi10 + 1); + // sq.xyzw vf30, 2(vi10) | nop 738 + sq_buffer(Mask::xyzw, vu.vf30, vu.vi10 + 2); + // sq.xyzw vf24, 3(vi10) | nop 739 + sq_buffer(Mask::xyzw, vu.vf24, vu.vi10 + 3); + // sq.xyzw vf25, 4(vi10) | nop 740 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi10 + 4); + // sq.xyzw vf26, 5(vi10) | nop 741 + sq_buffer(Mask::xyzw, vu.vf26, vu.vi10 + 5); + // iaddiu vi06, vi05, 0x4000 | nop 742 + vu.vi06 = vu.vi05 + 0x4000; /* 16384 */ + // BRANCH! + // bal vi13, L43 | nop 743 + // ASSERT(false); + // iaddiu vi06, vi06, 0x4000 | nop 744 + vu.vi06 = vu.vi06 + 0x4000; /* 16384 */ + // if (bc) { goto L43; } + run_L43_vu2c(); + +L42: + // BRANCH! + // ibgtz vi14, L39 | nop 745 + bc = ((s16)vu.vi14) > 0; + // nop | nop 746 + + if (bc) { + goto L39; + } + + // jr vi15 | nop 747 + // nop | nop 748 +} + void OceanMid::run_L43_vu2c() { bool bc; // sq.xyzw vf07, -1(vi08) | nop 749 diff --git a/game/graphics/opengl_renderer/ocean/OceanNear.cpp b/game/graphics/opengl_renderer/ocean/OceanNear.cpp index 210b53567d..36629ad817 100644 --- a/game/graphics/opengl_renderer/ocean/OceanNear.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanNear.cpp @@ -13,8 +13,8 @@ OceanNear::OceanNear(const std::string& name, int my_id) void OceanNear::draw_debug_window() {} -void OceanNear::init_textures(TexturePool& pool) { - m_texture_renderer.init_textures(pool); +void OceanNear::init_textures(TexturePool& pool, GameVersion version) { + m_texture_renderer.init_textures(pool, version); } static bool is_end_tag(const DmaTag& tag, const VifCode& v0, const VifCode& v1) { @@ -33,6 +33,19 @@ void OceanNear::render(DmaFollower& dma, return; } + switch (render_state->version) { + case GameVersion::Jak1: + render_jak1(dma, render_state, prof); + break; + case GameVersion::Jak2: + render_jak2(dma, render_state, prof); + break; + } +} + +void OceanNear::render_jak1(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof) { // jump to bucket auto data0 = dma.read_and_advance(); ASSERT(data0.vif1() == 0); @@ -52,7 +65,7 @@ void OceanNear::render(DmaFollower& dma, { auto p = prof.make_scoped_child("texture"); // TODO: this looks the same as the previous ocean renderer to me... why do it again? - m_texture_renderer.handle_ocean_texture(dma, render_state, p); + m_texture_renderer.handle_ocean_texture_jak1(dma, render_state, p); } if (dma.current_tag().qwc != 2) { @@ -117,6 +130,88 @@ void OceanNear::render(DmaFollower& dma, m_common_ocean_renderer.flush_near(render_state, prof); } +void OceanNear::render_jak2(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof) { + // jump to bucket + auto data0 = dma.read_and_advance(); + ASSERT(data0.vif1() == 0 || data0.vifcode1().kind == VifCode::Kind::NOP); + ASSERT(data0.vif0() == 0 || data0.vifcode0().kind == VifCode::Kind::MARK); + ASSERT(data0.size_bytes == 0); + + // see if bucket is empty or not + if (dma.current_tag_offset() == render_state->next_bucket) { + // fmt::print("ocean-near: early exit!\n"); + return; + } + + { + auto p = prof.make_scoped_child("texture"); + m_texture_renderer.handle_ocean_texture_jak2(dma, render_state, p); + } + + if (dma.current_tag().qwc != 2) { + lg::error("abort OceanNear::render!"); + while (dma.current_tag_offset() != render_state->next_bucket) { + dma.read_and_advance(); + } + return; + } + + // direct setup + { + m_common_ocean_renderer.init_for_near(); + auto setup = dma.read_and_advance(); + ASSERT(setup.vifcode0().kind == VifCode::Kind::NOP); + ASSERT(setup.vifcode1().kind == VifCode::Kind::DIRECT); + ASSERT(setup.size_bytes == 32); + } + + // offset and base + { + auto ob = dma.read_and_advance(); + ASSERT(ob.size_bytes == 0); + auto base = ob.vifcode0(); + auto off = ob.vifcode1(); + ASSERT(base.kind == VifCode::Kind::BASE); + ASSERT(off.kind == VifCode::Kind::OFFSET); + ASSERT(base.immediate == VU1_INPUT_BUFFER_BASE); + ASSERT(off.immediate == VU1_INPUT_BUFFER_OFFSET); + } + + while (!is_end_tag(dma.current_tag(), dma.current_tag_vif0(), dma.current_tag_vif1())) { + auto data = dma.read_and_advance(); + auto v0 = data.vifcode0(); + auto v1 = data.vifcode1(); + + if (v0.kind == VifCode::Kind::STCYCL && v1.kind == VifCode::Kind::UNPACK_V4_32) { + ASSERT(v0.immediate == 0x404); + auto up = VifCodeUnpack(v1); + u16 addr = up.addr_qw + (up.use_tops_flag ? get_upload_buffer() : 0); + ASSERT(addr + v1.num <= 1024); + memcpy(m_vu_data + addr, data.data, 16 * v1.num); + } else if (v0.kind == VifCode::Kind::MSCALF && v1.kind == VifCode::Kind::STMOD) { + ASSERT(v1.immediate == 0); + switch (v0.immediate) { + case 0: + run_call0_vu2c_jak2(); + break; + case 39: + run_call39_vu2c_jak2(); + break; + default: + ASSERT_MSG(false, fmt::format("unknown ocean near call: {}", v0.immediate)); + } + } + } + + while (dma.current_tag_offset() != render_state->next_bucket) { + dma.read_and_advance(); + } + + m_common_ocean_renderer.flush_near(render_state, prof); +} + void OceanNear::xgkick(u16 addr) { m_common_ocean_renderer.kick_from_near((const u8*)&m_vu_data[addr]); } diff --git a/game/graphics/opengl_renderer/ocean/OceanNear.h b/game/graphics/opengl_renderer/ocean/OceanNear.h index 7fb52b716a..bf98078878 100644 --- a/game/graphics/opengl_renderer/ocean/OceanNear.h +++ b/game/graphics/opengl_renderer/ocean/OceanNear.h @@ -9,16 +9,23 @@ class OceanNear : public BucketRenderer { public: OceanNear(const std::string& name, int my_id); void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override; + void render_jak1(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof); + void render_jak2(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof); void draw_debug_window() override; - void init_textures(TexturePool& pool) override; + void init_textures(TexturePool& pool, GameVersion version) override; private: void run_call0_vu2c(); + void run_call0_vu2c_jak2(); void run_call39_vu2c(); + void run_call39_vu2c_jak2(); void run_L15_vu2c(); + void run_L15_vu2c_jak2(); void run_L21_vu2c(); + void run_L21_vu2c_jak2(); void run_L23_vu2c(); void run_L25_vu2c(); + void run_L25_vu2c_jak2(); void run_L30_vu2c(); void run_L32_vu2c(); diff --git a/game/graphics/opengl_renderer/ocean/OceanNear_PS2.cpp b/game/graphics/opengl_renderer/ocean/OceanNear_PS2.cpp index 3904740c2d..81817f996e 100644 --- a/game/graphics/opengl_renderer/ocean/OceanNear_PS2.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanNear_PS2.cpp @@ -557,6 +557,563 @@ L14: // nop | nop 206 } +void OceanNear::run_call0_vu2c_jak2() { + bool bc; + // lq.xyzw vf01, 951(vi00) | nop 0 + lq_buffer(Mask::xyzw, vu.vf01, 951); + // lq.xyzw vf02, 953(vi00) | nop 1 + lq_buffer(Mask::xyzw, vu.vf02, 953); + // lq.xyzw vf03, 954(vi00) | nop 2 + lq_buffer(Mask::xyzw, vu.vf03, 954); + // lq.xyzw vf05, 955(vi00) | nop 3 + lq_buffer(Mask::xyzw, vu.vf05, 955); + // lq.xyzw vf06, 956(vi00) | nop 4 + lq_buffer(Mask::xyzw, vu.vf06, 956); + // iaddiu vi09, vi00, 0x213 | nop 5 + vu.vi09 = 0x213; /* 531 */ + // iaddi vi01, vi00, 0x6 | nop 6 + vu.vi01 = 6; +L1: + // lq.xyzw vf12, 962(vi01) | nop 7 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi01 + 963); + // lq.xyzw vf13, 969(vi01) | nop 8 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi01 + 970); + // sq.xyzw vf12, 531(vi01) | nop 9 + sq_buffer(Mask::xyzw, vu.vf12, vu.vi01 + 531); + // sq.xyzw vf12, 671(vi01) | nop 10 + sq_buffer(Mask::xyzw, vu.vf12, vu.vi01 + 671); + // sq.xyzw vf13, 592(vi01) | nop 11 + sq_buffer(Mask::xyzw, vu.vf13, vu.vi01 + 592); + // sq.xyzw vf13, 732(vi01) | nop 12 + sq_buffer(Mask::xyzw, vu.vf13, vu.vi01 + 732); + // sq.xyzw vf12, 811(vi01) | nop 13 + sq_buffer(Mask::xyzw, vu.vf12, vu.vi01 + 811); + // sq.xyzw vf12, 881(vi01) | nop 14 + sq_buffer(Mask::xyzw, vu.vf12, vu.vi01 + 881); + // sq.xyzw vf13, 846(vi01) | nop 15 + sq_buffer(Mask::xyzw, vu.vf13, vu.vi01 + 846); + // sq.xyzw vf13, 916(vi01) | nop 16 + sq_buffer(Mask::xyzw, vu.vf13, vu.vi01 + 916); + // BRANCH! + // ibgtz vi01, L1 | nop 17 + bc = ((s16)vu.vi01) > 0; + // iaddi vi01, vi01, -0x1 | nop 18 + vu.vi01 = vu.vi01 + -1; + if (bc) { + goto L1; + } + + // lq.xyzw vf08, 977(vi00) | nop 19 + lq_buffer(Mask::xyzw, vu.vf08, 977); + // iaddi vi04, vi00, 0x8 | nop 20 + vu.vi04 = 8; + // iaddiu vi06, vi00, 0x11 | ftoi0.xyzw vf08, vf08 21 + vu.vf08.ftoi0(Mask::xyzw, vu.vf08); + vu.vi06 = 0x11; /* 17 */ +L2: + // sq.xyzw vf08, 592(vi04) | nop 22 + sq_buffer(Mask::xyzw, vu.vf08, vu.vi04 + 592); + // sq.xyzw vf08, 732(vi04) | nop 23 + sq_buffer(Mask::xyzw, vu.vf08, vu.vi04 + 732); + // iaddi vi04, vi04, 0x3 | nop 24 + vu.vi04 = vu.vi04 + 3; + // BRANCH! + // ibgtz vi06, L2 | nop 25 + bc = ((s16)vu.vi06) > 0; + // iaddi vi06, vi06, -0x1 | nop 26 + vu.vi06 = vu.vi06 + -1; + if (bc) { + goto L2; + } + + // lq.xyzw vf07, 957(vi00) | nop 27 + lq_buffer(Mask::xyzw, vu.vf07, 957); + // iaddi vi05, vi00, 0x0 | mul.xyzw vf16, vf00, vf00 28 + vu.vf16.mul(Mask::xyzw, vu.vf00, vu.vf00); + vu.vi05 = 0; + // iaddi vi07, vi00, 0x8 | nop 29 + vu.vi07 = 8; +L3: + // iaddi vi06, vi00, 0x8 | mul.x vf16, vf00, vf00 30 + vu.vf16.mul(Mask::x, vu.vf00, vu.vf00); + vu.vi06 = 8; +L4: + // sq.xyzw vf16, 290(vi05) | nop 31 + sq_buffer(Mask::xyzw, vu.vf16, vu.vi05 + 290); + // iaddi vi05, vi05, 0x3 | addx.x vf16, vf16, vf07 32 + vu.vf16.add(Mask::x, vu.vf16, vu.vf07.x()); + vu.vi05 = vu.vi05 + 3; + // BRANCH! + // ibgtz vi06, L4 | nop 33 + bc = ((s16)vu.vi06) > 0; + // iaddi vi06, vi06, -0x1 | nop 34 + vu.vi06 = vu.vi06 + -1; + if (bc) { + goto L4; + } + + // BRANCH! + // ibgtz vi07, L3 | addx.z vf16, vf16, vf07 35 + vu.vf16.add(Mask::z, vu.vf16, vu.vf07.x()); + bc = ((s16)vu.vi07) > 0; + // iaddi vi07, vi07, -0x1 | nop 36 + vu.vi07 = vu.vi07 + -1; + if (bc) { + goto L3; + } + + // nop | nop :e 37 + + // nop | nop 38 +} + +void OceanNear::run_call39_vu2c_jak2() { + bool bc; + // xtop vi02 | nop 39 + vu.vi02 = xtop(); + // ilw.x vi03, 10(vi02) | nop 40 + ilw_buffer(Mask::x, vu.vi03, vu.vi02 + 10); + // ilw.y vi04, 10(vi02) | nop 41 + ilw_buffer(Mask::y, vu.vi04, vu.vi02 + 10); + // iaddi vi05, vi00, 0x0 | nop 42 + vu.vi05 = 0; + // iaddi vi07, vi00, 0x7 | nop 43 + vu.vi07 = 7; +L6: + // lq.xyzw vf28, 32(vi03) | nop 44 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi03 + 32); + // lq.xyzw vf29, 33(vi03) | nop 45 + lq_buffer(Mask::xyzw, vu.vf29, vu.vi03 + 33); + // lq.xyzw vf30, 32(vi04) | nop 46 + lq_buffer(Mask::xyzw, vu.vf30, vu.vi04 + 32); + // lq.xyzw vf24, 290(vi05) | nop 47 + lq_buffer(Mask::xyzw, vu.vf24, vu.vi05 + 290); + // lq.xyzw vf25, 293(vi05) | nop 48 + lq_buffer(Mask::xyzw, vu.vf25, vu.vi05 + 293); + // lq.xyzw vf26, 296(vi05) | nop 49 + lq_buffer(Mask::xyzw, vu.vf26, vu.vi05 + 296); + // lq.xyzw vf27, 299(vi05) | nop 50 + lq_buffer(Mask::xyzw, vu.vf27, vu.vi05 + 299); + // lq.xyzw vf12, 302(vi05) | addx.y vf24, vf00, vf28 51 + vu.vf24.add(Mask::y, vu.vf00, vu.vf28.x()); + lq_buffer(Mask::xyzw, vu.vf12, vu.vi05 + 302); + // lq.xyzw vf13, 305(vi05) | addy.y vf25, vf00, vf28 52 + vu.vf25.add(Mask::y, vu.vf00, vu.vf28.y()); + lq_buffer(Mask::xyzw, vu.vf13, vu.vi05 + 305); + // lq.xyzw vf14, 308(vi05) | addz.y vf26, vf00, vf28 53 + vu.vf26.add(Mask::y, vu.vf00, vu.vf28.z()); + lq_buffer(Mask::xyzw, vu.vf14, vu.vi05 + 308); + // lq.xyzw vf15, 311(vi05) | addw.y vf27, vf00, vf28 54 + vu.vf27.add(Mask::y, vu.vf00, vu.vf28.w()); + lq_buffer(Mask::xyzw, vu.vf15, vu.vi05 + 311); + // lq.xyzw vf08, 314(vi05) | addx.y vf12, vf00, vf29 55 + vu.vf12.add(Mask::y, vu.vf00, vu.vf29.x()); + lq_buffer(Mask::xyzw, vu.vf08, vu.vi05 + 314); + // sq.xyzw vf24, 290(vi05) | addy.y vf13, vf00, vf29 56 + vu.vf13.add(Mask::y, vu.vf00, vu.vf29.y()); + sq_buffer(Mask::xyzw, vu.vf24, vu.vi05 + 290); + // sq.xyzw vf25, 293(vi05) | addz.y vf14, vf00, vf29 57 + vu.vf14.add(Mask::y, vu.vf00, vu.vf29.z()); + sq_buffer(Mask::xyzw, vu.vf25, vu.vi05 + 293); + // sq.xyzw vf26, 296(vi05) | addw.y vf15, vf00, vf29 58 + vu.vf15.add(Mask::y, vu.vf00, vu.vf29.w()); + sq_buffer(Mask::xyzw, vu.vf26, vu.vi05 + 296); + // sq.xyzw vf27, 299(vi05) | addx.y vf08, vf00, vf30 59 + vu.vf08.add(Mask::y, vu.vf00, vu.vf30.x()); + sq_buffer(Mask::xyzw, vu.vf27, vu.vi05 + 299); + // sq.xyzw vf12, 302(vi05) | nop 60 + sq_buffer(Mask::xyzw, vu.vf12, vu.vi05 + 302); + // sq.xyzw vf13, 305(vi05) | nop 61 + sq_buffer(Mask::xyzw, vu.vf13, vu.vi05 + 305); + // sq.xyzw vf14, 308(vi05) | nop 62 + sq_buffer(Mask::xyzw, vu.vf14, vu.vi05 + 308); + // sq.xyzw vf15, 311(vi05) | nop 63 + sq_buffer(Mask::xyzw, vu.vf15, vu.vi05 + 311); + // sq.xyzw vf08, 314(vi05) | nop 64 + sq_buffer(Mask::xyzw, vu.vf08, vu.vi05 + 314); + // iaddi vi03, vi03, 0x8 | nop 65 + vu.vi03 = vu.vi03 + 8; + // iaddi vi04, vi04, 0x8 | nop 66 + vu.vi04 = vu.vi04 + 8; + // iaddiu vi05, vi05, 0x1b | nop 67 + vu.vi05 = vu.vi05 + 0x1b; /* 27 */ + // BRANCH! + // ibgtz vi07, L6 | nop 68 + bc = ((s16)vu.vi07) > 0; + // iaddi vi07, vi07, -0x1 | nop 69 + vu.vi07 = vu.vi07 + -1; + if (bc) { + goto L6; + } + + // ilw.z vi03, 10(vi02) | nop 70 + ilw_buffer(Mask::z, vu.vi03, vu.vi02 + 10); + // ilw.w vi04, 10(vi02) | nop 71 + ilw_buffer(Mask::w, vu.vi04, vu.vi02 + 10); + // lq.xyzw vf28, 32(vi03) | nop 72 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi03 + 32); + // lq.xyzw vf29, 33(vi03) | nop 73 + lq_buffer(Mask::xyzw, vu.vf29, vu.vi03 + 33); + // lq.xyzw vf30, 32(vi04) | nop 74 + lq_buffer(Mask::xyzw, vu.vf30, vu.vi04 + 32); + // lq.xyzw vf24, 290(vi05) | nop 75 + lq_buffer(Mask::xyzw, vu.vf24, vu.vi05 + 290); + // lq.xyzw vf25, 293(vi05) | nop 76 + lq_buffer(Mask::xyzw, vu.vf25, vu.vi05 + 293); + // lq.xyzw vf26, 296(vi05) | nop 77 + lq_buffer(Mask::xyzw, vu.vf26, vu.vi05 + 296); + // lq.xyzw vf27, 299(vi05) | nop 78 + lq_buffer(Mask::xyzw, vu.vf27, vu.vi05 + 299); + // lq.xyzw vf12, 302(vi05) | addx.y vf24, vf00, vf28 79 + vu.vf24.add(Mask::y, vu.vf00, vu.vf28.x()); + lq_buffer(Mask::xyzw, vu.vf12, vu.vi05 + 302); + // lq.xyzw vf13, 305(vi05) | addy.y vf25, vf00, vf28 80 + vu.vf25.add(Mask::y, vu.vf00, vu.vf28.y()); + lq_buffer(Mask::xyzw, vu.vf13, vu.vi05 + 305); + // lq.xyzw vf14, 308(vi05) | addz.y vf26, vf00, vf28 81 + vu.vf26.add(Mask::y, vu.vf00, vu.vf28.z()); + lq_buffer(Mask::xyzw, vu.vf14, vu.vi05 + 308); + // lq.xyzw vf15, 311(vi05) | addw.y vf27, vf00, vf28 82 + vu.vf27.add(Mask::y, vu.vf00, vu.vf28.w()); + lq_buffer(Mask::xyzw, vu.vf15, vu.vi05 + 311); + // lq.xyzw vf08, 314(vi05) | addx.y vf12, vf00, vf29 83 + vu.vf12.add(Mask::y, vu.vf00, vu.vf29.x()); + lq_buffer(Mask::xyzw, vu.vf08, vu.vi05 + 314); + // sq.xyzw vf24, 290(vi05) | addy.y vf13, vf00, vf29 84 + vu.vf13.add(Mask::y, vu.vf00, vu.vf29.y()); + sq_buffer(Mask::xyzw, vu.vf24, vu.vi05 + 290); + // sq.xyzw vf25, 293(vi05) | addz.y vf14, vf00, vf29 85 + vu.vf14.add(Mask::y, vu.vf00, vu.vf29.z()); + sq_buffer(Mask::xyzw, vu.vf25, vu.vi05 + 293); + // sq.xyzw vf26, 296(vi05) | addw.y vf15, vf00, vf29 86 + vu.vf15.add(Mask::y, vu.vf00, vu.vf29.w()); + sq_buffer(Mask::xyzw, vu.vf26, vu.vi05 + 296); + // sq.xyzw vf27, 299(vi05) | addx.y vf08, vf00, vf30 87 + vu.vf08.add(Mask::y, vu.vf00, vu.vf30.x()); + sq_buffer(Mask::xyzw, vu.vf27, vu.vi05 + 299); + // sq.xyzw vf12, 302(vi05) | nop 88 + sq_buffer(Mask::xyzw, vu.vf12, vu.vi05 + 302); + // sq.xyzw vf13, 305(vi05) | nop 89 + sq_buffer(Mask::xyzw, vu.vf13, vu.vi05 + 305); + // sq.xyzw vf14, 308(vi05) | nop 90 + sq_buffer(Mask::xyzw, vu.vf14, vu.vi05 + 308); + // sq.xyzw vf15, 311(vi05) | nop 91 + sq_buffer(Mask::xyzw, vu.vf15, vu.vi05 + 311); + // sq.xyzw vf08, 314(vi05) | nop 92 + sq_buffer(Mask::xyzw, vu.vf08, vu.vi05 + 314); + // lq.xyzw vf07, 957(vi00) | nop 93 + lq_buffer(Mask::xyzw, vu.vf07, 957); + // lq.xyzw vf12, 11(vi02) | nop 94 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi02 + 11); + // lq.xyzw vf13, 11(vi02) | nop 95 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi02 + 11); + // lq.xyzw vf22, 12(vi02) | nop 96 + lq_buffer(Mask::xyzw, vu.vf22, vu.vi02 + 12); + // lq.xyzw vf23, 13(vi02) | nop 97 + lq_buffer(Mask::xyzw, vu.vf23, vu.vi02 + 13); + // lq.xyzw vf16, 14(vi02) | nop 98 + lq_buffer(Mask::xyzw, vu.vf16, vu.vi02 + 14); + // lq.xyzw vf17, 15(vi02) | nop 99 + lq_buffer(Mask::xyzw, vu.vf17, vu.vi02 + 15); + // nop | sub.xyzw vf09, vf16, vf22 100 + vu.vf09.sub(Mask::xyzw, vu.vf16, vu.vf22); + // nop | sub.xyzw vf11, vf17, vf23 101 + vu.vf11.sub(Mask::xyzw, vu.vf17, vu.vf23); + // nop | muly.xyzw vf09, vf09, vf07 102 + vu.vf09.mul(Mask::xyzw, vu.vf09, vu.vf07.y()); + // nop | muly.xyzw vf11, vf11, vf07 103 + vu.vf11.mul(Mask::xyzw, vu.vf11, vu.vf07.y()); + // iaddi vi05, vi00, 0x0 | nop 104 + vu.vi05 = 0; + // iaddi vi07, vi00, 0x8 | nop 105 + vu.vi07 = 8; +L7: + // nop | sub.xyzw vf08, vf23, vf22 106 + vu.vf08.sub(Mask::xyzw, vu.vf23, vu.vf22); + // nop | mulw.xyzw vf16, vf22, vf00 107 + vu.vf16.mul(Mask::xyzw, vu.vf22, vu.vf00.w()); + // iaddi vi06, vi00, 0x8 | mulw.x vf12, vf13, vf00 108 + vu.vf12.mul(Mask::x, vu.vf13, vu.vf00.w()); + vu.vi06 = 8; + // nop | muly.xyzw vf08, vf08, vf07 109 + vu.vf08.mul(Mask::xyzw, vu.vf08, vu.vf07.y()); +L8: + // sq.xyzw vf12, 288(vi05) | nop 110 + sq_buffer(Mask::xyzw, vu.vf12, vu.vi05 + 288); + // sq.xyzw vf16, 289(vi05) | nop 111 + sq_buffer(Mask::xyzw, vu.vf16, vu.vi05 + 289); + // iaddi vi05, vi05, 0x3 | addw.x vf12, vf12, vf07 112 + vu.vf12.add(Mask::x, vu.vf12, vu.vf07.w()); + vu.vi05 = vu.vi05 + 3; + // BRANCH! + // ibgtz vi06, L8 | add.xyzw vf16, vf16, vf08 113 + vu.vf16.add(Mask::xyzw, vu.vf16, vu.vf08); + bc = ((s16)vu.vi06) > 0; + // iaddi vi06, vi06, -0x1 | nop 114 + vu.vi06 = vu.vi06 + -1; + if (bc) { + goto L8; + } + + // nop | add.xyzw vf22, vf22, vf09 115 + vu.vf22.add(Mask::xyzw, vu.vf22, vu.vf09); + // nop | add.xyzw vf23, vf23, vf11 116 + vu.vf23.add(Mask::xyzw, vu.vf23, vu.vf11); + // BRANCH! + // ibgtz vi07, L7 | addw.y vf12, vf12, vf07 117 + vu.vf12.add(Mask::y, vu.vf12, vu.vf07.w()); + bc = ((s16)vu.vi07) > 0; + // iaddi vi07, vi07, -0x1 | nop 118 + vu.vi07 = vu.vi07 + -1; + if (bc) { + goto L7; + } + + // lq.xyzw vf08, 0(vi02) | nop 119 + lq_buffer(Mask::xyzw, vu.vf08, vu.vi02); + // lq.xyzw vf09, 1(vi02) | nop 120 + lq_buffer(Mask::xyzw, vu.vf09, vu.vi02 + 1); + // lq.xyzw vf10, 2(vi02) | nop 121 + lq_buffer(Mask::xyzw, vu.vf10, vu.vi02 + 2); + // lq.xyzw vf04, 8(vi02) | nop 122 + lq_buffer(Mask::xyzw, vu.vf04, vu.vi02 + 8); + // iaddi vi07, vi00, 0x3 | nop 123 + vu.vi07 = 3; +L9: + // mtir vi10, vf04.x | nop 124 + vu.vi10 = vu.vf04.x_as_u16(); + // iaddiu vi11, vi00, 0xff | nop 125 + vu.vi11 = 0xff; /* 255 */ + // mr32.xyzw vf04, vf04 | nop 126 + vu.vf04.mr32(Mask::xyzw, vu.vf04); + // BRANCH! + // ibeq vi11, vi10, L11 | nop 127 + bc = (vu.vi11 == vu.vi10); + // lq.xyzw vf11, 3(vi02) | nop 128 + lq_buffer(Mask::xyzw, vu.vf11, vu.vi02 + 3); + if (bc) { + goto L11; + } + + // lq.xyzw vf12, 4(vi02) | nop 129 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi02 + 4); + // lq.xyzw vf13, 5(vi02) | nop 130 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi02 + 5); + // lq.xyzw vf14, 6(vi02) | nop 131 + lq_buffer(Mask::xyzw, vu.vf14, vu.vi02 + 6); + // lq.xyzw vf15, 7(vi02) | nop 132 + lq_buffer(Mask::xyzw, vu.vf15, vu.vi02 + 7); + // ilw.x vi05, 984(vi07) | nop 133 + ilw_buffer(Mask::x, vu.vi05, vu.vi07 + 984); + // BRANCH! + // bal vi15, L15 | nop 134 + // ASSERT(false); + // iaddi vi08, vi09, 0x7 | nop 135 + vu.vi08 = vu.vi09 + 7; + // if (bc) { goto L15; } + run_L15_vu2c_jak2(); + + // lq.xyzw vf07, 969(vi00) | nop 136 + lq_buffer(Mask::xyzw, vu.vf07, 969); + // iaddiu vi08, vi00, 0x3d2 | nop 137 + vu.vi08 = 0x3d2; /* 977 */ + // sq.xyzw vf07, 6(vi09) | nop 138 + sq_buffer(Mask::xyzw, vu.vf07, vu.vi09 + 6); + // xgkick vi09 | nop 139 + xgkick(vu.vi09); + // lq.xyzw vf07, 981(vi00) | nop 140 + lq_buffer(Mask::xyzw, vu.vf07, 981); + // xgkick vi08 | nop 141 + xgkick(vu.vi08); + // sq.xyzw vf07, 6(vi09) | nop 142 + sq_buffer(Mask::xyzw, vu.vf07, vu.vi09 + 6); + // iaddi vi08, vi09, 0x6 | nop 143 + vu.vi08 = vu.vi09 + 6; + // nop | nop 144 + + // xgkick vi08 | nop 145 + xgkick(vu.vi08); + // iaddiu vi08, vi00, 0x3d6 | nop 146 + vu.vi08 = 0x3d6; /* 981 */ + // nop | nop 147 + + // xgkick vi08 | nop 148 + xgkick(vu.vi08); + // BRANCH! + // bal vi15, L21 | nop 149 + // ASSERT(false); + // iaddiu vi08, vi09, 0x44 | nop 150 + vu.vi08 = vu.vi09 + 0x44; /* 68 */ + // if (bc) { goto L21; } + run_L21_vu2c_jak2(); + + // BRANCH! + // ibeq vi00, vi14, L10 | nop 151 + bc = (vu.vi14 == 0); + // nop | nop 152 + + if (bc) { + goto L10; + } + + // BRANCH! + // bal vi15, L25 | nop 153 + // ASSERT(false); + // nop | nop 154 + + // if (bc) { goto L25; } + run_L25_vu2c_jak2(); + +L10: + // BRANCH! + // bal vi15, L23 | nop 155 + // ASSERT(false); + // iaddiu vi08, vi09, 0x44 | nop 156 + vu.vi08 = vu.vi09 + 0x44; /* 68 */ + // if (bc) { goto L23; } + run_L23_vu2c(); + + // iaddiu vi08, vi09, 0x3d | nop 157 + vu.vi08 = vu.vi09 + 0x3d; /* 61 */ + // iaddiu vi01, vi00, 0x4b2 | nop 158 + vu.vi01 = 0x4b2; /* 1202 */ + // xgkick vi08 | nop 159 + xgkick(vu.vi08); + // isub vi09, vi01, vi09 | nop 160 + vu.vi09 = vu.vi01 - vu.vi09; +L11: + // BRANCH! + // ibgtz vi07, L9 | nop 161 + bc = ((s16)vu.vi07) > 0; + // iaddi vi07, vi07, -0x1 | nop 162 + vu.vi07 = vu.vi07 + -1; + if (bc) { + goto L9; + } + + // lq.xyzw vf04, 9(vi02) | nop 163 + lq_buffer(Mask::xyzw, vu.vf04, vu.vi02 + 9); + // iaddi vi07, vi00, 0x3 | nop 164 + vu.vi07 = 3; +L12: + // mtir vi10, vf04.x | nop 165 + vu.vi10 = vu.vf04.x_as_u16(); + // iaddiu vi11, vi00, 0xff | nop 166 + vu.vi11 = 0xff; /* 255 */ + // mr32.xyzw vf04, vf04 | nop 167 + vu.vf04.mr32(Mask::xyzw, vu.vf04); + // BRANCH! + // ibeq vi11, vi10, L14 | nop 168 + bc = (vu.vi11 == vu.vi10); + // lq.xyzw vf11, 3(vi02) | nop 169 + lq_buffer(Mask::xyzw, vu.vf11, vu.vi02 + 3); + if (bc) { + goto L14; + } + + // lq.xyzw vf12, 4(vi02) | nop 170 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi02 + 4); + // lq.xyzw vf13, 5(vi02) | nop 171 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi02 + 5); + // lq.xyzw vf14, 6(vi02) | nop 172 + lq_buffer(Mask::xyzw, vu.vf14, vu.vi02 + 6); + // lq.xyzw vf15, 7(vi02) | nop 173 + lq_buffer(Mask::xyzw, vu.vf15, vu.vi02 + 7); + // ilw.y vi05, 984(vi07) | nop 174 + ilw_buffer(Mask::y, vu.vi05, vu.vi07 + 984); + // BRANCH! + // bal vi15, L15 | nop 175 + // ASSERT(false); + // iaddi vi08, vi09, 0x7 | nop 176 + vu.vi08 = vu.vi09 + 7; + // if (bc) { goto L15; } + run_L15_vu2c_jak2(); + + // lq.xyzw vf07, 969(vi00) | nop 177 + lq_buffer(Mask::xyzw, vu.vf07, 969); + // iaddiu vi08, vi00, 0x3d1 | nop 178 + vu.vi08 = 0x3d2; /* 977 */ + // sq.xyzw vf07, 6(vi09) | nop 179 + sq_buffer(Mask::xyzw, vu.vf07, vu.vi09 + 6); + // xgkick vi09 | nop 180 + xgkick(vu.vi09); + // lq.xyzw vf07, 981(vi00) | nop 181 + lq_buffer(Mask::xyzw, vu.vf07, 981); + // xgkick vi08 | nop 182 + xgkick(vu.vi08); + // sq.xyzw vf07, 6(vi09) | nop 183 + sq_buffer(Mask::xyzw, vu.vf07, vu.vi09 + 6); + // iaddi vi08, vi09, 0x6 | nop 184 + vu.vi08 = vu.vi09 + 6; + // nop | nop 185 + + // xgkick vi08 | nop 186 + xgkick(vu.vi08); + // iaddiu vi08, vi00, 0x3d6 | nop 187 + vu.vi08 = 0x3d6; /* 981 */ + // nop | nop 188 + + // xgkick vi08 | nop 189 + xgkick(vu.vi08); + // BRANCH! + // bal vi15, L21 | nop 190 + // ASSERT(false); + // iaddiu vi08, vi09, 0x44 | nop 191 + vu.vi08 = vu.vi09 + 0x44; /* 68 */ + // if (bc) { goto L21; } + run_L21_vu2c_jak2(); + + // BRANCH! + // ibeq vi00, vi14, L13 | nop 192 + bc = (vu.vi14 == 0); + // nop | nop 193 + + if (bc) { + goto L13; + } + + // BRANCH! + // bal vi15, L25 | nop 194 + // ASSERT(false); + // nop | nop 195 + + // if (bc) { goto L25; } + run_L25_vu2c_jak2(); + +L13: + // BRANCH! + // bal vi15, L23 | nop 196 + // ASSERT(false); + // iaddiu vi08, vi09, 0x44 | nop 197 + vu.vi08 = vu.vi09 + 0x44; /* 68 */ + // if (bc) { goto L23; } + run_L23_vu2c(); + + // iaddiu vi08, vi09, 0x3d | nop 198 + vu.vi08 = vu.vi09 + 0x3d; /* 61 */ + // iaddiu vi01, vi00, 0x4b2 | nop 199 + vu.vi01 = 0x4b2; /* 1202 */ + // nop | nop 200 + + // xgkick vi08 | nop 201 + xgkick(vu.vi08); + // isub vi09, vi01, vi09 | nop 202 + vu.vi09 = vu.vi01 - vu.vi09; +L14: + // BRANCH! + // ibgtz vi07, L12 | nop 203 + bc = ((s16)vu.vi07) > 0; + // iaddi vi07, vi07, -0x1 | nop 204 + vu.vi07 = vu.vi07 + -1; + if (bc) { + goto L12; + } + + // nop | nop :e 205 + + // nop | nop 206 +} + static inline REALLY_INLINE float eleng(const Vf& in) { float len = in.x() * in.x() + in.y() * in.y() + in.z() * in.z(); return std::sqrt(len); @@ -1193,6 +1750,587 @@ L20: // nop | nop 397 } +void OceanNear::run_L15_vu2c_jak2() { + u32 cf; + bool bc; + // iaddi vi01, vi05, 0x9 | nop 207 + vu.vi01 = vu.vi05 + 9; + // lq.xyzw vf24, 290(vi05) | nop 208 + lq_buffer(Mask::xyzw, vu.vf24, vu.vi05 + 290); + // lq.xyzw vf25, 317(vi05) | nop 209 + lq_buffer(Mask::xyzw, vu.vf25, vu.vi05 + 317); + // lq.xyzw vf05, 959(vi00) | mulax.xyzw ACC, vf08, vf24 210 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf24.x()); + lq_buffer(Mask::xyzw, vu.vf05, 959); + // iaddi vi05, vi05, 0x3 | madday.xyzw ACC, vf09, vf24 211 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf24.y()); + vu.vi05 = vu.vi05 + 3; + // isw.x vi01, 988(vi00) | nop 212 + isw_buffer(Mask::x, vu.vi01, 988); + // iaddi vi01, vi00, 0x0 | maddaz.xyzw ACC, vf10, vf24 213 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf24.z()); + vu.vi01 = 0; + // iaddi vi13, vi00, 0x0 | maddw.xyzw vf26, vf11, vf00 214 + vu.acc.madd(Mask::xyzw, vu.vf26, vu.vf11, vu.vf00.w()); + vu.vi13 = 0; + // iaddi vi11, vi00, 0x0 | mulax.xyzw ACC, vf08, vf25 215 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf25.x()); + vu.vi11 = 0; + // fcset 0x0 | madday.xyzw ACC, vf09, vf25 216 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf25.y()); + cf = 0x0; + + // lq.xyzw vf28, 287(vi05) | maddaz.xyzw ACC, vf10, vf25 217 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf25.z()); + lq_buffer(Mask::xyzw, vu.vf28, vu.vi05 + 287); + // eleng.xyz P, vf26 | maddw.xyzw vf27, vf11, vf00 218 + vu.acc.madd(Mask::xyzw, vu.vf27, vu.vf11, vu.vf00.w()); + vu.P = eleng(vu.vf26); + // iaddi vi14, vi00, 0x0 | mulw.xyzw vf20, vf26, vf00 219 + vu.vf20.mul(Mask::xyzw, vu.vf26, vu.vf00.w()); + vu.vi14 = 0; + // lq.xyzw vf22, 286(vi05) | nop 220 + lq_buffer(Mask::xyzw, vu.vf22, vu.vi05 + 286); + // waitp | nop 221 + // ASSERT(false); + // mfp.w vf20, P | nop 222 + vu.vf20.mfp(Mask::w, vu.P); + // eleng.xyz P, vf27 | mulw.xyzw vf21, vf27, vf00 223 + vu.vf21.mul(Mask::xyzw, vu.vf27, vu.vf00.w()); + vu.P = eleng(vu.vf27); + // lq.xyzw vf07, 958(vi00) | nop 224 + lq_buffer(Mask::xyzw, vu.vf07, 958); + // nop | nop 225 + + // iaddi vi12, vi00, 0x1 | mulw.w vf22, vf20, vf05 226 + vu.vf22.mul(Mask::w, vu.vf20, vu.vf05.w()); + vu.vi12 = 1; + // nop | nop 227 + + // nop | nop 228 + + // nop | nop 229 + + // nop | miniw.w vf22, vf22, vf00 230 + vu.vf22.mini(Mask::w, vu.vf22, vu.vf00.w()); + // nop | nop 231 + + // nop | nop 232 + + // nop | nop 233 + + // nop | subw.w vf28, vf00, vf22 234 + vu.vf28.sub(Mask::w, vu.vf00, vu.vf22.w()); + // nop | maxx.w vf22, vf22, vf05 235 + vu.vf22.max(Mask::w, vu.vf22, vu.vf05.x()); + // nop | nop 236 + + // nop | mulaz.w ACC, vf00, vf07 237 + vu.acc.mula(Mask::w, vu.vf00, vu.vf07.z()); + // nop | mulw.y vf28, vf28, vf28 238 + vu.vf28.mul(Mask::y, vu.vf28, vu.vf28.w()); + // lq.xyzw vf24, 290(vi05) | msubx.w vf07, vf22, vf07 239 + vu.acc.msub(Mask::w, vu.vf07, vu.vf22, vu.vf07.x()); + lq_buffer(Mask::xyzw, vu.vf24, vu.vi05 + 290); + // nop | mulax.xyzw ACC, vf12, vf28 240 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf28.x()); + // nop | madday.xyzw ACC, vf13, vf28 241 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf28.y()); + // nop | maddaz.xyzw ACC, vf14, vf28 242 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf28.z()); + // nop | maddw.xyzw vf30, vf15, vf00 243 + vu.acc.madd(Mask::xyzw, vu.vf30, vu.vf15, vu.vf00.w()); + // nop | mulax.xyzw ACC, vf08, vf24 244 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf24.x()); + // nop | madday.xyzw ACC, vf09, vf24 245 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf24.y()); + // nop | maddaz.xyzw ACC, vf10, vf24 246 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf24.z()); + // nop | maddw.xyzw vf26, vf11, vf00 247 + vu.acc.madd(Mask::xyzw, vu.vf26, vu.vf11, vu.vf00.w()); + // div Q, vf03.x, vf30.w | mul.xyzw vf18, vf30, vf01 248 + vu.vf18.mul(Mask::xyzw, vu.vf30, vu.vf01); + vu.Q = vu.vf03.x() / vu.vf30.w(); + // lq.xyzw vf23, 313(vi05) | mulw.w vf22, vf22, vf06 249 + vu.vf22.mul(Mask::w, vu.vf22, vu.vf06.w()); + lq_buffer(Mask::xyzw, vu.vf23, vu.vi05 + 313); + // waitp | mulw.xyz vf22, vf22, vf07 250 + vu.vf22.mul(Mask::xyz, vu.vf22, vu.vf07.w()); + // mfp.w vf21, P | nop 251 + vu.vf21.mfp(Mask::w, vu.P); + // eleng.xyz P, vf26 | nop 252 + vu.P = eleng(vu.vf26); + // nop | clipw.xyz vf18, vf18 253 + cf = clip(vu.vf18, vu.vf18.w(), cf); + // nop | mulaw.w ACC, vf30, vf00 254 + vu.acc.mula(Mask::w, vu.vf30, vu.vf00.w()); + // lq.xyzw vf29, 314(vi05) | mulw.w vf23, vf21, vf05 255 + vu.vf23.mul(Mask::w, vu.vf21, vu.vf05.w()); + lq_buffer(Mask::xyzw, vu.vf29, vu.vi05 + 314); + // nop | mula.xyz ACC, vf30, Q 256 + vu.acc.mula(Mask::xyz, vu.vf30, vu.Q); + // nop | maddw.xyzw vf16, vf02, vf00 257 + vu.acc.madd(Mask::xyzw, vu.vf16, vu.vf02, vu.vf00.w()); + // nop | miniy.xyzw vf22, vf22, vf07 258 + vu.vf22.mini(Mask::xyzw, vu.vf22, vu.vf07.y()); + // nop | miniw.w vf23, vf23, vf00 259 + vu.vf23.mini(Mask::w, vu.vf23, vu.vf00.w()); + // nop | nop 260 + + // nop | miniz.w vf16, vf16, vf03 261 + vu.vf16.mini(Mask::w, vu.vf16, vu.vf03.z()); + // nop | ftoi0.xyzw vf22, vf22 262 + vu.vf22.ftoi0(Mask::xyzw, vu.vf22); + // waitp | subw.w vf29, vf00, vf23 263 + vu.vf29.sub(Mask::w, vu.vf00, vu.vf23.w()); + // BRANCH! + // b L18 | maxx.w vf23, vf23, vf05 264 + vu.vf23.max(Mask::w, vu.vf23, vu.vf05.x()); + bc = true; + // iaddi vi06, vi00, 0x8 | maxy.w vf16, vf16, vf03 265 + vu.vf16.max(Mask::w, vu.vf16, vu.vf03.y()); + vu.vi06 = 8; + if (bc) { + goto L18; + } + +L16: + // BRANCH! + // ibeq vi00, vi01, L17 | nop 266 + bc = (vu.vi01 == 0); + // lq.xyzw vf26, 309(vi05) | nop 267 + lq_buffer(Mask::xyzw, vu.vf26, vu.vi05 + 309); + if (bc) { + goto L17; + } + + // BRANCH! + // ibne vi00, vi13, L17 | addw.w vf17, vf17, vf03 268 + vu.vf17.add(Mask::w, vu.vf17, vu.vf03.w()); + bc = (vu.vi13 != 0); + // fcor vi01, 0xfdf7df | nop 269 + fcor(vu.vi01, 0xfdf7df, cf); + + if (bc) { + goto L17; + } + + // isw.x vi12, 989(vi14) | nop 270 + isw_buffer(Mask::x, vu.vi12, vu.vi14 + 989); + // BRANCH! + // ibne vi00, vi01, L17 | nop 271 + bc = (vu.vi01 != 0); + // fcor vi01, 0xff7df7 | nop 272 + fcor(vu.vi01, 0xff7df7, cf); + + if (bc) { + goto L17; + } + + // isw.y vi05, 989(vi14) | nop 273 + isw_buffer(Mask::y, vu.vi05, vu.vi14 + 989); + // BRANCH! + // ibne vi00, vi01, L17 | nop 274 + bc = (vu.vi01 != 0); + // fcor vi01, 0xffbefb | nop 275 + fcor(vu.vi01, 0xffbefb, cf); + + if (bc) { + goto L17; + } + + // ilw.x vi11, 988(vi00) | nop 276 + ilw_buffer(Mask::x, vu.vi11, 988); + // BRANCH! + // ibne vi00, vi01, L17 | nop 277 + bc = (vu.vi01 != 0); + // fcor vi01, 0xffdf7d | nop 278 + fcor(vu.vi01, 0xffdf7d, cf); + + if (bc) { + goto L17; + } + + // isw.z vi08, 989(vi14) | nop 279 + isw_buffer(Mask::z, vu.vi08, vu.vi14 + 989); + // BRANCH! + // ibne vi00, vi01, L17 | nop 280 + bc = (vu.vi01 != 0); + // fcor vi01, 0xffefbe | nop 281 + fcor(vu.vi01, 0xffefbe, cf); + + if (bc) { + goto L17; + } + + // isub vi11, vi05, vi11 | nop 282 + vu.vi11 = vu.vi05 - vu.vi11; + // BRANCH! + // ibne vi00, vi01, L17 | nop 283 + bc = (vu.vi01 != 0); + // nop | nop 284 + + if (bc) { + goto L17; + } + + // BRANCH! + // ibltz vi11, L17 | nop 285 + bc = ((s16)vu.vi11) < 0; + // nop | nop 286 + + if (bc) { + goto L17; + } + + // iaddi vi14, vi14, 0x1 | nop 287 + vu.vi14 = vu.vi14 + 1; +L17: + // nop | mulw.y vf28, vf28, vf28 288 + vu.vf28.mul(Mask::y, vu.vf28, vu.vf28.w()); + // nop | mulaz.w ACC, vf00, vf07 289 + vu.acc.mula(Mask::w, vu.vf00, vu.vf07.z()); + // nop | msubx.w vf07, vf22, vf07 290 + vu.acc.msub(Mask::w, vu.vf07, vu.vf22, vu.vf07.x()); + // nop | ftoi4.xyzw vf17, vf17 291 + vu.vf17.ftoi4(Mask::xyzw, vu.vf17); + // lq.xyzw vf24, 290(vi05) | mul.xyzw vf26, vf26, Q 292 + vu.vf26.mul(Mask::xyzw, vu.vf26, vu.Q); + lq_buffer(Mask::xyzw, vu.vf24, vu.vi05 + 290); + // sq.xyzw vf21, 64(vi08) | mulax.xyzw ACC, vf12, vf28 293 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf28.x()); + sq_buffer(Mask::xyzw, vu.vf21, vu.vi08 + 64); + // sq.xyzw vf23, 4(vi08) | madday.xyzw ACC, vf13, vf28 294 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf28.y()); + sq_buffer(Mask::xyzw, vu.vf23, vu.vi08 + 4); + // sq.xyzw vf17, 5(vi08) | maddaz.xyzw ACC, vf14, vf28 295 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf28.z()); + sq_buffer(Mask::xyzw, vu.vf17, vu.vi08 + 5); + // sq.xyzw vf19, 66(vi08) | maddw.xyzw vf30, vf15, vf00 296 + vu.acc.madd(Mask::xyzw, vu.vf30, vu.vf15, vu.vf00.w()); + sq_buffer(Mask::xyzw, vu.vf19, vu.vi08 + 66); + // sq.xyzw vf26, 3(vi08) | mulax.xyzw ACC, vf08, vf24 297 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf24.x()); + sq_buffer(Mask::xyzw, vu.vf26, vu.vi08 + 3); + // nop | madday.xyzw ACC, vf09, vf24 298 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf24.y()); + // nop | maddaz.xyzw ACC, vf10, vf24 299 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf24.z()); + // nop | maddw.xyzw vf26, vf11, vf00 300 + vu.acc.madd(Mask::xyzw, vu.vf26, vu.vf11, vu.vf00.w()); + // div Q, vf03.x, vf30.w | mul.xyzw vf18, vf30, vf01 301 + vu.vf18.mul(Mask::xyzw, vu.vf30, vu.vf01); + vu.Q = vu.vf03.x() / vu.vf30.w(); + // lq.xyzw vf23, 313(vi05) | mulw.xyz vf21, vf27, vf00 302 + vu.vf21.mul(Mask::xyz, vu.vf27, vu.vf00.w()); + lq_buffer(Mask::xyzw, vu.vf23, vu.vi05 + 313); + // mfp.w vf21, P | mulw.w vf22, vf22, vf06 303 + vu.vf22.mul(Mask::w, vu.vf22, vu.vf06.w()); + vu.vf21.mfp(Mask::w, vu.P); + // eleng.xyz P, vf26 | mulw.xyz vf22, vf22, vf07 304 + vu.vf22.mul(Mask::xyz, vu.vf22, vu.vf07.w()); + vu.P = eleng(vu.vf26); + // iaddi vi08, vi08, 0x6 | clipw.xyz vf18, vf18 305 + cf = clip(vu.vf18, vu.vf18.w(), cf); + vu.vi08 = vu.vi08 + 6; + // nop | mulaw.w ACC, vf30, vf00 306 + vu.acc.mula(Mask::w, vu.vf30, vu.vf00.w()); + // nop | mulw.w vf23, vf21, vf05 307 + vu.vf23.mul(Mask::w, vu.vf21, vu.vf05.w()); + // iand vi13, vi10, vi12 | mula.xyz ACC, vf30, Q 308 + vu.acc.mula(Mask::xyz, vu.vf30, vu.Q); + vu.vi13 = vu.vi10 & vu.vi12; + // fcand vi01, 0x3ffff | maddw.xyzw vf16, vf02, vf00 309 + vu.acc.madd(Mask::xyzw, vu.vf16, vu.vf02, vu.vf00.w()); + fcand(vu.vi01, 0x3ffff, cf); + + // iadd vi12, vi12, vi12 | miniy.xyzw vf22, vf22, vf07 310 + vu.vf22.mini(Mask::xyzw, vu.vf22, vu.vf07.y()); + vu.vi12 = vu.vi12 + vu.vi12; + // lq.xyzw vf29, 314(vi05) | miniw.w vf23, vf23, vf00 311 + vu.vf23.mini(Mask::w, vu.vf23, vu.vf00.w()); + lq_buffer(Mask::xyzw, vu.vf29, vu.vi05 + 314); + // nop | nop 312 + + // ior vi01, vi01, vi13 | miniz.w vf16, vf16, vf03 313 + vu.vf16.mini(Mask::w, vu.vf16, vu.vf03.z()); + vu.vi01 = vu.vi01 | vu.vi13; + // nop | ftoi0.xyzw vf22, vf22 314 + vu.vf22.ftoi0(Mask::xyzw, vu.vf22); + // nop | subw.w vf29, vf00, vf23 315 + vu.vf29.sub(Mask::w, vu.vf00, vu.vf23.w()); + // nop | maxx.w vf23, vf23, vf05 316 + vu.vf23.max(Mask::w, vu.vf23, vu.vf05.x()); + // nop | maxy.w vf16, vf16, vf03 317 + vu.vf16.max(Mask::w, vu.vf16, vu.vf03.y()); + // nop | nop 318 + +L18: + // BRANCH! + // ibeq vi00, vi01, L19 | nop 319 + bc = (vu.vi01 == 0); + // lq.xyzw vf27, 285(vi05) | nop 320 + lq_buffer(Mask::xyzw, vu.vf27, vu.vi05 + 285); + if (bc) { + goto L19; + } + + // BRANCH! + // ibne vi00, vi13, L19 | addw.w vf16, vf16, vf03 321 + vu.vf16.add(Mask::w, vu.vf16, vu.vf03.w()); + bc = (vu.vi13 != 0); + // fcor vi01, 0xfdf7df | nop 322 + fcor(vu.vi01, 0xfdf7df, cf); + + if (bc) { + goto L19; + } + + // isw.x vi00, 989(vi14) | nop 323 + isw_buffer(Mask::x, 0, vu.vi14 + 989); + // BRANCH! + // ibne vi00, vi01, L19 | nop 324 + bc = (vu.vi01 != 0); + // fcor vi01, 0xff7df7 | nop 325 + fcor(vu.vi01, 0xff7df7, cf); + + if (bc) { + goto L19; + } + + // isw.y vi05, 989(vi14) | nop 326 + isw_buffer(Mask::y, vu.vi05, vu.vi14 + 989); + // BRANCH! + // ibne vi00, vi01, L19 | nop 327 + bc = (vu.vi01 != 0); + // fcor vi01, 0xffbefb | nop 328 + fcor(vu.vi01, 0xffbefb, cf); + + if (bc) { + goto L19; + } + + // isw.z vi08, 989(vi14) | nop 329 + isw_buffer(Mask::z, vu.vi08, vu.vi14 + 989); + // BRANCH! + // ibne vi00, vi01, L19 | nop 330 + bc = (vu.vi01 != 0); + // fcor vi01, 0xffdf7d | nop 331 + fcor(vu.vi01, 0xffdf7d, cf); + + if (bc) { + goto L19; + } + + // nop | nop 332 + + // BRANCH! + // ibne vi00, vi01, L19 | nop 333 + bc = (vu.vi01 != 0); + // fcor vi01, 0xffefbe | nop 334 + fcor(vu.vi01, 0xffefbe, cf); + + if (bc) { + goto L19; + } + + // nop | nop 335 + + // BRANCH! + // ibne vi00, vi01, L19 | nop 336 + bc = (vu.vi01 != 0); + // nop | nop 337 + + if (bc) { + goto L19; + } + + // iaddi vi14, vi14, 0x1 | nop 338 + vu.vi14 = vu.vi14 + 1; +L19: + // nop | mulw.y vf29, vf29, vf29 339 + vu.vf29.mul(Mask::y, vu.vf29, vu.vf29.w()); + // nop | mulaz.w ACC, vf00, vf07 340 + vu.acc.mula(Mask::w, vu.vf00, vu.vf07.z()); + // nop | msubx.w vf07, vf23, vf07 341 + vu.acc.msub(Mask::w, vu.vf07, vu.vf23, vu.vf07.x()); + // nop | ftoi4.xyzw vf16, vf16 342 + vu.vf16.ftoi4(Mask::xyzw, vu.vf16); + // lq.xyzw vf25, 317(vi05) | mul.xyzw vf27, vf27, Q 343 + vu.vf27.mul(Mask::xyzw, vu.vf27, vu.Q); + lq_buffer(Mask::xyzw, vu.vf25, vu.vi05 + 317); + // sq.xyzw vf20, 61(vi08) | mulax.xyzw ACC, vf12, vf29 344 + vu.acc.mula(Mask::xyzw, vu.vf12, vu.vf29.x()); + sq_buffer(Mask::xyzw, vu.vf20, vu.vi08 + 61); + // sq.xyzw vf22, 1(vi08) | madday.xyzw ACC, vf13, vf29 345 + vu.acc.madda(Mask::xyzw, vu.vf13, vu.vf29.y()); + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 1); + // sq.xyzw vf16, 2(vi08) | maddaz.xyzw ACC, vf14, vf29 346 + vu.acc.madda(Mask::xyzw, vu.vf14, vu.vf29.z()); + sq_buffer(Mask::xyzw, vu.vf16, vu.vi08 + 2); + // sq.xyzw vf18, 63(vi08) | maddw.xyzw vf31, vf15, vf00 347 + vu.acc.madd(Mask::xyzw, vu.vf31, vu.vf15, vu.vf00.w()); + sq_buffer(Mask::xyzw, vu.vf18, vu.vi08 + 63); + // sq.xyzw vf27, 0(vi08) | mulax.xyzw ACC, vf08, vf25 348 + vu.acc.mula(Mask::xyzw, vu.vf08, vu.vf25.x()); + sq_buffer(Mask::xyzw, vu.vf27, vu.vi08); + // nop | madday.xyzw ACC, vf09, vf25 349 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf25.y()); + // iaddi vi05, vi05, 0x3 | maddaz.xyzw ACC, vf10, vf25 350 + vu.acc.madda(Mask::xyzw, vu.vf10, vu.vf25.z()); + vu.vi05 = vu.vi05 + 3; + // nop | maddw.xyzw vf27, vf11, vf00 351 + vu.acc.madd(Mask::xyzw, vu.vf27, vu.vf11, vu.vf00.w()); + // div Q, vf03.x, vf31.w | mul.xyzw vf19, vf31, vf01 352 + vu.vf19.mul(Mask::xyzw, vu.vf31, vu.vf01); + vu.Q = vu.vf03.x() / vu.vf31.w(); + // lq.xyzw vf22, 286(vi05) | mulw.xyz vf20, vf26, vf00 353 + vu.vf20.mul(Mask::xyz, vu.vf26, vu.vf00.w()); + lq_buffer(Mask::xyzw, vu.vf22, vu.vi05 + 286); + // mfp.w vf20, P | mulw.w vf23, vf23, vf06 354 + vu.vf23.mul(Mask::w, vu.vf23, vu.vf06.w()); + vu.vf20.mfp(Mask::w, vu.P); + // eleng.xyz P, vf27 | mulw.xyz vf23, vf23, vf07 355 + vu.vf23.mul(Mask::xyz, vu.vf23, vu.vf07.w()); + vu.P = eleng(vu.vf27); + // nop | clipw.xyz vf19, vf19 356 + cf = clip(vu.vf19, vu.vf19.w(), cf); + // nop | mulaw.w ACC, vf31, vf00 357 + vu.acc.mula(Mask::w, vu.vf31, vu.vf00.w()); + // nop | mulw.w vf22, vf20, vf05 358 + vu.vf22.mul(Mask::w, vu.vf20, vu.vf05.w()); + // nop | mula.xyz ACC, vf31, Q 359 + vu.acc.mula(Mask::xyz, vu.vf31, vu.Q); + // fcand vi01, 0x3ffff | maddw.xyzw vf17, vf02, vf00 360 + vu.acc.madd(Mask::xyzw, vu.vf17, vu.vf02, vu.vf00.w()); + fcand(vu.vi01, 0x3ffff, cf); + + // nop | miniy.xyzw vf23, vf23, vf07 361 + vu.vf23.mini(Mask::xyzw, vu.vf23, vu.vf07.y()); + // lq.xyzw vf28, 287(vi05) | miniw.w vf22, vf22, vf00 362 + vu.vf22.mini(Mask::w, vu.vf22, vu.vf00.w()); + lq_buffer(Mask::xyzw, vu.vf28, vu.vi05 + 287); + // nop | nop 363 + + // ior vi01, vi01, vi13 | miniz.w vf17, vf17, vf03 364 + vu.vf17.mini(Mask::w, vu.vf17, vu.vf03.z()); + vu.vi01 = vu.vi01 | vu.vi13; + // nop | ftoi0.xyzw vf23, vf23 365 + vu.vf23.ftoi0(Mask::xyzw, vu.vf23); + // nop | subw.w vf28, vf00, vf22 366 + vu.vf28.sub(Mask::w, vu.vf00, vu.vf22.w()); + // nop | maxx.w vf22, vf22, vf05 367 + vu.vf22.max(Mask::w, vu.vf22, vu.vf05.x()); + // BRANCH! + // ibgtz vi06, L16 | maxy.w vf17, vf17, vf03 368 + vu.vf17.max(Mask::w, vu.vf17, vu.vf03.y()); + bc = ((s16)vu.vi06) > 0; + // iaddi vi06, vi06, -0x1 | nop 369 + vu.vi06 = vu.vi06 + -1; + if (bc) { + goto L16; + } + + // BRANCH! + // ibeq vi00, vi01, L20 | nop 370 + bc = (vu.vi01 == 0); + // lq.xyzw vf26, 309(vi05) | nop 371 + lq_buffer(Mask::xyzw, vu.vf26, vu.vi05 + 309); + if (bc) { + goto L20; + } + + // BRANCH! + // ibne vi00, vi13, L20 | addw.w vf17, vf17, vf03 372 + vu.vf17.add(Mask::w, vu.vf17, vu.vf03.w()); + bc = (vu.vi13 != 0); + // fcor vi01, 0xfdf7df | nop 373 + fcor(vu.vi01, 0xfdf7df, cf); + + if (bc) { + goto L20; + } + + // isw.x vi12, 989(vi14) | nop 374 + isw_buffer(Mask::x, vu.vi12, vu.vi14 + 989); + // BRANCH! + // ibne vi00, vi01, L20 | nop 375 + bc = (vu.vi01 != 0); + // fcor vi01, 0xff7df7 | nop 376 + fcor(vu.vi01, 0xff7df7, cf); + + if (bc) { + goto L20; + } + + // isw.y vi05, 989(vi14) | nop 377 + isw_buffer(Mask::y, vu.vi05, vu.vi14 + 989); + // BRANCH! + // ibne vi00, vi01, L20 | nop 378 + bc = (vu.vi01 != 0); + // fcor vi01, 0xffbefb | nop 379 + fcor(vu.vi01, 0xffbefb, cf); + + if (bc) { + goto L20; + } + + // isw.z vi08, 989(vi14) | nop 380 + isw_buffer(Mask::z, vu.vi08, vu.vi14 + 989); + // BRANCH! + // ibne vi00, vi01, L20 | nop 381 + bc = (vu.vi01 != 0); + // fcor vi01, 0xffdf7d | nop 382 + fcor(vu.vi01, 0xffdf7d, cf); + + if (bc) { + goto L20; + } + + // nop | nop 383 + + // BRANCH! + // ibne vi00, vi01, L20 | nop 384 + bc = (vu.vi01 != 0); + // fcor vi01, 0xffefbe | nop 385 + fcor(vu.vi01, 0xffefbe, cf); + + if (bc) { + goto L20; + } + + // nop | nop 386 + + // BRANCH! + // ibne vi00, vi01, L20 | nop 387 + bc = (vu.vi01 != 0); + // nop | nop 388 + + if (bc) { + goto L20; + } + + // iaddi vi14, vi14, 0x1 | nop 389 + vu.vi14 = vu.vi14 + 1; +L20: + // isw.y vi14, 988(vi00) | ftoi4.xyzw vf17, vf17 390 + vu.vf17.ftoi4(Mask::xyzw, vu.vf17); + isw_buffer(Mask::y, vu.vi14, 988); + // sq.xyzw vf21, 64(vi08) | mul.xyzw vf26, vf26, Q 391 + vu.vf26.mul(Mask::xyzw, vu.vf26, vu.Q); + sq_buffer(Mask::xyzw, vu.vf21, vu.vi08 + 64); + // sq.xyzw vf23, 4(vi08) | nop 392 + sq_buffer(Mask::xyzw, vu.vf23, vu.vi08 + 4); + // sq.xyzw vf17, 5(vi08) | nop 393 + sq_buffer(Mask::xyzw, vu.vf17, vu.vi08 + 5); + // sq.xyzw vf19, 66(vi08) | nop 394 + sq_buffer(Mask::xyzw, vu.vf19, vu.vi08 + 66); + // sq.xyzw vf26, 3(vi08) | nop 395 + sq_buffer(Mask::xyzw, vu.vf26, vu.vi08 + 3); + // jr vi15 | nop 396 + // nop | nop 397 +} + void OceanNear::run_L21_vu2c() { bool bc; // iaddi vi06, vi00, 0x5 | nop 398 @@ -1298,6 +2436,113 @@ L22: // nop | nop 442 } +void OceanNear::run_L21_vu2c_jak2() { + bool bc; + // lq.xyzw vf05, 955(vi00) | nop 398 + lq_buffer(Mask::xyzw, vu.vf05, 955); + // iaddi vi06, vi00, 0x5 | nop 398 + vu.vi06 = 5; +L22: + // lq.xyzw vf20, 0(vi08) | nop 399 + lq_buffer(Mask::xyzw, vu.vf20, vu.vi08); + // lq.xyzw vf21, 3(vi08) | nop 400 + lq_buffer(Mask::xyzw, vu.vf21, vu.vi08 + 3); + // lq.xyzw vf18, 6(vi08) | nop 401 + lq_buffer(Mask::xyzw, vu.vf18, vu.vi08 + 6); + // lq.xyzw vf19, 9(vi08) | maxw.xyzw vf11, vf00, vf00 402 + vu.vf11.max(Mask::xyzw, vu.vf00, vu.vf00.w()); + lq_buffer(Mask::xyzw, vu.vf19, vu.vi08 + 9); + // div Q, vf00.w, vf20.w | nop 403 + vu.Q = vu.vf00.w() / vu.vf20.w(); + // nop | nop 404 + + // nop | nop 405 + + // nop | nop 406 + + // nop | nop 407 + + // nop | nop 408 + + // nop | nop 409 + + // div Q, vf00.w, vf21.w | mul.xy vf20, vf20, Q 410 + vu.vf20.mul(Mask::xy, vu.vf20, vu.Q); + vu.Q = vu.vf00.w() / vu.vf21.w(); + // nop | nop 411 + + // nop | nop 412 + + // nop | nop 413 + + // nop | nop 414 + + // nop | nop 415 + + // nop | nop 416 + + // div Q, vf00.w, vf18.w | mul.xy vf21, vf21, Q 417 + vu.vf21.mul(Mask::xy, vu.vf21, vu.Q); + vu.Q = vu.vf00.w() / vu.vf18.w(); + // nop | mula.xyzw ACC, vf20, vf05 418 + vu.acc.mula(Mask::xyzw, vu.vf20, vu.vf05); + // nop | maddw.xyzw vf20, vf06, vf00 419 + vu.acc.madd(Mask::xyzw, vu.vf20, vu.vf06, vu.vf00.w()); + // nop | nop 420 + + // nop | mula.xyzw ACC, vf21, vf05 421 + vu.acc.mula(Mask::xyzw, vu.vf21, vu.vf05); + // nop | maddw.xyzw vf21, vf06, vf00 422 + vu.acc.madd(Mask::xyzw, vu.vf21, vu.vf06, vu.vf00.w()); + // nop | nop 423 + + // div Q, vf00.w, vf19.w | mul.xy vf18, vf18, Q 424 + vu.vf18.mul(Mask::xy, vu.vf18, vu.Q); + vu.Q = vu.vf00.w() / vu.vf19.w(); + // nop | nop 425 + + // nop | nop 426 + + // nop | nop 427 + + // nop | nop 428 + + // nop | nop 429 + + // nop | nop 430 + + // sq.xyz vf20, 0(vi08) | mul.xy vf19, vf19, Q 431 + vu.vf19.mul(Mask::xy, vu.vf19, vu.Q); + sq_buffer(Mask::xyz, vu.vf20, vu.vi08); + // sq.xyz vf21, 3(vi08) | mula.xyzw ACC, vf18, vf05 432 + vu.acc.mula(Mask::xyzw, vu.vf18, vu.vf05); + sq_buffer(Mask::xyz, vu.vf21, vu.vi08 + 3); + // nop | maddw.xyzw vf18, vf06, vf00 433 + vu.acc.madd(Mask::xyzw, vu.vf18, vu.vf06, vu.vf00.w()); + // nop | nop 434 + + // nop | mula.xyzw ACC, vf19, vf05 435 + vu.acc.mula(Mask::xyzw, vu.vf19, vu.vf05); + // iaddi vi08, vi08, 0xc | maddw.xyzw vf19, vf06, vf00 436 + vu.acc.madd(Mask::xyzw, vu.vf19, vu.vf06, vu.vf00.w()); + vu.vi08 = vu.vi08 + 12; + // iaddi vi06, vi06, -0x1 | nop 437 + vu.vi06 = vu.vi06 + -1; + // sq.xyz vf18, -6(vi08) | nop 438 + sq_buffer(Mask::xyz, vu.vf18, vu.vi08 + -6); + // BRANCH! + // ibgtz vi06, L22 | nop 439 + bc = ((s16)vu.vi06) > 0; + // sq.xyz vf19, -3(vi08) | nop 440 + sq_buffer(Mask::xyz, vu.vf19, vu.vi08 + -3); + if (bc) { + goto L22; + } + + // jr vi15 | nop 441 + // nop | nop 442 +} + void OceanNear::run_L23_vu2c() { bool bc; // iaddi vi06, vi00, 0x4 | nop 443 @@ -1600,6 +2845,244 @@ L29: lq_buffer(Mask::xyzw, vu.vf10, vu.vi02 + 2); } +void OceanNear::run_L25_vu2c_jak2() { + bool bc; + // lq.xyzw vf31, 952(vi00) | nop 469 + lq_buffer(Mask::xyzw, vu.vf31, 952); + // iaddiu vi10, vi00, 0x32b | nop 470 + vu.vi10 = 0x32b; /* 811 */ +L26: + // iaddi vi14, vi14, -0x1 | nop 471 + vu.vi14 = vu.vi14 + -1; + // iaddi vi08, vi10, 0x7 | nop 472 + vu.vi08 = vu.vi10 + 7; + // ilw.x vi12, 989(vi14) | nop 473 + ilw_buffer(Mask::x, vu.vi12, vu.vi14 + 989); + // ilw.y vi05, 989(vi14) | nop 474 + ilw_buffer(Mask::y, vu.vi05, vu.vi14 + 989); + // BRANCH! + // ibne vi00, vi12, L27 | nop 475 + bc = (vu.vi12 != 0); + // ilw.z vi03, 989(vi14) | nop 476 + ilw_buffer(Mask::z, vu.vi03, vu.vi14 + 989); + if (bc) { + goto L27; + } + + // lq.xyzw vf20, 282(vi05) | nop 477 + lq_buffer(Mask::xyzw, vu.vf20, vu.vi05 + 282); + // lq.xyzw vf21, 309(vi05) | nop 478 + lq_buffer(Mask::xyzw, vu.vf21, vu.vi05 + 309); + // lq.xyzw vf18, 285(vi05) | nop 479 + lq_buffer(Mask::xyzw, vu.vf18, vu.vi05 + 285); + // lq.xyzw vf22, -5(vi03) | nop 480 + lq_buffer(Mask::xyzw, vu.vf22, vu.vi03 + -5); + // lq.xyzw vf23, -2(vi03) | nop 481 + lq_buffer(Mask::xyzw, vu.vf23, vu.vi03 + -2); + // lq.xyzw vf16, 1(vi03) | nop 482 + lq_buffer(Mask::xyzw, vu.vf16, vu.vi03 + 1); + // lq.xyzw vf08, 55(vi03) | nop 483 + lq_buffer(Mask::xyzw, vu.vf08, vu.vi03 + 55); + // lq.xyzw vf09, 58(vi03) | nop 484 + lq_buffer(Mask::xyzw, vu.vf09, vu.vi03 + 58); + // lq.xyzw vf10, 61(vi03) | nop 485 + lq_buffer(Mask::xyzw, vu.vf10, vu.vi03 + 61); + // lq.xyzw vf28, 57(vi03) | nop 486 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi03 + 57); + // lq.xyzw vf29, 60(vi03) | nop 487 + lq_buffer(Mask::xyzw, vu.vf29, vu.vi03 + 60); + // BRANCH! + // b L28 | nop 488 + bc = true; + // lq.xyzw vf30, 63(vi03) | nop 489 + lq_buffer(Mask::xyzw, vu.vf30, vu.vi03 + 63); + if (bc) { + goto L28; + } + +L27: + // lq.xyzw vf20, 306(vi05) | nop 490 + lq_buffer(Mask::xyzw, vu.vf20, vu.vi05 + 306); + // lq.xyzw vf21, 282(vi05) | nop 491 + lq_buffer(Mask::xyzw, vu.vf21, vu.vi05 + 282); + // lq.xyzw vf18, 309(vi05) | nop 492 + lq_buffer(Mask::xyzw, vu.vf18, vu.vi05 + 309); + // lq.xyzw vf22, -2(vi03) | nop 493 + lq_buffer(Mask::xyzw, vu.vf22, vu.vi03 + -2); + // lq.xyzw vf23, 1(vi03) | nop 494 + lq_buffer(Mask::xyzw, vu.vf23, vu.vi03 + 1); + // lq.xyzw vf16, 4(vi03) | nop 495 + lq_buffer(Mask::xyzw, vu.vf16, vu.vi03 + 4); + // lq.xyzw vf08, 58(vi03) | nop 496 + lq_buffer(Mask::xyzw, vu.vf08, vu.vi03 + 58); + // lq.xyzw vf09, 61(vi03) | nop 497 + lq_buffer(Mask::xyzw, vu.vf09, vu.vi03 + 61); + // lq.xyzw vf10, 64(vi03) | nop 498 + lq_buffer(Mask::xyzw, vu.vf10, vu.vi03 + 64); + // lq.xyzw vf28, 60(vi03) | nop 499 + lq_buffer(Mask::xyzw, vu.vf28, vu.vi03 + 60); + // lq.xyzw vf29, 63(vi03) | nop 500 + lq_buffer(Mask::xyzw, vu.vf29, vu.vi03 + 63); + // lq.xyzw vf30, 66(vi03) | nop 501 + lq_buffer(Mask::xyzw, vu.vf30, vu.vi03 + 66); +L28: + // sq.xyzw vf20, 0(vi08) | itof0.xyzw vf22, vf22 502 + vu.vf22.itof0(Mask::xyzw, vu.vf22); + sq_buffer(Mask::xyzw, vu.vf20, vu.vi08); + // sq.xyzw vf21, 3(vi08) | itof0.xyzw vf23, vf23 503 + vu.vf23.itof0(Mask::xyzw, vu.vf23); + sq_buffer(Mask::xyzw, vu.vf21, vu.vi08 + 3); + // sq.xyzw vf18, 6(vi08) | itof0.xyzw vf16, vf16 504 + vu.vf16.itof0(Mask::xyzw, vu.vf16); + sq_buffer(Mask::xyzw, vu.vf18, vu.vi08 + 6); + // sq.xyzw vf20, 9(vi08) | nop 505 + sq_buffer(Mask::xyzw, vu.vf20, vu.vi08 + 9); + // sq.xyzw vf22, 1(vi08) | nop 506 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 1); + // sq.xyzw vf23, 4(vi08) | nop 507 + sq_buffer(Mask::xyzw, vu.vf23, vu.vi08 + 4); + // sq.xyzw vf16, 7(vi08) | nop 508 + sq_buffer(Mask::xyzw, vu.vf16, vu.vi08 + 7); + // sq.xyzw vf22, 10(vi08) | nop 509 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 10); + // sq.xyzw vf28, 2(vi08) | nop 510 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 2); + // sq.xyzw vf29, 5(vi08) | nop 511 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi08 + 5); + // sq.xyzw vf30, 8(vi08) | nop 512 + sq_buffer(Mask::xyzw, vu.vf30, vu.vi08 + 8); + // sq.xyzw vf28, 11(vi08) | nop 513 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 11); + // lq.xyzw vf22, 977(vi00) | nop 514 + lq_buffer(Mask::xyzw, vu.vf22, 977); + // sq.xyzw vf08, 35(vi08) | nop 515 + sq_buffer(Mask::xyzw, vu.vf08, vu.vi08 + 35); + // sq.xyzw vf09, 38(vi08) | nop 516 + sq_buffer(Mask::xyzw, vu.vf09, vu.vi08 + 38); + // sq.xyzw vf10, 41(vi08) | nop 517 + sq_buffer(Mask::xyzw, vu.vf10, vu.vi08 + 41); + // sq.xyzw vf08, 44(vi08) | nop 518 + sq_buffer(Mask::xyzw, vu.vf08, vu.vi08 + 44); + // sq.xyzw vf22, 36(vi08) | nop 519 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 36); + // sq.xyzw vf22, 39(vi08) | nop 520 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 39); + // sq.xyzw vf22, 42(vi08) | nop 521 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 42); + // sq.xyzw vf22, 45(vi08) | nop 522 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi08 + 45); + // sq.xyzw vf28, 37(vi08) | nop 523 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 37); + // sq.xyzw vf29, 40(vi08) | nop 524 + sq_buffer(Mask::xyzw, vu.vf29, vu.vi08 + 40); + // sq.xyzw vf30, 43(vi08) | nop 525 + sq_buffer(Mask::xyzw, vu.vf30, vu.vi08 + 43); + // sq.xyzw vf28, 46(vi08) | nop 526 + sq_buffer(Mask::xyzw, vu.vf28, vu.vi08 + 46); + // lq.xyzw vf07, 960(vi00) | maddw.xyzw vf26, vf06, vf00 527 + vu.acc.madd(Mask::xyzw, vu.vf26, vu.vf06, vu.vf00.w()); + lq_buffer(Mask::xyzw, vu.vf07, 960); + // ior vi03, vi08, vi00 | nop 528 + vu.vi03 = vu.vi08; + // BRANCH! + // bal vi13, L32 | nop 529 + // ASSERT(false); + // iaddi vi05, vi00, 0x3 | nop 530 + vu.vi05 = 3; + // if (bc) { goto L32; } + run_L32_vu2c(); + + // BRANCH! + // ibeq vi00, vi05, L29 | nop 531 + bc = (vu.vi05 == 0); + // iaddiu vi06, vi05, 0x4000 | nop 532 + vu.vi06 = vu.vi05 + 0x4000; /* 16384 */ + if (bc) { + goto L29; + } + + // BRANCH! + // bal vi13, L30 | nop 533 + // ASSERT(false); + // iaddiu vi06, vi06, 0x4000 | nop 534 + vu.vi06 = vu.vi06 + 0x4000; /* 16384 */ + // if (bc) { goto L30; } + run_L30_vu2c(); + + // iaddiu vi08, vi00, 0x3d2 | nop 535 + vu.vi08 = 0x3d2; /* 977 */ + // xgkick vi10 | nop 536 + xgkick(vu.vi10); + // lq.xyzw vf07, 960(vi00) | nop 537 + lq_buffer(Mask::xyzw, vu.vf07, 960); + // xgkick vi08 | nop 538 + xgkick(vu.vi08); + // iaddi vi08, vi10, 0x6 | nop 539 + vu.vi08 = vu.vi10 + 6; + // sq.xyzw vf07, 6(vi10) | nop 540 + sq_buffer(Mask::xyzw, vu.vf07, vu.vi10 + 6); + // isw.x vi06, 6(vi10) | nop 541 + isw_buffer(Mask::x, vu.vi06, vu.vi10 + 6); + // xgkick vi08 | nop 542 + xgkick(vu.vi08); + // iaddiu vi08, vi00, 0x3d6 | nop 543 + vu.vi08 = 0x3d6; /* 981 */ + // nop | nop 544 + + // xgkick vi08 | nop 545 + xgkick(vu.vi08); + // iaddiu vi08, vi10, 0x2a | nop 546 + vu.vi08 = vu.vi10 + 0x2a; /* 42 */ + // iaddiu vi03, vi10, 0x2a | nop 547 + vu.vi03 = vu.vi10 + 0x2a; /* 42 */ + // iaddi vi05, vi00, 0x3 | nop 548 + vu.vi05 = 3; + // BRANCH! + // bal vi13, L32 | nop 549 + // ASSERT(false); + // lq.xyzw vf07, 962(vi00) | nop 550 + lq_buffer(Mask::xyzw, vu.vf07, 962); + // if (bc) { goto L32; } + run_L32_vu2c(); + + // iaddiu vi06, vi05, 0x4000 | nop 551 + vu.vi06 = vu.vi05 + 0x4000; /* 16384 */ + // BRANCH! + // bal vi13, L30 | nop 552 + // ASSERT(false); + // iaddiu vi06, vi06, 0x4000 | nop 553 + vu.vi06 = vu.vi06 + 0x4000; /* 16384 */ + // if (bc) { goto L30; } + run_L30_vu2c(); + + // iaddiu vi08, vi10, 0x23 | nop 554 + vu.vi08 = vu.vi10 + 0x23; /* 35 */ + // iaddiu vi01, vi00, 0x69c | nop 555 + vu.vi01 = 0x69c; /* 1692 */ + // xgkick vi08 | nop 556 + xgkick(vu.vi08); + // isub vi10, vi01, vi10 | nop 557 + vu.vi10 = vu.vi01 - vu.vi10; +L29: + // BRANCH! + // ibgtz vi14, L26 | nop 558 + bc = ((s16)vu.vi14) > 0; + // nop | nop 559 + + if (bc) { + goto L26; + } + + // lq.xyzw vf08, 0(vi02) | nop 560 + lq_buffer(Mask::xyzw, vu.vf08, vu.vi02); + // lq.xyzw vf09, 1(vi02) | nop 561 + lq_buffer(Mask::xyzw, vu.vf09, vu.vi02 + 1); + // jr vi15 | nop 562 + // ASSERT(false); + // lq.xyzw vf10, 2(vi02) | nop 563 + lq_buffer(Mask::xyzw, vu.vf10, vu.vi02 + 2); +} + void OceanNear::run_L30_vu2c() { bool bc; // sq.xyzw vf07, -1(vi08) | nop 564 diff --git a/game/graphics/opengl_renderer/ocean/OceanTexture.cpp b/game/graphics/opengl_renderer/ocean/OceanTexture.cpp index 2c5f037cf1..986eccaaf9 100644 --- a/game/graphics/opengl_renderer/ocean/OceanTexture.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanTexture.cpp @@ -4,7 +4,9 @@ #include "third-party/imgui/imgui.h" -constexpr int OCEAN_TEX_TBP = 8160; // todo +constexpr int OCEAN_TEX_TBP_JAK1 = 8160; // todo +constexpr int OCEAN_TEX_TBP_JAK2 = 672; + OceanTexture::OceanTexture(bool generate_mipmaps) : m_generate_mipmaps(generate_mipmaps), m_result_texture(TEX0_SIZE, @@ -53,7 +55,7 @@ OceanTexture::~OceanTexture() { destroy_pc(); } -void OceanTexture::init_textures(TexturePool& pool) { +void OceanTexture::init_textures(TexturePool& pool, GameVersion version) { TextureInput in; in.gpu_texture = m_result_texture.texture(); in.w = TEX0_SIZE; @@ -61,7 +63,14 @@ void OceanTexture::init_textures(TexturePool& pool) { in.debug_page_name = "PC-OCEAN"; in.debug_name = fmt::format("pc-ocean-mip-{}", m_generate_mipmaps); in.id = pool.allocate_pc_port_texture(); - m_tex0_gpu = pool.give_texture_and_load_to_vram(in, OCEAN_TEX_TBP); + switch (version) { + case GameVersion::Jak1: + m_tex0_gpu = pool.give_texture_and_load_to_vram(in, OCEAN_TEX_TBP_JAK1); + break; + case GameVersion::Jak2: + m_tex0_gpu = pool.give_texture_and_load_to_vram(in, OCEAN_TEX_TBP_JAK2); + break; + } } void OceanTexture::draw_debug_window() { @@ -70,9 +79,9 @@ void OceanTexture::draw_debug_window() { } } -void OceanTexture::handle_ocean_texture(DmaFollower& dma, - SharedRenderState* render_state, - ScopedProfilerNode& prof) { +void OceanTexture::handle_ocean_texture_jak1(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof) { // if we're doing mipmaps, render to temp. // otherwise, render directly to target. FramebufferTexturePairContext ctxt(m_generate_mipmaps ? m_temp_texture : m_result_texture); @@ -224,7 +233,169 @@ void OceanTexture::handle_ocean_texture(DmaFollower& dma, } // give to gpu! - render_state->texture_pool->move_existing_to_vram(m_tex0_gpu, OCEAN_TEX_TBP); + render_state->texture_pool->move_existing_to_vram(m_tex0_gpu, OCEAN_TEX_TBP_JAK1); +} + +void OceanTexture::handle_ocean_texture_jak2(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof) { + // if we're doing mipmaps, render to temp. + // otherwise, render directly to target. + FramebufferTexturePairContext ctxt(m_generate_mipmaps ? m_temp_texture : m_result_texture); + // render to the first texture + { + // (set-display-gs-state arg0 21 128 128 0 0) + auto data = dma.read_and_advance(); + (void)data; + } + + // set up GS for envmap texture drawing + { + // (ocean-texture-add-envmap arg0) + auto data = dma.read_and_advance(); + ASSERT(data.size_bytes == sizeof(AdGifData) + 16); // 16 for the giftag. + ASSERT(data.vifcode0().kind == VifCode::Kind::NOP); + ASSERT(data.vifcode1().kind == VifCode::Kind::DIRECT); + memcpy(&m_envmap_adgif, data.data + 16, sizeof(AdGifData)); + // HACK + setup_renderer(); + } + + // set up VIF + { + // (new 'static 'vif-tag) + // (new 'static 'vif-tag :imm #x4 :cmd (vif-cmd offset)) + auto data = dma.read_and_advance(); + ASSERT(data.size_bytes == 64); + ASSERT(data.vifcode0().kind == VifCode::Kind::NOP); + ASSERT(data.vifcode1().kind == VifCode::Kind::DIRECT); + ASSERT(data.vifcode0().immediate == 0); + ASSERT(data.vifcode1().immediate == 0x4); + } + + // (dma-buffer-add-vu-function arg0 ocean-texture-vu1-block 1) + dma.read_and_advance(); + + { + // (ocean-texture-add-constants obj arg0) + auto data = dma.read_and_advance(); + ASSERT(data.size_bytes == sizeof(OceanTextureConstants)); + ASSERT(data.vifcode0().kind == VifCode::Kind::STCYCL); + ASSERT(data.vifcode0().immediate == 0x404); + ASSERT(data.vifcode1().kind == VifCode::Kind::UNPACK_V4_32); + ASSERT(data.vifcode1().num == data.size_bytes / 16); + ASSERT(data.vifcode1().immediate == TexVu1Data::CONSTANTS); + memcpy(&m_texture_constants, data.data, sizeof(OceanTextureConstants)); + } + + // vertices are uploaded double buffered + m_texture_vertices_loading = m_texture_vertices_a; + m_texture_vertices_drawing = m_texture_vertices_b; + + // add first group of vertices + { + // (ocean-texture-add-verts arg0 sv-16) + auto data = dma.read_and_advance(); + ASSERT(data.size_bytes == sizeof(m_texture_vertices_a)); + ASSERT(data.vifcode0().kind == VifCode::Kind::STCYCL); + ASSERT(data.vifcode0().immediate == 0x404); + ASSERT(data.vifcode1().kind == VifCode::Kind::UNPACK_V4_32); + ASSERT(data.vifcode1().num == data.size_bytes / 16); + VifCodeUnpack up(data.vifcode1()); + ASSERT(up.addr_qw == 0); + ASSERT(up.use_tops_flag == true); + memcpy(m_texture_vertices_loading, data.data, sizeof(m_texture_vertices_a)); + } + + // first call + { + auto data = dma.read_and_advance(); + ASSERT(data.size_bytes == 0); + ASSERT(data.vifcode0().kind == VifCode::Kind::MSCALF); + ASSERT(data.vifcode0().immediate == TexVu1Prog::START); + ASSERT(data.vifcode1().kind == VifCode::Kind::STMOD); // not sure why... + run_L1_PC_jak2(); + } + + // loop over vertex groups + for (int i = 0; i < NUM_FRAG_LOOPS; i++) { + auto verts = dma.read_and_advance(); + ASSERT(verts.size_bytes == sizeof(m_texture_vertices_a)); + ASSERT(verts.vifcode0().kind == VifCode::Kind::STCYCL); + ASSERT(verts.vifcode0().immediate == 0x404); + ASSERT(verts.vifcode1().kind == VifCode::Kind::UNPACK_V4_32); + ASSERT(verts.vifcode1().num == verts.size_bytes / 16); + VifCodeUnpack up(verts.vifcode1()); + ASSERT(up.addr_qw == 0); + ASSERT(up.use_tops_flag == true); + memcpy(m_texture_vertices_loading, verts.data, sizeof(m_texture_vertices_a)); + + auto call = dma.read_and_advance(); + ASSERT(call.size_bytes == 0); + ASSERT(call.vifcode0().kind == VifCode::Kind::MSCALF); + ASSERT(call.vifcode0().immediate == TexVu1Prog::REST); + ASSERT(call.vifcode1().kind == VifCode::Kind::STMOD); // not sure why... + run_L2_PC_jak2(); + } + + // last upload does something weird... + { + // (ocean-texture-add-verts-last arg0 (the-as (inline-array vector) sv-48) sv-64) + auto data0 = dma.read_and_advance(); + ASSERT(data0.size_bytes == 128 * 16); + ASSERT(data0.vifcode0().kind == VifCode::Kind::STCYCL); + ASSERT(data0.vifcode0().immediate == 0x404); + ASSERT(data0.vifcode1().kind == VifCode::Kind::UNPACK_V4_32); + ASSERT(data0.vifcode1().num == data0.size_bytes / 16); + VifCodeUnpack up0(data0.vifcode1()); + ASSERT(up0.addr_qw == 0); + ASSERT(up0.use_tops_flag == true); + memcpy(m_texture_vertices_loading, data0.data, 128 * 16); + + auto data1 = dma.read_and_advance(); + ASSERT(data1.size_bytes == 64 * 16); + ASSERT(data1.vifcode0().kind == VifCode::Kind::STCYCL); + ASSERT(data1.vifcode0().immediate == 0x404); + ASSERT(data1.vifcode1().kind == VifCode::Kind::UNPACK_V4_32); + ASSERT(data1.vifcode1().num == data1.size_bytes / 16); + VifCodeUnpack up1(data1.vifcode1()); + ASSERT(up1.addr_qw == 128); + ASSERT(up1.use_tops_flag == true); + memcpy(m_texture_vertices_loading + 128, data1.data, 64 * 16); + } + + // last rest call + { + auto data = dma.read_and_advance(); + ASSERT(data.size_bytes == 0); + ASSERT(data.vifcode0().kind == VifCode::Kind::MSCALF); + ASSERT(data.vifcode0().immediate == TexVu1Prog::REST); + ASSERT(data.vifcode1().kind == VifCode::Kind::STMOD); // not sure why... + run_L2_PC_jak2(); + } + + // last call + { + auto data = dma.read_and_advance(); + ASSERT(data.size_bytes == 0); + ASSERT(data.vifcode0().kind == VifCode::Kind::MSCALF); + ASSERT(data.vifcode0().immediate == TexVu1Prog::DONE); + ASSERT(data.vifcode1().kind == VifCode::Kind::STMOD); // not sure why... + // this program does nothing. + } + + flush(render_state, prof); + if (m_generate_mipmaps) { + // if we did mipmaps, the above code rendered to temp, and now we need to generate mipmaps + // in the real output + make_texture_with_mipmaps(render_state, prof); + } + + // (reset-display-gs-state *display* arg0) + // dma.read_and_advance(); + + // give to gpu! + render_state->texture_pool->move_existing_to_vram(m_tex0_gpu, OCEAN_TEX_TBP_JAK2); } /*! diff --git a/game/graphics/opengl_renderer/ocean/OceanTexture.h b/game/graphics/opengl_renderer/ocean/OceanTexture.h index cfa4e13125..5c2066f804 100644 --- a/game/graphics/opengl_renderer/ocean/OceanTexture.h +++ b/game/graphics/opengl_renderer/ocean/OceanTexture.h @@ -8,10 +8,13 @@ class OceanTexture { public: OceanTexture(bool generate_mipmaps); - void handle_ocean_texture(DmaFollower& dma, - SharedRenderState* render_state, - ScopedProfilerNode& prof); - void init_textures(TexturePool& pool); + void handle_ocean_texture_jak1(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof); + void handle_ocean_texture_jak2(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof); + void init_textures(TexturePool& pool, GameVersion version); void draw_debug_window(); ~OceanTexture(); @@ -22,6 +25,10 @@ class OceanTexture { void run_L5_PC(); void xgkick_PC(Vf* src); + void run_L1_PC_jak2(); + void run_L2_PC_jak2(); + void run_L3_PC_jak2(); + void setup_renderer(); void flush(SharedRenderState* render_state, ScopedProfilerNode& prof); diff --git a/game/graphics/opengl_renderer/ocean/OceanTexture_PC.cpp b/game/graphics/opengl_renderer/ocean/OceanTexture_PC.cpp index 78d06427ca..6d9e248084 100644 --- a/game/graphics/opengl_renderer/ocean/OceanTexture_PC.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanTexture_PC.cpp @@ -394,6 +394,240 @@ void OceanTexture::xgkick_PC(Vf* src) { } } +void OceanTexture::run_L1_PC_jak2() { + // L1: + // lq.xyzw vf14_startx, 988(vi00) | maxw.xyzw vf01_ones, vf00, vf00 + vu.startx = Vf(m_texture_constants.start); + // lq.xyzw vf02_offset, 989(vi00) + // lq.xyzw vf03_tbuf, 986(vi00) + // lq.xyzw vf04_dbuf, 987(vi00) + // lq.xyzw vf05_giftag, 985(vi00) + // lq.xyzw vf06_cam_nrm, 991(vi00) + // lq.xyzw vf07_constants, 990(vi00) + // iaddiu vi11_0x80, vi00, 0x80 + // mtir vi08_tptr, vf03_tbuf.x + vu.tptr = get_tbuf(); + // mtir vi09_tbase, vf03_tbuf.x + vu.tbase = get_tbuf(); + // mr32.xyzw vf03_tbuf, vf03_tbuf + swap_tbuf(); + // xtop vi05_in_ptr + vu.in_ptr = swap_vu_upload_buffers(); + + // mtir vi06_dbuf_write, vf04_dbuf.x + vu.dbuf_write = get_dbuf(); + // bal vi12_ra, L3 + // mr32.xyzw vf04_dbuf, vf04_dbuf + swap_dbuf(); + run_L3_PC_jak2(); + + // mtir vi06_dbuf_write, vf04_dbuf.x + vu.dbuf_write = get_dbuf(); + // bal vi12_ra, L3 + // mr32.xyzw vf04_dbuf, vf04_dbuf + swap_dbuf(); + run_L3_PC_jak2(); + + // mtir vi03_dbuf_read_a, vf04_dbuf.x + vu.dbuf_read_a = get_dbuf(); + // bal vi12_ra, L5 + // mtir vi04_dbuf_read_b, vf04_dbuf.y + vu.dbuf_read_b = get_dbuf_other(); + run_L5_PC(); + + // mtir vi06_dbuf_write, vf04_dbuf.x + vu.dbuf_write = get_dbuf(); + // bal vi12_ra, L3 + // mr32.xyzw vf04_dbuf, vf04_dbuf + swap_dbuf(); + run_L3_PC_jak2(); + + // mtir vi03_dbuf_read_a, vf04_dbuf.x + vu.dbuf_read_a = get_dbuf(); + // bal vi12_ra, L5 + // mtir vi04_dbuf_read_b, vf04_dbuf.y + vu.dbuf_read_b = get_dbuf_other(); + run_L5_PC(); + + // nop :e + // nop +} + +void OceanTexture::run_L2_PC_jak2() { + // L2: + // xtop vi05_in_ptr + vu.in_ptr = swap_vu_upload_buffers(); + // mtir vi06_dbuf_write, vf04_dbuf.x + vu.dbuf_write = get_dbuf(); + // bal vi12_ra, L3 + // mr32.xyzw vf04_dbuf, vf04_dbuf + swap_dbuf(); + run_L3_PC_jak2(); + + // mtir vi03_dbuf_read_a, vf04_dbuf.x + vu.dbuf_read_a = get_dbuf(); + // bal vi12_ra, L5 + // mtir vi04_dbuf_read_b, vf04_dbuf.y + vu.dbuf_read_b = get_dbuf_other(); + run_L5_PC(); + + // mtir vi06_dbuf_write, vf04_dbuf.x + vu.dbuf_write = get_dbuf(); + // bal vi12_ra, L3 + // mr32.xyzw vf04_dbuf, vf04_dbuf + swap_dbuf(); + run_L3_PC_jak2(); + + // mtir vi03_dbuf_read_a, vf04_dbuf.x + vu.dbuf_read_a = get_dbuf(); + // bal vi12_ra, L5 + // mtir vi04_dbuf_read_b, vf04_dbuf.y + vu.dbuf_read_b = get_dbuf_other(); + run_L5_PC(); + + // mtir vi06_dbuf_write, vf04_dbuf.x + vu.dbuf_write = get_dbuf(); + // bal vi12_ra, L3 + // mr32.xyzw vf04_dbuf, vf04_dbuf + swap_dbuf(); + run_L3_PC_jak2(); + + // mtir vi03_dbuf_read_a, vf04_dbuf.x + vu.dbuf_read_a = get_dbuf(); + // bal vi12_ra, L5 + // mtir vi04_dbuf_read_b, vf04_dbuf.y + vu.dbuf_read_b = get_dbuf_other(); + run_L5_PC(); + + // nop :e + // nop +} + +void OceanTexture::run_L3_PC_jak2() { + Vf base_pos; // vf15 + u16 loop_idx; + + Vf vtx0; // vf16 + Vf vtx1; // vf17 + Vf vtx2; // vf18 + Vf vtx3; // vf19 + + Vf res0; // vf20 + Vf res1; // vf21 + Vf res2; // vf22 + Vf res3; // vf23 + + Vf nrm0; // vf24 + Vf nrm1; // vf25 + Vf nrm2; // vf26 + + Vf reflect; // vf27 + + Vf cout0; // vf28 + Vf cout1; // vf29 + Vf cout2; // vf30 + Vf cout3; // vf31 + + Accumulator acc; + const Vf ones(1, 1, 1, 1); + const Vf vf00(0, 0, 0, 1); + const u16 vi11 = 0x80; + bool bc; + + // clang-format off + // L3: + // ior vi07, vi06, vi00 | nop 56 + vu.dbuf_write_base = vu.dbuf_write; + // move.xyzw vf15, vf14 | nop 57 + base_pos.move(Mask::xyzw, vu.startx); + // iaddi vi01, vi00, 0x8 | nop 58 + loop_idx = 8; + // lq.xyzw vf24, 1(vi05) | mulw.xyzw vf20, vf15, vf00 59 (?? what are they doing here) + res0.mul(Mask::xyzw, base_pos, 1.f); lq_buffer(Mask::xyzw, nrm0, vu.in_ptr + 1); + // lq.xyzw vf26, 3(vi05) | mulw.xyzw vf21, vf15, vf00 60 + res1.mul(Mask::xyzw, base_pos, 1.f); lq_buffer(Mask::xyzw, nrm2, vu.in_ptr + 5); + // nop | mulw.xyzw vf22, vf15, vf00 61 + lq_buffer(Mask::xyzw, nrm2, vu.in_ptr + 5); + // nop | mulw.xyzw vf23, vf15, vf00 62 + res3.mul(Mask::xyzw, base_pos, 1.f); + // nop | addx.x vf21, vf21, vf02 63 + res1.add(Mask::x, res1, m_texture_constants.offsets.x()); + // nop | addy.x vf22, vf22, vf02 64 + res2.add(Mask::x, res2, m_texture_constants.offsets.y()); + L4: + // nop | addz.x vf23, vf23, vf02 65 + res3.add(Mask::x, res3, m_texture_constants.offsets.z()); + // nop | addw.x vf15, vf15, vf02 66 + base_pos.add(Mask::x, base_pos, m_texture_constants.offsets.w()); + // sq.xyzw vf20, 2(vi06) | mulx.x vf28, vf01, vf24 67 + cout0.mul(Mask::x, ones, nrm0.x()); sq_buffer(Mask::xyzw, res0, vu.dbuf_write + 2); + // sq.xyzw vf21, 5(vi06) | muly.x vf29, vf01, vf24 68 + cout1.mul(Mask::x, ones, nrm0.y()); sq_buffer(Mask::xyzw, res1, vu.dbuf_write + 5); + // sq.xyzw vf22, 8(vi06) | mulz.x vf30, vf01, vf24 69 + cout2.mul(Mask::x, ones, nrm0.z()); sq_buffer(Mask::xyzw, res2, vu.dbuf_write + 8); + // sq.xyzw vf23, 11(vi06) | mulw.x vf31, vf01, vf24 70 + cout3.mul(Mask::x, ones, nrm0.w()); sq_buffer(Mask::xyzw, res3, vu.dbuf_write + 11); + // lq.xyzw vf16, 0(vi05) | mulx.y vf28, vf01, vf26 71 + cout0.mul(Mask::y, ones, nrm2.x()); lq_buffer(Mask::xyzw, vtx0, vu.in_ptr); + // lq.xyzw vf17, 2(vi05) | muly.y vf29, vf01, vf26 72 + cout1.mul(Mask::y, ones, nrm2.y()); lq_buffer(Mask::xyzw, vtx1, vu.in_ptr + 2); + // lq.xyzw vf18, 4(vi05) | mulz.y vf30, vf01, vf26 73 + cout2.mul(Mask::y, ones, nrm2.z()); lq_buffer(Mask::xyzw, vtx2, vu.in_ptr + 4); + // lq.xyzw vf19, 6(vi05) | mulw.y vf31, vf01, vf26 74 + cout3.mul(Mask::y, ones, nrm2.w()); lq_buffer(Mask::xyzw, vtx3, vu.in_ptr + 6); + // iaddi vi05, vi05, 0x8 | ftoi0.xyzw vf16, vf16 75 + vtx0.ftoi0(Mask::xyzw, vtx0); vu.in_ptr = vu.in_ptr + 8; + // nop | ftoi0.xyzw vf17, vf17 76 + vtx1.ftoi0(Mask::xyzw, vtx1); + // nop | ftoi0.xyzw vf18, vf18 77 + vtx2.ftoi0(Mask::xyzw, vtx2); + // iaddi vi01, vi01, -0x1 | ftoi0.xyzw vf19, vf19 78 + vtx3.ftoi0(Mask::xyzw, vtx3); loop_idx = loop_idx + -1; + // sq.xyzw vf16, 1(vi06) | add.xyzw vf28, vf28, vf07 79 + cout0.add(Mask::xyzw, cout0, m_texture_constants.cam_nrm); sq_buffer(Mask::xyzw, vtx0, vu.dbuf_write + 1); + // sq.xyzw vf17, 4(vi06) | add.xyzw vf29, vf29, vf07 80 + cout1.add(Mask::xyzw, cout1, m_texture_constants.cam_nrm); sq_buffer(Mask::xyzw, vtx1, vu.dbuf_write + 4); + // sq.xyzw vf18, 7(vi06) | add.xyzw vf30, vf30, vf07 81 + cout2.add(Mask::xyzw, cout2, m_texture_constants.cam_nrm); sq_buffer(Mask::xyzw, vtx2, vu.dbuf_write + 7); + // sq.xyzw vf19, 10(vi06) | add.xyzw vf31, vf31, vf07 82 + cout3.add(Mask::xyzw, cout3, m_texture_constants.cam_nrm); sq_buffer(Mask::xyzw, vtx3, vu.dbuf_write + 10); + // lq.xyzw vf24, 1(vi05) | sub.zw vf28, vf01, vf00 83 + cout0.sub(Mask::zw, ones, vf00); lq_buffer(Mask::xyzw, nrm0, vu.in_ptr + 1); + // lq.xyzw vf26, 5(vi05) | sub.zw vf29, vf01, vf00 84 + cout1.sub(Mask::zw, ones, vf00); lq_buffer(Mask::xyzw, nrm2, vu.in_ptr + 5); + // nop | sub.zw vf30, vf01, vf00 85 + cout2.sub(Mask::zw, ones, vf00); + // nop | sub.zw vf31, vf01, vf00 86 + cout3.sub(Mask::zw, ones, vf00); + // sq.xyzw vf28, 0(vi06) | mulw.xyzw vf20, vf15, vf00 87 + res0.mul(Mask::xyzw, base_pos, 1.f); sq_buffer(Mask::xyzw, cout0, vu.dbuf_write); + // sq.xyzw vf29, 3(vi06) | mulw.xyzw vf21, vf15, vf00 88 + res1.mul(Mask::xyzw, base_pos, 1.f); sq_buffer(Mask::xyzw, cout1, vu.dbuf_write + 3); + // sq.xyzw vf30, 6(vi06) | mulw.xyzw vf22, vf15, vf00 89 + res2.mul(Mask::xyzw, base_pos, 1.f); sq_buffer(Mask::xyzw, cout2, vu.dbuf_write + 6); + // sq.xyzw vf31, 9(vi06) | mulw.xyzw vf23, vf15, vf00 90 + res3.mul(Mask::xyzw, base_pos, 1.f); sq_buffer(Mask::xyzw, cout3, vu.dbuf_write + 9); + // BRANCH! + // ibgtz vi01, L4 | addx.x vf21, vf21, vf02 91 + res1.add(Mask::x, res1, m_texture_constants.offsets.x()); bc = ((s16)loop_idx) > 0; + // iaddi vi06, vi06, 0xc | addy.x vf22, vf22, vf02 92 + res2.add(Mask::x, res2, m_texture_constants.offsets.y()); vu.dbuf_write = vu.dbuf_write + 12; + if (bc) { goto L4; } + + // lq.xyzw vf28, 0(vi07) | addx.y vf14, vf14, vf02 93 + vu.startx.add(Mask::y, vu.startx, m_texture_constants.offsets.x()); lq_buffer(Mask::xyzw, cout0, vu.dbuf_write_base); + // lq.xyzw vf16, 1(vi07) | nop 94 + lq_buffer(Mask::xyzw, vtx0, vu.dbuf_write_base + 1); + // sq.xyzw vf20, 2(vi06) | nop 95 + sq_buffer(Mask::xyzw, res0, vu.dbuf_write + 2); + // sq.xyzw vf28, 0(vi06) | nop 96 + sq_buffer(Mask::xyzw, cout0, vu.dbuf_write); + // jr vi12 | nop 97 + // sq.xyzw vf16, 1(vi06) | nop 98 + sq_buffer(Mask::xyzw, vtx0, vu.dbuf_write + 1); + // clang-format on +} + void OceanTexture::setup_renderer() { m_pc.vtx_idx = 0; } diff --git a/game/graphics/opengl_renderer/shaders/ocean_common.vert b/game/graphics/opengl_renderer/shaders/ocean_common.vert index 9e71b5f696..1ff675f83d 100644 --- a/game/graphics/opengl_renderer/shaders/ocean_common.vert +++ b/game/graphics/opengl_renderer/shaders/ocean_common.vert @@ -9,7 +9,7 @@ out vec4 fragment_color; out vec3 tex_coord; out float fog; -const float SCISSOR_ADJUST = 512.0/448.0; +const float SCISSOR_ADJUST = HEIGHT_SCALE * 512.0/448.0; uniform int bucket; diff --git a/goal_src/jak2/engine/gfx/ocean/ocean-mid.gc b/goal_src/jak2/engine/gfx/ocean/ocean-mid.gc index 1b6a4b562d..8ad64c8022 100644 --- a/goal_src/jak2/engine/gfx/ocean/ocean-mid.gc +++ b/goal_src/jak2/engine/gfx/ocean/ocean-mid.gc @@ -7,7 +7,7 @@ ;; DECOMP BEGINS -(define ocean-mid-block (new 'static 'vu-function :length #x490 :qlength #x248)) +(define ocean-mid-block (new 'static 'vu-function #|:length #x490 :qlength #x248|#)) (defmethod ocean-mid-setup-constants ocean ((obj ocean) (arg0 ocean-mid-constants)) (let ((v1-0 *math-camera*)) diff --git a/goal_src/jak2/engine/gfx/ocean/ocean-near.gc b/goal_src/jak2/engine/gfx/ocean/ocean-near.gc index 2d755a7a63..01c1e9aaeb 100644 --- a/goal_src/jak2/engine/gfx/ocean/ocean-near.gc +++ b/goal_src/jak2/engine/gfx/ocean/ocean-near.gc @@ -7,7 +7,7 @@ ;; DECOMP BEGINS -(define ocean-near-block (new 'static 'vu-function :length #x3dd :qlength #x1ef)) +(define ocean-near-block (new 'static 'vu-function #|:length #x3dd :qlength #x1ef|#)) (defmethod ocean-near-add-call ocean ((obj ocean) (arg0 dma-buffer) (arg1 int)) (let* ((v1-0 arg0) diff --git a/goal_src/jak2/engine/gfx/ocean/ocean-texture.gc b/goal_src/jak2/engine/gfx/ocean/ocean-texture.gc index 8b7bdcf97c..ec2f84d611 100644 --- a/goal_src/jak2/engine/gfx/ocean/ocean-texture.gc +++ b/goal_src/jak2/engine/gfx/ocean/ocean-texture.gc @@ -7,7 +7,7 @@ ;; DECOMP BEGINS -(define ocean-texture-vu1-block (new 'static 'vu-function :length #x7c :qlength 62)) +(define ocean-texture-vu1-block (new 'static 'vu-function #|:length #x7c :qlength 62|#)) (defmethod ocean-texture-setup-constants ocean ((obj ocean) (arg0 ocean-texture-constants)) (set! (-> arg0 giftag tag) @@ -203,8 +203,8 @@ ) (ocean-texture-add-call-rest obj arg0) (ocean-texture-add-call-done obj arg0) - (ocean-method-81 obj arg0) - (reset-display-gs-state *display* arg0) + ;; (ocean-method-81 obj arg0) + ;; (reset-display-gs-state *display* arg0) 0 (none) ) diff --git a/goal_src/jak2/engine/gfx/ocean/ocean.gc b/goal_src/jak2/engine/gfx/ocean/ocean.gc index e6f26cafab..539a8ebd24 100644 --- a/goal_src/jak2/engine/gfx/ocean/ocean.gc +++ b/goal_src/jak2/engine/gfx/ocean/ocean.gc @@ -1207,11 +1207,14 @@ (let* ((s4-0 (-> *display* frames (-> *display* on-screen) global-buf)) (s5-2 (-> s4-0 base)) ) - (if (-> *time-of-day-context* sky) - (ocean-method-89 obj s4-0) - ) + ;; TODO handle ocean::79 and ocean::89 + ;; diasble tod ocean stuff + ;; (if (-> *time-of-day-context* sky) + ;; (ocean-method-89 obj s4-0) + ;; ) (draw-ocean-texture obj s4-0 (the-as int (-> obj verts))) - (ocean-method-79 obj s4-0) + ;; disable whatever this is + ;; (ocean-method-79 obj s4-0) (init-buffer! obj s4-0) (if (-> obj far-on) (draw-ocean-far obj s4-0) @@ -1230,7 +1233,7 @@ ) (dma-bucket-insert-tag (-> *display* frames (-> *display* on-screen) bucket-group) - (bucket-id bucket-6) + (bucket-id ocean-mid-far) s5-2 (the-as (pointer dma-tag) a3-3) ) @@ -1256,7 +1259,7 @@ ) (dma-bucket-insert-tag (-> *display* frames (-> *display* on-screen) bucket-group) - (bucket-id bucket-310) + (bucket-id ocean-near) s5-3 (the-as (pointer dma-tag) a3-5) ) diff --git a/goal_src/jak2/engine/gfx/vu1-user-h.gc b/goal_src/jak2/engine/gfx/vu1-user-h.gc index 6b311c1f9b..4715ebaf7e 100644 --- a/goal_src/jak2/engine/gfx/vu1-user-h.gc +++ b/goal_src/jak2/engine/gfx/vu1-user-h.gc @@ -33,7 +33,7 @@ (bucket-3 3) ;; blit displays (tex-lcom-sky-pre 4) ;; tex (sky-draw 5) ;; sky - (bucket-6 6) ;; ocean + (ocean-mid-far 6) ;; ocean ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; All levels with tfrag tpage @@ -389,7 +389,7 @@ (tex-lcom-sky-post 309) - (bucket-310 310) ;; ocean + (ocean-near 310) ;; ocean (bucket-311 311) ;; depth-cue (tex-all-sprite 312) diff --git a/test/decompiler/reference/jak2/engine/gfx/ocean/ocean_REF.gc b/test/decompiler/reference/jak2/engine/gfx/ocean/ocean_REF.gc index 82349f546c..66540de901 100644 --- a/test/decompiler/reference/jak2/engine/gfx/ocean/ocean_REF.gc +++ b/test/decompiler/reference/jak2/engine/gfx/ocean/ocean_REF.gc @@ -1485,7 +1485,7 @@ ) (dma-bucket-insert-tag (-> *display* frames (-> *display* on-screen) bucket-group) - (bucket-id bucket-6) + (bucket-id ocean-mid-far) s5-2 (the-as (pointer dma-tag) a3-3) ) @@ -1511,7 +1511,7 @@ ) (dma-bucket-insert-tag (-> *display* frames (-> *display* on-screen) bucket-group) - (bucket-id bucket-310) + (bucket-id ocean-near) s5-3 (the-as (pointer dma-tag) a3-5) ) @@ -1613,3 +1613,7 @@ ;; definition (debug) for function test-to-from-spr ;; ERROR: function was not converted to expressions. Cannot decompile. + + + +