273 lines
7.3 KiB
C
273 lines
7.3 KiB
C
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
#include <ncurses.h>
|
|
#include <string.h>
|
|
|
|
#include <l3tde/game.h>
|
|
#include <l3tde/map.h>
|
|
#include <l3tde/overworld.h>
|
|
|
|
static L3TDEMapPtr
|
|
l3tde_game_create_default_map (void);
|
|
static L3TDEGamePtr
|
|
l3tde_game_create_default_game (void);
|
|
void
|
|
l3tde_game_render_game (L3TDEGamePtr game);
|
|
static size_t
|
|
l3tde_game_render_game_get_start_node (size_t current_pos,
|
|
size_t nodes_len, size_t max);
|
|
static void
|
|
l3tde_game_render_game_get_start_nodes (L3TDEGamePtr game,
|
|
int max_x, int max_y, size_t *x, size_t *y);
|
|
void
|
|
l3tde_game_loop (L3TDEGamePtr game);
|
|
void
|
|
l3tde_game_move_to_pos_if_posible (L3TDEGamePtr game,
|
|
size_t dest_x, size_t dest_y);
|
|
|
|
void
|
|
l3tde_game_init (void) {
|
|
L3TDEGamePtr game = l3tde_game_create_default_game ();
|
|
initscr ();
|
|
start_color ();
|
|
curs_set (0);
|
|
raw ();
|
|
keypad (stdscr, TRUE);
|
|
noecho ();
|
|
l3tde_game_loop (game);
|
|
endwin ();
|
|
}
|
|
|
|
void
|
|
l3tde_game_loop (L3TDEGamePtr game) {
|
|
int input;
|
|
while (1) {
|
|
erase ();
|
|
l3tde_game_render_game (game);
|
|
input = getch ();
|
|
bool end_game = 0;
|
|
bool is_movement = false;
|
|
size_t dest_x, dest_y;
|
|
switch (input) {
|
|
case KEY_UP:
|
|
if (game->y_pos) {
|
|
is_movement = true;
|
|
dest_x = game->x_pos;
|
|
dest_y = game->y_pos - 1;
|
|
}
|
|
break;
|
|
case KEY_DOWN:
|
|
if (game->current_map
|
|
->nodes_y_len -1
|
|
> game->y_pos) {
|
|
is_movement = true;
|
|
dest_x = game->x_pos;
|
|
dest_y = game->y_pos + 1;
|
|
}
|
|
break;
|
|
case KEY_RIGHT:
|
|
if (game->current_map
|
|
->nodes_x_len -1
|
|
> game->x_pos) {
|
|
is_movement = true;
|
|
dest_x = game->x_pos + 1;
|
|
dest_y = game->y_pos;
|
|
}
|
|
break;
|
|
case KEY_LEFT:
|
|
if (game->x_pos) {
|
|
is_movement = true;
|
|
dest_x = game->x_pos - 1;
|
|
dest_y = game->y_pos;
|
|
}
|
|
break;
|
|
case 'q':
|
|
end_game = 1;
|
|
|
|
}
|
|
if (is_movement) {
|
|
l3tde_game_move_to_pos_if_posible (game, dest_x,
|
|
dest_y);
|
|
}
|
|
if (end_game) break;
|
|
}
|
|
}
|
|
|
|
void
|
|
l3tde_game_move_to_pos_if_posible (L3TDEGamePtr game,
|
|
size_t dest_x, size_t dest_y) {
|
|
if (game->current_map->nodes[dest_x][dest_y]->navigation
|
|
& L3TDE_MAP_NODE_NAVIGATION_WALKABLE) {
|
|
game->x_pos = dest_x;
|
|
game->y_pos = dest_y;
|
|
}
|
|
}
|
|
|
|
void
|
|
l3tde_game_render_game_map (L3TDEGamePtr game) {
|
|
L3TDEMapPtr current_map = game->current_map;
|
|
|
|
size_t start_node_x, start_node_y;
|
|
size_t max_node_x, max_node_y;
|
|
size_t nodes_x_len, nodes_y_len;
|
|
int max_x, max_y;
|
|
|
|
getmaxyx (stdscr, max_y, max_x);
|
|
|
|
l3tde_game_render_game_get_start_nodes (game,
|
|
max_x, max_y, &start_node_x, &start_node_y);
|
|
|
|
nodes_x_len = current_map->nodes_x_len;
|
|
nodes_y_len = current_map->nodes_y_len;
|
|
|
|
max_node_x = start_node_x + max_x;
|
|
max_node_y = start_node_y + max_y;
|
|
|
|
if (max_node_x > nodes_x_len) {
|
|
max_node_x = nodes_x_len;
|
|
}
|
|
|
|
if (max_node_y > nodes_y_len) {
|
|
max_node_y = nodes_y_len;
|
|
}
|
|
int printing_x = 0;
|
|
short pairs = 0;
|
|
int **color_pairs = NULL;
|
|
for (size_t i = start_node_x; i<max_node_x; i++, printing_x++) {
|
|
int printing_y = 0;
|
|
for (size_t j = start_node_y; j<max_node_y; j++, printing_y++) {
|
|
short current_pair = 0;
|
|
L3TDEMapNodePtr node = current_map->nodes[i][j];
|
|
L3TDEMapTerrainPtr terrain = node->terrain;
|
|
char symbol = terrain->symbol;
|
|
for (short i = 0; i < pairs; i++) {
|
|
if (color_pairs[i][0] == terrain->foreground &&
|
|
color_pairs[i][1]
|
|
== terrain->background ) {
|
|
current_pair = i +1;
|
|
}
|
|
}
|
|
if (!current_pair) {
|
|
pairs++;
|
|
current_pair = pairs;
|
|
init_pair(current_pair, terrain->foreground,
|
|
terrain->background);
|
|
color_pairs = realloc (color_pairs,
|
|
sizeof *color_pairs * pairs);
|
|
color_pairs[pairs-1] = malloc (sizeof **color_pairs);
|
|
color_pairs[pairs-1][0] = terrain->foreground;
|
|
color_pairs[pairs-1][1] = terrain->background;
|
|
}
|
|
attron (COLOR_PAIR (current_pair));
|
|
mvprintw (printing_y, printing_x, "%c", symbol);
|
|
attroff (COLOR_PAIR (current_pair));
|
|
}
|
|
}
|
|
free (color_pairs);
|
|
}
|
|
|
|
void
|
|
l3tde_game_render_game (L3TDEGamePtr game) {
|
|
size_t start_node_x, start_node_y;
|
|
int max_x, max_y;
|
|
int current_pos_map_x, current_pos_map_y;
|
|
|
|
erase ();
|
|
|
|
getmaxyx (stdscr, max_y, max_x);
|
|
|
|
l3tde_game_render_game_get_start_nodes (game,
|
|
max_x, max_y, &start_node_x, &start_node_y);
|
|
|
|
l3tde_game_render_game_map (game);
|
|
|
|
current_pos_map_x = game->x_pos - start_node_x;
|
|
current_pos_map_y = game->y_pos - start_node_y;
|
|
attron (A_BOLD);
|
|
mvprintw (current_pos_map_y, current_pos_map_x, "@");
|
|
attroff (A_BOLD);
|
|
}
|
|
|
|
static void
|
|
l3tde_game_render_game_get_start_nodes (L3TDEGamePtr game,
|
|
int max_x, int max_y, size_t *x, size_t *y) {
|
|
size_t nodes_x_len, nodes_y_len;
|
|
size_t current_pos_x, current_pos_y;
|
|
|
|
L3TDEMapPtr current_map = game->current_map;
|
|
|
|
|
|
current_pos_x = game->x_pos;
|
|
current_pos_y = game->y_pos;
|
|
|
|
nodes_x_len = current_map->nodes_x_len;
|
|
nodes_y_len = current_map->nodes_y_len;
|
|
|
|
*x = l3tde_game_render_game_get_start_node (current_pos_x,
|
|
nodes_x_len, max_x);
|
|
*y = l3tde_game_render_game_get_start_node (current_pos_y,
|
|
nodes_y_len, max_y);
|
|
}
|
|
|
|
static size_t
|
|
l3tde_game_render_game_get_start_node (size_t current_pos,
|
|
size_t nodes_len, size_t max) {
|
|
int center = max / 2;
|
|
size_t draw_center;
|
|
size_t start_pos;
|
|
|
|
if (current_pos < center) {
|
|
draw_center = center;
|
|
} else if (nodes_len - current_pos < center) {
|
|
draw_center = nodes_len - center - 1;
|
|
} else {
|
|
draw_center = current_pos;
|
|
}
|
|
|
|
if (center > draw_center) {
|
|
start_pos = 0;
|
|
} else {
|
|
start_pos = draw_center - center;
|
|
}
|
|
return start_pos;
|
|
}
|
|
|
|
static L3TDEGamePtr
|
|
l3tde_game_create_default_game (void) {
|
|
L3TDEMapPtr map = l3tde_game_create_default_map ();
|
|
L3TDEGamePtr game = l3tde_game_create (map, 0, 0);
|
|
return game;
|
|
}
|
|
|
|
static L3TDEMapPtr
|
|
l3tde_game_create_default_map (void) {
|
|
L3TDEOverworldPtr overworld = l3tde_overworld_create ();
|
|
L3TDEMapPtr map = l3tde_overworld_get_map (overworld, 0);
|
|
return map;
|
|
}
|
|
|
|
L3TDEGamePtr
|
|
l3tde_game_create (L3TDEMapPtr map,
|
|
size_t x, size_t y) {
|
|
L3TDEGamePtr self = malloc (sizeof *self);
|
|
|
|
self->current_map = map;
|
|
self->x_pos = x;
|
|
self->y_pos = y;
|
|
|
|
return self;
|
|
}
|
|
|
|
void
|
|
l3tde_game_destroy (L3TDEGamePtr self) {
|
|
if (self->current_map) {
|
|
l3tde_map_destroy (self->current_map);
|
|
self->current_map = NULL;
|
|
}
|
|
free (self);
|
|
}
|
|
|
|
void l3tde_game_render () {
|
|
|
|
}
|