#include "world.h" #include "game.h" #include #include #include #include int TIMEOUT = 100; 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) { snprintf(msg, sizeof(msg), "%s: width %d is out of bounds (0,%d)", source, x, COLS); abort_game(msg); } if (y < 0 || y >= LINES) { snprintf(msg, sizeof(msg), "%s: height %d is out of bounds (0,%d)", source, y, LINES); abort_game(msg); } } void clear_screen() { mvaddch(0, 0, ' '); int screenchars = LINES * COLS; for (int i = 1; i < screenchars; i++) { addch(' '); } } void game_speed(int value) { if (value < 0) { abort_game("world_seed:: cannot be negative\n"); } TIMEOUT = value; } void set_message(const char* message, int x, int y) { int l = strlen(message); for (int i = 0; i < l; i++) { check_bounds("set_message", x + i, y); set_cell(message[i], x + i, y); } } void assert_message(int event, const char* message) { if (event == 0) { abort_game(message); } } void set_cell(int character, int x, int y) { check_bounds("set_cell", x, 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 = COLOR_COUNT * front_color + back_color; attron(COLOR_PAIR(pair)); mvaddch(y, x, character); attroff(COLOR_PAIR(pair)); } else { mvaddch(y, x, character); } } int world_run(void* (*init_game)(), int (*world_event)(struct event* event, void* game)) { void* game = init_game(); if (!game) { return -1; } timeout(TIMEOUT); struct event event; memset(&event, 0, sizeof(struct event)); event.height = LINES; event.width = COLS; event.type = EVENT_START; clock_t start_time = clock(); clock_t last_timeout = start_time; event.time_ms = start_time; while (1) { memset(&event, 0, sizeof(struct event)); event.height = LINES; event.width = COLS; event.type = EVENT_START; event.time_ms = clock(); world_event(&event, game); if (event.key == ERR) { event.type = EVENT_TIMEOUT; last_timeout = clock(); event.time_ms = last_timeout + TIMEOUT; } else if (event.key == KEY_MOUSE) { event.type = EVENT_MOUSE; MEVENT mouse_event; if (getmouse(&mouse_event) == OK) { event.mouse_x = mouse_event.x; event.mouse_y = mouse_event.y; if (mouse_event.bstate & BUTTON1_PRESSED) { event.mouse_left = 1; } if (mouse_event.bstate & BUTTON2_PRESSED) { event.mouse_middle = 1; } if (mouse_event.bstate & BUTTON3_PRESSED) { event.mouse_right = 1; } } } else if (event.key == KEY_RESIZE) { event.type = EVENT_RESIZE; } else { event.type = EVENT_KEY; if (event.key == 27) { // ESC key event.type = EVENT_ESC; } } event.time_ms = clock(); world_event(&event, game); timeout(TIMEOUT); } return 0; }