mirror of
https://github.com/Xeeynamo/sotn-decomp.git
synced 2024-11-23 13:09:44 +00:00
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:
parent
a118211c10
commit
6057bddea4
@ -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
|
||||
|
10
src/pc/pc.h
10
src/pc/pc.h
@ -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);
|
||||
|
||||
|
167
src/pc/sotn.c
167
src/pc/sotn.c
@ -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;
|
||||
|
97
src/pc/stages/stage_dummy.c
Normal file
97
src/pc/stages/stage_dummy.c
Normal 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; }
|
@ -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; }
|
10
src/pc/stages/stage_loader.h
Normal file
10
src/pc/stages/stage_loader.h
Normal 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
|
@ -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
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user