diff --git a/.vscode/settings.json b/.vscode/settings.json index bb9079a..5281033 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,7 @@ "structure.h": "c", "limits": "c", "base.h": "c", - "cars.h": "c" + "cars.h": "c", + "sdl_image.h": "c" } } \ No newline at end of file diff --git a/Makefile b/Makefile index 4c154f6..b9c110b 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ test: bin/back mem: bin/back valgrind --leak-check=full ./bin/back -bin/back: obj/main.o obj/display.o obj/base.o obj/cars.o obj/rooms.o +bin/back: obj/main.o obj/display.o obj/base.o obj/cars.o obj/rooms.o obj/structure.o mkdir -p bin $(CC) $(FLAGS) $^ $(LFLAGS) -o $@ @@ -23,6 +23,7 @@ obj/display.o: src/display.c obj/base.o: src/base.c obj/cars.o: src/cars.c obj/rooms.o: src/rooms.c +obj/structure.o: src/structure.c .PHONY: clean mrproper diff --git a/bin/back b/bin/back index 9861678..3a2daf0 100755 Binary files a/bin/back and b/bin/back differ diff --git a/levels/test.txt b/levels/test.txt new file mode 100644 index 0000000..c7dea7e --- /dev/null +++ b/levels/test.txt @@ -0,0 +1,17 @@ +5 6 +S..... +031E.. +024... +215... +...... + +$ +. = NULL +0 = Vertical +1 = Horizontal +2 = TopRight (NE) +3 = BottomRight (SE) +4 = BottomLeft (SW) +5 = TopLeft (NW) +S = Start +E = End \ No newline at end of file diff --git a/obj/base.o b/obj/base.o index 3407883..1e40980 100644 Binary files a/obj/base.o and b/obj/base.o differ diff --git a/obj/cars.o b/obj/cars.o index af76b9d..7b2fd51 100644 Binary files a/obj/cars.o and b/obj/cars.o differ diff --git a/obj/display.o b/obj/display.o index 85f7eaa..b3e9699 100644 Binary files a/obj/display.o and b/obj/display.o differ diff --git a/obj/main.o b/obj/main.o index e11486a..369ef42 100644 Binary files a/obj/main.o and b/obj/main.o differ diff --git a/obj/rooms.o b/obj/rooms.o index 165971d..7ef8db7 100644 Binary files a/obj/rooms.o and b/obj/rooms.o differ diff --git a/obj/structure.o b/obj/structure.o new file mode 100644 index 0000000..54ce4d2 Binary files /dev/null and b/obj/structure.o differ diff --git a/src/base.c b/src/base.c index 145bf78..80bf439 100644 --- a/src/base.c +++ b/src/base.c @@ -24,7 +24,6 @@ void init_all(int nPl) { currentTurn = 0; players = malloc(sizeof(carData)*nPlayers); for(int p = 0; p < nPlayers; p++) { - players[p].curChunk = start; players[p].c = init_car("player"); } } diff --git a/src/cars.c b/src/cars.c index a72efc7..0841f90 100644 --- a/src/cars.c +++ b/src/cars.c @@ -15,10 +15,8 @@ #include "base.h" #include "cars.h" -car* init_car(const char* name) { +car* init_car() { car* res = malloc(sizeof(car)); - res->name = "e"; - res->size = 40; res->itm = NULL; res->nCoins = 0; res->pos = (ptf){.fx = 0.0, .fy = 0.0}; @@ -26,7 +24,7 @@ car* init_car(const char* name) { return res; } -void move_car(car* c, double x, double y) { +void place_car(car* c, double x, double y) { c->pos.fx = x; c->pos.fy = y; } @@ -38,4 +36,6 @@ void set_speed_car(car* c, double vx, double vy) { void destroy_car(car* c) { free(c); -} \ No newline at end of file +} + +// ------------------------------------------------------------ // \ No newline at end of file diff --git a/src/cars.h b/src/cars.h index 36a0a39..2102df7 100644 --- a/src/cars.h +++ b/src/cars.h @@ -1,10 +1,10 @@ #ifndef CARS_H #define CARS_H -car* init_car(const char* name); +car* init_car(); void destroy_car(car* c); -void move_car(car* c, double x, double y); +void place_car(car* c, double x, double y); void set_speed_car(car* c, double vx, double vy); #endif \ No newline at end of file diff --git a/src/display.c b/src/display.c index df9431f..657b6d8 100644 --- a/src/display.c +++ b/src/display.c @@ -212,7 +212,8 @@ void draw7SegNumberToRenderer(SDL_Renderer* renderer, int n, int X, int Y, int W //---------------------------------------------------------------------------------------------------------------------// // circle functions by @Gumichan01 at https://gist.github.com/Gumichan01/332c26f6197a432db91cc4327fcabb1c (not native) // //---------------------------------------------------------------------------------------------------------------------// -void SDL_RenderDrawCircle(SDL_Renderer * renderer, int x, int y, int radius) { +void SDL_RenderDrawCircle(SDL_Renderer * renderer, int x, int y, int radius, int r, int g, int b, int a) { + SDL_SetRenderDrawColor(renderer, r, g, b, a); int offsetx, offsety, d; int status; @@ -253,7 +254,8 @@ void SDL_RenderDrawCircle(SDL_Renderer * renderer, int x, int y, int radius) { } -void SDL_RenderFillCircle(SDL_Renderer * renderer, int x, int y, int radius) { +void SDL_RenderFillCircle(SDL_Renderer * renderer, int x, int y, int radius, int r, int g, int b, int a) { + SDL_SetRenderDrawColor(renderer, r, g, b, a); int offsetx, offsety, d; int status; @@ -295,6 +297,129 @@ void SDL_RenderFillCircle(SDL_Renderer * renderer, int x, int y, int radius) { // ------------------------------------------------------------------------------------------------------------------------- // +void renderStraights(SDL_Renderer* renderer, level* lvl, int cx, int cy, int range, int rsize) { + for(int x = -range; x <= range; x++) { + for(int y = -range; y <= range; y++) { + if(cx+x >= 0 && cy+y >= 0 && cx+x < lvl->lines && cy+y < lvl->cols) { + switch (lvl->map[cx+x][cy+y]){ + case NONE: + placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); + break; + + case START: + case END: + placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); + placeRectToRenderer(renderer, + (WIDTH-rsize)/2+rsize*y+(int)(START_EDGE*rsize), + (HEIGHT-rsize)/2+rsize*x, + rsize-(int)(2*START_EDGE*rsize), + rsize, + 32, 32, 32, 255); + placeRectToRenderer(renderer, + (WIDTH-rsize)/2+rsize*y, + (HEIGHT-rsize)/2+rsize*x+(int)(START_EDGE*rsize), + rsize, + rsize-(int)(2*START_EDGE*rsize), + 32, 32, 32, 255); + break; + + case STR_H: + placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); + placeRectToRenderer(renderer, + (WIDTH-rsize)/2+rsize*y, + (HEIGHT-rsize)/2+rsize*x+(int)(DIST_EDGE*rsize), + rsize, + rsize-(int)(2*DIST_EDGE*rsize), + 32, 32, 32, 255); + break; + + case STR_V: + placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); + placeRectToRenderer(renderer, + (WIDTH-rsize)/2+rsize*y+(int)(DIST_EDGE*rsize), + (HEIGHT-rsize)/2+rsize*x, + rsize-(int)(2*DIST_EDGE*rsize), + rsize, + 32, 32, 32, 255); + break; + + case TURN_NE: + break; + + case TURN_SE: + break; + + case TURN_SW: + break; + + case TURN_NW: + break; + + default: + break; + } + } + } + } +} + +void renderCircles(SDL_Renderer* renderer, level* lvl, int cx, int cy, int range, int rsize) { + for(int x = -range; x <= range; x++) { + for(int y = -range; y <= range; y++) { + if(cx+x >= 0 && cy+y >= 0 && cx+x < lvl->lines && cy+y < lvl->cols) { + switch (lvl->map[cx+x][cy+y]){ + case NONE: + break; + + case START: + case END: + break; + + case STR_H: + break; + + case STR_V: + break; + + case TURN_NE: + placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); + SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y+rsize, (HEIGHT-rsize)/2+rsize*x , (int)(rsize*(1-DIST_EDGE)), 32, 32, 32, 255); + SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y+rsize, (HEIGHT-rsize)/2+rsize*x , (int)(rsize*DIST_EDGE), 0, 0, 0, 255); + break; + + case TURN_SE: + placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); + SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y+rsize, (HEIGHT-rsize)/2+rsize*x+rsize, (int)(rsize*(1-DIST_EDGE)), 32, 32, 32, 255); + SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y+rsize, (HEIGHT-rsize)/2+rsize*x+rsize, (int)(rsize*DIST_EDGE), 0, 0, 0, 255); + break; + + case TURN_SW: + placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); + SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y , (HEIGHT-rsize)/2+rsize*x+rsize, (int)(rsize*(1-DIST_EDGE)), 32, 32, 32, 255); + SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y , (HEIGHT-rsize)/2+rsize*x+rsize, (int)(rsize*DIST_EDGE), 0, 0, 0, 255); + break; + + case TURN_NW: + placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); + SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y , (HEIGHT-rsize)/2+rsize*x , (int)(rsize*(1-DIST_EDGE)), 32, 32, 32, 255); + SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y , (HEIGHT-rsize)/2+rsize*x , (int)(rsize*DIST_EDGE), 0, 0, 0, 255); + break; + + default: + break; + } + } + } + } +} + +void renderMap(SDL_Renderer* renderer, level* lvl, int cx, int cy, int range, int rsize) { + renderCircles(renderer, lvl, cx, cy, range, rsize); + renderStraights(renderer, lvl, cx, cy, range, rsize); +} + +// ------------------------------------------------------------------------------------------------------------------------- // + void import_digits(SDL_Renderer* renderer) { imgs* res = malloc(sizeof(imgs)); res->arr = malloc(sizeof(SDL_Texture*)*11); diff --git a/src/display.h b/src/display.h index fa04f9b..1518086 100644 --- a/src/display.h +++ b/src/display.h @@ -12,8 +12,10 @@ void drawNumberToRenderer(SDL_Renderer* renderer, int n, int X, int Y, int W, in void drawStringToRenderer(SDL_Renderer* renderer, char* s, int X, int Y, int W, int H); void draw7SegDigitToRenderer(SDL_Renderer* renderer, int n, int X, int Y, int W, int H, int thicc, int R, int G, int B, int A); void draw7SegNumberToRenderer(SDL_Renderer* renderer, int n, int X, int Y, int W, int H, int thicc, int R, int G, int B, int A, int side, int dot); -void SDL_RenderDrawCircle(SDL_Renderer * renderer, int x, int y, int radius); -void SDL_RenderFillCircle(SDL_Renderer * renderer, int x, int y, int radius); +void SDL_RenderDrawCircle(SDL_Renderer * renderer, int x, int y, int radius, int r, int g, int b, int a); +void SDL_RenderFillCircle(SDL_Renderer * renderer, int x, int y, int radius, int r, int g, int b, int a); + +void renderMap(SDL_Renderer* renderer, level* lvl, int cx, int cy, int range, int rsize); void import_digits(SDL_Renderer* renderer); void import_letters(SDL_Renderer* renderer); diff --git a/src/main.c b/src/main.c index 988a4f7..2e59d3c 100644 --- a/src/main.c +++ b/src/main.c @@ -17,9 +17,6 @@ #include "rooms.h" #include "cars.h" -const int WIDTH = 1000; -const int HEIGHT = 800; - const int N_PLAYERS = 4; int main() { @@ -38,16 +35,20 @@ int main() { import_letters(rend); import_digits(rend); - init_rooms(); init_all(N_PLAYERS); // ---------------------------- // - + //test_file("levels/test.txt"); + level* test = parse_level("levels/test.txt"); - usleep(1000000); + renderMap(rend, test, 1, 1, 2, 250); + updateRenderer(rend); + + int n; + scanf("%d", &n); // ---------------------------- // free_digits(digits); free_digits(letters); - destroy_rooms(); + free_level(test); SDL_DestroyRenderer(rend); SDL_DestroyWindow(win); diff --git a/src/rooms.c b/src/rooms.c index a380cb5..751030a 100644 --- a/src/rooms.c +++ b/src/rooms.c @@ -15,52 +15,103 @@ #include "base.h" #include "rooms.h" -chunk* start; -chunk** allRooms; -int nMaxRooms; -int curRoom; +bool is_digit(char c) { + return ((int)c >= 48 && (int)c <= 57); +} -// returns the index of the new chunk -int build_empty_room(int CX, int CY, int w, int h, chunk* north, chunk* east, chunk* south, chunk* west) { - if(curRoom < nMaxRooms) { - chunk* res = malloc(sizeof(chunk)); - res->north = north; - res->east = east; - res->south = south; - res->west = west; - res->chW = w; - res->chH = h; - res->chX = CX; - res->chY = CY; +int read_int(FILE* ptr) { + int res = 0; + char c = fgetc(ptr); + while(c != EOF && !is_digit(c)) { + c = fgetc(ptr); + } + while(c != EOF && is_digit(c)) { + res = 10*res + (int)c - 48; + c = fgetc(ptr); + } + return res; +} - res->rects = malloc(sizeof(rectangle)*32); - res->nRects = 0; - res->circles = malloc(sizeof(circle)*32); - res->nCircles = 0; - - allRooms[curRoom] = res; - curRoom += 1; - return (curRoom-1); - } else { - fprintf(stderr, "ERROR : all rooms are filled, cannot create a new one\n"); - return (-1); +// typedef enum road_t {NONE, START, END, STR_V, STR_H, TURN_NE, TURN_SE, TURN_SW, TURN_NW} road; // +/* +. = NULL +0 = Vertical +1 = Horizontal +2 = TopRight (NE) +3 = BottomRight (SE) +4 = BottomLeft (SW) +5 = TopLeft (NW) +S = Start +E = End +*/ +road get_type(char c) { + switch (c){ + case '.': + return NONE; + case 'S': + return START; + case 'E': + return END; + case '0': + return STR_V; + case '1': + return STR_H; + case '2': + return TURN_NE; + case '3': + return TURN_SE; + case '4': + return TURN_SW; + case '5': + return TURN_NW; + + default: + fprintf(stderr, "unrecognized character '%c' encountered in parsing", c); + return NONE; } } -void init_rooms() { - nMaxRooms = 128; - curRoom = 0; - allRooms = malloc(sizeof(chunk*)*nMaxRooms); - - int id0 = build_empty_room(0, 0, 500, 500, NULL, NULL, NULL, NULL); - start = allRooms[id0]; +void test_file(char* path) { + FILE* ptr = fopen(path, "r"); + char c = fgetc(ptr); + while(c != EOF) { + printf("%c", c); + c = fgetc(ptr); + } + fclose(ptr); } -void destroy_rooms() { - for(int r = 0; r < curRoom; r++) { - free(allRooms[r]->circles); - free(allRooms[r]->rects); - free(allRooms[r]); +level* parse_level(char* path) { + FILE* ptr = fopen(path, "r"); + + level* lvl = malloc(sizeof(level)); + lvl->lines = read_int(ptr); + lvl->cols = read_int(ptr); + + //printf("dims : (%d %d)\n", lvl->lines, lvl->cols); + + lvl->map = malloc(sizeof(road*)*(lvl->lines)); + for(int l = 0; l < lvl->lines; l++) { + lvl->map[l] = malloc(sizeof(road)*(lvl->cols)); } - free(allRooms); + + for(int l = 0; l < lvl->lines; l++) { + for(int c = 0; c < lvl->cols; c++) { + char ch = fgetc(ptr); + if(ch == '\n') {ch = fgetc(ptr); printf("\n");} + printf("%c", ch); + lvl->map[l][c] = get_type(ch); + //printf("(%d %d -> %c)", l, c, ch); + } + } + + return lvl; +} + +void free_level(level* lvl) { + for(int l = 0; l < lvl->lines; l++) { + free(lvl->map[l]); + } + free(lvl->map); + free(lvl); } \ No newline at end of file diff --git a/src/rooms.h b/src/rooms.h index 14ff590..dd86fb2 100644 --- a/src/rooms.h +++ b/src/rooms.h @@ -1,9 +1,9 @@ #ifndef ROOMS_H #define ROOMS_H -int build_empty_room(int CX, int CY, int w, int h, chunk* north, chunk* east, chunk* south, chunk* west); +void test_file(char* path); -void init_rooms(); -void destroy_rooms(); +level* parse_level(char* path); +void free_level(level* lvl); #endif \ No newline at end of file diff --git a/src/structure.c b/src/structure.c new file mode 100644 index 0000000..95d2c3a --- /dev/null +++ b/src/structure.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include "structure.h" + +const int WIDTH = 1000; +const int HEIGHT = 1000; + +const int ROOM_SIZE = 100; +const int MAX_SPEED = 66; + +const double DIST_EDGE = 0.2; +const double START_EDGE = 0.05; +const int BARRIERS = 1; +const int RESTITUTION_WALL = 0.8; +const int RESTITUTION_PLAYER = 0.8; + +const double FRICTION = 0.75; +const double DV = 0.01; diff --git a/src/structure.h b/src/structure.h index 0701b45..0b842c3 100644 --- a/src/structure.h +++ b/src/structure.h @@ -11,7 +11,6 @@ typedef struct imgs { // ------------------------------------------------------------------------ // // car shenanigans - typedef struct pt_t {int ix; int iy;} pt; typedef struct ptf_t {double fx; double fy;} ptf; @@ -26,9 +25,7 @@ typedef struct item_t { } item; typedef struct car_t { - const char* name; - ptf pos; - int size; + ptf pos; // remains in [0, ROOM_SIZE[ ptf vel; int nCoins; item* itm; // either NULL or a pointer to an item @@ -42,53 +39,23 @@ typedef struct color_t { uint8_t blue; } color; -// 2 types of objects : rectangles and circles -typedef struct rectangle_t { - int x; - int y; - int w; - int h; - color rgb; - double restitution; - void (*onHit)(struct rectangle_t * self, car* bonk); - void (*betweenTurn) (struct rectangle_t * self); -} rectangle; +// one chunk +typedef enum road_t {NONE, START, END, STR_V, STR_H, TURN_NE, TURN_SE, TURN_SW, TURN_NW} road; -typedef struct circle_t { - int x; - int y; - int r; - color rgb; - double restitution; - void (*onHit)(struct circle_t * self, car* bonk); - void (*betweenTurn) (struct circle_t * self); -} circle; - -typedef struct chunk_t { - rectangle* rects; - int nRects; - circle* circles; - int nCircles; - - // size of the chunk - int chW; - int chH; - - // absolute coords - int chX; - int chY; - - // neighbors - struct chunk_t* north; - struct chunk_t* east; - struct chunk_t* south; - struct chunk_t* west; -} chunk; +typedef struct level_t { + pt start; + pt end; + int lines; + int cols; + road** map; +} level; // global car data typedef struct carData_t { car* c; - chunk* curChunk; + color rgb; + int chx; + int chy; } carData; // ------------------------------------------------------------------------ // @@ -97,10 +64,23 @@ extern imgs* letters; // SDL data extern int currentTurn; // name explains -extern chunk* start; // starting chunk -extern chunk** allRooms; // an array containing every generated room, used for free() -extern int nMaxRooms; // size of allRooms extern carData* players; // contains each player and its corresponding data extern int nPlayers; // size of players +// ------------------------------------------------------------------------ // +// constants +extern const int WIDTH; +extern const int HEIGHT; + +extern const int ROOM_SIZE; +extern const int MAX_SPEED; + +extern const double DIST_EDGE; +extern const double START_EDGE; +extern const int BARRIERS; +extern const int RESTITUTION_WALL; +extern const int RESTITUTION_PLAYER; + +extern const double FRICTION; +extern const double DV; #endif \ No newline at end of file