[game] make visibility work (#1031)

* make vis work

* update comments
This commit is contained in:
water111
2021-12-28 15:13:46 -05:00
committed by GitHub
parent 0d79b85d1c
commit 798356802b
31 changed files with 569 additions and 267 deletions
+1 -6
View File
@@ -5129,11 +5129,6 @@
;; - Types
(defenum vis-info-flag
:bitfield #t
:type uint32
(waiting-for-load 30)
)
(declare-type bsp-header basic)
(deftype level-vis-info (basic)
((level symbol :offset-assert 4)
@@ -6313,7 +6308,7 @@
(collide-ray (_type_ int collide-list) none 13)
(collect-stats (_type_) none 14)
(debug-draw (_type_ drawable display-frame) none 15)
(dummy-16 (_type_ object object) object 16)
(unpack-vis (_type_ (pointer int8) (pointer int8)) (pointer int8) 16)
(collect-ambients (_type_ sphere int ambient-list) none 17)
)
)
@@ -267,9 +267,6 @@
// target2 BUG
"look-for-points-of-interest", // Failed to split nested sc - looks like dead code to me
// drawable-tree
"(method 16 drawable-tree)",
// collide-cache
"(method 10 collide-puss-work)", // CFG
"(method 9 collide-puss-work)", // decompiler crash
@@ -482,7 +479,8 @@
"birth-pickup-at-point": [0],
"draw-bones": [0, 1, 2, 8, 81],
"draw-bones-hud": [7, 8]
"draw-bones-hud": [7, 8],
"(method 16 drawable-tree)": [7, 9, 10]
},
// Sometimes the game might use format strings that are fetched dynamically,
@@ -7282,5 +7282,21 @@
"(method 13 drawable-inline-array-instance-tie)": [
[[1, 6], "v1", "instance-tie"]
],
"(method 10 drawable-tree-array)": [
[4, "v1", "terrain-context"]
],
"(method 16 drawable-tree)":[
[[1,4], "v1", "drawable-inline-array-node"],
//[4, "a1", "int"],
[11, "v1", "(pointer int8)"],
[[29,34], "t0", "drawable-inline-array-node"],
[31, "t2", "drawable-inline-array-node"],
//[[34,36], "a1", "int"],
[36, "t1", "(pointer int8)"],
[[9, 42], "a2", "(pointer int8)"]
],
"placeholder-do-not-add-below": []
}
+22
View File
@@ -2,14 +2,19 @@
; Each entry should consist of an ISO name, followed by a file name
; note that tweakval, vagdir, screen1 have dummy data for now.
;; CGO Files
KERNEL.CGO out/iso/KERNEL.CGO
GAME.CGO out/iso/GAME.CGO
TEST.CGO resources/TEST.CGO
ART.CGO out/iso/ART.CGO
;; Special Weird Files
TWEAKVAL.MUS resources/TWEAKVAL.MUS
VAGDIR.AYB resources/VAGDIR.AYB
SCREEN1.USA resources/SCREEN1.USA
SAVEGAME.ICO resources/SAVEGAME.ICO
;; Text files
0COMMON.TXT out/iso/0COMMON.TXT
1COMMON.TXT out/iso/1COMMON.TXT
2COMMON.TXT out/iso/2COMMON.TXT
@@ -17,6 +22,8 @@ SAVEGAME.ICO resources/SAVEGAME.ICO
4COMMON.TXT out/iso/4COMMON.TXT
5COMMON.TXT out/iso/5COMMON.TXT
0TEST.TXT out/iso/0TEST.TXT
;; Level DGO
VI1.DGO out/iso/VI1.DGO
VI2.DGO out/iso/VI2.DGO
VI3.DGO out/iso/VI3.DGO
@@ -28,6 +35,21 @@ MAI.DGO out/iso/MAI.DGO
BEA.DGO out/iso/BEA.DGO
CIT.DGO out/iso/CIT.DGO
SUN.DGO out/iso/SUN.DGO
;; Level VIS
VI1.VIS out/iso/VI1.VIS
VI2.VIS out/iso/VI2.VIS
VI3.VIS out/iso/VI3.VIS
TRA.VIS out/iso/TRA.VIS
FIN.VIS out/iso/FIN.VIS
FIC.VIS out/iso/FIC.VIS
JUN.VIS out/iso/JUN.VIS
MAI.VIS out/iso/MAI.VIS
BEA.VIS out/iso/BEA.VIS
CIT.VIS out/iso/CIT.VIS
SUN.VIS out/iso/SUN.VIS
;; Streaming Animations
FUCVICTO.STR out/iso/FUCVICTO.STR
FUCV2.STR out/iso/FUCV2.STR
FUCV3.STR out/iso/FUCV3.STR
+1 -1
View File
@@ -731,7 +731,7 @@ u32 CopyDataToIOP(IsoMessage* _cmd, IsoBufferHeader* buffer_header) {
memcpy(cmd->dst_ptr, buffer_header->get_data(), bytes_to_send);
cmd->dest_addr += bytes_to_send;
cmd->dst_ptr += bytes_to_send;
cmd->bytes_done += bytes_to_send;
buffer_header->data = nullptr;
buffer_header->data_size = 0;
+2 -1
View File
@@ -139,6 +139,7 @@ void* RPC_Ramdisk(unsigned int fno, void* data, int size) {
gNumFiles++;
// Load file into IOP at the appropriate spot
printf("[OVERLORD RAMDISK] loading file %s with size %d\n", cmd->name, file_length);
LoadISOFileToIOP(file_record, gMem + gMemUsed, file_length);
gMemUsed += gFiles[gNumFiles].size;
} else {
@@ -169,7 +170,7 @@ void* RPC_Ramdisk(unsigned int fno, void* data, int size) {
}
// copy to return buffer. This way RAMDISK data is valid until another GET_DATA.
memcpy(gReturnBuffer, gMem + offset + gFiles[file_idx].additional_offset, size);
memcpy(gReturnBuffer, gMem + offset + gFiles[file_idx].additional_offset, cmd->size);
return gReturnBuffer;
} else if (fno == RAMDISK_BYPASS_LOAD_FILE) {
printf("[OVERLORD RAMDISK] got \"%s\"\n", cmd->name);
+3 -20
View File
@@ -6,26 +6,8 @@
#include <io.h>
#endif
#include "SystemThread.h"
//#include "shared_config.h"
//#include "ps2/SCE_IOP.h"
//#include "overlord/ramdisk.h"
//#include "ps2/SCE_SIF.h"
//#include "IOP.h"
//
//#include "overlord/dma.h"
//#include "overlord/fake_iso.h"
//#include "overlord/iso.h"
//#include "overlord/iso_api.h"
//#include "overlord/iso_cd.h"
//#include "overlord/iso_queue.h"
//#include "overlord/isocommon.h"
//#include "overlord/overlord.h"
//#include "overlord/ramdisk.h"
//#include "overlord/sbank.h"
//#include "overlord/soundcommon.h"
//#include "overlord/srpc.h"
//#include "overlord/ssound.h"
//#include "overlord/stream.h"
#include <cstring>
IOP::IOP() {}
@@ -68,6 +50,7 @@ void IOP::reset_allocator() {
void* IOP::iop_alloc(int size) {
void* mem = malloc(size);
memset(mem, 0xaa, size);
allocations.push_back(mem);
return mem;
}
+136 -115
View File
@@ -5,15 +5,11 @@
;; name in dgo: cam-update
;; dgos: GAME, ENGINE
;; definition for function plane-from-points
(defun
plane-from-points
((arg0 (inline-array plane))
(arg1 vector)
(arg2 vector)
(arg3 vector)
(arg4 int)
)
;; Once the camera's position and orientation has been calculated,
;; the camera and visibility outputs are updated in this file.
(defun plane-from-points ((arg0 (inline-array plane)) (arg1 vector) (arg2 vector) (arg3 vector) (arg4 int))
"Get a plane that contains the 3 given points."
(let ((s4-0 (new 'stack-no-clear 'vector)))
(vector-cross! s4-0 arg1 arg2)
(vector-normalize! s4-0 1.0)
@@ -28,8 +24,8 @@
)
)
;; definition for function set-point
(defun set-point ((arg0 vector) (arg1 float) (arg2 float) (arg3 float))
"Set a vector to an xyz point (sets w = 1.0)"
(set! (-> arg0 x) arg1)
(set! (-> arg0 y) arg2)
(set! (-> arg0 z) arg3)
@@ -39,11 +35,8 @@
)
)
;; definition for function update-view-planes
;; Used lq/sq
(defun
update-view-planes
((arg0 math-camera) (arg1 (inline-array plane)) (arg2 float))
(defun update-view-planes ((arg0 math-camera) (arg1 (inline-array plane)) (arg2 float))
"Compute the frustum planes from the given camera."
(local-vars (sv-240 vector))
(when (not *artist-fix-frustum*)
(let ((s5-0 (new 'stack 'view-frustum)))
@@ -129,116 +122,144 @@
)
)
;; definition for symbol *update-leaf-when-outside-bsp*, type symbol
;; if we should still attempt vis updates when outside of the bsp's boxes.
(define *update-leaf-when-outside-bsp* #t)
;; definition for function update-visible
(defun update-visible ((arg0 math-camera))
"Update occlusion visibility data for the camera position.
Each level has a bsp. Each leaf of the bsp stores a list of visible objects.
This is used to implement occlusion culling.
The vis-bits of the level will be updated if needed."
(local-vars (a0-16 symbol) (s3-0 level-vis-info) (s4-0 level-vis-info))
(when (not *artist-fix-visible*)
(dotimes (s5-0 (-> *level* length))
(let ((v1-4 (-> *level* level s5-0)))
(when (= (-> v1-4 status) 'active)
(if
(and
(nonzero? (-> v1-4 bsp nodes))
(or *update-leaf-when-outside-bsp* (-> v1-4 inside-boxes?))
)
(bsp-camera-asm (-> v1-4 bsp) (-> arg0 trans))
)
)
)
)
(dotimes (gp-1 (-> *level* length))
(let ((s5-1 (-> *level* level gp-1)))
(when (= (-> s5-1 status) 'active)
(let ((a2-0 (/ (+ (-> s5-1 bsp visible-list-length) 15) 16)))
(set! (-> s5-1 all-visible?) (if (-> s5-1 all-visible?)
(-> s5-1 all-visible?)
#t
)
)
(cond
((or (not (-> s5-1 force-all-visible?)) (-> s5-1 inside-boxes?))
(cond
((or *artist-all-visible* (zero? (-> s5-1 bsp nodes)))
(quad-copy! (-> s5-1 vis-bits) (-> s5-1 bsp all-visible-list) a2-0)
)
((begin
(set! s4-0 (-> s5-1 vis-info (-> s5-1 vis-self-index)))
(set! s3-0 (-> s5-1 vis-info (-> s5-1 vis-adj-index)))
(let ((v1-32 #f))
(set! a0-16 #f)
(when s4-0
(set! v1-32 (nonzero? (logand (shl #x8000 16) (-> s4-0 flags))))
(if (< (-> s4-0 length) (-> s4-0 from-bsp current-leaf-idx))
(set! v1-32 #f)
)
;; first, determine which leaf of the bsp we are in (per level).
(dotimes (s5-0 (-> *level* length))
(let ((v1-4 (-> *level* level s5-0)))
(when (= (-> v1-4 status) 'active)
(if (and (nonzero? (-> v1-4 bsp nodes))
(or *update-leaf-when-outside-bsp* (-> v1-4 inside-boxes?))
)
;; will store in the bsp's current-leaf-idx.
(bsp-camera-asm (-> v1-4 bsp) (-> arg0 trans))
)
(when s3-0
(set! a0-16 (nonzero? (logand (shl #x8000 16) (-> s3-0 flags))))
(if (< (-> s3-0 length) (-> s3-0 from-bsp current-leaf-idx))
(set! a0-16 #f)
)
)
v1-32
)
)
(if (!= (-> s5-1 all-visible?) 'loading)
(set! (-> s5-1 all-visible?) #f)
)
(when
(update-vis! s5-1 s4-0 (-> s4-0 ramdisk) (-> s4-0 string-block))
(countdown (v1-40 8)
(let ((a0-22 (-> s5-1 vis-info v1-40)))
(when a0-22
(if (!= a0-22 s4-0)
(set! (-> a0-22 current-vis-string) (the-as uint -1))
)
)
)
)
(set! (-> s5-1 all-visible?) #f)
)
)
(a0-16
(if (!= (-> s5-1 all-visible?) 'loading)
(set! (-> s5-1 all-visible?) #f)
)
(when
(update-vis! s5-1 s3-0 (-> s3-0 ramdisk) (-> s3-0 string-block))
(countdown (v1-50 8)
(let ((a0-27 (-> s5-1 vis-info v1-50)))
(when a0-27
(if (!= a0-27 s3-0)
(set! (-> a0-27 current-vis-string) (the-as uint -1))
)
)
)
)
(set! (-> s5-1 all-visible?) #f)
)
)
((and (= (-> s5-1 all-visible?) 'loading) (-> *level* play?))
)
(else
(quad-copy! (-> s5-1 vis-bits) (-> s5-1 bsp all-visible-list) a2-0)
)
)
)
(else
(quad-copy! (-> s5-1 vis-bits) (-> s5-1 bsp all-visible-list) a2-0)
)
)
)
(if (and *stats-bsp* (= *master-mode* 'game))
(format *stdcon* "~0kleaf-index = ~d~%" (-> s5-1 bsp current-leaf-idx))
)
)
)
;; do vis updates.
(dotimes (gp-1 (-> *level* length))
(let ((s5-1 (-> *level* level gp-1)))
(when (= (-> s5-1 status) 'active)
(let ((a2-0 (/ (+ (-> s5-1 bsp visible-list-length) 15) 16)))
;; start by setting all-visible to something truthy (either original, or #t)
;; below, we'll try to figure out a way to get vis data and set this back to #f.
(set! (-> s5-1 all-visible?) (if (-> s5-1 all-visible?)
(-> s5-1 all-visible?)
#t
)
)
(cond
((or (not (-> s5-1 force-all-visible?)) (-> s5-1 inside-boxes?))
;; we are inside the level's bsp, we should attempt vis stuff.
(cond
((or *artist-all-visible* (zero? (-> s5-1 bsp nodes)))
;; we have no bsp, or manual override all visible. Copy the all vis list
;; to our vis string.
(quad-copy! (-> s5-1 vis-bits) (-> s5-1 bsp all-visible-list) a2-0)
)
((begin
;; our vis info
(set! s4-0 (-> s5-1 vis-info (-> s5-1 vis-self-index)))
;; adj vis info (idx will be 7 if there's no adj right now, and will give us #f)
(set! s3-0 (-> s5-1 vis-info (-> s5-1 vis-adj-index)))
(let ((v1-32 #f)) ;; should use self vis
(set! a0-16 #f) ;; should use adj vis
;; see if we want self vis
(when s4-0
(set! v1-32 (nonzero? (logand (shl #x8000 16) (-> s4-0 flags))))
;; not sure when this would happen, but make sure that our leaf
;; index is in bounds (maybe if you use the wrong version of levels)
(if (< (-> s4-0 length) (-> s4-0 from-bsp current-leaf-idx))
(set! v1-32 #f)
)
)
;; see if we want adj vis.
(when s3-0
(set! a0-16 (nonzero? (logand (shl #x8000 16) (-> s3-0 flags))))
(if (< (-> s3-0 length) (-> s3-0 from-bsp current-leaf-idx))
(set! a0-16 #f)
)
)
v1-32 ;; this is the cond condition, and is if we want the self vis.
)
)
;; want self. clear all visible if we aren't loading.
(if (!= (-> s5-1 all-visible?) 'loading)
(set! (-> s5-1 all-visible?) #f)
)
(when (update-vis! s5-1 s4-0 (-> s4-0 ramdisk) (-> s4-0 string-block))
;; success! Remove all other vis strings.
;; if update vis failed (due to still loading, etc), keep previous.
(countdown (v1-40 8)
(let ((a0-22 (-> s5-1 vis-info v1-40)))
(when a0-22
(if (!= a0-22 s4-0)
(set! (-> a0-22 current-vis-string) (the-as uint -1))
)
)
)
)
;; successful vis update, remove all-visible.
(set! (-> s5-1 all-visible?) #f)
)
)
;; same case as above, but if we want to use the other vis.
(a0-16
(if (!= (-> s5-1 all-visible?) 'loading)
(set! (-> s5-1 all-visible?) #f)
)
(when
(update-vis! s5-1 s3-0 (-> s3-0 ramdisk) (-> s3-0 string-block))
(countdown (v1-50 8)
(let ((a0-27 (-> s5-1 vis-info v1-50)))
(when a0-27
(if (!= a0-27 s3-0)
(set! (-> a0-27 current-vis-string) (the-as uint -1))
)
)
)
)
(set! (-> s5-1 all-visible?) #f)
)
)
((and (= (-> s5-1 all-visible?) 'loading) (-> *level* play?))
;; if we're in between vis, then leave the old string.
)
(else
;; couldn't find any vis, just make everything visible
(quad-copy! (-> s5-1 vis-bits) (-> s5-1 bsp all-visible-list) a2-0)
)
)
)
(else
;; outside boxes, and force all visible is set.
(quad-copy! (-> s5-1 vis-bits) (-> s5-1 bsp all-visible-list) a2-0)
)
)
)
(if (and *stats-bsp* (= *master-mode* 'game))
(format *stdcon* "~0kleaf-index = ~d~%" (-> s5-1 bsp current-leaf-idx))
)
)
)
)
#f
)
#f
)
)
;; definition for symbol *save-camera-inv-rot*, type matrix
+1 -4
View File
@@ -21,10 +21,7 @@
)
;; definition for method 16 of type drawable-tree-collide-fragment
(defmethod
dummy-16
drawable-tree-collide-fragment
((obj drawable-tree-collide-fragment) (arg0 object) (arg1 object))
(defmethod unpack-vis drawable-tree-collide-fragment ((obj drawable-tree-collide-fragment) (arg0 (pointer int8)) (arg1 (pointer int8)))
arg1
)
+1 -1
View File
@@ -38,7 +38,7 @@
(none)
)
(defmethod dummy-16 drawable-tree-ambient ((obj drawable-tree-ambient) (arg0 object) (arg1 object))
(defmethod unpack-vis drawable-tree-ambient ((obj drawable-tree-ambient) (arg0 (pointer int8)) (arg1 (pointer int8)))
arg1
)
+3 -3
View File
@@ -107,9 +107,9 @@
(none)
)
(defmethod dummy-16 drawable-group ((obj drawable-group) (arg0 object) (arg1 object))
(dotimes (s4-0 (-> obj length))
(set! arg1 (dummy-16 (-> obj data s4-0) arg0 arg1))
(defmethod unpack-vis drawable-group ((obj drawable-group) (arg0 (pointer int8)) (arg1 (pointer int8)))
(dotimes (s4-0 (-> obj length) arg1)
(set! arg1 (unpack-vis (-> obj data s4-0) arg0 arg1))
)
arg1
)
+1 -1
View File
@@ -31,7 +31,7 @@
(collide-ray (_type_ int collide-list) none 13)
(collect-stats (_type_) none 14)
(debug-draw (_type_ drawable display-frame) none 15)
(dummy-16 (_type_ object object) object 16)
(unpack-vis (_type_ (pointer int8) (pointer int8)) (pointer int8) 16)
(collect-ambients (_type_ sphere int ambient-list) none 17)
)
)
+111 -6
View File
@@ -5,11 +5,116 @@
;; name in dgo: drawable-tree
;; dgos: GAME, ENGINE
;; todo
(defmethod debug-draw drawable-tree-array ((obj drawable-tree-array) (arg0 drawable) (arg1 display-frame))
(dotimes (s3-0 (-> obj length))
(debug-draw (-> obj trees s3-0) (-> (the-as drawable-tree-array arg0) trees s3-0) arg1)
)
;; The "drawable tree" represents a BVH for a specific render.
;; Typically, levels will have ~10 drawable trees. There will be a tree for
;; tfrag, a tree for actors, a tree for tie,
;; This file contains common functions for all drawable trees.
(defmethod draw drawable-tree-array ((obj drawable-tree-array) (arg0 drawable-tree-array) (arg1 display-frame))
"Draw a drawable tree array. If the current level is set to special or special-vis, the draw is skipped."
(let ((v1-1 (-> (scratchpad-object terrain-context) bsp lev-index)))
(case (-> *level* level v1-1 display?)
(('special 'special-vis #f)
)
(else
(dotimes (s3-0 (-> obj length))
(draw (-> obj trees s3-0) (-> arg0 trees s3-0) arg1)
)
)
)
)
0
(none)
)
)
(defmethod collect-stats drawable-tree-array ((obj drawable-tree-array))
(dotimes (s5-0 (-> obj length))
(collect-stats (-> obj trees s5-0))
)
(none)
)
(defmethod debug-draw drawable-tree-array ((obj drawable-tree-array) (arg0 drawable) (arg1 display-frame))
(dotimes (s3-0 (-> obj length))
(debug-draw (-> obj trees s3-0) (-> (the-as drawable-tree-array arg0) trees s3-0) arg1)
)
(none)
)
(defmethod unpack-vis drawable-tree ((obj drawable-tree) (arg0 (pointer int8)) (arg1 (pointer int8)))
"Copy our visibility data from arg1 to arg0, unpacking it."
(local-vars (t5-1 int))
;; grab the first array
(let* ((v1-0 (the-as drawable-inline-array-node (-> obj data 0)))
;; first elt in top array
(a3-1 (/ (-> v1-0 data 0 id) 8))
;; number in first array (8 or fewer)
(t0-0 (-> v1-0 length))
;; offset in destination
(v1-1 (&+ arg0 a3-1))
;; number of bytes
(a3-3 (/ (+ t0-0 7) 8))
)
;; copy the data!
;;(mem-print (the (pointer uint32) arg1) 10)
(dotimes (t0-1 a3-3)
(let ((t1-0 (-> arg1 0)))
;;(format 0 "top-copy: #x~X~%" t1-0)
(set! arg1 (&-> arg1 1))
(set! (-> v1-1 0) t1-0)
)
(set! v1-1 (&-> v1-1 1))
)
)
;; now, the remaining arrays, excluding the final which isn't a draw node array.
(let ((v1-5 (+ (-> obj length) -1)))
(when (nonzero? v1-5)
(dotimes (a3-5 v1-5)
;; pointer to this array
(let* ((t0-4 (-> obj data a3-5))
;; pointer to next depth array
(t2-0 (-> obj data (+ a3-5 1)))
;; id of first in prev
(t1-5 (/ (-> (the-as drawable-inline-array-node t0-4) data 0 id) 8))
;; id of first in next
(t2-2 (/ (-> (the-as drawable-inline-array-node t2-0) data 0 id) 8))
;; number of nodes in this one
(t0-5 (-> (the-as drawable-inline-array-node t0-4) length))
;; output for prev level
(t1-6 (&+ arg0 t1-5))
;; output for next level
(t2-3 (&+ arg0 t2-2))
)
(while #t
;; load the vis byte for the one in this array
(let ((t3-0 (-> t1-6 0)))
;; inc vis ptr.
(set! t1-6 (&-> t1-6 1))
;; vis mask bit. (init at highest)
(let ((t4-0 128))
(label cfg-7)
;; check if we're visible
(b! (zero? (logand t3-0 t4-0)) cfg-9 :delay (set! t5-1 (-> arg1 0)))
;; we are visible. write 8 in the output
(set! arg1 (&-> arg1 1))
(set! (-> t2-3 0) t5-1)
(label cfg-9)
(+! t0-5 -1)
;; check if we've done all nodes
(b! (zero? t0-5) cfg-12 :delay (.sra t4-0 t4-0 1))
;; check if we're done with this byte and inc output.
(b! (nonzero? t4-0) cfg-7 :delay (set! t2-3 (&-> t2-3 1)))
)
)
)
)
(label cfg-12)
(nop!)
0
)
)
)
arg1
)
+4
View File
@@ -37,6 +37,10 @@
)
)
(defmethod unpack-vis drawable ((obj drawable) (arg0 (pointer int8)) (arg1 (pointer int8)))
arg1
)
(defun-debug find-instance-by-name ((arg0 string))
(dotimes (s5-0 (-> *level* length))
(let ((v1-3 (-> *level* level s5-0)))
+4 -1
View File
@@ -659,6 +659,7 @@
)
;; added
#|
(let (
(remain (&- (-> global top) (-> global current)))
(total (&- (-> global top) (-> global base)))
@@ -668,11 +669,13 @@
(* 100.0 (/ (the float remain) (the float total)))
)
)
;; added
(format *stdcon* "~3LDMA global: ~d debug: ~d~0L~%"
(dma-buffer-free (-> disp frames (-> disp on-screen) frame global-buf))
(dma-buffer-free (-> disp frames (-> disp on-screen) frame debug-buf))
)
#|
;; added, prints some level status.
(dotimes (i 2)
(let ((level-heap (-> *level* level i heap)))
+3
View File
@@ -5,3 +5,6 @@
;; name in dgo: shrubbery
;; dgos: GAME, ENGINE
(defmethod unpack-vis drawable-tree-instance-shrub ((obj drawable-tree-instance-shrub) (arg0 (pointer int8)) (arg1 (pointer int8)))
arg1
)
-1
View File
@@ -158,7 +158,6 @@
)
;; set the time of day float. This is in hours (0-24)
(format *stdcon* "~0kstars: ~d time ~d:~2d~%" (-> self star-count) (-> self hour) (-> self minute))
(let* ((f0-4 (the float (-> self frame)))
(f0-6 (+ (* 0.0033333334 f0-4) (the float (-> self second))))
(f0-8 (+ (* 0.016666668 f0-6) (the float (-> self minute))))
+9 -2
View File
@@ -5,12 +5,16 @@
;; name in dgo: bsp-h
;; dgos: GAME, ENGINE
;; Each level has . There is a bsp-header, and a list of bsp-nodes.
;; Each level has a bsp file. There is a bsp-header, and a list of bsp-nodes.
;; The bsp-nodes make up a tree. Each node has a plane and two child nodes.
;; The bsp-header also contains (or references) all of the static level information.
;; The file containing the bsp-header is called the "bt" and is loaded in a special
;; way because that allows it to use all of the remaining level heap memory.
;; This file is very large (>8 MB), and always the last file in a level DGO.
;; The bsp file also contains all the drawable trees and lots of other level data,
;; so the "bsp-header" name isn't very accurate.
;; Typically, the "bsp" refers to the static level data, and the "level" to the runtime level info.
;; In the game, all of these bsp-header files have -vis after their name
;; I believe this means that this is a version of a level that has an associated vis file
@@ -19,6 +23,9 @@
(declare-type entity-camera basic)
;; flags: 1 = load
;; 2 = display
;; a node in the bsp tree
(deftype bsp-node (structure)
((front int32 :offset-assert 0) ;; if > 0, is a pointer to another bsp-node
@@ -48,7 +55,7 @@
(unk-zero-0 basic :offset-assert 68)
(name symbol :offset-assert 72)
(nickname symbol :offset-assert 76)
(vis-info level-vis-info 8 :offset-assert 80)
(vis-info level-vis-info 8 :offset-assert 80) ;; note: 0 when not present.
(actors drawable-inline-array-actor :offset-assert 112)
(cameras (array entity-camera) :offset-assert 116)
(nodes (inline-array bsp-node) :offset-assert 120)
+1
View File
@@ -216,6 +216,7 @@
(add-irq-to-tex-buckets! lev)
;; upload the visible list to the scratchpad.
;; the final result of all visibility calculations is stored in vis-bits.
;; this goes at the end of the scratchpad.
(let ((vis-list-qwc (/ (+ (-> obj visible-list-length) 15) 16)))
(dma-send-to-spr-no-flush
+22 -6
View File
@@ -6,19 +6,35 @@
;; dgos: GAME, ENGINE
;; The level system is responsible for loading and managning the two levels.
;; The "level" type contains runtime information about a level (possibly one that is loading)
;; and the "level-group" type contains two levels.
(defconstant LEVEL_COUNT 2) ;; there are two levels in memory!
(defenum vis-info-flag
:bitfield #t
:type uint32
(waiting-for-load 30)
(twenty-nine 29) ;; is .VIS file vis?
(waiting-for-iop-to-ee 30)
(thirty-one 31) ;; single vis?
)
;; Information related to visibility data for a level.
;; Unclear why there are 8 of these per level.
;; Perhaps there are up to 8 "chunks" of the visibility loaded at a single time?
;; The full visibility data lives on the IOP.
;; This is just metadata that describes the actual VIS file.
;; The typical use is to do (-> info vis-string idx) to get the offset (in the .VIS file) of the
;; compressed visibility string for a given bsp leaf.
;; Each level may have multiple level-vis-infos.
;; Each .VIS file can have visibility data for multiple levels.
;; Each level that is present in a .VIS has a level-vis-info to go with is.
;; One level-vis-info (the first) is always for the
;; actual level, and there is typically one for each neighboring level.
;; The final level-vis-info (7) should always be empty (set to 0 in the bsp-header)
;; When travelling between two levels, the game will only have one .VIS file loaded,
;; and it does two lookups in this .VIS file - one for the current level, and one for the nearby
;; levels. This means that visibility for "beach" near the border of "village1" is stored in
;; both BEA.VIS and VI1.VIS.
(declare-type bsp-header basic)
(deftype level-vis-info (basic)
((level symbol :offset-assert 4)
@@ -30,7 +46,7 @@
(dictionary-length uint32 :offset-assert 28)
(dictionary uint32 :offset-assert 32)
(string-block uint32 :offset-assert 36)
(ramdisk uint32 :offset-assert 40)
(ramdisk uint32 :offset-assert 40) ;; ramdisk file ID.
(vis-bits pointer :offset-assert 44)
(current-vis-string uint32 :offset-assert 48)
(vis-string uint32 :dynamic :offset-assert 52)
@@ -135,7 +151,7 @@
(all-visible? symbol :offset-assert 396)
(force-all-visible? symbol :offset-assert 400)
(linking basic :offset-assert 404)
(vis-info level-vis-info 8 :offset-assert 408)
(vis-info level-vis-info 8 :offset-assert 408) ;; note: #f when doesn't exist.
(vis-self-index int32 :offset-assert 440)
(vis-adj-index int32 :offset-assert 444)
(vis-buffer uint8 2048 :offset-assert 448)
+88 -42
View File
@@ -175,27 +175,40 @@
(defmethod vis-clear level ((obj level))
"Clear the visibility info for when the level is loading."
;; clear vis-infos, so we can't try to look up a vis string.
(countdown (v1-0 8)
(nop!) ;; the usual.
(set! (-> obj vis-info v1-0) #f)
)
;; set the vis string to all 0s.
(dotimes (v1-3 128)
(set! (deref int128 (-> obj vis-bits) v1-3) (the-as int128 0))
)
;; this flag indicates we don't have vis data because loading is in progress
(set! (-> obj all-visible?) 'loading)
0
)
(defmethod vis-load level ((obj level))
"Start the initial load of a VIS file to the IOP VIS buffer. After this is done, we can use
ramdisk-load to load chunks."
;; check to see if we have a buffer for loaded vis data.
(when (zero? (-> obj vis-info (-> obj vis-self-index) ramdisk))
;; nope, we have no vis data buffer, we need to set it up.
;; first, we should see if the other level has loaded vis. if so, kill it.
(let ((vis (-> obj other vis-info (-> obj other vis-self-index))))
(when (and vis (nonzero? (-> vis ramdisk)))
(set! (-> vis flags) (logand #xffffffffbfffffff (-> vis flags))) ;; clear #x40000000
(set! (-> vis flags) (logand #xffffffffbfffffff (-> vis flags))) ;; clear waiting-for-load
(set! (-> vis ramdisk) 0)
0
)
)
;; set up a ramdisk rpc (fill command, actually load the file from DVD to IOP buffer)
(let ((visname (make-file-name (file-kind vis) (the-as string (-> obj nickname)) 0 #f))
(cmd (the-as ramdisk-rpc-fill (add-element *ramdisk-rpc*)))
(s5-0 (+ *current-ramdisk-id* 1))
@@ -203,10 +216,14 @@
(set! *current-ramdisk-id* s5-0)
(set! (-> cmd filename) (string->sound-name visname))
(set! (-> cmd ee-id) s5-0)
(call *ramdisk-rpc* (the-as uint 1) (the-as pointer 0) (the-as uint 0))
(load-dbg "doing ramdisk vis load: ~A~%" visname)
(call *ramdisk-rpc* RAMDISK_RPC_FILL_FNO (the-as pointer 0) (the-as uint 0))
;; remember which ramdisk id we are assigned
(set! (-> obj vis-info (-> obj vis-self-index) ramdisk) s5-0)
)
)
;; return the ramdisk ID.
(-> obj vis-info (-> obj vis-self-index) ramdisk)
)
@@ -227,30 +244,42 @@
)
(defmethod init-vis level ((obj level))
"Link vis data to level."
"Set up the vis info in a level from the vis info in the BSP."
(when (not (or (= (-> obj status) 'inactive) (not (-> obj bsp))))
;; no vis loaded at first, mark as loading/invalid.
(set! (-> obj all-visible?) 'loading)
;; vis info 0 is always self.
(let ((s5-0 (-> obj bsp vis-info 0)))
;; check that our vis info is valid.
(cond
((and s5-0 (nonzero? s5-0) (valid? s5-0 level-vis-info #f #f 0))
;; add to the level
(set! (-> obj vis-info 0) s5-0)
;; don't have a string loaded yet
(set! (-> s5-0 current-vis-string) (the-as uint -1))
;; link to bsp
(set! (-> s5-0 from-bsp) (-> obj bsp))
;; the current vis string (uncompressed). The level allocates/manages this.
(set! (-> s5-0 vis-bits) (-> obj vis-bits))
(set!
(-> s5-0 flags)
(logand (the-as uint #xffffffff3fffffff) (-> s5-0 flags))
)
;; clear waiting-for-load, thirty-one
(set! (-> s5-0 flags) (logand (the-as uint #xffffffff3fffffff) (-> s5-0 flags)))
;; set twenty-nine
(set! (-> s5-0 flags) (logior #x20000000 (-> s5-0 flags)))
(set! (-> s5-0 ramdisk) (the-as uint 0))
(set! (-> s5-0 string-block) (the-as uint #f))
;; remember that we use the vis system. This will enable warnings in the kernel
;; if we run out of actor memory. Without vis, I guess this happens a lot.
(set! *vis-boot* #t)
)
(else
;; we don't have vis (but it's okay)
(set! (-> obj vis-info 0) #f)
)
)
)
;; check for up to 6 neighbor level vis info. The last one is always left as null.
(dotimes (s5-1 6)
(let* ((s3-0 (+ s5-1 1))
(s4-0 (-> obj bsp vis-info s3-0))
@@ -261,10 +290,8 @@
(set! (-> s4-0 current-vis-string) (the-as uint -1))
(set! (-> s4-0 from-bsp) #f)
(set! (-> s4-0 vis-bits) (-> obj vis-bits))
(set!
(-> s4-0 flags)
(logand (the-as uint #xffffffff1fffffff) (-> s4-0 flags))
)
;; clear 29, 30, 31
(set! (-> s4-0 flags) (logand (the-as uint #xffffffff1fffffff) (-> s4-0 flags)))
(set! *vis-boot* #t)
)
(else
@@ -1017,7 +1044,7 @@
;; method 10 level
(defmethod is-object-visible? level ((obj level) (arg0 int))
"Is arg0 visible?"
"Is arg0 visible? Note that this will return #f if the visibility data is not loaded."
;; check the vis bits!
(let* (;; lwu v1, 388(a0)
(vis-data (-> obj vis-bits))
@@ -1033,10 +1060,11 @@
;; dsllv v1, v1, a0
(check-sign-word (the int (shl vis-byte shift-amount))) ;; signed
)
;; slt v1, v1, r0
;; slt v1, v1, r0 v1 = (csw < 0)
;; daddiu v0, s7, 8
;; movz v0, s7, v1
(>= check-sign-word 0)
;; movz v0, s7, v1 if (csw >= 0) result = false
;;(format 0 "vis check ~D ~X ~X ~A~%" arg0 vis-byte check-sign-word (>= check-sign-word 0))
(< check-sign-word 0)
)
)
@@ -1062,7 +1090,7 @@
(< (-> arg0 y) (-> v1-5 0 max y))
(< (-> arg0 z) (-> v1-5 0 max z))
)
#t
(return #t)
)
(set! v1-5 (the (inline-array box8s) (-> v1-5 1)))
)
@@ -1759,23 +1787,33 @@
)
)
)
;; load vis info.
;; The load-state's vis-nick is the level we want vis data for.
;; Note that we won't load vis until we are inside the level's boxes.
;; this will be the level that is currently being used.
(let ((s5-3 #f))
(dotimes (v1-121 (-> *level* length))
(let ((a0-55 (-> *level* level v1-121)))
(when (= (-> a0-55 status) 'active)
(if (nonzero? (-> a0-55 vis-info (-> a0-55 vis-self-index) ramdisk))
(when (= (-> a0-55 status) 'active) ;; level is active
(if (nonzero? (-> a0-55 vis-info (-> a0-55 vis-self-index) ramdisk)) ;; and vis is set up.
(set! s5-3 (-> a0-55 nickname))
)
)
)
)
;; if we have the wrong vis
(when (and (!= s5-3 (-> obj vis-nick)) (-> *level* vis?))
;; and we want a vis
(when (-> obj vis-nick)
;; find matching level and load vis
(dotimes (s4-3 (-> *level* length))
(let ((v1-133 (-> *level* level s4-3)))
(when (= (-> v1-133 status) 'active)
(if (and (= (-> v1-133 nickname) (-> obj vis-nick))
(-> v1-133 inside-boxes?)
(-> v1-133 inside-boxes?) ;; note: only start if we are inside boxes.
)
(load-vis-info (-> obj vis-nick) s5-3)
)
@@ -1814,6 +1852,7 @@
(when (= (-> s4-0 status) 'active)
(set! (-> s4-0 inside-boxes?) (point-in-boxes? s4-0 (-> *math-camera* trans)))
(set! (-> s4-0 inside-sphere?) (>= (-> s4-0 bsp bsphere w) (-> s4-0 level-distance)))
;; being inside sets your meta-inside to #t. If you are outside, remember your old inside.
(if (-> s4-0 inside-boxes?)
(set! (-> s4-0 meta-inside?) #t)
)
@@ -1828,6 +1867,7 @@
(dotimes (s5-2 (-> obj length))
(let ((s4-1 (-> obj level s5-2)))
(when (= (-> s4-1 status) 'active)
;; if you're outside here, and inside somewhere else, kick out of meta inside.
(if (and (-> s4-1 inside-boxes?) (not (-> s4-1 other inside-boxes?)))
(set! (-> s4-1 other meta-inside?) #f)
)
@@ -1858,17 +1898,21 @@
)
)
;; handle visibility stuff
;; determine vis info idx for each level
(dotimes (v1-67 (-> obj length))
(let ((a0-26 (-> obj level v1-67)))
(when (= (-> a0-26 status) 'active)
;; self is always 0
(set! (-> a0-26 vis-self-index) 0)
;; neighbor level defaults to 7 (null placeholder)...
(set! (-> a0-26 vis-adj-index) 7)
;; but if there's a second level that's active, search for a vis info for that level...
(when (= (-> a0-26 other status) 'active)
(dotimes (a1-10 8)
(if (and (-> a0-26 vis-info a1-10)
(= (-> a0-26 vis-info a1-10 from-level) (-> a0-26 other load-name))
)
;; and store it in the adj index.
(set! (-> a0-26 vis-adj-index) a1-10)
)
)
@@ -1905,12 +1949,16 @@
)
)
;; not sure what this does yet...
;; if we have vis for level A, but we aren't "in" it, display an error and
;; force us out of the other level. Ideally the boxes and the load boundary system
;; will be consistent and there is no way to set a vis to a level that we aren't in.
;; (you can be "in" multiple levels at the same time, when crossing levels, it is expected
;; that you are in both.)
(dotimes (s5-4 (-> obj length))
(let ((s4-4 (-> obj level s5-4)))
(when (= (-> s4-4 status) 'active)
(when (and (= (-> s4-4 nickname) (-> *load-state* vis-nick))
(not (-> s4-4 inside-boxes?))
(when (and (= (-> s4-4 nickname) (-> *load-state* vis-nick)) ;; vis for A
(not (-> s4-4 inside-boxes?)) ;; but not in A
)
(if (and (= *cheat-mode* 'debug) (-> s4-4 other inside-boxes?))
(format
@@ -1925,7 +1973,9 @@
)
)
;; do the bsp vis stuff.
;; if we are outside of the boxes, we consider ourselves "outside of bsp"
;; if we are outside of both levels boxes, then we don't really know what to do
;; for vis, and we can display the classic "outside of bsp" error.
(cond
((not (or (-> obj level0 inside-boxes?) (-> obj level1 inside-boxes?)))
(when (or (-> obj level0 vis-info 0) (-> obj level1 vis-info 0))
@@ -1935,16 +1985,18 @@
)
)
(else
;; we are in at least one bsp.
;; now we need to link vis info to bsps.
(dotimes (v1-125 (-> obj length))
(let ((a0-44 (-> obj level v1-125)))
(when (= (-> a0-44 status) 'active)
;; loop over vis infos
(dotimes (a1-17 8)
(let ((a2-18 (-> a0-44 vis-info a1-17)))
(when a2-18
(set!
(-> a2-18 flags)
(logand (the-as uint #xffffffff7fffffff) (-> a2-18 flags))
)
;; clear bit 31
(set! (-> a2-18 flags) (logand (the-as uint #xffffffff7fffffff) (-> a2-18 flags)))
;; link info to bsp
(cond
((= a1-17 (-> a0-44 vis-self-index))
(set! (-> a2-18 from-bsp) (-> a0-44 bsp))
@@ -1959,34 +2011,30 @@
)
)
)
;; now, handle setting bit 31 (maybe single vis mode?)
(cond
;; special display self mode.
((= (-> a0-44 display?) 'display-self)
(let ((a0-46 (-> a0-44 vis-info (-> a0-44 vis-self-index))))
(if a0-46
(set!
(-> a0-46 flags)
(the-as uint (logior (shl #x8000 16) (-> a0-46 flags)))
)
(set! (-> a0-46 flags) (the-as uint (logior (shl #x8000 16) (-> a0-46 flags))))
)
)
)
;; in this level, but not the other, only use vis for this.
((and (-> a0-44 inside-boxes?) (not (-> a0-44 other inside-boxes?)))
(let ((a0-48 (-> a0-44 vis-info (-> a0-44 vis-self-index))))
(if a0-48
(set!
(-> a0-48 flags)
(the-as uint (logior (shl #x8000 16) (-> a0-48 flags)))
)
(set! (-> a0-48 flags) (the-as uint (logior (shl #x8000 16) (-> a0-48 flags))))
)
)
)
;; only in other level, only use vis for other.
((-> a0-44 other inside-boxes?)
(let ((a0-50 (-> a0-44 vis-info (-> a0-44 vis-adj-index))))
(if a0-50
(set!
(-> a0-50 flags)
(the-as uint (logior (shl #x8000 16) (-> a0-50 flags)))
)
(set! (-> a0-50 flags) (the-as uint (logior (shl #x8000 16) (-> a0-50 flags))))
)
)
)
@@ -2113,8 +2161,6 @@
)
(defmacro test-play ()
`(begin
;; before calling play, the C Kernel would set this.
+72 -41
View File
@@ -5,6 +5,8 @@
;; name in dgo: decomp
;; dgos: GAME, ENGINE
;; This file contains update-vis! which updates the vis-bits string from the loaded VIS file.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; decompression functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -110,56 +112,64 @@
)
(defmethod update-vis! level ((obj level) (vis-info level-vis-info) (arg1 uint) (arg2 uint))
"Update the vis-bits for the level with the given vis info.
arg1 unused. if the vis-file flag isn't set, will use arg2 as vis data."
(local-vars (t0-3 uint128) (vis-buffer object))
(let* ((cam-leaf-idx (-> vis-info from-bsp current-leaf-idx)) ;; current bsp leaf of camera
(curr-vis-str (-> vis-info current-vis-string)) ;; currently loaded vis-string.
(desired-vis-str (-> vis-info vis-string cam-leaf-idx)) ;; vis-string ptr for what we want.
(desired-vis-str (-> vis-info vis-string cam-leaf-idx)) ;; vis-string offset for bsp leaf.
)
;; oops
0
(+ 16 #x70000000)
(+ 2064 #x70000000)
;; wait on ramdisk load, or do nothing because we already have the right stuff.
;; this is the same string we asked for last time.
(when (= curr-vis-str desired-vis-str)
;; we match. but are we loading?
(cond
((logtest? (vis-info-flag waiting-for-load) (-> vis-info flags))
(if (check-busy *ramdisk-rpc*)
;; loading, and ramdisk not done, return #f, we don't have vis.
(return #f)
)
;; we are done loading. Jump to code that sets it up.
(logclear! (-> vis-info flags) (vis-info-flag waiting-for-load))
((logtest? (vis-info-flag waiting-for-iop-to-ee) (-> vis-info flags))
;; we started IOP -> EE, but it might not be done yet.
(when (check-busy *ramdisk-rpc*)
;; not done, wait.
(return #f)
)
;; we're done! Deal with the vis data.
(logclear! (-> vis-info flags) (vis-info-flag waiting-for-iop-to-ee))
(set! vis-buffer (-> obj vis-buffer))
(b! #t cfg-27 :delay (nop!))
)
(else
;; matched, and loaded!
;; matched, and loaded! A previous run would have done setup.
(return #t)
)
)
)
;; wait for any pending load to finish.
(when (logtest? (vis-info-flag waiting-for-load) (-> vis-info flags))
(if (check-busy *ramdisk-rpc*)
;; wait for any pending load to finish before trying to change things.
(when (logtest? (vis-info-flag waiting-for-iop-to-ee) (-> vis-info flags))
(when (check-busy *ramdisk-rpc*)
(return #f)
)
(logclear! (-> vis-info flags) (vis-info-flag waiting-for-load))
(logclear! (-> vis-info flags) (vis-info-flag waiting-for-iop-to-ee))
)
;; not sure what this does yet.
;; ok, we can now change the current string and request from iop.
(set! (-> vis-info current-vis-string) desired-vis-str)
;; this branch picks between .VIS file ramdisk and BSP file visibility data.
;; the self vis is always in the ramdisk, and the adj file is in the BSP file.
(b! (logtest? #x20000000 (-> vis-info flags)) cfg-15)
;; we're a BSP file file vis. Just use the given pointer and skip the ramdisk stuff.
(set! vis-buffer (the-as (pointer uint8) (+ arg2 desired-vis-str)))
(b! #t cfg-27 :delay (nop!))
(label cfg-15)
;; start a ramdisk load.
;; start a ramdisk load. This should have already been done as part of level loading anyway.
;; so this will just get the ramdisk file ID.
(let ((vis-load-result (vis-load obj)))
(b! (nonzero? vis-load-result) cfg-21)
;; ramdisk failed, make everything visible.
(let* ((dest-bits (-> vis-info vis-bits))
(len (-> obj bsp visible-list-length))
(bsp-bits (the-as (pointer uinteger) (-> obj bsp all-visible-list)))
@@ -178,6 +188,8 @@
(b! #t cfg-55 :delay (nop!))
(the-as none 0)
(label cfg-21)
;; if the ramdisk is busy at this point, it means that it's still loading the file
;; from the DVD. So display a message and keep us in loading.
(when (check-busy *ramdisk-rpc*)
(set! (-> vis-info current-vis-string) (the-as uint -1))
(set! (-> obj all-visible?) 'loading)
@@ -186,60 +198,64 @@
)
(return #f)
)
;; now the ramdisk has the file in the IOP for sure. we want to ask for the IOP->EE transfer
;; for the string for our leaf node. Set a flag to remember that we're waiting on IOP->EE:
(set! (-> vis-info flags) (logior (-> vis-info flags) #x40000000))
;; and kick off a load
(ramdisk-load
(the-as int vis-load-result)
desired-vis-str
(the-as uint 2048)
(-> obj vis-buffer)
(the-as int vis-load-result) ;; file ID in ramdisk
desired-vis-str ;; the offset in the VIS file
(the-as uint 2048) ;; always do 2kB. it's a worst case if the string can't be compressed
(-> obj vis-buffer) ;; copy to the level buffer for vis data
)
(set! result #f)
(set! result #f) ;; this takes time, so quit and report that we failed.
(b! #t cfg-55 :delay (nop!))
;; setup loaded
;; we'll get here once the compressed vis data is in vis-buffer
;; this can come from IOP->EE or from the BSP file directly
(label cfg-27)
;; the vis info has data on how to decompress the data in the lower flag bits
(let ((lower-flag-bits (the-as int (logand #x1fffffff (-> vis-info flags))))
(spad-start (the-as object (+ 16 #x70000000)))
(spad-end (+ 2064 #x70000000))
(spad-start (the-as object (scratchpad-object object :offset 16)))
(spad-end (the-as int (scratchpad-object int :offset 2064)))
(list-len (-> obj bsp visible-list-length))
)
(when (zero? (the-as vis-info-flag lower-flag-bits))
;; set the spad buffer to 0 (but we write over this next??)
(let ((list-qwc (/ (+ list-len 15) 16)))
(dotimes (a0-28 list-qwc)
(set!
(-> (the-as (pointer uint128) spad-start) a0-28)
(the-as uint128 0)
)
(set! (-> (the-as (pointer uint128) spad-start) a0-28) (the-as uint128 0))
)
)
(mem-copy!
(the-as pointer spad-start)
(the-as pointer vis-buffer)
list-len
)
;; but then copy the vis buffer directly.
(mem-copy! (the-as pointer spad-start) (the-as pointer vis-buffer) list-len)
)
(while (nonzero? lower-flag-bits)
(case (logand lower-flag-bits 7)
((1)
((1) ;; decomp type 1: this unpacks data that exploits the BVH tree structure.
;; it omits 0's for children of invisible parents. But to unpack, we need
;; to know all the BVHs in the level.
(let ((v1-55 (/ (+ list-len 15) 16)))
(dotimes (a0-32 v1-55)
(set! (-> (the-as (pointer uint128) spad-start) a0-32) (the-as uint128 0))
)
)
(dummy-16
(unpack-vis
(-> obj bsp drawable-trees)
(the-as int spad-start)
(the-as object vis-buffer)
(the-as (pointer int8) spad-start)
(the-as (pointer int8) vis-buffer)
)
)
((2)
((2) ;; decomp type 2: run length encoding. Haven't seen this yet.
(format 0 "hit RLE case in decomp.gc, probably worth checking.~%")
(unpack-comp-rle
(the-as (pointer int8) spad-start)
(the-as (pointer int8) vis-buffer)
)
)
((3)
((3) ;; decomp type 3: huffman encoding. most common.
(unpack-comp-huf
(the-as (pointer uint8) spad-start)
(the-as (pointer uint8) vis-buffer)
@@ -250,14 +266,24 @@
)
)
)
;; we have 3 rotating 2kB buffers for this unpacking process.
;; we really only need 2, but I think they did 3 like this so we do RAM -> SPAD, SPAD->SPAD
;; in practice, I've only seen this hit exactly 2 decompressions, so no need for more complicated
;; logic to keep us in scratch after the first.
(set! vis-buffer (the-as (pointer uint8) (the-as int spad-start)))
(set! spad-start spad-end)
(set! spad-end (the-as int vis-buffer))
(.sra lower-flag-bits lower-flag-bits 3)
)
;; now vis-buffer points to the uncompressed data.
;; if things went well, we shouldn't have any bits set for drawables that don't exist.
;; we can check this by anding with the all visible list, and confirming it doesn't
;; remove any bits.
;; this just prints errors.
(let ((s2-1 (the-as object vis-buffer))
(s1-1 (the-as (pointer uinteger) (-> obj bsp all-visible-list)))
(v1-67 #f)
(v1-67 #f) ;; found error
)
(dotimes (s0-1 list-len)
(when (!= (logand (-> (the-as (pointer uint8) s2-1) 0)
@@ -270,6 +296,7 @@
(-> (the-as (pointer uint8) s2-1) 0)
(-> (the-as (pointer uint8) s1-1) 0)
)
(format #t "bad addr: #x~X~%" s2-1) ;; added
(set! v1-67 #t)
)
(set! s2-1 (&-> (the-as (pointer uint8) s2-1) 1))
@@ -286,6 +313,9 @@
0
)
)
;; just in case we failed the above check, and with the all visible list anyway.
;; also copy from vis-buffer (may be spad) to the final vis-bits output
(let ((v1-71 (the-as object vis-buffer))
(a0-47 (-> vis-info vis-bits))
(a1-22 (the-as (pointer uinteger) (-> obj bsp all-visible-list)))
@@ -304,6 +334,7 @@
)
)
)
;; succeeded!
(set! result #t)
(label cfg-55)
result
+2
View File
@@ -9,6 +9,8 @@
;; unlike most other loads, ramdisk actually uses the response buffer of the RPC
;; to send the data.
(defconstant RAMDISK_RPC_FILL_FNO (the uint 1))
;; command to load something into the OVERLORD RAMDISK from the DVD
;; use with fno = 1
(deftype ramdisk-rpc-fill (structure)
@@ -945,13 +945,14 @@
(set! (-> obj center quad) (-> arg0 quad))
;; check if we are visible (remove this check to force particles to be drawn.)
(if (not (or #t ;;(is-visible? obj arg0)
(if (not (or (is-visible? obj arg0)
(logtest? (-> obj group flags) (sp-group-flag always-draw screen-space))
)
)
(return (the-as object 0))
)
(let ((s4-0 *particle-300hz-timer*)
(s5-0 (-> obj last-spawn-time))
)
+53 -2
View File
@@ -117,6 +117,17 @@
:tool 'copy
:out '(,(string-append "out/iso/" name ".STR")))))
(defmacro copy-vis-files (&rest files)
`(begin ,@(apply (lambda (x) `(copy-vis-file ,x)) files)))
(defmacro copy-vis-file (name)
(let* ((folder (get-environment-variable "OPENGOAL_DECOMP_DIR" :default ""))
(path (string-append "iso_data/" folder "/VIS/" name ".VIS")))
`(defstep :in ,path
:tool 'copy
:out '(,(string-append "out/iso/" name ".VIS")))))
(defmacro group (name &rest stuff)
@@ -184,8 +195,10 @@
;; Streaming anim (common)
;;;;;;;;;;;;;;;;;;;;;;;;;;;
(copy-strs "FUCV3"
"FUCV4")
(copy-strs
"FUCVICTO"
"FUCV3"
"FUCV4")
;;;;;;;;;;;;;;;;;;;;;
@@ -230,6 +243,7 @@
"out/iso/0COMMON.TXT"
"out/iso/KERNEL.CGO"
"out/iso/GAME.CGO"
;; level dgo
"out/iso/VI1.DGO"
"out/iso/VI2.DGO"
"out/iso/VI3.DGO"
@@ -241,6 +255,20 @@
"out/iso/BEA.DGO"
"out/iso/CIT.DGO"
"out/iso/SUN.DGO"
;; level vis
"out/iso/VI1.VIS"
"out/iso/VI2.VIS"
"out/iso/VI3.VIS"
"out/iso/TRA.VIS"
"out/iso/FIN.VIS"
"out/iso/FIC.VIS"
"out/iso/JUN.VIS"
"out/iso/MAI.VIS"
"out/iso/BEA.VIS"
"out/iso/CIT.VIS"
"out/iso/SUN.VIS"
"out/iso/FUCVICTO.STR"
"out/iso/FUCV3.STR"
"out/iso/FUCV4.STR"
)
@@ -327,6 +355,9 @@
"vi1.gd"
)
;; the VIS file
(copy-vis-files "VI1")
;; the code
(goal-src-sequence
"levels/"
@@ -396,6 +427,8 @@
(cgo "JUN.DGO"
"jun.gd")
(copy-vis-files "JUN")
(goal-src-sequence
"levels/jungle/"
:deps ;; no idea what these depend on, make it depend on the whole engine
@@ -460,6 +493,8 @@
"bea.gd"
)
(copy-vis-files "BEA")
(goal-src-sequence
"levels/beach/"
:deps ("out/obj/default-menu.o")
@@ -520,6 +555,8 @@
"fic.gd"
)
(copy-vis-files "FIC")
(copy-textures 1119) ;; might be common/zoomer hud??
(goal-src-sequence
@@ -553,6 +590,8 @@
(cgo "TRA.DGO"
"tra.gd")
(copy-vis-files "TRA")
;; The code
(goal-src-sequence
"levels/training/"
@@ -584,6 +623,8 @@
(cgo "VI2.DGO" "vi2.gd")
(copy-vis-files "VI2")
(goal-src-sequence
"levels/village2/"
:deps ("out/obj/default-menu.o")
@@ -644,6 +685,8 @@
(cgo "SUN.DGO" "sun.gd")
(copy-vis-files "SUN")
(goal-src-sequence
"levels/sunken/"
:deps ("out/obj/default-menu.o")
@@ -715,6 +758,8 @@
;; the definition for the DGO file.
(cgo "VI3.DGO" "vi3.gd")
(copy-vis-files "VI3")
;; the code
(goal-src-sequence
"levels/"
@@ -760,6 +805,8 @@
(cgo "MAI.DGO" "mai.gd")
(copy-vis-files "MAI")
(goal-src-sequence
"levels/"
:deps ;; no idea what these depend on, make it depend on the whole engine
@@ -813,6 +860,8 @@
(cgo "CIT.DGO" "cit.gd")
(copy-vis-files "CIT")
(goal-src-sequence
"levels/citadel/"
:deps ("out/obj/default-menu.o")
@@ -872,6 +921,8 @@
(cgo "FIN.DGO" "fin.gd")
(copy-vis-files "FIN")
(goal-src-sequence
"levels/finalboss/"
:deps ("out/obj/default-menu.o")
+3 -3
View File
@@ -1645,13 +1645,13 @@ void IR_Int128Math3Asm::do_codegen(emitter::ObjectGenerator* gen,
gen->add_instr(IGen::parallel_compare_e_w(dst, src2, src1), irec);
break;
case Kind::PCGTB:
gen->add_instr(IGen::parallel_compare_gt_b(dst, src2, src1), irec);
gen->add_instr(IGen::parallel_compare_gt_b(dst, src1, src2), irec);
break;
case Kind::PCGTH:
gen->add_instr(IGen::parallel_compare_gt_h(dst, src2, src1), irec);
gen->add_instr(IGen::parallel_compare_gt_h(dst, src1, src2), irec);
break;
case Kind::PCGTW:
gen->add_instr(IGen::parallel_compare_gt_w(dst, src2, src1), irec);
gen->add_instr(IGen::parallel_compare_gt_w(dst, src1, src2), irec);
break;
case Kind::PSUBW:
// psubW on mips is psubD on x86...
+1 -1
View File
@@ -19,7 +19,7 @@
)
;; definition for method 16 of type drawable-tree-collide-fragment
(defmethod dummy-16 drawable-tree-collide-fragment ((obj drawable-tree-collide-fragment) (arg0 object) (arg1 object))
(defmethod unpack-vis drawable-tree-collide-fragment ((obj drawable-tree-collide-fragment) (arg0 (pointer int8)) (arg1 (pointer int8)))
arg1
)
+1 -1
View File
@@ -48,7 +48,7 @@
)
;; definition for method 16 of type drawable-tree-ambient
(defmethod dummy-16 drawable-tree-ambient ((obj drawable-tree-ambient) (arg0 object) (arg1 object))
(defmethod unpack-vis drawable-tree-ambient ((obj drawable-tree-ambient) (arg0 (pointer int8)) (arg1 (pointer int8)))
arg1
)
+2 -2
View File
@@ -108,9 +108,9 @@
)
;; definition for method 16 of type drawable-group
(defmethod dummy-16 drawable-group ((obj drawable-group) (arg0 object) (arg1 object))
(defmethod unpack-vis drawable-group ((obj drawable-group) (arg0 (pointer int8)) (arg1 (pointer int8)))
(dotimes (s4-0 (-> obj length))
(set! arg1 (dummy-16 (-> obj data s4-0) arg0 arg1))
(set! arg1 (unpack-vis (-> obj data s4-0) arg0 arg1))
)
arg1
)
+1 -1
View File
@@ -17,7 +17,7 @@
(collide-ray (_type_ int collide-list) none 13)
(collect-stats (_type_) none 14)
(debug-draw (_type_ drawable display-frame) none 15)
(dummy-16 (_type_ object object) object 16)
(unpack-vis (_type_ (pointer int8) (pointer int8)) (pointer int8) 16)
(collect-ambients (_type_ sphere int ambient-list) none 17)
)
)
+1 -1
View File
@@ -192,7 +192,7 @@
(set! (-> (the-as (pointer uint128) spad-start) a0-32) (the-as uint128 0))
)
)
(dummy-16 (-> obj bsp drawable-trees) (the-as int spad-start) vis-buffer)
(unpack-vis (-> obj bsp drawable-trees) (the-as (pointer int8) spad-start) (the-as (pointer int8) vis-buffer))
)
((2)
(unpack-comp-rle (the-as (pointer int8) spad-start) (the-as (pointer int8) vis-buffer))