#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" /*** S C R A T C H ***/ #define NUM_TILES 128 #define NUM_SPRITES 64 #define OFF_TILES 0x5000 #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; } } } #define DIR_N 0 #define DIR_E 1 #define DIR_W 2 #define DIR_S 3 #define STATE_MAP 0 #define STATE_DIALOG 1 struct entity; typedef struct entity Entity_t; struct entity { int x; int y; int dir; int sprites[4]; }; void drawEntity(Entity_t *entity) { int isprite = entity->sprites[entity->dir]; drawSprite(&sprites[isprite * SPRITE_STRIDE], entity->x, entity->y); } void playerThink(Entity_t *self) { if (keyIsDown(K_LEFT)) { self->x -= 3; self->dir = DIR_W; } if (keyIsDown(K_RIGHT)) { self->x += 3; self->dir = DIR_E; } if (keyIsDown(K_UP)) { self->y -= 3; self->dir = DIR_N; } if (keyIsDown(K_DOWN)) { self->y += 3; self->dir = DIR_S; } } typedef struct { int dy; int y; } Footer_t; typedef struct { Entity_t player; Footer_t footer; int state; } Game_t; Game_t game; void game_init() { FILE *f; TifImageMeta_t meta; game.player.x = 100; game.player.y = 100; game.player.dir = DIR_E; game.player.sprites[DIR_E] = 0; game.player.sprites[DIR_N] = 1; game.player.sprites[DIR_W] = 2; game.player.sprites[DIR_S] = 3; game.footer.y = 0; game.state = STATE_MAP; setEGAMode(); atexit(vid_cleanup); kbd_init(); timer_init(TIMER_30HZ); tile_init(); fillMap(); f = fopen("FOOTER.TIF", "rb"); meta = tifLoadMeta(f); tifLoadEGA(f, meta, 0, 24, 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); loadTiles(OFF_TILES, tiles); loadMap(map, 100, 100); scroll(0, 0); } void showDialog() { game.state = STATE_DIALOG; game.footer.dy = 1; } void dialogThink() { if (keyWasPressed(K_SPACE)) { game.footer.dy = -1; } game.footer.y += game.footer.dy; if (game.footer.dy > 0 && game.footer.y > 24) { game.footer.y = 24; game.footer.dy = 0; } else if (game.footer.dy < 0 && game.footer.y < 0) { game.footer.y = 0; game.footer.dy = 0; game.state = STATE_MAP; } setSplitScreen(399 - (game.footer.y << 1)); } void overworldThink() { if (keyWasPressed(K_SPACE)) { showDialog(); } playerThink(&game.player); scroll(game.player.x - 152, game.player.y - 92); } void f_seremit() { ser_write_byte(TOP().i); if (TOP().i == '\n') { ser_write_byte('\r'); } DROP(1); } void f_keyWasPressed() { TOP().i = keyWasPressed(TOP().i); } 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); } void f_ticks() { PUSHU(timer_counter); } void game_f_init() { f_init(); CDEF("seremit", f_seremit); CDEF("key-pressed", f_keyWasPressed); CDEF("key-down", f_keyIsDown); CDEF("sprite", f_drawSprite); CDEF("scroll", f_scroll); CDEF("draw", drawScreen); CDEF("ticks", f_ticks); f_loadfile("game.jor"); } void f_poll() { static char line[256] = { 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'; } } f_taskloop(); } int main() { ser_init(SER_COM2, BAUD_19200, SER_8N1); game_init(); game_f_init(); while (!keyIsDown(K_ESC)) { kbd_debounce(); f_poll(); if (game.state == STATE_MAP) { overworldThink(); } else if (game.state == STATE_DIALOG) { dialogThink(); } drawEntity(&game.player); drawScreen(); } return 0; }