196 lines
6.7 KiB
C
196 lines
6.7 KiB
C
#include <curses.h>
|
|
#include <string.h>
|
|
#include "curses.h"
|
|
#include "../helper.h"
|
|
#include "../player.h"
|
|
#include "../game.h"
|
|
#include "../wall.h"
|
|
#include "../main.h"
|
|
#include "../common.h"
|
|
#include "../context.h"
|
|
#include "../stubs.h"
|
|
#include "../tile.h" // for DoorTile, etc.
|
|
#include "../tiles/curses_tiles.h"
|
|
|
|
#include "../console.h"
|
|
|
|
int interfaceInit() {
|
|
// initialize ncurses library
|
|
if ((screen = initscr()) == NULL) {
|
|
perror("initscr() error'd");
|
|
return ERROR;
|
|
}
|
|
original_cursor = curs_set(0); // store original cursor position for restore and hide cursor
|
|
keypad(screen, TRUE); // enable arrow keys/keypad
|
|
noecho(); // turn off key echoing
|
|
nonl(); // do not do NL->CR/NL on output
|
|
cbreak(); // Handle char presses immediately, do not wait for \n
|
|
|
|
if (has_colors()) {
|
|
start_color();
|
|
// set up all possible color pairs using COLORS as our max (8 default)
|
|
int x, y;
|
|
for (x=0;x<COLORS;x++) {
|
|
for(y=0;y<COLORS;y++) {
|
|
init_pair(x*COLORS+y, x, y);
|
|
}
|
|
}
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
void interfaceLoop() {
|
|
int key = getch();
|
|
globalContext(key);
|
|
}
|
|
|
|
void interfaceDraw() {
|
|
//clear();
|
|
int step_x = player->x - ((struct PlayerTile*)player->data)->vision;
|
|
int step_y = player->y - ((struct PlayerTile*)player->data)->vision;
|
|
int end_x = player->x + ((struct PlayerTile*)player->data)->vision;
|
|
int end_y = player->y + ((struct PlayerTile*)player->data)->vision;
|
|
float camera_offset_x = player->x - (80/2); // TODO: get term size
|
|
float camera_offset_y = player->y - (24/2);
|
|
while (step_x < end_x) {
|
|
step_y = player->y - ((struct PlayerTile*)player->data)->vision;
|
|
while (step_y < end_y) {
|
|
//if (visible_matrix[step_x][step_y] & TILE_VISIBLE) {
|
|
if (step_x >= 0 && step_y >= 0 && step_x < current_map->width && step_y < current_map->height) {
|
|
struct Tile *current_tile;
|
|
current_tile = &(current_map)->matrix[step_x][step_y];
|
|
while(current_tile) {
|
|
short tile_id = current_tile->id;
|
|
unsigned int type_id = current_tile->tid;
|
|
int color;
|
|
switch (type_id) {
|
|
case WALL:
|
|
color = curses_walls[tile_id].fg * COLORS + curses_walls[tile_id].bg;
|
|
attron(COLOR_PAIR(color) | curses_walls[tile_id].attr);
|
|
mvwaddch(screen, step_y-camera_offset_y, step_x-camera_offset_x, curses_walls[tile_id].ch);
|
|
attroff(COLOR_PAIR(color) | curses_walls[tile_id].attr);
|
|
break;
|
|
case FLOOR:
|
|
color = curses_walls[tile_id].fg * COLORS + curses_walls[tile_id].bg;
|
|
attron(COLOR_PAIR(color) | curses_walls[tile_id].attr);
|
|
mvwaddch(screen, step_y-camera_offset_y, step_x-camera_offset_x, '.');
|
|
attroff(COLOR_PAIR(color) | curses_walls[tile_id].attr);
|
|
break;
|
|
case DOOR:
|
|
// doors work by taking the original id(0) and adding the current state(0=closed,1=open,2=broken,3=missing). For one door, you need 4 individual tiles.
|
|
tile_id = tile_id*4;
|
|
tile_id += ((struct DoorTile*)(current_tile->data))->state;
|
|
color = curses_doors[tile_id].fg * COLORS + curses_doors[tile_id].bg;
|
|
attron(COLOR_PAIR(color) | curses_doors[tile_id].attr);
|
|
mvwaddch(screen, step_y-camera_offset_y, step_x-camera_offset_x, curses_doors[tile_id].ch);
|
|
attroff(COLOR_PAIR(color) | curses_doors[tile_id].attr);
|
|
break;
|
|
case PLAYER:
|
|
color = curses_players[tile_id].fg * COLORS + curses_players[tile_id].bg;
|
|
attron(COLOR_PAIR(color) | curses_players[tile_id].attr);
|
|
mvwaddch(screen, step_y-camera_offset_y, step_x-camera_offset_x, '@');
|
|
attroff(COLOR_PAIR(color) | curses_players[tile_id].attr);
|
|
break;
|
|
case NPC:
|
|
color = curses_npcs[tile_id].fg * COLORS + curses_npcs[tile_id].bg;
|
|
attron(COLOR_PAIR(color) | curses_npcs[tile_id].attr);
|
|
mvwaddch(screen, step_y-camera_offset_y, step_x-camera_offset_x, curses_npcs[tile_id].ch);
|
|
attroff(COLOR_PAIR(color) | curses_npcs[tile_id].attr);
|
|
break;
|
|
}
|
|
current_tile = current_tile->next;
|
|
}
|
|
} else {
|
|
mvwaddch(screen, step_y-camera_offset_y, step_x-camera_offset_x, ' ');
|
|
}
|
|
step_y++; // move down
|
|
}
|
|
step_x++; // move right
|
|
}
|
|
move(player->y-camera_offset_y, player->x-camera_offset_x);
|
|
if (current_context == &consoleContext) {
|
|
interfaceDrawConsole();
|
|
}
|
|
refresh();
|
|
}
|
|
|
|
void interfaceClose() {
|
|
wrefresh(screen);
|
|
delwin(screen);
|
|
endwin();
|
|
}
|
|
|
|
/* non-main() funcs */
|
|
void interfacePrint(const char *input_string) {
|
|
// TODO: "zero" out whole line before printing new one (so overlap is gone)
|
|
mvwaddstr(screen, 22, 0, input_string);
|
|
consoleLog(input_string);
|
|
}
|
|
|
|
void interfacePrintf(const char *input_string, ...) {
|
|
int *byte_location;
|
|
byte_location = &input_string+1; // our first arg, effectively
|
|
int byte_offset; // our memory reference used for getting argument offsets from the original string
|
|
|
|
char formatted_string[32];// start at 32?
|
|
//int formatted_string_length = 8;
|
|
int format_step = 0;
|
|
int input_step = 0;
|
|
char current_char = input_string[0];
|
|
formatted_string[0] = current_char;
|
|
int handle_format = 0;
|
|
while (current_char != '\0') {
|
|
input_step++;
|
|
current_char = input_string[input_step];
|
|
if (handle_format == 1) {
|
|
switch(current_char) {
|
|
case 'c': // for char
|
|
byte_offset = *byte_location++; // our arg location
|
|
handle_format = 0;
|
|
format_step++;
|
|
//formatted_string[format_step] = *byte_location;
|
|
formatted_string[format_step] = byte_offset;
|
|
// convert decimal to curses
|
|
break;
|
|
case 's':
|
|
handle_format = 0;
|
|
byte_offset = *byte_location++; // our arg location
|
|
while(byte_offset != '\0') {
|
|
format_step++;
|
|
formatted_string[format_step] = byte_offset;
|
|
byte_offset = *byte_location++; // our arg location
|
|
}
|
|
break;
|
|
}
|
|
} else if (current_char == '%') {
|
|
handle_format = 1;
|
|
} else {
|
|
format_step++;
|
|
formatted_string[format_step] = current_char;
|
|
}
|
|
}
|
|
mvwaddstr(screen, 22, 0, formatted_string);
|
|
}
|
|
|
|
void interfaceDrawConsole() {
|
|
int line;
|
|
struct ConsoleEntry *entry;
|
|
entry = console_last_entry;
|
|
for (line = 7;line >= 0;line--) {
|
|
move(line, 0);
|
|
if (entry->size > 0) {
|
|
addstr(consoleGetEntryString(entry));
|
|
}
|
|
if (entry->prev)
|
|
entry = entry->prev;
|
|
hline(' ', 80);
|
|
}
|
|
move(9, 0);
|
|
hline('-', 80);
|
|
move(8, 0);
|
|
hline(' ', 80);
|
|
move(8, 0);
|
|
addstr("> ");
|
|
addstr(console_cmd);
|
|
}
|