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",
"limits": "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
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

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;
players = malloc(sizeof(carData)*nPlayers);
for(int p = 0; p < nPlayers; p++) {
players[p].curChunk = start;
players[p].c = init_car("player");
}
}

View File

@ -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);
}
}
// ------------------------------------------------------------ //

View File

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

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) //
//---------------------------------------------------------------------------------------------------------------------//
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);

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 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);

View File

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

View File

@ -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);
}

View File

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

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