From 09b254006a157885e5a710e0a866796d58dc22b7 Mon Sep 17 00:00:00 2001 From: bnnm Date: Thu, 16 Jul 2020 22:51:58 +0200 Subject: [PATCH] Add Konami Viper .adp [ParaParaParadise 2ndMIX] --- src/coding/oki_decoder.c | 20 +++++++++---- src/formats.c | 1 + src/libvgmstream.vcproj | 12 +++++--- src/libvgmstream.vcxproj | 1 + src/libvgmstream.vcxproj.filters | 3 ++ src/meta/adp_konami.c | 51 ++++++++++++++++++++++++++++++++ src/meta/meta.h | 2 ++ src/vgmstream.c | 1 + src/vgmstream.h | 1 + 9 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 src/meta/adp_konami.c diff --git a/src/coding/oki_decoder.c b/src/coding/oki_decoder.c index 2151c476..35280681 100644 --- a/src/coding/oki_decoder.c +++ b/src/coding/oki_decoder.c @@ -17,7 +17,7 @@ static const int stex_indexes[16] = { /* OKI table (also from IMA) */ }; -static void pcfx_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index, int16_t *out_sample, int mode) { +static void pcfx_expand_nibble(VGMSTREAMCHANNEL* stream, off_t byte_offset, int nibble_shift, int32_t* hist1, int32_t* step_index, int16_t* out_sample, int mode) { int code, step, delta; code = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift) & 0xf; @@ -57,7 +57,7 @@ static void pcfx_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int } } -static void oki16_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index, int16_t *out_sample) { +static void oki16_expand_nibble(VGMSTREAMCHANNEL* stream, off_t byte_offset, int nibble_shift, int32_t* hist1, int32_t* step_index, int16_t* out_sample) { int code, step, delta; code = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift) & 0xf; @@ -79,7 +79,15 @@ static void oki16_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, in *out_sample = *hist1; } -static void oki4s_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index, int16_t *out_sample) { +/* Possible variation for adp_konami (Viper hardware): + * delta = ((n&7) + 0.5) * stepsize / 4; clamps 2047,-2048; nigh nibble first + * + * Results are very similar, but can't verify actual decoding, and oki4s is used in + * Jubeat (also Konami) so it makes sense they would have reused it. + * Viper sound chip may be a YMZ280B though. + */ + +static void oki4s_expand_nibble(VGMSTREAMCHANNEL* stream, off_t byte_offset, int nibble_shift, int32_t* hist1, int32_t* step_index, int16_t* out_sample) { int code, step, delta; code = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift) & 0xf; @@ -116,7 +124,7 @@ static void oki4s_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, in * so it's needs GENH/TXTH. Sample rate can only be base_value divided by 1/2/3/4, where * base_value is approximately ~31468.5 (follows hardware clocks), mono or interleaved for stereo. */ -void decode_pcfx(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int mode) { +void decode_pcfx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int mode) { int i, sample_count = 0; int32_t hist1 = stream->adpcm_history1_32; int step_index = stream->adpcm_step_index; @@ -137,7 +145,7 @@ void decode_pcfx(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacin /* OKI variation with 16-bit output (vs standard's 12-bit), found in FrontWing's PS2 games (Sweet Legacy, Hooligan). * Reverse engineered from the ELF with help from the folks at hcs. */ -void decode_oki16(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) { +void decode_oki16(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) { int i, sample_count = 0; int32_t hist1 = stream->adpcm_history1_32; int step_index = stream->adpcm_step_index; @@ -169,7 +177,7 @@ void decode_oki16(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspaci /* OKI variation with 16-bit output (vs standard's 12-bit) and pre-adjusted tables (shifted by 4), found in Jubeat Clan (AC). * Reverse engineered from the DLLs. */ -void decode_oki4s(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) { +void decode_oki4s(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) { int i, sample_count = 0; int32_t hist1 = stream->adpcm_history1_32; int step_index = stream->adpcm_step_index; diff --git a/src/formats.c b/src/formats.c index 053708a5..bd610caa 100644 --- a/src/formats.c +++ b/src/formats.c @@ -1302,6 +1302,7 @@ static const meta_info meta_info_list[] = { {meta_KTSR, "Koei Tecmo KTSR header"}, {meta_KAT, "Sega KAT header"}, {meta_PCM_SUCCESS, "Success PCM header"}, + {meta_ADP_KONAMI, "Konami ADP header"}, }; void get_vgmstream_coding_description(VGMSTREAM *vgmstream, char *out, size_t out_size) { diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index 58c38fa0..39c1470f 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -468,10 +468,14 @@ RelativePath=".\meta\acb.c" > - - + + + + diff --git a/src/libvgmstream.vcxproj b/src/libvgmstream.vcxproj index c6b98294..6f0bfc37 100644 --- a/src/libvgmstream.vcxproj +++ b/src/libvgmstream.vcxproj @@ -271,6 +271,7 @@ + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 6b340829..d7bd2c54 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -337,6 +337,9 @@ meta\Source Files + + meta\Source Files + meta\Source Files diff --git a/src/meta/adp_konami.c b/src/meta/adp_konami.c new file mode 100644 index 00000000..8d458eb5 --- /dev/null +++ b/src/meta/adp_konami.c @@ -0,0 +1,51 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* ADP - from Konami Viper arcade games [ParaParaParadise 2ndMIX (AC)] */ +VGMSTREAM* init_vgmstream_adp_konami(STREAMFILE* sf) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + int loop_flag, channels; + size_t data_size, file_size; + + + /* checks */ + if (!check_extensions(sf, "adp")) + goto fail; + if (read_u32be(0x00,sf) != 0x41445002) /* "ADP\2" */ + goto fail; + + start_offset = 0x10; + channels = 2; /* probably @0x03 */ + loop_flag = 0; + + data_size = read_u32be(0x04,sf); + file_size = get_streamfile_size(sf); + if (!(data_size + start_offset - 0x04 <= file_size && + data_size + start_offset + 0x04 >= file_size)) /* 1 byte padding in some files */ + goto fail; + + if (read_u32be(0x08,sf) != 0 || read_u32be(0x0c,sf) != 0) /* maybe reserved for loop points */ + goto fail; + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_ADP_KONAMI; + vgmstream->sample_rate = 44100; + + vgmstream->num_samples = oki_bytes_to_samples(data_size, channels); + + vgmstream->coding_type = coding_OKI4S; + vgmstream->layout_type = layout_none; + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/meta.h b/src/meta/meta.h index 61b770f4..1d704492 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -909,4 +909,6 @@ VGMSTREAM* init_vgmstream_pcm_success(STREAMFILE* sf); VGMSTREAM* init_vgmstream_ktsc(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_adp_konami(STREAMFILE* sf); + #endif /*_META_H*/ diff --git a/src/vgmstream.c b/src/vgmstream.c index 6c1a3cbb..e77c73f7 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -502,6 +502,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = { init_vgmstream_kat, init_vgmstream_pcm_success, init_vgmstream_ktsc, + init_vgmstream_adp_konami, /* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */ init_vgmstream_txth, /* proper parsers should supersede TXTH, once added */ diff --git a/src/vgmstream.h b/src/vgmstream.h index 7d54e5d4..2b9b93f9 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -734,6 +734,7 @@ typedef enum { meta_KTSR, meta_KAT, meta_PCM_SUCCESS, + meta_ADP_KONAMI, } meta_t; /* standard WAVEFORMATEXTENSIBLE speaker positions */