zz
This commit is contained in:
		
							parent
							
								
									74d9392626
								
							
						
					
					
						commit
						f96905a79e
					
				
							
								
								
									
										4
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
									
									
									
									
								
							@ -9,6 +9,6 @@ clean:
 | 
			
		||||
	rm *.o
 | 
			
		||||
	rm game
 | 
			
		||||
 | 
			
		||||
game: main.o game.o world.o snake.o
 | 
			
		||||
	gcc -rdynamic -g main.o game.o world.o snake.o -lcurses -lm -o game
 | 
			
		||||
game: main.o world.o snake.o
 | 
			
		||||
	gcc -rdynamic -g main.o world.o snake.o -lcurses -lm -o game
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								game.c
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								game.c
									
									
									
									
									
								
							@ -4,16 +4,17 @@
 | 
			
		||||
#include "world.h"
 | 
			
		||||
#include "game.h"
 | 
			
		||||
#include "snake.h"
 | 
			
		||||
 | 
			
		||||
// This file contains functions for drawing the the game and changing the state
 | 
			
		||||
 | 
			
		||||
// Start is called one in the beginning
 | 
			
		||||
void* init_game(struct world* world){
 | 
			
		||||
 | 
			
		||||
void* init_game(){
 | 
			
		||||
    // Allocate memory for the state
 | 
			
		||||
    struct state* st = calloc(1,(sizeof(struct state)));
 | 
			
		||||
    st->snake = NULL;
 | 
			
		||||
    st->sx = 1;
 | 
			
		||||
    st->sy = 0;
 | 
			
		||||
    return st;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_snake(struct event* world, struct state* st){
 | 
			
		||||
    int cy = world->height/2;
 | 
			
		||||
    int cx = world->width/2 - 5;
 | 
			
		||||
    for (int i = 0; i < 5; i++){
 | 
			
		||||
@ -26,15 +27,17 @@ void* init_game(struct world* world){
 | 
			
		||||
        st->foodx[i] = rand() % w;
 | 
			
		||||
        st->foody[i] = rand() % h;
 | 
			
		||||
    }
 | 
			
		||||
    return st;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Step is called in a loop once in interval.
 | 
			
		||||
// It should modify the state and draw it.
 | 
			
		||||
int world_event(struct world* w,void* game){
 | 
			
		||||
int world_event(struct event* w,void* game){
 | 
			
		||||
    // Get state pointer
 | 
			
		||||
    struct state* st = game;
 | 
			
		||||
    if (w->type == EVENT_START){
 | 
			
		||||
        init_snake(w,st);
 | 
			
		||||
    }
 | 
			
		||||
    else if (w->type == EVENT_KEY){
 | 
			
		||||
        int key = w->key;
 | 
			
		||||
 | 
			
		||||
        if (key == KEY_RIGHT){
 | 
			
		||||
@ -53,28 +56,31 @@ int world_event(struct world* w,void* game){
 | 
			
		||||
            st->sx = 0;
 | 
			
		||||
            st->sy = -1;
 | 
			
		||||
        }
 | 
			
		||||
    else if (key == KEY_ENTER){
 | 
			
		||||
    }
 | 
			
		||||
    else if (w->type == EVENT_ESC){
 | 
			
		||||
            // Non zero means finish the loop and stop the game.
 | 
			
		||||
            return 1;
 | 
			
		||||
    }
 | 
			
		||||
    else if (w->type == EVENT_TIMEOUT){
 | 
			
		||||
        st->width = w->width;
 | 
			
		||||
        st->height = w->height;
 | 
			
		||||
        int r = step_state(st);
 | 
			
		||||
        // Draw snake
 | 
			
		||||
        struct snake* sn = st->snake;
 | 
			
		||||
        while (sn != NULL){
 | 
			
		||||
        set_cell(w,'x',sn->x,sn->y);
 | 
			
		||||
            set_cell('x',sn->x,sn->y);
 | 
			
		||||
            sn = sn->next;
 | 
			
		||||
        }
 | 
			
		||||
        for (int i = 0 ; i < FOOD_COUNT; i++){
 | 
			
		||||
            if (st->foodx[i] >= 0 && st->foody[i] >= 0){
 | 
			
		||||
            set_cell(w,'*',st->foodx[i],st->foody[i]);
 | 
			
		||||
                set_cell('*',st->foodx[i],st->foody[i]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (r){
 | 
			
		||||
            char message[] = "Koniec";
 | 
			
		||||
            for (int i = 0; i < 6; i++){
 | 
			
		||||
            set_cell(w,message[i],10+i,10);
 | 
			
		||||
                set_cell(message[i],10+i,10);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								game.h
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								game.h
									
									
									
									
									
								
							@ -2,25 +2,10 @@
 | 
			
		||||
#define _GAME_H_INCLUDE_
 | 
			
		||||
#include "world.h"
 | 
			
		||||
 | 
			
		||||
// Set of variables that expresses state of the game.
 | 
			
		||||
// 
 | 
			
		||||
struct game {
 | 
			
		||||
    // X position of the cat
 | 
			
		||||
    int catx;
 | 
			
		||||
    // Y opsition of the cat
 | 
			
		||||
    int caty;
 | 
			
		||||
    // X position of the mouse
 | 
			
		||||
    int mousex;
 | 
			
		||||
    // Y position of the mouse
 | 
			
		||||
    int mousey;
 | 
			
		||||
    // Funky message
 | 
			
		||||
    char message[100];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Returns pointer to  newly allocated world
 | 
			
		||||
void* init_game(struct world* g);
 | 
			
		||||
// Returns pointer to  newly allocated state
 | 
			
		||||
void* init_game();
 | 
			
		||||
 | 
			
		||||
// Changes world according to the game state (pressed key, screen size or other event)
 | 
			
		||||
int world_event(struct world* world,void* game);
 | 
			
		||||
int world_event(struct event* event,void* state);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										88
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								main.c
									
									
									
									
									
								
							@ -1,9 +1,93 @@
 | 
			
		||||
#include "game.h"
 | 
			
		||||
#include "world.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <curses.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "snake.h"
 | 
			
		||||
// This file contains functions for drawing the the game and changing the state
 | 
			
		||||
 | 
			
		||||
// Start is called one in the beginning
 | 
			
		||||
void* init_game(){
 | 
			
		||||
    // Allocate memory for the state
 | 
			
		||||
    struct state* st = calloc(1,(sizeof(struct state)));
 | 
			
		||||
    return st;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_snake(struct event* world, struct state* st){
 | 
			
		||||
    int cy = world->height/2;
 | 
			
		||||
    int cx = world->width/2 - 5;
 | 
			
		||||
    for (int i = 0; i < 5; i++){
 | 
			
		||||
        st->snake = add_snake(st->snake,cx + i ,cy);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int h = world->height;
 | 
			
		||||
    int w = world->width;
 | 
			
		||||
    for (int i = 0; i < 5; i++){
 | 
			
		||||
        st->foodx[i] = rand() % w;
 | 
			
		||||
        st->foody[i] = rand() % h;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Step is called in a loop once in interval.
 | 
			
		||||
// It should modify the state and draw it.
 | 
			
		||||
int world_event(struct event* w,void* game){
 | 
			
		||||
    // Get state pointer
 | 
			
		||||
    struct state* st = game;
 | 
			
		||||
    if (w->type == EVENT_START){
 | 
			
		||||
        init_snake(w,st);
 | 
			
		||||
    }
 | 
			
		||||
    else if (w->type == EVENT_KEY){
 | 
			
		||||
        int key = w->key;
 | 
			
		||||
 | 
			
		||||
        if (key == KEY_RIGHT){
 | 
			
		||||
           st->sx = 1;
 | 
			
		||||
           st->sy = 0;
 | 
			
		||||
        }
 | 
			
		||||
        else if (key == KEY_LEFT){
 | 
			
		||||
            st->sx = -1;
 | 
			
		||||
            st->sy = 0;
 | 
			
		||||
        }
 | 
			
		||||
        else if (key == KEY_DOWN){
 | 
			
		||||
            st->sx = 0;
 | 
			
		||||
            st->sy = 1;
 | 
			
		||||
        }
 | 
			
		||||
        else if (key == KEY_UP){
 | 
			
		||||
            st->sx = 0;
 | 
			
		||||
            st->sy = -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else if (w->type == EVENT_ESC){
 | 
			
		||||
            // Non zero means finish the loop and stop the game.
 | 
			
		||||
            return 1;
 | 
			
		||||
    }
 | 
			
		||||
    else if (w->type == EVENT_TIMEOUT){
 | 
			
		||||
        st->width = w->width;
 | 
			
		||||
        st->height = w->height;
 | 
			
		||||
        int r = step_state(st);
 | 
			
		||||
        // Draw snake
 | 
			
		||||
        struct snake* sn = st->snake;
 | 
			
		||||
        while (sn != NULL){
 | 
			
		||||
            set_cell('x',sn->x,sn->y);
 | 
			
		||||
            sn = sn->next;
 | 
			
		||||
        }
 | 
			
		||||
        for (int i = 0 ; i < FOOD_COUNT; i++){
 | 
			
		||||
            if (st->foodx[i] >= 0 && st->foody[i] >= 0){
 | 
			
		||||
                set_cell('*',st->foodx[i],st->foody[i]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (r){
 | 
			
		||||
            char message[] = "Koniec";
 | 
			
		||||
            for (int i = 0; i < 6; i++){
 | 
			
		||||
                set_cell(message[i],10+i,10);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main(int argc, char** argv){
 | 
			
		||||
    start_world(world_event,init_game,free);
 | 
			
		||||
    start_world(init_game,world_event,free);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										218
									
								
								world.c
									
									
									
									
									
								
							
							
						
						
									
										218
									
								
								world.c
									
									
									
									
									
								
							@ -5,67 +5,80 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <execinfo.h>
 | 
			
		||||
 | 
			
		||||
void print_backtrace() {
 | 
			
		||||
    //https://linux.die.net/man/3/backtrace_symbols
 | 
			
		||||
    int j, nptrs;
 | 
			
		||||
    void *buffer[100];
 | 
			
		||||
    char **strings;
 | 
			
		||||
    nptrs = backtrace(buffer, 100);
 | 
			
		||||
    printf("backtrace() returned %d addresses\n", nptrs);
 | 
			
		||||
 | 
			
		||||
   /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
 | 
			
		||||
       would produce similar output to the following: */
 | 
			
		||||
 | 
			
		||||
    strings = backtrace_symbols(buffer, nptrs);
 | 
			
		||||
    if (strings == NULL) {
 | 
			
		||||
        perror("backtrace_symbols");
 | 
			
		||||
        exit(EXIT_FAILURE);
 | 
			
		||||
    }
 | 
			
		||||
   for (j = 0; j < nptrs; j++)
 | 
			
		||||
        printf("%s\n", strings[j]);
 | 
			
		||||
   free(strings);
 | 
			
		||||
}
 | 
			
		||||
int TIMEOUT;
 | 
			
		||||
 | 
			
		||||
void abort_game(const char* message){
 | 
			
		||||
    endwin();
 | 
			
		||||
    print_backtrace();
 | 
			
		||||
    puts(message);
 | 
			
		||||
    exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void check_bounds(const char* source,int x, int y){
 | 
			
		||||
    char msg[200];
 | 
			
		||||
    if (x < 0 || x >= COLS){
 | 
			
		||||
        sprintf(msg,"%s:: width %d is out of bounds (0,%d)",source,x,COLS);
 | 
			
		||||
        abort_game(msg);
 | 
			
		||||
    }
 | 
			
		||||
    if (y < 0 || y >= LINES){
 | 
			
		||||
        sprintf(msg,"%s:: height %d is out of bounds (0,%d)",source,y,LINES);
 | 
			
		||||
        abort_game(msg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void clear_screen(){
 | 
			
		||||
    // Clear screen
 | 
			
		||||
    mvaddch(0,0,' ');
 | 
			
		||||
    int screenchars = LINES*COLS;
 | 
			
		||||
    for (int j = 1; j < screenchars;j++ ){
 | 
			
		||||
        addch(' ');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void game_speed(int value){
 | 
			
		||||
    if (value < 0){
 | 
			
		||||
        abort_game("world_seed:: cannot be negative\n");
 | 
			
		||||
    }
 | 
			
		||||
    TIMEOUT =value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_message(const char* message,int x,int y) {
 | 
			
		||||
    int l = strlen(message);
 | 
			
		||||
    for (int i = 0; i < l; i++){
 | 
			
		||||
        check_bounds("set_message",x+i,y);
 | 
			
		||||
        set_cell(message[i],x+i,y);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assert_message(int event,const char* message){
 | 
			
		||||
    if (event == 0){
 | 
			
		||||
        abort_game(message);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void stamp_cell(struct world* w,int character,enum color_stamp pen, int x,int y) {
 | 
			
		||||
    assert_message(w != NULL,"stamp_cell:: world is NULL"); 
 | 
			
		||||
    if (x < 0 || x >= w->width){
 | 
			
		||||
        char msg[100];
 | 
			
		||||
        sprintf(msg,"stamp_cell:: width %d is out of bounds (0,%d)",x,w->width);
 | 
			
		||||
        abort_game(msg);
 | 
			
		||||
 | 
			
		||||
void set_cell(int character,int x,int y) {
 | 
			
		||||
    check_bounds("set_cell",x,y);
 | 
			
		||||
    set_color_cell(character,x,y,COLOR_WHITE,COLOR_BLACK);
 | 
			
		||||
}
 | 
			
		||||
    if (y < 0 || y >= w->height){
 | 
			
		||||
        char msg[100];
 | 
			
		||||
        sprintf(msg,"stamp_cell:: height %d is out of bounds (0,%d)",y,w->height);
 | 
			
		||||
        abort_game(msg);
 | 
			
		||||
    }
 | 
			
		||||
    attron(pen);
 | 
			
		||||
 | 
			
		||||
void set_color_cell(int character,int x,int y,short front_color,short back_color){
 | 
			
		||||
    check_bounds("set_color_cell",x,y);
 | 
			
		||||
    if (has_colors()){
 | 
			
		||||
        int pair = COLOR_COUNT * front_color + back_color; 
 | 
			
		||||
        attron(COLOR_PAIR(pair));
 | 
			
		||||
        mvaddch(y,x,character);
 | 
			
		||||
    attroff(pen);
 | 
			
		||||
        attroff(COLOR_PAIR(pair));
 | 
			
		||||
    }
 | 
			
		||||
    else{
 | 
			
		||||
        mvaddch(y,x,character);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_cell(struct world* w,int character,int x,int y) {
 | 
			
		||||
    stamp_cell(w,character,0,x,y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int start_world(int (*world_event)(struct world* world,void* game),void* (*init_game)(struct world*),void (*destroy_game)(void*)){
 | 
			
		||||
int start_world(void* (*init_game)(),int (*world_event)(struct event* event,void* game),void (*destroy_game)(void*)){
 | 
			
		||||
    srand(time(NULL));
 | 
			
		||||
    int r = 1;
 | 
			
		||||
    // Speed global variable
 | 
			
		||||
    TIMEOUT = 100;
 | 
			
		||||
    if (initscr() == NULL){
 | 
			
		||||
        // TODO Which Error?
 | 
			
		||||
        puts("Curses Error.");
 | 
			
		||||
@ -76,60 +89,107 @@ int start_world(int (*world_event)(struct world* world,void* game),void* (*init_
 | 
			
		||||
    nodelay(stdscr,TRUE); // Nečakaj na stlačenie
 | 
			
		||||
    keypad(stdscr,TRUE); // Aktivuje šípky
 | 
			
		||||
    curs_set(FALSE); // Neviditeľný kurzor
 | 
			
		||||
    /* Get all the mouse events */
 | 
			
		||||
    mousemask(ALL_MOUSE_EVENTS, NULL);
 | 
			
		||||
    MEVENT mouse_event;
 | 
			
		||||
    if (has_colors()){ // Zistenie či terminál podporuje farby
 | 
			
		||||
        start_color();
 | 
			
		||||
        // Pera na ciernom podklade
 | 
			
		||||
        init_pair(BLACK_FRONT,  COLOR_BLACK, COLOR_BLACK);
 | 
			
		||||
        init_pair(WHITE_FRONT,  COLOR_WHITE, COLOR_BLACK);
 | 
			
		||||
        init_pair(RED_FRONT,    COLOR_RED, COLOR_BLACK);
 | 
			
		||||
        init_pair(GREEN_FRONT,  COLOR_GREEN, COLOR_BLACK);
 | 
			
		||||
        init_pair(BLUE_FRONT,   COLOR_BLUE, COLOR_BLACK);
 | 
			
		||||
        init_pair(CYAN_FRONT,   COLOR_CYAN, COLOR_BLACK);
 | 
			
		||||
        init_pair(MAGENTA_FRONT,COLOR_MAGENTA, COLOR_BLACK);
 | 
			
		||||
        init_pair(YELLOW_FRONT, COLOR_YELLOW, COLOR_BLACK);
 | 
			
		||||
        init_pair(BLACK_BACK,   COLOR_BLACK, COLOR_BLACK);
 | 
			
		||||
        init_pair(WHITE_BACK,   COLOR_BLACK, COLOR_WHITE);
 | 
			
		||||
        init_pair(RED_BACK,     COLOR_BLACK, COLOR_RED);
 | 
			
		||||
        init_pair(GREEN_BACK,   COLOR_BLACK, COLOR_GREEN);
 | 
			
		||||
        init_pair(BLUE_BACK,    COLOR_BLACK, COLOR_BLUE);
 | 
			
		||||
        init_pair(CYAN_BACK,    COLOR_BLACK, COLOR_CYAN);
 | 
			
		||||
        init_pair(MAGENTA_BACK, COLOR_BLACK, COLOR_MAGENTA);
 | 
			
		||||
        init_pair(YELLOW_BACK,  COLOR_BLACK, COLOR_YELLOW);
 | 
			
		||||
        for (int i = 0; i < COLOR_COUNT;i++){
 | 
			
		||||
            for (int j = 0; j < COLOR_COUNT;j++){
 | 
			
		||||
                init_pair(i * COLOR_COUNT + j, i,j);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        puts("No colors!\n");
 | 
			
		||||
    }
 | 
			
		||||
    struct world world;
 | 
			
		||||
    world.height = LINES;
 | 
			
		||||
    world.width = COLS;
 | 
			
		||||
    world.interval = 100;
 | 
			
		||||
    world.key = ERR;
 | 
			
		||||
 | 
			
		||||
    void* game = NULL;
 | 
			
		||||
    if (init_game != NULL){
 | 
			
		||||
         game = init_game(&world);
 | 
			
		||||
         assert_message(game != NULL,"init_game should return non null pointer");
 | 
			
		||||
         game = init_game();
 | 
			
		||||
         assert_message(game != NULL,"init_game:: should return non null pointer");
 | 
			
		||||
    }
 | 
			
		||||
    timeout(world.interval);
 | 
			
		||||
    timeout(TIMEOUT);
 | 
			
		||||
    // Initial step
 | 
			
		||||
    r = world_event(&world,game);
 | 
			
		||||
    struct event event;
 | 
			
		||||
    memset(&event,0,sizeof(struct event));
 | 
			
		||||
    event.height = LINES;
 | 
			
		||||
    event.width = COLS;
 | 
			
		||||
    event.type = EVENT_START;
 | 
			
		||||
    clock_t start_time = clock();
 | 
			
		||||
    clock_t last_timeout = start_time;
 | 
			
		||||
    clock_t next_timeout = last_timeout + TIMEOUT;
 | 
			
		||||
    event.time_ms = start_time;
 | 
			
		||||
    // Start event
 | 
			
		||||
    r = world_event(&event,game);
 | 
			
		||||
    refresh();
 | 
			
		||||
    while (!r) {
 | 
			
		||||
        world.height = LINES;
 | 
			
		||||
        world.width = COLS;
 | 
			
		||||
        world.key = getch();
 | 
			
		||||
        // Clear screen
 | 
			
		||||
        mvaddch(0,0,' ');
 | 
			
		||||
        int screenchars = LINES*COLS;
 | 
			
		||||
        for (int j = 1; j < screenchars;j++ ){
 | 
			
		||||
            addch(' ');
 | 
			
		||||
        memset(&event,0,sizeof(struct event));
 | 
			
		||||
        event.height = LINES;
 | 
			
		||||
        event.width = COLS;
 | 
			
		||||
        event.key = getch();
 | 
			
		||||
        // No key was pressed
 | 
			
		||||
        if (event.key == ERR){
 | 
			
		||||
            event.type = EVENT_TIMEOUT;
 | 
			
		||||
            last_timeout = clock();
 | 
			
		||||
            next_timeout = last_timeout + TIMEOUT;
 | 
			
		||||
        }
 | 
			
		||||
        // Mouse event
 | 
			
		||||
        else if (event.key == KEY_MOUSE ){
 | 
			
		||||
            event.type = EVENT_MOUSE;
 | 
			
		||||
            if(getmouse(&mouse_event) == OK){
 | 
			
		||||
                event.mouse_x = mouse_event.x;
 | 
			
		||||
                event.mouse_y = mouse_event.y;
 | 
			
		||||
                if(mouse_event.bstate & BUTTON1_PRESSED){
 | 
			
		||||
                    event.mouse_left = 1;
 | 
			
		||||
                }
 | 
			
		||||
                if(mouse_event.bstate & BUTTON2_PRESSED){
 | 
			
		||||
                    event.mouse_middle = 1;
 | 
			
		||||
                }
 | 
			
		||||
                if(mouse_event.bstate & BUTTON3_PRESSED){
 | 
			
		||||
                    event.mouse_right = 1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (event.key == KEY_RESIZE) {
 | 
			
		||||
            event.type = EVENT_RESIZE;
 | 
			
		||||
        }
 | 
			
		||||
        else{
 | 
			
		||||
            event.type = EVENT_KEY;
 | 
			
		||||
            if (event.key == 27){
 | 
			
		||||
                int k = getch();
 | 
			
		||||
                if (k == -1){
 | 
			
		||||
                    // Esc Was pressed
 | 
			
		||||
                    event.type = EVENT_ESC;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    // Alt was pressed
 | 
			
		||||
                    event.key = k;
 | 
			
		||||
                    event.alt_key = 1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Draw new world
 | 
			
		||||
        r = world_event(&world,game);
 | 
			
		||||
        event.time_ms = clock();
 | 
			
		||||
        r = world_event(&event,game);
 | 
			
		||||
        refresh();
 | 
			
		||||
        event.time_ms = clock();
 | 
			
		||||
        // set new timeout
 | 
			
		||||
        timeout(world.interval);
 | 
			
		||||
        int nt = next_timeout - event.time_ms;
 | 
			
		||||
        //printf("%d\n",nt);
 | 
			
		||||
        if (nt > 0){
 | 
			
		||||
            timeout(nt);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            timeout(TIMEOUT);
 | 
			
		||||
            next_timeout = event.time_ms + TIMEOUT;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    memset(&event,0,sizeof(struct event));
 | 
			
		||||
    event.height = LINES;
 | 
			
		||||
    event.width = COLS;
 | 
			
		||||
    event.type = EVENT_END;
 | 
			
		||||
    event.time_ms = clock();
 | 
			
		||||
    world_event(&event,game);
 | 
			
		||||
    if (destroy_game != NULL){
 | 
			
		||||
        destroy_game(game);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										77
									
								
								world.h
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								world.h
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
#define _WORLD_H_
 | 
			
		||||
 | 
			
		||||
#include <curses.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * World represented as a rectangular matrix of colorful characters.
 | 
			
		||||
 * 
 | 
			
		||||
@ -9,7 +10,17 @@
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct world {
 | 
			
		||||
enum event_type {
 | 
			
		||||
    EVENT_START,
 | 
			
		||||
    EVENT_TIMEOUT,
 | 
			
		||||
    EVENT_KEY,
 | 
			
		||||
    EVENT_MOUSE,
 | 
			
		||||
    EVENT_RESIZE,
 | 
			
		||||
    EVENT_ESC,
 | 
			
		||||
    EVENT_END,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct event {
 | 
			
		||||
    /**
 | 
			
		||||
     * Last width of the screen.
 | 
			
		||||
     */
 | 
			
		||||
@ -18,10 +29,6 @@ struct world {
 | 
			
		||||
     * Last height of the screen.
 | 
			
		||||
     */
 | 
			
		||||
    int height;
 | 
			
		||||
    /**
 | 
			
		||||
     * Interval in miliseconds to wait for next step. 
 | 
			
		||||
     */
 | 
			
		||||
    int interval;
 | 
			
		||||
    /**
 | 
			
		||||
     * Last pressed key or Curses event.
 | 
			
		||||
     *
 | 
			
		||||
@ -48,53 +55,59 @@ struct world {
 | 
			
		||||
     * KEY_BACKSPACE
 | 
			
		||||
     */
 | 
			
		||||
    int key;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
enum color_stamp {
 | 
			
		||||
    BLACK_FRONT,
 | 
			
		||||
    WHITE_FRONT,
 | 
			
		||||
    RED_FRONT,
 | 
			
		||||
    GREEN_FRONT,
 | 
			
		||||
    BLUE_FRONT,
 | 
			
		||||
    CYAN_FRONT,
 | 
			
		||||
    MAGENTA_FRONT,
 | 
			
		||||
    YELLOW_FRONT,
 | 
			
		||||
    BLACK_BACK,
 | 
			
		||||
    WHITE_BACK,
 | 
			
		||||
    RED_BACK,
 | 
			
		||||
    GREEN_BACK,
 | 
			
		||||
    BLUE_BACK,
 | 
			
		||||
    CYAN_BACK,
 | 
			
		||||
    MAGENTA_BACK,
 | 
			
		||||
    YELLOW_BACK,
 | 
			
		||||
    int alt_key;
 | 
			
		||||
    enum event_type type;
 | 
			
		||||
    int mouse_x;
 | 
			
		||||
    int mouse_y;
 | 
			
		||||
    int mouse_left;
 | 
			
		||||
    int mouse_right;
 | 
			
		||||
    int mouse_middle;
 | 
			
		||||
    long int time_ms;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Sets cell to a state.
 | 
			
		||||
 * @param world
 | 
			
		||||
 * @param event 
 | 
			
		||||
 * @param x coordinate of cell
 | 
			
		||||
 * @param y coordinate of cell
 | 
			
		||||
 * @param new state of the cell
 | 
			
		||||
 */
 | 
			
		||||
void set_cell(struct world* w,int character,int x,int y);
 | 
			
		||||
void set_cell(int character,int x,int y);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * COLOR_BLACK   0
 | 
			
		||||
 * COLOR_RED     1
 | 
			
		||||
 * COLOR_GREEN   2
 | 
			
		||||
 * COLOR_YELLOW  3
 | 
			
		||||
 * COLOR_BLUE    4
 | 
			
		||||
 * COLOR_MAGENTA 5
 | 
			
		||||
 * COLOR_CYAN    6
 | 
			
		||||
 * COLOR_WHITE   7
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define COLOR_COUNT 8
 | 
			
		||||
 | 
			
		||||
void set_color_cell(int character,int x,int y,short front_color,short back_color);
 | 
			
		||||
 | 
			
		||||
void stamp_cell(struct world* w,int character,enum color_stamp stamp,int x,int y);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @param world
 | 
			
		||||
 * @param event
 | 
			
		||||
 * @param number of commandline arguments
 | 
			
		||||
 * @param init_world
 | 
			
		||||
 * @param destroy_world
 | 
			
		||||
 *
 | 
			
		||||
 * void init_world(struct world* w);
 | 
			
		||||
 * void init_world(struct event* w);
 | 
			
		||||
 * Initializes user state.
 | 
			
		||||
 * Free user state.
 | 
			
		||||
 * @param world
 | 
			
		||||
 * @param event
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int start_world(int (*world_event)(struct world* world,void* game),void* (*init_game)(struct world* world),void (*destroy_game)(void* game));
 | 
			
		||||
int start_world(void* (*init_game)(),int (*world_event)(struct event* event,void* game),void (*destroy_game)(void* game));
 | 
			
		||||
 | 
			
		||||
void game_speed(int value);
 | 
			
		||||
 | 
			
		||||
void set_message(const char* message,int x,int y);
 | 
			
		||||
void clear_screen();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user