56 lines
1.7 KiB
Fennel
56 lines
1.7 KiB
Fennel
(local {: lo : hi} (require :lib.util))
|
|
|
|
; Entity memory layout:
|
|
; +0 - yx
|
|
; +2 - event handler
|
|
; +4 - link word
|
|
; +6 - link data
|
|
|
|
; All entities exist in a single page in RAM - with this structure we can have up to 32
|
|
; (players are handled specially and never require a link)
|
|
; if we really need more we could have one page for entities and one page for link data
|
|
; hellmaze level 2 from MS-DOS Neut Tower has 36 entities - good excuse to simplify IMO
|
|
; The entity count for a level is stored after the map.
|
|
|
|
(local ev {
|
|
:touch 0
|
|
:act 1
|
|
:deact 2
|
|
:tog 3
|
|
})
|
|
(fn install [vm entity-org]
|
|
(vm:word :entity-count :lit :map-entity-count :bget)
|
|
(vm:def :lookup-entity ; i -- entity
|
|
[:lda vm.TOP :x]
|
|
[:asl :a] [:asl :a] [:asl :a] ; x8
|
|
[:sta vm.TOP :x]
|
|
[:lda #(hi entity-org.org)]
|
|
[:sta vm.TOPH :x])
|
|
(vm:word :entity-at ; yx -- entity|0
|
|
:>r 0 :entity-count
|
|
(vm:while [:dup] :dec ; entity|0 i
|
|
:dup :lookup-entity :get :rtop :=
|
|
(vm:when :lookup-entity :swap)
|
|
) :drop :rdrop)
|
|
(vm.code:append :responder [:dw 0])
|
|
(vm:word :entity>do ; entity ev --
|
|
:over :lit :responder :dup :get :>r :set
|
|
:swap 2 :+ :get :execute
|
|
:r> :lit :responder :set)
|
|
|
|
(vm:word :touch-entity ; yx -- f
|
|
:entity-at :dup (vm:when ev.touch :entity>do 1)))
|
|
|
|
(fn append-from-map [map entity-org]
|
|
(each [_ entity (ipairs map.objects)]
|
|
(when entity.name
|
|
(entity-org:append entity.name))
|
|
(entity-org:append
|
|
[:db (- entity.x 1)] [:db (- entity.y 1)]
|
|
[:ref entity.func]
|
|
[:ref (if (and entity.linkword (> (length entity.linkword) 0)) entity.linkword :lit)]
|
|
(if entity.link [:dw (+ entity-org.org (* entity.link 8))] [:dw 0]))))
|
|
|
|
{: ev : install : append-from-map}
|
|
|