jak3 support

This commit is contained in:
water111
2025-06-19 11:23:42 -04:00
parent 72d87f2867
commit a89b20eb18
7 changed files with 200 additions and 9 deletions
@@ -356,8 +356,8 @@ void add_data_to_level(tfrag3::ShadowModelGroup& sd, const std::vector<ShadowDat
out_frag.num_two_bone_vertices = in_frag.two_bone_vertices.size();
ASSERT(out_frag.num_one_bone_vertices + out_frag.num_two_bone_vertices <=
tfrag3::ShadowModel::kMaxVertices);
ASSERT(out_frag.single_tris.size() + out_frag.double_tris.size() <=
tfrag3::ShadowModel::kMaxTris);
ASSERT(out_frag.single_tris.size() <= tfrag3::ShadowModel::kMaxTris);
ASSERT(out_frag.double_tris.size() <= tfrag3::ShadowModel::kMaxTris);
// insert top vertices
auto vertices = convert_vertices(in_frag);
@@ -60,6 +60,7 @@ void Shadow3::setup_for_level(SharedRenderState* render_state, const LevelData*
glEnableVertexAttribArray(3);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GEQUAL);
glDepthMask(GL_FALSE); // no depth writes.
glVertexAttribPointer(0, // location 0 in the shader
3, // 3 values per vert
@@ -200,7 +201,6 @@ void Shadow3::draw_model(SharedRenderState* render_state,
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glDepthFunc(GL_GEQUAL);
glDepthMask(GL_FALSE); // no depth writes.
if (false) {
glEnable(GL_CULL_FACE);
@@ -232,6 +232,8 @@ void Shadow3::draw_model(SharedRenderState* render_state,
void Shadow3::finish(SharedRenderState* render_state, ScopedProfilerNode& prof) {
// finally, draw shadow.
if (!m_hacks) {
glDepthMask(GL_FALSE); // no depth writes.
if (render_state->version == GameVersion::Jak1) {
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
@@ -191,7 +191,6 @@ void find_facing_double_tris(const ShadowCPUInput& input,
ShadowCPUOutput* output,
const std::vector<tfrag3::ShadowTri>& tris) {
const int num_verts = input.model->num_one_bone_vertices + input.model->num_two_bone_vertices;
const int flag_offset = 0;
for (size_t i = 0; i < tris.size(); i++) {
const auto& tri = tris[i];
@@ -200,7 +199,7 @@ void find_facing_double_tris(const ShadowCPUInput& input,
math::Vector3f v2 = work->vertices[tri.verts[2]].xyz();
math::Vector3f n = (v1 - v0).cross(v2 - v0);
if (n.dot(input.light_dir) < 0.f) {
work->tri_flags[i + flag_offset] = 1;
work->tri_flags[i] = 1;
// treat this as a normal single-sided triangle that is facing.
output->push_index(tri.verts[0], false);
output->push_index(tri.verts[1], false);
@@ -209,7 +208,7 @@ void find_facing_double_tris(const ShadowCPUInput& input,
output->push_index(static_cast<int>(tri.verts[2]) + num_verts, false);
output->push_index(static_cast<int>(tri.verts[1]) + num_verts, false);
} else {
work->tri_flags[i + flag_offset] = 0;
work->tri_flags[i] = 0;
// we need to flip vertices to face the light.
output->push_index(tri.verts[0], false);
output->push_index(tri.verts[2], false);
+23
View File
@@ -1441,6 +1441,29 @@
)
)
)
;; og:preserve-this
(let ((v1-0 *pc-shadow-globals*))
(dotimes (a0-0 3)
(let ((a1-2 (-> v1-0 bucket a0-0)))
(set! (-> a1-2 first) (the-as pointer 0))
(set! (-> a1-2 next) (the-as pointer 0))
(set! (-> a1-2 shadow-color) (cond
((zero? a0-0)
(new 'static 'rgba :r #xf0 :g #xf0 :b #xf0 :a #x80)
)
((= a0-0 1)
(the-as rgba (-> *setting-control* user-current spotlight-color))
)
(else
(the-as rgba (-> *setting-control* user-current highlight-color))
)
)
)
(set! (-> a1-2 constants) (the-as shadow-vu1-constants 0))
)
)
)
(none)
)
@@ -19,6 +19,9 @@
;; Note: merc mode 5 seems to be totally bogus - the buckets are somewhat random.
;; when set, use the rewritten PC shadow render (faster)
(define *use-pc-shadow* #t)
;; DECOMP BEGINS
(define foreground-vu0-block (new 'static 'vu-function #|:length 9 :qlength 5|#))
@@ -825,8 +828,101 @@
)
)
;; og:preserve-this
(defun pc-draw-bones-shadow ((dc draw-control) (mtx pointer) (dma-ptr pointer))
"Add shadows for this draw-control to the *pc-shadow-queue* to be drawn in pc-shadow-execute-all.
This places a pc-shadow-request in the DMA buffer and adds it to the linked list of requests
for the currently selected run in *pc-shadow-queue*"
(when (-> dc shadow-ctrl)
;; update the "center" position of the shadow control, I guess to let some other thing look at it?
(let ((center-pos (-> dc skeleton bones (-> dc shadow-joint-index) position))
(settings (-> dc shadow-ctrl settings))
)
(set! (-> settings center x) (-> center-pos x))
(set! (-> settings center y) (-> center-pos y))
(set! (-> settings center z) (-> center-pos z))
)
)
(let* ((pse (the pc-shadow-request dma-ptr))
(sgeo (-> dc shadow))
(settings (if (-> dc shadow-ctrl) (-> dc shadow-ctrl settings) *default-shadow-settings*))
(flags (-> settings flags))
)
;; if fade is enabled, and we're all the way faded out, disable draw
(when (not (logtest? flags (shadow-flags disable-fade)))
(let ((dist (-> (scratchpad-object foreground-work) distance w)))
(#when PC_PORT
(if (not (-> *pc-settings* ps2-shadow?))
(set! dist 0.0)))
(if (< (-> settings fade-dist) dist)
(logior! flags (shadow-flags disable-draw))
)
)
)
;; if disabled, early return
(if (logtest? flags (shadow-flags disable-draw))
(return dma-ptr)
)
;; settings
(mem-copy! (the pointer (-> pse settings)) (the pointer settings) (size-of shadow-settings))
;; update the "center" position.
(let ((center-pos (-> dc skeleton bones (-> dc shadow-joint-index) position)))
(set! (-> pse settings center x) (-> center-pos x))
(set! (-> pse settings center y) (-> center-pos y))
(set! (-> pse settings center z) (-> center-pos z))
)
;; set the other properties
(set! (-> pse geo-name) (-> sgeo name))
(set! (-> pse mtx) mtx)
(set! (-> pse num-joints) (-> sgeo num-joints))
;; TODO: this is probably the wrong color!!!
(vector-copy! (-> pse color) (-> *time-of-day-context* current-shadow-color))
;; set up linked list.
(let* ((run (-> *pc-shadow-globals* bucket (-> settings shadow-type)))
(next (-> run next))
)
;; if we're the first in the list, store in the run
(when (zero? (-> run first))
(set! (-> run first) (the pointer pse)))
;; patch next pointer of previous
(if (nonzero? next) (set! (-> (the (pointer structure) next) 0) pse))
;; remember where to patch for the next one
(set! (-> run next) (&-> pse next))
;; clear our next pointer in case we're last
(set! (-> pse next) (the pc-shadow-request 0))
;; set up next tag at the start, to skip over this data.
;; this is a bit of a hack, this function gets called when building merc chains,
;; and inserts a bit of shadow dma that will later be referenced by the shadow bucket.
;; but the original game did the same thing!
(&+! dma-ptr (size-of pc-shadow-request))
(set! (-> pse dma-next dma) (new 'static 'dma-tag :id (dma-tag-id next) :addr (the-as int dma-ptr)))
(set! (-> pse dma-next vif0) (new 'static 'vif-tag))
(set! (-> pse dma-next vif1) (new 'static 'vif-tag))
)
dma-ptr
)
)
(defun foreground-shadow ((arg0 draw-control) (arg1 (inline-array pris-mtx)) (arg2 pointer))
"Generate DMA for shadow drawing."
;; og:preserve-this
(when *use-pc-shadow*
(return (pc-draw-bones-shadow arg0 (the pointer arg1) arg2))
)
(local-vars (a3-3 shadow-settings))
(let ((v1-0 (-> arg0 shadow))
(t0-0 (-> (scratchpad-object foreground-work) distance w))
@@ -120,13 +120,28 @@
(define *shadow-globals* (new 'global 'shadow-globals))
(set! (-> *shadow-globals* bucket 0 bucket-id) (bucket-id shadow))
(set! (-> *shadow-globals* bucket 1 bucket-id) (bucket-id shadow2))
(set! (-> *shadow-globals* bucket 2 bucket-id) (bucket-id shadow3))
;; og:preserve-this
;; separate copy of shadow-globals for storing only the PC format requests.
(define *pc-shadow-globals* (new 'global 'shadow-globals))
(declare-type pc-shadow-request structure)
(deftype pc-shadow-request (structure)
((dma-next dma-packet :inline)
(settings shadow-settings :inline)
(color vector :inline)
(geo-name string) ;; name to send to PC renderer
(mtx pointer) ;; pointer to DMA memory that will contain bones
(num-joints uint32) ;; number of joints needed for shadow
(next pc-shadow-request)
)
)
(set! (-> *pc-shadow-globals* bucket 0 bucket-id) (bucket-id shadow))
(set! (-> *pc-shadow-globals* bucket 1 bucket-id) (bucket-id shadow2))
(set! (-> *pc-shadow-globals* bucket 2 bucket-id) (bucket-id shadow3))
(deftype shadow-vertex (structure)
((x float)
(y float)
@@ -659,9 +659,65 @@
(none)
)
;; og:preserve-this
(defun pc-shadow-execute-all ()
"Send PC shadow queue to the PC shadow renderer."
;; bail if disabled
(if (not (logtest? (-> *display* vu1-enable-user) (vu1-renderer-mask rn32)))
(return #f)
)
(dotimes (i 3)
(when (nonzero? (-> *pc-shadow-globals* bucket i first))
;; patch the color of each request.
(let ((iter (the pc-shadow-request (-> *pc-shadow-globals* bucket i first)))
(color (new-stack-vector0))
)
(cond
((= i 0)
(vector-float*! color (-> *time-of-day-context* current-shadow-color) 128.0)
)
(else
(let ((c (-> *pc-shadow-globals* bucket i shadow-color)))
(set! (-> color x) (the float (-> c r)))
(set! (-> color y) (the float (-> c g)))
(set! (-> color z) (the float (-> c b)))
)
)
)
(set! (-> color w) (the float (-> *pc-shadow-globals* bucket i shadow-color a)))
(while (nonzero? iter)
;(vector-copy! (-> iter color) color)
(set! (-> iter color quad) (-> color quad))
(set! iter (-> iter next))
)
)
(with-dma-buffer-add-bucket ((dma-buf (-> (current-frame) global-buf)) (-> *pc-shadow-globals* bucket i bucket-id))
(dma-buffer-add-ref-vif2
dma-buf
6
(-> *pc-shadow-globals* bucket i first)
(new 'static 'vif-tag :cmd (vif-cmd pc-port))
(new 'static 'vif-tag :cmd (vif-cmd pc-port))
)
)
)
)
(none)
)
;; ERROR: Failed store: (s.h! (+ v1-25 18) 0) at op 61
;; ERROR: Failed store: (s.h! (+ v1-25 16) 0) at op 62
(defun shadow-execute-all ((arg0 dma-buffer))
(when *use-pc-shadow*
(pc-shadow-execute-all)
(return #f)
)
(when *debug-segment*
(let ((gp-0 (-> *display* frames (-> *display* on-screen) profile-array data 0))
(v1-7 'other)