diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 7d8705517d..9f56e639ae 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -8526,22 +8526,24 @@ (define-extern *debug-engine* engine) ;; res-h - (deftype res-tag (uint128) - ((unk0 uint32 :offset 0 :size 32) - (unk1 uint16 :offset 32 :size 16) - (unk2 uint64 :offset 64 :size 64) + ((name symbol :offset 0) + (key-frame float :offset 32) + (elt-type type :offset 64) + (data-offset uint16 :offset 96) ;; guess. (data-offset is 16-bit in Crash) + (elt-count uint32 :offset 112 :size 15) + (inlined? uint8 :offset 127 :size 1) ) :flag-assert #x900000010 ) (deftype res-lump (basic) - ((length int32 :offset-assert 4) - (allocated-length int32 :offset-assert 8) - (data-base pointer :offset-assert 12) - (data-top pointer :offset-assert 16) - (data-size int32 :offset-assert 20) - (extra basic :offset-assert 24) + ((length int32 :offset-assert 4) + (allocated-length int32 :offset-assert 8) + (data-base pointer :offset-assert 12) + (data-top pointer :offset-assert 16) + (data-size int32 :offset-assert 20) + (extra basic :offset-assert 24) (tag (pointer res-tag) :offset-assert 28) ) :method-count-assert 22 @@ -8554,8 +8556,8 @@ (dummy-10 (_type_ symbol symbol int symbol symbol pointer) int 10) (dummy-11 (_type_ symbol symbol int int symbol pointer) int 11) (dummy-12 (_type_ symbol symbol float float symbol pointer) float 12) - (dummy-13 (_type_ int) pointer 13) ;; advance tag pointer - (dummy-14 (_type_ uint) pointer 14) + (dummy-13 (_type_ int) pointer 13) + (dummy-14 (_type_ res-tag) pointer 14) (dummy-15 (_type_) none 15) (dummy-16 (_type_ int int int int) none 16) (dummy-17 (_type_ int int) res-lump 17) diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index eb88f4fc9f..bfef2aee4f 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -381,6 +381,13 @@ ], // RES + "(method 4 res-tag)": [[12, "a0", "type"]], + "(method 19 res-lump)": [ + [46, "t2", "(pointer uint64)"], + [100, "t3", "(pointer uint64)"], + [184, "t5", "(pointer uint64)"], + [64, "t6", "(pointer uint64)"] + ], "(method 13 res-lump)": [[6, "a0", "res-tag"]], "(method 14 res-lump)": [[2, "a0", "res-tag"]], diff --git a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc index 83576fc715..d4ae9f7f5c 100644 --- a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc @@ -1571,7 +1571,13 @@ "args": ["allocation", "type-to-make", "bottom-offset", "top-offset", "dir", "center", "fade"], "vars": { "v0-0": "obj" } }, - + + // RES + "(method 0 res-lump)": { + "args": ["allocation", "type-to-make", "data-count", "data-size"], + "vars": { "v0-0": "obj" } + }, + // FACT-H "(method 0 fact-info-target)": { "vars": { "gp-0": "obj" } diff --git a/goal_src/engine/data/res-h.gc b/goal_src/engine/data/res-h.gc index dfde629266..33573ff1e2 100644 --- a/goal_src/engine/data/res-h.gc +++ b/goal_src/engine/data/res-h.gc @@ -5,12 +5,17 @@ ;; name in dgo: res-h ;; dgos: GAME, ENGINE +;; res is the very generic resource storage system. See res.gc for more information. + (deftype res-tag (uint128) - ((unk0 uint32 :offset 0 :size 32) - (unk1 uint16 :offset 32 :size 16) - (unk2 uint64 :offset 64 :size 64) + ((name symbol :offset 0) + (key-frame float :offset 32) + (elt-type type :offset 64) + (data-offset uint16 :offset 96) ;; guess. (data-offset is 16-bit in Crash) + (elt-count uint32 :offset 112 :size 15) + (inlined? uint8 :offset 127 :size 1) ) - :flag-assert #x900000010 + :flag-assert #x900000010 ) (deftype res-lump (basic) @@ -32,8 +37,8 @@ (dummy-10 (_type_ symbol symbol int symbol symbol pointer) int 10) (dummy-11 (_type_ symbol symbol int int symbol pointer) int 11) (dummy-12 (_type_ symbol symbol float float symbol pointer) float 12) - (dummy-13 (_type_ int) pointer 13) ;; advance tag pointer - (dummy-14 (_type_ uint) pointer 14) + (dummy-13 (_type_ int) pointer 13) + (dummy-14 (_type_ res-tag) pointer 14) (dummy-15 (_type_) none 15) (dummy-16 (_type_ int int int int) none 16) (dummy-17 (_type_ int int) res-lump 17) @@ -44,4 +49,4 @@ ) ) -(define *res-key-string* (new 'global 'string 64 (the-as string #f))) +(define *res-key-string* (new 'global 'string 64 (the-as string #f))) ;; why 64? diff --git a/goal_src/engine/data/res.gc b/goal_src/engine/data/res.gc index fb566a7f7c..784567277b 100644 --- a/goal_src/engine/data/res.gc +++ b/goal_src/engine/data/res.gc @@ -5,3 +5,119 @@ ;; name in dgo: res ;; dgos: GAME, ENGINE +;; TODO! Needs a lot of 128-bit type support for res-tag + +;; res is a very generic resource storage system used for the game entities. +;; It can be used to store all of the data for some sort of "object" (such as an entity), and that data can be of many types. +;; The data itself can also be sorted in many different manners, such as: +;; - single element +;; - array of elements +;; - array of arrays? +;; - keyframed array of elements +;; - array of keyframed array of elements? +;; +;; A res-lump stores and is used to access all of the data for a single "resource". +;; This is similar to a C++ map or C# dictionary. The key is a res-tag and the value is the corresponding binary data. +;; +;; A res-tag is a tag that contains information about a particular property of this resource. +;; For example, information about an array of vectors that make up a path - for a moving platform - or an integer to store its entity ID. +;; +;; Keyframes are used to specify when/where the data is relevant. +;; For example (this is made-up), say you have a camera spline, and you want the FOV to change three times: +;; when it starts, somewhere in the middle, and at the end. +;; You would store an array of three FOV values. The key-frame field could then be used to say at which point in the spline +;; the FOV change should occur. A similar concept is used for keyframe animation. +;; +;; Properties are looked up from a res-lump using their name, stored as a symbol. +;; +;; This is updated from the resource system used for entities in Crash 2, which had most of these features and worked very similarly! + +(defmacro res-ref? (tag) + "Checks resource tag, and returns #t if resource data is a reference type, #f if it is inlined." + + `(zero? (-> ,tag inlined?)) + ) + +(defmethod print res-tag ((obj res-tag)) + "print a res-tag." + + (let ((obj obj)) + (if (res-ref? obj) + + (format #t "#" + (-> obj name) + (-> obj key-frame) + (-> obj elt-type) + (-> obj elt-count) + ) + + (format #t "#" + (-> obj name) + (-> obj key-frame) + (-> obj elt-type) + (-> obj elt-count) + ) + ) + + obj + ) + ) + +(defmethod length res-tag ((obj res-tag)) + "get the length in bytes of this tag's resource." + + (the int + (if (res-ref? obj) + + (* (-> obj elt-count) 4) + + (* (-> obj elt-count) (-> obj elt-type size)) + ) + ) + ) + +(defmethod dummy-13 res-lump ((obj res-lump) (n int)) + "get the address of the n'th property." + + (&+ (-> obj data-base) + (-> obj tag n data-offset)) + ) + +(defmethod dummy-14 res-lump ((obj res-lump) (tag res-tag)) + "get the address of the specified property." + + (&+ (-> obj data-base) + (-> tag data-offset)) + ) + +(defmethod new res-lump ((allocation symbol) (type-to-make type) (data-count int) (data-size int)) + "Allocate a new res-lump." + + (let ((obj (object-new allocation type-to-make (the int (+ (+ (-> type-to-make size) + (* (1- data-count) (size-of res-tag)) + ) + data-size))))) + (set! (-> obj allocated-length) data-count) + (set! (-> obj data-size) data-size) + (set! (-> obj length) 0) + (set! (-> obj data-base) (&-> (-> obj tag) data-count)) + (set! (-> obj data-top) (&-> (-> obj tag) data-count)) + obj + ) + ) + +(defmethod length res-lump ((obj res-lump)) + "get the amount of resources in a res-lump." + + (-> obj length) + ) + +(defmethod asize-of res-lump ((obj res-lump)) + "get the allocated size of a res-lump." + + (the int (+ (+ (-> obj type psize) ;; psize is used here, but size is used in the allocation? + (* (-> obj allocated-length) (size-of res-tag)) + ) + (-> obj data-size))) + ) +