Skip to content

Commit 700309a

Browse files
committed
Small refactor, use file names for Digimon refs
1 parent 7d92be0 commit 700309a

6 files changed

Lines changed: 350 additions & 312 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ set(CMAKE_WARN_DEPRECATED TRUE CACHE BOOL "" FORCE)
6767

6868
# --- Target ---
6969
set(SOURCE_FILES ${SOURCE_FILES} "src/main.cpp" "src/TIM.cpp" "src/Animation.cpp" "src/CLUTMap.cpp"
70-
"src/Model.cpp" "src/GLTF.cpp" "src/MAP.cpp")
70+
"src/Model.cpp" "src/GLTF.cpp" "src/MAP.cpp" "src/GameData.cpp")
7171

7272
add_executable(DW1ModelConverter ${SOURCE_FILES})
7373

src/GameData.cpp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
2+
#include "GameData.hpp"
3+
4+
#include <array>
5+
#include <fstream>
6+
7+
template<typename T> std::vector<T> readFileAsVector(std::filesystem::path path)
8+
{
9+
std::vector<T> data;
10+
std::ifstream slus(path, std::ios::binary);
11+
auto size = std::filesystem::file_size(path);
12+
data.resize(size / sizeof(T));
13+
slus.read(reinterpret_cast<char*>(data.data()), size);
14+
return data;
15+
}
16+
17+
VersionData getVersion(std::filesystem::path parentPath)
18+
{
19+
VersionData version;
20+
21+
if (std::filesystem::exists(parentPath / SLPS_10_DATA.psexePath))
22+
{
23+
auto size = std::filesystem::file_size(parentPath / SLPS_10_DATA.psexePath);
24+
25+
if (size == 0xAF000)
26+
return SLPS_11_DATA;
27+
else if (size == 0xAE000)
28+
return SLPS_10_DATA;
29+
}
30+
31+
for (VersionData v : VERSION_DATA)
32+
if (std::filesystem::exists(parentPath / v.psexePath)) return v;
33+
34+
return SLUS_DATA;
35+
}
36+
37+
std::vector<DigimonEntry> loadDigimonEntries(std::filesystem::path parentPath)
38+
{
39+
using DigimonFileName = char[8];
40+
41+
std::vector<DigimonEntry> digimonEntries;
42+
VersionData version = getVersion(parentPath);
43+
std::vector<uint8_t> data = readFileAsVector<uint8_t>(parentPath / version.psexePath);
44+
std::vector<MMDTexture> textureData = readFileAsVector<MMDTexture>(parentPath / version.alltimPath);
45+
DigimonFileName* names = reinterpret_cast<DigimonFileName*>(data.data() + version.nameOffset);
46+
DigimonPara* para = reinterpret_cast<DigimonPara*>(data.data() + version.paraOffset);
47+
DigimonParaPAL* paraPAL = reinterpret_cast<DigimonParaPAL*>(data.data() + version.paraOffset);
48+
uint32_t* skelOffset = reinterpret_cast<uint32_t*>(data.data() + version.skelOffset);
49+
50+
for (int i = 0; i < 180; i++)
51+
{
52+
NodeEntry* skeletonOffset = reinterpret_cast<NodeEntry*>(data.data() + skelOffset[i] - 0x80090000);
53+
int32_t boneCount = version.isPAL ? paraPAL[i].boneCount : para[i].boneCount;
54+
55+
DigimonEntry entry;
56+
entry.filename = std::string(names[i]);
57+
58+
for (int32_t j = 0; j < boneCount; j++)
59+
entry.skeleton.push_back(skeletonOffset[j]);
60+
61+
std::copy(textureData[i].buffer, textureData[i].buffer + sizeof(MMDTexture), std::back_inserter(entry.texture));
62+
digimonEntries.push_back(entry);
63+
}
64+
65+
return digimonEntries;
66+
}
67+
68+
std::array<MapEntry, 255> getMapEntries(std::filesystem::path parentPath)
69+
{
70+
using MapName = char[28];
71+
72+
std::array<MapEntry, 255> entries;
73+
VersionData version = getVersion(parentPath);
74+
std::vector<uint8_t> data = readFileAsVector<uint8_t>(version.psexePath);
75+
MapEntryData* mapData = reinterpret_cast<MapEntryData*>(data.data() + version.mapEntryOffset);
76+
ToiletData* toiletData = reinterpret_cast<ToiletData*>(data.data() + version.toiletDataOffset);
77+
DoorData* doorData = reinterpret_cast<DoorData*>(data.data() + version.doorDataOffset);
78+
uint32_t* mapNamePtr = reinterpret_cast<uint32_t*>(data.data() + version.mapNamePtrOffset);
79+
80+
for (auto i = 0; i < 255; i++)
81+
{
82+
auto entryData = mapData[i];
83+
84+
entries[i].data = entryData;
85+
if (entryData.toiletId != 0) entries[i].toilet = toiletData[entryData.toiletId - 1];
86+
if (entryData.doorsId != 0) entries[i].doors = doorData[entryData.doorsId - 1];
87+
88+
std::string_view view =
89+
*reinterpret_cast<MapName*>(data.data() + PSEXE_OFFSET(mapNamePtr[entryData.loadingNameId]));
90+
view.remove_suffix(view.size() - view.find_last_not_of(' ') - 1);
91+
view.remove_prefix(view.find_first_not_of(' '));
92+
entries[i].name = view;
93+
}
94+
95+
return entries;
96+
}

src/GameData.hpp

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
#pragma once
2+
#include "Model.hpp"
3+
4+
#include <cstdint>
5+
#include <optional>
6+
#include <string_view>
7+
#include <vector>
8+
#include <filesystem>
9+
10+
// structs
11+
struct DigimonPara
12+
{
13+
char name[20];
14+
int32_t boneCount;
15+
int16_t radius;
16+
int16_t height;
17+
uint8_t type;
18+
uint8_t level;
19+
uint8_t special[3];
20+
uint8_t dropItem;
21+
uint8_t dropChance;
22+
int8_t moves[16];
23+
uint8_t padding;
24+
};
25+
26+
struct DigimonParaPAL
27+
{
28+
int32_t boneCount;
29+
int16_t radius;
30+
int16_t height;
31+
uint8_t type;
32+
uint8_t level;
33+
uint8_t special[3];
34+
uint8_t dropItem;
35+
uint8_t dropChance;
36+
int8_t moves[16];
37+
uint8_t padding;
38+
};
39+
40+
static_assert(sizeof(DigimonPara) == 52);
41+
static_assert(sizeof(DigimonParaPAL) == 32);
42+
43+
struct VersionData
44+
{
45+
std::string_view psexePath;
46+
std::string_view alltimPath;
47+
uint32_t nameOffset;
48+
uint32_t paraOffset;
49+
uint32_t skelOffset;
50+
uint32_t mapEntryOffset;
51+
uint32_t mapNamePtrOffset;
52+
uint32_t toiletDataOffset;
53+
uint32_t doorDataOffset;
54+
bool isPAL;
55+
};
56+
57+
struct MMDTexture
58+
{
59+
uint8_t buffer[0x4800];
60+
};
61+
62+
struct DigimonEntry
63+
{
64+
std::string filename;
65+
std::vector<NodeEntry> skeleton;
66+
std::vector<uint8_t> texture;
67+
};
68+
69+
70+
71+
struct ToiletData
72+
{
73+
int16_t x1;
74+
int16_t y1;
75+
int16_t x2;
76+
int16_t y2;
77+
};
78+
79+
struct MapEntryFlags
80+
{
81+
uint8_t soundId : 5;
82+
uint8_t : 1; // padding
83+
bool hasNoTimeCycle : 1;
84+
bool hasDigimon : 1;
85+
};
86+
87+
static_assert(sizeof(MapEntryFlags) == 1);
88+
89+
struct MapEntryData
90+
{
91+
char name[10];
92+
uint8_t numMapImages;
93+
uint8_t numMapObjects;
94+
MapEntryFlags flags;
95+
uint8_t doorsId;
96+
uint8_t toiletId;
97+
uint8_t loadingNameId;
98+
};
99+
100+
struct DoorData
101+
{
102+
uint8_t modelId[6];
103+
int16_t posX[6];
104+
int16_t posY[6];
105+
int16_t posZ[6];
106+
int16_t rotation[6];
107+
};
108+
109+
struct MapEntry
110+
{
111+
MapEntryData data;
112+
std::string name;
113+
std::optional<ToiletData> toilet;
114+
std::optional<DoorData> doors;
115+
};
116+
117+
static_assert(sizeof(MapEntryData) == 0x10);
118+
119+
// TODO map entry data
120+
// data
121+
/*
122+
* name para skel mapEntry mapName toilets doors
123+
* SLUS_010.32 0x133B44 0x12CEB4 0x11ce60 0x1292d4 0x1291bc 0x122e10 0x122e60
124+
* SLPS_017.97 0x13d844 0x13b344 0x123780 (1.1)
125+
* SLPS_017.97 0x13CE24 0x13A924 0x122E68 (1.0)
126+
* SLPM_804.02 0x13e874 0x13c32c 0x124728
127+
* SLES_029.14 0x13AC0C 0x138B5C 0x122DD4
128+
* SLES_034.34 0x13AE00 0x138D50 0x122DE4
129+
* SLES_034.35 0x13ADD8 0x138D28 0x122D6C
130+
* SLES_034.36 0x13B7E4 0x139734 0x122DA0
131+
* SLES_034.37 0x13B314 0x139264 0x122DA0
132+
*/
133+
constexpr uint32_t PSEXE_OFFSET(uint32_t offset) { return (offset - 0x90000) & 0x7FFFFFFF; }
134+
135+
constexpr VersionData SLUS_DATA = {
136+
.psexePath = "SLUS_010.32",
137+
.alltimPath = "CHDAT/ALLTIM.TIM",
138+
.nameOffset = PSEXE_OFFSET(0x133b44),
139+
.paraOffset = PSEXE_OFFSET(0x12ceb4),
140+
.skelOffset = PSEXE_OFFSET(0x11ce60),
141+
.mapEntryOffset = PSEXE_OFFSET(0x1292d4),
142+
.mapNamePtrOffset = PSEXE_OFFSET(0x1291bc),
143+
.toiletDataOffset = PSEXE_OFFSET(0x122e10),
144+
.doorDataOffset = PSEXE_OFFSET(0x122e60),
145+
.isPAL = false,
146+
};
147+
148+
constexpr VersionData SLPS_11_DATA = {
149+
.psexePath = "SLPS_017.97",
150+
.alltimPath = "CHDAT/ALLTIM.TIM",
151+
.nameOffset = PSEXE_OFFSET(0x13d844),
152+
.paraOffset = PSEXE_OFFSET(0x13b344),
153+
.skelOffset = PSEXE_OFFSET(0x123780),
154+
.isPAL = false,
155+
};
156+
157+
constexpr VersionData SLPS_10_DATA = {
158+
.psexePath = "SLPS_017.97",
159+
.alltimPath = "CHDAT/ALLTIM.TIM",
160+
.nameOffset = PSEXE_OFFSET(0x13ce24),
161+
.paraOffset = PSEXE_OFFSET(0x13a924),
162+
.skelOffset = PSEXE_OFFSET(0x122e68),
163+
.isPAL = false,
164+
};
165+
166+
constexpr VersionData SLPM_DATA = {
167+
.psexePath = "SLPM_804.02",
168+
.alltimPath = "CHDAT/ALLTIM.TIM",
169+
.nameOffset = PSEXE_OFFSET(0x13e874),
170+
.paraOffset = PSEXE_OFFSET(0x13c32c),
171+
.skelOffset = PSEXE_OFFSET(0x124728),
172+
.isPAL = false,
173+
};
174+
175+
constexpr VersionData SLES02914_DATA = {
176+
.psexePath = "SLES_029.14",
177+
.alltimPath = "CHDAT/ALLTIM.TIM",
178+
.nameOffset = PSEXE_OFFSET(0x13ac0c),
179+
.paraOffset = PSEXE_OFFSET(0x138b5c),
180+
.skelOffset = PSEXE_OFFSET(0x122dd4),
181+
.isPAL = true,
182+
};
183+
184+
constexpr VersionData SLES03434_DATA = {
185+
.psexePath = "SLES_034.34",
186+
.alltimPath = "CHDAT/ALLTIM.TIM",
187+
.nameOffset = PSEXE_OFFSET(0x13ae00),
188+
.paraOffset = PSEXE_OFFSET(0x138d50),
189+
.skelOffset = PSEXE_OFFSET(0x122de4),
190+
.isPAL = true,
191+
};
192+
193+
constexpr VersionData SLES03435_DATA = {
194+
.psexePath = "SLES_034.35",
195+
.alltimPath = "CHDAT/ALLTIM.TIM",
196+
.nameOffset = PSEXE_OFFSET(0x13add8),
197+
.paraOffset = PSEXE_OFFSET(0x138d28),
198+
.skelOffset = PSEXE_OFFSET(0x122d6c),
199+
.isPAL = true,
200+
};
201+
202+
constexpr VersionData SLES03436_DATA = {
203+
.psexePath = "SLES_034.36",
204+
.alltimPath = "CHDAT/ALLTIM.TIM",
205+
.nameOffset = PSEXE_OFFSET(0x13b7e4),
206+
.paraOffset = PSEXE_OFFSET(0x139734),
207+
.skelOffset = PSEXE_OFFSET(0x122da0),
208+
.isPAL = true,
209+
};
210+
211+
constexpr VersionData SLES03437_DATA = {
212+
.psexePath = "SLES_034.37",
213+
.alltimPath = "CHDAT/ALLTIM.TIM",
214+
.nameOffset = PSEXE_OFFSET(0x13b314),
215+
.paraOffset = PSEXE_OFFSET(0x139264),
216+
.skelOffset = PSEXE_OFFSET(0x122da0),
217+
.isPAL = true,
218+
};
219+
220+
constexpr VersionData VERSION_DATA[] = { SLUS_DATA, SLPS_11_DATA, SLPS_10_DATA, SLPM_DATA, SLES02914_DATA,
221+
SLES03434_DATA, SLES03435_DATA, SLES03436_DATA, SLES03437_DATA };
222+
// functions
223+
224+
VersionData getVersion(std::filesystem::path parentPath);
225+
std::vector<DigimonEntry> loadDigimonEntries(std::filesystem::path parentPath);
226+
std::array<MapEntry, 255> getMapEntries(std::filesystem::path parentPath);

src/MAP.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,9 @@ void to_json(nlohmann::ordered_json& json, const MapDigimon& elements)
197197
json["ai"]["tracking_range"] = elements.trackingRange;
198198
json["ai"]["ai_mod"] = elements.chargeMode;
199199
json["location"]["position"] = elements.pos;
200-
json["location"]["rotation"]["X"] = elements.rotX;
201-
json["location"]["rotation"]["Y"] = elements.rotY;
202-
json["location"]["rotation"]["Z"] = elements.rotZ;
200+
json["location"]["rotation"]["x"] = elements.rotX;
201+
json["location"]["rotation"]["y"] = elements.rotY;
202+
json["location"]["rotation"]["z"] = elements.rotZ;
203203
json["stats"]["hp"] = elements.hp;
204204
json["stats"]["mp"] = elements.mp;
205205
json["stats"]["hp_max"] = elements.maxHP;
@@ -421,6 +421,14 @@ bool MAPExporter::save(std::filesystem::path outputDir)
421421
else
422422
val = "";
423423
}
424+
for (auto& itr : json["elements"]["digimon"])
425+
{
426+
auto& val = itr["type"];
427+
if(val < digimonEntries.size())
428+
val = digimonEntries[val].filename;
429+
else
430+
val = "";
431+
}
424432
std::ofstream(outputDir / "map.json") << json.dump(2);
425433

426434
// write background images

0 commit comments

Comments
 (0)