diff --git a/src/formats.c b/src/formats.c index 39f00422..7c99d037 100644 --- a/src/formats.c +++ b/src/formats.c @@ -25,7 +25,7 @@ static const char* extension_list[] = { "208", "2dx9", "3do", - "3ds", //txth/reserved [F1 2011 (3DS)] + "3ds", "4", //for Game.com audio "8", //txth/reserved [Gungage (PS1)] "800", @@ -765,17 +765,17 @@ const char** vgmstream_get_common_formats(size_t* size) { typedef struct { coding_t type; - const char *description; + const char* description; } coding_info; typedef struct { layout_t type; - const char *description; + const char* description; } layout_info; typedef struct { meta_t type; - const char *description; + const char* description; } meta_info; @@ -1459,11 +1459,10 @@ static const meta_info meta_info_list[] = { {meta_HD_BD, "Sony HD+BD header"}, {meta_PPHD, "Sony PPHD header"}, {meta_XABP, "cavia XABp header"}, + {meta_I3DS, "Codemasters i3DS header"}, }; void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) { - int i, list_length; - const char *description; #ifdef VGM_USE_FFMPEG if (vgmstream->coding_type == coding_FFmpeg) { @@ -1481,7 +1480,7 @@ void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t ou } #endif - description = "CANNOT DECODE"; + const char* description = "CANNOT DECODE"; switch (vgmstream->coding_type) { #ifdef VGM_USE_FFMPEG @@ -1491,23 +1490,22 @@ void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t ou description = "FFmpeg"; break; #endif - default: - list_length = sizeof(coding_info_list) / sizeof(coding_info); - for (i = 0; i < list_length; i++) { + default: { + int list_length = sizeof(coding_info_list) / sizeof(coding_info); + for (int i = 0; i < list_length; i++) { if (coding_info_list[i].type == vgmstream->coding_type) description = coding_info_list[i].description; } break; + } } strncpy(out, description, out_size); } static const char* get_layout_name(layout_t layout_type) { - int i, list_length; - - list_length = sizeof(layout_info_list) / sizeof(layout_info); - for (i = 0; i < list_length; i++) { + int list_length = sizeof(layout_info_list) / sizeof(layout_info); + for (int i = 0; i < list_length; i++) { if (layout_info_list[i].type == layout_type) return layout_info_list[i].description; } @@ -1515,13 +1513,12 @@ static const char* get_layout_name(layout_t layout_type) { return NULL; } -static int has_sublayouts(VGMSTREAM** vgmstreams, int count) { - int i; - for (i = 0; i < count; i++) { +static bool has_sublayouts(VGMSTREAM** vgmstreams, int count) { + for (int i = 0; i < count; i++) { 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: @@ -1539,7 +1536,7 @@ static int has_sublayouts(VGMSTREAM** vgmstreams, int count) { * ("mixed" is added externally) */ 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; if (vgmstream->layout_type == layout_layered) { @@ -1565,7 +1562,7 @@ static int get_layout_mixed_description(VGMSTREAM* vgmstream, char* dst, int dst 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); } @@ -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) { const char* description; - int mixed = 0; + bool mixed = false; description = get_layout_name(vgmstream->layout_type); 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) { - int i, list_length; - const char* description; + const char* description = "THEY SHOULD HAVE SENT A POET"; - description = "THEY SHOULD HAVE SENT A POET"; - - list_length = sizeof(meta_info_list) / sizeof(meta_info); - for (i=0; i < list_length; i++) { + int list_length = sizeof(meta_info_list) / sizeof(meta_info); + for (int i = 0; i < list_length; i++) { if (meta_info_list[i].type == vgmstream->meta_type) description = meta_info_list[i].description; } diff --git a/src/libvgmstream.vcxproj b/src/libvgmstream.vcxproj index 32cd2276..a411b9ca 100644 --- a/src/libvgmstream.vcxproj +++ b/src/libvgmstream.vcxproj @@ -517,6 +517,7 @@ + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index ba57fe07..470db619 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -1381,6 +1381,9 @@ meta\Source Files + + meta\Source Files + meta\Source Files diff --git a/src/meta/i3ds.c b/src/meta/i3ds.c new file mode 100644 index 00000000..1e74df9f --- /dev/null +++ b/src/meta/i3ds.c @@ -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); +} diff --git a/src/meta/meta.h b/src/meta/meta.h index 90c0b363..556eff51 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -1021,4 +1021,6 @@ VGMSTREAM* init_vgmstream_pphd(STREAMFILE* sf); VGMSTREAM* init_vgmstream_xabp(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_i3ds(STREAMFILE* sf); + #endif diff --git a/src/vgmstream_init.c b/src/vgmstream_init.c index b6a54e37..6ac3c928 100644 --- a/src/vgmstream_init.c +++ b/src/vgmstream_init.c @@ -514,6 +514,7 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_hd_bd, init_vgmstream_pphd, init_vgmstream_xabp, + init_vgmstream_i3ds, /* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */ init_vgmstream_agsc, diff --git a/src/vgmstream_types.h b/src/vgmstream_types.h index 71c70822..11363bda 100644 --- a/src/vgmstream_types.h +++ b/src/vgmstream_types.h @@ -715,6 +715,7 @@ typedef enum { meta_HD_BD, meta_PPHD, meta_XABP, + meta_I3DS, } meta_t;