renamed to Swine Meeper, title screen, readme

This commit is contained in:
Jeremy Penner 2023-09-26 12:59:46 -04:00
parent 66dcbbdbd7
commit e98c04584a
4 changed files with 134 additions and 5 deletions

BIN
mines.com

Binary file not shown.

73
readme.txt Executable file
View file

@ -0,0 +1,73 @@
S W I N E M E E P E R
=======================
Created for the DOS COM Game Jam 2023
https://itch.io/jam/dos-com-game-jam
Technical Details
-----------------
This source repository contains a full development toolchain for creating
DOS COM programs in Forth and assembly. This toolchain was written in a
custom Forth dialect originally built for Neut Tower[1]; through a fairly
involved bootstrapping process it is now completely capable of rebuilding
itself. Every byte of every .COM file in this repository has been generated
from the included 8086 assembler, including the .COM file of the assembler.
We start with MINIJORT.EXE, compiled with Borland Turbo C++ from MINIJORT.C
and MAIN.C. This is a stripped-down version of the Jorth engine that Neut
Tower[1] was built with, and the only part of this project that existed in
any form before August 14, 2023. (I started early on the jam because I
basically knew what I wanted to implement, and I knew that getting _anything_
playable by the end of September with the absurd plan I had in mind was
going to be a long shot.) MINIJORT.EXE is a simple Forth interpreter that
loads BOOT.JOR and then reads the rest of its input from stdin.
We then use MiniJort to generate TINYJORT.COM. This is done by piping the
contents of TINYBOOT.JRT to MiniJort. TINYBOOT loads some common definitions
from DEFS.JRT and the assembler from TARGET.JRT and ASM.JRT, then executes
TINYJORT.JRT, which assembles a second Forth interpreter that understands
a substantially similar vocabulary as MiniJort, with some improvements.
TinyJort internally embeds the definitions from BOOT.JOR and is entirely
self-contained.
We could load TINYBOOT into TINYJORT.COM to rebuild itself, but one of the
big advantages of TinyJort over MiniJort is that TinyJort is trivially
capable of adding more definitions to itself and then writing out a new
.COM file with those definitions already loaded. So the next step is to use
TinyJort to build ASSEMBLE.COM, which is just TinyJort with the basic defs
and assembler pre-loaded, ready to get to work as soon as you launch it,
saving precious seconds of build time. TINYJORT.JRT can be loaded directly
into ASSEMBLE.COM in order to produce a byte-exact copy of TINYJORT.COM.
REBUILD.BAT automates the process of bootstrapping TinyJort, and includes
a check to ensure that both Jorts produce the same .COM file. REASM.BAT
regenerates TINYJORT.COM and ASSEMBLE.COM using TINYJORT.COM and
ASSEMBLE.COM and is much faster.
But that's not enough Forth interpreters yet! This tooling would allow us
to write assembly code _using_ Forth, and it would allow us to _extend_
TinyForth to produce another Forth interpreter, but it does not yet allow
us to generate .COM files, written in Forth, that do not include extraneous
data like the Forth dictionary and the assembler. Since the .COM format is
limited to 64kb, space is at a premium. The final custom Forth interpreter
is ZIPOFF.COM and ZIPSTUB.SEG.
Why ZipOff? Imagine a pair of Jorts - these are the Forth interpreter,
assembler, and extended runtime. Now imagine extending these Jorts into
full-on Jeans, by bringing in the definitions of the code that needs to
actually be included in the final product. When the two pieces are together,
the host Jorts can take advantage of the immediate interactive development
workflow of Forth, calling out to words defined in the final .COM, and
providing useful debugging tools not needed for the final product. But once
the development cycle is complete, the legs of the Jeans can be jettisoned -
zipped off, if you will - and... worn on their own, I guess? The metaphor
breaks down a little bit here. The point is that the target .COM file is
minimal and completely self-sufficient.
Yo dawg, I heard you liked Forth, so I wrote a Forth interpreter in Forth
that I used to implement another Forth.
THIS, finally, is the tool we use to build games and demos with. Importing
SWINE.JRT into ZipOff produces SWINE.COM; importing DIRTRECT.JRT produces
DIRTRECT.COM, and so forth.
[1] https://spindleyq.itch.io/neut-tower/

BIN
swine.com Executable file

Binary file not shown.

View file

@ -88,8 +88,8 @@ var theme
{ :timm deftheme CREATE >t >t >t >t >t >t DOES} theme ! ; { :timm deftheme CREATE >t >t >t >t >t >t DOES} theme ! ;
( cursor grid block mine flag bg ) ( cursor grid block mine flag bg )
blue white black black red lgray deftheme win31 blue white black magenta red lgray deftheme win31
white yellow black black yellow red deftheme hotdog white yellow black lmagenta yellow red deftheme hotdog
win31 win31
@ -97,7 +97,7 @@ win31
NEIGHBOUR-MASK & dup col-count NEIGHBOUR-MASK & dup col-count
dup if [ key 0 lit ] + else drop [ key lit ] then draw-char ; dup if [ key 0 lit ] + else drop [ key lit ] then draw-char ;
: draw-flag ( -- ) col-flag 0x0d draw-char ; : draw-flag ( -- ) col-flag 0x0d draw-char ;
: draw-mine ( -- ) col-mine 0x0f draw-char ; : draw-mine ( -- ) col-mine 0xec draw-char ;
: draw-block ( -- ) col-block 0xb1 draw-char ; : draw-block ( -- ) col-block 0xb1 draw-char ;
: draw-revealed ( b -- ) : draw-revealed ( b -- )
dup FMINE & if draw-mine drop else draw-neighbour-count then ; dup FMINE & if draw-mine drop else draw-neighbour-count then ;
@ -207,4 +207,60 @@ IN-PROGRESS bvar, game-state
' start ' main redefine ' start ' main redefine
{ s" mines.com" writecom } ( title menu )
array title-text t", SWINE MEEPER"
: emptych? ( ch -- f ) dup 32 = swap 0 = or ;
: drawdot? ( st -- f ) dup b@ emptych? swap 1+ b@ emptych? or not ;
: dot 7 draw-char ;
: sp 32 draw-char ;
: spacer ( st -- ) sp drawdot? if dot else sp then sp ;
: draw-spaced-text ( st -- )
begin dup b@ dup while draw-char dup spacer 1+ repeat drop drop ;
2 cells const menu-optsize
2 const menu-size
array menu-options menu-optsize menu-size * allot
: menu-option ( iopt -- p ) menu-optsize * menu-options + ;
: defmenu ( cp name iopt -- ) menu-option dup >rot ! cell + ! ;
' start s" Start Game" 0 defmenu
' terminate s" Quit" 1 defmenu
0 var, menu-selected
: menu-activate menu-selected @ menu-option cell + @ execute ;
: draw-selection ( iopt -- )
menu-selected @ = if draw-mine else sp then sp ;
: draw-option ( iopt -- ) white fg! menu-option @ draw-text ;
: draw-menu
33 10 textxy!
textx 0 begin dup menu-size < while
dup draw-selection dup draw-option 1+ nextline over textx! repeat
drop drop ;
: draw-title
blue bg! yellow fg! 32 fill-page
17 3 textxy! title-text draw-spaced-text
draw-menu ;
: menu-selected! ( i -- )
dup 0 >= over menu-size < and if menu-selected ! else drop then ;
: menu-selected+! ( di -- ) menu-selected @ + menu-selected! ;
: await-menu
wait-key key>scan
dup %esc = if terminate then
dup %up = if -1 menu-selected+! then
dup %down = if 1 menu-selected+! then
%enter = if menu-activate then ;
: title draw-title begin await-menu draw-menu again ;
' title ' main redefine
{ s" swine.com" writecom }