Jump to content

Pokemon Mystery Dungeon 2 - Psy_commando's Tools and research notes


Recommended Posts

Also, I cleaned up and organized everything and put it on Codeplex : https://ppmd2utilslib.codeplex.com/

I'm don't know how much work I'll be able to put on that page, given I'm not entirely trusting any web-services like that fully.. I've heard waaay too many horror stories..

And the fact that they've initialized my repo at revision "35230" doesn't really reassure me..

Link to comment
Share on other sites

Nice work !

I was going to write a little something to attempt converting to midi. But, I was busy with the sprites xD

(Which I still have no ideas how to guess the resolution from those..)

Ironically though, yesterday I got some enlightenment on what a few messages codes meant, and on the delay between notes, and updated a little my notes, which were not very accurate ^^;

I'm under the impression that, the delay that can optionally be prefixed to events is probably dependent on the tempo. So that might be one of the issue you're having.

Also, if you want, we could probably split tasks, so we wouldn't all work on the same thing! Since you got smd well on its way, I could probably focus on the swd that contain the samples?

I made some nice finds on those recently !

Speaking of which, you wouldn't happen to know of a good library of re-usable code for decoding whatever format of ADPCM the NDS is using ? I tried writing my own algorithm, but, it only gives static.. I had some success exporting samples using Audacity's Dialogic/VOX ADPCM decoder to read the samples in PMD:EoS, but, I can't find code for any of that, and I'm pretty sure they didn't use Dialogic's specification for encoding those.. Probably something close, but not the same..

Yeah, I knew about it not guessing it just like that, but I didn't bother updating the notes until yesterday ironically ^^;

I noticed that the ( 0100 ) bit in the high nybble was always 1 when there were two parameters. Really sorry about that :/

At one point I was pretty much convinced nobody besides me would use those notes xD

What do you mean though ?

0xE3 is for the channel's volume. While 0xE0 seems to have some echo/reverb-like effect on the notes.

I'm just asking, just to make sure I'm not missing something.

And would you mind if I'd update my notes with your findings, and your own notes ? I'd mention that you contributed of course !

(…)

Also, I don't recommend using a disassembler to figure out this stuff, well at least with PMD2. It would have been way more trouble than it would be worth it xD

What I did was simply look at the midi format, and think, "what do I need to play music in a sequencer?", basically.. I just looked at the features that midi offered, and looked for values that would fall within the same range in the smd file. And since most sequencers are event based, it was easy to guess it would be the same thing here ! Especially since they probably wrote the song in midi first before transferring it to the game. Which meant they'd logically want something that supports all common midi features!

And, if you want to guess what all events do, I strongly suggest taking an existing song in the game, removing all tracks but track 0 and another one. And just replace the content of the track that isn't track 0 (unless you really want to) manually with what you want to try, set the file length in the header, and set the track length in the track chunk, properly set the end padding of the track.

And there you go, your own poor man's sequencer ! xD

I'd have tried everything out myself, but I wanted to focus on sprites, and other file format first. But its probably the best way to do, even though its a little time consuming.

I'll also say that, plugging in my midi keyboard and just looking at the events and trying to play what notes the track seemed to contain along with the actual music revealed a lot !

And I transcribed a few of them by ear, so it made things easier xD

https://dl.dropboxusercontent.com/u/13343993/MyMidis/idwtsg_49.ogg

https://dl.dropboxusercontent.com/u/13343993/MyMidis/otbad_6.mp3

https://dl.dropboxusercontent.com/u/13343993/MyMidis/Main%20Menu.ogg

Those are probably not 100% accurate, but if it can help, I could probably share the midis for those !

Right now, I'm not very concerned with the .SWDs. However, a tool that can make them into .SF2s would be useful for checking progress on SMD research.

I can't suggest any particular libraries for NDS formats, as I don't have experience with them myself. I'd ask my friend, who has marginally more experience, but they're offline right now.

Right now, from my perspective (which is only concerned with reading), 0xE0 is the channel volume. It is not set in stone, and just represents a guess based on how it is never nonzero in the files I've tested, like BGM0002 (Title)

Track 3: tID=3, oID=3
Events: (93 count)
0       0xE3 0x71               UNK_E3: param1=113 // Volume command? Also not decimal-round
1       0xA9 0x79               UNK_A9: param1=121
2       0xAA 0x41               UNK_AA: param1=65
3       0xE0 0x50               Volume: 80  // 0xE0 command. Note the decimal-round '80' value
4       0xE8 0x40               UNK_E8: param1=64
5       0xE3 0x71               UNK_E3: param1=113 // Repeated volume command? Might contribute proof
6       0xAC 0x06               Sample: 6
7       0xD7 0x00 0x00          UNK_D7: param1=0, param2=0
8       0x99                    -- LOOP --

If you actually hacking the sequences experimentially can confirm that it is an echo, then I have to figure out how to implement that in midiFile.cpp. I'll do some tests with it as volume, I guess.

By all means, you can update your notes with my findings that you agree with. It is what I did with yours, after all.

(post …)

Game sequencer routines in general are very messy. Only reason I could do research on GB games were because of the helpful .gbs format, which isolates that code from the rest of the code.

I don't believe the songs were written in MIDI, per say, first. Definitly they were written in something like a tracker, of some sort, but not necessairily with MIDI. Then again, there is that 48 ticks per beat, which is pretty common with MIDI, so who knows.

Regarding the timing, I'm working under the assumption that the there are 48 ticks per beat. Each DELTA_TIME event (previously prefixed-time parameters) waits for a specific number of ticks, as with the WAIT_1BYTE and WAIT_2BYTE commands. This makes BGM0002 match up extremely nicely with the actual song (loaded in Audacity with a click track acting as a metronome).

Yay, I'm helping!

I think that would be stored in one of the GROUND\vXXpXXaXX.wan files. psy_commando's sprite tool can extract some tiles from them, and will probably support them much better in the near future.

I was actually talking about the source you just posted. I compiled it and besides line 41 of smdRead.cpp, which doesn't seem to be used anywhere, some tracks like Beach Cave and Drenched Bluff (bgm0021 and bgm0022) both had some sort of int exception (I didn't look too far into it, just let the program continue running, which resulted in the position on the track it failed on holding the same note until the end of the song, while the other tracks play.)

Out of curiosity, what compiler do you use? I'm not that familiar with C++ for the time being, and haven't found how to compile using the makefiles you included, I just put the cpp files into Visual Studio to let it compile them.

Regarding the backgrounds, I decided to just load up the game in my emu, with a 100% save from GameFAQs (too lazy to look for my DS Lite + ARDSi to dump my actual savegame), and stitch the tiles together with GIMP.

Regarding line 41, I just realised that I typoed. Thanks for pointing that out. It is supposed to be 'fname', not 'name'.

If you are talking about the "throw" lines:

EFAULT: Thrown if the read pointer for a track goes past the end of the track

ENOTSUP: Thrown if an event opcode which isn't recorded in the table at the end of my notes is encountered. The main reason is because it needs someone to tell it how many parameter bytes there are for the instruction, since I don't know a good way to program a guess.

Both of those stop reading for the track, since it doesn't know how to proceed in the latter case, and it did something wrong in the former.

I pretty much exclusively use gcc for compiling. I have a Debian VM on my laptop (host OS is Win7) which I do my programming inside of. In Linux, build instructions consist of './configure', followed by 'make'.

Link to comment
Share on other sites

Right now, I'm not very concerned with the .SWDs. However, a tool that can make them into .SF2s would be useful for checking progress on SMD research.

I can't suggest any particular libraries for NDS formats, as I don't have experience with them myself. I'd ask my friend, who has marginally more experience, but they're offline right now.

Alright. That's pretty much what I had in mind actually. Do a little like that "GBA Music Ripper" program someone made that also export the samples and all.

And I'd really appreciate it if you'd ask him ! :)

Right now, from my perspective (which is only concerned with reading), 0xE0 is the channel volume. It is not set in stone, and just represents a guess based on how it is never nonzero in the files I've tested, like BGM0002 (Title)

Track 3: tID=3, oID=3
Events: (93 count)
0       0xE3 0x71               UNK_E3: param1=113 // Volume command? Also not decimal-round
1       0xA9 0x79               UNK_A9: param1=121
2       0xAA 0x41               UNK_AA: param1=65
3       0xE0 0x50               Volume: 80  // 0xE0 command. Note the decimal-round '80' value
4       0xE8 0x40               UNK_E8: param1=64
5       0xE3 0x71               UNK_E3: param1=113 // Repeated volume command? Might contribute proof
6       0xAC 0x06               Sample: 6
7       0xD7 0x00 0x00          UNK_D7: param1=0, param2=0
8       0x99                    -- LOOP --

If you actually hacking the sequences experimentially can confirm that it is an echo, then I have to figure out how to implement that in midiFile.cpp. I'll do some tests with it as volume, I guess.

After re-testing with a fresh track, 0xE0 seems to have an impact on the volume, but it sounds as if it was an Attack / Release parameter..

You should try it yourself with several tracks using different samples to see what I mean.

I got those values :

0x32 ( 0011 0010 ) //Slow release cello string

0x3C ( 0011 1100 ) //Slow release vibraphone like

0x64 ( 0110 0100 )

So I guess its possible that like you've said, its always divisible by 10 perfectly, which is very odd IMO...

At first I thought the high nybble and low nybble each contained a value for a different purpose, given a value of 0xFF produces no sounds at all, while 0xF0 does for example..

I've also tried a couple of values for 0xE0 on a drum track from bgm0034 and here are the results (0xE3 is at the default value 0x73):

- 0x01 (Completely silent, even from looking at the waveform)

- 0x1F

- 0x50 (default)

- 0x8F

- 0xF0

And as for 0xE3 being the channel volume, here is the same track with 2 values of 0xE3 (0xE0 is at the default value 0x50 !):

- 0x1F

- 0xFF

It odd because it seems that unlike 0xE0, when its set at 0x1F, the sound isn't mostly at around the same loudness, but its as if it would "fade-in" and "fade-out" just like the attack / release parameters usually do..

But then again, its impossible to entirely bypass the effect of either 0xE3 or 0xE0, so what we're hearing is probably both combined.. I'll run more tests later, changing both values this time..

I also stumbled on this track from bgm0034, the music for Northern Desert, which happens to make everything even more messed up!

There is this cello part that plays and its loudness slowly decays.

When looking at the events, we see that after and before each play note events, there are several 0xE3 events in a row, and the value of their parameter increases and decreases in a linear or maybe even sinusoidal fashion :

bgm0034_Track11_events.png

Maybe it simulates some kind of vibrato like effect ?

Its worth nothing that, here is only a single 0xE0 event at the beginning of this track.

By all means, you can update your notes with my findings that you agree with. It is what I did with yours, after all.

Thanks !

I'm just asking anyways, out of politeness. Some people might find it rude, so I'm not taking chances xD

I don't believe the songs were written in MIDI, per say, first. Definitly they were written in something like a tracker, of some sort, but not necessairily with MIDI. Then again, there is that 48 ticks per beat, which is pretty common with MIDI, so who knows.

Well, considering MIDI is everywhere, in the keyboards musician uses, in the DAW they use, and in music notation software, and also how this console is post 2000s, its highly likely the data was either stored as a MIDI clone, or as a MIDI file itself before being converted.

Its just way too practical not to go for it.

But I guess some devs might still use trackers.

I doubt its really all that common on the NDS though, given how they need to train their staff to use new software everytime. While with MIDI they can use anything they're accustomed with..

It just makes sense to me, that's all. I don't claim its necessarily the case either though. xD

Regarding the timing, I'm working under the assumption that the there are 48 ticks per beat. Each DELTA_TIME event (previously prefixed-time parameters) waits for a specific number of ticks, as with the WAIT_1BYTE and WAIT_2BYTE commands. This makes BGM0002 match up extremely nicely with the actual song (loaded in Audacity with a click track acting as a metronome).

That's actually a good guess! I wasn't sure of the exact frequency of the ticks or how many there were per beat, but that could really make sense!

Speaking of which, there are 2 values that I thought could be linked to timing in the songs. They're at offset 0xE and 0xF in each smd, and their exact value is repeated in every single tracks preceded with an event code 0xAA and 0xA9 respectively.. I'd guess it might be the duration of the track, but it doesn't make much sense, given the duration could be obtained from the longest track anyways :/

Those two values have been really puzzling..

I don't know if you've found out what they do yet, since I haven't had the time to sit down and look at your notes in-depth yet. So sorry if you've already documented those.

Regarding the backgrounds, I decided to just load up the game in my emu, with a 100% save from GameFAQs (too lazy to look for my DS Lite + ARDSi to dump my actual savegame), and stitch the tiles together with GIMP.

Well, I guess that works too! xD

I pretty much exclusively use gcc for compiling. I have a Debian VM on my laptop (host OS is Win7) which I do my programming inside of. In Linux, build instructions consist of './configure', followed by 'make'.

That reminds me I should really switch completely to GCC one of these days..

MSVC2012 has an absolutely horrible support for C++ 11.. There are actually some serious and breaking issues in their implementation of the STL.. Like std::packaged_tasks can't take functions with a void return type for some reasons.. And there are even worst than that..

It doesn't even seems like most of those were fixed in VS2013..

And they don't make any patches for those things..

Link to comment
Share on other sites

Just as a heads-up, you probably should assume that the param for 0xE0 and 0xE3 both range 0..127. But...there are two MIDI params which affect the volume. You ofc have controller 7 MAIN VOLUME, but you also have controller 11 EXPRESSION. I'd bet that 0xE0 might be it, while 0xE3 is volume.

Generally, with NDS, a tracker is used, which works with SSEQ, which is packaged with a number of other files in the .sdat, which is what most other games use. PMD doesn't, and that's the main issue.

Gonna quickly test this before officially updating the toolset

EDIT: Seems legit, got that implemented.

Toolset has been updated, same link as before:

* Now supports .map files, which remap instruments. A line is matched with the format "0x%02X\t%i"; the map I used for http://cdusto.selfip.com/bgm0003.mid (sample) is:

0x1A    38
0x07    8
0x08    8
0x15    26
0x01    98
0x0E    6
0x4B    45
0x0F    15
0x02    75
0x61    0

* Timing for 0x8D..0x8F has been reduced by one tick; this fixes the desync issues

* Documentation updated for SET_XPRESS command

* Timing added to smdRead.cpp and smdDump:

debian-VM:/~/projects/pmd2mid
chris:$ ./smdDump bgm0002.smd | head -n 20
Name: B_SYS_MENU.SMD
Track count: 12
Track 0: tID=0, oID=1
Events: (5 count)
0            1:1.00     0xE3 0x71               Volume: 113
1            1:1.00     0xA4 0x68               Tempo: 104
2            1:1.00     0x99                    -- LOOP --
3            1:1.00     0x93 0x00 0x09          Wait: 0x0900 ( 2304/192 )
4           13:1.00     0x98                    -- END --
(end events for tID=0, LOOP=12:0.0)

Track 1: tID=1, oID=1
Events: (131 count)
0            1:1.00     0xE3 0x71               Volume: 113
1            1:1.00     0xA9 0x79               UNK_A9: param1=121
2            1:1.00     0xAA 0x41               UNK_AA: param1=65
3            1:1.00     0xE0 0x5A               Expression: 90
4            1:1.00     0xE8 0x40               UNK_E8: param1=64
5            1:1.00     0xE3 0x71               Volume: 113
6            1:1.00     0xAC 0x4B               Sample: 75

* Dumped MIDI files have META marker events indicating UNK_xx instructions; this is in addition to the old "LOOP" markers I had in there

Known bugs:

* I forgot to update the NOTES file, so ignore that it says that .map support isn't implemented

I now believe they started with, and converted from, MIDI:

* SET_VOLUME and SET_XPRESS

* 48 ticks per clock (pretty common)

* Container is NOT a .sdat

* Drum set matches MIDI ordering and notes (oh, I got that working)

** Drum set tends to be on output 15 (MIDI channel 16) (the MIDI dumper will automatically swap Ch10 with Ch16, so drums are correct for GM)

Link to comment
Share on other sites

Just as a heads-up, you probably should assume that the param for 0xE0 and 0xE3 both range 0..127. But...there are two MIDI params which affect the volume. You ofc have controller 7 MAIN VOLUME, but you also have controller 11 EXPRESSION. I'd bet that 0xE0 might be it, while 0xE3 is volume.

Generally, with NDS, a tracker is used, which works with SSEQ, which is packaged with a number of other files in the .sdat, which is what most other games use. PMD doesn't, and that's the main issue.

Gonna quickly test this before officially updating the toolset

EDIT: Seems legit, got that implemented.

I rarely saw anything else that was limited between 0 and 127.. I think they hate signed integers.. xD

For example, I just re-confirmed that 0xE8 was track panning, and it ranges from 0x0 to 0x80, with 0x40 being the middle. They're not doing things conventionally it seems..

And its not just SSEQ that's different, PMD uses a entirely different development toolset apparently. Most of its file formats were found in other games as well. But strangely very little tools have surfaced to deal with those..

I also found some more details on Expression and Volume in the MIDI guidelines on page 10 :

Composer/Application Recommendations:

Volume should be used to set the overall volume of the Channel prior to music data playback as well as for mixdown fader-style movements, while Expression should be used during music data playback to attenuate the programmed MIDI volume, thus creating diminuendos and crescendos.

This enables a listener, after the fact, to adjust the relative mix of instruments (using MIDI volume) without destroying the dynamic expression of that instrument.

So maybe its actually the opposite ? 0xE0 is the volume, and 0xE3 is the expression parameter ?

Or maybe they didn't read this when they made the music xD

Also, you didn't say anything about the fade-in and fade-out effect that I mentioned, that appeared on the drum when you lower 0xE3 to 0x1F and keep 0xE0 at 0x50.

That is a significant difference from the other recording of 0xE3 at 0x73 and 0xE0 at 1F..

And its an effect that is used a lot in music, if we neglect subtleties like that, it will make a significant difference in how the tracks come out.

Maybe finding out what's going on here could help prevent future headaches ?

Toolset has been updated, same link as before:

* Now supports .map files, which remap instruments. A line is matched with the format "0x%02X\t%i"; the map I used for http://cdusto.selfip.com/bgm0003.mid (sample) is:

0x1A    38
0x07    8
0x08    8
0x15    26
0x01    98
0x0E    6
0x4B    45
0x0F    15
0x02    75
0x61    0

You probably wouldn't have to resort to this if we could map the link between the individual SWDs for each SMDs and the bgm.swd file.

The actual "static" instrument samples are stored inside "bgm.swd", and those have probably a static ID value. But for the IDs used in each track of an smd file, the "sample ids" seems to vary from one song to another.

The ID used inside the smd files are referred in the accompanying swd file, and each swd files that accompanies a smd seems to actually define "instruments" sometimes made up of references to several samples.

If you look at the structure, it defines a lot of information seemingly on how to playback the samples most likely from the bgm.swd file, and it maps them to an ID which can be found when looking at the swd file and comparing with the IDs used in the smd file.

For examples, I've seen the same string sample mapped to a different instrument ID several times.

Not to mention that some samples, like square waves and noise seems to be generated at runtime based on the content of swd files.

Of course, I can't say this and be 100% sure of it, given I made many epic fails in my notes in the past.. But given I heard all the instrument samples in the bgm.swd, its a pretty safe bet that its possible to guess instruments that way.

Link to comment
Share on other sites

My friend, who is pretty familiar with MIDI, confirms 0xE0 SET_XPRESS and 0xE3 SET_VOLUME, and that seems to follow what you quoted. Every track, I believe, starts with SET_VOLUME 107 (this seems to hold for _every_ track, including tempo), and e.g. track 3 (MIDI 3) for the Medley uses SET_XPRESS as if it is for MIDI expression.

I said to do the limiting because MIDI restricts those values to 0..127, and if the format is indeed based around MIDI, greater values could have unexpected results. I have not found anything exceed the range, as well.

I haven't done much analyses into the drums, aside from aligning them properly to MIDI. I'm not sure, but the drums might be handled differently from chromatic notes. I know they are, to an extent, in MIDI. I'm working on getting the bulk of everything figured out.

8:54 PM - TruePikachu: I know that Rescue Team Medley uses SET_XPRESS in conjunction with notes that are playing at the moment, for a fading effect thing

8:55 PM - <<PRIVATE>>: Really?

8:55 PM - TruePikachu: :

Track 3: tID=3, oID=3
Events: (1325 count)
0            1:1.00     0xE3 0x6C               Volume: 108
1            1:1.00     0xA9 0x78               UNK_A9: param1=120
2            1:1.00     0xAA 0x6C               UNK_AA: param1=108
3            1:1.00     0xAC 0x1F               Sample: 31
4            1:1.00     0xE0 0x5A               Expression: 90
5            1:1.00     0xE3 0x6C               Volume: 108
6            1:1.00     0xE8 0x40               UNK_E8: param1=64
7            1:1.00     0xE0 0x0A               Expression: 10
8            1:1.00     0xE0 0x06               Expression: 6
9            1:1.00     0xA0 0x04               Octave: 4 (real 3)
10           1:1.00     0x6E 0x61 0xC0          Note: Velocity=110, param1=97 (flag=6 (Oct== LEN), key=C#), param2=192/192 length
11           1:1.00     0x6E 0x3A               Note: Velocity=110, param1=58 (flag=3 (Oct++), key=A#)
12           1:1.00     0x8C                    Delta: 0xC( 1/32 )
13           1:1.06     0xE0 0x07               Expression: 7
14           1:1.06     0x8C                    Delta: 0xC( 1/32 )
15           1:1.12     0xE0 0x09               Expression: 9
16           1:1.12     0x8C                    Delta: 0xC( 1/32 )
17           1:1.18     0xE0 0x0C               Expression: 12
18           1:1.18     0x8C                    Delta: 0xC( 1/32 )
19           1:1.24     0xE0 0x10               Expression: 16
20           1:1.24     0x8C                    Delta: 0xC( 1/32 )
21           1:1.30     0xE0 0x14               Expression: 20
22           1:1.30     0x8C                    Delta: 0xC( 1/32 )
23           1:1.36     0xE0 0x19               Expression: 25
24           1:1.36     0x8C                    Delta: 0xC( 1/32 )
25           1:1.42     0xE0 0x1D               Expression: 29
26           1:1.42     0x8C                    Delta: 0xC( 1/32 )
27           1:2.00     0xE0 0x22               Expression: 34
28           1:2.00     0x8C                    Delta: 0xC( 1/32 )

etc.

8:55 PM - <<PRIVATE>>: That's pretty rare to find; it's actually the correct way most of the time.

EDIT: Work on the SWD prgi chunk; just after the header, there is a list of word offsets (like wavi) which are indexed by instrument ID. That is what would link sample numbers in the SMDs to actual instruments, if anything. First field is a uint16_t matching sample number

Final update for the night:

* Added WAIT_AGAIN, WAIT_ADD, and SET_PAN commands

* Made sure to extend the MIDI track so a NOTEOFF isn't put after the end of the track. This seems to have fixed all file load problems, from my testing.

* Added another error condition to smdRead.cpp, which will only trigger when trying to dump enviornmentals

* Added another program, checkSmds, which takes a list of SMD files as parameters, and sees if smdRead can read all of them without errors. Right now, only enviornmentals in BGM fail - all music tracks parse with no "100% unknown" commands (read: commands we don't know how many arguments there are for).

Edited by TruePikachu
Link to comment
Share on other sites

No offense, but it kind of makes it hard to discuss when your replies are half changelogs.. :/

I think I see it now how they could be signed integer.. Its funny how much stuff you can miss when you're stuck thinking on your own about problems.. ^^;

And, about the medley.. Its quite possible they imported those from the older games, and thus that they'd use the commands differently.. While Northern Desert was written for EoS/D/T.. I'd rely more on examples straight from this game, rather than based on stuff that might just come from an older system/toolset..

I mean, In northern desert, 0xE3 is expression. While in your example from the medley, its 0xE0..

There's a pretty big contradiction here.. Most likely because the GBA only handled channel volume, and not expression..

And about the drums, from looking at things quickly, they seems to possibly be assigned to notes within one of the SWD files (either the accompanying SWD, or the bgm.swd). To simulate GM MIDI drums probably..

I think the way it works is transparent to the SMD and handled in the SWD. Like, there are no different commands for the end-user to use drums, and its the drums that are twisted around to work like a regular instrument..

Link to comment
Share on other sites

Just a quick update before I head to college, got the 0xD7 SET_TUNE command documented and implemented, and started research on the UNK_A9 and UNK_AA commands (the ones which have values in the header), or rather I researched those values in the header.

With a quick Perl script, I concluded that they do not relate to the playback directly, but might be priority levels. This is supported by the fact that, it appears, no two files have the same values for both the A9 and AA fields (+0x0F and +0x0E) in the header.

I think that the A9/0x0F field is an enum which identifies the category of piece (things like enviornmentals versus plot music), while the AA/0x0E field gives a priority or identifier or something within the specific category.

It is interesting to note that all the pieces except bgm0077 "B_EVENT_TIMEWHE" have a "large" (0x70<n<0x80) A9/0x0F field, while bgm0077 has 0x01 there.

File          IName                 UNK_A9    UNK_AA
bgm0000.smd   B_ENV_BEACH_01.      0x78=120  0x64=100
bgm0001.smd   B_SYS_P3_OPENIN      0x7F=127  0x00=  0
bgm0002.smd   B_SYS_MENU.SMD ÿ     0x79=121  0x41= 65
bgm0003.smd   B_SYS_TRAINING.      0x79=121  0x42= 66
bgm0004.smd   B_SYS_MINIGAME.      0x79=121  0x43= 67
bgm0005.smd   B_SYS_EVENTCLEA      0x79=121  0x44= 68
bgm0006.smd   B_SYS_SHINDAN_0      0x79=121  0x45= 69
bgm0007.smd   B_MAP_GUILD_01.      0x78=120  0x6D=109
bgm0008.smd   B_MAP_GUILD_02.      0x78=120  0x68=104
bgm0009.smd   B_MAP_TOWN_01.S      0x78=120  0x6B=107
bgm0010.smd   B_MAP_HOME_01.S      0x79=121  0x3F= 63
bgm0011.smd   B_SYS_MONSTERHO      0x79=121  0x32= 50
bgm0012.smd   B_SYS_SHOP.SMD ÿ     0x79=121  0x33= 51
bgm0013.smd   B_SYS_STEEL.SMD      0x79=121  0x34= 52
bgm0014.smd   B_EVENT_BOSSFLO      0x79=121  0x35= 53
bgm0015.smd   B_EVENT_BOSS_01      0x79=121  0x36= 54
bgm0016.smd   B_EVENT_BOSS_02      0x78=120  0x00=  0
bgm0017.smd   B_EVENT_BOSS_03      0x79=121  0x38= 56
bgm0018.smd   B_EVENT_BOSS_04      0x79=121  0x39= 57
bgm0019.smd   B_ME_GAMEOVER.S      0x7A=122  0x0B= 11
bgm0020.smd   B_ME_GAMECLEAR.      0x7A=122  0x0A= 10
bgm0021.smd   B_DUN_KAIGANNOD      0x79=121  0x01=  1
bgm0022.smd   B_DUN_SHIMETTAI      0x79=121  0x02=  2
bgm0023.smd   B_DUN_TOGETOGEY      0x79=121  0x03=  3
bgm0024.smd   B_DUN_TAKITSUBO      0x79=121  0x04=  4
bgm0025.smd   B_DUN_RINGONOMO      0x79=121  0x05=  5
bgm0026.smd   B_DUN_ENGANNOIW      0x79=121  0x06=  6
bgm0027.smd   B_DUN_YOKOANA_0      0x79=121  0x07=  7
bgm0028.smd   B_DUN_TSUNOYAMA      0x79=121  0x08=  8
bgm0029.smd   B_DUN_NOUMU_01.      0x79=121  0x0A= 10
bgm0030.smd   B_DUN_NESSUI_01      0x79=121  0x0C= 12
bgm0031.smd   B_DUN_NESSUI_02      0x79=121  0x0D= 13
bgm0032.smd   B_DUN_EREKIHEIG      0x79=121  0x0E= 14
bgm0033.smd   B_DUN_EREKIHEIG      0x79=121  0x0F= 15
bgm0034.smd   B_DUN_NISHINOSA      0x79=121  0x10= 16
bgm0035.smd   B_DUN_RYUUSA_01      0x79=121  0x11= 17
bgm0036.smd   B_DUN_RYUUSA_02      0x79=121  0x12= 18
bgm0037.smd   B_DUN_SUISYOU_0      0x79=121  0x13= 19
bgm0038.smd   B_DUN_DAISUISYO      0x79=121  0x14= 20
bgm0039.smd   B_DUN_KUUKAN_01      0x79=121  0x15= 21
bgm0040.smd   B_DUN_KURAYAMI_      0x79=121  0x16= 22
bgm0041.smd   B_DUN_FUUINNOIW      0x79=121  0x17= 23
bgm0042.smd   B_DUN_FUUINNOIW      0x79=121  0x18= 24
bgm0043.smd   B_DUN_KURONOMOR      0x79=121  0x19= 25
bgm0044.smd   B_DUN_MORINOTAK      0x79=121  0x1A= 26
bgm0045.smd   B_DUN_KIZAKINOM      0x79=121  0x1B= 27
bgm0046.smd   B_DUN_ISONODOUK      0x79=121  0x1C= 28
bgm0047.smd   B_DUN_ISONODOUK      0x79=121  0x1D= 29
bgm0048.smd   B_DUN_MABOROSHI      0x79=121  0x1E= 30
bgm0049.smd   B_DUN_MABOROSHI      0x79=121  0x1F= 31
bgm0050.smd   B_DUN_JIGENNOTO      0x78=120  0x6F=111
bgm0051.smd   B_DUN_JIGENNOTO      0x78=120  0x73=115
bgm0052.smd   B_DUN_SHINPI_01      0x79=121  0x22= 34
bgm0053.smd   B_DUN_HASSAM_01      0x78=120  0x6C=108
bgm0054.smd   B_DUN_TOZASARET      0x79=121  0x25= 37
bgm0055.smd   B_DUN_KISEKINOU      0x79=121  0x26= 38
bgm0056.smd   B_DUN_BANNIN_01      0x79=121  0x23= 35
bgm0057.smd   B_DUN_KAKUSARET      0x79=121  0x24= 36
bgm0058.smd   B_DUN_SYUGYOUYA      0x79=121  0x2B= 43
File          IName                 UNK_A9    UNK_AA
bgm0059.smd   B_DUN_AKUMUNONA      0x79=121  0x2C= 44
bgm0060.smd   B_DUN_SORANOSAK      0x79=121  0x2D= 45
bgm0061.smd   B_DUN_SORANOSAK      0x79=121  0x2E= 46
bgm0062.smd   B_DUN_YAMINOKAK      0x79=121  0x2F= 47
bgm0063.smd   B_DUN_YAMINOKAK      0x79=121  0x30= 48
bgm0064.smd   B_SYS_TITLE_02.      0x79=121  0x40= 64
bgm0065.smd   B_ME_MINIGAME_0      0x7A=122  0x01=  1
bgm0066.smd   B_ME_MINIGAME_0      0x7A=122  0x02=  2
bgm0067.smd   B_ME_MINIGAME_0      0x7A=122  0x03=  3
bgm0068.smd   B_ME_MINIGAME_0      0x7A=122  0x04=  4
bgm0069.smd   B_EVENT_MEETING      0x78=120  0x6F=111
bgm0070.smd   B_EVENT_CALMLY_      0x79=121  0x46= 70
bgm0071.smd   B_EVENT_CALMLY_      0x79=121  0x47= 71
bgm0072.smd   B_EVENT_CALMLY_      0x79=121  0x48= 72
bgm0073.smd   B_EVENT_COMICAL      0x78=120  0x6B=107
bgm0074.smd   B_EVENT_FEAR_01      0x79=121  0x4A= 74
bgm0075.smd   B_EVENT_FEAR_02      0x79=121  0x4B= 75
bgm0076.smd   B_EVENT_TENSION      0x79=121  0x4C= 76
bgm0077.smd   B_EVENT_TIMEWHE      0x01=  1  0x00=  0
bgm0078.smd   B_EVENT_TIMEWHE      0x79=121  0x4E= 78
bgm0079.smd   B_EVENT_JIKUU_0      0x79=121  0x51= 81
bgm0080.smd   B_EVENT_ROUGOKU      0x78=120  0x6A=106
bgm0081.smd   B_EVENT_ANKOKU_      0x78=120  0x69=105
bgm0082.smd   B_EVENT_SEPARAT      0x79=121  0x6F=111
bgm0083.smd   B_EVENT_SEPARAT      0x79=121  0x70=112
bgm0084.smd   B_EVENT_PEACEFU      0x79=121  0x75=117
bgm0085.smd   B_EVENT_SEPARAT      0x78=120  0x72=114
bgm0086.smd   B_EVENT_SEPARAT      0x78=120  0x74=116
bgm0087.smd   B_EVENT_SEPARAT      0x79=121  0x7E=126
bgm0088.smd   B_EVENT_SEPARAT      0x78=120  0x6E=110
bgm0089.smd   B_EVENT_STAFFRO      0x78=120  0x75=117
bgm0090.smd   B_EVENT_STAFFRO      0x78=120  0x71=113
bgm0091.smd   B_EVENT_EPIROGU      0x78=120  0x76=118
bgm0092.smd   B_EVENT_TITLECA      0x79=121  0x59= 89
bgm0093.smd   B_EVENT_TITLECA      0x79=121  0x59= 89
bgm0094.smd   B_DUN_P3_P1_CHI      0x7E=126  0x5E= 94
bgm0095.smd   B_DUN_P3_P1_GEN      0x7E=126  0x5F= 95
bgm0096.smd   B_DUN_P3_P1_MYS      0x7E=126  0x60= 96
bgm0097.smd   B_DUN_P3_P1_GEN      0x7E=126  0x61= 97
bgm0098.smd   B_DUN_P3_P1_CHI      0x7E=126  0x62= 98
bgm0099.smd   B_DUN_P3_P1_CHI      0x7E=126  0x63= 99
bgm0100.smd   B_ENV_BEACH_01.      0x78=120  0x64=100
bgm0101.smd   B_ENV_STORM_01.      0x78=120  0x65=101
bgm0102.smd   B_ENV_STORM_02.      0x78=120  0x66=102
bgm0103.smd   B_ENV_QUAKE_01.      0x78=120  0x67=103
bgm0104.smd   B_ENV_QUAKE_02.      0x78=120  0x68=104
bgm0105.smd   B_ENV_QUAKE_03.      0x78=120  0x69=105
bgm0106.smd   B_ENV_MAGMA_01.      0x78=120  0x6A=106
bgm0107.smd   B_ENV_LASTBOSS_      0x78=120  0x66=102
bgm0108.smd   B_ENV_LASTBOSS_      0x78=120  0x67=103
bgm0110.smd   B_SE_MAIN26_LIG      0x7F=127  0x01=  1
bgm0111.smd   B_SE_MAIN26_LIG      0x7F=127  0x02=  2
bgm0112.smd   B_EVENT_MIKARUG      0x78=120  0x70=112
bgm0113.smd   B_SE_MAIN19_HAD      0x78=120  0x71=113
bgm0114.smd   B_SE_MAIN19_ELE      0x78=120  0x72=114
bgm0115.smd   B_EVENT_TAKIBI.      0x78=120  0x73=115
bgm0116.smd   B_EVENT_TAKIGI.      0x78=120  0x74=116
bgm0117.smd   B_SE_MAIN23_KAK      0x78=120  0x75=117
bgm0118.smd   B_SE_MAIN25_ISH      0x78=120  0x76=118
File          IName                 UNK_A9    UNK_AA
bgm0119.smd   B_SE_MAIN25_ISH      0x7F=127  0x0A= 10
bgm0120.smd   B_EVENT_JIKUU_0      0x7F=127  0x0B= 11
bgm0121.smd   B_EVENT_SEPARAT      0x78=120  0x77=119
bgm0122.smd   B_EVENT_SEPARAT      0x78=120  0x78=120
bgm0123.smd   B_EVENT_BOSS_05      0x79=121  0x7D=125
bgm0124.smd   B_DUN_HASSAM_01      0x78=120  0x64=100
bgm0125.smd   B_ENV_WATERFALL      0x7B=123  0x02=  2
bgm0126.smd   B_ENV_SYOKUJI_0      0x7B=123  0x01=  1
bgm0127.smd   B_ENV_DRONE_01.      0x78=120  0x7F=127
bgm0128.smd   B_SE_MAIN05_DAK      0x78=120  0x80=128
bgm0129.smd   B_MAP_ISLAND.SM      0x7C=124  0x32= 50
bgm0130.smd   B_EVENT_TITLECA      0x79=121  0x59= 89
bgm0131.smd   B_EVENT_CALMLY_      0x78=120  0x7E=126
bgm0132.smd   B_EVENT_FEAR_03      0x7B=123  0x05=  5
bgm0133.smd   B_EVENT_FEAR_04      0x78=120  0x7F=127
bgm0134.smd   B_EVENT_TENSION      0x7B=123  0x04=  4
bgm0135.smd   B_EVENT_P3_CALM      0x7F=127  0x3C= 60
bgm0136.smd   B_EVENT_P3_IMAG      0x7F=127  0x04=  4
bgm0137.smd   B_EVENT_P3_MYST      0x7F=127  0x03=  3
bgm0138.smd   B_MAP_P3_GUILD_      0x7F=127  0x02=  2
bgm0139.smd   B_DUN_P3_GANSEK      0x7F=127  0x0F= 15
bgm0140.smd   B_DUN_P3_GENSEN      0x7F=127  0x0E= 14
bgm0141.smd   B_DUN_P3_HOSHI_      0x7F=127  0x05=  5
bgm0142.smd   B_DUN_P3_HOSHI_      0x7F=127  0x06=  6
bgm0143.smd   B_DUN_P3_SHONYU      0x7F=127  0x10= 16
bgm0144.smd   B_DUN_P3_SHONYU      0x7F=127  0x11= 17
bgm0145.smd   B_DUN_P3_ZAIHO_      0x7F=127  0x19= 25
bgm0146.smd   B_DUN_P3_ZAIHO_      0x7F=127  0x08=  8
bgm0147.smd   B_DUN_P3_ZAIHO_      0x7F=127  0x09=  9
bgm0148.smd   B_DUN_P3_KOKATS      0x7F=127  0x14= 20
bgm0149.smd   B_DUN_P3_KURAGA      0x7F=127  0x15= 21
bgm0150.smd   B_DUN_P3_KUUKAN      0x7F=127  0x16= 22
bgm0151.smd   B_DUN_P3_KURAYA      0x7F=127  0x17= 23
bgm0152.smd   B_DUN_P3_HYOCHU      0x7F=127  0x18= 24
bgm0153.smd   B_DUN_P3_HYOUZA      0x7F=127  0x1A= 26
bgm0154.smd   B_DUN_P3_HYOUZA      0x7F=127  0x1B= 27
bgm0155.smd   B_DUN_P3_SORA_0      0x7F=127  0x1C= 28
bgm0156.smd   B_DUN_P3_SORA_0      0x7F=127  0x1D= 29
bgm0157.smd   B_DUN_P3_SORA_0      0x7F=127  0x1E= 30
bgm0158.smd   B_DUN_P3_SORA_0      0x7F=127  0x1F= 31
bgm0159.smd   B_MAP_P3_CAFE.S      0x7F=127  0x20= 32
bgm0160.smd   B_EVENT_P3_DANC      0x7F=127  0x21= 33
bgm0161.smd   B_EVENT_P3_WICK      0x7F=127  0x22= 34
bgm0162.smd   B_EVENT_P3_PUPU      0x7F=127  0x23= 35
bgm0163.smd   B_EVENT_P3_PUPU      0x7F=127  0x24= 36
bgm0164.smd   B_EVENT_P3_PUPU      0x7F=127  0x25= 37
bgm0165.smd   B_EVENT_P3_CHAR      0x7F=127  0x26= 38
bgm0166.smd   B_EVENT_P3_CHAR      0x7F=127  0x27= 39
bgm0167.smd   B_EVENT_P3_NEWL      0x7F=127  0x28= 40
bgm0168.smd   B_EVENT_P3_SOUL      0x7F=127  0x29= 41
bgm0169.smd   B_EVENT_P3_PRID      0x7F=127  0x2A= 42
bgm0170.smd   B_EVENT_P3_SUNR      0x7F=127  0x2B= 43
bgm0171.smd   B_EVENT_P3_NEWW      0x7F=127  0x2C= 44
bgm0172.smd   B_EVENT_P3_NOTM      0x7F=127  0x2D= 45
bgm0173.smd   B_EVENT_P3_S09S      0x7F=127  0x2E= 46
bgm0174.smd   B_EVENT_P3_DESI      0x7F=127  0x2F= 47
bgm0175.smd   B_EVENT_P3_WIND      0x7F=127  0x30= 48
bgm0176.smd   B_EVENT_P3_ADVE      0x7F=127  0x31= 49
bgm0177.smd   B_EVENT_P3_SHAY      0x7F=127  0x32= 50
File          IName                 UNK_A9    UNK_AA
bgm0178.smd   B_EVENT_P3_CHAR      0x7F=127  0x33= 51
bgm0179.smd   B_ENV_P3_LAVA_0      0x7D=125  0x01=  1
bgm0180.smd   B_ENV_P3_LAVA_0      0x7D=125  0x02=  2
bgm0181.smd   B_ENV_P3_WAVE_0      0x7D=125  0x03=  3
bgm0182.smd   B_ENV_P3_GRASSY      0x7D=125  0x04=  4
bgm0183.smd   B_ENV_P3_CAVE_0      0x7D=125  0x05=  5
bgm0184.smd   B_ENV_P3_FIRESP      0x7D=125  0x06=  6
bgm0185.smd   B_ENV_P3_FIREWA      0x7D=125  0x07=  7
bgm0186.smd   B_ENV_P3_RAIN_0      0x7D=125  0x08=  8
bgm0187.smd   B_ENV_P3_TOP_01      0x7D=125  0x09=  9
bgm0188.smd   B_ENV_P3_SOURCE      0x7D=125  0x0A= 10
bgm0189.smd   B_ENV_P3_RUINS_      0x7D=125  0x0B= 11
bgm0190.smd   B_ENV_P3_JUNGLE      0x7D=125  0x0C= 12
bgm0191.smd   B_ENV_P3_CRAG_0      0x7D=125  0x0D= 13
bgm0192.smd   B_ENV_P3_MEMORY      0x7D=125  0x0E= 14
bgm0193.smd   B_ENV_P3_CAVE_0      0x7D=125  0x0F= 15
bgm0199.smd   B_EVENT_P3_CHAR      0x7F=127  0x34= 52
bgm0200.smd   B_EVENT_P3_CHAR      0x7F=127  0x35= 53
bgm0201.smd   B_EVENT_P3_CHAR      0x7F=127  0x36= 54

If it is true that these correspond to priorities or something, then the existance of UNK_A9 and UNK_AA (the commands) reveals that there is the capability to dynamically override other pieces, at least in theory (I haven't checked to see if they are used anywhere other than the start of tracks).

EDIT: Ninjas!

Another piece of supporting evidence for my assignments are that the channel volume always gets set, first thing. I'll check dumps of Northern Desert when I'm able to.

Yeah, drum assignments would be handled in the .swd files, because as far as the .smd is concerned, they are just another instrument. However, they are always assigned to output ID 15 (MIDI 16), so it is possible the synth engine itself does special handling with it for some things.

RAPIDEDIT: I see what you mean, getting the two swapped right now when I have time

Link to comment
Share on other sites

Just a quick update before I head to college, got the 0xD7 SET_TUNE command documented and implemented, and started research on the UNK_A9 and UNK_AA commands (the ones which have values in the header), or rather I researched those values in the header.

With a quick Perl script, I concluded that they do not relate to the playback directly, but might be priority levels. This is supported by the fact that, it appears, no two files have the same values for both the A9 and AA fields (+0x0F and +0x0E) in the header.

I think that the A9/0x0F field is an enum which identifies the category of piece (things like enviornmentals versus plot music), while the AA/0x0E field gives a priority or identifier or something within the specific category.

It is interesting to note that all the pieces except bgm0077 "B_EVENT_TIMEWHE" have a "large" (0x70<n<0x80) A9/0x0F field, while bgm0077 has 0x01 there.

If it is true that these correspond to priorities or something, then the existance of UNK_A9 and UNK_AA (the commands) reveals that there is the capability to dynamically override other pieces, at least in theory (I haven't checked to see if they are used anywhere other than the start of tracks).

I never seen those used anywhere else than the beginning of a track. With the exception of maybe right after a 0x90 event, given some events you only see at the beginning of a track seem to be repeated right after a 0x90.. I gotta double check though, I'm still trying to find where I saw a 0x90 event the last time..

But those two being about priority makes a lot of sense ! Given the game seamlessly change songs constantly. If those are enums, maybe we could find those values in the game executable, one after another ?

Yeah, drum assignments would be handled in the .swd files, because as far as the .smd is concerned, they are just another instrument. However, they are always assigned to output ID 15 (MIDI 16), so it is possible the synth engine itself does special handling with it for some things.

RAPIDEDIT: I see what you mean, getting the two swapped right now when I have time

That sounds pretty likely, or maybe its just a coincidence with the software they've used to compose the tracks using 15 instead of 10 or something? I'll try setting a drum track to another track number just for fun!

EDIT:

I changed the drum track in Northern Desert from 0x0D and 0x0F to 0x01 and 0x01, and it stills plays like it should!

So, I'd say its mainly a coincidence that all drum tracks are 0x0F.

EDIT2:

Ok, now I completely agree with you that 0x90 is probably a repeated silence.

Link to comment
Share on other sites

Yeah, I had some spare time, Sentry Duty music has drums off of MIDI 16. I changed my local copy to instead identify a drum track by sample ID 0x7F. Speaking of which...

I did some digging into the .swd files, and might have figured out the mapping for instruments -> samples. Each SMD instrument has a number of samples, which are selected by the associated SWD; this selects the sample to use by the MIDI key number (!) and possibly velocity, mapping into what I'm guessing is a sample in bgm.swd. So now I have a 3,492 line file which lists all the sample ID numbers (0..948), as well as what instruments in what tracks use them; this is at http://cdusto.selfip.com/pmdMus/instSampMap.txt. Now I just need to figure out the sample clusters (the clusters of samples which are for the same instrument), and make a very big .map file to map sample ID numbers to MIDI instruments.

EDIT: And I can't come up with any good way to do the mapping. There is probably more stuff in the .swd which could be used to determine instruments from each other, possibly even sample grouping in bgm.swd, but I'm not properly equipped to do a full analyses of the format right now. I'm going to toss my current code up on my server, and see if I can get some sort of globally-accessable svn (compared to the SVN over SSH setup I have right now).

Probably going to do a rewrite of the tools, as they are right now, so that they are more helpful both in finding out what still needs research, and in documenting the format gracefully (like consistantly using the command name enums rather than using the name in some places and the opcode in others).

Edited by TruePikachu
Link to comment
Share on other sites

Yeah, I had some spare time, Sentry Duty music has drums off of MIDI 16. I changed my local copy to instead identify a drum track by sample ID 0x7F. Speaking of which...

I did some digging into the .swd files, and might have figured out the mapping for instruments -> samples. Each SMD instrument has a number of samples, which are selected by the associated SWD; this selects the sample to use by the MIDI key number (!) and possibly velocity, mapping into what I'm guessing is a sample in bgm.swd. So now I have a 3,492 line file which lists all the sample ID numbers (0..948), as well as what instruments in what tracks use them; this is at http://cdusto.selfip.com/pmdMus/instSampMap.txt. Now I just need to figure out the sample clusters (the clusters of samples which are for the same instrument), and make a very big .map file to map sample ID numbers to MIDI instruments.

EDIT: And I can't come up with any good way to do the mapping. There is probably more stuff in the .swd which could be used to determine instruments from each other, possibly even sample grouping in bgm.swd, but I'm not properly equipped to do a full analyses of the format right now. I'm going to toss my current code up on my server, and see if I can get some sort of globally-accessable svn (compared to the SVN over SSH setup I have right now).

Probably going to do a rewrite of the tools, as they are right now, so that they are more helpful both in finding out what still needs research, and in documenting the format gracefully (like consistantly using the command name enums rather than using the name in some places and the opcode in others).

That's all good. If you want my opinion, you should wait before getting into making proper mapping until we're more familiar with everything. Because if we find out an easy way to do it, you'd have wasted a lot of time on doing that. But that's just my opinion.

And at this point, I'd suggest a good old brute force approach to try to get some more results. Directly editing values in the SWDs and etc..

That's what I'm planning to do with the sprite pretty soon. It usually gives great results. That's how I figured half of what I wrote in my notes on the SMDs ! xD

Link to comment
Share on other sites

Well, I got a huge list of instrument guesses, and apparently bgm0050 has two drum track programs, 0x7E and 0x7F. Anyway, this grouping isn't very useful without the samples <_<. But I have code to guess groups written up.

Going to mess around with the outputted MIDI sequences, see how nice I can get them to be, might help with IDing unknown commands.

Link to comment
Share on other sites

Someone pm-ed me the link to an utility that extracts the tracks from PMD2 perfectly as midi:

http://pan.baidu.com/wap/shareview?&shareid=878289138&uk=1829041001&dir=%2F%E6%88%91%E7%9A%84%E6%96%87%E6%A1%A3%2F%E6%B8%B8%E6%88%8F%E8%B5%84%E6%BA%90%E6%8F%90%E5%8F%96%E7%A8%8B%E5%BA%8F&page=1&num=20&fsid=1084154235148743&third=0

To use it simply put as parameter the path to the BGM folder, with no trailing slash at the end.

Then as second parameter the path to the folder to output midis to, with no trailling slash at the end.

You can also put options before those two paths. "-l" is to set the loop count. and "-d" for outputting debug input I guess.

In the folder there are 2 files used to map instruments, and they're very small..

And it seriously seems to get absolutely everything 100% right.. Its seriously impressive... Just play the BGM0004.mid to see what I mean.. The flute just sounds exactly the same way.. Its scary.. xD

EDIT:

I'm having feels attack listening to these ;_;

xD

EDIT2:

One thing to note is that, there's an issue where the in Chasm Cave and etc, the French Horn is replaced with an Oboe for some reasons..

And the trumpet in "The Power of Darkness" is replaced with an Alto Sax..

Edited by psy_commando
Link to comment
Share on other sites

No source code...guess its time to pull out the disassembler >:D (I can easily handle x86)

EDIT:

Looks like C and not C++:

 if ( argc == 1 )
 {
   printf("SMD to MIDI File Converter V%.2f\n", 0.1);
   printf("Usage  : smd2mid.exe [options] <InDir> <OutDir>\n");
   printf("Options:\n");
   printf("\t -np          \t Not use 'prog_table.txt'\n");
   printf("\t -nd          \t Not use 'drum_table.txt'\n");
   printf("\t -l  <count>  \t Loop count\n");
   printf("\t -d           \t Debug mode\n");
   printf("\n");
   result = EXIT_SUCCESS;
 }

That makes things even easier, since I don't have to mess with classes.

EDIT: gah, might need to localize strings:

printf("âtâ@âCâïé¬èJé»é_é¦é");

Link to comment
Share on other sites

No source code...guess its time to pull out the disassembler >:D (I can easily handle x86)

EDIT:

Looks like C and not C++:

 if ( argc == 1 )
 {
   printf("SMD to MIDI File Converter V%.2f\n", 0.1);
   printf("Usage  : smd2mid.exe [options] <InDir> <OutDir>\n");
   printf("Options:\n");
   printf("\t -np          \t Not use 'prog_table.txt'\n");
   printf("\t -nd          \t Not use 'drum_table.txt'\n");
   printf("\t -l  <count>  \t Loop count\n");
   printf("\t -d           \t Debug mode\n");
   printf("\n");
   result = EXIT_SUCCESS;
 }

That makes things even easier, since I don't have to mess with classes.

EDIT: gah, might need to localize strings:

printf("âtâ@âCâïé¬èJé»é_é¦é");

That's funny.. The readme mentioned C++.. I guess its one of these person who codes in C in C++ xD

Also, I don't even know if C support Unicode, or the JIS character set :/

Also, what disassembler are you using, just by curiosity ? ^^;

EDIT:

Wait.. The C++ compiler removes literally everything about classes when it compiles stuff.. So I guess its normal that it looks like there aren't any.. Unless I'm missing something..

Link to comment
Share on other sites

Also, what disassembler are you using, just by curiosity ? ^^;

IDA, only one I've found that works well for me. There is a free version availible, but it lacks pseudocode and platforms other than x86.

C89 doesn't support Unicode proper, where C99 supports it to an extent (at least under gcc, I forget if it was a gcc extension that adds the \u escape).

It does look like a C++ compiler was used, given that there are functions with names such as "?strncnt@@YAHPBDH@Z_0" (being "int __cdecl strncnt(char const *,int)"). main() doesn't seem to use anything C++ specific, instead using printf() and scanf() (the latter for the debug mode prompt).

It doesn't look like this program will be useful for converting anything outside the BGM:

     songID = 0;
     while ( 1 )
     {
       sprintf(smdFilename, "%s/bgm%04d.smd", ParamInDir, songID);
       sprintf(midFilename, "%s/bgm%04d.mid", ParamOutDir, songID);
       if ( smd2mid(smdFilename, midFilename) )
         break;
       printf("==============================================\n");
       ++songID;
       if ( songID > 201 )
         return EXIT_SUCCESS;
     }

Link to comment
Share on other sites

On the contrary, there are a lot of other NDS games that use the Procyon driver to play music. If you can work out the format, you might make a lot of other people very happy. :P

Apparently the SWD files are of the IMA ADPCM variety...does that mean anything to you?

Link to comment
Share on other sites

On the contrary, there are a lot of other NDS games that use the Procyon driver to play music. If you can work out the format, you might make a lot of other people very happy. :P

Apparently the SWD files are of the IMA ADPCM variety...does that mean anything to you?

IMA ADPCM has a LOT of variants.. If you want to hear some of the sound effects, try to load the BGM.swd or any SWD that has something in their pcmd chunk as raw data into Audacity. Then select VOX ADPCM, little endian, mono, and the sample rate is indicated inside the corresponding wavi chunk entry, but you can usually go for 22050hz if you're not sure.

Ideally, you'd only want to feed audacity the data in the pcmd chunk, given ADPCM is "incremental" in the way it decompresses stuff, and any extra data before will change the sound a little..

(If anyone ever stumble on ADPCM decoding libs for the NDS, I'd appreciate hearing about those !)

@TruePikachu:

I believe that what's in the ME folder has a very similar structure to everything in BGM. So that might work too.

EDIT:

Speaking of which. SED files are highly similar to SMD files. Except they seem to have several new chunks.

EDIT2:

Kr3nshaw That link you gave me about the Procyon sequencer and stuff, it has some nice little tidbits of information even when quickly translated:

http://www.procyon-studio.co.jp/dse/spec.html

High-quality sound, audio file playback with the high compression

By its own voice compression algorithm, high-quality sound, audio file playback with the high compression is possible. In streaming playback of the Nintendo DS, we reduce the noise of the DS-specific in particular. In addition, because the CPU load is very low in spite of the high-quality sound, (CPU load values, please refer to the technical specification) and you can always do a audio streaming music and high-quality sound while playing a movie of high quality.

※ Because there is a considerable difference in the output of the game machine on the actual audio output of NITORO EMULATOR, (the amount of noise is different) I have been recording directly from the headphone jack of the game machine in our demo.

Estimated capacity (if you use the 512K ROM)

[Music]

○ recorded possible 8 minutes for high-quality music (codec1_Hi) about 1 hour

○ recorded a 16-minute (codec1_Low) about 2 hours music for high compression

○ 4 minutes recorded music available for high-quality (codec4_Hi) about 1 hour

○ recorded possible 8 minutes (codec4_Low) about 2 hours music for high compression

[Dialogue]

○ recorded possible (codec8_Q10) about 3 hours and 15 minutes for high-quality music

○ (codec8_Q8) about 5 hours recorded voice possible for normal

○ (codec8_Q6) about 7 hours recorded sound possible for high compression

○ (codec8_Q4) about 11 hours recorded voice possible for ultra-high compression

※ other, it is a large number can be set, but ask them to describe a codec which is often used in general.

(Standard ADPCM data)

(DSE own data)

Program editing features that have been refined

By the design and screen configuration that is simple yet sophisticated, it has become the interface controls efficient and intuitive as possible. Waveform registration easy as drag-and-drop the 'Wave Entry window' audio file. In the editing program, by using a graphical interface, you can edit easily Notes Split & velocity layer, the envelope.

※ The keyboard window, you will see note split layer that has been programmed registration is color-coded. In addition, by clicking on the keyboard of the keyboard window with the mouse, you can check the sound directly.

Flexible voice control

You can use the flexible control of pronunciation in the song sequence and sound effects and effective use of the few voice. In addition, you can avoid the sound out of the unexpected even if you manage the priority of a music unit, usually music and ambient music songs such as, multiple simultaneous playback.

※ It is also possible to be played in the specified channel the sound of specific.

A variety of LFO function

It is possible to modulate at the same time up to four pitch, volume, localization for each program. Also, I can choose the waveform square wave, triangle wave, sawtooth wave, such as noise as generated waveform of LFO. Of course, such as random orientation modulation, each key-on using the MIDI control change, various expressions can be playing terms, such as tremolo and vibrato that is synchronized with the key-on. Also, since you are processing your own, LFO function of this driver will be reproduced in the same LFO and Wii NINTENDO DS.

※ In each LFO, depth, rate, delay, fade, flexible configuration is possible.

Streaming player installed

Equipped with a handy streaming player when you listen to the (such as voice files in particular) streaming large amounts of data, to adjust the volume. Can listen simply by pressing the space key according to the file you want to listen to the (↑ ↓) cursor. Select the file you want to change the volume control more than one file, it can be changed relative, absolutely if you enter a number, (+ arithmetic operator - to increase the uniform volume at 1.2 times if × ÷ as '× 1.2' can also batch process it has used the possibility). In addition, can also be set send levels to the (delay etc. Ribabu) FX for each file in the Wii.

※ the entire capacity that has been registered, and the number of files is also displayed. In addition, the capacity of only the selected file (s) also can be checked easily.

Can be set by a variety of envelope processing of its own

In the 'Digital Sound Elements', it is possible by processing its own envelope, setting a fine envelope time. In addition, the parameters of the ADSR, you can have AL, AR, HOLD, DR, SL, SR, RR, is RX, to set the envelope of a higher degree of freedom. In addition, the same envelope will be reproduced in the NINTENDO DS & Wii similarly to the LFO, you are treated to our own driver.

※ AL (Attack Level), HOLD (hold), RX (scaling) is a parameter of our driver-specific.

Sequence sound effects editor equipped

In game development sought the capacity limit, becoming sequence effect sound is essential. In addition to the import of MIDI, the event list editing of proprietary format, utilizing the features of the driver, the sound effect of representation and complex flexible production is possible to sequence sound effect. Since it offers a command pitch change and fade in / out, and detune, without having to write a lot of control change, etc. in MIDI, which clean change is possible with a small amount of data.

※ Editor window is displayed by double-clicking the region.

Automatic creation of sound list

Work of sound creators not only make the music and sound effects. From being devoted the most time wasted it or would not be a sound list of the music and sound effects that you made? No need to learn and how to use Excel, a description of the html purposely in order to create a sound list. For us to create automatically (html) Sound list, easy-to-view together when you update the music and sound effects in the DSE. Also seemingly tend to forget these, DSE I support sound creator.

※ not only music, sound effects and audio list, can be output also include files.

Possible game production tools in common with and Wii NINTENDO DS

By using a common development tools, just to switch the output format, it is possible to output the data of both the Wii and the NINTENDO DS.

※ Change the project settings, just re-make the file, and then output the appropriate data to match the platform.

※ Because of development, there are times when it is subject to change screen. Please understand.

EDIT3:

And if anyone is wondering what is IMA ADPCM its a standard, its not a "specific" format.

http://wiki.multimedia.cx/index.php?title=IMA_ADPCM

And I was able to find out that the vgmstream lib Kode54 maintains has support for Procyon studio NDS ADPCM : https://github.com/kode54/vgmstream

I'm looking at the code and I suggest people interested to look within the source code for the enum constant named "coding_NDS_PROCYON" as a starting point.

Link to comment
Share on other sites

I'm glad it was useful! :D

Unfortunately, I think that the entry in vgmstream.h is just a placeholder. As far as I know, they haven't actually worked out the format yet. :(

EDIT: I take that back. Two years is a long time.

https://github.com/kode54/vgmstream/blob/44075c4e911d713ad7277a6b2ee4b7cd9572f7ee/src/coding/nds_procyon_decoder.c

https://github.com/kode54/vgmstream/blob/44075c4e911d713ad7277a6b2ee4b7cd9572f7ee/src/meta/nds_sad.c

Edited by kr3nshaw
Link to comment
Share on other sites

hehehe...

I think I've disassembled all I need to do so from that program. Of note:

* SET_VOLUME and SET_XPRESS are confirmed to be correct for their current settings (Medley uses SET_VOLUME incorrectly)

* New command: SET_MODU, which adjusts the MIDI modulation

* All other old commands I've documented are CONFIRMED

* No other new MIDI commands

* "Proper" way to handle SET_TUNE (gonna port a bit of code over to my project)

* Can parse the drum_table.txt and prog_table.txt files; of note, the entries to use are determined by...the UNK_AA-related field! It selects the instrument group to use, it doesn't give priorities. I have the line syntax at the end of my notes file.

Time to do some coding!

EDIT: I seem to be wrong about the UNK_AA field

EDIT: False alarm, value of 0 means defaults

EDIT: Just pushed an updated version of the converter to the server. smd2mid (my tool) now supports looping, and will automatically remap instruments if it has those two .txt files in the working directory (which I have in the package). It also has SET_TUNE (now SET_BEND) corrected, SET_MODU support, and UNK_AA display in smdDump.

EDIT: As a quick side project, I dumped the in-game music titles for the Sky Jukebox, alongside the filenames:

##       File       Title
----   -----------   -----
  1   bgm0001.smd   Pokémon Exploration Team Theme
  2   bgm0002.smd   Top Menu Theme
  3   bgm0006.smd   Welcome to the World of Pokémon!
  4   bgm0069.smd   On the Beach at Dusk
  5   bgm0021.smd   Beach Cave
  6   bgm0014.smd   In the Depths of the Pit
  7   bgm0130.smd   Title Theme
  8   bgm0007.smd   Wigglytuff's Guild
  9   bgm0073.smd   Guildmaster Wigglytuff
 10   bgm0070.smd   Goodnight
 11   bgm0008.smd   Wigglytuff's Guild Remix
 12   bgm0022.smd   Drenched Bluff
 13   bgm0005.smd   Job Clear!
 14   bgm0009.smd   Treasure Town
 15   bgm0131.smd   Heartwarming
 16   bgm0074.smd   Growing Anxiety
 17   bgm0076.smd   Oh No!
 18   bgm0023.smd   Mt. Bristle
 19   bgm0015.smd   Boss Battle!
 20   bgm0078.smd   Time Gear Remix
 21   bgm0004.smd   The Gatekeepers
 22   bgm0013.smd   Outlaw!
 23   bgm0079.smd   I Saw Something Again...
 24   bgm0024.smd   Waterfall Cave
 25   bgm0012.smd   Kecleon's Shop
 26   bgm0134.smd   Team Skull
 27   bgm0159.smd   Spinda's Café
 28   bgm0160.smd   Ludicolo Dance
 29   bgm0025.smd   Apple Woods
 30   bgm0026.smd   Craggy Coast
 31   bgm0027.smd   Cave and Side Path
 32   bgm0028.smd   Mt. Horn
 33   bgm0029.smd   Foggy Forest
 34   bgm0030.smd   Steam Cave
 35   bgm0031.smd   Upper Steam Cave
 36   bgm0032.smd   Amp Plains
 37   bgm0033.smd   Far Amp Plains
 38   bgm0011.smd   Monster House!
 39   bgm0133.smd   Rising Fear
 40   bgm0034.smd   Northern Desert
 41   bgm0035.smd   Quicksand Cave
 42   bgm0036.smd   Quicksand Pit
 43   bgm0037.smd   Crystal Cave
 44   bgm0038.smd   Crystal Crossing
 45   bgm0072.smd   At the End of the Day
 46   bgm0080.smd   In the Future
 47   bgm0081.smd   Planet's Paralysis
 48   bgm0039.smd   Chasm Cave
 49   bgm0040.smd   Dark Hill
 50   bgm0041.smd   Sealed Ruin
 51   bgm0042.smd   Sealed Ruin Pit
 52   bgm0043.smd   Dusk Forest
 53   bgm0044.smd   Deep Dusk Forest
 54   bgm0075.smd   The Power of Darkness
 55   bgm0061.smd   Treeshroud Forest
 56   bgm0046.smd   Brine Cave
 57   bgm0047.smd   Lower Brine Cave
 58   bgm0048.smd   Hidden Land
 59   bgm0049.smd   Hidden Highland
 60   bgm0017.smd   Battle against Dusknoir
 61   bgm0077.smd   Time Gear
 62   bgm0082.smd   Through the Sea of Time
 63   bgm0083.smd   In the Hands of Fate
 64   bgm0050.smd   Temporal Tower
 65   bgm0051.smd   Temporal Spire
 66   bgm0108.smd   Temporal Pinnacle
 67   bgm0132.smd   Down a Dark Path
 68   bgm0016.smd   Dialga's Fight to the Finish!
 69   bgm0084.smd   Time Restored
 70   bgm0085.smd   Don't Ever Forget...
 71   bgm0121.smd   Have to Get Home
 72   bgm0122.smd   Farther Away...
 73   bgm0086.smd   A Wish for Peace
 74   bgm0088.smd   Memories Returned
 75   bgm0089.smd   Ending Theme Intro
 76   bgm0090.smd   Ending Theme
 77   bgm0091.smd   Epilogue Theme
 78   bgm0052.smd   Mystifying Forest
 79   bgm0010.smd   Do Your Best, as Always!
 80   bgm0177.smd   Shaymin Village
 81   bgm0155.smd   Sky Peak Forest
 82   bgm0095.smd   Sky Peak Cave
 83   bgm0156.smd   Sky Peak Prairie
 84   bgm0097.smd   Sky Peak Coast
 85   bgm0157.smd   Sky Peak Snowfield
 86   bgm0158.smd   Sky Peak Final Pass
 87   bgm0053.smd   Blizzard Island Rescue Team Medley
 88   bgm0054.smd   Surrounded Sea
 89   bgm0060.smd   Miracle Sea
 90   bgm0056.smd   Aegis Cave
 91   bgm0018.smd   Defy the Legends
 92   bgm0057.smd   Concealed Ruins
 93   bgm0058.smd   Mt. Travail
 94   bgm0059.smd   In the Nightmare
 95   bgm0123.smd   Palkia's Onslaught!
 96   bgm0062.smd   Dark Crater
 97   bgm0063.smd   Deep Dark Crater
 98   bgm0055.smd   Random Dungeon Theme 1
 99   bgm0045.smd   Random Dungeon Theme 2
100   bgm0145.smd   Random Dungeon Theme 3
101   bgm0003.smd   Marowak Dojo
102   bgm0129.smd   Pelipper Island
103   bgm0135.smd   Sympathy
104   bgm0136.smd   Beyond the Dream
105   bgm0137.smd   Air of Unease
106   bgm0141.smd   Star Cave
107   bgm0142.smd   Deep Star Cave
108   bgm0138.smd   One for All, All for One!
109   bgm0094.smd   Murky Forest
110   bgm0176.smd   A Fun Exploration
111   bgm0146.smd   Fortune Ravine
112   bgm0147.smd   Fortune Ravine Depths
113   bgm0162.smd   It Can't Be...
114   bgm0163.smd   Defend Globe
115   bgm0164.smd   Defend Globe (Ending)
116   bgm0098.smd   Spring Cave
117   bgm0099.smd   Lower Spring Cave
118   bgm0140.smd   Spring Cave Depths
119   bgm0166.smd   Here Comes Team Charm!
120   bgm0096.smd   Southern Jungle
121   bgm0139.smd   Boulder Quarry
122   bgm0161.smd   Illusion Stone Chamber
123   bgm0143.smd   Limestone Cavern
124   bgm0144.smd   Deep Limestone Cavern
125   bgm0165.smd   Team Charm's Theme
126   bgm0167.smd   For a New Life
127   bgm0148.smd   Barren Valley
128   bgm0149.smd   Dark Wasteland
129   bgm0150.smd   Spacial Cliffs
130   bgm0151.smd   Dark Ice Mountain
131   bgm0168.smd   Living Spirit
132   bgm0152.smd   Icicle Forest
133   bgm0169.smd   Proud Accomplishment
134   bgm0153.smd   Vast Ice Mountain
135   bgm0154.smd   Vast Ice Mountain Peak
136   bgm0170.smd   In the Morning Sun
137   bgm0171.smd   A New World
138   bgm0174.smd   It's Not a Miracle
139   bgm0172.smd   Thoughts for Friends
140   bgm0175.smd   A Message on the Wind
141   bgm0173.smd   Life Goes On! (Ending)

I hope that the full internal filenames are somewhere in the ROM, but it doesn't look like they are :( I might see about getting the other files identified, but I don't know how plausable it will be (especially since EoS lacks the debug EoT/EoD had). I could try making a hack, though, to change the songs in the Jukebox...

Here is the dumper code, if anyone has any interest in it.

#!/usr/bin/perl
use warnings;
use strict;
use Fcntl 'SEEK_SET';

open NDSROM,'< nds/pmd-eos.nds';

my ($jukeboxID,$title,$filename);
format STDOUT_TOP =
##       File       Title
----   -----------   -----
.
format STDOUT =
@>>>   @||||||||||   @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$jukeboxID,$filename,$title
.

my $buffer;
for($jukeboxID=1;$jukeboxID<=141;$jukeboxID++) {
       {
               local $/ = "\0";
               seek NDSROM,0x176BE2 + 2*$jukeboxID,SEEK_SET;
               read NDSROM,$buffer,2;
               my $songID = unpack "v",$buffer;
               $filename = 'bgm'.substr('0000'.$songID,-4).'.smd';
               my $stringID = 1276+$jukeboxID;
               seek NDSROM,0x2075E00 + 4*$stringID,SEEK_SET;
               read NDSROM,$buffer,4;
               seek NDSROM,0x2075E01+unpack("L",$buffer),SEEK_SET;
               $buffer = <NDSROM>;
               chomp $buffer;
               $title = $buffer;
               $title =~ s/\xE9/é/g;
       }
       write;
}

Edited by TruePikachu
Link to comment
Share on other sites

Sounds good. And the internal names are unrecoverable AFAIK. I'm not sure why they even bothered to put them inside those files at all..

Its possible they're refered to as those names in the scripting system however.. But you'd have to ask Nerketur about that..

I looked at the vgmstream lib code, and its hard-coded for SADL files from Professor Layton.. The ADPCM decoding code however might just be very useful, if we can isolate it and re-use it.. But its some very messy C code, with some not very intuitive structure and variable naming..

Its going to take a while to figure it out.. -_-

Also, I'll admit I kinda feel useless with everyone making that much progress, and me not doing much right now ^^;

Link to comment
Share on other sites

Generally, internal names are useful for making sure that the correct files are actually in the correct locations.

I'm not entirely sure that the script system has access to the names; I tried a few greps on the ROM...

cDusto:/~
chris:$ md5sum pmd-eos.nds
ef6e0ec5e1b482aa77c0b2f623128ef9  pmd-eos.nds
cDusto:/~
chris:$ grep -boia B_ENV_BEACH_01 pmd-eos.nds | perl -e 'while(my$p=<STDIN>){chomp$p;my($o,$t)=split/:/,$p;printf("0x%08X\n",$o)if$o;}'     # Offsets of "B_ENV_BEACH_01", ignore the 0x00000000
0x04987E05
0x04989D69
0x04B1B894
0x00000000
cDusto:/~
chris:$ grep -boia B_ENV_BEACH_01\\. pmd-eos.nds | perl -e 'while(my$p=<STDIN>){chomp$p;my($o,$t)=split/:/,$p;printf("0x%08X\n",$o)if$o;}'     # Offsets of "B_ENV_BEACH_01.", ignore the 0x00000000
0x04987E05
0x04989D69
0x04B1B894
0x00000000
cDusto:/~
chris:$ grep -boia B_ENV_BEACH_01\\.SMD pmd-eos.nds | perl -e 'while(my$p=<STDIN>){chomp$p;my($o,$t)=split/:/,$p;printf("0x%08X\n",$o)if$o;}'     # Offsets of "B_ENV_BEACH_01.SMD"
cDusto:/~
chris:$ grep -boia B._.E.N.V._.B.E.A.C.H._.0.1.\\..S.M.D pmd-eos.nds | perl -e 'while(my$p=<STDIN>){chomp$p;my($o,$t)=split/:/,$p;printf("0x%08X\n",$o)if$o;}'     # Offsets of "B_ENV_BEACH_01.SMD", 2-byte chars
cDusto:/~
chris:$

(that inline Perl script just drops grep(1)'s repetition of the match text, and converts the offset to hex)

You can continue work on the .swf format, or go back to sprite stuff. I'm pretty much not doing research that requires ROM hacking.

Link to comment
Share on other sites

on Pokemon Mystery Dungeon - Gates to Infinity, is seems used standard nintendo 3ds format ... (only on 3d models and texture, but not on 2d sprite)

sir0 file containing 3d model , always have this structure :

0x0 - 4 byte - sir0 (0x53 0x49 0x52 0x30)
0x4 - 4 byte - offset (start) for 2nd header (on 3ds case, is for file description, filename and size) (A)
0x8 - 4 byte - offset (start) for 3rd header (B)
0xc - 4 byte - padding
#filename region header data (containing filesize and offset)

0x0 - 4 byte - offset to file description
0x4 - 4 byte - file count
0x8 - 8 byte - padding (?)

file description is need 16 byte for each entry

0x0 - 4 byte - length (?)
0x4 - 4 byte - start offset of file
0x8 - 4 byte - end offset of file
0xc - 4 byte - padding

3rd header

0x0 - 2 byte - 0x4
0x2 - 2 byte - 0x4
0x4 - 2 byte - 0x81 , 0x82 (depend on size)
0x8 - 2 byte - ...
0xc - 1 byte*filecount - filled by 0x10 (i was thing is for file description length since is always 0x10) // if is not fully filled (multiply by 0x10), it will padding by 0x0

^ with 0x4 0x4 as magic header

pokemon motion database (PMDB), effect database (EFDB), and other is similar with this one.

well i just got bunch of code from rom :

265W424P
287K4NHW
29NP969C
29SYRYRX
2C3YJ43F
2C4Q5P9Q
2F6MFWR8
2H7YCY78
2HJ2HTCH
2SRTN2FC
2TKMQ62C
2W6J2X8K
2XRJRQ93
32SHFRW3
3CMS47R2
3K6XSKQP
3M7M3T2M
3QCXJ83J
3SQST3WM
3XS5Q3P3
3YP232KN
43PC9JQT
475MQRQF
47SPF752
47W4YMWX
484HS83Q
4CF26XTY
4CX794YR
4YK3NMYP
526KS6QC
56F78P7C
572KT2TW
5JNRYN5K
5KNKY3MK
5MRQ8MKQ
5PMHM339
5TW8F8T6
5WX56NF8
62RYJ8CM
63X4M3N2
6CF7N69W
6HW2M53H
6M83QYCW
6P7NSQFS
6RC7YF47
6S63793Y
6SM86QY3
6TXTFJWX
6XTMC9JH
78S47MF7
79C8NXX3
7F3CJ9FP
7FJ2XW3W
7RXJSXTN
83F2R7NX
846CH46F
89W848PY
8F2X9XW7
8HXH4894
8J7NJRC4
8M5FK3SH
8M946HX4
8N8Y7HY5
8P868TP7
8PR8H748
8Q2J2K2S
8QR65YQS
8RXH37H7
8S793KF7
8SYQ8R43
8W7TNK36
9292Y79K
932FRNJH
95JRS7YP
96CCF6QH
98W8H98T
9CN768CP
9F7M6826
9JW94J9S
9K4Q8WRC
9QY5W7NW
9RPKRPSN
9SQYRYSF
C29253XF
CNTX386T
CQ49QCHK
CY86PHW4
F6H9RHR9
F6M67SS7
F6NCFWM2
FYPQ892Q
H5FTM82N
H5NY4THR
H9HFJPNF
H9JR9Y2S
HCJ48PCP
HQ7N7HKQ
HS87J6YS
HW4FM3CF
HXH6FC7H
HXK3WSTF
J82HRY2H
J98S5J5T
JMK5MFKS
JR4XC6HX
JTN34N92
K93YR926
KNHR8M56
KQ5ST45X
KQM4W3H2
KTY3XPMH
M3QMWTMR
M676YKQN
MFN89K9X
MJ653J36
MS34W2YN
MS7P57F4
MTN6P7YM
MX956M5C
N2R9467N
N3HJX9PT
N5JYR74T
N5SF2S6M
N6P467CX
N7XMCJK7
N9PH7547
NF6FK85X
NP725NJ5
NPWRWH8Q
NT6MYXRQ
NW7X5T72
P326J5WX
P6WK88NS
PFM7YXP5
PY3PQSH9
Q5N39QH2
Q6HM5M3N
Q7NYK8Q9
QP3QN7SQ
QR3XPX6X
QR5TS6JY
R3Q6CYM3
R8F37Y8P
R8J38MYN
R9N7JP89
RJ2KPX9M
RKX8CH9S
RM2PX85Y
RM73CM6N
RSNWY62X
RY2K2S5H
S37CF46P
S49RK6NM
S4TR4FR4
S5N8R8RS
SJ5PN6T3
SJ6NQ6T3
SPJ2MY36
SPJYN4HY
SRPJ7PRS
SSJMN96R
SWH42K9C
SX9QSP2M
SXM7H3HN
T2PST5TM
TK7TQNW5
TQRQ3685
TRYF8HS4
TY2XTMNP
W3KCMQMP
W84MR32P
WH9N98QW
WPSCHY6N
WRJ5H72T
WY5TF47S
X68W3WXP
XFH2P557
XN83N4W6
XPR47M2P
Y4W83XRY
Y52XPKRX
Y7HPJN7K
Y96PKF92
YJ4C58CY
YMN83HXM
YRPHWN9S

^ 186 Code XP

Link to comment
Share on other sites

Sorry, but I'm not sure I understand what you're trying to say. ^^;

What are those codes ?

I think those are from Gates to Infinity (3DS), not Explorers (NDS). However, for the entire list of "code from rom", I'm calling BS on that for now, unless more context is given.

@TruePikachu:

Well, technically we're all romhacking here, no ? Do you mean you'd rather stick with only the smds ?

Also, I'm guessing you meant swd, because swf are flash "movies" :P

Yeah, I always typo that extension.

I haven't actually made any edits to the ROM, only read data from it. I know there are a huge number of pieces of research possible by modifying the source material (i.e. compiled binary) to see what effects it has on the output, but I've only really done things like that when I'm trying to make the software behave differently in a specific way.

I don't know why I never actually do it. Case in point, Dwarf Fortress (which is very open to modding) has all the creature and object data stored in plain text files, called raws. However, incorrect modding results in what is called "duped raws" or "duplicated raws", where the game goes crazy because something very weird happened with the resources, and I _mean_ _crazy_ (even by DF standards; you can get things like embarking as elephants with picks made of spit, on dirt made of flesh and stone which is actually bacon). I really want to experiment with duped raws at some point, but never get around to it.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...