diff --git a/editor/init.fnl b/editor/init.fnl index f4dc184..7f3486a 100644 --- a/editor/init.fnl +++ b/editor/init.fnl @@ -10,6 +10,7 @@ (local common (require :core.common)) (require :editor.8bitsy) +(require :presentation.commands) (let [commands {}] (each [_ name (ipairs [:tile :portrait :font :brush :map])] diff --git a/kfest2021.md b/kfest2021.md new file mode 100644 index 0000000..8692fdf --- /dev/null +++ b/kfest2021.md @@ -0,0 +1,66 @@ +# Honeylisp + +## Introduction +* 286 project +* Honeylisp vision + +## Assembler +### What is an assembler? +* I _thought_ the hard part was going to be converting mnemonics to bytes +* Turns out the hard part is actually converting labels to bytes +* zero-page instructions are a different size! +### How it works +* Represent each opcode as a Fennel data literal +* nest blocks arbitrarily - "lexical scope" +* multi-pass + +## VM +* Forth-ish stack machine +* "direct threaded" inner interpreter +* extend assembler with :vm directive +* "immediate words" are just Fennel functions + +## Lite +* Minimal extensible text editor built in Lua +* love2d port + +## Custom Editors +* imgui style +* show tile editor with map editor +* font + portrait editors based on tile editor +* generate bytes / code with fennel functions! (maps, gfx, etc) + +## MAME Upload +* Nod to Dagen Brock's 2016 KFest talk on GSPlus https://www.youtube.com/watch?v=1LzCmpAanpE +* Integrated Jeejah networked REPL into MAME +* Can send arbitrary Fennel code to MAME to control it +* Poke blocks of memory over the network (nREPL uses bencode from bittorrent, which allows this to be fairly low overhead) + +## Live Code Injection +* The assembled program is an object in memory, which we can extend interactively +* We can write new code and poke it into memory while the old code is running! +* Game code is a loop - we can have a "sync point" at the top of the loop where the state of the game is well-known +* (demo switching video modes, printing debug output, making sounds) + +## Hot Reload +* Because the assembled program is an object in memory + +## Tape generation +* Benefit of building tools in a game engine - I can just output audio +* Extended assembler to accept BASIC tokens and generate linked list of BASIC lines, so the whole thing could be bootstrapped + +## Disk generation +* Take a ProDOS disk image, parse it, and add files to it +* Generate loader program, rest of game can be loaded as an overlay +* New disk image is generated on every build because why not? It's fast + +## Neu] [ower +* Fun tricks: Random number generator (never used for gameplay purposes) = just dump a couple dozen random bytes + +## 8-Bitsy +* Full "code-optional" environment +* Kind of awkward to actually use, but it works! +* Son drew some art +* Improvisational game design! + + diff --git a/lib/lume.lua b/lib/lume.lua index 2157891..9f7792c 100644 --- a/lib/lume.lua +++ b/lib/lume.lua @@ -694,7 +694,7 @@ function lume.hotswap(modname) local oldmt, newmt = getmetatable(old), getmetatable(new) if oldmt and newmt then update(oldmt, newmt) end for k, v in pairs(new) do - if type(v) == "table" then update(old[k], v) else old[k] = v end + if type(v) == "table" and type(old[k]) == "table" then update(old[k], v) else old[k] = v end end end local err = nil diff --git a/presentation/commands.fnl b/presentation/commands.fnl new file mode 100644 index 0000000..06121da --- /dev/null +++ b/presentation/commands.fnl @@ -0,0 +1,24 @@ +(local core (require :core)) +(local command (require :core.command)) +(local keymap (require :core.keymap)) +(local SlideshowView (require :presentation.engine)) + +(command.add nil { + "presentation:start" (fn [] + (let [node (core.root_view:get_active_node)] + (node:add_view (SlideshowView (require :presentation.slides)))) + ) +}) +(command.add :presentation.engine { + "presentation:next" #(core.active_view:advance) + "presentation:prev" #(core.active_view:back) + "presentation:next-slide" #(core.active_view:next-slide) + "presentation:prev-slide" #(core.active_view:prev-slide) +}) +(keymap.add { + "left" "presentation:prev" + "right" "presentation:next" + "," "presentation:prev-slide" + "." "presentation:next-slide" +}) + diff --git a/presentation/engine.fnl b/presentation/engine.fnl new file mode 100644 index 0000000..e72c885 --- /dev/null +++ b/presentation/engine.fnl @@ -0,0 +1,63 @@ +(local lume (require :lib.lume)) +(local style (require :core.style)) +(local common (require :core.common)) +(local View (require :core.view)) + +(local SlideshowView (View:extend)) +(fn SlideshowView.parse [slides] + (var style nil) + (icollect [_ slide (ipairs slides)] + (icollect [_ elem (ipairs slide)] + (match (type elem) + :table (do (set style elem) nil) + :string (lume.merge style {:text elem}))))) + +(fn SlideshowView.new [self slides] + (SlideshowView.super.new self) + (set self.slides slides) + (set self.islide 1) + (set self.ielem 0) + (self:advance)) + +(fn SlideshowView.next-slide [self] + (set self.islide (if (= self.islide (length self.slides)) 1 (+ self.islide 1))) + (set self.ielem 0) + (self:advance)) + +(fn SlideshowView.prev-slide [self] + (set self.islide (if (= self.islide 1) (length self.slides) (- self.islide 1))) + (set self.ielem (+ 1 (length (. self.slides self.islide)))) + (self:back)) + +(fn SlideshowView.ielemNext [self ielem di] + (let [slide (. self.slides self.islide) + elem (. slide ielem)] + (when elem + (if elem.pause-after ielem + (self:ielemNext (+ ielem di) di))))) + +(fn SlideshowView.advance [self] + (let [ielemNext (self:ielemNext (+ self.ielem 1) 1)] + (if ielemNext (set self.ielem ielemNext) + (self:next-slide)))) + +(fn SlideshowView.back [self] + (let [ielemNext (self:ielemNext (- self.ielem 1) -1)] + (if ielemNext (set self.ielem ielemNext) + (self:prev-slide)))) + +(fn SlideshowView.render-element [self element y] + (let [x (+ self.position.x + (match element.justify + :center (/ (- self.size.x (element.font:get_width element.text)) 2) + :left style.padding.x))] + (renderer.draw_text element.font element.text x y element.color) + (+ y (* style.padding.y 2) (element.font:get_height)))) + +(fn SlideshowView.draw [self] + (self:draw_background style.background) + (var y (+ style.padding.y self.position.y)) + (each [ielem element (ipairs (. self.slides self.islide)) :until (> ielem self.ielem)] + (set y (self:render-element element y)))) + +SlideshowView diff --git a/presentation/font/FreeLicense.txt b/presentation/font/FreeLicense.txt new file mode 100644 index 0000000..e48a09b --- /dev/null +++ b/presentation/font/FreeLicense.txt @@ -0,0 +1,20 @@ +KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE +version 1.2f + +Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: + +1. The User may not sell copies of the Software for a fee. + +1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. + +2. The User may not modify, reverse-engineer, or create any derivative works of the Software. + +3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! + +3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. + +4. This license becomes null and void if any of the above conditions are not met. + +5. Kreative Software reserves the right to change this license at any time without notice. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. diff --git a/presentation/font/PRNumber3.ttf b/presentation/font/PRNumber3.ttf new file mode 100644 index 0000000..4843041 Binary files /dev/null and b/presentation/font/PRNumber3.ttf differ diff --git a/presentation/font/PrintChar21.ttf b/presentation/font/PrintChar21.ttf new file mode 100644 index 0000000..7204e97 Binary files /dev/null and b/presentation/font/PrintChar21.ttf differ diff --git a/presentation/font/Shaston320.ttf b/presentation/font/Shaston320.ttf new file mode 100644 index 0000000..f4328fe Binary files /dev/null and b/presentation/font/Shaston320.ttf differ diff --git a/presentation/font/Shaston640.ttf b/presentation/font/Shaston640.ttf new file mode 100644 index 0000000..14109fb Binary files /dev/null and b/presentation/font/Shaston640.ttf differ diff --git a/presentation/font/ShastonHi320.ttf b/presentation/font/ShastonHi320.ttf new file mode 100644 index 0000000..fd77def Binary files /dev/null and b/presentation/font/ShastonHi320.ttf differ diff --git a/presentation/font/ShastonHi640.ttf b/presentation/font/ShastonHi640.ttf new file mode 100644 index 0000000..cfabff2 Binary files /dev/null and b/presentation/font/ShastonHi640.ttf differ diff --git a/presentation/slides.fnl b/presentation/slides.fnl new file mode 100644 index 0000000..3b14157 --- /dev/null +++ b/presentation/slides.fnl @@ -0,0 +1,26 @@ +(local util (require :lib.util)) +(local {: parse} (util.require :presentation.engine)) +(local style (require :core.style)) +(local h + {:font (renderer.font.load "presentation/font/PrintChar21.ttf" (* 64 SCALE)) + :color style.caret + :justify :center}) +(local ** + {:font (renderer.font.load "presentation/font/PRNumber3.ttf" (* 32 SCALE)) + :color style.text + :justify :left + :pause-after true}) + +(parse [ + [h "Some Background" + ** "In 2019 I built a 16-bit MS-DOS game engine." + "* Built on hardware" + "* Using only period software" + "* Powered by Forth"] + [h "Neut Tower" + ** "In 2020, I did the Global Game Jam on my 286." + "Finished the 'Shareware Episode' a couple of months later."] + [h "Then Kansasfest Happened." ** ""] + [h "Oh Dang Bill" + ** "Oh gee oh whiz on toast"] +])