Encrypted ADX playback, currently assumed Clover Stuios key without any checking

git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@533 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
halleyscometsw 2008-12-24 07:19:15 +00:00
parent 4b578db302
commit c70680a1e6
5 changed files with 95 additions and 1 deletions

View File

@ -33,3 +33,49 @@ void decode_adx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
stream->adpcm_history1_32 = hist1;
stream->adpcm_history2_32 = hist2;
}
void adx_next_key(VGMSTREAMCHANNEL * stream)
{
stream->adx_xor = ( stream->adx_xor * stream->adx_mult + stream->adx_add ) & 0x7fff;
}
void decode_adx_enc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
int i;
int32_t sample_count;
int framesin = first_sample/32;
int32_t scale = (read_16bitBE(stream->offset+framesin*18,stream->streamfile) ^ stream->adx_xor) + 1;
int32_t hist1 = stream->adpcm_history1_32;
int32_t hist2 = stream->adpcm_history2_32;
int coef1 = stream->adpcm_coef[0];
int coef2 = stream->adpcm_coef[1];
first_sample = first_sample%32;
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
int sample_byte = read_8bit(stream->offset+framesin*18+2+i/2,stream->streamfile);
outbuf[sample_count] = clamp16(
(i&1?
get_low_nibble_signed(sample_byte):
get_high_nibble_signed(sample_byte)
) * scale +
((coef1 * hist1 + coef2 * hist2) >> 12)
);
hist2 = hist1;
hist1 = outbuf[sample_count];
}
stream->adpcm_history1_32 = hist1;
stream->adpcm_history2_32 = hist2;
if (!(i % 32)) {
for (i=0;i<stream->adx_channels;i++)
{
adx_next_key(stream);
}
}
}

View File

@ -4,6 +4,9 @@
#include "../vgmstream.h"
void decode_adx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_adx_enc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void adx_next_key(VGMSTREAMCHANNEL * stream);
void decode_g721(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void g72x_init_state(struct g72x_state *state_ptr);

View File

@ -3,6 +3,7 @@
#endif
#include <math.h>
#include "meta.h"
#include "../coding/coding.h"
#include "../util.h"
VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
@ -20,6 +21,8 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
int16_t coef1, coef2;
uint16_t cutoff;
char filename[260];
int coding_type = coding_CRI_ADX;
uint16_t xor_start=0,xor_mult=0,xor_add=0;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
@ -49,6 +52,16 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
/* check version signature, read loop info */
version_signature = read_16bitBE(0x12,streamFile);
/* encryption */
if (version_signature == 0x0408) {
/* TODO: check key */
coding_type = coding_CRI_ADX_enc;
/* Clover Studio (GOD HAND, Okami), 2nd result from guessadx */
xor_start = 0x49e1;
xor_mult = 0x4a57;
xor_add = 0x553d;
version_signature = 0x0400;
}
if (version_signature == 0x0300) { /* type 03 */
header_type = meta_ADX_03;
if (stream_offset-6 >= 0x2c) { /* enough space for loop info? */
@ -94,7 +107,7 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
vgmstream->loop_start_sample = loop_start_sample;
vgmstream->loop_end_sample = loop_end_sample;
vgmstream->coding_type = coding_CRI_ADX;
vgmstream->coding_type = coding_type;
if (channel_count==1)
vgmstream->layout_type = layout_none;
else
@ -136,6 +149,18 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
vgmstream->ch[i].adpcm_coef[0] = coef1;
vgmstream->ch[i].adpcm_coef[1] = coef2;
if (coding_type == coding_CRI_ADX_enc)
{
int j;
vgmstream->ch[i].adx_channels = channel_count;
vgmstream->ch[i].adx_xor = xor_start;
vgmstream->ch[i].adx_mult = xor_mult;
vgmstream->ch[i].adx_add = xor_add;
for (j=0;j<i;j++)
adx_next_key(&vgmstream->ch[i]);
}
}
}

View File

@ -558,6 +558,7 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
switch (vgmstream->coding_type) {
case coding_CRI_ADX:
case coding_CRI_ADX_enc:
return 32;
case coding_NGC_DSP:
return 14;
@ -643,6 +644,7 @@ int get_vgmstream_samples_per_shortframe(VGMSTREAM * vgmstream) {
int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
switch (vgmstream->coding_type) {
case coding_CRI_ADX:
case coding_CRI_ADX_enc:
return 18;
case coding_NGC_DSP:
return 8;
@ -735,6 +737,14 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
samples_to_do);
}
break;
case coding_CRI_ADX_enc:
for (chan=0;chan<vgmstream->channels;chan++) {
decode_adx_enc(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
vgmstream->channels,vgmstream->samples_into_block,
samples_to_do);
}
break;
case coding_NGC_DSP:
for (chan=0;chan<vgmstream->channels;chan++) {
@ -1172,6 +1182,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
case coding_CRI_ADX:
snprintf(temp,TEMPSIZE,"CRI ADX 4-bit ADPCM");
break;
case coding_CRI_ADX_enc:
snprintf(temp,TEMPSIZE,"encrypted CRI ADX 4-bit ADPCM");
break;
case coding_NDS_IMA:
snprintf(temp,TEMPSIZE,"NDS-style 4-bit IMA ADPCM");
break;

View File

@ -43,6 +43,7 @@ typedef enum {
/* 4-bit ADPCM */
coding_NDS_IMA, /* IMA ADPCM w/ NDS layout */
coding_CRI_ADX, /* CRI ADX */
coding_CRI_ADX_enc, /* encrypted CRI ADX */
coding_NGC_DSP, /* NGC ADPCM, called DSP */
coding_NGC_DTK, /* NGC hardware disc ADPCM, called DTK, TRK or ADP */
coding_G721, /* CCITT G.721 ADPCM */
@ -384,6 +385,12 @@ typedef struct {
int samples_done;
int16_t loop_history1,loop_history2;
#endif
/* ADX encryption */
int adx_channels;
uint16_t adx_xor;
uint16_t adx_mult;
uint16_t adx_add;
} VGMSTREAMCHANNEL;
typedef struct {