Map objects rendered and correctly used.
This commit is contained in:
@@ -6,13 +6,7 @@
|
|||||||
#ifndef STATE_CONSTS_H
|
#ifndef STATE_CONSTS_H
|
||||||
#define STATE_CONSTS_H
|
#define STATE_CONSTS_H
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__)
|
|
||||||
#define F_SEP "\\"
|
|
||||||
#elif defined(__linux__) || defined(__GNUC__)
|
|
||||||
#define F_SEP "/"
|
#define F_SEP "/"
|
||||||
#else
|
|
||||||
#error "Unrecognized system."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum COLORS {
|
enum COLORS {
|
||||||
BAR_COLOR = 1,
|
BAR_COLOR = 1,
|
||||||
|
|||||||
@@ -11,50 +11,50 @@
|
|||||||
#define MAX_STR 128
|
#define MAX_STR 128
|
||||||
|
|
||||||
typedef enum FLOOR_TYPES {
|
typedef enum FLOOR_TYPES {
|
||||||
VOID = 0,
|
VOID = 0,
|
||||||
SOLID_WALL,
|
SOLID_WALL,
|
||||||
SECRET_WALL,
|
SECRET_WALL,
|
||||||
CLEAR_WALL,
|
CLEAR_WALL,
|
||||||
NEON_WALL,
|
NEON_WALL,
|
||||||
WINDOW_WALL,
|
WINDOW_WALL,
|
||||||
EMPTY_FLOOR,
|
EMPTY_FLOOR,
|
||||||
RUG,
|
RUG,
|
||||||
WATER,
|
WATER,
|
||||||
BAR
|
BAR
|
||||||
} floor_t;
|
} floor_t;
|
||||||
|
|
||||||
typedef enum OBJECT_TYPES {
|
typedef enum OBJECT_TYPES {
|
||||||
DOOR = 0,
|
DOOR = 0,
|
||||||
KEY,
|
KEY,
|
||||||
PERSON,
|
PERSON,
|
||||||
PLAYER_START,
|
PLAYER_START,
|
||||||
EXIT,
|
EXIT,
|
||||||
DIALOG,
|
DIALOG,
|
||||||
NONE = 9989
|
NONE = 9989
|
||||||
} obj_t;
|
} obj_t;
|
||||||
|
|
||||||
typedef enum ERROR_CODES {
|
typedef enum ERROR_CODES {
|
||||||
NO_ERROR = 0,
|
NO_ERROR = 0,
|
||||||
FILE_NOT_FOUND,
|
FILE_NOT_FOUND,
|
||||||
OUT_OF_MEMORY,
|
OUT_OF_MEMORY,
|
||||||
PREMATURE_EOF,
|
PREMATURE_EOF,
|
||||||
MAP_TOO_LARGE,
|
MAP_TOO_LARGE,
|
||||||
INVALID_KEY
|
INVALID_KEY
|
||||||
} errcode_t;
|
} errcode_t;
|
||||||
|
|
||||||
typedef struct MAP_CELL{
|
typedef struct MAP_CELL{
|
||||||
floor_t f;
|
floor_t f;
|
||||||
} map_cell_t;
|
} map_cell_t;
|
||||||
|
|
||||||
typedef struct OBJECT {
|
typedef struct OBJECT {
|
||||||
obj_t type;
|
obj_t type;
|
||||||
short x, y, eX, eY, sX, sY;
|
short x, y, eX, eY, sX, sY;
|
||||||
short id;
|
short id;
|
||||||
short dId;
|
short dId;
|
||||||
char name[MAX_STR];
|
char name[MAX_STR];
|
||||||
char target[MAX_STR];
|
char target[MAX_STR];
|
||||||
char dialog[MAX_STR];
|
char dialog[MAX_STR];
|
||||||
unsigned char unlocked;
|
unsigned char unlocked;
|
||||||
} game_obj_t;
|
} game_obj_t;
|
||||||
|
|
||||||
extern errcode_t readMapData(const char *, map_cell_t ***, int *, int *);
|
extern errcode_t readMapData(const char *, map_cell_t ***, int *, int *);
|
||||||
|
|||||||
612
src/in_game.c
612
src/in_game.c
@@ -12,6 +12,13 @@
|
|||||||
#include "in_game.h"
|
#include "in_game.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
|
#define MAX_KEYS 15
|
||||||
|
|
||||||
|
static const char *keyMsg = "You picked up a key.";
|
||||||
|
static const char *saysMsg = " says: ";
|
||||||
|
static const char *openDoor = "The door opens.";
|
||||||
|
static const char *doorLock = "This door is locked.";
|
||||||
|
|
||||||
typedef struct PLAYER {
|
typedef struct PLAYER {
|
||||||
unsigned short x;
|
unsigned short x;
|
||||||
unsigned short y;
|
unsigned short y;
|
||||||
@@ -22,12 +29,16 @@ static bool **seen;
|
|||||||
static bool ** wmap;
|
static bool ** wmap;
|
||||||
static bool w_mov = FALSE;
|
static bool w_mov = FALSE;
|
||||||
static bool uK, dK, lK, rK;
|
static bool uK, dK, lK, rK;
|
||||||
static clock_t then;
|
static clock_t then, msgThen;
|
||||||
static player_t player;
|
static player_t player;
|
||||||
static map_cell_t ** map;
|
static map_cell_t ** map;
|
||||||
game_obj_t objs[MAX_OBJECTS];
|
static game_obj_t objs[MAX_OBJECTS];
|
||||||
static int mW, mH, nO;
|
static int mW, mH, nO;
|
||||||
fov_settings_type fov_settings;
|
static fov_settings_type fov_settings;
|
||||||
|
static int keys[MAX_KEYS];
|
||||||
|
static int freeKey;
|
||||||
|
static char msg[128];
|
||||||
|
static bool newMsg = FALSE;
|
||||||
|
|
||||||
void input();
|
void input();
|
||||||
gsname_t update();
|
gsname_t update();
|
||||||
@@ -35,9 +46,12 @@ void render(int, int);
|
|||||||
void drawGui(int, int);
|
void drawGui(int, int);
|
||||||
void setPlayerStart();
|
void setPlayerStart();
|
||||||
void initObjects();
|
void initObjects();
|
||||||
|
void initKeys();
|
||||||
void drawNeon(int, int, floor_t);
|
void drawNeon(int, int, floor_t);
|
||||||
void apply(void *, int, int, int, int, void *);
|
void apply(void *, int, int, int, int, void *);
|
||||||
bool opaque(void *, int, int);
|
bool opaque(void *, int, int);
|
||||||
|
void loadMap(const char *);
|
||||||
|
bool canMoveTo(int, int);
|
||||||
|
|
||||||
void initInGameState( gs_t * gs) {
|
void initInGameState( gs_t * gs) {
|
||||||
int i, j;
|
int i, j;
|
||||||
@@ -47,12 +61,12 @@ void initInGameState( gs_t * gs) {
|
|||||||
gs->update = &update;
|
gs->update = &update;
|
||||||
gs->render = &render;
|
gs->render = &render;
|
||||||
|
|
||||||
map = ( map_cell_t ** ) malloc ( sizeof ( map_cell_t * ) * MAX_MAP_SIZE);
|
map = ( map_cell_t ** ) malloc ( sizeof ( map_cell_t * ) * MAX_MAP_SIZE);
|
||||||
for ( i = 0; i < MAX_MAP_SIZE; ++i ) {
|
for ( i = 0; i < MAX_MAP_SIZE; ++i ) {
|
||||||
map[ i ] = ( map_cell_t * ) calloc ( MAX_MAP_SIZE , sizeof ( map_cell_t ) );
|
map[ i ] = ( map_cell_t * ) calloc ( MAX_MAP_SIZE , sizeof ( map_cell_t ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
wmap = ( bool ** ) malloc ( sizeof ( bool * ) * MAX_MAP_SIZE);
|
wmap = ( bool ** ) malloc ( sizeof ( bool * ) * MAX_MAP_SIZE);
|
||||||
for ( i = 0; i < MAX_MAP_SIZE; ++i ) {
|
for ( i = 0; i < MAX_MAP_SIZE; ++i ) {
|
||||||
wmap[ i ] = ( bool * ) calloc ( MAX_MAP_SIZE, sizeof ( bool ) );
|
wmap[ i ] = ( bool * ) calloc ( MAX_MAP_SIZE, sizeof ( bool ) );
|
||||||
for(j = 0; j < MAX_MAP_SIZE; ++j){
|
for(j = 0; j < MAX_MAP_SIZE; ++j){
|
||||||
@@ -60,37 +74,23 @@ void initInGameState( gs_t * gs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vis = ( bool ** ) malloc ( sizeof ( bool * ) * MAX_MAP_SIZE);
|
vis = ( bool ** ) malloc ( sizeof ( bool * ) * MAX_MAP_SIZE);
|
||||||
seen = ( bool ** ) malloc ( sizeof ( bool * ) * MAX_MAP_SIZE);
|
seen = ( bool ** ) malloc ( sizeof ( bool * ) * MAX_MAP_SIZE);
|
||||||
for ( i = 0; i < MAX_MAP_SIZE; ++i ) {
|
for ( i = 0; i < MAX_MAP_SIZE; ++i ) {
|
||||||
vis[ i ] = ( bool * ) calloc ( MAX_MAP_SIZE, sizeof ( bool ) );
|
vis[ i ] = ( bool * ) calloc ( MAX_MAP_SIZE, sizeof ( bool ) );
|
||||||
seen[ i ] = ( bool * ) calloc ( MAX_MAP_SIZE, sizeof ( bool ) );
|
seen[ i ] = ( bool * ) calloc ( MAX_MAP_SIZE, sizeof ( bool ) );
|
||||||
for(j = 0; j < MAX_MAP_SIZE; ++j){
|
for(j = 0; j < MAX_MAP_SIZE; ++j){
|
||||||
vis[i][j] = TRUE;
|
vis[i][j] = TRUE;
|
||||||
seen[i][j] = FALSE;
|
seen[i][j] = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initObjects();
|
initObjects();
|
||||||
|
loadMap("map_file.map");
|
||||||
|
|
||||||
errcode_t rc = readMapData("map_file.map", &map, &mW, &mH);
|
fov_settings_init(&fov_settings);
|
||||||
if(rc != NO_ERROR){
|
fov_settings_set_opacity_test_function(&fov_settings, opaque);
|
||||||
fprintf(stderr, "\t%s: readMapData() returned %d\n", __FILE__, rc);
|
fov_settings_set_apply_lighting_function(&fov_settings, apply);
|
||||||
exit(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
game_obj_t * objsP = objs;
|
|
||||||
rc = readMapObjects("map_file.map", &objsP, &nO);
|
|
||||||
if(rc != NO_ERROR){
|
|
||||||
fprintf(stderr, "\t%s: readMapObjects() returned %d\n", __FILE__, rc);
|
|
||||||
exit(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
setPlayerStart();
|
|
||||||
|
|
||||||
fov_settings_init(&fov_settings);
|
|
||||||
fov_settings_set_opacity_test_function(&fov_settings, opaque);
|
|
||||||
fov_settings_set_apply_lighting_function(&fov_settings, apply);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void input(){
|
void input(){
|
||||||
@@ -99,7 +99,6 @@ void input(){
|
|||||||
key = getch();
|
key = getch();
|
||||||
|
|
||||||
if(key != ERR){
|
if(key != ERR){
|
||||||
fprintf(stderr, "\t%s: Caught keycode %d\n", __FILE__, key);
|
|
||||||
if(key == KEY_UP) uK = TRUE;
|
if(key == KEY_UP) uK = TRUE;
|
||||||
if(key == KEY_DOWN) dK = TRUE;
|
if(key == KEY_DOWN) dK = TRUE;
|
||||||
if(key == KEY_LEFT) lK = TRUE;
|
if(key == KEY_LEFT) lK = TRUE;
|
||||||
@@ -108,32 +107,133 @@ void input(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
gsname_t update(){
|
gsname_t update(){
|
||||||
int iX, iY;
|
clock_t msgNow, delta;
|
||||||
|
int i, j, k, d, iX, iY, nX, nY;
|
||||||
|
|
||||||
iX = player.x;
|
iX = player.x;
|
||||||
iY = player.y;
|
iY = player.y;
|
||||||
|
nX = iX;
|
||||||
|
nY = iY;
|
||||||
|
|
||||||
|
if(uK) nY = iY - 1 < 0 ? mH - 1 : iY - 1;
|
||||||
|
|
||||||
|
if(dK) nY = (iY + 1) % mH;
|
||||||
|
|
||||||
|
if(lK) nX = iX - 1 < 0 ? mW - 1 : iX - 1;
|
||||||
|
|
||||||
|
if(rK) nX = (iX + 1) % mW;
|
||||||
|
|
||||||
|
/* Find if the player is standing on an exit, then load the next map. */
|
||||||
|
for(i = 0; i < nO; i++){
|
||||||
|
if(objs[i].type == EXIT){
|
||||||
|
if(objs[i].x == iY && objs[i].y == iX){
|
||||||
|
player.x = objs[i].eX;
|
||||||
|
player.y = objs[i].eY;
|
||||||
|
loadMap(objs[i].target);
|
||||||
|
return IN_GAME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: use keys.*/
|
||||||
|
for(i = 0; i < nO; i++){
|
||||||
|
if(objs[i].type == KEY){
|
||||||
|
if(objs[i].x == iY && objs[i].y == iX){
|
||||||
|
keys[freeKey] = objs[i].id;
|
||||||
|
objs[i].type = NONE;
|
||||||
|
for(j = 0; keyMsg[j] && j < 128; j++){
|
||||||
|
msg[j] = keyMsg[j];
|
||||||
|
}
|
||||||
|
newMsg = TRUE;
|
||||||
|
msgThen = clock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Listen to a person. */
|
||||||
|
for(i = 0; i < nO; i++){
|
||||||
|
if(objs[i].type == PERSON){
|
||||||
|
if(objs[i].x == nY && objs[i].y == nX){
|
||||||
|
for(k = 0; k < nO; k++)
|
||||||
|
if(objs[k].type == DIALOG && objs[k].id == objs[i].dId) break;
|
||||||
|
|
||||||
|
for(j = 0; objs[i].name[j] && j < 128; j++)
|
||||||
|
msg[j] = objs[i].name[j];
|
||||||
|
|
||||||
|
for(d = 0; saysMsg[d] && j < 128; j++, d++)
|
||||||
|
msg[j] = saysMsg[d];
|
||||||
|
|
||||||
|
for(d = 0; objs[k].dialog[d] && j < 128; j++, d++)
|
||||||
|
msg[j] = objs[k].dialog[d];
|
||||||
|
|
||||||
|
newMsg = TRUE;
|
||||||
|
msgThen = clock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < nO; i++){
|
||||||
|
if(objs[i].type == DOOR){
|
||||||
|
if(objs[i].x == nY && objs[i].y == nX){
|
||||||
|
if(!objs[i].unlocked){
|
||||||
|
for(j = 0; j < MAX_KEYS; j++){
|
||||||
|
if(keys[j] == objs[i].id){
|
||||||
|
objs[i].unlocked = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(objs[i].unlocked){
|
||||||
|
for(j = 0; openDoor[j] && j < 128; j++){
|
||||||
|
msg[j] = openDoor[j];
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
for(j = 0; doorLock[j] && j < 128; j++){
|
||||||
|
msg[j] = doorLock[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newMsg = TRUE;
|
||||||
|
msgThen = clock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newMsg){
|
||||||
|
msgNow = clock();
|
||||||
|
delta = msgNow - msgThen;
|
||||||
|
if((int)delta / (int)CLOCKS_PER_SEC >= 4){
|
||||||
|
msgThen = msgNow;
|
||||||
|
for(j = 0; j < 128; j++){
|
||||||
|
msg[j] = '\0';
|
||||||
|
}
|
||||||
|
newMsg = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the player. */
|
||||||
if(uK){
|
if(uK){
|
||||||
iY = iY - 1 < 0 ? mH - 1 : iY - 1;
|
iY = iY - 1 < 0 ? mH - 1 : iY - 1;
|
||||||
if((map[iY][iX].f > WINDOW_WALL && map[iY][iX].f <= WATER) || map[iY][iX].f == SECRET_WALL) player.y = iY;
|
if(canMoveTo(iY, iX)) player.y = iY;
|
||||||
uK = FALSE;
|
uK = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dK){
|
if(dK){
|
||||||
iY = (iY + 1) % mH;
|
iY = (iY + 1) % mH;
|
||||||
if((map[iY][iX].f > WINDOW_WALL && map[iY][iX].f <= WATER) || map[iY][iX].f == SECRET_WALL) player.y = iY;
|
if(canMoveTo(iY, iX)) player.y = iY;
|
||||||
dK = FALSE;
|
dK = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lK){
|
if(lK){
|
||||||
iX = iX - 1 < 0 ? mW - 1 : iX - 1;
|
iX = iX - 1 < 0 ? mW - 1 : iX - 1;
|
||||||
if((map[iY][iX].f > WINDOW_WALL && map[iY][iX].f <= WATER) || map[iY][iX].f == SECRET_WALL) player.x = iX;
|
if(canMoveTo(iY, iX)) player.x = iX;
|
||||||
lK = FALSE;
|
lK = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rK){
|
if(rK){
|
||||||
iX = (iX + 1) % mW;
|
iX = (iX + 1) % mW;
|
||||||
if((map[iY][iX].f > WINDOW_WALL && map[iY][iX].f <= WATER) || map[iY][iX].f == SECRET_WALL) player.x = iX;
|
if(canMoveTo(iY, iX)) player.x = iX;
|
||||||
rK = FALSE;
|
rK = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +242,7 @@ gsname_t update(){
|
|||||||
|
|
||||||
void render(int w, int h){
|
void render(int w, int h){
|
||||||
clock_t now, delta;
|
clock_t now, delta;
|
||||||
int i, j, pi, pj, ioff, joff, di, dj;
|
int i, j, k, pi, pj, ioff, joff, di, dj;
|
||||||
|
|
||||||
now = clock();
|
now = clock();
|
||||||
delta = now - then;
|
delta = now - then;
|
||||||
@@ -151,16 +251,16 @@ void render(int w, int h){
|
|||||||
w_mov = TRUE;
|
w_mov = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pi = (((w - 1) - 27) / 2) + 27;
|
pi = (((w - 1) - 1) / 2) + 1;
|
||||||
pj = (h - 2) / 2 + 1;
|
pj = (h - 3) / 2 + 1;
|
||||||
|
|
||||||
ioff = (w - 28) / 2;
|
ioff = (w - 28 - 27) / 2;
|
||||||
joff = (h - 2) / 2;
|
joff = (h - 3) / 2;
|
||||||
|
|
||||||
fov_circle(&fov_settings, &map, NULL, player.x, player.y, (MAX_MAP_SIZE / 2) - 1);
|
fov_circle(&fov_settings, &map, NULL, player.x, player.y, (MAX_MAP_SIZE / 2) - 1);
|
||||||
|
|
||||||
for(i = 27; i < w - 1; i++){
|
for(i = 1; i < w - 1; i++){
|
||||||
for(j = 1; j < h - 1; j++){
|
for(j = 1; j < h - 3; j++){
|
||||||
move(j, i);
|
move(j, i);
|
||||||
|
|
||||||
di = i - 27 + player.x - ioff;
|
di = i - 27 + player.x - ioff;
|
||||||
@@ -169,67 +269,84 @@ void render(int w, int h){
|
|||||||
if( di < 0 || di >= mW || dj < 0 || dj >= mH ){
|
if( di < 0 || di >= mW || dj < 0 || dj >= mH ){
|
||||||
printw(" ");
|
printw(" ");
|
||||||
}else{
|
}else{
|
||||||
if(vis[dj][di] || seen[dj][di]){
|
if(vis[dj][di] || seen[dj][di]){
|
||||||
switch(map[dj][di].f){
|
switch(map[dj][di].f){
|
||||||
case WATER:
|
case WATER:
|
||||||
attron(COLOR_PAIR(DW_COLOR));
|
attron(COLOR_PAIR(DW_COLOR));
|
||||||
if(w_mov)
|
if(w_mov)
|
||||||
wmap[dj][di] = !wmap[dj][di];
|
wmap[dj][di] = !wmap[dj][di];
|
||||||
if(wmap[dj][di])
|
if(wmap[dj][di])
|
||||||
printw("\u2248");
|
printw("\u2248");
|
||||||
else
|
else
|
||||||
printw("~");
|
printw("~");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VOID:
|
case VOID:
|
||||||
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
||||||
else attron(COLOR_PAIR(MN_COLOR));
|
else attron(COLOR_PAIR(MN_COLOR));
|
||||||
printw(" ");
|
printw(" ");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EMPTY_FLOOR:
|
case EMPTY_FLOOR:
|
||||||
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
||||||
else attron(COLOR_PAIR(MN_COLOR));
|
else attron(COLOR_PAIR(MN_COLOR));
|
||||||
printw(" ");
|
printw(" ");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RUG:
|
case RUG:
|
||||||
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
||||||
else attron(COLOR_PAIR(SN_COLOR));
|
else attron(COLOR_PAIR(SN_COLOR));
|
||||||
printw("\u2592");
|
printw("\u2592");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WINDOW_WALL:
|
case WINDOW_WALL:
|
||||||
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
||||||
else attron(COLOR_PAIR(SW_COLOR));
|
else attron(COLOR_PAIR(SW_COLOR));
|
||||||
printw("\u2591");
|
printw("\u2591");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLEAR_WALL:
|
case CLEAR_WALL:
|
||||||
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
||||||
else attron(COLOR_PAIR(SW_COLOR));
|
else attron(COLOR_PAIR(SW_COLOR));
|
||||||
printw("\u2588");
|
printw("\u2588");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SECRET_WALL:
|
case SECRET_WALL:
|
||||||
case SOLID_WALL:
|
case SOLID_WALL:
|
||||||
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
||||||
else attron(COLOR_PAIR(MN_COLOR));
|
else attron(COLOR_PAIR(MN_COLOR));
|
||||||
printw("\u2588");
|
printw("\u2588");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NEON_WALL:
|
case NEON_WALL:
|
||||||
drawNeon(dj, di, NEON_WALL);
|
drawNeon(dj, di, NEON_WALL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BAR:
|
case BAR:
|
||||||
drawNeon(dj, di, BAR);
|
drawNeon(dj, di, BAR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
attron(COLOR_PAIR(MN_COLOR));
|
move(j, i);
|
||||||
printw(" ");
|
for(k = 0; k < nO; k++){
|
||||||
}
|
if(objs[k].x == dj && objs[k].y == di){
|
||||||
|
if(!vis[dj][di]) attron(COLOR_PAIR(DW_COLOR));
|
||||||
|
else attron(COLOR_PAIR(MN_COLOR));
|
||||||
|
|
||||||
|
if(objs[k].type == DOOR){
|
||||||
|
printw("\u25D9");
|
||||||
|
}else if(objs[k].type == KEY){
|
||||||
|
printw("k");
|
||||||
|
}else if(objs[k].type == PERSON){
|
||||||
|
printw("\u263A");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
attron(COLOR_PAIR(MN_COLOR));
|
||||||
|
printw(" ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,7 +358,7 @@ void render(int w, int h){
|
|||||||
|
|
||||||
drawGui(w, h);
|
drawGui(w, h);
|
||||||
|
|
||||||
for ( i = 0; i < MAX_MAP_SIZE; ++i ) {
|
for ( i = 0; i < MAX_MAP_SIZE; ++i ) {
|
||||||
for(j = 0; j < MAX_MAP_SIZE; ++j){
|
for(j = 0; j < MAX_MAP_SIZE; ++j){
|
||||||
vis[i][j] = FALSE;
|
vis[i][j] = FALSE;
|
||||||
}
|
}
|
||||||
@@ -249,174 +366,241 @@ void render(int w, int h){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void drawNeon(int i, int j, floor_t floor){
|
void drawNeon(int i, int j, floor_t floor){
|
||||||
int r;
|
int r;
|
||||||
bool n, s, e, w;
|
bool n, s, e, w;
|
||||||
|
|
||||||
if(floor == NEON_WALL){
|
if(floor == NEON_WALL){
|
||||||
if(!vis[i][j]) attron(COLOR_PAIR(DW_COLOR));
|
if(!vis[i][j]) attron(COLOR_PAIR(DW_COLOR));
|
||||||
else{
|
else{
|
||||||
r = rand() % 1000;
|
r = rand() % 1000;
|
||||||
if(r < 998)
|
if(r < 998)
|
||||||
attron(COLOR_PAIR(FR_COLOR));
|
attron(COLOR_PAIR(FR_COLOR));
|
||||||
else
|
else
|
||||||
attron(COLOR_PAIR(MN_COLOR));
|
attron(COLOR_PAIR(MN_COLOR));
|
||||||
}
|
}
|
||||||
}else if(floor == BAR){
|
}else if(floor == BAR){
|
||||||
if(!vis[i][j]) attron(COLOR_PAIR(DW_COLOR));
|
if(!vis[i][j]) attron(COLOR_PAIR(DW_COLOR));
|
||||||
else attron(COLOR_PAIR(SN_COLOR));
|
else attron(COLOR_PAIR(SN_COLOR));
|
||||||
}
|
}
|
||||||
|
|
||||||
n = map[i ][j - 1 < 0 ? mH - 1 : j - 1].f == floor;
|
n = map[i ][j - 1 < 0 ? mH - 1 : j - 1].f == floor;
|
||||||
s = map[i ][(j + 1) % mH ].f == floor;
|
s = map[i ][(j + 1) % mH ].f == floor;
|
||||||
e = map[i - 1 < 0 ? mW - 1 : i - 1][j ].f == floor;
|
e = map[i - 1 < 0 ? mW - 1 : i - 1][j ].f == floor;
|
||||||
w = map[(i + 1) % mW ][j ].f == floor;
|
w = map[(i + 1) % mW ][j ].f == floor;
|
||||||
|
|
||||||
if((n && s && e) && (!w)){
|
if((n && s && e) && (!w)){
|
||||||
printw("\u2560");
|
printw("\u2560");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((n || s) && (!e && !w)){
|
if((n || s) && (!e && !w)){
|
||||||
printw("\u2550");
|
printw("\u2550");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((e || w) && (!n && !s)){
|
if((e || w) && (!n && !s)){
|
||||||
printw("\u2551");
|
printw("\u2551");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((e && n) && (!s && !w)){
|
if((e && n) && (!s && !w)){
|
||||||
printw("\u255D");
|
printw("\u255D");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((w && n) && (!s && !e)){
|
if((w && n) && (!s && !e)){
|
||||||
printw("\u2557");
|
printw("\u2557");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((e && s) && (!n && !w)){
|
if((e && s) && (!n && !w)){
|
||||||
printw("\u255A");
|
printw("\u255A");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((w && s) && (!n && !e)){
|
if((w && s) && (!n && !e)){
|
||||||
printw("\u2554");
|
printw("\u2554");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((s && e && w) && (!n)){
|
if((s && e && w) && (!n)){
|
||||||
printw("\u2560");
|
printw("\u2560");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((n && w && e) && (!s)){
|
if((n && w && e) && (!s)){
|
||||||
printw("\u2563");
|
printw("\u2563");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n && s && e && w){
|
if(n && s && e && w){
|
||||||
printw("\u256C");
|
printw("\u256C");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawGui(int w, int h){
|
void drawGui(int w, int h){
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
attron(COLOR_PAIR(BSC_COLOR));
|
attron(COLOR_PAIR(BSC_COLOR));
|
||||||
|
|
||||||
/* Clear the gui space. */
|
/* Clear the gui space. */
|
||||||
for(i = 1; i < 26; i++){
|
for(i = 1; i < w - 1; i++){
|
||||||
for(j = 1; j < h - 1; j++){
|
move(h - 2, i);
|
||||||
move(j, i);
|
printw(" ");
|
||||||
printw(" ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Upper horizontal bar. */
|
/* Upper horizontal bar. */
|
||||||
move(0, 0);
|
move(0, 0);
|
||||||
printw("\u2554");
|
printw("\u2554");
|
||||||
for(i = 0; i < w - 2; i++){
|
for(i = 0; i < w - 2; i++){
|
||||||
if(i != 25){
|
printw("\u2550");
|
||||||
printw("\u2550");
|
|
||||||
}else{
|
|
||||||
printw("\u2566");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
printw("\u2557");
|
printw("\u2557");
|
||||||
|
|
||||||
/* Lower horizontal bar. */
|
/* Lower horizontal bars. */
|
||||||
|
move(h - 3, 0);
|
||||||
|
printw("\u255A");
|
||||||
|
for(i = 0; i < w - 2; i++){
|
||||||
|
printw("\u2550");
|
||||||
|
}
|
||||||
|
printw("\u255D");
|
||||||
|
|
||||||
move(h - 1, 0);
|
move(h - 1, 0);
|
||||||
printw("\u255A");
|
printw("\u255A");
|
||||||
for(i = 0; i < w - 2; i++){
|
for(i = 0; i < w - 2; i++){
|
||||||
if(i != 25){
|
printw("\u2550");
|
||||||
printw("\u2550");
|
|
||||||
}else{
|
|
||||||
printw("\u2569");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
printw("\u255D");
|
printw("\u255D");
|
||||||
|
|
||||||
/* Vertical bars. */
|
/* Vertical bars. */
|
||||||
for(i = 1; i < h - 1; i++){
|
for(i = 1; i < h - 1; i++){
|
||||||
move(i, 0);
|
move(i, 0);
|
||||||
printw("\u2551");
|
if(i != h - 3) printw("\u2551");
|
||||||
move(i, 26);
|
else printw("\u2560");
|
||||||
printw("\u2551");
|
|
||||||
move(i, w-1);
|
move(i, w-1);
|
||||||
printw("\u2551");
|
if(i != h - 3) printw("\u2551");
|
||||||
|
else printw("\u2563");
|
||||||
|
}
|
||||||
|
|
||||||
|
move(h - 2, 1);
|
||||||
|
for(i = 0; msg[i] && i < w - 2; i++){
|
||||||
|
printw("%c", msg[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPlayerStart(){
|
void setPlayerStart(){
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < nO; i++){
|
for(i = 0; i < nO; i++){
|
||||||
if(objs[i].type == PLAYER_START){
|
if(objs[i].type == PLAYER_START){
|
||||||
player.y = objs[i].sX;
|
player.y = objs[i].sX;
|
||||||
player.x = objs[i].sY;
|
player.x = objs[i].sY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initObjects(){
|
void initObjects(){
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < MAX_OBJECTS; ++i){
|
for(i = 0; i < MAX_OBJECTS; ++i){
|
||||||
objs[i].type = NONE;
|
objs[i].type = NONE;
|
||||||
objs[i].x = 0;
|
objs[i].x = 0;
|
||||||
objs[i].y = 0;
|
objs[i].y = 0;
|
||||||
objs[i].eX = 0;
|
objs[i].eX = 0;
|
||||||
objs[i].eY = 0;
|
objs[i].eY = 0;
|
||||||
objs[i].sX = 0;
|
objs[i].sX = 0;
|
||||||
objs[i].sY = 0;
|
objs[i].sY = 0;
|
||||||
objs[i].id = 0;
|
objs[i].id = 0;
|
||||||
objs[i].dId = 0;
|
objs[i].dId = 0;
|
||||||
objs[i].name[0] = '\0';
|
objs[i].name[0] = '\0';
|
||||||
objs[i].target[0] = '\0';
|
objs[i].target[0] = '\0';
|
||||||
objs[i].dialog[0] = '\0';
|
objs[i].dialog[0] = '\0';
|
||||||
objs[i].unlocked = 0;
|
objs[i].unlocked = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initKeys(){
|
||||||
|
int i;
|
||||||
|
|
||||||
|
freeKey = 0;
|
||||||
|
for(i = 0; i < MAX_KEYS; ++i){
|
||||||
|
keys[i] = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply(void *map, int x, int y, int dx, int dy, void *src){
|
void apply(void *map, int x, int y, int dx, int dy, void *src){
|
||||||
if(x < 0 || x >= MAX_MAP_SIZE) return;
|
if(x < 0 || x >= MAX_MAP_SIZE) return;
|
||||||
if(y < 0 || y >= MAX_MAP_SIZE) return;
|
if(y < 0 || y >= MAX_MAP_SIZE) return;
|
||||||
|
|
||||||
vis[y][x] = TRUE;
|
vis[y][x] = TRUE;
|
||||||
seen[y][x] = TRUE;
|
seen[y][x] = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool opaque(void *m, int x, int y){
|
bool opaque(void *m, int x, int y){
|
||||||
if(x < 0 || x >= MAX_MAP_SIZE) return FALSE;
|
int k;
|
||||||
if(y < 0 || y >= MAX_MAP_SIZE) return FALSE;
|
if(x < 0 || x >= MAX_MAP_SIZE) return FALSE;
|
||||||
|
if(y < 0 || y >= MAX_MAP_SIZE) return FALSE;
|
||||||
|
|
||||||
if(map[y][x].f == SOLID_WALL || map[y][x].f == SECRET_WALL){
|
if(map[y][x].f == SOLID_WALL || map[y][x].f == SECRET_WALL){
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}else{
|
}else{
|
||||||
return FALSE;
|
for(k = 0; k < nO; k++){
|
||||||
}
|
if(objs[k].type == DOOR){
|
||||||
|
if(objs[k].x == y && objs[k].y == x){
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadMap(const char * file){
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
errcode_t rc = readMapData(file, &map, &mW, &mH);
|
||||||
|
if(rc != NO_ERROR){
|
||||||
|
fprintf(stderr, "\t%s.loadMap(): readMapData() returned %d\n", __FILE__, rc);
|
||||||
|
exit(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
game_obj_t * objsP = objs;
|
||||||
|
rc = readMapObjects(file, &objsP, &nO);
|
||||||
|
if(rc != NO_ERROR){
|
||||||
|
fprintf(stderr, "\t%s.loadMap(): readMapObjects() returned %d\n", __FILE__, rc);
|
||||||
|
exit(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPlayerStart();
|
||||||
|
initKeys();
|
||||||
|
|
||||||
|
for ( i = 0; i < MAX_MAP_SIZE; ++i ) {
|
||||||
|
for(j = 0; j < MAX_MAP_SIZE; ++j){
|
||||||
|
vis[i][j] = FALSE;
|
||||||
|
seen[i][j] = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool canMoveTo(int iY, int iX){
|
||||||
|
int k;
|
||||||
|
|
||||||
|
for(k = 0; k < nO; k++){
|
||||||
|
if(objs[k].x == iY && objs[k].y == iX){
|
||||||
|
if(objs[k].type == DOOR){
|
||||||
|
if(objs[k].unlocked) return TRUE;
|
||||||
|
else return FALSE;
|
||||||
|
}else if(objs[k].type == PERSON){
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((map[iY][iX].f > WINDOW_WALL && map[iY][iX].f <= WATER) || map[iY][iX].f == SECRET_WALL)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
32
src/main.c
32
src/main.c
@@ -28,22 +28,16 @@ static bool resize = FALSE;
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
bool finished = FALSE;
|
bool finished = FALSE;
|
||||||
#if defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__)
|
char * home_dir = getenv("HOME");
|
||||||
char * home_dir = getenv("APPDATA");
|
FILE * f; /* To avoid a warning. */
|
||||||
#elif defined(__linux__) || defined(__GNUC__)
|
clock_t then, now, delta;
|
||||||
char * home_dir = getenv("HOME");
|
unsigned int fps = 0, pfps = 0;
|
||||||
#else
|
char * data_dir;
|
||||||
#error "Unrecognized system."
|
char * log_file;
|
||||||
#endif
|
time_t raw_date;
|
||||||
FILE * f; /* To avoid a warning. */
|
struct tm * current_date;
|
||||||
clock_t then, now, delta;
|
gs_t * states;
|
||||||
unsigned int fps = 0, pfps = 0;
|
int c_state;
|
||||||
char * data_dir;
|
|
||||||
char * log_file;
|
|
||||||
time_t raw_date;
|
|
||||||
struct tm * current_date;
|
|
||||||
gs_t * states;
|
|
||||||
int c_state;
|
|
||||||
|
|
||||||
atexit(leave);
|
atexit(leave);
|
||||||
signal(SIGINT, manage_signal);
|
signal(SIGINT, manage_signal);
|
||||||
@@ -70,15 +64,11 @@ int main() {
|
|||||||
fprintf(stderr, "%s", asctime(current_date));
|
fprintf(stderr, "%s", asctime(current_date));
|
||||||
|
|
||||||
/* Try to create the data directory with permissions 775. */
|
/* Try to create the data directory with permissions 775. */
|
||||||
if(mkdir(data_dir, S_IRWXU | S_IWGRP | S_IRGRP| S_IROTH | S_IXOTH) == 0){
|
if(mkdir(data_dir, S_IRWXU | S_IWGRP | S_IRGRP| S_IROTH | S_IXOTH) != 0){
|
||||||
/* The data directory was sucessfully created. */
|
|
||||||
}else{
|
|
||||||
if(errno != EEXIST){
|
if(errno != EEXIST){
|
||||||
/* The directory does not exists and could not be created. */
|
/* The directory does not exists and could not be created. */
|
||||||
perror("\t" __FILE__);
|
perror("\t" __FILE__);
|
||||||
fprintf(stderr, "\tdata_dir is: %s\n", data_dir);
|
fprintf(stderr, "\tdata_dir is: %s\n", data_dir);
|
||||||
}else{
|
|
||||||
/* The directory already exits. */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
586
src/map.c
586
src/map.c
@@ -11,360 +11,360 @@
|
|||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
errcode_t readMapData(const char * file, map_cell_t *** map, int * w, int * h){
|
errcode_t readMapData(const char * file, map_cell_t *** map, int * w, int * h){
|
||||||
size_t n = 2048;
|
size_t n = 2048;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
FILE * f;
|
FILE * f;
|
||||||
|
|
||||||
f = fopen(file, "r");
|
f = fopen(file, "r");
|
||||||
if(f == NULL) return FILE_NOT_FOUND;
|
if(f == NULL) return FILE_NOT_FOUND;
|
||||||
|
|
||||||
buffer = (char*)calloc(n + 1, sizeof(char));
|
buffer = (char*)calloc(n + 1, sizeof(char));
|
||||||
if(buffer == NULL) return OUT_OF_MEMORY;
|
if(buffer == NULL) return OUT_OF_MEMORY;
|
||||||
|
|
||||||
while(getline(&buffer, &n, f) != -1){
|
while(getline(&buffer, &n, f) != -1){
|
||||||
if(strcmp(buffer, "[MAP]\n") == 0){
|
if(strcmp(buffer, "[MAP]\n") == 0){
|
||||||
int rc, i, j;
|
int rc, i, j;
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
fprintf(stderr, "\t%s.readMapData() : found a map.\n", __FILE__);
|
fprintf(stderr, "\t%s.readMapData() : found a map.\n", __FILE__);
|
||||||
|
|
||||||
rc = getline(&buffer, &n, f);
|
rc = getline(&buffer, &n, f);
|
||||||
if(rc == -1){
|
if(rc == -1){
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return PREMATURE_EOF;
|
return PREMATURE_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
*w = strtol(buffer, &end, 10);
|
*w = strtol(buffer, &end, 10);
|
||||||
*h = strtol(end, NULL, 10);
|
*h = strtol(end, NULL, 10);
|
||||||
|
|
||||||
if((*w <= 0 || *w > MAX_MAP_SIZE) || (*h <= 0 || *h > MAX_MAP_SIZE)){
|
if((*w <= 0 || *w > MAX_MAP_SIZE) || (*h <= 0 || *h > MAX_MAP_SIZE)){
|
||||||
*w = -1;
|
*w = -1;
|
||||||
*h = -1;
|
*h = -1;
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return MAP_TOO_LARGE;
|
return MAP_TOO_LARGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < *w; i++){
|
for(i = 0; i < *w; i++){
|
||||||
rc = getline(&buffer, &n, f);
|
rc = getline(&buffer, &n, f);
|
||||||
if(rc == -1){
|
if(rc == -1){
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return PREMATURE_EOF;
|
return PREMATURE_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip commentaries. */
|
/* Skip commentaries. */
|
||||||
if(buffer[0] == '%'){
|
if(buffer[0] == '%'){
|
||||||
i--;
|
i--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(j = 0; buffer[j] && j < *h; j++){
|
for(j = 0; buffer[j] && j < *h; j++){
|
||||||
if(buffer[j] >= '0' && buffer[j] <= '9'){
|
if(buffer[j] >= '0' && buffer[j] <= '9'){
|
||||||
switch(buffer[j]){
|
switch(buffer[j]){
|
||||||
case '0': (*map)[i][j].f = VOID; break;
|
case '0': (*map)[i][j].f = VOID; break;
|
||||||
case '1': (*map)[i][j].f = SOLID_WALL; break;
|
case '1': (*map)[i][j].f = SOLID_WALL; break;
|
||||||
case '2': (*map)[i][j].f = SECRET_WALL; break;
|
case '2': (*map)[i][j].f = SECRET_WALL; break;
|
||||||
case '3': (*map)[i][j].f = CLEAR_WALL; break;
|
case '3': (*map)[i][j].f = CLEAR_WALL; break;
|
||||||
case '4': (*map)[i][j].f = NEON_WALL; break;
|
case '4': (*map)[i][j].f = NEON_WALL; break;
|
||||||
case '5': (*map)[i][j].f = WINDOW_WALL; break;
|
case '5': (*map)[i][j].f = WINDOW_WALL; break;
|
||||||
case '6': (*map)[i][j].f = EMPTY_FLOOR; break;
|
case '6': (*map)[i][j].f = EMPTY_FLOOR; break;
|
||||||
case '7': (*map)[i][j].f = RUG; break;
|
case '7': (*map)[i][j].f = RUG; break;
|
||||||
case '8': (*map)[i][j].f = WATER; break;
|
case '8': (*map)[i][j].f = WATER; break;
|
||||||
case '9': (*map)[i][j].f = BAR; break;
|
case '9': (*map)[i][j].f = BAR; break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "\t%s.readMapData() : Invalid character %c in map file %s\n", __FILE__, buffer[j], file);
|
fprintf(stderr, "\t%s.readMapData() : Invalid character %c in map file %s\n", __FILE__, buffer[j], file);
|
||||||
(*map)[i][j].f = VOID;
|
(*map)[i][j].f = VOID;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
fprintf(stderr, "\t%s.readMapData() : Invalid character %c in map file %s\n", __FILE__, buffer[j], file);
|
fprintf(stderr, "\t%s.readMapData() : Invalid character %c in map file %s\n", __FILE__, buffer[j], file);
|
||||||
(*map)[i][j].f = VOID;
|
(*map)[i][j].f = VOID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Skip the rest of the file. */
|
/* Skip the rest of the file. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
errcode_t readMapObjects(const char * file, game_obj_t ** objArr, int *nObj){
|
errcode_t readMapObjects(const char * file, game_obj_t ** objArr, int *nObj){
|
||||||
size_t n = 2048;
|
size_t n = 2048;
|
||||||
int rc;
|
int rc;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
FILE * f;
|
FILE * f;
|
||||||
|
|
||||||
*nObj = 0;
|
*nObj = 0;
|
||||||
|
|
||||||
f = fopen(file, "r");
|
f = fopen(file, "r");
|
||||||
if(f == NULL) return FILE_NOT_FOUND;
|
if(f == NULL) return FILE_NOT_FOUND;
|
||||||
|
|
||||||
buffer = (char*)calloc(n + 1, sizeof(char));
|
buffer = (char*)calloc(n + 1, sizeof(char));
|
||||||
if(buffer == NULL) return OUT_OF_MEMORY;
|
if(buffer == NULL) return OUT_OF_MEMORY;
|
||||||
|
|
||||||
rc = getline(&buffer, &n, f);
|
rc = getline(&buffer, &n, f);
|
||||||
if(rc == -1){
|
if(rc == -1){
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return PREMATURE_EOF;
|
return PREMATURE_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(*nObj < MAX_OBJECTS && rc != -1){
|
while(*nObj < MAX_OBJECTS && rc != -1){
|
||||||
if(buffer[0] == '%') continue;
|
if(buffer[0] == '%') continue;
|
||||||
|
|
||||||
if(strcmp(buffer, "[MAP]\n") == 0){
|
if(strcmp(buffer, "[MAP]\n") == 0){
|
||||||
int i, w;
|
int i, w;
|
||||||
|
|
||||||
rc = getline(&buffer, &n, f);
|
rc = getline(&buffer, &n, f);
|
||||||
if(rc == -1){
|
if(rc == -1){
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return PREMATURE_EOF;
|
return PREMATURE_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
w = strtol(buffer, NULL, 10);
|
w = strtol(buffer, NULL, 10);
|
||||||
|
|
||||||
for(i = 0; i <= w; ++i){
|
for(i = 0; i <= w; ++i){
|
||||||
rc = getline(&buffer, &n, f);
|
rc = getline(&buffer, &n, f);
|
||||||
if(rc == -1){
|
if(rc == -1){
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return PREMATURE_EOF;
|
return PREMATURE_EOF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}else if(strcmp(buffer, "[PLAYER]\n") == 0){
|
}else if(strcmp(buffer, "[PLAYER]\n") == 0){
|
||||||
do{
|
do{
|
||||||
rc = getline(&buffer, &n, f);
|
rc = getline(&buffer, &n, f);
|
||||||
if(rc == -1) break;
|
if(rc == -1) break;
|
||||||
|
|
||||||
if(buffer[0] == '%') continue;
|
if(buffer[0] == '%') continue;
|
||||||
else if(buffer[0] == 'p'){
|
else if(buffer[0] == 'p'){
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; buffer[i] && buffer[i] != '='; ++i);
|
for(i = 0; buffer[i] && buffer[i] != '='; ++i);
|
||||||
|
|
||||||
if(strncmp(buffer, "player =", i) == 0){
|
if(strncmp(buffer, "player =", i) == 0){
|
||||||
int sX, sY;
|
int sX, sY;
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
sX = strtol(&buffer[i + 1], &end, 10);
|
sX = strtol(&buffer[i + 1], &end, 10);
|
||||||
sY = strtol(end, NULL, 10);
|
sY = strtol(end, NULL, 10);
|
||||||
|
|
||||||
(*objArr)[*nObj].type = PLAYER_START;
|
(*objArr)[*nObj].type = PLAYER_START;
|
||||||
(*objArr)[*nObj].sX = sX;
|
(*objArr)[*nObj].sX = sX;
|
||||||
(*objArr)[*nObj].sY = sY;
|
(*objArr)[*nObj].sY = sY;
|
||||||
|
|
||||||
*nObj += 1;
|
*nObj += 1;
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): Skipped invalid data in PLAYER key in map file %s.\n", __FILE__, file);
|
fprintf(stderr, "\t%s.readMapObjects(): Skipped invalid data in PLAYER key in map file %s.\n", __FILE__, file);
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): The invalid line is %s.\n", __FILE__, buffer);
|
fprintf(stderr, "\t%s.readMapObjects(): The invalid line is %s.\n", __FILE__, buffer);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}while(buffer[0] != '[');
|
}while(buffer[0] != '[');
|
||||||
|
|
||||||
}else if(strcmp(buffer, "[EXITS]\n") == 0){
|
}else if(strcmp(buffer, "[EXITS]\n") == 0){
|
||||||
do{
|
do{
|
||||||
rc = getline(&buffer, &n, f);
|
rc = getline(&buffer, &n, f);
|
||||||
if(rc == -1) break;
|
if(rc == -1) break;
|
||||||
|
|
||||||
if(buffer[0] == '%') continue;
|
if(buffer[0] == '%') continue;
|
||||||
else if(buffer[0] == 'e'){
|
else if(buffer[0] == 'e'){
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; buffer[i] && buffer[i] != '='; ++i);
|
for(i = 0; buffer[i] && buffer[i] != '='; ++i);
|
||||||
|
|
||||||
if(strncmp(buffer, "exit =", i) == 0){
|
if(strncmp(buffer, "exit =", i) == 0){
|
||||||
int x, y, eX, eY;
|
int x, y, eX, eY;
|
||||||
char *end, *end2, *end3;
|
char *end, *end2, *end3;
|
||||||
|
|
||||||
x = strtol(&buffer[i + 1], &end, 10);
|
x = strtol(&buffer[i + 1], &end, 10);
|
||||||
y = strtol(end, &end2, 10);
|
y = strtol(end, &end2, 10);
|
||||||
end2++;
|
end2++;
|
||||||
|
|
||||||
(*objArr)[*nObj].type = EXIT;
|
(*objArr)[*nObj].type = EXIT;
|
||||||
(*objArr)[*nObj].x = x;
|
(*objArr)[*nObj].x = x;
|
||||||
(*objArr)[*nObj].y = y;
|
(*objArr)[*nObj].y = y;
|
||||||
|
|
||||||
for(i = 0; end2[i] && end2[i] != ' '; ++i);
|
for(i = 0; end2[i] && end2[i] != ' '; ++i);
|
||||||
|
|
||||||
strncpy((*objArr)[*nObj].target, end2, i);
|
strncpy((*objArr)[*nObj].target, end2, i);
|
||||||
(*objArr)[*nObj].target[i] = '\0';
|
(*objArr)[*nObj].target[i] = '\0';
|
||||||
|
|
||||||
eX = strtol(&end2[i], &end3, 10);
|
eX = strtol(&end2[i], &end3, 10);
|
||||||
eY = strtol(end3, NULL, 10);
|
eY = strtol(end3, NULL, 10);
|
||||||
|
|
||||||
(*objArr)[*nObj].eX = eX;
|
(*objArr)[*nObj].eX = eX;
|
||||||
(*objArr)[*nObj].eY = eY;
|
(*objArr)[*nObj].eY = eY;
|
||||||
|
|
||||||
*nObj += 1;
|
*nObj += 1;
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): Skipped invalid data in EXITS key in map file %s.\n", __FILE__, file);
|
fprintf(stderr, "\t%s.readMapObjects(): Skipped invalid data in EXITS key in map file %s.\n", __FILE__, file);
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): The invalid line is %s.\n", __FILE__, buffer);
|
fprintf(stderr, "\t%s.readMapObjects(): The invalid line is %s.\n", __FILE__, buffer);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}while(buffer[0] != '[');
|
}while(buffer[0] != '[');
|
||||||
|
|
||||||
}else if(strcmp(buffer, "[DOORS]\n") == 0){
|
}else if(strcmp(buffer, "[DOORS]\n") == 0){
|
||||||
do{
|
do{
|
||||||
rc = getline(&buffer, &n, f);
|
rc = getline(&buffer, &n, f);
|
||||||
if(rc == -1) break;
|
if(rc == -1) break;
|
||||||
|
|
||||||
if(buffer[0] == '%') continue;
|
if(buffer[0] == '%') continue;
|
||||||
else if(buffer[0] == 'd'){
|
else if(buffer[0] == 'd'){
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; buffer[i] && buffer[i] != '='; ++i);
|
for(i = 0; buffer[i] && buffer[i] != '='; ++i);
|
||||||
|
|
||||||
if(strncmp(buffer, "door =", i) == 0){
|
if(strncmp(buffer, "door =", i) == 0){
|
||||||
int dX, dY, dId, un;
|
int dX, dY, dId, un;
|
||||||
char *end, *end2, *end3;
|
char *end, *end2, *end3;
|
||||||
|
|
||||||
dX = strtol(&buffer[i + 1], &end, 10);
|
dX = strtol(&buffer[i + 1], &end, 10);
|
||||||
dY = strtol(end, &end2, 10);
|
dY = strtol(end, &end2, 10);
|
||||||
dId = strtol(end2, &end3, 10);
|
dId = strtol(end2, &end3, 10);
|
||||||
un = strtol(end3, NULL, 10);
|
un = strtol(end3, NULL, 10);
|
||||||
|
|
||||||
(*objArr)[*nObj].type = DOOR;
|
(*objArr)[*nObj].type = DOOR;
|
||||||
(*objArr)[*nObj].x = dX;
|
(*objArr)[*nObj].x = dX;
|
||||||
(*objArr)[*nObj].y = dY;
|
(*objArr)[*nObj].y = dY;
|
||||||
(*objArr)[*nObj].id = dId;
|
(*objArr)[*nObj].id = dId;
|
||||||
(*objArr)[*nObj].unlocked = un;
|
(*objArr)[*nObj].unlocked = un;
|
||||||
|
|
||||||
*nObj += 1;
|
*nObj += 1;
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): Skipped invalid data in DOORS key in map file %s.\n", __FILE__, file);
|
fprintf(stderr, "\t%s.readMapObjects(): Skipped invalid data in DOORS key in map file %s.\n", __FILE__, file);
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): The invalid line is %s.\n", __FILE__, buffer);
|
fprintf(stderr, "\t%s.readMapObjects(): The invalid line is %s.\n", __FILE__, buffer);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}while(buffer[0] != '[');
|
}while(buffer[0] != '[');
|
||||||
|
|
||||||
}else if(strcmp(buffer, "[KEYS]\n") == 0){
|
}else if(strcmp(buffer, "[KEYS]\n") == 0){
|
||||||
do{
|
do{
|
||||||
rc = getline(&buffer, &n, f);
|
rc = getline(&buffer, &n, f);
|
||||||
if(rc == -1) break;
|
if(rc == -1) break;
|
||||||
|
|
||||||
if(buffer[0] == '%') continue;
|
if(buffer[0] == '%') continue;
|
||||||
else if(buffer[0] == 'k'){
|
else if(buffer[0] == 'k'){
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; buffer[i] && buffer[i] != '='; ++i);
|
for(i = 0; buffer[i] && buffer[i] != '='; ++i);
|
||||||
|
|
||||||
if(strncmp(buffer, "key =", i) == 0){
|
if(strncmp(buffer, "key =", i) == 0){
|
||||||
int kX, kY, kId;
|
int kX, kY, kId;
|
||||||
char *end, *end2;
|
char *end, *end2;
|
||||||
|
|
||||||
kX = strtol(&buffer[i + 1], &end, 10);
|
kX = strtol(&buffer[i + 1], &end, 10);
|
||||||
kY = strtol(end, &end2, 10);
|
kY = strtol(end, &end2, 10);
|
||||||
kId = strtol(end2, NULL, 10);
|
kId = strtol(end2, NULL, 10);
|
||||||
|
|
||||||
(*objArr)[*nObj].type = KEY;
|
(*objArr)[*nObj].type = KEY;
|
||||||
(*objArr)[*nObj].x = kX;
|
(*objArr)[*nObj].x = kX;
|
||||||
(*objArr)[*nObj].y = kY;
|
(*objArr)[*nObj].y = kY;
|
||||||
(*objArr)[*nObj].id = kId;
|
(*objArr)[*nObj].id = kId;
|
||||||
|
|
||||||
*nObj += 1;
|
*nObj += 1;
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): Skipped invalid data in KEYS key in map file %s.\n", __FILE__, file);
|
fprintf(stderr, "\t%s.readMapObjects(): Skipped invalid data in KEYS key in map file %s.\n", __FILE__, file);
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): The invalid line is %s.\n", __FILE__, buffer);
|
fprintf(stderr, "\t%s.readMapObjects(): The invalid line is %s.\n", __FILE__, buffer);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}while(buffer[0] != '[');
|
}while(buffer[0] != '[');
|
||||||
|
|
||||||
}else if(strcmp(buffer, "[PERSONS]\n") == 0){
|
}else if(strcmp(buffer, "[PERSONS]\n") == 0){
|
||||||
do{
|
do{
|
||||||
rc = getline(&buffer, &n, f);
|
rc = getline(&buffer, &n, f);
|
||||||
if(rc == -1) break;
|
if(rc == -1) break;
|
||||||
|
|
||||||
if(buffer[0] == '%') continue;
|
if(buffer[0] == '%') continue;
|
||||||
else if(buffer[0] == 'p'){
|
else if(buffer[0] == 'p'){
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; buffer[i] && buffer[i] != '='; ++i);
|
for(i = 0; buffer[i] && buffer[i] != '='; ++i);
|
||||||
|
|
||||||
if(strncmp(buffer, "person =", i) == 0){
|
if(strncmp(buffer, "person =", i) == 0){
|
||||||
int pX, pY, pDId;
|
int pX, pY, pDId;
|
||||||
char *end, *end2;
|
char *end, *end2;
|
||||||
|
|
||||||
pX = strtol(&buffer[i + 1], &end, 10);
|
pX = strtol(&buffer[i + 1], &end, 10);
|
||||||
pY = strtol(end, &end2, 10);
|
pY = strtol(end, &end2, 10);
|
||||||
end2++;
|
end2++;
|
||||||
|
|
||||||
(*objArr)[*nObj].type = PERSON;
|
(*objArr)[*nObj].type = PERSON;
|
||||||
(*objArr)[*nObj].x = pX;
|
(*objArr)[*nObj].x = pX;
|
||||||
(*objArr)[*nObj].y = pY;
|
(*objArr)[*nObj].y = pY;
|
||||||
|
|
||||||
for(i = 0; end2[i] && end2[i] != ' '; ++i);
|
for(i = 0; end2[i] && end2[i] != ' '; ++i);
|
||||||
|
|
||||||
strncpy((*objArr)[*nObj].name, end2, i);
|
strncpy((*objArr)[*nObj].name, end2, i);
|
||||||
(*objArr)[*nObj].name[i] = '\0';
|
(*objArr)[*nObj].name[i] = '\0';
|
||||||
|
|
||||||
pDId = strtol(&end2[i], NULL, 10);
|
pDId = strtol(&end2[i], NULL, 10);
|
||||||
(*objArr)[*nObj].dId = pDId;
|
(*objArr)[*nObj].dId = pDId;
|
||||||
|
|
||||||
*nObj += 1;
|
*nObj += 1;
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): Skipped invalid data in PERSONS key in map file %s.\n", __FILE__, file);
|
fprintf(stderr, "\t%s.readMapObjects(): Skipped invalid data in PERSONS key in map file %s.\n", __FILE__, file);
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): The invalid line is %s.\n", __FILE__, buffer);
|
fprintf(stderr, "\t%s.readMapObjects(): The invalid line is %s.\n", __FILE__, buffer);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}while(buffer[0] != '[');
|
}while(buffer[0] != '[');
|
||||||
|
|
||||||
}else if(strcmp(buffer, "[DIALOGS]\n") == 0){
|
}else if(strcmp(buffer, "[DIALOGS]\n") == 0){
|
||||||
do{
|
do{
|
||||||
rc = getline(&buffer, &n, f);
|
rc = getline(&buffer, &n, f);
|
||||||
if(rc == -1) break;
|
if(rc == -1) break;
|
||||||
|
|
||||||
if(buffer[0] == '%') continue;
|
if(buffer[0] == '%') continue;
|
||||||
else if(buffer[0] == 'd'){
|
else if(buffer[0] == 'd'){
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; buffer[i] && buffer[i] != '='; ++i);
|
for(i = 0; buffer[i] && buffer[i] != '='; ++i);
|
||||||
|
|
||||||
if(strncmp(buffer, "dialog =", i) == 0){
|
if(strncmp(buffer, "dialog =", i) == 0){
|
||||||
int dId;
|
int dId;
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
dId = strtol(&buffer[i + 1], &end, 10);
|
dId = strtol(&buffer[i + 1], &end, 10);
|
||||||
end++;
|
end++;
|
||||||
|
|
||||||
(*objArr)[*nObj].type = DIALOG;
|
(*objArr)[*nObj].type = DIALOG;
|
||||||
(*objArr)[*nObj].id = dId;
|
(*objArr)[*nObj].id = dId;
|
||||||
|
|
||||||
strcpy((*objArr)[*nObj].dialog, end);
|
strcpy((*objArr)[*nObj].dialog, end);
|
||||||
for(i = 0; (*objArr)[*nObj].dialog[i] && (*objArr)[*nObj].dialog[i] != '\n'; ++i);
|
for(i = 0; (*objArr)[*nObj].dialog[i] && (*objArr)[*nObj].dialog[i] != '\n'; ++i);
|
||||||
(*objArr)[*nObj].dialog[i] = '\0';
|
(*objArr)[*nObj].dialog[i] = '\0';
|
||||||
|
|
||||||
*nObj += 1;
|
*nObj += 1;
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): Skipped invalid data in DIALOGS key in map file %s.\n", __FILE__, file);
|
fprintf(stderr, "\t%s.readMapObjects(): Skipped invalid data in DIALOGS key in map file %s.\n", __FILE__, file);
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): The invalid line is %s.\n", __FILE__, buffer);
|
fprintf(stderr, "\t%s.readMapObjects(): The invalid line is %s.\n", __FILE__, buffer);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}while(buffer[0] != '[');
|
}while(buffer[0] != '[');
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
fprintf(stderr, "\t%s.readMapObjects(): Found invalid key in map file %s. Key is %s\n", __FILE__, file, buffer);
|
fprintf(stderr, "\t%s.readMapObjects(): Found invalid key in map file %s. Key is %s\n", __FILE__, file, buffer);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return INVALID_KEY;
|
return INVALID_KEY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user