load map first pass
This commit is contained in:
@@ -20,7 +20,10 @@ assetdef_t ASSET_DEFINITIONS[ASSET_TYPE_COUNT] = {
|
|||||||
},
|
},
|
||||||
[ASSET_TYPE_CONFIG] = {
|
[ASSET_TYPE_CONFIG] = {
|
||||||
"DCF", assetConfigLoad, assetConfigDispose
|
"DCF", assetConfigLoad, assetConfigDispose
|
||||||
}
|
},
|
||||||
|
[ASSET_TYPE_RPG_MAP] = {
|
||||||
|
"DRM", assetRPGMapLoad, assetRPGMapDispose
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
errorret_t assetInit(asset_t *asset, const char_t *filename) {
|
errorret_t assetInit(asset_t *asset, const char_t *filename) {
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include "asset/type/assetpaletteimage.h"
|
#include "asset/type/assetpaletteimage.h"
|
||||||
#include "asset/type/assetalphaimage.h"
|
#include "asset/type/assetalphaimage.h"
|
||||||
#include "asset/type/assetconfig.h"
|
#include "asset/type/assetconfig.h"
|
||||||
|
#include "asset/type/assetrpgmap.h"
|
||||||
|
|
||||||
#define ASSET_HEADER_SIZE 3
|
#define ASSET_HEADER_SIZE 3
|
||||||
#define ASSET_REFERENCE_COUNT_MAX 8
|
#define ASSET_REFERENCE_COUNT_MAX 8
|
||||||
@@ -33,6 +34,7 @@ typedef enum {
|
|||||||
ASSET_TYPE_PALETTE_IMAGE,
|
ASSET_TYPE_PALETTE_IMAGE,
|
||||||
ASSET_TYPE_ALPHA_IMAGE,
|
ASSET_TYPE_ALPHA_IMAGE,
|
||||||
ASSET_TYPE_CONFIG,
|
ASSET_TYPE_CONFIG,
|
||||||
|
ASSET_TYPE_RPG_MAP,
|
||||||
|
|
||||||
ASSET_TYPE_COUNT
|
ASSET_TYPE_COUNT
|
||||||
} assettype_t;
|
} assettype_t;
|
||||||
@@ -47,8 +49,9 @@ typedef struct asset_s {
|
|||||||
|
|
||||||
union {
|
union {
|
||||||
assetpaletteimage_t paletteImage;
|
assetpaletteimage_t paletteImage;
|
||||||
assetalphaimager_t alphaImage;
|
assetalphaimage_t alphaImage;
|
||||||
assetconfig_t config;
|
assetconfig_t config;
|
||||||
|
assetrpgmap_t rpgMap;
|
||||||
};
|
};
|
||||||
} asset_t;
|
} asset_t;
|
||||||
|
|
||||||
|
@@ -9,4 +9,5 @@ target_sources(${DUSK_TARGET_NAME}
|
|||||||
assetalphaimage.c
|
assetalphaimage.c
|
||||||
assetconfig.c
|
assetconfig.c
|
||||||
assetpaletteimage.c
|
assetpaletteimage.c
|
||||||
|
assetrpgmap.c
|
||||||
)
|
)
|
@@ -27,7 +27,7 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
texture_t texture;
|
texture_t texture;
|
||||||
} assetalphaimager_t;
|
} assetalphaimage_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads an alpha image asset from the given asset structure. The asset must
|
* Loads an alpha image asset from the given asset structure. The asset must
|
||||||
|
98
src/asset/type/assetrpgmap.c
Normal file
98
src/asset/type/assetrpgmap.c
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "assetrpgmap.h"
|
||||||
|
#include "asset/asset.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "display/tileset/tilesetlist.h"
|
||||||
|
|
||||||
|
errorret_t assetRPGMapLoad(asset_t *asset) {
|
||||||
|
assertNotNull(asset, "Asset cannot be NULL.");
|
||||||
|
assertTrue(
|
||||||
|
asset->type == ASSET_TYPE_RPG_MAP,
|
||||||
|
"Asset is not of type ASSET_TYPE_RPG_MAP."
|
||||||
|
);
|
||||||
|
|
||||||
|
assetrpgmapraw_t raw;
|
||||||
|
|
||||||
|
// Read map header info
|
||||||
|
zip_int64_t bytesRead = zip_fread(
|
||||||
|
asset->file, &raw.header, sizeof(assetrpgmapheader_t)
|
||||||
|
);
|
||||||
|
if(bytesRead != sizeof(raw.header)) {
|
||||||
|
errorThrow("Failed to read RPG map header.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(raw.header.mapWidth == 0 || raw.header.mapWidth > MAP_WIDTH_MAX) {
|
||||||
|
errorThrow("Invalid RPG map width.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(raw.header.mapHeight == 0 || raw.header.mapHeight > MAP_HEIGHT_MAX) {
|
||||||
|
errorThrow("Invalid RPG map height.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(raw.header.tilesetCount == 0) {
|
||||||
|
errorThrow("Invalid RPG map tileset count.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(raw.header.tilesetCount > ASSET_RPG_MAP_TILESET_COUNT_MAX) {
|
||||||
|
errorThrow("Invalid RPG map tileset count.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(raw.header.tileLayerCount == 0) {
|
||||||
|
errorThrow("Invalid RPG map layer count.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(raw.header.tileLayerCount > MAP_LAYER_COUNT_MAX) {
|
||||||
|
errorThrow("Invalid RPG map layer count.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read layers
|
||||||
|
for(uint32_t layer = 0; layer < raw.header.tileLayerCount; layer++) {
|
||||||
|
// Read width * height tiles
|
||||||
|
bytesRead = zip_fread(
|
||||||
|
asset->file,
|
||||||
|
&raw.layers[layer].tiles,
|
||||||
|
sizeof(assetrpgmaptile_t) * raw.header.mapWidth * raw.header.mapHeight
|
||||||
|
);
|
||||||
|
if(bytesRead != (
|
||||||
|
sizeof(assetrpgmaptile_t) * raw.header.mapWidth * raw.header.mapHeight
|
||||||
|
)) errorThrow("Failed to read RPG map layer %u.", layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each tileset
|
||||||
|
for(uint32_t tileset = 0; tileset < raw.header.tilesetCount; tileset++) {
|
||||||
|
// Read tileset
|
||||||
|
bytesRead = zip_fread(
|
||||||
|
asset->file,
|
||||||
|
&raw.tilesets[tileset],
|
||||||
|
sizeof(assetrpgmaptileset_t)
|
||||||
|
);
|
||||||
|
if(bytesRead != sizeof(assetrpgmaptileset_t)) {
|
||||||
|
errorThrow("Failed to read RPG map tileset %u.", tileset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map data is loaded, we can load it into the map structure.
|
||||||
|
mapInit(&asset->rpgMap.map);
|
||||||
|
|
||||||
|
entity_t *ent;
|
||||||
|
ent = mapEntityAdd(&asset->rpgMap.map);
|
||||||
|
entityInit(ent, ENTITY_TYPE_PLAYER, &asset->rpgMap.map);
|
||||||
|
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t assetRPGMapDispose(asset_t *asset) {
|
||||||
|
assertNotNull(asset, "Asset cannot be NULL.");
|
||||||
|
assertTrue(
|
||||||
|
asset->type == ASSET_TYPE_RPG_MAP,
|
||||||
|
"Asset is not of type ASSET_TYPE_RPG_MAP."
|
||||||
|
);
|
||||||
|
|
||||||
|
errorOk();
|
||||||
|
}
|
64
src/asset/type/assetrpgmap.h
Normal file
64
src/asset/type/assetrpgmap.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "error/error.h"
|
||||||
|
#include "rpg/world/map.h"
|
||||||
|
|
||||||
|
typedef struct asset_s asset_t;
|
||||||
|
|
||||||
|
#define ASSET_RPG_MAP_TILESET_COUNT_MAX 16
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct {
|
||||||
|
uint32_t mapWidth;
|
||||||
|
uint32_t mapHeight;
|
||||||
|
uint32_t tilesetCount;
|
||||||
|
uint32_t tileLayerCount;
|
||||||
|
} assetrpgmapheader_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t firstGid;
|
||||||
|
uint32_t tilesetIndex;
|
||||||
|
} assetrpgmaptileset_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t tilesetIndex;
|
||||||
|
} assetrpgmaptile_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
assetrpgmaptile_t tiles[MAP_TILE_COUNT_MAX];
|
||||||
|
} assetrpgmaplayer_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
assetrpgmapheader_t header;
|
||||||
|
assetrpgmaplayer_t layers[MAP_LAYER_COUNT_MAX];
|
||||||
|
assetrpgmaptileset_t tilesets[ASSET_RPG_MAP_TILESET_COUNT_MAX];
|
||||||
|
} assetrpgmapraw_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
map_t map;
|
||||||
|
} assetrpgmap_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads an RPG map asset from the given asset structure. The asset must be of
|
||||||
|
* type ASSET_TYPE_RPG_MAP and must be loaded.
|
||||||
|
*
|
||||||
|
* @param asset The asset to load the RPG map from.
|
||||||
|
* @return An error code.
|
||||||
|
*/
|
||||||
|
errorret_t assetRPGMapLoad(asset_t *asset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes of an RPG map asset, freeing any allocated resources.
|
||||||
|
*
|
||||||
|
* @param asset The asset to dispose of.
|
||||||
|
* @return An error code.
|
||||||
|
*/
|
||||||
|
errorret_t assetRPGMapDispose(asset_t *asset);
|
@@ -37,9 +37,11 @@ errorret_t sceneOverworldInit(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sceneOverworldUpdate(void) {
|
void sceneOverworldUpdate(void) {
|
||||||
|
if(RPG.map == NULL) return;
|
||||||
|
|
||||||
// Move camera to player.
|
// Move camera to player.
|
||||||
const entity_t *start = &testMap.entities[0];
|
const entity_t *start = &RPG.map->entities[0];
|
||||||
const entity_t *end = &testMap.entities[testMap.entityCount];
|
const entity_t *end = &RPG.map->entities[RPG.map->entityCount];
|
||||||
while(start < end) {
|
while(start < end) {
|
||||||
if(start->type == ENTITY_TYPE_PLAYER) {
|
if(start->type == ENTITY_TYPE_PLAYER) {
|
||||||
SCENE_OVERWORLD.camera.lookat.target[0] = start->position[0];
|
SCENE_OVERWORLD.camera.lookat.target[0] = start->position[0];
|
||||||
@@ -70,7 +72,7 @@ void sceneOverworldRender(void) {
|
|||||||
|
|
||||||
cameraPushMatrix(&SCENE_OVERWORLD.camera);
|
cameraPushMatrix(&SCENE_OVERWORLD.camera);
|
||||||
|
|
||||||
sceneOverworldRenderMap(&testMap);
|
if(RPG.map != NULL) sceneOverworldRenderMap(RPG.map);
|
||||||
|
|
||||||
spriteBatchFlush();
|
spriteBatchFlush();
|
||||||
cameraPopMatrix();
|
cameraPopMatrix();
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "display/camera.h"
|
#include "display/camera.h"
|
||||||
#include "rpg/world/map.h"
|
#include "rpg/rpg.h"
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@@ -6,28 +6,44 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "rpg.h"
|
#include "rpg.h"
|
||||||
|
|
||||||
#include "rpg/world/map.h"
|
#include "rpg/world/map.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "asset/assetmanager.h"
|
||||||
|
|
||||||
map_t testMap;
|
rpg_t RPG;
|
||||||
|
|
||||||
|
asset_t *asset;
|
||||||
|
ref_t assetRef;
|
||||||
|
|
||||||
void rpgInit() {
|
void rpgInit() {
|
||||||
mapInit(&testMap);
|
memoryZero(&RPG, sizeof(RPG));
|
||||||
testMap.width = 2;
|
|
||||||
testMap.height = 2;
|
errorret_t ret = assetManagerLoadAsset("map/untitled.drm", &asset, &assetRef);
|
||||||
for(uint32_t i = 0; i < testMap.width * testMap.height; i++) {
|
if(ret.code != ERROR_OK) {
|
||||||
testMap.base.tiles[i].id = 1;
|
errorPrint(ret);
|
||||||
|
errorCatch(ret);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
RPG.map = &asset->rpgMap.map;
|
||||||
|
|
||||||
entity_t *ent = mapEntityAdd(&testMap);
|
// mapInit(&testMap);
|
||||||
entityInit(ent, ENTITY_TYPE_PLAYER, &testMap);
|
// testMap.width = 2;
|
||||||
|
// testMap.height = 2;
|
||||||
|
// for(uint32_t i = 0; i < testMap.width * testMap.height; i++) {
|
||||||
|
// testMap.base.tiles[i].id = 1;
|
||||||
|
// }
|
||||||
|
|
||||||
entity_t *npc = mapEntityAdd(&testMap);
|
// entity_t *ent = mapEntityAdd(&testMap);
|
||||||
entityInit(npc, ENTITY_TYPE_NPC, &testMap);
|
// entityInit(ent, ENTITY_TYPE_PLAYER, &testMap);
|
||||||
npc->position[0] = 32.0f;
|
|
||||||
npc->position[1] = 32.0f;
|
// entity_t *npc = mapEntityAdd(&testMap);
|
||||||
|
// entityInit(npc, ENTITY_TYPE_NPC, &testMap);
|
||||||
|
// npc->position[0] = 32.0f;
|
||||||
|
// npc->position[1] = 32.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpgUpdate() {
|
void rpgUpdate() {
|
||||||
mapUpdate(&testMap);
|
if(RPG.map != NULL) {
|
||||||
|
mapUpdate(RPG.map);
|
||||||
|
}
|
||||||
}
|
}
|
@@ -6,6 +6,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "rpg/world/map.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
map_t *map;
|
||||||
|
} rpg_t;
|
||||||
|
|
||||||
|
extern rpg_t RPG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the RPG subsystem.
|
* Initializes the RPG subsystem.
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#define MAP_WIDTH_MAX 64
|
#define MAP_WIDTH_MAX 64
|
||||||
#define MAP_HEIGHT_MAX 64
|
#define MAP_HEIGHT_MAX 64
|
||||||
#define MAP_TILE_COUNT_MAX (MAP_WIDTH_MAX * MAP_HEIGHT_MAX)
|
#define MAP_TILE_COUNT_MAX (MAP_WIDTH_MAX * MAP_HEIGHT_MAX)
|
||||||
|
#define MAP_LAYER_COUNT_MAX 2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t id;
|
uint8_t id;
|
||||||
|
@@ -2,6 +2,7 @@ import sys, os
|
|||||||
from args import inputAssets, args
|
from args import inputAssets, args
|
||||||
from processasset import processAsset
|
from processasset import processAsset
|
||||||
from processpalette import processPaletteList
|
from processpalette import processPaletteList
|
||||||
|
from processtileset import processTilesetList
|
||||||
from assethelpers import getBuiltAssetsRelativePath
|
from assethelpers import getBuiltAssetsRelativePath
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ with zipfile.ZipFile(outputFileName, 'w') as zipf:
|
|||||||
|
|
||||||
# Generate additional headers.
|
# Generate additional headers.
|
||||||
processPaletteList()
|
processPaletteList()
|
||||||
|
processTilesetList()
|
||||||
|
|
||||||
# Finalize build
|
# Finalize build
|
||||||
if args.build_type == 'header':
|
if args.build_type == 'header':
|
||||||
|
@@ -109,42 +109,21 @@ def processMap(asset):
|
|||||||
|
|
||||||
# Now we have our layers all parsed out.
|
# Now we have our layers all parsed out.
|
||||||
data = bytearray()
|
data = bytearray()
|
||||||
data += b'drm' # Dusk RPG Map
|
data += b'DRM' # Dusk RPG Map
|
||||||
data += mapWidth.to_bytes(4, 'little') # Map width in tiles
|
data += mapWidth.to_bytes(4, 'little') # Map width in tiles
|
||||||
data += mapHeight.to_bytes(4, 'little') # Map height in tiles
|
data += mapHeight.to_bytes(4, 'little') # Map height in tiles
|
||||||
data += len(tilesets).to_bytes(4, 'little') # Number of tilesets
|
data += len(tilesets).to_bytes(4, 'little') # Number of tilesets
|
||||||
data += len(tileLayers).to_bytes(4, 'little') # Number of layers
|
data += len(tileLayers).to_bytes(4, 'little') # Number of layers
|
||||||
|
|
||||||
# For each tileset
|
|
||||||
for tileset in tilesets:
|
|
||||||
data += tileset['firstGid'].to_bytes(4, 'little') # First GID
|
|
||||||
|
|
||||||
# For each layer...
|
# For each layer...
|
||||||
for layer in tileLayers:
|
for layer in tileLayers:
|
||||||
for gid in layer['data']:
|
for gid in layer['data']:
|
||||||
# Get tileset for this gid, since the tilesets are already sorted we can
|
data += gid.to_bytes(4, 'little') # Tileset index
|
||||||
# simply find the first one that has firstGid <= gid
|
|
||||||
if gid == 0:
|
|
||||||
# Empty tile
|
|
||||||
localIndex = 0xFF
|
|
||||||
tilesetIndex = 0xFFFFFFFF
|
|
||||||
else:
|
|
||||||
for tileset in tilesets:
|
|
||||||
if gid >= tileset['firstGid']:
|
|
||||||
tilesetIndex = tilesets.index(tileset)
|
|
||||||
localIndex = gid - tileset['firstGid']
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
# If no tileset was found, this is an invalid gid
|
|
||||||
print(f"Error: Invalid tile GID {gid} in {asset['path']}")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if localIndex > 255:
|
# For each tileset
|
||||||
print(f"Error: Local tile index {localIndex} exceeds 255 in {asset['path']}")
|
for tileset in tilesets:
|
||||||
sys.exit(1)
|
data += tileset['firstGid'].to_bytes(4, 'little') # First GID
|
||||||
|
data += tileset['tileset']['tilesetIndex'].to_bytes(4, 'little') # Tileset index
|
||||||
data += tilesetIndex.to_bytes(4, 'little') # Tileset index
|
|
||||||
data += localIndex.to_bytes(1, 'little') # Local tile index
|
|
||||||
|
|
||||||
relative = getAssetRelativePath(asset['path'])
|
relative = getAssetRelativePath(asset['path'])
|
||||||
fileNameWithoutExt = os.path.splitext(os.path.basename(asset['path']))[0]
|
fileNameWithoutExt = os.path.splitext(os.path.basename(asset['path']))[0]
|
||||||
|
@@ -8,6 +8,8 @@ from args import args
|
|||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
from assetcache import assetGetCache, assetCache
|
from assetcache import assetGetCache, assetCache
|
||||||
|
|
||||||
|
tilesets = []
|
||||||
|
|
||||||
def loadTilesetFromTSX(asset):
|
def loadTilesetFromTSX(asset):
|
||||||
# Load the TSX file
|
# Load the TSX file
|
||||||
tree = ElementTree.parse(asset['path'])
|
tree = ElementTree.parse(asset['path'])
|
||||||
@@ -138,10 +140,36 @@ def processTileset(asset):
|
|||||||
os.makedirs(os.path.dirname(outputFile), exist_ok=True)
|
os.makedirs(os.path.dirname(outputFile), exist_ok=True)
|
||||||
with open(outputFile, 'w') as f:
|
with open(outputFile, 'w') as f:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
|
|
||||||
return assetCache(asset['path'], {
|
|
||||||
|
tileset = {
|
||||||
"files": [],
|
"files": [],
|
||||||
"image": tilesetData['image'],
|
"image": tilesetData['image'],
|
||||||
"headerFile": outputFile,
|
"headerFile": os.path.relpath(outputFile, args.headers_dir),
|
||||||
|
"tilesetName": tilesetName,
|
||||||
|
"tilesetNameUpper": tilesetNameUpper,
|
||||||
|
"tilesetIndex": len(tilesets),
|
||||||
|
"tilesetData": tilesetData,
|
||||||
"files": tilesetData['image']['files'],
|
"files": tilesetData['image']['files'],
|
||||||
})
|
}
|
||||||
|
|
||||||
|
tilesets.append(tileset)
|
||||||
|
return assetCache(asset['path'], tileset)
|
||||||
|
|
||||||
|
def processTilesetList():
|
||||||
|
data = f"// Tileset List Generated at {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
|
||||||
|
data += f"#pragma once\n"
|
||||||
|
for tileset in tilesets:
|
||||||
|
data += f"#include \"{tileset['headerFile']}\"\n"
|
||||||
|
data += f"\n"
|
||||||
|
data += f"#define TILESET_LIST_COUNT {len(tilesets)}\n\n"
|
||||||
|
data += f"static const tileset_t* TILESET_LIST[TILESET_LIST_COUNT] = {{\n"
|
||||||
|
for tileset in tilesets:
|
||||||
|
data += f" &TILESET_{tileset['tilesetNameUpper']},\n"
|
||||||
|
data += f"}};\n"
|
||||||
|
|
||||||
|
# Write header.
|
||||||
|
outputFile = os.path.join(args.headers_dir, "display", "tileset", f"tilesetlist.h")
|
||||||
|
os.makedirs(os.path.dirname(outputFile), exist_ok=True)
|
||||||
|
with open(outputFile, 'w') as f:
|
||||||
|
f.write(data)
|
Reference in New Issue
Block a user