Lunar Porter, rung two: it lands, or it does not

The terrain is an array in Data Memory rather than something read back out
of the map, and that is the whole reason this is cheap: the ground under
the lander is one index into 128 bytes, where asking the screen would be a
transfer through the controller every frame.

The column is the world position over eight, masked to the moon's 128. The
surface is that column's row times eight - three turns left of the shift
register, since a row is at most 24 and 192 fits in the low half. The feet
are the lander's top plus its eight pixels.

WHAT DECIDES IS THE SPEED AT THE MOMENT IT ARRIVES. Both of them, and both
have to be gentle: three quarters of a pixel a frame downwards and half of
one sideways. Sideways is the tighter on purpose, because a landing that
was soft downwards and sliding is a lander on its side - which is the
interesting half of the difficulty, and the half the drift bar was blind
about until it existed.

Two fixtures say it works, and they differ only in what was held: one
holds nothing and falls the whole way, the other pulses the thruster six
frames in sixteen and survives. Same terrain, same seed, same keys.

Also: the gamepad did nothing, and the reason is that the four direction
buttons are the D-PAD. A lot of controllers made this century have one
nobody uses - the thumb goes on the stick, which reports as an axis rather
than a button - so a pad that was plugged in and working correctly did
nothing at all. The stick counts as held past halfway now. Untested here,
because there is no controller in this environment and the suite runs
headless; Voyager also says at startup which controllers it can see, so a
pad that still does nothing can be told apart from one nothing noticed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-09-02 22:33:32 -04:00
co-authored by Claude Opus 5
parent db0c26e13f
commit 8eb4e4d67e
20 changed files with 207 additions and 18 deletions
+30
View File
@@ -129,6 +129,24 @@ static void readPads(void) {
if (IsGamepadButtonDown(n, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)){ held |= PAD_B; }
if (IsGamepadButtonDown(n, GAMEPAD_BUTTON_MIDDLE_RIGHT)) { held |= PAD_START; }
if (IsGamepadButtonDown(n, GAMEPAD_BUTTON_MIDDLE_LEFT)) { held |= PAD_SELECT; }
// ---- And the stick, which is what most people actually push ----
//
// The four buttons above are the D-PAD, and a lot of controllers made this
// century have one that nobody uses: the thumb goes on the stick, which reports
// as an axis and not as a button, so a pad that was plugged in and working did
// nothing at all.
//
// Past halfway counts as held. That is a blunt line and the right kind of blunt
// for a device that reports what is DOWN - a machine with eight bits a pad has
// nothing to say about three-fifths of a push, and picking the threshold here
// rather than in every program is the point of the pad being a device.
const float across = GetGamepadAxisMovement(n, GAMEPAD_AXIS_LEFT_X);
const float down = GetGamepadAxisMovement(n, GAMEPAD_AXIS_LEFT_Y);
if (across > 0.5f) { held |= PAD_RIGHT; }
if (across < -0.5f) { held |= PAD_LEFT; }
if (down > 0.5f) { held |= PAD_DOWN; }
if (down < -0.5f) { held |= PAD_UP; }
}
if (n == 0) {
// ---- And the keyboard, on top of it ----
@@ -431,6 +449,18 @@ int main(int argc, char *argv[]) {
// to find out that a default was left as it was found.
SetExitKey(KEY_NULL);
// ---- What controllers the host can see, said out loud ----
//
// A pad that is plugged in and does nothing is indistinguishable from a pad the front
// end never noticed, and the difference is the whole of what to do about it: one is a
// mapping to fix and the other is a driver. Saying which at startup costs a line and
// answers it without anybody having to guess.
for (int n = 0; n < PAD_COUNT; n++) {
if (IsGamepadAvailable(n)) {
printf("Controller %d: %s\n", n, GetGamepadName(n));
}
}
// ---- And a speaker, if the host has one ----
//
// Asked for rather than assumed: a machine with no audio device is a perfectly good