You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

163 lines
4.2 KiB

#include <stdlib.h>
#include <ncurses.h>
#include <unistd.h>
#include "gfx.h"
#include "merge.h"
#include <gettext.h>
#include <locale.h>
#define NUMBER_OF_COLORS 7
#define iterate(n, expression)\
do {\
int i;\
for (i = 0; i < n; ++i) { expression; }\
} while (0)
struct gfx_state {
WINDOW *window;
size_t window_height, window_width;
};
struct gfx_state* gfx_init(struct gamestate *g)
{
initscr();
cbreak();
keypad(stdscr, true);
noecho();
curs_set(FALSE);
refresh();
struct gfx_state *s = malloc(sizeof(struct gfx_state));
if (!s) return NULL;
s->window_height = g->opts->grid_height * (g->print_width + 2) + 3;
s->window_width = g->opts->grid_width * (g->print_width + 2) + 1;
s->window = newwin(s->window_height, s->window_width, 1, 1);
keypad(s->window, TRUE);
if (g->opts->enable_color && has_colors()) {
start_color();
#ifdef INVERT_COLORS
init_pair(1, COLOR_BLACK, COLOR_RED);
init_pair(2, COLOR_BLACK, COLOR_GREEN);
init_pair(3, COLOR_BLACK, COLOR_YELLOW);
init_pair(4, COLOR_BLACK, COLOR_BLUE);
init_pair(5, COLOR_BLACK, COLOR_MAGENTA);
init_pair(6, COLOR_BLACK, COLOR_CYAN);
init_pair(7, COLOR_BLACK, COLOR_WHITE);
#else
init_pair(1, COLOR_RED, COLOR_BLACK);
init_pair(2, COLOR_GREEN, COLOR_BLACK);
init_pair(3, COLOR_YELLOW, COLOR_BLACK);
init_pair(4, COLOR_BLUE, COLOR_BLACK);
init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
init_pair(6, COLOR_CYAN, COLOR_BLACK);
init_pair(7, COLOR_WHITE, COLOR_BLACK);
#endif
}
return s;
}
void gfx_draw(struct gfx_state *s, struct gamestate *g)
{
if (g->score_last)
mvwprintw(s->window, 0, 0, gettext("Score: %d (+%d)\n"), g->score, g->score_last);
else
mvwprintw(s->window, 0, 0, gettext("Score: %d\n"), g->score);
if (g->score >= g->score_high)
g->score_high = g->score;
mvwprintw(s->window, 1, 0, gettext(" Hi: %d\n"), g->score_high);
wattron(s->window, A_DIM);
iterate(g->opts->grid_width * (g->print_width + 2) + 1, waddch(s->window, '-'));
wattroff(s->window, A_DIM);
int x, y,
xpos = 0,
ypos = 3;
for (y = 0; y < g->opts->grid_height; ++y, ++ypos, xpos = 0) {
wattron(s->window, A_DIM);
mvwprintw(s->window, ypos, xpos++, "|");
wattroff(s->window, A_DIM);
for (x = 0; x < g->opts->grid_width; ++x) {
if (g->grid[x][y]) {
wattron(s->window, COLOR_PAIR(g->grid[x][y] % NUMBER_OF_COLORS + 1));
mvwprintw(s->window, ypos, xpos, "%-*ld", g->print_width, merge_value(g->grid[x][y]));
mvwprintw(s->window, ypos, xpos + g->print_width, " ");
wattroff(s->window, COLOR_PAIR(g->grid[x][y] % NUMBER_OF_COLORS + 1));
wattron(s->window, A_DIM);
mvwprintw(s->window, ypos, xpos + g->print_width + 1, "|");
wattroff(s->window, A_DIM);
}
else {
wattron(s->window, A_DIM);
iterate(g->print_width + 1, waddch(s->window, ' '));
waddch(s->window, '|');
wattroff(s->window, A_DIM);
}
xpos += (g->print_width + 2);
}
}
wattron(s->window, A_DIM);
iterate(g->opts->grid_height * (g->print_width + 2) + 1, waddch(s->window, '-'));
wattroff(s->window, A_DIM);
wrefresh(s->window);
mvwprintw(s->window, 12, 0, "2048");
mvwprintw(s->window, 13, 0, "----");
mvwprintw(s->window, 15, 0, "Use WASD for direction");
mvwprintw(s->window, 16, 0, "Q to quit.");
}
int gfx_getch(struct gfx_state *s)
{
int c = wgetch(s->window);
/* Flush buffer */
nodelay(s->window, TRUE);
while (wgetch(s->window) != ERR);
nodelay(s->window, FALSE);
switch (c)
{
case KEY_UP:
return INPUT_UP;
break;
case KEY_DOWN:
return INPUT_DOWN;
break;
case KEY_RIGHT:
return INPUT_RIGHT;
break;
case KEY_LEFT:
return INPUT_LEFT;
break;
default:
return c;
break;
}
}
void gfx_sleep(int ms)
{
usleep(ms * 1000);
}
void gfx_destroy(struct gfx_state *s)
{
free(s);
endwin();
}