mirror of
https://github.com/open-goal/jak-project
synced 2026-09-09 20:21:28 -04:00
up to draw-node
This commit is contained in:
@@ -184,9 +184,17 @@ goos::Object SimpleAtom::to_form(const std::vector<DecompilerLabel>& labels, con
|
||||
case Kind::VARIABLE:
|
||||
return m_variable.to_form(env);
|
||||
case Kind::INTEGER_CONSTANT: {
|
||||
if (m_int == 0x70000000 && env.scratchpad_type()) {
|
||||
constexpr s64 kScratchpadBase = 0x70000000;
|
||||
constexpr s64 kScratchpadSize = 16 * 1024;
|
||||
if (m_int >= kScratchpadBase && m_int < kScratchpadBase + kScratchpadSize &&
|
||||
env.scratchpad_type()) {
|
||||
env.note_scratchpad_access();
|
||||
return pretty_print::to_symbol("spad");
|
||||
const auto offset = m_int - kScratchpadBase;
|
||||
if (offset == 0) {
|
||||
return pretty_print::to_symbol("spad");
|
||||
}
|
||||
return pretty_print::build_list("&+", pretty_print::to_symbol("spad"),
|
||||
goos::Object::make_integer_no_hex(offset));
|
||||
}
|
||||
if (m_display_int_as_float) {
|
||||
float f;
|
||||
|
||||
@@ -18,6 +18,7 @@ const std::map<InstructionKind, OpenGOALAsm::Function> MIPS_ASM_TO_OPEN_GOAL_FUN
|
||||
{InstructionKind::MFPC, {".mfpc", {}}},
|
||||
{InstructionKind::SYNCP, {".sync.p", {}}},
|
||||
{InstructionKind::SYNCL, {".sync.l", {}}},
|
||||
{InstructionKind::CACHE_DXWBIN, {".cache dxwbin", {}}},
|
||||
|
||||
// Shifts and such
|
||||
{InstructionKind::PSLLW, {".pw.sll", {}}},
|
||||
|
||||
@@ -7673,7 +7673,7 @@ level is hidden or uses the special or special-vis rendering path.")
|
||||
|
||||
(deftype gsf-info (structure)
|
||||
((ptr-iks uint32 :offset-assert 0)
|
||||
(ptr-verts uint32 :offset-assert 4)
|
||||
(ptr-verts (inline-array gsf-vertex) :offset-assert 4)
|
||||
(ptr-fx uint32 :offset-assert 8)
|
||||
(dummy2 uint32 :offset-assert 12)
|
||||
)
|
||||
@@ -11227,7 +11227,7 @@ active channel."
|
||||
|
||||
;; - Functions
|
||||
|
||||
(define-extern invalidate-cache-line "Write back and invalidate both ways of an EE data-cache line." (function pointer int))
|
||||
(define-extern invalidate-cache-line "Write back and invalidate both ways of an EE data-cache line." (function object int))
|
||||
|
||||
;; - Symbols
|
||||
|
||||
|
||||
@@ -443,6 +443,52 @@
|
||||
"match": "(set! (-> $font flags) (font-flags $*flags))",
|
||||
"rewrite": "(set-flags! $font (font-flags $*flags))"
|
||||
},
|
||||
{
|
||||
// perf-stat.reset! is commonly inlined. Anchor the rule on *perf-stats* so the method's own
|
||||
// definition is not rewritten into a recursive call.
|
||||
"name": "perf-stat-reset",
|
||||
"match": [
|
||||
"(let* (($stat (-> *perf-stats* data $bucket)) ($ctrl (-> $stat ctrl))) (+! (-> $stat count) 1) (b! (zero? $ctrl) $done :delay (nop!)) (.mtc0 Perf 0) (.sync.l) (.sync.p) (.mtpc pcr0 0) (.mtpc pcr1 0) (.sync.l) (.sync.p) (.mtc0 Perf $ctrl))",
|
||||
"(.sync.l)",
|
||||
"(.sync.p)",
|
||||
"(label $done)",
|
||||
"0"
|
||||
],
|
||||
"rewrite": "(reset! (-> *perf-stats* data $bucket))"
|
||||
},
|
||||
{
|
||||
// perf-stat.read! has the same branch-and-label expansion but accumulates both counters.
|
||||
"name": "perf-stat-read",
|
||||
"match": [
|
||||
"(let (($stat (-> *perf-stats* data $bucket))) (b! (zero? (-> $stat ctrl)) $done :delay (nop!)) (.mtc0 Perf 0) (.sync.l) (.sync.p) (.mfpc $counter0 pcr0) (+! (-> $stat accum0) $counter0) (.mfpc $counter1 pcr1) (+! (-> $stat accum1) $counter1))",
|
||||
"(label $done)",
|
||||
"0"
|
||||
],
|
||||
"rewrite": "(read! (-> *perf-stats* data $bucket))"
|
||||
},
|
||||
{
|
||||
// DMA accounting is always guarded by the debug usage block. Its high-water total mirrors
|
||||
// the cumulative used byte count rather than accumulating independently aligned sizes.
|
||||
"name": "dma-mem-usage-add-{{symbol}}",
|
||||
"for_each": "mem-usage-id",
|
||||
"match": "(let (($usage *dma-mem-usage*)) (when (nonzero? $usage) (set! (-> $usage length) (max {{next}} (-> $usage length))) (set! (-> $usage data {{value}} name) \"{{symbol}}\") (+! (-> $usage data {{value}} count) $count) (+! (-> $usage data {{value}} used) $bytes) (set! (-> $usage data {{value}} total) (-> $usage data {{value}} used))))",
|
||||
"rewrite": "(dma-mem-usage-add! {{symbol}} $count $bytes)"
|
||||
},
|
||||
{
|
||||
"name": "dma-mem-usage-add-enum-index-{{symbol}}",
|
||||
"for_each": "mem-usage-id",
|
||||
"match": "(let (($usage *dma-mem-usage*)) (when (nonzero? $usage) (set! (-> $usage length) (max {{next}} (-> $usage length))) (set! (-> $usage data (mem-usage-id {{symbol}}) name) \"{{symbol}}\") (+! (-> $usage data (mem-usage-id {{symbol}}) count) $count) (+! (-> $usage data (mem-usage-id {{symbol}}) used) $bytes) (set! (-> $usage data (mem-usage-id {{symbol}}) total) (-> $usage data (mem-usage-id {{symbol}}) used))))",
|
||||
"rewrite": "(dma-mem-usage-add! {{symbol}} $count $bytes)"
|
||||
},
|
||||
{
|
||||
"name": "invalidate-cache-line",
|
||||
"match": [
|
||||
"(let (($address $value)) (.sync.l) (.cache dxwbin $address 0) (.sync.l) (.cache dxwbin $address 1))",
|
||||
"(.sync.l)",
|
||||
"0"
|
||||
],
|
||||
"rewrite": "(invalidate-cache-line $value)"
|
||||
},
|
||||
{
|
||||
"name": "mem-usage-add-{{symbol}}",
|
||||
"for_each": "mem-usage-id",
|
||||
|
||||
@@ -5,5 +5,17 @@
|
||||
"field_score_overrides": [
|
||||
{"type": "work-area", "field": "background", "score": 1000}
|
||||
]
|
||||
},
|
||||
"generic-merc": {
|
||||
"type": "terrain-context",
|
||||
"field_score_overrides": [
|
||||
{"type": "foreground-area", "field": "generic-work", "score": 1000000000000}
|
||||
]
|
||||
},
|
||||
"generic-tie": {
|
||||
"type": "terrain-context",
|
||||
"field_score_overrides": [
|
||||
{"type": "foreground-area", "field": "generic-work", "score": 1000000000000}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5766,16 +5766,10 @@
|
||||
[281, "v1", "merc-fragment"]
|
||||
],
|
||||
"generic-merc-execute-all": [
|
||||
[[165, 170], "v1", "terrain-context"],
|
||||
[92, "a0", "terrain-context"],
|
||||
[96, "v1", "terrain-context"],
|
||||
[100, "v1", "terrain-context"],
|
||||
[103, "a0", "generic-envmap-saves"],
|
||||
[100, "v1", "(pointer int32)"],
|
||||
[103, "a0", "(pointer int32)"],
|
||||
[105, "v1", "(pointer int32)"],
|
||||
[47, "v1", "terrain-context"],
|
||||
[49, "v1", "terrain-context"],
|
||||
[51, "v1", "terrain-context"],
|
||||
[66, "a0", "terrain-context"],
|
||||
[109, "a0", "(pointer int32)"],
|
||||
[[114, 117], "v1", "dma-packet"]
|
||||
],
|
||||
"generic-initialize-without-sink": [
|
||||
@@ -6127,10 +6121,6 @@
|
||||
[[47, 55], "a0", "dma-packet"]
|
||||
],
|
||||
"(method 12 effect-control)": [["_stack_", 112, "res-tag"]],
|
||||
"generic-tie-execute": [
|
||||
[118, "v1", "terrain-context"],
|
||||
[124, "v1", "terrain-context"]
|
||||
],
|
||||
"target-collision-reaction": [
|
||||
["_stack_", 96, "collide-status"],
|
||||
["_stack_", 104, "cshape-reaction-flags"]
|
||||
|
||||
@@ -31646,6 +31646,16 @@
|
||||
"i"
|
||||
]
|
||||
},
|
||||
"generic-tie-debug": {
|
||||
"vars": {
|
||||
"gp-0": "vertices",
|
||||
"s5-0": "i",
|
||||
"a2-0": "vertex",
|
||||
"f2-0": "x",
|
||||
"f1-0": "y",
|
||||
"f0-0": "z"
|
||||
}
|
||||
},
|
||||
"generic-tie-execute": {
|
||||
"args": [
|
||||
"sink",
|
||||
@@ -31662,6 +31672,13 @@
|
||||
"calls",
|
||||
"generic-tie-calls"
|
||||
],
|
||||
"v1-27": "time-of-day",
|
||||
"a0-26": "work",
|
||||
"v1-28": "env-color-32",
|
||||
"v1-29": "env-color-16",
|
||||
"v1-30": "env-color-8",
|
||||
"a0-33": "pcr0",
|
||||
"a0-35": "pcr1",
|
||||
"v1-37": "dma-usage"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -163,7 +163,6 @@ set(RUNTIME_SOURCE
|
||||
mips2c/jak1_functions/collide_probe.cpp
|
||||
mips2c/jak1_functions/draw_string.cpp
|
||||
mips2c/jak1_functions/generic_merc.cpp
|
||||
mips2c/jak1_functions/generic_tie.cpp
|
||||
mips2c/jak1_functions/merc_blend_shape.cpp
|
||||
mips2c/jak1_functions/ocean_vu0.cpp
|
||||
mips2c/jak1_functions/ocean.cpp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -99,8 +99,6 @@ namespace shadow_calc_dual_verts { extern void link(); }
|
||||
namespace shadow_xform_verts { extern void link(); }
|
||||
namespace draw_inline_array_instance_tie { extern void link(); }
|
||||
namespace draw_inline_array_prototype_tie_generic_asm { extern void link(); }
|
||||
namespace generic_tie_dma_to_spad_sync { extern void link(); }
|
||||
namespace generic_tie_convert { extern void link(); }
|
||||
} // namespace jak1
|
||||
|
||||
namespace jak2 {
|
||||
@@ -439,8 +437,7 @@ PerGameVersion<std::unordered_map<std::string, std::vector<void (*)()>>> gMips2C
|
||||
jak1::shadow_xform_verts::link}},
|
||||
{"tie-methods",
|
||||
{jak1::draw_inline_array_instance_tie::link,
|
||||
jak1::draw_inline_array_prototype_tie_generic_asm::link}},
|
||||
{"generic-tie", {jak1::generic_tie_dma_to_spad_sync::link, jak1::generic_tie_convert::link}}},
|
||||
jak1::draw_inline_array_prototype_tie_generic_asm::link}}},
|
||||
/////////// JAK 2
|
||||
{{"collide-func",
|
||||
{jak2::collide_do_primitives::link, jak2::moving_sphere_triangle_intersect::link}},
|
||||
|
||||
@@ -189,4 +189,16 @@
|
||||
(+! (-> ,usage data (mem-usage-id ,kind) used) ,bytes)
|
||||
(+! (-> ,usage data (mem-usage-id ,kind) total) (align16 ,bytes))))))
|
||||
|
||||
;; Record DMA bytes in a named category when DMA-memory debugging is enabled. Unlike ordinary
|
||||
;; allocation accounting, each category's total mirrors its cumulative used byte count.
|
||||
(defmacro dma-mem-usage-add! (kind count size)
|
||||
(with-gensyms (usage)
|
||||
`(let ((,usage *dma-mem-usage*))
|
||||
(when (nonzero? ,usage)
|
||||
(set! (-> ,usage length) (max (+ 1 (mem-usage-id-int ,kind)) (-> ,usage length)))
|
||||
(set! (-> ,usage data (mem-usage-id ,kind) name) ,(symbol->string kind))
|
||||
(+! (-> ,usage data (mem-usage-id ,kind) count) ,count)
|
||||
(+! (-> ,usage data (mem-usage-id ,kind) used) ,size)
|
||||
(set! (-> ,usage data (mem-usage-id ,kind) total) (-> ,usage data (mem-usage-id ,kind) used))))))
|
||||
|
||||
(defun-extern mem-size basic symbol mem-usage-flags int)
|
||||
|
||||
@@ -15,47 +15,45 @@
|
||||
;; The recursive draw call through the drawable trees will add drawables to various lists.
|
||||
;; After this, (finish-background) is called to finalize DMA lists.
|
||||
;;
|
||||
;; Which renderers, and how they differ, because the answer is not obvious from any one file:
|
||||
;; TFRAG -- terrain, smooth cave walls, etc. Not instanced. Detail is a nested
|
||||
;; vertex array (base points, then level-0 additions, then level-1 additions).
|
||||
;; To simplify, it moves a vertex to the midpoint of a parent edge, creating a degenerate triangle
|
||||
;; that can be removed.
|
||||
;; To avoid t-junctions, morph weights are calculated per _vertex_ meaning that points appearing in
|
||||
;; multiple fragments are computed the same way in both fragments.
|
||||
;; Colors come from one time-of-day palette per tree, indexed per fragment. There are
|
||||
;; several categories: ordinary, translucent, dirt, ice, and low-resolution versions of the first
|
||||
;; two. These share the same renderer but have different ordering and blending settings.
|
||||
;; Geometry that reaches the camera goes to TFRAG-NEAR, which clips. There is no generic fallback,
|
||||
;; the generic field is never populated and there's no renderer.
|
||||
;;
|
||||
;; TFRAG -- terrain. Not instanced: every fragment is its own geometry, drawn once. Detail is a nested
|
||||
;; vertex array (base points, then level-0 additions, then level-1 additions) and the renderer unwinds
|
||||
;; one subdivision level at a time as a fragment recedes, sliding each added point onto the midpoint of
|
||||
;; the parent edge it split until it is collinear and contributes nothing. Nothing is ever dropped by the
|
||||
;; renderer -- a strip's length is fixed before its first vertex -- the point simply becomes redundant and
|
||||
;; the EE stops uploading that level. The morph weight is evaluated per *vertex*, from that vertex's own
|
||||
;; transformed w, which is what lets two fragments agree along a shared edge provided the exporter gave
|
||||
;; them the same two parents; a fragment only gives up a level once its whole bounding sphere is past
|
||||
;; that level's collapse distance, so a shared vertex has finished collapsing in the neighbour before
|
||||
;; anyone stops drawing it. Colors come from one time-of-day palette per tree, indexed per fragment. Six tree
|
||||
;; categories share the code: ordinary, translucent, dirt, ice, and low-resolution versions of the first
|
||||
;; two. Geometry that reaches the camera goes to TFRAG-NEAR, which clips. There is no GENERIC path --
|
||||
;; tfragment has a `generic` field, but generic-tfragment is a four-byte stub and nothing consumes it.
|
||||
;;
|
||||
;; TIE -- background models placed repeatedly: crates, huts, pillars, fences. Instanced, and that shapes
|
||||
;; everything: a prototype's geometry is uploaded to VU1 once and then every placement that chose it
|
||||
;; streams through as a 64-byte instance record. Detail is four separately authored meshes per prototype
|
||||
;; rather than a subdivision hierarchy, and the whole instance is drawn at one level, with one morph
|
||||
;; TIE -- background models placed repeatedly, typically rocks, trees, roof tiles, etc.
|
||||
;; TIE can handle very small objects placed many times, or very complicated objects placed few times
|
||||
;; quite well.
|
||||
;; A prototype's geometry is uploaded to VU1 once and then every placement that chose it
|
||||
;; streams through as a 64-byte instance record. The whole instance is drawn at one level, with one morph
|
||||
;; weight for the entire placement -- there is no per-vertex evaluation and no seam problem, because
|
||||
;; every fragment of a prototype is always at the same level. One time-of-day palette per prototype,
|
||||
;; shared by all its instances; what an instance owns is a byte of palette *index* per vertex, so the
|
||||
;; same authored crate can stand in sunlight and in shadow. Instances near the camera go to TIE-NEAR,
|
||||
;; shared by all its instances; each index has its own palette *index* per vertex, so the
|
||||
;; same prototype have different lighting per instance. Instances near the camera go to TIE-NEAR,
|
||||
;; which clips. Prototypes needing an environment map leave the VU1 path entirely and go through
|
||||
;; GENERIC-TIE.
|
||||
;; GENERIC-TIE. On PC, we send those to ETIE instead of taking the slower generic path.
|
||||
;;
|
||||
;; SHRUB -- small vegetation, instanced like TIE but with no LOD morph, no clipping path and no GENERIC
|
||||
;; path. The cheapest of the three.
|
||||
;; SHRUB -- small vegetation, instanced like TIE but with no LOD morph. Turns into billboard or fades
|
||||
;; out at long distance. Each instance is "lit" by a single time-of-day color.
|
||||
;;
|
||||
;; All three share the VU0 program uploaded by background-upload-vu0 below, the scratchpad
|
||||
;; terrain-context, and the convention that vf16..vf31 hold camera state for the whole background pass.
|
||||
;; finish-background draws them in the order shrubbery, terrain, TIE, then any GENERIC-TIE fallback.
|
||||
;; The original design has all background renderers share the VU0 program uploaded by background-upload-vu0 below,
|
||||
;; the scratchpad terrain-context, and the convention that vf16..vf31 hold camera state for the whole background pass.
|
||||
;; However, the final versions of these renderers set up their own conventions.
|
||||
|
||||
(define *background-work* (new 'global 'background-work))
|
||||
|
||||
;; The setup entry stores the camera state in VU0 data memory:
|
||||
;; 0..3 clipping-plane matrix
|
||||
;; 4..7 camera rotation
|
||||
;; 8..11 camera temporary matrix
|
||||
;; 4..7 camera rotation (includes translation)
|
||||
;; 8..11 camera temporary matrix (camera with perspective)
|
||||
;; 12..15 each camera-rotation row's z coefficient broadcast across all lanes
|
||||
;; used for distance-from-camera testing to select level of detail
|
||||
;;
|
||||
;; Entries 16, 25, and 29 reload the clipping planes and either depth or full rotation constants.
|
||||
;; Entry 33 transforms one point to plane distances and camera depth. Entry 42 additionally applies
|
||||
@@ -344,33 +342,20 @@
|
||||
;;;;;;;;;;;;;;;;
|
||||
;; shrubbery
|
||||
;;;;;;;;;;;;;;;;
|
||||
(set! (-> *instance-shrub-work* paused) (paused?))
|
||||
(set! (-> *instance-shrub-work* paused) (paused?))
|
||||
(when (nonzero? (-> *background-work* shrub-tree-count))
|
||||
(if *debug-segment*
|
||||
(add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0)
|
||||
'draw
|
||||
(new 'static 'rgba :r #x40 :b #x40 :a #x80)))
|
||||
;; iterate over all drawable trees
|
||||
(add-profile-frame! #x40 0 #x40 #x80 'draw)
|
||||
(dotimes (i (-> *background-work* shrub-tree-count))
|
||||
;; update the level index in the scratchpad
|
||||
(set! (-> (scratchpad-object terrain-context) bsp lev-index) (-> *background-work* shrub-levels i index))
|
||||
(flush-cache 0)
|
||||
(let ((shrub-tree (-> *background-work* shrub-trees i))
|
||||
(shrub-lev (-> *background-work* shrub-levels i)))
|
||||
;; setup colors for shrub (skipping because I don't think we'll need it here...)
|
||||
; (if (nonzero? (-> shrub-tree colors-added))
|
||||
; (time-of-day-interp-colors
|
||||
; (-> *instance-shrub-work* colors)
|
||||
; (-> shrub-tree colors-added)
|
||||
; (-> shrub-lev mood)
|
||||
; )
|
||||
; )
|
||||
;; and draw!
|
||||
;; og:perserve-this - shrub colors computed in C++ now
|
||||
;; (if (nonzero? (-> shrub-tree colors-added))
|
||||
;; (time-of-day-interp-colors (-> *instance-shrub-work* colors) (-> shrub-tree colors-added) (-> shrub-lev mood)))
|
||||
(draw-drawable-tree-instance-shrub shrub-tree shrub-lev)))
|
||||
(if *debug-segment*
|
||||
(add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0)
|
||||
'draw
|
||||
(new 'static 'rgba :r #x40 :g #x60 :b #x80 :a #x80))))
|
||||
(add-profile-frame! #x40 #x60 #x80 #x80 'draw))
|
||||
|
||||
(let ((previous-lev (the-as level #f)))
|
||||
(when (or (nonzero? (-> *background-work* tfrag-tree-count))
|
||||
(nonzero? (-> *background-work* trans-tfrag-tree-count))
|
||||
@@ -405,10 +390,7 @@
|
||||
(previous-palette (the-as time-of-day-palette #f))
|
||||
(tfrag-tree-count (max (max highres-tree-count (-> *background-work* lowres-tfrag-tree-count))
|
||||
(-> *background-work* lowres-trans-tfrag-tree-count))))
|
||||
(if *debug-segment*
|
||||
(add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0)
|
||||
'draw
|
||||
(new 'static 'rgba :r #x40 :b #x40 :a #x80)))
|
||||
(add-profile-frame! #x40 0 #x40 #x80 'draw)
|
||||
;; loop over all tfrag trees
|
||||
(dotimes (i tfrag-tree-count)
|
||||
;;;;;;;;;;;;;; Normal TFRAG
|
||||
@@ -514,19 +496,13 @@
|
||||
(set! (-> *level* level (-> (scratchpad-object terrain-context) bsp lev-index) closest-object 3)
|
||||
(fmin (-> *level* level (-> (scratchpad-object terrain-context) bsp lev-index) closest-object 3)
|
||||
(-> *tfrag-work* min-dist z)))))))
|
||||
(if *debug-segment*
|
||||
(add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0)
|
||||
'draw
|
||||
(new 'static 'rgba :r #x40 :g #x80 :b #x60 :a #x80))))
|
||||
(add-profile-frame! #x40 #x80 #x60 #x80 'draw))
|
||||
;;;;;;;;;; TIE (TFRAG Instance Engine)
|
||||
;; common setup
|
||||
(set! (-> *instance-tie-work* paused) (paused?))
|
||||
(when (nonzero? (-> *background-work* tie-tree-count))
|
||||
(tie-near-make-perspective-matrix (-> *instance-tie-work* tie-near-perspective-matrix))
|
||||
(if *debug-segment*
|
||||
(add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0)
|
||||
'draw
|
||||
(new 'static 'rgba :r #x40 :b #x40 :a #x80)))
|
||||
(add-profile-frame! #x40 0 #x40 #x80 'draw)
|
||||
;;;;;;;;;; Normal TIE
|
||||
(dotimes (i (-> *background-work* tie-tree-count))
|
||||
(let ((tie-lev (-> *background-work* tie-levels i)))
|
||||
@@ -538,13 +514,9 @@
|
||||
(set! (-> (scratchpad-object terrain-context) bsp lev-index) (-> tie-lev index))
|
||||
(set! (-> (scratchpad-object terrain-context) bsp mood) (-> tie-lev mood))
|
||||
(draw-drawable-tree-instance-tie (-> *background-work* tie-trees i) tie-lev))
|
||||
;; This field holds the 32-bit EE address of a generated generic-prototype DMA chain rather
|
||||
;; than a GOAL object. generic-tie-execute treats that address as an opaque chain head.
|
||||
(set! (-> *background-work* tie-generic i) (the-as basic (-> *instance-tie-work* first-generic-prototype))))
|
||||
(if *debug-segment*
|
||||
(add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0)
|
||||
'draw
|
||||
(new 'static 'rgba :r #x80 :g #x20 :b #x60 :a #x80)))
|
||||
(add-profile-frame! #x80 #x20 #x60 #x80 'draw)
|
||||
|
||||
;; TIE Generic
|
||||
(when (not *use-etie*)
|
||||
(dotimes (i (-> *background-work* tie-tree-count))
|
||||
|
||||
@@ -117,25 +117,15 @@
|
||||
(set! (-> direct-packet vif0) (new 'static 'vif-tag))
|
||||
(set! (-> direct-packet vif1) (new 'static 'vif-tag :imm #x4 :cmd (vif-cmd direct) :msk #x1))
|
||||
(set! (-> packet-buffer base) (&+ (the-as pointer direct-packet) 16)))
|
||||
(let* ((tag-buffer dma-buf)
|
||||
(gif-tag (the-as gs-gif-tag (-> tag-buffer base))))
|
||||
(set! (-> gif-tag tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x3))
|
||||
(set! (-> gif-tag regs) GIF_REGS_ALL_AD)
|
||||
(set! (-> tag-buffer base) (&+ (the-as pointer gif-tag) 16)))
|
||||
(dma-buffer-add-gif-tag dma-buf (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x3) GIF_REGS_ALL_AD)
|
||||
(let* ((state-buffer dma-buf)
|
||||
(state-out (-> state-buffer base)))
|
||||
(set! (-> (the-as (pointer gs-xy-offset) state-out) 0)
|
||||
(new 'static
|
||||
'gs-xy-offset
|
||||
:ofx #x7000
|
||||
:ofy (+ (* (-> *video-parms* screen-miny) 16) field-offset)))
|
||||
(new 'static 'gs-xy-offset :ofx #x7000 :ofy (+ (* (-> *video-parms* screen-miny) 16) field-offset)))
|
||||
(set! (-> (the-as (pointer gs-reg64) state-out) 1) (gs-reg64 xyoffset-1))
|
||||
;; Mask RGB so these sprites establish only the destination-alpha stencil.
|
||||
(set! (-> (the-as (pointer gs-frame) state-out) 2)
|
||||
(new 'static 'gs-frame :fbw #x8 :fbmsk #xffffff :fbp framebuffer-page))
|
||||
(set! (-> (the-as (pointer gs-frame) state-out) 2) (new 'static 'gs-frame :fbw #x8 :fbmsk #xffffff :fbp framebuffer-page))
|
||||
(set! (-> (the-as (pointer gs-reg64) state-out) 3) (gs-reg64 frame-1))
|
||||
(set! (-> (the-as (pointer gs-test) state-out) 4)
|
||||
(new 'static 'gs-test :zte #x1 :ztst (gs-ztest greater-equal)))
|
||||
(set! (-> (the-as (pointer gs-test) state-out) 4) (new 'static 'gs-test :zte #x1 :ztst (gs-ztest greater-equal)))
|
||||
(set! (-> (the-as (pointer gs-reg64) state-out) 5) (gs-reg64 test-1))
|
||||
(set! (-> state-buffer base) (&+ state-out 48)))
|
||||
(let ((packet-data (the-as (inline-array vector4w) (-> dma-buf base)))
|
||||
@@ -143,19 +133,15 @@
|
||||
(sprite-width 1024))
|
||||
(set! (-> packet-data 0 quad) (-> *depth-cue-work* stencil-tmpl dma-vif quad))
|
||||
(set! (-> packet-data 1 quad) (-> *depth-cue-work* stencil-tmpl quad 1))
|
||||
(let ((cursor (the-as (inline-array vector4w) (-> packet-data 2))))
|
||||
(let ((cursor (&-> packet-data 2)))
|
||||
(dotimes (i 2)
|
||||
(set! (-> cursor 0 quad) (-> color quad))
|
||||
(set! cursor (the-as (inline-array vector4w) (-> cursor 1)))
|
||||
(set! cursor (&-> cursor 1))
|
||||
(dotimes (j 5)
|
||||
(set-vector! (-> cursor 0) x (* (-> *video-parms* screen-miny) 16) depth 0)
|
||||
(set-vector! (-> cursor 1)
|
||||
(+ x sprite-width)
|
||||
(* (-> *video-parms* screen-maxy) 16)
|
||||
depth
|
||||
#x10000)
|
||||
(set-vector! (-> cursor 1) (+ x sprite-width) (* (-> *video-parms* screen-maxy) 16) depth #x10000)
|
||||
(+! x sprite-width)
|
||||
(set! cursor (the-as (inline-array vector4w) (-> cursor 2)))))
|
||||
(set! cursor (&-> cursor 2))))
|
||||
(set! (-> dma-buf base) (the-as pointer cursor))
|
||||
(the-as vector4w cursor))))
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -51,7 +51,7 @@
|
||||
(dma-list dma-packet :inline :overlay-at (-> buffer 0 joint 0 control-bits 0))))
|
||||
|
||||
(#unless PC_PORT
|
||||
(defun invalidate-cache-line ((address pointer))
|
||||
(defun invalidate-cache-line ((address object))
|
||||
"Write back and invalidate both ways of an EE data-cache line."
|
||||
(declare (asm-func int))
|
||||
(rlet ((address-reg :reg a0)
|
||||
@@ -65,7 +65,7 @@
|
||||
(jr ra :delay (add sp sp r0)))))
|
||||
|
||||
(#when PC_PORT
|
||||
(defun invalidate-cache-line ((address pointer))
|
||||
(defun invalidate-cache-line ((address object))
|
||||
"Write back and invalidate both ways of an EE data-cache line."
|
||||
0))
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,17 +8,16 @@
|
||||
(require "engine/gfx/generic/generic-h.gc")
|
||||
(define-extern *generic-envmap-texture* texture)
|
||||
|
||||
;; GENERIC converts expanded fragment geometry into the DMA/VIF packets consumed by the Generic VU1
|
||||
;; renderer. MERC and Generic TIE first build a GSF source buffer in main memory. Its header supplies
|
||||
;; strip and draw-point counts, ptr-iks supplies the indexed draw order, and ptr-verts addresses the
|
||||
;; expanded 32-byte position/texture/normal/color records. Camera, lighting, packet-template, shader,
|
||||
;; and output-cursor state lives in the shared generic-work scratchpad page.
|
||||
;; GENERIC Effect processors convert GSF format vertices generated by generic-tie/generic-merc into
|
||||
;; DMA/VIF packets for the GENERIC VU1 renderer. Generic VU1 doesn't support effects like lighting
|
||||
;; or environment mapping, so these are done on the EE during conversion. The input GSF format supports
|
||||
;; indexed strips, which are de-indexed in this process.
|
||||
;;
|
||||
;; Each packet is assembled in one of the two scratchpad banks selected by saves.cur-outbuf:
|
||||
;;
|
||||
;; 1. A packet builder writes the outer DMA/VIF prefix, VU1 header, and per-strip A+D shaders.
|
||||
;; 2. It reserves packed position, color, and texture-coordinate payloads and publishes their
|
||||
;; scratchpad addresses through generic-saves.
|
||||
;; 2. It reserves packed position, color, and texture-coordinate payloads and stores their
|
||||
;; scratchpad addresses in generic-saves.
|
||||
;; 3. The selected effect processors gather GSF vertices in draw-point order and fill those spans.
|
||||
;; 4. The caller copies saves.qwc quadwords from cur-outbuf through fromSPR to saves.basep, the
|
||||
;; current write cursor in the frame's main-memory DMA buffer, then flips the scratchpad bank.
|
||||
@@ -30,8 +29,9 @@
|
||||
;; Builders and processors take no arguments because generic-saves is their shared interface. Stream
|
||||
;; sizes are rounded to four draw points, matching the original four-at-a-time processors and keeping
|
||||
;; each payload qword-aligned; the final group may therefore consume converter-provided padding.
|
||||
;; Each gsf-ik contributes an 8-bit vertex index and an 8-bit no-kick flag. The processors place the
|
||||
;; flag in bit 0 of S, which VU1 removes from the coordinate and converts to the GS ADC bit. Authored
|
||||
;; Each gsf-ik specifies an 8-bit vertex index and an 8-bit no-kick flag. The processors de-index
|
||||
;; the vertices and plage the flag in bit 0 of S
|
||||
;; which VU1 removes from the coordinate and converts to the GS ADC bit. Authored
|
||||
;; texture coordinates must consequently keep bit 0 clear.
|
||||
;;
|
||||
;; Single-pass packet:
|
||||
@@ -47,6 +47,11 @@
|
||||
;; once and shaded twice. generic-light-proc fills the base streams; generic-envmap-proc fills the two
|
||||
;; environment streams.
|
||||
|
||||
;; On PC, this is only used as a fallback from the more optimized C++ render when GOAL code
|
||||
;; queries vertex positions. This only happens during enemy deaths and dark eco pools to find particle
|
||||
;; spawn points.
|
||||
;; Generic-tie is no longer supported on PC.
|
||||
|
||||
(define *target-lock* (the-as symbol 0))
|
||||
|
||||
;; Immutable packet templates and arithmetic constants. generic-work-init copies this block into
|
||||
@@ -231,11 +236,11 @@
|
||||
;; Plain GOAL effect implementations
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Portable versions of the packet builders and per-draw-point processors used by the PC converters.
|
||||
;; They preserve the original scratchpad ABI: builders publish raw stream addresses in generic-saves,
|
||||
;; processors fill those addresses, and the surrounding MERC/TIE code performs the fromSPR copy.
|
||||
;; Simplified PC-port implementations. These are faster than MIPS2C and more understandable,
|
||||
;; but lack the extreme optimization from the original game. See generic-effect-ee-asm.gc for
|
||||
;; the original optimized version
|
||||
|
||||
;; Optional counters for comparing the portable effect path with the surrounding conversion cost.
|
||||
;; Enable optional counters
|
||||
(define *generic-effect-stats* #f)
|
||||
|
||||
(deftype generic-effect-debug-stats (structure)
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
;; the packet builders have to recompute the divisions.
|
||||
(deftype gsf-info (structure)
|
||||
((ptr-iks uint32) ;; gsf-ik, one per draw point
|
||||
(ptr-verts uint32) ;; gsf-vertex, one per vertex
|
||||
(ptr-verts (inline-array gsf-vertex)) ;; one per vertex
|
||||
(ptr-fx uint32) ;; gsf-fx-vertex, one per draw point; environment-map pass only
|
||||
(dummy2 uint32)))
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,10 @@
|
||||
(bundles "ENGINE.CGO" "GAME.CGO")
|
||||
(require "engine/gfx/shadow/shadow-cpu.gc")
|
||||
|
||||
;; NOTE: this file is a bit of a mess now.
|
||||
;; I'm planning to remove most of it and replace with PC shadow
|
||||
;; renderer very soon.
|
||||
|
||||
;; The perspective matrix goes in at the bottom of VU1 data memory, one row per quadword.
|
||||
(defconstant SHADOW-VU1-MATRIX 0)
|
||||
|
||||
@@ -1084,49 +1088,48 @@
|
||||
)
|
||||
|
||||
(defun shadow-vu1-add-constants ((dma-buf dma-buffer))
|
||||
"Upload the shadow projection, texture, fog, and color constants, then the four-quadword GIF tag block
|
||||
the clipper writes its polygons into."
|
||||
"Upload the shadow projection, texture, fog, color, and GIF constants plus the initial VU1 GIF
|
||||
buffer template."
|
||||
(let* ((qwc 13)
|
||||
(packet-buffer dma-buf)
|
||||
(upload-packet (the-as object (-> packet-buffer base))))
|
||||
(set! (-> (the-as dma-packet upload-packet) dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc qwc))
|
||||
(set! (-> (the-as dma-packet upload-packet) vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl)))
|
||||
(set! (-> (the-as dma-packet upload-packet) vif1) (new 'static 'vif-tag :imm SHADOW-VU-CONSTS :cmd (vif-cmd unpack-v4-32) :num qwc))
|
||||
(upload-packet (the-as dma-packet (-> packet-buffer base))))
|
||||
(set! (-> upload-packet dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc qwc))
|
||||
(set! (-> upload-packet vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl)))
|
||||
(set! (-> upload-packet vif1) (new 'static 'vif-tag :imm #x370 :cmd (vif-cmd unpack-v4-32) :num qwc))
|
||||
(set! (-> packet-buffer base) (&+ (the-as pointer upload-packet) 16)))
|
||||
(let ((constants (the-as object (-> dma-buf base)))
|
||||
(let ((constants (the-as shadow-vu1-constants (-> dma-buf base)))
|
||||
(camera *math-camera*)
|
||||
(shadow-state *shadow-data*)
|
||||
(tri-template *shadow-vu1-tri-template*))
|
||||
(vector-copy! (-> (the-as shadow-vu1-constants constants) hmgescale) (-> camera hmge-scale))
|
||||
(vector-copy! (-> (the-as shadow-vu1-constants constants) invhscale) (-> camera inv-hmge-scale))
|
||||
(vector-copy! (-> (the-as shadow-vu1-constants constants) texoffset) (-> shadow-state texoffset))
|
||||
(vector-copy! (-> (the-as shadow-vu1-constants constants) texscale) (-> shadow-state texscale))
|
||||
(vector-copy! (-> (the-as shadow-vu1-constants constants) hvdfoff) (-> camera hvdf-off))
|
||||
(set! (-> (the-as shadow-vu1-constants constants) fog x) (-> camera pfog0))
|
||||
(vector-copy! (-> (the-as shadow-vu1-constants constants) clrs 0) (-> shadow-state clrs 0))
|
||||
(vector-copy! (-> (the-as shadow-vu1-constants constants) clrs 1) (-> shadow-state clrs 1))
|
||||
(set! (-> (the-as shadow-vu1-constants constants) adgif qword) (-> tri-template adgif qword))
|
||||
(set! (-> (the-as shadow-vu1-constants constants) texflush quad) (-> tri-template ad quad))
|
||||
(set! (-> (the-as shadow-vu1-constants constants) flush quad) (-> tri-template flush quad))
|
||||
(set! (-> (the-as shadow-vu1-constants constants) trigif qword) (-> tri-template trigif qword))
|
||||
(set! (-> (the-as shadow-vu1-constants constants) quadgif qword) (-> tri-template quadgif qword)))
|
||||
(vector-copy! (-> constants hmgescale) (-> camera hmge-scale))
|
||||
(vector-copy! (-> constants invhscale) (-> camera inv-hmge-scale))
|
||||
(vector-copy! (-> constants texoffset) (-> shadow-state texoffset))
|
||||
(vector-copy! (-> constants texscale) (-> shadow-state texscale))
|
||||
(vector-copy! (-> constants hvdfoff) (-> camera hvdf-off))
|
||||
(set! (-> constants fog x) (-> camera pfog0))
|
||||
(vector-copy! (-> constants clrs 0) (-> shadow-state clrs 0))
|
||||
(vector-copy! (-> constants clrs 1) (-> shadow-state clrs 1))
|
||||
(set! (-> constants adgif qword) (-> tri-template adgif qword))
|
||||
(set! (-> constants texflush quad) (-> tri-template ad quad))
|
||||
(set! (-> constants flush quad) (-> tri-template flush quad))
|
||||
(set! (-> constants trigif qword) (-> tri-template trigif qword))
|
||||
(set! (-> constants quadgif qword) (-> tri-template quadgif qword)))
|
||||
(&+! (-> dma-buf base) 208)
|
||||
(let* ((gif-upload-buffer dma-buf)
|
||||
(gif-upload (the-as object (-> gif-upload-buffer base))))
|
||||
(set! (-> (the-as dma-packet gif-upload) dma) (new 'static 'dma-tag :qwc #x4 :id (dma-tag-id cnt)))
|
||||
(set! (-> (the-as dma-packet gif-upload) vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl)))
|
||||
(set! (-> (the-as dma-packet gif-upload) vif1) (new 'static 'vif-tag :imm SHADOW-VU1-CLIP-GIF :num #x4 :cmd (vif-cmd unpack-v4-32)))
|
||||
(gif-upload (the-as dma-packet (-> gif-upload-buffer base))))
|
||||
(set! (-> gif-upload dma) (new 'static 'dma-tag :qwc #x4 :id (dma-tag-id cnt)))
|
||||
(set! (-> gif-upload vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl)))
|
||||
(set! (-> gif-upload vif1) (new 'static 'vif-tag :imm #x3ac :num #x4 :cmd (vif-cmd unpack-v4-32)))
|
||||
(set! (-> gif-upload-buffer base) (&+ (the-as pointer gif-upload) 16)))
|
||||
(let* ((gif-template-buffer dma-buf)
|
||||
(gif-template (the-as object (-> gif-template-buffer base))))
|
||||
(set! (-> (the-as shadow-vu1-gifbuf-template gif-template) adgif tag) (new 'static 'gif-tag64 :nloop #x1 :nreg #x2))
|
||||
(set! (-> (the-as shadow-vu1-gifbuf-template gif-template) adgif regs)
|
||||
(new 'static 'gif-tag-regs :regs0 (gif-reg-id a+d) :regs1 (gif-reg-id rgbaq)))
|
||||
(set! (-> (the-as shadow-vu1-gifbuf-template gif-template) ad data) (the-as uint 0))
|
||||
(set! (-> (the-as shadow-vu1-gifbuf-template gif-template) ad cmds) (the-as uint 63))
|
||||
(set! (-> (the-as shadow-vu1-gifbuf-template gif-template) flush data) (the-as uint 0))
|
||||
(set! (-> (the-as shadow-vu1-gifbuf-template gif-template) flush cmds) (the-as uint 0))
|
||||
(set! (-> (the-as shadow-vu1-gifbuf-template gif-template) trigif tag)
|
||||
(gif-template (the-as shadow-vu1-gifbuf-template (-> gif-template-buffer base))))
|
||||
(set! (-> gif-template adgif tag) (new 'static 'gif-tag64 :nloop #x1 :nreg #x2))
|
||||
(set! (-> gif-template adgif regs) (gs-reg-list a+d rgbaq))
|
||||
(set! (-> gif-template ad data) (the-as uint 0))
|
||||
(set! (-> gif-template ad cmds) (the-as uint 63))
|
||||
(set! (-> gif-template flush data) (the-as uint 0))
|
||||
(set! (-> gif-template flush cmds) (the-as uint 0))
|
||||
(set! (-> gif-template trigif tag)
|
||||
(new 'static
|
||||
'gif-tag64
|
||||
:nloop #x3
|
||||
@@ -1135,8 +1138,7 @@
|
||||
:prim
|
||||
(new 'static 'gs-prim :prim (gs-prim-type tri-fan) :tme #x1)
|
||||
:nreg #x2))
|
||||
(set! (-> (the-as shadow-vu1-gifbuf-template gif-template) trigif regs)
|
||||
(new 'static 'gif-tag-regs :regs0 (gif-reg-id st) :regs1 (gif-reg-id xyzf2)))
|
||||
(set! (-> gif-template trigif regs) (gs-reg-list st xyzf2))
|
||||
(set! (-> gif-template-buffer base) (&+ (the-as pointer gif-template) 64)))
|
||||
(none))
|
||||
|
||||
@@ -1160,10 +1162,8 @@
|
||||
(dma-buffer-add-vu-function dma-buf shadow-vu1-block 1)
|
||||
(shadow-vu1-add-constants dma-buf)
|
||||
(shadow-vu1-add-matrix dma-buf *math-camera*)
|
||||
(let* ((packet-buffer dma-buf)
|
||||
(start-packet (the-as object (-> packet-buffer base))))
|
||||
(set! (-> (the-as dma-packet start-packet) dma) (new 'static 'dma-tag :id (dma-tag-id cnt)))
|
||||
(set! (-> (the-as dma-packet start-packet) vif0) (new 'static 'vif-tag :cmd (vif-cmd mscalf) :msk #x1 :imm SHADOW-VU1-ENTRY-INIT))
|
||||
(set! (-> (the-as dma-packet start-packet) vif1) (new 'static 'vif-tag :cmd (vif-cmd flushe) :msk #x1))
|
||||
(set! (-> packet-buffer base) (&+ (the-as pointer start-packet) 16)))
|
||||
(dma-buffer-add-cnt-vif2 dma-buf
|
||||
0
|
||||
(new 'static 'vif-tag :cmd (vif-cmd mscalf) :msk #x1 :imm #xa)
|
||||
(new 'static 'vif-tag :cmd (vif-cmd flushe) :msk #x1))
|
||||
(none))
|
||||
|
||||
@@ -26,26 +26,30 @@
|
||||
;; The signed control byte selects a repeated or literal section.
|
||||
(set! control (-> src 0))
|
||||
(set! src (&-> src 1))
|
||||
(b! (<= control 0) cfg-5 :delay (nop!))
|
||||
(b! (<= control 0) zero-or-neg :delay (nop!))
|
||||
;; A positive control stores the repeated run length minus one.
|
||||
(let ((repeated-value (-> src 0)))
|
||||
(set! src (&-> src 1))
|
||||
(label cfg-3)
|
||||
(label write-repeated)
|
||||
(nop!)
|
||||
(nop!)
|
||||
(nop!)
|
||||
(nop!)
|
||||
(set! (-> dst 0) repeated-value))
|
||||
(set! dst (&-> dst 1))
|
||||
(b! (> control 0) cfg-3 :delay (set! control (+ control -1))))
|
||||
(label cfg-5)
|
||||
(b! (> control 0) write-repeated :delay (set! control (+ control -1))))
|
||||
(label zero-or-neg)
|
||||
;; Zero ends the stream; a negative control introduces that many literal bytes.
|
||||
(b! (zero? control) cfg-8 :delay (set! copy-length (- control)))
|
||||
(label cfg-6)
|
||||
(let ((literal-value (-> src 0))) (set! src (&-> src 1)) (nop!) (nop!) (set! (-> dst 0) literal-value))
|
||||
(b! (zero? control) end :delay (set! copy-length (- control)))
|
||||
(label copy)
|
||||
(let ((literal-value (-> src 0)))
|
||||
(set! src (&-> src 1))
|
||||
(nop!)
|
||||
(nop!)
|
||||
(set! (-> dst 0) literal-value))
|
||||
(+! copy-length -1)
|
||||
(b! (> copy-length 0) cfg-6 :delay (set! dst (&-> dst 1))))
|
||||
(label cfg-8)
|
||||
(b! (> copy-length 0) copy :delay (set! dst (&-> dst 1))))
|
||||
(label end)
|
||||
0
|
||||
(none))
|
||||
|
||||
|
||||
@@ -110,15 +110,14 @@ TEST(Demacro, ExpandsPatternTables) {
|
||||
]
|
||||
}
|
||||
)RULES");
|
||||
const auto result =
|
||||
demacro::rewrite("(begin (expanded-kind 0) (expanded-kind 1))", rules);
|
||||
const auto result = demacro::rewrite("(begin (expanded-kind 0) (expanded-kind 1))", rules);
|
||||
EXPECT_EQ(result.rewrite_count(), 2);
|
||||
EXPECT_EQ(result.source, "(begin (kind first) (kind second))");
|
||||
}
|
||||
|
||||
TEST(Demacro, Jak1PreservesMemUsageNameSemantics) {
|
||||
const auto rules = demacro::load_rules(
|
||||
file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
const auto rules =
|
||||
demacro::load_rules(file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
const std::string source = R"((begin
|
||||
(set! (-> usage length) (max 1 (-> usage length)))
|
||||
(set! (-> usage data 0 name) "drawable-group")
|
||||
@@ -141,9 +140,65 @@ TEST(Demacro, Jak1PreservesMemUsageNameSemantics) {
|
||||
)");
|
||||
}
|
||||
|
||||
TEST(Demacro, Jak1RecognizesPerfStatAndDmaMemUsageMacros) {
|
||||
const auto rules =
|
||||
demacro::load_rules(file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
const std::string source = R"((begin
|
||||
(let* ((stat (-> *perf-stats* data 1))
|
||||
(ctrl (-> stat ctrl)))
|
||||
(+! (-> stat count) 1)
|
||||
(b! (zero? ctrl) reset-done :delay (nop!))
|
||||
(.mtc0 Perf 0)
|
||||
(.sync.l)
|
||||
(.sync.p)
|
||||
(.mtpc pcr0 0)
|
||||
(.mtpc pcr1 0)
|
||||
(.sync.l)
|
||||
(.sync.p)
|
||||
(.mtc0 Perf ctrl))
|
||||
(.sync.l)
|
||||
(.sync.p)
|
||||
(label reset-done)
|
||||
0
|
||||
(let ((stat (-> *perf-stats* data 1)))
|
||||
(b! (zero? (-> stat ctrl)) read-done :delay (nop!))
|
||||
(.mtc0 Perf 0)
|
||||
(.sync.l)
|
||||
(.sync.p)
|
||||
(.mfpc counter0 pcr0)
|
||||
(+! (-> stat accum0) counter0)
|
||||
(.mfpc counter1 pcr1)
|
||||
(+! (-> stat accum1) counter1))
|
||||
(label read-done)
|
||||
0
|
||||
(let ((usage *dma-mem-usage*))
|
||||
(when (nonzero? usage)
|
||||
(set! (-> usage length) (max 87 (-> usage length)))
|
||||
(set! (-> usage data 86 name) "pris-generic")
|
||||
(+! (-> usage data 86 count) 1)
|
||||
(+! (-> usage data 86 used) bytes)
|
||||
(set! (-> usage data 86 total) (-> usage data 86 used))))
|
||||
(let ((line (-> dma-buf base)))
|
||||
(.sync.l)
|
||||
(.cache dxwbin line 0)
|
||||
(.sync.l)
|
||||
(.cache dxwbin line 1))
|
||||
(.sync.l)
|
||||
0)
|
||||
)";
|
||||
const auto result = demacro::rewrite(source, rules);
|
||||
EXPECT_EQ(result.rewrite_count(), 4);
|
||||
EXPECT_EQ(result.source, R"((begin
|
||||
(reset! (-> *perf-stats* data 1))
|
||||
(read! (-> *perf-stats* data 1))
|
||||
(dma-mem-usage-add! pris-generic 1 bytes)
|
||||
(invalidate-cache-line (-> dma-buf base)))
|
||||
)");
|
||||
}
|
||||
|
||||
TEST(Demacro, Jak1RecognizesCachedEngineIteration) {
|
||||
const auto rules = demacro::load_rules(
|
||||
file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
const auto rules =
|
||||
demacro::load_rules(file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
const std::string source = R"((let ((node (-> *collide-player-list* alive-list next0)))
|
||||
*collide-player-list*
|
||||
(let ((next-node (-> node next0)))
|
||||
@@ -162,8 +217,8 @@ TEST(Demacro, Jak1RecognizesCachedEngineIteration) {
|
||||
}
|
||||
|
||||
TEST(Demacro, Jak1RecognizesMergedCachedEngineIterations) {
|
||||
const auto rules = demacro::load_rules(
|
||||
file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
const auto rules =
|
||||
demacro::load_rules(file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
const std::string source = R"((begin
|
||||
(let ((node (-> first-engine alive-list next0)))
|
||||
first-engine
|
||||
@@ -210,8 +265,8 @@ TEST(Demacro, Jak1RecognizesMergedCachedEngineIterations) {
|
||||
}
|
||||
|
||||
TEST(Demacro, Jak1RecognizesDmaBucketConstruction) {
|
||||
const auto rules = demacro::load_rules(
|
||||
file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
const auto rules =
|
||||
demacro::load_rules(file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
const std::string source = R"((let* ((buf (-> (current-frame) debug-buf))
|
||||
(start (-> buf base)))
|
||||
;; Keep the packet-building body.
|
||||
@@ -232,8 +287,8 @@ TEST(Demacro, Jak1RecognizesDmaBucketConstruction) {
|
||||
}
|
||||
|
||||
TEST(Demacro, Jak1RecognizesInlinedFontEnumSetters) {
|
||||
const auto rules = demacro::load_rules(
|
||||
file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
const auto rules =
|
||||
demacro::load_rules(file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
const std::string source = R"((begin
|
||||
(set! (-> font flags) (font-flags shadow kerning large))
|
||||
;; Keep the color choice with its reconstructed call.
|
||||
|
||||
Reference in New Issue
Block a user