Load all levels into RAM at once, implement exit doors

This commit is contained in:
Jeremy Penner 2021-01-03 14:01:48 -05:00
parent ba08d57df5
commit 19691a2d09
22 changed files with 99 additions and 68 deletions

View file

@ -151,7 +151,7 @@
(fn dat-parser.export [label block] (fn dat-parser.export [label block]
(tset block.globals (. label 2) true) (tset block.globals (. label 2) true)
nil) nil)
(fn dat-parser.pad [pad] {:type :pad :align (. pad 2)}) (fn dat-parser.align [pad] {:type :pad :align (. pad 2)})
(local pdat-processor { (local pdat-processor {
:op {} :op {}
@ -178,7 +178,10 @@
(fn pdat-processor.op.size [op] (size op.mode)) (fn pdat-processor.op.size [op] (size op.mode))
(fn pdat-processor.var.size [d] d.size) (fn pdat-processor.var.size [d] d.size)
(fn pdat-processor.ref.size [r] 2) (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] (fn pdat-processor.op.bytes [op env]
(local bytegen (. opcodes op.opcode)) (local bytegen (. opcodes op.opcode))

View file

@ -19,9 +19,7 @@
(local org { (local org {
:tiles (prg:org 0x4000) :tiles (prg:org 0x4000)
:font (prg:org 0x4f00) :font (prg:org 0x4f00)
:map (prg:org 0x5100) :level (prg:org 0x5100)
:entity (prg:org 0x5200)
:levelcode (prg:org 0x5300)
:code vm.code :code vm.code
}) })
@ -95,16 +93,35 @@
[:sta vm.TOPH :x] [:sta vm.TOPH :x]
[:sta :0xc010]]) [:sta :0xc010]])
(fn deflevel [mapfile] ; 20x12 means full map is 240 bytes - we have an extra 16 bytes at the end for metadata
(local level prg) ; todo: (asm.new prg) (fn append-map [map org label]
(local map-org (level:org org.map.org)) (org:append
(local entity-org (level:org org.entity.org)) [: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 map (readjson mapfile))
(local tile (require :game.tiles))
(local entity (require :game.entity)) (local entity (require :game.entity))
(tile.append-map map map-org) (append-map map org label)
(entity.append-from-map map entity-org) (entity.append-from-map map org label)
(set level.vm.code (level:org org.levelcode.org)) (set level.vm.code org)
level) level)
(fn say-runon [portrait ...] (fn say-runon [portrait ...]

View file

@ -15,6 +15,5 @@
(disk:validate-entries) (disk:validate-entries)
(disk:add-file "STARTUP" Prodos.file-type.BAS 0x801 org.block.bytes) (disk:add-file "STARTUP" Prodos.file-type.BAS 0x801 org.block.bytes)
(disk:update-volume-header {:name "NEUT.TOWER"}) (disk:update-volume-header {:name "NEUT.TOWER"})
; (pp disk) (disk:write "NeutTower.dsk")
(disk:write "Test.dsk")

View file

@ -25,12 +25,11 @@
:noop 6 :noop 6
}) })
(vm:word :entity-count :lit :map-entity-count :bget)
(vm:def :lookup-entity ; i -- entity (vm:def :lookup-entity ; i -- entity
[:lda vm.TOP :x] [:lda vm.TOP :x]
[:asl :a] [:asl :a] [:asl :a] ; x8 [:asl :a] [:asl :a] [:asl :a] ; x8
[:sta vm.TOP :x] [:sta vm.TOP :x]
[:lda #(hi org.entity.org)] [:lda :map-page] [:clc] [:adc 1]
[:sta vm.TOPH :x]) [:sta vm.TOPH :x])
(vm:word :entity-at ; yx -- entity|0 (vm:word :entity-at ; yx -- entity|0
:>r 0 :entity-count :>r 0 :entity-count
@ -82,11 +81,20 @@
:linked-entity :swap :entity>do :linked-entity :swap :entity>do
] [:drop])) ] [:drop]))
(vm:word :door ; ev -- (vm:word :walking-through-door
(vm:if-and [[:is-walking?] [:dup ev.touch :=] [:responder-itile (itile :dooropen) :=]] (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] [:move-to-responder :drop]
[(itile :doorclosed) (itile :dooropen) :handle-onoff])) [(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 :move-to-responder :get-responder :get :move-player-to)
(vm:word :switch ; ev -- (vm:word :switch ; ev --
(vm:if-and [[:is-rexx? :not] [:dup ev.touch :=]] (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 :=]] [(vm:if-and [[:is-neut?] [:libb-present :get] [:libb-yx :get 0xffff :=]]
[:neut-yx :get ev.hack :entity-at>do :drop])])) [:neut-yx :get ev.hack :entity-at>do :drop])]))
(fn append-from-map [map entity-org] (fn append-from-map [map entity-org prefix]
(each [_ entity (ipairs map.objects)] (entity-org:append [:align 0x100])
(each [ientity entity (ipairs map.objects)]
(when entity.name (when entity.name
(entity-org:append entity.name)) (entity-org:append entity.name))
(entity-org:append (entity-org:append
(.. prefix "-entity-" ientity)
[:db (- entity.x 1)] [:db (- entity.y 1)] [:db (- entity.x 1)] [:db (- entity.y 1)]
[:ref entity.func] [:ref entity.func]
(if (and entity.linkword (> (length entity.linkword) 0)) [:ref entity.linkword] [:dw 0]) (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} {: ev : append-from-map}

View file

@ -116,13 +116,13 @@
:inc :swap :inc :inc :swap) :swap :drop) :inc :swap :inc :inc :swap) :swap :drop)
(vm:word :drawmap (vm:word :drawmap
:lit :map 0x0c00 (vm:until 0x100 :- :map 0x0c00 (vm:until 0x100 :-
:dup :yx>screen ; pmap yx pscreen :dup :yx>screen ; pmap yx pscreen
:<rot :drawmaprow :swap ; pmap yx :<rot :drawmaprow :swap ; pmap yx
:dup :not) :drop :drop) :dup :not) :drop :drop)
(vm:word :clearfooter (vm:word :clearfooter
:lit :map 0x0300 (vm:until 0x100 :- :map 0x0300 (vm:until 0x100 :-
:dup 0x0900 :+ :yx>screen :dup 0x0900 :+ :yx>screen
:<rot :drawmaprow :swap :<rot :drawmaprow :swap
:dup :not) :drop :drop :player-redraw) :dup :not) :drop :drop :player-redraw)

View file

@ -8,19 +8,32 @@
(util.reload :game.map) (util.reload :game.map)
(util.reload :game.entity) (util.reload :game.entity)
(util.reload :game.player) (util.reload :game.player)
(util.reload :game.bosskey)
(tile.appendtiles org.tiles) (tile.appendtiles org.tiles)
(tile.appendgfx org.font (tile.loadgfx tile.fn-font)) (tile.appendgfx org.font (tile.loadgfx tile.fn-font))
(util.reload :game.level1)
(util.reload :game.level2)
(util.reload :game.level3)
(util.reload :game.level4)
(util.reload :game.level5)
(util.reload :game.level6)
(util.reload :game.bosskey)
(vm:var :tick-count) (vm:var :tick-count)
(vm:word :handle-key :tick :read-key :player-key :hide-footer) (vm:word :handle-key :tick :read-key :player-key :hide-footer)
(vm:word :tick :map-specific-tick :tick-count :get 1 :+ :tick-count :set :player-redraw) (vm:word :tick :map-specific-tick :tick-count :get 1 :+ :tick-count :set :player-redraw)
(vm:word :load-level (vm:var :next-level 0)
:lit :map-jaye-yx :get :jaye-yx :set (vm:word :load-next-level :next-level :get :dup (vm:if [:load-level 0 :next-level :set] [:drop]))
:lit :map-neut-yx :get :neut-yx :set (vm:word :load-level ; level-ptr --
:lit :map-gord-yx :get :gord-yx :set :lit :map-ptr :set :reload-level)
(vm:word :reload-level
:map-jaye-yx :jaye-yx :set
:map-neut-yx :neut-yx :set
:map-gord-yx :gord-yx :set
0 :gord-dir :set 0 :gord-dir :set
0xffff :rexx-yx :set 0xffff :rexx-yx :set
:full-redraw) :full-redraw)
@ -29,15 +42,13 @@
[:jsr :reset] [:jsr :reset]
[:jsr :interpret] [:jsr :interpret]
[:vm :hires [:vm :hires
:load-level :lit :level1 :load-level
(vm:forever (vm:forever
(vm:hotswap-sync :load-level) (vm:hotswap-sync :reload-level)
:interactive-eval-checkpoint :interactive-eval-checkpoint
:handle-key :handle-key
) )
:quit]) :quit])
(util.reload :game.level6)
(prg:assemble) (prg:assemble)

View file

@ -1,6 +1,6 @@
(local {: deflevel : say : itile : controlstate} (require :game.defs)) (local {: deflevel : say : itile : controlstate} (require :game.defs))
(local {: ev} (require :game.entity)) (local {: ev} (require :game.entity))
(local level (deflevel "game/map1.json")) (local level (deflevel "game/map1.json" :level1))
(local vm level.vm) (local vm level.vm)
(vm:word :firstdoor (vm:word :firstdoor

View file

@ -1,6 +1,6 @@
(local {: deflevel : say : itile} (require :game.defs)) (local {: deflevel : say : itile} (require :game.defs))
(local {: ev} (require :game.entity)) (local {: ev} (require :game.entity))
(local level (deflevel "game/map2.json")) (local level (deflevel "game/map2.json" :level2))
(local vm level.vm) (local vm level.vm)
level level

View file

@ -1,6 +1,6 @@
(local {: deflevel : say : itile : controlstate} (require :game.defs)) (local {: deflevel : say : itile : controlstate} (require :game.defs))
(local {: ev} (require :game.entity)) (local {: ev} (require :game.entity))
(local level (deflevel "game/map3.json")) (local level (deflevel "game/map3.json" :level3))
(local tile (require :game.tiles)) (local tile (require :game.tiles))
(local {: walkable : neutable : debris} tile.flag-to-bit) (local {: walkable : neutable : debris} tile.flag-to-bit)

View file

@ -1,6 +1,6 @@
(local {: deflevel : say : itile} (require :game.defs)) (local {: deflevel : say : itile} (require :game.defs))
(local {: ev} (require :game.entity)) (local {: ev} (require :game.entity))
(local level (deflevel "game/map4.json")) (local level (deflevel "game/map4.json" :level4))
(local vm level.vm) (local vm level.vm)
(vm:word :term-dual-link (vm:word :term-dual-link

View file

@ -2,7 +2,7 @@
(local {: ev} (require :game.entity)) (local {: ev} (require :game.entity))
(local tile (require :game.tiles)) (local tile (require :game.tiles))
(local {: walkable : neutable : debris : sittable} tile.flag-to-bit) (local {: walkable : neutable : debris : sittable} tile.flag-to-bit)
(local level (deflevel "game/map5.json")) (local level (deflevel "game/map5.json" :level5))
(local vm level.vm) (local vm level.vm)
(vm:word :randomgarbage (itile :broken-table)) (vm:word :randomgarbage (itile :broken-table))

View file

@ -2,7 +2,7 @@
(local {: ev} (require :game.entity)) (local {: ev} (require :game.entity))
(local tile (require :game.tiles)) (local tile (require :game.tiles))
(local {: walkable : neutable : debris : sittable} tile.flag-to-bit) (local {: walkable : neutable : debris : sittable} tile.flag-to-bit)
(local level (deflevel "game/map6.json")) (local level (deflevel "game/map6.json" :level6))
(local vm level.vm) (local vm level.vm)
(vm:word :linkloop ; e -- e (vm:word :linkloop ; e -- e

View file

@ -24,7 +24,7 @@
[:clc] [:adc vm.TOPH :x] ; x20 [:clc] [:adc vm.TOPH :x] ; x20
[:adc vm.TOP :x] [:adc vm.TOP :x]
[:sta vm.TOP :x] [:sta vm.TOP :x]
[:lda #(hi ($1:lookup-addr :map))] [:lda :map-page]
[:sta vm.TOPH :x]) [:sta vm.TOPH :x])
(vm:word :itile-at ; yx -- itile (vm:word :itile-at ; yx -- itile
:map-at :bget) :map-at :bget)

View file

@ -1 +1 @@
{"jaye":{"y":9,"x":15},"objects":[{"x":8,"func":"door","y":6,"name":"","linkword":""},{"link":3,"x":2,"y":4,"linkword":"","name":"","func":"firstterm"},{"link":2,"x":17,"y":8,"linkword":"","name":"","func":"neutterm"},{"link":8,"x":13,"y":8,"linkword":"","name":"","func":"switch"},{"link":6,"y":1,"func":"exitscanner","name":"","linkword":"","x":9},{"x":10,"func":"door","name":"","linkword":"","y":1},{"link":1,"y":6,"func":"switch","name":"","linkword":"","x":6},{"x":13,"func":"firstdoor","y":10,"linkword":"","name":""}],"map":"212121214121212121212121212141212121212161026161610261616102616161616102616161216143C0C0E2C0C0C0C0C0C0C081C0C0C0C0C0612161C0C0A282C0C0C0A2C0C0C061C0C0C0C0C2024161C0C0C0C0C0C0C0C0C2C0A2C1A2C0C0E082612161E2C08282C0C0C0C0A2C0C061616161616161216161616161C16181616161616143C0C0E282612161C0C0C0C0C0C0C0C0C0C0C061C0C0C0C0C0022161E08282A2C0C0C0C0E2C0C081C0C0C0C003612161E2C2C2C0C0C0C0C0C0C0C061C0C0C0C0C06141610303C063E2C0C0C0C0C0C061C0C0C023C061216161616161616161228161616161616161610221"} {"map":"212121214121212121212121212141212121212161026161610261616102616161616102616161216143C0C0E2C0C0C0C0C0C0C081C0C0C0C0C0612161C0C0A282C0C0C0A2C0C0C061C0C0C0C0C2024161C0C0C0C0C0C0C0C0C2C0A2C1A2C0C0E082612161E2C08282C0C0C0C0A2C0C061616161616161216161616161C16181616161616143C0C0E282612161C0C0C0C0C0C0C0C0C0C0C061C0C0C0C0C0022161E08282A2C0C0C0C0E2C0C081C0C0C0C003612161E2C2C2C0C0C0C0C0C0C0C061C0C0C0C0C06141610303C063E2C0C0C0C0C0C061C0C0C023C061216161616161616161228161616161616161610221","jaye":{"y":9,"x":15},"tickword":"","moveword":"","objects":[{"x":8,"func":"door","linkword":"","name":"","y":6},{"x":2,"func":"firstterm","y":4,"name":"","linkword":"","link":3},{"x":17,"func":"neutterm","y":8,"name":"","linkword":"","link":2},{"x":13,"func":"switch","y":8,"name":"","linkword":"","link":8},{"link":6,"x":9,"y":1,"linkword":"","name":"","func":"exitscanner"},{"x":10,"func":"exitdoor","y":1,"name":"","linkword":"level2"},{"link":1,"x":6,"y":6,"linkword":"","name":"","func":"switch"},{"x":13,"func":"firstdoor","name":"","linkword":"","y":10}]}

View file

@ -1 +1 @@
{"jaye":{"y":11,"x":11},"objects":[{"link":2,"y":11,"func":"term","name":"","linkword":"","x":9},{"link":6,"y":3,"func":"term","name":"","linkword":"","x":2},{"x":6,"func":"door","y":10,"linkword":"","name":""},{"link":5,"y":5,"func":"scan","name":"","linkword":"","x":1},{"x":8,"func":"door","y":8,"linkword":"","name":""},{"link":2,"y":6,"func":"term","name":"","linkword":"","x":7},{"link":8,"y":1,"func":"scan","name":"","linkword":"","x":12},{"x":17,"func":"door","y":7,"linkword":"","name":""},{"link":10,"y":1,"func":"scan","name":"","linkword":"","x":13},{"x":13,"func":"door","y":8,"linkword":"","name":""},{"link":12,"y":6,"func":"switch","name":"","linkword":"","x":15},{"link":13,"y":10,"func":"term","name":"","linkword":"","x":2},{"link":12,"y":5,"func":"term","name":"","linkword":"","x":12},{"link":15,"y":9,"func":"scan","name":"","linkword":"","x":15},{"x":15,"func":"door","y":10,"linkword":"","name":""},{"link":17,"y":6,"func":"term","name":"","linkword":"","x":16},{"link":16,"y":10,"func":"term","name":"","linkword":"","x":18},{"x":15,"func":"door","y":3,"linkword":"","name":""},{"link":18,"y":9,"func":"scan","name":"","linkword":"","x":19},{"link":21,"y":3,"func":"term","name":"","linkword":"","x":13},{"link":20,"y":2,"func":"term","name":"","linkword":"","x":18},{"link":23,"y":1,"func":"scan","name":"","linkword":"","x":8},{"x":9,"func":"door","y":1,"linkword":"","name":""},{"link":3,"y":1,"func":"switch","name":"","linkword":"","x":16},{"link":26,"y":1,"func":"switch","name":"","linkword":"","x":3},{"x":6,"func":"door","y":3,"linkword":"","name":""},{"link":28,"y":3,"func":"term","name":"","linkword":"","x":9},{"link":27,"y":2,"func":"term","name":"","linkword":"","x":7},{"x":3,"func":"door","y":7,"linkword":"","name":""},{"link":29,"y":1,"func":"switch","name":"","linkword":"","x":17}],"neut":{"y":12,"x":10},"map":"616161616161626161618161616161616161612161C0C0C06361C0C0E0C0C0C0C0C06103C0C0022161E0C0C0C081C0C0C0C0C0C0C0C081C0C0E0614161C0C0C0C06143C0C0C0C0C0C04322C0C0C0222161C0C0C0C061618161616161816161C0C0C00221616181616161C0C0C06143C0C0C061618161612161C0C0C06361E0C0C061C0C0C0C0C1E0C003612122C0C0C0C061C0C0C061C0E0C0C061C0C0C0022161C0C0C0C061616161616261616161C0C0C061416101C0C0C081C0C0E061C0C0E0C081C0C0C0022162C0C0C02361E0C0C06143C0C0C061E2A2E061216161C1616261612281616122226162C1C1616121"} {"neut":{"y":12,"x":10},"map":"616161616161626161618161616161616161612161C0C0C06361C0C0E0C0C0C0C0C06103C0C0022161E0C0C0C081C0C0C0C0C0C0C0C081C0C0E0614161C0C0C0C06143C0C0C0C0C0C04322C0C0C0222161C0C0C0C061618161616161816161C0C0C00221616181616161C0C0C06143C0C0C061618161612161C0C0C06361E0C0C061C0C0C0C0C1E0C003612122C0C0C0C061C0C0C061C0E0C0C061C0C0C0022161C0C0C0C061616161616261616161C0C0C061416101C0C0C081C0C0E061C0C0E0C081C0C0C0022162C0C0C02361E0C0C06143C0C0C061E2A2E061216161C1616261612281616122226162C1C1616121","jaye":{"y":11,"x":11},"tickword":"","moveword":"","objects":[{"link":2,"x":9,"y":11,"linkword":"","name":"","func":"term"},{"link":6,"x":2,"y":3,"linkword":"","name":"","func":"term"},{"x":6,"func":"door","name":"","linkword":"","y":10},{"link":5,"x":1,"y":5,"linkword":"","name":"","func":"scan"},{"x":8,"func":"door","name":"","linkword":"","y":8},{"link":2,"x":7,"y":6,"linkword":"","name":"","func":"term"},{"link":8,"x":12,"y":1,"linkword":"","name":"","func":"scan"},{"x":17,"func":"door","name":"","linkword":"","y":7},{"link":10,"x":13,"y":1,"linkword":"","name":"","func":"scan"},{"x":13,"func":"door","name":"","linkword":"","y":8},{"link":12,"x":15,"y":6,"linkword":"","name":"","func":"switch"},{"link":13,"x":2,"y":10,"linkword":"","name":"","func":"term"},{"link":12,"x":12,"y":5,"linkword":"","name":"","func":"term"},{"link":15,"x":15,"y":9,"linkword":"","name":"","func":"scan"},{"x":15,"func":"door","name":"","linkword":"","y":10},{"link":17,"x":16,"y":6,"linkword":"","name":"","func":"term"},{"link":16,"x":18,"y":10,"linkword":"","name":"","func":"term"},{"x":15,"func":"door","name":"","linkword":"","y":3},{"link":18,"x":19,"y":9,"linkword":"","name":"","func":"scan"},{"link":21,"x":13,"y":3,"linkword":"","name":"","func":"term"},{"link":20,"x":18,"y":2,"linkword":"","name":"","func":"term"},{"link":23,"x":8,"y":1,"linkword":"","name":"","func":"scan"},{"x":9,"func":"exitdoor","name":"","linkword":"level3","y":1},{"link":3,"x":16,"y":1,"linkword":"","name":"","func":"switch"},{"link":26,"x":3,"y":1,"linkword":"","name":"","func":"switch"},{"x":6,"func":"door","name":"","linkword":"","y":3},{"link":28,"x":9,"y":3,"linkword":"","name":"","func":"term"},{"link":27,"x":7,"y":2,"linkword":"","name":"","func":"term"},{"x":3,"func":"door","name":"","linkword":"","y":7},{"link":29,"x":17,"y":1,"linkword":"","name":"","func":"switch"}]}

View file

@ -1 +1 @@
{"jaye":{"y":11,"x":9},"objects":[{"x":1,"func":"scan","y":5,"name":"","linkword":"","link":2},{"x":1,"func":"door","y":4,"name":"","linkword":""},{"x":7,"func":"gordterm","y":6,"name":"","linkword":"","link":4},{"x":14,"func":"term","y":11,"name":"","linkword":"","link":7},{"x":9,"func":"switch","y":6,"name":"gordswitch","linkword":"","link":6},{"x":11,"func":"door","y":9,"name":"","linkword":""},{"x":10,"func":"term","y":3,"name":"","linkword":"","link":3},{"x":11,"func":"scan","y":10,"name":"","linkword":"","link":9},{"x":14,"func":"door","y":7,"name":"","linkword":""},{"x":7,"func":"meetrexx","linkword":"","name":"","y":3},{"x":8,"func":"meetgord","linkword":"","name":"","y":6}],"neut":{"y":12,"x":8},"map":"616161616161616181616161616161616161612161C063C0C0C0C0C0C0C06143C0E0C2C0C043022161C0C0C0C0C0C0C0C0C022C0C0C0C0C0C0C0612161C0C0C2C0C0C0C0C0C081C0C0C0C0C0C0C0612161C08282A2C0C0C0C0436123C0C0C0C0C0030221616161616161616261616161618161616161612161C063C0C02301C3C163C0C0C0C0C0822363022122C0C0C0C0C0C0A2A1C0C0C0C0C0C0C2C0C0612181C0C0C0C0E2C0C061C0C0C0C0C0C0C0C2C061216123C0C0C0C083C061E0C2C0C0C0C0438203022161610261610261616161026161026161026161212121212121212121212121212121212121212121"} {"neut":{"y":12,"x":8},"map":"616161616161616181616161616161616161612161C063C0C0C0C0C0C0C06143C0E0C2C0C043022161C0C0C0C0C0C0C0C0C022C0C0C0C0C0C0C0612161C0C0C2C0C0C0C0C0C081C0C0C0C0C0C0C0612161C08282A2C0C0C0C0436123C0C0C0C0C0030221616161616161616261616161618161616161612161C063C0C02301C3C163C0C0C0C0C0822363022122C0C0C0C0C0C0A2A1C0C0C0C0C0C0C2C0C0612181C0C0C0C0E2C0C061C0C0C0C0C0C0C0C2C061216123C0C0C0C083C061E0C2C0C0C0C0438203022161610261610261616161026161026161026161212121212121212121212121212121212121212121","jaye":{"y":11,"x":9},"tickword":"","moveword":"","objects":[{"x":1,"link":2,"func":"scan","linkword":"","name":"","y":5},{"x":1,"func":"exitdoor","linkword":"level4","name":"","y":4},{"x":7,"link":4,"func":"gordterm","linkword":"","name":"","y":6},{"x":14,"link":7,"func":"term","linkword":"","name":"","y":11},{"x":9,"link":6,"func":"switch","linkword":"","name":"gordswitch","y":6},{"x":11,"func":"door","linkword":"","name":"","y":9},{"x":10,"link":3,"func":"term","linkword":"","name":"","y":3},{"x":11,"link":9,"func":"scan","linkword":"","name":"","y":10},{"x":14,"func":"door","linkword":"","name":"","y":7},{"x":7,"func":"meetrexx","y":3,"linkword":"","name":""},{"x":8,"func":"meetgord","y":6,"linkword":"","name":""}]}

View file

@ -1 +1 @@
{"neut":{"y":5,"x":20},"jaye":{"y":4,"x":19},"gord-following":true,"map":"61616161616161616261616161616161616161616143C0C0C082E082C0C0636163C0C083C0C0436161C0C0C0C0C0C2C0C0C0C0C1C0C0C0C0C0C0C06161C0C0C0C0C0C0C0C0C0C0C1C0C0C0C0C0C0C2616103C0C0A3C0C0C003C0C06163C0C0C0C082A261616161616161C1616161812261618161616161616143C0C0C0C0C0C04361C0C0C0C0C0C0C0C0636181C0C0C0C0C0C0C0C081C0C0C0C0C0C0C0C0C06122C0C0C0C0C0E2C0C0C1A2E2C0C0C0C0C0C0C08161E082828282E0C02361A2C0C0C0C0C0C003236161026161610222616102616161610261616102612121214121212121212121212121412121212121","objects":[{"x":7,"func":"term","y":11,"linkword":"term-dual-link","name":""},{"link":1,"y":3,"func":"term","name":"term-exit","linkword":"","x":2},{"link":1,"y":3,"func":"term","name":"term-scan","linkword":"","x":7},{"link":2,"y":10,"func":"switch","name":"","linkword":"","x":12},{"link":3,"y":9,"func":"switch","name":"","linkword":"","x":12},{"x":11,"func":"door","y":7,"linkword":"","name":""},{"link":6,"y":7,"func":"scan","name":"","linkword":"","x":12},{"x":15,"func":"door","y":7,"linkword":"","name":""},{"link":8,"y":7,"func":"switch","name":"","linkword":"","x":7},{"x":10,"func":"door","y":5,"linkword":"","name":""},{"link":6,"y":4,"func":"switch","name":"","linkword":"","x":10},{"x":16,"func":"rexx","y":11,"linkword":"","name":""},{"link":10,"y":2,"func":"scan","name":"","linkword":"","x":7},{"link":15,"y":4,"func":"scan","name":"","linkword":"","x":1},{"x":1,"func":"door","y":5,"linkword":"","name":""},{"x":5,"func":"rexx","y":8,"linkword":"","name":""},{"x":7,"func":"tutorial-chair","linkword":"","name":"","y":10}]} {"neut":{"y":5,"x":20},"map":"61616161616161616261616161616161616161616143C0C0C082E082C0C0636163C0C083C0C0436161C0C0C0C0C0C2C0C0C0C0C1C0C0C0C0C0C0C06161C0C0C0C0C0C0C0C0C0C0C1C0C0C0C0C0C0C2616103C0C0A3C0C0C003C0C06163C0C0C0C082A261616161616161C1616161812261618161616161616143C0C0C0C0C0C04361C0C0C0C0C0C0C0C0636181C0C0C0C0C0C0C0C081C0C0C0C0C0C0C0C0C06122C0C0C0C0C0E2C0C0C1A2E2C0C0C0C0C0C0C08161E082828282E0C02361A2C0C0C0C0C0C003236161026161610222616102616161610261616102612121214121212121212121212121412121212121","gord-following":true,"jaye":{"y":4,"x":19},"tickword":"","moveword":"","objects":[{"x":7,"func":"term","name":"","linkword":"term-dual-link","y":11},{"link":1,"x":2,"y":3,"linkword":"","name":"term-exit","func":"term"},{"link":1,"x":7,"y":3,"linkword":"","name":"term-scan","func":"term"},{"link":2,"x":12,"y":10,"linkword":"","name":"","func":"switch"},{"link":3,"x":12,"y":9,"linkword":"","name":"","func":"switch"},{"x":11,"func":"door","name":"","linkword":"","y":7},{"link":6,"x":12,"y":7,"linkword":"","name":"","func":"scan"},{"x":15,"func":"door","name":"","linkword":"","y":7},{"link":8,"x":7,"y":7,"linkword":"","name":"","func":"switch"},{"x":10,"func":"door","name":"","linkword":"","y":5},{"link":6,"x":10,"y":4,"linkword":"","name":"","func":"switch"},{"x":16,"func":"rexx","name":"","linkword":"","y":11},{"link":10,"x":7,"y":2,"linkword":"","name":"","func":"scan"},{"link":15,"x":1,"y":4,"linkword":"","name":"","func":"scan"},{"x":1,"func":"exitdoor","name":"","linkword":"level5","y":5},{"x":5,"func":"rexx","name":"","linkword":"","y":8},{"x":7,"func":"tutorial-chair","y":10,"linkword":"","name":""}]}

View file

@ -1 +1 @@
{"neut":{"y":6,"x":20},"map":"21616161228161616161616161616161616162612102E0C0C0C0C0E0C04361C0C0C0C0C0A3C0C0612161C0C0C0C0C0C0C0C022C0C0C08282C0828261416103C0C0C0C0C0C0C081C0C0C0C0C0C0C0C2C1210203C0C0C0C0C0C04361C0C0C08282838282622161616161816161616161618161616161616161216163C0C0C0C0E0C0C06143C0C0C0C0C0C063612102C0C0C0C0C0C0C0C061C0C0C0C0C0C0C0C0814161C0C0C0C0E2C0E2836101C0C0C0C0C0C0C0C1216143C0C0C082A2A2A281C0C0C043034382E26121610261610261C16102616161026161610261612121212121214121212121212121214121212121","tickword":"doortimer-tick","jaye":{"y":5,"x":19},"gord-following":true,"moveword":"move-garbagerexx","objects":[{"x":17,"func":"garbagerexx","y":11,"name":"south-rexx","linkword":""},{"x":17,"func":"garbagerexx","y":8,"name":"","linkword":""},{"x":20,"func":"do-timedswitch","y":9,"name":"timedswitch","linkword":"","link":13},{"x":20,"func":"switch","y":4,"name":"","linkword":"","link":16},{"x":12,"func":"term","y":4,"name":"","linkword":"","link":9},{"x":10,"func":"healthyrexx","y":4,"name":"","linkword":""},{"x":8,"func":"switch","y":2,"name":"","linkword":"","link":17},{"x":8,"func":"term","y":6,"name":"","linkword":"","link":10},{"x":8,"func":"term","y":11,"name":"","linkword":"","link":5},{"x":3,"func":"term","y":11,"name":"","linkword":"","link":8},{"x":5,"func":"scan","y":12,"name":"","linkword":"","link":12},{"x":6,"func":"door","y":12,"name":"","linkword":""},{"x":6,"func":"door","y":7,"name":"","linkword":""},{"x":11,"func":"explodingdoor","y":9,"name":"","linkword":""},{"x":11,"func":"scan","y":10,"name":"","linkword":"","link":14},{"x":13,"func":"door","y":7,"name":"","linkword":""},{"x":11,"func":"door","y":3,"name":"","linkword":""}]} {"neut":{"y":6,"x":20},"map":"21616161228161616161616161616161616162612102E0C0C0C0C0E0C04361C0C0C0C0C0A3C0C0612161C0C0C0C0C0C0C0C022C0C0C08282C0828261416103C0C0C0C0C0C0C081C0C0C0C0C0C0C0C2C1210203C0C0C0C0C0C04361C0C0C08282838282622161616161816161616161618161616161616161216163C0C0C0C0E0C0C06143C0C0C0C0C0C063612102C0C0C0C0C0C0C0C061C0C0C0C0C0C0C0C0814161C0C0C0C0E2C0E2836101C0C0C0C0C0C0C0C1216143C0C0C082A2A2A281C0C0C043034382E26121610261610261C16102616161026161610261612121212121214121212121212121214121212121","tickword":"doortimer-tick","jaye":{"y":5,"x":19},"gord-following":true,"moveword":"move-garbagerexx","objects":[{"x":17,"func":"garbagerexx","linkword":"","name":"south-rexx","y":11},{"x":17,"func":"garbagerexx","linkword":"","name":"","y":8},{"x":20,"link":13,"func":"do-timedswitch","linkword":"","name":"timedswitch","y":9},{"x":20,"link":16,"func":"switch","linkword":"","name":"","y":4},{"x":12,"link":9,"func":"term","linkword":"","name":"","y":4},{"x":10,"func":"healthyrexx","linkword":"","name":"","y":4},{"x":8,"link":17,"func":"switch","linkword":"","name":"","y":2},{"x":8,"link":10,"func":"term","linkword":"","name":"","y":6},{"x":8,"link":5,"func":"term","linkword":"","name":"","y":11},{"x":3,"link":8,"func":"term","linkword":"","name":"","y":11},{"x":5,"link":12,"func":"scan","linkword":"","name":"","y":12},{"x":6,"func":"exitdoor","linkword":"level6","name":"","y":12},{"x":6,"func":"door","linkword":"","name":"","y":7},{"x":11,"func":"explodingdoor","linkword":"","name":"","y":9},{"x":11,"link":14,"func":"scan","linkword":"","name":"","y":10},{"x":13,"func":"door","linkword":"","name":"","y":7},{"x":11,"func":"door","linkword":"","name":"","y":3}]}

View file

@ -161,7 +161,7 @@
[:movement-dir :dup] [:movement-dir :dup]
[:player-yx :get :swap ; oldyx dir [:player-yx :get :swap ; oldyx dir
:try-move-player :try-move-player
:dup :player-yx :get := (vm:if [:drop] [:party-follow :untouch-entity])] :dup :player-yx :get := (vm:if [:drop] [:party-follow :untouch-entity :load-next-level])]
[:drop])) [:drop]))
(vm:word :full-redraw :drawmap :player-redraw) (vm:word :full-redraw :drawmap :player-redraw)

View file

@ -39,7 +39,7 @@
(fn appendtiles [org] (fn appendtiles [org]
(local tiles (loadgfx fn-tiles)) (local tiles (loadgfx fn-tiles))
(appendgfx org tiles) (appendgfx org tiles)
(org:append [:pad 0x100] :neut-tileset) (org:append [:align 0x100] :neut-tileset)
(appendgfx org tiles :neut true) (appendgfx org tiles :neut true)
(appendgfx org (loadgfx fn-portraits)) (appendgfx org (loadgfx fn-portraits))
(org:append :tileflags) (org:append :tileflags)
@ -52,17 +52,6 @@
(fn encode-yx [xy] (fn encode-yx [xy]
(if xy (bit.bor (bit.lshift (- xy.y 1) 8) (- xy.x 1)) 0xffff)) (if xy (bit.bor (bit.lshift (- xy.y 1) 8) (- xy.x 1)) 0xffff))
; 20x12 means full map is 240 bytes - we have an extra 16 bytes at the end for metadata
(fn append-map [map org]
(org:append
:map [:bytes (map.map:fromhex)]
:map-entity-count [:db (length map.objects)]
:map-jaye-yx [:dw (encode-yx map.jaye)]
:map-neut-yx [:dw (encode-yx map.neut)]
:map-gord-yx [:dw (if map.gord-following (encode-yx map.jaye) 0xffff)]
:map-specific-tick [:jmp (if (= (or map.tickword "") "") :next map.tickword)]
:map-specific-move [:jmp (if (= (or map.moveword "") "") :move-noop map.moveword)]))
(fn find-itile [tiles label ?itilenext] (fn find-itile [tiles label ?itilenext]
(local itile (or ?itilenext 1)) (local itile (or ?itilenext 1))
(local tile (. tiles itile)) (local tile (. tiles itile))
@ -71,6 +60,6 @@
(bit.bor (bit.lshift (bit.band (- itile 1) 0x07) 5) (bit.rshift (bit.band (- itile 1) 0xf8) 3)) (bit.bor (bit.lshift (bit.band (- itile 1) 0x07) 5) (bit.rshift (bit.band (- itile 1) 0xf8) 3))
(find-itile tiles label (+ itile 1)))) (find-itile tiles label (+ itile 1))))
{: loadgfx : savegfx : appendtiles : appendgfx : append-map : flags : flag-to-bit : find-itile {: loadgfx : savegfx : appendtiles : appendgfx : flags : flag-to-bit : find-itile
: fn-tiles : fn-portraits : fn-font : encode-yx} : fn-tiles : fn-portraits : fn-font : encode-yx}

View file

@ -86,16 +86,18 @@
(when self.monitor (self.monitor:shutdown-session)) (when self.monitor (self.monitor:shutdown-session))
(when (nrepl:connected?) (nrepl:disconnect)) (when (nrepl:connected?) (nrepl:disconnect))
(set self.breakpoints {})) (set self.breakpoints {}))
(fn Machine.write [self addr bytes] (fn Machine.write [self addr bytes]
(self:eval-input (if (> (bytes:len) 0x1000)
"(let [bencode (require :bencode) (do (self:write addr (bytes:sub 1 0x1000))
{: addr : bytes} (bencode.decode (io.read)) (self:write (+ addr 0x1000) (bytes:sub 0x1001)))
mem (-> (manager:machine) (. :devices ::maincpu :spaces :program))] (self:eval-input
(print :writing (bytes:len) :to addr) "(let [bencode (require :bencode)
(for [i 1 (bytes:len)] {: addr : bytes} (bencode.decode (io.read))
(mem:write_u8 (+ addr i -1) (string.byte (bytes:sub i i)))))" mem (-> (manager:machine) (. :devices ::maincpu :spaces :program))]
(bencode.encode {: addr : bytes}))) (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] (fn Machine.launch [self prg]
(self:eval "(: (manager:machine) :soft_reset)") (self:eval "(: (manager:machine) :soft_reset)")
(self:eval (string.format "(emu.keypost \"CALL-151\\n %xG\\n\")" (prg:lookup-addr prg.start-symbol)))) (self:eval (string.format "(emu.keypost \"CALL-151\\n %xG\\n\")" (prg:lookup-addr prg.start-symbol))))

View file

@ -36,7 +36,7 @@ $0c00-$1fff 3kb-8kb - free space
$2000-$4000 8kb-16kb - hgr gfx page 1 $2000-$4000 8kb-16kb - hgr gfx page 1
Game: Game:
* level loading * fix hot reload :O
* Title screen * Title screen
* Ending screen * Ending screen