-
Posts
425 -
Joined
-
Last visited
-
Days Won
1
Content Type
Profiles
Pokédex
Portal
Technical Documentation
Pages
Tutorials
Forums
Events
Downloads
Gallery
Blogs
Everything posted by psy_commando
-
That looks pretty nice! And any reasons you're giving up on it? I've had something similar in the work, that also handles the string UUID and the extra unknown values from the table, but issues with utf-8/utf-16 handling on windows and the fact that the MSVC C++ stdlib is broken are holding me back. (That, and I also keep messing up my git branches by editing things unrelated to the current "topic" of the branch all the time.. I can't github flow ^^; ) I've also looked at using the stdlib's codecvt header, but thing is, MSVC doesn't support specialized string literals.. And the examples won't build.. And its all pretty unclear how it works. (And for some reasons my Codelite install can't use clang or gcc to compile..) I've been looking at using ICU, but the build requirements are ridiculous.. I'd need to ship a full cygwin environment with it just to build on windows(or a script that setups said environment), and the library is huge.. http://source.icu-project.org/repos/icu/icu/trunk/readme.html#HowToBuildWindows I might just use POCO's utf-8 utf-16 handling tools instead.. But they recommend using ICU instead.. Long story short, if anyone is ever looking at handling utf encoded text, don't use C++.. At least, until they add proper support in the few next revisions hopefully.. EDIT: Also, have you checked your PMs?
-
That's pretty much the usual SIR0 format. The part below that begins with 0x04 0x04 is not another header, its the encoded pointer list. SIR0 is just a wrapper around data, the content itself is what differ. Its used on stuff that gets loaded directly to memory as a data structure to translate pointers from relative to the file, to relative to the system memory. http://www.projectpokemon.org/wiki/Pmd2_SIR0 I forgot to link my notes on it in this thread. But in GTI its exactly the same thing as it was in Rescue Team, and Explorers.
-
You know, I wouldn't even be surprised.. Everything on this damn thing is encrypted.. My main source of info is GBATemp/reddit/random rom website and between threads people either keep contradicting eachothers, or just don't talk about those things. It seems to me that all the info on the 3DS online is really unreliable, outdated, or incomplete. Though, lower firmware 3ds aren't on sale anymore AFAIK. I've been looking around for one, and I can't find anything that isn't outrageously expensive.(factory sealed stuff..) And trying to get one used with a specific firmware is asking to get scammed. I might just give up looking for PSMD's decrypted data at this point. I've been wasting way too much time on that. And I'll probably have to wait until citra can run things better to do anything in-depth with GTI.. EDIT: In other news, I think I finally got the basics of the FARC format figured out, in comparison to my original post on page1 : https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/PMD_GTI/FileFormats/FARC_archive.txt
-
Well, that's good to hear that some formats are similar! But, what about the rest, is it still mostly the same? I don't think the filenames were part of the FARC format though. They were in a SIR0 container on their own. It probably just means that they're using something different than filenames to refer to game resources now. Possibly by GUIDs? I mean, considering the game text is stored in text databases and each entries are referred to by GUID. Its funny though, because EMD still has that SIR0 with the filenames. They might have changed things a bit.. But, I don't have the PSMD game files yet, so I can't take a look.. (No decrypted rom anywhere to be found.. I'm considering getting my 3ds hard modded with a microSD adapter, to make a forced firmware downgrade..) That's all good. And, that brings up something I completely forgot about ^^; I'd better add a notice telling people to hide PSMD spoilers in this thread!
-
I'd have posted the link to your post sooner if I knew you'd come and post here But seriously, that really helpful! thanks ! That looks like its very similar to how it was in Explorers of Sky! Though, the data was encoded/shortened in EoS. Nice! I've been looking for where they were storing the pokemon names for a while! Also, its possible that grade.bin is for the paradise ranks. There's a lot of engrish used in the game files (The scripts are particularly filled with engrish ) That sounds also very similar to EoS's waza_p.bin file. And its all good, French is my first language so I didn't have too much issues, even though some names are just completely different in French. (I usually play the games in english though) Alright. And my code is terrible too, but I post it anyways You never know, it might be helpful to some people.
-
So, the PSMD dump is out, but as expected they dumped it encrypted, because it works better on some flashcarts. So yeah... Anyways, Idk if SciresM is going to answer my post + pm, but in the meantime, I stumbled on this a while ago on the forums : http://projectpokemon.org/forums/showthread.php?43617-Gates-to-Infinity-From-IMG-file-to-PNG Which would probably come in handy. I've also been taking apart the game text, but the annoying thing about those is that, they're stored using unique hashes to refer to them.. Oddly enough, those appear to be language independent since they're placed directly into the script files to refer to particular strings. But the thing is, Idk how those hashes are computed, or if they're just GUID, and not actual hashes.. But I have very little experience with custom hash maps, so its a bit hard for me to figure this out. If anyone with experience on those would want to take a look it would be appreciated! Here are my notes on the format: https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/PMD_GTI/FileFormats/string_database.txt Those files are found under the /message/ directory, they all have the .bin extension, as they're just SIR0 containers meant to be loaded in memory directly. They're loaded in scripts by filenames via the MENU:LoadMenuTextPool function, and then they're referred to by number in a variety of function. The decompiler doesn't seem to differentiate between what's a GUID/hash or not, so the values are represented as very large, signed, decimal numbers and are easy to spot really.
-
I released the new gui for statsutil : https://github.com/PsyCommando/ppmdu_gui_frontends/releases/download/ppmd_statsutil_0.21_gui_0.20/ppmd_statsutil_0_21_gui_0_20.7z If I can get some feedback on it, I'll make a proper release with a readme and all I got rid of the rom extraction/rebuilding, because it caused a lot of problems, and it made no sense, considering someone modifying the game probably won't only change some text strings and statistics.. I might make a project manager app, eventually. Something very simple that doesn't get in the way and would allow people to edit the game file with any means they want and and just repack everything in a single click. Also, I've been trying to help with script research lately, because on one hand it will allow me to edit the game dialog stored within the script files, and on the other, it means we'll be able to do more with the game if I do find something. Also, I'm still looking for information on how to translate the values in the NDS's sound registers into volume units. And I haven't heard back from anyone I asked questions on that matter to. And the documentation on the NDS DSP is pretty shallow apparently..
-
Well, evandixon is helping with that already. But thanks, I'll keep that in mind. I really need to somehow get an exploitable 3ds, because I just work better when I can test things immediately myself. I'm less afraid of trying things that might crash the game and make the process longer. Though I don't really plan on having any money to spend on that kind of hardware for at least 3 to 6 months.. (I wish I hadn't updated my firmware.. >_<) I'm waiting for a dump too. (But I'll be really lucky if I even find a decrypted one..) However, personally, I don't plan on doing any real datamining in PSMD until the game is released in november, because I doubt there is much interest from most in getting spoilers on a game that won't release for another 2 months, and I don't really want to ruin the game for me ^^; I just want to confirm PSMD uses the "same" engine as GTI. And perhaps poke at the script engine, and any new file formats a bit. Then I can just use GTI and Etrian Mystery Dungeon to develop most things that will be needed for PSMD.
-
So, I realized that I completely overlooked the fact that people might use the program on multiple session.. And I'll have to rethink the whole user interface.. But in the meantime, here's a little temporary fix to make things a little easier: https://github.com/PsyCommando/ppmdu_gui_frontends/releases/download/ppmd_statsutil_0.21_gui_0.11/ppmd_statsutil_0_21_gui_0_11.zip It will automatically check if the rom data was already extracted and set it automatically as rom input path. Which means that you can just import your existing changes and then rebuild the rom.
-
So I found out that the game strings import was completely broken, and I fixed it! https://github.com/PsyCommando/ppmdu/releases/download/ppmd_statsutil_0.21a/ppmd_statsutil_0.21.zip I also spent the day working on a tiny GUI for statsutil. (I also added a bunch of useless features...) : https://github.com/PsyCommando/ppmdu_gui_frontends/releases/download/ppmd_statsutil_gui_0.21/ppmd_statsutil_gui_0.21.zip I got sick of trying to find ndstool's license, after years.. So I just slapped it into the executable, along with the statsutil stuff. Everything is just copied to the current working directory when the program is launched.
-
I finally got a new version of statsutil ready for release! https://github.com/PsyCommando/ppmdu/releases/download/ppmd_statsutil_0.2a/ppmd_statsutil_0.2.zip I added support for item data from Explorers of Sky! Don't use it with Explorers of Time/Darkness. Those are unsupported for now, and will crash the program. I won't write a big announcement post because I'm a bit sick right now, and I have a huge headache. But hopefully, the readme will answer your questions.
-
Lua is very flexible We even edited scripted scenes ! evandixon hasn't uploaded it yet, but I messed with the intro scene and I changed a lot of stuff. It was pretty funny to see Pikachu's head spinning at weird angles It was a bit unstable though. I wonder how accurate the decompiler was.. (Debugging modded scripts is going to be complicated though.. Unless we write a lua ui to place over everything else to display debug messages on, or something like that.. Or just manage to toggle on the debug mode that's mentioned in the scripts.) And I'm sure we could find extra hooks and function to call from the scripts if we'd search the binaries! (Or maybe even some of the ones used in Etrian Mystery Dungeon were already in PMD GTI ?) I'd need a RAM dump to have a better idea though.. It would really beat reading through a decompiled binary. I also wonder if we can't load shared libraries through the lua script, since lua comes with a function for that.. However I don't know much about their ARM lua build.. I know the ARM11 can work with a form of shared libraries, but Idk if its taken in charge in their implementation.. I wish I had a gateway and a 3ds with an old firmware. I could do a lot more testing without pestering anyone On another note, I'm looking for something like Doxygen, but for lua. Just to make a basic documentation of everything! So if anyone else has any suggestions, it would be much appreciated!
-
Nice ! So that means we can modify the game's scripts very easily, without doing anything special ! Wanna try the a modified intro sequence + pokemon choice ? Just start a new game with those: This one may crash at one point.. Idk if I added pokemons the correct way. But I messed around with the neck rotations and etc It should be much more interesting and conclusive than moving the menu elements around ! script_EditedIntro_and_pokechoice.zip
-
Pokémon Mystery Dungeon: Gates to Infinity
psy_commando posted a technical document in Mystery Dungeon 3DS
General Information This page contains data on the Pokémon Mystery Dungeon: Gates to Infinity game. File Structure Script Engine Details The Script engine of PMD:GTI uses compiled lua 5.1 scripts. List of all function, objects, and globals : Here File/Data Formats Container Format BIN(FARC) Image Data IMG Game Strings BIN(GameStrings) Script Engine Formats LUA Files with Unique Formats External Resources -
General Information The SMDL format is a container for sequenced music. Its very close to the MIDI format, similarly to the SSEQ format normally used in most NDS games. File Structure Overview Offset Length Name Description 0x0 64 SMDLHeader The container's header. 0x40 64 Song Chunk Information on the entire sequence. After Song Chunk Varies Trk Chunk The first Track of the sequence. Its role is to set the tempo. ..Additional tracks here.. After all Track Chunks 16 End of Content Chunk This empty chunk marks the end of the SMDL container. SMDL Header Total length 64 bytes Offset Length Type Name Description 0x00 4 char[4] magicn The 4 characters "smdl" {0x73,0x6D,0x64,0x6C} 0x04 4 - unk7 4 bytes of zeroes. 0x08 4 uint32 flen File length in bytes. 0x0C 2 uint16 version? Version number? ( 0x1504 ) 0x0E 1 uint8 unk1 Unknown. 0x0F 1 uint8 unk2 Unknown. 0x10 4 - unk3 4 bytes of zeroes. 0x14 4 - unk4 4 bytes of zeroes. 0x18 2 uint16 year Year the file was last modified. 0x1A 1 uint8 month Month the file was last modified. 0x1B 1 uint8 day Day the file was last modified. 0x1C 1 uint8 hour Hour the file was last modified. 0x1D 1 uint8 minute Minute the file was last modified. 0x1E 1 uint8 second Second the file was last modified. 0x1F 1 uint8 centisecond? Could possibly be the centisecond that the file was last modified. 0x20 16 char[16] fname Filename, ASCII null terminated string. Any extra space after the 0 on the total 16 bytes, is padded with 0xAA. 0x30 4 uint32 unk5 Unknown, usually 0x1. 0x34 4 uint32 unk6 Unknown, usually 0x1. 0x38 4 uint32 unk8 Unknown, usually 0xFFFFFFFF. 0x3C 4 uint32 unk9 Unknown, usually 0xFFFFFFFF. Song Chunk The song chunk is made of a single header. Song Chunk Header ( Total length 64 bytes ) Offset Length Type Name Description 0x00 4 char[4] label Song chunk label "song" {0x73,0x6F,0x6E,0x67} 0x04 4 uint32 unk1 Unknown. Usually 0x1. 0x08 4 uint32 unk2 Unknown. Usually 0xFF10. 0x0C 4 uint32 unk3 Unknown. Usually 0xFFFFFFB0. 0x10 2 uint16 unk4 Unknown. Usually 0x1. 0x12 2 uint16 tpqn Ticks Per Quarter Note? Usually 0x30 or 48 ticks per quarter note. (Works like MIDI clock ticks it seems.) Or possibly just the tick rate.. 0x14 2 uint16 unk5 Unknown. Usually 0xFF01 0x16 1 uint8 nbtrks Number of track(trk) chunks 0x17 1 uint8 nbchans Number of channels. (Unsure how channels works with DSE) 0x18 4 uint32 unk6 Unknown. Usually 0x0F000000 0x1C 4 uint32 unk7 Unknown. Usually 0xFFFFFFFF 0x20 4 uint32 unk8 Unknown. Usually 0x40000000 0x24 4 uint32 unk9 Unknown. Usually 0x00404000 0x28 2 uint16 unk10 Unknown. Usually 0x0200 0x2A 2 uint16 unk11 Unknown. Usually 0x0800 0x2C 4 uint21 unk12 Unknown. Usually 0xFFFFFF00 0x30 16 - unkpad Unknown sequence of 16, 0xFF bytes. Possibly padding? Trk Chunk Track chunks contain the events for each individual tracks of the music sequence. They work much like MIDI tracks. Header Offset Length Type Name Description 0x00 4 char[4] label Track chunk label "trk\0x20" {0x74,0x72,0x6B,0x20} 0x04 4 uint32 param1 Unknown. Usually 0x01000000. 0x08 4 uint32 param2 Unknown. Usually 0x0000FF04. 0x0C 4 uint32 chunklen Length of the trk chunk. Starting after this field, to the first 0x98 event encountered in the track. The length is in bytes. The content begins immediately after the header! Preamble Each tracks has a short preamble after the header, and before the actual events. That preamble indicates the channel and the track id assigned to the track. Offset Length Type Name Description 0x00 1 uint8 trkid The track ID of the track. A number between 0 and 0x11. 0x01 1 uint8 chanid The channel ID of the track. A number between 0 and 0x0F?. 0x02 1 uint8 unk1 Unknown. Often 0. 0x03 1 uint8 unk2 Unknown. Often 0. Events All tracks must have a 0x98 event at their end. And the size of a track is counted up to that event, ignoring the padding bytes. Events themselves are not aligned on 4 bytes. Offset Length Type Name Description After Preamble varies - events Track events begin here. After Events 0-3 - Padding Padding to align the end of the track on 4 bytes. The value is usually the terminating 0x98 byte repeated as needed, up to 3 extra times. Example Here's an example "Events" section (it does not include the preamble and header): E3 73 A4 82 93 E0 1F 98 It ends on an offset divisible by 4, so there is only a single 0x98 event at the end. Here's what would happen if we'd add an extra events. Lets copy the 0xE3 event and its parameter once: E3 73 E3 73 A4 82 93 E0 1F 98 98 98 ..we needed to add 2 extra 0x98 events to make the track end on an offset divisible by 4! Eoc Chunk The EoC chunk marks the end of the SMDL file/container. Total length 16 bytes Offset Length Type Name Description 0x0 4 - ChunkID The chunk ID "eoc\0x20" {0x65, 0x6F, 0x63, 0x20} 0x4 4 uint32 Param1 Unknown meaning, is often 0x00000001. 0x8 4 uint32 Param2 Unknown meaning, is often 0x04FF0000. 0xC 4 uint32 Length Always 0, for end of content chunks. DSE Events Tracks are filled with events. Each event starts by a single byte containing a code, which indicates to the sequencer what to do. Their value ranges from 0x0 to 0xFF. Values from 0x0 to 0x7F are reserved for the PlayNote event. Values from 0x80 to 0x8F are reserved for fixed duration pause events. Values from 0x90 to 0xFF all have their unique event assigned to them. PlayNote(0x0 to 0x7F) The play note event is special in that its format is particular. The event code itself is the velocity(0x0 - 0x7F) of the note to be played. The first parameter byte is obligatory, and it contains info on whether we modify the track's current octave, how many extra parameters are there, and what note to play. The second parameter is optional, and its length varies depending on the length specified in the obligatory parameter. It contains the duration the key is "held down" before being released. Here's a breakdown of the NoteData byte: Bits Name Meaning 1100 0000 NbParamBytes A value from 0 to 3 which indicates the amount of extra parameter bytes that should be read. 0011 0000 OctaveMod A value from 0 to 3 from which 2 is subtracted. The result is a signed value that we add to the track's current octave. 0000 1111 Note The Note that should be played at the track's current octave(after OctaveMod). Note List Value Note Name 0x0 C 0x1 C# 0x2 D 0x3 D# 0x4 E 0x5 F 0x6 F# 0x7 G 0x8 G# 0x9 A 0xA A# 0xB B 0xF Unknown Example Event[edit] Velocity NoteData (Opt)KeyDownDuration 0x7F 0xE5 0x20 0x01 0x10 This event will play the note F, at the current track octave with no modifications, and hold the note for 0x100120 ticks. Fixed Duration Pause(0x80 to 0x8F) The fixed duration pause is a pause event based on the duration of common musical time intervals. Its event code goes from 0x80-0x8F. Here's a table of the possible durations: Code Musical Time Interval Duration in Ticks 0x80 Half Note 96 0x81 Dotted Quarter Note 72 0x82 2/3 of a Half Note (Half Note as part of a triplet?) 64 0x83 Quarter Note 48 0x84 Dotted 8th Note 36 0x85 2/3 of a Quarter Note (Quarter Note as part of a triplet?) 32 0x86 8th Note 24 0x87 Dotted 16th Note 18 0x88 2/3 of a 8th Note (8th Note as part of a triplet?) 16 0x89 16th Note 12 0x8A Dotted 32nd Note 9 0x8B 2/3 of a 16th Note (16th Note as part of a triplet?) 8 0x8C 32nd Note 6 0x8D Dotted 64th Note 4 0x8E 2/3 of a 32nd Note (32th Note as part of a triplet?) 3 0x8F 64th Note 2 Others(0x90 to 0xFF) Here is a list of all known events : Code Parameter Length Parameters Name Description 0x90 0 - RepeatLastPause Pause the track processing for the duration of the last pause.(Includes fixed duration pauses) 0x91 1 (uint8)Duration AddToLastPause Pause the track processing for the duration of the last pause + the duration in ticks specified.(Includes fixed duration pauses) 0x92 1 (uint8)Duration Pause8Bits Pause the track processing for the duration in ticks. 0x93 2 (uint16)Duration Pause16Bits Pause the track processing for the duration in ticks. 0x94 3 (uint24)Duration Pause24Bits Pause the track processing for the duration in ticks. 0x95 1 (uint8)CheckInterval PauseUntilRelease Pause the track processing as long as a note is held down. Will wait for at least "CheckInterval" ticks, then checks every "CheckInterval" ticks if all notes have been released on the current track. 0x96 0 - INVALID Disable current track. 0x97 0 - INVALID Disable current track. 0x98 0 - EndOfTrack Marks the end of the track. Is also used as padding to align the end of the track on 4 bytes. 0x99 0 - LoopPoint Marks the point the track will loop to after the end of track is reached. 0x9A 0 - INVALID Disable current track. 0x9B 0 - INVALID Disable current track. 0x9C 1 ?? ?? ?? 0x9D 0 ?? ?? ?? 0x9E 0 ?? ?? ?? 0x9F 0 - INVALID Disable current track. 0xA0 1 (uint8)Octave SetTrackOctave Sets the current track's octave to the value specified. Valid range is 0 - 9. 0xA1 1 (uint8)Octave AddToTrackOctave Adds the value specified to the current track octave. 0xA2 0 - INVALID Disable current track. 0xA3 0 - INVALID Disable current track. 0xA4 1 (uint8)TempoBPM SetTempo Sets the track's tempo in beats per minute. 0xA5 1 (uint8)TempoBPM SetTempo Sets the track's tempo in beats per minute? (The code is identical to 0xA4) 0xA6 0 - INVALID Disable current track. 0xA7 0 - INVALID Disable current track. 0xA8 2 ?? ?? ?? 0xA9 1 ?? ?? ?? 0xAA 1 ?? ?? ?? 0xAB 0 - SkipNextByte Skips the next byte in the track. 0xAC 1 (uint8)ProgramID SetProgram Change the track's program(Instrument Preset) to the one specified. 0xAD 0 - INVALID Disable current track. 0xAE 0 - INVALID Disable current track. 0xAF 3 ?? ?? ?? 0xB0 0 ?? ?? ?? 0xB1 1 ?? ?? ?? 0xB2 1 ?? ?? ?? 0xB3 1 ?? ?? ?? 0xB4 2 ?? ?? ?? 0xB5 1 ?? ?? ?? 0xB6 1 ?? ?? ?? 0xB7 0 - INVALID Disable current track. 0xB8 0 - INVALID Disable current track. 0xB9 0 - INVALID Disable current track. 0xBA 0 - INVALID Disable current track. 0xBB 0 - INVALID Disable current track. 0xBC 1 ?? ?? ?? 0xBD 0 - INVALID Disable current track. 0xBE 1 ?? ?? ?? 0xBF 1 ?? ?? ?? 0xC0 1 ?? ?? ?? 0xC1 0 - INVALID Disable current track. 0xC2 0 - INVALID Disable current track. 0xC3 1 ?? ?? ?? 0xC4 0 - INVALID Disable current track. 0xC5 0 - INVALID Disable current track. 0xC6 0 - INVALID Disable current track. 0xC7 0 - INVALID Disable current track. 0xC8 0 - INVALID Disable current track. 0xC9 0 - INVALID Disable current track. 0xCA 0 - INVALID Disable current track. 0xCB 0 - SkipNext2Bytes Skip the next 2 bytes in the track. 0xCC 0 - INVALID Disable current track. 0xCD 0 - INVALID Disable current track. 0xCE 0 - INVALID Disable current track. 0xCF 0 - INVALID Disable current track. 0xD0 1 ?? ?? ?? 0xD1 1 ?? ?? ?? 0xD2 1 ?? ?? ?? 0xD3 2 ?? ?? ?? 0xD4 3 ?? ?? ?? 0xD5 2 ?? ?? ?? 0xD6 2 ?? ?? ?? 0xD7 2 (uint16)Bend PitchBend Bend the pitch of the note. 0xD8 2 ?? ?? ?? 0xD9 0 - INVALID Disable current track. 0xDA 0 - INVALID Disable current track. 0xDB 1 ?? ?? ?? 0xDC 5 ?? ?? ?? 0xDD 4 ?? ?? ?? 0xDE 0 - INVALID Disable current track. 0xDF 1 ?? ?? ?? 0xE0 1 (int8)TrackVolume SetTrackVolume Change the track's volume to the value specified. (0x0-0x7F) 0xE1 1 ?? ?? ?? 0xE2 3 ?? ?? ?? 0xE3 1 (int8)TrackExpression SetTrackExpression Change the track's expression(secondary volume) to the value specified. (0x0-0x7F) 0xE4 5 ?? ?? ?? 0xE5 4 ?? ?? ?? 0xE6 0 - INVALID Disable current track. 0xE7 1 ?? ?? ?? 0xE8 1 (int8)Pan SetTrackPan Change the track's pan to the value specified. (0x0-0x7F. 0x40 is middle, 0x0 full left, and 0x7F full right ) 0xE9 1 ?? ?? ?? 0xEA 3 ?? ?? ?? 0xEB 0 - INVALID Disable current track. 0xEC 5 ?? ?? ?? 0xED 4 ?? ?? ?? 0xEE 0 - INVALID Disable current track. 0xEF 1 ?? ?? ?? 0xF0 5 ?? ?? ?? 0xF1 4 ?? ?? ?? 0xF2 2 ?? ?? ?? 0xF3 3 ?? ?? ?? 0xF4 0 - INVALID Disable current track. 0xF5 0 - INVALID Disable current track. 0xF6 1 ?? ?? ?? 0xF7 0 - INVALID Disable current track. 0xF8 0 - SkipNext2Bytes2 Skips the next 2 bytes in the track. 0xF9 0 - INVALID Disable current track. 0xFA 0 - INVALID Disable current track. 0xFB 0 - INVALID Disable current track. 0xFC 0 - INVALID Disable current track. 0xFD 0 - INVALID Disable current track. 0xFE 0 - INVALID Disable current track. 0xFF 0 - INVALID Disable current track. Credits TruePikachu for some of the details on the SMDL format! [1] The unknown Japanese author of the "smd2mid v0.10" utility floating around the web.
-
Procyon Studios Digital Sound Elements
psy_commando posted a technical document in Mystery Dungeon NDS
General Information The Digital Sound Elements sound driver is an audio engine for games on the Nintendo DS, and Wii. It supports sequenced music and streamed audio. It was used by several games on the NDS including Pokémon Mystery Dungeon : Explorers of Sky/Time/Darkness. This article will focus mainly on the implementation in PMD2 however. Known Versions So far, two versions of the DSE engine have been spotted in NDS games. Version Number Description 0x415 Most common version. Used in all versions of PMD2. 0x402 Much rarer version. Used only in the game Luminous Arc this far. Only the format of SWDL containers seems to differs significantly between versions this far. Inner Workings The sound driver adds a few layers of extra processing over the data fed to the audio registers of the NDS. Memory Structure The system creates 2 chunks in memory, the "mseq", and "mdev" chunks. They're only labeled as such in a few games using DSE, like PMD2. In other games, like Fushigi no Dungeon - Fuurai no Shiren DS 2 and Professor Layton and the Last Specter, the labels are not there in memory. The "mseq" chunk contains a set of sequencer wide variables, like counters and such, along with data structs for holding the state of each tracks during playback. The "mdev" chunk contains a set of channels wide variables, and data structs for every sound channels the driver has. Those structs hold the state for each channels during playback. Apart from this, the smdl and swdl for a track currently playing are copied once to memory. And then the entries in the swdl for samples, and program splits are copied and any overridable properties samples have are overriden by the program split's shared properties, like volume envelope and etc..(See swdl structure) Code Structure (Offsets are from the North American Explorers of Sky game's disassembled game code, not the ROM !!!) The channels state are updated at line 0x0207448C. A loop begins further down. And the track Volume envelopes are updated here: 0x02074E0C The function that updates the sequencer tracks begins at 0x020713E8. The actual loop begins at 02071648. The function that parses DSE events begins at 0x02071224. The table containing the function pointers for all DSE events begins at 0x020B0B90. File/Data Formats The system uses the following formats: swdl : Container for programs/presets data, and optionally sample data, used by the sequencer engine. smdl : Container for sequenced music. sedl : Container for sequenced sound effects, and sound presets/programs. sadl : Container for streamed audio. File Layout Game using DSE can store the various container formats in many different ways. Here are some of the known approaches: PMD2 : There is a main sample bank called bgm.swd, which is referred to by the SWDL files accompanying every SMDL music sequences file. Each SWDL contains only program/presets data, and refers to samples from the main bank. Fushigi no Dungeon - Fuurai no Shiren DS 2 - Sabaku no Majou : Here, the SMDL and SWDL are stored in their own separate folder. They're loaded in pair, just like PMD2, but there is no main bank. Instead sample data is stored within every SWDL. Which result in lots of duplicate samples throughout all SWDL. Zombi Daisuki: This game uses SMDL+SWDL pairs as well, without a main bank. But instead of having the SMDL and SWDL for a single music track stored in their own respective file, they're both stored within a SIR0 container, with the extension ".sd". Professor Layton and the Last Specter: This game works like PMD2, it has a main bank, however, all its SMDL + SWDL pairs are stored within an archive "ll_common.darc". And oddly enough, there are 2 copies of the main bank! One is named "bgm_common.SWD" and is stored outside the "ll_common.darc" archive, while the other is named "BG.SWD" and stored within the archive. External Resources Official Website (in Japanese) [1] -
That should be mostly doable. Though I haven't tested adding more pokemon. And you'd have to ask Nerketur about dungeons and story event-related stuff. He's working on a PMD2 script editor. But, I guess it might be possible to make a few tweaks to the game code to increase the amount of pokes in the game if we ever need to. We'd need some more testing.. The main problem is the way the stats file is made, and the way portraits are stored. Because pokemons are stored as entities, and there is 2 entities per regular pokemon, one for the male, and one for the female (There are invalid entities for genderless pokes and single gender pokemon). But the thing is that, half of the list is made of the male pokes, and the the other half is made of the female pokemon.. Which means that we'd need to shift the point where female pokemon entities begins from.. And I'm not sure what it implies.. Maybe its really stupidly simple though.. It might be possible.. At least I know you can absolutely move the camera, either by editing possibly a script, or just directly in memory. But I don't know if the graphic engine will render the level further around the characters.. Again, that's something to test. The models and animations are definitely possible. I'm working in my other thread on reversing those among other things!
-
I made some more research with DSE events. I'm trying to map the DSE memory. And find out what most events do. I'm also working on a big cleanup of my code, so hopefully I can get statutil out next, and then get back into gfxutils. I also found a nice pun to name an editor as.. So I might as well try to make one now XP It might end up being for PSMD / GTI though. It depends really on what's left to cover. And here are a few things I found on some events: 0x95, takes a duration in ticks as a byte, and its a wait loop that checks every nth ticks if the track is still playing a sample/has still a key pressed. Event 0x96, along with every other events that directs to line 0x0207191C just disable the track completely. Here's the complete list of invalid/track disabling events: [font=Fixedsys]0x96 0x97 0x9A 0x9B 0x9F 0xA2 0xA3 0xA6 0xA7 0xAD 0xAE 0xB7 0xB8 0xB9 0xBA 0xBB 0xBD 0xC1 0xC2 0xC4 0xC5 0xC6 0xC7 0xC8 0xC9 0xCA 0xCC 0xCD 0xCE 0xCF 0xD9 0xDA 0xDE 0xE6 0xEB 0xEE 0xF4 0xF5 0xF7 0xF9 0xFA 0xFB 0xFC 0xFD 0xFE 0xFF[/font] I also found out something funny about event 0x9C.. If you call it in a looping track, it will eventually corrupt the pointer to part of the sequencer's memory I still have no ideas what its for though.. I don't think you can really turn it into GTI, if I understand what you mean. Core gameplay and most in-game menus appear hard-coded. You'd need to inject some code in there on your own. Though it will eventually be possible to turn GTI or even PSMD into something close to EoS if someone really wanted. Those two use a lua script engine, and a significant part of the game is in script form, menus, debug routine, cutscenes, and etc.. Most of the stats data is loaded via script too. Not to mention that, with lua you could probably do way more than what they did !
-
That reminds me. I forgot I had only a few things to fix to get statutil out.. I wish I wouldn't leave things half-done all the time.. And honestly I don't really know. But, the 3ds mods won't be very useful until we either get a good, easy, stable exploit, or a 3ds emulator actually gets decent enough.
-
Well, have you tried with only a single decompiled file? Because the decompiler might not be perfect. So if you only decompile a single one, you reduce the chances of that interfering. The best thing to do would be to try it a few times with small files and see what happens. EDIT: Also, have you tried to rebuild the rom without changes and testing it ? maybe something went wrong during repacking? EDIT2: If that also doesn't work, here's a recompiled "menu_top.lua" file to try out if it works with recompiled script files : script.zip
-
Apparently the volume calculation sums up to this.. ( ( ( ( (( 0x7F * (( ((0x7F * (0x64 * 0x73)) >> 31) + ( (0xFFFFFFFF00000000 & ( (0x7F * (0x64 * 0x73)) * 0x82061029 ) + (0x7F * (0x64 * 0x73))) >> 13 ) ) * ( SampleVolume + (0>>6) )) ) >> 31) + ( ( 0x7F * (( ((0x7F * (0x64 * 0x73)) >> 31) + ( (0xFFFFFFFF00000000 & ( (0x7F * (0x64 * 0x73)) * 0x82061029 ) + (0x7F * (0x64 * 0x73))) >> 13 ) ) * ( SampleVolume + (0>>6) )) ) + ( ( 0xFFFFFFFF00000000 & ( 0x828CBFBF * (0x7F * (( ((0x7F * (0x64 * 0x73)) >> 31) + ( (0xFFFFFFFF00000000 & ( (0x7F * (0x64 * 0x73)) * 0x82061029 ) + (0x7F * (0x64 * 0x73))) >> 13 ) ) * ( SampleVolume + (0>>6) ))) ) ) ) >> 12 ) ) * (( 0x7F * (( ((0x7F * (0x64 * 0x73)) >> 31) + ( (0xFFFFFFFF00000000 & ( (0x7F * (0x64 * 0x73)) * 0x82061029 ) + (0x7F * (0x64 * 0x73))) >> 13 ) ) * ( SampleVolume + (0>>6) )) ) >> 31) + ( ( 0x7F * (( ((0x7F * (0x64 * 0x73)) >> 31) + ( (0xFFFFFFFF00000000 & ( (0x7F * (0x64 * 0x73)) * 0x82061029 ) + (0x7F * (0x64 * 0x73))) >> 13 ) ) * ( SampleVolume + (0>>6) )) ) + ( ( 0xFFFFFFFF00000000 & ( 0x828CBFBF * (0x7F * (( ((0x7F * (0x64 * 0x73)) >> 31) + ( (0xFFFFFFFF00000000 & ( (0x7F * (0x64 * 0x73)) * 0x82061029 ) + (0x7F * (0x64 * 0x73))) >> 13 ) ) * ( SampleVolume + (0>>6) ))) ) ) ) >> 12 ) ) + ( ( ( (( 0x7F * (( ((0x7F * (0x64 * 0x73)) >> 31) + ( (0xFFFFFFFF00000000 & ( (0x7F * (0x64 * 0x73)) * 0x82061029 ) + (0x7F * (0x64 * 0x73))) >> 13 ) ) * ( SampleVolume + (0>>6) )) ) >> 31) + ( ( 0x7F * (( ((0x7F * (0x64 * 0x73)) >> 31) + ( (0xFFFFFFFF00000000 & ( (0x7F * (0x64 * 0x73)) * 0x82061029 ) + (0x7F * (0x64 * 0x73))) >> 13 ) ) * ( SampleVolume + (0>>6) )) ) + ( ( 0xFFFFFFFF00000000 & ( 0x828CBFBF * (0x7F * (( ((0x7F * (0x64 * 0x73)) >> 31) + ( (0xFFFFFFFF00000000 & ( (0x7F * (0x64 * 0x73)) * 0x82061029 ) + (0x7F * (0x64 * 0x73))) >> 13 ) ) * ( SampleVolume + (0>>6) ))) ) ) ) >> 12 ) ) * (( 0x7F * (( ((0x7F * (0x64 * 0x73)) >> 31) + ( (0xFFFFFFFF00000000 & ( (0x7F * (0x64 * 0x73)) * 0x82061029 ) + (0x7F * (0x64 * 0x73))) >> 13 ) ) * ( SampleVolume + (0>>6) )) ) >> 31) + ( ( 0x7F * (( ((0x7F * (0x64 * 0x73)) >> 31) + ( (0xFFFFFFFF00000000 & ( (0x7F * (0x64 * 0x73)) * 0x82061029 ) + (0x7F * (0x64 * 0x73))) >> 13 ) ) * ( SampleVolume + (0>>6) )) ) + ( ( 0xFFFFFFFF00000000 & ( 0x828CBFBF * (0x7F * (( ((0x7F * (0x64 * 0x73)) >> 31) + ( (0xFFFFFFFF00000000 & ( (0x7F * (0x64 * 0x73)) * 0x82061029 ) + (0x7F * (0x64 * 0x73))) >> 13 ) ) * ( SampleVolume + (0>>6) ))) ) ) ) >> 12 ) ) >> 8 ) >> 23 ) >> 9 ) ;_; So many shifts.. Now I need to simplify.. The result is 0x3F btw.. Thanks. But, not so much has been done really. That's just the music format we've been working on lately. Still, we're pretty far from importing midis and sample data back into the game.. If we could make some breakthroughs in the following areas, we'd be much closer to an actual devkit for pmd2 : - Sprite files - Map tiles - Scripts - Dungeon data files To make a level editor, probably the most important part, we'll need to support fully the sprite and tile format, and have a better understanding of the scripts. And right now I have no ideas when we're going to make breakthroughs like that.. It would help if we weren't only ~3 doing that
-
hmm.. Well crap.. I thought I could buy one for myself, but I'm on 9.9 now.. >_< Well, from what I read on GBATek, the ARM7 is pretty much unused when running NDS software. Its mainly used while running GBA games. Otherwise it apparently does some audio processing, and possibly a few things on the side.(Though, most of the audio processing stuff I saw was handled on the NDS9..) I think I read somewhere in a homebrew game tutorial that the NDS9 didn't have interrupts for all buttons, and that some button had to be accessed through the other processor, or something along those lines.. Also, apparently that the Nitrosdk wouldn't let developers run anything on the NDS7 themselves. Sounds good ! If that doesn't work feel free to improvise Any info we can get on the game would be very useful! In other news, I figured out the format for the game strings: https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/PMD_GTI/FileFormats/string_database.txt Having the scripts decompiled helped a bunch! It made me realize that they're referring to strings through 32bits hashes/uid. (unluac interpret them as signed 32bits integer in the scripts) I validated by looking at what string db file they were loading in a particular script, and tried to find the hash of a string from the script in the db file. I was able to find exactly the values I was looking for, so I guess it works