diff --git a/decompiler/ObjectFile/ObjectFileDB_IR2.cpp b/decompiler/ObjectFile/ObjectFileDB_IR2.cpp index 204d795add..09732dd883 100644 --- a/decompiler/ObjectFile/ObjectFileDB_IR2.cpp +++ b/decompiler/ObjectFile/ObjectFileDB_IR2.cpp @@ -159,6 +159,11 @@ void ObjectFileDB::ir2_run_mips2c(const Config& config, ObjectFileData& data) { lg::info("MIPS2C on {}", func.name()); run_mips2c(&func); } + + auto it = config.hacks.mips2c_jump_table_functions.find(func.name()); + if (it != config.hacks.mips2c_jump_table_functions.end()) { + run_mips2c_jump_table(&func, it->second); + } }); } diff --git a/decompiler/analysis/mips2c.cpp b/decompiler/analysis/mips2c.cpp index 607298db78..ef22330048 100644 --- a/decompiler/analysis/mips2c.cpp +++ b/decompiler/analysis/mips2c.cpp @@ -126,11 +126,17 @@ struct Mips2C_Line { * The output is built by write_to_string. */ struct Mips2C_Output { + bool jump_table = false; /*! * Add a label at the current line. */ void output_label(int block_idx) { lines.push_back(fmt::format("\nblock_{}:", block_idx)); } + void output_jump_table_block_label(int block_idx) { + lines.push_back(fmt::format("\ncase {}:", block_idx)); + lines.push_back(fmt::format("next_block = {};", block_idx + 1)); + } + /*! * Add a full line comment at the current line. Includes "//" automatically */ @@ -146,7 +152,8 @@ struct Mips2C_Output { /*! * Convert the output to a string. */ - std::string write_to_string(const FunctionName& goal_func_name) const { + std::string write_to_string(const FunctionName& goal_func_name, + const std::string& extra = "") const { std::string name = goal_to_c_function_name(goal_func_name); std::string result = "//--------------------------MIPS2C---------------------\n"; result += "#include \"game/mips2c/mips2c_private.h\"\n"; @@ -181,6 +188,12 @@ struct Mips2C_Output { result += " bool cop1_bc = false;\n"; } + if (jump_table) { + result += "u32 next_block = 0;\n"; + result += "while(true) {\n"; + result += " switch(next_block) {\n"; + } + // add all lines for (auto& line : lines) { result += " "; @@ -198,6 +211,11 @@ struct Mips2C_Output { result += '\n'; } + if (jump_table) { + result += " }\n"; + result += "}\n"; + } + // return! result += "end_of_function:\n return c->gprs[v0].du64[0];\n"; result += "}\n\n"; @@ -213,6 +231,8 @@ struct Mips2C_Output { fmt::format(" gLinkedFunctionTable.reg(\"{}\", execute);\n", goal_func_name.to_string()); result += "}\n\n"; + result += extra; + result += fmt::format("}} // namespace {}\n", name); result += "} // namespace Mips2C\n"; @@ -932,6 +952,8 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output, return handle_generic_op2_mask(i0, instr_str, "vitof0"); case InstructionKind::VITOF12: return handle_generic_op2_mask(i0, instr_str, "vitof12"); + case InstructionKind::VITOF15: + return handle_generic_op2_mask(i0, instr_str, "vitof15"); case InstructionKind::VFTOI0: return handle_generic_op2_mask(i0, instr_str, "vftoi0"); case InstructionKind::VFTOI4: @@ -1078,6 +1100,157 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output, } } +struct JumpTableBlock { + int idx = -1; + int start_instr = -1; + int end_instr = -1; // not inclusive + int succ_branch = -1; // block idx if we take the branch + int succ_ft = -1; // block idx if we don't take the branch (or there is none) + bool has_branch = false; // ends in a branch instruction? + bool branch_likely = false; // that branch is likely branch? + bool branch_always = false; // that branch is always taken? +}; + +void run_mips2c_jump_table(Function* f, const std::vector& jump_table_locations) { + fmt::print("mips2c-jump on {}\n", f->name()); + u32 magic_code = std::hash()(f->name()); + std::unordered_map loc_to_block; + for (size_t bb_idx = 0; bb_idx < f->basic_blocks.size(); bb_idx++) { + loc_to_block[f->basic_blocks[bb_idx].start_word] = bb_idx; + } + + auto* file = f->ir2.env.file; + std::unordered_set likely_delay_blocks; + auto blocks = setup_preds_and_succs(*f, *file, likely_delay_blocks); + Mips2C_Output output; + output.jump_table = true; + int unknown_count = 0; + + for (size_t block_idx = 0; block_idx < blocks.size(); block_idx++) { + const auto& block = blocks[block_idx]; + + if (likely_delay_blocks.count(block_idx)) { + continue; + } + + output.output_jump_table_block_label(block_idx); + + for (int i = block.start_instr; i < block.end_instr; i++) { + size_t old_line_count = output.lines.size(); + auto& instr = f->instructions.at(i); + auto instr_str = instr.to_string(file->labels); + + if (is_branch(instr, {})) { + if (block.branch_likely) { + auto branch_line = handle_likely_branch_bc(instr, instr_str); + output.lines.emplace_back(fmt::format("if ({}) {{", branch_line.code), + branch_line.comment); + // next block should be the delay slot + assert((int)block_idx + 1 == block.succ_branch); + auto& delay_block = blocks.at(block.succ_branch); + assert(delay_block.end_instr - delay_block.start_instr == 1); // only 1 instr. + auto& delay_instr = f->instructions.at(delay_block.start_instr); + auto delay_instr_str = delay_instr.to_string(file->labels); + auto delay_instr_line = + handle_normal_instr(output, delay_instr, delay_instr_str, unknown_count, file); + output.lines.emplace_back(fmt::format(" {}", delay_instr_line.code), + delay_instr_line.comment); + assert(delay_block.succ_ft == -1); + output.lines.emplace_back(fmt::format(" next_block = {};", delay_block.succ_branch), ""); + output.lines.emplace_back("break;"); + output.lines.emplace_back("}", ""); + } else { + if (is_always_branch(instr)) { + // skip the branch ins. + output.lines.emplace_back("//" + instr_str, instr_str); + // then the delay slot + assert(i + 1 < block.end_instr); + i++; + auto& delay_i = f->instructions.at(i); + auto delay_i_str = delay_i.to_string(file->labels); + output.lines.push_back( + handle_normal_instr(output, delay_i, delay_i_str, unknown_count, file)); + assert(i + 1 == block.end_instr); + // then the goto + output.lines.emplace_back(fmt::format("next_block = {};", block.succ_branch), + "branch always\n"); + output.lines.emplace_back("break;"); + + } else { + // set the branch condition + output.lines.push_back(handle_non_likely_branch_bc(instr, instr_str)); + // then the delay slot + assert(i + 1 < block.end_instr); + i++; + auto& delay_i = f->instructions.at(i); + auto delay_i_str = delay_i.to_string(file->labels); + output.lines.push_back( + handle_normal_instr(output, delay_i, delay_i_str, unknown_count, file)); + assert(i + 1 == block.end_instr); + // then the goto + output.lines.emplace_back( + fmt::format("if (bc) {{next_block = {};}}", block.succ_branch), + "branch non-likely\n"); + output.lines.emplace_back("break;"); + } + } + } else if (is_jr_ra(instr)) { + // skip + output.lines.emplace_back("//" + instr_str, instr_str); + // then the delay slot + assert(i + 1 < block.end_instr); + i++; + auto& delay_i = f->instructions.at(i); + auto delay_i_str = delay_i.to_string(file->labels); + output.lines.push_back( + handle_normal_instr(output, delay_i, delay_i_str, unknown_count, file)); + + // then the goto + output.lines.emplace_back(fmt::format("goto end_of_function;", block.succ_branch), + "return\n"); + } else if (instr.kind == InstructionKind::JALR) { + assert(instr.get_dst(0).is_reg(Register(Reg::GPR, Reg::RA))); + assert(i < block.end_instr - 1); + output.lines.emplace_back( + fmt::format("call_addr = c->gprs[{}].du32[0];", reg_to_name(instr.get_src(0))), + "function call:"); + i++; + auto& delay_i = f->instructions.at(i); + auto delay_i_str = delay_i.to_string(file->labels); + output.lines.push_back( + handle_normal_instr(output, delay_i, delay_i_str, unknown_count, file)); + output.lines.emplace_back("c->jalr(call_addr);", instr_str); + } else if (instr.kind == InstructionKind::JR) { + // special case for jr's to handle the jump tableing. + output.lines.emplace_back(fmt::format("next_block = 0x{:x} ^ c->gprs[{}].du32[0];", + magic_code, reg_to_name(instr.get_src(0))), + instr_str); + output.lines.emplace_back(fmt::format("assert(next_block < {});", f->basic_blocks.size())); + output.lines.emplace_back("break;"); + + } else { + output.lines.push_back(handle_normal_instr(output, instr, instr_str, unknown_count, file)); + } + + assert(output.lines.size() > old_line_count); + } + } + + std::string jump_loc_table = + fmt::format("u32 jump_table_vals[{}] = {{\n", jump_table_locations.size()); + for (auto loc : jump_table_locations) { + auto block = loc_to_block.at(loc + 1); + jump_loc_table += + fmt::format(" 0x{:x}, // = {} ^ {}\n", ((u32)block) ^ magic_code, block, magic_code); + } + jump_loc_table += "};\n\n"; + + f->mips2c_output = output.write_to_string(f->guessed_name, jump_loc_table); + if (g_unknown > 0) { + lg::error("Mips to C pass in {} hit {} unknown instructions", f->name(), g_unknown); + } +} + void run_mips2c(Function* f) { g_unknown = 0; auto* file = f->ir2.env.file; diff --git a/decompiler/analysis/mips2c.h b/decompiler/analysis/mips2c.h index acf922ef20..a13dfcbd6e 100644 --- a/decompiler/analysis/mips2c.h +++ b/decompiler/analysis/mips2c.h @@ -1,7 +1,10 @@ #pragma once +#include + namespace decompiler { class Function; void run_mips2c(Function* f); +void run_mips2c_jump_table(Function* f, const std::vector& jump_table_locations); } // namespace decompiler diff --git a/decompiler/config.cpp b/decompiler/config.cpp index 69b9679972..7c6ff9c74c 100644 --- a/decompiler/config.cpp +++ b/decompiler/config.cpp @@ -185,6 +185,9 @@ Config read_config_file(const std::string& path_to_config_file) { .get>>>(); config.hacks.mips2c_functions_by_name = hacks_json.at("mips2c_functions_by_name").get>(); + config.hacks.mips2c_jump_table_functions = + hacks_json.at("mips2c_jump_table_functions") + .get>>(); for (auto& entry : hacks_json.at("cond_with_else_max_lengths")) { auto func_name = entry.at(0).get(); diff --git a/decompiler/config.h b/decompiler/config.h index d0c11063c3..c2d6b8bf36 100644 --- a/decompiler/config.h +++ b/decompiler/config.h @@ -77,6 +77,7 @@ struct DecompileHacks { std::unordered_map>> format_ops_with_dynamic_string_by_func_name; std::unordered_set mips2c_functions_by_name; + std::unordered_map> mips2c_jump_table_functions; std::unordered_map>> missing_textures_by_level; }; diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 7ef7f4c495..6fcc50dff2 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -10261,9 +10261,9 @@ ;; inherited inspect of process (:methods (initialize-skeleton (_type_ skeleton-group pair) none 14) - (dummy-15 (_type_ string object) _type_ 15) + (initialize-skeleton-by-name (_type_ string object) _type_ 15) (dummy-16 (_type_ int (inline-array vector) vector) collide-shape 16) - (dummy-17 (_type_) none 17) + (do-joint-math! (_type_) none 17) (dummy-18 (_type_) none 18) (dummy-19 (_type_) none 19) ) @@ -15863,7 +15863,7 @@ (define-extern flatten-joint-control-to-spr (function joint-control int)) (define-extern make-joint-jump-tables (function int)) -(define-extern calc-animation-from-spr (function (inline-array vector) int object)) +(define-extern calc-animation-from-spr (function (inline-array vector) int none)) (define-extern decompress-fixed-data-to-accumulator (function none)) (define-extern decompress-frame-data-to-accumulator (function none)) (define-extern decompress-frame-data-pair-to-accumulator (function none)) @@ -16457,7 +16457,7 @@ :type uint16 :bitfield #t (bncfl00 0) - (bncfl01 1) + (bncfl01 1) ;; use identity matrix in bone matrix calc instead of cam rot (effectively screen-space bones?) (bncfl02 2) (bncfl03 3) (bncfl04 4) @@ -16548,7 +16548,7 @@ (define-extern bones-reset-sqwc (function none)) (define-extern bones-init (function dma-buffer dma-foreground-sink-group none)) (define-extern draw-bones-mtx-calc (function bone-calculation int bone-calc-flags object)) -(define-extern bones-mtx-calc (function int pointer pointer int none)) +(define-extern bones-mtx-calc (function int pointer pointer int object none)) (define-extern bones-mtx-calc-execute (function none)) (define-extern bones-wrapup (function none)) (define-extern dump-qword (function qword none)) @@ -16691,7 +16691,7 @@ (define-extern mercneric-convert function) (define-extern high-speed-reject function) (define-extern generic-merc-execute-asm function) -(define-extern generic-merc-add-to-cue function) +(define-extern generic-merc-add-to-cue (function uint none)) (define-extern generic-merc-execute-all (function none)) ;; - Unknowns @@ -23254,7 +23254,7 @@ (deftype ropebridge-tuning (structure) ((num-springs int32 :offset-assert 0) (num-spring-points int32 :offset-assert 4) - (col-mesh-indexes pointer :offset-assert 8) ;; pointer to a variable sized thing + (col-mesh-indexes (pointer uint8) :offset-assert 8) ;; pointer to a variable sized thing (view-frustum-radius float :offset-assert 12) (root-prim-radius float :offset-assert 16) (desired-spring-len float :offset-assert 20) @@ -23289,9 +23289,9 @@ ) (deftype ropebridge (process-drawable) - ((root-override basic :offset 112) + ((root-override collide-shape :score 100 :offset 112) (subtype uint64 :offset-assert 176) - (subtype-name basic :offset-assert 184) + (subtype-name string :offset-assert 184) (agitated-time-stamp uint64 :offset-assert 192) (bonk-time-stamp uint64 :offset-assert 200) (attack-flop-time-stamp uint64 :offset-assert 208) @@ -23309,14 +23309,14 @@ :heap-base #x7d0 :flag-assert #x1d07d00840 (:methods - (dummy-20 (_type_) none 20) - (dummy-21 (_type_) none 21) - (dummy-22 (_type_) none 22) - (dummy-23 (_type_) none 23) - (dummy-24 (_type_) none 24) - (dummy-25 (_type_) none 25) - (dummy-26 (_type_) none 26) - (dummy-27 (_type_) none 27) + (set-vel-from-impact (_type_ uint vector int float) none 20) + (set-vel-from-riders (_type_) none 21) ;; physics2 + (set-vel-from-rider (_type_ uint vector int) none 22) + (clear-spring-forces (_type_) none 23) ;; physics1 + (debug-draw (_type_) none 24) + (set-to-rest-state (_type_) none 25) + (add-collision-meshes (_type_) none 26) + (do-integration (_type_) none 27) ;; physics3 (dummy-28 (_type_) none 28) ) (:states @@ -23325,15 +23325,15 @@ ;; - Functions -(define-extern ropebridge-joint-callback function) +(define-extern ropebridge-joint-callback (function ropebridge none)) ;; - Unknowns (define-extern *ropebridge-tunings* (inline-array ropebridge-tuning)) ;; unknown type -(define-extern *ropebridge-70-rest-state* (inline-array ropebridge-spring-point)) ;; can't find ropebridges with these ids in the game?? -(define-extern *ropebridge-52-rest-state* (inline-array ropebridge-spring-point)) -(define-extern *ropebridge-32-rest-state* (inline-array ropebridge-spring-point)) -(define-extern *ropebridge-36-rest-state* (inline-array ropebridge-spring-point)) +(define-extern *ropebridge-70-rest-state* (inline-array vector)) ;; can't find ropebridges with these ids in the game?? +(define-extern *ropebridge-52-rest-state* (inline-array vector)) +(define-extern *ropebridge-32-rest-state* (inline-array vector)) +(define-extern *ropebridge-36-rest-state* (inline-array vector)) (define-extern *ropebridge-32-sg* skeleton-group) (define-extern *snow-bridge-36-sg* skeleton-group) (define-extern *ropebridge-52-sg* skeleton-group) diff --git a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc index 0ae51a605d..08e9fa7706 100644 --- a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc @@ -282,9 +282,6 @@ "ocean-generate-verts", // crash "ocean-interp-wave", - // ropebridge BUG - "(method 27 ropebridge)", - // all unchecked and in level DGO code "(anon-function 21 plant-boss)", // CFG //"target-flut-falling-anim-trans", // CFG failure @@ -501,7 +498,8 @@ "start-collect-nav": [0], "end-collect-nav": [0], "robotboss-always-trans": [9, 10, 11, 12, 13, 14, 15, 18, 29, 36, 45, 48], - "target-flut-falling-anim-trans" : [5, 6] + "target-flut-falling-anim-trans" : [5, 6], + "(method 27 ropebridge)" : [5, 7] }, // Sometimes the game might use format strings that are fetched dynamically, @@ -575,9 +573,20 @@ "(method 16 collide-edge-work)", "(method 10 collide-edge-hold-list)", "(method 15 collide-edge-work)", - "(method 18 collide-edge-work)" + "(method 18 collide-edge-work)", + "normalize-frame-quaternions", + "calc-animation-from-spr", + "clear-frame-accumulator", + "bones-mtx-calc", + "cspace<-parented-transformq-joint!" ], + "mips2c_jump_table_functions": { + "decompress-fixed-data-to-accumulator" : [108, 199, 233, 286, 301, 366, 387, 100, 155, 199, 261, 286, 335, 366, 402, 100], + "decompress-frame-data-to-accumulator" : [84, 92, 119, 140, 205, 220, 273, 307, 84, 107, 119, 174, 205, 248, 273, 354], + "decompress-frame-data-pair-to-accumulator" : [117, 125, 169, 197, 293, 318, 408, 459, 117, 150, 169, 248, 293, 366, 408, 533] + }, + // there are some missing textures. I don't know what the game actually does here. // the format for entries is [level, tpage, index] "missing_textures": [ diff --git a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc index e856b3e4b6..07ff8d2250 100644 --- a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc @@ -1429,10 +1429,10 @@ "ropebridge": [ ["L97", "(inline-array ropebridge-tuning)", 6], - ["L104", "(inline-array ropebridge-spring-point)", 8], - ["L105", "(inline-array ropebridge-spring-point)", 7], - ["L106", "(inline-array ropebridge-spring-point)", 11], - ["L107", "(inline-array ropebridge-spring-point)", 15] + ["L104", "(inline-array vector)", 18], // 70/72 words + ["L105", "(inline-array vector)", 16], // 62/64 words + ["L106", "(inline-array vector)", 26], // 102/104 words + ["L107", "(inline-array vector)", 35] // 138/140 words ], "double-lurker": [ diff --git a/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc b/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc index 061ece57a9..0dc7c6bbc8 100644 --- a/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc @@ -6361,5 +6361,22 @@ [64, "event-message-block"] ], + "(event ropebridge-idle)" : [ + [16, "vector"], + [32, "vector"] + ], + + "(method 21 ropebridge)" : [ + [16, "vector"] + ], + + "(method 24 ropebridge)":[ + [16, "vector"] + ], + + "ropebridge-joint-callback": [ + [16, "vector"] + ], + "placeholder-do-not-add-below!": [] } diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index b6eb4f8b02..a2b53670a5 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -7058,7 +7058,8 @@ ], "bones-wrapup": [ - [[3, 26], "v1", "bone-memory"] + [[3, 26], "v1", "bone-memory"], + [[9, 12], "a1", "dma-packet"] ], "texscroll-make-request": [ @@ -7822,5 +7823,42 @@ [34, "v1", "nav-poly"] ], + "foreground-engine-execute" : [ + [114, "v1", "(pointer uint32)"] + ], + + "(event ropebridge-idle)": [ + [65, "v1", "touching-shapes-entry"], + [12, "v1", "float"] + ], + + "(method 23 ropebridge)": [ + [[1, 9], "v1", "ropebridge-spring-point"] + ], + + "(method 21 ropebridge)": [ + [20, "v1", "process-drawable"], + [[4, 50], "s5", "collide-sticky-rider"] + ], + + "(method 24 ropebridge)": [ + [[3, 22], "s5", "ropebridge-spring-point"] + ], + + "(method 25 ropebridge)": [ + [[4, 24], "a1", "vector"], + [[3, 24], "v1", "ropebridge-spring-point"], + [[30, 42], "v1", "ropebridge-spring-point"] + ], + + "(method 11 ropebridge)" : [ + [[17, 21], "s4", "symbol"] + ], + + "ropebridge-joint-callback" : [ + [[27,70], "s5", "(inline-array ropebridge-spring-point)"], + [[23, 24], "s3", "ropebridge-spring-point"] + ], + "placeholder-do-not-add-below": [] } diff --git a/decompiler/util/data_decompile.cpp b/decompiler/util/data_decompile.cpp index f81a230c5e..519ba96c18 100644 --- a/decompiler/util/data_decompile.cpp +++ b/decompiler/util/data_decompile.cpp @@ -319,6 +319,83 @@ int index_of_closest_following_label_in_segment(int start_byte, return result_idx; } +/*! + * Attempt to decompile a reference to an inline array, without knowing the size. + */ +goos::Object decomp_ref_to_integer_array_guess_size( + const std::vector& words, + const std::vector& labels, + int my_seg, + int field_location, + const TypeSystem& ts, + const std::vector>& all_words, + const LinkedObjectFile* file, + const TypeSpec& array_elt_type, + int stride) { + // fmt::print("Decomp decomp_ref_to_inline_array_guess_size {}\n", array_elt_type.print()); + + // verify types + auto elt_type_info = ts.lookup_type(array_elt_type); + assert(stride == elt_type_info->get_size_in_memory()); + assert(!elt_type_info->is_reference()); + + // the input is the location of the data field. + // we expect that to be a label: + assert((field_location % 4) == 0); + auto pointer_to_data = words.at(field_location / 4); + assert(pointer_to_data.kind() == LinkedWord::PTR); + + // the data shouldn't have any labels in the middle of it, so we can find the end of the array + // by searching for the label after the start label. + const auto& start_label = labels.at(pointer_to_data.label_id()); + int end_label_idx = + index_of_closest_following_label_in_segment(start_label.offset, my_seg, labels); + + int end_offset = all_words.at(my_seg).size() * 4; + if (end_label_idx < 0) { + lg::warn( + "Failed to find label: likely just an unimplemented case for when the data is the last " + "thing in the file."); + } else { + const auto& end_label = labels.at(end_label_idx); + end_offset = end_label.offset; + } + + // fmt::print("Data is from {} to {}\n", start_label.name, end_label.name); + + // now we can figure out the size + int size_bytes = end_offset - start_label.offset; + int size_elts = size_bytes / stride; // 32 bytes per ocean-near-index + int leftover_bytes = size_bytes % stride; + // fmt::print("Size is {} bytes ({} elts), with {} bytes left over\n", size_bytes, + // size_elts,leftover_bytes); + + // if we have leftover, should verify that its all zeros, or that it's the type pointer + // of the next basic in the data section. + // ex: + // .word + // .type + // L21: ; label some other basic + // + int padding_start = end_offset - leftover_bytes; + int padding_end = end_offset; + for (int pad_byte_idx = padding_start; pad_byte_idx < padding_end; pad_byte_idx++) { + auto& word = all_words.at(my_seg).at(pad_byte_idx / 4); + switch (word.kind()) { + case LinkedWord::PLAIN_DATA: + assert(word.get_byte(pad_byte_idx) == 0); + break; + case LinkedWord::TYPE_PTR: + break; + default: + assert(false); + } + } + + return decompile_value_array(array_elt_type, elt_type_info, size_elts, stride, start_label.offset, + all_words.at(start_label.target_segment), ts); +} + /*! * Attempt to decompile a reference to an inline array, without knowing the size. */ @@ -726,6 +803,11 @@ goos::Object decompile_structure(const TypeSpec& type, field_defs_out.emplace_back(field.name(), sp_launch_grp_launcher_decompile( obj_words, labels, label.target_segment, field_start, ts, words, file)); + } else if (field.name() == "col-mesh-indexes" && type.print() == "ropebridge-tuning") { + field_defs_out.emplace_back( + field.name(), decomp_ref_to_integer_array_guess_size( + obj_words, labels, label.target_segment, field_start, ts, words, + file, TypeSpec("uint8"), 1)); } else { if (field.type().base_type() == "pointer") { if (obj_words.at(field_start / 4).kind() != LinkedWord::SYM_PTR) { diff --git a/docs/markdown/progress-notes/changelog.md b/docs/markdown/progress-notes/changelog.md index 87599dd700..b55e67b620 100644 --- a/docs/markdown/progress-notes/changelog.md +++ b/docs/markdown/progress-notes/changelog.md @@ -1,3 +1,4 @@ + # Language Changes ## V0.1 @@ -212,4 +213,5 @@ - Debugger will now correctly track when object files are loaded over previous files - Asm ops requiring 128-bit inputs will now try harder to convert their inputs when it is appropriate. - 0's that are constant propagated to the input of a 128-bit instruction will use `vpxor` instruction to generate the value, instead of `xor` and a `mov`. -- Add a `stack-singleton-no-clear` stack construction type. It will create a "singleton" inside this function - all other `(new 'stack-singleton` forms with the same type will return the same stack object. \ No newline at end of file +- Add a `stack-singleton-no-clear` stack construction type. It will create a "singleton" inside this function - all other `(new 'stack-singleton` forms with the same type will return the same stack object. +- Added support for using `(new 'static 'array ...)` for setting a static field of type `(pointer ...)` \ No newline at end of file diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index 1e9c5203c8..b8a08e5f73 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -60,12 +60,14 @@ set(RUNTIME_SOURCE kernel/ksocket.cpp kernel/ksound.cpp mips2c/mips2c_table.cpp + mips2c/functions/bones.cpp mips2c/functions/collide_cache.cpp mips2c/functions/collide_edge_grab.cpp mips2c/functions/collide_func.cpp mips2c/functions/collide_mesh.cpp mips2c/functions/collide_probe.cpp mips2c/functions/draw_string.cpp + mips2c/functions/joint.cpp mips2c/functions/sky_tng.cpp mips2c/functions/sparticle.cpp mips2c/functions/sparticle_launcher.cpp diff --git a/game/graphics/opengl_renderer/OpenGLRenderer.cpp b/game/graphics/opengl_renderer/OpenGLRenderer.cpp index e4c6612c56..eefb8aa419 100644 --- a/game/graphics/opengl_renderer/OpenGLRenderer.cpp +++ b/game/graphics/opengl_renderer/OpenGLRenderer.cpp @@ -106,7 +106,7 @@ void OpenGLRenderer::init_bucket_renderers() { sprite_renderers.push_back(std::make_unique("sprite-3", BucketId::SPRITE)); init_bucket_renderer("sprite", BucketId::SPRITE, std::move(sprite_renderers)); - init_bucket_renderer("debug-draw-0", BucketId::DEBUG_DRAW_0, 0x8000, + init_bucket_renderer("debug-draw-0", BucketId::DEBUG_DRAW_0, 0x20000, DirectRenderer::Mode::NORMAL); init_bucket_renderer("debug-draw-1", BucketId::DEBUG_DRAW_1, 0x8000, DirectRenderer::Mode::NORMAL); diff --git a/game/mips2c/functions/bones.cpp b/game/mips2c/functions/bones.cpp new file mode 100644 index 0000000000..6d3dcde9be --- /dev/null +++ b/game/mips2c/functions/bones.cpp @@ -0,0 +1,691 @@ + +//--------------------------MIPS2C--------------------- +// clang-format off +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace bones_mtx_calc { + +struct Cache { + void* fake_scratchpad_data; // *fake-scratchpad-data* +} cache; + +void exec_mpg(ExecutionContext* c) { +/* + nop | mulax.xyzw ACC, vf05, vf01 + nop | madday.xyzw ACC, vf06, vf01 + nop | maddaz.xyzw ACC, vf07, vf01 + nop | maddw.xyzw vf13, vf08, vf01 + nop | mulax.xyzw ACC, vf05, vf02 + nop | madday.xyzw ACC, vf06, vf02 + nop | maddaz.xyzw ACC, vf07, vf02 + nop | maddw.xyzw vf14, vf08, vf02 + nop | mulax.xyzw ACC, vf05, vf03 + nop | madday.xyzw ACC, vf06, vf03 + nop | maddaz.xyzw ACC, vf07, vf03 + nop | maddw.xyzw vf15, vf08, vf03 + nop | mulax.xyzw ACC, vf05, vf04 + nop | madday.xyzw ACC, vf06, vf04 + nop | maddaz.xyzw ACC, vf07, vf04 + nop | maddw.xyzw vf16, vf08, vf04 + nop | opmula.xyz ACC, vf14, vf15 + nop | opmsub.xyz vf09, vf15, vf14 + nop | opmula.xyz ACC, vf15, vf13 + nop | opmsub.xyz vf10, vf13, vf15 + nop | opmula.xyz ACC, vf13, vf14 + nop | mul.xyz vf12, vf13, vf09 + nop | opmsub.xyz vf11, vf14, vf13 + nop | mulax.xyzw ACC, vf28, vf13 + nop | madday.xyzw ACC, vf29, vf13 + nop | maddaz.xyzw ACC, vf30, vf13 + nop | maddw.xyzw vf13, vf31, vf13 + nop | mulax.w ACC, vf00, vf12 + nop | madday.w ACC, vf00, vf12 + nop | maddz.w vf12, vf00, vf12 + nop | mulax.xyzw ACC, vf28, vf14 + nop | madday.xyzw ACC, vf29, vf14 + nop | maddaz.xyzw ACC, vf30, vf14 + div Q, vf00.w, vf12.w | maddw.xyzw vf14, vf31, vf14 + nop | mulax.xyzw ACC, vf28, vf15 + nop | madday.xyzw ACC, vf29, vf15 + nop | maddaz.xyzw ACC, vf30, vf15 + nop | maddw.xyzw vf15, vf31, vf15 + nop | mulax.xyzw ACC, vf28, vf16 + nop | madday.xyzw ACC, vf29, vf16 + nop | maddaz.xyzw ACC, vf30, vf16 + nop | maddw.xyzw vf16, vf31, vf16 + nop | mul.xyzw vf09, vf09, Q + nop | mul.xyzw vf10, vf10, Q + nop | mul.xyzw vf11, vf11, Q + nop | mulax.xyzw ACC, vf25, vf09 + nop | madday.xyzw ACC, vf26, vf09 + nop | maddz.xyzw vf09, vf27, vf09 + nop | mulax.xyzw ACC, vf25, vf10 + nop | madday.xyzw ACC, vf26, vf10 + nop | maddz.xyzw vf10, vf27, vf10 + nop | mulax.xyzw ACC, vf25, vf11 + nop | madday.xyzw ACC, vf26, vf11 :e + nop | maddz.xyzw vf11, vf27, vf11 + */ + +// printf("vf1 is %f %f %f %f\n", c->vfs[vf1].f[0], c->vfs[vf1].f[1], c->vfs[vf1].f[2], c->vfs[vf1].f[3]); + c->vmula_bc(DEST::xyzw, BC::x, vf05, vf1); + c->vmadda_bc(DEST::xyzw, BC::y, vf06, vf01); + c->vmadda_bc(DEST::xyzw, BC::z, vf07, vf01); + c->vmadd_bc(DEST::xyzw, BC::w, vf13, vf08, vf01); + c->vmula_bc(DEST::xyzw, BC::x, vf05, vf02); + c->vmadda_bc(DEST::xyzw, BC::y, vf06, vf02); + c->vmadda_bc(DEST::xyzw, BC::z, vf07, vf02); + c->vmadd_bc(DEST::xyzw, BC::w, vf14, vf08, vf02); + c->vmula_bc(DEST::xyzw, BC::x, vf05, vf03); + c->vmadda_bc(DEST::xyzw, BC::y, vf06, vf03); + c->vmadda_bc(DEST::xyzw, BC::z, vf07, vf03); + c->vmadd_bc(DEST::xyzw, BC::w, vf15, vf08, vf03); + c->vmula_bc(DEST::xyzw, BC::x, vf05, vf04); + c->vmadda_bc(DEST::xyzw, BC::y, vf06, vf04); + c->vmadda_bc(DEST::xyzw, BC::z, vf07, vf04); + c->vmadd_bc(DEST::xyzw, BC::w, vf16, vf08, vf04); +// printf("vf05 is %f %f %f %f\n", c->vfs[vf05].f[0], c->vfs[vf05].f[1], c->vfs[vf05].f[2], c->vfs[vf05].f[3]); + +// printf("vf06 is %f %f %f %f\n", c->vfs[vf06].f[0], c->vfs[vf06].f[1], c->vfs[vf06].f[2], c->vfs[vf06].f[3]); + c->vopmula(vf14, vf15); + c->vopmsub(vf09, vf15, vf14); + c->vopmula(vf15, vf13); + c->vopmsub(vf10, vf13, vf15); + c->vopmula(vf13, vf14); + //nop | mul.xyz vf12, vf13, vf09 + c->vmul(DEST::xyz, vf12, vf13, vf09); +// printf("vf12 is %f %f %f %f\n", c->vfs[vf12].f[0], c->vfs[vf12].f[1], c->vfs[vf12].f[2], c->vfs[vf12].f[3]); +// printf("vf13 is %f %f %f %f\n", c->vfs[vf13].f[0], c->vfs[vf13].f[1], c->vfs[vf13].f[2], c->vfs[vf13].f[3]); + +// printf("vf09 is %f %f %f %f\n", c->vfs[vf09].f[0], c->vfs[vf09].f[1], c->vfs[vf09].f[2], c->vfs[vf09].f[3]); + + c->vopmsub(vf11, vf14, vf13); + c->vmula_bc(DEST::xyzw, BC::x, vf28, vf13); + c->vmadda_bc(DEST::xyzw, BC::y, vf29, vf13); + c->vmadda_bc(DEST::xyzw, BC::z, vf30, vf13); + c->vmadd_bc(DEST::xyzw, BC::w, vf13, vf31, vf13); + //nop | mulax.w ACC, vf00, vf12 + c->vmula_bc(DEST::w, BC::x, vf0, vf12); + //nop | madday.w ACC, vf00, vf12 + c->vmadda_bc(DEST::w, BC::y, vf0, vf12); + //nop | maddz.w vf12, vf00, vf12 + c->vmadd_bc(DEST::w, BC::z, vf12, vf0, vf12); + c->vmula_bc(DEST::xyzw, BC::x, vf28, vf14); + c->vmadda_bc(DEST::xyzw, BC::y, vf29, vf14); + c->vmadda_bc(DEST::xyzw, BC::z, vf30, vf14); + //div Q, vf00.w, vf12.w | maddw.xyzw vf14, vf31, vf14 + c->vdiv(vf0, BC::w, vf12, BC::w); +//printf("vf12.w is %f\n", c->vfs[vf12].f[3]); + c->vmadd_bc(DEST::xyzw, BC::w, vf14, vf31, vf14); + c->vmula_bc(DEST::xyzw, BC::x, vf28, vf15); + c->vmadda_bc(DEST::xyzw, BC::y, vf29, vf15); + c->vmadda_bc(DEST::xyzw, BC::z, vf30, vf15); + c->vmadd_bc(DEST::xyzw, BC::w, vf15, vf31, vf15); + c->vmula_bc(DEST::xyzw, BC::x, vf28, vf16); + c->vmadda_bc(DEST::xyzw, BC::y, vf29, vf16); + c->vmadda_bc(DEST::xyzw, BC::z, vf30, vf16); + c->vmadd_bc(DEST::xyzw, BC::w, vf16, vf31, vf16); + //nop | mul.xyzw vf09, vf09, Q + c->vmulq(DEST::xyzw, vf09, vf09); + // nop | mul.xyzw vf10, vf10, Q + c->vmulq(DEST::xyzw, vf10, vf10); + // nop | mul.xyzw vf11, vf11, Q + c->vmulq(DEST::xyzw, vf11, vf11); + c->vmula_bc(DEST::xyzw, BC::x, vf25, vf09); + c->vmadda_bc(DEST::xyzw, BC::y, vf26, vf09); + //nop | maddz.xyzw vf09, vf27, vf09 + c->vmadd_bc(DEST::xyzw, BC::z, vf09, vf27, vf09); + c->vmula_bc(DEST::xyzw, BC::x, vf25, vf10); + c->vmadda_bc(DEST::xyzw, BC::y, vf26, vf10); + c->vmadd_bc(DEST::xyzw, BC::z, vf10, vf27, vf10); + c->vmula_bc(DEST::xyzw, BC::x, vf25, vf11); + c->vmadda_bc(DEST::xyzw, BC::y, vf26, vf11); // :e + c->vmadd_bc(DEST::xyzw, BC::z, vf11, vf27, vf11); +} + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; +//printf("start\n"); + bool bc = false; + u32 madr, sadr, qwc; + // hack, added this that should be loaded by the caller. + // lqc2 vf28, 0(v1) ;; [ 60] (set! vf28 (l.vf v1-13)) [v1: matrix ] -> [] + c->lqc2(vf28, 0, t0); + // lqc2 vf29, 16(v1) ;; [ 61] (set! vf29 (l.vf (+ v1-13 16))) [v1: matrix ] -> [] + c->lqc2(vf29, 16, t0); + // lqc2 vf30, 32(v1) ;; [ 62] (set! vf30 (l.vf (+ v1-13 32))) [v1: matrix ] -> [] + c->lqc2(vf30, 32, t0); + // lqc2 vf31, 48(v1) ;; [ 63] (set! vf31 (l.vf (+ v1-13 48))) [v1: matrix ] -> [] + c->lqc2(vf31, 48, t0); + // lqc2 vf25, 0(v1) ;; [ 64] (set! vf25 (l.vf v1-13)) [v1: matrix ] -> [] + c->lqc2(vf25, 0, t0); + // lqc2 vf26, 16(v1) ;; [ 65] (set! vf26 (l.vf (+ v1-13 16))) [v1: matrix ] -> [] + c->lqc2(vf26, 16, t0); + // lqc2 vf27, 32(v1) ;; [ 66] (set! vf27 (l.vf (+ v1-13 32))) [v1: matrix ] -> [] + c->lqc2(vf27, 32, t0); + + c->daddiu(sp, sp, -96); // daddiu sp, sp, -96 + c->sd(ra, 0, sp); // sd ra, 0(sp) + c->sq(s2, 16, sp); // sq s2, 16(sp) + c->sq(s3, 32, sp); // sq s3, 32(sp) + c->sq(s4, 48, sp); // sq s4, 48(sp) + c->sq(s5, 64, sp); // sq s5, 64(sp) + c->sq(gp, 80, sp); // sq gp, 80(sp) + c->lui(v1, 4096); // lui v1, 4096 + c->lui(t0, 4096); // lui t0, 4096 + c->ori(v1, v1, 54272); // ori v1, v1, 54272 0xd400 (spr to) + c->ori(t0, t0, 53248); // ori t0, t0, 53248 0xd000 (spr from) + c->lui(t2, 32767); // lui t2, 32767 + c->daddiu(t1, a3, -16); // daddiu t1, a3, -16 + c->ori(t2, t2, 65535); // ori t2, t2, 65535 + // c->lui(at, 28672); // lui at, 28672 <- spr + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c); + c->addiu(t4, r0, 64); // addiu t4, r0, 64 + c->addiu(t5, r0, 1280); // addiu t5, r0, 1280 + bc = ((s64)c->sgpr64(t1)) >= 0; // bgez t1, L117 + c->addiu(t3, r0, 16); // addiu t3, r0, 16 + if (bc) {goto block_2;} // branch non-likely + + c->addiu(t1, r0, 0); // addiu t1, r0, 0 + c->mov64(t3, a3); // or t3, a3, r0 + c->dsll(t4, t3, 2); // dsll t4, t3, 2 + c->dsll(a3, t3, 4); // dsll a3, t3, 4 + c->dsll(t5, t3, 6); // dsll t5, t3, 6 + c->daddu(t5, t5, a3); // daddu t5, t5, a3 + + block_2: + c->addiu(a3, r0, 0); // addiu a3, r0, 0 + c->addiu(t6, r0, 1); // addiu t6, r0, 1 + c->and_(a1, a1, t2); // and a1, a1, t2 + // nop // sll r0, r0, 0 + c->daddiu(a1, a1, 12); // daddiu a1, a1, 12 + c->mov64(a0, a0); // or a0, a0, r0 + c->daddiu(a1, a1, -80); // daddiu a1, a1, -80 + // nop // sll r0, r0, 0 + + /* + block_3: + c->lw(t6, 0, v1); // lw t6, 0(v1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->andi(t6, t6, 256); // andi t6, t6, 256 + // nop // sll r0, r0, 0 + bc = c->sgpr64(t6) == 0; // beq t6, r0, L119 + // nop // sll r0, r0, 0 + if (bc) {goto block_5;} // branch non-likely + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + //beq r0, r0, L118 // beq r0, r0, L118 + // nop // sll r0, r0, 0 + goto block_3; // branch always + */ + + + c->addiu(t6, r0, 256); // addiu t6, r0, 256 + c->addiu(t7, r0, 264); // addiu t7, r0, 264 + // c->sw(t6, 128, v1); // sw t6, 128(v1) sadr + // c->sw(a1, 16, v1); // sw a1, 16(v1) madr + // c->sw(t4, 32, v1); // sw t4, 32(v1) qwc + // c->sw(t7, 0, v1); // sw t7, 0(v1) go! + spad_to_dma_no_sadr_off_bones_interleave(cache.fake_scratchpad_data, c->sgpr64(a1), c->sgpr64(t6), c->sgpr64(t4)); + c->daddu(a1, a1, t5); // daddu a1, a1, t5 + + /* + block_6: + c->lw(t4, 0, v1); // lw t4, 0(v1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->andi(t4, t4, 256); // andi t4, t4, 256 + // nop // sll r0, r0, 0 + bc = c->sgpr64(t4) == 0; // beq t4, r0, L121 + // nop // sll r0, r0, 0 + if (bc) {goto block_8;} // branch non-likely + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + //beq r0, r0, L120 // beq r0, r0, L120 + // nop // sll r0, r0, 0 + goto block_6; // branch always + */ + + + c->and_(a2, a2, t2); // and a2, a2, t2 + c->dsll(t2, t3, 1); // dsll t2, t3, 1 + c->dsll(t5, t3, 2); // dsll t5, t3, 2 + c->addiu(t4, r0, 256); // addiu t4, r0, 256 + c->daddu(t2, t5, t2); // daddu t2, t5, t2 + c->addiu(t6, r0, 1280); // addiu t6, r0, 1280 + c->dsll(t5, t2, 4); // dsll t5, t2, 4 + // c->sw(t6, 128, v1); // sw t6, 128(v1) + sadr = c->sgpr64(t6); + c->addiu(t8, r0, 0); // addiu t8, r0, 0 + // c->sw(a2, 16, v1); // sw a2, 16(v1) + madr = c->sgpr64(a2); + c->daddu(a2, a2, t5); // daddu a2, a2, t5 + // c->sw(t2, 32, v1); // sw t2, 32(v1) + qwc = c->sgpr64(t2); + c->addiu(t2, r0, 1); // addiu t2, r0, 1 + // c->sw(t4, 0, v1); // sw t4, 0(v1) + spad_to_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); + + + block_9: + /* + c->lw(t5, 0, v1); // lw t5, 0(v1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->andi(t5, t5, 256); // andi t5, t5, 256 + // nop // sll r0, r0, 0 + bc = c->sgpr64(t5) == 0; // beq t5, r0, L123 + // nop // sll r0, r0, 0 + if (bc) {goto block_11;} // branch non-likely + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + //beq r0, r0, L122 // beq r0, r0, L122 + // nop // sll r0, r0, 0 + goto block_9; // branch always + */ + + + c->dsll(t5, t8, 2); // dsll t5, t8, 2 + c->daddu(t9, t5, at); // daddu t9, t5, at + // nop // sll r0, r0, 0 + c->lwu(t5, 16, t9); // lwu t5, 16(t9) + c->mov64(t6, t3); // or t6, t3, r0 + c->lwu(t7, 24, t9); // lwu t7, 24(t9) + c->mov64(ra, t3); // or ra, t3, r0 + c->lwu(t3, 32, t9); // lwu t3, 32(t9) + // nop // sll r0, r0, 0 + c->sw(ra, 232, at); // sw ra, 232(at) + bc = c->sgpr64(ra) == 0; // beq ra, r0, L136 + c->sw(t8, 236, at); // sw t8, 236(at) + if (bc) {goto block_33;} // branch non-likely + + c->daddiu(t1, t1, -16); // daddiu t1, t1, -16 + c->addiu(t9, r0, 1280); // addiu t9, r0, 1280 + bc = ((s64)c->sgpr64(t1)) >= 0; // bgez t1, L124 + c->addiu(t8, r0, 16); // addiu t8, r0, 16 + if (bc) {goto block_14;} // branch non-likely + + c->daddiu(t8, t1, 16); // daddiu t8, t1, 16 + c->addiu(t1, r0, 0); // addiu t1, r0, 0 + c->dsll(t9, t8, 4); // dsll t9, t8, 4 + c->dsll(ra, t8, 6); // dsll ra, t8, 6 + bc = c->sgpr64(t8) == 0; // beq t8, r0, L125 + c->daddu(t9, ra, t9); // daddu t9, ra, t9 + if (bc) {goto block_15;} // branch non-likely + + + block_14: + c->dsll(t4, t8, 2); // dsll t4, t8, 2 + c->dsll(ra, t2, 2); // dsll ra, t2, 2 + c->daddu(gp, ra, at); // daddu gp, ra, at + // c->sw(a1, 16, v1); // sw a1, 16(v1) + madr = c->sgpr64(a1); + c->addiu(ra, r0, 264); // addiu ra, r0, 264 + c->lwu(gp, 16, gp); // lwu gp, 16(gp) + c->andi(gp, gp, 16383); // andi gp, gp, 16383 + // c->sw(t4, 32, v1); // sw t4, 32(v1) + qwc = c->sgpr64(t4); + c->daddu(a1, a1, t9); // daddu a1, a1, t9 + // c->sw(gp, 128, v1); // sw gp, 128(v1) + sadr = c->sgpr64(gp); + c->addiu(t4, r0, 0); // addiu t4, r0, 0 + // c->sw(ra, 0, v1); // sw ra, 0(v1) + spad_to_dma_no_sadr_off_bones_interleave(cache.fake_scratchpad_data, madr, sadr, qwc); + + block_15: + // nop // sll r0, r0, 0 + c->sw(t8, 228, at); // sw t8, 228(at) + // nop // sll r0, r0, 0 + c->lqc2(vf1, 0, t5); // lqc2 vf1, 0(t5) + // nop // sll r0, r0, 0 + c->lqc2(vf2, 16, t5); // lqc2 vf2, 16(t5) + // nop // sll r0, r0, 0 + c->lqc2(vf3, 32, t5); // lqc2 vf3, 32(t5) + // nop // sll r0, r0, 0 + c->lqc2(vf4, 48, t5); // lqc2 vf4, 48(t5) + // nop // sll r0, r0, 0 + c->lqc2(vf5, 0, t7); // lqc2 vf5, 0(t7) + // nop // sll r0, r0, 0 + c->lqc2(vf6, 16, t7); // lqc2 vf6, 16(t7) + // nop // sll r0, r0, 0 + c->lqc2(vf7, 32, t7); // lqc2 vf7, 32(t7) + // nop // sll r0, r0, 0 + c->lqc2(vf8, 48, t7); // lqc2 vf8, 48(t7) + // Unknown instr: vcallms 0 + exec_mpg(c); + // nop // sll r0, r0, 0 + + block_16: + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->daddiu(t5, t5, 64); // daddiu t5, t5, 64 + // nop // sll r0, r0, 0 + c->daddiu(t7, t7, 96); // daddiu t7, t7, 96 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->lq(t8, 0, t5); // lq t8, 0(t5) +// printf("load is 0x%lx, 0x%lx\n", c->sgpr64(t5), c->sgpr64(t7)); +// printf("t8: %f %f %f\n", c->gprs[t8].f[0], c->gprs[t8].f[1], c->gprs[t8].f[2]); + + // nop // sll r0, r0, 0 + c->lq(t9, 16, t5); // lq t9, 16(t5) + // nop // sll r0, r0, 0 + c->lq(ra, 32, t5); // lq ra, 32(t5) + // nop // sll r0, r0, 0 + c->lq(gp, 48, t5); // lq gp, 48(t5) +// printf("t5: %f %f %f\n", c->gprs[gp].f[0], c->gprs[gp].f[1], c->gprs[gp].f[2]); + // nop // sll r0, r0, 0 + c->lq(s5, 0, t7); // lq s5, 0(t7) + // nop // sll r0, r0, 0 + c->lq(s4, 16, t7); // lq s4, 16(t7) + // nop // sll r0, r0, 0 + c->lq(s3, 32, t7); // lq s3, 32(t7) + // nop // sll r0, r0, 0 + c->lq(s2, 48, t7); // lq s2, 48(t7) +// printf("t7: %f %f %f\n", c->gprs[s3].f[0], c->gprs[s3].f[1], c->gprs[s3].f[2]); + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf1, t8); // qmtc2.ni vf1, t8 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf2, t9); // qmtc2.ni vf2, t9 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf3, ra); // qmtc2.ni vf3, ra + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf4, gp); // qmtc2.ni vf4, gp + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf5, s5); // qmtc2.ni vf5, s5 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf6, s4); // qmtc2.ni vf6, s4 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf7, s3); // qmtc2.ni vf7, s3 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf8, s2); // qmtc2.ni vf8, s2 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(t8, vf13); // qmfc2.i t8, vf13 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(t9, vf14); // qmfc2.ni t9, vf14 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(ra, vf15); // qmfc2.ni ra, vf15 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(gp, vf16); // qmfc2.ni gp, vf16 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(s5, vf9); // qmfc2.ni s5, vf9 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(s4, vf10); // qmfc2.ni s4, vf10 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(s3, vf11); // qmfc2.ni s3, vf11 + // Unknown instr: vcallms 0 + exec_mpg(c); + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 +// printf("store is 0x%lx\n", c->sgpr64(t3)); + c->sq(t8, 0, t3); // sq t8, 0(t3) + // nop // sll r0, r0, 0 + c->sq(t9, 16, t3); // sq t9, 16(t3) + // nop // sll r0, r0, 0 + c->sq(ra, 32, t3); // sq ra, 32(t3) + // nop // sll r0, r0, 0 + c->sq(gp, 48, t3); // sq gp, 48(t3) + // nop // sll r0, r0, 0 + c->sq(s5, 64, t3); // sq s5, 64(t3) + // nop // sll r0, r0, 0 + c->sq(s4, 80, t3); // sq s4, 80(t3) + // nop // sll r0, r0, 0 + c->sq(s3, 96, t3); // sq s3, 96(t3) + // nop // sll r0, r0, 0 + c->sq(r0, 112, t3); // sq r0, 112(t3) + c->daddiu(t3, t3, 128); // daddiu t3, t3, 128 + c->daddiu(t6, t6, -1); // daddiu t6, t6, -1 + bc = ((s64)c->sgpr64(t6)) > 0; // bgtz t6, L126 + // nop // sll r0, r0, 0 + if (bc) {goto block_16;} // branch non-likely + + // nop // sll r0, r0, 0 + c->lw(t3, 228, at); // lw t3, 228(at) + bc = c->sgpr64(t3) == 0; // beq t3, r0, L129 + // nop // sll r0, r0, 0 + if (bc) {goto block_21;} // branch non-likely + + /* + block_18: + c->lw(t4, 0, v1); // lw t4, 0(v1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->andi(t4, t4, 256); // andi t4, t4, 256 + // nop // sll r0, r0, 0 + bc = c->sgpr64(t4) == 0; // beq t4, r0, L128 + // nop // sll r0, r0, 0 + if (bc) {goto block_20;} // branch non-likely + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + //beq r0, r0, L127 // beq r0, r0, L127 + // nop // sll r0, r0, 0 + goto block_18; // branch always + */ + + + c->dsll(t5, t2, 2); // dsll t5, t2, 2 + // nop // sll r0, r0, 0 + c->addiu(t4, r0, 1); // addiu t4, r0, 1 + c->daddu(t6, t5, at); // daddu t6, t5, at + c->dsll(t5, t3, 1); // dsll t5, t3, 1 + c->lwu(t7, 24, t6); // lwu t7, 24(t6) + c->dsll(t6, t3, 2); // dsll t6, t3, 2 + c->andi(t7, t7, 16383); // andi t7, t7, 16383 + c->daddu(t5, t6, t5); // daddu t5, t6, t5 + // c->sw(t7, 128, v1); // sw t7, 128(v1) + sadr = c->sgpr64(t7); + c->dsll(t6, t5, 4); // dsll t6, t5, 4 + //c->sw(a2, 16, v1); // sw a2, 16(v1) + madr = c->sgpr64(a2); + c->addiu(t7, r0, 256); // addiu t7, r0, 256 + // c->sw(t5, 32, v1); // sw t5, 32(v1) + qwc = c->sgpr64(t5); + c->daddu(a2, a2, t6); // daddu a2, a2, t6 + // c->sw(t7, 0, v1); // sw t7, 0(v1) + spad_to_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); + + block_21: + // nop // sll r0, r0, 0 + c->lw(t5, 236, at); // lw t5, 236(at) + // nop // sll r0, r0, 0 + c->lw(t6, 232, at); // lw t6, 232(at) + + /* + block_22: + c->lw(t7, 0, t0); // lw t7, 0(t0) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->andi(t7, t7, 256); // andi t7, t7, 256 + // nop // sll r0, r0, 0 + bc = c->sgpr64(t7) == 0; // beq t7, r0, L131 + // nop // sll r0, r0, 0 + if (bc) {goto block_24;} // branch non-likely + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + //beq r0, r0, L130 // beq r0, r0, L130 + // nop // sll r0, r0, 0 + goto block_22; // branch always + */ + + + bc = c->sgpr64(t6) == 0; // beq t6, r0, L132 + // nop // sll r0, r0, 0 + if (bc) {goto block_26;} // branch non-likely + + c->dsll(t7, t5, 2); // dsll t7, t5, 2 + // c->lui(t8, 28672); // lui t8, 28672 + get_fake_spad_addr(t8, cache.fake_scratchpad_data, 0, c); + c->daddu(t7, t7, t8); // daddu t7, t7, t8 + c->lwu(t7, 32, t7); // lwu t7, 32(t7) + c->andi(t7, t7, 16383); // andi t7, t7, 16383 + //c->sw(t7, 128, t0); // sw t7, 128(t0) + sadr = c->sgpr64(t7); + //c->sw(a0, 16, t0); // sw a0, 16(t0) + madr = c->sgpr64(a0); + c->dsll(t7, t6, 3); // dsll t7, t6, 3 + // c->sw(t7, 32, t0); // sw t7, 32(t0) + qwc = c->sgpr64(t7); + c->addiu(t7, r0, 256); // addiu t7, r0, 256 + // c->sw(t7, 0, t0); // sw t7, 0(t0) + spad_from_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); + c->dsll(t6, t6, 7); // dsll t6, t6, 7 + c->daddu(a0, a0, t6); // daddu a0, a0, t6 + + block_26: + bc = c->sgpr64(t3) == 0; // beq t3, r0, L135 + // nop // sll r0, r0, 0 + if (bc) {goto block_31;} // branch non-likely + + bc = c->sgpr64(t4) != 0; // bne t4, r0, L135 + // nop // sll r0, r0, 0 + if (bc) {goto block_31;} // branch non-likely + + /* + block_28: + c->lw(t6, 0, v1); // lw t6, 0(v1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->andi(t6, t6, 256); // andi t6, t6, 256 + // nop // sll r0, r0, 0 + bc = c->sgpr64(t6) == 0; // beq t6, r0, L134 + // nop // sll r0, r0, 0 + if (bc) {goto block_30;} // branch non-likely + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + //beq r0, r0, L133 // beq r0, r0, L133 + // nop // sll r0, r0, 0 + goto block_28; // branch always + */ + + + c->dsll(t6, t2, 2); // dsll t6, t2, 2 + // c->lui(t7, 28672); // lui t7, 28672 + get_fake_spad_addr(t7, cache.fake_scratchpad_data, 0, c); + c->daddu(t6, t6, t7); // daddu t6, t6, t7 + c->lwu(t6, 24, t6); // lwu t6, 24(t6) + c->andi(t6, t6, 16383); // andi t6, t6, 16383 + //c->sw(t6, 128, v1); // sw t6, 128(v1) + sadr = c->sgpr64(t6); + //c->sw(a2, 16, v1); // sw a2, 16(v1) + madr = c->sgpr64(a2); + c->addiu(t6, r0, 6); // addiu t6, r0, 6 + c->mult3(t6, t6, t3); // mult3 t6, t6, t3 + //c->sw(t6, 32, v1); // sw t6, 32(v1) + qwc = c->sgpr64(t6); + c->addiu(t6, r0, 256); // addiu t6, r0, 256 + //c->sw(t6, 0, v1); // sw t6, 0(v1) + spad_to_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); + c->addiu(t6, r0, 96); // addiu t6, r0, 96 + c->mult3(t6, t6, t3); // mult3 t6, t6, t3 + c->daddu(a2, a2, t6); // daddu a2, a2, t6 + + block_31: + c->mov64(t8, t2); // or t8, t2, r0 + bc = c->sgpr64(t1) != 0; // bne t1, r0, L122 + c->mov64(t2, t5); // or t2, t5, r0 + if (bc) {goto block_9;} // branch non-likely + + bc = c->sgpr64(a3) == 0; // beq a3, r0, L122 + c->addiu(a3, r0, 1); // addiu a3, r0, 1 + if (bc) {goto block_9;} // branch non-likely + + + block_33: + c->gprs[v0].du64[0] = 0; // or v0, r0, r0 + c->ld(ra, 0, sp); // ld ra, 0(sp) + c->lq(gp, 80, sp); // lq gp, 80(sp) + c->lq(s5, 64, sp); // lq s5, 64(sp) + c->lq(s4, 48, sp); // lq s4, 48(sp) + c->lq(s3, 32, sp); // lq s3, 32(sp) + c->lq(s2, 16, sp); // lq s2, 16(sp) + //jr ra // jr ra + c->daddiu(sp, sp, 96); // daddiu sp, sp, 96 + 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() { + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + gLinkedFunctionTable.reg("bones-mtx-calc", execute, 256); +} + +} // namespace bones_mtx_calc +} // namespace Mips2C + diff --git a/game/mips2c/functions/joint.cpp b/game/mips2c/functions/joint.cpp new file mode 100644 index 0000000000..3e8217e994 --- /dev/null +++ b/game/mips2c/functions/joint.cpp @@ -0,0 +1,2543 @@ +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" + +// clang-format off + +namespace { +struct Cache { + void* clear_frame_accumulator; // clear-frame-accumulator + void* decompress_fixed_data_to_accumulator; // decompress-fixed-data-to-accumulator + void* decompress_frame_data_pair_to_accumulator; // decompress-frame-data-pair-to-accumulator + void* decompress_frame_data_to_accumulator; // decompress-frame-data-to-accumulator + void* normalize_frame_quaternions; // normalize-frame-quaternions + void* fake_scratchpad_data; // *fake-scratchpad-data* + +} cache; +} + +namespace Mips2C { +namespace decompress_frame_data_pair_to_accumulator { +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + u32 next_block = 0; + while(true) { + switch(next_block) { + + case 0: + next_block = 1; + c->daddiu(sp, sp, -64); // daddiu sp, sp, -64 + c->sq(a0, 0, sp); // sq a0, 0(sp) + c->sq(t7, 16, sp); // sq t7, 16(sp) + c->sq(s0, 32, sp); // sq s0, 32(sp) + c->sq(s1, 48, sp); // sq s1, 48(sp) + c->mov128_vf_gpr(vf11, t0); // qmtc2.i vf11, t0 + c->daddu(a3, a3, a1); // daddu a3, a3, a1 + c->mov128_vf_gpr(vf13, a2); // qmtc2.i vf13, a2 + //c->lui(t2, 28672); // lui t2, 28672 + get_fake_spad_addr(t2, cache.fake_scratchpad_data, 0, c); + c->lw(t4, 0, a1); // lw t4, 0(a1) + c->daddiu(v1, a1, 16); // daddiu v1, a1, 16 + c->lw(t5, 4, a1); // lw t5, 4(a1) + c->daddu(s5, t1, r0); // daddu s5, t1, r0 + c->lw(t6, 8, a1); // lw t6, 8(a1) + c->daddu(t4, t4, v1); // daddu t4, t4, v1 + c->vsub_bc(DEST::w, BC::x, vf11, vf0, vf11); // vsubx.w vf11, vf0, vf11 + c->lw(t7, 0, a3); // lw t7, 0(a3) + c->vmul_bc(DEST::xyzw, BC::x, vf13, vf14, vf13); // vmulx.xyzw vf13, vf14, vf13 + c->daddiu(t2, t2, 1760); // daddiu t2, t2, 1760 + c->lw(s2, 56, t1); // lw s2, 56(t1) + c->daddu(t5, t5, v1); // daddu t5, t5, v1 + c->lw(s4, 60, t1); // lw s4, 60(t1) + c->daddu(t6, t6, v1); // daddu t6, t6, v1 + c->addiu(s3, r0, 8); // addiu s3, r0, 8 + c->daddiu(s5, s5, 4); // daddiu s5, s5, 4 + c->vmul_bc(DEST::xy, BC::w, vf13, vf13, vf11); // vmulw.xy vf13, vf13, vf11 + c->lw(s0, 4, a3); // lw s0, 4(a3) + c->vmul_bc(DEST::zw, BC::x, vf13, vf13, vf11); // vmulx.zw vf13, vf13, vf11 + c->lw(s1, 8, a3); // lw s1, 8(a3) + // nop // sll r0, r0, 0 + c->daddiu(v1, a3, 16); // daddiu v1, a3, 16 + c->daddu(t7, t7, v1); // daddu t7, t7, v1 + c->daddu(s0, s0, v1); // daddu s0, s0, v1 + c->daddu(s1, s1, v1); // daddu s1, s1, v1 + // nop // sll r0, r0, 0 + c->andi(t3, s4, 1); // andi t3, s4, 1 + // nop // sll r0, r0, 0 + bc = c->sgpr64(t3) == 0; // beq t3, r0, L10 + // nop // sll r0, r0, 0 + if (bc) {next_block = 2;} // branch non-likely + + break; + + case 1: + next_block = 2; + c->lqc2(vf1, 0, t4); // lqc2 vf1, 0(t4) + c->lqc2(vf2, 16, t4); // lqc2 vf2, 16(t4) + c->lqc2(vf3, 32, t4); // lqc2 vf3, 32(t4) + c->lqc2(vf4, 48, t4); // lqc2 vf4, 48(t4) + c->lqc2(vf5, 0, t7); // lqc2 vf5, 0(t7) + c->lqc2(vf6, 16, t7); // lqc2 vf6, 16(t7) + c->lqc2(vf7, 32, t7); // lqc2 vf7, 32(t7) + c->lqc2(vf8, 48, t7); // lqc2 vf8, 48(t7) + c->lqc2(vf9, 0, a0); // lqc2 vf9, 0(a0) + c->daddiu(t4, t4, 64); // daddiu t4, t4, 64 + c->lqc2(vf10, 16, a0); // lqc2 vf10, 16(a0) + c->daddiu(t7, t7, 64); // daddiu t7, t7, 64 + c->lqc2(vf11, 32, a0); // lqc2 vf11, 32(a0) + c->lqc2(vf12, 48, a0); // lqc2 vf12, 48(a0) + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf13); // vmaddax.xyzw acc, vf1, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf5, vf13); // vmaddw.xyzw vf9, vf5, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf2, vf13); // vmaddax.xyzw acc, vf2, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf10, vf6, vf13); // vmaddw.xyzw vf10, vf6, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf11, vf0); // vmulaw.xyzw acc, vf11, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf3, vf13); // vmaddax.xyzw acc, vf3, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf11, vf7, vf13); // vmaddw.xyzw vf11, vf7, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf12, vf0); // vmulaw.xyzw acc, vf12, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf4, vf13); // vmaddax.xyzw acc, vf4, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf12, vf8, vf13); // vmaddw.xyzw vf12, vf8, vf13 + c->sqc2(vf9, 0, a0); // sqc2 vf9, 0(a0) + c->sqc2(vf10, 16, a0); // sqc2 vf10, 16(a0) + c->sqc2(vf11, 32, a0); // sqc2 vf11, 32(a0) + c->sqc2(vf12, 48, a0); // sqc2 vf12, 48(a0) + + case 2: + next_block = 3; + c->andi(t3, s4, 2); // andi t3, s4, 2 + c->daddiu(a0, a0, 64); // daddiu a0, a0, 64 + bc = c->sgpr64(t3) == 0; // beq t3, r0, L11 + // nop // sll r0, r0, 0 + if (bc) {next_block = 4;} // branch non-likely + + break; + + case 3: + next_block = 4; + c->lqc2(vf1, 0, t4); // lqc2 vf1, 0(t4) + c->lqc2(vf2, 16, t4); // lqc2 vf2, 16(t4) + c->lqc2(vf3, 32, t4); // lqc2 vf3, 32(t4) + c->lqc2(vf4, 48, t4); // lqc2 vf4, 48(t4) + c->lqc2(vf5, 0, t7); // lqc2 vf5, 0(t7) + c->lqc2(vf6, 16, t7); // lqc2 vf6, 16(t7) + c->lqc2(vf7, 32, t7); // lqc2 vf7, 32(t7) + c->lqc2(vf8, 48, t7); // lqc2 vf8, 48(t7) + c->lqc2(vf9, 0, a0); // lqc2 vf9, 0(a0) + c->daddiu(t4, t4, 64); // daddiu t4, t4, 64 + c->lqc2(vf10, 16, a0); // lqc2 vf10, 16(a0) + c->daddiu(t7, t7, 64); // daddiu t7, t7, 64 + c->lqc2(vf11, 32, a0); // lqc2 vf11, 32(a0) + c->lqc2(vf12, 48, a0); // lqc2 vf12, 48(a0) + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf13); // vmaddax.xyzw acc, vf1, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf5, vf13); // vmaddw.xyzw vf9, vf5, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf2, vf13); // vmaddax.xyzw acc, vf2, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf10, vf6, vf13); // vmaddw.xyzw vf10, vf6, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf11, vf0); // vmulaw.xyzw acc, vf11, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf3, vf13); // vmaddax.xyzw acc, vf3, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf11, vf7, vf13); // vmaddw.xyzw vf11, vf7, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf12, vf0); // vmulaw.xyzw acc, vf12, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf4, vf13); // vmaddax.xyzw acc, vf4, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf12, vf8, vf13); // vmaddw.xyzw vf12, vf8, vf13 + c->sqc2(vf9, 0, a0); // sqc2 vf9, 0(a0) + c->sqc2(vf10, 16, a0); // sqc2 vf10, 16(a0) + c->sqc2(vf11, 32, a0); // sqc2 vf11, 32(a0) + c->sqc2(vf12, 48, a0); // sqc2 vf12, 48(a0) + + case 4: + next_block = 5; + c->lw(s4, -4, s5); // lw s4, -4(s5) + c->daddiu(a0, a0, 64); // daddiu a0, a0, 64 + + case 5: + next_block = 6; + c->andi(t3, s4, 15); // andi t3, s4, 15 + c->sra(s4, s4, 4); // sra s4, s4, 4 + c->sll(t3, t3, 2); // sll t3, t3, 2 + c->daddiu(s3, s3, -1); // daddiu s3, s3, -1 + c->daddu(t3, t3, t2); // daddu t3, t3, t2 + c->daddiu(s2, s2, -1); // daddiu s2, s2, -1 + c->lw(t3, 0, t3); // lw t3, 0(t3) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + next_block = 0x4d7666d9 ^ c->gprs[t3].du32[0]; // jr t3 + assert(next_block < 33); + break; + // nop // sll r0, r0, 0 + + case 6: + next_block = 7; + bc = c->sgpr64(s2) == 0; // beq s2, r0, L20 + c->daddiu(a0, a0, 48); // daddiu a0, a0, 48 + if (bc) {next_block = 32;} // branch non-likely + + break; + + case 7: + next_block = 8; + bc = c->sgpr64(s3) != 0; // bne s3, r0, L12 + // nop // sll r0, r0, 0 + if (bc) {next_block = 5;} // branch non-likely + + break; + + case 8: + next_block = 9; + c->lw(s4, 0, s5); // lw s4, 0(s5) + c->daddiu(s5, s5, 4); // daddiu s5, s5, 4 + //beq r0, r0, L12 // beq r0, r0, L12 + c->addiu(s3, r0, 8); // addiu s3, r0, 8 + next_block = 5; // branch always + + break; + + case 9: + next_block = 10; + c->lw(s6, 0, t5); // lw s6, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(gp, 0, t6); // lh gp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->lw(s6, 0, s0); // lw s6, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->lh(gp, 0, s1); // lh gp, 0(s1) + c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 + c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 + c->vitof0(DEST::xyzw, vf2, vf2); // vitof0.xyzw vf2, vf2 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadda_bc(DEST::xyzw, BC::y, vf1, vf13); // vmadday.xyzw acc, vf1, vf13 + c->vmadd_bc(DEST::xyzw, BC::z, vf3, vf2, vf13); // vmaddz.xyzw vf3, vf2, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + //beq r0, r0, L13 // beq r0, r0, L13 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 10: + next_block = 11; + c->ld(s6, 0, t4); // ld s6, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lw(gp, 0, t5); // lw gp, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->ld(s6, 0, t7); // ld s6, 0(t7) + c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 + c->lw(gp, 0, s0); // lw gp, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf13); // vmaddax.xyzw acc, vf1, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf3, vf2, vf13); // vmaddw.xyzw vf3, vf2, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + //beq r0, r0, L13 // beq r0, r0, L13 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 11: + next_block = 12; + c->ld(t9, 0, t4); // ld t9, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->ld(t9, 0, t7); // ld t9, 0(t7) + c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf5, t9); // qmtc2.i vf5, t9 + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->vitof15(DEST::xyzw, vf5, vf5); // vitof15.xyzw vf5, vf5 + c->vmula_bc(DEST::xyzw, BC::x, vf4, vf13); // vmulax.xyzw acc, vf4, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf4, vf5, vf13); // vmaddw.xyzw vf4, vf5, vf13 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L14 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 13; + break; + } + + case 13: + next_block = 14; + c->vadd(DEST::xyzw, vf6, vf6, vf4); // vadd.xyzw vf6, vf6, vf4 + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + //beq r0, r0, L13 // beq r0, r0, L13 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 14: + next_block = 15; + c->ld(t9, 0, t4); // ld t9, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->ld(t9, 0, t7); // ld t9, 0(t7) + c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf5, t9); // qmtc2.i vf5, t9 + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->lw(s6, 0, t5); // lw s6, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(gp, 0, t6); // lh gp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->vitof15(DEST::xyzw, vf5, vf5); // vitof15.xyzw vf5, vf5 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->vmula_bc(DEST::xyzw, BC::x, vf4, vf13); // vmulax.xyzw acc, vf4, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf4, vf5, vf13); // vmaddw.xyzw vf4, vf5, vf13 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->lw(s6, 0, s0); // lw s6, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->lh(gp, 0, s1); // lh gp, 0(s1) + c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 + c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L15 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 16; + break; + } + + case 16: + next_block = 17; + c->vitof0(DEST::xyzw, vf2, vf2); // vitof0.xyzw vf2, vf2 + c->vadd(DEST::xyzw, vf6, vf6, vf4); // vadd.xyzw vf6, vf6, vf4 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadda_bc(DEST::xyzw, BC::y, vf1, vf13); // vmadday.xyzw acc, vf1, vf13 + c->vmadd_bc(DEST::xyzw, BC::z, vf3, vf2, vf13); // vmaddz.xyzw vf3, vf2, vf13 + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + //beq r0, r0, L13 // beq r0, r0, L13 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 17: + next_block = 18; + c->ld(t9, 8, t4); // ld t9, 8(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->ld(t9, 8, t7); // ld t9, 8(t7) + c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf5, t9); // qmtc2.i vf5, t9 + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->ld(s6, -8, t4); // ld s6, -8(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lw(gp, 0, t5); // lw gp, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->vitof15(DEST::xyzw, vf5, vf5); // vitof15.xyzw vf5, vf5 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->vmula_bc(DEST::xyzw, BC::x, vf4, vf13); // vmulax.xyzw acc, vf4, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf4, vf5, vf13); // vmaddw.xyzw vf4, vf5, vf13 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->ld(s6, -8, t7); // ld s6, -8(t7) + c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 + c->lw(gp, 0, s0); // lw gp, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L16 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 19; + break; + } + + case 19: + next_block = 20; + c->vadd(DEST::xyzw, vf6, vf6, vf4); // vadd.xyzw vf6, vf6, vf4 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf13); // vmaddax.xyzw acc, vf1, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf3, vf2, vf13); // vmaddw.xyzw vf3, vf2, vf13 + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + //beq r0, r0, L13 // beq r0, r0, L13 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 20: + next_block = 21; + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->lw(t8, 0, s0); // lw t8, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->lh(fp, 0, s1); // lh fp, 0(s1) + c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf8, t8); // qmtc2.i vf8, t8 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vitof12(DEST::xyzw, vf8, vf8); // vitof12.xyzw vf8, vf8 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf7, vf13); // vmaddax.xyzw acc, vf7, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf8, vf13); // vmaddw.xyzw vf9, vf8, vf13 + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L13 // beq r0, r0, L13 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 21: + next_block = 22; + c->lw(s6, 0, t5); // lw s6, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(gp, 0, t6); // lh gp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->lw(s6, 0, s0); // lw s6, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->lh(gp, 0, s1); // lh gp, 0(s1) + c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 + c->vitof0(DEST::xyzw, vf2, vf2); // vitof0.xyzw vf2, vf2 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadda_bc(DEST::xyzw, BC::y, vf1, vf13); // vmadday.xyzw acc, vf1, vf13 + c->vmadd_bc(DEST::xyzw, BC::z, vf3, vf2, vf13); // vmaddz.xyzw vf3, vf2, vf13 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->lw(t8, 0, s0); // lw t8, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->lh(fp, 0, s1); // lh fp, 0(s1) + c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf8, t8); // qmtc2.i vf8, t8 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vitof12(DEST::xyzw, vf8, vf8); // vitof12.xyzw vf8, vf8 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf7, vf13); // vmaddax.xyzw acc, vf7, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf8, vf13); // vmaddw.xyzw vf9, vf8, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L13 // beq r0, r0, L13 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 22: + next_block = 23; + c->ld(s6, 0, t4); // ld s6, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lw(gp, 0, t5); // lw gp, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->ld(s6, 0, t7); // ld s6, 0(t7) + c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 + c->lw(gp, 0, s0); // lw gp, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf13); // vmaddax.xyzw acc, vf1, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf3, vf2, vf13); // vmaddw.xyzw vf3, vf2, vf13 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->lw(t8, 0, s0); // lw t8, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->lh(fp, 0, s1); // lh fp, 0(s1) + c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf8, t8); // qmtc2.i vf8, t8 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vitof12(DEST::xyzw, vf8, vf8); // vitof12.xyzw vf8, vf8 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf7, vf13); // vmaddax.xyzw acc, vf7, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf8, vf13); // vmaddw.xyzw vf9, vf8, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L13 // beq r0, r0, L13 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 23: + next_block = 24; + c->ld(t9, 0, t4); // ld t9, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->ld(t9, 0, t7); // ld t9, 0(t7) + c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf5, t9); // qmtc2.i vf5, t9 + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->vitof15(DEST::xyzw, vf5, vf5); // vitof15.xyzw vf5, vf5 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->vmula_bc(DEST::xyzw, BC::x, vf4, vf13); // vmulax.xyzw acc, vf4, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf4, vf5, vf13); // vmaddw.xyzw vf4, vf5, vf13 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->lw(t8, 0, s0); // lw t8, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->lh(fp, 0, s1); // lh fp, 0(s1) + c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf8, t8); // qmtc2.i vf8, t8 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vitof12(DEST::xyzw, vf8, vf8); // vitof12.xyzw vf8, vf8 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L17 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 25; + break; + } + + case 25: + next_block = 26; + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf7, vf13); // vmaddax.xyzw acc, vf7, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf8, vf13); // vmaddw.xyzw vf9, vf8, vf13 + c->vadd(DEST::xyzw, vf6, vf6, vf4); // vadd.xyzw vf6, vf6, vf4 + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L13 // beq r0, r0, L13 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 26: + next_block = 27; + c->ld(t9, 0, t4); // ld t9, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->ld(t9, 0, t7); // ld t9, 0(t7) + c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf5, t9); // qmtc2.i vf5, t9 + c->lw(s6, 0, t5); // lw s6, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(gp, 0, t6); // lh gp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->vitof15(DEST::xyzw, vf5, vf5); // vitof15.xyzw vf5, vf5 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->vmula_bc(DEST::xyzw, BC::x, vf4, vf13); // vmulax.xyzw acc, vf4, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf4, vf5, vf13); // vmaddw.xyzw vf4, vf5, vf13 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->lw(s6, 0, s0); // lw s6, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->lh(gp, 0, s1); // lh gp, 0(s1) + c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L18 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 28; + break; + } + + case 28: + next_block = 29; + c->vitof0(DEST::xyzw, vf2, vf2); // vitof0.xyzw vf2, vf2 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadda_bc(DEST::xyzw, BC::y, vf1, vf13); // vmadday.xyzw acc, vf1, vf13 + c->vmadd_bc(DEST::xyzw, BC::z, vf3, vf2, vf13); // vmaddz.xyzw vf3, vf2, vf13 + c->vadd(DEST::xyzw, vf6, vf6, vf4); // vadd.xyzw vf6, vf6, vf4 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->lw(t8, 0, s0); // lw t8, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->lh(fp, 0, s1); // lh fp, 0(s1) + c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf8, t8); // qmtc2.i vf8, t8 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vitof12(DEST::xyzw, vf8, vf8); // vitof12.xyzw vf8, vf8 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf7, vf13); // vmaddax.xyzw acc, vf7, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf8, vf13); // vmaddw.xyzw vf9, vf8, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L13 // beq r0, r0, L13 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 29: + next_block = 30; + c->ld(t9, 8, t4); // ld t9, 8(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->ld(t9, 8, t7); // ld t9, 8(t7) + c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf5, t9); // qmtc2.i vf5, t9 + c->ld(s6, -8, t4); // ld s6, -8(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lw(gp, 0, t5); // lw gp, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->vitof15(DEST::xyzw, vf5, vf5); // vitof15.xyzw vf5, vf5 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->vmula_bc(DEST::xyzw, BC::x, vf4, vf13); // vmulax.xyzw acc, vf4, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf4, vf5, vf13); // vmaddw.xyzw vf4, vf5, vf13 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->ld(s6, -8, t7); // ld s6, -8(t7) + c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 + c->lw(gp, 0, s0); // lw gp, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L19 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 31; + break; + } + + case 31: + next_block = 32; + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf13); // vmaddax.xyzw acc, vf1, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf3, vf2, vf13); // vmaddw.xyzw vf3, vf2, vf13 + c->vadd(DEST::xyzw, vf6, vf6, vf4); // vadd.xyzw vf6, vf6, vf4 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->lw(t8, 0, s0); // lw t8, 0(s0) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->lh(fp, 0, s1); // lh fp, 0(s1) + c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf8, t8); // qmtc2.i vf8, t8 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vitof12(DEST::xyzw, vf8, vf8); // vitof12.xyzw vf8, vf8 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadda_bc(DEST::xyzw, BC::x, vf7, vf13); // vmaddax.xyzw acc, vf7, vf13 + c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf8, vf13); // vmaddw.xyzw vf9, vf8, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L13 // beq r0, r0, L13 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 32: + next_block = 33; + c->lq(a0, 0, sp); // lq a0, 0(sp) + c->lq(t7, 16, sp); // lq t7, 16(sp) + c->lq(s0, 32, sp); // lq s0, 32(sp) + c->lq(s1, 48, sp); // lq s1, 48(sp) + //jr ra // jr ra + c->daddiu(sp, sp, 64); // daddiu sp, sp, 64 + goto end_of_function; // return + + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + } + } + end_of_function: + return c->gprs[v0].du64[0]; +} + +u32 jump_table_vals[16] = { + 0x4d7666df, // = 6 ^ 1299605209 + 0x4d7666d0, // = 9 ^ 1299605209 + 0x4d7666d2, // = 11 ^ 1299605209 + 0x4d7666d7, // = 14 ^ 1299605209 + 0x4d7666cd, // = 20 ^ 1299605209 + 0x4d7666cc, // = 21 ^ 1299605209 + 0x4d7666ce, // = 23 ^ 1299605209 + 0x4d7666c3, // = 26 ^ 1299605209 + 0x4d7666df, // = 6 ^ 1299605209 + 0x4d7666d3, // = 10 ^ 1299605209 + 0x4d7666d2, // = 11 ^ 1299605209 + 0x4d7666c8, // = 17 ^ 1299605209 + 0x4d7666cd, // = 20 ^ 1299605209 + 0x4d7666cf, // = 22 ^ 1299605209 + 0x4d7666ce, // = 23 ^ 1299605209 + 0x4d7666c4, // = 29 ^ 1299605209 +}; + +} // namespace decompress_frame_data_pair_to_accumulator +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace decompress_frame_data_to_accumulator { +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + u32 next_block = 0; + while(true) { + switch(next_block) { + + case 0: + next_block = 1; + c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 + c->mov128_vf_gpr(vf13, a2); // qmtc2.i vf13, a2 + c->sq(a0, 0, sp); // sq a0, 0(sp) + //c->lui(t2, 28672); // lui t2, 28672 + get_fake_spad_addr(t2, cache.fake_scratchpad_data, 0, c); + c->lw(t4, 0, a1); // lw t4, 0(a1) + c->daddiu(v1, a1, 16); // daddiu v1, a1, 16 + c->lw(t5, 4, a1); // lw t5, 4(a1) + c->daddu(s5, t1, r0); // daddu s5, t1, r0 + c->lw(t6, 8, a1); // lw t6, 8(a1) + c->daddu(t4, t4, v1); // daddu t4, t4, v1 + c->vmul_bc(DEST::xyzw, BC::x, vf13, vf14, vf13); // vmulx.xyzw vf13, vf14, vf13 + c->daddiu(t2, t2, 1696); // daddiu t2, t2, 1696 + c->lw(s2, 56, t1); // lw s2, 56(t1) + c->daddu(t5, t5, v1); // daddu t5, t5, v1 + c->lw(s4, 60, t1); // lw s4, 60(t1) + c->daddu(t6, t6, v1); // daddu t6, t6, v1 + c->addiu(s3, r0, 8); // addiu s3, r0, 8 + c->daddiu(s5, s5, 4); // daddiu s5, s5, 4 + c->andi(t3, s4, 1); // andi t3, s4, 1 + // nop // sll r0, r0, 0 + bc = c->sgpr64(t3) == 0; // beq t3, r0, L22 + // nop // sll r0, r0, 0 + if (bc) {next_block = 2;} // branch non-likely + + break; + + case 1: + next_block = 2; + c->lqc2(vf1, 0, t4); // lqc2 vf1, 0(t4) + c->lqc2(vf2, 16, t4); // lqc2 vf2, 16(t4) + c->lqc2(vf3, 32, t4); // lqc2 vf3, 32(t4) + c->lqc2(vf4, 48, t4); // lqc2 vf4, 48(t4) + c->lqc2(vf9, 0, a0); // lqc2 vf9, 0(a0) + c->daddiu(t4, t4, 64); // daddiu t4, t4, 64 + c->lqc2(vf10, 16, a0); // lqc2 vf10, 16(a0) + // nop // sll r0, r0, 0 + c->lqc2(vf11, 32, a0); // lqc2 vf11, 32(a0) + c->lqc2(vf12, 48, a0); // lqc2 vf12, 48(a0) + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf1, vf13); // vmaddx.xyzw vf9, vf1, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf2, vf13); // vmaddx.xyzw vf10, vf2, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf11, vf0); // vmulaw.xyzw acc, vf11, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf11, vf3, vf13); // vmaddx.xyzw vf11, vf3, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf12, vf0); // vmulaw.xyzw acc, vf12, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf12, vf4, vf13); // vmaddx.xyzw vf12, vf4, vf13 + c->sqc2(vf9, 0, a0); // sqc2 vf9, 0(a0) + c->sqc2(vf10, 16, a0); // sqc2 vf10, 16(a0) + c->sqc2(vf11, 32, a0); // sqc2 vf11, 32(a0) + c->sqc2(vf12, 48, a0); // sqc2 vf12, 48(a0) + + case 2: + next_block = 3; + c->andi(t3, s4, 2); // andi t3, s4, 2 + c->daddiu(a0, a0, 64); // daddiu a0, a0, 64 + bc = c->sgpr64(t3) == 0; // beq t3, r0, L23 + // nop // sll r0, r0, 0 + if (bc) {next_block = 4;} // branch non-likely + + break; + + case 3: + next_block = 4; + c->lqc2(vf1, 0, t4); // lqc2 vf1, 0(t4) + c->lqc2(vf2, 16, t4); // lqc2 vf2, 16(t4) + c->lqc2(vf3, 32, t4); // lqc2 vf3, 32(t4) + c->lqc2(vf4, 48, t4); // lqc2 vf4, 48(t4) + c->lqc2(vf9, 0, a0); // lqc2 vf9, 0(a0) + c->daddiu(t4, t4, 64); // daddiu t4, t4, 64 + c->lqc2(vf10, 16, a0); // lqc2 vf10, 16(a0) + // nop // sll r0, r0, 0 + c->lqc2(vf11, 32, a0); // lqc2 vf11, 32(a0) + c->lqc2(vf12, 48, a0); // lqc2 vf12, 48(a0) + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf1, vf13); // vmaddx.xyzw vf9, vf1, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf2, vf13); // vmaddx.xyzw vf10, vf2, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf11, vf0); // vmulaw.xyzw acc, vf11, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf11, vf3, vf13); // vmaddx.xyzw vf11, vf3, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf12, vf0); // vmulaw.xyzw acc, vf12, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf12, vf4, vf13); // vmaddx.xyzw vf12, vf4, vf13 + c->sqc2(vf9, 0, a0); // sqc2 vf9, 0(a0) + c->sqc2(vf10, 16, a0); // sqc2 vf10, 16(a0) + c->sqc2(vf11, 32, a0); // sqc2 vf11, 32(a0) + c->sqc2(vf12, 48, a0); // sqc2 vf12, 48(a0) + + case 4: + next_block = 5; + c->lw(s4, -4, s5); // lw s4, -4(s5) + c->daddiu(a0, a0, 64); // daddiu a0, a0, 64 + + case 5: + next_block = 6; + c->andi(t3, s4, 15); // andi t3, s4, 15 + c->sra(s4, s4, 4); // sra s4, s4, 4 + c->sll(t3, t3, 2); // sll t3, t3, 2 + c->daddiu(s3, s3, -1); // daddiu s3, s3, -1 + c->daddu(t3, t3, t2); // daddu t3, t3, t2 + c->daddiu(s2, s2, -1); // daddiu s2, s2, -1 + c->lw(t3, 0, t3); // lw t3, 0(t3) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + next_block = 0x7b2191d ^ c->gprs[t3].du32[0]; // jr t3 + assert(next_block < 33); + break; + // nop // sll r0, r0, 0 + + case 6: + next_block = 7; + bc = c->sgpr64(s2) == 0; // beq s2, r0, L32 + c->daddiu(a0, a0, 48); // daddiu a0, a0, 48 + if (bc) {next_block = 32;} // branch non-likely + + break; + + case 7: + next_block = 8; + bc = c->sgpr64(s3) != 0; // bne s3, r0, L24 + // nop // sll r0, r0, 0 + if (bc) {next_block = 5;} // branch non-likely + + break; + + case 8: + next_block = 9; + c->lw(s4, 0, s5); // lw s4, 0(s5) + c->daddiu(s5, s5, 4); // daddiu s5, s5, 4 + //beq r0, r0, L24 // beq r0, r0, L24 + c->addiu(s3, r0, 8); // addiu s3, r0, 8 + next_block = 5; // branch always + + break; + + case 9: + next_block = 10; + c->lw(s6, 0, t5); // lw s6, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(gp, 0, t6); // lh gp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + //beq r0, r0, L25 // beq r0, r0, L25 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 10: + next_block = 11; + c->ld(s6, 0, t4); // ld s6, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lw(gp, 0, t5); // lw gp, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + //beq r0, r0, L25 // beq r0, r0, L25 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 11: + next_block = 12; + c->ld(t9, 0, t4); // ld t9, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L26 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 13; + break; + } + + case 13: + next_block = 14; + c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + //beq r0, r0, L25 // beq r0, r0, L25 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 14: + next_block = 15; + c->ld(t9, 0, t4); // ld t9, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->lw(s6, 0, t5); // lw s6, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(gp, 0, t6); // lh gp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L27 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 16; + break; + } + + case 16: + next_block = 17; + c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + //beq r0, r0, L25 // beq r0, r0, L25 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 17: + next_block = 18; + c->ld(t9, 8, t4); // ld t9, 8(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->ld(s6, -8, t4); // ld s6, -8(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lw(gp, 0, t5); // lw gp, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L28 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 19; + break; + } + + case 19: + next_block = 20; + c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + //beq r0, r0, L25 // beq r0, r0, L25 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 20: + next_block = 21; + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L25 // beq r0, r0, L25 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 21: + next_block = 22; + c->lw(s6, 0, t5); // lw s6, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(gp, 0, t6); // lh gp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L25 // beq r0, r0, L25 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 22: + next_block = 23; + c->ld(s6, 0, t4); // ld s6, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lw(gp, 0, t5); // lw gp, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L25 // beq r0, r0, L25 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 23: + next_block = 24; + c->ld(t9, 0, t4); // ld t9, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L29 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 25; + break; + } + + case 25: + next_block = 26; + c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L25 // beq r0, r0, L25 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 26: + next_block = 27; + c->ld(t9, 0, t4); // ld t9, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->lw(s6, 0, t5); // lw s6, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(gp, 0, t6); // lh gp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L30 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 28; + break; + } + + case 28: + next_block = 29; + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L25 // beq r0, r0, L25 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 29: + next_block = 30; + c->ld(t9, 8, t4); // ld t9, 8(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->ld(s6, -8, t4); // ld s6, -8(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lw(gp, 0, t5); // lw gp, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L31 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 31; + break; + } + + case 31: + next_block = 32; + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L25 // beq r0, r0, L25 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 32: + next_block = 33; + c->lq(a0, 0, sp); // lq a0, 0(sp) + // nop // sll r0, r0, 0 + //jr ra // jr ra + c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 + goto end_of_function; // return + + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + } + } + end_of_function: + return c->gprs[v0].du64[0]; +} + +u32 jump_table_vals[16] = { + 0x7b2191b, // = 6 ^ 129112349 + 0x7b21914, // = 9 ^ 129112349 + 0x7b21916, // = 11 ^ 129112349 + 0x7b21913, // = 14 ^ 129112349 + 0x7b21909, // = 20 ^ 129112349 + 0x7b21908, // = 21 ^ 129112349 + 0x7b2190a, // = 23 ^ 129112349 + 0x7b21907, // = 26 ^ 129112349 + 0x7b2191b, // = 6 ^ 129112349 + 0x7b21917, // = 10 ^ 129112349 + 0x7b21916, // = 11 ^ 129112349 + 0x7b2190c, // = 17 ^ 129112349 + 0x7b21909, // = 20 ^ 129112349 + 0x7b2190b, // = 22 ^ 129112349 + 0x7b2190a, // = 23 ^ 129112349 + 0x7b21900, // = 29 ^ 129112349 +}; + +} // namespace decompress_frame_data_to_accumulator +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace decompress_fixed_data_to_accumulator { +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + u32 next_block = 0; + while(true) { + switch(next_block) { + + case 0: + next_block = 1; + c->lq(t4, 0, a1); // lq t4, 0(a1) + c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 + c->lq(t5, 16, a1); // lq t5, 16(a1) + // nop // sll r0, r0, 0 + c->sq(t4, 0, t1); // sq t4, 0(t1) + // nop // sll r0, r0, 0 + c->sq(t5, 16, t1); // sq t5, 16(t1) + // nop // sll r0, r0, 0 + c->lq(t4, 32, a1); // lq t4, 32(a1) + // nop // sll r0, r0, 0 + c->lq(t5, 48, a1); // lq t5, 48(a1) + // nop // sll r0, r0, 0 + c->sq(t4, 32, t1); // sq t4, 32(t1) + // nop // sll r0, r0, 0 + c->sq(t5, 48, t1); // sq t5, 48(t1) + // nop // sll r0, r0, 0 + c->sq(a0, 0, sp); // sq a0, 0(sp) + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf13, a2); // qmtc2.i vf13, a2 + // c->lui(t2, 28672); // lui t2, 28672 + get_fake_spad_addr(t2, cache.fake_scratchpad_data, 0, c); + c->lw(t4, 64, a1); // lw t4, 64(a1) + c->daddiu(v1, a1, 80); // daddiu v1, a1, 80 + c->lw(t5, 68, a1); // lw t5, 68(a1) + c->daddu(s5, t1, r0); // daddu s5, t1, r0 + c->lw(t6, 72, a1); // lw t6, 72(a1) + c->daddu(t4, t4, v1); // daddu t4, t4, v1 + c->vmul_bc(DEST::xyzw, BC::x, vf13, vf14, vf13); // vmulx.xyzw vf13, vf14, vf13 + c->daddiu(t2, t2, 1632); // daddiu t2, t2, 1632 + c->lw(s2, 56, t1); // lw s2, 56(t1) + c->daddu(t5, t5, v1); // daddu t5, t5, v1 + c->lw(s4, 60, t1); // lw s4, 60(t1) + c->daddu(t6, t6, v1); // daddu t6, t6, v1 + c->addiu(s3, r0, 8); // addiu s3, r0, 8 + c->daddiu(s5, s5, 4); // daddiu s5, s5, 4 + c->andi(t3, s4, 1); // andi t3, s4, 1 + // nop // sll r0, r0, 0 + bc = c->sgpr64(t3) != 0; // bne t3, r0, L34 + // nop // sll r0, r0, 0 + if (bc) {next_block = 2;} // branch non-likely + + break; + + case 1: + next_block = 2; + c->lqc2(vf1, 0, t4); // lqc2 vf1, 0(t4) + c->lqc2(vf2, 16, t4); // lqc2 vf2, 16(t4) + c->lqc2(vf3, 32, t4); // lqc2 vf3, 32(t4) + c->lqc2(vf4, 48, t4); // lqc2 vf4, 48(t4) + c->lqc2(vf9, 0, a0); // lqc2 vf9, 0(a0) + c->daddiu(t4, t4, 64); // daddiu t4, t4, 64 + c->lqc2(vf10, 16, a0); // lqc2 vf10, 16(a0) + // nop // sll r0, r0, 0 + c->lqc2(vf11, 32, a0); // lqc2 vf11, 32(a0) + c->lqc2(vf12, 48, a0); // lqc2 vf12, 48(a0) + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf1, vf13); // vmaddx.xyzw vf9, vf1, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf2, vf13); // vmaddx.xyzw vf10, vf2, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf11, vf0); // vmulaw.xyzw acc, vf11, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf11, vf3, vf13); // vmaddx.xyzw vf11, vf3, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf12, vf0); // vmulaw.xyzw acc, vf12, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf12, vf4, vf13); // vmaddx.xyzw vf12, vf4, vf13 + c->sqc2(vf9, 0, a0); // sqc2 vf9, 0(a0) + c->sqc2(vf10, 16, a0); // sqc2 vf10, 16(a0) + c->sqc2(vf11, 32, a0); // sqc2 vf11, 32(a0) + c->sqc2(vf12, 48, a0); // sqc2 vf12, 48(a0) + + case 2: + next_block = 3; + c->andi(t3, s4, 2); // andi t3, s4, 2 + c->daddiu(a0, a0, 64); // daddiu a0, a0, 64 + bc = c->sgpr64(t3) != 0; // bne t3, r0, L35 + // nop // sll r0, r0, 0 + if (bc) {next_block = 4;} // branch non-likely + + break; + + case 3: + next_block = 4; + c->lqc2(vf1, 0, t4); // lqc2 vf1, 0(t4) + c->lqc2(vf2, 16, t4); // lqc2 vf2, 16(t4) + c->lqc2(vf3, 32, t4); // lqc2 vf3, 32(t4) + c->lqc2(vf4, 48, t4); // lqc2 vf4, 48(t4) + c->lqc2(vf9, 0, a0); // lqc2 vf9, 0(a0) + c->daddiu(t4, t4, 64); // daddiu t4, t4, 64 + c->lqc2(vf10, 16, a0); // lqc2 vf10, 16(a0) + // nop // sll r0, r0, 0 + c->lqc2(vf11, 32, a0); // lqc2 vf11, 32(a0) + c->lqc2(vf12, 48, a0); // lqc2 vf12, 48(a0) + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf1, vf13); // vmaddx.xyzw vf9, vf1, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf2, vf13); // vmaddx.xyzw vf10, vf2, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf11, vf0); // vmulaw.xyzw acc, vf11, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf11, vf3, vf13); // vmaddx.xyzw vf11, vf3, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf12, vf0); // vmulaw.xyzw acc, vf12, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf12, vf4, vf13); // vmaddx.xyzw vf12, vf4, vf13 + c->sqc2(vf9, 0, a0); // sqc2 vf9, 0(a0) + c->sqc2(vf10, 16, a0); // sqc2 vf10, 16(a0) + c->sqc2(vf11, 32, a0); // sqc2 vf11, 32(a0) + c->sqc2(vf12, 48, a0); // sqc2 vf12, 48(a0) + + case 4: + next_block = 5; + c->lw(s4, -4, s5); // lw s4, -4(s5) + c->daddiu(a0, a0, 64); // daddiu a0, a0, 64 + + case 5: + next_block = 6; + c->andi(t3, s4, 15); // andi t3, s4, 15 + c->sra(s4, s4, 4); // sra s4, s4, 4 + c->sll(t3, t3, 2); // sll t3, t3, 2 + c->daddiu(s3, s3, -1); // daddiu s3, s3, -1 + c->daddu(t3, t3, t2); // daddu t3, t3, t2 + c->daddiu(s2, s2, -1); // daddiu s2, s2, -1 + c->lw(t3, 0, t3); // lw t3, 0(t3) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + next_block = 0x3ee6b6f0 ^ c->gprs[t3].du32[0]; // jr t3 + assert(next_block < 33); + break; + // nop // sll r0, r0, 0 + + case 6: + next_block = 7; + bc = c->sgpr64(s2) == 0; // beq s2, r0, L44 + c->daddiu(a0, a0, 48); // daddiu a0, a0, 48 + if (bc) {next_block = 32;} // branch non-likely + + break; + + case 7: + next_block = 8; + bc = c->sgpr64(s3) != 0; // bne s3, r0, L36 + // nop // sll r0, r0, 0 + if (bc) {next_block = 5;} // branch non-likely + + break; + + case 8: + next_block = 9; + c->lw(s4, 0, s5); // lw s4, 0(s5) + c->daddiu(s5, s5, 4); // daddiu s5, s5, 4 + //beq r0, r0, L36 // beq r0, r0, L36 + c->addiu(s3, r0, 8); // addiu s3, r0, 8 + next_block = 5; // branch always + + break; + + case 9: + next_block = 10; + c->ld(t9, 0, t4); // ld t9, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->lw(s6, 0, t5); // lw s6, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(gp, 0, t6); // lh gp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L38 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 11; + break; + } + + case 11: + next_block = 12; + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L37 // beq r0, r0, L37 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 12: + next_block = 13; + c->ld(t9, 8, t4); // ld t9, 8(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->ld(s6, -8, t4); // ld s6, -8(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lw(gp, 0, t5); // lw gp, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L39 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 14; + break; + } + + case 14: + next_block = 15; + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L37 // beq r0, r0, L37 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 15: + next_block = 16; + c->ld(t9, 0, t4); // ld t9, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L40 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 17; + break; + } + + case 17: + next_block = 18; + c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L37 // beq r0, r0, L37 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 18: + next_block = 19; + c->lw(s6, 0, t5); // lw s6, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(gp, 0, t6); // lh gp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L37 // beq r0, r0, L37 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 19: + next_block = 20; + c->ld(s6, 0, t4); // ld s6, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lw(gp, 0, t5); // lw gp, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L37 // beq r0, r0, L37 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 20: + next_block = 21; + c->lw(t8, 0, t5); // lw t8, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(fp, 0, t6); // lh fp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) + c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 + c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 + c->psraw(t8, t8, 16); // psraw t8, t8, 16 + c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 + c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 + c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 + c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) + //beq r0, r0, L37 // beq r0, r0, L37 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 21: + next_block = 22; + c->ld(t9, 0, t4); // ld t9, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->lw(s6, 0, t5); // lw s6, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(gp, 0, t6); // lh gp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L41 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 23; + break; + } + + case 23: + next_block = 24; + c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + //beq r0, r0, L37 // beq r0, r0, L37 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 24: + next_block = 25; + c->ld(t9, 8, t4); // ld t9, 8(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->ld(s6, -8, t4); // ld s6, -8(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lw(gp, 0, t5); // lw gp, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L42 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 26; + break; + } + + case 26: + next_block = 27; + c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + //beq r0, r0, L37 // beq r0, r0, L37 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 27: + next_block = 28; + c->ld(t9, 0, t4); // ld t9, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) + c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 + c->psraw(t9, t9, 16); // psraw t9, t9, 16 + c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 + c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 + c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 + c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 + c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 + if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L43 + c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 + next_block = 29; + break; + } + + case 29: + next_block = 30; + c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 + c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) + //beq r0, r0, L37 // beq r0, r0, L37 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 30: + next_block = 31; + c->lw(s6, 0, t5); // lw s6, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lh(gp, 0, t6); // lh gp, 0(t6) + c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 + c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 + c->psraw(s6, s6, 16); // psraw s6, s6, 16 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + //beq r0, r0, L37 // beq r0, r0, L37 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 31: + next_block = 32; + c->ld(s6, 0, t4); // ld s6, 0(t4) + c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 + c->lw(gp, 0, t5); // lw gp, 0(t5) + c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 + c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) + c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 + c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 + c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 + c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 + c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) + //beq r0, r0, L37 // beq r0, r0, L37 + // nop // sll r0, r0, 0 + next_block = 6; // branch always + + break; + + case 32: + next_block = 33; + c->lq(a0, 0, sp); // lq a0, 0(sp) + // nop // sll r0, r0, 0 + //jr ra // jr ra + c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 + goto end_of_function; // return + + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + } + } + end_of_function: + return c->gprs[v0].du64[0]; +} + +u32 jump_table_vals[16] = { + 0x3ee6b6f9, // = 9 ^ 1055307504 + 0x3ee6b6ff, // = 15 ^ 1055307504 + 0x3ee6b6e2, // = 18 ^ 1055307504 + 0x3ee6b6e4, // = 20 ^ 1055307504 + 0x3ee6b6e5, // = 21 ^ 1055307504 + 0x3ee6b6eb, // = 27 ^ 1055307504 + 0x3ee6b6ee, // = 30 ^ 1055307504 + 0x3ee6b6f6, // = 6 ^ 1055307504 + 0x3ee6b6fc, // = 12 ^ 1055307504 + 0x3ee6b6ff, // = 15 ^ 1055307504 + 0x3ee6b6e3, // = 19 ^ 1055307504 + 0x3ee6b6e4, // = 20 ^ 1055307504 + 0x3ee6b6e8, // = 24 ^ 1055307504 + 0x3ee6b6eb, // = 27 ^ 1055307504 + 0x3ee6b6ef, // = 31 ^ 1055307504 + 0x3ee6b6f6, // = 6 ^ 1055307504 +}; + +} // namespace decompress_fixed_data_to_accumulator +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace normalize_frame_quaternions { +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 + c->daddiu(s2, s2, -2); // daddiu s2, s2, -2 + c->sw(a0, 0, sp); // sw a0, 0(sp) + c->daddiu(a0, a0, 128); // daddiu a0, a0, 128 + + block_1: + c->lqc2(vf4, 16, a0); // lqc2 vf4, 16(a0) + c->lqc2(vf1, 0, a0); // lqc2 vf1, 0(a0) + c->lqc2(vf7, 32, a0); // lqc2 vf7, 32(a0) + c->vmul(DEST::xyzw, vf10, vf4, vf4); // vmul.xyzw vf10, vf4, vf4 + c->vmove(DEST::w, vf1, vf0); // vmove.w vf1, vf0 + c->vmove(DEST::w, vf7, vf0); // vmove.w vf7, vf0 + c->vmula_bc(DEST::xyzw, BC::w, vf0, vf10); // vmulaw.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 + c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 + c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 + c->sqc2(vf1, 0, a0); // sqc2 vf1, 0(a0) + c->sqc2(vf7, 32, a0); // sqc2 vf7, 32(a0) + c->daddiu(a0, a0, 48); // daddiu a0, a0, 48 + c->vrsqrt(vf0, BC::w, vf10, BC::w); // vrsqrt Q, vf0.w, vf10.w + c->vwaitq(); // vwaitq + c->vmulq(DEST::xyzw, vf4, vf4); // vmulq.xyzw vf4, vf4, Q + c->daddiu(s2, s2, -1); // daddiu s2, s2, -1 + bc = c->sgpr64(s2) != 0; // bne s2, r0, L46 + c->sqc2(vf4, -32, a0); // sqc2 vf4, -32(a0) + if (bc) {goto block_1;} // branch non-likely + + c->lw(a0, 0, sp); // lw a0, 0(sp) + // nop // sll r0, r0, 0 + //jr ra // jr ra + c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 + goto end_of_function; // return + + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +} // namespace normalize_frame_quaternions +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace clear_frame_accumulator { +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 + // nop // sll r0, r0, 0 + c->sw(a0, 0, sp); // sw a0, 0(sp) + // nop // sll r0, r0, 0 + c->sq(r0, 0, a0); // sq r0, 0(a0) + c->daddiu(s2, s2, -2); // daddiu s2, s2, -2 + c->sq(r0, 16, a0); // sq r0, 16(a0) + // nop // sll r0, r0, 0 + c->sq(r0, 32, a0); // sq r0, 32(a0) + // nop // sll r0, r0, 0 + c->sq(r0, 48, a0); // sq r0, 48(a0) + // nop // sll r0, r0, 0 + c->sq(r0, 64, a0); // sq r0, 64(a0) + // nop // sll r0, r0, 0 + c->sq(r0, 80, a0); // sq r0, 80(a0) + // nop // sll r0, r0, 0 + c->sq(r0, 96, a0); // sq r0, 96(a0) + // nop // sll r0, r0, 0 + c->sq(r0, 112, a0); // sq r0, 112(a0) + c->daddiu(a0, a0, 128); // daddiu a0, a0, 128 + + block_1: + c->sq(r0, 0, a0); // sq r0, 0(a0) + c->daddiu(s2, s2, -1); // daddiu s2, s2, -1 + c->sq(r0, 16, a0); // sq r0, 16(a0) + c->daddiu(a0, a0, 48); // daddiu a0, a0, 48 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + bc = c->sgpr64(s2) != 0; // bne s2, r0, L48 + c->sq(r0, -16, a0); // sq r0, -16(a0) + if (bc) {goto block_1;} // branch non-likely + + c->lw(a0, 0, sp); // lw a0, 0(sp) + // nop // sll r0, r0, 0 + //jr ra // jr ra + c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 + goto end_of_function; // return + + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} +} // namespace clear_frame_accumulator +} // namespace Mips2C + + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace calc_animation_from_spr { + + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + u32 call_addr = 0; + u32 madr, sadr, qwc; + c->mov64(v1, a1); // or v1, a1, r0 + c->daddiu(sp, sp, -192); // daddiu sp, sp, -192 + c->sq(s0, 0, sp); // sq s0, 0(sp) + c->sq(s1, 16, sp); // sq s1, 16(sp) + c->sq(s2, 32, sp); // sq s2, 32(sp) + c->sq(s3, 48, sp); // sq s3, 48(sp) + c->sq(s4, 64, sp); // sq s4, 64(sp) + c->sq(s5, 80, sp); // sq s5, 80(sp) + c->sq(s6, 96, sp); // sq s6, 96(sp) + c->sq(t8, 112, sp); // sq t8, 112(sp) + c->sq(t9, 128, sp); // sq t9, 128(sp) + c->sq(gp, 144, sp); // sq gp, 144(sp) + c->sq(fp, 160, sp); // sq fp, 160(sp) + c->sq(ra, 176, sp); // sq ra, 176(sp) + c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 + c->mov128_vf_gpr(vf15, r0); // qmtc2.i vf15, r0 + c->sw(a1, 0, sp); // sw a1, 0(sp) + //c->lui(v1, 28672); // lui v1, 28672 + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c); + c->lw(s1, 2400, v1); // lw s1, 2400(v1) + c->daddiu(t7, v1, 1824); // daddiu t7, v1, 1824 + c->lui(s0, 4096); // lui s0, 4096 + c->daddiu(t1, v1, 7344); // daddiu t1, v1, 7344 + bc = c->sgpr64(s1) == 0; // beq s1, r0, L7 + c->ori(s0, s0, 54272); // ori s0, s0, 54272 // spr to (d400) + if (bc) {goto block_12;} // branch non-likely + + c->lw(t2, 0, t7); // lw t2, 0(t7) + c->addiu(t3, r0, 7408); // addiu t3, r0, 7408 + c->lw(t4, 4, t7); // lw t4, 4(t7) + c->addiu(v1, r0, 256); // addiu v1, r0, 256 + // c->sw(t2, 16, s0); // sw t2, 16(s0) + madr = c->sgpr64(t2); + c->vadd_bc(DEST::xyzw, BC::w, vf14, vf15, vf0); // vaddw.xyzw vf14, vf15, vf0 + //c->sw(t3, 128, s0); // sw t3, 128(s0) + sadr = c->sgpr64(t3); + // nop // sll r0, r0, 0 + //c->sw(t4, 32, s0); // sw t4, 32(s0) + qwc = c->sgpr64(t4); + // Unknown instr: sync.l + //c->sw(v1, 0, s0); // sw v1, 0(s0) + spad_to_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); + // Unknown instr: sync.l + c->load_symbol(t9, cache.clear_frame_accumulator);// lw t9, clear-frame-accumulator(s7) + c->vadd(DEST::yz, vf14, vf14, vf14); // vadd.yz vf14, vf14, vf14 + c->lw(s2, 0, sp); // lw s2, 0(sp) + // nop // sll r0, r0, 0 + call_addr = c->gprs[t9].du32[0]; // function call: + c->vadd(DEST::yz, vf14, vf14, vf14); // vadd.yz vf14, vf14, vf14 + //c->jalr(call_addr); // jalr ra, t9 + clear_frame_accumulator::execute(c); + + block_2: +// c->lw(v1, 0, s0); // lw v1, 0(s0) +// // nop // sll r0, r0, 0 +// c->andi(v1, v1, 256); // andi v1, v1, 256 +// // nop // sll r0, r0, 0 +// // nop // sll r0, r0, 0 +// // nop // sll r0, r0, 0 +// bc = c->sgpr64(v1) != 0; // bne v1, r0, L3 +// // nop // sll r0, r0, 0 +// if (bc) {goto block_2;} // branch non-likely + + c->lw(t2, 8, t7); // lw t2, 8(t7) + c->addiu(t3, r0, 9616); // addiu t3, r0, 9616 + c->lw(t4, 12, t7); // lw t4, 12(t7) + c->addiu(v1, r0, 256); // addiu v1, r0, 256 + //c->sw(t2, 16, s0); // sw t2, 16(s0) + madr = c->sgpr64(t2); + // nop // sll r0, r0, 0 + //c->sw(t3, 128, s0); // sw t3, 128(s0) + sadr = c->sgpr64(t3); + // nop // sll r0, r0, 0 + //c->sw(t4, 32, s0); // sw t4, 32(s0) + qwc = c->sgpr64(t4); + // Unknown instr: sync.l + //c->sw(v1, 0, s0); // sw v1, 0(s0) + spad_to_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); + // Unknown instr: sync.l + c->lw(a2, 16, t7); // lw a2, 16(t7) + //c->lui(a1, 28672); // lui a1, 28672 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c); + c->load_symbol(t9, cache.decompress_fixed_data_to_accumulator);// lw t9, decompress-fixed-data-to-accumulator(s7) + c->daddiu(a1, a1, 7408); // daddiu a1, a1, 7408 + call_addr = c->gprs[t9].du32[0]; // function call: + c->daddiu(s1, s1, -1); // daddiu s1, s1, -1 + //c->jalr(call_addr); // jalr ra, t9 + decompress_fixed_data_to_accumulator::execute(c); + +// block_4: +// c->lw(v1, 0, s0); // lw v1, 0(s0) +// // nop // sll r0, r0, 0 +// c->andi(v1, v1, 256); // andi v1, v1, 256 +// // nop // sll r0, r0, 0 +// // nop // sll r0, r0, 0 +// // nop // sll r0, r0, 0 +// bc = c->sgpr64(v1) != 0; // bne v1, r0, L4 +// // nop // sll r0, r0, 0 +// if (bc) {goto block_4;} // branch non-likely + + bc = c->sgpr64(s1) == 0; // beq s1, r0, L5 + // nop // sll r0, r0, 0 + if (bc) {goto block_7;} // branch non-likely + + c->lw(t2, 24, t7); // lw t2, 24(t7) + c->addiu(t3, r0, 7408); // addiu t3, r0, 7408 + c->lw(t4, 28, t7); // lw t4, 28(t7) + c->addiu(v1, r0, 256); // addiu v1, r0, 256 + //c->sw(t2, 16, s0); // sw t2, 16(s0) + madr = c->sgpr64(t2); + // nop // sll r0, r0, 0 + //c->sw(t3, 128, s0); // sw t3, 128(s0) + sadr = c->sgpr64(t3); + // nop // sll r0, r0, 0 + //c->sw(t4, 32, s0); // sw t4, 32(s0) + qwc = c->sgpr64(t4); + // Unknown instr: sync.l + //c->sw(v1, 0, s0); // sw v1, 0(s0) + spad_to_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); + // Unknown instr: sync.l + + block_7: + c->lw(t0, 20, t7); // lw t0, 20(t7) + //c->lui(a1, 28672); // lui a1, 28672 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c); + c->lw(a2, 16, t7); // lw a2, 16(t7) + c->daddiu(a1, a1, 9616); // daddiu a1, a1, 9616 + bc = c->sgpr64(t0) == 0; // beq t0, r0, L6 + // nop // sll r0, r0, 0 + if (bc) {goto block_10;} // branch non-likely + + c->lw(a3, 12, t7); // lw a3, 12(t7) + // nop // sll r0, r0, 0 + c->load_symbol(t9, cache.decompress_frame_data_pair_to_accumulator);// lw t9, decompress-frame-data-pair-to-accumulator(s7) + // nop // sll r0, r0, 0 + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(a3, a3, 3); // sll a3, a3, 3 + //c->jalr(call_addr); // jalr ra, t9 + decompress_frame_data_pair_to_accumulator::execute(c); + bc = c->sgpr64(s1) != 0; // bne s1, r0, L3 + c->daddiu(t7, t7, 24); // daddiu t7, t7, 24 + if (bc) {goto block_2;} // branch non-likely + + c->load_symbol(t9, cache.normalize_frame_quaternions);// lw t9, normalize-frame-quaternions(s7) + // nop // sll r0, r0, 0 + c->lw(s2, 0, sp); // lw s2, 0(sp) + // nop // sll r0, r0, 0 + call_addr = c->gprs[t9].du32[0]; // function call: + // nop // sll r0, r0, 0 + //c->jalr(call_addr); // jalr ra, t9 + normalize_frame_quaternions::execute(c); + c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 + // nop // sll r0, r0, 0 + c->lq(s0, 0, sp); // lq s0, 0(sp) + c->lq(s1, 16, sp); // lq s1, 16(sp) + c->lq(s2, 32, sp); // lq s2, 32(sp) + c->lq(s3, 48, sp); // lq s3, 48(sp) + c->lq(s4, 64, sp); // lq s4, 64(sp) + c->lq(s5, 80, sp); // lq s5, 80(sp) + c->lq(s6, 96, sp); // lq s6, 96(sp) + c->lq(t8, 112, sp); // lq t8, 112(sp) + c->lq(t9, 128, sp); // lq t9, 128(sp) + c->lq(gp, 144, sp); // lq gp, 144(sp) + c->lq(ra, 176, sp); // lq ra, 176(sp) + c->lq(fp, 160, sp); // lq fp, 160(sp) + //jr ra // jr ra + c->daddiu(sp, sp, 192); // daddiu sp, sp, 192 + goto end_of_function; // return + + + block_10: + c->load_symbol(t9, cache.decompress_frame_data_to_accumulator);// lw t9, decompress-frame-data-to-accumulator(s7) + // nop // sll r0, r0, 0 + call_addr = c->gprs[t9].du32[0]; // function call: + // nop // sll r0, r0, 0 + //c->jalr(call_addr); // jalr ra, t9 + decompress_frame_data_to_accumulator::execute(c); + bc = c->sgpr64(s1) != 0; // bne s1, r0, L3 + c->daddiu(t7, t7, 24); // daddiu t7, t7, 24 + if (bc) {goto block_2;} // branch non-likely + + c->load_symbol(t9, cache.normalize_frame_quaternions);// lw t9, normalize-frame-quaternions(s7) + // nop // sll r0, r0, 0 + c->lw(s2, 0, sp); // lw s2, 0(sp) + // nop // sll r0, r0, 0 + call_addr = c->gprs[t9].du32[0]; // function call: + // nop // sll r0, r0, 0 + //c->jalr(call_addr); // jalr ra, t9 + normalize_frame_quaternions::execute(c); + + block_12: + c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 + // nop // sll r0, r0, 0 + c->lq(s0, 0, sp); // lq s0, 0(sp) + c->lq(s1, 16, sp); // lq s1, 16(sp) + c->lq(s2, 32, sp); // lq s2, 32(sp) + c->lq(s3, 48, sp); // lq s3, 48(sp) + c->lq(s4, 64, sp); // lq s4, 64(sp) + c->lq(s5, 80, sp); // lq s5, 80(sp) + c->lq(s6, 96, sp); // lq s6, 96(sp) + c->lq(t8, 112, sp); // lq t8, 112(sp) + c->lq(t9, 128, sp); // lq t9, 128(sp) + c->lq(gp, 144, sp); // lq gp, 144(sp) + c->lq(ra, 176, sp); // lq ra, 176(sp) + c->lq(fp, 160, sp); // lq fp, 160(sp) + //jr ra // jr ra + c->daddiu(sp, sp, 192); // daddiu sp, sp, 192 + goto end_of_function; // return + + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.clear_frame_accumulator = intern_from_c("clear-frame-accumulator").c(); + cache.decompress_fixed_data_to_accumulator = intern_from_c("decompress-fixed-data-to-accumulator").c(); + cache.decompress_frame_data_pair_to_accumulator = intern_from_c("decompress-frame-data-pair-to-accumulator").c(); + cache.decompress_frame_data_to_accumulator = intern_from_c("decompress-frame-data-to-accumulator").c(); + cache.normalize_frame_quaternions = intern_from_c("normalize-frame-quaternions").c(); + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + + gLinkedFunctionTable.reg("calc-animation-from-spr", execute, 1024); +} + +} // namespace calc_animation_from_spr +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace cspace_parented_transformq_joint { +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + // nop // sll r0, r0, 0 + c->lw(a3, 0, a0); // lw a3, 0(a0) + c->lui(v1, 16256); // lui v1, 16256 + c->lqc2(vf5, 16, a1); // lqc2 vf5, 16(a1) + c->mtc1(f0, v1); // mtc1 f0, v1 + c->lw(t0, 16, a3); // lw t0, 16(a3) + // nop // sll r0, r0, 0 + c->lw(a2, 16, a0); // lw a2, 16(a0) + c->vadd(DEST::xyzw, vf6, vf5, vf5); // vadd.xyzw vf6, vf5, vf5 + c->lwc1(f1, 64, t0); // lwc1 f1, 64(t0) + c->vadd_bc(DEST::x, BC::w, vf2, vf0, vf5); // vaddw.x vf2, vf0, vf5 + c->lqc2(vf15, 0, a1); // lqc2 vf15, 0(a1) + c->vadd_bc(DEST::y, BC::z, vf2, vf0, vf5); // vaddz.y vf2, vf0, vf5 + c->lqc2(vf1, 32, a1); // lqc2 vf1, 32(a1) + c->divs(f4, f0, f1); // div.s f4, f0, f1 + c->lqc2(vf7, 0, t0); // lqc2 vf7, 0(t0) + c->vsub_bc(DEST::z, BC::y, vf2, vf0, vf5); // vsuby.z vf2, vf0, vf5 + c->lqc2(vf8, 16, t0); // lqc2 vf8, 16(t0) + c->vsub_bc(DEST::w, BC::w, vf2, vf0, vf0); // vsubw.w vf2, vf0, vf0 + c->lqc2(vf9, 32, t0); // lqc2 vf9, 32(t0) + c->vsub_bc(DEST::x, BC::z, vf3, vf0, vf5); // vsubz.x vf3, vf0, vf5 + c->lqc2(vf10, 48, t0); // lqc2 vf10, 48(t0) + c->vadd_bc(DEST::y, BC::w, vf3, vf0, vf5); // vaddw.y vf3, vf0, vf5 + c->lwc1(f2, 68, t0); // lwc1 f2, 68(t0) + c->vadd_bc(DEST::z, BC::x, vf3, vf0, vf5); // vaddx.z vf3, vf0, vf5 + c->sqc2(vf1, 64, a2); // sqc2 vf1, 64(a2) + c->vsub_bc(DEST::w, BC::w, vf3, vf0, vf0); // vsubw.w vf3, vf0, vf0 + c->lwc1(f3, 72, t0); // lwc1 f3, 72(t0) + c->vadd_bc(DEST::x, BC::y, vf4, vf0, vf5); // vaddy.x vf4, vf0, vf5 + c->lw(v1, 76, t0); // lw v1, 76(t0) + c->vsub_bc(DEST::y, BC::x, vf4, vf0, vf5); // vsubx.y vf4, vf0, vf5 + c->mfc1(t1, f4); // mfc1 t1, f4 + c->vadd_bc(DEST::z, BC::w, vf4, vf0, vf5); // vaddw.z vf4, vf0, vf5 + c->divs(f4, f0, f2); // div.s f4, f0, f2 + c->vsub_bc(DEST::w, BC::w, vf4, vf0, vf0); // vsubw.w vf4, vf0, vf0 + c->vopmula(vf6, vf2); // vopmula.xyz acc, vf6, vf2 + c->vopmsub(vf2, vf2, vf6); // vopmsub.xyz vf2, vf2, vf6 + c->vopmula(vf6, vf3); // vopmula.xyz acc, vf6, vf3 + c->vopmsub(vf3, vf3, vf6); // vopmsub.xyz vf3, vf3, vf6 + c->vopmula(vf6, vf4); // vopmula.xyz acc, vf6, vf4 + c->vopmsub(vf4, vf4, vf6); // vopmsub.xyz vf4, vf4, vf6 + c->vadd_bc(DEST::x, BC::w, vf2, vf2, vf0); // vaddw.x vf2, vf2, vf0 + c->vadd_bc(DEST::y, BC::w, vf3, vf3, vf0); // vaddw.y vf3, vf3, vf0 + c->vadd_bc(DEST::z, BC::w, vf4, vf4, vf0); // vaddw.z vf4, vf4, vf0 + c->mfc1(t2, f4); // mfc1 t2, f4 + bc = c->sgpr64(v1) != 0; // bne v1, r0, L50 + c->divs(f4, f0, f3); // div.s f4, f0, f3 + if (bc) {goto block_2;} // branch non-likely + + c->vmul_bc(DEST::xyzw, BC::x, vf2, vf2, vf1); // vmulx.xyzw vf2, vf2, vf1 + c->vmul_bc(DEST::xyzw, BC::y, vf3, vf3, vf1); // vmuly.xyzw vf3, vf3, vf1 + c->vmul_bc(DEST::xyzw, BC::z, vf4, vf4, vf1); // vmulz.xyzw vf4, vf4, vf1 + c->vmula_bc(DEST::xyzw, BC::x, vf7, vf2); // vmulax.xyzw acc, vf7, vf2 + c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf2); // vmadday.xyzw acc, vf8, vf2 + c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf2); // vmaddaz.xyzw acc, vf9, vf2 + c->vmadd_bc(DEST::xyzw, BC::w, vf11, vf10, vf2); // vmaddw.xyzw vf11, vf10, vf2 + c->vmula_bc(DEST::xyzw, BC::x, vf7, vf3); // vmulax.xyzw acc, vf7, vf3 + c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf3); // vmadday.xyzw acc, vf8, vf3 + c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf3); // vmaddaz.xyzw acc, vf9, vf3 + c->vmadd_bc(DEST::xyzw, BC::w, vf12, vf10, vf3); // vmaddw.xyzw vf12, vf10, vf3 + c->vmula_bc(DEST::xyzw, BC::x, vf7, vf4); // vmulax.xyzw acc, vf7, vf4 + c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf4); // vmadday.xyzw acc, vf8, vf4 + c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf4); // vmaddaz.xyzw acc, vf9, vf4 + c->vmadd_bc(DEST::xyzw, BC::w, vf13, vf10, vf4); // vmaddw.xyzw vf13, vf10, vf4 + c->vmula_bc(DEST::xyzw, BC::x, vf7, vf15); // vmulax.xyzw acc, vf7, vf15 + c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf15); // vmadday.xyzw acc, vf8, vf15 + c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf15); // vmaddaz.xyzw acc, vf9, vf15 + c->vmadd_bc(DEST::xyzw, BC::w, vf14, vf10, vf0); // vmaddw.xyzw vf14, vf10, vf0 + c->sqc2(vf11, 0, a2); // sqc2 vf11, 0(a2) + c->sqc2(vf12, 16, a2); // sqc2 vf12, 16(a2) + c->sqc2(vf13, 32, a2); // sqc2 vf13, 32(a2) + c->sqc2(vf14, 48, a2); // sqc2 vf14, 48(a2) + //jr ra // jr ra + // nop // sll r0, r0, 0 + goto end_of_function; // return + + + block_2: + c->pextlw(t1, t2, t1); // pextlw t1, t2, t1 + c->vmul_bc(DEST::xyzw, BC::x, vf2, vf2, vf1); // vmulx.xyzw vf2, vf2, vf1 + c->vmul_bc(DEST::xyzw, BC::y, vf3, vf3, vf1); // vmuly.xyzw vf3, vf3, vf1 + c->vmul_bc(DEST::xyzw, BC::z, vf4, vf4, vf1); // vmulz.xyzw vf4, vf4, vf1 + c->mfc1(t3, f4); // mfc1 t3, f4 + c->pcpyld(t1, t3, t1); // pcpyld t1, t3, t1 + c->mov128_vf_gpr(vf16, t1); // qmtc2.i vf16, t1 + c->vmul(DEST::xyzw, vf2, vf2, vf16); // vmul.xyzw vf2, vf2, vf16 + c->vmul(DEST::xyzw, vf3, vf3, vf16); // vmul.xyzw vf3, vf3, vf16 + c->vmul(DEST::xyzw, vf4, vf4, vf16); // vmul.xyzw vf4, vf4, vf16 + c->vmula_bc(DEST::xyzw, BC::x, vf7, vf2); // vmulax.xyzw acc, vf7, vf2 + c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf2); // vmadday.xyzw acc, vf8, vf2 + c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf2); // vmaddaz.xyzw acc, vf9, vf2 + c->vmadd_bc(DEST::xyzw, BC::w, vf11, vf10, vf2); // vmaddw.xyzw vf11, vf10, vf2 + c->vmula_bc(DEST::xyzw, BC::x, vf7, vf3); // vmulax.xyzw acc, vf7, vf3 + c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf3); // vmadday.xyzw acc, vf8, vf3 + c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf3); // vmaddaz.xyzw acc, vf9, vf3 + c->vmadd_bc(DEST::xyzw, BC::w, vf12, vf10, vf3); // vmaddw.xyzw vf12, vf10, vf3 + c->vmula_bc(DEST::xyzw, BC::x, vf7, vf4); // vmulax.xyzw acc, vf7, vf4 + c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf4); // vmadday.xyzw acc, vf8, vf4 + c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf4); // vmaddaz.xyzw acc, vf9, vf4 + c->vmadd_bc(DEST::xyzw, BC::w, vf13, vf10, vf4); // vmaddw.xyzw vf13, vf10, vf4 + c->vmula_bc(DEST::xyzw, BC::x, vf7, vf15); // vmulax.xyzw acc, vf7, vf15 + c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf15); // vmadday.xyzw acc, vf8, vf15 + c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf15); // vmaddaz.xyzw acc, vf9, vf15 + c->vmadd_bc(DEST::xyzw, BC::w, vf14, vf10, vf0); // vmaddw.xyzw vf14, vf10, vf0 + c->sqc2(vf11, 0, a2); // sqc2 vf11, 0(a2) + c->sqc2(vf12, 16, a2); // sqc2 vf12, 16(a2) + c->sqc2(vf13, 32, a2); // sqc2 vf13, 32(a2) + c->sqc2(vf14, 48, a2); // sqc2 vf14, 48(a2) + //jr ra // jr ra + // nop // sll r0, r0, 0 + goto end_of_function; // return + + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + gLinkedFunctionTable.reg("cspace<-parented-transformq-joint!", execute, 128); +} + +} // namespace cspace<_parented_transformq_joint +} // namespace Mips2C +// add cspace<_parented_transformq_joint::link to the link callback table for the object file. +// FWD DEC: + + +namespace normalize_frame_quaternions { extern void link(); } + +namespace decompress_fixed_data_to_accumulator { extern void link(); } +namespace decompress_frame_data_to_accumulator { extern void link(); } + + +namespace decompress_frame_data_pair_to_accumulator { extern void link(); } \ No newline at end of file diff --git a/game/mips2c/mips2c_private.h b/game/mips2c/mips2c_private.h index c9afb91f18..356005e04b 100644 --- a/game/mips2c/mips2c_private.h +++ b/game/mips2c/mips2c_private.h @@ -62,14 +62,23 @@ enum Gpr { enum VfName { vf0 = 0, vf1 = 1, + vf01 = 1, vf2 = 2, + vf02 = 2, vf3 = 3, + vf03 = 3, vf4 = 4, + vf04 = 4, vf5 = 5, + vf05 = 5, vf6 = 6, + vf06 = 6, vf7 = 7, + vf07 = 7, vf8 = 8, + vf08 = 8, vf9 = 9, + vf09 = 9, vf10 = 10, vf11 = 11, vf12 = 12, @@ -955,6 +964,15 @@ struct ExecutionContext { } } + void vitof15(DEST mask, int dst, int src) { + auto s = vf_src(src); + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + vfs[dst].f[i] = ((float)s.ds32[i]) * (1.f / 32768.f); + } + } + } + void vftoi12(DEST mask, int dst, int src) { auto s = vf_src(src); for (int i = 0; i < 4; i++) { @@ -1072,6 +1090,48 @@ inline void spad_to_dma(void* spad_sym_addr, u32 madr, u32 sadr, u32 qwc) { memcpy(spad_addr_c, g_ee_main_mem + madr, qwc * 16); } +inline void spad_to_dma_no_sadr_off(void* spad_sym_addr, u32 madr, u32 sadr, u32 qwc) { + u32 spad_addr_goal; + memcpy(&spad_addr_goal, spad_sym_addr, 4); + + assert((madr & 0xf) == 0); + assert((sadr & 0xf) == 0); + assert(sadr < 0x4000); + assert((sadr + 16 * qwc) <= 0x4000); + assert(qwc <= 0x4000); + + void* spad_addr_c = g_ee_main_mem + spad_addr_goal + sadr; + + memcpy(spad_addr_c, g_ee_main_mem + madr, qwc * 16); +} + +inline void spad_to_dma_no_sadr_off_bones_interleave(void* spad_sym_addr, + u32 madr, + u32 sadr, + u32 qwc) { + u32 spad_addr_goal; + memcpy(&spad_addr_goal, spad_sym_addr, 4); + + assert((madr & 0xf) == 0); + assert((sadr & 0xf) == 0); + assert(sadr < 0x4000); + assert((sadr + 16 * qwc) <= 0x4000); + assert(qwc <= 0x4000); + + u8* spad_addr_c = g_ee_main_mem + spad_addr_goal + sadr; + const u8* mem_addr = g_ee_main_mem + madr; + assert((qwc & 3) == 0); + while (qwc > 0) { + // transfer 4. + memcpy(spad_addr_c, mem_addr, 4 * 16); + spad_addr_c += (4 * 16); + sadr += 4 * 16; + // but skip 5 + mem_addr += (5 * 16); + qwc -= 4; + } +} + inline void spad_from_dma(void* spad_sym_addr, u32 madr, u32 sadr, u32 qwc) { u32 spad_addr_goal; memcpy(&spad_addr_goal, spad_sym_addr, 4); @@ -1087,6 +1147,20 @@ inline void spad_from_dma(void* spad_sym_addr, u32 madr, u32 sadr, u32 qwc) { memcpy(g_ee_main_mem + madr, spad_addr_c, qwc * 16); } +inline void spad_from_dma_no_sadr_off(void* spad_sym_addr, u32 madr, u32 sadr, u32 qwc) { + u32 spad_addr_goal; + memcpy(&spad_addr_goal, spad_sym_addr, 4); + assert((madr & 0xf) == 0); + assert((sadr & 0xf) == 0); + assert(sadr < 0x4000); + assert((sadr + 16 * qwc) <= 0x4000); + assert(qwc <= 0x4000); + + void* spad_addr_c = g_ee_main_mem + spad_addr_goal + sadr; + + memcpy(g_ee_main_mem + madr, spad_addr_c, qwc * 16); +} + inline void load_vfs_from_tf_regs(const void* tf_regs_sym, ExecutionContext* c) { u32 goal_addr_of_vf1; memcpy(&goal_addr_of_vf1, tf_regs_sym, 4); diff --git a/game/mips2c/mips2c_table.cpp b/game/mips2c/mips2c_table.cpp index a182fb25d4..3fc2ccc125 100644 --- a/game/mips2c/mips2c_table.cpp +++ b/game/mips2c/mips2c_table.cpp @@ -203,6 +203,15 @@ namespace method_18_collide_edge_work { extern void link(); } +namespace calc_animation_from_spr { +extern void link(); +} +namespace bones_mtx_calc { +extern void link(); +} +namespace cspace_parented_transformq_joint { +extern void link(); +} LinkedFunctionTable gLinkedFunctionTable; Rng gRng; std::unordered_map> gMips2CLinkCallbacks = { @@ -234,7 +243,9 @@ std::unordered_map> gMips2CLinkCallbacks = method_10_collide_puss_work::link, method_9_collide_puss_work::link}}, {"collide-edge-grab", {method_16_collide_edge_work::link, method_15_collide_edge_work::link, - method_10_collide_edge_hold_list::link, method_18_collide_edge_work::link}}}; + method_10_collide_edge_hold_list::link, method_18_collide_edge_work::link}}, + {"joint", {calc_animation_from_spr::link, cspace_parented_transformq_joint::link}}, + {"bones", {bones_mtx_calc::link}}}; void LinkedFunctionTable::reg(const std::string& name, u64 (*exec)(void*), u32 stack_size) { const auto& it = m_executes.insert({name, {exec, Ptr()}}); diff --git a/game/overlord/iso.cpp b/game/overlord/iso.cpp index dab3ba86e1..80e1d51da2 100644 --- a/game/overlord/iso.cpp +++ b/game/overlord/iso.cpp @@ -941,8 +941,14 @@ void CancelDGO(RPC_Dgo_Cmd* cmd) { // this will cause a crash if we cancel because we try to load 2 dgos at the same time. // this should succeed if it's an actual cancel because we changed which level we're trying to // load. - assert(cmd); - cmd->result = DGO_RPC_RESULT_ABORTED; + // I don't understand how this works in the real game. + // maybe the IOP doesn't crash on writing to 0x0? + // or, we have some other bug. + if (cmd) { + printf("null pointer case in CancelDGO hit!\n"); + cmd->result = DGO_RPC_RESULT_ABORTED; + } + scmd.cmd_id = 0; } } diff --git a/goal_src/engine/anim/bones.gc b/goal_src/engine/anim/bones.gc index c64b0f8d30..00864150b8 100644 --- a/goal_src/engine/anim/bones.gc +++ b/goal_src/engine/anim/bones.gc @@ -5,5 +5,743 @@ ;; name in dgo: bones ;; dgos: GAME, ENGINE +;; Bones. +;; There are 4 main functions used by the outside world: +;; - bones-init. Call this before doing process-drawable DMA building. +;; - draw-bones. Call this once for each process-drawable during DMA building. +;; - bones-wrapup. Call this after all calls to draw-bones. +;; the above 3 functions are done separate for different levels. +;; - bones-mtx-calc-execute. Call this after all that. + +;; It's more than just bones in here - submitting to merc is done from here. + + +;;;;;;;;;;;;;;;;;; +;; calc list +;;;;;;;;;;;;;;;;;; + +(defenum bone-calc-flags + :type uint16 + :bitfield #t + (bncfl00 0) + (bncfl01 1) ;; use identity matrix in bone matrix calc instead of cam rot (effectively screen-space bones?) + (bncfl02 2) + (bncfl03 3) + (bncfl04 4) + (bncfl05 5) + (bncfl06 6) + (bncfl07 7) + (bncfl08 8) + (bncfl09 9) + (bncfl10 10) + (bncfl11 11) + (bncfl12 12) + (bncfl13 13) + (bncfl14 14) + (bncfl15 15) + ) + +;; this type represents a "calculation" that will be performed at later time. +(deftype bone-calculation (structure) + ((flags bone-calc-flags :offset-assert 0) + (num-bones uint16 :offset-assert 2) + (matrix-area (inline-array matrix) :offset-assert 4) + (joints (inline-array joint) :offset-assert 8) + (bones (inline-array bone) :offset-assert 12) + (ripple-scale float :offset-assert 16) + (ripple-y-scale float :offset-assert 20) + (ripple-normal-scale float :offset-assert 24) + (ripple-area (inline-array vector) :offset-assert 28) + (next bone-calculation :offset-assert 32) + (dummy-1 uint32 :offset-assert 36) + (dummy-2 uint32 :offset-assert 40) + (dummy-3 uint32 :offset-assert 44) + ) + :method-count-assert 9 + :size-assert #x30 + :flag-assert #x900000030 + ) + +;; linked list of bone-calculations. +;; you have to bring your own bone-calculations +(deftype bone-calculation-list (structure) + ((first bone-calculation :offset-assert 0) + (next bone-calculation :offset-assert 4) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; the global calculation list. +(define *bone-calculation-list* (new 'global 'bone-calculation-list)) + +(defun bone-list-init () + "Reset the bone list to have nothing." + (let ((v1-0 *bone-calculation-list*)) + (set! (-> v1-0 first) (the-as bone-calculation 0)) + (set! (-> v1-0 next) (the-as bone-calculation 0)) + ) + (none) + ) + +(bone-list-init) + +;;;;;;;;;;;;;;;;;; +;; texscroll +;;;;;;;;;;;;;;;;;; + +;; the "texture scroll" moves the texture. This is done by modifying the merc data. + +;; list of all texture scroll effects. +(deftype texscroll-globals (structure) + ((requests int32 :offset-assert 0) + (effects merc-effect 32 :offset-assert 4) + ) + :method-count-assert 9 + :size-assert #x84 + :flag-assert #x900000084 + ) + +(define *texscroll-globals* (new 'global 'texscroll-globals)) + +(defun texscroll-make-request ((arg0 merc-effect)) + "Request that the given merc-effect have its texture scroll updated. + Note: only call this if you actually have a texture scroll effect!" + (let* ((v1-1 (-> *texscroll-globals* requests)) + (a1-0 (-> arg0 extra-info)) + (a1-1 (the-as mei-texture-scroll (+ (the-as uint a1-0) (* (-> a1-0 texture-scroll-offset) 16)))) + ) + (when (< v1-1 32) + (let* ((a3-1 (-> *display* integral-frame-counter)) + (a2-3 (-> a1-1 time-factor)) + (t0-2 (+ (ash 1 a2-3) -1)) + ) + (if (zero? (-> a1-1 scroll-dir)) + (set! a3-1 (- a3-1)) + ) + (let ((a2-5 (ash (ash (logand a3-1 t0-2) (- 12 (the-as int (-> a1-1 st-int-scale)))) (- (the-as int a2-3))))) + (when (!= a2-5 (-> a1-1 cached-time)) + (set! (-> a1-1 time-delta) (the-as uint (- a2-5 (the-as int (-> a1-1 cached-time))))) + (set! (-> a1-1 cached-time) (the-as uint a2-5)) + (set! (-> *texscroll-globals* effects v1-1) arg0) + (+! (-> *texscroll-globals* requests) 1) + ) + ) + ) + ) + ) + (none) + ) + +(defun texscroll-execute () + "Do all requested texture scroll updates." + (dotimes (v1-0 (-> *texscroll-globals* requests)) + (let* ((a2-0 (-> *texscroll-globals* effects v1-0)) + (a0-2 (-> a2-0 frag-count)) + (a1-1 (-> a2-0 extra-info)) + (a1-2 (the-as mei-texture-scroll (+ (the-as uint a1-1) (* (-> a1-1 texture-scroll-offset) 16)))) + (t1-0 (-> a2-0 frag-geo)) + (a2-1 (-> a2-0 frag-ctrl)) + ) + (dotimes (a3-2 (the-as int a0-2)) + (let ((t0-4 (&+ (the-as pointer t1-0) (logand (* (+ (-> a2-1 unsigned-four-count) 3) 4) #xfff0)))) + (let ((t2-2 (+ (-> t1-0 header mat1-cnt) (-> t1-0 header mat2-cnt) (-> t1-0 header mat3-cnt)))) + (the-as (pointer int8) (-> a1-2 time-delta)) + (let* ((t1-3 (the-as (pointer int8) (&+ t0-4 9))) + (t2-4 (&+ t1-3 (* (the-as uint 12) t2-2))) + (t3-3 (-> a1-2 time-delta)) + ) + (nop!) + (label cfg-3) + (let ((t4-0 (-> t1-3 0))) + (nop!) + (nop!) + (nop!) + (let ((t4-1 (+ t4-0 t3-3))) + (set! t1-3 (&-> t1-3 12)) + (b! (!= t1-3 t2-4) cfg-3 :delay (set! (-> t1-3 -12) t4-1)) + ) + ) + ) + ) + (set! t1-0 (the-as + merc-fragment + (&+ (&+ t0-4 (logand (* (+ (-> a2-1 lump-four-count) 3) 4) #xfff0)) (* (-> a2-1 fp-qwc) 16)) + ) + ) + ) + (set! a2-1 (the-as merc-fragment-control (+ (the-as uint a2-1) (* (-> a2-1 mat-xfer-count) 2) 4))) + ) + ) + ) + (set! (-> *texscroll-globals* requests) 0) + 0 + (none) + ) + + +;;;;;;;;;;;;;;;;;;;; +;; Merc Submission +;;;;;;;;;;;;;;;;;;;; + +;; when submitting to merc, we must provide some information to pick the appropriate rendering settings. +;; this information can't be precomputed and is done in bones. + +;; per-effect information +(deftype merc-effect-bucket-info (structure) + ((color-fade rgba :offset-assert 0) + (use-mercneric uint8 :offset-assert 4) + (ignore-alpha uint8 :offset-assert 5) + (pad0 uint8 :offset-assert 6) + (pad1 uint8 :offset-assert 7) + ) + :pack-me + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; information for everything being submitted. +(deftype merc-bucket-info (structure) + ((light vu-lights :inline :offset-assert 0) + (needs-clip int32 :offset-assert 112) + (need-mercprime-if-merc int32 :offset-assert 116) + (must-use-mercneric-for-clip int32 :offset-assert 120) + (effect merc-effect-bucket-info 16 :inline :offset-assert 124) + ) + :method-count-assert 9 + :size-assert #xfc + :flag-assert #x9000000fc + ) + +(define *merc-bucket-info* (new 'global 'merc-bucket-info)) + +;; UNUSED. +(define *use-generic* #f) + +;;;;;;;;;;;;;;;; +;; VU / DMA +;;;;;;;;;;;;;;;; + +(define bones-vu0-block (new 'static 'vu-function #|:length 63 :qlength 32|#)) + +;; these changes only matter if transferring in _interleave_ mode. + +(defun bones-set-sqwc () + ;; transfer 4, skip 1. + (#unless PC_PORT + (set! (-> (the-as dma-bank-control #x1000e000) sqwc) (new 'static 'dma-sqwc :sqwc #x1 :tqwc #x4)) + ) + (none) + ) + +(defun bones-reset-sqwc () + ;; transfer 1, skip 1 + ;; note: not sure what uses this mode?? + (#unless PC_PORT + (set! (-> (the-as dma-bank-control #x1000e000) sqwc) (new 'static 'dma-sqwc :sqwc #x1 :tqwc #x1)) + ) + (none) + ) + +;; ?? used by generic merc +(define *merc-global-array* (new 'global 'merc-global-array)) + +(defun vu-lights<-light-group! ((arg0 vu-lights) (arg1 light-group)) + "Convert a light-group to the VU format lights used by merc." + (local-vars (v1-0 uint128) (v1-1 uint128) (a2-1 uint128) (t0-1 uint128) (t1-1 uint128)) + (rlet ((vf0 :class vf) + (vf10 :class vf) + (vf11 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + (vf8 :class vf) + (vf9 :class vf) + ) + (init-vf0-vector) + (nop!) + (let ((a3-0 (the-as uint128 (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0)))) + (nop!) + (let ((a2-0 (-> arg1 dir0 direction quad))) + (nop!) + (let ((t1-0 (-> arg1 dir1 direction quad))) + (nop!) + (.lvf vf4 (&-> arg1 dir0 color quad)) + (.pextlw v1-0 t1-0 a2-0) + (let ((t0-0 (-> arg1 dir2 direction quad))) + (.pextuw a2-1 t1-0 a2-0) + (.lvf vf8 (&-> arg1 dir0 levels quad)) + (.pextlw t1-1 a3-0 t0-0) + (.lvf vf5 (&-> arg1 dir1 color quad)) + (.pextuw t0-1 a3-0 t0-0) + ) + ) + ) + ) + (.lvf vf9 (&-> arg1 dir1 levels quad)) + (let ((a3-1 (make-u128 t1-1 v1-0))) + (.lvf vf6 (&-> arg1 dir2 color quad)) + (.pcpyud v1-1 v1-0 t1-1) + (.lvf vf10 (&-> arg1 dir2 levels quad)) + (let ((a2-2 (make-u128 (the-as int t0-1) a2-1))) + (.lvf vf7 (&-> arg1 ambi color quad)) + (.mul.x.vf vf4 vf4 vf8) + (.lvf vf11 (&-> arg1 ambi levels quad)) + (.mul.x.vf vf5 vf5 vf9) + (set! (-> arg0 direction 0 quad) (the-as uint128 a3-1)) + (.mul.x.vf vf6 vf6 vf10) + (set! (-> arg0 direction 1 quad) v1-1) + (.mul.x.vf vf7 vf7 vf11) + (set! (-> arg0 direction 2 quad) (the-as uint128 a2-2)) + ) + ) + (.min.x.vf vf4 vf0 vf0 :mask #b1000) + (nop!) + (.min.x.vf vf5 vf0 vf0 :mask #b1000) + (nop!) + (.min.x.vf vf6 vf0 vf0 :mask #b1000) + (nop!) + (.max.w.vf vf7 vf0 vf0 :mask #b1000) + (nop!) + (nop!) + (.svf (&-> arg0 color 0 quad) vf4) + (nop!) + (.svf (&-> arg0 color 1 quad) vf5) + (nop!) + (.svf (&-> arg0 color 2 quad) vf6) + (nop!) + (.svf (&-> arg0 ambient quad) vf7) + 0 + (none) + ) + ) + +;;;;;;;;;;;;;;;;;;;; +;; BONE +;;;;;;;;;;;;;;;;;;;; + +(defun bones-init ((arg0 dma-buffer) (arg1 dma-foreground-sink-group)) + "Initialize the scratchpad and VU0 for bone work." + (scratchpad-object int) + (let ((a2-1 (the-as bone-memory (+ 16 (scratchpad-object int)))) + (v1-2 (the-as bone-memory (+ 16 (scratchpad-object int)))) + ) + + ;; layout joints, bones, and outputs + (set! (-> a2-1 work layout joint 0) (the-as joint (+ 256 (scratchpad-object int)))) + (set! (-> a2-1 work layout joint 1) (the-as joint (+ 4864 (scratchpad-object int)))) + (set! (-> a2-1 work layout bone 0) (the-as bone (+ 1280 (scratchpad-object int)))) + (set! (-> a2-1 work layout bone 1) (the-as bone (+ 5888 (scratchpad-object int)))) + (set! (-> a2-1 work layout output 0) (the-as uint (+ 2816 (scratchpad-object int)))) + (set! (-> a2-1 work layout output 1) (the-as uint (+ 7424 (scratchpad-object int)))) + + ;; set up work + (set! (-> v1-2 work next-tag dma) (new 'static 'dma-tag :id (dma-tag-id next))) + (set! (-> v1-2 work next-tag vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl))) + (set! (-> v1-2 work next-tag vif1) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl))) + (set! (-> v1-2 work dma-buf) arg0) + (set! (-> v1-2 work sink-group) arg1) + (set! (-> v1-2 work next-merc) (the-as dma-packet 0)) + ) + + ;; reset globals + (let ((v1-3 *merc-globals*)) + (set! (-> v1-3 first) (the-as uint 0)) + (set! (-> v1-3 next) (the-as uint 0)) + ) + + ;; upload bones program. + (#unless PC_PORT + (let ((gp-0 *vu0-dma-list*)) + (let ((v1-4 gp-0)) + (set! (-> v1-4 base) (-> v1-4 data)) + (set! (-> v1-4 end) (&-> v1-4 data-buffer (-> v1-4 allocated-length))) + ) + (dma-buffer-add-vu-function gp-0 bones-vu0-block 0) + (let* ((v1-5 gp-0) + (a0-6 (-> v1-5 base)) + ) + (set! (-> (the-as (pointer int64) a0-6)) #x70000000) + (set! (-> (the-as (pointer int64) a0-6) 1) 0) + (set! (-> v1-5 base) (&+ a0-6 16)) + ) + (.sync.l) + (dma-buffer-send-chain (the-as dma-bank-source #x10008000) gp-0) + ) + ) + + ;; we will use "run" in the shadow queue. Reset that (but don't increment yet, just in case we don't draw shadows) + (let ((gp-1 *shadow-queue*)) + (if (>= (-> gp-1 cur-run) (the-as uint 15)) + (format #t "Too many shadow-queues!!~%") + ) + (let ((v1-13 (-> gp-1 run (-> gp-1 cur-run)))) + (set! (-> v1-13 first) (the-as uint 0)) + (set! (-> v1-13 next) (the-as uint 0)) + ) + ) + 0 + (none) + ) + +(defun draw-bones-mtx-calc ((arg0 bone-calculation) (arg1 int) (arg2 bone-calc-flags)) + "Add the current work to the bone calculation list." + (let ((t2-0 (the-as bone-memory (+ 16 (scratchpad-object int)))) + (v1-1 *bone-calculation-list*) + (a3-1 arg0) + ) + ;; grab active buffers + (let ((t0-0 (-> t2-0 work regs joint-ptr)) + (t1-0 (-> t2-0 work regs bone-ptr)) + (t2-1 (-> t2-0 work regs num-bones)) + (t3-0 a3-1) + ) + (set! (-> t3-0 flags) arg2) + (set! (-> t3-0 num-bones) t2-1) + (set! (-> t3-0 matrix-area) (the-as (inline-array matrix) arg1)) + (set! (-> t3-0 joints) t0-0) + (set! (-> t3-0 bones) t1-0) + (set! (-> t3-0 next) (the-as bone-calculation 0)) + ) + ;; splice into list + (if (nonzero? (-> v1-1 next)) + (set! (-> v1-1 next next) a3-1) + ) + (if (zero? (-> v1-1 first)) + (set! (-> v1-1 first) a3-1) + ) + (set! (-> v1-1 next) a3-1) + ) + (the-as object (&+ arg0 48)) + ) + +(def-mips2c bones-mtx-calc (function int pointer pointer int object none)) + +(defun bones-mtx-calc-execute () + "Do all pending bone calculations" + (local-vars (v1-14 float)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + (vf25 :class vf) + (vf26 :class vf) + (vf27 :class vf) + (vf28 :class vf) + (vf29 :class vf) + (vf3 :class vf) + (vf30 :class vf) + (vf31 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + (vf8 :class vf) + ) + (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 ((v1-8 (the-as bone-memory (+ 16 (scratchpad-object int))))) + (+ 16 #x70000000) + (set! (-> v1-8 work layout joint 0) (the-as joint (+ 256 (scratchpad-object int)))) + (set! (-> v1-8 work layout joint 1) (the-as joint (+ 4864 (scratchpad-object int)))) + (set! (-> v1-8 work layout bone 0) (the-as bone (+ 1280 (scratchpad-object int)))) + (set! (-> v1-8 work layout bone 1) (the-as bone (+ 5888 (scratchpad-object int)))) + (set! (-> v1-8 work layout output 0) (the-as uint (+ 2816 (scratchpad-object int)))) + (set! (-> v1-8 work layout output 1) (the-as uint (+ 7424 (scratchpad-object int)))) + ) + (#unless PC_PORT (set! (-> (the-as dma-bank-control #x1000e000) sqwc) (new 'static 'dma-sqwc :sqwc #x1 :tqwc #x4))) + (let* ((v1-10 *bone-calculation-list*) + (gp-0 *identity-matrix*) + (s5-0 (-> *math-camera* camera-rot)) + (s4-0 (-> v1-10 first)) + ) + (while (nonzero? s4-0) + (let ((v1-13 (if (logtest? (-> s4-0 flags) (bone-calc-flags bncfl01)) + gp-0 + s5-0 + ) + ) + ) + (.lvf vf28 (&-> v1-13 vector 0 quad)) + (.lvf vf29 (&-> v1-13 vector 1 quad)) + (.lvf vf30 (&-> v1-13 vector 2 quad)) + (.lvf vf31 (&-> v1-13 vector 3 quad)) + (.lvf vf25 (&-> v1-13 vector 0 quad)) + (.lvf vf26 (&-> v1-13 vector 1 quad)) + (.lvf vf27 (&-> v1-13 vector 2 quad)) + + (.mov v1-14 vf27) + (bones-mtx-calc + (the-as int (-> s4-0 matrix-area)) + (the-as pointer (-> s4-0 joints)) + (the-as pointer (-> s4-0 bones)) + (the-as int (-> s4-0 num-bones)) + v1-13 ;; hack, added + ) + ) + (when (logtest? (-> s4-0 flags) (bone-calc-flags bncfl00)) + (let ((v1-18 (-> s4-0 matrix-area)) + (a0-22 (-> s4-0 num-bones)) + (f1-0 (-> s4-0 ripple-scale)) + (f2-0 (-> s4-0 ripple-y-scale)) + (f0-0 (-> s4-0 ripple-normal-scale)) + (a1-9 (-> s4-0 ripple-area)) + ) + (let ((a2-2 f2-0)) + (.mov vf1 a2-2) + ) + (let ((a2-3 f1-0)) + (.mov vf2 a2-3) + ) + (let ((a2-4 f0-0)) + (.mov vf3 a2-4) + ) + (label cfg-8) + (.lvf vf5 (&-> v1-18 0 vector 1 quad)) + (.lvf vf6 (&-> v1-18 0 vector 3 quad)) + (.lvf vf7 (&-> v1-18 1 vector 0 quad)) + (.lvf vf8 (&-> v1-18 1 vector 2 quad)) + (.mul.x.vf vf4 vf5 vf2) + (.mul.x.vf vf5 vf5 vf1) + (let ((a3-1 (-> v1-18 0 vector 0 quad))) + (.mul.x.vf vf7 vf7 vf3) + (let ((a2-6 (-> v1-18 0 vector 2 quad))) + (.mul.x.vf vf8 vf8 vf3) + (set! (-> a1-9 0 quad) a3-1) + (let ((a3-2 (-> v1-18 1 vector 1 quad))) + (.sub.vf vf6 vf6 vf4) + (set! (-> a1-9 2 quad) a2-6) + (.svf (&-> a1-9 1 quad) vf5) + (set! (-> a1-9 5 quad) a3-2) + ) + ) + ) + (+! a0-22 -1) + (.svf (&-> a1-9 4 quad) vf7) + ;(.addiu v1-18 (the-as object v1-18) 128) + (&+ v1-18 128) + (.svf (&-> a1-9 3 quad) vf6) + ;;(.addiu (the-as (inline-array vector) a1-9) a1-9 128) + (&+ a1-9 128) + (b! (nonzero? a0-22) cfg-8 :delay (.svf (&-> a1-9 -2 quad) vf8)) + ) + 0 + ) + (set! s4-0 (-> s4-0 next)) + ) + ) + (#unless PC_PORT (set! (-> (the-as dma-bank-control #x1000e000) sqwc) (new 'static 'dma-sqwc :sqwc #x1 :tqwc #x1))) + (bone-list-init) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x7b :g #x7b :b #x7b :a #x80) + ) + ) + 0 + (none) + ) + ) + +(defun bones-wrapup () + (let ((v1-1 (the-as bone-memory (+ 16 (scratchpad-object int))))) + (when (nonzero? (-> v1-1 work next-merc)) + ;; only add if we actually drew with merc. + (let* ((a0-2 (-> v1-1 work dma-buf)) + (a3-0 (-> a0-2 base)) + ) + (let ((a1-0 (the-as object (-> a0-2 base)))) + (set! (-> (the-as dma-packet a1-0) dma) (new 'static 'dma-tag :id (dma-tag-id next))) + (set! (-> (the-as dma-packet a1-0) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet a1-0) vif1) (new 'static 'vif-tag)) + (set! (-> a0-2 base) (&+ (the-as pointer a1-0) 16)) + ) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) frame bucket-group) + (-> v1-1 work sink-group merc-sink bucket) + (the-as pointer (-> v1-1 work next-merc)) + (the-as (pointer dma-tag) a3-0) + ) + ) + ) + ) + (none) + ) + +;;;;;;;;;;;;;;; +;; bone debug +;;;;;;;;;;;;;;; + +(define *bones-first* #f) + +(defun-debug dump-qword ((arg0 qword)) + (let ((v1-0 arg0)) + (format + 0 + "~8,'0X: ~8,'0X ~8,'0X ~8,'0X ~8,'0X~%" + v1-0 + (-> v1-0 data 0) + (-> v1-0 data 1) + (-> v1-0 data 2) + (-> v1-0 data 3) + ) + ) + 0 + (none) + ) + +(defun-debug dump-mem ((arg0 pointer) (arg1 int)) + (dotimes (s4-0 arg1) + (format + 0 + "~8,'0X: ~8,'0X ~8,'0X ~8,'0X ~8,'0X" + (&+ arg0 (* (* s4-0 4) 4)) + (-> (the-as (pointer uint32) (&+ arg0 (* (* s4-0 4) 4)))) + (-> (the-as (pointer uint32) (&+ arg0 (* (+ (* s4-0 4) 1) 4)))) + (-> (the-as (pointer uint32) (&+ arg0 (* (+ (* s4-0 4) 2) 4)))) + (-> (the-as (pointer uint32) (&+ arg0 (* (+ (* s4-0 4) 3) 4)))) + ) + (format + 0 + " ~F ~F ~F ~F ~%" + (-> (the-as (pointer uint32) (&+ arg0 (* (* s4-0 4) 4)))) + (-> (the-as (pointer uint32) (&+ arg0 (* (+ (* s4-0 4) 1) 4)))) + (-> (the-as (pointer uint32) (&+ arg0 (* (+ (* s4-0 4) 2) 4)))) + (-> (the-as (pointer uint32) (&+ arg0 (* (+ (* s4-0 4) 3) 4)))) + ) + ) + 0 + (none) + ) + +(defun-debug bones-debug () + 0 + (none) + ) + +(defun-debug dump-bone-mem () + (format 0 "== joints 0 ===========~%") + (dump-mem (the-as pointer (+ 256 #x70000000)) 64) + (format 0 "== bones 0 ============~%") + (dump-mem (the-as pointer (+ 1280 #x70000000)) 96) + (format 0 "== output 0 ===========~%") + (dump-mem (the-as pointer (+ 2816 #x70000000)) 128) + (format 0 "~%~%~%") + (format 0 "== joints 1 ===========~%") + (dump-mem (the-as pointer (+ 4864 #x70000000)) 64) + (format 0 "== bones 1 ============~%") + (dump-mem (the-as pointer (+ 5888 #x70000000)) 96) + (format 0 "== output 1 ===========~%") + (dump-mem (the-as pointer (+ 7424 #x70000000)) 128) + (format 0 "== dma-list ===========~%") + (dump-mem (the-as pointer (+ 256 #x70000000)) 90) + (format 0 "========================~%~%") + 0 + (none) + ) + (define-extern draw-bones (function draw-control dma-buffer float none)) + +;; HACK incomplete: +(defun draw-bones ((arg0 draw-control) (arg1 dma-buffer) (arg2 float)) + (local-vars + (at-0 object) + (a0-16 int) + (a0-17 int) + (a0-62 int) + (a2-10 int) + (a2-12 int) + (sv-96 int) + (sv-112 int) + (sv-128 int) + (sv-144 ripple-control) + ) + (rlet ((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) + ) + (let* ((s1-0 (+ (-> arg0 mgeo num-joints) 3)) + (a0-1 (* s1-0 128)) + ) + ;;(.lui at-0 28672) + (let* ((v1-2 (-> arg1 base)) + (a1-1 (the-as object (&+ v1-2 16))) + (s3-0 (the-as object (&+ v1-2 64))) + ) + (let ((a2-1 (logand (the-as int s3-0) 48))) + (b! (zero? a2-1) cfg-2 :delay (nop!)) + (set! s3-0 (&- (&+ (the-as pointer s3-0) 64) (the-as uint a2-1))) + ) + (label cfg-2) + ; (let* ((a2-3 (-> *perf-stats* data 13)) + ; (a3-1 (-> a2-3 ctrl)) + ; ) + ; (+! (-> a2-3 count) 1) + ; (b! (zero? a3-1) cfg-4 :delay (nop!)) + ; (.mtc0 Perf r0) + ; (.sync.l) + ; (.sync.p) + ; (.mtpc pcr0 r0) + ; (.mtpc pcr1 r0) + ; (.sync.l) + ; (.sync.p) + ; (.mtc0 Perf a3-1) + ; ) + ; (.sync.l) + ; (.sync.p) + ; (label cfg-4) + 0 + (let ((a2-6 (the-as bone-regs (+ 240 (scratchpad-object int))))) + (set! (-> a2-6 joint-ptr) (the-as (inline-array joint) (-> arg0 jgeo data 0))) + (set! (-> a2-6 bone-ptr) (-> arg0 skeleton bones)) + (set! (-> a2-6 num-bones) (the-as uint s1-0)) + ) + (let ((t0-2 s3-0) + (t1-0 0) + (t4-0 (the-as bone-memory (+ 16 (scratchpad-object int)))) + (a2-8 *bone-calculation-list*) + (a3-8 (the-as bone-calculation a1-1)) + ) + (let ((t2-0 (-> t4-0 work regs joint-ptr)) + (t3-0 (-> t4-0 work regs bone-ptr)) + (t4-1 (-> t4-0 work regs num-bones)) + (t5-0 a3-8) + ) + (set! (-> t5-0 flags) (the-as bone-calc-flags t1-0)) + (set! (-> t5-0 num-bones) t4-1) + (set! (-> t5-0 matrix-area) (the-as (inline-array matrix) t0-2)) + (set! (-> t5-0 joints) t2-0) + (set! (-> t5-0 bones) t3-0) + (set! (-> t5-0 next) (the-as bone-calculation 0)) + ) + (if (nonzero? (-> a2-8 next)) + (set! (-> a2-8 next next) a3-8) + ) + (if (zero? (-> a2-8 first)) + (set! (-> a2-8 first) a3-8) + ) + (set! (-> a2-8 next) a3-8) + ;; total guess + (&+! (-> arg1 base) (* 2 (+ 256 a0-1))) + ) + ))) + (none)) + +(defun draw-bones-hud ((arg0 draw-control) (arg1 dma-buffer)) + ;; hack + (none) + ) (define-extern draw-bones-hud (function draw-control dma-buffer none)) \ No newline at end of file diff --git a/goal_src/engine/anim/joint.gc b/goal_src/engine/anim/joint.gc index c5cac6e3fa..ec4e6308d1 100644 --- a/goal_src/engine/anim/joint.gc +++ b/goal_src/engine/anim/joint.gc @@ -1169,132 +1169,133 @@ ;; all run by create-interpolated-joint-animation-frame -(defun cspace<-parented-transformq-joint! ((arg0 cspace) (arg1 transformq)) - (nop!) - ;; the ops in these funcs were scrambled for pipeline optimization. screw that. - ;; f0 = 1.0 - ;; a3 = -> arg0 parent (used once) - (rlet ((acc :class vf) - (vf0 :class vf) ;; unit - (vf5 :class vf) ;; quat - (vf15 :class vf) ;; trans - (vf6 :class vf) ;; temp - (vf2 :class vf) ;; temp - (vf3 :class vf) ;; temp - (vf4 :class vf) ;; temp +(def-mips2c cspace<-parented-transformq-joint! (function cspace transformq none)) +; (defun cspace<-parented-transformq-joint! ((arg0 cspace) (arg1 transformq)) +; (nop!) +; ;; the ops in these funcs were scrambled for pipeline optimization. screw that. +; ;; f0 = 1.0 +; ;; a3 = -> arg0 parent (used once) +; (rlet ((acc :class vf) +; (vf0 :class vf) ;; unit +; (vf5 :class vf) ;; quat +; (vf15 :class vf) ;; trans +; (vf6 :class vf) ;; temp +; (vf2 :class vf) ;; temp +; (vf3 :class vf) ;; temp +; (vf4 :class vf) ;; temp - (vf1 :class vf) ;; temp - (vf7 :class vf) ;; temp - (vf8 :class vf) ;; temp - (vf9 :class vf) ;; temp - (vf10 :class vf) ;; temp +; (vf1 :class vf) ;; temp +; (vf7 :class vf) ;; temp +; (vf8 :class vf) ;; temp +; (vf9 :class vf) ;; temp +; (vf10 :class vf) ;; temp - (vf11 :class vf) ;; temp - (vf12 :class vf) ;; temp - (vf13 :class vf) ;; temp - (vf14 :class vf) ;; temp +; (vf11 :class vf) ;; temp +; (vf12 :class vf) ;; temp +; (vf13 :class vf) ;; temp +; (vf14 :class vf) ;; temp - (vf16 :class vf) ;; temp - (t1 :class vf) - (t2 :class vf) - (t3 :class vf) - ) - (init-vf0-vector) - (.lvf vf5 (-> arg1 quat)) - (.lvf vf15 (-> arg1 trans)) - (let ((t0 (-> arg0 parent bone)) - (a2 (-> arg0 bone)) - ) - (.add.vf vf6 vf5 vf5) - ;; set vf2 - (.add.w.vf vf2 vf0 vf5 :mask #b0001) - (.add.z.vf vf2 vf0 vf5 :mask #b0010) - (.sub.y.vf vf2 vf0 vf5 :mask #b0100) - (.sub.w.vf vf2 vf0 vf0 :mask #b1000) - ;; set vf3 - (.sub.z.vf vf3 vf0 vf5 :mask #b0001) - (.add.w.vf vf3 vf0 vf5 :mask #b0010) - (.add.x.vf vf3 vf0 vf5 :mask #b0100) - (.sub.w.vf vf3 vf0 vf0 :mask #b1000) - ;; set vf4 - (.add.y.vf vf4 vf0 vf5 :mask #b0001) - (.sub.x.vf vf4 vf0 vf5 :mask #b0010) - (.add.w.vf vf4 vf0 vf5 :mask #b0100) - (.sub.w.vf vf4 vf0 vf0 :mask #b1000) - ;; outer prods - (.outer.product.a.vf acc vf6 vf2) - (.outer.product.b.vf vf2 vf2 vf6 acc) - (.outer.product.a.vf acc vf6 vf3) - (.outer.product.b.vf vf3 vf3 vf6 acc) - (.outer.product.a.vf acc vf6 vf4) - (.outer.product.b.vf vf4 vf4 vf6 acc) - ;; add ones - (.add.w.vf vf2 vf2 vf0 :mask #b0001) - (.add.w.vf vf3 vf3 vf0 :mask #b0010) - (.add.w.vf vf4 vf4 vf0 :mask #b0100) +; (vf16 :class vf) ;; temp +; (t1 :class vf) +; (t2 :class vf) +; (t3 :class vf) +; ) +; (init-vf0-vector) +; (.lvf vf5 (-> arg1 quat)) +; (.lvf vf15 (-> arg1 trans)) +; (let ((t0 (-> arg0 parent bone)) +; (a2 (-> arg0 bone)) +; ) +; (.add.vf vf6 vf5 vf5) +; ;; set vf2 +; (.add.w.vf vf2 vf0 vf5 :mask #b0001) +; (.add.z.vf vf2 vf0 vf5 :mask #b0010) +; (.sub.y.vf vf2 vf0 vf5 :mask #b0100) +; (.sub.w.vf vf2 vf0 vf0 :mask #b1000) +; ;; set vf3 +; (.sub.z.vf vf3 vf0 vf5 :mask #b0001) +; (.add.w.vf vf3 vf0 vf5 :mask #b0010) +; (.add.x.vf vf3 vf0 vf5 :mask #b0100) +; (.sub.w.vf vf3 vf0 vf0 :mask #b1000) +; ;; set vf4 +; (.add.y.vf vf4 vf0 vf5 :mask #b0001) +; (.sub.x.vf vf4 vf0 vf5 :mask #b0010) +; (.add.w.vf vf4 vf0 vf5 :mask #b0100) +; (.sub.w.vf vf4 vf0 vf0 :mask #b1000) +; ;; outer prods +; (.outer.product.a.vf acc vf6 vf2) +; (.outer.product.b.vf vf2 vf2 vf6 acc) +; (.outer.product.a.vf acc vf6 vf3) +; (.outer.product.b.vf vf3 vf3 vf6 acc) +; (.outer.product.a.vf acc vf6 vf4) +; (.outer.product.b.vf vf4 vf4 vf6 acc) +; ;; add ones +; (.add.w.vf vf2 vf2 vf0 :mask #b0001) +; (.add.w.vf vf3 vf3 vf0 :mask #b0010) +; (.add.w.vf vf4 vf4 vf0 :mask #b0100) - ;; things for cond blocks - (.lvf vf7 (-> t0 transform vector 0)) - (.lvf vf8 (-> t0 transform vector 1)) - (.lvf vf9 (-> t0 transform vector 2)) - (.lvf vf10 (-> t0 transform vector 3)) - (.lvf vf1 (-> a2 scale)) +; ;; things for cond blocks +; (.lvf vf7 (-> t0 transform vector 0)) +; (.lvf vf8 (-> t0 transform vector 1)) +; (.lvf vf9 (-> t0 transform vector 2)) +; (.lvf vf10 (-> t0 transform vector 3)) +; (.lvf vf1 (-> a2 scale)) - (cond - ((zero? (-> t0 scale w)) - (.mul.x.vf vf2 vf2 vf1) - (.mul.y.vf vf3 vf3 vf1) - (.mul.z.vf vf4 vf4 vf1) +; (cond +; ((zero? (-> t0 scale w)) +; (.mul.x.vf vf2 vf2 vf1) +; (.mul.y.vf vf3 vf3 vf1) +; (.mul.z.vf vf4 vf4 vf1) - ;; the same - (.matrix*! acc (vf11 vf12 vf13 vf14) (vf2 vf3 vf4 (vf15 vf15 vf15 vf0)) (vf7 vf8 vf9 vf10)) - (.svf (-> a2 transform vector 0) vf11) - (.svf (-> a2 transform vector 1) vf12) - (.svf (-> a2 transform vector 2) vf13) - (.svf (-> a2 transform vector 3) vf14) - ) - (else - (.mul.x.vf vf2 vf2 vf1) - (.mul.y.vf vf3 vf3 vf1) - (.mul.z.vf vf4 vf4 vf1) +; ;; the same +; (.matrix*! acc (vf11 vf12 vf13 vf14) (vf2 vf3 vf4 (vf15 vf15 vf15 vf0)) (vf7 vf8 vf9 vf10)) +; (.svf (-> a2 transform vector 0) vf11) +; (.svf (-> a2 transform vector 1) vf12) +; (.svf (-> a2 transform vector 2) vf13) +; (.svf (-> a2 transform vector 3) vf14) +; ) +; (else +; (.mul.x.vf vf2 vf2 vf1) +; (.mul.y.vf vf3 vf3 vf1) +; (.mul.z.vf vf4 vf4 vf1) - (.mov t1 (/ 1.0 (-> t0 scale x))) - (.mov t2 (/ 1.0 (-> t0 scale y))) - (.mov t3 (/ 1.0 (-> t0 scale z))) - (.pextlw t1 t1 t2) - (.pcpyld t1 t1 t3) - (.mov vf16 t1) - (.mul.vf vf2 vf2 vf16) - (.mul.vf vf3 vf3 vf16) - (.mul.vf vf4 vf4 vf16) +; (.mov t1 (/ 1.0 (-> t0 scale x))) +; (.mov t2 (/ 1.0 (-> t0 scale y))) +; (.mov t3 (/ 1.0 (-> t0 scale z))) +; (.pextlw t1 t1 t2) +; (.pcpyld t1 t1 t3) +; (.mov vf16 t1) +; (.mul.vf vf2 vf2 vf16) +; (.mul.vf vf3 vf3 vf16) +; (.mul.vf vf4 vf4 vf16) - ;; the same - (.matrix*! acc (vf11 vf12 vf13 vf14) (vf2 vf3 vf4 (vf15 vf15 vf15 vf0)) (vf7 vf8 vf9 vf10)) - (.svf (-> a2 transform vector 0) vf11) - (.svf (-> a2 transform vector 1) vf12) - (.svf (-> a2 transform vector 2) vf13) - (.svf (-> a2 transform vector 3) vf14) - ) - ) - ) - ) - ) +; ;; the same +; (.matrix*! acc (vf11 vf12 vf13 vf14) (vf2 vf3 vf4 (vf15 vf15 vf15 vf0)) (vf7 vf8 vf9 vf10)) +; (.svf (-> a2 transform vector 0) vf11) +; (.svf (-> a2 transform vector 1) vf12) +; (.svf (-> a2 transform vector 2) vf13) +; (.svf (-> a2 transform vector 3) vf14) +; ) +; ) +; ) +; ) +; ) -(defun clear-frame-accumulator ((arg0 (inline-array vector))) -;; TODO - (with-sp - (.sub sp 16) - (nop!) - (nop!) - (nop!) - (nop!) - (nop!) - (nop!) - (nop!) - (nop!) - (.add sp 16) - ) - ) +; (defun clear-frame-accumulator ((arg0 (inline-array vector))) +; ;; TODO +; (with-sp +; (.sub sp 16) +; (nop!) +; (nop!) +; (nop!) +; (nop!) +; (nop!) +; (nop!) +; (nop!) +; (nop!) +; (.add sp 16) +; ) +; ) (define-extern decompress-fixed-data-to-accumulator (function none)) (define-extern decompress-frame-data-to-accumulator (function none)) @@ -1305,179 +1306,156 @@ ;; ERROR: function was not converted to expressions. Cannot decompile. + + (defun make-joint-jump-tables () +#| + #x3ee6b6f9, // = 9 ^ 1055307504 + #x3ee6b6ff, // = 15 ^ 1055307504 + #x3ee6b6e2, // = 18 ^ 1055307504 + #x3ee6b6e4, // = 20 ^ 1055307504 + #x3ee6b6e5, // = 21 ^ 1055307504 + #x3ee6b6eb, // = 27 ^ 1055307504 + #x3ee6b6ee, // = 30 ^ 1055307504 + #x3ee6b6f6, // = 6 ^ 1055307504 + #x3ee6b6fc, // = 12 ^ 1055307504 + #x3ee6b6ff, // = 15 ^ 1055307504 + #x3ee6b6e3, // = 19 ^ 1055307504 + #x3ee6b6e4, // = 20 ^ 1055307504 + #x3ee6b6e8, // = 24 ^ 1055307504 + #x3ee6b6eb, // = 27 ^ 1055307504 + #x3ee6b6ef, // = 31 ^ 1055307504 + #x3ee6b6f6, // = 6 ^ 1055307504 + |# (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 0) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 108 4))) + (the-as (function none) (+ 0 #x3ee6b6f9)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 1) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4))) + (the-as (function none) (+ 0 #x3ee6b6ff)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 2) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 233 4))) + (the-as (function none) (+ 0 #x3ee6b6e2)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 3) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4))) + (the-as (function none) (+ 0 #x3ee6b6e4)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 4) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 301 4))) + (the-as (function none) (+ 0 #x3ee6b6e5)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 5) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4))) + (the-as (function none) (+ 0 #x3ee6b6eb)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 6) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 387 4))) + (the-as (function none) (+ 0 #x3ee6b6ee)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 7) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4))) + (the-as (function none) (+ 0 #x3ee6b6f6)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 8) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 155 4))) + (the-as (function none) (+ 0 #x3ee6b6fc)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 9) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4))) + (the-as (function none) (+ 0 #x3ee6b6ff)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 10) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 261 4))) + (the-as (function none) (+ 0 #x3ee6b6e3)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 11) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4))) + (the-as (function none) (+ 0 #x3ee6b6e4)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 12) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 335 4))) + (the-as (function none) (+ 0 #x3ee6b6e8)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 13) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4))) + (the-as (function none) (+ 0 #x3ee6b6eb)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 14) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 402 4))) + (the-as (function none) (+ 0 #x3ee6b6ef)) ) (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 15) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 0) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 1) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 92 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 2) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 3) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 140 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 4) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 5) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 220 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 6) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 7) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 307 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 8) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 9) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 107 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 10) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 11) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 174 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 12) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 13) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 248 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 14) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 15) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 354 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 0) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 1) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 125 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 2) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 3) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 197 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 4) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 5) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 318 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 6) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 7) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 459 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 8) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 9) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 150 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 10) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 11) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 248 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 12) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 13) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 366 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 14) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4))) - ) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 15) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 533 4))) + (the-as (function none) (+ 0 #x3ee6b6f6)) ) + + + (let ((arr (new 'static 'array uint32 16 + #x7b2191b ;; = 6 ^ 129112349 + #x7b21914 ;; = 9 ^ 129112349 + #x7b21916 ;; = 11 ^ 129112349 + #x7b21913 ;; = 14 ^ 129112349 + #x7b21909 ;; = 20 ^ 129112349 + #x7b21908 ;; = 21 ^ 129112349 + #x7b2190a ;; = 23 ^ 129112349 + #x7b21907 ;; = 26 ^ 129112349 + #x7b2191b ;; = 6 ^ 129112349 + #x7b21917 ;; = 10 ^ 129112349 + #x7b21916 ;; = 11 ^ 129112349 + #x7b2190c ;; = 17 ^ 129112349 + #x7b21909 ;; = 20 ^ 129112349 + #x7b2190b ;; = 22 ^ 129112349 + #x7b2190a ;; = 23 ^ 129112349 + #x7b21900 ;; = 29 ^ 129112349 + ))) + (dotimes (i 16) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table i) + (the-as (function none) (-> arr i)) + ) + ) + ) + + (let ((arr (new 'static 'array uint32 16 + #x4d7666df ;; = 6 ^ 1299605209 + #x4d7666d0 ;; = 9 ^ 1299605209 + #x4d7666d2 ;; = 11 ^ 1299605209 + #x4d7666d7 ;; = 14 ^ 1299605209 + #x4d7666cd ;; = 20 ^ 1299605209 + #x4d7666cc ;; = 21 ^ 1299605209 + #x4d7666ce ;; = 23 ^ 1299605209 + #x4d7666c3 ;; = 26 ^ 1299605209 + #x4d7666df ;; = 6 ^ 1299605209 + #x4d7666d3 ;; = 10 ^ 1299605209 + #x4d7666d2 ;; = 11 ^ 1299605209 + #x4d7666c8 ;; = 17 ^ 1299605209 + #x4d7666cd ;; = 20 ^ 1299605209 + #x4d7666cf ;; = 22 ^ 1299605209 + #x4d7666ce ;; = 23 ^ 1299605209 + #x4d7666c4 ;; = 29 ^ 1299605209 + ))) + (dotimes (i 16) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table i) + (the-as (function none) (-> arr i)) + ) + ) + ) 0 ) -(defun calc-animation-from-spr ((arg0 (inline-array vector)) (arg1 int)) - (declare (asm-func object) - (allow-saved-regs) ;; very dangerous! - ) - (with-sp - ;; useless possibly leftover reg move here - (rlet ( - (s0 :reg rbx) - (s1 :reg rbp) - (s2 :reg r10) - (s3 :reg r11) - (s4 :reg r12) - (s6 :reg r13) - ) - ;(.sub sp -16) +; (defun calc-animation-from-spr ((arg0 (inline-array vector)) (arg1 int)) +; (declare (asm-func object) +; (allow-saved-regs) ;; very dangerous! +; ) +; (with-sp +; ;; useless possibly leftover reg move here +; (rlet ( +; (s0 :reg rbx) +; (s1 :reg rbp) +; (s2 :reg r10) +; (s3 :reg r11) +; (s4 :reg r12) +; (s6 :reg r13) +; ) +; ;(.sub sp -16) - (let ((joint-num arg1)) +; (let ((joint-num arg1)) - ) +; ) - ;(.add sp 16) - ) - ) - (.ret) - ) +; ;(.add sp 16) +; ) +; ) +; (.ret) +; ) + +(def-mips2c calc-animation-from-spr (function (inline-array vector) int none)) (defun create-interpolated-joint-animation-frame ((arg0 (inline-array vector)) (arg1 int) (arg2 process-drawable)) (flatten-joint-control-to-spr (-> arg2 skel)) diff --git a/goal_src/engine/draw/drawable.gc b/goal_src/engine/draw/drawable.gc index f74f006396..053df56985 100644 --- a/goal_src/engine/draw/drawable.gc +++ b/goal_src/engine/draw/drawable.gc @@ -5,6 +5,16 @@ ;; name in dgo: drawable ;; dgos: GAME, ENGINE +(defun sphere-cull ((arg0 vector)) + #t + ;; todo + ) + +(defun guard-band-cull ((arg0 vector)) + #t + ;; todo + ) + (defun sphere-in-view-frustum? ((arg0 sphere)) (local-vars (r0-0 uint128) (v1-1 uint128) (v1-2 uint128) (v1-3 uint128)) (rlet ((acc :class vf) @@ -75,10 +85,95 @@ ) ) +(defun vis-cull ((id int)) + "Is this thing visible? By draw-node id." + ;; todo + #t + + #| + (let* ((addr (scratchpad-ptr int8 :offset (+ #x3b80 (/ id 8)))) ;; address of the vis data + (vis-byte (-> addr 0)) ;; vis byte + (shift-amount (+ 56 (logand id 7))) + (shifted (shl vis-byte shift-amount)) + ) + (< shifted 0) + ) + |# + ) + +(defun error-sphere ((arg0 drawable-error) (arg1 string)) + (when *artist-error-spheres* + (when (vis-cull (-> arg0 id)) + (when (sphere-cull (-> arg0 bsphere)) + (add-debug-sphere + #t + (bucket-id debug-draw0) + (-> arg0 bsphere) + (-> arg0 bsphere w) + (new 'static 'rgba :r #x80 :a #x80) + ) + (add-debug-text-3d #t (bucket-id debug-draw1) arg1 (-> arg0 bsphere) (font-color white) (the-as vector2h #f)) + ) + ) + ) + 0 + (none) + ) + +(defmethod login drawable ((obj drawable)) + obj + ) + +(defmethod draw drawable ((obj drawable) (arg0 drawable) (arg1 display-frame)) + 0 + (none) + ) + +(defmethod collide-with-box drawable ((obj drawable) (arg0 int) (arg1 collide-list)) + 0 + (none) + ) + +(defmethod collide-y-probe drawable ((obj drawable) (arg0 int) (arg1 collide-list)) + 0 + (none) + ) + +(defmethod collide-ray drawable ((obj drawable) (arg0 int) (arg1 collide-list)) + 0 + (none) + ) + +(defmethod collect-ambients drawable ((obj drawable) (arg0 sphere) (arg1 int) (arg2 ambient-list)) + 0 + (none) + ) + +(defmethod collect-stats drawable ((obj drawable)) + 0 + (none) + ) + +(defmethod debug-draw drawable ((obj drawable) (arg0 drawable) (arg1 display-frame)) + 0 + (none) + ) + +(defmethod draw drawable-error ((obj drawable-error) (arg0 drawable-error) (arg1 display-frame)) + (error-sphere arg0 (-> arg0 name)) + (none) + ) + (defmethod unpack-vis drawable ((obj drawable) (arg0 (pointer int8)) (arg1 (pointer int8))) arg1 ) +(define *edit-instance* (the-as string #f)) + +(when *debug-segment* + (define *instance-mem-usage* (new 'debug 'memory-usage-block)) + ) + (defun-debug find-instance-by-name ((arg0 string)) (dotimes (s5-0 (-> *level* length)) (let ((v1-3 (-> *level* level s5-0))) @@ -115,7 +210,52 @@ (the-as prototype-bucket #f) ) -(define-extern prototype-bucket-type (function prototype-bucket type)) ;; TODO +(defun-debug find-instance-by-index ((arg0 type) (arg1 int) (arg2 bsp-header)) + (dotimes (v1-0 (-> *level* length)) + (let ((a3-3 (-> *level* level v1-0))) + (when (= (-> a3-3 status) 'active) + (let ((a3-4 (-> a3-3 bsp))) + (when (or (not arg2) (= a3-4 arg2)) + (let ((a3-5 (-> a3-4 drawable-trees))) + (dotimes (t0-5 (-> a3-5 length)) + (let ((t1-3 (-> a3-5 trees t0-5))) + (case (-> t1-3 type) + ((drawable-tree-instance-shrub) + (when (= arg0 (-> t1-3 type)) + (let ((v1-2 (-> (the-as drawable-tree-instance-shrub t1-3) info prototype-inline-array-shrub))) + (return (-> v1-2 data arg1)) + ) + ) + ) + ((drawable-tree-instance-tie) + (when (= arg0 (-> t1-3 type)) + (let ((v1-5 (-> (the-as drawable-tree-instance-tie t1-3) prototypes prototype-array-tie))) + (return (-> v1-5 array-data arg1)) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + (the-as prototype-bucket #f) + ) + +(defun-debug prototype-bucket-type ((arg0 prototype-bucket)) + (case (-> arg0 geometry 1 type) + ((prototype-shrubbery shrubbery) + instance-shrubbery + ) + ((prototype-tie prototype-tie tie-fragment) + instance-tie + ) + ) + ) (defun-debug prototype-bucket-recalc-fields ((arg0 prototype-bucket)) (case (prototype-bucket-type arg0) @@ -133,31 +273,597 @@ arg0 ) -(defun sphere-cull ((arg0 vector)) - #t - ;; todo - ) -(defun guard-band-cull ((arg0 vector)) - #t - ;; todo - ) - -(defun vis-cull ((id int)) - "Is this thing visible? By draw-node id." - ;; todo - #t - - #| - (let* ((addr (scratchpad-ptr int8 :offset (+ #x3b80 (/ id 8)))) ;; address of the vis data - (vis-byte (-> addr 0)) ;; vis byte - (shift-amount (+ 56 (logand id 7))) - (shifted (shl vis-byte shift-amount)) - ) - (< shifted 0) +#| +(defun-debug draw-instance-info ((arg0 string)) + (local-vars + (sv-16 int) + (sv-32 uint) + (sv-48 uint) + (sv-64 int) + (sv-80 int) + (sv-96 int) + (sv-112 int) + (sv-128 int) + (sv-144 int) ) - |# + (when (and *display-instance-info* *edit-instance*) + (let ((s5-0 (find-instance-by-name *edit-instance*))) + (when s5-0 + (let ((s2-0 (prototype-bucket-type s5-0))) + (let ((s4-0 0)) + 0 + (cond + ((= s2-0 instance-shrubbery) + (set! s4-0 595) + ) + ((= s2-0 instance-tie) + (reset! *instance-mem-usage*) + (dotimes (s4-1 4) + (when (nonzero? (-> s5-0 geometry s4-1)) + (let* ((a0-4 (-> s5-0 geometry s4-1)) + (t9-3 (method-of-object a0-4 mem-usage)) + (a1-0 *instance-mem-usage*) + (v1-16 s4-1) + ) + (t9-3 a0-4 a1-0 (logior (cond + ((= v1-16 1) + 4 + ) + ((= v1-16 2) + 8 + ) + ((= v1-16 3) + 16 + ) + (else + 0 + ) + ) + 2 + ) + ) + ) + ) + ) + (set! s4-0 (+ (calculate-total *instance-mem-usage*) 580)) + ) + ) + (mem-usage s5-0 (reset! *instance-mem-usage*) 0) + (let ((v1-26 (calculate-total *instance-mem-usage*))) + (format + arg0 + "~%~A ~A b @ #x~X ~,,2fK/~,,2fK~%" + s2-0 + (-> s5-0 name) + s5-0 + (* 0.0009765625 (the float v1-26)) + (* 0.0009765625 (the float s4-0)) + ) + ) + ) + (format arg0 "near: ~m mid: ~m far: ~m~%" (-> s5-0 dists x) (-> s5-0 dists z) (-> s5-0 dists w)) + (let ((s3-1 0) + (s4-2 0) + ) + (cond + ((= s2-0 instance-shrubbery) + (let ((f30-0 0.0)) + (format + arg0 + "usage: vis: ~D shurb: ~D trans-shrub ~D bill: ~D in level: ~D~%" + (-> s5-0 count 0) + (-> s5-0 count 1) + (-> s5-0 count 2) + (-> s5-0 count 3) + (-> s5-0 in-level) + ) + (format arg0 "~%frag# tris dverts strlen tex~%") + (let ((s1-1 (-> s5-0 geometry 1)) + (s2-1 (+ (-> s5-0 count 1) (-> s5-0 count 2))) + ) + (dotimes (s0-0 (-> (the-as drawable-group s1-1) length)) + (set! sv-16 (shrub-num-tris (the-as shrubbery (+ (+ (* s0-0 32) 32) (the-as int s1-1))))) + (set! sv-32 (-> (the-as prototype-shrubbery (+ (the-as uint s1-1) (* s0-0 32))) data 0 header data 2)) + (set! sv-48 (-> (the-as prototype-shrubbery (+ (the-as uint s1-1) (* s0-0 32))) data 0 header data 0)) + (format + arg0 + "~5D ~4D ~5D ~6f ~D~%" + s0-0 + sv-16 + sv-32 + (/ (* 2.0 (the float sv-16)) (the float (- sv-32 (the-as uint sv-16)))) + sv-48 + ) + (+! s3-1 sv-16) + (+! s4-2 sv-32) + (set! f30-0 + (+ 29.0 + (* 5.5 (the float (- sv-32 (the-as uint sv-16)))) + (* 22.0 (the float sv-48)) + (* 8.0 (the float sv-32)) + (* 53.0 (the float (/ (+ s2-1 9) (the-as uint 10)))) + (* (the float s2-1) (+ 15.0 (* 5.0 (the float sv-48)) (* 13.5 (the float sv-32)))) + f30-0 + ) + ) + ) + (format + arg0 + "total ~4D ~5D ~6f ~D speed: ~f~%" + s3-1 + s4-2 + (/ (* 2.0 (the float s3-1)) (the float (- s4-2 s3-1))) + (-> s5-0 utextures) + (/ f30-0 (* (the float s2-1) (the float s3-1))) + ) + ) + ) + ) + ((= s2-0 instance-tie) + (set! sv-144 0) + (let ((s1-2 0) + (s0-1 0) + (s2-2 0) + ) + (format arg0 "~%level visible frags tris dverts strlen tex ttris~%") + (set! sv-64 1) + (set! sv-80 3) + (while (>= sv-80 sv-64) + (let ((v1-65 (-> s5-0 geometry sv-64))) + (set! sv-96 0) + (set! sv-112 0) + (set! sv-128 0) + (dotimes (a0-23 (-> (the-as prototype-tie v1-65) length)) + (set! sv-96 (+ sv-96 (l.hu (+ (the-as uint v1-65) (* a0-23 64) 68)))) + (set! sv-112 (+ sv-112 (l.hu (+ (the-as uint v1-65) (* a0-23 64) 70)))) + (set! sv-128 (+ sv-128 (l.hu (+ (the-as uint v1-65) (* a0-23 64) 60)))) + ) + (set! sv-144 (+ sv-144 (-> s5-0 count sv-64))) + (format arg0 "~5D ~7D ~5D ~5D" sv-64 (-> s5-0 count sv-64) (-> (the-as prototype-tie v1-65) length) sv-96) + ) + (format + arg0 + " ~5D ~6f ~3D ~5D~%" + sv-112 + (/ (* 2.0 (the float sv-96)) (the float (- sv-112 sv-96))) + sv-128 + (* (the-as uint sv-96) (-> s5-0 count sv-64)) + ) + (+! s1-2 (* (the-as uint sv-96) (-> s5-0 count sv-64))) + (+! s0-1 (* (the-as uint sv-112) (-> s5-0 count sv-64))) + (+! s3-1 sv-96) + (+! s4-2 sv-112) + (+! s2-2 sv-128) + (set! sv-64 (+ sv-64 1)) + ) + (let ((t9-18 format) + (a0-39 arg0) + (a1-22 "total ~7D/~3D ~5D") + (a3-11 (-> s5-0 in-level)) + ) + (t9-18 a0-39 a1-22 sv-144 a3-11 s3-1) + ) + (format + arg0 + " ~5D ~6f ~3D ~5D~%" + s4-2 + (/ (* 2.0 (the float s1-2)) (the float (- s0-1 s1-2))) + s2-2 + s1-2 + ) + ) + ) + ) + ) + ) + ) + ) + ) + (none) ) +|# + +(defun dma-add-process-drawable ((arg0 process-drawable) (arg1 draw-control) (arg2 symbol) (arg3 dma-buffer)) + (local-vars (v1-37 float) (sv-16 process-drawable)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :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) + (vf22 :class vf) + (vf23 :class vf) + (vf24 :class vf) + (vf25 :class vf) + (vf26 :class vf) + (vf27 :class vf) + (vf28 :class vf) + (vf29 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + ) + (init-vf0-vector) + (set! sv-16 arg0) + (logclear! (-> arg1 status) (draw-status drwf03)) + (when (zero? (logand (-> arg1 status) (draw-status drwf01 drwf02 drwf04))) + (let ((s4-0 (the-as vector (+ 48 (the-as int (scratchpad-object int))))) + (s2-0 (the-as vu-lights (+ 64 (the-as int (scratchpad-object int))))) + (s3-0 *time-of-day-context*) + ) + (.lvf vf16 (&-> arg1 origin quad)) + (.lvf vf17 (&-> arg1 bounds quad)) + (.mul.x.vf vf16 vf16 vf0 :mask #b1000) + (.add.vf vf16 vf16 vf17) + (.svf (&-> s4-0 quad) vf16) + (.lvf vf28 (&-> arg1 color-mult quad)) + (.lvf vf29 (&-> arg1 color-emissive quad)) + (when (sphere-in-view-frustum? (the-as sphere s4-0)) + (case (-> arg1 global-effect) + (((draw-effect title)) + (when (not (-> s3-0 title-updated)) + (set! (-> s3-0 title-updated) #t) + (let ((s0-0 (-> *math-camera* inv-camera-rot)) + (a1-1 (new 'stack-no-clear 'vector)) + (s1-0 (new 'stack-no-clear 'vector)) + ) + (set-vector! a1-1 0.612 0.5 -0.612 0.0) + (set-vector! s1-0 -0.696 0.174 0.696 0.0) + (vector-matrix*! (the-as vector (-> s3-0 title-light-group)) a1-1 s0-0) + (vector-matrix*! (the-as vector (-> s3-0 title-light-group dir1)) s1-0 s0-0) + ) + (set-vector! (-> *time-of-day-context* current-shadow) 0.612 -0.5 -0.612 1.0) + ) + (vu-lights<-light-group! s2-0 (-> s3-0 title-light-group)) + ) + (else + (let ((f28-0 (-> arg1 secondary-interp)) + (f30-0 (-> arg1 current-secondary-interp)) + (v1-17 (-> arg1 shadow-mask)) + (a0-10 (-> arg1 level-index)) + (s0-1 (-> s3-0 light-group (-> *target* draw light-index))) + (s1-1 (new 'stack-no-clear 'light-group)) + ) + (cond + ((= (-> arg1 light-index) 255) + ) + ((= a0-10 2) + (set! s0-1 (-> s3-0 light-group (-> arg1 light-index))) + ) + (else + (set! s0-1 (-> s3-0 moods a0-10 light-group (-> arg1 light-index))) + ) + ) + (when (not (or (= a0-10 2) (zero? v1-17))) + (let* ((a1-22 (-> s3-0 light-masks-0 a0-10)) + (a2-14 (-> s3-0 light-masks-1 a0-10)) + (f26-0 (-> s3-0 light-interp a0-10)) + (a0-13 (logand a1-22 v1-17)) + (v1-18 (logand a2-14 v1-17)) + ) + (cond + ((and (zero? a0-13) (zero? v1-18)) + ) + (else + (set! f28-0 (cond + ((and (nonzero? a0-13) (nonzero? v1-18)) + 1.0 + ) + ((zero? a0-13) + (quad-copy! (the-as pointer s1-1) (the-as pointer s0-1) 12) + (set! s0-1 s1-1) + (set! (-> s0-1 dir1 levels x) 0.0) + f26-0 + ) + (else + (quad-copy! (the-as pointer s1-1) (the-as pointer s0-1) 12) + (set! s0-1 s1-1) + (set! (-> s0-1 dir0 levels x) 0.0) + (- 1.0 f26-0) + ) + ) + ) + ) + ) + ) + ) + (if *teleport* + (set! f30-0 f28-0) + ) + (when (not (or (paused?) (= f28-0 f30-0))) + (let ((f0-15 (- f30-0 f28-0))) + (set! f30-0 (cond + ((< (fabs f0-15) 0.2) + f28-0 + ) + ((< f0-15 0.0) + (+ 0.2 f30-0) + ) + (else + (+ -0.2 f30-0) + ) + ) + ) + ) + (set! (-> arg1 current-secondary-interp) f30-0) + ) + (cond + ((= f30-0 0.0) + (vu-lights<-light-group! s2-0 s0-1) + ) + (else + (if (!= s0-1 s1-1) + (quad-copy! (the-as pointer s1-1) (the-as pointer s0-1) 12) + ) + (let ((f0-20 (- 1.0 f30-0))) + (set! (-> s1-1 dir0 levels x) (* (-> s1-1 dir0 levels x) f0-20)) + (set! (-> s1-1 dir0 levels y) (* (-> s1-1 dir0 levels y) f0-20)) + (set! (-> s1-1 dir1 levels x) (* (-> s1-1 dir1 levels x) f0-20)) + (set! (-> s1-1 dir1 levels y) (* (-> s1-1 dir1 levels y) f0-20)) + (set! (-> s1-1 dir2 levels x) (* (-> s1-1 dir2 levels x) f0-20)) + (set! (-> s1-1 dir2 levels y) (* (-> s1-1 dir2 levels y) f0-20)) + ) + (vu-lights<-light-group! s2-0 s1-1) + ) + ) + ) + (.lvf vf2 (&-> s2-0 color 0 quad)) + (.lvf vf3 (&-> s2-0 color 1 quad)) + (.lvf vf4 (&-> s2-0 color 2 quad)) + (.lvf vf5 (&-> s2-0 ambient quad)) + (.mul.vf vf5 vf5 vf28) + (.mul.vf vf2 vf2 vf28) + (.mul.vf vf3 vf3 vf28) + (.mul.vf vf4 vf4 vf28) + (.add.vf vf5 vf5 vf29) + (.svf (&-> s2-0 color 0 quad) vf2) + (.svf (&-> s2-0 color 1 quad) vf3) + (.svf (&-> s2-0 color 2 quad) vf4) + (.svf (&-> s2-0 ambient quad) vf5) + (.mov v1-37 vf5) + ) + ) + (if *display-lights* + (add-debug-lights + #t + (bucket-id debug-draw0) + (the-as (inline-array light) (-> s3-0 light-group)) + (-> arg1 origin) + ) + ) + (let ((at-0 *math-camera*)) + (.lvf vf16 (&-> at-0 plane 0 quad)) + (.lvf vf17 (&-> at-0 plane 1 quad)) + (.lvf vf18 (&-> at-0 plane 2 quad)) + (.lvf vf19 (&-> at-0 plane 3 quad)) + (.lvf vf20 (&-> at-0 guard-plane 0 quad)) + (.lvf vf21 (&-> at-0 guard-plane 1 quad)) + (.lvf vf22 (&-> at-0 guard-plane 2 quad)) + (.lvf vf23 (&-> at-0 guard-plane 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)) + ) + (let ((v1-42 (the-as vector (+ 176 (the-as int (scratchpad-object int)))))) + (.lvf vf15 (&-> s4-0 quad)) + (.mul.w.vf acc vf27 vf0) + (.add.mul.x.vf acc vf24 vf15 acc) + (.add.mul.y.vf acc vf25 vf15 acc) + (.add.mul.z.vf vf15 vf26 vf15 acc :mask #b111) + (.mul.vf vf28 vf15 vf15) + (.max.w.vf vf29 vf0 vf0) + (.add.y.vf acc vf28 vf28) + (.add.mul.z.vf vf28 vf29 vf28 acc :mask #b1) + (.sqrt.vf Q vf28 :ftf #b0) + (.sub.w.vf vf28 vf0 vf15 :mask #b1000) + (.wait.vf) + (.add.vf vf15 vf28 Q :mask #b1000) + (.svf (&-> v1-42 quad) vf15) + (when (< 0.0 (+ (-> v1-42 z) (-> arg1 bounds w))) + (let ((lod-to-use 0)) + (let ((cam-dist (-> v1-42 w))) + (when (nonzero? (-> arg1 lod-set max-lod)) + (cond + ((>= (-> arg1 force-lod) 0) + (set! lod-to-use (-> arg1 force-lod)) + (if (< (-> arg1 lod-set lod (-> arg1 lod-set max-lod) dist) cam-dist) + (return #f) + ) + ) + (else + (while (and (< lod-to-use (-> arg1 lod-set max-lod)) (< (-> arg1 lod-set lod lod-to-use dist) cam-dist)) + (+! lod-to-use 1) + ) + ) + ) + ) + (if (and (< (-> arg1 lod-set lod lod-to-use dist) cam-dist) (< (-> arg1 force-lod) 0)) + (return #f) + ) + (let ((v1-64 (-> arg1 sink-group level)) + (a0-26 (+ (-> arg1 sink-group merc-sink foreground-texture-page) 6)) + ) + (when (zero? (logand (-> arg1 status) (draw-status drwf06))) + (if (< cam-dist (-> v1-64 closest-object a0-26)) + (set! (-> v1-64 closest-object a0-26) cam-dist) + ) + (when (and (!= a0-26 6) (!= (-> arg1 level-index) 2)) + (let ((a1-45 (cond + ((< 102400.0 cam-dist) + (-> arg1 mgeo header masks 0) + ) + ((< 81920.0 cam-dist) + (-> arg1 mgeo header masks 1) + ) + (else + (-> arg1 mgeo header masks 2) + ) + ) + ) + ) + (logior! (-> v1-64 texture-mask a0-26) a1-45) + ) + ) + ) + ) + (if (or (guard-band-cull s4-0) (< cam-dist (* 1.2 (-> *math-camera* d)))) + (logior! (-> arg1 status) (draw-status drwf00)) + (logclear! (-> arg1 status) (draw-status drwf00)) + ) + (logior! (-> arg1 status) (draw-status drwf03)) + (if (logtest? (-> arg1 status) (draw-status drwf05)) + (return #f) + ) + (draw-bones arg1 arg3 cam-dist) + ) + (when (and (< lod-to-use (-> arg1 cur-lod)) (logtest? (-> arg1 status) (draw-status drwf07))) + (let ((v1-82 *matrix-engine*)) + (set! (-> v1-82 (-> v1-82 length)) (process->handle sv-16)) + (+! (-> v1-82 length) 1) + ) + ) + (lod-set! arg1 lod-to-use) + ) + ) + ) + ) + ) + ) + 0 + (none) + ) + ) + +(define *hud-lights* (new 'global 'vu-lights)) +(set-vector! (-> *hud-lights* direction 0) 1.0 0.0 0.0 1.0) +(set-vector! (-> *hud-lights* direction 1) 0.0 1.0 0.0 1.0) +(set-vector! (-> *hud-lights* direction 2) 0.0 0.0 1.0 1.0) +(set-vector! (-> *hud-lights* color 0) 0.0 0.0 0.0 1.0) +(set-vector! (-> *hud-lights* color 1) 0.0 0.0 0.0 1.0) +(set-vector! (-> *hud-lights* color 2) 0.5 0.5 0.5 1.0) +(set-vector! (-> *hud-lights* ambient) 0.5 0.5 0.5 1.0) + +(defun dma-add-process-drawable-hud ((arg0 process-drawable) (arg1 draw-control) (arg2 symbol) (arg3 dma-buffer)) + (logclear! (-> arg1 status) (draw-status drwf03)) + (when (zero? (logand (-> arg1 status) (draw-status drwf01 drwf02 drwf04))) + (let ((v1-6 (the-as vu-lights (+ 64 (scratchpad-object int)))) + (a0-3 *hud-lights*) + ) + (set! (-> v1-6 direction 0 quad) (-> a0-3 direction 0 quad)) + (set! (-> v1-6 direction 1 quad) (-> a0-3 direction 1 quad)) + (set! (-> v1-6 direction 2 quad) (-> a0-3 direction 2 quad)) + (set! (-> v1-6 color 0 quad) (-> a0-3 color 0 quad)) + (set! (-> v1-6 color 1 quad) (-> a0-3 color 1 quad)) + (set! (-> v1-6 color 2 quad) (-> a0-3 color 2 quad)) + (set! (-> v1-6 ambient quad) (-> a0-3 ambient quad)) + ) + (lod-set! arg1 0) + (logior! (-> arg1 status) (draw-status drwf03)) + (draw-bones-hud arg1 arg3) + ) + 0 + (none) + ) + +(defun add-process-drawable ((arg0 process-drawable) (arg1 draw-control) (arg2 symbol) (arg3 dma-buffer)) + ((-> arg1 dma-add-func) arg0 arg1 arg2 arg3) + (none) + ) + +(defun foreground-engine-execute ((arg0 engine) (arg1 display-frame) (arg2 int) (arg3 int)) + (let ((s4-0 (-> *display* frames (-> *display* on-screen) frame global-buf base))) + (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-2 (+ (+ (* arg3 32) 272 (* 2608 arg2)) (the-as int *level*))) + (s2-1 (-> arg1 global-buf)) + ) + ; (let ((v1-14 (-> s2-1 base))) + ; (.sync.l) + ; (.cache dxwbin v1-14 0) + ; (.sync.l) + ; (.cache dxwbin v1-14 1) + ; ) + ; (.sync.l) + 0 + (bones-init s2-1 (the-as dma-foreground-sink-group a1-2)) + (execute-connections arg0 s2-1) + ) + (bones-wrapup) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #xbe :g #x55 :b #x82 :a #x80) + ) + ) + (let ((v1-24 *dma-mem-usage*)) + (when (nonzero? v1-24) + (set! (-> v1-24 length) (max 36 (-> v1-24 length))) + (set! (-> v1-24 data 35 name) "pris-fragment") + (+! (-> v1-24 data 35 count) 1) + (+! (-> v1-24 data 35 used) + (&- (-> *display* frames (-> *display* on-screen) frame global-buf base) (the-as uint s4-0)) + ) + (set! (-> v1-24 data 35 total) (-> v1-24 data 35 used)) + ) + ) + ) + ;; todo + ; (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic)) + ; (when (nonzero? (-> *merc-globals* first)) + ; (let ((s4-1 (-> *display* frames (-> *display* on-screen) frame global-buf base))) + ; (let ((a0-25 (-> (the-as (pointer uint32) (+ (the-as uint *level*) (* 2608 arg2) (* arg3 32))) 69))) + ; (generic-merc-add-to-cue a0-25) + ; ) + ; (let ((a0-26 *dma-mem-usage*)) + ; (when (nonzero? a0-26) + ; (set! (-> a0-26 length) (max 87 (-> a0-26 length))) + ; (set! (-> a0-26 data 86 name) "pris-generic") + ; (+! (-> a0-26 data 86 count) 1) + ; (+! (-> a0-26 data 86 used) + ; (&- (-> *display* frames (-> *display* on-screen) frame global-buf base) (the-as uint s4-1)) + ; ) + ; (set! (-> a0-26 data 86 total) (-> a0-26 data 86 used)) + ; ) + ; ) + ; ) + ; ) + ; ) + (when #t + (let ((v1-41 *shadow-queue*)) + (+! (-> v1-41 cur-run) 1) + ) + ) + 0 + (none) + ) + +(defun-debug main-debug-hook () + (when (not (or (= *master-mode* 'menu) (= *master-mode* 'progress))) + (execute-connections *debug-engine* #f) + ;; (draw-instance-info *stdcon*) + ) + (none) + ) + +;; definition for symbol *debug-hook*, type (function none) +(define *debug-hook* main-debug-hook) + +(define *add-sphere* #f) + +(define *generic-effect-mode* 0) (defun real-main-draw-hook () (when *slow-frame-rate* @@ -299,8 +1005,9 @@ ;; closest (update-ocean) ;; draw ocean - ;; merc - ;; init bg + (set! (-> *merc-global-array* count) (the-as uint 0)) + (set! *merc-globals* (the-as merc-globals (-> *merc-global-array* globals))) + (set! (-> *shadow-queue* cur-run) (the-as uint 0)) (init-background) ;; exec bg @@ -330,7 +1037,23 @@ ) ) (start-perf-stat-collection) - + (foreground-engine-execute + (-> *level* level-default foreground-draw-engine 0) + (-> *display* frames (-> *display* on-screen) frame) + 2 + 0 + ) + (foreground-engine-execute + (-> *level* level-default foreground-draw-engine 1) + (-> *display* frames (-> *display* on-screen) frame) + 2 + 1 + ) + (let ((gp-9 (-> *display* frames (-> *display* on-screen) frame global-buf))) + (bones-mtx-calc-execute) + ;;(generic-merc-execute-all) + ;;(shadow-execute-all gp-9 *shadow-queue*) + ) ;; fg engine ;; bones ;; gmerc @@ -367,16 +1090,7 @@ (define *draw-hook* main-draw-hook) -(defun-debug main-debug-hook () - (when (not (or (= *master-mode* 'menu) (= *master-mode* 'progress))) - (execute-connections *debug-engine* #f) - ;; (draw-instance-info *stdcon*) - ) - (none) - ) -;; definition for symbol *debug-hook*, type (function none) -(define *debug-hook* main-debug-hook) (defun debug-init-buffer ((arg0 bucket-id) (arg1 gs-zbuf) (arg2 gs-test)) "Initialize a bucket for debug draw with the given zbuf and test settings" @@ -880,339 +1594,6 @@ (display-sync disp) ;; also starts next ) -(defun add-process-drawable ((arg0 process-drawable) (arg1 draw-control) (arg2 symbol) (arg3 dma-buffer)) - ((-> arg1 dma-add-func) arg0 arg1 arg2 arg3) - (none) - ) - -(defun dma-add-process-drawable ((arg0 process-drawable) (arg1 draw-control) (arg2 symbol) (arg3 dma-buffer)) - (local-vars (v1-37 float) (sv-16 process-drawable)) - (rlet ((acc :class vf) - (Q :class vf) - (vf0 :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) - (vf22 :class vf) - (vf23 :class vf) - (vf24 :class vf) - (vf25 :class vf) - (vf26 :class vf) - (vf27 :class vf) - (vf28 :class vf) - (vf29 :class vf) - (vf3 :class vf) - (vf4 :class vf) - (vf5 :class vf) - ) - (init-vf0-vector) - (set! sv-16 arg0) - (logclear! (-> arg1 status) (draw-status drwf03)) - (when (zero? (logand (-> arg1 status) (draw-status drwf01 drwf02 drwf04))) - (let ((s4-0 (the-as vector (+ 48 (the-as int (the-as terrain-context #x70000000))))) - (s2-0 (the-as vu-lights (+ 64 (the-as int (the-as terrain-context #x70000000))))) - (s3-0 *time-of-day-context*) - ) - (.lvf vf16 (&-> arg1 origin quad)) - (.lvf vf17 (&-> arg1 bounds quad)) - (.mul.x.vf vf16 vf16 vf0 :mask #b1000) - (.add.vf vf16 vf16 vf17) - (.svf (&-> s4-0 quad) vf16) - (.lvf vf28 (&-> arg1 color-mult quad)) - (.lvf vf29 (&-> arg1 color-emissive quad)) - (when (sphere-in-view-frustum? (the-as sphere s4-0)) - (case (-> arg1 global-effect) - (((draw-effect title)) - (when (not (-> s3-0 title-updated)) - (set! (-> s3-0 title-updated) #t) - (let ((s0-0 (-> *math-camera* inv-camera-rot)) - (a1-1 (new 'stack-no-clear 'vector)) - (s1-0 (new 'stack-no-clear 'vector)) - ) - (set-vector! a1-1 0.612 0.5 -0.612 0.0) - (set-vector! s1-0 -0.696 0.174 0.696 0.0) - (vector-matrix*! (the-as vector (-> s3-0 title-light-group)) a1-1 s0-0) - (vector-matrix*! (the-as vector (-> s3-0 title-light-group dir1)) s1-0 s0-0) - ) - (set-vector! (-> *time-of-day-context* current-shadow) 0.612 -0.5 -0.612 1.0) - ) - (vu-lights<-light-group! s2-0 (-> s3-0 title-light-group)) - ) - (else - (let ((f28-0 (-> arg1 secondary-interp)) - (f30-0 (-> arg1 current-secondary-interp)) - (v1-17 (-> arg1 shadow-mask)) - (a0-10 (-> arg1 level-index)) - (s0-1 (-> s3-0 light-group (-> *target* draw light-index))) - (s1-1 (new 'stack-no-clear 'light-group)) - ) - (cond - ((= (-> arg1 light-index) 255) - ) - ((= a0-10 2) - (set! s0-1 (-> s3-0 light-group (-> arg1 light-index))) - ) - (else - (set! s0-1 (-> s3-0 moods a0-10 light-group (-> arg1 light-index))) - ) - ) - (when (not (or (= a0-10 2) (zero? v1-17))) - (let* ((a1-22 (-> s3-0 light-masks-0 a0-10)) - (a2-14 (-> s3-0 light-masks-1 a0-10)) - (f26-0 (-> s3-0 light-interp a0-10)) - (a0-13 (logand a1-22 v1-17)) - (v1-18 (logand a2-14 v1-17)) - ) - (cond - ((and (zero? a0-13) (zero? v1-18)) - ) - (else - (set! f28-0 (cond - ((and (nonzero? a0-13) (nonzero? v1-18)) - 1.0 - ) - ((zero? a0-13) - (quad-copy! (the-as pointer s1-1) (the-as pointer s0-1) 12) - (set! s0-1 s1-1) - (set! (-> s0-1 dir1 levels x) 0.0) - f26-0 - ) - (else - (quad-copy! (the-as pointer s1-1) (the-as pointer s0-1) 12) - (set! s0-1 s1-1) - (set! (-> s0-1 dir0 levels x) 0.0) - (- 1.0 f26-0) - ) - ) - ) - ) - ) - ) - ) - (if *teleport* - (set! f30-0 f28-0) - ) - (when (not (or (paused?) (= f28-0 f30-0))) - (let ((f0-15 (- f30-0 f28-0))) - (set! f30-0 (cond - ((< (fabs f0-15) 0.2) - f28-0 - ) - ((< f0-15 0.0) - (+ 0.2 f30-0) - ) - (else - (+ -0.2 f30-0) - ) - ) - ) - ) - (set! (-> arg1 current-secondary-interp) f30-0) - ) - (cond - ((= f30-0 0.0) - (vu-lights<-light-group! s2-0 s0-1) - ) - (else - (if (!= s0-1 s1-1) - (quad-copy! (the-as pointer s1-1) (the-as pointer s0-1) 12) - ) - (let ((f0-20 (- 1.0 f30-0))) - (set! (-> s1-1 dir0 levels x) (* (-> s1-1 dir0 levels x) f0-20)) - (set! (-> s1-1 dir0 levels y) (* (-> s1-1 dir0 levels y) f0-20)) - (set! (-> s1-1 dir1 levels x) (* (-> s1-1 dir1 levels x) f0-20)) - (set! (-> s1-1 dir1 levels y) (* (-> s1-1 dir1 levels y) f0-20)) - (set! (-> s1-1 dir2 levels x) (* (-> s1-1 dir2 levels x) f0-20)) - (set! (-> s1-1 dir2 levels y) (* (-> s1-1 dir2 levels y) f0-20)) - ) - (vu-lights<-light-group! s2-0 s1-1) - ) - ) - ) - (.lvf vf2 (&-> s2-0 color 0 quad)) - (.lvf vf3 (&-> s2-0 color 1 quad)) - (.lvf vf4 (&-> s2-0 color 2 quad)) - (.lvf vf5 (&-> s2-0 ambient quad)) - (.mul.vf vf5 vf5 vf28) - (.mul.vf vf2 vf2 vf28) - (.mul.vf vf3 vf3 vf28) - (.mul.vf vf4 vf4 vf28) - (.add.vf vf5 vf5 vf29) - (.svf (&-> s2-0 color 0 quad) vf2) - (.svf (&-> s2-0 color 1 quad) vf3) - (.svf (&-> s2-0 color 2 quad) vf4) - (.svf (&-> s2-0 ambient quad) vf5) - (.mov v1-37 vf5) - ) - ) - (if *display-lights* - (add-debug-lights - #t - (bucket-id debug-draw0) - (the-as (inline-array light) (-> s3-0 light-group)) - (-> arg1 origin) - ) - ) - (let ((at-0 *math-camera*)) - (.lvf vf16 (&-> at-0 plane 0 quad)) - (.lvf vf17 (&-> at-0 plane 1 quad)) - (.lvf vf18 (&-> at-0 plane 2 quad)) - (.lvf vf19 (&-> at-0 plane 3 quad)) - (.lvf vf20 (&-> at-0 guard-plane 0 quad)) - (.lvf vf21 (&-> at-0 guard-plane 1 quad)) - (.lvf vf22 (&-> at-0 guard-plane 2 quad)) - (.lvf vf23 (&-> at-0 guard-plane 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)) - ) - (let ((v1-42 (the-as vector (+ 176 (the-as int (the-as terrain-context #x70000000)))))) - (.lvf vf15 (&-> s4-0 quad)) - (.mul.w.vf acc vf27 vf0) - (.add.mul.x.vf acc vf24 vf15 acc) - (.add.mul.y.vf acc vf25 vf15 acc) - (.add.mul.z.vf vf15 vf26 vf15 acc :mask #b111) - (.mul.vf vf28 vf15 vf15) - (.max.w.vf vf29 vf0 vf0) - (.add.y.vf acc vf28 vf28) - (.add.mul.z.vf vf28 vf29 vf28 acc :mask #b1) - (.sqrt.vf Q vf28 :ftf #b0) - (.sub.w.vf vf28 vf0 vf15 :mask #b1000) - (.wait.vf) - (.add.vf vf15 vf28 Q :mask #b1000) - (.svf (&-> v1-42 quad) vf15) - (when (< 0.0 (+ (-> v1-42 z) (-> arg1 bounds w))) - (let ((lod-to-use 0)) - (let ((cam-dist (-> v1-42 w))) - (when (nonzero? (-> arg1 lod-set max-lod)) - (cond - ((>= (-> arg1 force-lod) 0) - (set! lod-to-use (-> arg1 force-lod)) - (if (< (-> arg1 lod-set lod (-> arg1 lod-set max-lod) dist) cam-dist) - (return #f) - ) - ) - (else - (while (and (< lod-to-use (-> arg1 lod-set max-lod)) (< (-> arg1 lod-set lod lod-to-use dist) cam-dist)) - (+! lod-to-use 1) - ) - ) - ) - ) - (if (and (< (-> arg1 lod-set lod lod-to-use dist) cam-dist) (< (-> arg1 force-lod) 0)) - (return #f) - ) - (let ((v1-64 (-> arg1 sink-group level)) - (a0-26 (+ (-> arg1 sink-group merc-sink foreground-texture-page) 6)) - ) - (when (zero? (logand (-> arg1 status) (draw-status drwf06))) - (if (< cam-dist (-> v1-64 closest-object a0-26)) - (set! (-> v1-64 closest-object a0-26) cam-dist) - ) - (when (and (!= a0-26 6) (!= (-> arg1 level-index) 2)) - (let ((a1-45 (cond - ((< 102400.0 cam-dist) - (-> arg1 mgeo header masks 0) - ) - ((< 81920.0 cam-dist) - (-> arg1 mgeo header masks 1) - ) - (else - (-> arg1 mgeo header masks 2) - ) - ) - ) - ) - (logior! (-> v1-64 texture-mask a0-26) a1-45) - ) - ) - ) - ) - (if (or (guard-band-cull s4-0) (< cam-dist (* 1.2 (-> *math-camera* d)))) - (logior! (-> arg1 status) (draw-status drwf00)) - (logclear! (-> arg1 status) (draw-status drwf00)) - ) - (logior! (-> arg1 status) (draw-status drwf03)) - (if (logtest? (-> arg1 status) (draw-status drwf05)) - (return #f) - ) - (draw-bones arg1 arg3 cam-dist) - ) - (when (and (< lod-to-use (-> arg1 cur-lod)) (logtest? (-> arg1 status) (draw-status drwf07))) - (let ((v1-82 *matrix-engine*)) - (set! (-> v1-82 (-> v1-82 length)) (process->handle sv-16)) - (+! (-> v1-82 length) 1) - ) - ) - (lod-set! arg1 lod-to-use) - ) - ) - ) - ) - ) - ) - 0 - (none) - ) - ) - -(define *hud-lights* (new 'global 'vu-lights)) -(set-vector! (-> *hud-lights* direction 0) 1.0 0.0 0.0 1.0) -(set-vector! (-> *hud-lights* direction 1) 0.0 1.0 0.0 1.0) -(set-vector! (-> *hud-lights* direction 2) 0.0 0.0 1.0 1.0) -(set-vector! (-> *hud-lights* color 0) 0.0 0.0 0.0 1.0) -(set-vector! (-> *hud-lights* color 1) 0.0 0.0 0.0 1.0) -(set-vector! (-> *hud-lights* color 2) 0.5 0.5 0.5 1.0) -(set-vector! (-> *hud-lights* ambient) 0.5 0.5 0.5 1.0) - -(defun dma-add-process-drawable-hud ((arg0 process-drawable) (arg1 draw-control) (arg2 symbol) (arg3 dma-buffer)) - (logclear! (-> arg1 status) (draw-status drwf03)) - (when (zero? (logand (-> arg1 status) (draw-status drwf01 drwf02 drwf04))) - (let ((v1-6 (the-as vu-lights (+ 64 #x70000000))) - (a0-3 *hud-lights*) - ) - (set! (-> v1-6 direction 0 quad) (-> a0-3 direction 0 quad)) - (set! (-> v1-6 direction 1 quad) (-> a0-3 direction 1 quad)) - (set! (-> v1-6 direction 2 quad) (-> a0-3 direction 2 quad)) - (set! (-> v1-6 color 0 quad) (-> a0-3 color 0 quad)) - (set! (-> v1-6 color 1 quad) (-> a0-3 color 1 quad)) - (set! (-> v1-6 color 2 quad) (-> a0-3 color 2 quad)) - (set! (-> v1-6 ambient quad) (-> a0-3 ambient quad)) - ) - (lod-set! arg1 0) - (logior! (-> arg1 status) (draw-status drwf03)) - (draw-bones-hud arg1 arg3) - ) - 0 - (none) - ) - -(defmethod collide-ray drawable ((obj drawable) (arg0 int) (arg1 collide-list)) - 0 - (none) - ) - -(defmethod collide-with-box drawable ((obj drawable) (arg0 int) (arg1 collide-list)) - 0 - (none) - ) - -(defmethod collide-y-probe drawable ((obj drawable) (arg0 int) (arg1 collide-list)) - 0 - (none) - ) - -(defmethod collect-ambients drawable ((obj drawable) (arg0 sphere) (arg1 int) (arg2 ambient-list)) - 0 - (none) - ) - (defun-debug marks-cam-restore () (let ((a0-0 (new-stack-vector0)) (a1-0 (new-stack-matrix0)) @@ -1490,7 +1871,3 @@ ) (none) ) - - - - diff --git a/goal_src/engine/draw/process-drawable.gc b/goal_src/engine/draw/process-drawable.gc index 737122fbea..41ff1d60e1 100644 --- a/goal_src/engine/draw/process-drawable.gc +++ b/goal_src/engine/draw/process-drawable.gc @@ -261,7 +261,7 @@ (countdown (s5-0 (-> gp-0 length)) (let ((a0-1 (handle->process (-> gp-0 s5-0)))) (if a0-1 - (dummy-17 (the-as process-drawable a0-1)) + (do-joint-math! (the-as process-drawable a0-1)) ) ) ) @@ -271,9 +271,25 @@ 0 ) -(defmethod dummy-17 process-drawable ((obj process-drawable)) +(define-extern draw-joint-spheres (function process-drawable symbol)) + +(defun-debug draw-bone-lines ((obj process-drawable)) + "Added in PC port to debug bones" + (dotimes (i (-> obj node-list length)) + (let ((parent (-> obj node-list data i parent))) + (when (and parent (nonzero? parent) (-> parent joint) (-> parent parent)) + (let ((child (vector<-cspace! (new-stack-vector0) (-> obj node-list data i))) + ) + (add-debug-line #t (bucket-id debug-draw0) child (vector<-cspace! (new-stack-vector0) parent) (new 'static 'rgba :g #xff :a #x40) #f (the rgba -1)) + ) + ) + ) + ) + ) + +(defmethod do-joint-math! process-drawable ((obj process-drawable)) (cond - (#t;;(logtest? (-> obj draw status) (draw-status drwf01 drwf02)) TODO + ((logtest? (-> obj draw status) (draw-status drwf01 drwf02)) ) ((zero? (-> obj skel)) (matrix<-transformq+trans! @@ -288,12 +304,12 @@ (let ((s4-0 (+ s5-0 2))) (+ s4-0 1) ((-> obj skel generate-frame-function) - (the-as (inline-array vector) (+ 2416 (the-as int (the-as terrain-context #x70000000)))) + (the-as (inline-array vector) (+ 2416 (the-as int (the-as terrain-context (scratchpad-object int))))) s4-0 obj ) (if (-> obj skel prebind-function) - ((-> obj skel prebind-function) (the-as pointer (+ 2416 #x70000000)) s4-0 obj) + ((-> obj skel prebind-function) (the-as pointer (+ 2416 (scratchpad-object int))) s4-0 obj) ) ) (dotimes (s4-1 1) @@ -307,7 +323,7 @@ ) (dotimes (s4-2 2) (let* ((a0-15 (-> obj node-list data (+ s4-2 1))) - (a1-5 (+ (* s4-2 64) 2416 #x70000000)) + (a1-5 (+ (* s4-2 64) 2416 (scratchpad-object int))) (t9-4 (-> a0-15 param0)) ) (if t9-4 @@ -318,7 +334,7 @@ (let ((s4-3 3)) (dotimes (s3-0 s5-0) (let ((a0-17 (-> obj node-list data (+ s3-0 s4-3))) - (a1-7 (+ (* 48 s3-0) 2544 #x70000000)) + (a1-7 (+ (* 48 s3-0) 2544 (scratchpad-object int))) ) (if (-> a0-17 param0) ((the-as (function cspace matrix none) (-> a0-17 param0)) a0-17 (the-as matrix a1-7)) @@ -345,6 +361,9 @@ ) ) ) + (draw-bone-lines obj) + ;; (draw-joint-spheres obj) + 0 (none) ) @@ -364,6 +383,7 @@ (dotimes (s5-0 (-> arg0 node-list length)) (let ((a2-0 (vector<-cspace! (new-stack-vector0) (-> arg0 node-list data s5-0)))) (add-debug-sphere #t (bucket-id debug-draw0) a2-0 819.2 (new 'static 'rgba :g #xff :a #x40)) + ;;(add-debug-text-sphere #t (bucket-id debug-draw0) a2-0 819.2 (the string (-> arg0 node-list data s5-0 joint name)) (new 'static 'rgba :g #xff :a #x40)) ) ) #f @@ -578,7 +598,7 @@ (none) ) -(defmethod dummy-15 process-drawable ((obj process-drawable) (arg0 string) (arg1 object)) +(defmethod initialize-skeleton-by-name process-drawable ((obj process-drawable) (arg0 string) (arg1 object)) (let ((s3-0 string->symbol)) (format (clear *temp-string*) "*~S-sg*" arg0) (let ((s3-1 (-> (s3-0 *temp-string*) value))) @@ -954,22 +974,10 @@ (when (nonzero? (-> self skel)) (dummy-19 self) - (#when TARGET_STARTUP_HACKS - (when (eq? (-> self type) target) - (format *stdcon* "no bones for you~%") - (dotimes (i (length (-> self node-list))) - (matrix-identity! (-> self node-list data i bone transform)) - (set! (-> self node-list data i bone position quad) - (-> (the-as target self) control trans quad) - ) - (set! (-> self node-list data i bone position w) 1.0) - (+! (-> self node-list data i bone position y) (meters 0.0)) - ) - ) - ) + (when (or (logtest? (-> self skel status) 1) gp-1) - ;; (dummy-17 self) TODO + (do-joint-math! self) (if (and gp-1 (type-type? (-> self root type) collide-shape)) (update-transforms! (the-as collide-shape (-> self root))) ) diff --git a/goal_src/engine/game/game-h.gc b/goal_src/engine/game/game-h.gc index de94622c51..b6fb8ba39e 100644 --- a/goal_src/engine/game/game-h.gc +++ b/goal_src/engine/game/game-h.gc @@ -42,9 +42,9 @@ :flag-assert #x14004000b0 (:methods (initialize-skeleton (_type_ skeleton-group pair) none 14) - (dummy-15 (_type_ string object) _type_ 15) + (initialize-skeleton-by-name (_type_ string object) _type_ 15) (dummy-16 (_type_ int (inline-array vector) vector) collide-shape 16) - (dummy-17 (_type_) none 17) + (do-joint-math! (_type_) none 17) (dummy-18 (_type_) none 18) (dummy-19 (_type_) none 19) ) diff --git a/goal_src/engine/game/generic-obs.gc b/goal_src/engine/game/generic-obs.gc index 619fe2c33d..21f4a26e5c 100644 --- a/goal_src/engine/game/generic-obs.gc +++ b/goal_src/engine/game/generic-obs.gc @@ -64,7 +64,7 @@ (logior! (-> self draw status) (draw-status drwf02)) ) ) - (dummy-17 self) + (do-joint-math! self) (let ((a0-22 (-> self skel effect))) (if a0-22 (TODO-RENAME-9 a0-22) @@ -492,7 +492,7 @@ "" ) ) - (dummy-17 self) + (do-joint-math! self) ) (('clone-anim) (clone-anim-once @@ -1376,7 +1376,7 @@ (* s3-1 8) ) ) - (dummy-15 obj *lev-string* '()) + (initialize-skeleton-by-name obj *lev-string* '()) (logior! (-> obj draw status) (draw-status drwf06)) (if (nonzero? (-> obj draw)) (go med-res-level-idle) diff --git a/goal_src/engine/game/main-h.gc b/goal_src/engine/game/main-h.gc index 14cdf3ea27..eac3c839ed 100644 --- a/goal_src/engine/game/main-h.gc +++ b/goal_src/engine/game/main-h.gc @@ -7,7 +7,7 @@ ;; Global engine settings: (defglobalconstant TARGET_STARTUP_HACKS #t) -(defglobalconstant NO_BONES_HACK #t) +(defglobalconstant NO_BONES_HACK #f) (define *stats-poly* #f) (define *stats-memory* #f) (define *stats-memory-short* #f) diff --git a/goal_src/engine/game/task/process-taskable.gc b/goal_src/engine/game/task/process-taskable.gc index d4f2b00cb4..a42c5daf27 100644 --- a/goal_src/engine/game/task/process-taskable.gc +++ b/goal_src/engine/game/task/process-taskable.gc @@ -1347,6 +1347,7 @@ (s1-0 (or (!= (-> self spooling?) #t) (logtest? (-> (the-as process-taskable s2-0) skel status) 32))) ) (vector<-cspace! s5-0 (-> (the-as process-taskable s2-0) node-list data (-> self cam-joint-index))) + (vector-normalize-copy! gp-0 (-> s4-0 vector 2) -1.0) (when s1-0 (when (not (-> self had-valid-frame)) @@ -1418,20 +1419,22 @@ ) (defmethod draw-npc-shadow process-taskable ((obj process-taskable)) - (let ((gp-0 (-> obj draw shadow-ctrl))) - (cond - ((and (-> obj draw shadow) (zero? (-> obj draw cur-lod)) (logtest? (-> obj draw status) (draw-status drwf03))) - (dummy-15 gp-0 (-> obj draw origin) -4096.0 4096.0 32768.0) - (dummy-14 gp-0) - ) - (else - (let ((v1-10 gp-0)) - (logior! (-> v1-10 settings flags) 32) - ) - 0 - ) - ) - ) + (#unless TARGET_STARTUP_HACKS + (let ((gp-0 (-> obj draw shadow-ctrl))) + (cond + ((and (-> obj draw shadow) (zero? (-> obj draw cur-lod)) (logtest? (-> obj draw status) (draw-status drwf03))) + (dummy-15 gp-0 (-> obj draw origin) -4096.0 4096.0 32768.0) + (dummy-14 gp-0) + ) + (else + (let ((v1-10 gp-0)) + (logior! (-> v1-10 settings flags) 32) + ) + 0 + ) + ) + ) + ) (none) ) diff --git a/goal_src/engine/load/loader.gc b/goal_src/engine/load/loader.gc index 5982d0f994..fda5eec974 100644 --- a/goal_src/engine/load/loader.gc +++ b/goal_src/engine/load/loader.gc @@ -872,202 +872,198 @@ (define-extern joint-control-channel-group! (function joint-control-channel art-joint-anim (function joint-control-channel float float float) int)) (define-extern ja-aframe-num (function int float :behavior process-drawable)) +;; this function is modified to work without sound. +(define *str-pos-hack* 0) +(define *str-play-speed* 17) (define-extern ja-abort-spooled-anim (function spool-anim art-joint-anim int int :behavior process-drawable)) (defbehavior ja-play-spooled-anim process-drawable ((arg0 spool-anim) (arg1 art-joint-anim) (arg2 art-joint-anim) (arg3 (function process-drawable symbol))) - "Set up and start playing a spooled animation. details not understood yet." - - (let ((spool-part 0) - (sv-24 -17.0) - (old-skel-status (-> self skel status)) - (sv-32 -2) - (sv-40 0) - (sv-48 0) - (sv-56 0) - (spool-sound (new-sound-id)) - ) - (backup-load-state-and-set-cmds *load-state* (-> arg0 command-list)) - (set-setting! *setting-control* self 'spooling (the-as symbol (process->ppointer self)) 0.0 0) - (logior! (-> self skel status) #x7) - (kill-current-level-hint '() '() 'die) - (level-hint-surpress!) - (copy-settings-from-target! *setting-control*) - - ;; the spool lock is active (or we're not in game mode for some reason?) - ;; we can't nest or do multiple spooled joint animations. - (when (or (handle->process (-> *art-control* spool-lock)) - (!= *master-mode* 'game) - ) - (cond + (local-vars + (v0-39 int) + (spool-part int) + (sv-24 float) + (old-skel-status uint) + (sv-32 int) + (sv-40 int) + (sv-48 int) + (sv-56 int) + (spool-sound sound-id) + (sv-72 int) + ) + (set! *str-pos-hack* 0) + (set! spool-part 0) + (set! sv-24 -17.0) + (set! old-skel-status (-> self skel status)) + (set! sv-32 -2) + (set! sv-40 0) + (set! sv-48 0) + (set! sv-56 0) + (set! spool-sound (new-sound-id)) + (backup-load-state-and-set-cmds *load-state* (-> arg0 command-list)) + (set-setting! *setting-control* self 'spooling (the-as symbol (process->ppointer self)) 0.0 0) + (logior! (-> self skel status) 7) + (kill-current-level-hint '() '() 'die) + (level-hint-surpress!) + (copy-settings-from-target! *setting-control*) + (when (or (handle->process (-> *art-control* spool-lock)) (!= *master-mode* 'game)) + (cond (arg1 - (when (!= (if (> (-> self skel active-channels) 0) - (-> self skel root-channel 0 frame-group) + (when (!= (if (> (-> self skel active-channels) 0) + (-> self skel root-channel 0 frame-group) + ) + arg1 ) - arg1 - ) - (ja-channel-push! 1 15) - ;; TODO macro - (let ((s2-0 (-> self skel root-channel 0))) - (joint-control-channel-group-eval! s2-0 arg1 num-func-identity) - (set! (-> s2-0 frame-num) 0.0) - ) + (ja-channel-push! 1 15) + (let ((s2-0 (-> self skel root-channel 0))) + (joint-control-channel-group-eval! s2-0 arg1 num-func-identity) + (set! (-> s2-0 frame-num) 0.0) + ) + ) ) - ) (else - (ja-channel-set! 0) - ) + (ja-channel-set! 0) + ) ) - (while (or (handle->process (-> *art-control* spool-lock)) - (!= *master-mode* 'game) - ) + (while (or (handle->process (-> *art-control* spool-lock)) (!= *master-mode* 'game)) (format #t "WARNING: ---------------------> loader stall on lock~%") (if (arg3 self) - (goto anim-abort) - ) + (goto cfg-88) + ) (spool-push *art-control* (-> arg0 name) spool-part self -9.0) (suspend) (when arg1 - ;; TODO macro - (let ((a0-17 (-> self skel root-channel 0))) - (set! (-> a0-17 param 0) 1.0) - (joint-control-channel-group-eval! a0-17 (the-as art-joint-anim #f) num-func-loop!) - ) - ) - ) - ) - - ;; grab the lock - (set! (-> *art-control* spool-lock) (process->handle self)) - (set! sv-48 (the-as int (-> *display* base-frame-counter))) - - ;; iterate through parts (this loop suspends, so it lasts the whole animation) - (while (< spool-part (-> arg0 parts)) - ;; run the loader - (spool-push *art-control* (-> arg0 name) spool-part self -20.0) - (update *art-control* #f) - (spool-push *art-control* (-> arg0 name) spool-part self -20.0) - (when (!= (file-status *art-control* (-> arg0 name) spool-part) 'active) - (cond - (arg1 - (when (!= (if (> (-> self skel active-channels) 0) - (-> self skel root-channel 0 frame-group) - ) - arg1 - ) - (ja-channel-set! 1) - (let ((s2-2 (-> self skel root-channel 0))) - (joint-control-channel-group-eval! s2-2 arg1 num-func-identity) - (set! (-> s2-2 frame-num) 0.0) + (let ((a0-17 (-> self skel root-channel 0))) + (set! (-> a0-17 param 0) 1.0) + (joint-control-channel-group-eval! a0-17 (the-as art-joint-anim #f) num-func-loop!) ) - ) ) - (else - (ja-channel-set! 0) - ) - ) - (while (!= (file-status *art-control* (-> arg0 name) spool-part) 'active) - (if (arg3 self) - (goto anim-abort) - ) - (spool-push *art-control* (-> arg0 name) spool-part self -20.0) - (format #t "WARNING: ---------------------> loader stall on art ~S ~D~%" (-> arg0 name) spool-part) - (suspend) - (when arg1 - (let ((a0-37 (-> self skel root-channel 0))) - (set! (-> a0-37 param 0) 1.0) - (joint-control-channel-group-eval! a0-37 (the-as art-joint-anim #f) num-func-loop!) - ) - ) - ) ) - (spool-push *art-control* (-> arg0 name) spool-part self -20.0) - (let ((s2-4 (the-as art-joint-anim (dummy-10 (-> self draw art-group) (-> arg0 name) art-joint-anim)))) - (cond - (s2-4 - (ja-channel-set! 1) - (let ((a0-42 (-> self skel root-channel 0))) - (set! (-> a0-42 frame-group) s2-4) - (set! (-> a0-42 param 0) (the float (+ (-> s2-4 data 0 length) -1))) - (set! (-> a0-42 param 1) 1.0) - (set! (-> a0-42 frame-num) 0.0) - (joint-control-channel-group! a0-42 s2-4 num-func-seek!) - ) - (when (zero? spool-part) - (str-play-async (-> arg0 name) spool-sound) - (set! (-> *art-control* active-stream) (-> arg0 name)) - ) - (let* ((f30-0 (* 0.05859375 (-> s2-4 speed))) - (f28-0 (+ sv-24 (/ (the float (+ (-> s2-4 data 0 length) -1)) f30-0))) - (sv-72 (current-str-pos spool-sound)) - ) - (set! sv-40 (the-as int (-> *display* base-frame-counter))) - ;; uhh... - (until (begin - (spool-push *art-control* (-> arg0 name) spool-part self -20.0) - (cond - ((< (1+ spool-part) (-> arg0 parts)) - (spool-push *art-control* (-> arg0 name) (1+ spool-part) self -10.0) - ) - (else - (logclear! (-> self skel status) #x4) - ) - ) - - ;; execute sequence commands for loading/spawning/etc. - (execute-commands-up-to *load-state* (ja-aframe-num 0)) - - (cond - ((and (< sv-32 sv-72) (= (current-str-id) spool-sound)) - (+! sv-56 (the-as int (- (-> *display* base-frame-counter) (-> *display* old-base-frame-counter)))) - (set! sv-40 (the-as int (-> *display* base-frame-counter))) - ) - (else - 0 - ) - ) - (set! sv-32 sv-72) - (set! sv-48 (the-as int (-> *display* base-frame-counter))) - (suspend) - (let ((f0-14 (* (- (the float (current-str-pos spool-sound)) sv-24) f30-0)) - (a0-69 (-> self skel root-channel 0)) - ) - (set! (-> a0-69 param 0) (the float (+ (-> a0-69 frame-group data 0 length) -1))) - (set! (-> a0-69 param 1) 1.0) - (set! (-> a0-69 frame-num) f0-14) - (joint-control-channel-group! a0-69 (the-as art-joint-anim #f) num-func-seek!) - ) - (let ((v0-39 (current-str-pos spool-sound))) - (set! sv-72 v0-39) - (>= (the float v0-39) f28-0) - ) - ) - (if (= (-> self skel root-channel 0) (-> self skel channel)) - (logior! (-> self skel status) #x20) - ) - (if (or (arg3 self) - (and (<= sv-72 0) - (>= (the-as int (- (-> *display* base-frame-counter) sv-40)) (seconds 4)) - ) - (and (< (seconds 1) sv-56) (<= sv-72 0)) - ) - (goto anim-abort) - ) - ) - (set! sv-24 f28-0) - ) - (logclear! (-> self skel status) #x20) - ) - (else - (format 0 "ERROR: ~A in spool anim loop for ~A ~D, but not loaded.~" self (-> arg0 name) spool-part) - (goto anim-abort) - ) - ) - ) - (1+! spool-part) - ) - (1-! spool-part) - (label anim-abort) - (ja-abort-spooled-anim arg0 arg2 spool-part) ) + (let ((v1-46 (process->ppointer self))) + (set! (-> *art-control* spool-lock) + (new 'static 'handle :process v1-46 :pid (-> (the-as process (-> v1-46 0)) pid)) + ) + ) + (set! sv-48 (-> *display* base-frame-counter)) + (while (< spool-part (-> arg0 parts)) + (spool-push *art-control* (-> arg0 name) spool-part self -20.0) + (update *art-control* #f) + (spool-push *art-control* (-> arg0 name) spool-part self -20.0) + (when (!= (file-status *art-control* (-> arg0 name) spool-part) 'active) + (cond + (arg1 + (when (!= (if (> (-> self skel active-channels) 0) + (-> self skel root-channel 0 frame-group) + ) + arg1 + ) + (ja-channel-set! 1) + (let ((s2-2 (-> self skel root-channel 0))) + (joint-control-channel-group-eval! s2-2 arg1 num-func-identity) + (set! (-> s2-2 frame-num) 0.0) + ) + ) + ) + (else + (ja-channel-set! 0) + ) + ) + (while (!= (file-status *art-control* (-> arg0 name) spool-part) 'active) + (if (arg3 self) + (goto cfg-88) + ) + (spool-push *art-control* (-> arg0 name) spool-part self -20.0) + (format #t "WARNING: ---------------------> loader stall on art ~S ~D~%" (-> arg0 name) spool-part) + (suspend) + (when arg1 + (let ((a0-37 (-> self skel root-channel 0))) + (set! (-> a0-37 param 0) 1.0) + (joint-control-channel-group-eval! a0-37 (the-as art-joint-anim #f) num-func-loop!) + ) + ) + ) + ) + (spool-push *art-control* (-> arg0 name) spool-part self -20.0) + (let ((s2-4 (the-as art-joint-anim (dummy-10 (-> self draw art-group) (-> arg0 name) art-joint-anim)))) + (cond + (s2-4 + (ja-channel-set! 1) + (let ((a0-42 (-> self skel root-channel 0))) + (set! (-> a0-42 frame-group) s2-4) + (set! (-> a0-42 param 0) (the float (+ (-> s2-4 data 0 length) -1))) + (set! (-> a0-42 param 1) 1.0) + (set! (-> a0-42 frame-num) 0.0) + (joint-control-channel-group! a0-42 s2-4 num-func-seek!) + ) + (when (zero? spool-part) + (str-play-async (-> arg0 name) spool-sound) + ;; hack! + ;;(set! *str-pos-hack* 0) + ;; + (set! (-> *art-control* active-stream) (-> arg0 name)) + ) + (let* ((f30-0 (* 0.05859375 (-> s2-4 speed))) + (f28-0 (+ sv-24 (/ (the float (+ (-> s2-4 data 0 length) -1)) f30-0))) + ) + ;;(set! sv-72 (current-str-pos spool-sound)) + (set! sv-72 *str-pos-hack*) + + + (set! sv-40 (-> *display* base-frame-counter)) + (until (>= (the float v0-39) f28-0) + (+! *str-pos-hack* *str-play-speed*) + (if (= (-> self skel root-channel 0) (-> self skel channel)) + (logior! (-> self skel status) 32) + ) + (if (or (arg3 self) + (and (<= sv-72 0) (>= (- (-> *display* base-frame-counter) sv-40) 1200)) + (and (< 300 sv-56) (<= sv-72 0)) + ) + (goto cfg-88) + ) + (spool-push *art-control* (-> arg0 name) spool-part self -20.0) + (if (< (+ spool-part 1) (-> arg0 parts)) + (spool-push *art-control* (-> arg0 name) (+ spool-part 1) self -10.0) + (set! (-> self skel status) (logand -5 (-> self skel status))) + ) + (execute-commands-up-to *load-state* (ja-aframe-num 0)) + (cond + ((and (< sv-32 sv-72) #|(= (current-str-id) spool-sound)|#) + (set! sv-56 (+ sv-56 (- (-> *display* base-frame-counter) (-> *display* old-base-frame-counter)))) + (set! sv-40 (-> *display* base-frame-counter)) + ) + (else + 0 + ) + ) + (set! sv-32 sv-72) + (set! sv-48 (-> *display* base-frame-counter)) + (suspend) + (let ((f0-14 (* (- (the float *str-pos-hack* #|(current-str-pos spool-sound)|#) sv-24) f30-0)) + (a0-69 (-> self skel root-channel 0)) + ) + (set! (-> a0-69 param 0) (the float (+ (-> a0-69 frame-group data 0 length) -1))) + (set! (-> a0-69 param 1) 1.0) + (set! (-> a0-69 frame-num) f0-14) + (joint-control-channel-group! a0-69 (the-as art-joint-anim #f) num-func-seek!) + ) + (set! v0-39 *str-pos-hack* #|(current-str-pos spool-sound)|#) + (set! sv-72 v0-39) + ) + (set! sv-24 f28-0) + ) + (set! (-> self skel status) (logand -33 (-> self skel status))) + ) + (else + (format 0 "ERROR: ~A in spool anim loop for ~A ~D, but not loaded.~" self (-> arg0 name) spool-part) + (goto cfg-88) + ) + ) + ) + (set! spool-part (+ spool-part 1)) + ) + (set! spool-part (+ spool-part -1)) + (label cfg-88) + (ja-abort-spooled-anim arg0 arg2 spool-part) 0 ) diff --git a/goal_src/engine/math/trigonometry.gc b/goal_src/engine/math/trigonometry.gc index 61f288e7a5..22fc7325cf 100644 --- a/goal_src/engine/math/trigonometry.gc +++ b/goal_src/engine/math/trigonometry.gc @@ -1256,7 +1256,18 @@ (defun acos ((arg0 float)) "Inverse cosine. Returns rotation units" - (- 16384.000000 (asin arg0)) + (let ((result (- 16384.000000 (asin arg0)))) + (#when PC_PORT + ;; to avoid punch glitch: + ;; (note: it might be a better fix to change the global rounding mode, + ;; but it's not super clear to me that the mode picked by PCSX2 is + ;; more accurate than normal in all cases. So, we'll do this for now.) + (when (= result 0.0) + (set! result 0.00000000001) + ) + ) + result + ) ) (defun acos-rad ((arg0 float)) diff --git a/goal_src/engine/target/logic-target.gc b/goal_src/engine/target/logic-target.gc index e06ee3ec64..b877b783ec 100644 --- a/goal_src/engine/target/logic-target.gc +++ b/goal_src/engine/target/logic-target.gc @@ -1291,7 +1291,7 @@ ) ) (set-quaternion! (-> self control) (-> self control dir-targ)) - (dummy-17 self) + (do-joint-math! self) (none) ) @@ -1319,7 +1319,7 @@ ) ) (set! (-> self control unknown-float110) 0.0) - (dummy-17 self) + (do-joint-math! self) (none) ) @@ -1405,7 +1405,7 @@ ) ) (set-quaternion! (-> self control) (-> self control dir-targ)) - (dummy-17 self) + (do-joint-math! self) (update-transforms! (-> self control)) (none) ) diff --git a/goal_src/engine/target/sidekick.gc b/goal_src/engine/target/sidekick.gc index 385aeed893..c8313c9267 100644 --- a/goal_src/engine/target/sidekick.gc +++ b/goal_src/engine/target/sidekick.gc @@ -162,7 +162,7 @@ (new 'static 'rgba :r #x40 :b #x40 :a #x80) ) ) - (dummy-17 self) + (do-joint-math! self) (if *debug-segment* (add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0) diff --git a/goal_src/kernel/gkernel-h.gc b/goal_src/kernel/gkernel-h.gc index 067d14fa4b..415ab636f8 100644 --- a/goal_src/kernel/gkernel-h.gc +++ b/goal_src/kernel/gkernel-h.gc @@ -46,10 +46,7 @@ (defconstant PROCESS_STACK_SAVE_SIZE 256) ;; the size of the shared heap used by dynamically sized processes -(#if PC_BIG_MEMORY - (defconstant PROCESS_HEAP_SIZE (* 984 1024 4)) ;; 4x 984kB = 3936kB - (defconstant PROCESS_HEAP_SIZE (* 984 1024)) - ) +(defconstant PROCESS_HEAP_SIZE (* 984 1024)) ;; -system- diff --git a/goal_src/kernel/gkernel.gc b/goal_src/kernel/gkernel.gc index 896ef40e94..808db8566c 100644 --- a/goal_src/kernel/gkernel.gc +++ b/goal_src/kernel/gkernel.gc @@ -120,9 +120,9 @@ (#cond (PC_PORT - ;; similar thing for the scratchpad data. - (let* ((mem (new 'global 'array 'uint8 (* (+ 16 8) 1024))) - (aligned (logand (&+ mem 8192) (lognot 8191))) + ;; make sure the scratchpad is 16kb aligned + (let* ((mem (new 'global 'array 'uint8 (* (+ 16 16) 1024))) + (aligned (logand (&+ mem 16384) (lognot 16383))) ) (define *fake-scratchpad-data* aligned) ) diff --git a/goal_src/levels/common/ropebridge.gc b/goal_src/levels/common/ropebridge.gc index c5f8714a10..768c7ae62f 100644 --- a/goal_src/levels/common/ropebridge.gc +++ b/goal_src/levels/common/ropebridge.gc @@ -5,3 +5,904 @@ ;; name in dgo: ropebridge ;; dgos: GAME, COMMON, L1 + +(deftype ropebridge-tuning (structure) + ((num-springs int32 :offset-assert 0) + (num-spring-points int32 :offset-assert 4) + (col-mesh-indexes (pointer uint8) :offset-assert 8) + (view-frustum-radius float :offset-assert 12) + (root-prim-radius float :offset-assert 16) + (desired-spring-len float :offset-assert 20) + (gravity float :offset-assert 24) + (spring-coefficient float :offset-assert 28) + (spring-mass float :offset-assert 32) + (friction float :offset-assert 36) + (max-influence-dist float :offset-assert 40) + (rider-max-gravity float :offset-assert 44) + (max-bonk-influence-dist float :offset-assert 48) + (rider-bonk-force float :offset-assert 52) + (rider-bonk-min float :offset-assert 56) + (rider-bonk-max float :offset-assert 60) + (normal-board-len float :offset-assert 64) + (bridge-end-to-end-len float :offset-assert 68) + (rest-state symbol :offset-assert 72) + ) + :method-count-assert 9 + :size-assert #x4c + :flag-assert #x90000004c + ) + + +(define *ropebridge-70-rest-state* (new 'static 'inline-array vector 35 + (new 'static 'vector :x -2361.8552 :y 8191.9688 :z -1.9208 :w -0.1275) + (new 'static 'vector :x -4584.7974 :y 16383.936 :z -3.5561 :w -0.0995) + (new 'static 'vector :x -6668.8125 :y 24575.91 :z -5.0685 :w 0.035) + (new 'static 'vector :x -8613.924 :y 32767.895 :z -6.1218 :w 0.1992) + (new 'static 'vector :x -10420.142 :y 40959.875 :z -6.9367 :w 0.0449) + (new 'static 'vector :x -12087.479 :y 49151.86 :z -8.0159 :w -0.1151) + (new 'static 'vector :x -13615.937 :y 57343.848 :z -9.2313 :w 0.1964) + (new 'static 'vector :x -15005.52 :y 65535.84 :z -9.975 :w 0.1667) + (new 'static 'vector :x -16256.195 :y 73727.84 :z -10.6569 :w -0.1727) + (new 'static 'vector :x -17367.94 :y 81919.84 :z -11.9885 :w 0.271) + (new 'static 'vector :x -18340.738 :y 90111.85 :z -13.5812 :w -0.1759) + (new 'static 'vector :x -19174.588 :y 98303.85 :z -15.0931 :w 0.363) + (new 'static 'vector :x -19869.475 :y 106495.86 :z -16.4569 :w 0.1326) + (new 'static 'vector :x -20425.404 :y 114687.86 :z -17.9534 :w 0.2799) + (new 'static 'vector :x -20842.35 :y 122879.875 :z -18.7552 :w 0.3967) + (new 'static 'vector :x -21120.309 :y 131071.88 :z -19.6815 :w -0.4682) + (new 'static 'vector :x -21259.275 :y 139263.89 :z -20.0082 :w -0.3457) + (new 'static 'vector :x -21259.275 :y 147455.9 :z -19.9398 :w -0.0757) + (new 'static 'vector :x -21120.31 :y 155647.92 :z -19.5994 :w 0.9825) + (new 'static 'vector :x -20842.354 :y 163839.92 :z -18.8809 :w 0.0018) + (new 'static 'vector :x -20425.402 :y 172031.94 :z -17.8884 :w 0.1869) + (new 'static 'vector :x -19869.475 :y 180223.95 :z -16.6081 :w 0.6356) + (new 'static 'vector :x -19174.584 :y 188415.97 :z -15.0626 :w 0.5303) + (new 'static 'vector :x -18340.738 :y 196607.98 :z -13.5152 :w 0.1638) + (new 'static 'vector :x -17367.94 :y 204799.98 :z -11.9936 :w 0.0825) + (new 'static 'vector :x -16256.193 :y 212991.98 :z -10.6949 :w 0.3726) + (new 'static 'vector :x -15005.518 :y 221183.95 :z -9.9551 :w 0.0157) + (new 'static 'vector :x -13615.937 :y 229375.98 :z -9.2192 :w 0.5676) + (new 'static 'vector :x -12087.478 :y 237568.0 :z -7.9867 :w 0.9663) + (new 'static 'vector :x -10420.145 :y 245760.0 :z -6.9835 :w -0.4067) + (new 'static 'vector :x -8613.921 :y 253952.0 :z -6.0589 :w 0.2085) + (new 'static 'vector :x -6668.8105 :y 262144.0 :z -5.0582 :w 0.8373) + (new 'static 'vector :x -4584.7974 :y 270336.0 :z -3.5881 :w 1.1422) + (new 'static 'vector :x -2361.8545 :y 278528.0 :z -1.8908 :w 1.4099) + (new 'static 'vector :y 286720.0) + ) + ) + +(define *ropebridge-52-rest-state* (new 'static 'inline-array vector 26 + (new 'static 'vector :x -1737.1892 :y 8191.979 :z 12.1884 :w 0.1708) + (new 'static 'vector :x -3335.4602 :y 16383.967 :z 25.0793 :w 0.0007) + (new 'static 'vector :x -4794.766 :y 24575.955 :z 37.6373 :w -0.0002) + (new 'static 'vector :x -6115.041 :y 32767.947 :z 50.0327 :w 0.0733) + (new 'static 'vector :x -7296.247 :y 40959.934 :z 59.5924 :w -0.033) + (new 'static 'vector :x -8338.399 :y 49151.93 :z 64.8644 :w -0.0244) + (new 'static 'vector :x -9241.526 :y 57343.938 :z 70.8964 :w 0.072) + (new 'static 'vector :x -10005.708 :y 65535.938 :z 76.9547 :w 0.0023) + (new 'static 'vector :x -10630.993 :y 73727.945 :z 79.8365 :w 0.2395) + (new 'static 'vector :x -11117.421 :y 81919.95 :z 79.5707 :w 0.0572) + (new 'static 'vector :x -11464.953 :y 90111.96 :z 78.7975 :w -0.0422) + (new 'static 'vector :x -11673.532 :y 98303.96 :z 77.7957 :w 0.019) + (new 'static 'vector :x -11743.086 :y 106495.95 :z 77.2108 :w -0.3523) + (new 'static 'vector :x -11673.532 :y 114687.96 :z 77.7399 :w 0.197) + (new 'static 'vector :x -11464.951 :y 122879.97 :z 78.838 :w 0.0763) + (new 'static 'vector :x -11117.423 :y 131071.98 :z 79.5788 :w 0.423) + (new 'static 'vector :x -10630.993 :y 139263.98 :z 79.8296 :w -0.2595) + (new 'static 'vector :x -10005.708 :y 147455.98 :z 76.9285 :w 0.7404) + (new 'static 'vector :x -9241.526 :y 155647.98 :z 70.8901 :w 0.2474) + (new 'static 'vector :x -8338.398 :y 163840.0 :z 64.9246 :w -0.0395) + (new 'static 'vector :x -7296.2456 :y 172032.0 :z 59.556 :w 0.5165) + (new 'static 'vector :x -6115.0415 :y 180224.0 :z 50.0342 :w 0.8282) + (new 'static 'vector :x -4794.7666 :y 188416.0 :z 37.644 :w 0.0407) + (new 'static 'vector :x -3335.4592 :y 196608.0 :z 25.1033 :w -0.258) + (new 'static 'vector :x -1737.1888 :y 204800.02 :z 12.1495 :w 1.1935) + (new 'static 'vector :y 212992.0) + ) + ) + +(define *ropebridge-32-rest-state* (new 'static 'inline-array vector 16 + (new 'static 'vector :x -1041.5476 :y 8191.998 :z -4.4282 :w -0.0321) + (new 'static 'vector :x -1944.2802 :y 16383.992 :z -8.0124 :w 0.0452) + (new 'static 'vector :x -2708.21 :y 24576.0 :z -11.5897 :w 0.311) + (new 'static 'vector :x -3333.2952 :y 32767.992 :z -15.9391 :w -0.1053) + (new 'static 'vector :x -3819.4963 :y 40959.984 :z -19.7012 :w -0.1924) + (new 'static 'vector :x -4166.8076 :y 49152.0 :z -22.6499 :w 0.3457) + (new 'static 'vector :x -4375.184 :y 57343.996 :z -24.2658 :w 0.0078) + (new 'static 'vector :x -4444.632 :y 65536.0 :z -24.3671 :w -0.1826) + (new 'static 'vector :x -4375.184 :y 73728.0 :z -24.2597 :w -0.0109) + (new 'static 'vector :x -4166.8076 :y 81920.0 :z -22.6363 :w 0.4393) + (new 'static 'vector :x -3819.4968 :y 90112.0 :z -19.7122 :w 0.0509) + (new 'static 'vector :x -3333.2952 :y 98304.01 :z -15.9279 :w 0.091) + (new 'static 'vector :x -2708.21 :y 106496.01 :z -11.5961 :w -0.3329) + (new 'static 'vector :x -1944.28 :y 114688.01 :z -8.0186 :w 0.2261) + (new 'static 'vector :x -1041.5474 :y 122880.016 :z -4.4277 :w 0.1558) + (new 'static 'vector :y 131072.0) + ) + ) + +(define *ropebridge-36-rest-state* (new 'static 'inline-array vector 18 + (new 'static 'vector :x -1180.706 :y 8191.9907 :z -0.027 :w -0.0559) + (new 'static 'vector :x -2222.5103 :y 16383.984 :z -0.0441 :w -0.0457) + (new 'static 'vector :x -3125.4124 :y 24575.979 :z -0.047 :w -0.004) + (new 'static 'vector :x -3889.4092 :y 32767.977 :z -0.0962 :w 0.1168) + (new 'static 'vector :x -4514.496 :y 40959.977 :z -0.1679 :w 0.2095) + (new 'static 'vector :x -5000.6753 :y 49151.977 :z -0.3088 :w 0.0938) + (new 'static 'vector :x -5347.9487 :y 57343.98 :z -0.5083 :w -0.0745) + (new 'static 'vector :x -5556.315 :y 65535.98 :z -0.6251 :w 0.2297) + (new 'static 'vector :x -5625.7715 :y 73727.984 :z -0.6877 :w -0.1315) + (new 'static 'vector :x -5556.3154 :y 81919.99 :z -0.6232 :w 0.4198) + (new 'static 'vector :x -5347.948 :y 90111.99 :z -0.5092 :w -0.0617) + (new 'static 'vector :x -5000.675 :y 98303.99 :z -0.2973 :w 0.1242) + (new 'static 'vector :x -4514.4956 :y 106496.0 :z -0.1663 :w 0.1304) + (new 'static 'vector :x -3889.4084 :y 114688.0 :z -0.0908 :w 0.3045) + (new 'static 'vector :x -3125.4133 :y 122880.0 :z -0.0447 :w 0.0666) + (new 'static 'vector :x -2222.5103 :y 131072.0 :z -0.0628 :w 0.4962) + (new 'static 'vector :x -1180.706 :y 139264.0 :z -0.0328 :w 0.6014) + (new 'static 'vector :y 147456.0) + ) + ) + +(define + *ropebridge-tunings* + (new 'static 'inline-array ropebridge-tuning 6 + (new 'static 'ropebridge-tuning + :num-springs 16 + :num-spring-points 17 + :col-mesh-indexes + (new 'static 'array uint8 16 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3) + :view-frustum-radius 81920.0 + :root-prim-radius 81920.0 + :desired-spring-len 4096.0 + :gravity -22.755556 + :spring-coefficient 0.16384 + :spring-mass 0.018 + :friction 0.97 + :max-influence-dist 49152.0 + :rider-max-gravity -56.88889 + :max-bonk-influence-dist 49152.0 + :rider-bonk-force 49152.0 + :rider-bonk-min 8192.0 + :rider-bonk-max 77824.0 + :normal-board-len 8192.0 + :bridge-end-to-end-len 131072.0 + :rest-state '*ropebridge-32-rest-state* + ) + (new 'static 'ropebridge-tuning + :num-springs 18 + :num-spring-points 19 + :col-mesh-indexes + (new 'static 'array uint8 32 + #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 #x3 + #x3 #x3 #x3 #x3 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 + #x0 #x0 #x0 #x0 + ) + :view-frustum-radius 98304.0 + :root-prim-radius 98304.0 + :desired-spring-len 4096.0 + :gravity -22.755556 + :spring-coefficient 0.16384 + :spring-mass 0.018 + :friction 0.97 + :max-influence-dist 49152.0 + :rider-max-gravity -56.88889 + :max-bonk-influence-dist 49152.0 + :rider-bonk-force 49152.0 + :rider-bonk-min 8192.0 + :rider-bonk-max 77824.0 + :normal-board-len 8192.0 + :bridge-end-to-end-len 147456.0 + :rest-state '*ropebridge-36-rest-state* + ) + (new 'static 'ropebridge-tuning + :num-springs 26 + :num-spring-points 27 + :col-mesh-indexes + (new 'static 'array uint8 32 + #x3 #x3 #x3 #x3 #x3 #x1 #x4 #x4 #x2 #x3 #x3 #x3 #x3 + #x3 #x3 #x3 #x3 #x3 #x1 #x4 #x4 #x4 #x2 #x3 #x3 #x3 + #x0 #x0 #x0 #x0 #x0 #x0 + ) + :view-frustum-radius 122880.0 + :root-prim-radius 122880.0 + :desired-spring-len 4096.0 + :gravity -22.755556 + :spring-coefficient 0.16384 + :spring-mass 0.018 + :friction 0.97 + :max-influence-dist 49152.0 + :rider-max-gravity -56.88889 + :max-bonk-influence-dist 49152.0 + :rider-bonk-force 49152.0 + :rider-bonk-min 8192.0 + :rider-bonk-max 77824.0 + :normal-board-len 8192.0 + :bridge-end-to-end-len 212992.0 + :rest-state '*ropebridge-52-rest-state* + ) + (new 'static 'ropebridge-tuning + :num-springs 35 + :num-spring-points 36 + :col-mesh-indexes + (new 'static 'array uint8 48 + #x3 #x3 #x3 #x3 #x3 #x1 #x4 #x4 #x2 #x7 #x4 #x4 #x2 #x3 #x3 + #x1 #x4 #x4 #x4 #x2 #x3 #x3 #x3 #x6 #x4 #x4 #x5 #x3 #x3 #x3 + #x3 #x3 #x3 #x3 #x3 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 + #x0 #x0 #x0 + ) + :view-frustum-radius 163840.0 + :root-prim-radius 163840.0 + :desired-spring-len 4096.0 + :gravity -22.755556 + :spring-coefficient 0.16384 + :spring-mass 0.018 + :friction 0.97 + :max-influence-dist 49152.0 + :rider-max-gravity -56.88889 + :max-bonk-influence-dist 49152.0 + :rider-bonk-force 49152.0 + :rider-bonk-min 8192.0 + :rider-bonk-max 77824.0 + :normal-board-len 8192.0 + :bridge-end-to-end-len 286720.0 + :rest-state '*ropebridge-70-rest-state* + ) + (new 'static 'ropebridge-tuning + :num-springs 18 + :num-spring-points 19 + :col-mesh-indexes + (new 'static 'array uint8 32 + #x3 #x3 #x3 #x3 #x1 #x4 #x4 #x4 #x6 #x3 #x5 #x4 #x4 #x4 + #x2 #x3 #x3 #x3 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 + #x0 #x0 #x0 #x0 + ) + :view-frustum-radius 98304.0 + :root-prim-radius 98304.0 + :desired-spring-len 4096.0 + :gravity -22.755556 + :spring-coefficient 0.16384 + :spring-mass 0.018 + :friction 0.97 + :max-influence-dist 49152.0 + :rider-max-gravity -56.88889 + :max-bonk-influence-dist 49152.0 + :rider-bonk-force 49152.0 + :rider-bonk-min 8192.0 + :rider-bonk-max 77824.0 + :normal-board-len 8192.0 + :bridge-end-to-end-len 147456.0 + :rest-state '*ropebridge-36-rest-state* + ) + (new 'static 'ropebridge-tuning + :num-springs 18 + :num-spring-points 19 + :col-mesh-indexes + (new 'static 'array uint8 32 + #x3 #x3 #x3 #x3 #x1 #x4 #x4 #x2 #x1 #x4 #x4 #x2 #x3 #x1 #x4 + #x4 #x2 #x3 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0 + #x0 #x0 + ) + :view-frustum-radius 98304.0 + :root-prim-radius 98304.0 + :desired-spring-len 4096.0 + :gravity -22.755556 + :spring-coefficient 0.16384 + :spring-mass 0.018 + :friction 0.97 + :max-influence-dist 49152.0 + :rider-max-gravity -56.88889 + :max-bonk-influence-dist 49152.0 + :rider-bonk-force 49152.0 + :rider-bonk-min 8192.0 + :rider-bonk-max 77824.0 + :normal-board-len 8192.0 + :bridge-end-to-end-len 147456.0 + :rest-state '*ropebridge-36-rest-state* + ) + ) + ) + +(deftype ropebridge-spring-point (structure) + ((local-pos vector :inline :offset-assert 0) + (vel vector :inline :offset-assert 16) + (extra-force vector :inline :offset-assert 32) + ) + :pack-me + :method-count-assert 9 + :size-assert #x30 + :flag-assert #x900000030 + ) + + +(deftype ropebridge (process-drawable) + ((root-override collide-shape :offset 112) + (subtype uint64 :offset-assert 176) + (subtype-name string :offset-assert 184) + (agitated-time-stamp uint64 :offset-assert 192) + (bonk-time-stamp uint64 :offset-assert 200) + (attack-flop-time-stamp uint64 :offset-assert 208) + (player-attack-id uint64 :offset-assert 216) + (sleep-dist float :offset-assert 224) + (do-physics? basic :offset-assert 228) + (tuning ropebridge-tuning :offset-assert 232) + (world-matrix matrix :inline :offset-assert 240) + (inv-world-matrix matrix :inline :offset-assert 304) + (extra-trans vector :inline :offset-assert 368) + (spring-point ropebridge-spring-point 36 :inline :offset-assert 384) + ) + :heap-base #x7d0 + :method-count-assert 29 + :size-assert #x840 + :flag-assert #x1d07d00840 + (:methods + (set-vel-from-impact (_type_ uint vector int float) none 20) + (set-vel-from-riders (_type_) none 21) + (set-vel-from-rider (_type_ uint vector int) none 22) + (clear-spring-forces (_type_) none 23) + (debug-draw (_type_) none 24) + (set-to-rest-state (_type_) none 25) + (add-collision-meshes (_type_) none 26) + (do-integration (_type_) none 27) + (dummy-28 (_type_) none 28) + ) + (:states + ropebridge-idle + ) + ) + + +(defskelgroup *ropebridge-32-sg* ropebridge-32 + 0 + 3 + ((1 (meters 20)) (2 (meters 999999))) + :bounds (static-spherem 0 0 0 4) + :longest-edge (meters 4) + ) + +(defskelgroup *snow-bridge-36-sg* snow-bridge-36 + 0 + 3 + ((1 (meters 20)) (2 (meters 999999))) + :bounds (static-spherem 0 0 0 4) + :longest-edge (meters 3.8) + ) + +(defskelgroup *ropebridge-52-sg* ropebridge-52 + 0 + 3 + ((1 (meters 20)) (2 (meters 999999))) + :bounds (static-spherem 0 0 0 4) + :longest-edge (meters 3.6) + ) + +(defskelgroup *ropebridge-70-sg* ropebridge-70 + 0 + 3 + ((1 (meters 20)) (2 (meters 999999))) + :bounds (static-spherem 0 0 0 4) + :longest-edge (meters 3.6) + ) + +(defskelgroup *ropebridge-36-sg* ropebridge-36 + 0 + 3 + ((1 (meters 20)) (2 (meters 999999))) + :bounds (static-spherem 0 0 0 4) + :longest-edge (meters 4) + ) + +(defskelgroup *vil3-bridge-36-sg* vil3-bridge-36 + 0 + 2 + ((1 (meters 999999))) + :bounds (static-spherem 0 0 0 4) + :longest-edge (meters 3.6) + ) + +(defstate ropebridge-idle (ropebridge) + :event + (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) + (let ((f0-0 -1.0)) + (cond + ((= arg2 'bonk) + (when (>= (- (-> *display* base-frame-counter) (the-as int (-> self bonk-time-stamp))) 60) + (set! (-> self bonk-time-stamp) (the-as uint (-> *display* base-frame-counter))) + (set! f0-0 (the-as float (-> arg3 param 1))) + (if (>= f0-0 (-> self tuning rider-bonk-max)) + (set! f0-0 (-> self tuning rider-bonk-max)) + ) + ) + ) + ((and (= arg2 'attack) (= (-> arg3 param 1) 'flop)) + (let ((v1-17 (-> arg3 param 2))) + (when (!= v1-17 (-> self player-attack-id)) + (set! (-> self player-attack-id) v1-17) + (set! (-> self attack-flop-time-stamp) (the-as uint (-> *display* base-frame-counter))) + (set! f0-0 (* 1.1 (-> self tuning rider-bonk-max))) + ) + ) + ) + ) + (the-as + object + (when (and (>= f0-0 (-> self tuning rider-bonk-min)) (-> arg3 param 0)) + (set! (-> self agitated-time-stamp) (the-as uint (-> *display* base-frame-counter))) + (let* ((f30-0 (/ (* (- f0-0 (-> self tuning rider-bonk-min)) (-> self tuning rider-bonk-force)) + (- (-> self tuning rider-bonk-max) (-> self tuning rider-bonk-min)) + ) + ) + (gp-0 (-> arg3 param 0)) + (a0-7 (-> (the-as touching-shapes-entry gp-0) head)) + (s4-0 (-> self root-override)) + (s5-0 (get-touched-prim a0-7 s4-0 (the-as touching-shapes-entry gp-0))) + (v1-33 ((method-of-type touching-shapes-entry get-touched-shape) (the-as touching-shapes-entry gp-0) s4-0)) + (gp-1 (new 'stack-no-clear 'vector)) + ) + (vector-matrix*! gp-1 (-> v1-33 trans) (-> self inv-world-matrix)) + (let ((s5-1 (-> s5-0 prim-id))) + (let ((v1-37 (-> self spring-point s5-1))) + (new 'stack-no-clear 'vector) + (&+ v1-37 48) + ) + (set-vel-from-impact self s5-1 gp-1 -1 f30-0) + (set-vel-from-impact self (+ s5-1 1) gp-1 1 f30-0) + ) + ) + ) + ) + ) + ) + :code + (behavior () + (while #t + (suspend) + (detect-riders! (-> self root-override)) + (when (-> self do-physics?) + (clear-spring-forces self) + (set-vel-from-riders self) + (do-integration self) + ) + ) + (none) + ) + :post + (behavior () + (ja-post) + (let ((gp-0 (-> self root-override))) + (update-transforms! gp-0) + (when (-> self do-physics?) + (pull-riders! gp-0) + (do-push-aways! gp-0) + ) + ) + 0 + (none) + ) + ) + +(defmethod set-vel-from-impact ropebridge ((obj ropebridge) (arg0 uint) (arg1 vector) (arg2 int) (arg3 float)) + (while #t + (let ((f0-2 (fabs (- (-> arg1 z) (-> obj spring-point (the-as int arg0) local-pos z))))) + (if (< (-> obj tuning max-bonk-influence-dist) f0-2) + (return #f) + ) + (let* ((f0-4 (/ (* 8.0 f0-2) (-> obj tuning max-bonk-influence-dist))) + (f0-5 (+ 1.0 f0-4)) + (f0-6 (/ 1.0 f0-5)) + ) + (set! (-> obj spring-point (the-as int arg0) vel y) + (- (-> obj spring-point (the-as int arg0) vel y) (* f0-6 arg3)) + ) + ) + ) + (set! arg0 (+ arg0 arg2)) + (if (or (< (the-as int arg0) 0) (>= (the-as int arg0) (-> obj tuning num-spring-points))) + (return #f) + ) + ) + (none) + ) + +(defmethod clear-spring-forces ropebridge ((obj ropebridge)) + (let ((v1-0 (the-as ropebridge-spring-point (-> obj spring-point)))) + (countdown (a0-2 (-> obj tuning num-spring-points)) + (set! (-> v1-0 extra-force quad) (the-as uint128 0)) + (nop!) + (nop!) + (&+! v1-0 48) + ) + ) + (none) + ) + +(defmethod set-vel-from-riders ropebridge ((obj ropebridge)) + (let ((v1-1 (-> obj root-override riders))) + (when v1-1 + (let ((s5-0 (the-as collide-sticky-rider (-> v1-1 rider)))) + (countdown (s4-0 (-> v1-1 num-riders)) + (let ((v1-3 (handle->process (-> s5-0 rider-handle)))) + (when v1-3 + (let ((v1-5 (-> (the-as process-drawable v1-3) root)) + (s2-0 (-> s5-0 sticky-prim)) + ) + (when s2-0 + (let ((s3-0 (new 'stack-no-clear 'vector))) + (vector-matrix*! s3-0 (-> v1-5 trans) (-> obj inv-world-matrix)) + (let ((s2-1 (-> s2-0 prim-id))) + (set-vel-from-rider obj s2-1 s3-0 -1) + (set-vel-from-rider obj (+ s2-1 1) s3-0 1) + ) + ) + (set! (-> obj agitated-time-stamp) (the-as uint (-> *display* base-frame-counter))) + ) + ) + ) + ) + (&+! s5-0 32) + ) + ) + ) + ) + (none) + ) + +(defmethod set-vel-from-rider ropebridge ((obj ropebridge) (arg0 uint) (arg1 vector) (arg2 int)) + (while #t + (let ((f0-0 (vector-vector-distance arg1 (the-as vector (-> obj spring-point (the-as int arg0)))))) + (if (< (-> obj tuning max-influence-dist) f0-0) + (return #f) + ) + (let* ((f0-2 (/ (* 8.0 f0-0) (-> obj tuning max-influence-dist))) + (f0-3 (+ 1.0 f0-2)) + (f0-4 (/ 1.0 f0-3)) + ) + (+! (-> obj spring-point (the-as int arg0) extra-force y) (* f0-4 (-> obj tuning rider-max-gravity))) + ) + ) + (+! arg0 arg2) + (if (or (< (the-as int arg0) 0) (>= (the-as int arg0) (-> obj tuning num-spring-points))) + (return #f) + ) + ) + (none) + ) + +(defmethod do-integration ropebridge ((obj ropebridge)) + (local-vars (a2-1 float) (a3-0 float)) + (rlet ((Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf10 :class vf) + (vf11 :class vf) + (vf12 :class vf) + (vf13 :class vf) + (vf14 :class vf) + (vf15 :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) + (let ((v1-1 (-> obj tuning gravity))) + (.mov vf9 v1-1) + ) + (.add.x.vf vf9 vf0 vf9 :mask #b10) + (.mov.vf vf9 vf0 :mask #b1101) + 0 + (let ((v1-4 (-> obj tuning friction))) + (.mov vf12 v1-4) + ) + (.add.x.vf vf12 vf0 vf12 :mask #b10) + (.add.x.vf vf12 vf0 vf12 :mask #b100) + 0 + (let ((v1-7 (/ 1.0 (-> obj tuning spring-mass)))) + (.mov vf14 v1-7) + ) + (.add.x.vf vf14 vf0 vf14 :mask #b10) + (.add.x.vf vf14 vf0 vf14 :mask #b100) + 0 + (let ((v1-11 (+ (-> obj tuning num-spring-points) -2))) + (let* ((a2-0 (-> obj spring-point)) + (a1-1 (-> a2-0 1)) + ) + (.lvf vf2 (&-> a2-0 0 local-pos quad)) + (label cfg-1) + (.lvf vf1 (&-> a1-1 extra-force quad)) + (.lvf vf3 (&-> a1-1 local-pos quad)) + (.add.vf vf1 vf1 vf9 :mask #b111) + (.sub.vf vf5 vf2 vf3) + (.mul.vf vf7 vf5 vf5 :mask #b111) + (.add.y.vf vf7 vf7 vf7 :mask #b1) + (.add.z.vf vf7 vf7 vf7 :mask #b1) + (.mov a2-1 vf7) + (let ((f0-5 (- a2-1 (-> obj tuning desired-spring-len)))) + (when (< 0.0 f0-5) + (.div.vf Q vf0 vf7 :fsf #b11 :ftf #b0) + (.wait.vf) + (.mul.vf vf5 vf5 Q) + (let ((a2-5 (* f0-5 (-> obj tuning spring-coefficient)))) + (.mov vf10 a2-5) + ) + (.mul.x.vf vf10 vf5 vf10 :mask #b111) + (.add.vf vf1 vf1 vf10 :mask #b111) + 0 + ) + ) + (let ((a2-8 (&+ a1-1 48))) + (.lvf vf4 (&-> a2-8 local-pos quad)) + (.sub.vf vf6 vf4 vf3) + (.mul.vf vf8 vf6 vf6 :mask #b111) + (.add.y.vf vf8 vf8 vf8 :mask #b1) + (.add.z.vf vf8 vf8 vf8 :mask #b1) + (.mov a3-0 vf8) + (let ((f0-8 (- a3-0 (-> obj tuning desired-spring-len)))) + (when (< 0.0 f0-8) + (.div.vf Q vf0 vf8 :fsf #b11 :ftf #b0) + (.wait.vf) + (.mul.vf vf6 vf6 Q) + (let ((a3-4 (* f0-8 (-> obj tuning spring-coefficient)))) + (.mov vf10 a3-4) + ) + (.mul.x.vf vf10 vf6 vf10 :mask #b111) + (.add.vf vf1 vf1 vf10 :mask #b111) + 0 + ) + ) + (.mul.vf vf15 vf1 vf14 :mask #b111) + (.lvf vf11 (&-> a1-1 vel quad)) + (.add.vf vf11 vf11 vf15 :mask #b111) + (.mul.vf vf11 vf11 vf12 :mask #b111) + (.svf (&-> a1-1 vel quad) vf11) + (set! a1-1 a2-8) + ) + ) + (.mov.vf vf2 vf3) + (.mov.vf vf3 vf4) + (+! v1-11 -1) + (b! (> v1-11 0) cfg-1 :delay (nop!)) + ) + (let ((v1-13 (-> *display* seconds-per-frame))) + (.mov vf13 v1-13) + ) + (.add.x.vf vf13 vf0 vf13 :mask #b10) + (.add.x.vf vf13 vf0 vf13 :mask #b100) + 0 + (let ((v1-17 (+ (-> obj tuning num-spring-points) -2))) + (let ((a0-1 (&-> obj stack 320))) + (label cfg-7) + (.lvf vf11 (&+ a0-1 16)) + (.lvf vf3 a0-1) + (.mul.vf vf11 vf11 vf13 :mask #b111) + (.add.vf vf3 vf3 vf11 :mask #b111) + (.svf (the-as (pointer uint128) (&-> a0-1 0)) vf3) + (set! a0-1 (&-> a0-1 48)) + ) + (+! v1-17 -1) + (b! (> v1-17 0) cfg-7 :delay (nop!)) + ) + 0 + (none) + ) + ) + +(defmethod debug-draw ropebridge ((obj ropebridge)) + (let ((gp-0 (-> obj node-list data 0 bone transform)) + (s5-0 (the-as ropebridge-spring-point (-> obj spring-point))) + (s4-0 (new 'stack-no-clear 'vector)) + ) + (countdown (s3-0 (-> obj tuning num-spring-points)) + (vector-matrix*! s4-0 (-> s5-0 local-pos) gp-0) + (add-debug-sphere #t (bucket-id debug-draw0) s4-0 2048.0 (new 'static 'rgba :r #xff :g #xff :b #xff :a #x40)) + (&+! s5-0 48) + ) + ) + (none) + ) + +(defmethod set-to-rest-state ropebridge ((obj ropebridge)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (init-vf0-vector) + (let ((a1-0 (the-as structure (-> obj tuning rest-state)))) + (cond + ((the-as symbol a1-0) + (let ((v1-1 (the-as ropebridge-spring-point (-> obj spring-point))) + (a1-1 (the-as vector (-> (the-as vector a1-0) x))) + ) + (.svf (&-> v1-1 local-pos quad) vf0) + (.svf (&-> v1-1 vel quad) vf0) + (countdown (a0-3 (+ (-> obj tuning num-spring-points) -1)) + (&+! v1-1 48) + (.svf (&-> v1-1 local-pos quad) vf0) + (.svf (&-> v1-1 vel quad) vf0) + (set! (-> v1-1 local-pos y) (-> a1-1 x)) + (set! (-> v1-1 local-pos z) (-> a1-1 y)) + (set! (-> v1-1 vel y) (-> a1-1 z)) + (set! (-> v1-1 vel z) (-> a1-1 w)) + (&+! a1-1 16) + ) + ) + ) + (else + (let ((a1-2 8192.0)) + (.mov.vf vf1 vf0) + (let ((v1-3 (the-as ropebridge-spring-point (-> obj spring-point)))) + (.mov vf2 a1-2) + (.add.x.vf vf2 vf0 vf2) + (.mov.vf vf2 vf0 :mask #b1011) + (countdown (a0-5 (-> obj tuning num-spring-points)) + (.svf (&-> v1-3 local-pos quad) vf1) + (.svf (&-> v1-3 vel quad) vf0) + (.add.vf vf1 vf1 vf2 :mask #b111) + (&+! v1-3 48) + ) + ) + ) + ) + ) + ) + (none) + ) + ) + +(defun ropebridge-joint-callback ((arg0 ropebridge)) + (let ((s5-0 (-> arg0 node-list data 3 bone transform))) + (matrix-identity! s5-0) + (set-vector! (-> s5-0 vector 3) 0.0 0.0 (- (-> arg0 tuning normal-board-len)) 1.0) + ) + (let* ((s5-1 (-> arg0 spring-point)) + (s3-0 (the-as object s5-1)) + (s4-0 0) + ) + (while (< s4-0 (-> arg0 tuning num-springs)) + (set! s3-0 (&+ (the-as ropebridge-spring-point s3-0) 48)) + (let ((v1-4 (new 'stack-no-clear 'vector))) + (vector-! v1-4 (-> (the-as ropebridge-spring-point s3-0) local-pos) (the-as vector (-> s5-1 0))) + (let ((f0-8 (- (atan (-> v1-4 y) (-> v1-4 z)))) + (s2-0 (-> arg0 node-list data (+ s4-0 4) bone transform)) + ) + (matrix-rotate-x! s2-0 f0-8) + (set! (-> s2-0 vector 3 quad) (-> s5-1 0 local-pos quad)) + ) + ) + (set! s5-1 (the-as (inline-array ropebridge-spring-point) (the-as ropebridge-spring-point s3-0))) + (+! s4-0 1) + ) + (let ((s4-1 (-> arg0 node-list data (+ s4-0 4) bone transform))) + (matrix-identity! s4-1) + (set! (-> s4-1 vector 3 quad) (-> s5-1 0 local-pos quad)) + ) + ) + (dotimes (s5-2 (+ (-> arg0 tuning num-springs) 2)) + (let ((a1-3 (-> arg0 node-list data (+ s5-2 3) bone transform))) + (matrix*! a1-3 a1-3 (-> arg0 world-matrix)) + ) + ) + 0 + (none) + ) + +(defmethod add-collision-meshes ropebridge ((obj ropebridge)) + (let* ((s5-0 (-> obj root-override)) + (s3-0 (-> obj tuning)) + (s4-0 (new 'process 'collide-shape-prim-group s5-0 (the-as uint (-> s3-0 num-springs)) 0)) + ) + (set! (-> s4-0 prim-core collide-as) (collide-kind ground-object)) + (set! (-> s4-0 collide-with) (collide-kind target)) + (set-vector! (-> s4-0 local-sphere) 0.0 0.0 0.0 (-> s3-0 root-prim-radius)) + (set! (-> s4-0 transform-index) (+ (/ (-> s3-0 num-springs) 2) 4)) + (set! (-> s4-0 prim-core action) (collide-action solid ca-1)) + (set-root-prim! s5-0 s4-0) + (let ((s3-1 (-> obj tuning col-mesh-indexes))) + (dotimes (s2-0 (-> obj tuning num-springs)) + (let* ((a3-1 (-> s3-1 s2-0)) + (a1-3 (new 'process 'collide-shape-prim-mesh s5-0 a3-1 (the-as uint s2-0))) + ) + (set! (-> a1-3 prim-core action) (collide-action solid ca-1)) + (set! (-> a1-3 prim-core collide-as) (collide-kind ground-object)) + (set! (-> a1-3 collide-with) (collide-kind target)) + (set! (-> a1-3 prim-core offense) (collide-offense indestructible)) + (set-vector! (-> a1-3 local-sphere) 0.0 6144.0 4096.0 18022.4) + (set! (-> a1-3 transform-index) (+ s2-0 4)) + (append-prim s4-0 a1-3) + ) + ) + ) + ) + (none) + ) + +(defmethod run-logic? ropebridge ((obj ropebridge)) + (or (zero? (logand (-> obj mask) (process-mask actor-pause))) + (< (- (-> *display* base-frame-counter) (the-as int (-> obj agitated-time-stamp))) 1500) + (or (>= (-> obj sleep-dist) (vector-vector-distance (-> obj root-override trans) (math-camera-pos))) + (and (nonzero? (-> obj skel)) (!= (-> obj skel root-channel 0) (-> obj skel channel))) + (and (nonzero? (-> obj draw)) (logtest? (-> obj draw status) (draw-status drwf04))) + ) + ) + ) + +(defmethod dummy-28 ropebridge ((obj ropebridge)) + 0 + (none) + ) + +(defmethod init-from-entity! ropebridge ((obj ropebridge) (arg0 entity-actor)) + (let ((s4-0 (res-lump-struct (-> obj entity) 'art-name structure))) + (if (not s4-0) + (set! s4-0 "ropebridge-32") + ) + (if (= (-> (the-as symbol s4-0) type) symbol) + (set! s4-0 (symbol->string (the-as symbol s4-0))) + ) + (set! (-> obj subtype-name) (the-as string s4-0)) + (set! (-> obj subtype) (the-as uint (cond + ((string= (the-as string s4-0) "ropebridge-32") + 0 + ) + ((string= (the-as string s4-0) "ropebridge-36") + 1 + ) + ((string= (the-as string s4-0) "ropebridge-52") + 2 + ) + ((string= (the-as string s4-0) "ropebridge-70") + 3 + ) + ((string= (the-as string s4-0) "snow-bridge-36") + 4 + ) + ((string= (the-as string s4-0) "vil3-bridge-36") + 5 + ) + (else + 0 + ) + ) + ) + ) + ) + (set! (-> obj tuning) (-> *ropebridge-tunings* (the-as int (-> obj subtype)))) + (set! (-> obj agitated-time-stamp) (the-as uint (-> *display* base-frame-counter))) + (set! (-> obj bonk-time-stamp) (the-as uint (-> *display* base-frame-counter))) + (set! (-> obj attack-flop-time-stamp) (the-as uint (-> *display* base-frame-counter))) + (set-vector! (-> obj extra-trans) 0.0 0.0 (- (* 0.5 (-> obj tuning bridge-end-to-end-len))) 1.0) + (set! (-> obj do-physics?) #t) + (let ((a0-13 (new 'process 'collide-shape obj (collide-list-enum hit-by-player)))) + (set! (-> obj root-override) a0-13) + (alloc-riders a0-13 3) + ) + (add-collision-meshes obj) + (process-drawable-from-entity! obj arg0) + (initialize-skeleton-by-name obj (-> obj subtype-name) '()) + (logior! (-> obj skel status) 1) + (let ((v1-29 (-> obj tuning))) + (set! (-> obj draw bounds w) (-> v1-29 view-frustum-radius)) + (set! (-> obj sleep-dist) (+ 40960.0 (* 0.5 (-> v1-29 bridge-end-to-end-len)))) + (if (or (< 35 (-> v1-29 num-springs)) (< 36 (-> v1-29 num-spring-points))) + (format 0 "ERROR: ##########~%Exceeded max # of springs in ropebridge! Stomping memory!~%##########~%") + ) + ) + (set! (-> obj skel postbind-function) ropebridge-joint-callback) + (matrix<-transformq+trans! + (-> obj world-matrix) + (the-as transformq (-> obj root-override trans)) + (-> obj extra-trans) + ) + (matrix-4x4-inverse! (-> obj inv-world-matrix) (-> obj world-matrix)) + (set-to-rest-state obj) + (go ropebridge-idle) + (none) + ) + + + + diff --git a/goalc/compiler/compilation/Static.cpp b/goalc/compiler/compilation/Static.cpp index fb714717cb..ac350b16ee 100644 --- a/goalc/compiler/compilation/Static.cpp +++ b/goalc/compiler/compilation/Static.cpp @@ -241,18 +241,27 @@ void Compiler::compile_static_structure_inline(const goos::Object& form, sr.reference()->get_addr_offset()); } else if (field_info.type.base_type() == "pointer") { auto sr = compile_static(field_value, env); - if (!sr.is_symbol() || sr.symbol_name() != "#f") { - throw_compiler_error(form, "Invalid definition of field {}", field_info.field.name()); + if (sr.is_symbol() && sr.symbol_name() == "#f") { + // allow #f to be used for a pointer. + structure->add_symbol_record(sr.symbol_name(), field_offset); + auto deref_info = m_ts.get_deref_info(m_ts.make_pointer_typespec(field_info.type)); + assert(deref_info.mem_deref); + assert(deref_info.can_deref); + assert(deref_info.load_size == 4); + // the linker needs to see a -1 in order to know to insert a symbol pointer + // instead of just the symbol table offset. + u32 linker_val = 0xffffffff; + memcpy(structure->data.data() + field_offset, &linker_val, 4); + } else { + if (!sr.is_reference()) { + throw_compiler_error(form, "Invalid definition of field {}", field_info.field.name()); + } + typecheck(form, field_info.type, sr.typespec()); + assert(sr.reference()->get_addr_offset() == 0); + structure->add_pointer_record(field_offset, sr.reference(), + sr.reference()->get_addr_offset()); } - structure->add_symbol_record(sr.symbol_name(), field_offset); - auto deref_info = m_ts.get_deref_info(m_ts.make_pointer_typespec(field_info.type)); - assert(deref_info.mem_deref); - assert(deref_info.can_deref); - assert(deref_info.load_size == 4); - // the linker needs to see a -1 in order to know to insert a symbol pointer - // instead of just the symbol table offset. - u32 linker_val = 0xffffffff; - memcpy(structure->data.data() + field_offset, &linker_val, 4); + } else { @@ -859,7 +868,7 @@ StaticResult Compiler::fill_static_array(const goos::Object& form, // get all arguments now auto args = get_list_as_vector(rest); if (args.size() < 4) { - throw_compiler_error(form, "new static boxed array must have type and min-size arguments"); + throw_compiler_error(form, "new static array must have type and min-size arguments"); } auto content_type = parse_typespec(args.at(2)); s64 min_size; diff --git a/test/decompiler/reference/engine/collide/collide-cache-h_REF.gc b/test/decompiler/reference/engine/collide/collide-cache-h_REF.gc index 901f88f257..fb6f9858c7 100644 --- a/test/decompiler/reference/engine/collide/collide-cache-h_REF.gc +++ b/test/decompiler/reference/engine/collide/collide-cache-h_REF.gc @@ -3,12 +3,12 @@ ;; definition of type collide-using-spheres-params (deftype collide-using-spheres-params (structure) - ((spheres (pointer sphere) :offset-assert 0) - (num-spheres uint32 :offset-assert 4) - (collide-with collide-kind :offset-assert 8) - (proc process-drawable :offset-assert 16) - (ignore-pat uint32 :offset-assert 20) - (solid-only basic :offset-assert 24) + ((spheres (inline-array sphere) :offset-assert 0) + (num-spheres uint32 :offset-assert 4) + (collide-with collide-kind :offset-assert 8) + (proc process-drawable :offset-assert 16) + (ignore-pat uint32 :offset-assert 20) + (solid-only basic :offset-assert 24) ) :method-count-assert 9 :size-assert #x1c diff --git a/test/decompiler/reference/engine/draw/drawable_REF.gc b/test/decompiler/reference/engine/draw/drawable_REF.gc index 0362ac1ddb..61e31b2b7f 100644 --- a/test/decompiler/reference/engine/draw/drawable_REF.gc +++ b/test/decompiler/reference/engine/draw/drawable_REF.gc @@ -876,292 +876,82 @@ ) ;; definition for function foreground-engine-execute -;; WARN: Type Propagation failed: Failed type prop at op 114 ((set! a0 (l.wu (+ v1 276)))): Could not get type of load: (set! a0 (l.wu (+ v1 276))). -;; WARN: Type Propagation failed: Type analysis failed +;; INFO: Return type mismatch int vs none. ;; WARN: Unsupported inline assembly instruction kind - [sync.l] ;; WARN: Unsupported inline assembly instruction kind - [cache dxwbin v1, 0] ;; WARN: Unsupported inline assembly instruction kind - [sync.l] ;; WARN: Unsupported inline assembly instruction kind - [cache dxwbin v1, 1] ;; WARN: Unsupported inline assembly instruction kind - [sync.l] -(defun foreground-engine-execute ((a0-0 engine) (a1-0 display-frame) (a2-0 int) (a3-0 int)) - (local-vars - (v0-0 profile-frame) - (v0-1 none) - (v0-2 int) - (v0-3 none) - (v0-4 profile-frame) - (v0-5 none) - (v0-6 none) - (v1-0 display) - (v1-1 int) - (v1-2 display-frame) - (v1-3 dma-buffer) - (v1-4 symbol) - (v1-6 display) - (v1-7 int) - (v1-8 display-frame) - (v1-9 type) - (v1-11 int) - (v1-12 int) - (v1-13 int) - (v1-14 pointer) - (v1-15 int) - (v1-16 type) - (v1-19 symbol) - (v1-20 display) - (v1-21 int) - (v1-22 display-frame) - (v1-23 type) - (v1-24 memory-usage-block) - (v1-25 vu1-renderer-mask) - (v1-26 vu1-renderer-mask) - (v1-28 merc-globals) - (v1-29 uint) - (v1-31 display) - (v1-32 int) - (v1-33 display-frame) - (v1-34 dma-buffer) - (v1-35 level-group) - (v1-36 int) - (v1-37 int) - (v1-39 none) - (v1-41 none) - (a0-1 display) - (a0-2 int) - (a0-3 int) - (a0-4 display) - (a0-5 int) - (a0-6 int) - (a0-7 profile-bar) - (a0-8 int) - (a0-9 int) - (a0-10 level-group) - (a0-11 dma-buffer) - (a0-12 engine) - (a0-14 display) - (a0-15 int) - (a0-16 int) - (a0-17 profile-bar) - (a0-19 display) - (a0-20 int) - (a0-21 int) - (a0-22 int) - (a0-23 int) - (a0-24 int) - (a0-25 none) - (a0-26 none) - (a0-27 none) - (a0-28 none) - (a1-1 symbol) - (a1-2 int) - (a1-3 dma-buffer) - (a1-4 symbol) - (a1-6 int) - (a1-7 int) - (a1-8 string) - (a1-9 int) - (a1-10 int) - (a1-11 int) - (a1-12 int) - (a1-13 int) - (a1-15 none) - (a1-16 none) - (a1-17 none) - (a1-18 none) - (a1-19 none) - (a1-20 none) - (a1-21 none) - (a1-22 none) - (a2-1 uint) - (a2-2 uint) - (a2-3 int) - (a2-4 display) - (a2-5 int) - (a2-6 display-frame) - (a2-7 dma-buffer) - (a2-8 pointer) - (a2-9 int) - (a2-10 none) - (a2-11 none) - (a2-12 none) - (a2-13 none) - (a2-14 none) - (a2-15 none) - (a2-16 none) - (a3-1 display) - (a3-2 int) - (a3-3 int) - (a3-4 none) - (a3-5 none) - (a3-6 none) - (s2-1 dma-buffer) - (s4-0 pointer) - (s4-1 pointer) - (t9-0 (function profile-bar symbol rgba profile-frame)) - (t9-1 (function dma-buffer dma-foreground-sink-group none)) - (t9-2 (function engine object int)) - (t9-3 (function none)) - (t9-4 (function profile-bar symbol rgba profile-frame)) - (t9-5 none) - ) - (when (begin - (when (begin - (when (begin - (set! v1-0 *display*) - (set! a0-1 *display*) - (set! a0-2 (-> a0-1 on-screen)) - (set! a0-3 (sll a0-2 5)) - (set! v1-1 (+ v1-0 a0-3)) - (set! v1-2 (dynamic-array-field-access v1-1 frames PLACEHOLDER frame)) - (set! v1-3 (-> v1-2 global-buf)) - (set! s4-0 (-> v1-3 base)) - (set! v1-4 *debug-segment*) - v1-4 - ) - (set! v1-6 *display*) - (set! a0-4 *display*) - (set! a0-5 (-> a0-4 on-screen)) - (set! a0-6 (sll a0-5 5)) - (set! v1-7 (+ v1-6 a0-6)) - (set! v1-8 (dynamic-array-field-access v1-7 frames PLACEHOLDER frame)) - (set! a0-7 (-> v1-8 profile-bar 0)) - (set! v1-9 (-> a0-7 type)) - (set! t9-0 (method-of-type v1-9 add-frame)) - (set! a1-1 'draw) - (set! a2-1 (the-as uint #x80400040)) - (call! a0-7 a1-1 a2-1) - (set! v1-10 v0-0) - ) - (set! v1-11 (sll a3-0 5)) - (set! v1-12 (+ v1-11 272)) - (set! a0-8 2608) - (set! a0-9 (*.si a0-8 a2-0)) - (set! v1-13 (+ v1-12 a0-9)) - (set! a0-10 *level*) - (set! a1-2 (+ v1-13 a0-10)) - (set! s2-1 (-> a1-0 global-buf)) - (set! v1-14 (-> s2-1 base)) - (.sync.l) - (.cache dxwbin v1-14 0) - (.sync.l) - (.cache dxwbin v1-14 1) - (.sync.l) - (set! v1-15 0) - (set! t9-1 bones-init) - (set! a0-11 s2-1) - (call! a0-11 a1-2) - (set! v1-16 (-> a0-0 type)) - (set! t9-2 (method-of-type v1-16 execute-connections)) - (set! a0-12 a0-0) - (set! a1-3 s2-1) - (call! a0-12 a1-3) - (set! v1-17 v0-2) - (set! t9-3 bones-wrapup) - (call!) - (set! v1-18 v0-3) - (set! v1-19 *debug-segment*) - v1-19 - ) - (set! v1-20 *display*) - (set! a0-14 *display*) - (set! a0-15 (-> a0-14 on-screen)) - (set! a0-16 (sll a0-15 5)) - (set! v1-21 (+ v1-20 a0-16)) - (set! v1-22 (dynamic-array-field-access v1-21 frames PLACEHOLDER frame)) - (set! a0-17 (-> v1-22 profile-bar 0)) - (set! v1-23 (-> a0-17 type)) - (set! t9-4 (method-of-type v1-23 add-frame)) - (set! a1-4 'draw) - (set! a2-2 (the-as uint #x808255be)) - (call! a0-17 a1-4 a2-2) - (set! a0-18 v0-4) - ) - (when (begin (set! v1-24 *dma-mem-usage*) (nonzero? v1-24)) - (set! a1-6 36) - (set! a2-3 (-> v1-24 length)) - (set! a1-7 (max.si a1-6 a2-3)) - (set! (-> v1-24 length) a1-7) - (set! a1-8 L171) - (set! (-> v1-24 data 35 name) a1-8) - (set! a1-9 (-> v1-24 data 35 count)) - (set! a1-10 (+ a1-9 1)) - (set! (-> v1-24 data 35 count) a1-10) - (set! a1-11 (-> v1-24 data 35 used)) - (set! a2-4 *display*) - (set! a3-1 *display*) - (set! a3-2 (-> a3-1 on-screen)) - (set! a3-3 (sll a3-2 5)) - (set! a2-5 (+ a2-4 a3-3)) - (set! a2-6 (dynamic-array-field-access a2-5 frames PLACEHOLDER frame)) - (set! a2-7 (-> a2-6 global-buf)) - (set! a2-8 (-> a2-7 base)) - (set! a2-9 (- a2-8 s4-0)) - (set! a1-12 (+ a1-11 a2-9)) - (set! (-> v1-24 data 35 used) a1-12) - (set! a1-13 (-> v1-24 data 35 used)) - (set! (-> v1-24 data 35 total) a1-13) - ) - (set! v1-25 *vu1-enable-user*) - (set! v1-26 (logand v1-25 512)) - (nonzero? v1-26) +(defun foreground-engine-execute ((arg0 engine) (arg1 display-frame) (arg2 int) (arg3 int)) + (let ((s4-0 (-> *display* frames (-> *display* on-screen) frame global-buf base))) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x40 :b #x40 :a #x80) ) - (when (begin (set! v1-28 *merc-globals*) (set! v1-29 (-> v1-28 first)) (nonzero? v1-29)) - (when (begin - (set! v1-31 *display*) - (set! a0-19 *display*) - (set! a0-20 (-> a0-19 on-screen)) - (set! a0-21 (sll a0-20 5)) - (set! v1-32 (+ v1-31 a0-21)) - (set! v1-33 (dynamic-array-field-access v1-32 frames PLACEHOLDER frame)) - (set! v1-34 (-> v1-33 global-buf)) - (set! s4-1 (-> v1-34 base)) - (set! v1-35 *level*) - (set! a0-22 2608) - (set! a0-23 (*.si a0-22 a2-0)) - (set! v1-36 (+ v1-35 a0-23)) - (set! a0-24 (sll a3-0 5)) - (set! v1-37 (+ v1-36 a0-24)) - (set! a0-25 (the-as none (l.wu (+ v1-37 276)))) - (set! t9-5 (the-as none generic-merc-add-to-cue)) - (call!) - (set! v1-38 (the-as none v0-5)) - (set! a0-26 (the-as none *dma-mem-usage*)) - (nonzero? a0-26) - ) - (set! a1-15 (the-as none 87)) - (set! a2-10 (the-as none (l.w (+ a0-26 4)))) - (set! a1-16 (the-as none (max.si a1-15 a2-10))) - (s.w! (+ a0-26 4) a1-16) - (set! a1-17 (the-as none L170)) - (s.w! (+ a0-26 1388) a1-17) - (set! a1-18 (the-as none (l.w (+ a0-26 1392)))) - (set! a1-19 (the-as none (+ a1-18 1))) - (s.w! (+ a0-26 1392) a1-19) - (set! a1-20 (the-as none (l.w (+ a0-26 1396)))) - (set! a2-11 (the-as none *display*)) - (set! a3-4 (the-as none *display*)) - (set! a3-5 (the-as none (l.w (+ a3-4 556)))) - (set! a3-6 (the-as none (sll a3-5 5))) - (set! a2-12 (the-as none (+ a2-11 a3-6))) - (set! a2-13 (the-as none (l.wu (+ a2-12 580)))) - (set! a2-14 (the-as none (l.wu (+ a2-13 36)))) - (set! a2-15 (the-as none (l.wu (+ a2-14 4)))) - (set! a2-16 (the-as none (- a2-15 s4-1))) - (set! a1-21 (the-as none (+ a1-20 a2-16))) - (s.w! (+ a0-26 1396) a1-21) - (set! a1-22 (the-as none (l.w (+ a0-26 1396)))) - (s.w! (+ a0-26 1400) a1-22) + ) + (let ((a1-2 (+ (+ (* arg3 32) 272 (* 2608 arg2)) (the-as int *level*))) + (s2-1 (-> arg1 global-buf)) + ) + (let ((v1-14 (-> s2-1 base))) + (.sync.l) + (.cache dxwbin v1-14 0) + (.sync.l) + (.cache dxwbin v1-14 1) + ) + (.sync.l) + 0 + (bones-init s2-1 (the-as dma-foreground-sink-group a1-2)) + (execute-connections arg0 s2-1) + ) + (bones-wrapup) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #xbe :g #x55 :b #x82 :a #x80) + ) + ) + (let ((v1-24 *dma-mem-usage*)) + (when (nonzero? v1-24) + (set! (-> v1-24 length) (max 36 (-> v1-24 length))) + (set! (-> v1-24 data 35 name) "pris-fragment") + (+! (-> v1-24 data 35 count) 1) + (+! (-> v1-24 data 35 used) + (&- (-> *display* frames (-> *display* on-screen) frame global-buf base) (the-as uint s4-0)) + ) + (set! (-> v1-24 data 35 total) (-> v1-24 data 35 used)) ) ) ) - (when (begin (set! v1-39 (the-as none #t)) v1-39) - (set! v1-41 (the-as none *shadow-queue*)) - (set! a0-27 (the-as none (l.wu (+ v1-41 4)))) - (set! a0-28 (the-as none (+ a0-27 1))) - (s.w! (+ v1-41 4) a0-28) + (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic)) + (when (nonzero? (-> *merc-globals* first)) + (let ((s4-1 (-> *display* frames (-> *display* on-screen) frame global-buf base))) + (let ((a0-25 (-> (the-as (pointer uint32) (+ (the-as uint *level*) (* 2608 arg2) (* arg3 32))) 69))) + (generic-merc-add-to-cue a0-25) + ) + (let ((a0-26 *dma-mem-usage*)) + (when (nonzero? a0-26) + (set! (-> a0-26 length) (max 87 (-> a0-26 length))) + (set! (-> a0-26 data 86 name) "pris-generic") + (+! (-> a0-26 data 86 count) 1) + (+! (-> a0-26 data 86 used) + (&- (-> *display* frames (-> *display* on-screen) frame global-buf base) (the-as uint s4-1)) + ) + (set! (-> a0-26 data 86 total) (-> a0-26 data 86 used)) + ) + ) + ) + ) ) - (set! v0-6 (the-as none 0)) - (ret-none) + (when #t + (let ((v1-41 *shadow-queue*)) + (+! (-> v1-41 cur-run) 1) + ) + ) + 0 + (none) ) ;; definition (debug) for function main-debug-hook diff --git a/test/decompiler/reference/engine/draw/process-drawable_REF.gc b/test/decompiler/reference/engine/draw/process-drawable_REF.gc index 7fd41f67f8..6c2d2ef62c 100644 --- a/test/decompiler/reference/engine/draw/process-drawable_REF.gc +++ b/test/decompiler/reference/engine/draw/process-drawable_REF.gc @@ -272,7 +272,7 @@ (countdown (s5-0 (-> gp-0 length)) (let ((a0-1 (handle->process (-> gp-0 s5-0)))) (if a0-1 - (dummy-17 (the-as process-drawable a0-1)) + (do-joint-math! (the-as process-drawable a0-1)) ) ) ) @@ -285,7 +285,7 @@ ;; definition for method 17 of type process-drawable ;; INFO: Return type mismatch int vs none. ;; Used lq/sq -(defmethod dummy-17 process-drawable ((obj process-drawable)) +(defmethod do-joint-math! process-drawable ((obj process-drawable)) (cond ((logtest? (-> obj draw status) (draw-status drwf01 drwf02)) ) @@ -601,7 +601,7 @@ ) ;; definition for method 15 of type process-drawable -(defmethod dummy-15 process-drawable ((obj process-drawable) (arg0 string) (arg1 object)) +(defmethod initialize-skeleton-by-name process-drawable ((obj process-drawable) (arg0 string) (arg1 object)) (let ((s3-0 string->symbol)) (format (clear *temp-string*) "*~S-sg*" arg0) (let ((s3-1 (-> (s3-0 *temp-string*) value))) @@ -999,7 +999,7 @@ (when (nonzero? (-> self skel)) (dummy-19 self) (when (or (logtest? (-> self skel status) 1) gp-1) - (dummy-17 self) + (do-joint-math! self) (if (and gp-1 (type-type? (-> self root type) collide-shape)) (update-transforms! (the-as collide-shape (-> self root))) ) diff --git a/test/decompiler/reference/engine/game/game-h_REF.gc b/test/decompiler/reference/engine/game/game-h_REF.gc index 6cf5764dd1..a68828ea5b 100644 --- a/test/decompiler/reference/engine/game/game-h_REF.gc +++ b/test/decompiler/reference/engine/game/game-h_REF.gc @@ -25,9 +25,9 @@ :flag-assert #x14004000b0 (:methods (initialize-skeleton (_type_ skeleton-group pair) none 14) - (dummy-15 (_type_ string object) _type_ 15) + (initialize-skeleton-by-name (_type_ string object) _type_ 15) (dummy-16 (_type_ int (inline-array vector) vector) collide-shape 16) - (dummy-17 (_type_) none 17) + (do-joint-math! (_type_) none 17) (dummy-18 (_type_) none 18) (dummy-19 (_type_) none 19) ) diff --git a/test/decompiler/reference/engine/game/generic-obs_REF.gc b/test/decompiler/reference/engine/game/generic-obs_REF.gc index 1b126eb910..cc8dff91aa 100644 --- a/test/decompiler/reference/engine/game/generic-obs_REF.gc +++ b/test/decompiler/reference/engine/game/generic-obs_REF.gc @@ -51,7 +51,7 @@ (logior! (-> self draw status) (draw-status drwf02)) ) ) - (dummy-17 self) + (do-joint-math! self) (let ((a0-22 (-> self skel effect))) (if a0-22 (TODO-RENAME-9 a0-22) @@ -554,7 +554,7 @@ "" ) ) - (dummy-17 self) + (do-joint-math! self) ) (('clone-anim) (clone-anim-once @@ -836,35 +836,37 @@ ) ;; definition for function command-get-camera +;; INFO: Return type mismatch object vs state. (defun command-get-camera ((arg0 object) (arg1 state)) - (cond - ((null? arg0) - (empty) - arg1 - ) - ((= arg0 'base) - *camera-base-mode* - ) - ((= arg0 'string) - cam-string - ) - ((= arg0 'fixed) - cam-fixed - ) - ((type-type? (rtype-of arg0) symbol) - (the-as state (-> (the-as symbol arg0) value)) - ) - ((type-type? (rtype-of arg0) string) - (the-as state arg0) - ) - ((type-type? (rtype-of arg0) state) - (the-as state arg0) - ) - (else - (empty) - arg1 - ) - ) + (the-as state (cond + ((null? arg0) + (empty) + arg1 + ) + ((= arg0 'base) + *camera-base-mode* + ) + ((= arg0 'string) + cam-string + ) + ((= arg0 'fixed) + cam-fixed + ) + ((type-type? (rtype-of arg0) symbol) + (the-as state (-> (the-as symbol arg0) value)) + ) + ((type-type? (rtype-of arg0) string) + (the-as state arg0) + ) + ((type-type? (rtype-of arg0) state) + (the-as state arg0) + ) + (else + (empty) + arg1 + ) + ) + ) ) ;; definition for function command-get-trans @@ -938,26 +940,7 @@ ) ;; definition for function camera-change-to -(defun camera-change-to ((arg0 string) (arg1 int) (arg2 symbol)) - (let ((gp-0 (command-get-camera arg0 *camera-base-mode*))) - (cond - ((not gp-0) - #f - ) - ((type-type? (rtype-of gp-0) string) - (send-event *camera* 'change-to-entity-by-name gp-0) - #t - ) - ((type-type? (rtype-of gp-0) state) - (send-event *camera* 'change-state gp-0 arg1) - (if arg2 - (send-event *camera* 'blend-from-as-fixed) - ) - #t - ) - ) - ) - ) +;; ERROR: function was not converted to expressions. Cannot decompile. ;; definition for function camera-look-at (defbehavior camera-look-at camera-tracker ((arg0 pair) (arg1 uint)) @@ -1489,7 +1472,7 @@ (* s3-1 8) ) ) - (dummy-15 obj *lev-string* '()) + (initialize-skeleton-by-name obj *lev-string* '()) (logior! (-> obj draw status) (draw-status drwf06)) (if (nonzero? (-> obj draw)) (go med-res-level-idle) diff --git a/test/decompiler/reference/engine/geometry/bounding-box-h_REF.gc b/test/decompiler/reference/engine/geometry/bounding-box-h_REF.gc index 3d34532e5c..d0a146ec54 100644 --- a/test/decompiler/reference/engine/geometry/bounding-box-h_REF.gc +++ b/test/decompiler/reference/engine/geometry/bounding-box-h_REF.gc @@ -10,12 +10,12 @@ :size-assert #x20 :flag-assert #x1000000020 (:methods - (add-spheres! (_type_ (pointer sphere) int) int 9) + (add-spheres! (_type_ (inline-array sphere) int) int 9) (add-point! (_type_ vector3s) int 10) (set-from-point-offset! (_type_ vector3s vector3s) int 11) (set-from-point-offset-pad! (_type_ vector3s vector3s float) int 12) (set-from-sphere! (_type_ sphere) int 13) - (set-from-spheres! (_type_ (pointer sphere) int) int 14) + (set-from-spheres! (_type_ (inline-array sphere) int) int 14) (add-box! (_type_ bounding-box) int 15) ) ) diff --git a/test/decompiler/reference/engine/target/logic-target_REF.gc b/test/decompiler/reference/engine/target/logic-target_REF.gc index 1f0ad4c145..018e80a936 100644 --- a/test/decompiler/reference/engine/target/logic-target_REF.gc +++ b/test/decompiler/reference/engine/target/logic-target_REF.gc @@ -1329,7 +1329,7 @@ ) ) (set-quaternion! (-> self control) (-> self control dir-targ)) - (dummy-17 self) + (do-joint-math! self) (none) ) @@ -1359,7 +1359,7 @@ ) ) (set! (-> self control unknown-float110) 0.0) - (dummy-17 self) + (do-joint-math! self) (none) ) @@ -1448,7 +1448,7 @@ ) ) (set-quaternion! (-> self control) (-> self control dir-targ)) - (dummy-17 self) + (do-joint-math! self) (update-transforms! (-> self control)) (none) ) diff --git a/test/decompiler/reference/engine/target/sidekick_REF.gc b/test/decompiler/reference/engine/target/sidekick_REF.gc index ea90889cba..d7cc57ec81 100644 --- a/test/decompiler/reference/engine/target/sidekick_REF.gc +++ b/test/decompiler/reference/engine/target/sidekick_REF.gc @@ -157,7 +157,7 @@ (new 'static 'rgba :r #x40 :b #x40 :a #x80) ) ) - (dummy-17 self) + (do-joint-math! self) (if *debug-segment* (add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0) diff --git a/test/decompiler/reference/engine/target/target-h_REF.gc b/test/decompiler/reference/engine/target/target-h_REF.gc index 69cfaa1382..9c3ba1c5aa 100644 --- a/test/decompiler/reference/engine/target/target-h_REF.gc +++ b/test/decompiler/reference/engine/target/target-h_REF.gc @@ -66,7 +66,7 @@ (target-flut-clone-anim handle) (target-flut-death symbol) (target-flut-double-jump float float) - target-flut-falling + (target-flut-falling symbol) (target-flut-get-off handle) (target-flut-get-off-hit-ground symbol) (target-flut-get-off-jump handle) diff --git a/test/decompiler/reference/engine/target/target-util_REF.gc b/test/decompiler/reference/engine/target/target-util_REF.gc index 9fb2f5e2d3..c3d00655c3 100644 --- a/test/decompiler/reference/engine/target/target-util_REF.gc +++ b/test/decompiler/reference/engine/target/target-util_REF.gc @@ -958,7 +958,7 @@ (set! (-> s5-0 1 quad) (-> self control trans quad)) (set! (-> s5-0 1 y) (+ 2867.2 (-> *TARGET-bank* body-radius) (-> s5-0 1 y))) (set! (-> s5-0 1 w) (-> *TARGET-bank* body-radius)) - (set! (-> gp-0 spheres) (the-as (pointer sphere) s5-0)) + (set! (-> gp-0 spheres) s5-0) ) (set! (-> gp-0 num-spheres) (the-as uint 2)) (set! (-> gp-0 collide-with) (-> self control root-prim collide-with)) diff --git a/test/decompiler/reference/engine/target/target2_REF.gc b/test/decompiler/reference/engine/target/target2_REF.gc index 312b00cc11..ddb448f8a7 100644 --- a/test/decompiler/reference/engine/target/target2_REF.gc +++ b/test/decompiler/reference/engine/target/target2_REF.gc @@ -1553,7 +1553,7 @@ (= (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) stick0-speed) 0.0) ) (let ((a1-2 (new 'stack-no-clear 'collide-using-spheres-params))) - (set! (-> a1-2 spheres) (the-as (pointer sphere) (-> *collide-edge-work* world-player-leap-up-spheres))) + (set! (-> a1-2 spheres) (-> *collide-edge-work* world-player-leap-up-spheres)) (set! (-> a1-2 num-spheres) (the-as uint 6)) (set! (-> a1-2 collide-with) (-> self control root-prim collide-with)) (set! (-> a1-2 proc) #f) diff --git a/test/decompiler/reference/levels/finalboss/final-door_REF.gc b/test/decompiler/reference/levels/finalboss/final-door_REF.gc index 3a40a6d54f..78f1982573 100644 --- a/test/decompiler/reference/levels/finalboss/final-door_REF.gc +++ b/test/decompiler/reference/levels/finalboss/final-door_REF.gc @@ -51,7 +51,7 @@ (:methods (idle () _type_ :state 20) (dummy-21 (_type_) none 21) - (open () _type_ :state 22) + (open (symbol) _type_ :state 22) ) ) @@ -97,8 +97,7 @@ (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) (case arg2 (('open) - enter-state - (go-virtual open) + (go-virtual open #f) ) ) ) @@ -136,45 +135,45 @@ ) ) :code - (behavior () + (behavior ((arg0 symbol)) (case (-> self type) ((power-left) - (let ((a0-1 (-> self skel root-channel 0))) - (set! (-> a0-1 frame-group) (the-as art-joint-anim (-> self draw art-group data 2))) - (set! (-> a0-1 param 0) + (let ((a0-2 (-> self skel root-channel 0))) + (set! (-> a0-2 frame-group) (the-as art-joint-anim (-> self draw art-group data 2))) + (set! (-> a0-2 param 0) (the float (+ (-> (the-as art-joint-anim (-> self draw art-group data 2)) data 0 length) -1)) ) - (set! (-> a0-1 param 1) 0.353) - (set! (-> a0-1 frame-num) 0.0) - (joint-control-channel-group! a0-1 (the-as art-joint-anim (-> self draw art-group data 2)) num-func-seek!) + (set! (-> a0-2 param 1) 0.353) + (set! (-> a0-2 frame-num) 0.0) + (joint-control-channel-group! a0-2 (the-as art-joint-anim (-> self draw art-group data 2)) num-func-seek!) ) (until (ja-done? 0) (transform-post) (suspend) - (let ((a0-2 (-> self skel root-channel 0))) - (set! (-> a0-2 param 0) (the float (+ (-> a0-2 frame-group data 0 length) -1))) - (set! (-> a0-2 param 1) 0.353) - (joint-control-channel-group-eval! a0-2 (the-as art-joint-anim #f) num-func-seek!) + (let ((a0-3 (-> self skel root-channel 0))) + (set! (-> a0-3 param 0) (the float (+ (-> a0-3 frame-group data 0 length) -1))) + (set! (-> a0-3 param 1) 0.353) + (joint-control-channel-group-eval! a0-3 (the-as art-joint-anim #f) num-func-seek!) ) ) ) (else - (let ((a0-4 (-> self skel root-channel 0))) - (set! (-> a0-4 frame-group) (the-as art-joint-anim (-> self draw art-group data 2))) - (set! (-> a0-4 param 0) + (let ((a0-5 (-> self skel root-channel 0))) + (set! (-> a0-5 frame-group) (the-as art-joint-anim (-> self draw art-group data 2))) + (set! (-> a0-5 param 0) (the float (+ (-> (the-as art-joint-anim (-> self draw art-group data 2)) data 0 length) -1)) ) - (set! (-> a0-4 param 1) 0.353) - (set! (-> a0-4 frame-num) 0.0) - (joint-control-channel-group! a0-4 (the-as art-joint-anim (-> self draw art-group data 2)) num-func-seek!) + (set! (-> a0-5 param 1) 0.353) + (set! (-> a0-5 frame-num) 0.0) + (joint-control-channel-group! a0-5 (the-as art-joint-anim (-> self draw art-group data 2)) num-func-seek!) ) (until (ja-done? 0) (transform-post) (suspend) - (let ((a0-5 (-> self skel root-channel 0))) - (set! (-> a0-5 param 0) (the float (+ (-> a0-5 frame-group data 0 length) -1))) - (set! (-> a0-5 param 1) 0.353) - (joint-control-channel-group-eval! a0-5 (the-as art-joint-anim #f) num-func-seek!) + (let ((a0-6 (-> self skel root-channel 0))) + (set! (-> a0-6 param 0) (the float (+ (-> a0-6 frame-group data 0 length) -1))) + (set! (-> a0-6 param 1) 0.353) + (joint-control-channel-group-eval! a0-6 (the-as art-joint-anim #f) num-func-seek!) ) ) ) diff --git a/test/decompiler/reference/levels/flut_common/target-flut_REF.gc b/test/decompiler/reference/levels/flut_common/target-flut_REF.gc index 8b36e8ff32..15a39428dd 100644 --- a/test/decompiler/reference/levels/flut_common/target-flut_REF.gc +++ b/test/decompiler/reference/levels/flut_common/target-flut_REF.gc @@ -428,10 +428,9 @@ ) ) (('falling) - (when #t - enter-state - (go target-flut-falling) - ) + (if #t + (go target-flut-falling #f) + ) ) (('swim) (let* ((gp-1 (-> self control last-known-safe-ground)) @@ -696,27 +695,26 @@ (if (can-hands? #t) (go target-flut-running-attack) ) - (when (and (zero? (logand (-> self control status) 1)) - (and (>= (- (-> *display* base-frame-counter) (-> self control unknown-dword11)) (-> *FLUT-bank* ground-timeout)) - (>= 0.0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv))) - (let ((v1-37 (if (> (-> self skel active-channels) 0) - (-> self skel root-channel 0 frame-group) - ) - ) - ) - (or (not (or (= v1-37 (-> self draw art-group data 59)) - (= v1-37 (-> self draw art-group data 60)) - (= v1-37 (-> self draw art-group data 61)) + (if (and (zero? (logand (-> self control status) 1)) + (and (>= (- (-> *display* base-frame-counter) (-> self control unknown-dword11)) (-> *FLUT-bank* ground-timeout)) + (>= 0.0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv))) + (let ((v1-37 (if (> (-> self skel active-channels) 0) + (-> self skel root-channel 0 frame-group) ) ) - (< 4096.0 (target-height-above-ground)) - ) - ) + ) + (or (not (or (= v1-37 (-> self draw art-group data 59)) + (= v1-37 (-> self draw art-group data 60)) + (= v1-37 (-> self draw art-group data 61)) + ) + ) + (< 4096.0 (target-height-above-ground)) + ) ) - ) - enter-state - (go target-flut-falling) - ) + ) + ) + (go target-flut-falling #f) + ) (none) ) :code @@ -857,27 +855,26 @@ (if (can-hands? #t) (go target-flut-running-attack) ) - (when (and (zero? (logand (-> self control status) 1)) - (and (>= (- (-> *display* base-frame-counter) (-> self control unknown-dword11)) (-> *FLUT-bank* ground-timeout)) - (>= 0.0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv))) - (let ((v1-37 (if (> (-> self skel active-channels) 0) - (-> self skel root-channel 0 frame-group) - ) - ) - ) - (or (not (or (= v1-37 (-> self draw art-group data 59)) - (= v1-37 (-> self draw art-group data 60)) - (= v1-37 (-> self draw art-group data 61)) + (if (and (zero? (logand (-> self control status) 1)) + (and (>= (- (-> *display* base-frame-counter) (-> self control unknown-dword11)) (-> *FLUT-bank* ground-timeout)) + (>= 0.0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv))) + (let ((v1-37 (if (> (-> self skel active-channels) 0) + (-> self skel root-channel 0 frame-group) ) ) - (< 4096.0 (target-height-above-ground)) - ) - ) + ) + (or (not (or (= v1-37 (-> self draw art-group data 59)) + (= v1-37 (-> self draw art-group data 60)) + (= v1-37 (-> self draw art-group data 61)) + ) + ) + (< 4096.0 (target-height-above-ground)) + ) ) - ) - enter-state - (go target-flut-falling) - ) + ) + ) + (go target-flut-falling #f) + ) (let ((f30-1 (fabs (deg-diff (quaternion-y-angle (-> self control dir-targ)) (y-angle (-> self control)))))) (set! (-> self control unknown-surface00 turnv) (lerp-scale (the-as float (-> self control unknown-uint20)) @@ -1483,27 +1480,26 @@ (if (move-legs?) (go target-flut-walk) ) - (when (and (zero? (logand (-> self control status) 1)) - (and (>= (- (-> *display* base-frame-counter) (-> self control unknown-dword11)) (-> *FLUT-bank* ground-timeout)) - (>= 0.0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv))) - (let ((v1-34 (if (> (-> self skel active-channels) 0) - (-> self skel root-channel 0 frame-group) - ) - ) - ) - (or (not (or (= v1-34 (-> self draw art-group data 59)) - (= v1-34 (-> self draw art-group data 60)) - (= v1-34 (-> self draw art-group data 61)) + (if (and (zero? (logand (-> self control status) 1)) + (and (>= (- (-> *display* base-frame-counter) (-> self control unknown-dword11)) (-> *FLUT-bank* ground-timeout)) + (>= 0.0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv))) + (let ((v1-34 (if (> (-> self skel active-channels) 0) + (-> self skel root-channel 0 frame-group) ) ) - (< 4096.0 (target-height-above-ground)) - ) - ) + ) + (or (not (or (= v1-34 (-> self draw art-group data 59)) + (= v1-34 (-> self draw art-group data 60)) + (= v1-34 (-> self draw art-group data 61)) + ) + ) + (< 4096.0 (target-height-above-ground)) + ) ) - ) - enter-state - (go target-flut-falling) - ) + ) + ) + (go target-flut-falling #f) + ) (none) ) :code @@ -1523,7 +1519,7 @@ :event (-> target-flut-jump event) :enter - (behavior () + (behavior ((arg0 symbol)) (set! (-> self control unknown-surface00) *flut-jump-mods*) (set! (-> self state-time) (-> *display* base-frame-counter)) (none) @@ -1560,7 +1556,7 @@ (none) ) :code - (behavior () + (behavior ((arg0 symbol)) (cond ((= (if (> (-> self skel active-channels) 0) (-> self skel root-channel 0 frame-group) @@ -1579,11 +1575,11 @@ (ja-channel-push! 2 150) ) ) - (let ((a0-10 (-> self skel root-channel 0))) - (set! (-> a0-10 frame-group) (the-as art-joint-anim (-> self draw art-group data 144))) - (set! (-> a0-10 param 0) 1.0) - (set! (-> a0-10 frame-num) 0.0) - (joint-control-channel-group! a0-10 (the-as art-joint-anim (-> self draw art-group data 144)) num-func-loop!) + (let ((a0-11 (-> self skel root-channel 0))) + (set! (-> a0-11 frame-group) (the-as art-joint-anim (-> self draw art-group data 144))) + (set! (-> a0-11 param 0) 1.0) + (set! (-> a0-11 frame-num) 0.0) + (joint-control-channel-group! a0-11 (the-as art-joint-anim (-> self draw art-group data 144)) num-func-loop!) ) (let ((gp-0 (-> self skel root-channel 1))) (set! (-> gp-0 frame-interp) (-> self control unknown-float122)) @@ -1596,14 +1592,14 @@ ) (while #t (suspend) - (let ((a0-12 (-> self skel root-channel 0))) - (set! (-> a0-12 param 0) (the float (+ (-> a0-12 frame-group data 0 length) -1))) - (joint-control-channel-group-eval! a0-12 (the-as art-joint-anim #f) num-func-loop!) + (let ((a0-13 (-> self skel root-channel 0))) + (set! (-> a0-13 param 0) (the float (+ (-> a0-13 frame-group data 0 length) -1))) + (joint-control-channel-group-eval! a0-13 (the-as art-joint-anim #f) num-func-loop!) ) - (let ((a0-13 (-> self skel root-channel 1))) - (set! (-> a0-13 frame-interp) (-> self control unknown-float122)) - (set! (-> a0-13 param 0) 0.0) - (joint-control-channel-group-eval! a0-13 (the-as art-joint-anim #f) num-func-chan) + (let ((a0-14 (-> self skel root-channel 1))) + (set! (-> a0-14 frame-interp) (-> self control unknown-float122)) + (set! (-> a0-14 param 0) 0.0) + (joint-control-channel-group-eval! a0-14 (the-as art-joint-anim #f) num-func-chan) ) ) (none) @@ -1836,8 +1832,7 @@ ) ) ) - enter-state - (go target-flut-falling) + (go target-flut-falling #f) ) ((and (nonzero? (-> self control unknown-uint30)) (>= (the-as uint (- (-> *display* base-frame-counter) (the-as int (-> self control unknown-uint30)))) @@ -1876,26 +1871,25 @@ (set! f30-0 (* f30-0 (the-as float (fmin 1.0 (the-as float (-> self control unknown-float140)))))) ) ) - (when (and (zero? (logand (-> self control status) 1)) - (>= (- (-> *display* base-frame-counter) (-> self control unknown-dword11)) (-> *FLUT-bank* ground-timeout)) - (>= 0.0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv))) - (let ((v1-105 (if (> (-> self skel active-channels) 0) - (-> self skel root-channel 0 frame-group) - ) - ) - ) - (or (not (or (= v1-105 (-> self draw art-group data 59)) - (= v1-105 (-> self draw art-group data 60)) - (= v1-105 (-> self draw art-group data 61)) - ) - ) - (< 4096.0 (target-height-above-ground)) - ) - ) + (if (and (zero? (logand (-> self control status) 1)) + (>= (- (-> *display* base-frame-counter) (-> self control unknown-dword11)) (-> *FLUT-bank* ground-timeout)) + (>= 0.0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv))) + (let ((v1-105 (if (> (-> self skel active-channels) 0) + (-> self skel root-channel 0 frame-group) + ) + ) + ) + (or (not (or (= v1-105 (-> self draw art-group data 59)) + (= v1-105 (-> self draw art-group data 60)) + (= v1-105 (-> self draw art-group data 61)) + ) + ) + (< 4096.0 (target-height-above-ground)) + ) ) - enter-state - (go target-flut-falling) - ) + ) + (go target-flut-falling #f) + ) (when (!= f30-0 0.0) (set! (-> self trans-hook) (-> target-flut-hit-ground trans)) (if (not (ja-done? 0)) diff --git a/test/decompiler/reference/levels/ogre/flying-lurker_REF.gc b/test/decompiler/reference/levels/ogre/flying-lurker_REF.gc index 8dcfcba492..57952be45b 100644 --- a/test/decompiler/reference/levels/ogre/flying-lurker_REF.gc +++ b/test/decompiler/reference/levels/ogre/flying-lurker_REF.gc @@ -515,7 +515,7 @@ (vector+float! (-> s2-2 min) s1-1 -18432.0) (vector+float! (-> s2-2 max) s1-1 18432.0) ) - (add-spheres! s2-2 (the-as (pointer sphere) (-> s3-1 intersect)) 1) + (add-spheres! s2-2 (the-as (inline-array sphere) (-> s3-1 intersect)) 1) (let ((f0-17 (* 0.5 (vector-vector-distance (-> s2-2 min) (-> s2-2 max))))) (set-vector! (-> obj draw bounds)