commit 6640b9d402fb48924c6db5414c24ed9ee4de85c8 Author: Alexandre Date: Tue May 13 22:06:00 2025 +0200 E+EE+EEE diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..bb9079a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "sdl.h": "c", + "assert.h": "c", + "display.h": "c", + "structure.h": "c", + "limits": "c", + "base.h": "c", + "cars.h": "c" + } +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4c154f6 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +CC = gcc +FLAGS = -Wall -Wextra -g +LFLAGS = -lSDL2 -lSDL2_image -lm + +all: bin/back + +test: bin/back + 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 + mkdir -p bin + $(CC) $(FLAGS) $^ $(LFLAGS) -o $@ + +obj/%.o: src/%.c + @mkdir -p obj + $(CC) -o $@ -c $(FLAGS) $< + +obj/main.o: src/main.c +obj/display.o: src/display.c +obj/base.o: src/base.c +obj/cars.o: src/cars.c +obj/rooms.o: src/rooms.c + +.PHONY: clean mrproper + +clean: + rm -rf obj/ + +mrproper: clean + rm -rf bin/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..60a41d0 --- /dev/null +++ b/README.md @@ -0,0 +1,152 @@ +# --| Controls |-- +- in-game: +**WASD/ZQSD** (depends on keyboard, usually WASD) - movement +**QE/AE** (depends on keyboard, usually QE)- horizontal camera rotation +**PM** - vertical camera rotation +**ESC** - exit application + +- creative tools: +**Y** select level destination +**R** warp to targetted level (resets player's position) +**T** warp to targetted level (no update top player's position) + +- while in menus: + when editing a value : **A** (add), **S** (subtract), **M** (multiply), **D** (divide), **ENTER/SPACE** (proceed) + +# --| Mods (in case you find it easy) |-- + +*Hidden* (HD) : makes the terrain blink to be totally invisible sometimes +*HardRock* (HR) : multiplies damage taken, enables fall damage and kills you upon falling into the void +*DoubleTime* (DT) : makes everything faster +*SuddenDeath* (SD) : sets your HP at 1 and disables healing +*Flashlight* (FL) : drastically lowers your view distance +*Speedy* (SP) : makes you lose HP over time +*Flip* (FP) : flips the screen over the Y axis, inverting some directions + +# --| Syntax for level files |-- + +1) **General rules** +. each file must be named "room_k" where k is a positive integer + if "room_k" exists then all "room_u" where 0 <= u < k exists + +. you can add text at the end of each line as comments + but *do not use caps*, *this might confuse the parser* + +. at the end of each file, the weight of the room is required (can be any positive integer) + if **there is only one file (==> its name is room_0) AND weight is 0**, the room will only generate at the central chunk (any other will be NULL) + use this if you want to create parkour levels, puzzles... + else, **make sure the total weight (the sum of all) is not equal to 0** *(you may end up with a floating point exception)* + +. no matter what, room_0 will **always** generate at chunk (0, 0) + +2) **Data structure** +below is a detailled list for all block types ; +each block type (Blocks, Teleporters, Entities) must have the corresponding word directly above it +not all three keywords have to be written + +[] is mandatory data +{} is optionnal data + +*Data-specific structure :* +``` +blocks: + [x, y, z, w, h, d, rhz, rvt, r, g, b] + +teleporters: + [x, y, z, w, h, d, rhz, rvt, r, g, b, dest_chx, dest_chy] + +entities: + [x, y, z, w, h, d, rhz, rvt, r, g, b, hp, damage, entityType ..] + + + |> if entityType >= 4, use 1 for HP and 0 for damage <| + |> *Entity types are :* <| + + -> 0 (coin) -> HP equals the coin's value + -> 1 (non-moving explosive) + -> 2 (damaging firebar/spinning platform (set damage to 0)) + [.. hz_rps, vt_rps, x_offset, y_offset, z_offset, dps] with + {hz,vt}_rps = double + hz0, vt_0 = double + {x,y,z}_offset = double // if all is 0.0, the solid will rotate according to its center of mass, this shifts that center + dps = int[>0] + + -> 3 (shooting (towards player), maybe moving explosive) + [.. proj_speed, shoot_speed, shot_freq, shot_ttl] with + {all} = double[>= 0.0] + + -> 4 (moving platform) + [.. amplitude_x, amplitude_y, amplitude_z, mult, divd, phase, {initialState, triggerButton}] with + amplitude_{x,y,z} = double[>= 0.0] + {mult,divd} = int + {phase} = int[0, 360] + {..} = int(>=0) + + -> 5 (linear moving platform) + [.. amplitude_x, amplitude_y, amplitude_z, speed_x, speed_y, speed_z, {initialState, triggerButton}] with + amplitude_{x,y,z} = double[>= 0.0] + speed_{x,y,z} = double + {..} = int(>=0) + + -> 6 (text box) + [.. text, tred, tgreen, tblue] with + text = {char*} + + -> 7 (warp text box) + [.. dest_folder, room_count, text, tred, tgreen, tblue] with + {dest_folder,text} = {char*} (length <= 50) + {r,g,b} = int[0-256] + + + -> 8 (lock box) + [.. cost, doPay, tred, tgreen, tblue] with + cost = int[> 0] (0 breaks) + doPay = {0, 1} (bool) + + -> 9 (beat block) + [.. ontime, offtime, start] with + {ontime,offtime} = double[>0.0] + start = {0,1} + + -> 10 (movable block) + [.. friction, mass] with + friction = double[>0.0] + mass = double[>0.0] (in kg) + + -> 11 (button trigger) + [.. freq, dtime] with + freq = int[0 - 15] + dtime = double([>0.0] for time-limited press, or use -1.0 if no deactivation) + + -> 12 (button block) + [.. freq, defaultState] with + freq = int[0 - 15] + defaultState = {0, 1} + + -> 13 (math block) + [.. defaultState, timeOff] with + defaultState = {0, 1} + dtime = double([>0.0] for time-limited press, or use -1.0 if no deactivation) + + -> 14 (movable object-related button) + [.. freq] with + freq = int[0 - 15] + + -> 15 (gun) + [.. vx, vy, vz, ax, ay, az, cooldown, phase, ttl, dmg, psize_x, psize_y, psize_z] with + all\{dmg} = double (cooldown > 0.0 and ttl > 0.0 and psize_{x,y,z} > 0.0) + dmg = int (>0) + + -> 16 (type 1 entity) + [.. speed, jump_height, dmg, kbPlayer, {buttonActivation}] with + all\{dmg} = double[>=0.0] + dmg = int (>=0) + buttonActivation = int[0-16] + + -> 17 (type 2 entity) + [.. speed, jump_height, dmg, kbPlayer, kbEntity, {buttonActivation}] with + all\{dmg} = double[>=0.0] + dmg = int (>=0) + buttonActivation = int[0-16] + +``` \ No newline at end of file diff --git a/bin/back b/bin/back new file mode 100755 index 0000000..0f0ee94 Binary files /dev/null and b/bin/back differ diff --git a/code b/code new file mode 100644 index 0000000..e69de29 diff --git a/obj/base.o b/obj/base.o new file mode 100644 index 0000000..e9509e0 Binary files /dev/null and b/obj/base.o differ diff --git a/obj/cars.o b/obj/cars.o new file mode 100644 index 0000000..60671b2 Binary files /dev/null and b/obj/cars.o differ diff --git a/obj/display.o b/obj/display.o new file mode 100644 index 0000000..85f7eaa Binary files /dev/null and b/obj/display.o differ diff --git a/obj/main.o b/obj/main.o new file mode 100644 index 0000000..e11486a Binary files /dev/null and b/obj/main.o differ diff --git a/obj/rooms.o b/obj/rooms.o new file mode 100644 index 0000000..356cc1e Binary files /dev/null and b/obj/rooms.o differ diff --git a/res/arrows.png b/res/arrows.png new file mode 100644 index 0000000..1771d4a Binary files /dev/null and b/res/arrows.png differ diff --git a/res/brick.jpeg b/res/brick.jpeg new file mode 100644 index 0000000..9e2747f Binary files /dev/null and b/res/brick.jpeg differ diff --git a/res/brick.png b/res/brick.png new file mode 100644 index 0000000..02a5481 Binary files /dev/null and b/res/brick.png differ diff --git a/res/button_off.jpg b/res/button_off.jpg new file mode 100644 index 0000000..7afe72d Binary files /dev/null and b/res/button_off.jpg differ diff --git a/res/button_on.png b/res/button_on.png new file mode 100644 index 0000000..281aa53 Binary files /dev/null and b/res/button_on.png differ diff --git a/res/coin2.png b/res/coin2.png new file mode 100644 index 0000000..4f3089c Binary files /dev/null and b/res/coin2.png differ diff --git a/res/container.jpg b/res/container.jpg new file mode 100644 index 0000000..d07bee4 Binary files /dev/null and b/res/container.jpg differ diff --git a/res/exclamation_block.png b/res/exclamation_block.png new file mode 100644 index 0000000..a422303 Binary files /dev/null and b/res/exclamation_block.png differ diff --git a/res/gateway.jpeg b/res/gateway.jpeg new file mode 100644 index 0000000..fb81d68 Binary files /dev/null and b/res/gateway.jpeg differ diff --git a/res/lock.jpg b/res/lock.jpg new file mode 100644 index 0000000..114280a Binary files /dev/null and b/res/lock.jpg differ diff --git a/res/lock.png b/res/lock.png new file mode 100644 index 0000000..2e87321 Binary files /dev/null and b/res/lock.png differ diff --git a/res/minecraft_lava.jpg b/res/minecraft_lava.jpg new file mode 100644 index 0000000..5c99402 Binary files /dev/null and b/res/minecraft_lava.jpg differ diff --git a/res/money.png b/res/money.png new file mode 100644 index 0000000..f8e80ba Binary files /dev/null and b/res/money.png differ diff --git a/res/pi.jpeg b/res/pi.jpeg new file mode 100644 index 0000000..1eed52b Binary files /dev/null and b/res/pi.jpeg differ diff --git a/res/pi.png b/res/pi.png new file mode 100644 index 0000000..4cf3fae Binary files /dev/null and b/res/pi.png differ diff --git a/res/question_block.png b/res/question_block.png new file mode 100644 index 0000000..1ec52ba Binary files /dev/null and b/res/question_block.png differ diff --git a/res/rotation.png b/res/rotation.png new file mode 100644 index 0000000..fdf3176 Binary files /dev/null and b/res/rotation.png differ diff --git a/res/selection-mod-doubletime.png b/res/selection-mod-doubletime.png new file mode 100644 index 0000000..5f23c09 Binary files /dev/null and b/res/selection-mod-doubletime.png differ diff --git a/res/selection-mod-flashlight.png b/res/selection-mod-flashlight.png new file mode 100644 index 0000000..a7c0ac0 Binary files /dev/null and b/res/selection-mod-flashlight.png differ diff --git a/res/selection-mod-hardrock.png b/res/selection-mod-hardrock.png new file mode 100644 index 0000000..e226aeb Binary files /dev/null and b/res/selection-mod-hardrock.png differ diff --git a/res/selection-mod-suddendeath.png b/res/selection-mod-suddendeath.png new file mode 100644 index 0000000..88c5572 Binary files /dev/null and b/res/selection-mod-suddendeath.png differ diff --git a/res/sq_dotted.png b/res/sq_dotted.png new file mode 100644 index 0000000..3407548 Binary files /dev/null and b/res/sq_dotted.png differ diff --git a/res/sq_full.png b/res/sq_full.png new file mode 100644 index 0000000..25c1dfe Binary files /dev/null and b/res/sq_full.png differ diff --git a/res/steel.jpeg b/res/steel.jpeg new file mode 100644 index 0000000..197e348 Binary files /dev/null and b/res/steel.jpeg differ diff --git a/res/tnt.png b/res/tnt.png new file mode 100644 index 0000000..4b82ae7 Binary files /dev/null and b/res/tnt.png differ diff --git a/res/white.png b/res/white.png new file mode 100644 index 0000000..009abfc Binary files /dev/null and b/res/white.png differ diff --git a/src/base.c b/src/base.c new file mode 100644 index 0000000..e0b018d --- /dev/null +++ b/src/base.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "structure.h" +#include "cars.h" +#include "base.h" + +int currentTurn; +int nPlayers; +carData* players; + +void init_all(int nPl) { + nPlayers = 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"); + } +} + +void destroy_all() { + for(int p = 0; p < nPlayers; p++) { + destroy_car(players[p].c); + } + free(players); +} + +int ln_baseN(int n, int b) { + if(nb)?(a):(b);} +int min(int a, int b) {return (a +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "structure.h" +#include "base.h" +#include "cars.h" + +car* init_car(const char* name) { + car* res = malloc(sizeof(car)); + res->name = "e"; + res->itm = NULL; + res->nCoins = 0; + res->pos = (ptf){.fx = 0.0, .fy = 0.0}; + res->vel = (ptf){.fx = 0.0, .fy = 0.0}; + return res; +} + +void move_car(car* c, double x, double y) { + c->pos.fx = x; + c->pos.fy = y; +} + +void set_speed_car(car* c, double vx, double vy) { + c->vel.fx = vx; + c->vel.fy = vy; +} + +void destroy_car(car* c) { + free(c); +} \ No newline at end of file diff --git a/src/cars.h b/src/cars.h new file mode 100644 index 0000000..36a0a39 --- /dev/null +++ b/src/cars.h @@ -0,0 +1,10 @@ +#ifndef CARS_H +#define CARS_H + +car* init_car(const char* name); +void destroy_car(car* c); + +void move_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 new file mode 100644 index 0000000..df9431f --- /dev/null +++ b/src/display.c @@ -0,0 +1,547 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "structure.h" +#include "base.h" +#include "display.h" + +imgs* digits; +imgs* letters; + +void updateRenderer(SDL_Renderer* renderer) { + //printf("E"); + SDL_RenderPresent(renderer); +} + +void resetRenderer(SDL_Renderer* renderer) { + SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255); + SDL_RenderClear(renderer); +} + +void drawRectToRenderer(SDL_Renderer* renderer, SDL_Rect* rect, int R, int G, int B, int A) { + SDL_SetRenderDrawColor(renderer, R, G, B, A); + SDL_RenderFillRect(renderer, rect); +} + +void placeRectToRenderer(SDL_Renderer* renderer, int X, int Y, int W, int H, int R, int G, int B, int A) { + SDL_Rect rect; + rect.x = X; + rect.y = Y; + rect.w = W; + rect.h = H; + SDL_SetRenderDrawColor(renderer, R, G, B, A); + SDL_RenderFillRect(renderer, &rect); +} + +void drawLineWithThicc(SDL_Renderer* renderer, int width, int x1, int x2, int y1, int y2, int R, int G, int B, int A) { + // draws line with width (native SDL cannot do that) + double theta = 0.0; + double seglen = distance_pt(x1, x2, y1, y2); + while(theta < 1.0) { + placeRectToRenderer(renderer, convex_seg(x1, x2, theta)-width/2, convex_seg(y1, y2, theta)-width/2, width, width, R, G, B, A); + theta += 1 / seglen; + } +} + +void drawDigitToRenderer(SDL_Renderer* renderer, int digit, int X, int Y, int W, int H) { + if(digit == -727) { + SDL_Rect rect; + rect.x = X; + rect.y = Y; + rect.w = W; + rect.h = H; + + SDL_Texture* texture = digits->arr[10]; + + SDL_RenderCopy(renderer, texture, NULL, &rect); + } else if (!(0 <= digit && digit <= 9)) { + fprintf(stderr, "Illegal digit : '%d'.\n", digit); + exit(1); + } else { + SDL_Rect rect; + rect.x = X; + rect.y = Y; + rect.w = W; + rect.h = H; + + SDL_Texture* texture = digits->arr[digit]; + + SDL_RenderCopy(renderer, texture, NULL, &rect); + } +} + +void drawCharToRenderer(SDL_Renderer* renderer, char c, int X, int Y, int W, int H) { + if ((int)c >= 97 && (int)c <= 122) { + SDL_Rect rect; + rect.x = X; + rect.y = Y; + rect.w = W; + rect.h = H; + + SDL_Texture* texture = letters->arr[(int)c - 97]; + + SDL_RenderCopy(renderer, texture, NULL, &rect); + } +} + +void drawNumberToRenderer(SDL_Renderer* renderer, int n, int X, int Y, int W, int H, int Woffset) { + if(n == 0) { + drawDigitToRenderer(renderer, 0, X + W, Y, W, H); + } else if(n > 0) { + int toDraw = 0, remaining = n, nIter = notLN(n, 10); + while(nIter != 0) { + toDraw = remaining%10; + remaining = remaining / 10; + drawDigitToRenderer(renderer, toDraw, X + (W-Woffset)*nIter, Y, W, H); + nIter--; + } + } else { + int toDraw = 0, remaining = -n, nIter = notLN(-n, 10); + drawDigitToRenderer(renderer, -727, X, Y, W, H); + while(nIter != 0) { + toDraw = remaining%10; + remaining = remaining / 10; + drawDigitToRenderer(renderer, toDraw, X + (W-Woffset)*nIter, Y, W, H); + nIter--; + } + } +} + +void drawStringToRenderer(SDL_Renderer* renderer, char* s, int X, int Y, int W, int H) { + int k = 0; + while(s[k] != '\0') { + drawCharToRenderer(renderer, s[k], X + W*k, Y, W, H); + k += 1; + } +} + +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) { + if(n == 0) { + placeRectToRenderer(renderer, X+thicc, Y+thicc, W+thicc, thicc, R, G, B, A); // top + placeRectToRenderer(renderer, X+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top left + placeRectToRenderer(renderer, X+W+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top right + placeRectToRenderer(renderer, X+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom left + placeRectToRenderer(renderer, X+W+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom right + placeRectToRenderer(renderer, X+thicc, Y+2*H+thicc, W+thicc, thicc, R, G, B, A); // bottom + } else if(n == 1) { + placeRectToRenderer(renderer, X+W+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top right + placeRectToRenderer(renderer, X+W+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom right + } else if(n == 2) { + placeRectToRenderer(renderer, X+thicc, Y+thicc, W+thicc, thicc, R, G, B, A); // top + placeRectToRenderer(renderer, X+W+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top right + placeRectToRenderer(renderer, X+thicc, Y+H+thicc, W+thicc, thicc, R, G, B, A); // mid + placeRectToRenderer(renderer, X+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom left + placeRectToRenderer(renderer, X+thicc, Y+2*H+thicc, W+thicc, thicc, R, G, B, A); // bottom + } else if(n == 3) { + placeRectToRenderer(renderer, X+thicc, Y+thicc, W+thicc, thicc, R, G, B, A); // top + placeRectToRenderer(renderer, X+W+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top right + placeRectToRenderer(renderer, X+thicc, Y+H+thicc, W+thicc, thicc, R, G, B, A); // mid + placeRectToRenderer(renderer, X+W+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom right + placeRectToRenderer(renderer, X+thicc, Y+2*H+thicc, W+thicc, thicc, R, G, B, A); // bottom + } else if(n == 4) { + placeRectToRenderer(renderer, X+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top left + placeRectToRenderer(renderer, X+W+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top right + placeRectToRenderer(renderer, X+thicc, Y+H+thicc, W+thicc, thicc, R, G, B, A); // mid + placeRectToRenderer(renderer, X+W+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom right + } else if(n == 5) { + placeRectToRenderer(renderer, X+thicc, Y+thicc, W+thicc, thicc, R, G, B, A); // top + placeRectToRenderer(renderer, X+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top left + placeRectToRenderer(renderer, X+thicc, Y+H+thicc, W+thicc, thicc, R, G, B, A); // mid + placeRectToRenderer(renderer, X+W+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom right + placeRectToRenderer(renderer, X+thicc, Y+2*H+thicc, W+thicc, thicc, R, G, B, A); // bottom + } else if(n == 6) { + placeRectToRenderer(renderer, X+thicc, Y+thicc, W+thicc, thicc, R, G, B, A); // top + placeRectToRenderer(renderer, X+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top left + placeRectToRenderer(renderer, X+thicc, Y+H+thicc, W+thicc, thicc, R, G, B, A); // mid + placeRectToRenderer(renderer, X+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom left + placeRectToRenderer(renderer, X+W+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom right + placeRectToRenderer(renderer, X+thicc, Y+2*H+thicc, W+thicc, thicc, R, G, B, A); // bottom + } else if(n == 7) { + placeRectToRenderer(renderer, X+thicc, Y+thicc, W+thicc, thicc, R, G, B, A); // top + placeRectToRenderer(renderer, X+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top left + placeRectToRenderer(renderer, X+W+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top right + placeRectToRenderer(renderer, X+W+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom right + } else if(n == 8) { + placeRectToRenderer(renderer, X+thicc, Y+thicc, W+thicc, thicc, R, G, B, A); // top + placeRectToRenderer(renderer, X+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top left + placeRectToRenderer(renderer, X+W+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top right + placeRectToRenderer(renderer, X+thicc, Y+H+thicc, W+thicc, thicc, R, G, B, A); // mid + placeRectToRenderer(renderer, X+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom left + placeRectToRenderer(renderer, X+W+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom right + placeRectToRenderer(renderer, X+thicc, Y+2*H+thicc, W+thicc, thicc, R, G, B, A); // bottom + } else if(n == 9) { + placeRectToRenderer(renderer, X+thicc, Y+thicc, W+thicc, thicc, R, G, B, A); // top + placeRectToRenderer(renderer, X+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top left + placeRectToRenderer(renderer, X+W+thicc, Y+thicc, thicc, H+thicc, R, G, B, A); // top right + placeRectToRenderer(renderer, X+thicc, Y+H+thicc, W+thicc, thicc, R, G, B, A); // mid + placeRectToRenderer(renderer, X+W+thicc, Y+H+thicc, thicc, H+thicc, R, G, B, A); // bottom right + placeRectToRenderer(renderer, X+thicc, Y+2*H+thicc, W+thicc, thicc, R, G, B, A); // bottom + } +} + +// H = size of ont segment (therefore the actual size of the number is W x 2H) +// side is -1 (alignedLeft), 0 (centered) or 1 (alignedRight) +// dot if for placing a dot (for decimals) at a specified place (enter -1 if none) +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) { + int nlen = 1+ln_baseN(n, 10); + int incrX = W+3*thicc; + int curX = X +(side==0)*(incrX*(nlen)/2-incrX) +(side==-1)*incrX*(nlen-1); + int curN = n; + int doot = (dot==-1)?(nlen+1):(nlen-(dot-1)); + while(nlen > 0) { + draw7SegDigitToRenderer(renderer, curN%10, curX, Y, W, H, thicc, R, G, B, A); + curX -= incrX; + if(nlen == doot) { + placeRectToRenderer(renderer, curX-2*thicc+incrX, Y+2*H, 2*thicc, 2*thicc, R, G, B, A); + curX -= 6*thicc; + } + curN /= 10; + nlen -= 1; + } +} +//---------------------------------------------------------------------------------------------------------------------// +// 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) { + int offsetx, offsety, d; + int status; + + offsetx = 0; + offsety = radius; + d = radius -1; + status = 0; + + while (offsety >= offsetx) { + status += SDL_RenderDrawPoint(renderer, x + offsetx, y + offsety); + status += SDL_RenderDrawPoint(renderer, x + offsety, y + offsetx); + status += SDL_RenderDrawPoint(renderer, x - offsetx, y + offsety); + status += SDL_RenderDrawPoint(renderer, x - offsety, y + offsetx); + status += SDL_RenderDrawPoint(renderer, x + offsetx, y - offsety); + status += SDL_RenderDrawPoint(renderer, x + offsety, y - offsetx); + status += SDL_RenderDrawPoint(renderer, x - offsetx, y - offsety); + status += SDL_RenderDrawPoint(renderer, x - offsety, y - offsetx); + + if (status < 0) { + status = -1; + break; + } + + if (d >= 2*offsetx) { + d -= 2*offsetx + 1; + offsetx +=1; + } else if (d < 2 * (radius - offsety)) { + d += 2 * offsety - 1; + offsety -= 1; + } else { + d += 2 * (offsety - offsetx - 1); + offsety -= 1; + offsetx += 1; + } + } + + //return status; +} + + +void SDL_RenderFillCircle(SDL_Renderer * renderer, int x, int y, int radius) { + int offsetx, offsety, d; + int status; + + offsetx = 0; + offsety = radius; + d = radius -1; + status = 0; + + while (offsety >= offsetx) { + + status += SDL_RenderDrawLine(renderer, x - offsety, y + offsetx, + x + offsety, y + offsetx); + status += SDL_RenderDrawLine(renderer, x - offsetx, y + offsety, + x + offsetx, y + offsety); + status += SDL_RenderDrawLine(renderer, x - offsetx, y - offsety, + x + offsetx, y - offsety); + status += SDL_RenderDrawLine(renderer, x - offsety, y - offsetx, + x + offsety, y - offsetx); + + if (status < 0) { + status = -1; + break; + } + + if (d >= 2*offsetx) { + d -= 2*offsetx + 1; + offsetx +=1; + } else if (d < 2 * (radius - offsety)) { + d += 2 * offsety - 1; + offsety -= 1; + } else { + d += 2 * (offsety - offsetx - 1); + offsety -= 1; + offsetx += 1; + } + } + //return status; +} + +// ------------------------------------------------------------------------------------------------------------------------- // + +void import_digits(SDL_Renderer* renderer) { + imgs* res = malloc(sizeof(imgs)); + res->arr = malloc(sizeof(SDL_Texture*)*11); + SDL_Texture* texture; + SDL_Surface* img; + + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/digits/digit-0.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[0] = texture; + + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/digits/digit-1.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[1] = texture; + + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/digits/digit-2.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[2] = texture; + + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/digits/digit-3.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[3] = texture; + + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/digits/digit-4.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[4] = texture; + + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/digits/digit-5.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[5] = texture; + + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/digits/digit-6.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[6] = texture; + + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/digits/digit-7.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[7] = texture; + + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/digits/digit-8.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[8] = texture; + + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/digits/digit-9.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[9] = texture; + + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/digits/sign-minus.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[10] = texture; + + res->len = 11; + digits = res; +} +void import_letters(SDL_Renderer* renderer) { + imgs* res = malloc(sizeof(imgs)); + res->arr = malloc(sizeof(SDL_Texture*)*26); + SDL_Texture* texture; + SDL_Surface* img; + + int cc = 0; + + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-a.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-b.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-c.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-d.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-e.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-f.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-g.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-h.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-i.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-j.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-k.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-l.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-m.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-n.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-o.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-p.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-q.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-r.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-s.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-t.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-u.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-v.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-w.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-x.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-y.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + cc += 1; + // -------------------------------------------------------- // + img = SDL_LoadBMP("./res/letters/letter-z.bmp"); + texture = SDL_CreateTextureFromSurface(renderer, img); + SDL_FreeSurface(img); + res->arr[cc] = texture; + + res->len = 26; + letters = res; +} + +void free_digits(imgs* dgts) { + for(int i = 0; i < dgts->len; i++) { + SDL_DestroyTexture(dgts->arr[i]); + } + free(dgts->arr); + free(dgts); +} \ No newline at end of file diff --git a/src/display.h b/src/display.h new file mode 100644 index 0000000..fa04f9b --- /dev/null +++ b/src/display.h @@ -0,0 +1,22 @@ +#ifndef DISPLAY_H +#define DISPLAY_H + +void updateRenderer(SDL_Renderer* renderer); +void resetRenderer(SDL_Renderer* renderer); +void drawRectToRenderer(SDL_Renderer* renderer, SDL_Rect* rect, int R, int G, int B, int A); +void placeRectToRenderer(SDL_Renderer* renderer, int X, int Y, int W, int H, int R, int G, int B, int A); +void drawLineWithThicc(SDL_Renderer* renderer, int width, int x1, int x2, int y1, int y2, int R, int G, int B, int A); +void drawDigitToRenderer(SDL_Renderer* renderer, int digit, int X, int Y, int W, int H); +void drawCharToRenderer(SDL_Renderer* renderer, char c, int X, int Y, int W, int H); +void drawNumberToRenderer(SDL_Renderer* renderer, int n, int X, int Y, int W, int H, int Woffset); +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 import_digits(SDL_Renderer* renderer); +void import_letters(SDL_Renderer* renderer); +void free_digits(imgs* dgts); + +#endif \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..988a4f7 --- /dev/null +++ b/src/main.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "structure.h" +#include "base.h" +#include "display.h" +#include "rooms.h" +#include "cars.h" + +const int WIDTH = 1000; +const int HEIGHT = 800; + +const int N_PLAYERS = 4; + +int main() { + srand(time(NULL)); + if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { + printf("error initializing SDL: %s\n", SDL_GetError()); + } + SDL_Window* win = SDL_CreateWindow("Game", + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + WIDTH, HEIGHT, 0); + + Uint32 render_flags = SDL_RENDERER_ACCELERATED; + SDL_Renderer* rend = SDL_CreateRenderer(win, -1, render_flags); + SDL_SetRenderDrawBlendMode(rend, SDL_BLENDMODE_BLEND); + + import_letters(rend); + import_digits(rend); + init_rooms(); + init_all(N_PLAYERS); + // ---------------------------- // + + + usleep(1000000); + // ---------------------------- // + free_digits(digits); + free_digits(letters); + destroy_rooms(); + + SDL_DestroyRenderer(rend); + SDL_DestroyWindow(win); + SDL_Quit(); + return 0; +} + +/* TODO : + - add display + - add collisions + - add level parsing/generation + - add player input parsing (and some dumb code to test it) + - add function that gives players the necessary data to play + - check seg faults + + add items + + add hazards +*/ \ No newline at end of file diff --git a/src/rooms.c b/src/rooms.c new file mode 100644 index 0000000..f7c6348 --- /dev/null +++ b/src/rooms.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "structure.h" +#include "base.h" +#include "rooms.h" + +chunk* start; +chunk** allRooms; +int nMaxRooms; +int curRoom; + +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; + + 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); + } +} + +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 destroy_rooms() { + for(int r = 0; r < curRoom; r++) { + free(allRooms[r]->circles); + free(allRooms[r]->rects); + free(allRooms[r]); + } + free(allRooms); +} \ No newline at end of file diff --git a/src/rooms.h b/src/rooms.h new file mode 100644 index 0000000..14ff590 --- /dev/null +++ b/src/rooms.h @@ -0,0 +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 init_rooms(); +void destroy_rooms(); + +#endif \ No newline at end of file diff --git a/src/structure.h b/src/structure.h new file mode 100644 index 0000000..40d88d6 --- /dev/null +++ b/src/structure.h @@ -0,0 +1,106 @@ +#ifndef CONSTS_H +#define CONSTS_H + +// ------------------------------------------------------------------------ // +// SDL-related struct + +typedef struct imgs { + int len; + SDL_Texture** arr; +} imgs; + +// ------------------------------------------------------------------------ // +// car shenanigans + +typedef struct pt_t { + int ix; + int iy; +} pt; + +typedef struct ptf_t { + double fx; + double fy; +} ptf; + +typedef struct car_t car; +// unused for now +typedef struct item_t { + const char* name; + void (*onCollect)(car* user); + void (*onUse)(car* user); +} item; + +typedef struct car_t { + const char* name; + ptf pos; + ptf vel; + int nCoins; + item* itm; // either NULL or a pointer to an item +} car; + +// ------------------------------------------------------------------------ // +// (take a) map +typedef struct color_t { + uint8_t red; + uint8_t green; + uint8_t blue; +} color; + +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; + +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; + + int chW; + int chH; + + // absolute coords + int chX; + int chY; + struct chunk_t* north; + struct chunk_t* east; + struct chunk_t* south; + struct chunk_t* west; +} chunk; + +// global car data here +typedef struct carData_t { + car* c; + chunk* curChunk; +} carData; + +// ------------------------------------------------------------------------ // +extern imgs* digits; +extern imgs* letters; + +extern int currentTurn; + +extern chunk* start; +extern chunk** allRooms; +extern int nMaxRooms; +extern carData* players; +extern int nPlayers; + +#endif \ No newline at end of file