#include #include #include #include #include #include #include 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; inodes[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 () { }