Add Codemasters .3ds [F1 2011 (3DS)]

This commit is contained in:
bnnm 2025-01-19 00:26:22 +01:00
parent 7d967a2b49
commit 45ed922338
7 changed files with 79 additions and 28 deletions

View File

@ -25,7 +25,7 @@ static const char* extension_list[] = {
"208", "208",
"2dx9", "2dx9",
"3do", "3do",
"3ds", //txth/reserved [F1 2011 (3DS)] "3ds",
"4", //for Game.com audio "4", //for Game.com audio
"8", //txth/reserved [Gungage (PS1)] "8", //txth/reserved [Gungage (PS1)]
"800", "800",
@ -765,17 +765,17 @@ const char** vgmstream_get_common_formats(size_t* size) {
typedef struct { typedef struct {
coding_t type; coding_t type;
const char *description; const char* description;
} coding_info; } coding_info;
typedef struct { typedef struct {
layout_t type; layout_t type;
const char *description; const char* description;
} layout_info; } layout_info;
typedef struct { typedef struct {
meta_t type; meta_t type;
const char *description; const char* description;
} meta_info; } meta_info;
@ -1459,11 +1459,10 @@ static const meta_info meta_info_list[] = {
{meta_HD_BD, "Sony HD+BD header"}, {meta_HD_BD, "Sony HD+BD header"},
{meta_PPHD, "Sony PPHD header"}, {meta_PPHD, "Sony PPHD header"},
{meta_XABP, "cavia XABp header"}, {meta_XABP, "cavia XABp header"},
{meta_I3DS, "Codemasters i3DS header"},
}; };
void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) { void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) {
int i, list_length;
const char *description;
#ifdef VGM_USE_FFMPEG #ifdef VGM_USE_FFMPEG
if (vgmstream->coding_type == coding_FFmpeg) { if (vgmstream->coding_type == coding_FFmpeg) {
@ -1481,7 +1480,7 @@ void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t ou
} }
#endif #endif
description = "CANNOT DECODE"; const char* description = "CANNOT DECODE";
switch (vgmstream->coding_type) { switch (vgmstream->coding_type) {
#ifdef VGM_USE_FFMPEG #ifdef VGM_USE_FFMPEG
@ -1491,23 +1490,22 @@ void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t ou
description = "FFmpeg"; description = "FFmpeg";
break; break;
#endif #endif
default: default: {
list_length = sizeof(coding_info_list) / sizeof(coding_info); int list_length = sizeof(coding_info_list) / sizeof(coding_info);
for (i = 0; i < list_length; i++) { for (int i = 0; i < list_length; i++) {
if (coding_info_list[i].type == vgmstream->coding_type) if (coding_info_list[i].type == vgmstream->coding_type)
description = coding_info_list[i].description; description = coding_info_list[i].description;
} }
break; break;
}
} }
strncpy(out, description, out_size); strncpy(out, description, out_size);
} }
static const char* get_layout_name(layout_t layout_type) { static const char* get_layout_name(layout_t layout_type) {
int i, list_length; int list_length = sizeof(layout_info_list) / sizeof(layout_info);
for (int i = 0; i < list_length; i++) {
list_length = sizeof(layout_info_list) / sizeof(layout_info);
for (i = 0; i < list_length; i++) {
if (layout_info_list[i].type == layout_type) if (layout_info_list[i].type == layout_type)
return layout_info_list[i].description; return layout_info_list[i].description;
} }
@ -1515,13 +1513,12 @@ static const char* get_layout_name(layout_t layout_type) {
return NULL; return NULL;
} }
static int has_sublayouts(VGMSTREAM** vgmstreams, int count) { static bool has_sublayouts(VGMSTREAM** vgmstreams, int count) {
int i; for (int i = 0; i < count; i++) {
for (i = 0; i < count; i++) {
if (vgmstreams[i]->layout_type == layout_segmented || vgmstreams[i]->layout_type == layout_layered) if (vgmstreams[i]->layout_type == layout_segmented || vgmstreams[i]->layout_type == layout_layered)
return 1; return true;
} }
return 0; return false;
} }
/* Makes a mixed description, considering a segments/layers can contain segments/layers infinitely, like: /* Makes a mixed description, considering a segments/layers can contain segments/layers infinitely, like:
@ -1539,7 +1536,7 @@ static int has_sublayouts(VGMSTREAM** vgmstreams, int count) {
* ("mixed" is added externally) * ("mixed" is added externally)
*/ */
static int get_layout_mixed_description(VGMSTREAM* vgmstream, char* dst, int dst_size) { static int get_layout_mixed_description(VGMSTREAM* vgmstream, char* dst, int dst_size) {
int i, count, done = 0; int count, done = 0;
VGMSTREAM** vgmstreams = NULL; VGMSTREAM** vgmstreams = NULL;
if (vgmstream->layout_type == layout_layered) { if (vgmstream->layout_type == layout_layered) {
@ -1565,7 +1562,7 @@ static int get_layout_mixed_description(VGMSTREAM* vgmstream, char* dst, int dst
dst[done++] = '['; dst[done++] = '[';
} }
for (i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
done += get_layout_mixed_description(vgmstreams[i], dst + done, dst_size - done); done += get_layout_mixed_description(vgmstreams[i], dst + done, dst_size - done);
} }
@ -1578,7 +1575,7 @@ static int get_layout_mixed_description(VGMSTREAM* vgmstream, char* dst, int dst
void get_vgmstream_layout_description(VGMSTREAM* vgmstream, char* out, size_t out_size) { void get_vgmstream_layout_description(VGMSTREAM* vgmstream, char* out, size_t out_size) {
const char* description; const char* description;
int mixed = 0; bool mixed = false;
description = get_layout_name(vgmstream->layout_type); description = get_layout_name(vgmstream->layout_type);
if (!description) description = "INCONCEIVABLE"; if (!description) description = "INCONCEIVABLE";
@ -1609,13 +1606,10 @@ void get_vgmstream_layout_description(VGMSTREAM* vgmstream, char* out, size_t ou
} }
void get_vgmstream_meta_description(VGMSTREAM* vgmstream, char* out, size_t out_size) { void get_vgmstream_meta_description(VGMSTREAM* vgmstream, char* out, size_t out_size) {
int i, list_length; const char* description = "THEY SHOULD HAVE SENT A POET";
const char* description;
description = "THEY SHOULD HAVE SENT A POET"; int list_length = sizeof(meta_info_list) / sizeof(meta_info);
for (int i = 0; i < list_length; i++) {
list_length = sizeof(meta_info_list) / sizeof(meta_info);
for (i=0; i < list_length; i++) {
if (meta_info_list[i].type == vgmstream->meta_type) if (meta_info_list[i].type == vgmstream->meta_type)
description = meta_info_list[i].description; description = meta_info_list[i].description;
} }

View File

@ -517,6 +517,7 @@
<ClCompile Include="meta\hgc1.c" /> <ClCompile Include="meta\hgc1.c" />
<ClCompile Include="meta\his.c" /> <ClCompile Include="meta\his.c" />
<ClCompile Include="meta\hxd.c" /> <ClCompile Include="meta\hxd.c" />
<ClCompile Include="meta\i3ds.c" />
<ClCompile Include="meta\idsp_ie.c" /> <ClCompile Include="meta\idsp_ie.c" />
<ClCompile Include="meta\idtech.c" /> <ClCompile Include="meta\idtech.c" />
<ClCompile Include="meta\ifs.c" /> <ClCompile Include="meta\ifs.c" />

View File

@ -1381,6 +1381,9 @@
<ClCompile Include="meta\hxd.c"> <ClCompile Include="meta\hxd.c">
<Filter>meta\Source Files</Filter> <Filter>meta\Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="meta\i3ds.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\idsp_ie.c"> <ClCompile Include="meta\idsp_ie.c">
<Filter>meta\Source Files</Filter> <Filter>meta\Source Files</Filter>
</ClCompile> </ClCompile>

49
src/meta/i3ds.c Normal file
View File

@ -0,0 +1,49 @@
#include "meta.h"
#include "../util/meta_utils.h"
#include "../coding/coding.h"
/* i3DS - interleaved dsp [F1 2011 (3DS)] */
VGMSTREAM* init_vgmstream_i3ds(STREAMFILE* sf) {
/* checks */
if (!is_id32be(0x00,sf, "i3DS"))
return NULL;
if (!check_extensions(sf, "3ds"))
return NULL;
meta_header_t h = {
.meta = meta_I3DS
};
// 04: data start? (0x10)
h.data_size = read_u32le(0x08,sf);
h.interleave = read_u32le(0x0c,sf);
// 2 mono CWAV headers pasted together then "DATA" then stream, no loop info but many tracks repeat
if (!is_id32be(0x10,sf, "CWAV"))
return NULL;
h.sample_rate = read_s32le(0x10 + 0x4c, sf);
h.num_samples = read_s32le(0x10 + 0x54, sf);
h.coefs_offset = 0x10 + 0x7c;
h.coefs_spacing = 0xC0;
//h.hists_offset = 0x00; //?
//h.hists_spacing = h.coefs_spacing;
// interleaved data starts from 0x10 after DATA (chunk *2), so unsure if header's offset are actually used
uint32_t chdt_offset = 0x08 + 0x08; //read_u32le(0x10 + 0x6c, sf) + 0x08;
h.channels = h.interleave ? 2 : 1;
h.stream_offset = 0x10 + 0xc0 * h.channels + chdt_offset;
h.stream_size = h.data_size - h.stream_offset;
if (h.interleave > 0)
h.interleave_last = (h.stream_size % (h.interleave * h.channels)) / h.channels;
h.coding = coding_NGC_DSP;
h.layout = layout_interleave;
h.open_stream = true;
h.sf = sf;
return alloc_metastream(&h);
}

View File

@ -1021,4 +1021,6 @@ VGMSTREAM* init_vgmstream_pphd(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_xabp(STREAMFILE* sf); VGMSTREAM* init_vgmstream_xabp(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_i3ds(STREAMFILE* sf);
#endif #endif

View File

@ -514,6 +514,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_hd_bd, init_vgmstream_hd_bd,
init_vgmstream_pphd, init_vgmstream_pphd,
init_vgmstream_xabp, init_vgmstream_xabp,
init_vgmstream_i3ds,
/* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */ /* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */
init_vgmstream_agsc, init_vgmstream_agsc,

View File

@ -715,6 +715,7 @@ typedef enum {
meta_HD_BD, meta_HD_BD,
meta_PPHD, meta_PPHD,
meta_XABP, meta_XABP,
meta_I3DS,
} meta_t; } meta_t;