// Draw a tetris block. Kind of looks like the gameboy tetris blocks a bit // But with 2600-y looking colors. void draw_tile(uint32_t color1, uint32_t color2, int x, int y) { int xp = x+32; int yp = y+32; draw_rect_outline(color2, x, y, xp, yp); draw_rect(color1, x+1, y+1, xp-1, yp-1); draw_rect_outline(color2, x+2, y+2, xp-2, yp-2); draw_rect_outline(color2, x+4, y+4, xp-4, yp-4); /* draw_rect(color2, x+2, y+2, xp-2, yp-2); draw_rect(color1, x+4, y+4, xp-4, yp-4); */ }
static void draw_square_cursor(drawing *dr, game_drawstate *ds, int dx, int dy) { int coff = TILE_SIZE/8; draw_rect_outline(dr, dx + coff, dy + coff, TILE_SIZE - coff*2, TILE_SIZE - coff*2, COL_CURSOR); }
static void draw_laser_tile(drawing *dr, game_state *gs, game_drawstate *ds, game_ui *ui, int lno, int force) { int gx, gy, dx, dy, unused; int wrong, omitted, reflect, hit, laserval, flash = 0, tmp; unsigned int gs_tile, ds_tile, exitno; tmp = range2grid(gs, lno, &gx, &gy, &unused); assert(tmp); gs_tile = GRID(gs, gx, gy); ds_tile = GRID(ds, gx, gy); dx = TODRAW(gx); dy = TODRAW(gy); wrong = gs->exits[lno] & LASER_WRONG; omitted = gs->exits[lno] & LASER_OMITTED; exitno = gs->exits[lno] & ~LASER_FLAGMASK; reflect = gs_tile & LASER_REFLECT; hit = gs_tile & LASER_HIT; laserval = gs_tile & ~LASER_FLAGMASK; if (lno == ds->flash_laserno) gs_tile |= LASER_FLASHED; else if (!(gs->exits[lno] & (LASER_HIT | LASER_REFLECT))) { if (exitno == ds->flash_laserno) gs_tile |= LASER_FLASHED; } if (gs_tile & LASER_FLASHED) flash = 1; gs_tile |= wrong | omitted; if (ui->cur_visible && ui->cur_x == gx && ui->cur_y == gy) gs_tile |= FLAG_CURSOR; if (gs_tile != ds_tile || force) { draw_rect(dr, dx, dy, TILE_SIZE, TILE_SIZE, COL_BACKGROUND); draw_rect_outline(dr, dx, dy, TILE_SIZE, TILE_SIZE, COL_GRID); if (gs_tile &~ (LASER_WRONG | LASER_OMITTED | FLAG_CURSOR)) { char str[32]; int tcol = flash ? COL_FLASHTEXT : omitted ? COL_WRONG : COL_TEXT; if (reflect || hit) sprintf(str, "%s", reflect ? "R" : "H"); else sprintf(str, "%d", laserval); if (wrong) { draw_circle(dr, dx + TILE_SIZE/2, dy + TILE_SIZE/2, ds->rrad, COL_WRONG, COL_WRONG); draw_circle(dr, dx + TILE_SIZE/2, dy + TILE_SIZE/2, ds->rrad - TILE_SIZE/16, COL_BACKGROUND, COL_WRONG); } draw_text(dr, dx + TILE_SIZE/2, dy + TILE_SIZE/2, FONT_VARIABLE, TILE_SIZE/2, ALIGN_VCENTRE | ALIGN_HCENTRE, tcol, str); } if (gs_tile & FLAG_CURSOR) draw_square_cursor(dr, ds, dx, dy); draw_update(dr, dx, dy, TILE_SIZE, TILE_SIZE); } GRID(ds, gx, gy) = gs_tile; }
static void draw_arena_tile(drawing *dr, game_state *gs, game_drawstate *ds, game_ui *ui, int ax, int ay, int force, int isflash) { int gx = ax+1, gy = ay+1; int gs_tile = GRID(gs, gx, gy), ds_tile = GRID(ds, gx, gy); int dx = TODRAW(gx), dy = TODRAW(gy); if (ui->cur_visible && ui->cur_x == gx && ui->cur_y == gy) gs_tile |= FLAG_CURSOR; if (gs_tile != ds_tile || gs->reveal != ds->reveal || force) { int bcol, ocol, bg; bg = (gs->reveal ? COL_BACKGROUND : (gs_tile & BALL_LOCK) ? COL_LOCK : COL_COVER); draw_rect(dr, dx, dy, TILE_SIZE, TILE_SIZE, bg); draw_rect_outline(dr, dx, dy, TILE_SIZE, TILE_SIZE, COL_GRID); if (gs->reveal) { /* Guessed balls are always black; if they're incorrect they'll * have a red cross added later. * Missing balls are red. */ if (gs_tile & BALL_GUESS) { bcol = isflash ? bg : COL_BALL; } else if (gs_tile & BALL_CORRECT) { bcol = isflash ? bg : COL_WRONG; } else { bcol = bg; } } else { /* guesses are black/black, all else background. */ if (gs_tile & BALL_GUESS) { bcol = COL_BALL; } else { bcol = bg; } } ocol = (gs_tile & FLAG_CURSOR && bcol != bg) ? COL_CURSOR : bcol; draw_circle(dr, dx + TILE_SIZE/2, dy + TILE_SIZE/2, ds->crad-1, ocol, ocol); draw_circle(dr, dx + TILE_SIZE/2, dy + TILE_SIZE/2, ds->crad-3, bcol, bcol); if (gs_tile & FLAG_CURSOR && bcol == bg) draw_square_cursor(dr, ds, dx, dy); if (gs->reveal && (gs_tile & BALL_GUESS) && !(gs_tile & BALL_CORRECT)) { int x1 = dx + 3, y1 = dy + 3; int x2 = dx + TILE_SIZE - 3, y2 = dy + TILE_SIZE-3; int coords[8]; /* Incorrect guess; draw a red cross over the ball. */ coords[0] = x1-1; coords[1] = y1+1; coords[2] = x1+1; coords[3] = y1-1; coords[4] = x2+1; coords[5] = y2-1; coords[6] = x2-1; coords[7] = y2+1; draw_polygon(dr, coords, 4, COL_WRONG, COL_WRONG); coords[0] = x2+1; coords[1] = y1+1; coords[2] = x2-1; coords[3] = y1-1; coords[4] = x1-1; coords[5] = y2-1; coords[6] = x1+1; coords[7] = y2+1; draw_polygon(dr, coords, 4, COL_WRONG, COL_WRONG); } draw_update(dr, dx, dy, TILE_SIZE, TILE_SIZE); } GRID(ds,gx,gy) = gs_tile; }
static void game_print(drawing *dr, game_state *state, int tilesize) { int w = state->par.w; int ink = print_mono_colour(dr, 0); int i, x, y; /* Ick: fake up `ds->tilesize' for macro expansion purposes */ game_drawstate ads, *ds = &ads; game_set_size(dr, ds, NULL, tilesize); /* * Border. */ print_line_width(dr, 3 * TILESIZE / 40); draw_rect_outline(dr, BORDER, BORDER, w*TILESIZE, w*TILESIZE, ink); /* * Main grid. */ for (x = 1; x < w; x++) { print_line_width(dr, TILESIZE / 40); draw_line(dr, BORDER+x*TILESIZE, BORDER, BORDER+x*TILESIZE, BORDER+w*TILESIZE, ink); } for (y = 1; y < w; y++) { print_line_width(dr, TILESIZE / 40); draw_line(dr, BORDER, BORDER+y*TILESIZE, BORDER+w*TILESIZE, BORDER+y*TILESIZE, ink); } /* * Clues. */ for (i = 0; i < 4*w; i++) { char str[128]; if (!state->clues->clues[i]) continue; CLUEPOS(x, y, i, w); sprintf (str, "%d", state->clues->clues[i]); draw_text(dr, BORDER + x*TILESIZE + TILESIZE/2, BORDER + y*TILESIZE + TILESIZE/2, FONT_VARIABLE, TILESIZE/2, ALIGN_VCENTRE | ALIGN_HCENTRE, ink, str); } /* * Numbers for the solution, if any. */ for (y = 0; y < w; y++) for (x = 0; x < w; x++) if (state->grid[y*w+x]) { char str[2]; str[1] = '\0'; str[0] = state->grid[y*w+x] + '0'; draw_text(dr, BORDER + x*TILESIZE + TILESIZE/2, BORDER + y*TILESIZE + TILESIZE/2, FONT_VARIABLE, TILESIZE/2, ALIGN_VCENTRE | ALIGN_HCENTRE, ink, str); } }