From 43612b0750ce9dcc29cd107352c011e1cac9874e Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Mon, 7 Mar 2022 20:28:53 -0500 Subject: [PATCH] add ocean far big triangle stuff (#1224) --- decompiler/config/all-types.gc | 2 +- .../config/jak1_ntsc_black_label/hacks.jsonc | 9 +- .../jak1_ntsc_black_label/type_casts.jsonc | 43 ++ .../jak1_ntsc_black_label/var_names.jsonc | 6 + game/CMakeLists.txt | 2 + .../opengl_renderer/OceanMidAndFar.cpp | 66 ++ .../graphics/opengl_renderer/OceanMidAndFar.h | 14 + .../opengl_renderer/OpenGLRenderer.cpp | 4 +- game/graphics/opengl_renderer/buckets.h | 25 +- game/mips2c/functions/ocean.cpp | 370 ++++++++++ game/mips2c/mips2c_table.cpp | 13 +- goal_src/engine/draw/drawable.gc | 2 +- goal_src/engine/gfx/ocean/ocean-h.gc | 1 + goal_src/engine/gfx/ocean/ocean.gc | 656 +++++++++++++++++- 14 files changed, 1204 insertions(+), 9 deletions(-) create mode 100644 game/graphics/opengl_renderer/OceanMidAndFar.cpp create mode 100644 game/graphics/opengl_renderer/OceanMidAndFar.h create mode 100644 game/mips2c/functions/ocean.cpp diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 0ad2c459bf..acb7074e29 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -21711,7 +21711,7 @@ (define-extern draw-ocean-near (function dma-buffer none)) ; not confirmed (define-extern init-ocean-far-regs (function none)) (define-extern render-ocean-far (function dma-buffer int none)) -(define-extern render-ocean-quad (function ocean-mid-upload2 none)) +(define-extern render-ocean-quad (function (inline-array ocean-vertex) dma-buffer symbol)) (define-extern draw-large-polygon-ocean (function none)) (define-extern draw-ocean (function none)) (define-extern update-ocean (function none)) diff --git a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc index 5949777e40..9b178babfa 100644 --- a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc @@ -573,8 +573,6 @@ "setup-blerc-chains-for-one-fragment", "blerc-execute", - // generic merc - //"generic-merc-execute-all", "generic-merc-execute-asm", "high-speed-reject", "mercneric-convert", @@ -591,7 +589,12 @@ "ripple-matrix-scale", "ripple-apply-wave-table", "ripple-create-wave-table", - "ripple-execute-init" + "ripple-execute-init", + + // ocean + "init-ocean-far-regs", + "draw-large-polygon-ocean", + "render-ocean-quad" ], "mips2c_jump_table_functions": { diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index be7d916c6f..08ae852c68 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -7382,5 +7382,48 @@ [[21, 42], "gp", "adgif-shader"] ], + "render-ocean-far": [ + [[23,588], "s5", "(inline-array ocean-vertex)"] + ], + + "draw-ocean-far": [ + [[65, 72], "gp", "dma-packet"] + ], + + "ocean-init-buffer": [ + [[9, 14], "a2", "dma-packet"], + [[19, 22], "a2", "gs-gif-tag"], + [27, "s4", "(pointer gs-test)"], + [29, "s4", "(pointer gs-reg64)"], + [31, "s4", "(pointer gs-alpha)"], + [33, "s4", "(pointer gs-reg64)"], + [49, "s4", "(pointer gs-tex0)"], + [51, "s4", "(pointer gs-reg64)"], + [53, "s4", "(pointer gs-tex1)"], + [55, "s4", "(pointer gs-reg64)"], + [57, "s4", "(pointer gs-texa)"], + [59, "s4", "(pointer gs-reg64)"], + [71, "s4", "(pointer gs-miptbp)"], + [73, "s4", "(pointer gs-reg64)"], + [87, "s4", "(pointer gs-miptbp)"], + [89, "s4", "(pointer gs-reg64)"], + [90, "s4", "(pointer gs-clamp)"], + [92, "s4", "(pointer gs-reg64)"], + [94, "s4", "(pointer gs-fogcol)"], + [96, "s4", "(pointer gs-reg64)"] + ], + + "ocean-end-buffer": [ + [[3, 7], "a1", "dma-packet"], + [[13, 16], "a1", "gs-gif-tag"], + [22, "a0", "(pointer gs-texa)"], + [24, "a0", "(pointer gs-reg64)"] + ], + + "draw-ocean": [ + [[166, 169], "v1", "dma-packet"], + [[114, 117], "v1", "dma-packet"] + ], + "placeholder-do-not-add-below": [] } diff --git a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc index ceb0db4f9c..9a8f088f0d 100644 --- a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc @@ -4028,5 +4028,11 @@ } }, + "render-ocean-far" : { + "vars": { + "s5-0" : ["vertices", "(inline-array ocean-vertex)"] + } + }, + "aaaaaaaaaaaaaaaaaaaaaaa": {} } diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index 35b2be9d42..53cf90f164 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -49,6 +49,7 @@ set(RUNTIME_SOURCE mips2c/functions/generic_merc.cpp mips2c/functions/joint.cpp mips2c/functions/merc_blend_shape.cpp + mips2c/functions/ocean.cpp mips2c/functions/ripple.cpp mips2c/functions/sky_tng.cpp mips2c/functions/sparticle.cpp @@ -93,6 +94,7 @@ set(RUNTIME_SOURCE graphics/opengl_renderer/Loader.cpp graphics/opengl_renderer/MercProgram.cpp graphics/opengl_renderer/MercRenderer.cpp + graphics/opengl_renderer/OceanMidAndFar.cpp graphics/opengl_renderer/opengl_utils.cpp graphics/opengl_renderer/OpenGLRenderer.cpp graphics/opengl_renderer/Profiler.cpp diff --git a/game/graphics/opengl_renderer/OceanMidAndFar.cpp b/game/graphics/opengl_renderer/OceanMidAndFar.cpp new file mode 100644 index 0000000000..471236914a --- /dev/null +++ b/game/graphics/opengl_renderer/OceanMidAndFar.cpp @@ -0,0 +1,66 @@ +#include "OceanMidAndFar.h" + +OceanMidAndFar::OceanMidAndFar(const std::string& name, BucketId my_id) + : BucketRenderer(name, my_id), m_direct(name, my_id, 4096) {} + +void OceanMidAndFar::draw_debug_window() { + m_direct.draw_debug_window(); +} + +void OceanMidAndFar::render(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof) { + // skip if disabled + if (!m_enabled) { + while (dma.current_tag_offset() != render_state->next_bucket) { + dma.read_and_advance(); + } + return; + } + + // jump to bucket + auto data0 = dma.read_and_advance(); + ASSERT(data0.vif1() == 0); + ASSERT(data0.vif0() == 0); + ASSERT(data0.size_bytes == 0); + + // see if bucket is empty or not + if (dma.current_tag().kind == DmaTag::Kind::CALL) { + // renderer didn't run, let's just get out of here. + for (int i = 0; i < 4; i++) { + dma.read_and_advance(); + } + ASSERT(dma.current_tag_offset() == render_state->next_bucket); + return; + } + m_direct.reset_state(); + + auto init_data = dma.read_and_advance(); + ASSERT(init_data.size_bytes == 160); + u8 init_data_buffer[160]; + memcpy(init_data_buffer, init_data.data, 160); + + // this is a bit of a hack, but it patches the ta0 to 0 in + // (set! (-> (the-as (pointer gs-texa) s4-0) 8) (new 'static 'gs-texa :ta0 #x80 :ta1 #x80)) + u8 val = 0; + memcpy(init_data_buffer + 80, &val, 1); + m_direct.render_gif(init_data_buffer, 160, render_state, prof); + + while (dma.current_tag().kind == DmaTag::Kind::CNT) { + auto data = dma.read_and_advance(); + ASSERT(data.vifcode0().kind == VifCode::Kind::NOP); + ASSERT(data.vifcode1().kind == VifCode::Kind::DIRECT); + ASSERT(data.size_bytes / 16 == data.vifcode1().immediate); + m_direct.render_gif(data.data, data.size_bytes, 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 < 4; i++) { + dma.read_and_advance(); + } + ASSERT(dma.current_tag_offset() == render_state->next_bucket); + + m_direct.flush_pending(render_state, prof); +} \ No newline at end of file diff --git a/game/graphics/opengl_renderer/OceanMidAndFar.h b/game/graphics/opengl_renderer/OceanMidAndFar.h new file mode 100644 index 0000000000..6e9b124d29 --- /dev/null +++ b/game/graphics/opengl_renderer/OceanMidAndFar.h @@ -0,0 +1,14 @@ +#pragma once + +#include "game/graphics/opengl_renderer/BucketRenderer.h" +#include "game/graphics/opengl_renderer/DirectRenderer.h" + +class OceanMidAndFar : public BucketRenderer { + public: + OceanMidAndFar(const std::string& name, BucketId my_id); + void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override; + void draw_debug_window() override; + + private: + DirectRenderer m_direct; +}; diff --git a/game/graphics/opengl_renderer/OpenGLRenderer.cpp b/game/graphics/opengl_renderer/OpenGLRenderer.cpp index 0c5fc66018..9a28a7b2d2 100644 --- a/game/graphics/opengl_renderer/OpenGLRenderer.cpp +++ b/game/graphics/opengl_renderer/OpenGLRenderer.cpp @@ -14,6 +14,7 @@ #include "game/graphics/opengl_renderer/MercRenderer.h" #include "game/graphics/opengl_renderer/EyeRenderer.h" #include "game/graphics/opengl_renderer/GenericRenderer.h" +#include "game/graphics/opengl_renderer/OceanMidAndFar.h" // for the vif callback #include "game/kernel/kmachine.h" @@ -84,7 +85,8 @@ void OpenGLRenderer::init_bucket_renderers() { // 1 // 2 init_bucket_renderer("sky", BucketCategory::OTHER, BucketId::SKY_DRAW); // 3 - // 4 + init_bucket_renderer("ocean-mid-far", BucketCategory::OTHER, + BucketId::OCEAN_MID_AND_FAR); // 4 //----------------------- // LEVEL 0 tfrag texture diff --git a/game/graphics/opengl_renderer/buckets.h b/game/graphics/opengl_renderer/buckets.h index 74fad1e758..d7f49fdc49 100644 --- a/game/graphics/opengl_renderer/buckets.h +++ b/game/graphics/opengl_renderer/buckets.h @@ -5,30 +5,52 @@ enum class BucketId { BUCKET0 = 0, BUCKET1 = 1, + // 2 SKY_DRAW = 3, + OCEAN_MID_AND_FAR = 4, TFRAG_TEX_LEVEL0 = 5, TFRAG_LEVEL0 = 6, + // 7 + // 8 TIE_LEVEL0 = 9, MERC_TFRAG_TEX_LEVEL0 = 10, GMERC_TFRAG_TEX_LEVEL0 = 11, TFRAG_TEX_LEVEL1 = 12, TFRAG_LEVEL1 = 13, + // 14 + // 15 TIE_LEVEL1 = 16, MERC_TFRAG_TEX_LEVEL1 = 17, GMERC_TFRAG_TEX_LEVEL1 = 18, SHRUB_TEX_LEVEL0 = 19, + // 20 + // 21 + // 22 + // 23 + // 24 SHRUB_TEX_LEVEL1 = 25, + // 26 + // 27 + // 28 + // 29 GENERIC_SHRUB = 30, ALPHA_TEX_LEVEL0 = 31, TFRAG_TRANS0_AND_SKY_BLEND_LEVEL0 = 32, + // 33 TFRAG_DIRT_LEVEL0 = 34, + // 35 TFRAG_ICE_LEVEL0 = 36, + // 37 ALPHA_TEX_LEVEL1 = 38, TFRAG_TRANS1_AND_SKY_BLEND_LEVEL1 = 39, + // 40 TFRAG_DIRT_LEVEL1 = 41, + // 42 TFRAG_ICE_LEVEL1 = 43, + // 44 MERC_AFTER_ALPHA = 45, GENERIC_ALPHA = 46, + // 47 PRIS_TEX_LEVEL0 = 48, MERC_PRIS_LEVEL0 = 49, GENERIC_PRIS_LEVEL0 = 50, @@ -44,7 +66,8 @@ enum class BucketId { WATER_TEX_LEVEL1 = 60, MERC_WATER_LEVEL1 = 61, GENERIC_WATER_LEVEL1 = 62, - // ... + OCEAN_NEAR = 63, + // 64 PRE_SPRITE_TEX = 65, // maybe it's just common textures? SPRITE = 66, DEBUG_DRAW_0 = 67, diff --git a/game/mips2c/functions/ocean.cpp b/game/mips2c/functions/ocean.cpp new file mode 100644 index 0000000000..e4c5019ce5 --- /dev/null +++ b/game/mips2c/functions/ocean.cpp @@ -0,0 +1,370 @@ +// clang-format off + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +ExecutionContext ocean_regs_vfs; + +namespace init_ocean_far_regs { +struct Cache { + void* math_camera; // *math-camera* + void* sky_tng_data; // *sky-tng-data* +} cache; + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + u32 call_addr = 0; + c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 + c->sd(fp, 8, sp); // sd fp, 8(sp) + c->mov64(fp, t9); // or fp, t9, r0 + c->load_symbol(v1, cache.math_camera); // lw v1, *math-camera*(s7) + c->load_symbol(a0, cache.sky_tng_data); // lw a0, *sky-tng-data*(s7) + c->daddiu(a0, a0, 60); // daddiu a0, a0, 60 + c->lwc1(f0, 828, v1); // lwc1 f0, 828(v1) + c->swc1(f0, 0, a0); // swc1 f0, 0(a0) + c->lwc1(f0, 128, v1); // lwc1 f0, 128(v1) + c->swc1(f0, 4, a0); // swc1 f0, 4(a0) + c->lwc1(f0, 124, v1); // lwc1 f0, 124(v1) + c->swc1(f0, 8, a0); // swc1 f0, 8(a0) + c->fprs[f0] = 3071.0; // lwc1 f0, L77(fp) + c->swc1(f0, 12, a0); // swc1 f0, 12(a0) + c->lqc2(vf31, 572, v1); // lqc2 vf31, 572(v1) + c->lqc2(vf30, 588, v1); // lqc2 vf30, 588(v1) + c->lqc2(vf29, 604, v1); // lqc2 vf29, 604(v1) + c->lqc2(vf28, 620, v1); // lqc2 vf28, 620(v1) + c->lqc2(vf26, 716, v1); // lqc2 vf26, 716(v1) + c->lqc2(vf14, 700, v1); // lqc2 vf14, 700(v1) + c->lqc2(vf25, 732, v1); // lqc2 vf25, 732(v1) + c->load_symbol(v1, cache.sky_tng_data); // lw v1, *sky-tng-data*(s7) + c->lqc2(vf13, 60, v1); // lqc2 vf13, 60(v1) + c->load_symbol(v1, cache.sky_tng_data); // lw v1, *sky-tng-data*(s7) + c->lqc2(vf27, 44, v1); // lqc2 vf27, 44(v1) + c->vmove(DEST::xyzw, vf24, vf0); // vmove.xyzw vf24, vf0 + c->mov128_gpr_vf(v1, vf24); // qmfc2.i v1, vf24 + c->gprs[v0].du64[0] = 0; // or v0, r0, r0 + c->ld(fp, 8, sp); // ld fp, 8(sp) + //jr ra // jr ra + c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + ocean_regs_vfs.copy_vfs_from_other(c); + return c->gprs[v0].du64[0]; +} + +void link() { + cache.math_camera = intern_from_c("*math-camera*").c(); + cache.sky_tng_data = intern_from_c("*sky-tng-data*").c(); + gLinkedFunctionTable.reg("init-ocean-far-regs", execute, 128); +} + +} // namespace init_ocean_far_regs +} // namespace Mips2C + +namespace Mips2C { +namespace clip_polygon_against_positive_hyperplane { +u64 execute(void* ctxt); +} +namespace clip_polygon_against_negative_hyperplane { +u64 execute(void* ctxt); +} +} +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace draw_large_polygon_ocean { +struct Cache { + void* clip_polygon_against_negative_hyperplane; // clip-polygon-against-negative-hyperplane + void* clip_polygon_against_positive_hyperplane; // clip-polygon-against-positive-hyperplane +} cache; + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + u32 call_addr = 0; + // nop // sll r0, r0, 0 + c->daddiu(sp, sp, -8); // daddiu sp, sp, -8 + c->mov64(t6, s7); // or t6, s7, r0 + c->sd(ra, 0, sp); // sd ra, 0(sp) + c->load_symbol(t9, cache.clip_polygon_against_positive_hyperplane);// lw t9, clip-polygon-against-positive-hyperplane(s7) + c->mov64(a2, t4); // or a2, t4, r0 + c->mov64(a3, t5); // or a3, t5, r0 + call_addr = c->gprs[t9].du32[0]; // function call: + c->daddu(t2, a2, r0); // daddu t2, a2, r0 + // c->jalr(call_addr); // jalr ra, t9 + clip_polygon_against_positive_hyperplane::execute(ctxt); + bc = c->sgpr64(t0) == 0; // beq t0, r0, L70 + // nop // sll r0, r0, 0 + if (bc) {goto block_11;} // branch non-likely + + c->mov64(a2, t5); // or a2, t5, r0 + c->mov64(a3, t4); // or a3, t4, r0 + call_addr = c->gprs[t9].du32[0]; // function call: + c->daddiu(t2, a2, 4); // daddiu t2, a2, 4 + // c->jalr(call_addr); // jalr ra, t9 + clip_polygon_against_positive_hyperplane::execute(ctxt); + bc = c->sgpr64(t0) == 0; // beq t0, r0, L70 + c->load_symbol(t9, cache.clip_polygon_against_negative_hyperplane);// lw t9, clip-polygon-against-negative-hyperplane(s7) + if (bc) {goto block_11;} // branch non-likely + + c->mov64(a2, t4); // or a2, t4, r0 + c->mov64(a3, t5); // or a3, t5, r0 + call_addr = c->gprs[t9].du32[0]; // function call: + c->daddu(t2, a2, r0); // daddu t2, a2, r0 + // c->jalr(call_addr); // jalr ra, t9 + clip_polygon_against_negative_hyperplane::execute(ctxt); + bc = c->sgpr64(t0) == 0; // beq t0, r0, L70 + // nop // sll r0, r0, 0 + if (bc) {goto block_11;} // branch non-likely + + c->mov64(a2, t5); // or a2, t5, r0 + c->mov64(a3, t4); // or a3, t4, r0 + call_addr = c->gprs[t9].du32[0]; // function call: + c->daddiu(t2, a2, 4); // daddiu t2, a2, 4 + // c->jalr(call_addr); // jalr ra, t9 + clip_polygon_against_negative_hyperplane::execute(ctxt); + bc = c->sgpr64(t0) == 0; // beq t0, r0, L70 + c->lw(a3, 4, a1); // lw a3, 4(a1) + if (bc) {goto block_11;} // branch non-likely + + bc = c->sgpr64(t6) == c->sgpr64(s7); // beq t6, s7, L68 + c->mov64(a2, t4); // or a2, t4, r0 + if (bc) {goto block_8;} // branch non-likely + + c->sqc2(vf27, 0, a3); // sqc2 vf27, 0(a3) + c->daddiu(a3, a3, 16); // daddiu a3, a3, 16 + c->sw(t0, -16, a3); // sw t0, -16(a3) + // nop // sll r0, r0, 0 + + block_6: + c->lqc2(vf1, 0, a2); // lqc2 vf1, 0(a2) + // nop // sll r0, r0, 0 + c->lqc2(vf2, 16, a2); // lqc2 vf2, 16(a2) + // nop // sll r0, r0, 0 + c->lqc2(vf3, 32, a2); // lqc2 vf3, 32(a2) + c->vdiv(vf0, BC::w, vf1, BC::w); // vdiv Q, vf0.w, vf1.w + c->vmul(DEST::xyzw, vf1, vf1, vf26); // vmul.xyzw vf1, vf1, vf26 + // nop // sll r0, r0, 0 + c->vftoi0(DEST::xyzw, vf3, vf3); // vftoi0.xyzw vf3, vf3 + // nop // sll r0, r0, 0 + c->vadd(DEST::xyzw, vf2, vf2, vf24); // vadd.xyzw vf2, vf2, vf24 + // nop // sll r0, r0, 0 + c->vwaitq(); // vwaitq + // nop // sll r0, r0, 0 + c->vmulq(DEST::xyz, vf1, vf1); // vmulq.xyz vf1, vf1, Q + c->sqc2(vf3, 16, a3); // sqc2 vf3, 16(a3) + c->vmulq(DEST::xyzw, vf2, vf2); // vmulq.xyzw vf2, vf2, Q + c->daddiu(a2, a2, 48); // daddiu a2, a2, 48 + c->vadd(DEST::xyzw, vf1, vf1, vf25); // vadd.xyzw vf1, vf1, vf25 + c->daddiu(a3, a3, 48); // daddiu a3, a3, 48 + c->vmax_bc(DEST::z, BC::z, vf1, vf1, vf0); // vmaxz.z vf1, vf1, vf0 + // nop // sll r0, r0, 0 + c->vmini_bc(DEST::w, BC::z, vf1, vf1, vf13); // vminiz.w vf1, vf1, vf13 + // nop // sll r0, r0, 0 + c->vmax_bc(DEST::w, BC::y, vf1, vf1, vf13); // vmaxy.w vf1, vf1, vf13 + // nop // sll r0, r0, 0 + c->sqc2(vf2, -48, a3); // sqc2 vf2, -48(a3) + c->daddiu(t0, t0, -1); // daddiu t0, t0, -1 + c->vftoi4(DEST::xyzw, vf1, vf1); // vftoi4.xyzw vf1, vf1 + // nop // sll r0, r0, 0 + bc = c->sgpr64(t0) != 0; // bne t0, r0, L67 + c->sqc2(vf1, -16, a3); // sqc2 vf1, -16(a3) + if (bc) {goto block_6;} // branch non-likely + + c->sw(a3, 4, a1); // sw a3, 4(a1) + // nop // sll r0, r0, 0 + c->ld(ra, 0, sp); // ld ra, 0(sp) + c->daddiu(v0, s7, 8); // daddiu v0, s7, 8 + //jr ra // jr ra + c->daddiu(sp, sp, 8); // daddiu sp, sp, 8 + goto end_of_function; // return + + + block_8: + c->sqc2(vf27, 0, a3); // sqc2 vf27, 0(a3) + c->daddiu(a3, a3, 16); // daddiu a3, a3, 16 + c->sw(t0, -16, a3); // sw t0, -16(a3) + // nop // sll r0, r0, 0 + c->sqc2(vf15, 0, a2); // sqc2 vf15, 0(a2) + // nop // sll r0, r0, 0 + c->sqc2(vf15, 192, a2); // sqc2 vf15, 192(a2) + // nop // sll r0, r0, 0 + c->sqc2(vf16, 48, a2); // sqc2 vf16, 48(a2) + // nop // sll r0, r0, 0 + c->sqc2(vf17, 96, a2); // sqc2 vf17, 96(a2) + // nop // sll r0, r0, 0 + c->sqc2(vf18, 144, a2); // sqc2 vf18, 144(a2) + // nop // sll r0, r0, 0 + + block_9: + c->lqc2(vf1, 0, a2); // lqc2 vf1, 0(a2) + // nop // sll r0, r0, 0 + c->lqc2(vf3, 32, a2); // lqc2 vf3, 32(a2) + // nop // sll r0, r0, 0 + c->lqc2(vf2, 16, a2); // lqc2 vf2, 16(a2) + c->vdiv(vf13, BC::x, vf1, BC::w); // vdiv Q, vf13.x, vf1.w + c->vftoi0(DEST::xyzw, vf3, vf3); // vftoi0.xyzw vf3, vf3 + // nop // sll r0, r0, 0 + c->vwaitq(); // vwaitq + // nop // sll r0, r0, 0 + c->vmulq(DEST::xyz, vf1, vf1); // vmulq.xyz vf1, vf1, Q + c->sqc2(vf3, 16, a3); // sqc2 vf3, 16(a3) + c->vmulq(DEST::xyzw, vf2, vf2); // vmulq.xyzw vf2, vf2, Q + c->daddiu(a2, a2, 48); // daddiu a2, a2, 48 + c->vadd(DEST::xyzw, vf1, vf1, vf25); // vadd.xyzw vf1, vf1, vf25 + c->daddiu(a3, a3, 48); // daddiu a3, a3, 48 + c->vmax_bc(DEST::z, BC::z, vf1, vf1, vf0); // vmaxz.z vf1, vf1, vf0 + // nop // sll r0, r0, 0 + c->vmini_bc(DEST::w, BC::z, vf1, vf1, vf13); // vminiz.w vf1, vf1, vf13 + // nop // sll r0, r0, 0 + c->vmax_bc(DEST::w, BC::y, vf1, vf1, vf13); // vmaxy.w vf1, vf1, vf13 + // nop // sll r0, r0, 0 + c->sqc2(vf2, -48, a3); // sqc2 vf2, -48(a3) + c->daddiu(t0, t0, -1); // daddiu t0, t0, -1 + c->vftoi4(DEST::xyzw, vf1, vf1); // vftoi4.xyzw vf1, vf1 + // nop // sll r0, r0, 0 + bc = c->sgpr64(t0) != 0; // bne t0, r0, L69 + c->sqc2(vf1, -16, a3); // sqc2 vf1, -16(a3) + if (bc) {goto block_9;} // branch non-likely + + c->sw(a3, 4, a1); // sw a3, 4(a1) + // nop // sll r0, r0, 0 + c->ld(ra, 0, sp); // ld ra, 0(sp) + c->daddiu(v0, s7, 8); // daddiu v0, s7, 8 + //jr ra // jr ra + c->daddiu(sp, sp, 8); // daddiu sp, sp, 8 + goto end_of_function; // return + + + block_11: + c->ld(ra, 0, sp); // ld ra, 0(sp) + c->mov64(v0, s7); // or v0, s7, r0 + //jr ra // jr ra + c->daddiu(sp, sp, 8); // daddiu sp, sp, 8 + goto end_of_function; // return + + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.clip_polygon_against_negative_hyperplane = intern_from_c("clip-polygon-against-negative-hyperplane").c(); + cache.clip_polygon_against_positive_hyperplane = intern_from_c("clip-polygon-against-positive-hyperplane").c(); + gLinkedFunctionTable.reg("draw-large-polygon-ocean", execute, 128); +} + +} // namespace draw_large_polygon_ocean +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace render_ocean_quad { +struct Cache { + void* fake_scratchpad_data; // *fake-scratchpad-data* + void* draw_large_polygon_ocean; // draw-large-polygon-ocean +} cache; + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + c->copy_vfs_from_other(&ocean_regs_vfs); + bool bc = false; + u32 call_addr = 0; + c->mov64(v1, a0); // or v1, a0, r0 + get_fake_spad_addr(t4, cache.fake_scratchpad_data, 0, c);// lui t4, 28672 + c->ori(t4, t4, 12288); // ori t4, t4, 12288 + get_fake_spad_addr(t5, cache.fake_scratchpad_data, 0, c);// lui t5, 28672 + c->ori(t5, t5, 14336); // ori t5, t5, 14336 + c->mov64(a3, t4); // or a3, t4, r0 + // nop // sll r0, r0, 0 + c->lqc2(vf1, 0, a0); // lqc2 vf1, 0(a0) + c->addiu(t0, r0, 4); // addiu t0, r0, 4 + c->lqc2(vf2, 16, a0); // lqc2 vf2, 16(a0) + // nop // sll r0, r0, 0 + c->lqc2(vf3, 32, a0); // lqc2 vf3, 32(a0) + c->vmula_bc(DEST::xyzw, BC::x, vf31, vf1); // vmulax.xyzw acc, vf31, vf1 + c->lqc2(vf4, 48, a0); // lqc2 vf4, 48(a0) + c->vmadda_bc(DEST::xyzw, BC::y, vf30, vf1); // vmadday.xyzw acc, vf30, vf1 + c->lqc2(vf5, 64, a0); // lqc2 vf5, 64(a0) + c->vmadda_bc(DEST::xyzw, BC::z, vf29, vf1); // vmaddaz.xyzw acc, vf29, vf1 + c->lqc2(vf6, 80, a0); // lqc2 vf6, 80(a0) + c->vmadd_bc(DEST::xyzw, BC::w, vf15, vf28, vf1); // vmaddw.xyzw vf15, vf28, vf1 + c->lqc2(vf7, 96, a0); // lqc2 vf7, 96(a0) + // nop // sll r0, r0, 0 + c->lqc2(vf8, 112, a0); // lqc2 vf8, 112(a0) + c->vmula_bc(DEST::xyzw, BC::x, vf31, vf4); // vmulax.xyzw acc, vf31, vf4 + c->lqc2(vf9, 128, a0); // lqc2 vf9, 128(a0) + c->vmadda_bc(DEST::xyzw, BC::y, vf30, vf4); // vmadday.xyzw acc, vf30, vf4 + c->lqc2(vf10, 144, a0); // lqc2 vf10, 144(a0) + c->vmadda_bc(DEST::xyzw, BC::z, vf29, vf4); // vmaddaz.xyzw acc, vf29, vf4 + c->lqc2(vf11, 160, a0); // lqc2 vf11, 160(a0) + c->vmadd_bc(DEST::xyzw, BC::w, vf16, vf28, vf4); // vmaddw.xyzw vf16, vf28, vf4 + c->lqc2(vf12, 176, a0); // lqc2 vf12, 176(a0) + c->vmul(DEST::xyzw, vf1, vf15, vf14); // vmul.xyzw vf1, vf15, vf14 + c->sqc2(vf2, 16, a3); // sqc2 vf2, 16(a3) + c->vmula_bc(DEST::xyzw, BC::x, vf31, vf7); // vmulax.xyzw acc, vf31, vf7 + c->sqc2(vf3, 32, a3); // sqc2 vf3, 32(a3) + c->vmadda_bc(DEST::xyzw, BC::y, vf30, vf7); // vmadday.xyzw acc, vf30, vf7 + c->sqc2(vf5, 64, a3); // sqc2 vf5, 64(a3) + c->vmadda_bc(DEST::xyzw, BC::z, vf29, vf7); // vmaddaz.xyzw acc, vf29, vf7 + c->sqc2(vf6, 80, a3); // sqc2 vf6, 80(a3) + c->vmadd_bc(DEST::xyzw, BC::w, vf17, vf28, vf7); // vmaddw.xyzw vf17, vf28, vf7 + c->sqc2(vf8, 112, a3); // sqc2 vf8, 112(a3) + c->vmul(DEST::xyzw, vf4, vf16, vf14); // vmul.xyzw vf4, vf16, vf14 + c->sqc2(vf9, 128, a3); // sqc2 vf9, 128(a3) + c->vmula_bc(DEST::xyzw, BC::x, vf31, vf10); // vmulax.xyzw acc, vf31, vf10 + c->sqc2(vf11, 160, a3); // sqc2 vf11, 160(a3) + c->vmadda_bc(DEST::xyzw, BC::y, vf30, vf10); // vmadday.xyzw acc, vf30, vf10 + c->sqc2(vf12, 176, a3); // sqc2 vf12, 176(a3) + c->vmadda_bc(DEST::xyzw, BC::z, vf29, vf10); // vmaddaz.xyzw acc, vf29, vf10 + c->sqc2(vf2, 208, a3); // sqc2 vf2, 208(a3) + c->vmadd_bc(DEST::xyzw, BC::w, vf18, vf28, vf10); // vmaddw.xyzw vf18, vf28, vf10 + c->sqc2(vf3, 224, a3); // sqc2 vf3, 224(a3) + c->vmul(DEST::xyzw, vf7, vf17, vf14); // vmul.xyzw vf7, vf17, vf14 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->sqc2(vf1, 0, a3); // sqc2 vf1, 0(a3) + c->vmul(DEST::xyzw, vf10, vf18, vf14); // vmul.xyzw vf10, vf18, vf14 + c->sqc2(vf1, 192, a3); // sqc2 vf1, 192(a3) + // nop // sll r0, r0, 0 + c->sqc2(vf4, 48, a3); // sqc2 vf4, 48(a3) + // nop // sll r0, r0, 0 + c->sqc2(vf7, 96, a3); // sqc2 vf7, 96(a3) + // nop // sll r0, r0, 0 + c->sqc2(vf10, 144, a3); // sqc2 vf10, 144(a3) + c->load_symbol(t9, cache.draw_large_polygon_ocean);// lw t9, draw-large-polygon-ocean(s7) + // Unknown instr: jr t9 + return draw_large_polygon_ocean::execute(c); + // nop // sll r0, r0, 0 + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + cache.draw_large_polygon_ocean = intern_from_c("draw-large-polygon-ocean").c(); + gLinkedFunctionTable.reg("render-ocean-quad", execute, 256); +} + +} // namespace render_ocean_quad +} // namespace Mips2C diff --git a/game/mips2c/mips2c_table.cpp b/game/mips2c/mips2c_table.cpp index 31409ba2a4..dcc576595a 100644 --- a/game/mips2c/mips2c_table.cpp +++ b/game/mips2c/mips2c_table.cpp @@ -260,6 +260,15 @@ extern void link(); namespace ripple_matrix_scale { extern void link(); } +namespace init_ocean_far_regs { +extern void link(); +} +namespace render_ocean_quad { +extern void link(); +} +namespace draw_large_polygon_ocean { +extern void link(); +} LinkedFunctionTable gLinkedFunctionTable; Rng gRng; std::unordered_map> gMips2CLinkCallbacks = { @@ -304,7 +313,9 @@ std::unordered_map> gMips2CLinkCallbacks = generic_prepare_dma_single::link}}, {"ripple", {ripple_execute_init::link, ripple_create_wave_table::link, ripple_apply_wave_table::link, - ripple_matrix_scale::link}}}; + ripple_matrix_scale::link}}, + {"ocean", + {init_ocean_far_regs::link, render_ocean_quad::link, draw_large_polygon_ocean::link}}}; void LinkedFunctionTable::reg(const std::string& name, u64 (*exec)(void*), u32 stack_size) { const auto& it = m_executes.insert({name, {exec, Ptr()}}); diff --git a/goal_src/engine/draw/drawable.gc b/goal_src/engine/draw/drawable.gc index 4fb41b2e28..d4c16a3878 100644 --- a/goal_src/engine/draw/drawable.gc +++ b/goal_src/engine/draw/drawable.gc @@ -1048,7 +1048,7 @@ (update-time-of-day *time-of-day-context*) ;; closest (update-ocean) - ;; draw ocean + ;; (draw-ocean) (set! (-> *merc-global-array* count) (the-as uint 0)) (set! *merc-globals* (the-as merc-globals (-> *merc-global-array* globals))) (set! (-> *shadow-queue* cur-run) (the-as uint 0)) diff --git a/goal_src/engine/gfx/ocean/ocean-h.gc b/goal_src/engine/gfx/ocean/ocean-h.gc index 6ab166c35a..d25e934a8f 100644 --- a/goal_src/engine/gfx/ocean/ocean-h.gc +++ b/goal_src/engine/gfx/ocean/ocean-h.gc @@ -8,6 +8,7 @@ ;; NOTE - for water (define-extern ocean-get-height (function vector float)) (define-extern update-ocean (function none)) +(define-extern draw-ocean (function none)) ;; The "ocean" renderer is used to render the infinite water. ;; It doesn't draw the rivers in FJ or the water near the farmer. diff --git a/goal_src/engine/gfx/ocean/ocean.gc b/goal_src/engine/gfx/ocean/ocean.gc index 33b7f7343a..3f543b243a 100644 --- a/goal_src/engine/gfx/ocean/ocean.gc +++ b/goal_src/engine/gfx/ocean/ocean.gc @@ -8,7 +8,6 @@ ;; TODO - for ocean-transition (define-extern *ocean-map* ocean-map) ;; TODO - for rigid-body -(define-extern ocean-get-height (function vector float)) (defun ocean-get-height ((arg0 vector)) (cond @@ -38,6 +37,661 @@ ) ) +(def-mips2c init-ocean-far-regs (function none)) +(def-mips2c render-ocean-quad (function (inline-array ocean-vertex) dma-buffer symbol)) + +;; (vertices (-> (scratchpad-object terrain-context) work background dma-area ocean-vertex)) + +(defun render-ocean-far ((arg0 dma-buffer) (arg1 int)) + (local-vars + (sv-16 float) + (sv-32 int) + (sv-48 int) + (sv-64 float) + (sv-80 int) + (sv-96 int) + (sv-112 float) + (sv-128 int) + (sv-144 float) + (sv-160 int) + ) + (let* ((s1-0 48) + (s3-0 48) + (f24-0 (-> *ocean-map* start-corner x)) + (f30-0 (-> *ocean-map* start-corner y)) + (f22-0 (-> *ocean-map* start-corner z)) + (f28-0 (+ f22-0 (* 393216.0 (the float s3-0)))) + (f26-0 (+ f24-0 (* 393216.0 (the float s1-0)))) + (vertices (-> (scratchpad-object terrain-context) work background dma-area ocean-vertex)) + ) + (let ((s2-0 #f)) + 0 + (set! (-> vertices 0 col quad) (-> *ocean-map* far-color quad)) + (set! (-> vertices 1 col quad) (-> *ocean-map* far-color quad)) + (set! (-> vertices 2 col quad) (-> *ocean-map* far-color quad)) + (set! (-> vertices 3 col quad) (-> *ocean-map* far-color quad)) + (set-vector! (-> vertices 0 stq) 0.0 0.0 1.0 1.0) + (set-vector! (-> vertices 1 stq) 1.0 0.0 1.0 1.0) + (set-vector! (-> vertices 2 stq) 1.0 15.0 1.0 1.0) + (set-vector! (-> vertices 3 stq) 0.0 15.0 1.0 1.0) + (when (zero? (logand arg1 2)) + (let ((f20-0 (+ -5898240.0 f22-0))) + (set! sv-16 f22-0) + (let ((s0-0 #f)) + (set! sv-32 0) + (set! sv-48 0) + (while (< sv-48 s1-0) + (let ((f0-23 (+ (* 393216.0 (the float sv-48)) f24-0))) + (let ((f1-7 (+ 393216.0 f0-23))) + (let ((v1-19 (-> vertices 0))) + (set! (-> v1-19 pos x) f0-23) + (set! (-> v1-19 pos y) f30-0) + (set! (-> v1-19 pos z) f20-0) + (set! (-> v1-19 pos w) 0.0) + ) + (let ((v1-20 (-> vertices 1))) + (set! (-> v1-20 pos x) f1-7) + (set! (-> v1-20 pos y) f30-0) + (set! (-> v1-20 pos z) f20-0) + (set! (-> v1-20 pos w) 0.0) + ) + (let ((v1-21 (-> vertices 2))) + (set! (-> v1-21 pos x) f1-7) + (set! (-> v1-21 pos y) f30-0) + (set! (-> v1-21 pos z) sv-16) + (set! (-> v1-21 pos w) 1.0) + ) + ) + (let ((v1-22 (-> vertices 3))) + (set! (-> v1-22 pos x) f0-23) + (set! (-> v1-22 pos y) f30-0) + (set! (-> v1-22 pos z) sv-16) + (set! (-> v1-22 pos w) 1.0) + ) + ) + (set! sv-32 (logand (+ sv-32 1) 7)) + (set! s2-0 (render-ocean-quad vertices arg0)) + (cond + (s2-0 + (set! s0-0 #t) + ) + (else + (if s0-0 + (goto cfg-10) + ) + ) + ) + (set! sv-48 (+ sv-48 1)) + ) + ) + ) + ) + (label cfg-10) + (when (zero? (logand arg1 4)) + (let ((f20-1 f28-0)) + (set! sv-64 (+ 5898240.0 f20-1)) + (let ((s0-1 #f)) + (set! sv-80 0) + (set! sv-96 0) + (while (< sv-96 s1-0) + (let ((f0-30 (+ (* 393216.0 (the float sv-96)) f24-0))) + (let ((f1-14 (+ (* 393216.0 (the float (+ sv-96 1))) f24-0))) + (let ((v1-43 (-> vertices 0))) + (set! (-> v1-43 pos x) f0-30) + (set! (-> v1-43 pos y) f30-0) + (set! (-> v1-43 pos z) f20-1) + (set! (-> v1-43 pos w) 1.0) + ) + (let ((v1-44 (-> vertices 1))) + (set! (-> v1-44 pos x) f1-14) + (set! (-> v1-44 pos y) f30-0) + (set! (-> v1-44 pos z) f20-1) + (set! (-> v1-44 pos w) 1.0) + ) + (let ((v1-45 (-> vertices 2))) + (set! (-> v1-45 pos x) f1-14) + (set! (-> v1-45 pos y) f30-0) + (set! (-> v1-45 pos z) sv-64) + (set! (-> v1-45 pos w) 0.0) + ) + ) + (let ((v1-46 (-> vertices 3))) + (set! (-> v1-46 pos x) f0-30) + (set! (-> v1-46 pos y) f30-0) + (set! (-> v1-46 pos z) sv-64) + (set! (-> v1-46 pos w) 0.0) + ) + ) + (set! sv-80 (logand (+ sv-80 1) 7)) + (render-ocean-quad vertices arg0) + (cond + (s2-0 + (set! s0-1 #t) + ) + (else + (if s0-1 + (goto cfg-20) + ) + ) + ) + (set! sv-96 (+ sv-96 1)) + ) + ) + ) + ) + (label cfg-20) + (set-vector! (-> vertices 0 stq) 0.0 0.0 1.0 1.0) + (set-vector! (-> vertices 1 stq) 15.0 0.0 1.0 1.0) + (set-vector! (-> vertices 2 stq) 15.0 1.0 1.0 1.0) + (set-vector! (-> vertices 3 stq) 0.0 1.0 1.0 1.0) + (when (zero? (logand arg1 16)) + (let ((f20-2 (+ -5898240.0 f24-0))) + (set! sv-112 f24-0) + (let ((s1-1 #f)) + (set! sv-128 0) + (dotimes (s0-2 s3-0) + (let* ((f1-19 (+ (* 393216.0 (the float s0-2)) f22-0)) + (f0-53 (+ 393216.0 f1-19)) + ) + (let ((v1-66 (-> vertices 0))) + (set! (-> v1-66 pos x) f20-2) + (set! (-> v1-66 pos y) f30-0) + (set! (-> v1-66 pos z) f1-19) + (set! (-> v1-66 pos w) 0.0) + ) + (let ((v1-67 (-> vertices 1))) + (set! (-> v1-67 pos x) sv-112) + (set! (-> v1-67 pos y) f30-0) + (set! (-> v1-67 pos z) f1-19) + (set! (-> v1-67 pos w) 1.0) + ) + (let ((v1-68 (-> vertices 2))) + (set! (-> v1-68 pos x) sv-112) + (set! (-> v1-68 pos y) f30-0) + (set! (-> v1-68 pos z) f0-53) + (set! (-> v1-68 pos w) 1.0) + ) + (let ((v1-69 (-> vertices 3))) + (set! (-> v1-69 pos x) f20-2) + (set! (-> v1-69 pos y) f30-0) + (set! (-> v1-69 pos z) f0-53) + (set! (-> v1-69 pos w) 0.0) + ) + ) + (set! sv-128 (logand (+ sv-128 1) 7)) + (render-ocean-quad vertices arg0) + (cond + (s2-0 + (set! s1-1 #t) + ) + (else + (if s1-1 + (goto cfg-30) + ) + ) + ) + ) + ) + ) + ) + (label cfg-30) + (when (zero? (logand arg1 8)) + (let ((f20-3 f26-0)) + (set! sv-144 (+ 5898240.0 f26-0)) + (let ((s1-2 #f)) + (set! sv-160 0) + (dotimes (s0-3 s3-0) + (let* ((f1-25 (+ (* 393216.0 (the float s0-3)) f22-0)) + (f0-60 (+ 393216.0 f1-25)) + ) + (let ((v1-83 (-> vertices 0))) + (set! (-> v1-83 pos x) f20-3) + (set! (-> v1-83 pos y) f30-0) + (set! (-> v1-83 pos z) f1-25) + (set! (-> v1-83 pos w) 1.0) + ) + (let ((v1-84 (-> vertices 1))) + (set! (-> v1-84 pos x) sv-144) + (set! (-> v1-84 pos y) f30-0) + (set! (-> v1-84 pos z) f1-25) + (set! (-> v1-84 pos w) 0.0) + ) + (let ((v1-85 (-> vertices 2))) + (set! (-> v1-85 pos x) sv-144) + (set! (-> v1-85 pos y) f30-0) + (set! (-> v1-85 pos z) f0-60) + (set! (-> v1-85 pos w) 0.0) + ) + (let ((v1-86 (-> vertices 3))) + (set! (-> v1-86 pos x) f20-3) + (set! (-> v1-86 pos y) f30-0) + (set! (-> v1-86 pos z) f0-60) + (set! (-> v1-86 pos w) 1.0) + ) + ) + (set! sv-160 (logand (+ sv-160 1) 7)) + (render-ocean-quad vertices arg0) + (cond + (s2-0 + (set! s1-2 #t) + ) + (else + (if s1-2 + (goto cfg-40) + ) + ) + ) + ) + ) + ) + ) + ) + (label cfg-40) + (set-vector! (-> vertices 0 stq) 0.0 0.0 1.0 1.0) + (set-vector! (-> vertices 1 stq) 15.0 0.0 1.0 1.0) + (set-vector! (-> vertices 2 stq) 15.0 15.0 1.0 1.0) + (set-vector! (-> vertices 3 stq) 0.0 15.0 1.0 1.0) + (when (not (or (logtest? arg1 2) (logtest? arg1 16))) + (let ((f0-79 (+ -5898240.0 f24-0)) + (f3-0 (+ -5898240.0 f22-0)) + (f2-10 f24-0) + (f1-30 f22-0) + ) + (let ((v1-105 (-> vertices 0))) + (set! (-> v1-105 pos x) f0-79) + (set! (-> v1-105 pos y) f30-0) + (set! (-> v1-105 pos z) f3-0) + (set! (-> v1-105 pos w) 0.0) + ) + (let ((v1-106 (-> vertices 1))) + (set! (-> v1-106 pos x) f2-10) + (set! (-> v1-106 pos y) f30-0) + (set! (-> v1-106 pos z) f3-0) + (set! (-> v1-106 pos w) 0.0) + ) + (let ((v1-107 (-> vertices 2))) + (set! (-> v1-107 pos x) f2-10) + (set! (-> v1-107 pos y) f30-0) + (set! (-> v1-107 pos z) f1-30) + (set! (-> v1-107 pos w) 1.0) + ) + (let ((v1-108 (-> vertices 3))) + (set! (-> v1-108 pos x) f0-79) + (set! (-> v1-108 pos y) f30-0) + (set! (-> v1-108 pos z) f1-30) + (set! (-> v1-108 pos w) 0.0) + ) + ) + (render-ocean-quad vertices arg0) + ) + (when (not (or (logtest? arg1 2) (logtest? arg1 8))) + (let ((f0-81 f26-0)) + (let ((f2-12 (+ -5898240.0 f22-0)) + (f1-33 (+ 5898240.0 f26-0)) + ) + (let ((v1-114 (-> vertices 0))) + (set! (-> v1-114 pos x) f0-81) + (set! (-> v1-114 pos y) f30-0) + (set! (-> v1-114 pos z) f2-12) + (set! (-> v1-114 pos w) 0.0) + ) + (let ((v1-115 (-> vertices 1))) + (set! (-> v1-115 pos x) f1-33) + (set! (-> v1-115 pos y) f30-0) + (set! (-> v1-115 pos z) f2-12) + (set! (-> v1-115 pos w) 0.0) + ) + (let ((v1-116 (-> vertices 2))) + (set! (-> v1-116 pos x) f1-33) + (set! (-> v1-116 pos y) f30-0) + (set! (-> v1-116 pos z) f22-0) + (set! (-> v1-116 pos w) 0.0) + ) + ) + (let ((v1-117 (-> vertices 3))) + (set! (-> v1-117 pos x) f0-81) + (set! (-> v1-117 pos y) f30-0) + (set! (-> v1-117 pos z) f22-0) + (set! (-> v1-117 pos w) 1.0) + ) + ) + (render-ocean-quad vertices arg0) + ) + (when (not (or (logtest? arg1 4) (logtest? arg1 16))) + (let ((f0-84 (+ -5898240.0 f24-0)) + (f2-14 f28-0) + (f1-36 (+ 5898240.0 f28-0)) + ) + (let ((v1-123 (-> vertices 0))) + (set! (-> v1-123 pos x) f0-84) + (set! (-> v1-123 pos y) f30-0) + (set! (-> v1-123 pos z) f2-14) + (set! (-> v1-123 pos w) 0.0) + ) + (let ((v1-124 (-> vertices 1))) + (set! (-> v1-124 pos x) f24-0) + (set! (-> v1-124 pos y) f30-0) + (set! (-> v1-124 pos z) f2-14) + (set! (-> v1-124 pos w) 1.0) + ) + (let ((v1-125 (-> vertices 2))) + (set! (-> v1-125 pos x) f24-0) + (set! (-> v1-125 pos y) f30-0) + (set! (-> v1-125 pos z) f1-36) + (set! (-> v1-125 pos w) 0.0) + ) + (let ((v1-126 (-> vertices 3))) + (set! (-> v1-126 pos x) f0-84) + (set! (-> v1-126 pos y) f30-0) + (set! (-> v1-126 pos z) f1-36) + (set! (-> v1-126 pos w) 0.0) + ) + ) + (render-ocean-quad vertices arg0) + ) + (when (not (or (logtest? arg1 4) (logtest? arg1 8))) + (let ((f0-86 f26-0) + (f1-37 f28-0) + (f2-18 (+ 5898240.0 f26-0)) + (f3-5 (+ 5898240.0 f28-0)) + ) + (let ((v1-131 (-> vertices 0))) + (set! (-> v1-131 pos x) f0-86) + (set! (-> v1-131 pos y) f30-0) + (set! (-> v1-131 pos z) f1-37) + (set! (-> v1-131 pos w) 1.0) + ) + (let ((v1-132 (-> vertices 1))) + (set! (-> v1-132 pos x) f2-18) + (set! (-> v1-132 pos y) f30-0) + (set! (-> v1-132 pos z) f1-37) + (set! (-> v1-132 pos w) 0.0) + ) + (let ((v1-133 (-> vertices 2))) + (set! (-> v1-133 pos x) f2-18) + (set! (-> v1-133 pos y) f30-0) + (set! (-> v1-133 pos z) f3-5) + (set! (-> v1-133 pos w) 0.0) + ) + (let ((v1-134 (-> vertices 3))) + (set! (-> v1-134 pos x) f0-86) + (set! (-> v1-134 pos y) f30-0) + (set! (-> v1-134 pos z) f3-5) + (set! (-> v1-134 pos w) 0.0) + ) + ) + (render-ocean-quad vertices arg0) + ) + ) + (none) + ) + +;; definition for symbol *swamp-low-ocean-marker*, type vector +(define *swamp-low-ocean-marker* (new 'global 'vector)) + +;; failed to figure out what this is: +(set-vector! *swamp-low-ocean-marker* 2621440.0 0.0 -8151040.0 1.0) + +(defun draw-ocean-far ((arg0 dma-buffer)) + (init-ocean-far-regs) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x40 :b #x40 :a #x80) + ) + ) + (let ((gp-0 (the-as object (-> arg0 base)))) + (&+! (-> arg0 base) 16) + (let ((v1-9 *ocean-facing*)) + (cond + ((zero? v1-9) + (render-ocean-far arg0 4) + ) + ((= v1-9 1) + (render-ocean-far arg0 2) + ) + ((= v1-9 3) + (render-ocean-far arg0 8) + ) + ((= v1-9 2) + (render-ocean-far arg0 16) + ) + ) + ) + (close-sky-buffer arg0) + (let ((v1-18 (/ (the-as int (+ (- -16 (the-as int gp-0)) (the-as int (-> arg0 base)))) 16))) + (set! (-> (the-as dma-packet gp-0) dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc v1-18)) + (set! (-> (the-as dma-packet gp-0) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet gp-0) vif1) (new 'static 'vif-tag :cmd (vif-cmd direct) :msk #x1 :imm v1-18)) + ) + ) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :g #xff :a #x80) + ) + ) + ) + +(defun ocean-init-buffer ((arg0 dma-buffer)) + (let* ((a1-0 *ocean-base-page*) + (v1-0 *ocean-base-block*) + (s3-0 (* (+ a1-0 8) 32)) + (gp-0 (* (+ a1-0 10) 32)) + ) + (let* ((a1-2 arg0) + (a2-1 (the-as object (-> a1-2 base))) + ) + (set! (-> (the-as dma-packet a2-1) dma) (new 'static 'dma-tag :qwc #xa :id (dma-tag-id cnt))) + (set! (-> (the-as dma-packet a2-1) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet a2-1) vif1) (new 'static 'vif-tag :imm #xa :cmd (vif-cmd direct) :msk #x1)) + (set! (-> a1-2 base) (the-as pointer (&+ (the-as dma-packet a2-1) 16))) + ) + (let* ((a1-3 arg0) + (a2-3 (the-as object (-> a1-3 base))) + ) + (set! (-> (the-as gs-gif-tag a2-3) tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x9)) + (set! (-> (the-as gs-gif-tag a2-3) regs) (new 'static 'gif-tag-regs + :regs0 (gif-reg-id a+d) + :regs1 (gif-reg-id a+d) + :regs2 (gif-reg-id a+d) + :regs3 (gif-reg-id a+d) + :regs4 (gif-reg-id a+d) + :regs5 (gif-reg-id a+d) + :regs6 (gif-reg-id a+d) + :regs7 (gif-reg-id a+d) + :regs8 (gif-reg-id a+d) + :regs9 (gif-reg-id a+d) + :regs10 (gif-reg-id a+d) + :regs11 (gif-reg-id a+d) + :regs12 (gif-reg-id a+d) + :regs13 (gif-reg-id a+d) + :regs14 (gif-reg-id a+d) + :regs15 (gif-reg-id a+d) + ) + ) + (set! (-> a1-3 base) (&+ (the-as pointer a2-3) 16)) + ) + (let* ((s5-0 arg0) + (s4-0 (-> s5-0 base)) + ) + (set! (-> (the-as (pointer gs-test) s4-0) 0) + (new 'static 'gs-test :ate #x1 :atst (gs-atest always) :zte #x1 :ztst (gs-ztest always)) + ) + (set! (-> (the-as (pointer gs-reg64) s4-0) 1) (gs-reg64 test-1)) + (set! (-> (the-as (pointer gs-alpha) s4-0) 2) (new 'static 'gs-alpha :b #x1 :d #x1)) + (set! (-> (the-as (pointer gs-reg64) s4-0) 3) (gs-reg64 alpha-1)) + (set! (-> (the-as (pointer gs-tex0) s4-0) 4) + (new 'static 'gs-tex0 :tbw #x2 :th (log2 128) :tw (log2 128) :tbp0 v1-0) + ) + (set! (-> (the-as (pointer gs-reg64) s4-0) 5) (gs-reg64 tex0-1)) + (set! (-> (the-as (pointer gs-tex1) s4-0) 6) + (new 'static 'gs-tex1 :mxl #x6 :mmag #x1 :mmin #x4 :l #x1 :k #xeed) + ) + (set! (-> (the-as (pointer gs-reg64) s4-0) 7) (gs-reg64 tex1-1)) + (set! (-> (the-as (pointer gs-texa) s4-0) 8) (new 'static 'gs-texa :ta0 #x80 :ta1 #x80)) + (set! (-> (the-as (pointer gs-reg64) s4-0) 9) (gs-reg64 texa)) + (set! (-> (the-as (pointer gs-miptbp) s4-0) 10) + (new 'static 'gs-miptbp :tbw1 #x1 :tbw2 #x1 :tbw3 #x1 :tbp3 (+ gp-0 16) :tbp2 gp-0 :tbp1 s3-0) + ) + (set! (-> (the-as (pointer gs-reg64) s4-0) 11) (gs-reg64 miptbp1-1)) + (set! (-> (the-as (pointer gs-miptbp) s4-0) 12) + (new 'static 'gs-miptbp :tbw1 #x1 :tbw2 #x1 :tbw3 #x1 :tbp3 (+ gp-0 22) :tbp2 (+ gp-0 21) :tbp1 (+ gp-0 20)) + ) + (set! (-> (the-as (pointer gs-reg64) s4-0) 13) (gs-reg64 miptbp2-1)) + (set! (-> (the-as (pointer gs-clamp) s4-0) 14) (new 'static 'gs-clamp)) + (set! (-> (the-as (pointer gs-reg64) s4-0) 15) (gs-reg64 clamp-1)) + (set! (-> (the-as (pointer gs-fogcol) s4-0) 16) (the-as gs-fogcol *fog-color*)) + (set! (-> (the-as (pointer gs-reg64) s4-0) 17) (gs-reg64 fogcol)) + (let ((v0-2 (&+ s4-0 144))) + (set! (-> s5-0 base) v0-2) + v0-2 + ) + ) + ) + ) + +(defun ocean-end-buffer ((arg0 dma-buffer)) + (let* ((v1-0 arg0) + (a1-0 (the-as object (-> v1-0 base))) + ) + (set! (-> (the-as dma-packet a1-0) dma) (new 'static 'dma-tag :qwc #x2 :id (dma-tag-id cnt))) + (set! (-> (the-as dma-packet a1-0) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet a1-0) vif1) (new 'static 'vif-tag :imm #x2 :cmd (vif-cmd direct) :msk #x1)) + (set! (-> v1-0 base) (&+ (the-as pointer a1-0) 16)) + ) + (let* ((v1-1 arg0) + (a1-2 (the-as object (-> v1-1 base))) + ) + (set! (-> (the-as gs-gif-tag a1-2) tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x1)) + (set! (-> (the-as gs-gif-tag a1-2) regs) + (new 'static 'gif-tag-regs + :regs0 (gif-reg-id a+d) + :regs1 (gif-reg-id a+d) + :regs2 (gif-reg-id a+d) + :regs3 (gif-reg-id a+d) + :regs4 (gif-reg-id a+d) + :regs5 (gif-reg-id a+d) + :regs6 (gif-reg-id a+d) + :regs7 (gif-reg-id a+d) + :regs8 (gif-reg-id a+d) + :regs9 (gif-reg-id a+d) + :regs10 (gif-reg-id a+d) + :regs11 (gif-reg-id a+d) + :regs12 (gif-reg-id a+d) + :regs13 (gif-reg-id a+d) + :regs14 (gif-reg-id a+d) + :regs15 (gif-reg-id a+d) + ) + ) + (set! (-> v1-1 base) (&+ (the-as pointer a1-2) 16)) + ) + (let* ((v1-2 arg0) + (a0-1 (-> v1-2 base)) + ) + (set! (-> (the-as (pointer gs-texa) a0-1) 0) (new 'static 'gs-texa :ta1 #x80)) + (set! (-> (the-as (pointer gs-reg64) a0-1) 1) (gs-reg64 texa)) + (let ((v0-0 (&+ a0-1 16))) + (set! (-> v1-2 base) v0-0) + v0-0 + ) + ) + ) + +(defun draw-ocean () + (set! *ocean-heights* #f) + (set! *ocean-verts* (the-as (pointer vector) #f)) + ; (let ((gp-0 (-> *display* frames (-> *display* on-screen) frame global-buf))) + ; (set! *ocean-heights* (the-as ocean-wave-info (-> gp-0 base))) + ; (ocean-interp-wave *ocean-heights* (the-as uint (-> *display* integral-frame-counter))) + ; (&+! (-> gp-0 base) 4096) + ; (set! *ocean-verts* (the-as (pointer vector) (-> gp-0 base))) + ; (ocean-generate-verts *ocean-verts* *ocean-heights*) + ; (&+! (-> gp-0 base) #x8000) + ; ) + (when *ocean-map* + (let* ((v1-12 (camera-pos)) + (a0-6 *swamp-low-ocean-marker*) + (f0-1 (* 0.00024414062 (- (-> v1-12 x) (-> a0-6 x)))) + (f0-3 (* f0-1 f0-1)) + (f1-3 (* 0.00024414062 (- (-> v1-12 z) (-> a0-6 z)))) + ) + (cond + ((< (+ f0-3 (* f1-3 f1-3)) 40000.0) + (set! (-> *ocean-map* start-corner y) -4096.0) + ) + ((or (< -409600.0 (-> v1-12 y)) (movie?)) + (set! (-> *ocean-map* start-corner y) 0.0) + ) + (else + (set! (-> *ocean-map* start-corner y) -98304.0) + ) + ) + ) + (when (not *ocean-off*) + (when (logtest? *vu1-enable-user* (vu1-renderer-mask ocean)) + (let* ((s5-0 (-> *display* frames (-> *display* on-screen) frame global-buf)) + (gp-1 (-> s5-0 base)) + ) + ;; (draw-ocean-texture s5-0 *ocean-verts* #t) + (ocean-init-buffer s5-0) + (draw-ocean-far s5-0) + ; (if (not *ocean-mid-off*) + ; (draw-ocean-mid s5-0) + ; ) + (ocean-end-buffer s5-0) + (let ((a3-0 (-> s5-0 base))) + (let ((v1-32 (the-as object (-> s5-0 base)))) + (set! (-> (the-as dma-packet v1-32) dma) (new 'static 'dma-tag :id (dma-tag-id next))) + (set! (-> (the-as dma-packet v1-32) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet v1-32) vif1) (new 'static 'vif-tag)) + (set! (-> s5-0 base) (&+ (the-as pointer v1-32) 16)) + ) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) frame bucket-group) + (bucket-id bucket-4) + gp-1 + (the-as (pointer dma-tag) a3-0) + ) + ) + ) + ; (when (not (or *ocean-near-off* (or *ocean-mid-off* (< 196608.0 (fabs (-> *math-camera* trans y)))))) + ; (let* ((s5-1 (-> *display* frames (-> *display* on-screen) frame global-buf)) + ; (gp-2 (-> s5-1 base)) + ; ) + ; (draw-ocean-texture s5-1 *ocean-verts* #f) + ; (draw-ocean-near s5-1) + ; (ocean-end-buffer s5-1) + ; (let ((a3-1 (-> s5-1 base))) + ; (let ((v1-46 (the-as object (-> s5-1 base)))) + ; (set! (-> (the-as dma-packet v1-46) dma) (new 'static 'dma-tag :id (dma-tag-id next))) + ; (set! (-> (the-as dma-packet v1-46) vif0) (new 'static 'vif-tag)) + ; (set! (-> (the-as dma-packet v1-46) vif1) (new 'static 'vif-tag)) + ; (set! (-> s5-1 base) (&+ (the-as pointer v1-46) 16)) + ; ) + ; (dma-bucket-insert-tag + ; (-> *display* frames (-> *display* on-screen) frame bucket-group) + ; (bucket-id bucket-63) + ; gp-2 + ; (the-as (pointer dma-tag) a3-1) + ; ) + ; ) + ; ) + ; ) + ) + ) + ) + (when (not (paused?)) + (set! *ocean-off* #f) + (set! *ocean-mid-off* #f) + (set! *ocean-near-off* #f) + ) + 0 + (none) + ) + (defun update-ocean () (set! *ocean-map* #f) (dotimes (v1-0 (-> *level* length))