major refactoring

This commit is contained in:
Alexandre 2025-05-14 23:09:52 +02:00
parent 517395d500
commit 8f20ebb87d
20 changed files with 309 additions and 113 deletions

View File

@ -6,6 +6,7 @@
"structure.h": "c", "structure.h": "c",
"limits": "c", "limits": "c",
"base.h": "c", "base.h": "c",
"cars.h": "c" "cars.h": "c",
"sdl_image.h": "c"
} }
} }

View File

@ -10,7 +10,7 @@ test: bin/back
mem: bin/back mem: bin/back
valgrind --leak-check=full ./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 mkdir -p bin
$(CC) $(FLAGS) $^ $(LFLAGS) -o $@ $(CC) $(FLAGS) $^ $(LFLAGS) -o $@
@ -23,6 +23,7 @@ obj/display.o: src/display.c
obj/base.o: src/base.c obj/base.o: src/base.c
obj/cars.o: src/cars.c obj/cars.o: src/cars.c
obj/rooms.o: src/rooms.c obj/rooms.o: src/rooms.c
obj/structure.o: src/structure.c
.PHONY: clean mrproper .PHONY: clean mrproper

BIN
bin/back

Binary file not shown.

17
levels/test.txt Normal file
View File

@ -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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
obj/structure.o Normal file

Binary file not shown.

View File

@ -24,7 +24,6 @@ void init_all(int nPl) {
currentTurn = 0; currentTurn = 0;
players = malloc(sizeof(carData)*nPlayers); players = malloc(sizeof(carData)*nPlayers);
for(int p = 0; p < nPlayers; p++) { for(int p = 0; p < nPlayers; p++) {
players[p].curChunk = start;
players[p].c = init_car("player"); players[p].c = init_car("player");
} }
} }

View File

@ -15,10 +15,8 @@
#include "base.h" #include "base.h"
#include "cars.h" #include "cars.h"
car* init_car(const char* name) { car* init_car() {
car* res = malloc(sizeof(car)); car* res = malloc(sizeof(car));
res->name = "e";
res->size = 40;
res->itm = NULL; res->itm = NULL;
res->nCoins = 0; res->nCoins = 0;
res->pos = (ptf){.fx = 0.0, .fy = 0.0}; res->pos = (ptf){.fx = 0.0, .fy = 0.0};
@ -26,7 +24,7 @@ car* init_car(const char* name) {
return res; 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.fx = x;
c->pos.fy = y; c->pos.fy = y;
} }
@ -38,4 +36,6 @@ void set_speed_car(car* c, double vx, double vy) {
void destroy_car(car* c) { void destroy_car(car* c) {
free(c); free(c);
} }
// ------------------------------------------------------------ //

View File

@ -1,10 +1,10 @@
#ifndef CARS_H #ifndef CARS_H
#define CARS_H #define CARS_H
car* init_car(const char* name); car* init_car();
void destroy_car(car* c); 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); void set_speed_car(car* c, double vx, double vy);
#endif #endif

View File

@ -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) // // 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 offsetx, offsety, d;
int status; 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 offsetx, offsety, d;
int status; 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) { void import_digits(SDL_Renderer* renderer) {
imgs* res = malloc(sizeof(imgs)); imgs* res = malloc(sizeof(imgs));
res->arr = malloc(sizeof(SDL_Texture*)*11); res->arr = malloc(sizeof(SDL_Texture*)*11);

View File

@ -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 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 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 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_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); 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_digits(SDL_Renderer* renderer);
void import_letters(SDL_Renderer* renderer); void import_letters(SDL_Renderer* renderer);

View File

@ -17,9 +17,6 @@
#include "rooms.h" #include "rooms.h"
#include "cars.h" #include "cars.h"
const int WIDTH = 1000;
const int HEIGHT = 800;
const int N_PLAYERS = 4; const int N_PLAYERS = 4;
int main() { int main() {
@ -38,16 +35,20 @@ int main() {
import_letters(rend); import_letters(rend);
import_digits(rend); import_digits(rend);
init_rooms();
init_all(N_PLAYERS); 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(digits);
free_digits(letters); free_digits(letters);
destroy_rooms(); free_level(test);
SDL_DestroyRenderer(rend); SDL_DestroyRenderer(rend);
SDL_DestroyWindow(win); SDL_DestroyWindow(win);

View File

@ -15,52 +15,103 @@
#include "base.h" #include "base.h"
#include "rooms.h" #include "rooms.h"
chunk* start; bool is_digit(char c) {
chunk** allRooms; return ((int)c >= 48 && (int)c <= 57);
int nMaxRooms; }
int curRoom;
// returns the index of the new chunk int read_int(FILE* ptr) {
int build_empty_room(int CX, int CY, int w, int h, chunk* north, chunk* east, chunk* south, chunk* west) { int res = 0;
if(curRoom < nMaxRooms) { char c = fgetc(ptr);
chunk* res = malloc(sizeof(chunk)); while(c != EOF && !is_digit(c)) {
res->north = north; c = fgetc(ptr);
res->east = east; }
res->south = south; while(c != EOF && is_digit(c)) {
res->west = west; res = 10*res + (int)c - 48;
res->chW = w; c = fgetc(ptr);
res->chH = h; }
res->chX = CX; return res;
res->chY = CY; }
res->rects = malloc(sizeof(rectangle)*32); // typedef enum road_t {NONE, START, END, STR_V, STR_H, TURN_NE, TURN_SE, TURN_SW, TURN_NW} road; //
res->nRects = 0; /*
res->circles = malloc(sizeof(circle)*32); . = NULL
res->nCircles = 0; 0 = Vertical
1 = Horizontal
allRooms[curRoom] = res; 2 = TopRight (NE)
curRoom += 1; 3 = BottomRight (SE)
return (curRoom-1); 4 = BottomLeft (SW)
} else { 5 = TopLeft (NW)
fprintf(stderr, "ERROR : all rooms are filled, cannot create a new one\n"); S = Start
return (-1); 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() { void test_file(char* path) {
nMaxRooms = 128; FILE* ptr = fopen(path, "r");
curRoom = 0; char c = fgetc(ptr);
allRooms = malloc(sizeof(chunk*)*nMaxRooms); while(c != EOF) {
printf("%c", c);
int id0 = build_empty_room(0, 0, 500, 500, NULL, NULL, NULL, NULL); c = fgetc(ptr);
start = allRooms[id0]; }
fclose(ptr);
} }
void destroy_rooms() { level* parse_level(char* path) {
for(int r = 0; r < curRoom; r++) { FILE* ptr = fopen(path, "r");
free(allRooms[r]->circles);
free(allRooms[r]->rects); level* lvl = malloc(sizeof(level));
free(allRooms[r]); 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);
} }

View File

@ -1,9 +1,9 @@
#ifndef ROOMS_H #ifndef ROOMS_H
#define 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(); level* parse_level(char* path);
void destroy_rooms(); void free_level(level* lvl);
#endif #endif

19
src/structure.c Normal file
View File

@ -0,0 +1,19 @@
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#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;

View File

@ -11,7 +11,6 @@ typedef struct imgs {
// ------------------------------------------------------------------------ // // ------------------------------------------------------------------------ //
// car shenanigans // car shenanigans
typedef struct pt_t {int ix; int iy;} pt; typedef struct pt_t {int ix; int iy;} pt;
typedef struct ptf_t {double fx; double fy;} ptf; typedef struct ptf_t {double fx; double fy;} ptf;
@ -26,9 +25,7 @@ typedef struct item_t {
} item; } item;
typedef struct car_t { typedef struct car_t {
const char* name; ptf pos; // remains in [0, ROOM_SIZE[
ptf pos;
int size;
ptf vel; ptf vel;
int nCoins; int nCoins;
item* itm; // either NULL or a pointer to an item item* itm; // either NULL or a pointer to an item
@ -42,53 +39,23 @@ typedef struct color_t {
uint8_t blue; uint8_t blue;
} color; } color;
// 2 types of objects : rectangles and circles // one chunk
typedef struct rectangle_t { typedef enum road_t {NONE, START, END, STR_V, STR_H, TURN_NE, TURN_SE, TURN_SW, TURN_NW} road;
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;
typedef struct circle_t { typedef struct level_t {
int x; pt start;
int y; pt end;
int r; int lines;
color rgb; int cols;
double restitution; road** map;
void (*onHit)(struct circle_t * self, car* bonk); } level;
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;
// global car data // global car data
typedef struct carData_t { typedef struct carData_t {
car* c; car* c;
chunk* curChunk; color rgb;
int chx;
int chy;
} carData; } carData;
// ------------------------------------------------------------------------ // // ------------------------------------------------------------------------ //
@ -97,10 +64,23 @@ extern imgs* letters; // SDL data
extern int currentTurn; // name explains 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 carData* players; // contains each player and its corresponding data
extern int nPlayers; // size of players 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 #endif