[Scummvm-git-logs] scummvm master -> ea5029209929423eaeec402added5972e7c60a2f
mduggan
noreply at scummvm.org
Sun Oct 27 07:27:40 UTC 2024
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:
50cface678 DGDS: Implement Heart of China intro natives
ea50292099 DGDS: JANITORIAL: Fix whitespace
Commit: 50cface678ec6a0bacb5dc455ef1898965955378
https://github.com/scummvm/scummvm/commit/50cface678ec6a0bacb5dc455ef1898965955378
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-10-27T18:25:47+11:00
Commit Message:
DGDS: Implement Heart of China intro natives
The full intro cinematic can now play correctly.
Changed paths:
A engines/dgds/dragon_native.cpp
A engines/dgds/dragon_native.h
A engines/dgds/hoc_intro.cpp
A engines/dgds/hoc_intro.h
engines/dgds/dgds.cpp
engines/dgds/dgds.h
engines/dgds/globals.cpp
engines/dgds/globals.h
engines/dgds/menu.cpp
engines/dgds/module.mk
engines/dgds/scene.cpp
engines/dgds/scene.h
engines/dgds/shell_game.h
engines/dgds/sound/drivers/midipatch.cpp
engines/dgds/ttm.cpp
diff --git a/engines/dgds/dgds.cpp b/engines/dgds/dgds.cpp
index 86f29035f00..7e41e539f41 100644
--- a/engines/dgds/dgds.cpp
+++ b/engines/dgds/dgds.cpp
@@ -63,6 +63,7 @@
#include "dgds/sound.h"
#include "dgds/game_palettes.h"
#include "dgds/dragon_arcade.h"
+#include "dgds/hoc_intro.h"
// for frame contents debugging
//#define DUMP_FRAME_DATA 1
@@ -81,7 +82,7 @@ const byte DgdsEngine::HOC_CHAR_SWAP_ICONS[] = { 0, 20, 21, 22 };
DgdsEngine::DgdsEngine(OSystem *syst, const ADGameDescription *gameDesc)
: Engine(syst), _fontManager(nullptr), _console(nullptr), _inventory(nullptr),
_soundPlayer(nullptr), _decompressor(nullptr), _scene(nullptr), _shellGame(nullptr),
- _gdsScene(nullptr), _resource(nullptr), _gamePals(nullptr), _gameGlobals(nullptr),
+ _hocIntro(nullptr), _gdsScene(nullptr), _resource(nullptr), _gamePals(nullptr), _gameGlobals(nullptr),
_detailLevel(kDgdsDetailHigh), _textSpeed(1), _justChangedScene1(false), _justChangedScene2(false),
_random("dgds"), _currentCursor(-1), _menuToTrigger(kMenuNone), _isLoading(true), _flipMode(false),
_rstFileName(nullptr), _difficulty(1), _menu(nullptr), _adsInterp(nullptr), _isDemo(false),
@@ -129,6 +130,7 @@ DgdsEngine::~DgdsEngine() {
delete _menu;
delete _inventory;
delete _shellGame;
+ delete _hocIntro;
delete _dragonArcade;
_icons.reset();
@@ -323,10 +325,9 @@ void DgdsEngine::init(bool restarting) {
delete _menu;
delete _adsInterp;
delete _inventory;
- if (_dragonArcade)
- delete _dragonArcade;
- if (_shellGame)
- delete _shellGame;
+ delete _dragonArcade;
+ delete _shellGame;
+ delete _hocIntro;
}
_gamePals = new GamePalettes(_resource, _decompressor);
@@ -339,8 +340,10 @@ void DgdsEngine::init(bool restarting) {
_inventory = new Inventory();
if (_gameId == GID_DRAGON)
_dragonArcade = new DragonArcade();
- else if (_gameId == GID_HOC)
+ else if (_gameId == GID_HOC) {
_shellGame = new ShellGame();
+ _hocIntro = new HocIntro();
+ }
_backgroundBuffer.create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
_storedAreaBuffer.create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
diff --git a/engines/dgds/dgds.h b/engines/dgds/dgds.h
index cfcef2f1cce..72fc40b2544 100644
--- a/engines/dgds/dgds.h
+++ b/engines/dgds/dgds.h
@@ -60,6 +60,7 @@ class ADSInterpreter;
class Globals;
class ShellGame;
class DragonArcade;
+class HocIntro;
const float MS_PER_FRAME = 16.6667f;
@@ -141,6 +142,7 @@ private:
// HoC only
ShellGame *_shellGame;
+ HocIntro *_hocIntro;
FontManager *_fontManager;
Common::SharedPtr<Image> _corners;
@@ -242,6 +244,7 @@ public:
void setMenuToTrigger(MenuId menu) { _menuToTrigger = menu; }
bool isInvButtonVisible() const;
ShellGame *getShellGame() { return _shellGame; }
+ HocIntro *getHocIntro() { return _hocIntro; }
DragonArcade *getDragonArcade() { return _dragonArcade; }
void setSkipNextFrame() { _skipNextFrame = true; }
diff --git a/engines/dgds/dragon_native.cpp b/engines/dgds/dragon_native.cpp
new file mode 100644
index 00000000000..f62aa2f5f12
--- /dev/null
+++ b/engines/dgds/dragon_native.cpp
@@ -0,0 +1,122 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "dgds/dragon_native.h"
+#include "dgds/globals.h"
+#include "dgds/scene.h"
+
+namespace Dgds {
+
+
+/*static*/
+void DragonNative::drawCountdown(FontManager::FontType fontType, int16 x, int16 y) {
+ DgdsEngine *engine = DgdsEngine::getInstance();
+ int16 countdownEnd = engine->getGameGlobals()->getGlobal(0x22);
+ int16 currentMins = engine->getClock().getMins();
+ const DgdsFont *fnt = engine->getFontMan()->getFont(fontType);
+ Common::String str = Common::String::format("%d", countdownEnd - currentMins);
+ fnt->drawString(&engine->_compositionBuffer, str, x, y, 320 - x, 10);
+}
+
+
+// The first row of this array corresponds to the
+// positions of buttons in game passcode
+// RYP YWP YRPWRY PBW
+static const uint16 DRAGON_PASSCODE[] = {
+ 1, 4, 3, 4, 0, 3, 4, 1, 3, 0, 1, 4, 3, 2, 0,
+ 4, 4, 2, 3, 4, 0, 0, 4, 3, 2, 1, 1, 2, 4, 0,
+ 4, 1, 3, 2, 0, 2, 1, 4, 3, 4, 1, 3, 2, 0, 1
+};
+
+static uint16 passcodeBlockNum = 0;
+static uint16 passcodeVal1 = 0;
+static uint16 passcodeVal2 = 0;
+static uint16 passcodeVal3 = 0;
+static uint16 passcodeVal4 = 0;
+
+/*static*/
+ void DragonNative::updatePasscodeGlobal() {
+ GDSScene *gdsScene = DgdsEngine::getInstance()->getGDSScene();
+ int16 globalval = gdsScene->getGlobal(0x20);
+
+ if (globalval > 34)
+ return;
+
+ if (globalval >= 30) {
+ // One of the keypad buttons
+ if (DRAGON_PASSCODE[passcodeVal4 + passcodeBlockNum * 15] == globalval - 30) {
+ debug("sceneOpUpdatePasscodeGlobal CORRECT: variables %d %d %d %d block %d, curval %d",
+ passcodeVal1, passcodeVal2, passcodeVal3, passcodeVal4, passcodeBlockNum, globalval);
+
+ // Correct entry! Increment the expected button
+ passcodeVal4++;
+ if (passcodeVal4 < passcodeVal3) {
+ globalval = 0;
+ } else if (passcodeVal3 < 15) {
+ globalval = 5;
+ } else {
+ // Finished!
+ globalval = 6;
+ }
+ } else {
+ // Mistake
+ debug("sceneOpUpdatePasscodeGlobal WRONG: variables %d %d %d %d block %d, curval %d",
+ passcodeVal1, passcodeVal2, passcodeVal3, passcodeVal4, passcodeBlockNum, globalval);
+ passcodeVal1 = 0;
+ passcodeVal2 = 5;
+ globalval = 7;
+ }
+ } else {
+ if (globalval > 4 || globalval == 0)
+ return;
+
+ debug("sceneOpUpdatePasscodeGlobal OTHER: variables %d %d %d %d block %d, curval %d",
+ passcodeVal1, passcodeVal2, passcodeVal3, passcodeVal4, passcodeBlockNum, globalval);
+
+ if (globalval < 4) {
+ passcodeBlockNum = globalval - 1; // expect block globalval-1
+ passcodeVal1 = 5;
+ passcodeVal2 = 0;
+ passcodeVal3 = 15; // 15 buttons expected
+ passcodeVal4 = 0;
+ return;
+ } else if (passcodeVal2 > passcodeVal1) {
+ passcodeVal1++;
+ globalval = DRAGON_PASSCODE[passcodeVal1 + passcodeBlockNum * 15] + 20;
+ } else if (passcodeVal2 > 14) {
+ passcodeVal1 = 0;
+ passcodeVal3 = passcodeVal2;
+ passcodeVal4 = 0;
+ globalval = 8;
+ } else {
+ passcodeVal1 = 0;
+ passcodeVal2 += 5;
+ passcodeVal3 = passcodeVal1;
+ passcodeVal4 = 0;
+ globalval = 8;
+ }
+ }
+
+ gdsScene->setGlobal(0x20, globalval);
+}
+
+
+} // end namespace Dgds
diff --git a/engines/dgds/dragon_native.h b/engines/dgds/dragon_native.h
new file mode 100644
index 00000000000..a9a1bc0b542
--- /dev/null
+++ b/engines/dgds/dragon_native.h
@@ -0,0 +1,45 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DGDS_DRAGON_NATIVE_H
+#define DGDS_DRAGON_NATIVE_H
+
+#include "dgds/font.h"
+
+namespace Dgds {
+
+/**
+ * Native scene ops for Rise of the Dragon.
+ *
+ * The arcade section is more complex, see `dragon_arcade.h`
+ */
+class DragonNative {
+public:
+ static void updatePasscodeGlobal();
+ static void drawCountdown(FontManager::FontType fontType, int16 x, int16 y);
+
+private:
+ DragonNative(); // only static ops, don't instantiate
+};
+
+} // end namespace Dgds
+
+#endif // DGDS_DRAGON_NATIVE_H
diff --git a/engines/dgds/globals.cpp b/engines/dgds/globals.cpp
index fc7e23c40c8..35a67a0d7d2 100644
--- a/engines/dgds/globals.cpp
+++ b/engines/dgds/globals.cpp
@@ -233,52 +233,52 @@ public:
};
-HocGlobals::HocGlobals(Clock &clock) : Globals(clock), _unk82(1), _unk55(0),
+HocGlobals::HocGlobals(Clock &clock) : Globals(clock), _difficultyLevel(1), _unk55(0),
_unkDlgFileNum(0), _unkDlgDlgNum(0), _currentCharacter2(0), _currentCharacter(0),
- _unk50(0), _nativeGameState(0), _unk48(0), _unk47(0), _unk46(0), _unk45(0x3f), _sheckels(0),
- _shellBet(0), _shellPea(0), _unk41(0), _unk40(3), _unk39(0) {
+ _tankFinished(0), _nativeGameState(0), _tankState(0), _unk47(0), _unk46(0), _unk45(0x3f), _sheckels(0),
+ _shellBet(0), _shellPea(0), _trainState(0), _startScene(3), _introState(0) {
_globals.push_back(new DetailLevelROGlobal(0x53));
- _globals.push_back(new RWI16Global(0x52, &_unk82));
- _globals.push_back(new RWI16Global(0x37, &_unk55)); // TODO: Special update function FUN_1407_080d, sound init related
+ _globals.push_back(new RWI16Global(0x52, &_difficultyLevel)); // TODO: Sync with difficulty in menu
+ _globals.push_back(new RWI16Global(0x37, &_unk55)); // TODO: Special update function FUN_1407_080d, sound init related.. sound bank?
_globals.push_back(new RWI16Global(0x36, &_unkDlgFileNum));
_globals.push_back(new RWI16Global(0x35, &_unkDlgDlgNum));
_globals.push_back(new HocCharacterGlobal(0x34, &_currentCharacter));
_globals.push_back(new HocCharacterGlobal(0x33, &_currentCharacter2));
- _globals.push_back(new RWI16Global(0x32, &_unk50));
+ _globals.push_back(new RWI16Global(0x32, &_tankFinished));
_globals.push_back(new RWI16Global(0x31, &_nativeGameState));
- _globals.push_back(new RWI16Global(0x30, &_unk48));
- _globals.push_back(new RWI16Global(0x2F, &_unk47));
- _globals.push_back(new RWI16Global(0x2E, &_unk46));
+ _globals.push_back(new RWI16Global(0x30, &_tankState));
+ _globals.push_back(new RWI16Global(0x2F, &_unk47)); // tank related.. cows?
+ _globals.push_back(new RWI16Global(0x2E, &_unk46)); // tank related.. start point?
_globals.push_back(new RWI16Global(0x2D, &_unk45)); // TODO: Special update function FUN_1407_0784, palette related?
_globals.push_back(new RWI16Global(0x2C, &_sheckels)); // used as currency in Istanbul
_globals.push_back(new RWI16Global(0x2B, &_shellBet));
_globals.push_back(new RWI16Global(0x2A, &_shellPea));
- _globals.push_back(new RWI16Global(0x29, &_unk41));
- _globals.push_back(new RWI16Global(0x28, &_unk40));
- _globals.push_back(new ROI16Global(0x27, &_unk39));
+ _globals.push_back(new RWI16Global(0x29, &_trainState));
+ _globals.push_back(new RWI16Global(0x28, &_startScene));
+ _globals.push_back(new ROI16Global(0x27, &_introState));
}
Common::Error HocGlobals::syncState(Common::Serializer &s) {
Globals::syncState(s);
- s.syncAsSint16LE(_unk39);
- s.syncAsSint16LE(_unk40);
- s.syncAsSint16LE(_unk41);
+ s.syncAsSint16LE(_introState);
+ s.syncAsSint16LE(_startScene);
+ s.syncAsSint16LE(_trainState);
s.syncAsSint16LE(_shellPea);
s.syncAsSint16LE(_shellBet);
s.syncAsSint16LE(_sheckels);
s.syncAsSint16LE(_unk45);
s.syncAsSint16LE(_unk46);
s.syncAsSint16LE(_unk47);
- s.syncAsSint16LE(_unk48);
+ s.syncAsSint16LE(_tankState);
s.syncAsSint16LE(_nativeGameState);
- s.syncAsSint16LE(_unk50);
+ s.syncAsSint16LE(_tankFinished);
s.syncAsSint16LE(_currentCharacter);
s.syncAsSint16LE(_currentCharacter2);
s.syncAsSint16LE(_unkDlgDlgNum);
s.syncAsSint16LE(_unkDlgFileNum);
s.syncAsSint16LE(_unk55);
- s.syncAsSint16LE(_unk82);
+ s.syncAsSint16LE(_difficultyLevel);
return Common::kNoError;
}
diff --git a/engines/dgds/globals.h b/engines/dgds/globals.h
index 30cae66926d..dd088737263 100644
--- a/engines/dgds/globals.h
+++ b/engines/dgds/globals.h
@@ -164,26 +164,29 @@ public:
int16 getNativeGameState() const { return _nativeGameState; }
void setNativeGameState(int16 state) { _nativeGameState = state; }
+ int16 getIntroState() const { return _introState; }
+ void setIntroState(int16 state) { _introState = state; }
+
private:
// HoC-specific globals
- int16 _unk39;
- int16 _unk40;
- int16 _unk41;
+ int16 _introState;
+ int16 _startScene;
+ int16 _trainState;
int16 _shellPea;
int16 _shellBet;
int16 _sheckels;
int16 _unk45;
int16 _unk46;
int16 _unk47;
- int16 _unk48;
+ int16 _tankState;
int16 _nativeGameState; // state for the shell game, tank game, etc.
- int16 _unk50;
+ int16 _tankFinished;
int16 _currentCharacter;
int16 _currentCharacter2;
int16 _unkDlgDlgNum;
int16 _unkDlgFileNum;
int16 _unk55;
- int16 _unk82;
+ int16 _difficultyLevel;
Common::Error syncState(Common::Serializer &s) override;
};
diff --git a/engines/dgds/hoc_intro.cpp b/engines/dgds/hoc_intro.cpp
new file mode 100644
index 00000000000..67fdc0adb13
--- /dev/null
+++ b/engines/dgds/hoc_intro.cpp
@@ -0,0 +1,212 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/textconsole.h"
+#include "dgds/hoc_intro.h"
+#include "dgds/dgds.h"
+#include "dgds/sound.h"
+#include "dgds/game_palettes.h"
+#include "dgds/image.h"
+#include "dgds/includes.h"
+#include "dgds/globals.h"
+
+namespace Dgds {
+
+HocIntro::HocIntro() : _scrollCountdown1(0), _xOffset203e(0), _xOffset2042(0), _scrollCountdown2(0) {
+
+}
+
+void HocIntro::init() {
+ DgdsEngine *engine = DgdsEngine::getInstance();
+ HocGlobals *globals = static_cast<HocGlobals *>(engine->getGameGlobals());
+
+ if (globals->getIntroState())
+ return;
+
+ _scrollCountdown2 = 137;
+ _xOffset2042 = 320;
+ _scrollCountdown1 = 150;
+ engine->_soundPlayer->loadMusic("INTRO1.SNG");
+ engine->_soundPlayer->playMusic(0);
+ engine->getGamePals()->loadPalette("xx.pal");
+ Image tmp(engine->getResourceManager(), engine->getDecompressor());
+ tmp.drawScreen("xx.scr", engine->getBackgroundBuffer());
+
+ _maskImg.reset(new Image(engine->getResourceManager(), engine->getDecompressor()));
+ _noMaskImg.reset(new Image(engine->getResourceManager(), engine->getDecompressor()));
+ _maskImg->loadBitmap("xx_mask.bmp");
+ _noMaskImg->loadBitmap("xx_nomas.bmp");
+
+ engine->_compositionBuffer.fillRect(Common::Rect(SCREEN_WIDTH, SCREEN_HEIGHT), 81);
+ globals->setIntroState(1);
+
+ // TODO: Is this the right variable?
+ globals->setNativeGameState(32);
+
+ engine->_soundPlayer->playSFX(35);
+}
+
+void HocIntro::tick() {
+ DgdsEngine *engine = DgdsEngine::getInstance();
+ HocGlobals *globals = static_cast<HocGlobals *>(engine->getGameGlobals());
+ if (!globals->getIntroState())
+ return;
+
+ if (_scrollCountdown2 != 0)
+ _scrollCountdown2--;
+
+ if (_xOffset2042 > -90)
+ _xOffset2042 -= 3;
+
+ _scrollCountdown1--;
+
+ doScroll();
+
+ _drawWin.left = 0;
+}
+
+void HocIntro::doScroll() {
+ DgdsEngine *engine = DgdsEngine::getInstance();
+ HocGlobals *globals = static_cast<HocGlobals *>(engine->getGameGlobals());
+ assert(globals->getIntroState());
+
+ if (_scrollCountdown1 == 0) {
+ globals->setIntroState(2);
+ _scrollCountdown1 = 1;
+ }
+
+ // For the start of the scroll, we want to blank out the background.
+ // The original does this differently but this will do.
+ if (_xOffset2042 > 0)
+ engine->_compositionBuffer.fillRect(Common::Rect(_xOffset2042, 200), 81);
+
+ // set clip window
+ _drawWin.top = 0;
+ _drawWin.left = MAX((int16)0, _xOffset2042);
+ _drawWin.right = 320;
+ _drawWin.bottom = 200;
+ clean1(_scrollCountdown2);
+ clean2(_xOffset2042);
+ draw1(_scrollCountdown2);
+ draw2(_xOffset2042);
+}
+
+static int16 _clipXOffset(int16 x1, int16 x2) {
+ if (x1 + x2 > 320)
+ x2 = 320 - x1;
+
+ if (x2 < 0)
+ x2 = 0;
+
+ return x2;
+}
+
+void HocIntro::leave() {
+ DgdsEngine *engine = DgdsEngine::getInstance();
+ HocGlobals *globals = static_cast<HocGlobals *>(engine->getGameGlobals());
+ if (!globals->getIntroState())
+ return;
+
+ //engine->getGamePals()->freePal("xx.pal");
+
+ // Store the current frame in the background
+ engine->getBackgroundBuffer().blitFrom(engine->_compositionBuffer);
+
+ _maskImg.reset();
+ _noMaskImg.reset();
+
+ globals->setIntroState(0);
+ static_cast<HocGlobals *>(engine->getGameGlobals())->setNativeGameState(0);
+}
+
+void HocIntro::doCopy(int16 x1, int16 y1, int16 x2, int16 y2) {
+ int16 xx = _xOffset203e + x1;
+ if (xx < _drawWin.left)
+ xx = _drawWin.left;
+
+ if (xx < 320) {
+ DgdsEngine *engine = DgdsEngine::getInstance();
+ Graphics::ManagedSurface &bg = engine->getBackgroundBuffer();
+ Graphics::ManagedSurface &comp = engine->_compositionBuffer;
+ int16 xx2 = _clipXOffset(xx, x2);
+ Common::Rect copyRect(Common::Point(xx, y1), xx2, y2);
+ comp.blitFrom(bg, copyRect, copyRect);
+ }
+}
+
+void HocIntro::clean1(int16 xoff) {
+ _xOffset203e = xoff;
+ doCopy(0x6c, 0x58, 0x10, 0x1a);
+ doCopy(0x87, 0x38, 0x2b, 0x11);
+ doCopy(0xa4, 0x48, 0x1b, 0x1e);
+ doCopy(0xc0, 0x40, 0xd, 4);
+}
+
+void HocIntro::clean2(int16 xoff) {
+ _xOffset203e = xoff;
+ doCopy(0, 0x14, 0x46, 0x25);
+ doCopy(0x31, 0x39, 0x2b, 0x1a);
+ doCopy(0x5b, 0x52, 0x36, 0x1f);
+ doCopy(0x7d, 0x70, 0x1b, 6);
+}
+
+void HocIntro::draw1(int16 xoff) {
+ Graphics::ManagedSurface &dst = DgdsEngine::getInstance()->_compositionBuffer;
+ _noMaskImg->drawBitmap(1, xoff + 0xcc, 0x33, _drawWin, dst);
+ _noMaskImg->drawBitmap(0, xoff + 0xf8, 0x14, _drawWin, dst);
+ _noMaskImg->drawBitmap(2, xoff, 0x7a, _drawWin, dst);
+ _maskImg->drawBitmap(1, xoff + 0xcf, 0x15, _drawWin, dst);
+ _maskImg->drawBitmap(2, xoff + 0xbc, 0x35, _drawWin, dst);
+ _maskImg->drawBitmap(3, xoff + 0xb7, 99, _drawWin, dst);
+ _maskImg->drawBitmap(4, xoff + 0x79, 0x38, _drawWin, dst);
+ _maskImg->drawBitmap(5, xoff + 0x5d, 0x58, _drawWin, dst);
+ _maskImg->drawBitmap(0, xoff + 0x19, 0x72, _drawWin, dst);
+}
+
+void HocIntro::draw2(int16 xoff) {
+ Graphics::ManagedSurface &dst = DgdsEngine::getInstance()->_compositionBuffer;
+
+ if (8 < xoff)
+ dst.fillRect(Common::Rect(Common::Point(0, 0x14), 8, 0x88), 81);
+
+ if (_drawWin.left < 9) {
+ if (_drawWin.left > 0)
+ dst.fillRect(Common::Rect(Common::Point(0, 0x14), xoff, 100), 81);
+ } else {
+ dst.fillRect(Common::Rect(Common::Point(xoff - 8, 0x14), 8, 0x68), 81);
+ _drawWin.left = 8;
+ }
+
+ dst.fillRect(Common::Rect(Common::Point(xoff, 0x31), 0x29, 0x6b), 81);
+
+ _maskImg->drawBitmap(6, xoff, 0x14, _drawWin, dst);
+ _noMaskImg->drawBitmap(3, xoff + 0x29, 0x49, _drawWin, dst);
+ _noMaskImg->drawBitmap(4, xoff + 0x43, 0x53, _drawWin, dst);
+ _noMaskImg->drawBitmap(5, xoff + 0x57, 0x6d, _drawWin, dst);
+ _maskImg->drawBitmap(7, xoff + 0x29, 0x19, _drawWin, dst);
+ _maskImg->drawBitmap(8, xoff + 0x43, 0x3c, _drawWin, dst);
+ _maskImg->drawBitmap(9, xoff + 0x57, 0x52, _drawWin, dst);
+ _maskImg->drawBitmap(10, xoff + 0x7a, 0x5c, _drawWin, dst);
+ _maskImg->drawBitmap(11, xoff + 0x90, 0x8c, _drawWin, dst);
+ _maskImg->drawBitmap(11, xoff + 0x13b, 0x8c, _drawWin, dst);
+}
+
+} // end namespace Dgds
diff --git a/engines/dgds/hoc_intro.h b/engines/dgds/hoc_intro.h
new file mode 100644
index 00000000000..0f538f0d534
--- /dev/null
+++ b/engines/dgds/hoc_intro.h
@@ -0,0 +1,60 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DGDS_HOC_INTRO_H
+#define DGDS_HOC_INTRO_H
+
+#include "common/ptr.h"
+#include "dgds/image.h"
+
+namespace Dgds {
+
+/**
+ * Native scene ops for Heart of China intro.
+ */
+class HocIntro {
+public:
+ HocIntro();
+ void init();
+ void tick();
+ void leave();
+
+private:
+ void clean1(int16 xoff);
+ void clean2(int16 xoff);
+ void draw1(int16 xoff);
+ void draw2(int16 xoff);
+
+ void doCopy(int16 x1, int16 y1, int16 x2, int16 y2);
+ void doScroll();
+
+ int16 _scrollCountdown1;
+ int16 _xOffset2042;
+ int16 _xOffset203e;
+ int16 _scrollCountdown2;
+ Common::SharedPtr<Image> _noMaskImg;
+ Common::SharedPtr<Image> _maskImg;
+ Common::Rect _drawWin;
+};
+
+} // end namespace Dgds
+
+#endif // DGDS_HOC_INTRO_H
diff --git a/engines/dgds/menu.cpp b/engines/dgds/menu.cpp
index 565594df0e2..ba75de61e20 100644
--- a/engines/dgds/menu.cpp
+++ b/engines/dgds/menu.cpp
@@ -596,7 +596,7 @@ void Menu::handleClickSkipPlayIntroMenu(const Common::Point &mouse) {
case kMenuIntroJumpToIntroduction:
hideMenu();
if (engine->getGameId() == GID_HOC)
- engine->changeScene(98);
+ engine->changeScene(100);
else if (engine->getGameId() == GID_WILLY)
engine->changeScene(24);
break;
diff --git a/engines/dgds/module.mk b/engines/dgds/module.mk
index 302680c9159..2d80da976ef 100644
--- a/engines/dgds/module.mk
+++ b/engines/dgds/module.mk
@@ -10,10 +10,12 @@ MODULE_OBJS := \
dialog.o \
dragon_arcade.o \
dragon_arcade_ttm.o \
+ dragon_native.o \
drawing.o \
font.o \
game_palettes.o \
globals.o \
+ hoc_intro.o \
image.o \
inventory.o \
menu.o \
@@ -21,12 +23,12 @@ MODULE_OBJS := \
parser.o \
request.o \
resource.o \
+ scene.o \
scripts.o \
shell_game.o \
+ sound.o \
sound_raw.o \
ttm.o \
- scene.o \
- sound.o \
sound/midiparser_sci.o \
sound/music.o \
sound/drivers/adlib.o \
diff --git a/engines/dgds/scene.cpp b/engines/dgds/scene.cpp
index bd172d507ae..ba1b52aff8e 100644
--- a/engines/dgds/scene.cpp
+++ b/engines/dgds/scene.cpp
@@ -43,6 +43,8 @@
#include "dgds/image.h"
#include "dgds/inventory.h"
#include "dgds/dragon_arcade.h"
+#include "dgds/dragon_native.h"
+#include "dgds/hoc_intro.h"
namespace Dgds {
@@ -164,9 +166,9 @@ static Common::String _sceneOpCodeName(SceneOpCode code) {
case kSceneOpOpenChinaTrainMenu: return "trainMenu";
case kSceneOpOpenChinaOpenGameOverMenu: return "gameOverMenu";
case kSceneOpOpenChinaOpenSkipCreditsMenu: return "skipCreditsMenu";
- case kSceneOpOpenChinaStartIntro: return "startIntro";
- case kSceneOpChina117: return "hocSceneOp117";
- case kSceneOpChina118: return "hocSceneOp118";
+ case kSceneOpChinaOnIntroInit: return "chinaOnIntroInit";
+ case kSceneOpChinaOnIntroTick: return "chinaOnIntroTick";
+ case kSceneOpChinaOnIntroLeave: return "chinaOnIntroLeave";
default:
break;
}
@@ -609,15 +611,6 @@ void Scene::segmentStateOps(const Common::Array<uint16> &args) {
}
}
-static void _drawDragonCountdown(FontManager::FontType fontType, int16 x, int16 y) {
- DgdsEngine *engine = DgdsEngine::getInstance();
- int16 countdownEnd = engine->getGameGlobals()->getGlobal(0x22);
- int16 currentMins = engine->getClock().getMins();
- const DgdsFont *fnt = engine->getFontMan()->getFont(fontType);
- Common::String str = Common::String::format("%d", countdownEnd - currentMins);
- fnt->drawString(&engine->_compositionBuffer, str, x, y, 320 - x, 10);
-}
-
bool Scene::runSceneOp(const SceneOp &op) {
DgdsEngine *engine = DgdsEngine::getInstance();
@@ -734,7 +727,7 @@ bool Scene::runDragonOp(const SceneOp &op) {
DgdsEngine *engine = DgdsEngine::getInstance();
switch (op._opCode) {
case kSceneOpPasscode:
- engine->getScene()->sceneOpUpdatePasscodeGlobal();
+ DragonNative::updatePasscodeGlobal();
break;
case kSceneOpMeanwhile:
// TODO: Should we draw "meanwhile" like the original? it just gets overwritten with the image anyway.
@@ -755,10 +748,10 @@ bool Scene::runDragonOp(const SceneOp &op) {
engine->getDragonArcade()->arcadeTick();
break;
case kSceneOpDrawDragonCountdown1:
- _drawDragonCountdown(FontManager::k4x5Font, 141, 56);
+ DragonNative::drawCountdown(FontManager::k4x5Font, 141, 56);
break;
case kSceneOpDrawDragonCountdown2:
- _drawDragonCountdown(FontManager::k8x8Font, 250, 42);
+ DragonNative::drawCountdown(FontManager::k8x8Font, 250, 42);
break;
case kSceneOpOpenPlaySkipIntroMenu:
engine->setMenuToTrigger(kMenuSkipPlayIntro);
@@ -793,10 +786,15 @@ bool Scene::runChinaOp(const SceneOp &op) {
case kSceneOpShellGameEnd:
engine->getShellGame()->shellGameEnd();
break;
- case kSceneOpOpenChinaStartIntro:
- // The game first jumps to scene 100, and then to 98
- engine->changeScene(98);
- return true;
+ case kSceneOpChinaOnIntroInit:
+ engine->getHocIntro()->init();
+ break;
+ case kSceneOpChinaOnIntroTick:
+ engine->getHocIntro()->tick();
+ break;
+ case kSceneOpChinaOnIntroLeave:
+ engine->getHocIntro()->leave();
+ break;
default:
warning("TODO: Implement china-specific scene opcode %d", op._opCode);
break;
@@ -1403,86 +1401,6 @@ void SDSScene::addAndShowTiredDialog() {
}
-// The first row of this array corresponds to the
-// positions of buttons in game passcode
-// RYP YWP YRPWRY PBW
-static const uint16 DRAGON_PASSCODE[] = {
- 1, 4, 3, 4, 0, 3, 4, 1, 3, 0, 1, 4, 3, 2, 0,
- 4, 4, 2, 3, 4, 0, 0, 4, 3, 2, 1, 1, 2, 4, 0,
- 4, 1, 3, 2, 0, 2, 1, 4, 3, 4, 1, 3, 2, 0, 1
-};
-
-static uint16 passcodeBlockNum = 0;
-static uint16 passcodeVal1 = 0;
-static uint16 passcodeVal2 = 0;
-static uint16 passcodeVal3 = 0;
-static uint16 passcodeVal4 = 0;
-
-void SDSScene::sceneOpUpdatePasscodeGlobal() {
- GDSScene *gdsScene = DgdsEngine::getInstance()->getGDSScene();
- int16 globalval = gdsScene->getGlobal(0x20);
-
- if (globalval > 34)
- return;
-
- if (globalval >= 30) {
- // One of the keypad buttons
- if (DRAGON_PASSCODE[passcodeVal4 + passcodeBlockNum * 15] == globalval - 30) {
- debug("sceneOpUpdatePasscodeGlobal CORRECT: variables %d %d %d %d block %d, curval %d",
- passcodeVal1, passcodeVal2, passcodeVal3, passcodeVal4, passcodeBlockNum, globalval);
-
- // Correct entry! Increment the expected button
- passcodeVal4++;
- if (passcodeVal4 < passcodeVal3) {
- globalval = 0;
- } else if (passcodeVal3 < 15) {
- globalval = 5;
- } else {
- // Finished!
- globalval = 6;
- }
- } else {
- // Mistake
- debug("sceneOpUpdatePasscodeGlobal WRONG: variables %d %d %d %d block %d, curval %d",
- passcodeVal1, passcodeVal2, passcodeVal3, passcodeVal4, passcodeBlockNum, globalval);
- passcodeVal1 = 0;
- passcodeVal2 = 5;
- globalval = 7;
- }
- } else {
- if (globalval > 4 || globalval == 0)
- return;
-
- debug("sceneOpUpdatePasscodeGlobal OTHER: variables %d %d %d %d block %d, curval %d",
- passcodeVal1, passcodeVal2, passcodeVal3, passcodeVal4, passcodeBlockNum, globalval);
-
- if (globalval < 4) {
- passcodeBlockNum = globalval - 1; // expect block globalval-1
- passcodeVal1 = 5;
- passcodeVal2 = 0;
- passcodeVal3 = 15; // 15 buttons expected
- passcodeVal4 = 0;
- return;
- } else if (passcodeVal2 > passcodeVal1) {
- passcodeVal1++;
- globalval = DRAGON_PASSCODE[passcodeVal1 + passcodeBlockNum * 15] + 20;
- } else if (passcodeVal2 > 14) {
- passcodeVal1 = 0;
- passcodeVal3 = passcodeVal2;
- passcodeVal4 = 0;
- globalval = 8;
- } else {
- passcodeVal1 = 0;
- passcodeVal2 += 5;
- passcodeVal3 = passcodeVal1;
- passcodeVal4 = 0;
- globalval = 8;
- }
- }
-
- gdsScene->setGlobal(0x20, globalval);
-}
-
void SDSScene::showDialog(uint16 fileNum, uint16 dlgNum) {
if (fileNum)
loadDialogData(fileNum);
diff --git a/engines/dgds/scene.h b/engines/dgds/scene.h
index daeffe7ce92..e7cefce500a 100644
--- a/engines/dgds/scene.h
+++ b/engines/dgds/scene.h
@@ -125,15 +125,17 @@ enum SceneOpCode {
kSceneOpOpenBetterSaveGameMenu = 108, // args: none. DRAGON: Show menu 46, the "Before arcade maybe you better save your game" menu.
// China-specific opcodes
+ kSceneOpChinaTankInit = 100,
+ kSceneOpChinaTankExit = 101,
kSceneOpOpenChinaTankMenu = 102,
kSceneOpShellGameEnd = 109,
kSceneOpShellGameTick = 110,
kSceneOpOpenChinaTrainMenu = 113,
kSceneOpOpenChinaOpenGameOverMenu = 114, // args: none.
kSceneOpOpenChinaOpenSkipCreditsMenu = 115, // args: none.
- kSceneOpOpenChinaStartIntro = 116, // args: none.
- kSceneOpChina117 = 117, // args: none. ??
- kSceneOpChina118 = 118, // args: none. ??
+ kSceneOpChinaOnIntroTick = 116, // args: none.
+ kSceneOpChinaOnIntroInit = 117, // args: none.
+ kSceneOpChinaOnIntroLeave = 118, // args: none.
// Beamish-specific opcodes
kSceneOpOpenBeamishGameOverMenu = 100,
diff --git a/engines/dgds/shell_game.h b/engines/dgds/shell_game.h
index be2285d13a0..a213dabec76 100644
--- a/engines/dgds/shell_game.h
+++ b/engines/dgds/shell_game.h
@@ -26,7 +26,7 @@
namespace Dgds {
-/* Native code for the shell game from Heart of China. */
+/** Native code for the shell game from Heart of China. */
class ShellGame {
public:
ShellGame();
diff --git a/engines/dgds/sound/drivers/midipatch.cpp b/engines/dgds/sound/drivers/midipatch.cpp
index d88693db219..8c8d89838bb 100644
--- a/engines/dgds/sound/drivers/midipatch.cpp
+++ b/engines/dgds/sound/drivers/midipatch.cpp
@@ -39,7 +39,7 @@ namespace Dgds {
static const char *PATCH_RESOURCES[] = {
"SXTITLE.OVL", // dragon
- "SXCODE1.OVL", // china (TODO: when do we load SXCODE2??)
+ "SXCODE1.OVL", // hoc (TODO: when do we load SXCODE2 - maybe when global 0x37 changes)
"SX.OVL", // newer games (beamish, sq5 demo)
};
diff --git a/engines/dgds/ttm.cpp b/engines/dgds/ttm.cpp
index 176540ea5d4..c2a756bbdaa 100644
--- a/engines/dgds/ttm.cpp
+++ b/engines/dgds/ttm.cpp
@@ -1056,7 +1056,7 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
case 0xf010: { // LOAD SCR: filename:str
if (seq._executed) // this is a one-shot op
break;
- Image tmp = Image(_vm->getResourceManager(), _vm->getDecompressor());
+ Image tmp(_vm->getResourceManager(), _vm->getDecompressor());
tmp.drawScreen(sval, _vm->getBackgroundBuffer());
_vm->_compositionBuffer.blitFrom(_vm->getBackgroundBuffer());
_vm->getStoredAreaBuffer().fillRect(Common::Rect(SCREEN_WIDTH, SCREEN_HEIGHT), 0);
Commit: ea5029209929423eaeec402added5972e7c60a2f
https://github.com/scummvm/scummvm/commit/ea5029209929423eaeec402added5972e7c60a2f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-10-27T18:25:47+11:00
Commit Message:
DGDS: JANITORIAL: Fix whitespace
Changed paths:
engines/dgds/game_palettes.cpp
engines/dgds/metaengine.cpp
engines/dgds/request.cpp
engines/dgds/ttm.cpp
diff --git a/engines/dgds/game_palettes.cpp b/engines/dgds/game_palettes.cpp
index eb64f937458..0771321040a 100644
--- a/engines/dgds/game_palettes.cpp
+++ b/engines/dgds/game_palettes.cpp
@@ -29,22 +29,22 @@
namespace Dgds {
static const byte EGA_COLORS[16][3] = {
- { 0x00, 0x00, 0x00 },
- { 0x00, 0x00, 0xAA },
- { 0x00, 0xAA, 0x00 },
- { 0x00, 0xAA, 0xAA },
- { 0xAA, 0x00, 0x00 },
- { 0xAA, 0x00, 0xAA },
- { 0xAA, 0x55, 0x00 },
- { 0xAA, 0xAA, 0xAA },
- { 0x55, 0x55, 0x55 },
- { 0x55, 0x55, 0xFF },
- { 0x55, 0xFF, 0x55 },
- { 0x55, 0xFF, 0xFF },
- { 0xFF, 0x55, 0x55 },
- { 0xFF, 0x55, 0xFF },
- { 0xFF, 0xFF, 0x55 },
- { 0xFF, 0xFF, 0xFF },
+ { 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0xAA },
+ { 0x00, 0xAA, 0x00 },
+ { 0x00, 0xAA, 0xAA },
+ { 0xAA, 0x00, 0x00 },
+ { 0xAA, 0x00, 0xAA },
+ { 0xAA, 0x55, 0x00 },
+ { 0xAA, 0xAA, 0xAA },
+ { 0x55, 0x55, 0x55 },
+ { 0x55, 0x55, 0xFF },
+ { 0x55, 0xFF, 0x55 },
+ { 0x55, 0xFF, 0xFF },
+ { 0xFF, 0x55, 0x55 },
+ { 0xFF, 0x55, 0xFF },
+ { 0xFF, 0xFF, 0x55 },
+ { 0xFF, 0xFF, 0xFF },
};
DgdsPal::DgdsPal() : Palette(256) {
diff --git a/engines/dgds/metaengine.cpp b/engines/dgds/metaengine.cpp
index 5b4436db7e3..c4a2d1dae5f 100644
--- a/engines/dgds/metaengine.cpp
+++ b/engines/dgds/metaengine.cpp
@@ -61,11 +61,11 @@ Common::Error DgdsMetaEngine::createInstance(OSystem *syst, Engine **engine, con
}
struct KeybindingRecord {
- Dgds::DgdsKeyEvent _action;
- const char *_id;
- const Common::U32String _desc;
- const char *_key;
- const char *_altKey;
+ Dgds::DgdsKeyEvent _action;
+ const char *_id;
+ const Common::U32String _desc;
+ const char *_key;
+ const char *_altKey;
};
Common::KeymapArray DgdsMetaEngine::initKeymaps(const char *target) const {
diff --git a/engines/dgds/request.cpp b/engines/dgds/request.cpp
index 3e3ac10b262..17b17a40024 100644
--- a/engines/dgds/request.cpp
+++ b/engines/dgds/request.cpp
@@ -416,8 +416,8 @@ byte ButtonGadget::drawChinaBg(Graphics::ManagedSurface *dst, bool enabled) cons
dst->drawLine(x + x2_, y + x2_, x + x2_, y2 - x2_, drawCol);
dst->drawLine(x + x2_, y2 - x2_, (x2 - x2_) + -1, y2 - x2_, drawCol);
}
- }
- return colors[7];
+ }
+ return colors[7];
}
byte ButtonGadget::drawWillyBg(Graphics::ManagedSurface *dst, bool enabled) const {
diff --git a/engines/dgds/ttm.cpp b/engines/dgds/ttm.cpp
index c2a756bbdaa..80e7831e1a4 100644
--- a/engines/dgds/ttm.cpp
+++ b/engines/dgds/ttm.cpp
@@ -513,8 +513,8 @@ int16 TTMInterpreter::doOpInitCreditScroll(const Image *img) {
y += ygap + height;
if (y > 200)
break;
- }
- return scrollFinished;
+ }
+ return scrollFinished;
}
void TTMInterpreter::doDrawDialogForStrings(TTMEnviro &env, TTMSeq &seq, int16 x, int16 y, int16 width, int16 height) {
More information about the Scummvm-git-logs
mailing list