diff --git a/Makefile b/Makefile index c2c281c..a0ef6b4 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ CC = gcc -SOURCES = src/main.c -OBJECTS = obj/main.o +SOURCES = src/main.c src/game_state.c src/in_game.c +OBJECTS = obj/main.o obj/game_state.o obj/in_game.o TARGET = bin/cyjam -CFLAGS = -Wall -I./include +CFLAGS = -Wall -I./include -std=c99 LDFLAGS = -L./lib -LDLIBS = -lm -lisland -lfov -lncurses +LDLIBS = -lm -lisland -lfov -lncursesw all: CFLAGS += -O3 all: $(TARGET) @@ -15,7 +15,13 @@ debug: $(TARGET) $(TARGET): $(OBJECTS) $(CC) -o $(TARGET) $(OBJECTS) $(CLFAGS) $(LDFLAGS) $(LDLIBS) -obj/main.o: src/main.c +obj/main.o: src/main.c include/constants.h include/game_state.h + $(CC) -c -o $@ $< $(CFLAGS) + +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 $(CC) -c -o $@ $< $(CFLAGS) clean: diff --git a/include/constants.h b/include/constants.h index ae042e0..6d5d7a2 100644 --- a/include/constants.h +++ b/include/constants.h @@ -1,22 +1,35 @@ -#pragma once +/** + * Copyright (c) 2014, Miguel Angel Astor Romero. All rights reserved. + * See the file LICENSE for more details. + */ + #ifndef STATE_CONSTS_H #define STATE_CONSTS_H -static const int BAR_COLOR = 1; -static const int BSC_COLOR = 2; -static const int HLT_COLOR = 3; -static const int OFF_COLOR = 4; -static const int DIM_COLOR = 5; -static const int LIT_COLOR = 6; -static const int GUI_COLOR = 7; -static const int EMP_COLOR = 8; +#if defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__) +#define F_SEP "\\" +#elif defined(__linux__) || defined(__GNUC__) +#define F_SEP "/" +#else +#error "Unrecognized system." +#endif -static const int INTRO_STATE = 0; -static const int MENU_STATE = 1; -static const int LOAD_STATE = 2; -static const int SCORE_STATE = 3; -static const int GAME_STATE = 4; - -static const int QUIT_STATE = -1; +enum COLORS { + BAR_COLOR = 1, + BSC_COLOR, + HLT_COLOR, + OFF_COLOR, + DIM_COLOR, + LIT_COLOR, + GUI_COLOR, + EMP_COLOR, + DW_COLOR, + SW_COLOR, + SN_COLOR, + GR_COLOR, + FR_COLOR, + HL_COLOR, + MN_COLOR +}; #endif diff --git a/include/game_state.h b/include/game_state.h new file mode 100644 index 0000000..9fe435e --- /dev/null +++ b/include/game_state.h @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2014, Miguel Angel Astor Romero. All rights reserved. + * See the file LICENSE for more details. + */ + +#ifndef GAME_STATE_H +#define GAME_STATE_H + +static const int NUM_STATES = 4; + +typedef enum GAME_STATE_NAMES { INTRO = 0, MENU = 1, IN_GAME = 2, GAME_OVER = 3 } gsname_t; + +typedef struct GAME_STATE { + gsname_t name; + void (*input)(); + gsname_t (*update)(); + void (*render)(int, int); +} gs_t; + +extern void initStateArray(gs_t **); + +#endif diff --git a/include/in_game.h b/include/in_game.h new file mode 100644 index 0000000..be4d39a --- /dev/null +++ b/include/in_game.h @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2014, Miguel Angel Astor Romero. All rights reserved. + * See the file LICENSE for more details. + */ + +#ifndef IN_GAME_H +#define IN_GAME_H + +#include "game_state.h" + +extern void initInGameState(gs_t *); + +#endif diff --git a/src/game_state.c b/src/game_state.c new file mode 100644 index 0000000..088d0bd --- /dev/null +++ b/src/game_state.c @@ -0,0 +1,10 @@ +#include "game_state.h" +#include "in_game.h" + +void initStateArray(gs_t ** s){ + int i; + + for(i = 0; i < NUM_STATES; i++){ + initInGameState(&((*s)[i])); + } +} diff --git a/src/in_game.c b/src/in_game.c new file mode 100644 index 0000000..95ec1be --- /dev/null +++ b/src/in_game.c @@ -0,0 +1,94 @@ +#include +#include +#include + +#include "constants.h" +#include "in_game.h" + +static const int I_SIZE = 257; +static int ** imap; + +void input(); +gsname_t update(); +void render(int, int); + +void initInGameState( gs_t * gs) { + int n, i; + float ** map; + + gs->name = IN_GAME; + gs->input = &input; + gs->update = &update; + gs->render = &render; + + n = I_SIZE; + + map = ( float ** ) malloc ( sizeof ( float * ) * n); + for ( i = 0; i < n; ++i ) { + map[ i ] = ( float * ) calloc ( n, sizeof ( float ) ); + } + + imap = ( int ** ) malloc ( sizeof ( int * ) * n); + for ( i = 0; i < n; ++i ) { + imap[ i ] = ( int * ) calloc ( n, sizeof ( int ) ); + } + + ds ( &map, n ); + island ( &imap, n ); + normInt ( &imap, n ); + norm ( &map, n ); + mult ( &map, &imap, n ); + smooth( &imap, n ); + normInt ( &imap, n ); + + free(map); +} + +void input(){ + +} + +gsname_t update(){ + return IN_GAME; +} + +void render(int w, int h){ + int i, j; + + for(i = 0; i < w; i++){ + for(j = 0; j < h; j++){ + move(j, i); + + switch(terrainType( imap[(i + (I_SIZE/4)) % I_SIZE][(j + (I_SIZE/4)) % I_SIZE] )){ + case DEEP_WATER: + attron(COLOR_PAIR(DW_COLOR)); + printw("~"); + break; + case SHALLOW_WATER: + attron(COLOR_PAIR(SW_COLOR)); + printw("~"); + break; + case SAND: + attron(COLOR_PAIR(SN_COLOR)); + printw("."); + break; + case GRASS: + attron(COLOR_PAIR(GR_COLOR)); + printw("\u2591"); + break; + case FOREST: + attron(COLOR_PAIR(FR_COLOR)); + printw("\u2660"); + break; + case HILL: + attron(COLOR_PAIR(HL_COLOR)); + printw("\u2302"); + break; + case MOUNTAIN: + attron(COLOR_PAIR(MN_COLOR)); + printw("\u25B2"); + break; + } + } + } +} diff --git a/src/main.c b/src/main.c index ea0bcf7..0ad93f3 100644 --- a/src/main.c +++ b/src/main.c @@ -10,12 +10,15 @@ #include #include #include -#include +#include #include +#include #include #include #include + #include "constants.h" +#include "game_state.h" void leave(void); void manage_signal(int signal); @@ -28,11 +31,19 @@ static int w = 0, h = 0; int main() { bool finished = false; - char *home_dir = getenv("HOME"); - char *data_dir; - char *log_file; - time_t raw_date; - struct tm *current_date; +#if defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__) + char * home_dir = getenv("APPDATA"); +#elif defined(__linux__) || defined(__GNUC__) + char * home_dir = getenv("HOME"); +#else +#error "Unrecoginized compiler." +#endif + char * data_dir; + char * log_file; + time_t raw_date; + struct tm * current_date; + gs_t * states; + int c_state; atexit(leave); signal(SIGINT, manage_signal); @@ -45,12 +56,12 @@ int main() { /* If we got the user's home directory, build the data directory path. */ data_dir = (char*)malloc(strlen(home_dir) + 7); strcpy(data_dir, home_dir); - strcat(data_dir, "/.tomb"); + strcat(data_dir, F_SEP ".cyjam"); /* Redirect stderr output to a file. */ log_file = (char*)malloc(strlen(data_dir) + 8); strcpy(log_file, data_dir); - strcat(log_file, "/stderr"); + strcat(log_file, F_SEP "stderr"); freopen(log_file, "a", stderr); /* Log the current date and time. */ @@ -61,13 +72,11 @@ int main() { /* Try to create the data directory with permissions 775. */ if(mkdir(data_dir, S_IRWXU | S_IWGRP | S_IRGRP| S_IROTH | S_IXOTH) == 0){ /* The data directory was sucessfully created. */ - //init_scores(data_dir); }else{ if(errno != EEXIST){ /* The directory does not exists and could not be created. */ - perror("\tmain.c"); + perror("\t" __FILE__); fprintf(stderr, "\tdata_dir is: %s\n", data_dir); - //init_scores(NULL); }else{ /* The directory already exits. */ //init_scores(data_dir); @@ -75,22 +84,31 @@ int main() { } }else{ /* If there is no HOME environment variable, quit. */ - fprintf(stderr, "\tmain.c: Couldn't find the user's home directory\n"); + fprintf(stderr, "\t%s: Couldn't find the user's home directory\n", __FILE__); return EXIT_FAILURE; } /* Start ncurses. */ if(start_ncurses() != 0){ - fprintf(stderr, "\tmain.c: Ncurses could not be initialized.\n"); + fprintf(stderr, "\t%s: Ncurses could not be initialized.\n", __FILE__); return EXIT_FAILURE; } set_colors(); - do{ - clear_screen(); + c_state = 2; + + states = (gs_t *)malloc(sizeof(gs_t) * NUM_STATES); + initStateArray(&states); - refresh(); - }while(!finished); + do{ + clear_screen(); + + states[c_state].input(); + c_state = states[c_state].update(); + states[c_state].render(w, h); + + refresh(); + }while(!finished); return EXIT_SUCCESS; } @@ -101,8 +119,8 @@ void leave(void){ /* Finish ncurses. */ endwin(); - /* Close the scores database and todays log. */ - // close_scores(); + + /* Mark the end of this run's log. */ for(i = 0; i < 80; i++) fprintf(stderr, "-"); fprintf(stderr, "\n"); @@ -113,12 +131,19 @@ void manage_signal(int signal){ switch(signal){ case SIGINT: fprintf(stderr, "\tSIGINT caught.\n"); + exit(EXIT_SUCCESS); break; + case SIGSEGV: fprintf(stderr, "\tSegmentation fault.\n"); + exit(EXIT_FAILURE); + break; + case SIGTERM: + fprintf(stderr, "\tSIGTERM caught.\n"); exit(EXIT_FAILURE); break; + } } @@ -127,40 +152,51 @@ void on_resize(int signal){ /* Request the new size of the terminal. */ ioctl(1, TIOCGWINSZ, &ws); - /* Resize ncurse's stdscr. */ + + /* Resize ncurses's stdscr. */ resizeterm(ws.ws_row, ws.ws_col); + /* Get the new size of the window. */ getmaxyx(stdscr, h, w); + fprintf(stderr, "\tSIGWINCH caught. (W: %d, H: %d)\n", w, h); } int start_ncurses(void){ WINDOW *win_ptr; int ret_code; + + setlocale(LC_ALL, ""); + /* Prepare the terminal. */ win_ptr = initscr(); if(win_ptr == NULL) return -1; + /* Enable special characters. */ ret_code = keypad(stdscr, TRUE); if(ret_code == ERR) return -1; + /* Disable line buffering. */ ret_code = cbreak(); if(ret_code == ERR) return -1; + /* Disable echo. */ ret_code = noecho(); if(ret_code == ERR) return -1; + /* Hide the cursor. */ ret_code = curs_set(FALSE); if(ret_code == ERR) return -1; + /* Initialize the screen size variables. */ getmaxyx(stdscr, h, w); - return 0; + return EXIT_SUCCESS; } void set_colors(void){ @@ -168,16 +204,29 @@ void set_colors(void){ ret_code = start_color(); if(ret_code == OK){ if(has_colors() == TRUE){ - init_pair(1, COLOR_WHITE, COLOR_RED); /* The color for the top and bottom bars. */ - init_pair(2, COLOR_WHITE, COLOR_BLACK); /* Basic text color. */ - init_pair(3, COLOR_YELLOW, COLOR_BLACK); /* Highlighted text color. */ - init_pair(4, COLOR_BLUE, COLOR_BLACK); /* Lights off color. */ - init_pair(5, COLOR_RED, COLOR_BLACK); /* Dim light color. */ - init_pair(6, COLOR_YELLOW, COLOR_BLACK); /* Lights on color. */ - init_pair(7, COLOR_YELLOW, COLOR_YELLOW); /* Main GUI bar color. */ - init_pair(8, COLOR_WHITE, COLOR_WHITE); /* Empty GUI bar color. */ + init_color(COLOR_MAGENTA, 0, 0, 500); + + init_pair(BAR_COLOR, COLOR_WHITE, COLOR_RED); /* The color for the top and bottom bars. */ + init_pair(BSC_COLOR, COLOR_WHITE, COLOR_BLACK); /* Basic text color. */ + init_pair(HLT_COLOR, COLOR_YELLOW, COLOR_BLACK); /* Highlighted text color. */ + init_pair(OFF_COLOR, COLOR_BLUE, COLOR_BLACK); /* Lights off color. */ + init_pair(DIM_COLOR, COLOR_RED, COLOR_BLACK); /* Dim light color. */ + init_pair(LIT_COLOR, COLOR_YELLOW, COLOR_BLACK); /* Lights on color. */ + init_pair(GUI_COLOR, COLOR_YELLOW, COLOR_YELLOW); /* Main GUI bar color. */ + init_pair(EMP_COLOR, COLOR_WHITE, COLOR_WHITE); /* Empty GUI bar color. */ + + init_pair(DW_COLOR, COLOR_MAGENTA, COLOR_BLACK); + init_pair(SW_COLOR, COLOR_BLUE, COLOR_BLACK); + init_pair(SN_COLOR, COLOR_YELLOW, COLOR_BLACK); + init_pair(GR_COLOR, COLOR_GREEN, COLOR_BLACK); + init_pair(FR_COLOR, COLOR_GREEN, COLOR_BLACK); + init_pair(HL_COLOR, COLOR_RED, COLOR_BLACK); + init_pair(MN_COLOR, COLOR_WHITE, COLOR_BLACK); } - } + }else{ + fprintf(stderr, "\t%s: Colors not supported.\n", __FILE__); + exit(EXIT_FAILURE); + } } void clear_screen(void){