From 9d7549e57b25dfe8fcfaa74967b0611c81513f8f Mon Sep 17 00:00:00 2001 From: KikooDX Date: Fri, 11 Jun 2021 01:32:47 +0200 Subject: [PATCH] engine base --- .clang-format | 9 +++++++ .gitignore | 5 ++++ CMakeLists.txt | 45 ++++++++++++++++++++++++++++++++++ assets/graphics/icon-sel.png | Bin 0 -> 2444 bytes assets/graphics/icon-uns.png | Bin 0 -> 593 bytes include/entity.h | 22 +++++++++++++++++ include/player.h | 12 +++++++++ include/tiles.h | 7 ++++++ include/wall.h | 8 ++++++ src/entity/collide.c | 34 ++++++++++++++++++++++++++ src/entity/draw_hitbox.c | 23 ++++++++++++++++++ src/entity/init.c | 46 +++++++++++++++++++++++++++++++++++ src/main.c | 36 +++++++++++++++++++++++++++ src/player/init.c | 12 +++++++++ src/wall/init.c | 8 ++++++ 15 files changed, 267 insertions(+) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 assets/graphics/icon-sel.png create mode 100644 assets/graphics/icon-uns.png create mode 100644 include/entity.h create mode 100644 include/player.h create mode 100644 include/tiles.h create mode 100644 include/wall.h create mode 100644 src/entity/collide.c create mode 100644 src/entity/draw_hitbox.c create mode 100644 src/entity/init.c create mode 100644 src/main.c create mode 100644 src/player/init.c create mode 100644 src/wall/init.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..57fd90a --- /dev/null +++ b/.clang-format @@ -0,0 +1,9 @@ +BasedOnStyle: LLVM +IndentWidth: 8 +UseTab: AlignWithSpaces +BreakBeforeBraces: Linux +AllowShortIfStatementsOnASingleLine: false +IndentCaseLabels: false +ColumnLimit: 80 +AlignConsecutiveMacros: true +AlwaysBreakAfterReturnType: TopLevelDefinitions diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f867ea7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build-cg/ +build-fx/ +*.g3a +CMakeLists.txt~ +*.png~ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4842738 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,45 @@ +# Configure with [fxsdk build-fx] or [fxsdk build-cg], which provide the +# toolchain file and module path of the fxSDK + +cmake_minimum_required(VERSION 3.18) +project(RC C) + +include(GenerateG3A) +include(Fxconv) + +find_package(Gint 2.5.3 REQUIRED) +find_package(LibImg 2.4.0 REQUIRED) + +include_directories(include) + +set(SOURCES + src/main.c + src/entity/collide.c + src/entity/draw_hitbox.c + src/entity/init.c + src/wall/init.c + src/player/init.c +) + +set(ASSETS +) + +set(FLAGS + -Wall -Wextra -Wshadow -Wswitch-default -Wswitch-enum + -Wunreachable-code -Wstrict-prototypes -Wmissing-prototypes + -Wold-style-definition -Werror-implicit-function-declaration + -fms-extensions -std=c99 -O3 +) + +fxconv_declare_assets(${ASSETS} WITH_METADATA) + +add_executable(${PROJECT_NAME} ${SOURCES} ${ASSETS}) +target_compile_options(${PROJECT_NAME} PRIVATE ${FLAGS}) +target_link_libraries(${PROJECT_NAME} Gint::Gint) +target_link_libraries(${PROJECT_NAME} LibImg::LibImg) +target_link_options(${PROJECT_NAME} PRIVATE -Wl,-Map=map) + +generate_g3a(TARGET ${PROJECT_NAME} + OUTPUT "${PROJECT_NAME}.g3a" + NAME "${PROJECT_NAME}" + ICONS assets/graphics/icon-uns.png assets/graphics/icon-sel.png) diff --git a/assets/graphics/icon-sel.png b/assets/graphics/icon-sel.png new file mode 100644 index 0000000000000000000000000000000000000000..e37d12432dc65002d2d04424e4a229e414e6c05f GIT binary patch literal 2444 zcmV;733K*|P)oES7Evus;YU; zbBBYTG5dx!p9pJyas;P`@cb({IfR4%>fN7T;L~-uB(%?FFj`d)KyelZNUx4g@)-$S zT3+EA;-n0a-Xg5hnBfeTHqD^ZgX8fL{QM0Z{PB7B&vn>dC?QfBY(QlAvr=SOnjoDN z2L>AKkyAN$dLw=-oOgr^*d=x%B9|8)-#>!YhwHd{AS@sw;>)XJ7r8&y4xlq7S}wFCQx~Fp`4IwR6mI z3y;D5pR`(Ko;;@z78#e`75D@Gn`N))1G7^JjYf-{icVvFFnQeBo9f184=x;pk0G92 z5+@8Oe5JrC!liNJE{}1Umuu$&#jI`Aur6PI!zp7-vf=QBjK$rWGiHxQQnK6DL9{dO z;TR#mIW%U3kpnWHdJNW>!V?OVZ`qGndhn@EEk!&lijO1F-apHFoBn}=2*o;jZiU3c z?Rm80FOnuDjh0L|6{F(fvq!5EOT9}p9_{RI-=y|9PYI5cFj+fEv>i_U zO~igi<85|j?=jn7Jf^F5kyh3qlcTr@?ae;sa@LSUWJP(lK|keQ1wKmvjfrd>P?QYA zse}7tIG2(UXysF2nIzLvxsQpOH9Rbq@+lND-+`ktH=#%)Jpp1J`@|@D&`-Hnytt4q zizwL*6YWhRl%+$bS@h9n-Ub802gUmMAq9j(^*wF5og|z+ zQZ4Uq+8JGHOMVam(SEnV zm}WVjvMLwG-AhE4Hcuj-qSa@KiDxgfSi*iIg_OEEkgua28Pe!RU>gK+I^vFKW6^WFqNUtj5Bbj;av zQJ0tszx8Q<{e*~z>N=qkVl3&NXHhWZ9O>lWWORILgwUSz+pFgqN%>_KO75FWHYW>Grd z077S~xT@4~UFT!}&bHV)QRQ|9QZ8=rXv5yHtgJe4X?;W}F(@iExDfAFy)0fMRH2=r zO1tBs*@khOgY=975f2A&(@1N{h5iL0HSySVZd7oQuzsuB>Sl>};kT|myjB^p}2qE&~GU}SCbhN1wR0&!V zh+Ibt0IK>rK}U2;V&bu&KMzgYd0|9qeUS>0v>i0#yVHSyYb!K`3^S=uMx<&<$7KZQ z;w-*fZ1zD=rp}4$U8$Zm*#uS6aKeJ&Fu2qL9ma)pgmIDUA~ErfjEANxm2;$Jfy{G5 zB>@`$?vb9mL8NM)BQ&QGGFLP`+Eu}1YI2Si44Z%;T9?gD-AgO1LG=836G7QxL3drk z#e?!r;CsHYxJXCNchWN$5Bzf@%STsH1wP#rZ#U*DVcX1T#v9L!CiG=am zh$xs!8}0>)IB1Ka^Hj*-`IT+2v{8w0_9ZS2ch)6eM&p9Q1}W*+G|nFFN=k}1K%P4= zty?*mqN}oOhV?P?>+6k@6cmV{9=V9fw(d0kq&_4{u8N9dl{uVuf^nh4LxI%t({Ktq zn(sft`>RYPg|13BpgTOa6u@n}8g zfarhaOz;Yg9zp8eHf%KD&dLLqMF!e_ib)B(97dYWlR-+IfRMOsg)iSG6m0b+TU<~h z6Bc&x)5qPlh;$sNCUcuN@Gd;|cCd?IJb;c)_|AMv$89-kL~eTe>)4|Vtsgy*5EPbG zG(ARw(k4BsVD;@`UTEy>7j5@8Z-6RxFYvBlXa@ojojow0gtqrBHk?}4D~P{!pyI>y z;|7>6n-eH1w@{Zu9xUDEI6Z`w|M%oj)OKO+@<*fdPUdbpf9n860>Q)^IiCV*MsNZ* zX`zx_@Q*%3sS%5a4hVO!Q%Xg&^&`8pRY$v*@KcT}c>Wj;)K7(oHW%oyopE_dkBqdU z$cclf(6yRv)T)(^>@h$!lz*KA+vK7*t^bCf*P63K`0g>BIQSnm$lZO5fFnTw0000< KMNUMnLSTZ(eVa!B literal 0 HcmV?d00001 diff --git a/assets/graphics/icon-uns.png b/assets/graphics/icon-uns.png new file mode 100644 index 0000000000000000000000000000000000000000..cd5bb320dcf8559e97ccb0ae99ce28bb49511309 GIT binary patch literal 593 zcmeAS@N?(olHy`uVBq!ia0vp^F+l9V!2~2FX12cvQk(@Ik;M!Q+`=Ht$S`Y;1Oo#T zv!{z=NX4zUvjX!DEAX^2KhnDW_xxtrwos=o4c`NX`#Tr^UBO@LA^UrCZ?4w~%lw%4 z+Cq#A1-KR}gxAGKJhY#ERj+UA9S4Jck=*wfb04en#>Ic*Z%M9X*f&)q)77)}NySOyuDt~v z`R+XZM?_z4p1r;J;Jd9F8oha38$Ex_x>dJ0>EZG@OQ+gRVfkq@%dN@N)9kJCnpXQF zg%Dvw-Z*jDwRcW@x-{wHSHJS9f$={t_#9K56XyQ9uWXb2Wb2o~=fdAP{p5Y%&>;SP z=E7ygB^SKqyK~Pso%k!gcKc_(*Rw=zH6G@w+OKlh)|uE@At7?2El51m^ijobNxs<$ zsh`!tPgj*}I&u8TL1VY4o^N|zoa#{zm4AKkxb)M@X7WZqc+N|TR$adourHJSz~ROV zi(b@7Ejahn_*#39O1>mdORdJPmweWH=6cTVJbuuDV||Tm?8Z)pCvxhK!-VF@9>4ZK z-(r@fXt-e+v&u9Xy9I6+{x6i$exT(htG{c(+|It4!e+M{H+<~xx z4{94;E?=`Q$tFW#)_>`otZzG8Pi*=mBECnW?(Csmb?kA@<+UXa8ZAyx6a#0$8UOSC aGR}4};*WT;KMI&e7(8A5T-G@yGywqQY6h18 literal 0 HcmV?d00001 diff --git a/include/entity.h b/include/entity.h new file mode 100644 index 0000000..f4b5810 --- /dev/null +++ b/include/entity.h @@ -0,0 +1,22 @@ +#pragma once +#include + +struct Entity { + int x; + int y; + int hb_x; + int hb_y; + int hb_w; + int hb_h; + color_t hb_color; +}; + +#define ENTITY_GRID_SIZE 256 +extern struct Entity *g_entity_grid[ENTITY_GRID_SIZE]; + +void entity_init(void *restrict entity, int x, int y, int hb_x, int hb_y, + int hb_w, int hb_h, color_t hb_color); +void entity_deinit(void *restrict entity); +void entity_draw_hitbox(void *restrict entity); +void entity_grid_draw_hitboxes(void); +int entity_collide(void *restrict entity); diff --git a/include/player.h b/include/player.h new file mode 100644 index 0000000..4a85313 --- /dev/null +++ b/include/player.h @@ -0,0 +1,12 @@ +#pragma once +#include "entity.h" + +struct Player { + struct Entity; + float spd_x; + float spd_y; + float rem_x; + float rem_y; +}; + +void player_init(struct Player *restrict, int x, int y); diff --git a/include/tiles.h b/include/tiles.h new file mode 100644 index 0000000..8e7aac6 --- /dev/null +++ b/include/tiles.h @@ -0,0 +1,7 @@ +#pragma once + +enum Tile { + TILE_VOID, + TILE_SOLID, +}; +#define TILE_OOB TILE_VOID diff --git a/include/wall.h b/include/wall.h new file mode 100644 index 0000000..402735c --- /dev/null +++ b/include/wall.h @@ -0,0 +1,8 @@ +#pragma once +#include "entity.h" + +struct Wall { + struct Entity; +}; + +void wall_init(struct Wall *restrict, int x, int y, int width, int height); diff --git a/src/entity/collide.c b/src/entity/collide.c new file mode 100644 index 0000000..5111879 --- /dev/null +++ b/src/entity/collide.c @@ -0,0 +1,34 @@ +#include "entity.h" + +static int entity_collide_with(struct Entity *restrict, + struct Entity *restrict); + +int +entity_collide(void *restrict entity) +{ + struct Entity *const e = entity; + int i; + + i = ENTITY_GRID_SIZE; + while (i-- > 0) + if (entity_collide_with(e, g_entity_grid[i])) + return 1; + + return 0; +} + +/* axis aligned bounding box collision checking */ +static int +entity_collide_with(struct Entity *restrict self, struct Entity *restrict other) +{ + const int sx = self->x + self->hb_x; + const int sy = self->y + self->hb_y; + const int ox = other->x + other->hb_x; + const int oy = other->y + other->hb_y; + + if (self == NULL || other == NULL || self == other) + return 0; + + return sx < ox + other->hb_w && sx + self->hb_w > ox && + sy < oy + other->hb_h && sy + self->hb_h > oy; +} diff --git a/src/entity/draw_hitbox.c b/src/entity/draw_hitbox.c new file mode 100644 index 0000000..4f0629f --- /dev/null +++ b/src/entity/draw_hitbox.c @@ -0,0 +1,23 @@ +#include "entity.h" +#include + +void +entity_draw_hitbox(void *restrict entity) +{ + const struct Entity *const e = entity; + const int x = e->x + e->hb_x; + const int y = e->y + e->hb_y; + drect_border(e->x, e->y, e->x + 2, e->y + 2, C_NONE, 1, e->hb_color); + drect_border(x, y, x + e->hb_w - 1, y + e->hb_h - 1, C_NONE, 1, + e->hb_color); +} + +void +entity_grid_draw_hitboxes(void) +{ + int i; + i = ENTITY_GRID_SIZE; + while (i-- > 0) + if (g_entity_grid[i] != NULL) + entity_draw_hitbox(g_entity_grid[i]); +} diff --git a/src/entity/init.c b/src/entity/init.c new file mode 100644 index 0000000..d29facd --- /dev/null +++ b/src/entity/init.c @@ -0,0 +1,46 @@ +#include "entity.h" +#include + +struct Entity *g_entity_grid[ENTITY_GRID_SIZE]; + +void +entity_init(void *restrict entity, int x, int y, int hb_x, int hb_y, int hb_w, + int hb_h, color_t hb_color) +{ + static int init_grid = 1; + struct Entity *const e = entity; + int i; + e->x = x; + e->y = y; + e->hb_x = hb_x; + e->hb_y = hb_y; + e->hb_w = hb_w; + e->hb_h = hb_h; + e->hb_color = hb_color; + + if (init_grid) { + init_grid = 0; + i = ENTITY_GRID_SIZE; + while (i-- > 0) + g_entity_grid[i] = NULL; + } + + /* add to grid */ + i = ENTITY_GRID_SIZE; + while (i-- > 0) + if (g_entity_grid[i] == NULL) + break; + g_entity_grid[i] = entity; +} + +void +entity_deinit(void *restrict entity) +{ + int i; + /* remove from grid */ + i = ENTITY_GRID_SIZE; + while (i-- > 0) + if (g_entity_grid[i] == entity) + break; + g_entity_grid[i] = NULL; +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..c875535 --- /dev/null +++ b/src/main.c @@ -0,0 +1,36 @@ +#include "entity.h" +#include "player.h" +#include "wall.h" +#include +#include + +void +main(void) +{ + struct Player player; + struct Wall walls[5]; + + player_init(&player, 16, 32); + wall_init(&walls[0], 16, 0, DWIDTH - 32, 16); + wall_init(&walls[1], 16, DHEIGHT - 16, DWIDTH - 32, 16); + wall_init(&walls[2], 0, 0, 16, DHEIGHT); + wall_init(&walls[3], DWIDTH - 16, 0, 16, DHEIGHT); + wall_init(&walls[4], DWIDTH / 2 - 24, DHEIGHT - 64, 48, 48); + + do { + const int previous_x = player.x; + const int previous_y = player.y; + dclear(C_BLACK); + entity_grid_draw_hitboxes(); + dupdate(); + clearevents(); + player.x += keydown(KEY_RIGHT) - keydown(KEY_LEFT); + player.y += keydown(KEY_DOWN) - keydown(KEY_UP); + if (entity_collide(&player)) { + player.x = previous_x; + player.y = previous_y; + } + } while (!keydown(KEY_EXIT)); + + return; +} diff --git a/src/player/init.c b/src/player/init.c new file mode 100644 index 0000000..f250f97 --- /dev/null +++ b/src/player/init.c @@ -0,0 +1,12 @@ +#include "player.h" +#include + +void +player_init(struct Player *restrict p, int x, int y) +{ + entity_init(p, x, y, 2, 2, 12, 12, C_BLUE); + p->spd_x = 0.0; + p->spd_y = 0.0; + p->rem_x = 0.0; + p->rem_y = 0.0; +} diff --git a/src/wall/init.c b/src/wall/init.c new file mode 100644 index 0000000..8b3fc2c --- /dev/null +++ b/src/wall/init.c @@ -0,0 +1,8 @@ +#include "wall.h" +#include + +void +wall_init(struct Wall *restrict w, int x, int y, int width, int height) +{ + entity_init(w, x, y, 0, 0, width, height, C_DARK); +}