[Scummvm-git-logs] scummvm master -> cab620551efd401cbb4c1613ee14efb62e9d6296
mgerhardy
martin.gerhardy at gmail.com
Thu Feb 18 22:53:57 UTC 2021
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
5670e59e3d TWINE: support dotemu enhanced edition save games
cab620551e TWINE: added steam achievement support
Commit: 5670e59e3da2cfa00d7b928413cde2e73bfdcea1
https://github.com/scummvm/scummvm/commit/5670e59e3da2cfa00d7b928413cde2e73bfdcea1
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-02-18T23:52:24+01:00
Commit Message:
TWINE: support dotemu enhanced edition save games
Changed paths:
engines/twine/scene/gamestate.cpp
diff --git a/engines/twine/scene/gamestate.cpp b/engines/twine/scene/gamestate.cpp
index ab2c18ed73..850f53ca80 100644
--- a/engines/twine/scene/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -152,7 +152,9 @@ bool GameState::loadGame(Common::SeekableReadStream *file) {
}
debug(2, "Load game");
- if (file->readByte() != 0x03) {
+ const byte saveFileVersion = file->readByte();
+ // 4 is dotemu enhanced version of lba1
+ if (saveFileVersion != 3 && saveFileVersion != 4) {
warning("Could not load savegame - wrong magic byte");
return false;
}
@@ -216,6 +218,12 @@ bool GameState::loadGame(Common::SeekableReadStream *file) {
inventoryNumLeafs = file->readByte();
usingSabre = file->readByte();
+ if (saveFileVersion == 4) {
+ // the time the game was played
+ file->readUint32LE();
+ file->readUint32LE();
+ }
+
_engine->_scene->currentSceneIdx = -1;
_engine->_scene->heroPositionType = ScenePositionType::kReborn;
return true;
Commit: cab620551efd401cbb4c1613ee14efb62e9d6296
https://github.com/scummvm/scummvm/commit/cab620551efd401cbb4c1613ee14efb62e9d6296
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-02-18T23:52:24+01:00
Commit Message:
TWINE: added steam achievement support
Not all achievements are implemented yet
Changed paths:
A engines/twine/achievements_tables.h
engines/twine/metaengine.cpp
engines/twine/scene/actor.cpp
engines/twine/scene/actor.h
engines/twine/scene/extra.cpp
engines/twine/scene/gamestate.cpp
engines/twine/scene/gamestate.h
engines/twine/scene/scene.cpp
engines/twine/script/script_life_v1.cpp
engines/twine/script/script_move_v1.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/achievements_tables.h b/engines/twine/achievements_tables.h
new file mode 100644
index 0000000000..6e5d1609a4
--- /dev/null
+++ b/engines/twine/achievements_tables.h
@@ -0,0 +1,78 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_ACHIEVEMENTS_H
+#define TWINE_ACHIEVEMENTS_H
+
+#include "common/achievements.h"
+
+namespace TwinE {
+
+struct AchievementDescriptionList {
+ const char *gameId;
+ Common::AchievementsPlatform platform;
+ const char *appId;
+ const Common::AchievementDescription descriptions[64];
+};
+
+#define ACHIEVEMENT_SIMPLE_ENTRY(id, title, comment) \
+ { id, false, title, comment }
+#define ACHIEVEMENT_NODESC_ENTRY(id, title) \
+ { id, false, title, "" }
+#define ACHIEVEMENT_HIDDEN_ENTRY(id, title) \
+ { id, true, title, "" }
+#define ACHIEVEMENTS_LISTEND \
+ { 0, 0, 0, 0 }
+
+static const AchievementDescriptionList achievementDescriptionList[] = {
+ {
+ // https://steamdb.info/app/397330/stats/
+ "lba",
+ Common::STEAM_ACHIEVEMENTS,
+ "397330",
+ {
+ ACHIEVEMENT_SIMPLE_ENTRY("LBA_ACH_001", "Victory!", "Finish the game."),
+ ACHIEVEMENT_SIMPLE_ENTRY("LBA_ACH_002", "Heavily armed", "Get the magic saber."),
+ ACHIEVEMENT_SIMPLE_ENTRY("LBA_ACH_003", "Collector", "Unlock all the clover boxes."),
+ ACHIEVEMENT_SIMPLE_ENTRY("LBA_ACH_004", "FIRE !", "Fire the canon in the museum."),
+ ACHIEVEMENT_SIMPLE_ENTRY("LBA_ACH_005", "New record", "Finish the game in less than 4h."),
+ ACHIEVEMENT_SIMPLE_ENTRY("LBA_ACH_006", "Double vision", "Get into the meca-pinguin room."),
+ ACHIEVEMENT_SIMPLE_ENTRY("LBA_ACH_007", "I do what I want!", "Get the syrup in the pharmacy before going to Twinsen's house."),
+ ACHIEVEMENT_SIMPLE_ENTRY("LBA_ACH_008", "Fanboy", "Talk to the Star Wars fanboy."),
+ ACHIEVEMENT_SIMPLE_ENTRY("LBA_ACH_009", "Secret breaker", "Find the secret passage in the museum."),
+ ACHIEVEMENT_SIMPLE_ENTRY("LBA_ACH_010", "Seasickness", "Unlock the second video of the ferry trip."),
+ ACHIEVEMENT_SIMPLE_ENTRY("LBA_ACH_011", "Croesus", "Have at least 500 Kashes in your wallet."),
+ ACHIEVEMENT_SIMPLE_ENTRY("LBA_ACH_012", "In your face", "Unlock the 4 videos in which Twinsen gets a slap."),
+ ACHIEVEMENTS_LISTEND
+ }
+ },
+
+ {0, Common::UNK_ACHIEVEMENTS, 0, {ACHIEVEMENTS_LISTEND}}};
+
+} // namespace TwinE
+
+#undef ACHIEVEMENT_SIMPLE_ENTRY
+#undef ACHIEVEMENT_NODESC_ENTRY
+#undef ACHIEVEMENT_HIDDEN_ENTRY
+#undef ACHIEVEMENTS_LISTEND
+
+#endif // TWINE_ACHIEVEMENTS_H
diff --git a/engines/twine/metaengine.cpp b/engines/twine/metaengine.cpp
index 06c48774ec..56b6308c8f 100644
--- a/engines/twine/metaengine.cpp
+++ b/engines/twine/metaengine.cpp
@@ -29,7 +29,7 @@
#include "common/translation.h"
#include "engines/advancedDetector.h"
#include "twine/detection.h"
-
+#include "twine/achievements_tables.h"
#include "twine/input.h"
#include "twine/twine.h"
@@ -60,6 +60,8 @@ public:
Common::Array<Common::Keymap *> initKeymaps(const char *target) const override;
const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const override;
+
+ const Common::AchievementsInfo getAchievementsInfo(const Common::String &target) const override;
};
static const ExtraGuiOption OptWallCollision = {
@@ -165,6 +167,30 @@ const ExtraGuiOptions TwinEMetaEngine::getExtraGuiOptions(const Common::String &
return options;
}
+const Common::AchievementsInfo TwinEMetaEngine::getAchievementsInfo(const Common::String &target) const {
+ Common::String gameId = ConfMan.get("gameid", target);
+
+ Common::AchievementsPlatform platform = Common::UNK_ACHIEVEMENTS;
+ Common::String extra = ConfMan.get("extra", target);
+ if (extra.contains("Steam")) {
+ platform = Common::STEAM_ACHIEVEMENTS;
+ }
+
+ // "(gameId, platform) -> result" search
+ Common::AchievementsInfo result;
+ for (const TwinE::AchievementDescriptionList *i = TwinE::achievementDescriptionList; i->gameId; ++i) {
+ if (i->gameId == gameId && i->platform == platform) {
+ result.platform = i->platform;
+ result.appId = i->appId;
+ for (const Common::AchievementDescription *it = i->descriptions; it->id; ++it) {
+ result.descriptions.push_back(*it);
+ }
+ break;
+ }
+ }
+ return result;
+}
+
//
// unused:
// JOY_LEFT_TRIGGER
diff --git a/engines/twine/scene/actor.cpp b/engines/twine/scene/actor.cpp
index e30e7baca2..392ba6970e 100644
--- a/engines/twine/scene/actor.cpp
+++ b/engines/twine/scene/actor.cpp
@@ -350,6 +350,7 @@ void Actor::initActor(int16 actorIdx) {
void Actor::resetActor(int16 actorIdx) {
ActorStruct *actor = _engine->_scene->getActor(actorIdx);
+ actor->actorIdx = actorIdx;
actor->body = BodyType::btNormal;
actor->anim = AnimationTypes::kStanding;
actor->x = 0;
diff --git a/engines/twine/scene/actor.h b/engines/twine/scene/actor.h
index 074afa4bcc..707de2bc1d 100644
--- a/engines/twine/scene/actor.h
+++ b/engines/twine/scene/actor.h
@@ -195,6 +195,7 @@ public:
bool isAttackAnimationActive() const;
bool isJumpAnimationActive() const;
+ int16 actorIdx = 0; // own actor index
int32 x = 0;
int32 y = 0;
int32 z = 0;
diff --git a/engines/twine/scene/extra.cpp b/engines/twine/scene/extra.cpp
index cad2fdefea..95527d8348 100644
--- a/engines/twine/scene/extra.cpp
+++ b/engines/twine/scene/extra.cpp
@@ -883,6 +883,9 @@ void Extra::processExtras() {
if (_engine->_gameState->inventoryNumKashes > 999) {
_engine->_gameState->inventoryNumKashes = 999;
}
+ if (_engine->_gameState->inventoryNumKashes >= 500) {
+ _engine->unlockAchievement("LBA_ACH_011");
+ }
} else if (extra->info0 == SPRITEHQR_LIFEPOINTS) {
_engine->_scene->sceneHero->life += extra->info1;
if (_engine->_scene->sceneHero->life > 50) {
diff --git a/engines/twine/scene/gamestate.cpp b/engines/twine/scene/gamestate.cpp
index 850f53ca80..828f268e06 100644
--- a/engines/twine/scene/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -284,6 +284,27 @@ bool GameState::saveGame(Common::WriteStream *file) {
return true;
}
+void GameState::setGameFlag(uint8 index, uint8 value) {
+ debug(2, "Set gameStateFlags[%u]=%u", index, value);
+ _gameStateFlags[index] = value;
+
+ // all 4 slap videos
+ if ((index == 200 || index == 201 || index == 202 || index == 215) &&
+ _gameStateFlags[200] != 0 && _gameStateFlags[201] != 0 && _gameStateFlags[202] != 0 && _gameStateFlags[215] != 0) {
+ _engine->unlockAchievement("LBA_ACH_012");
+ }
+ // second video of ferry trip
+ if (index == 209) {
+ _engine->unlockAchievement("LBA_ACH_010");
+ }
+ if (index == (int)InventoryItems::kiUseSabre) {
+ _engine->unlockAchievement("LBA_ACH_002");
+ }
+ if (index == (int)InventoryItems::kBottleOfSyrup) {
+ _engine->unlockAchievement("LBA_ACH_007");
+ }
+}
+
void GameState::processFoundItem(int32 item) {
_engine->_grid->newCameraX = (_engine->_scene->sceneHero->x + BRICK_HEIGHT) / BRICK_SIZE;
_engine->_grid->newCameraY = (_engine->_scene->sceneHero->y + BRICK_HEIGHT) / BRICK_HEIGHT;
diff --git a/engines/twine/scene/gamestate.h b/engines/twine/scene/gamestate.h
index e95362508d..1f621789f1 100644
--- a/engines/twine/scene/gamestate.h
+++ b/engines/twine/scene/gamestate.h
@@ -146,10 +146,7 @@ public:
return _gameStateFlags[index];
}
- inline void setGameFlag(uint8 index, uint8 value) {
- debug(2, "Set gameStateFlags[%u]=%u", index, value);
- _gameStateFlags[index] = value;
- }
+ void setGameFlag(uint8 index, uint8 value);
/**
* LBA engine chapter
diff --git a/engines/twine/scene/scene.cpp b/engines/twine/scene/scene.cpp
index 2179e73a7a..f40847a920 100644
--- a/engines/twine/scene/scene.cpp
+++ b/engines/twine/scene/scene.cpp
@@ -465,6 +465,14 @@ void Scene::changeScene() {
previousSceneIdx = currentSceneIdx;
currentSceneIdx = needChangeScene;
+ if (needChangeScene == LBA1SceneId::Polar_Island_end_scene) {
+ _engine->unlockAchievement("LBA_ACH_001");
+ // TODO: if you finish in under 4 hours - unlock the achievement - see version 4 savegames
+ // _engine->unlockAchievment("LBA_ACH_005");
+ } else if (needChangeScene == LBA1SceneId::Brundle_Island_Secret_room) {
+ _engine->unlockAchievement("LBA_ACH_006");
+ }
+
_engine->_sound->stopSamples();
resetScene();
diff --git a/engines/twine/script/script_life_v1.cpp b/engines/twine/script/script_life_v1.cpp
index 9af9f08db6..fe1d5c466d 100644
--- a/engines/twine/script/script_life_v1.cpp
+++ b/engines/twine/script/script_life_v1.cpp
@@ -652,6 +652,9 @@ static int32 lMESSAGE(TwinEEngine *engine, LifeScriptContext &ctx) {
engine->_text->setFontCrossColor(ctx.actor->talkColor);
engine->_scene->talkingActor = ctx.actorIdx;
engine->_text->drawTextProgressive(textIdx);
+ if (engine->_scene->currentSceneIdx == LBA1SceneId::Principal_Island_Library && engine->_scene->talkingActor == 8)/* && (*(short *)lifeScriptPosition == 0xe2 [226])*/ {
+ engine->unlockAchievement("LBA_ACH_008");
+ }
engine->unfreezeTime();
engine->_redraw->redrawEngineActions(true);
@@ -1242,6 +1245,9 @@ static int32 lPLAY_MIDI(TwinEEngine *engine, LifeScriptContext &ctx) {
static int32 lINC_CLOVER_BOX(TwinEEngine *engine, LifeScriptContext &ctx) {
if (engine->_gameState->inventoryNumLeafsBox < 10) {
engine->_gameState->inventoryNumLeafsBox++;
+ if (engine->_gameState->inventoryNumLeafsBox == 5) {
+ engine->unlockAchievement("LBA_ACH_003");
+ }
}
return 0;
}
diff --git a/engines/twine/script/script_move_v1.cpp b/engines/twine/script/script_move_v1.cpp
index 63c2d67c15..a0003c917e 100644
--- a/engines/twine/script/script_move_v1.cpp
+++ b/engines/twine/script/script_move_v1.cpp
@@ -211,6 +211,10 @@ static int32 mPOS_POINT(TwinEEngine *engine, MoveScriptContext &ctx) {
static int32 mLABEL(TwinEEngine *engine, MoveScriptContext &ctx) {
ctx.actor->labelIdx = ctx.stream.readByte();
ctx.actor->currentLabelPtr = ctx.stream.pos() - 2;
+ if (engine->_scene->currentSceneIdx == LBA1SceneId::Proxima_Island_Museum && ctx.actor->actorIdx == 2 &&
+ (ctx.actor->labelIdx == 0 || ctx.actor->labelIdx == 1)) {
+ engine->unlockAchievement("LBA_ACH_004");
+ }
return 0;
}
@@ -438,6 +442,9 @@ static int32 mOPEN_LEFT(TwinEEngine *engine, MoveScriptContext &ctx) {
ctx.actor->speed = 1000;
engine->_movements->setActorAngle(ANGLE_0, ANGLE_351, ANGLE_17, &ctx.actor->move);
}
+ if (engine->_scene->currentSceneIdx == LBA1SceneId::Proxima_Island_Museum && ctx.actor->actorIdx == 16) {
+ engine->unlockAchievement("LBA_ACH_009");
+ }
return 0;
}
@@ -454,6 +461,9 @@ static int32 mOPEN_RIGHT(TwinEEngine *engine, MoveScriptContext &ctx) {
ctx.actor->speed = 1000;
engine->_movements->setActorAngle(ANGLE_0, ANGLE_351, ANGLE_17, &ctx.actor->move);
}
+ if (engine->_scene->currentSceneIdx == LBA1SceneId::Proxima_Island_Museum && ctx.actor->actorIdx == 16) {
+ engine->unlockAchievement("LBA_ACH_009");
+ }
return 0;
}
@@ -470,6 +480,9 @@ static int32 mOPEN_UP(TwinEEngine *engine, MoveScriptContext &ctx) {
ctx.actor->speed = 1000;
engine->_movements->setActorAngle(ANGLE_0, ANGLE_351, ANGLE_17, &ctx.actor->move);
}
+ if (engine->_scene->currentSceneIdx == LBA1SceneId::Proxima_Island_Museum && ctx.actor->actorIdx == 16) {
+ engine->unlockAchievement("LBA_ACH_009");
+ }
return 0;
}
@@ -486,6 +499,9 @@ static int32 mOPEN_DOWN(TwinEEngine *engine, MoveScriptContext &ctx) {
ctx.actor->speed = 1000;
engine->_movements->setActorAngle(ANGLE_0, ANGLE_351, ANGLE_17, &ctx.actor->move);
}
+ if (engine->_scene->currentSceneIdx == LBA1SceneId::Proxima_Island_Museum && ctx.actor->actorIdx == 16) {
+ engine->unlockAchievement("LBA_ACH_009");
+ }
return 0;
}
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 3aa749bbe4..022e90b881 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -1167,4 +1167,27 @@ void TwinEEngine::drawText(int32 x, int32 y, const char *string, int32 center) {
center ? Graphics::kTextAlignCenter : Graphics::kTextAlignLeft);
}
+const char *TwinEEngine::getGameId() const {
+ if (isLBA1()) {
+ return "lba";
+ }
+ assert(isLBA2());
+ return "lba2";
+}
+
+bool TwinEEngine::unlockAchievement(const Common::String &id) {
+ const MetaEngine &meta = getMetaEngine();
+ const Common::AchievementsInfo &achievementsInfo = meta.getAchievementsInfo(getGameId());
+
+ Common::String msg = id;
+ for (uint32 i = 0; i < achievementsInfo.descriptions.size(); i++) {
+ if (id == achievementsInfo.descriptions[i].id) {
+ msg = achievementsInfo.descriptions[i].title;
+ break;
+ }
+ }
+
+ return AchMan.setAchievement(id, msg);
+}
+
} // namespace TwinE
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index ec843c1204..e375fdbca7 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -228,6 +228,9 @@ public:
bool isLBA1() const { return _gameType == TwineGameType::GType_LBA; }
bool isLBA2() const { return _gameType == TwineGameType::GType_LBA2; }
+ const char *getGameId() const;
+
+ bool unlockAchievement(const Common::String &id);
Actor *_actor;
Animations *_animations;
More information about the Scummvm-git-logs
mailing list