diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 11183a4478..4812357907 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -3477,7 +3477,7 @@ ;; - Functions -(define-extern dma-buffer-add-buckets (function dma-buffer int none)) +(define-extern dma-buffer-add-buckets (function dma-buffer int dma-bucket)) (define-extern dma-buffer-patch-buckets (function dma-bucket int dma-bucket)) (define-extern dma-bucket-insert-tag (function dma-bucket bucket-id pointer (pointer dma-tag) pointer)) diff --git a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc index af309befff..7a961a5d5e 100644 --- a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc @@ -96,7 +96,8 @@ "font": [ ["L95", "(inline-array vector)", true, 250], - ["L94", "(inline-array vector)", true, 289] + ["L94", "(inline-array vector)", true, 289], + ["L96", "float", true] ], "display": [ @@ -596,9 +597,12 @@ ["L317", "uint64", true], ["L316", "uint64", true], ["L320", "uint64", true], + ["L310", "uint64", true], ["L314", "uint64", true], ["L313", "uint64", true], - ["L315", "uint64", true] + ["L315", "uint64", true], + ["L318", "uint64", true], + ["L319", "uint64", true] ], "geometry": [ diff --git a/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc b/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc index 7f17190e8e..9e2078715d 100644 --- a/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc @@ -828,6 +828,10 @@ "print-game-text": [ [16, "font-context"] ], + + "draw-string-xy": [ + [16, "font-context"] + ], "placeholder-do-not-add-below!": [] } diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index e70578fe2f..cacc4adf2d 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -432,7 +432,39 @@ "display-loop": [ [152, "v1", "(pointer int32)"], - [157, "a0", "(pointer process-drawable)"] + [157, "a0", "(pointer process-drawable)"], + [[477, 481], "a0", "dma-packet"], + [[487, 490], "a0", "gs-gif-tag"], + + [497, "a0", "(pointer gs-reg64)"], + [495, "a0", "(pointer gs-alpha)"], + + [501, "a0", "(pointer gs-reg64)"], + [499, "a0", "(pointer gs-zbuf)"], + + [505, "a0", "(pointer gs-reg64)"], + [503, "a0", "(pointer gs-test)"], + + [508, "a0", "(pointer gs-reg64)"], + [506, "a0", "(pointer uint64)"], // pabe + + [512, "a0", "(pointer gs-reg64)"], + [510, "a0", "(pointer gs-clamp)"], + + [516, "a0", "(pointer gs-reg64)"], + [514, "a0", "(pointer gs-tex1)"], + + [521, "a0", "(pointer gs-reg64)"], + [519, "a0", "(pointer gs-texa)"], + + [525, "a0", "(pointer gs-reg64)"], + [523, "a0", "(pointer gs-texclut)"], + + [529, "a0", "(pointer gs-reg64)"], + [527, "a0", "(pointer gs-fogcol)"], + + [[588, 591], "v1", "dma-packet"], + [[672, 675], "v1", "dma-packet"] ], "load-game-text-info": [[4, "v1", "game-text-info"]], diff --git a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc index b583614271..f04901b797 100644 --- a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc @@ -1385,7 +1385,11 @@ }, "display-loop": { - "vars": {} + "vars": { + "s3-0":"debug-buf", + "gp-0":"disp", + "s5-2":"debug-txt-buf" + } }, "adgif-shader-login": { diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index 17e31fc7d3..32cead00de 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -73,6 +73,7 @@ set(RUNTIME_SOURCE overlord/stream.cpp graphics/gfx.cpp graphics/display.cpp + graphics/sceGraphicsInterface.cpp system/vm/dmac.cpp system/vm/vm.cpp) diff --git a/game/graphics/gfx.cpp b/game/graphics/gfx.cpp index 4ddcb20a3e..a1ee6c1bec 100644 --- a/game/graphics/gfx.cpp +++ b/game/graphics/gfx.cpp @@ -5,6 +5,9 @@ #include "gfx.h" #include +#include +#include +#include #include "common/log/log.h" #include "game/runtime.h" #include "display.h" @@ -13,6 +16,16 @@ namespace Gfx { +struct GraphicsData { + std::mutex sync_mutex; + std::condition_variable sync_cv; + u64 frame_idx = 0; +}; + +std::unique_ptr g_gfx_data; + +bool g_is_initialized = false; + void GlfwErrorCallback(int err, const char* msg) { lg::error("GLFW ERR {}: " + std::string(msg), err); } @@ -33,6 +46,8 @@ u32 Init() { Display::InitDisplay(640, 480, "testy", Display::display); } + g_gfx_data = std::make_unique(); + g_is_initialized = true; return 0; } @@ -48,6 +63,13 @@ void Loop(std::function f) { glfwSwapBuffers(Display::display); + // toggle even odd and wake up anybody waiting on vsync. + { + std::unique_lock lock(g_gfx_data->sync_mutex); + g_gfx_data->frame_idx++; + g_gfx_data->sync_cv.notify_all(); + } + // poll events TODO integrate input with cpad glfwPollEvents(); @@ -61,6 +83,8 @@ void Loop(std::function f) { } u32 Exit() { + g_is_initialized = false; + g_gfx_data.reset(); lg::debug("gfx exit"); Display::KillDisplay(Display::display); glfwTerminate(); @@ -68,4 +92,23 @@ u32 Exit() { return 0; } +bool is_initialized() { + return g_is_initialized; +} + +/*! + * Wait for the next vsync. Returns 0 or 1 depending on if frame is even or odd. + */ +u32 vsync() { + if (!g_gfx_data) { + return 0; + } + + std::unique_lock lock(g_gfx_data->sync_mutex); + auto init_frame = g_gfx_data->frame_idx; + g_gfx_data->sync_cv.wait(lock, [=] { return g_gfx_data->frame_idx > init_frame; }); + + return g_gfx_data->frame_idx & 1; +} + } // namespace Gfx diff --git a/game/graphics/gfx.h b/game/graphics/gfx.h index abc1171fee..639f2a6af6 100644 --- a/game/graphics/gfx.h +++ b/game/graphics/gfx.h @@ -19,6 +19,10 @@ u32 Init(); void Loop(std::function f); u32 Exit(); +u32 vsync(); +void wait_for_render_completion(); +bool is_initialized(); + } // namespace Gfx #endif // RUNTIME_GFX_H diff --git a/game/graphics/sceGraphicsInterface.cpp b/game/graphics/sceGraphicsInterface.cpp new file mode 100644 index 0000000000..2c6180c607 --- /dev/null +++ b/game/graphics/sceGraphicsInterface.cpp @@ -0,0 +1,33 @@ +#include "game/graphics/sceGraphicsInterface.h" +#include "common/util/assert.h" +#include "game/graphics/gfx.h" + +#include + +/*! + * Wait for rendering to complete. + * In the PC Port, this currently does nothing. + * + * From my current understanding, we can get away with this and just sync everything on vsync. + * However, there are two calls to this per frame. + * + * But I don't fully understand why they call sceGsSyncPath where they do (right before depth cue) + * so maybe the depth cue looks at the z-buffer of the last rendered frame when setting up the dma + * for the next frame? The debug drawing also happens after this. + * + * The second call is right before swapping buffers/vsync, so that makes sense. + * + * + */ +u32 sceGsSyncPath(u32 mode, u32 timeout) { + assert(mode == 0 && timeout == 0); + return 0; +} + +/*! + * Actual vsync. + */ +u32 sceGsSyncV(u32 mode) { + assert(mode == 0); + return Gfx::vsync(); +} diff --git a/game/graphics/sceGraphicsInterface.h b/game/graphics/sceGraphicsInterface.h new file mode 100644 index 0000000000..fe3cacf90c --- /dev/null +++ b/game/graphics/sceGraphicsInterface.h @@ -0,0 +1,13 @@ +#pragma once + +#include "common/common_types.h" +#include "common/util/assert.h" + +/*! + * @file sceGraphicInterface.h + * This file contains implementations of the SCE graphics library functions that manage + * synchronization and settings. + */ + +u32 sceGsSyncPath(u32 mode, u32 timeout); +u32 sceGsSyncV(u32 mode); \ No newline at end of file diff --git a/game/kernel/kboot.cpp b/game/kernel/kboot.cpp index 0399b89aaa..3234a87775 100644 --- a/game/kernel/kboot.cpp +++ b/game/kernel/kboot.cpp @@ -170,7 +170,7 @@ void KernelCheckAndDispatch() { } auto time_ms = kernel_dispatch_timer.getMs(); - if (time_ms > 3) { + if (time_ms > 30) { printf("Kernel dispatch time: %.3f ms\n", time_ms); } diff --git a/game/kernel/kmachine.cpp b/game/kernel/kmachine.cpp index ec4f172c31..9944d3d7f9 100644 --- a/game/kernel/kmachine.cpp +++ b/game/kernel/kmachine.cpp @@ -30,6 +30,7 @@ #include "common/symbols.h" #include "common/log/log.h" #include "common/util/Timer.h" +#include "game/graphics/sceGraphicsInterface.h" #include "game/system/vm/vm.h" using namespace ee; @@ -417,7 +418,12 @@ u64 CPadOpen(u64 cpad_info, s32 pad_number) { // TODO CPadGetData void CPadGetData() { - assert(false); + static bool warned = false; + if (!warned) { + lg::warn("ignoring calls to CPadGetData"); + warned = true; + } + } // TODO InstallHandler @@ -429,6 +435,10 @@ void InstallDebugHandler() { assert(false); } +void send_gfx_dma_chain(u32 bank, u32 chain) { + +} + /*! * Open a file-stream. Name is a GOAL string. Mode is a GOAL symbol. Use 'read for readonly * and anything else for write only. @@ -565,7 +575,7 @@ void DecodeTime() { // TODO PutDisplayEnv void PutDisplayEnv() { - assert(false); + //assert(false); } /*! @@ -587,6 +597,7 @@ void InitMachine_PCPort() { // PC Port added functions make_function_symbol_from_c("__read-ee-timer", (void*)read_ee_timer); make_function_symbol_from_c("__mem-move", (void*)c_memmove); + make_function_symbol_from_c("__send-gfx-dma-chain", (void*)send_gfx_dma_chain); } /*! @@ -598,7 +609,7 @@ void InitMachine_PCPort() { */ void InitMachineScheme() { make_function_symbol_from_c("put-display-env", (void*)PutDisplayEnv); // used in drawable - make_function_symbol_from_c("syncv", (void*)ee::sceGsSyncV); // used in drawable + make_function_symbol_from_c("syncv", (void*)sceGsSyncV); // used in drawable make_function_symbol_from_c("sync-path", (void*)sceGsSyncPath); // used make_function_symbol_from_c("reset-path", (void*)sceGsResetPath); // used in dma make_function_symbol_from_c("reset-graph", (void*)sceGsResetGraph); // used diff --git a/game/sce/stubs.cpp b/game/sce/stubs.cpp index efd82b25b7..046f07eec2 100644 --- a/game/sce/stubs.cpp +++ b/game/sce/stubs.cpp @@ -4,13 +4,7 @@ namespace ee { -void sceGsSyncV() { - assert(false); -} -void sceGsSyncPath() { - assert(false); -} void sceGsResetGraph() { assert(false); diff --git a/game/sce/stubs.h b/game/sce/stubs.h index e07de52d95..1b902657f6 100644 --- a/game/sce/stubs.h +++ b/game/sce/stubs.h @@ -3,8 +3,6 @@ #include "common/common_types.h" namespace ee { -void sceGsSyncV(); -void sceGsSyncPath(); void sceGsPutIMR(); void sceGsGetIMR(); void sceGsExecStoreImage(); diff --git a/goal_src/engine/dma/dma-bucket.gc b/goal_src/engine/dma/dma-bucket.gc index 5bb55edc85..651dc76dce 100644 --- a/goal_src/engine/dma/dma-bucket.gc +++ b/goal_src/engine/dma/dma-bucket.gc @@ -32,7 +32,10 @@ (defun dma-buffer-add-buckets ((dma-buf dma-buffer) (count int)) "Add count buckets. Each bucket is initialized as empty and won't transfer anything." - (let ((current-bucket (the-as dma-bucket (-> dma-buf base)))) + (let* ((initial-bucket (the-as dma-bucket (-> dma-buf base))) + (current-bucket initial-bucket)) + + ;;(let ((current-bucket (the-as dma-bucket (-> dma-buf base)))) (dotimes (i count) ;; set the DMA tag to next, with a qwc of zero. ;; the address is set to the next bucket. @@ -51,8 +54,8 @@ ) ;; update base ptr of dma-buffer to point after the buckets. (set! (-> dma-buf base) (the-as pointer current-bucket)) + initial-bucket ) - (none) ) @@ -74,7 +77,6 @@ (defun dma-bucket-insert-tag ((base dma-bucket) (idx bucket-id) (tag-start pointer) (tag-end (pointer dma-tag))) "Add a dma chain to the idx bucket" - ;; find the bucket (let ((bucket (the-as dma-bucket (&+ base (the-as uint (shl idx 4)))))) ;; update our last bucket to point to this one. diff --git a/goal_src/engine/dma/dma.gc b/goal_src/engine/dma/dma.gc index 167f299f0f..ac0fbea082 100644 --- a/goal_src/engine/dma/dma.gc +++ b/goal_src/engine/dma/dma.gc @@ -89,9 +89,9 @@ (defun dma-send-chain ((arg0 dma-bank-source) (tadr uint)) "Send DMA! tadr should be a tag address, possibly in spad ram. - This is useful for sending to VIF. - Tag transfer is enabled, and DIR is set so a VIF1 transfer - goes from tadr -> VIF." + This is useful for sending to VIF. + Tag transfer is enabled, and DIR is set so a VIF1 transfer + goes from tadr -> VIF." (dma-sync (the-as pointer arg0) 0 0) (flush-cache 0) (.sync.l) @@ -102,15 +102,16 @@ ;;(set! (-> arg0 chcr) 325) (set! (-> arg0 chcr) (new 'static 'dma-chcr - :dir 1 ;; from memory - :mod 1 ;; source chain - :tte 1 ;; send tags - :str 1) ;; go! + :dir 1 ;; from memory + :mod 1 ;; source chain + :tte 1 ;; send tags + :str 1) ;; go! ) (.sync.l) (none) ) + (defun dma-send-chain-no-tte ((arg0 dma-bank-source) (arg1 uint)) "Send DMA chain! TTE bit is not set, don't transfer tags. This is never used." diff --git a/goal_src/engine/draw/drawable.gc b/goal_src/engine/draw/drawable.gc index 0bf12ed0f7..f5439b46be 100644 --- a/goal_src/engine/draw/drawable.gc +++ b/goal_src/engine/draw/drawable.gc @@ -78,6 +78,7 @@ "Set up a new frame. Call this before drawing anything. new-frame-idx is the display frame that will be set up. odd-even is the odd-even of the new frame" + ;; due to a HW bug in the PS2, you must set this. ;;(set! (-> (the-as vif-bank #x10003c00) err me0) 1) @@ -87,12 +88,34 @@ ;; due to vsync, we should never go too fast. (let ((time-ratio (the float (+ (/ (timer-count (the-as timer-bank #x10000800)) (the-as uint *ticks-per-frame*)) - 1 + 1 ;; so we round up. ) ) + ) ) + (let ((float-time-ratio (/ (the float (timer-count (the-as timer-bank #x10000800))) (the float *ticks-per-frame*)))) + ;; on the PS2, if you have > 1/60 seconds between frames, it means you missed a vsync. + ;; this doesn't seem to be the case on my machine. It appears that glfwSwapBuffers sometimes returns ~1 ms early, + ;; making the next frame ~1 ms too long. + + ;; to work around with, we internally run the game at 60 fps if it appears to be slightly too slow. + ;; if we actually do miss a frame, the time ratio will be around 2. + + (#when PC_PORT + (if (< float-time-ratio 1.3) + (set! time-ratio 1.0) + ) + #| + (if (> time-ratio 1.) + (format #t "LAG ~f frames~%" (- time-ratio 1.)) + ) + |# + ) + ) + + ;; inform display system of our speed. This will adjust the scaling used in all physics calculations (set-time-ratios *display* time-ratio) @@ -373,6 +396,15 @@ 0 ) +(define *surrogate-dma-buffer* (the dma-buffer #f)) + +(defmacro cpu-usage () + "print out the cpu usage of the most recently rendered frame" + `(format #t "CPU: ~,,2f%~%frame-time: ~,,1fms~%" + (* 100. (/ (the float (current-display-frame run-time)) *ticks-per-frame*)) + (* 1000. (/ 1. 60.) (/ (the float (current-display-frame run-time)) *ticks-per-frame*)) + ) + ) (defun display-sync ((disp display)) "Switch frames! This assumes that you have called display-frame-finish on the current frame. @@ -427,7 +459,8 @@ ;; begin rendering the next frame (let ((dma-buf-to-send (-> disp frames frame-idx frame calc-buf))) (if (nonzero? (dma-buffer-length dma-buf-to-send)) - (dma-buffer-send-chain (the-as dma-bank-source #x10009000) + ;; was dma-send-chain originally. + (__send-gfx-dma-chain (the-as dma-bank-source #x10009000) (cond ;; some buffer for debugging, not used (*surrogate-dma-buffer* diff --git a/goal_src/engine/game/main-h.gc b/goal_src/engine/game/main-h.gc index 8a17960817..c245449480 100644 --- a/goal_src/engine/game/main-h.gc +++ b/goal_src/engine/game/main-h.gc @@ -138,3 +138,4 @@ (define-extern set-master-mode (function symbol none)) (define-extern paused? (function symbol)) +(define-extern toggle-pause (function int)) \ No newline at end of file diff --git a/goal_src/engine/game/main.gc b/goal_src/engine/game/main.gc index 7233659647..620ae43c38 100644 --- a/goal_src/engine/game/main.gc +++ b/goal_src/engine/game/main.gc @@ -135,7 +135,7 @@ (-> *setting-control* default process-mask) ) ) - (sound-group-continue (the-as uint 255)) + ;; (sound-group-continue (the-as uint 255)) TODO (we need to flush sound commands) ;;(hide-progress-screen) TODO ) ) @@ -944,6 +944,10 @@ ) +(defmacro dloop-dbg (str &rest args) + `(format 0 ,(string-append "[display-loop] " str) ,@args) + ) + (defun display-loop () "This is in progress..." @@ -957,8 +961,10 @@ (set! *teleport* #t) (update-per-frame-settings! *setting-control*) ;;(init-time-of-day-context *time-of-day-context*) TODO - ;;(display-sync disp) - ;; (swap-display disp) + (format 0 "DISPLAY LOOP calling sync~%") + (display-sync disp) + (format 0 "first call to sync done~%") + (swap-display disp) ;; touching list ;; bler init ;; collide dma @@ -977,24 +983,278 @@ ;; update-camera ;; draw hook ;; menu hook - ;; update-current-level-availabe-to-progress + (add-ee-profile-frame 'draw :g #x40) + + ;; make-current-level-availabe-to-progress ;; update-task-hitns - ;; load-level-textu-files (load-level-text-files -1) - ;; sync/timeout + + (add-ee-profile-frame 'unknown-cpu-time) + ;; collect perf stats + (read! (-> *perf-stats* data (perf-stat-bucket all-code))) + + (when (nonzero? (sync-path 0 0)) + (*dma-timeout-hook*) + (reset-vif1-path) + (if *debug-segment* + (format + 0 + "profile bar at ~D.~%" + (-> + *display* + frames + (-> *display* on-screen) + frame + profile-bar + 1 + profile-frame-count + ) + ) + ) + ) + (reset! (-> *perf-stats* data (perf-stat-bucket all-code))) ;; depth cue ;; screen filter - ;; letterbox - ;; blackout - ;; debug draw - ;; deci count - ;; file info - ;; pause text - ;; iop info - ;; mc info - ;; dma memory usage + + ;; run letterbox if needed + (when (or (movie?) + (< (the-as int (-> *display* base-frame-counter)) + (the-as int (-> *game-info* letterbox-time)) + ) + ) + (if (< (the-as int (-> *game-info* letterbox-time)) + (the-as int (-> *display* base-frame-counter)) + ) + (set! (-> *game-info* letterbox-time) (-> *display* base-frame-counter)) + ) + (if (= (-> *setting-control* current aspect-ratio) 'aspect4x3) + (letterbox) + ) + ) + + ;; do blackout if needed. + (if (< (the-as int (-> *display* base-frame-counter)) + (the-as int (-> *game-info* blackout-time)) + ) + (set! (-> *setting-control* default bg-a-force) 1.0) + (set! (-> *setting-control* default bg-a-force) 0.0) + ) + (read! (-> *perf-stats* data (perf-stat-bucket all-code))) + + ;; grab a buffer for drawing debug stuff. + ;; we might draw even outside of debug mode if cheat-mode is disabled. + (let ((debug-txt-buf + (-> (if *debug-segment* + (-> disp frames (-> disp on-screen) frame debug-buf) + (-> disp frames (-> disp on-screen) frame global-buf) + ) + base + ) + ) + ) + + ;; debug drawing + (when *debug-segment* + (debug-draw-buffers) ;; lines/text + + ;; debug dma + (let* ((debug-buf (-> disp frames (-> disp on-screen) frame debug-buf)) + (s4-3 (-> debug-buf base)) + ) + (when *display-profile* + (let* ((v1-172 debug-buf) + (a0-77 (the-as object (-> v1-172 base))) + ) + (set! (-> (the-as dma-packet a0-77) dma) (new 'static 'dma-tag :qwc #xa :id (dma-tag-id cnt))) + (set! (-> (the-as dma-packet a0-77) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet a0-77) vif1) (new 'static 'vif-tag :imm #xa :cmd (vif-cmd direct) :msk #x1)) + (set! (-> v1-172 base) (&+ (the-as pointer a0-77) 16)) + ) + (let* ((v1-173 debug-buf) + (a0-79 (the-as object (-> v1-173 base))) + ) + (set! (-> (the-as gs-gif-tag a0-79) tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x9)) + (set! (-> (the-as gs-gif-tag a0-79) regs) + (new 'static 'gif-tag-regs + :regs0 (gif-reg-id a+d) + :regs1 (gif-reg-id a+d) + :regs2 (gif-reg-id a+d) + :regs3 (gif-reg-id a+d) + :regs4 (gif-reg-id a+d) + :regs5 (gif-reg-id a+d) + :regs6 (gif-reg-id a+d) + :regs7 (gif-reg-id a+d) + :regs8 (gif-reg-id a+d) + :regs9 (gif-reg-id a+d) + :regs10 (gif-reg-id a+d) + :regs11 (gif-reg-id a+d) + :regs12 (gif-reg-id a+d) + :regs13 (gif-reg-id a+d) + :regs14 (gif-reg-id a+d) + :regs15 (gif-reg-id a+d) + ) + ) + (set! (-> v1-173 base) (&+ (the-as pointer a0-79) 16)) + ) + (let* ((v1-174 debug-buf) + (a0-81 (-> v1-174 base)) + ) + (set! (-> (the-as (pointer gs-alpha) a0-81) 0) (new 'static 'gs-alpha :b #x1 :d #x1)) + (set! (-> (the-as (pointer gs-reg64) a0-81) 1) (gs-reg64 alpha-1)) + (set! (-> (the-as (pointer gs-zbuf) a0-81) 2) (new 'static 'gs-zbuf :zbp #x1c0 :psm (gs-psm ct24) :zmsk #x1)) + (set! (-> (the-as (pointer gs-reg64) a0-81) 3) (gs-reg64 zbuf-1)) + (set! (-> (the-as (pointer gs-test) a0-81) 4) (new 'static 'gs-test :zte #x1 :ztst (gs-ztest always))) + (set! (-> (the-as (pointer gs-reg64) a0-81) 5) (gs-reg64 test-1)) + (set! (-> (the-as (pointer uint64) a0-81) 6) (the-as uint 0)) + (set! (-> (the-as (pointer gs-reg64) a0-81) 7) (gs-reg64 pabe)) + (set! (-> (the-as (pointer gs-clamp) a0-81) 8) + (new 'static 'gs-clamp + :wms (gs-tex-wrap-mode clamp) + :wmt (gs-tex-wrap-mode clamp) + ) + ) + (set! (-> (the-as (pointer gs-reg64) a0-81) 9) (gs-reg64 clamp-1)) + (set! (-> (the-as (pointer gs-tex1) a0-81) 10) + (new 'static 'gs-tex1 :mmag #x1 :mmin #x1) + ) + (set! (-> (the-as (pointer gs-reg64) a0-81) 11) (gs-reg64 tex1-1)) + (set! (-> (the-as (pointer gs-texa) a0-81) 12) + (new 'static 'gs-texa :ta1 #x80) + ) + (set! (-> (the-as (pointer gs-reg64) a0-81) 13) (gs-reg64 texa)) + (set! (-> (the-as (pointer gs-texclut) a0-81) 14) + (new 'static 'gs-texclut :cbw #x4) + ) + (set! (-> (the-as (pointer gs-reg64) a0-81) 15) (gs-reg64 texclut)) + (set! (-> (the-as (pointer gs-fogcol) a0-81) 16) + (the-as gs-fogcol *fog-color*) + ) + (set! (-> (the-as (pointer gs-reg64) a0-81) 17) (gs-reg64 fogcol)) + (set! (-> v1-174 base) (&+ a0-81 144)) + ) + + ;; draw the profile bars + (dotimes (s2-0 2) + (let ((s1-0 (-> disp frames (-> disp on-screen) frame profile-bar s2-0))) + (add-end-frame + s1-0 + 'end-draw + (new 'static 'rgba :r #x40 :g #x40 :b #x40 :a #x40) + ) + (draw s1-0 debug-buf (* 10 s2-0)) + ) + 0 + ) + ) ;; end profiler draw + + + (when *display-deci-count* + (let ((s2-1 draw-string-xy)) + (format (clear *temp-string*) "~D" *deci-count*) + (s2-1 *temp-string* debug-buf 448 210 0 3) + ) + ) + + (display-file-info) + + ;; add it all to debug-draw1 + (let ((a3-6 (-> debug-buf base))) + (let ((v1-188 (the-as object (-> debug-buf base)))) + (set! (-> (the-as dma-packet v1-188) dma) + (new 'static 'dma-tag :id (dma-tag-id next)) + ) + (set! (-> (the-as dma-packet v1-188) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet v1-188) vif1) (new 'static 'vif-tag)) + (set! (-> debug-buf base) (&+ (the-as pointer v1-188) 16)) + ) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) frame bucket-group) + (bucket-id debug-draw1) + s4-3 + (the-as (pointer dma-tag) a3-6) + ) + ) + ) ;; end dma let + ) ;; end debug-segment + + ;; draw pause text. + (let* ((s3-1 (if *debug-segment* + (-> disp frames (-> disp on-screen) frame debug-buf) + (-> disp frames (-> disp on-screen) frame global-buf) + ) + ) + (s4-4 (-> s3-1 base)) + ) + (if (= *master-mode* 'pause) + (draw-string-xy + (lookup-text! *common-text* (game-text-id pause) #f) + s3-1 256 160 3 39) + ) + + ;; draw console text on screen + (let ((a3-8 (the int (draw-string *stdcon0* s3-1 *font-context*)))) + (draw-string-xy *stdcon1* + s3-1 + (the int (-> *font-context* origin x)) + a3-8 + 0 + 3 + ) + ) + + ;; draw misc info + (if *display-iop-info* + (show-iop-info s3-1) + ) + (if *display-memcard-info* + (show-mc-info s3-1) + ) + + ;; draw to debug0 + (let ((a3-9 (-> s3-1 base))) + (let ((v1-215 (the-as object (-> s3-1 base)))) + (set! (-> (the-as dma-packet v1-215) dma) + (new 'static 'dma-tag :id (dma-tag-id next)) + ) + (set! (-> (the-as dma-packet v1-215) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet v1-215) vif1) (new 'static 'vif-tag)) + (set! (-> s3-1 base) (&+ (the-as pointer v1-215) 16)) + ) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) frame bucket-group) + (bucket-id debug-draw0) + s4-4 + (the-as (pointer dma-tag) a3-9) + ) + ) + ) + (let ((v1-220 *dma-mem-usage*)) + (when (nonzero? v1-220) + (set! (-> v1-220 length) (max 85 (-> v1-220 length))) + (set! (-> v1-220 data 84 name) "debug") + (+! (-> v1-220 data 84 count) 1) + (+! (-> v1-220 data 84 used) + (&- (-> (if *debug-segment* + (-> disp frames (-> disp on-screen) frame debug-buf) + (-> disp frames (-> disp on-screen) frame global-buf) + ) + base + ) + (the-as uint debug-txt-buf) + ) + ) + (set! (-> v1-220 data 84 total) (-> v1-220 data 84 used)) + ) + ) + ) + ;; console buffers + (set! *stdcon* (clear *stdcon0*)) + + ;; here it is: + (swap-display disp) + ;; swap display ;; particles ;; vif0 collid diff --git a/goal_src/engine/gfx/font.gc b/goal_src/engine/gfx/font.gc index a9a6b2d203..38c16edec0 100644 --- a/goal_src/engine/gfx/font.gc +++ b/goal_src/engine/gfx/font.gc @@ -588,7 +588,7 @@ "Draw a string." ;; note: this function is > 4000 instructions and around 80 kB of x86-64. ;; it contains over 2000 iregisters. - (declare (print-asm)) + ;;(declare (print-asm)) (local-vars (r0 uint128) (v0-0 float) @@ -2132,3 +2132,19 @@ v0-0 ) ) + +(defun draw-string-xy ((arg0 string) (arg1 dma-buffer) (arg2 int) (arg3 int) (arg4 int) (arg5 int)) + (let ((a2-2 (new 'stack 'font-context + *font-default-matrix* + arg2 + arg3 + 0.0 + arg4 + (the-as uint arg5) + ) + ) + ) + (draw-string arg0 arg1 a2-2) + ) + (none) + ) diff --git a/goal_src/engine/gfx/merc/merc.gc b/goal_src/engine/gfx/merc/merc.gc index 5c2a0d3bca..aa84dc70be 100644 --- a/goal_src/engine/gfx/merc/merc.gc +++ b/goal_src/engine/gfx/merc/merc.gc @@ -5,3 +5,6 @@ ;; name in dgo: merc ;; dgos: GAME, ENGINE +(defun merc-vu1-init-buffers () + ;; TODO stub + ) diff --git a/goal_src/engine/gfx/tie/tie-methods.gc b/goal_src/engine/gfx/tie/tie-methods.gc index 3558626d87..14e4287926 100644 --- a/goal_src/engine/gfx/tie/tie-methods.gc +++ b/goal_src/engine/gfx/tie/tie-methods.gc @@ -5,3 +5,6 @@ ;; name in dgo: tie-methods ;; dgos: GAME, ENGINE +(defun tie-init-buffers ((dma-buf dma-buffer)) + ;; TODO stub. + ) diff --git a/goal_src/engine/ps2/timer-h.gc b/goal_src/engine/ps2/timer-h.gc index ddddcabf08..bf6f7c6de6 100644 --- a/goal_src/engine/ps2/timer-h.gc +++ b/goal_src/engine/ps2/timer-h.gc @@ -172,6 +172,17 @@ ) ) +(defmacro add-ee-profile-frame (name &key (r 0) &key (g 0) &key (b 0) &key (a #x80)) + `(if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + ,name + (new 'static 'rgba :r ,r :g ,g :b ,b :a ,a) + ) + ) + ) + + ;; tentative name (defmethod get-last-frame-time-stamp profile-bar ((obj profile-bar)) "Returns the timestamp of the last (non-remaining) frame on the profiler bar." diff --git a/goal_src/engine/ui/progress-h.gc b/goal_src/engine/ui/progress-h.gc index 2d070bbb26..3411c5c9f2 100644 --- a/goal_src/engine/ui/progress-h.gc +++ b/goal_src/engine/ui/progress-h.gc @@ -142,7 +142,7 @@ (dummy-29 () none 29) (dummy-30 () none 30) (dummy-31 () none 31) - (dummy-32 () none 32) + (dummy-32 (_type_) none 32) (dummy-33 () none 33) (dummy-34 () none 34) (dummy-35 () none 35) @@ -183,3 +183,4 @@ (define-extern activate-orb-all (function int int)) ;; maybe in hud? (define-extern progress-allowed? (function symbol)) (define-extern pause-allowed? (function symbol)) +(define-extern deactivate-progress (function none)) \ No newline at end of file diff --git a/goal_src/engine/ui/progress/progress.gc b/goal_src/engine/ui/progress/progress.gc index fa963f8d4b..82eb2afa38 100644 --- a/goal_src/engine/ui/progress/progress.gc +++ b/goal_src/engine/ui/progress/progress.gc @@ -15,3 +15,65 @@ (= (-> *progress-process* 0 in-out-position) 4096) ) ) + +(defun deactivate-progress () + ;; todo stub + ) + +(defun progress-allowed? () + (with-pp + (not + (or + (-> *setting-control* current talking) + (-> *setting-control* current movie) + (movie?) + (handle->process (-> *game-info* pov-camera-handle)) + (handle->process (-> *game-info* other-camera-handle)) + (< + (the-as int (-> *display* base-frame-counter)) + (the-as int (-> *game-info* letterbox-time)) + ) + (< + (the-as int (-> *display* base-frame-counter)) + (the-as int (-> *game-info* blackout-time)) + ) + (!= (-> *setting-control* current bg-a) 0.0) + (!= (-> *setting-control* current bg-a-force) 0.0) + (not (-> *setting-control* current allow-progress)) + (or + (and + (handle->process (-> *game-info* auto-save-proc)) + (let ((a1-3 (new 'stack-no-clear 'event-message-block))) + (set! (-> a1-3 from) pp) + (set! (-> a1-3 num-params) 0) + (set! (-> a1-3 message) 'progress-allowed?) + (not + (send-event-function + (handle->process (-> *game-info* auto-save-proc)) + a1-3 + ) + ) + ) + ) + (not *target*) + ) + ) + ) + ) + ) + +(defun pause-allowed? () + (not + (or + (< + (the-as int (-> *display* base-frame-counter)) + (the-as int (-> *game-info* blackout-time)) + ) + (!= (-> *setting-control* current bg-a) 0.0) + (!= (-> *setting-control* current bg-a-force) 0.0) + (not (-> *setting-control* current allow-pause)) + (handle->process (-> *game-info* auto-save-proc)) + (not *target*) + ) + ) + ) \ No newline at end of file diff --git a/goal_src/goal-lib.gc b/goal_src/goal-lib.gc index 552d3cd7eb..33c01e4b55 100644 --- a/goal_src/goal-lib.gc +++ b/goal_src/goal-lib.gc @@ -705,5 +705,14 @@ `(make ,(string-append "GROUP:" name) :verbose ,verbose :force ,force) ) +(defmacro rl () + `(begin + (make-group "iso") + (lg) + (dbg) + ) + ) + ;; load the default project (load-project "goal_src/game.gp") + diff --git a/goal_src/kernel-defs.gc b/goal_src/kernel-defs.gc index 75b040f58c..73d6e95340 100644 --- a/goal_src/kernel-defs.gc +++ b/goal_src/kernel-defs.gc @@ -136,11 +136,12 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; put-display-env -;; syncv -(define-extern sync-path (function int int none)) +(define-extern put-display-env (function object none)) +(define-extern syncv (function int int)) +(define-extern sync-path (function int int int)) (define-extern reset-path (function none)) (define-extern reset-graph (function int int int int none)) + ;; dma-sync (define-extern dma-sync (function pointer int int int)) ;; gs-put-imr @@ -180,6 +181,7 @@ ;; PC Port functions (define-extern __read-ee-timer (function uint)) (define-extern __mem-move (function pointer pointer uint none)) +(define-extern __send-gfx-dma-chain (function object object none)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ksound - InitSoundScheme diff --git a/goalc/compiler/CodeGenerator.cpp b/goalc/compiler/CodeGenerator.cpp index c36ff35962..6c0e323664 100644 --- a/goalc/compiler/CodeGenerator.cpp +++ b/goalc/compiler/CodeGenerator.cpp @@ -32,7 +32,7 @@ std::vector CodeGenerator::run(const TypeSystem* ts) { f->name().c_str()); throw std::runtime_error("Failed to codegen."); } - m_gen.add_function_to_seg(f->segment, &m_debug_info->add_function(f->name())); + m_gen.add_function_to_seg(f->segment, &m_debug_info->add_function(f->name(), m_fe->name())); } // next, add all static objects. diff --git a/goalc/debugger/DebugInfo.h b/goalc/debugger/DebugInfo.h index e10ced32a6..a1d69a3ef4 100644 --- a/goalc/debugger/DebugInfo.h +++ b/goalc/debugger/DebugInfo.h @@ -19,6 +19,7 @@ struct FunctionDebugInfo { u32 length; u8 seg; std::string name; + std::string obj_name; std::vector irs; std::vector instructions; // contains mapping to IRs @@ -34,12 +35,13 @@ class DebugInfo { public: explicit DebugInfo(std::string obj_name); - FunctionDebugInfo& add_function(const std::string& name) { + FunctionDebugInfo& add_function(const std::string& name, const std::string& obj_name) { if (m_functions.find(name) != m_functions.end()) { assert(false); } auto& result = m_functions[name]; result.name = name; + result.obj_name = obj_name; return result; } diff --git a/goalc/debugger/Debugger.cpp b/goalc/debugger/Debugger.cpp index 88f7520e51..aff84e1954 100644 --- a/goalc/debugger/Debugger.cpp +++ b/goalc/debugger/Debugger.cpp @@ -216,7 +216,7 @@ std::vector Debugger::get_backtrace(u64 rip, u64 rsp) { if (frame.rip_info.knows_function && frame.rip_info.func_debug && frame.rip_info.func_debug->stack_usage) { - fmt::print("{}\n", frame.rip_info.function_name); + fmt::print("{} from {}\n", frame.rip_info.function_name, frame.rip_info.func_debug->obj_name); // we're good! u64 rsp_at_call = rsp + *frame.rip_info.func_debug->stack_usage;