20 Followers
21 Following
56 Posts

lucie, lola ou luz 

j'utilise >1 prénoms. je préfère sans majuscule !
fyi mon display name est aléatoirement rotate tout les jours

Pronounsaël/elle - she/her
les supérieurs hiérarchiques qui envoient des mails un dimanche après-midi sans même dire bonjour/merci 
Scooby Doo Who's Watching Who DS Intro X Destiny's Child Lose My Breath Mashup

YouTube

so, what is this leftover code? probably a particle system! there is a flag to enable the spawn of new particle at the current (x, y) coordinates, the particle will move downwards with a random aspect, they all share a single texture...

a possible usecase that I can see (although it would only work on the subscreen..) would to be spawn a trail of particles when the screen is touched. But I have no idea how it would have been used by this game (it's not like the touch-screen is used a lot...)

the many other global variables are:

  • the maximum number of "alive" structure instances;
  • the current number of "alive" structure instances;
  • whether the system is active at all;
  • whether new structure instances will be spawned is the maximum number of alive parameter
  • the state of a linear congruent generator (the current state, and the two LCG parameters) (interesting that these two parameters are not hardcoded!)
  • the base age for newly spawned instances;
  • the initial position of newly spawned instances;
  • whether to enable gravity: if enabled, the y direction vector component willbe decremented by 1 each update loop.
  • two 12 and 16 bytes values. these values are not referenced by anything sotheir purpose is unknown.
  • on which screen the instances must be spawned.

the LCG are used to randomize the instance's direction when they are spawned (between (-6, 0) and (4, 5)) as well as the instance time-to-live.

by reading the decompiled code, giving types to variables and names to variables, we can understand what the code does.

in essence, each of the 32 structure represent a sprite. each sprite has a "frames-to-live" field. structure instances with a non-zero field are considered "alive". an allocated object id. they also have an (x, y) pair of coordinates, a direction vector.

regarding the two functions:

  • the function called as part of the update loop updates all "alive" instances. it update their position field according to the direction vector and update the OAM attributes of their allocated object id with to match the newly updated position.
    it will also spawn new instances if possible, more on that below.

  • the function conditionally called when a GUI transition happens frees allocated OAM/OBJ slots.
    a single OAM slot is reserved for each structure, and 4 OBJ tiles are reserved and shared for all sprites.

  • moreover, these functions use stuff related to OAM/OBJ management that I previously reverse-engineered.

    okay! by analysing the two large functions, we can find reverse engineer the global data referenced. It contains many global parameters and an array of 32 structures (which are relatively small, 0x18 bytes each).

    these global variables are all grouped together and sandwiched between other values I already understood, so it all makes sense. we can check via the cross references to those globals to make sure we didn't miss other related functions.

    before analying these functions, we need to talk about how 2D rendering on the Nintendo DS works.

    among other things, the NDS has moveable objects (often called sprites). these can be moved to arbitrary positions, have their rendering priority configured, their palette changed...

    each sprite is configured via its OAM (object attribute memory). the OAM for a sprite is just 4 bytes located at a specific address in memory.

    the OAM does not direct contain the sprite data (that wouldn't fit). instead, the attributes of a sprite contain the tile index to use for the sprite. this way, the pixel data can be shared between sprites.

    tile data is stored in another part of VRAM called "OBJ vram". OBJ memory is divded into "slots" with a size of 8x8 pixels, although sprites can be larger than 8x8.

    a final thing: the Nintendo DS has two screens! OAM and OBJ memory is duplicated for both screen: the main screen, and the sub screen.

    what code is left in the ROM? essentially, code that called in two update loops:

  • in the update loop of the "2d rendering" loop.a function is always unconditionally called.
  • in a specific part of the GUI update loop, ran when a GUI screen is changed(like when opening the pause menu). in this case, it calls a function, which returns a global value. if this value isn't 0, another function is called. among other things, it resets the flag to zero.