From 83426eb04291e369d7de4d35b29aa27577f8086c Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 21 Feb 2021 22:07:08 +0100 Subject: [PATCH 1/4] Adjust tri-Ace codec issues --- src/coding/tac_decoder.c | 26 ++++++++++++++------------ src/coding/tac_decoder_lib.c | 6 +++--- src/coding/tac_decoder_lib.h | 16 ++++++++-------- src/meta/tac.c | 6 +++--- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/coding/tac_decoder.c b/src/coding/tac_decoder.c index b46f4c18..2cce8df6 100644 --- a/src/coding/tac_decoder.c +++ b/src/coding/tac_decoder.c @@ -12,7 +12,7 @@ struct tac_codec_data { int encoder_delay; uint8_t buf[TAC_BLOCK_SIZE]; - int read_block; + int feed_block; off_t offset; int16_t* samples; @@ -38,7 +38,7 @@ tac_codec_data* init_tac(STREAMFILE* sf) { data->handle = tac_init(data->buf, bytes); if (!data->handle) goto fail; - data->read_block = 0; /* ok to use current block */ + data->feed_block = 0; /* ok to use current block */ data->offset = bytes; data->channels = TAC_CHANNELS; data->frame_samples = TAC_FRAME_SAMPLES; @@ -66,15 +66,17 @@ static int decode_frame(tac_codec_data* data) { err = tac_decode_frame(data->handle, data->buf); if (err == TAC_PROCESS_NEXT_BLOCK) { - data->read_block = 1; + data->feed_block = 1; return 1; } if (err == TAC_PROCESS_DONE) { + VGM_LOG("TAC: process done (EOF) %i\n", err); goto fail; /* shouldn't reach this */ } if (err != TAC_PROCESS_OK) { + VGM_LOG("TAC: process error %i\n", err); goto fail; } @@ -90,10 +92,10 @@ fail: static int read_frame(tac_codec_data* data, STREAMFILE* sf) { /* new block must be read only when signaled by lib */ - if (data->read_block) { + if (data->feed_block) { int bytes = read_streamfile(data->buf, data->offset, sizeof(data->buf), sf); data->offset += bytes; - data->read_block = 0; + data->feed_block = 0; if (bytes <= 0) goto fail; /* can read less that buf near EOF */ } @@ -139,7 +141,8 @@ void reset_tac(tac_codec_data* data) { tac_reset(data->handle); - data->read_block = 1; + data->offset = 0; + data->feed_block = 1; data->sbuf.filled = 0; data->samples_discard = data->encoder_delay; @@ -149,20 +152,19 @@ void reset_tac(tac_codec_data* data) { void seek_tac(tac_codec_data* data, int32_t num_sample) { int32_t loop_sample; const tac_header_t* hdr; - + if (!data) return; hdr = tac_get_header(data->handle); - loop_sample = hdr->loop_frame * TAC_FRAME_SAMPLES + hdr->loop_discard; + loop_sample = (hdr->loop_frame - 1) * TAC_FRAME_SAMPLES + hdr->loop_discard; if (loop_sample == num_sample) { - /* simulates original looping (that wouldn't clean codec internals) */ - tac_set_loop(data->handle); + tac_set_loop(data->handle); /* direct looping */ data->samples_discard = hdr->loop_discard; data->offset = hdr->loop_offset; - data->read_block = 1; + data->feed_block = 1; data->sbuf.filled = 0; } else { @@ -170,7 +172,7 @@ void seek_tac(tac_codec_data* data, int32_t num_sample) { data->samples_discard = num_sample; data->offset = 0; - data->read_block = 1; + data->feed_block = 1; data->sbuf.filled = 0; } } diff --git a/src/coding/tac_decoder_lib.c b/src/coding/tac_decoder_lib.c index 4627f645..7252e54b 100644 --- a/src/coding/tac_decoder_lib.c +++ b/src/coding/tac_decoder_lib.c @@ -16,8 +16,8 @@ * container?) and handler lib may be "Csd". Looks inspired by MPEG (much simplified) with bits * from other codecs (per-file codebook and 1024 samples). * - * Original decoder is implemented in the PS2's VU1, a coprocessor specialized in vector/SIMD and - * parallel instructions. As VU1 works with many 128 bit registers (typically x4 floats) algorithm + * Original decoder is mainly implemented in the PS2's VU1, a coprocessor specialized in vector/SIMD + * and parallel instructions. As VU1 works with many 128 bit registers (typically x4 floats) algorithm * was tailored to do multiple ops at once. This code tries to simplify it into standard C to a point, * but keeps this vector style in main decoding to ease porting (since tables are made with SIMD in * mind it would need some transposing around) and for PS2 float simulation. @@ -1053,7 +1053,7 @@ static int init_header(tac_header_t* header, const uint8_t* buf) { /* header size ia block-aligned (but actual size can be smaller, ex. VP 00000715) */ if (header->file_size % TAC_BLOCK_SIZE != 0) return TAC_PROCESS_HEADER_ERROR; - /* assumed but should be ok */ + /* loop_discard over max makes game crash, while frame_discard seems to ignore it */ if (header->loop_discard > TAC_FRAME_SAMPLES || header->frame_discard > TAC_FRAME_SAMPLES) return TAC_PROCESS_HEADER_ERROR; /* looping makes sense */ diff --git a/src/coding/tac_decoder_lib.h b/src/coding/tac_decoder_lib.h index 5094b42f..82a610a1 100644 --- a/src/coding/tac_decoder_lib.h +++ b/src/coding/tac_decoder_lib.h @@ -24,15 +24,15 @@ typedef struct tac_handle_t tac_handle_t; typedef struct { /* 0x20 header config */ uint32_t huffman_offset; /* setup */ - uint32_t unknown; /* ignored? may be CDVD stuff (divided/multiplied during PS2 process), not file size related */ - uint16_t loop_frame; /* aligned to block stard */ - uint16_t loop_discard; /* assumed */ - uint16_t frame_count; /* number of valid frames ("block end" frame not included) */ - uint16_t frame_discard; /* assumed */ - uint32_t loop_offset; /* file size if not looped */ - uint32_t file_size; /* actual file size can be a bit smaller if last block is truncated */ + uint32_t unknown; /* ignored? (may be CDVD stuff, divided/multiplied during PS2 process, not size related) */ + uint16_t loop_frame; /* aligned to block start */ + uint16_t loop_discard; /* discarded start samples in loop frame (lower = outputs more) */ + uint16_t frame_count; /* number of valid frames ("block end" frames not included) */ + uint16_t frame_discard; /* discarded end samples in final frame (lower = outputs less), even for non-looped files */ + uint32_t loop_offset; /* points to a block; file size if not looped */ + uint32_t file_size; /* block aligned; actual file size can be a bit smaller if last block is truncated */ uint32_t joint_stereo; /* usually 0 and rarely 1 */ - uint32_t empty; /* null? */ + uint32_t empty; /* always null */ } tac_header_t; diff --git a/src/meta/tac.c b/src/meta/tac.c index 16515a15..fe92ce19 100644 --- a/src/meta/tac.c +++ b/src/meta/tac.c @@ -35,7 +35,7 @@ VGMSTREAM* init_vgmstream_tac(STREAMFILE* sf) { goto fail; channel_count = 2; /* always stereo */ - loop_flag = (loop_offset != stream_size); + loop_flag = (loop_offset != stream_size); /* actual check may be loop_frame > 0? */ start_offset = 0; @@ -45,8 +45,8 @@ VGMSTREAM* init_vgmstream_tac(STREAMFILE* sf) { vgmstream->meta_type = meta_TAC; vgmstream->sample_rate = 48000; - vgmstream->num_samples = frame_count * 1024 - frame_discard; - vgmstream->loop_start_sample = loop_frame * 1024 + loop_discard; + vgmstream->num_samples = frame_count * 1024 - (1024 - frame_discard); + vgmstream->loop_start_sample = (loop_frame - 1) * 1024 + loop_discard; vgmstream->loop_end_sample = vgmstream->num_samples; { From a0e44bba3a2fe8b8c268548e088941317b566cc3 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 21 Feb 2021 22:08:44 +0100 Subject: [PATCH 2/4] Add scramble key for .awb w/ ADX [Assault Lily Last Bullet (Android)] --- src/meta/adx.c | 90 +++++++++++++++++++++++++++------------------ src/meta/adx_keys.h | 2 +- src/meta/awb.c | 2 +- src/meta/meta.h | 3 +- 4 files changed, 58 insertions(+), 39 deletions(-) diff --git a/src/meta/adx.c b/src/meta/adx.c index 35d721b5..111e10d0 100644 --- a/src/meta/adx.c +++ b/src/meta/adx.c @@ -11,11 +11,15 @@ #define ADX_KEY_MAX_TEST_FRAMES 32768 #define ADX_KEY_TEST_BUFFER_SIZE 0x8000 -static int find_adx_key(STREAMFILE *sf, uint8_t type, uint16_t *xor_start, uint16_t *xor_mult, uint16_t *xor_add); +static int find_adx_key(STREAMFILE *sf, uint8_t type, uint16_t *xor_start, uint16_t *xor_mult, uint16_t *xor_add, uint16_t subkey); + +VGMSTREAM* init_vgmstream_adx(STREAMFILE* sf) { + return init_vgmstream_adx_subkey(sf, 0); +} /* ADX - CRI Middleware format */ -VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) { + VGMSTREAM* vgmstream = NULL; off_t start_offset, hist_offset = 0; int loop_flag = 0, channel_count; int32_t loop_start_sample = 0, loop_end_sample = 0; @@ -32,18 +36,18 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) { /* checks*/ /* .adx: standard * .adp: Headhunter (DC) */ - if (!check_extensions(streamFile,"adx,adp")) + if (!check_extensions(sf,"adx,adp")) goto fail; - if ((uint16_t)read_16bitBE(0x00,streamFile) != 0x8000) + if (read_u16be(0x00,sf) != 0x8000) goto fail; - start_offset = (uint16_t)read_16bitBE(0x02,streamFile) + 0x04; - if ((uint16_t)read_16bitBE(start_offset - 0x06,streamFile) != 0x2863 || /* "(c" */ - (uint32_t)read_32bitBE(start_offset - 0x04,streamFile) != 0x29435249) /* ")CRI" */ + start_offset = read_u16be(0x02,sf) + 0x04; + if (read_u16be(start_offset - 0x06,sf) != 0x2863 || /* "(c" */ + read_u32be(start_offset - 0x04,sf) != 0x29435249) /* ")CRI" */ goto fail; - encoding_type = read_8bit(0x04, streamFile); + encoding_type = read_u8(0x04, sf); switch (encoding_type) { case 0x02: coding_type = coding_CRI_ADX_fixed; @@ -60,29 +64,29 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) { /* ADX encoders can't set this value, but is honored by ADXPlay if changed and multiple of 0x12, * though output is unusual and may not be fully supported (works in mono so not an interleave) */ - frame_size = read_8bit(0x05, streamFile); + frame_size = read_8bit(0x05, sf); - if (read_8bit(0x06,streamFile) != 4) /* bits per sample */ + if (read_u8(0x06,sf) != 4) /* bits per sample */ goto fail; /* older ADX (adxencd) up to 2ch, newer ADX (criatomencd) up to 8 */ - channel_count = read_8bit(0x07,streamFile); + channel_count = read_u8(0x07,sf); /* 0x08: sample rate */ /* 0x0c: samples */ /* 0x10: high-pass frequency */ - version = read_16bitBE(0x12,streamFile); + version = read_u16be(0x12,sf); /* encryption */ if (version == 0x0408) { - if (find_adx_key(streamFile, 8, &xor_start, &xor_mult, &xor_add)) { + if (find_adx_key(sf, 8, &xor_start, &xor_mult, &xor_add, 0)) { coding_type = coding_CRI_ADX_enc_8; version = 0x0400; } VGM_ASSERT(version != 0x0400, "ADX: keystring not found\n"); } else if (version == 0x0409) { - if (find_adx_key(streamFile, 9, &xor_start, &xor_mult, &xor_add)) { + if (find_adx_key(sf, 9, &xor_start, &xor_mult, &xor_add, subkey)) { coding_type = coding_CRI_ADX_enc_9; version = 0x0400; } @@ -103,11 +107,11 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) { /* 0x00 (2): initial loop padding (the encoder adds a few blank samples so loop start is block-aligned; max 31) * ex. loop_start=12: enc_start=32, padding=20 (32-20=12); loop_start=35: enc_start=64, padding=29 (64-29=35) * 0x02 (2): loop sample(?) flag (always 1) */ - loop_flag = read_32bitBE(loops_offset+0x04,streamFile) != 0; /* loop offset(?) flag (always 1) */ - loop_start_sample = read_32bitBE(loops_offset+0x08,streamFile); - //loop_start_offset = read_32bitBE(loops_offset+0x0c,streamFile); - loop_end_sample = read_32bitBE(loops_offset+0x10,streamFile); - //loop_end_offset = read_32bitBE(loops_offset+0x14,streamFile); + loop_flag = read_32bitBE(loops_offset+0x04,sf) != 0; /* loop offset(?) flag (always 1) */ + loop_start_sample = read_32bitBE(loops_offset+0x08,sf); + //loop_start_offset = read_32bitBE(loops_offset+0x0c,sf); + loop_end_sample = read_32bitBE(loops_offset+0x10,sf); + //loop_end_offset = read_32bitBE(loops_offset+0x14,sf); } } else if (version == 0x0400) { /* common */ @@ -120,8 +124,8 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) { hist_size = (channel_count > 1 ? 0x04 * channel_count : 0x04 + 0x04); /* min is 8, even in 1ch files */ ainf_offset = base_size + hist_size + 0x04; /* not seen with >2ch though */ - if ((uint32_t)read_32bitBE(ainf_offset+0x00,streamFile) == 0x41494E46) /* "AINF" */ - ainf_size = read_32bitBE(ainf_offset+0x04,streamFile); + if (read_u32be(ainf_offset+0x00,sf) == 0x41494E46) /* "AINF" */ + ainf_size = read_32bitBE(ainf_offset+0x04,sf); if (start_offset - ainf_size - 0x06 >= hist_offset + hist_size + loops_size) { /* enough space for loop info? */ off_t loops_offset = base_size + hist_size; @@ -129,11 +133,11 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) { /* 0x00 (2): initial loop padding (the encoder adds a few blank samples so loop start is block-aligned; max 31) * ex. loop_start=12: enc_start=32, padding=20 (32-20=12); loop_start=35: enc_start=64, padding=29 (64-29=35) * 0x02 (2): loop sample(?) flag (always 1) */ - loop_flag = read_32bitBE(loops_offset+0x04,streamFile) != 0; /* loop offset(?) flag (always 1) */ - loop_start_sample = read_32bitBE(loops_offset+0x08,streamFile); - //loop_start_offset = read_32bitBE(loops_offset+0x0c,streamFile); - loop_end_sample = read_32bitBE(loops_offset+0x10,streamFile); - //loop_end_offset = read_32bitBE(loops_offset+0x14,streamFile); + loop_flag = read_32bitBE(loops_offset+0x04,sf) != 0; /* loop offset(?) flag (always 1) */ + loop_start_sample = read_32bitBE(loops_offset+0x08,sf); + //loop_start_offset = read_32bitBE(loops_offset+0x0c,sf); + loop_end_sample = read_32bitBE(loops_offset+0x10,sf); + //loop_end_offset = read_32bitBE(loops_offset+0x14,sf); } /* AINF header info (may be inserted by CRI's tools but is rarely used) @@ -165,8 +169,8 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) { vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - vgmstream->sample_rate = read_32bitBE(0x08,streamFile); - vgmstream->num_samples = read_32bitBE(0x0c,streamFile); + vgmstream->sample_rate = read_32bitBE(0x08,sf); + vgmstream->num_samples = read_32bitBE(0x0c,sf); vgmstream->loop_start_sample = loop_start_sample; vgmstream->loop_end_sample = loop_end_sample; @@ -195,7 +199,7 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) { double x,y,z,a,b,c; int i; /* high-pass cutoff frequency, always 500 that I've seen */ - uint16_t cutoff = (uint16_t)read_16bitBE(0x10,streamFile); + uint16_t cutoff = read_u16be(0x10,sf); x = cutoff; y = vgmstream->sample_rate; @@ -222,8 +226,8 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) { /* 2 hist shorts per ch, corresponding to the very first original sample repeated (verified with CRI's encoders). * Not vital as their effect is small, after a few samples they don't matter, and most songs start in silence. */ if (hist_offset) { - vgmstream->ch[i].adpcm_history1_32 = read_16bitBE(hist_offset + i*4 + 0x00,streamFile); - vgmstream->ch[i].adpcm_history2_32 = read_16bitBE(hist_offset + i*4 + 0x02,streamFile); + vgmstream->ch[i].adpcm_history1_32 = read_16bitBE(hist_offset + i*4 + 0x00,sf); + vgmstream->ch[i].adpcm_history2_32 = read_16bitBE(hist_offset + i*4 + 0x02,sf); } if (coding_type == coding_CRI_ADX_enc_8 || coding_type == coding_CRI_ADX_enc_9) { @@ -240,7 +244,7 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) { } - if ( !vgmstream_open_stream(vgmstream,streamFile,start_offset) ) + if ( !vgmstream_open_stream(vgmstream, sf, start_offset) ) goto fail; return vgmstream; @@ -252,7 +256,7 @@ fail: /* ADX key detection works by reading XORed ADPCM scales in frames, and un-XORing with keys in * a list. If resulting values are within the expected range for N scales we accept that key. */ -static int find_adx_key(STREAMFILE *sf, uint8_t type, uint16_t *xor_start, uint16_t *xor_mult, uint16_t *xor_add) { +static int find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint16_t *xor_mult, uint16_t *xor_add, uint16_t subkey) { const int frame_size = 0x12; uint16_t *scales = NULL; uint16_t *prescales = NULL; @@ -295,7 +299,17 @@ static int find_adx_key(STREAMFILE *sf, uint8_t type, uint16_t *xor_start, uint1 return 1; } else if (type == 9 && key_size == 0x08) { - uint64_t keycode = (uint64_t)get_64bitBE(keybuf); + uint64_t keycode = get_u64be(keybuf); + if (subkey) { + keycode = keycode * ( ((uint64_t)subkey << 16u) | ((uint16_t)~subkey + 2u) ); + } + derive_adx_key9(keycode, xor_start, xor_mult, xor_add); + return 1; + } + else if (type == 9 && key_size == 0x08+0x02) { + uint64_t file_key = get_u64be(keybuf+0x00); + uint16_t file_sub = get_u16be(keybuf+0x08); + uint64_t keycode = file_key * ( ((uint64_t)file_sub << 16u) | ((uint16_t)~file_sub + 2u) ); derive_adx_key9(keycode, xor_start, xor_mult, xor_add); return 1; } @@ -414,7 +428,11 @@ static int find_adx_key(STREAMFILE *sf, uint8_t type, uint16_t *xor_start, uint1 derive_adx_key8(keys[key_id].key8, &key_xor, &key_mul, &key_add); } else if (type == 9 && keys[key_id].key9) { - derive_adx_key9(keys[key_id].key9, &key_xor, &key_mul, &key_add); + uint64_t keycode = keys[key_id].key9; + if (subkey) { + keycode = keycode * ( ((uint64_t)subkey << 16u) | ((uint16_t)~subkey + 2u) ); + } + derive_adx_key9(keycode, &key_xor, &key_mul, &key_add); } else { VGM_LOG("ADX: incorrectly defined key id=%i\n", key_id); diff --git a/src/meta/adx_keys.h b/src/meta/adx_keys.h index 911e322c..af33f5c5 100644 --- a/src/meta/adx_keys.h +++ b/src/meta/adx_keys.h @@ -244,7 +244,7 @@ static const adxkey_info adxkey9_list[] = { {0x0000,0x1c85,0x7043, NULL,29915170}, // 0000000001C87822 /* Assault Lily Last Bullet (Android) */ - {0x0aca,0x0ef5,0x05c9, NULL,0}, // guessed with VGAudio (possible key: 5650EF42E5 / 370725044965) + {0x0000,0x0000,0x0000, NULL,6349046567469313}, // 00168E6C99510101 (+ AWB subkeys) }; diff --git a/src/meta/awb.c b/src/meta/awb.c index 29a091aa..5d3293d9 100644 --- a/src/meta/awb.c +++ b/src/meta/awb.c @@ -135,7 +135,7 @@ VGMSTREAM* init_vgmstream_awb_memory(STREAMFILE* sf, STREAMFILE* sf_acb) { if (!vgmstream) goto fail; break; case ADX: /* Okami HD (PS4) */ - vgmstream = init_vgmstream_adx(temp_sf); + vgmstream = init_vgmstream_adx_subkey(temp_sf, subkey); if (!vgmstream) goto fail; break; case VAG: /* Ukiyo no Roushi (Vita) */ diff --git a/src/meta/meta.h b/src/meta/meta.h index f84f56a7..7506315f 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -6,7 +6,8 @@ VGMSTREAM* init_vgmstream_silence(int channels, int sample_rate, int32_t num_samples); -VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile); +VGMSTREAM* init_vgmstream_adx(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey); VGMSTREAM * init_vgmstream_afc(STREAMFILE *streamFile); From c72ca9eeffd30a1c3ac1ae5ae1a40104a75fde24 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 21 Feb 2021 22:09:11 +0100 Subject: [PATCH 3/4] Add encrypted Ogg [Adventure Field 4 (PC)] --- src/meta/ogg_vorbis.c | 47 +++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/src/meta/ogg_vorbis.c b/src/meta/ogg_vorbis.c index 5cfebf28..969935a9 100644 --- a/src/meta/ogg_vorbis.c +++ b/src/meta/ogg_vorbis.c @@ -82,6 +82,20 @@ static void rpgmvo_ogg_decryption_callback(void* ptr, size_t size, size_t nmemb, } } +static void at4_ogg_decryption_callback(void* ptr, size_t size, size_t nmemb, void* datasource) { + static const uint8_t af4_key[0x10] = { + 0x00,0x0E,0x08,0x1E, 0x18,0x37,0x12,0x00, 0x48,0x87,0x46,0x0B, 0x9C,0x68,0xA8,0x4B + }; + uint8_t *ptr8 = ptr; + size_t bytes_read = size * nmemb; + ogg_vorbis_io *io = datasource; + int i; + + for (i = 0; i < bytes_read; i++) { + ptr8[i] -= af4_key[(io->offset + i) % sizeof(af4_key)]; + } +} + static const uint32_t xiph_mappings[] = { 0, @@ -152,31 +166,34 @@ VGMSTREAM* init_vgmstream_ogg_vorbis(STREAMFILE* sf) { } if (is_ogg) { - if (read_32bitBE(0x00,sf) == 0x2c444430) { /* Psychic Software [Darkwind: War on Wheels (PC)] */ + if (read_u32be(0x00,sf) == 0x2c444430) { /* Psychic Software [Darkwind: War on Wheels (PC)] */ ovmi.decryption_callback = psychic_ogg_decryption_callback; } - else if (read_32bitBE(0x00,sf) == 0x4C325344) { /* "L2SD" instead of "OggS" [Lineage II Chronicle 4 (PC)] */ + else if (read_u32be(0x00,sf) == 0x4C325344) { /* "L2SD" instead of "OggS" [Lineage II Chronicle 4 (PC)] */ cfg.is_header_swap = 1; cfg.is_encrypted = 1; } - else if (read_32bitBE(0x00,sf) == 0x048686C5) { /* "OggS" XOR'ed + bitswapped [Ys VIII (PC)] */ + else if (read_u32be(0x00,sf) == 0x048686C5) { /* "OggS" XOR'ed + bitswapped [Ys VIII (PC)] */ cfg.key[0] = 0xF0; cfg.key_len = 1; cfg.is_nibble_swap = 1; cfg.is_encrypted = 1; } - else if (read_32bitBE(0x00,sf) == 0x00000000 && /* null instead of "OggS" [Yuppie Psycho (PC)] */ - read_32bitBE(0x3a,sf) == 0x4F676753) { /* "OggS" in next page */ + else if (read_u32be(0x00,sf) == 0x00000000 && /* null instead of "OggS" [Yuppie Psycho (PC)] */ + read_u32be(0x3a,sf) == 0x4F676753) { /* "OggS" in next page */ cfg.is_header_swap = 1; cfg.is_encrypted = 1; } - else if (read_32bitBE(0x00,sf) != 0x4F676753 && /* random(?) swap instead of "OggS" [Tobi Tsukihime (PC)] */ - read_32bitBE(0x3a,sf) == 0x4F676753) { /* "OggS" in next page */ + else if (read_u32be(0x00,sf) != 0x4F676753 && /* random(?) swap instead of "OggS" [Tobi Tsukihime (PC)] */ + read_u32be(0x3a,sf) == 0x4F676753) { /* "OggS" in next page */ cfg.is_header_swap = 1; cfg.is_encrypted = 1; } - else if (read_32bitBE(0x00,sf) == 0x4F676753) { /* "OggS" (standard) */ + else if (read_u32be(0x00,sf) == 0x4F756F71) { /* "OggS" encrypted [Adventure Field 4 (PC)]*/ + ovmi.decryption_callback = at4_ogg_decryption_callback; + } + else if (read_u32be(0x00,sf) == 0x4F676753) { /* "OggS" (standard) */ ; } else { @@ -185,13 +202,13 @@ VGMSTREAM* init_vgmstream_ogg_vorbis(STREAMFILE* sf) { } if (is_um3) { /* ["Ultramarine3" (???)] */ - if (read_32bitBE(0x00,sf) != 0x4f676753) { /* "OggS" (optionally encrypted) */ + if (read_u32be(0x00,sf) != 0x4f676753) { /* "OggS" (optionally encrypted) */ ovmi.decryption_callback = um3_ogg_decryption_callback; } } if (is_kovs) { /* Koei Tecmo PC games */ - if (read_32bitBE(0x00,sf) != 0x4b4f5653) { /* "KOVS" */ + if (read_u32be(0x00,sf) != 0x4b4f5653) { /* "KOVS" */ goto fail; } ovmi.loop_start = read_32bitLE(0x08,sf); @@ -203,7 +220,7 @@ VGMSTREAM* init_vgmstream_ogg_vorbis(STREAMFILE* sf) { } if (is_sngw) { /* [Capcom's MT Framework PC games] */ - if (read_32bitBE(0x00,sf) != 0x4f676753) { /* "OggS" (optionally encrypted) */ + if (read_u32be(0x00,sf) != 0x4f676753) { /* "OggS" (optionally encrypted) */ cfg.key_len = read_streamfile(cfg.key, 0x00, 0x04, sf); cfg.is_header_swap = 1; cfg.is_nibble_swap = 1; @@ -217,7 +234,7 @@ VGMSTREAM* init_vgmstream_ogg_vorbis(STREAMFILE* sf) { const char *isl_name = NULL; /* check various encrypted "OggS" values */ - if (read_32bitBE(0x00,sf) == 0xAF678753) { /* Azure Striker Gunvolt (PC) */ + if (read_u32be(0x00,sf) == 0xAF678753) { /* Azure Striker Gunvolt (PC) */ static const uint8_t isd_gv_key[16] = { 0xe0,0x00,0xe0,0x00,0xa0,0x00,0x00,0x00,0xe0,0x00,0xe0,0x80,0x40,0x40,0x40,0x00 }; @@ -225,7 +242,7 @@ VGMSTREAM* init_vgmstream_ogg_vorbis(STREAMFILE* sf) { memcpy(cfg.key, isd_gv_key, cfg.key_len); isl_name = "GV_steam.isl"; } - else if (read_32bitBE(0x00,sf) == 0x0FE787D3) { /* Mighty Gunvolt (PC) */ + else if (read_u32be(0x00,sf) == 0x0FE787D3) { /* Mighty Gunvolt (PC) */ static const uint8_t isd_mgv_key[120] = { 0x40,0x80,0xE0,0x80,0x40,0x40,0xA0,0x00,0xA0,0x40,0x00,0x80,0x00,0x40,0xA0,0x00, 0xC0,0x40,0xE0,0x00,0x60,0x40,0x80,0x00,0xA0,0x00,0xE0,0x00,0x60,0x40,0xC0,0x00, @@ -240,7 +257,7 @@ VGMSTREAM* init_vgmstream_ogg_vorbis(STREAMFILE* sf) { memcpy(cfg.key, isd_mgv_key, cfg.key_len); isl_name = "MGV_steam.isl"; } - else if (read_32bitBE(0x00,sf) == 0x0FA74753) { /* Blaster Master Zero (PC) */ + else if (read_u32be(0x00,sf) == 0x0FA74753) { /* Blaster Master Zero (PC) */ static const uint8_t isd_bmz_key[120] = { 0x40,0xC0,0x20,0x00,0x40,0xC0,0xC0,0x00,0x00,0x80,0xE0,0x80,0x80,0x40,0x20,0x00, 0x60,0xC0,0xC0,0x00,0xA0,0x80,0x60,0x00,0x40,0x40,0x20,0x00,0x60,0x40,0xC0,0x00, @@ -374,7 +391,7 @@ VGMSTREAM* init_vgmstream_ogg_vorbis(STREAMFILE* sf) { uint32_t xor_be; put_32bitLE(key, (uint32_t)file_size); - xor_be = (uint32_t)get_32bitBE(key); + xor_be = get_u32be(key); if ((read_32bitBE(0x00,sf) ^ xor_be) == 0x4F676753) { /* "OggS" */ int i; cfg.key_len = 4; From 5d40f91ecda805e88266ce232fd55e84662919e6 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 21 Feb 2021 22:09:36 +0100 Subject: [PATCH 4/4] ubi_sb: Missing include --- src/meta/ubi_sb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/meta/ubi_sb.c b/src/meta/ubi_sb.c index fe0f7993..a5ab0501 100644 --- a/src/meta/ubi_sb.c +++ b/src/meta/ubi_sb.c @@ -1,3 +1,4 @@ +#include #include "meta.h" #include "../layout/layout.h" #include "../coding/coding.h"