[jak3] prim rendering for cloth (#3607)
Some checks are pending
Build / 🖥️ Windows (push) Waiting to run
Build / 🐧 Linux (push) Waiting to run
Build / 🍎 MacOS (push) Waiting to run
Inform Pages Repo / Generate Documentation (push) Waiting to run
Lint / 📝 Required Checks (push) Waiting to run
Lint / 📝 Optional Checks (push) Waiting to run
Lint / 📝 Formatting (push) Waiting to run

This commit is contained in:
water111 2024-07-26 20:31:32 -04:00 committed by GitHub
parent f0b46ff2e5
commit 82a23c747e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 4833 additions and 83 deletions

View file

@ -4,7 +4,7 @@
#include "fmt/core.h"
std::string DmaTag::print() {
std::string DmaTag::print() const {
std::string result;
const char* mode_names[8] = {"refe", "cnt", "next", "ref", "refs", "call", "ret", "end"};
result += fmt::format("TAG: 0x{:08x} {:4s} qwc 0x{:04x}", addr, mode_names[(int)kind], qwc);
@ -15,7 +15,7 @@ std::string DmaTag::print() {
return result;
}
std::string VifCode::print() {
std::string VifCode::print() const {
std::string result;
switch (kind) {

View file

@ -52,7 +52,7 @@ struct DmaTag {
bool operator!=(const DmaTag& other) const { return !((*this) == other); }
std::string print();
std::string print() const;
};
inline void emulate_dma(const void* source_base, void* dest_base, u32 tadr, u32 dadr) {
@ -148,7 +148,7 @@ struct VifCode {
u16 num;
u16 immediate;
std::string print();
std::string print() const;
};
struct VifCodeStcycl {

View file

@ -15147,8 +15147,8 @@
:size-assert #x4
:flag-assert #xb00000004
(:methods
(init! (_type_) int) ;; 9
(cloth-base-method-10 (_type_ cloth-params handle) int) ;; 10
(update! (_type_) int) ;; 9
(setup-from-params! (_type_ cloth-params handle) int) ;; 10
)
)
@ -33950,7 +33950,7 @@
)
(deftype particle-array (inline-array-class)
((data verlet-particle :dynamic :inline :offset-assert 16)
((data verlet-particle :dynamic :inline :offset-assert 16 :score 1)
)
:method-count-assert 14
:size-assert #x10
@ -34017,12 +34017,12 @@
:size-assert #x40
:flag-assert #x1000000040
(:methods
(calculate-wind!
(accumulate-external-forces!
"If this cloth system has the wind flag, calculate the wind force."
(_type_) none) ;; 11
(verlet-particle-system-method-12 (_type_ float) none) ;; 12
(verlet-particle-system-method-13 (_type_) none) ;; 13
(verlet-particle-system-method-14 (_type_) none) ;; 14
(compute-verlet-step (_type_ float) none) ;; 12
(run-one-iteration "Run one iteration of the system." (_type_) none) ;; 13
(reset! "Reset to stationary/default state." (_type_) none) ;; 14
(debug-draw (_type_) none) ;; 15
)
)
@ -34082,9 +34082,9 @@
"Set up this cloth system with the given [[cloth-params]]."
(_type_ cloth-params) none) ;; 16
(debug-draw-spheres (_type_) none) ;; 17
(cloth-system-method-18 (_type_) int) ;; 18
(cloth-system-method-19 (_type_) none) ;; 19
(cloth-system-method-20 (_type_) none) ;; 20
(post-physics-update (_type_) int) ;; 18
(enforce-constraints-1 (_type_) none) ;; 19
(enforce-constraints-2 (_type_) none) ;; 20
(cloth-system-method-21 (_type_) none) ;; 21
(cloth-system-method-22 (_type_) none) ;; 22
(cloth-system-method-23 (_type_) none) ;; 23
@ -34098,9 +34098,9 @@
(cloth-system-method-31 (_type_ current-position-info) none) ;; 31
(cloth-system-method-32 (_type_ vector int int current-position-info) none) ;; 32
(cloth-system-method-33 (_type_ vu-lights) none) ;; 33
(cloth-system-method-34 (_type_) none) ;; 34
(cloth-system-method-35 (_type_) none) ;; 35
(cloth-system-method-36 (_type_) none) ;; 36
(hide! (_type_) none) ;; 34
(reset-locations (_type_) none) ;; 35
(pre-physics-update "Callback to update prior to running verlet integration. Can handle movement of the entire system in the world, for example" (_type_) none) ;; 36
(cloth-system-cmd-handler (_type_ pair) none) ;; 37
)
)
@ -34122,8 +34122,8 @@
;; cloth ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-extern get-neighboring-faces (function vector int int int int int))
(define-extern *normal-array* (pointer vector))
(define-extern get-neighboring-faces (function vector4w int int int int int))
(define-extern *normal-array* (inline-array vector))
(define-extern light-vertex (function current-position-info vector rgba))
(define-extern *once* symbol)
(define-extern *cloth-fade-alpha* gs-alpha)

View file

@ -2576,7 +2576,6 @@ void CallOp::propagate_types2(types2::Instruction& instr,
if (can_use_call_parent) {
out_types[Register(Reg::GPR, Reg::V0)]->type = TP_Type::make_from_ts(call_parent_result_type);
lg::print("used special {}\n", call_parent_result_type.print());
use_normal_last_arg = false;
}
}

View file

@ -201,6 +201,7 @@ set(RUNTIME_SOURCE
mips2c/jak3_functions/sky.cpp
mips2c/jak3_functions/texture.cpp
mips2c/jak3_functions/particle_curves.cpp
mips2c/jak3_functions/cloth.cpp
mips2c/jak3_functions/collide_cache.cpp
mips2c/jak3_functions/collide_hash.cpp
mips2c/jak3_functions/collide_edge_grab.cpp

View file

@ -579,6 +579,7 @@ u32 get_direct_qwc_or_nop(const VifCode& code) {
return code.immediate;
}
default:
printf("expected direct, got %s\n", code.print().c_str());
ASSERT(false);
}
}

View file

@ -267,6 +267,11 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
GET_BUCKET_ID_FOR_LIST(BucketId::GMERC_L0_PRIS, BucketId::GMERC_L1_PRIS, i), m_generic2,
Generic2::Mode::NORMAL);
init_bucket_renderer<Generic2BucketRenderer>(
fmt::format("gmerc2-l{}-pris", i), BucketCategory::GENERIC,
GET_BUCKET_ID_FOR_LIST(BucketId::GMERC2_L0_PRIS, BucketId::GMERC2_L1_PRIS, i), m_generic2,
Generic2::Mode::PRIM);
init_bucket_renderer<Merc2BucketRenderer>(
fmt::format("merc-l{}-pris2", i), BucketCategory::MERC,
GET_BUCKET_ID_FOR_LIST(BucketId::MERC_L0_PRIS2, BucketId::MERC_L1_PRIS2, i), m_merc2);
@ -274,6 +279,10 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
fmt::format("gmerc-l{}-pris2", i), BucketCategory::GENERIC,
GET_BUCKET_ID_FOR_LIST(BucketId::GMERC_L0_PRIS2, BucketId::GMERC_L1_PRIS2, i), m_generic2,
Generic2::Mode::NORMAL);
init_bucket_renderer<Generic2BucketRenderer>(
fmt::format("gmerc2-l{}-pris2", i), BucketCategory::GENERIC,
GET_BUCKET_ID_FOR_LIST(BucketId::GMERC2_L0_PRIS2, BucketId::GMERC2_L1_PRIS2, i),
m_generic2, Generic2::Mode::PRIM);
}
// 401
@ -285,6 +294,10 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
BucketId::GMERC_LCOM_PRIS, m_generic2,
Generic2::Mode::NORMAL);
init_bucket_renderer<Generic2BucketRenderer>("gmerc2-lcom-pris", BucketCategory::GENERIC,
BucketId::GMERC2_LCOM_PRIS, m_generic2,
Generic2::Mode::PRIM);
// 461
init_bucket_renderer<TextureUploadHandler>("tex-lcom-sky-post", BucketCategory::TEX,
BucketId::TEX_LCOM_SKY_POST, m_texture_animator);
@ -317,11 +330,20 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
BucketId::TEX_LCOM_WATER, m_texture_animator);
init_bucket_renderer<Merc2BucketRenderer>("merc-lcom-water", BucketCategory::MERC,
BucketId::MERC_LCOM_WATER, m_merc2);
init_bucket_renderer<Generic2BucketRenderer>("generic2-lcom-water", BucketCategory::GENERIC,
BucketId::GMERC2_LCOM_WATER, m_generic2,
Generic2::Mode::PRIM);
// 568
init_bucket_renderer<TextureUploadHandler>("tex-sprite", BucketCategory::TEX,
BucketId::TEX_SPRITE, m_texture_animator);
init_bucket_renderer<Generic2BucketRenderer>("generic-sprite-1", BucketCategory::GENERIC,
BucketId::GENERIC_SPRITE_1, m_generic2,
Generic2::Mode::PRIM);
init_bucket_renderer<Sprite3>("particles", BucketCategory::SPRITE, BucketId::PARTICLES);
init_bucket_renderer<Generic2BucketRenderer>("generic-sprite-2", BucketCategory::GENERIC,
BucketId::GENERIC_SPRITE_2, m_generic2,
Generic2::Mode::PRIM);
init_bucket_renderer<Generic2BucketRenderer>("generic-sprite-3", BucketCategory::OTHER,
BucketId::GENERIC_SPRITE_3, m_generic2,
Generic2::Mode::LIGHTNING);

View file

@ -70,6 +70,9 @@ void Generic2::render_in_mode(DmaFollower& dma,
case Mode::LIGHTNING:
process_dma_lightning(dma, render_state->next_bucket);
break;
case Mode::PRIM:
process_dma_prim(dma, render_state->next_bucket);
break;
default:
ASSERT_NOT_REACHED();
}
@ -83,6 +86,7 @@ void Generic2::render_in_mode(DmaFollower& dma,
auto p = prof.make_scoped_child("setup");
switch (mode) {
case Mode::NORMAL:
case Mode::PRIM:
setup_draws(true, true);
break;
case Mode::LIGHTNING:

View file

@ -11,7 +11,7 @@ class Generic2 {
u32 num_buckets = 800);
~Generic2();
enum class Mode { NORMAL, LIGHTNING, WARP };
enum class Mode { NORMAL, LIGHTNING, WARP, PRIM };
void render_in_mode(DmaFollower& dma,
SharedRenderState* render_state,
@ -43,6 +43,7 @@ class Generic2 {
void process_dma_jak1(DmaFollower& dma, u32 next_bucket);
void process_dma_lightning(DmaFollower& dma, u32 next_bucket);
void process_dma_jak2(DmaFollower& dma, u32 next_bucket);
void process_dma_prim(DmaFollower& dma, u32 next_bucket);
void setup_draws(bool enable_at, bool default_fog);
void do_draws(SharedRenderState* render_state, ScopedProfilerNode& prof);
void do_draws_for_alpha(SharedRenderState* render_state,
@ -85,6 +86,8 @@ class Generic2 {
float hud_mat_23, hud_mat_32, hud_mat_33;
bool uses_hud = false;
bool uses_full_matrix = false;
math::Vector4f full_matrix[4];
} m_drawing_config;
struct GsState {
@ -199,7 +202,7 @@ class Generic2 {
GLuint vertex_buffer;
GLuint index_buffer;
GLuint alpha_reject, color_mult, fog_color, scale, mat_23, mat_32, mat_33, fog_consts,
hvdf_offset;
hvdf_offset, use_full_matrix, full_matrix;
GLuint gfx_hack_no_tex;
GLuint warp_sample_mode;
} m_ogl;

View file

@ -271,6 +271,10 @@ void Generic2::process_matrices() {
bool found_proj_matrix = false;
std::array<math::Vector4f, 4> projection_matrix, hud_matrix;
for (u32 i = 0; i < m_next_free_frag; i++) {
if (m_drawing_config.uses_full_matrix) {
memcpy(&m_drawing_config.full_matrix, m_fragments[i].header, 64);
break;
}
float mat_33;
memcpy(&mat_33, m_fragments[i].header + 15 * sizeof(float), sizeof(float));
if (mat_33 == 0) {

View file

@ -550,6 +550,83 @@ void unpack_vertex(Generic2::Vertex* out, const u8* in, int count) {
}
}
void Generic2::process_dma_prim(DmaFollower& dma, u32 next_bucket) {
reset_buffers();
auto first_data = dma.read_and_advance();
// handle the stuff at the beginning.
// if the engine didn't run the generic renderer setup function, this bucket will end here.
if (is_nop_zero(first_data) && next_bucket == dma.current_tag_offset()) {
return;
}
// MARK NOP (for profiling)
auto v0k = first_data.vifcode0().kind;
ASSERT((v0k == VifCode::Kind::MARK || v0k == VifCode::Kind::NOP) &&
first_data.vifcode1().kind == VifCode::Kind::NOP);
// NOP DIRECT (set up GS, from generic setup)
auto direct_setup = dma.read_and_advance();
ASSERT(direct_setup.size_bytes == 32 && direct_setup.vifcode0().kind == VifCode::Kind::NOP &&
direct_setup.vifcode1().kind == VifCode::Kind::DIRECT);
m_drawing_config.zmsk = false;
m_drawing_config.uses_full_matrix = true;
// STYCYCL to set up generic VU1 constants
auto constants = dma.read_and_advance();
ASSERT(constants.size_bytes == 128);
ASSERT(constants.vifcode0().kind == VifCode::Kind::STCYCL);
ASSERT(constants.vifcode1().kind == VifCode::Kind::UNPACK_V4_32);
memcpy(&m_drawing_config.pfog0, constants.data + 0, 4);
memcpy(&m_drawing_config.fog_min, constants.data + 4, 4);
memcpy(&m_drawing_config.fog_max, constants.data + 8, 4);
memcpy(m_drawing_config.hvdf_offset.data(), constants.data + 32, 16);
// 32: MSCALF 0x0 STMOD 0b0 init generic VU1
auto mscalf = dma.read_and_advance();
ASSERT(mscalf.vifcode0().kind == VifCode::Kind::MSCALF &&
mscalf.vifcode1().kind == VifCode::Kind::STMOD);
// 0: NOP NOP
// auto another_nop = dma.read_and_advance();
// ASSERT(is_nop_zero(another_nop));
while (dma.current_tag_offset() != next_bucket) {
auto up1 = dma.read_and_advance();
while (up1.vifcode0().kind == VifCode::Kind::NOP && up1.vifcode1().kind == VifCode::Kind::NOP) {
up1 = dma.read_and_advance();
}
if (up1.vifcode0().kind == VifCode::Kind::FLUSHA) {
while (dma.current_tag_offset() != next_bucket) {
auto it = dma.read_and_advance();
}
break;
}
auto up2 = dma.read_and_advance();
auto call = dma.read_and_advance();
// up1 is a 12 qw upload for control:
// up2 is vertex upload.
auto* frag = &next_frag();
ASSERT(up1.size_bytes == Generic2::FRAG_HEADER_SIZE + 5 * 16); // header + adgif
memcpy(frag->header, up1.data, Generic2::FRAG_HEADER_SIZE);
frag->adgif_idx = m_next_free_adgif;
frag->adgif_count = 1;
frag->mscal_addr = 6;
frag->uses_hud = false;
auto* adgif = &next_adgif();
memcpy(&adgif->data, up1.data + Generic2::FRAG_HEADER_SIZE, sizeof(AdGifData));
// (new 'static 'gif-tag-regs-32 :regs0 (gif-reg-id st) :regs1 (gif-reg-id rgbaq) :regs2
// (gif-reg-id xyzf2))
int num_vtx = up2.size_bytes / (16 * 3);
frag->vtx_count = num_vtx;
frag->vtx_idx = m_next_free_vert;
alloc_vtx(num_vtx);
unpack_vertex(&m_verts[frag->vtx_idx], up2.data, num_vtx);
}
}
void Generic2::process_dma_lightning(DmaFollower& dma, u32 next_bucket) {
reset_buffers();
auto first_data = dma.read_and_advance();

View file

@ -74,6 +74,8 @@ void Generic2::opengl_setup(ShaderLibrary& shaders) {
m_ogl.hvdf_offset = glGetUniformLocation(id, "hvdf_offset");
m_ogl.gfx_hack_no_tex = glGetUniformLocation(id, "gfx_hack_no_tex");
m_ogl.warp_sample_mode = glGetUniformLocation(id, "warp_sample_mode");
m_ogl.use_full_matrix = glGetUniformLocation(id, "use_full_matrix");
m_ogl.full_matrix = glGetUniformLocation(id, "full_matrix");
}
void Generic2::opengl_cleanup() {
@ -307,6 +309,12 @@ void Generic2::do_draws(SharedRenderState* render_state, ScopedProfilerNode& pro
glPrimitiveRestartIndex(UINT32_MAX);
opengl_bind_and_setup_proj(render_state);
if (m_drawing_config.uses_full_matrix) {
glUniform1i(m_ogl.use_full_matrix, 1);
glUniformMatrix4fv(m_ogl.full_matrix, 1, GL_FALSE, m_drawing_config.full_matrix[0].data());
} else {
glUniform1i(m_ogl.use_full_matrix, 0);
}
constexpr DrawMode::AlphaBlend alpha_order[ALPHA_MODE_COUNT] = {
DrawMode::AlphaBlend::SRC_0_FIX_DST, DrawMode::AlphaBlend::SRC_SRC_SRC_SRC,
DrawMode::AlphaBlend::SRC_DST_SRC_DST, DrawMode::AlphaBlend::SRC_0_SRC_DST,

View file

@ -768,9 +768,7 @@ void Merc2::switch_to_emerc(SharedRenderState* render_state) {
void Merc2::render(DmaFollower& dma,
SharedRenderState* render_state,
ScopedProfilerNode& prof,
MercDebugStats* stats,
bool debug) {
m_debug = true;
MercDebugStats* stats) {
bool hack = stats->collect_debug_model_list;
*stats = {};
stats->collect_debug_model_list = hack;

View file

@ -46,8 +46,7 @@ class Merc2 {
void render(DmaFollower& dma,
SharedRenderState* render_state,
ScopedProfilerNode& prof,
MercDebugStats* stats,
bool debug);
MercDebugStats* stats);
static constexpr int kMaxBlerc = 40;
private:
@ -139,7 +138,6 @@ class Merc2 {
};
Uniforms m_merc_uniforms, m_emerc_uniforms;
bool m_debug = false;
void init_shader_common(Shader& shader, Uniforms* uniforms, bool include_lights);
void handle_setup_dma(DmaFollower& dma, SharedRenderState* render_state);

View file

@ -16,7 +16,7 @@ void Merc2BucketRenderer::render(DmaFollower& dma,
return;
}
m_renderer->render(dma, render_state, prof, &m_debug_stats, m_my_id == 362);
m_renderer->render(dma, render_state, prof, &m_debug_stats);
m_empty = m_debug_stats.num_predicted_draws == 0;
}

View file

@ -10,6 +10,8 @@ uniform vec3 fog_constants;
uniform vec4 scale;
uniform float mat_23;
uniform float mat_33;
uniform bool use_full_matrix;
uniform mat4 full_matrix;
uniform vec4 hvdf_offset;
uniform uint warp_sample_mode;
@ -38,11 +40,17 @@ void main() {
// maddax.xyzw ACC, vf08, vf16 matrix multiply X
// vu.acc.madda(Mask::xyzw, gen.mat0, gen.vtx_load0.x());
transformed.xyz = position_in * scale.xyz;
transformed.z += mat_32;
transformed.w = mat_23 * position_in.z + mat_33;
transformed *= -1; // todo?
if (use_full_matrix) {
transformed = -full_matrix[3];
transformed -= full_matrix[0] * position_in.x ;
transformed -= full_matrix[1] * position_in.y;
transformed -= full_matrix[2] * position_in.z ;
} else {
transformed.xyz = position_in * scale.xyz;
transformed.z += mat_32;
transformed.w = mat_23 * position_in.z + mat_33;
transformed *= -1;
}
// div Q, vf01.x, vf12.w perspective divide

View file

@ -0,0 +1,220 @@
//--------------------------MIPS2C---------------------
// clang-format off
#include "game/mips2c/mips2c_private.h"
#include "game/kernel/jak3/kscheme.h"
using ::jak3::intern_from_c;
namespace Mips2C::jak3 {
namespace method_21_cloth_system {
u64 execute(void* ctxt) {
auto* c = (ExecutionContext*)ctxt;
bool bc = false;
u32 call_addr = 0;
c->daddiu(sp, sp, -80); // daddiu sp, sp, -80
c->daddiu(a3, sp, 16); // daddiu a3, sp, 16
c->daddiu(t0, sp, 32); // daddiu t0, sp, 32
c->lwu(v1, 68, a0); // lwu v1, 68(a0)
c->lw(v1, 0, v1); // lw v1, 0(v1)
c->lw(a1, 96, a0); // lw a1, 96(a0)
c->daddiu(a1, a1, -1); // daddiu a1, a1, -1
c->lw(a2, 100, a0); // lw a2, 100(a0)
c->daddiu(a2, a2, -1); // daddiu a2, a2, -1
c->addiu(t1, r0, 0); // addiu t1, r0, 0
c->addiu(t1, r0, 0); // addiu t1, r0, 0
c->mov64(t1, a3); // or t1, a3, r0
c->lui(t2, 16000); // lui t2, 16000
c->mtc1(f0, t2); // mtc1 f0, t2
c->swc1(f0, 0, t1); // swc1 f0, 0(t1)
c->lui(t2, 16000); // lui t2, 16000
c->mtc1(f0, t2); // mtc1 f0, t2
c->swc1(f0, 4, t1); // swc1 f0, 4(t1)
c->lui(t2, 16000); // lui t2, 16000
c->mtc1(f0, t2); // mtc1 f0, t2
c->swc1(f0, 8, t1); // swc1 f0, 8(t1)
c->lui(t2, 16000); // lui t2, 16000
c->mtc1(f0, t2); // mtc1 f0, t2
c->swc1(f0, 12, t1); // swc1 f0, 12(t1)
c->mov64(t1, t0); // or t1, t0, r0
c->mtc1(f0, r0); // mtc1 f0, r0
c->swc1(f0, 0, t1); // swc1 f0, 0(t1)
c->mtc1(f0, r0); // mtc1 f0, r0
c->swc1(f0, 4, t1); // swc1 f0, 4(t1)
c->mtc1(f0, r0); // mtc1 f0, r0
c->swc1(f0, 8, t1); // swc1 f0, 8(t1)
c->lwc1(f0, 144, a0); // lwc1 f0, 144(a0)
c->swc1(f0, 12, t1); // swc1 f0, 12(t1)
c->vmax_bc(DEST::xyzw, BC::w, vf1, vf0, vf0); // vmaxw.xyzw vf1, vf0, vf0
c->lqc2(vf10, 0, a3); // lqc2 vf10, 0(a3)
c->lqc2(vf15, 0, t0); // lqc2 vf15, 0(t0)
c->sd(r0, 48, sp); // sd r0, 48(sp)
c->addiu(a3, r0, 0); // addiu a3, r0, 0
//beq r0, r0, L187 // beq r0, r0, L187
// nop // sll r0, r0, 0
goto block_10; // branch always
block_1:
c->addiu(t0, r0, 0); // addiu t0, r0, 0
//beq r0, r0, L186 // beq r0, r0, L186
// nop // sll r0, r0, 0
goto block_8; // branch always
block_2:
c->addiu(t1, r0, 48); // addiu t1, r0, 48
c->ld(t2, 48, sp); // ld t2, 48(sp)
c->mult3(t1, t1, t2); // mult3 t1, t1, t2
c->daddiu(t1, t1, 12); // daddiu t1, t1, 12
c->lwu(t2, 0, a0); // lwu t2, 0(a0)
c->daddu(t1, t1, t2); // daddu t1, t1, t2
c->sw(t1, 56, sp); // sw t1, 56(sp)
c->addiu(t1, r0, 48); // addiu t1, r0, 48
c->ld(t2, 48, sp); // ld t2, 48(sp)
c->daddiu(t2, t2, 1); // daddiu t2, t2, 1
c->mult3(t1, t1, t2); // mult3 t1, t1, t2
c->daddiu(t1, t1, 12); // daddiu t1, t1, 12
c->lwu(t2, 0, a0); // lwu t2, 0(a0)
c->daddu(t1, t1, t2); // daddu t1, t1, t2
c->sw(t1, 60, sp); // sw t1, 60(sp)
c->addiu(t1, r0, 48); // addiu t1, r0, 48
c->ld(t2, 48, sp); // ld t2, 48(sp)
c->lw(t3, 96, a0); // lw t3, 96(a0)
c->daddu(t2, t2, t3); // daddu t2, t2, t3
c->mult3(t1, t1, t2); // mult3 t1, t1, t2
c->daddiu(t1, t1, 12); // daddiu t1, t1, 12
c->lwu(t2, 0, a0); // lwu t2, 0(a0)
c->daddu(t1, t1, t2); // daddu t1, t1, t2
c->sw(t1, 64, sp); // sw t1, 64(sp)
c->addiu(t1, r0, 48); // addiu t1, r0, 48
c->lw(t2, 96, a0); // lw t2, 96(a0)
c->daddiu(t2, t2, 1); // daddiu t2, t2, 1
c->ld(t3, 48, sp); // ld t3, 48(sp)
c->daddu(t2, t2, t3); // daddu t2, t2, t3
c->mult3(t1, t1, t2); // mult3 t1, t1, t2
c->daddiu(t1, t1, 12); // daddiu t1, t1, 12
c->lwu(t2, 0, a0); // lwu t2, 0(a0)
c->daddu(t1, t1, t2); // daddu t1, t1, t2
c->sw(t1, 68, sp); // sw t1, 68(sp)
c->lwu(t1, 56, sp); // lwu t1, 56(sp)
c->lqc2(vf2, 0, t1); // lqc2 vf2, 0(t1)
c->lwu(t1, 68, sp); // lwu t1, 68(sp)
c->lqc2(vf5, 0, t1); // lqc2 vf5, 0(t1)
c->lwu(t1, 60, sp); // lwu t1, 60(sp)
c->lqc2(vf3, 0, t1); // lqc2 vf3, 0(t1)
c->lwu(t1, 64, sp); // lwu t1, 64(sp)
c->lqc2(vf4, 0, t1); // lqc2 vf4, 0(t1)
c->lwu(t1, 56, sp); // lwu t1, 56(sp)
c->lqc2(vf20, 32, t1); // lqc2 vf20, 32(t1)
c->lwu(t1, 68, sp); // lwu t1, 68(sp)
c->lqc2(vf23, 32, t1); // lqc2 vf23, 32(t1)
c->lwu(t1, 60, sp); // lwu t1, 60(sp)
c->lqc2(vf21, 32, t1); // lqc2 vf21, 32(t1)
c->lwu(t1, 64, sp); // lwu t1, 64(sp)
c->lqc2(vf22, 32, t1); // lqc2 vf22, 32(t1)
c->vmula_bc(DEST::xyzw, BC::x, vf2, vf20); // vmulax.xyzw acc, vf2, vf20
c->vmadda_bc(DEST::xyzw, BC::x, vf3, vf21); // vmaddax.xyzw acc, vf3, vf21
c->vmadda_bc(DEST::xyzw, BC::x, vf5, vf23); // vmaddax.xyzw acc, vf5, vf23
c->vmadd_bc(DEST::xyzw, BC::x, vf8, vf4, vf22); // vmaddx.xyzw vf8, vf4, vf22
c->vmul_bc(DEST::xyzw, BC::x, vf8, vf8, vf10); // vmulx.xyzw vf8, vf8, vf10
c->lwu(t1, 68, a0); // lwu t1, 68(a0)
c->daddiu(t1, t1, 12); // daddiu t1, t1, 12
c->addiu(t2, r0, 0); // addiu t2, r0, 0
//beq r0, r0, L185 // beq r0, r0, L185
// nop // sll r0, r0, 0
goto block_6; // branch always
block_3:
c->lqc2(vf11, 0, t1); // lqc2 vf11, 0(t1)
c->vsub(DEST::xyzw, vf13, vf8, vf11); // vsub.xyzw vf13, vf8, vf11
c->vmul(DEST::xyzw, vf9, vf13, vf13); // vmul.xyzw vf9, vf13, vf13
c->vmula_bc(DEST::xyzw, BC::x, vf1, vf9); // vmulax.xyzw acc, vf1, vf9
c->vmadda_bc(DEST::xyzw, BC::y, vf1, vf9); // vmadday.xyzw acc, vf1, vf9
c->vmadd_bc(DEST::xyzw, BC::z, vf14, vf1, vf9); // vmaddz.xyzw vf14, vf1, vf9
c->vadd_bc(DEST::w, BC::w, vf11, vf11, vf15); // vaddw.w vf11, vf11, vf15
c->vmul(DEST::xyzw, vf12, vf11, vf11); // vmul.xyzw vf12, vf11, vf11
c->vsub_bc(DEST::xyzw, BC::w, vf9, vf14, vf12); // vsubw.xyzw vf9, vf14, vf12
c->mov128_gpr_vf(t3, vf9); // qmfc2.i t3, vf9
bc = ((s64)c->sgpr64(t3)) >= 0; // bgez t3, L184
// nop // sll r0, r0, 0
if (bc) {goto block_5;} // branch non-likely
c->vrsqrt(vf11, BC::w, vf14, BC::x); // vrsqrt Q, vf11.w, vf14.x
c->vmax_bc(DEST::xyz, BC::x, vf20, vf0, vf20); // vmaxx.xyz vf20, vf0, vf20
c->vmax_bc(DEST::xyz, BC::x, vf21, vf0, vf21); // vmaxx.xyz vf21, vf0, vf21
c->vmax_bc(DEST::xyz, BC::x, vf22, vf0, vf22); // vmaxx.xyz vf22, vf0, vf22
c->vmax_bc(DEST::xyz, BC::x, vf23, vf0, vf23); // vmaxx.xyz vf23, vf0, vf23
c->vwaitq(); // vwaitq
// Unknown instr: vmulaq.xyzw acc, vf13, Q
c->vmula_q(DEST::xyzw, vf13);
c->vmsuba(DEST::xyzw, vf1, vf13); // vmsuba.xyzw acc, vf1, vf13
c->vmadd(DEST::xyzw, vf2, vf1, vf2); // vmadd.xyzw vf2, vf1, vf2
c->vmadd(DEST::xyzw, vf3, vf1, vf3); // vmadd.xyzw vf3, vf1, vf3
c->vmadd(DEST::xyzw, vf5, vf1, vf5); // vmadd.xyzw vf5, vf1, vf5
c->vmadd(DEST::xyzw, vf4, vf1, vf4); // vmadd.xyzw vf4, vf1, vf4
c->vmadd(DEST::xyzw, vf8, vf1, vf8); // vmadd.xyzw vf8, vf1, vf8
block_5:
c->daddiu(t1, t1, 16); // daddiu t1, t1, 16
c->daddiu(t2, t2, 1); // daddiu t2, t2, 1
block_6:
c->slt(t3, t2, v1); // slt t3, t2, v1
bc = c->sgpr64(t3) != 0; // bne t3, r0, L183
// nop // sll r0, r0, 0
if (bc) {goto block_3;} // branch non-likely
c->mov64(t1, s7); // or t1, s7, r0
c->mov64(t1, s7); // or t1, s7, r0
c->lwu(t1, 56, sp); // lwu t1, 56(sp)
c->sqc2(vf2, 0, t1); // sqc2 vf2, 0(t1)
c->lwu(t1, 68, sp); // lwu t1, 68(sp)
c->sqc2(vf5, 0, t1); // sqc2 vf5, 0(t1)
c->lwu(t1, 60, sp); // lwu t1, 60(sp)
c->sqc2(vf3, 0, t1); // sqc2 vf3, 0(t1)
c->lwu(t1, 64, sp); // lwu t1, 64(sp)
c->sqc2(vf4, 0, t1); // sqc2 vf4, 0(t1)
c->mov128_gpr_vf(t1, vf4); // qmfc2.i t1, vf4
c->ld(t1, 48, sp); // ld t1, 48(sp)
c->daddiu(t1, t1, 1); // daddiu t1, t1, 1
c->sd(t1, 48, sp); // sd t1, 48(sp)
c->daddiu(t0, t0, 1); // daddiu t0, t0, 1
block_8:
c->slt(t1, t0, a1); // slt t1, t0, a1
bc = c->sgpr64(t1) != 0; // bne t1, r0, L182
// nop // sll r0, r0, 0
if (bc) {goto block_2;} // branch non-likely
c->mov64(t0, s7); // or t0, s7, r0
c->mov64(t0, s7); // or t0, s7, r0
c->ld(t0, 48, sp); // ld t0, 48(sp)
c->daddiu(t0, t0, 1); // daddiu t0, t0, 1
c->sd(t0, 48, sp); // sd t0, 48(sp)
c->daddiu(a3, a3, 1); // daddiu a3, a3, 1
block_10:
c->slt(t0, a3, a2); // slt t0, a3, a2
bc = c->sgpr64(t0) != 0; // bne t0, r0, L181
// nop // sll r0, r0, 0
if (bc) {goto block_1;} // branch non-likely
c->mov64(v1, s7); // or v1, s7, r0
c->mov64(v0, s7); // or v0, s7, r0
//jr ra // jr ra
c->daddiu(sp, sp, 80); // daddiu sp, sp, 80
goto end_of_function; // return
// nop // sll r0, r0, 0
// nop // sll r0, r0, 0
// nop // sll r0, r0, 0
end_of_function:
return c->gprs[v0].du64[0];
}
void link() {
gLinkedFunctionTable.reg("(method 21 cloth-system)", execute, 256);
}
} // namespace method_21_cloth_system
} // namespace Mips2C

View file

@ -905,6 +905,16 @@ struct ExecutionContext {
}
}
void vmula_q(DEST mask, int src0) {
auto s0 = vf_src(src0);
for (int i = 0; i < 4; i++) {
if ((u64)mask & (1 << i)) {
acc.f[i] = s0.f[i] * Q;
}
}
}
void vadda_bc(DEST mask, BC bc, int src0, int src1) {
auto s0 = vf_src(src0);
auto s1 = vf_src(src1);

View file

@ -393,6 +393,7 @@ namespace shadow_add_double_edges { extern void link(); }
namespace shadow_add_single_tris { extern void link(); }
namespace shadow_add_double_tris { extern void link(); }
namespace shadow_execute { extern void link(); }
namespace method_21_cloth_system { extern void link(); }
}
// clang-format on
@ -654,7 +655,8 @@ PerGameVersion<std::unordered_map<std::string, std::vector<void (*)()>>> gMips2C
jak3::shadow_find_single_edges::link, jak3::shadow_find_double_edges::link,
jak3::shadow_add_verts::link, jak3::shadow_add_facing_single_tris::link,
jak3::shadow_add_single_edges::link, jak3::shadow_add_double_edges::link,
jak3::shadow_add_single_tris::link, jak3::shadow_add_double_tris::link}}}};
jak3::shadow_add_single_tris::link, jak3::shadow_add_double_tris::link}},
{"cloth", {jak3::method_21_cloth_system::link}}}};
void LinkedFunctionTable::reg(const std::string& name, u64 (*exec)(void*), u32 stack_size) {
const auto& it = m_executes.insert({name, {exec, Ptr<u8>()}});

View file

@ -146,7 +146,7 @@
(deftype cloth-base (basic)
()
(:methods
(init! (_type_) int)
(cloth-base-method-10 (_type_ cloth-params handle) int)
(update! (_type_) int)
(setup-from-params! (_type_ cloth-params handle) int)
)
)

View file

@ -6,11 +6,13 @@
;; dgos: GAME
(declare-type region-prim-list structure)
(declare-type draw-control structure)
(define-extern sphere-cull "Is this sphere visible? Uses cached camera matrix registers, so use with care." (function vector symbol))
(define-extern sphere-in-view-frustum? (function sphere symbol))
(define-extern line-in-view-frustum? (function vector vector symbol))
(define-extern vis-cull (function int symbol))
(define-extern calc-vu1-lights (function vu-lights draw-control symbol none))
;; DECOMP BEGINS

View file

@ -1458,7 +1458,7 @@
(shadow-execute-all gp-0)
)
(lightning-draw-all)
;(prim-engine-execute)
(prim-engine-execute)
(none)
)

View file

@ -117,10 +117,10 @@
(momentum vector :inline)
)
(:methods
(calculate-wind! (_type_) none)
(verlet-particle-system-method-12 (_type_ float) none)
(verlet-particle-system-method-13 (_type_) none)
(verlet-particle-system-method-14 (_type_) none)
(accumulate-external-forces! (_type_) none)
(compute-verlet-step (_type_ float) none)
(run-one-iteration (_type_) none)
(reset! (_type_) none)
(debug-draw (_type_) none)
)
)
@ -173,9 +173,9 @@
(:methods
(initialize-cloth-system! (_type_ cloth-params) none)
(debug-draw-spheres (_type_) none)
(cloth-system-method-18 (_type_) int)
(cloth-system-method-19 (_type_) none)
(cloth-system-method-20 (_type_) none)
(post-physics-update (_type_) int)
(enforce-constraints-1 (_type_) none)
(enforce-constraints-2 (_type_) none)
(cloth-system-method-21 (_type_) none)
(cloth-system-method-22 (_type_) none)
(cloth-system-method-23 (_type_) none)
@ -189,9 +189,9 @@
(cloth-system-method-31 (_type_ current-position-info) none)
(cloth-system-method-32 (_type_ vector int int current-position-info) none)
(cloth-system-method-33 (_type_ vu-lights) none)
(cloth-system-method-34 (_type_) none)
(cloth-system-method-35 (_type_) none)
(cloth-system-method-36 (_type_) none)
(hide! (_type_) none)
(reset-locations (_type_) none)
(pre-physics-update (_type_) none)
(cloth-system-cmd-handler (_type_ pair) none)
)
)

File diff suppressed because it is too large Load diff

View file

@ -414,7 +414,7 @@
(let ((proc (handle->process (-> gp-0 s4-0))))
(when proc
(dotimes (i (-> (the-as process-drawable proc) draw cloth-instances length))
(init! (-> (the-as process-drawable proc) draw cloth-instances i))
(update! (-> (the-as process-drawable proc) draw cloth-instances i))
)
)
)
@ -919,7 +919,7 @@
(set! (-> this draw cloth-instances length) (-> this draw cloth-instances allocated-length))
(dotimes (s4-4 (-> arg0 clothing length))
(set! (-> this draw cloth-instances s4-4) (new 'process 'cloth-on-skeleton))
(cloth-base-method-10 (-> this draw cloth-instances s4-4) (-> arg0 clothing s4-4) (process->handle this))
(setup-from-params! (-> this draw cloth-instances s4-4) (-> arg0 clothing s4-4) (process->handle this))
)
)
(logior! (-> this draw global-effect) (-> arg0 global-effects))
@ -2273,7 +2273,7 @@
)
(dotimes (i (-> proc draw cloth-instances length))
(if (not arg1)
(cloth-system-method-34 (-> proc draw cloth-instances i))
(hide! (-> proc draw cloth-instances i))
(logclear! (-> proc draw cloth-instances i flags) (cloth-flag hidden))
)
)

View file

@ -424,7 +424,7 @@
(case (-> self ext-geo)
(((target-geo jakc))
(dotimes (s5-1 (-> gp-1 clothing length))
(cloth-base-method-10 (-> self draw cloth-instances s5-1) (-> gp-1 clothing s5-1) (process->handle self))
(setup-from-params! (-> self draw cloth-instances s5-1) (-> gp-1 clothing s5-1) (process->handle self))
(logior! (-> self draw cloth-instances s5-1 flags) (cloth-flag need-reset active))
)
)

View file

@ -255,8 +255,8 @@
(deftype cloth-base (basic)
()
(:methods
(init! (_type_) int)
(cloth-base-method-10 (_type_ cloth-params handle) int)
(update! (_type_) int)
(setup-from-params! (_type_ cloth-params handle) int)
)
)
@ -273,7 +273,3 @@
;; failed to figure out what this is:
0

View file

@ -291,10 +291,10 @@
(momentum vector :inline)
)
(:methods
(calculate-wind! (_type_) none)
(verlet-particle-system-method-12 (_type_ float) none)
(verlet-particle-system-method-13 (_type_) none)
(verlet-particle-system-method-14 (_type_) none)
(accumulate-external-forces! (_type_) none)
(compute-verlet-step (_type_ float) none)
(run-one-iteration (_type_) none)
(reset! (_type_) none)
(debug-draw (_type_) none)
)
)
@ -388,9 +388,9 @@
(:methods
(initialize-cloth-system! (_type_ cloth-params) none)
(debug-draw-spheres (_type_) none)
(cloth-system-method-18 (_type_) int)
(cloth-system-method-19 (_type_) none)
(cloth-system-method-20 (_type_) none)
(post-physics-update (_type_) int)
(enforce-constraints-1 (_type_) none)
(enforce-constraints-2 (_type_) none)
(cloth-system-method-21 (_type_) none)
(cloth-system-method-22 (_type_) none)
(cloth-system-method-23 (_type_) none)
@ -404,9 +404,9 @@
(cloth-system-method-31 (_type_ current-position-info) none)
(cloth-system-method-32 (_type_ vector int int current-position-info) none)
(cloth-system-method-33 (_type_ vu-lights) none)
(cloth-system-method-34 (_type_) none)
(cloth-system-method-35 (_type_) none)
(cloth-system-method-36 (_type_) none)
(hide! (_type_) none)
(reset-locations (_type_) none)
(pre-physics-update (_type_) none)
(cloth-system-cmd-handler (_type_ pair) none)
)
)

File diff suppressed because it is too large Load diff

View file

@ -378,7 +378,7 @@
(let ((proc (handle->process (-> gp-0 s4-0))))
(when proc
(dotimes (i (-> (the-as process-drawable proc) draw cloth-instances length))
(init! (-> (the-as process-drawable proc) draw cloth-instances i))
(update! (-> (the-as process-drawable proc) draw cloth-instances i))
)
)
)
@ -898,7 +898,7 @@
(set! (-> this draw cloth-instances length) (-> this draw cloth-instances allocated-length))
(dotimes (s4-4 (-> arg0 clothing length))
(set! (-> this draw cloth-instances s4-4) (new 'process 'cloth-on-skeleton))
(cloth-base-method-10 (-> this draw cloth-instances s4-4) (-> arg0 clothing s4-4) (process->handle this))
(setup-from-params! (-> this draw cloth-instances s4-4) (-> arg0 clothing s4-4) (process->handle this))
)
)
(logior! (-> this draw global-effect) (-> arg0 global-effects))
@ -2312,7 +2312,7 @@
)
(dotimes (i (-> proc draw cloth-instances length))
(if (not arg1)
(cloth-system-method-34 (-> proc draw cloth-instances i))
(hide! (-> proc draw cloth-instances i))
(logclear! (-> proc draw cloth-instances i flags) (cloth-flag hidden))
)
)

View file

@ -427,7 +427,7 @@
(case (-> self ext-geo)
(((target-geo jakc))
(dotimes (s5-1 (-> gp-1 clothing length))
(cloth-base-method-10 (-> self draw cloth-instances s5-1) (-> gp-1 clothing s5-1) (process->handle self))
(setup-from-params! (-> self draw cloth-instances s5-1) (-> gp-1 clothing s5-1) (process->handle self))
(logior! (-> self draw cloth-instances s5-1 flags) (cloth-flag need-reset active))
)
)

View file

@ -384,7 +384,10 @@
// asm
"close-sky-buffer",
// protect-gunship
"find-reposition-pt"
"find-reposition-pt",
// asm
"(method 19 cloth-system)",
"(method 37 cloth-system)"
],
"skip_compile_states": {