Skip to content

Commit 106e972

Browse files
committed
Add float and uint8 data types to map arrays
1 parent 600089d commit 106e972

4 files changed

Lines changed: 155 additions & 9 deletions

File tree

include/libtcod-fov/map_inline.h

Lines changed: 131 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ static inline int TCODFOV_map2d_get_width(const TCODFOV_Map2D* __restrict map) {
3636
switch (map->type) {
3737
case TCODFOV_MAP2D_CALLBACK:
3838
case TCODFOV_MAP2D_BITPACKED:
39+
case TCODFOV_MAP2D_CONTIGIOUS:
3940
// Multiple structs share the same shape format
4041
return map->bool_callback.shape[1];
4142
case TCODFOV_MAP2D_DEPRECATED:
@@ -52,6 +53,7 @@ static inline int TCODFOV_map2d_get_height(const TCODFOV_Map2D* __restrict map)
5253
switch (map->type) {
5354
case TCODFOV_MAP2D_CALLBACK:
5455
case TCODFOV_MAP2D_BITPACKED:
56+
case TCODFOV_MAP2D_CONTIGIOUS:
5557
return map->bool_callback.shape[0];
5658
case TCODFOV_MAP2D_DEPRECATED:
5759
return map->deprecated_map.map.height;
@@ -76,7 +78,6 @@ static inline bool TCODFOV_map2d_in_bounds(const TCODFOV_Map2D* __restrict map,
7678
/// @param y Y coordinate.
7779
/// @return Boolean result, false if out-of-bounds or `map` is NULL.
7880
static inline bool TCODFOV_map2d_get_bool(const TCODFOV_Map2D* __restrict map, int x, int y) {
79-
if (!map) return 0;
8081
if (!TCODFOV_map2d_in_bounds(map, x, y)) return 0;
8182
switch (map->type) {
8283
case TCODFOV_MAP2D_CALLBACK:
@@ -98,6 +99,21 @@ static inline bool TCODFOV_map2d_get_bool(const TCODFOV_Map2D* __restrict map, i
9899
const uint8_t active_bit = 1 << (x % 8);
99100
return (map->bitpacked.data[map->bitpacked.y_stride * y + (x / 8)] & active_bit) != 0;
100101
}
102+
case TCODFOV_MAP2D_CONTIGIOUS: {
103+
const ptrdiff_t index = map->contigious.shape[0] * y + x;
104+
switch (map->contigious.item_type) {
105+
case TCODFOV_DATATYPE_BOOL:
106+
return ((bool*)map->contigious.data)[index];
107+
case TCODFOV_DATATYPE_UINT8:
108+
return ((uint8_t*)map->contigious.data)[index] != 0;
109+
case TCODFOV_DATATYPE_FLOAT:
110+
return ((float*)map->contigious.data)[index] != 0;
111+
case TCODFOV_DATATYPE_DOUBLE:
112+
return ((double*)map->contigious.data)[index] != 0;
113+
default:
114+
return 0;
115+
}
116+
};
101117
default:
102118
return 0;
103119
}
@@ -109,7 +125,6 @@ static inline bool TCODFOV_map2d_get_bool(const TCODFOV_Map2D* __restrict map, i
109125
/// @param y Y coordinate.
110126
/// @param value Assigned value.
111127
static inline void TCODFOV_map2d_set_bool(TCODFOV_Map2D* __restrict map, int x, int y, bool value) {
112-
if (!map) return;
113128
if (!TCODFOV_map2d_in_bounds(map, x, y)) return;
114129
switch (map->type) {
115130
case TCODFOV_MAP2D_CALLBACK:
@@ -137,25 +152,134 @@ static inline void TCODFOV_map2d_set_bool(TCODFOV_Map2D* __restrict map, int x,
137152
map->bitpacked.data[index] = (map->bitpacked.data[index] & ~active_bit) | (value ? active_bit : 0);
138153
return;
139154
}
155+
case TCODFOV_MAP2D_CONTIGIOUS: {
156+
const ptrdiff_t index = map->contigious.shape[0] * y + x;
157+
switch (map->contigious.item_type) {
158+
case TCODFOV_DATATYPE_BOOL:
159+
((bool*)map->contigious.data)[index] = value;
160+
return;
161+
case TCODFOV_DATATYPE_UINT8:
162+
((uint8_t*)map->contigious.data)[index] = value;
163+
return;
164+
case TCODFOV_DATATYPE_FLOAT:
165+
((float*)map->contigious.data)[index] = value;
166+
return;
167+
case TCODFOV_DATATYPE_DOUBLE:
168+
((double*)map->contigious.data)[index] = value;
169+
return;
170+
default:
171+
return;
172+
}
173+
};
140174
default:
141175
return;
142176
}
143177
}
144178

145-
/// @brief Assign `value` to `{x, y}` on `map`. Out-of-bounds writes are ignored.
179+
static inline uint8_t TCODFOV_map2d_get_u8(TCODFOV_Map2D* __restrict map, int x, int y) {
180+
if (!TCODFOV_map2d_in_bounds(map, x, y)) return 0;
181+
switch (map->type) {
182+
case TCODFOV_MAP2D_CONTIGIOUS: {
183+
const ptrdiff_t index = map->contigious.shape[0] * y + x;
184+
switch (map->contigious.item_type) {
185+
case TCODFOV_DATATYPE_BOOL:
186+
return ((bool*)map->contigious.data)[index] ? 255 : 0;
187+
case TCODFOV_DATATYPE_UINT8:
188+
return ((uint8_t*)map->contigious.data)[index];
189+
case TCODFOV_DATATYPE_FLOAT:
190+
return (uint8_t)(((float*)map->contigious.data)[index] * 255.0f);
191+
case TCODFOV_DATATYPE_DOUBLE:
192+
return (uint8_t)(((double*)map->contigious.data)[index] * 255.0);
193+
default:
194+
return 0;
195+
}
196+
};
197+
default:
198+
return TCODFOV_map2d_get_bool(map, x, y) ? 255 : 0;
199+
}
200+
}
201+
202+
/// @brief Assign a normalized `value` to `{x, y}` on `map`. Out-of-bounds writes are ignored.
146203
/// @param map Map union pointer, can be NULL.
147204
/// @param x X coordinate.
148205
/// @param y Y coordinate.
149206
/// @param value Assigned value.
150-
static inline void TCODFOV_map2d_set_int(TCODFOV_Map2D* __restrict map, int x, int y, int value) {
151-
TCODFOV_map2d_set_bool(map, x, y, value != 0); // Fallback until maps can hold integers
207+
static inline void TCODFOV_map2d_set_u8(TCODFOV_Map2D* __restrict map, int x, int y, uint8_t value) {
208+
if (!TCODFOV_map2d_in_bounds(map, x, y)) return;
209+
switch (map->type) {
210+
case TCODFOV_MAP2D_CONTIGIOUS: {
211+
const ptrdiff_t index = map->contigious.shape[0] * y + x;
212+
switch (map->contigious.item_type) {
213+
case TCODFOV_DATATYPE_BOOL:
214+
((bool*)map->contigious.data)[index] = value > 0;
215+
return;
216+
case TCODFOV_DATATYPE_UINT8:
217+
((uint8_t*)map->contigious.data)[index] = value;
218+
return;
219+
case TCODFOV_DATATYPE_FLOAT:
220+
((float*)map->contigious.data)[index] = (float)value * (1.0f / 255.0f);
221+
return;
222+
case TCODFOV_DATATYPE_DOUBLE:
223+
((double*)map->contigious.data)[index] = (double)value * (1.0 / 255.0);
224+
return;
225+
default:
226+
return;
227+
}
228+
};
229+
default:
230+
TCODFOV_map2d_set_bool(map, x, y, value > 0);
231+
return;
232+
}
152233
}
153234

154235
static inline double TCODFOV_map2d_get_d(const TCODFOV_Map2D* __restrict map, int x, int y) {
155-
return TCODFOV_map2d_get_bool(map, x, y) ? 1.0 : 0.0; // Fallback until maps can hold floats
236+
if (!TCODFOV_map2d_in_bounds(map, x, y)) return 0;
237+
switch (map->type) {
238+
case TCODFOV_MAP2D_CONTIGIOUS: {
239+
const ptrdiff_t index = map->contigious.shape[0] * y + x;
240+
switch (map->contigious.item_type) {
241+
case TCODFOV_DATATYPE_BOOL:
242+
return ((bool*)map->contigious.data)[index] ? 1.0 : 0.0;
243+
case TCODFOV_DATATYPE_UINT8:
244+
return (double)((uint8_t*)map->contigious.data)[index] * (1.0 / 255.0);
245+
case TCODFOV_DATATYPE_FLOAT:
246+
return (double)((float*)map->contigious.data)[index];
247+
case TCODFOV_DATATYPE_DOUBLE:
248+
return ((double*)map->contigious.data)[index];
249+
default:
250+
return 0;
251+
}
252+
};
253+
default:
254+
return TCODFOV_map2d_get_bool(map, x, y) ? 1.0 : 0.0;
255+
}
156256
}
157257

158258
static inline void TCODFOV_map2d_set_d(TCODFOV_Map2D* __restrict map, int x, int y, double value) {
159-
TCODFOV_map2d_set_bool(map, x, y, value >= 0.5); // Fallback until maps can hold floats
259+
if (!TCODFOV_map2d_in_bounds(map, x, y)) return;
260+
switch (map->type) {
261+
case TCODFOV_MAP2D_CONTIGIOUS: {
262+
const ptrdiff_t index = map->contigious.shape[0] * y + x;
263+
switch (map->contigious.item_type) {
264+
case TCODFOV_DATATYPE_BOOL:
265+
((bool*)map->contigious.data)[index] = value >= 0.5;
266+
return;
267+
case TCODFOV_DATATYPE_UINT8:
268+
((uint8_t*)map->contigious.data)[index] = (uint8_t)(value * 255.0);
269+
return;
270+
case TCODFOV_DATATYPE_FLOAT:
271+
((float*)map->contigious.data)[index] = (float)value;
272+
return;
273+
case TCODFOV_DATATYPE_DOUBLE:
274+
((double*)map->contigious.data)[index] = value;
275+
return;
276+
default:
277+
return;
278+
}
279+
};
280+
default:
281+
TCODFOV_map2d_set_bool(map, x, y, value >= 0.5);
282+
return;
283+
}
160284
}
161285
#endif // TCODFOV_MAP_INLINE_H_

include/libtcod-fov/map_types.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,16 @@ typedef enum TCODFOV_Map2DType {
1414
TCODFOV_MAP2D_CALLBACK = 1,
1515
TCODFOV_MAP2D_DEPRECATED = 2,
1616
TCODFOV_MAP2D_BITPACKED = 3,
17+
TCODFOV_MAP2D_CONTIGIOUS = 4,
1718
} TCODFOV_Map2DType;
1819

20+
typedef enum TCODFOV_DataType {
21+
TCODFOV_DATATYPE_BOOL = 0,
22+
TCODFOV_DATATYPE_UINT8 = 1,
23+
TCODFOV_DATATYPE_FLOAT = 2,
24+
TCODFOV_DATATYPE_DOUBLE = 3,
25+
} TCODFOV_DataType;
26+
1927
/// @brief Callbacks to get/set on 2D grids.
2028
struct TCODFOV_Map2DCallback {
2129
TCODFOV_Map2DType type; // Must be TCODFOV_MAP2D_CALLBACK
@@ -40,11 +48,20 @@ struct TCODFOV_Map2DBitpacked {
4048
ptrdiff_t y_stride; // Array stride along the y-axis
4149
};
4250

51+
/// @brief Contigious 2D grid.
52+
struct TCODFOV_Map2DContigious {
53+
TCODFOV_Map2DType type; // Must be TCODFOV_MAP2D_CONTIGIOUS
54+
int shape[2]; // {height, width}
55+
unsigned char* __restrict data; // Boolean data packed into bytes
56+
TCODFOV_DataType item_type;
57+
};
58+
4359
/// @brief Union type for 2D maps.
4460
typedef union TCODFOV_Map2D {
4561
TCODFOV_Map2DType type;
4662
struct TCODFOV_Map2DCallback bool_callback;
4763
struct TCODFOV_Map2DDeprecated deprecated_map;
4864
struct TCODFOV_Map2DBitpacked bitpacked;
65+
struct TCODFOV_Map2DContigious contigious;
4966
} TCODFOV_Map2D;
5067
#endif // TCODFOV_MAP_TYPES_H_

src/libtcod-fov/fov_pascal.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
#include "map_inline.h"
88

9+
/// @file fov_pascal.c
10+
/// Pascal’s triangle diffusion, based on a modifed version of this article:
11+
/// https://towardsdatascience.com/a-quick-and-clear-look-at-grid-based-visibility-bf63769fbc78
12+
913
static void pascal_scan_line(
1014
const TCODFOV_Map2D* __restrict transparent, // Input transparency
1115
TCODFOV_Map2D* __restrict out,
@@ -26,6 +30,7 @@ static void pascal_scan_line(
2630
++casts;
2731
visiblity += prev_row[x - x_step];
2832

33+
// Simple case will cause visiblity to cross the diagonal partition. Not sure if this is a major issue yet.
2934
if (pov_x - iteration <= x && x <= pov_x + iteration) { // Cast from previous row
3035
++casts;
3136
visiblity += prev_row[x];

src/libtcod-fov/fov_triage.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ static void triage_scan_next_row(
7171

7272
// Output triage data
7373
for (int x = 0; x < TCODFOV_map2d_get_width(out); ++x) {
74-
TCODFOV_map2d_set_int(out, x, scan_y, next_row[x] & 0b11);
74+
TCODFOV_map2d_set_u8(out, x, scan_y, next_row[x] & 0b11);
7575
}
7676

7777
// Swap next_row and prev_row and continue
@@ -95,7 +95,7 @@ static void triage_scan_init(
9595
if (row[x - 1] & 0b100) row[x] = TCODFOV_map2d_get_bool(transparent, x, pov_y) ? 0b111 : 0b011;
9696
}
9797
for (int x = 0; x < TCODFOV_map2d_get_width(out); ++x) {
98-
TCODFOV_map2d_set_int(out, x, pov_y, row[x] & 0b11);
98+
TCODFOV_map2d_set_u8(out, x, pov_y, row[x] & 0b11);
9999
}
100100
}
101101

0 commit comments

Comments
 (0)