Skip to content
Snippets Groups Projects
Commit fe0595e0 authored by KosmX's avatar KosmX
Browse files

probably 1.0 (at least on linux)

parent 0585d6de
No related branches found
No related tags found
No related merge requests found
use_utf8 = 1 use_utf8 = 1
tickspeed = 180 tickspeed = 180
repeat_map = 1 repeat_map = 0
food_text_file = foods.txt
feed_amount = 23 feed_amount = 23
...@@ -20,23 +20,43 @@ ...@@ -20,23 +20,43 @@
//Init some platform dependent configurations //Init some platform dependent configurations
/**
* @deprecated
*/
void refreshScreen(void){ void refreshScreen(void){
#ifdef __linux__ #ifdef __linux__
//TODO //TODO
#endif #endif
} }
#ifdef __linux__
struct termios term_config;
#endif
//Init platform specific IO //Init platform specific IO
/**
* Init platform dependent stuff, mostly the custom oi control
*/
void initMultiplatform(void){ void initMultiplatform(void){
#ifdef __linux__ #ifdef __linux__
struct termios info; struct termios info;
tcgetattr(0, &info); //get attr tcgetattr(0, &info); //get attr
term_config = info; //store the original terminal config
info.c_lflag &= ~ICANON; //turn off canonical mode info.c_lflag &= ~ICANON; //turn off canonical mode
info.c_lflag &= ~ECHO; info.c_lflag &= ~ECHO;
tcsetattr(0, TCSANOW, &info); //set attr tcsetattr(0, TCSANOW, &info); //set attr
setbuf(stdin, NULL); //??? setbuf(stdin, NULL); //???
#endif #endif
} }
/**
* Unload and undo platform dependent configs
*/
void endMultiplatformLib(void){
#ifdef __linux__
tcsetattr(0, TCSANOW, &term_config); //undo terminal config changes
#endif
}
#ifdef __linux__ #ifdef __linux__
//linux equivalent conio _kbhit //linux equivalent conio _kbhit
int _kbhit(){ int _kbhit(){
...@@ -46,7 +66,11 @@ int _kbhit(){ ...@@ -46,7 +66,11 @@ int _kbhit(){
} }
#endif #endif
//returns the char or EOF /**
* get the next char form stdin without waiting
*
* @return EOF if no character on stdiní the char instead
*/
int getNextChar(void){ int getNextChar(void){
if(_kbhit()){ if(_kbhit()){
#ifdef __linux__ #ifdef __linux__
...@@ -60,7 +84,9 @@ int getNextChar(void){ ...@@ -60,7 +84,9 @@ int getNextChar(void){
} }
} }
//Returns with the size of the terminal /**
* @return returns with the size of the terminal window
*/
struct Vec2i getWindowSize(void){ struct Vec2i getWindowSize(void){
struct Vec2i size; struct Vec2i size;
#ifdef __linux__ #ifdef __linux__
...@@ -77,7 +103,11 @@ struct Vec2i getWindowSize(void){ ...@@ -77,7 +103,11 @@ struct Vec2i getWindowSize(void){
return size; return size;
} }
//sleem /**
* sleep
*
* @param milisec time to sleep in milis
*/
void unisleep(int milisec){ void unisleep(int milisec){
#ifdef __linux__ #ifdef __linux__
struct timespec ts; struct timespec ts;
...@@ -90,8 +120,15 @@ void unisleep(int milisec){ ...@@ -90,8 +120,15 @@ void unisleep(int milisec){
} }
//NOT TRUE MOD FUNCTION /**
//makes a false modulus what is always positive * work only in k > -m and k < 2m where k is the input m is the modulo
*
* always return r >= 0 && < m
* @param i input
* @param base modulus base
* @param repeat is in repeat mode
* @return modulo i
*/
int mod(int i, int base, int repeat){ int mod(int i, int base, int repeat){
if(i < 0){ if(i < 0){
if(repeat){ if(repeat){
......
...@@ -7,6 +7,8 @@ struct Vec2i getWindowSize(void); ...@@ -7,6 +7,8 @@ struct Vec2i getWindowSize(void);
void initMultiplatform(void); void initMultiplatform(void);
void endMultiplatformLib(void);
void refreshScreen(void); void refreshScreen(void);
int getNextChar(void); int getNextChar(void);
......
#include<stdio.h> #include<stdio.h>
#include<stdlib.h> #include<stdlib.h>
#include<string.h> #include<string.h>
#ifdef DEBUG //include debugmalloc only in debug mode compile :D
#include "debugmalloc.h" #include "debugmalloc.h"
#endif
#include<locale.h> #include<locale.h>
#include<ctype.h> #include<ctype.h>
...@@ -10,6 +13,9 @@ ...@@ -10,6 +13,9 @@
#include "structs.h" #include "structs.h"
#include "multiplatformLib.h" #include "multiplatformLib.h"
#define true 1
#define false 0
//debugmalloc from infoc //debugmalloc from infoc
#define green "\e[0;32m" #define green "\e[0;32m"
...@@ -199,12 +205,14 @@ void printChunk(chunk ch, Pos pos, screenData *scrDat){ ...@@ -199,12 +205,14 @@ void printChunk(chunk ch, Pos pos, screenData *scrDat){
return; //if pos is not on the screen, just do nothing. return; //if pos is not on the screen, just do nothing.
} }
if(ch.isFood){ if(ch.isFood){
chunk ch = scrDat->foodTexture.text[ch.data.FRand%scrDat->foodTexture.len]; ch = scrDat->foodTexture.text[ch.data.FRand%scrDat->foodTexture.len];
printf(green);
} }
printf("\e[%d;%dH", pos.y+1, pos.x *2+1); printf("\e[%d;%dH", pos.y+1, pos.x *2+1);
for(int i = 0; i < 2; i++){ for(int i = 0; i < 2; i++){
printChar(ch.data.chars[i]); printChar(ch.data.chars[i]);
} }
printf("\e[0m");
#ifdef DEBUG #ifdef DEBUG
printf("\e[0;0H\n"); //to update terminal after EVERY print but drasticlally slowing it down printf("\e[0;0H\n"); //to update terminal after EVERY print but drasticlally slowing it down
#endif #endif
...@@ -457,14 +465,16 @@ void updateFood(Matrix *map, int *foodTick, int feedAmount, snakeChain *firstSna ...@@ -457,14 +465,16 @@ void updateFood(Matrix *map, int *foodTick, int feedAmount, snakeChain *firstSna
//pos is available //pos is available
{ {
*foodTick = 0; *foodTick = 0;
chunk c;
//chunk c;
map->matrix[pos.x][pos.y].isFood = 1; map->matrix[pos.x][pos.y].isFood = 1;
map->matrix[pos.x][pos.y].data.FRand = rand(); map->matrix[pos.x][pos.y].data.FRand = rand();
c.data.chars[0].bytes.c[0] = 'X'; //c.data.chars[0].bytes.c[0] = 'X';
c.data.chars[1].bytes.c[0] = 'X'; //c.data.chars[1].bytes.c[0] = 'X';
printf(green);
print(c, pos, scrDat, map->width, map->height); //printf(green); //foods are green
printf("\e[0m"); print(map->matrix[pos.x][pos.y], pos, scrDat, map->width, map->height);
//printf("\e[0m");
break; break;
} }
} }
...@@ -540,6 +550,7 @@ int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head, ...@@ -540,6 +550,7 @@ int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head,
{ {
snake = snake->next; snake = snake->next;
chunk c; chunk c;
c.isFood = 0;
//if snek hit itself //if snek hit itself
if(snake != head && snake->pos.x == head->pos.x && snake->pos.y == head->pos.y){ if(snake != head && snake->pos.x == head->pos.x && snake->pos.y == head->pos.y){
...@@ -579,13 +590,15 @@ int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head, ...@@ -579,13 +590,15 @@ int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head,
snake->dir = dir_tmp; snake->dir = dir_tmp;
//render snek //render snek
dir_tmp = dir_tmp2;
/*
c.data.chars[0].bytes.c[0] = '>'; c.data.chars[0].bytes.c[0] = '>';
c.data.chars[1].bytes.c[0] = '<'; c.data.chars[1].bytes.c[0] = '<';
*/
if(snake->pos.x != -1){ if(snake->pos.x != -1){
//TODO call render printf(blue);
print(c, snake->pos, scrDat, map->width, map->height); //TODO direction snake
} }
//create a new segment //create a new segment
...@@ -599,8 +612,6 @@ int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head, ...@@ -599,8 +612,6 @@ int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head,
snake->next->pos = tmp_pos1; snake->next->pos = tmp_pos1;
snake->next->num = snake->num + 1; snake->next->num = snake->num + 1;
} }
//printf(blue);
//print(c, snake->pos, scrDat, map->width, map->height); //TODO direction snake
#ifdef DEBUG #ifdef DEBUG
printf("\e[0m"); //if debug active, update display after every segments printf("\e[0m"); //if debug active, update display after every segments
...@@ -611,19 +622,21 @@ int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head, ...@@ -611,19 +622,21 @@ int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head,
//clear last segment form the screen //clear last segment form the screen
if(tmp_pos2.x != -1){ if(tmp_pos2.x != -1){
chunk c; chunk c;
c.isFood = 0;
c.data.chars[0].bytes.c[0] = ' '; c.data.chars[0].bytes.c[0] = ' ';
c.data.chars[1].bytes.c[0] = ' '; c.data.chars[1].bytes.c[0] = ' ';
print(c, tmp_pos2, scrDat, map->width, map->height); //set this to air. print(c, tmp_pos2, scrDat, map->width, map->height); //set this to air.
} }
chunk c; chunk c;
c.isFood = 0;
c.data.chars[0].bytes.c[0] = '('; c.data.chars[0].bytes.c[0] = '(';
c.data.chars[1].bytes.c[0] = ')'; c.data.chars[1].bytes.c[0] = ')';
printf(blue); printf(blue);
print(c, head->pos, scrDat, map->width, map->height); //TODO direction snake print(c, head->pos, scrDat, map->width, map->height); //TODO direction snake
#ifdef DEBUG //set color back to white
printf("\e[0m"); printf("\e[0m");
#endif
} }
else else
{ {
...@@ -632,6 +645,44 @@ int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head, ...@@ -632,6 +645,44 @@ int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head,
return 0; return 0;
} }
//----------texture loader(s)----------
/**
* load food skins from file
*
* @param f file
* @param data data pointer to store the information
* @param size size pointer for the data
*/
int load_food_skin(FILE *f, chunk **data, int *len){
int size;
fscanf(f, "%d", &size);
*data = calloc(size, sizeof(chunk));
if(data == 0){
return EOF;
}
*len = size;
for(int i = 0; i < size; i++){
int c;
while(c = fgetc(f), c != '\n'){
if(c == EOF){
return c;
}
}
for(int ch = 0; ch < 2; ch++){
c = fgetc(f);
(*data)[i].data.chars[ch].bytes.c[0] = c;
if(isUnicodeEncoding(0)){
int n = checkUnicharLen(c);
for (int p = 1; p < n; p++){
(*data)[i].data.chars[ch].bytes.c[p] = fgetc(f);
}
}
}
}
return 0;
}
//------------config loader------------ //------------config loader------------
/** /**
...@@ -641,10 +692,12 @@ int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head, ...@@ -641,10 +692,12 @@ int updateSnake(Matrix *map, screenData *scrDat, Direction d, snakeChain *head,
* @param repeatMap is the map repeated * @param repeatMap is the map repeated
* @param feedAmount food spawn rate * @param feedAmount food spawn rate
* @param canBite can snek bite itself * @param canBite can snek bite itself
* @param foodText food textures
* @param foodLen food textures amount
* *
* @return EOF if error 0 instead * @return EOF if error 0 instead
*/ */
int loadConfig(int *tickSpeed, int *repeatMap, int *feedAmount, int *canBite){ int loadConfig(int *tickSpeed, int *repeatMap, int *feedAmount, int *canBite, chunk **foodText, int *foodLen){
FILE *config; FILE *config;
config = fopen("config.cfg", "r"); config = fopen("config.cfg", "r");
//int stillFile = 1; //boolean to show file is ended... //int stillFile = 1; //boolean to show file is ended...
...@@ -686,6 +739,33 @@ int loadConfig(int *tickSpeed, int *repeatMap, int *feedAmount, int *canBite){ ...@@ -686,6 +739,33 @@ int loadConfig(int *tickSpeed, int *repeatMap, int *feedAmount, int *canBite){
else if(strncmp(name, "can_bite", 9) == 0){ else if(strncmp(name, "can_bite", 9) == 0){
fscanf(config, " %d", canBite); fscanf(config, " %d", canBite);
} }
else if(strncmp(name, "food_text_file", 10) == 0){
char fname[64] = {0}; //set it to zeros
int tmp_bool = true;
while(c = fgetc(config), isspace(c)){
if(c == '\n'){
tmp_bool = false;
break;
}
}
if(tmp_bool){
int tmp_int = 0;
do{
fname[tmp_int++] = c;
c = fgetc(config);
}while(!isspace(c));
}
FILE *skin_file = fopen(fname, "rb");
if(skin_file == 0){
return 1;
}
if(load_food_skin(skin_file, foodText, foodLen)){
fclose(skin_file);
return 2;
}
fclose(skin_file);
}
else{ else{
printf("Unknown keyword: %s", name); printf("Unknown keyword: %s", name);
} }
...@@ -728,6 +808,7 @@ int tick(Matrix *map, screenData *scrDat, snakeChain *snake, Direction *d, int f ...@@ -728,6 +808,7 @@ int tick(Matrix *map, screenData *scrDat, snakeChain *snake, Direction *d, int f
updateScreen(map, scrDat, snake, *d); updateScreen(map, scrDat, snake, *d);
if(*d == NONE){ if(*d == NONE){
chunk c; chunk c;
c.isFood = false;
c.data.chars[0].bytes.c[0] = '('; c.data.chars[0].bytes.c[0] = '(';
c.data.chars[1].bytes.c[0] = ')'; c.data.chars[1].bytes.c[0] = ')';
printf(blue); printf(blue);
...@@ -738,7 +819,7 @@ int tick(Matrix *map, screenData *scrDat, snakeChain *snake, Direction *d, int f ...@@ -738,7 +819,7 @@ int tick(Matrix *map, screenData *scrDat, snakeChain *snake, Direction *d, int f
updateFood(map, &foodTick, feedAmount, snake, scrDat); updateFood(map, &foodTick, feedAmount, snake, scrDat);
if(updateSnake(map, scrDat, *d, snake, canBite)){ if(updateSnake(map, scrDat, *d, snake, canBite)){
*d = NONE; *d = NONE;
//TODO Game over or remove 1 hp or ... return 1; //game over
} }
//printf("\e[0;0H\n"); //Update the terminal (mostly on Unix based systems) //printf("\e[0;0H\n"); //Update the terminal (mostly on Unix based systems)
fflush(stdout); fflush(stdout);
...@@ -753,9 +834,11 @@ int tick(Matrix *map, screenData *scrDat, snakeChain *snake, Direction *d, int f ...@@ -753,9 +834,11 @@ int tick(Matrix *map, screenData *scrDat, snakeChain *snake, Direction *d, int f
* @param repeatMap does the map repeat itself * @param repeatMap does the map repeat itself
* @param feedAmount food spawn rate * @param feedAmount food spawn rate
* @param canBite can snake bite itself * @param canBite can snake bite itself
* @param foodText food textures in chunks array
* @param foodTextLen food texture length
* @return 0 * @return 0
*/ */
int loop(Matrix *matrix, int tickspeed, int repeatMap, int feedAmount, int canBite){ int loop(Matrix *matrix, int tickspeed, int repeatMap, int feedAmount, int canBite, chunk *foodText, int foodTextLen){
Direction d = NONE; //Init with none Direction d = NONE; //Init with none
screenData scrDat; screenData scrDat;
...@@ -790,12 +873,23 @@ int loop(Matrix *matrix, int tickspeed, int repeatMap, int feedAmount, int canBi ...@@ -790,12 +873,23 @@ int loop(Matrix *matrix, int tickspeed, int repeatMap, int feedAmount, int canBi
scrDat.repeatMap = repeatMap; scrDat.repeatMap = repeatMap;
scrDat.commands[0] = NONE; scrDat.commands[0] = NONE;
scrDat.commands[1] = NONE; scrDat.commands[1] = NONE;
scrDat.foodTexture.text = foodText;
scrDat.foodTexture.len = foodTextLen;
scrDat.isXRepeat = false;
scrDat.isYRepeat = false;
while(42){ while(42){
if(tick(matrix, &scrDat, &snake, &d, feedAmount, canBite)){ if(tick(matrix, &scrDat, &snake, &d, feedAmount, canBite)){
break; break;
} }
unisleep(tickspeed); //Special sleep to work both in windows and unix environment unisleep(tickspeed); //Special sleep to work both in windows and unix environment
} }
chain = snake.next;
while (chain != NULL)
{
snakeChain *next = chain->next;
free(chain);
chain = next;
}
return 0; return 0;
} }
...@@ -854,24 +948,42 @@ void _print1char(Matrix *map){ ...@@ -854,24 +948,42 @@ void _print1char(Matrix *map){
* *
* @param argc redirected argc * @param argc redirected argc
* @param argv redirected argv * @param argv redirected argv
* @return 2 if config error 0 is okay
*/ */
int core(int argc, char const *argv[]) int core(int argc, char const *argv[])
{ {
if(argc == 1){
printf("Usage: snake <map name> [<snek skin>]");
return 0;
}
FILE *f; FILE *f;
Matrix map; Matrix map;
initMultiplatform(); // init stuff.
srand(time(0)); // bee a bit more random srand(time(0)); // bee a bit more random
int tickspeed = 100, repeatMap = 0, feedAmount = 20, canBite = true; // if no config, default value int tickspeed = 100, repeatMap = 0, feedAmount = 20, canBite = true; // if no config, default value
//----load config---- //----load config----
chunk *foodText = NULL;
int foodLen = 0;
if(loadConfig(&tickspeed, &repeatMap, &feedAmount, &canBite)){ if(loadConfig(&tickspeed, &repeatMap, &feedAmount, &canBite, &foodText, &foodLen)){
printf("Error while loading config..."); printf("Error while loading config...");
} }
if(foodText == NULL){
printf("No food texture file were found in config.");
return 2;
}
if(foodLen == 0){
printf("No food texture error");
free(foodText);
return 2;
}
//----init tasks---- //----init tasks----
if(isUnicodeEncoding(0)){ if(isUnicodeEncoding(0)){
...@@ -882,18 +994,14 @@ int core(int argc, char const *argv[]) ...@@ -882,18 +994,14 @@ int core(int argc, char const *argv[])
//----import map---- //----import map----
if(argc == 1){
printf("Usage: snake \<map name\> \[\<snake skin\>\]");
return 0;
}
else{
f = fopen(argv[1], "rb"); f = fopen(argv[1], "rb");
if(f == NULL){ if(f == NULL){
printf("Map file not found: %s", argv[1]); printf("Map file not found: %s", argv[1]);
return EOF; return EOF;
} }
readFile(f, &map); readFile(f, &map);
}
//----start game---- //----start game----
...@@ -902,7 +1010,15 @@ int core(int argc, char const *argv[]) ...@@ -902,7 +1010,15 @@ int core(int argc, char const *argv[])
_testprint(&map); _testprint(&map);
#endif #endif
loop(&map, tickspeed, repeatMap, feedAmount, canBite); initMultiplatform(); // init stuff.
printf("\e[7\e[?25l");//save cursor state and turn invisible cursor
loop(&map, tickspeed, repeatMap, feedAmount, canBite, foodText, foodLen);
printf("\e[8\e[2JGAME OVER...\n");
unisleep(2000);
endMultiplatformLib();
//test code //test code
//printf("map:\n"); //printf("map:\n");
...@@ -911,8 +1027,10 @@ int core(int argc, char const *argv[]) ...@@ -911,8 +1027,10 @@ int core(int argc, char const *argv[])
//free stuff //free stuff
free(foodText);
rmMatrix(&map); rmMatrix(&map);
printf("\npress any key to continue\n");
getchar();
return 0; return 0;
} }
...@@ -934,15 +1052,13 @@ int main(int argc, char const *argv[]) ...@@ -934,15 +1052,13 @@ int main(int argc, char const *argv[])
*/ */
int main(int argc, char const *argv[]) int main(int argc, char const *argv[])
{ {
int walltest; //warning: unused variable ‘walltest’ [-Wunused-variable] //int walltest; //warning: unused variable ‘walltest’ [-Wunused-variable]
//2 + 3; //... this does nothing... //2 + 3; //... this does nothing...
#ifdef DEBUG #ifdef DEBUG
int ret; int ret;
char const *array[] = {argv[0], "snake.c"}; // set the debug input char const *array[] = {argv[0], "map1.txt"}; // set the debug input
ret = core(2, array); ret = core(2, array);
printf("\npress any key to continue");
getchar();
//return 0, ret; //Miért van ez a függvény tele szeméttel??? pl 0, smt... //return 0, ret; //Miért van ez a függvény tele szeméttel??? pl 0, smt...
return ret; // így szép. return ret; // így szép.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment