#include "world.h" #include #include #include #include #include int TIMEOUT; void abort_game(const char* message) { endwin(); puts(message); exit(1); } void check_bounds(const char* source, int x, int y) { char msg[200]; if (x < 0 || x >= COLS) { sprintf(msg, "%s: width %d out of bounds (0,%d)", source, x, COLS); abort_game(msg); } if (y < 0 || y >= LINES) { sprintf(msg, "%s: height %d out of bounds (0,%d)", source, y, LINES); abort_game(msg); } } void clear_screen() { erase(); } void game_speed(int value) { if (value < 0) abort_game("game_speed: negative"); TIMEOUT = value; } void set_message(const char* message, int x, int y) { mvprintw(y, x, "%s", message); } void set_cell(int character, int x, int y) { set_color_cell(character, x, y, COLOR_WHITE, COLOR_BLACK); } void set_color_cell(int character, int x, int y, short front_color, short back_color) { check_bounds("set_color_cell", x, y); if (has_colors()) { int pair_id = front_color * 8 + back_color + 1; attron(COLOR_PAIR(pair_id)); mvaddch(y, x, character); attroff(COLOR_PAIR(pair_id)); } else { mvaddch(y, x, character); } } int start_world(void* (*init_game)(), int (*world_event)(struct event* event, void* game), void (*destroy_game)(void* game)) { srand(time(NULL)); int r = 0; TIMEOUT = 100; if (initscr() == NULL) { puts("Curses Error."); return -1; } noecho(); cbreak(); nodelay(stdscr, TRUE); keypad(stdscr, TRUE); curs_set(FALSE); if (has_colors()) { start_color(); for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) init_pair(i * 8 + j + 1, i, j); } void* game_state = NULL; if (init_game != NULL) { game_state = init_game(); assert(game_state != NULL); } timeout(TIMEOUT); struct event event; memset(&event, 0, sizeof(struct event)); event.height = LINES; event.width = COLS; event.type = EVENT_START; r = world_event(&event, game_state); refresh(); while (!r) { memset(&event, 0, sizeof(struct event)); event.height = LINES; event.width = COLS; event.key = getch(); if (event.key == ERR) event.type = EVENT_TIMEOUT; else if (event.key == KEY_RESIZE) event.type = EVENT_RESIZE; else { event.type = EVENT_KEY; if (event.key == 27) { int k = getch(); if (k == -1) event.type = EVENT_ESC; else { event.key = k; event.alt_key = 1; } } } r = world_event(&event, game_state); refresh(); timeout(TIMEOUT); } if (destroy_game != NULL) destroy_game(game_state); endwin(); return r; }