aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/gob/pregob/onceupon/abracadabra.cpp31
-rw-r--r--engines/gob/pregob/onceupon/abracadabra.h6
-rw-r--r--engines/gob/pregob/onceupon/babayaga.cpp31
-rw-r--r--engines/gob/pregob/onceupon/babayaga.h6
-rw-r--r--engines/gob/pregob/onceupon/onceupon.cpp403
-rw-r--r--engines/gob/pregob/onceupon/onceupon.h71
6 files changed, 541 insertions, 7 deletions
diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp
index 9db018c4aa..696e4d9594 100644
--- a/engines/gob/pregob/onceupon/abracadabra.cpp
+++ b/engines/gob/pregob/onceupon/abracadabra.cpp
@@ -48,7 +48,13 @@ namespace Gob {
namespace OnceUpon {
+const OnceUpon::MenuButton Abracadabra::kAnimalsButtons = {
+ true, 131, 127, 183, 164, 193, 0, 243, 35, 132, 128, 0
+};
+
+
Abracadabra::Abracadabra(GobEngine *vm) : OnceUpon(vm) {
+ setAnimalsButton(&kAnimalsButtons);
}
Abracadabra::~Abracadabra() {
@@ -64,6 +70,31 @@ void Abracadabra::run() {
// Show the intro
showIntro();
+ if (_vm->shouldQuit())
+ return;
+
+ mainLoop();
+
+ if (!_vm->shouldQuit())
+ warning("Abracadabra::run(): TODO: Show \"Bye Bye\"");
+}
+
+void Abracadabra::mainLoop() {
+ clearScreen();
+
+ MenuType mainMenu = kMenuTypeMainStart;
+
+ while (!_vm->shouldQuit()) {
+ MenuAction action = doMenu(mainMenu);
+ if (action == kMenuActionPlay)
+ warning("Abracadabra::mainLoop(): TODO: Play");
+ else if (action == kMenuActionRestart)
+ warning("Abracadabra::mainLoop(): TODO: Restart");
+ else if (action == kMenuActionAnimals)
+ warning("Abracadabra::mainLoop(): TODO: Animals");
+ else if (action == kMenuActionQuit)
+ break;
+ }
}
} // End of namespace OnceUpon
diff --git a/engines/gob/pregob/onceupon/abracadabra.h b/engines/gob/pregob/onceupon/abracadabra.h
index 855d2bf131..64deaf4389 100644
--- a/engines/gob/pregob/onceupon/abracadabra.h
+++ b/engines/gob/pregob/onceupon/abracadabra.h
@@ -35,6 +35,12 @@ public:
~Abracadabra();
void run();
+
+private:
+ static const MenuButton kAnimalsButtons;
+
+
+ void mainLoop();
};
} // End of namespace OnceUpon
diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp
index 8b80a38084..b752bb0862 100644
--- a/engines/gob/pregob/onceupon/babayaga.cpp
+++ b/engines/gob/pregob/onceupon/babayaga.cpp
@@ -48,7 +48,13 @@ namespace Gob {
namespace OnceUpon {
+const OnceUpon::MenuButton BabaYaga::kAnimalsButtons = {
+ true, 131, 127, 183, 164, 193, 0, 245, 37, 131, 127, 0
+};
+
+
BabaYaga::BabaYaga(GobEngine *vm) : OnceUpon(vm) {
+ setAnimalsButton(&kAnimalsButtons);
}
BabaYaga::~BabaYaga() {
@@ -64,6 +70,31 @@ void BabaYaga::run() {
// Show the intro
showIntro();
+ if (_vm->shouldQuit())
+ return;
+
+ mainLoop();
+
+ if (!_vm->shouldQuit())
+ warning("BabaYaga::run(): TODO: Show \"Bye Bye\"");
+}
+
+void BabaYaga::mainLoop() {
+ clearScreen();
+
+ MenuType mainMenu = kMenuTypeMainStart;
+
+ while (!_vm->shouldQuit()) {
+ MenuAction action = doMenu(mainMenu);
+ if (action == kMenuActionPlay)
+ warning("BabaYaga::mainLoop(): TODO: Play");
+ else if (action == kMenuActionRestart)
+ warning("BabaYaga::mainLoop(): TODO: Restart");
+ else if (action == kMenuActionAnimals)
+ warning("BabaYaga::mainLoop(): TODO: Animals");
+ else if (action == kMenuActionQuit)
+ break;
+ }
}
} // End of namespace OnceUpon
diff --git a/engines/gob/pregob/onceupon/babayaga.h b/engines/gob/pregob/onceupon/babayaga.h
index b3339b0ca8..98d452418f 100644
--- a/engines/gob/pregob/onceupon/babayaga.h
+++ b/engines/gob/pregob/onceupon/babayaga.h
@@ -35,6 +35,12 @@ public:
~BabaYaga();
void run();
+
+private:
+ static const MenuButton kAnimalsButtons;
+
+
+ void mainLoop();
};
} // End of namespace OnceUpon
diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp
index f2708b380b..67004d2912 100644
--- a/engines/gob/pregob/onceupon/onceupon.cpp
+++ b/engines/gob/pregob/onceupon/onceupon.cpp
@@ -227,8 +227,28 @@ namespace Gob {
namespace OnceUpon {
+const OnceUpon::MenuButton OnceUpon::kMainMenuDifficultyButton[3] = {
+ {false, 29, 18, 77, 57, 0, 0, 0, 0, 0, 0, 0},
+ {false, 133, 18, 181, 57, 0, 0, 0, 0, 0, 0, 1},
+ {false, 241, 18, 289, 57, 0, 0, 0, 0, 0, 0, 2},
+};
+
+const OnceUpon::MenuButton OnceUpon::kSectionButtons[4] = {
+ {false, 27, 121, 91, 179, 0, 0, 0, 0, 0, 0, 0},
+ { true, 95, 121, 159, 179, 4, 1, 56, 49, 100, 126, 2},
+ { true, 163, 121, 227, 179, 64, 1, 120, 49, 168, 126, 6},
+ { true, 231, 121, 295, 179, 128, 1, 184, 49, 236, 126, 10}
+};
+
+const OnceUpon::MenuButton OnceUpon::kIngameButtons[3] = {
+ {true, 108, 83, 139, 116, 0, 0, 31, 34, 108, 83, 0},
+ {true, 144, 83, 175, 116, 36, 0, 67, 34, 144, 83, 1},
+ {true, 180, 83, 211, 116, 72, 0, 103, 34, 180, 83, 2}
+};
+
+
OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm), _jeudak(0), _lettre(0), _plettre(0), _glettre(0),
- _openedArchives(false) {
+ _openedArchives(false), _animalsButton(0) {
}
@@ -267,6 +287,9 @@ void OnceUpon::init() {
"Thanks", _vm->getLangDesc(_vm->_global->_language));
initScreen();
+
+ _difficulty = kDifficultyMAX;
+ _section = 0;
}
void OnceUpon::deinit() {
@@ -289,6 +312,10 @@ void OnceUpon::deinit() {
_openedArchives = false;
}
+void OnceUpon::setAnimalsButton(const MenuButton *animalsButton) {
+ _animalsButton = animalsButton;
+}
+
void OnceUpon::setCopyProtectionPalette() {
setPalette(kCopyProtectionPalette, kPaletteSize);
}
@@ -300,6 +327,14 @@ void OnceUpon::setGamePalette(uint palette) {
setPalette(kGamePalettes[palette], kPaletteSize);
}
+void OnceUpon::setGameCursor() {
+ Surface cursor(320, 16, 1);
+
+ _vm->_video->drawPackedSprite("icon.cmp", cursor);
+
+ setCursor(cursor, 105, 0, 120, 15, 0, 0);
+}
+
enum CopyProtectionState {
kCPStateSetup, // Set up the screen
kCPStateWaitUser, // Waiting for the user to pick a shape
@@ -489,12 +524,12 @@ void OnceUpon::setAnimState(ANIObject &ani, uint16 state, bool once, bool pause)
ani.setPosition();
}
-void OnceUpon::showWait() {
+void OnceUpon::showWait(uint palette) {
// Show the loading floppy
fadeOut();
clearScreen();
- setGamePalette(10);
+ setGamePalette(palette);
Surface wait(320, 43, 1);
@@ -510,7 +545,7 @@ void OnceUpon::showIntro() {
// Show all intro parts
// "Loading"
- showWait();
+ showWait(10);
if (_vm->shouldQuit())
return;
@@ -530,7 +565,7 @@ void OnceUpon::showIntro() {
return;
// "Loading"
- showWait();
+ showWait(17);
}
void OnceUpon::showQuote() {
@@ -667,6 +702,364 @@ void OnceUpon::showChapter(int chapter) {
fadeOut();
}
+OnceUpon::MenuAction OnceUpon::doMenu(MenuType type) {
+ bool cursorVisible = isCursorVisible();
+
+ // Set the cursor
+ addCursor();
+ setGameCursor();
+
+ // Backup the screen
+ Surface screenBackup(320, 200, 1);
+ screenBackup.blit(*_vm->_draw->_backSurface);
+
+ // Handle the specific menu
+ MenuAction action;
+ if (type == kMenuTypeMainStart)
+ action = doMenuMainStart();
+ else if (type == kMenuTypeMainIngame)
+ action = doMenuMainIngame();
+ else if (type == kMenuTypeIngame)
+ action = doMenuIngame();
+ else
+ error("OnceUpon::doMenu(): No such menu %d", type);
+
+ if (_vm->shouldQuit())
+ return action;
+
+ // The ingame menu cleans itself up in a special way
+ if (type == kMenuTypeIngame)
+ clearMenuIngame(screenBackup);
+
+ // The main menus fade out
+ if ((type == kMenuTypeMainStart) || (type == kMenuTypeMainIngame))
+ fadeOut();
+
+ // Restore the screen
+ _vm->_draw->_backSurface->blit(screenBackup);
+ _vm->_draw->forceBlit();
+
+ // Restore the cursor
+ if (!cursorVisible)
+ hideCursor();
+ removeCursor();
+
+ return action;
+}
+
+OnceUpon::MenuAction OnceUpon::doMenuMainStart() {
+ fadeOut();
+ drawMenuMainStart();
+ showCursor();
+ fadeIn();
+
+ MenuAction action = kMenuActionNone;
+ while (!_vm->shouldQuit() && (action == kMenuActionNone)) {
+ endFrame(true);
+
+ // Check user input
+
+ int16 mouseX, mouseY;
+ MouseButtons mouseButtons;
+
+ int16 key = checkInput(mouseX, mouseY, mouseButtons);
+ if (key == kKeyEscape)
+ // ESC -> Quit
+ return kMenuActionQuit;
+
+ if (mouseButtons != kMouseButtonsLeft)
+ continue;
+
+ // If we clicked on a difficulty button, show the selected difficulty and start the game
+ Difficulty difficulty = checkDifficultyButton(mouseX, mouseY);
+ if (difficulty < kDifficultyMAX) {
+ _difficulty = difficulty;
+ action = kMenuActionPlay;
+
+ drawMenuMainStart();
+ _vm->_util->longDelay(1000);
+ }
+
+ if (checkAnimalsButton(mouseX, mouseY))
+ action = kMenuActionAnimals;
+
+ }
+
+ return action;
+}
+
+OnceUpon::MenuAction OnceUpon::doMenuMainIngame() {
+ fadeOut();
+ drawMenuMainIngame();
+ showCursor();
+ fadeIn();
+
+ MenuAction action = kMenuActionNone;
+ while (!_vm->shouldQuit() && (action == kMenuActionNone)) {
+ endFrame(true);
+
+ // Check user input
+
+ int16 mouseX, mouseY;
+ MouseButtons mouseButtons;
+
+ int16 key = checkInput(mouseX, mouseY, mouseButtons);
+ if (key == kKeyEscape)
+ // ESC -> Quit
+ return kMenuActionQuit;
+
+ if (mouseButtons != kMouseButtonsLeft)
+ continue;
+
+ // If we clicked on a difficulty button, change the current difficulty level
+ Difficulty difficulty = checkDifficultyButton(mouseX, mouseY);
+ if ((difficulty < kDifficultyMAX) && (_difficulty != difficulty)) {
+ _difficulty = difficulty;
+
+ drawMenuMainIngame();
+ }
+
+ // If we clicked on a section button, restart the game from this section
+ int8 section = checkSectionButton(mouseX, mouseY);
+ if (section >= 0) {
+ _section = section;
+ action = kMenuActionRestart;
+ }
+
+ }
+
+ return action;
+}
+
+OnceUpon::MenuAction OnceUpon::doMenuIngame() {
+ drawMenuIngame();
+ showCursor();
+
+ MenuAction action = kMenuActionNone;
+ while (!_vm->shouldQuit() && (action == kMenuActionNone)) {
+ endFrame(true);
+
+ // Check user input
+
+ int16 mouseX, mouseY;
+ MouseButtons mouseButtons;
+
+ int16 key = checkInput(mouseX, mouseY, mouseButtons);
+ if ((key == kKeyEscape) || (mouseButtons == kMouseButtonsRight))
+ // ESC or right mouse button -> Dismiss the menu
+ action = kMenuActionPlay;
+
+ if (mouseButtons != kMouseButtonsLeft)
+ continue;
+
+ // Check if we've pressed one of the buttons
+ int8 button = checkIngameButton(mouseX, mouseY);
+ if (button == 0)
+ action = kMenuActionQuit;
+ else if (button == 1)
+ action = kMenuActionMainMenu;
+ else if (button == 2)
+ action = kMenuActionPlay;
+
+ }
+
+ return action;
+}
+
+void OnceUpon::drawMenuMainStart() {
+ // Draw the background
+ _vm->_video->drawPackedSprite("menu2.cmp", *_vm->_draw->_backSurface);
+
+ // Draw the "Listen to animal names" button
+ if (_animalsButton) {
+ Surface elements(320, 38, 1);
+ _vm->_video->drawPackedSprite("elemenu.cmp", elements);
+ _vm->_draw->_backSurface->fillRect(_animalsButton->left , _animalsButton->top,
+ _animalsButton->right, _animalsButton->bottom, 0);
+ _vm->_draw->_backSurface->blit(elements,
+ _animalsButton->srcLeft , _animalsButton->srcTop,
+ _animalsButton->srcRight, _animalsButton->srcBottom,
+ _animalsButton->dstX , _animalsButton->dstY);
+ }
+
+ // Highlight the current difficulty
+ drawMenuDifficulty();
+
+ _vm->_draw->forceBlit();
+}
+
+void OnceUpon::drawMenuMainIngame() {
+ // Draw the background
+ _vm->_video->drawPackedSprite("menu.cmp", *_vm->_draw->_backSurface);
+
+ // Highlight the current difficulty
+ drawMenuDifficulty();
+
+ // Draw the section buttons
+ Surface elements(320, 200, 1);
+ _vm->_video->drawPackedSprite("elemenu.cmp", elements);
+
+ for (uint i = 0; i < ARRAYSIZE(kSectionButtons); i++) {
+ const MenuButton &button = kSectionButtons[i];
+
+ if (!button.needDraw)
+ continue;
+
+ if (_section >= (uint)button.id)
+ _vm->_draw->_backSurface->blit(elements, button.srcLeft, button.srcTop, button.srcRight, button.srcBottom,
+ button.dstX, button.dstY);
+ }
+
+ _vm->_draw->forceBlit();
+}
+
+void OnceUpon::drawMenuIngame() {
+ Surface menu(320, 34, 1);
+ _vm->_video->drawPackedSprite("icon.cmp", menu);
+
+ // Draw the menu in a special way
+ for (uint i = 0; i < ARRAYSIZE(kIngameButtons); i++) {
+ const MenuButton &button = kIngameButtons[i];
+
+ drawLineByLine(menu, button.srcLeft, button.srcTop, button.srcRight, button.srcBottom,
+ button.dstX, button.dstY);
+ }
+
+ _vm->_draw->forceBlit();
+ _vm->_video->retrace();
+}
+
+void OnceUpon::drawMenuDifficulty() {
+ if (_difficulty == kDifficultyMAX)
+ return;
+
+ TXTFile *difficulties = loadTXT(getLocFile("diffic.tx"), TXTFile::kFormatStringPositionColor);
+
+ // Draw the difficulty name
+ difficulties->draw((uint) _difficulty, *_vm->_draw->_backSurface, &_plettre, 1);
+
+ // Draw a border around the current difficulty
+ _vm->_draw->_backSurface->drawRect(kMainMenuDifficultyButton[_difficulty].left,
+ kMainMenuDifficultyButton[_difficulty].top,
+ kMainMenuDifficultyButton[_difficulty].right,
+ kMainMenuDifficultyButton[_difficulty].bottom,
+ difficulties->getLines()[_difficulty].color);
+
+ delete difficulties;
+}
+
+void OnceUpon::clearMenuIngame(const Surface &background) {
+ // Find the area encompassing the whole ingame menu
+
+ int16 left = 0x7FFF;
+ int16 top = 0x7FFF;
+ int16 right = 0x0000;
+ int16 bottom = 0x0000;
+
+ for (uint i = 0; i < ARRAYSIZE(kIngameButtons); i++) {
+ const MenuButton &button = kIngameButtons[i];
+
+ if (!button.needDraw)
+ continue;
+
+ left = MIN<int16>(left , button.dstX);
+ top = MIN<int16>(top , button.dstY);
+ right = MAX<int16>(right , button.dstX + (button.srcRight - button.srcLeft + 1) - 1);
+ bottom = MAX<int16>(bottom, button.dstY + (button.srcBottom - button.srcTop + 1) - 1);
+ }
+
+ if ((left > right) || (top > bottom))
+ return;
+
+ // Clear it line by line
+ drawLineByLine(background, left, top, right, bottom, left, top);
+}
+
+OnceUpon::Difficulty OnceUpon::checkDifficultyButton(int16 x, int16 y) const {
+ for (uint i = 0; i < ARRAYSIZE(kMainMenuDifficultyButton); i++) {
+ const MenuButton &button = kMainMenuDifficultyButton[i];
+
+ if ((x >= button.left) && (x <= button.right) && (y >= button.top) && (y <= button.bottom))
+ return (Difficulty) button.id;
+ }
+
+ return kDifficultyMAX;
+}
+
+bool OnceUpon::checkAnimalsButton(int16 x, int16 y) const {
+ if (!_animalsButton)
+ return false;
+
+ return (x >= _animalsButton->left) && (x <= _animalsButton->right) &&
+ (y >= _animalsButton->top) && (y <= _animalsButton->bottom);
+}
+
+int8 OnceUpon::checkSectionButton(int16 x, int16 y) const {
+ for (uint i = 0; i < ARRAYSIZE(kSectionButtons); i++) {
+ const MenuButton &button = kSectionButtons[i];
+
+ if ((uint)button.id > _section)
+ continue;
+
+ if ((x >= button.left) && (x <= button.right) && (y >= button.top) && (y <= button.bottom))
+ return (int8)button.id;
+ }
+
+ return -1;
+}
+
+int8 OnceUpon::checkIngameButton(int16 x, int16 y) const {
+ for (uint i = 0; i < ARRAYSIZE(kIngameButtons); i++) {
+ const MenuButton &button = kIngameButtons[i];
+
+ if ((x >= button.left) && (x <= button.right) && (y >= button.top) && (y <= button.bottom))
+ return (int8)button.id;
+ }
+
+ return -1;
+}
+
+void OnceUpon::drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom,
+ int16 x, int16 y) const {
+
+ // A special way of drawing something:
+ // Draw every other line "downwards", wait a bit after each line
+ // Then, draw the remaining lines "upwards" and again wait a bit after each line.
+
+ if (_vm->shouldQuit())
+ return;
+
+ const int16 width = right - left + 1;
+ const int16 height = bottom - top + 1;
+
+ if ((width <= 0) || (height <= 0))
+ return;
+
+ for (int16 i = 0; i < height; i += 2) {
+ if (_vm->shouldQuit())
+ return;
+
+ _vm->_draw->_backSurface->blit(src, left, top + i, right, top + i, x, y + i);
+
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, y + i, x + width - 1, y + 1);
+ _vm->_draw->blitInvalidated();
+
+ _vm->_util->longDelay(1);
+ }
+
+ for (int16 i = (height & 1) ? height : (height - 1); i >= 0; i -= 2) {
+ if (_vm->shouldQuit())
+ return;
+
+ _vm->_draw->_backSurface->blit(src, left, top + i, right, top + i, x, y + i);
+
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, y + i, x + width - 1, y + 1);
+ _vm->_draw->blitInvalidated();
+
+ _vm->_util->longDelay(1);
+ }
+}
+
} // End of namespace OnceUpon
} // End of namespace Gob
diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h
index 968c70ef48..640e61383d 100644
--- a/engines/gob/pregob/onceupon/onceupon.h
+++ b/engines/gob/pregob/onceupon/onceupon.h
@@ -42,18 +42,59 @@ public:
~OnceUpon();
protected:
+ enum MenuType {
+ kMenuTypeMainStart = 0, ///< The big main menu at game start.
+ kMenuTypeMainIngame, ///< The big main menu during the game.
+ kMenuTypeIngame ///< The small popup menu during the game.
+ };
+
+ enum MenuAction {
+ kMenuActionNone = 0, ///< No action.
+ kMenuActionAnimals , ///< Do the animal names.
+ kMenuActionPlay , ///< Play the game.
+ kMenuActionRestart , ///< Restart the section.
+ kMenuActionMainMenu, ///< Go to the main menu.
+ kMenuActionQuit ///< Quit the game.
+ };
+
+ enum Difficulty {
+ kDifficultyBeginner = 0,
+ kDifficultyIntermediate = 1,
+ kDifficultyAdvanced = 2,
+ kDifficultyMAX
+ };
+
+ struct MenuButton {
+ bool needDraw;
+ int16 left, top, right, bottom;
+ int16 srcLeft, srcTop, srcRight, srcBottom;
+ int16 dstX, dstY;
+ int id;
+ };
+
+ static const uint kSectionCount = 15;
+
+
void init();
void deinit();
+ void setAnimalsButton(const MenuButton *animalsButton);
+
void setGamePalette(uint palette);
+ void setGameCursor();
bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]);
- void showWait(); ///< Show the wait / loading screen.
- void showIntro(); ///< Show the whole intro.
+ void showWait(uint palette = 0xFFFF); ///< Show the wait / loading screen.
+ void showIntro(); ///< Show the whole intro.
void showChapter(int chapter); ///< Show a chapter intro text.
+ MenuAction doMenu(MenuType type);
+
+ void drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom,
+ int16 x, int16 y) const;
+
// Fonts
Font *_jeudak;
@@ -61,7 +102,14 @@ protected:
Font *_plettre;
Font *_glettre;
+ Difficulty _difficulty;
+ uint8 _section;
+
private:
+ static const MenuButton kMainMenuDifficultyButton[3];
+ static const MenuButton kSectionButtons[4];
+ static const MenuButton kIngameButtons[3];
+
void setCopyProtectionPalette();
void setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const;
@@ -82,8 +130,27 @@ private:
void playTitleMusicAtariST();
void stopTitleMusic();
+ // Menu helpers
+ MenuAction doMenuMainStart();
+ MenuAction doMenuMainIngame();
+ MenuAction doMenuIngame();
+
+ void drawMenuMainStart();
+ void drawMenuMainIngame();
+ void drawMenuIngame();
+ void drawMenuDifficulty();
+
+ void clearMenuIngame(const Surface &background);
+
+ Difficulty checkDifficultyButton(int16 x, int16 y) const;
+ bool checkAnimalsButton (int16 x, int16 y) const;
+ int8 checkSectionButton (int16 x, int16 y) const;
+ int8 checkIngameButton (int16 x, int16 y) const;
+
bool _openedArchives;
+
+ const MenuButton *_animalsButton;
};
} // End of namespace OnceUpon