Restructure presentation, add button support

This commit is contained in:
Jeremy Penner 2021-07-08 23:36:15 -04:00
parent 17375a5929
commit a56705ac01
5 changed files with 130 additions and 89 deletions

View file

@ -95,11 +95,12 @@
(activate view tag x y w h) (activate view tag x y w h)
(values (and (active? view tag) (= view.imstate.left :released) (mouse-inside x y w h)) (+ y h style.padding.y))) (values (and (active? view tag) (= view.imstate.left :released) (mouse-inside x y w h)) (+ y h style.padding.y)))
(fn textbutton [view label x y] (fn textbutton [view label x y ?font]
(local (w h) (values (+ (style.font:get_width label) style.padding.x) (+ (style.font:get_height) style.padding.y))) (let [font (or ?font style.font)]
(local (w h) (values (+ (font:get_width label) style.padding.x) (+ (font:get_height) style.padding.y)))
(renderer.draw_rect x y w h style.selection) (renderer.draw_rect x y w h style.selection)
(renderer.draw_text style.font label (+ x (/ style.padding.x 2)) (+ y (/ style.padding.y 2)) style.text) (renderer.draw_text font label (+ x (/ style.padding.x 2)) (+ y (/ style.padding.y 2)) style.text)
(values (button view label x y w h) (+ y h))) (values (button view label x y w h) (+ y h))))
(fn checkbox [view name isset x y ?tag] (fn checkbox [view name isset x y ?tag]
(love.graphics.rectangle (if isset :fill :line) x y (* 12 SCALE) (* 12 SCALE)) (love.graphics.rectangle (if isset :fill :line) x y (* 12 SCALE) (* 12 SCALE))

View file

@ -143,7 +143,7 @@
[:jmp (if (= (or map.moveword "") "") :move-noop map.moveword)] [:jmp (if (= (or map.moveword "") "") :move-noop map.moveword)]
[:jmp (if (= (or map.loadword "") "") :next map.loadword)])) [:jmp (if (= (or map.loadword "") "") :next map.loadword)]))
(vm.code:append :map-ptr [:db 0] :map-page [:db 0]) (vm.code:append :map-ptr [:db 0] [:hot-preserve :map-page [:db 0]])
(vm:word :map :lit :map-ptr :get) (vm:word :map :lit :map-ptr :get)
(vm:word :entity-count :map 240 :+ :bget) (vm:word :entity-count :map 240 :+ :bget)
(vm:word :map-jaye-yx :map 241 :+ :get) (vm:word :map-jaye-yx :map 241 :+ :get)

View file

@ -2,6 +2,7 @@
(local style (require :core.style)) (local style (require :core.style))
(local common (require :core.common)) (local common (require :core.common))
(local View (require :core.view)) (local View (require :core.view))
(local {: attach-imstate : textbutton} (require :editor.imstate))
(local SlideshowView (View:extend)) (local SlideshowView (View:extend))
(fn SlideshowView.parse [slides] (fn SlideshowView.parse [slides]
@ -10,11 +11,12 @@
(icollect [_ elem (ipairs slide)] (icollect [_ elem (ipairs slide)]
(match (type elem) (match (type elem)
(where :table elem.style) (do (set style elem) nil) (where :table elem.style) (do (set style elem) nil)
:table elem :table (if elem.button (lume.merge style elem) elem)
:string (lume.merge style {:text elem}))))) :string (lume.merge style {:text elem})))))
(fn SlideshowView.new [self slides] (fn SlideshowView.new [self slides]
(SlideshowView.super.new self) (SlideshowView.super.new self)
(attach-imstate self)
(set self.slides slides) (set self.slides slides)
(set self.imagecache {}) (set self.imagecache {})
(set self.islide 1) (set self.islide 1)
@ -87,7 +89,16 @@
lines)) lines))
(fn SlideshowView.render-element [self element y] (fn SlideshowView.render-element [self element y]
(if element.text (if element.button
(let [(pressed yNext) (textbutton self
element.text
(+ self.position.x (self:justify element (element.font:get_width element.text)))
y
element.font)]
(when pressed (element:button))
(self:next-y element (- yNext y) y))
element.text
(let [lines (self:word-wrap element) (let [lines (self:word-wrap element)
line-height (element.font:get_height) line-height (element.font:get_height)
full-height (+ (* line-height (length lines)) (* style.padding.y (- (length lines) 1)))] full-height (+ (* line-height (length lines)) (* style.padding.y (- (length lines) 1)))]

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -9,6 +9,7 @@
(local FontEditView (require :editor.fontedit)) (local FontEditView (require :editor.fontedit))
(local ScreenEditView (require :editor.screenedit)) (local ScreenEditView (require :editor.screenedit))
(local files (require :game.files)) (local files (require :game.files))
(local link (require :link))
(local h (local h
{:style true {:style true
@ -24,8 +25,8 @@
:justify :left :justify :left
:lowerPadding 7 :lowerPadding 7
:pause-after true}) :pause-after true})
(fn p [style] (lume.merge style {:pause-after true})) (fn p [style ?text] (lume.merge style {:pause-after true} (if ?text {:text ?text :style false})))
(fn np [style] (lume.merge style {:pause-after false})) (fn np [style ?text] (lume.merge style {:pause-after false} (if ?text {:text ?text :style false})))
(fn bgimg [filename] {:image filename :justify :center :overlay true :alpha 0.3 :topPadding 0}) (fn bgimg [filename] {:image filename :justify :center :overlay true :alpha 0.3 :topPadding 0})
@ -52,6 +53,21 @@
view) view)
?extra)) ?extra))
(fn boot-game []
(let [p (util.reload :game)]
(util.in-coro (fn [] (link:switch :mame)
(link.machine:run)
(util.waitfor #(link.machine:connected?))
(p:upload link.machine)
(link.machine:launch p)))
nil))
(fn vm-eval [...]
(let [prg (require :game)
overlay (prg.vm:gen-eval-prg [:vm ...])]
(link.machine:overlay overlay)
nil))
(parse [ (parse [
[h "" "" "" [h "" "" ""
"Honeylisp" "Honeylisp"
@ -63,26 +79,58 @@
"https://gamemaking.social/@SpindleyQ" "https://gamemaking.social/@SpindleyQ"
"https://twitter.com/SpindleyQ" "https://twitter.com/SpindleyQ"
{:pause-after true}] {:pause-after true}]
[h "Honeylisp is hard to explain"
** "It is an experimental programming environment designed to enable a productive Apple // game development workflow"
"https://fennel-lang.org/"]
[(bgimg "presentation/pics/pete286.jpeg") [(bgimg "presentation/pics/pete286.jpeg")
h "Some Background" h "Some Background"
** "In 2019 I built a 16-bit MS-DOS game engine." ** "2019: Built a 16-bit MS-DOS game engine, using only retro hardware and software."]
"* Built on hardware"
"* Using only period-appropriate software (Turbo C, NeoPaint)"
"* Powered by Forth"
"* Integrated custom tools"
"* Interactive development via serial terminal"]
[(bgimg "presentation/pics/ggj2020.jpeg") [(bgimg "presentation/pics/ggj2020.jpeg")
h "Neut Tower" h "Neut Tower"
** "In 2020, I did the Global Game Jam on my 286." ** "2020: Created Neut Tower as part of two game jams.
"Finished 'Shareware Episode 1' a couple of months later."] * Global Game Jam - One weekend - Feb 2020 - First two rooms
[h "The Idea" * MS-DOS Game Jam - 1.5 months - April 2020 - 'Shareware Episode 1'"]
** "What if I took a similar DIY approach with modern tooling?" [(bgimg "presentation/pics/boot-tower.jpeg")
"* I'd done Forth; what about Lisp?" {:action #(files.reload :neuttower/game.json)}
" https://fennel-lang.org/" h "Neu] [ower"
"* How far can I push fast iterative development?" ** "A small puzzle adventure game!"
"* Could I integrate an editor?" "Magic Trick #1"
"* How can I leverage emulation?"] {:action boot-game}
[h "Step 1: Assembler" "--== D E M O ==--"]
[h "How It's Made"
** "Is the Apple ][ running Lisp?"
" * Not really?"
"Is the code written in Lisp?"
" * Sort of!"
"Show me some Lisp already! >:/"
(openfile :neuttower/level1.fnl {:split :right :line 42})
" * OK!"]
[h "What is this unholy abomination?"
** "Lisp and Forth?!"
{:image "presentation/pics/thinkhard.png" :justify :center}
"Not super keen on writing a complicated compiler"
" * \"Direct threaded\" inner interpreter"
"Forth allows efficient, composable, interactive code"]
[h "Why use Lisp to compile Forth?"
** "\"Immediate words\" can be Fennel functions that generate code!"
"Program can be compiled into a rich data structure"
(openfile :neuttower/level1.fnl {:split :right :line 59})
"Magic Trick #2"
(np **) "Magic Trick #3"
{:button #(vm-eval :mixed) :text ":mixed"}
{:button #(vm-eval :hires) :text ":hires"}
{:button #(vm-eval 1 2 :+ :.) :text "1 2 :+ :."}
{:button #(vm-eval :earthquake) :text ":earthquake"}
{:pause-after true}]
[h "Explain this voodoo!"
** "Directly inspired by Dagen Brock's 2016 KFest talk on GSPlus"
"Ended up using MAME - Lua plugin system exposes EVERYTHING"
"Use Jeejah nREPL server library with custom nREPL client"
"1. What if I could poke my program directly into an emulator's memory?"
"2. What if I could preserve the current runtime state but rewrite the code?"
" ... even if the data has moved?"
"3. What if I could interactively try out new code while my game was running?"]
[h "Digging Deeper: Assembler"
** "Represent instructions using Fennel data literals" ** "Represent instructions using Fennel data literals"
(openfile :neuttower/defs.fnl {:split :right :line 57}) (openfile :neuttower/defs.fnl {:split :right :line 57})
" [:lda 0xff]" " [:lda 0xff]"
@ -90,7 +138,6 @@
" :loop [:bne :loop]" " :loop [:bne :loop]"
"Lexical scope with nested blocks" "Lexical scope with nested blocks"
" [:block :loop (generate-loop-code) [:bne :loop]]"] " [:block :loop (generate-loop-code) [:bne :loop]]"]
; ;; DEMO before tech dive??
[h "Wait WTF Is An Assembler" [h "Wait WTF Is An Assembler"
** "It's just converting mnemonics to bytes, right?" ** "It's just converting mnemonics to bytes, right?"
{:image "presentation/pics/assembly-markup.png" :justify :center :pause-after true} {:image "presentation/pics/assembly-markup.png" :justify :center :pause-after true}
@ -101,31 +148,8 @@
" [:db 123] [:dw 12345] [:bytes \"HELLO WORLD\"] [:ref :hello]" " [:db 123] [:dw 12345] [:bytes \"HELLO WORLD\"] [:ref :hello]"
"Must be able to line up bytes on page boundaries" "Must be able to line up bytes on page boundaries"
" [:align 0x100]"] " [:align 0x100]"]
[h "Step 2: Virtual Machine" [h "The Tools"
{:image "presentation/pics/thinkhard.png" :justify :center} ** {:image "presentation/pics/retro-game-dev-quote.png" :justify :center :pause-after true}
** "Not super keen on writing a complicated compiler"
"I'm already very comfortable with Forth"
"Let's build a stack machine!"
"\"Direct threaded\" inner interpreter"
"\"Immediate words\" can be Fennel functions that generate code!"]
[h "Extensible Assembler??"
** "How do you turn code into bytes?"
" [:vm 1 2 :+ :.]"
"Branching?"
" (vm:if [:do-true-thing] [:do-false-thing])"
"I can even do short-circuiting OR!"
" (vm:if-or [[:dup 1 :=] [:dup 3 :=]] [:do-true-thing] [:do-false-thing])"]
[h "Step 3: Tooling And Workflow"
** "I want an environment that makes it easy to make graphical tools"
"I'm SO tired of web tech"
"Could LÖVE2D with an imgui work?"]
[h "lite"
** "A small, highly-extensible text editor written in Lua"
"Backend is SDL"
"Could I rewrite it to run under LÖVE2D?"
" Yes! In a weekend!"]
[h "Custom Editors"
** "Retro game programming is just the process of writing a series of barely-usable custom paint programs."
{:action #(files.reload :neuttower/game.json)} {:action #(files.reload :neuttower/game.json)}
"14x16 tile editor" "14x16 tile editor"
(openview #(TileEditView)) (openview #(TileEditView))
@ -138,46 +162,20 @@
"Full-screen bitmap editor" "Full-screen bitmap editor"
(openview #(ScreenEditView :neuttower/title.screen) {:pause-after true}) (openview #(ScreenEditView :neuttower/title.screen) {:pause-after true})
(openfile :presentation/slides.fnl {:split :right :line 133}) (openfile :presentation/slides.fnl {:split :right :line 133})
"Presentation viewer!?"] "Presentation viewer"]
[h "Editing Editors With My Editor" [h "Editing Editors With My Editor"
** "Lua provides a very dynamic environment that allows me tremendous flexibility" ** "lite is a small, highly-extensible text editor written in Lua"
"Lua provides a very dynamic environment"
(openview #(MapEditView)) (openview #(MapEditView))
(openfile :editor/mapedit.fnl {:split :right :line 235}) (openfile :editor/mapedit.fnl {:split :right :line 235})
"Downside:" "Downside:"
{:image "presentation/pics/bsod.png" :justify :center :pause-after true}] {:image "presentation/pics/bsod.png" :justify :center :pause-after true}]
[h "Step 4: Emulator Integration" [(bgimg "presentation/pics/bitsy.png")
** "Directly inspired by Dagen Brock's 2016 KFest talk on GSPlus" {:action #(files.reload :bitsy/game.json)}
"Ended up using MAME - has a full Lua plugin system" h "8-Bitsy"
"What if I could poke my program directly into an emulator's memory?" ** "Bitsy is a popular free, accessible, web-based game-making tool"
"What if I could preserve the current runtime state but rewrite the code?" {:action boot-game :pause-after true}
"... even if the data has moved?" (openview #(MapEditView) {:pause-after true})]
"What if I could interactively try out new code while my game was running?"]
[h "Step 5: Running on Hardware"
** "I have a IIgs with a serial cable - I can poke bytes in directly from the monitor"
"]IN#2\n]PR#2\n]CALL-151"
"Easy to send bytes faster than the monitor can process them"]
[h "Audio"
** "I have a II+ with a cassette port"
"LÖVE2D is a game engine - my editor can generate audio and play it back immediately"
"Need to generate a BASIC program to bootstrap my machine code"
(openfile :asm/tape.fnl {:split :right})
" [:basic [10 :call :2061]]"
"Future work: Apple Game Server fastloader"]
[(bgimg "presentation/pics/beneath-apple-prodos.png")
h "ProDOS"
** "Disk image is a must-have for distribution"
(openfile :asm/prodos.fnl {:split :right :line 132})
"Of course I wrote my own disk image generation code!"
"Start with a blank ProDOS disk and add to it"
"Fun bugs!"
"* Accidentally implemented undelete instead of inserting new files at first"
"* Read the free space bitmap backwards and overwrote the OS"
"* Tried to name a volume starting with a number"]
[(bgimg "presentation/pics/boot-tower.jpeg")
{:action #(files.reload :neuttower/game.json)}
h "Neu] [ower"
** "A small puzzle adventure game!"
"--== D E M O ==--"]
[(bgimg "presentation/pics/bitsy.png") [(bgimg "presentation/pics/bitsy.png")
{:action #(files.reload :bitsy/game.json)} {:action #(files.reload :bitsy/game.json)}
h "8-Bitsy" h "8-Bitsy"
@ -187,5 +185,36 @@
(openview #(MapEditView) {:pause-after true})] (openview #(MapEditView) {:pause-after true})]
[h "Thanks!" [h "Thanks!"
(openfile :neuttower/level6.fnl {:split :right :line 153}) (openfile :neuttower/level6.fnl {:split :right :line 153})
** "Questions?"] ** "Questions?"
(np **) {:topPadding 128}
"Jeremy Penner"
"https://spindleyq.itch.io/"
"https://blog.information-superhighway.net/"
"https://bitbucket.org/SpindleyQ/honeylisp"
"https://gamemaking.social/@SpindleyQ"
"https://twitter.com/SpindleyQ"
{:pause-after true}]
]) ])
; [h "Step 5: Running on Hardware"
; ** "I have a IIgs with a serial cable - I can poke bytes in directly from the monitor"
; "]IN#2\n]PR#2\n]CALL-151"
; "Easy to send bytes faster than the monitor can process them"]
; [h "Audio"
; ** "I have a II+ with a cassette port"
; "LÖVE2D is a game engine - my editor can generate audio and play it back immediately"
; "Need to generate a BASIC program to bootstrap my machine code"
; (openfile :asm/tape.fnl {:split :right})
; " [:basic [10 :call :2061]]"
; "Future work: Apple Game Server fastloader"]
; [(bgimg "presentation/pics/beneath-apple-prodos.png")
; h "ProDOS"
; ** "Disk image is a must-have for distribution"
; (openfile :asm/prodos.fnl {:split :right :line 132})
; "Of course I wrote my own disk image generation code!"
; "Start with a blank ProDOS disk and add to it"
; "Fun bugs!"
; "* Accidentally implemented undelete instead of inserting new files at first"
; "* Read the free space bitmap backwards and overwrote the OS"
; "* Tried to name a volume starting with a number"]