pete286/testbed.c
2019-06-25 21:58:52 -04:00

353 lines
6.6 KiB
C
Executable file

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <alloc.h>
#include "video.h"
#include "kbd.h"
#include "mouse.h"
#include "tiff.h"
#include "tiles.h"
#include "serial.h"
#include "timer.h"
#include "jorth.h"
#include "egamap.h"
#include "adlib.h"
/*** T E X T ***/
char far *font = NULL;
void text_init() {
unsigned int fontSeg, fontOff;
asm {
push es
push bp
mov ah, 11h
mov al, 30h
mov bh, 3
int 10h
mov ax, bp
pop bp
mov fontSeg, es
mov fontOff, ax
pop es
}
font = MK_FP(fontSeg, fontOff);
}
void text_draw_char(unsigned int vidOffset, unsigned char c) {
unsigned int fontOffset = c << 3;
int i;
for (i = 0; i < 8; i ++) {
VID[vidOffset] = font[fontOffset++];
vidOffset += PAGE_STRIDE;
}
}
void text_draw(unsigned int vidOffset, unsigned char *s) {
while (*s) {
text_draw_char(vidOffset++, *s++);
}
}
/*** S C R A T C H ***/
#define NUM_SPRITES 64
#define TILE_STRIDE 64
#define SPRITE_STRIDE 80
unsigned int far *tiles;
unsigned int far *sprites;
unsigned char map[10000];
void deallocate_gfx() {
if (tiles) farfree(tiles);
if (sprites) farfree(sprites);
}
void allocate_gfx() {
unsigned long memleft = farcoreleft();
tiles = farmalloc(NUM_TILES * TILE_STRIDE * 2);
sprites = farmalloc(NUM_SPRITES * SPRITE_STRIDE * 2);
atexit(deallocate_gfx);
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;
for (y = 0; y < 100; y ++) {
for (x = 0; x < 100; x ++) {
map[x + (y * 100)] = ((x + y + z) >> 2) % 4;
}
}
}
void readTiles(char *filename) {
FILE *f;
TifImageMeta_t meta;
f = fopen(filename, "rb");
meta = tifLoadMeta(f);
tifLoad(f, meta, tiles, NUM_TILES * 16, 16, 4);
tifLoadEGA(f, meta, OFF_TILES, NUM_TILES * 16, 16);
fclose(f);
loadTiles(OFF_TILES, tiles);
}
void f_loadtiles() {
readTiles(TOP().s);
DROP(1);
}
void game_init() {
FILE *f;
TifImageMeta_t meta;
allocate_gfx();
mouse_init();
setEGAMode();
atexit(vid_cleanup);
kbd_init();
timer_init(TIMER_30HZ);
text_init();
tile_init();
fillMap();
f = fopen("FOOTER.TIF", "rb");
meta = tifLoadMeta(f);
tifLoadEGA(f, meta, 0, 48, 336);
fclose(f);
f = fopen("SPRITE.TIF", "rb");
meta = tifLoadMeta(f);
tifLoad(f, meta, sprites, NUM_SPRITES * 16, 16, 5);
fclose(f);
f = fopen("PORTRAIT.TIF", "rb");
meta = tifLoadMeta(f);
tifLoadEGA(f, meta, OFF_PORTRAITS, NUM_PORTRAITS * 32, 32);
fclose(f);
readTiles("TILES.TIF");
loadMap(map, 100, 100);
scroll(0, 0);
}
void f_seremit() {
ser_write_byte(TOP().i);
if (TOP().i == '\n') {
ser_write_byte('\r');
}
DROP(1);
}
void f_keyWasPressed() {
int k = TOP().i;
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);
}
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);
}
void f_textc() { // ( col line c color -- )
setWriteMode(0);
setPlaneColor(TOP().u);
DROP(1);
text_draw_char(ST2().u + (ST1().u * PAGE_STRIDE), TOP().i);
DROP(3);
}
void f_text() { // ( col line s color -- )
setWriteMode(0);
setPlaneColor(TOP().u);
DROP(1);
text_draw(ST2().u + (ST1().u * PAGE_STRIDE), TOP().s);
DROP(3);
}
void f_map() {
PUSHP(map);
}
void f_mapsize() { // ( -- w h )
PUSHI(screen.w);
PUSHI(screen.h);
}
void f_mapsize_set() { // ( w h -- )
loadMap(map, ST1().i, TOP().i);
DROP(2);
}
void f_mousepos() { // ( -- x y )
PUSHI(MOUSE.x);
PUSHI(MOUSE.y);
}
void f_mousebuttons() {
PUSHI(MOUSE.buttons);
}
void f_drawportrait() {
setAllPlanes();
setWriteMode(1);
blit32x32(OFF_PORTRAITS + (TOP().u << 7), (PAGE_STRIDE << 3) + 1);
DROP(1);
}
void f_adlib() {
adlib_write(TOP().u, ST1().u);
DROP(2);
}
cell f_atexit;
void f_cleanup() {
f_execcp(f_atexit);
}
void f_glitch() {
int count = TOP().u;
int i, x, y;
DROP(1);
for (i = 0; i < count; i ++) {
x = screen.scrollX + (rand() % 352) - 16;
y = screen.scrollY + (rand() % 232) - 16;
switch(rand()%2) {
case 0:
drawSprite(sprites + (rand() % (NUM_SPRITES * SPRITE_STRIDE)), x, y);
break;
case 1:
drawSprite(mem + (rand() % MEM_SIZE), x, y);
break;
}
}
}
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);
CDEF("scrollpos", f_scrollpos);
CDEF("draw-screen", drawScreen);
CDEF("split-screen", f_splitscreen);
CDEF("ticks", f_ticks);
CDEF("text", f_text);
CDEF("textc", f_textc);
CDEF("map", f_map);
CDEF("mapsize", f_mapsize);
CDEF("mapsize!", f_mapsize_set);
CDEF("mousepos", f_mousepos);
CDEF("mousebuttons", f_mousebuttons);
CDEF("loadtiles", f_loadtiles);
CDEF("glitch", f_glitch);
CDEF("unfuck", tile_init);
f_loadjor("gameboot.jor");
f_atexit = f_lookupcp("atexit");
atexit(f_cleanup);
}
void f_poll() {
static char line[128] = { 0 };
while (ser_getline(line)) {
PUSHS(line);
f_runstring("REPL send");
f_taskloop();
line[0] = '\0';
}
}
int DONE = 0;
static void f_quit() {
DONE = 1;
}
void do_repl(char *exe) {
char buf[128];
f_init(exe);
CDEF("quit", f_quit);
CDEF("adlib", f_adlib);
f_loadfile("repl.jor");
f_taskloop();
while (!DONE) {
PUSHS(gets(buf));
f_runstring("REPL send");
f_taskloop();
}
}
int main(int argc, char *argv[]) {
cell tick, draw;
if (argc > 1) {
do_repl(argv[0]);
return 0;
}
ser_init(SER_COM2, BAUD_19200, SER_8N1);
game_init();
game_f_init(argv[0]);
tick = f_lookupcp("tick");
draw = f_lookupcp("draw");
while (!keyIsDown(K_ESC)) {
kbd_debounce();
f_poll();
f_taskloop();
f_execcp(tick);
f_taskloop();
f_execcp(draw);
}
return 0;
}