]>
git.bts.cx Git - benzene.git/blob - src/bz/game/tilemap.c
1 #include <bz/game/tilemap_internal.h>
3 #include <bz/math/random.h>
4 #include <bz/memory/allocator.h>
5 #include <bz/resources/resource.h>
6 #include <bz/types/identifier_internal.h>
9 static uint32_t tilemapAddTileTagFlag(BZTilemapID tilemap
, BZIdentifierHash tag
) {
10 for (size_t i
= 0; i
< 32; ++i
) {
11 if (tag
== tilemap
->tags
[i
]) {
15 if (tilemap
->tags
[i
] == 0) {
16 tilemap
->tags
[i
] = tag
;
21 bzAssertMessage(false, "Out of flags");
26 BZTilemapID
bzGameLoadTilemap(BZMemoryArenaID arena
, const char *identifierFmt
, ...) {
27 bzMakeIdentifier(identifier
, identifierFmt
);
29 BZResourceID handle
= bzResourcesOpenResource("tilemap", "assets/tilemaps/%s.tilemap.json", identifier
);
30 size_t length
= bzResourcesFileLength(handle
);
31 char *data
= (char *)alloca(length
); // FIXME, need working space off the stack
32 bzResourcesReadBytes(handle
, data
, length
);
33 bzResourcesCloseResource(handle
);
35 //json_set_allocation_functions
36 JSON_Value
*tilemapJson
= json_parse_string(data
);
37 JSON_Object
*tilemapJsonObject
= json_object(tilemapJson
);
39 size_t tilemapWidth
= json_object_get_number(tilemapJsonObject
, "width");
40 size_t tilemapHeight
= json_object_get_number(tilemapJsonObject
, "height");
42 BZTilemap
*tilemap
= (BZTilemap
*)bzMemoryAlloc(arena
, sizeof(BZTilemap
) + tilemapWidth
* tilemapHeight
* sizeof(BZTilemapTile
));
43 tilemap
->width
= tilemapWidth
;
44 tilemap
->height
= tilemapHeight
;
46 JSON_Array
*tilesArray
= json_object_get_array(tilemapJsonObject
, "tiles");
47 size_t tilesArraySize
= json_array_get_count(tilesArray
);
48 for (size_t y
= 0, i
= 0; y
< tilemap
->height
; ++y
) {
49 for (size_t x
= 0; x
< tilemap
->width
; ++x
, ++i
) {
50 if (i
< tilesArraySize
) {
51 uint8_t t
= (uint8_t)json_array_get_number(tilesArray
, i
);
52 tilemap
->tiles
[i
].tileDefinitionIdx
= t
;
53 tilemap
->tiles
[i
].spriteIdx
= 0;
55 bzAssert(t
< 256); // fixme, define
56 tilemap
->tileDefinitions
[t
].spriteIdx
= t
;
57 tilemap
->tileDefinitions
[t
].height
= 1;
58 tilemap
->tileDefinitions
[t
].tagsFlag
= 0;
60 tilemap
->tiles
[i
].tileDefinitionIdx
= 0;
61 tilemap
->tiles
[i
].spriteIdx
= 0;
66 JSON_Array
*tileTagArray
= json_object_get_array(tilemapJsonObject
, "tags");
67 size_t tileTagArraySize
= json_array_get_count(tileTagArray
);
68 for (size_t i
= 0; i
< tileTagArraySize
; ++i
) {
69 JSON_Object
*tileTagObject
= json_array_get_object(tileTagArray
, i
);
70 BZIdentifierHash tag
= bzIdentifierHashFromIdentifier(json_object_get_string(tileTagObject
, "tag"));
72 uint32_t tagsFlag
= tilemapAddTileTagFlag(tilemap
, tag
);
74 JSON_Array
*tileArray
= json_object_get_array(tileTagObject
, "tiles");
75 size_t tileArraySize
= json_array_get_count(tileArray
);
76 for (size_t j
= 0; j
< tileArraySize
; ++j
) {
77 size_t t
= (size_t)json_array_get_number(tileArray
, j
);
78 bzAssert(t
< 256); // fixme, define
79 tilemap
->tileDefinitions
[t
].tagsFlag
|= tagsFlag
;
83 JSON_Array
*tileDefinitionArray
= json_object_get_array(tilemapJsonObject
, "definitions");
84 size_t tileDefinitionArraySize
= json_array_get_count(tileDefinitionArray
);
85 for (size_t i
= 0; i
< tileDefinitionArraySize
; ++i
) {
86 JSON_Object
*tileDefinitionObject
= json_array_get_object(tileDefinitionArray
, i
);
87 size_t tileIndex
= json_object_get_number(tileDefinitionObject
, "tile");
88 bzAssert(tileIndex
< 256); // fixme
90 if (json_object_has_value(tileDefinitionObject
, "height")) {
91 tilemap
->tileDefinitions
[tileIndex
].height
= json_object_get_number(tileDefinitionObject
, "height");
94 if (json_object_has_value(tileDefinitionObject
, "tags")) {
95 JSON_Array
*tileTagArray
= json_object_get_array(tileDefinitionObject
, "tags");
96 size_t tileTagArraySize
= json_array_get_count(tileTagArray
);
97 for (size_t j
= 0; j
< tileTagArraySize
; ++j
) {
98 BZIdentifierHash tag
= bzIdentifierHashFromIdentifier(json_array_get_string(tileTagArray
, j
));
100 uint32_t tagsFlag
= tilemapAddTileTagFlag(tilemap
, tag
);
102 tilemap
->tileDefinitions
[tileIndex
].tagsFlag
|= tagsFlag
;
106 if (json_object_has_value(tileDefinitionObject
, "sprite")) {
107 JSON_Array
*tileSpritesArray
= json_object_get_array(tileDefinitionObject
, "sprite");
108 size_t tileSpritesArraySize
= json_array_get_count(tileSpritesArray
);
109 for (size_t y
= 0, j
= 0; y
< tilemap
->height
; ++y
) {
110 for (size_t x
= 0; x
< tilemap
->width
; ++x
, ++j
) {
111 if (tilemap
->tiles
[j
].tileDefinitionIdx
== tileIndex
) {
112 tilemap
->tiles
[j
].spriteIdx
= (uint8_t)json_array_get_number(tileSpritesArray
, bzRandomInteger(tileSpritesArraySize
));
119 json_value_free(tilemapJson
);
124 uint8_t bzGameGetTilemapTile(BZTilemapID tilemap
, uint8_t mx
, uint8_t my
) {
125 size_t tileIdx
= my
* tilemap
->width
+ mx
;
127 //uint8_t spriteIdx = 0;
129 uint8_t tileDefinitionIdx
= tilemap
->tiles
[tileIdx
].tileDefinitionIdx
;
130 /*if (tileDefinitionIdx > 0) {
131 spriteIdx = tilemap->tiles[tileIdx].spriteIdx;
132 if (spriteIdx == 0) {
133 spriteIdx = tilemap->tileDefinitions[tileDefinitionIdx].spriteIdx;
137 return tileDefinitionIdx
;
140 uint8_t bzGameGetTilemapSprite(BZTilemapID tilemap
, uint8_t mx
, uint8_t my
) {
141 size_t tileIdx
= my
* tilemap
->width
+ mx
;
143 uint8_t spriteIdx
= 0;
145 uint8_t tileDefinitionIdx
= bzGameGetTilemapTile(tilemap
, mx
, my
);
146 if (tileDefinitionIdx
> 0) {
147 spriteIdx
= tilemap
->tiles
[tileIdx
].spriteIdx
;
148 if (spriteIdx
== 0) {
149 spriteIdx
= tilemap
->tileDefinitions
[tileDefinitionIdx
].spriteIdx
;
156 uint8_t bzGameSetTilemapTile(BZTilemapID tilemap
, uint8_t mx
, uint8_t my
, uint8_t idx
) {
157 size_t tileIdx
= my
* tilemap
->width
+ mx
;
158 tilemap
->tiles
[tileIdx
].spriteIdx
= idx
;
159 return bzGameGetTilemapTile(tilemap
, mx
, my
);
162 bool bzGameGetTilemapHasFlag(BZTilemapID tilemap
, uint8_t mx
, uint8_t my
, BZIdentifierHash tag
) {
163 uint32_t flagMask
= bzGameCalculateTilemapFlagsMask(tilemap
, 1, &tag
);
164 uint8_t tileDefinitionIdx
= bzGameGetTilemapTile(tilemap
, mx
, my
);
165 return (tilemap
->tileDefinitions
[tileDefinitionIdx
].tagsFlag
& flagMask
) > 0;
168 uint32_t bzGameCalculateTilemapFlagsMask(BZTilemapID tilemap
, size_t tagCount
, BZIdentifierHash tags
[]) {
169 uint32_t flagMask
= 0;
171 for (size_t i
= 0; i
< tagCount
; ++i
) {
172 for (size_t j
= 0; j
< 32; ++j
) {
173 if (tags
[i
] == tilemap
->tags
[j
]) {