;;-*-Lisp-*- (in-package goal) ;; name: level-h.gc ;; name in dgo: level-h ;; dgos: GAME, ENGINE ;; The level system is responsible for loading and managning the two levels. (defconstant LEVEL_COUNT 2) ;; there are two levels in memory! ;; 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. (declare-type bsp-header basic) (deftype level-vis-info (basic) ((level symbol :offset-assert 4) (from-level symbol :offset-assert 8) (from-bsp bsp-header :offset-assert 12) (flags uint32 :offset-assert 16) (length uint32 :offset-assert 20) (allocated-length uint32 :offset-assert 24) (dictionary-length uint32 :offset-assert 28) (dictionary uint32 :offset-assert 32) (string-block uint32 :offset-assert 36) (ramdisk uint32 :offset-assert 40) (vis-bits pointer :offset-assert 44) (current-vis-string uint32 :offset-assert 48) (vis-string uint8 :dynamic :offset-assert 52) ) :method-count-assert 9 :size-assert #x34 :flag-assert #x900000034 ) (defmethod asize-of level-vis-info ((obj level-vis-info)) "Get the size of a level-vis-info in memory" (the-as int (+ (-> level-vis-info size) (-> obj dictionary-length))) ) ;; Per level information related to how to load the level. ;; These are stored in level-info.gc (deftype level-load-info (basic) ((name-list symbol 3 :offset-assert 4) (index int32 :offset-assert 16) ;; the level number (starting with 1?) (name symbol :offset 4) ;; symbol with full name, like "misty" (visname symbol :offset 8) ;; symbol with vis file name, like "misty-vis" (nickname symbol :offset 12) ;; 3 letter name for DGO, like "mis" (packages pair :offset-assert 20) ;; list of symbols, usually empty or the level name (sound-banks pair :offset-assert 24) ;; require sound bank files (list of symbols) (music-bank symbol :offset-assert 28) ;; name of level music (ambient-sounds pair :offset-assert 32) ;; always empty list. (mood symbol :offset-assert 36) ;; mood object name (mood-func symbol :offset-assert 40) ;; mood update function name (ocean symbol :offset-assert 44) ;; ocean map object (sky symbol :offset-assert 48) ;; boolean to enable sky (sun-fade float :offset-assert 52) ;; sun/sky setting (continues pair :offset-assert 56) ;; list of checkpoints (tasks pair :offset-assert 60) ;; list of boxed integers for tasks (priority int32 :offset-assert 64) ;; either 100 or 200 (load-commands pair :offset-assert 68) ;; ?? (alt-load-commands pair :offset-assert 72) ;; ?? (bsp-mask uint64 :offset-assert 80) ;; ?? (bsphere sphere :offset-assert 88) ;; boundings sphere of level? (buzzer int32 :offset-assert 92) ;; which task is the scout fly? (bottom-height meters :offset-assert 96) (run-packages pair :offset-assert 100) ;; possibly unused? (prev-level basic :offset-assert 104) (next-level basic :offset-assert 108) (wait-for-load symbol :offset-assert 112) ) :method-count-assert 9 :size-assert #x74 :flag-assert #x900000074 ) ;; The levels are initialized (called "login") over multiple frames. ;; The state of this process is stored in a login-state. (declare-type drawable basic) (deftype login-state (basic) ((state int32 :offset-assert 4) (pos uint32 :offset-assert 8) (elts uint32 :offset-assert 12) (elt drawable 16 :offset-assert 16) ;; might be more specific ) :method-count-assert 9 :size-assert #x50 :flag-assert #x900000050 ) (declare-type engine basic) (declare-type entity-links-array basic) (declare-type entity-ambient-data-array basic) (declare-type mood-context basic) (deftype level (basic) ((name symbol :offset-assert 4) (load-name symbol :offset-assert 8) (nickname symbol :offset-assert 12) (index int32 :offset-assert 16) (status symbol :offset-assert 20) (other level :offset-assert 24) (heap kheap :inline :offset-assert 32) (bsp bsp-header :offset-assert 48) (art-group load-dir-art-group :offset-assert 52) (info level-load-info :offset-assert 56) (texture-page texture-page 9 :offset-assert 60) (loaded-texture-page texture-page 16 :offset-assert 96) (loaded-texture-page-count int32 :offset-assert 160) ; (foreground-sink-group-0 dma-foreground-sink-group :inline :offset-assert 176) ; (foreground-sink-group-1 dma-foreground-sink-group :inline :offset-assert 208) ; (foreground-sink-group-2 dma-foreground-sink-group :inline :offset-assert 240) ; (array-pad uint8 12) (foreground-sink-group dma-foreground-sink-group 3 :inline :offset-assert 176) ;; inline basic (foreground-draw-engine engine 3 :offset-assert 272) (entity entity-links-array :offset-assert 284) (ambient entity-ambient-data-array :offset-assert 288) (closest-object float 9 :offset-assert 292) (upload-size int32 9 :offset-assert 328) (level-distance meters :offset-assert 364) (inside-sphere? symbol :offset-assert 368) (inside-boxes? symbol :offset-assert 372) (display? symbol :offset-assert 376) (meta-inside? symbol :offset-assert 380) (mood mood-context :offset-assert 384) (mood-func function :offset-assert 388) (vis-bits pointer :offset-assert 392) (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-self-index int32 :offset-assert 440) (vis-adj-index int32 :offset-assert 444) (vis-buffer uint8 2048 :offset-assert 448) (mem-usage-block memory-usage-block :offset-assert 2496) (mem-usage int32 :offset-assert 2500) (code-memory-start pointer :offset-assert 2504) (code-memory-end pointer :offset-assert 2508) (texture-mask uint32 9 :offset-assert 2512) (force-inside? symbol :offset-assert 2548) (pad uint8 56) ) :method-count-assert 29 :size-assert #xa30 :flag-assert #x1d00000a30 (:methods (deactivate (_type_) _type_ 9) (dummy-10 (_type_ int) symbol 10) (add-irq-to-tex-buckets! (_type_) none 11) (unload! (_type_) _type_ 12) (bsp-name (_type_) symbol 13) (dummy-14 (_type_ object) memory-usage-block 14) (dummy-15 (_type_ vector) symbol 15) (dummy-16 (_type_) none 16) (load-continue (_type_) _type_ 17) (load-begin (_type_) _type_ 18) (login (_type_) _type_ 19) (vis-load (_type_) uint 20) (dummy-21 (_type_) none 21) (activate (_type_) _type_ 22) (level-status-set! (_type_ symbol) _type_ 23) (dummy-24 (_type_) _type_ 24) (dummy-25 (_type_) int 25) (vis-clear (_type_) int 26) (dummy-27 (_type_ vector string) none 27) (art-group-get-by-name (_type_ string) art-group 28) ) ) (declare-type entity-links structure) ;; Main *level* object. ;; There are actually three levels. level0 and level1 correspond to the actual buffered levels ;; The level-default seems to be a fake level that can possibly be used by renderers that ;; don't belong to any level, for example to render Jak. (declare-type entity-links structure) (deftype level-group (basic) ((length int32 :offset-assert 4) (log-in-level level :offset-assert 8) ;; level currently logging in (loading-level level :offset-assert 12) ;; currently loading (entity-link entity-links :offset-assert 16) ;; not sure what's going on here (border? basic :offset-assert 20) (vis? basic :offset-assert 24) (want-level basic :offset-assert 28) (receiving-level basic :offset-assert 32) (load-commands pair :offset-assert 36) (play? symbol :offset-assert 40) ;; there's something? from 40 -> 96. (_hack-pad uint8 :offset 90) (level0 level :inline :offset-assert 96) (level1 level :inline :offset-assert 2704) (level-default level :inline :offset-assert 5312) ;; this actually went earlier, (level level 3 :inline :offset 96) ;; and this one too. why another one? (data level 3 :score -1 :inline :offset 96) (pad uint32) ) :method-count-assert 27 :size-assert #x1ef4 :flag-assert #x1b00001ef4 (:methods (level-get (_type_ symbol) level 9) (level-get-with-status (_type_ symbol) level 10) (level-get-for-use (_type_ symbol symbol) level 11) (activate-levels! (_type_) int 12) (dummy-13 () none 13) (dummy-14 (_type_ object) none 14) (dummy-15 () none 15) (dummy-16 (_type_) int 16) (level-get-target-inside (_type_) level 17) (alloc-levels! (_type_ symbol) int 18) (load-commands-set! (_type_ pair) pair 19) (art-group-get-by-name (_type_ string) art-group 20) (load-command-get-index (_type_ symbol int) pair 21) (dummy-22 () none 22) (dummy-23 () none 23) (dummy-24 () none 24) (level-status (_type_ symbol) symbol 25) (level-get-most-disposable (_type_) level 26) ) ) (defun-extern level-update-after-load level login-state level) ;; Initialize the level structure. This assigns DMA buckets to each level. ;; TODO: figure out exactly which buckets are used for what. (define-extern *level* level-group) (if (zero? *level*) (set! *level* (new 'static 'level-group :length 2 :log-in-level #f :loading-level #f :entity-link #f :border? #f :want-level #f :load-commands '() :play? #f :level0 (new 'static 'level :name #f :status 'inactive :foreground-sink-group (new 'static 'inline-array dma-foreground-sink-group 3 (new 'static 'dma-foreground-sink-group :sink (new 'static 'array dma-foreground-sink 3 (new 'static 'dma-foreground-sink :bucket 10) (new 'static 'generic-dma-foreground-sink :bucket 11 :foreground-output-bucket 1 ) ) ) (new 'static 'dma-foreground-sink-group :sink (new 'static 'array dma-foreground-sink 3 (new 'static 'dma-foreground-sink :bucket 49 :foreground-texture-page 1 ) (new 'static 'generic-dma-foreground-sink :bucket 50 :foreground-texture-page 1 :foreground-output-bucket 1) ) ) (new 'static 'dma-foreground-sink-group :sink (new 'static 'array dma-foreground-sink 3 (new 'static 'dma-foreground-sink :bucket 58 :foreground-texture-page 2 ) (new 'static 'generic-dma-foreground-sink :bucket 59 :foreground-texture-page 2 :foreground-output-bucket 1 ) ) ) ) :inside-sphere? #f :inside-boxes? #f :force-inside? #f ) :level1 (new 'static 'level :name #f :index 1 :status 'inactive :foreground-sink-group (new 'static 'inline-array dma-foreground-sink-group 3 (new 'static 'dma-foreground-sink-group :sink (new 'static 'array dma-foreground-sink 3 (new 'static 'dma-foreground-sink :bucket 17 :foreground-texture-level 1 ) (new 'static 'generic-dma-foreground-sink :bucket 18 :foreground-texture-level 1 :foreground-output-bucket 1 ) ) ) (new 'static 'dma-foreground-sink-group :sink (new 'static 'array dma-foreground-sink 3 (new 'static 'dma-foreground-sink :bucket 52 :foreground-texture-page 1 :foreground-texture-level 1 ) (new 'static 'generic-dma-foreground-sink :bucket 53 :foreground-texture-page 1 :foreground-texture-level 1 :foreground-output-bucket 1 ) ) ) (new 'static 'dma-foreground-sink-group :sink (new 'static 'array dma-foreground-sink 3 (new 'static 'dma-foreground-sink :bucket 61 :foreground-texture-page 2 :foreground-texture-level 1 ) (new 'static 'generic-dma-foreground-sink :bucket 62 :foreground-texture-page 2 :foreground-texture-level 1 :foreground-output-bucket 1 ) ) ) ) :inside-sphere? #f :inside-boxes? #f :force-inside? #f ) :level-default (new 'static 'level :name 'default :index 2 :status 'reserved :foreground-sink-group (new 'static 'inline-array dma-foreground-sink-group 3 (new 'static 'dma-foreground-sink-group :sink (new 'static 'array dma-foreground-sink 3 (new 'static 'dma-foreground-sink :bucket 45 :foreground-texture-level 2 ) (new 'static 'generic-dma-foreground-sink :bucket 46 :foreground-texture-level 2 :foreground-output-bucket 1 ) ) ) (new 'static 'dma-foreground-sink-group :sink (new 'static 'array dma-foreground-sink 3 (new 'static 'dma-foreground-sink :bucket 55 :foreground-texture-page 1 :foreground-texture-level 2 ) (new 'static 'generic-dma-foreground-sink :bucket 56 :foreground-texture-page 1 :foreground-texture-level 2 :foreground-output-bucket 1 ) ) ) (new 'static 'dma-foreground-sink-group :sink (new 'static 'array dma-foreground-sink 3 (new 'static 'dma-foreground-sink :bucket 58 :foreground-texture-page 2 :foreground-texture-level 2 ) (new 'static 'generic-dma-foreground-sink :bucket 59 :foreground-texture-page 2 :foreground-texture-level 2 :foreground-output-bucket 1 ) ) ) ) :inside-sphere? #f :inside-boxes? #f :force-inside? #f ) ) ) ) (define-extern *level-load-list* pair)