From 50fbbc45aa7d2538bba6a268e1d4493afb213790 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Fri, 11 Jun 2021 19:04:47 -0400 Subject: [PATCH] [decomp] start on `actor-link-h` (#579) * wip * fix tests --- decompiler/analysis/variable_naming.cpp | 27 +- decompiler/config/all-types.gc | 55 +-- .../stack_structures.jsonc | 8 + .../jak1_ntsc_black_label/type_casts.jsonc | 39 +- .../jak1_ntsc_black_label/var_names.jsonc | 28 ++ goal_src/engine/entity/actor-link-h.gc | 410 ++++++++++++++++++ goal_src/engine/entity/entity-h.gc | 13 +- .../reference/all_forward_declarations.gc | 6 + .../reference/engine/entity/entity-h_REF.gc | 30 +- .../reference/engine/math/vector_REF.gc | 20 +- 10 files changed, 565 insertions(+), 71 deletions(-) diff --git a/decompiler/analysis/variable_naming.cpp b/decompiler/analysis/variable_naming.cpp index f37435045..791ce6a6c 100644 --- a/decompiler/analysis/variable_naming.cpp +++ b/decompiler/analysis/variable_naming.cpp @@ -414,15 +414,40 @@ SSA make_rc_ssa(const Function& function, const RegUsageInfo& rui, const Functio } // process succs: - auto& end_op_info = rui.op.at(end_op - 1); + // auto& end_op_info = rui.op.at(end_op - 1); for (auto succ : {block.succ_branch, block.succ_ft}) { if (succ != -1) { + auto first_op_in_succ_id = ops.block_id_to_first_atomic_op.at(succ); + const auto& first_op_info = rui.op.at(first_op_in_succ_id); + const auto& first_op = ops.ops.at(first_op_in_succ_id); + // these are the registers that will actually be used in the successor block. + RegSet regs; + for (auto& reg : first_op->read_regs()) { + regs.insert(reg); + } + + for (auto& reg : first_op_info.live) { + if (std::find(first_op->write_regs().begin(), first_op->write_regs().end(), reg) == + first_op->write_regs().end()) { + regs.insert(reg); + } + } + + for (auto reg : regs) { + // only update phis for variables that are actually live at the next block. + if (reg.get_kind() == Reg::FPR || reg.get_kind() == Reg::GPR) { + ssa.add_source_to_phi(succ, reg, current_regs.at(reg)); + } + } + + /* for (auto reg : end_op_info.live) { // only update phis for variables that are actually live at the next block. if (reg.get_kind() == Reg::FPR || reg.get_kind() == Reg::GPR) { ssa.add_source_to_phi(succ, reg, current_regs.at(reg)); } } + */ } } } diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 7308fe78a..2a6ae6941 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -8928,7 +8928,7 @@ (data-base pointer :offset-assert 12) (data-top pointer :offset-assert 16) (data-size int32 :offset-assert 20) - (extra basic :offset-assert 24) ;; NOTE - can be anything it seems + (extra basic :offset-assert 24) ;; NOTE - can be anything it seems - have seen entity-links (tag (pointer res-tag) :offset-assert 28) ) :method-count-assert 22 @@ -12559,6 +12559,12 @@ ;; - Types +(defenum entity-perm-status + :bitfield #t + :type uint16 + (dead 2) + (complete 6)) + (deftype entity-perm (structure) ((user-object object 2 :offset-assert 0) (user-uint64 uint64 :offset 0) @@ -12569,7 +12575,7 @@ (user-uint16 uint16 4 :offset 0) (user-int8 int8 8 :offset 0) (user-uint8 uint8 8 :offset 0) - (status uint16 :offset-assert 8) + (status entity-perm-status :offset-assert 8) (dummy uint8 1 :offset-assert 10) (task uint8 :offset-assert 11) (aid uint32 :offset-assert 12) @@ -12588,7 +12594,7 @@ ((prev-link entity-links :offset-assert 0) (next-link entity-links :offset-assert 4) (entity basic :offset-assert 8) - (process basic :offset-assert 12) + (process process :offset-assert 12) (level basic :offset-assert 16) (vis-id int32 :offset-assert 20) (trans vector :inline :offset-assert 32) @@ -12666,7 +12672,7 @@ (deftype entity-actor (entity) ( (nav-mesh nav-mesh :offset-assert 52) - (etype basic :offset-assert 56) + (etype basic :offset-assert 56) ;; probably type (task uint8 :offset-assert 60) (vis-id uint16 :offset-assert 62) (quat quaternion :inline :offset-assert 64) @@ -13134,9 +13140,8 @@ ;; - Types (deftype actor-link-info (basic) - ((process basic :offset-assert 4) + ((process process :offset-assert 4) (next entity-actor :offset-assert 8) - ;; prev is a guess here. (prev entity-actor :offset-assert 12) ) :method-count-assert 26 @@ -13144,23 +13149,23 @@ :flag-assert #x1a00000010 (:methods (new (symbol type process) _type_) - (dummy-9 () none 9) - (dummy-10 () none 10) - (dummy-11 () none 11) + (get-matching-actor-type-mask (_type_ type) int 9) + (actor-count-before (_type_) int 10) + (link (_type_) entity-actor 11) (get-next (_type_) entity-actor 12) (get-prev (_type_) entity-actor 13) - (dummy-14 (_type_) none 14) ;; decompiler broken... - (dummy-15 () none 15) - (dummy-16 () none 16) - (dummy-17 () none 17) - (dummy-18 () none 18) - (dummy-19 () none 19) - (dummy-20 () none 20) - (dummy-21 () none 21) - (dummy-22 () none 22) - (dummy-23 () none 23) - (dummy-24 () none 24) - (dummy-25 () none 25) + (get-next-process (_type_) process 14) + (get-prev-process (_type_) process 15) + (apply-function-forward (_type_ (function entity-actor object object) object) int 16) + (apply-function-reverse (_type_ (function entity-actor object object) object) int 17) + (apply-all (_type_ (function entity-actor object object) object) int 18) + (dummy-19 (_type_ object) none 19) + (dummy-20 (_type_ object) none 20) ;; weird sc error + (dummy-21 (_type_ object) none 21) ;; weird sc error + (send-to-next-and-prev (_type_ object) none 22) + (send-to-next (_type_ object) none 23) + (send-to-prev (_type_ object) none 24) + (actor-count (_type_) int 25) ) ) @@ -13168,10 +13173,10 @@ (define-extern entity-actor-count (function res-lump symbol int)) (define-extern entity-by-name (function string entity)) -(define-extern entity-by-aid (function int entity)) -(define-extern actor-link-subtask-complete-hook function) -(define-extern actor-link-dead-hook function) -(define-extern alt-actor-list-subtask-incomplete-count function) +(define-extern entity-by-aid (function uint entity)) +(define-extern actor-link-subtask-complete-hook (function entity-actor (pointer symbol) symbol)) +(define-extern actor-link-dead-hook (function entity-actor (pointer symbol) symbol)) +(define-extern alt-actor-list-subtask-incomplete-count (function process-drawable int)) ;; - Functions diff --git a/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc b/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc index d46b9bf49..e77785a0a 100644 --- a/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc @@ -350,5 +350,13 @@ [32, "vector"], [48, "vector"], [64, "vector"] + ], + + "(method 23 actor-link-info)": [ + [16, "event-message-block"] + ], + + "(method 24 actor-link-info)": [ + [16, "event-message-block"] ] } diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index 27f8b688e..6a9f5fafd 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -391,9 +391,7 @@ [22, "t1", "(pointer uint64)"], [29, "t2", "(pointer uint64)"] ], - "(method 18 res-lump)": [ - ["_stack_", 16, "res-tag"] - ], + "(method 18 res-lump)": [["_stack_", 16, "res-tag"]], "(method 21 res-lump)": [ ["_stack_", 16, "res-tag"], ["_stack_", 32, "res-tag"] @@ -474,9 +472,10 @@ "entity-actor-count": [["_stack_", 16, "res-tag"]], - "entity-actor-lookup": [["_stack_", 16, "res-tag"], - [[10, 33], "v1", "(pointer uint32)"] -], + "entity-actor-lookup": [ + ["_stack_", 16, "res-tag"], + [[10, 33], "v1", "(pointer uint32)"] + ], "(method 11 joint-mod)": [ [15, "s3", "process-drawable"], @@ -527,19 +526,21 @@ [[35, 37], "a2", "qword"] ], - "(method 3 sparticle-cpuinfo)": [ - [106, "f0", "float"] - ], + "(method 3 sparticle-cpuinfo)": [[106, "f0", "float"]], - "cspace-by-name-no-fail": [ - [[0, 100], "v0", "cspace"] - ], - - "camera-teleport-to-entity": [ - [9, "a0", "transform"] - ], + "cspace-by-name-no-fail": [[[0, 100], "v0", "cspace"]], - "add-debug-sphere-from-table": [ - [[9, 18], "s1", "(inline-array vector)"] - ] + "camera-teleport-to-entity": [[9, "a0", "transform"]], + + "add-debug-sphere-from-table": [[[9, 18], "s1", "(inline-array vector)"]], + + "(method 14 actor-link-info)": [[5, "v1", "entity-links"]], + "(method 15 actor-link-info)": [[5, "v1", "entity-links"]], + + "(method 23 actor-link-info)": [[4, "v1", "entity-links"]], + "(method 24 actor-link-info)": [[4, "v1", "entity-links"]], + "(method 9 actor-link-info)": [[[0, 36], "s3", "entity-actor"]], + "alt-actor-list-subtask-incomplete-count": [[19, "a0", "entity-links"]], + "actor-link-dead-hook": [[1, "v1", "entity-links"]], + "actor-link-subtask-complete-hook": [[1, "v1", "entity-links"]] } diff --git a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc index 49ecab190..8c4d8a025 100644 --- a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc @@ -1844,5 +1844,33 @@ "add-debug-sphere-from-table": { "vars": { "s1-0": ["points", "(inline-array vector)"] } + }, + + "entity-actor-lookup": { + "args":["lump", "name", "idx"] + }, + + "(method 0 actor-link-info)" : { + "args":["allocation", "type-to-make", "proc"], + "vars": {"s5-0":"obj", "a0-1":"ent"} + }, + + "(method 25 actor-link-info)" : { + "vars": {"s5-0":"actor", "gp-0":"count"} + }, + + "(method 9 actor-link-info)" : { + "args": ["obj", "matching-type"], + "vars": {"s3-0":"actor", "s5-0":"mask", "s4-0":"current-bit"} + }, + + "(method 10 actor-link-info)" : { + "vars" : {"s5-0":"this-actor", "s4-0":"actor", "gp-0":"count"} + }, + + "alt-actor-list-subtask-incomplete-count": { + "vars":{"s4-0":"alt-actor-count", "gp-0":"incomplete-count", "s3-0":"alt-actor-idx"} } + + } diff --git a/goal_src/engine/entity/actor-link-h.gc b/goal_src/engine/entity/actor-link-h.gc index 5954a1038..ade91c8db 100644 --- a/goal_src/engine/entity/actor-link-h.gc +++ b/goal_src/engine/entity/actor-link-h.gc @@ -5,3 +5,413 @@ ;; name in dgo: actor-link-h ;; dgos: GAME, ENGINE +;; The exact details of actor-link-h are not yet understood, but this system links entities to processes. + +;; One entity may have a reference to another entity, either by name or by ID. +;; Some common ones are next-actor and prev-actor. + +(defun entity-actor-lookup ((lump res-lump) (name symbol) (idx int)) + "Given an entity (the res-lump), look up a reference to another entity and return that entity." + (local-vars (sv-16 res-tag)) + (set! sv-16 (new 'static 'res-tag)) + + ;; look up the reference + (let ((v1-1 (the-as (pointer uint32) + (get-property-data + lump + name + 'interp + -1000000000.0 + (the-as pointer #f) + (& sv-16) + *res-static-buf* + ) + ) + ) + ) + (the-as entity-actor + ;; check in range, and lookup succesful + (when (and v1-1 (< idx (the-as int (-> sv-16 elt-count)))) + ;; pick between string and aid lookup. + (if (= (-> sv-16 elt-type) string) + (entity-by-name (-> (the-as (pointer string) v1-1) idx)) + (entity-by-aid (-> (the-as (pointer uint32) v1-1) idx)) + ) + ) + ) + ) + ) + +(defun entity-actor-count ((res res-lump) (name symbol)) + "Get the number of entities that this res references under the name. + This works on more than just next/prev." + (local-vars (tag res-tag)) + (set! tag (new 'static 'res-tag)) + (if (get-property-data + res + name + 'interp + -1000000000.0 + (the-as pointer #f) + (& tag) + *res-static-buf* + ) + (the-as int (-> tag elt-count)) + 0 + ) + ) + +;; entity-actors are part of a linked list of entities. +;; It is not yet known where these are allocated. + +(deftype actor-link-info (basic) + ((process process :offset-assert 4) ;; process for this entity + (next entity-actor :offset-assert 8) ;; next entity in the list + (prev entity-actor :offset-assert 12) ;; prev entity in the list + ) + :method-count-assert 26 + :size-assert #x10 + :flag-assert #x1a00000010 + (:methods + (new (symbol type process) _type_ 0) + (get-matching-actor-type-mask (_type_ type) int 9) + (actor-count-before (_type_) int 10) + (link (_type_) entity-actor 11) + (get-next (_type_) entity-actor 12) + (get-prev (_type_) entity-actor 13) + (get-next-process (_type_) process 14) + (get-prev-process (_type_) process 15) + (apply-function-forward (_type_ (function entity-actor object object) object) int 16) + (apply-function-reverse (_type_ (function entity-actor object object) object) int 17) + (apply-all (_type_ (function entity-actor object object) object) int 18) + (dummy-19 (_type_ object) none 19) + (dummy-20 (_type_ object) none 20) + (dummy-21 (_type_ object) none 21) + (send-to-next-and-prev (_type_ object) none 22) + (send-to-next (_type_ object) none 23) + (send-to-prev (_type_ object) none 24) + (actor-count (_type_) int 25) + ) + ) + +(defmethod next-actor entity-actor ((obj entity-actor)) + "Utility function to look up the next actor in the list, assuming we don't have actor-link-info yet." + ;; look up reference to next-actor - this is slow. + (entity-actor-lookup obj 'next-actor 0) + ) + +(defmethod prev-actor entity-actor ((obj entity-actor)) + "Look up previous actor in the list" + (entity-actor-lookup obj 'prev-actor 0) + ) + +(defmethod new actor-link-info ((allocation symbol) (type-to-make type) (proc process)) + "Set up an actor-link-info for the given process. The entity of this process should be the entity-actor + that will get this actor-link-info" + (let ((obj (object-new allocation type-to-make (the-as int (-> type-to-make size))))) + (set! (-> obj process) proc) + + ;; set next (likely next-actor inlined) + (let ((ent (-> proc entity))) + (set! (-> obj next) (entity-actor-lookup (the-as res-lump ent) 'next-actor 0)) + ) + + ;; set prev (likely prev-actor inlined) + (let ((a0-2 (-> proc entity))) + (set! (-> obj prev) (entity-actor-lookup (the-as res-lump a0-2) 'prev-actor 0)) + ) + obj + ) + ) + + +;; These methods can now be used to get next/prev more efficiently, without having to do a res lookup. +(defmethod get-next actor-link-info ((obj actor-link-info)) + (-> obj next) + ) + +(defmethod get-prev actor-link-info ((obj actor-link-info)) + (-> obj prev) + ) + +(defmethod get-next-process actor-link-info ((obj actor-link-info)) + "Get the process for the next, if it exists." + ;; we can't easily get to the actor-link-info of the next, so we have to grab it from entity-links. + (the-as process + (and (-> obj next) (-> (the-as entity-links (-> obj next extra)) process)) + ) + ) + +(defmethod get-prev-process actor-link-info ((obj actor-link-info)) + "Get the process for the prev, if it exists" + (the-as process + (and (-> obj prev) (-> (the-as entity-links (-> obj prev extra)) process)) + ) + ) + +(defmethod link actor-link-info ((obj actor-link-info)) + "Redo the linking in the constructor by looking up the next/prev actor." + (let ((a0-1 (-> obj process entity))) + (set! (-> obj next) + (entity-actor-lookup (the-as res-lump a0-1) 'next-actor 0) + ) + ) + (let ((a0-2 (-> obj process entity))) + (set! (-> obj prev) + (entity-actor-lookup (the-as res-lump a0-2) 'prev-actor 0) + ) + ) + (-> obj next) + ) + + +(defmethod apply-function-forward actor-link-info + ((obj actor-link-info) (arg0 (function entity-actor object object)) (arg1 object)) + "Iterate forward through actors, and apply this function. Starts at (-> obj next) + If the function returns truthy, stop iterating." + (let ((s3-0 (-> obj next))) + (while s3-0 + (if (arg0 s3-0 arg1) + (return (the-as int #f)) + ) + (set! s3-0 (entity-actor-lookup s3-0 'next-actor 0)) + ) + ) + 0 + ) + +(defmethod apply-function-reverse actor-link-info + ((obj actor-link-info) (arg0 (function entity-actor object object)) (arg1 object)) + "Iterate backward through actors and apply function. + If the function returns truth, stop iterating." + (let ((s3-0 (-> obj prev))) + (while s3-0 + (if (arg0 s3-0 arg1) + (return (the-as int #f)) + ) + (set! s3-0 (entity-actor-lookup s3-0 'prev-actor 0)) + ) + ) + 0 + ) + +(defmethod apply-all actor-link-info + ((obj actor-link-info) (arg0 (function entity-actor object object)) (arg1 object)) + "Apply to all entities. Starts at the back and hits everyone, including this object." + ;; start at us (next may give us #f here, so can't do that.) + (let ((s4-0 (-> obj process entity))) + ;; while there is a prev... + (while (let ((a0-2 s4-0)) + (entity-actor-lookup (the-as res-lump a0-2) 'prev-actor 0) + ) + ;; set prev (this is stupid, they do the slow lookup twice!) + (set! s4-0 (entity-actor-lookup (the-as res-lump s4-0) 'prev-actor 0)) + ) + + ;; now iterate forward. + (while s4-0 + (if (arg0 (the-as entity-actor s4-0) arg1) + (return (the-as int #f)) + ) + (let ((a0-4 s4-0)) + (set! s4-0 (entity-actor-lookup (the-as res-lump a0-4) 'next-actor 0)) + ) + ) + ) + 0 + ) + +;; TODO: 20 and 21 don't decompile yet + +(defmethod send-to-next actor-link-info ((obj actor-link-info) (arg0 object)) + "Send event arg0 to the next actor's process" + (with-pp + (let ((a0-1 (-> obj next))) + ;; do we have a next? + (when a0-1 + ;; get the actual process + (let ((a0-2 (-> (the-as entity-links (-> a0-1 extra)) process))) + ;; do we have a process? + (when a0-2 + ;; create a block on the stack + (let ((v1-4 (new 'stack-no-clear 'event-message-block))) + (set! (-> v1-4 from) pp) + (set! (-> v1-4 num-params) 0) + (set! (-> v1-4 message) (the-as basic arg0)) + ;; and send it! + (send-event-function (the process a0-2) v1-4) + ) + ) + ) + ) + ) + ) + (none) + ) + +(defmethod send-to-prev actor-link-info ((obj actor-link-info) (arg0 object)) + "Send event arg1 to the next actor's process." + (with-pp + (let ((a0-1 (-> obj prev))) + (when a0-1 + (let ((a0-2 (-> (the-as entity-links (-> a0-1 extra)) process))) + (when a0-2 + (let ((v1-4 (new 'stack-no-clear 'event-message-block))) + (set! (-> v1-4 from) pp) + (set! (-> v1-4 num-params) 0) + (set! (-> v1-4 message) (the-as basic arg0)) + (send-event-function (the process a0-2) v1-4) + ) + ) + ) + ) + ) + ) + (none) + ) + +(defmethod send-to-next-and-prev actor-link-info ((obj actor-link-info) (arg0 object)) + "Send event arg0 to both next and prev." + (send-to-next obj arg0) + (send-to-prev obj arg0) + (none) + ) + +(defmethod dummy-19 actor-link-info ((obj actor-link-info) (arg0 object)) + (dummy-20 obj arg0) + (dummy-21 obj arg0) + (none) + ) + +(defmethod actor-count actor-link-info ((obj actor-link-info)) + "Count the number of actors in the entire list" + (let ((actor (-> obj process entity)) + (count 0) + ) + ;; get back to the beginning. + (while (let ((a0-2 actor)) + (entity-actor-lookup (the-as res-lump a0-2) 'prev-actor 0) + ) + (set! actor (entity-actor-lookup (the-as res-lump actor) 'prev-actor 0)) + ) + ;; iterate and set the count + (while actor + (+! count 1) + (let ((a0-3 actor)) + (set! actor (entity-actor-lookup (the-as res-lump a0-3) 'next-actor 0)) + ) + ) + count + ) + ) + +(defmethod get-matching-actor-type-mask actor-link-info ((obj actor-link-info) (matching-type type)) + "Iterate through _all_ actors that are part of this actor list. + If the nth actor is type matching-type, then set the nth bit of the result." + (let ((actor (the-as entity-actor (-> obj process entity))) + (mask 0) + ) + (let ((current-bit 1)) + + ;; seek to beginning + (while (let ((a0-2 actor)) (entity-actor-lookup a0-2 'prev-actor 0)) + (set! actor (entity-actor-lookup actor 'prev-actor 0)) + ) + + ;; loop over actors + (while actor + ;; if we match, set the bit + (if (= (-> actor etype) matching-type) + (set! mask (logior mask current-bit)) + ) + ;; next + (let ((a0-3 actor)) + (set! actor (entity-actor-lookup a0-3 'next-actor 0)) + ) + ;; next bit + (set! current-bit (* current-bit 2)) + ) + ) + mask + ) + ) + +(defmethod actor-count-before actor-link-info ((obj actor-link-info)) + "Get the number of actors _before_ this actor in the list." + (let* ((this-actor (-> obj process entity)) + (actor this-actor) + (count 0) + ) + ;; go to beginning (why not count here???) + (while (let ((a0-2 actor)) + (entity-actor-lookup (the-as res-lump a0-2) 'prev-actor 0) + ) + (set! actor (entity-actor-lookup (the-as res-lump actor) 'prev-actor 0)) + ) + ;; go forward, until we hit this actor + (while (!= actor this-actor) + (+! count 1) + (let ((a0-3 actor)) + (set! actor (entity-actor-lookup (the-as res-lump a0-3) 'next-actor 0)) + ) + ) + count + ) + ) + +(defun actor-link-subtask-complete-hook ((arg0 entity-actor) (arg1 (pointer symbol))) + "Sets arg1 if the thing is complete. Returns the opposite value." + (cond + ((nonzero? (logand + (-> (the-as entity-links (-> arg0 extra)) perm status) + (entity-perm-status complete) + ) + ) + (set! (-> arg1 0) #t) + #f + ) + (else + (set! (-> arg1 0) #f) + #t + ) + ) + ) + +(defun actor-link-dead-hook ((arg0 entity-actor) (arg1 (pointer symbol))) + "Sets arg1 is the thing is dead. Returns the opposite value." + (cond + ((nonzero? (logand + (-> (the-as entity-links (-> arg0 extra)) perm status) + (entity-perm-status dead) + ) + ) + (set! (-> arg1 0) #t) + #f + ) + (else + (set! (-> arg1 0) #f) + #t + ) + ) + ) + +(defun alt-actor-list-subtask-incomplete-count ((arg0 process-drawable)) + "Get the number of alt-actors which do not have the complete bit set in their perm." + (let ((alt-actor-count (entity-actor-count (the-as res-lump (-> arg0 entity)) 'alt-actor)) + (incomplete-count 0) + ) + + ;; iterate over all alt actors + (dotimes (alt-actor-idx alt-actor-count) + ;; look up the alt actor + (let ((a0-3 (entity-actor-lookup (the-as res-lump (-> arg0 entity)) 'alt-actor alt-actor-idx))) + (if (or (not a0-3) + (zero? (logand (-> (the-as entity-links (-> a0-3 extra)) perm status) (entity-perm-status complete))) + ) + (+! incomplete-count 1) + ) + ) + ) + incomplete-count + ) + ) diff --git a/goal_src/engine/entity/entity-h.gc b/goal_src/engine/entity/entity-h.gc index 7810b3d3a..e243255cc 100644 --- a/goal_src/engine/entity/entity-h.gc +++ b/goal_src/engine/entity/entity-h.gc @@ -14,6 +14,12 @@ ;; definition for symbol *generate-actor-vis-output*, type symbol (define *generate-actor-vis-output* #f) +(defenum entity-perm-status + :bitfield #t + :type uint16 + (dead 2) + (complete 6)) + ;; definition of type entity-perm (deftype entity-perm (structure) ((user-object object 2 :offset-assert 0) @@ -25,7 +31,7 @@ (user-uint16 uint16 4 :offset 0) (user-int8 int8 8 :offset 0) (user-uint8 uint8 8 :offset 0) - (status uint16 :offset-assert 8) + (status entity-perm-status :offset-assert 8) (dummy uint8 1 :offset-assert 10) (task uint8 :offset-assert 11) (aid uint32 :offset-assert 12) @@ -45,7 +51,7 @@ ((prev-link entity-links :offset-assert 0) (next-link entity-links :offset-assert 4) (entity basic :offset-assert 8) - (process basic :offset-assert 12) + (process process :offset-assert 12) (level basic :offset-assert 16) (vis-id int32 :offset-assert 20) (trans vector :inline :offset-assert 32) @@ -208,3 +214,6 @@ :birth-max 10 ) ) + +(defun-extern entity-by-name string entity) +(defun-extern entity-by-aid uint entity) diff --git a/test/decompiler/reference/all_forward_declarations.gc b/test/decompiler/reference/all_forward_declarations.gc index f9fe40d60..37a6244b4 100644 --- a/test/decompiler/reference/all_forward_declarations.gc +++ b/test/decompiler/reference/all_forward_declarations.gc @@ -902,3 +902,9 @@ :size-assert #x25f0 :flag-assert #x9000025f0 ) + +(defenum entity-perm-status + :bitfield #t + :type uint16 + (dead 2) + (complete 6)) \ No newline at end of file diff --git a/test/decompiler/reference/engine/entity/entity-h_REF.gc b/test/decompiler/reference/engine/entity/entity-h_REF.gc index a5ff9e71a..22e45577e 100644 --- a/test/decompiler/reference/engine/entity/entity-h_REF.gc +++ b/test/decompiler/reference/engine/entity/entity-h_REF.gc @@ -12,20 +12,20 @@ ;; definition of type entity-perm (deftype entity-perm (structure) - ((user-object object 2 :offset-assert 0) - (user-uint64 uint64 :offset 0) - (user-float float 2 :offset 0) - (user-int32 int32 2 :offset 0) - (user-uint32 uint32 2 :offset 0) - (user-int16 int16 4 :offset 0) - (user-uint16 uint16 4 :offset 0) - (user-int8 int8 8 :offset 0) - (user-uint8 uint8 8 :offset 0) - (status uint16 :offset-assert 8) - (dummy uint8 1 :offset-assert 10) - (task uint8 :offset-assert 11) - (aid uint32 :offset-assert 12) - (quad uint128 :offset 0) + ((user-object object 2 :offset-assert 0) + (user-uint64 uint64 :offset 0) + (user-float float 2 :offset 0) + (user-int32 int32 2 :offset 0) + (user-uint32 uint32 2 :offset 0) + (user-int16 int16 4 :offset 0) + (user-uint16 uint16 4 :offset 0) + (user-int8 int8 8 :offset 0) + (user-uint8 uint8 8 :offset 0) + (status entity-perm-status :offset-assert 8) + (dummy uint8 1 :offset-assert 10) + (task uint8 :offset-assert 11) + (aid uint32 :offset-assert 12) + (quad uint128 :offset 0) ) :pack-me :method-count-assert 10 @@ -62,7 +62,7 @@ ((prev-link entity-links :offset-assert 0) (next-link entity-links :offset-assert 4) (entity basic :offset-assert 8) - (process basic :offset-assert 12) + (process process :offset-assert 12) (level basic :offset-assert 16) (vis-id int32 :offset-assert 20) (trans vector :inline :offset-assert 32) diff --git a/test/decompiler/reference/engine/math/vector_REF.gc b/test/decompiler/reference/engine/math/vector_REF.gc index d3ab745c9..ab8c5e162 100644 --- a/test/decompiler/reference/engine/math/vector_REF.gc +++ b/test/decompiler/reference/engine/math/vector_REF.gc @@ -828,11 +828,12 @@ (defun vector-length-max! ((arg0 vector) (arg1 float)) (let ((f0-0 (vector-length arg0))) (when (not (or (= f0-0 0.0) (< f0-0 arg1))) - (set! f0-0 (/ f0-0 arg1)) - (when (!= f0-0 0.0) - (set! (-> arg0 x) (/ (-> arg0 x) f0-0)) - (set! (-> arg0 y) (/ (-> arg0 y) f0-0)) - (set! (-> arg0 z) (/ (-> arg0 z) f0-0)) + (let ((f0-1 (/ f0-0 arg1))) + (when (!= f0-1 0.0) + (set! (-> arg0 x) (/ (-> arg0 x) f0-1)) + (set! (-> arg0 y) (/ (-> arg0 y) f0-1)) + (set! (-> arg0 z) (/ (-> arg0 z) f0-1)) + ) ) ) ) @@ -843,10 +844,11 @@ (defun vector-xz-length-max! ((arg0 vector) (arg1 float)) (let ((f0-0 (vector-xz-length arg0))) (when (not (or (= f0-0 0.0) (< f0-0 arg1))) - (set! f0-0 (/ f0-0 arg1)) - (when (!= f0-0 0.0) - (set! (-> arg0 x) (/ (-> arg0 x) f0-0)) - (set! (-> arg0 z) (/ (-> arg0 z) f0-0)) + (let ((f0-1 (/ f0-0 arg1))) + (when (!= f0-1 0.0) + (set! (-> arg0 x) (/ (-> arg0 x) f0-1)) + (set! (-> arg0 z) (/ (-> arg0 z) f0-1)) + ) ) ) )