#include "koopatlas/starcoin.h" #include int getStarCoinCountCoins() { SaveBlock *save = GetSaveFile()->GetBlock(-1); int coinsSpent = save->credits_hiscore; int coinsEarned = 0; for (int w = 0; w < 10; w++) { for (int l = 0; l < 10; l++) { u32 conds = save->GetLevelCondition(w, l); if (conds & COND_COIN1) { coinsEarned++; } if (conds & COND_COIN2) { coinsEarned++; } if (conds & COND_COIN3) { coinsEarned++; } } } int coinsLeft = coinsEarned - coinsSpent; return coinsLeft; } /*****************************************************************************/ // Starcoin Layout // dWMStarCoin *dWMStarCoin::instance = 0; dWMStarCoin *dWMStarCoin::build() { void *buffer = AllocFromGameHeap1(sizeof(dWMStarCoin)); dWMStarCoin *c = new(buffer) dWMStarCoin; instance = c; return c; } dWMStarCoin::dWMStarCoin() { layoutLoaded = false; isHidden = true; } int dWMStarCoin::onCreate() { if (!layoutLoaded) { bool gotFile = layout.loadArc("coin.arc", false); if (!gotFile) return false; isHidden = false; static const char *brlanNames[2] = {"coin_inWindow.brlan", "coin_outWindow.brlan"}; static const char *groupNames[2] = {"A00_Window", "A00_Window"}; bool output = layout.build("coin.brlyt"); nw4r::lyt::Pane *red = layout.findPictureByName("red"); red->alpha = 0; if (!IsWideScreen()) { layout.clippingEnabled = true; layout.clipX = 0; layout.clipY = 52; layout.clipWidth = 640; layout.clipHeight = 352; layout.layout.rootPane->scale.x = 0.7711f; layout.layout.rootPane->scale.y = 0.7711f; } layout.loadAnimations(brlanNames, 2); layout.loadGroups(groupNames, (int[2]){0, 1}, 2); layout.disableAllAnimations(); layout.drawOrder = 0x01; layoutLoaded = true; } return true; } int dWMStarCoin::onDelete() { return layout.free(); } int dWMStarCoin::onExecute() { layout.execAnimations(); layout.update(); if (!isHidden) { int nowPressed = Remocon_GetPressed(GetActiveRemocon()); if (!layout.isAnyAnimOn()) { if (nowPressed & WPAD_B) { MapSoundPlayer(SoundRelatedClass, SE_SYS_DIALOGUE_OUT_AUTO, 1); isHidden = true; layout.enableNonLoopAnim(1); } } } return true; } int dWMStarCoin::onDraw() { if (isHidden) { if (layout.isAnimOn(1)) { layout.scheduleForDrawing(); } } if (!isHidden) { layout.scheduleForDrawing(); } return true; } void dWMStarCoin::specialDraw1() { if (!isHidden) { Vec pos = {420.0f, 194.0f, -1000.0f}; S16Vec rot = {0,rotation,0}; Vec scale = {2.0f, 2.0f, 2.0f}; matrix.translation(pos.x, pos.y, pos.z); matrix.applyRotationYXZ(&rot.x, &rot.y, &rot.z); shopkeep.setDrawMatrix(matrix); shopkeep.setScale(&scale); shopkeep.calcWorld(false); shopkeep.scheduleForDrawing(); rotation += 0x100; } return; } void dWMStarCoin::LoadCoinsForWorld(int world) { if (!isHidden) { return; } int levelArray[14][2][8] = { { {1,2,3,4,15}, {5,6,7,8,25,38} }, { {1,2,3,4,15}, {5,6,7,8,9,10,25,38} }, { {1,2,3,4,15}, {5,6,7,25,38} }, { {1,2,3,4,15}, {5,6,7,8,25,38} }, { {1,2,3,4,5,15}, {6,7,8,9,10,25,38} }, { {1,2,3,4,15}, {5,6,7,8,9,25,38} }, { {1,2,3,4}, {5,15,6,7,8,9,25,38} }, { {1,2,3,15,4,25,5}, {6,7,16,8,9,10,26} }, { {1,2,3,4,5}, {6,7,8,9,10} }, { {1,2,3,4,5}, {} }, { {6,7,8,9,10}, {} }, { {11,12,13,14,15}, {} }, { {16,17,18}, {} }, { {19,22,23,24,25}, {} } }; // Handle showing it MapSoundPlayer(SoundRelatedClass, SE_SYS_DIALOGUE_IN, 1); isHidden = false; layout.enableNonLoopAnim(0); // Model creation allocator.link(-1, GameHeaps[0], 0, 0x20); res.data = getResource("star_coin", "g3d/star_coin.brres"); nw4r::g3d::ResMdl mdl = res.GetResMdl("star_coinA"); shopkeep.setup(mdl, &allocator, 0x224, 1, 0); SetupTextures_MapObj(&shopkeep, 1); allocator.unlink(); // Display Total Star Coin Count int myCoins = getStarCoinCountCoins(); char myCoinsStr [4]; sprintf(myCoinsStr, "%03d", myCoins); setText(myCoinsStr, "T_overall_01"); // Display World Name setWorldName(world); // Display Per level coins int totalCoins = 0; int currentCoins = 0; int i = 0; int j = 1; SaveBlock *save = GetSaveFile()->GetBlock(-1); for (int l = 0; l < 2; l++) { for (int i = 0; i < 8; i++) { int levelNum = levelArray[world][l][i]; char levelPane[11]; sprintf(levelPane, "T_level_%02d", i+j); if (levelArray[world][l][i]) { levelNum--; dLevelInfo_c *li = &dScKoopatlas_c::instance->levelInfo; dLevelInfo_c::entry_s *entry = li->search(world, levelNum); setText(li->getNameForLevel(entry), levelPane); totalCoins += 3; } else { setText(" ", levelPane); } bool collect; u32 conds = save->GetLevelCondition(world, i+j); collect = conds & COND_COIN1; setCoin(collect, 1, i+j); if (collect) { currentCoins++; } collect = conds & COND_COIN2; setCoin(collect, 2, i+j); if (collect) { currentCoins++; } collect = conds & COND_COIN3; setCoin(collect, 3, i+j); if (collect) { currentCoins++; } } j += 8; i = 0; } // Display per-world Count char tcStr [3]; sprintf(tcStr, "%02d", totalCoins); setText(tcStr, "T_total_01"); char ccStr [3]; sprintf(ccStr, "%02d", currentCoins); setText(ccStr, "T_collected_01"); } void dWMStarCoin::setCoin(bool on, int coin, int slot) { char coinOn[16]; char coinOff[16]; if (coin == 1) { sprintf(coinOn, "P_first_on_%02d", slot); sprintf(coinOff, "P_first_off_%02d", slot); } else if (coin == 2) { sprintf(coinOn, "P_second_on_%02d", slot); sprintf(coinOff, "P_second_off_%02d", slot); } else if (coin == 3) { sprintf(coinOn, "P_third_on_%02d", slot); sprintf(coinOff, "P_third_off_%02d", slot); } else { return; } nw4r::lyt::Pane *picOn = layout.findPictureByName(coinOn); nw4r::lyt::Pane *picOff = layout.findPictureByName(coinOff); if (on) { picOn->alpha = 0xFF; picOff->alpha = 0; } else { picOn->alpha = 0; picOff->alpha = 0xFF; } } void dWMStarCoin::setText(const char *str, const char *name) { int length = strlen(str); wchar_t newString[128]; int i; for (i = 0; i < length && i < 128; i++) { newString[i] = str[i]; } newString[i] = 0; int wlength = wcslen(newString); nw4r::lyt::TextBox *box = layout.findTextBoxByName(name); nw4r::ut::TextWriter tw; tw.font = box->font; tw.SetFontSize(box->fontSizeX, box->fontSizeY); tw.somethingRelatedToLineHeight = box->lineSpace; tw.charSpace = box->charSpace; if (box->tagProc != 0) tw.tagProcessorMaybe = box->tagProc; float width = tw.CalcStringWidth(newString, wlength); SpammyReport("Text width: %f\n", width); OSReport("Setting text: %s", newString); box->SetString(newString); } void dWMStarCoin::setWorldName(int world) { switch (world+1) { case 1: setText("Yoshi's Island", "T_lefttitle_01"); setText("Yoshi's Island", "T_righttitle_01"); break; case 2: setText("Soggy Sewers", "T_lefttitle_01"); setText("Rubble Ruins", "T_righttitle_01"); break; case 3: setText("Mushroom Peaks", "T_lefttitle_01"); setText("Mushroom Peaks", "T_righttitle_01"); break; case 4: setText("Sakura Village", "T_lefttitle_01"); setText("Sakura Village", "T_righttitle_01"); break; case 5: setText("FreezeFlame Valley", "T_lefttitle_01"); setText("FreezeFlame Volcano", "T_righttitle_01"); break; case 6: setText("Pumpkin Boneyard", "T_lefttitle_01"); setText("Pumpkin Boneyard", "T_righttitle_01"); break; case 7: setText("Sky Mountain", "T_lefttitle_01"); setText("Starry Skies", "T_righttitle_01"); break; case 8: setText("Koopa Planet", "T_lefttitle_01"); setText("Koopa Core", "T_righttitle_01"); break; case 9: setText("Bonus Land", "T_lefttitle_01"); setText("Bonus Land", "T_righttitle_01"); break; case 10: setText("Goldwood Forest", "T_lefttitle_01"); setText(" ", "T_righttitle_01"); break; case 11: setText("Mini-Mega Island", "T_lefttitle_01"); setText(" ", "T_righttitle_01"); break; case 12: setText("Crystal Caves", "T_lefttitle_01"); setText(" ", "T_righttitle_01"); break; case 13: setText("Bombard Cliffs", "T_lefttitle_01"); setText(" ", "T_righttitle_01"); break; case 14: setText("Sky City", "T_lefttitle_01"); setText(" ", "T_righttitle_01"); break; default: setText("Unknown World", "T_lefttitle_01"); setText("Unknown World", "T_righttitle_01"); break; } }