mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-15 19:13:20 +01:00
Add .SNGW Ogg Vorbis (normal and encrypted) [Capcom PC games]
Also remove ifdefs for meta_OGG_x, there was no benefit
This commit is contained in:
parent
7134610495
commit
a67a83b9ed
@ -282,6 +282,7 @@ static const char* extension_list[] = {
|
||||
"snd",
|
||||
"snds",
|
||||
"sng",
|
||||
"sngw",
|
||||
"snr",
|
||||
"sns",
|
||||
"snu",
|
||||
@ -933,16 +934,15 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_NGC_VID1, "Neversoft VID1 header"},
|
||||
{meta_PC_FLX, "Ultima IX .FLX header"},
|
||||
{meta_MOGG, "Harmonix Music Systems MOGG Vorbis"},
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
{meta_OGG_VORBIS, "Ogg Vorbis"},
|
||||
{meta_OGG_SLI, "Ogg Vorbis with .sli (start,length) for looping"},
|
||||
{meta_OGG_SLI2, "Ogg Vorbis with .sli (from,to) for looping"},
|
||||
{meta_OGG_SFL, "Ogg Vorbis with SFPL for looping"},
|
||||
{meta_OGG_UM3, "Ogg Vorbis, Ultramarine3 'encryption'"},
|
||||
{meta_OGG_KOVS, "Ogg Vorbis, KOVS header"},
|
||||
{meta_OGG_PSYCH, "Ogg Vorbis, Psychic Software obfuscation"},
|
||||
#endif
|
||||
{meta_OGG_UM3, "Ogg Vorbis (Ultramarine3)"},
|
||||
{meta_OGG_KOVS, "Ogg Vorbis (KOVS header)"},
|
||||
{meta_OGG_PSYCH, "Ogg Vorbis (Psychic Software)"},
|
||||
{meta_OGG_SNGW, "Ogg Vorbis (Capcom)"},
|
||||
|
||||
#ifdef VGM_USE_MP4V2
|
||||
{meta_MP4, "AAC header"},
|
||||
#endif
|
||||
|
@ -103,6 +103,7 @@ typedef struct {
|
||||
void (*decryption_callback)(void *ptr, size_t size, size_t nmemb, void *datasource);
|
||||
uint8_t scd_xor;
|
||||
off_t scd_xor_length;
|
||||
uint32_t sngw_xor;
|
||||
|
||||
} vgm_vorbis_info_t;
|
||||
|
||||
|
@ -110,6 +110,30 @@ static void psychic_ogg_decryption_callback(void *ptr, size_t size, size_t nmemb
|
||||
}
|
||||
}
|
||||
|
||||
static void sngw_ogg_decryption_callback(void *ptr, size_t size, size_t nmemb, void *datasource) {
|
||||
size_t bytes_read = size*nmemb;
|
||||
ogg_vorbis_streamfile * const ov_streamfile = datasource;
|
||||
int i;
|
||||
char *header_id = "OggS";
|
||||
uint8_t key[4];
|
||||
|
||||
put_32bitBE(key, ov_streamfile->sngw_xor);
|
||||
|
||||
/* bytes are xor'd with key and nibble-swapped */
|
||||
{
|
||||
for (i = 0; i < bytes_read; i++) {
|
||||
if (ov_streamfile->offset+i < 0x04) {
|
||||
/* replace key in the first 4 bytes with "OggS" */
|
||||
((uint8_t*)ptr)[i] = (uint8_t)header_id[(ov_streamfile->offset + i) % 4];
|
||||
}
|
||||
else {
|
||||
uint8_t val = ((uint8_t*)ptr)[i] ^ key[(ov_streamfile->offset + i) % 4];
|
||||
((uint8_t*)ptr)[i] = ((val << 4) & 0xf0) | ((val >> 4) & 0x0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Ogg Vorbis, by way of libvorbisfile; may contain loop comments */
|
||||
VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
||||
@ -121,6 +145,7 @@ VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
||||
int is_um3 = 0;
|
||||
int is_kovs = 0;
|
||||
int is_psychic = 0;
|
||||
int is_sngw = 0;
|
||||
|
||||
|
||||
/* check extension */
|
||||
@ -130,6 +155,8 @@ VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
||||
is_um3 = 1;
|
||||
} else if (check_extensions(streamFile,"kvs,kovs")) { /* .kvs: Atelier Sophie (PC), kovs: header id only? */
|
||||
is_kovs = 1;
|
||||
} else if (check_extensions(streamFile,"sngw")) { /* .sngw: Devil May Cry 4 SE (PC), Biohazard 6 (PC) */
|
||||
is_sngw = 1;
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
@ -167,12 +194,23 @@ VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
||||
start_offset = 0x20;
|
||||
}
|
||||
|
||||
/* check SNGW (Capcom's MT Framework PC games), may be encrypted */
|
||||
if (is_sngw) {
|
||||
if (read_32bitBE(0x00,streamFile) != 0x4f676753) { /* "OggS" */
|
||||
inf.sngw_xor = read_32bitBE(0x00,streamFile);
|
||||
inf.decryption_callback = sngw_ogg_decryption_callback;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (is_um3) {
|
||||
inf.meta_type = meta_OGG_UM3;
|
||||
} else if (is_kovs) {
|
||||
inf.meta_type = meta_OGG_KOVS;
|
||||
} else if (is_psychic) {
|
||||
inf.meta_type = meta_OGG_PSYCH;
|
||||
} else if (is_sngw) {
|
||||
inf.meta_type = meta_OGG_SNGW;
|
||||
} else {
|
||||
inf.meta_type = meta_OGG_VORBIS;
|
||||
}
|
||||
@ -220,6 +258,7 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
|
||||
temp_streamfile.decryption_callback = vgm_inf->decryption_callback;
|
||||
temp_streamfile.scd_xor = vgm_inf->scd_xor;
|
||||
temp_streamfile.scd_xor_length = vgm_inf->scd_xor_length;
|
||||
temp_streamfile.sngw_xor = vgm_inf->sngw_xor;
|
||||
|
||||
/* open the ogg vorbis file for testing */
|
||||
memset(&temp_ovf, 0, sizeof(temp_ovf));
|
||||
@ -245,6 +284,7 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
|
||||
data->ov_streamfile.decryption_callback = vgm_inf->decryption_callback;
|
||||
data->ov_streamfile.scd_xor = vgm_inf->scd_xor;
|
||||
data->ov_streamfile.scd_xor_length = vgm_inf->scd_xor_length;
|
||||
data->ov_streamfile.sngw_xor = vgm_inf->sngw_xor;
|
||||
|
||||
/* open the ogg vorbis file for real */
|
||||
if (ov_open_callbacks(&data->ov_streamfile, &data->ogg_vorbis_file, NULL, 0, *callbacks_p))
|
||||
|
@ -645,16 +645,15 @@ typedef enum {
|
||||
meta_NGC_VID1, /* Neversoft .ogg (Gun GC) */
|
||||
meta_PC_FLX, /* Ultima IX PC */
|
||||
meta_MOGG, /* Harmonix Music Systems MOGG Vorbis */
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
meta_OGG_VORBIS, /* Ogg Vorbis */
|
||||
meta_OGG_SLI, /* Ogg Vorbis file w/ companion .sli for looping */
|
||||
meta_OGG_SLI2, /* Ogg Vorbis file w/ different styled .sli for looping */
|
||||
meta_OGG_SFL, /* Ogg Vorbis file w/ .sfl (RIFF SFPL) for looping */
|
||||
meta_OGG_UM3, /* Ogg Vorbis with first 0x800 bytes XOR 0xFF */
|
||||
meta_OGG_KOVS, /* Ogg Vorbis with exta header and 0x100 bytes XOR */
|
||||
meta_OGG_PSYCH, /* Ogg Vorbis with all bytes -0x23*/
|
||||
#endif
|
||||
meta_OGG_UM3, /* Ogg Vorbis with optional first 0x800 bytes XOR 0xFF */
|
||||
meta_OGG_KOVS, /* Ogg Vorbis with extra header and 0x100 bytes XOR */
|
||||
meta_OGG_PSYCH, /* Ogg Vorbis with all bytes -0x23 */
|
||||
meta_OGG_SNGW, /* Ogg Vorbis with optional key XOR + nibble swap */
|
||||
|
||||
#ifdef VGM_USE_MP4V2
|
||||
meta_MP4, /* AAC (iOS) */
|
||||
#endif
|
||||
@ -798,11 +797,12 @@ typedef struct {
|
||||
ogg_int64_t size;
|
||||
ogg_int64_t other_header_bytes;
|
||||
|
||||
/* XOR setup (SCD) */
|
||||
int decryption_enabled;
|
||||
void (*decryption_callback)(void *ptr, size_t size, size_t nmemb, void *datasource, int bytes_read);
|
||||
/* decryption setup */
|
||||
void (*decryption_callback)(void *ptr, size_t size, size_t nmemb, void *datasource);
|
||||
uint8_t scd_xor;
|
||||
off_t scd_xor_length;
|
||||
uint32_t sngw_xor;
|
||||
|
||||
} ogg_vorbis_streamfile;
|
||||
|
||||
typedef struct {
|
||||
|
Loading…
Reference in New Issue
Block a user