[Request] Random Track Music
#1
There is already a code that can randomize the track .szs itself made by CLF78 (https://mkwii.com/showthread.php?tid=165...76#pid7976). A similar code that could let you give tracks multiple .brstm files and pick them at random every time you race them would be pretty cool for adding custom music to your own game, not limiting you to hearing the same song every time.
Reply
#2
I've made this code a month ago, just never bothered to port it and post it. It's kinda untested so i don't know how much it will work.

Code:
# Hook (PAL ONLY) = 8009E0BC

# Address Ports (PAL ONLY)
.set UtilRandint, 0x800F2EE0
.set Racedata, 0x809BD728
.set sprintf, 0x80011A2C

# Exception Vector Values (DON'T PORT)
.set LastVariant, 0x800001B0

# Check if we are loading a track song by checking the file's first character
lbz r3, 0x15C(r1)

cmpwi r3, 'n'
beq+ isTrack

cmpwi r3, 'S'
beq+ isTrack

cmpwi r3, 'r'
bne end

# Backup LR
isTrack:
mflr r26

# Do bl trick
bl trick

# Track counts
.byte 0, 0, 0, 0    # Mario Circuit, Moo Moo Meadows, Mushroom Gorge, Grumble Volcano
.byte 0, 0, 0, 0    # Toad's Factory, Coconut Mall, DK Summit, Wario's Gold Mine
.byte 0, 0, 0, 0    # Luigi Circuit, Daisy Circuit, Moonview Highway, Maple Treeway
.byte 0, 0, 0, 0    # Bowser Castle, Rainbow Road, Dry Dry Ruins, Koopa Cape
.byte 0, 0, 0, 0    # GCN Peach Beach, GCN Mario Circuit, GCN Waluigi Stadium, GCN DK Mountain
.byte 0, 0, 0, 0    # DS Yoshi Falls, DS Desert Hills, DS Peach Gardens, DS Delfino Square
.byte 0, 0, 0, 0    # SNES Mario Circuit 3, SNES Ghost Valley 2, N64 Mario Raceway, N64 Sherbet Land
.byte 0, 0, 0, 0    # N64 Bowser's Castle, N64 DK's Jungle Parkway, GBA Bowser Castle 3, GBA Shy Guy Beach
.byte 0, 0, 0, 0, 0 # Delfino Pier, Block Plaza, Chain Chomp Wheel, Funky Stadium, Thwomp Desert
.byte 0, 0, 0, 0, 0 # GCN Cookie Land, DS Twilight House, SNES Battle Course 4, GBA Battle Course 3, N64 Skyscraper
.byte 0                # Galaxy Colosseum
.align 2

# Format string for final name
.string "/%d%s.brstm"

# String for final lap music
.string "_F"

# String for regular lap music
.string ""
.align 2

# Swap LR back
trick:
mflr r8
mtlr r26

# Load last character of filename before the extension
addi r7, r28, 0x150
lbzx r7, r7, r1

# Assume not fast
li r26, 0

# Check for an F either lower or uppercase
cmpwi r7, 'f'
beq isFast

cmpwi r7, 'F'
bne noFast

# Set r26 to 1 if so
isFast:
li r26, 1

# Check if we should randomize or pick the existing number
noFast:
cmpwi r26, 1
beq lastLap

# Get track slot
lis r7, Racedata@ha
lwz r7, Racedata@l(r7)
lwz r7, 0xB68(r7)

# Setup arguments
li r3, 0
lbzx r4, r7, r8
addi r4, r4, 1

# Call randint
lis r12, UtilRandint@h
ori r12, r12, UtilRandint@l
mtctr r12
bctrl

# Move result to r5 and store it in the EVA
mr r5, r3
lis r3, LastVariant@ha
stb r5, LastVariant@l(r3)
b numberPicked

# Otherwise get previous number stored there
lastLap:
lis r5, LastVariant@ha
lbz r5, LastVariant@l(r5)

# If result is 0, load original track
numberPicked:
cmpwi r5, 0
beq end

# Set the buffer to the beginning of the file extension
addi r3, r28, 0x14F
add r3, r3, r1

# Set format string
addi r4, r8, 0x2C

# Set empty string
addi r6, r8, 0x3B
cmpwi r26, 1
beq call

# Otherwise set fast lap string
subi r6, r6, 3

# Call sprintf
call:
lis r12, sprintf@h
ori r12, r12, sprintf@l
mtctr r12
bctrl

# Original instruction
end:
addi r26, r1, 0x150
Reply
#3
(08-06-2021, 05:50 PM)CLF78 Wrote: I've made this code a month ago, just never bothered to port it and post it. It's kinda untested so i don't know how much it will work.

Code:
# Hook (PAL ONLY) = 8009E0BC

# Address Ports (PAL ONLY)
.set UtilRandint, 0x800F2EE0
.set Racedata, 0x809BD728
.set sprintf, 0x80011A2C

# Exception Vector Values (DON'T PORT)
.set LastVariant, 0x800001B0

# Check if we are loading a track song by checking the file's first character
lbz r3, 0x15C(r1)

cmpwi r3, 'n'
beq+ isTrack

cmpwi r3, 'S'
beq+ isTrack

cmpwi r3, 'r'
bne end

# Backup LR
isTrack:
mflr r26

# Do bl trick
bl trick

# Track counts
.byte 0, 0, 0, 0    # Mario Circuit, Moo Moo Meadows, Mushroom Gorge, Grumble Volcano
.byte 0, 0, 0, 0    # Toad's Factory, Coconut Mall, DK Summit, Wario's Gold Mine
.byte 0, 0, 0, 0    # Luigi Circuit, Daisy Circuit, Moonview Highway, Maple Treeway
.byte 0, 0, 0, 0    # Bowser Castle, Rainbow Road, Dry Dry Ruins, Koopa Cape
.byte 0, 0, 0, 0    # GCN Peach Beach, GCN Mario Circuit, GCN Waluigi Stadium, GCN DK Mountain
.byte 0, 0, 0, 0    # DS Yoshi Falls, DS Desert Hills, DS Peach Gardens, DS Delfino Square
.byte 0, 0, 0, 0    # SNES Mario Circuit 3, SNES Ghost Valley 2, N64 Mario Raceway, N64 Sherbet Land
.byte 0, 0, 0, 0    # N64 Bowser's Castle, N64 DK's Jungle Parkway, GBA Bowser Castle 3, GBA Shy Guy Beach
.byte 0, 0, 0, 0, 0 # Delfino Pier, Block Plaza, Chain Chomp Wheel, Funky Stadium, Thwomp Desert
.byte 0, 0, 0, 0, 0 # GCN Cookie Land, DS Twilight House, SNES Battle Course 4, GBA Battle Course 3, N64 Skyscraper
.byte 0                # Galaxy Colosseum
.align 2

# Format string for final name
.string "/%d%s.brstm"

# String for final lap music
.string "_F"

# String for regular lap music
.string ""
.align 2

# Swap LR back
trick:
mflr r8
mtlr r26

# Load last character of filename before the extension
addi r7, r28, 0x150
lbzx r7, r7, r1

# Assume not fast
li r26, 0

# Check for an F either lower or uppercase
cmpwi r7, 'f'
beq isFast

cmpwi r7, 'F'
bne noFast

# Set r26 to 1 if so
isFast:
li r26, 1

# Check if we should randomize or pick the existing number
noFast:
cmpwi r26, 1
beq lastLap

# Get track slot
lis r7, Racedata@ha
lwz r7, Racedata@l(r7)
lwz r7, 0xB68(r7)

# Setup arguments
li r3, 0
lbzx r4, r7, r8
addi r4, r4, 1

# Call randint
lis r12, UtilRandint@h
ori r12, r12, UtilRandint@l
mtctr r12
bctrl

# Move result to r5 and store it in the EVA
mr r5, r3
lis r3, LastVariant@ha
stb r5, LastVariant@l(r3)
b numberPicked

# Otherwise get previous number stored there
lastLap:
lis r5, LastVariant@ha
lbz r5, LastVariant@l(r5)

# If result is 0, load original track
numberPicked:
cmpwi r5, 0
beq end

# Set the buffer to the beginning of the file extension
addi r3, r28, 0x14F
add r3, r3, r1

# Set format string
addi r4, r8, 0x2C

# Set empty string
addi r6, r8, 0x3B
cmpwi r26, 1
beq call

# Otherwise set fast lap string
subi r6, r6, 3

# Call sprintf
call:
lis r12, sprintf@h
ori r12, r12, sprintf@l
mtctr r12
bctrl

# Original instruction
end:
addi r26, r1, 0x150

This is awesome! I don't know how to compile ASM tho, so I'll be patient for when you release it, however long it takes.
Reply
#4
(08-07-2021, 05:06 AM)Yuri Bacon Wrote: This is awesome! I don't know how to compile ASM tho, so I'll be patient for when you release it, however long it takes.

There are four different programs to compile PPC ASM to Wii Gecko Codes
  • PyiiASMH 3
  • CodeWrite
  • PyiiASMH (legacy)
  • WiiRD GUI

I think there's also a fifth that the Smashboard community uses, iirc.

Anyway, PyiiASMH3 is the most modern and has the most features - https://mkwii.com/showthread.php?tid=1529

The four fields that you need to be concerned with are the left hand box, right hand box, address, and type.

To compile:
Place the code's source into the left hand box. Some sources have a region compilation setting value that must be filled in beforehand, and/or other values that may also need to be filled in, it all depends on the particular source and how the coder/dev wrote it. Even if you don't know PPC ASM, chances are there will be instructions within the source on how to fill in said missing values.

Set the Code Type for the source (C0, C2, etc). If it's C2, you need to set the address (the hook/insertion address).

Hit the right hand arrow button and the source will compile to a Wii Gecko Code. If any error occurs, PyiiASMH3 will tell you which line(s) in the source are preventing the compilation. If it doesn't tell you the line(s), then the source was botched and/or the labels it uses (i.e. for branch instructions) were bad. If that's the case, contact the Coder/Dev who wrote the source for a fix.



To decompile:
Pretty much the opposite. Take the Gecko Code, place it in right hand box. Set it's code type. Address doesnt matter ofc because you already have it. If a Wii Gecko code has values to fill in, fill those in or else it cannot be decompiled. Hit the left hand arrow button. Code will be decompiled to a generic source.
Reply
#5
(08-07-2021, 12:34 PM)Vega Wrote:
(08-07-2021, 05:06 AM)Yuri Bacon Wrote: This is awesome! I don't know how to compile ASM tho, so I'll be patient for when you release it, however long it takes.

There are four different programs to compile PPC ASM to Wii Gecko Codes
  • PyiiASMH 3
  • CodeWrite
  • PyiiASMH (legacy)
  • WiiRD GUI

I think there's also a fifth that the Smashboard community uses, iirc.

Anyway, PyiiASMH3 is the most modern and has the most features - https://mkwii.com/showthread.php?tid=1529

The four fields that you need to be concerned with are the left hand box, right hand box, address, and type.

To compile:
Place the code's source into the left hand box. Some sources have a region compilation setting value that must be filled in beforehand, and/or other values that may also need to be filled in, it all depends on the particular source and how the coder/dev wrote it. Even if you don't know PPC ASM, chances are there will be instructions within the source on how to fill in said missing values.

Set the Code Type for the source (C0, C2, etc). If it's C2, you need to set the address (the hook/insertion address).

Hit the right hand arrow button and the source will compile to a Wii Gecko Code. If any error occurs, PyiiASMH3 will tell you which line(s) in the source are preventing the compilation. If it doesn't tell you the line(s), then the source was botched and/or the labels it uses (i.e. for branch instructions) were bad. If that's the case, contact the Coder/Dev who wrote the source for a fix.



To decompile:
Pretty much the opposite. Take the Gecko Code, place it in right hand box. Set it's code type. Address doesnt matter ofc because you already have it. If a Wii Gecko code has values to fill in, fill those in or else it cannot be decompiled. Hit the left hand arrow button. Code will be decompiled to a generic source.

I know I probably wouldn't actually get a usable code out of this but gave it a shot anyways.

 - I use NTSC-U, so I had to port the addresses with wstrt port. The hook address was "unverified".
 - IDK what code type it is, so I picked C2 as the code type.
 - CLF78 never said where it loads the extra BRSTMs from, so I guessed that it worked like the Track Randomizer code.

Got the code compiled and inserted into the main.dol, added extra BRSTMs with Riivolution, and all I get is that Mario Circuit (only track set to 1, all others I left at 0) has no music (including lap 3). Other tracks are fine. Maybe I put the files in the wrong place, maybe I compiled as the wrong code type, and/or maybe the hook address is incorrect, but I don't have any way of knowing for these 3. CLF78 said the code was untested anyways, so maybe it just doesn't work.

So yeah, I think I'll wait for the code to be finished up on.

Here is the source and compiled code I used, for shits and giggles.

Code:
# Hook (USA ONLY) = 8009e01c

# Address Ports (USA ONLY)
.set UtilRandint, 0x800f2e40
.set Racedata, 0x809b8f68
.set sprintf, 0x80010ecc

# Exception Vector Values (DON'T PORT)
.set LastVariant, 0x800001B0

# Check if we are loading a track song by checking the file's first character
lbz r3, 0x15C(r1)

cmpwi r3, 'n'
beq+ isTrack

cmpwi r3, 'S'
beq+ isTrack

cmpwi r3, 'r'
bne end

# Backup LR
isTrack:
mflr r26

# Do bl trick
bl trick

# Track counts
.byte 1, 0, 0, 0    # Mario Circuit, Moo Moo Meadows, Mushroom Gorge, Grumble Volcano
.byte 0, 0, 0, 0    # Toad's Factory, Coconut Mall, DK Summit, Wario's Gold Mine
.byte 0, 0, 0, 0    # Luigi Circuit, Daisy Circuit, Moonview Highway, Maple Treeway
.byte 0, 0, 0, 0    # Bowser Castle, Rainbow Road, Dry Dry Ruins, Koopa Cape
.byte 0, 0, 0, 0    # GCN Peach Beach, GCN Mario Circuit, GCN Waluigi Stadium, GCN DK Mountain
.byte 0, 0, 0, 0    # DS Yoshi Falls, DS Desert Hills, DS Peach Gardens, DS Delfino Square
.byte 0, 0, 0, 0    # SNES Mario Circuit 3, SNES Ghost Valley 2, N64 Mario Raceway, N64 Sherbet Land
.byte 0, 0, 0, 0    # N64 Bowser's Castle, N64 DK's Jungle Parkway, GBA Bowser Castle 3, GBA Shy Guy Beach
.byte 0, 0, 0, 0, 0 # Delfino Pier, Block Plaza, Chain Chomp Wheel, Funky Stadium, Thwomp Desert
.byte 0, 0, 0, 0, 0 # GCN Cookie Land, DS Twilight House, SNES Battle Course 4, GBA Battle Course 3, N64 Skyscraper
.byte 1                # Galaxy Colosseum
.align 2

# Format string for final name
.string "/%d%s.brstm"

# String for final lap music
.string "_F"

# String for regular lap music
.string ""
.align 2

# Swap LR back
trick:
mflr r8
mtlr r26

# Load last character of filename before the extension
addi r7, r28, 0x150
lbzx r7, r7, r1

# Assume not fast
li r26, 0

# Check for an F either lower or uppercase
cmpwi r7, 'f'
beq isFast

cmpwi r7, 'F'
bne noFast

# Set r26 to 1 if so
isFast:
li r26, 1

# Check if we should randomize or pick the existing number
noFast:
cmpwi r26, 1
beq lastLap

# Get track slot
lis r7, Racedata@ha
lwz r7, Racedata@l(r7)
lwz r7, 0xB68(r7)

# Setup arguments
li r3, 0
lbzx r4, r7, r8
addi r4, r4, 1

# Call randint
lis r12, UtilRandint@h
ori r12, r12, UtilRandint@l
mtctr r12
bctrl

# Move result to r5 and store it in the EVA
mr r5, r3
lis r3, LastVariant@ha
stb r5, LastVariant@l(r3)
b numberPicked

# Otherwise get previous number stored there
lastLap:
lis r5, LastVariant@ha
lbz r5, LastVariant@l(r5)

# If result is 0, load original track
numberPicked:
cmpwi r5, 0
beq end

# Set the buffer to the beginning of the file extension
addi r3, r28, 0x14F
add r3, r3, r1

# Set format string
addi r4, r8, 0x2C

# Set empty string
addi r6, r8, 0x3B
cmpwi r26, 1
beq call

# Otherwise set fast lap string
subi r6, r6, 3

# Call sprintf
call:
lis r12, sprintf@h
ori r12, r12, sprintf@l
mtctr r12
bctrl

# Original instruction
end:
addi r26, r1, 0x150
Code:
NTSC-U:
C209e01c 00000022
8861015C 2C03006E
41A20014 2C030053
41A2000C 2C030072
408200EC 7F4802A6
48000041 01000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000100
2F256425 732E6272
73746D00 5F460000
7D0802A6 7F4803A6
38FC0150 7CE708AE
3B400000 2C070066
4182000C 2C070046
40820008 3B400001
2C1A0001 4182003C
3CE0809C 80E78F68
80E70B68 38600000
7C8740AE 38840001
3D80800F 618C2E40
7D8903A6 4E800421
7C651B78 3C608000
98A301B0 4800000C
3CA08000 88A501B0
2C050000 41820030
387C014F 7C630A14
3888002C 38C8003B
2C1A0001 41820008
38C6FFFD 3D808001
618C0ECC 7D8903A6
4E800421 3B410150
60000000 00000000
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)