• 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 Memory Card Variables

Punkline

Dr. Frankenstack
Joined
May 15, 2015
Messages
423
This code maxes out the trophy collection in a savegame, and then scraps the memory mechanic used to keep track of how many trophies are collected.

In return, the code provides developers with 0x240 bytes of space on the memory card that can be used to define custom variables that can be recovered after the game powers off. This contiguous region can be accessed from from a buffer starting at static address 8045C394 without any special setup:


UnclePunch UnclePunch T tauKhan DRGN DRGN SinsOfApathy SinsOfApathy

---


A couple of important things to note before using this code:


INSTALLING THIS WILL DESTROY YOUR TROPHY COLLECTION DATA.

This code deliberately corrupts and repurposes a small memory region that is responsible for copying information about the number of trophies you have collected to/from the memory card, and any records you have will be destroyed!
  • If you care about this, then back up your memory card before installing!


UNINSTALLING THIS WILL DESTROY THE STATE OF CUSTOM VARIABLES.

Though this code affects data on the memory card; it is itself installed in the DOL.
  • This may unexpectedly cause issues if used on a memory card that is shared between multiple Melee setups.
  • If the code is uninstalled, or a version of Melee without the code loads a modified save file -- then normal trophy spawning/collection behavior will overwrite any variables being saved in the region.
I have designed it so that the trophy total will be interpreted as 0 if the inhibitors to the vanilla interface included with the code fail for any reason.
  • This should allow for vanilla trophy collection behavior to resume without issue when uninstalling the code.
    • Any residual data in the region however will still provide lasting artifacts in the gallery index, so it’s recommended to also erase your trophy data from the options menu if you decide to stop using the code with a save file.

---


Memory Card Variables:

Code:
-==-

Memory Card Variables
Repurpose the trophy collection array normally stored in the memory card.
Enables 0x240 contiguous bytes for savable variabls, starting at 8045C394.

- Trophy collection in gallery appears complete by default when code is installed.
- Installing code destroys record of existing trophy counts.
- Uninstalling code after memorycard has initialized destroys state of custom variables.
[Punkline]
NTSC 1.02 --- 0x80304908 ---- 7C03022E -> 38007fff
------------- 0x80304a3c ---- 7C03022E -> 38007fff
------------- 0x8030496c ---- 7C03022E -> 38007fff
------------- 0x80304ad8 ---- 7C03222E -> 38007fff
------------- 0x803049dc ---- B0030000 -> 60000000
------------- 0x80304de4 ---- 7C03CA2E -> 38007fff
------------- 0x80305128 ---- 7C03E22E -> 38007fff
------------- 0x8030519c ---- 7C03E22E -> 38007fff
------------- 0x8030522c ---- 7C03E22E -> 38007fff
------------- 0x8030526c ---- 7C03E22E -> 38007fff
------------- 0x803052a4 ---- 7C03E22E -> 38007fff
------------- 0x80311990 ---- 38BF0000 -> 38BE019C
------------- 0x803123a8 ---- B0050000 -> 60000000
------------- 0x803123c4 ---- B0050000 -> 60000000
------------- 0x80312448 ---- B01A0000 -> 60000000
------------- 0x803125e8 ---- B01D0000 -> 60000000
------------- 0x80312748 ---- B01C0000 -> 60000000
------------- 0x803054a4 ---- 7C03EA2E -> 38007fff
------------- 0x80305500 ---- B0030000 -> 60000000
------------- 0x803055fc ---- B0030000 -> 60000000
------------- 0x8030567c ---- 7C03EA2E -> 38007fff
------------- 0x803056bc ---- B0030000 -> 60000000
------------- 0x803057cc ---- B0030000 -> 60000000
------------- 0x8030580c ---- B0040000 -> 60000000
------------- 0x80305a24 ---- 7C03DA2E -> 38007fff
------------- 0x80305a3c ---- B0030000 -> 60000000
------------- 0x80305a74 ---- 7C03DB2E -> 60000000
------------- 0x80306690 ---- 7C03F22E -> 38007fff
------------- 0x8030b2a0 ---- 7C03022E -> 38007fff
------------- 0x8030b2f4 ---- B0030000 -> 60000000
------------- 0x80310550 ---- 7C03022E -> 38007fff
------------- 0x803105a8 ---- B0030000 -> 60000000
------------- 0x80310704 ---- 7C03022E -> 38007fff
------------- 0x80310758 ---- B0030000 -> 60000000
------------- 0x80311710 ---- B01D0000 -> 60000000
------------- 0x80311744 ---- B01D0000 -> 60000000
------------- 0x8015cc94 ---- 38631cd0 -> 38631f18
------------- 0x8015cc80 ---- 4e800020 -> Branch
A003FFFC 2C000000 40820010 80030246 2C007FFF 41A20034 38000124 38A3FFFE 7C0903A6 38000000 B4050002 4200FFFC 38007FFF 38C00000 B0030248 38E00125 B0C3FFFC B0E30244 4E800020 60000000
#
Code:
    -==-

!
ASM - Memory Card Variables
Repurpose the trophy collection array normally stored in the memory card.
Enables 0x240 contiguous bytes for savable variabls, starting at 8045C394.

- Trophy collection in gallery appears complete by default when code is installed.
- Installing code destroys record of existing trophy counts.
- Uninstalling code after memorycard has initialized destroys state of custom variables.
[Punkline]
NTSC 1.02 --- 0x80304908 ---- 7C03022E -> 38007fff
------------- 0x80304a3c ---- 7C03022E -> 38007fff
------------- 0x8030496c ---- 7C03022E -> 38007fff
------------- 0x80304ad8 ---- 7C03222E -> 38007fff
------------- 0x803049dc ---- B0030000 -> 60000000
------------- 0x80304de4 ---- 7C03CA2E -> 38007fff
------------- 0x80305128 ---- 7C03E22E -> 38007fff
------------- 0x8030519c ---- 7C03E22E -> 38007fff
------------- 0x8030522c ---- 7C03E22E -> 38007fff
------------- 0x8030526c ---- 7C03E22E -> 38007fff
------------- 0x803052a4 ---- 7C03E22E -> 38007fff
------------- 0x80311990 ---- 38BF0000 -> 38BE019C
------------- 0x803123a8 ---- B0050000 -> 60000000
------------- 0x803123c4 ---- B0050000 -> 60000000
------------- 0x80312448 ---- B01A0000 -> 60000000
------------- 0x803125e8 ---- B01D0000 -> 60000000
------------- 0x80312748 ---- B01C0000 -> 60000000
------------- 0x803054a4 ---- 7C03EA2E -> 38007fff
------------- 0x80305500 ---- B0030000 -> 60000000
------------- 0x803055fc ---- B0030000 -> 60000000
------------- 0x8030567c ---- 7C03EA2E -> 38007fff
------------- 0x803056bc ---- B0030000 -> 60000000
------------- 0x803057cc ---- B0030000 -> 60000000
------------- 0x8030580c ---- B0040000 -> 60000000
------------- 0x80305a24 ---- 7C03DA2E -> 38007fff
------------- 0x80305a3c ---- B0030000 -> 60000000
------------- 0x80305a74 ---- 7C03DB2E -> 60000000
------------- 0x80306690 ---- 7C03F22E -> 38007fff
------------- 0x8030b2a0 ---- 7C03022E -> 38007fff
------------- 0x8030b2f4 ---- B0030000 -> 60000000
------------- 0x80310550 ---- 7C03022E -> 38007fff
------------- 0x803105a8 ---- B0030000 -> 60000000
------------- 0x80310704 ---- 7C03022E -> 38007fff
------------- 0x80310758 ---- B0030000 -> 60000000
------------- 0x80311710 ---- B01D0000 -> 60000000
------------- 0x80311744 ---- B01D0000 -> 60000000
------------- 0x8015cc94 ---- 38631cd0 -> 38631f18
------------- 0x8015cc80 ---- 4e800020 -> Branch
lhz r0, -0x4(r3) # r0 = total unique trophies
cmpwi r0, 0      # == minimum?
bne- _clear
# if total collection is not 0, then we haven't initialized yet
# else, confirm initialization conditions:

lwz r0, 291<<1(r3)
cmpwi r0, 0x7FFF
beq+ _return
# if collection is 0 naturally, then the value 0x00007FFF here will be impossible
# -- if comparison is successful, then we know that card is currently storing custom variables
# -- else, we need to initialize memory for first use:

  _clear:
  li r0, 292
  subi r5, r3, 2
  mtctr r0
  li r0, 0
  # setup for loop

  _for_each_hword:
    sthu r0, 0x2(r5)
    bdnz+ _for_each_hword
    # clear all but last hword in trophy array

  li r0, 0x7FFF
  li r6, 0
  sth r0, 292<<1(r3)
  li r7, 293
  sth r6, -0x4(r3)
  sth r7, 290<<1(r3)
  # update conditional values so that newly initialized space isn't cleared next time

_return:
blr
nop

---


Examples:
(coming soon)
 
Last edited:

UnclePunch

Smash Ace
Joined
Nov 9, 2014
Messages
673
This code maxes out the trophy collection in a savegame, and then scraps the memory mechanic used to keep track of how many trophies are collected.

In return, the code provides developers with 0x240 bytes of space on the memory card that can be used to define custom variables that can be recovered after the game powers off. This contiguous region can be accessed from from a buffer starting at static address 8045C394 without any special setup:


UnclePunch UnclePunch T tauKhan DRGN DRGN SinsOfApathy SinsOfApathy

---


A couple of important things to note before using this code:


INSTALLING THIS WILL DESTROY YOUR TROPHY COLLECTION DATA.

This code deliberately corrupts and repurposes a small memory region that is responsible for copying information about the number of trophies you have collected to/from the memory card, and any records you have will be destroyed!
  • If you care about this, then back up your memory card before installing!


UNINSTALLING THIS WILL DESTROY THE STATE OF CUSTOM VARIABLES.

Though this code affects data on the memory card; it is itself installed in the DOL.
  • This may unexpectedly cause issues if used on a memory card that is shared between multiple Melee setups.
  • If the code is uninstalled, or a version of Melee without the code loads a modified save file -- then normal trophy spawning/collection behavior will overwrite any variables being saved in the region.
I have designed it so that the trophy total will be interpreted as 0 if the inhibitors to the vanilla interface included with the code fail for any reason.
  • This should allow for vanilla trophy collection behavior to resume without issue when uninstalling the code.
    • Any residual data in the region however will still provide lasting artifacts in the gallery index, so it’s recommended to also erase your trophy data from the options menu if you decide to stop using the code with a save file.

---


Memory Card Variables:

Code:
-==-

Memory Card Variables
Repurpose the trophy collection array normally stored in the memory card.
Enables 0x240 contiguous bytes for savable variabls, starting at 8045C394.

- Trophy collection in gallery appears complete by default when code is installed.
- Installing code destroys record of existing trophy counts.
- Uninstalling code after memorycard has initialized destroys state of custom variables.
[Punkline]
NTSC 1.02 --- 0x80304908 ---- 7C03022E -> 38007fff
------------- 0x80304a3c ---- 7C03022E -> 38007fff
------------- 0x8030496c ---- 7C03022E -> 38007fff
------------- 0x80304ad8 ---- 7C03222E -> 38007fff
------------- 0x803049dc ---- B0030000 -> 60000000
------------- 0x80304de4 ---- 7C03CA2E -> 38007fff
------------- 0x80305128 ---- 7C03E22E -> 38007fff
------------- 0x8030519c ---- 7C03E22E -> 38007fff
------------- 0x8030522c ---- 7C03E22E -> 38007fff
------------- 0x8030526c ---- 7C03E22E -> 38007fff
------------- 0x803052a4 ---- 7C03E22E -> 38007fff
------------- 0x80311990 ---- 38BF0000 -> 38BE019C
------------- 0x803123a8 ---- B0050000 -> 60000000
------------- 0x803123c4 ---- B0050000 -> 60000000
------------- 0x80312448 ---- B01A0000 -> 60000000
------------- 0x803125e8 ---- B01D0000 -> 60000000
------------- 0x80312748 ---- B01C0000 -> 60000000
------------- 0x803054a4 ---- 7C03EA2E -> 38007fff
------------- 0x80305500 ---- B0030000 -> 60000000
------------- 0x803055fc ---- B0030000 -> 60000000
------------- 0x8030567c ---- 7C03EA2E -> 38007fff
------------- 0x803056bc ---- B0030000 -> 60000000
------------- 0x803057cc ---- B0030000 -> 60000000
------------- 0x8030580c ---- B0040000 -> 60000000
------------- 0x80305a24 ---- 7C03DA2E -> 38007fff
------------- 0x80305a3c ---- B0030000 -> 60000000
------------- 0x80305a74 ---- 7C03DB2E -> 60000000
------------- 0x80306690 ---- 7C03F22E -> 38007fff
------------- 0x8030b2a0 ---- 7C03022E -> 38007fff
------------- 0x8030b2f4 ---- B0030000 -> 60000000
------------- 0x80310550 ---- 7C03022E -> 38007fff
------------- 0x803105a8 ---- B0030000 -> 60000000
------------- 0x80310704 ---- 7C03022E -> 38007fff
------------- 0x80310758 ---- B0030000 -> 60000000
------------- 0x80311710 ---- B01D0000 -> 60000000
------------- 0x80311744 ---- B01D0000 -> 60000000
------------- 0x8015cc94 ---- 38631cd0 -> 38631f18
------------- 0x8015cc80 ---- 4e800020 -> Branch
A003FFFC 2C000000 40820010 80030246 2C007FFF 41A20034 38000124 38A3FFFE 7C0903A6 38000000 B4050002 4200FFFC 38007FFF 38C00000 B0030248 38E00125 B0C3FFFC B0E30244 4E800020 60000000
#
Code:
    -==-

!
ASM - Memory Card Variables
Repurpose the trophy collection array normally stored in the memory card.
Enables 0x240 contiguous bytes for savable variabls, starting at 8045C394.

- Trophy collection in gallery appears complete by default when code is installed.
- Installing code destroys record of existing trophy counts.
- Uninstalling code after memorycard has initialized destroys state of custom variables.
[Punkline]
NTSC 1.02 --- 0x80304908 ---- 7C03022E -> 38007fff
------------- 0x80304a3c ---- 7C03022E -> 38007fff
------------- 0x8030496c ---- 7C03022E -> 38007fff
------------- 0x80304ad8 ---- 7C03222E -> 38007fff
------------- 0x803049dc ---- B0030000 -> 60000000
------------- 0x80304de4 ---- 7C03CA2E -> 38007fff
------------- 0x80305128 ---- 7C03E22E -> 38007fff
------------- 0x8030519c ---- 7C03E22E -> 38007fff
------------- 0x8030522c ---- 7C03E22E -> 38007fff
------------- 0x8030526c ---- 7C03E22E -> 38007fff
------------- 0x803052a4 ---- 7C03E22E -> 38007fff
------------- 0x80311990 ---- 38BF0000 -> 38BE019C
------------- 0x803123a8 ---- B0050000 -> 60000000
------------- 0x803123c4 ---- B0050000 -> 60000000
------------- 0x80312448 ---- B01A0000 -> 60000000
------------- 0x803125e8 ---- B01D0000 -> 60000000
------------- 0x80312748 ---- B01C0000 -> 60000000
------------- 0x803054a4 ---- 7C03EA2E -> 38007fff
------------- 0x80305500 ---- B0030000 -> 60000000
------------- 0x803055fc ---- B0030000 -> 60000000
------------- 0x8030567c ---- 7C03EA2E -> 38007fff
------------- 0x803056bc ---- B0030000 -> 60000000
------------- 0x803057cc ---- B0030000 -> 60000000
------------- 0x8030580c ---- B0040000 -> 60000000
------------- 0x80305a24 ---- 7C03DA2E -> 38007fff
------------- 0x80305a3c ---- B0030000 -> 60000000
------------- 0x80305a74 ---- 7C03DB2E -> 60000000
------------- 0x80306690 ---- 7C03F22E -> 38007fff
------------- 0x8030b2a0 ---- 7C03022E -> 38007fff
------------- 0x8030b2f4 ---- B0030000 -> 60000000
------------- 0x80310550 ---- 7C03022E -> 38007fff
------------- 0x803105a8 ---- B0030000 -> 60000000
------------- 0x80310704 ---- 7C03022E -> 38007fff
------------- 0x80310758 ---- B0030000 -> 60000000
------------- 0x80311710 ---- B01D0000 -> 60000000
------------- 0x80311744 ---- B01D0000 -> 60000000
------------- 0x8015cc94 ---- 38631cd0 -> 38631f18
------------- 0x8015cc80 ---- 4e800020 -> Branch
lhz r0, -0x4(r3) # r0 = total unique trophies
cmpwi r0, 0      # == minimum?
bne- _clear
# if total collection is not 0, then we haven't initialized yet
# else, confirm initialization conditions:

lwz r0, 291<<1(r3)
cmpwi r0, 0x7FFF
beq+ _return
# if collection is 0 naturally, then the value 0x00007FFF here will be impossible
# -- if comparison is successful, then we know that card is currently storing custom variables
# -- else, we need to initialize memory for first use:

  _clear:
  li r0, 292
  subi r5, r3, 2
  mtctr r0
  li r0, 0
  # setup for loop

  _for_each_hword:
    sthu r0, 0x2(r5)
    bdnz+ _for_each_hword
    # clear all but last hword in trophy array

  li r0, 0x7FFF
  li r6, 0
  sth r0, 292<<1(r3)
  li r7, 293
  sth r6, -0x4(r3)
  sth r7, 290<<1(r3)
  # update conditional values so that newly initialized space isn't cleared next time

_return:
blr
nop

---


Examples:
(coming soon)
this is perfect, i could use some extra space to save data in training mode.

i tried doing something like this a few weeks ago but it seemed most the code that references trophy data was in-lined and spread all over the place. thanks for putting in the time to track it all down!
 

Punkline

Dr. Frankenstack
Joined
May 15, 2015
Messages
423
this is perfect, i could use some extra space to save data in training mode.

i tried doing something like this a few weeks ago but it seemed most the code that references trophy data was in-lined and spread all over the place. thanks for putting in the time to track it all down!

I’m glad to hear it’ll be useful!

I actually didn’t know much about this memory card region until the other day. I was reviewing this code to see if I could make some variables for additional parameters in the options menu, and I learned that the following r13 offset seems to hold a pointer to the start of a region used at least in part by the memory card:

-0x77C0(r13) = Melee NTSC 1.2, 1.2, 1.0
-0x77A8(r13) = Melee PAL


In NTSC 1.02, this pointer points to static address 8045A6C0, and does not appear to change during runtime.
I’m unsure of what it’s total scope is, but from the various functions I skimmed over, I found that it appears to go on at least for 0x2FF8 bytes, and includes the “current multiplayer match settings” described in the SSBM Data Sheet, among other static structures.

While looking at a function that accesses this region, I noticed that many other functions compiled nearby also accessed -0x77C0(r13).

I counted something like 155 contiguous functions starting at 8015CC34. The bulk of them are simple get/set interface functions, and are informative of various data structures contained in this 8045A6C0 region used by the memory card.
SinsOfApathy SinsOfApathy

---


I was interested to see if I could exploit these interface functions by providing an AND mask for getting/setting things like the language region ID, or the deflicker option. I thought I could then use the unused bits for storing bools. I realized though that doing so would probably cause bad things to happen if the code was ever uninstalled, so I started exploring for safer variables to hitch a ride on.

I didn’t explore much, but here’s what I found before deciding to dig into the trophy array:

Code:
From 8015CC34 base (or -0x77C0(r13) pointer):

0x0000    byte -- unknown flag (for checking card status?)

---

0x1868    start of a 0x1790-byte region
# gets copied from call made at 803ab480.
# also see 8015ed8c
0x2FF8    (end of copied region)

Inside of region:


0x186C    byte -- unknown flag bits (0F)
0x1870    unknown base address
0x1880    unknown base address
0x1890    unknown base address
0x1898    unknown base address
# see interface functions at and around 8015ed98
# (I only noted the ones I saw in-between start of copied region and trophies)



0x1cb8    byte -- Item Frequency
# FF = None, 00 = Very Low, 01 = Low  
# ...  
# 04 = Very High, 05+ = (unselectable) Very Very High

0x1cbc    word -- Item Toggle Flagfield
# bools

0x1cc0    byte -- Rumble P1
0x1cc1    byte -- Rumble P2
0x1cc2    byte -- Rumble P3
0x1cc3    byte -- Rumble P4
# 00 = Off, 01 = On

0x1cc4    byte -- Sound Balance
# 00 = regular, 64 = only SFX, 9C = only Music
# between 0x65-0x9B crashes

0x1cc5    byte -- Deflicker
# 00 = Off, 01 = On

0x1cc6    byte -- Language
# 00 = Japanese, 01 = US Eng
# PAL Only: 02 = UK Eng, 03 = German, 04 = French, 05 = Italian, 06 = Spanish

0x1cc8    word -- Random Stage Toggle Flagfield
# bools



0x1cd0    hword - Unique Trophy count
# if higher than true trophy count, gallery displays dummy MARIO trophies
# if higher than max trophy count (293, 0x125) then attempt to display crashes

0x1cd2    hword - Trophy flags
# unknown bools describe state of trophy collection?

0x1cd4    beginning of array of 293 trophy hwords


For each trophy hword:
0x0    (80) bool = “New!” status
# game removes flag on first viewing in gallery

0x0    (40) bool = Allow this trophy to be spawned
# game assigns, and uses them to create a spawn pool
# by forcing the bools to be all false, no trophies will spawn

0x0    (3F) padding? Unknown use, needs testing

0x1    byte = trophy count
# if count is 0, then it will not be displayed in gallery
# if count is set to 0 while being displayed in gallery, it will still show up

UnclePunch UnclePunch - I’m not 100% sure if all of the bools in each trophy hword are accounted for there, but if they are then it would mean that 6 bits in every 16 are unused padding that gets naturally ignored by masks.

I'm pretty sure that would mean that any flags or small ints residing there might survive even with the vanilla trophy collecting behavior, which would be really interesting.
 
Last edited:
Top Bottom