aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob')
-rw-r--r--engines/gob/console.cpp18
-rw-r--r--engines/gob/console.h1
-rw-r--r--engines/gob/detection_tables.h4
-rw-r--r--engines/gob/draw_v1.cpp4
-rw-r--r--engines/gob/game.cpp3
-rw-r--r--engines/gob/gob.cpp2
-rw-r--r--engines/gob/init.h8
-rw-r--r--engines/gob/init_geisha.cpp47
-rw-r--r--engines/gob/init_v1.cpp4
-rw-r--r--engines/gob/init_v2.cpp4
-rw-r--r--engines/gob/inter.h12
-rw-r--r--engines/gob/inter_geisha.cpp103
-rw-r--r--engines/gob/inter_v1.cpp14
-rw-r--r--engines/gob/module.mk1
14 files changed, 217 insertions, 8 deletions
diff --git a/engines/gob/console.cpp b/engines/gob/console.cpp
index b8aed37727..e7296fb81b 100644
--- a/engines/gob/console.cpp
+++ b/engines/gob/console.cpp
@@ -29,6 +29,7 @@ namespace Gob {
GobConsole::GobConsole(GobEngine *vm) : GUI::Debugger(), _vm(vm) {
DCmd_Register("varSize", WRAP_METHOD(GobConsole, cmd_varSize));
+ DCmd_Register("dumpVars", WRAP_METHOD(GobConsole, cmd_dumpVars));
DCmd_Register("var8", WRAP_METHOD(GobConsole, cmd_var8));
DCmd_Register("var16", WRAP_METHOD(GobConsole, cmd_var16));
DCmd_Register("var32", WRAP_METHOD(GobConsole, cmd_var32));
@@ -44,6 +45,23 @@ bool GobConsole::cmd_varSize(int argc, const char **argv) {
return true;
}
+bool GobConsole::cmd_dumpVars(int argc, const char **argv) {
+ if (!_vm->_inter->_variables)
+ return true;
+
+ Common::DumpFile file;
+
+ if (!file.open("variables.dmp"))
+ return true;
+
+ file.write(_vm->_inter->_variables->getAddressOff8(0), _vm->_inter->_variables->getSize());
+
+ file.flush();
+ file.close();
+
+ return true;
+}
+
bool GobConsole::cmd_var8(int argc, const char **argv) {
if (argc == 1) {
DebugPrintf("Usage: var8 <var offset> (<value>)\n");
diff --git a/engines/gob/console.h b/engines/gob/console.h
index b9f9b81d0e..b9c3f5ed70 100644
--- a/engines/gob/console.h
+++ b/engines/gob/console.h
@@ -38,6 +38,7 @@ private:
GobEngine *_vm;
bool cmd_varSize(int argc, const char **argv);
+ bool cmd_dumpVars(int argc, const char **argv);
bool cmd_var8(int argc, const char **argv);
bool cmd_var16(int argc, const char **argv);
bool cmd_var32(int argc, const char **argv);
diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h
index 04173837da..4c1ff9a8e3 100644
--- a/engines/gob/detection_tables.h
+++ b/engines/gob/detection_tables.h
@@ -2496,7 +2496,7 @@ static const GOBGameDescription gameDescriptions[] = {
GUIO_NOSUBTITLES | GUIO_NOSPEECH
},
kGameTypeGeisha,
- kFeaturesEGA,
+ kFeaturesEGA | kFeaturesAdLib,
"disk1.stk", "intro.tot", 0
},
{
@@ -2510,7 +2510,7 @@ static const GOBGameDescription gameDescriptions[] = {
GUIO_NOSUBTITLES | GUIO_NOSPEECH
},
kGameTypeGeisha,
- kFeaturesEGA,
+ kFeaturesEGA | kFeaturesAdLib,
"disk1.stk", "intro.tot", 0
},
{
diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp
index 3873a99d5f..064c74958a 100644
--- a/engines/gob/draw_v1.cpp
+++ b/engines/gob/draw_v1.cpp
@@ -44,8 +44,8 @@ void Draw_v1::initScreen() {
_backSurface = _vm->_video->initSurfDesc(320, 200);
_frontSurface = _vm->_global->_primarySurfDesc;
- _cursorSprites = _vm->_video->initSurfDesc(32, 16, 2);
- _scummvmCursor = _vm->_video->initSurfDesc(16, 16, SCUMMVM_CURSOR);
+ _cursorSprites = _vm->_video->initSurfDesc(_cursorWidth * 2, _cursorHeight, 2);
+ _scummvmCursor = _vm->_video->initSurfDesc(_cursorWidth , _cursorHeight, SCUMMVM_CURSOR);
}
void Draw_v1::closeScreen() {
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index 926027e15d..7b43e9c4d7 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -492,9 +492,6 @@ void Game::prepareStart() {
_vm->_draw->_noInvalidated = true;
_vm->_draw->_applyPal = false;
_vm->_draw->_paletteCleared = false;
- _vm->_draw->_cursorWidth = 16;
- _vm->_draw->_cursorHeight = 16;
- _vm->_draw->_transparentCursor = 1;
for (int i = 0; i < 40; i++) {
_vm->_draw->_cursorAnimLow[i] = -1;
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index 59a96951dd..7bb7928406 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -414,7 +414,7 @@ bool GobEngine::initGameParts() {
break;
case kGameTypeGeisha:
- _init = new Init_v1(this);
+ _init = new Init_Geisha(this);
_video = new Video_v1(this);
_inter = new Inter_Geisha(this);
_mult = new Mult_v1(this);
diff --git a/engines/gob/init.h b/engines/gob/init.h
index 1cb2904099..e8c948c72e 100644
--- a/engines/gob/init.h
+++ b/engines/gob/init.h
@@ -56,6 +56,14 @@ public:
void initVideo();
};
+class Init_Geisha : public Init_v1 {
+public:
+ Init_Geisha(GobEngine *vm);
+ ~Init_Geisha();
+
+ void initVideo();
+};
+
class Init_v2 : public Init_v1 {
public:
Init_v2(GobEngine *vm);
diff --git a/engines/gob/init_geisha.cpp b/engines/gob/init_geisha.cpp
new file mode 100644
index 0000000000..01081a5af6
--- /dev/null
+++ b/engines/gob/init_geisha.cpp
@@ -0,0 +1,47 @@
+/* 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.
+ *
+ */
+
+#include "common/endian.h"
+
+#include "gob/gob.h"
+#include "gob/init.h"
+#include "gob/global.h"
+#include "gob/draw.h"
+#include "gob/video.h"
+
+namespace Gob {
+
+Init_Geisha::Init_Geisha(GobEngine *vm) : Init_v1(vm) {
+}
+
+Init_Geisha::~Init_Geisha() {
+}
+
+void Init_Geisha::initVideo() {
+ Init_v1::initVideo();
+
+ _vm->_draw->_cursorWidth = 16;
+ _vm->_draw->_cursorHeight = 23;
+ _vm->_draw->_transparentCursor = 1;
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/init_v1.cpp b/engines/gob/init_v1.cpp
index 6772a13eb0..25d521aca6 100644
--- a/engines/gob/init_v1.cpp
+++ b/engines/gob/init_v1.cpp
@@ -52,6 +52,10 @@ void Init_v1::initVideo() {
_vm->_global->_pPaletteDesc->unused2 = _vm->_global->_unusedPalette2;
_vm->_video->initSurfDesc(320, 200, PRIMARY_SURFACE);
+
+ _vm->_draw->_cursorWidth = 16;
+ _vm->_draw->_cursorHeight = 16;
+ _vm->_draw->_transparentCursor = 1;
}
} // End of namespace Gob
diff --git a/engines/gob/init_v2.cpp b/engines/gob/init_v2.cpp
index f10d586a34..1289d561ea 100644
--- a/engines/gob/init_v2.cpp
+++ b/engines/gob/init_v2.cpp
@@ -62,6 +62,10 @@ void Init_v2::initVideo() {
_vm->_global->_pPaletteDesc->unused2 = _vm->_global->_unusedPalette2;
_vm->_video->initSurfDesc(_vm->_video->_surfWidth, _vm->_video->_surfHeight, PRIMARY_SURFACE);
+
+ _vm->_draw->_cursorWidth = 16;
+ _vm->_draw->_cursorHeight = 16;
+ _vm->_draw->_transparentCursor = 1;
}
} // End of namespace Gob
diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index ecbf22610d..84180f407d 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -344,7 +344,19 @@ protected:
virtual void setupOpcodesFunc();
virtual void setupOpcodesGob();
+ void oGeisha_loadCursor(OpFuncParams &params);
+ void oGeisha_goblinFunc(OpFuncParams &params);
void oGeisha_loadSound(OpFuncParams &params);
+ void oGeisha_checkData(OpFuncParams &params);
+
+ void oGeisha_gamePenetration(OpGobParams &params);
+ void oGeisha_gameDiving(OpGobParams &params);
+ void oGeisha_loadTitleMusic(OpGobParams &params);
+ void oGeisha_playMusic(OpGobParams &params);
+ void oGeisha_stopMusic(OpGobParams &params);
+
+ void oGeisha_caress1(OpGobParams &params);
+ void oGeisha_caress2(OpGobParams &params);
int16 loadSound(int16 slot);
};
diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp
index e3f3a24a98..658f2346f4 100644
--- a/engines/gob/inter_geisha.cpp
+++ b/engines/gob/inter_geisha.cpp
@@ -26,7 +26,10 @@
#include "gob/inter.h"
#include "gob/dataio.h"
#include "gob/script.h"
+#include "gob/resources.h"
#include "gob/game.h"
+#include "gob/draw.h"
+#include "gob/video.h"
#include "gob/sound/sound.h"
#include "gob/sound/sounddesc.h"
@@ -47,16 +50,46 @@ void Inter_Geisha::setupOpcodesDraw() {
void Inter_Geisha::setupOpcodesFunc() {
Inter_v1::setupOpcodesFunc();
+ OPCODEFUNC(0x03, oGeisha_loadCursor);
+ OPCODEFUNC(0x25, oGeisha_goblinFunc);
OPCODEFUNC(0x3A, oGeisha_loadSound);
+ OPCODEFUNC(0x3F, oGeisha_checkData);
+
+ OPCODEGOB(0, oGeisha_gamePenetration);
+ OPCODEGOB(1, oGeisha_gameDiving);
+ OPCODEGOB(2, oGeisha_loadTitleMusic);
+ OPCODEGOB(3, oGeisha_playMusic);
+ OPCODEGOB(4, oGeisha_stopMusic);
+ OPCODEGOB(6, oGeisha_caress1);
+ OPCODEGOB(7, oGeisha_caress2);
}
void Inter_Geisha::setupOpcodesGob() {
}
+void Inter_Geisha::oGeisha_loadCursor(OpFuncParams &params) {
+ if (_vm->_game->_script->peekByte(1) & 0x80)
+ warning("Geisha Stub: oGeisha_loadCursor: script[1] & 0x80");
+
+ o1_loadCursor(params);
+}
+
void Inter_Geisha::oGeisha_loadSound(OpFuncParams &params) {
loadSound(-1);
}
+void Inter_Geisha::oGeisha_goblinFunc(OpFuncParams &params) {
+ OpGobParams gobParams;
+ int16 cmd;
+
+ cmd = _vm->_game->_script->readInt16();
+
+ gobParams.paramCount = _vm->_game->_script->readInt16();
+ gobParams.extraData = cmd;
+
+ executeOpcodeGob(cmd, gobParams);
+}
+
int16 Inter_Geisha::loadSound(int16 slot) {
const char *sndFile = _vm->_game->_script->evalString();
@@ -80,4 +113,74 @@ int16 Inter_Geisha::loadSound(int16 slot) {
return 0;
}
+void Inter_Geisha::oGeisha_checkData(OpFuncParams &params) {
+ const char *file = _vm->_game->_script->evalString();
+ int16 varOff = _vm->_game->_script->readVarIndex();
+
+ Common::String fileName(file);
+
+ fileName.toLowercase();
+ if (fileName.hasSuffix(".0ot"))
+ fileName.setChar('t', fileName.size() - 3);
+
+ if (!_vm->_dataIO->hasFile(fileName)) {
+ warning("File \"%s\" not found", fileName.c_str());
+ WRITE_VAR_OFFSET(varOff, (uint32) -1);
+ } else
+ WRITE_VAR_OFFSET(varOff, 50); // "handle" between 50 and 128 = in archive
+}
+
+void Inter_Geisha::oGeisha_gamePenetration(OpGobParams &params) {
+ uint16 var1 = _vm->_game->_script->readUint16();
+ uint16 var2 = _vm->_game->_script->readUint16();
+ uint16 var3 = _vm->_game->_script->readUint16();
+ uint16 var4 = _vm->_game->_script->readUint16();
+
+ WRITE_VAR_UINT32(var4, 0);
+
+ warning("Geisha Stub: Minigame \"Penetration\": %d, %d, %d, %d", var1, var2, var3, var4);
+
+ // Fudge a win for now
+ WRITE_VAR_UINT32(var4, 1);
+}
+
+void Inter_Geisha::oGeisha_gameDiving(OpGobParams &params) {
+ uint16 var1 = _vm->_game->_script->readUint16();
+ uint16 var2 = _vm->_game->_script->readUint16();
+ uint16 var3 = _vm->_game->_script->readUint16();
+
+ WRITE_VAR_UINT32(var3, 1);
+
+ warning("Geisha Stub: Minigame \"Diving\": %d, %d, %d", var1, var2, var3);
+
+ // Fudge a win for now
+ WRITE_VAR_UINT32(var3, 0);
+}
+
+void Inter_Geisha::oGeisha_loadTitleMusic(OpGobParams &params) {
+ _vm->_sound->adlibLoadTBR("geisha.tbr");
+ _vm->_sound->adlibLoadMDY("geisha.mdy");
+}
+
+void Inter_Geisha::oGeisha_playMusic(OpGobParams &params) {
+ // TODO: The MDYPlayer is still broken!
+ warning("Geisha Stub: oGeisha_playMusic");
+ // _vm->_sound->adlibPlay();
+}
+
+void Inter_Geisha::oGeisha_stopMusic(OpGobParams &params) {
+ _vm->_sound->adlibStop();
+ _vm->_sound->adlibUnload();
+}
+
+void Inter_Geisha::oGeisha_caress1(OpGobParams &params) {
+ if (_vm->_draw->_spritesArray[0])
+ _vm->_video->drawPackedSprite("hp1.cmp", *_vm->_draw->_spritesArray[0]);
+}
+
+void Inter_Geisha::oGeisha_caress2(OpGobParams &params) {
+ if (_vm->_draw->_spritesArray[1])
+ _vm->_video->drawPackedSprite("hpsc1.cmp", *_vm->_draw->_spritesArray[1]);
+}
+
} // End of namespace Gob
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 8d675d1500..0eb8be1a03 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -658,6 +658,20 @@ void Inter_v1::o1_callSub(OpFuncParams &params) {
return;
}
+ // A cheat to get around the stupid mastermind puzzle in Geisha,
+ // while we're still testing it
+ if ((_vm->getGameType() == kGameTypeGeisha) && (offset == 12934) &&
+ _vm->isCurrentTot("hard.tot") && _vm->_inter->_variables) {
+
+ uint32 digit1 = READ_VARO_UINT32(0x768);
+ uint32 digit2 = READ_VARO_UINT32(0x76C);
+ uint32 digit3 = READ_VARO_UINT32(0x770);
+ uint32 digit4 = READ_VARO_UINT32(0x774);
+ uint32 digit5 = READ_VARO_UINT32(0x778);
+
+ warning("Mastermind solution: %d %d %d %d %d", digit1, digit2, digit3, digit4, digit5);
+ }
+
// Skipping the copy protection screen in Gobliiins
if (!_vm->_copyProtection && (_vm->getGameType() == kGameTypeGob1) && (offset == 3905) &&
_vm->isCurrentTot(_vm->_startTot)) {
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 7c634dfaa1..b85c387734 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -25,6 +25,7 @@ MODULE_OBJS := \
iniconfig.o \
init.o \
init_v1.o \
+ init_geisha.o \
init_v2.o \
init_fascin.o \
init_v3.o \