diff --git a/include/constants.h b/include/constants.h index 6d5d7a2..00ec5bb 100644 --- a/include/constants.h +++ b/include/constants.h @@ -15,21 +15,21 @@ #endif 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 + 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 index 9fe435e..34be94d 100644 --- a/include/game_state.h +++ b/include/game_state.h @@ -11,10 +11,10 @@ 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); + gsname_t name; + void (*input)(); + gsname_t (*update)(); + void (*render)(int, int); } gs_t; extern void initStateArray(gs_t **); diff --git a/src/game_state.c b/src/game_state.c index b838173..43f9620 100644 --- a/src/game_state.c +++ b/src/game_state.c @@ -7,9 +7,9 @@ #include "in_game.h" void initStateArray(gs_t ** s){ - int i; + int i; - for(i = 0; i < NUM_STATES; i++){ - initInGameState(&((*s)[i])); - } + for(i = 0; i < NUM_STATES; i++){ + initInGameState(&((*s)[i])); + } } diff --git a/src/in_game.c b/src/in_game.c index f303431..9375aeb 100644 --- a/src/in_game.c +++ b/src/in_game.c @@ -11,132 +11,250 @@ #include "constants.h" #include "in_game.h" -static const int I_SIZE = 257; +typedef struct PLAYER { + unsigned short x; + unsigned short y; +} player_t; + +static const int I_SIZE = 513; static int ** imap; static bool ** wmap; static bool w_mov = FALSE; +static bool uK, dK, lK, rK; static clock_t then; +static player_t player; void input(); gsname_t update(); void render(int, int); +void drawGui(int, int); +void setPlayerStart(); void initInGameState( gs_t * gs) { - int n, i, j; - float ** map; + int n, i, j; + float ** map; - gs->name = IN_GAME; - gs->input = &input; - gs->update = &update; - gs->render = &render; + gs->name = IN_GAME; + gs->input = &input; + gs->update = &update; + gs->render = &render; - n = I_SIZE; + n = I_SIZE; - srand(time(NULL)); + srand(time(NULL)); - map = ( float ** ) malloc ( sizeof ( float * ) * n); - for ( i = 0; i < n; ++i ) { - map[ i ] = ( float * ) calloc ( n, sizeof ( float ) ); - } + 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 ) ); - } + imap = ( int ** ) malloc ( sizeof ( int * ) * n); + for ( i = 0; i < n; ++i ) { + imap[ i ] = ( int * ) calloc ( n, sizeof ( int ) ); + } - wmap = ( bool ** ) malloc ( sizeof ( bool * ) * n); - for ( i = 0; i < n; ++i ) { - wmap[ i ] = ( bool * ) calloc ( n, sizeof ( bool ) ); - for(j = 0; j < n; ++j){ - wmap[i][j] = rand() % 2; - } - } + wmap = ( bool ** ) malloc ( sizeof ( bool * ) * n); + for ( i = 0; i < n; ++i ) { + wmap[ i ] = ( bool * ) calloc ( n, sizeof ( bool ) ); + for(j = 0; j < n; ++j){ + wmap[i][j] = rand() % 2; + } + } - ds ( &map, n ); - island ( &imap, n ); - normInt ( &imap, n ); - norm ( &map, n ); - mult ( &map, &imap, n ); - smooth( &imap, n ); - normInt ( &imap, n ); + ds ( &map, n ); + island ( &imap, n ); + normInt ( &imap, n ); + norm ( &map, n ); + mult ( &map, &imap, n ); + smooth( &imap, n ); + normInt ( &imap, n ); - for ( i = 0; i < n; ++i ) { - free(map[ i ]); - } - free(map); + for ( i = 0; i < n; ++i ) { + free(map[ i ]); + } + free(map); + + setPlayerStart(); + uK = dK = lK = rK = FALSE; } void input(){ - int key = 0; + int key = 0; - key = getch(); + key = getch(); - if(key != ERR){ - fprintf(stderr, "\t%s: Caught keycode %d\n", __FILE__, key); - } + if(key != ERR){ + fprintf(stderr, "\t%s: Caught keycode %d\n", __FILE__, key); + if(key == KEY_UP) uK = TRUE; + if(key == KEY_DOWN) dK = TRUE; + if(key == KEY_LEFT) lK = TRUE; + if(key == KEY_RIGHT) rK = TRUE; + } } gsname_t update(){ - return IN_GAME; + if(uK){ + if(terrainType( imap[player.x][player.y - 1] ) != DEEP_WATER && terrainType( imap[player.x][player.y - 1] ) != MOUNTAIN) player.y -= 1; + uK = FALSE; + } + + if(dK){ + if(terrainType( imap[player.x][player.y + 1]) != DEEP_WATER && terrainType( imap[player.x][player.y + 1]) != MOUNTAIN ) player.y += 1; + dK = FALSE; + } + + if(lK){ + if(terrainType( imap[player.x - 1][player.y]) != DEEP_WATER && terrainType( imap[player.x - 1][player.y]) != MOUNTAIN) player.x -= 1; + lK = FALSE; + } + + if(rK){ + if(terrainType( imap[player.x + 1][player.y]) != DEEP_WATER && terrainType( imap[player.x + 1][player.y]) != MOUNTAIN) player.x += 1; + rK = FALSE; + } + + return IN_GAME; } void render(int w, int h){ - clock_t now, delta; - int i, j; + clock_t now, delta; + int i, j, pi, pj, ioff, joff, di, dj; - now = clock(); - delta = now - then; - if((float)delta / (float)CLOCKS_PER_SEC >= 0.25f){ - then = now; - w_mov = TRUE; - } + now = clock(); + delta = now - then; + if((float)delta / (float)CLOCKS_PER_SEC >= 0.25f){ + then = now; + w_mov = TRUE; + } - for(i = 0; i < w; i++){ - for(j = 0; j < h; j++){ - move(j, i); + pi = (((w - 1) - 27) / 2) + 27; + pj = (h - 2) / 2 + 1; - switch(terrainType( imap[(i + (I_SIZE/4)) % I_SIZE][(j + (I_SIZE/4)) % I_SIZE] )){ - case DEEP_WATER: - attron(COLOR_PAIR(DW_COLOR)); - if(w_mov) - wmap[(i + (I_SIZE/4)) % I_SIZE][(j + (I_SIZE/4)) % I_SIZE] = !wmap[(i + (I_SIZE/4)) % I_SIZE][(j + (I_SIZE/4)) % I_SIZE]; - if(wmap[(i + (I_SIZE/4)) % I_SIZE][(j + (I_SIZE/4)) % I_SIZE]) - printw("\u2248"); - else - printw("~"); - break; - case SHALLOW_WATER: - attron(COLOR_PAIR(SW_COLOR)); - if(w_mov) - wmap[(i + (I_SIZE/4)) % I_SIZE][(j + (I_SIZE/4)) % I_SIZE] = !wmap[(i + (I_SIZE/4)) % I_SIZE][(j + (I_SIZE/4)) % I_SIZE]; - if(wmap[(i + (I_SIZE/4)) % I_SIZE][(j + (I_SIZE/4)) % I_SIZE]) - printw("\u2248"); - else - printw("~"); - break; - case SAND: - attron(COLOR_PAIR(SN_COLOR)); - printw("."); - break; - case GRASS: - attron(COLOR_PAIR(GR_COLOR)); - printw("n"); - 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; - } - //printw("\u2588"); + ioff = (w - 28) / 2; + joff = (h - 2) / 2; + + for(i = 27; i < w - 1; i++){ + for(j = 1; j < h - 1; j++){ + move(j, i); + + di = i - 27 + player.x - ioff; + dj = j - 1 + player.y - joff; + + if( di < 0 || di >= I_SIZE){ + printw(" "); + }else{ + switch(terrainType( imap[di][dj] )){ + case DEEP_WATER: + attron(COLOR_PAIR(DW_COLOR)); + if(w_mov) + wmap[di][dj] = !wmap[di][dj]; + if(wmap[di][dj]) + printw("\u2248"); + else + printw("~"); + break; + case SHALLOW_WATER: + attron(COLOR_PAIR(SW_COLOR)); + if(w_mov) + wmap[di][dj] = !wmap[di][dj]; + if(wmap[di][dj]) + printw("\u2248"); + else + printw("~"); + break; + case SAND: + attron(COLOR_PAIR(SN_COLOR)); + printw("."); + break; + case GRASS: + attron(COLOR_PAIR(GR_COLOR)); + printw("n"); + 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; + } + } + } + } + w_mov = FALSE; + + move(pj, pi); + attron(COLOR_PAIR(BSC_COLOR)); + printw(/*"\u263A"*/ "@"); + + drawGui(w, h); +} + +void drawGui(int w, int h){ + int i, j; + + attron(COLOR_PAIR(BSC_COLOR)); + + /* Clear the gui space. */ + for(i = 1; i < 26; i++){ + for(j = 1; j < h - 1; j++){ + move(j, i); + printw(" "); + } + } + + /* Upper horizontal bar. */ + move(0, 0); + printw("\u2554"); + for(i = 0; i < w - 2; i++){ + if(i != 25){ + printw("\u2550"); + }else{ + printw("\u2566"); + } + } + printw("\u2557"); + + /* Lower horizontal bar. */ + move(h - 1, 0); + printw("\u255A"); + for(i = 0; i < w - 2; i++){ + if(i != 25){ + printw("\u2550"); + }else{ + printw("\u2569"); + } + } + printw("\u255D"); + + /* Vertical bars. */ + for(i = 1; i < h - 1; i++){ + move(i, 0); + printw("\u2551"); + move(i, 26); + printw("\u2551"); + move(i, w-1); + printw("\u2551"); + } +} + +void setPlayerStart(){ + int x, y; + bool posFound = false; + + while(!posFound){ + x = (I_SIZE / 4) + (rand() % (I_SIZE / 2)); + y = (I_SIZE / 4) + (rand() % (I_SIZE / 2)); + + if(terrainType(imap[x][y]) == GRASS){ + player.x = x; + player.y = y; + posFound = true; } } - w_mov = FALSE; } diff --git a/src/main.c b/src/main.c index 471ca50..648d0b1 100644 --- a/src/main.c +++ b/src/main.c @@ -29,21 +29,21 @@ static bool resize = FALSE; int main() { bool finished = FALSE; #if defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__) - char * home_dir = getenv("APPDATA"); + char * home_dir = getenv("APPDATA"); #elif defined(__linux__) || defined(__GNUC__) - char * home_dir = getenv("HOME"); + char * home_dir = getenv("HOME"); #else #error "Unrecognized system." #endif - FILE * f; /* To avoid a warning. */ - clock_t then, now, delta; - unsigned int fps = 0, pfps = 0; - char * data_dir; - char * log_file; - time_t raw_date; - struct tm * current_date; - gs_t * states; - int c_state; + FILE * f; /* To avoid a warning. */ + clock_t then, now, delta; + unsigned int fps = 0, pfps = 0; + 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); @@ -94,52 +94,52 @@ int main() { } set_colors(); - /* Create the state data structures. */ - c_state = 2; - states = (gs_t *)malloc(sizeof(gs_t) * NUM_STATES); - initStateArray(&states); + /* Create the state data structures. */ + c_state = 2; + states = (gs_t *)malloc(sizeof(gs_t) * NUM_STATES); + initStateArray(&states); - /* Start the game loop. */ - then = clock(); + /* Start the game loop. */ + then = clock(); do{ - /* Handle terminal resize. */ - if(resize){ - endwin(); - refresh(); + /* Handle terminal resize. */ + if(resize){ + endwin(); + refresh(); - getmaxyx(stdscr, h, w); + getmaxyx(stdscr, h, w); - fprintf(stderr, "\tSIGWINCH caught. (W: %d, H: %d)\n", w, h); + fprintf(stderr, "\tSIGWINCH caught. (W: %d, H: %d)\n", w, h); - resize = FALSE; - signal(SIGWINCH, on_resize); - } + resize = FALSE; + signal(SIGWINCH, on_resize); + } - states[c_state].input(); - c_state = states[c_state].update(); + states[c_state].input(); + c_state = states[c_state].update(); - if(c_state == -1) finished = TRUE; + if(c_state == -1) finished = TRUE; - states[c_state].render(w, h); + states[c_state].render(w, h); - fps++; + fps++; - now = clock(); - delta = now - then; - if((int)delta / (int)CLOCKS_PER_SEC == 1){ - then = now; - pfps = fps; - fps = 0; - } + now = clock(); + delta = now - then; + if((int)delta / (int)CLOCKS_PER_SEC == 1){ + then = now; + pfps = fps; + fps = 0; + } - move(0, 0); - attron(COLOR_PAIR(BAR_COLOR)); - printw("FPS: %u", pfps); + move(1, 1); + attron(COLOR_PAIR(BSC_COLOR)); + printw("FPS: %u", pfps); - refresh(); - }while(!finished); + refresh(); + }while(!finished); - fclose(f); + fclose(f); return EXIT_SUCCESS; } @@ -151,7 +151,7 @@ void leave(void){ /* Finish ncurses. */ endwin(); - /* Mark the end of this run's log. */ + /* Mark the end of this run's log. */ for(i = 0; i < 80; i++) fprintf(stderr, "-"); fprintf(stderr, "\n"); @@ -162,30 +162,30 @@ void manage_signal(int signal){ switch(signal){ case SIGINT: fprintf(stderr, "\tSIGINT caught.\n"); - exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); break; case SIGSEGV: fprintf(stderr, "\tSegmentation fault.\n"); - exit(EXIT_FAILURE); - break; + exit(EXIT_FAILURE); + break; case SIGTERM: - fprintf(stderr, "\tSIGTERM caught.\n"); + fprintf(stderr, "\tSIGTERM caught.\n"); exit(EXIT_FAILURE); break; } } void on_resize(int signal){ - resize = TRUE; + resize = TRUE; } int start_ncurses(void){ WINDOW *win_ptr; int ret_code; - setlocale(LC_ALL, ""); + setlocale(LC_ALL, ""); /* Prepare the terminal. */ win_ptr = initscr(); @@ -212,9 +212,9 @@ int start_ncurses(void){ if(ret_code == ERR) return -1; - /* Set delay. */ - ret_code = nodelay(stdscr, TRUE); - if(ret_code == ERR) + /* Set delay. */ + ret_code = nodelay(stdscr, TRUE); + if(ret_code == ERR) return -1; /* Initialize the screen size variables. */ @@ -228,29 +228,29 @@ void set_colors(void){ ret_code = start_color(); if(ret_code == OK){ if(has_colors() == TRUE){ - init_color(COLOR_MAGENTA, 0, 0, 500); + 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(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(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_BLUE, COLOR_BLACK); - init_pair(SW_COLOR, COLOR_CYAN, 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_WHITE, COLOR_BLACK); - init_pair(MN_COLOR, COLOR_WHITE, COLOR_BLACK); + init_pair(DW_COLOR, COLOR_BLUE, COLOR_BLACK); + init_pair(SW_COLOR, COLOR_CYAN, 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_WHITE, COLOR_BLACK); + init_pair(MN_COLOR, COLOR_WHITE, COLOR_BLACK); } }else{ - fprintf(stderr, "\t%s: Colors not supported.\n", __FILE__); - exit(EXIT_FAILURE); - } + fprintf(stderr, "\t%s: Colors not supported.\n", __FILE__); + exit(EXIT_FAILURE); + } } void clear_screen(void){