ff3:ff3us:tutorial:music:songdata

This is an old revision of the document!


Updated: 07/07/2024
This tutorial can also be found here.

In this tutorial, we'll be using a FF3us ROM to import a new song that is already in the FF6 music format. You do not need musical knowledge to complete the following steps. The only thing that will help is being familiar with the hexadecimal system and the concept of offset. This tutorial is aimed at beginners, so if for example you are familiar with hex editors and ROM headers, you might want to skip some of the explanations included here.

Before you read any further, if you want to only replace an existing song with another one, you can use INSERTMFVI by emberling. It's a great tool that can do more than this task alone, but to my knowledge it does not relocate what needs to be relocated to add more songs than the current game limit, an aspect that is covered in this tutorial.

For this tutorial, we'll be working with the song FF4 - Prologue from the FF6Hacking wiki song database. If you feel comfortable enough, you can choose another song for the tutorial but offsets and addresses from the tutorial screenshots might differ a bit, each song hack having a different size in bytes. The other thing you will need is a hex editor. This tutorial uses HxD but other hex editors could also be suitable for the job.

Each zip folders from the song database contains at least 3 files: a .spc file, which is a music file of the song as it sounds in FFVI that you can play with SPC players. For more info on this you can check this great page from fantasyanime.com. The second and third files are binary files and are used for the song hack. The INST file contains the BRR instrument IDs used for the song. This file is always 32 (0x20) bytes in size. The DATA file is the song data itself, in other words: notes, effects, jumps, loops that you find in a sequenced piece of music. Both files are going to be inserted in the ROM.

We will be working with a headerless (no header) FF3us 1.0 or 1.1 ROM. To remove (or add) a header, you can use GUI utilities such as Advanced SNES ROM Utility or SNEStuff. We will also be expanding the ROM from 24 Mbit to 32 MBit. For this you can use Lunar Expand. The following screenshot shows which option to select in Lunar Expand.

The following code block shows the order of music-related data in the ROM. There is no room to just add sequentially new data/pointers for a new song or instrument without moving some things first. We will therefore first move to expanded ROM region the instruments for each song ($C53F95-$C53A34). This will give us room for new instrument data for the new song in expanded ROM region and a new song pointer that will be located at $C53F95.

    C53C5E-C53C5E	Number of Songs (1 byte)
    C53C5F-C53D1B	Pointers to Instrument BRR Data (3 bytes each, absolute)
    C53D1C-C53D99	Instrument Loop Start Positions (63 items, 2 bytes each)
    C53D9A-C53E17	Instrument Pitch Multipliers (63 items, 2 bytes each)
    C53E18-C53E95	Instrument ADSR Data (63 items, 2 bytes each)
    C53E96-C53F94	Pointers to Song Data (3 bytes each, absolute)
    C53F95-C54A34	Instruments for Each Song (85 items, 32 bytes each)
    C54A35-C85C79	Instrument BRR Data (63 items, variable size)
    C85C7A-C9FDFF	Song Data (85 items, variable size)

Before I go any further, I'll explain the difference between an HiROM and an absolute address/offset. Think of the beginning of your ROM as offset $C00000 (HiROM) and $000000 (absolute). It's basically two ways to refer to the same address/offset. Programs like general purpose hex editors will use absolute offsets because they have no knowledge of the SNES ROM mapping but the SNES assembly code will use the HiROM offsets (for an HiROM game like FF3us). So in other words, each time you see a HiROM offset ($C00000 to $FFFFFF), subtract $C00000 from it to get its absolute value. For example, HiROM offset $D12890 translates to $112890.

Now we will proceed with moving the instrument data. First, open HxD and load you expanded ROM. Press Search → Go to… (Ctrl+g) and enter 053F95 which is the offset of the beginning of the instrument data.

You HxD cursor should now be placed at $053F95 as shown here:

Now do Edit → Select block (Ctrl+e), Select the Length option and enter AA0. This will select the totality of the instrument data, which is $0AA0 bytes long (85 song instruments times 32 bytes each set in decimal).

The instrument data should now be selected with your cursor at the end of it, as shown here:

You can now right-click on the blue region and do Copy (Ctrl+c). The next step is going to expanded ROM and insert the instrument data there. I decided to put this data at $341000 ($F41000) but it could be anywhere where there is free space as long as there is enough of it.

When you have moved to $341000, right-click with the mouse and do Paste write (Ctrl+b). You'll see the pasted instrument data in red. You can now save (Ctrl+s).

We have one more thing to do to make instrument data relocation complete but we'll get back to it later for convenience.

Open in HxD the song INST file then select everything (Ctrl+a) and copy it (Ctrl+c). Go back to your ROM and paste write your new 32 bytes of instrument data at $341AA0 as shown here. You can save the ROM after.

We'll do a similar thing with the DATA file. Open it in HxD, select all and copy, then go to $342000 and paste write the song data. Your song data should start and end here:

We are putting the song data at $F42000 in order to leave some room before for other instrument if you decide to add more songs in the future.

The next step is changing some code for the new instrument location. We need to go at $0501E3 ($C501E3) to put the new offset of the start of instrument data. Below is what need to be changed and how it looks in HxD:

    C5/01E2:	BF953FC5	LDA $C53F95,X

    C5/01E2:	BF0010F4	LDA $F41000,X

One of the reason we relocated instrument data is to be able to add a new song pointer. So we'll go to $C53F95 and add 00 20 F4 ($F42000), the start of our new song data.

There is a little thing left to do and it's to change the number of songs byte, from $55 to $56, which is located at $C53C5E.

So that's it! All the mandatory steps have been made, you can now use your new song in the game! The next and final step will show one way songs are used and will do a modification to play it in the load menu.

Most song plays are triggered in events or battle, but some are hardcoded. The load menu prelude is an example of the latter in the menu code module. To replace that song, change the $01 at $C30182 (Prelude ID) to the song ID you want.

    C3/0181: A9 01  LDA #$01    ; song $01 (the prelude)

    C3/0181: A9 55  LDA #$55    ; song $55 (the prologue)

When you have a number of entries with a fixed size, you can calculate where you need to add or change an entry. This is done with the formula base_offset + (id * entry_size). The two examples below show how this is done with our new song ID ($55) regarding the pointer offset and instrument data offset.

    Song pointer:
    $C53E96 + (0x55 * 0x03) = $C53F95

    Instrument data:
    $F41000 + (0x55 * 0x20) = $F41AA0

As you know by now, each song instrument data is 32 bytes ($20). In a set, each pair of bytes point to an instrument ID. The list of instruments can be found on this FF6Hacking wiki page. You can change these instruments but note that these change can require an octave change for the new instrument because of differences between BRR samples. Some instrument data from the FF6Hacking wiki song database have instrument IDs above $3F, the original limit. These song hack are mostly imported from FF6 T-Edition and would require instrument import or vanilla instrument IDs replacing IDs above $3F in their instrument data.

  • /home/rf47utc0amet/public_html/g8tr5498lk/7te29876kgnbd75ks/pages/ff3/ff3us/tutorial/music/songdata.txt
  • Last modified: 13 days ago
  • by madsiur