Jump to content

waffleoRai

New Member
  • Posts

    4
  • Joined

  • Last visited

Reputation

2 Neutral
  1. UPDATE Got it! I think. For the sake of anyone who might come across this in the future and doesn't already know, here's the trick. For some baffling reason, GF decided to basically encrypt the pokemon battle sprites (like someone who really wanted to rip them wouldn't just dump from an emulator VRAM, but okay). I really should have been able to tell from looking that the data were scrambled/encrypted, but I didn't really know why they would bother encrypting DS assets stored in a standard format...? Weird. The encryption method appears to be the same as the one used for DP save files. Only the actual pixel data in the RAHC block is encrypted, which is why the rest of the NCGR looks normal. The decryption seed for the PRNG is the last word in the encrypted data. The algorithm goes word by word backwards from there until it gets to the start of the data. Words are read Little-Endian. I seemed to get the proper results by xor-ing with the lower 16 bits of the PRNG output, not the upper like the linked doc suggests. Had to pop PokeDsPic DP into ILSpy to get that answer. So thanks to the dev of PokeDsPic! None of the other DS tools I tried seemed to be able to read these sprites. No idea if this exact algorithm is used for Pt, HGSS, or Gen V since I haven't checked yet. They are definitely obscured though - least I got scrambled garbage when I tried to look at battle sprites in these other games.
  2. Hey! I'm working on some code to dump sprites of interest from pokemon ROMs (my goal is to add it to my own tools - I do not need a tool that does ROM editing or reading and I do not need an existing sprite dump) and since I already had various Nitro format parsing code from my file explorer I thought I would start with Diamond/Pearl (specifically, my copy of Diamond). I've had no issue with the majority of NCGR and NCLR files, can read NARC files just fine, LZ decompression seems to work just fine. However, there's a ton of totally normal looking NCGRs (from hex view) that when dumped to png seem to produce nothing but garbage static. I tried reading them linear, I tried reading them tiled, I tried all kinds of wacky combinations of tile sizes and image dimensions. Garbage. I thought I might have a really weird bug in my program, so I decided to try viewing them with Tinke.... and got the exact same thing! On one hand, good to know I am not completely crazy, but on the other hand this would imply that either Diamond is full of garbage image data or there's some other trick you need to do to read the image data that isn't indicated in the NCGR file itself. Are there higher level sprite/tile maps (NCER etc) that map pixel-by-pixel rather than by tile? Why have a NCGR at all then? The files I'm looking at are in poketool/pokegra/pokegra.narc. Generally, I am having a lot of difficulty finding clear documentation on the location of the various pokemon sprites for DPPt (eg. battle sprites) and potential quirks like this with their formatting. Maybe it's just something that's known in the community so nobody feels the need to write it up? Maybe it's just hard to look up (always get buried with existing spritesheets when try to search)? I dunno, all I can think of now is to just troll through random bin files for tables or run game in emulators and look at RAM/VRAM dumps. Maybe dig through the code of an open source pokemon gen IV specific sprite extractor/injector tool? I just feel so stupid running around in circles over this problem that seems obvious and has been solved for 15+ years... Anyway, any help would be appreciated - even redirecting me to an old post asking the same question! Thanks! -B
  3. The oscillators are partially implemented for playback, but not for SF2 export. I think the volume and pan oscillators are working (need to properly test) for playback. For pitch and LPF(?) the oscillator value calculation works for all wave shapes, but the interpolator can't handle extremely rapid pitch changes at the moment (I intend to debug this at some point because it's kind of a big problem, think it has to do with the counter resetting), so the code that loads the pitch oscillators into a playback sample is currently commented out. LPF oscillators aren't implemented beyond the general oscillator value calculation, and that's also because I did something wrong writing my LPF classes causing them to output silence. Now I think I might be able to encode the oscillators in SF2 as modulators, but the only reason I haven't thus far is laziness. There's also a weird bug with pan scaling and the envelopes are a rough estimate for now. Other than that, seems to work alright. I'm able to open the resulting files in Polyphone and play them back nicely. Just needs a bit of tweaking to sound as accurate as possible. I definitely intend to fix/add these things, just haven't done so yet. The explorer GUI tool is here. I don't really consider it polished enough to officially "release" quite yet (especially since my last few changes broke it), but I like using GitHub to bounce my code between computers cleanly so eh. It's all Java since Java is my crutch language and I keep going "eh, it'll just be a quick little applet, don't need to pull out the C...". I believe the JAR in /jar/ was built before I broke the type detection system, so if you wanted to check out a vastly inferior version of all the existing DS ROM explorers, that should do the trick . It does detect and play back SMD/SWD though (if not still a bit roughly), so that's something! Noooow unfortunately, the SF2 export buttons on the GUI seem to be outputting air for some reason. The issue isn't obvious so might take me a few to figure out why it's not writing anything. Some link is probably broken in the callback chain. However, the conversion and writing methods themselves absolutely work! At least, last I checked! THESE are in my game formats library -- class is waffeoRai_soundbank.procyon.SWD The little main test in the same package (SMDTest) has an example of how to do it since I export to SF2 as a means of debugging soundbanks, but here's basically all you would need to do to call it directly: String swd_waves_path = "mydir/bgm.swd"; //The file containing the wave data String swd_art_path = "mydir/bgm0025.swd"; //The file containing articulation data, here I just picked Apple Woods String sf2_path = "mydir/bgm0025.sf2"; //Open a FileBuffer. This is my file wrapper class that handles multi-byte fields. //The second arg is byte order as a bool (false is LE) FileBuffer filedata = FileBuffer.createBuffer(swd_waves_path, false); SWD swd_war = SWD.readSWD(filedata, 0); //Second arg is offset from file start to begin reading filedata = FileBuffer.createBuffer(swd_art_path, false); //Open the articulation data file SWD swd_art = SWD.readSWD(filedata, 0); //Parse as SWD swd_art.loadSoundDataFrom(swd_war); //Load the sound data from the sound SWD to the articulation SWD swd.writeSF2(sf2_path); Probably with a try/catch to get those I/O and parsing exceptions. And of course since this is all open source, feel free to look at SWD.java and be like "noooo, that's not good". If yall are interested in using this as a converter, I wouldn't mind prioritizing debugging and cleaning up the SWD stuff. I can also just JAR up a dedicated SWD/SWD->SF2 command line tool. For sure, SF2 lacks some flexibility that would be nice to have... I mostly only use it as the "default soundbank conversion target" because it's usually recognized by a lot of programs? Only thing I could get to import into my version of Kontakt. (Attached most recent output of bgm0025.sf2) bgm0025.sf2
  4. Hey! So, swdl format issue. I apologize if this is the wrong place to discuss this, or if this has been brought up before. I did a quick scan of the various docs and notes and didn't see any mention of this, so I thought I'd go ahead and post on the off chance that someone hasn't come across this yet? I've been writing a little ROM explorer for funsies - thought I'd add a swdl/smdl player since I already had a makeshift but working synthesizer and player GUI as well as code for handling smd files (a couple years back decided to do a dump of the EoT BGM to midi because I like messing with the sequences in protools). Getting to the point, the issue is with sound sample tuning. I've been using Apple Woods (bgm0025) as my test track. This is the creepypasta reject I get when playing it: rotten_apples.mp3 I think my interpolator still has some problems, but does play back sseq/sbnk and playstation seq/vab songs without any tuning issues. The most glaring source of the discord I have tracked back to Programs 52 and 53 in bgm0025.swd (which are identical except for the envelopes, I think 53 is the main one and 52 is used for delay tracks). Tabled the tuning values (as read from the fields specified by the https://projectpokemon.org/docs/mystery-dungeon-nds/dse-swdl-format-r14/) for all the non-percussive programs in bgm0025.swd: Included Polyphone's suggested tuning in the last two columns (dumped to sf2 so I could play with tuning directly). It's prone to being wrong on the octave of the root key, but its fine tune suggestions do seem to be pretty close to the actual notes (once root key is corrected for). No coarse tune in Polyphone suggestions. So here's the weird thing I'm confused about. When I modify the "coarse tune" and "fine tune" fields in the file directly on the ROM and run it through an emulator, I get the exact same results as yall - 0x14 appears to control fine tune by cents and 0x15 appears to control coarse tune by semis. But applying the same parameters to an external player does not produce accurate playback. In fact, in the sf2 dump I generated programs 52 & 53 don't even have continuous regions pitch-wise? It's pretty weird. Yet it seems pretty clear that when I modify these fields and put them back in the game, the tuning is affected by about the amounts changed? And then there's the fact that the default coarse tune is -7st, but the song does not play 7st lower than the sequence? I'm wondering, are there values stored elsewhere or loaded with the driver that scale the tuning somehow? I didn't see any obvious currently unknown values in the swd that could be candidates (most unknown bytes are 0x00 or 0xaa), but I'll probably look again. Hoping to probe into it more this week once I get some quality sleep and some more stuff for work projects done. But if this is something that's already well characterized that my tired brain just skimmed over, absolutely feel free to just point me to the appropriate documentation/notes instead! Again, sorry to sort of throw off the groove of this conversation, but this seemed the most prudent thread to bring it up. Feel free to delete it or move it if you need ! EDIT: Got it. Sort of. Seems to be a low level value telling the player how to tune it to the root note relative to the stored sample rate. For a high level smd player, this value can be completely ignored as the weird sample rates of the values account for the fine tuning already. I did try mapping it as one byte coarse tune and one byte fine tune relative to the sample rates and it doesn't quite add up, so wondering if it's a 16-bit LE value meant to be loaded into a voice control register or used directly by the driver? I soooo don't know, I'm just throwing stuff out there. Anyway, that's that. Just thought I'd note that here in case anyone else happens to have the same issue.
×
×
  • Create New...