From f31c6a05f83d11fef166843e77138cf40b2b5560 Mon Sep 17 00:00:00 2001 From: Ted Stier Date: Fri, 17 Jan 2020 04:46:36 -0500 Subject: [PATCH 01/12] bit borken --- src/demo.c | 20 +++++++++----- src/draw.c | 72 ++++++++++++++++++++++++++++++--------------------- src/raycast.c | 42 ++++++++++++++---------------- src/torch.h | 15 +++++++++-- 4 files changed, 88 insertions(+), 61 deletions(-) mode change 100644 => 100755 src/demo.c mode change 100644 => 100755 src/draw.c mode change 100644 => 100755 src/raycast.c mode change 100644 => 100755 src/torch.h diff --git a/src/demo.c b/src/demo.c old mode 100644 new mode 100755 index 3132212..f5f0eaa --- a/src/demo.c +++ b/src/demo.c @@ -75,8 +75,6 @@ void cast_light_at(struct tile *tile, int y, int x, void *context) def_entity_fn(demo_player_update) { - int y = this->posy; - int x = this->posx; float bright = player_lantern_on && player_fuel > 0 ? 0.5f : 0.1f; if (player_lantern_on) { if (player_fuel > 0) { @@ -85,14 +83,22 @@ def_entity_fn(demo_player_update) player_lantern_on = false; } } + //cast_light(this->floor->map, y, x, 6, 0.3f, this->r, this->g, this->b); - int radius = sqrt(1.f / (1.f / 255)); - raycast_at(this->floor->map, y, x, radius, &cast_light_at, - &(struct light_info) { - .map = &this->floor->map, + + raycast_at(*(struct raycast_params) { + .callback = &cast_light_at, + .context = &(struct light_info) { + .map = &this->floor->map, .bright = bright, .y = y, .x = x, .color = this->color, - }); + } + .floor = this->floor->map, + .y = this->posy, + .x = this->posx, + .radius = sqrt(1.f / (1.f / 255)), + }); + memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_LINES * MAP_COLS)); } diff --git a/src/draw.c b/src/draw.c old mode 100644 new mode 100755 index 7bfc9e3..58bbb3d --- a/src/draw.c +++ b/src/draw.c @@ -29,20 +29,21 @@ void draw_map(void) uint8_t b = min(tile.b * tile.light + tile.db, 255); if (visibility[viewy + line][viewx + col]) { - ui_draw_at(line, col, (struct ui_cell){ + ui_draw_at(line, col, (struct ui_cell) { .codepoint = { [0] = tile.token }, - .fg = { - .r = r, .g = g, .b = b, + .fg = { + .r = r, .g = g, .b = b, }, .bg = { .r = 0, .g = 0, .b = 0, }, }); - } else { + } + else { ui_draw_at(line, col, (struct ui_cell) { .codepoint = " ", - .fg = { - .r = 0, .g = 0, .b = 0, + .fg = { + .r = 0, .g = 0, .b = 0, }, .bg = { .r = 0, .g = 0, .b = 0, @@ -62,7 +63,7 @@ void draw_entities(void) raycast_at(cur_floor->map, player.posy, player.posx, 100, &set_visible, NULL); - struct entity *pos; + struct entity * pos; list_for_each_entry(pos, &cur_floor->entities, list) { int line = pos->posy - clamp((player.posy - view_lines / 2), 0, MAP_LINES - view_lines); int col = pos->posx - clamp((player.posx - view_cols / 2), 0, MAP_COLS - view_cols); @@ -76,18 +77,19 @@ void draw_entities(void) if (visibility[pos->posy][pos->posx]) { ui_draw_at(line, col, (struct ui_cell) { .codepoint = { [0] = pos->token }, - .fg = { - .r = r, .g = g, .b = b, + .fg = { + .r = r, .g = g, .b = b, }, .bg = { .r = 0, .g = 0, .b = 0, }, }); - } else { + } + else { ui_draw_at(line, col, (struct ui_cell) { .codepoint = " ", - .fg = { - .r = 0, .g = 0, .b = 0, + .fg = { + .r = 0, .g = 0, .b = 0, }, .bg = { .r = 0, .g = 0, .b = 0, @@ -104,24 +106,25 @@ struct draw_info { int view_lines, view_cols; }; -int draw_thing(struct tile *tile, int y, int x, void *context) +void draw_thing(struct tile * tile, int y, int x, void * context) { - struct draw_info *info = context; + struct draw_info * info = context; int line = y - clamp(player.posy - info->view_lines / 2, 0, MAP_LINES - info->view_lines); int col = x - clamp(player.posx - info->view_cols / 2, 0, MAP_COLS - info->view_cols); if (tile->entity) { - ui_draw_at(line, col, (struct ui_cell){ + ui_draw_at(line, col, (struct ui_cell) { .codepoint = { [0] = tile->entity->token }, - /* = tile.entity->color * tile.light + tile.dcolor */ - .fg = color_add(color_multiply_by(tile->entity->color, tile->light), tile->dcolor), - .bg = { 0, 0, 0 }, + /* = tile.entity->color * tile.light + tile.dcolor */ + .fg = color_add(color_multiply_by(tile->entity->color, tile->light), tile->dcolor), + .bg = { 0, 0, 0 }, }); - } else { - ui_draw_at(line, col, (struct ui_cell){ + } + else { + ui_draw_at(line, col, (struct ui_cell) { .codepoint = { [0] = tile->token }, - /* = tile.color * tile.light + tile.dcolor */ - .fg = color_add(color_multiply_by(tile->color, tile->light), tile->dcolor), - .bg = { 0, 0, 0 }, + /* = tile.color * tile.light + tile.dcolor */ + .fg = color_add(color_multiply_by(tile->color, tile->light), tile->dcolor), + .bg = { 0, 0, 0 }, }); } } @@ -130,14 +133,25 @@ void draw_shit(void) { int view_lines, view_cols; ui_dimensions(&view_lines, &view_cols); - raycast_at(cur_floor->map, player.posy, player.posx, max(view_lines, view_cols) / 2, &draw_thing, &(struct draw_info) { - view_lines, view_cols + + raycast_at( + &(struct raycast_params) { + .callback = &draw_thing, + .context = &(struct draw_info) { + .view_lines = view_lines, + .view_cols = view_cols + }, + .floor = cur_floor, + .y = player.posy, + .x = player.posx, + .radius = max(view_lines, view_cols) / 2 }); size_t needed = snprintf(NULL, 0, "%3d %3d", player_fuel, player_torches) + 1; - char *buf = malloc(needed); + char * buf = malloc(needed); sprintf(buf, "%3d %3d", player_fuel, player_torches); - ui_draw_str_at(1, 0, buf, (struct ui_cell){ .fg = { 0xe2, 0x58, 0x22 } }); -// ui_draw_at(2, 0, (struct ui_cell){ .codepoint = { [0] = player_fuel }, .fg = { 77, 26, 128 }, }); -// ui_draw_at(2, 2, (struct ui_cell){ .codepoint = { [0] = player_torches }, .fg = { 77, 26, 128 }, }); + ui_draw_str_at(1, 0, buf, (struct ui_cell) { .fg = { 0xe2, 0x58, 0x22 } }); + + // ui_draw_at(2, 0, (struct ui_cell){ .codepoint = { [0] = player_fuel }, .fg = { 77, 26, 128 }, }); + // ui_draw_at(2, 2, (struct ui_cell){ .codepoint = { [0] = player_torches }, .fg = { 77, 26, 128 }, }); } diff --git a/src/raycast.c b/src/raycast.c old mode 100644 new mode 100755 index 37ceaaf..74a88a3 --- a/src/raycast.c +++ b/src/raycast.c @@ -3,30 +3,25 @@ #include #include -static void raycast_octant_at(struct floor *floor, int y, int x, int radius, - int row, float start_slope, float end_slope, int octant, - raycast_callback_fn callback, void *context); +static void raycast_octant_at(const struct raycast_params * params, int row, float start_slope, float end_slope, int octant); static void transform_point_by_octant(int y, int x, int dy, int dx, int octant, int *ay, int *ax); /* Hides hard-coded initial values for raycast_octant_at() */ -#define RAYCAST_OCTANT_AT(map, y, x, radius, octant, callback, context) do { \ - raycast_octant_at(map, y, x, radius, 1, 1.0, 0.0, octant, \ - callback, context); \ - } while (0); +#define RAYCAST_OCTANT_AT(params, octant) (raycast_octant_at(params, 1, 1.0, 0.0, octant)) /* Uses Björn Bergström's Recursive Shadowcasting Algorithm, which divides the map into eight congruent triangular octants, and calculates each octant individually. */ -void raycast_at(struct floor *floor, int y, int x, int radius, - raycast_callback_fn callback, void *context) +void raycast_at(const struct raycast_params * params) { /* raycast_octant_at() does not cast on the origin (y, x). */ - callback(&floor->map[y][x], y, x, context); + params->callback(¶ms->floor->map[params->y][params->x], params->y, params->x, params->context); - for (int octant = 0; octant < 8; ++octant) - RAYCAST_OCTANT_AT(floor, y, x, radius, octant, callback, context); + for (int octant = 0; octant < 8; ++octant) { + RAYCAST_OCTANT_AT(params, octant); + } } /* Iterates through each tile, left to right, of each row of a given octant, @@ -45,9 +40,12 @@ void raycast_at(struct floor *floor, int y, int x, int radius, calculating them as dx / dy rather than dy / dx. Consequently, as a line approaches the bottom left, its slope approaches infinity, and as a line approaches the top right, its slope approaches zero. */ -static void raycast_octant_at(struct floor *floor, int y, int x, int radius, - int row, float start_slope, float end_slope, int octant, - raycast_callback_fn callback, void *context) +static void raycast_octant_at( + const struct raycast_params * params, + int row, + float start_slope, + float end_slope, + int octant) { if (start_slope < end_slope) return; @@ -56,7 +54,7 @@ static void raycast_octant_at(struct floor *floor, int y, int x, int radius, except for the last one. next_start_slope contains the slope of the top right corner of the rightmost blocking tile. */ float next_start_slope = start_slope; - for (; row <= radius; ++row) { + for (; row <= params->radius; ++row) { /* Doesn't do anything. Here for clarity. */ start_slope = next_start_slope; /* Contains whether or not the last tile blocked light. Used @@ -80,14 +78,14 @@ static void raycast_octant_at(struct floor *floor, int y, int x, int radius, /* Contains the actual coordinate of the current tile. */ int ay, ax; - transform_point_by_octant(y, x, dy, dx, octant, &ay, &ax); + transform_point_by_octant(params->y, params->x, dy, dx, octant, &ay, &ax); if (!floor_map_in_bounds(ay, ax)) continue; - if (dx * dx + dy * dy < radius * radius) - callback(&floor->map[ay][ax], ay, ax, context); + if (dx * dx + dy * dy < params->radius * params->radius) + params->callback(¶ms->floor->map[ay][ax], ay, ax, params->context); - struct tile tile = floor_map_at(floor, ay, ax); + struct tile tile = floor_map_at(params->floor, ay, ax); if (blocked) { if (tile_blocks_light(tile)) { float tr_slope = (dx + 0.5) / (dy - 0.5); @@ -103,9 +101,7 @@ static void raycast_octant_at(struct floor *floor, int y, int x, int radius, next_start_slope = tr_slope; float bl_slope = (dx - 0.5) / (dy + 0.5); /* Recurse! */ - raycast_octant_at(floor, y, x, radius, row + 1, - start_slope, bl_slope, octant, callback, - context); + raycast_octant_at(params, row + 1, start_slope, bl_slope, octant); } } if (blocked) { /* If the last tile of the row blocks light. */ diff --git a/src/torch.h b/src/torch.h old mode 100644 new mode 100755 index 97f5a5e..59fb61d --- a/src/torch.h +++ b/src/torch.h @@ -6,6 +6,7 @@ #include #include #include +#include #define back(arr) (arr[sizeof(arr)/sizeof(*arr)]) #define min(a, b) (a < b ? a : b) @@ -134,9 +135,19 @@ def_input_key_fn(demo_get_fuel); extern struct floor demo_floor; /* Raycast */ + typedef void raycast_callback_fn(struct tile *tile, int y, int x, void *context); -void raycast_at(struct floor *floor, int y, int x, int radius, - raycast_callback_fn callback, void *context); +struct raycast_params +{ + struct floor * floor; + int x; + int y; + int radius; + raycast_callback_fn * callback; + void * context; +}; + +void raycast_at(const struct raycast_params * params); #endif From 1afe032bcf991495a2091a9f8366de6176fbd510 Mon Sep 17 00:00:00 2001 From: Ted Stier Date: Fri, 17 Jan 2020 05:00:51 -0500 Subject: [PATCH 02/12] guess what i unborked demo --- src/demo.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/demo.c b/src/demo.c index f5f0eaa..da62683 100755 --- a/src/demo.c +++ b/src/demo.c @@ -86,14 +86,14 @@ def_entity_fn(demo_player_update) //cast_light(this->floor->map, y, x, 6, 0.3f, this->r, this->g, this->b); - raycast_at(*(struct raycast_params) { + raycast_at(&(struct raycast_params) { .callback = &cast_light_at, .context = &(struct light_info) { - .map = &this->floor->map, - .bright = bright, .y = y, .x = x, - .color = this->color, - } - .floor = this->floor->map, + .map = &this->floor->map, + .bright = bright, .y = this->posy, .x = this->posx, + .color = this->color + }, + .floor = this->floor, .y = this->posy, .x = this->posx, .radius = sqrt(1.f / (1.f / 255)), @@ -104,21 +104,22 @@ def_entity_fn(demo_player_update) def_entity_fn(demo_torch_update) { - int y = (rand() % 3 - 1); - int x = (rand() % 3 - 1); - -// entity_move_pos_rel(this, y, x); + // entity_move_pos_rel(this, y, x); - y = this->posy; - x = this->posx; //cast_light(this->floor->map, y, x, 6, 1.f, this->r, this->g, this->b); - int radius = sqrt(1.f / (1.f / 255)); - raycast_at(this->floor->map, y, x, radius, &cast_light_at, - &(struct light_info) { + + raycast_at(&(struct raycast_params) { + .callback = &cast_light_at, + .context = &(struct light_info) { .map = &this->floor->map, - .bright = 1.f, .y = y, .x = x, + .bright = 1.f, .y = this->posy, .x = this->posx, .color = this->color, - }); + }, + .floor = this->floor, + .y = this->posy, + .x = this->posx, + .radius = sqrt(1.f / (1.f / 255)) + }); memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_LINES * MAP_COLS)); } From eb9bbffe0faec54b69a6908d5fa63212c6f9d50d Mon Sep 17 00:00:00 2001 From: Ted Stier Date: Fri, 17 Jan 2020 22:12:11 -0500 Subject: [PATCH 03/12] enspeedened raycasting --- .vs/ProjectSettings.json | 3 - .vs/slnx.sqlite | Bin 90112 -> 0 bytes src/demo.c | 14 +- src/draw.c | 2 +- src/floor.c | 14 +- src/raycast.c | 401 +++++++++++++++++++++++++++------------ src/torch.h | 29 +-- 7 files changed, 311 insertions(+), 152 deletions(-) delete mode 100755 .vs/ProjectSettings.json delete mode 100755 .vs/slnx.sqlite mode change 100644 => 100755 src/floor.c diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json deleted file mode 100755 index b11371a..0000000 --- a/.vs/ProjectSettings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "CurrentProjectSetting": "No Configurations" -} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite deleted file mode 100755 index 0afc4edf9262bbafbf67b73f08ca6b820af0b57e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90112 zcmeI5dvF`adBE=o@IZjXEhs)fiDm`M_K1jd6y6WJo)!Wj2^IxXASheIAe_V9L4pke zG5|_u>pm#O&P47w^-N;_;r!!HTYEZo+KJPdrY|=$P2#w1nmV1jQ#WlVP2IH9CNt?H zb=`KlyLX3s05oYSR^9N!NXNTxzuo)xx8Jw7w+q}YpIxYRlt8uFS{FNkDC1*Tmih5O zfMJ+4{y&NT>z^^ay3*e`eh1@>oI99A6w86^;=%%{Yhf{)Sr->DXIACX12Hd`G2c?|WUd%kD(25*isu8TbLRt@mC|CqfQvnoE0nNR`2Whn z!cnc1rB?HDO;%dw+`5jcLK>l%JCQ5q3fbIpU{%kNYjkRz&GKwlfQtwkS#Z0pEX@-T z7(+HQpR***=N58Cl5UI&uy8I@%$~{=XCv`=uxqf5tDfb=M!mjyc0;V!sx?LKSAexW z^n9nWml(YC8tbVUNmAPFTBTMeRqSH5tJ!?8N6)CT86XLi<;`|SS??mWiwMeqk^4qi zE;J>P#AmU2W%~-~O4(+8W4+O<=k)})jt#r~YdEgfXk1ZCC9%;^T3J!LsI2vxu11+% zal{&B_T+8LF~yuc5B9y@vzLR{Ry;J~9xu~~v*)rO4_hP7o{Z10N1Q#$95cI!IIThZ z+1%qfmWZS0-PvJo&R_JfHdjjbcZ)T;V%K?fK~Mbm5AxFHCEQEuJ(Ye6J@QJmb*0@A z*DsX=r1L1{&)}XE_gBOd1-Hw8EXZC()D!j7lJeHbMi;1td9-F-Ddf+tbgw+RPB)Xu zz4SD#V)z=POH`9>9Z5I!oYHFJKhM(H<{g$*OtVV(&(&_Zrh$V)VKZY zTILc=O=(vn1BQNA=cD*?MoqA1AilhHoOAgf!ad)n(es(2P&;*RPE-G9Qg>;L*3q`5)*^wVNuU%36=f^b2}Jp7)@DgD-Uld4LoYI9y%<3V@sTEVCO%Ia|X9g zvM&GhG<#K{Woou*e+DdNtZGt|%W0BZ=4t1|`UY-Cn|H3@yR}h|7jK;--(}FZ(JSbA zyaOK~00e*l5C8%|00;m9AOHk_zz+w3$KuXG=AP?6M($tp#>&&OIz!zKX&-_7wQag- zk$5PPkfn%_sDx!99G25UT8>wUx}1*2Q)#i95F&|4JX{HC0S4s@vss~$CC*Ki!0HHlt?9oNGdD|F)1MnVnhrJ zQ8|^2RjOh{j>$r@60OK_IVz;0iHH!3BxL~`8xxYTNHwBFBJl*SR4NpYCga!$IT4Nt zv2ZnxmC{imo{B}QN+PO=sfduSR8#3nS`w7Bj87LzM)B#Q2_dQ^E0JWX8V^fJK}tkY ziKHY6iKLhkVreNMh-o<_L@G)(nn=s3N);u?4s)f)tL()o5H+ zlyq8<(~)pQipxSe85eO$SW`^Kqe7$_PbDhVN;Q;B3UXCS#?#@nkdj4QyGl$FDsn6? zgcET&Qjw~OY9cHsaw?3OCxvJz9v5N>DJ-O`N(k33AxY_YG!zYo1f`lzDV20cs8rJx z+`vjqs8r$+A(RS*BB79!7841f8i~r4cqJkvf00e-* z2ZF%3(;=|*dn=|dR*sE296`7K#VhqoW8(w5qUozLhlW|lG^>3F!Rf&@a-tU)^cU#& z(F+LH|345d3`PI}AOHk_01yBIKmZ5;0U!VbfWTfQFzvX9-R4Ux&I!jcw&$w>j&XeN zZ~tPzfX{K*ZTS)aS^uB$W*GF(=$mC%o(gUG@E4gV$nMgEigPw`d$ z3?Jubc&GQDynpKbg7-!5)83!)u6i@xJNIgvK)rzg5C8%|00;m9AOHk_01)_LBQSIO z^dXM9i*<8zon}kAICpWbedQ82^v1J^kA3C~KRGqSF$ZyCOWc(3j|%1_l5+Ha-hM_r zbQ{OS-EI!A$v&t^9c{(6J@;U{*&sSEU;pE`CZ;)NKhE7zTI+Mt6cz9P*4M@laEu>| z+j89`9ox?_6Ii-Yo4ZKQ@-kK(o#L2Lb_ff*qDeo;Op`)Ya}D{VS*{vNittZx%na7Q zR2MgumR19jFgdPfs5LHa=ryDAF;!lzH=AaC|30-K{EQC#93)dg6QgQ1<(7EGEcR() zWxZ(lg_=jGHSk_TteY|) z80MHeu!`KOT~=B`r#5F~pZ2Itucb+CbK<0%*g2$^?bNNA7*eZMuVH_Z}(iJ&WQKhE( z6mGSt0gkyH=bpQOAGmg*(QFy{Syg%Na+~JAzB)+O|7ZB88T60nZS+la93|0F^c32{ zcmHF^g})W>8T3c|fAYV`Kh3|2zR3R$`UUhL`Y&-35mzsbMJzs|q@!xr&SA0Pk( zfB+Bx0zd!=00AHX1b_e#cwY$YbNC#0vF6E@Lte*0wmYFRGv$c0{U%Xv^Emdi>deWs z+u>*FY{`Kk#{^4eNcMA%QM@xXjKA%!&4l=keQ9#UF~jOJ9up)%o8=fM``XOL7*Wz^ zGxm|wsWTX(beGOr_=vhTQ-O%x-PsA=d?a}%9brAqGz&3;9CzSCyE6~NgoSyw!9#6U zXD{63wCb$F5D{xL2`-mojK$Lj9I;lPGZ-X7JW=2zfAQ>qgLmA{8dCxToMX(5=K<*b zKU!tbf1&TA@8NF&d>j2O`YR-&KS!_Qd;b^k{r;!X)9B~Xb@Wm6)94Y@LaXQx(U{4w^MZMr`t)oouJ!sx*en2eRMlYw?4W>Wb5YX)=Re|bURG992}EJ zU|1K~aAY$`Hcql}kj;R@!MN4+f0;c0|3A=Qqa)}?&?vssZ=nJHU-`GtpP^quukvs3 z9bV?2MX&HrqG!-~lt*dwS^g{hZ}FeypXZ0zgzRoC>V4tSgsEM3*- z_76En$u2kLbxvbt?Kcj7(~-nY^3EByySmR!&_w-L4CC}j|LwvURn^z{xqZ|G?RN^J z>Vf*}1Ru?&|0V&^N_E%z-Mr;ka(kzoVYMpwmkOr!e)q_z^A1*D;itbf7^cX~YyNJJ zS{rrM-|41i=)WcyaZWScmH#2<7(f00e*l5C8%|00;m9AOHkD@C4${mBa4$eE(0@|Ht@W zVbFKbU!vF0Z=hdBpTutfxP(4}7SP>j7EK~2|2_O3fUokujn&`-1b_e#00KY&2mk>f z00e*l5C8%|;C&|G!!I3R-7Gibz|XFq`&G~He#(bmH$WuQL~``k`KMm?;r9#>$pKAr z+t+>g6$3=FUzK>j`u9Hkb^#*s6G`~{D~~&*5g0n!|w(l5+9L7 zzg7u-$cJAGKqN@b<@xlNefW(4MB>pThu`wy7XlE8SCzPb&ga9g0w9thRWc-8@!>ZC z5Xp!p;eOVKUj#rTydl9a03ecKRpNT^MY8@shCacde?Z?r@1XDEr~myMdIS9l`UCVu z^a}bsdKteH@OktcdKSMK@DuNI6GQPp00;m9AOHk_01yBIKmZ5;0U!Vb_67m+*uEM1 z;J<15;J*X(!GHVdga7>W!GDwV!G9CRKIEr9?K00KY&2mk>f00e*l5C8%|00`_=0%ZLk z?*I2{>qEVP01yBIKmZ5;0U!VbfB+Bx0zhD|5P&Z@L`ZS;tcYZx0j)?%OLgpq@8RVCzoa<-cEGx6alYvhv9C=6a=BpI552 zMy*q8HrCYL#)T8Lx{{aI^8J)hwwTM5a)EqdKKDRibysDSy`BL6EEan8%YoTd>uJlu ztqHHopT%aL>~Cg4Tvz%V$M0aAk#h%=h+;XAU0hfobuBDrGt0T)WA~1@{DQz<7dm34 zuGp(?KlW za)lDM3jbeOSU9Scvear`uE|QvoLkpXRY)Tgb0>1eTp^oV4y@`qa*a-{vss?)3UCoY zBMWY~m8E$C0%OQ#=5v;$`P@RzNYaf_0T#|>irG_{;%p=y4|WZ5dvb~T$1_UIW^HUlJqvb@>uDC=E> zb`e1tFmm4r%Y~*SlK3n(uWVldT`AkFZ>%?Z^}L?o*0Euie+|dg8jUMzsU$WUN-HZ$ z7nQYM)72=mD~?#B%$~e$Ii{Gi=fS?$d-ihh+KPup+~Z{$arRvH<6&#W*^}}4^@y`4 znPX-b5vMh1Kbw0z#}aY$ygNJ0&H0NS*5*p-{%)~GSL`~kF6fE>{y|>ayo7s6y{FPo zp+{b+wyv~0;`*g>fOHN+F9B4f~|5awl0M^d_@A^4gNvQW~8# z(rw$*hWfUjUCUg8sVVJhWWdnx>U&T9*|(EHZjtZL}De&z;DuER+J$MvF#lNAIR_kT)GJe|VbRI!ME0S?P3YjSDoU zwehwpaa#SUSC6_89qy|cwhP+e(g5c_a)dokJ*WLJ9-}F1ZROz&rGZCn)B1!N6nI{=k z7>44fz~p6NNO5xICgvRE(m#Czj{l zySY6@Q1c&sG;sLChXeS}(pl=)5X}?I z__p5A#+B*QO81)WA)Stn9d|iikKVe=b00ctv%B4O46oun?Kpr`O{ za(`zDVhmPRh6p>^zRYfnkkyu_@&quudG6#MT9+)9)&@%}h?Q}fafpoKS%;`))`1QWi%M0&oq?pRb@zxr=o62IZ*-H#w+oi8M*pJvhD$dOZmsUV zY5=}ri1>CgdS1DtG-R>S*}>?sosI5W)Q(2ma+QORPa~H<8fBj_&6Ze6_hIVWF5J6J z`o?@WwKs5gaTlx4pXg!JFTVQ6y`E#|Kzq+qmUf;$*q+F!&W%g~c5!PCYS{LFdn018 ziwp?Mfo}J*P3Q4G_BP#_C+obFHs=J3ANu@&scW$>T5Nl#28$oC_;Eus9XB}y)7Lfj z-r@)R{{NOwa=;0J01yBIKmZ5;0U!VbfB+Bx0zd!=+;ReN|9{Jo!wG=^5C8%|00;m9 zAOHk_01yBIKmZ8basu%DzgvzRP6z~m01yBIKmZ5;0U!VbfB+Bx0zlxF6M*&qTaFw~ d2n2ut5C8%|00;m9AOHk_01yBIK;V`W_+Rhc)&~Fp diff --git a/src/demo.c b/src/demo.c index e8d7b58..0d7d927 100755 --- a/src/demo.c +++ b/src/demo.c @@ -19,7 +19,7 @@ void demo_floor_load_map(const char *filename) floor_map_generate(&floors[0], CAVE); /* Make this not shit please. */ - for (size_t line = 0; line < MAP_LINES; ++line) { + for (size_t line = 0; line < MAP_ROWS; ++line) { for (size_t col = 0; col < MAP_COLS; ++col) { // fscanf(mapfp, "%c", &demo_floor.map[line][col].token); floors[0].map[line][col].light = 0; @@ -37,14 +37,14 @@ void demo_floor_load_map(const char *filename) // fclose(mapfp); - for (int i = 0; i < 20; ++i) { - int y = rand() % MAP_LINES; + for (int i = 0; i < 0; ++i) { + int y = rand() % MAP_ROWS; int x = rand() % MAP_COLS; demo_place_snake(y, x); } } -int drawn_to[MAP_LINES][MAP_COLS] = { 0 }; +int drawn_to[MAP_ROWS][MAP_COLS] = { 0 }; struct light_info { tile_map *map; @@ -75,7 +75,7 @@ void cast_light_at(struct tile *tile, int y, int x, void *context) def_entity_fn(demo_player_update) { - float bright = player_lantern_on && player_fuel > 0 ? 0.5f : 0.1f; + float bright = player_lantern_on && player_fuel > 0 ? 20.0f : 0.1f; if (player_lantern_on) { if (player_fuel > 0) { player_fuel--; @@ -99,7 +99,7 @@ def_entity_fn(demo_player_update) .radius = sqrt(1.f / (1.f / 255)), }); - memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_LINES * MAP_COLS)); + memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_ROWS * MAP_COLS)); } def_entity_fn(demo_torch_update) @@ -120,7 +120,7 @@ def_entity_fn(demo_torch_update) .x = this->posx, .radius = sqrt(1.f / (1.f / 255)) }); - memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_LINES * MAP_COLS)); + memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_ROWS * MAP_COLS)); } def_entity_fn(demo_torch_destroy) diff --git a/src/draw.c b/src/draw.c index ff7e7a5..16724b3 100755 --- a/src/draw.c +++ b/src/draw.c @@ -110,7 +110,7 @@ struct draw_info { void draw_thing(struct tile *tile, int y, int x, void *context) { struct draw_info * info = context; - int line = y - clamp(player.posy - info->view_lines / 2, 0, MAP_LINES - info->view_lines); + int line = y - clamp(player.posy - info->view_lines / 2, 0, MAP_ROWS - info->view_lines); int col = x - clamp(player.posx - info->view_cols / 2, 0, MAP_COLS - info->view_cols); if (tile->entity) { ui_draw_at(line, col, (struct ui_cell) { diff --git a/src/floor.c b/src/floor.c old mode 100644 new mode 100755 index c2ea73c..14d5ab1 --- a/src/floor.c +++ b/src/floor.c @@ -5,7 +5,7 @@ #include typedef int cell; -typedef cell cell_grid[MAP_LINES][MAP_COLS]; +typedef cell cell_grid[MAP_ROWS][MAP_COLS]; #define cell_grid_for_each_cell(pos, grid) \ for (pos = *grid; pos != back(grid); ++pos) @@ -40,7 +40,7 @@ static void intern_populate_grid(cell_grid grid, float rate) *pos = 0; } */ - for (int y = 0; y < MAP_LINES; ++y) { + for (int y = 0; y < MAP_ROWS; ++y) { for (int x = 0; x < MAP_COLS; ++x) { if (rand() % 100 / 100.f < rate) grid[y][x] = 1; @@ -53,7 +53,7 @@ static void intern_populate_grid(cell_grid grid, float rate) static void intern_iterate_grid(cell_grid grid, int birth, int survive) { cell_grid new = { 0 }; - for (int y = 0; y < MAP_LINES; ++y) + for (int y = 0; y < MAP_ROWS; ++y) for (int x = 0; x < MAP_COLS; ++x) { int alive = intern_cell_alive_neighbours(grid, y, x); if (grid[y][x]) { @@ -66,7 +66,7 @@ static void intern_iterate_grid(cell_grid grid, int birth, int survive) } // memcpy(new, grid, sizeof(new)); - for (int y = 0; y < MAP_LINES; ++y) + for (int y = 0; y < MAP_ROWS; ++y) for (int x = 0; x < MAP_COLS; ++x) { grid[y][x] = new[y][x]; } @@ -129,7 +129,7 @@ struct tile floor_map_at(struct floor *floor, int y, int x) int floor_map_in_bounds(int y, int x) { - return y >= 0 && y < MAP_LINES && x >= 0 && x < MAP_COLS; + return y >= 0 && y < MAP_ROWS && x >= 0 && x < MAP_COLS; } void floor_map_clear_lights(void) @@ -162,7 +162,7 @@ void floor_update_entities(struct floor *floor) } } -bool tile_blocks_light(struct tile tile) +bool tile_blocks_light(const struct tile * tile) { - return !tile.walk || (tile.entity ? tile.entity->blocks_light : tile.entity); + return !tile->walk || (tile->entity && tile->entity->blocks_light); } diff --git a/src/raycast.c b/src/raycast.c index 53b5432..f0e7385 100755 --- a/src/raycast.c +++ b/src/raycast.c @@ -3,145 +3,306 @@ #include #include -static void raycast_octant_at( - const struct raycast_params * params, - int row, - float start_slope, - float end_slope, - int octant); +struct index_interval +{ + int begin; + int end; +}; -static void transform_point_by_octant( - int y, +/* +Fetches the selected tile, calls back, and returns +the selected tile. + +preconditions: + - rparams->floor points to a valid floor + - rparams->callback points to a valid function + - (x, y) denotes a tile which is in the floor bounds + +postconditions: + - rparams->callback is called with the corresponding tile + - the result is a pointer to that tile +*/ +static struct tile * get_tile_and_call_back( + const struct raycast_params * rparams, + int x, int y) +{ + struct tile * tile = &rparams->floor->map[y][x]; + rparams->callback(tile, y, x, rparams->context); + return tile; +} + +void swapi(int * l, int * r) +{ + int t = *l; + *l = *r; + *r = t; +} + +struct point +{ + int x; + int y; +}; + +/* +Transform zeroth octant coordinates into other octants' coordinates. + +Diagram of octant layout: + + \ 7 | 5 / + 6 \ | / 4 + - - - - - + 2 / | \ 0 + / 3 | 1 \ + +If first octant bit is set, flip across the diagonal. +If second octant bit is set, flip across the vertical. +If third octant bit is set, flip across the horizontal. +*/ +static struct point transform_point_to_octant( int x, - int dy, + int y, int dx, - int octant, - int *ay, - int *ax); + int dy, + int octant) +{ + if (octant & 1) + { + swapi(&dx, &dy); + } + if (octant & 2) + { + dx = -dx; + } + if (octant & 4) + { + dy = -dy; + } -/* Hides hard-coded initial values for raycast_octant_at() */ -#define RAYCAST_OCTANT_AT(params, octant) (raycast_octant_at(params, 1, 1.0, 0.0, octant)) + return (struct point){ x + dx, y + dy }; +} + +/* +Transforms the coordinates according to the octant, +fetches the selected tile, calls back, and returns +the selected tile. -/* Uses Björn Bergström's Recursive Shadowcasting Algorithm, which - divides the map into eight congruent triangular octants, and calculates each - octant individually. */ -void raycast_at(const struct raycast_params * params) +preconditions: + - rparams->floor points to a valid floor + - rparams->callback is a valid function pointer + - (dx, dy) denotes a tile which is in the floor bounds + +postconditions: + - rparams->callback is called with the corresponding tile + - the result is a pointer to that tile +*/ +static struct tile * get_transformed_tile_and_call_back( + const struct raycast_params * rparams, + int dx, int dy, + int octant) { - /* raycast_octant_at() does not cast on the origin (y, x). */ - params->callback(¶ms->floor->map[params->y][params->x], params->y, params->x, params->context); + struct point r = transform_point_to_octant( + rparams->x, rparams->y, + dx, dy, + octant); + return get_tile_and_call_back(rparams, r.x, r.y); +} - for (int octant = 0; octant < 8; ++octant) { - RAYCAST_OCTANT_AT(params, octant); - } +/* +preconditions: + - oparams->dx_min <= oparams->dx_max + +postconditions: + - result.begin and result.end denote an in-bounds tile sequence corresponding to the requested slope interval +*/ +struct index_interval make_dy_interval( + float slope_begin, + float slope_end, + int dx, + int dy_max) +{ + struct index_interval dy_interval = { + slope_begin * (dx - 0.5f) + 0.5f, + slope_end * (dx + 0.5f) + 0.5f + }; + dy_interval.begin = min(dy_interval.begin, dy_max); + dy_interval.end = min(dy_interval.end, dy_max); + return dy_interval; } -/* Iterates through each tile, left to right, of each row of a given octant, - recursing in each gap between blocking tiles, except for the last one. - - 7 --....-- - = visible tile --....-- - 6 --...-- . = hidden tile --...-- - 5 --##-- # = blocking tile --!#-- ! = function recurses here - 4 ----- ----- - 3 ---- ---- - 2 --- --- - 1 -- -- - @ @ = the centre @ - - Note: the algorithm uses an unorthodox understanding of coordinate gradients, - calculating them as dx / dy rather than dy / dx. Consequently, as a line - approaches the bottom left, its slope approaches infinity, and as a line - approaches the top right, its slope approaches zero. */ +struct octant_params +{ + int octant; + int dx_max; + int dy_max; +}; + +/* +Accepts slopes corresponding a gap between blocking tiles. +Iterates through columns from left to right, then through each +tile,top to bottom, of the gap, searching for deeper gaps. +Recurses in each gap except those enclosed by the last tile +of the column. Exits if there is no such gap. + +Diagram of zeroth octant: + + dx 01234567 dy + @------- 0 `-` = visible tile + ------- 1 `.` = hidden tile + ---!.. 2 `#` = blocking tile + --#.. 3 `@` = centre + --.. 4 `!` = blocking tile where function recurses + --. 5 + -- 6 + - 7 + +The algorithm always works in the coordinates of the zeroth octant, +then applies a transformation to obtain the actual coordinate of the +selected tile. + +As a column is iterated: + +If the previous tile blocks light, but the current tile does not, we have +encountered the beginning of a gap. If the previous tile allows light, but +the current tile does not, we have encountered the end of the gap, and we recurse. + +Each time we encounter any such bound, we calculate the slope of the associated +point on the tile. Slopes for beginnings of regions correspond to bottom left points +of tiles. Slopes for ends of regions correspond to top right points of tiles. +Those slopes are used in next recursion or iteration. + +Diagram of begin and end slopes: + + @xxxxxx + xxxxxxxxx ####### + xxx xxxxxx####### begin + xxx ------- + xxx ------- + xxx------- + xxx---- + ---xxx- + ------x end + ####### + ####### + +preconditions: + - rparams->floor points to a valid floor + - rparams->callback points to a valid function + - (rparams->x, rparams->y) denotes a tile which is in the floor bounds + - oparams->dx_min <= oparams->dx_max + - start_slope < end_slope + - the coordinates and bounds in rparams and oparams denote a set of tiles + which are in the floor bounds + +postconditions: + - rparams->callback is called at least once for each tile in line of sight + within the octant and oparams->dx_max +*/ static void raycast_octant_at( - const struct raycast_params * params, - int row, + const struct raycast_params * rparams, + const struct octant_params * oparams, + int dx, float start_slope, - float end_slope, - int octant) + float end_slope) { - if (start_slope < end_slope) - return; - - /* This function is called recursively on each gap in blocking tiles - except for the last one. next_start_slope contains the slope of the - top right corner of the rightmost blocking tile. */ - float next_start_slope = start_slope; - for (; row <= params->radius; ++row) { - /* Doesn't do anything. Here for clarity. */ - start_slope = next_start_slope; - /* Contains whether or not the last tile blocked light. Used - to determine when to recurse. */ - bool blocked = false; - /* Contains the vector of the current tile from the centre. */ - int dx, dy; - /* This implementation pretends its always calculating the - zeroth octant, then applies a transformation. */ - for (dx = -row, dy = -row; dx <= 0; ++dx) { - /* Slope of the bottom left and top right corners - of the current tile from the centre, respectively */ - float bl_slope = (dx - 0.5) / (dy + 0.5); - float tr_slope = (dx + 0.5) / (dy - 0.5); - /* Accounts for mathematical edgecases. */ - if (start_slope < tr_slope) { - continue; - } else if (end_slope > bl_slope) { - break; - } + bool blocked = false; + for (; dx <= oparams->dx_max && !blocked; ++dx) + { + struct index_interval dy_interval = make_dy_interval( + start_slope, + end_slope, + dx, + oparams->dy_max); + + int dy = dy_interval.begin; + + struct tile * tile = get_transformed_tile_and_call_back( + rparams, + dx, dy, + oparams->octant); + + blocked = tile_blocks_light(tile); - /* Contains the actual coordinate of the current tile. */ - int ay, ax; - transform_point_by_octant(params->y, params->x, dy, dx, octant, &ay, &ax); - if (!floor_map_in_bounds(ay, ax)) - continue; - - if (dx * dx + dy * dy < params->radius * params->radius) - params->callback(¶ms->floor->map[ay][ax], ay, ax, params->context); - - struct tile tile = floor_map_at(params->floor, ay, ax); - if (blocked) { - if (tile_blocks_light(tile)) { - float tr_slope = (dx + 0.5) / (dy - 0.5); - next_start_slope = tr_slope; - continue; - } else { /* Still blocked. */ - blocked = false; - start_slope = next_start_slope; - } - } else if (tile_blocks_light(tile)) { + for (++dy; dy <= dy_interval.end; ++dy) { + tile = get_transformed_tile_and_call_back( + rparams, + dx, dy, + oparams->octant); + + if (blocked && !tile_blocks_light(tile)) { + blocked = false; + start_slope = (dy + 0.5f) / (dx - 0.5f); + } else if (!blocked && tile_blocks_light(tile)) { blocked = true; - float tr_slope = (dx + 0.5) / (dy - 0.5); - next_start_slope = tr_slope; - float bl_slope = (dx - 0.5) / (dy + 0.5); - /* Recurse! */ - raycast_octant_at(params, row + 1, start_slope, bl_slope, octant); + raycast_octant_at( + rparams, + oparams, + dx + 1, + start_slope, + (dy - 0.5f) / (dx + 0.5f)); } } - if (blocked) { /* If the last tile of the row blocks light. */ - break; - } } } -/* raycast_octant_at() pretends its always calculating the zeroth octant. - transform_point_by_octant() applies the transformation. */ -static void transform_point_by_octant(int y, int x, int dy, int dx, int octant, - int *ay, int *ax) +/* Uses a modified version ofBjörn Bergström's Recursive Shadowcasting Algorithm, + which divides the map into eight congruent triangular octants, and calculates + each octant individually. + + Casts on the origin, then enters the recursive functions for each octant. + +preconditions: + - rparams->floor points to a valid floor + - rparams->callback points to a valid function + - (rparams->x, rparams->y) denotes a tile which is in the floor bounds + - the coordinates and bounds in rparams and oparams denote a set of tiles + which are in the floor bounds + +postconditions: + - rparams->callback is called at least once for each tile in rparams->radius + and line of sight + +notes: + - may call back for cells outside the requested radius. + - may call back multiple times for cells along axes and diagonals. +*/ +void raycast_at(const struct raycast_params * rparams) { - /* Notice that either yy and xx are non-zero, or yx and xy are non-zero. - When yy and xx are zero, yx and xy swap r and x respectively. - When yx and xy are zero, y and x flip along the axis respectively. */ - static const int transforms[8][2][2] = { - /* yy yx xx xy */ - { { 1, 0}, { 1, 0} }, - { { 0, 1}, { 0, 1} }, - { { 0, 1}, { 0, -1} }, - { { 1, 0}, {-1, 0} }, - { {-1, 0}, {-1, 0} }, - { { 0, -1}, { 0, -1} }, - { { 0, -1}, { 0, 1} }, - { {-1, 0}, { 1, 0} }, + get_tile_and_call_back(rparams, rparams->x, rparams->y); + + const int dx_max[] = { + min(rparams->radius, MAP_COLS - rparams->x - 1), + min(rparams->radius, MAP_ROWS - rparams->y - 1), + min(rparams->radius, rparams->x ), + min(rparams->radius, MAP_ROWS - rparams->y - 1), + min(rparams->radius, MAP_COLS - rparams->x - 1), + min(rparams->radius, rparams->y ), + min(rparams->radius, rparams->x ), + min(rparams->radius, rparams->y ), }; - const int (*t)[2] = transforms[octant]; - *ay = y + dy * t[0][0] + dx * t[0][1]; - *ax = x + dx * t[1][0] + dy * t[1][1]; -} + const int dy_max[] = { + MAP_ROWS - rparams->y - 1, + MAP_COLS - rparams->x - 1, + MAP_ROWS - rparams->y - 1, + rparams->x , + rparams->y , + MAP_COLS - rparams->x - 1, + rparams->y , + rparams->x , + }; + + for (int octant = 0; octant < 8; octant++) + { + raycast_octant_at( + rparams, + &(struct octant_params) { + octant, + dx_max[octant], + dy_max[octant] + }, + 1, + 0.0, + 1.0); + } +} \ No newline at end of file diff --git a/src/torch.h b/src/torch.h index 59fb61d..32357f8 100755 --- a/src/torch.h +++ b/src/torch.h @@ -79,12 +79,12 @@ struct tile { uint walk : 1; }; -bool tile_blocks_light(struct tile); +bool tile_blocks_light(struct tile const *); -#define MAP_LINES 100 +#define MAP_ROWS 100 #define MAP_COLS 100 -typedef struct tile tile_map[MAP_LINES][MAP_COLS]; +typedef struct tile tile_map[MAP_ROWS][MAP_COLS]; typedef struct list_head entity_list; struct floor { @@ -100,10 +100,10 @@ enum floor_type { CAVE, }; -struct tile floor_map_at(struct floor *floor, int y, int x); -int floor_map_in_bounds(int y, int x); -void floor_map_clear_lights(void); -void floor_map_generate(struct floor *floor, enum floor_type type); +struct tile floor_map_at(struct floor *floor, int y, int x); +int floor_map_in_bounds(int y, int x); +void floor_map_clear_lights(void); +void floor_map_generate(struct floor *floor, enum floor_type type); int floor_add_entity(struct floor *floor, struct entity *entity); void floor_update_entities(struct floor *floor); @@ -136,18 +136,19 @@ extern struct floor demo_floor; /* Raycast */ -typedef void raycast_callback_fn(struct tile *tile, int y, int x, void *context); +typedef void raycast_callback_fn(struct tile *tile, int x, int y, void *context); struct raycast_params { - struct floor * floor; - int x; - int y; + struct floor *floor; + int x; + int y; int radius; - raycast_callback_fn * callback; - void * context; + raycast_callback_fn *callback; + void *context; }; -void raycast_at(const struct raycast_params * params); +void raycast_at(const struct raycast_params *params); +void raycast(const struct raycast_params *params); #endif From 42cfcdbc01c73ecbdd7b22851d953f4b87b1c298 Mon Sep 17 00:00:00 2001 From: Ted Stier Date: Fri, 17 Jan 2020 22:29:51 -0500 Subject: [PATCH 04/12] raycasting tweaks --- .gitignore | 4 ++-- src/raycast.c | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 6a4818f..9cb6e41 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ a.out debug_log tags -bin/torch -bin/debug +bin +.vs diff --git a/src/raycast.c b/src/raycast.c index f0e7385..c8b1d3f 100755 --- a/src/raycast.c +++ b/src/raycast.c @@ -122,7 +122,7 @@ struct index_interval make_dy_interval( int dy_max) { struct index_interval dy_interval = { - slope_begin * (dx - 0.5f) + 0.5f, + slope_begin * (dx - 0.5f) - 0.5f, slope_end * (dx + 0.5f) + 0.5f }; dy_interval.begin = min(dy_interval.begin, dy_max); @@ -231,7 +231,7 @@ static void raycast_octant_at( if (blocked && !tile_blocks_light(tile)) { blocked = false; - start_slope = (dy + 0.5f) / (dx - 0.5f); + start_slope = (dy - 0.5f) / (dx - 0.5f); } else if (!blocked && tile_blocks_light(tile)) { blocked = true; raycast_octant_at( @@ -297,12 +297,12 @@ void raycast_at(const struct raycast_params * rparams) raycast_octant_at( rparams, &(struct octant_params) { - octant, - dx_max[octant], - dy_max[octant] + .octant = octant, + .dx_max = dx_max[octant], + .dy_max = dy_max[octant] }, 1, - 0.0, - 1.0); + 0.0f, + 1.0f); } } \ No newline at end of file From 92a56166ef688b95a3e742d0685d5fed0b9b064f Mon Sep 17 00:00:00 2001 From: Ted Stier Date: Fri, 17 Jan 2020 23:07:32 -0500 Subject: [PATCH 05/12] fixed the fixed raycasting --- src/demo.c | 2 +- src/draw.c | 0 src/floor.c | 0 src/raycast.c | 22 +++++++++++++--------- src/torch.h | 0 5 files changed, 14 insertions(+), 10 deletions(-) mode change 100755 => 100644 src/demo.c mode change 100755 => 100644 src/draw.c mode change 100755 => 100644 src/floor.c mode change 100755 => 100644 src/raycast.c mode change 100755 => 100644 src/torch.h diff --git a/src/demo.c b/src/demo.c old mode 100755 new mode 100644 index 0d7d927..4e8eee6 --- a/src/demo.c +++ b/src/demo.c @@ -75,7 +75,7 @@ void cast_light_at(struct tile *tile, int y, int x, void *context) def_entity_fn(demo_player_update) { - float bright = player_lantern_on && player_fuel > 0 ? 20.0f : 0.1f; + float bright = player_lantern_on && player_fuel > 0 ? 0.5f : 0.1f; if (player_lantern_on) { if (player_fuel > 0) { player_fuel--; diff --git a/src/draw.c b/src/draw.c old mode 100755 new mode 100644 diff --git a/src/floor.c b/src/floor.c old mode 100755 new mode 100644 diff --git a/src/raycast.c b/src/raycast.c old mode 100755 new mode 100644 index c8b1d3f..a5bbf77 --- a/src/raycast.c +++ b/src/raycast.c @@ -3,12 +3,6 @@ #include #include -struct index_interval -{ - int begin; - int end; -}; - /* Fetches the selected tile, calls back, and returns the selected tile. @@ -108,12 +102,22 @@ static struct tile * get_transformed_tile_and_call_back( return get_tile_and_call_back(rparams, r.x, r.y); } +struct index_interval +{ + int begin; + int end; +}; + /* +Figures the range of y coordinates we need to iterate over for +the given slopes. Clamps this range to fit in floor bounds. + preconditions: - oparams->dx_min <= oparams->dx_max postconditions: - - result.begin and result.end denote an in-bounds tile sequence corresponding to the requested slope interval + - result.begin and result.end denote an in-bounds tile + sequence corresponding to the requested slope interval */ struct index_interval make_dy_interval( float slope_begin, @@ -122,8 +126,8 @@ struct index_interval make_dy_interval( int dy_max) { struct index_interval dy_interval = { - slope_begin * (dx - 0.5f) - 0.5f, - slope_end * (dx + 0.5f) + 0.5f + slope_begin * (dx - 0.5f) + 0.5f, + slope_end * (dx + 0.5f) - 0.5f }; dy_interval.begin = min(dy_interval.begin, dy_max); dy_interval.end = min(dy_interval.end, dy_max); diff --git a/src/torch.h b/src/torch.h old mode 100755 new mode 100644 From 7ab7e3a36719bc5cb558700a651746111c377d9c Mon Sep 17 00:00:00 2001 From: Ted Stier Date: Fri, 17 Jan 2020 23:21:26 -0500 Subject: [PATCH 06/12] nicer names --- src/demo.c | 10 ++-- src/draw.c | 2 +- src/floor.c | 10 ++-- src/raycast.c | 155 ++++++++++++++++++++++++++------------------------ src/torch.h | 4 +- 5 files changed, 93 insertions(+), 88 deletions(-) diff --git a/src/demo.c b/src/demo.c index 4e8eee6..144d166 100644 --- a/src/demo.c +++ b/src/demo.c @@ -19,7 +19,7 @@ void demo_floor_load_map(const char *filename) floor_map_generate(&floors[0], CAVE); /* Make this not shit please. */ - for (size_t line = 0; line < MAP_ROWS; ++line) { + for (size_t line = 0; line < MAP_LINES; ++line) { for (size_t col = 0; col < MAP_COLS; ++col) { // fscanf(mapfp, "%c", &demo_floor.map[line][col].token); floors[0].map[line][col].light = 0; @@ -38,13 +38,13 @@ void demo_floor_load_map(const char *filename) // fclose(mapfp); for (int i = 0; i < 0; ++i) { - int y = rand() % MAP_ROWS; + int y = rand() % MAP_LINES; int x = rand() % MAP_COLS; demo_place_snake(y, x); } } -int drawn_to[MAP_ROWS][MAP_COLS] = { 0 }; +int drawn_to[MAP_LINES][MAP_COLS] = { 0 }; struct light_info { tile_map *map; @@ -99,7 +99,7 @@ def_entity_fn(demo_player_update) .radius = sqrt(1.f / (1.f / 255)), }); - memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_ROWS * MAP_COLS)); + memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_LINES * MAP_COLS)); } def_entity_fn(demo_torch_update) @@ -120,7 +120,7 @@ def_entity_fn(demo_torch_update) .x = this->posx, .radius = sqrt(1.f / (1.f / 255)) }); - memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_ROWS * MAP_COLS)); + memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_LINES * MAP_COLS)); } def_entity_fn(demo_torch_destroy) diff --git a/src/draw.c b/src/draw.c index 16724b3..ff7e7a5 100644 --- a/src/draw.c +++ b/src/draw.c @@ -110,7 +110,7 @@ struct draw_info { void draw_thing(struct tile *tile, int y, int x, void *context) { struct draw_info * info = context; - int line = y - clamp(player.posy - info->view_lines / 2, 0, MAP_ROWS - info->view_lines); + int line = y - clamp(player.posy - info->view_lines / 2, 0, MAP_LINES - info->view_lines); int col = x - clamp(player.posx - info->view_cols / 2, 0, MAP_COLS - info->view_cols); if (tile->entity) { ui_draw_at(line, col, (struct ui_cell) { diff --git a/src/floor.c b/src/floor.c index 14d5ab1..59c48b5 100644 --- a/src/floor.c +++ b/src/floor.c @@ -5,7 +5,7 @@ #include typedef int cell; -typedef cell cell_grid[MAP_ROWS][MAP_COLS]; +typedef cell cell_grid[MAP_LINES][MAP_COLS]; #define cell_grid_for_each_cell(pos, grid) \ for (pos = *grid; pos != back(grid); ++pos) @@ -40,7 +40,7 @@ static void intern_populate_grid(cell_grid grid, float rate) *pos = 0; } */ - for (int y = 0; y < MAP_ROWS; ++y) { + for (int y = 0; y < MAP_LINES; ++y) { for (int x = 0; x < MAP_COLS; ++x) { if (rand() % 100 / 100.f < rate) grid[y][x] = 1; @@ -53,7 +53,7 @@ static void intern_populate_grid(cell_grid grid, float rate) static void intern_iterate_grid(cell_grid grid, int birth, int survive) { cell_grid new = { 0 }; - for (int y = 0; y < MAP_ROWS; ++y) + for (int y = 0; y < MAP_LINES; ++y) for (int x = 0; x < MAP_COLS; ++x) { int alive = intern_cell_alive_neighbours(grid, y, x); if (grid[y][x]) { @@ -66,7 +66,7 @@ static void intern_iterate_grid(cell_grid grid, int birth, int survive) } // memcpy(new, grid, sizeof(new)); - for (int y = 0; y < MAP_ROWS; ++y) + for (int y = 0; y < MAP_LINES; ++y) for (int x = 0; x < MAP_COLS; ++x) { grid[y][x] = new[y][x]; } @@ -129,7 +129,7 @@ struct tile floor_map_at(struct floor *floor, int y, int x) int floor_map_in_bounds(int y, int x) { - return y >= 0 && y < MAP_ROWS && x >= 0 && x < MAP_COLS; + return y >= 0 && y < MAP_LINES && x >= 0 && x < MAP_COLS; } void floor_map_clear_lights(void) diff --git a/src/raycast.c b/src/raycast.c index a5bbf77..0f76963 100644 --- a/src/raycast.c +++ b/src/raycast.c @@ -8,23 +8,30 @@ Fetches the selected tile, calls back, and returns the selected tile. preconditions: - - rparams->floor points to a valid floor - - rparams->callback points to a valid function + - raycast->floor points to a valid floor + - raycast->callback points to a valid function - (x, y) denotes a tile which is in the floor bounds postconditions: - - rparams->callback is called with the corresponding tile + - raycast->callback is called with the corresponding tile - the result is a pointer to that tile */ static struct tile * get_tile_and_call_back( - const struct raycast_params * rparams, + const struct raycast_params * raycast, int x, int y) { - struct tile * tile = &rparams->floor->map[y][x]; - rparams->callback(tile, y, x, rparams->context); + struct tile * tile = &raycast->floor->map[y][x]; + raycast->callback(tile, y, x, raycast->context); return tile; } +/* +preconditions: + - l and r point to valid integers + +postconditions: + - the values of *l and *r are swapped +*/ void swapi(int * l, int * r) { int t = *l; @@ -39,7 +46,7 @@ struct point }; /* -Transform zeroth octant coordinates into other octants' coordinates. +Transforms zeroth octant coordinates into other octants' coordinates. Diagram of octant layout: @@ -52,23 +59,25 @@ Diagram of octant layout: If first octant bit is set, flip across the diagonal. If second octant bit is set, flip across the vertical. If third octant bit is set, flip across the horizontal. + +wide contract */ static struct point transform_point_to_octant( int x, int y, int dx, int dy, - int octant) + int octant_number) { - if (octant & 1) + if (octant_number & 1) { swapi(&dx, &dy); } - if (octant & 2) + if (octant_number & 2) { dx = -dx; } - if (octant & 4) + if (octant_number & 4) { dy = -dy; } @@ -82,24 +91,24 @@ fetches the selected tile, calls back, and returns the selected tile. preconditions: - - rparams->floor points to a valid floor - - rparams->callback is a valid function pointer + - raycast->floor points to a valid floor + - raycast->callback is a valid function pointer - (dx, dy) denotes a tile which is in the floor bounds postconditions: - - rparams->callback is called with the corresponding tile + - raycast->callback is called with the corresponding tile - the result is a pointer to that tile */ static struct tile * get_transformed_tile_and_call_back( - const struct raycast_params * rparams, + const struct raycast_params * raycast, int dx, int dy, int octant) { struct point r = transform_point_to_octant( - rparams->x, rparams->y, + raycast->x, raycast->y, dx, dy, octant); - return get_tile_and_call_back(rparams, r.x, r.y); + return get_tile_and_call_back(raycast, r.x, r.y); } struct index_interval @@ -112,12 +121,7 @@ struct index_interval Figures the range of y coordinates we need to iterate over for the given slopes. Clamps this range to fit in floor bounds. -preconditions: - - oparams->dx_min <= oparams->dx_max - -postconditions: - - result.begin and result.end denote an in-bounds tile - sequence corresponding to the requested slope interval +wide contract */ struct index_interval make_dy_interval( float slope_begin, @@ -136,7 +140,7 @@ struct index_interval make_dy_interval( struct octant_params { - int octant; + int number; int dx_max; int dy_max; }; @@ -150,15 +154,16 @@ of the column. Exits if there is no such gap. Diagram of zeroth octant: - dx 01234567 dy - @------- 0 `-` = visible tile - ------- 1 `.` = hidden tile - ---!.. 2 `#` = blocking tile - --#.. 3 `@` = centre - --.. 4 `!` = blocking tile where function recurses - --. 5 - -- 6 - - 7 + dx 01234567 dy + + @------- 0 `-` = visible tile + ------- 1 `.` = hidden tile + ---!.. 2 `#` = blocking tile + --#.. 3 `@` = centre + --.. 4 `!` = blocking tile where function recurses + --. 5 + -- 6 + - 7 The algorithm always works in the coordinates of the zeroth octant, then applies a transformation to obtain the actual coordinate of the @@ -190,48 +195,48 @@ Diagram of begin and end slopes: ####### preconditions: - - rparams->floor points to a valid floor - - rparams->callback points to a valid function - - (rparams->x, rparams->y) denotes a tile which is in the floor bounds - - oparams->dx_min <= oparams->dx_max + - raycast->floor points to a valid floor + - raycast->callback points to a valid function + - (raycast->x, raycast->y) denotes a tile which is in the floor bounds + - octant->dx_min <= octant->dx_max - start_slope < end_slope - - the coordinates and bounds in rparams and oparams denote a set of tiles + - the coordinates and bounds in raycast and octant denote a set of tiles which are in the floor bounds postconditions: - - rparams->callback is called at least once for each tile in line of sight - within the octant and oparams->dx_max + - raycast->callback is called at least once for each tile in line of sight + within the octant and octant->dx_max */ static void raycast_octant_at( - const struct raycast_params * rparams, - const struct octant_params * oparams, + const struct raycast_params * raycast, + const struct octant_params * octant, int dx, float start_slope, float end_slope) { bool blocked = false; - for (; dx <= oparams->dx_max && !blocked; ++dx) + for (; dx <= octant->dx_max && !blocked; ++dx) { struct index_interval dy_interval = make_dy_interval( start_slope, end_slope, dx, - oparams->dy_max); + octant->dy_max); int dy = dy_interval.begin; struct tile * tile = get_transformed_tile_and_call_back( - rparams, + raycast, dx, dy, - oparams->octant); + octant->number); blocked = tile_blocks_light(tile); for (++dy; dy <= dy_interval.end; ++dy) { tile = get_transformed_tile_and_call_back( - rparams, + raycast, dx, dy, - oparams->octant); + octant->number); if (blocked && !tile_blocks_light(tile)) { blocked = false; @@ -239,8 +244,8 @@ static void raycast_octant_at( } else if (!blocked && tile_blocks_light(tile)) { blocked = true; raycast_octant_at( - rparams, - oparams, + raycast, + octant, dx + 1, start_slope, (dy - 0.5f) / (dx + 0.5f)); @@ -253,53 +258,53 @@ static void raycast_octant_at( which divides the map into eight congruent triangular octants, and calculates each octant individually. - Casts on the origin, then enters the recursive functions for each octant. + Casts on the origin, then kicks off the recursive functions for each octant. preconditions: - - rparams->floor points to a valid floor - - rparams->callback points to a valid function - - (rparams->x, rparams->y) denotes a tile which is in the floor bounds - - the coordinates and bounds in rparams and oparams denote a set of tiles + - raycast->floor points to a valid floor + - raycast->callback points to a valid function + - (raycast->x, raycast->y) denotes a tile which is in the floor bounds + - the coordinates and bounds in raycast and octant denote a set of tiles which are in the floor bounds postconditions: - - rparams->callback is called at least once for each tile in rparams->radius + - raycast->callback is called at least once for each tile in raycast->radius and line of sight notes: - may call back for cells outside the requested radius. - may call back multiple times for cells along axes and diagonals. */ -void raycast_at(const struct raycast_params * rparams) +void raycast_at(const struct raycast_params * raycast) { - get_tile_and_call_back(rparams, rparams->x, rparams->y); + get_tile_and_call_back(raycast, raycast->x, raycast->y); const int dx_max[] = { - min(rparams->radius, MAP_COLS - rparams->x - 1), - min(rparams->radius, MAP_ROWS - rparams->y - 1), - min(rparams->radius, rparams->x ), - min(rparams->radius, MAP_ROWS - rparams->y - 1), - min(rparams->radius, MAP_COLS - rparams->x - 1), - min(rparams->radius, rparams->y ), - min(rparams->radius, rparams->x ), - min(rparams->radius, rparams->y ), + min(raycast->radius, MAP_COLS - raycast->x - 1), + min(raycast->radius, MAP_LINES - raycast->y - 1), + min(raycast->radius, raycast->x ), + min(raycast->radius, MAP_LINES - raycast->y - 1), + min(raycast->radius, MAP_COLS - raycast->x - 1), + min(raycast->radius, raycast->y ), + min(raycast->radius, raycast->x ), + min(raycast->radius, raycast->y ), }; const int dy_max[] = { - MAP_ROWS - rparams->y - 1, - MAP_COLS - rparams->x - 1, - MAP_ROWS - rparams->y - 1, - rparams->x , - rparams->y , - MAP_COLS - rparams->x - 1, - rparams->y , - rparams->x , + MAP_LINES - raycast->y - 1, + MAP_COLS - raycast->x - 1, + MAP_LINES - raycast->y - 1, + raycast->x , + raycast->y , + MAP_COLS - raycast->x - 1, + raycast->y , + raycast->x , }; for (int octant = 0; octant < 8; octant++) { raycast_octant_at( - rparams, + raycast, &(struct octant_params) { .octant = octant, .dx_max = dx_max[octant], diff --git a/src/torch.h b/src/torch.h index 32357f8..80eb882 100644 --- a/src/torch.h +++ b/src/torch.h @@ -81,10 +81,10 @@ struct tile { bool tile_blocks_light(struct tile const *); -#define MAP_ROWS 100 +#define MAP_LINES 100 #define MAP_COLS 100 -typedef struct tile tile_map[MAP_ROWS][MAP_COLS]; +typedef struct tile tile_map[MAP_LINES][MAP_COLS]; typedef struct list_head entity_list; struct floor { From e0854a840fd98c8d64224a1bc0856d99b942b694 Mon Sep 17 00:00:00 2001 From: Ted Stier Date: Sat, 18 Jan 2020 00:22:35 -0500 Subject: [PATCH 07/12] added .clang-format --- .clang-format | 92 +++++++++++ src/color.c | 13 +- src/demo.c | 93 +++++------ src/draw.c | 45 +++--- src/entity.c | 6 +- src/floor.c | 102 +++++-------- src/player.c | 29 ++-- src/raycast.c | 415 ++++++++++++++++++++++---------------------------- src/torch.c | 8 +- src/torch.h | 34 ++--- src/ui.h | 19 +-- src/ui/term.c | 1 + 12 files changed, 420 insertions(+), 437 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..079344d --- /dev/null +++ b/.clang-format @@ -0,0 +1,92 @@ +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignConsecutiveMacros: false +AlignEscapedNewlines: Right +AlignTrailingComments: true +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Always +AllowShortLambdasOnASingleLine: None +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakBeforeBinaryOperators: All +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: AfterColon +BreakInheritanceList: AfterColon +BreakStringLiterals: true +ColumnLimit: 120 +CompactNamespaces: true +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: true +FixNamespaceComments: false +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '".*"' + Priority: 1 + - Regex: '<[a-zA-Z0-9.]*>' + Priority: 2 +IndentCaseLabels: false +IndentPPDirectives: BeforeHash +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: Inner +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortUsingDeclarations : true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 4 +UseTab: ForContinuationAndIndentation \ No newline at end of file diff --git a/src/color.c b/src/color.c index 1373d35..0f75f2b 100644 --- a/src/color.c +++ b/src/color.c @@ -2,26 +2,23 @@ #include -struct color color_add(struct color c, struct color a) -{ - return (struct color){ +struct color color_add(struct color c, struct color a) { + return (struct color) { min(c.r + a.r, 255), min(c.g + a.g, 255), min(c.b + a.b, 255), }; } -struct color color_multiply_by(struct color c, float m) -{ - return (struct color){ +struct color color_multiply_by(struct color c, float m) { + return (struct color) { min(c.r * m, 255), min(c.g * m, 255), min(c.b * m, 255), }; } -int color_approximate_256(struct color c) -{ +int color_approximate_256(struct color c) { /* L. */ return rand() % 256; } diff --git a/src/demo.c b/src/demo.c index 144d166..43ed8a2 100644 --- a/src/demo.c +++ b/src/demo.c @@ -1,29 +1,28 @@ #include "torch.h" #include "ui.h" -#include -#include #include #include #include +#include #include +#include struct floor *cur_floor = &floors[0]; struct entity demo_new_snake(int y, int x); void demo_place_snake(int y, int x); -void demo_floor_load_map(const char *filename) -{ -// FILE *mapfp = fopen(filename, "r"); +void demo_floor_load_map(const char *filename) { + // FILE *mapfp = fopen(filename, "r"); floor_map_generate(&floors[0], CAVE); /* Make this not shit please. */ for (size_t line = 0; line < MAP_LINES; ++line) { for (size_t col = 0; col < MAP_COLS; ++col) { -// fscanf(mapfp, "%c", &demo_floor.map[line][col].token); + // fscanf(mapfp, "%c", &demo_floor.map[line][col].token); floors[0].map[line][col].light = 0; - floors[0].map[line][col].color = (struct color){ 51, 51, 51 }; + floors[0].map[line][col].color = (struct color) { 51, 51, 51 }; #if 0 if (demo_floor.map[line][col].token != '.') { @@ -32,12 +31,12 @@ void demo_floor_load_map(const char *filename) } #endif } -// (void)fgetc(mapfp); + // (void)fgetc(mapfp); } -// fclose(mapfp); + // fclose(mapfp); - for (int i = 0; i < 0; ++i) { + for (int i = 0; i < 20; ++i) { int y = rand() % MAP_LINES; int x = rand() % MAP_COLS; demo_place_snake(y, x); @@ -55,10 +54,8 @@ struct light_info { #include -void cast_light_at(struct tile *tile, int y, int x, void *context) -{ - if (drawn_to[y][x]) - return; +void cast_light_at(struct tile *tile, int y, int x, void *context) { + if (drawn_to[y][x]) return; struct light_info *info = context; drawn_to[y][x] = 1; int distance = sqrt(pow(y - info->y, 2) + pow(x - info->x, 2)); @@ -67,14 +64,13 @@ void cast_light_at(struct tile *tile, int y, int x, void *context) (*info->map)[y][x].light += info->bright; } else { (*info->map)[y][x].light += dlight; -// assert((*info->map)[y][x].light > 0); + // assert((*info->map)[y][x].light > 0); /* = info->r * dlight + tile.dcolor */ (*info->map)[y][x].dcolor = color_add(color_multiply_by(info->color, dlight), tile->dcolor); } } -def_entity_fn(demo_player_update) -{ +def_entity_fn(demo_player_update) { float bright = player_lantern_on && player_fuel > 0 ? 0.5f : 0.1f; if (player_lantern_on) { if (player_fuel > 0) { @@ -84,29 +80,29 @@ def_entity_fn(demo_player_update) } } - //cast_light(this->floor->map, y, x, 6, 0.3f, this->r, this->g, this->b); + // cast_light(this->floor->map, y, x, 6, 0.3f, this->r, this->g, this->b); raycast_at(&(struct raycast_params) { .callback = &cast_light_at, .context = &(struct light_info) { .map = &this->floor->map, - .bright = bright, .y = this->posy, .x = this->posx, - .color = this->color - }, + .bright = bright, + .y = this->posy, + .x = this->posx, + .color = this->color }, .floor = this->floor, .y = this->posy, .x = this->posx, - .radius = sqrt(1.f / (1.f / 255)), + .radius = sqrt(255.0f), }); memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_LINES * MAP_COLS)); } -def_entity_fn(demo_torch_update) -{ +def_entity_fn(demo_torch_update) { // entity_move_pos_rel(this, y, x); - //cast_light(this->floor->map, y, x, 6, 1.f, this->r, this->g, this->b); + // cast_light(this->floor->map, y, x, 6, 1.f, this->r, this->g, this->b); raycast_at(&(struct raycast_params) { .callback = &cast_light_at, @@ -118,18 +114,15 @@ def_entity_fn(demo_torch_update) .floor = this->floor, .y = this->posy, .x = this->posx, - .radius = sqrt(1.f / (1.f / 255)) + .radius = 15 }); memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_LINES * MAP_COLS)); } -def_entity_fn(demo_torch_destroy) -{ - +def_entity_fn(demo_torch_destroy) { } -void demo_add_entities(void) -{ +void demo_add_entities(void) { #if 0 struct entity torch = { .r = 0xe2, .g = /*0x58*/0, .b = 0x22, @@ -171,11 +164,12 @@ void demo_add_entities(void) #endif } -struct entity demo_new_torch(int y, int x) -{ +struct entity demo_new_torch(int y, int x) { struct entity torch = { .color = { - .r = 0xe2, .g = 0x58, .b = 0x22, + .r = 0xe2, + .g = 0x58, + .b = 0x22, }, .token = '!', .posy = y, .posx = x, @@ -189,10 +183,8 @@ struct entity demo_new_torch(int y, int x) return torch; } -def_input_key_fn(place_torch) -{ - if (!player_torches) - return 0; +def_input_key_fn(place_torch) { + if (!player_torches) return 0; player_torches--; int y = player.posy; int x = player.posx; @@ -209,37 +201,31 @@ def_input_key_fn(place_torch) return floor_add_entity(cur_floor, t); } -def_input_key_fn(demo_get_fuel) -{ +def_input_key_fn(demo_get_fuel) { player_fuel += 10; return 0; } -void demo_place_snake(int y, int x) -{ +void demo_place_snake(int y, int x) { struct entity snake = demo_new_snake(y, x); struct entity *s = malloc(sizeof(snake)); memcpy(s, &snake, sizeof(snake)); floor_add_entity(&floors[0], s); } -def_entity_fn(demo_snake_update) -{ +def_entity_fn(demo_snake_update) { int y = 0; int x = 0; - if (this->posy < player.posy) - y = 1; + if (this->posy < player.posy) y = 1; else if (this->posy > player.posy) y = -1; - if (this->posx < player.posx) - x = 1; + if (this->posx < player.posx) x = 1; else if (this->posx > player.posx) x = -1; entity_move_pos_rel(this, y, x); - if (floor_map_at(this->floor, this->posy, this->posx).light > 0.2) - entity_move_pos_rel(this, -y, -x); + if (floor_map_at(this->floor, this->posy, this->posx).light > 0.2) entity_move_pos_rel(this, -y, -x); if (abs(this->posy - player.posy) == 1 && abs(this->posx - player.posx) == 1) { ui_clear(); ui_flush(); @@ -249,11 +235,12 @@ def_entity_fn(demo_snake_update) } } -struct entity demo_new_snake(int y, int x) -{ +struct entity demo_new_snake(int y, int x) { struct entity snake = { .color = { - .r = 0xa, .g = 0xCA, .b = 0xa, + .r = 0xa, + .g = 0xCA, + .b = 0xa, }, .token = 's', .posy = y, .posx = x, diff --git a/src/draw.c b/src/draw.c index ff7e7a5..76cdd87 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1,8 +1,8 @@ #include "torch.h" #include "ui.h" -#include #include +#include #if 0 static int visibility[MAP_LINES][MAP_COLS] = { 0 }; @@ -39,8 +39,7 @@ void draw_map(void) .r = 0, .g = 0, .b = 0, }, }); - } - else { + } else { ui_draw_at(line, col, (struct ui_cell) { .codepoint = " ", .fg = { @@ -107,49 +106,45 @@ struct draw_info { int view_lines, view_cols; }; -void draw_thing(struct tile *tile, int y, int x, void *context) -{ - struct draw_info * info = context; +void draw_thing(struct tile *tile, int y, int x, void *context) { + struct draw_info *info = context; int line = y - clamp(player.posy - info->view_lines / 2, 0, MAP_LINES - info->view_lines); int col = x - clamp(player.posx - info->view_cols / 2, 0, MAP_COLS - info->view_cols); if (tile->entity) { - ui_draw_at(line, col, (struct ui_cell) { - .codepoint = { [0] = tile->entity->token }, + ui_draw_at(line, + col, + (struct ui_cell) { + .codepoint = { [0] = tile->entity->token }, /* = tile.entity->color * tile.light + tile.dcolor */ .fg = color_add(color_multiply_by(tile->entity->color, tile->light), tile->dcolor), .bg = { 0, 0, 0 }, - }); - } - else { - ui_draw_at(line, col, (struct ui_cell) { - .codepoint = { [0] = tile->token }, + }); + } else { + ui_draw_at(line, + col, + (struct ui_cell) { + .codepoint = { [0] = tile->token }, /* = tile.color * tile.light + tile.dcolor */ .fg = color_add(color_multiply_by(tile->color, tile->light), tile->dcolor), .bg = { 0, 0, 0 }, - }); + }); } } -void draw_shit(void) -{ +void draw_shit(void) { int view_lines, view_cols; ui_dimensions(&view_lines, &view_cols); - raycast_at( - &(struct raycast_params) { + raycast_at(&(struct raycast_params) { .callback = &draw_thing, - .context = &(struct draw_info) { - .view_lines = view_lines, - .view_cols = view_cols - }, + .context = &(struct draw_info) { .view_lines = view_lines, .view_cols = view_cols }, .floor = cur_floor, .y = player.posy, .x = player.posx, - .radius = max(view_lines, view_cols) / 2 - }); + .radius = max(view_lines, view_cols) / 2 }); size_t needed = snprintf(NULL, 0, "%3d %3d", player_fuel, player_torches) + 1; - char * buf = malloc(needed); + char *buf = malloc(needed); sprintf(buf, "%3d %3d", player_fuel, player_torches); ui_draw_str_at(1, 0, buf, (struct ui_cell) { .fg = { 0xe2, 0x58, 0x22 } }); diff --git a/src/entity.c b/src/entity.c index c5c54a0..e856ca6 100644 --- a/src/entity.c +++ b/src/entity.c @@ -1,7 +1,6 @@ #include "torch.h" -int entity_move_pos(struct entity *entity, int y, int x) -{ +int entity_move_pos(struct entity *entity, int y, int x) { struct tile tile = floor_map_at(entity->floor, y, x); if (floor_map_in_bounds(y, x) && !tile.entity && tile.walk) { /* Slightly dangerous raw access. */ @@ -15,7 +14,6 @@ int entity_move_pos(struct entity *entity, int y, int x) return -1; } -int entity_move_pos_rel(struct entity *entity, int y, int x) -{ +int entity_move_pos_rel(struct entity *entity, int y, int x) { return entity_move_pos(entity, entity->posy + y, entity->posx + x); } diff --git a/src/floor.c b/src/floor.c index 59c48b5..690ce58 100644 --- a/src/floor.c +++ b/src/floor.c @@ -1,5 +1,5 @@ -#include "torch.h" #include "list.h" +#include "torch.h" #include #include @@ -7,8 +7,7 @@ typedef int cell; typedef cell cell_grid[MAP_LINES][MAP_COLS]; -#define cell_grid_for_each_cell(pos, grid) \ - for (pos = *grid; pos != back(grid); ++pos) +#define cell_grid_for_each_cell(pos, grid) for (pos = *grid; pos != back(grid); ++pos) static void intern_populate_grid(cell_grid grid, float rate); static void intern_iterate_grid(cell_grid grid, int birth, int survive); @@ -17,8 +16,7 @@ static int intern_cell_grid_at(cell_grid grid, int y, int x); static void intern_floor_write_grid(struct floor *floor, cell_grid grid); -void floor_map_generate(struct floor *floor, enum floor_type type) -{ +void floor_map_generate(struct floor *floor, enum floor_type type) { cell_grid grid = { 0 }; intern_populate_grid(grid, 0.45f); @@ -26,62 +24,56 @@ void floor_map_generate(struct floor *floor, enum floor_type type) intern_iterate_grid(grid, 4, 5); } - intern_floor_write_grid(floor, grid); + intern_floor_write_grid(floor, grid); } -static void intern_populate_grid(cell_grid grid, float rate) -{ -/* - cell *pos; - cell_grid_for_each_cell(pos, grid) { - if (rand() % 100 / 100.f < rate) - *pos = 1; - else - *pos = 0; - } -*/ +static void intern_populate_grid(cell_grid grid, float rate) { + /* + cell *pos; + cell_grid_for_each_cell(pos, grid) { + if (rand() % 100 / 100.f < rate) + *pos = 1; + else + *pos = 0; + } + */ for (int y = 0; y < MAP_LINES; ++y) { for (int x = 0; x < MAP_COLS; ++x) { - if (rand() % 100 / 100.f < rate) - grid[y][x] = 1; + if (rand() % 100 / 100.f < rate) grid[y][x] = 1; else grid[y][x] = 0; }; } } -static void intern_iterate_grid(cell_grid grid, int birth, int survive) -{ +static void intern_iterate_grid(cell_grid grid, int birth, int survive) { cell_grid new = { 0 }; for (int y = 0; y < MAP_LINES; ++y) for (int x = 0; x < MAP_COLS; ++x) { int alive = intern_cell_alive_neighbours(grid, y, x); if (grid[y][x]) { - if (alive >= survive) - new[y][x] = 1; + if (alive >= survive) new[y][x] = 1; } else { - if (alive >= birth) - new[y][x] = 1; + if (alive >= birth) new[y][x] = 1; } } -// memcpy(new, grid, sizeof(new)); + // memcpy(new, grid, sizeof(new)); for (int y = 0; y < MAP_LINES; ++y) for (int x = 0; x < MAP_COLS; ++x) { grid[y][x] = new[y][x]; } } -static int intern_cell_alive_neighbours(cell_grid grid, int y, int x) -{ +static int intern_cell_alive_neighbours(cell_grid grid, int y, int x) { int alive = 0; -/* - for (int i = -1; i < 2; ++i) - for (int j = -1; j < 2; ++j) { - if (i != 0 && j != 0 && grid[y + i][x + j]) - alive++; - } -*/ + /* + for (int i = -1; i < 2; ++i) + for (int j = -1; j < 2; ++j) { + if (i != 0 && j != 0 && grid[y + i][x + j]) + alive++; + } + */ intern_cell_grid_at(grid, y - 1, x - 1) ? alive++ : 0; intern_cell_grid_at(grid, y - 1, x) ? alive++ : 0; @@ -91,20 +83,17 @@ static int intern_cell_alive_neighbours(cell_grid grid, int y, int x) intern_cell_grid_at(grid, y + 1, x - 1) ? alive++ : 0; intern_cell_grid_at(grid, y + 1, x) ? alive++ : 0; intern_cell_grid_at(grid, y + 1, x + 1) ? alive++ : 0; - + return alive; } -static int intern_cell_grid_at(cell_grid grid, int y, int x) -{ - if (floor_map_in_bounds(y, x)) - return grid[y][x]; +static int intern_cell_grid_at(cell_grid grid, int y, int x) { + if (floor_map_in_bounds(y, x)) return grid[y][x]; else return 1; } -static void intern_floor_write_grid(struct floor *floor, cell_grid grid) -{ +static void intern_floor_write_grid(struct floor *floor, cell_grid grid) { struct tile *t; cell *c = *grid; floor_for_each_tile(t, floor) { @@ -119,21 +108,17 @@ static void intern_floor_write_grid(struct floor *floor, cell_grid grid) } } -struct tile floor_map_at(struct floor *floor, int y, int x) -{ - if (floor_map_in_bounds(y, x)) - return (floor->map)[y][x]; +struct tile floor_map_at(struct floor *floor, int y, int x) { + if (floor_map_in_bounds(y, x)) return (floor->map)[y][x]; else - return (struct tile){ .token = ' ' }; + return (struct tile) { .token = ' ' }; } -int floor_map_in_bounds(int y, int x) -{ +int floor_map_in_bounds(int y, int x) { return y >= 0 && y < MAP_LINES && x >= 0 && x < MAP_COLS; } -void floor_map_clear_lights(void) -{ +void floor_map_clear_lights(void) { struct tile *pos; floor_for_each_tile(pos, cur_floor) { pos->light = 0; @@ -143,26 +128,21 @@ void floor_map_clear_lights(void) } } -int floor_add_entity(struct floor *floor, struct entity *entity) -{ - if (floor->map[entity->posy][entity->posx].entity) - return -1; +int floor_add_entity(struct floor *floor, struct entity *entity) { + if (floor->map[entity->posy][entity->posx].entity) return -1; list_add(&entity->list, &floor->entities); entity->floor = floor; floor->map[entity->posy][entity->posx].entity = entity; return 0; } -void floor_update_entities(struct floor *floor) -{ +void floor_update_entities(struct floor *floor) { struct entity *pos; list_for_each_entry(pos, &floor->entities, list) { - if (pos->update) - pos->update(pos); + if (pos->update) pos->update(pos); } } -bool tile_blocks_light(const struct tile * tile) -{ +bool tile_blocks_light(const struct tile *tile) { return !tile->walk || (tile->entity && tile->entity->blocks_light); } diff --git a/src/player.c b/src/player.c index feeb412..ac103f2 100644 --- a/src/player.c +++ b/src/player.c @@ -1,5 +1,5 @@ -#include "torch.h" #include "list.h" +#include "torch.h" #include @@ -19,48 +19,39 @@ bool player_lantern_on = false; int player_fuel = 100; int player_torches = 'z'; -def_input_key_fn(player_move_left) -{ +def_input_key_fn(player_move_left) { return entity_move_pos_rel(&player, 0, -1); } -def_input_key_fn(player_move_down) -{ +def_input_key_fn(player_move_down) { return entity_move_pos_rel(&player, 1, 0); } -def_input_key_fn(player_move_up) -{ +def_input_key_fn(player_move_up) { return entity_move_pos_rel(&player, -1, 0); } -def_input_key_fn(player_move_right) -{ +def_input_key_fn(player_move_right) { return entity_move_pos_rel(&player, 0, 1); } -def_input_key_fn(player_move_upleft) -{ +def_input_key_fn(player_move_upleft) { return entity_move_pos_rel(&player, -1, -1); } -def_input_key_fn(player_move_upright) -{ +def_input_key_fn(player_move_upright) { return entity_move_pos_rel(&player, -1, 1); } -def_input_key_fn(player_move_downleft) -{ +def_input_key_fn(player_move_downleft) { return entity_move_pos_rel(&player, 1, -1); } -def_input_key_fn(player_move_downright) -{ +def_input_key_fn(player_move_downright) { return entity_move_pos_rel(&player, 1, 1); } -def_input_key_fn(player_toggle_lantern) -{ +def_input_key_fn(player_toggle_lantern) { player_lantern_on = !player_lantern_on; return 0; } diff --git a/src/raycast.c b/src/raycast.c index 0f76963..2ff5f59 100644 --- a/src/raycast.c +++ b/src/raycast.c @@ -1,317 +1,262 @@ #include "torch.h" -#include #include +#include /* -Fetches the selected tile, calls back, and returns -the selected tile. - -preconditions: - - raycast->floor points to a valid floor - - raycast->callback points to a valid function - - (x, y) denotes a tile which is in the floor bounds - -postconditions: - - raycast->callback is called with the corresponding tile - - the result is a pointer to that tile -*/ -static struct tile * get_tile_and_call_back( - const struct raycast_params * raycast, - int x, int y) -{ - struct tile * tile = &raycast->floor->map[y][x]; + * Fetches the selected tile, calls back, and returns + * the selected tile. + * + * preconditions: + * - raycast->floor points to a valid floor + * - raycast->callback points to a valid function + * - (x, y) denotes a tile which is in the floor bounds + * + * postconditions: + * - raycast->callback is called with the corresponding tile + * - the result is a pointer to that tile + */ +static struct tile *get_tile_and_call_back(const struct raycast_params *raycast, int x, int y) { + struct tile *tile = &raycast->floor->map[y][x]; raycast->callback(tile, y, x, raycast->context); return tile; } /* -preconditions: - - l and r point to valid integers - -postconditions: - - the values of *l and *r are swapped -*/ -void swapi(int * l, int * r) -{ + * preconditions: + * - l and r point to valid integers + * + * postconditions: + * - the values of *l and *r are swapped + */ +void swapi(int *l, int *r) { int t = *l; *l = *r; *r = t; } -struct point -{ +struct point { int x; int y; }; /* -Transforms zeroth octant coordinates into other octants' coordinates. - -Diagram of octant layout: - - \ 7 | 5 / - 6 \ | / 4 - - - - - - - 2 / | \ 0 - / 3 | 1 \ - -If first octant bit is set, flip across the diagonal. -If second octant bit is set, flip across the vertical. -If third octant bit is set, flip across the horizontal. - -wide contract -*/ -static struct point transform_point_to_octant( - int x, - int y, - int dx, - int dy, - int octant_number) -{ - if (octant_number & 1) - { + * Transforms zeroth octant coordinates into other octants' coordinates. + * + * Diagram of octant layout: + * + * \ 7 | 5 / + * 6 \ | / 4 + * - - - - - + * 2 / | \ 0 + * / 3 | 1 \ + * + * If first octant bit is set, flip across the diagonal. + * If second octant bit is set, flip across the vertical. + * If third octant bit is set, flip across the horizontal. + * + * wide contract + */ +static struct point transform_point_to_octant(int x, int y, int dx, int dy, int octant_number) { + if (octant_number & 1) { swapi(&dx, &dy); } - if (octant_number & 2) - { + if (octant_number & 2) { dx = -dx; } - if (octant_number & 4) - { + if (octant_number & 4) { dy = -dy; } - return (struct point){ x + dx, y + dy }; + return (struct point) { x + dx, y + dy }; } /* -Transforms the coordinates according to the octant, -fetches the selected tile, calls back, and returns -the selected tile. - -preconditions: - - raycast->floor points to a valid floor - - raycast->callback is a valid function pointer - - (dx, dy) denotes a tile which is in the floor bounds - -postconditions: - - raycast->callback is called with the corresponding tile - - the result is a pointer to that tile -*/ -static struct tile * get_transformed_tile_and_call_back( - const struct raycast_params * raycast, - int dx, int dy, - int octant) -{ - struct point r = transform_point_to_octant( - raycast->x, raycast->y, - dx, dy, - octant); + * Transforms the coordinates according to the octant, + * fetches the selected tile, calls back, and returns + * the selected tile. + * + * preconditions: + * - raycast->floor points to a valid floor + * - raycast->callback is a valid function pointer + * - (dx, dy) denotes a tile which is in the floor bounds + * + * postconditions: + * - raycast->callback is called with the corresponding tile + * - the result is a pointer to that tile + */ +static struct tile * +get_transformed_tile_and_call_back(const struct raycast_params *raycast, int dx, int dy, int octant) { + struct point r = transform_point_to_octant(raycast->x, raycast->y, dx, dy, octant); return get_tile_and_call_back(raycast, r.x, r.y); } -struct index_interval -{ +struct index_interval { int begin; int end; }; /* -Figures the range of y coordinates we need to iterate over for -the given slopes. Clamps this range to fit in floor bounds. - -wide contract -*/ -struct index_interval make_dy_interval( - float slope_begin, - float slope_end, - int dx, - int dy_max) -{ - struct index_interval dy_interval = { - slope_begin * (dx - 0.5f) + 0.5f, - slope_end * (dx + 0.5f) - 0.5f - }; + * Figures the range of y coordinates we need to iterate over for + * the given slopes. Clamps this range to fit in floor bounds. + * + * wide contract + */ +struct index_interval make_dy_interval(float slope_begin, float slope_end, int dx, int dy_max) { + struct index_interval dy_interval = { slope_begin * (dx - 0.5f) + 0.5f, slope_end * (dx + 0.5f) - 0.5f }; dy_interval.begin = min(dy_interval.begin, dy_max); dy_interval.end = min(dy_interval.end, dy_max); return dy_interval; } -struct octant_params -{ +struct octant_params { int number; int dx_max; int dy_max; }; /* -Accepts slopes corresponding a gap between blocking tiles. -Iterates through columns from left to right, then through each -tile,top to bottom, of the gap, searching for deeper gaps. -Recurses in each gap except those enclosed by the last tile -of the column. Exits if there is no such gap. - -Diagram of zeroth octant: - - dx 01234567 dy - - @------- 0 `-` = visible tile - ------- 1 `.` = hidden tile - ---!.. 2 `#` = blocking tile - --#.. 3 `@` = centre - --.. 4 `!` = blocking tile where function recurses - --. 5 - -- 6 - - 7 - -The algorithm always works in the coordinates of the zeroth octant, -then applies a transformation to obtain the actual coordinate of the -selected tile. - -As a column is iterated: - -If the previous tile blocks light, but the current tile does not, we have -encountered the beginning of a gap. If the previous tile allows light, but -the current tile does not, we have encountered the end of the gap, and we recurse. - -Each time we encounter any such bound, we calculate the slope of the associated -point on the tile. Slopes for beginnings of regions correspond to bottom left points -of tiles. Slopes for ends of regions correspond to top right points of tiles. -Those slopes are used in next recursion or iteration. - -Diagram of begin and end slopes: - - @xxxxxx - xxxxxxxxx ####### - xxx xxxxxx####### begin - xxx ------- - xxx ------- - xxx------- - xxx---- - ---xxx- - ------x end - ####### - ####### - -preconditions: - - raycast->floor points to a valid floor - - raycast->callback points to a valid function - - (raycast->x, raycast->y) denotes a tile which is in the floor bounds - - octant->dx_min <= octant->dx_max - - start_slope < end_slope - - the coordinates and bounds in raycast and octant denote a set of tiles - which are in the floor bounds - -postconditions: - - raycast->callback is called at least once for each tile in line of sight - within the octant and octant->dx_max -*/ -static void raycast_octant_at( - const struct raycast_params * raycast, - const struct octant_params * octant, + * Accepts slopes corresponding a gap between blocking tiles. + * Iterates through columns from left to right, then through each + * tile,top to bottom, of the gap, searching for deeper gaps. + * Recurses in each gap except those enclosed by the last tile + * of the column. Exits if there is no such gap. + * + * Diagram of zeroth octant: + * + * dx 01234567 dy + * + * @------- 0 `-` = visible tile + * ------- 1 `.` = hidden tile + * ---!.. 2 `#` = blocking tile + * --#.. 3 `@` = centre + * --.. 4 `!` = blocking tile where function recurses + * --. 5 + * -- 6 + * - 7 + * + * The algorithm always works in the coordinates of the zeroth octant, + * then applies a transformation to obtain the actual coordinate of the + * selected tile. + * + * As a column is iterated: + * + * If the previous tile blocks light, but the current tile does not, we have + * encountered the beginning of a gap. If the previous tile allows light, but + * the current tile does not, we have encountered the end of the gap, and we recurse. + * + * Each time we encounter any such bound, we calculate the slope of the associated + * point on the tile. Slopes for beginnings of regions correspond to bottom left points + * of tiles. Slopes for ends of regions correspond to top right points of tiles. + * Those slopes are used in next recursion or iteration. + * + * Diagram of begin and end slopes: + * + * @xxxxxx + * xxxxxxxxx ####### + * xxx xxxxxx####### begin + * xxx ------- + * xxx ------- + * xxx------- + * xxx---- + * ---xxx- + * ------x end + * ####### + * ####### + * + * preconditions: + * - raycast->floor points to a valid floor + * - raycast->callback points to a valid function + * - (raycast->x, raycast->y) denotes a tile which is in the floor bounds + * - octant->dx_min <= octant->dx_max + * - start_slope < end_slope + * - the coordinates and bounds in raycast and octant denote a set of tiles + * which are in the floor bounds + * + * postconditions: + * - raycast->callback is called at least once for each tile in line of sight + * within the octant and octant->dx_max + */ +static void raycast_octant_at(const struct raycast_params *raycast, + const struct octant_params *octant, int dx, float start_slope, - float end_slope) -{ + float end_slope) { bool blocked = false; - for (; dx <= octant->dx_max && !blocked; ++dx) - { - struct index_interval dy_interval = make_dy_interval( - start_slope, - end_slope, - dx, - octant->dy_max); + for (; dx <= octant->dx_max && !blocked; ++dx) { + struct index_interval dy_interval = make_dy_interval(start_slope, end_slope, dx, octant->dy_max); - int dy = dy_interval.begin; + int dy = dy_interval.begin; - struct tile * tile = get_transformed_tile_and_call_back( - raycast, - dx, dy, - octant->number); + struct tile *tile = get_transformed_tile_and_call_back(raycast, dx, dy, octant->number); blocked = tile_blocks_light(tile); for (++dy; dy <= dy_interval.end; ++dy) { - tile = get_transformed_tile_and_call_back( - raycast, - dx, dy, - octant->number); + tile = get_transformed_tile_and_call_back(raycast, dx, dy, octant->number); if (blocked && !tile_blocks_light(tile)) { blocked = false; start_slope = (dy - 0.5f) / (dx - 0.5f); } else if (!blocked && tile_blocks_light(tile)) { blocked = true; - raycast_octant_at( - raycast, - octant, - dx + 1, - start_slope, - (dy - 0.5f) / (dx + 0.5f)); + raycast_octant_at(raycast, octant, dx + 1, start_slope, (dy - 0.5f) / (dx + 0.5f)); } } } } /* Uses a modified version ofBjörn Bergström's Recursive Shadowcasting Algorithm, - which divides the map into eight congruent triangular octants, and calculates - each octant individually. - - Casts on the origin, then kicks off the recursive functions for each octant. - -preconditions: - - raycast->floor points to a valid floor - - raycast->callback points to a valid function - - (raycast->x, raycast->y) denotes a tile which is in the floor bounds - - the coordinates and bounds in raycast and octant denote a set of tiles - which are in the floor bounds - -postconditions: - - raycast->callback is called at least once for each tile in raycast->radius - and line of sight - -notes: - - may call back for cells outside the requested radius. - - may call back multiple times for cells along axes and diagonals. -*/ -void raycast_at(const struct raycast_params * raycast) -{ + * which divides the map into eight congruent triangular octants, and calculates + * each octant individually. + * + * Casts on the origin, then kicks off the recursive functions for each octant. + * + * preconditions: + * - raycast->floor points to a valid floor + * - raycast->callback points to a valid function + * - (raycast->x, raycast->y) denotes a tile which is in the floor bounds + * - the coordinates and bounds in raycast and octant denote a set of tiles + * which are in the floor bounds + * + * postconditions: + * - raycast->callback is called at least once for each tile in raycast->radius + * and line of sight + * + * notes: + * - may call back for cells outside the requested radius. + * - may call back multiple times for cells along axes and diagonals. + */ +void raycast_at(const struct raycast_params *raycast) { get_tile_and_call_back(raycast, raycast->x, raycast->y); const int dx_max[] = { - min(raycast->radius, MAP_COLS - raycast->x - 1), - min(raycast->radius, MAP_LINES - raycast->y - 1), - min(raycast->radius, raycast->x ), - min(raycast->radius, MAP_LINES - raycast->y - 1), - min(raycast->radius, MAP_COLS - raycast->x - 1), - min(raycast->radius, raycast->y ), - min(raycast->radius, raycast->x ), - min(raycast->radius, raycast->y ), + min(raycast->radius, MAP_COLS - raycast->x - 1), + min(raycast->radius, MAP_LINES - raycast->y - 1), + min(raycast->radius, raycast->x), + min(raycast->radius, MAP_LINES - raycast->y - 1), + min(raycast->radius, MAP_COLS - raycast->x - 1), + min(raycast->radius, raycast->y), + min(raycast->radius, raycast->x), + min(raycast->radius, raycast->y), }; const int dy_max[] = { - MAP_LINES - raycast->y - 1, - MAP_COLS - raycast->x - 1, - MAP_LINES - raycast->y - 1, - raycast->x , - raycast->y , - MAP_COLS - raycast->x - 1, - raycast->y , - raycast->x , + MAP_LINES - raycast->y - 1, + MAP_COLS - raycast->x - 1, + MAP_LINES - raycast->y - 1, + raycast->x, + raycast->y, + MAP_COLS - raycast->x - 1, + raycast->y, + raycast->x, }; - for (int octant = 0; octant < 8; octant++) - { - raycast_octant_at( - raycast, - &(struct octant_params) { - .octant = octant, - .dx_max = dx_max[octant], - .dy_max = dy_max[octant] - }, + for (int octant = 0; octant < 8; octant++) { + raycast_octant_at(raycast, + &(struct octant_params) { .octant = octant, .dx_max = dx_max[octant], .dy_max = dy_max[octant] }, 1, 0.0f, 1.0f); } -} \ No newline at end of file +} diff --git a/src/torch.c b/src/torch.c index e0377ad..f574713 100644 --- a/src/torch.c +++ b/src/torch.c @@ -2,16 +2,15 @@ #include "ui.h" #include +#include #include #include -#include #ifdef DEBUG FILE *debug_log; #endif -int main(void) -{ +int main() { srand(time(NULL)); #ifdef DEBUG debug_log = fopen("debug_log", "w"); @@ -28,8 +27,7 @@ int main(void) struct ui_event event = { .key = 'e' }; do { - if (!input_keymap[event.key] || input_keymap[event.key]()) - continue; + if (!input_keymap[event.key] || input_keymap[event.key]()) continue; floor_map_clear_lights(); floor_update_entities(cur_floor); diff --git a/src/torch.h b/src/torch.h index 80eb882..f82dfcc 100644 --- a/src/torch.h +++ b/src/torch.h @@ -3,12 +3,12 @@ #include "list.h" -#include -#include #include +#include +#include #include -#define back(arr) (arr[sizeof(arr)/sizeof(*arr)]) +#define back(arr) (arr[sizeof(arr) / sizeof(*arr)]) #define min(a, b) (a < b ? a : b) #define max(a, b) (a > b ? a : b) #define clamp(v, lo, hi) ((v < lo) ? lo : (hi < v) ? hi : v) @@ -82,7 +82,7 @@ struct tile { bool tile_blocks_light(struct tile const *); #define MAP_LINES 100 -#define MAP_COLS 100 +#define MAP_COLS 100 typedef struct tile tile_map[MAP_LINES][MAP_COLS]; typedef struct list_head entity_list; @@ -100,20 +100,19 @@ enum floor_type { CAVE, }; -struct tile floor_map_at(struct floor *floor, int y, int x); -int floor_map_in_bounds(int y, int x); -void floor_map_clear_lights(void); -void floor_map_generate(struct floor *floor, enum floor_type type); +struct tile floor_map_at(struct floor *floor, int y, int x); +int floor_map_in_bounds(int y, int x); +void floor_map_clear_lights(void); +void floor_map_generate(struct floor *floor, enum floor_type type); -int floor_add_entity(struct floor *floor, struct entity *entity); +int floor_add_entity(struct floor *floor, struct entity *entity); void floor_update_entities(struct floor *floor); -#define floor_for_each_tile(pos, floor) \ - for (pos = *floor->map; pos != back(floor->map); ++pos) +#define floor_for_each_tile(pos, floor) for (pos = *floor->map; pos != back(floor->map); ++pos) /* Draw */ #define VIEW_LINES 23 -#define VIEW_COLS 79 +#define VIEW_COLS 79 #if 0 void draw_map(void); @@ -138,14 +137,13 @@ extern struct floor demo_floor; typedef void raycast_callback_fn(struct tile *tile, int x, int y, void *context); -struct raycast_params -{ - struct floor *floor; +struct raycast_params { + struct floor *floor; int x; int y; - int radius; - raycast_callback_fn *callback; - void *context; + int radius; + raycast_callback_fn *callback; + void *context; }; void raycast_at(const struct raycast_params *params); diff --git a/src/ui.h b/src/ui.h index 80bf258..d2becf5 100644 --- a/src/ui.h +++ b/src/ui.h @@ -3,8 +3,8 @@ #include "torch.h" -#include #include +#include void ui_init(void); void ui_quit(void); @@ -12,13 +12,14 @@ void ui_dimensions(int *lines, int *cols); struct ui_cell { char codepoint[5]; - struct color fg, bg; - unsigned int bold : 1, - italic : 1, - under_ : 1, - blink : 1, - reverse_vid : 1, - strikethru : 1; + struct color fg; + struct color bg; + unsigned int bold : 1; + unsigned int italic : 1; + unsigned int under_ : 1; + unsigned int blink : 1; + unsigned int reverse_vid : 1; + unsigned int strikethru : 1; }; void ui_draw_at(int line, int col, struct ui_cell cell); @@ -38,7 +39,7 @@ enum ui_event_key { }; struct ui_event { - enum ui_event_type type; + enum ui_event_type type; union { long key; }; diff --git a/src/ui/term.c b/src/ui/term.c index 2400b9b..74abded 100644 --- a/src/ui/term.c +++ b/src/ui/term.c @@ -15,6 +15,7 @@ #define NORMAL_SCREEN "?1049l" #define HIDE_CURSOR "?25l" #define SHOW_CURSOR "?25h" + static void get_terminal_size(); static void handle_resize(int signal); From 95e1c4283d25cccd4a956e47bb9781e8fcec7630 Mon Sep 17 00:00:00 2001 From: Ted Stier Date: Sat, 18 Jan 2020 00:30:10 -0500 Subject: [PATCH 08/12] reviewed clang-format changes --- .clang-format | 18 ++++++++------ src/color.c | 9 ++++--- src/demo.c | 43 ++++++++++++++++++++------------ src/draw.c | 12 +++++---- src/entity.c | 6 +++-- src/floor.c | 45 ++++++++++++++++++++++------------ src/player.c | 27 +++++++++++++------- src/raycast.c | 31 ++++++++++++++--------- src/torch.c | 4 ++- src/torch.h | 18 +++++++++----- src/ui.h | 15 ++++++++---- src/ui/term.c | 68 +++++++++++++++++++++++---------------------------- 12 files changed, 177 insertions(+), 119 deletions(-) diff --git a/.clang-format b/.clang-format index 079344d..7aa0ad2 100644 --- a/.clang-format +++ b/.clang-format @@ -24,14 +24,14 @@ BinPackArguments: false BinPackParameters: false BraceWrapping: AfterCaseLabel: false - AfterClass: false + AfterClass: true AfterControlStatement: false - AfterEnum: false - AfterFunction: false - AfterNamespace: false - AfterStruct: false - AfterUnion: false - AfterExternBlock: false + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true BeforeCatch: false BeforeElse: false IndentBraces: false @@ -39,7 +39,7 @@ BraceWrapping: SplitEmptyRecord: false SplitEmptyNamespace: false BreakBeforeBinaryOperators: All -BreakBeforeBraces: Attach +BreakBeforeBraces: Custom BreakBeforeTernaryOperators: true BreakConstructorInitializers: AfterColon BreakInheritanceList: AfterColon @@ -59,6 +59,8 @@ IncludeCategories: - Regex: '".*"' Priority: 1 - Regex: '<[a-zA-Z0-9.]*>' + Priority: 3 + - Regex: '.*' Priority: 2 IndentCaseLabels: false IndentPPDirectives: BeforeHash diff --git a/src/color.c b/src/color.c index 0f75f2b..ff67bc9 100644 --- a/src/color.c +++ b/src/color.c @@ -2,7 +2,8 @@ #include -struct color color_add(struct color c, struct color a) { +struct color color_add(struct color c, struct color a) +{ return (struct color) { min(c.r + a.r, 255), min(c.g + a.g, 255), @@ -10,7 +11,8 @@ struct color color_add(struct color c, struct color a) { }; } -struct color color_multiply_by(struct color c, float m) { +struct color color_multiply_by(struct color c, float m) +{ return (struct color) { min(c.r * m, 255), min(c.g * m, 255), @@ -18,7 +20,8 @@ struct color color_multiply_by(struct color c, float m) { }; } -int color_approximate_256(struct color c) { +int color_approximate_256(struct color c) +{ /* L. */ return rand() % 256; } diff --git a/src/demo.c b/src/demo.c index 43ed8a2..7d072c9 100644 --- a/src/demo.c +++ b/src/demo.c @@ -13,7 +13,8 @@ struct floor *cur_floor = &floors[0]; struct entity demo_new_snake(int y, int x); void demo_place_snake(int y, int x); -void demo_floor_load_map(const char *filename) { +void demo_floor_load_map(const char *filename) +{ // FILE *mapfp = fopen(filename, "r"); floor_map_generate(&floors[0], CAVE); @@ -45,7 +46,8 @@ void demo_floor_load_map(const char *filename) { int drawn_to[MAP_LINES][MAP_COLS] = { 0 }; -struct light_info { +struct light_info +{ tile_map *map; float bright; int y, x; @@ -54,7 +56,8 @@ struct light_info { #include -void cast_light_at(struct tile *tile, int y, int x, void *context) { +void cast_light_at(struct tile *tile, int y, int x, void *context) +{ if (drawn_to[y][x]) return; struct light_info *info = context; drawn_to[y][x] = 1; @@ -70,7 +73,8 @@ void cast_light_at(struct tile *tile, int y, int x, void *context) { } } -def_entity_fn(demo_player_update) { +def_entity_fn(demo_player_update) +{ float bright = player_lantern_on && player_fuel > 0 ? 0.5f : 0.1f; if (player_lantern_on) { if (player_fuel > 0) { @@ -84,8 +88,7 @@ def_entity_fn(demo_player_update) { raycast_at(&(struct raycast_params) { .callback = &cast_light_at, - .context = &(struct light_info) { - .map = &this->floor->map, + .context = &(struct light_info) { .map = &this->floor->map, .bright = bright, .y = this->posy, .x = this->posx, @@ -99,7 +102,8 @@ def_entity_fn(demo_player_update) { memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_LINES * MAP_COLS)); } -def_entity_fn(demo_torch_update) { +def_entity_fn(demo_torch_update) +{ // entity_move_pos_rel(this, y, x); // cast_light(this->floor->map, y, x, 6, 1.f, this->r, this->g, this->b); @@ -119,10 +123,11 @@ def_entity_fn(demo_torch_update) { memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_LINES * MAP_COLS)); } -def_entity_fn(demo_torch_destroy) { -} +def_entity_fn(demo_torch_destroy) +{} -void demo_add_entities(void) { +void demo_add_entities(void) +{ #if 0 struct entity torch = { .r = 0xe2, .g = /*0x58*/0, .b = 0x22, @@ -164,7 +169,8 @@ void demo_add_entities(void) { #endif } -struct entity demo_new_torch(int y, int x) { +struct entity demo_new_torch(int y, int x) +{ struct entity torch = { .color = { .r = 0xe2, @@ -183,7 +189,8 @@ struct entity demo_new_torch(int y, int x) { return torch; } -def_input_key_fn(place_torch) { +def_input_key_fn(place_torch) +{ if (!player_torches) return 0; player_torches--; int y = player.posy; @@ -201,19 +208,22 @@ def_input_key_fn(place_torch) { return floor_add_entity(cur_floor, t); } -def_input_key_fn(demo_get_fuel) { +def_input_key_fn(demo_get_fuel) +{ player_fuel += 10; return 0; } -void demo_place_snake(int y, int x) { +void demo_place_snake(int y, int x) +{ struct entity snake = demo_new_snake(y, x); struct entity *s = malloc(sizeof(snake)); memcpy(s, &snake, sizeof(snake)); floor_add_entity(&floors[0], s); } -def_entity_fn(demo_snake_update) { +def_entity_fn(demo_snake_update) +{ int y = 0; int x = 0; if (this->posy < player.posy) y = 1; @@ -235,7 +245,8 @@ def_entity_fn(demo_snake_update) { } } -struct entity demo_new_snake(int y, int x) { +struct entity demo_new_snake(int y, int x) +{ struct entity snake = { .color = { .r = 0xa, diff --git a/src/draw.c b/src/draw.c index 76cdd87..41bd25c 100644 --- a/src/draw.c +++ b/src/draw.c @@ -102,11 +102,13 @@ void draw_entities(void) } #endif -struct draw_info { +struct draw_info +{ int view_lines, view_cols; }; -void draw_thing(struct tile *tile, int y, int x, void *context) { +void draw_thing(struct tile *tile, int y, int x, void *context) +{ struct draw_info *info = context; int line = y - clamp(player.posy - info->view_lines / 2, 0, MAP_LINES - info->view_lines); int col = x - clamp(player.posx - info->view_cols / 2, 0, MAP_COLS - info->view_cols); @@ -131,12 +133,12 @@ void draw_thing(struct tile *tile, int y, int x, void *context) { } } -void draw_shit(void) { +void draw_shit(void) +{ int view_lines, view_cols; ui_dimensions(&view_lines, &view_cols); - raycast_at(&(struct raycast_params) { - .callback = &draw_thing, + raycast_at(&(struct raycast_params) { .callback = &draw_thing, .context = &(struct draw_info) { .view_lines = view_lines, .view_cols = view_cols }, .floor = cur_floor, .y = player.posy, diff --git a/src/entity.c b/src/entity.c index e856ca6..c5c54a0 100644 --- a/src/entity.c +++ b/src/entity.c @@ -1,6 +1,7 @@ #include "torch.h" -int entity_move_pos(struct entity *entity, int y, int x) { +int entity_move_pos(struct entity *entity, int y, int x) +{ struct tile tile = floor_map_at(entity->floor, y, x); if (floor_map_in_bounds(y, x) && !tile.entity && tile.walk) { /* Slightly dangerous raw access. */ @@ -14,6 +15,7 @@ int entity_move_pos(struct entity *entity, int y, int x) { return -1; } -int entity_move_pos_rel(struct entity *entity, int y, int x) { +int entity_move_pos_rel(struct entity *entity, int y, int x) +{ return entity_move_pos(entity, entity->posy + y, entity->posx + x); } diff --git a/src/floor.c b/src/floor.c index 690ce58..cade488 100644 --- a/src/floor.c +++ b/src/floor.c @@ -16,7 +16,8 @@ static int intern_cell_grid_at(cell_grid grid, int y, int x); static void intern_floor_write_grid(struct floor *floor, cell_grid grid); -void floor_map_generate(struct floor *floor, enum floor_type type) { +void floor_map_generate(struct floor *floor, enum floor_type type) +{ cell_grid grid = { 0 }; intern_populate_grid(grid, 0.45f); @@ -27,7 +28,8 @@ void floor_map_generate(struct floor *floor, enum floor_type type) { intern_floor_write_grid(floor, grid); } -static void intern_populate_grid(cell_grid grid, float rate) { +static void intern_populate_grid(cell_grid grid, float rate) +{ /* cell *pos; cell_grid_for_each_cell(pos, grid) { @@ -46,7 +48,8 @@ static void intern_populate_grid(cell_grid grid, float rate) { } } -static void intern_iterate_grid(cell_grid grid, int birth, int survive) { +static void intern_iterate_grid(cell_grid grid, int birth, int survive) +{ cell_grid new = { 0 }; for (int y = 0; y < MAP_LINES; ++y) for (int x = 0; x < MAP_COLS; ++x) { @@ -65,7 +68,8 @@ static void intern_iterate_grid(cell_grid grid, int birth, int survive) { } } -static int intern_cell_alive_neighbours(cell_grid grid, int y, int x) { +static int intern_cell_alive_neighbours(cell_grid grid, int y, int x) +{ int alive = 0; /* for (int i = -1; i < 2; ++i) @@ -87,16 +91,19 @@ static int intern_cell_alive_neighbours(cell_grid grid, int y, int x) { return alive; } -static int intern_cell_grid_at(cell_grid grid, int y, int x) { +static int intern_cell_grid_at(cell_grid grid, int y, int x) +{ if (floor_map_in_bounds(y, x)) return grid[y][x]; else return 1; } -static void intern_floor_write_grid(struct floor *floor, cell_grid grid) { +static void intern_floor_write_grid(struct floor *floor, cell_grid grid) +{ struct tile *t; cell *c = *grid; - floor_for_each_tile(t, floor) { + floor_for_each_tile(t, floor) + { if (*c) { t->token = '#'; t->walk = 0; @@ -108,19 +115,23 @@ static void intern_floor_write_grid(struct floor *floor, cell_grid grid) { } } -struct tile floor_map_at(struct floor *floor, int y, int x) { +struct tile floor_map_at(struct floor *floor, int y, int x) +{ if (floor_map_in_bounds(y, x)) return (floor->map)[y][x]; else return (struct tile) { .token = ' ' }; } -int floor_map_in_bounds(int y, int x) { +int floor_map_in_bounds(int y, int x) +{ return y >= 0 && y < MAP_LINES && x >= 0 && x < MAP_COLS; } -void floor_map_clear_lights(void) { +void floor_map_clear_lights(void) +{ struct tile *pos; - floor_for_each_tile(pos, cur_floor) { + floor_for_each_tile(pos, cur_floor) + { pos->light = 0; pos->dcolor.r = 0; pos->dcolor.g = 0; @@ -128,7 +139,8 @@ void floor_map_clear_lights(void) { } } -int floor_add_entity(struct floor *floor, struct entity *entity) { +int floor_add_entity(struct floor *floor, struct entity *entity) +{ if (floor->map[entity->posy][entity->posx].entity) return -1; list_add(&entity->list, &floor->entities); entity->floor = floor; @@ -136,13 +148,16 @@ int floor_add_entity(struct floor *floor, struct entity *entity) { return 0; } -void floor_update_entities(struct floor *floor) { +void floor_update_entities(struct floor *floor) +{ struct entity *pos; - list_for_each_entry(pos, &floor->entities, list) { + list_for_each_entry(pos, &floor->entities, list) + { if (pos->update) pos->update(pos); } } -bool tile_blocks_light(const struct tile *tile) { +bool tile_blocks_light(const struct tile *tile) +{ return !tile->walk || (tile->entity && tile->entity->blocks_light); } diff --git a/src/player.c b/src/player.c index ac103f2..ff7a32a 100644 --- a/src/player.c +++ b/src/player.c @@ -19,39 +19,48 @@ bool player_lantern_on = false; int player_fuel = 100; int player_torches = 'z'; -def_input_key_fn(player_move_left) { +def_input_key_fn(player_move_left) +{ return entity_move_pos_rel(&player, 0, -1); } -def_input_key_fn(player_move_down) { +def_input_key_fn(player_move_down) +{ return entity_move_pos_rel(&player, 1, 0); } -def_input_key_fn(player_move_up) { +def_input_key_fn(player_move_up) +{ return entity_move_pos_rel(&player, -1, 0); } -def_input_key_fn(player_move_right) { +def_input_key_fn(player_move_right) +{ return entity_move_pos_rel(&player, 0, 1); } -def_input_key_fn(player_move_upleft) { +def_input_key_fn(player_move_upleft) +{ return entity_move_pos_rel(&player, -1, -1); } -def_input_key_fn(player_move_upright) { +def_input_key_fn(player_move_upright) +{ return entity_move_pos_rel(&player, -1, 1); } -def_input_key_fn(player_move_downleft) { +def_input_key_fn(player_move_downleft) +{ return entity_move_pos_rel(&player, 1, -1); } -def_input_key_fn(player_move_downright) { +def_input_key_fn(player_move_downright) +{ return entity_move_pos_rel(&player, 1, 1); } -def_input_key_fn(player_toggle_lantern) { +def_input_key_fn(player_toggle_lantern) +{ player_lantern_on = !player_lantern_on; return 0; } diff --git a/src/raycast.c b/src/raycast.c index 2ff5f59..c6561fa 100644 --- a/src/raycast.c +++ b/src/raycast.c @@ -16,7 +16,8 @@ * - raycast->callback is called with the corresponding tile * - the result is a pointer to that tile */ -static struct tile *get_tile_and_call_back(const struct raycast_params *raycast, int x, int y) { +static struct tile *get_tile_and_call_back(const struct raycast_params *raycast, int x, int y) +{ struct tile *tile = &raycast->floor->map[y][x]; raycast->callback(tile, y, x, raycast->context); return tile; @@ -29,13 +30,15 @@ static struct tile *get_tile_and_call_back(const struct raycast_params *raycast, * postconditions: * - the values of *l and *r are swapped */ -void swapi(int *l, int *r) { +void swapi(int *l, int *r) +{ int t = *l; *l = *r; *r = t; } -struct point { +struct point +{ int x; int y; }; @@ -57,7 +60,8 @@ struct point { * * wide contract */ -static struct point transform_point_to_octant(int x, int y, int dx, int dy, int octant_number) { +static struct point transform_point_to_octant(int x, int y, int dx, int dy, int octant_number) +{ if (octant_number & 1) { swapi(&dx, &dy); } @@ -85,13 +89,14 @@ static struct point transform_point_to_octant(int x, int y, int dx, int dy, int * - raycast->callback is called with the corresponding tile * - the result is a pointer to that tile */ -static struct tile * -get_transformed_tile_and_call_back(const struct raycast_params *raycast, int dx, int dy, int octant) { +static struct tile *get_transformed_tile_and_call_back(const struct raycast_params *raycast, int dx, int dy, int octant) +{ struct point r = transform_point_to_octant(raycast->x, raycast->y, dx, dy, octant); return get_tile_and_call_back(raycast, r.x, r.y); } -struct index_interval { +struct index_interval +{ int begin; int end; }; @@ -102,14 +107,16 @@ struct index_interval { * * wide contract */ -struct index_interval make_dy_interval(float slope_begin, float slope_end, int dx, int dy_max) { +struct index_interval make_dy_interval(float slope_begin, float slope_end, int dx, int dy_max) +{ struct index_interval dy_interval = { slope_begin * (dx - 0.5f) + 0.5f, slope_end * (dx + 0.5f) - 0.5f }; dy_interval.begin = min(dy_interval.begin, dy_max); dy_interval.end = min(dy_interval.end, dy_max); return dy_interval; } -struct octant_params { +struct octant_params +{ int number; int dx_max; int dy_max; @@ -181,7 +188,8 @@ static void raycast_octant_at(const struct raycast_params *raycast, const struct octant_params *octant, int dx, float start_slope, - float end_slope) { + float end_slope) +{ bool blocked = false; for (; dx <= octant->dx_max && !blocked; ++dx) { struct index_interval dy_interval = make_dy_interval(start_slope, end_slope, dx, octant->dy_max); @@ -227,7 +235,8 @@ static void raycast_octant_at(const struct raycast_params *raycast, * - may call back for cells outside the requested radius. * - may call back multiple times for cells along axes and diagonals. */ -void raycast_at(const struct raycast_params *raycast) { +void raycast_at(const struct raycast_params *raycast) +{ get_tile_and_call_back(raycast, raycast->x, raycast->y); const int dx_max[] = { diff --git a/src/torch.c b/src/torch.c index f574713..105f868 100644 --- a/src/torch.c +++ b/src/torch.c @@ -1,4 +1,5 @@ #include "torch.h" + #include "ui.h" #include @@ -10,7 +11,8 @@ FILE *debug_log; #endif -int main() { +int main() +{ srand(time(NULL)); #ifdef DEBUG debug_log = fopen("debug_log", "w"); diff --git a/src/torch.h b/src/torch.h index f82dfcc..06c44aa 100644 --- a/src/torch.h +++ b/src/torch.h @@ -24,7 +24,8 @@ typedef def_input_key_fn(input_key_fn); extern input_key_fn *input_keymap[]; /* Color */ -struct color { +struct color +{ uint8_t r, g, b; }; @@ -39,7 +40,8 @@ struct entity; #define def_entity_fn(name) void name(struct entity *this) typedef def_entity_fn(entity_fn); -struct entity { +struct entity +{ struct color color; char token; int posy, posx; @@ -70,7 +72,8 @@ def_input_key_fn(player_move_downright); def_input_key_fn(player_toggle_lantern); /* Floor */ -struct tile { +struct tile +{ struct color color; char token; float light; @@ -87,7 +90,8 @@ bool tile_blocks_light(struct tile const *); typedef struct tile tile_map[MAP_LINES][MAP_COLS]; typedef struct list_head entity_list; -struct floor { +struct floor +{ tile_map map; entity_list entities; }; @@ -96,7 +100,8 @@ extern struct floor floors[]; extern struct floor *cur_floor; -enum floor_type { +enum floor_type +{ CAVE, }; @@ -137,7 +142,8 @@ extern struct floor demo_floor; typedef void raycast_callback_fn(struct tile *tile, int x, int y, void *context); -struct raycast_params { +struct raycast_params +{ struct floor *floor; int x; int y; diff --git a/src/ui.h b/src/ui.h index d2becf5..44746b1 100644 --- a/src/ui.h +++ b/src/ui.h @@ -10,7 +10,8 @@ void ui_init(void); void ui_quit(void); void ui_dimensions(int *lines, int *cols); -struct ui_cell { +struct ui_cell +{ char codepoint[5]; struct color fg; struct color bg; @@ -29,18 +30,22 @@ void ui_flush(void); /* Hacky garbage. */ void ui_draw_str_at(int line, int col, const char *str, struct ui_cell attr); -enum ui_event_type { +enum ui_event_type +{ UI_EVENT_KEY, }; -enum ui_event_key { +enum ui_event_key +{ UI_EVENT_KEY_a = 'a', UI_EVENT_KEY_A = 'A', }; -struct ui_event { +struct ui_event +{ enum ui_event_type type; - union { + union + { long key; }; }; diff --git a/src/ui/term.c b/src/ui/term.c index 74abded..4c085cd 100644 --- a/src/ui/term.c +++ b/src/ui/term.c @@ -1,14 +1,15 @@ -#include "ui.h" #include "termkey.h" #include "torch.h" +#include "ui.h" #include -#include + #include #include +#include #include #include -#include +#include #define CSI "\e[" #define ALTERNATE_SCREEN "?1049h" @@ -73,13 +74,11 @@ static void __ui_buffer_realloc(int lines, int cols) /* Initial allocation. Should only be ran once. */ if (!old_lines) { ui_buffer = malloc(sizeof(struct ui_cell *) * lines); - if (!ui_buffer) - goto fail; + if (!ui_buffer) goto fail; for (int line = 0; line < lines; ++line) { ui_buffer[line] = malloc(sizeof(struct ui_cell) * cols); - if (!ui_buffer[line]) - goto fail; + if (!ui_buffer[line]) goto fail; } } else { /* Free all uneeded lines. */ @@ -89,23 +88,20 @@ static void __ui_buffer_realloc(int lines, int cols) /* Resize the top array of pointers. */ struct ui_cell **tmp = realloc(ui_buffer, sizeof(struct ui_cell *) * lines); - if (!tmp) - goto fail; + if (!tmp) goto fail; ui_buffer = tmp; /* Resize existing lines. */ for (int line = 0; line < min(old_lines, lines); ++line) { struct ui_cell *tmp = realloc(ui_buffer[line], sizeof(struct ui_cell) * cols); - if (!tmp) - goto fail; + if (!tmp) goto fail; ui_buffer[line] = tmp; } /* Allocate all new lines. */ for (int line = old_lines; line < lines; ++line) { ui_buffer[line] = malloc(sizeof(struct ui_cell) * cols); - if (!ui_buffer[line]) - goto fail; + if (!ui_buffer[line]) goto fail; } } @@ -128,10 +124,8 @@ void ui_quit(void) void ui_dimensions(int *lines, int *cols) { - if (lines) - *lines = ui_lines; - if (cols) - *cols = ui_cols; + if (lines) *lines = ui_lines; + if (cols) *cols = ui_cols; } void ui_draw_at(int line, int col, struct ui_cell cell) @@ -222,7 +216,7 @@ void ui_flush(void) } if (this.strikethru != last.strikethru) { - sgr_params[nparams++] = this.strikethru? 9 : 29; + sgr_params[nparams++] = this.strikethru ? 9 : 29; sgrlen += this.strikethru ? 1 : 2; } @@ -230,10 +224,10 @@ void ui_flush(void) char *iter = sgr_buf; iter += sprintf(iter, "\e["); - for (int i = 0; i < nparams-1; i++) + for (int i = 0; i < nparams - 1; i++) iter += sprintf(iter, "%d;", sgr_params[i]); if (nparams > 0) // no semicolon for last parameter - iter += sprintf(iter, "%d", sgr_params[nparams-1]); + iter += sprintf(iter, "%d", sgr_params[nparams - 1]); sprintf(iter, "m"); } else sgr_buf[0] = '\0'; @@ -249,8 +243,7 @@ void ui_flush(void) static void move_cursor(int line, int col) { if (ui_buffer_in_bounds(line, col)) - if (line == 1 && col == 1) - printf(CSI "H"); + if (line == 1 && col == 1) printf(CSI "H"); else if (col == 1) printf(CSI "%dH", line); else @@ -269,31 +262,30 @@ void ui_draw_str_at(int line, int col, const char *str, struct ui_cell attr) struct ui_event ui_poll_event(void) { - bool cont = true; + bool cont = true; TermKeyKey key; struct ui_event event; - - while (cont) switch (termkey_waitkey(termkey_instance, &key)) { - case TERMKEY_RES_KEY: - switch (key.type) { - case TERMKEY_TYPE_UNICODE: - event.key = key.code.codepoint; - cont = false; - break; - default: + + while (cont) + switch (termkey_waitkey(termkey_instance, &key)) { + case TERMKEY_RES_KEY: + switch (key.type) { + case TERMKEY_TYPE_UNICODE: + event.key = key.code.codepoint; + cont = false; + break; + default: break; + } break; + default: break; } - break; - default: - break; - } return event; } #ifdef TEST -#include + #include int main(void) { @@ -313,7 +305,7 @@ int main(void) }); assert(strcmp(ui_buffer[lines - 1][0].codepoint, "L") == 0); - ui_draw_str_at(3, 3, "Test", (struct ui_cell){.fg = {19, 103, 76}}); + ui_draw_str_at(3, 3, "Test", (struct ui_cell) { .fg = { 19, 103, 76 } }); ui_flush(); struct ui_event event = ui_poll_event(); From 4fe1e41206b0766d2471dbc5c3cfddd9c7cb0b8e Mon Sep 17 00:00:00 2001 From: Ted Stier Date: Sat, 18 Jan 2020 00:33:53 -0500 Subject: [PATCH 09/12] further review of clang-format changes --- .clang-format | 2 +- src/demo.c | 15 ++++++++++----- src/floor.c | 21 ++++++++++++++------- src/torch.c | 3 ++- src/ui/sdl.c | 1 + src/ui/term.c | 24 ++++++++++++++++-------- 6 files changed, 44 insertions(+), 22 deletions(-) diff --git a/.clang-format b/.clang-format index 7aa0ad2..4a6a890 100644 --- a/.clang-format +++ b/.clang-format @@ -14,7 +14,7 @@ AllowAllParametersOfDeclarationOnNextLine: false AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: true AllowShortFunctionsOnASingleLine: None -AllowShortIfStatementsOnASingleLine: Always +AllowShortIfStatementsOnASingleLine: Never AllowShortLambdasOnASingleLine: None AllowShortLoopsOnASingleLine: false AlwaysBreakAfterReturnType: None diff --git a/src/demo.c b/src/demo.c index 7d072c9..b7e4ba3 100644 --- a/src/demo.c +++ b/src/demo.c @@ -58,7 +58,8 @@ struct light_info void cast_light_at(struct tile *tile, int y, int x, void *context) { - if (drawn_to[y][x]) return; + if (drawn_to[y][x]) + return; struct light_info *info = context; drawn_to[y][x] = 1; int distance = sqrt(pow(y - info->y, 2) + pow(x - info->x, 2)); @@ -191,7 +192,8 @@ struct entity demo_new_torch(int y, int x) def_input_key_fn(place_torch) { - if (!player_torches) return 0; + if (!player_torches) + return 0; player_torches--; int y = player.posy; int x = player.posx; @@ -226,16 +228,19 @@ def_entity_fn(demo_snake_update) { int y = 0; int x = 0; - if (this->posy < player.posy) y = 1; + if (this->posy < player.posy) + y = 1; else if (this->posy > player.posy) y = -1; - if (this->posx < player.posx) x = 1; + if (this->posx < player.posx) + x = 1; else if (this->posx > player.posx) x = -1; entity_move_pos_rel(this, y, x); - if (floor_map_at(this->floor, this->posy, this->posx).light > 0.2) entity_move_pos_rel(this, -y, -x); + if (floor_map_at(this->floor, this->posy, this->posx).light > 0.2) + entity_move_pos_rel(this, -y, -x); if (abs(this->posy - player.posy) == 1 && abs(this->posx - player.posx) == 1) { ui_clear(); ui_flush(); diff --git a/src/floor.c b/src/floor.c index cade488..34a91ed 100644 --- a/src/floor.c +++ b/src/floor.c @@ -41,7 +41,8 @@ static void intern_populate_grid(cell_grid grid, float rate) */ for (int y = 0; y < MAP_LINES; ++y) { for (int x = 0; x < MAP_COLS; ++x) { - if (rand() % 100 / 100.f < rate) grid[y][x] = 1; + if (rand() % 100 / 100.f < rate) + grid[y][x] = 1; else grid[y][x] = 0; }; @@ -55,9 +56,11 @@ static void intern_iterate_grid(cell_grid grid, int birth, int survive) for (int x = 0; x < MAP_COLS; ++x) { int alive = intern_cell_alive_neighbours(grid, y, x); if (grid[y][x]) { - if (alive >= survive) new[y][x] = 1; + if (alive >= survive) + new[y][x] = 1; } else { - if (alive >= birth) new[y][x] = 1; + if (alive >= birth) + new[y][x] = 1; } } @@ -93,7 +96,8 @@ static int intern_cell_alive_neighbours(cell_grid grid, int y, int x) static int intern_cell_grid_at(cell_grid grid, int y, int x) { - if (floor_map_in_bounds(y, x)) return grid[y][x]; + if (floor_map_in_bounds(y, x)) + return grid[y][x]; else return 1; } @@ -117,7 +121,8 @@ static void intern_floor_write_grid(struct floor *floor, cell_grid grid) struct tile floor_map_at(struct floor *floor, int y, int x) { - if (floor_map_in_bounds(y, x)) return (floor->map)[y][x]; + if (floor_map_in_bounds(y, x)) + return (floor->map)[y][x]; else return (struct tile) { .token = ' ' }; } @@ -141,7 +146,8 @@ void floor_map_clear_lights(void) int floor_add_entity(struct floor *floor, struct entity *entity) { - if (floor->map[entity->posy][entity->posx].entity) return -1; + if (floor->map[entity->posy][entity->posx].entity) + return -1; list_add(&entity->list, &floor->entities); entity->floor = floor; floor->map[entity->posy][entity->posx].entity = entity; @@ -153,7 +159,8 @@ void floor_update_entities(struct floor *floor) struct entity *pos; list_for_each_entry(pos, &floor->entities, list) { - if (pos->update) pos->update(pos); + if (pos->update) + pos->update(pos); } } diff --git a/src/torch.c b/src/torch.c index 105f868..54398f5 100644 --- a/src/torch.c +++ b/src/torch.c @@ -29,7 +29,8 @@ int main() struct ui_event event = { .key = 'e' }; do { - if (!input_keymap[event.key] || input_keymap[event.key]()) continue; + if (!input_keymap[event.key] || input_keymap[event.key]()) + continue; floor_map_clear_lights(); floor_update_entities(cur_floor); diff --git a/src/ui/sdl.c b/src/ui/sdl.c index e69de29..8b13789 100644 --- a/src/ui/sdl.c +++ b/src/ui/sdl.c @@ -0,0 +1 @@ + diff --git a/src/ui/term.c b/src/ui/term.c index 4c085cd..9b44b4b 100644 --- a/src/ui/term.c +++ b/src/ui/term.c @@ -74,11 +74,13 @@ static void __ui_buffer_realloc(int lines, int cols) /* Initial allocation. Should only be ran once. */ if (!old_lines) { ui_buffer = malloc(sizeof(struct ui_cell *) * lines); - if (!ui_buffer) goto fail; + if (!ui_buffer) + goto fail; for (int line = 0; line < lines; ++line) { ui_buffer[line] = malloc(sizeof(struct ui_cell) * cols); - if (!ui_buffer[line]) goto fail; + if (!ui_buffer[line]) + goto fail; } } else { /* Free all uneeded lines. */ @@ -88,20 +90,23 @@ static void __ui_buffer_realloc(int lines, int cols) /* Resize the top array of pointers. */ struct ui_cell **tmp = realloc(ui_buffer, sizeof(struct ui_cell *) * lines); - if (!tmp) goto fail; + if (!tmp) + goto fail; ui_buffer = tmp; /* Resize existing lines. */ for (int line = 0; line < min(old_lines, lines); ++line) { struct ui_cell *tmp = realloc(ui_buffer[line], sizeof(struct ui_cell) * cols); - if (!tmp) goto fail; + if (!tmp) + goto fail; ui_buffer[line] = tmp; } /* Allocate all new lines. */ for (int line = old_lines; line < lines; ++line) { ui_buffer[line] = malloc(sizeof(struct ui_cell) * cols); - if (!ui_buffer[line]) goto fail; + if (!ui_buffer[line]) + goto fail; } } @@ -124,8 +129,10 @@ void ui_quit(void) void ui_dimensions(int *lines, int *cols) { - if (lines) *lines = ui_lines; - if (cols) *cols = ui_cols; + if (lines) + *lines = ui_lines; + if (cols) + *cols = ui_cols; } void ui_draw_at(int line, int col, struct ui_cell cell) @@ -243,7 +250,8 @@ void ui_flush(void) static void move_cursor(int line, int col) { if (ui_buffer_in_bounds(line, col)) - if (line == 1 && col == 1) printf(CSI "H"); + if (line == 1 && col == 1) + printf(CSI "H"); else if (col == 1) printf(CSI "%dH", line); else From 92e861fe027761e3f821c27938ef83f20d1c689f Mon Sep 17 00:00:00 2001 From: Ted Stier Date: Sat, 18 Jan 2020 00:39:49 -0500 Subject: [PATCH 10/12] finished cleaning up after clang-format --- src/demo.c | 4 +++- src/draw.c | 10 +++++++--- src/ui.h | 10 +++++----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/demo.c b/src/demo.c index b7e4ba3..b0883d0 100644 --- a/src/demo.c +++ b/src/demo.c @@ -113,7 +113,9 @@ def_entity_fn(demo_torch_update) .callback = &cast_light_at, .context = &(struct light_info) { .map = &this->floor->map, - .bright = 1.f, .y = this->posy, .x = this->posx, + .bright = 1.f, + .y = this->posy, + .x = this->posx, .color = this->color, }, .floor = this->floor, diff --git a/src/draw.c b/src/draw.c index 41bd25c..80b283d 100644 --- a/src/draw.c +++ b/src/draw.c @@ -63,7 +63,7 @@ void draw_entities(void) raycast_at(cur_floor->map, player.posy, player.posx, 100, &set_visible, NULL); - struct entity * pos; + struct entity *pos; list_for_each_entry(pos, &cur_floor->entities, list) { int line = pos->posy - clamp((player.posy - view_lines / 2), 0, MAP_LINES - view_lines); int col = pos->posx - clamp((player.posx - view_cols / 2), 0, MAP_COLS - view_cols); @@ -138,8 +138,12 @@ void draw_shit(void) int view_lines, view_cols; ui_dimensions(&view_lines, &view_cols); - raycast_at(&(struct raycast_params) { .callback = &draw_thing, - .context = &(struct draw_info) { .view_lines = view_lines, .view_cols = view_cols }, + raycast_at(&(struct raycast_params) { + .callback = &draw_thing, + .context = &(struct draw_info) { + .view_lines = view_lines, + .view_cols = view_cols + }, .floor = cur_floor, .y = player.posy, .x = player.posx, diff --git a/src/ui.h b/src/ui.h index 44746b1..b44be93 100644 --- a/src/ui.h +++ b/src/ui.h @@ -15,12 +15,12 @@ struct ui_cell char codepoint[5]; struct color fg; struct color bg; - unsigned int bold : 1; - unsigned int italic : 1; - unsigned int under_ : 1; - unsigned int blink : 1; + unsigned int bold : 1; + unsigned int italic : 1; + unsigned int under_ : 1; + unsigned int blink : 1; unsigned int reverse_vid : 1; - unsigned int strikethru : 1; + unsigned int strikethru : 1; }; void ui_draw_at(int line, int col, struct ui_cell cell); From 2541c406045bb10474bae22ff25b42c2d73e16a6 Mon Sep 17 00:00:00 2001 From: Ted Stier Date: Sat, 18 Jan 2020 00:49:46 -0500 Subject: [PATCH 11/12] y so memcpy? --- src/demo.c | 11 +++++------ src/raycast.c | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/demo.c b/src/demo.c index b0883d0..845ba7a 100644 --- a/src/demo.c +++ b/src/demo.c @@ -206,9 +206,9 @@ def_input_key_fn(place_torch) case 'k': y--; break; case 'l': x++; break; } - struct entity torch = demo_new_torch(y, x); - struct entity *t = malloc(sizeof(torch)); - memcpy(t, &torch, sizeof(torch)); + + struct entity *t = malloc(sizeof(struct entity)); + *t = demo_new_torch(y, x); return floor_add_entity(cur_floor, t); } @@ -220,9 +220,8 @@ def_input_key_fn(demo_get_fuel) void demo_place_snake(int y, int x) { - struct entity snake = demo_new_snake(y, x); - struct entity *s = malloc(sizeof(snake)); - memcpy(s, &snake, sizeof(snake)); + struct entity *s = malloc(sizeof(struct entity)); + *s = demo_new_snake(y, x); floor_add_entity(&floors[0], s); } diff --git a/src/raycast.c b/src/raycast.c index c6561fa..6981131 100644 --- a/src/raycast.c +++ b/src/raycast.c @@ -263,7 +263,7 @@ void raycast_at(const struct raycast_params *raycast) for (int octant = 0; octant < 8; octant++) { raycast_octant_at(raycast, - &(struct octant_params) { .octant = octant, .dx_max = dx_max[octant], .dy_max = dy_max[octant] }, + &(struct octant_params) { .number = octant, .dx_max = dx_max[octant], .dy_max = dy_max[octant] }, 1, 0.0f, 1.0f); From 469c665947465bf2b3885097691a2361d98de146 Mon Sep 17 00:00:00 2001 From: Ted Stier Date: Sat, 18 Jan 2020 03:09:44 -0500 Subject: [PATCH 12/12] fixed more clang-format weirdness; also better comments --- src/demo.c | 4 ++-- src/draw.c | 20 +++++++++++++------ src/player.c | 7 +++++-- src/raycast.c | 55 +++++++++++++++++++++++++++++---------------------- 4 files changed, 52 insertions(+), 34 deletions(-) diff --git a/src/demo.c b/src/demo.c index 845ba7a..a2097e6 100644 --- a/src/demo.c +++ b/src/demo.c @@ -113,7 +113,7 @@ def_entity_fn(demo_torch_update) .callback = &cast_light_at, .context = &(struct light_info) { .map = &this->floor->map, - .bright = 1.f, + .bright = 1.0f, .y = this->posy, .x = this->posx, .color = this->color, @@ -121,7 +121,7 @@ def_entity_fn(demo_torch_update) .floor = this->floor, .y = this->posy, .x = this->posx, - .radius = 15 + .radius = sqrt(255.0f) }); memset(drawn_to, 0, (sizeof(drawn_to[0][0]) * MAP_LINES * MAP_COLS)); } diff --git a/src/draw.c b/src/draw.c index 80b283d..5f0b8b2 100644 --- a/src/draw.c +++ b/src/draw.c @@ -32,21 +32,29 @@ void draw_map(void) if (visibility[viewy + line][viewx + col]) { ui_draw_at(line, col, (struct ui_cell) { .codepoint = { [0] = tile.token }, - .fg = { - .r = r, .g = g, .b = b, + .fg = { + .r = r, + .g = g, + .b = b, }, .bg = { - .r = 0, .g = 0, .b = 0, + .r = 0, + .g = 0, + .b = 0, }, }); } else { ui_draw_at(line, col, (struct ui_cell) { .codepoint = " ", - .fg = { - .r = 0, .g = 0, .b = 0, + .fg = { + .r = 0, + .g = 0, + .b = 0, }, .bg = { - .r = 0, .g = 0, .b = 0, + .r = 0, + .g = 0, + .b = 0, }, }); } diff --git a/src/player.c b/src/player.c index ff7a32a..d392e52 100644 --- a/src/player.c +++ b/src/player.c @@ -5,10 +5,13 @@ struct entity player = { .color = { - .r = 151, .g = 151, .b = 151, + .r = 151, + .g = 151, + .b = 151, }, .token = '@', - .posy = 13, .posx = 14, + .posy = 13, + .posx = 14, .update = demo_player_update, .destroy = NULL, .list = LIST_HEAD_INIT(player.list), diff --git a/src/raycast.c b/src/raycast.c index 6981131..893e5c2 100644 --- a/src/raycast.c +++ b/src/raycast.c @@ -16,7 +16,7 @@ * - raycast->callback is called with the corresponding tile * - the result is a pointer to that tile */ -static struct tile *get_tile_and_call_back(const struct raycast_params *raycast, int x, int y) +static struct tile *get_tile(const struct raycast_params *raycast, int x, int y) { struct tile *tile = &raycast->floor->map[y][x]; raycast->callback(tile, y, x, raycast->context); @@ -89,10 +89,10 @@ static struct point transform_point_to_octant(int x, int y, int dx, int dy, int * - raycast->callback is called with the corresponding tile * - the result is a pointer to that tile */ -static struct tile *get_transformed_tile_and_call_back(const struct raycast_params *raycast, int dx, int dy, int octant) +static struct tile *get_transformed_tile(const struct raycast_params *raycast, int dx, int dy, int octant) { struct point r = transform_point_to_octant(raycast->x, raycast->y, dx, dy, octant); - return get_tile_and_call_back(raycast, r.x, r.y); + return get_tile(raycast, r.x, r.y); } struct index_interval @@ -109,7 +109,10 @@ struct index_interval */ struct index_interval make_dy_interval(float slope_begin, float slope_end, int dx, int dy_max) { - struct index_interval dy_interval = { slope_begin * (dx - 0.5f) + 0.5f, slope_end * (dx + 0.5f) - 0.5f }; + struct index_interval dy_interval = { + slope_begin * (dx - 0.5f) + 0.5f, + slope_end * (dx + 0.5f) - 0.5f + }; dy_interval.begin = min(dy_interval.begin, dy_max); dy_interval.end = min(dy_interval.end, dy_max); return dy_interval; @@ -125,9 +128,10 @@ struct octant_params /* * Accepts slopes corresponding a gap between blocking tiles. * Iterates through columns from left to right, then through each - * tile,top to bottom, of the gap, searching for deeper gaps. - * Recurses in each gap except those enclosed by the last tile - * of the column. Exits if there is no such gap. + * tile, top to bottom, of the gap, searching for deeper gaps. + * Recurses in each gap except those containing the last tile + * of the column. Iterates into gaps containing the last tile. + * Exits if there is no such gap. * * Diagram of zeroth octant: * @@ -153,8 +157,8 @@ struct octant_params * the current tile does not, we have encountered the end of the gap, and we recurse. * * Each time we encounter any such bound, we calculate the slope of the associated - * point on the tile. Slopes for beginnings of regions correspond to bottom left points - * of tiles. Slopes for ends of regions correspond to top right points of tiles. + * point on the tile. Slopes for beginnings of gaps correspond to bottom left points + * of tiles. Slopes for ends of gaps correspond to top right points of tiles. * Those slopes are used in next recursion or iteration. * * Diagram of begin and end slopes: @@ -166,8 +170,7 @@ struct octant_params * xxx ------- * xxx------- * xxx---- - * ---xxx- - * ------x end + * ---xxx- end * ####### * ####### * @@ -187,28 +190,28 @@ struct octant_params static void raycast_octant_at(const struct raycast_params *raycast, const struct octant_params *octant, int dx, - float start_slope, - float end_slope) + float slope_begin, + float slope_end) { bool blocked = false; for (; dx <= octant->dx_max && !blocked; ++dx) { - struct index_interval dy_interval = make_dy_interval(start_slope, end_slope, dx, octant->dy_max); + struct index_interval dy_interval = make_dy_interval(slope_begin, slope_end, dx, octant->dy_max); int dy = dy_interval.begin; - struct tile *tile = get_transformed_tile_and_call_back(raycast, dx, dy, octant->number); + struct tile *tile = get_transformed_tile(raycast, dx, dy, octant->number); blocked = tile_blocks_light(tile); for (++dy; dy <= dy_interval.end; ++dy) { - tile = get_transformed_tile_and_call_back(raycast, dx, dy, octant->number); + tile = get_transformed_tile(raycast, dx, dy, octant->number); if (blocked && !tile_blocks_light(tile)) { blocked = false; - start_slope = (dy - 0.5f) / (dx - 0.5f); + slope_begin = (dy - 0.5f) / (dx - 0.5f); } else if (!blocked && tile_blocks_light(tile)) { blocked = true; - raycast_octant_at(raycast, octant, dx + 1, start_slope, (dy - 0.5f) / (dx + 0.5f)); + raycast_octant_at(raycast, octant, dx + 1, slope_begin, (dy - 0.5f) / (dx + 0.5f)); } } } @@ -237,14 +240,14 @@ static void raycast_octant_at(const struct raycast_params *raycast, */ void raycast_at(const struct raycast_params *raycast) { - get_tile_and_call_back(raycast, raycast->x, raycast->y); + get_tile(raycast, raycast->x, raycast->y); const int dx_max[] = { - min(raycast->radius, MAP_COLS - raycast->x - 1), + min(raycast->radius, MAP_COLS - raycast->x - 1), min(raycast->radius, MAP_LINES - raycast->y - 1), min(raycast->radius, raycast->x), min(raycast->radius, MAP_LINES - raycast->y - 1), - min(raycast->radius, MAP_COLS - raycast->x - 1), + min(raycast->radius, MAP_COLS - raycast->x - 1), min(raycast->radius, raycast->y), min(raycast->radius, raycast->x), min(raycast->radius, raycast->y), @@ -252,18 +255,22 @@ void raycast_at(const struct raycast_params *raycast) const int dy_max[] = { MAP_LINES - raycast->y - 1, - MAP_COLS - raycast->x - 1, + MAP_COLS - raycast->x - 1, MAP_LINES - raycast->y - 1, raycast->x, raycast->y, - MAP_COLS - raycast->x - 1, + MAP_COLS - raycast->x - 1, raycast->y, raycast->x, }; for (int octant = 0; octant < 8; octant++) { raycast_octant_at(raycast, - &(struct octant_params) { .number = octant, .dx_max = dx_max[octant], .dy_max = dy_max[octant] }, + &(struct octant_params) { + .number = octant, + .dx_max = dx_max[octant], + .dy_max = dy_max[octant] + }, 1, 0.0f, 1.0f);