#include #include #include #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 tiles[NUM_TILES * TILE_STRIDE]; unsigned int sprites[NUM_SPRITES * SPRITE_STRIDE]; unsigned char map[10000]; 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 game_init() { FILE *f; TifImageMeta_t meta; 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("TILES.TIF", "rb"); meta = tifLoadMeta(f); tifLoad(f, meta, tiles, NUM_TILES * 16, 16, 4); tifLoadEGA(f, meta, OFF_TILES, NUM_TILES * 16, 16); 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); loadTiles(OFF_TILES, tiles); 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); } void game_f_init(char *exe) { f_init(exe); CDEF("seremit", f_seremit); CDEF("key-pressed", f_keyWasPressed); CDEF("key-down", f_keyIsDown); 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("unfuck", tile_init); f_loadjor("gameboot.jor"); } 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'); PUSHS(line); f_runstring("REPL send"); f_taskloop(); i = 0; line[i] = '\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; }