honeylisp/game/entity.fnl
2020-11-23 23:41:00 -05:00

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}