Decompile joint, collide-func, clean up joint decompression code for all games (#3369)

I finally read through all the joint code and wrote up some
documentation. I think this will be really helpful when we try to
understand all the functions in `process-drawable`, or if somebody ever
wants to import/export animations.

This switches all three games to using a new faster GOAL joint
decompressor. It is on by default, but you can go back to the old
version by setting `*use-new-decompressor*` to false.

Also fix the log-related crash, fix the clock speed used in timer math.
This commit is contained in:
water111
2024-02-11 09:50:07 -05:00
committed by GitHub
parent a4e629ebf9
commit 79d14af0b5
32 changed files with 8951 additions and 129 deletions
+6 -3
View File
@@ -1,5 +1,6 @@
#include "log.h"
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <mutex>
@@ -118,6 +119,8 @@ void log_vprintf(const char* format, va_list arg_list) {
// We always immediately flush prints because since it has no associated level
// it could be anything from a fatal error to a useless debug log.
std::lock_guard<std::mutex> lock(gLogger.mutex);
va_list arg_list_2;
va_copy(arg_list_2, arg_list);
if (gLogger.fp) {
// Log to File
vfprintf(gLogger.fp, format, arg_list);
@@ -125,7 +128,7 @@ void log_vprintf(const char* format, va_list arg_list) {
}
if (gLogger.stdout_log_level < lg::level::off_unless_die) {
vprintf(format, arg_list);
vprintf(format, arg_list_2);
fflush(stdout);
fflush(stderr);
}
@@ -133,8 +136,8 @@ void log_vprintf(const char* format, va_list arg_list) {
}
} // namespace internal
void printstd(const std::string& format, va_list arg_list) {
internal::log_vprintf(format.c_str(), arg_list);
void printstd(const char* format, va_list arg_list) {
internal::log_vprintf(format, arg_list);
}
// how many extra log files for a single program should be kept?
+1 -1
View File
@@ -77,7 +77,7 @@ void print(const fmt::text_style& ts, const std::string& format, Args&&... args)
}
// same as print but uses the C printf instead of fmt
void printstd(const std::string& format, va_list arg_list);
void printstd(const char* format, va_list arg_list);
template <typename... Args>
void trace(const std::string& format, Args&&... args) {
+11 -1
View File
@@ -228,7 +228,17 @@ struct Mips2C_Output {
result += "void link() {\n";
// lookup all symbols
for (auto& sym : symbol_cache) {
result += fmt::format(" cache.{} = intern_from_c(\"{}\").c();\n", goal_to_c_name(sym), sym);
switch (version) {
case GameVersion::Jak1:
case GameVersion::Jak2:
result +=
fmt::format(" cache.{} = intern_from_c(\"{}\").c();\n", goal_to_c_name(sym), sym);
break;
case GameVersion::Jak3:
result += fmt::format(" cache.{} = intern_from_c(-1, 0, \"{}\").c();\n",
goal_to_c_name(sym), sym);
break;
}
}
// this adds us to a table for lookup later, and also allocates our trampoline.
result += fmt::format(" gLinkedFunctionTable.reg(\"{}\", execute, PUT_STACK_SIZE_HERE);\n",
+109 -66
View File
@@ -10481,7 +10481,22 @@
(defenum mem-usage-id
:bitfield #f
:type uint32
(joint 68)
(joint-anim-compressed-control 70)
(joint-anim-fixed 71)
(joint-anim-frame 72)
(art-group 74)
(art-mesh-anim 75)
(art-mesh-geo 76)
(art-joint-geo 77)
(art-joint-anim 78)
(texture 83)
(eye-anim 112)
)
(deftype memory-usage-info (structure)
@@ -14097,9 +14112,10 @@
(:methods
(login (_type_) _type_) ;; 9
(art-method-10 (_type_) _type_) ;; 10
(get-art-by-name-method (_type_ string type) basic) ;; 11
(get-art-idx-by-name-method (_type_ string type) int) ;; 12
(needs-link? (_type_) symbol) ;; 13
(get-art-by-name-method "Look inside this art for an art with the given name and type. Return #f if not found" (_type_ string type) basic) ;; 11
(get-art-idx-by-name-method "Look inside this art for an art with the given name and type and return the index of the art. Return #f if not found." (_type_ string type) int) ;; 12
(contains-art-for-other-group? "Some art groups have placeholder #f's for some art that will be loaded separately as needed.
Does this art group contain art that needs to be added to another group?" (_type_) symbol) ;; 13
)
)
@@ -14116,7 +14132,7 @@
(deftype art-mesh-anim (art-element)
"An unused mesh animation."
()
((data basic :dynamic))
:flag-assert #xe00000030
)
@@ -14144,21 +14160,22 @@
)
:flag-assert #x1000000020
(:methods
(relocate (_type_ kheap (pointer uint8)) _type_ :replace)
(link-art! (_type_) art-group)
(relocate (_type_ kheap (pointer uint8)) none :replace) ;; 7
(link-art-to-master (_type_) none)
(unknown-1 () none)
)
)
(deftype art-mesh-geo (art-element)
"Unused art format for a mesh. This might have been for the renderer that came before merc."
()
((data basic :dynamic :offset-assert 48)
)
:flag-assert #xe00000030
)
(deftype art-joint-geo (art-element)
"Collection of joints for an actor."
((data joint :dynamic :offset 48)
((data joint :dynamic :offset-assert 48)
)
:flag-assert #xe00000030
)
@@ -14200,11 +14217,11 @@
:flag-assert #xe00000430
(:methods
(new (symbol type int) _type_) ;; 0 ;; (new (symbol type int) _type_)
(art-joint-anim-manager-method-9 () none) ;; 9 ;; (decompress (_type_ art-joint-anim) art-joint-anim)
(art-joint-anim-manager-method-10 () none) ;; 10 ;; (update-time-stamp (_type_ art-joint-anim) art-joint-anim)
(art-joint-anim-manager-method-11 () none) ;; 11 ;; (unload-from-slot (_type_ int) art-joint-anim)
(art-joint-anim-manager-method-12 () none) ;; 12 ;; (used-bytes-for-slot (_type_ int) int)
(art-joint-anim-manager-method-13 () none) ;; 13 ;; (unload-from-level (_type_ level) none)
(decompress "Decompress the given animation and store the decompressed data in this cache." (_type_ art-joint-anim) art-joint-anim) ;; 9
(mark-anim-in-use "Inform the cache this animation is in used, so it is not evicted." (_type_ art-joint-anim) art-joint-anim) ;; 10
(unload-from-slot "Remove the given animation from the cache." (_type_ int) art-joint-anim) ;; 11
(used-bytes-for-slot "Get how many bytes of our heap are used by the given anim slot." (_type_ int) int) ;; 12
(unload-from-heap "Remove all animations which have their original compressed data in the given heap." (_type_ kheap) none) ;; 13
)
)
@@ -16928,7 +16945,7 @@
;(UNKNOWN UNKNOWN :offset-assert -1) ;; field could not be read.
(top-anim top-anim-joint-control :offset-assert 56) ;; guessed by decompiler
(override (array float) :offset-assert 60) ;; guessed by decompiler
(channel joint-control-channel :dynamic :offset-assert 64) ;; guessed by decompiler
(channel joint-control-channel :dynamic :inline :offset-assert 64) ;; guessed by decompiler
;(UNKNOWN UNKNOWN :offset-assert -1) ;; field could not be read.
)
:method-count-assert 13
@@ -16936,10 +16953,10 @@
:flag-assert #xd00000040
;; field joint-control-status is likely a value type.
(:methods
(new (symbol type) _type_) ;; 0 ;; (new (symbol type int) _type_)
(new (symbol type int) _type_) ;; 0
(joint-control-method-9 () none) ;; 9 ;; (current-cycle-distance (_type_) float)
(joint-control-method-10 () none) ;; 10 ;; (update-anim-data (_type_) none)
(joint-control-method-11 () none) ;; 11 ;; (debug-print-channels (_type_ symbol) int)
(debug-print-channels "Print the list of joint animations playing in the flattened blend tree." (_type_ symbol) int) ;; 11
(joint-control-method-12 () none) ;; 12
)
)
@@ -27542,16 +27559,16 @@
;; collide-func ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (define-extern raw-ray-sphere-intersect function)
;; (define-extern ray-sphere-intersect function) ;; (function vector vector vector float float)
;; (define-extern ray-circle-intersect function) ;; (function vector vector vector float float)
;; (define-extern ray-cylinder-intersect function) ;; (function vector vector vector vector float float vector float)
;; (define-extern ray-plane-intersect function) ;; (function vector vector vector vector vector vector vector float)
;; (define-extern ray-triangle-intersect function)
;; (define-extern collide-do-primitives function)
;; (define-extern moving-sphere-triangle-intersect function) ;; (function vector vector float collide-cache-tri vector vector float)
;; (define-extern moving-sphere-sphere-intersect function)
;; (define-extern moving-sphere-moving-sphere-intersect function)
(define-extern raw-ray-sphere-intersect function)
(define-extern ray-sphere-intersect (function vector vector vector float float))
(define-extern ray-circle-intersect (function vector vector vector float float))
(define-extern ray-cylinder-intersect (function vector vector vector vector float float vector float))
(define-extern ray-plane-intersect (function vector vector vector vector vector vector vector float))
; (define-extern ray-triangle-intersect function)
; (define-extern collide-do-primitives function)
(define-extern moving-sphere-triangle-intersect (function vector vector float collide-cache-tri vector vector float))
; (define-extern moving-sphere-sphere-intersect function)
; (define-extern moving-sphere-moving-sphere-intersect function)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; joint ;;
@@ -27576,49 +27593,75 @@
)
|#
;; (define-extern joint-anim-login function) ;; (function joint-anim-drawable joint-anim-drawable)
;; (define-extern joint-anim-inspect-elt function) ;; (function joint-anim float joint-anim)
;; (define-extern jacc-mem-usage function) ;; (function joint-anim-compressed-control memory-usage-block int joint-anim-compressed-control)
;; (define-extern joint-control-cleanup function)
;; (define-extern joint-control-channel-eval function) ;; (function joint-control-channel float :behavior process)
;; (define-extern joint-control-channel-eval! function) ;; (function joint-control-channel (function joint-control-channel float float float float) float :behavior process)
;; (define-extern joint-control-channel-group-eval! function) ;; (function joint-control-channel art-joint-anim (function joint-control-channel float float float float) int)
;; (define-extern joint-control-channel-group! function) ;; (function joint-control-channel art-joint-anim (function joint-control-channel float float float float) int)
;; (define-extern joint-control-copy! function) ;; (function joint-control joint-control joint-control)
;; (define-extern joint-control-remap! function) ;; (function joint-control art-group art-group pair int string symbol)
;; (define-extern flatten-joint-control-to-spr function) ;; (function joint-control int)
;; (define-extern matrix-from-joint-anim-frame function) ;; (function joint-anim-compressed-control int int matrix)
;; (define-extern matrix-from-control-channel! function) ;; (function matrix joint joint-control-channel matrix)
;; (define-extern matrix-from-control-pair! function) ;; (function matrix matrix joint int matrix)
;; (define-extern matrix-from-control! function) ;; (function matrix-stack joint joint-control symbol matrix)
;; (define-extern cspace<-cspace! function) ;; (function cspace cspace matrix)
;; (define-extern cspace<-cspace-normalized! function) ;; (function cspace cspace matrix)
;; (define-extern cspace<-parent-joint! function) ;; (function cspace (pointer process-drawable) int matrix)
;; (define-extern cspace<-rot-yxy! function) ;; (function cspace transform matrix)
;; (define-extern cspace<-transform-yxy! function) ;; (function cspace transform matrix)
(define-extern cspace<-transformq! (function cspace transformq matrix))
;; (define-extern cspace<-transformq+trans! function) ;; (function cspace transformq vector matrix)
;; (define-extern cspace<-transformq+world-trans! function) ;; (function cspace transformq vector matrix)
;; (define-extern cspace<-transformq+rot-offset! function) ;; (function cspace transformq vector matrix)
;; (define-extern cspace-calc-total-matrix! function) ;; (function cspace matrix matrix)
;; (define-extern cspace<-matrix-no-push-joint! function) ;; (function cspace joint-control matrix)
;; (define-extern cspace<-matrix-joint! function) ;; (function cspace matrix matrix)
;; (define-extern cspace<-parented-matrix-joint! function) ;; (function cspace matrix matrix)
;; (define-extern cspace<-parented-matrix-mirror! function) ;; (function cspace matrix matrix)
;; (define-extern cspace<-parented-matrix-joint-flip-z! function) ;; (function cspace matrix matrix)
;; (define-extern cspace<-matrix-joint-flip-z! function) ;; (function cspace matrix none)
(define-extern cspace<-parented-transformq-joint! (function cspace transformq none))
;; (define-extern cspace<-parented-transformq-joint-flip-z! function) ;; (function cspace transformq none)
(define-extern joint-anim-login "Login a joint-anim-drawable by calling login on all drawables" (function joint-anim-drawable joint-anim-drawable))
(define-extern joint-anim-inspect-elt "Inspect an uncompressed anim (unused)" (function joint-anim float joint-anim))
(define-extern jacc-mem-usage "Compute memory usage stats for a compressed joint anim." (function joint-anim-compressed-control memory-usage-block int joint-anim-compressed-control))
(define-extern joint-control-cleanup "Remove all animations that are stored on the given heap and return those slots to a safe default." (function joint-control kheap art-joint-anim none))
(define-extern joint-control-channel-eval "Run the num-func to produce the current frame for this channel." (function joint-control-channel float :behavior process))
(define-extern joint-control-channel-eval! "Update the num-func for this channel and evaluate it." (function joint-control-channel (function joint-control-channel float float float float) float :behavior process))
(define-extern joint-control-channel-group-eval! (function joint-control-channel art-joint-anim (function joint-control-channel float float float float) int))
(define-extern joint-control-channel-group! (function joint-control-channel art-joint-anim (function joint-control-channel float float float float) int))
(define-extern joint-control-copy! "Copy all settings and channels from one joint-control to another." (function joint-control joint-control joint-control))
(define-extern joint-control-remap!
"Map animation from parent to child using the given animation mapping.
This is used to animate daxter based on the animation of jak."
(function joint-control art-group art-group pair int string symbol))
(define-extern flatten-joint-control-to-spr "Walk the blend tree and compute interpolation weights, prepare animation upload info." (function joint-control int))
(define-extern matrix-from-joint-anim-frame "Get a matrix from a joint-animation at a given (integer) frame.
This only works on the first two joints, since those are the only ones that store matrices."(function joint-anim-compressed-control int int matrix))
(define-extern matrix-from-control-channel! "Get a matrix for a joint (must be 0 or 1) for the animation specified by the channel.
Will interpolate if we are in between animation frames.
This does not apply any frame-interp blending." (function matrix joint joint-control-channel matrix))
(define-extern matrix-from-control-pair! "Modify the matrix to add in a blended animation for the given channel."
(function matrix joint-control-channel joint int matrix))
(define-extern matrix-from-control!
"Compute a matrix for a given joint (must be 0 or 1) given the entire joint-control.
This walks the blend tree."
(function matrix-stack joint joint-control symbol matrix))
(define-extern cspace<-cspace! "Set one cspace's bone from another" (function cspace cspace matrix))
(define-extern cspace<-cspace-normalized! "Set one cspace's bone from another, and normalize the rows of the matrix." (function cspace cspace matrix))
(define-extern cspace<-parent-joint! "Set one cspace's bone to another from the given process-drawable" (function cspace (pointer process-drawable) int matrix))
(define-extern cspace<-rot-yxy! "Set one cspace's bone to a yxy rotation and scale." (function cspace transform matrix))
(define-extern cspace<-transform-yxy! "Set one cspace's bone to yxy rotation, translation, and scale" (function cspace transform matrix))
(define-extern cspace<-transformq! "Set one cspace's from a transformq" (function cspace transformq matrix))
(define-extern cspace<-transformq+trans! "Set one cspace from a transformq and an additional local translation." (function cspace transformq vector matrix))
(define-extern cspace<-transformq+world-trans! "Set one cspace from a transformq and an additional world translation." (function cspace transformq vector matrix))
(define-extern cspace<-transformq+rot-offset! "Set one cspace from a transformq and an additional rotate." (function cspace transformq vector matrix))
(define-extern cspace-calc-total-matrix! "Combine the bone matrix and camera matrix.
This is not actually a useful matrix since it does not include the inverse bind pose, but
is close to the rendering matrices computed by bones.gc"
(function cspace matrix matrix))
(define-extern cspace<-matrix-no-push-joint! "Compute animated matrix, using the special 'no-push mode." (function cspace joint-control matrix))
(define-extern cspace<-matrix-joint! "Set the cspace from a matrix." (function cspace matrix matrix))
(define-extern cspace<-parented-matrix-joint!
"Compute the bone matrix of a cspace from combining the transform of the parent bone and the given joint matrix.
This computes world-space bones from a tree of bones (skeleton)"
(function cspace matrix matrix))
(define-extern cspace<-parented-matrix-mirror!
"Mirror the provided matrix (using cspace param1,2 as the normal/tangent dirs) as the joint matrix
This is similar to cspace<-parented-matrix-joint!, but essentially mirrors the joint."
(function cspace matrix matrix))
(define-extern cspace<-parented-matrix-joint-flip-z!
"Compute the bone matrix from the parent bone and joint, but flip the z-axis of the joint frame."
(function cspace matrix matrix))
(define-extern cspace<-matrix-joint-flip-z!
"Set the bone matrix directly from the joint matrix, flipping z."
(function cspace matrix none))
(define-extern cspace<-parented-transformq-joint!
"Main function for doing skeletal animation from decompressed transformq's.
Sets the cspace bone to the parent bone, plus the transformq."
(function cspace transformq none))
(define-extern cspace<-parented-transformq-joint-flip-z! "Unused, but would flip the z-axis of the transformq and do a normal parented joint transform." (function cspace transformq none))
;; (define-extern clear-frame-accumulator function)
;; (define-extern normalize-frame-quaternions function)
;; (define-extern decompress-fixed-data-to-accumulator function) ;; function
;; (define-extern decompress-frame-data-to-accumulator function) ;; function
;; (define-extern decompress-frame-data-pair-to-accumulator function) ;; function
;; (define-extern make-joint-jump-tables function) ;; (function int)
;; (define-extern calc-animation-from-spr function) ;; (function joint-anim-frame int none)
;; (define-extern create-interpolated-joint-animation-frame function) ;; (function joint-anim-frame int joint-control int)
;; (define-extern create-interpolated2-joint-animation-frame function) ;; (function joint-anim-frame int joint-control int)
;; (define-extern *anim-manager* object) ;; art-joint-anim-manager
(define-extern make-joint-jump-tables (function int))
(define-extern calc-animation-from-spr (function joint-anim-frame int none))
(define-extern create-interpolated-joint-animation-frame (function joint-anim-frame int joint-control int))
(define-extern create-interpolated2-joint-animation-frame (function joint-anim-frame int joint-control int))
(define-extern *anim-manager* art-joint-anim-manager)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; joint-mod ;;
@@ -28748,7 +28791,7 @@
;; (define-extern unpack-comp-rle function) ;; (function (pointer int8) (pointer int8) (pointer int8))
;; (define-extern unpack-comp-huf function) ;; (function (pointer uint8) (pointer uint8) uint huf-dictionary-node none)
;; (define-extern unpack-comp-lzo function) ;; (function (pointer uint8) (pointer uint8) none)
(define-extern unpack-comp-lzo (function (pointer uint8) (pointer uint8) none))
;; (define-extern pack-comp-rle function) ;; (function (pointer uint8) (pointer uint8) int int (pointer uint8))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -35730,7 +35773,7 @@
;; memory-usage-block is already defined!
;; (define-extern mem-size function) ;; (function basic symbol int int)
(define-extern mem-size (function basic symbol int int))
;; (define-extern *max-dma* object) ;; int
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -322,6 +322,9 @@
[15, "gp", "collide-shape-moving"],
[35, "gp", "collide-shape-moving"]
],
"joint-mod-rotate-world-callback": [
[[0, 24], "s3", "joint-mod-rotate-world"]
],
"joint-mod-set-local-callback": [[[1, 24], "v1", "joint-mod-set-local"]],
"joint-mod-add-local-callback": [[[1, 37], "s4", "joint-mod-add-local"]],
"joint-mod-set-world-callback": [[[1, 4], "v1", "joint-mod-set-local"]],
@@ -423,6 +426,7 @@
],
"ear-trans": [[32, "s5", "process-focusable"]],
"loader-test-command": [[[5, 10], "v1", "sound-rpc-test-cmd"]],
"(method 11 connection)": [[5, "a1", "pointer"]],
"update-light-hash": [
[[234, 239], "a1", "light-hash-bucket"],
[[207, 211], "a0", "light-hash-bucket"]
@@ -524,5 +528,61 @@
"merc-vu1-init-buffer": [[[90, 92], "v1", "dma-packet"]],
"texture-usage-init": [[27, "a1", "vector"]],
"(method 9 art)": [[9, "v1", "pointer"]],
"(code pov-camera-start-playing pov-camera)": [[24, "v0", "joint"]]
"(code pov-camera-start-playing pov-camera)": [[24, "v0", "joint"]],
"(method 9 art)": [[9, "v1", "pointer"]],
"(method 9 art-mesh-geo)": [
[20, "s4", "(pointer int16)"],
[[14, 19], "a0", "drawable"],
[10, "v1", "(pointer art)"],
[14, "v1", "(pointer art)"]
],
"(method 9 art-joint-anim)": [[9, "v1", "pointer"]],
"joint-control-copy!": [
[8, "a0", "uint"],
[8, "v1", "uint"]
],
"joint-control-remap!": [
[127, "t9", "(function joint-control joint-control-channel int object)"],
[181, "t9", "(function joint-control joint-control-channel int object)"],
["_stack_", 60, "basic"]
],
"flatten-joint-control-to-spr": [
[[201, 203], "a1", "terrain-context"],
[[131, 133], "a0", "terrain-context"],
[[182, 184], "a1", "terrain-context"],
[[164, 166], "a0", "terrain-context"],
[195, "v1", "terrain-context"],
[65, "a3", "(pointer float)"],
[67, "a3", "(pointer float)"],
[[18, 47], "a2", "(inline-array vector)"],
[47, "a2", "pointer"],
[[48, 118], "a2", "(inline-array vector)"],
[118, "a2", "pointer"],
[24, "a3", "(pointer float)"],
[17, "a2", "int"]
],
"(method 12 art-joint-anim-manager)": [
[15, "a0", "pointer"],
[15, "v1", "pointer"],
[21, "a0", "pointer"],
[21, "v1", "pointer"]
],
"(method 11 art-joint-anim-manager)": [
[54, "v1", "uint"],
[54, "s2", "uint"],
[60, "s2", "uint"],
[66, "s2", "uint"],
[72, "s2", "uint"],
[88, "a1", "uint"],
[95, "a2", "uint"]
],
"(method 2 art-joint-anim-manager-slot)": [
[21, "s2", "uint"],
[21, "v1", "uint"]
],
"create-interpolated2-joint-animation-frame": [
[[48, 125], "v1", "joint-anim-frame"],
[[62, 67], "t2", "(inline-array vector)"],
[[67, 71], "a2", "(inline-array vector)"]
]
}
@@ -1174,6 +1174,260 @@
"vars": {
"v0-0": ["this", "align-control"]
}
},
"flatten-joint-control-to-spr": {
"args": ["jc"],
"vars": {
"s5-0": "chan-count",
"f0-0": "one",
"v1-2": "chan-float-offset",
"a2-0": ["chan-vector-ptr", "(inline-array vector)"],
"a0-2": "interp2-selected-idx",
"a1-0": "chan-idx",
"a3-2": "chan",
"a3-3": ["flt1", "(pointer float)"],
"f1-0": "interp2-selected-weight1",
"a2-1": ["prev-chan-ptr", "(inline-array vector)"],
"f2-2": "interp2-selected-weight2",
"f1-2": "one-minus-interp2",
"a2-2": ["chans-to-stack", "(inline-array vector)"],
"s4-0": "upload-count",
"s3-0": "upload-chan-idx",
"v1-11": "upload-chan",
"s2-0": "anim",
"f0-2": "frame-num",
"s1-0": "int-frame-num",
"f30-0": "frame-frac",
"s0-0": "last-frame",
"v1-20": "upload"
}
},
"matrix-from-joint-anim-frame": {
"args": ["jacc", "joint-idx", "frame-idx"],
"vars": {
"v1-1": "fixed-matrix",
"v0-0": "frame-matrix"
}
},
"matrix-from-control-channel!": {
"args": ["dest-mat", "requested-joint", "chan"],
"vars": {
"s4-0": "jacc",
"s5-0": "joint-num",
"f30-0": "frame-num",
"a2-3": "mat",
"s3-1": "first-mat",
"a2-7": "second-mat",
"f0-9": "mat-blend"
}
},
"joint-anim-login": {
"args": [
"jad"
]
},
"joint-anim-inspect-elt": {
"args": [
"ja",
"frame"
]
},
"jacc-mem-usage": {
"args": [
"jacc",
"mem-block",
"flags"
]
},
"joint-control-cleanup": {
"args": [
"jc",
"heap",
"ja"
]
},
"joint-control-channel-eval": {
"args": [
"jcc"
]
},
"joint-control-channel-eval!": {
"args": [
"jcc",
"num-func"
]
},
"joint-control-channel-group-eval!": {
"args": [
"jcc",
"ja",
"num-func"
]
},
"joint-control-channel-group!": {
// "args": [
// "jcc",
// "ja",
// "num-func"
// ]
},
"joint-control-copy!": {
"args": [
"dst",
"src"
]
},
"joint-control-remap!": {
"args": [
"jc",
"dst-art-group",
"parent-art-group",
"remap-list",
"seed",
"prefix"
]
},
"matrix-from-control-pair!": {
"args": [
"matrix-to-modify",
"jcc",
"jnt",
"active-frame-interp"
]
},
"matrix-from-control!": {
"args": [
"mat-stack",
"jnt",
"jc",
"mode"
]
},
"cspace<-cspace!": {
"args": [
"dst",
"src"
]
},
"cspace<-cspace-normalized!": {
"args": [
"dst",
"src"
]
},
"cspace<-parent-joint!": {
"args": [
"dst",
"proc",
"parent-idx"
]
},
"cspace<-rot-yxy!": {
"args": [
"dst",
"src"
]
},
"cspace<-transform-yxy!": {
"args": [
"dst",
"src"
]
},
"cspace<-transformq!": {
"args": [
"dst",
"src"
]
},
"cspace<-transformq+trans!": {
"args": [
"dst",
"src",
"extra-trans"
]
},
"cspace<-transformq+world-trans!": {
"args": [
"dst",
"src",
"extra-trans"
]
},
"cspace<-transformq+rot-offset!": {
"args": [
"dst",
"src",
"extra-rot"
]
},
"cspace-calc-total-matrix!": {
"args": [
"csp",
"dst"
]
},
"cspace<-matrix-no-push-joint!": {
"args": [
"dst",
"jc"
]
},
"cspace<-matrix-joint!": {
"args": [
"dst",
"src"
]
},
"cspace<-parented-matrix-joint!": {
"args": [
"dst",
"joint-mat"
]
},
"cspace<-parented-matrix-mirror!": {
"args": [
"dst",
"joint-mat"
]
},
"cspace<-parented-matrix-joint-flip-z!": {
"args": [
"dst",
"joint-mat"
]
},
"cspace<-matrix-joint-flip-z!": {
"args": [
"dst",
"src"
]
},
"cspace<-parented-transformq-joint!": {
"args": [
"dst",
"joint-transformq"
]
},
"cspace<-parented-transformq-joint-flip-z!": {
"args": [
"dst",
"joint-transformq"
]
},
"create-interpolated-joint-animation-frame": {
"args": [
"dst",
"num-joints",
"jc"
]
},
"create-interpolated2-joint-animation-frame": {
"args": [
"dst",
"num-joints",
"jc"
]
},
"(method 37 cloth-system)": {
"args": ["this", "command"],
+13 -1
View File
@@ -1961,7 +1961,19 @@ bool load_var_op_determine_type(types2::Type& type_out,
// normal virtual method access.
// first check special cases
if (type_name == "art" || type_name == "art-group") {
if (method_id == 10) {
int art_get_by_name_method_id = -1;
switch (dts.version()) {
case GameVersion::Jak1:
case GameVersion::Jak2:
art_get_by_name_method_id = 10;
break;
case GameVersion::Jak3:
art_get_by_name_method_id = 11;
break;
default:
ASSERT_NOT_REACHED();
}
if (method_id == art_get_by_name_method_id) {
type_out.type =
TP_Type::make_get_art_by_name(method_type, TypeSpec(type_name), method_id);
return true;
File diff suppressed because it is too large Load Diff
+1
View File
@@ -186,6 +186,7 @@ set(RUNTIME_SOURCE
mips2c/jak2_functions/squid.cpp
mips2c/jak2_functions/texture.cpp
mips2c/jak2_functions/vortex.cpp
mips2c/jak3_functions/collide_func.cpp
mips2c/jak3_functions/lights.cpp
mips2c/mips2c_table.cpp
overlord/common/dma.cpp
+506
View File
@@ -0,0 +1,506 @@
//--------------------------MIPS2C---------------------
// clang-format off
#include "game/mips2c/mips2c_private.h"
#include "game/kernel/jak3/kscheme.h"
using ::jak3::intern_from_c;
namespace Mips2C::jak3 {
namespace moving_sphere_triangle_intersect {
struct Cache {
void* collide_do_primitives; // collide-do-primitives
} cache;
u64 execute(void* ctxt) {
auto* c = (ExecutionContext*)ctxt;
bool bc = false;
u32 call_addr = 0;
c->daddiu(sp, sp, -16); // daddiu sp, sp, -16
c->sd(ra, 0, sp); // sd ra, 0(sp)
c->lqc2(vf14, 0, a0); // lqc2 vf14, 0(a0)
c->lqc2(vf15, 0, a1); // lqc2 vf15, 0(a1)
c->lqc2(vf11, 0, a3); // lqc2 vf11, 0(a3)
c->lqc2(vf12, 16, a3); // lqc2 vf12, 16(a3)
c->lqc2(vf13, 32, a3); // lqc2 vf13, 32(a3)
c->mov128_vf_gpr(vf1, a2); // qmtc2.i vf1, a2
c->vadd(DEST::xyzw, vf6, vf14, vf15); // vadd.xyzw vf6, vf14, vf15
c->vsub(DEST::xyzw, vf11, vf11, vf12); // vsub.xyzw vf11, vf11, vf12
c->vsub(DEST::xyzw, vf13, vf13, vf12); // vsub.xyzw vf13, vf13, vf12
c->vsub(DEST::xyzw, vf14, vf14, vf12); // vsub.xyzw vf14, vf14, vf12
c->vsub(DEST::xyzw, vf6, vf6, vf12); // vsub.xyzw vf6, vf6, vf12
c->vmini(DEST::xyzw, vf2, vf11, vf0); // vmini.xyzw vf2, vf11, vf0
c->vopmula(vf13, vf11); // vopmula.xyz acc, vf13, vf11
c->vopmsub(vf16, vf11, vf13); // vopmsub.xyz vf16, vf11, vf13
c->vmax(DEST::xyzw, vf3, vf11, vf0); // vmax.xyzw vf3, vf11, vf0
c->vmini(DEST::xyzw, vf4, vf14, vf6); // vmini.xyzw vf4, vf14, vf6
c->vmax(DEST::xyzw, vf5, vf14, vf6); // vmax.xyzw vf5, vf14, vf6
c->vmul(DEST::xyzw, vf7, vf16, vf16); // vmul.xyzw vf7, vf16, vf16
c->vmini(DEST::xyzw, vf2, vf2, vf13); // vmini.xyzw vf2, vf2, vf13
c->vmax(DEST::xyzw, vf3, vf3, vf13); // vmax.xyzw vf3, vf3, vf13
c->vsub_bc(DEST::xyzw, BC::x, vf4, vf4, vf1); // vsubx.xyzw vf4, vf4, vf1
c->vadd_bc(DEST::x, BC::y, vf7, vf7, vf7); // vaddy.x vf7, vf7, vf7
c->vadd_bc(DEST::xyzw, BC::x, vf5, vf5, vf1); // vaddx.xyzw vf5, vf5, vf1
// nop // sll r0, r0, 0
c->vsub(DEST::xyzw, vf3, vf3, vf4); // vsub.xyzw vf3, vf3, vf4
c->vadd_bc(DEST::x, BC::z, vf7, vf7, vf7); // vaddz.x vf7, vf7, vf7
c->vsub(DEST::xyzw, vf5, vf5, vf2); // vsub.xyzw vf5, vf5, vf2
// nop // sll r0, r0, 0
c->mov128_gpr_vf(t2, vf3); // qmfc2.i t2, vf3
c->mov128_gpr_vf(v1, vf5); // qmfc2.i v1, vf5
c->vrsqrt(vf0, BC::w, vf7, BC::x); // vrsqrt Q, vf0.w, vf7.x
c->or_(v1, t2, v1); // or v1, t2, v1
c->pcgtw(v1, r0, v1); // pcgtw v1, r0, v1
c->ppach(v1, r0, v1); // ppach v1, r0, v1
c->dsll(v1, v1, 16); // dsll v1, v1, 16
bc = c->sgpr64(v1) != 0; // bne v1, r0, L14
// nop // sll r0, r0, 0
if (bc) {goto block_14;} // branch non-likely
c->vmul(DEST::xyzw, vf2, vf16, vf15); // vmul.xyzw vf2, vf16, vf15
c->vmul(DEST::xyzw, vf3, vf16, vf14); // vmul.xyzw vf3, vf16, vf14
c->vadd_bc(DEST::x, BC::y, vf2, vf2, vf2); // vaddy.x vf2, vf2, vf2
c->vsub_bc(DEST::y, BC::y, vf3, vf0, vf3); // vsuby.y vf3, vf0, vf3
c->vadd_bc(DEST::x, BC::z, vf2, vf2, vf2); // vaddz.x vf2, vf2, vf2
c->vsub_bc(DEST::y, BC::x, vf3, vf3, vf3); // vsubx.y vf3, vf3, vf3
c->vsub_bc(DEST::y, BC::z, vf3, vf3, vf3); // vsubz.y vf3, vf3, vf3
c->vadd_bc(DEST::x, BC::x, vf3, vf0, vf0); // vaddx.x vf3, vf0, vf0
c->vadd_bc(DEST::x, BC::x, vf4, vf0, vf0); // vaddx.x vf4, vf0, vf0
c->vwaitq(); // vwaitq
c->vmulq(DEST::xyzw, vf16, vf16); // vmulq.xyzw vf16, vf16, Q
c->vmove(DEST::w, vf16, vf0); // vmove.w vf16, vf0
c->vmulq(DEST::xyzw, vf2, vf2); // vmulq.xyzw vf2, vf2, Q
c->vmulq(DEST::xyzw, vf4, vf3); // vmulq.xyzw vf4, vf3, Q
c->vmulq(DEST::xyzw, vf3, vf3); // vmulq.xyzw vf3, vf3, Q
c->sqc2(vf16, 0, t1); // sqc2 vf16, 0(t1)
// nop // vnop
// nop // vnop
c->vdiv(vf0, BC::w, vf2, BC::x); // vdiv Q, vf0.w, vf2.x
c->vadd_bc(DEST::y, BC::x, vf3, vf3, vf1); // vaddx.y vf3, vf3, vf1
c->vsub_bc(DEST::y, BC::x, vf4, vf4, vf1); // vsubx.y vf4, vf4, vf1
c->vwaitq(); // vwaitq
c->vmulq(DEST::xyzw, vf3, vf3); // vmulq.xyzw vf3, vf3, Q
c->vmulq(DEST::xyzw, vf4, vf4); // vmulq.xyzw vf4, vf4, Q
// nop // sll r0, r0, 0
// nop // sll r0, r0, 0
c->mov128_gpr_vf(v1, vf3); // qmfc2.i v1, vf3
c->mov128_gpr_vf(t1, vf4); // qmfc2.i t1, vf4
bc = ((s64)c->sgpr64(v1)) < 0; // bltz v1, L12
// nop // sll r0, r0, 0
if (bc) {goto block_11;} // branch non-likely
bc = ((s64)c->sgpr64(t1)) < 0; // bltz t1, L13
// nop // sll r0, r0, 0
if (bc) {goto block_12;} // branch non-likely
c->dsubu(v1, v1, t1); // dsubu v1, v1, t1
bc = ((s64)c->sgpr64(v1)) < 0; // bltz v1, L9
// nop // sll r0, r0, 0
if (bc) {goto block_6;} // branch non-likely
c->vsub_bc(DEST::xyzw, BC::w, vf2, vf4, vf0); // vsubw.xyzw vf2, vf4, vf0
c->mov128_gpr_vf(v1, vf2); // qmfc2.i v1, vf2
bc = ((s64)c->sgpr64(v1)) >= 0; // bgez v1, L14
// nop // sll r0, r0, 0
if (bc) {goto block_14;} // branch non-likely
c->mov128_gpr_vf(v0, vf4); // qmfc2.i v0, vf4
c->vmula_bc(DEST::xyzw, BC::w, vf14, vf0); // vmulaw.xyzw acc, vf14, vf0
c->vmadd_bc(DEST::xyzw, BC::y, vf8, vf15, vf4); // vmaddy.xyzw vf8, vf15, vf4
//beq r0, r0, L10 // beq r0, r0, L10
// nop // sll r0, r0, 0
goto block_8; // branch always
block_6:
c->vsub_bc(DEST::xyzw, BC::w, vf2, vf3, vf0); // vsubw.xyzw vf2, vf3, vf0
c->mov128_gpr_vf(v1, vf2); // qmfc2.i v1, vf2
bc = ((s64)c->sgpr64(v1)) >= 0; // bgez v1, L14
// nop // sll r0, r0, 0
if (bc) {goto block_14;} // branch non-likely
c->vmula_bc(DEST::xyzw, BC::w, vf14, vf0); // vmulaw.xyzw acc, vf14, vf0
c->vmadd_bc(DEST::xyzw, BC::y, vf8, vf15, vf3); // vmaddy.xyzw vf8, vf15, vf3
c->mov128_gpr_vf(v0, vf3); // qmfc2.i v0, vf3
block_8:
c->dsra32(v0, v0, 0); // dsra32 v0, v0, 0
c->vsub(DEST::xyzw, vf9, vf8, vf13); // vsub.xyzw vf9, vf8, vf13
c->vsub(DEST::xyzw, vf10, vf8, vf11); // vsub.xyzw vf10, vf8, vf11
c->vopmula(vf13, vf8); // vopmula.xyz acc, vf13, vf8
c->vopmsub(vf5, vf8, vf13); // vopmsub.xyz vf5, vf8, vf13
c->vopmula(vf8, vf11); // vopmula.xyz acc, vf8, vf11
c->vopmsub(vf6, vf11, vf8); // vopmsub.xyz vf6, vf11, vf8
c->vopmula(vf9, vf10); // vopmula.xyz acc, vf9, vf10
c->vopmsub(vf7, vf10, vf9); // vopmsub.xyz vf7, vf10, vf9
c->vmul(DEST::xyzw, vf5, vf5, vf16); // vmul.xyzw vf5, vf5, vf16
c->vmul(DEST::xyzw, vf6, vf6, vf16); // vmul.xyzw vf6, vf6, vf16
c->vmul(DEST::xyzw, vf7, vf7, vf16); // vmul.xyzw vf7, vf7, vf16
c->vadd_bc(DEST::y, BC::x, vf5, vf5, vf5); // vaddx.y vf5, vf5, vf5
c->vadd_bc(DEST::y, BC::x, vf6, vf6, vf6); // vaddx.y vf6, vf6, vf6
c->vadd_bc(DEST::y, BC::x, vf7, vf7, vf7); // vaddx.y vf7, vf7, vf7
c->vadd_bc(DEST::y, BC::z, vf5, vf5, vf5); // vaddz.y vf5, vf5, vf5
c->vadd_bc(DEST::y, BC::z, vf6, vf6, vf6); // vaddz.y vf6, vf6, vf6
c->vadd_bc(DEST::y, BC::z, vf7, vf7, vf7); // vaddz.y vf7, vf7, vf7
c->mov128_gpr_vf(t1, vf5); // qmfc2.i t1, vf5
c->mov128_gpr_vf(t2, vf6); // qmfc2.i t2, vf6
c->mov128_gpr_vf(v1, vf7); // qmfc2.i v1, vf7
c->or_(t1, t1, t2); // or t1, t1, t2
c->or_(v1, t1, v1); // or v1, t1, v1
bc = ((s64)c->sgpr64(v1)) < 0; // bltz v1, L11
// nop // sll r0, r0, 0
if (bc) {goto block_10;} // branch non-likely
c->vopmula(vf8, vf16); // vopmula.xyz acc, vf8, vf16
c->vopmsub(vf5, vf16, vf8); // vopmsub.xyz vf5, vf16, vf8
c->vopmula(vf16, vf5); // vopmula.xyz acc, vf16, vf5
c->vopmsub(vf5, vf5, vf16); // vopmsub.xyz vf5, vf5, vf16
c->vadd(DEST::xyzw, vf5, vf5, vf12); // vadd.xyzw vf5, vf5, vf12
c->sqc2(vf5, 0, t0); // sqc2 vf5, 0(t0)
//beq r0, r0, L15 // beq r0, r0, L15
// nop // sll r0, r0, 0
goto block_15; // branch always
block_10:
c->load_symbol2(t9, cache.collide_do_primitives); // lw t9, collide-do-primitives(s7)
call_addr = c->gprs[t9].du32[0]; // function call:
c->sll(v0, ra, 0); // sll v0, ra, 0
c->jalr(call_addr); // jalr ra, t9
c->mov64(v1, v0); // or v1, v0, r0
//beq r0, r0, L15 // beq r0, r0, L15
// nop // sll r0, r0, 0
goto block_15; // branch always
block_11:
bc = ((s64)c->sgpr64(t1)) < 0; // bltz t1, L14
// nop // sll r0, r0, 0
if (bc) {goto block_14;} // branch non-likely
block_12:
c->vsub(DEST::xyzw, vf9, vf14, vf13); // vsub.xyzw vf9, vf14, vf13
c->vsub(DEST::xyzw, vf10, vf14, vf11); // vsub.xyzw vf10, vf14, vf11
c->vopmula(vf13, vf14); // vopmula.xyz acc, vf13, vf14
c->vopmsub(vf5, vf14, vf13); // vopmsub.xyz vf5, vf14, vf13
c->vopmula(vf14, vf11); // vopmula.xyz acc, vf14, vf11
c->vopmsub(vf6, vf11, vf14); // vopmsub.xyz vf6, vf11, vf14
c->vopmula(vf9, vf10); // vopmula.xyz acc, vf9, vf10
c->vopmsub(vf7, vf10, vf9); // vopmsub.xyz vf7, vf10, vf9
c->vmul(DEST::xyzw, vf5, vf5, vf16); // vmul.xyzw vf5, vf5, vf16
c->vmul(DEST::xyzw, vf6, vf6, vf16); // vmul.xyzw vf6, vf6, vf16
c->vmul(DEST::xyzw, vf7, vf7, vf16); // vmul.xyzw vf7, vf7, vf16
c->vadd_bc(DEST::y, BC::x, vf5, vf5, vf5); // vaddx.y vf5, vf5, vf5
c->vadd_bc(DEST::y, BC::x, vf6, vf6, vf6); // vaddx.y vf6, vf6, vf6
c->vadd_bc(DEST::y, BC::x, vf7, vf7, vf7); // vaddx.y vf7, vf7, vf7
c->vadd_bc(DEST::y, BC::z, vf5, vf5, vf5); // vaddz.y vf5, vf5, vf5
c->vadd_bc(DEST::y, BC::z, vf6, vf6, vf6); // vaddz.y vf6, vf6, vf6
c->vadd_bc(DEST::y, BC::z, vf7, vf7, vf7); // vaddz.y vf7, vf7, vf7
c->mov128_gpr_vf(t1, vf5); // qmfc2.i t1, vf5
c->mov128_gpr_vf(t2, vf6); // qmfc2.i t2, vf6
c->mov128_gpr_vf(v1, vf7); // qmfc2.i v1, vf7
c->or_(t1, t1, t2); // or t1, t1, t2
c->or_(v1, t1, v1); // or v1, t1, v1
bc = ((s64)c->sgpr64(v1)) < 0; // bltz v1, L11
// nop // sll r0, r0, 0
if (bc) {goto block_10;} // branch non-likely
c->vopmula(vf14, vf16); // vopmula.xyz acc, vf14, vf16
c->vopmsub(vf5, vf16, vf14); // vopmsub.xyz vf5, vf16, vf14
c->vopmula(vf16, vf5); // vopmula.xyz acc, vf16, vf5
c->vopmsub(vf5, vf5, vf16); // vopmsub.xyz vf5, vf5, vf16
c->vadd(DEST::xyzw, vf5, vf5, vf12); // vadd.xyzw vf5, vf5, vf12
c->sqc2(vf5, 0, t0); // sqc2 vf5, 0(t0)
//beq r0, r0, L15 // beq r0, r0, L15
c->addiu(v0, r0, 0); // addiu v0, r0, 0
goto block_15; // branch always
block_14:
c->lui(v0, -13122); // lui v0, -13122
c->ori(v0, v0, 48160); // ori v0, v0, 48160
block_15:
c->ld(ra, 0, sp); // ld ra, 0(sp)
//jr ra // jr ra
c->daddiu(sp, sp, 16); // daddiu sp, sp, 16
goto end_of_function; // return
// nop // sll r0, r0, 0
// nop // sll r0, r0, 0
// nop // sll r0, r0, 0
end_of_function:
return c->gprs[v0].du64[0];
}
void link() {
cache.collide_do_primitives = intern_from_c(-1, 0, "collide-do-primitives").c();
gLinkedFunctionTable.reg("moving-sphere-triangle-intersect", execute, 512);
}
} // namespace moving_sphere_triangle_intersect
} // namespace Mips2C
// add moving_sphere_triangle_intersect::link to the link callback table for the object file.
// FWD DEC:
namespace moving_sphere_triangle_intersect { extern void link(); }
//--------------------------MIPS2C---------------------
// clang-format off
#include "game/mips2c/mips2c_private.h"
#include "game/kernel/jak3/kscheme.h"
using ::jak3::intern_from_c;
namespace Mips2C::jak3 {
namespace collide_do_primitives {
struct Cache {
void* ray_cylinder_intersect; // ray-cylinder-intersect
void* ray_sphere_intersect; // ray-sphere-intersect
} cache;
u64 execute(void* ctxt) {
auto* c = (ExecutionContext*)ctxt;
bool bc = false;
u32 call_addr = 0;
bool cop1_bc = false;
c->daddiu(sp, sp, -144); // daddiu sp, sp, -144
c->sd(ra, 0, sp); // sd ra, 0(sp)
c->sq(s1, 32, sp); // sq s1, 32(sp)
c->sq(s2, 48, sp); // sq s2, 48(sp)
c->sq(s3, 64, sp); // sq s3, 64(sp)
c->sq(s4, 80, sp); // sq s4, 80(sp)
c->sq(s5, 96, sp); // sq s5, 96(sp)
c->sq(gp, 112, sp); // sq gp, 112(sp)
c->swc1(f28, 128, sp); // swc1 f28, 128(sp)
c->swc1(f30, 132, sp); // swc1 f30, 132(sp)
c->mov64(s4, a0); // or s4, a0, r0
c->mov64(s3, a1); // or s3, a1, r0
c->mov64(s1, a2); // or s1, a2, r0
c->mov64(s5, a3); // or s5, a3, r0
c->mov64(gp, t0); // or gp, t0, r0
c->daddiu(s2, sp, 16); // daddiu s2, sp, 16
c->lui(v1, 16384); // lui v1, 16384
c->mtc1(f31, v1); // mtc1 f31, v1
c->mtc1(f28, r0); // mtc1 f28, r0
c->load_symbol2(t9, cache.ray_sphere_intersect); // lw t9, ray-sphere-intersect(s7)
c->mov64(a0, s4); // or a0, s4, r0
c->mov64(a1, s3); // or a1, s3, r0
c->daddu(a2, r0, s5); // daddu a2, r0, s5
c->mov64(a3, s1); // or a3, s1, r0
call_addr = c->gprs[t9].du32[0]; // function call:
c->sll(v0, ra, 0); // sll v0, ra, 0
c->jalr(call_addr); // jalr ra, t9
c->mov64(v1, v0); // or v1, v0, r0
c->mtc1(f30, v0); // mtc1 f30, v0
cop1_bc = c->fprs[f30] < c->fprs[f28]; // c.lt.s f30, f28
bc = cop1_bc; // bc1t L17
// nop // sll r0, r0, 0
if (bc) {goto block_2;} // branch non-likely
c->mtc1(f31, v0); // mtc1 f31, v0
c->lqc2(vf31, 0, s5); // lqc2 vf31, 0(s5)
block_2:
c->load_symbol2(t9, cache.ray_sphere_intersect); // lw t9, ray-sphere-intersect(s7)
c->mov64(a0, s4); // or a0, s4, r0
c->mov64(a1, s3); // or a1, s3, r0
c->daddiu(a2, s5, 16); // daddiu a2, s5, 16
c->mov64(a3, s1); // or a3, s1, r0
call_addr = c->gprs[t9].du32[0]; // function call:
c->sll(v0, ra, 0); // sll v0, ra, 0
c->jalr(call_addr); // jalr ra, t9
c->mov64(v1, v0); // or v1, v0, r0
c->mtc1(f30, v0); // mtc1 f30, v0
cop1_bc = c->fprs[f30] < c->fprs[f28]; // c.lt.s f30, f28
bc = cop1_bc; // bc1t L18
cop1_bc = c->fprs[f30] < c->fprs[f31]; // c.lt.s f30, f31
if (bc) {goto block_5;} // branch non-likely
bc = !cop1_bc; // bc1f L18
// nop // sll r0, r0, 0
if (bc) {goto block_5;} // branch non-likely
c->mtc1(f31, v0); // mtc1 f31, v0
c->lqc2(vf31, 16, s5); // lqc2 vf31, 16(s5)
block_5:
c->load_symbol2(t9, cache.ray_sphere_intersect); // lw t9, ray-sphere-intersect(s7)
c->mov64(a0, s4); // or a0, s4, r0
c->mov64(a1, s3); // or a1, s3, r0
c->daddiu(a2, s5, 32); // daddiu a2, s5, 32
c->mov64(a3, s1); // or a3, s1, r0
call_addr = c->gprs[t9].du32[0]; // function call:
c->sll(v0, ra, 0); // sll v0, ra, 0
c->jalr(call_addr); // jalr ra, t9
c->mov64(v1, v0); // or v1, v0, r0
c->mtc1(f30, v0); // mtc1 f30, v0
cop1_bc = c->fprs[f30] < c->fprs[f28]; // c.lt.s f30, f28
bc = cop1_bc; // bc1t L19
cop1_bc = c->fprs[f30] < c->fprs[f31]; // c.lt.s f30, f31
if (bc) {goto block_8;} // branch non-likely
bc = !cop1_bc; // bc1f L19
// nop // sll r0, r0, 0
if (bc) {goto block_8;} // branch non-likely
c->mtc1(f31, v0); // mtc1 f31, v0
c->lqc2(vf31, 32, s5); // lqc2 vf31, 32(s5)
block_8:
c->lqc2(vf1, 0, s5); // lqc2 vf1, 0(s5)
c->lqc2(vf2, 16, s5); // lqc2 vf2, 16(s5)
c->vsub(DEST::xyzw, vf2, vf2, vf1); // vsub.xyzw vf2, vf2, vf1
c->vmul(DEST::xyzw, vf3, vf2, vf2); // vmul.xyzw vf3, vf2, vf2
c->vadd_bc(DEST::x, BC::y, vf3, vf3, vf3); // vaddy.x vf3, vf3, vf3
c->vadd_bc(DEST::x, BC::z, vf3, vf3, vf3); // vaddz.x vf3, vf3, vf3
c->vrsqrt(vf0, BC::w, vf3, BC::x); // vrsqrt Q, vf0.w, vf3.x
c->mov128_gpr_vf(v1, vf3); // qmfc2.i v1, vf3
c->mtc1(f30, v1); // mtc1 f30, v1
c->sqrts(f30, f30); // sqrt.s f30, f30
c->vwaitq(); // vwaitq
c->vmulq(DEST::xyzw, vf2, vf2); // vmulq.xyzw vf2, vf2, Q
c->sqc2(vf2, 0, s2); // sqc2 vf2, 0(s2)
c->mfc1(t1, f30); // mfc1 t1, f30
c->load_symbol2(t9, cache.ray_cylinder_intersect);// lw t9, ray-cylinder-intersect(s7)
c->mov64(a0, s4); // or a0, s4, r0
c->mov64(a1, s3); // or a1, s3, r0
c->daddu(a2, r0, s5); // daddu a2, r0, s5
c->mov64(a3, s2); // or a3, s2, r0
c->mov64(t0, s1); // or t0, s1, r0
c->mov64(t2, gp); // or t2, gp, r0
call_addr = c->gprs[t9].du32[0]; // function call:
c->sll(v0, ra, 0); // sll v0, ra, 0
c->jalr(call_addr); // jalr ra, t9
c->mov64(v1, v0); // or v1, v0, r0
c->mtc1(f30, v0); // mtc1 f30, v0
cop1_bc = c->fprs[f30] < c->fprs[f28]; // c.lt.s f30, f28
bc = cop1_bc; // bc1t L20
cop1_bc = c->fprs[f30] < c->fprs[f31]; // c.lt.s f30, f31
if (bc) {goto block_11;} // branch non-likely
bc = !cop1_bc; // bc1f L20
// nop // sll r0, r0, 0
if (bc) {goto block_11;} // branch non-likely
c->mtc1(f31, v0); // mtc1 f31, v0
c->lqc2(vf31, 0, gp); // lqc2 vf31, 0(gp)
block_11:
c->lqc2(vf1, 16, s5); // lqc2 vf1, 16(s5)
c->lqc2(vf2, 32, s5); // lqc2 vf2, 32(s5)
c->vsub(DEST::xyzw, vf2, vf2, vf1); // vsub.xyzw vf2, vf2, vf1
c->vmul(DEST::xyzw, vf3, vf2, vf2); // vmul.xyzw vf3, vf2, vf2
c->vadd_bc(DEST::x, BC::y, vf3, vf3, vf3); // vaddy.x vf3, vf3, vf3
c->vadd_bc(DEST::x, BC::z, vf3, vf3, vf3); // vaddz.x vf3, vf3, vf3
c->vrsqrt(vf0, BC::w, vf3, BC::x); // vrsqrt Q, vf0.w, vf3.x
c->mov128_gpr_vf(v1, vf3); // qmfc2.i v1, vf3
c->mtc1(f30, v1); // mtc1 f30, v1
c->sqrts(f30, f30); // sqrt.s f30, f30
c->vwaitq(); // vwaitq
c->vmulq(DEST::xyzw, vf2, vf2); // vmulq.xyzw vf2, vf2, Q
c->sqc2(vf2, 0, s2); // sqc2 vf2, 0(s2)
c->mfc1(t1, f30); // mfc1 t1, f30
c->load_symbol2(t9, cache.ray_cylinder_intersect);// lw t9, ray-cylinder-intersect(s7)
c->mov64(a0, s4); // or a0, s4, r0
c->mov64(a1, s3); // or a1, s3, r0
c->daddiu(a2, s5, 16); // daddiu a2, s5, 16
c->mov64(a3, s2); // or a3, s2, r0
c->mov64(t0, s1); // or t0, s1, r0
c->mov64(t2, gp); // or t2, gp, r0
call_addr = c->gprs[t9].du32[0]; // function call:
c->sll(v0, ra, 0); // sll v0, ra, 0
c->jalr(call_addr); // jalr ra, t9
c->mov64(v1, v0); // or v1, v0, r0
c->mtc1(f30, v0); // mtc1 f30, v0
cop1_bc = c->fprs[f30] < c->fprs[f28]; // c.lt.s f30, f28
bc = cop1_bc; // bc1t L21
cop1_bc = c->fprs[f30] < c->fprs[f31]; // c.lt.s f30, f31
if (bc) {goto block_14;} // branch non-likely
bc = !cop1_bc; // bc1f L21
// nop // sll r0, r0, 0
if (bc) {goto block_14;} // branch non-likely
c->mtc1(f31, v0); // mtc1 f31, v0
c->lqc2(vf31, 0, gp); // lqc2 vf31, 0(gp)
block_14:
c->lqc2(vf1, 32, s5); // lqc2 vf1, 32(s5)
c->lqc2(vf2, 0, s5); // lqc2 vf2, 0(s5)
c->vsub(DEST::xyzw, vf2, vf2, vf1); // vsub.xyzw vf2, vf2, vf1
c->vmul(DEST::xyzw, vf3, vf2, vf2); // vmul.xyzw vf3, vf2, vf2
c->vadd_bc(DEST::x, BC::y, vf3, vf3, vf3); // vaddy.x vf3, vf3, vf3
c->vadd_bc(DEST::x, BC::z, vf3, vf3, vf3); // vaddz.x vf3, vf3, vf3
c->vrsqrt(vf0, BC::w, vf3, BC::x); // vrsqrt Q, vf0.w, vf3.x
c->mov128_gpr_vf(v1, vf3); // qmfc2.i v1, vf3
c->mtc1(f30, v1); // mtc1 f30, v1
c->sqrts(f30, f30); // sqrt.s f30, f30
c->vwaitq(); // vwaitq
c->vmulq(DEST::xyzw, vf2, vf2); // vmulq.xyzw vf2, vf2, Q
c->sqc2(vf2, 0, s2); // sqc2 vf2, 0(s2)
c->mfc1(t1, f30); // mfc1 t1, f30
c->load_symbol2(t9, cache.ray_cylinder_intersect);// lw t9, ray-cylinder-intersect(s7)
c->daddiu(a2, s5, 32); // daddiu a2, s5, 32
c->mov64(t2, gp); // or t2, gp, r0
c->mov64(a0, s4); // or a0, s4, r0
c->mov64(a1, s3); // or a1, s3, r0
c->mov64(a3, s2); // or a3, s2, r0
c->mov64(t0, s1); // or t0, s1, r0
call_addr = c->gprs[t9].du32[0]; // function call:
c->sll(v0, ra, 0); // sll v0, ra, 0
c->jalr(call_addr); // jalr ra, t9
c->mov64(v1, v0); // or v1, v0, r0
c->mtc1(f30, v0); // mtc1 f30, v0
cop1_bc = c->fprs[f30] < c->fprs[f28]; // c.lt.s f30, f28
bc = cop1_bc; // bc1t L22
cop1_bc = c->fprs[f30] < c->fprs[f31]; // c.lt.s f30, f31
if (bc) {goto block_17;} // branch non-likely
bc = !cop1_bc; // bc1f L22
// nop // sll r0, r0, 0
if (bc) {goto block_17;} // branch non-likely
c->mtc1(f31, v0); // mtc1 f31, v0
c->lqc2(vf31, 0, gp); // lqc2 vf31, 0(gp)
block_17:
c->lui(v1, 16256); // lui v1, 16256
c->mtc1(f0, v1); // mtc1 f0, v1
c->lui(v1, -13122); // lui v1, -13122
c->ori(v1, v1, 48160); // ori v1, v1, 48160
cop1_bc = c->fprs[f0] < c->fprs[f31]; // c.lt.s f0, f31
if (cop1_bc) { // bc1tl L23
c->mtc1(f31, v1); // mtc1 f31, v1
goto block_19;
}
block_19:
c->mfc1(v0, f31); // mfc1 v0, f31
c->sqc2(vf31, 0, gp); // sqc2 vf31, 0(gp)
c->ld(ra, 0, sp); // ld ra, 0(sp)
c->lwc1(f30, 132, sp); // lwc1 f30, 132(sp)
c->lwc1(f28, 128, sp); // lwc1 f28, 128(sp)
c->lq(gp, 112, sp); // lq gp, 112(sp)
c->lq(s5, 96, sp); // lq s5, 96(sp)
c->lq(s4, 80, sp); // lq s4, 80(sp)
c->lq(s3, 64, sp); // lq s3, 64(sp)
c->lq(s2, 48, sp); // lq s2, 48(sp)
c->lq(s1, 32, sp); // lq s1, 32(sp)
//jr ra // jr ra
c->daddiu(sp, sp, 144); // daddiu sp, sp, 144
goto end_of_function; // return
// nop // sll r0, r0, 0
// nop // sll r0, r0, 0
end_of_function:
return c->gprs[v0].du64[0];
}
void link() {
cache.ray_cylinder_intersect = intern_from_c(-1, 0, "ray-cylinder-intersect").c();
cache.ray_sphere_intersect = intern_from_c(-1, 0, "ray-sphere-intersect").c();
gLinkedFunctionTable.reg("collide-do-primitives", execute, 512);
}
} // namespace collide_do_primitives
} // namespace Mips2C
// add collide_do_primitives::link to the link callback table for the object file.
// FWD DEC:
namespace collide_do_primitives { extern void link(); }
+499 -3
View File
@@ -8,6 +8,491 @@
;; a joint is just used to store the tree structure of a skeleton + bind pose.
;; it's mostly used as a more user-friendly interface
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; experimental new joint decompressor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define *use-new-decompressor* #t)
;; this was re-written in GOAL. Despite being not well optimized, it ends up being faster
;; than the original.
;; request to decompress data from an animation
(deftype joint-decomp-request (structure)
((jacc joint-anim-compressed-control)
(frame int)
(frame-interp float)
(amount float))
)
(deftype blend-tree-stack-frame (structure)
((weights float 24)
(quads vector 6 :inline :overlay-at weights))
)
(deftype new-joint-decompressor-work (structure)
((requests joint-decomp-request 24 :inline)
(num-requests int32)
(blend-stack blend-tree-stack-frame 4 :inline)
)
(:methods
(eval-blend-tree! (_type_ joint-control) none)
(output-blend-tree! (_type_ joint-control) none)
(build-requests! (_type_ joint-control) none)
(init-frame! (_type_ joint-anim-frame int) none)
(process-request! (_type_ joint-decomp-request joint-anim-frame int) none)
(process-requests! (_type_ joint-anim-frame int) none)
(finalize-frame! (_type_ joint-anim-frame int) none)
)
)
(define *new-joint-decompressor-work* (new 'global 'new-joint-decompressor-work))
(defun new-joint-decompressor ((dst joint-anim-frame) (num-joints int) (jc joint-control))
"Decompress a joint animation!"
;; determine anim weights, write them out to the joint-control for other stuff to see.
(eval-blend-tree! *new-joint-decompressor-work* jc)
(output-blend-tree! *new-joint-decompressor-work* jc)
;; figure out which animations need decompression
(build-requests! *new-joint-decompressor-work* jc)
;; run the decompression
(init-frame! *new-joint-decompressor-work* dst num-joints)
(process-requests! *new-joint-decompressor-work* dst num-joints)
(finalize-frame! *new-joint-decompressor-work* dst num-joints)
(none)
)
(defmethod eval-blend-tree! ((this new-joint-decompressor-work) (jc joint-control))
"Evaluate weights of all channels, producing the final per-animation weights in the first stack-frame."
(let ((num-channels (-> jc active-channels))
(stack-top 0)
)
(when (> num-channels 24)
(break!) ;; insufficient weights per stack frame
)
;; loop over channels
(dotimes (chan-idx num-channels)
(let ((chan (-> jc channel chan-idx)))
(case (-> chan command)
(('push) ;; push new anim to stack frame
(when (> stack-top 4)
(break!) ;; insufficient stack frames.
)
;; init all weights to zero:
(let ((new-frame (-> this blend-stack stack-top)))
(vector-zero! (-> new-frame quads 0))
(vector-zero! (-> new-frame quads 1))
(vector-zero! (-> new-frame quads 2))
(vector-zero! (-> new-frame quads 3))
(vector-zero! (-> new-frame quads 4))
(vector-zero! (-> new-frame quads 5))
;; except for this channel
(set! (-> new-frame weights chan-idx) 1.0)
)
(+! stack-top 1) ;; bump stack pointer!
)
;; blend case: note that push1/stack1 always are a pair, so we can treat push1 as blend and ignore
;; the stack1 as an optimization.
(('blend 'push1)
(let* ((sf (-> this blend-stack (- stack-top 1))) ;; modify most recent stack frame
(new-weight (-> chan frame-interp))
(old-weight (- 1.0 new-weight)))
;; do the multiplies:
(rlet ((temp :class vf)
(weight-vec :class vf))
(.mov weight-vec old-weight)
(dotimes (i 6)
(.lvf temp (&-> sf quads i quad))
(.mul.x.vf temp temp weight-vec)
(.svf (&-> sf quads i quad) temp)
)
(+! (-> sf weights chan-idx) new-weight)
)
)
)
;; stack case: pop two frames, add together, push result.
(('stack)
(let* ((sf0 (-> this blend-stack (- stack-top 1)))
(sf1 (-> this blend-stack (- stack-top 2)))
(weight0 (-> chan frame-interp))
(weight1 (- 1.0 weight0)))
(rlet ((temp0 :class vf)
(temp1 :class vf)
(weight0-vec :class vf)
(weight1-vec :class vf))
(.mov weight0-vec weight0)
(.mov weight1-vec weight1)
(dotimes (i 6)
(.lvf temp0 (&-> sf0 quads i quad))
(.lvf temp1 (&-> sf1 quads i quad))
(.mul.x.vf temp0 temp0 weight0-vec)
(.mul.x.vf temp1 temp1 weight1-vec)
(.add.vf temp0 temp0 temp1)
(.svf (&-> sf1 quads i quad) temp0)
)
)
(-! stack-top 1) ;; pop stack frame
)
)
)
)
)
)
(none)
)
(defmethod output-blend-tree! ((this new-joint-decompressor-work) (jc joint-control))
"Copy result of the blend tree evaluation into the joint-control."
(let ((num-channels (-> jc active-channels)))
(dotimes (chan-idx num-channels)
(set! (-> jc channel chan-idx inspector-amount) (-> this blend-stack 0 weights chan-idx))
)
)
(none)
)
(defmethod build-requests! ((this new-joint-decompressor-work) (jc joint-control))
"Use the anim weights computed by eval-blend-tree! to build decompression requests"
(set! (-> this num-requests) 0)
(let ((num-channels (-> jc active-channels)))
(dotimes (chan-idx num-channels)
(let ((weight (-> this blend-stack 0 weights chan-idx))
(chan (-> jc channel chan-idx)))
(when (> weight 0.001) ;; only both if weight is nonzero
(let* ((req (-> this requests (-> this num-requests))) ;; request to create
(jacc (-> chan frame-group frames)) ;; compressed animation
(frame-num (-> chan frame-num)) ;; floating-point frame (eg 1.23)
(base-frame (the int frame-num)) ;; integer round-down frame (eg 1)
(frac-frame (- frame-num (the float base-frame))) ;; interp to next frame (eg 0.23)
(last-frame (the int (- (-> jacc num-frames) 1)))
)
(+! (-> this num-requests) 1)
;; check our frame group is valid
;; TODO
;; make sure we didn't go off the end of the animation:
(when (>= base-frame last-frame)
(set! frac-frame 0.0)
(set! base-frame last-frame)
)
;; set up request
(set! (-> req jacc) jacc)
(set! (-> req frame) base-frame)
(set! (-> req frame-interp) frac-frame)
(set! (-> req amount) weight)
)
)
)
)
)
(none)
)
(defmethod init-frame! ((this new-joint-decompressor-work) (output-frame joint-anim-frame) (num-joints int))
"Initialize an output frame by zeroing the data."
(let ((num-qwc 8) ;; 2x matrix, each 4 qw
(data (the (pointer uint128) output-frame)))
(when (> num-joints 2) ;; we have transformq's
(+! num-qwc (* 3 (- num-joints 2)))
)
(let ((data-end (&+ data (* num-qwc 16))))
(rlet ((zero :class vf))
(.xor.vf zero zero zero)
(while (!= data data-end) ;; this loop is 5 instructions :)
(.svf data zero)
(&+! data 16)
)
)
)
)
(none)
)
(defmethod process-requests! ((this new-joint-decompressor-work) (output-frame joint-anim-frame) (num-joints int))
"Decompress all pending animation requests."
(dotimes (i (-> this num-requests))
(process-request! this (-> this requests i) output-frame num-joints)
)
(set! (-> this num-requests) 0)
(none)
)
(defmacro fderef-s16 (ptr)
`(the float (-> (the (pointer int16) ,ptr)))
)
(defmacro deref-f32 (ptr)
`(-> (the (pointer float) ,ptr))
)
(defconstant QUAT_SCALE 0.000030517578125)
(defconstant SCALE_SCALE 0.000244140625)
(defun decomp-fixed ((output-frame joint-anim-frame) (num-joints int) (anim joint-anim-compressed-fixed) (amount float))
"Decompress the fixed part."
(let* ((mbits (-> anim hdr matrix-bits))
(data (the pointer (&-> anim data 0 quad)))
(data64 (the (pointer uint64) (&+ data (-> anim offset-64))))
(data32 (the (pointer uint32) (&+ data (-> anim offset-32))))
(data16 (the (pointer uint16) (&+ data (-> anim offset-16))))
(ctrl-ptr (-> anim hdr control-bits))
)
;; process matrix:
(when (zero? (logand mbits 1))
;; matrix comes from fixed data
(matrix-copy! (-> output-frame matrices 0) (the matrix data64))
(&+! data64 64)
)
(when (zero? (logand mbits 2))
;; matrix comes from fixed data
(matrix-copy! (-> output-frame matrices 1) (the matrix data64))
(&+! data64 64)
)
;; process tq's
(dotimes (tqi num-joints) ;; TODO - not sure if this is too many??
(let* ((ctrl-idx (/ tqi 8))
(ctrl-shift (* 4 (mod tqi 8)))
(ctrl (logand #b1111 (sar (-> ctrl-ptr ctrl-idx) ctrl-shift)))
;(tq (-> output-frame data tqi))
(tq (-> (the (inline-array transformq) (-> output-frame data)) tqi))
)
;; TRANS
(when (zero? (logand ctrl #b0001))
;; we have trans
(cond
((nonzero? (logand ctrl #b1000))
;; big trans
(+! (-> tq trans x) (* amount (deref-f32 data64)))
(&+! data64 4)
(+! (-> tq trans y) (* amount (deref-f32 data64)))
(&+! data64 4)
(+! (-> tq trans z) (* amount (deref-f32 data32)))
(&+! data32 4)
)
(else
;; little trans
(+! (-> tq trans x) (* amount (fderef-s16 data32) 4.))
(&+! data32 2)
(+! (-> tq trans y) (* amount (fderef-s16 data32) 4.))
(&+! data32 2)
(+! (-> tq trans z) (* amount (fderef-s16 data16) 4.))
(&+! data16 2)
)
)
)
;; QUAT
(when (zero? (logand ctrl #b0010))
(let ((temp (new 'stack-no-clear 'vector)))
(set! (-> temp x) (fderef-s16 data64)) (&+! data64 2)
(set! (-> temp y) (fderef-s16 data64)) (&+! data64 2)
(set! (-> temp z) (fderef-s16 data64)) (&+! data64 2)
(set! (-> temp w) (fderef-s16 data64)) (&+! data64 2)
(let ((dot (+ (* (-> temp x) (-> tq quat x))
(* (-> temp y) (-> tq quat y))
(* (-> temp z) (-> tq quat z))
(* (-> temp w) (-> tq quat w)))))
(when (< dot 0.0)
(*! (-> temp x) -1.)
(*! (-> temp y) -1.)
(*! (-> temp z) -1.)
(*! (-> temp w) -1.)
)
(+! (-> tq quat x) (* amount (-> temp x) QUAT_SCALE))
(+! (-> tq quat y) (* amount (-> temp y) QUAT_SCALE))
(+! (-> tq quat z) (* amount (-> temp z) QUAT_SCALE))
(+! (-> tq quat w) (* amount (-> temp w) QUAT_SCALE))
)
)
)
;; SCALE
(when (zero? (logand ctrl #b0100))
(+! (-> tq scale x) (* amount (fderef-s16 data32) SCALE_SCALE))
(&+! data32 2)
(+! (-> tq scale y) (* amount (fderef-s16 data32) SCALE_SCALE))
(&+! data32 2)
(+! (-> tq scale z) (* amount (fderef-s16 data16) SCALE_SCALE))
(&+! data16 2)
)
)
)
)
(none)
)
(defun decomp-frame ((output-frame joint-anim-frame) (num-joints int) (anim joint-anim-compressed-frame) (amount float) (hdr joint-anim-compressed-hdr))
"Decompress the fixed part."
(let* ((mbits (-> hdr matrix-bits))
(data (the pointer (-> anim data)))
(data64 (the (pointer uint64) (&+ data (-> anim offset-64))))
(data32 (the (pointer uint32) (&+ data (-> anim offset-32))))
(data16 (the (pointer uint16) (&+ data (-> anim offset-16))))
(ctrl-ptr (-> hdr control-bits))
)
;; process matrix:
(when (nonzero? (logand mbits 1))
;; matrix comes from fixed data
(matrix-copy! (-> output-frame matrices 0) (the matrix data64))
(&+! data64 64)
)
(when (nonzero? (logand mbits 2))
;; matrix comes from fixed data
(matrix-copy! (-> output-frame matrices 1) (the matrix data64))
(&+! data64 64)
)
;; process tq's
(dotimes (tqi num-joints) ;; TODO - not sure if this is too many??
(let* ((ctrl-idx (/ tqi 8))
(ctrl-shift (* 4 (mod tqi 8)))
(ctrl (logand #b1111 (sar (-> ctrl-ptr ctrl-idx) ctrl-shift)))
;(tq (-> output-frame data tqi))
(tq (-> (the (inline-array transformq) (-> output-frame data)) tqi))
)
;; TRANS
(when (nonzero? (logand ctrl #b0001))
;; we have trans
(cond
((nonzero? (logand ctrl #b1000))
;; big trans
(+! (-> tq trans x) (* amount (deref-f32 data64)))
(&+! data64 4)
(+! (-> tq trans y) (* amount (deref-f32 data64)))
(&+! data64 4)
(+! (-> tq trans z) (* amount (deref-f32 data32)))
(&+! data32 4)
)
(else
;; little trans
(+! (-> tq trans x) (* amount (fderef-s16 data32) 4.))
(&+! data32 2)
(+! (-> tq trans y) (* amount (fderef-s16 data32) 4.))
(&+! data32 2)
(+! (-> tq trans z) (* amount (fderef-s16 data16) 4.))
(&+! data16 2)
)
)
)
;; QUAT
(when (nonzero? (logand ctrl #b0010))
(let ((temp (new 'stack-no-clear 'vector)))
(set! (-> temp x) (fderef-s16 data64)) (&+! data64 2)
(set! (-> temp y) (fderef-s16 data64)) (&+! data64 2)
(set! (-> temp z) (fderef-s16 data64)) (&+! data64 2)
(set! (-> temp w) (fderef-s16 data64)) (&+! data64 2)
(let ((dot (+ (* (-> temp x) (-> tq quat x))
(* (-> temp y) (-> tq quat y))
(* (-> temp z) (-> tq quat z))
(* (-> temp w) (-> tq quat w)))))
(when (< dot 0.0)
(*! (-> temp x) -1.)
(*! (-> temp y) -1.)
(*! (-> temp z) -1.)
(*! (-> temp w) -1.)
)
(+! (-> tq quat x) (* amount (-> temp x) QUAT_SCALE))
(+! (-> tq quat y) (* amount (-> temp y) QUAT_SCALE))
(+! (-> tq quat z) (* amount (-> temp z) QUAT_SCALE))
(+! (-> tq quat w) (* amount (-> temp w) QUAT_SCALE))
)
)
)
;; SCALE
(when (nonzero? (logand ctrl #b0100))
(+! (-> tq scale x) (* amount (fderef-s16 data32) SCALE_SCALE))
(&+! data32 2)
(+! (-> tq scale y) (* amount (fderef-s16 data32) SCALE_SCALE))
(&+! data32 2)
(+! (-> tq scale z) (* amount (fderef-s16 data16) SCALE_SCALE))
(&+! data16 2)
)
)
)
)
(none)
)
(defmethod process-request! ((this new-joint-decompressor-work) (request joint-decomp-request) (output-frame joint-anim-frame) (num-joints int))
"Decompress a single animation, adding to accumulator"
;; first, the fixed part
(decomp-fixed output-frame num-joints (-> request jacc fixed) (-> request amount))
;; base frame
(decomp-frame
output-frame
num-joints
(-> request jacc data (-> request frame))
(* (- 1.0 (-> request frame-interp)) (-> request amount))
(-> request jacc fixed hdr)
)
;; interpolate to next frame
(cond
((!= 0.0 (-> request frame-interp))
(decomp-frame
output-frame
num-joints
(-> request jacc data (+ 1 (-> request frame)))
(* (-> request frame-interp) (-> request amount))
(-> request jacc fixed hdr))
)
(else
)
)
(none)
)
(defmethod finalize-frame! ((this new-joint-decompressor-work) (output-frame joint-anim-frame) (num-joints int))
(when (<= num-joints 2)
(return #f)
)
(dotimes (tqi (- num-joints 2))
(let ((tq (-> (the (inline-array transformq) (-> output-frame data)) tqi)))
(set! (-> tq trans w) 1.0)
(set! (-> tq scale w) 1.0)
(quaternion-normalize! (-> tq quat))
)
)
(none)
)
;; DECOMP BEGINS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -975,6 +1460,7 @@
(defun matrix-from-control! ((arg0 matrix-stack) (arg1 joint) (arg2 joint-control) (arg3 symbol))
(set! (-> arg0 top) (the-as matrix (-> arg0 data)))
;(set! arg3 'a)
(dotimes (s2-0 (-> arg2 active-channels))
(let* ((a2-1 (-> arg2 channel s2-0))
(v1-4 (-> a2-1 command))
@@ -1006,6 +1492,7 @@
((= v1-4 'push)
(matrix-from-control-channel! (-> arg0 top) arg1 a2-1)
(set! (-> arg0 top) (the-as matrix (+ (the-as uint (-> arg0 top)) s1-0)))
;(return (-> arg0 data 0))
)
((or (= v1-4 'blend) (= v1-4 'push1))
(matrix-from-control-pair!
@@ -1456,8 +1943,17 @@
(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))
(make-joint-jump-tables)
(calc-animation-from-spr arg0 arg1)
(cond
(*use-new-decompressor*
(new-joint-decompressor (the joint-anim-frame arg0) arg1 (-> arg2 skel))
)
(else
(flatten-joint-control-to-spr (-> arg2 skel))
(make-joint-jump-tables)
(calc-animation-from-spr arg0 arg1)
)
)
0
)
+1 -1
View File
@@ -181,7 +181,7 @@
)
)
(defglobalconstant EE_SECONDS_PER_TICK (/ 1.0 3000000)) ;; 300MHz is a "decent enough" estimate
(defglobalconstant EE_SECONDS_PER_TICK (/ 1.0 300000000)) ;; 300MHz is a "decent enough" estimate
(defmacro cpu-ticks-to-seconds (ticks)
`(* ,EE_SECONDS_PER_TICK ,ticks)
)
+534 -10
View File
@@ -8,6 +8,512 @@
(define-extern create-interpolated-joint-animation-frame (function joint-anim-frame int joint-control int))
(define-extern *anim-manager* art-joint-anim-manager)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; experimental new joint decompressor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define *use-new-decompressor* #t)
;; this was re-written in GOAL. Despite being not well optimized, it ends up being faster
;; than the original when decompiled with MIPS2C.
;; request to decompress data from an animation
(deftype joint-decomp-request (structure)
((jacc joint-anim-compressed-control)
(frame int)
(frame-interp float)
(amount float))
)
(deftype blend-tree-stack-frame (structure)
((weights float 24)
(quads vector 6 :inline :overlay-at weights))
)
(deftype new-joint-decompressor-work (structure)
((requests joint-decomp-request 24 :inline)
(num-requests int32)
(blend-stack blend-tree-stack-frame 4 :inline)
)
(:methods
(eval-blend-tree! (_type_ joint-control) none)
(output-blend-tree! (_type_ joint-control) none)
(build-requests! (_type_ joint-control) none)
(init-frame! (_type_ joint-anim-frame int) none)
(process-request! (_type_ joint-decomp-request joint-anim-frame int) none)
(process-requests! (_type_ joint-anim-frame int) none)
(finalize-frame! (_type_ joint-anim-frame int) none)
)
)
(deftype new-joint-decompressor-stats (structure)
((num-calls int32)
(num-anims int32)
(num-joints int32)
(total-time int32)
)
(:methods
(reset! (_type_) none)
)
)
(defmethod reset! ((this new-joint-decompressor-stats))
(set! (-> this num-calls) 0)
(set! (-> this num-anims) 0)
(set! (-> this num-joints) 0)
(set! (-> this total-time) 0)
(none)
)
(define *new-joint-decompressor-stats* (new 'global 'new-joint-decompressor-stats))
(define *new-joint-decompressor-work* (new 'global 'new-joint-decompressor-work))
(defun new-joint-decompressor ((dst joint-anim-frame) (num-joints int) (jc joint-control))
"Decompress a joint animation!"
(+! (-> *new-joint-decompressor-stats* num-calls) 1)
;; determine anim weights, write them out to the joint-control for other stuff to see.
(eval-blend-tree! *new-joint-decompressor-work* jc)
(output-blend-tree! *new-joint-decompressor-work* jc)
;; figure out which animations need decompression
(build-requests! *new-joint-decompressor-work* jc)
;; run the decompression
(init-frame! *new-joint-decompressor-work* dst num-joints)
(process-requests! *new-joint-decompressor-work* dst num-joints)
(finalize-frame! *new-joint-decompressor-work* dst num-joints)
(none)
)
(defmethod eval-blend-tree! ((this new-joint-decompressor-work) (jc joint-control))
"Evaluate weights of all channels, producing the final per-animation weights in the first stack-frame."
(let ((num-channels (+ (-> jc active-channels) (-> jc float-channels)))
(stack-top 0)
)
(when (> num-channels 24)
(break!) ;; insufficient weights per stack frame
)
;; loop over channels
(dotimes (chan-idx num-channels)
(let ((chan (-> jc channel chan-idx)))
(case (-> chan command)
(((joint-control-command push)) ;; push new anim to stack frame
(when (> stack-top 4)
(break!) ;; insufficient stack frames.
)
;; init all weights to zero:
(let ((new-frame (-> this blend-stack stack-top)))
(vector-zero! (-> new-frame quads 0))
(vector-zero! (-> new-frame quads 1))
(vector-zero! (-> new-frame quads 2))
(vector-zero! (-> new-frame quads 3))
(vector-zero! (-> new-frame quads 4))
(vector-zero! (-> new-frame quads 5))
;; except for this channel
(set! (-> new-frame weights chan-idx) 1.0)
)
(+! stack-top 1) ;; bump stack pointer!
)
;; blend case: note that push1/stack1 always are a pair, so we can treat push1 as blend and ignore
;; the stack1 as an optimization.
(((joint-control-command blend) (joint-control-command push1) (joint-control-command float))
(let* ((sf (-> this blend-stack (- stack-top 1))) ;; modify most recent stack frame
(new-weight (-> chan frame-interp (-> jc active-frame-interp)))
(old-weight (- 1.0 new-weight)))
;; do the multiplies:
(rlet ((temp :class vf)
(weight-vec :class vf))
(.mov weight-vec old-weight)
(dotimes (i 6)
(.lvf temp (&-> sf quads i quad))
(.mul.x.vf temp temp weight-vec)
(.svf (&-> sf quads i quad) temp)
)
(+! (-> sf weights chan-idx) new-weight)
)
)
)
;; stack case: pop two frames, add together, push result.
(((joint-control-command stack))
(let* ((sf0 (-> this blend-stack (- stack-top 1)))
(sf1 (-> this blend-stack (- stack-top 2)))
(weight0 (-> chan frame-interp (-> jc active-frame-interp)))
(weight1 (- 1.0 weight0)))
(rlet ((temp0 :class vf)
(temp1 :class vf)
(weight0-vec :class vf)
(weight1-vec :class vf))
(.mov weight0-vec weight0)
(.mov weight1-vec weight1)
(dotimes (i 6)
(.lvf temp0 (&-> sf0 quads i quad))
(.lvf temp1 (&-> sf1 quads i quad))
(.mul.x.vf temp0 temp0 weight0-vec)
(.mul.x.vf temp1 temp1 weight1-vec)
(.add.vf temp0 temp0 temp1)
(.svf (&-> sf1 quads i quad) temp0)
)
)
(-! stack-top 1) ;; pop stack frame
)
)
)
)
)
)
(none)
)
(defmethod output-blend-tree! ((this new-joint-decompressor-work) (jc joint-control))
"Copy result of the blend tree evaluation into the joint-control."
(let ((num-channels (+ (-> jc active-channels) (-> jc float-channels))))
(dotimes (chan-idx num-channels)
(set! (-> jc channel chan-idx inspector-amount)
(the int (* 255.0 (-> this blend-stack 0 weights chan-idx))))
)
)
(none)
)
(defmethod build-requests! ((this new-joint-decompressor-work) (jc joint-control))
"Use the anim weights computed by eval-blend-tree! to build decompression requests"
(set! (-> this num-requests) 0)
(let ((num-channels (+ (-> jc active-channels) (-> jc float-channels))))
(dotimes (chan-idx num-channels)
(let ((weight (-> this blend-stack 0 weights chan-idx))
(chan (-> jc channel chan-idx)))
(when (> weight 0.001) ;; only both if weight is nonzero
(let* ((req (-> this requests (-> this num-requests))) ;; request to create
(jacc (-> chan frame-group frames)) ;; compressed animation
(frame-num (-> chan frame-num)) ;; floating-point frame (eg 1.23)
(base-frame (the int frame-num)) ;; integer round-down frame (eg 1)
(frac-frame (- frame-num (the float base-frame))) ;; interp to next frame (eg 0.23)
(last-frame (the int (- (-> jacc num-frames) 1)))
)
(+! (-> this num-requests) 1)
;; check our frame group is valid
;; TODO
;; make sure we didn't go off the end of the animation:
(when (>= base-frame last-frame)
(set! frac-frame 0.0)
(set! base-frame last-frame)
)
;; set up request
(set! (-> req jacc) jacc)
(set! (-> req frame) base-frame)
(set! (-> req frame-interp) frac-frame)
(set! (-> req amount) weight)
)
)
)
)
)
(none)
)
(defmethod init-frame! ((this new-joint-decompressor-work) (output-frame joint-anim-frame) (num-joints int))
"Initialize an output frame by zeroing the data."
(let ((num-qwc 8) ;; 2x matrix, each 4 qw
(data (the (pointer uint128) output-frame)))
(when (> num-joints 2) ;; we have transformq's
(+! num-qwc (* 3 (- num-joints 2)))
)
(let ((data-end (&+ data (* num-qwc 16))))
(rlet ((zero :class vf))
(.xor.vf zero zero zero)
(while (!= data data-end) ;; this loop is 5 instructions :)
(.svf data zero)
(&+! data 16)
)
)
)
)
(none)
)
(defmethod process-requests! ((this new-joint-decompressor-work) (output-frame joint-anim-frame) (num-joints int))
"Decompress all pending animation requests."
(dotimes (i (-> this num-requests))
(process-request! this (-> this requests i) output-frame num-joints)
)
(set! (-> this num-requests) 0)
(none)
)
(defmacro fderef-s16 (ptr)
`(the float (-> (the (pointer int16) ,ptr)))
)
(defmacro deref-f32 (ptr)
`(-> (the (pointer float) ,ptr))
)
(defconstant QUAT_SCALE 0.000030517578125)
(defconstant SCALE_SCALE 0.000244140625)
(defun decomp-fixed ((output-frame joint-anim-frame) (num-joints int) (anim joint-anim-compressed-fixed) (amount float))
"Decompress the fixed part."
(let* ((mbits (-> anim hdr matrix-bits))
(data (the pointer (&-> anim data 0 quad)))
(data64 (the (pointer uint64) (&+ data (-> anim offset-64))))
(data32 (the (pointer uint32) (&+ data (-> anim offset-32))))
(data16 (the (pointer uint16) (&+ data (-> anim offset-16))))
(ctrl-ptr (-> anim hdr control-bits))
)
;; process matrix:
(when (zero? (logand mbits 1))
;; matrix comes from fixed data
(matrix-copy! (-> output-frame matrices 0) (the matrix data64))
(&+! data64 64)
)
(when (zero? (logand mbits 2))
;; matrix comes from fixed data
(matrix-copy! (-> output-frame matrices 1) (the matrix data64))
(&+! data64 64)
)
;; process tq's
(dotimes (tqi num-joints) ;; TODO - not sure if this is too many??
(let* ((ctrl-idx (/ tqi 8))
(ctrl-shift (* 4 (mod tqi 8)))
(ctrl (logand #b1111 (sar (-> ctrl-ptr ctrl-idx) ctrl-shift)))
(tq (-> output-frame data tqi))
)
;; TRANS
(when (zero? (logand ctrl #b0001))
;; we have trans
(cond
((nonzero? (logand ctrl #b1000))
;; big trans
(+! (-> tq trans x) (* amount (deref-f32 data64)))
(&+! data64 4)
(+! (-> tq trans y) (* amount (deref-f32 data64)))
(&+! data64 4)
(+! (-> tq trans z) (* amount (deref-f32 data32)))
(&+! data32 4)
)
(else
;; little trans
(+! (-> tq trans x) (* amount (fderef-s16 data32) 4.))
(&+! data32 2)
(+! (-> tq trans y) (* amount (fderef-s16 data32) 4.))
(&+! data32 2)
(+! (-> tq trans z) (* amount (fderef-s16 data16) 4.))
(&+! data16 2)
)
)
)
;; QUAT
(when (zero? (logand ctrl #b0010))
(let ((temp (new 'stack-no-clear 'vector)))
(set! (-> temp x) (fderef-s16 data64)) (&+! data64 2)
(set! (-> temp y) (fderef-s16 data64)) (&+! data64 2)
(set! (-> temp z) (fderef-s16 data64)) (&+! data64 2)
(set! (-> temp w) (fderef-s16 data64)) (&+! data64 2)
(let ((dot (+ (* (-> temp x) (-> tq quat x))
(* (-> temp y) (-> tq quat y))
(* (-> temp z) (-> tq quat z))
(* (-> temp w) (-> tq quat w)))))
(when (< dot 0.0)
(*! (-> temp x) -1.)
(*! (-> temp y) -1.)
(*! (-> temp z) -1.)
(*! (-> temp w) -1.)
)
(+! (-> tq quat x) (* amount (-> temp x) QUAT_SCALE))
(+! (-> tq quat y) (* amount (-> temp y) QUAT_SCALE))
(+! (-> tq quat z) (* amount (-> temp z) QUAT_SCALE))
(+! (-> tq quat w) (* amount (-> temp w) QUAT_SCALE))
)
)
)
;; SCALE
(when (zero? (logand ctrl #b0100))
(+! (-> tq scale x) (* amount (fderef-s16 data32) SCALE_SCALE))
(&+! data32 2)
(+! (-> tq scale y) (* amount (fderef-s16 data32) SCALE_SCALE))
(&+! data32 2)
(+! (-> tq scale z) (* amount (fderef-s16 data16) SCALE_SCALE))
(&+! data16 2)
)
)
)
)
(none)
)
(defun decomp-frame ((output-frame joint-anim-frame) (num-joints int) (anim joint-anim-compressed-frame) (amount float) (hdr joint-anim-compressed-hdr))
"Decompress the fixed part."
(let* ((mbits (-> hdr matrix-bits))
(data (the pointer (-> anim data)))
(data64 (the (pointer uint64) (&+ data (-> anim offset-64))))
(data32 (the (pointer uint32) (&+ data (-> anim offset-32))))
(data16 (the (pointer uint16) (&+ data (-> anim offset-16))))
(ctrl-ptr (-> hdr control-bits))
)
;; process matrix:
(when (nonzero? (logand mbits 1))
;; matrix comes from fixed data
(matrix-copy! (-> output-frame matrices 0) (the matrix data64))
(&+! data64 64)
)
(when (nonzero? (logand mbits 2))
;; matrix comes from fixed data
(matrix-copy! (-> output-frame matrices 1) (the matrix data64))
(&+! data64 64)
)
;; process tq's
(dotimes (tqi num-joints) ;; TODO - not sure if this is too many??
(let* ((ctrl-idx (/ tqi 8))
(ctrl-shift (* 4 (mod tqi 8)))
(ctrl (logand #b1111 (sar (-> ctrl-ptr ctrl-idx) ctrl-shift)))
(tq (-> output-frame data tqi))
)
;; TRANS
(when (nonzero? (logand ctrl #b0001))
;; we have trans
(cond
((nonzero? (logand ctrl #b1000))
;; big trans
(+! (-> tq trans x) (* amount (deref-f32 data64)))
(&+! data64 4)
(+! (-> tq trans y) (* amount (deref-f32 data64)))
(&+! data64 4)
(+! (-> tq trans z) (* amount (deref-f32 data32)))
(&+! data32 4)
)
(else
;; little trans
(+! (-> tq trans x) (* amount (fderef-s16 data32) 4.))
(&+! data32 2)
(+! (-> tq trans y) (* amount (fderef-s16 data32) 4.))
(&+! data32 2)
(+! (-> tq trans z) (* amount (fderef-s16 data16) 4.))
(&+! data16 2)
)
)
)
;; QUAT
(when (nonzero? (logand ctrl #b0010))
(let ((temp (new 'stack-no-clear 'vector)))
(set! (-> temp x) (fderef-s16 data64)) (&+! data64 2)
(set! (-> temp y) (fderef-s16 data64)) (&+! data64 2)
(set! (-> temp z) (fderef-s16 data64)) (&+! data64 2)
(set! (-> temp w) (fderef-s16 data64)) (&+! data64 2)
(let ((dot (+ (* (-> temp x) (-> tq quat x))
(* (-> temp y) (-> tq quat y))
(* (-> temp z) (-> tq quat z))
(* (-> temp w) (-> tq quat w)))))
(when (< dot 0.0)
(*! (-> temp x) -1.)
(*! (-> temp y) -1.)
(*! (-> temp z) -1.)
(*! (-> temp w) -1.)
)
(+! (-> tq quat x) (* amount (-> temp x) QUAT_SCALE))
(+! (-> tq quat y) (* amount (-> temp y) QUAT_SCALE))
(+! (-> tq quat z) (* amount (-> temp z) QUAT_SCALE))
(+! (-> tq quat w) (* amount (-> temp w) QUAT_SCALE))
)
)
)
;; SCALE
(when (nonzero? (logand ctrl #b0100))
(+! (-> tq scale x) (* amount (fderef-s16 data32) SCALE_SCALE))
(&+! data32 2)
(+! (-> tq scale y) (* amount (fderef-s16 data32) SCALE_SCALE))
(&+! data32 2)
(+! (-> tq scale z) (* amount (fderef-s16 data16) SCALE_SCALE))
(&+! data16 2)
)
)
)
)
(none)
)
(defmethod process-request! ((this new-joint-decompressor-work) (request joint-decomp-request) (output-frame joint-anim-frame) (num-joints int))
"Decompress a single animation, adding to accumulator"
(+! (-> *new-joint-decompressor-stats* num-anims) 1)
(+! (-> *new-joint-decompressor-stats* num-joints) (+ num-joints 2))
;; first, the fixed part
(decomp-fixed output-frame num-joints (-> request jacc fixed) (-> request amount))
;; base frame
(decomp-frame
output-frame
num-joints
(-> request jacc data (-> request frame))
(* (- 1.0 (-> request frame-interp)) (-> request amount))
(-> request jacc fixed hdr)
)
;; interpolate to next frame
(cond
((!= 0.0 (-> request frame-interp))
(decomp-frame
output-frame
num-joints
(-> request jacc data (+ 1 (-> request frame)))
(* (-> request frame-interp) (-> request amount))
(-> request jacc fixed hdr))
)
(else
)
)
(none)
)
(defmethod finalize-frame! ((this new-joint-decompressor-work) (output-frame joint-anim-frame) (num-joints int))
(when (<= num-joints 2)
(return #f)
)
(dotimes (tqi (- num-joints 2))
(let ((tq (-> output-frame data tqi)))
(set! (-> tq trans w) 1.0)
(set! (-> tq scale w) 1.0)
(quaternion-normalize! (-> tq quat))
)
)
(none)
)
;; DECOMP BEGINS
(defmethod print ((this joint))
@@ -1537,10 +2043,25 @@
(def-mips2c calc-animation-from-spr (function joint-anim-frame int none))
(defun create-interpolated-joint-animation-frame ((arg0 joint-anim-frame) (arg1 int) (arg2 joint-control))
(flatten-joint-control-to-spr arg2)
(make-joint-jump-tables)
(calc-animation-from-spr arg0 arg1)
(defun create-interpolated-joint-animation-frame ((output-frame joint-anim-frame) (arg1 int) (arg2 joint-control))
(let ((start (get-cpu-clock)))
(cond
(*use-new-decompressor*
(new-joint-decompressor output-frame arg1 arg2)
)
(else
(flatten-joint-control-to-spr arg2)
(make-joint-jump-tables)
(calc-animation-from-spr output-frame arg1)
)
)
(+! (-> *new-joint-decompressor-stats* total-time)
(the int (* 1000000. (cpu-ticks-to-seconds (- (get-cpu-clock) start))))
)
)
0
)
@@ -1549,9 +2070,10 @@
(return (create-interpolated-joint-animation-frame arg0 arg1 arg2))
)
(set! (-> arg2 active-frame-interp) (the-as uint 1))
(flatten-joint-control-to-spr arg2)
(make-joint-jump-tables)
(calc-animation-from-spr arg0 arg1)
(create-interpolated-joint-animation-frame arg0 arg1 arg2)
;(flatten-joint-control-to-spr arg2)
;(make-joint-jump-tables)
;(calc-animation-from-spr arg0 arg1)
;; happens during gun stuff, seems to work.
; (format 0 "create-interpolated2-joint-animation-frame: untested copy~%")
(ultimate-memcpy (the-as pointer *gsf-buffer*) (the-as pointer arg0) (the-as uint (+ (* 48 arg1) 128)))
@@ -1562,9 +2084,11 @@
; #f
; )
(set! (-> arg2 active-frame-interp) (the-as uint 0))
(flatten-joint-control-to-spr arg2)
(make-joint-jump-tables)
(calc-animation-from-spr arg0 arg1)
;(flatten-joint-control-to-spr arg2)
;(make-joint-jump-tables)
;;(calc-animation-from-spr arg0 arg1)
(create-interpolated-joint-animation-frame arg0 arg1 arg2)
(let ((v1-9 (the-as joint-anim-frame *gsf-buffer*)))
(let ((a0-8 (-> arg2 interp-select 0)))
(dotimes (a1-5 2)
@@ -3501,6 +3501,7 @@
(flag "Blerc" *stats-blerc* dm-boolean-toggle-pick-func)
(flag "Profile bars" *stats-profile-bars* dm-boolean-toggle-pick-func)
(flag "Perf" *stats-perf* dm-boolean-toggle-pick-func)
(flag "Joint" *stats-joint* dm-boolean-toggle-pick-func)
(menu
"Memory Stats"
(flag "Enable" *stats-memory* dm-boolean-toggle-pick-func)
+8
View File
@@ -1647,6 +1647,14 @@
(if (and (!= *master-mode* 'menu) *stats-collide*)
(print-collide-stats)
)
(when (and (!= *master-mode* 'menu) *stats-joint*)
(format *stdcon* "joint calls: ~D~%" (-> *new-joint-decompressor-stats* num-calls))
(format *stdcon* "joint anims: ~D~%" (-> *new-joint-decompressor-stats* num-anims))
(format *stdcon* "joint joints: ~D~%" (-> *new-joint-decompressor-stats* num-joints))
(format *stdcon* "joint time us: ~D~%" (-> *new-joint-decompressor-stats* total-time))
(reset! *new-joint-decompressor-stats*)
)
)
(start-perf-stat-collection)
+3
View File
@@ -124,6 +124,9 @@
(define-extern set-blackout-frames (function time-frame none))
;; added
(define *stats-joint* #f)
;; DECOMP BEGINS
+1
View File
@@ -47,6 +47,7 @@
(defun matrix-copy! ((arg0 matrix) (arg1 matrix))
"Copy arg1 to arg0"
(declare (inline))
(let ((v1-0 (-> arg1 quad 0))
(a2-0 (-> arg1 quad 1))
(a3-0 (-> arg1 quad 2))
+1 -1
View File
@@ -171,7 +171,7 @@
)
)
(defglobalconstant EE_SECONDS_PER_TICK (/ 1.0 3000000)) ;; 300MHz is a "decent enough" estimate
(defglobalconstant EE_SECONDS_PER_TICK (/ 1.0 300000000)) ;; 300MHz is a "decent enough" estimate
(defmacro cpu-ticks-to-seconds (ticks)
`(* ,EE_SECONDS_PER_TICK ,ticks)
)
+3 -3
View File
@@ -108,13 +108,13 @@ Multiple channels are used to blend animations together."
(interp-select int64 2)
(top-anim top-anim-joint-control)
(override (array float))
(channel joint-control-channel :dynamic)
(channel joint-control-channel :inline :dynamic)
)
(:methods
(new (symbol type) _type_)
(new (symbol type int) _type_)
(joint-control-method-9 () none)
(joint-control-method-10 () none)
(joint-control-method-11 () none)
(debug-print-channels (_type_ symbol) int)
(joint-control-method-12 () none)
)
)
File diff suppressed because it is too large Load Diff
+397 -1
View File
@@ -5,5 +5,401 @@
;; name in dgo: collide-func
;; dgos: GAME
;; DECOMP BEGINS
;; Note: this file is entirely identical from jak 2 and copied from there -
;; this is heavily modified from the original implementation and this shouldn't be updated by the decompiler.
#|@file
This file contains the primitive intersection functions used for collision.
Most take a description of primitive and a "probe"
The probe has an origin and a direction. The length of the direction vector is the length
of the probe.
Generally, collision functions will return the fraction of the probe to reach the primitive.
For example, if the probe is 5.0 long, and hits the primitive 2.0 away from the probe origin,
the return value (u) would be 0.4.
If (u) would be > 1.0, then it counts as "not intersecting" (object too far away)
If (u) would be < 0.0, then it counts as "not intersecting" (object behind probe)
If there's a miss, return COLLISION_MISS, a large negative number.
If we are inside of the primitive, return 0.0
|#
(defconstant COLLISION_MISS -100000000.0)
(defun raw-ray-sphere-intersect ((arg0 float))
"DANGER: this function takes two arguments by vf registers.
As a result, it doesn't work properly in OpenGOAL. See the functions below."
(local-vars
(v1-1 float)
(v1-2 float)
(v1-4 number)
(a0-1 float)
(a0-2 float)
(a0-3 int)
(a1-0 float)
)
(crash!)
(rlet ((Q :class vf)
(vf0 :class vf)
(vf1 :class vf)
(vf2 :class vf)
(vf3 :class vf)
(vf4 :class vf)
(vf5 :class vf)
(vf6 :class vf)
(vf7 :class vf)
(vf8 :class vf)
(vf9 :class vf)
)
(init-vf0-vector)
(.mov vf3 arg0) ;; vf3 = radius
;; sphere is at the origin, vf1 is source of the ray (o)
;; vf2 is the ray's unit vector (u)
(.mul.vf vf4 vf2 vf2) ;; vf4 = u.^2
(.mul.vf vf3 vf3 vf3) ;; vf3 = r^2
(.mul.vf vf6 vf1 vf1) ;; vf6 = o.^2
(.mul.vf vf5 vf2 vf1) ;; vf5 = u . o
(.add.y.vf vf4 vf4 vf4 :mask #b1)
(let ((result (the-as float 0)))
(.add.x.vf vf6 vf6 vf6 :mask #b10)
(.sub.x.vf vf6 vf6 vf3 :mask #b100)
(.add.z.vf vf4 vf4 vf4 :mask #b1)
(.add.x.vf vf5 vf5 vf5 :mask #b10)
(let ((v1-0 (the-as float 0)))
(.add.z.vf vf6 vf6 vf6 :mask #b10)
(.div.vf Q vf0 vf4 :fsf #b11 :ftf #b0)
(.add.z.vf vf5 vf5 vf5 :mask #b10)
(.mov a0-1 vf4)
(.mul.x.vf vf7 vf6 vf4)
(.mov a1-0 vf6)
(.mul.vf vf8 vf5 vf5)
(b! (< (the-as int a1-0) 0) cfg-7 :delay (set! a0-2 a0-1))
(.mul.vf vf4 vf0 Q :mask #b1000)
(.sub.vf vf9 vf8 vf7)
(b! (= a0-2 v1-0) cfg-6 :delay (.mov v1-1 vf5))
)
(.sqrt.vf Q vf9 :ftf #b1)
(b! (>= (the-as int v1-1) 0) cfg-6 :delay (.mov v1-2 vf9))
(b! (< (the-as int v1-2) 0) cfg-6 :delay 1.0)
(.add.x.vf vf6 vf5 vf4)
(.mov v1-4 vf6)
(.mul.vf vf6 vf6 vf6)
(.mul.vf vf9 vf0 Q :mask #b1000)
(.sub.vf vf6 vf9 vf6)
(.add.w.vf vf9 vf5 vf9 :mask #b10)
(.mov a0-3 vf6)
(.mul.w.vf vf9 vf9 vf4 :mask #b10)
(b!
(< (logand (the-as uint v1-4) (the-as uint a0-3)) 0)
cfg-6
:delay
(.sub.y.vf vf4 vf0 vf9)
)
(b! #t cfg-7 :delay (.mov result vf4))
(label cfg-6)
(set! result -100000000.0)
(label cfg-7)
(the-as float result)
)
)
)
(defmacro pc-port-do-raw-ray-sphere-intersect (rad vf1-val vf2-val)
"Calls to raw-ray-sphere-intersect should be replaced with this macro,
and this should be given vf1, vf2, which contain the origin and direction of the probe."
`(let ((vf1-storage (new 'stack-no-clear 'vector))
(vf2-storage (new 'stack-no-clear 'vector))
)
(.svf (&-> vf1-storage quad) ,vf1-val)
(.svf (&-> vf2-storage quad) ,vf2-val)
(pc-port-raw-ray-sphere-implementation ,rad vf1-storage vf2-storage)
)
)
(defun pc-port-raw-ray-sphere-implementation ((rad float) (vf1-val vector) (vf2-val vector))
"This is one of the main primitives for collision.
Assumes a sphere of radius rad is at the origin.
Handles:
- miss (return MISS)
- behind (return MISS)
- too far away (return MISS)
- inside (return 0)
"
(local-vars
(v1-1 int)
(v1-2 int)
(v1-4 int)
(a0-1 float)
(a0-2 float)
(a0-3 int)
(a1-0 int)
)
(rlet ((Q :class vf)
(vf0 :class vf)
(vf1 :class vf)
(vf2 :class vf)
(vf3 :class vf)
(vf4 :class vf)
(vf5 :class vf)
(vf6 :class vf)
(vf7 :class vf)
(vf8 :class vf)
(vf9 :class vf)
)
(init-vf0-vector)
(.lvf vf1 (&-> vf1-val quad))
(.lvf vf2 (&-> vf2-val quad))
(.mov vf3 rad)
(.mul.vf vf4 vf2 vf2)
(.mul.vf vf3 vf3 vf3)
(.mul.vf vf6 vf1 vf1)
(.mul.vf vf5 vf2 vf1)
(.add.y.vf vf4 vf4 vf4 :mask #b1)
(let ((result (the-as float 0)))
(.add.x.vf vf6 vf6 vf6 :mask #b10)
(.sub.x.vf vf6 vf6 vf3 :mask #b100)
(.add.z.vf vf4 vf4 vf4 :mask #b1)
(.add.x.vf vf5 vf5 vf5 :mask #b10)
(let ((v1-0 (the-as float 0)))
(.add.z.vf vf6 vf6 vf6 :mask #b10)
(.div.vf Q vf0 vf4 :fsf #b11 :ftf #b0)
(.add.z.vf vf5 vf5 vf5 :mask #b10)
(.mov a0-1 vf4)
(.mul.x.vf vf7 vf6 vf4)
(.mov a1-0 vf6)
(.mul.vf vf8 vf5 vf5)
(b! (< (the-as int a1-0) 0) cfg-7 :delay (set! a0-2 a0-1)) ;; in the sphere
(.mul.vf vf4 vf0 Q :mask #b1000)
(.sub.vf vf9 vf8 vf7)
(b! (= a0-2 v1-0) cfg-6 :delay (.mov v1-1 vf5)) ;; bad denominator in division
)
(.sqrt.vf Q vf9 :ftf #b1)
(b! (>= (the-as int v1-1) 0) cfg-6 :delay (.mov v1-2 vf9)) ;; wrong dir
(b! (< (the-as int v1-2) 0) cfg-6 :delay 1.0) ;; bad sqrt
(.add.x.vf vf6 vf5 vf4)
(.mov v1-4 vf6)
(.mul.vf vf6 vf6 vf6)
(.mul.vf vf9 vf0 Q :mask #b1000)
(.sub.vf vf6 vf9 vf6)
(.add.w.vf vf9 vf5 vf9 :mask #b10)
(.mov a0-3 vf6)
(.mul.w.vf vf9 vf9 vf4 :mask #b10)
;; too far.
(b! (< (logand (the-as int v1-4) (the-as int a0-3)) 0)
cfg-6
:delay (.sub.y.vf vf4 vf0 vf9)
)
(b! #t cfg-7 :delay (.mov result vf4))
(label cfg-6)
(set! result -100000000.0)
(label cfg-7)
(the-as float result)
)
)
)
(defun ray-sphere-intersect ((ray-origin vector) (ray-dir vector) (sph-origin vector) (radius float))
"Intersect a ray and sphere. Will return 0 if you are in the sphere, -huge number if you don't hit it.
Returns the length of the ray to the first intersection."
;; offset stuff as if the sphere is at the origin.
(rlet ((vf1 :class vf)
(vf2 :class vf)
)
(.lvf vf1 (&-> ray-origin quad))
(.lvf vf2 (&-> sph-origin quad))
(.sub.vf vf1 vf1 vf2) ;; the sphere is at the origin in the actual intersection.
(.lvf vf2 (&-> ray-dir quad))
;;(raw-ray-sphere-intersect radius)
(pc-port-do-raw-ray-sphere-intersect radius vf1 vf2)
)
)
(defun ray-circle-intersect ((ray-origin vector) (ray-dir vector) (circle-origin vector) (radius float))
"Intersect ray with circle. Circle is on the y plane and this throws out the y components
of ray-origin, circle-origin, and ray-dir"
(rlet ((vf0 :class vf)
(vf1 :class vf)
(vf2 :class vf)
)
(init-vf0-vector)
(.lvf vf1 (&-> ray-origin quad))
(.mov.vf vf1 vf0 :mask #b10)
(.lvf vf2 (&-> circle-origin quad))
(.mov.vf vf2 vf0 :mask #b10)
(.sub.vf vf1 vf1 vf2)
(.lvf vf2 (&-> ray-dir quad))
(.mov.vf vf2 vf0 :mask #b10)
;;(raw-ray-sphere-intersect radius)
(pc-port-do-raw-ray-sphere-intersect radius vf1 vf2)
)
)
(defun ray-cylinder-intersect ((ray-origin vector) (ray-dir vector) (cyl-origin vector) (cyl-axis vector) (cyl-rad float) (cyl-len float) (pt-out vector))
"Intersect with a cylinder.
Currently this is untested."
(local-vars
(v0-1 float)
(v1-0 int)
(v1-2 int)
(a0-1 int)
(a0-2 int)
(a0-4 int)
(a0-5 int)
)
(rlet ((vf1 :class vf)
(vf10 :class vf)
(vf11 :class vf)
(vf12 :class vf)
(vf13 :class vf)
(vf14 :class vf)
(vf15 :class vf)
(vf16 :class vf)
(vf17 :class vf)
(vf18 :class vf)
(vf19 :class vf)
(vf2 :class vf)
(vf20 :class vf)
(vf21 :class vf)
)
(.lvf vf10 (&-> ray-origin quad))
(.lvf vf12 (&-> cyl-origin quad))
(.sub.vf vf15 vf10 vf12)
(.lvf vf11 (&-> ray-dir quad))
(.lvf vf13 (&-> cyl-axis quad))
(.mov vf14 cyl-len)
(.mul.vf vf16 vf15 vf13)
(.mul.vf vf17 vf11 vf13)
(.add.x.vf vf16 vf16 vf16 :mask #b10)
(.add.x.vf vf17 vf17 vf17 :mask #b10)
(.add.z.vf vf16 vf16 vf16 :mask #b10)
(.add.z.vf vf17 vf17 vf17 :mask #b10)
(.mul.y.vf vf1 vf13 vf16)
(.add.vf vf18 vf17 vf16)
(.sub.x.vf vf19 vf16 vf14)
(.mul.y.vf vf2 vf13 vf17)
(.mov v1-0 vf16)
(.sub.x.vf vf20 vf18 vf14)
(.mov a0-1 vf18)
(let ((v1-1 (logand v1-0 (the-as uint a0-1))))
(.sub.vf vf1 vf15 vf1)
(b! (< v1-1 0) cfg-6 :delay (.sub.vf vf2 vf11 vf2))
)
(.mov v1-2 vf19)
(.mov a0-2 vf20)
(b! (>= (the-as int (logior v1-2 (the-as uint a0-2))) 0) cfg-6 :delay (nop!))
;;(let ((v1-4 (raw-ray-sphere-intersect cyl-rad)))
(let ((v1-4 (pc-port-do-raw-ray-sphere-intersect cyl-rad vf1 vf2)))
(b! (< (the-as int v1-4) 0) cfg-6 :delay (.mov vf21 v1-4))
(.mul.x.vf vf17 vf17 vf21)
(.add.vf vf16 vf16 vf17)
(.mul.y.vf vf13 vf13 vf16)
(.sub.x.vf vf19 vf16 vf14)
(.mov a0-4 vf16)
(b!
(< (the-as int a0-4) 0)
cfg-6
:delay
(.add.vf vf12 vf12 vf13 :mask #b111)
)
(.mov a0-5 vf19)
(b! (>= (the-as int a0-5) 0) cfg-6 :delay (.svf (&-> pt-out quad) vf12))
(b! #t cfg-7 :delay (set! v0-1 v1-4))
)
(label cfg-6)
(set! v0-1 -100000000.0)
(label cfg-7)
v0-1
)
)
(defun ray-plane-intersect ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 vector) (arg4 vector) (arg5 vector) (arg6 vector))
"Unused."
(local-vars (v1-0 float) (v1-1 float) (a2-1 float))
(rlet ((acc :class vf)
(Q :class vf)
(vf0 :class vf)
(vf1 :class vf)
(vf2 :class vf)
(vf3 :class vf)
(vf4 :class vf)
(vf5 :class vf)
(vf6 :class vf)
(vf7 :class vf)
(vf8 :class vf)
(vf9 :class vf)
)
(init-vf0-vector)
(.lvf vf3 (&-> arg5 quad))
(.lvf vf1 (&-> arg4 quad))
(.lvf vf2 (&-> arg6 quad))
(.sub.vf vf1 vf3 vf1)
(.sub.vf vf2 vf3 vf2)
(.lvf vf6 (&-> arg2 quad))
(.lvf vf7 (&-> arg3 quad))
(.sub.vf vf8 vf3 vf6)
(.outer.product.a.vf acc vf2 vf1)
(.outer.product.b.vf vf4 vf1 vf2 acc)
(.mul.vf vf8 vf8 vf4)
(.mul.vf vf9 vf7 vf4)
(.mul.vf vf5 vf4 vf4)
(.add.y.vf vf8 vf8 vf8 :mask #b1)
(.add.y.vf vf9 vf9 vf9 :mask #b1)
(.add.y.vf vf5 vf5 vf5 :mask #b1)
(.add.z.vf vf8 vf8 vf8 :mask #b1)
(.add.z.vf vf9 vf9 vf9 :mask #b1)
(.add.z.vf vf5 vf5 vf5 :mask #b1)
(.mov v1-0 vf9)
(.mov a2-1 vf8)
(.isqrt.vf Q vf0 vf5 :fsf #b11 :ftf #b0)
(let ((f1-0 a2-1)
(f2-0 v1-0)
)
(cond
((!= f2-0 0.0)
(let ((f1-1 (/ f1-0 f2-0)))
(.mov.vf vf4 vf0 :mask #b1000)
(.wait.vf)
(.mul.vf vf4 vf4 Q :mask #b111)
(let ((v0-0 f1-1))
(.mov vf8 v0-0)
(.svf (&-> arg1 quad) vf4)
(.mul.x.vf acc vf7 vf8)
(.add.mul.w.vf vf7 vf6 vf0 acc :mask #b111)
(.svf (&-> arg0 quad) vf7)
(.mov v1-1 vf7)
v0-0
)
)
)
(else
-100000000.0
)
)
)
)
)
;; ray-triangle-intersect (unused)
;; collide-do-primitives (used in moving-sphere-triangle-intersect)
(def-mips2c collide-do-primitives (function float))
;; moving-sphere-triangle-intersect (used in cam)
(def-mips2c moving-sphere-triangle-intersect (function vector vector float collide-cache-tri vector vector float))
;; moving-sphere-sphere-intersect (used in collide)
(defun moving-sphere-sphere-intersect ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 vector))
(let ((f30-0 (ray-sphere-intersect arg0 arg1 arg2 (+ (-> arg0 w) (-> arg2 w)))))
(when (>= f30-0 0.0)
(let ((s3-1 (vector-normalize! (vector-! (new-stack-vector0) arg2 arg0) (-> arg0 w))))
(vector+*! arg3 arg0 arg1 f30-0)
(vector+! arg3 arg3 s3-1)
)
)
f30-0
)
)
;; moving-sphere-moving-sphere-intersect (unused)
+14 -12
View File
@@ -160,7 +160,7 @@ This can be either an art container containing more arts, or an actual art thing
(art-method-10 (_type_) _type_)
(get-art-by-name-method (_type_ string type) basic)
(get-art-idx-by-name-method (_type_ string type) int)
(needs-link? (_type_) symbol)
(contains-art-for-other-group? (_type_) symbol)
)
)
@@ -176,7 +176,8 @@ This can be either an art container containing more arts, or an actual art thing
(deftype art-mesh-anim (art-element)
"An unused mesh animation."
()
((data basic :dynamic)
)
)
(deftype art-joint-anim (art-element)
@@ -198,20 +199,21 @@ actor, like the mesh, animations, shadow mesh, skeleton, etc."
(data art-element :dynamic :offset 32)
)
(:methods
(relocate (_type_ kheap (pointer uint8)) _type_ :replace)
(link-art! (_type_) art-group)
(relocate (_type_ kheap (pointer uint8)) none :replace)
(link-art-to-master (_type_) none)
(unknown-1 () none)
)
)
(deftype art-mesh-geo (art-element)
"Unused art format for a mesh. This might have been for the renderer that came before merc."
()
((data basic :dynamic)
)
)
(deftype art-joint-geo (art-element)
"Collection of joints for an actor."
((data joint :dynamic :offset 48)
((data joint :dynamic)
)
)
@@ -249,11 +251,11 @@ This is used for short, commonly used animations that always remain in RAM."
)
(:methods
(new (symbol type int) _type_)
(art-joint-anim-manager-method-9 () none)
(art-joint-anim-manager-method-10 () none)
(art-joint-anim-manager-method-11 () none)
(art-joint-anim-manager-method-12 () none)
(art-joint-anim-manager-method-13 () none)
(decompress (_type_ art-joint-anim) art-joint-anim)
(mark-anim-in-use (_type_ art-joint-anim) art-joint-anim)
(unload-from-slot (_type_ int) art-joint-anim)
(used-bytes-for-slot (_type_ int) int)
(unload-from-heap (_type_ kheap) none)
)
)
@@ -462,4 +464,4 @@ Each process-drawable has a draw-control."
)
(import "goal_src/jak3/engine/data/art-elts.gc")
;; (import "goal_src/jak3/engine/data/joint-nodes.gc")
;; (import "goal_src/jak3/engine/data/joint-nodes.gc")
+1
View File
@@ -16,6 +16,7 @@
(define-extern *level* level-group)
(define-extern *draw-index* int)
(define-extern *level-index* int)
(define-extern *print-login* symbol)
(define-extern level-remap-texture (function texture-id texture-id))
+2
View File
@@ -5,6 +5,8 @@
;; name in dgo: decomp-h
;; dgos: GAME
(define-extern unpack-comp-lzo (function (pointer uint8) (pointer uint8) none))
;; DECOMP BEGINS
(deftype decomp-work (structure)
@@ -8,6 +8,9 @@
(declare-type transformq structure)
(define-extern matrix<-transformq! (function matrix transformq matrix))
(define-extern matrix<-parented-transformq! (function matrix transformq vector matrix))
(define-extern matrix<-transformq+trans! (function matrix transformq vector matrix))
(define-extern matrix<-transformq+world-trans! (function matrix transformq vector matrix))
(define-extern matrix<-transformq+rot-offset! (function matrix transformq vector matrix))
;; DECOMP BEGINS
@@ -107,8 +107,8 @@
(let ((a1-5 (/ (&- (the-as pointer chan) (the-as uint (the-as pointer (-> v1-0 channel)))) 64)))
(if (< a1-5 (the-as int (+ (-> v1-0 active-channels) (-> v1-0 float-channels))))
(qmem-copy<-!
(the-as pointer (+ (+ (* a1-5 64) 60) (the-as int v1-0)))
(the-as pointer (+ (+ (* (+ a1-5 1) 64) 60) (the-as int v1-0)))
(the-as pointer (-> v1-0 channel a1-5))
(the-as pointer (-> v1-0 channel (+ a1-5 1)))
(the-as int (* (-> v1-0 float-channels) 64))
)
)
+1 -1
View File
@@ -164,7 +164,7 @@
)
)
(defglobalconstant EE_SECONDS_PER_TICK (/ 1.0 3000000)) ;; 300MHz is a "decent enough" estimate
(defglobalconstant EE_SECONDS_PER_TICK (/ 1.0 300000000)) ;; 300MHz is a "decent enough" estimate
(defmacro cpu-ticks-to-seconds (ticks)
`(* ,EE_SECONDS_PER_TICK ,ticks)
)
+4 -4
View File
@@ -157,13 +157,13 @@ Multiple channels are used to blend animations together."
(interp-select int64 2)
(top-anim top-anim-joint-control)
(override (array float))
(channel joint-control-channel :dynamic)
(channel joint-control-channel :inline :dynamic)
)
(:methods
(new (symbol type) _type_)
(new (symbol type int) _type_)
(joint-control-method-9 () none)
(joint-control-method-10 () none)
(joint-control-method-11 () none)
(debug-print-channels (_type_ symbol) int)
(joint-control-method-12 () none)
)
)
@@ -232,7 +232,7 @@ Multiple channels are used to blend animations together."
(format #t "~1Toverride: ~A~%" (-> this override))
(format #t "~1Tchannel[0] @ #x~X~%" (-> this channel))
(dotimes (s5-2 (the-as int (-> this active-channels)))
(format #t "~T [~D]~1Tchannel: ~`joint-control-channel`P~%" s5-2 (+ (+ (* s5-2 64) 60) (the-as int this)))
(format #t "~T [~D]~1Tchannel: ~`joint-control-channel`P~%" s5-2 (-> this channel s5-2))
)
(label cfg-32)
this
File diff suppressed because it is too large Load Diff
+13 -11
View File
@@ -234,7 +234,7 @@ This can be either an art container containing more arts, or an actual art thing
(art-method-10 (_type_) _type_)
(get-art-by-name-method (_type_ string type) basic)
(get-art-idx-by-name-method (_type_ string type) int)
(needs-link? (_type_) symbol)
(contains-art-for-other-group? (_type_) symbol)
)
)
@@ -280,7 +280,8 @@ This can be either an art container containing more arts, or an actual art thing
;; definition of type art-mesh-anim
(deftype art-mesh-anim (art-element)
"An unused mesh animation."
()
((data basic :dynamic)
)
)
;; definition of type art-joint-anim
@@ -325,8 +326,8 @@ actor, like the mesh, animations, shadow mesh, skeleton, etc."
(data art-element :dynamic :offset 32)
)
(:methods
(relocate (_type_ kheap (pointer uint8)) _type_ :replace)
(link-art! (_type_) art-group)
(relocate (_type_ kheap (pointer uint8)) none :replace)
(link-art-to-master (_type_) none)
(unknown-1 () none)
)
)
@@ -334,13 +335,14 @@ actor, like the mesh, animations, shadow mesh, skeleton, etc."
;; definition of type art-mesh-geo
(deftype art-mesh-geo (art-element)
"Unused art format for a mesh. This might have been for the renderer that came before merc."
()
((data basic :dynamic)
)
)
;; definition of type art-joint-geo
(deftype art-joint-geo (art-element)
"Collection of joints for an actor."
((data joint :dynamic :offset 48)
((data joint :dynamic)
)
)
@@ -417,11 +419,11 @@ This is used for short, commonly used animations that always remain in RAM."
)
(:methods
(new (symbol type int) _type_)
(art-joint-anim-manager-method-9 () none)
(art-joint-anim-manager-method-10 () none)
(art-joint-anim-manager-method-11 () none)
(art-joint-anim-manager-method-12 () none)
(art-joint-anim-manager-method-13 () none)
(decompress (_type_ art-joint-anim) art-joint-anim)
(mark-anim-in-use (_type_ art-joint-anim) art-joint-anim)
(unload-from-slot (_type_ int) art-joint-anim)
(used-bytes-for-slot (_type_ int) int)
(unload-from-heap (_type_ kheap) none)
)
)
@@ -108,8 +108,8 @@
(let ((a1-5 (/ (&- (the-as pointer chan) (the-as uint (the-as pointer (-> v1-0 channel)))) 64)))
(if (< a1-5 (the-as int (+ (-> v1-0 active-channels) (-> v1-0 float-channels))))
(qmem-copy<-!
(the-as pointer (+ (+ (* a1-5 64) 60) (the-as int v1-0)))
(the-as pointer (+ (+ (* (+ a1-5 1) 64) 60) (the-as int v1-0)))
(the-as pointer (-> v1-0 channel a1-5))
(the-as pointer (-> v1-0 channel (+ a1-5 1)))
(the-as int (* (-> v1-0 float-channels) 64))
)
)
@@ -187,7 +187,3 @@
;; failed to figure out what this is:
0
+2 -1
View File
@@ -6,7 +6,8 @@
"skip_compile_files": [
"types-h", // weird array of types.
"hfrag-h" // weird duplicate type
"hfrag-h", // weird duplicate type
"joint"
],
"skip_compile_functions": [