From b376ded880b4c863adfbe99ef04155d492e82c01 Mon Sep 17 00:00:00 2001 From: Treeki Date: Thu, 28 Feb 2013 05:52:50 +0100 Subject: update stars on File Select properly when a level is beaten --- koopatlas.yaml | 6 ++++++ src/levelinfo.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/koopatlas.yaml b/koopatlas.yaml index 3cf2aab..1b619c9 100644 --- a/koopatlas.yaml +++ b/koopatlas.yaml @@ -108,3 +108,9 @@ hooks: src_addr_pal: 0x800B2FF0 target_func: 'ResetAllCompletionCandidates(void)' + - name: UpdateFSStars + type: branch_insn + branch_type: b + src_addr_pal: 0x801028D0 + target_func: 'UpdateFSStars(void)' + diff --git a/src/levelinfo.cpp b/src/levelinfo.cpp index 728f802..d0ddd9a 100644 --- a/src/levelinfo.cpp +++ b/src/levelinfo.cpp @@ -71,3 +71,58 @@ dLevelInfo_c::entry_s *dLevelInfo_c::searchByDisplayNum(int world, int level) { return 0; } + +void UpdateFSStars() { + dLevelInfo_c *li = &dLevelInfo_c::s_info; + SaveBlock *save = GetSaveFile()->GetBlock(-1); + + bool coinsNormal = true, exitsNormal = true; + bool coinsW9 = true, exitsW9 = true; + + for (int i = 0; i < li->sectionCount(); i++) { + dLevelInfo_c::section_s *sect = li->getSectionByIndex(i); + + for (int j = 0; j < sect->levelCount; j++) { + dLevelInfo_c::entry_s *entry = §->levels[j]; + + // Levels only + if (!(entry->flags & 2)) + continue; + + u32 conds = save->GetLevelCondition(entry->worldSlot, entry->levelSlot); + + if (entry->displayWorld == 9) { + if ((conds & COND_COIN_ALL) != COND_COIN_ALL) + coinsW9 = false; + if (entry->flags & 0x10) + if (!(conds & COND_NORMAL)) + exitsW9 = false; + if (entry->flags & 0x20) + if (!(conds & COND_SECRET)) + exitsW9 = false; + } else { + if ((conds & COND_COIN_ALL) != COND_COIN_ALL) + coinsNormal = false; + if (entry->flags & 0x10) + if (!(conds & COND_NORMAL)) + exitsNormal = false; + if (entry->flags & 0x20) + if (!(conds & COND_SECRET)) + exitsNormal = false; + } + } + } + + bool beatGame = (save->GetLevelCondition(7, 23) & COND_NORMAL) != 0; + + save->bitfield &= ~0x3E; + save->bitfield |= + (beatGame ? 2 : 0) | + (exitsNormal ? 4 : 0) | + (coinsNormal ? 8 : 0) | + (exitsW9 ? 0x10 : 0) | + (coinsW9 ? 0x20 : 0); + + OSReport("FS Stars updated: Status: Game beaten: %d, Normal exits: %d, Normal coins: %d, W9 exits: %d, W9 coins: %d\n", beatGame, exitsNormal, coinsNormal, exitsW9, coinsW9); +} + -- cgit v1.2.3