mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-24 15:00:11 +01:00
Merge pull request #1431 from bnnm/asrs
- Add/fix some .srsa [Fate/Samurai Remnant (PC)] - Add FSB key
This commit is contained in:
commit
9073e90aaa
4
.github/formats-info.py
vendored
4
.github/formats-info.py
vendored
@ -317,7 +317,7 @@ class App:
|
||||
with open(file, 'r', encoding='utf-8') as f:
|
||||
is_updating = False
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
line = line.strip('\n')
|
||||
|
||||
# find list section, add all current lines and ignore old ones until next section
|
||||
if line.startswith('### List'):
|
||||
@ -334,6 +334,8 @@ class App:
|
||||
if not is_updating:
|
||||
doc_lines.append(line)
|
||||
|
||||
doc_lines.append('')
|
||||
|
||||
with open(file, 'w', encoding='utf-8', newline='\n') as f:
|
||||
f.write('\n'.join(doc_lines))
|
||||
|
||||
|
@ -523,6 +523,7 @@ static const char* extension_list[] = {
|
||||
"sps",
|
||||
"spsd",
|
||||
"spw",
|
||||
"srsa",
|
||||
"ss2",
|
||||
"ssd", //txth/reserved [Zack & Wiki (Wii)]
|
||||
"ssm",
|
||||
|
@ -71,6 +71,7 @@ static const fsbkey_info fsbkey_list[] = {
|
||||
{ MODE_FSB5_STD, FSBKEY_ADD("Aurogon666") }, // Afterimage demo (PC)
|
||||
{ MODE_FSB5_STD, FSBKEY_ADD("IfYouLikeThosesSoundsWhyNotRenumerateTheir2Authors?") }, // Blanc (PC/Switch)
|
||||
{ MODE_FSB5_STD, FSBKEY_ADD("L36nshM520") }, // Nishuihan Mobile (Android)
|
||||
{ MODE_FSB5_STD, FSBKEY_ADD("Forza2!") }, // Forza Motorsport (PC)
|
||||
|
||||
/* these games use a key per file, seemingly generated from the filename; could be possible to add them but there is a lot of songs,
|
||||
so external .fsbkey may be better (use guessfsb 3.1 with --write-key-file) */
|
||||
|
@ -7,6 +7,7 @@ typedef enum { NONE, MSADPCM, DSP, GCADPCM, ATRAC9, RIFF_ATRAC9, KOVS, KTSS, } k
|
||||
#define MAX_CHANNELS 8
|
||||
|
||||
typedef struct {
|
||||
bool is_srsa;
|
||||
int total_subsongs;
|
||||
int target_subsong;
|
||||
ktsr_codec codec;
|
||||
@ -31,12 +32,53 @@ typedef struct {
|
||||
char name[255+1];
|
||||
} ktsr_header;
|
||||
|
||||
static VGMSTREAM* init_vgmstream_ktsr_internal(STREAMFILE* sf, bool is_srsa);
|
||||
static int parse_ktsr(ktsr_header* ktsr, STREAMFILE* sf);
|
||||
static layered_layout_data* build_layered_atrac9(ktsr_header* ktsr, STREAMFILE *sf, uint32_t config_data);
|
||||
static VGMSTREAM* init_vgmstream_ktsr_sub(STREAMFILE* sf_b, ktsr_header* ktsr, VGMSTREAM* (*init_vgmstream)(STREAMFILE* sf), const char* ext);
|
||||
|
||||
/* KTSR - Koei Tecmo sound resource container */
|
||||
VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf) {
|
||||
return init_vgmstream_ktsr_internal(sf, false) ;
|
||||
}
|
||||
|
||||
/* ASRS - container of KTSR found in newer games */
|
||||
VGMSTREAM* init_vgmstream_asrs(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* temp_sf = NULL;
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00, sf, "ASRS"))
|
||||
return NULL;
|
||||
/* 0x04: null */
|
||||
/* 0x08: file size */
|
||||
/* 0x0c: null */
|
||||
|
||||
/* .srsa: header id (as generated by common tools) */
|
||||
if (!check_extensions(sf, "srsa"))
|
||||
return NULL;
|
||||
|
||||
|
||||
/* mini-container of memory-KTSR (streams also have a "TSRS" for stream-KTSR).
|
||||
* .srsa/srst usually have hashed filenames, so it isn't easy to match them, so this is mainly useful
|
||||
* for .srsa with internal streams. */
|
||||
uint32_t subfile_offset = 0x10;
|
||||
uint32_t subfile_size = get_streamfile_size(sf) - subfile_offset;
|
||||
|
||||
/* use a subfile b/c it's a pain to change all the offsets below and it's also how engine would do it */
|
||||
temp_sf = setup_subfile_streamfile(sf, subfile_offset,subfile_size, "ktsl2asbin");
|
||||
if (!temp_sf) goto fail;
|
||||
|
||||
vgmstream = init_vgmstream_ktsr_internal(temp_sf, true);
|
||||
close_streamfile(temp_sf);
|
||||
return vgmstream;
|
||||
fail:
|
||||
close_streamfile(temp_sf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static VGMSTREAM* init_vgmstream_ktsr_internal(STREAMFILE* sf, bool is_srsa) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* sf_b = NULL;
|
||||
ktsr_header ktsr = {0};
|
||||
@ -46,20 +88,22 @@ VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf) {
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00, sf, "KTSR"))
|
||||
goto fail;
|
||||
if (read_u32be(0x04, sf) != 0x777B481A) /* hash(?) id: 0x777B481A=as, 0x0294DDFC=st, 0xC638E69E=gc */
|
||||
goto fail;
|
||||
return NULL;
|
||||
if (read_u32be(0x04, sf) != 0x777B481A) /* hash id: 0x777B481A=as, 0x0294DDFC=st, 0xC638E69E=gc */
|
||||
return NULL;
|
||||
|
||||
/* .ktsl2asbin: common [Atelier Ryza (PC/Switch), Nioh (PC)]
|
||||
* .asbin: Warriors Orochi 4 (PC) */
|
||||
if (!check_extensions(sf, "ktsl2asbin,asbin"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
/* KTSR can be a memory file (ktsl2asbin), streams (ktsl2stbin) and global config (ktsl2gcbin)
|
||||
* This accepts .ktsl2asbin with internal data or external streams as subsongs.
|
||||
* Some info from KTSR.bt */
|
||||
* Hashes are meant to be read LE, but here are BE for easier comparison. Some info from KTSR.bt */
|
||||
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
ktsr.target_subsong = target_subsong;
|
||||
ktsr.is_srsa = is_srsa;
|
||||
|
||||
if (!parse_ktsr(&ktsr, sf))
|
||||
goto fail;
|
||||
@ -67,6 +111,9 @@ VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf) {
|
||||
/* open companion body */
|
||||
if (ktsr.is_external) {
|
||||
const char* companion_ext = check_extensions(sf, "asbin") ? "stbin" : "ktsl2stbin";
|
||||
if (ktsr.is_srsa)
|
||||
companion_ext = "srst";
|
||||
|
||||
sf_b = open_streamfile_by_ext(sf, companion_ext);
|
||||
if (!sf_b) {
|
||||
vgm_logi("KTSR: companion file '*.%s' not found\n", companion_ext);
|
||||
@ -253,6 +300,7 @@ static int parse_codec(ktsr_header* ktsr) {
|
||||
/* platform + format to codec, simplified until more codec combos are found */
|
||||
switch(ktsr->platform) {
|
||||
case 0x01: /* PC */
|
||||
case 0x05: /* PC/Steam [Fate/Samurai Remnant (PC)] */
|
||||
if (ktsr->is_external) {
|
||||
if (ktsr->format == 0x0005)
|
||||
ktsr->codec = KOVS; // Atelier Ryza (PC)
|
||||
@ -483,7 +531,7 @@ static int parse_ktsr(ktsr_header* ktsr, STREAMFILE* sf) {
|
||||
* 08: version?
|
||||
* 0a: unknown (usually 00, 02/03 seen in Vita)
|
||||
* 0b: platform (01=PC, 03=Vita, 04=Switch)
|
||||
* 0c: game id?
|
||||
* 0c: audio id? (seen in multiple files/games and used as Ogg stream IDs)
|
||||
* 10: null
|
||||
* 14: null
|
||||
* 18: file size
|
||||
@ -506,8 +554,8 @@ static int parse_ktsr(ktsr_header* ktsr, STREAMFILE* sf) {
|
||||
|
||||
/* parse chunk-like subfiles, usually N configs then N songs */
|
||||
switch(type) {
|
||||
case 0x6172DBA8: /* padding (empty) */
|
||||
case 0xBD888C36: /* config (floats, stream id, etc, may have extended name) */
|
||||
case 0x6172DBA8: /* ? (mostly empty) */
|
||||
case 0xBD888C36: /* cue? (floats, stream id, etc, may have extended name; can have sub-chunks)-appears N times */
|
||||
case 0xC9C48EC1: /* unknown (has some string inside like "boss") */
|
||||
case 0xA9D23BF1: /* "state container", some kind of config/floats, witgh names like 'State_bgm01'..N */
|
||||
case 0x836FBECA: /* unknown (~0x300, encrypted? table + data) */
|
||||
@ -566,6 +614,13 @@ static int parse_ktsr(ktsr_header* ktsr, STREAMFILE* sf) {
|
||||
parse_longname(ktsr, sf, stream_id);
|
||||
build_name(ktsr, sf);
|
||||
|
||||
/* skip TSRS header */
|
||||
if (ktsr->is_external && ktsr->is_srsa) {
|
||||
for (int i = 0; i < ktsr->channels; i++) {
|
||||
ktsr->stream_offsets[i] += 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
vgm_logi("KTSR: unknown variation (report)\n");
|
||||
|
@ -884,6 +884,7 @@ VGMSTREAM* init_vgmstream_diva(STREAMFILE* sf);
|
||||
VGMSTREAM* init_vgmstream_imuse(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf);
|
||||
VGMSTREAM* init_vgmstream_asrs(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_mups(STREAMFILE* sf);
|
||||
|
||||
|
@ -458,6 +458,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
||||
init_vgmstream_diva,
|
||||
init_vgmstream_imuse,
|
||||
init_vgmstream_ktsr,
|
||||
init_vgmstream_asrs,
|
||||
init_vgmstream_mups,
|
||||
init_vgmstream_kat,
|
||||
init_vgmstream_pcm_success,
|
||||
|
Loading…
Reference in New Issue
Block a user