Skip to content

Commit

Permalink
[jak3] fix process stack overflow + collision renderer (#3473)
Browse files Browse the repository at this point in the history
  • Loading branch information
ManDude authored Apr 16, 2024
1 parent e601a3d commit 8e58303
Show file tree
Hide file tree
Showing 13 changed files with 62 additions and 38 deletions.
7 changes: 7 additions & 0 deletions .vs/launch.vs.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@
"name": "Game - Jak 2 - Runtime (release)",
"args": ["-v", "--game", "jak2", "--", "-boot", "-fakeiso"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "gk.exe (bin\\gk.exe)",
"name": "Game - Jak 3 - Runtime (boot)",
"args": ["-v", "--game", "jak3", "--", "-boot", "-fakeiso", "-debug"]
},
{
"type": "default",
"project": "CMakeLists.txt",
Expand Down
2 changes: 1 addition & 1 deletion decompiler/config/jak3/jak3_config.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
"rip_levels": false,
// should we also extract collision meshes to the .fr3 files?
// these can be displayed in-game with the OpenGOAL collision renderer
"extract_collision": false,
"extract_collision": true,
// turn this on if you want extracted level collision to be saved as .obj files in debug_out/<game>
"rip_collision": false,
// save game textures as .png files to decompiler_out/<game>/textures
Expand Down
1 change: 1 addition & 0 deletions game/graphics/opengl_renderer/CollideMeshRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ void CollideMeshRenderer::init_pat_colors(GameVersion version) {
mode_colors = &mode_colors_jak1;
break;
case GameVersion::Jak2:
case GameVersion::Jak3:
material_colors = &material_colors_jak2;
event_colors = &event_colors_jak2;
mode_colors = &mode_colors_jak2;
Expand Down
7 changes: 6 additions & 1 deletion game/graphics/opengl_renderer/OpenGLRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1302,7 +1302,12 @@ void OpenGLRenderer::dispatch_buckets_jak3(DmaFollower dma,
vif_interrupt_callback(bucket_id + 1);
m_category_times[(int)m_bucket_categories[bucket_id]] += bucket_prof.get_elapsed_time();

// TODO: collision renderer
// hack to draw the collision mesh in the middle the drawing
if (bucket_id + 1 == (int)jak3::BucketId::TEX_L0_ALPHA &&
Gfx::g_global_settings.collision_enable) {
auto p = prof.make_scoped_child("collision-draw");
m_collide_renderer.render(&m_render_state, p);
}
}
vif_interrupt_callback(m_bucket_renderers.size());

Expand Down
8 changes: 4 additions & 4 deletions game/graphics/opengl_renderer/shaders/collision.vert
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ const int MODE_MODE = 1;
const int MODE_EVENT = 2;
const int MODE_MATERIAL = 3;

uint pat_get_mode(uint p) { return version == 2 ? (p >> 7) & 0x7u : (p >> 3) & 0x7u; }
uint pat_get_material(uint p) { return version == 2 ? (p >> 10) & 0x3fu : (p >> 6) & 0x3fu; }
uint pat_get_event(uint p) { return version == 2 ? (p >> 18) & 0x3fu : (p >> 14) & 0x3fu; }
uint pat_get_skip(uint p) { return version == 2 ? p & 0x1f03007fu : p & 0x3007u; }
uint pat_get_mode(uint p) { return version == 2 || version == 3 ? (p >> 7) & 0x7u : (p >> 3) & 0x7u; }
uint pat_get_material(uint p) { return version == 2 || version == 3 ? (p >> 10) & 0x3fu : (p >> 6) & 0x3fu; }
uint pat_get_event(uint p) { return version == 2 || version == 3 ? (p >> 18) & 0x3fu : (p >> 14) & 0x3fu; }
uint pat_get_skip(uint p) { return version == 2 || version == 3 ? p & 0x1f03007fu : p & 0x3007u; }

bool logtest(uint a, uint b) { return (a & b) != 0; }
bool logtesta(uint a, uint b) { return (a & b) == b; }
Expand Down
4 changes: 2 additions & 2 deletions game/mips2c/mips2c_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,8 @@ struct ExecutionContext {

void sq(int src, int offset, int addr) {
auto s = gpr_src(src);
ASSERT((offset & 15) == 0);
memcpy(g_ee_main_mem + gpr_addr(addr) + offset, &s.du32[0], 16);
// ASSERT((offset & 15) == 0);
memcpy(g_ee_main_mem + ((gpr_addr(addr) + offset) & (~15)), &s.du32[0], 16);
}

void sqc2(int src, int offset, int addr) {
Expand Down
10 changes: 1 addition & 9 deletions goal_src/jak3/engine/common-obs/projectile-h.gc
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,7 @@

(defun spawn-projectile ((proj-type type) (params projectile-init-by-other-params) (parent-proc-tree process-tree) (pool dead-pool))
"Create a new process for a projectile of the given type."
(let ((s4-0 (get-process pool proj-type #x4000 1)))
(when s4-0
(let ((t9-1 (method-of-type process activate)))
(t9-1 s4-0 parent-proc-tree "projectile" (the-as pointer #x70004000))
)
(run-now-in-process s4-0 projectile-init-by-other params)
(-> s4-0 ppointer)
)
)
(process-spawn proj-type :runtime #t :name "projectile" :from pool :to parent-proc-tree :init projectile-init-by-other params)
)

(deftype projectile-bounce (projectile)
Expand Down
5 changes: 1 addition & 4 deletions goal_src/jak3/engine/common-obs/projectile.gc
Original file line number Diff line number Diff line change
Expand Up @@ -494,10 +494,7 @@
;; (usually the vehicle firing the projectile) to set the quat instead.
;; on original hardware, this would not crash because misaligned qw loads silently mask the lower bits
;; of the address, loading a junk value instead.
(if (= parent *rigid-body-queue-manager*)
(quaternion-copy! (-> s5-0 quat) (-> (the process-drawable (-> parent parent 0)) root quat))
(quaternion-copy! (-> s5-0 quat) (-> self parent 0 root quat))
)
(quaternion-copy! (-> s5-0 quat) (the-as quaternion (align16 (+ -16 (the-as int (-> self parent 0 root quat))))))
(vector-identity! (-> s5-0 scale))
(set! (-> s5-0 transv quad) (-> arg0 vel quad))
(set! (-> self pre-move-transv quad) (-> arg0 vel quad))
Expand Down
2 changes: 1 addition & 1 deletion goal_src/jak3/engine/draw/drawable.gc
Original file line number Diff line number Diff line change
Expand Up @@ -1435,7 +1435,7 @@
;; (shadow-execute-all gp-0)
)
(lightning-draw-all)
(prim-engine-execute)
;(prim-engine-execute)
(none)
)

Expand Down
4 changes: 2 additions & 2 deletions goal_src/jak3/kernel/gkernel-h.gc
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
(defconstant *kernel-major-version* 2)
(defconstant *kernel-minor-version* 0)

(defconstant DPROCESS_STACK_SIZE (#if PC_PORT #x8000 #x3800))
(defconstant PROCESS_STACK_SIZE (#if PC_PORT #x4000 #x1c00))
(defconstant DPROCESS_STACK_SIZE (#if PC_PORT #x10000 #x3800))
(defconstant PROCESS_STACK_SIZE (#if PC_PORT #x8000 #x1c00))

(#if PC_BIG_MEMORY
(defconstant PROCESS_HEAP_MULT 4) ;; 4x actors
Expand Down
41 changes: 31 additions & 10 deletions goal_src/jak3/kernel/gkernel.gc
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@
)

;; The stack for running user code.
(define *canary-1* (the-as (pointer uint64) (malloc 'global 8)))
(define *dram-stack* (the-as (pointer uint8) (malloc 'global DPROCESS_STACK_SIZE)))
(define *canary-2* (the-as (pointer uint64) (malloc 'global 8)))
(defconstant *kernel-dram-stack* (&+ *dram-stack* DPROCESS_STACK_SIZE))

;; The kernel can also run code using the scratchpad as the stack.
Expand All @@ -130,41 +132,47 @@
;; DECOMP DEVIATION
(#cond
(PC_PORT
(define *canary-4* (the-as (pointer uint64) (malloc 'global 8)))
;; we'll create a fake scratchpad:
;; make sure the scratchpad is 64kb aligned, and make it 32 kB so we can big stacks on it.
;; some (partially buggy) code in generic tie relies on 64 kB alignment.
(let* ((mem (new 'global 'array 'uint8 (* 128 1024)))
(define *fake-scratchpad-size* (* 128 1024))
(let* ((mem (new 'global 'array 'uint8 (* 2 *fake-scratchpad-size*)))
)
(define *fake-scratchpad-data* (the pointer (align-n mem (* 64 1024))))
(define *fake-scratchpad-alloc* mem)
(define *fake-scratchpad-data* (the pointer (align-n mem *fake-scratchpad-size*)))
)

;; use the same memory for the scratchpad stacks.
;; defining it as a separate thing so we can split them for debugging stack corruption easily.
(define *fake-scratchpad-stack* *fake-scratchpad-data*)
;; (define *canary-3* (the-as (pointer uint64) (malloc 'global 8)))
(define *canary-3* (the-as (pointer uint64) (malloc 'global 8)))

(defmacro scratchpad-start ()
"Get the start of the scratchpad. At least 64kB aligned."
'*fake-scratchpad-data*
)
(defmacro scratchpad-end ()
"Get the start of the scratchpad. At least 64kB aligned."
`(&+ (scratchpad-start) *fake-scratchpad-size*)
)
)
(else
(defmacro scratchpad-start ()
#x70000000
)
(defmacro scratchpad-end ()
"Get the start of the scratchpad. At least 64kB aligned."
`(&+ (scratchpad-start) (* 16 1024))
)
)
)

(defmacro scratchpad-end ()
"Get the end of the scratchpad memory"
`(&+ (scratchpad-start) (* 16 1024))
)

(defmacro in-scratchpad? (x)
"Is the given address in the scratchpad?"
`(and
(>= (the-as int ,x) (scratchpad-start))
(< (the-as int ,x) (scratchpad-end))
(<= (the-as int ,x) (scratchpad-end))
)
)

Expand Down Expand Up @@ -1525,6 +1533,10 @@
(execute-process-tree
*active-pool*
(lambda ((arg0 process))
;; (+! (-> *canary-1*) 1)
;; (+! (-> *canary-2*) 1)
;; (+! (-> *canary-3*) 1)
;; (+! (-> *canary-4*) 1)
(let ((s5-0 *kernel-context*))
(case (-> arg0 status)
(('waiting-to-run 'suspended)
Expand All @@ -1539,6 +1551,8 @@
(set! *debug-draw-pauseable* #f)
)
)
;; run the trans function.
;; (format 0 "Trans | Proc ~A | C1: ~X C2: ~X C3: ~X C4: ~X~%" (-> arg0 name) (-> *canary-1*) (-> *canary-2*) (-> *canary-3*) (-> *canary-4*))
(when (-> arg0 trans-hook)
(let ((s4-0 (new 'process 'cpu-thread arg0 'trans 256 (-> arg0 main-thread stack-top))))
(reset-and-call s4-0 (-> arg0 trans-hook))
Expand All @@ -1549,21 +1563,28 @@
(return 'dead)
)
)
;; run the main thread!
;; (format 0 "Code | Proc ~A | C1: ~X C2: ~X C3: ~X C4: ~X~%" (-> arg0 name) (-> *canary-1*) (-> *canary-2*) (-> *canary-3*) (-> *canary-4*))
(if (logtest? (-> arg0 mask) (process-mask sleep-code))
(set! (-> arg0 status) 'suspended)
((-> arg0 main-thread resume-hook) (-> arg0 main-thread))
)
;; (format 0 "Finished Code | Proc ~A | C1: ~X C2: ~X C3: ~X C4: ~X~%" (-> arg0 name) (-> *canary-1*) (-> *canary-2*) (-> *canary-3*) (-> *canary-4*))
(cond
((= (-> arg0 status) 'dead)
(set! (-> s5-0 current-process) #f)
'dead
)
(else
;; run post.
;; NOTE: post always runs on the dram stack, so you can use ja-post and use the scratchpad for anims.
(when (-> arg0 post-hook)
;; (format 0 "Post | Proc ~A | C1: ~X C2: ~X C3: ~X C4: ~X~%" (-> arg0 name) (-> *canary-1*) (-> *canary-2*) (-> *canary-3*) (-> *canary-4*))
(let ((s4-1 (new 'process 'cpu-thread arg0 'post 256 *kernel-dram-stack*)))
(reset-and-call s4-1 (-> arg0 post-hook))
(delete s4-1)
)
;; (format 0 "Finished Post | Proc ~A | C1: ~X C2: ~X C3: ~X C4: ~X~%" (-> arg0 name) (-> *canary-1*) (-> *canary-2*) (-> *canary-3*) (-> *canary-4*))
(when (= (-> arg0 status) 'dead)
(set! (-> s5-0 current-process) #f)
(return 'dead)
Expand Down Expand Up @@ -2029,7 +2050,7 @@
;; if we got the scratchpad stack, move to the fake scratchpad.
(#when PC_PORT
(when (= stack-pointer *scratch-memory-top*)
(set! stack-pointer (&+ *fake-scratchpad-stack* (* 32 1024)))
(set! stack-pointer (scratchpad-end))
)
)
(set! (-> this mask)
Expand Down
7 changes: 4 additions & 3 deletions goal_src/jak3/kernel/gstate.gc
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,17 @@
&key (stack-size #x4000)
&key (stack *scratch-memory-top*)
&key (unk 1)
&key (runtime #f)
&rest args)
"Start a new process and run an init function on it.
Returns a pointer to the new process, or #f (or is it 0?) if something goes wrong."

(with-gensyms (new-proc)
`(let ((,new-proc (the-as ,proc-type (get-process ,from ,proc-type ,stack-size ,unk))))
`(let ((,new-proc (the-as ,(if runtime 'process proc-type) (get-process ,from ,proc-type ,stack-size ,unk))))
(when ,new-proc
((method-of-type ,proc-type activate) ,new-proc ,to ,(if name name `(symbol->string ,proc-type)) ,stack)
((method-of-type ,(if runtime 'process proc-type) activate) ,new-proc ,to ,(if name name `(symbol->string ,proc-type)) ,stack)
(run-now-in-process ,new-proc ,(if init init (string->symbol (fmt #f "{}-init-by-other" proc-type))) ,@args)
(the (pointer ,proc-type) (-> ,new-proc ppointer))
(the (pointer ,(if runtime 'process proc-type)) (-> ,new-proc ppointer))
)
)
)
Expand Down
2 changes: 1 addition & 1 deletion goalc/debugger/Debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ void Debugger::read_symbol_table_jak3() {
// ASSERT(sym_offset < SYM_TABLE_MEM_SIZE / 4);

std::string str(str_buff);
if (str.length() >= 50) {
if (str.length() >= 60) {
lg::print("Invalid symbol #x{:x}!\n", sym_offset);
continue;
}
Expand Down

0 comments on commit 8e58303

Please sign in to comment.