Skeetendo

’Cause all games were better on the GBC

You are not logged in.

#1 2014-01-18 23:24:41

tkemert24
New member
Registered: 2013-12-22
Post 2/5

Changing what music plays in RB?

Is there a way of changing the music that plays during a battle? I was going to try and change the music of the Articuno/Moltres/Zapdos/Mewtwo battles, is that even possible? I'm really new to hacking, so sorry if this a simple thing to do. D:

Offline

#2 2014-01-19 16:03:10

Danny-E 33
Administrator
Registered: 2012-06-09
Post 715/1,034

Re: Changing what music plays in RB?

Right now, the easiest way to edit music is by using the pokered disassembly.
There are music files for each song that are easy to read and easy to edit, such as the gym leader battle music.

It sounds like you want to add a new song, without replacing an existing song. This is possible, but tricky, due to the way that song headers work.

The easiest way would be to edit this routine that chooses the song to play based on the type of battle:

PlayBattleMusic: ; 0x90c6
    xor a
    ld [wMusicHeaderPointer], a
    ld [$d083], a
    dec a
    ld [$c0ee], a
    call PlaySound ; stop music
    call DelayFrame
    ld c, BANK(Music_GymLeaderBattle)
    ld a, [W_GYMLEADERNO]
    and a
    jr z, .notGymLeaderBattle
    ld a, (Music_GymLeaderBattle - $4000) / 3
    jr .playSong
.notGymLeaderBattle
    ld a, [W_CUROPPONENT]
    cp $c8
    jr c, .wildBattle
    cp SONY3 + $c8
    jr z, .finalBattle
    cp LANCE + $c8
    jr nz, .normalTrainerBattle
    ld a, (Music_GymLeaderBattle - $4000) / 3 ; lance also plays gym leader theme
    jr .playSong
.normalTrainerBattle
    ld a, (Music_TrainerBattle - $4000) / 3
    jr .playSong
.finalBattle
    ld a, (Music_FinalBattle - $4000) / 3
    jr .playSong
.wildBattle
    ld a, (Music_WildBattle - $4000) / 3
.playSong
    jp PlayMusic

As you can see, the game uses 8-bit pointers to the song headers instead of 16-bit pointers. (I know you're new to this, so that just basically means that you don't have very many possibilities for more pointers, and there are so many sound effects in the game that it's basically impossible to add a new song header without replacing an old song header)

So since we can't create a new song header, the easiest way to play a new song is to begin a song using an existing song header and then overwriting the headers pointers to the music channels.

Here's what I mean. Use the routine shown above to add a check to see if the current opponent is Articuno, Zapdos, Moltres, or Mewtwo, and if so, jump to a new routine.
At this new routine, begin playing any song, like the wild battle song, using these three lines:

ld c, BANK(Music_WildBattle)
ld a, (Music_WildBattle - $4000) / 39
call PlayMusic

Then immediately after beginning the song, overwrite the channel pointers like this:

ld hl, $C006
ld de, XXYY ; pointer to channel 1
call Music8_OverwriteChannelPointer
ld de, XXYY ; pointer to channel 2
call Music8_OverwriteChannelPointer
ld de, XXYY ; pointer to channel 3
jp Music8_OverwriteChannelPointer

This should allow you to play a new song that doesn't have a song header and this is probably the easiest way to do it. (Gamefreak themselves used this method for the Viridian City theme, the Rival theme and the Poke Flute-in-battle song)


Red Hack: Pokémon Prototype

Total number of registered users: 8000+
Total number of active users: ~12

Offline

#3 2014-01-19 16:17:47

tkemert24
New member
Registered: 2013-12-22
Post 3/5

Re: Changing what music plays in RB?

All I really want to do, until I kinda get the used to editing and hacking, is just swap the song for an overworld battle like Articuno/Zapdos/Moltres/Mewtwo, maybe to the champion theme as a placeholder? Does your above method work in doing that? o:

Offline

#4 2014-01-19 17:28:27

Miksy91
Member
Registered: 2010-10-16
Post 2,052/2,317

Re: Changing what music plays in RB?

tkemert24 wrote:

All I really want to do, until I kinda get the used to editing and hacking, is just swap the song for an overworld battle like Articuno/Zapdos/Moltres/Mewtwo, maybe to the champion theme as a placeholder? Does your above method work in doing that? o:

You would have to code in a routine that does that.
So yes... you would have to modify that routine Danny pointed out, so that it would implement the wanted effect in the game.

Offline

#5 2014-01-19 17:56:31

Danny-E 33
Administrator
Registered: 2012-06-09
Post 716/1,034

Re: Changing what music plays in RB?

Yes exactly. You would only make this simple modification:

PlayBattleMusic: ; 0x90c6
    xor a
    ld [wMusicHeaderPointer], a
    ld [$d083], a
    dec a
    ld [$c0ee], a
    call PlaySound ; stop music
    call DelayFrame
    ld c, BANK(Music_GymLeaderBattle)
    ld a, [W_GYMLEADERNO]
    and a
    jr z, .notGymLeaderBattle
    ld a, (Music_GymLeaderBattle - $4000) / 3
    jr .playSong
.notGymLeaderBattle
    call CheckForLegendaryBattle ; *** the only edited line of the original function ***
    cp $c8
    jr c, .wildBattle
    cp SONY3 + $c8
    jr z, .finalBattle
    cp LANCE + $c8
    jr nz, .normalTrainerBattle
    ld a, (Music_GymLeaderBattle - $4000) / 3 ; lance also plays gym leader theme
    jr .playSong
.normalTrainerBattle
    ld a, (Music_TrainerBattle - $4000) / 3
    jr .playSong
.finalBattle
    ld a, (Music_FinalBattle - $4000) / 3
    jr .playSong
.wildBattle
    ld a, (Music_WildBattle - $4000) / 3
.playSong
    jp PlayMusic

...

CheckForLegendaryBattle: ; new function
    ld a, [W_CUROPPONENT]
    cp ARTICUNO
    jr z .legendary
    cp ZAPDOS
    jr z .legendary
    cp MOLTRES
    jr z .legendary
    cp MEWTWO
    jr z .legendary
    ret
.legendary
    ld a, SONY3 + $c8
    ret

This new code will call "CheckForLegendaryBattle" which uses the final rival id as the opponent id if the opponent is a legendary (which triggers the final battle theme). And if the opponent is not a legendary, use the real opponent id to correctly load the song.
That's all it takes to make legendaries play a different (but already existing) song.

So my first post is irrelevant since I didn't realize you weren't talking about using a brand new song, but I'll leave that post for anyone else because it still has useful information.


Red Hack: Pokémon Prototype

Total number of registered users: 8000+
Total number of active users: ~12

Offline

#6 2014-01-20 00:02:45

comet
Member
Registered: 2012-04-09
Post 357/679

Re: Changing what music plays in RB?

Danny-E 33 wrote:

This new code will call "CheckForLegendaryBattle" which uses the final rival id as the opponent id if the opponent is a legendary (which triggers the final battle theme). And if the opponent is not a legendary, use the real opponent id to correctly load the song.

Why not just hook into the wild battle part?

.wildBattle
    ld a, (Music_WildBattle - $4000) / 3

to

.wildBattle
    call CheckLegendaryMon
    jr nc, .legendary
    ld a, MUSIC_WILD_BATTLE
    jr .playSong
.legendary
    ld a, MUSIC_FINAL_BATTLE

Instead of returning an arbitrary trainer value, just return carry if it's not legendary.

CheckLegendaryMon:
    cp ARTICUNO
    ret z
    cp ZAPDOS
    ret z
    cp MOLTRES
    ret z
    cp MEWTWO
    ret z
    scf
    ret

Offline

#7 2014-01-20 04:25:30

Danny-E 33
Administrator
Registered: 2012-06-09
Post 717/1,034

Re: Changing what music plays in RB?

Because I was going for a simple way that doesn't lengthen the code since he is hex editing.

If your taking an approach that lengthens the code, you might as well call IsInArray and turn CheckLegendaryMon into a table.


Red Hack: Pokémon Prototype

Total number of registered users: 8000+
Total number of active users: ~12

Offline

Board footer

Powered by FluxBB