Presentation slides with demo
move sprites + tiles to far memory to free up space
This commit is contained in:
parent
6c4e5ff396
commit
64d421429e
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -4,4 +4,4 @@
|
|||
*.swp
|
||||
*.log
|
||||
*.jim
|
||||
|
||||
game.map
|
||||
|
|
2
egamap.h
2
egamap.h
|
@ -1,6 +1,6 @@
|
|||
#include "tiles.h"
|
||||
|
||||
#define NUM_TILES 128
|
||||
#define NUM_TILES 64
|
||||
#define NUM_PORTRAITS 16
|
||||
|
||||
#define SIZE_FOOTER (PAGE_STRIDE * 48)
|
||||
|
|
BIN
egavga.bgi
Executable file
BIN
egavga.bgi
Executable file
Binary file not shown.
BIN
footer2.tif
Executable file
BIN
footer2.tif
Executable file
Binary file not shown.
10
game.jor
10
game.jor
|
@ -112,9 +112,6 @@ player :tick
|
|||
;entity
|
||||
|
||||
( S T U F F )
|
||||
: hello-world
|
||||
player.state DRIVING fnot! ;
|
||||
|
||||
: reset-level
|
||||
:| player yield 0 |; ' entities redefine
|
||||
:| drop drop 0 |; ' player-touch redefine ;
|
||||
|
@ -122,9 +119,6 @@ player :tick
|
|||
: mode-move
|
||||
entities each EVTICK entity>do more
|
||||
tick-mapedit
|
||||
^SPACE key-pressed if
|
||||
' hello-world JOB send
|
||||
then
|
||||
tick-debounce
|
||||
q-level @ dup if
|
||||
0 q-level !
|
||||
|
@ -141,13 +135,17 @@ player :tick
|
|||
r@ entity.dir @ r< entity>sprite
|
||||
draw-sprite ;
|
||||
|
||||
var showmouse
|
||||
1 showmouse !
|
||||
: full-draw
|
||||
player entity.x @ 152 -
|
||||
player entity.y @ 92 -
|
||||
scroll
|
||||
|
||||
entities each draw-entity more
|
||||
showmouse @ if
|
||||
mouseworldpos 4 draw-sprite
|
||||
then
|
||||
draw-screen
|
||||
draw-footer ;
|
||||
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
: blah ' seremit task-emit ! ;
|
||||
blah
|
||||
|
||||
: start-repl activate blah
|
||||
s" game.log" open seekend fdeactivate const LOGFILE
|
||||
: emit-log fdeactivate LOGFILE factivate fputc fdeactivate drop factivate ;
|
||||
: atexit LOGFILE factivate close ;
|
||||
|
||||
: start-repl activate blah ' emit-log task-echo !
|
||||
s" .:: J O R T H ( jean forth) ::." type cr
|
||||
begin receive loadstring s" ok" type cr again ;
|
||||
task const REPL
|
||||
|
@ -19,6 +23,7 @@ s" footer.jor" loadfile
|
|||
s" map.jor" loadfile
|
||||
s" game.jor" loadfile
|
||||
s" state.jor" loadfile
|
||||
s" slide.jor" loadfile
|
||||
; execute
|
||||
|
||||
intern pete.jor
|
||||
|
@ -30,4 +35,4 @@ intern trail1.jor
|
|||
:noname loadfile ; checkpoint _loadlevel
|
||||
' _loadlevel ' loadlevel redefine
|
||||
|
||||
pete.jor loadlevel
|
||||
( pete.jor loadlevel )
|
||||
|
|
1
jopl.jor
1
jopl.jor
|
@ -228,6 +228,7 @@ var t2
|
|||
: ontick startt2 player status trackstatus ;
|
||||
|
||||
: files findfile begin dup while yield findnext repeat ;
|
||||
: .files files each type s" " type more ;
|
||||
|
||||
: keynote [ inline|
|
||||
44 b, 31 b, 45 b, 32 b, 46 b, 47 b, 34 b, 48 b, 35 b, 49 b, 36 b, 50 b,
|
||||
|
|
12
jorth.c
12
jorth.c
|
@ -342,6 +342,10 @@ void f_fputc() {
|
|||
DROP(1);
|
||||
}
|
||||
|
||||
void f_gets() {
|
||||
gets(TOP().s);
|
||||
}
|
||||
|
||||
void f_fput() {
|
||||
if (ACTIVE_FILE) {
|
||||
fwrite(&TOP().u, 2, 1, ACTIVE_FILE);
|
||||
|
@ -747,6 +751,12 @@ void f_tell() {
|
|||
PUSHU(ftell(ACTIVE_FILE));
|
||||
}
|
||||
|
||||
void f_exists() {
|
||||
struct stat statbuf;
|
||||
int rc = stat(TOP().s, &statbuf);
|
||||
TOP().i = rc == 0;
|
||||
}
|
||||
|
||||
void f_swapinput() {
|
||||
cell *key = RUNNING + TASK_USER_KEY;
|
||||
cell *keysrc = RUNNING + TASK_USER_KEYSRC;
|
||||
|
@ -1111,6 +1121,7 @@ void f_init(char *exe) {
|
|||
CDEF("swap-input", f_swapinput);
|
||||
CDEF("putc", f_putc);
|
||||
CDEF("fputc", f_fputc);
|
||||
CDEF("gets", f_gets);
|
||||
CDEF("number", f_number);
|
||||
CDEF("LIT_", f_lit_);
|
||||
CDEF("GOTO_", f_goto_);
|
||||
|
@ -1127,6 +1138,7 @@ void f_init(char *exe) {
|
|||
CDEF("open", f_open);
|
||||
CDEF("overwrite", f_overwrite);
|
||||
CDEF("close", f_close);
|
||||
CDEF("exists", f_exists);
|
||||
CDEF("factivate", f_activate);
|
||||
CDEF("fdeactivate", f_deactivate);
|
||||
CDEF("seek", f_seek);
|
||||
|
|
22
serial.c
22
serial.c
|
@ -85,3 +85,25 @@ void ser_write(char *str) {
|
|||
ser_write_byte(*str);
|
||||
}
|
||||
}
|
||||
|
||||
int ser_getline(char *line) {
|
||||
int i = strlen(line);
|
||||
int value;
|
||||
for (value = ser_poll(); value != SER_NODATA; value = ser_poll()) {
|
||||
if (value == '\b' || value == 127) {
|
||||
i --;
|
||||
} else {
|
||||
line[i] = value;
|
||||
i ++;
|
||||
}
|
||||
line[i] = '\0';
|
||||
ser_write_byte(value); // echo
|
||||
|
||||
if (value == '\r') {
|
||||
line[i - 1] = '\n';
|
||||
ser_write_byte('\n');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
3
serial.h
3
serial.h
|
@ -19,10 +19,11 @@
|
|||
#define BAUD_57600 0x0002
|
||||
#define BAUD_115200 0x0001
|
||||
|
||||
#define SER_READ_BUFFER_SIZE 0x200
|
||||
#define SER_READ_BUFFER_SIZE 64
|
||||
#define SER_NODATA -1
|
||||
|
||||
void ser_init(int port, int baudrate, int protocol);
|
||||
int ser_poll();
|
||||
void ser_write_byte(char byte);
|
||||
void ser_write(char *str);
|
||||
int ser_getline(char *line);
|
||||
|
|
82
slide.c
Executable file
82
slide.c
Executable file
|
@ -0,0 +1,82 @@
|
|||
#include <graphics.h>
|
||||
#include "jorth.h"
|
||||
|
||||
static int bgi_on = 0;
|
||||
void bgi_shutdown() {
|
||||
if (bgi_on) {
|
||||
closegraph();
|
||||
bgi_on = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void bgi_init() {
|
||||
int driver = VGA;
|
||||
int mode = VGAHI;
|
||||
if (!bgi_on) {
|
||||
initgraph(&driver, &mode, NULL);
|
||||
bgi_on = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void s_outtext() {
|
||||
outtext(TOP().s);
|
||||
DROP(1);
|
||||
}
|
||||
|
||||
void s_justify() {
|
||||
settextjustify(TOP().i, TOP_TEXT);
|
||||
DROP(1);
|
||||
}
|
||||
|
||||
void s_font() {
|
||||
struct textsettingstype settings;
|
||||
gettextsettings(&settings);
|
||||
settextstyle(ST1().i, settings.direction, TOP().i);
|
||||
DROP(2);
|
||||
}
|
||||
|
||||
void s_direction() {
|
||||
struct textsettingstype settings;
|
||||
gettextsettings(&settings);
|
||||
settextstyle(settings.font, TOP().i, settings.charsize);
|
||||
DROP(1);
|
||||
}
|
||||
|
||||
void s_moveto() {
|
||||
moveto(ST1().i, TOP().i);
|
||||
DROP(2);
|
||||
}
|
||||
|
||||
void s_pos() {
|
||||
PUSHI(getx());
|
||||
PUSHI(gety());
|
||||
}
|
||||
|
||||
void s_setcolor() {
|
||||
setcolor(TOP().i);
|
||||
DROP(1);
|
||||
}
|
||||
|
||||
void s_setbgcolor() {
|
||||
setbkcolor(TOP().i);
|
||||
DROP(1);
|
||||
}
|
||||
|
||||
void s_clear() {
|
||||
cleardevice();
|
||||
}
|
||||
|
||||
void slide_init() {
|
||||
CDEF("bgi-on", bgi_init);
|
||||
CDEF("bgi-off", bgi_shutdown);
|
||||
CDEF("outtext", s_outtext);
|
||||
CDEF("justify", s_justify);
|
||||
CDEF("font", s_font);
|
||||
CDEF("direction", s_direction);
|
||||
CDEF("moveto", s_moveto);
|
||||
CDEF("pos", s_pos);
|
||||
CDEF("color!", s_setcolor);
|
||||
CDEF("bg!", s_setbgcolor);
|
||||
CDEF("wipe", s_clear);
|
||||
atexit(bgi_shutdown);
|
||||
}
|
181
slide.jor
Executable file
181
slide.jor
Executable file
|
@ -0,0 +1,181 @@
|
|||
( K E Y B O A R D )
|
||||
57 const ^SPACE
|
||||
75 const ^LEFT
|
||||
77 const ^RIGHT
|
||||
51 const ^<
|
||||
52 const ^>
|
||||
31 const ^S
|
||||
59 const ^F1
|
||||
|
||||
0 const BLACK
|
||||
1 const BLUE
|
||||
2 const GREEN
|
||||
3 const CYAN
|
||||
4 const RED
|
||||
5 const MAGENTA
|
||||
6 const BROWN
|
||||
7 const LGRAY
|
||||
8 const DGRAY
|
||||
9 const LBLUE
|
||||
10 const LGREEN
|
||||
11 const LCYAN
|
||||
12 const PINK
|
||||
13 const LMAGENTA
|
||||
14 const YELLOW
|
||||
15 const WHITE
|
||||
|
||||
: rungame
|
||||
0 player.state DRIVING f!
|
||||
1 showmouse !
|
||||
[ MODE-MOVE @ lit ] dup MODE-MOVE ! ' tick redefine
|
||||
' full-draw ' draw redefine
|
||||
12 11 tile>world player entity.pos!
|
||||
bgi-off 320x200 loadportraits
|
||||
s" pete.jor" loadfile
|
||||
begin suspend again ;
|
||||
|
||||
( S L I D E )
|
||||
var skip
|
||||
var autoslide
|
||||
: pause
|
||||
skip @ not if
|
||||
begin
|
||||
suspend 0
|
||||
^< key-pressed if drop 1 1 skip ! -1 autoslide ! then
|
||||
^> key-pressed if drop 1 1 skip ! 1 autoslide ! then
|
||||
^S key-pressed if drop 1 1 skip ! then
|
||||
^RIGHT key-pressed ^SPACE key-pressed or if drop 1 then
|
||||
^F1 key-pressed if rungame then
|
||||
until
|
||||
then ;
|
||||
|
||||
defer write
|
||||
: y pos swap drop ;
|
||||
: nexty ( dy -- y ) y + ;
|
||||
: writeline ( s x dy ) nexty <rot outtext moveto ;
|
||||
|
||||
: header :| 320 50 writeline |; ' write redefine
|
||||
wipe BLUE bg! 1 5 font 1 justify WHITE color! 320 10 moveto ;
|
||||
|
||||
: bullet :| 30 30 writeline |; ' write redefine
|
||||
3 3 font 0 justify LCYAN color! 30 y 30 + moveto ;
|
||||
|
||||
: goof :| 320 60 writeline |; ' write redefine
|
||||
wipe 4 7 font 1 justify CYAN color! 320 100 moveto ;
|
||||
|
||||
( S L I D E S )
|
||||
|
||||
' noop
|
||||
:noname 12 11 tile>world player entity.pos!
|
||||
s" pete.jor" loadfile ;
|
||||
:noname :| player yield 0 |; ' entities redefine
|
||||
0 player.state DRIVING f!
|
||||
1 showmouse ! MODE-MOVE @ ' tick redefine
|
||||
12 11 tile>world player entity.pos!
|
||||
loadportraits ;
|
||||
:noname s" hide-footer" REPL send ;
|
||||
:noname s" show-footer" REPL send ;
|
||||
:noname :| player yield 0 |; ' entities redefine
|
||||
1 player.state DRIVING f! E player entity.dir ! ;
|
||||
:noname :| 0 |; ' entities redefine 0 showmouse ! ;
|
||||
array demostates , , , , , , ,
|
||||
var demostate
|
||||
|
||||
: enterdemostate
|
||||
demostate @ cells demostates + @ execute ;
|
||||
|
||||
: tick-nextslide
|
||||
^SPACE key-pressed if 1 demostate +! enterdemostate then ;
|
||||
|
||||
: demotick
|
||||
tick-nextslide
|
||||
0 ^LEFT key-down if 3 - then
|
||||
^RIGHT key-down if 3 + then
|
||||
0 ^UP key-down if 3 - then
|
||||
^DOWN key-down if 3 + then
|
||||
player entity.y +!
|
||||
player entity.x +!
|
||||
tick-mapedit
|
||||
tick-debounce ;
|
||||
|
||||
: autoadvance autoslide @ not if 1 autoslide ! then ;
|
||||
: demo ( endstate startstate -- )
|
||||
bgi-off 320x200
|
||||
' full-draw ' draw redefine
|
||||
' demotick ' tick redefine
|
||||
demostate ! enterdemostate
|
||||
begin suspend dup demostate @ <= until drop
|
||||
' noop ' draw redefine
|
||||
' noop ' tick redefine
|
||||
bgi-on autoadvance ;
|
||||
|
||||
var demorepldone
|
||||
: quit 1 demorepldone ! ;
|
||||
: start-demorepl activate ' putc task-emit !
|
||||
s" .:: J O R T H ( jean forth) ::." type cr
|
||||
begin receive loadstring s" ok" type cr again ;
|
||||
task const DEMOREPL
|
||||
array replbuf 256 allot
|
||||
|
||||
: demorepl
|
||||
bgi-off key-end 0 demorepldone !
|
||||
DEMOREPL start-demorepl suspend
|
||||
begin replbuf gets DEMOREPL send suspend
|
||||
demorepldone @ until
|
||||
bgi-on key-start autoadvance ;
|
||||
|
||||
array filenamebuf 13 allot
|
||||
var filenameindex
|
||||
: store-fn-char filenamebuf filenameindex @ + b! ;
|
||||
: filename-emit
|
||||
dup [ key lit ] != if
|
||||
store-fn-char
|
||||
1 filenameindex +!
|
||||
0 store-fn-char
|
||||
else drop then ;
|
||||
|
||||
: slidefilename ( i -- s )
|
||||
task-emit @
|
||||
' filename-emit task-emit !
|
||||
0 filenameindex !
|
||||
s" slide" type
|
||||
swap .
|
||||
s" .jor" type
|
||||
task-emit !
|
||||
filenamebuf ;
|
||||
|
||||
var slidecount
|
||||
var slideindex
|
||||
|
||||
: skipto ( i -- )
|
||||
slideindex @ - autoslide ! 1 skip ! ;
|
||||
|
||||
: fixindex
|
||||
slideindex @ 0 < if slidecount @ 1 - slideindex ! else
|
||||
slideindex @ slidecount @ >= if 0 slideindex ! then then ;
|
||||
|
||||
: show ( i -- ) 0 skip ! 0 autoslide ! slidefilename loadjor ;
|
||||
: nextslide
|
||||
autoslide @ if
|
||||
autoslide @ slideindex +!
|
||||
else
|
||||
begin
|
||||
suspend
|
||||
^LEFT key-pressed ^< key-pressed or
|
||||
if -1 else
|
||||
^RIGHT key-pressed ^SPACE key-pressed or ^> key-pressed or
|
||||
if 1 else 0 then then
|
||||
dup if dup slideindex +! then
|
||||
until
|
||||
then fixindex ;
|
||||
|
||||
: slideshow activate blah
|
||||
bgi-on ' noop ' draw redefine ' noop ' tick redefine
|
||||
begin slideindex @ show nextslide again ;
|
||||
task const SLIDESHOW
|
||||
SLIDESHOW slideshow
|
||||
|
||||
:noname
|
||||
0 begin dup slidefilename exists while 1 + repeat slidecount !
|
||||
:| tick-nextslide [ MODE-MOVE @ , ] |; MODE-MOVE !
|
||||
; ' onload redefine
|
8
slide0.jor
Executable file
8
slide0.jor
Executable file
|
@ -0,0 +1,8 @@
|
|||
MAGENTA bg!
|
||||
goof
|
||||
s" What A 30-Year" write
|
||||
s" Old PC Can Teach" write
|
||||
s" Us About Graphic" write
|
||||
s" Design" write pause
|
||||
BLUE bg! bullet
|
||||
s" (just kidding)" write
|
4
slide1.jor
Executable file
4
slide1.jor
Executable file
|
@ -0,0 +1,4 @@
|
|||
header 320 180 moveto
|
||||
s" Building Your Own Tools" write pause
|
||||
bullet
|
||||
s" Or, Be Moore Like Chuck" write
|
16
slide10.jor
Executable file
16
slide10.jor
Executable file
|
@ -0,0 +1,16 @@
|
|||
header
|
||||
s" Things Jorth is missing" write pause
|
||||
bullet
|
||||
s" * Garbage collection" write pause
|
||||
s" * Dynamic memory allocation" write pause
|
||||
s" * Garbage" write pause
|
||||
s" * Memory safety" write pause
|
||||
s" * Error reporting" write pause
|
||||
s" * Static types" write pause
|
||||
s" * Dynamic types" write pause
|
||||
s" * Objects" write pause
|
||||
s" * Polymorphic methods" write pause
|
||||
s" * Closures" write pause
|
||||
s" * Flow control (in the interpreter)" write pause
|
||||
s" * Local variables" write pause
|
||||
s" * Syntax" write
|
10
slide11.jor
Executable file
10
slide11.jor
Executable file
|
@ -0,0 +1,10 @@
|
|||
header
|
||||
s" Things Jorth has" write
|
||||
bullet
|
||||
s" * An interactive embedded REPL" write pause
|
||||
s" * Lightweight co-operative multitasking" write pause
|
||||
s" * A C FFI" write pause
|
||||
s" * An extensible compiler, defined in itself" write pause
|
||||
s" * The ability to fit comfortably in 16kb of RAM" write pause
|
||||
s" * An entire codebase I completely understand" write
|
||||
s" and am willing to change to fit my problem" write
|
15
slide12.jor
Executable file
15
slide12.jor
Executable file
|
@ -0,0 +1,15 @@
|
|||
header
|
||||
s" Jorth Crash Course" write
|
||||
s" Syntax & Semantics" write
|
||||
bullet
|
||||
s" * Read text until a space is encountered" write pause
|
||||
s" * Look up word in dictionary" write pause
|
||||
s" * If a definition is found: Execute it" write pause
|
||||
s" * Otherwise: Parse it as a number" write pause
|
||||
s" * Otherwise: Give up" write pause
|
||||
s" * Postfix / Reverse Polish Notation" write
|
||||
s" parameters and return values live on The Stack" write pause
|
||||
s" * D E M O !" write pause
|
||||
demorepl
|
||||
|
||||
|
9
slide13.jor
Executable file
9
slide13.jor
Executable file
|
@ -0,0 +1,9 @@
|
|||
header
|
||||
s" Jorth Crash Course" write
|
||||
s" The Jorth Virtual Machine" write
|
||||
bullet
|
||||
s" while (IP.p) {" write
|
||||
s" W = *IP.p;" write
|
||||
s" IP.p++;" write
|
||||
s" W.p->f();" write
|
||||
s" }" write
|
11
slide14.jor
Executable file
11
slide14.jor
Executable file
|
@ -0,0 +1,11 @@
|
|||
header
|
||||
s" Jorth Crash Course" write
|
||||
s" Calling Conventions" write
|
||||
bullet
|
||||
s" void f_docolon() {" write
|
||||
s" RPUSH(IP);" write
|
||||
s" IP.p = W.p + 1;" write
|
||||
s" }" write pause
|
||||
s" void f_ret() { " write
|
||||
s" IP = *RPOP();" write
|
||||
s" }" write
|
14
slide15.jor
Executable file
14
slide15.jor
Executable file
|
@ -0,0 +1,14 @@
|
|||
header
|
||||
s" Jorth Crash Course" write
|
||||
s" Writing Jorth In Itself" write
|
||||
bullet
|
||||
s" : begin here ; immediate" write
|
||||
s" : until ' BZ_ , , ; immediate" write pause
|
||||
s" " write
|
||||
s" : if ' BZ_ , here 0 , ; immediate" write
|
||||
s" : then here swap ! ; immediate" write pause
|
||||
s" " write
|
||||
s" : ( begin key ')' = until ; immediate" write
|
||||
|
||||
|
||||
|
8
slide16.jor
Executable file
8
slide16.jor
Executable file
|
@ -0,0 +1,8 @@
|
|||
header
|
||||
s" What Good Was It?" write
|
||||
bullet
|
||||
s" * Jorth soon spread to every part of the project" write pause
|
||||
s" * C for the hardware, Jorth for everything else" write pause
|
||||
s" * All game & drawing logic" write pause
|
||||
s" * Map editing" write pause
|
||||
6 4 demo
|
9
slide17.jor
Executable file
9
slide17.jor
Executable file
|
@ -0,0 +1,9 @@
|
|||
header
|
||||
s" Entirely Intuitive Results" write
|
||||
bullet
|
||||
s" * Forth does not scale up" write pause
|
||||
s" * Arranging postfix expressions without local" write
|
||||
s" variables is hard" write pause
|
||||
s" * It's too easy to fill 64kb of memory" write pause
|
||||
s" * This would have been impossible without" write
|
||||
s" the internet" write
|
16
slide18.jor
Executable file
16
slide18.jor
Executable file
|
@ -0,0 +1,16 @@
|
|||
header
|
||||
s" Counterintuitive Results" write
|
||||
bullet
|
||||
s" * Complicated Forth code is AWFUL..." write pause
|
||||
s" ... which is a powerful force for simplicity" write pause
|
||||
s" * Virtually ALL state is global..." write pause
|
||||
s" ... which makes it all visible when debugging" write pause
|
||||
s" ... and which lets code stay small and focussed" write pause
|
||||
s" * Hard to tell what a word might do..." write pause
|
||||
s" ... but this makes huge implementation" write
|
||||
s" changes possible!" write pause
|
||||
s" * The most flexible abstraction may be the tiniest" write pause
|
||||
s" * It's easier to write my own!" write pause
|
||||
s" * Map editor" write pause
|
||||
s" * Music livecoding REPL (<300 LOC!)" write pause
|
||||
s" * This presentation software (<200 LOC!)" write
|
4
slide19.jor
Executable file
4
slide19.jor
Executable file
|
@ -0,0 +1,4 @@
|
|||
header
|
||||
s" I should shut up now" write pause
|
||||
goof CYAN bg! MAGENTA color!
|
||||
s" Questions?" write
|
6
slide2.jor
Executable file
6
slide2.jor
Executable file
|
@ -0,0 +1,6 @@
|
|||
header
|
||||
s" Background" write
|
||||
bullet
|
||||
s" I decided to write a game" write pause
|
||||
s" for a 30-year-old computer" write pause
|
||||
s" on a 30-year-old computer" write
|
6
slide3.jor
Executable file
6
slide3.jor
Executable file
|
@ -0,0 +1,6 @@
|
|||
header
|
||||
s" WHY?!" write pause
|
||||
bullet
|
||||
s" * I fell in love with MS-DOS" write pause
|
||||
s" * I wanted to see if I could" write pause
|
||||
s" * Learning is fun" write
|
30
slide4.jor
Executable file
30
slide4.jor
Executable file
|
@ -0,0 +1,30 @@
|
|||
header
|
||||
s" What were my restrictions?" write
|
||||
bullet
|
||||
s" * Turbo C++ 1.0 (C & assembler)" write pause
|
||||
s" * 16-bit real-mode x86" write pause
|
||||
pos s" * 640kb of RAM" write pause
|
||||
moveto s" -----" write
|
||||
pos s" * ~550-600kb of RAM" write pause
|
||||
moveto s" ----------" write
|
||||
s" * 64kb of code, 64kb of data," write
|
||||
s" 256kb of video memory" write pause
|
||||
s" * E" outtext
|
||||
2 color! s" G" outtext
|
||||
3 color! s" A " outtext
|
||||
4 color! s" G" outtext
|
||||
5 color! s" r" outtext
|
||||
6 color! s" a" outtext
|
||||
7 color! s" p" outtext
|
||||
8 color! s" h" outtext
|
||||
9 color! s" i" outtext
|
||||
10 color! s" c" outtext
|
||||
11 color! s" s" outtext
|
||||
12 color! s" !" outtext
|
||||
13 color! s" !" outtext
|
||||
14 color! s" !" write
|
||||
LCYAN color!
|
||||
s" * 320x200 pixel resolution, 16 colours" write pause
|
||||
s" * AdLib sound" write
|
||||
s" * FM synthesis - no digital sampling" write pause
|
||||
s" * All work done ON THE 286" write
|
11
slide5.jor
Executable file
11
slide5.jor
Executable file
|
@ -0,0 +1,11 @@
|
|||
header
|
||||
s" How would I learn all this?" write
|
||||
bullet
|
||||
pos s" * StackOverflow" write pause
|
||||
moveto s" -----------" write pause
|
||||
s" * Graphics Programming Black Book" write
|
||||
s" by Michael Abrash" write pause
|
||||
s" * Teach Yourself Game Programming in 21 Days" write
|
||||
s" by Andre LaMothe" write pause
|
||||
s" * Commander Keen Dreams source code" write pause
|
||||
s" * Google... sometimes helped" write
|
8
slide6.jor
Executable file
8
slide6.jor
Executable file
|
@ -0,0 +1,8 @@
|
|||
header
|
||||
s" First Steps" write
|
||||
bullet
|
||||
s" * Could I write a tile engine?" write pause
|
||||
s" * Stretch goal: Could I make it scroll smoothly?" write pause
|
||||
s" * And obviously I've got to draw stuff on top..." write pause
|
||||
s" * Ooh, what about a stationary HUD?" write pause
|
||||
3 0 demo
|
7
slide7.jor
Executable file
7
slide7.jor
Executable file
|
@ -0,0 +1,7 @@
|
|||
BLUE bg!
|
||||
header
|
||||
s" Problems: One Month In" write
|
||||
bullet
|
||||
s" * Game logic was messy" write pause
|
||||
s" * Debugging is hard!" write pause
|
||||
s" * How to edit maps?" write
|
20
slide8.jor
Executable file
20
slide8.jor
Executable file
|
@ -0,0 +1,20 @@
|
|||
header
|
||||
s" I know, I'll just..." write pause
|
||||
s" WRITE MY OWN" write
|
||||
s" SCRIPTING LANGUAGE" write pause
|
||||
bullet
|
||||
s" What could POSSIBLY go wrong??" write pause
|
||||
|
||||
header
|
||||
s" @SpindleyQ" write pause
|
||||
bullet
|
||||
s" ohhh noooo I am definitely going to" write
|
||||
s" write a 16-bit x86 Forth as a scripting" write
|
||||
s" language for my game, this is happeniiiiing" write pause
|
||||
|
||||
header
|
||||
s" @mogwai_poet" write pause
|
||||
bullet
|
||||
s" @SpindleyQ Have you used forth before?" write
|
||||
s" It's like programming assembly" write
|
||||
s" on a CPU designed by an alien." write
|
8
slide9.jor
Executable file
8
slide9.jor
Executable file
|
@ -0,0 +1,8 @@
|
|||
header
|
||||
s" FORTH" write
|
||||
bullet
|
||||
s" * Invented by Chuck Moore around 1970" write pause
|
||||
s" * Still used in embedded systems & firmware" write pause
|
||||
s" * The tiniest possible useful language" write pause
|
||||
s" * 'If you've seen one Forth, you've seen one forth'" write pause
|
||||
s" * I called mine Jorth ( jean forth)" write
|
19
slidenot.es
Executable file
19
slidenot.es
Executable file
|
@ -0,0 +1,19 @@
|
|||
: slideNotes
|
||||
bullet
|
||||
s" * The tiniest abstraction may be the most flexible" write
|
||||
s" (if you're willing to trade off 'safety')" write
|
||||
|
||||
* Forth is really, really good for one person who understands everything
|
||||
* It is not necessarily great for complex problems
|
||||
(Change the problem!)
|
||||
* It is not necessarily great for co-operation
|
||||
(write-only language)
|
||||
* It's kind of an anti-social language
|
||||
(not least because you want to talk about it at length once you learn it!)
|
||||
|
||||
Challenges:
|
||||
* I spent a couple of hours figuring out how to free up enough
|
||||
memory in the data segment to hold my game engine, Jorth data,
|
||||
graphics data, and the slide fonts, all at the same time
|
||||
* Then I wrote some more slides and ran out of RAM to store all
|
||||
the text, so I
|
95
testbed.c
95
testbed.c
|
@ -1,6 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dos.h>
|
||||
#include <alloc.h>
|
||||
|
||||
#include "video.h"
|
||||
#include "kbd.h"
|
||||
|
@ -12,6 +13,7 @@
|
|||
#include "jorth.h"
|
||||
#include "egamap.h"
|
||||
#include "adlib.h"
|
||||
#include "slide.h"
|
||||
|
||||
/*** T E X T ***/
|
||||
char far *font = NULL;
|
||||
|
@ -54,11 +56,23 @@ void text_draw(unsigned int vidOffset, unsigned char *s) {
|
|||
#define NUM_SPRITES 64
|
||||
#define TILE_STRIDE 64
|
||||
#define SPRITE_STRIDE 80
|
||||
unsigned int tiles[NUM_TILES * TILE_STRIDE];
|
||||
unsigned int sprites[NUM_SPRITES * SPRITE_STRIDE];
|
||||
|
||||
unsigned int far *tiles;
|
||||
unsigned int far *sprites;
|
||||
unsigned char map[10000];
|
||||
|
||||
void allocate_gfx() {
|
||||
unsigned long memleft = farcoreleft();
|
||||
tiles = farmalloc(NUM_TILES * TILE_STRIDE);
|
||||
sprites = farmalloc(NUM_SPRITES * SPRITE_STRIDE);
|
||||
if (!tiles || !sprites) {
|
||||
printf("%lu bytes free - need %lu\n", memleft,
|
||||
(unsigned long)
|
||||
((NUM_TILES * TILE_STRIDE) +
|
||||
(NUM_SPRITES * SPRITE_STRIDE)));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void fillMap() {
|
||||
unsigned int x, y, z;
|
||||
z = 0;
|
||||
|
@ -74,6 +88,8 @@ void game_init() {
|
|||
FILE *f;
|
||||
TifImageMeta_t meta;
|
||||
|
||||
allocate_gfx();
|
||||
|
||||
mouse_init();
|
||||
|
||||
setEGAMode();
|
||||
|
@ -125,13 +141,16 @@ void f_keyWasPressed() {
|
|||
TOP().i = keyWasPressed(k);
|
||||
consumeKey(k);
|
||||
}
|
||||
|
||||
void f_keyIsDown() {
|
||||
TOP().i = keyIsDown(TOP().i);
|
||||
}
|
||||
|
||||
void f_drawSprite() { // ( x y sprite -- )
|
||||
drawSprite(&sprites[TOP().i * SPRITE_STRIDE], ST2().i, ST1().i);
|
||||
DROP(3);
|
||||
}
|
||||
|
||||
void f_scroll() { // ( x y -- )
|
||||
scroll(ST1().i, TOP().i);
|
||||
DROP(2);
|
||||
|
@ -141,9 +160,11 @@ void f_scrollpos() { // ( -- x y )
|
|||
PUSHI(screen.scrollX);
|
||||
PUSHI(screen.scrollY);
|
||||
}
|
||||
|
||||
void f_ticks() {
|
||||
PUSHU(timer_counter);
|
||||
}
|
||||
|
||||
void f_splitscreen() {
|
||||
setSplitScreen(399 - (TOP().i << 1));
|
||||
DROP(1);
|
||||
|
@ -199,11 +220,51 @@ void f_adlib() {
|
|||
DROP(2);
|
||||
}
|
||||
|
||||
cell f_atexit;
|
||||
void f_cleanup() {
|
||||
f_execcp(f_atexit);
|
||||
}
|
||||
|
||||
void f_320x200() {
|
||||
FILE *f;
|
||||
TifImageMeta_t meta;
|
||||
|
||||
setEGAMode();
|
||||
tile_init();
|
||||
|
||||
f = fopen("FOOTER2.TIF", "rb");
|
||||
meta = tifLoadMeta(f);
|
||||
tifLoadEGA(f, meta, 0, 48, 336);
|
||||
fclose(f);
|
||||
|
||||
f = fopen("TILES.TIF", "rb");
|
||||
meta = tifLoadMeta(f);
|
||||
tifLoadEGA(f, meta, OFF_TILES, NUM_TILES * 16, 16);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void f_loadportraits() {
|
||||
FILE *f;
|
||||
TifImageMeta_t meta;
|
||||
|
||||
f = fopen("FOOTER.TIF", "rb");
|
||||
meta = tifLoadMeta(f);
|
||||
tifLoadEGA(f, meta, 0, 48, 336);
|
||||
fclose(f);
|
||||
|
||||
f = fopen("PORTRAIT.TIF", "rb");
|
||||
meta = tifLoadMeta(f);
|
||||
tifLoadEGA(f, meta, OFF_PORTRAITS, NUM_PORTRAITS * 32, 32);
|
||||
fclose(f);
|
||||
|
||||
}
|
||||
void game_f_init(char *exe) {
|
||||
f_init(exe);
|
||||
CDEF("seremit", f_seremit);
|
||||
CDEF("key-pressed", f_keyWasPressed);
|
||||
CDEF("key-down", f_keyIsDown);
|
||||
CDEF("key-start", kbd_init);
|
||||
CDEF("key-end", kbd_cleanup);
|
||||
CDEF("draw-sprite", f_drawSprite);
|
||||
CDEF("draw-portrait", f_drawportrait);
|
||||
CDEF("scroll", f_scroll);
|
||||
|
@ -219,33 +280,25 @@ void game_f_init(char *exe) {
|
|||
CDEF("mousepos", f_mousepos);
|
||||
CDEF("mousebuttons", f_mousebuttons);
|
||||
CDEF("unfuck", tile_init);
|
||||
CDEF("320x200", f_320x200);
|
||||
CDEF("loadportraits", f_loadportraits);
|
||||
|
||||
slide_init();
|
||||
f_loadjor("gameboot.jor");
|
||||
|
||||
f_atexit = f_lookupcp("atexit");
|
||||
atexit(f_cleanup);
|
||||
|
||||
}
|
||||
|
||||
void f_poll() {
|
||||
static char line[128] = { 0 };
|
||||
|
||||
int i = strlen(line);
|
||||
int value;
|
||||
for (value = ser_poll(); value != SER_NODATA; value = ser_poll()) {
|
||||
if (value == '\b' || value == 127) {
|
||||
i --;
|
||||
} else {
|
||||
line[i] = value;
|
||||
i ++;
|
||||
}
|
||||
line[i] = '\0';
|
||||
ser_write_byte(value); // echo
|
||||
|
||||
if (value == '\r') {
|
||||
line[i - 1] = '\n';
|
||||
ser_write_byte('\n');
|
||||
while (ser_getline(line)) {
|
||||
PUSHS(line);
|
||||
f_runstring("REPL send");
|
||||
f_taskloop();
|
||||
i = 0;
|
||||
line[i] = '\0';
|
||||
}
|
||||
line[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
tiff.c
12
tiff.c
|
@ -117,7 +117,7 @@ int tifLoadEGA(FILE *f, TifImageMeta_t meta, unsigned int vidOffset, int maxY, u
|
|||
return y;
|
||||
}
|
||||
|
||||
int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int yRepeat, int planes) {
|
||||
int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int far *planeBuf, int maxY, int yRepeat, int planes) {
|
||||
int istrip;
|
||||
int irow;
|
||||
int ipixelpair;
|
||||
|
@ -125,11 +125,11 @@ int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int
|
|||
unsigned long offset;
|
||||
unsigned char rowData[MAX_WIDTH >> 1];
|
||||
unsigned int planeStride = (meta.width >> 4) * yRepeat;
|
||||
unsigned int *bp = planeBuf;
|
||||
unsigned int *gp = bp + planeStride;
|
||||
unsigned int *rp = gp + planeStride;
|
||||
unsigned int *ip = rp + planeStride;
|
||||
unsigned int *mp = ip + planeStride;
|
||||
unsigned int far *bp = planeBuf;
|
||||
unsigned int far *gp = bp + planeStride;
|
||||
unsigned int far *rp = gp + planeStride;
|
||||
unsigned int far *ip = rp + planeStride;
|
||||
unsigned int far *mp = ip + planeStride;
|
||||
unsigned int bv, gv, rv, iv;
|
||||
|
||||
if (meta.width > MAX_WIDTH || (meta.width % 16) != 0 || planes < 4 || planes > 5) {
|
||||
|
|
2
tiff.h
2
tiff.h
|
@ -14,4 +14,4 @@ typedef struct {
|
|||
|
||||
TifImageMeta_t tifLoadMeta(FILE *f);
|
||||
int tifLoadEGA(FILE *f, TifImageMeta_t meta, unsigned int vidOffset, int maxY, unsigned int w);
|
||||
int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int yRepeat, int planes);
|
||||
int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int far *planeBuf, int maxY, int yRepeat, int planes);
|
||||
|
|
14
tiles.c
14
tiles.c
|
@ -52,7 +52,7 @@ void blit32x32(unsigned int offsetFrom, unsigned int offsetTo) {
|
|||
TiledScreen_t screen = { 0, 0, 0, 0, { OFF_PAGE1, OFF_PAGE2 }, 0, 0, NULL, NULL,
|
||||
0, 0, 0, 0, 0 };
|
||||
|
||||
void loadTiles(unsigned int tilesOffset, unsigned int *memTiles) {
|
||||
void loadTiles(unsigned int tilesOffset, unsigned int far *memTiles) {
|
||||
screen.tilesOffset = tilesOffset;
|
||||
screen.memTiles = memTiles;
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ void loadMap(unsigned char *map, unsigned int w, unsigned int h) {
|
|||
|
||||
int prepareBuffer(int pageX, int pageY) {
|
||||
unsigned char *dirty = &screen.dirty[screen.currentPage][pageX + (pageY * PAGE_TILES_W)];
|
||||
int i;
|
||||
if (!isBufIndex(*dirty)) {
|
||||
unsigned int startX = screen.scrollX >> 4;
|
||||
unsigned int startY = screen.scrollY >> 4;
|
||||
|
@ -73,15 +74,18 @@ int prepareBuffer(int pageX, int pageY) {
|
|||
unsigned char ibuffer = screen.nextBuffer;
|
||||
screen.nextBuffer = nextBufferIndex(ibuffer);
|
||||
*dirty = ibuffer;
|
||||
memcpy(screen.buffer[ibuffer], &screen.memTiles[tile * BUF_WSIZE], BUF_WSIZE << 1);
|
||||
for (i = 0; i < BUF_WSIZE; i ++) {
|
||||
screen.buffer[ibuffer][i] = (&screen.memTiles[tile * BUF_WSIZE])[i];
|
||||
}
|
||||
screen.bufferOffset[ibuffer] = screen.pageOffset[screen.currentPage]
|
||||
+ (pageX << 1) + (pageY * PAGE_STRIDE * 16);
|
||||
}
|
||||
return *dirty;
|
||||
}
|
||||
|
||||
void drawSpriteToBuf(unsigned int *sprite, int pageX, int pageY, int shift, int yStart) {
|
||||
unsigned int *buf, *mask;
|
||||
void drawSpriteToBuf(unsigned int far *sprite, int pageX, int pageY, int shift, int yStart) {
|
||||
unsigned int *buf;
|
||||
unsigned int far *mask;
|
||||
unsigned int maskval;
|
||||
int y, h, plane;
|
||||
if (pageX < 0 || pageY < 0 ||
|
||||
|
@ -122,7 +126,7 @@ void drawSpriteToBuf(unsigned int *sprite, int pageX, int pageY, int shift, int
|
|||
}
|
||||
}
|
||||
|
||||
void drawSprite(unsigned int *sprite, int x, int y) {
|
||||
void drawSprite(unsigned int far *sprite, int x, int y) {
|
||||
int pageX = (int)(x - (screen.scrollX & 0xfff0)) >> 4;
|
||||
int pageY = (int)(y - (screen.scrollY & 0xfff0)) >> 4;
|
||||
int pageOffsetX = x & 0x0f;
|
||||
|
|
8
tiles.h
8
tiles.h
|
@ -4,9 +4,9 @@
|
|||
|
||||
void tile_init();
|
||||
|
||||
void loadTiles(unsigned int tilesOffset, unsigned int *memTiles);
|
||||
void loadTiles(unsigned int tilesOffset, unsigned int far *memTiles);
|
||||
void loadMap(unsigned char *map, unsigned int w, unsigned int h);
|
||||
void drawSprite(unsigned int *sprite, int x, int y);
|
||||
void drawSprite(unsigned int far *sprite, int x, int y);
|
||||
void scroll(int newX, int newY);
|
||||
void drawScreen();
|
||||
|
||||
|
@ -17,7 +17,7 @@ void blit32x32(unsigned int offsetFrom, unsigned int offsetTo);
|
|||
#define PAGE_TILES_COUNT (PAGE_TILES_H * PAGE_TILES_W)
|
||||
#define PAGE_STRIDE (PAGE_TILES_W << 1)
|
||||
|
||||
#define NUM_BUFFERS 32
|
||||
#define NUM_BUFFERS 20
|
||||
#define BUF_WSTRIDE 16
|
||||
#define BUF_WSIZE (BUF_WSTRIDE * 4)
|
||||
|
||||
|
@ -29,7 +29,7 @@ typedef struct {
|
|||
unsigned int pageOffset[2];
|
||||
unsigned char dirty[2][PAGE_TILES_COUNT];
|
||||
unsigned int tilesOffset;
|
||||
unsigned int *memTiles;
|
||||
unsigned int far *memTiles;
|
||||
unsigned char *map;
|
||||
unsigned int buffer[NUM_BUFFERS][BUF_WSIZE];
|
||||
unsigned int bufferOffset[NUM_BUFFERS];
|
||||
|
|
Loading…
Reference in a new issue