X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=ansitris;a=blobdiff_plain;f=src%2Fgame.c;h=f530bac4259cddeaf85ddfe1b83ee75765d05900;hp=0adc772e1cb1b5af9ba2fec4eda30b2399c178ed;hb=HEAD;hpb=bbe47075b6b56c7c6eb14b968a72cfb79d55d7bc diff --git a/src/game.c b/src/game.c index 0adc772..f530bac 100644 --- a/src/game.c +++ b/src/game.c @@ -46,14 +46,19 @@ int scr[SCR_COLS * SCR_ROWS]; static int collision(int piece, const int *pos); static void stick(int piece, const int *pos); +static void erase_completed(void); static void draw_piece(int piece, const int *pos, int rot, int mode); static void drawbg(void); +static void drawpf(void); +static void draw_line(int row, int blink); static void wrtile(int tileid); static int pos[2], next_pos[2]; static int cur_piece = -1; static int cur_rot, prev_rot; +static int complines[4] = {-1, -1, -1, -1}; +static int num_complines; enum { TILE_BLACK, @@ -121,6 +126,8 @@ void cleanup_game(void) ansi_reset(); } +#define BLINK_UPD_RATE 100 + long update(long msec) { static long prev_tick; @@ -128,20 +135,40 @@ long update(long msec) dt = msec - prev_tick; + if(num_complines) { + /* lines where completed, we're in blinking mode */ + int i, blink = dt >> 8; + + if(blink > 6) { + erase_completed(); + num_complines = 0; + return 0; + } + + for(i=0; i= tick_interval) { if(cur_piece >= 0) { next_pos[0] = pos[0] + 1; if(collision(cur_piece, next_pos)) { next_pos[0] = pos[0]; - fprintf(stderr, "stick at row %d col %d\n", pos[0], pos[1]); stick(cur_piece, next_pos); cur_piece = -1; + return 0; } } else { + /* respawn */ cur_piece = rand() % NUM_PIECES; - fprintf(stderr, "spawn: %d\n", cur_piece); - pos[0] = next_pos[0] = piece_spawnpos[cur_piece][0]; + prev_rot = cur_rot = 0; + pos[0] = piece_spawnpos[cur_piece][0]; + next_pos[0] = pos[0] + 1; pos[1] = next_pos[1] = PF_COLS / 2 + piece_spawnpos[cur_piece][1]; } @@ -155,13 +182,92 @@ long update(long msec) memcpy(pos, next_pos, sizeof pos); prev_rot = cur_rot; } + return tick_interval - dt; } + +#define C0 0x9b +#define SS3 0x8f + +static void runesc(int csi, char *buf) +{ + if(csi != C0) return; + + if(buf[1] == 0) { + switch(buf[0]) { + case 'A': + game_input('w'); /* up */ + break; + case 'B': + game_input('s'); /* down */ + break; + case 'C': + game_input('d'); /* right */ + break; + case 'D': + game_input('a'); /* left */ + break; + default: + break; + } + } +} + void game_input(int c) { + static int esc, csi; + static int esctop; + static char escbuf[64]; + + if(esc) { + esc = 0; + if(c == 27) { + quit = 1; + return; + } + + switch(c) { + case '[': + csi = C0; + return; + case 'O': + csi = SS3; + return; + default: + break; + } + } + + if(csi) { + if(c < 0x20 || c >= 0x80) { + csi = 0; + esctop = 0; + } + + escbuf[esctop++] = c; + + if(c >= 0x40) { + int prevcsi = csi; + escbuf[esctop] = 0; + csi = 0; + esctop = 0; + runesc(prevcsi, escbuf); + } + return; + } + switch(c) { case 27: + esc = 1; + break; + + case C0: + esc = 1; + csi = C0; + break; + + case 'q': quit = 1; break; @@ -196,6 +302,7 @@ void game_input(int c) break; default: + fprintf(stderr, "unhandled input: %x\n", c); break; } } @@ -210,6 +317,8 @@ static int collision(int piece, const int *pos) int y = PF_YOFFS + pos[0] + BLKY(*p); p++; + if(y < 0) continue; + if(scr[y * SCR_COLS + x] != TILE_PF) return 1; } @@ -218,16 +327,75 @@ static int collision(int piece, const int *pos) static void stick(int piece, const int *pos) { - int i; + int i, j, nblank; + int *pfline; unsigned char *p = pieces[piece][cur_rot]; for(i=0; i<4; i++) { - int x = PF_XOFFS + pos[1] + BLKX(*p); - int y = PF_YOFFS + pos[0] + BLKY(*p); + int x = pos[1] + BLKX(*p); + int y = pos[0] + BLKY(*p); p++; - scr[y * SCR_COLS + x] = piece + FIRST_PIECE_TILE; + pfline = scr + (y + PF_YOFFS) * SCR_COLS + PF_XOFFS; + pfline[x] = piece + FIRST_PIECE_TILE; + + nblank = 0; + for(j=0; j complines[i]) { + int tmp = complines[j]; + complines[j] = complines[i]; + complines[i] = tmp; + } + } + } + + srow = drow = PF_ROWS - 1; + + for(i=0; i