pete286/testbed.c

549 lines
11 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++);
}
}
/*** I / O ***/
size_t fwritefar(FILE *fp, void far *buf, size_t length) {
char nearbuf[32];
size_t written = 0;
size_t towrite;
for (; towrite = min(32, length), length > 0; length -= towrite) {
movedata(FP_SEG(buf), FP_OFF(buf) + written, _SS, nearbuf, towrite);
if (!fwrite(nearbuf, towrite, 1, fp)) {
break;
}
written += towrite;
}
return written;
}
size_t freadfar(FILE *fp, void far *buf, size_t length) {
char nearbuf[32];
size_t totalread = 0;
size_t toread;
for (; toread = min(32, length), length > 0; length -= toread) {
size_t bytesread = fread(nearbuf, 1, toread, fp);
movedata(_SS, nearbuf, FP_SEG(buf), FP_OFF(buf) + totalread, bytesread);
totalread += bytesread;
if (bytesread != toread) {
break;
}
}
return totalread;
}
/*** 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);
}
#define SPRITE_GFX
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);
#ifdef SPRITE_GFX
f = fopen("sprite.gfx", "rb");
freadfar(f, sprites, NUM_SPRITES * SPRITE_STRIDE * 2);
fclose(f);
#else
f = fopen("SPRITE.TIF", "rb");
meta = tifLoadMeta(f);
tifLoad(f, meta, sprites, NUM_SPRITES * 16, 16, 5);
fclose(f);
#endif
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;
}
}
}
/* JILES */
#define SCREEN_STRIDE 40
int getsprpixel(int x, int y, unsigned int far *spr) {
int shift = (15 - x);
int b = (spr[y + 0] & (1 << shift)) >> shift;
int g = (spr[y + 16] & (1 << shift)) >> shift;
int r = (spr[y + 32] & (1 << shift)) >> shift;
int i = (spr[y + 48] & (1 << shift)) >> shift;
int v = (spr[y + 64] & (1 << shift)) ? 0 : 1;
return b | (g << 1) | (r << 2) | (i << 3) | (v << 4);
}
int resetEnabledCache = 0;
#define setResetEnabledCached(m) \
if (resetEnabledCache != m) { \
resetEnabledCache = m; \
setResetEnabled(m); \
}
void drawFatBox(int x, int y, int color) {
int faty;
int fill1 = color <= 0x0f ? 0xff : 0x55;
int fill2 = fill1 == 0xff ? 0xff : 0xaa;
unsigned int dst = SCREEN_STRIDE * y;
if (color > 0x0f) {
setResetEnabledCached(0);
} else {
setResetEnabledCached(0x0f);
setResetMask(color);
}
for ( faty = 0; faty < 8; faty ++) {
VID[dst + x + (SCREEN_STRIDE * faty)] = (faty % 2) ? fill1 : fill2;
}
}
void f_drawfatsprite() {
int isprite = TOP().i;
unsigned int far *spr = &sprites[isprite * SPRITE_STRIDE];
int x, y;
DROP(1);
setAllPlanes();
for ( y = 0; y < 16; y ++ ) {
for ( x = 0; x < 16; x ++ ) {
int color = getsprpixel(x, y, spr);
drawFatBox(x, y << 3, color);
}
}
}
void f_drawfatbox() {
drawFatBox(ST1().i, TOP().i, ST2().i);
DROP(3);
}
void f_savegfx() {
FILE *fp;
fp = fopen("sprite.gfx", "wb");
fwritefar(fp, sprites, NUM_SPRITES * SPRITE_STRIDE * 2);
fclose(fp);
}
void f_mousehide() {
mouse_hide();
}
void f_mouseshow() {
mouse_show();
}
void f_resetvideo() {
setLogicalWidth(SCREEN_STRIDE >> 1);
setResetEnabledCached(0);
setWriteMode(0);
setAllPlanes();
setDisplayOffset(0);
setHorizontalPan(0);
}
void f_putpixel() {
int isprite = TOP().i;
unsigned int far *spr = &sprites[isprite * SPRITE_STRIDE];
int x = ST2().i;
int y = ST1().i;
int color, shift, b, g, r, i, v;
DROP(3);
color = TOP().i;
DROP(1);
shift = (15 - x);
b = (color & 0x01);
g = (color & 0x02) >> 1;
r = (color & 0x04) >> 2;
i = (color & 0x08) >> 3;
v = ((color & 0x10) >> 4) ^ 1;
spr[y + 0] = (spr[y + 0] & ~(1 << shift)) | (b << shift);
spr[y + 16] = (spr[y + 16] & ~(1 << shift)) | (g << shift);
spr[y + 32] = (spr[y + 32] & ~(1 << shift)) | (r << shift);
spr[y + 48] = (spr[y + 48] & ~(1 << shift)) | (i << shift);
spr[y + 64] = (spr[y + 64] & ~(1 << shift)) | (v << shift);
}
void f_getpixel() {
int isprite = TOP().i;
unsigned int far *spr = &sprites[isprite * SPRITE_STRIDE];
int x = ST2().i;
int y = ST1().i;
DROP(2);
TOP().i = getsprpixel(x, y, spr);
}
void f_spritecount() {
PUSHI(NUM_SPRITES);
}
void f_tile2buf() {
unsigned int *buf = TOP().p;
unsigned int itile = ST1().u;
DROP(2);
writeTile(buf, &tiles[itile * TILE_STRIDE]);
}
void f_spr2buf() {
unsigned int *buf = TOP().p;
unsigned int isprite = ST1().u;
DROP(2);
overlaySprite(buf, &sprites[isprite * SPRITE_STRIDE], 0, 0);
}
void f_paintbuf() {
unsigned int *buf = TOP().p;
int y = ST1().i;
int x = ST2().i;
DROP(3);
paintBuffer(buf, x + (y * 40));
}
/* INIT */
void game_f_init(char *exe, char *bootjor) {
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);
CDEF("fuck", f_resetvideo);
CDEF("mouseshow", f_mouseshow);
CDEF("mousehide", f_mousehide);
CDEF("drawfatsprite", f_drawfatsprite);
CDEF("drawfatbox", f_drawfatbox);
CDEF("putpixel", f_putpixel);
CDEF("getpixel", f_getpixel);
CDEF("spritecount", f_spritecount);
CDEF("savegfx", f_savegfx);
CDEF("tile>buf", f_tile2buf);
CDEF("spr>buf", f_spr2buf);
CDEF("paintbuf", f_paintbuf);
f_loadjor(bootjor);
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;
char *bootjor = "gameboot.jor";
if (argc > 1) {
bootjor = argv[1];
}
ser_init(SER_COM2, BAUD_19200, SER_8N1);
game_init();
game_f_init(argv[0], bootjor);
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;
}