From 19691a2d09be099c7719dfc84f18bc6c76453a72 Mon Sep 17 00:00:00 2001 From: Jeremy Penner Date: Sun, 3 Jan 2021 14:01:48 -0500 Subject: [PATCH] Load all levels into RAM at once, implement exit doors --- asm/asm.fnl | 7 +++++-- game/defs.fnl | 39 ++++++++++++++++++++++++++++----------- game/disk.fnl | 3 +-- game/entity.fnl | 22 ++++++++++++++++------ game/gfx.fnl | 4 ++-- game/init.fnl | 29 ++++++++++++++++++++--------- game/level1.fnl | 2 +- game/level2.fnl | 2 +- game/level3.fnl | 2 +- game/level4.fnl | 2 +- game/level5.fnl | 2 +- game/level6.fnl | 2 +- game/map.fnl | 2 +- game/map1.json | 2 +- game/map2.json | 2 +- game/map3.json | 2 +- game/map4.json | 2 +- game/map5.json | 2 +- game/player.fnl | 2 +- game/tiles.fnl | 15 ++------------- link/mame.fnl | 20 +++++++++++--------- todo.txt | 2 +- 22 files changed, 99 insertions(+), 68 deletions(-) diff --git a/asm/asm.fnl b/asm/asm.fnl index 39949d3..ea4cd5d 100644 --- a/asm/asm.fnl +++ b/asm/asm.fnl @@ -151,7 +151,7 @@ (fn dat-parser.export [label block] (tset block.globals (. label 2) true) nil) - (fn dat-parser.pad [pad] {:type :pad :align (. pad 2)}) + (fn dat-parser.align [pad] {:type :pad :align (. pad 2)}) (local pdat-processor { :op {} @@ -178,7 +178,10 @@ (fn pdat-processor.op.size [op] (size op.mode)) (fn pdat-processor.var.size [d] d.size) (fn pdat-processor.ref.size [r] 2) - (fn pdat-processor.pad.size [pad] (- pad.align (% pad.addr pad.align))) + (fn pdat-processor.pad.size [pad] + (let [misalignment (% pad.addr pad.align)] + (if (= misalignment 0) 0 + (- pad.align misalignment)))) (fn pdat-processor.op.bytes [op env] (local bytegen (. opcodes op.opcode)) diff --git a/game/defs.fnl b/game/defs.fnl index 5e862a6..f7f6f8b 100644 --- a/game/defs.fnl +++ b/game/defs.fnl @@ -19,9 +19,7 @@ (local org { :tiles (prg:org 0x4000) :font (prg:org 0x4f00) - :map (prg:org 0x5100) - :entity (prg:org 0x5200) - :levelcode (prg:org 0x5300) + :level (prg:org 0x5100) :code vm.code }) @@ -95,16 +93,35 @@ [:sta vm.TOPH :x] [:sta :0xc010]]) -(fn deflevel [mapfile] - (local level prg) ; todo: (asm.new prg) - (local map-org (level:org org.map.org)) - (local entity-org (level:org org.entity.org)) +; 20x12 means full map is 240 bytes - we have an extra 16 bytes at the end for metadata +(fn append-map [map org label] + (org:append + [:align 0x100] label + [:bytes (map.map:fromhex)] + [:db (length map.objects)] + [:dw (tiles.encode-yx map.jaye)] + [:dw (tiles.encode-yx map.neut)] + [:dw (if map.gord-following (tiles.encode-yx map.jaye) 0xffff)] + [:jmp (if (= (or map.tickword "") "") :next map.tickword)] + [:jmp (if (= (or map.moveword "") "") :move-noop map.moveword)])) + +(vm.code:append :map-ptr [:db 0] :map-page [:db 0]) +(vm:word :map :lit :map-ptr :get) +(vm:word :entity-count :map 240 :+ :bget) +(vm:word :map-jaye-yx :map 241 :+ :get) +(vm:word :map-neut-yx :map 243 :+ :get) +(vm:word :map-gord-yx :map 245 :+ :get) +(vm:word :map-specific-tick :map 247 :+ :execute) +(vm:word :map-specific-move :map 250 :+ :execute) + +(fn deflevel [mapfile label] + (local level prg) ; todo: (asm.new prg) - if we want to load levels as an overlay + (local org (level:org org.level.org)) (local map (readjson mapfile)) - (local tile (require :game.tiles)) (local entity (require :game.entity)) - (tile.append-map map map-org) - (entity.append-from-map map entity-org) - (set level.vm.code (level:org org.levelcode.org)) + (append-map map org label) + (entity.append-from-map map org label) + (set level.vm.code org) level) (fn say-runon [portrait ...] diff --git a/game/disk.fnl b/game/disk.fnl index 5013964..6f18b04 100644 --- a/game/disk.fnl +++ b/game/disk.fnl @@ -15,6 +15,5 @@ (disk:validate-entries) (disk:add-file "STARTUP" Prodos.file-type.BAS 0x801 org.block.bytes) (disk:update-volume-header {:name "NEUT.TOWER"}) -; (pp disk) -(disk:write "Test.dsk") +(disk:write "NeutTower.dsk") diff --git a/game/entity.fnl b/game/entity.fnl index 9d8a8ea..53b8c96 100644 --- a/game/entity.fnl +++ b/game/entity.fnl @@ -25,12 +25,11 @@ :noop 6 }) -(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 org.entity.org)] + [:lda :map-page] [:clc] [:adc 1] [:sta vm.TOPH :x]) (vm:word :entity-at ; yx -- entity|0 :>r 0 :entity-count @@ -82,11 +81,20 @@ :linked-entity :swap :entity>do ] [:drop])) -(vm:word :door ; ev -- +(vm:word :walking-through-door (vm:if-and [[:is-walking?] [:dup ev.touch :=] [:responder-itile (itile :dooropen) :=]] + [vm.true] [vm.false])) + +(vm:word :door ; ev -- + :walking-through-door (vm:if [:move-to-responder :drop] [(itile :doorclosed) (itile :dooropen) :handle-onoff])) +(vm:word :exitdoor ; ev -- + :walking-through-door (vm:if + [:move-to-responder :drop :get-responder 4 :+ :get :next-level :set] + [:door])) + (vm:word :move-to-responder :get-responder :get :move-player-to) (vm:word :switch ; ev -- (vm:if-and [[:is-rexx? :not] [:dup ev.touch :=]] @@ -166,15 +174,17 @@ [(vm:if-and [[:is-neut?] [:libb-present :get] [:libb-yx :get 0xffff :=]] [:neut-yx :get ev.hack :entity-at>do :drop])])) -(fn append-from-map [map entity-org] - (each [_ entity (ipairs map.objects)] +(fn append-from-map [map entity-org prefix] + (entity-org:append [:align 0x100]) + (each [ientity entity (ipairs map.objects)] (when entity.name (entity-org:append entity.name)) (entity-org:append + (.. prefix "-entity-" ientity) [:db (- entity.x 1)] [:db (- entity.y 1)] [:ref entity.func] (if (and entity.linkword (> (length entity.linkword) 0)) [:ref entity.linkword] [:dw 0]) - (if entity.link [:dw (+ entity-org.org (* (- entity.link 1) 8))] [:dw 0])))) + (if entity.link [:ref (.. prefix "-entity-" entity.link)] [:dw 0])))) {: ev : append-from-map} diff --git a/game/gfx.fnl b/game/gfx.fnl index 3af7556..df3e431 100644 --- a/game/gfx.fnl +++ b/game/gfx.fnl @@ -116,13 +116,13 @@ :inc :swap :inc :inc :swap) :swap :drop) (vm:word :drawmap - :lit :map 0x0c00 (vm:until 0x100 :- + :map 0x0c00 (vm:until 0x100 :- :dup :yx>screen ; pmap yx pscreen :screen : (manager:machine) (. :devices ::maincpu :spaces :program))] - (print :writing (bytes:len) :to addr) - (for [i 1 (bytes:len)] - (mem:write_u8 (+ addr i -1) (string.byte (bytes:sub i i)))))" - (bencode.encode {: addr : bytes}))) + (if (> (bytes:len) 0x1000) + (do (self:write addr (bytes:sub 1 0x1000)) + (self:write (+ addr 0x1000) (bytes:sub 0x1001))) + (self:eval-input + "(let [bencode (require :bencode) + {: addr : bytes} (bencode.decode (io.read)) + mem (-> (manager:machine) (. :devices ::maincpu :spaces :program))] + (print :writing (bytes:len) :to addr) + (for [i 1 (bytes:len)] + (mem:write_u8 (+ addr i -1) (string.byte (bytes:sub i i)))))" + (bencode.encode {: addr : bytes})))) (fn Machine.launch [self prg] (self:eval "(: (manager:machine) :soft_reset)") (self:eval (string.format "(emu.keypost \"CALL-151\\n %xG\\n\")" (prg:lookup-addr prg.start-symbol)))) diff --git a/todo.txt b/todo.txt index 20bae15..1f8e778 100644 --- a/todo.txt +++ b/todo.txt @@ -36,7 +36,7 @@ $0c00-$1fff 3kb-8kb - free space $2000-$4000 8kb-16kb - hgr gfx page 1 Game: -* level loading +* fix hot reload :O * Title screen * Ending screen