summaryrefslogtreecommitdiff
path: root/include/nw4r/snd/snd_SoundArchiveFile.h
blob: 07b52a47d2974250197e6252219316d1b0274aca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
#ifndef NW4R_SND_SOUND_ARCHIVE_FILE_H
#define NW4R_SND_SOUND_ARCHIVE_FILE_H

/*******************************************************************************
 * headers
 */

#include "common.h"

#include "nw4r/snd/snd_SoundArchive.h"
#include "nw4r/snd/snd_Util.h"

#include "nw4r/ut/ut_binaryFileFormat.h"
#include "nw4r/ut/ut_algorithm.h"

/*******************************************************************************
 * types
 */

namespace nw4r { namespace snd { namespace detail
{
	struct SoundArchiveFile
	{
		/* Header */

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x240a6
		struct Header
		{
			ut::BinaryFileHeader	fileHeader;			// size 0x10, offset 0x00
			u32						symbolDataOffset;	// size 0x04, offset 0x10
			u32						symbolDataSize;		// size 0x04, offset 0x14
			u32						infoOffset;			// size 0x04, offset 0x18
			u32						infoSize;			// size 0x04, offset 0x1c
			u32						fileImageOffset;	// size 0x04, offset 0x20
			u32						fileImageSize;		// size 0x04, offset 0x24
		}; // size 0x28

		static const int HEADER_AREA_SIZE = ROUND_UP(sizeof(Header), 32) + 40;

		/* SymbolBlock */

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x24881
		struct StringTreeNode
		{
			u16	flags;		// size 0x02, offset 0x00
			u16	bit;		// size 0x02, offset 0x02
			u32		leftIdx;	// size 0x04, offset 0x04
			u32		rightIdx;	// size 0x04, offset 0x08
			u32		strIdx;		// size 0x04, offset 0x0c
			u32		id;			// size 0x04, offset 0x10
		}; // size 0x14

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x24a2e
		struct StringTree
		{
			u32							rootIdx;	// size 0x04, offset 0x00
			Util::Table<StringTreeNode>	nodeTable;	// size 0x18, offset 0x04
		}; // size 0x1c

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x24830
		struct StringTable
		{
			Util::Table<u32>	offsetTable;	// size 0x08, offset 0x00
		}; // size 0x08

		struct StringChunk
		{
			u32	tableOffset;		// size 0x04, offset 0x00
			u32	soundTreeOffset;	// size 0x04, offset 0x04
			u32	playerTreeOffset;	// size 0x04, offset 0x08
			u32	groupTreeOffset;	// size 0x04, offset 0x0c
			u32	bankTreeOffset;		// size 0x04, offset 0x10
		}; // size 0x14

		union StringBlock
		{
			StringTable	stringTable;	// size 0x08
			StringChunk	stringChunk;	// size 0x14
		}; // size 0x14

		static u32 const SIGNATURE_SYMB_BLOCK =
			NW4R_FOUR_BYTE('S', 'Y', 'M', 'B');

		struct SymbolBlock
		{
			ut::BinaryBlockHeader	blockHeader;	// size 0x08, offset 0x00
			StringBlock				stringBlock;	// size 0x14, offset 0x08
		}; // size 0x20

		/* InfoBlock */

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2da8f9
		enum SoundType
		{
			SOUND_TYPE_INVALID,

			SOUND_TYPE_SEQ,
			SOUND_TYPE_STRM,
			SOUND_TYPE_WAVE,
		};

		struct Sound3DParam {
			u32 flags;
			u8 decayCurve;
			u8 decayRatio;
			u8 field_0x06;
		};

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x25183
		struct SeqSoundInfo
		{
			u32		dataOffset;			// size 0x04, offset 0x00
			u32		bankId;				// size 0x04, offset 0x04
			u32		allocTrack;			// size 0x04, offset 0x08
			u8		channelPriority;	// size 0x01, offset 0x0c
			u8		releasePriorityFix;	// size 0x01, offset 0x0d
			u8	padding[2];
			u32	reserved;
		}; // size 0x14

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x25089
		struct StrmSoundInfo
		{
			u32		startPosition;		// size 0x04, offset 0x00
			u16		allocChannelCount;	// size 0x02, offset 0x04
			u16	allocTrackFlag;		// size 0x02, offset 0x06
			u32	reserved;
		}; // size 0x0c

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x24f62
		struct WaveSoundInfo
		{
			s32		subNo;				// size 0x04, offset 0x00
			u32		allocTrack;			// size 0x04, offset 0x04
			u8		channelPriority;	// size 0x01, offset 0x08
			u8		releasePriorityFix;	// size 0x01, offset 0x09
			u8	padding[2];
			u32	reserved;
		}; // size 0x10

		typedef Util::DataRef<void, SeqSoundInfo, StrmSoundInfo, WaveSoundInfo>
			SoundInfoRef;

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2546c
		struct SoundCommonInfo
		{
			u32							stringId;		// size 0x04, offset 0x00
			u32							fileId;			// size 0x04, offset 0x04
			u32							playerId;		// size 0x04, offset 0x08
			Util::DataRef<Sound3DParam>	param3dRef;		// size 0x08, offset 0x0c
			u8							volume;			// size 0x01, offset 0x14
			u8							playerPriority;	// size 0x01, offset 0x15
			u8							soundType;		// size 0x01, offset 0x16
			u8							remoteFilter;	// size 0x01, offset 0x17
			SoundInfoRef				soundInfoRef;	// size 0x08, offset 0x18
			u32					userParam[2];	// size 0x08, offset 0x20
			u8							panMode;		// size 0x01, offset 0x28
			u8							panCurve;		// size 0x01, offset 0x29
			u8							actorPlayerId;	// size 0x01, offset 0x2a
			u8						reserved;
		}; // size 0x2c

		typedef Util::Table<Util::DataRef<SoundCommonInfo> >
			SoundCommonInfoTable;

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2db9b5
		struct SoundArchivePlayerInfo
		{
			u16		seqSoundCount;		// size 0x02, offset 0x00
			u16		seqTrackCount;		// size 0x02, offset 0x02
			u16		strmSoundCount;		// size 0x02, offset 0x04
			u16		strmTrackCount;		// size 0x02, offset 0x06
			u16		strmChannelCount;	// size 0x02, offset 0x08
			u16		waveSoundCount;		// size 0x02, offset 0x0a
			u16		waveTrackCount;		// size 0x02, offset 0x0c
			u16	padding;
			u32	reserved;
		}; // size 0x14

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x24eab
		struct BankInfo
		{
			u32		stringId;	// size 0x04, offset 0x00
			u32		fileId;		// size 0x04, offset 0x04
			u32	reserved;
		}; // size 0x0c

		typedef Util::Table<Util::DataRef<BankInfo> > BankInfoTable;

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x24d8f
		struct PlayerInfo
		{
			u32		stringId;			// size 0x04, offset 0x00
			u8		playableSoundCount;	// size 0x01, offset 0x04
			u8	padding;
			u16	padding2;
			u32		heapSize;			// size 0x04, offset 0x08
			u32	reserved;
		}; // size 0x10

		typedef Util::Table<Util::DataRef<PlayerInfo> > PlayerInfoTable;

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2db6e3
		struct GroupItemInfo
		{
			u32		fileId;			// size 0x04, offset 0x00
			u32		offset;			// size 0x04, offset 0x04
			u32		size;			// size 0x04, offset 0x08
			u32		waveDataOffset;	// size 0x04, offset 0x0c
			u32		waveDataSize;	// size 0x04, offset 0x10
			u32	reserved;
		}; // size 0x18

		typedef Util::Table<Util::DataRef<GroupItemInfo> > GroupItemInfoTable;

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x24c1b
		struct GroupInfo
		{
			u32									stringId;		// size 0x04, offset 0x00
			s32									entryNum;		// size 0x04, offset 0x04
			Util::DataRef<char>					extFilePathRef;	// size 0x08, offset 0x08
			u32									offset;			// size 0x04, offset 0x10
			u32									size;			// size 0x04, offset 0x14
			u32									waveDataOffset;	// size 0x04, offset 0x18
			u32									waveDataSize;	// size 0x04, offset 0x1c
			Util::DataRef<GroupItemInfoTable>	itemTableRef;	// size 0x08, offset 0x20
		}; // size 0x28

		typedef Util::Table<Util::DataRef<GroupInfo> > GroupInfoTable;

		typedef Util::Table<Util::DataRef<SoundArchive::FilePos> > FilePosTable;

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2dc40b
		struct FileInfo
		{
			u32							fileSize;			// size 0x04, offset 0x00
			u32							waveDataFileSize;	// size 0x04, offset 0x04
			s32							entryNum;			// size 0x04, offset 0x08
			Util::DataRef<char>			extFilePathRef;		// size 0x08, offset 0x0c
			Util::DataRef<FilePosTable>	filePosTableRef;	// size 0x08, offset 0x14
		}; // size 0x1c

		typedef Util::Table<Util::DataRef<FileInfo> > FileInfoTable;

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x24665
		struct Info
		{
			Util::DataRef<SoundCommonInfoTable>		soundTableRef;				// size 0x08, offset 0x00
			Util::DataRef<BankInfoTable>			bankTableRef;				// size 0x08, offset 0x08
			Util::DataRef<PlayerInfoTable>			playerTableRef;				// size 0x08, offset 0x10
			Util::DataRef<FileInfoTable>			fileTableRef;				// size 0x08, offset 0x18
			Util::DataRef<GroupInfoTable>			groupTableRef;				// size 0x08, offset 0x20
			Util::DataRef<SoundArchivePlayerInfo>	soundArchivePlayerInfoRef;	// size 0x08, offset 0x28
		}; // size 0x30

		static u32 const SIGNATURE_INFO_BLOCK =
			NW4R_FOUR_BYTE('I', 'N', 'F', 'O');

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2da76d
		struct InfoBlock
		{
			ut::BinaryBlockHeader	blockHeader;	// size 0x08, offset 0x00
			Info					info;			// size 0x30, offset 0x08
		}; // size 0x38

		/* SoundArchiveFile */

		static u32 const SIGNATURE_FILE =
			NW4R_FOUR_BYTE('R', 'S', 'A', 'R');
		static int const FILE_VERSION = NW4R_FILE_VERSION(1, 4);
	}; // "namespace" SoundArchiveFile
}}} // namespace nw4r::snd::detail

/*******************************************************************************
 * classes and functions
 */

namespace nw4r { namespace snd { namespace detail
{
	// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x261f8
	class SoundArchiveFileReader
	{
	// methods
	public:
		// cdtors
		SoundArchiveFileReader();
		~SoundArchiveFileReader() {} // not default?

		// methods
		void Init(void const *soundArchiveData);

		u16 GetVersion() const { return mHeader.fileHeader.version; }
		u32 GetLabelStringChunkOffset() const
		{
			return mHeader.symbolDataOffset;
		}
		u32 GetLabelStringChunkSize() const { return mHeader.symbolDataSize; }
		u32 GetInfoChunkOffset() const { return mHeader.infoOffset; }
		u32 GetInfoChunkSize() const { return mHeader.infoSize; }

		char const *GetString(u32 id) const;
		SoundArchive::SoundType GetSoundType(u32 soundId) const;
		u32 GetSoundStringId(u32 id) const;
		u32 GetBankCount() const;
		u32 GetPlayerCount() const;
		u32 GetGroupCount() const;
		u32 GetFileCount() const;
		void const *GetPtrConst(void const *base, u32 offset) const
		{
			if (offset == 0)
				return nullptr;

			return ut::AddOffsetToPtr(base, offset);
		}

		void SetStringChunk(void const *stringChunk, u32 stringChunkSize);
		void SetInfoChunk(void const *infoChunk, u32 infoChunkSize);

		bool ReadSeqSoundInfo(u32 soundId,
		                      SoundArchive::SeqSoundInfo *info) const;
		bool ReadStrmSoundInfo(u32 soundId,
		                       SoundArchive::StrmSoundInfo *info) const;
		bool ReadWaveSoundInfo(u32 soundId,
		                       SoundArchive::WaveSoundInfo *info) const;
		bool ReadSoundArchivePlayerInfo(
			SoundArchive::SoundArchivePlayerInfo *info) const;
		bool ReadSoundInfo(u32 soundId, SoundArchive::SoundInfo *info) const;

		bool ReadBankInfo(u32 bankId, SoundArchive::BankInfo *info) const;

		bool ReadPlayerInfo(u32 playerId, SoundArchive::PlayerInfo *info) const;
		bool ReadSound3DParam(u32 soundId, nw4r::snd::SoundArchive::Sound3DParam* info) const;

		bool ReadGroupItemInfo(u32 groupId, u32 index,
		                       SoundArchive::GroupItemInfo *info) const;
		bool ReadGroupInfo(u32 groupId, SoundArchive::GroupInfo *info) const;

		bool ReadFileInfo(u32 fileId, SoundArchive::FileInfo *info) const;
		bool ReadFilePos(u32 fileId, u32 index,
		                 SoundArchive::FilePos *filePos) const;

		u32 ConvertLabelStringToId(SoundArchiveFile::StringTree const *tree,
		                           char const *str) const;
		const char* GetSoundLabelString(u32 id) const;
		u32 GetSoundUserParam(u32 id) const;

		u32 ConvertLabelStringToSoundId(const char* pLabel) const {
			return ConvertLabelStringToId(mStringTreeSound, pLabel);
		}
		u32 ConvertLabelStringToPlayerId(const char* pLabel) const {
			return ConvertLabelStringToId(mStringTreePlayer, pLabel);
		}
		u32 ConvertLabelStringToGroupId(const char* pLabel) const {
			return ConvertLabelStringToId(mStringTreeGroup, pLabel);
		}
		u32 ConvertLabelStringToBankId(const char* pLabel) const {
			return ConvertLabelStringToId(mStringTreeBank, pLabel);
		}

	private:
		static bool IsValidFileHeader(void const *soundArchiveData);

		SoundArchiveFile::SeqSoundInfo const *impl_GetSeqSoundInfo(
			u32 soundId) const;
		SoundArchiveFile::StrmSoundInfo const *impl_GetStrmSoundInfo(
			u32 soundId) const;
		SoundArchiveFile::WaveSoundInfo const *impl_GetWaveSoundInfo(
			u32 soundId) const;
		SoundArchiveFile::SoundCommonInfo const *impl_GetSoundInfo(
			u32 soundId) const;

		bool impl_GetSoundInfoOffset(
			u32 soundId, SoundArchiveFile::SoundInfoRef *soundInfoRef) const;

		SoundArchiveFile::BankInfo const *impl_GetBankInfo(u32 bankId) const;

		SoundArchiveFile::PlayerInfo const *impl_GetPlayerInfo(
			u32 playerId) const;

		SoundArchiveFile::GroupInfo const *impl_GetGroupInfo(u32 groupId) const;

	// static members
	public:
		static u16 const SUPPORTED_FILE_VERSION = NW4R_FILE_VERSION(1, 4);

	// members
	private:
		SoundArchiveFile::Header		mHeader;					// size 0x28, offset 0x00
		SoundArchiveFile::Info			const *mInfo;				// size 0x04, offset 0x28
		void							const *mStringBase;			// size 0x04, offset 0x2c
		SoundArchiveFile::StringTable	const *mStringTable;		// size 0x04, offset 0x30
		SoundArchiveFile::StringTree	const *mStringTreeSound;	// size 0x04, offset 0x34
		SoundArchiveFile::StringTree	const *mStringTreePlayer;	// size 0x04, offset 0x38
		SoundArchiveFile::StringTree	const *mStringTreeGroup;	// size 0x04, offset 0x3c
		SoundArchiveFile::StringTree	const *mStringTreeBank;		// size 0x04, offset 0x40
	}; // size 0x44
}}} // namespace nw4r::snd::detail

#endif // NW4R_SND_SOUND_ARCHIVE_FILE_H