From 7018827a50f45ad44f5619c0e06338c679e1277c Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Sat, 1 May 2021 15:51:53 -0400 Subject: [PATCH] decompile display (#408) --- decompiler/IR2/bitfields.cpp | 29 +- decompiler/config/all-types.gc | 89 +- .../jak1_ntsc_black_label/label_types.jsonc | 3 +- .../jak1_ntsc_black_label/type_casts.jsonc | 105 +- .../jak1_ntsc_black_label/var_names.jsonc | 110 +- goal_src/engine/camera/math-camera-h.gc | 3 + goal_src/engine/camera/math-camera.gc | 14 +- goal_src/engine/gfx/hw/display-h.gc | 106 +- goal_src/engine/gfx/hw/display.gc | 1015 ++++++++++++++++ goal_src/engine/gfx/hw/video-h.gc | 1 + goalc/emitter/Register.cpp | 2 +- .../reference/all_forward_declarations.gc | 70 +- test/decompiler/reference/display-h_REF.gc | 40 +- test/decompiler/reference/display_REF.gc | 1059 +++++++++++++++++ test/offline/offline_test_main.cpp | 16 +- 15 files changed, 2583 insertions(+), 79 deletions(-) create mode 100644 test/decompiler/reference/display_REF.gc diff --git a/decompiler/IR2/bitfields.cpp b/decompiler/IR2/bitfields.cpp index cd285502c9..ff63438777 100644 --- a/decompiler/IR2/bitfields.cpp +++ b/decompiler/IR2/bitfields.cpp @@ -15,7 +15,11 @@ namespace decompiler { BitfieldStaticDefElement::BitfieldStaticDefElement(const TypeSpec& type, const std::vector& field_defs) - : m_type(type), m_field_defs(field_defs) {} + : m_type(type), m_field_defs(field_defs) { + for (auto& x : field_defs) { + x.value->parent_element = this; + } +} BitfieldStaticDefElement::BitfieldStaticDefElement( const TypeSpec& type, @@ -53,11 +57,28 @@ goos::Object BitfieldStaticDefElement::to_form_internal(const Env& env) const { void BitfieldStaticDefElement::apply(const std::function& f) { f(this); + for (auto& x : m_field_defs) { + x.value->apply(f); + } } -void BitfieldStaticDefElement::apply_form(const std::function&) {} -void BitfieldStaticDefElement::collect_vars(RegAccessSet&, bool) const {} -void BitfieldStaticDefElement::get_modified_regs(RegSet&) const {} +void BitfieldStaticDefElement::apply_form(const std::function& f) { + for (auto& x : m_field_defs) { + x.value->apply_form(f); + } +} +void BitfieldStaticDefElement::collect_vars(RegAccessSet& vars, bool recursive) const { + if (recursive) { + for (auto& x : m_field_defs) { + x.value->collect_vars(vars, recursive); + } + } +} +void BitfieldStaticDefElement::get_modified_regs(RegSet& regs) const { + for (auto& x : m_field_defs) { + x.value->get_modified_regs(regs); + } +} ModifiedCopyBitfieldElement::ModifiedCopyBitfieldElement( const TypeSpec& type, diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 8ecf9b8cef..fe819d8d70 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -3511,24 +3511,87 @@ :flag-assert #x900000028 ) +(defenum gs-reg + :type uint8 + (prim 0) + (rgbaq 1) + (st 2) + (uv 3) + (xyzf2 4) + (xyz2 5) + (tex0-1 6) + (tex0-2 7) + (clamp-1 8) + (clamp-2 9) + (fog 10) + (xyzf3 12) + (xyz3 13) + (tex1-1 20) + (tex1-2 21) + (tex2-1 22) + (tex2-2 23) + (xyoffset-1 24) + (xyoffset-2 25) + (prmodecont 26) + (prmode 27) + (texclut 28) + (scanmsk 34) + (miptbp1-1 52) + (miptbp1-2 53) + (miptbp2-1 54) + (miptbp2-2 55) + (texa 59) + (fogcol 61) + (texflush 63) + (scissor-1 64) + (scissor-2 65) + (alpha-1 66) + (alpha-2 67) + (dimx 68) + (dthe 69) + (colclamp 70) + (test-1 71) + (test-2 72) + (pabe 73) + (fba-1 74) + (fba-2 75) + (frame-1 76) + (frame-2 77) + (zbuf-1 78) + (zbuf-2 79) + (bitbltbuf 80) + (trxpos 81) + (trxreg 82) + (trxdir 83) + (hwreg 84) + (signal 96) + (finish 97) + (label 98) + ) + +(defenum gs-reg64 + :type uint64 + :copy-entries gs-reg + ) + ;; the "addr" fields represent GS register addresses (deftype draw-env (structure) ((frame1 gs-frame :offset-assert 0) - (frame1addr int64 :offset-assert 8) + (frame1addr gs-reg64 :offset-assert 8) (zbuf1 gs-zbuf :offset-assert 16) - (zbuf1addr int64 :offset-assert 24) + (zbuf1addr gs-reg64 :offset-assert 24) (xyoffset1 gs-xy-offset :offset-assert 32) - (xyoffset1addr int64 :offset-assert 40) + (xyoffset1addr gs-reg64 :offset-assert 40) (scissor1 gs-scissor :offset-assert 48) - (scissor1addr int64 :offset-assert 56) + (scissor1addr gs-reg64 :offset-assert 56) (prmodecont gs-prmode-cont :offset-assert 64) - (prmodecontaddr int64 :offset-assert 72) + (prmodecontaddr gs-reg64 :offset-assert 72) (colclamp gs-color-clamp :offset-assert 80) - (colclampaddr int64 :offset-assert 88) + (colclampaddr gs-reg64 :offset-assert 88) (dthe gs-dthe :offset-assert 96) - (dtheaddr int64 :offset-assert 104) + (dtheaddr gs-reg64 :offset-assert 104) (test1 gs-test :offset-assert 112) - (test1addr int64 :offset-assert 120) + (test1addr gs-reg64 :offset-assert 120) ) :method-count-assert 9 :size-assert #x80 @@ -3575,11 +3638,11 @@ ((display-env0 display-env :inline :offset-assert 8) (display-env1 display-env :inline :offset-assert 48) (display-env2 display-env :inline :offset-assert 88) - (gif-tag0 uint128 :offset-assert 128) + (gif-tag0 gs-gif-tag :inline :offset-assert 128) (draw0 draw-env :inline :offset-assert 144) - (gif-tag1 uint128 :offset-assert 272) + (gif-tag1 gs-gif-tag :inline :offset-assert 272) (draw1 draw-env :inline :offset-assert 288) - (gif-tag2 uint128 :offset-assert 416) + (gif-tag2 gs-gif-tag :inline :offset-assert 416) (draw2 draw-env :inline :offset-assert 432) (on-screen int32 :offset-assert 560) (last-screen int32 :offset-assert 564) @@ -4423,7 +4486,7 @@ (define-extern init-for-transform function) (define-extern move-target-from-pad (function transform int none)) (define-extern transform-point-vector! function) -(define-extern fog-corrector-setup (function fog-corrector math-camera float)) +(define-extern fog-corrector-setup (function fog-corrector math-camera none)) ;;(define-extern fog-corrector object) ;; unknown type (define-extern math-cam-start-smoothing (function float float quaternion)) (define-extern update-math-camera (function math-camera symbol symbol math-camera)) @@ -33318,7 +33381,7 @@ ;;(define-extern font-context object) ;; unknown type (define-extern *font-work* font-work) ;; unknown type ;;(define-extern decomp-work object) ;; unknown type -(define-extern draw-string-xy (function string dma-buffer int int int none)) +(define-extern draw-string-xy (function string dma-buffer int int int int none)) ;;(define-extern end-draw object) ;; unknown type (define-extern start function) ;;(define-extern pal object) ;; unknown type diff --git a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc index de39f9194e..e070878f15 100644 --- a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc @@ -238,7 +238,8 @@ ["L56", "uint64", true], ["L57", "uint64", true], ["L58", "uint64", true], - ["L80", "rgba", true] + ["L80", "rgba", true], + ["L81", "uint64", true] ], "text-h": [["L2", "_auto_", true]], diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index 06c21ac944..05fc19f2dc 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -146,12 +146,10 @@ ], // dma-buffer - "dma-buffer-add-vu-function": [ - [[9, 33], "t2", "dma-packet"] - ], + "dma-buffer-add-vu-function": [[[9, 33], "t2", "dma-packet"]], // dma-bucket - "dma-buffer-add-buckets":[ + "dma-buffer-add-buckets": [ [[1, 4], "v1", "dma-bucket"], [5, "v1", "pointer"], [[9, 11], "v1", "dma-bucket"], @@ -198,7 +196,7 @@ //[133, "v1", "(pointer uint64)"], [152, "v1", "(pointer uint64)"], - + [167, "v1", "(pointer uint64)"], [176, "v1", "(pointer uint64)"], [198, "v1", "(pointer uint64)"], @@ -227,7 +225,100 @@ ], // DISPLAY - "put-display-alpha-env": [ - [[0, 5], "v1", "gs-bank"] + "put-display-alpha-env": [[[0, 5], "v1", "gs-bank"]], + + "(method 13 profile-bar)": [ + [[27, 43], "t2", "dma-packet"], + [[46, 56], "t2", "gs-gif-tag"], + [[65, 67], "t3", "(pointer gs-prim)"], + [67, "t3", "(pointer uint64)"], + [79, "t3", "(pointer gs-xyzf)"], + [110, "t2", "(pointer gs-xyzf)"] + ], + + "draw-sprite2d-xy": [ + [[41, 45], "a3", "dma-packet"], + [[51, 54], "a3", "gs-gif-tag"], + [59, "a3", "(pointer gs-prim)"], + [61, "a3", "(pointer gs-rgbaq)"], + [72, "a3", "(pointer gs-xyzf)"], + [97, "a3", "(pointer gs-xyzf)"], + [[106, 117], "v1", "(pointer dma-tag)"], + [109, "a2", "dma-tag"] + ], + + "draw-quad2d": [ + [[22, 28], "t1", "dma-packet"], + [[31, 37], "t1", "gs-gif-tag"], + [42, "t1", "(pointer gs-prim)"], + [44, "t1", "(pointer gs-rgbaq)"], + [52, "t1", "(pointer gs-xyzf)"], + [54, "t1", "(pointer gs-rgbaq)"], + [67, "t1", "(pointer gs-xyzf)"], + [69, "t1", "(pointer gs-rgbaq)"], + [86, "t1", "(pointer gs-xyzf)"], + [88, "t1", "(pointer gs-rgbaq)"], + [110, "t1", "(pointer gs-xyzf)"], + [111, "t1", "(pointer uint64)"], + [[120, 131], "v1", "(pointer dma-tag)"], + [123, "a2", "dma-tag"] + ], + + "set-display-gs-state": [ + [[3, 10], "t3", "dma-packet"], + [[13, 19], "t3", "gs-gif-tag"], + [30, "t3", "(pointer gs-scissor)"], + [32, "t3", "(pointer gs-reg64)"], + [33, "t3", "(pointer gs-xy-offset)"], + [35, "t3", "(pointer gs-reg64)"], + [46, "t3", "(pointer gs-frame)"], + [48, "t3", "(pointer gs-reg64)"], + [50, "t3", "(pointer gs-test)"], + [52, "t3", "(pointer gs-reg64)"], + [54, "t3", "(pointer gs-texa)"], + [56, "t3", "(pointer gs-reg64)"], + [58, "t3", "(pointer gs-zbuf)"], + [60, "t3", "(pointer gs-reg64)"], + [61, "t3", "(pointer uint64)"], + [63, "t3", "(pointer gs-reg64)"] + ], + + "set-display-gs-state-offset": [ + [[3, 10], "t5", "dma-packet"], + [[13, 19], "t5", "gs-gif-tag"], + [30, "t5", "(pointer gs-scissor)"], + [32, "t5", "(pointer gs-reg64)"], + [40, "t5", "(pointer gs-xy-offset)"], + [42, "t5", "(pointer gs-reg64)"], + [53, "t5", "(pointer gs-frame)"], + [55, "t5", "(pointer gs-reg64)"], + [57, "t5", "(pointer gs-test)"], + [59, "t5", "(pointer gs-reg64)"], + [61, "t5", "(pointer gs-texa)"], + [63, "t5", "(pointer gs-reg64)"], + [65, "t5", "(pointer gs-zbuf)"], + [67, "t5", "(pointer gs-reg64)"], + [68, "t5", "(pointer uint64)"], + [70, "t5", "(pointer gs-reg64)"] + ], + + "reset-display-gs-state": [ + [[9, 16], "t0", "dma-packet"], + [[19, 25], "t0", "gs-gif-tag"], + [34, "a3", "(pointer gs-scissor)"], + [36, "a3", "(pointer gs-reg64)"], + [44, "a3", "(pointer gs-xy-offset)"], + [46, "a3", "(pointer gs-reg64)"], + [51, "a3", "(pointer gs-frame)"], + [53, "a3", "(pointer gs-reg64)"], + + [55, "a3", "(pointer gs-test)"], + [57, "a3", "(pointer gs-reg64)"], + [60, "a3", "(pointer gs-texa)"], + [62, "a3", "(pointer gs-reg64)"], + [64, "a3", "(pointer gs-zbuf)"], + [66, "a3", "(pointer gs-reg64)"], + [67, "a3", "(pointer uint64)"], + [69, "a3", "(pointer gs-reg64)"] ] } diff --git a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc index 5e5af9ce26..6414df9646 100644 --- a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc @@ -892,31 +892,31 @@ "file-info-correct-version?": { "args": ["info", "kind", "version-override"], - "vars": {"s5-0":"expected-version", "s4-0":"kind-name"} + "vars": { "s5-0": "expected-version", "s4-0": "kind-name" } }, "(method 0 load-dir)": { "args": ["allocation", "type-to-make", "length", "unk"], - "vars": {"s4-0": "obj"} + "vars": { "s4-0": "obj" } }, "(method 0 load-dir-art-group)": { "args": ["allocation", "type-to-make", "length", "unk"], - "vars": {"v0-0": "obj"} + "vars": { "v0-0": "obj" } }, "(method 0 external-art-buffer)": { "args": ["allocation", "type-to-make", "idx"], - "vars": {"v0-0":"obj"} + "vars": { "v0-0": "obj" } }, "(method 0 external-art-control)": { - "vars": {"gp-0":"obj", "s4-0":"buff-idx", "v1-9":"rec-idx"} + "vars": { "gp-0": "obj", "s4-0": "buff-idx", "v1-9": "rec-idx" } }, "(method 9 display)": { - "args": ["obj", "delta-seconds"], - "vars": { "gp-0": "obj", "s5-0": "delta" } + "args": ["obj", "slowdown"], + "vars": { "gp-0": "obj", "s5-0": "ratio" } }, "set-draw-env-offset": { @@ -932,11 +932,11 @@ }, "set-display": { - "args": ["display", "psm", "w", "h", "ztest", "zpsm"] + "args": ["disp", "psm", "w", "h", "ztest", "zpsm"] }, "set-display2": { - "args": ["display", "psm", "w", "h", "ztest", "zpsm"] + "args": ["disp", "psm", "w", "h", "ztest", "zpsm"] }, "(method 11 profile-bar)": { @@ -990,6 +990,10 @@ "args": ["exp", "maximum", "msg-exp", "msg-max"] }, + "fog-corrector-setup": { + "args": ["corrector", "math-cam"] + }, + "update-math-camera": { "args": ["math-cam", "ignored", "aspect"], "vars": { @@ -1058,6 +1062,94 @@ } }, + "(method 13 profile-bar)": { + "args": ["obj", "buf", "bar-pos"], + "vars": { + "v1-1": "height", + "a1-4": "block-idx", + "a2-1": "block-count", + "t0-0": "left", + "v1-3": "end-time", + "s4-0": "worst-time-cache", + "a3-1": "screen-y", + "t2-0": ["direct-tag", "dma-packet"], + "t2-2": ["start-gif-tag", "gs-gif-tag"], + "t1-4": "block" + } + }, + + "draw-sprite2d-xy": { + "args": ["buf", "x", "y", "w", "h", "color"], + "vars": { + "t2-1": "context", + "a0-3": "draw-x", + "a1-9": "draw-y", + "t1-2": "draw-w", + "t0-2": "draw-h", + "a3-2": ["dma", "dma-packet"], + "a3-4": ["gif", "gs-gif-tag"], + "v1-10": ["end-dma", "dma-packet"], + "a0-13": "total-qwc", + "a3-6": "gif-buf" + } + }, + + "draw-quad2d": { + "args": ["buf", "context"], + "vars": { + "a2-1": "draw-x", + "a3-7": "draw-y", + "t3-0": "draw-w", + "t2-0": "draw-h", + "v1-8": "end-dma", + "t1-0": ["dma", "dma-packet"], + "t1-2": ["gif", "gs-gif-tag"], + "t1-4": "gif-buf", + "a1-11": "total-qwc" + } + }, + + "set-display-gs-state": { + "args": ["dma-buf", "fbp", "scx", "scy", "fb-msk", "psm"], + "vars": { + "t3-0": ["dma", "dma-packet"], + "t3-2": ["gif", "gs-gif-tag"], + "t3-4": "gif-buf", + "t2-0": "fbw" + } + }, + + "set-display-gs-state-offset": { + "args": [ + "dma-buf", + "fbp", + "width", + "height", + "fb-msk", + "psm", + "off-x", + "off-y" + ], + "vars": { + "t4-0": "fbw", + "t5-0": ["dma", "dma-packet"], + "t5-2": ["gif", "gs-gif-tag"], + "t5-4": ["gif-data", "(pointer uint64)"] + } + }, + + "reset-display-gs-state": { + "args": ["disp", "dma-buf", "oddeven"], + "vars": { + "a3-0": "onscreen", + "v1-0": "hoff", + "a2-6": "fbp", + "t0-0": ["dma", "dma-packet"], + "t0-2": ["gif", "gs-gif-tag"], + "a3-3": ["gif-data", "(pointer uint64)"] + } + }, + "(method 0 engine)": { "args": ["allocation", "type-to-make", "name", "length"], "vars": { "v0-0": "obj", "v1-11": "idx-to-link", "a0-1": "end-idx" } diff --git a/goal_src/engine/camera/math-camera-h.gc b/goal_src/engine/camera/math-camera-h.gc index 1d7cbf275a..5079840ee4 100644 --- a/goal_src/engine/camera/math-camera-h.gc +++ b/goal_src/engine/camera/math-camera-h.gc @@ -98,3 +98,6 @@ :size-assert #x424 :flag-assert #x900000424 ) + + +(define-extern *math-camera* math-camera) diff --git a/goal_src/engine/camera/math-camera.gc b/goal_src/engine/camera/math-camera.gc index 157d39aef8..9d6daea950 100644 --- a/goal_src/engine/camera/math-camera.gc +++ b/goal_src/engine/camera/math-camera.gc @@ -14,11 +14,17 @@ :flag-assert #x900000008 ) +(defun fog-corrector-setup ((corrector fog-corrector) (math-cam math-camera)) + "Set the fog-corrector from the math camera" -(defun fog-corrector-setup ((arg0 fog-corrector) (arg1 math-camera)) - "Set up a fog-corrector based on the math-camera" - (set! (-> arg0 fog-end) (* (-> arg1 fog-end) (-> arg1 fov-correction-factor))) - (set! (-> arg0 fog-start) (* (-> arg1 fog-start) (-> arg1 fov-correction-factor))) + ;; just apply the correction factor to the value is math cam. + (set! (-> corrector fog-end) + (* (-> math-cam fog-end) (-> math-cam fov-correction-factor)) + ) + (set! (-> corrector fog-start) + (* (-> math-cam fog-start) (-> math-cam fov-correction-factor)) + ) + (none) ) (define *math-camera-fog-correction* (new 'global 'fog-corrector)) diff --git a/goal_src/engine/gfx/hw/display-h.gc b/goal_src/engine/gfx/hw/display-h.gc index 183518eaf7..2f57759508 100644 --- a/goal_src/engine/gfx/hw/display-h.gc +++ b/goal_src/engine/gfx/hw/display-h.gc @@ -6,6 +6,10 @@ ;; dgos: GAME, ENGINE ;; display-env stores the GS settings for displaying a framebuffer on screen. +;; this is identical to the Sony sceGsDispEnv struct. +;; you can set one of these up with set-display-env, then use it with +;; put-display-env, which is implemented in the kernel and is a wrapper +;; around a Sony function. (deftype display-env (structure) ((pmode gs-pmode :offset-assert 0) (smode2 gs-smode2 :offset-assert 8) @@ -19,25 +23,90 @@ :flag-assert #x900000028 ) +(defenum gs-reg + :type uint8 + (prim 0) + (rgbaq 1) + (st 2) + (uv 3) + (xyzf2 4) + (xyz2 5) + (tex0-1 6) + (tex0-2 7) + (clamp-1 8) + (clamp-2 9) + (fog 10) + (xyzf3 12) + (xyz3 13) + (tex1-1 20) + (tex1-2 21) + (tex2-1 22) + (tex2-2 23) + (xyoffset-1 24) + (xyoffset-2 25) + (prmodecont 26) + (prmode 27) + (texclut 28) + (scanmsk 34) + (miptbp1-1 52) + (miptbp1-2 53) + (miptbp2-1 54) + (miptbp2-2 55) + (texa 59) + (fogcol 61) + (texflush 63) + (scissor-1 64) + (scissor-2 65) + (alpha-1 66) + (alpha-2 67) + (dimx 68) + (dthe 69) + (colclamp 70) + (test-1 71) + (test-2 72) + (pabe 73) + (fba-1 74) + (fba-2 75) + (frame-1 76) + (frame-2 77) + (zbuf-1 78) + (zbuf-2 79) + (bitbltbuf 80) + (trxpos 81) + (trxreg 82) + (trxdir 83) + (hwreg 84) + (signal 96) + (finish 97) + (label 98) + ) + +(defenum gs-reg64 + :type uint64 + :copy-entries gs-reg + ) + ;; draw-env stores the GS settings for drawing to somewhere in VRAM. ;; the "addr" fields represent GS register addresses +;; this is identical to the Sony sceGsDrawEnv1/2 structs +;; Internally, this is register + address GIF data. (deftype draw-env (structure) ((frame1 gs-frame :offset-assert 0) - (frame1addr int64 :offset-assert 8) + (frame1addr gs-reg64 :offset-assert 8) (zbuf1 gs-zbuf :offset-assert 16) - (zbuf1addr int64 :offset-assert 24) + (zbuf1addr gs-reg64 :offset-assert 24) (xyoffset1 gs-xy-offset :offset-assert 32) - (xyoffset1addr int64 :offset-assert 40) + (xyoffset1addr gs-reg64 :offset-assert 40) (scissor1 gs-scissor :offset-assert 48) - (scissor1addr int64 :offset-assert 56) + (scissor1addr gs-reg64 :offset-assert 56) (prmodecont gs-prmode-cont :offset-assert 64) - (prmodecontaddr int64 :offset-assert 72) + (prmodecontaddr gs-reg64 :offset-assert 72) (colclamp gs-color-clamp :offset-assert 80) - (colclampaddr int64 :offset-assert 88) + (colclampaddr gs-reg64 :offset-assert 88) (dthe gs-dthe :offset-assert 96) - (dtheaddr int64 :offset-assert 104) + (dtheaddr gs-reg64 :offset-assert 104) (test1 gs-test :offset-assert 112) - (test1addr int64 :offset-assert 120) + (test1addr gs-reg64 :offset-assert 120) ) :method-count-assert 9 :size-assert #x80 @@ -109,11 +178,14 @@ ((display-env0 display-env :inline :offset-assert 8) (display-env1 display-env :inline :offset-assert 48) (display-env2 display-env :inline :offset-assert 88) - (gif-tag0 uint128 :offset-assert 128) + ;; the gif-tag + draw is a gif-packet to setting the draw-env. + ;; the draw-env is actually just a+d data. + (gif-tag0 gs-gif-tag :inline :offset-assert 128) (draw0 draw-env :inline :offset-assert 144) - (gif-tag1 uint128 :offset-assert 272) + + (gif-tag1 gs-gif-tag :inline :offset-assert 272) (draw1 draw-env :inline :offset-assert 288) - (gif-tag2 uint128 :offset-assert 416) + (gif-tag2 gs-gif-tag :inline :offset-assert 416) (draw2 draw-env :inline :offset-assert 432) (on-screen int32 :offset-assert 560) (last-screen int32 :offset-assert 564) @@ -170,12 +242,12 @@ (set! (-> obj frames 3 display-last) (-> obj display-env2)) (set! (-> obj frames 4 display-last) (-> obj display-env0)) (set! (-> obj frames 5 display-last) (-> obj display-env1)) - (set! (-> obj frames 0 gif) (&-> obj gif-tag0)) - (set! (-> obj frames 1 gif) (&-> obj gif-tag1)) - (set! (-> obj frames 2 gif) (&-> obj gif-tag2)) - (set! (-> obj frames 3 gif) (&-> obj gif-tag0)) - (set! (-> obj frames 4 gif) (&-> obj gif-tag1)) - (set! (-> obj frames 5 gif) (&-> obj gif-tag2)) + (set! (-> obj frames 0 gif) (&-> obj gif-tag0 qword)) + (set! (-> obj frames 1 gif) (&-> obj gif-tag1 qword)) + (set! (-> obj frames 2 gif) (&-> obj gif-tag2 qword)) + (set! (-> obj frames 3 gif) (&-> obj gif-tag0 qword)) + (set! (-> obj frames 4 gif) (&-> obj gif-tag1 qword)) + (set! (-> obj frames 5 gif) (&-> obj gif-tag2 qword)) (set! (-> obj frames 0 draw) (-> obj draw0)) (set! (-> obj frames 1 draw) (-> obj draw1)) (set! (-> obj frames 2 draw) (-> obj draw2)) diff --git a/goal_src/engine/gfx/hw/display.gc b/goal_src/engine/gfx/hw/display.gc index 732a49dd00..d66cc090ba 100644 --- a/goal_src/engine/gfx/hw/display.gc +++ b/goal_src/engine/gfx/hw/display.gc @@ -5,3 +5,1018 @@ ;; name in dgo: display ;; dgos: GAME, ENGINE +;; todo - move to font-h +(define-extern draw-string-xy (function string dma-buffer int int int int none)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; TIME +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; for some reason, the display also tracks some timing stuff. + +(defun get-current-time () + "Possibly the wall-clock time" + (-> *display* base-frame-counter) + ) + +(defun get-integral-current-time () + "The integral of game frame time (this slows down as we lag)" + (-> *display* integral-frame-counter) + ) + + +(defmethod set-video-time-params display ((obj display) (slowdown float)) + "Set timing parameters for the current game speed. For example, set slowdown = 1.0 if the game + is running at full speed or slowdown = 2.0 if the game is running at half speed." + + ;; don't allow slowdowns of more than 4x. This prevents the dt's in the physics + ;; calculations from getting huge. + (let ((ratio (fmin 4.0 slowdown))) + (set! (-> obj time-ratio) ratio) + (let ((v1-0 (get-video-mode))) + (cond + ((= v1-0 'pal) + (set! (-> obj time-adjust-ratio) (* 1.2 ratio)) + (set! (-> obj seconds-per-frame) (* 0.02 ratio)) + (set! (-> obj frames-per-second) (* 50.0 (/ 1.0 ratio))) + ;; 6 "ticks" per frame * 50 fps = 300 ticks per second. + (set! (-> obj time-factor) 6.0) + ) + (else + (set! (-> obj time-adjust-ratio) ratio) + (set! (-> obj seconds-per-frame) (* 0.016666668 ratio)) + (set! (-> obj frames-per-second) (* 60.0 (/ 1.0 ratio))) + ;; 5 "ticks" per frame * 60 fps = 300 ticks per second. + (set! (-> obj time-factor) 5.0) + ) + ) + ) + ) + (-> obj time-ratio) + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DISPLAY ENV and DRAW ENV +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; the "display env" controls what is on screen. +;; it is controlled by writing to GS registers mapped to EE memory and is independent of drawing. + +;; the "draw env" controls settings for rendering triangles +;; unlike the display env, these GS registers are set through DMA. +;; the draw env structure is actually A+D format data that can be sent directly! + +(defun set-display-env ((env display-env) (psm int) (width int) (height int) (dx int) (dy int) (fbp int)) + "Set the commonly used parameters of a display env. + psm: texture format + width/height: dimensions of the framebuffer + dx/dy: location on the TV screen + fpb: the framebuffer." + + ;; these will eventually be consumed by a sony function. I think it just sets GS registers. + + ;; set these to the mode that makes the GS actually work. Basically every game uses exactly this. + (set! (-> env pmode) + (new 'static 'gs-pmode :en1 #x1 :mmod #x1 :slbg #x1 :alp #xff) + ) + (set! (-> env smode2) (new 'static 'gs-smode2 :int #x1 :ffmd #x1)) + + ;; set up the framebuffer. + (set! (-> env dspfb) + (new 'static 'gs-display-fb :psm psm :fbw (sar width 6) :fbp fbp) + ) + + ;; set up the display area. + (set! (-> env display) + (new 'static 'gs-display + :dw #x9ff + :dy (+ dy 50) + :dx (+ (* dx (/ 2560 width)) 652) + :dh (+ (shl height 1) -1) + :magh (+ (/ (+ width 2559) width) -1) + ) + ) + + ;; I think bgcolor = 0 is required. + (set! (-> env bgcolor) (new 'static 'gs-bgcolor)) + env + ) + +(defun set-draw-env ((env draw-env) (psm int) (width int) (height int) (ztest int) (zpsm int) (fbp int)) + "Set parameters of the draw env" + + ;; each register needs address + data set. + + ;; frame buffer: + (set! (-> env frame1addr) (gs-reg64 frame-1)) + (set! (-> env frame1) + (new 'static 'gs-frame :fbw (sar width 6) :psm (logand psm 15) :fbp fbp) + ) + + ;; dithering is enabled/disabled based on the texture format. + ;; it's not allowed in psmct32 and psmct24 so I assume it's always off. + (set! (-> env dtheaddr) (gs-reg64 dthe)) + (cond + ((zero? (logand psm 2)) + (set! (-> env dthe) (new 'static 'gs-dthe)) + ) + (else + (set! (-> env dthe) (new 'static 'gs-dthe :dthe #x1)) + ) + ) + + ;; z buffer: + (set! (-> env zbuf1addr) (gs-reg64 zbuf-1)) + (set! (-> env zbuf1) + (new 'static 'gs-zbuf + :zbp #x1c0 + :psm (logand zpsm 15) + :zmsk (if (zero? ztest) 1 0) + ) + ) + + ;; pixel test. you only get to pick the ztst field. + (set! (-> env test1addr) (gs-reg64 test-1)) + (cond + ((zero? ztest) + (set! (-> env test1) (new 'static 'gs-test)) + ) + (else + (set! (-> env test1) (new 'static 'gs-test :zte #x1 :ztst ztest)) + ) + ) + + ;; offset to window coordinate system (WCS) + (set! (-> env xyoffset1addr) (gs-reg64 xyoffset-1)) + (set! (-> env xyoffset1) + (new 'static 'gs-xy-offset + :ofx #x7000 + :ofy (shl (-> *video-parms* screen-miny) 4) ;; 12.4 fixed point. + ) + ) + + ;; scissor to the given width/height (in WCS) + (set! (-> env scissor1addr) (gs-reg64 scissor-1)) + ;; the lower bound is set to 0: the origin of the WCS which is the xyoffset + (set! (-> env scissor1) + (new 'static 'gs-scissor :scax1 (+ width -1) :scay1 (+ height -1)) + ) + + ;; use the prim register for primitive settings, not prmode. + (set! (-> env prmodecontaddr) (gs-reg64 prmodecont)) + (set! (-> env prmodecont) (new 'static 'gs-prmode-cont :ac #x1)) + + ;; clamp colors (don't wrap) + (set! (-> env colclampaddr) (gs-reg64 colclamp)) + (set! (-> env colclamp) (new 'static 'gs-color-clamp :clamp #x1)) + env + ) + +(defun set-draw-env-offset ((env draw-env) (x int) (y int) (arg3 int)) + "Set the drawing offset (origin of the WCS). + The input x and y should be in pixels to the _center_ of the window. + The width/height of the window are taken from the scissoring settings. + It is assumed that scax0 and scay0 are set to 0." + (set! (-> env xyoffset1) + (new 'static 'gs-xy-offset + :ofx (shl (- x + (shr (+ (-> env scissor1 scax1) 1) 1) ;; half the width. + ) + 4) ;; 12.4 + :ofy (+ (shl (- y + (shr (+ (-> env scissor1 scay1) 1) 1)) ;; half the height. + 4) ;; convert to 12.4 + (if (zero? arg3) 0 8) ;; and add a half-pixel offset. + ) + ) + ) + env + ) + +(defun put-display-alpha-env ((arg0 display-env)) + "Set display1 and dspfb1 directly, right now. + This is unused." + (let ((v1-0 (the-as gs-bank #x12000000))) + (set! (-> v1-0 dspfb1) (-> arg0 dspfb)) + (set! (-> v1-0 display1) (-> arg0 display)) + ) + (none) + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DISPLAY +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; the display structure manages all of the display and draw envs, as well as frame timing related stuff. + +(defun set-display ((disp display) (psm int) (w int) (h int) (ztest int) (zpsm int)) + "Set up the entire display structure, both draw and display envs" + + ;; set up gif-tag for the gif-packet to tset the draw env + (let ((v1-0 (-> disp gif-tag0))) + ;; 8x registers, data in a+d format. + (set! (-> v1-0 tag) (new 'static 'gif-tag64 :nloop #x8 :eop #x1 :nreg #x1)) + (set! (-> v1-0 regs) (new 'static 'gif-tag-regs :regs0 (gs-reg-id a+d))) + ) + + ;; copy to the other envs. + (set! (-> disp gif-tag1 qword) (-> disp gif-tag0 qword)) + (set! (-> disp gif-tag2 qword) (-> disp gif-tag0 qword)) + + ;; set the display envs. + (set-display-env (-> disp display-env0) psm w h (-> *video-parms* display-dx) (-> *video-parms* display-dy) 320) + (set-display-env (-> disp display-env1) psm w h (-> *video-parms* display-dx) (-> *video-parms* display-dy) 384) + + ;; set the draw envs (note the framebuffers are swapped - draw 0 will draw to the fb for disp 1) + (set-draw-env (-> disp draw0) psm w h ztest zpsm 384) + (set-draw-env (-> disp draw1) psm w h ztest zpsm 320) + + ;; initialize a bunch of counters + (set! (-> disp base-frame-counter) (the-as uint #x493e0)) + (set! (-> disp game-frame-counter) (the-as uint #x493e0)) + (set! (-> disp real-frame-counter) (the-as uint #x493e0)) + (set! (-> disp part-frame-counter) (the-as uint #x493e0)) + (set! (-> disp integral-frame-counter) (the-as uint #x493e0)) + (set! (-> disp real-integral-frame-counter) (the-as uint #x493e0)) + + ;; and the "old" version, which I think was their value on the last... frame? + (set! (-> disp old-base-frame-counter) (+ (-> disp base-frame-counter) -1)) + (set! (-> disp old-game-frame-counter) (+ (-> disp game-frame-counter) -1)) + (set! (-> disp old-real-frame-counter) (+ (-> disp real-frame-counter) -1)) + (set! (-> disp old-integral-frame-counter) (+ (-> disp integral-frame-counter) -1)) + (set! (-> disp old-real-integral-frame-counter) (+ (-> disp real-integral-frame-counter) -1)) + (set! (-> disp old-part-frame-counter) (+ (-> disp part-frame-counter) -1)) + (set! (-> disp old-actual-frame-counter) (+ (-> disp actual-frame-counter) -1)) + (set! (-> disp old-real-actual-frame-counter) (+ (-> disp real-actual-frame-counter) -1)) + disp + ) + +(defun set-display2 ((disp display) (psm int) (w int) (h int) (ztest int) (zpsm int)) + "Set the display and draw envs only. This assumes you have already done a set-display." + (set-display-env (-> disp display-env0) psm w h (-> *video-parms* display-dx) (-> *video-parms* display-dy) 320) + (set-display-env (-> disp display-env1) psm w h (-> *video-parms* display-dx) (-> *video-parms* display-dy) 384) + (set-draw-env (-> disp draw0) psm w h ztest zpsm 384) + (set-draw-env (-> disp draw1) psm w h ztest zpsm 320) + disp + ) + + +(defun allocate-dma-buffers ((arg0 display)) + "Allocate the main DMA buffers!" + (when (zero? (-> arg0 frames 0 frame calc-buf)) + ;; not sure what these "calc-buf"s are. Maybe VU0 DMA or other small stuff that is used in the same frame? + (set! (-> arg0 frames 0 frame calc-buf) (new 'global 'dma-buffer 10000)) + (set! (-> arg0 frames 1 frame calc-buf) (new 'global 'dma-buffer 10000)) + ;; the main DMA buffers for each frame's drawing. + (set! (-> arg0 frames 0 frame global-buf) (new 'global 'dma-buffer #x1ac000)) + (set! (-> arg0 frames 1 frame global-buf) (new 'global 'dma-buffer #x1ac000)) + + ;; there are separate debug buffers in debug mode that live in the debug heap. + ;; these are used to draw all of the debug stuff. + (when *debug-segment* + (set! (-> arg0 frames 0 frame debug-buf) (new 'debug 'dma-buffer #x800000)) + (set! (-> arg0 frames 1 frame debug-buf) (new 'debug 'dma-buffer #x800000)) + ) + ) + arg0 + ) + +;; need font-h. +#| +(define *font-context* (new 'global 'font-context *font-default-matrix* 0 24 0.0 0 3)) +(define *pause-context* (new 'global 'font-context *font-default-matrix* 256 170 0.0 3 3)) +|# + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PROFILE BAR +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defmethod add-frame profile-bar ((obj profile-bar) (name symbol) (color rgba)) + "Add a block to the profile bar. Looks at the timer to determine the current time." + (if *debug-segment* + (let ((new-frame (-> obj data (-> obj profile-frame-count)))) + (set! (-> obj profile-frame-count) (+ (-> obj profile-frame-count) 1)) + (set! (-> new-frame name) name) + (set! (-> new-frame time-stamp) (timer-count (the-as timer-bank #x10000800))) + (set! (-> new-frame color) color) + new-frame + ) + ) + ) + +(defmethod reset profile-bar ((obj profile-bar)) + "Clear all blocks from the profile bar. Adds the start block" + (set! (-> obj profile-frame-count) 0) + (add-frame obj 'start (new 'static 'rgba :r #x40 :b #x40 :a #x80)) + obj + ) + +(defmethod add-end-frame profile-bar ((obj profile-bar) (name symbol) (color rgba)) + "Finish the frame." + (let ((new-frame (-> obj data (-> obj profile-frame-count)))) + (set! (-> obj profile-frame-count) (+ (-> obj profile-frame-count) 1)) + (set! (-> new-frame name) name) + (set! (-> new-frame time-stamp) (the-as uint *ticks-per-frame*)) + (set! (-> new-frame color) color) + new-frame + ) + ) + +;; location and size +(define *profile-x* 1808) +(define *profile-y* (+ (-> *video-parms* screen-miny) 8)) +(define *profile-w* 416) +(define *profile-h* 8) + +;; ticks or percent? +(define *profile-ticks* #f) + +(defmethod draw profile-bar ((obj profile-bar) (buf dma-buffer) (bar-pos int)) + "Draw the bar! The bar pos shouldn't be changed." + + ;; recompute y stuff based on the current relative-y-scale. + ;; I don't know what would change it. + (let ((height (the int (* 8.0 (-> *video-parms* relative-y-scale))))) + (set! *profile-y* (+ (-> *video-parms* screen-miny) height)) + (set! *profile-h* height) + ) + (let ((block-idx 1) ;; block to draw (0 is 'start) + (block-count (-> obj profile-frame-count)) ;; total number of blocks + (left (shl *profile-x* 4)) ;; x (12.4) of the current block. initialized to start of bar. + (end-time 0) ;; end of last block + ;; if there's a single really slow frame, we want its time to appear for + ;; a little while so you can actually notice. This caches the worst time + ;; over the last ~1 second. It's a static array so it won't get reset + ;; between runs. + (worst-time-cache (new 'static 'array uint32 2 #x0 #x0)) + ) + ;; the position for this particular bar in y. + (let ((screen-y (the int (* (the float bar-pos) (-> *video-parms* relative-y-scale))))) + + ;; set up dma/vif tags: + (let* ((t1-0 buf) + (direct-tag (the-as dma-packet (-> t1-0 base)))) + ;; dma + (set! (-> direct-tag dma) + (new 'static 'dma-tag + :id (dma-tag-id cnt) + :qwc (+ (shl block-count 1) -1) ;; 2 quadwords per non-starting block + 1 (giftag) + ) + ) + ;; vif - direct: send straight to gif. + (set! (-> direct-tag vif0) (new 'static 'vif-tag)) + (set! (-> direct-tag vif1) + (new 'static 'vif-tag + :cmd (vif-cmd direct) + :msk #x1 + :imm (+ (shl block-count 1) -1) ;; same qwc as above. + ) + ) + (set! (-> t1-0 base) (&+ (the-as pointer direct-tag) 16)) + ) + + ;; set up gif tag + (let* ((t1-1 buf) + (start-gif-tag (the-as gs-gif-tag (-> t1-1 base))) + ) + ;; NREG = 4, one for each block, except for the first. + (set! (-> start-gif-tag tag) + (new 'static 'gif-tag64 + :eop #x1 + :flg #x1 + :nreg #x4 + :nloop (+ block-count -1) + ) + ) + ;; each block gets a prim, color, and two vertices. + (set! (-> start-gif-tag regs) + (new 'static 'gif-tag-regs + :regs0 (gs-reg-id prim) + :regs1 (gs-reg-id rgbaq) + :regs2 (gs-reg-id xyzf2) + :regs3 (gs-reg-id xyzf2) + ) + ) + (set! (-> t1-1 base) (&+ (the-as pointer start-gif-tag) 16)) + ) + + ;; loop through blocks to draw. + (while (< block-idx block-count) + (let ((block (-> obj data block-idx))) + ;; add first three regs (prim, color, one vertex) + (let* ((t2-4 buf) + (t3-8 (-> t2-4 base)) + ) + ;; draw sprite (alpha blend enable) + (set! (-> (the-as (pointer gs-prim) t3-8) 0) + (new 'static 'gs-prim :prim (gs-prim-type sprite) :abe #x1) + ) + ;; set color. + (set! (-> (the-as (pointer uint64) t3-8) 1) + (the-as uint (-> block color)) + ) + ;; set vertex (left side) + (set! (-> (the-as (pointer gs-xyzf) t3-8) 2) + (new 'static 'gs-xyzf + :z #x3fffff + :y (shl (+ *profile-y* screen-y) 4) ;; 12.4 + :x left ;; end of previous bar + ) + ) + (set! (-> t2-4 base) (&+ t3-8 24)) + ) + + ;; update end-time, when the work for the frame is done. + ;; don't include end-draw. + (if (!= (-> block name) 'end-draw) + (set! end-time (the-as int (-> block time-stamp))) + ) + + ;; compute left, the end of this bar. + (set! left + (shl (+ *profile-x* ;; bar start + (/ (* (-> block time-stamp) (the-as uint *profile-w*)) ;; fraction of ticks per frame + (the-as uint *ticks-per-frame*) + ) + ) + 4 ;; convert to 12.4 + ) + ) + ) + + ;; add other vertex. + (let* ((t1-8 buf) + (t2-8 (-> t1-8 base)) + ) + (set! (-> (the-as (pointer gs-xyzf) t2-8) 0) + (new 'static 'gs-xyzf + :z #x3fffff + :y (shl (+ (+ *profile-y* screen-y) *profile-h*) 4) ;; add height. + :x left ;; now the end of this bar. + ) + ) + (set! (-> t1-8 base) (&+ t2-8 8)) + ) + + ;; next block! + (+! block-idx 1) + ) + ;; end loop over blocks. + ) + + ;; update the worst time cache if its more than 75 frames old, or we did worse + ;; than the cached value. + ;; we use bar-pos/10 as the index into the cache, which is kind of sketchy. + (when (or (< 75 (- (-> *display* real-frame-counter) (-> obj cache-time))) + (>= end-time (the-as int (-> worst-time-cache (/ bar-pos 10)))) + ) + (set! (-> worst-time-cache (/ bar-pos 10)) (the-as uint end-time)) + (set! (-> obj cache-time) (-> *display* real-frame-counter)) + ) + + ;; draw the time, either in ticks or percent. + (cond + (*profile-ticks* + (let ((s3-0 draw-string-xy)) + (format (clear *temp-string*) "~5D" (-> worst-time-cache (/ bar-pos 10))) + (s3-0 *temp-string* buf 488 (+ bar-pos 8) 0 17) + ) + (the float (-> worst-time-cache (/ bar-pos 10))) + ) + (else + ;; for some reason, they use 104% here. This means that when you see + ;; 100%, it actually means ~96% of ticks-per-frame. + (let ((f30-0 (/ (* 104.0 (the float (-> worst-time-cache (/ bar-pos 10)))) + (the float *ticks-per-frame*) + ) + ) + ) + (let ((s4-1 draw-string-xy)) + (format (clear *temp-string*) "~5,,2f" f30-0) + (s4-1 *temp-string* buf 488 (+ bar-pos 8) + (if (>= f30-0 100.0) 3 0) ;; turn red if over 100. + 17 + ) + ) + f30-0 + ) + ) + ) + ) + ) + +;; get rid of these methods when not debugging. +(when (not *debug-segment*) + (set! (-> profile-bar method-table 11) nothing) ;; add + (set! (-> profile-bar method-table 12) nothing) ;; end + (set! (-> profile-bar method-table 10) nothing) ;; reset + (set! (-> profile-bar method-table 13) nothing) ;; draw + ) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DRAWING HELPERS +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun draw-sprite2d-xy ((buf dma-buffer) (x int) (y int) (w int) (h int) (color rgba)) + "Draw a sprite primitive with the given color and dimensions." + + ;; create context and clip dimensions. + (let* ((context (new 'stack 'draw-context x y w h color)) + (draw-x (max 1792 (min 2304 (+ (-> context orgx) 1792)))) + (draw-y (max (min (+ (-> context orgy) (-> *video-parms* screen-miny)) + (-> *video-parms* screen-maxy) + ) + (-> *video-parms* screen-miny) + ) + ) + (draw-w (-> context width)) + (draw-h (-> context height)) + ;; remember the address of the first dma-tag + (end-dma (the-as dma-packet (-> buf base))) + ) + ;; dma and vif setup + (let* ((a2-2 buf) + (dma (the-as dma-packet (-> a2-2 base))) + ) + ;; don't set dma or vif qwc yet. + (set! (-> dma dma) (new 'static 'dma-tag :id (dma-tag-id cnt))) + (set! (-> dma vif0) (new 'static 'vif-tag)) + (set! (-> dma vif1) (new 'static 'vif-tag :cmd (vif-cmd direct) :msk #x1)) + (set! (-> a2-2 base) (&+ (the-as pointer dma) 16)) + ) + + ;; gif setup + (let* ((a2-3 buf) + (gif (the-as gs-gif-tag (-> a2-3 base))) + ) + (set! (-> gif tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :flg #x1 :nreg #x4)) + (set! (-> gif regs) + (new 'static 'gif-tag-regs + :regs0 (gs-reg-id prim) + :regs1 (gs-reg-id rgbaq) + :regs2 (gs-reg-id xyzf2) + :regs3 (gs-reg-id xyzf2) + ) + ) + (set! (-> a2-3 base) (&+ (the-as pointer gif) 16)) + ) + + ;; gif data + (let* ((a2-4 buf) + (gif-buf (-> a2-4 base)) + ) + (set! (-> (the-as (pointer gs-prim) gif-buf) 0) + (new 'static 'gs-prim :prim (gs-prim-type sprite) :abe #x1) + ) + (set! (-> (the-as (pointer gs-rgbaq) gif-buf) 1) + (the-as gs-rgbaq (-> context color 0)) + ) + (set! (-> (the-as (pointer gs-xyzf) gif-buf) 2) + (new 'static 'gs-xyzf :z #x3fffff :y (shl draw-y 4) :x (shl draw-x 4)) + ) + (set! (-> (the-as (pointer gs-xyzf) gif-buf) 3) + (new 'static 'gs-xyzf + :z #x3fffff + :y (shl (max (min (+ draw-y draw-h) (-> *video-parms* screen-maxy)) (-> *video-parms* screen-miny)) 4) + :x (shl (max 1792 (min 2304 (+ draw-x draw-w))) 4) + ) + ) + (set! (-> a2-4 base) (&+ gif-buf 32)) + ) + + ;; patch up the qwc. This code is super weird. + (let ((total-qwc (sar (+ (- -16 (the-as int (the-as pointer end-dma))) (the-as int (-> buf base))) 4))) + (cond + ((nonzero? total-qwc) + ;; this is _not_ a normal bitfield set, but could be oring with a new bitfield? + (set! (-> (the-as (pointer dma-tag) end-dma) 0) + (logior + (-> (the-as (pointer dma-tag) end-dma) 0) + (the-as uint (new 'static 'dma-tag :qwc total-qwc)) + ) + ) + ;; this is an even weirder one (shl, shr, shl nested)? + (set! (-> (the-as (pointer dma-tag) end-dma) 1) + (logior (-> (the-as (pointer dma-tag) end-dma) 1) + (the-as uint (shl (shr (shl total-qwc 48) 48) 32)) + ) + ) + ) + (else + (set! (-> buf base) (the-as pointer end-dma)) + ) + ) + ) + ) + (none) + ) + +(defun draw-quad2d ((buf dma-buffer) (context draw-context)) + "Draw a quad that fills the entire context" + (let ((draw-x (max 1792 (min 2304 (+ (-> context orgx) 1792)))) + (draw-y (max (min (+ (-> context orgy) (-> *video-parms* screen-miny)) + (-> *video-parms* screen-maxy) + ) + (-> *video-parms* screen-miny)) + ) + (draw-w (-> context width)) + (draw-h (-> context height)) + (end-dma (-> buf base)) + ) + + ;; setup dma/vif + (let* ((t0-0 buf) + (dma (the-as dma-packet (-> t0-0 base))) + ) + (set! (-> dma dma) (new 'static 'dma-tag :id (dma-tag-id cnt))) + (set! (-> dma vif0) (new 'static 'vif-tag)) + (set! (-> dma vif1) (new 'static 'vif-tag :cmd (vif-cmd direct) :msk #x1)) + (set! (-> t0-0 base) (&+ (the-as pointer dma) 16)) + ) + ;; setup gif + (let* ((t0-1 buf) + (gif (the-as gs-gif-tag (-> t0-1 base))) + ) + (set! (-> gif tag) + (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :flg #x1 :nreg #x9) + ) + (set! (-> gif regs) + (new 'static 'gif-tag-regs + :regs1 (gs-reg-id rgbaq) + :regs2 (gs-reg-id xyzf2) + :regs3 (gs-reg-id rgbaq) + :regs4 (gs-reg-id xyzf2) + :regs5 (gs-reg-id rgbaq) + :regs6 (gs-reg-id xyzf2) + :regs7 (gs-reg-id rgbaq) + :regs8 (gs-reg-id xyzf2) + ) + ) + (set! (-> t0-1 base) (&+ (the-as pointer gif) 16)) + ) + + ;; set gif data + (let* ((t0-2 buf) + (gif-buf (-> t0-2 base)) + ) + (set! (-> (the-as (pointer gs-prim) gif-buf) 0) + (new 'static 'gs-prim :prim (gs-prim-type tri-strip) :iip #x1 :abe #x1) + ) + (set! (-> (the-as (pointer gs-rgbaq) gif-buf) 1) + (the-as gs-rgbaq (-> context color 0)) + ) + (set! (-> (the-as (pointer gs-xyzf) gif-buf) 2) + (new 'static 'gs-xyzf :y (shl draw-y 4) :x (shl draw-x 4)) + ) + (set! (-> (the-as (pointer gs-rgbaq) gif-buf) 3) + (the-as gs-rgbaq (-> context color 1)) + ) + (set! (-> (the-as (pointer gs-xyzf) gif-buf) 4) + (new 'static 'gs-xyzf + :y (shl draw-y 4) + :x (shl (max 1792 (min 2304 (+ draw-x draw-w))) 4) + ) + ) + (set! (-> (the-as (pointer gs-rgbaq) gif-buf) 5) + (the-as gs-rgbaq (-> context color 2)) + ) + (set! (-> (the-as (pointer gs-xyzf) gif-buf) 6) + (new 'static 'gs-xyzf + :y (shl (max (min (+ draw-y draw-h) (-> *video-parms* screen-maxy)) (-> *video-parms* screen-miny)) 4) + :x (shl draw-x 4) + ) + ) + (set! (-> (the-as (pointer gs-rgbaq) gif-buf) 7) + (the-as gs-rgbaq (-> context color 3)) + ) + (set! (-> (the-as (pointer gs-xyzf) gif-buf) 8) + (new 'static 'gs-xyzf + :y (shl (max (min (+ draw-y draw-h) (-> *video-parms* screen-maxy)) (-> *video-parms* screen-miny)) 4) + :x (shl (max 1792 (min 2304 (+ draw-x draw-w))) 4) + ) + ) + (set! (-> (the-as (pointer uint64) gif-buf) 9) (the-as uint 0)) + (set! (-> t0-2 base) (&+ gif-buf 80)) + ) + + ;; patch qwc. + (let ((total-qwc (sar (+ (- -16 (the-as int end-dma)) (the int (-> buf base))) 4))) + (cond + ((nonzero? total-qwc) + (set! + (-> (the-as (pointer dma-tag) end-dma) 0) + (logior + (-> (the-as (pointer dma-tag) end-dma) 0) + (the-as uint (new 'static 'dma-tag :qwc total-qwc)) + ) + ) + (set! + (-> (the-as (pointer dma-tag) end-dma) 1) + (logior + (-> (the-as (pointer dma-tag) end-dma) 1) + (the-as uint (shl (shr (shl total-qwc 48) 48) 32)) + ) + ) + ) + (else + (set! (-> buf base) end-dma) + ) + ) + ) + ) + (none) + ) + +(defun screen-gradient ((arg0 dma-buffer) (arg1 rgba) (arg2 rgba) (arg3 rgba) (arg4 rgba)) + "Fill the screen with a sprite with the given colors." + (let ((a1-2 (new 'stack 'draw-context 0 0 512 224 (the-as rgba 0)))) + (set! (-> a1-2 color 0) arg1) + (set! (-> a1-2 color 1) arg2) + (set! (-> a1-2 color 2) arg3) + (set! (-> a1-2 color 3) arg4) + (draw-quad2d arg0 a1-2) + ) + (none) + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; INTERRUPT HANDLERS +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; In debug mode, there was a vif handler that called (add-band (-> *display* profile-bar)) +;; in non-debug, there was a vif interrupt handler that did nothing. + +;; There was also a vblank hanlder that incremented *vblank-counter*, but it is disabled. + +(define *oddeven* 0) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; More GS State Helpers +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun set-display-gs-state ((dma-buf dma-buffer) (fbp int) (scx int) (scy int) (fb-msk int) (psm int)) + "Set various gs state registers" + (let ((fbw (sar (+ scx 63) 6))) ;; fbw is in 2^6 units. + ;; set dma and vif. + (let* ((v1-1 dma-buf) + (dma (the-as dma-packet (-> v1-1 base))) + ) + ;; qwc = 8 -> 1 gif tag + 7 A+D regs. + (set! (-> dma dma) (new 'static 'dma-tag :qwc #x8 :id (dma-tag-id cnt))) + (set! (-> dma vif0) (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1)) + (set! (-> dma vif1) (new 'static 'vif-tag :imm #x8 :cmd (vif-cmd direct) :msk #x1)) + (set! (-> v1-1 base) (&+ (the-as pointer dma) 16)) + ) + + ;; setup gif. + (let* ((v1-2 dma-buf) + (gif (the-as gs-gif-tag (-> v1-2 base))) + ) + (set! (-> gif tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x7)) + (set! (-> gif regs) + (new 'static 'gif-tag-regs + :regs0 (gs-reg-id a+d) + :regs1 (gs-reg-id a+d) + :regs2 (gs-reg-id a+d) + :regs3 (gs-reg-id a+d) + :regs4 (gs-reg-id a+d) + :regs5 (gs-reg-id a+d) + :regs6 (gs-reg-id a+d) + :regs7 (gs-reg-id a+d) + :regs8 (gs-reg-id a+d) + :regs9 (gs-reg-id a+d) + :regs10 (gs-reg-id a+d) + :regs11 (gs-reg-id a+d) + :regs12 (gs-reg-id a+d) + :regs13 (gs-reg-id a+d) + :regs14 (gs-reg-id a+d) + :regs15 (gs-reg-id a+d) + ) + ) + (set! (-> v1-2 base) (&+ (the-as pointer gif) 16)) + ) + + ;; set gif data. + (let* ((v1-3 dma-buf) + (gif-buf (-> v1-3 base)) + ) + ;; scissor + (set! (-> (the-as (pointer gs-scissor) gif-buf) 0) + (new 'static 'gs-scissor :scax1 (+ scx -1) :scay1 (+ scy -1)) + ) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 1) (gs-reg64 scissor-1)) + ;; offset + (set! (-> (the-as (pointer gs-xy-offset) gif-buf) 2) (new 'static 'gs-xy-offset)) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 3) (gs-reg64 xyoffset-1)) + ;; frame + (set! (-> (the-as (pointer gs-frame) gif-buf) 4) + (new 'static 'gs-frame :fbp fbp :fbw fbw :psm psm :fbmsk fb-msk) + ) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 5) (gs-reg64 frame-1)) + ;; ztest + (set! (-> (the-as (pointer gs-test) gif-buf) 6) + (new 'static 'gs-test :zte #x1 :ztst #x1) + ) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 7) (gs-reg64 test-1)) + ;; texa + (set! (-> (the-as (pointer gs-texa) gif-buf) 8) + (new 'static 'gs-texa :ta0 #x80 :ta1 #x80) + ) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 9) (gs-reg64 texa)) + ;; zbuf + (set! (-> (the-as (pointer gs-zbuf) gif-buf) 10) + (new 'static 'gs-zbuf :zbp #x1c0 :psm #x1 :zmsk #x1) + ) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 11) (gs-reg64 zbuf-1)) + ;; texflush + (set! (-> (the-as (pointer uint64) gif-buf) 12) (the-as uint 0)) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 13) (gs-reg64 texflush)) + (set! (-> v1-3 base) (&+ gif-buf 112)) + ) + ) + dma-buf + ) + +(defun set-display-gs-state-offset ((dma-buf dma-buffer) (fbp int) (width int) (height int) (fb-msk int) (psm int) (off-x int) (off-y int)) + "Set various gs state registers" + (let ((fbw (sar (+ width 63) 6))) + (let* ((v1-1 dma-buf) + (dma (the-as dma-packet (-> v1-1 base))) + ) + (set! (-> dma dma) (new 'static 'dma-tag :qwc #x8 :id (dma-tag-id cnt))) + (set! (-> dma vif0) (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1)) + (set! (-> dma vif1) + (new 'static 'vif-tag :imm #x8 :cmd (vif-cmd direct) :msk #x1) + ) + (set! (-> v1-1 base) (&+ (the-as pointer dma) 16)) + ) + (let* ((v1-2 dma-buf) + (gif (the-as gs-gif-tag (-> v1-2 base))) + ) + (set! (-> gif tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x7)) + (set! (-> gif regs) + (new 'static 'gif-tag-regs + :regs0 (gs-reg-id a+d) + :regs1 (gs-reg-id a+d) + :regs2 (gs-reg-id a+d) + :regs3 (gs-reg-id a+d) + :regs4 (gs-reg-id a+d) + :regs5 (gs-reg-id a+d) + :regs6 (gs-reg-id a+d) + :regs7 (gs-reg-id a+d) + :regs8 (gs-reg-id a+d) + :regs9 (gs-reg-id a+d) + :regs10 (gs-reg-id a+d) + :regs11 (gs-reg-id a+d) + :regs12 (gs-reg-id a+d) + :regs13 (gs-reg-id a+d) + :regs14 (gs-reg-id a+d) + :regs15 (gs-reg-id a+d) + ) + ) + (set! (-> v1-2 base) (&+ (the-as pointer gif) 16)) + ) + (let* ((v1-3 dma-buf) + (gif-data (the-as (pointer uint64) (-> v1-3 base))) + ) + (set! (-> (the-as (pointer gs-scissor) gif-data) 0) + (new 'static 'gs-scissor :scax1 (+ width -1) :scay1 (+ height -1)) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 1) (gs-reg64 scissor-1)) + (set! (-> (the-as (pointer gs-xy-offset) gif-data) 2) + (new 'static 'gs-xy-offset :ofx (shl off-x 4) :ofy (shl off-y 4)) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 3) (gs-reg64 xyoffset-1)) + (set! (-> (the-as (pointer gs-frame) gif-data) 4) + (new 'static 'gs-frame :fbp fbp :fbw fbw :psm psm :fbmsk fb-msk) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 5) (gs-reg64 frame-1)) + (set! (-> (the-as (pointer gs-test) gif-data) 6) + (new 'static 'gs-test :zte #x1 :ztst #x1) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 7) (gs-reg64 test-1)) + (set! (-> (the-as (pointer gs-texa) gif-data) 8) + (new 'static 'gs-texa :ta0 #x80 :ta1 #x80) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 9) (gs-reg64 texa)) + (set! (-> (the-as (pointer gs-zbuf) gif-data) 10) + (new 'static 'gs-zbuf :zbp #x1c0 :psm #x1 :zmsk #x1) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 11) (gs-reg64 zbuf-1)) + (set! (-> gif-data 12) (the-as uint 0)) + (set! (-> (the-as (pointer gs-reg64) gif-data) 13) (gs-reg64 texflush)) + (set! (-> v1-3 base) (&+ (the-as pointer gif-data) 112)) + ) + ) + dma-buf + ) + +(defun reset-display-gs-state ((disp display) (dma-buf dma-buffer) (oddeven int)) + "Set the gs state back to something reasonable" + (let* ((onscreen (-> disp on-screen)) + (hoff (shl oddeven 3)) ;; half pixel offset. + (fbp (-> disp frames onscreen draw frame1 fbp)) + ) + ;; set dma/vif + (let* ((a3-1 dma-buf) + (dma (the-as dma-packet (-> a3-1 base))) + ) + (set! (-> dma dma) (new 'static 'dma-tag :qwc #x8 :id (dma-tag-id cnt))) + (set! (-> dma vif0) (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1)) + (set! + (-> dma vif1) + (new 'static 'vif-tag :imm #x8 :cmd (vif-cmd direct) :msk #x1) + ) + (set! (-> a3-1 base) (&+ (the-as pointer dma) 16)) + ) + + ;; setup gif + (let* ((a3-2 dma-buf) + (gif (the-as gs-gif-tag (-> a3-2 base))) + ) + (set! (-> gif tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x7)) + (set! + (-> gif regs) + (new 'static 'gif-tag-regs + :regs0 (gs-reg-id a+d) + :regs1 (gs-reg-id a+d) + :regs2 (gs-reg-id a+d) + :regs3 (gs-reg-id a+d) + :regs4 (gs-reg-id a+d) + :regs5 (gs-reg-id a+d) + :regs6 (gs-reg-id a+d) + :regs7 (gs-reg-id a+d) + :regs8 (gs-reg-id a+d) + :regs9 (gs-reg-id a+d) + :regs10 (gs-reg-id a+d) + :regs11 (gs-reg-id a+d) + :regs12 (gs-reg-id a+d) + :regs13 (gs-reg-id a+d) + :regs14 (gs-reg-id a+d) + :regs15 (gs-reg-id a+d) + ) + ) + (set! (-> a3-2 base) (&+ (the-as pointer gif) 16)) + ) + (let ((gif-data (the-as (pointer uint64) (-> dma-buf base)))) + (set! (-> (the-as (pointer gs-scissor) gif-data) 0) + (new 'static 'gs-scissor + :scax1 #x1ff + :scay1 (-> *video-parms* screen-masky) + ) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 1) (gs-reg64 scissor-1)) + + (set! (-> (the-as (pointer gs-xy-offset) gif-data) 2) + (new 'static 'gs-xy-offset + :ofx #x7000 + :ofy (+ (shl (-> *video-parms* screen-miny) 4) hoff) + ) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 3) (gs-reg64 xyoffset-1)) + + (set! (-> (the-as (pointer gs-frame) gif-data) 4) + (new 'static 'gs-frame :fbw #x8 :fbp (the-as int fbp)) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 5) (gs-reg64 frame-1)) + + (set! (-> (the-as (pointer gs-test) gif-data) 6) + (new 'static 'gs-test :atst #x7 :zte #x1 :ztst #x2) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 7) (gs-reg64 test-1)) + + (set! (-> (the-as (pointer gs-texa) gif-data) 8) + (new 'static 'gs-texa :ta1 #x80) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 9) (gs-reg64 texa)) + + (set! (-> (the-as (pointer gs-zbuf) gif-data) 10) + (new 'static 'gs-zbuf :zbp #x1c0 :psm #x1) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 11) (gs-reg64 zbuf-1)) + + (set! (-> gif-data 12) (the-as uint 0)) + (set! (-> (the-as (pointer gs-reg64) gif-data) 13) (gs-reg64 texflush)) + + (set! (-> dma-buf base) (&+ (the-as pointer gif-data) 112)) + ) + ) + (none) + ) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Display Setup +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; separate dma list for VU0 +(define *vu0-dma-list* (new 'global 'dma-buffer 4096)) + +;; main display structure +(define *display* (new 'global 'display 0 512 256 2 49)) + +;; main dma +(allocate-dma-buffers *display*) diff --git a/goal_src/engine/gfx/hw/video-h.gc b/goal_src/engine/gfx/hw/video-h.gc index 55ec373cfc..61155a87e0 100644 --- a/goal_src/engine/gfx/hw/video-h.gc +++ b/goal_src/engine/gfx/hw/video-h.gc @@ -47,3 +47,4 @@ ) ) +(define-extern get-video-mode (function symbol)) diff --git a/goalc/emitter/Register.cpp b/goalc/emitter/Register.cpp index 0368cf6c54..13ab94dd00 100644 --- a/goalc/emitter/Register.cpp +++ b/goalc/emitter/Register.cpp @@ -53,7 +53,7 @@ RegisterInfo RegisterInfo::make_register_info() { } // todo - experiment with better orders for allocation. - info.m_gpr_alloc_order = {RAX, RCX, RDX, RBX, RBP, RSI, RDI, R8, R9, R10, R11}; // arbitrary + info.m_gpr_alloc_order = {RAX, RCX, RDX, RBX, RBP, RSI, RDI, R8, R9, R10}; // arbitrary info.m_xmm_alloc_order = {XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13}; diff --git a/test/decompiler/reference/all_forward_declarations.gc b/test/decompiler/reference/all_forward_declarations.gc index 3012372869..a3ee27000c 100644 --- a/test/decompiler/reference/all_forward_declarations.gc +++ b/test/decompiler/reference/all_forward_declarations.gc @@ -329,7 +329,75 @@ ;; loader-h (declare-type art-group basic) +;; math-camera +(declare-type math-camera basic) +(define-extern *math-camera* math-camera) + ;; level-h (declare-type entity-links structure) (declare-type level-group basic) -(define-extern *level* level-group) \ No newline at end of file +(define-extern *level* level-group) +(define-extern log2 (function int int)) + +(defenum gs-reg + :type uint8 + (prim 0) + (rgbaq 1) + (st 2) + (uv 3) + (xyzf2 4) + (xyz2 5) + (tex0-1 6) + (tex0-2 7) + (clamp-1 8) + (clamp-2 9) + (fog 10) + (xyzf3 12) + (xyz3 13) + (tex1-1 20) + (tex1-2 21) + (tex2-1 22) + (tex2-2 23) + (xyoffset-1 24) + (xyoffset-2 25) + (prmodecont 26) + (prmode 27) + (texclut 28) + (scanmsk 34) + (miptbp1-1 52) + (miptbp1-2 53) + (miptbp2-1 54) + (miptbp2-2 55) + (texa 59) + (fogcol 61) + (texflush 63) + (scissor-1 64) + (scissor-2 65) + (alpha-1 66) + (alpha-2 67) + (dimx 68) + (dthe 69) + (colclamp 70) + (test-1 71) + (test-2 72) + (pabe 73) + (fba-1 74) + (fba-2 75) + (frame-1 76) + (frame-2 77) + (zbuf-1 78) + (zbuf-2 79) + (bitbltbuf 80) + (trxpos 81) + (trxreg 82) + (trxdir 83) + (hwreg 84) + (signal 96) + (finish 97) + (label 98) + ) + +(defenum gs-reg64 + :type uint64 + :copy-entries gs-reg + ) \ No newline at end of file diff --git a/test/decompiler/reference/display-h_REF.gc b/test/decompiler/reference/display-h_REF.gc index f3792ed510..8f30daed12 100644 --- a/test/decompiler/reference/display-h_REF.gc +++ b/test/decompiler/reference/display-h_REF.gc @@ -29,21 +29,21 @@ ;; definition of type draw-env (deftype draw-env (structure) ((frame1 gs-frame :offset-assert 0) - (frame1addr int64 :offset-assert 8) + (frame1addr gs-reg64 :offset-assert 8) (zbuf1 gs-zbuf :offset-assert 16) - (zbuf1addr int64 :offset-assert 24) + (zbuf1addr gs-reg64 :offset-assert 24) (xyoffset1 gs-xy-offset :offset-assert 32) - (xyoffset1addr int64 :offset-assert 40) + (xyoffset1addr gs-reg64 :offset-assert 40) (scissor1 gs-scissor :offset-assert 48) - (scissor1addr int64 :offset-assert 56) + (scissor1addr gs-reg64 :offset-assert 56) (prmodecont gs-prmode-cont :offset-assert 64) - (prmodecontaddr int64 :offset-assert 72) + (prmodecontaddr gs-reg64 :offset-assert 72) (colclamp gs-color-clamp :offset-assert 80) - (colclampaddr int64 :offset-assert 88) + (colclampaddr gs-reg64 :offset-assert 88) (dthe gs-dthe :offset-assert 96) - (dtheaddr int64 :offset-assert 104) + (dtheaddr gs-reg64 :offset-assert 104) (test1 gs-test :offset-assert 112) - (test1addr int64 :offset-assert 120) + (test1addr gs-reg64 :offset-assert 120) ) :method-count-assert 9 :size-assert #x80 @@ -163,11 +163,11 @@ ((display-env0 display-env :inline :offset-assert 8) (display-env1 display-env :inline :offset-assert 48) (display-env2 display-env :inline :offset-assert 88) - (gif-tag0 uint128 :offset-assert 128) + (gif-tag0 gs-gif-tag :inline :offset-assert 128) (draw0 draw-env :inline :offset-assert 144) - (gif-tag1 uint128 :offset-assert 272) + (gif-tag1 gs-gif-tag :inline :offset-assert 272) (draw1 draw-env :inline :offset-assert 288) - (gif-tag2 uint128 :offset-assert 416) + (gif-tag2 gs-gif-tag :inline :offset-assert 416) (draw2 draw-env :inline :offset-assert 432) (on-screen int32 :offset-assert 560) (last-screen int32 :offset-assert 564) @@ -211,11 +211,11 @@ (format #t "~Tdisplay-env0: #~%" (-> obj display-env0)) (format #t "~Tdisplay-env1: #~%" (-> obj display-env1)) (format #t "~Tdisplay-env2: #~%" (-> obj display-env2)) - (format #t "~Tgif-tag0: #x~X~%" (-> obj gif-tag0)) + (format #t "~Tgif-tag0: #x~X~%" (-> obj gif-tag0 qword)) (format #t "~Tdraw0: #~%" (-> obj draw0)) - (format #t "~Tgif-tag1: #x~X~%" (-> obj gif-tag1)) + (format #t "~Tgif-tag1: #x~X~%" (-> obj gif-tag1 qword)) (format #t "~Tdraw1: #~%" (-> obj draw1)) - (format #t "~Tgif-tag2: #x~X~%" (-> obj gif-tag2)) + (format #t "~Tgif-tag2: #x~X~%" (-> obj gif-tag2 qword)) (format #t "~Tdraw2: #~%" (-> obj draw2)) (format #t "~Ton-screen: ~D~%" (-> obj on-screen)) (format #t "~Tlast-screen: ~D~%" (-> obj last-screen)) @@ -299,12 +299,12 @@ (set! (-> obj frames 3 display-last) (-> obj display-env2)) (set! (-> obj frames 4 display-last) (-> obj display-env0)) (set! (-> obj frames 5 display-last) (-> obj display-env1)) - (set! (-> obj frames 0 gif) (&-> obj gif-tag0)) - (set! (-> obj frames 1 gif) (&-> obj gif-tag1)) - (set! (-> obj frames 2 gif) (&-> obj gif-tag2)) - (set! (-> obj frames 3 gif) (&-> obj gif-tag0)) - (set! (-> obj frames 4 gif) (&-> obj gif-tag1)) - (set! (-> obj frames 5 gif) (&-> obj gif-tag2)) + (set! (-> obj frames 0 gif) (the-as pointer (-> obj gif-tag0))) + (set! (-> obj frames 1 gif) (the-as pointer (-> obj gif-tag1))) + (set! (-> obj frames 2 gif) (the-as pointer (-> obj gif-tag2))) + (set! (-> obj frames 3 gif) (the-as pointer (-> obj gif-tag0))) + (set! (-> obj frames 4 gif) (the-as pointer (-> obj gif-tag1))) + (set! (-> obj frames 5 gif) (the-as pointer (-> obj gif-tag2))) (set! (-> obj frames 0 draw) (-> obj draw0)) (set! (-> obj frames 1 draw) (-> obj draw1)) (set! (-> obj frames 2 draw) (-> obj draw2)) diff --git a/test/decompiler/reference/display_REF.gc b/test/decompiler/reference/display_REF.gc new file mode 100644 index 0000000000..54d1f5a92d --- /dev/null +++ b/test/decompiler/reference/display_REF.gc @@ -0,0 +1,1059 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition for function get-current-time +(defun get-current-time () + (-> *display* base-frame-counter) + ) + +;; definition for function get-integral-current-time +(defun get-integral-current-time () + (-> *display* integral-frame-counter) + ) + +;; definition for method 9 of type display +(defmethod set-video-time-params display ((obj display) (slowdown float)) + (let ((ratio (fmin 4.0 slowdown))) + (set! (-> obj time-ratio) ratio) + (let ((v1-0 (get-video-mode))) + (cond + ((= v1-0 'pal) + (set! (-> obj time-adjust-ratio) (* 1.2 ratio)) + (set! (-> obj seconds-per-frame) (* 0.02 ratio)) + (set! (-> obj frames-per-second) (* 50.0 (/ 1.0 ratio))) + (set! (-> obj time-factor) 6.0) + ) + (else + (set! (-> obj time-adjust-ratio) ratio) + (set! (-> obj seconds-per-frame) (* 0.016666668 ratio)) + (set! (-> obj frames-per-second) (* 60.0 (/ 1.0 ratio))) + (set! (-> obj time-factor) 5.0) + ) + ) + ) + ) + (-> obj time-ratio) + ) + +;; definition for function set-display-env +(defun + set-display-env + ((env display-env) + (psm int) + (width int) + (height int) + (dx int) + (dy int) + (fbp int) + ) + (set! + (-> env pmode) + (new 'static 'gs-pmode :en1 #x1 :mmod #x1 :slbg #x1 :alp #xff) + ) + (set! (-> env smode2) (new 'static 'gs-smode2 :int #x1 :ffmd #x1)) + (set! + (-> env dspfb) + (new 'static 'gs-display-fb :psm psm :fbw (sar width 6) :fbp fbp) + ) + (set! + (-> env display) + (new 'static 'gs-display + :dw #x9ff + :dy (+ dy 50) + :dx (+ (* dx (/ 2560 width)) 652) + :dh (+ (shl height 1) -1) + :magh (+ (/ (+ width 2559) width) -1) + ) + ) + (set! (-> env bgcolor) (new 'static 'gs-bgcolor)) + env + ) + +;; definition for function set-draw-env +(defun + set-draw-env + ((env draw-env) + (psm int) + (width int) + (height int) + (ztest int) + (zpsm int) + (fbp int) + ) + (set! (-> env frame1addr) (gs-reg64 frame-1)) + (set! + (-> env frame1) + (new 'static 'gs-frame :fbw (sar width 6) :psm (logand psm 15) :fbp fbp) + ) + (set! (-> env dtheaddr) (gs-reg64 dthe)) + (cond + ((zero? (logand psm 2)) + (set! (-> env dthe) (new 'static 'gs-dthe)) + (let ((v1-7 0)) + ) + ) + (else + (set! (-> env dthe) (new 'static 'gs-dthe :dthe #x1)) + ) + ) + (set! (-> env zbuf1addr) (gs-reg64 zbuf-1)) + (set! + (-> env zbuf1) + (new 'static 'gs-zbuf + :zbp #x1c0 + :psm (logand zpsm 15) + :zmsk (if (zero? ztest) 1 0) + ) + ) + (set! (-> env test1addr) (gs-reg64 test-1)) + (cond + ((zero? ztest) + (set! (-> env test1) (new 'static 'gs-test)) + (let ((v1-16 0)) + ) + ) + (else + (set! (-> env test1) (new 'static 'gs-test :zte #x1 :ztst ztest)) + ) + ) + (set! (-> env xyoffset1addr) (gs-reg64 xyoffset-1)) + (set! + (-> env xyoffset1) + (new 'static 'gs-xy-offset + :ofx #x7000 + :ofy (shl (-> *video-parms* screen-miny) 4) + ) + ) + (set! (-> env scissor1addr) (gs-reg64 scissor-1)) + (set! + (-> env scissor1) + (new 'static 'gs-scissor :scax1 (+ width -1) :scay1 (+ height -1)) + ) + (set! (-> env prmodecontaddr) (gs-reg64 prmodecont)) + (set! (-> env prmodecont) (new 'static 'gs-prmode-cont :ac #x1)) + (set! (-> env colclampaddr) (gs-reg64 colclamp)) + (set! (-> env colclamp) (new 'static 'gs-color-clamp :clamp #x1)) + env + ) + +;; definition for function set-draw-env-offset +(defun set-draw-env-offset ((env draw-env) (x int) (y int) (arg3 int)) + (set! + (-> env xyoffset1) + (new 'static 'gs-xy-offset + :ofx (shl (- x (the-as int (shr (the-as int (+ (the-as uint (-> env scissor1 scax1)) (the-as uint 1))) 1))) 4) + :ofy (+ (shl (- y (the-as int (shr (the-as int (+ (the-as uint (-> env scissor1 scay1)) (the-as uint 1))) 1))) 4) (if (zero? arg3) 0 8)) + ) + ) + env + ) + +;; definition for function put-display-alpha-env +;; INFO: Return type mismatch gs-display vs none. +(defun put-display-alpha-env ((arg0 display-env)) + (let ((v1-0 (the-as gs-bank #x12000000))) + (set! (-> v1-0 dspfb1) (-> arg0 dspfb)) + (set! (-> v1-0 display1) (-> arg0 display)) + ) + (none) + ) + +;; definition for function set-display +;; Used lq/sq +(defun + set-display + ((disp display) (psm int) (w int) (h int) (ztest int) (zpsm int)) + (let ((v1-0 (-> disp gif-tag0))) + (set! (-> v1-0 tag) (new 'static 'gif-tag64 :nloop #x8 :eop #x1 :nreg #x1)) + (set! (-> v1-0 regs) (new 'static 'gif-tag-regs :regs0 (gs-reg-id a+d))) + ) + (set! (-> disp gif-tag1 qword) (-> disp gif-tag0 qword)) + (set! (-> disp gif-tag2 qword) (-> disp gif-tag0 qword)) + (set-display-env + (-> disp display-env0) + psm + w + h + (-> *video-parms* display-dx) + (-> *video-parms* display-dy) + 320 + ) + (set-display-env + (-> disp display-env1) + psm + w + h + (-> *video-parms* display-dx) + (-> *video-parms* display-dy) + 384 + ) + (set-draw-env (-> disp draw0) psm w h ztest zpsm 384) + (set-draw-env (-> disp draw1) psm w h ztest zpsm 320) + (set! (-> disp base-frame-counter) (the-as uint #x493e0)) + (set! (-> disp game-frame-counter) (the-as uint #x493e0)) + (set! (-> disp real-frame-counter) (the-as uint #x493e0)) + (set! (-> disp part-frame-counter) (the-as uint #x493e0)) + (set! (-> disp integral-frame-counter) (the-as uint #x493e0)) + (set! (-> disp real-integral-frame-counter) (the-as uint #x493e0)) + (set! (-> disp old-base-frame-counter) (+ (-> disp base-frame-counter) -1)) + (set! (-> disp old-game-frame-counter) (+ (-> disp game-frame-counter) -1)) + (set! (-> disp old-real-frame-counter) (+ (-> disp real-frame-counter) -1)) + (set! + (-> disp old-integral-frame-counter) + (+ (-> disp integral-frame-counter) -1) + ) + (set! + (-> disp old-real-integral-frame-counter) + (+ (-> disp real-integral-frame-counter) -1) + ) + (set! (-> disp old-part-frame-counter) (+ (-> disp part-frame-counter) -1)) + (set! + (-> disp old-actual-frame-counter) + (+ (-> disp actual-frame-counter) -1) + ) + (set! + (-> disp old-real-actual-frame-counter) + (+ (-> disp real-actual-frame-counter) -1) + ) + disp + ) + +;; definition for function set-display2 +(defun + set-display2 + ((disp display) (psm int) (w int) (h int) (ztest int) (zpsm int)) + (set-display-env + (-> disp display-env0) + psm + w + h + (-> *video-parms* display-dx) + (-> *video-parms* display-dy) + 320 + ) + (set-display-env + (-> disp display-env1) + psm + w + h + (-> *video-parms* display-dx) + (-> *video-parms* display-dy) + 384 + ) + (set-draw-env (-> disp draw0) psm w h ztest zpsm 384) + (set-draw-env (-> disp draw1) psm w h ztest zpsm 320) + disp + ) + +;; definition for function allocate-dma-buffers +(defun allocate-dma-buffers ((arg0 display)) + (when (zero? (-> arg0 frames 0 frame calc-buf)) + (set! (-> arg0 frames 0 frame calc-buf) (new 'global 'dma-buffer 10000)) + (set! (-> arg0 frames 1 frame calc-buf) (new 'global 'dma-buffer 10000)) + (set! (-> arg0 frames 0 frame global-buf) (new 'global 'dma-buffer #x1ac000)) + (set! (-> arg0 frames 1 frame global-buf) (new 'global 'dma-buffer #x1ac000)) + (when *debug-segment* + (set! (-> arg0 frames 0 frame debug-buf) (new 'debug 'dma-buffer #x800000)) + (set! (-> arg0 frames 1 frame debug-buf) (new 'debug 'dma-buffer #x800000)) + ) + ) + arg0 + ) + +;; definition for symbol *font-context*, type font-context +(define + *font-context* + (new 'global 'font-context *font-default-matrix* 0 24 0.0 0 3) + ) + +;; definition for symbol *pause-context*, type font-context +(define + *pause-context* + (new 'global 'font-context *font-default-matrix* 256 170 0.0 3 3) + ) + +;; definition for method 11 of type profile-bar +(defmethod add-frame profile-bar ((obj profile-bar) (name symbol) (color rgba)) + (if *debug-segment* + (let ((new-frame (-> obj data (-> obj profile-frame-count)))) + (set! (-> obj profile-frame-count) (+ (-> obj profile-frame-count) 1)) + (set! (-> new-frame name) name) + (set! + (-> new-frame time-stamp) + (timer-count (the-as timer-bank #x10000800)) + ) + (set! (-> new-frame color) color) + new-frame + ) + ) + ) + +;; definition for method 10 of type profile-bar +(defmethod reset profile-bar ((obj profile-bar)) + (set! (-> obj profile-frame-count) 0) + (add-frame obj 'start (new 'static 'rgba :r #x40 :b #x40 :a #x80)) + obj + ) + +;; definition for method 12 of type profile-bar +(defmethod + add-end-frame + profile-bar + ((obj profile-bar) (name symbol) (color rgba)) + (let ((new-frame (-> obj data (-> obj profile-frame-count)))) + (set! (-> obj profile-frame-count) (+ (-> obj profile-frame-count) 1)) + (set! (-> new-frame name) name) + (set! (-> new-frame time-stamp) (the-as uint *ticks-per-frame*)) + (set! (-> new-frame color) color) + new-frame + ) + ) + +;; definition for symbol *profile-x*, type int +(define *profile-x* 1808) + +;; definition for symbol *profile-y*, type int +(define *profile-y* (+ (-> *video-parms* screen-miny) 8)) + +;; definition for symbol *profile-w*, type int +(define *profile-w* 416) + +;; definition for symbol *profile-h*, type int +(define *profile-h* 8) + +;; definition for symbol *profile-ticks*, type symbol +(define *profile-ticks* #f) + +;; definition for method 13 of type profile-bar +(defmethod draw profile-bar ((obj profile-bar) (buf dma-buffer) (bar-pos int)) + (let ((height (the int (* 8.0 (-> *video-parms* relative-y-scale))))) + (set! *profile-y* (+ (-> *video-parms* screen-miny) height)) + (set! *profile-h* height) + ) + (let ((block-idx 1) + (block-count (-> obj profile-frame-count)) + (left (shl *profile-x* 4)) + (end-time 0) + (worst-time-cache (new 'static 'array uint32 2 #x0 #x0)) + ) + (let + ((screen-y + (the int (* (the float bar-pos) (-> *video-parms* relative-y-scale))) + ) + ) + (let* ((t1-0 buf) + (direct-tag (the-as dma-packet (-> t1-0 base))) + ) + (set! + (-> direct-tag dma) + (new 'static 'dma-tag + :id (dma-tag-id cnt) + :qwc (+ (shl block-count 1) -1) + ) + ) + (set! (-> direct-tag vif0) (new 'static 'vif-tag)) + (set! + (-> direct-tag vif1) + (new 'static 'vif-tag + :cmd (vif-cmd direct) + :msk #x1 + :imm (+ (shl block-count 1) -1) + ) + ) + (set! (-> t1-0 base) (&+ (the-as pointer direct-tag) 16)) + ) + (let* ((t1-1 buf) + (start-gif-tag (the-as gs-gif-tag (-> t1-1 base))) + ) + (set! + (-> start-gif-tag tag) + (new 'static 'gif-tag64 + :eop #x1 + :flg #x1 + :nreg #x4 + :nloop (+ block-count -1) + ) + ) + (set! + (-> start-gif-tag regs) + (new 'static 'gif-tag-regs + :regs1 (gs-reg-id rgbaq) + :regs2 (gs-reg-id xyzf2) + :regs3 (gs-reg-id xyzf2) + ) + ) + (set! (-> t1-1 base) (&+ (the-as pointer start-gif-tag) 16)) + ) + (while (< block-idx block-count) + (let ((block (-> obj data block-idx))) + (let* ((t2-4 buf) + (t3-8 (-> t2-4 base)) + ) + (set! + (-> (the-as (pointer gs-prim) t3-8) 0) + (new 'static 'gs-prim :prim (gs-prim-type sprite) :abe #x1) + ) + (set! + (-> (the-as (pointer uint64) t3-8) 1) + (the-as uint (-> block color)) + ) + (set! + (-> (the-as (pointer gs-xyzf) t3-8) 2) + (new 'static 'gs-xyzf + :z #x3fffff + :y (shl (+ *profile-y* screen-y) 4) + :x left + ) + ) + (set! (-> t2-4 base) (&+ t3-8 24)) + ) + (if (!= (-> block name) 'end-draw) + (set! end-time (the-as int (-> block time-stamp))) + ) + (set! + left + (shl + (+ + *profile-x* + (the-as + int + (/ + (* (-> block time-stamp) (the-as uint *profile-w*)) + (the-as uint *ticks-per-frame*) + ) + ) + ) + 4 + ) + ) + ) + (let* ((t1-8 buf) + (t2-8 (-> t1-8 base)) + ) + (set! + (-> (the-as (pointer gs-xyzf) t2-8) 0) + (new 'static 'gs-xyzf + :z #x3fffff + :y (shl (+ (+ *profile-y* screen-y) *profile-h*) 4) + :x left + ) + ) + (set! (-> t1-8 base) (&+ t2-8 8)) + ) + (+! block-idx 1) + ) + ) + (when + (or + (< + 75 + (the-as int (- (-> *display* real-frame-counter) (-> obj cache-time))) + ) + (>= end-time (the-as int (-> worst-time-cache (/ bar-pos 10)))) + ) + (set! (-> worst-time-cache (/ bar-pos 10)) (the-as uint end-time)) + (set! (-> obj cache-time) (-> *display* real-frame-counter)) + ) + (cond + (*profile-ticks* + (let ((s3-0 draw-string-xy)) + (format (clear *temp-string*) "~5D" (-> worst-time-cache (/ bar-pos 10))) + (s3-0 *temp-string* buf 488 (+ bar-pos 8) 0 17) + ) + (the float (-> worst-time-cache (/ bar-pos 10))) + ) + (else + (let + ((f30-0 + (/ + (* 104.0 (the float (-> worst-time-cache (/ bar-pos 10)))) + (the float *ticks-per-frame*) + ) + ) + ) + (let ((s4-1 draw-string-xy)) + (format (clear *temp-string*) "~5,,2f" f30-0) + (s4-1 *temp-string* buf 488 (+ bar-pos 8) (if (>= f30-0 100.0) + 3 + 0 + ) + 17 + ) + ) + f30-0 + ) + ) + ) + ) + ) + +;; failed to figure out what this is: +(when (not *debug-segment*) + (set! (-> profile-bar method-table 11) nothing) + (set! (-> profile-bar method-table 12) nothing) + (set! (-> profile-bar method-table 10) nothing) + (set! (-> profile-bar method-table 13) nothing) + ) + +;; definition for function draw-sprite2d-xy +;; INFO: Return type mismatch pointer vs none. +(defun + draw-sprite2d-xy + ((buf dma-buffer) (x int) (y int) (w int) (h int) (color rgba)) + (let* + ((context + ((method-of-type draw-context new) + (the-as symbol (new 'stack-no-clear 'draw-context)) + draw-context + x + y + w + h + color + ) + ) + (draw-x (max 1792 (min 2304 (+ (-> context orgx) 1792)))) + (draw-y + (max + (min + (+ (-> context orgy) (-> *video-parms* screen-miny)) + (-> *video-parms* screen-maxy) + ) + (-> *video-parms* screen-miny) + ) + ) + (draw-w (-> context width)) + (draw-h (-> context height)) + (end-dma (the-as dma-packet (-> buf base))) + ) + (let* ((a2-2 buf) + (dma (the-as dma-packet (-> a2-2 base))) + ) + (set! (-> dma dma) (new 'static 'dma-tag :id (dma-tag-id cnt))) + (set! (-> dma vif0) (new 'static 'vif-tag)) + (set! (-> dma vif1) (new 'static 'vif-tag :cmd (vif-cmd direct) :msk #x1)) + (set! (-> a2-2 base) (&+ (the-as pointer dma) 16)) + ) + (let* ((a2-3 buf) + (gif (the-as gs-gif-tag (-> a2-3 base))) + ) + (set! + (-> gif tag) + (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :flg #x1 :nreg #x4) + ) + (set! + (-> gif regs) + (new 'static 'gif-tag-regs + :regs1 (gs-reg-id rgbaq) + :regs2 (gs-reg-id xyzf2) + :regs3 (gs-reg-id xyzf2) + ) + ) + (set! (-> a2-3 base) (&+ (the-as pointer gif) 16)) + ) + (let* ((a2-4 buf) + (gif-buf (-> a2-4 base)) + ) + (set! + (-> (the-as (pointer gs-prim) gif-buf) 0) + (new 'static 'gs-prim :prim (gs-prim-type sprite) :abe #x1) + ) + (set! + (-> (the-as (pointer gs-rgbaq) gif-buf) 1) + (the-as gs-rgbaq (-> context color 0)) + ) + (set! + (-> (the-as (pointer gs-xyzf) gif-buf) 2) + (new 'static 'gs-xyzf :z #x3fffff :y (shl draw-y 4) :x (shl draw-x 4)) + ) + (set! + (-> (the-as (pointer gs-xyzf) gif-buf) 3) + (new 'static 'gs-xyzf + :z #x3fffff + :y (shl (max (min (+ draw-y draw-h) (-> *video-parms* screen-maxy)) (-> *video-parms* screen-miny)) 4) + :x (shl (max 1792 (min 2304 (+ draw-x draw-w))) 4) + ) + ) + (set! (-> a2-4 base) (&+ gif-buf 32)) + ) + (let + ((total-qwc + (sar (&+ (- -16 (the-as int (the-as pointer end-dma))) (-> buf base)) 4) + ) + ) + (cond + ((nonzero? total-qwc) + (set! + (-> (the-as (pointer dma-tag) end-dma) 0) + (logior + (-> (the-as (pointer dma-tag) end-dma) 0) + (the-as uint (new 'static 'dma-tag :qwc total-qwc)) + ) + ) + (set! + (-> (the-as (pointer dma-tag) end-dma) 1) + (logior + (-> (the-as (pointer dma-tag) end-dma) 1) + (the-as uint (shl (shr (shl total-qwc 48) 48) 32)) + ) + ) + ) + (else + (set! (-> buf base) (the-as pointer end-dma)) + ) + ) + ) + ) + (none) + ) + +;; definition for function draw-quad2d +;; INFO: Return type mismatch pointer vs none. +(defun draw-quad2d ((buf dma-buffer) (context draw-context)) + (let ((draw-x (max 1792 (min 2304 (+ (-> context orgx) 1792)))) + (draw-y + (max + (min + (+ (-> context orgy) (-> *video-parms* screen-miny)) + (-> *video-parms* screen-maxy) + ) + (-> *video-parms* screen-miny) + ) + ) + (draw-w (-> context width)) + (draw-h (-> context height)) + (end-dma (-> buf base)) + ) + (let* ((t0-0 buf) + (dma (the-as dma-packet (-> t0-0 base))) + ) + (set! (-> dma dma) (new 'static 'dma-tag :id (dma-tag-id cnt))) + (set! (-> dma vif0) (new 'static 'vif-tag)) + (set! (-> dma vif1) (new 'static 'vif-tag :cmd (vif-cmd direct) :msk #x1)) + (set! (-> t0-0 base) (&+ (the-as pointer dma) 16)) + ) + (let* ((t0-1 buf) + (gif (the-as gs-gif-tag (-> t0-1 base))) + ) + (set! + (-> gif tag) + (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :flg #x1 :nreg #x9) + ) + (set! + (-> gif regs) + (new 'static 'gif-tag-regs + :regs1 (gs-reg-id rgbaq) + :regs2 (gs-reg-id xyzf2) + :regs3 (gs-reg-id rgbaq) + :regs4 (gs-reg-id xyzf2) + :regs5 (gs-reg-id rgbaq) + :regs6 (gs-reg-id xyzf2) + :regs7 (gs-reg-id rgbaq) + :regs8 (gs-reg-id xyzf2) + ) + ) + (set! (-> t0-1 base) (&+ (the-as pointer gif) 16)) + ) + (let* ((t0-2 buf) + (gif-buf (-> t0-2 base)) + ) + (set! + (-> (the-as (pointer gs-prim) gif-buf) 0) + (new 'static 'gs-prim :prim (gs-prim-type tri-strip) :iip #x1 :abe #x1) + ) + (set! + (-> (the-as (pointer gs-rgbaq) gif-buf) 1) + (the-as gs-rgbaq (-> context color 0)) + ) + (set! + (-> (the-as (pointer gs-xyzf) gif-buf) 2) + (new 'static 'gs-xyzf :y (shl draw-y 4) :x (shl draw-x 4)) + ) + (set! + (-> (the-as (pointer gs-rgbaq) gif-buf) 3) + (the-as gs-rgbaq (-> context color 1)) + ) + (set! + (-> (the-as (pointer gs-xyzf) gif-buf) 4) + (new 'static 'gs-xyzf + :y (shl draw-y 4) + :x (shl (max 1792 (min 2304 (+ draw-x draw-w))) 4) + ) + ) + (set! + (-> (the-as (pointer gs-rgbaq) gif-buf) 5) + (the-as gs-rgbaq (-> context color 2)) + ) + (set! + (-> (the-as (pointer gs-xyzf) gif-buf) 6) + (new 'static 'gs-xyzf + :y (shl (max (min (+ draw-y draw-h) (-> *video-parms* screen-maxy)) (-> *video-parms* screen-miny)) 4) + :x (shl draw-x 4) + ) + ) + (set! + (-> (the-as (pointer gs-rgbaq) gif-buf) 7) + (the-as gs-rgbaq (-> context color 3)) + ) + (set! + (-> (the-as (pointer gs-xyzf) gif-buf) 8) + (new 'static 'gs-xyzf + :y (shl (max (min (+ draw-y draw-h) (-> *video-parms* screen-maxy)) (-> *video-parms* screen-miny)) 4) + :x (shl (max 1792 (min 2304 (+ draw-x draw-w))) 4) + ) + ) + (set! (-> (the-as (pointer uint64) gif-buf) 9) (the-as uint 0)) + (set! (-> t0-2 base) (&+ gif-buf 80)) + ) + (let ((total-qwc (sar (&+ (- -16 (the-as int end-dma)) (-> buf base)) 4))) + (cond + ((nonzero? total-qwc) + (set! + (-> (the-as (pointer dma-tag) end-dma) 0) + (logior + (-> (the-as (pointer dma-tag) end-dma) 0) + (the-as uint (new 'static 'dma-tag :qwc total-qwc)) + ) + ) + (set! + (-> (the-as (pointer dma-tag) end-dma) 1) + (logior + (-> (the-as (pointer dma-tag) end-dma) 1) + (the-as uint (shl (shr (shl total-qwc 48) 48) 32)) + ) + ) + ) + (else + (set! (-> buf base) end-dma) + ) + ) + ) + ) + (none) + ) + +;; definition for function screen-gradient +(defun + screen-gradient + ((arg0 dma-buffer) (arg1 rgba) (arg2 rgba) (arg3 rgba) (arg4 rgba)) + (let + ((a1-2 + ((method-of-type draw-context new) + (the-as symbol (new 'stack-no-clear 'draw-context)) + draw-context + 0 + 0 + 512 + 224 + (the-as rgba 0) + ) + ) + ) + (set! (-> a1-2 color 0) arg1) + (set! (-> a1-2 color 1) arg2) + (set! (-> a1-2 color 2) arg3) + (set! (-> a1-2 color 3) arg4) + (draw-quad2d arg0 a1-2) + ) + (none) + ) + +;; definition for function vif1-handler-debug +;; ERROR: function was not converted to expressions. Cannot decompile. + +;; definition for function vif1-handler +;; ERROR: function was not converted to expressions. Cannot decompile. + +;; failed to figure out what this is: +(install-handler 5 (if *debug-segment* + vif1-handler-debug + vif1-handler + ) + ) + +;; failed to figure out what this is: +(when #f + (set! *vblank-counter* 0) + (set! vblank-handler (the-as (function int) L5)) + (install-handler 3 vblank-handler) + ) + +;; definition for symbol *oddeven*, type int +(define *oddeven* 0) + +;; definition for function set-display-gs-state +(defun + set-display-gs-state + ((dma-buf dma-buffer) (fbp int) (scx int) (scy int) (fb-msk int) (psm int)) + (let ((fbw (sar (+ scx 63) 6))) + (let* ((v1-1 dma-buf) + (dma (the-as dma-packet (-> v1-1 base))) + ) + (set! (-> dma dma) (new 'static 'dma-tag :qwc #x8 :id (dma-tag-id cnt))) + (set! (-> dma vif0) (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1)) + (set! + (-> dma vif1) + (new 'static 'vif-tag :imm #x8 :cmd (vif-cmd direct) :msk #x1) + ) + (set! (-> v1-1 base) (&+ (the-as pointer dma) 16)) + ) + (let* ((v1-2 dma-buf) + (gif (the-as gs-gif-tag (-> v1-2 base))) + ) + (set! (-> gif tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x7)) + (set! + (-> gif regs) + (new 'static 'gif-tag-regs + :regs0 (gs-reg-id a+d) + :regs1 (gs-reg-id a+d) + :regs2 (gs-reg-id a+d) + :regs3 (gs-reg-id a+d) + :regs4 (gs-reg-id a+d) + :regs5 (gs-reg-id a+d) + :regs6 (gs-reg-id a+d) + :regs7 (gs-reg-id a+d) + :regs8 (gs-reg-id a+d) + :regs9 (gs-reg-id a+d) + :regs10 (gs-reg-id a+d) + :regs11 (gs-reg-id a+d) + :regs12 (gs-reg-id a+d) + :regs13 (gs-reg-id a+d) + :regs14 (gs-reg-id a+d) + :regs15 (gs-reg-id a+d) + ) + ) + (set! (-> v1-2 base) (&+ (the-as pointer gif) 16)) + ) + (let* ((v1-3 dma-buf) + (gif-buf (-> v1-3 base)) + ) + (set! + (-> (the-as (pointer gs-scissor) gif-buf) 0) + (new 'static 'gs-scissor :scax1 (+ scx -1) :scay1 (+ scy -1)) + ) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 1) (gs-reg64 scissor-1)) + (set! + (-> (the-as (pointer gs-xy-offset) gif-buf) 2) + (new 'static 'gs-xy-offset) + ) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 3) (gs-reg64 xyoffset-1)) + (set! + (-> (the-as (pointer gs-frame) gif-buf) 4) + (new 'static 'gs-frame :fbp fbp :fbw fbw :psm psm :fbmsk fb-msk) + ) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 5) (gs-reg64 frame-1)) + (set! + (-> (the-as (pointer gs-test) gif-buf) 6) + (new 'static 'gs-test :zte #x1 :ztst #x1) + ) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 7) (gs-reg64 test-1)) + (set! + (-> (the-as (pointer gs-texa) gif-buf) 8) + (new 'static 'gs-texa :ta0 #x80 :ta1 #x80) + ) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 9) (gs-reg64 texa)) + (set! + (-> (the-as (pointer gs-zbuf) gif-buf) 10) + (new 'static 'gs-zbuf :zbp #x1c0 :psm #x1 :zmsk #x1) + ) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 11) (gs-reg64 zbuf-1)) + (set! (-> (the-as (pointer uint64) gif-buf) 12) (the-as uint 0)) + (set! (-> (the-as (pointer gs-reg64) gif-buf) 13) (gs-reg64 texflush)) + (set! (-> v1-3 base) (&+ gif-buf 112)) + ) + ) + dma-buf + ) + +;; definition for function set-display-gs-state-offset +(defun + set-display-gs-state-offset + ((dma-buf dma-buffer) + (fbp int) + (width int) + (height int) + (fb-msk int) + (psm int) + (off-x int) + (off-y int) + ) + (let ((fbw (sar (+ width 63) 6))) + (let* ((v1-1 dma-buf) + (dma (the-as dma-packet (-> v1-1 base))) + ) + (set! (-> dma dma) (new 'static 'dma-tag :qwc #x8 :id (dma-tag-id cnt))) + (set! (-> dma vif0) (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1)) + (set! + (-> dma vif1) + (new 'static 'vif-tag :imm #x8 :cmd (vif-cmd direct) :msk #x1) + ) + (set! (-> v1-1 base) (&+ (the-as pointer dma) 16)) + ) + (let* ((v1-2 dma-buf) + (gif (the-as gs-gif-tag (-> v1-2 base))) + ) + (set! (-> gif tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x7)) + (set! + (-> gif regs) + (new 'static 'gif-tag-regs + :regs0 (gs-reg-id a+d) + :regs1 (gs-reg-id a+d) + :regs2 (gs-reg-id a+d) + :regs3 (gs-reg-id a+d) + :regs4 (gs-reg-id a+d) + :regs5 (gs-reg-id a+d) + :regs6 (gs-reg-id a+d) + :regs7 (gs-reg-id a+d) + :regs8 (gs-reg-id a+d) + :regs9 (gs-reg-id a+d) + :regs10 (gs-reg-id a+d) + :regs11 (gs-reg-id a+d) + :regs12 (gs-reg-id a+d) + :regs13 (gs-reg-id a+d) + :regs14 (gs-reg-id a+d) + :regs15 (gs-reg-id a+d) + ) + ) + (set! (-> v1-2 base) (&+ (the-as pointer gif) 16)) + ) + (let* ((v1-3 dma-buf) + (gif-data (the-as (pointer uint64) (-> v1-3 base))) + ) + (set! + (-> (the-as (pointer gs-scissor) gif-data) 0) + (new 'static 'gs-scissor :scax1 (+ width -1) :scay1 (+ height -1)) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 1) (gs-reg64 scissor-1)) + (set! + (-> (the-as (pointer gs-xy-offset) gif-data) 2) + (new 'static 'gs-xy-offset :ofx (shl off-x 4) :ofy (shl off-y 4)) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 3) (gs-reg64 xyoffset-1)) + (set! + (-> (the-as (pointer gs-frame) gif-data) 4) + (new 'static 'gs-frame :fbp fbp :fbw fbw :psm psm :fbmsk fb-msk) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 5) (gs-reg64 frame-1)) + (set! + (-> (the-as (pointer gs-test) gif-data) 6) + (new 'static 'gs-test :zte #x1 :ztst #x1) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 7) (gs-reg64 test-1)) + (set! + (-> (the-as (pointer gs-texa) gif-data) 8) + (new 'static 'gs-texa :ta0 #x80 :ta1 #x80) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 9) (gs-reg64 texa)) + (set! + (-> (the-as (pointer gs-zbuf) gif-data) 10) + (new 'static 'gs-zbuf :zbp #x1c0 :psm #x1 :zmsk #x1) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 11) (gs-reg64 zbuf-1)) + (set! (-> gif-data 12) (the-as uint 0)) + (set! (-> (the-as (pointer gs-reg64) gif-data) 13) (gs-reg64 texflush)) + (set! (-> v1-3 base) (&+ (the-as pointer gif-data) 112)) + ) + ) + dma-buf + ) + +;; definition for function reset-display-gs-state +;; INFO: Return type mismatch display vs none. +(defun reset-display-gs-state ((disp display) (dma-buf dma-buffer) (oddeven int)) + (let* ((onscreen (-> disp on-screen)) + (hoff (shl oddeven 3)) + (fbp (-> disp frames onscreen draw frame1 fbp)) + ) + (let* ((a3-1 dma-buf) + (dma (the-as dma-packet (-> a3-1 base))) + ) + (set! (-> dma dma) (new 'static 'dma-tag :qwc #x8 :id (dma-tag-id cnt))) + (set! (-> dma vif0) (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1)) + (set! + (-> dma vif1) + (new 'static 'vif-tag :imm #x8 :cmd (vif-cmd direct) :msk #x1) + ) + (set! (-> a3-1 base) (&+ (the-as pointer dma) 16)) + ) + (let* ((a3-2 dma-buf) + (gif (the-as gs-gif-tag (-> a3-2 base))) + ) + (set! (-> gif tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x7)) + (set! + (-> gif regs) + (new 'static 'gif-tag-regs + :regs0 (gs-reg-id a+d) + :regs1 (gs-reg-id a+d) + :regs2 (gs-reg-id a+d) + :regs3 (gs-reg-id a+d) + :regs4 (gs-reg-id a+d) + :regs5 (gs-reg-id a+d) + :regs6 (gs-reg-id a+d) + :regs7 (gs-reg-id a+d) + :regs8 (gs-reg-id a+d) + :regs9 (gs-reg-id a+d) + :regs10 (gs-reg-id a+d) + :regs11 (gs-reg-id a+d) + :regs12 (gs-reg-id a+d) + :regs13 (gs-reg-id a+d) + :regs14 (gs-reg-id a+d) + :regs15 (gs-reg-id a+d) + ) + ) + (set! (-> a3-2 base) (&+ (the-as pointer gif) 16)) + ) + (let ((gif-data (the-as (pointer uint64) (-> dma-buf base)))) + (set! + (-> (the-as (pointer gs-scissor) gif-data) 0) + (new 'static 'gs-scissor + :scax1 #x1ff + :scay1 (-> *video-parms* screen-masky) + ) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 1) (gs-reg64 scissor-1)) + (set! + (-> (the-as (pointer gs-xy-offset) gif-data) 2) + (new 'static 'gs-xy-offset + :ofx #x7000 + :ofy (+ (shl (-> *video-parms* screen-miny) 4) hoff) + ) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 3) (gs-reg64 xyoffset-1)) + (set! + (-> (the-as (pointer gs-frame) gif-data) 4) + (new 'static 'gs-frame :fbw #x8 :fbp (the-as int fbp)) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 5) (gs-reg64 frame-1)) + (set! + (-> (the-as (pointer gs-test) gif-data) 6) + (new 'static 'gs-test :atst #x7 :zte #x1 :ztst #x2) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 7) (gs-reg64 test-1)) + (set! + (-> (the-as (pointer gs-texa) gif-data) 8) + (new 'static 'gs-texa :ta1 #x80) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 9) (gs-reg64 texa)) + (set! + (-> (the-as (pointer gs-zbuf) gif-data) 10) + (new 'static 'gs-zbuf :zbp #x1c0 :psm #x1) + ) + (set! (-> (the-as (pointer gs-reg64) gif-data) 11) (gs-reg64 zbuf-1)) + (set! (-> gif-data 12) (the-as uint 0)) + (set! (-> (the-as (pointer gs-reg64) gif-data) 13) (gs-reg64 texflush)) + (set! (-> dma-buf base) (&+ (the-as pointer gif-data) 112)) + ) + ) + (none) + ) + +;; definition for symbol *vu0-dma-list*, type dma-buffer +(define *vu0-dma-list* (new 'global 'dma-buffer 4096)) + +;; definition for symbol *display*, type display +(define *display* (new 'global 'display 0 512 256 2 49)) + +;; failed to figure out what this is: +(allocate-dma-buffers *display*) + + diff --git a/test/offline/offline_test_main.cpp b/test/offline/offline_test_main.cpp index 36264fb2bb..fb4b0c9616 100644 --- a/test/offline/offline_test_main.cpp +++ b/test/offline/offline_test_main.cpp @@ -18,7 +18,7 @@ const std::unordered_set g_object_files_to_decompile = { "euler", /* geometry, trigonometry, */ "gsound-h", "timer-h", "timer", "vif-h", "dma-h", "video-h", "vu1-user-h", "dma", "dma-buffer", "dma-bucket", "dma-disasm", "pad", "gs", "display-h", "vector", "file-io", "loader-h", - "level-h", "math-camera-h", + "texture-h", "level-h", "math-camera-h", /* math-camera, "font-h",*/ "decomp-h", "display", /* gap */ "bounding-box", /* gap */ @@ -34,11 +34,16 @@ const std::vector g_object_files_to_check_against_reference = { "matrix", "transform", "quaternion", "euler", /* geometry, trigonometry */ "gsound-h", "timer-h", /* timer, */ "vif-h", "dma-h", "video-h", "vu1-user-h", "dma", "dma-buffer", "dma-bucket", "dma-disasm", "pad", "gs", "display-h", "vector", "file-io", - "loader-h", "level-h", "math-camera-h", + "loader-h", "texture-h", "level-h", "math-camera-h", /* math-camera, "font-h",*/ "decomp-h", + "display", /* gap */ "bounding-box", /* gap */ "sync-info-h", "sync-info"}; +const std::unordered_set skip_files_in_compiling = { + "display" // interrupt handler setup +}; + // the functions we expect the decompiler to skip const std::unordered_set expected_skip_in_decompiler = { // gcommon @@ -74,6 +79,10 @@ const std::unordered_set expected_skip_in_decompiler = { // dma "symlink2", "symlink3", "dma-sync-hang", // handwritten asm "vector=", // asm branching + // displyy + "vblank-handler", // asm + "vif1-handler", "vif1-handler-debug", + // sync-info "(method 15 sync-info)", // needs *res-static-buf* "(method 15 sync-info-eased)", // needs *res-static-buf* @@ -440,6 +449,9 @@ TEST_F(OfflineDecompilation, Compile) { Timer timer; int total_lines = 0; for (auto& file : g_object_files_to_check_against_reference) { + if (skip_files_in_compiling.find(file) != skip_files_in_compiling.end()) { + continue; + } auto& obj_l = db->obj_files_by_name.at(file); ASSERT_EQ(obj_l.size(), 1);