Jump to content
psy_commando

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

Recommended Posts

Posted (edited)

Mokuroh Dungeon: add the Rowlet-line into Explorers of Sky

 

PMD2EoSRowlet__19521.png.be244bd950f54edd2dbdf3dc0eb72659.png

 

Hi there, ProjectPokémon! This mod adds the Rowlet line into Explorers of Sky. It does not replace any existing mon, but some of the unused dummies in the files.

I wanted to share the results with the forum.

 

Version 2.01: DOWNLOAD

Spoiler
  • The download has folders for portraits and .xml files for all the members of the Rowlet-line. Rowlet and Dartrix are finished, whereas Decidueye still lacks its own sprites.
  • Rowlet has sprites for both normal events of the game and the story. It is designed with it being picked as the starter or partner in mind.
  • Dartrix (and in the future, Decidueye) is in line with the other starters' evolutions: its sprites are thought for normal events. If chosen as the starter, it will do the default walking animation in certain events, just like any other non-starter Pokémon.
  • The Rowlet line personal items are also in, with their effects properly done. The current issue is how to obtain them, being Rowlet's items the only ones available by clearing Zero Isle Center with it (not with any of the evos, just Rowlet). This is basically EoS's endgame sooo...
  • The new Pokémon use their moveset from Ultra Sun and Ultra Moon. Given this is gen 4, certain moves were inevitably removed, such as Leafage. However, for the Rowlet line, it manages to adjust perfectly with the Platinum movesets EoS uses. Beware though that Ominious Wind at level 16 is pretty much broken (but fun for Destiny Tower and such!), might do an alternative version replacing it with Shadow Sneak or rebalancing the moves' levels, idk.
  • These additional Pokémon will not appear in any dungeon at the moment as encounters cannot be modified, so these Pokémon (preferably Rowlet because of the story sprites and portraits) will have to either be your starter or the partner.
  • An issue with the EUR version's English string has been fixed. Lots of important stuff such as typings, attacks or species names had an offset of two entries. This was due to me lazily using the same English.txt for both the US and EU roms, which was a fatal mistake.

 

Installation:

It is recommended to follow the steps in the following spoiler:

Spoiler
  • Create a new Solution for your rom with SkyEditor. We'll use this tool for starter and portrait editing. In case you need a tutorial for initiating those mods, evadinxon explained how it works:
  • Drag the files in the "SkyEditor files" folder into your Portrait mod folder. The latter is found in your SkyEditor solution's folder after creating its respective project (see tutorial above).
  • As for the starters, modify both leader and partner options as you wish. In order to include the Rowlet line, you'll need to put the first dummy right after Giratina's second entry (Rowlet), the second dummy (Dartrix) or the third (Decidueye, though it is unfinished) as an available option. Do not forget to save the starter editing file.

guide1.png.b90e37535807e2d04b5973e984e9cdc0.png

  • Replace the "BaseRom/Raw Files/data/MONSTER" files with the ones provided in the "data/MONSTER" folder of the download link. This step can be made at any time before making the rom in the final step, but it is very important to get it done as it contains all of the Rowlet line's overworld sprites.
  • Next, we are going to make use of psy_commando's StatsUtil tools and tutorial, specifically the ones in the following post. We are not using the StatsUtil utility available in SkyEditor because the strings do not seem to be modified (and thus the new Pokémon would appear as "??????????" which we do not desire).
  • We build the Solution (after saving everything) in SkyEditor, and then we have two options: either drag the new rom into the recently provided "pmd2_modding_setup" folder and extract the rom files following the tutorial, or add manually the edits available in the Starter and Portrait mod folders to our main BaseRom folder (that is, by dragging all Raw Files folders found in those two mods to the one found in BaseRom), then take the new Raw Files to the "pmd2_modding_setup" directory renamed as "rom". I suggest this second method due to issues I had while trying extract the ROM following psy_commando's tutorial, but theoretically both methods should work.
  • Drag the pokenames.txt in the "StatsUtil files (which has two options depending of your ROM: EUR or USA)" folder to the "pmd2_modding_setup" directory, then follow the decompilling step in psy_commando's tutorial.
  • Drop the rest of the files found in "StatsUtil files" again to the "pmd2_modding_setup" directory, then go to romstats/pokemon_data and delete 0537___________.xml (you should now have 0537_Rowlet.xml next to it). This is to avoid any possible problem for having unneccesary files. Another note regarding this step is that we have a 0536_Giratina.xml file. Replacing the old one with ours is required for Rowlet's stats growth, as the program displaces this particular data by one entry. Giratina-O is not affected by this (tested in my most recent EoS run).
  • Press "3a_CompileEverythingAndMakeRom" and the Rowlet-enhanced rom should appear as rom.nds there!

Whereas you can play the whole game perfectly with the two Pokémon added, the mod is still fairly incomplete. Like mentioned before, Decidueye is in the data, but its sprites are the same as Rowlet's (yeah, Dartrix devolves), and some little details (the footprint, or a method outside of Zero Island Center for obtaining the Rowlet line's personal items) need to be implemented. Despite this, I think I managed to both add my favourite Pokémon line and showcase how useful psy_commando's tools (and SkyEditor) can be.

Credits to:

  • psy_commando and evadinxon for their tools, which are the basis of this project.
  • End45, for helping me out with the stats growths, strings issues and species items, and in general still being an huge contributor to the EoS modding scene.
  • The user Nightmare from Pokémon Reloaded: el foro. My sprites are heavily based on his walking, attack and damaged animations.
  • All those who gave (or give, if this post is well received) feedback to my posts.

That is all. If by any chance you want all Rowlet's and Dartrix's graphics separately, it is here.

Edited by Reimu_needs_$$$
  • Thanks 2

Share this post


Link to post
Share on other sites
6 hours ago, SonikkuA/Kinopio said:

How did you add more images? Does the imageindex need to be modified?

Yes. In the Pokémon data, each species has a certain number in SpriteIndex which corresponds to a sprites folder for dungeon (m.attack, m.monster) and outside (m.ground) animations. What is interesting is the possibility of adding new folders after 0598, which is my Rowlet's case (0599). Then assign that number in the SpriteIndex and if the frames were well done (indexed, the right size, etc) your creation will appear accordingly.

Share this post


Link to post
Share on other sites
17 hours ago, SonikkuA/Kinopio said:

How did you add more images? Does the imageindex need to be modified?

Well I'm not making an entirely new slot, just editing an existing one. If I extract with grfxcrunch and add images, repack, the new ones added are glitched as shown image.thumb.png.b4dc2f6bd687b8bd30f2bf556558182b.png
Even though it's supposed to be a 32 by 32 square like this 
0050.png.e8f54ce88d51deda5ad6848f50f53d36.png

Share this post


Link to post
Share on other sites
Posted (edited)

Can't help you much with the sprites editor since it crashed all the time in my computer, so for my sprites I copied Piplup's as a base then modify the sprites, palette and size of some images.

You can always try this with Psyduck: replace all the .xml files in m.ground save the Psyduck sprites and palette for one corresponding to a starter then add the amount of images needed for those files to work (for which I do advise to watch the animations with the editor so you know the ImageIndex for eah sprite). Sure it is not exactly the desired result since you lose Psyduck's normal animations, but you can make a copy of the original then compare both in order to restore them.

Does the editor work well when you save edits? Despite its usefulness I read it was in a beta state.

Edited by Reimu_needs_$$$
  • Like 1

Share this post


Link to post
Share on other sites

Yeah the editor is a bit buggy. Just to edit the pallete it crashes, so I'm forced to use grfxcrunch for that. Doesn't save images if I try to import over the corrupted ones either : / 
As for copying over Piplup, I'll try that

Share this post


Link to post
Share on other sites

Weirdly the offset was really off compared to Piplup. But after a lot of edits to the animation XML I'm almost done!
image.png.d994654f818b3ff149f8598e37cd2ece.png

 image.png.d8acf4afc4edc65eba7b6c57fec7d136.png
Just need to check the quicksand, tumble, lookup, and breathing in anim

Something weird I noticed when editing, the Y axis value is flipped. Negative makes the sprite go up, and vice versa

Anyway, thanks for the help Reimu_needs_$$$

Share this post


Link to post
Share on other sites

@Reimu_needs_$$$ I just tried out your Rowlet mod and it's surprisingly well done but for whatever reason the IQ groups for male and female Rowlets are different seeing that Females have it at group 0 I'm guessing that's unintentional.

Share this post


Link to post
Share on other sites
19 hours ago, XModxGodX said:

@Reimu_needs_$$$ I just tried out your Rowlet mod and it's surprisingly well done but for whatever reason the IQ groups for male and female Rowlets are different seeing that Females have it at group 0 I'm guessing that's unintentional.

Yes it was unintentional, I already updated the download link with the fix. Kinda weird since I recall copypasting the data and forgetting to switch the gender (which already did before as another fix). I guess I hadn't decided on Rowlet's IQ Group back then.

BTW I finished my Rowlet run and only found the following bug, which I figured out today how to solve:

bug1.png.f10862efb2ae07ce172e460c6a7b0004.pngFIXED.png.25cb70da95c2dde4a1aa718b74827ffb.png

First picture happened if you chose Rowlet as your Pokémon, and had to do with this particular sprite's offset being wrongly introduced This fix is also included in the download link.

As a bonus (don't want to brag about it, but...):

arceus.png.507c0f049a0035c88b3c3d0609561442.png

Edited by Reimu_needs_$$$

Share this post


Link to post
Share on other sites

Oh wow I was just going to report that bug.

Also don't tell Arceus you stole his dex number.

Share this post


Link to post
Share on other sites

So I have been attempting to implement new personal items to the game's database, and thus far I had the following issues:

  • These items, which replace unused, empty slots, do not have any effect. In the .xml corresponding to the items' data, I have managed only to introduce their sprite, descriptions, coin value and type.
  • You cannot even mix them in Croagunk's Swap Shop, game does not recognize them (f. ex. Rowlet Wing and Rowlet Card are the 1 star rarity items, but you cannot get Rowlet Tag, the 2 star rarity one). I managed to get the items, however, by clearing Zero Isle Center.

Pics ("Ala Rowlet" is "Rowlet Wing" in Spanish):

items_showcase.png.d25897efae37f5cf7bb88c230837d38b.png     AlaRowlet.png.4208d594f9c9cb509e48507a0967768a.png

Is there any research on this I might have overlooked?

On 2/10/2020 at 3:24 AM, XModxGodX said:

Also don't tell Arceus you stole his dex number.

Yep, did that because it would be weird to have Shaymin at #492 and then jump straight to Rowlet's original #722. Don't think it is an important matter but it is very easy to modify in Rowlet's .xml file regardless.

Edited by Reimu_needs_$$$

Share this post


Link to post
Share on other sites
On 2/11/2020 at 10:58 PM, Reimu_needs_$$$ said:

So I have been attempting to implement new personal items to the game's database, and thus far I had the following issues:

  • These items, which replace unused, empty slots, do not have any effect. In the .xml corresponding to the items' data, I have managed only to introduce their sprite, descriptions, coin value and type.
  • You cannot even mix them in Croagunk's Swap Shop, game does not recognize them (f. ex. Rowlet Wing and Rowlet Card are the 1 star rarity items, but you cannot get Rowlet Tag, the 2 star rarity one). I managed to get the items, however, by clearing Zero Isle Center.

After reading this I went ahead and did some research on the effects of exclusive items. I expected them to be hardcoded and basically impossible to edit, but turns out they are not! You can change the effects of exclusve items or add new ones with some hex editing.
Here's what I found out:

There is a table inside arm9.bin that goes from 0x98568 to 0x98CD9 which contains one entry for every exclusive item in the game, including the last 48 dummy items at the end of the list. Each entry has 2 bytes:

  •     The first one is the ID of the effect the item has, which ranges from 0 to 0x80 (Both included, 0 means no effect)
  •     The second one is used to address the stat buffs table (see below). 0 means the item does not buff any stats.

I guess you replaced some of the unused items, so to give them an effect you just need to go to the part of the table corresponding to the unused entries (It starts at 0x98c80, every entry is 00 00 from that point on) and change the values there for each item.
This is the list of effects: (I have checked only some of the random chances, but it seems that they are always the same for similar effects)

Spoiler

1: Immunity to paralysis
2: Immunity to confusion
3: Immunity to infatuation
4: Immunity to freeze
5: Immunity to critical hits
6: Reduces damage from Selfdestruct and Explosion by 50%
7: Reduces damage from any explosion by 50%
8: Immunity to move sealing
9: Immunity to damage from the weather
a: Immunity to sleep
b: Chance to cause poison, paralysis or sleep after being attacked (30%)
c : Chance to cause poison after being attacked (30%)
d: Chance to leave foe asleep after being attacked
e: Chance to cause a nightmare after being attacked (30%)
f: Chance to cause a burn after being attacked
10: Chance to cause paralysis after being attacked
11: Chance to cause confusion after being attacked (30%)
12: Chance to cause infatuation after being attacked
13: Chance to cause freeze after being attacked
14: Chance to cause shadow hold after being attacked
15: Chance to cause constriction after being attacked
16: Chance to cause cringe after being attacked
17: Chance to cause blindness after being attacked (30%)
18: Chance to seal the move used by foe after being attacked
19: Chance to obtain invisibility after being attacked (30%)
1a: Chance to increase movement speed after being attacked
1b: Chance of being teleported after being attacked if the attack left the pokemon on low HP (50%)
1c: Chance to cause perish song after being attacked (30%)
1d: Chance of reducing foe's speed after being attacked
1e: Reduces damage taken from physical attacks by 50%. Doesn't stack with reflect.
1f: Reduces damage taken from special attacks by 50%. Doesn't stack with light screen.
20: Allows countering physical and regular attacks (Full damage, always happens)
21: Chance to return moves that cause status conditions to foe (60%)
22: Chance to prevent fainting, leaving the pokemon with 1HP instead (50%)
23: Allows countering physical and regular attacks (25% of the damage, always happens)
24: Increases the range of thrown items (Thorns and similar won't stop until they hit something)
25: Chance to return a move to the attacker (20%)
26: Immunity to stat reductions
27: Changes the pokemon's type to one that is resistant to the type of the last move that hit it
28: Protects against status problems under clear weather
29: Protects against status problems under sunny weather
2a: Protects against status problems under sandstorm weather
2b: Protects against status problems under cloudy weather
2c: Protects against status problems under rainy weather
2d: Protects against status problems under hail weather
2e: Protects against status problems under foggy weather
2f: Increases movement speed under clear weather
30: Increases movement speed under sunny weather
31: Increases movement speed under sandstorm weather
32: Increases movement speed under cloudy weather
33: Increases movement speed under rainy weather
34: Increases movement speed under hail weather
35: Increases movement speed under foggy weather
36: Increases attack speed under clear weather
37: Increases attack speed under sunny weather
38: (Most likely increases attack speed under sandstorm weather, untested)
39: (Most likely increases attack speed under cloudy weather, untested)
3a: Increases attack speed under rainy weather
3b: Increases attack speed under hail weather
3c: (Most likely increases attack speed under foggy weather, untested)
3d: Increases evasiveness by 2 levels under clear weather
3e: Increases evasiveness by 2 levels under sunny weather
3f: (Most likely increases evasiveness by 2 levels under sandstorm weather, untested)
40: Increases evasiveness by 2 levels under cloudy weather
41: Increases evasiveness by 2 levels under rainy weather
42: (Most likely increases evasiveness by 2 levels under hail weather, untested)
43: Increases evasiveness by 2 levels under foggy weather
44: The pokemon's attacks ignore reflect and lightscreen
45: Increases damage dealt against ghost type pokemon with normal and fighting type moves
46: Increases damage dealt against dark type pokemon with normal and psychic type moves
47: All of the pokemon's moves recover 1 PP when entering a new floor
48: The pokemon recovers all of its HP when entering a new floor
49: Increases natural HP regeneration speed
4a: Max PP + 2
4b: Max PP + 4
4c: Max HP + 10
4d: Max HP + 20
4e: Max HP + 30
4f: Increases received EXP
50: The pokemon receives EXP when taking damage
51: Chance to recover PP when getting hit by an attack (30%)
52: Chance of not consuming PP when using an attack (10%)
53: Prevents thrown items from hitting the pokemon
54: Returns items thrown against the pokemon
55: Extends the effects of the Pokémon's moves from itself to the whole team
56: Increased chest drop chance
57: Doubles the amount of recovered HP when using HP-draining moves
58: Boosts the abilty Pressure, causing enemies to consume more PP when attacking
59: Immunity to status changes
5a: Reduction of damage taken from moves by 50%
5b: Increase of damage dealt with moves by 50%
5c: If an ally is poisoned, the pokemon absorbs the status to heal HP
5d: Recover HP when eating berries or apples
5e: Increased chance of a keckleon shop appearing in a dungeon (Base chance increased by 19%)
5f: Increased chance of hidden stairs appearing in a dungeon (Base chance increased by 19%)
60: Allows using items and moves without damaging allies
61: Increased chance of activation of Pickup
62: Increased chance of defeated foes dropping money
63: (?)
64: HP recovers faster while on water
65: Stepping on water heals status problems
66: Fire-type moves used against the pokemon will always miss
67: Water-type moves used against the pokemon will always miss
68: Grass-type moves used against the pokemon will always miss
69: Electric-type moves used against the pokemon will always miss
6a: Fighting-type moves used against the pokemon will always miss
6b: Ground-type moves used against the pokemon will always miss
6c: Flying-type moves used against the pokemon will always miss
6d: Psychic-type moves used against the pokemon will always miss
6e: Ghost-type moves used against the pokemon will always miss
6f: Dragon-type moves used against the pokemon will always miss
70: Dark-type moves used against the pokemon will always miss
71: Steel-type moves used against the pokemon will always miss
72: The pokemon absorbs fire-type moves and heals HP
73: The pokemon absorbs water-type moves and heals HP
74: The pokemon absorbs grass-type moves and heals HP
75: The pokemon absorbs electric-type moves and heals HP
76: The pokemon absorbs ice-type moves and heals HP
77: The pokemon absorbs fighting-type moves and heals HP
78: The pokemon absorbs ground-type moves and heals HP
79: The pokemon absorbs flying-type moves and heals HP
7a: The pokemon absorbs psychic-type moves and heals HP
7b: The pokemon absorbs bug-type moves and heals HP
7c: The pokemon absorbs rock-type moves and heals HP
7d: The pokemon absorbs ghost-type moves and heals HP
7e: The pokemon absorbs dragon-type moves and heals HP
7f: The pokemon absorbs dark-type moves and heals HP
80: The pokemon absorbs steel-type moves and heals HP

The stat buffs table starts at 0x9852C and ends at 0x98567, right before the effect table. It has 15 entries, each one is 4 bytes long.
Each of the 4 bytes indicates how much each stat is buffed by the item (Order: Atk, Def, SpAtk, SpDef)
For example, if an exclusive item has its second byte on the effect table set to 3, the buffs granted by it can be found at 0x9852C+4*3 = 0x98538 = [10, 0, 10, 0]. An item with this value would increase attack and special attack by 10.

So if you want an item to just give a stat boost you would need to set its first byte on the effect table to 0 and the second one to 1-14, depending on the stats you want to increase. Keep in mind that you can't change the values on the stat buffs table without affecting every other item which uses the same entry there.

Getting the items to show up in Croagunk's swap is going to be trickier though. If you look at the list you will see that all the items that follow the *, *, **, *** pattern are together between position 506 and 1013. The game only checks if you have the required items to create higher rarity ones within that range, that's why yours don't appear on the list.
Fixing that would require to write a rom hack that changed the behaviour of the code that does those checks and then create a patch to apply the changes on the rom.

Edited by End45
  • Like 1
  • Speechless 1

Share this post


Link to post
Share on other sites

I'm really amazed how you guys are managing to do something with gfxcrunch! Its pretty awful to work with ^^; Which is why I began working on that editor, which ironically isn't doing much better right now XD

Also, about croagunk's shop, there's some loose files that contains swap lists. I think its in SYNTH/synth.bin. Its something I didn't really invest too much time into, but, its most likely doable to change those. Otherwise, if its just a table in the binaries, its fairly easy to write a wrapper to load the table from a custom sir0 file. I did that with the level list a while ago to allow adding custom maps to the game without having to mod the binaries.

 

Share this post


Link to post
Share on other sites

 

RELEASE

Surprised I didn't upload the edits I did for Psyduck and Golduck
Here's the compiled Bins for the Monster folder: MONSTER.rar 

Differences;

The Pallete for Psyduck was given better contrast for his yellow. Golduck's red is stronger as well

Psyducks anim entries extended by using Piplup as a base. Custom sprites were made as well: 

image.thumb.png.8ec7d043b3236ceb14abd50ecede4747.png

Video showing Dialga fight: 

 

  • Amazed 1

Share this post


Link to post
Share on other sites
Posted (edited)

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:

values.png.9e54496e28d6030f3c48aea535719b94.png

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.

Edited by waffleoRai
update - no more tuning issue
  • Like 1

Share this post


Link to post
Share on other sites
On 5/5/2020 at 11:54 PM, waffleoRai said:

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.

Hey! Its all good. This is really what this thread is for XD

I'll admit, I'm about as clueless as you are about the sample pitch.. I know that some samples get tuned a bit from the oscillator effects, and without emulating that thing it won't sound right. But it also seems like some samples with just the fine pitch are just kinda off a bit still.. SF2 has been a pain in the butt to work with though, so I assumed it might have been part of the issue.. But glad to hear someone else noticed that as well..

Its possible its used for the voice yeah. What makes it tricky to trace down is that most of what goes into the driver is converted to an "analog" value almost immediatly..

Btw, are you planning to release that tool? It sounds pretty interesting! And any plans to emulate the oscillator processing stuff?

Share this post


Link to post
Share on other sites

Hey im having problems using pmdaudiotuli in that... i dont know how to use it. how do i use it?

Share this post


Link to post
Share on other sites
On 6/10/2020 at 6:48 PM, pupco1 said:

Hey im having problems using pmdaudiotuli in that... i dont know how to use it. how do i use it?

Well, most of it is explained in the readme, but you need to extract the rom, and pass the path to the extracted rom in parameters to the utility. There are a couple of exemple commands in the readme that you can pretty much just copy-paste and replace the missing bit with the right paths and stuff.

Share this post


Link to post
Share on other sites

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

  • Like 1

Share this post


Link to post
Share on other sites
On 6/13/2020 at 3:14 PM, psy_commando said:

Well, most of it is explained in the readme, but you need to extract the rom, and pass the path to the extracted rom in parameters to the utility. There are a couple of exemple commands in the readme that you can pretty much just copy-paste and replace the missing bit with the right paths and stuff.

ok that's good to know but when i open the application a command line only opens then closes. and i cant put anything in

Share this post


Link to post
Share on other sites

You need to open a command line window to get it to run. Usually you can just right click while holding shift in a directory you want to open the command line window in. On windows 10 it'll be called "power shell" I think. But then all you gotta do is type the name of the program and then the arguments.

Share this post


Link to post
Share on other sites
On 6/15/2020 at 6:11 PM, waffleoRai said:

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 280.45 kB · 3 downloads

Thanks for the links!

One thing I noticed when exporting to sf2 is that they lacked range for a lot of parameters in the official specs. DSE just seems to have unlimited pitch bending and oscilator rate XD So there's the issue that some programs might play things better than others, and its a real headache XD I also looked into the sfz format and it looked a bit better, but its still not very well supported. At that point, maybe a VST synth for DSE games might be one of the better solutions.

 

Share this post


Link to post
Share on other sites
On 6/22/2020 at 4:09 PM, psy_commando said:

You need to open a command line window to get it to run. Usually you can just right click while holding shift in a directory you want to open the command line window in. On windows 10 it'll be called "power shell" I think. But then all you gotta do is type the name of the program and then the arguments.

Whats an argument?

Share this post


Link to post
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...