You've already forked Starlight-SMO-Example
mirror of
https://github.com/CraftyBoss/Starlight-SMO-Example.git
synced 2026-04-01 08:53:17 -07:00
56 lines
2.2 KiB
C++
56 lines
2.2 KiB
C++
#include "al/LiveActor.hpp"
|
|
#include "al/util.hpp"
|
|
#include "game/StageScene.hpp"
|
|
#include "rs/util.hpp"
|
|
|
|
void teleportMarioIfNeeded() {
|
|
// We replaced a `MOV X19, X0` instruction with the hook
|
|
// that calls this function; manually reimplement the
|
|
// now-missing instruction here
|
|
__asm ("MOV X19, X0");
|
|
|
|
// A reference to the current `StageScene` is in the X0 register;
|
|
// read it into a local variable.
|
|
//
|
|
// Note: Because the `StageScene` reference is in X0, we could also
|
|
// just accept it as a parameter for this function, since that
|
|
// parameter would be expected to be passed in X0. Likewise,
|
|
// we could return `stageScene` at the end of this function to
|
|
// place it back in X0.
|
|
//
|
|
// However, that sort of interaction with the hooked code
|
|
// isn't semantically what's happening here; plus, the values you
|
|
// need might not always be in the argument registers;
|
|
// so I'd rather think of this as code that simply reads whatever
|
|
// state is necessary and restores registers at the end, rather
|
|
// than pretending it's a normal function call.
|
|
StageScene *stageScene;
|
|
__asm ("MOV %[result], X0" : [result] "=r" (stageScene));
|
|
|
|
// Check if Left D-Pad is pressed, using the default
|
|
// controller port (specified by `-1`)
|
|
if (al::isPadTriggerLeft(-1)) {
|
|
|
|
// Get the current player actor.
|
|
//
|
|
// Note: The teleportation does not appear to affect captures,
|
|
// so this presumably always returns a reference to Mario
|
|
// rather than the currently-controlled actor.
|
|
al::LiveActor *player = rs::getPlayerActor(stageScene);
|
|
|
|
// Set the player's vertical translation.
|
|
//
|
|
// Note: Collision is still a factor here, and this will
|
|
// not teleport Mario through walls.
|
|
//
|
|
// If you see no change, try triggering the teleportation
|
|
// during a jump; you may have been seeing no movement on
|
|
// the ground because the y=0 plane is below you in the current area.
|
|
al::setTransY(player, 0.0);
|
|
}
|
|
|
|
// Restore original state by placing
|
|
// `stageScene` back into the X0 register
|
|
__asm ("MOV X0, %[input]" : [input] "=r" (stageScene));
|
|
}
|