• Welcome to Smashboards, the world's largest Super Smash Brothers community! Over 250,000 Smash Bros. fans from around the world have come to discuss these great games in over 19 million posts!

    You are currently viewing our boards as a visitor. Click here to sign up right now and start on your path in the Smash community!

Completed Announcer Fanfares 2.0

Punkline

Dr. Frankenstack
Joined
May 15, 2015
Messages
423
Stormghetti Stormghetti requested a code that plays unused fanfare BGM when triggering the announcer voice at the end of stadium games, event matches, and other mini games.

Announcer Fanfares 2.0:
uses mytoc blocks 155, 158, and 341

Code:
-==-
Announcer Fanfares 2.0
Pair announcer SFX IDs with a fanfare BGM ID.
Default configuration triggers unused fanfares:
"Complete!"  - plays FF_GOOD.hps
"Success!"   - plays FF_GOOD.hps
"New Record!"   - plays FF_STEP3.hps
"Failure"   - plays FF_BAD.hps
[Punkline]
1.02 ----- 802F7358 --- C822E0D0 -> C8228000
1.02 ----- 802F72D0 --- C822E0D0 -> C8228000
1.02 ----- 8017F398 --- CBC2AAB0 -> CBC280A0
1.02 ----- 8017C3D8 --- C862AA50 -> C86280A0
1.02 ----- 80023864 --- 38210008 -> 38210030
1.02 ----- 80023860 --- 8001000c -> 80010034
1.02 ----- 804DA430 --- 43300000 -> branch
4E800021 # start list

# modify these to change triggers, or the resulting fanfares
00009C46 00000012 # "Complete!" SFX ID,   FF_GOOD.hps
0007C85E 00000012 # "Success!" SFX ID,    FF_GOOD.hps
00009C40 0000001C # "New Record!" SFX ID, FF_STEP3.hps ID
00009C48 0000000C # "Failure" SFX ID,     FF_BAD.hps

FFFFFFFF # end of list
1.02 ----- 804DA490 --- 43300000 -> branch
7C0802A6 90010004 9421FFF0 8062AAB4 2C030000 40810010
bl 0x80023f28
38600000 9062AAB4 38210010 80010004 7C0803A6 4E800020 00000000
1.02 ----- 804DA434 --- 80000000 -> branch
7C0802A6 90010004 9421FFF8 38C2AA50 7CC803A6 4E800021 7CC802A6 80E60000 7C071800 40A2001C 80E60004 90E2AAB4 9062E0D4 3902AAB0 9102E0D0 48000010 84E60008 2C070000 4181FFD8 38210008 80010004 7C0803A6 4E800020 00000000
1.02 ----- 800237bc --- 9421fff8 -> branch
9421FFD0 7C000026 90010020 80C2E0D0 80E2E0D4 39000000 9102E0D0 9102E0D4 2C060000 40A00028 7C071800 40A20020 38E10010 7C6765AA 7CE33B78 7CC803A6 4E800021 38610010 7C6364AA 80010020 7C0FF120 00000000
1.02 ----- 802f72e8 --- 4c411382 -> branch
4C411382 7C600026 90610018 40A20028 807E0020 2C030000 41810010 807E000C 2C030000 40810010 3802AA54 7C0803A6 4E800021 80610018 7C6FF120 00000000
1.02 ----- 802f6ecc --- 281e0000 -> branch
3862AA54 7C6803A6 7FA3EB78 4E800021 281E0000 00000000
1.02 ----- 80180d14 --- 981e0000 -> branch
981E0000 7C000026 90010018 800DAF34 2C000000 40A20044 807E0004 5463103A 7C63F214 80030014 7C1D0000 4181002C 38000001 900DAF34 3C600001 38639C48 3882AA54 7C8803A6 4E800021 3880007F 38A00040
bl 0x800237a8
80010018 7C0FF120 00000000
1.02 ----- 80180e94 --- 3880007f -> branch
3882AA54 7C8803A6 4E800021 3880007F 00000000
$Announcer Fanfares 2.0 [Punkline]
042F7358 C8228000
042F72D0 C8228000
0417F398 CBC280A0
0417C3D8 C86280A0
04023864 38210030
04023860 80010034
C24DA430 00000006
60000000 4E800021
00009C46 00000012
0007C85E 00000012
00009C40 0000001C
00009C48 0000000C

FFFFFFFF 00000000
C24DA490 00000009
7C0802A6 90010004
9421FFF0 8062AAB4
2C030000 4081001C
3D808002 618C3F28
7D8803A6 4E800021
38600000 9062AAB4
38210010 80010004
7C0803A6 4E800020
60000000 00000000
C24DA434 0000000C
7C0802A6 90010004
9421FFF8 38C2AA50
7CC803A6 4E800021
7CC802A6 80E60000
7C071800 40A2001C
80E60004 90E2AAB4
9062E0D4 3902AAB0
9102E0D0 48000010
84E60008 2C070000
4181FFD8 38210008
80010004 7C0803A6
4E800020 00000000
C20237BC 0000000B
9421FFD0 7C000026
90010020 80C2E0D0
80E2E0D4 39000000
9102E0D0 9102E0D4
2C060000 40A00028
7C071800 40A20020
38E10010 7C6765AA
7CE33B78 7CC803A6
4E800021 38610010
7C6364AA 80010020
7C0FF120 00000000
C22F72E8 00000008
4C411382 7C600026
90610018 40A20028
807E0020 2C030000
41810010 807E000C
2C030000 40810010
3802AA54 7C0803A6
4E800021 80610018
7C6FF120 00000000
C22F6ECC 00000003
3862AA54 7C6803A6
7FA3EB78 4E800021
281E0000 00000000
C2180D14 0000000E
981E0000 7C000026
90010018 800DAF34
2C000000 40A20050
807E0004 5463103A
7C63F214 80030014
7C1D0000 41810038
38000001 900DAF34
3C600001 38639C48
3882AA54 7C8803A6
4E800021 3880007F
38A00040 3D808002
618C37A8 7D8803A6
4E800021 80010018
7C0FF120 00000000
C2180E94 00000003
3882AA54 7C8803A6
4E800021 3880007F
60000000 00000000
Code:
-==-
!
ASM Gecko - Fanfare on New Records 2.0
Announcer Fanfares 2.0
Pair announcer SFX IDs with a fanfare BGM ID to play it when the announcer speaks.
Default configuration uses unused hps files:
"Complete!" plays FF_GOOD.hps
"Success!" plays FF_GOOD.hps
"New Record!" plays FF_STEP3.hps
"Failure" plays FF_BAD.hps
[Punkline]
1.02 ----- 802F7358 --- C822E0D0 -> C8228000
1.02 ----- 802F72D0 --- C822E0D0 -> C8228000
# mytoc -0x1F30(rtoc), -0x1F2C(rtoc)
1.02 ----- 8017F398 --- CBC2AAB0 -> CBC280A0
# mytoc -0x5550(rtoc), -0x554C(rtoc)
1.02 ----- 8017C3D8 --- C862AA50 -> C86280A0
# mytoc -0x55B0(rtoc), -0x55AC(rtoc)

1.02 ----- 80023864 --- 38210008 -> 38210030
1.02 ----- 80023860 --- 8001000c -> 80010034
# alters stack epilog for SFX function


1.02 ----- 804DA430 --- 43300000 -> branch
# this is branched to from rtoc - 0x55B0
# it handles storing globals for the fanfare pairings
blrl
.long 0x9C46,  0x12  # "Complete!" SFX ID,   FF_GOOD.hps
.long 0x7c85e, 0x12  # "Success!" SFX ID,    FF_GOOD.hps
.long 0x9C40,  0x1C  # "New Record!" SFX ID, FF_STEP3.hps ID
.long 0x9c48,  0x0C  # "Failure" SFX ID,     FF_BAD.hps
.long -1  # terminate list


1.02 ----- 804DA490 --- 43300000 -> branch
# this is branched to from rtoc - 0x5550
# it is not an injection, but rather a branch to a callback function
# it handles playing a fanfare when recognizing a SFX ID
mflr r0
stw  r0, 0x4(sp)
stwu sp, -0x10(sp)

.set mytoc_fanfare_BGM_ID,    -0x554C

lwz r3, mytoc_fanfare_BGM_ID(rtoc)
cmpwi r3, 0
ble- _return
# bl 0x80023f28
lis  r12, 0x8002
ori  r12, r12, 0x3F28
mtlr r12
blrl
li  r3, 0
stw r3, mytoc_fanfare_BGM_ID(rtoc)

_return:
addi sp, sp, 0x10
lwz  r0, 0x4(sp)
mtlr r0
blr
# .long 0


1.02 ----- 804DA434 --- 80000000 -> branch
# this function is branched to from rtoc - 0x55AC
# it handles checking the default fanfare pairings
# r3 = SFX ID (key for lookup)
# returns r3, r4, r5 unchanged
mflr r0
stw  r0, 0x4(sp)
stwu sp, -0x8(sp)

.set mytoc_SFX_event_pointer, -0x1F30
.set mytoc_SFX_ID,            -0x1F2C
.set mytoc_fanfare_callback,  -0x5550
.set mytoc_fanfare_BGM_ID,    -0x554C
.set mytoc_fanfare_defaults,  -0x55B0

addi r6, rtoc, mytoc_fanfare_defaults
mtlr r6
blrl
mflr r6
# r6 now = base address of default SFX/BGM pairings

lwz   r7, 0(r6)
_loop:
  cmpw r7, r3
  bne+ _iterate_loop

_exit_loop:
  lwz r7, 4(r6)
  stw r7, mytoc_fanfare_BGM_ID(rtoc)
  stw r3, mytoc_SFX_ID(rtoc)
  addi r8, rtoc, mytoc_fanfare_callback
  stw  r8, mytoc_SFX_event_pointer(rtoc)
  b _return

_iterate_loop:
  lwzu r7, 8(r6)
  cmpwi r7, 0
  bgt+ _loop

_return:
addi sp, sp, 0x8
lwz  r0, 0x4(sp)
mtlr r0
blr


1.02 ----- 800237bc --- 9421fff8 -> branch
# this injection sets up a callback event inside of a SFX func
# the SFX func is a prefunction that seems to be used only for a
# limited range of SFX IDs, but it includes announcer SFX
stwu    sp, -0x0030(sp)
mfcr r0
stw  r0, 0x20(sp)
.set mytoc_SFX_event_pointer, -0x1F30
.set mytoc_SFX_ID,            -0x1F2C

lwz   r6, mytoc_SFX_event_pointer(rtoc)
lwz   r7, mytoc_SFX_ID(rtoc)
li    r8, 0
stw   r8, mytoc_SFX_event_pointer(rtoc)
stw   r8, mytoc_SFX_ID(rtoc)

cmpwi r6, 0
bge+ _return  # check r6 for address
cmpw  r7, r3
bne+ _return  # make sure IDs match

# original instruction activates stack frame
# we alter the offset to include more space

_callback_event:
addi r7, sp, 0x10
stswi r3, r7, 0xC
# now args are stored in stack:

# r3 = SFX ID
# r4 = volume
# r5 = stereo mix

# we'll pass this string to the callback,
# so that it may optionally alter the SFX behavior
mr r3, r7
mtlr r6

blrl  # callback

addi r3, sp, 0x10
lswi r3, r3, 0xC
# arguments are restored for opening of SFX func

_return:
lwz r0, 0x20(sp)
mtcr r0
# .long 0


1.02 ----- 802f72e8 --- 4c411382 -> branch
# this injection sets up a callback for the previous event
# it only includes the scope of SFX tied to an 000E entity type
# includes "Ready..." "GO!" "Failer" etc
# r31 = JObj root belonging to graphic (?)
# f31 = some float derived from r31 (likely an AObj timer)
# r30 = SFX structure
# 0xC  = SFX ID for normal announcer voice
# 0x10 = timer byte 1 (for announcer)
# 0x11 = timer byte 2 (for crowd SFX?)
# 0x12 = flags byte (bit 80 seems to signify SFX played)
# 0x20 = SFX ID for special announcer (New Record!)
# 0x24 = SFX ID for crowd SFX
# -- if any SFX IDs are null, they are skipped
_code_start:
cror cr2, cr1, cr2
mfcr r3
stw  r3, 0x18(sp)
# hold CR in stack for safe branch
# we'll be using what's currently in cr0 to determine
# which offset to look at from r30

bne+ _return
lwz   r3, 0x20(r30)
cmpwi r3, 0
bgt- _set_fanfare_callback
_normal_announcer:
lwz   r3, 0xC(r30)
cmpwi r3, 0
ble _return
_set_fanfare_callback:

.set mytoc_fanfare_assign_default, -0x55AC

addi r0, rtoc, mytoc_fanfare_assign_default
mtlr r0
blrl

_return:
lwz  r3, 0x18(sp)
mtcr r3
# .long 0


1.02 ----- 802f6ecc --- 281e0000 -> branch
# r29 = incoming SFX ID for announcer call on trophy stage
.set mytoc_fanfare_assign_default, -0x55AC
.set rSFXID, 29

# .set trophy_stageID, 0x26
# lis r3, 0x804A
# lwz r3, -0x18B0(r3) # r3 = current stage ID (internal)
# cmpwi r3, trophy_stageID
# bne+ _return
# _if_trophy_stage_exit:

addi r3, rtoc, mytoc_fanfare_assign_default
mtlr r3
mr   r3, rSFXID
blrl  # assign BGM ID if pending SFX ID matches a default def

cmplwi    r30, 0  # original instruction
# .long 0


1.02 ----- 80180d14 --- 981e0000 -> branch
# add artificial announcer SFX to HRC
.set mytoc_fanfare_assign_default, -0x55AC
stb    r0, 0 (r30) # original instruction
mfcr r0
stw  r0, 0x18(sp) # store CR for return

lwz r0, -0x50CC(r13)  # flag word indicates sound has been played
cmpwi r0, 0
bne+ _return

lwz   r3, 0x4(r30)
slwi  r3, r3, 2
add   r3, r3, r30
lwz   r0, 0x14(r3)
cmpw r29, r0      # r29 = current distance
bgt- _return
# if distance <= record, then play "Failure" SFX and flag -0x50CC(r13)

li  r0, 1
stw r0, -0x50CC(r13)
lis r3, 1
addi r3, r3, -0x63B8  # load ID for Failure SFX
addi r4, rtoc, mytoc_fanfare_assign_default
mtlr r4
blrl  # prime fanfare
li   r4, 127
li   r5, 64
# bl 0x800237a8  # call SFX
lis  r12, 0x8002
ori  r12, r12, 0x37A8
mtlr r12
blrl

_return:
lwz r0, 0x18(sp)
mtcr r0
# .long 0


1.02 ----- 80180e94 --- 3880007f -> branch
# fanfare for HRC New record
.set mytoc_fanfare_assign_default, -0x55AC
addi r4, rtoc, mytoc_fanfare_assign_default
mtlr r4
blrl  # prime fanfare
li   r4, 127
# .long 0

---

This code allows users to pair BGM IDs with announcer SFX IDs to create triggers for playing a fanfare. The default configuration includes:

00009C46 00000012 # “Complete!” = FF_GOOD
0007C85E 00000012 # “Success!” = FF_GOOD
00009C40 0000001C # “A New Record!” = FF_STEP3
00009C48 0000000C # “Failure” = FF_BAD

Here's a list of BGM IDs, for reference. These were acquired by observing the index starting at 803BBDDC:
Code:
ID - Music:

00 - 1p_qk.hps
01 - akaneia.hps
02 - baloon.hps
03 - bigblue.hps
04 - castle.hps
05 - continue.hps
06 - corneria.hps
07 - docmari.hps
08 - ending.hps
09 - famidemo.hps
0A - ff_1p01.hps
0B - ff_1p02.hps
0C - ff_bad.hps
0D - ff_dk.hps
0E - ff_emb.hps
0F - ff_flat.hps
10 - ff_fox.hps
11 - ff_fzero.hps
12 - ff_good.hps
13 - ff_ice.hps
14 - ff_kirby.hps
15 - ff_link.hps
16 - ff_mario.hps
17 - ff_nes.hps
18 - ff_poke.hps
19 - ff_samus.hps
1A - ff_step1.hps
1B - ff_step2.hps
1C - ff_step3.hps
1D - ff_yoshi.hps
1E - flatzone.hps
1F - fourside.hps
20 - gameover.hps
21 - garden.hps
22 - greatbay.hps
23 - greens.hps
24 - howto.hps
25 - howto_s.hps
26 - hyaku.hps
27 - hyaku2.hps
28 - icemt.hps
29 - inis1_01.hps
2A - inis1_02.hps
2B - inis2_01.hps
2C - inis2_02.hps
2D - intro_es.hps
2E - intro_nm.hps
2F - item_h.hps
30 - item_s.hps
31 - izumi.hps
32 - kongo.hps
33 - kraid.hps
34 - menu01.hps
35 - menu02.hps
36 - menu3.hps
37 - mrider.hps
38 - mutecity.hps
39 - old_dk.hps
3A - old_kb.hps
3B - old_ys.hps
3C - onetto.hps
3D - onetto2.hps
3E - opening.hps
3F - pokesta.hps
40 - pstadium.hps
41 - pura.hps
42 - rcruise.hps
43 - s_info1.hps
44 - s_info2.hps
45 - s_info3.hps
46 - s_new1.hps
47 - s_new2.hps
48 - s_newcom.hps
49 - s_select.hps
4A - saria.hps
4B - shrine.hps
4C - siren.hps
4D - smari3.hps
4E - sp_end.hps
4F - sp_giga.hps
50 - sp_metal.hps
51 - sp_zako.hps
52 - swm_15min.hps
53 - target.hps
54 - venom.hps
55 - vl_battle.hps
56 - vl_castle.hps
57 - vl_corneria.hps
58 - vl_cosmos.hps
59 - vl_figure1.hps
5A - vl_figure2.hps
5B - vl_fzero.hps
5C - vl_last_v2.hps
5D - vs_hyou1.hps
5E - vs_hyou2.hps
5F - yorster.hps
60 - ystory.hps
61 - zebes.hps
62 - testnz.hps

---

To customize what fanfare plays, modify the list inside either the DOL mod or the Gecko Code to use music from the above index:



---

Update notes:

As of 3/28/2018, this code has been completely rewritten to include some new features:

- Reusable move-logic-like callback pointer allows (the next) SFX call made from 800237A8 to execute additional code before playing a sound.
- Fanfare mechanic uses callback pointer from a higher level function used only for applying SFX that correspond with the animation timing of announcer .
- Default fanfares for “Failure” and “Success” announcements have been added to configuration.
- Default SFX/BGM ID pairings may be given custom definitions with code installation.
- Default SFX/BGM ID pairings may be modified procedurally by other codes for conditional fanfares.
- non-default SFX/BGM IDs may be assigned manually via injection code triggers.
- Fanfare mechanic has been extended to include classic/adventure mode races.
- Fanfare mechanic has been extended to include a scene transition function used by the Trophy collection mini game.
- HRC scene function has been given artificial “Failure” SFX call conditions for unbroken records and no distance.
Edit 3/18/2018 : New code version (1.1) fixes instances where breaking records would mess up the event trigger:

- Added the FF_STEP3.hps fanfare when setting a new record. These should trigger on Target Test and Event matches.
- Added injection to include fanfare in Home Run Contest new records.
- rtoc event pointer is now reset in case of new records.

Thanks Stormghetti Stormghetti and @tauKhan for helping me troubleshoot this!
 
Last edited:

Brandondorf9999

Smash Cadet
Joined
Mar 6, 2012
Messages
71
You know you could also use the Game Over theme for the new record failure event. Also, the IDs to the two music are "0x05" (for Continue) and "0x20" (for Game Over).
 
Last edited:

Stormghetti

Smash Journeyman
Joined
Aug 23, 2015
Messages
400
Location
Europe
Slippi.gg
STRM#798
NNID
Stormghetti
I requested him something similar: FF_BAD for a "Failure".
 

Punkline

Dr. Frankenstack
Joined
May 15, 2015
Messages
423
Well, it took some time and some shotgun surgery, but I think this now covers all of the normal announcer SFX calls.

As of 3/28/2018, this code has been completely rewritten to include some new features:

- Reusable move-logic-like callback pointer allows (the next) SFX call made from 800237A8 to execute additional code before playing a sound.
- Fanfare mechanic uses callback pointer from a higher level function used only for applying SFX that correspond with the animation timing of announcer graphic.
- Default fanfares for “Failure” and “Success” announcements have been added to configuration.
- Default SFX/BGM ID pairings may be given custom definitions with code installation.
- Default SFX/BGM ID pairings may be modified procedurally by other codes for conditional fanfares.
- non-default SFX/BGM IDs may be assigned manually via injection code triggers.
- Fanfare mechanic has been extended to include classic/adventure mode races.
- Fanfare mechanic has been extended to include a scene transition function used by the Trophy collection mini game.
- HRC scene function has been given artificial “Failure” SFX call conditions for unbroken records and no distance.

Stormghetti Stormghetti Benny P Benny P , the default configuration should now create the effect you requested.

You know you could also use the Game Over theme for the new record failure event. Also, the IDs to the two music are "0x05" (for Continue) and "0x20" (for Game Over).
B Brandondorf9999 you can now customize the IDs that play. To set up the Continue or Game Over music, modify the list described in the updated OP to something like this:

00009C46 00000012 # “Complete!” = FF_GOOD
0007C85E 00000012 # “Success!” = FF_GOOD
00009C40 0000001C # “A New Record!” = FF_STEP3
00009C48 00000005 # “Failure” = Continue music
00009C46 00000012 # “Complete!” = FF_GOOD
0007C85E 00000012 # “Success!” = FF_GOOD
00009C40 0000001C # “A New Record!” = FF_STEP3
00009C48 00000020 # “Failure” = Game Over music
 
Last edited:

Stormghetti

Smash Journeyman
Joined
Aug 23, 2015
Messages
400
Location
Europe
Slippi.gg
STRM#798
NNID
Stormghetti
Well, it took some time and some shotgun surgery, but I think this now covers all of the normal announcer SFX calls.

As of 3/28/2018, this code has been completely rewritten to include some new features:

- Reusable move-logic-like callback pointer allows (the next) SFX call made from 800237A8 to execute additional code before playing a sound.
- Fanfare mechanic uses callback pointer from a higher level function used only for applying SFX that correspond with the animation timing of announcer graphic.
- Default fanfares for “Failure” and “Success” announcements have been added to configuration.
- Default SFX/BGM ID pairings may be given custom definitions with code installation.
- Default SFX/BGM ID pairings may be modified procedurally by other codes for conditional fanfares.
- non-default SFX/BGM IDs may be assigned manually via injection code triggers.
- Fanfare mechanic has been extended to include classic/adventure mode races.
- Fanfare mechanic has been extended to include a scene transition function used by the Trophy collection mini game.
- HRC scene function has been given artificial “Failure” SFX call conditions for unbroken records and no distance.

Stormghetti Stormghetti Benny P Benny P , the default configuration should now create the effect you requested.



B Brandondorf9999 you can now customize the IDs that play. To set up the Continue or Game Over music, modify the list described in the updated OP to something like this:
This is insanely awesome. I'm getting excited over short fanfares, lol.

I love you.
 
Top Bottom