aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorJacob Janzen <jacob.a.s.janzen@gmail.com>2024-02-14 12:01:03 -0600
committerJacob Janzen <jacob.a.s.janzen@gmail.com>2024-02-14 12:01:03 -0600
commitb5b4a5d66deefa3858bedf7bc58e6c96340e829b (patch)
tree4aa42f746be3c6ce409938796ca95175dfd1da86 /main.c
parent8bd664e467f760db6f689eb9d30c3d685abe6de5 (diff)
major refactor
Diffstat (limited to 'main.c')
-rw-r--r--main.c246
1 files changed, 35 insertions, 211 deletions
diff --git a/main.c b/main.c
index a693ae0..2d1e6c0 100644
--- a/main.c
+++ b/main.c
@@ -4,169 +4,11 @@
#include <time.h>
#include "cavegen.h"
+#include "common.h"
+#include "display.h"
+#include "entity.h"
#include "ht.h"
-#define MAIN_PANEL_WIDTH 100
-#define MAIN_PANEL_HEIGHT 41
-#define INSTRUCTION_PANEL_WIDTH 32
-#define INSTRUCTION_PANEL_HEIGHT 39
-#define MESSAGE_PANEL_WIDTH 100
-#define MESSAGE_PANEL_HEIGHT 3
-#define STATUS_PANEL_WIDTH 32
-#define STATUS_PANEL_HEIGHT 5
-
-#define MAX_ENTITIES 100
-
-struct entity {
- struct point p;
- char *disp_ch;
- bool solid;
- bool visible;
-};
-
-struct windows {
- WINDOW *main;
- WINDOW *inst;
- WINDOW *msgs;
- WINDOW *stat;
-};
-
-WINDOW *create_newwin(int height, int width, int starty, int startx)
-
-{
- WINDOW *local_win = newwin(height, width, starty, startx);
- box(local_win, 0, 0);
- wrefresh(local_win);
-
- return local_win;
-}
-
-void initialize(void)
-{
- setlocale(LC_ALL, ""); // allow extended ASCII
-
- initscr(); // initialize curses
-
- // exit on unsupported consoles
- if (LINES < MAIN_PANEL_HEIGHT + MESSAGE_PANEL_HEIGHT ||
- COLS < MAIN_PANEL_WIDTH + INSTRUCTION_PANEL_WIDTH || !has_colors()) {
- endwin();
- fprintf(
- stderr,
- "a color terminal is required with at least %dx%d characters\n",
- INSTRUCTION_PANEL_WIDTH + MAIN_PANEL_WIDTH,
- MAIN_PANEL_HEIGHT + MESSAGE_PANEL_HEIGHT
- );
- exit(1);
- }
-
- // configure curses if startup was successful
- raw(); // disable line buffering
- keypad(stdscr, TRUE); // enable reading function keys
- noecho(); // don't print input
- curs_set(0); // disable the cursor
- start_color(); // enable colours
-
- // setup colours
- init_pair(1, COLOR_WHITE, COLOR_BLACK);
- init_pair(2, COLOR_BLACK, COLOR_RED);
- wattron(stdscr, COLOR_PAIR(1));
- refresh();
-}
-
-void display_map(WINDOW *win, struct map *map, ht_t *entities)
-{
- // print map
- struct entity *camera = ht_find(entities, "camera");
-
- for (int i = 1; i < MAIN_PANEL_HEIGHT - 1; ++i) {
- for (int j = 1; j < MAIN_PANEL_WIDTH - 1; ++j) {
- int map_i = i - 1 + camera->p.y;
- int map_j = j - 1 + camera->p.x;
-
- if (map_i > map->height || map_j > map->width || map_i < 0 ||
- map_j < 0) {
- mvwaddch(win, i, j, ' ');
- } else {
- switch (map->map[map_i * map->width + map_j]) {
- case GROUND : mvwaddch(win, i, j, '.'); break;
- case UP_STAIR : mvwaddch(win, i, j, '<'); break;
- case DOWN_STAIR :
- wattron(win, COLOR_PAIR(2));
- mvwaddch(win, i, j, '>');
- wattroff(win, COLOR_PAIR(2));
- break;
- case WALL :
- if (map_i > 0 &&
- map->map[(map_i - 1) * map->width + map_j] != WALL) {
- mvwprintw(win, i, j, "█");
- } else if (map_i < map->width - 1 && map->map[(map_i + 1) * map->width + map_j] != WALL) {
- mvwprintw(win, i, j, "█");
- } else if (map_j > 0 && map->map[map_i * map->width + map_j - 1] != WALL) {
- mvwprintw(win, i, j, "█");
- } else if (map_j < map->width - 1 && map->map[map_i * map->width + map_j + 1] != WALL) {
- mvwprintw(win, i, j, "█");
- } else {
- mvwaddch(win, i, j, ' ');
- }
- break;
- default : mvwaddch(win, i, j, ' ');
- }
- }
- }
- }
-
- // print entities
- ht_iter_init(entities);
- struct entity *e;
- while ((e = ht_iter_next(entities))) {
- if (e->visible) {
- mvwprintw(
- win, e->p.y - camera->p.y + 1, e->p.x - camera->p.x + 1,
- e->disp_ch
- );
- }
- }
-
- wrefresh(win);
-}
-
-void display_instructions(WINDOW *win)
-{
- mvwprintw(win, 1, 2, "h - move left");
- mvwprintw(win, 2, 2, "j - move down");
- mvwprintw(win, 3, 2, "k - move up");
- mvwprintw(win, 4, 2, "l - move right");
- mvwprintw(win, 5, 2, "> - move down staircase");
- mvwprintw(win, 6, 2, "< - exit via staircase");
- wrefresh(win);
-}
-
-void display_message(WINDOW *win, char *msg)
-{
- for (int i = 1; i < MESSAGE_PANEL_WIDTH - 1; ++i) {
- mvwaddch(win, 1, i, ' ');
- }
-
- mvwprintw(win, 1, 1, msg);
- wrefresh(win);
-}
-
-void display_status(WINDOW *win, struct entity *entity)
-{
- for (int i = 1; i < STATUS_PANEL_HEIGHT - 1; ++i) {
- for (int j = 1; j < STATUS_PANEL_WIDTH - 1; ++j) {
- mvwaddch(win, i, j, ' ');
- }
- }
-
- mvwprintw(win, 1, 2, "HP:");
- mvwprintw(win, 2, 2, "STAMINA:");
- mvwprintw(win, 3, 2, "MANA:");
-
- wrefresh(win);
-}
-
bool entity_set_pos(struct entity *e, struct point p, struct map *map)
{
if (e->solid) {
@@ -183,59 +25,38 @@ bool entity_set_pos(struct entity *e, struct point p, struct map *map)
return true;
}
-void create_windows(struct windows *wins)
-{
- wins->inst = create_newwin(
- INSTRUCTION_PANEL_HEIGHT, INSTRUCTION_PANEL_WIDTH,
- (LINES - INSTRUCTION_PANEL_HEIGHT - STATUS_PANEL_HEIGHT) / 2 + 1,
- (COLS - MAIN_PANEL_WIDTH - INSTRUCTION_PANEL_WIDTH) / 2 +
- MAIN_PANEL_WIDTH - 1
- );
- wins->msgs = create_newwin(
- MESSAGE_PANEL_HEIGHT, MESSAGE_PANEL_WIDTH,
- (LINES - MAIN_PANEL_HEIGHT - MESSAGE_PANEL_HEIGHT) / 2 +
- MAIN_PANEL_HEIGHT,
- (COLS - MESSAGE_PANEL_WIDTH - INSTRUCTION_PANEL_WIDTH) / 2
- );
- wins->stat = create_newwin(
- STATUS_PANEL_HEIGHT, STATUS_PANEL_WIDTH,
- (LINES - INSTRUCTION_PANEL_HEIGHT - STATUS_PANEL_HEIGHT) / 2 +
- INSTRUCTION_PANEL_HEIGHT,
- (COLS - MAIN_PANEL_WIDTH - INSTRUCTION_PANEL_WIDTH) / 2 +
- MAIN_PANEL_WIDTH - 1
- );
- wins->main = create_newwin(
- MAIN_PANEL_HEIGHT, MAIN_PANEL_WIDTH,
- (LINES - MAIN_PANEL_HEIGHT - MESSAGE_PANEL_HEIGHT) / 2 + 1,
- (COLS - MAIN_PANEL_WIDTH - INSTRUCTION_PANEL_WIDTH) / 2
- );
-}
-
-bool process_input(int ch, ht_t *entities, struct map *map)
+bool game_update(
+ display_t *disp, enum action action, ht_t *entities, struct map *map
+)
{
struct entity *player = ht_find(entities, "player");
struct entity *camera = ht_find(entities, "camera");
struct point newp = player->p;
struct point newp_cam = camera->p;
- switch (ch) {
- case 'k' :
+ switch (action) {
+ case ACTION_EXIT : return true;
+ case ACTION_UP :
--newp.y;
--newp_cam.y;
+ display_message(disp, "moving up");
break;
- case 'j' :
+ case ACTION_DOWN :
++newp.y;
++newp_cam.y;
+ display_message(disp, "moving down");
break;
- case 'h' :
+ case ACTION_LEFT :
--newp.x;
--newp_cam.x;
+ display_message(disp, "moving left");
break;
- case 'l' :
+ case ACTION_RIGHT :
++newp.x;
++newp_cam.x;
+ display_message(disp, "moving right");
break;
- case '>' :
+ case ACTION_STAIR_DOWN :
if (map->map[player->p.y * map->width + player->p.x] == DOWN_STAIR) {
free(map->map);
create_cave(map);
@@ -243,13 +64,20 @@ bool process_input(int ch, ht_t *entities, struct map *map)
newp = map->entry_point;
newp_cam.x = map->entry_point.x - MAIN_PANEL_WIDTH / 2 + 1;
newp_cam.y = map->entry_point.y - MAIN_PANEL_HEIGHT / 2 + 1;
+ display_message(disp, "moving down stairs");
+ } else {
+ display_message(disp, "no stairs to go down");
}
break;
- case '<' :
+ case ACTION_STAIR_UP :
if (map->map[player->p.y * WIDTH + player->p.x] == UP_STAIR) {
+ display_message(disp, "moving up stairs");
return true;
+ } else {
+ display_message(disp, "no stairs to go up");
}
break;
+ default : display_message(disp, "unrecognized command"); break;
}
if (entity_set_pos(player, newp, map))
@@ -263,18 +91,14 @@ int main(void)
unsigned int seed = time(NULL);
srand(seed);
- initialize();
-
- // create windows
- struct windows windows;
- create_windows(&windows);
+ display_t *disp = display_init();
// create the map
struct map map;
create_cave(&map);
// create the entity map
- ht_t *entities = ht_create();
+ ht_t *entities = ht_create(1);
// create the camera
struct entity camera;
@@ -299,17 +123,17 @@ int main(void)
entity_set_pos(&camera, cam_p, &map);
// start displaying things
- display_map(windows.main, &map, entities);
- display_instructions(windows.inst);
- display_status(windows.stat, &player);
- display_message(windows.msgs, "");
+ display_map(disp, &map, entities);
+ display_instructions(disp);
+ display_status(disp, &player);
+ display_message(disp, "");
int ch;
bool done = false;
- while (!done && (ch = getch()) != KEY_F(1)) {
- if (process_input(ch, entities, &map))
- break;
- display_map(windows.main, &map, entities);
+ while (!done) {
+ enum action action = display_process_input();
+ done = game_update(disp, action, entities, &map);
+ display_map(disp, &map, entities);
}
free(map.map);