From d952475c770bc6c5b909348abe21d2f139a82f6d Mon Sep 17 00:00:00 2001 From: ManDude <7569514+ManDude@users.noreply.github.com> Date: Fri, 26 Feb 2021 13:59:28 +0000 Subject: [PATCH] [glist/glist-h] Decompile this stupidity (#286) * [glist/glist-h] Decompile this stupidity * [glist] fix macros * [glist] fix return types --- decompiler/config/all-types.gc | 116 ++++++------ .../jak1_ntsc_black_label/type_hints.jsonc | 8 + goal_src/engine/util/glist-h.gc | 102 ++++++++++ goal_src/engine/util/glist.gc | 175 ++++++++++++++++++ 4 files changed, 346 insertions(+), 55 deletions(-) diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 9ba74dc2a0..8d29423b8f 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -15242,38 +15242,21 @@ ; :flag-assert #x900000054 ; ) -; ;; glist-h -; (deftype glst-node (structure) -; ((next glst-node :offset-assert 0) -; (prev glst-node :offset-assert 4) -; ) -; :method-count-assert 9 -; :size-assert #x8 -; :flag-assert #x900000008 -; ) -; ;; glist-h -; (deftype glst-named-node (glst-node) -; ((next glst-node :offset-assert 0) -; (prev glst-node :offset-assert 4) -; (privname basic :offset-assert 8) -; ) -; :method-count-assert 9 -; :size-assert #xc -; :flag-assert #x90000000c -; ) +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; GLIST-H ;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; -; ;; glist-h -; (deftype glst-list (structure) -; ((head glst-node :offset-assert 0) -; (tail glst-node :offset-assert 4) -; (tailpred glst-node :offset-assert 8) -; (numelem int32 :offset-assert 12) -; ) -; :method-count-assert 9 -; :size-assert #x10 -; :flag-assert #x900000010 -; ) +(deftype glst-node (structure) + ((next glst-node :offset-assert 0) + (prev glst-node :offset-assert 4) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) ; ;; anim-tester ; (deftype list-control (UNKNOWN) @@ -15283,6 +15266,13 @@ ; :flag-assert #x0 ; ;; bad get label ; ) +(deftype glst-named-node (glst-node) + ((privname string :offset-assert 8) + ) + :method-count-assert 9 + :size-assert #xc + :flag-assert #x90000000c + ) ; ;; anim-tester ; (deftype list-field (UNKNOWN) @@ -15292,6 +15282,47 @@ ; :flag-assert #x0 ; ;; bad get label ; ) +(deftype glst-list (structure) + ((head glst-node :offset-assert 0) + (tail glst-node :offset-assert 4) + (tailpred glst-node :offset-assert 8) + (numelem int32 :offset-assert 12) + ) + :method-count-assert 9 + :size-assert #x10 + :flag-assert #x900000010 + ) + +(define-extern glst-next (function glst-node glst-node)) +(define-extern glst-prev (function glst-node glst-node)) +(define-extern glst-head (function glst-list glst-node)) +(define-extern glst-tail (function glst-list glst-node)) +(define-extern glst-end-of-list? (function glst-node symbol)) +(define-extern glst-start-of-list? (function glst-node symbol)) +(define-extern glst-empty? (function glst-list symbol)) +(define-extern glst-node-name (function glst-named-node string)) +(define-extern glst-set-name! (function glst-named-node string string)) + + +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; GLIST ;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + +(define-extern glst-num-elements (function glst-list int)) +(define-extern glst-remove (function glst-list glst-node glst-node)) +(define-extern glst-remove-tail (function glst-list glst-node)) +(define-extern glst-remove-head (function glst-list glst-node)) +(define-extern glst-insert-before (function glst-list glst-node glst-node glst-node)) +(define-extern glst-insert-after (function glst-list glst-node glst-node glst-node)) +(define-extern glst-add-tail (function glst-list glst-node glst-node)) +(define-extern glst-add-head (function glst-list glst-node glst-node)) +(define-extern glst-init-list! (function glst-list glst-list)) +(define-extern glst-find-node-by-name (function glst-list string glst-node)) +(define-extern glst-get-node-by-index (function glst-list int glst-node)) +(define-extern glst-length-of-longest-name (function glst-list int)) +(define-extern glst-get-node-index (function glst-list glst-node int)) ; ;; anim-tester ; (deftype DISP_LIST-bank (UNKNOWN) @@ -36379,31 +36410,6 @@ (define-extern convert-eye-data function) (define-extern render-eyes function) ;;(define-extern *eye-work* object) ;; unknown type -;;(define-extern glst-named-node object) ;; unknown type -(define-extern glst-head function) -(define-extern glst-tail function) -(define-extern glst-empty? function) -(define-extern glst-node-name function) -(define-extern glst-end-of-list? function) -(define-extern glst-prev function) -;;(define-extern glst-list object) ;; unknown type -(define-extern glst-set-name! function) -(define-extern glst-next function) -(define-extern glst-start-of-list? function) -;;(define-extern glst-node object) ;; unknown type -(define-extern glst-num-elements function) -(define-extern glst-get-node-index function) -(define-extern glst-remove-tail function) -(define-extern glst-find-node-by-name function) -(define-extern glst-remove-head function) -(define-extern glst-add-head function) -(define-extern glst-insert-before function) -(define-extern glst-add-tail function) -(define-extern glst-init-list! function) -(define-extern glst-remove function) -(define-extern glst-insert-after function) -(define-extern glst-length-of-longest-name function) -(define-extern glst-get-node-by-index function) (define-extern anim-tester-start function) ;;(define-extern *DISP_LIST-bank* object) ;; unknown type (define-extern anim-test-obj-remove-invalid function) diff --git a/decompiler/config/jak1_ntsc_black_label/type_hints.jsonc b/decompiler/config/jak1_ntsc_black_label/type_hints.jsonc index 37838b7645..cccd650cbc 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_hints.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_hints.jsonc @@ -187,6 +187,14 @@ [31, ["a1", "(pointer uint64)"]], [68, ["a0", "gs-gif-tag"]], [72, ["a0", "pointer"]] + ], + + "glst-find-node-by-name":[ + [17, ["s5", "glst-named-node"]] + ], + + "glst-length-of-longest-name":[ + [17, ["s5", "glst-named-node"]] ] diff --git a/goal_src/engine/util/glist-h.gc b/goal_src/engine/util/glist-h.gc index 46e08aa0e2..20d28c746a 100644 --- a/goal_src/engine/util/glist-h.gc +++ b/goal_src/engine/util/glist-h.gc @@ -5,3 +5,105 @@ ;; name in dgo: glist-h ;; dgos: GAME, ENGINE + +;; This whole linked list system is hellspawn! Whoever made this is insane and a danger to society + +(when *debug-segment* + +(deftype glst-node (structure) + ((next glst-node :offset-assert 0) + (prev glst-node :offset-assert 4) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +(deftype glst-named-node (glst-node) + ((privname string :offset-assert 8) + ) + :method-count-assert 9 + :size-assert #xc + :flag-assert #x90000000c + ) + +(deftype glst-list (structure) + ((head glst-node :offset-assert 0) + (tail glst-node :offset-assert 4) + (tailpred glst-node :offset-assert 8) + (numelem int32 :offset-assert 12) + ) + :method-count-assert 9 + :size-assert #x10 + :flag-assert #x900000010 + ) + + +;; FUN FACT! The "defun" macro only checks if the first item in the function body is a +;; string (the docstring), but because these functions were marked as inline (or debug) +;; BEFORE the docstring, they end up being considered part of the body and the compiled output! +;; This amusing mistake is reproduced here. + +(defun-debug glst-next ((node glst-node)) + (declare (inline)) + "return the next node in the list" + + (-> node next) + ) + +(defun-debug glst-prev ((node glst-node)) + (declare (inline)) + "return the previous node in the list" + + (-> node prev) + ) + +(defun-debug glst-head ((list glst-list)) + (declare (inline)) + "return the start of the list" + + (-> list head) + ) + +(defun-debug glst-tail ((list glst-list)) + (declare (inline)) + "return the tail of the list" + + (-> list tailpred) + ) + +(defun-debug glst-end-of-list? ((node glst-node)) + (declare (inline)) + "is this node the end of the list. #t = end" + + (not (-> node next)) + ) + +(defun-debug glst-start-of-list? ((node glst-node)) + (declare (inline)) + "is this node the start of the list. #t = start" + + (not (-> node prev)) + ) + +(defun-debug glst-empty? ((list glst-list)) + (declare (inline)) + "is the list empty, #t = empty" + + (= (-> list tailpred) (&-> list head)) + ) + +(defun-debug glst-node-name ((node glst-named-node)) + "Return the name of the node" + + (-> node privname) + ) + +(defun-debug glst-set-name! ((node glst-named-node) (name string)) + "Set the name of the node" + + (set! (-> node privname) name) + ) + + ) + diff --git a/goal_src/engine/util/glist.gc b/goal_src/engine/util/glist.gc index a2c99fd70b..eb54a41e82 100644 --- a/goal_src/engine/util/glist.gc +++ b/goal_src/engine/util/glist.gc @@ -5,3 +5,178 @@ ;; name in dgo: glist ;; dgos: GAME, ENGINE + +;; THIS FILE IS REALLY STUPID PLEASE JUST LOOK AWAY + +(when *debug-segment* + +(defun-debug glst-num-elements ((list glst-list)) + "Return the number of elements on the list" + (-> list numelem) + ) + +(defun-debug glst-remove ((list glst-list) (node glst-node)) + "Remove the node from the list" + + (let ((prev (glst-prev node)) + (next (glst-next node))) + (set! (-> prev next) next) + (set! (-> next prev) prev) + ) + + (+! (-> list numelem) -1) + node + ) + +(defun-debug glst-remove-tail ((list glst-list)) + "Remove the last node from the list, if it is not also the first. + Returns the deleted node, or #f otherwise" + + (let ((tail (glst-tail list))) + (if (not (glst-start-of-list? (-> tail prev))) + (glst-remove list tail) + ) + ) + ) + +(defun-debug glst-remove-head ((list glst-list)) + "Remove the first node from the list, if it is not also the last. + Returns the deleted node, or #f otherwise" + + (let ((head (glst-head list))) + (if (not (glst-end-of-list? (-> head next))) + (glst-remove list head) + ) + ) + ) + +(defun-debug glst-insert-before ((list glst-list) (node glst-node) (new-node glst-node)) + "Insert a new node before node in the list. + Returns the new node." + + (let ((prev (glst-prev node))) + (set! (-> new-node prev) prev) + (set! (-> new-node next) node) + (set! (-> prev next) new-node) + (set! (-> node prev) new-node) + ) + + (+! (-> list numelem) 1) + new-node + ) + +(defun-debug glst-insert-after ((list glst-list) (node glst-node) (new-node glst-node)) + "Insert a new node after node in the list. + Returns the new node." + + (let ((next (glst-next node))) + (set! (-> new-node next) next) + (set! (-> new-node prev) node) + (set! (-> next prev) new-node) + (set! (-> node next) new-node) + ) + + (+! (-> list numelem) 1) + new-node + ) + +(defun-debug glst-add-tail ((list glst-list) (node glst-node)) + "Add a node to the end of the list" + + (glst-insert-before list (the-as glst-node (&-> list tail)) node) + ) + +(defun-debug glst-add-head ((list glst-list) (node glst-node)) + "Add a node to the start of the list" + + (glst-insert-after list (the-as glst-node (&-> list head)) node) + ) + +(defun-debug glst-init-list! ((list glst-list)) + "Init the list" + + (set! (-> list head) (the-as glst-node (&-> list tail))) + (set! (-> list tail) #f) + (set! (-> list tailpred) (the-as glst-node (&-> list head))) + (set! (-> list numelem) 0) + list + ) + +(defmacro glst-iterate-list (list node &rest body) + "Iterate through the list using node as the current node variable" + + `(let ((,node (glst-head ,list))) + (while (not (glst-end-of-list? (-> ,node next))) + ,@body + (set! ,node (glst-next ,node)) + ) + ) + ) + +(defmacro glst-iterate-named-list (list node &rest body) + "Iterate through the named node list using node as the current node variable" + + `(let ((,node (the glst-named-node (glst-head ,list)))) + (while (not (glst-end-of-list? (-> ,node next))) + ,@body + (set! ,node (the glst-named-node (glst-next ,node))) + ) + ) + ) + +(defun-debug glst-find-node-by-name ((list glst-list) (name string)) + "Find the node in the list with the given name and return it. If it is not found, #f is returned instead" + + (glst-iterate-named-list list node + (if (name= (-> node privname) name) + (return node) + ) + ) + (the-as glst-node #f) + ) + +(defun-debug glst-get-node-by-index ((list glst-list) (n int)) + "Return the n-th node in the list, beginning at zero + Obviously since this list system sucks there's no upper bounds checking" + + (if (and (< n (glst-num-elements list)) (>= n 0)) + (let ((node (glst-head list))) + (dotimes (index n) + ;; (nop!) x4 + (set! node (glst-next node)) + ) + node + ) + ) + (the-as glst-node #f) + ) + +(defun-debug glst-length-of-longest-name ((list glst-list)) + "Returns the length of longest name in a list of named nodes" + + (let ((max-len 0)) + (glst-iterate-named-list list node + (let ((len ((method-of-type string length) (-> node privname)))) ;; TODO method call + (when (< max-len len) + (set! max-len len) + ) + ) + ) + max-len + ) + ) + +(defun-debug glst-get-node-index ((list glst-list) (node glst-node)) + "Returns the index of the node in the list. If the node is not found on the list, returns -1" + + (let ((index 0)) + (glst-iterate-list list current-node + (if (= current-node node) (return index)) + (+! index 1) + ) + -1 + ) + ) + + ) +