diff --git a/Makefile b/Makefile index ff64137..915c81d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = gcc -SOURCES = src/main.c src/game_state.c src/in_game.c -OBJECTS = obj/main.o obj/game_state.o obj/in_game.o +SOURCES = src/main.c src/game_state.c src/in_game.c src/map.c +OBJECTS = obj/main.o obj/game_state.o obj/in_game.o obj/map.o TARGET = bin/cyjam CFLAGS = -Wall -I./include -std=c99 LDFLAGS = -L./lib @@ -21,7 +21,10 @@ obj/main.o: src/main.c include/constants.h include/game_state.h obj/game_state.o: src/game_state.c include/game_state.h include/in_game.h $(CC) -c -o $@ $< $(CFLAGS) -obj/in_game.o: src/in_game.c include/in_game.h include/game_state.h +obj/in_game.o: src/in_game.c include/in_game.h include/game_state.h include/map.h + $(CC) -c -o $@ $< $(CFLAGS) + +obj/map.o: src/map.c include/map.h $(CC) -c -o $@ $< $(CFLAGS) clean: diff --git a/editor/editor.py b/editor/editor.py index aa9f6f3..6d691df 100755 --- a/editor/editor.py +++ b/editor/editor.py @@ -13,10 +13,10 @@ Usage: *) Left click to place an object on the game_map. Objects have to be edited by hand once the game_map has been saved. Use - the keys 'd', 'k', 'p', 'n', 'e' and 'q' to set the active object type. - The active object type is displayed on the title bar. + the keys 'd', 'k', 'p', 'n' and 'e' to set the active object type. The + active object type is displayed on the title bar. - *) Press 'p' to set the player's starting position. + *) Press 'q' to set the player's starting position. *) Press 's' to save the map to the text file 'map_file.map'. This will replace any previous map with the same name! diff --git a/include/map.h b/include/map.h new file mode 100644 index 0000000..a38a962 --- /dev/null +++ b/include/map.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2014, Miguel Angel Astor Romero. All rights reserved. + * See the file LICENSE for more details. + */ + +#ifndef MAP_H +#define MAP_H + +static const int MAX_MAP_SIZE = 64; + +typedef enum FLOOR_TYPES { + VOID = 0, + SOLID_WALL, + SECRET_WALL, + CLEAR_WALL, + NEON_WALL, + WINDOW_WALL, + EMPTY_FLOOR, + RUG, + WATER, + BAR + } floor_t; + +typedef enum OBJECT_TYPES { + DOOR = 0, + KEY, + PERSON, + PLAYER_START, + EXIT, + NONE = 9989 + } obj_t; + +typedef enum ERROR_CODES { + NO_ERROR = 0, + FILE_NOT_FOUND, + OUT_OF_MEMORY, + PREMATURE_EOF, + MAP_TOO_LARGE + } errcode_t; + +typedef struct MAP_CELL{ + floor_t f; +} map_cell_t; + +extern errcode_t readMapData(const char *, map_cell_t ***, int *, int *); + +#endif diff --git a/src/in_game.c b/src/in_game.c index 9375aeb..32b10b9 100644 --- a/src/in_game.c +++ b/src/in_game.c @@ -10,6 +10,7 @@ #include "constants.h" #include "in_game.h" +#include "map.h" typedef struct PLAYER { unsigned short x; @@ -23,6 +24,8 @@ static bool w_mov = FALSE; static bool uK, dK, lK, rK; static clock_t then; static player_t player; +static map_cell_t ** map; +static int mW, mH; void input(); gsname_t update(); @@ -32,7 +35,7 @@ void setPlayerStart(); void initInGameState( gs_t * gs) { int n, i, j; - float ** map; + float ** fmap; gs->name = IN_GAME; gs->input = &input; @@ -43,9 +46,9 @@ void initInGameState( gs_t * gs) { srand(time(NULL)); - map = ( float ** ) malloc ( sizeof ( float * ) * n); + fmap = ( float ** ) malloc ( sizeof ( float * ) * n); for ( i = 0; i < n; ++i ) { - map[ i ] = ( float * ) calloc ( n, sizeof ( float ) ); + fmap[ i ] = ( float * ) calloc ( n, sizeof ( float ) ); } imap = ( int ** ) malloc ( sizeof ( int * ) * n); @@ -61,21 +64,36 @@ void initInGameState( gs_t * gs) { } } - ds ( &map, n ); + ds ( &fmap, n ); island ( &imap, n ); normInt ( &imap, n ); - norm ( &map, n ); - mult ( &map, &imap, n ); + norm ( &fmap, n ); + mult ( &fmap, &imap, n ); smooth( &imap, n ); normInt ( &imap, n ); for ( i = 0; i < n; ++i ) { - free(map[ i ]); + free(fmap[ i ]); } - free(map); + free(fmap); setPlayerStart(); uK = dK = lK = rK = FALSE; + + /*map = ( map_cell_t ** ) malloc ( sizeof ( map_cell_t * ) * 32); + for ( i = 0; i < 32; ++i ) { + map[ i ] = ( map_cell_t * ) calloc ( 32 , sizeof ( map_cell_t ) ); + } + + errcode_t rc = readMapData("map_file.map", &map, &mW, &mH); + + fprintf(stderr, "\t%s: readMapData() returned %d\n", __FILE__, rc); + fprintf(stderr, "\t%s: Map size is (%d, %d).\n", __FILE__, mW, mH); + + for ( i = 0; i < 32; ++i ) { + free(map[ i ]); + } + free(map);*/ } void input(){ diff --git a/src/map.c b/src/map.c new file mode 100644 index 0000000..38a46ba --- /dev/null +++ b/src/map.c @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2014, Miguel Angel Astor Romero. All rights reserved. + * See the file LICENSE for more details. + */ +#define _GNU_SOURCE +#include +#include +#include + +#include "map.h" + +errcode_t readMapData(const char * file, map_cell_t *** map, int * w, int * h){ + char *buffer; + FILE * f; + size_t n = 2048; + + f = fopen(file, "r"); + if(f == NULL) return FILE_NOT_FOUND; + + buffer = (char*)calloc(n + 1, sizeof(char)); + if(buffer == NULL) return OUT_OF_MEMORY; + + while(getline(&buffer, &n, f) != -1){ + if(strcmp(buffer, "[MAP]\n") == 0){ + int rc, i, j; + char *end; + + fprintf(stderr, "\t%s.readMapData() : found a map.\n", __FILE__); + + rc = getline(&buffer, &n, f); + if(rc == -1){ + free(buffer); + return PREMATURE_EOF; + } + + *w = strtol(buffer, &end, 10); + *h = strtol(end, NULL, 10); + + if((*w <= 0 || *w > MAX_MAP_SIZE) || (*h <= 0 || *h > MAX_MAP_SIZE)){ + *w = -1; + *h = -1; + free(buffer); + return MAP_TOO_LARGE; + } + + for(i = 0; i < *w; i++){ + rc = getline(&buffer, &n, f); + if(rc == -1){ + free(buffer); + return PREMATURE_EOF; + } + + /* Skip commentaries. */ + if(buffer[0] == '%'){ + i--; + continue; + } + + for(j = 0; buffer[j] && j < *h; j++){ + if(buffer[j] >= '0' && buffer[j] <= '9'){ + switch(buffer[j]){ + case '0': (*map)[i][j].f = VOID; break; + case '1': (*map)[i][j].f = SOLID_WALL; break; + case '2': (*map)[i][j].f = SECRET_WALL; break; + case '3': (*map)[i][j].f = CLEAR_WALL; break; + case '4': (*map)[i][j].f = NEON_WALL; break; + case '5': (*map)[i][j].f = WINDOW_WALL; break; + case '6': (*map)[i][j].f = EMPTY_FLOOR; break; + case '7': (*map)[i][j].f = RUG; break; + case '8': (*map)[i][j].f = WATER; break; + case '9': (*map)[i][j].f = BAR; break; + default: + fprintf(stderr, "\t%s.readMapData() : Invalid character %c in map file %s\n", __FILE__, buffer[j], file); + (*map)[i][j].f = VOID; + break; + } + }else{ + fprintf(stderr, "\t%s.readMapData() : Invalid character %c in map file %s\n", __FILE__, buffer[j], file); + (*map)[i][j].f = VOID; + } + } + } + /* Skip the rest of the file. */ + break; + } + } + + fclose(f); + free(buffer); + + return NO_ERROR; +}