mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-14 16:07:39 +00:00
TWINE: started to implement saving and loading as well as player name entering
This commit is contained in:
parent
64ce952c74
commit
71921f241c
@ -53,6 +53,7 @@ bool TwinEConsole::doChangeScene(int argc, const char **argv) {
|
||||
bool TwinEConsole::doGiveAllItems(int argc, const char **argv) {
|
||||
for (int32 i = 0; i < NUM_INVENTORY_ITEMS; ++i) {
|
||||
_engine->_gameState->gameFlags[i] = 1;
|
||||
_engine->_gameState->inventoryFlags[i] = 1;
|
||||
}
|
||||
int amount = 10;
|
||||
if (argc > 1) {
|
||||
|
@ -71,7 +71,7 @@ void DebugGrid::changeGrid() {
|
||||
if (_engine->_input->toggleActionIfActive(TwinEActionType::NextRoom)) {
|
||||
_engine->_scene->currentSceneIdx++;
|
||||
if (_engine->_scene->currentSceneIdx >= LBA1SceneId::SceneIdMax) {
|
||||
_engine->_scene->currentSceneIdx = 0;
|
||||
_engine->_scene->currentSceneIdx = LBA1SceneId::Citadel_Island_Prison;
|
||||
}
|
||||
_engine->_scene->needChangeScene = _engine->_scene->currentSceneIdx;
|
||||
_engine->_redraw->reqBgRedraw = true;
|
||||
@ -80,7 +80,7 @@ void DebugGrid::changeGrid() {
|
||||
// Press down - less X positions
|
||||
if (_engine->_input->toggleActionIfActive(TwinEActionType::PreviousRoom)) {
|
||||
_engine->_scene->currentSceneIdx--;
|
||||
if (_engine->_scene->currentSceneIdx < 0) {
|
||||
if (_engine->_scene->currentSceneIdx < LBA1SceneId::Citadel_Island_Prison) {
|
||||
_engine->_scene->currentSceneIdx = LBA1SceneId::SceneIdMax - 1;
|
||||
}
|
||||
_engine->_scene->needChangeScene = _engine->_scene->currentSceneIdx;
|
||||
|
@ -169,19 +169,16 @@ void GameState::initEngineVars() {
|
||||
_engine->_actor->previousHeroBehaviour = kNormal;
|
||||
}
|
||||
|
||||
bool GameState::loadGame() {
|
||||
Common::File file;
|
||||
// TODO: the filename must be handled properly
|
||||
if (!file.open(SAVE_DIR "S9999.LBA")) {
|
||||
warning("Could not load the gamestate");
|
||||
bool GameState::loadGame(Common::InSaveFile* file) {
|
||||
if (file == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
file.skip(1); // skip save game id
|
||||
file->skip(1); // skip save game id
|
||||
|
||||
int playerNameIdx = 0;
|
||||
do {
|
||||
const byte c = file.readByte();
|
||||
const byte c = file->readByte();
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
@ -193,94 +190,87 @@ bool GameState::loadGame() {
|
||||
} while (true);
|
||||
playerName[playerNameIdx] = '\0';
|
||||
|
||||
byte numGameFlags = file.readByte();
|
||||
byte numGameFlags = file->readByte();
|
||||
if (numGameFlags != NUM_GAME_FLAGS) {
|
||||
warning("Failed to load gameflags");
|
||||
return false;
|
||||
}
|
||||
file.read(gameFlags, numGameFlags);
|
||||
_engine->_scene->needChangeScene = file.readByte(); // scene index
|
||||
gameChapter = file.readByte();
|
||||
file->read(gameFlags, numGameFlags);
|
||||
_engine->_scene->needChangeScene = file->readByte(); // scene index
|
||||
gameChapter = file->readByte();
|
||||
|
||||
_engine->_actor->heroBehaviour = (HeroBehaviourType)file.readByte();
|
||||
_engine->_actor->heroBehaviour = (HeroBehaviourType)file->readByte();
|
||||
_engine->_actor->previousHeroBehaviour = _engine->_actor->heroBehaviour;
|
||||
_engine->_scene->sceneHero->life = file.readByte();
|
||||
inventoryNumKashes = file.readSint16LE();
|
||||
magicLevelIdx = file.readByte();
|
||||
inventoryMagicPoints = file.readByte();
|
||||
inventoryNumLeafsBox = file.readByte();
|
||||
_engine->_scene->newHeroX = file.readSint16LE();
|
||||
_engine->_scene->newHeroY = file.readSint16LE();
|
||||
_engine->_scene->newHeroZ = file.readSint16LE();
|
||||
_engine->_scene->sceneHero->angle = file.readSint16LE();
|
||||
_engine->_scene->sceneHero->life = file->readByte();
|
||||
inventoryNumKashes = file->readSint16LE();
|
||||
magicLevelIdx = file->readByte();
|
||||
inventoryMagicPoints = file->readByte();
|
||||
inventoryNumLeafsBox = file->readByte();
|
||||
_engine->_scene->newHeroX = file->readSint16LE();
|
||||
_engine->_scene->newHeroY = file->readSint16LE();
|
||||
_engine->_scene->newHeroZ = file->readSint16LE();
|
||||
_engine->_scene->sceneHero->angle = file->readSint16LE();
|
||||
_engine->_actor->previousHeroAngle = _engine->_scene->sceneHero->angle;
|
||||
_engine->_scene->sceneHero->body = file.readByte();
|
||||
_engine->_scene->sceneHero->body = file->readByte();
|
||||
|
||||
const byte numHolemapFlags = file.readByte(); // number of holomap locations, always 150
|
||||
const byte numHolemapFlags = file->readByte(); // number of holomap locations, always 150
|
||||
if (numHolemapFlags != ARRAYSIZE(holomapFlags)) {
|
||||
warning("Failed to load holomapflags");
|
||||
return false;
|
||||
}
|
||||
file.read(holomapFlags, numHolemapFlags);
|
||||
file->read(holomapFlags, numHolemapFlags);
|
||||
|
||||
inventoryNumGas = file.readByte();
|
||||
inventoryNumGas = file->readByte();
|
||||
|
||||
const byte numInventoryFlags = file.readByte(); // number of used inventory items, always 28
|
||||
const byte numInventoryFlags = file->readByte(); // number of used inventory items, always 28
|
||||
if (numInventoryFlags != NUM_INVENTORY_ITEMS) {
|
||||
warning("Failed to load inventoryFlags");
|
||||
return false;
|
||||
}
|
||||
file.read(inventoryFlags, numInventoryFlags);
|
||||
file->read(inventoryFlags, numInventoryFlags);
|
||||
|
||||
inventoryNumLeafs = file.readByte();
|
||||
usingSabre = file.readByte();
|
||||
inventoryNumLeafs = file->readByte();
|
||||
usingSabre = file->readByte();
|
||||
|
||||
_engine->_scene->currentSceneIdx = -1;
|
||||
_engine->_scene->heroPositionType = ScenePositionType::kReborn;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameState::saveGame() {
|
||||
Common::DumpFile file;
|
||||
// TODO: the filename must be handled properly
|
||||
if (!file.open(SAVE_DIR "S9999.LBA")) {
|
||||
warning("Could not save the game");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GameState::saveGame(Common::OutSaveFile* file) {
|
||||
// TODO: the player name must be handled properly
|
||||
Common::strlcpy(playerName, "TwinEngineSave", sizeof(playerName));
|
||||
|
||||
file.writeByte(0x03);
|
||||
file.writeString(playerName);
|
||||
file.writeByte(NUM_GAME_FLAGS);
|
||||
file.write(gameFlags, sizeof(gameFlags));
|
||||
file.writeByte(_engine->_scene->currentSceneIdx);
|
||||
file.writeByte(gameChapter);
|
||||
file.writeByte(_engine->_actor->heroBehaviour);
|
||||
file.writeByte(_engine->_scene->sceneHero->life);
|
||||
file.writeSint16LE(inventoryNumKashes);
|
||||
file.writeByte(magicLevelIdx);
|
||||
file.writeByte(inventoryMagicPoints);
|
||||
file.writeByte(inventoryNumLeafsBox);
|
||||
file.writeSint16LE(_engine->_scene->newHeroX);
|
||||
file.writeSint16LE(_engine->_scene->newHeroY);
|
||||
file.writeSint16LE(_engine->_scene->newHeroZ);
|
||||
file.writeSint16LE(_engine->_scene->sceneHero->angle);
|
||||
file.writeByte(_engine->_scene->sceneHero->body);
|
||||
file->writeByte(0x03);
|
||||
file->writeString(playerName);
|
||||
file->writeByte(NUM_GAME_FLAGS);
|
||||
file->write(gameFlags, sizeof(gameFlags));
|
||||
file->writeByte(_engine->_scene->currentSceneIdx);
|
||||
file->writeByte(gameChapter);
|
||||
file->writeByte(_engine->_actor->heroBehaviour);
|
||||
file->writeByte(_engine->_scene->sceneHero->life);
|
||||
file->writeSint16LE(inventoryNumKashes);
|
||||
file->writeByte(magicLevelIdx);
|
||||
file->writeByte(inventoryMagicPoints);
|
||||
file->writeByte(inventoryNumLeafsBox);
|
||||
file->writeSint16LE(_engine->_scene->newHeroX);
|
||||
file->writeSint16LE(_engine->_scene->newHeroY);
|
||||
file->writeSint16LE(_engine->_scene->newHeroZ);
|
||||
file->writeSint16LE(_engine->_scene->sceneHero->angle);
|
||||
file->writeByte(_engine->_scene->sceneHero->body);
|
||||
|
||||
// number of holomap locations
|
||||
file.writeByte(ARRAYSIZE(holomapFlags));
|
||||
file.write(holomapFlags, sizeof(holomapFlags));
|
||||
file->writeByte(ARRAYSIZE(holomapFlags));
|
||||
file->write(holomapFlags, sizeof(holomapFlags));
|
||||
|
||||
file.writeByte(inventoryNumGas);
|
||||
file->writeByte(inventoryNumGas);
|
||||
|
||||
// number of inventory items
|
||||
file.writeByte(ARRAYSIZE(inventoryFlags));
|
||||
file.write(inventoryFlags, sizeof(inventoryFlags));
|
||||
file->writeByte(ARRAYSIZE(inventoryFlags));
|
||||
file->write(inventoryFlags, sizeof(inventoryFlags));
|
||||
|
||||
file.writeByte(inventoryNumLeafs);
|
||||
file.writeByte(usingSabre);
|
||||
file->writeByte(inventoryNumLeafs);
|
||||
file->writeByte(usingSabre);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#ifndef TWINE_GAMESTATE_H
|
||||
#define TWINE_GAMESTATE_H
|
||||
|
||||
#include "common/savefile.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "twine/actor.h"
|
||||
|
||||
@ -119,8 +120,8 @@ public:
|
||||
|
||||
void processFoundItem(int32 item);
|
||||
|
||||
bool loadGame();
|
||||
bool saveGame();
|
||||
bool loadGame(Common::InSaveFile* file);
|
||||
bool saveGame(Common::OutSaveFile* file);
|
||||
|
||||
void processGameChoices(int32 choiceIdx);
|
||||
|
||||
|
@ -142,6 +142,31 @@ void Input::enableKeyMap(const char *id) {
|
||||
debug("enable keymap %s", id);
|
||||
}
|
||||
|
||||
uint8 Input::processCustomEngineEventStart(const Common::Event &event) {
|
||||
if (!_engine->cfgfile.Debug) {
|
||||
switch (event.customType) {
|
||||
case TwinEActionType::NextRoom:
|
||||
case TwinEActionType::PreviousRoom:
|
||||
case TwinEActionType::ApplyCellingGrid:
|
||||
case TwinEActionType::IncreaseCellingGridIndex:
|
||||
case TwinEActionType::DecreaseCellingGridIndex:
|
||||
break;
|
||||
default:
|
||||
actionStates[event.customType] = 1 + event.kbdRepeat;
|
||||
return twineactions[event.customType].localKey;
|
||||
}
|
||||
} else {
|
||||
actionStates[event.customType] = 1 + event.kbdRepeat;
|
||||
return twineactions[event.customType].localKey;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 Input::processCustomEngineEventEnd(const Common::Event &event) {
|
||||
actionStates[event.customType] = 0;
|
||||
return twineactions[event.customType].localKey;
|
||||
}
|
||||
|
||||
void Input::readKeys() {
|
||||
skippedKey = 0;
|
||||
|
||||
@ -150,27 +175,10 @@ void Input::readKeys() {
|
||||
uint8 localKey = 0;
|
||||
switch (event.type) {
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
|
||||
actionStates[event.customType] = 0;
|
||||
localKey = twineactions[event.customType].localKey;
|
||||
localKey = processCustomEngineEventEnd(event);
|
||||
break;
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
|
||||
if (!_engine->cfgfile.Debug) {
|
||||
switch (event.customType) {
|
||||
case TwinEActionType::NextRoom:
|
||||
case TwinEActionType::PreviousRoom:
|
||||
case TwinEActionType::ApplyCellingGrid:
|
||||
case TwinEActionType::IncreaseCellingGridIndex:
|
||||
case TwinEActionType::DecreaseCellingGridIndex:
|
||||
break;
|
||||
default:
|
||||
localKey = twineactions[event.customType].localKey;
|
||||
actionStates[event.customType] = 1 + event.kbdRepeat;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
localKey = twineactions[event.customType].localKey;
|
||||
actionStates[event.customType] = 1 + event.kbdRepeat;
|
||||
}
|
||||
localKey = processCustomEngineEventStart(event);
|
||||
break;
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
leftMouse = 1;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#ifndef TWINE_KEYBOARD_H
|
||||
#define TWINE_KEYBOARD_H
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/keyboard.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
@ -219,6 +220,8 @@ public:
|
||||
void getMousePositions(MouseStatusStruct *mouseData);
|
||||
|
||||
void readKeys();
|
||||
uint8 processCustomEngineEventStart(const Common::Event& event);
|
||||
uint8 processCustomEngineEventEnd(const Common::Event& event);
|
||||
};
|
||||
|
||||
inline const Common::String Input::currentKeyMap() const {
|
||||
|
@ -443,9 +443,6 @@ void Menu::drawButton(const int16 *menuSettings, bool hover) {
|
||||
|
||||
currentButton++;
|
||||
topHeight += 56; // increase button top height
|
||||
|
||||
// slow down the CPU
|
||||
_engine->_system->delayMillis(1);
|
||||
} while (currentButton < maxButton);
|
||||
}
|
||||
|
||||
@ -571,6 +568,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
|
||||
// draw plasma effect for the current selected button
|
||||
drawButton(menuSettings, true);
|
||||
// TODO: update volume settings
|
||||
_engine->_system->delayMillis(10);
|
||||
} while (!_engine->_input->toggleActionIfActive(TwinEActionType::UIEnter));
|
||||
|
||||
currentButton = *(menuSettings + MenuSettings_FirstButton + currentButton * 2); // get current browsed button
|
||||
|
@ -21,7 +21,9 @@
|
||||
*/
|
||||
|
||||
#include "twine/menuoptions.h"
|
||||
#include "common/keyboard.h"
|
||||
#include "common/system.h"
|
||||
#include "common/util.h"
|
||||
#include "twine/flamovies.h"
|
||||
#include "twine/gamestate.h"
|
||||
#include "twine/input.h"
|
||||
@ -41,6 +43,9 @@ namespace TwinE {
|
||||
/** Main menu enter players name */
|
||||
#define MAINMENU_ENTERPLAYERNAME 42
|
||||
|
||||
#define ONSCREENKEYBOARD_WIDTH 14
|
||||
#define ONSCREENKEYBOARD_HEIGHT 5
|
||||
|
||||
static const char allowedCharIndex[] = " ABCDEFGHIJKLM.NOPQRSTUVWXYZ-abcdefghijklm?nopqrstuvwxyz!0123456789\040\b\r\0";
|
||||
|
||||
void MenuOptions::newGame() {
|
||||
@ -113,10 +118,10 @@ void MenuOptions::showCredits() {
|
||||
_engine->setPalette(_engine->_screens->paletteRGBA);
|
||||
}
|
||||
|
||||
void MenuOptions::drawSelectableCharacter(int32 x, int32 y, int32 arg) {
|
||||
void MenuOptions::drawSelectableCharacter(int32 x, int32 y, bool selected) {
|
||||
char buffer[2];
|
||||
|
||||
buffer[0] = allowedCharIndex[y + x * 14];
|
||||
buffer[0] = allowedCharIndex[y + x * ONSCREENKEYBOARD_WIDTH];
|
||||
buffer[1] = '\0';
|
||||
|
||||
const int32 centerX = y * 45 + 25;
|
||||
@ -126,7 +131,7 @@ void MenuOptions::drawSelectableCharacter(int32 x, int32 y, int32 arg) {
|
||||
const int32 centerY = x * 56 + 200;
|
||||
const int32 bottom = x * 56 + 200 + 25;
|
||||
|
||||
if (arg != 0) {
|
||||
if (selected) {
|
||||
_engine->_interface->drawSplittedBox(left, top, right, bottom, 91);
|
||||
} else {
|
||||
_engine->_interface->blitBox(left, top, right, bottom, (const int8 *)_engine->workVideoBuffer.getPixels(), left, top, (int8 *)_engine->frontVideoBuffer.getPixels());
|
||||
@ -142,9 +147,9 @@ void MenuOptions::drawSelectableCharacter(int32 x, int32 y, int32 arg) {
|
||||
}
|
||||
|
||||
void MenuOptions::drawSelectableCharacters() {
|
||||
for (int8 x = 0; x < 5; x++) {
|
||||
for (int8 y = 0; y < 14; y++) {
|
||||
drawSelectableCharacter(x, y, 0);
|
||||
for (int8 x = 0; x < ONSCREENKEYBOARD_HEIGHT; x++) {
|
||||
for (int8 y = 0; y < ONSCREENKEYBOARD_WIDTH; y++) {
|
||||
drawSelectableCharacter(x, y, _onScreenKeyboardY == x && _onScreenKeyboardX == y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -154,7 +159,7 @@ void MenuOptions::drawPlayerName(int32 centerx, int32 top, int32 type) {
|
||||
const int left = _engine->_text->dialTextBoxLeft;
|
||||
const int right = _engine->_text->dialTextBoxRight;
|
||||
if (type == 1) {
|
||||
_engine->_menu->processPlasmaEffect(left, top, right, 1);
|
||||
_engine->_menu->processPlasmaEffect(left, top, right, 32);
|
||||
}
|
||||
|
||||
const int bottom = _engine->_text->dialTextBoxBottom;
|
||||
@ -167,54 +172,120 @@ void MenuOptions::drawPlayerName(int32 centerx, int32 top, int32 type) {
|
||||
// TODO: _engine->copyBlockPhys(left, top, right, bottom);
|
||||
}
|
||||
|
||||
int32 MenuOptions::enterPlayerName(int32 textIdx) {
|
||||
bool MenuOptions::enterPlayerName(int32 textIdx) {
|
||||
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
|
||||
_engine->flip();
|
||||
playerName[0] = '\0'; // TODO: read from settings?
|
||||
while (1) {
|
||||
_engine->_text->initTextBank(0);
|
||||
char buffer[256];
|
||||
_engine->_text->getMenuText(textIdx, buffer, sizeof(buffer));
|
||||
_engine->_text->setFontColor(15);
|
||||
const int halfScreenWidth = (SCREEN_WIDTH / 2);
|
||||
_engine->_text->drawText(halfScreenWidth - (_engine->_text->getTextSize(buffer) / 2), 20, buffer);
|
||||
_engine->copyBlockPhys(0, 0, SCREEN_WIDTH - 1, 99);
|
||||
drawPlayerName(halfScreenWidth, 100, 1);
|
||||
drawSelectableCharacters();
|
||||
_engine->flip();
|
||||
_engine->_text->initTextBank(0);
|
||||
char buffer[256];
|
||||
_engine->_text->getMenuText(textIdx, buffer, sizeof(buffer));
|
||||
_engine->_text->setFontColor(15);
|
||||
const int halfScreenWidth = (SCREEN_WIDTH / 2);
|
||||
_engine->_text->drawText(halfScreenWidth - (_engine->_text->getTextSize(buffer) / 2), 20, buffer);
|
||||
_engine->copyBlockPhys(0, 0, SCREEN_WIDTH - 1, 99);
|
||||
_engine->flip();
|
||||
|
||||
// we don't want custom events here - as we are entering the player name
|
||||
ScopedKeyMapperDisable scopedKeyMapperDisable;
|
||||
for (;;) {
|
||||
Common::Event event;
|
||||
while (g_system->getEventManager()->pollEvent(event)) {
|
||||
if (event.type == Common::EVENT_KEYDOWN) {
|
||||
if (event.kbd.keycode == Common::KEYCODE_KP_ENTER || event.kbd.keycode == Common::KEYCODE_RETURN) {
|
||||
return 1;
|
||||
for (;;) {
|
||||
Common::Event event;
|
||||
while (g_system->getEventManager()->pollEvent(event)) {
|
||||
switch (event.type) {
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
|
||||
_engine->_input->processCustomEngineEventEnd(event);
|
||||
break;
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
|
||||
_engine->_input->processCustomEngineEventStart(event);
|
||||
|
||||
if (_engine->_input->toggleActionIfActive(TwinEActionType::UIEnter)) {
|
||||
if (_onScreenKeyboardLeaveViaOkButton) {
|
||||
if (_onScreenKeyboardX == ONSCREENKEYBOARD_WIDTH - 1 && _onScreenKeyboardY == ONSCREENKEYBOARD_HEIGHT - 1) {
|
||||
return true;
|
||||
}
|
||||
const size_t size = strlen(playerName);
|
||||
if (_onScreenKeyboardX == ONSCREENKEYBOARD_WIDTH - 2 && _onScreenKeyboardY == ONSCREENKEYBOARD_HEIGHT - 1) {
|
||||
if (size >= 1) {
|
||||
playerName[size - 1] = '\0';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const char chr = allowedCharIndex[_onScreenKeyboardX + _onScreenKeyboardY * ONSCREENKEYBOARD_WIDTH];
|
||||
playerName[size] = chr;
|
||||
playerName[size + 1] = '\0';
|
||||
if (size + 1 >= sizeof(playerName) - 1) {
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const size_t size = strlen(playerName);
|
||||
if (size >= sizeof(playerName) - 1) {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
if (_engine->_input->toggleActionIfActive(TwinEActionType::UIAbort)) {
|
||||
return false;
|
||||
}
|
||||
if (_engine->_input->toggleActionIfActive(TwinEActionType::UILeft)) {
|
||||
--_onScreenKeyboardX;
|
||||
if (_onScreenKeyboardX < 0) {
|
||||
_onScreenKeyboardX = ONSCREENKEYBOARD_WIDTH - 1;
|
||||
}
|
||||
_onScreenKeyboardLeaveViaOkButton = true;
|
||||
} else if (_engine->_input->toggleActionIfActive(TwinEActionType::UIRight)) {
|
||||
++_onScreenKeyboardX;
|
||||
if (_onScreenKeyboardX >= ONSCREENKEYBOARD_WIDTH) {
|
||||
_onScreenKeyboardX = 0;
|
||||
}
|
||||
_onScreenKeyboardLeaveViaOkButton = true;
|
||||
}
|
||||
if (_engine->_input->toggleActionIfActive(TwinEActionType::UIUp)) {
|
||||
--_onScreenKeyboardY;
|
||||
if (_onScreenKeyboardY < 0) {
|
||||
_onScreenKeyboardY = ONSCREENKEYBOARD_HEIGHT - 1;
|
||||
}
|
||||
_onScreenKeyboardLeaveViaOkButton = true;
|
||||
} else if (_engine->_input->toggleActionIfActive(TwinEActionType::UIDown)) {
|
||||
++_onScreenKeyboardY;
|
||||
if (_onScreenKeyboardY >= ONSCREENKEYBOARD_HEIGHT) {
|
||||
_onScreenKeyboardY = 0;
|
||||
}
|
||||
_onScreenKeyboardLeaveViaOkButton = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case Common::EVENT_KEYDOWN: {
|
||||
const size_t size = strlen(playerName);
|
||||
if (!Common::isPrint(event.kbd.ascii)) {
|
||||
if (event.kbd.keycode == Common::KEYCODE_BACKSPACE) {
|
||||
if (size >= 1) {
|
||||
playerName[size - 1] = '\0';
|
||||
_onScreenKeyboardLeaveViaOkButton = false;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (size >= sizeof(playerName) - 1) {
|
||||
return true;
|
||||
}
|
||||
if (strchr(allowedCharIndex, event.kbd.ascii)) {
|
||||
playerName[size] = event.kbd.ascii;
|
||||
playerName[size + 1] = '\0';
|
||||
debug("name: %s", playerName);
|
||||
|
||||
drawPlayerName(halfScreenWidth, 100, 1);
|
||||
_engine->flip();
|
||||
_onScreenKeyboardLeaveViaOkButton = false;
|
||||
}
|
||||
}
|
||||
if (_engine->shouldQuit()) {
|
||||
|
||||
_engine->flip();
|
||||
break;
|
||||
}
|
||||
_engine->_system->delayMillis(1);
|
||||
};
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_engine->shouldQuit()) {
|
||||
break;
|
||||
}
|
||||
_engine->_system->delayMillis(10);
|
||||
drawPlayerName(halfScreenWidth, 100, 1);
|
||||
drawSelectableCharacters();
|
||||
}
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
void MenuOptions::newGameMenu() {
|
||||
// TODO: process players name
|
||||
if (enterPlayerName(MAINMENU_ENTERPLAYERNAME)) {
|
||||
_engine->_gameState->initEngineVars();
|
||||
newGame();
|
||||
@ -225,16 +296,41 @@ void MenuOptions::newGameMenu() {
|
||||
}
|
||||
}
|
||||
|
||||
int MenuOptions::chooseSave(int textIdx) {
|
||||
if (!_engine->hasSavedSlots()) {
|
||||
return -1;
|
||||
}
|
||||
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
|
||||
_engine->flip();
|
||||
do {
|
||||
// TODO: assemble menu with save slots and make then loadable.
|
||||
_engine->_text->initTextBank(0);
|
||||
char buffer[256];
|
||||
_engine->_text->getMenuText(textIdx, buffer, sizeof(buffer));
|
||||
_engine->_text->setFontColor(15);
|
||||
const int halfScreenWidth = (SCREEN_WIDTH / 2);
|
||||
_engine->_text->drawText(halfScreenWidth - (_engine->_text->getTextSize(buffer) / 2), 20, buffer);
|
||||
_engine->copyBlockPhys(0, 0, SCREEN_WIDTH - 1, 99);
|
||||
_engine->flip();
|
||||
|
||||
if (_engine->shouldQuit()) {
|
||||
break;
|
||||
}
|
||||
_engine->_system->delayMillis(1);
|
||||
} while (_engine->_input->toggleAbortAction());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MenuOptions::continueGameMenu() {
|
||||
//TODO: get list of saved games
|
||||
//if(chooseSave(MAINMENU_CONTINUEGAME))
|
||||
{
|
||||
const int slot = chooseSave(MAINMENU_CONTINUEGAME);
|
||||
if (slot >= 0) {
|
||||
_engine->_gameState->initEngineVars();
|
||||
_engine->_gameState->loadGame();
|
||||
_engine->loadSaveSlot(slot);
|
||||
if (_engine->_scene->newHeroX == -1) {
|
||||
_engine->_scene->heroPositionType = ScenePositionType::kNoPosition;
|
||||
}
|
||||
if (_engine->_gameState->gameChapter == 0 && _engine->_scene->currentSceneIdx == 0) {
|
||||
if (_engine->_gameState->gameChapter == 0 && _engine->_scene->currentSceneIdx == LBA1SceneId::Citadel_Island_Prison) {
|
||||
newGame();
|
||||
} else {
|
||||
_engine->_text->newGameVar5 = 0;
|
||||
|
@ -32,12 +32,17 @@ class MenuOptions {
|
||||
private:
|
||||
TwinEEngine *_engine;
|
||||
|
||||
int32 enterPlayerName(int32 textIdx);
|
||||
int _onScreenKeyboardX = 0;
|
||||
int _onScreenKeyboardY = 0;
|
||||
bool _onScreenKeyboardLeaveViaOkButton = false;
|
||||
|
||||
bool enterPlayerName(int32 textIdx);
|
||||
void drawSelectableCharacters();
|
||||
void drawPlayerName(int32 centerx, int32 top, int32 type);
|
||||
void drawSelectableCharacter(int32 x, int32 y, int32 arg);
|
||||
void drawSelectableCharacter(int32 x, int32 y, bool selected);
|
||||
void showCredits();
|
||||
void newGame();
|
||||
int chooseSave(int textIdx);
|
||||
|
||||
public:
|
||||
MenuOptions(TwinEEngine *engine) : _engine(engine) {}
|
||||
|
@ -304,7 +304,7 @@ void Scene::changeScene() {
|
||||
if (previousSceneIdx != needChangeScene) {
|
||||
_engine->_actor->previousHeroBehaviour = _engine->_actor->heroBehaviour;
|
||||
_engine->_actor->previousHeroAngle = sceneHero->angle;
|
||||
_engine->_gameState->saveGame();
|
||||
_engine->autoSave();
|
||||
}
|
||||
|
||||
_engine->_actor->restartHeroScene();
|
||||
|
@ -248,8 +248,8 @@ public:
|
||||
uint8 *currentScene = nullptr;
|
||||
|
||||
int32 needChangeScene = LBA1SceneId::Citadel_Island_Prison;
|
||||
int32 currentSceneIdx = 0;
|
||||
int32 previousSceneIdx = 0;
|
||||
int32 currentSceneIdx = LBA1SceneId::Citadel_Island_Prison;
|
||||
int32 previousSceneIdx = LBA1SceneId::Citadel_Island_Prison;
|
||||
|
||||
uint8 *spriteShadowPtr = nullptr;
|
||||
uint8 *spriteBoundingBoxPtr = nullptr;
|
||||
|
@ -1396,11 +1396,11 @@ static int32 lTHE_END(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
|
||||
engine->_gameState->inventoryNumLeafs = 0;
|
||||
engine->_scene->sceneHero->life = 50;
|
||||
engine->_gameState->inventoryMagicPoints = 80;
|
||||
engine->_scene->currentSceneIdx = 113;
|
||||
engine->_scene->currentSceneIdx = LBA1SceneId::Polar_Island_Final_Battle;
|
||||
engine->_actor->heroBehaviour = engine->_actor->previousHeroBehaviour;
|
||||
engine->_scene->newHeroX = -1;
|
||||
engine->_scene->sceneHero->angle = engine->_actor->previousHeroAngle;
|
||||
engine->_gameState->saveGame();
|
||||
engine->autoSave();
|
||||
return 1; // break;
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,14 @@
|
||||
#include "common/error.h"
|
||||
#include "common/events.h"
|
||||
#include "common/keyboard.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/str.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/system.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "common/translation.h"
|
||||
#include "engines/util.h"
|
||||
#include "engines/metaengine.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "graphics/palette.h"
|
||||
#include "graphics/pixelformat.h"
|
||||
@ -167,6 +170,36 @@ bool TwinEEngine::hasFeature(EngineFeature f) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TwinEEngine::hasSavedSlots() {
|
||||
Common::SaveFileManager *saveFileMan = getSaveFileManager();
|
||||
const Common::String pattern(getMetaEngine().getSavegameFilePattern(_targetName.c_str()));
|
||||
return !saveFileMan->listSavefiles(pattern).empty();
|
||||
}
|
||||
|
||||
void TwinEEngine::wipeSaveSlot(int slot) {
|
||||
Common::SaveFileManager *saveFileMan = getSaveFileManager();
|
||||
const Common::String& saveFile = getMetaEngine().getSavegameFile(slot, _targetName.c_str());
|
||||
saveFileMan->removeSavefile(saveFile);
|
||||
}
|
||||
|
||||
bool TwinEEngine::loadSaveSlot(int slot) {
|
||||
Common::SaveFileManager *saveFileMan = getSaveFileManager();
|
||||
const Common::String& saveFile = getMetaEngine().getSavegameFile(slot, _targetName.c_str());
|
||||
Common::InSaveFile* file = saveFileMan->openForLoading(saveFile);
|
||||
return _gameState->loadGame(file);
|
||||
}
|
||||
|
||||
bool TwinEEngine::saveSlot(int slot) {
|
||||
Common::SaveFileManager *saveFileMan = getSaveFileManager();
|
||||
const Common::String& saveFile = getMetaEngine().getSavegameFile(slot, _targetName.c_str());
|
||||
Common::OutSaveFile* file = saveFileMan->openForSaving(saveFile);
|
||||
return _gameState->saveGame(file);
|
||||
}
|
||||
|
||||
void TwinEEngine::autoSave() {
|
||||
// TODO:
|
||||
}
|
||||
|
||||
void TwinEEngine::allocVideoMemory() {
|
||||
const Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();
|
||||
workVideoBuffer.create(SCREEN_WIDTH, SCREEN_HEIGHT, format);
|
||||
@ -362,7 +395,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
|
||||
unfreezeTime();
|
||||
_redraw->redrawEngineActions(1);
|
||||
freezeTime();
|
||||
_gameState->saveGame(); // auto save game
|
||||
autoSave();
|
||||
quitGame = 0;
|
||||
unfreezeTime();
|
||||
return 0;
|
||||
@ -705,7 +738,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
|
||||
_scene->currentSceneIdx = _scene->previousSceneIdx;
|
||||
}
|
||||
|
||||
_gameState->saveGame();
|
||||
autoSave();
|
||||
_gameState->processGameoverAnimation();
|
||||
quitGame = 0;
|
||||
return 0;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "graphics/pixelformat.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "metaengine.h"
|
||||
#include "twine/actor.h"
|
||||
#include "twine/input.h"
|
||||
#include "twine/detection.h"
|
||||
@ -167,6 +168,12 @@ public:
|
||||
Common::Error run() override;
|
||||
bool hasFeature(EngineFeature f) const override;
|
||||
|
||||
void wipeSaveSlot(int slot);
|
||||
bool hasSavedSlots();
|
||||
bool loadSaveSlot(int slot);
|
||||
bool saveSlot(int slot);
|
||||
void autoSave();
|
||||
|
||||
bool isLBA1() const { return _gameType == TwineGameType::GType_LBA; };
|
||||
bool isLBA2() const { return _gameType == TwineGameType::GType_LBA2; };
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user