Add blueprint support (#1271)

I had to cherry-pick some existing changes from another branch, but that
part is tested and working.

For the blueprint stuff, I changed the fields from the strings `"TRUE"`
and `"FALSE"` to native JSON boolean values `true` and `false`. That
made things much easier to parse.

The parsing mechanic is straightforward. I'd like to have @bismurphy
review on the blueprint parser and asset changes specifically.
This commit is contained in:
Luciano Ciccariello 2024-06-06 22:21:03 +01:00 committed by GitHub
parent a118211c10
commit 6057bddea4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 309 additions and 170 deletions

View File

@ -36,7 +36,8 @@ set(SOURCE_FILES_PC
src/pc/str.c
src/pc/sim_pc.c
src/pc/pl_ric.c
src/pc/stage_dummy.c
src/pc/stages/stage_loader.c
src/pc/stages/stage_dummy.c
)
if(WIN32)
@ -112,7 +113,7 @@ set(SOURCE_FILES_DRA
)
set(SOURCE_FILES_STAGE_SEL
src/pc/stage_sel.c
src/pc/stages/stage_sel.c
src/st/sel/banks.c
src/st/sel/CD54.c
src/st/sel/2C048.c

View File

@ -24,8 +24,16 @@ typedef struct {
size_t length;
} FileLoad;
typedef struct {
const char* path;
const char* content;
size_t length;
void* param;
} FileStringified;
bool FileRead(bool (*cb)(FILE* file), const char* path);
bool FileStringify(bool (*cb)(const char* content), const char* path);
bool FileStringify(
bool (*cb)(FileStringified* file), const char* path, void* param);
bool FileUseContent(
bool (*cb)(FileLoad* file, void* param), const char* path, void* param);

View File

@ -59,6 +59,7 @@ GfxBank** g_GfxStageBank[0x40] = {
};
extern u_long* D_800A3BB8[];
FactoryBlueprint g_FactoryBlueprints[0xC0] = {0};
u8 g_BmpCastleMap[0x20000];
#define MAX_SIZE_FOR_COMPRESSED_GFX 8192
@ -113,8 +114,9 @@ void InitSubwpnDefs(void);
void InitGfxEquipIcons(FILE* f);
void InitPalEquipIcons(FILE* f);
void InitVbVh(void);
bool InitSfxData(const char* content);
bool InitXaData(const char* content);
static bool InitSfxData(FileStringified* file);
static bool InitXaData(FileStringified* file);
static bool InitBlueprintData(FileStringified* file);
bool InitGame(void) {
if (!InitPlatform()) {
@ -217,12 +219,21 @@ bool InitGame(void) {
FileRead(InitPalEquipIcons, "assets/dra/g_PalEquipIcon.bin");
InitVbVh();
if (!FileStringify(InitSfxData, "assets/dra/sfx.json")) {
WARNF("failed to init sfx");
if (!FileStringify(InitSfxData, "assets/dra/sfx.json", NULL)) {
ERRORF("failed to init sfx");
return false;
}
if (!FileStringify(InitXaData, "assets/dra/music_xa.json")) {
WARNF("failed to init xa data");
if (!FileStringify(InitXaData, "assets/dra/music_xa.json", NULL)) {
ERRORF("failed to init xa data");
return false;
}
// TODO different between RIC and ARC
if (!FileStringify(
InitBlueprintData, "assets/dra/factory_blueprint.json", NULL)) {
ERRORF("failed to init blueprint data");
return false;
}
return true;
@ -243,7 +254,8 @@ bool FileRead(bool (*cb)(FILE* file), const char* path) {
fclose(f);
return r;
}
bool FileStringify(bool (*cb)(const char* content), const char* path) {
bool FileStringify(
bool (*cb)(FileStringified* file), const char* path, void* param) {
INFOF("open '%s'", path);
FILE* f = fopen(path, "rb");
if (f == NULL) {
@ -272,7 +284,12 @@ bool FileStringify(bool (*cb)(const char* content), const char* path) {
((char*)content)[len] = '\0';
bool r = cb(content);
FileStringified file;
file.path = path;
file.content = content;
file.length = len;
file.param = param;
bool r = cb(&file);
free(content);
fclose(f);
return r;
@ -465,56 +482,116 @@ void InitVbVh() {
\
if (cJSON_IsNumber(field)) { \
to_set = field->valueint; \
} else if (cJSON_IsBool(field)) { \
if (cJSON_IsTrue(field)) { \
to_set = 1; \
} else if (cJSON_IsFalse(field)) { \
to_set = 0; \
} else { \
ERRORF("undefined behaviour for %s", field_str); \
exit(1); \
} \
} else { \
ERRORF("Wrong field %s", field_str); \
exit(1); \
} \
}
bool InitSfxData(const char* content) {
cJSON* json = cJSON_Parse(content);
static bool InitSfxData(FileStringified* file) {
cJSON* json = cJSON_Parse(file->content);
if (!json) {
ERRORF("failed to parse '%s': %s", file->param, cJSON_GetErrorPtr());
return false;
}
cJSON* array = cJSON_GetObjectItemCaseSensitive(json, "asset_data");
if (cJSON_IsArray(array)) {
int len = cJSON_GetArraySize(array);
for (int i = 0; i < len; i++) {
Unkstruct_800BF554* item = &g_SfxData[i];
cJSON* jitem = cJSON_GetArrayItem(array, i);
DO_ITEM("vabid", jitem, item, item->vabid);
DO_ITEM("prog", jitem, item, item->prog);
DO_ITEM("note", jitem, item, item->note);
DO_ITEM("volume", jitem, item, item->volume);
DO_ITEM("unk4", jitem, item, item->unk4);
DO_ITEM("tone", jitem, item, item->tone);
DO_ITEM("unk6", jitem, item, item->unk6);
}
} else {
ERRORF("Error loading sfx.");
exit(1);
if (!cJSON_IsArray(array)) {
cJSON_Delete(json);
ERRORF("data malformed in '%s'", file->param);
return false;
}
int len = cJSON_GetArraySize(array);
for (int i = 0; i < len; i++) {
Unkstruct_800BF554* item = &g_SfxData[i];
cJSON* jitem = cJSON_GetArrayItem(array, i);
DO_ITEM("vabid", jitem, item, item->vabid);
DO_ITEM("prog", jitem, item, item->prog);
DO_ITEM("note", jitem, item, item->note);
DO_ITEM("volume", jitem, item, item->volume);
DO_ITEM("unk4", jitem, item, item->unk4);
DO_ITEM("tone", jitem, item, item->tone);
DO_ITEM("unk6", jitem, item, item->unk6);
}
cJSON_Delete(json);
return true;
}
bool InitXaData(const char* content) {
cJSON* json = cJSON_Parse(content);
static bool InitXaData(FileStringified* file) {
cJSON* json = cJSON_Parse(file->content);
if (!json) {
ERRORF("failed to parse '%s': %s", file->param, cJSON_GetErrorPtr());
return false;
}
cJSON* array = cJSON_GetObjectItemCaseSensitive(json, "asset_data");
if (cJSON_IsArray(array)) {
int len = cJSON_GetArraySize(array);
for (int i = 0; i < len; i++) {
struct XaMusicConfig* item = &g_XaMusicConfigs[i];
cJSON* jitem = cJSON_GetArrayItem(array, i);
DO_ITEM("cd_addr", jitem, item, item->cd_addr);
DO_ITEM("unk228", jitem, item, item->unk228);
DO_ITEM("filter_file", jitem, item, item->filter_file);
DO_ITEM("filter_channel_id", jitem, item, item->filter_channel_id);
DO_ITEM("volume", jitem, item, item->volume);
DO_ITEM("unk22f", jitem, item, item->unk22f);
DO_ITEM("unk230", jitem, item, item->unk230);
// ignore pad for now
}
} else {
ERRORF("Error loading sfx.");
exit(1);
if (!cJSON_IsArray(array)) {
cJSON_Delete(json);
ERRORF("data malformed in '%s'", file->param);
return false;
}
int len = cJSON_GetArraySize(array);
for (int i = 0; i < len; i++) {
struct XaMusicConfig* item = &g_XaMusicConfigs[i];
cJSON* jitem = cJSON_GetArrayItem(array, i);
DO_ITEM("cd_addr", jitem, item, item->cd_addr);
DO_ITEM("unk228", jitem, item, item->unk228);
DO_ITEM("filter_file", jitem, item, item->filter_file);
DO_ITEM("filter_channel_id", jitem, item, item->filter_channel_id);
DO_ITEM("volume", jitem, item, item->volume);
DO_ITEM("unk22f", jitem, item, item->unk22f);
DO_ITEM("unk230", jitem, item, item->unk230);
// ignore pad for now
}
cJSON_Delete(json);
return true;
}
static bool InitBlueprintData(FileStringified* file) {
cJSON* json = cJSON_Parse(file->content);
if (!json) {
ERRORF("failed to parse '%s': %s", file->param, cJSON_GetErrorPtr());
return false;
}
cJSON* array = cJSON_GetObjectItemCaseSensitive(json, "asset_data");
if (!cJSON_IsArray(array)) {
cJSON_Delete(json);
ERRORF("data malformed in '%s'", file->param);
return false;
}
int len = cJSON_GetArraySize(array);
for (int i = 0; i < len; i++) {
u32 bits = 0;
FactoryBlueprint* item = &g_FactoryBlueprints[i];
cJSON* jitem = cJSON_GetArrayItem(array, i);
DO_ITEM("childId", jitem, item, item->childId);
DO_ITEM("unk1", jitem, item, item->unk1);
DO_ITEM("unk3", jitem, item, item->unk3);
DO_ITEM("unk5", jitem, item, item->unk5);
cJSON* jUnk2 = cJSON_GetObjectItem(jitem, "unk2");
DO_ITEM("bottom6", jUnk2, item, item->unk2);
DO_ITEM("bit6", jUnk2, item, bits);
item->unk2 |= !!bits << 6;
DO_ITEM("bit7", jUnk2, item, bits);
item->unk2 |= !!bits << 7;
cJSON* jUnk4 = cJSON_GetObjectItem(jitem, "unk4");
DO_ITEM("bottomHalf", jUnk4, item, item->unk4);
DO_ITEM("topHalf", jUnk4, item, bits);
item->unk4 |= bits << 4;
}
cJSON_Delete(json);
return true;

View File

@ -0,0 +1,97 @@
#include <game.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cJSON/cJSON.h>
#include "stage_loader.h"
#include "sfx.h"
static void Update(void);
static void TestCollisions(void);
static void func_8018A7AC(void);
static void InitRoomEntities(s32 objLayoutId);
static RoomHeader g_Rooms[1];
static s16** g_SpriteBanks[1];
static u16* g_Cluts[1];
static void* g_EntityGfxs[17];
static void UpdateStageEntities(void);
static Overlay g_StageDesc = {
Update,
TestCollisions,
func_8018A7AC,
InitRoomEntities,
g_Rooms,
g_SpriteBanks,
g_Cluts,
NULL,
NULL,
g_EntityGfxs,
UpdateStageEntities,
NULL,
NULL,
NULL,
NULL,
NULL,
};
static RoomHeader g_Rooms[1] = {0};
static s16** g_SpriteBanks[1] = {0};
static u32* D_801801B8[] = {
(u32*)0x00000000, (u32*)0x00000000, (u32*)0x00000000,
(u32*)0x00000000, (u32*)0xFFFFFFFF,
};
static void* g_EntityGfxs[] = {
D_801801B8, D_801801B8, D_801801B8, D_801801B8, D_801801B8, D_801801B8,
D_801801B8, D_801801B8, D_801801B8, D_801801B8, D_801801B8, D_801801B8,
D_801801B8, D_801801B8, D_801801B8, D_801801B8, NULL,
};
static u8 D_80181D08[0x2000];
static u32* D_801800A0[] = {
(u32*)0x00000005, (u32*)0x00002000, (u32*)0x00000010,
(u32*)D_80181D08, (u32*)0xFFFFFFFF,
};
static u16* g_Cluts[] = {
D_801800A0,
};
void InitStageDummy(Overlay* o) {
FILE* f;
f = fopen("assets/st/wrp/D_80181D08.dec", "rb");
if (f) {
fseek(f, 0, SEEK_END);
size_t len = ftell(f);
fseek(f, 0, SEEK_SET);
fread(D_80181D08, len, 1, f);
fclose(f);
}
g_StageDesc.tileLayers = LoadRooms("assets/st/wrp/rooms.layers.json");
memcpy(o, &g_StageDesc, sizeof(Overlay));
}
static void Update(void) { NOT_IMPLEMENTED; }
static void TestCollisions(void) { NOT_IMPLEMENTED; }
static void func_8018A7AC(void) { NOT_IMPLEMENTED; }
void SetGameState(GameState gameState);
void PlaySfx(s32 sfxId);
static void InitRoomEntities(s32 objLayoutId) {
if (g_StageId == STAGE_SEL) {
SetGameState(Game_NowLoading);
g_GameStep = NowLoading_2;
g_StageId = STAGE_WRP;
return;
}
INFOF("Stage ID: %02X", g_StageId);
PlaySfx(MU_REQUIEM_FOR_THE_GODS);
}
static void UpdateStageEntities(void) { NOT_IMPLEMENTED; }

View File

@ -1,70 +1,18 @@
#include <game.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cJSON/cJSON.h>
#include "pc.h"
#include "sfx.h"
#include "stage_loader.h"
static void Update(void);
static void HitDetection(void);
static void func_8018A7AC(void);
static void InitRoomEntities(s32 objLayoutId);
static RoomHeader g_Rooms[1];
static s16** g_SpriteBanks[1];
static u16* g_Cluts[1];
static RoomDef g_TileLayers[0x100];
void* g_EntityGfxs[17];
static void UpdateStageEntities(void);
static Overlay g_StageDummy = {
Update,
HitDetection,
func_8018A7AC,
InitRoomEntities,
g_Rooms,
g_SpriteBanks,
g_Cluts,
NULL,
g_TileLayers,
g_EntityGfxs,
UpdateStageEntities,
NULL,
NULL,
NULL,
NULL,
NULL,
};
static RoomHeader g_Rooms[1] = {0};
static s16** g_SpriteBanks[1] = {0};
static RoomDef g_TileLayers[0x100] = {0};
static u32* D_801801B8[] = {
(u32*)0x00000000, (u32*)0x00000000, (u32*)0x00000000,
(u32*)0x00000000, (u32*)0xFFFFFFFF,
};
void* g_EntityGfxs[] = {
D_801801B8, D_801801B8, D_801801B8, D_801801B8, D_801801B8, D_801801B8,
D_801801B8, D_801801B8, D_801801B8, D_801801B8, D_801801B8, D_801801B8,
D_801801B8, D_801801B8, D_801801B8, D_801801B8, NULL,
};
static u8 D_80181D08[0x2000];
static u32* D_801800A0[] = {
(u32*)0x00000005, (u32*)0x00002000, (u32*)0x00000010,
(u32*)D_80181D08, (u32*)0xFFFFFFFF,
};
static u16* g_Cluts[] = {
D_801800A0,
};
typedef struct {
const char* assetPath;
} RoomLoadDesc;
#define JITEM(x) cJSON_GetObjectItemCaseSensitive(jitem, x)
static TileDefinition* g_TileDefToLoad = NULL;
bool LoadRoomTileDef(const char* content) {
static bool LoadRoomTileDef(FileStringified* file) {
INFOF("load");
cJSON* jitem = cJSON_Parse(content);
RoomLoadDesc* desc = (RoomLoadDesc*)file->param;
cJSON* jitem = cJSON_Parse(file->content);
if (!jitem) {
ERRORF("failed to parse: %s", cJSON_GetErrorPtr());
return false;
@ -72,41 +20,45 @@ bool LoadRoomTileDef(const char* content) {
FILE* f;
char buf[0x100];
snprintf(buf, sizeof(buf), "assets/st/wrp/%s.bin",
snprintf(buf, sizeof(buf), "%s/%s.bin", desc->assetPath,
JITEM("gfxPage")->valuestring);
f = fopen(buf, "rb");
if (f) {
fread(g_TileDefToLoad->gfxPage, 0x1000, 1, f);
fclose(f);
} else {
WARNF("unable to load '%s'", buf);
ERRORF("unable to load '%s'", buf);
return false;
}
snprintf(buf, sizeof(buf), "assets/st/wrp/%s.bin",
snprintf(buf, sizeof(buf), "%s/%s.bin", desc->assetPath,
JITEM("gfxIndex")->valuestring);
f = fopen(buf, "rb");
if (f) {
fread(g_TileDefToLoad->gfxIndex, 0x1000, 1, f);
fclose(f);
} else {
WARNF("unable to load '%s'", buf);
ERRORF("unable to load '%s'", buf);
return false;
}
snprintf(
buf, sizeof(buf), "assets/st/wrp/%s.bin", JITEM("clut")->valuestring);
snprintf(buf, sizeof(buf), "%s/%s.bin", desc->assetPath,
JITEM("clut")->valuestring);
f = fopen(buf, "rb");
if (f) {
fread(g_TileDefToLoad->clut, 0x1000, 1, f);
fclose(f);
} else {
WARNF("unable to load '%s'", buf);
ERRORF("unable to load '%s'", buf);
return false;
}
snprintf(buf, sizeof(buf), "assets/st/wrp/%s.bin",
snprintf(buf, sizeof(buf), "%s/%s.bin", desc->assetPath,
JITEM("collision")->valuestring);
f = fopen(buf, "rb");
if (f) {
fread(g_TileDefToLoad->collision, 0x1000, 1, f);
fclose(f);
} else {
WARNF("unable to load '%s'", buf);
ERRORF("unable to load '%s'", buf);
return false;
}
cJSON_Delete(jitem);
@ -118,7 +70,7 @@ static TileDefinition g_TileDefPool[0x40];
static TileDefinition g_TileDefDataPool[0x40][4][0x1000];
static int g_LayoutIndex = 0;
static u16 g_LayoutPool[0x10000];
void LoadRoomLayerDef(LayerDef* l, cJSON* jitem) {
static bool LoadRoomLayerDef(LayerDef* l, cJSON* jitem, RoomLoadDesc* desc) {
l->rect.left = JITEM("left")->valueint;
l->rect.top = JITEM("top")->valueint;
l->rect.right = JITEM("right")->valueint;
@ -128,7 +80,7 @@ void LoadRoomLayerDef(LayerDef* l, cJSON* jitem) {
char buf[0x100];
FILE* f;
snprintf(buf, sizeof(buf), "assets/st/wrp/%s.tilelayout.bin",
snprintf(buf, sizeof(buf), "%s/%s.tilelayout.bin", desc->assetPath,
JITEM("data")->valuestring);
f = fopen(buf, "rb");
if (f) {
@ -136,20 +88,21 @@ void LoadRoomLayerDef(LayerDef* l, cJSON* jitem) {
size_t len = ftell(f);
fseek(f, 0, SEEK_SET);
if (g_LayoutIndex + len > LEN(g_LayoutPool)) {
ERRORF("out of memory");
exit(1);
ERRORF("%s out of memory", NAMEOF(g_LayoutPool));
return false;
}
l->layout = g_LayoutPool + g_LayoutIndex;
g_LayoutIndex += len;
fread(l->layout, len, 1, f);
fclose(f);
} else {
WARNF("unable to load '%s'", buf);
ERRORF("unable to load '%s'", buf);
return false;
}
if (g_TileDefIndex >= LEN(g_TileDefPool)) {
ERRORF("out of memory");
exit(1);
ERRORF("%s out of memory", NAMEOF(g_TileDefPool));
return false;
}
l->tileDef = g_TileDefPool + g_TileDefIndex;
l->tileDef->gfxPage = g_TileDefDataPool[g_TileDefIndex][0];
@ -157,17 +110,20 @@ void LoadRoomLayerDef(LayerDef* l, cJSON* jitem) {
l->tileDef->clut = g_TileDefDataPool[g_TileDefIndex][2];
l->tileDef->collision = g_TileDefDataPool[g_TileDefIndex][3];
g_TileDefIndex++;
snprintf(buf, sizeof(buf), "assets/st/wrp/%s.tiledef.json",
snprintf(buf, sizeof(buf), "%s/%s.tiledef.json", desc->assetPath,
JITEM("tiledef")->valuestring);
g_TileDefToLoad = l->tileDef;
FileStringify(LoadRoomTileDef, buf);
return FileStringify(LoadRoomTileDef, buf, desc);
}
static int g_LayerDefIndex = 0;
static LayerDef g_LayerDefPool[0x40];
bool LoadTileLayers(const char* content) {
static RoomDef g_TileLayers[0x100];
static bool LoadTileLayers(FileStringified* file) {
INFOF("load");
cJSON* json = cJSON_Parse(content);
RoomLoadDesc* desc = (RoomLoadDesc*)file->param;
cJSON* json = cJSON_Parse(file->content);
if (!json) {
ERRORF("failed to parse: %s", cJSON_GetErrorPtr());
return false;
@ -191,7 +147,9 @@ bool LoadTileLayers(const char* content) {
exit(1);
}
if (jbg) {
LoadRoomLayerDef(item->bg, jbg);
if (!LoadRoomLayerDef(item->bg, jbg, desc)) {
return false;
}
} else {
memset(item->bg, 0, sizeof(LayerDef));
}
@ -199,56 +157,45 @@ bool LoadTileLayers(const char* content) {
cJSON* jfg = JITEM("fg");
item->fg = g_LayerDefPool + g_LayerDefIndex++;
if (g_LayerDefIndex >= LEN(g_LayerDefPool)) {
ERRORF("out of memory");
exit(1);
ERRORF("%s out of memory", NAMEOF(g_LayerDefPool));
return false;
}
if (jfg) {
LoadRoomLayerDef(item->fg, jfg);
if (!LoadRoomLayerDef(item->fg, jfg, desc)) {
return false;
}
} else {
memset(item->fg, 0, sizeof(LayerDef));
}
}
cJSON_Delete(json);
for (int i = len; i < LEN(g_TileLayers); i++) {
g_TileLayers[i].fg = NULL;
g_TileLayers[i].bg = NULL;
}
return true;
}
void InitStageDummy(Overlay* o) {
FILE* f;
f = fopen("assets/st/wrp/D_80181D08.dec", "rb");
if (f) {
fseek(f, 0, SEEK_END);
size_t len = ftell(f);
fseek(f, 0, SEEK_SET);
fread(D_80181D08, len, 1, f);
fclose(f);
}
RoomDef* LoadRooms(const char* filePath) {
char assetPath[0x100];
const char* strTerminator = strrchr(filePath, '/');
size_t len = (size_t)(strTerminator - filePath);
len = MIN(len, LEN(assetPath) - 1);
memcpy(assetPath, filePath, len);
assetPath[len] = '\0';
g_TileDefIndex = 0;
g_LayerDefIndex = 0;
g_LayoutIndex = 0;
FileStringify(LoadTileLayers, "assets/st/wrp/rooms.layers.json");
g_TileDefIndex = 0;
memcpy(o, &g_StageDummy, sizeof(Overlay));
}
static void Update(void) { NOT_IMPLEMENTED; }
static void HitDetection(void) { NOT_IMPLEMENTED; }
static void func_8018A7AC(void) { NOT_IMPLEMENTED; }
void SetGameState(GameState gameState);
void PlaySfx(s32 sfxId);
static void InitRoomEntities(s32 objLayoutId) {
if (g_StageId == STAGE_SEL) {
SetGameState(Game_NowLoading);
g_GameStep = NowLoading_2;
g_StageId = STAGE_WRP;
return;
RoomLoadDesc desc;
desc.assetPath = assetPath;
if (!FileStringify(LoadTileLayers, filePath, &desc)) {
ERRORF("failed to load '%s'", filePath);
return NULL;
}
INFOF("Stage ID: %02X", g_StageId);
PlaySfx(MU_REQUIEM_FOR_THE_GODS);
return g_TileLayers;
}
static void UpdateStageEntities(void) { NOT_IMPLEMENTED; }

View File

@ -0,0 +1,10 @@
#ifndef STAGE_LOADER_H
#define STAGE_LOADER_H
#include "../pc.h"
// load a rooms.layers.json file and all its dependencies to the returned
// pre-allocated RoomDef array. Returns NULL in case of a failure.
RoomDef* LoadRooms(const char* filePath);
#endif

View File

@ -1,6 +1,6 @@
#include <game.h>
#include "../st/sel/sel.h"
#include "pc.h"
#include "../../st/sel/sel.h"
#include "../pc.h"
#include "sfx.h"
// stubs

View File

@ -206,7 +206,6 @@ SVECTOR* D_800B0CB4[][4] = {
&stubbbbbbbb, &stubbbbbbbb, &stubbbbbbbb,
};
unk_800B08CC D_800B08CC[6] = {0};
FactoryBlueprint g_FactoryBlueprints[400] = {0}; // TODO load from JSON file
s32 D_800B07C8 = 0x12345678;
Unkstruct_80138094 D_80138094[100]; // unknown size
s32 D_8013808C;

View File

@ -99,9 +99,9 @@ def serialize_asset(content: str, asset_config: str) -> bytearray:
field_bitsize = field_def[field_name]
# If the field is a bit flag
if field_bitsize == 1:
if subvalue == "TRUE":
if subvalue == True:
packed_bitstring += "1"
elif subvalue == "FALSE":
elif subvalue == False:
packed_bitstring += "0"
else:
print("Problem serializing asset")
@ -206,7 +206,7 @@ class PSXSegAssets(N64Segment):
# If the field is a bit flag
if field_bitcount == 1:
bit_state = (
"TRUE" if value_bits[bit_index] == "1" else "FALSE"
True if value_bits[bit_index] == "1" else False
)
parsed_fields[field_name] = bit_state
bit_index += 1