Updated VGMStream to r1050-536-gf670ae05.
parent
95e853a544
commit
c831470851
|
@ -400,7 +400,7 @@ static const coding_info coding_info_list[] = {
|
|||
{coding_CRI_ADX_exp, "CRI ADX 4-bit ADPCM with exponential scale"},
|
||||
{coding_CRI_ADX_fixed, "CRI ADX 4-bit ADPCM with fixed coefficients"},
|
||||
{coding_CRI_ADX_enc_8, "CRI ADX 4-bit ADPCM (type 8 encryption)"},
|
||||
{coding_CRI_ADX_enc_9, "CRI ADX 4-bit ADPCM (type 8 encryption)"},
|
||||
{coding_CRI_ADX_enc_9, "CRI ADX 4-bit ADPCM (type 9 encryption)"},
|
||||
{coding_NGC_DSP, "Nintendo DSP 4-bit ADPCM"},
|
||||
{coding_NGC_DTK, "Nintendo DTK 4-bit ADPCM"},
|
||||
{coding_NGC_AFC, "Nintendo AFC 4-bit ADPCM"},
|
||||
|
|
|
@ -240,8 +240,8 @@ static struct {
|
|||
uint16_t start,mult,add;
|
||||
} keys_8[] = {
|
||||
/* Clover Studio (GOD HAND, Okami) */
|
||||
/* I'm pretty sure this is right, based on a decrypted version of some GOD HAND tracks. */
|
||||
/* Also it is the 2nd result from guessadx */
|
||||
/* Verified by VGAudio and the game's executable */
|
||||
/* Key string: karaage */
|
||||
{0x49e1,0x4a57,0x553d},
|
||||
|
||||
/* Grasshopper Manufacture 0 (Blood+) */
|
||||
|
@ -261,7 +261,8 @@ static struct {
|
|||
{0x66f5,0x58bd,0x4459},
|
||||
|
||||
/* Sonic Team 0 (Phantasy Star Universe) */
|
||||
/* this is estimated */
|
||||
/* Verified by VGAudio and the game's executable */
|
||||
/* Key string: 3x5k62bg9ptbwy */
|
||||
{0x5deb,0x5f27,0x673f},
|
||||
|
||||
/* G.rev 0 (Senko no Ronde) */
|
||||
|
@ -284,11 +285,13 @@ static struct {
|
|||
{0x4d65,0x5eb7,0x5dfd},
|
||||
|
||||
/* Sonic Team 2 (Sonic and the Black Knight) */
|
||||
/* confirmed unique with guessadx */
|
||||
/* Verified by VGAudio and the game's executable */
|
||||
/* Key string: morio */
|
||||
{0x55b7,0x6191,0x5a77},
|
||||
|
||||
/* Enterbrain (Amagami) */
|
||||
/* one of 32 from guessadx */
|
||||
/* Verified by VGAudio and the game's executable */
|
||||
/* Key string: mituba */
|
||||
{0x5a17,0x509f,0x5bfd},
|
||||
|
||||
/* Yamasa (Yamasa Digi Portable: Matsuri no Tatsujin) */
|
||||
|
@ -471,17 +474,25 @@ static struct {
|
|||
{0x07d2,0x1ec5,0x0c7f},
|
||||
|
||||
/* Dragon Ball Z: Dokkan Battle
|
||||
* guessed with degod */
|
||||
* Verified by VGAudio
|
||||
* Key code: 416383518 */
|
||||
{0x0003,0x0d19,0x043b},
|
||||
|
||||
/* Kisou Ryouhei Gunhound EX (2013-01-31)(Dracue)[PSP]
|
||||
* guessed with degod */
|
||||
* Verified by VGAudio
|
||||
* Key code: 683461999 */
|
||||
{0x0005,0x0bcd,0x1add},
|
||||
|
||||
/* Raramagi [Android]
|
||||
* found in 2ch */
|
||||
* Verified by VGAudio
|
||||
* Key code: 12160794 */
|
||||
{0x0000,0x0b99,0x1e33},
|
||||
|
||||
/* Sonic runners [Android]
|
||||
* Verified by VGAudio
|
||||
* Key code: 19910623 */
|
||||
{0x0000,0x12fd,0x1fbd},
|
||||
|
||||
};
|
||||
|
||||
static const int keys_8_count = sizeof(keys_8)/sizeof(keys_8[0]);
|
||||
|
@ -548,6 +559,8 @@ static int find_key(STREAMFILE *file, uint8_t type, uint16_t *xor_start, uint16_
|
|||
{
|
||||
/* try to guess key */
|
||||
#define MAX_FRAMES (INT_MAX/0x8000)
|
||||
struct { uint16_t start, mult, add; } *keys = NULL;
|
||||
int keycount = 0, keymask = 0;
|
||||
int scales_to_do;
|
||||
int key_id;
|
||||
|
||||
|
@ -582,82 +595,52 @@ static int find_key(STREAMFILE *file, uint8_t type, uint16_t *xor_start, uint16_
|
|||
|
||||
if (type == 8)
|
||||
{
|
||||
/* guess each of the keys */
|
||||
for (key_id=0;key_id<keys_8_count;key_id++) {
|
||||
/* test pre-scales */
|
||||
uint16_t xor = keys_8[key_id].start;
|
||||
uint16_t mult = keys_8[key_id].mult;
|
||||
uint16_t add = keys_8[key_id].add;
|
||||
int i;
|
||||
|
||||
for (i=0;i<bruteframe &&
|
||||
((prescales[i]&0x6000)==(xor&0x6000) ||
|
||||
prescales[i]==0);
|
||||
i++) {
|
||||
xor = xor * mult + add;
|
||||
}
|
||||
|
||||
if (i == bruteframe)
|
||||
{
|
||||
/* test */
|
||||
for (i=0;i<scales_to_do &&
|
||||
(scales[i]&0x6000)==(xor&0x6000);i++) {
|
||||
xor = xor * mult + add;
|
||||
}
|
||||
if (i == scales_to_do)
|
||||
{
|
||||
*xor_start = keys_8[key_id].start;
|
||||
*xor_mult = keys_8[key_id].mult;
|
||||
*xor_add = keys_8[key_id].add;
|
||||
|
||||
rc = 1;
|
||||
goto find_key_cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
keys = &keys_8;
|
||||
keycount = keys_8_count;
|
||||
keymask = 0x6000;
|
||||
}
|
||||
else if (type == 9)
|
||||
{
|
||||
/* smarter XOR as seen in PSO2, can't do an exact match so we
|
||||
* have to search for the lowest */
|
||||
long best_score = MAX_FRAMES * 0x1fff;
|
||||
/* smarter XOR as seen in PSO2. The scale is technically 13 bits,
|
||||
* but the maximum value assigned by the encoder is 0x1000.
|
||||
* This is written to the ADX file as 0xFFF, leaving the high bit
|
||||
* empty, which is used to validate a key */
|
||||
keys = &keys_9;
|
||||
keycount = keys_9_count;
|
||||
keymask = 0x1000;
|
||||
}
|
||||
|
||||
/* guess each of the keys */
|
||||
for (key_id=0;key_id<keys_9_count;key_id++) {
|
||||
/* run past pre-scales */
|
||||
uint16_t xor = keys_9[key_id].start;
|
||||
uint16_t mult = keys_9[key_id].mult;
|
||||
uint16_t add = keys_9[key_id].add;
|
||||
int i;
|
||||
long total_score = 0;
|
||||
/* guess each of the keys */
|
||||
for (key_id=0;key_id<keycount;key_id++) {
|
||||
/* test pre-scales */
|
||||
uint16_t xor = keys[key_id].start;
|
||||
uint16_t mult = keys[key_id].mult;
|
||||
uint16_t add = keys[key_id].add;
|
||||
int i;
|
||||
|
||||
for (i=0;i<bruteframe;i++) {
|
||||
xor = xor * mult + add;
|
||||
}
|
||||
|
||||
if (i == bruteframe)
|
||||
{
|
||||
/* test */
|
||||
for (i=0;i<scales_to_do && total_score < best_score;i++) {
|
||||
xor = xor * mult + add;
|
||||
total_score += (scales[i]^xor)&0x1fff;
|
||||
}
|
||||
|
||||
if (total_score < best_score)
|
||||
{
|
||||
*xor_start = keys_9[key_id].start;
|
||||
*xor_mult = keys_9[key_id].mult;
|
||||
*xor_add = keys_9[key_id].add;
|
||||
|
||||
best_score = total_score;
|
||||
}
|
||||
}
|
||||
for (i=0;i<bruteframe &&
|
||||
((prescales[i]&keymask)==(xor&keymask) ||
|
||||
prescales[i]==0);
|
||||
i++) {
|
||||
xor = xor * mult + add;
|
||||
}
|
||||
|
||||
/* arbitrarily decide if we have won? */
|
||||
if (best_score < scales_to_do * 0x1000)
|
||||
if (i == bruteframe)
|
||||
{
|
||||
rc = 1;
|
||||
/* test */
|
||||
for (i=0;i<scales_to_do &&
|
||||
(scales[i]&keymask)==(xor&keymask);i++) {
|
||||
xor = xor * mult + add;
|
||||
}
|
||||
if (i == scales_to_do)
|
||||
{
|
||||
*xor_start = keys[key_id].start;
|
||||
*xor_mult = keys[key_id].mult;
|
||||
*xor_add = keys[key_id].add;
|
||||
|
||||
rc = 1;
|
||||
goto find_key_cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue