Presentation slides with demo

move sprites + tiles to far memory to free up space
This commit is contained in:
Jeremy Penner 2019-04-25 21:55:23 -04:00
parent 6c4e5ff396
commit 64d421429e
49 changed files with 651 additions and 52 deletions

2
.gitignore vendored
View file

@ -4,4 +4,4 @@
*.swp *.swp
*.log *.log
*.jim *.jim
game.map

View file

@ -1,6 +1,6 @@
#include "tiles.h" #include "tiles.h"
#define NUM_TILES 128 #define NUM_TILES 64
#define NUM_PORTRAITS 16 #define NUM_PORTRAITS 16
#define SIZE_FOOTER (PAGE_STRIDE * 48) #define SIZE_FOOTER (PAGE_STRIDE * 48)

BIN
egavga.bgi Executable file

Binary file not shown.

BIN
footer2.tif Executable file

Binary file not shown.

BIN
game.exe

Binary file not shown.

View file

@ -112,9 +112,6 @@ player :tick
;entity ;entity
( S T U F F ) ( S T U F F )
: hello-world
player.state DRIVING fnot! ;
: reset-level : reset-level
:| player yield 0 |; ' entities redefine :| player yield 0 |; ' entities redefine
:| drop drop 0 |; ' player-touch redefine ; :| drop drop 0 |; ' player-touch redefine ;
@ -122,9 +119,6 @@ player :tick
: mode-move : mode-move
entities each EVTICK entity>do more entities each EVTICK entity>do more
tick-mapedit tick-mapedit
^SPACE key-pressed if
' hello-world JOB send
then
tick-debounce tick-debounce
q-level @ dup if q-level @ dup if
0 q-level ! 0 q-level !
@ -141,13 +135,17 @@ player :tick
r@ entity.dir @ r< entity>sprite r@ entity.dir @ r< entity>sprite
draw-sprite ; draw-sprite ;
var showmouse
1 showmouse !
: full-draw : full-draw
player entity.x @ 152 - player entity.x @ 152 -
player entity.y @ 92 - player entity.y @ 92 -
scroll scroll
entities each draw-entity more entities each draw-entity more
mouseworldpos 4 draw-sprite showmouse @ if
mouseworldpos 4 draw-sprite
then
draw-screen draw-screen
draw-footer ; draw-footer ;

BIN
game.prj

Binary file not shown.

View file

@ -1,7 +1,11 @@
: blah ' seremit task-emit ! ; : blah ' seremit task-emit ! ;
blah 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 s" .:: J O R T H ( jean forth) ::." type cr
begin receive loadstring s" ok" type cr again ; begin receive loadstring s" ok" type cr again ;
task const REPL task const REPL
@ -19,6 +23,7 @@ s" footer.jor" loadfile
s" map.jor" loadfile s" map.jor" loadfile
s" game.jor" loadfile s" game.jor" loadfile
s" state.jor" loadfile s" state.jor" loadfile
s" slide.jor" loadfile
; execute ; execute
intern pete.jor intern pete.jor
@ -30,4 +35,4 @@ intern trail1.jor
:noname loadfile ; checkpoint _loadlevel :noname loadfile ; checkpoint _loadlevel
' _loadlevel ' loadlevel redefine ' _loadlevel ' loadlevel redefine
pete.jor loadlevel ( pete.jor loadlevel )

BIN
goth.chr Executable file

Binary file not shown.

BIN
jopl.exe

Binary file not shown.

View file

@ -228,6 +228,7 @@ var t2
: ontick startt2 player status trackstatus ; : ontick startt2 player status trackstatus ;
: files findfile begin dup while yield findnext repeat ; : files findfile begin dup while yield findnext repeat ;
: .files files each type s" " type more ;
: keynote [ inline| : 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, 44 b, 31 b, 45 b, 32 b, 46 b, 47 b, 34 b, 48 b, 35 b, 49 b, 36 b, 50 b,

BIN
jopl.prj

Binary file not shown.

12
jorth.c
View file

@ -342,6 +342,10 @@ void f_fputc() {
DROP(1); DROP(1);
} }
void f_gets() {
gets(TOP().s);
}
void f_fput() { void f_fput() {
if (ACTIVE_FILE) { if (ACTIVE_FILE) {
fwrite(&TOP().u, 2, 1, ACTIVE_FILE); fwrite(&TOP().u, 2, 1, ACTIVE_FILE);
@ -747,6 +751,12 @@ void f_tell() {
PUSHU(ftell(ACTIVE_FILE)); PUSHU(ftell(ACTIVE_FILE));
} }
void f_exists() {
struct stat statbuf;
int rc = stat(TOP().s, &statbuf);
TOP().i = rc == 0;
}
void f_swapinput() { void f_swapinput() {
cell *key = RUNNING + TASK_USER_KEY; cell *key = RUNNING + TASK_USER_KEY;
cell *keysrc = RUNNING + TASK_USER_KEYSRC; cell *keysrc = RUNNING + TASK_USER_KEYSRC;
@ -1111,6 +1121,7 @@ void f_init(char *exe) {
CDEF("swap-input", f_swapinput); CDEF("swap-input", f_swapinput);
CDEF("putc", f_putc); CDEF("putc", f_putc);
CDEF("fputc", f_fputc); CDEF("fputc", f_fputc);
CDEF("gets", f_gets);
CDEF("number", f_number); CDEF("number", f_number);
CDEF("LIT_", f_lit_); CDEF("LIT_", f_lit_);
CDEF("GOTO_", f_goto_); CDEF("GOTO_", f_goto_);
@ -1127,6 +1138,7 @@ void f_init(char *exe) {
CDEF("open", f_open); CDEF("open", f_open);
CDEF("overwrite", f_overwrite); CDEF("overwrite", f_overwrite);
CDEF("close", f_close); CDEF("close", f_close);
CDEF("exists", f_exists);
CDEF("factivate", f_activate); CDEF("factivate", f_activate);
CDEF("fdeactivate", f_deactivate); CDEF("fdeactivate", f_deactivate);
CDEF("seek", f_seek); CDEF("seek", f_seek);

BIN
litt.chr Executable file

Binary file not shown.

BIN
sans.chr Executable file

Binary file not shown.

View file

@ -85,3 +85,25 @@ void ser_write(char *str) {
ser_write_byte(*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;
}

View file

@ -19,10 +19,11 @@
#define BAUD_57600 0x0002 #define BAUD_57600 0x0002
#define BAUD_115200 0x0001 #define BAUD_115200 0x0001
#define SER_READ_BUFFER_SIZE 0x200 #define SER_READ_BUFFER_SIZE 64
#define SER_NODATA -1 #define SER_NODATA -1
void ser_init(int port, int baudrate, int protocol); void ser_init(int port, int baudrate, int protocol);
int ser_poll(); int ser_poll();
void ser_write_byte(char byte); void ser_write_byte(char byte);
void ser_write(char *str); void ser_write(char *str);
int ser_getline(char *line);

82
slide.c Executable file
View 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);
}

BIN
slide.exe Executable file

Binary file not shown.

1
slide.h Executable file
View file

@ -0,0 +1 @@
void slide_init();

181
slide.jor Executable file
View 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

BIN
slide.prj Executable file

Binary file not shown.

8
slide0.jor Executable file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

101
testbed.c
View file

@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <dos.h> #include <dos.h>
#include <alloc.h>
#include "video.h" #include "video.h"
#include "kbd.h" #include "kbd.h"
@ -12,6 +13,7 @@
#include "jorth.h" #include "jorth.h"
#include "egamap.h" #include "egamap.h"
#include "adlib.h" #include "adlib.h"
#include "slide.h"
/*** T E X T ***/ /*** T E X T ***/
char far *font = NULL; char far *font = NULL;
@ -54,11 +56,23 @@ void text_draw(unsigned int vidOffset, unsigned char *s) {
#define NUM_SPRITES 64 #define NUM_SPRITES 64
#define TILE_STRIDE 64 #define TILE_STRIDE 64
#define SPRITE_STRIDE 80 #define SPRITE_STRIDE 80
unsigned int tiles[NUM_TILES * TILE_STRIDE]; unsigned int far *tiles;
unsigned int sprites[NUM_SPRITES * SPRITE_STRIDE]; unsigned int far *sprites;
unsigned char map[10000]; 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() { void fillMap() {
unsigned int x, y, z; unsigned int x, y, z;
z = 0; z = 0;
@ -74,6 +88,8 @@ void game_init() {
FILE *f; FILE *f;
TifImageMeta_t meta; TifImageMeta_t meta;
allocate_gfx();
mouse_init(); mouse_init();
setEGAMode(); setEGAMode();
@ -125,13 +141,16 @@ void f_keyWasPressed() {
TOP().i = keyWasPressed(k); TOP().i = keyWasPressed(k);
consumeKey(k); consumeKey(k);
} }
void f_keyIsDown() { void f_keyIsDown() {
TOP().i = keyIsDown(TOP().i); TOP().i = keyIsDown(TOP().i);
} }
void f_drawSprite() { // ( x y sprite -- ) void f_drawSprite() { // ( x y sprite -- )
drawSprite(&sprites[TOP().i * SPRITE_STRIDE], ST2().i, ST1().i); drawSprite(&sprites[TOP().i * SPRITE_STRIDE], ST2().i, ST1().i);
DROP(3); DROP(3);
} }
void f_scroll() { // ( x y -- ) void f_scroll() { // ( x y -- )
scroll(ST1().i, TOP().i); scroll(ST1().i, TOP().i);
DROP(2); DROP(2);
@ -141,9 +160,11 @@ void f_scrollpos() { // ( -- x y )
PUSHI(screen.scrollX); PUSHI(screen.scrollX);
PUSHI(screen.scrollY); PUSHI(screen.scrollY);
} }
void f_ticks() { void f_ticks() {
PUSHU(timer_counter); PUSHU(timer_counter);
} }
void f_splitscreen() { void f_splitscreen() {
setSplitScreen(399 - (TOP().i << 1)); setSplitScreen(399 - (TOP().i << 1));
DROP(1); DROP(1);
@ -199,11 +220,51 @@ void f_adlib() {
DROP(2); 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) { void game_f_init(char *exe) {
f_init(exe); f_init(exe);
CDEF("seremit", f_seremit); CDEF("seremit", f_seremit);
CDEF("key-pressed", f_keyWasPressed); CDEF("key-pressed", f_keyWasPressed);
CDEF("key-down", f_keyIsDown); CDEF("key-down", f_keyIsDown);
CDEF("key-start", kbd_init);
CDEF("key-end", kbd_cleanup);
CDEF("draw-sprite", f_drawSprite); CDEF("draw-sprite", f_drawSprite);
CDEF("draw-portrait", f_drawportrait); CDEF("draw-portrait", f_drawportrait);
CDEF("scroll", f_scroll); CDEF("scroll", f_scroll);
@ -219,33 +280,25 @@ void game_f_init(char *exe) {
CDEF("mousepos", f_mousepos); CDEF("mousepos", f_mousepos);
CDEF("mousebuttons", f_mousebuttons); CDEF("mousebuttons", f_mousebuttons);
CDEF("unfuck", tile_init); CDEF("unfuck", tile_init);
CDEF("320x200", f_320x200);
CDEF("loadportraits", f_loadportraits);
slide_init();
f_loadjor("gameboot.jor"); f_loadjor("gameboot.jor");
f_atexit = f_lookupcp("atexit");
atexit(f_cleanup);
} }
void f_poll() { void f_poll() {
static char line[128] = { 0 }; static char line[128] = { 0 };
int i = strlen(line); while (ser_getline(line)) {
int value; PUSHS(line);
for (value = ser_poll(); value != SER_NODATA; value = ser_poll()) { f_runstring("REPL send");
if (value == '\b' || value == 127) { f_taskloop();
i --; line[0] = '\0';
} else {
line[i] = value;
i ++;
}
line[i] = '\0';
ser_write_byte(value); // echo
if (value == '\r') {
line[i - 1] = '\n';
ser_write_byte('\n');
PUSHS(line);
f_runstring("REPL send");
f_taskloop();
i = 0;
line[i] = '\0';
}
} }
} }

12
tiff.c
View file

@ -117,7 +117,7 @@ int tifLoadEGA(FILE *f, TifImageMeta_t meta, unsigned int vidOffset, int maxY, u
return y; 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 istrip;
int irow; int irow;
int ipixelpair; int ipixelpair;
@ -125,11 +125,11 @@ int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int
unsigned long offset; unsigned long offset;
unsigned char rowData[MAX_WIDTH >> 1]; unsigned char rowData[MAX_WIDTH >> 1];
unsigned int planeStride = (meta.width >> 4) * yRepeat; unsigned int planeStride = (meta.width >> 4) * yRepeat;
unsigned int *bp = planeBuf; unsigned int far *bp = planeBuf;
unsigned int *gp = bp + planeStride; unsigned int far *gp = bp + planeStride;
unsigned int *rp = gp + planeStride; unsigned int far *rp = gp + planeStride;
unsigned int *ip = rp + planeStride; unsigned int far *ip = rp + planeStride;
unsigned int *mp = ip + planeStride; unsigned int far *mp = ip + planeStride;
unsigned int bv, gv, rv, iv; unsigned int bv, gv, rv, iv;
if (meta.width > MAX_WIDTH || (meta.width % 16) != 0 || planes < 4 || planes > 5) { if (meta.width > MAX_WIDTH || (meta.width % 16) != 0 || planes < 4 || planes > 5) {

2
tiff.h
View file

@ -14,4 +14,4 @@ typedef struct {
TifImageMeta_t tifLoadMeta(FILE *f); TifImageMeta_t tifLoadMeta(FILE *f);
int tifLoadEGA(FILE *f, TifImageMeta_t meta, unsigned int vidOffset, int maxY, unsigned int w); 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
View file

@ -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, TiledScreen_t screen = { 0, 0, 0, 0, { OFF_PAGE1, OFF_PAGE2 }, 0, 0, NULL, NULL,
0, 0, 0, 0, 0 }; 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.tilesOffset = tilesOffset;
screen.memTiles = memTiles; screen.memTiles = memTiles;
} }
@ -66,6 +66,7 @@ void loadMap(unsigned char *map, unsigned int w, unsigned int h) {
int prepareBuffer(int pageX, int pageY) { int prepareBuffer(int pageX, int pageY) {
unsigned char *dirty = &screen.dirty[screen.currentPage][pageX + (pageY * PAGE_TILES_W)]; unsigned char *dirty = &screen.dirty[screen.currentPage][pageX + (pageY * PAGE_TILES_W)];
int i;
if (!isBufIndex(*dirty)) { if (!isBufIndex(*dirty)) {
unsigned int startX = screen.scrollX >> 4; unsigned int startX = screen.scrollX >> 4;
unsigned int startY = screen.scrollY >> 4; unsigned int startY = screen.scrollY >> 4;
@ -73,15 +74,18 @@ int prepareBuffer(int pageX, int pageY) {
unsigned char ibuffer = screen.nextBuffer; unsigned char ibuffer = screen.nextBuffer;
screen.nextBuffer = nextBufferIndex(ibuffer); screen.nextBuffer = nextBufferIndex(ibuffer);
*dirty = 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] screen.bufferOffset[ibuffer] = screen.pageOffset[screen.currentPage]
+ (pageX << 1) + (pageY * PAGE_STRIDE * 16); + (pageX << 1) + (pageY * PAGE_STRIDE * 16);
} }
return *dirty; return *dirty;
} }
void drawSpriteToBuf(unsigned int *sprite, int pageX, int pageY, int shift, int yStart) { void drawSpriteToBuf(unsigned int far *sprite, int pageX, int pageY, int shift, int yStart) {
unsigned int *buf, *mask; unsigned int *buf;
unsigned int far *mask;
unsigned int maskval; unsigned int maskval;
int y, h, plane; int y, h, plane;
if (pageX < 0 || pageY < 0 || 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 pageX = (int)(x - (screen.scrollX & 0xfff0)) >> 4;
int pageY = (int)(y - (screen.scrollY & 0xfff0)) >> 4; int pageY = (int)(y - (screen.scrollY & 0xfff0)) >> 4;
int pageOffsetX = x & 0x0f; int pageOffsetX = x & 0x0f;

View file

@ -4,9 +4,9 @@
void tile_init(); 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 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 scroll(int newX, int newY);
void drawScreen(); 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_TILES_COUNT (PAGE_TILES_H * PAGE_TILES_W)
#define PAGE_STRIDE (PAGE_TILES_W << 1) #define PAGE_STRIDE (PAGE_TILES_W << 1)
#define NUM_BUFFERS 32 #define NUM_BUFFERS 20
#define BUF_WSTRIDE 16 #define BUF_WSTRIDE 16
#define BUF_WSIZE (BUF_WSTRIDE * 4) #define BUF_WSIZE (BUF_WSTRIDE * 4)
@ -29,7 +29,7 @@ typedef struct {
unsigned int pageOffset[2]; unsigned int pageOffset[2];
unsigned char dirty[2][PAGE_TILES_COUNT]; unsigned char dirty[2][PAGE_TILES_COUNT];
unsigned int tilesOffset; unsigned int tilesOffset;
unsigned int *memTiles; unsigned int far *memTiles;
unsigned char *map; unsigned char *map;
unsigned int buffer[NUM_BUFFERS][BUF_WSIZE]; unsigned int buffer[NUM_BUFFERS][BUF_WSIZE];
unsigned int bufferOffset[NUM_BUFFERS]; unsigned int bufferOffset[NUM_BUFFERS];

BIN
trip.chr Executable file

Binary file not shown.