From 2b6684aa5c24e79543ad7da33f8cc575c75eb07e Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Sun, 25 Jul 2021 15:30:37 -0400 Subject: [PATCH] [decompiler] Working toward `bsp` (#717) * clean up * before int to float stuff * before trying to eliminate the separate read and write maps * partial fix for register issues * add missing include --- common/goos/Object.cpp | 26 + common/goos/Object.h | 5 +- decompiler/Disasm/InstructionParser.cpp | 80 +- decompiler/Disasm/InstructionParser.h | 1 + decompiler/Disasm/OpcodeInfo.cpp | 104 +- decompiler/Disasm/OpcodeInfo.h | 3 + decompiler/Function/CfgVtx.cpp | 6 +- decompiler/IR2/Env.cpp | 17 +- decompiler/IR2/FormExpressionAnalysis.cpp | 11 +- decompiler/IR2/OpenGoalMapping.cpp | 6 +- decompiler/analysis/atomic_op_builder.cpp | 3 +- decompiler/analysis/variable_naming.cpp | 100 ++ decompiler/config/all-types.gc | 359 +++--- .../config/jak1_ntsc_black_label/hacks.jsonc | 21 +- .../jak1_ntsc_black_label/label_types.jsonc | 59 +- .../jak1_ntsc_black_label/type_casts.jsonc | 119 +- .../jak1_ntsc_black_label/var_names.jsonc | 252 ++++ decompiler/util/DecompilerTypeSystem.cpp | 5 + goal_src/engine/camera/cam-debug-h.gc | 2 + goal_src/engine/collide/collide-frag.gc | 30 +- goal_src/engine/collide/collide-func.gc | 165 +++ goal_src/engine/debug/memory-usage-h.gc | 5 +- goal_src/engine/debug/stats-h.gc | 3 +- goal_src/engine/dma/dma-h.gc | 1 + goal_src/engine/draw/drawable-actor-h.gc | 1 + goal_src/engine/draw/drawable-ambient-h.gc | 1 + goal_src/engine/draw/drawable-h.gc | 15 +- goal_src/engine/draw/drawable-inline-array.gc | 6 +- goal_src/engine/geometry/cylinder.gc | 337 +++++- goal_src/engine/gfx/sprite/sprite-h.gc | 17 +- goal_src/engine/gfx/sprite/sprite.gc | 1024 +++++++++++++++++ goal_src/engine/gfx/texture.gc | 2 + goal_src/engine/gfx/tfrag/subdivide-h.gc | 6 +- goal_src/engine/gfx/tfrag/subdivide.gc | 416 ++++++- goal_src/engine/gfx/tfrag/tfrag-h.gc | 2 + goal_src/engine/gfx/vis/bsp-h.gc | 93 +- goal_src/engine/gfx/vis/bsp.gc | 650 +++++++++++ goal_src/engine/level/level-h.gc | 32 +- goal_src/engine/level/level.gc | 16 +- goal_src/engine/math/vector-h.gc | 15 +- goal_src/kernel/gcommon.gc | 2 +- goal_src/kernel/gkernel-h.gc | 5 + goal_src/kernel/gkernel.gc | 4 + goalc/compiler/Compiler.h | 3 + goalc/compiler/IR.cpp | 18 + goalc/compiler/IR.h | 2 +- goalc/compiler/compilation/Asm.cpp | 52 + goalc/compiler/compilation/Atoms.cpp | 4 + goalc/emitter/IGen.h | 41 +- test/CMakeLists.txt | 1 + test/decompiler/FormRegressionTest.cpp | 5 + .../engine/collide/collide-frag_REF.gc | 30 +- .../reference/engine/data/res_REF.gc | 12 +- .../reference/engine/debug/stats-h_REF.gc | 3 +- .../engine/draw/drawable-actor-h_REF.gc | 2 + .../engine/draw/drawable-ambient-h_REF.gc | 2 + .../reference/engine/draw/drawable-h_REF.gc | 12 +- .../engine/draw/drawable-inline-array_REF.gc | 9 +- .../reference/engine/geometry/cylinder_REF.gc | 384 +++++++ .../engine/gfx/sprite/sprite-h_REF.gc | 54 +- .../reference/engine/gfx/texture_REF.gc | 28 +- .../engine/gfx/tfrag/subdivide-h_REF.gc | 4 +- .../engine/gfx/tfrag/subdivide_REF.gc | 540 +++++++++ .../reference/engine/gfx/vis/bsp-h_REF.gc | 57 +- .../reference/engine/gfx/vis/bsp_REF.gc | 653 +++++++++++ .../reference/engine/level/level-h_REF.gc | 36 +- .../reference/engine/math/trigonometry_REF.gc | 4 +- .../reference/engine/math/vector-h_REF.gc | 8 +- .../reference/engine/math/vector_REF.gc | 16 +- test/decompiler/test_FormExpressionBuild3.cpp | 56 + test/decompiler/test_InstructionParser.cpp | 18 +- .../with_game/test-pand-por-pnor.gc | 51 + test/goalc/test_with_game.cpp | 11 + test/offline/offline_test_main.cpp | 18 +- test/test_emitter_avx.cpp | 45 + test/test_goos.cpp | 3 + 76 files changed, 5695 insertions(+), 514 deletions(-) create mode 100644 test/decompiler/reference/engine/geometry/cylinder_REF.gc create mode 100644 test/decompiler/reference/engine/gfx/tfrag/subdivide_REF.gc create mode 100644 test/decompiler/reference/engine/gfx/vis/bsp_REF.gc create mode 100644 test/decompiler/test_FormExpressionBuild3.cpp create mode 100644 test/goalc/source_templates/with_game/test-pand-por-pnor.gc diff --git a/common/goos/Object.cpp b/common/goos/Object.cpp index 16db652654..9f004a668d 100644 --- a/common/goos/Object.cpp +++ b/common/goos/Object.cpp @@ -304,4 +304,30 @@ bool Arguments::only_contains_named(const std::unordered_set& names return true; } +namespace { +std::string escape_string(const std::string& in) { + std::string result; + result.reserve(in.size()); + + for (char c : in) { + if (c == '"') { + result.push_back('\\'); + result.push_back('"'); + } else { + result.push_back(c); + } + } + + return result; +} +} // namespace + +std::string StringObject::print() const { + return "\"" + escape_string(data) + "\""; +} + +std::string StringObject::inspect() const { + return "[string] \"" + escape_string(data) + "\"\n"; +} + } // namespace goos diff --git a/common/goos/Object.h b/common/goos/Object.h index dd39d5c204..518bdbbcb2 100644 --- a/common/goos/Object.h +++ b/common/goos/Object.h @@ -416,9 +416,8 @@ class StringObject : public HeapObject { return obj; } - std::string print() const override { return "\"" + data + "\""; } - - std::string inspect() const override { return "[string] \"" + data + "\"\n"; } + std::string print() const override; + std::string inspect() const override; ~StringObject() override = default; }; diff --git a/decompiler/Disasm/InstructionParser.cpp b/decompiler/Disasm/InstructionParser.cpp index aa1db16f1a..7bf85de01c 100644 --- a/decompiler/Disasm/InstructionParser.cpp +++ b/decompiler/Disasm/InstructionParser.cpp @@ -1,6 +1,7 @@ #include "common/util/assert.h" #include #include +#include #include "common/common_types.h" #include "InstructionParser.h" @@ -46,14 +47,24 @@ InstructionParser::InstructionParser() { InstructionKind::MFLO1, InstructionKind::SYNCL, InstructionKind::PCPYUD, InstructionKind::PEXTUW, InstructionKind::POR, InstructionKind::VMOVE, InstructionKind::VSUB, InstructionKind::LQC2, InstructionKind::SQC2, - InstructionKind::MULAS, InstructionKind::MADDAS}) { + InstructionKind::MULAS, InstructionKind::MADDAS, InstructionKind::QMTC2, + InstructionKind::QMFC2, InstructionKind::VITOF0, InstructionKind::VFTOI0, + InstructionKind::PSLLW, InstructionKind::PSRAW}) { auto& info = gOpcodeInfo[int(i)]; if (info.defined) { m_opcode_name_lookup[info.name] = int(i); added++; } } - assert(added == int(m_opcode_name_lookup.size())); + + for (auto i : {InstructionKind::VMUL_BC}) { + auto& info = gOpcodeInfo[int(i)]; + if (info.defined) { + m_opcode_name_broadcast_lookup[info.name] = int(i); + added++; + } + } + assert(added == int(m_opcode_name_lookup.size()) + int(m_opcode_name_broadcast_lookup.size())); } namespace { @@ -89,6 +100,18 @@ std::string get_instr_name(std::string& instr) { } } auto name = instr.substr(0, i); + + // qmXc2.i should not grab the i. + if (name == "qmtc2.i") { + name = "qmtc2"; // strip .i + i -= 2; // leave the i for the next step. + } + + if (name == "qmfc2.i") { + name = "qmfc2"; // strip .i + i -= 2; // leave the i for the next step. + } + if (i == instr.length()) { instr.clear(); } else { @@ -220,14 +243,34 @@ Instruction InstructionParser::parse_single_instruction( std::string str, const std::vector& labels) { auto name = get_instr_name(str); + + std::optional op_idx; auto lookup = m_opcode_name_lookup.find(name); if (lookup == m_opcode_name_lookup.end()) { + // it might be a VU with broadcast. + if (!name.empty() && name.front() == 'v') { + char last_char = name.back(); + if (last_char == 'x' || last_char == 'y' || last_char == 'z' || last_char == 'w') { + str.insert(str.begin(), ' '); + str.insert(str.begin(), last_char); + name.pop_back(); + auto bc_lookup = m_opcode_name_broadcast_lookup.find(name); + if (bc_lookup != m_opcode_name_broadcast_lookup.end()) { + op_idx = bc_lookup->second; + } + } + } + } else { + op_idx = lookup->second; + } + + if (!op_idx) { throw std::runtime_error("InstructionParser cannot handle opcode " + name); } Instruction instr; - instr.kind = InstructionKind(lookup->second); - auto& info = gOpcodeInfo[lookup->second]; + instr.kind = InstructionKind(*op_idx); + auto& info = gOpcodeInfo[*op_idx]; for (u8 i = 0; i < info.step_count; i++) { auto& step = info.steps[i]; switch (step.decode) { @@ -333,7 +376,36 @@ Instruction InstructionParser::parse_single_instruction( break; } + case DecodeType::IL: { + auto thing = get_until_space(str); + if (thing == "i") { + instr.il = 1; + } else if (thing == "ni") { + instr.il = 0; + } else { + printf("Bad interlock specification. Got %s\n", thing.c_str()); + assert(false); + } + } break; + + case DecodeType::BC: { + auto thing = get_until_space(str); + if (thing == "x") { + instr.cop2_bc = 0; + } else if (thing == "y") { + instr.cop2_bc = 1; + } else if (thing == "z") { + instr.cop2_bc = 2; + } else if (thing == "w") { + instr.cop2_bc = 3; + } else { + printf("Bad broadcast. Got %s\n", thing.c_str()); + assert(false); + } + } break; + default: + printf("missing DecodeType: %d\n", (int)step.decode); assert(false); } } diff --git a/decompiler/Disasm/InstructionParser.h b/decompiler/Disasm/InstructionParser.h index 5bff880f10..6bbcaa4802 100644 --- a/decompiler/Disasm/InstructionParser.h +++ b/decompiler/Disasm/InstructionParser.h @@ -26,5 +26,6 @@ class InstructionParser { private: std::unordered_map m_opcode_name_lookup; + std::unordered_map m_opcode_name_broadcast_lookup; }; } // namespace decompiler \ No newline at end of file diff --git a/decompiler/Disasm/OpcodeInfo.cpp b/decompiler/Disasm/OpcodeInfo.cpp index 0e12baf2a1..de13ecadc6 100644 --- a/decompiler/Disasm/OpcodeInfo.cpp +++ b/decompiler/Disasm/OpcodeInfo.cpp @@ -253,16 +253,16 @@ void init_opcode_info() { .dst(FT::RD, DT::COP0); // Move to System Control Coprocessor def(IK::MFC0, "mfc0") .dst_gpr(FT::RT) - .src(FT::RD, DT::COP0); // Move from System Control Coprocessor - def(IK::MTDAB, "mtdab").src_gpr(FT::RT); // Move to Data Address Breakpoint Register - def(IK::MTDABM, "mtdabm").src_gpr(FT::RT); // Move to Data Address Breakpoint Mask Register - drd(def(IK::MFHI, "mfhi")); // Move from HI Register - drd(def(IK::MFLO, "mflo")); // Move from LO Register - def(IK::MTLO1, "mtlo1").src_gpr(FT::RS); // Move to LO1 Register - drd(def(IK::MFLO1, "mflo1")); // Move from LO1 Register - drd(def(IK::PMFHL_UW, "pmfhl.uw")); // Parallel Move From HI/LO Register - drd(def(IK::PMFHL_LW, "pmfhl.lw")); - drd(def(IK::PMFHL_LH, "pmfhl.lh")); + .src(FT::RD, DT::COP0); // Move from System Control Coprocessor + def(IK::MTDAB, "mtdab").src_gpr(FT::RT); // Move to Data Address Breakpoint Register + def(IK::MTDABM, "mtdabm").src_gpr(FT::RT); // Move to Data Address Breakpoint Mask Register + drd(def(IK::MFHI, "mfhi")); // Move from HI Register + drd(def(IK::MFLO, "mflo")); // Move from LO Register + def(IK::MTLO1, "mtlo1").src_gpr(FT::RS); // Move to LO1 Register + drd(def(IK::MFLO1, "mflo1")); // Move from LO1 Register + drd(def(IK::PMFHL_UW, "pmfhl.uw").gpr128()); // Parallel Move From HI/LO Register + drd(def(IK::PMFHL_LW, "pmfhl.lw").gpr128()); + drd(def(IK::PMFHL_LH, "pmfhl.lh").gpr128()); def(IK::MFPC, "mfpc").dst_gpr(FT::RT).src(FT::PCR, DT::PCR); // Move from Performance Counter def(IK::MTPC, "mtpc").src_gpr(FT::RT).dst(FT::PCR, DT::PCR); // Move to Performance Counter @@ -279,45 +279,48 @@ void init_opcode_info() { def(IK::ERET, "eret"); // Exception Return def(IK::EI, "ei"); // Enable Interrupt - drd_srs_srt(def(IK::PPACB, "ppacb")); // Parallel Pack to Byte - drd_srs_srt(def(IK::PPACH, "ppach")); // Parallel Pack to Halfword - drd_srs_srt(def(IK::PPACW, "ppacw")); // Parallel Pack to Word - drd_srs_srt(def(IK::PADDH, "paddh")); // Parallel Add Halfword - drd_srs_srt(def(IK::PADDW, "paddw")); // Parallel Add Word - drd_srs_srt(def(IK::PSUBW, "psubw")); // Parallel Subtract Word - drd_srs_srt(def(IK::PMINH, "pminh")); // Parallel Minimize Halfword - drd_srs_srt(def(IK::PMINW, "pminw")); // Parallel Minimize Word - drd_srs_srt(def(IK::PMAXH, "pmaxh")); // Parallel Maximize Halfword - drd_srs_srt(def(IK::PMAXW, "pmaxw")); // Parallel Maximize Word - drd_srs_srt(def(IK::PEXTLB, "pextlb")); // Parallel Extend Lower from Byte - drd_srs_srt(def(IK::PEXTLH, "pextlh")); // Parallel Extend Lower from Halfword - drd_srs_srt(def(IK::PEXTLW, "pextlw")); // Parallel Extend Lower from Word - drd_srs_srt(def(IK::PCGTW, "pcgtw")); // Parallel Compare for Greater Than Word - drd_srs_srt(def(IK::PCEQB, "pceqb")); // Parallel Compare for Equal Byte - drd_srs_srt(def(IK::PCEQW, "pceqw")); // Parallel Compare for Equal Word - drd_srs_srt(def(IK::PEXTUB, "pextub")); // Parallel Extend Upper from Byte - drd_srs_srt(def(IK::PEXTUH, "pextuh")); // Parallel Extend Upper from Halfword - drd_srs_srt(def(IK::PEXTUW, "pextuw")); // Parallel Extend Upper from Word - drd_srs_srt(def(IK::PCPYUD, "pcpyud")); // Parallel Copy Upper Doubleword - drd_srs_srt(def(IK::PCPYLD, "pcpyld")); // Parallel Copy Lower Doubleword - drd_srs_srt(def(IK::PMADDH, "pmaddh")); // Parallel Multiply-Add Halfword - drd_srs_srt(def(IK::PMULTH, "pmulth")); // Parallel Multiply Halfword - drd_srs_srt(def(IK::PEXEW, "pexew")); // Parallel Exchange Even Word - drd_srs_srt(def(IK::PINTEH, "pinteh")); // Parallel Interleave Even Halfword - drd_srs_srt(def(IK::PAND, "pand")); // Parallel And - drd_srs_srt(def(IK::POR, "por")); // Parallel Or - drd_srs_srt(def(IK::PNOR, "pnor")); // Parallel Not Or + drd_srs_srt(def(IK::PPACB, "ppacb").gpr128()); // Parallel Pack to Byte + drd_srs_srt(def(IK::PPACH, "ppach").gpr128()); // Parallel Pack to Halfword + drd_srs_srt(def(IK::PPACW, "ppacw").gpr128()); // Parallel Pack to Word + drd_srs_srt(def(IK::PADDH, "paddh").gpr128()); // Parallel Add Halfword + drd_srs_srt(def(IK::PADDW, "paddw").gpr128()); // Parallel Add Word + drd_srs_srt(def(IK::PSUBW, "psubw").gpr128()); // Parallel Subtract Word + drd_srs_srt(def(IK::PMINH, "pminh").gpr128()); // Parallel Minimize Halfword + drd_srs_srt(def(IK::PMINW, "pminw").gpr128()); // Parallel Minimize Word + drd_srs_srt(def(IK::PMAXH, "pmaxh").gpr128()); // Parallel Maximize Halfword + drd_srs_srt(def(IK::PMAXW, "pmaxw").gpr128()); // Parallel Maximize Word + drd_srs_srt(def(IK::PEXTLB, "pextlb").gpr128()); // Parallel Extend Lower from Byte + drd_srs_srt(def(IK::PEXTLH, "pextlh").gpr128()); // Parallel Extend Lower from Halfword + drd_srs_srt(def(IK::PEXTLW, "pextlw").gpr128()); // Parallel Extend Lower from Word + drd_srs_srt(def(IK::PCGTW, "pcgtw").gpr128()); // Parallel Compare for Greater Than Word + drd_srs_srt(def(IK::PCEQB, "pceqb").gpr128()); // Parallel Compare for Equal Byte + drd_srs_srt(def(IK::PCEQW, "pceqw").gpr128()); // Parallel Compare for Equal Word + drd_srs_srt(def(IK::PEXTUB, "pextub").gpr128()); // Parallel Extend Upper from Byte + drd_srs_srt(def(IK::PEXTUH, "pextuh").gpr128()); // Parallel Extend Upper from Halfword + drd_srs_srt(def(IK::PEXTUW, "pextuw").gpr128()); // Parallel Extend Upper from Word + drd_srs_srt(def(IK::PCPYUD, "pcpyud").gpr128()); // Parallel Copy Upper Doubleword + drd_srs_srt(def(IK::PCPYLD, "pcpyld").gpr128()); // Parallel Copy Lower Doubleword + drd_srs_srt(def(IK::PMADDH, "pmaddh").gpr128()); // Parallel Multiply-Add Halfword + drd_srs_srt(def(IK::PMULTH, "pmulth").gpr128()); // Parallel Multiply Halfword + drd_srs_srt(def(IK::PEXEW, "pexew").gpr128()); // Parallel Exchange Even Word + drd_srs_srt(def(IK::PINTEH, "pinteh").gpr128()); // Parallel Interleave Even Halfword + drd_srs_srt(def(IK::PAND, "pand").gpr128()); // Parallel And + drd_srs_srt(def(IK::POR, "por").gpr128()); // Parallel Or + drd_srs_srt(def(IK::PNOR, "pnor").gpr128()); // Parallel Not Or - drd_srt_ssa(def(IK::PSLLW, "psllw")); // Parallel Shift Left Logical Word - drd_srt_ssa(def(IK::PSLLH, "psllh")); // Parallel Shift Left Logical Halfword - drd_srt_ssa(def(IK::PSRAW, "psraw")); // Parallel Shift Right Arithmetic Word - drd_srt_ssa(def(IK::PSRAH, "psrah")); // Parallel Shift Right Arithmetic Halfword - drd_srt_ssa(def(IK::PSRLH, "psrlh")); // Parallel Shift Right Logical Halfword + drd_srt_ssa(def(IK::PSLLW, "psllw").gpr128()); // Parallel Shift Left Logical Word + drd_srt_ssa(def(IK::PSLLH, "psllh").gpr128()); // Parallel Shift Left Logical Halfword + drd_srt_ssa(def(IK::PSRAW, "psraw").gpr128()); // Parallel Shift Right Arithmetic Word + drd_srt_ssa(def(IK::PSRAH, "psrah").gpr128()); // Parallel Shift Right Arithmetic Halfword + drd_srt_ssa(def(IK::PSRLH, "psrlh").gpr128()); // Parallel Shift Right Logical Halfword - def(IK::PLZCW, "plzcw").dst_gpr(FT::RD).src_gpr(FT::RS); // Parallel Leading Zero Count Word - def(IK::PABSW, "pabsw").dst_gpr(FT::RD).src_gpr(FT::RT); // Parallel Absolute Word - def(IK::PROT3W, "prot3w").dst_gpr(FT::RD).src_gpr(FT::RT); // Parallel Rotate 3 Word - def(IK::PCPYH, "pcpyh").dst_gpr(FT::RD).src_gpr(FT::RT); // Parallel Copy Halfword + def(IK::PLZCW, "plzcw") + .dst_gpr(FT::RD) + .src_gpr(FT::RS) + .gpr128(); // Parallel Leading Zero Count Word + def(IK::PABSW, "pabsw").dst_gpr(FT::RD).src_gpr(FT::RT).gpr128(); // Parallel Absolute Word + def(IK::PROT3W, "prot3w").dst_gpr(FT::RD).src_gpr(FT::RT).gpr128(); // Parallel Rotate 3 Word + def(IK::PCPYH, "pcpyh").dst_gpr(FT::RD).src_gpr(FT::RT).gpr128(); // Parallel Copy Halfword // COP1 @@ -436,7 +439,7 @@ void init_opcode_info() { def(IK::VIADDI, "viaddi").dst_vi(FT::FT).src_vi(FT::FS).src(FT::IMM5, DT::IMM); def(IK::QMFC2, "qmfc2").src(FT::IL, DT::IL).dst_gpr(FT::RT).src_vf(FT::FS); - def(IK::QMTC2, "qmtc2").src(FT::IL, DT::IL).src_gpr(FT::RT).dst_vf(FT::FS); + def(IK::QMTC2, "qmtc2").src(FT::IL, DT::IL).dst_vf(FT::FS).src_gpr(FT::RT); def(IK::VSQRT, "vsqrt").dst(FT::ZERO, DT::VU_Q).src_vf(FT::FT).src(FT::FT_F, DT::VF_F); def(IK::VRXOR, "vrxor").src(FT::BC, DT::BC).src_vf(FT::FS); def(IK::VRNEXT, "vrnext").src(FT::DEST, DT::DEST).dst_vf(FT::FT); @@ -518,4 +521,9 @@ OpcodeInfo& OpcodeInfo::dst_vf(FieldType field) { OpcodeInfo& OpcodeInfo::dst_vi(FieldType field) { return dst(field, DT::VI); } + +OpcodeInfo& OpcodeInfo::gpr128() { + gpr_128 = true; + return *this; +} } // namespace decompiler diff --git a/decompiler/Disasm/OpcodeInfo.h b/decompiler/Disasm/OpcodeInfo.h index d941951506..407ef78dec 100644 --- a/decompiler/Disasm/OpcodeInfo.h +++ b/decompiler/Disasm/OpcodeInfo.h @@ -335,6 +335,7 @@ struct OpcodeInfo { bool is_store = false; bool is_load = false; bool has_delay_slot = false; + bool gpr_128 = false; // does it requires 128-bit registers? void step(DecodeStep& s); @@ -350,6 +351,8 @@ struct OpcodeInfo { OpcodeInfo& dst_vf(FieldType field); OpcodeInfo& dst_vi(FieldType field); + OpcodeInfo& gpr128(); + uint8_t step_count = 0; DecodeStep steps[MAX_DECODE_STEPS]; }; diff --git a/decompiler/Function/CfgVtx.cpp b/decompiler/Function/CfgVtx.cpp index 3fa0a43ab1..e4d3ca1cfe 100644 --- a/decompiler/Function/CfgVtx.cpp +++ b/decompiler/Function/CfgVtx.cpp @@ -538,6 +538,10 @@ bool ControlFlowGraph::is_until_loop(CfgVtx* b1, CfgVtx* b2) { if (!b1 || !b2) return false; + if (b2->end_branch.asm_branch) { + return false; + } + // check next and prev if (b1->next != b2) return false; @@ -790,7 +794,7 @@ bool ControlFlowGraph::find_until1_loop() { bool found = false; for_each_top_level_vtx([&](CfgVtx* vtx) { - if (vtx->succ_branch == vtx && vtx->succ_ft) { + if (vtx->succ_branch == vtx && vtx->succ_ft && !vtx->end_branch.asm_branch) { auto loop = alloc(); loop->block = vtx; loop->pred = vtx->pred; diff --git a/decompiler/IR2/Env.cpp b/decompiler/IR2/Env.cpp index ed587959fb..4fbca41a1d 100644 --- a/decompiler/IR2/Env.cpp +++ b/decompiler/IR2/Env.cpp @@ -117,6 +117,10 @@ goos::Object Env::get_variable_name_with_cast(const RegisterAccess& access) cons } } +std::string Env::get_variable_name(const RegisterAccess& access) const { + return get_variable_and_cast(access).name; +} + VariableWithCast Env::get_variable_and_cast(const RegisterAccess& access) const { if (access.reg().get_kind() == Reg::FPR || access.reg().get_kind() == Reg::GPR) { auto& var_info = m_var_names.lookup(access.reg(), access.idx(), access.mode()); @@ -250,19 +254,6 @@ std::optional Env::get_user_cast_for_access(const RegisterAccess& acce return {}; } -std::string Env::get_variable_name(const RegisterAccess& access) const { - if (access.reg().get_kind() == Reg::FPR || access.reg().get_kind() == Reg::GPR) { - std::string lookup_name = m_var_names.lookup(access.reg(), access.idx(), access.mode()).name(); - auto remapped = m_var_remap.find(lookup_name); - if (remapped != m_var_remap.end()) { - lookup_name = remapped->second; - } - return lookup_name; - } else { - throw std::runtime_error("Cannot store a variable in this reg"); - } -} - /*! * Get the type of the variable currently in the register. * NOTE: this is _NOT_ the most specific type known to the decompiler, but instead the type diff --git a/decompiler/IR2/FormExpressionAnalysis.cpp b/decompiler/IR2/FormExpressionAnalysis.cpp index 4b1ab33a36..e0082e5989 100644 --- a/decompiler/IR2/FormExpressionAnalysis.cpp +++ b/decompiler/IR2/FormExpressionAnalysis.cpp @@ -583,7 +583,7 @@ void SimpleExpressionElement::update_from_stack_gpr_to_fpr(const Env& env, // set ourself to identity. m_expr = src.as_expr(); - if (src_type.typespec() == TypeSpec("float")) { + if (env.dts->ts.tc(TypeSpec("float"), src_type.typespec())) { // got a float as an input, we can convert it to an FPR with no effect. for (auto x : src_fes) { result->push_back(x); @@ -884,7 +884,7 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env, result->push_back(pool.alloc_element(args.at(0), rd_ok.addr_of, tokens)); return; } else { - throw std::runtime_error("Failed to match product_with_constant inline array access."); + throw std::runtime_error("Failed to match product_with_constant inline array access 1."); } } } else if (arg0_type.kind == TP_Type::Kind::PRODUCT_WITH_CONSTANT && @@ -914,7 +914,9 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env, {Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::MULTIPLICATION), {Matcher::any(0), Matcher::integer(rd_in.stride)}), Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::MULTIPLICATION), - {Matcher::integer(rd_in.stride), Matcher::any(0)})}); + {Matcher::match_or({Matcher::cast("uint", Matcher::integer(rd_in.stride)), + Matcher::integer(rd_in.stride)}), + Matcher::any(0)})}); auto match_result = match(arg0_matcher, args.at(0)); if (match_result.matched) { bool used_index = false; @@ -932,7 +934,8 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env, result->push_back(pool.alloc_element(args.at(1), rd_ok.addr_of, tokens)); return; } else { - throw std::runtime_error("Failed to match product_with_constant inline array access."); + lg::error("Bad is {}\n", args.at(0)->to_string(env)); + throw std::runtime_error("Failed to match product_with_constant inline array access 2."); } } } diff --git a/decompiler/IR2/OpenGoalMapping.cpp b/decompiler/IR2/OpenGoalMapping.cpp index 512bda474f..98c334afac 100644 --- a/decompiler/IR2/OpenGoalMapping.cpp +++ b/decompiler/IR2/OpenGoalMapping.cpp @@ -12,6 +12,10 @@ const std::map MIPS_ASM_TO_OPEN_GOAL_FUN {InstructionKind::PSRAW, {".pw.sra", {}}}, {InstructionKind::PSUBW, {".psubw", {}}}, + {InstructionKind::POR, {".por", {}}}, + {InstructionKind::PNOR, {".pnor", {}}}, + {InstructionKind::PAND, {".pand", {}}}, + {InstructionKind::PEXTUW, {".pextuw", {}}}, {InstructionKind::PEXTLW, {".pextlw", {}}}, {InstructionKind::PCPYLD, {".pcpyld", {}}}, @@ -174,7 +178,7 @@ std::vector OpenGOALAsm::get_args(const std::vector convert_mfc1_1(const Instruction& i0, int idx) { } std::unique_ptr convert_lw_1(const Instruction& i0, int idx) { - if (i0.get_dst(0).is_reg(rra()) || i0.get_dst(0).is_reg(make_gpr(Reg::AT))) { + if (i0.get_dst(0).is_reg(rra()) || + (i0.get_dst(0).is_reg(make_gpr(Reg::AT)) && !i0.get_src(1).is_reg(rs7()))) { return std::make_unique(i0, idx); } if (i0.get_dst(0).is_reg(rr0()) && i0.get_src(0).is_imm(2) && i0.get_src(1).is_reg(rr0())) { diff --git a/decompiler/analysis/variable_naming.cpp b/decompiler/analysis/variable_naming.cpp index 7115642180..4413445362 100644 --- a/decompiler/analysis/variable_naming.cpp +++ b/decompiler/analysis/variable_naming.cpp @@ -916,6 +916,104 @@ std::unordered_map SSA::get_use_def_info( return result; } +namespace { + +VariableNames::VarInfo* try_lookup_read(VariableNames* in, RegId var_id) { + auto kv = in->read_vars.find(var_id.reg); + if (kv != in->read_vars.end()) { + if ((int)kv->second.size() > var_id.id) { + auto& entry = kv->second.at(var_id.id); + if (entry.initialized) { + return &entry; + } + } + } + return nullptr; +} + +VariableNames::VarInfo* try_lookup_write(VariableNames* in, RegId var_id) { + auto kv = in->write_vars.find(var_id.reg); + if (kv != in->write_vars.end()) { + if ((int)kv->second.size() > var_id.id) { + auto& entry = kv->second.at(var_id.id); + if (entry.initialized) { + return &entry; + } + } + } + return nullptr; +} + +bool is_128bit(const TP_Type& type, const DecompilerTypeSystem& dts) { + if (dts.ts.tc(TypeSpec("uint128"), type.typespec())) { + return true; + } + + if (dts.ts.tc(TypeSpec("int128"), type.typespec())) { + return true; + } + + if (type.kind == TP_Type::Kind::PCPYUD_BITFIELD) { + return true; + } + + if (type.kind == TP_Type::Kind::PCPYUD_BITFIELD_AND) { + return true; + } + + return false; +} + +void promote_register_class(const Function& func, + VariableNames* result, + const DecompilerTypeSystem& dts) { + enum class PromotionType { PROMOTE_64, PROMOTE_128 }; + std::unordered_map promote_map; + // here we loop through ops and find cases where we need to adjust types. + + auto& ao = func.ir2.atomic_ops; + for (size_t op_idx = 0; op_idx < ao->ops.size() - 1; op_idx++) { + auto* op = ao->ops.at(op_idx).get(); + auto op_as_asm = dynamic_cast(op); + if (op_as_asm) { + auto& instr = op_as_asm->instruction(); + if (gOpcodeInfo[(int)instr.kind].gpr_128) { + for (auto& reg : op_as_asm->write_regs()) { + if (reg.get_kind() == Reg::GPR) { + auto& info = result->lookup(reg, op_idx, AccessMode::WRITE); + promote_map[info.reg_id] = PromotionType::PROMOTE_128; + } + } + + for (auto& reg : op_as_asm->read_regs()) { + if (reg.get_kind() == Reg::GPR) { + auto& info = result->lookup(reg, op_idx, AccessMode::READ); + promote_map[info.reg_id] = PromotionType::PROMOTE_128; + } + } + } + } + } + + for (const auto& promotion : promote_map) { + // fmt::print("Promote {} to {}\n", promotion.first.print(), "uint128"); + + // first reads: + auto read_info = try_lookup_read(result, promotion.first); + auto write_info = try_lookup_write(result, promotion.first); + assert(read_info || write_info); + + if (read_info && !is_128bit(read_info->type, dts)) { + read_info->type = TP_Type::make_from_ts("uint128"); + } + + if (write_info && !is_128bit(write_info->type, dts)) { + write_info->type = TP_Type::make_from_ts("uint128"); + } + } +} +} // namespace + std::optional run_variable_renaming(const Function& function, const RegUsageInfo& rui, const FunctionAtomicOps& ops, @@ -1001,6 +1099,8 @@ std::optional run_variable_renaming(const Function& function, // auto result = ssa.get_vars(); result.use_def_info = ssa.get_use_def_info(ssa_mapping); + + promote_register_class(function, &result, dts); return result; } else { return std::nullopt; diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index efecba0c36..b22633808f 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -118,7 +118,7 @@ ;; - Unknowns -;;(define-extern quad-copy! UNKNOWN) +(define-extern quad-copy! (function pointer pointer int none)) ;; ---------------------- @@ -531,6 +531,7 @@ ;; merc1 61 ;; generic1 62 (bucket-65 65) + (sprite 66) ;; debug spheres? 67 (debug-draw0 67) ;; debug text 68 @@ -1837,8 +1838,8 @@ :size-assert #x28 :flag-assert #xb00000028 (:methods - (TODO-RENAME-HUGE-9 (_type_ vector) none 9) - (TODO-RENAME-10 (_type_ vector vector) float 10) + (debug-draw (_type_ vector) none 9) + (ray-capsule-intersect (_type_ vector vector) float 10) ) ) @@ -1852,8 +1853,8 @@ :size-assert #x28 :flag-assert #xb00000028 (:methods - (TODO-RENAME-HUGE-9 (_type_ vector) none 9) - (TODO-RENAME-10 (_type_ vector vector) float 10) + (debug-draw (_type_ vector) none 9) + (ray-flat-cyl-intersect (_type_ vector vector) float 10) ) ) @@ -4897,7 +4898,7 @@ (declare-type entity-links structure) (deftype level-group (basic) ((length int32 :offset-assert 4) - (log-in-level level :offset-assert 8) + (log-in-level-bsp bsp-header :offset-assert 8) (loading-level level :offset-assert 12) (entity-link entity-links :offset-assert 16) ;; not sure what's going on here (border? basic :offset-assert 20) @@ -5846,12 +5847,12 @@ :flag-assert #x1200000020 (:methods (login (_type_) _type_ 9) ;; probably login or init. - (draw (_type_ drawable display-frame) int 10) ;; display-frame is from the method inspect tool - (dummy-11 (_type_ int) none 11) ; int - length - (dummy-12 (_type_ int) none 12) ; int - length - (dummy-13 (_type_ int) none 13) ; int - length - (dummy-14 () none 14) - (dummy-15 (_type_) none 15) + (draw (_type_ drawable display-frame) none 10) ;; display-frame is from the method inspect tool + (dummy-11 (_type_ int object) none 11) ; int - length, collision related + (dummy-12 (_type_ int object) none 12) ; int - length, collision related + (dummy-13 (_type_ int object) none 13) ; int - length, collision related + (dummy-14 (_type_) none 14) + (dummy-15 (_type_ object object) none 15) ;; something debugging (dummy-16 (_type_ object object) object 16) (dummy-17 (_type_ sphere int ambient-list) none 17) ) @@ -11529,12 +11530,13 @@ (to-spr-waits uint32 :offset-assert 44) (from-spr-waits uint32 :offset-assert 48) ) + :pack-me :method-count-assert 14 :size-assert #x34 :flag-assert #xe00000034 (:methods (dummy-9 (_type_) none 9) - (dummy-10 (_type_) none 10) + (print-to-stream (_type_ string basic) none 10) (reset! (_type_) none 11) (read! (_type_) none 12) (update-wait-stats (_type_ uint uint uint) none 13) @@ -11579,9 +11581,9 @@ (pat pointer :offset-assert 44) (pat-length int32 :offset-assert 48) - ;; not sure what this is - (unk-data-0 pointer :offset-assert 52) - (unk-data-0-len int32 :offset-assert 56) + ;; some osrt of texture remapping info + (texture-remap-table (pointer uint64) :offset-assert 52) + (texture-remap-table-len int32 :offset-assert 56) (unk-data-1 pointer :offset-assert 60) (unk-data-1-len int32 :offset-assert 64) @@ -11596,10 +11598,11 @@ (nodes (inline-array bsp-node) :offset-assert 120) (level level :offset-assert 124) - (unk-data-2 uint32 5 :offset-assert 128) + (current-leaf-idx uint16 :offset-assert 128) + (unk-data-2 uint16 9 :offset-assert 130) (boxes box8s-array :offset-assert 148) - (unk-data-3 uint32 :offset-assert 152) + (current-bsp-back-flags uint32 :offset-assert 152) (ambients drawable-inline-array-ambient :offset-assert 156) (unk-data-4 float :offset-assert 160) (unk-data-5 float :offset-assert 164) @@ -12589,7 +12592,7 @@ (far float 4 :offset-assert 60) ) (:methods - (new (symbol type float float) _type_) + (new (symbol type meters meters) _type_) ) :method-count-assert 9 :size-assert #x4c @@ -12959,9 +12962,9 @@ ;; - Types (deftype sprite-vec-data-2d (structure) - ((x-y-z-sx vector :inline :offset-assert 0) - (flag-rot-sy vector :inline :offset-assert 16) - (r-g-b-a vector :inline :offset-assert 32) + ((x-y-z-sx vector :inline :offset-assert 0 :score -10) + (flag-rot-sy vector :inline :offset-assert 16 :score -10) + (r-g-b-a vector :inline :offset-assert 32 :score -10) (x float :offset 0) (y float :offset 4) (z float :offset 8) @@ -12986,13 +12989,16 @@ ) (deftype sprite-array-2d (basic) - ((num-sprites uint32 2 :offset-assert 4) - (num-valid uint32 2 :offset-assert 12) + ((num-sprites int32 2 :offset-assert 4) + (num-valid int32 2 :offset-assert 12) (vec-data uint32 :offset-assert 20) (adgif-data uint32 :offset-assert 24) (pad uint128 4 :offset-assert 32) (data uint128 1 :offset-assert 96) ) + (:methods + (new (symbol type int int) _type_ 0) + ) :method-count-assert 9 :size-assert #x70 :flag-assert #x900000070 @@ -13025,12 +13031,15 @@ ) (deftype sprite-array-3d (basic) - ((num-sprites uint32 2 :offset-assert 4) - (num-valid uint32 2 :offset-assert 12) + ((num-sprites int32 2 :offset-assert 4) + (num-valid int32 2 :offset-assert 12) (vec-data uint32 :offset-assert 20) (adgif-data uint32 :offset-assert 24) (data uint128 1 :offset-assert 32) ) + (:methods + (new (symbol type int int) _type_ 0) + ) :method-count-assert 9 :size-assert #x30 :flag-assert #x900000030 @@ -14697,7 +14706,7 @@ (define-extern ray-circle-intersect (function vector vector vector float float)) (define-extern ray-cylinder-intersect (function vector vector vector vector float float vector float)) (define-extern ray-plane-intersect (function vector vector vector vector vector vector vector float)) -(define-extern ray-triangle-intersect (function vector)) ;; NOTE - didn't bother to check input args +(define-extern ray-triangle-intersect (function vector vector float matrix vector vector float)) (define-extern collide-do-primitives (function float)) ;; NOTE - didn't bother to check input args (define-extern moving-sphere-sphere-intersect (function vector vector vector vector float)) (define-extern moving-sphere-moving-sphere-intersect (function vector vector vector vector float)) @@ -14724,7 +14733,7 @@ (define-extern create-interpolated-joint-animation-frame (function joint-control int process-drawable int)) (define-extern mem-size (function basic symbol int int)) (define-extern jacc-mem-usage (function pointer memory-usage-block int int)) -(define-extern joint-anim-inspect-elt (function joint-anim float int)) +(define-extern joint-anim-inspect-elt (function joint-anim float joint-anim)) (define-extern joint-anim-login (function joint-anim-drawable joint-anim-drawable)) (define-extern joint-control-channel-eval (function joint-control-channel float)) (define-extern joint-control-channel-eval! (function joint-control-channel (function joint-control-channel float float float) float)) @@ -14795,10 +14804,10 @@ ;; - Functions -(define-extern print-cl-stat function) -(define-extern clear-cl-stat function) -(define-extern mem-usage-bsp-tree (function bsp-header (inline-array bsp-node) memory-usage-block int none)) -(define-extern bsp-camera-asm function) +(define-extern print-cl-stat (function cl-stat string none)) +(define-extern clear-cl-stat (function cl-stat none)) +(define-extern mem-usage-bsp-tree (function bsp-header bsp-node memory-usage-block int none)) +(define-extern bsp-camera-asm (function bsp-header vector none)) (define-extern print-collide-stats (function none)) ;; - Unknowns @@ -14814,13 +14823,32 @@ ;; - Functions -(define-extern perf-stat-bucket->string function) -(define-extern print-tr-stat function) -(define-extern clear-tr-stat function) +(defenum perf-stat-bucket + (all-code 0) + (mercneric 1) + (tie-generic 2) + (background 3) + (drawable 4) + (tfrag 5) + (tfrag-near 6) + (inst-shrub 7) + (proto-shrub 8) + (inst-tie 9) + (proto-tie-g 10) + (proto-tie 11) + (proto-tie-n 12) + (bones 13) + (nav 14) + (collide 15) + (camera 16)) + +(define-extern perf-stat-bucket->string (function perf-stat-bucket string)) +(define-extern print-tr-stat (function tr-stat string string none)) +(define-extern clear-tr-stat (function tr-stat none)) (define-extern print-terrain-stats (function none)) -(define-extern update-subdivide-settings! function) -(define-extern set-tfrag-dists! function) -(define-extern start-perf-stat-collection (function engine display-frame int int none)) +(define-extern update-subdivide-settings! (function subdivide-settings math-camera int none)) +(define-extern set-tfrag-dists! (function (pointer float) none)) +(define-extern start-perf-stat-collection (function none)) (define-extern end-perf-stat-collection (function none)) (define-extern print-perf-stats (function none)) @@ -14829,17 +14857,17 @@ (define-extern *subdivide-settings* subdivide-settings) (define-extern *tfrag-work* tfrag-work) ;; unknown type (define-extern *perf-stats* perf-stat-array) ;; unknown type -;;(define-extern *merc-global-stats* object) ;; unknown type -;;(define-extern *stat-string-tfrag-near* object) ;; unknown type -;;(define-extern *stat-string-tfrag* object) ;; unknown type -;;(define-extern *stat-string-total* object) ;; unknown type +(define-extern *merc-global-stats* merc-global-stats) +(define-extern *stat-string-tfrag-near* string) +(define-extern *stat-string-tfrag* string) ;; unknown type +(define-extern *stat-string-total* string) ;; unknown type (define-extern *terrain-context* terrain-context) ;; unknown type -;;(define-extern GSH_ENABLE object) ;; unknown type -;;(define-extern GSH_BUCKET object) ;; unknown type -;;(define-extern GSH_WHICH_STAT object) ;; unknown type -;;(define-extern GSH_MAX_DISPLAY object) ;; unknown type -;;(define-extern GSH_TIME object) ;; unknown type -;;(define-extern *gomi-stats-hack* object) ;; unknown type +(define-extern GSH_ENABLE symbol) ;; unknown type +(define-extern GSH_BUCKET bucket-id) ;; unknown type +(define-extern GSH_WHICH_STAT int) ;; unknown type +(define-extern GSH_MAX_DISPLAY basic) ;; unknown type +(define-extern GSH_TIME int) ;; unknown type +(define-extern *gomi-stats-hack* (inline-array perf-stat)) ;; unknown type ;; ---------------------- @@ -14850,104 +14878,115 @@ ;; - Types -; (deftype sprite-header (structure) -; ((header UNKNOWN 1 :offset-assert 0) -; (num-sprites int32 :offset-assert 0) -; ) -; :method-count-assert 9 -; :size-assert #x10 -; :flag-assert #x900000010 -; ) +(deftype sprite-header (structure) + ( + (header qword 1 :inline :offset-assert 0) + (num-sprites int32 :offset 0) + ) + :method-count-assert 9 + :size-assert #x10 + :flag-assert #x900000010 + ) -; (deftype sprite-hvdf-data (structure) -; ((data UNKNOWN 76 :offset-assert 0) -; ) -; :method-count-assert 9 -; :size-assert #x4c0 -; :flag-assert #x9000004c0 -; ) +(deftype sprite-hvdf-data (structure) + ((data qword 76 :inline :offset-assert 0) + ) + :method-count-assert 9 + :size-assert #x4c0 + :flag-assert #x9000004c0 + ) -; (deftype sprite-hvdf-control (structure) -; ((alloc UNKNOWN 76 :offset-assert 0) -; ) -; :method-count-assert 9 -; :size-assert #x4c -; :flag-assert #x90000004c -; ) +(deftype sprite-hvdf-control (structure) + ((alloc int8 76 :offset-assert 0) + ) + :method-count-assert 9 + :size-assert #x4c + :flag-assert #x90000004c + ) -; (deftype sprite-aux-list (basic) -; ((num-entries int32 :offset-assert 4) -; (entry int32 :offset-assert 8) -; (data UNKNOWN 1 :offset-assert 12) -; ) -; :method-count-assert 9 -; :size-assert #x10 -; :flag-assert #x900000010 -; ) +(deftype sprite-aux-list (basic) + ((num-entries int32 :offset-assert 4) + (entry int32 :offset-assert 8) + (data sprite-vec-data-2d 1 :offset-assert 12) ;; likely 4-bytes each + ) + (:methods + (new (symbol type int) _type_ 0) + ) + :method-count-assert 9 + :size-assert #x10 + :flag-assert #x900000010 + ) -; (deftype sprite-frame-data (structure) -; ((data UNKNOWN 41 :offset-assert 0) -; (cdata UNKNOWN 16 :offset-assert 0) -; (fdata UNKNOWN 25 :offset-assert 256) -; (xy-array UNKNOWN 8 :offset-assert 0) -; (st-array UNKNOWN 4 :offset-assert 128) -; (xyz-array UNKNOWN 4 :offset-assert 192) -; (hmge-scale vector :inline :offset-assert 256) -; (consts vector :inline :offset-assert 272) -; (pfog0 float :offset-assert 272) -; (deg-to-rad float :offset-assert 276) -; (min-scale float :offset-assert 280) -; (inv-area float :offset-assert 284) -; (adgif-giftag qword :inline :offset-assert 288) -; (sprite-2d-giftag qword :inline :offset-assert 304) -; (sprite-2d-giftag-2 qword :inline :offset-assert 320) -; (sincos-01 vector :inline :offset-assert 336) -; (sincos-23 vector :inline :offset-assert 352) -; (sincos-45 vector :inline :offset-assert 368) -; (sincos-67 vector :inline :offset-assert 384) -; (sincos-89 vector :inline :offset-assert 400) -; (basis-x vector :inline :offset-assert 416) -; (basis-y vector :inline :offset-assert 432) -; (sprite-3d-giftag qword :inline :offset-assert 448) -; (screen-shader adgif-shader :inline :offset-assert 464) -; (clipped-giftag qword :inline :offset-assert 544) -; (inv-hmge-scale vector :inline :offset-assert 560) -; (stq-offset vector :inline :offset-assert 576) -; (stq-scale vector :inline :offset-assert 592) -; (rgba-plain qword :inline :offset-assert 608) -; (warp-giftag qword :inline :offset-assert 624) -; (fog-clamp vector :inline :offset-assert 640) -; (fog-min float :offset-assert 640) -; (fog-max float :offset-assert 644) -; (max-scale float :offset-assert 648) -; ) -; :method-count-assert 9 -; :size-assert #x290 -; :flag-assert #x900000290 -; ) +(deftype sprite-frame-data (structure) + ( + ;(data UNKNOWN 41 :offset-assert 0) + (cdata vector 16 :inline :offset-assert 0) + ;(fdata UNKNOWN 25 :offset-assert 256) + ;(xy-array UNKNOWN 8 :offset-assert 0) + ;(st-array UNKNOWN 4 :offset-assert 128) + ;(xyz-array UNKNOWN 4 :offset-assert 192) + (hmge-scale vector :inline :offset 256) + (consts vector :inline :offset-assert 272 :score -100.) + (pfog0 float :offset 272) + (deg-to-rad float :offset 276) + (min-scale float :offset 280) + (inv-area float :offset 284) + ;(adgif-giftag qword :inline :offset-assert 288) + (adgif-giftag gs-gif-tag :inline :offset-assert 288) + (sprite-2d-giftag gs-gif-tag :inline :offset-assert 304) + (sprite-2d-giftag-2 gs-gif-tag :inline :offset-assert 320) + ;;(sprite-2d-giftag qword :inline :offset-assert 304) + ;;(sprite-2d-giftag-2 qword :inline :offset-assert 320) + (sincos-01 vector :inline :offset-assert 336) + (sincos-23 vector :inline :offset-assert 352) + (sincos-45 vector :inline :offset-assert 368) + (sincos-67 vector :inline :offset-assert 384) + (sincos-89 vector :inline :offset-assert 400) + (basis-x vector :inline :offset-assert 416) + (basis-y vector :inline :offset-assert 432) + ;;(sprite-3d-giftag qword :inline :offset-assert 448) + (sprite-3d-giftag gs-gif-tag :inline :offset-assert 448) + (screen-shader adgif-shader :inline :offset-assert 464) + ;;(clipped-giftag qword :inline :offset-assert 544) + (clipped-giftag gs-gif-tag :inline :offset-assert 544) + (inv-hmge-scale vector :inline :offset-assert 560) + (stq-offset vector :inline :offset-assert 576) + (stq-scale vector :inline :offset-assert 592) + (rgba-plain qword :inline :offset-assert 608) + ;;(warp-giftag qword :inline :offset-assert 624) + (warp-giftag gs-gif-tag :inline :offset-assert 624) + (fog-clamp vector :inline :offset-assert 640) + (fog-min float :offset 640) + (fog-max float :offset 644) + (max-scale float :offset 648) + ) + :method-count-assert 9 + :size-assert #x290 + :flag-assert #x900000290 + ) ;; - Functions -(define-extern sprite-init-distorter function) -(define-extern sprite-draw-distorters function) -(define-extern sprite-add-frame-data function) -(define-extern sprite-add-matrix-data function) -(define-extern sprite-add-3d-all function) -(define-extern sprite-add-2d-all function) -(define-extern sprite-add-shadow-all function) -(define-extern sprite-add-shadow-chunk function) -(define-extern sprite-setup-header function) -(define-extern sprite-add-3d-chunk function) -(define-extern sprite-add-2d-chunk function) -(define-extern sprite-setup-frame-data function) -(define-extern clear-sprite-aux-list function) -(define-extern add-to-sprite-aux-list function) -(define-extern sprite-set-3d-quaternion! function) -(define-extern sprite-get-3d-quaternion! function) +(define-extern sprite-init-distorter (function dma-buffer uint none)) +(define-extern sprite-draw-distorters (function dma-buffer none)) +(define-extern sprite-add-frame-data (function dma-buffer uint none)) +(define-extern sprite-add-matrix-data (function dma-buffer uint none)) +(define-extern sprite-add-3d-all (function sprite-array-3d dma-buffer int none)) +(define-extern sprite-add-2d-all (function sprite-array-2d dma-buffer int none)) +(define-extern sprite-add-shadow-all (function fake-shadow-buffer dma-buffer none)) +(define-extern sprite-add-shadow-chunk (function fake-shadow-buffer int int dma-buffer none)) +(define-extern sprite-setup-header (function sprite-header int none)) +(define-extern sprite-add-3d-chunk (function sprite-array-3d int int dma-buffer none)) +(define-extern sprite-add-2d-chunk (function sprite-array-2d int int dma-buffer int none)) +(define-extern sprite-setup-frame-data (function sprite-frame-data int none)) +(define-extern clear-sprite-aux-list (function none)) +(define-extern add-to-sprite-aux-list function) ;; it's a callback. +(define-extern sprite-set-3d-quaternion! (function sprite-vec-data-3d quaternion quaternion)) +(define-extern sprite-get-3d-quaternion! (function quaternion sprite-vec-data-3d quaternion)) (define-extern sprite-draw (function display none)) -(define-extern sprite-allocate-user-hvdf function) -(define-extern sprite-release-user-hvdf function) -(define-extern sprite-get-user-hvdf function) +(define-extern sprite-allocate-user-hvdf (function int)) +(define-extern sprite-release-user-hvdf (function int none)) +(define-extern sprite-get-user-hvdf (function int qword)) ;; - Symbols @@ -14955,12 +14994,12 @@ ;; - Unknowns -;;(define-extern *sprite-hvdf-data* object) ;; unknown type -;;(define-extern *sprite-hvdf-control* object) ;; unknown type -;;(define-extern sprite-vu1-block object) ;; unknown type -;;(define-extern *sprite-array-3d* object) ;; unknown type -;;(define-extern *sprite-array-2d* object) ;; unknown type -;;(define-extern *sprite-aux-list* object) ;; unknown type +(define-extern *sprite-hvdf-data* sprite-hvdf-data) ;; unknown type +(define-extern *sprite-hvdf-control* sprite-hvdf-control) ;; unknown type +(define-extern sprite-vu1-block vu-function) ;; unknown type +(define-extern *sprite-array-3d* sprite-array-3d) ;; unknown type +(define-extern *sprite-array-2d* sprite-array-2d) ;; unknown type +(define-extern *sprite-aux-list* sprite-aux-list) ;; ---------------------- @@ -14971,23 +15010,23 @@ ;; - Types -; (deftype sprite-distorter-sine-tables (basic) -; ((aspx float :offset-assert 4) -; (aspy float :offset-assert 8) -; (entry UNKNOWN 128 :offset-assert 16) -; (ientry UNKNOWN 9 :offset-assert 2064) -; (giftag qword :inline :offset-assert 2208) -; (color qword :inline :offset-assert 2224) -; ) -; :method-count-assert 9 -; :size-assert #x8c0 -; :flag-assert #x9000008c0 -; ) +(deftype sprite-distorter-sine-tables (basic) + ((aspx float :offset-assert 4) + (aspy float :offset-assert 8) + (entry vector 128 :inline :offset-assert 16) + (ientry qword 9 :inline :offset-assert 2064) + (giftag gs-gif-tag :inline :offset-assert 2208) ;; was qword + (color qword :inline :offset-assert 2224) + ) + :method-count-assert 9 + :size-assert #x8c0 + :flag-assert #x9000008c0 + ) ;; - Unknowns -;;(define-extern *sprite-distorter-sine-tables* object) ;; unknown type -;;(define-extern sprite-distort-vu1-block object) ;; unknown type +(define-extern *sprite-distorter-sine-tables* sprite-distorter-sine-tables) +(define-extern sprite-distort-vu1-block vu-function) ;; ---------------------- @@ -18015,7 +18054,7 @@ (define-extern move-camera-from-pad function) (define-extern update-view-planes function) -(define-extern update-visible function) +(define-extern update-visible (function math-camera none)) (define-extern set-point function) (define-extern plane-from-points function) (define-extern update-camera (function none)) @@ -18026,7 +18065,7 @@ ;;(define-extern *timer-value* object) ;; unknown type ;;(define-extern *start-pos* object) ;; unknown type ;;(define-extern *save-camera-inv-rot* object) ;; unknown type -;;(define-extern *update-leaf-when-outside-bsp* object) ;; unknown type +(define-extern *update-leaf-when-outside-bsp* symbol) ;; ---------------------- diff --git a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc index bc9d61d96f..681eb61ba5 100644 --- a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc @@ -107,8 +107,6 @@ // collide-func "moving-sphere-triangle-intersect", // P: weird branching "collide-do-primitives", // P: asm branching - "ray-triangle-intersect", // F: asm branching - "ray-cylinder-intersect", // F: asm branching // joint "calc-animation-from-spr", // F: asm branching @@ -119,11 +117,6 @@ "clear-frame-accumulator", // F: asm branching "cspace<-parented-transformq-joint!", - // bsp - "level-remap-texture", // BUG: probably missing branch case? - "bsp-camera-asm", // F: asm branching - "sprite-draw-distorters", - // merc-blend-shape "setup-blerc-chains-for-one-fragment", // F: asm branching "blerc-execute", // F: asm branching @@ -494,7 +487,9 @@ " textures ~192H~5DK ~280Htextures~456H~5DK~%": 2, " entity ~192H~5DK~%": 2, " misc ~192H~5DK ~280Hsprite~456H~5DK~%": 2, - "ERROR: ~A in spool anim loop for ~A ~D, but not loaded.~": 3 + "ERROR: ~A in spool anim loop for ~A ~D, but not loaded.~": 3, + "~0k~5d/~d ~6d/~d ~6d/~d ": 6, + "~0k~s~%": 1 }, "blocks_ending_in_asm_branch": { @@ -536,6 +531,14 @@ "(method 11 perf-stat)": [0], "(method 20 actor-link-info)": [2], "(method 21 actor-link-info)": [2], - "raw-ray-sphere-intersect": [0, 1, 2, 3, 4, 5] + "raw-ray-sphere-intersect": [0, 1, 2, 3, 4, 5], + "ray-cylinder-intersect": [0, 1, 2, 3, 4, 5], + "ray-triangle-intersect": [0, 1, 2, 3, 4], + "bsp-camera-asm": [1, 2, 3], + "level-remap-texture": [2, 3, 4, 5, 6], + "start-perf-stat-collection": [26], + "end-perf-stat-collection": [0], + + "sprite-draw-distorters": [4, 5] } } diff --git a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc index df4c4d32ce..06d376fc62 100644 --- a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc @@ -497,12 +497,18 @@ "cam-update-h": [["L2", "bfloat", true]], - "collide-func": [["L41", "float", true], ["L40", "float", true]], + "collide-func": [ + ["L41", "float", true], + ["L40", "float", true] + ], "cylinder": [ ["L27", "float", true], ["L54", "vector", true], - ["L60", "float", true] + ["L60", "float", true], + ["L57", "vector", true], + ["L56", "vector", true], + ["L53", "vector", true] ], "debug-sphere": [["L10", "debug-sphere-table", true]], @@ -1201,7 +1207,7 @@ ["L78", "rgba", true], ["L79", "rgba", true] ], - + "loader": [ ["L279", "float", true], ["L283", "float", true], @@ -1211,7 +1217,7 @@ ["L281", "float", true], ["L278", "float", true] ], - + "yakow": [ ["L150", "float", true], ["L162", "float", true], @@ -1226,9 +1232,48 @@ ["L152", "float", true], ["L149", "float", true] ], - - "farmer": [ - ["L50", "float", true] + + "farmer": [["L50", "float", true]], + + "bsp": [ + ["L54", "rgba", true], + ["L85", "rgba", true], + ["L86", "rgba", true], + ["L55", "rgba", true], + ["L53", "uint64", true], + ["L56", "uint64", true] + ], + + "subdivide": [ + ["L129", "float", true], + ["L128", "float", true], + ["L114", "rgba", true], + ["L113", "uint64", true] + ], + + "sprite": [ + ["L93", "uint64", true], + ["L92", "uint64", true], + ["L83", "uint64", true], + ["L90", "uint64", true], + ["L91", "uint64", true], + ["L84", "uint64", true], + ["L89", "uint64", true], + ["L88", "uint64", true], + ["L86", "uint64", true], + ["L82", "uint64", true], + ["L94", "uint64", true], + ["L87", "uint64", true], + ["L85", "uint64", true] + ], + + "sprite-distort": [ + ["L42", "uint64", true], + ["L39", "uint64", true], + ["L41", "uint64", true], + ["L40", "uint64", true], + ["L37", "uint64", true], + ["L38", "uint64", true] ], // please do not add things after this entry! git is dumb. diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index d3ec4fe5a2..58d2de4172 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -1079,7 +1079,7 @@ [196, "s4", "pointer"], [[203, 210], "s4", "game-save-tag"] ], - + "drawable-load": [ [17, "s5", "drawable"], [18, "s5", "drawable"], @@ -1101,7 +1101,7 @@ ], "(method 13 art-group)": [[16, "s3", "art-joint-anim"]], "(method 14 art-group)": [[16, "s3", "art-joint-anim"]], - + "(method 9 external-art-control)": [ [171, "s4", "external-art-buffer"], [172, "s4", "external-art-buffer"], @@ -1109,7 +1109,7 @@ [177, "s4", "external-art-buffer"], [183, "s4", "external-art-buffer"], [190, "s4", "external-art-buffer"], - + [233, "s4", "spool-anim"], [240, "s4", "spool-anim"], [243, "s4", "spool-anim"], @@ -1118,16 +1118,14 @@ [253, "s4", "spool-anim"], [257, "s4", "spool-anim"] ], - - "(method 10 external-art-control)": [ - [18, "v1", "spool-anim"] - ], - + + "(method 10 external-art-control)": [[18, "v1", "spool-anim"]], + "(method 16 external-art-control)": [ [37, "a0", "process"], [17, "s5", "process-drawable"] ], - + "ja-play-spooled-anim": [ [154, "a0", "process"], [286, "s2", "art-joint-anim"], @@ -1137,7 +1135,7 @@ [320, "s2", "art-joint-anim"], [324, "s2", "art-joint-anim"] ], - + "(method 11 external-art-control)": [ [127, "a0", "process"], [151, "a0", "process"], @@ -1241,24 +1239,24 @@ "blackout": [[[20, 24], "v1", "dma-packet"]], "(method 10 external-art-control)": [[18, "v1", "pointer"]], - + "(method 15 load-state)": [ [31, "t9", "(function int)"], [291, "s5", "entity-actor"], [370, "s3", "process-drawable"] ], - + "yakow-default-event-handler": [ [27, "a0", "collide-shape"], [32, "a0", "collide-shape"] ], - + "(method 11 yakow)": [ [184, "v1", "vector"], [186, "v1", "vector"], [189, "v1", "vector"] ], - + "yakow-post": [ [114, "a0", "collide-shape-moving"], [130, "a0", "collide-shape-moving"] @@ -1269,5 +1267,98 @@ [36, "v1", "uint"] ], + "(method 10 bsp-header)": [ + [[51, 61], "a0", "(pointer uint128)"], + [[51, 61], "a1", "(pointer uint128)"], + [133, "v1", "terrain-bsp"], + [141, "v1", "terrain-bsp"], + [148, "v1", "terrain-bsp"], + [5, "a0", "terrain-bsp"], + [8, "a0", "terrain-bsp"] + ], + + "(method 15 bsp-header)": [ + [5, "a0", "terrain-bsp"], + [8, "a0", "terrain-bsp"] + ], + + "bsp-camera-asm": [ + [[4, 14], "a1", "bsp-node"], + [[0, 9], "v1", "bsp-node"], + [[12, 16], "v1", "bsp-node"] + ], + + "level-remap-texture": [ + [15, "t0", "(pointer int32)"], + [21, "t0", "(pointer int32)"], + [19, "t0", "(pointer uint64)"], + [12, "v1", "int"] + ], + + "sprite-add-matrix-data": [ + [[5, 15], "a2", "dma-packet"], + [[24, 29], "a1", "matrix"], + [[47, 57], "a2", "dma-packet"], + [[60, 97], "a1", "matrix"], + [[116, 129], "a1", "vector"] + ], + + "sprite-add-frame-data": [[[8, 16], "a0", "dma-packet"]], + + "sprite-add-2d-chunk": [ + [[12, 20], "a0", "dma-packet"], + [[45, 52], "a0", "dma-packet"], + [[69, 76], "a0", "dma-packet"], + [[80, 87], "v1", "dma-packet"] + ], + + "sprite-add-3d-chunk": [ + [[11, 19], "a0", "dma-packet"], + [[44, 51], "a0", "dma-packet"], + [[68, 75], "a0", "dma-packet"], + [[79, 87], "v1", "dma-packet"] + ], + + "sprite-add-shadow-chunk": [ + [[11, 19], "a0", "dma-packet"], + [[37, 44], "a0", "dma-packet"], + [[49, 77], "a0", "(inline-array vector)"], + [[93, 100], "a0", "dma-packet"], + [[105, 121], "s1", "adgif-shader"], + [[130, 138], "v1", "dma-packet"] + ], + + "sprite-draw": [ + [[33, 37], "a0", "dma-packet"], + [[43, 46], "a0", "gs-gif-tag"], + [51, "a0", "(pointer gs-test)"], + [53, "a0", "(pointer gs-reg64)"], + [55, "a0", "(pointer gs-clamp)"], + [57, "a0", "(pointer gs-reg64)"], + [[78, 87], "a0", "dma-packet"], + [[92, 97], "a0", "dma-packet"], + [[125, 129], "a0", "dma-packet"], + [[143, 146], "v1", "dma-packet"] + ], + + "sprite-init-distorter": [ + [59, "a3", "uint"], + [[3, 7], "a2", "dma-packet"], + [[13, 16], "a2", "gs-gif-tag"], + [21, "a2", "(pointer gs-zbuf)"], + [23, "a2", "(pointer gs-reg64)"], + [29, "a2", "(pointer gs-tex0)"], + [31, "a2", "(pointer gs-reg64)"], + [33, "a2", "(pointer gs-tex1)"], + [35, "a2", "(pointer gs-reg64)"], + [36, "a2", "(pointer gs-miptbp)"], + [38, "a2", "(pointer gs-reg64)"], + [45, "a2", "(pointer gs-clamp)"], + [47, "a2", "(pointer gs-reg64)"], + [49, "a2", "(pointer gs-alpha)"], + [51, "a2", "(pointer gs-reg64)"], + [[62, 67], "a1", "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 36f90c57eb..9e3f4204e1 100644 --- a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc @@ -2485,6 +2485,68 @@ "args": ["ray-origin", "ray-dir", "sph-origin", "radius"] }, + "ray-circle-intersect": { + "args": ["ray-origin", "ray-dir", "circle-origin", "radius"] + }, + + "ray-cylinder-intersect": { + "args": [ + "ray-origin", + "ray-dir", + "cyl-origin", + "cyl-axis", + "cyl-rad", + "cyl-len" + ] + }, + + "(method 10 cylinder)": { + "args": ["obj", "probe-origin", "probe-dir"], + "vars": { + "f30-0": "result", + "f0-5": "u-origin-sph", + "s4-0": "end-pt", + "f0-8": "u-end-sphere" + } + }, + + "(method 10 cylinder-flat)": { + "args": ["obj", "probe-origin", "probe-dir"], + "vars": { + "f30-0": "result", + "f0-5": "u-origin-circle", + "s5-0": "end-pt", + "f0-8": "u-end-circle" + } + }, + + "ray-arbitrary-circle-intersect": { + "args": [ + "probe-origin", + "probe-dir", + "circle-origin", + "circle-normal", + "radius" + ] + }, + + "print-tr-stat": { + "args": ["stat", "name", "dest"] + }, + + "update-subdivide-settings!": { + "args": ["settings", "math-cam", "idx"] + }, + + "start-perf-stat-collection": { + "vars": { + "v1-2": "frame-idx", + "v1-5": "bucket", + "a0-2": "which-stat", + "a0-7": "stat-idx" + } + }, + "ja-play-spooled-anim": { "vars": { "sv-16": "spool-part", @@ -2493,5 +2555,195 @@ } }, + "sprite-setup-header": { + "args": ["hdr", "num-sprites"] + }, + + "(method 0 sprite-aux-list)": { + "args": ["allocation", "type-to-make", "size"] + }, + + "sprite-setup-frame-data": { + "args": ["data", "tbp-offset"] + }, + + "(method 0 sprite-array-2d)": { + "args": ["allocation", "type-to-make", "group-0-size", "group-1-size"], + "vars": { + "v1-0": "sprite-count", + "s4-0": "vec-data-size", + "a2-3": "adgif-data-size" + } + }, + + "(method 0 sprite-array-3d)": { + "args": ["allocation", "type-to-make", "group-0-size", "group-1-size"], + "vars": { + "v1-0": "sprite-count", + "s4-0": "vec-data-size", + "a2-3": "adgif-data-size" + } + }, + + "sprite-set-3d-quaternion": { + "args": ["data", "quat"] + }, + "sprite-get-3d-quaternion": { + "args": ["data", "quat"] + }, + "sprite-add-matrix-data": { + "args": ["dma-buff", "matrix-mode"], + "vars": { + "v1-0": "count", + "a2-1": ["pkt1", "dma-packet"], + "a1-2": ["mtx", "matrix"], + "a2-9": ["pkt2", "dma-packet"], + "a1-11": "mtx2", + "a1-20": "hvdf-idx" + } + }, + + "sprite-add-frame-data": { + "args": ["dma-buff", "tbp-offset"], + "vars": { + "a0-1": ["pkt", "dma-packet"] + } + }, + + "sprite-add-2d-chunk": { + "args": [ + "sprites", + "start-sprite-idx", + "num-sprites", + "dma-buff", + "mscal-addr" + ], + "vars": { + "a0-1": ["pkt1", "dma-packet"], + "s1-0": "qwc-pkt1", + "a1-7": "qwc-pkt2", + "a0-5": ["pkt2", "dma-packet"], + "a1-11": "qwc-pkt3", + "a0-7": ["pkt3", "dma-packet"], + "v1-7": ["pkt4", "dma-packet"] + } + }, + + "sprite-add-2d-all": { + "args": ["sprites", "dma-buff", "group-idx"], + "vars": { + "s4-0": "current-sprite-idx", + "s2-0": "remaining-sprites", + "s3-0": "mscal-addr" + } + }, + + "sprite-add-3d-chunk": { + "args": ["sprites", "start-sprite-idx", "num-sprites", "dma-buff"], + "vars": { + "a0-1": ["pkt1", "dma-packet"], + "s2-0": "qwc-pkt1", + "a1-7": "qwc-pkt2", + "a0-5": ["pkt2", "dma-packet"], + "a1-11": "qwc-pkt3", + "a0-7": ["pkt3", "dma-packet"], + "v1-7": ["pkt4", "dma-packet"] + } + }, + + "sprite-add-3d-all": { + "args": ["sprites", "dma-buff", "group-idx"], + "vars": { + "s4-0": "current-sprite-idx", + "s3-0": "remaining-sprites" + } + }, + + "sprite-add-shadow-chunk": { + "args": ["shadow-buff", "start-idx", "num-sprites", "dma-buff"], + "vars": { + "s2-0": "pkt1-qwc", + "a0-1": ["pkt1", "dma-packet"], + "a1-7": "pkt2-qwc", + "a0-5": ["pkt2", "dma-packet"], + "v1-5": "sprite-idx", + "a0-7": "dma-vec-data", + "a1-14": "in-vec-data", + "a1-5": "pkt3-qwc", + "a0-11": ["pkt3", "dma-packet"], + "s2-1": "si", + "s1-0": "dma-adgif-data", + "s0-0": "in-adgif-data", + "v1-21": ["pkt4", "dma-packet"] + } + }, + + "sprite-add-shadow-all": { + "args": ["shadow-buff", "dma-buff"], + "vars": { + "s4-0": "current-shadow", + "s3-0": "remaining-shadows" + } + }, + + "sprite-draw": { + "args": "disp", + "vars": { + "gp-0": "dma-mem-begin", + "s4-0": "dma-buff", + "s5-0": "dma-bucket-begin", + "a0-9": ["pkt1", "dma-packet"], + "a0-11": ["giftag", "gs-gif-tag"], + "a0-17": ["pkt2", "dma-packet"], + "a0-19": ["pkt3", "dma-packet"], + "a0-26": ["pkt4", "dma-packet"], + "v1-26": ["pkt5", "dma-packet"], + "v1-31": "mem-use" + } + }, + + "mem-usage-bsp-tree": { + "args": ["header", "node", "mem-use", "flags"] + }, + + "(method 8 bsp-header)": { + "args": ["obj", "mem-use", "flags"] + }, + + "(method 10 bsp-header)": { + "args": ["obj", "other-draw", "disp-frame"], + "vars": { + "s4-0": "lev", + "a2-3": "vis-list-qwc", + "v1-15": "vis-list-qwc2", + "a0-9": ["vis-list-spad", "(pointer uint128)"], + "a1-5": ["vis-list-lev", "(pointer uint128)"], + "a2-4": "current-qw" + } + }, + + "bsp-camera-asm": { + "args": ["bsp-hdr", "camera-pos"], + "vars": { + "v1-0": ["next-node", "bsp-node"], + "a1-1": "real-node" + } + }, + + "level-remap-texture": { + "args": ["tex-id"], + "vars": { + "v1-1":"bsp-hdr", + "a3-0": "table-size", + "v1-2": ["table-data-start", "(pointer uint64)"], + "t0-0":"table-data-ptr", + "a1-1":"mask1", + "a2-1":"masked-tex-id", + "a3-2":"table-data-end", + "t0-3":"midpoint", + "t1-1":"diff" + } + }, + "aaaaaaaaaaaaaaaaaaaaaaa": {} } diff --git a/decompiler/util/DecompilerTypeSystem.cpp b/decompiler/util/DecompilerTypeSystem.cpp index 916c8c3187..b22ff380fb 100644 --- a/decompiler/util/DecompilerTypeSystem.cpp +++ b/decompiler/util/DecompilerTypeSystem.cpp @@ -414,6 +414,11 @@ int DecompilerTypeSystem::get_format_arg_count(const std::string& str) const { continue; } + // ~0k + if (i + 1 < str.length() && (str.at(i) == '0') && str.at(i + 1) == 'k') { + continue; + } + // ~2j if (i + 1 < str.length() && (str.at(i) == '2') && str.at(i + 1) == 'j') { continue; diff --git a/goal_src/engine/camera/cam-debug-h.gc b/goal_src/engine/camera/cam-debug-h.gc index 6dd977ef3b..24a33bc67c 100644 --- a/goal_src/engine/camera/cam-debug-h.gc +++ b/goal_src/engine/camera/cam-debug-h.gc @@ -100,3 +100,5 @@ (defun-extern debug-set-camera-pos-rot! vector matrix int) ) + +(define-extern camera-line (function vector vector vector none)) diff --git a/goal_src/engine/collide/collide-frag.gc b/goal_src/engine/collide/collide-frag.gc index c1d95b5eec..8cb7d9057a 100644 --- a/goal_src/engine/collide/collide-frag.gc +++ b/goal_src/engine/collide/collide-frag.gc @@ -17,7 +17,7 @@ (draw (-> obj data s4-0) (-> obj data s4-0) arg1) ) ) - 0 + (none) ) ;; definition for method 16 of type drawable-tree-collide-fragment @@ -33,8 +33,8 @@ (defmethod dummy-11 drawable-tree-collide-fragment - ((obj drawable-tree-collide-fragment) (arg0 int)) - (dummy-11 (-> obj data 0) (-> obj length)) + ((obj drawable-tree-collide-fragment) (arg0 int) (arg1 object)) + (dummy-11 (-> obj data 0) (-> obj length) arg1) (let ((v0-1 0)) ) (none) @@ -45,8 +45,8 @@ (defmethod dummy-12 drawable-tree-collide-fragment - ((obj drawable-tree-collide-fragment) (arg0 int)) - (dummy-12 (-> obj data 0) (-> obj length)) + ((obj drawable-tree-collide-fragment) (arg0 int) (arg1 object)) + (dummy-12 (-> obj data 0) (-> obj length) arg1) (let ((v0-1 0)) ) (none) @@ -57,8 +57,8 @@ (defmethod dummy-13 drawable-tree-collide-fragment - ((obj drawable-tree-collide-fragment) (arg0 int)) - (dummy-13 (-> obj data 0) (-> obj length)) + ((obj drawable-tree-collide-fragment) (arg0 int) (arg1 object)) + (dummy-13 (-> obj data 0) (-> obj length) arg1) (let ((v0-1 0)) ) (none) @@ -126,7 +126,7 @@ ;; definition for method 10 of type collide-fragment (defmethod draw collide-fragment ((obj collide-fragment) (arg0 drawable) (arg1 display-frame)) - 0 + (none) ) ;; definition for method 10 of type drawable-inline-array-collide-fragment @@ -138,7 +138,7 @@ ) ) ) - 0 + (none) ) ;; definition for method 11 of type drawable-inline-array-collide-fragment @@ -146,8 +146,8 @@ (defmethod dummy-11 drawable-inline-array-collide-fragment - ((obj drawable-inline-array-collide-fragment) (arg0 int)) - (dummy-11 (the-as collide-fragment (-> obj data)) (-> obj length)) + ((obj drawable-inline-array-collide-fragment) (arg0 int) (arg1 object)) + (dummy-11 (the-as collide-fragment (-> obj data)) (-> obj length) arg1) (none) ) @@ -156,8 +156,8 @@ (defmethod dummy-12 drawable-inline-array-collide-fragment - ((obj drawable-inline-array-collide-fragment) (arg0 int)) - (dummy-12 (the-as collide-fragment (-> obj data)) (-> obj length)) + ((obj drawable-inline-array-collide-fragment) (arg0 int) (arg1 object)) + (dummy-12 (the-as collide-fragment (-> obj data)) (-> obj length) arg1) (none) ) @@ -166,8 +166,8 @@ (defmethod dummy-13 drawable-inline-array-collide-fragment - ((obj drawable-inline-array-collide-fragment) (arg0 int)) - (dummy-13 (the-as collide-fragment (-> obj data)) (-> obj length)) + ((obj drawable-inline-array-collide-fragment) (arg0 int) (arg1 object)) + (dummy-13 (the-as collide-fragment (-> obj data)) (-> obj length) arg1) (none) ) diff --git a/goal_src/engine/collide/collide-func.gc b/goal_src/engine/collide/collide-func.gc index 804518d396..f1a9f6ccc7 100644 --- a/goal_src/engine/collide/collide-func.gc +++ b/goal_src/engine/collide/collide-func.gc @@ -214,3 +214,168 @@ (pc-port-do-raw-ray-sphere-intersect radius vf1 vf2) ) ) + +(defun ray-circle-intersect ((ray-origin vector) (ray-dir vector) (circle-origin vector) (radius float)) + "Intersect ray with circle. Circle is on the y plane and this throws out the y components + of ray-origin, circle-origin, and ray-dir" + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (init-vf0-vector) + (.lvf vf1 (&-> ray-origin quad)) + (.mov.vf vf1 vf0 :mask #b10) + (.lvf vf2 (&-> circle-origin quad)) + (.mov.vf vf2 vf0 :mask #b10) + (.sub.vf vf1 vf1 vf2) + (.lvf vf2 (&-> ray-dir quad)) + (.mov.vf vf2 vf0 :mask #b10) + ;;(raw-ray-sphere-intersect radius) + (pc-port-do-raw-ray-sphere-intersect radius vf1 vf2) + ) + ) + +(defun ray-cylinder-intersect ((ray-origin vector) (ray-dir vector) (cyl-origin vector) (cyl-axis vector) (cyl-rad float) (cyl-len float) (pt-out vector)) + "Intersect with a cylinder. + Currently this is untested." + (local-vars + (v0-1 float) + (v1-0 int) + (v1-2 int) + (a0-1 int) + (a0-2 int) + (a0-4 int) + (a0-5 int) + ) + (rlet ((vf1 :class vf) + (vf10 :class vf) + (vf11 :class vf) + (vf12 :class vf) + (vf13 :class vf) + (vf14 :class vf) + (vf15 :class vf) + (vf16 :class vf) + (vf17 :class vf) + (vf18 :class vf) + (vf19 :class vf) + (vf2 :class vf) + (vf20 :class vf) + (vf21 :class vf) + ) + (.lvf vf10 (&-> ray-origin quad)) + (.lvf vf12 (&-> cyl-origin quad)) + (.sub.vf vf15 vf10 vf12) + (.lvf vf11 (&-> ray-dir quad)) + (.lvf vf13 (&-> cyl-axis quad)) + (.mov vf14 cyl-len) + (.mul.vf vf16 vf15 vf13) + (.mul.vf vf17 vf11 vf13) + (.add.x.vf vf16 vf16 vf16 :mask #b10) + (.add.x.vf vf17 vf17 vf17 :mask #b10) + (.add.z.vf vf16 vf16 vf16 :mask #b10) + (.add.z.vf vf17 vf17 vf17 :mask #b10) + (.mul.y.vf vf1 vf13 vf16) + (.add.vf vf18 vf17 vf16) + (.sub.x.vf vf19 vf16 vf14) + (.mul.y.vf vf2 vf13 vf17) + (.mov v1-0 vf16) + (.sub.x.vf vf20 vf18 vf14) + (.mov a0-1 vf18) + (let ((v1-1 (logand v1-0 (the-as uint a0-1)))) + (.sub.vf vf1 vf15 vf1) + (b! (< v1-1 0) cfg-6 :delay (.sub.vf vf2 vf11 vf2)) + ) + (.mov v1-2 vf19) + (.mov a0-2 vf20) + (b! (>= (the-as int (logior v1-2 (the-as uint a0-2))) 0) cfg-6 :delay (nop!)) + ;;(let ((v1-4 (raw-ray-sphere-intersect cyl-rad))) + (let ((v1-4 (pc-port-do-raw-ray-sphere-intersect cyl-rad vf1 vf2))) + (b! (< (the-as int v1-4) 0) cfg-6 :delay (.mov vf21 v1-4)) + (.mul.x.vf vf17 vf17 vf21) + (.add.vf vf16 vf16 vf17) + (.mul.y.vf vf13 vf13 vf16) + (.sub.x.vf vf19 vf16 vf14) + (.mov a0-4 vf16) + (b! + (< (the-as int a0-4) 0) + cfg-6 + :delay + (.add.vf vf12 vf12 vf13 :mask #b111) + ) + (.mov a0-5 vf19) + (b! (>= (the-as int a0-5) 0) cfg-6 :delay (.svf (&-> pt-out quad) vf12)) + (b! #t cfg-7 :delay (set! v0-1 v1-4)) + ) + (label cfg-6) + (set! v0-1 -100000000.0) + (label cfg-7) + v0-1 + ) + ) + +(defun ray-plane-intersect ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 vector) (arg4 vector) (arg5 vector) (arg6 vector)) + "Unused." + (local-vars (v1-0 float) (v1-1 float) (a2-1 float)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + (vf8 :class vf) + (vf9 :class vf) + ) + (init-vf0-vector) + (.lvf vf3 (&-> arg5 quad)) + (.lvf vf1 (&-> arg4 quad)) + (.lvf vf2 (&-> arg6 quad)) + (.sub.vf vf1 vf3 vf1) + (.sub.vf vf2 vf3 vf2) + (.lvf vf6 (&-> arg2 quad)) + (.lvf vf7 (&-> arg3 quad)) + (.sub.vf vf8 vf3 vf6) + (.outer.product.vf vf4 vf2 vf1) + (.mul.vf vf8 vf8 vf4) + (.mul.vf vf9 vf7 vf4) + (.mul.vf vf5 vf4 vf4) + (.add.y.vf vf8 vf8 vf8 :mask #b1) + (.add.y.vf vf9 vf9 vf9 :mask #b1) + (.add.y.vf vf5 vf5 vf5 :mask #b1) + (.add.z.vf vf8 vf8 vf8 :mask #b1) + (.add.z.vf vf9 vf9 vf9 :mask #b1) + (.add.z.vf vf5 vf5 vf5 :mask #b1) + (.mov v1-0 vf9) + (.mov a2-1 vf8) + (.isqrt.vf Q vf0 vf5 :fsf #b11 :ftf #b0) + (let ((f1-0 a2-1) + (f2-0 v1-0) + ) + (cond + ((!= f2-0 0.0) + (let ((f1-1 (/ f1-0 f2-0))) + (.mov.vf vf4 vf0 :mask #b1000) + (.wait.vf) + (.mul.vf vf4 vf4 Q :mask #b111) + (let ((v0-0 f1-1)) + (.mov vf8 v0-0) + (.svf (&-> arg1 quad) vf4) + (.mul.x.vf acc vf7 vf8) + (.add.mul.w.vf vf7 vf6 vf0 acc :mask #b111) + (.svf (&-> arg0 quad) vf7) + (.mov v1-1 vf7) + v0-0 + ) + ) + ) + (else + -100000000.0 + ) + ) + ) + ) + ) + diff --git a/goal_src/engine/debug/memory-usage-h.gc b/goal_src/engine/debug/memory-usage-h.gc index 3653c53165..2f3ccdeaa7 100644 --- a/goal_src/engine/debug/memory-usage-h.gc +++ b/goal_src/engine/debug/memory-usage-h.gc @@ -112,7 +112,9 @@ (entity-links 64) ;; or ambient links, its messed up (joint 65) (joint-anim-compressed 66) - ;; + (joint-anim-compressed-control 67) + (joint-anim-fixed 68) + (joint-anim-frame 69) (art-group 70) (art-mesh-anim 71) (art-mesh-geo 72) @@ -125,6 +127,7 @@ (texture 79) (string 80) (array 81) + (sprite 82) ;; (debug-dma 84) ;; maybe (sky-dma 85) ;; maybe diff --git a/goal_src/engine/debug/stats-h.gc b/goal_src/engine/debug/stats-h.gc index 067f0e30fa..f63445cf3b 100644 --- a/goal_src/engine/debug/stats-h.gc +++ b/goal_src/engine/debug/stats-h.gc @@ -45,12 +45,13 @@ (to-spr-waits uint32 :offset-assert 44) (from-spr-waits uint32 :offset-assert 48) ) + :pack-me :method-count-assert 14 :size-assert #x34 :flag-assert #xe00000034 (:methods (dummy-9 (_type_) none 9) - (dummy-10 (_type_) none 10) + (print-to-stream (_type_ string basic) none 10) (reset! (_type_) none 11) (read! (_type_) none 12) (update-wait-stats (_type_ uint uint uint) none 13) diff --git a/goal_src/engine/dma/dma-h.gc b/goal_src/engine/dma/dma-h.gc index af8140d175..4415a410cd 100644 --- a/goal_src/engine/dma/dma-h.gc +++ b/goal_src/engine/dma/dma-h.gc @@ -246,6 +246,7 @@ ;; merc1 61 ;; generic1 62 (bucket-65 65) + (sprite 66) ;; debug spheres? 67 (debug-draw0 67) ;; debug text 68 diff --git a/goal_src/engine/draw/drawable-actor-h.gc b/goal_src/engine/draw/drawable-actor-h.gc index 182aa3fb8d..baa768a334 100644 --- a/goal_src/engine/draw/drawable-actor-h.gc +++ b/goal_src/engine/draw/drawable-actor-h.gc @@ -29,4 +29,5 @@ (defmethod draw drawable-tree-actor ((obj _type_) (arg0 drawable) (arg1 display-frame)) 0 + (none) ) diff --git a/goal_src/engine/draw/drawable-ambient-h.gc b/goal_src/engine/draw/drawable-ambient-h.gc index bccfc24f5f..9ce0142417 100644 --- a/goal_src/engine/draw/drawable-ambient-h.gc +++ b/goal_src/engine/draw/drawable-ambient-h.gc @@ -33,6 +33,7 @@ (defmethod draw drawable-tree-ambient ((obj _type_) (arg0 drawable) (arg1 display-frame)) 0 + (none) ) (defmethod dummy-16 drawable-tree-ambient ((obj drawable-tree-ambient) (arg0 object) (arg1 object)) diff --git a/goal_src/engine/draw/drawable-h.gc b/goal_src/engine/draw/drawable-h.gc index e65ee8af7f..fa79b8c50e 100644 --- a/goal_src/engine/draw/drawable-h.gc +++ b/goal_src/engine/draw/drawable-h.gc @@ -18,12 +18,12 @@ :flag-assert #x1200000020 (:methods (login (_type_) _type_ 9) ;; probably login or init. - (draw (_type_ drawable display-frame) int 10) ;; display-frame is from the method inspect tool - (dummy-11 (_type_ int) none 11) ; int - length - (dummy-12 (_type_ int) none 12) ; int - length - (dummy-13 (_type_ int) none 13) ; int - length - (dummy-14 () none 14) ;; related to culling? - (dummy-15 (_type_) none 15) + (draw (_type_ drawable display-frame) none 10) ;; display-frame is from the method inspect tool + (dummy-11 (_type_ int object) none 11) ; int - length + (dummy-12 (_type_ int object) none 12) ; int - length + (dummy-13 (_type_ int object) none 13) ; int - length + (dummy-14 (_type_) none 14) ;; related to culling? + (dummy-15 (_type_ object object) none 15) (dummy-16 (_type_ object object) object 16) (dummy-17 (_type_ sphere int ambient-list) none 17) ) @@ -38,4 +38,5 @@ ) (declare-type process-drawable process) -(define-extern process-drawable-art-error (state string process-drawable)) \ No newline at end of file +(define-extern process-drawable-art-error (state string process-drawable)) +(define-extern foreground-engine-execute (function engine display-frame int int none)) diff --git a/goal_src/engine/draw/drawable-inline-array.gc b/goal_src/engine/draw/drawable-inline-array.gc index 6ebb628f99..0cebcbb136 100644 --- a/goal_src/engine/draw/drawable-inline-array.gc +++ b/goal_src/engine/draw/drawable-inline-array.gc @@ -16,15 +16,15 @@ ) (defmethod draw drawable-inline-array ((obj drawable-inline-array) (arg0 drawable) (arg1 display-frame)) - 0 + (none) ) -(defmethod dummy-14 drawable-inline-array () +(defmethod dummy-14 drawable-inline-array ((obj drawable-inline-array)) 0 (none) ) -(defmethod dummy-15 drawable-inline-array ((obj drawable-inline-array)) +(defmethod dummy-15 drawable-inline-array ((obj drawable-inline-array) (arg0 object) (arg1 object)) 0 (none) ) diff --git a/goal_src/engine/geometry/cylinder.gc b/goal_src/engine/geometry/cylinder.gc index 5600178a80..0396e7cbad 100644 --- a/goal_src/engine/geometry/cylinder.gc +++ b/goal_src/engine/geometry/cylinder.gc @@ -5,5 +5,338 @@ ;; name in dgo: cylinder ;; dgos: GAME, ENGINE -;; TODO - done but depends on collide-func functions (asm related). -;; TODO - also will need manual cleanup around `vector-dot` being inlined +;; Note: "cylinder" refers to a capsule, "cylinder-flat" refers to a real cylinder with end caps. + +(defmethod ray-capsule-intersect cylinder ((obj cylinder) (probe-origin vector) (probe-dir vector)) + "Intersect a ray with a capsule." + (let ((t2-0 (new 'stack-no-clear 'vector)) + (end-pt (new 'stack-no-clear 'vector)) + ) + ;; first intersect with the cylinder part. + (let ((result (ray-cylinder-intersect + probe-origin + probe-dir + (-> obj origin) + (-> obj axis) + (-> obj radius) + (-> obj length) + t2-0 + ) + ) + ) + ;; next, intersect with the sphere at the origin. + (let ((u-origin-sph (ray-sphere-intersect + probe-origin + probe-dir + (-> obj origin) + (-> obj radius) + ) + ) + ) + ;; if that was closer, we went through both the sphere and the wall, and we want the sphere. + (if (and (>= u-origin-sph 0.0) (or (< result 0.0) (< u-origin-sph result))) + (set! result u-origin-sph) + ) + ) + ;; compute the location of the other end's sphere's origin + (vector+float*! end-pt (-> obj origin) (-> obj axis) (-> obj length)) + ;; intersect that + (let ((u-end-sphere (ray-sphere-intersect probe-origin probe-dir end-pt (-> obj radius)))) + ;; and pick it if it's closer. + (if (and (>= u-end-sphere 0.0) (or (< result 0.0) (< u-end-sphere result))) + (set! result u-end-sphere) + ) + ) + result + ) + ) + ) + +;; This is used to hold vertices for debug-drawing cylinders. +(deftype cylinder-verts (structure) + ((vert vector 24 :inline :offset-assert 0) + ) + :method-count-assert 9 + :size-assert #x180 + :flag-assert #x900000180 + ) + + +(defmethod debug-draw cylinder ((obj cylinder) (arg0 vector)) + "Debug draw a cylinder. This is slow and ugly" + (local-vars + (sv-896 matrix) + (sv-912 int) + (sv-928 (function vector vector vector float vector)) + (sv-944 vector) + (sv-960 vector) + (sv-976 vector) + (sv-992 (function vector vector vector float vector)) + (sv-1008 vector) + (sv-1024 vector) + (sv-1040 vector) + (sv-1056 (function vector vector vector float vector)) + (sv-1072 vector) + (sv-1088 vector) + (sv-1104 vector) + (sv-1120 (function vector vector vector float vector)) + (sv-1136 vector) + (sv-1152 vector) + (sv-1168 vector) + ) + (rlet ((vf0 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + ) + (init-vf0-vector) + (let ((s1-0 (new 'stack-no-clear 'vector)) + (s0-0 (new 'stack-no-clear 'vector)) + ) + (if (< 0.999 (fabs (-> obj axis y))) + (vector-cross! s1-0 (-> obj axis) (new 'static 'vector :z 1.0)) + (vector-cross! s1-0 (-> obj axis) (new 'static 'vector :y 1.0)) + ) + (vector-normalize! s1-0 (-> obj radius)) + (vector-float*! s0-0 (-> obj axis) (* 0.125 (-> obj length))) + (let ((s5-0 (new 'stack-no-clear 'cylinder-verts)) + (s4-0 (new 'stack-no-clear 'cylinder-verts)) + (s3-0 (new 'stack-no-clear 'matrix)) + ) + (matrix-axis-angle! s3-0 (-> obj axis) 4096.0) + (set! sv-896 (new 'stack-no-clear 'matrix)) + (vector-matrix*! (the-as vector sv-896) (-> obj origin) s3-0) + (let ((v1-5 (-> s3-0 vector 3))) + (.lvf vf4 (&-> (-> obj origin) quad)) + (.lvf vf5 (&-> sv-896 vector 0 quad)) + (.mov.vf vf6 vf0 :mask #b1000) + (.sub.vf vf6 vf4 vf5 :mask #b111) + (.svf (&-> v1-5 quad) vf6) + ) + (set! sv-912 0) + (while (< sv-912 8) + (vector+! (-> s5-0 vert (+ sv-912 8)) (-> obj origin) s1-0) + (vector+float*! + (-> s5-0 vert (+ sv-912 8)) + (-> s5-0 vert (+ sv-912 8)) + s0-0 + (the float sv-912) + ) + (set! sv-912 (+ sv-912 1)) + ) + (dotimes (s0-1 8) + (set! sv-928 vector+float*!) + (set! sv-944 (-> s5-0 vert s0-1)) + (set! sv-960 (-> obj origin)) + (set! sv-976 s1-0) + (let ((a3-1 (cos (* 2048.0 (the float (- 7 s0-1)))))) + (sv-928 sv-944 sv-960 sv-976 a3-1) + ) + (set! sv-992 vector+float*!) + (set! sv-1008 (-> s5-0 vert s0-1)) + (set! sv-1024 (-> s5-0 vert s0-1)) + (set! sv-1040 (-> obj axis)) + (let + ((a3-2 (* (- (-> obj radius)) (sin (* 2048.0 (the float (- 7 s0-1))))))) + (sv-992 sv-1008 sv-1024 sv-1040 a3-2) + ) + (set! sv-1056 vector+float*!) + (set! sv-1072 (-> s5-0 vert (+ s0-1 16))) + (set! sv-1088 (-> obj origin)) + (set! sv-1104 s1-0) + (let ((a3-3 (cos (* 2048.0 (the float s0-1))))) + (sv-1056 sv-1072 sv-1088 sv-1104 a3-3) + ) + (set! sv-1120 vector+float*!) + (set! sv-1136 (-> s5-0 vert (+ s0-1 16))) + (set! sv-1152 (-> s5-0 vert (+ s0-1 16))) + (set! sv-1168 (-> obj axis)) + (let ((a3-4 (+ (-> obj length) + (* (-> obj radius) (sin (* 2048.0 (the float s0-1)))) + ) + ) + ) + (sv-1120 sv-1136 sv-1152 sv-1168 a3-4) + ) + ) + (dotimes (s2-1 16) + (dotimes (s1-1 24) + (vector-matrix*! (-> s4-0 vert s1-1) (-> s5-0 vert s1-1) s3-0) + (camera-line (-> s5-0 vert s1-1) (-> s4-0 vert s1-1) arg0) + (if (nonzero? s1-1) + (camera-line (-> s5-0 vert s1-1) (-> s5-0 vert (+ s1-1 -1)) arg0) + ) + ) + (let ((v1-77 s5-0)) + (set! s5-0 s4-0) + (set! s4-0 v1-77) + ) + ) + ) + ) + 0 + (none) + ) + ) + +(defun ray-arbitrary-circle-intersect ((probe-origin vector) (probe-dir vector) (circle-origin vector) (circle-normal vector) (radius float)) + "Intersect a ray with a non-axis-aligned circle." + (let* ((v1-1 (vector-! (new 'stack-no-clear 'vector) circle-origin probe-origin)) ;; circle -> probe offset + (f0-2 (/ (vector-dot v1-1 circle-normal) (vector-dot probe-dir circle-normal))) + ) + (cond + ((or (< 1.0 f0-2) (< f0-2 0.0)) + -100000000.0 + ) + ((let ((a0-7 (new 'stack-no-clear 'vector))) + (vector-float*! a0-7 probe-dir f0-2) + (vector-! a0-7 a0-7 v1-1) + (< (vector-dot a0-7 a0-7) (* radius radius)) + ) + f0-2 + ) + (else + -100000000.0 + ) + ) + ) + ) + +(defmethod ray-flat-cyl-intersect cylinder-flat ((obj cylinder-flat) (probe-origin vector) (probe-dir vector)) + "Intersect with a real cylinder." + (let ((gp-0 (new 'stack-no-clear 'vector)) + (end-pt (new 'stack-no-clear 'vector)) + ) + 0.0 + 0.0 + ;; walls + (let ((result (ray-cylinder-intersect + probe-origin + probe-dir + (-> obj origin) + (-> obj axis) + (-> obj radius) + (-> obj length) + gp-0 + ) + ) + ) + ;; one end cap + (let ((u-origin-circle (ray-arbitrary-circle-intersect + probe-origin + probe-dir + (-> obj origin) + (-> obj axis) + (-> obj radius) + ) + ) + ) + (when (and (>= u-origin-circle 0.0) (or (< result 0.0) (< u-origin-circle result))) + (set! result u-origin-circle) + (set! (-> gp-0 quad) (-> obj origin quad)) + ) + ) + ;; get other end cap + (vector+float*! end-pt (-> obj origin) (-> obj axis) (-> obj length)) + (let ((u-end-circle (ray-arbitrary-circle-intersect + probe-origin + probe-dir + end-pt + (-> obj axis) + (-> obj radius) + ) + ) + ) + (when (and (>= u-end-circle 0.0) (or (< result 0.0) (< u-end-circle result))) + (set! result u-end-circle) + (set! (-> gp-0 quad) (-> end-pt quad)) + ) + ) + result + ) + ) + ) + +;; debug draw for cylinder flat. +(deftype cylinder-flat-verts (structure) + ((vert vector 10 :inline :offset-assert 0) + ) + :method-count-assert 9 + :size-assert #xa0 + :flag-assert #x9000000a0 + ) + + +(defmethod debug-draw cylinder-flat ((obj cylinder-flat) (arg0 vector)) + (local-vars (sv-448 vector) (sv-464 int)) + (rlet ((vf0 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + ) + (init-vf0-vector) + (let ((s1-0 (new 'stack-no-clear 'vector)) + (s0-0 (new 'stack-no-clear 'vector)) + ) + (if (< 0.999 (fabs (-> obj axis y))) + (vector-cross! s1-0 (-> obj axis) (new 'static 'vector :z 1.0)) + (vector-cross! s1-0 (-> obj axis) (new 'static 'vector :y 1.0)) + ) + (vector-normalize! s1-0 (-> obj radius)) + (vector-float*! s0-0 (-> obj axis) (* 0.14285715 (-> obj length))) + (let ((s5-0 (new 'stack-no-clear 'cylinder-flat-verts)) + (s4-0 (new 'stack-no-clear 'cylinder-flat-verts)) + (s3-0 (new 'stack-no-clear 'matrix)) + ) + (matrix-axis-angle! s3-0 (-> obj axis) 4096.0) + (set! sv-448 (new 'stack-no-clear 'vector)) + (vector-matrix*! sv-448 (-> obj origin) s3-0) + (let ((v1-5 (-> s3-0 vector 3))) + (.lvf vf4 (&-> (-> obj origin) quad)) + (.lvf vf5 (&-> sv-448 quad)) + (.mov.vf vf6 vf0 :mask #b1000) + (.sub.vf vf6 vf4 vf5 :mask #b111) + (.svf (&-> v1-5 quad) vf6) + ) + (set! sv-464 0) + (while (< sv-464 8) + (vector+! (-> s5-0 vert (+ sv-464 1)) (-> obj origin) s1-0) + (vector+float*! + (-> s5-0 vert (+ sv-464 1)) + (-> s5-0 vert (+ sv-464 1)) + s0-0 + (the float sv-464) + ) + (set! sv-464 (+ sv-464 1)) + ) + (set! (-> s5-0 vert 0 quad) (-> obj origin quad)) + (vector+float*! + (-> s5-0 vert 9) + (-> obj origin) + (-> obj axis) + (-> obj length) + ) + (dotimes (s2-1 16) + (dotimes (s1-1 10) + (vector-matrix*! (-> s4-0 vert s1-1) (-> s5-0 vert s1-1) s3-0) + (camera-line (-> s5-0 vert s1-1) (-> s4-0 vert s1-1) arg0) + (if (nonzero? s1-1) + (camera-line (-> s5-0 vert s1-1) (-> s5-0 vert (+ s1-1 -1)) arg0) + ) + ) + (let ((v1-43 s5-0)) + (set! s5-0 s4-0) + (set! s4-0 v1-43) + ) + ) + ) + ) + 0 + (none) + ) + ) + + + + + diff --git a/goal_src/engine/gfx/sprite/sprite-h.gc b/goal_src/engine/gfx/sprite/sprite-h.gc index dc05a3ca29..848b6946df 100644 --- a/goal_src/engine/gfx/sprite/sprite-h.gc +++ b/goal_src/engine/gfx/sprite/sprite-h.gc @@ -34,13 +34,16 @@ ) (deftype sprite-array-2d (basic) - ((num-sprites uint32 2 :offset-assert 4) - (num-valid uint32 2 :offset-assert 12) + ((num-sprites int32 2 :offset-assert 4) + (num-valid int32 2 :offset-assert 12) (vec-data uint32 :offset-assert 20) (adgif-data uint32 :offset-assert 24) (pad uint128 4 :offset-assert 32) (data uint128 1 :offset-assert 96) ) + (:methods + (new (symbol type int int) _type_ 0) + ) :method-count-assert 9 :size-assert #x70 :flag-assert #x900000070 @@ -73,13 +76,19 @@ ) (deftype sprite-array-3d (basic) - ((num-sprites uint32 2 :offset-assert 4) - (num-valid uint32 2 :offset-assert 12) + ((num-sprites int32 2 :offset-assert 4) + (num-valid int32 2 :offset-assert 12) (vec-data uint32 :offset-assert 20) (adgif-data uint32 :offset-assert 24) (data uint128 1 :offset-assert 32) ) + (:methods + (new (symbol type int int) _type_ 0) + ) :method-count-assert 9 :size-assert #x30 :flag-assert #x900000030 ) +(define-extern sprite-init-distorter (function dma-buffer uint none)) +(define-extern sprite-draw-distorters (function dma-buffer none)) +(define-extern sprite-vu1-block vu-function) diff --git a/goal_src/engine/gfx/sprite/sprite.gc b/goal_src/engine/gfx/sprite/sprite.gc index d4f3236f5d..149dc8ed31 100644 --- a/goal_src/engine/gfx/sprite/sprite.gc +++ b/goal_src/engine/gfx/sprite/sprite.gc @@ -5,3 +5,1027 @@ ;; name in dgo: sprite ;; dgos: GAME, ENGINE +;; the sprite renderer draw 2D or 3D sprites, plus the old circular "fake shadow". + +;; Most of the work is done on VU1 and this code just sets up +;; DMA lists for chunks of sprites + +;; at most, 48 sprites may be rendered per chunk. +(defconstant SPRITE_CHUNK_COUNT 48) + +;; This is the first quadword of the data sent to VU1. +;; It contains the number of sprites that should be drawn. +(deftype sprite-header (structure) + ((header qword 1 :inline :offset-assert 0) + (num-sprites int32 :offset 0) + ) + :method-count-assert 9 + :size-assert #x10 + :flag-assert #x900000010 + ) + +(defun sprite-setup-header ((hdr sprite-header) (num-sprites int)) + "Setup a sprite-header for the given number of sprites" + (set! (-> hdr num-sprites) num-sprites) + (none) + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; HVDF Data +;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; the meaning of this is unknown. +;; the first one in the list is special and the remaining 75 can be allocated/freed. +(deftype sprite-hvdf-data (structure) + ((data qword 76 :inline :offset-assert 0) + ) + :method-count-assert 9 + :size-assert #x4c0 + :flag-assert #x9000004c0 + ) + +;; Each byte indicates if the corresponding entry in +;; sprite-hvdf-data is allocated or not. +(deftype sprite-hvdf-control (structure) + ((alloc int8 76 :offset-assert 0) + ) + :method-count-assert 9 + :size-assert #x4c + :flag-assert #x90000004c + ) + +(define *sprite-hvdf-data* (new 'global 'sprite-hvdf-data)) +(define *sprite-hvdf-control* (new 'global 'sprite-hvdf-control)) + +;; make all unallocated... +(dotimes (v1-6 76) + (set! (-> *sprite-hvdf-control* alloc v1-6) 0) + ) + +;; except for the first. +(set! (-> *sprite-hvdf-control* alloc 0) 1) + +;;;;;;;;;;;;;;;;;;;;;;;;;; +;; aux list +;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; this list is not currently understood, but the sparticle system +;; pushes stuff onto it. + +(deftype sprite-aux-list (basic) + ((num-entries int32 :offset-assert 4) ;; capacity + (entry int32 :offset-assert 8) ;; current entry + (data sprite-vec-data-2d 1 :offset-assert 12) ;; "dynamic" array. + ) + :method-count-assert 9 + :size-assert #x10 + :flag-assert #x900000010 + (:methods + (new (symbol type int) _type_ 0) + ) + ) + +(defmethod new sprite-aux-list ((allocation symbol) (type-to-make type) (size int)) + "Allocate a sprite-aux-list with room for size 4-byte entries" + (let ((v0-0 (object-new allocation type-to-make + (the-as int (+ (-> type-to-make size) (the-as uint (* (+ size -1) 4)))) + ) + ) + ) + (set! (-> v0-0 num-entries) size) + (set! (-> v0-0 entry) 0) + v0-0 + ) + ) + +#| +;; until we figure out the entry type, we can't have this function. +(defmethod inspect sprite-aux-list ((obj sprite-aux-list)) + (format #t "[~X] sprite-aux-list:~%" obj) + (format #t "~Tnum-entries: ~D~%" (-> obj num-entries)) + (format #t "~Tentry: ~D~%" (-> obj entry)) + (dotimes (s5-0 (-> obj entry)) + (format #t "~T~D : ~X~%" s5-0 (l.wu (+ (+ (* s5-0 4) (the-as int obj)) 8))) + ) + (the-as sprite-aux-list #f) + ) +|# + +(define *sprite-aux-list* (new 'global 'sprite-aux-list 256)) + +(defun clear-sprite-aux-list () + "Remove everything from the sprite aux list" + (set! (-> *sprite-aux-list* entry) 0) + (none) + ) + +;; TODO function add-to-sprite-aux-list + +;; The sprite-frame-data is data transferred to VU1 and remains there for all chunks of sprites. +(deftype sprite-frame-data (structure) + ((cdata vector 16 :inline :offset-assert 0) + (hmge-scale vector :inline :offset 256) ;; math camera value + (consts vector :inline :offset-assert 272) + (pfog0 float :offset 272) ;; math camera value + (deg-to-rad float :offset 276) ;; 2*pi / 65,536 + (min-scale float :offset 280) + (inv-area float :offset 284) + (adgif-giftag gs-gif-tag :inline :offset-assert 288) ;; sets adgif shader values + (sprite-2d-giftag gs-gif-tag :inline :offset-assert 304) ;; draws 2d sprites + (sprite-2d-giftag-2 gs-gif-tag :inline :offset-assert 320) ;; 2d with different settings + (sincos-01 vector :inline :offset-assert 336) + (sincos-23 vector :inline :offset-assert 352) + (sincos-45 vector :inline :offset-assert 368) + (sincos-67 vector :inline :offset-assert 384) + (sincos-89 vector :inline :offset-assert 400) + (basis-x vector :inline :offset-assert 416) + (basis-y vector :inline :offset-assert 432) + (sprite-3d-giftag gs-gif-tag :inline :offset-assert 448) ;; draws 3d sprites + (screen-shader adgif-shader :inline :offset-assert 464) + (clipped-giftag gs-gif-tag :inline :offset-assert 544) + (inv-hmge-scale vector :inline :offset-assert 560) ;; math camera value + (stq-offset vector :inline :offset-assert 576) + (stq-scale vector :inline :offset-assert 592) + (rgba-plain qword :inline :offset-assert 608) + (warp-giftag gs-gif-tag :inline :offset-assert 624) + (fog-clamp vector :inline :offset-assert 640) + (fog-min float :offset 640) + (fog-max float :offset 644) + (max-scale float :offset 648) + ) + :method-count-assert 9 + :size-assert #x290 + :flag-assert #x900000290 + ) + +(defun sprite-setup-frame-data ((data sprite-frame-data) (tbp-offset int)) + "Build the sprite-frame-data. This should be done once per frame" + (set! (-> data hmge-scale quad) (-> *math-camera* hmge-scale quad)) + (set! (-> data inv-hmge-scale quad) (-> *math-camera* inv-hmge-scale quad)) + (set! (-> data pfog0) (-> *math-camera* pfog0)) + (set! (-> data deg-to-rad) 0.000095873795) + + ;; the adgif-giftag sets GS registers according to the adgif shader using + ;; the A+D mode + ;; each adgif has 5x registers, so we set up a tag to do 5x a+d's + (set! (-> data adgif-giftag tag) (new 'static 'gif-tag64 :nloop #x1 :nreg #x5)) + (set! (-> data adgif-giftag 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) + ) + ) + + ;; I believe this is used for the group 0's in 2d + ;; TODO prim. + (set! (-> data sprite-2d-giftag tag) + (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :pre #x1 :prim #x75 :nreg #x9) + ) + (set! (-> data sprite-2d-giftag regs) + (new 'static 'gif-tag-regs + :regs0 (gif-reg-id rgbaq) + :regs1 (gif-reg-id st) + :regs2 (gif-reg-id xyzf2) + :regs3 (gif-reg-id st) + :regs4 (gif-reg-id xyzf2) + :regs5 (gif-reg-id st) + :regs6 (gif-reg-id xyzf2) + :regs7 (gif-reg-id st) + :regs8 (gif-reg-id xyzf2) + ) + ) + + + ;; group 1's in 2d + (set! (-> data sprite-2d-giftag-2 tag) + (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :pre #x1 :prim #x55 :nreg #x9) + ) + (set! (-> data sprite-2d-giftag-2 regs) + (new 'static 'gif-tag-regs + :regs0 (gif-reg-id rgbaq) + :regs1 (gif-reg-id st) + :regs2 (gif-reg-id xyzf2) + :regs3 (gif-reg-id st) + :regs4 (gif-reg-id xyzf2) + :regs5 (gif-reg-id st) + :regs6 (gif-reg-id xyzf2) + :regs7 (gif-reg-id st) + :regs8 (gif-reg-id xyzf2) + ) + ) + + ;; 3d's don't have different groups? + (set! (-> data sprite-3d-giftag tag) + (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :pre #x1 :prim #x75 :nreg #xc) + ) + ;; note that we have rgbaq's per vertex in 3d + (set! (-> data sprite-3d-giftag regs) + (new 'static 'gif-tag-regs + :regs0 (gif-reg-id st) + :regs1 (gif-reg-id rgbaq) + :regs2 (gif-reg-id xyzf2) + :regs3 (gif-reg-id st) + :regs4 (gif-reg-id rgbaq) + :regs5 (gif-reg-id xyzf2) + :regs6 (gif-reg-id st) + :regs7 (gif-reg-id rgbaq) + :regs8 (gif-reg-id xyzf2) + :regs9 (gif-reg-id st) + :regs10 (gif-reg-id rgbaq) + :regs11 (gif-reg-id xyzf2) + ) + ) + + ;; ?? + (set! (-> data clipped-giftag tag) + (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :pre #x1 :prim #x75 :nreg #x3) + ) + (set! + (-> data clipped-giftag regs) + (new 'static 'gif-tag-regs + :regs0 (gif-reg-id st) + :regs1 (gif-reg-id rgbaq) + :regs2 (gif-reg-id xyzf2) + ) + ) + + ;; not sure what this is either + (set! (-> data warp-giftag tag) + (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :pre #x1 :prim #x53 :nreg #xc) + ) + (set! (-> data warp-giftag regs) + (new 'static 'gif-tag-regs + :regs0 (gif-reg-id st) + :regs1 (gif-reg-id rgbaq) + :regs2 (gif-reg-id xyzf2) + :regs3 (gif-reg-id st) + :regs4 (gif-reg-id rgbaq) + :regs5 (gif-reg-id xyzf2) + :regs6 (gif-reg-id st) + :regs7 (gif-reg-id rgbaq) + :regs8 (gif-reg-id xyzf2) + ) + ) + + ;; set up an adgif. + (set! (-> data screen-shader prims 1) (gs-reg64 tex0-1)) + (set! (-> data screen-shader tex0) (new 'static 'gs-tex0 :tbw #x8 :tw #xa :th #x8 :tbp0 (* tbp-offset 32))) + (set! (-> data screen-shader prims 3) (gs-reg64 tex1-1)) + (set! (-> data screen-shader tex1) (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (set! (-> data screen-shader prims 5) (gs-reg64 miptbp1-1)) + (set! (-> data screen-shader miptbp1) (new 'static 'gs-miptbp)) + (set! (-> data screen-shader clamp-reg) (gs-reg64 clamp-1)) + (set! (-> data screen-shader clamp) (new 'static 'gs-clamp :wms #x2 :wmt #x2 :maxu #x27f :maxv #xef)) + (set! (-> data screen-shader prims 9) (gs-reg64 alpha-1)) + (set! (-> data screen-shader alpha) (new 'static 'gs-miptbp :tbp1 #x44)) + + ;; sin/cosine table + (set! (-> data sincos-01 z) 0.999998) + (set! (-> data sincos-23 z) -0.16666014) + (set! (-> data sincos-45 z) 0.008326521) + (set! (-> data sincos-67 z) -0.0001956241) + (set! (-> data sincos-89 z) 0.0000023042373) + (set! (-> data sincos-01 w) 1.0) + (set! (-> data sincos-23 w) -0.49998003) + (set! (-> data sincos-45 w) 0.041620404) + (set! (-> data sincos-67 w) -0.0013636408) + (set! (-> data sincos-89 w) 0.000020170546) + + ;; math camera stuff + (set! (-> data basis-x quad) (the-as uint128 0)) + (set! (-> data basis-x x) (- (-> *math-camera* perspective vector 0 x))) + (set! (-> data basis-y quad) (the-as uint128 0)) + (set! (-> data basis-y y) (- (-> *math-camera* perspective vector 1 y))) + (set! (-> data min-scale) (sqrtf (* (/ 1.0 (-> data basis-x x)) (/ 1.0 (-> data basis-y y))))) + (set! (-> data inv-area) (/ 1.0 (* (-> data min-scale) (-> data min-scale)))) + ;; ?? + (set-vector! (-> data cdata 0) -0.5 -0.5 0.0 0.0) + (set-vector! (-> data cdata 1) 0.5 -0.5 0.0 0.0) + (set-vector! (-> data cdata 2) 0.5 0.5 0.0 0.0) + (set-vector! (-> data cdata 3) -0.5 0.5 0.0 0.0) + (set-vector! (-> data cdata 4) 0.0 -0.5 0.0 0.0) + (set-vector! (-> data cdata 5) 1.0 -0.5 0.0 0.0) + (set-vector! (-> data cdata 6) 1.0 0.5 0.0 0.0) + (set-vector! (-> data cdata 7) 0.0 0.5 0.0 0.0) + (set-vector! (-> data cdata 8) 0.0 0.0 1.0 0.0) + (set-vector! (-> data cdata 9) 1.0 0.0 1.0 0.0) + (set-vector! (-> data cdata 10) 1.0 1.0 1.0 0.0) + (set-vector! (-> data cdata 11) 0.0 1.0 1.0 0.0) + (set-vector! (-> data cdata 12) -0.5 0.0 -0.5 0.0) + (set-vector! (-> data cdata 13) 0.5 0.0 -0.5 0.0) + (set-vector! (-> data cdata 14) 0.5 0.0 0.5 0.0) + (set-vector! (-> data cdata 15) -0.5 0.0 0.5 0.0) + + ;; perspective correction stuff + (set-vector! (-> data stq-offset) + -1792.0 + (+ -2048.0 (the float (-> *video-parms* screen-hy))) + 0.0 + 0.0 + ) + (set-vector! (-> data stq-scale) 0.0009765625 0.00390625 1.0 1.0) + + ;; ?? + (set! (-> data rgba-plain vector4w x) 128) + (set! (-> data rgba-plain vector4w y) 128) + (set! (-> data rgba-plain vector4w z) 128) + (set! (-> data rgba-plain vector4w w) 64) + (set! (-> data fog-clamp x) (-> *math-camera* fog-min)) + (set! (-> data fog-clamp y) (-> *math-camera* fog-max)) + (set! (-> data fog-clamp z) 2048.0) + (none) + ) + +;;(define sprite-vu1-block (the-as vu-function L58)) + +;;;;;;;;;;;;;;;;;; +;; sprite-arrays +;;;;;;;;;;;;;;;;;; + +;; There are two global sprite arrays - one for 2d and one for 3d +;; Each array has two groups, but 3d sprites only use group 0. +;; Data from these arrarys is used in sprite-draw to build DMA lists. + +(defmethod new sprite-array-2d ((allocation symbol) (type-to-make type) (group-0-size int) (group-1-size int)) + "Allocate a sprite-array for 2d sprites. There are two groups, each can contain the given number." + (let* ((sprite-count (+ group-0-size group-1-size)) + (vec-data-size (* 3 sprite-count)) ;; 3 quadwords of vec-data per sprite + (adgif-data-size (* 5 sprite-count)) ;; 5 quadwords of adgif data per sprite + (v0-0 (object-new allocation type-to-make + (the-as int (+ (-> type-to-make size) (the-as uint (* (+ (+ adgif-data-size -1) vec-data-size) 16)))) + ) + ) + ) + (set! (-> v0-0 num-sprites 0) group-0-size) + (set! (-> v0-0 num-sprites 1) group-1-size) + (set! (-> v0-0 num-valid 0) 0) + (set! (-> v0-0 num-valid 1) 0) + + ;; internally, we put the vec-data and then the adgif-data + (set! (-> v0-0 vec-data) (the-as uint (-> v0-0 data))) + (set! (-> v0-0 adgif-data) (the-as uint (&-> v0-0 data vec-data-size))) + v0-0 + ) + ) + +(defmethod new sprite-array-3d ((allocation symbol) (type-to-make type) (group-0-size int) (group-1-size int)) + "Allocate a sprite-array for 3d sprites. There are two groups, each can contain the given number of sprites. + Group 1 size is zero in practive for 3d." + (let* ((sprite-count (+ group-0-size group-1-size)) + (vec-data-size (* 3 sprite-count)) + (adgif-data-size (* 5 sprite-count)) + (v0-0 (object-new allocation type-to-make + (the-as int (+ (-> type-to-make size) (the-as uint (* (+ (+ adgif-data-size -1) vec-data-size) 16)))) + ) + ) + ) + (set! (-> v0-0 num-sprites 0) group-0-size) + (set! (-> v0-0 num-sprites 1) group-1-size) + (set! (-> v0-0 num-valid 0) 0) + (set! (-> v0-0 num-valid 1) 0) + (set! (-> v0-0 vec-data) (the-as uint (-> v0-0 data))) + (set! (-> v0-0 adgif-data) (the-as uint (&-> v0-0 data vec-data-size))) + v0-0 + ) + ) + +(define *sprite-array-2d* (new 'global 'sprite-array-2d 1920 128)) +;; note that there are 0 group 1 3d's +(define *sprite-array-3d* (new 'global 'sprite-array-3d 256 0)) + +(defun sprite-set-3d-quaternion! ((arg0 sprite-vec-data-3d) (arg1 quaternion)) + "Set the quaternion for a 3d sprite. + NOTE: the w component of the quaternion is not stored and + the original w value is preserved." + (local-vars (v1-0 float) (v1-1 float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (init-vf0-vector) + (cond + ((< (-> arg1 w) 0.0) + (.lvf vf1 (&-> arg0 qx-qy-qz-sy quad)) + (.lvf vf2 (&-> arg1 vec quad)) + (.sub.vf vf1 vf0 vf2 :mask #b111) + (.svf (&-> arg0 qx-qy-qz-sy quad) vf1) + (.mov v1-0 vf1) + ) + (else + (.lvf vf1 (&-> arg0 qx-qy-qz-sy quad)) + (.lvf vf2 (&-> arg1 vec quad)) + (.add.vf vf1 vf0 vf2 :mask #b111) + (.svf (&-> arg0 qx-qy-qz-sy quad) vf1) + (.mov v1-1 vf1) + ) + ) + arg1 + ) + ) + +(defun sprite-get-3d-quaternion! ((arg0 quaternion) (arg1 sprite-vec-data-3d)) + "Get a quaternion. It's stored with only 3 components, so qw is + recalculated." + (let ((f0-0 (-> arg1 qx-qy-qz-sy x)) + (f1-0 (-> arg1 qx-qy-qz-sy y)) + (f3-0 (-> arg1 qx-qy-qz-sy z)) + ) + (set! (-> arg0 x) f0-0) + (set! (-> arg0 y) f1-0) + (set! (-> arg0 z) f3-0) + (set! + (-> arg0 w) + (sqrtf (- (- (- 1.0 (* f3-0 f3-0)) (* f1-0 f1-0)) (* f0-0 f0-0))) + ) + ) + arg0 + ) + +(defun sprite-add-matrix-data ((dma-buff dma-buffer) (matrix-mode uint)) + "Add matrix data to a dma-buffer. + Mode 0 = send (-> *math-camera* camera-temp) + Mode 1 = screen sprites, like the HUD" + (let ((count 900)) ;; maybe address?? + (cond + ((zero? matrix-mode) + + ;; upload to VU1 memory setup + (let* ((a1-1 dma-buff) + (pkt1 (the-as dma-packet (-> a1-1 base))) + ) + (set! (-> pkt1 dma) (new 'static 'dma-tag :qwc #x5 :id (dma-tag-id cnt))) + (set! (-> pkt1 vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl))) + (set! (-> pkt1 vif1) (new 'static 'vif-tag + :num #x5 + :cmd (vif-cmd unpack-v4-32) + :imm (shr (shl count 54) 54) + ) + ) + (set! (-> a1-1 base) (&+ (the-as pointer pkt1) 16)) + ) + + ;; sent the camera-temp matrix + (let* ((mtx (the-as matrix (-> dma-buff base))) + (t1-0 (-> *math-camera* camera-temp)) + (a2-4 (-> t1-0 vector 0 quad)) + (a3-4 (-> t1-0 vector 1 quad)) + (t0-4 (-> t1-0 vector 2 quad)) + (t1-1 (-> t1-0 vector 3 quad)) + ) + (set! (-> mtx vector 0 quad) a2-4) + (set! (-> mtx vector 1 quad) a3-4) + (set! (-> mtx vector 2 quad) t0-4) + (set! (-> mtx vector 3 quad) t1-1) + ) + (&+! (-> dma-buff base) 64) + + ;; also send this thing. + (let ((v1-1 (+ count 4))) + (set! (-> (the-as (pointer uint128) (-> dma-buff base))) + (-> *math-camera* hvdf-off quad) + ) + (&+! (-> dma-buff base) 16) + (+ v1-1 1) + ) + ) + + ((= matrix-mode 1) + (let* ((a1-10 dma-buff) + (pkt2 (the-as dma-packet (-> a1-10 base))) + ) + (set! (-> pkt2 dma) (new 'static 'dma-tag :qwc #x50 :id (dma-tag-id cnt))) + (set! (-> pkt2 vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl))) + (set! (-> pkt2 vif1) (new 'static 'vif-tag + :num #x50 ;; this looks wrong... + :cmd (vif-cmd unpack-v4-32) + :imm (shr (shl count 54) 54) + ) + ) + (set! (-> a1-10 base) (&+ (the-as pointer pkt2) 16)) + ) + (let ((mtx2 (the-as matrix (-> dma-buff base))) + (f1-0 (-> *math-camera* perspective vector 0 x)) + (f2-0 (-> *math-camera* perspective vector 1 y)) + (f0-1 (* -1.9996 (-> *math-camera* perspective vector 0 x))) + ) + (set-vector! (-> mtx2 vector 0) f0-1 0.0 0.0 0.0) + (set-vector! (-> mtx2 vector 1) 0.0 (- (* (/ f2-0 f1-0) f0-1)) 0.0 0.0) + (set-vector! (-> mtx2 vector 2) 0.0 0.0 (- f0-1) 0.0) + (set-vector! (-> mtx2 vector 3) + 0.0 + 0.0 + (* 500000000.0 f0-1) + (* (* 60.0 f0-1) (-> *math-camera* pfog0)) + ) + ) + (&+! (-> dma-buff base) 64) + (let ((v1-2 (+ count 4))) + (let ((a1-16 (the-as vector (-> dma-buff base)))) + (set! (-> a1-16 quad) (-> *math-camera* hvdf-off quad)) + (set! (-> a1-16 x) 2048.0) + (set! (-> a1-16 y) 2048.0) + (set! (-> a1-16 z) (-> *math-camera* hvdf-off z)) + ) + (&+! (-> dma-buff base) 16) + (let ((v1-3 (+ v1-2 1))) + (dotimes (hvdf-idx 75) + (set! + (-> (the-as (pointer uint128) (-> dma-buff base))) + (-> *sprite-hvdf-data* data (+ hvdf-idx 1) quad) + ) + (&+! (-> dma-buff base) 16) + (+! v1-3 1) + ) + ) + ) + ) + ) + ) + 0 + (none) + ) + +(defun sprite-add-frame-data ((dma-buff dma-buffer) (tbp-offset uint)) + "Upload the frame data." + (let ((s5-0 41)) ;; qwc of frame data. + (let* ((v1-0 dma-buff) + (pkt (the-as dma-packet (-> v1-0 base))) + ) + (set! (-> pkt dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc s5-0)) + (set! (-> pkt vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl))) + (set! (-> pkt vif1) (new 'static 'vif-tag :imm #x3d4 :cmd (vif-cmd unpack-v4-32) :num s5-0)) + (set! (-> v1-0 base) (&+ (the-as pointer pkt) 16)) + ) + ;; setup frame data directly in the dma buffer. + (sprite-setup-frame-data + (the-as sprite-frame-data (-> dma-buff base)) + (the-as int tbp-offset) + ) + (&+! (-> dma-buff base) (* s5-0 16)) + ) + (none) + ) + +(defun sprite-add-2d-chunk ((sprites sprite-array-2d) (start-sprite-idx int) (num-sprites int) (dma-buff dma-buffer) (mscal-addr int)) + "Upload sprite data from elements in the array." + ;; first packet is just the header + (let ((qwc-pkt1 1)) + (let* ((v1-0 dma-buff) + (pkt1 (the-as dma-packet (-> v1-0 base))) + ) + ;; setup for VU1 data memory + (set! (-> pkt1 dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc qwc-pkt1)) + (set! (-> pkt1 vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl))) + (set! (-> pkt1 vif1) (new 'static 'vif-tag + :imm #x8000 + :cmd (vif-cmd unpack-v4-32) + :num qwc-pkt1 + ) + ) + (set! (-> v1-0 base) (&+ (the-as pointer pkt1) 16)) + ) + ;; set up the header data. + (sprite-setup-header (the-as sprite-header (-> dma-buff base)) num-sprites) + (&+! (-> dma-buff base) (* qwc-pkt1 16)) + ) + + ;; second packet is vector data (3 qw / sprite) + (let* ((qwc-pkt2 (* 3 num-sprites)) + (v1-4 dma-buff) + (pkt2 (the-as dma-packet (-> v1-4 base))) + ) + ;; we do a ref to the vec-data and don't actually copy it into the dma-buffer + (set! (-> pkt2 dma) + (new 'static 'dma-tag + :id (dma-tag-id ref) + :addr (+ (-> sprites vec-data) (the-as uint (* 48 start-sprite-idx))) + :qwc qwc-pkt2 + ) + ) + (set! (-> pkt2 vif0) (new 'static 'vif-tag)) + (set! (-> pkt2 vif1) (new 'static 'vif-tag :imm #x8001 :cmd (vif-cmd unpack-v4-32) :num qwc-pkt2)) + (set! (-> v1-4 base) (&+ (the-as pointer pkt2) 16)) + ) + + ;; third packet is adgif data (5 qw/sprite) + (let* ((qwc-pkt3 (* 5 num-sprites)) + (v1-6 dma-buff) + (pkt3 (the-as dma-packet (-> v1-6 base))) + ) + (set! (-> pkt3 dma) (new 'static 'dma-tag + :id (dma-tag-id ref) + :addr (+ (-> sprites adgif-data) (the-as uint (* 80 start-sprite-idx))) + :qwc qwc-pkt3 + ) + ) + (set! (-> pkt3 vif0) (new 'static 'vif-tag)) + (set! (-> pkt3 vif1) (new 'static 'vif-tag :imm #x8091 :cmd (vif-cmd unpack-v4-32) :num qwc-pkt3)) + (set! (-> v1-6 base) (&+ (the-as pointer pkt3) 16)) + ) + + ;; fourth packet runs the renderer! + (let ((pkt4 (the-as dma-packet (-> dma-buff base)))) + (set! (-> pkt4 dma) (new 'static 'dma-tag :id (dma-tag-id cnt))) + (set! (-> pkt4 vif0) (new 'static 'vif-tag)) + (set! (-> pkt4 vif1) (new 'static 'vif-tag :cmd (vif-cmd mscal) :msk #x1 :imm mscal-addr)) + (set! (-> dma-buff base) (&+ (the-as pointer pkt4) 16)) + ) + (none) + ) + +(defun sprite-add-2d-all ((sprites sprite-array-2d) (dma-buff dma-buffer) (group-idx int)) + "Builds a DMA list for sprites" + ;; skip if we have no sprites + (when (> (-> sprites num-valid group-idx) 0) + ;; we'll do batches of up to 48 at a time. + (let ((current-sprite-idx 0) + (mscal-addr 3) + ) + (when (= group-idx 1) + ;; if we're doing group 1 sprites, start at the first sprite in group 1. + (set! current-sprite-idx (-> sprites num-sprites 0)) + ;; and use the other mpg. + (set! mscal-addr 109) + ) + + ;; loop over chunks + (let ((remaining-sprites (-> sprites num-valid group-idx))) + (while (< 48 remaining-sprites) + (sprite-add-2d-chunk sprites current-sprite-idx 48 dma-buff mscal-addr) + (+! current-sprite-idx 48) + (+! remaining-sprites -48) + ) + (sprite-add-2d-chunk sprites current-sprite-idx remaining-sprites dma-buff mscal-addr) + ) + ) + ) + (none) + ) + +(defun sprite-add-3d-chunk ((sprites sprite-array-3d) (start-sprite-idx int) (num-sprites int) (dma-buff dma-buffer)) + "Add DMA list data for up to 48 sprites. This is very similar to the 2D one, see that for more documentation" + (let ((qwc-pkt1 1)) + (let* ((v1-0 dma-buff) + (pkt1 (the-as dma-packet (-> v1-0 base))) + ) + (set! (-> pkt1 dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc qwc-pkt1)) + (set! (-> pkt1 vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl))) + (set! (-> pkt1 vif1) (new 'static 'vif-tag + :imm #x8000 + :cmd (vif-cmd unpack-v4-32) + :num qwc-pkt1 + ) + ) + (set! (-> v1-0 base) (&+ (the-as pointer pkt1) 16)) + ) + (sprite-setup-header (the-as sprite-header (-> dma-buff base)) num-sprites) + (&+! (-> dma-buff base) (* qwc-pkt1 16)) + ) + (let* ((qwc-pkt2 (* 3 num-sprites)) + (v1-4 dma-buff) + (pkt2 (the-as dma-packet (-> v1-4 base))) + ) + (set! (-> pkt2 dma) (new 'static 'dma-tag + :id (dma-tag-id ref) + :addr (+ (-> sprites vec-data) (the-as uint (* 48 start-sprite-idx))) + :qwc qwc-pkt2 + ) + ) + (set! (-> pkt2 vif0) (new 'static 'vif-tag)) + (set! (-> pkt2 vif1) (new 'static 'vif-tag :imm #x8001 :cmd (vif-cmd unpack-v4-32) :num qwc-pkt2)) + (set! (-> v1-4 base) (&+ (the-as pointer pkt2) 16)) + ) + (let* ((qwc-pkt3 (* 5 num-sprites)) + (v1-6 dma-buff) + (pkt3 (the-as dma-packet (-> v1-6 base))) + ) + (set! (-> pkt3 dma) (new 'static 'dma-tag + :id (dma-tag-id ref) + :addr (+ (-> sprites adgif-data) (the-as uint (* 80 start-sprite-idx))) + :qwc qwc-pkt3 + ) + ) + (set! (-> pkt3 vif0) (new 'static 'vif-tag)) + (set! (-> pkt3 vif1) (new 'static 'vif-tag :imm #x8091 :cmd (vif-cmd unpack-v4-32) :num qwc-pkt3)) + (set! (-> v1-6 base) (&+ (the-as pointer pkt3) 16)) + ) + (let ((pkt4 (the-as dma-packet (-> dma-buff base)))) + (set! (-> pkt4 dma) (new 'static 'dma-tag :id (dma-tag-id cnt))) + (set! (-> pkt4 vif0) (new 'static 'vif-tag)) + (set! (-> pkt4 vif1) (new 'static 'vif-tag :cmd (vif-cmd mscal) :msk #x1 :imm #xd3)) + (set! (-> dma-buff base) (&+ (the-as pointer pkt4) 16)) + ) + (none) + ) + +(defun sprite-add-3d-all ((sprites sprite-array-3d) (dma-buff dma-buffer) (group-idx int)) + "Set up DMA for all 3d sprites" + (when (> (-> sprites num-valid group-idx) 0) + ;; pick the starting idx + (let ((current-sprite-idx + (if (zero? group-idx) + 0 + (-> sprites num-sprites 0) + ) + ) + (remaining-sprites (-> sprites num-valid group-idx)) + ) + ;; loop over chunks + (while (< 48 remaining-sprites) + (sprite-add-3d-chunk sprites current-sprite-idx 48 dma-buff) + (+! current-sprite-idx 48) + (+! remaining-sprites -48) + ) + (sprite-add-3d-chunk sprites current-sprite-idx remaining-sprites dma-buff) + ) + ) + (none) + ) + +(defun sprite-add-shadow-chunk ((shadow-buff fake-shadow-buffer) (start-idx int) (num-sprites int) (dma-buff dma-buffer)) + "Add shadow sprites" + + ;; first packet is a header + (let ((pkt1-qwc 1)) + (let* ((v1-0 dma-buff) + (pkt1 (the-as dma-packet (-> v1-0 base))) + ) + (set! (-> pkt1 dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc pkt1-qwc)) + (set! (-> pkt1 vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl))) + (set! (-> pkt1 vif1) (new 'static 'vif-tag + :imm #x8000 + :cmd (vif-cmd unpack-v4-32) + :num pkt1-qwc + ) + ) + (set! (-> v1-0 base) (&+ (the-as pointer pkt1) 16)) + ) + (sprite-setup-header (the-as sprite-header (-> dma-buff base)) num-sprites) + (&+! (-> dma-buff base) (* pkt1-qwc 16)) + ) + + ;; next vec data + (let* ((pkt2-qwc (* 3 num-sprites)) + (v1-4 dma-buff) + (pkt2 (the-as dma-packet (-> v1-4 base))) + ) + (set! (-> pkt2 dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc pkt2-qwc)) + (set! (-> pkt2 vif0) (new 'static 'vif-tag)) + (set! (-> pkt2 vif1) (new 'static 'vif-tag :imm #x8001 :cmd (vif-cmd unpack-v4-32) :num pkt2-qwc)) + (set! (-> v1-4 base) (&+ (the-as pointer pkt2) 16)) + ) + ;; which we populate inside the dma-buffer, unlike normal sprites + (dotimes (sprite-idx num-sprites) + (let ((dma-vec-data (the-as (inline-array vector) (-> dma-buff base)))) + (let ((in-vec-data (-> shadow-buff data (+ start-idx sprite-idx)))) + (set! (-> dma-vec-data 0 x) (-> in-vec-data px)) + (set! (-> dma-vec-data 0 y) (-> in-vec-data py)) + (set! (-> dma-vec-data 0 z) (-> in-vec-data pz)) + (set! (-> dma-vec-data 0 w) (-> in-vec-data scale)) + (set! (-> dma-vec-data 1 x) (-> in-vec-data qx)) + (set! (-> dma-vec-data 1 y) (-> in-vec-data qy)) + (set! (-> dma-vec-data 1 z) (-> in-vec-data qz)) + (set! (-> dma-vec-data 1 w) (-> in-vec-data scale)) + ) + (set! (-> dma-vec-data 2 x) 128.0) + (set! (-> dma-vec-data 2 y) 128.0) + (set! (-> dma-vec-data 2 z) 128.0) + (set! (-> dma-vec-data 2 w) 40.0) + ) + (&+! (-> dma-buff base) 48) + ) + + ;; and adgif data + (let* ((a1-15 (* 5 num-sprites)) + (v1-9 dma-buff) + (pkt3 (the-as dma-packet (-> v1-9 base))) + ) + (set! (-> pkt3 dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc a1-15)) + (set! (-> pkt3 vif0) (new 'static 'vif-tag)) + (set! (-> pkt3 vif1) (new 'static 'vif-tag :imm #x8091 :cmd (vif-cmd unpack-v4-32) :num a1-15)) + (set! (-> v1-9 base) (&+ (the-as pointer pkt3) 16)) + ) + ;; again, populated as we go. This is inefficient, but these shadows were only temporary. + (dotimes (si num-sprites) + (let ((dma-adgif-data (the-as adgif-shader (-> dma-buff base))) + (in-adgif-data (-> shadow-buff data (+ start-idx si))) + ) + (adgif-shader<-texture-simple! dma-adgif-data *shadow-middot-texture*) + (if (logtest? (-> in-adgif-data flags) 1) + (set! (-> dma-adgif-data alpha) (new 'static 'gs-miptbp :tbp1 #x48)) + (set! (-> dma-adgif-data alpha) (new 'static 'gs-miptbp :tbp1 #x42)) + ) + ) + (&+! (-> dma-buff base) 80) + ) + + ;; and run + (let ((pkt4 (the-as dma-packet (-> dma-buff base)))) + (set! (-> pkt4 dma) (new 'static 'dma-tag :id (dma-tag-id cnt))) + (set! (-> pkt4 vif0) (new 'static 'vif-tag)) + (set! (-> pkt4 vif1) (new 'static 'vif-tag :cmd (vif-cmd mscal) :msk #x1 :imm #xd3)) + (set! (-> dma-buff base) (&+ (the-as pointer pkt4) 16)) + ) + (none) + ) + +(defun sprite-add-shadow-all ((shadow-buff fake-shadow-buffer) (dma-buff dma-buffer)) + "Set up DMA to add all shadows in the shadow buffer" + (when (> (-> shadow-buff num-shadows) 0) + (let ((current-shadow 0) + (remaining-shadows (-> shadow-buff num-shadows)) + ) + (while (< 48 remaining-shadows) + (sprite-add-shadow-chunk shadow-buff current-shadow 48 dma-buff) + (+! current-shadow 48) + (+! remaining-shadows -48) + ) + (sprite-add-shadow-chunk shadow-buff current-shadow remaining-shadows dma-buff) + ) + ) + (none) + ) + +(defun sprite-draw ((disp display)) + "Main sprite draw function." + ;; start of our DMA for all the sprite data + (let ((dma-mem-begin (-> *display* frames (-> *display* on-screen) frame global-buf base))) + ;; draw in global-buf + (let* ((dma-buff (-> *display* frames (-> *display* on-screen) frame global-buf)) + (dma-bucket-begin (-> dma-buff base)) + ) + + ;; run the distorters + (sprite-init-distorter dma-buff (-> disp frames (-> disp on-screen) draw frame1 fbp)) + (sprite-draw-distorters dma-buff) + + ;; first packet - set up the GS registers + (let* ((v1-13 dma-buff) + (pkt1 (the-as dma-packet (-> v1-13 base))) + ) + (set! (-> pkt1 dma) (new 'static 'dma-tag :qwc #x3 :id (dma-tag-id cnt))) + (set! (-> pkt1 vif0) (new 'static 'vif-tag)) + (set! (-> pkt1 vif1) (new 'static 'vif-tag :imm #x3 :cmd (vif-cmd direct) :msk #x1)) + (set! (-> v1-13 base) (&+ (the-as pointer pkt1) 16)) + ) + (let* ((v1-14 dma-buff) + (giftag (the-as gs-gif-tag (-> v1-14 base))) + ) + (set! (-> giftag tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x2)) + (set! (-> giftag 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-14 base) (&+ (the-as pointer giftag) 16)) + ) + (let* ((v1-15 dma-buff) + (a0-13 (-> v1-15 base)) + ) + ;; set test and clamp + (set! (-> (the-as (pointer gs-test) a0-13) 0) + (new 'static 'gs-test + :ate #x1 + :atst #x5 + :aref #x26 + :afail #x1 + :zte #x1 + :ztst #x2 + ) + ) + (set! (-> (the-as (pointer gs-reg64) a0-13) 1) (gs-reg64 test-1)) + (set! (-> (the-as (pointer gs-clamp) a0-13) 2) (new 'static 'gs-clamp :wms #x1 :wmt #x1)) + (set! (-> (the-as (pointer gs-reg64) a0-13) 3) (gs-reg64 clamp-1)) + (set! (-> v1-15 base) (&+ a0-13 32)) + ) + + ;; load the VU1 code + (dma-buffer-add-vu-function dma-buff sprite-vu1-block 1) + ;; add the common data + (sprite-add-frame-data dma-buff (-> disp frames (-> disp on-screen) draw frame1 fbp)) + + ;; run the init part of the VU1 mpg + (let* ((v1-22 dma-buff) + (pkt2 (the-as dma-packet (-> v1-22 base))) + ) + (set! (-> pkt2 dma) (new 'static 'dma-tag :id (dma-tag-id cnt))) + (set! (-> pkt2 vif0) (new 'static 'vif-tag :cmd (vif-cmd mscalf) :msk #x1 :imm #x0)) + (set! (-> pkt2 vif1) (new 'static 'vif-tag :cmd (vif-cmd flushe) :msk #x1)) + (set! (-> v1-22 base) (&+ (the-as pointer pkt2) 16)) + ) + + ;; set up double buffer upload and draw + (let* ((v1-23 dma-buff) + (pkt3 (the-as dma-packet (-> v1-23 base))) + ) + (set! (-> pkt3 dma) (new 'static 'dma-tag :id (dma-tag-id cnt))) + (set! (-> pkt3 vif0) (new 'static 'vif-tag :cmd (vif-cmd base))) + (set! (-> pkt3 vif1) (new 'static 'vif-tag :imm #x190 :cmd (vif-cmd offset))) + (set! (-> v1-23 base) (&+ (the-as pointer pkt3) 16)) + ) + + ;; add matrix data (not needed for init) + (sprite-add-matrix-data dma-buff (the-as uint 0)) + ;; draw 3d's + (sprite-add-3d-all *sprite-array-3d* dma-buff 0) + ;; draw 2d's (group 0) + (sprite-add-2d-all *sprite-array-2d* dma-buff 0) + ;; draw shadows + (sprite-add-shadow-all (if (= *fake-shadow-buffer* *fake-shadow-buffer-1*) + *fake-shadow-buffer-2* + *fake-shadow-buffer-1* + ) + dma-buff + ) + (let* ((v1-25 dma-buff) + (pkt4 (the-as dma-packet (-> v1-25 base))) + ) + (set! (-> pkt4 dma) (new 'static 'dma-tag :id (dma-tag-id cnt))) + (set! (-> pkt4 vif0) (new 'static 'vif-tag)) + (set! (-> pkt4 vif1) (new 'static 'vif-tag :cmd (vif-cmd flushe) :msk #x1)) + (set! (-> v1-25 base) (&+ (the-as pointer pkt4) 16)) + ) + ;; set matrix for group 1 (screen-space sprites) + (sprite-add-matrix-data dma-buff (the-as uint 1)) + ;; draw screen sprites + (sprite-add-2d-all *sprite-array-2d* dma-buff 1) + + ;; patch up the bucket + (let ((a3-0 (-> dma-buff base))) + (let ((pkt5 (the-as dma-packet (-> dma-buff base)))) + (set! (-> pkt5 dma) (new 'static 'dma-tag :id (dma-tag-id next))) + (set! (-> pkt5 vif0) (new 'static 'vif-tag)) + (set! (-> pkt5 vif1) (new 'static 'vif-tag)) + (set! (-> dma-buff base) (&+ (the-as pointer pkt5) 16)) + ) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) frame bucket-group) + (bucket-id sprite) + dma-bucket-begin + (the-as (pointer dma-tag) a3-0) + ) + ) + ) + + ;; update memory usage + (let ((mem-use *dma-mem-usage*)) + (when (nonzero? mem-use) + (set! (-> mem-use length) (max 83 (-> mem-use length))) + (set! (-> mem-use data 82 name) "sprite") + (+! (-> mem-use data 82 count) 1) + (+! (-> mem-use data 82 used) + (&- (-> *display* frames (-> *display* on-screen) frame global-buf base) + (the-as uint dma-mem-begin) + ) + ) + (set! (-> mem-use data 82 total) (-> mem-use data 82 used)) + ) + ) + ) + 0 + (none) + ) + +(defun sprite-allocate-user-hvdf () + "Allocate an HVDF entry. Returns the index. Or 0 if it fails" + (dotimes (v1-0 76) + (when (zero? (-> *sprite-hvdf-control* alloc v1-0)) + (set! (-> *sprite-hvdf-control* alloc v1-0) 1) + (return v1-0) + ) + ) + 0 + ) + +(defun sprite-release-user-hvdf ((arg0 int)) + "Free an HVDF" + (when (and (>= arg0 1) (< arg0 76)) + (set! (-> *sprite-hvdf-control* alloc arg0) 0) + ) + (none) + ) + +(defun sprite-get-user-hvdf ((arg0 int)) + "Get an HVDF entry by index" + (-> *sprite-hvdf-data* data arg0) + ) + + diff --git a/goal_src/engine/gfx/texture.gc b/goal_src/engine/gfx/texture.gc index 9c8ce0c732..d79db65004 100644 --- a/goal_src/engine/gfx/texture.gc +++ b/goal_src/engine/gfx/texture.gc @@ -3318,3 +3318,5 @@ (define *texture-pool* (new 'global 'texture-pool)) + +(define-extern *shadow-middot-texture* texture) diff --git a/goal_src/engine/gfx/tfrag/subdivide-h.gc b/goal_src/engine/gfx/tfrag/subdivide-h.gc index 37850a19ae..6a3ed04875 100644 --- a/goal_src/engine/gfx/tfrag/subdivide-h.gc +++ b/goal_src/engine/gfx/tfrag/subdivide-h.gc @@ -15,11 +15,11 @@ :size-assert #x4c :flag-assert #x90000004c (:methods - (new (symbol type float float) _type_ 0) + (new (symbol type meters meters) _type_ 0) ) ) -(defmethod new subdivide-settings ((allocation symbol) (type-to-make type) (arg0 float) (arg1 float)) +(defmethod new subdivide-settings ((allocation symbol) (type-to-make type) (arg0 meters) (arg1 meters)) (let ((v0-0 (object-new allocation type-to-make (the-as int (-> type-to-make size))))) (dotimes (v1-2 3) (set! (-> v0-0 close v1-2) arg0) @@ -192,3 +192,5 @@ (define *terrain-stats* (new 'global 'terrain-stats)) (define *collide-stats* (new 'global 'collide-stats)) +(define-extern *subdivide-settings* subdivide-settings) +(define-extern update-subdivide-settings! (function subdivide-settings math-camera int none)) diff --git a/goal_src/engine/gfx/tfrag/subdivide.gc b/goal_src/engine/gfx/tfrag/subdivide.gc index 1a89c7386f..4dc38e8416 100644 --- a/goal_src/engine/gfx/tfrag/subdivide.gc +++ b/goal_src/engine/gfx/tfrag/subdivide.gc @@ -5,5 +5,419 @@ ;; name in dgo: subdivide ;; dgos: GAME, ENGINE +;; This file mainly contains statistics stuff for the background renderers. +;; And the mysterious "gomi stats hack", abbreviated GSH. -(define *subdivide-settings* (new 'global 'subdivide-settings (meters 30.0) (meters 70.0))) \ No newline at end of file +(define *merc-global-stats* (new 'global 'merc-global-stats)) + +(defun clear-tr-stat ((arg0 tr-stat)) + (set! (-> arg0 groups) (the-as uint 0)) + (set! (-> arg0 fragments) (the-as uint 0)) + (set! (-> arg0 tris) (the-as uint 0)) + (set! (-> arg0 dverts) (the-as uint 0)) + (set! (-> arg0 instances) (the-as uint 0)) + 0 + (none) + ) + +;; These contain the groups/frags/tris/dverts/insts statistics. +(define *stat-string-tfrag* (new 'global 'string 128 (the-as string #f))) +(define *stat-string-tfrag-near* (new 'global 'string 128 (the-as string #f))) +(define *stat-string-total* (new 'global 'string 128 (the-as string #f))) + +(defun-debug print-tr-stat ((stat tr-stat) (name string) (dest string)) + "Print the statistics for stat to dest and to the screen. Also add them to the total stats" + (clear dest) + (when (nonzero? (+ (+ (+ (+ (-> stat groups) (-> stat fragments)) (-> stat tris)) (-> stat dverts)) (-> stat instances))) + (format dest "~0k~4d ~5d ~6d ~6d" + (-> stat groups) + (-> stat fragments) + (-> stat tris) + (-> stat dverts) + ) + (format dest "~0k ~7f ~5d ~s" + (/ (* 2.0 (the float (-> stat tris))) (the float (- (-> stat dverts) (-> stat tris)))) + (-> stat instances) + name + ) + ;; print to the screen + (format *stdcon* "~S~%" dest) + ;; update total + (+! (-> *terrain-stats* total groups) (-> stat groups)) + (+! (-> *terrain-stats* total fragments) (-> stat fragments)) + (+! (-> *terrain-stats* total tris) (-> stat tris)) + (+! (-> *terrain-stats* total dverts) (-> stat dverts)) + (+! (-> *terrain-stats* total instances) (-> stat instances)) + ) + (none) + ) + +(defun-debug print-terrain-stats () + "Print all terrain statistics" + + ;; make our own profile thing. + (if *debug-segment* + (add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x40 :b #x40 :a #x80) + ) + ) + + ;; print level memory stats + (dotimes (gp-0 (-> *level* length)) + (let ((s5-0 (-> *level* level gp-0))) + (when (= (-> s5-0 status) 'active) + (dummy-14 s5-0 #f) + (format *stdcon* "~0k~D ~A ~,,2fK + textures~%" + (-> s5-0 index) + (-> s5-0 name) + (* 0.0009765625 (the float (-> s5-0 mem-usage))) + ) + ) + ) + ) + + ;; print all stats + (format *stdcon* "~0k~%grps frags tris dverts strip insts~%") + (print-tr-stat (-> *terrain-stats* pris) "pris" *temp-string*) + (print-tr-stat (-> *merc-global-stats* merc) "merc" *temp-string*) + (print-tr-stat (-> *merc-global-stats* mercneric) "mercneric" *temp-string*) + (print-tr-stat (-> *terrain-stats* tie-near) "tie-near" *temp-string*) + (print-tr-stat (-> *terrain-stats* tie) "tie" *temp-string*) + (print-tr-stat (-> *terrain-stats* tie-generic) "tie-generic" *temp-string*) + (print-tr-stat (-> *terrain-stats* shrub-near) "shrub-near" *temp-string*) + (print-tr-stat (-> *terrain-stats* shrub) "shrub" *temp-string*) + (print-tr-stat (-> *terrain-stats* tfrag-near) "tfrag-near" *stat-string-tfrag-near*) + (print-tr-stat (-> *terrain-stats* tfrag) "tfrag" *stat-string-tfrag*) + (print-tr-stat (-> *terrain-stats* trans-tfrag) "trans-tfrag" *temp-string*) + (print-tr-stat (-> *terrain-stats* trans-tfrag-near) "trans-tfrag-near" *temp-string*) + (print-tr-stat (-> *terrain-stats* trans-pris) "trans-pris" *temp-string*) + (print-tr-stat (-> *terrain-stats* billboard) "billboard" *temp-string*) + (print-tr-stat (-> *terrain-stats* trans-shrub) "trans-shrub" *temp-string*) + (print-tr-stat (-> *terrain-stats* ocean-mid) "ocean-mid" *temp-string*) + (print-tr-stat (-> *terrain-stats* ocean-near) "ocean-near" *temp-string*) + (format *stdcon* "~0k---------------------------------------------------------------~%") + (print-tr-stat (-> *terrain-stats* total) "total" *stat-string-total*) + + (clear-tr-stat (-> *terrain-stats* pris)) + (clear-tr-stat (-> *merc-global-stats* merc)) + (clear-tr-stat (-> *merc-global-stats* mercneric)) + (clear-tr-stat (-> *terrain-stats* shrub-near)) + (clear-tr-stat (-> *terrain-stats* tie-near)) + (clear-tr-stat (-> *terrain-stats* tie)) + (clear-tr-stat (-> *terrain-stats* tie-generic)) + (clear-tr-stat (-> *terrain-stats* shrub)) + (clear-tr-stat (-> *terrain-stats* tfrag-near)) + (clear-tr-stat (-> *terrain-stats* tfrag)) + (clear-tr-stat (-> *terrain-stats* trans-tfrag)) + (clear-tr-stat (-> *terrain-stats* trans-tfrag-near)) + (clear-tr-stat (-> *terrain-stats* trans-pris)) + (clear-tr-stat (-> *terrain-stats* billboard)) + (clear-tr-stat (-> *terrain-stats* trans-shrub)) + (clear-tr-stat (-> *terrain-stats* ocean-mid)) + (clear-tr-stat (-> *terrain-stats* ocean-near)) + (clear-tr-stat (-> *terrain-stats* total)) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :b #xff :a #x80) + ) + ) + 0 + (none) + ) + +(defun update-subdivide-settings! ((settings subdivide-settings) (math-cam math-camera) (idx int)) + "Change the subdivide settings." + (set! (-> settings meters 0) (-> settings far idx)) + (set! (-> settings meters 4) (-> settings close idx)) + (let ((f0-3 (* 0.14285715 (- (-> settings meters 0) (-> settings meters 4))))) + (set! (-> settings meters 3) (+ (-> settings meters 4) (* 0.5 f0-3))) + (set! (-> settings meters 2) (+ (-> settings meters 3) f0-3)) + (set! (-> settings meters 1) (+ (-> settings meters 2) (* 2.0 f0-3))) + ) + (let ((f0-7 (/ (-> math-cam inv-hmge-scale w) (-> math-cam d)))) + (dotimes (v1-5 5) + (set! (-> settings dist v1-5) (* f0-7 (-> settings meters v1-5))) + ) + ) + (set! (-> *tfrag-work* frag-dists x) (- (-> settings meters 0))) + (set! (-> *tfrag-work* frag-dists y) (- (-> settings meters 1))) + (set! (-> *tfrag-work* frag-dists z) (- (-> settings meters 2))) + (set! (-> *tfrag-work* frag-dists w) (- (-> settings meters 4))) + 0 + (none) + ) + +(define *subdivide-settings* (new 'global 'subdivide-settings (meters 30.0) (meters 70.0))) + +(defun set-tfrag-dists! ((arg0 (pointer float))) + "TODO - better type for arg0?" + (let ((f2-0 (-> *subdivide-settings* dist 0)) + (f1-0 (-> *subdivide-settings* dist 1)) + (f0-0 (-> *subdivide-settings* dist 2)) + ) + (set! (-> arg0 3) f2-0) + (set! (-> arg0 7) f1-0) + (let ((f4-1 (/ 1.0 (- f2-0 f1-0))) + (f3-2 (/ 1.0 (- f1-0 f0-0))) + ) + (set! (-> arg0 1) (- f4-1)) + (set! (-> arg0 5) (- f3-2)) + (set! (-> arg0 0) (* 0.5 f4-1)) + (set! (-> arg0 4) (* 0.5 f3-2)) + (let ((f2-1 (* f2-0 f4-1)) + (f5-7 (* f1-0 f3-2)) + ) + (set! (-> arg0 9) f2-1) + (set! (-> arg0 13) f5-7) + ) + (set! (-> arg0 8) (* (* -0.5 f4-1) f1-0)) + (set! (-> arg0 12) (* (* -0.5 f3-2) f0-0)) + ) + ) + (none) + ) + +(define *terrain-context* (new 'global 'terrain-context)) + +;; oops, this runs even when not debugging and ends up on global. +(define *perf-stats* (new 'debug 'perf-stat-array 17)) + +(defmethod print-to-stream perf-stat ((obj perf-stat) (arg0 string) (arg1 basic)) + "Print performance info to a stream. But the stream is ignored and it is + printed to the screen." + (format *stdcon* "~3d ~8d ~8d ~6d ~6d" + (-> obj count) + (-> obj cycles) + (-> obj instructions) + (-> obj icache) + (-> obj dcache) + ) + (format *stdcon* " ~2d ~2d ~2d" + (-> obj to-vu0-waits) + (-> obj to-spr-waits) + (-> obj from-spr-waits) + ) + (format *stdcon* " ~s~%" arg0) + (none) + ) + +(defenum perf-stat-bucket + (all-code 0) + (mercneric 1) + (tie-generic 2) + (background 3) + (drawable 4) + (tfrag 5) + (tfrag-near 6) + (inst-shrub 7) + (proto-shrub 8) + (inst-tie 9) + (proto-tie-g 10) + (proto-tie 11) + (proto-tie-n 12) + (bones 13) + (nav 14) + (collide 15) + (camera 16)) + +(defun-debug perf-stat-bucket->string ((arg0 perf-stat-bucket)) + (case arg0 + (((perf-stat-bucket camera)) "camera") + (((perf-stat-bucket collide)) "collide") + (((perf-stat-bucket nav)) "nav") + (((perf-stat-bucket bones)) "bones") + (((perf-stat-bucket proto-tie-n)) "proto-tie-n") + (((perf-stat-bucket proto-tie)) "proto-tie") + (((perf-stat-bucket proto-tie-g)) "proto-tie-g") + (((perf-stat-bucket inst-tie)) "inst-tie") + (((perf-stat-bucket proto-shrub)) "proto-shrub") + (((perf-stat-bucket inst-shrub)) "inst-shrub") + (((perf-stat-bucket tfrag-near)) "tfrag-near") + (((perf-stat-bucket tfrag)) "tfrag") + (((perf-stat-bucket drawable)) "drawable") + (((perf-stat-bucket background)) "background") + (((perf-stat-bucket tie-generic)) "tie-generic") + (((perf-stat-bucket mercneric)) "mercneric") + (((perf-stat-bucket all-code)) "all-code") + (else "*unknown*") + ) + ) + + +;; Set up for the GOMI STATS HACK +(define GSH_ENABLE #f) +(define GSH_BUCKET (the-as bucket-id 3)) +(define GSH_WHICH_STAT 1) +(define GSH_MAX_DISPLAY (the-as basic #f)) +(define GSH_TIME 64) + +(define *gomi-stats-hack* (the-as (inline-array perf-stat) (malloc 'debug (* 52 (+ GSH_TIME 1))))) + +(defun-debug start-perf-stat-collection () + (let ((frame-idx (+ (-> *perf-stats* data 0 frame-number) 1))) + (set! (-> *perf-stats* data 0 frame-number) frame-idx) + (let ((gp-0 (mod frame-idx (the-as uint 34)))) + (when GSH_ENABLE + (let ((bucket GSH_BUCKET)) + (let ((which-stat GSH_WHICH_STAT)) + (set! gp-0 (the-as uint (+ (* bucket 2) (the-as uint which-stat)))) + ) + (when GSH_MAX_DISPLAY + (let ((stat-idx (logand (-> *perf-stats* data 0 frame-number) (+ GSH_TIME -1)))) + (set! (-> *gomi-stats-hack* stat-idx cycles) + (-> *perf-stats* data (the-as int bucket) cycles) + ) + (set! (-> *gomi-stats-hack* stat-idx instructions) + (-> *perf-stats* data (the-as int bucket) instructions) + ) + (set! (-> *gomi-stats-hack* stat-idx icache) + (-> *perf-stats* data (the-as int bucket) icache) + ) + (set! (-> *gomi-stats-hack* stat-idx dcache) + (-> *perf-stats* data (the-as int bucket) dcache) + ) + (when (zero? stat-idx) + (set! (-> *gomi-stats-hack* GSH_TIME cycles) (the-as uint 0)) + (set! (-> *gomi-stats-hack* GSH_TIME instructions) (the-as uint 0)) + (set! (-> *gomi-stats-hack* GSH_TIME icache) (the-as uint 0)) + (set! (-> *gomi-stats-hack* GSH_TIME dcache) (the-as uint 0)) + (dotimes (v1-22 GSH_TIME) + (if (< (-> *gomi-stats-hack* GSH_TIME cycles) (-> *gomi-stats-hack* v1-22 cycles)) + (set! (-> *gomi-stats-hack* GSH_TIME cycles) + (-> *gomi-stats-hack* v1-22 cycles) + ) + ) + (if (< (-> *gomi-stats-hack* GSH_TIME instructions) (-> *gomi-stats-hack* v1-22 instructions)) + (set! (-> *gomi-stats-hack* GSH_TIME instructions) + (-> *gomi-stats-hack* v1-22 instructions) + ) + ) + (if (< (-> *gomi-stats-hack* GSH_TIME icache) (-> *gomi-stats-hack* v1-22 icache)) + (set! (-> *gomi-stats-hack* GSH_TIME icache) + (-> *gomi-stats-hack* v1-22 icache) + ) + ) + (if (< (-> *gomi-stats-hack* GSH_TIME dcache) (-> *gomi-stats-hack* v1-22 dcache)) + (set! (-> *gomi-stats-hack* GSH_TIME dcache) + (-> *gomi-stats-hack* v1-22 dcache) + ) + ) + ) + ) + ) + (format *stdcon* "~%") + (print-to-stream (-> *gomi-stats-hack* GSH_TIME) "max-value" *stdcon*) + ) + ) + ) + (dotimes (v1-27 17) + (set! (-> *perf-stats* data v1-27 count) (the-as uint 0)) + (cond + ((!= v1-27 (shr gp-0 1)) + (set! (-> *perf-stats* data v1-27 ctrl) (the-as uint 0)) + 0 + ) + (else + (let ((a1-63 (logand gp-0 1)) + (a0-64 (the-as uint #x80004010)) + ) + (cond + ((zero? a1-63) + (set! a0-64 (the-as uint (+ #x60020 (the-as int a0-64)))) + ) + ((= a1-63 1) + (set! a0-64 (the-as uint (+ #x300c0 (the-as int a0-64)))) + ) + ) + (set! (-> *perf-stats* data v1-27 select) a1-63) + (set! (-> *perf-stats* data v1-27 ctrl) a0-64) + ) + (set! (-> *perf-stats* data v1-27 accum0) (the-as uint 0)) + (set! (-> *perf-stats* data v1-27 accum1) (the-as uint 0)) + (set! (-> *perf-stats* data v1-27 to-vu0-waits) (the-as uint 0)) + (set! (-> *perf-stats* data v1-27 to-spr-waits) (the-as uint 0)) + (set! (-> *perf-stats* data v1-27 from-spr-waits) (the-as uint 0)) + 0 + ) + ) + ) + ) + ) + (let* ((v1-31 (-> *perf-stats* data)) + (a0-76 (-> v1-31 0 ctrl)) + ) + (+! (-> v1-31 0 count) 1) + (b! (zero? a0-76) cfg-28) + #| + (.mtc0 Perf r0-0) + (.sync.l) + (.sync.p) + (.mtpc pcr0 r0-0) + (.mtpc pcr1 r0-0) + (.sync.l) + (.sync.p) + (.mtc0 Perf a0-76) + |# + ) + (.sync.l) + (.sync.p) + (label cfg-28) + 0 + 0 + (none) + ) + +(defun-debug end-perf-stat-collection () + (local-vars (r0-0 none) (a0-1 int) (a0-3 int)) + (let ((v1-1 (-> *perf-stats* data))) + (b! (zero? (-> v1-1 0 ctrl)) cfg-2) + ;;(.mtc0 Perf r0-0) + (.sync.l) + (.sync.p) + ;;(.mfpc a0-1 pcr0) + (+! (-> v1-1 0 accum0) (the-as uint a0-1)) + ;;(.mfpc a0-3 pcr1) + (+! (-> v1-1 0 accum1) (the-as uint a0-3)) + ) + (label cfg-2) + 0 + (dotimes (v1-3 17) + (when (nonzero? (-> *perf-stats* data v1-3 ctrl)) + (let ((a2-0 (-> *perf-stats* data v1-3 select)) + (a1-8 (-> *perf-stats* data v1-3 accum0)) + (a0-15 (-> *perf-stats* data v1-3 accum1)) + ) + (cond + ((zero? a2-0) + (set! (-> *perf-stats* data v1-3 cycles) a1-8) + (set! (-> *perf-stats* data v1-3 instructions) a0-15) + ) + ((= a2-0 1) + (set! (-> *perf-stats* data v1-3 icache) a1-8) + (set! (-> *perf-stats* data v1-3 dcache) a0-15) + ) + ) + ) + ) + ) + 0 + (none) + ) + +(defun-debug print-perf-stats () + (format *stdcon* "~0k~%count cycles instr icache dcache vu0/to/from~%") + (dotimes (gp-0 17) + (if (nonzero? (-> *perf-stats* data gp-0 count)) + (print-to-stream + (-> *perf-stats* data gp-0) + (perf-stat-bucket->string (the-as perf-stat-bucket gp-0)) + *stdcon* + ) + ) + ) + 0 + (none) + ) diff --git a/goal_src/engine/gfx/tfrag/tfrag-h.gc b/goal_src/engine/gfx/tfrag/tfrag-h.gc index 579710d81b..c31e70d2e3 100644 --- a/goal_src/engine/gfx/tfrag/tfrag-h.gc +++ b/goal_src/engine/gfx/tfrag/tfrag-h.gc @@ -251,3 +251,5 @@ :size-assert #x37fc :flag-assert #x9000037fc ) + +(define-extern *tfrag-work* tfrag-work) \ No newline at end of file diff --git a/goal_src/engine/gfx/vis/bsp-h.gc b/goal_src/engine/gfx/vis/bsp-h.gc index c42e709626..62d57f1959 100644 --- a/goal_src/engine/gfx/vis/bsp-h.gc +++ b/goal_src/engine/gfx/vis/bsp-h.gc @@ -5,55 +5,65 @@ ;; name in dgo: bsp-h ;; dgos: GAME, ENGINE -;; The level's layout is stored in a BSP. -;; There is a bsp-header that contains the actual nodes -;; as well as lists of entities and other stuff found in the level. -;; As a result, it is more than just a BSP. -;; The final file in the level DGO is the BSP, and is the largest file. +;; Each level has . There is a bsp-header, and a list of bsp-nodes. +;; The bsp-nodes make up a tree. Each node has a plane and two child nodes. +;; The bsp-header also contains (or references) all of the static level information. +;; The file containing the bsp-header is called the "bt" and is loaded in a special +;; way because that allows it to use all of the remaining level heap memory. +;; This file is very large (>8 MB), and always the last file in a level DGO. + +;; In the game, all of these bsp-header files have -vis after their name +;; I believe this means that this is a version of a level that has an associated vis file +;; for precomputed visibility. + (declare-type entity-camera basic) +;; a node in the bsp tree (deftype bsp-node (structure) - ((front int32 :offset-assert 0) - (back int32 :offset-assert 4) - (front-flags uint32 :offset-assert 8) - (back-flags uint32 :offset-assert 12) - (plane vector :inline :offset-assert 16) + ((front int32 :offset-assert 0) ;; if > 0, is a pointer to another bsp-node + (back int32 :offset-assert 4) ;; if > 0, is a pointer to another bsp-node + (front-flags uint32 :offset-assert 8) ;; ? + (back-flags uint32 :offset-assert 12) ;; ? + (plane vector :inline :offset-assert 16) ;; the partitioning plane ) :method-count-assert 9 :size-assert #x20 :flag-assert #x900000020 ) +;; This is the object stored first in the level bt (-vis) +;; It is also a drawable, and drawing it will draw the level. (deftype bsp-header (drawable) - ((info file-info :offset 4) - (all-visible-list (pointer uint16) :offset-assert 32) - (visible-list-length int32 :offset-assert 36) - (drawable-trees drawable-tree-array :offset-assert 40) - (pat pointer :offset-assert 44) - (pat-length int32 :offset-assert 48) - (unk-data-0 pointer :offset-assert 52) - (unk-data-0-len int32 :offset-assert 56) - (unk-data-1 pointer :offset-assert 60) - (unk-data-1-len int32 :offset-assert 64) - (unk-zero-0 basic :offset-assert 68) - (name symbol :offset-assert 72) - (nickname symbol :offset-assert 76) - (vis-info level-vis-info 8 :offset-assert 80) - (actors drawable-inline-array-actor :offset-assert 112) - (cameras (array entity-camera) :offset-assert 116) - (nodes (inline-array bsp-node) :offset-assert 120) - (level level :offset-assert 124) - (unk-data-2 uint32 5 :offset-assert 128) - (boxes box8s-array :offset-assert 148) - (unk-data-3 uint32 :offset-assert 152) - (ambients drawable-inline-array-ambient :offset-assert 156) - (unk-data-4 float :offset-assert 160) - (unk-data-5 float :offset-assert 164) - (adgifs adgif-shader-array :offset-assert 168) - (unk-data-6 pointer :offset-assert 172) - (unk-data-7 pointer :offset-assert 176) - (unk-data-8 uint32 55 :offset-assert 180) + ((info file-info :offset 4) + (all-visible-list (pointer uint16) :offset-assert 32) + (visible-list-length int32 :offset-assert 36) + (drawable-trees drawable-tree-array :offset-assert 40) + (pat pointer :offset-assert 44) + (pat-length int32 :offset-assert 48) + (texture-remap-table (pointer uint64) :offset-assert 52) + (texture-remap-table-len int32 :offset-assert 56) + (unk-data-1 pointer :offset-assert 60) + (unk-data-1-len int32 :offset-assert 64) + (unk-zero-0 basic :offset-assert 68) + (name symbol :offset-assert 72) + (nickname symbol :offset-assert 76) + (vis-info level-vis-info 8 :offset-assert 80) + (actors drawable-inline-array-actor :offset-assert 112) + (cameras (array entity-camera) :offset-assert 116) + (nodes (inline-array bsp-node) :offset-assert 120) + (level level :offset-assert 124) + (current-leaf-idx uint16 :offset-assert 128) + (unk-data-2 uint16 9 :offset-assert 130) + (boxes box8s-array :offset-assert 148) + (current-bsp-back-flags uint32 :offset-assert 152) + (ambients drawable-inline-array-ambient :offset-assert 156) + (unk-data-4 float :offset-assert 160) + (unk-data-5 float :offset-assert 164) + (adgifs adgif-shader-array :offset-assert 168) + (unk-data-6 pointer :offset-assert 172) + (unk-data-7 pointer :offset-assert 176) + (unk-data-8 uint32 55 :offset-assert 180) ) :method-count-assert 20 :size-assert #x190 @@ -66,6 +76,7 @@ ) ;; seems to be unused? +;; In practice, a normal bsp-header is a game-level. (deftype game-level (basic) ((master-bsp basic :offset-assert 4) ) @@ -102,6 +113,7 @@ ) (defun-debug inspect-bsp-tree ((arg0 bsp-header) (arg1 bsp-node)) + "Recursively print all nodes in a bsp tree. This makes a huge mess" (cond ((zero? arg1) ) @@ -127,6 +139,7 @@ (define-extern map-bsp-tree (function (function bsp-node none) bsp-header bsp-node none)) (defun map-bsp-tree ((arg0 (function bsp-node none)) (arg1 bsp-header) (arg2 bsp-node)) + "Recursively apply arg0 to all nodes in the bsp tree" (cond ((zero? arg2) ) @@ -169,3 +182,7 @@ :size-assert #x80 :flag-assert #x900000080 ) + +;; offsets of stuff in the scratchpad during bsp draw. +(defconstant TERRAIN_BSP_SCRATCHPAD #x0) +(defconstant VISIBLE_LIST_SCRATCHPAD #x38b0) diff --git a/goal_src/engine/gfx/vis/bsp.gc b/goal_src/engine/gfx/vis/bsp.gc index a7b2e63f3a..5cd4305495 100644 --- a/goal_src/engine/gfx/vis/bsp.gc +++ b/goal_src/engine/gfx/vis/bsp.gc @@ -5,3 +5,653 @@ ;; name in dgo: bsp ;; dgos: GAME, ENGINE + +;;;;;;;;;;;;;;; +;; memory use +;;;;;;;;;;;;;;; + +(defun-recursive mem-usage-bsp-tree none ((header bsp-header) (node bsp-node) (mem-use memory-usage-block) (flags int)) + "Update the given mem-use for the memory used by the tree structure itself" + (cond + ((zero? node) + ) + (else + (+! (-> mem-use data 58 count) 1) + (let ((v1-3 32)) + (+! (-> mem-use data 58 used) v1-3) + (+! (-> mem-use data 58 total) (logand -16 (+ v1-3 15))) + ) + (if (> (-> node front) 0) + (mem-usage-bsp-tree header (the-as bsp-node (-> node front)) mem-use flags) + ) + (if (> (-> node back) 0) + (mem-usage-bsp-tree header (the-as bsp-node (-> node back)) mem-use flags) + ) + ) + ) + (none) + ) + +(defmethod mem-usage bsp-header ((obj bsp-header) (mem-use memory-usage-block) (flags int)) + "Update the memory usage info for this bsp-header. + This will visit all the stuff in the level data." + + ;; start off by setting the current bsp + (set! (-> mem-use work-bsp) obj) + + ;; this seems slightly wrong, we count the file-info toward array. + (when (nonzero? (-> obj info)) + (set! (-> mem-use length) (max 82 (-> mem-use length))) + (set! (-> mem-use data 81 name) "array") + (+! (-> mem-use data 81 count) 1) + (let ((v1-8 (asize-of (-> obj info)))) + (+! (-> mem-use data 81 used) v1-8) + (+! (-> mem-use data 81 total) (logand -16 (+ v1-8 15))) + ) + ) + + ;; measure the drawable trees. + (if (nonzero? (-> obj drawable-trees)) + (mem-usage (-> obj drawable-trees) mem-use flags) + ) + + ;; add stuff + (set! (-> mem-use length) (max 63 (-> mem-use length))) + (set! (-> mem-use data 43 name) "entity") + (set! (-> mem-use data 44 name) "camera") + (set! (-> mem-use data 62 name) "pat") + (set! (-> mem-use data 58 name) "bsp-node") + (set! (-> mem-use length) (max 57 (-> mem-use length))) + + ;; add the bsp-header itself + (set! (-> mem-use data 56 name) "bsp-main") + (+! (-> mem-use data 56 count) 1) + (let ((v1-27 400)) + (+! (-> mem-use data 56 used) v1-27) + (+! (-> mem-use data 56 total) (logand -16 (+ v1-27 15))) + ) + + ;; add the visible list + (set! (-> mem-use length) (max 60 (-> mem-use length))) + (set! (-> mem-use data 59 name) "bsp-leaf-vis-self") + (+! (-> mem-use data 59 count) 1) + (let ((v1-36 (-> obj visible-list-length))) + (+! (-> mem-use data 59 used) v1-36) + (+! (-> mem-use data 59 total) (logand -16 (+ v1-36 15))) + ) + + ;; add the unk-data-0 + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-46 (* (-> obj texture-remap-table-len) 8))) + (+! (-> mem-use data 57 used) v1-46) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-46 15))) + ) + + ;; add the unk-data-1 + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-56 (* (-> obj unk-data-1-len) 4))) + (+! (-> mem-use data 57 used) v1-56) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-56 15))) + ) + + ;; add unk-zero-0 + (when (nonzero? (-> obj unk-zero-0)) + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-68 (asize-of (-> obj unk-zero-0)))) + (+! (-> mem-use data 57 used) v1-68) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-68 15))) + ) + ) + + ;; add adgifs + (when (nonzero? (-> obj adgifs)) + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-80 (asize-of (-> obj adgifs)))) + (+! (-> mem-use data 57 used) v1-80) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-80 15))) + ) + ) + + ;; add boxes + (when (nonzero? (-> obj boxes)) + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-92 (asize-of (-> obj boxes)))) + (+! (-> mem-use data 57 used) v1-92) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-92 15))) + ) + ;; add unk-data-7 (reloated to boxes?) + (when (nonzero? (-> obj unk-data-7)) + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-105 (* (-> obj boxes length) 2))) + (+! (-> mem-use data 57 used) v1-105) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-105 15))) + ) + ) + ) + + ;; add unk-data-6 + (when (nonzero? (-> obj unk-data-6)) + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + + ;; add actors + (let ((v1-118 (* (-> obj actors length) 4))) + (+! (-> mem-use data 57 used) v1-118) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-118 15))) + ) + ) + + ;; add pat + (+! (-> mem-use data 62 count) (-> obj pat-length)) + (let ((v1-125 (* (-> obj pat-length) 4))) + (+! (-> mem-use data 62 used) v1-125) + (+! (-> mem-use data 62 total) (logand -16 (+ v1-125 15))) + ) + + ;; add cameras + (let ((s3-0 (-> obj cameras))) + (when (nonzero? s3-0) + (dotimes (s2-0 (-> s3-0 length)) + (mem-usage (-> s3-0 s2-0) mem-use (logior flags 256)) + ) + ) + ) + + ;; add the tree itself + (mem-usage-bsp-tree obj (the-as bsp-node (-> obj nodes)) mem-use flags) + obj + ) + + +(defmethod login bsp-header ((obj bsp-header)) + "Main login for a level" + ;; login our drawables + (if (nonzero? (-> obj drawable-trees)) + (login (-> obj drawable-trees)) + ) + + ;; login our shaders + (when (nonzero? (-> obj adgifs)) + (let ((s5-0 (-> obj adgifs))) + (dotimes (s4-0 (-> s5-0 length)) + (adgif-shader-login-no-remap (-> s5-0 data s4-0)) + ) + ) + ) + obj + ) + +(define *test-shrub* 0) ;; unused. + +(defmethod draw bsp-header ((obj bsp-header) (other-draw drawable) (disp-frame display-frame)) + "Draw the level" + (local-vars (a3-4 uint128) (a3-5 uint128) (r0 uint128)) + (set! r0 (the-as uint128 0)) + (let ((lev (-> obj level))) + ;; set up some stuff in the scratchpad + (set! (-> (scratchpad-object terrain-bsp :offset TERRAIN_BSP_SCRATCHPAD) lev-index) (-> lev index)) + (set! (-> (scratchpad-object terrain-bsp :offset TERRAIN_BSP_SCRATCHPAD) mood) (-> lev mood)) + + ;; update the subdivision settings + (if *artist-use-menu-subdiv* + (update-subdivide-settings! *subdivide-settings* *math-camera* 3) + (update-subdivide-settings! *subdivide-settings* *math-camera* (-> lev index)) + ) + + ;; at this point we are no longer adding textures, so we can mark the end of the + ;; textures with interrupts to get rendering VIF interrupts for profiling. + (add-irq-to-tex-buckets! lev) + + ;; upload the visible list to the scratchpad. + ;; this goes at the end of the scratchpad. + (let ((vis-list-qwc (/ (+ (-> obj visible-list-length) 15) 16))) + (dma-send-to-spr-no-flush + (scratchpad-object uint :offset VISIBLE_LIST_SCRATCHPAD) + (the-as uint (-> lev vis-bits)) + (the-as uint vis-list-qwc) + #f + ) + ) + ) + + ;; this is a race condition with the previous DMA transfer. + ;; probably the DMA wins though. + ;; this messes with the visibility bits to invert what was just uploaded + (when *artist-flip-visible* + (let ((vis-list-qwc2 (/ (+ (-> obj visible-list-length) 15) 16)) + (vis-list-spad (scratchpad-object (pointer uint128) :offset VISIBLE_LIST_SCRATCHPAD)) + (vis-list-lev (the-as (pointer uint128) (-> obj all-visible-list))) + ) + ;; iterate through all qw's in the visible list. + (dotimes (current-qw vis-list-qwc2) + ;; invert the stuff in the spad list + (let ((a3-3 (-> vis-list-spad current-qw))) + ;; note: this isn't great x86 code, but it's probably fine. + (.pnor a3-4 a3-3 r0) + ) + ;; and with the all visible list so we don't + ;; accidentally turn on the vis bit for something that + ;; doesn't exist. + (let ((t0-2 (-> vis-list-lev current-qw))) + (.pand a3-5 a3-4 t0-2) + ) + (set! (-> vis-list-spad current-qw) a3-5) + ) + ) + ) + + ;; set up the math camera registers + (let ((at-0 *math-camera*)) + (with-vf (vf16 vf17 vf18 vf19 vf20 vf21 vf22 vf23 vf24 vf25 vf26 vf27 vf28 vf29 vf30 vf31) + :rw 'write + (.lvf vf16 (&-> at-0 plane 0)) + (.lvf vf17 (&-> at-0 plane 1)) + (.lvf vf18 (&-> at-0 plane 2)) + (.lvf vf19 (&-> at-0 plane 3)) + (.lvf vf20 (&-> at-0 shrub-mat vector 0 quad)) + (.lvf vf21 (&-> at-0 shrub-mat vector 1 quad)) + (.lvf vf22 (&-> at-0 shrub-mat vector 2 quad)) + (.lvf vf23 (&-> at-0 shrub-mat vector 3 quad)) + (.lvf vf24 (&-> at-0 camera-rot vector 0 quad)) + (.lvf vf25 (&-> at-0 camera-rot vector 1 quad)) + (.lvf vf26 (&-> at-0 camera-rot vector 2 quad)) + (.lvf vf27 (&-> at-0 camera-rot vector 3 quad)) + (.lvf vf28 (&-> at-0 camera-temp vector 0 quad)) + (.lvf vf29 (&-> at-0 camera-temp vector 1 quad)) + (.lvf vf30 (&-> at-0 camera-temp vector 2 quad)) + (.lvf vf31 (&-> at-0 camera-temp vector 3 quad)) + ) + ) + + ;; draw the drawables! + ;; start a profile bar. + (when (nonzero? (-> obj drawable-trees)) + (if *debug-segment* + (add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x40 :b #x40 :a #x80) + ) + ) + ;; draw! + (let ((a1-7 (-> obj drawable-trees))) + (draw a1-7 a1-7 disp-frame) + ) + ;; end a profile bar + (if *debug-segment* + (add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x80 :g #xc0 :a #x80) + ) + ) + ) + + ;; run the foreground system + (let ((s5-1 (-> *display* frames (-> *display* on-screen) frame))) + ;; 0 + (foreground-engine-execute + (-> obj level foreground-draw-engine 0) + s5-1 + (-> (scratchpad-object terrain-bsp :offset TERRAIN_BSP_SCRATCHPAD) lev-index) + 0 + ) + ;; 1 + (foreground-engine-execute + (-> obj level foreground-draw-engine 1) + s5-1 + (-> (scratchpad-object terrain-bsp :offset TERRAIN_BSP_SCRATCHPAD) lev-index) + 1 + ) + + ;; 2 + (foreground-engine-execute + (-> obj level foreground-draw-engine 2) + s5-1 + (-> (scratchpad-object terrain-bsp :offset TERRAIN_BSP_SCRATCHPAD) lev-index) + 2 + ) + ) + (none) + ) + +(defmethod dummy-15 bsp-header ((obj bsp-header) (arg0 object) (arg1 object)) + "This is some sort of debugging thing. It calls dummy-15 on the drawables + with the scratchpad and vfs set up." + (let ((s4-0 (-> obj level))) + ;; set up some stuff in the scratchpad + (set! (-> (scratchpad-object terrain-bsp :offset TERRAIN_BSP_SCRATCHPAD) lev-index) (-> s4-0 index)) + (set! (-> (scratchpad-object terrain-bsp :offset TERRAIN_BSP_SCRATCHPAD) mood) (-> s4-0 mood)) + (add-irq-to-tex-buckets! s4-0) + (let ((a2-1 (/ (+ (-> obj visible-list-length) 15) 16))) + (dma-send-to-spr-no-flush + (scratchpad-object uint :offset VISIBLE_LIST_SCRATCHPAD) + (the-as uint (-> s4-0 vis-bits)) + (the-as uint a2-1) + #f + ) + ) + ) + (let ((at-0 *math-camera*)) + (with-vf (vf16 vf17 vf18 vf19 vf20 vf21 vf22 vf23 vf24 vf25 vf26 vf27 vf28 vf29 vf30 vf31) + :rw 'write + (.lvf vf16 (&-> at-0 plane 0)) + (.lvf vf17 (&-> at-0 plane 1)) + (.lvf vf18 (&-> at-0 plane 2)) + (.lvf vf19 (&-> at-0 plane 3)) + (.lvf vf20 (&-> at-0 shrub-mat vector 0 quad)) + (.lvf vf21 (&-> at-0 shrub-mat vector 1 quad)) + (.lvf vf22 (&-> at-0 shrub-mat vector 2 quad)) + (.lvf vf23 (&-> at-0 shrub-mat vector 3 quad)) + (.lvf vf24 (&-> at-0 camera-rot vector 0 quad)) + (.lvf vf25 (&-> at-0 camera-rot vector 1 quad)) + (.lvf vf26 (&-> at-0 camera-rot vector 2 quad)) + (.lvf vf27 (&-> at-0 camera-rot vector 3 quad)) + (.lvf vf28 (&-> at-0 camera-temp vector 0 quad)) + (.lvf vf29 (&-> at-0 camera-temp vector 1 quad)) + (.lvf vf30 (&-> at-0 camera-temp vector 2 quad)) + (.lvf vf31 (&-> at-0 camera-temp vector 3 quad)) + ) + ) + (when (nonzero? (-> obj drawable-trees)) + (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 ((a1-3 (-> obj drawable-trees))) + (dummy-15 a1-3 a1-3 arg1) + ) + (if *debug-segment* + (add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x80 :g #xc0 :a #x80) + ) + ) + ) + (none) + ) + +(defmethod dummy-14 bsp-header ((obj bsp-header)) + "Also some sort of debug thing. + Calls dummy-14 on children with visible list and vfs set up + but no terrain-bsp" + (let ((v1-0 (-> obj level)) + (a2-0 (/ (+ (-> obj visible-list-length) 15) 16)) + ) + (dma-send-to-spr-no-flush + (scratchpad-object uint :offset VISIBLE_LIST_SCRATCHPAD) + (the-as uint (-> v1-0 vis-bits)) + (the-as uint a2-0) + #f + ) + ) + (let ((at-0 *math-camera*)) + (with-vf (vf16 vf17 vf18 vf19 vf20 vf21 vf22 vf23 vf24 vf25 vf26 vf27 vf28 vf29 vf30 vf31) + :rw 'write + (.lvf vf16 (&-> at-0 plane 0)) + (.lvf vf17 (&-> at-0 plane 1)) + (.lvf vf18 (&-> at-0 plane 2)) + (.lvf vf19 (&-> at-0 plane 3)) + (.lvf vf20 (&-> at-0 shrub-mat vector 0 quad)) + (.lvf vf21 (&-> at-0 shrub-mat vector 1 quad)) + (.lvf vf22 (&-> at-0 shrub-mat vector 2 quad)) + (.lvf vf23 (&-> at-0 shrub-mat vector 3 quad)) + (.lvf vf24 (&-> at-0 camera-rot vector 0 quad)) + (.lvf vf25 (&-> at-0 camera-rot vector 1 quad)) + (.lvf vf26 (&-> at-0 camera-rot vector 2 quad)) + (.lvf vf27 (&-> at-0 camera-rot vector 3 quad)) + (.lvf vf28 (&-> at-0 camera-temp vector 0 quad)) + (.lvf vf29 (&-> at-0 camera-temp vector 1 quad)) + (.lvf vf30 (&-> at-0 camera-temp vector 2 quad)) + (.lvf vf31 (&-> at-0 camera-temp vector 3 quad)) + ) + ) + (if (nonzero? (-> obj drawable-trees)) + (dummy-14 (-> obj drawable-trees)) + ) + (none) + ) + +(defun bsp-camera-asm ((bsp-hdr bsp-header) (camera-pos vector)) + "Look up the camera position in the bsp tree. + The result is stored in the bsp-hdr current-leaf-idx" + (local-vars (v1-1 int) (real-node bsp-node)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (nop!) + ;; next-node contains the node (or child) that we will check next. + (let ((next-node (the-as bsp-node (-> bsp-hdr nodes)))) + ;; vf1 = camera position always + (.lvf vf1 (&-> camera-pos quad)) + ;; top of loop that traverses the tree + (label cfg-1) + ;; branch if twe got a child + (b! (< (the-as int next-node) 0) cfg-4 :delay (set! real-node next-node)) + + ;; load the plane + (.lvf vf2 (&-> real-node plane quad)) + ;; elementwise multiply xyz + (.mul.vf vf2 vf2 vf1 :mask #b111) + ;; then horizontal sum, putting result in y. + (.add.x.vf vf2 vf2 vf2 :mask #b10) + (.add.z.vf vf2 vf2 vf2 :mask #b10) + (.sub.w.vf vf2 vf2 vf2 :mask #b10) + ;; move the result into v1-1. + ;; the sign bit of float y is now the sign bit of the int v1-1 + (.mov v1-1 vf2) + (let ((a2-0 (-> real-node front-flags))) + ;; branch to loop top, if we haven't gotten to the bottom + (b! (>= (the-as int v1-1) 0) + cfg-1 + ;; in the dealy slot, advance the node + :delay (set! next-node (the-as bsp-node (-> real-node front))) + ) + ;; otherwise, we are on the back side. + (set! a2-0 (-> real-node back-flags)) + (b! #t cfg-1 :delay (set! next-node (the-as bsp-node (-> real-node back)))) + + ;; here we got a child. + (label cfg-4) + (set! (-> bsp-hdr current-leaf-idx) (the-as uint next-node)) + ;; back flags is a bit confusing name. + ;; it's actually the flags for whatever side we are on of the + ;; lowest node. + (set! (-> bsp-hdr current-bsp-back-flags) a2-0) + ) + ) + 0 + (none) + ) + ) + +;;;;;;;;;;;;;;; +;; Collision +;;;;;;;;;;;;;;; + +(defmethod dummy-11 bsp-header ((obj bsp-header) (arg0 int) (arg1 object)) + (+! (-> *collide-stats* calls) 1) + (let ((s4-0 (-> obj drawable-trees))) + (dotimes (s3-0 (-> s4-0 length)) + (dummy-11 (-> s4-0 data s3-0) arg0 arg1) + ) + ) + (none) + ) + +(defmethod dummy-12 bsp-header ((obj bsp-header) (arg0 int) (arg1 object)) + (+! (-> *collide-stats* calls) 1) + (let ((s4-0 (-> obj drawable-trees))) + (dotimes (s3-0 (-> s4-0 length)) + (dummy-12 (-> s4-0 data s3-0) arg0 arg1) + ) + ) + (none) + ) + +(defmethod dummy-13 bsp-header ((obj bsp-header) (arg0 int) (arg1 object)) + (+! (-> *collide-stats* calls) 1) + (let ((s4-0 (-> obj drawable-trees))) + (dotimes (s3-0 (-> s4-0 length)) + (dummy-13 (-> s4-0 data s3-0) arg0 arg1) + ) + ) + (none) + ) + +(defmethod dummy-17 bsp-header ((obj bsp-header) (arg0 sphere) (arg1 int) (arg2 ambient-list)) + (let ((s3-0 (-> obj drawable-trees))) + (dotimes (s2-0 (-> s3-0 length)) + (dummy-17 (-> s3-0 data s2-0) arg0 arg1 arg2) + ) + ) + (none) + ) + +(defun clear-cl-stat ((arg0 cl-stat)) + "Reset stats" + (set! (-> arg0 fragments) (the-as uint 0)) + (set! (-> arg0 tris) (the-as uint 0)) + (set! (-> arg0 output) (the-as uint 0)) + 0 + (none) + ) + +(defun print-cl-stat ((arg0 cl-stat) (arg1 string)) + "Print stats for arg1" + (when (nonzero? (+ (-> arg0 fragments) (-> arg0 tris))) + (format + *stdcon* + "~0k~5d/~d ~6d/~d ~6d/~d " + (-> arg0 fragments) + (/ (-> arg0 fragments) (-> *collide-stats* calls)) + (-> arg0 tris) + (/ (-> arg0 tris) (-> *collide-stats* calls)) + (-> arg0 output) + (/ (-> arg0 output) (-> *collide-stats* calls)) + ) + (format *stdcon* "~0k~s~%" arg1) + (+! (-> *collide-stats* total fragments) (-> arg0 fragments)) + (+! (-> *collide-stats* total tris) (-> arg0 tris)) + (+! (-> *collide-stats* total output) (-> arg0 output)) + ) + (none) + ) + +(defun print-collide-stats () + "Print and reset collide stats for this frame" + ;; for some unknown reason, we profile this. + (if *debug-segment* + (add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x40 :b #x40 :a #x80) + ) + ) + (format *stdcon* "~0k frags tris output~%") + (print-cl-stat (-> *collide-stats* other) "other") + (format *stdcon* "~0k---------------------------------------------------------------~%") + (print-cl-stat (-> *collide-stats* total) "total") + (format *stdcon* "~0kcalls = ~d~%" (-> *collide-stats* calls)) + + ;; figure out how long we spent in each + (let ((gp-0 (stopwatch-elapsed-ticks (-> *collide-stats* total-target))) + (s4-0 (stopwatch-elapsed-ticks (-> *collide-stats* target-cache-fill))) + (s5-0 (stopwatch-elapsed-ticks (-> *collide-stats* target-ray-poly))) + ) + (format *stdcon* "~0ktotal-target ~D~%" gp-0) + ;; these can divide by zero if it doesn't run. + (format *stdcon* "~0ktarget-cache-fill ~D ~0,,2f%~%" + s4-0 + (/ (* 100.0 (the float s4-0)) (the float gp-0)) + ) + (format *stdcon* "~0ktarget-ray-poly ~D ~0,,2f%~%" + s5-0 + (/ (* 100.0 (the float s5-0)) (the float gp-0)) + ) + ) + ;; reset + (clear-cl-stat (-> *collide-stats* other)) + (clear-cl-stat (-> *collide-stats* total)) + (set! *collide-nodes* 0) + (set! (-> *collide-stats* calls) (the-as uint 0)) + (stopwatch-init (-> *collide-stats* total-target)) + (stopwatch-init (-> *collide-stats* target-cache-fill)) + (stopwatch-init (-> *collide-stats* target-ray-poly)) + (if *debug-segment* + (add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :b #xff :a #x80) + ) + ) + 0 + (none) + ) + +(defun level-remap-texture ((tex-id texture-id)) + "Levels can request textures to be remapped during login" + (let ((bsp-hdr (-> *level* log-in-level-bsp))) + (when bsp-hdr + (let* ((table-size (-> bsp-hdr texture-remap-table-len)) ;; in 64-bit entries + (table-data-start (-> bsp-hdr texture-remap-table)) + (table-data-ptr table-data-start) + (mask1 (the-as uint #xfffffff8)) ;; mask for table entry addresses + (masked-tex-id (logand (the-as uint #xffffff00) tex-id)) ;; bits of tex-id we care about + (table-data-end (&+ table-data-ptr (* table-size 8))) + ) + ;; top of binary search + (label cfg-2) + ;; if we didn't find anything, quit + (b! (= table-data-start table-data-end) cfg-8) + + ;; find the middle entry. + (let ((midpoint (logand (/ (+ (the-as int table-data-start) (the-as int table-data-end)) 2) + mask1 + ) + ) + ) + ;; how did we do? + (let ((diff (- (-> (the-as (pointer int32) midpoint) 0) (the-as int masked-tex-id)))) + (b! (zero? diff) cfg-7) + (b! (< diff 0) cfg-6 :delay (nop!)) + ) + ;; in the lower section + (b! #t cfg-2 + :delay + (set! table-data-end (the-as (pointer uint64) midpoint)) + ) + + ;; in the upper section (not including the midpoint) + (label cfg-6) + (b! #t cfg-2 + :delay + (set! table-data-start (the-as (pointer uint64) (+ (the-as int midpoint) 8))) + ) + + ;; exact match + (label cfg-7) + ;; not sure what this logior with 20 is about. + (set! tex-id + (the-as texture-id (logior (-> (the-as (pointer int32) midpoint) 1) 20)) + ) + ) + ) + (label cfg-8) + 0 + ) + ) + (the-as texture-id tex-id) + ) + diff --git a/goal_src/engine/level/level-h.gc b/goal_src/engine/level/level-h.gc index b90367860a..08ffaf053a 100644 --- a/goal_src/engine/level/level-h.gc +++ b/goal_src/engine/level/level-h.gc @@ -176,25 +176,25 @@ ;; don't belong to any level, for example to render Jak. (declare-type entity-links structure) (deftype level-group (basic) - ((length int32 :offset-assert 4) - (log-in-level level :offset-assert 8) ;; level currently logging in - (loading-level level :offset-assert 12) ;; currently loading - (entity-link entity-links :offset-assert 16) ;; not sure what's going on here - (border? basic :offset-assert 20) - (vis? basic :offset-assert 24) - (want-level basic :offset-assert 28) - (receiving-level basic :offset-assert 32) - (load-commands pair :offset-assert 36) - (play? symbol :offset-assert 40) + ((length int32 :offset-assert 4) + (log-in-level-bsp bsp-header :offset-assert 8) ;; level currently logging in + (loading-level level :offset-assert 12) ;; currently loading + (entity-link entity-links :offset-assert 16) ;; not sure what's going on here + (border? basic :offset-assert 20) + (vis? basic :offset-assert 24) + (want-level basic :offset-assert 28) + (receiving-level basic :offset-assert 32) + (load-commands pair :offset-assert 36) + (play? symbol :offset-assert 40) ;; there's something? from 40 -> 96. (_hack-pad uint8 :offset 90) - (level0 level :inline :offset-assert 96) - (level1 level :inline :offset-assert 2704) - (level-default level :inline :offset-assert 5312) + (level0 level :inline :offset-assert 96) + (level1 level :inline :offset-assert 2704) + (level-default level :inline :offset-assert 5312) ;; this actually went earlier, - (level level 3 :inline :offset 96) + (level level 3 :inline :offset 96) ;; and this one too. why another one? - (data level 3 :score -1 :inline :offset 96) + (data level 3 :score -1 :inline :offset 96) (pad uint32) ) :method-count-assert 27 @@ -232,7 +232,7 @@ (set! *level* (new 'static 'level-group :length 2 - :log-in-level #f + :log-in-level-bsp #f :loading-level #f :entity-link #f :border? #f diff --git a/goal_src/engine/level/level.gc b/goal_src/engine/level/level.gc index 9685ee64e3..b99c68e8c8 100644 --- a/goal_src/engine/level/level.gc +++ b/goal_src/engine/level/level.gc @@ -456,7 +456,7 @@ (set! loading-level (-> obj heap)) (set! (-> *level* loading-level) obj) - (set! (-> *level* log-in-level) #f) + (set! (-> *level* log-in-level-bsp) #f) (set! (-> obj nickname) #f) (set! (-> obj bsp) #f) (set! (-> obj entity) #f) @@ -487,7 +487,7 @@ (set! (-> *texture-pool* allocate-func) texture-page-default-allocate) (cond ((-> obj bsp) - (set! (-> *level* log-in-level) (the-as level (-> obj bsp))) + (set! (-> *level* log-in-level-bsp) (-> obj bsp)) ;; TODO ;;(login-level-textures *texture-pool* obj (-> obj bsp unk-data-1-len) (the-as (pointer texture-id) (-> obj bsp unk-data-1))) (let ((bsp (-> obj bsp))) @@ -702,7 +702,7 @@ (set! (-> loaded-level status) 'loaded) (set! loading-level global) (set! (-> *level* loading-level) (-> *level* level-default)) - (set! (-> *level* log-in-level) #f) + (set! (-> *level* log-in-level-bsp) #f) 0 ;;(.mfc0 v1-154 Count) ;;(- v1-154 initial-timer) @@ -717,10 +717,10 @@ (('loaded) (protect (loading-level (-> *level* loading-level) - (-> *level* log-in-level) + (-> *level* log-in-level-bsp) ) (set! loading-level (-> obj heap)) - (set! (-> *level* log-in-level) (the-as level (-> obj bsp))) + (set! (-> *level* log-in-level-bsp) (-> obj bsp)) (set! (-> *level* loading-level) obj) ;; (dummy-18 (-> obj bsp)) TODO (set! (-> obj status) 'alive) @@ -767,8 +767,8 @@ ) ) ) - (if (= (-> *level* log-in-level) (-> obj bsp)) - (set! (-> *level* log-in-level) #f) + (if (= (-> *level* log-in-level-bsp) (-> obj bsp)) + (set! (-> *level* log-in-level-bsp) #f) ) obj ) @@ -852,7 +852,7 @@ (when (= (-> *level* loading-level) obj) (set! loading-level global) (set! (-> *level* loading-level) (-> *level* level-default)) - (set! (-> *level* log-in-level) #f) + (set! (-> *level* log-in-level-bsp) #f) ) ) obj diff --git a/goal_src/engine/math/vector-h.gc b/goal_src/engine/math/vector-h.gc index e714d1f609..a07c9d864e 100644 --- a/goal_src/engine/math/vector-h.gc +++ b/goal_src/engine/math/vector-h.gc @@ -411,6 +411,7 @@ (set! (-> box8s-array heap-base) 32) +;; This is really a capsule - a cylinder with spheres at both end (deftype cylinder (structure) ((origin vector :inline :offset-assert 0) (axis vector :inline :offset-assert 16) @@ -421,12 +422,12 @@ :size-assert #x28 :flag-assert #xb00000028 (:methods - (TODO-RENAME-HUGE-9 (_type_ vector) none 9) - (TODO-RENAME-10 (_type_ vector vector) float 10) - ) + (debug-draw (_type_ vector) none 9) + (ray-capsule-intersect (_type_ vector vector) float 10) + ) ) -;; definition of type cylinder-flat +;; This is a normal cylinder. (deftype cylinder-flat (structure) ((origin vector :inline :offset-assert 0) (axis vector :inline :offset-assert 16) @@ -437,9 +438,9 @@ :size-assert #x28 :flag-assert #xb00000028 (:methods - (TODO-RENAME-HUGE-9 (_type_ vector) none 9) - (TODO-RENAME-10 (_type_ vector vector) float 10) - ) + (debug-draw (_type_ vector) none 9) + (ray-flat-cyl-intersect (_type_ vector vector) float 10) + ) ) (deftype vertical-planes (structure) diff --git a/goal_src/kernel/gcommon.gc b/goal_src/kernel/gcommon.gc index 887bc96234..60a0afcf27 100644 --- a/goal_src/kernel/gcommon.gc +++ b/goal_src/kernel/gcommon.gc @@ -1070,7 +1070,7 @@ (defun quad-copy! ((dst pointer) (src pointer) (qwc int)) "Optimized memory copy. The original is pretty clever, but this isn't." (qmem-copy<-! dst src (* qwc 16)) - 0 + (none) ) (defun-recursive fact int ((x int)) diff --git a/goal_src/kernel/gkernel-h.gc b/goal_src/kernel/gkernel-h.gc index 8d39dd56d9..623b9e9618 100644 --- a/goal_src/kernel/gkernel-h.gc +++ b/goal_src/kernel/gkernel-h.gc @@ -589,3 +589,8 @@ `(rlet ((sp :reg rsp :reset-here #t :type pointer)) ,@body) ) + +(defmacro scratchpad-object (type &key (offset 0)) + "Access an object on the scratchpad." + `(the-as ,type (&+ *fake-scratchpad-data* ,offset)) + ) \ No newline at end of file diff --git a/goal_src/kernel/gkernel.gc b/goal_src/kernel/gkernel.gc index 9e2535c178..1fac1b5bf8 100644 --- a/goal_src/kernel/gkernel.gc +++ b/goal_src/kernel/gkernel.gc @@ -122,6 +122,10 @@ ;; it might be possible to also throw them on the *dram-stack*, but they might depend on these ;; not overlapping. We can spare the 16k of memory. (define *fake-scratchpad-stack* (new 'global 'array 'uint8 (* 16 1024))) + + ;; similar thing for the scratchpad data. + ;; in + (define *fake-scratchpad-data* (new 'global 'array 'uint8 (* 16 1024))) ) diff --git a/goalc/compiler/Compiler.h b/goalc/compiler/Compiler.h index cc58e00790..80f64e15ca 100644 --- a/goalc/compiler/Compiler.h +++ b/goalc/compiler/Compiler.h @@ -465,6 +465,9 @@ class Compiler { Val* compile_asm_ppach(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_asm_psubw(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_asm_xorp(const goos::Object& form, const goos::Object& rest, Env* env); + Val* compile_asm_por(const goos::Object& form, const goos::Object& rest, Env* env); + Val* compile_asm_pnor(const goos::Object& form, const goos::Object& rest, Env* env); + Val* compile_asm_pand(const goos::Object& form, const goos::Object& rest, Env* env); // Atoms diff --git a/goalc/compiler/IR.cpp b/goalc/compiler/IR.cpp index 2eec597041..b5ec399bf0 100644 --- a/goalc/compiler/IR.cpp +++ b/goalc/compiler/IR.cpp @@ -1536,6 +1536,15 @@ std::string IR_Int128Math3Asm::print() { case Kind::PSUBW: function = ".psubw"; break; + case Kind::POR: + function = ".por"; + break; + case Kind::PXOR: + function = ".pxor"; + break; + case Kind::PAND: + function = ".pand"; + break; default: assert(false); } @@ -1583,6 +1592,15 @@ void IR_Int128Math3Asm::do_codegen(emitter::ObjectGenerator* gen, // psubW on mips is psubD on x86... gen->add_instr(IGen::vpsubd(dst, src1, src2), irec); break; + case Kind::POR: + gen->add_instr(IGen::parallel_bitwise_or(dst, src2, src1), irec); + break; + case Kind::PXOR: + gen->add_instr(IGen::parallel_bitwise_xor(dst, src2, src1), irec); + break; + case Kind::PAND: + gen->add_instr(IGen::parallel_bitwise_and(dst, src2, src1), irec); + break; default: assert(false); } diff --git a/goalc/compiler/IR.h b/goalc/compiler/IR.h index eaa99a7937..de627d5f11 100644 --- a/goalc/compiler/IR.h +++ b/goalc/compiler/IR.h @@ -562,7 +562,7 @@ class IR_VFMath3Asm : public IR_Asm { class IR_Int128Math3Asm : public IR_Asm { public: // these are MIPS names, not x86 names. - enum class Kind { PEXTLW, PEXTUW, PCPYUD, PCPYLD, PCEQW, PSUBW }; + enum class Kind { PEXTLW, PEXTUW, PCPYUD, PCPYLD, PCEQW, PSUBW, POR, PXOR, PAND }; IR_Int128Math3Asm(bool use_color, const RegVal* dst, const RegVal* src1, diff --git a/goalc/compiler/compilation/Asm.cpp b/goalc/compiler/compilation/Asm.cpp index 8d3da868f2..6f76fc66f8 100644 --- a/goalc/compiler/compilation/Asm.cpp +++ b/goalc/compiler/compilation/Asm.cpp @@ -634,6 +634,58 @@ Val* Compiler::compile_asm_pw_sra(const goos::Object& form, const goos::Object& return compile_asm_int128_math2_imm_u8(form, rest, IR_Int128Math2Asm::Kind::PW_SRA, env); } +Val* Compiler::compile_asm_por(const goos::Object& form, const goos::Object& rest, Env* env) { + return compile_asm_int128_math3(form, rest, IR_Int128Math3Asm::Kind::POR, env); +} + +bool ireg_is_128_ok(const IRegister& ireg) { + return ireg.reg_class == RegClass::VECTOR_FLOAT || ireg.reg_class == RegClass::INT_128; +} + +Val* Compiler::compile_asm_pnor(const goos::Object& form, const goos::Object& rest, Env* env) { + auto args = get_va(form, rest); + va_check(form, args, {{}, {}, {}}, {}); + + auto dest = compile_error_guard(args.unnamed.at(0), env)->to_reg(env); + auto src1 = compile_error_guard(args.unnamed.at(1), env)->to_reg(env); // rs + auto src2 = compile_error_guard(args.unnamed.at(2), env)->to_reg(env); // rt + auto temp = env->make_ireg(TypeSpec("uint128"), RegClass::INT_128); + + if (!ireg_is_128_ok(dest->ireg())) { + throw_compiler_error(args.unnamed.at(0), "bad destination register kind"); + } + if (!ireg_is_128_ok(src1->ireg())) { + throw_compiler_error(args.unnamed.at(1), "bad src1 register kind"); + } + if (!ireg_is_128_ok(src2->ireg())) { + throw_compiler_error(args.unnamed.at(2), "bad src2 register kind"); + } + + if (!dest->settable()) { + throw_compiler_error(form, "Cannot set destination"); + } + + // A NOR is equivalent to an inverted input AND + // Use the destination register and a temp register. + // There is also no PNOT instruction, so the easiest way to is to XOR with an all-ones register + // Remember - we do not want to mutate the source registers! + + // How do we create an all-ones-register? Compare it with itself + env->emit_ir(true, temp, temp, temp, IR_Int128Math3Asm::Kind::PCEQW); + // Then NOT the first input, store in destination + env->emit_ir(true, dest, temp, src1, IR_Int128Math3Asm::Kind::PXOR); + // NOT the second input, we not longer require the all-ones-register + env->emit_ir(true, temp, temp, src2, IR_Int128Math3Asm::Kind::PXOR); + // Preform the AND aka NOR + env->emit_ir(true, dest, dest, temp, IR_Int128Math3Asm::Kind::PAND); + + return get_none(); +} + +Val* Compiler::compile_asm_pand(const goos::Object& form, const goos::Object& rest, Env* env) { + return compile_asm_int128_math3(form, rest, IR_Int128Math3Asm::Kind::PAND, env); +} + Val* Compiler::compile_asm_pextlw(const goos::Object& form, const goos::Object& rest, Env* env) { return compile_asm_int128_math3(form, rest, IR_Int128Math3Asm::Kind::PEXTLW, env); } diff --git a/goalc/compiler/compilation/Atoms.cpp b/goalc/compiler/compilation/Atoms.cpp index 611cc663bb..7c2d9498f5 100644 --- a/goalc/compiler/compilation/Atoms.cpp +++ b/goalc/compiler/compilation/Atoms.cpp @@ -104,6 +104,10 @@ const std::unordered_map< {".ppach", &Compiler::compile_asm_ppach}, {".psubw", &Compiler::compile_asm_psubw}, + {".por", &Compiler::compile_asm_por}, + {".pnor", &Compiler::compile_asm_pnor}, + {".pand", &Compiler::compile_asm_pand}, + // BLOCK FORMS {"top-level", &Compiler::compile_top_level}, {"begin", &Compiler::compile_begin}, diff --git a/goalc/emitter/IGen.h b/goalc/emitter/IGen.h index b837f98f33..cedde7698d 100644 --- a/goalc/emitter/IGen.h +++ b/goalc/emitter/IGen.h @@ -1,8 +1,5 @@ #pragma once -#ifndef JAK_IGEN_H -#define JAK_IGEN_H - #include "common/util/assert.h" #include "Register.h" #include "Instruction.h" @@ -2555,7 +2552,41 @@ class IGen { instr.set(Imm(1, imm)); return instr; } + + static Instruction parallel_bitwise_or(Register dst, Register src0, Register src1) { + assert(dst.is_xmm()); + assert(src0.is_xmm()); + assert(src1.is_xmm()); + // VEX.128.66.0F.WIG EB /r VPOR xmm1, xmm2, xmm3/m128 + // reg, vex, r/m + Instruction instr(0xEB); + instr.set_vex_modrm_and_rex(dst.hw_id(), src1.hw_id(), VEX3::LeadingBytes::P_0F, src0.hw_id(), + false, VexPrefix::P_66); + return instr; + } + + static Instruction parallel_bitwise_xor(Register dst, Register src0, Register src1) { + assert(dst.is_xmm()); + assert(src0.is_xmm()); + assert(src1.is_xmm()); + // VEX.128.66.0F.WIG EF /r VPXOR xmm1, xmm2, xmm3/m128 + // reg, vex, r/m + Instruction instr(0xEF); + instr.set_vex_modrm_and_rex(dst.hw_id(), src1.hw_id(), VEX3::LeadingBytes::P_0F, src0.hw_id(), + false, VexPrefix::P_66); + return instr; + } + + static Instruction parallel_bitwise_and(Register dst, Register src0, Register src1) { + assert(dst.is_xmm()); + assert(src0.is_xmm()); + assert(src1.is_xmm()); + // VEX.128.66.0F.WIG DB /r VPAND xmm1, xmm2, xmm3/m128 + // reg, vex, r/m + Instruction instr(0xDB); + instr.set_vex_modrm_and_rex(dst.hw_id(), src1.hw_id(), VEX3::LeadingBytes::P_0F, src0.hw_id(), + false, VexPrefix::P_66); + return instr; + } }; } // namespace emitter - -#endif // JAK_IGEN_H diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f4fca65bc8..7b9035b34a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,6 +24,7 @@ add_executable(goalc-test ${CMAKE_CURRENT_LIST_DIR}/decompiler/test_FormBeforeExpressions.cpp ${CMAKE_CURRENT_LIST_DIR}/decompiler/test_FormExpressionBuild.cpp ${CMAKE_CURRENT_LIST_DIR}/decompiler/test_FormExpressionBuild2.cpp + ${CMAKE_CURRENT_LIST_DIR}/decompiler/test_FormExpressionBuild3.cpp ${CMAKE_CURRENT_LIST_DIR}/decompiler/test_FormExpressionBuildLong.cpp ${CMAKE_CURRENT_LIST_DIR}/decompiler/test_InstructionDecode.cpp ${CMAKE_CURRENT_LIST_DIR}/decompiler/test_InstructionParser.cpp diff --git a/test/decompiler/FormRegressionTest.cpp b/test/decompiler/FormRegressionTest.cpp index 4f960e4b94..6673a9248f 100644 --- a/test/decompiler/FormRegressionTest.cpp +++ b/test/decompiler/FormRegressionTest.cpp @@ -8,6 +8,7 @@ #include "decompiler/analysis/final_output.h" #include "decompiler/analysis/stack_spill.h" #include "decompiler/analysis/insert_lets.h" +#include "decompiler/analysis/inline_asm_rewrite.h" #include "decompiler/util/config_parsers.h" #include "common/goos/PrettyPrinter.h" #include "common/util/json_util.h" @@ -219,6 +220,10 @@ std::unique_ptr FormRegressionTest::make_function( if (!success) { return nullptr; } + + rewrite_inline_asm_instructions(test->func.ir2.top_form, *test->func.ir2.form_pool, + test->func, *dts); + // move variables into lets. insert_lets(test->func, test->func.ir2.env, *test->func.ir2.form_pool, test->func.ir2.top_form); diff --git a/test/decompiler/reference/engine/collide/collide-frag_REF.gc b/test/decompiler/reference/engine/collide/collide-frag_REF.gc index 9fa14a6fe6..3fbc0057d9 100644 --- a/test/decompiler/reference/engine/collide/collide-frag_REF.gc +++ b/test/decompiler/reference/engine/collide/collide-frag_REF.gc @@ -10,6 +10,7 @@ ) ;; definition for method 10 of type drawable-tree-collide-fragment +;; INFO: Return type mismatch int vs none. (defmethod draw drawable-tree-collide-fragment @@ -20,6 +21,7 @@ ) ) 0 + (none) ) ;; definition for method 16 of type drawable-tree-collide-fragment @@ -35,8 +37,8 @@ (defmethod dummy-11 drawable-tree-collide-fragment - ((obj drawable-tree-collide-fragment) (arg0 int)) - (dummy-11 (-> obj data 0) (-> obj length)) + ((obj drawable-tree-collide-fragment) (arg0 int) (arg1 object)) + (dummy-11 (-> obj data 0) (-> obj length) arg1) 0 (none) ) @@ -46,8 +48,8 @@ (defmethod dummy-12 drawable-tree-collide-fragment - ((obj drawable-tree-collide-fragment) (arg0 int)) - (dummy-12 (-> obj data 0) (-> obj length)) + ((obj drawable-tree-collide-fragment) (arg0 int) (arg1 object)) + (dummy-12 (-> obj data 0) (-> obj length) arg1) 0 (none) ) @@ -57,8 +59,8 @@ (defmethod dummy-13 drawable-tree-collide-fragment - ((obj drawable-tree-collide-fragment) (arg0 int)) - (dummy-13 (-> obj data 0) (-> obj length)) + ((obj drawable-tree-collide-fragment) (arg0 int) (arg1 object)) + (dummy-13 (-> obj data 0) (-> obj length) arg1) 0 (none) ) @@ -109,14 +111,17 @@ ) ;; definition for method 10 of type collide-fragment +;; INFO: Return type mismatch int vs none. (defmethod draw collide-fragment ((obj collide-fragment) (arg0 drawable) (arg1 display-frame)) 0 + (none) ) ;; definition for method 10 of type drawable-inline-array-collide-fragment +;; INFO: Return type mismatch int vs none. (defmethod draw drawable-inline-array-collide-fragment @@ -132,6 +137,7 @@ ) ) 0 + (none) ) ;; definition for method 11 of type drawable-inline-array-collide-fragment @@ -139,8 +145,8 @@ (defmethod dummy-11 drawable-inline-array-collide-fragment - ((obj drawable-inline-array-collide-fragment) (arg0 int)) - (dummy-11 (the-as collide-fragment (-> obj data)) (-> obj length)) + ((obj drawable-inline-array-collide-fragment) (arg0 int) (arg1 object)) + (dummy-11 (the-as collide-fragment (-> obj data)) (-> obj length) arg1) 0 (none) ) @@ -150,8 +156,8 @@ (defmethod dummy-12 drawable-inline-array-collide-fragment - ((obj drawable-inline-array-collide-fragment) (arg0 int)) - (dummy-12 (the-as collide-fragment (-> obj data)) (-> obj length)) + ((obj drawable-inline-array-collide-fragment) (arg0 int) (arg1 object)) + (dummy-12 (the-as collide-fragment (-> obj data)) (-> obj length) arg1) 0 (none) ) @@ -161,8 +167,8 @@ (defmethod dummy-13 drawable-inline-array-collide-fragment - ((obj drawable-inline-array-collide-fragment) (arg0 int)) - (dummy-13 (the-as collide-fragment (-> obj data)) (-> obj length)) + ((obj drawable-inline-array-collide-fragment) (arg0 int) (arg1 object)) + (dummy-13 (the-as collide-fragment (-> obj data)) (-> obj length) arg1) 0 (none) ) diff --git a/test/decompiler/reference/engine/data/res_REF.gc b/test/decompiler/reference/engine/data/res_REF.gc index 80821b697c..d3db036fbd 100644 --- a/test/decompiler/reference/engine/data/res_REF.gc +++ b/test/decompiler/reference/engine/data/res_REF.gc @@ -635,7 +635,7 @@ (set! (-> tag-addr 0) tag) ) (cond - ((type-type? tag-type uinteger) + ((type-type? (the-as type tag-type) uinteger) (case (-> tag elt-type size) ((1) (set! default (the-as uint128 (-> (the-as (pointer uint8) data)))) @@ -654,7 +654,7 @@ ) ) ) - ((type-type? tag-type integer) + ((type-type? (the-as type tag-type) integer) (case (-> tag elt-type size) ((1) (set! default (the-as uint128 (-> (the-as (pointer int8) data)))) @@ -673,7 +673,7 @@ ) ) ) - ((type-type? tag-type float) + ((type-type? (the-as type tag-type) float) (set! default (the-as uint128 (the int (-> (the-as (pointer float) data)))) @@ -719,10 +719,10 @@ (set! (-> tag-addr 0) tag) ) (cond - ((type-type? tag-type float) + ((type-type? (the-as type tag-type) float) (set! default (-> (the-as (pointer float) data))) ) - ((type-type? tag-type uinteger) + ((type-type? (the-as type tag-type) uinteger) (case (-> tag elt-type size) ((1) (set! v1-8 (-> (the-as (pointer uint8) data))) @@ -742,7 +742,7 @@ ) (set! default (the float v1-8)) ) - ((type-type? tag-type integer) + ((type-type? (the-as type tag-type) integer) (case (-> tag elt-type size) ((1) (set! v1-11 (-> (the-as (pointer int8) data))) diff --git a/test/decompiler/reference/engine/debug/stats-h_REF.gc b/test/decompiler/reference/engine/debug/stats-h_REF.gc index 5b8633a63c..1b02a011db 100644 --- a/test/decompiler/reference/engine/debug/stats-h_REF.gc +++ b/test/decompiler/reference/engine/debug/stats-h_REF.gc @@ -61,12 +61,13 @@ (to-spr-waits uint32 :offset-assert 44) (from-spr-waits uint32 :offset-assert 48) ) + :pack-me :method-count-assert 14 :size-assert #x34 :flag-assert #xe00000034 (:methods (dummy-9 (_type_) none 9) - (dummy-10 (_type_) none 10) + (print-to-stream (_type_ string basic) none 10) (reset! (_type_) none 11) (read! (_type_) none 12) (update-wait-stats (_type_ uint uint uint) none 13) diff --git a/test/decompiler/reference/engine/draw/drawable-actor-h_REF.gc b/test/decompiler/reference/engine/draw/drawable-actor-h_REF.gc index 0a2463eabd..6e8b7cbc9d 100644 --- a/test/decompiler/reference/engine/draw/drawable-actor-h_REF.gc +++ b/test/decompiler/reference/engine/draw/drawable-actor-h_REF.gc @@ -38,9 +38,11 @@ ) ;; definition for method 10 of type drawable-tree-actor +;; INFO: Return type mismatch int vs none. (defmethod draw drawable-tree-actor ((obj drawable-tree-actor) (arg0 drawable) (arg1 display-frame)) 0 + (none) ) diff --git a/test/decompiler/reference/engine/draw/drawable-ambient-h_REF.gc b/test/decompiler/reference/engine/draw/drawable-ambient-h_REF.gc index 1055c0fdf4..80c02b0f79 100644 --- a/test/decompiler/reference/engine/draw/drawable-ambient-h_REF.gc +++ b/test/decompiler/reference/engine/draw/drawable-ambient-h_REF.gc @@ -41,11 +41,13 @@ ) ;; definition for method 10 of type drawable-tree-ambient +;; INFO: Return type mismatch int vs none. (defmethod draw drawable-tree-ambient ((obj drawable-tree-ambient) (arg0 drawable) (arg1 display-frame)) 0 + (none) ) ;; definition for method 16 of type drawable-tree-ambient diff --git a/test/decompiler/reference/engine/draw/drawable-h_REF.gc b/test/decompiler/reference/engine/draw/drawable-h_REF.gc index ceb774e45e..618803de6c 100644 --- a/test/decompiler/reference/engine/draw/drawable-h_REF.gc +++ b/test/decompiler/reference/engine/draw/drawable-h_REF.gc @@ -11,12 +11,12 @@ :flag-assert #x1200000020 (:methods (login (_type_) _type_ 9) - (draw (_type_ drawable display-frame) int 10) - (dummy-11 (_type_ int) none 11) - (dummy-12 (_type_ int) none 12) - (dummy-13 (_type_ int) none 13) - (dummy-14 () none 14) - (dummy-15 (_type_) none 15) + (draw (_type_ drawable display-frame) none 10) + (dummy-11 (_type_ int object) none 11) + (dummy-12 (_type_ int object) none 12) + (dummy-13 (_type_ int object) none 13) + (dummy-14 (_type_) none 14) + (dummy-15 (_type_ object object) none 15) (dummy-16 (_type_ object object) object 16) (dummy-17 (_type_ sphere int ambient-list) none 17) ) diff --git a/test/decompiler/reference/engine/draw/drawable-inline-array_REF.gc b/test/decompiler/reference/engine/draw/drawable-inline-array_REF.gc index e75ec00306..cb3ce7e4ec 100644 --- a/test/decompiler/reference/engine/draw/drawable-inline-array_REF.gc +++ b/test/decompiler/reference/engine/draw/drawable-inline-array_REF.gc @@ -12,23 +12,28 @@ ) ;; definition for method 10 of type drawable-inline-array +;; INFO: Return type mismatch int vs none. (defmethod draw drawable-inline-array ((obj drawable-inline-array) (arg0 drawable) (arg1 display-frame)) 0 + (none) ) ;; definition for method 14 of type drawable-inline-array ;; INFO: Return type mismatch int vs none. -(defmethod dummy-14 drawable-inline-array () +(defmethod dummy-14 drawable-inline-array ((obj drawable-inline-array)) 0 (none) ) ;; definition for method 15 of type drawable-inline-array ;; INFO: Return type mismatch int vs none. -(defmethod dummy-15 drawable-inline-array ((obj drawable-inline-array)) +(defmethod + dummy-15 + drawable-inline-array + ((obj drawable-inline-array) (arg0 object) (arg1 object)) 0 (none) ) diff --git a/test/decompiler/reference/engine/geometry/cylinder_REF.gc b/test/decompiler/reference/engine/geometry/cylinder_REF.gc new file mode 100644 index 0000000000..3298540887 --- /dev/null +++ b/test/decompiler/reference/engine/geometry/cylinder_REF.gc @@ -0,0 +1,384 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition for method 10 of type cylinder +(defmethod + ray-capsule-intersect + cylinder + ((obj cylinder) (probe-origin vector) (probe-dir vector)) + (let ((t2-0 (new 'stack-no-clear 'vector)) + (end-pt (new 'stack-no-clear 'vector)) + ) + 0.0 + 0.0 + (let + ((result + (ray-cylinder-intersect + probe-origin + probe-dir + (-> obj origin) + (-> obj axis) + (-> obj radius) + (-> obj length) + t2-0 + ) + ) + ) + (let + ((u-origin-sph + (ray-sphere-intersect + probe-origin + probe-dir + (-> obj origin) + (-> obj radius) + ) + ) + ) + (if (and (>= u-origin-sph 0.0) (or (< result 0.0) (< u-origin-sph result))) + (set! result u-origin-sph) + ) + ) + (vector+float*! end-pt (-> obj origin) (-> obj axis) (-> obj length)) + (let + ((u-end-sphere + (ray-sphere-intersect probe-origin probe-dir end-pt (-> obj radius)) + ) + ) + (if (and (>= u-end-sphere 0.0) (or (< result 0.0) (< u-end-sphere result))) + (set! result u-end-sphere) + ) + ) + result + ) + ) + ) + +;; definition of type cylinder-verts +(deftype cylinder-verts (structure) + ((vert vector 24 :inline :offset-assert 0) + ) + :method-count-assert 9 + :size-assert #x180 + :flag-assert #x900000180 + ) + +;; definition for method 3 of type cylinder-verts +(defmethod inspect cylinder-verts ((obj cylinder-verts)) + (format #t "[~8x] ~A~%" obj 'cylinder-verts) + (format #t "~Tvert[24] @ #x~X~%" (-> obj vert)) + obj + ) + +;; definition for method 9 of type cylinder +;; INFO: Return type mismatch int vs none. +;; Used lq/sq +(defmethod debug-draw cylinder ((obj cylinder) (arg0 vector)) + (local-vars + (sv-896 matrix) + (sv-912 int) + (sv-928 (function vector vector vector float vector)) + (sv-944 vector) + (sv-960 vector) + (sv-976 vector) + (sv-992 (function vector vector vector float vector)) + (sv-1008 vector) + (sv-1024 vector) + (sv-1040 vector) + (sv-1056 (function vector vector vector float vector)) + (sv-1072 vector) + (sv-1088 vector) + (sv-1104 vector) + (sv-1120 (function vector vector vector float vector)) + (sv-1136 vector) + (sv-1152 vector) + (sv-1168 vector) + ) + (rlet ((vf0 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + ) + (init-vf0-vector) + (let ((s1-0 (new 'stack-no-clear 'vector)) + (s0-0 (new 'stack-no-clear 'vector)) + ) + (if (< 0.999 (fabs (-> obj axis y))) + (vector-cross! s1-0 (-> obj axis) (new 'static 'vector :z 1.0)) + (vector-cross! s1-0 (-> obj axis) (new 'static 'vector :y 1.0)) + ) + (vector-normalize! s1-0 (-> obj radius)) + (vector-float*! s0-0 (-> obj axis) (* 0.125 (-> obj length))) + (let ((s5-0 (new 'stack-no-clear 'cylinder-verts)) + (s4-0 (new 'stack-no-clear 'cylinder-verts)) + (s3-0 (new 'stack-no-clear 'matrix)) + ) + (matrix-axis-angle! s3-0 (-> obj axis) 4096.0) + (set! sv-896 (new 'stack-no-clear 'matrix)) + (vector-matrix*! (the-as vector sv-896) (-> obj origin) s3-0) + (let ((v1-5 (-> s3-0 vector 3))) + (.lvf vf4 (&-> (-> obj origin) quad)) + (.lvf vf5 (&-> sv-896 vector 0 quad)) + (.mov.vf vf6 vf0 :mask #b1000) + (.sub.vf vf6 vf4 vf5 :mask #b111) + (.svf (&-> v1-5 quad) vf6) + ) + (set! sv-912 0) + (while (< sv-912 8) + (vector+! (-> s5-0 vert (+ sv-912 8)) (-> obj origin) s1-0) + (vector+float*! + (-> s5-0 vert (+ sv-912 8)) + (-> s5-0 vert (+ sv-912 8)) + s0-0 + (the float sv-912) + ) + (set! sv-912 (+ sv-912 1)) + ) + (dotimes (s0-1 8) + (set! sv-928 vector+float*!) + (set! sv-944 (-> s5-0 vert s0-1)) + (set! sv-960 (-> obj origin)) + (set! sv-976 s1-0) + (let ((a3-1 (cos (* 2048.0 (the float (- 7 s0-1)))))) + (sv-928 sv-944 sv-960 sv-976 a3-1) + ) + (set! sv-992 vector+float*!) + (set! sv-1008 (-> s5-0 vert s0-1)) + (set! sv-1024 (-> s5-0 vert s0-1)) + (set! sv-1040 (-> obj axis)) + (let + ((a3-2 (* (- (-> obj radius)) (sin (* 2048.0 (the float (- 7 s0-1))))))) + (sv-992 sv-1008 sv-1024 sv-1040 a3-2) + ) + (set! sv-1056 vector+float*!) + (set! sv-1072 (-> s5-0 vert (+ s0-1 16))) + (set! sv-1088 (-> obj origin)) + (set! sv-1104 s1-0) + (let ((a3-3 (cos (* 2048.0 (the float s0-1))))) + (sv-1056 sv-1072 sv-1088 sv-1104 a3-3) + ) + (set! sv-1120 vector+float*!) + (set! sv-1136 (-> s5-0 vert (+ s0-1 16))) + (set! sv-1152 (-> s5-0 vert (+ s0-1 16))) + (set! sv-1168 (-> obj axis)) + (let + ((a3-4 + (+ + (-> obj length) + (* (-> obj radius) (sin (* 2048.0 (the float s0-1)))) + ) + ) + ) + (sv-1120 sv-1136 sv-1152 sv-1168 a3-4) + ) + ) + (dotimes (s2-1 16) + (dotimes (s1-1 24) + (vector-matrix*! (-> s4-0 vert s1-1) (-> s5-0 vert s1-1) s3-0) + (camera-line (-> s5-0 vert s1-1) (-> s4-0 vert s1-1) arg0) + (if (nonzero? s1-1) + (camera-line (-> s5-0 vert s1-1) (-> s5-0 vert (+ s1-1 -1)) arg0) + ) + ) + (let ((v1-77 s5-0)) + (set! s5-0 s4-0) + (set! s4-0 v1-77) + ) + ) + ) + ) + 0 + (none) + ) + ) + +;; definition for function ray-arbitrary-circle-intersect +(defun + ray-arbitrary-circle-intersect + ((probe-origin vector) + (probe-dir vector) + (circle-origin vector) + (circle-normal vector) + (radius float) + ) + (let* + ((v1-1 (vector-! (new 'stack-no-clear 'vector) circle-origin probe-origin)) + (f0-2 + (/ (vector-dot v1-1 circle-normal) (vector-dot probe-dir circle-normal)) + ) + ) + (cond + ((or (< 1.0 f0-2) (< f0-2 0.0)) + -100000000.0 + ) + ((let ((a0-7 (new 'stack-no-clear 'vector))) + (vector-float*! a0-7 probe-dir f0-2) + (vector-! a0-7 a0-7 v1-1) + (< (vector-dot a0-7 a0-7) (* radius radius)) + ) + f0-2 + ) + (else + -100000000.0 + ) + ) + ) + ) + +;; definition for method 10 of type cylinder-flat +;; Used lq/sq +(defmethod + ray-flat-cyl-intersect + cylinder-flat + ((obj cylinder-flat) (probe-origin vector) (probe-dir vector)) + (let ((gp-0 (new 'stack-no-clear 'vector)) + (end-pt (new 'stack-no-clear 'vector)) + ) + 0.0 + 0.0 + (let + ((result + (ray-cylinder-intersect + probe-origin + probe-dir + (-> obj origin) + (-> obj axis) + (-> obj radius) + (-> obj length) + gp-0 + ) + ) + ) + (let + ((u-origin-circle + (ray-arbitrary-circle-intersect + probe-origin + probe-dir + (-> obj origin) + (-> obj axis) + (-> obj radius) + ) + ) + ) + (when + (and + (>= u-origin-circle 0.0) + (or (< result 0.0) (< u-origin-circle result)) + ) + (set! result u-origin-circle) + (set! (-> gp-0 quad) (-> obj origin quad)) + ) + ) + (vector+float*! end-pt (-> obj origin) (-> obj axis) (-> obj length)) + (let + ((u-end-circle + (ray-arbitrary-circle-intersect + probe-origin + probe-dir + end-pt + (-> obj axis) + (-> obj radius) + ) + ) + ) + (when + (and (>= u-end-circle 0.0) (or (< result 0.0) (< u-end-circle result))) + (set! result u-end-circle) + (set! (-> gp-0 quad) (-> end-pt quad)) + ) + ) + result + ) + ) + ) + +;; definition of type cylinder-flat-verts +(deftype cylinder-flat-verts (structure) + ((vert vector 10 :inline :offset-assert 0) + ) + :method-count-assert 9 + :size-assert #xa0 + :flag-assert #x9000000a0 + ) + +;; definition for method 3 of type cylinder-flat-verts +(defmethod inspect cylinder-flat-verts ((obj cylinder-flat-verts)) + (format #t "[~8x] ~A~%" obj 'cylinder-flat-verts) + (format #t "~Tvert[10] @ #x~X~%" (-> obj vert)) + obj + ) + +;; definition for method 9 of type cylinder-flat +;; INFO: Return type mismatch int vs none. +;; Used lq/sq +(defmethod debug-draw cylinder-flat ((obj cylinder-flat) (arg0 vector)) + (local-vars (sv-448 vector) (sv-464 int)) + (rlet ((vf0 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + ) + (init-vf0-vector) + (let ((s1-0 (new 'stack-no-clear 'vector)) + (s0-0 (new 'stack-no-clear 'vector)) + ) + (if (< 0.999 (fabs (-> obj axis y))) + (vector-cross! s1-0 (-> obj axis) (new 'static 'vector :z 1.0)) + (vector-cross! s1-0 (-> obj axis) (new 'static 'vector :y 1.0)) + ) + (vector-normalize! s1-0 (-> obj radius)) + (vector-float*! s0-0 (-> obj axis) (* 0.14285715 (-> obj length))) + (let ((s5-0 (new 'stack-no-clear 'cylinder-flat-verts)) + (s4-0 (new 'stack-no-clear 'cylinder-flat-verts)) + (s3-0 (new 'stack-no-clear 'matrix)) + ) + (matrix-axis-angle! s3-0 (-> obj axis) 4096.0) + (set! sv-448 (new 'stack-no-clear 'vector)) + (vector-matrix*! sv-448 (-> obj origin) s3-0) + (let ((v1-5 (-> s3-0 vector 3))) + (.lvf vf4 (&-> (-> obj origin) quad)) + (.lvf vf5 (&-> sv-448 quad)) + (.mov.vf vf6 vf0 :mask #b1000) + (.sub.vf vf6 vf4 vf5 :mask #b111) + (.svf (&-> v1-5 quad) vf6) + ) + (set! sv-464 0) + (while (< sv-464 8) + (vector+! (-> s5-0 vert (+ sv-464 1)) (-> obj origin) s1-0) + (vector+float*! + (-> s5-0 vert (+ sv-464 1)) + (-> s5-0 vert (+ sv-464 1)) + s0-0 + (the float sv-464) + ) + (set! sv-464 (+ sv-464 1)) + ) + (set! (-> s5-0 vert 0 quad) (-> obj origin quad)) + (vector+float*! + (-> s5-0 vert 9) + (-> obj origin) + (-> obj axis) + (-> obj length) + ) + (dotimes (s2-1 16) + (dotimes (s1-1 10) + (vector-matrix*! (-> s4-0 vert s1-1) (-> s5-0 vert s1-1) s3-0) + (camera-line (-> s5-0 vert s1-1) (-> s4-0 vert s1-1) arg0) + (if (nonzero? s1-1) + (camera-line (-> s5-0 vert s1-1) (-> s5-0 vert (+ s1-1 -1)) arg0) + ) + ) + (let ((v1-43 s5-0)) + (set! s5-0 s4-0) + (set! s4-0 v1-43) + ) + ) + ) + ) + 0 + (none) + ) + ) + + + + diff --git a/test/decompiler/reference/engine/gfx/sprite/sprite-h_REF.gc b/test/decompiler/reference/engine/gfx/sprite/sprite-h_REF.gc index 0741c859e7..a88af013cc 100644 --- a/test/decompiler/reference/engine/gfx/sprite/sprite-h_REF.gc +++ b/test/decompiler/reference/engine/gfx/sprite/sprite-h_REF.gc @@ -32,33 +32,33 @@ ;; definition for method 3 of type sprite-vec-data-2d (defmethod inspect sprite-vec-data-2d ((obj sprite-vec-data-2d)) (format #t "[~8x] ~A~%" obj 'sprite-vec-data-2d) - (format #t "~Tx-y-z-sx: #~%" (-> obj x-y-z-sx)) - (format #t "~Tflag-rot-sy: #~%" (-> obj flag-rot-sy)) - (format #t "~Tr-g-b-a: #~%" (-> obj r-g-b-a)) - (format #t "~Tx: ~f~%" (-> obj x-y-z-sx x)) - (format #t "~Ty: ~f~%" (-> obj x-y-z-sx y)) - (format #t "~Tz: ~f~%" (-> obj x-y-z-sx z)) - (format #t "~Tsx: ~f~%" (-> obj x-y-z-sx w)) - (format #t "~Tsy: ~f~%" (-> obj flag-rot-sy w)) - (format #t "~Trot: ~f~%" (-> obj flag-rot-sy z)) - (format #t "~Tflag: ~D~%" (-> obj flag-rot-sy x)) - (format #t "~Tmatrix: ~D~%" (-> obj flag-rot-sy y)) - (format #t "~Twarp-turns: ~D~%" (-> obj flag-rot-sy x)) - (format #t "~Tr: ~f~%" (-> obj r-g-b-a x)) - (format #t "~Tg: ~f~%" (-> obj r-g-b-a y)) - (format #t "~Tb: ~f~%" (-> obj r-g-b-a z)) - (format #t "~Ta: ~f~%" (-> obj r-g-b-a w)) - (format #t "~Ttrans: #~%" (-> obj x-y-z-sx)) - (format #t "~Tcolor: #~%" (-> obj r-g-b-a)) - (format #t "~Tdata[1] @ #x~X~%" (-> obj x-y-z-sx)) - (format #t "~Tdata64[6] @ #x~X~%" (-> obj x-y-z-sx)) + (format #t "~Tx-y-z-sx: #~%" (&-> obj x)) + (format #t "~Tflag-rot-sy: #~%" (&-> obj flag)) + (format #t "~Tr-g-b-a: #~%" (&-> obj r)) + (format #t "~Tx: ~f~%" (-> obj x)) + (format #t "~Ty: ~f~%" (-> obj y)) + (format #t "~Tz: ~f~%" (-> obj z)) + (format #t "~Tsx: ~f~%" (-> obj sx)) + (format #t "~Tsy: ~f~%" (-> obj sy)) + (format #t "~Trot: ~f~%" (-> obj rot)) + (format #t "~Tflag: ~D~%" (-> obj flag)) + (format #t "~Tmatrix: ~D~%" (-> obj matrix)) + (format #t "~Twarp-turns: ~D~%" (-> obj flag)) + (format #t "~Tr: ~f~%" (-> obj r)) + (format #t "~Tg: ~f~%" (-> obj g)) + (format #t "~Tb: ~f~%" (-> obj b)) + (format #t "~Ta: ~f~%" (-> obj a)) + (format #t "~Ttrans: #~%" (&-> obj x)) + (format #t "~Tcolor: #~%" (&-> obj r)) + (format #t "~Tdata[1] @ #x~X~%" (&-> obj x)) + (format #t "~Tdata64[6] @ #x~X~%" (&-> obj x)) obj ) ;; definition of type sprite-array-2d (deftype sprite-array-2d (basic) - ((num-sprites uint32 2 :offset-assert 4) - (num-valid uint32 2 :offset-assert 12) + ((num-sprites int32 2 :offset-assert 4) + (num-valid int32 2 :offset-assert 12) (vec-data uint32 :offset-assert 20) (adgif-data uint32 :offset-assert 24) (pad uint128 4 :offset-assert 32) @@ -67,6 +67,9 @@ :method-count-assert 9 :size-assert #x70 :flag-assert #x900000070 + (:methods + (new (symbol type int int) _type_ 0) + ) ) ;; definition for method 3 of type sprite-array-2d @@ -135,8 +138,8 @@ ;; definition of type sprite-array-3d (deftype sprite-array-3d (basic) - ((num-sprites uint32 2 :offset-assert 4) - (num-valid uint32 2 :offset-assert 12) + ((num-sprites int32 2 :offset-assert 4) + (num-valid int32 2 :offset-assert 12) (vec-data uint32 :offset-assert 20) (adgif-data uint32 :offset-assert 24) (data uint128 1 :offset-assert 32) @@ -144,6 +147,9 @@ :method-count-assert 9 :size-assert #x30 :flag-assert #x900000030 + (:methods + (new (symbol type int int) _type_ 0) + ) ) ;; definition for method 3 of type sprite-array-3d diff --git a/test/decompiler/reference/engine/gfx/texture_REF.gc b/test/decompiler/reference/engine/gfx/texture_REF.gc index 0528c909d4..8619921d72 100644 --- a/test/decompiler/reference/engine/gfx/texture_REF.gc +++ b/test/decompiler/reference/engine/gfx/texture_REF.gc @@ -3200,11 +3200,11 @@ ;; WARN: Unsupported inline assembly instruction kind - [subu a3, t0, a3] (defun adgif-shader<-texture-with-update! ((arg0 adgif-shader) (arg1 texture)) (local-vars - (v1-11 int) + (v1-11 uint128) (v1-12 int) - (a3-4 int) + (a3-4 uint128) (a3-5 int) - (a3-9 int) + (a3-9 uint128) (a3-10 int) (a3-13 int) (a3-22 uint) @@ -3232,17 +3232,17 @@ (v1-8 (-> arg1 width 0)) (t1-6 (logior (logior t1-4 a3-2) (shl v1-8 14))) ) - (let ((v1-10 (-> arg1 wu))) - (.plzcw v1-11 v1-10) + (let ((v1-10 (the-as uint128 (-> arg1 wu)))) + (.plzcw v1-11 (the-as uint v1-10)) ) (let ((t0-0 30)) - (.subu v1-12 t0-0 v1-11) - (let ((a3-3 (-> arg1 hu)) + (.subu v1-12 t0-0 (the-as int v1-11)) + (let ((a3-3 (the-as uint128 (-> arg1 hu))) (v1-13 (shl v1-12 26)) ) - (.plzcw a3-4 a3-3) + (.plzcw a3-4 (the-as uint a3-3)) (let ((t1-7 (logior t1-6 v1-13))) - (.subu a3-5 t0-0 a3-4) + (.subu a3-5 t0-0 (the-as int a3-4)) (let* ((a3-6 (shl a3-5 30)) (v1-14 1) (t1-9 (logior (logior t1-7 a3-6) (shl v1-14 34))) @@ -3252,18 +3252,18 @@ (v1-19 (shl 1 61)) (f0-3 (the int f0-2)) (t1-12 (logior t1-11 v1-19)) - (v1-20 f0-3) + (v1-20 (the-as uint128 f0-3)) ) (set! (-> arg0 tex0) (the-as gs-tex0 t1-12)) - (.plzcw a3-9 v1-20) - (.subu a3-10 t0-0 a3-9) + (.plzcw a3-9 (the-as int v1-20)) + (.subu a3-10 t0-0 (the-as int a3-9)) (let ((t0-2 (+ (-> arg1 mip-shift) -1))) (nop!) (b! (zero? t0-2) cfg-2) ) (let* ((t0-3 (+ a3-10 -4)) (a3-11 (* a3-10 16)) - (t0-4 (sar v1-20 t0-3)) + (t0-4 (sar (the-as int v1-20) t0-3)) (a3-12 (+ a3-11 -175)) (t0-5 (logand t0-4 15)) ) @@ -3273,7 +3273,7 @@ (label cfg-2) (let* ((t0-6 (+ a3-10 -5)) (a3-14 (* a3-10 32)) - (t0-7 (sar v1-20 t0-6)) + (t0-7 (sar (the-as int v1-20) t0-6)) (a3-15 (+ a3-14 -350)) (t0-8 (logand t0-7 31)) ) diff --git a/test/decompiler/reference/engine/gfx/tfrag/subdivide-h_REF.gc b/test/decompiler/reference/engine/gfx/tfrag/subdivide-h_REF.gc index 7921342958..5f81890765 100644 --- a/test/decompiler/reference/engine/gfx/tfrag/subdivide-h_REF.gc +++ b/test/decompiler/reference/engine/gfx/tfrag/subdivide-h_REF.gc @@ -12,7 +12,7 @@ :size-assert #x4c :flag-assert #x90000004c (:methods - (new (symbol type float float) _type_ 0) + (new (symbol type meters meters) _type_ 0) ) ) @@ -30,7 +30,7 @@ (defmethod new subdivide-settings - ((allocation symbol) (type-to-make type) (arg0 float) (arg1 float)) + ((allocation symbol) (type-to-make type) (arg0 meters) (arg1 meters)) (let ((v0-0 (object-new allocation type-to-make (the-as int (-> type-to-make size))) diff --git a/test/decompiler/reference/engine/gfx/tfrag/subdivide_REF.gc b/test/decompiler/reference/engine/gfx/tfrag/subdivide_REF.gc new file mode 100644 index 0000000000..06b7a90e16 --- /dev/null +++ b/test/decompiler/reference/engine/gfx/tfrag/subdivide_REF.gc @@ -0,0 +1,540 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition for symbol *merc-global-stats*, type merc-global-stats +(define *merc-global-stats* (new 'global 'merc-global-stats)) + +;; definition for function clear-tr-stat +;; INFO: Return type mismatch int vs none. +(defun clear-tr-stat ((arg0 tr-stat)) + (set! (-> arg0 groups) (the-as uint 0)) + (set! (-> arg0 fragments) (the-as uint 0)) + (set! (-> arg0 tris) (the-as uint 0)) + (set! (-> arg0 dverts) (the-as uint 0)) + (set! (-> arg0 instances) (the-as uint 0)) + 0 + (none) + ) + +;; definition for symbol *stat-string-tfrag*, type string +(define *stat-string-tfrag* (new 'global 'string 128 (the-as string #f))) + +;; definition for symbol *stat-string-tfrag-near*, type string +(define *stat-string-tfrag-near* (new 'global 'string 128 (the-as string #f))) + +;; definition for symbol *stat-string-total*, type string +(define *stat-string-total* (new 'global 'string 128 (the-as string #f))) + +;; definition (debug) for function print-tr-stat +;; INFO: Return type mismatch uint vs none. +(defun-debug print-tr-stat ((stat tr-stat) (name string) (dest string)) + (clear dest) + (when + (nonzero? + (+ + (+ + (+ (+ (-> stat groups) (-> stat fragments)) (-> stat tris)) + (-> stat dverts) + ) + (-> stat instances) + ) + ) + (format + dest + "~0k~4d ~5d ~6d ~6d" + (-> stat groups) + (-> stat fragments) + (-> stat tris) + (-> stat dverts) + ) + (format + dest + "~0k ~7f ~5d ~s" + (/ + (* 2.0 (the float (-> stat tris))) + (the float (- (-> stat dverts) (-> stat tris))) + ) + (-> stat instances) + name + ) + (format *stdcon* "~S~%" dest) + (+! (-> *terrain-stats* total groups) (-> stat groups)) + (+! (-> *terrain-stats* total fragments) (-> stat fragments)) + (+! (-> *terrain-stats* total tris) (-> stat tris)) + (+! (-> *terrain-stats* total dverts) (-> stat dverts)) + (+! (-> *terrain-stats* total instances) (-> stat instances)) + ) + (none) + ) + +;; definition (debug) for function print-terrain-stats +;; INFO: Return type mismatch int vs none. +(defun-debug print-terrain-stats () + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x40 :b #x40 :a #x80) + ) + ) + (dotimes (gp-0 (-> *level* length)) + (let ((s5-0 (-> *level* level gp-0))) + (when (= (-> s5-0 status) 'active) + (dummy-14 s5-0 #f) + (format + *stdcon* + "~0k~D ~A ~,,2fK + textures~%" + (-> s5-0 index) + (-> s5-0 name) + (* 0.0009765625 (the float (-> s5-0 mem-usage))) + ) + ) + ) + ) + (format *stdcon* "~0k~%grps frags tris dverts strip insts~%") + (print-tr-stat (-> *terrain-stats* pris) "pris" *temp-string*) + (print-tr-stat (-> *merc-global-stats* merc) "merc" *temp-string*) + (print-tr-stat (-> *merc-global-stats* mercneric) "mercneric" *temp-string*) + (print-tr-stat (-> *terrain-stats* tie-near) "tie-near" *temp-string*) + (print-tr-stat (-> *terrain-stats* tie) "tie" *temp-string*) + (print-tr-stat (-> *terrain-stats* tie-generic) "tie-generic" *temp-string*) + (print-tr-stat (-> *terrain-stats* shrub-near) "shrub-near" *temp-string*) + (print-tr-stat (-> *terrain-stats* shrub) "shrub" *temp-string*) + (print-tr-stat + (-> *terrain-stats* tfrag-near) + "tfrag-near" + *stat-string-tfrag-near* + ) + (print-tr-stat (-> *terrain-stats* tfrag) "tfrag" *stat-string-tfrag*) + (print-tr-stat (-> *terrain-stats* trans-tfrag) "trans-tfrag" *temp-string*) + (print-tr-stat + (-> *terrain-stats* trans-tfrag-near) + "trans-tfrag-near" + *temp-string* + ) + (print-tr-stat (-> *terrain-stats* trans-pris) "trans-pris" *temp-string*) + (print-tr-stat (-> *terrain-stats* billboard) "billboard" *temp-string*) + (print-tr-stat (-> *terrain-stats* trans-shrub) "trans-shrub" *temp-string*) + (print-tr-stat (-> *terrain-stats* ocean-mid) "ocean-mid" *temp-string*) + (print-tr-stat (-> *terrain-stats* ocean-near) "ocean-near" *temp-string*) + (format + *stdcon* + "~0k---------------------------------------------------------------~%" + ) + (print-tr-stat (-> *terrain-stats* total) "total" *stat-string-total*) + (clear-tr-stat (-> *terrain-stats* pris)) + (clear-tr-stat (-> *merc-global-stats* merc)) + (clear-tr-stat (-> *merc-global-stats* mercneric)) + (clear-tr-stat (-> *terrain-stats* shrub-near)) + (clear-tr-stat (-> *terrain-stats* tie-near)) + (clear-tr-stat (-> *terrain-stats* tie)) + (clear-tr-stat (-> *terrain-stats* tie-generic)) + (clear-tr-stat (-> *terrain-stats* shrub)) + (clear-tr-stat (-> *terrain-stats* tfrag-near)) + (clear-tr-stat (-> *terrain-stats* tfrag)) + (clear-tr-stat (-> *terrain-stats* trans-tfrag)) + (clear-tr-stat (-> *terrain-stats* trans-tfrag-near)) + (clear-tr-stat (-> *terrain-stats* trans-pris)) + (clear-tr-stat (-> *terrain-stats* billboard)) + (clear-tr-stat (-> *terrain-stats* trans-shrub)) + (clear-tr-stat (-> *terrain-stats* ocean-mid)) + (clear-tr-stat (-> *terrain-stats* ocean-near)) + (clear-tr-stat (-> *terrain-stats* total)) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :b #xff :a #x80) + ) + ) + 0 + (none) + ) + +;; definition for function update-subdivide-settings! +;; INFO: Return type mismatch int vs none. +(defun + update-subdivide-settings! + ((settings subdivide-settings) (math-cam math-camera) (idx int)) + (set! (-> settings meters 0) (-> settings far idx)) + (set! (-> settings meters 4) (-> settings close idx)) + (let ((f0-3 (* 0.14285715 (- (-> settings meters 0) (-> settings meters 4))))) + (set! (-> settings meters 3) (+ (-> settings meters 4) (* 0.5 f0-3))) + (set! (-> settings meters 2) (+ (-> settings meters 3) f0-3)) + (set! (-> settings meters 1) (+ (-> settings meters 2) (* 2.0 f0-3))) + ) + (let ((f0-7 (/ (-> math-cam inv-hmge-scale w) (-> math-cam d)))) + (dotimes (v1-5 5) + (set! (-> settings dist v1-5) (* f0-7 (-> settings meters v1-5))) + ) + ) + (set! (-> *tfrag-work* frag-dists x) (- (-> settings meters 0))) + (set! (-> *tfrag-work* frag-dists y) (- (-> settings meters 1))) + (set! (-> *tfrag-work* frag-dists z) (- (-> settings meters 2))) + (set! (-> *tfrag-work* frag-dists w) (- (-> settings meters 4))) + 0 + (none) + ) + +;; definition for symbol *subdivide-settings*, type subdivide-settings +(define + *subdivide-settings* + (new 'global 'subdivide-settings (meters 30.0) (meters 70.0)) + ) + +;; definition for function set-tfrag-dists! +;; INFO: Return type mismatch (pointer float) vs none. +(defun set-tfrag-dists! ((arg0 (pointer float))) + (let ((f2-0 (-> *subdivide-settings* dist 0)) + (f1-0 (-> *subdivide-settings* dist 1)) + (f0-0 (-> *subdivide-settings* dist 2)) + ) + (set! (-> arg0 3) f2-0) + (set! (-> arg0 7) f1-0) + (let ((f4-1 (/ 1.0 (- f2-0 f1-0))) + (f3-2 (/ 1.0 (- f1-0 f0-0))) + ) + (set! (-> arg0 1) (- f4-1)) + (set! (-> arg0 5) (- f3-2)) + (set! (-> arg0 0) (* 0.5 f4-1)) + (set! (-> arg0 4) (* 0.5 f3-2)) + (let ((f2-1 (* f2-0 f4-1)) + (f5-7 (* f1-0 f3-2)) + ) + (set! (-> arg0 9) f2-1) + (set! (-> arg0 13) f5-7) + ) + (set! (-> arg0 8) (* (* -0.5 f4-1) f1-0)) + (set! (-> arg0 12) (* (* -0.5 f3-2) f0-0)) + ) + ) + (none) + ) + +;; definition for symbol *terrain-context*, type terrain-context +(define *terrain-context* (new 'global 'terrain-context)) + +;; definition for symbol *perf-stats*, type perf-stat-array +(define *perf-stats* (new 'debug 'perf-stat-array 17)) + +;; definition for method 10 of type perf-stat +;; INFO: Return type mismatch perf-stat vs none. +(defmethod print-to-stream perf-stat ((obj perf-stat) (arg0 string) (arg1 basic)) + (format + *stdcon* + "~3d ~8d ~8d ~6d ~6d" + (-> obj count) + (-> obj cycles) + (-> obj instructions) + (-> obj icache) + (-> obj dcache) + ) + (format + *stdcon* + " ~2d ~2d ~2d" + (-> obj to-vu0-waits) + (-> obj to-spr-waits) + (-> obj from-spr-waits) + ) + (format *stdcon* " ~s~%" arg0) + (none) + ) + +;; definition (debug) for function perf-stat-bucket->string +(defun-debug perf-stat-bucket->string ((arg0 perf-stat-bucket)) + (case arg0 + (((perf-stat-bucket camera)) + "camera" + ) + (((perf-stat-bucket collide)) + "collide" + ) + (((perf-stat-bucket nav)) + "nav" + ) + (((perf-stat-bucket bones)) + "bones" + ) + (((perf-stat-bucket proto-tie-n)) + "proto-tie-n" + ) + (((perf-stat-bucket proto-tie)) + "proto-tie" + ) + (((perf-stat-bucket proto-tie-g)) + "proto-tie-g" + ) + (((perf-stat-bucket inst-tie)) + "inst-tie" + ) + (((perf-stat-bucket proto-shrub)) + "proto-shrub" + ) + (((perf-stat-bucket inst-shrub)) + "inst-shrub" + ) + (((perf-stat-bucket tfrag-near)) + "tfrag-near" + ) + (((perf-stat-bucket tfrag)) + "tfrag" + ) + (((perf-stat-bucket drawable)) + "drawable" + ) + (((perf-stat-bucket background)) + "background" + ) + (((perf-stat-bucket tie-generic)) + "tie-generic" + ) + (((perf-stat-bucket mercneric)) + "mercneric" + ) + (((perf-stat-bucket all-code)) + "all-code" + ) + (else + "*unknown*" + ) + ) + ) + +;; definition for symbol GSH_ENABLE, type symbol +(define GSH_ENABLE #f) + +;; definition for symbol GSH_BUCKET, type bucket-id +(define GSH_BUCKET (the-as bucket-id 3)) + +;; definition for symbol GSH_WHICH_STAT, type int +(define GSH_WHICH_STAT 1) + +;; definition for symbol GSH_MAX_DISPLAY, type basic +(define GSH_MAX_DISPLAY (the-as basic #f)) + +;; definition for symbol GSH_TIME, type int +(define GSH_TIME 64) + +;; definition for symbol *gomi-stats-hack*, type (inline-array perf-stat) +(define + *gomi-stats-hack* + (the-as (inline-array perf-stat) (malloc 'debug (* 52 (+ GSH_TIME 1)))) + ) + +;; definition (debug) for function start-perf-stat-collection +;; INFO: Return type mismatch int vs none. +;; WARN: Unsupported inline assembly instruction kind - [mtc0 Perf, r0] +;; WARN: Unsupported inline assembly instruction kind - [sync.l] +;; WARN: Unsupported inline assembly instruction kind - [sync.p] +;; WARN: Unsupported inline assembly instruction kind - [mtpc pcr0, r0] +;; WARN: Unsupported inline assembly instruction kind - [mtpc pcr1, r0] +;; WARN: Unsupported inline assembly instruction kind - [sync.l] +;; WARN: Unsupported inline assembly instruction kind - [sync.p] +;; WARN: Unsupported inline assembly instruction kind - [mtc0 Perf, a0] +;; WARN: Unsupported inline assembly instruction kind - [sync.l] +;; WARN: Unsupported inline assembly instruction kind - [sync.p] +(defun-debug start-perf-stat-collection () + (local-vars (r0-0 none)) + (let ((frame-idx (+ (-> *perf-stats* data 0 frame-number) 1))) + (set! (-> *perf-stats* data 0 frame-number) frame-idx) + (let ((gp-0 (mod frame-idx (the-as uint 34)))) + (when GSH_ENABLE + (let ((bucket GSH_BUCKET)) + (let ((which-stat GSH_WHICH_STAT)) + (set! gp-0 (+ (* bucket 2) (the-as uint which-stat))) + ) + (when GSH_MAX_DISPLAY + (let + ((stat-idx + (logand (-> *perf-stats* data 0 frame-number) (+ GSH_TIME -1)) + ) + ) + (set! + (-> *gomi-stats-hack* stat-idx cycles) + (-> *perf-stats* data (the-as int bucket) cycles) + ) + (set! + (-> *gomi-stats-hack* stat-idx instructions) + (-> *perf-stats* data (the-as int bucket) instructions) + ) + (set! + (-> *gomi-stats-hack* stat-idx icache) + (-> *perf-stats* data (the-as int bucket) icache) + ) + (set! + (-> *gomi-stats-hack* stat-idx dcache) + (-> *perf-stats* data (the-as int bucket) dcache) + ) + (when (zero? stat-idx) + (set! (-> *gomi-stats-hack* GSH_TIME cycles) (the-as uint 0)) + (set! (-> *gomi-stats-hack* GSH_TIME instructions) (the-as uint 0)) + (set! (-> *gomi-stats-hack* GSH_TIME icache) (the-as uint 0)) + (set! (-> *gomi-stats-hack* GSH_TIME dcache) (the-as uint 0)) + (dotimes (v1-22 GSH_TIME) + (if + (< + (-> *gomi-stats-hack* GSH_TIME cycles) + (-> *gomi-stats-hack* v1-22 cycles) + ) + (set! + (-> *gomi-stats-hack* GSH_TIME cycles) + (-> *gomi-stats-hack* v1-22 cycles) + ) + ) + (if + (< + (-> *gomi-stats-hack* GSH_TIME instructions) + (-> *gomi-stats-hack* v1-22 instructions) + ) + (set! + (-> *gomi-stats-hack* GSH_TIME instructions) + (-> *gomi-stats-hack* v1-22 instructions) + ) + ) + (if + (< + (-> *gomi-stats-hack* GSH_TIME icache) + (-> *gomi-stats-hack* v1-22 icache) + ) + (set! + (-> *gomi-stats-hack* GSH_TIME icache) + (-> *gomi-stats-hack* v1-22 icache) + ) + ) + (if + (< + (-> *gomi-stats-hack* GSH_TIME dcache) + (-> *gomi-stats-hack* v1-22 dcache) + ) + (set! + (-> *gomi-stats-hack* GSH_TIME dcache) + (-> *gomi-stats-hack* v1-22 dcache) + ) + ) + ) + ) + ) + (format *stdcon* "~%") + (print-to-stream (-> *gomi-stats-hack* GSH_TIME) "max-value" *stdcon*) + ) + ) + ) + (dotimes (v1-27 17) + (set! (-> *perf-stats* data v1-27 count) (the-as uint 0)) + (cond + ((!= v1-27 (shr gp-0 1)) + (set! (-> *perf-stats* data v1-27 ctrl) (the-as uint 0)) + 0 + ) + (else + (let ((a1-63 (logand gp-0 1)) + (a0-64 (the-as uint #x80004010)) + ) + (cond + ((zero? a1-63) + (set! a0-64 (+ #x60020 (the-as int a0-64))) + ) + ((= a1-63 1) + (set! a0-64 (+ #x300c0 (the-as int a0-64))) + ) + ) + (set! (-> *perf-stats* data v1-27 select) a1-63) + (set! (-> *perf-stats* data v1-27 ctrl) a0-64) + ) + (set! (-> *perf-stats* data v1-27 accum0) (the-as uint 0)) + (set! (-> *perf-stats* data v1-27 accum1) (the-as uint 0)) + (set! (-> *perf-stats* data v1-27 to-vu0-waits) (the-as uint 0)) + (set! (-> *perf-stats* data v1-27 to-spr-waits) (the-as uint 0)) + (set! (-> *perf-stats* data v1-27 from-spr-waits) (the-as uint 0)) + 0 + ) + ) + ) + ) + ) + (let* ((v1-31 (-> *perf-stats* data)) + (a0-76 (-> v1-31 0 ctrl)) + ) + (+! (-> v1-31 0 count) 1) + (b! (zero? a0-76) cfg-28) + (.mtc0 Perf r0-0) + (.sync.l) + (.sync.p) + (.mtpc pcr0 r0-0) + (.mtpc pcr1 r0-0) + (.sync.l) + (.sync.p) + (.mtc0 Perf a0-76) + ) + (.sync.l) + (.sync.p) + (label cfg-28) + 0 + 0 + (none) + ) + +;; definition (debug) for function end-perf-stat-collection +;; INFO: Return type mismatch int vs none. +;; WARN: Unsupported inline assembly instruction kind - [mtc0 Perf, r0] +;; WARN: Unsupported inline assembly instruction kind - [sync.l] +;; WARN: Unsupported inline assembly instruction kind - [sync.p] +;; WARN: Unsupported inline assembly instruction kind - [mfpc a0, pcr0] +;; WARN: Unsupported inline assembly instruction kind - [mfpc a0, pcr1] +(defun-debug end-perf-stat-collection () + (local-vars (r0-0 none) (a0-1 int) (a0-3 int)) + (let ((v1-1 (-> *perf-stats* data))) + (b! (zero? (-> v1-1 0 ctrl)) cfg-2) + (.mtc0 Perf r0-0) + (.sync.l) + (.sync.p) + (.mfpc a0-1 pcr0) + (+! (-> v1-1 0 accum0) (the-as uint a0-1)) + (.mfpc a0-3 pcr1) + (+! (-> v1-1 0 accum1) (the-as uint a0-3)) + ) + (label cfg-2) + 0 + (dotimes (v1-3 17) + (when (nonzero? (-> *perf-stats* data v1-3 ctrl)) + (let ((a2-0 (-> *perf-stats* data v1-3 select)) + (a1-8 (-> *perf-stats* data v1-3 accum0)) + (a0-15 (-> *perf-stats* data v1-3 accum1)) + ) + (cond + ((zero? a2-0) + (set! (-> *perf-stats* data v1-3 cycles) a1-8) + (set! (-> *perf-stats* data v1-3 instructions) a0-15) + ) + ((= a2-0 1) + (set! (-> *perf-stats* data v1-3 icache) a1-8) + (set! (-> *perf-stats* data v1-3 dcache) a0-15) + ) + ) + ) + ) + ) + 0 + (none) + ) + +;; definition (debug) for function print-perf-stats +;; INFO: Return type mismatch int vs none. +(defun-debug print-perf-stats () + (format *stdcon* "~0k~%count cycles instr icache dcache vu0/to/from~%") + (dotimes (gp-0 17) + (if (nonzero? (-> *perf-stats* data gp-0 count)) + (print-to-stream + (-> *perf-stats* data gp-0) + (perf-stat-bucket->string (the-as perf-stat-bucket gp-0)) + *stdcon* + ) + ) + ) + 0 + (none) + ) + + + + diff --git a/test/decompiler/reference/engine/gfx/vis/bsp-h_REF.gc b/test/decompiler/reference/engine/gfx/vis/bsp-h_REF.gc index 3592834ca7..03943fb843 100644 --- a/test/decompiler/reference/engine/gfx/vis/bsp-h_REF.gc +++ b/test/decompiler/reference/engine/gfx/vis/bsp-h_REF.gc @@ -27,34 +27,35 @@ ;; definition of type bsp-header (deftype bsp-header (drawable) - ((info file-info :offset 4) - (all-visible-list (pointer uint16) :offset-assert 32) - (visible-list-length int32 :offset-assert 36) - (drawable-trees drawable-tree-array :offset-assert 40) - (pat pointer :offset-assert 44) - (pat-length int32 :offset-assert 48) - (unk-data-0 pointer :offset-assert 52) - (unk-data-0-len int32 :offset-assert 56) - (unk-data-1 pointer :offset-assert 60) - (unk-data-1-len int32 :offset-assert 64) - (unk-zero-0 basic :offset-assert 68) - (name symbol :offset-assert 72) - (nickname symbol :offset-assert 76) - (vis-info level-vis-info 8 :offset-assert 80) - (actors drawable-inline-array-actor :offset-assert 112) - (cameras (array entity-camera) :offset-assert 116) - (nodes (inline-array bsp-node) :offset-assert 120) - (level level :offset-assert 124) - (unk-data-2 uint32 5 :offset-assert 128) - (boxes box8s-array :offset-assert 148) - (unk-data-3 uint32 :offset-assert 152) - (ambients drawable-inline-array-ambient :offset-assert 156) - (unk-data-4 float :offset-assert 160) - (unk-data-5 float :offset-assert 164) - (adgifs adgif-shader-array :offset-assert 168) - (unk-data-6 pointer :offset-assert 172) - (unk-data-7 pointer :offset-assert 176) - (unk-data-8 uint32 55 :offset-assert 180) + ((info file-info :offset 4) + (all-visible-list (pointer uint16) :offset-assert 32) + (visible-list-length int32 :offset-assert 36) + (drawable-trees drawable-tree-array :offset-assert 40) + (pat pointer :offset-assert 44) + (pat-length int32 :offset-assert 48) + (texture-remap-table (pointer uint64) :offset-assert 52) + (texture-remap-table-len int32 :offset-assert 56) + (unk-data-1 pointer :offset-assert 60) + (unk-data-1-len int32 :offset-assert 64) + (unk-zero-0 basic :offset-assert 68) + (name symbol :offset-assert 72) + (nickname symbol :offset-assert 76) + (vis-info level-vis-info 8 :offset-assert 80) + (actors drawable-inline-array-actor :offset-assert 112) + (cameras (array entity-camera) :offset-assert 116) + (nodes (inline-array bsp-node) :offset-assert 120) + (level level :offset-assert 124) + (current-leaf-idx uint16 :offset-assert 128) + (unk-data-2 uint16 9 :offset-assert 130) + (boxes box8s-array :offset-assert 148) + (current-bsp-back-flags uint32 :offset-assert 152) + (ambients drawable-inline-array-ambient :offset-assert 156) + (unk-data-4 float :offset-assert 160) + (unk-data-5 float :offset-assert 164) + (adgifs adgif-shader-array :offset-assert 168) + (unk-data-6 pointer :offset-assert 172) + (unk-data-7 pointer :offset-assert 176) + (unk-data-8 uint32 55 :offset-assert 180) ) :method-count-assert 20 :size-assert #x190 diff --git a/test/decompiler/reference/engine/gfx/vis/bsp_REF.gc b/test/decompiler/reference/engine/gfx/vis/bsp_REF.gc new file mode 100644 index 0000000000..7e193be89b --- /dev/null +++ b/test/decompiler/reference/engine/gfx/vis/bsp_REF.gc @@ -0,0 +1,653 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition for function mem-usage-bsp-tree +;; INFO: Return type mismatch bsp-header vs none. +(defun + mem-usage-bsp-tree + ((header bsp-header) (node bsp-node) (mem-use memory-usage-block) (flags int)) + (cond + ((zero? node) + ) + (else + (+! (-> mem-use data 58 count) 1) + (let ((v1-3 32)) + (+! (-> mem-use data 58 used) v1-3) + (+! (-> mem-use data 58 total) (logand -16 (+ v1-3 15))) + ) + (if (> (-> node front) 0) + (mem-usage-bsp-tree header (the-as bsp-node (-> node front)) mem-use flags) + ) + (if (> (-> node back) 0) + (mem-usage-bsp-tree header (the-as bsp-node (-> node back)) mem-use flags) + ) + ) + ) + (none) + ) + +;; definition for method 8 of type bsp-header +(defmethod + mem-usage + bsp-header + ((obj bsp-header) (mem-use memory-usage-block) (flags int)) + (set! (-> mem-use work-bsp) obj) + (when (nonzero? (-> obj info)) + (set! (-> mem-use length) (max 82 (-> mem-use length))) + (set! (-> mem-use data 81 name) "array") + (+! (-> mem-use data 81 count) 1) + (let ((v1-8 (asize-of (-> obj info)))) + (+! (-> mem-use data 81 used) v1-8) + (+! (-> mem-use data 81 total) (logand -16 (+ v1-8 15))) + ) + ) + (if (nonzero? (-> obj drawable-trees)) + (mem-usage (-> obj drawable-trees) mem-use flags) + ) + (set! (-> mem-use length) (max 63 (-> mem-use length))) + (set! (-> mem-use data 43 name) "entity") + (set! (-> mem-use data 44 name) "camera") + (set! (-> mem-use data 62 name) "pat") + (set! (-> mem-use data 58 name) "bsp-node") + (set! (-> mem-use length) (max 57 (-> mem-use length))) + (set! (-> mem-use data 56 name) "bsp-main") + (+! (-> mem-use data 56 count) 1) + (let ((v1-27 400)) + (+! (-> mem-use data 56 used) v1-27) + (+! (-> mem-use data 56 total) (logand -16 (+ v1-27 15))) + ) + (set! (-> mem-use length) (max 60 (-> mem-use length))) + (set! (-> mem-use data 59 name) "bsp-leaf-vis-self") + (+! (-> mem-use data 59 count) 1) + (let ((v1-36 (-> obj visible-list-length))) + (+! (-> mem-use data 59 used) v1-36) + (+! (-> mem-use data 59 total) (logand -16 (+ v1-36 15))) + ) + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-46 (* (-> obj texture-remap-table-len) 8))) + (+! (-> mem-use data 57 used) v1-46) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-46 15))) + ) + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-56 (* (-> obj unk-data-1-len) 4))) + (+! (-> mem-use data 57 used) v1-56) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-56 15))) + ) + (when (nonzero? (-> obj unk-zero-0)) + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-68 (asize-of (-> obj unk-zero-0)))) + (+! (-> mem-use data 57 used) v1-68) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-68 15))) + ) + ) + (when (nonzero? (-> obj adgifs)) + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-80 (asize-of (-> obj adgifs)))) + (+! (-> mem-use data 57 used) v1-80) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-80 15))) + ) + ) + (when (nonzero? (-> obj boxes)) + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-92 (asize-of (-> obj boxes)))) + (+! (-> mem-use data 57 used) v1-92) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-92 15))) + ) + (when (nonzero? (-> obj unk-data-7)) + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-105 (* (-> obj boxes length) 2))) + (+! (-> mem-use data 57 used) v1-105) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-105 15))) + ) + ) + ) + (when (nonzero? (-> obj unk-data-6)) + (set! (-> mem-use length) (max 58 (-> mem-use length))) + (set! (-> mem-use data 57 name) "bsp-misc") + (+! (-> mem-use data 57 count) 1) + (let ((v1-118 (* (-> obj actors length) 4))) + (+! (-> mem-use data 57 used) v1-118) + (+! (-> mem-use data 57 total) (logand -16 (+ v1-118 15))) + ) + ) + (+! (-> mem-use data 62 count) (-> obj pat-length)) + (let ((v1-125 (* (-> obj pat-length) 4))) + (+! (-> mem-use data 62 used) v1-125) + (+! (-> mem-use data 62 total) (logand -16 (+ v1-125 15))) + ) + (let ((s3-0 (-> obj cameras))) + (when (nonzero? s3-0) + (dotimes (s2-0 (-> s3-0 length)) + (mem-usage (-> s3-0 s2-0) mem-use (logior flags 256)) + ) + ) + ) + (mem-usage-bsp-tree obj (the-as bsp-node (-> obj nodes)) mem-use flags) + obj + ) + +;; definition for method 9 of type bsp-header +(defmethod login bsp-header ((obj bsp-header)) + (if (nonzero? (-> obj drawable-trees)) + (login (-> obj drawable-trees)) + ) + (when (nonzero? (-> obj adgifs)) + (let ((s5-0 (-> obj adgifs))) + (dotimes (s4-0 (-> s5-0 length)) + (adgif-shader-login-no-remap (-> s5-0 data s4-0)) + ) + ) + ) + obj + ) + +;; definition for symbol *test-shrub*, type int +(define *test-shrub* 0) + +;; definition for method 10 of type bsp-header +;; Used lq/sq +(defmethod + draw + bsp-header + ((obj bsp-header) (other-draw drawable) (disp-frame display-frame)) + (local-vars (r0-0 uint128) (a3-4 uint128) (a3-5 uint128)) + (rlet ((vf16 :class vf) + (vf17 :class vf) + (vf18 :class vf) + (vf19 :class vf) + (vf20 :class vf) + (vf21 :class vf) + (vf22 :class vf) + (vf23 :class vf) + (vf24 :class vf) + (vf25 :class vf) + (vf26 :class vf) + (vf27 :class vf) + (vf28 :class vf) + (vf29 :class vf) + (vf30 :class vf) + (vf31 :class vf) + ) + (let ((lev (-> obj level))) + (set! (-> (the-as terrain-bsp #x70000000) lev-index) (-> lev index)) + (set! (-> (the-as terrain-bsp #x70000000) mood) (-> lev mood)) + (if *artist-use-menu-subdiv* + (update-subdivide-settings! *subdivide-settings* *math-camera* 3) + (update-subdivide-settings! + *subdivide-settings* + *math-camera* + (-> lev index) + ) + ) + (add-irq-to-tex-buckets! lev) + (let ((vis-list-qwc (/ (+ (-> obj visible-list-length) 15) 16))) + (dma-send-to-spr-no-flush + (the-as uint (+ #x38b0 #x70000000)) + (the-as uint (-> lev vis-bits)) + (the-as uint vis-list-qwc) + #f + ) + ) + ) + (when *artist-flip-visible* + (let ((vis-list-qwc2 (/ (+ (-> obj visible-list-length) 15) 16)) + (vis-list-spad (the-as (pointer uint128) (+ #x38b0 #x70000000))) + (vis-list-lev (the-as (pointer uint128) (-> obj all-visible-list))) + ) + (dotimes (current-qw vis-list-qwc2) + (let ((a3-3 (-> vis-list-spad current-qw))) + (.pnor a3-4 a3-3 r0-0) + ) + (let ((t0-2 (-> vis-list-lev current-qw))) + (.pand a3-5 a3-4 t0-2) + ) + (set! (-> vis-list-spad current-qw) a3-5) + ) + ) + ) + (let ((at-0 *math-camera*)) + (.lvf vf16 (&-> at-0 plane 0)) + (.lvf vf17 (&-> at-0 plane 1)) + (.lvf vf18 (&-> at-0 plane 2)) + (.lvf vf19 (&-> at-0 plane 3)) + (.lvf vf20 (&-> at-0 shrub-mat vector 0 quad)) + (.lvf vf21 (&-> at-0 shrub-mat vector 1 quad)) + (.lvf vf22 (&-> at-0 shrub-mat vector 2 quad)) + (.lvf vf23 (&-> at-0 shrub-mat vector 3 quad)) + (.lvf vf24 (&-> at-0 camera-rot vector 0 quad)) + (.lvf vf25 (&-> at-0 camera-rot vector 1 quad)) + (.lvf vf26 (&-> at-0 camera-rot vector 2 quad)) + (.lvf vf27 (&-> at-0 camera-rot vector 3 quad)) + (.lvf vf28 (&-> at-0 camera-temp vector 0 quad)) + (.lvf vf29 (&-> at-0 camera-temp vector 1 quad)) + (.lvf vf30 (&-> at-0 camera-temp vector 2 quad)) + (.lvf vf31 (&-> at-0 camera-temp vector 3 quad)) + ) + (when (nonzero? (-> obj drawable-trees)) + (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 ((a1-7 (-> obj drawable-trees))) + (draw a1-7 a1-7 disp-frame) + ) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x80 :g #xc0 :a #x80) + ) + ) + ) + (let ((s5-1 (-> *display* frames (-> *display* on-screen) frame))) + (foreground-engine-execute + (-> obj level foreground-draw-engine 0) + s5-1 + (-> (the-as terrain-bsp #x70000000) lev-index) + 0 + ) + (foreground-engine-execute + (-> obj level foreground-draw-engine 1) + s5-1 + (-> (the-as terrain-bsp #x70000000) lev-index) + 1 + ) + (foreground-engine-execute + (-> obj level foreground-draw-engine 2) + s5-1 + (-> (the-as terrain-bsp #x70000000) lev-index) + 2 + ) + ) + (none) + ) + ) + +;; definition for method 15 of type bsp-header +;; INFO: Return type mismatch profile-frame vs none. +(defmethod dummy-15 bsp-header ((obj bsp-header) (arg0 object) (arg1 object)) + (rlet ((vf16 :class vf) + (vf17 :class vf) + (vf18 :class vf) + (vf19 :class vf) + (vf20 :class vf) + (vf21 :class vf) + (vf22 :class vf) + (vf23 :class vf) + (vf24 :class vf) + (vf25 :class vf) + (vf26 :class vf) + (vf27 :class vf) + (vf28 :class vf) + (vf29 :class vf) + (vf30 :class vf) + (vf31 :class vf) + ) + (let ((s4-0 (-> obj level))) + (set! (-> (the-as terrain-bsp #x70000000) lev-index) (-> s4-0 index)) + (set! (-> (the-as terrain-bsp #x70000000) mood) (-> s4-0 mood)) + (add-irq-to-tex-buckets! s4-0) + (let ((a2-1 (/ (+ (-> obj visible-list-length) 15) 16))) + (dma-send-to-spr-no-flush + (the-as uint (+ #x38b0 #x70000000)) + (the-as uint (-> s4-0 vis-bits)) + (the-as uint a2-1) + #f + ) + ) + ) + (let ((at-0 *math-camera*)) + (.lvf vf16 (&-> at-0 plane 0)) + (.lvf vf17 (&-> at-0 plane 1)) + (.lvf vf18 (&-> at-0 plane 2)) + (.lvf vf19 (&-> at-0 plane 3)) + (.lvf vf20 (&-> at-0 shrub-mat vector 0 quad)) + (.lvf vf21 (&-> at-0 shrub-mat vector 1 quad)) + (.lvf vf22 (&-> at-0 shrub-mat vector 2 quad)) + (.lvf vf23 (&-> at-0 shrub-mat vector 3 quad)) + (.lvf vf24 (&-> at-0 camera-rot vector 0 quad)) + (.lvf vf25 (&-> at-0 camera-rot vector 1 quad)) + (.lvf vf26 (&-> at-0 camera-rot vector 2 quad)) + (.lvf vf27 (&-> at-0 camera-rot vector 3 quad)) + (.lvf vf28 (&-> at-0 camera-temp vector 0 quad)) + (.lvf vf29 (&-> at-0 camera-temp vector 1 quad)) + (.lvf vf30 (&-> at-0 camera-temp vector 2 quad)) + (.lvf vf31 (&-> at-0 camera-temp vector 3 quad)) + ) + (when (nonzero? (-> obj drawable-trees)) + (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 ((a1-3 (-> obj drawable-trees))) + (dummy-15 a1-3 a1-3 arg1) + ) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x80 :g #xc0 :a #x80) + ) + ) + ) + (none) + ) + ) + +;; definition for method 14 of type bsp-header +(defmethod dummy-14 bsp-header ((obj bsp-header)) + (rlet ((vf16 :class vf) + (vf17 :class vf) + (vf18 :class vf) + (vf19 :class vf) + (vf20 :class vf) + (vf21 :class vf) + (vf22 :class vf) + (vf23 :class vf) + (vf24 :class vf) + (vf25 :class vf) + (vf26 :class vf) + (vf27 :class vf) + (vf28 :class vf) + (vf29 :class vf) + (vf30 :class vf) + (vf31 :class vf) + ) + (let ((v1-0 (-> obj level)) + (a2-0 (/ (+ (-> obj visible-list-length) 15) 16)) + ) + (dma-send-to-spr-no-flush + (the-as uint (+ #x38b0 #x70000000)) + (the-as uint (-> v1-0 vis-bits)) + (the-as uint a2-0) + #f + ) + ) + (let ((at-0 *math-camera*)) + (.lvf vf16 (&-> at-0 plane 0)) + (.lvf vf17 (&-> at-0 plane 1)) + (.lvf vf18 (&-> at-0 plane 2)) + (.lvf vf19 (&-> at-0 plane 3)) + (.lvf vf20 (&-> at-0 shrub-mat vector 0 quad)) + (.lvf vf21 (&-> at-0 shrub-mat vector 1 quad)) + (.lvf vf22 (&-> at-0 shrub-mat vector 2 quad)) + (.lvf vf23 (&-> at-0 shrub-mat vector 3 quad)) + (.lvf vf24 (&-> at-0 camera-rot vector 0 quad)) + (.lvf vf25 (&-> at-0 camera-rot vector 1 quad)) + (.lvf vf26 (&-> at-0 camera-rot vector 2 quad)) + (.lvf vf27 (&-> at-0 camera-rot vector 3 quad)) + (.lvf vf28 (&-> at-0 camera-temp vector 0 quad)) + (.lvf vf29 (&-> at-0 camera-temp vector 1 quad)) + (.lvf vf30 (&-> at-0 camera-temp vector 2 quad)) + (.lvf vf31 (&-> at-0 camera-temp vector 3 quad)) + ) + (if (nonzero? (-> obj drawable-trees)) + (dummy-14 (-> obj drawable-trees)) + ) + (none) + ) + ) + +;; definition for function bsp-camera-asm +;; INFO: Return type mismatch int vs none. +;; WARN: Function may read a register that is not set: a2 +(defun bsp-camera-asm ((bsp-hdr bsp-header) (camera-pos vector)) + (local-vars (v1-1 float) (real-node bsp-node)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (nop!) + (let ((next-node (the-as bsp-node (-> bsp-hdr nodes)))) + (.lvf vf1 (&-> camera-pos quad)) + (label cfg-1) + (b! (< (the-as int next-node) 0) cfg-4 :delay (set! real-node next-node)) + (.lvf vf2 (&-> real-node plane quad)) + (.mul.vf vf2 vf2 vf1 :mask #b111) + (.add.x.vf vf2 vf2 vf2 :mask #b10) + (.add.z.vf vf2 vf2 vf2 :mask #b10) + (.sub.w.vf vf2 vf2 vf2 :mask #b10) + (.mov v1-1 vf2) + (let ((a2-0 (-> real-node front-flags))) + (b! + (>= (the-as int v1-1) 0) + cfg-1 + :delay + (set! next-node (the-as bsp-node (-> real-node front))) + ) + (set! a2-0 (-> real-node back-flags)) + (b! #t cfg-1 :delay (set! next-node (the-as bsp-node (-> real-node back)))) + (label cfg-4) + (set! (-> bsp-hdr current-leaf-idx) (the-as uint next-node)) + (set! (-> bsp-hdr current-bsp-back-flags) a2-0) + ) + ) + 0 + (none) + ) + ) + +;; definition for method 11 of type bsp-header +;; INFO: Return type mismatch symbol vs none. +(defmethod dummy-11 bsp-header ((obj bsp-header) (arg0 int) (arg1 object)) + (+! (-> *collide-stats* calls) 1) + (let ((s4-0 (-> obj drawable-trees))) + (dotimes (s3-0 (-> s4-0 length)) + (dummy-11 (-> s4-0 data s3-0) arg0 arg1) + ) + ) + (none) + ) + +;; definition for method 12 of type bsp-header +;; INFO: Return type mismatch symbol vs none. +(defmethod dummy-12 bsp-header ((obj bsp-header) (arg0 int) (arg1 object)) + (+! (-> *collide-stats* calls) 1) + (let ((s4-0 (-> obj drawable-trees))) + (dotimes (s3-0 (-> s4-0 length)) + (dummy-12 (-> s4-0 data s3-0) arg0 arg1) + ) + ) + (none) + ) + +;; definition for method 13 of type bsp-header +;; INFO: Return type mismatch symbol vs none. +(defmethod dummy-13 bsp-header ((obj bsp-header) (arg0 int) (arg1 object)) + (+! (-> *collide-stats* calls) 1) + (let ((s4-0 (-> obj drawable-trees))) + (dotimes (s3-0 (-> s4-0 length)) + (dummy-13 (-> s4-0 data s3-0) arg0 arg1) + ) + ) + (none) + ) + +;; definition for method 17 of type bsp-header +;; INFO: Return type mismatch symbol vs none. +(defmethod + dummy-17 + bsp-header + ((obj bsp-header) (arg0 sphere) (arg1 int) (arg2 ambient-list)) + (let ((s3-0 (-> obj drawable-trees))) + (dotimes (s2-0 (-> s3-0 length)) + (dummy-17 (-> s3-0 data s2-0) arg0 arg1 arg2) + ) + ) + (none) + ) + +;; definition for function clear-cl-stat +;; INFO: Return type mismatch int vs none. +(defun clear-cl-stat ((arg0 cl-stat)) + (set! (-> arg0 fragments) (the-as uint 0)) + (set! (-> arg0 tris) (the-as uint 0)) + (set! (-> arg0 output) (the-as uint 0)) + 0 + (none) + ) + +;; definition for function print-cl-stat +;; INFO: Return type mismatch uint vs none. +(defun print-cl-stat ((arg0 cl-stat) (arg1 string)) + (when (nonzero? (+ (-> arg0 fragments) (-> arg0 tris))) + (format + *stdcon* + "~0k~5d/~d ~6d/~d ~6d/~d " + (-> arg0 fragments) + (/ (-> arg0 fragments) (-> *collide-stats* calls)) + (-> arg0 tris) + (/ (-> arg0 tris) (-> *collide-stats* calls)) + (-> arg0 output) + (/ (-> arg0 output) (-> *collide-stats* calls)) + ) + (format *stdcon* "~0k~s~%" arg1) + (+! (-> *collide-stats* total fragments) (-> arg0 fragments)) + (+! (-> *collide-stats* total tris) (-> arg0 tris)) + (+! (-> *collide-stats* total output) (-> arg0 output)) + ) + (none) + ) + +;; definition for function print-collide-stats +;; INFO: Return type mismatch int vs none. +(defun print-collide-stats () + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x40 :b #x40 :a #x80) + ) + ) + (format *stdcon* "~0k frags tris output~%") + (print-cl-stat (-> *collide-stats* other) "other") + (format + *stdcon* + "~0k---------------------------------------------------------------~%" + ) + (print-cl-stat (-> *collide-stats* total) "total") + (format *stdcon* "~0kcalls = ~d~%" (-> *collide-stats* calls)) + (let ((gp-0 (stopwatch-elapsed-ticks (-> *collide-stats* total-target))) + (s4-0 (stopwatch-elapsed-ticks (-> *collide-stats* target-cache-fill))) + (s5-0 (stopwatch-elapsed-ticks (-> *collide-stats* target-ray-poly))) + ) + (format *stdcon* "~0ktotal-target ~D~%" gp-0) + (format + *stdcon* + "~0ktarget-cache-fill ~D ~0,,2f%~%" + s4-0 + (/ (* 100.0 (the float s4-0)) (the float gp-0)) + ) + (format + *stdcon* + "~0ktarget-ray-poly ~D ~0,,2f%~%" + s5-0 + (/ (* 100.0 (the float s5-0)) (the float gp-0)) + ) + ) + (clear-cl-stat (-> *collide-stats* other)) + (clear-cl-stat (-> *collide-stats* total)) + (set! *collide-nodes* 0) + (set! (-> *collide-stats* calls) (the-as uint 0)) + (stopwatch-init (-> *collide-stats* total-target)) + (stopwatch-init (-> *collide-stats* target-cache-fill)) + (stopwatch-init (-> *collide-stats* target-ray-poly)) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :b #xff :a #x80) + ) + ) + 0 + (none) + ) + +;; definition for function level-remap-texture +;; INFO: Return type mismatch int vs texture-id. +(defun level-remap-texture ((tex-id texture-id)) + (let ((bsp-hdr (-> *level* log-in-level-bsp))) + (when bsp-hdr + (let* ((table-size (-> bsp-hdr texture-remap-table-len)) + (table-data-start (-> bsp-hdr texture-remap-table)) + (table-data-ptr table-data-start) + (mask1 (the-as uint #xfffffff8)) + (masked-tex-id (logand (the-as uint #xffffff00) tex-id)) + (table-data-end (&+ table-data-ptr (* table-size 8))) + ) + (label cfg-2) + (b! (= (the-as object table-data-start) table-data-end) cfg-8) + (let + ((midpoint + (the-as + object + (logand + (/ + (the-as + int + (+ (the-as int table-data-start) (the-as int table-data-end)) + ) + 2 + ) + mask1 + ) + ) + ) + ) + (let + ((diff + (- (-> (the-as (pointer int32) midpoint) 0) (the-as int masked-tex-id)) + ) + ) + (b! (zero? diff) cfg-7) + (b! (< diff 0) cfg-6 :delay (nop!)) + ) + (b! + #t + cfg-2 + :delay + (set! + table-data-end + (the-as (pointer uint64) (the-as (pointer uint64) midpoint)) + ) + ) + (label cfg-6) + (b! + #t + cfg-2 + :delay + (set! + table-data-start + (the-as (pointer uint64) (+ (the-as int midpoint) 8)) + ) + ) + (label cfg-7) + (set! + tex-id + (the-as texture-id (logior (-> (the-as (pointer int32) midpoint) 1) 20)) + ) + ) + ) + (label cfg-8) + 0 + ) + ) + (the-as texture-id tex-id) + ) diff --git a/test/decompiler/reference/engine/level/level-h_REF.gc b/test/decompiler/reference/engine/level/level-h_REF.gc index 085f81e682..9e064dbc07 100644 --- a/test/decompiler/reference/engine/level/level-h_REF.gc +++ b/test/decompiler/reference/engine/level/level-h_REF.gc @@ -268,23 +268,23 @@ ;; definition of type level-group (deftype level-group (basic) - ((length int32 :offset-assert 4) - (log-in-level level :offset-assert 8) - (loading-level level :offset-assert 12) - (entity-link entity-links :offset-assert 16) - (border? basic :offset-assert 20) - (vis? basic :offset-assert 24) - (want-level basic :offset-assert 28) - (receiving-level basic :offset-assert 32) - (load-commands pair :offset-assert 36) - (play? symbol :offset-assert 40) - (_hack-pad uint8 :offset 90) - (level0 level :inline :offset-assert 96) - (level1 level :inline :offset-assert 2704) - (level-default level :inline :offset-assert 5312) - (level level 3 :inline :offset 96) - (data level 3 :inline :offset 96) - (pad uint32 :offset-assert 7920) + ((length int32 :offset-assert 4) + (log-in-level-bsp bsp-header :offset-assert 8) + (loading-level level :offset-assert 12) + (entity-link entity-links :offset-assert 16) + (border? basic :offset-assert 20) + (vis? basic :offset-assert 24) + (want-level basic :offset-assert 28) + (receiving-level basic :offset-assert 32) + (load-commands pair :offset-assert 36) + (play? symbol :offset-assert 40) + (_hack-pad uint8 :offset 90) + (level0 level :inline :offset-assert 96) + (level1 level :inline :offset-assert 2704) + (level-default level :inline :offset-assert 5312) + (level level 3 :inline :offset 96) + (data level 3 :inline :offset 96) + (pad uint32 :offset-assert 7920) ) :method-count-assert 27 :size-assert #x1ef4 @@ -336,7 +336,7 @@ *level* (new 'static 'level-group :length 2 - :log-in-level #f + :log-in-level-bsp #f :loading-level #f :entity-link #f :border? #f diff --git a/test/decompiler/reference/engine/math/trigonometry_REF.gc b/test/decompiler/reference/engine/math/trigonometry_REF.gc index 42e3ba6637..8f9ad4e50e 100644 --- a/test/decompiler/reference/engine/math/trigonometry_REF.gc +++ b/test/decompiler/reference/engine/math/trigonometry_REF.gc @@ -396,7 +396,7 @@ ;; definition for function vector-rad<-vector-deg! ;; INFO: Return type mismatch float vs none. (defun vector-rad<-vector-deg! ((arg0 vector) (arg1 vector)) - (local-vars (v0-0 float) (v1-1 float) (v1-2 int) (v1-3 int)) + (local-vars (v0-0 float) (v1-1 uint128) (v1-2 uint128) (v1-3 uint128)) (rlet ((vf1 :class vf) (vf2 :class vf) ) @@ -420,7 +420,7 @@ ;; definition for function vector-rad<-vector-deg/2! ;; INFO: Return type mismatch float vs int. (defun vector-rad<-vector-deg/2! ((arg0 vector) (arg1 vector)) - (local-vars (v0-0 float) (v1-1 float) (v1-2 int) (v1-3 int)) + (local-vars (v0-0 float) (v1-1 uint128) (v1-2 uint128) (v1-3 uint128)) (rlet ((vf1 :class vf) (vf2 :class vf) ) diff --git a/test/decompiler/reference/engine/math/vector-h_REF.gc b/test/decompiler/reference/engine/math/vector-h_REF.gc index 7375d51eb5..90babba6ac 100644 --- a/test/decompiler/reference/engine/math/vector-h_REF.gc +++ b/test/decompiler/reference/engine/math/vector-h_REF.gc @@ -682,8 +682,8 @@ :size-assert #x28 :flag-assert #xb00000028 (:methods - (TODO-RENAME-HUGE-9 (_type_ vector) none 9) - (TODO-RENAME-10 (_type_ vector vector) float 10) + (debug-draw (_type_ vector) none 9) + (ray-capsule-intersect (_type_ vector vector) float 10) ) ) @@ -708,8 +708,8 @@ :size-assert #x28 :flag-assert #xb00000028 (:methods - (TODO-RENAME-HUGE-9 (_type_ vector) none 9) - (TODO-RENAME-10 (_type_ vector vector) float 10) + (debug-draw (_type_ vector) none 9) + (ray-flat-cyl-intersect (_type_ vector vector) float 10) ) ) diff --git a/test/decompiler/reference/engine/math/vector_REF.gc b/test/decompiler/reference/engine/math/vector_REF.gc index 5f36b8e0b9..94dbd0077c 100644 --- a/test/decompiler/reference/engine/math/vector_REF.gc +++ b/test/decompiler/reference/engine/math/vector_REF.gc @@ -997,7 +997,7 @@ ;; definition for function vector-degi ;; Used lq/sq (defun vector-degi ((arg0 vector) (arg1 vector)) - (local-vars (v1-0 float) (v1-1 int)) + (local-vars (v1-0 uint128) (v1-1 uint128)) (rlet ((vf1 :class vf)) (.lvf vf1 (&-> arg1 quad)) (.ftoi.vf vf1 vf1) @@ -1025,7 +1025,7 @@ ;; definition for function vector-degmod (defun vector-degmod ((arg0 vector) (arg1 vector)) - (local-vars (v1-0 float) (v1-1 int) (v1-2 int)) + (local-vars (v1-0 uint128) (v1-1 uint128) (v1-2 uint128)) (rlet ((vf1 :class vf)) (.lvf vf1 (&-> arg1 quad)) (.ftoi.vf vf1 vf1) @@ -1044,12 +1044,12 @@ (defun vector-deg-diff ((arg0 vector) (arg1 vector) (arg2 vector)) (local-vars (v0-0 float) - (v1-0 float) - (v1-1 int) - (v1-2 int) - (v1-3 int) - (a1-1 float) - (a1-2 int) + (v1-0 uint128) + (v1-1 uint128) + (v1-2 uint128) + (v1-3 uint128) + (a1-1 uint128) + (a1-2 uint128) ) (rlet ((vf1 :class vf) (vf2 :class vf) diff --git a/test/decompiler/test_FormExpressionBuild3.cpp b/test/decompiler/test_FormExpressionBuild3.cpp new file mode 100644 index 0000000000..d77a213765 --- /dev/null +++ b/test/decompiler/test_FormExpressionBuild3.cpp @@ -0,0 +1,56 @@ +#include "gtest/gtest.h" +#include "FormRegressionTest.h" + +using namespace decompiler; + +// vector-rad<-vector-deg/2! +TEST_F(FormRegressionTest, VectorDegToVectorRad) { + std::string func = + "sll r0, r0, 0\n" + " lui v1, 14537\n" + " ori v1, v1, 4058\n" + " lui a2, 16128\n" + " lqc2 vf1, 0(a1)\n" + " qmtc2.i vf2, a2\n" + " vmulx.xyzw vf1, vf1, vf2\n" + " vftoi0.xyzw vf1, vf1\n" + " qmtc2.i vf2, v1\n" + " qmfc2.i v1, vf1\n" + " psllw v1, v1, 16\n" + " psraw v1, v1, 16\n" + " qmtc2.i vf1, v1\n" + " vitof0.xyzw vf1, vf1\n" + " vmulx.xyzw vf1, vf1, vf2\n" + " sqc2 vf1, 0(a0)\n" + " qmfc2.i v0, vf1\n" + " jr ra\n" + " daddu sp, sp, r0"; + std::string type = "(function vector vector none)"; + std::string expected = + "(defun test-function ((arg0 vector) (arg1 vector))\n" + " (local-vars (v0-0 float) (v1-1 uint128) (v1-2 uint128) (v1-3 uint128))\n" + " (rlet ((vf1 :class vf)\n" + " (vf2 :class vf)\n" + " )\n" + " (let ((v1-0 #x38c90fda))\n" + " (let ((a2-0 #x3f000000))\n" + " (.lvf vf1 (&-> arg1 quad))\n" + " (.mov vf2 a2-0)\n" + " )\n" + " (.mul.x.vf vf1 vf1 vf2)\n" + " (.ftoi.vf vf1 vf1)\n" + " (.mov vf2 v1-0)\n" + " )\n" + " (.mov v1-1 vf1)\n" + " (.pw.sll v1-2 v1-1 16)\n" + " (.pw.sra v1-3 v1-2 16)\n" + " (.mov vf1 v1-3)\n" + " (.itof.vf vf1 vf1)\n" + " (.mul.x.vf vf1 vf1 vf2)\n" + " (.svf (&-> arg0 quad) vf1)\n" + " (.mov v0-0 vf1)\n" + " (none)\n" + " )\n" + " )"; + test_final_function(func, type, expected); +} \ No newline at end of file diff --git a/test/decompiler/test_InstructionParser.cpp b/test/decompiler/test_InstructionParser.cpp index d8a2f486e5..632e7b46fb 100644 --- a/test/decompiler/test_InstructionParser.cpp +++ b/test/decompiler/test_InstructionParser.cpp @@ -41,11 +41,27 @@ TEST(DecompilerInstructionParser, ProgramLabels) { EXPECT_EQ(result.print(), program); } -TEST(DecompilerInstructionParser, VU) { +TEST(DecompilerInstructionParser, VuMask) { InstructionParser parser; std::string program = " vmove.xy vf1, vf2\n" " vsub.yw vf1, vf2, vf25\n"; auto result = parser.parse_program(program); EXPECT_EQ(result.print(), program); +} + +TEST(DecompilerInstructionParser, VuMoves) { + InstructionParser parser; + std::string program = + " qmtc2.i vf2, a2\n" + " qmfc2.i v0, vf1\n"; + auto result = parser.parse_program(program); + EXPECT_EQ(result.print(), program); +} + +TEST(DecompilerInstructionParser, VuBroadcast) { + InstructionParser parser; + std::string program = " vmuly.xyw vf1, vf1, vf2\n"; + auto result = parser.parse_program(program); + EXPECT_EQ(result.print(), program); } \ No newline at end of file diff --git a/test/goalc/source_templates/with_game/test-pand-por-pnor.gc b/test/goalc/source_templates/with_game/test-pand-por-pnor.gc new file mode 100644 index 0000000000..e25d6a1c7e --- /dev/null +++ b/test/goalc/source_templates/with_game/test-pand-por-pnor.gc @@ -0,0 +1,51 @@ + +(let ((v1 (new 'stack 'array 'uint8 16)) + (v2 (new 'stack 'array 'uint8 16)) + (v3 (new 'stack 'array 'uint8 16)) + ) + + ;; initialize stack arrays + (dotimes (i 16) + (set! (-> v1 i) i) + (set! (-> v2 i) (+ i 3)) + ) + (let ((v1-quad (-> (the (pointer uint128) v1))) + (v2-quad (-> (the (pointer uint128) v2))) + (v3-quad (the uint128 0)) + ) + + (.por v3-quad v1-quad v2-quad) + ;;(print128 v1-quad) (format #t "~%") + ;;(print128 v2-quad) (format #t "~%") + (print128 v3-quad) (format #t "~%") + + (.pnor v3-quad v1-quad v2-quad) + ;;(print128 v1-quad) (format #t "~%") + ;;(print128 v2-quad) (format #t "~%") + (print128 v3-quad) (format #t "~%") + + (.pand v3-quad v1-quad v2-quad) + ;;(print128 v1-quad) (format #t "~%") + ;;(print128 v2-quad) (format #t "~%") + (print128 v3-quad) (format #t "~%~%") + + (format #t "#x") + (countdown (i 16) + (format #t "~02x" (logand #xff (logior (-> v1 i) (-> v2 i)))) + ) + (format #t "~%") + + (format #t "#x") + (countdown (i 16) + (format #t "~02x" (logand #xff (lognor (-> v1 i) (-> v2 i)))) + ) + (format #t "~%") + + (format #t "#x") + (countdown (i 16) + (format #t "~02x" (logand #xff (logand (-> v1 i) (-> v2 i)))) + ) + (format #t "~%") + + ) + ) diff --git a/test/goalc/test_with_game.cpp b/test/goalc/test_with_game.cpp index 02c012d3d5..43aed8bdd4 100644 --- a/test/goalc/test_with_game.cpp +++ b/test/goalc/test_with_game.cpp @@ -805,6 +805,17 @@ TEST_F(WithGameTests, RaySphere) { "Got -100000000.0000\n0\n"}); } +TEST_F(WithGameTests, PandPorPnor) { + runner.run_static_test(env, testCategory, "test-pand-por-pnor.gc", + {"#x1f1f1d0f0f0f0d0b0f0f0d0707070503\n" + "#xe0e0e2f0f0f0f2f4f0f0f2f8f8f8fafc\n" + "#x0200000c0a0808080200000402000000\n" + "\n" + "#x1f1f1d0f0f0f0d0b0f0f0d0707070503\n" + "#xe0e0e2f0f0f0f2f4f0f0f2f8f8f8fafc\n" + "#x0200000c0a0808080200000402000000\n0\n"}); +} + TEST(TypeConsistency, TypeConsistency) { Compiler compiler; compiler.enable_throw_on_redefines(); diff --git a/test/offline/offline_test_main.cpp b/test/offline/offline_test_main.cpp index ebdc133878..b05eb043ea 100644 --- a/test/offline/offline_test_main.cpp +++ b/test/offline/offline_test_main.cpp @@ -100,11 +100,9 @@ const std::unordered_set g_functions_to_skip_compiling = { "rand-vu-nostep", // random hardware // trig - "sin-rad", // fpu acc - "cos-rad", // fpu acc - "atan-series-rad", // fpu acc - "vector-rad<-vector-deg!", // bad decisions on float vs int128 - "vector-rad<-vector-deg/2!", // bad decisions on float vs int128 + "sin-rad", // fpu acc + "cos-rad", // fpu acc + "atan-series-rad", // fpu acc /// VECTOR-H "(method 3 vector)", // this function appears twice, which confuses the compiler. @@ -121,10 +119,6 @@ const std::unordered_set g_functions_to_skip_compiling = { // display-h "put-draw-env", - // vector - // bad decisions on float vs int128 - "vector-degf", "vector-degmod", "vector-deg-diff", "vector-degi", - // geometry "calculate-basis-functions-vector!", // asm requiring manual rewrite "curve-evaluate!", // asm requiring manual rewrite @@ -153,6 +147,12 @@ const std::unordered_set g_functions_to_skip_compiling = { // aligner - return-from-thread, currently not supported "(method 9 align-control)", + // stat collection + "start-perf-stat-collection", "end-perf-stat-collection", + + // float to int + "(method 10 bsp-header)", + // loader - decompiler bug with detecting handle macros "(method 10 external-art-buffer)"}; diff --git a/test/test_emitter_avx.cpp b/test/test_emitter_avx.cpp index fbd9882ba0..c6664ea9da 100644 --- a/test/test_emitter_avx.cpp +++ b/test/test_emitter_avx.cpp @@ -521,4 +521,49 @@ TEST(EmitterAVX, VPSUBD) { tester.emit(IGen::vpsubd(XMM0 + 13, XMM0 + 13, XMM0 + 13)); EXPECT_EQ(tester.dump_to_hex_string(true), "C5E1FADBC4C161FADDC591FADBC4C111FADDC561FAEBC44161FAEDC511FAEBC44111FAED"); +} + +TEST(EmitterAVX, VPOR) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::parallel_bitwise_or(XMM0 + 3, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::parallel_bitwise_or(XMM0 + 3, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::parallel_bitwise_or(XMM0 + 3, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::parallel_bitwise_or(XMM0 + 3, XMM0 + 13, XMM0 + 13)); + tester.emit(IGen::parallel_bitwise_or(XMM0 + 13, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::parallel_bitwise_or(XMM0 + 13, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::parallel_bitwise_or(XMM0 + 13, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::parallel_bitwise_or(XMM0 + 13, XMM0 + 13, XMM0 + 13)); + EXPECT_EQ(tester.dump_to_hex_string(true), + "C5E1EBDBC4C161EBDDC591EBDBC4C111EBDDC561EBEBC44161EBEDC511EBEBC44111EBED"); +} + +TEST(EmitterAVX, VPXOR) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::parallel_bitwise_xor(XMM0 + 3, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::parallel_bitwise_xor(XMM0 + 3, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::parallel_bitwise_xor(XMM0 + 3, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::parallel_bitwise_xor(XMM0 + 3, XMM0 + 13, XMM0 + 13)); + tester.emit(IGen::parallel_bitwise_xor(XMM0 + 13, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::parallel_bitwise_xor(XMM0 + 13, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::parallel_bitwise_xor(XMM0 + 13, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::parallel_bitwise_xor(XMM0 + 13, XMM0 + 13, XMM0 + 13)); + EXPECT_EQ(tester.dump_to_hex_string(true), + "C5E1EFDBC4C161EFDDC591EFDBC4C111EFDDC561EFEBC44161EFEDC511EFEBC44111EFED"); +} + +TEST(EmitterAVX, VPAND) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::parallel_bitwise_and(XMM0 + 3, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::parallel_bitwise_and(XMM0 + 3, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::parallel_bitwise_and(XMM0 + 3, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::parallel_bitwise_and(XMM0 + 3, XMM0 + 13, XMM0 + 13)); + tester.emit(IGen::parallel_bitwise_and(XMM0 + 13, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::parallel_bitwise_and(XMM0 + 13, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::parallel_bitwise_and(XMM0 + 13, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::parallel_bitwise_and(XMM0 + 13, XMM0 + 13, XMM0 + 13)); + EXPECT_EQ(tester.dump_to_hex_string(true), + "C5E1DBDBC4C161DBDDC591DBDBC4C111DBDDC561DBEBC44161DBEDC511DBEBC44111DBED"); } \ No newline at end of file diff --git a/test/test_goos.cpp b/test/test_goos.cpp index 5064ea4d72..7d363428e6 100644 --- a/test/test_goos.cpp +++ b/test/test_goos.cpp @@ -1102,6 +1102,8 @@ TEST(GoosObject, String) { Object obj2 = StringObject::make_new("test2"); Object obj3 = StringObject::make_new("test1"); + Object obj4 = StringObject::make_new("test-with\"quote"); + EXPECT_TRUE(obj1.is_string()); EXPECT_TRUE(obj1 == obj3); @@ -1112,6 +1114,7 @@ TEST(GoosObject, String) { EXPECT_EQ(obj1.print(), "\"test1\""); EXPECT_EQ(obj1.inspect(), "[string] \"test1\"\n"); + EXPECT_EQ(obj4.print(), "\"test-with\\\"quote\""); } /*!