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",
|
"snd",
|
||||||
"snds",
|
"snds",
|
||||||
"sng",
|
"sng",
|
||||||
|
"sngw",
|
||||||
"snr",
|
"snr",
|
||||||
"sns",
|
"sns",
|
||||||
"snu",
|
"snu",
|
||||||
@ -933,16 +934,15 @@ static const meta_info meta_info_list[] = {
|
|||||||
{meta_NGC_VID1, "Neversoft VID1 header"},
|
{meta_NGC_VID1, "Neversoft VID1 header"},
|
||||||
{meta_PC_FLX, "Ultima IX .FLX header"},
|
{meta_PC_FLX, "Ultima IX .FLX header"},
|
||||||
{meta_MOGG, "Harmonix Music Systems MOGG Vorbis"},
|
{meta_MOGG, "Harmonix Music Systems MOGG Vorbis"},
|
||||||
|
|
||||||
#ifdef VGM_USE_VORBIS
|
|
||||||
{meta_OGG_VORBIS, "Ogg Vorbis"},
|
{meta_OGG_VORBIS, "Ogg Vorbis"},
|
||||||
{meta_OGG_SLI, "Ogg Vorbis with .sli (start,length) for looping"},
|
{meta_OGG_SLI, "Ogg Vorbis with .sli (start,length) for looping"},
|
||||||
{meta_OGG_SLI2, "Ogg Vorbis with .sli (from,to) for looping"},
|
{meta_OGG_SLI2, "Ogg Vorbis with .sli (from,to) for looping"},
|
||||||
{meta_OGG_SFL, "Ogg Vorbis with SFPL for looping"},
|
{meta_OGG_SFL, "Ogg Vorbis with SFPL for looping"},
|
||||||
{meta_OGG_UM3, "Ogg Vorbis, Ultramarine3 'encryption'"},
|
{meta_OGG_UM3, "Ogg Vorbis (Ultramarine3)"},
|
||||||
{meta_OGG_KOVS, "Ogg Vorbis, KOVS header"},
|
{meta_OGG_KOVS, "Ogg Vorbis (KOVS header)"},
|
||||||
{meta_OGG_PSYCH, "Ogg Vorbis, Psychic Software obfuscation"},
|
{meta_OGG_PSYCH, "Ogg Vorbis (Psychic Software)"},
|
||||||
#endif
|
{meta_OGG_SNGW, "Ogg Vorbis (Capcom)"},
|
||||||
|
|
||||||
#ifdef VGM_USE_MP4V2
|
#ifdef VGM_USE_MP4V2
|
||||||
{meta_MP4, "AAC header"},
|
{meta_MP4, "AAC header"},
|
||||||
#endif
|
#endif
|
||||||
|
@ -103,6 +103,7 @@ typedef struct {
|
|||||||
void (*decryption_callback)(void *ptr, size_t size, size_t nmemb, void *datasource);
|
void (*decryption_callback)(void *ptr, size_t size, size_t nmemb, void *datasource);
|
||||||
uint8_t scd_xor;
|
uint8_t scd_xor;
|
||||||
off_t scd_xor_length;
|
off_t scd_xor_length;
|
||||||
|
uint32_t sngw_xor;
|
||||||
|
|
||||||
} vgm_vorbis_info_t;
|
} 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 */
|
/* Ogg Vorbis, by way of libvorbisfile; may contain loop comments */
|
||||||
VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
||||||
@ -121,6 +145,7 @@ VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
|||||||
int is_um3 = 0;
|
int is_um3 = 0;
|
||||||
int is_kovs = 0;
|
int is_kovs = 0;
|
||||||
int is_psychic = 0;
|
int is_psychic = 0;
|
||||||
|
int is_sngw = 0;
|
||||||
|
|
||||||
|
|
||||||
/* check extension */
|
/* check extension */
|
||||||
@ -130,6 +155,8 @@ VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
|||||||
is_um3 = 1;
|
is_um3 = 1;
|
||||||
} else if (check_extensions(streamFile,"kvs,kovs")) { /* .kvs: Atelier Sophie (PC), kovs: header id only? */
|
} else if (check_extensions(streamFile,"kvs,kovs")) { /* .kvs: Atelier Sophie (PC), kovs: header id only? */
|
||||||
is_kovs = 1;
|
is_kovs = 1;
|
||||||
|
} else if (check_extensions(streamFile,"sngw")) { /* .sngw: Devil May Cry 4 SE (PC), Biohazard 6 (PC) */
|
||||||
|
is_sngw = 1;
|
||||||
} else {
|
} else {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -167,12 +194,23 @@ VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
|||||||
start_offset = 0x20;
|
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) {
|
if (is_um3) {
|
||||||
inf.meta_type = meta_OGG_UM3;
|
inf.meta_type = meta_OGG_UM3;
|
||||||
} else if (is_kovs) {
|
} else if (is_kovs) {
|
||||||
inf.meta_type = meta_OGG_KOVS;
|
inf.meta_type = meta_OGG_KOVS;
|
||||||
} else if (is_psychic) {
|
} else if (is_psychic) {
|
||||||
inf.meta_type = meta_OGG_PSYCH;
|
inf.meta_type = meta_OGG_PSYCH;
|
||||||
|
} else if (is_sngw) {
|
||||||
|
inf.meta_type = meta_OGG_SNGW;
|
||||||
} else {
|
} else {
|
||||||
inf.meta_type = meta_OGG_VORBIS;
|
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.decryption_callback = vgm_inf->decryption_callback;
|
||||||
temp_streamfile.scd_xor = vgm_inf->scd_xor;
|
temp_streamfile.scd_xor = vgm_inf->scd_xor;
|
||||||
temp_streamfile.scd_xor_length = vgm_inf->scd_xor_length;
|
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 */
|
/* open the ogg vorbis file for testing */
|
||||||
memset(&temp_ovf, 0, sizeof(temp_ovf));
|
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.decryption_callback = vgm_inf->decryption_callback;
|
||||||
data->ov_streamfile.scd_xor = vgm_inf->scd_xor;
|
data->ov_streamfile.scd_xor = vgm_inf->scd_xor;
|
||||||
data->ov_streamfile.scd_xor_length = vgm_inf->scd_xor_length;
|
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 */
|
/* open the ogg vorbis file for real */
|
||||||
if (ov_open_callbacks(&data->ov_streamfile, &data->ogg_vorbis_file, NULL, 0, *callbacks_p))
|
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_NGC_VID1, /* Neversoft .ogg (Gun GC) */
|
||||||
meta_PC_FLX, /* Ultima IX PC */
|
meta_PC_FLX, /* Ultima IX PC */
|
||||||
meta_MOGG, /* Harmonix Music Systems MOGG Vorbis */
|
meta_MOGG, /* Harmonix Music Systems MOGG Vorbis */
|
||||||
|
|
||||||
#ifdef VGM_USE_VORBIS
|
|
||||||
meta_OGG_VORBIS, /* Ogg Vorbis */
|
meta_OGG_VORBIS, /* Ogg Vorbis */
|
||||||
meta_OGG_SLI, /* Ogg Vorbis file w/ companion .sli for looping */
|
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_SLI2, /* Ogg Vorbis file w/ different styled .sli for looping */
|
||||||
meta_OGG_SFL, /* Ogg Vorbis file w/ .sfl (RIFF SFPL) 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_UM3, /* Ogg Vorbis with optional first 0x800 bytes XOR 0xFF */
|
||||||
meta_OGG_KOVS, /* Ogg Vorbis with exta header and 0x100 bytes XOR */
|
meta_OGG_KOVS, /* Ogg Vorbis with extra header and 0x100 bytes XOR */
|
||||||
meta_OGG_PSYCH, /* Ogg Vorbis with all bytes -0x23*/
|
meta_OGG_PSYCH, /* Ogg Vorbis with all bytes -0x23 */
|
||||||
#endif
|
meta_OGG_SNGW, /* Ogg Vorbis with optional key XOR + nibble swap */
|
||||||
|
|
||||||
#ifdef VGM_USE_MP4V2
|
#ifdef VGM_USE_MP4V2
|
||||||
meta_MP4, /* AAC (iOS) */
|
meta_MP4, /* AAC (iOS) */
|
||||||
#endif
|
#endif
|
||||||
@ -798,11 +797,12 @@ typedef struct {
|
|||||||
ogg_int64_t size;
|
ogg_int64_t size;
|
||||||
ogg_int64_t other_header_bytes;
|
ogg_int64_t other_header_bytes;
|
||||||
|
|
||||||
/* XOR setup (SCD) */
|
/* decryption setup */
|
||||||
int decryption_enabled;
|
void (*decryption_callback)(void *ptr, size_t size, size_t nmemb, void *datasource);
|
||||||
void (*decryption_callback)(void *ptr, size_t size, size_t nmemb, void *datasource, int bytes_read);
|
|
||||||
uint8_t scd_xor;
|
uint8_t scd_xor;
|
||||||
off_t scd_xor_length;
|
off_t scd_xor_length;
|
||||||
|
uint32_t sngw_xor;
|
||||||
|
|
||||||
} ogg_vorbis_streamfile;
|
} ogg_vorbis_streamfile;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user