#include "koopatlas/hud.h" dWMHud_c *dWMHud_c::instance = 0; dWMHud_c *dWMHud_c::build() { void *buffer = AllocFromGameHeap1(sizeof(dWMHud_c)); dWMHud_c *c = new(buffer) dWMHud_c; instance = c; return c; } dWMHud_c::dWMHud_c() { layoutLoaded = false; displayedControllerType = -1; } enum WMHudAnimation { SHOW_LIVES = 0, SHOW_HEADER, SHOW_FOOTER }; int dWMHud_c::onCreate() { if (!layoutLoaded) { bool gotFile = layout.loadArc("MapHUD.arc", false); if (!gotFile) return false; bool output = layout.build("maphud.brlyt"); 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; } static const char *brlanNames[2] = {"MapHUD_ShowMain.brlan", "MapHUD_ShowHeader.brlan"}; static const char *groupNames[3] = {"G_Lives", "G_Header", "G_Footer"}; layout.loadAnimations(brlanNames, 2); layout.loadGroups(groupNames, (int[3]){0, 1, 0}, 3); layout.disableAllAnimations(); layout.enableNonLoopAnim(SHOW_LIVES); layout.enableNonLoopAnim(SHOW_FOOTER); layout.resetAnim(SHOW_HEADER); static const char *tbNames[2] = {"MenuButtonInfo", "ItemsButtonInfo"}; layout.setLangStrings(tbNames, (int[2]){12, 15}, 4, 2); static const char *paneNames[] = { "N_IconPos1P_00", "N_IconPos2P_00", "N_IconPos3P_00", "N_IconPos4P_00" }; layout.getPanes(paneNames, &N_IconPosXP_00[0], 4); static const char *pictureNames[] = { "Header_Centre", "Header_Right", "NormalExitFlag", "SecretExitFlag", "StarCoinOn0", "StarCoinOn1", "StarCoinOn2", "P_marioFace_00", "P_luigiFace_00", "P_BkinoFace_00", "P_YkinoFace_00" }; layout.getPictures(pictureNames, &Header_Centre, 11); static const char *textBoxNames[] = { "LevelName", "LevelNameS", "LevelNumber", "LevelNumberS", "WorldName", "WorldNameS", "StarCoinCounter", "T_lifeNumber_00", "T_lifeNumber_01", "T_lifeNumber_02", "T_lifeNumber_03" }; layout.getTextBoxes(textBoxNames, &LevelName, 11); layoutLoaded = true; willShowHeader = false; willShowFooter = false; loadFooterInfo(); if (!dScKoopatlas_c::instance->pathManager.isMoving) enteredNode(); setupLives(); } return true; } int dWMHud_c::onDelete() { if (!layoutLoaded) return true; return layout.free(); } int dWMHud_c::onExecute() { if (!layoutLoaded) return true; if (willShowHeader && (!(layout.isAnimOn(SHOW_HEADER)))) { willShowHeader = false; loadHeaderInfo(); playShowAnim(SHOW_HEADER); } if (willShowFooter && (!(layout.isAnimOn(SHOW_FOOTER)))) { willShowFooter = false; loadFooterInfo(); playShowAnim(SHOW_FOOTER); } updatePressableButtonThingies(); layout.execAnimations(); layout.update(); return true; } int dWMHud_c::onDraw() { if (!layoutLoaded) return true; layout.scheduleForDrawing(); return true; } void dWMHud_c::playShowAnim(int id) { if (!this || !this->layoutLoaded) return; layout.enableNonLoopAnim(id); } void dWMHud_c::playHideAnim(int id) { if (!this || !this->layoutLoaded) return; if (!layout.isAnimOn(id)) { layout.enableNonLoopAnim(id, true); } layout.grpHandlers[id].frameCtrl.flags = 3; // NO_LOOP | REVERSE } void dWMHud_c::loadHeaderInfo() { dLevelInfo_c *levelInfo = &dScKoopatlas_c::instance->levelInfo; dLevelInfo_c::entry_s *infEntry = levelInfo->search( nodeForHeader->levelNumber[0]-1, nodeForHeader->levelNumber[1]-1); if (infEntry == 0) { LevelName->SetString(L"Unknown Level Name!"); LevelNameS->SetString(L"Unknown Level Name!"); return; } // LEVEL NAME wchar_t convertedLevelName[100]; const char *sourceLevelName = levelInfo->getNameForLevel(infEntry); int charCount = 0; while (*sourceLevelName != 0 && charCount < 99) { convertedLevelName[charCount] = *sourceLevelName; sourceLevelName++; charCount++; } convertedLevelName[charCount] = 0; LevelName->SetString(convertedLevelName); LevelNameS->SetString(convertedLevelName); // LEVEL NUMBER wchar_t levelNumber[6]; levelNumber[0] = '0' + nodeForHeader->levelNumber[0]; levelNumber[1] = '-'; if (nodeForHeader->levelNumber[1] >= 10) { levelNumber[2] = '0' + (nodeForHeader->levelNumber[1] / 10); levelNumber[3] = '0' + (nodeForHeader->levelNumber[1] % 10); levelNumber[4] = 0; } else { levelNumber[2] = '0' + nodeForHeader->levelNumber[1]; levelNumber[3] = 0; } LevelNumber->SetString(levelNumber); LevelNumberS->SetString(levelNumber); // INFO int w = nodeForHeader->levelNumber[0] - 1; int l = nodeForHeader->levelNumber[1] - 1; u32 conds = GetSaveFile()->GetBlock(-1)->GetLevelCondition(w, l); NormalExitFlag->SetVisible(conds & COND_NORMAL); SecretExitFlag->SetVisible(conds & COND_SECRET); StarCoinOn[0]->SetVisible(conds & COND_COIN1); StarCoinOn[1]->SetVisible(conds & COND_COIN2); StarCoinOn[2]->SetVisible(conds & COND_COIN3); // SIZE THING nw4r::ut::TextWriter tw; tw.font = LevelName->font; tw.SetFontSize(LevelName->fontSizeX, LevelName->fontSizeY); tw.lineSpace = LevelName->lineSpace; tw.charSpace = LevelName->charSpace; if (LevelName->tagProc != 0) tw.tagProcessor = LevelName->tagProc; float width = tw.CalcStringWidth(convertedLevelName, charCount); float totalWidth = width + LevelName->trans.x - 20.0f; if (totalWidth < 270.0f) totalWidth = 270.0f; Header_Centre->size.x = totalWidth; Header_Right->trans.x = totalWidth; } void dWMHud_c::loadFooterInfo() { SaveBlock *save = GetSaveFile()->GetBlock(-1); wchar_t convertedWorldName[36]; int i; for (i = 0; i < 36; i++) { convertedWorldName[i] = save->newerWorldName[i]; if (convertedWorldName[i] == 0) break; } convertedWorldName[35] = 0; WorldName->SetString(convertedWorldName); WorldNameS->SetString(convertedWorldName); WorldName->colour1 = save->hudTextColour[0]; WorldName->colour2 = save->hudTextColour[1]; } void dWMHud_c::enteredNode(dKPNode_s *node) { if (node == 0) node = dScKoopatlas_c::instance->pathManager.currentNode; if (node->type == dKPNode_s::LEVEL) { willShowHeader = true; nodeForHeader = node; } } void dWMHud_c::leftNode() { if (layout.grpHandlers[SHOW_HEADER].frameCtrl.currentFrame > 0.1f) { // not hidden if ((layout.isAnimOn(SHOW_HEADER) && (layout.grpHandlers[SHOW_HEADER].frameCtrl.flags & 2)) || (!layout.isAnimOn(SHOW_HEADER))) { // currently being shown, OR fully shown already playHideAnim(SHOW_HEADER); } } } void dWMHud_c::hideAndShowFooter() { willShowFooter = true; playHideAnim(SHOW_FOOTER); } void dWMHud_c::setupLives() { static const int LogicalPlayerIDs[] = {0,1,3,2}; P_marioFace_00->SetVisible(false); P_luigiFace_00->SetVisible(false); P_BkinoFace_00->SetVisible(false); P_YkinoFace_00->SetVisible(false); int playerCount = 0; for (int i = 0; i < 4; i++) { // The part in setupLives() int playerID = LogicalPlayerIDs[i]; int slotID = SearchForIndexOfPlayerID(playerID); int lives = Player_Lives[slotID]; int length = 2; WriteNumberToTextBox(&lives, &length, T_lifeNumber[slotID], true); // The part in setupIconThings() if (QueryPlayerAvailability(slotID)) { playerCount++; nw4r::lyt::Pane *facePane = (&P_marioFace_00)[playerID]; facePane->trans = N_IconPosXP_00[i]->trans; facePane->SetVisible(true); } } for (int i = 0; i < 4; i++) N_IconPosXP_00[i]->SetVisible(false); N_IconPosXP_00[playerCount - 1]->SetVisible(true); } void dWMHud_c::updatePressableButtonThingies() { int cntType = RemoconMng->controllers[0]->controllerType; if (cntType != displayedControllerType) { displayedControllerType = cntType; int beef = (cntType == 0) ? 0 : 1; GameMgrP->currentControllerType = beef; WriteBMGToTextBox( layout.findTextBoxByName("ItemsButtonInfo"), GetBMG(), 4, 15, 0); } }