Previous Page | Next Page

by Missingno_force at 1:11 PM EDT on September 10, 2018
Im gonna hijack this thread since its kinda related, but @Nisto, can you do a writeup on what you found out about how the MDX sequencer (or better yet, the whole sound system) works? Ive been fiddling with sequences for both MGS1 as well as ZOE1 (and to a lesser extent MGS2) and they are similar enough that you can parse them in almost the same way, but im at my wits end (and I havent gotten enough into disassembly yet to just work from there, especially since for the PS2 titles, the IOP is doing the heavy lifting and any modules that still have symbols in them dont really help me)
by Nisto at 2:56 PM EDT on September 13, 2018
@Missingno_force: First off, just a quick disclaimer: when ripping PSFs, you don't always need to figure out the sequence format or any of the lower-level sequencer routines (command handlers and such). With that said, I do have a basic grasp of how the sound system works overall, but it's not comprehensive by any means, and I cannot speak for other MDX-compatible games.

Also, I have recently updated my IDA database for MGS with function names based on debug symbols from the TGS build of ZoE. You might want to have a look at that.

So, it all starts with the function at 80082F18. It sets up the following sound buffers/pointers:

sng_data: Contains MDX data (entire MDX file).

wave_header: Contains up to three WVX headers (voice tables). A voice table is pretty self-descriptive: it defines parameters for the voices (samples) in the respective wave data. The wave from the "init" stage is always loaded in the first 2048 bytes; it contains the voice table for most of the instruments and sound effects used in the game. The remaining 2048 bytes are reserved for up to two voice tables, usually occupied by the WVX files for the current stage. In a WVX file, the first 32-bit word specifies where the voice table should be loaded (relative to the wave_header / voice_tbl buffer).

voice_tbl: Synonymous with wave_header.

CDLOAD_BUF: This is used to temporarily hold sound data read in from the CD-ROM (e.g. sample data which later gets transferred to SPU RAM).

I haven't looked into the other buffers much, but they're not relevant to sequenced music.

Next, you have the function at 80082A00, which configures the usual SPU parameters (reverb, volume, etc.), initializes sequencer variables, and sets up interrupts, so that the function which carries out sequence playback (80085218, from here on called IntSdMain) gets invoked at a regular interval. It's a little complicated to explain how the function (originally) actually gets invoked, since it involves understanding a bit about the Multi Task Scheduler (a proprietary engine for handling thread concurrency) and SPU IRQs (interrupt requests). But in my latest PSF rip, I bypass the use of both, which hopefully makes it easier to follow.

To control playback, the game uses "sound codes", which are passed around from place to place. I assume they usually originate from GCL scripts (I know virtually nothing about these, but I can't find many cross-references in the bare executable). They usually pass through the function at 800899B0 first, which stores the sound code in a circular buffer/queue, which can hold up to 16 codes (32 bits each) at a time. Here's some example codes:

01000002 play MDX song 2 (zero is not valid)
01FFFF01 pause music
01FFFF10 activate evasion mode (for ENCOUNTER)

Eventually, when invoked, IntSdMain pops the next sound code (song code) from the buffer and processes it. Once that's done, it goes on to check the sng_status variable (800BFB18). This variable indicates whether or not song (MDX) data is loaded, if it's ready to be played, etc. It needs to be updated to 2 prior to sending a Play code. This is normally done through the stage TOC parser, when an MDX ('m') entry is found, which prompts a call to both 80084C10 and 80084C58. When a Play code is sent and the sng_status is 2 (ready to be played), the function initializes subtrack info and bumps the sng_status to 3 (playing). Now that the sng_status is 3, IntSdMain goes through an additional loop which iterates through all the MDX subtracks (see 800856E0).

If you look closely, the loop only processes 13 subtracks. This is because the game reserves the first 13 SPU voices for music. The other 11 voices are for sound effects (8), streams (2), and SPU IRQs (1). Note that it keeps a global variable for the track currently being processed, and a pointer to a structure which holds all relevant information about it, such as the address of the next command, the current volume, panning, and much more. These variables are frequently referenced in lower-level functions (such as command handlers) and should give you lots of leads, I think. Also, there's a lot more to find in the IDA database (idb) after my latest update. Probably faster/easier to look at that, really.

The rest is a bit beyond me, sorry to say. There's a lot of subcalls and complex structures being passed around that I haven't quite figured out. But about half-way into the aforementioned loop, you'll find a call to 80086750, which subsequently calls 80086884. This function actually reads the next command from the current subtrack, so this would probably be good to look at as well. It uses an array to map the command number to a handler function, so it should be pretty easy to figure out what most commands are for, especially now that the functions are named thanks to debug symbols from Zone of the Enders. Note that the XREF to the array is to 8009FF1C because of some silly pointer arithmetic; you can find the actual table at 800A011C.

If there's something more specific you're wondering about, ask away.
by Missingno_force at 3:56 PM EDT on September 14, 2018
awesome post man, this is exactly what i had hoped for (and i didnt expect a full ready-to-print documentation, no worries). 80086884 sounds like a gold mine for what i was doing when i wrote my post (staring at data from mdx dumped into a csv to make sense of it while trying to change parameters by patching an iso of zoe and testing it via emu).
i assume the name of your idb is the mgs executable i want to grab to look around in (and that the functions you named here are all from there as well). if i come across something ill hit you up
by Nisto at 4:11 PM EDT on September 14, 2018
> i assume the name of your idb is the mgs executable i want to grab to look around in (and that the functions you named here are all from there as well). if i come across something ill hit you up

Correct. If you're only doing static disassembly, you won't actually need the executable though; you can open the IDB file by itself in IDA 6.8 or later.
by GirianSeed at 4:36 PM EDT on September 14, 2018
Whoa, great writeup. I remember noticing the different channels reserved for song/SE/stream playback a few years back when playing around with the game with a certain SPU plugin.

Only thing I could probably add right now is some of the original function names I noticed your IDB was missing. I could probably add more later but these are just off the top of my head.

GfxFormatHandlerK -> DG_LoadInitKmd
GfxFormatHandlerN -> DG_LoadInitNar
GfxFormatHandlerO -> DG_LoadInitOar
GfxFormatHandlerI -> DG_LoadInitImg

S and L are probably Sgt and Lit, respectively.

sub_80016DA0 -> GV_StrCode

This is the string hashing function, you'll see this getting called all over the place if you ever look into other areas of the program.

edited 4:37 PM EDT September 14, 2018
by radornkeldam at 5:10 PM EDT on September 21, 2018
Hey. Sorry to interrupt, as I seldomly come arround here.
I've been waiting for ages for someone to make a PSF set of this game, as I've always found the original soundtrack to be severely limited, missing all cutscene music.
I've just found the game has finally been ripped, which got me quite pumped, but it seems it only contains the tracks already present in the OST, for the most part.
Is there any plan to get the missing cutscene tracks eventually?
by GirianSeed at 8:44 PM EDT on September 21, 2018
All the cutscene audio is pre-mixed, sorry.
by radornkeldam at 9:54 PM EDT on September 21, 2018
Please, could you explain that?
What do you mean by pre-mixed here? Are they XA streams? It was a long time ago but I believe I tried looking at the ISO for XA and they weren't there...?
They are not sequenced tracks played by the game engine after all?
What makes them different from the regular tracks?

Do you mean perhaps, that the scenes have the animation, camera movement, etc.. and audio also, all mixed in a single script?

edited 10:02 PM EDT September 21, 2018
by GirianSeed at 2:47 PM EDT on September 26, 2018
All the sound effects, voices, and music are mixed together as a single VAG stream for each cutscene.
by Kirishima at 8:46 PM EDT on September 26, 2018
It's a limitation of the ps1. It can't stream more than one audio source at a time, so alot of times music,voices, and sfx are premixed into one file like GiriamSeed said, although there might be cases where that's not true. It's usually why you don't hear streamed music while a game is loading something.

Previous Page | Next Page
Go to Page 0 1 2 3 4 5

Search this thread

Show all threads

Reply to this thread:

User Name Tags:

bold: [b]bold[/b]
italics: [i]italics[/i]
emphasis: [em]emphasis[/em]
underline: [u]underline[/u]
small: [small]small[/small]
Link: [url=]Link[/url]


HCS Forum Index
Halley's Comet Software
forum source
Generated in 0.0033s;