Skip to content
Snippets Groups Projects
snake.c 9.71 KiB
Newer Older
KosmX's avatar
:D
KosmX committed
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
161400@bme.hu's avatar
161400@bme.hu committed
#include<locale.h>
KosmX's avatar
KosmX committed
#include<ctype.h>

KosmX's avatar
KosmX committed
#include "structs.h"
#include "multiplatformLib.h"
KosmX's avatar
:D
KosmX committed

KosmX's avatar
KosmX committed
//debugmalloc from infoc
#include "debugmalloc.h"

KosmX's avatar
KosmX committed
//There are lots of hints on https://infoc.eet.bme.hu/
KosmX's avatar
:D
KosmX committed

KosmX's avatar
KosmX committed
//#define windows 1 with #ifndef __linux__ solved...
//typedef unsigned long long int pointer; //Not optimal and not required. sometimes even the worst idea...
KosmX's avatar
KosmX committed

KosmX's avatar
KosmX committed
//-----------methods--------------
KosmX's avatar
KosmX committed

161400@bme.hu's avatar
161400@bme.hu committed
int isUnicodeEncoding(int set){
    static int bl = 0;
    if(set){
        bl = 1;
    }
    return bl;
}
KosmX's avatar
:D
KosmX committed

/**
 * Only the first byte is required
 */
int checkUnicharLen(char c){
    int i = 0;
KosmX's avatar
KosmX committed
    if(!isUnicodeEncoding(0)){
KosmX's avatar
:D
KosmX committed
        return 1; //int windows-xyzw every char has 1 len;
    }
    if(!(c & 0x80)){
        return 1;
    }
    while(c & 0x80){
        i++;
        c = c << 1;
        if(i > 8){
            return EOF;
        }
    }
    return i;
}

void printChar(unichar c){
    int len;
    len = checkUnicharLen(c.bytes.c[0]);
    for(int i = 0; i < len; i++){
        printf("%c", c.bytes.c[i]);
    }
}

KosmX's avatar
KosmX committed
//fueoetoeoecsoeoe *next //what to NOT do
KosmX's avatar
:D
KosmX committed

int readFile(FILE *file, Matrix *matrix){
KosmX's avatar
KosmX committed
    int c, len, maxLineLen = 0, lineCount = 1, lineLen = 0; //lineCount = (3,1) ??? why?... i was just bored
KosmX's avatar
:D
KosmX committed
    struct Vec2i pos;
    pos.x = 0;
    pos.y = 0;
    linkedString *linkedStr = 0, *current = 0, *next;
    //linkedStr = malloc(sizeof(linkedString));
KosmX's avatar
KosmX committed
    while(c = fgetc(file), c != EOF){
KosmX's avatar
:D
KosmX committed
        next = malloc(sizeof(linkedString));
        if(next == NULL){
            return EOF;
        }
        memset(next, 0, sizeof(linkedString)); //TODO remove after debugging
        next->next = 0;
        while (c == '\r')
        {
            c = fgetc(file);
            if(c == -1){
                break;
            }
        }
        next->value.bytes.c[0] = c;
        len = checkUnicharLen(c);
KosmX's avatar
KosmX committed
        if(isUnicodeEncoding(0) && len -1){
KosmX's avatar
:D
KosmX committed
            for (int i = 1; i < len; i++){
                c = fgetc(file);
                if(c == -1){
                    return EOF;
                }
                next->value.bytes.c[i] = c;
            }
        }
        else if(c == '\n'){       //checking newline (unichar can't be a newline char (\n))
            lineCount++;
            if(lineLen > maxLineLen){
                maxLineLen = lineLen;
            }
            lineLen = -1;
        }
        lineLen++;
        //next.value = chars;
        if(current != 0){
            current->next = next;
        }
        else
        {
            linkedStr = next;
            //current = next;
        }
        current = next;
    }
    maxLineLen = maxLineLen / 2 + maxLineLen % 2;
    matrix->height = lineCount;
    matrix->width = maxLineLen;
    matrix->matrix = calloc(maxLineLen, sizeof(chunk*));
    if(matrix->matrix == NULL){
        printf("failed to allocate memory for the matrix");
        return EOF-1;
    }
    for (int i = 0; i < maxLineLen; i++){
        matrix->matrix[i] = calloc(lineCount, sizeof(chunk));
        if(matrix->matrix[i] == NULL){
            printf("failed to allocate memory for the matrix");
            return EOF-1;
        }
        for(int n = 0; n < lineCount; n++){
            for(int a = 0; a < 2; a++){
                matrix->matrix[i][n].chars[a].bytes.c[0] = ' ';
            }
        }
    }

    current = linkedStr;
    while(current != 0){
        //tmp = current;
        //current = current->next;
        //free(tmp);
        if(current->value.bytes.c[0] == '\n'){
            pos.x = 0;
            pos.y++;
            //break;
        }
        else{
            for(int charPos = 0; charPos < 4; charPos++){
                matrix->matrix[pos.x/2][pos.y].chars[pos.x%2].bytes.c[charPos] = current->value.bytes.c[charPos];
            }
            pos.x++; 
        }
        next = current;
        current = current->next;
        free(next);
    }
    return 0;
}

void rmMatrix(Matrix *map){
    for(int i = 0; i < map->width; i++){
        free(map->matrix[i]);
    }
    free(map->matrix);
}

KosmX's avatar
KosmX committed
//Use what chunk,
//witch screen coordinates?
//just the screen data
KosmX's avatar
KosmX committed
void printChunk(chunk ch, Pos pos, screenData *scrDat){
    pos.x -= scrDat->pos.x;
    pos.y -= scrDat->pos.y;
    if(pos.x < 0 || pos.y < 0 || pos.x >= scrDat->pos.x || pos.y >= scrDat->pos.y){
        return; //if pos is not on the screen, just do nothing.
    }
    
}

KosmX's avatar
KosmX committed
int updateScreenSize(Matrix *map, screenData *scrDat){
    struct Vec2i size = getWindowSize();
    if(size.x == scrDat->size.x && size.y == scrDat->size.y){
        return 0; //no change happened
    }
    scrDat->size.x = size.x;
    scrDat->size.y = size.y;
    if(scrDat->repeatMap){
        scrDat->isXRepeat = size.x < map->width;
        scrDat->isYRepeat = size.y < map->height;
    }
    return 1;
}

//Update screen if required 
void  updateScreen(Matrix *map, screenData *scrDat, snakeChain *head){
    int do_update;
    do_update = updateScreenSize(map, scrDat);
    if(scrDat->isXRepeat){
KosmX's avatar
a  
KosmX committed
        if(head->pos.x < scrDat->pos.x - 6){//TODO
KosmX's avatar
KosmX committed
            
        }
    }
    else{
        scrDat->pos.x = 0;
    }
}

//Tick the game, step the snake, collect and place food.
KosmX's avatar
b  
KosmX committed
//check new direction
//update display
//uppdate food state
//step snake
KosmX's avatar
a  
KosmX committed
void tick(Matrix *map, screenData *scrDat, snakeChain *snake, Direction *d){
KosmX's avatar
KosmX committed

}
KosmX's avatar
KosmX committed

//------------config loader------------

KosmX's avatar
KosmX committed
int loadConfig(int *tickSpeed, int *repeatMap){
KosmX's avatar
KosmX committed
    FILE *config;
    config = fopen("config.cfg", "r");
    //int stillFile = 1; //boolean to show file is ended...
    if(config == NULL){
        return -1;
    }
    while(1){
        char name[32] = {0}, c; //it have to be enough;
        while(c = fgetc(config), c != -1 && isspace(c));
        if(c == -1){
            break;
        }
        //name[0] = c;
        for(int i = 0; i < 32 && !isspace(c) && c != '='; i++, c = fgetc(config)){
            name[i] = c;
        }
        //c = fgetc(config);
        while(c != '='){
            c = fgetc(config);
            if(c == -1){
                printf("I can't  understand the config file: %s", name);
                return EOF;
            }
        }
        if(strncmp(name, "use_utf8", 9) == 0){
            int bl;
            fscanf(config, " %d", &bl);
            isUnicodeEncoding(bl);
        }
        else if(strncmp(name, "tickspeed", 10) == 0){
            fscanf(config, " %d", tickSpeed);
        }
KosmX's avatar
KosmX committed
        else if(strncmp(name, "repeatMap", 10) == 0){
            fscanf(config, " %d", repeatMap);
        }
KosmX's avatar
KosmX committed
        else{
            printf("Unknown keyword: %s", name);
        }
    }
    return 0;
}



//------------LOOP METHOD--------------

int loop(Matrix *matrix, int tickspeed){

KosmX's avatar
a  
KosmX committed
    Direction d = DOWN;
    screenData scrDat;
    snakeChain snake;   //TODO init snake, screen data
KosmX's avatar
KosmX committed
    scrDat.size.x = 0;
    scrDat.size.y = 0;
KosmX's avatar
a  
KosmX committed
    while(42){
        tick(matrix, &scrDat, &snake, &d);
        unisleep(tickspeed); //Special sleep to work both in windows and unix environment
    }
KosmX's avatar
KosmX committed
    return 0;
}
KosmX's avatar
:D
KosmX committed

//------------TESTING METHODS-------------
void _testprint(Matrix *map){
    for (int y = 0; y < map->height; y++){
        for(int x = 0; x < map->width; x++){
            for(int i = 0; i < 2; i++){
                //printf("%c", map->matrix[x][y].chars->bytes.c[i * 4]); //WTF... I didn't indexed correctly, but accidentaly I've got the right value...
                printChar(map->matrix[x][y].chars[i]);
            }
            //printf("|");
        }
        printf("\n");
    }
}

void _print1char(Matrix *map){
    int x, y;
    while(scanf(" %d%d", &x, &y) == 2){
        if(x >= 0 && y >= 0 && x < map->width && y < map->height){
            for(int i = 0;i < 2; i++){
KosmX's avatar
KosmX committed
                printf("\nvalue: %hx, %hx, %hx, %hx\n",
unknown's avatar
unknown committed
                (unsigned)map->matrix[x][y].chars[i].bytes.c[0],
                (unsigned)map->matrix[x][y].chars[i].bytes.c[1],
                (unsigned)map->matrix[x][y].chars[i].bytes.c[2],
                (unsigned)map->matrix[x][y].chars[i].bytes.c[3]);
KosmX's avatar
:D
KosmX committed
                printf("as character: \"");
                printChar(map->matrix[x][y].chars[i]);
                printf("\"\n");
            }
        }
    }
}


//-------------CORE METHOD----------------

int core(int argc, char const *argv[])
{
    FILE *f;
    Matrix map;
161400@bme.hu's avatar
161400@bme.hu committed

KosmX's avatar
KosmX committed
    initMultiplatform(); // init stuff.

KosmX's avatar
KosmX committed
    int tickspeed = 100, repeatMap = 0; // if no config, default value
KosmX's avatar
KosmX committed

    //----load config----

KosmX's avatar
KosmX committed
    if(loadConfig(&tickspeed, &repeatMap)){
KosmX's avatar
KosmX committed
        printf("Error while loading config...");
    }

161400@bme.hu's avatar
161400@bme.hu committed
    //----init tasks----

KosmX's avatar
KosmX committed
    if(isUnicodeEncoding(0)){
KosmX's avatar
KosmX committed
        #ifndef __linux__
KosmX's avatar
KosmX committed
        setlocale(LC_ALL, ".utf-8");
KosmX's avatar
KosmX committed
        #endif
KosmX's avatar
KosmX committed
    }
161400@bme.hu's avatar
161400@bme.hu committed

    //----import map----

KosmX's avatar
:D
KosmX committed
    if(argc == 1){
        printf("Usage: snake <map name> [<snake skin>]");
        return 0;
    }
    else{
        f = fopen(argv[1], "rb");
        if(f == NULL){
            printf("Map file not found: %s", argv[1]);
            return EOF;
        }
        readFile(f, &map);
    }

    //test code
    printf("map:\n");
    _testprint(&map);
unknown's avatar
unknown committed
    _print1char(&map);
KosmX's avatar
:D
KosmX committed
    /* code */
    //free stuff
    rmMatrix(&map);

    return 0;
}


/*
int main(int argc, char const *argv[])
{
    return core(argc, argv);
}
*/

int main(int argc, char const *argv[])
{
KosmX's avatar
KosmX committed
    //2 + 3;  //... this does nothing...
KosmX's avatar
:D
KosmX committed
    int ret;
161400@bme.hu's avatar
161400@bme.hu committed
    char const *array[] = {argv[0], "map1.txt"};
KosmX's avatar
:D
KosmX committed
    ret = core(2, array);
    printf("\npress any key to continue");
    getchar();
KosmX's avatar
KosmX committed
    //return 0, ret; //Miért van ez a függvény tele szeméttel??? pl 0, smt...

    return ret; // így szép.
KosmX's avatar
:D
KosmX committed
}