+17
-12
include/keraforge/world.h
+17
-12
include/keraforge/world.h
···
10
10
11
11
#define KF_TILE_SIZE_PX 16
12
12
13
-
#define KF_TILEID_MAX UINT16_MAX
13
+
#define KF_TILE_IDWIDTH 10
14
+
#define KF_TILE_DATAWIDTH 4
15
+
16
+
#define KF_TILEID_MAX (1023) /* 2^10-1 */
17
+
18
+
/* Used to store tile IDs. Stored in 10 bits; max value is 1023! */
14
19
typedef u16 kf_tileid_t;
15
-
/* Used to store connectivity variant. */
16
-
typedef u16 kf_tiledatum_t;
20
+
/* Used to store connectivity variant. Stored in 4 bits; max value is 15! */
21
+
typedef u8 kf_tiledatum_t;
17
22
18
23
19
24
struct kf_actor; /* Forward declaration */
20
25
21
26
22
-
#define KF_TILEMASK_NORTH (0x0001)
23
-
#define KF_TILEMASK_WEST (0x0010)
24
-
#define KF_TILEMASK_EAST (0x0100)
25
-
#define KF_TILEMASK_SOUTH (0x1000)
27
+
#define KF_TILEMASK_NORTH (0b0001)
28
+
#define KF_TILEMASK_WEST (0b0010)
29
+
#define KF_TILEMASK_EAST (0b0100)
30
+
#define KF_TILEMASK_SOUTH (0b1000)
26
31
27
32
28
33
/* Represents a singular tile in the world. */
29
34
struct kf_tile
30
35
{
31
-
kf_tileid_t subid;
32
-
kf_tileid_t id;
33
-
kf_tiledatum_t data;
34
-
};
36
+
kf_tileid_t subid : KF_TILE_IDWIDTH;
37
+
kf_tileid_t id : KF_TILE_IDWIDTH;
38
+
kf_tiledatum_t data : KF_TILE_DATAWIDTH;
39
+
} __attribute__((packed));
35
40
36
41
/* Represents a world (or a subworld, often called "rooms"). */
37
42
struct kf_world
···
93
98
size_t kf_world_getsize(struct kf_world *world);
94
99
95
100
/* Get the sprite offset for a given tile datum. */
96
-
struct kf_vec2(u32) kf_getspritefortilebitmask(kf_tiledatum_t t);
101
+
struct kf_vec2(u32) kf_getspritefordatum(kf_tiledatum_t t);
97
102
98
103
/* Update a tile and optionally its neighbours. */
99
104
void kf_world_updatetile(struct kf_world *world, u32 x, u32 y, bool update_neighbours);
+1
-1
src/input.c
+1
-1
src/input.c
···
21
21
}
22
22
kf_inputbinds.count++;
23
23
24
-
kf_logdbg("add keybind: %d: %s (k=%d a=%d m=%d g=%d x=%d)", i, id, key, alt, mouse, gamepad, axis);
24
+
// kf_logdbg("add keybind: %d: %s (k=%d a=%d m=%d g=%d x=%d)", i, id, key, alt, mouse, gamepad, axis);
25
25
kf_inputbinds.id[i] = id;
26
26
kf_inputbinds.key[i] = key;
27
27
kf_inputbinds.alt[i] = alt;
+1
-2
src/main.c
+1
-2
src/main.c
···
341
341
selected_tile = t->id;
342
342
343
343
DrawRectangleLines(select.x * KF_TILE_SIZE_PX, select.y * KF_TILE_SIZE_PX, KF_TILE_SIZE_PX, KF_TILE_SIZE_PX, WHITE);
344
-
struct kf_vec2(u32) s = kf_getspritefortilebitmask(t->data);
345
-
DrawText(TextFormat("%d [0x%04x] (%d,%d) {%d,%d}", t->id, t->data, select.x, select.y, s.x, s.y), select.x * KF_TILE_SIZE_PX, select.y * KF_TILE_SIZE_PX - 10, 10, BLACK);
344
+
DrawText(TextFormat("%d [%d] (%d,%d)", t->id, t->data, select.x, select.y), select.x * KF_TILE_SIZE_PX, select.y * KF_TILE_SIZE_PX - 10, 10, BLACK);
346
345
}
347
346
player->draw(world, player);
348
347
EndMode2D();
+28
-26
src/world.c
+28
-26
src/world.c
···
72
72
w = x-1 >= world->width ? 0 : kf_world_gettile(world, x-1, y)->id,
73
73
e = x+1 >= world->width ? 0 : kf_world_gettile(world, x+1, y)->id,
74
74
s = y+1 >= world->height ? 0 : kf_world_gettile(world, x, y+1)->id;
75
-
t->data = 0x0000;
75
+
t->data = 0b0000;
76
76
if (t->id == n) t->data |= KF_TILEMASK_NORTH;
77
77
if (t->id == w) t->data |= KF_TILEMASK_WEST;
78
78
if (t->id == e) t->data |= KF_TILEMASK_EAST;
···
92
92
}
93
93
94
94
inline
95
-
struct kf_vec2(u32) kf_getspritefortilebitmask(kf_tiledatum_t t)
95
+
struct kf_vec2(u32) kf_getspritefordatum(kf_tiledatum_t t)
96
96
{
97
-
switch (t)
98
-
{
99
-
case 0x0000: return (struct kf_vec2(u32)){0, 3}; /* 0x0000: */
100
-
case 0x0001: return (struct kf_vec2(u32)){0, 2}; /* 0x0001: N */
101
-
case 0x0010: return (struct kf_vec2(u32)){3, 3}; /* 0x0010: W */
102
-
case 0x0011: return (struct kf_vec2(u32)){3, 2}; /* 0x0011: NW */
103
-
case 0x0100: return (struct kf_vec2(u32)){1, 3}; /* 0x0100: E */
104
-
case 0x0101: return (struct kf_vec2(u32)){1, 2}; /* 0x0101: EN */
105
-
case 0x0110: return (struct kf_vec2(u32)){2, 3}; /* 0x0110: EW */
106
-
case 0x0111: return (struct kf_vec2(u32)){2, 2}; /* 0x0111: EWN */
107
-
case 0x1000: return (struct kf_vec2(u32)){0, 0}; /* 0x1000: S */
108
-
case 0x1001: return (struct kf_vec2(u32)){0, 1}; /* 0x1001: SN */
109
-
case 0x1010: return (struct kf_vec2(u32)){3, 0}; /* 0x1010: SW */
110
-
case 0x1011: return (struct kf_vec2(u32)){3, 1}; /* 0x1011: SWN */
111
-
case 0x1100: return (struct kf_vec2(u32)){1, 0}; /* 0x1100: SE */
112
-
case 0x1101: return (struct kf_vec2(u32)){1, 1}; /* 0x1101: SEN */
113
-
case 0x1110: return (struct kf_vec2(u32)){2, 0}; /* 0x1110: SEW */
114
-
case 0x1111: return (struct kf_vec2(u32)){2, 1}; /* 0x1111: NESW */
115
-
}
116
-
KF_UNREACHABLE("invalid bitmask: 0x%x", t);
117
-
return (struct kf_vec2(u32)){-1, -1};
97
+
static const
98
+
struct kf_vec2(u32) v[] = {
99
+
{0, 3}, /* 0b0000: */
100
+
{0, 2}, /* 0b0001: N */
101
+
{3, 3}, /* 0b0010: W */
102
+
{3, 2}, /* 0b0011: NW */
103
+
{1, 3}, /* 0b0100: E */
104
+
{1, 2}, /* 0b0101: EN */
105
+
{2, 3}, /* 0b0110: EW */
106
+
{2, 2}, /* 0b0111: EWN */
107
+
{0, 0}, /* 0b1000: S */
108
+
{0, 1}, /* 0b1001: SN */
109
+
{3, 0}, /* 0b1010: SW */
110
+
{3, 1}, /* 0b1011: SWN */
111
+
{1, 0}, /* 0b1100: SE */
112
+
{1, 1}, /* 0b1101: SEN */
113
+
{2, 0}, /* 0b1110: SEW */
114
+
{2, 1}, /* 0b1111: NESW */
115
+
};
116
+
return v[t];
118
117
}
119
118
120
119
struct kf_tile *kf_world_gettile(struct kf_world *world, u32 x, u32 y)
···
184
183
for (x = sx ; x < ex ; x++)
185
184
{
186
185
KF_SANITY_CHECK(tile->subid <= kf_tiles.count, "erroneous subtile on map at %u,%u: %u (count=%u)", x, y, tile->subid, kf_tiles.count);
187
-
/* 0x1111: full tile, no subtile rendering needed */
188
186
KF_SANITY_CHECK(tile->id <= kf_tiles.count, "erroneous tile on map at %u,%u: %u (count=%u)", x, y, tile->id, kf_tiles.count);
189
-
if ((tile->data != 0x1111 || kf_tiles.transparent[tile->id]) && tile->subid && tile->id)
187
+
188
+
/* 15: full tile, no subtile rendering needed (unless transparent) */
189
+
if ((tile->data != 15 || kf_tiles.transparent[tile->id]) && tile->subid && tile->id)
190
190
{
191
191
kf_drawsprite_wh(
192
192
kf_tiles.sheet[tile->subid],
···
198
198
kf_tiles.sprite[tile->subid].y + 1
199
199
);
200
200
}
201
+
201
202
if (tile->id)
202
203
{
203
-
struct kf_vec2(u32) s = kf_getspritefortilebitmask(tile->data);
204
+
struct kf_vec2(u32) s = kf_getspritefordatum(tile->data);
204
205
kf_drawsprite_wh(
205
206
kf_tiles.sheet[tile->id],
206
207
x*KF_TILE_SIZE_PX,
···
211
212
kf_tiles.sprite[tile->id].y + s.y
212
213
);
213
214
}
215
+
214
216
tile++; /* shift tile pointer to the right */
215
217
}
216
218
tile += down; /* shift tile pointer down */