#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; } 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 *pictureNames[7] = { "Header_Centre", "Header_Right", "NormalExitFlag", "SecretExitFlag", "StarCoinOn0", "StarCoinOn1", "StarCoinOn2" }; layout.getPictures(pictureNames, &Header_Centre, 7); static const char *textBoxNames[7] = { "LevelName", "LevelNameS", "LevelNumber", "LevelNumberS", "WorldName", "WorldNameS", "StarCoinCounter" }; layout.getTextBoxes(textBoxNames, &LevelName, 7); layoutLoaded = true; willShowHeader = false; if (!dScKoopatlas_c::instance->pathManager.isMoving) enteredNode(); } 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(); playShowHeaderAnim(); } layout.execAnimations(); layout.update(); return true; } int dWMHud_c::onDraw() { if (!layoutLoaded) return true; layout.scheduleForDrawing(); return true; } void dWMHud_c::playShowHeaderAnim() { if (!this || !this->layoutLoaded) return; layout.enableNonLoopAnim(SHOW_HEADER); } void dWMHud_c::playHideHeaderAnim() { if (!this || !this->layoutLoaded) return; if (!layout.isAnimOn(SHOW_HEADER)) { layout.enableNonLoopAnim(SHOW_HEADER, true); } layout.grpHandlers[SHOW_HEADER].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::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 playHideHeaderAnim(); } } }