The Legend of Zelda: Majora's Mask
Nintendo's 2000 Nintendo 64 Zelda, a three-day cycle that resets, read through the zeldaret decompilation.
On this page
The atlas reads Majora’s Mask through the Zelda Reverse Engineering Team’s decompilation, C that rebuilds the Nintendo 64’s US 1.0 ROM. Names and comments quoted here are theirs. Nothing has been measured in the game yet.
The clock counts a day as 65,536 units and adds the scene’s time speed on each update, except while the game is paused, a cutscene runs, or most textboxes are open1. Before Link has his ocarina, any scene where time moves runs at 5 units an update, and the game updates once every 3 video frames: about 11 minutes a day, computed at NTSC’s 59.94 frames a second2. Once accepted, the Inverted Song of Time takes 2 units off each update where time moves2.
At the third dawn the moon falls: the day counter goes to 4 and the game fades to Termina Field3. The Song of Time heads it off by resetting the cycle: Link loses his rupees, ammo, keys, and what his bottles hold, but the bank balance stays4. Where the clock goes back to the first dawn is untraced. The Song of Double Time jumps the clock to the next 6:00 or 18:00, though not on the last night5.
Mechanics
| Mechanic | Kind | How |
|---|---|---|
| Time of day | Time loop | a day is 65,536 clock units; the moon falls at the third dawn unless the Song of Time resets the cycle to the first, keeping the bank but not Link's wallet |
Every claim about this game, by concept (5)
References
- ^In the N64 US 1.0 code the clock is a 16-bit count in which a day is 0x10000 units, so a game minute is about 45.5 units (computed; the macro CLOCK_TIME_MINUTE truncates it to 45). Each play update, Environment_UpdateTime adds the time speed R_TIME_SPEED and then, if that speed isn't 0, the save's timeSpeedOffset. It adds only when time isn't stopped, the game isn't paused or over, no textbox is open (or its message id is 0xF7, 0x20D2, 0x140C, or 0x100 through 0x200, or the game mode is the end credits), the debug frame advance (FrameAdvance_IsEnabled) is off, no transition is under way (transitionMode off, or a game mode other than normal) and none has been triggered, and no cutscene runs. From 18:00 until 6:00 it sets the save's isNight flag.Codezeldaret/mmrevised
How we know
23#define CLOCK_TIME(hr, min) (s32)(((hr) * 60 + (min)) * 0x10000 / (24 * 60)) 24#define CLOCK_TIME_MINUTE (CLOCK_TIME(0, 1)) 25#define CLOCK_TIME_HOUR (CLOCK_TIME(1, 0)) 26#define DAY_LENGTH (CLOCK_TIME(24, 0))
include/macros.h lines 23–26 at 710e1a7 · upstream ↗ 334 /* 0x0C */ u16 time; // "zelda_time" ⋮ 336 /* 0x10 */ s32 isNight; // "asahiru_fg" 337 /* 0x14 */ s32 timeSpeedOffset; // "change_zelda_time" 338 /* 0x18 */ s32 day; // "totalday"
include/z64save.h lines 334–338 at 710e1a7 · upstream ↗ 1203 if (!sEnvIsTimeStopped && (pauseCtx->state == PAUSE_STATE_OFF) && (gameOverCtx->state == GAMEOVER_INACTIVE)) { 1204 if ((msgCtx->msgMode == MSGMODE_NONE) || (msgCtx->currentTextId == 0xF7) || (msgCtx->currentTextId == 0x20D2) || 1205 (msgCtx->currentTextId == 0x140C) || 1206 ((msgCtx->currentTextId >= 0x100) && (msgCtx->currentTextId <= 0x200)) || 1207 (gSaveContext.gameMode == GAMEMODE_END_CREDITS)) { 1208 if (!FrameAdvance_IsEnabled(play) && 1209 ((play->transitionMode == TRANS_MODE_OFF) || (gSaveContext.gameMode != GAMEMODE_NORMAL))) { 1210 if (play->transitionTrigger == TRANS_TRIGGER_OFF) { 1211 if ((CutsceneManager_GetCurrentCsId() == CS_ID_NONE) && !Play_InCsMode(play)) { 1212 gSaveContext.save.time = CURRENT_TIME + (u16)R_TIME_SPEED; 1213 if (R_TIME_SPEED != 0) { 1214 gSaveContext.save.time = CURRENT_TIME + (u16)((void)0, gSaveContext.save.timeSpeedOffset);
src/code/z_kankyo.c lines 1203–1214 at 710e1a7 · upstream ↗ 1227 time = CURRENT_TIME; ⋮ 1229 if ((time >= CLOCK_TIME(18, 0)) || (time < CLOCK_TIME(6, 0))) { 1230 gSaveContext.save.isNight = true;
src/code/z_kankyo.c lines 1227–1230 at 710e1a7 · upstream ↗ 1774 if (pauseCtx->state == PAUSE_STATE_OFF) { ⋮ 1779 Environment_UpdateTime(play, envCtx, pauseCtx, msgCtx, gameOverCtx);
src/code/z_kankyo.c lines 1774–1779 at 710e1a7 · upstream ↗ 1051 Environment_Update(this, &this->envCtx, &this->lightCtx, &this->pauseCtx, &this->msgCtx, &this->gameOverCtx,src/code/z_play.c line 1051 at 710e1a7 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^ abcIn the N64 US 1.0 code each scene's header sets its time speed, and a header value of 0xFF gives 0, a scene where time stands still. While Link's ocarina slot is empty, a nonzero scene speed becomes 5, under a decompilers' comment that reads "Increase time speed during first cycle"; the scene's speed becomes R_TIME_SPEED only while Sun's Song is inactive. The Inverted Song of Time is offered only where the scene's restriction flags allow it (otherwise text 0x1B95 and nothing) and the speed isn't 0; accepting it sets the offset to −2, or back to 0 if it was already set, and the update adds the offset only while the speed isn't 0. The game updates once every 3 video frames, set by GameState_SetFramerateDivisor(3) into a field whose comment reads "how many VIs should elapse before next swap". Assuming NTSC's 59.94 video frames a second (the atlas's assumption, not in the code), that is about 20 updates a second, and at speed 5 a game minute takes about 0.46 s, a day about 656 s, and the three days about 33 minutes (computed). The usual speed of a scene is in its header, ROM data the decompilation doesn't hold.Codezeldaret/mmrevised
How we know
393 if (cmd->timeSettings.timeSpeed != 0xFF) { 394 play->envCtx.sceneTimeSpeed = cmd->timeSettings.timeSpeed; 395 } else { 396 play->envCtx.sceneTimeSpeed = 0; ⋮ 399 // Increase time speed during first cycle 400 if ((gSaveContext.save.saveInfo.inventory.items[SLOT_OCARINA] == ITEM_NONE) && (play->envCtx.sceneTimeSpeed != 0)) { 401 play->envCtx.sceneTimeSpeed = 5; ⋮ 404 if (gSaveContext.sunsSongState == SUNSSONG_INACTIVE) { 405 R_TIME_SPEED = play->envCtx.sceneTimeSpeed;
src/code/z_scene.c lines 393–406 at 710e1a7 · upstream ↗ 5890 } else if (sLastPlayedSong == OCARINA_SONG_INVERTED_TIME) { 5891 if (interfaceCtx->restrictions.invSongOfTime == 0) { 5892 if (R_TIME_SPEED != 0) { ⋮ 5895 } else { ⋮ 5898 play->msgCtx.ocarinaMode = OCARINA_MODE_PROCESS_INVERTED_TIME; 5899 } else { 5900 Message_StartTextbox(play, 0x1B8B, NULL); 5901 play->msgCtx.ocarinaMode = OCARINA_MODE_END; ⋮ 5903 } else { 5904 sLastPlayedSong = 0xFF; 5905 Message_StartTextbox(play, 0x1B95, NULL); 5906 play->msgCtx.ocarinaMode = OCARINA_MODE_PROCESS_RESTRICTED_SONG;
src/code/z_message.c lines 5890–5906 at 710e1a7 · upstream ↗ 1212 gSaveContext.save.time = CURRENT_TIME + (u16)R_TIME_SPEED; 1213 if (R_TIME_SPEED != 0) { 1214 gSaveContext.save.time = CURRENT_TIME + (u16)((void)0, gSaveContext.save.timeSpeedOffset);
src/code/z_kankyo.c lines 1212–1214 at 710e1a7 · upstream ↗ 5683 } else if ((msgCtx->textboxEndType == TEXTBOX_ENDTYPE_TWO_CHOICE) && 5684 (play->msgCtx.ocarinaMode == OCARINA_MODE_PROCESS_INVERTED_TIME)) { 5685 if (Message_ShouldAdvance(play)) { 5686 if (msgCtx->choiceIndex == 0) { 5687 Audio_PlaySfx_MessageDecide(); 5688 if (gSaveContext.save.timeSpeedOffset == 0) { 5689 play->msgCtx.ocarinaMode = OCARINA_MODE_APPLY_INV_SOT_SLOW; 5690 gSaveContext.save.timeSpeedOffset = -2; 5691 } else { 5692 play->msgCtx.ocarinaMode = OCARINA_MODE_APPLY_INV_SOT_FAST; 5693 gSaveContext.save.timeSpeedOffset = 0;
src/code/z_message.c lines 5683–5694 at 710e1a7 · upstream ↗ 40void GameState_SetFramerateDivisor(GameState* gameState, s32 divisor) { 41 R_UPDATE_RATE = divisor; 42 gameState->framerateDivisor = divisor; 43 GameState_UpdateFramerateDivisors(divisor);
src/code/game.c lines 40–43 at 710e1a7 · upstream ↗ 243 GameState_SetFramerateDivisor(gameState, 3);src/code/game.c line 243 at 710e1a7 · upstream ↗ 236 cfb->updateRate = gameState->framerateDivisor;src/code/graph.c line 236 at 710e1a7 · upstream ↗ 25 /* 0x11 */ s8 updateRate; // how many VIs should elapse before next swapinclude/scheduler.h line 25 at 710e1a7 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^In the N64 US 1.0 code, the actor En_Test4, which its file's comment describes as "Three-Day Events: day-night transitions", compares each update the clock with the next transition time (6:00 by night, 18:00 by day) by multiplying the 16-bit differences of the current and previous times from it and treating a product of 0 or less as a crossing (the atlas's reading of the test), unless a transition, a cutscene, setup actors, a room load, or the debug camera is under way. When the clock crosses 6:00 with the day counter at 3, it calls Interface_StartMoonCrash, which sets the day to 4 and the clock to 6:00 plus 10 units and starts a white fade to a Termina Field entrance. On days 1 and 2 the same crossing adds a day when no transition cutscene is set or the telescope is on; the other branch (z_en_test4.c L446-L470), which sets a flag the decomp names EVENTINF_TRIGGER_DAYTELOP for the Dawn of a New Day screen, is untraced. Play_Init spawns this actor in dungeon and boss rooms on any day but 0; elsewhere it comes from scene data the atlas hasn't read.Codezeldaret/mmrevised
How we know
4 * Description: Three-Day Events: day-night transitions, shrink screen before next day,src/overlays/actors/ovl_En_Test4/z_en_test4.c line 4 at 710e1a7 · upstream ↗ 404void EnTest4_HandleEvents(EnTest4* this, PlayState* play) { 405 static u16 sDayNightTransitionTimes[THREEDAY_DAYTIME_MAX] = { 406 CLOCK_TIME(6, 0), // THREEDAY_DAYTIME_NIGHT 407 CLOCK_TIME(18, 0), // THREEDAY_DAYTIME_DAY ⋮ 411 if ((play->transitionMode == TRANS_MODE_OFF) && !Play_InCsMode(play) && (play->numSetupActors <= 0) && 412 (play->roomCtx.status == 0) && !Play_IsDebugCamEnabled()) { 413 u16 transitionTime = sDayNightTransitionTimes[this->daytimeIndex]; ⋮ 419 curTimeUntilTransition = CURRENT_TIME - transitionTime; 420 prevTimeUntilTransition = this->prevTime - transitionTime; ⋮ 429 if ((curTimeUntilTransition * prevTimeUntilTransition) <= 0) { ⋮ 439 } else if (transitionTime == CLOCK_TIME(6, 0)) { 440 // previously night, turning day ⋮
src/overlays/actors/ovl_En_Test4/z_en_test4.c lines 404–445 at 710e1a7 · upstream ↗ 446 } else if (((sCsIdList[this->daytimeIndex] <= CS_ID_NONE) || 447 (play->actorCtx.flags & ACTORCTX_FLAG_TELESCOPE_ON)) && 448 (CURRENT_DAY != 3)) { 449 // Turn day without cutscene 450 EnTest4_HandleDayNightSwap(this, play); 451 } else { ⋮ 463 } else { ⋮ 470 SET_EVENTINF(EVENTINF_TRIGGER_DAYTELOP);
src/overlays/actors/ovl_En_Test4/z_en_test4.c lines 446–470 at 710e1a7 · upstream ↗ 115 } else if ((sCsIdList[this->daytimeIndex] <= CS_ID_NONE) || (play->actorCtx.flags & ACTORCTX_FLAG_TELESCOPE_ON)) { 116 // Previously night, turning day, without a cutscene 117 Sram_IncrementDay(); 118 gSaveContext.save.time = CLOCK_TIME(6, 0);
src/overlays/actors/ovl_En_Test4/z_en_test4.c lines 115–118 at 710e1a7 · upstream ↗ 655void Sram_IncrementDay(void) { 656 if (CURRENT_DAY <= 3) { 657 gSaveContext.save.day++; 658 gSaveContext.save.eventDayCount++;
src/code/z_sram_NES.c lines 655–658 at 710e1a7 · upstream ↗ 5612void Interface_StartMoonCrash(PlayState* play) { ⋮ 5617 gSaveContext.save.day = 4; 5618 gSaveContext.save.eventDayCount = 4; 5619 gSaveContext.save.time = CLOCK_TIME(6, 0) + 10; 5620 play->nextEntrance = ENTRANCE(TERMINA_FIELD, 12); 5621 gSaveContext.nextCutsceneIndex = 0; 5622 play->transitionTrigger = TRANS_TRIGGER_START; 5623 play->transitionType = TRANS_TYPE_FADE_WHITE;
src/code/z_parameter.c lines 5612–5623 at 710e1a7 · upstream ↗ 2316 if ((CURRENT_DAY != 0) && 2317 ((this->roomCtx.curRoom.type == ROOM_TYPE_DUNGEON) || (this->roomCtx.curRoom.type == ROOM_TYPE_BOSS))) { 2318 Actor_Spawn(&this->actorCtx, this, ACTOR_EN_TEST4, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0);
src/code/z_play.c lines 2316–2318 at 710e1a7 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^In the N64 US 1.0 code, answering yes to the Song of Time's prompt runs Sram_SaveEndOfCycle, whose comment says it is "Used by Song of Time (when clicking "Yes") and (indirectly) by the "Dawn of the New Day" cutscene". The function sets the day counter to 0 and the clock one unit before 6:00, clears the Inverted Song's offset, and adds one to a reset count capped at 999, but on the song's path the message code saves the day, the time, and the cutscene index before the call and puts them back right after it; where the cycle returns to the first dawn is untraced. It sets the rupees Link carries to 0 and every ammo count to 0 except the pictograph box's, and turns any bottle holding an item from ITEM_POTION_RED through ITEM_OBABA_DRINK back into an empty bottle. It sets a sword at or below the Razor Sword back to the Kokiri Sword (or the Gilded Sword if a stolen-item slot holds it), removes dungeon keys, boss keys, stray fairies, and the pictograph, and clears the event-info flags. Scene flags (switches, chests, collectibles) and week-event flags survive only where a per-scene or per-flag persistence table marks them. Among the rest, it resets five minigame high scores and the three Deku Playground scores, but not the bank balance, which is kept in the high-score slot HS_BANK_RUPEES.Codezeldaret/mmrevised
How we know
5881 if (sLastPlayedSong == OCARINA_SONG_TIME) { 5882 if (interfaceCtx->restrictions.songOfTime == 0) { 5883 Message_StartTextbox(play, 0x1B8A, NULL); 5884 play->msgCtx.ocarinaMode = OCARINA_MODE_PROCESS_SOT;
src/code/z_message.c lines 5881–5884 at 710e1a7 · upstream ↗ 5668 } else if ((msgCtx->textboxEndType == TEXTBOX_ENDTYPE_TWO_CHOICE) && 5669 (play->msgCtx.ocarinaMode == OCARINA_MODE_PROCESS_SOT)) { 5670 if (Message_ShouldAdvance(play)) { 5671 if (msgCtx->choiceIndex == 0) { 5672 Audio_PlaySfx_MessageDecide(); 5673 msgCtx->msgMode = MSGMODE_NEW_CYCLE_0;
src/code/z_message.c lines 5668–5673 at 710e1a7 · upstream ↗ 6022 case MSGMODE_NEW_CYCLE_0: 6023 play->state.unk_A3 = 1; 6024 sp44 = gSaveContext.save.cutsceneIndex; 6025 sp3E = CURRENT_TIME; 6026 sp40 = gSaveContext.save.day; ⋮ 6028 Sram_SaveEndOfCycle(play); 6029 gSaveContext.timerStates[TIMER_ID_MOON_CRASH] = TIMER_STATE_OFF; 6030 func_8014546C(&play->sramCtx); ⋮ 6032 gSaveContext.save.day = sp40; 6033 gSaveContext.save.time = sp3E; 6034 gSaveContext.save.cutsceneIndex = sp44;
src/code/z_message.c lines 6022–6034 at 710e1a7 · upstream ↗ 428 * Used by Song of Time (when clicking "Yes") and (indirectly) by the "Dawn of the New Day" cutscene ⋮ 430void Sram_SaveEndOfCycle(PlayState* play) { ⋮ 437 gSaveContext.save.timeSpeedOffset = 0; 438 gSaveContext.save.eventDayCount = 0; 439 gSaveContext.save.day = 0; 440 gSaveContext.save.time = CLOCK_TIME(6, 0) - 1; ⋮ 442 gSaveContext.save.saveInfo.playerData.threeDayResetCount++; 443 if (gSaveContext.save.saveInfo.playerData.threeDayResetCount > 999) { 444 gSaveContext.save.saveInfo.playerData.threeDayResetCount = 999;
src/code/z_sram_NES.c lines 427–444 at 710e1a7 · upstream ↗ 450 play->actorCtx.sceneFlags.chest &= sPersistentCycleSceneFlags[sceneId].chest; ⋮ 456 for (i = 0; i < SCENE_MAX; i++) { 457 gSaveContext.cycleSceneFlags[i].switch0 = 458 ((void)0, gSaveContext.cycleSceneFlags[i].switch0) & sPersistentCycleSceneFlags[i].switch0;
src/code/z_sram_NES.c lines 450–464 at 710e1a7 · upstream ↗ 486 for (i = 0; i < ARRAY_COUNT(sPersistentCycleWeekEventRegs); i++) { 487 u16 isPersistentBits = sPersistentCycleWeekEventRegs[i]; ⋮ 490 if (!(isPersistentBits & 3)) { 491 gSaveContext.save.saveInfo.weekEventReg[i] = 492 ((void)0, gSaveContext.save.saveInfo.weekEventReg[i]) & (0xFF ^ sBitFlags8[j]); ⋮ 498 for (i = 0; i < ARRAY_COUNT(gSaveContext.eventInf); i++) { 499 gSaveContext.eventInf[i] = 0;
src/code/z_sram_NES.c lines 486–499 at 710e1a7 · upstream ↗ 537 for (i = 0; i < ITEM_NUM_SLOTS; i++) { 538 if (gAmmoItems[i] != ITEM_NONE) { 539 if ((gSaveContext.save.saveInfo.inventory.items[i] != ITEM_NONE) && (i != SLOT_PICTOGRAPH_BOX)) { 540 item = gSaveContext.save.saveInfo.inventory.items[i]; 541 AMMO(item) = 0; ⋮ 546 for (i = SLOT_BOTTLE_1; i <= SLOT_BOTTLE_6; i++) { 547 // Check for all bottled items 548 if (gSaveContext.save.saveInfo.inventory.items[i] >= ITEM_POTION_RED) { 549 if (gSaveContext.save.saveInfo.inventory.items[i] <= ITEM_OBABA_DRINK) { ⋮ 556 gSaveContext.save.saveInfo.inventory.items[i] = ITEM_BOTTLE;
src/code/z_sram_NES.c lines 536–556 at 710e1a7 · upstream ↗ 561 REMOVE_QUEST_ITEM(QUEST_PICTOGRAPH); ⋮ 567 if (GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) <= EQUIP_VALUE_SWORD_RAZOR) { 568 SET_EQUIP_VALUE(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); ⋮ 570 if (CUR_FORM == 0) { 571 if ((STOLEN_ITEM_1 >= ITEM_SWORD_GILDED) || (STOLEN_ITEM_2 >= ITEM_SWORD_GILDED)) { 572 CUR_FORM_EQUIP(EQUIP_SLOT_B) = ITEM_SWORD_GILDED; 573 SET_EQUIP_VALUE(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_GILDED);
src/code/z_sram_NES.c lines 561–573 at 710e1a7 · upstream ↗ 637 Sram_ClearHighscores(); ⋮ 639 for (i = 0; i < 8; i++) { 640 gSaveContext.save.saveInfo.inventory.dungeonItems[i] &= (u8)~1; // remove boss key 641 DUNGEON_KEY_COUNT(i) = 0; 642 gSaveContext.save.saveInfo.inventory.strayFairies[i] = 0; ⋮ 645 gSaveContext.save.saveInfo.playerData.rupees = 0;
src/code/z_sram_NES.c lines 637–645 at 710e1a7 · upstream ↗ 404void Sram_ClearHighscores(void) { 405 HS_SET_BOAT_ARCHERY_HIGH_SCORE(19); 406 HS_SET_HIGH_SCORE_3_LOWER(10); 407 HS_SET_HORSE_BACK_BALLOON_TIME(SECONDS_TO_TIMER(60)); 408 HS_SET_TOWN_SHOOTING_GALLERY_HIGH_SCORE(39); 409 HS_SET_SWAMP_SHOOTING_GALLERY_HIGH_SCORE(10); ⋮ 411 gSaveContext.save.saveInfo.dekuPlaygroundHighScores[0] = SECONDS_TO_TIMER(75); 412 gSaveContext.save.saveInfo.dekuPlaygroundHighScores[1] = SECONDS_TO_TIMER(75); 413 gSaveContext.save.saveInfo.dekuPlaygroundHighScores[2] = SECONDS_TO_TIMER(76);
src/code/z_sram_NES.c lines 404–413 at 710e1a7 · upstream ↗ 613#define HS_GET_BANK_RUPEES() (HIGH_SCORE(HS_BANK_RUPEES) & 0xFFFF) 614#define HS_SET_BANK_RUPEES(rupees) (HIGH_SCORE(HS_BANK_RUPEES) = ((HIGH_SCORE(HS_BANK_RUPEES) & 0xFFFF0000) | (rupees)))
include/z64save.h lines 613–614 at 710e1a7 · upstream ↗ 694#if MM_VERSION >= N64_US 695 include "$(BUILD_DIR)/src/code/z_sram_NES.o" 696#endif
spec/spec lines 694–696 at 710e1a7 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^In the N64 US 1.0 code, accepting the Song of Double Time's prompt sets the clock to 6:00 if the save's isNight flag is set and to 18:00 if not, and turns off the moon's countdown timer; this code doesn't change the day counter. The three-day events actor (En_Test4) then sees the clock cross 6:00 and, in its no-cutscene branch, adds a day; that the jump to exactly 6:00 trips its crossing test is the atlas's reading. The song isn't offered on the third night (day 3 with isNight set) or where a scene's restriction flags forbid it.Codezeldaret/mmrevised
How we know
419 curTimeUntilTransition = CURRENT_TIME - transitionTime; 420 prevTimeUntilTransition = this->prevTime - transitionTime; ⋮ 429 if ((curTimeUntilTransition * prevTimeUntilTransition) <= 0) {
src/overlays/actors/ovl_En_Test4/z_en_test4.c lines 419–429 at 710e1a7 · upstream ↗ 115 } else if ((sCsIdList[this->daytimeIndex] <= CS_ID_NONE) || (play->actorCtx.flags & ACTORCTX_FLAG_TELESCOPE_ON)) { 116 // Previously night, turning day, without a cutscene 117 Sram_IncrementDay(); 118 gSaveContext.save.time = CLOCK_TIME(6, 0);
src/overlays/actors/ovl_En_Test4/z_en_test4.c lines 115–118 at 710e1a7 · upstream ↗ 5908 } else if (sLastPlayedSong == OCARINA_SONG_DOUBLE_TIME) { 5909 if (interfaceCtx->restrictions.songOfDoubleTime == 0) { 5910 if ((CURRENT_DAY != 3) || (gSaveContext.save.isNight == 0)) { 5911 if (gSaveContext.save.isNight) { 5912 Message_StartTextbox(play, sDoubleTimeSkipToDayTextIds[CURRENT_DAY - 1], NULL); 5913 } else { 5914 Message_StartTextbox(play, sDoubleTimeSkipToNightTextIds[CURRENT_DAY - 1], NULL); ⋮ 5916 play->msgCtx.ocarinaMode = OCARINA_MODE_PROCESS_DOUBLE_TIME; 5917 } else { 5918 Message_StartTextbox(play, 0x1B94, NULL); 5919 play->msgCtx.ocarinaMode = OCARINA_MODE_END;
src/code/z_message.c lines 5908–5919 at 710e1a7 · upstream ↗ 5702 } else if ((msgCtx->textboxEndType == TEXTBOX_ENDTYPE_TWO_CHOICE) && 5703 (play->msgCtx.ocarinaMode == OCARINA_MODE_PROCESS_DOUBLE_TIME)) { 5704 if (Message_ShouldAdvance(play)) { 5705 if (msgCtx->choiceIndex == 0) { 5706 Audio_PlaySfx_MessageDecide(); 5707 if (gSaveContext.save.isNight != 0) { 5708 gSaveContext.save.time = CLOCK_TIME(6, 0); 5709 } else { 5710 gSaveContext.save.time = CLOCK_TIME(18, 0); ⋮ 5712 play->msgCtx.ocarinaMode = OCARINA_MODE_APPLY_DOUBLE_SOT; 5713 gSaveContext.timerStates[TIMER_ID_MOON_CRASH] = TIMER_STATE_OFF;
src/code/z_message.c lines 5702–5713 at 710e1a7 · upstream ↗ 5305s16 sDoubleTimeSkipToNightTextIds[] = { 5306 0x1B91, // Night of 1st day 5307 0x1B90, // Night of 2nd day 5308 0x1B8F, // Night of final day ⋮ 5310s16 sDoubleTimeSkipToDayTextIds[] = { 5311 0x1B92, // Dawn of 2nd day 5312 0x1B8E, // Dawn of final day
src/code/z_message.c lines 5305–5313 at 710e1a7 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
Sources
Code
- zeldaret. 2026. “mm: a decompilation of The Legend of Zelda: Majora's Mask (zeldaret/mm).” Commit 710e1a7. zeldaret/mm @ 710e1a7 · licence, all uses