Initial commit
This commit is contained in:
2
engines/got/POTFILES
Normal file
2
engines/got/POTFILES
Normal file
@@ -0,0 +1,2 @@
|
||||
engines/got/metaengine.cpp
|
||||
engines/got/got.cpp
|
||||
3
engines/got/configure.engine
Normal file
3
engines/got/configure.engine
Normal file
@@ -0,0 +1,3 @@
|
||||
# This file is included from the main "configure" script
|
||||
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
|
||||
add_engine got "Got" yes "" "" ""
|
||||
187
engines/got/console.cpp
Normal file
187
engines/got/console.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/* 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 "got/console.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/system.h"
|
||||
#include "got/events.h"
|
||||
#include "got/got.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
static const char *SAVE_FILENAMES[3] = {
|
||||
"savegam1.got", "savegam1.gt2", "savegam1.gt3"};
|
||||
|
||||
Console::Console() : GUI::Debugger() {
|
||||
registerCmd("view", WRAP_METHOD(Console, cmdView));
|
||||
registerCmd("sound", WRAP_METHOD(Console, cmdSound));
|
||||
registerCmd("music", WRAP_METHOD(Console, cmdMusic));
|
||||
registerCmd("load", WRAP_METHOD(Console, cmdLoad));
|
||||
registerCmd("save", WRAP_METHOD(Console, cmdSave));
|
||||
registerCmd("magic", WRAP_METHOD(Console, cmdMagic));
|
||||
registerCmd("freeze", WRAP_METHOD(Console, cmdFreeze));
|
||||
registerCmd("level", WRAP_METHOD(Console, cmdLevel));
|
||||
registerCmd("flying", WRAP_METHOD(Console, cmdFlying));
|
||||
registerCmd("flag", WRAP_METHOD(Console, cmdFlag));
|
||||
}
|
||||
|
||||
Console::~Console() {
|
||||
}
|
||||
|
||||
bool Console::cmdView(int argc, const char **argv) {
|
||||
if (argc != 2) {
|
||||
debugPrintf("view <view name>\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
g_events->replaceView(argv[1], true);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Console::cmdSound(int argc, const char **argv) {
|
||||
if (argc == 2)
|
||||
_G(sound).playSound(atoi(argv[1]), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Console::cmdMusic(int argc, const char **argv) {
|
||||
if (argc == 2)
|
||||
_G(sound).musicPlay(atoi(argv[1]), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Console::cmdLoad(int argc, const char **argv) {
|
||||
Common::String filename = SAVE_FILENAMES[_G(area) - 1];
|
||||
if (argc == 2)
|
||||
filename = argv[1];
|
||||
|
||||
Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename);
|
||||
if (f == nullptr) {
|
||||
debugPrintf("Could not open %s\n", filename.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
Common::Serializer s(f, nullptr);
|
||||
g_engine->syncGame(s);
|
||||
delete f;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Console::cmdSave(int argc, const char **argv) {
|
||||
Common::String filename = SAVE_FILENAMES[_G(area) - 1];
|
||||
if (argc == 2)
|
||||
filename = argv[1];
|
||||
|
||||
Common::OutSaveFile *f = g_system->getSavefileManager()->openForSaving(filename, false);
|
||||
if (f == nullptr) {
|
||||
debugPrintf("Could not create %s\n", filename.c_str());
|
||||
|
||||
} else {
|
||||
Common::Serializer s(nullptr, f);
|
||||
g_engine->syncGame(s);
|
||||
|
||||
delete f;
|
||||
|
||||
debugPrintf("Created %s\n", filename.c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Console::cmdMagic(int argc, const char **argv) {
|
||||
_G(thorInfo)._magic = (argc == 2) ? CLIP(atoi(argv[1]), 0, 150) : 150;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Console::cmdFreeze(int argc, const char **argv) {
|
||||
if (argc != 2) {
|
||||
debugPrintf("freeze ['health', 'magic', 'gems']\n");
|
||||
} else if (!strcmp(argv[1], "health")) {
|
||||
_G(cheats)._freezeHealth = !_G(cheats)._freezeHealth;
|
||||
debugPrintf("Health is %s\n", _G(cheats)._freezeHealth ? "frozen" : "unfrozen");
|
||||
} else if (!strcmp(argv[1], "magic")) {
|
||||
_G(cheats)._freezeMagic = !_G(cheats)._freezeMagic;
|
||||
debugPrintf("Magic is %s\n", _G(cheats)._freezeMagic ? "frozen" : "unfrozen");
|
||||
} else if (!strcmp(argv[1], "jewels")) {
|
||||
_G(cheats)._freezeJewels = !_G(cheats)._freezeJewels;
|
||||
debugPrintf("Jewels are %s\n", _G(cheats)._freezeJewels ? "frozen" : "unfrozen");
|
||||
} else if (!strcmp(argv[1], "all")) {
|
||||
_G(cheats)._freezeHealth = _G(cheats)._freezeMagic =
|
||||
_G(cheats)._freezeJewels = !_G(cheats)._freezeHealth;
|
||||
debugPrintf("All are %s\n", _G(cheats)._freezeHealth ? "frozen" : "unfrozen");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Console::cmdLevel(int argc, const char **argv) {
|
||||
if (argc != 2) {
|
||||
debugPrintf("Current level = %d\n", _G(currentLevel));
|
||||
return true;
|
||||
}
|
||||
|
||||
_G(newLevel) = atoi(argv[1]);
|
||||
_G(warpFlag) = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Console::cmdFlying(int argc, const char **argv) {
|
||||
_G(thor)->_flying = !_G(thor)->_flying;
|
||||
debugPrintf("Flying is %s\n", _G(thor)->_flying ? "on" : "off");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Console::cmdFlag(int argc, const char **argv) {
|
||||
if (argc == 1) {
|
||||
for (int start = 0; start < 64; start += 10) {
|
||||
Common::String line;
|
||||
for (int i = start; i < (start == 60 ? 64 : (start + 10)); ++i) {
|
||||
if ((i % 5) == 0)
|
||||
line += " ";
|
||||
line += Common::String::format("%c",
|
||||
_G(setup)._flags[i] ? 'T' : 'F');
|
||||
}
|
||||
|
||||
debugPrintf("%s\n", line.c_str());
|
||||
}
|
||||
} else {
|
||||
int flag = atoi(argv[1]);
|
||||
|
||||
if (flag < 1 || flag > 64) {
|
||||
debugPrintf("Flags must be from 1 to 64\n");
|
||||
} else if (argc == 2) {
|
||||
debugPrintf("Flag #%d is %s\n", flag,
|
||||
_G(setup)._flags[flag - 1] ? "true" : "false");
|
||||
} else {
|
||||
bool val = tolower(argv[2][0]) == 't';
|
||||
_G(setup)._flags[flag - 1] = val;
|
||||
|
||||
debugPrintf("Flag #%d is %s\n", flag,
|
||||
val ? "true" : "false");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
50
engines/got/console.h
Normal file
50
engines/got/console.h
Normal file
@@ -0,0 +1,50 @@
|
||||
|
||||
/* 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 GOT_CONSOLE_H
|
||||
#define GOT_CONSOLE_H
|
||||
|
||||
#include "gui/debugger.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
class Console : public GUI::Debugger {
|
||||
private:
|
||||
bool cmdView(int argc, const char **argv);
|
||||
bool cmdSound(int argc, const char **argv);
|
||||
bool cmdMusic(int argc, const char **argv);
|
||||
bool cmdLoad(int argc, const char **argv);
|
||||
bool cmdSave(int argc, const char **argv);
|
||||
bool cmdMagic(int argc, const char **argv);
|
||||
bool cmdFreeze(int argc, const char **argv);
|
||||
bool cmdLevel(int argc, const char **argv);
|
||||
bool cmdFlying(int argc, const char **argv);
|
||||
bool cmdFlag(int argc, const char **argv);
|
||||
|
||||
public:
|
||||
Console();
|
||||
~Console() override;
|
||||
};
|
||||
|
||||
} // End of namespace Got
|
||||
|
||||
#endif // GOT_CONSOLE_H
|
||||
5
engines/got/credits.pl
Normal file
5
engines/got/credits.pl
Normal file
@@ -0,0 +1,5 @@
|
||||
begin_section("Got");
|
||||
add_person("Paul Gilbert", "DreamMaster", "");
|
||||
add_person("Arnaud Boutonné", "Strangerke", "");
|
||||
add_person("Coen Rampen", "NMIError", "");
|
||||
end_section();
|
||||
149
engines/got/data/actor.cpp
Normal file
149
engines/got/data/actor.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
/* 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 "got/data/actor.h"
|
||||
#include "common/algorithm.h"
|
||||
#include "common/memstream.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
void Actor::loadFixed(Common::SeekableReadStream *src) {
|
||||
_moveType = src->readByte();
|
||||
_width = src->readByte();
|
||||
_height = src->readByte();
|
||||
_directions = src->readByte();
|
||||
_framesPerDirection = src->readByte();
|
||||
_frameSpeed = src->readByte();
|
||||
src->read(_frameSequence, 4);
|
||||
_speed = src->readByte();
|
||||
_sizeX = src->readByte();
|
||||
_sizeY = src->readByte();
|
||||
_hitStrength = src->readByte();
|
||||
_health = src->readByte();
|
||||
_numMoves = src->readByte();
|
||||
_shotType = src->readByte();
|
||||
_shotPattern = src->readByte();
|
||||
_numShotsAllowed = src->readByte();
|
||||
_solid = src->readByte();
|
||||
_flying = src->readByte() == 1;
|
||||
_dropRating = src->readByte();
|
||||
_type = src->readByte();
|
||||
src->read(_name, 9);
|
||||
_funcNum = src->readByte();
|
||||
_funcPass = src->readByte();
|
||||
_magicHurts = src->readSint16LE();
|
||||
src->skip(4);
|
||||
}
|
||||
|
||||
void Actor::loadFixed(const byte *src) {
|
||||
Common::MemoryReadStream stream(src, 40);
|
||||
loadFixed(&stream);
|
||||
}
|
||||
|
||||
void Actor::copyFixedAndPics(const Actor &src) {
|
||||
_moveType = src._moveType;
|
||||
_width = src._width;
|
||||
_height = src._height;
|
||||
_directions = src._directions;
|
||||
_framesPerDirection = src._framesPerDirection;
|
||||
_frameSpeed = src._frameSpeed;
|
||||
Common::copy(src._frameSequence, src._frameSequence + 4, _frameSequence);
|
||||
_speed = src._speed;
|
||||
_sizeX = src._sizeX;
|
||||
_sizeY = src._sizeY;
|
||||
_hitStrength = src._hitStrength;
|
||||
_health = src._health;
|
||||
_numMoves = src._numMoves;
|
||||
_shotType = src._shotType;
|
||||
_shotPattern = src._shotPattern;
|
||||
_numShotsAllowed = src._numShotsAllowed;
|
||||
_solid = src._solid;
|
||||
_flying = src._flying;
|
||||
_dropRating = src._dropRating;
|
||||
_type = src._type;
|
||||
Common::copy(src._name, src._name + 9, _name);
|
||||
_funcNum = src._funcNum;
|
||||
_funcPass = src._funcPass;
|
||||
_magicHurts = src._magicHurts;
|
||||
|
||||
// Copy all the surfaces for all the directions over
|
||||
for (int d = 0; d < DIRECTION_COUNT; ++d) {
|
||||
for (int f = 0; f < FRAME_COUNT; ++f)
|
||||
pic[d][f].copyFrom(src.pic[d][f]);
|
||||
}
|
||||
}
|
||||
|
||||
Actor &Actor::operator=(const Actor &src) {
|
||||
// First copy the fixed portion and the pics
|
||||
copyFixedAndPics(src);
|
||||
|
||||
// Copy temporary fields
|
||||
_frameCount = src._frameCount;
|
||||
_dir = src._dir;
|
||||
_lastDir = src._lastDir;
|
||||
_x = src._x;
|
||||
_y = src._y;
|
||||
_center = src._center;
|
||||
Common::copy(src._lastX, src._lastX + 2, _lastX);
|
||||
Common::copy(src._lastY, src._lastY + 2, _lastY);
|
||||
_active = src._active;
|
||||
_nextFrame = src._nextFrame;
|
||||
_moveCountdown = src._moveCountdown;
|
||||
_vulnerableCountdown = src._vulnerableCountdown;
|
||||
_shotCountdown = src._shotCountdown;
|
||||
_currNumShots = src._currNumShots;
|
||||
_creator = src._creator;
|
||||
_unpauseCountdown = src._unpauseCountdown;
|
||||
_actorNum = src._actorNum;
|
||||
_moveCount = src._moveCount;
|
||||
_dead = src._dead;
|
||||
_toggle = src._toggle;
|
||||
_centerX = src._centerX;
|
||||
_centerY = src._centerY;
|
||||
_show = src._show;
|
||||
_temp1 = src._temp1;
|
||||
_temp2 = src._temp2;
|
||||
_counter = src._counter;
|
||||
_moveCounter = src._moveCounter;
|
||||
_edgeCounter = src._edgeCounter;
|
||||
_temp3 = src._temp3;
|
||||
_temp4 = src._temp4;
|
||||
_temp5 = src._temp5;
|
||||
_hitThor = src._hitThor;
|
||||
_rand = src._rand;
|
||||
_initDir = src._initDir;
|
||||
_passValue = src._passValue;
|
||||
_shotActor = src._shotActor;
|
||||
_magicHit = src._magicHit;
|
||||
_temp6 = src._temp6;
|
||||
_i1 = src._i1;
|
||||
_i2 = src._i2;
|
||||
_i3 = src._i3;
|
||||
_i4 = src._i4;
|
||||
_i5 = src._i5;
|
||||
_i6 = src._i6;
|
||||
_initHealth = src._initHealth;
|
||||
_talkCounter = src._talkCounter;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
123
engines/got/data/actor.h
Normal file
123
engines/got/data/actor.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/* 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 GOT_DATA_ACTOR_H
|
||||
#define GOT_DATA_ACTOR_H
|
||||
|
||||
#include "common/stream.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
#define DIRECTION_COUNT 4
|
||||
#define FRAME_COUNT 4
|
||||
|
||||
struct Actor {
|
||||
// First part loaded from disk
|
||||
byte _moveType = 0; // Movement pattern (0=none)
|
||||
byte _width = 0; // Physical width
|
||||
byte _height = 0; // Physical height
|
||||
byte _directions = 0; // 1, 2 or 4 (1=uni-directional)
|
||||
byte _framesPerDirection = 0; // # frames per direction
|
||||
byte _frameSpeed = 0; // # cycles between frame changes
|
||||
byte _frameSequence[4] = {}; // Sequence
|
||||
byte _speed = 0; // Move every Nth cycle
|
||||
byte _sizeX = 0; // Non-physical padding on X coordinate
|
||||
byte _sizeY = 0; // Non-physical padding on Y coordinate
|
||||
byte _hitStrength = 0; // Hit strength
|
||||
byte _health = 0; //
|
||||
byte _numMoves = 0; // # of moves every <_speed> cycles
|
||||
byte _shotType = 0; // Actor # of shot
|
||||
byte _shotPattern = 0; // Func number to decide to shoot
|
||||
byte _numShotsAllowed = 0; // # shots allowed on screen
|
||||
byte _solid = 0; // 1=solid (not ghost,etc)
|
||||
bool _flying = false; //
|
||||
byte _dropRating = 0; // rnd(100) < _dropRating = jewel
|
||||
byte _type = 0; // Actor (0 = thor, 1 = hammer, 2 = enemy, 3 = shot)
|
||||
char _name[9] = {}; // Actors name
|
||||
byte _funcNum = 0; // Special function when thor touches
|
||||
byte _funcPass = 0; // Value to pass to func
|
||||
uint16 _magicHurts = 0; // Bitwise magic hurts flags
|
||||
|
||||
// The rest is dynamic //size=216
|
||||
// Direction/frame surfaces
|
||||
Graphics::ManagedSurface pic[DIRECTION_COUNT][FRAME_COUNT];
|
||||
|
||||
byte _frameCount = 0; // Count to switch frames
|
||||
byte _dir = 0; // Direction of travel
|
||||
byte _lastDir = 0; // Last direction of travel
|
||||
int _x = 0; // Actual X coordinate
|
||||
int _y = 0; // Actual Y coordinate
|
||||
int _center = 0; // Center of object
|
||||
int _lastX[2] = {}; // Last X coordinate on each page
|
||||
int _lastY[2] = {}; // Last Y coordinate on each page
|
||||
bool _active = false; // true=active, false=not active
|
||||
byte _nextFrame = 0; // Next frame to be shown
|
||||
byte _moveCountdown = 0; // Count down to movement
|
||||
byte _vulnerableCountdown = 0; // Count down to vulnerability
|
||||
byte _shotCountdown = 0; // Count down to another shot
|
||||
byte _currNumShots = 0; // # of shots currently on screen
|
||||
byte _creator = 0; // Which actor # created this actor
|
||||
byte _unpauseCountdown = 0; // Must be 0 to move
|
||||
byte _actorNum = 0;
|
||||
byte _moveCount = 0;
|
||||
byte _dead = 0;
|
||||
byte _toggle = 0;
|
||||
byte _centerX = 0;
|
||||
byte _centerY = 0;
|
||||
byte _show = 0; // Display or not (for blinking)
|
||||
byte _temp1 = 0;
|
||||
byte _temp2 = 0;
|
||||
byte _counter = 0;
|
||||
byte _moveCounter = 0;
|
||||
byte _edgeCounter = 0;
|
||||
byte _temp3 = 0;
|
||||
byte _temp4 = 0;
|
||||
byte _temp5 = 0;
|
||||
bool _hitThor = false;
|
||||
int _rand = 0;
|
||||
byte _initDir = 0;
|
||||
byte _passValue = 0;
|
||||
byte _shotActor = 0;
|
||||
byte _magicHit = 0;
|
||||
byte _temp6 = 0;
|
||||
int _i1 = 0, _i2 = 0, _i3 = 0, _i4 = 0, _i5 = 0, _i6 = 0;
|
||||
byte _initHealth = 0;
|
||||
byte _talkCounter = 0;
|
||||
|
||||
void loadFixed(Common::SeekableReadStream *src);
|
||||
void loadFixed(const byte *src);
|
||||
|
||||
/**
|
||||
* Copies the fixed portion and pics from a source actor.
|
||||
*/
|
||||
void copyFixedAndPics(const Actor &src);
|
||||
|
||||
Actor &operator=(const Actor &src);
|
||||
|
||||
int getPos() const {
|
||||
return ((_x + 7) / 16) + (((_y + 8) / 16) * 20);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
72
engines/got/data/defines.h
Normal file
72
engines/got/data/defines.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* 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 GOT_DATA_DEFINES_H
|
||||
#define GOT_DATA_DEFINES_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/serializer.h"
|
||||
#include "got/data/actor.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
struct Header {
|
||||
long _offset = 0;
|
||||
long _length = 0;
|
||||
|
||||
void load(Common::SeekableReadStream *src) {
|
||||
_offset = src->readUint32LE();
|
||||
_length = src->readUint32LE();
|
||||
}
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
// Defines
|
||||
|
||||
#define MAX_ACTORS 35
|
||||
#define MAX_ENEMIES 16
|
||||
#define STAMINA 20
|
||||
|
||||
#define GOT_Z 44
|
||||
#define GOT_B 48
|
||||
#define TMP_SIZE 5800
|
||||
|
||||
#define GAME1 (_G(area) == 1)
|
||||
#define GAME2 (_G(area) == 2)
|
||||
#define GAME3 (_G(area) == 3)
|
||||
|
||||
#define APPLE_MAGIC 1
|
||||
#define LIGHTNING_MAGIC 2
|
||||
#define BOOTS_MAGIC 4
|
||||
#define WIND_MAGIC 8
|
||||
#define SHIELD_MAGIC 16
|
||||
#define THUNDER_MAGIC 32
|
||||
|
||||
#define BOSS_LEVEL1 59
|
||||
#define BOSS_LEVEL2 60
|
||||
#define BOSS_LEVEL3 95
|
||||
#define ENDING_SCREEN 106
|
||||
|
||||
#define DEMO_LEN 3600
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
33
engines/got/data/flags.h
Normal file
33
engines/got/data/flags.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* 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 GOT_DATA_FLAGS_H
|
||||
#define GOT_DATA_FLAGS_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
#define HERMIT_HAS_DOLL _G(setup).f04
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
106
engines/got/data/highscores.cpp
Normal file
106
engines/got/data/highscores.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/* 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/file.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/system.h"
|
||||
#include "got/data/highscores.h"
|
||||
#include "got/got.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
static const char *DEFAULT_NAMES[HIGH_SCORES_PER_AREA] = {
|
||||
"Ron Davis", "Gary Sirois", "Adam Pedersen", "Jason Blochowiak",
|
||||
"Roy Davis", "Wayne Timmerman", "Dan Linton"};
|
||||
|
||||
void HighScore::sync(Common::Serializer &s) {
|
||||
s.syncAsUint16LE(_unused);
|
||||
s.syncAsUint32LE(_total);
|
||||
s.syncBytes((byte *)_name, 32);
|
||||
}
|
||||
|
||||
void HighScores::sync(Common::Serializer &s) {
|
||||
for (int area = 0; area < 3; ++area) {
|
||||
for (int num = 0; num < HIGH_SCORES_PER_AREA; ++num)
|
||||
_scores[area][num].sync(s);
|
||||
}
|
||||
}
|
||||
|
||||
void HighScores::load() {
|
||||
Common::File f;
|
||||
const Common::String scoresName = g_engine->getHighScoresSaveName();
|
||||
Common::InSaveFile *sf = g_system->getSavefileManager()->openForLoading(scoresName);
|
||||
|
||||
if (sf != nullptr) {
|
||||
// ScummVM high scores data present
|
||||
Common::Serializer s(sf, nullptr);
|
||||
sync(s);
|
||||
delete sf;
|
||||
} else if (f.open("config.got")) {
|
||||
// Otherwise fall back on original generated config.got
|
||||
f.seek(0x32);
|
||||
Common::Serializer s(&f, nullptr);
|
||||
sync(s);
|
||||
} else {
|
||||
// Generate new data
|
||||
for (int area = 0; area < 3; ++area) {
|
||||
for (int num = 0; num < HIGH_SCORES_PER_AREA; ++num)
|
||||
_scores[area][num] = HighScore(DEFAULT_NAMES[num], 10000 - (num * 1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HighScores::save() {
|
||||
Common::OutSaveFile *sf = g_system->getSavefileManager()->openForSaving(g_engine->getHighScoresSaveName());
|
||||
if (!sf)
|
||||
error("Error creating high scores save file");
|
||||
|
||||
Common::Serializer s(nullptr, sf);
|
||||
sync(s);
|
||||
sf->finalize();
|
||||
delete sf;
|
||||
}
|
||||
|
||||
void HighScores::add(const int area, const Common::String &name, const uint total) {
|
||||
// Find the index for the new score in the list
|
||||
int newIndex;
|
||||
for (newIndex = 0; newIndex < HIGH_SCORES_PER_AREA && total < _scores[area - 1][newIndex]._total; ++newIndex) {
|
||||
}
|
||||
|
||||
if (newIndex == HIGH_SCORES_PER_AREA)
|
||||
// Lower than all current scores, so ignore it
|
||||
return;
|
||||
|
||||
// Shift any lower scores to make space
|
||||
for (int i = HIGH_SCORES_PER_AREA - 1; i > newIndex; --i)
|
||||
_scores[area - 1][i] = _scores[area - 1][i - 1];
|
||||
|
||||
// Insert in new score
|
||||
HighScore &hs = _scores[area - 1][newIndex];
|
||||
Common::fill(hs._name, hs._name + 32, 0);
|
||||
Common::strcpy_s(hs._name, name.c_str());
|
||||
hs._total = total;
|
||||
|
||||
// Save the resulting table
|
||||
save();
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
57
engines/got/data/highscores.h
Normal file
57
engines/got/data/highscores.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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 GOT_DATA_HIGH_SCORE_H
|
||||
#define GOT_DATA_HIGH_SCORE_H
|
||||
|
||||
#include "common/serializer.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
#define HIGH_SCORES_PER_AREA 7
|
||||
|
||||
struct HighScore {
|
||||
uint16 _unused = 0;
|
||||
uint32 _total = 0;
|
||||
char _name[32] = {};
|
||||
|
||||
HighScore() {}
|
||||
HighScore(const char *name, uint32 total) : _total(total) {
|
||||
Common::strcpy_s(_name, name);
|
||||
}
|
||||
void sync(Common::Serializer &s);
|
||||
};
|
||||
|
||||
struct HighScores {
|
||||
private:
|
||||
void sync(Common::Serializer &s);
|
||||
|
||||
public:
|
||||
HighScore _scores[3][HIGH_SCORES_PER_AREA];
|
||||
|
||||
void load();
|
||||
void save();
|
||||
void add(int area, const Common::String &name, uint total);
|
||||
};
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
69
engines/got/data/level.cpp
Normal file
69
engines/got/data/level.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/* 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/algorithm.h"
|
||||
#include "common/memstream.h"
|
||||
#include "got/data/defines.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
void Level::sync(Common::Serializer &s) {
|
||||
for (int i = 0; i < 12; ++i)
|
||||
s.syncBytes(_iconGrid[i], 20);
|
||||
|
||||
s.syncAsByte(_backgroundColor);
|
||||
s.syncAsByte(_music);
|
||||
|
||||
s.syncBytes(_actorType, 16);
|
||||
s.syncBytes(_actorLoc, 16);
|
||||
s.syncBytes(_actorValue, 16);
|
||||
s.syncBytes(_palColors, 3);
|
||||
s.syncBytes(_actorInvis, 16);
|
||||
s.syncBytes(_extra, 13);
|
||||
s.syncBytes(_staticObject, 30);
|
||||
|
||||
for (int i = 0; i < 30; ++i)
|
||||
s.syncAsSint16LE(_staticX[i]);
|
||||
for (int i = 0; i < 30; ++i)
|
||||
s.syncAsSint16LE(_staticY[i]);
|
||||
|
||||
s.syncBytes(_newLevel, 10);
|
||||
s.syncBytes(_newLevelLocation, 10);
|
||||
|
||||
s.syncAsByte(_area);
|
||||
s.syncBytes(_actorDir, 16);
|
||||
s.syncBytes(_filler, 3);
|
||||
}
|
||||
|
||||
void Level::load(const int level) {
|
||||
Common::MemoryReadStream src(_G(sdData)[level], 512);
|
||||
Common::Serializer s(&src, nullptr);
|
||||
sync(s);
|
||||
}
|
||||
|
||||
void Level::save(const int level) {
|
||||
Common::MemoryWriteStream dest(_G(sdData)[level], 512);
|
||||
Common::Serializer s(nullptr, &dest);
|
||||
sync(s);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
67
engines/got/data/level.h
Normal file
67
engines/got/data/level.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* 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 GOT_DATA_LEVEL_H
|
||||
#define GOT_DATA_LEVEL_H
|
||||
|
||||
#include "common/serializer.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
#define OBJECTS_COUNT 30
|
||||
|
||||
struct Level {
|
||||
private:
|
||||
void sync(Common::Serializer &s);
|
||||
|
||||
public:
|
||||
byte _iconGrid[12][20] = {}; // Grid of icons
|
||||
byte _backgroundColor = 0; // Background color
|
||||
byte _music = 0; // Music
|
||||
byte _actorType[16] = {}; // Type of enemies (12 max)
|
||||
byte _actorLoc[16] = {}; // Location of enemies
|
||||
byte _actorValue[16] = {}; // Pass value
|
||||
byte _palColors[3] = {}; // Change 251,253,254 to these three
|
||||
byte _actorInvis[16] = {};
|
||||
byte _extra[13] = {};
|
||||
|
||||
byte _staticObject[OBJECTS_COUNT] = {}; // Static objects (treasure, keys,etc)
|
||||
int _staticX[OBJECTS_COUNT] = {}; // X coordinates of static objects
|
||||
int _staticY[OBJECTS_COUNT] = {}; // Y coordinates of static objects
|
||||
byte _newLevel[10] = {}; // Level jump for icon 200-204
|
||||
byte _newLevelLocation[10] = {}; // Grid location to jump in to
|
||||
byte _area = 0; // Game area (1=forest,etc)
|
||||
byte _actorDir[16] = {}; // Initial _dir
|
||||
byte _filler[3] = {};
|
||||
/**
|
||||
* Loads level data from the global sd_data for the given level
|
||||
*/
|
||||
void load(int level);
|
||||
|
||||
/**
|
||||
* Saves the level data to the global sd_data
|
||||
*/
|
||||
void save(int level);
|
||||
};
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
51
engines/got/data/sd_data.cpp
Normal file
51
engines/got/data/sd_data.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 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 "got/data/sd_data.h"
|
||||
#include "got/utils/file.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
#define SD_DATA_SIZE 61440
|
||||
|
||||
SdData::SdData() {
|
||||
_data = new byte[SD_DATA_SIZE];
|
||||
}
|
||||
|
||||
SdData::~SdData() {
|
||||
delete[] _data;
|
||||
}
|
||||
|
||||
void SdData::load() {
|
||||
const Common::String fname = Common::String::format("SDAT%d", _area);
|
||||
resourceRead(fname, _data);
|
||||
}
|
||||
|
||||
void SdData::setArea(int area) {
|
||||
_area = area;
|
||||
load();
|
||||
}
|
||||
|
||||
void SdData::sync(Common::Serializer &s) {
|
||||
s.syncBytes(_data, SD_DATA_SIZE);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
53
engines/got/data/sd_data.h
Normal file
53
engines/got/data/sd_data.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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 GOT_DATA_SD_DATA_H
|
||||
#define GOT_DATA_SD_DATA_H
|
||||
|
||||
#include "common/serializer.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
class SdData {
|
||||
private:
|
||||
byte *_data;
|
||||
int _area = 1;
|
||||
|
||||
public:
|
||||
SdData();
|
||||
~SdData();
|
||||
void load();
|
||||
|
||||
bool getArea() const {
|
||||
return _area;
|
||||
}
|
||||
void setArea(int area);
|
||||
|
||||
void sync(Common::Serializer &s);
|
||||
|
||||
byte *operator[](int level) const {
|
||||
return _data + level * 512;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
68
engines/got/data/setup.cpp
Normal file
68
engines/got/data/setup.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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 "got/data/setup.h"
|
||||
#include "common/algorithm.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
SetupFlags &SetupFlags::operator=(const Got::SetupFlags &src) {
|
||||
Common::copy(src._flags, src._flags + 64, _flags);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SetupFlags::sync(Common::Serializer &s) {
|
||||
byte flags[8] = {};
|
||||
|
||||
if (s.isSaving()) {
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
if (_flags[i])
|
||||
flags[i / 8] = flags[i / 8] | (1 << (i % 8));
|
||||
}
|
||||
s.syncBytes(flags, 8);
|
||||
} else {
|
||||
s.syncBytes(flags, 8);
|
||||
for (int i = 0; i < 64; ++i)
|
||||
_flags[i] = (flags[i / 8] & (1 << (i % 8))) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Setup::sync(Common::Serializer &s) {
|
||||
// Sync the flags bit-fields
|
||||
SetupFlags::sync(s);
|
||||
|
||||
s.syncBytes(_value, 16);
|
||||
s.syncAsByte(_filler1);
|
||||
s.syncAsByte(_game);
|
||||
s.syncAsByte(_areaNum);
|
||||
s.syncAsByte(_speakerSound);
|
||||
s.syncAsByte(_digitalSound);
|
||||
s.syncAsByte(_musicEnabled);
|
||||
s.syncAsByte(_slowMode);
|
||||
s.syncAsByte(_scrollFlag);
|
||||
for (int i = 0; i < 3 ; ++i)
|
||||
s.syncAsByte(_bossDead[i]);
|
||||
s.syncAsByte(_difficultyLevel);
|
||||
s.syncAsByte(_gameOver);
|
||||
s.syncBytes(_filler2, 19);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
122
engines/got/data/setup.h
Normal file
122
engines/got/data/setup.h
Normal file
@@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GOT_DATA_SETUP_H
|
||||
#define GOT_DATA_SETUP_H
|
||||
|
||||
#include "common/serializer.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
struct SetupFlags {
|
||||
bool _flags[64] = {};
|
||||
bool &f01 = _flags[0];
|
||||
bool &f02 = _flags[1];
|
||||
bool &f03 = _flags[2];
|
||||
bool &f04 = _flags[3];
|
||||
bool &f05 = _flags[4];
|
||||
bool &f06 = _flags[5];
|
||||
bool &f07 = _flags[6];
|
||||
bool &f08 = _flags[7];
|
||||
bool &f09 = _flags[8];
|
||||
bool &f10 = _flags[9];
|
||||
bool &f11 = _flags[10];
|
||||
bool &f12 = _flags[11];
|
||||
bool &f13 = _flags[12];
|
||||
bool &f14 = _flags[13];
|
||||
bool &f15 = _flags[14];
|
||||
bool &f16 = _flags[15];
|
||||
bool &f17 = _flags[16];
|
||||
bool &f18 = _flags[17];
|
||||
bool &f19 = _flags[18];
|
||||
bool &f20 = _flags[19];
|
||||
bool &f21 = _flags[20];
|
||||
bool &f22 = _flags[21];
|
||||
bool &f23 = _flags[22];
|
||||
bool &f24 = _flags[23];
|
||||
bool &f25 = _flags[24];
|
||||
bool &f26 = _flags[25];
|
||||
bool &f27 = _flags[26];
|
||||
bool &f28 = _flags[27];
|
||||
bool &f29 = _flags[28];
|
||||
bool &f30 = _flags[29];
|
||||
bool &f31 = _flags[30];
|
||||
bool &f32 = _flags[31];
|
||||
bool &f33 = _flags[32];
|
||||
bool &f34 = _flags[33];
|
||||
bool &f35 = _flags[34];
|
||||
bool &f36 = _flags[35];
|
||||
bool &f37 = _flags[36];
|
||||
bool &f38 = _flags[37];
|
||||
bool &f39 = _flags[38];
|
||||
bool &f40 = _flags[39];
|
||||
bool &f41 = _flags[40];
|
||||
bool &f42 = _flags[41];
|
||||
bool &f43 = _flags[42];
|
||||
bool &f44 = _flags[43];
|
||||
bool &f45 = _flags[44];
|
||||
bool &f46 = _flags[45];
|
||||
bool &f47 = _flags[46];
|
||||
bool &f48 = _flags[47];
|
||||
bool &f49 = _flags[48];
|
||||
bool &f50 = _flags[49];
|
||||
bool &f51 = _flags[50];
|
||||
bool &f52 = _flags[51];
|
||||
bool &f53 = _flags[52];
|
||||
bool &f54 = _flags[53];
|
||||
bool &f55 = _flags[54];
|
||||
bool &f56 = _flags[55];
|
||||
bool &f57 = _flags[56];
|
||||
bool &f58 = _flags[57];
|
||||
bool &f59 = _flags[58];
|
||||
bool &f60 = _flags[59];
|
||||
bool &f61 = _flags[60];
|
||||
bool &f62 = _flags[61];
|
||||
bool &f63 = _flags[62];
|
||||
bool &f64 = _flags[63];
|
||||
|
||||
SetupFlags() {}
|
||||
virtual ~SetupFlags() {}
|
||||
virtual void sync(Common::Serializer &s);
|
||||
SetupFlags &operator=(const Got::SetupFlags &src);
|
||||
};
|
||||
|
||||
struct Setup : public SetupFlags {
|
||||
byte _value[16] = {};
|
||||
byte _filler1 = 0;
|
||||
byte _game = 0; // Unused
|
||||
byte _areaNum = 0; // 1,2,3
|
||||
bool _speakerSound = false; // always disabled
|
||||
bool _digitalSound = false; // true = enabled
|
||||
bool _musicEnabled = false; // true = enabled
|
||||
bool _slowMode = false; // true = slow mode (for slower 286's)
|
||||
bool _scrollFlag = false; // true = scroll when changing from a room to the other
|
||||
bool _bossDead[3] = {false, false, false};
|
||||
byte _difficultyLevel = 0; // 0=easy, 1=normal, 2=hard
|
||||
byte _gameOver = 0;
|
||||
byte _filler2[19] = {};
|
||||
|
||||
void sync(Common::Serializer &s) override;
|
||||
};
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
102
engines/got/data/thorinfo.cpp
Normal file
102
engines/got/data/thorinfo.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/* 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
|
||||
* as.syncAsUint32LE(with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/algorithm.h"
|
||||
#include "got/data/thorinfo.h"
|
||||
#include "got/game/back.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
void ThorInfo::clear() {
|
||||
_magic = 0;
|
||||
_keys = 0;
|
||||
_jewels = 0;
|
||||
_lastArea = 0;
|
||||
_lastScreen = 0;
|
||||
_lastIcon = 0;
|
||||
_lastDir = 0;
|
||||
_inventory = 0;
|
||||
_selectedItem = 0;
|
||||
_lastHealth = 0;
|
||||
_lastMagic = 0;
|
||||
_lastJewels = 0;
|
||||
_lastKeys = 0;
|
||||
_lastItem = 0;
|
||||
_lastInventory = 0;
|
||||
_level = 0;
|
||||
_score = 0;
|
||||
_lastScore = 0;
|
||||
_object = 0;
|
||||
_objectName = nullptr;
|
||||
_lastObject = 0;
|
||||
_lastObjectName = nullptr;
|
||||
_armor = 0;
|
||||
#ifdef USE_TTS
|
||||
_previousJewels = -1;
|
||||
_previousScore = -1;
|
||||
_previousKeys = -1;
|
||||
#endif
|
||||
Common::fill(_filler, _filler + 65, 0);
|
||||
}
|
||||
|
||||
void ThorInfo::sync(Common::Serializer &s) {
|
||||
uint32 ptr = 0;
|
||||
|
||||
s.syncAsByte(_magic);
|
||||
s.syncAsByte(_keys);
|
||||
s.syncAsSint16LE(_jewels);
|
||||
s.syncAsByte(_lastArea);
|
||||
s.syncAsByte(_lastScreen);
|
||||
s.syncAsByte(_lastIcon);
|
||||
s.syncAsByte(_lastDir);
|
||||
s.syncAsSint16LE(_inventory);
|
||||
s.syncAsByte(_selectedItem);
|
||||
s.syncAsByte(_lastHealth);
|
||||
s.syncAsByte(_lastMagic);
|
||||
s.syncAsSint16LE(_lastJewels);
|
||||
s.syncAsByte(_lastKeys);
|
||||
s.syncAsByte(_lastItem);
|
||||
s.syncAsSint16LE(_lastInventory);
|
||||
s.syncAsByte(_level);
|
||||
s.syncAsUint32LE(_score);
|
||||
s.syncAsUint32LE(_lastScore);
|
||||
|
||||
s.syncAsByte(_object);
|
||||
s.syncAsUint16LE(ptr);
|
||||
s.syncAsByte(_lastObject);
|
||||
s.syncAsUint16LE(ptr);
|
||||
|
||||
s.syncAsByte(_armor);
|
||||
s.syncBytes(_filler, 65);
|
||||
|
||||
if (s.isLoading()) {
|
||||
_objectName = (_object == 0) ? nullptr : OBJECT_NAMES[_object - 1];
|
||||
_lastObjectName = (_lastObject == 0) ? nullptr : OBJECT_NAMES[_lastObject - 1];
|
||||
|
||||
#ifdef USE_TTS
|
||||
_previousJewels = -1;
|
||||
_previousScore = -1;
|
||||
_previousKeys = -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
66
engines/got/data/thorinfo.h
Normal file
66
engines/got/data/thorinfo.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* 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 GOT_DATA_THORINFO_H
|
||||
#define GOT_DATA_THORINFO_H
|
||||
|
||||
#include "common/serializer.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
struct ThorInfo {
|
||||
byte _magic = 0;
|
||||
byte _keys = 0;
|
||||
int _jewels = 0;
|
||||
byte _lastArea = 0;
|
||||
byte _lastScreen = 0;
|
||||
byte _lastIcon = 0;
|
||||
byte _lastDir = 0;
|
||||
int _inventory = 0;
|
||||
byte _selectedItem = 0; //currently selected item
|
||||
byte _lastHealth = 0;
|
||||
byte _lastMagic = 0;
|
||||
int _lastJewels = 0;
|
||||
byte _lastKeys = 0;
|
||||
byte _lastItem = 0;
|
||||
int _lastInventory = 0;
|
||||
byte _level = 0; //current level (1,2,3)
|
||||
long _score = 0;
|
||||
long _lastScore = 0;
|
||||
byte _object = 0;
|
||||
const char *_objectName = nullptr;
|
||||
byte _lastObject = 0;
|
||||
const char *_lastObjectName = nullptr;
|
||||
byte _armor = 0;
|
||||
byte _filler[65] = {};
|
||||
#ifdef USE_TTS
|
||||
int _previousJewels = -1;
|
||||
int _previousScore = -1;
|
||||
int _previousKeys = -1;
|
||||
#endif
|
||||
|
||||
void clear();
|
||||
void sync(Common::Serializer &s);
|
||||
};
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
44
engines/got/detection.cpp
Normal file
44
engines/got/detection.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
/* 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 "base/plugins.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/file.h"
|
||||
#include "common/md5.h"
|
||||
#include "common/str-array.h"
|
||||
#include "common/util.h"
|
||||
#include "got/detection.h"
|
||||
#include "got/detection_tables.h"
|
||||
|
||||
const DebugChannelDef GotMetaEngineDetection::debugFlagList[] = {
|
||||
{ Got::kDebugGraphics, "Graphics", "Graphics debug level" },
|
||||
{ Got::kDebugPath, "Path", "Pathfinding debug level" },
|
||||
{ Got::kDebugFilePath, "FilePath", "File path debug level" },
|
||||
{ Got::kDebugScan, "Scan", "Scan for unrecognised games" },
|
||||
{ Got::kDebugScript, "Script", "Enable debug script dump" },
|
||||
DEBUG_CHANNEL_END
|
||||
};
|
||||
|
||||
GotMetaEngineDetection::GotMetaEngineDetection() : AdvancedMetaEngineDetection(
|
||||
Got::gameDescriptions, Got::gotGames) {
|
||||
}
|
||||
|
||||
REGISTER_PLUGIN_STATIC(GOT_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, GotMetaEngineDetection);
|
||||
70
engines/got/detection.h
Normal file
70
engines/got/detection.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* 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 GOT_DETECTION_H
|
||||
#define GOT_DETECTION_H
|
||||
|
||||
#include "engines/advancedDetector.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
enum GotDebugChannels {
|
||||
kDebugGraphics = 1,
|
||||
kDebugPath,
|
||||
kDebugScan,
|
||||
kDebugFilePath,
|
||||
kDebugScript,
|
||||
};
|
||||
|
||||
extern const PlainGameDescriptor gotGames[];
|
||||
|
||||
extern const ADGameDescription gameDescriptions[];
|
||||
|
||||
#define GAMEOPTION_ORIGINAL_SAVELOAD GUIO_GAMEOPTIONS1
|
||||
#define GAMEOPTION_TTS GUIO_GAMEOPTIONS2
|
||||
|
||||
} // End of namespace Got
|
||||
|
||||
class GotMetaEngineDetection : public AdvancedMetaEngineDetection<ADGameDescription> {
|
||||
static const DebugChannelDef debugFlagList[];
|
||||
|
||||
public:
|
||||
GotMetaEngineDetection();
|
||||
~GotMetaEngineDetection() override {}
|
||||
|
||||
const char *getName() const override {
|
||||
return "got";
|
||||
}
|
||||
|
||||
const char *getEngineName() const override {
|
||||
return "Got";
|
||||
}
|
||||
|
||||
const char *getOriginalCopyright() const override {
|
||||
return "Got (C) 1993-1994 Ron Davis";
|
||||
}
|
||||
|
||||
const DebugChannelDef *getDebugChannels() const override {
|
||||
return debugFlagList;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // GOT_DETECTION_H
|
||||
69
engines/got/detection_tables.h
Normal file
69
engines/got/detection_tables.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Got {
|
||||
|
||||
const PlainGameDescriptor gotGames[] = {
|
||||
{"got", "God of Thunder"},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
const ADGameDescription gameDescriptions[] = {
|
||||
{
|
||||
"got",
|
||||
"v1.0:143",
|
||||
AD_ENTRY1s("gotres.dat", "0fe859bcfd06772be0885bf510c2877d", 739732),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformDOS,
|
||||
ADGF_NO_FLAGS,
|
||||
GUIO2(GUIO_NOSPEECH, GAMEOPTION_TTS)
|
||||
},
|
||||
{
|
||||
"got",
|
||||
"v1.0:143 Shareware",
|
||||
AD_ENTRY1s("gotres.dat", "c316221a3b9d12a838faef55fde2f34c", 482738),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformDOS,
|
||||
ADGF_DEMO,
|
||||
GUIO2(GUIO_NOSPEECH, GAMEOPTION_TTS)
|
||||
},
|
||||
{
|
||||
"got",
|
||||
"v1.1:144",
|
||||
AD_ENTRY1s("gotres.dat", "747ed508ffa3808156a4eb080e9859f8", 739710),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformDOS,
|
||||
ADGF_NO_FLAGS,
|
||||
GUIO2(GUIO_NOSPEECH, GAMEOPTION_TTS)
|
||||
},
|
||||
{
|
||||
"got",
|
||||
"v1.1:144 Shareware",
|
||||
AD_ENTRY1s("gotres.dat", "c443aa09450566ee32998c3ebb15cbaa", 485858),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformDOS,
|
||||
ADGF_DEMO,
|
||||
GUIO2(GUIO_NOSPEECH, GAMEOPTION_TTS)
|
||||
},
|
||||
|
||||
AD_TABLE_END_MARKER};
|
||||
|
||||
} // End of namespace Got
|
||||
503
engines/got/events.cpp
Normal file
503
engines/got/events.cpp
Normal file
@@ -0,0 +1,503 @@
|
||||
/* 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 "got/events.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "got/gfx/palette.h"
|
||||
#include "got/got.h"
|
||||
#include "got/views/views.h"
|
||||
#include "graphics/screen.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
Events *g_events;
|
||||
|
||||
// Index and RGB63 values used for palette animation
|
||||
// like water effects and gems sparkling
|
||||
static const uint16 PAL_CLR1[] = {0xf300, 0x003b, 0xf000, 0x003b, 0xf100, 0x003b, 0xf200, 0x003b};
|
||||
static const uint16 PAL_SET1[] = {0xf027, 0x273f, 0xf127, 0x273f, 0xf227, 0x273f, 0xf327, 0x273f};
|
||||
static const uint16 PAL_CLR2[] = {0xf73b, 0x0000, 0xf43b, 0x0000, 0xf53b, 0x0000, 0xf63b, 0x0000};
|
||||
static const uint16 PAL_SET2[] = {0xf43f, 0x2727, 0xf53f, 0x2727, 0xf63f, 0x2727, 0xf73f, 0x2727};
|
||||
|
||||
Events::Events() : UIElement("Root", nullptr) {
|
||||
g_events = this;
|
||||
}
|
||||
|
||||
Events::~Events() {
|
||||
g_events = nullptr;
|
||||
}
|
||||
|
||||
void Events::runGame() {
|
||||
uint nextFrameTime = 0;
|
||||
int palCycleCtr = 0;
|
||||
_screen = new Graphics::Screen();
|
||||
Views::Views views; // Loads all views in the structure
|
||||
|
||||
// Set up the initial game view
|
||||
int saveSlot = ConfMan.getInt("save_slot");
|
||||
if (saveSlot != -1) {
|
||||
if (g_engine->loadGameState(saveSlot).getCode() != Common::kNoError)
|
||||
saveSlot = -1;
|
||||
}
|
||||
if (saveSlot == -1)
|
||||
addView("SplashScreen");
|
||||
|
||||
// Main game loop
|
||||
Common::Event e;
|
||||
while (!_views.empty() && !shouldQuit()) {
|
||||
while (g_system->getEventManager()->pollEvent(e)) {
|
||||
if (e.type == Common::EVENT_QUIT ||
|
||||
e.type == Common::EVENT_RETURN_TO_LAUNCHER) {
|
||||
_views.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
processEvent(e);
|
||||
}
|
||||
|
||||
if (_views.empty())
|
||||
break;
|
||||
|
||||
g_system->delayMillis(10);
|
||||
|
||||
// Rotate the palette
|
||||
if (++palCycleCtr == 2) {
|
||||
palCycleCtr = 0;
|
||||
|
||||
bool gameVisible = false;
|
||||
for (uint i = 0; i < _views.size() && !gameVisible; ++i)
|
||||
gameVisible = _views[i]->_name == "Game";
|
||||
|
||||
if (gameVisible)
|
||||
rotatePalette();
|
||||
}
|
||||
uint currTime = g_system->getMillis();
|
||||
if (currTime >= nextFrameTime) {
|
||||
nextFrameTime = currTime + FRAME_DELAY;
|
||||
nextFrame();
|
||||
}
|
||||
}
|
||||
|
||||
delete _screen;
|
||||
}
|
||||
|
||||
void Events::nextFrame() {
|
||||
// Update state variables
|
||||
_G(rand1) = getRandomNumber(99);
|
||||
_G(rand2) = getRandomNumber(99);
|
||||
_G(pge) = _G(pge) ^ 1;
|
||||
_G(shotOk) = true;
|
||||
_G(magicCounter++);
|
||||
|
||||
// In demo mode, handle the next key
|
||||
if (_G(demo) && focusedView()->getName() == "Game") {
|
||||
if (_G(demoKeys).empty()) {
|
||||
_G(demo) = false;
|
||||
send("TitleBackground", GameMessage("MAIN_MENU"));
|
||||
return;
|
||||
}
|
||||
|
||||
processDemoEvent(_G(demoKeys).pop());
|
||||
}
|
||||
|
||||
// Check if any script needs resuming
|
||||
_G(scripts).runIfResuming();
|
||||
|
||||
// Do tick action to the views to handle gameplay logic
|
||||
tick();
|
||||
|
||||
// Draw the current view's elements as needed, and update screen
|
||||
drawElements();
|
||||
_screen->update();
|
||||
}
|
||||
|
||||
#define LOOP_THRESHOLD 5
|
||||
|
||||
void Events::rotatePalette() {
|
||||
++_palLoop;
|
||||
|
||||
if (_palLoop > LOOP_THRESHOLD) {
|
||||
_palLoop = 0;
|
||||
} else {
|
||||
const uint16 *entry;
|
||||
switch (_palLoop) {
|
||||
case LOOP_THRESHOLD - 4:
|
||||
entry = &PAL_CLR2[_palCnt2];
|
||||
break;
|
||||
case LOOP_THRESHOLD - 3:
|
||||
entry = &PAL_SET2[_palCnt2];
|
||||
|
||||
_palCnt2 += 2;
|
||||
if (_palCnt2 >= 8)
|
||||
_palCnt2 = 0;
|
||||
break;
|
||||
case LOOP_THRESHOLD - 2:
|
||||
entry = &PAL_CLR1[_palCnt1];
|
||||
break;
|
||||
case LOOP_THRESHOLD - 1:
|
||||
entry = &PAL_SET1[_palCnt1];
|
||||
|
||||
_palCnt1 += 2;
|
||||
if (_palCnt1 >= 8)
|
||||
_palCnt1 = 0;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
Gfx::xSetPal(entry[0] >> 8, (entry[0] & 0xff) << 2,
|
||||
(entry[1] >> 8) << 2, (entry[1] & 0xff) << 2);
|
||||
}
|
||||
}
|
||||
|
||||
void Events::processEvent(Common::Event &ev) {
|
||||
switch (ev.type) {
|
||||
case Common::EVENT_KEYDOWN:
|
||||
if (!_G(demo)) {
|
||||
if (ev.kbd.keycode < 100)
|
||||
_G(keyFlag[ev.kbd.keycode]) = true;
|
||||
|
||||
if (ev.kbd.keycode < Common::KEYCODE_NUMLOCK)
|
||||
msgKeypress(KeypressMessage(ev.kbd));
|
||||
}
|
||||
break;
|
||||
case Common::EVENT_KEYUP:
|
||||
if (!_G(demo) && ev.kbd.keycode < 100)
|
||||
_G(keyFlag[ev.kbd.keycode]) = false;
|
||||
break;
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
|
||||
if (!_G(demo)) {
|
||||
_G(keyFlag[actionToKeyFlag(ev.customType)]) = true;
|
||||
msgAction(ActionMessage(ev.customType));
|
||||
} else if (ev.customType == KEYBIND_ESCAPE) {
|
||||
// The Escape action will return to main menu from demo
|
||||
_G(demo) = false;
|
||||
send("TitleBackground", GameMessage("MAIN_MENU"));
|
||||
}
|
||||
break;
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
|
||||
if (!_G(demo))
|
||||
_G(keyFlag[actionToKeyFlag(ev.customType)]) = false;
|
||||
break;
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
case Common::EVENT_RBUTTONDOWN:
|
||||
case Common::EVENT_MBUTTONDOWN:
|
||||
if (!_G(demo))
|
||||
msgMouseDown(MouseDownMessage(ev.type, ev.mouse));
|
||||
break;
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
case Common::EVENT_RBUTTONUP:
|
||||
case Common::EVENT_MBUTTONUP:
|
||||
if (!_G(demo))
|
||||
msgMouseUp(MouseUpMessage(ev.type, ev.mouse));
|
||||
break;
|
||||
case Common::EVENT_MOUSEMOVE:
|
||||
if (!_G(demo))
|
||||
msgMouseMove(MouseMoveMessage(ev.type, ev.mouse));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Events::processDemoEvent(byte ev) {
|
||||
if (!ev)
|
||||
return;
|
||||
|
||||
bool flag = ev & 0x80;
|
||||
ev &= 0x7f;
|
||||
|
||||
int action = -1;
|
||||
switch (ev) {
|
||||
case 72:
|
||||
ev = key_up;
|
||||
action = KEYBIND_UP;
|
||||
break;
|
||||
case 80:
|
||||
ev = key_down;
|
||||
break;
|
||||
case 75:
|
||||
ev = key_left;
|
||||
break;
|
||||
case 77:
|
||||
ev = key_right;
|
||||
break;
|
||||
case 56:
|
||||
ev = key_fire;
|
||||
action = KEYBIND_FIRE;
|
||||
break;
|
||||
case 29:
|
||||
ev = key_magic;
|
||||
action = KEYBIND_MAGIC;
|
||||
break;
|
||||
case 39:
|
||||
ev = key_select;
|
||||
action = KEYBIND_SELECT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_G(keyFlag[ev]) = flag;
|
||||
|
||||
if (flag && action != -1)
|
||||
msgAction(ActionMessage(action));
|
||||
}
|
||||
|
||||
int Events::actionToKeyFlag(int action) const {
|
||||
return (action == KEYBIND_ESCAPE) ? Common::KEYCODE_ESCAPE : (int)action;
|
||||
}
|
||||
|
||||
void Events::replaceView(UIElement *ui, bool replaceAllViews, bool fadeOutIn) {
|
||||
assert(ui);
|
||||
UIElement *oldView = focusedView();
|
||||
|
||||
if (fadeOutIn)
|
||||
Gfx::fadeOut();
|
||||
|
||||
if (replaceAllViews) {
|
||||
clearViews();
|
||||
|
||||
} else if (!_views.empty()) {
|
||||
oldView->msgUnfocus(UnfocusMessage());
|
||||
_views.pop();
|
||||
}
|
||||
|
||||
// Redraw any prior views to erase the removed view
|
||||
for (uint i = 0; i < _views.size(); ++i) {
|
||||
_views[i]->redraw();
|
||||
_views[i]->draw();
|
||||
}
|
||||
|
||||
// Add the new view
|
||||
_views.push(ui);
|
||||
|
||||
ui->redraw();
|
||||
ui->msgFocus(FocusMessage(oldView));
|
||||
ui->draw();
|
||||
|
||||
if (fadeOutIn)
|
||||
Gfx::fadeIn();
|
||||
}
|
||||
|
||||
void Events::replaceView(const Common::String &name, bool replaceAllViews, bool fadeOutIn) {
|
||||
replaceView(findView(name), replaceAllViews, fadeOutIn);
|
||||
}
|
||||
|
||||
void Events::addView(UIElement *ui) {
|
||||
assert(ui);
|
||||
UIElement *oldView = focusedView();
|
||||
|
||||
if (!_views.empty())
|
||||
oldView->msgUnfocus(UnfocusMessage());
|
||||
|
||||
_views.push(ui);
|
||||
ui->redraw();
|
||||
ui->msgFocus(FocusMessage(oldView));
|
||||
}
|
||||
|
||||
void Events::addView(const Common::String &name) {
|
||||
addView(findView(name));
|
||||
}
|
||||
|
||||
void Events::popView() {
|
||||
UIElement *oldView = focusedView();
|
||||
oldView->msgUnfocus(UnfocusMessage());
|
||||
_views.pop();
|
||||
|
||||
for (uint i = 0; i < _views.size(); ++i) {
|
||||
_views[i]->redraw();
|
||||
_views[i]->draw();
|
||||
}
|
||||
|
||||
if (!_views.empty()) {
|
||||
UIElement *view = focusedView();
|
||||
view->msgFocus(FocusMessage(oldView));
|
||||
view->redraw();
|
||||
view->draw();
|
||||
}
|
||||
}
|
||||
|
||||
bool Events::isPresent(const Common::String &name) const {
|
||||
for (uint i = 0; i < _views.size(); ++i) {
|
||||
if (_views[i]->_name == name)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Events::drawElements() {
|
||||
if (!_views.empty())
|
||||
focusedView()->drawElements();
|
||||
}
|
||||
|
||||
void Events::clearViews() {
|
||||
if (!_views.empty())
|
||||
focusedView()->msgUnfocus(UnfocusMessage());
|
||||
|
||||
_views.clear();
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
Bounds::Bounds(Common::Rect &innerBounds) : _bounds(0, 0, 320, 240),
|
||||
_innerBounds(innerBounds),
|
||||
left(_bounds.left), top(_bounds.top),
|
||||
right(_bounds.right), bottom(_bounds.bottom) {
|
||||
}
|
||||
|
||||
Bounds &Bounds::operator=(const Common::Rect &r) {
|
||||
_bounds = r;
|
||||
_innerBounds = r;
|
||||
_innerBounds.grow(-_borderSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Bounds::setBorderSize(size_t borderSize) {
|
||||
_borderSize = borderSize;
|
||||
_innerBounds = *this;
|
||||
_innerBounds.grow(-_borderSize);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
UIElement::UIElement(const Common::String &name) : _name(name), _parent(g_engine), _bounds(_innerBounds) {
|
||||
g_engine->_children.push_back(this);
|
||||
}
|
||||
|
||||
UIElement::UIElement(const Common::String &name, UIElement *uiParent) : _name(name), _parent(uiParent), _bounds(_innerBounds) {
|
||||
if (_parent)
|
||||
_parent->_children.push_back(this);
|
||||
}
|
||||
|
||||
void UIElement::redraw() {
|
||||
_needsRedraw = true;
|
||||
|
||||
for (size_t i = 0; i < _children.size(); ++i)
|
||||
_children[i]->redraw();
|
||||
}
|
||||
|
||||
void UIElement::drawElements() {
|
||||
if (_needsRedraw) {
|
||||
draw();
|
||||
_needsRedraw = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _children.size(); ++i)
|
||||
_children[i]->drawElements();
|
||||
}
|
||||
|
||||
UIElement *UIElement::findViewGlobally(const Common::String &name) {
|
||||
return g_events->findView(name);
|
||||
}
|
||||
|
||||
void UIElement::close() {
|
||||
assert(g_events->focusedView() == this);
|
||||
g_events->popView();
|
||||
#ifdef USE_TTS
|
||||
stopTextToSpeech();
|
||||
#endif
|
||||
}
|
||||
|
||||
void UIElement::draw() {
|
||||
for (size_t i = 0; i < _children.size(); ++i) {
|
||||
_children[i]->draw();
|
||||
}
|
||||
}
|
||||
|
||||
bool UIElement::tick() {
|
||||
if (_timeoutCtr && --_timeoutCtr == 0) {
|
||||
timeout();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _children.size(); ++i) {
|
||||
if (_children[i]->tick())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
UIElement *UIElement::findView(const Common::String &name) {
|
||||
if (_name.equalsIgnoreCase(name))
|
||||
return this;
|
||||
|
||||
for (size_t i = 0; i < _children.size(); ++i) {
|
||||
UIElement *result = _children[i]->findView(name);
|
||||
if (result != nullptr)
|
||||
return result;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UIElement::replaceView(UIElement *ui, bool replaceAllViews, bool fadeOutIn) {
|
||||
g_events->replaceView(ui, replaceAllViews, fadeOutIn);
|
||||
}
|
||||
|
||||
void UIElement::replaceView(const Common::String &name, bool replaceAllViews, bool fadeOutIn) {
|
||||
g_events->replaceView(name, replaceAllViews, fadeOutIn);
|
||||
}
|
||||
|
||||
void UIElement::addView(UIElement *ui) {
|
||||
g_events->addView(ui);
|
||||
}
|
||||
|
||||
void UIElement::addView(const Common::String &name) {
|
||||
g_events->addView(name);
|
||||
}
|
||||
|
||||
void UIElement::addView() {
|
||||
g_events->addView(this);
|
||||
}
|
||||
|
||||
GfxSurface UIElement::getSurface(bool innerBounds) const {
|
||||
return GfxSurface(*g_events->getScreen(),
|
||||
innerBounds ? _innerBounds : _bounds);
|
||||
}
|
||||
|
||||
int UIElement::getRandomNumber(int minNumber, int maxNumber) {
|
||||
return g_engine->getRandomNumber(maxNumber - minNumber + 1) + minNumber;
|
||||
}
|
||||
|
||||
int UIElement::getRandomNumber(int maxNumber) {
|
||||
return g_engine->getRandomNumber(maxNumber);
|
||||
}
|
||||
|
||||
void UIElement::timeout() {
|
||||
redraw();
|
||||
}
|
||||
|
||||
#ifdef USE_TTS
|
||||
|
||||
void UIElement::stopTextToSpeech() {
|
||||
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
|
||||
if (ttsMan && ConfMan.getBool("tts_enabled") && ttsMan->isSpeaking()) {
|
||||
ttsMan->stop();
|
||||
}
|
||||
|
||||
_previousSaid.clear();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace Got
|
||||
422
engines/got/events.h
Normal file
422
engines/got/events.h
Normal file
@@ -0,0 +1,422 @@
|
||||
/* 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 GOT_EVENTS_H
|
||||
#define GOT_EVENTS_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/stack.h"
|
||||
#include "got/gfx/gfx_surface.h"
|
||||
#include "got/messages.h"
|
||||
#include "graphics/screen.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
#define FRAME_RATE 60
|
||||
#define FRAME_DELAY (1000 / FRAME_RATE)
|
||||
|
||||
using Gfx::GfxSurface;
|
||||
class Events;
|
||||
|
||||
/**
|
||||
* Implements a thunk layer around an element's bounds,
|
||||
* allowing access to it as if it were a simple Common::Rect,
|
||||
* but any changes to it will also be applied to a linked inner bounds
|
||||
*/
|
||||
struct Bounds {
|
||||
private:
|
||||
Common::Rect _bounds;
|
||||
Common::Rect &_innerBounds;
|
||||
int _borderSize = 0;
|
||||
|
||||
public:
|
||||
const int16 &left;
|
||||
const int16 ⊤
|
||||
const int16 &right;
|
||||
const int16 ⊥
|
||||
|
||||
public:
|
||||
Bounds(Common::Rect &innerBounds);
|
||||
operator const Common::Rect &() const {
|
||||
return _bounds;
|
||||
}
|
||||
Bounds &operator=(const Common::Rect &r);
|
||||
void setBorderSize(size_t borderSize);
|
||||
size_t borderSize() const {
|
||||
return _borderSize;
|
||||
}
|
||||
int16 width() const {
|
||||
return _bounds.width();
|
||||
}
|
||||
int16 height() const {
|
||||
return _bounds.height();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* User interface element
|
||||
*/
|
||||
class UIElement {
|
||||
friend class Events;
|
||||
|
||||
private:
|
||||
int _timeoutCtr = 0;
|
||||
|
||||
protected:
|
||||
UIElement *_parent;
|
||||
Common::Array<UIElement *> _children;
|
||||
Common::Rect _innerBounds;
|
||||
Bounds _bounds;
|
||||
bool _needsRedraw = true;
|
||||
Common::String _name;
|
||||
#ifdef USE_TTS
|
||||
Common::String _previousSaid;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Returns true if a delay is active
|
||||
*/
|
||||
bool isDelayActive() const {
|
||||
return _timeoutCtr != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels any active delay
|
||||
*/
|
||||
void cancelDelay() {
|
||||
_timeoutCtr = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an active timeout countdown expired
|
||||
*/
|
||||
virtual void timeout();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Outer method for doing drawing
|
||||
*
|
||||
*/
|
||||
virtual void drawElements();
|
||||
|
||||
/**
|
||||
* Finds a view globally
|
||||
*/
|
||||
static UIElement *findViewGlobally(const Common::String &name);
|
||||
|
||||
public:
|
||||
UIElement(const Common::String &name, UIElement *uiParent);
|
||||
UIElement(const Common::String &name);
|
||||
virtual ~UIElement() {}
|
||||
|
||||
/**
|
||||
* Returns true if the elements needs to be redrawn
|
||||
*/
|
||||
bool needsRedraw() const {
|
||||
return _needsRedraw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets that the element needs to be redrawn
|
||||
*/
|
||||
void redraw();
|
||||
|
||||
/**
|
||||
* Closes the current view. The view must have been added
|
||||
* via addView, so there's a remaining view afterwards
|
||||
*/
|
||||
virtual void close();
|
||||
|
||||
/**
|
||||
* Sets the focus to a new view
|
||||
*/
|
||||
virtual void replaceView(UIElement *ui, bool replaceAllViews = false, bool fadeOutIn = false);
|
||||
virtual void replaceView(const Common::String &name, bool replaceAllViews = false, bool fadeOutIn = false);
|
||||
|
||||
/**
|
||||
* Adds a focused view to the view stack without replacing current one
|
||||
*/
|
||||
virtual void addView(UIElement *ui);
|
||||
virtual void addView(const Common::String &name);
|
||||
void addView();
|
||||
void open() {
|
||||
addView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random number
|
||||
*/
|
||||
int getRandomNumber(int minNumber, int maxNumber);
|
||||
int getRandomNumber(int maxNumber);
|
||||
|
||||
/**
|
||||
* Sets the element's bounds
|
||||
*/
|
||||
virtual void setBounds(const Common::Rect &r) {
|
||||
_bounds = r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the element's bounds
|
||||
*/
|
||||
Common::Rect getBounds() const {
|
||||
return _bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a view's name
|
||||
*/
|
||||
const Common::String &getName() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a surface for drawing the element
|
||||
*/
|
||||
Gfx::GfxSurface getSurface(bool innerBounds = false) const;
|
||||
|
||||
/**
|
||||
* Draws the element
|
||||
*/
|
||||
virtual void draw();
|
||||
|
||||
/**
|
||||
* Called for game frame ticks
|
||||
*/
|
||||
virtual bool tick();
|
||||
|
||||
/**
|
||||
* Find a view by name
|
||||
*/
|
||||
virtual UIElement *findView(const Common::String &name);
|
||||
|
||||
/**
|
||||
* Handles events
|
||||
*/
|
||||
// Mouse move only has a minimal implementation for performance reasons
|
||||
protected:
|
||||
virtual bool msgMouseMove(const MouseMoveMessage &msg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef USE_TTS
|
||||
/**
|
||||
* Stops TTS voicing and clears the previously spoken text
|
||||
*/
|
||||
void stopTextToSpeech();
|
||||
#endif
|
||||
|
||||
public:
|
||||
bool send(const MouseMoveMessage &msg) {
|
||||
return msgMouseMove(msg);
|
||||
}
|
||||
|
||||
#define MESSAGE(NAME) \
|
||||
protected: \
|
||||
virtual bool msg##NAME(const NAME##Message &e) { \
|
||||
for (Common::Array<UIElement *>::iterator it = _children.begin(); \
|
||||
it != _children.end(); ++it) { \
|
||||
if ((*it)->msg##NAME(e)) \
|
||||
return true; \
|
||||
} \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
public: \
|
||||
bool send(const Common::String &viewName, const NAME##Message &msg) { \
|
||||
UIElement *view = UIElement::findViewGlobally(viewName); \
|
||||
assert(view); \
|
||||
return view->msg##NAME(msg); \
|
||||
} \
|
||||
bool send(const NAME##Message &msg) { \
|
||||
return msg##NAME(msg); \
|
||||
}
|
||||
|
||||
MESSAGE(Focus);
|
||||
MESSAGE(Unfocus);
|
||||
MESSAGE(MouseEnter);
|
||||
MESSAGE(MouseLeave);
|
||||
MESSAGE(Keypress);
|
||||
MESSAGE(MouseDown);
|
||||
MESSAGE(MouseUp);
|
||||
MESSAGE(Action);
|
||||
MESSAGE(Game);
|
||||
MESSAGE(Value);
|
||||
#undef MESSAGE
|
||||
};
|
||||
|
||||
/**
|
||||
* Main events and view manager. This is kept separate from the engine
|
||||
* class because the engine may add a lot of globals and bring in other
|
||||
* classes. So to save on compilation time, classes that only need to
|
||||
* access basic view management methods like addView or replaceView
|
||||
* only need to include events.h rather than the whole engine.
|
||||
*/
|
||||
class Events : public UIElement {
|
||||
private:
|
||||
Graphics::Screen *_screen = nullptr;
|
||||
Common::Stack<UIElement *> _views;
|
||||
int _palLoop = 0;
|
||||
int _palCnt1 = 0;
|
||||
int _palCnt2 = 0;
|
||||
|
||||
void nextFrame();
|
||||
int actionToKeyFlag(int action) const;
|
||||
void rotatePalette();
|
||||
|
||||
/**
|
||||
* Process an event
|
||||
*/
|
||||
void processEvent(Common::Event &ev);
|
||||
|
||||
/**
|
||||
* Process a demo event
|
||||
*/
|
||||
void processDemoEvent(byte ev);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Returns true if the game should quit
|
||||
*/
|
||||
virtual bool shouldQuit() const = 0;
|
||||
|
||||
/**
|
||||
* Overrides events we want to only go to the focused view
|
||||
*/
|
||||
#define MESSAGE(NAME) \
|
||||
bool msg##NAME(const NAME##Message &e) override { \
|
||||
return !_views.empty() ? focusedView()->msg##NAME(e) : false; \
|
||||
}
|
||||
MESSAGE(Action);
|
||||
MESSAGE(Focus);
|
||||
MESSAGE(Unfocus);
|
||||
MESSAGE(MouseEnter);
|
||||
MESSAGE(MouseLeave);
|
||||
MESSAGE(Keypress);
|
||||
MESSAGE(MouseDown);
|
||||
MESSAGE(MouseUp);
|
||||
MESSAGE(MouseMove);
|
||||
#undef MESSAGE
|
||||
public:
|
||||
Events();
|
||||
virtual ~Events();
|
||||
|
||||
virtual bool isDemo() const = 0;
|
||||
|
||||
/**
|
||||
* Main game loop
|
||||
*/
|
||||
void runGame();
|
||||
|
||||
/**
|
||||
* Sets the focus to a new view
|
||||
*/
|
||||
void replaceView(UIElement *ui, bool replaceAllViews = false, bool fadeOutIn = false) override;
|
||||
void replaceView(const Common::String &name, bool replaceAllViews = false, bool fadeOutIn = false) override;
|
||||
|
||||
/**
|
||||
* Adds a focused view to the view stack without replacing current one
|
||||
*/
|
||||
void addView(UIElement *ui) override;
|
||||
void addView(const Common::String &name) override;
|
||||
|
||||
/**
|
||||
* Clears the view list
|
||||
*/
|
||||
void clearViews();
|
||||
|
||||
/**
|
||||
* Pops a view from the view stack
|
||||
*/
|
||||
void popView();
|
||||
|
||||
/**
|
||||
* Returns the currently focused view, if any
|
||||
*/
|
||||
UIElement *focusedView() const {
|
||||
return _views.empty() ? nullptr : _views.top();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view prior to the current view, if any
|
||||
*/
|
||||
UIElement *priorView() const {
|
||||
return _views.size() < 2 ? nullptr : _views[_views.size() - 2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first view in the stack
|
||||
*/
|
||||
UIElement *firstView() const {
|
||||
return _views.empty() ? nullptr : _views[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a view of a given name is present
|
||||
* at all in the visible view stack
|
||||
*/
|
||||
bool isPresent(const Common::String &name) const;
|
||||
|
||||
/**
|
||||
* Returns true if combat is active
|
||||
*/
|
||||
bool isInCombat() const {
|
||||
return isPresent("Combat");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying screen
|
||||
*/
|
||||
Graphics::Screen *getScreen() const {
|
||||
return _screen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the focused view
|
||||
*/
|
||||
void drawElements() override;
|
||||
|
||||
/**
|
||||
* Events manager doesn't have any intrinsic drawing
|
||||
*/
|
||||
void draw() override {}
|
||||
|
||||
/**
|
||||
* Called once every game frame
|
||||
*/
|
||||
bool tick() override {
|
||||
return !_views.empty() ? focusedView()->tick() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling the close method for g_events closes the active view
|
||||
*/
|
||||
void close() override {
|
||||
focusedView()->close();
|
||||
}
|
||||
};
|
||||
|
||||
extern Events *g_events;
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
334
engines/got/game/back.cpp
Normal file
334
engines/got/game/back.cpp
Normal file
@@ -0,0 +1,334 @@
|
||||
/* 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 "got/game/back.h"
|
||||
#include "common/file.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/boss1.h"
|
||||
#include "got/game/boss2.h"
|
||||
#include "got/game/boss3.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/game/object.h"
|
||||
#include "got/game/script.h"
|
||||
#include "got/gfx/image.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
const char *OBJECT_NAMES[] = {
|
||||
"Shrub", "Child's Doll", "UNUSED", "FUTURE",
|
||||
"FUTURE", "FUTURE", "FUTURE", "FUTURE", "FUTURE",
|
||||
"FUTURE", "FUTURE", "FUTURE", "FUTURE", "FUTURE",
|
||||
"FUTURE"};
|
||||
const char *ITEM_NAMES[] = {
|
||||
"Enchanted Apple", "Lightning Power",
|
||||
"Winged Boots", "Wind Power",
|
||||
"Amulet of Protection", "Thunder Power"};
|
||||
|
||||
static const char *odinEndMessage;
|
||||
|
||||
void showLevel(const int newLevel) {
|
||||
if (_G(area) == 2 && newLevel == 105) { // Shovel Maze
|
||||
_G(thorInfo)._armor = 2; // eyeballs mode
|
||||
loadNewThor();
|
||||
_G(eyeballs) = 1;
|
||||
} else if (_G(eyeballs) == 1) {
|
||||
_G(setup).f25 = 0;
|
||||
_G(thorInfo)._armor = 1;
|
||||
loadNewThor();
|
||||
_G(eyeballs) = 0;
|
||||
}
|
||||
|
||||
_G(bossActive) = false;
|
||||
if (!_G(shieldOn))
|
||||
_G(actor[2])._active = false;
|
||||
_G(slipping) = false;
|
||||
|
||||
if (_G(scrn)._iconGrid[_G(thor)->_centerY][_G(thor)->_centerX] == 154)
|
||||
_G(thor)->_dir = 0;
|
||||
|
||||
// The original copied 130 bytes from _G(scrn).static_object onwards into sd_data.
|
||||
// This doesn't make sense, because that would put the ending in the middle of _staticY.
|
||||
// Plus, it follows with an entire copy of scrn into sd_data anyway, so the first
|
||||
// move seems entirely redundant.
|
||||
_G(scrn).save(_G(currentLevel));
|
||||
_G(scrn).load(_G(newLevel));
|
||||
|
||||
_G(levelMusic) = _G(scrn)._music;
|
||||
|
||||
_G(thor)->_nextFrame = 0;
|
||||
|
||||
showObjects();
|
||||
showEnemies();
|
||||
|
||||
// The original was probably shortly displaying Thor in direction 0 before switching back to its prior position.
|
||||
// This behavior wasn't noticed during initial playthrough by Dreammaster - Warning has been added so it can be checked eventually.
|
||||
if (_G(scrn)._iconGrid[_G(thor)->_centerY][_G(thor)->_centerX] == 154)
|
||||
warning("showLevel - Potential short move missing");
|
||||
|
||||
if (_G(warpFlag))
|
||||
_G(currentLevel) = newLevel - 5; // Force phase
|
||||
_G(warpFlag) = false;
|
||||
|
||||
if (_G(warpScroll)) {
|
||||
_G(warpScroll) = false;
|
||||
if (_G(thor)->_dir == 0)
|
||||
_G(currentLevel) = newLevel + 10;
|
||||
else if (_G(thor)->_dir == 1)
|
||||
_G(currentLevel) = newLevel - 10;
|
||||
else if (_G(thor)->_dir == 2)
|
||||
_G(currentLevel) = newLevel + 1;
|
||||
else if (_G(thor)->_dir == 3)
|
||||
_G(currentLevel) = newLevel - 1;
|
||||
}
|
||||
|
||||
if (!_G(setup)._scrollFlag)
|
||||
_G(currentLevel) = newLevel; // Force no scroll
|
||||
|
||||
switch (_G(newLevel) - _G(currentLevel)) {
|
||||
case 0:
|
||||
// Nothing to do
|
||||
showLevelDone();
|
||||
break;
|
||||
case -1:
|
||||
_G(gameMode) = MODE_AREA_CHANGE;
|
||||
_G(transitionDir) = DIR_LEFT;
|
||||
break;
|
||||
case 1:
|
||||
_G(gameMode) = MODE_AREA_CHANGE;
|
||||
_G(transitionDir) = DIR_RIGHT;
|
||||
break;
|
||||
case -10:
|
||||
_G(gameMode) = MODE_AREA_CHANGE;
|
||||
_G(transitionDir) = DIR_UP;
|
||||
break;
|
||||
case 10:
|
||||
_G(gameMode) = MODE_AREA_CHANGE;
|
||||
_G(transitionDir) = DIR_DOWN;
|
||||
break;
|
||||
default:
|
||||
_G(gameMode) = MODE_AREA_CHANGE;
|
||||
_G(transitionDir) = DIR_PHASED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void showLevelDone() {
|
||||
_G(currentLevel) = _G(newLevel);
|
||||
|
||||
_G(thorInfo)._lastHealth = _G(thor)->_health;
|
||||
_G(thorInfo)._lastMagic = _G(thorInfo)._magic;
|
||||
_G(thorInfo)._lastJewels = _G(thorInfo)._jewels;
|
||||
_G(thorInfo)._lastKeys = _G(thorInfo)._keys;
|
||||
_G(thorInfo)._lastScore = _G(thorInfo)._score;
|
||||
_G(thorInfo)._lastItem = _G(thorInfo)._selectedItem;
|
||||
_G(thorInfo)._lastScreen = _G(currentLevel);
|
||||
_G(thorInfo)._lastIcon = ((_G(thor)->_x + 8) / 16) + (((_G(thor)->_y + 14) / 16) * 20);
|
||||
_G(thorInfo)._lastDir = _G(thor)->_dir;
|
||||
_G(thorInfo)._lastInventory = _G(thorInfo)._inventory;
|
||||
_G(thorInfo)._lastObject = _G(thorInfo)._object;
|
||||
_G(thorInfo)._lastObjectName = _G(thorInfo)._objectName;
|
||||
|
||||
_G(lastSetup) = _G(setup);
|
||||
|
||||
bool f = true;
|
||||
if (GAME1 && _G(newLevel) == BOSS_LEVEL1 && !_G(setup)._bossDead[0]) {
|
||||
boss1SetupLevel();
|
||||
f = false;
|
||||
}
|
||||
|
||||
if (GAME2 && _G(newLevel) == BOSS_LEVEL2 && !_G(setup)._bossDead[1]) {
|
||||
boss2SetupLevel();
|
||||
f = false;
|
||||
}
|
||||
|
||||
if (GAME3) {
|
||||
if (_G(newLevel) == BOSS_LEVEL3 && !_G(setup)._bossDead[2]) {
|
||||
boss3SetupLevel();
|
||||
f = false;
|
||||
}
|
||||
|
||||
if (_G(currentLevel) == ENDING_SCREEN) {
|
||||
endingScreen();
|
||||
f = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_G(startup))
|
||||
f = false;
|
||||
|
||||
if (f)
|
||||
musicPlay(_G(levelMusic), false);
|
||||
}
|
||||
|
||||
static void odin_speaks_end() {
|
||||
// In case Thor is now dead, flag as such
|
||||
if (!_G(thor)->_health) {
|
||||
_G(thor)->_show = 0;
|
||||
_G(exitFlag) = 2;
|
||||
}
|
||||
|
||||
// If there's an end message, pass it on to the view hierarchy.
|
||||
// This is used in cases like the game end where multiple
|
||||
// odinSpeaks are done in sequence
|
||||
if (odinEndMessage)
|
||||
g_events->send(GameMessage(odinEndMessage));
|
||||
}
|
||||
|
||||
void odinSpeaks(const int index, int item, const char *endMessage) {
|
||||
odinEndMessage = endMessage;
|
||||
|
||||
executeScript((long)index, _G(odin), odin_speaks_end);
|
||||
}
|
||||
|
||||
int switchIcons() {
|
||||
playSound(WOOP, false);
|
||||
|
||||
for (int y = 0; y < 12; y++) {
|
||||
for (int x = 0; x < 20; x++) {
|
||||
const int ix = x * 16;
|
||||
const int iy = y * 16;
|
||||
if (_G(scrn)._iconGrid[y][x] == 93) {
|
||||
placeTile(x, y, 144);
|
||||
} else if (_G(scrn)._iconGrid[y][x] == 144) {
|
||||
placeTile(x, y, 93);
|
||||
killEnemies(iy, ix);
|
||||
}
|
||||
|
||||
if (_G(scrn)._iconGrid[y][x] == 94) {
|
||||
placeTile(x, y, 146);
|
||||
} else if (_G(scrn)._iconGrid[y][x] == 146) {
|
||||
placeTile(x, y, 94);
|
||||
killEnemies(iy, ix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rotateArrows() {
|
||||
playSound(WOOP, false);
|
||||
|
||||
for (int y = 0; y < 12; y++) {
|
||||
for (int x = 0; x < 20; x++) {
|
||||
if (_G(scrn)._iconGrid[y][x] == 205)
|
||||
placeTile(x, y, 208);
|
||||
else if (_G(scrn)._iconGrid[y][x] == 206)
|
||||
placeTile(x, y, 207);
|
||||
else if (_G(scrn)._iconGrid[y][x] == 207)
|
||||
placeTile(x, y, 205);
|
||||
else if (_G(scrn)._iconGrid[y][x] == 208)
|
||||
placeTile(x, y, 206);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void killEnemies(const int iy, const int ix) {
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
for (int i = 3; i < MAX_ACTORS; i++) {
|
||||
if (_G(actor[i])._active) {
|
||||
x1 = _G(actor[i])._x;
|
||||
y1 = _G(actor[i])._y + _G(actor[i])._sizeY - 2;
|
||||
x2 = (_G(actor[i])._x + _G(actor[i])._sizeX);
|
||||
y2 = _G(actor[i])._y + _G(actor[i])._sizeY - 1;
|
||||
|
||||
if (pointWithin(x1, y1, ix, iy, ix + 15, iy + 15) || pointWithin(x2, y1, ix, iy, ix + 15, iy + 15)
|
||||
|| pointWithin(x1, y2, ix, iy, ix + 15, iy + 15) || pointWithin(x2, y2, ix, iy, ix + 15, iy + 15))
|
||||
actorDestroyed(&_G(actor[i]));
|
||||
}
|
||||
}
|
||||
|
||||
x1 = _G(thor)->_x;
|
||||
y1 = _G(thor)->_y + 11;
|
||||
x2 = x1 + 13;
|
||||
y2 = y1 + 5;
|
||||
|
||||
if (pointWithin(x1, y1, ix, iy, ix + 15, iy + 15) || pointWithin(x2, y1, ix, iy, ix + 15, iy + 15)
|
||||
|| pointWithin(x1, y2, ix, iy, ix + 15, iy + 15) || pointWithin(x2, y2, ix, iy, ix + 15, iy + 15)) {
|
||||
if (!_G(cheats)._freezeHealth) {
|
||||
_G(thor)->_health = 0;
|
||||
g_events->send(GameMessage("THOR_DIES"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeObjects(const int y, const int x) {
|
||||
const int p = (y * 20) + x;
|
||||
|
||||
if (_G(objectMap[p]) > 0) {
|
||||
_G(objectMap[p]) = 0;
|
||||
_G(objectIndex[p]) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void placeTile(const int x, const int y, const int tile) {
|
||||
_G(scrn)._iconGrid[y][x] = tile;
|
||||
removeObjects(y, x);
|
||||
}
|
||||
|
||||
int backgroundTile(int x, int y) {
|
||||
if (x < 0 || x >= 319 || y < 0 || y >= 191)
|
||||
return 0;
|
||||
|
||||
x = (x + 1) >> 4;
|
||||
y = (y + 1) >> 4;
|
||||
|
||||
return _G(scrn)._iconGrid[y][x];
|
||||
}
|
||||
|
||||
void selectItem() {
|
||||
// Only allow opening the dialog if something isn't currently going on
|
||||
if (g_engine->canSaveAutosaveCurrently()) {
|
||||
g_events->addView("SelectItem");
|
||||
}
|
||||
}
|
||||
|
||||
void actorSpeaks(const Actor *actor, int index, int item) {
|
||||
if (actor->_type != 4)
|
||||
return;
|
||||
|
||||
const int v = atoi(actor->_name);
|
||||
if (v < 1 || v > 20)
|
||||
return;
|
||||
|
||||
long lind = (long)_G(currentLevel);
|
||||
lind = lind * 1000;
|
||||
lind += (long)actor->_actorNum;
|
||||
|
||||
const Common::String str = Common::String::format("FACE%d", v);
|
||||
if (Common::File::exists(Common::Path(str))) {
|
||||
Gfx::Pics pics(str, 262);
|
||||
executeScript(lind, pics);
|
||||
} else {
|
||||
executeScript(lind, _G(odin));
|
||||
}
|
||||
|
||||
if (!_G(thor)->_health) {
|
||||
_G(thor)->_show = 0;
|
||||
_G(exitFlag) = 2;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
52
engines/got/game/back.h
Normal file
52
engines/got/game/back.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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 GOT_GAME_BACK_H
|
||||
#define GOT_GAME_BACK_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern const char *OBJECT_NAMES[];
|
||||
extern const char *ITEM_NAMES[];
|
||||
|
||||
/**
|
||||
* Shows a new level
|
||||
* In the original this did some initial actors setup and rendering.
|
||||
* Now in ScummVM, it only does the setup portions, since the
|
||||
* GameContent view takes care of the scene rendering.
|
||||
*/
|
||||
extern void showLevel(int newLevel);
|
||||
extern void showLevelDone();
|
||||
extern void odinSpeaks(int index, int item, const char *endMessage = nullptr);
|
||||
extern int switchIcons();
|
||||
extern int rotateArrows();
|
||||
extern void killEnemies(int iy, int ix);
|
||||
extern void removeObjects(int y, int x);
|
||||
extern void placeTile(int x, int y, int tile);
|
||||
extern int backgroundTile(int x, int y);
|
||||
extern void selectItem();
|
||||
extern void actorSpeaks(const Actor *actor, int index, int item);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
298
engines/got/game/boss1.cpp
Normal file
298
engines/got/game/boss1.cpp
Normal file
@@ -0,0 +1,298 @@
|
||||
/* 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 "got/game/boss1.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/game/move_patterns.h"
|
||||
#include "got/game/status.h"
|
||||
#include "got/gfx/image.h"
|
||||
#include "got/sound.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
static int boss1_dead();
|
||||
|
||||
int boss1Movement(Actor *actor) {
|
||||
bool f = false;
|
||||
|
||||
if (_G(bossDead))
|
||||
return boss1_dead();
|
||||
|
||||
int d = actor->_lastDir;
|
||||
int x1 = actor->_x;
|
||||
int y1 = actor->_y;
|
||||
|
||||
if (actor->_edgeCounter) {
|
||||
actor->_edgeCounter--;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (overlap(actor->_x + 2, actor->_y + 8, actor->_x + 30, actor->_y + 30,
|
||||
_G(thor)->_x, _G(thor)->_y + 8, _G(thor)->_x + 15, _G(thor)->_y + 15)) {
|
||||
thorDamaged(actor);
|
||||
}
|
||||
|
||||
if (actor->_temp3) { //start striking
|
||||
actor->_temp3--;
|
||||
if (!actor->_temp3)
|
||||
playSound(BOSS11, false);
|
||||
|
||||
actor->_numMoves = 6;
|
||||
|
||||
goto done0;
|
||||
}
|
||||
|
||||
// Strike
|
||||
if (actor->_temp1) {
|
||||
actor->_temp1--;
|
||||
if (actor->_x < (_G(thorX1) + 12))
|
||||
actor->_temp1 = 0;
|
||||
actor->_temp2 = 1;
|
||||
d = 2;
|
||||
actor->_x -= 2;
|
||||
|
||||
if (overlap(actor->_x + 2, actor->_y + 8, actor->_x + 32, actor->_y + 30,
|
||||
_G(thor)->_x, _G(thor)->_y + 8, _G(thor)->_x + 15, _G(thor)->_y + 15)) {
|
||||
actor->_temp1 = 0;
|
||||
goto done1;
|
||||
}
|
||||
|
||||
actor->_nextFrame = 3;
|
||||
actor->_numMoves = _G(setup)._difficultyLevel + 2;
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (actor->_temp2) { // Retreating
|
||||
if (actor->_x < 256) {
|
||||
d = 3;
|
||||
actor->_x += 2;
|
||||
if (overlap(actor->_x + 2, actor->_y + 8, actor->_x + 32, actor->_y + 30,
|
||||
_G(thor)->_x, _G(thor)->_y + 8, _G(thor)->_x + 15, _G(thor)->_y + 15)) {
|
||||
goto done1;
|
||||
}
|
||||
actor->_numMoves = _G(setup)._difficultyLevel + 1;
|
||||
goto done0;
|
||||
}
|
||||
|
||||
actor->_temp2 = 0;
|
||||
}
|
||||
|
||||
if (actor->_x > _G(thorX1) && ABS((_G(thorY1)) - (actor->_y + 20)) < 8) {
|
||||
actor->_temp3 = 75;
|
||||
actor->_temp1 = 130;
|
||||
actor->_temp2 = 0;
|
||||
}
|
||||
|
||||
if (actor->_counter) {
|
||||
actor->_counter--;
|
||||
switch (d) {
|
||||
case 1:
|
||||
case 3:
|
||||
x1 = _G(actor[5])._x;
|
||||
y1 = _G(actor[5])._y;
|
||||
y1 += 2;
|
||||
|
||||
if (!checkMove2(x1, y1, &_G(actor[5])))
|
||||
f = true;
|
||||
else {
|
||||
actor->_x = _G(actor[5])._x;
|
||||
actor->_y = _G(actor[5])._y - 16;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
case 2:
|
||||
y1 -= 2;
|
||||
if (!checkMove2(x1, y1, actor))
|
||||
f = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
f = true;
|
||||
|
||||
if (f) {
|
||||
actor->_counter = g_events->getRandomNumber(10, 99);
|
||||
d = g_events->getRandomNumber(1);
|
||||
actor->_edgeCounter = 20;
|
||||
}
|
||||
|
||||
done:
|
||||
if (d > 1)
|
||||
d -= 2;
|
||||
|
||||
done0:
|
||||
nextFrame(actor);
|
||||
if (actor->_nextFrame == 3)
|
||||
actor->_nextFrame = 0;
|
||||
|
||||
done1:
|
||||
actor->_lastDir = d;
|
||||
|
||||
_G(actor[4])._nextFrame = actor->_nextFrame;
|
||||
_G(actor[5])._nextFrame = actor->_nextFrame;
|
||||
_G(actor[6])._nextFrame = actor->_nextFrame;
|
||||
|
||||
_G(actor[4])._lastDir = d;
|
||||
_G(actor[5])._lastDir = d;
|
||||
_G(actor[6])._lastDir = d;
|
||||
|
||||
_G(actor[4])._x = actor->_x + 16;
|
||||
_G(actor[4])._y = actor->_y;
|
||||
_G(actor[5])._x = actor->_x;
|
||||
_G(actor[5])._y = actor->_y + 16;
|
||||
_G(actor[6])._x = actor->_x + 16;
|
||||
_G(actor[6])._y = actor->_y + 16;
|
||||
_G(actor[4])._numMoves = actor->_numMoves;
|
||||
_G(actor[5])._numMoves = actor->_numMoves;
|
||||
_G(actor[6])._numMoves = actor->_numMoves;
|
||||
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
void boss1CheckHit(const Actor *actor, const int x1, const int y1, const int x2, const int y2, const int actorNum) {
|
||||
if (actor->_moveType == 15 && actorNum == 4) {
|
||||
if ((!_G(actor[3])._vulnerableCountdown) && (_G(actor[3])._nextFrame != 3) &&
|
||||
overlap(x1, y1, x2, y2, actor->_x + 6, actor->_y + 4, actor->_x + 14, actor->_y + 20)) {
|
||||
actorDamaged(&_G(actor[3]), _G(hammer)->_hitStrength);
|
||||
if (_G(cheat) && _G(keyFlag[GOT_Z]))
|
||||
_G(actor[3])._health = 0;
|
||||
else
|
||||
_G(actor[3])._health -= 10;
|
||||
|
||||
_G(actor[3])._moveCountdown = 50;
|
||||
_G(actor[3])._vulnerableCountdown = 100;
|
||||
playSound(BOSS13, true);
|
||||
_G(actor[3])._nextFrame = 1;
|
||||
|
||||
for (int rep = 4; rep < 7; rep++) {
|
||||
_G(actor[rep])._nextFrame = 1;
|
||||
_G(actor[rep])._moveCountdown = 50;
|
||||
}
|
||||
|
||||
if (_G(actor[3])._health == 0)
|
||||
_G(bossDead) = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void boss1SetupLevel() {
|
||||
setupBoss(1);
|
||||
_G(bossActive) = true;
|
||||
musicPause();
|
||||
playSound(BOSS11, true);
|
||||
g_events->send("Game", GameMessage("PAUSE", 40));
|
||||
musicPlay(5, true);
|
||||
}
|
||||
|
||||
static int boss1_dead() {
|
||||
if (_G(bossDead)) {
|
||||
for (int rep = 0; rep < 4; rep++) {
|
||||
const int x1 = _G(actor[3 + rep])._lastX[_G(pge)];
|
||||
const int y1 = _G(actor[3 + rep])._lastY[_G(pge)];
|
||||
const int x = _G(actor[3 + rep])._x;
|
||||
const int y = _G(actor[3 + rep])._y;
|
||||
const int n = _G(actor[3 + rep])._actorNum;
|
||||
const int r = _G(actor[3 + rep])._dropRating;
|
||||
|
||||
_G(actor[3 + rep]) = _G(explosion);
|
||||
_G(actor[3 + rep])._actorNum = n;
|
||||
_G(actor[3 + rep])._dropRating = r;
|
||||
_G(actor[3 + rep])._x = x;
|
||||
_G(actor[3 + rep])._y = y;
|
||||
_G(actor[3 + rep])._lastX[_G(pge)] = x1;
|
||||
_G(actor[3 + rep])._lastX[_G(pge) ^ 1] = x;
|
||||
_G(actor[3 + rep])._lastY[_G(pge)] = y1;
|
||||
_G(actor[3 + rep])._lastY[_G(pge) ^ 1] = y;
|
||||
_G(actor[3 + rep])._active = true;
|
||||
_G(actor[3 + rep])._vulnerableCountdown = 255;
|
||||
_G(actor[3 + rep])._moveType = 6;
|
||||
_G(actor[3 + rep])._nextFrame = rep;
|
||||
_G(actor[3 + rep])._speed = g_events->getRandomNumber(6, 8);
|
||||
_G(actor[3 + rep])._currNumShots = (10 - _G(actor[3 + rep])._speed) * 10;
|
||||
_G(actor[3 + rep])._moveCountdown = _G(actor[3 + rep])._speed;
|
||||
}
|
||||
playSound(EXPLODE, true);
|
||||
_G(bossDead) = true;
|
||||
|
||||
for (int rep = 7; rep < MAX_ACTORS; rep++) {
|
||||
if (_G(actor[rep])._active)
|
||||
actorDestroyed(&_G(actor[rep]));
|
||||
}
|
||||
}
|
||||
|
||||
return _G(actor[3])._lastDir;
|
||||
}
|
||||
|
||||
void boss1ClosingSequence1() {
|
||||
_G(gameOver) = true;
|
||||
musicPlay(4, true);
|
||||
odinSpeaks(1001, 13, "CLOSING");
|
||||
}
|
||||
|
||||
void boss1ClosingSequence2() {
|
||||
_G(thorInfo)._armor = 1;
|
||||
loadNewThor();
|
||||
_G(thor)->_dir = 1;
|
||||
_G(thor)->_nextFrame = 0;
|
||||
fillScore(20, "CLOSING");
|
||||
}
|
||||
|
||||
void boss1ClosingSequence3() {
|
||||
fillHealth();
|
||||
fillMagic();
|
||||
odinSpeaks(1002, 0, "CLOSING");
|
||||
}
|
||||
|
||||
void boss1ClosingSequence4() {
|
||||
for (int rep = 0; rep < 16; rep++)
|
||||
_G(scrn)._actorType[rep] = 0;
|
||||
|
||||
_G(bossDead) = false;
|
||||
_G(setup)._bossDead[0] = true;
|
||||
_G(bossActive) = false;
|
||||
_G(scrn)._music = 4;
|
||||
showLevel(BOSS_LEVEL1);
|
||||
|
||||
#ifdef USE_TTS
|
||||
_G(thorInfo)._previousScore = -1;
|
||||
#endif
|
||||
|
||||
playSound(ANGEL, true);
|
||||
placeTile(18, 6, 148);
|
||||
placeTile(19, 6, 202);
|
||||
actorVisible(1);
|
||||
actorVisible(2);
|
||||
|
||||
Level lvl;
|
||||
lvl.load(59);
|
||||
lvl._iconGrid[6][18] = 148;
|
||||
lvl._iconGrid[6][19] = 202;
|
||||
lvl.save(59);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
40
engines/got/game/boss1.h
Normal file
40
engines/got/game/boss1.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* 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 GOT_GAME_BOSS1_H
|
||||
#define GOT_GAME_BOSS1_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
// Boss 1 - Snake (Jormangund)
|
||||
extern int boss1Movement(Actor *actor);
|
||||
extern void boss1CheckHit(const Actor *actor, int x1, int y1, int x2, int y2, int actorNum);
|
||||
extern void boss1SetupLevel();
|
||||
extern void boss1ClosingSequence1();
|
||||
extern void boss1ClosingSequence2();
|
||||
extern void boss1ClosingSequence3();
|
||||
extern void boss1ClosingSequence4();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
436
engines/got/game/boss2.cpp
Normal file
436
engines/got/game/boss2.cpp
Normal file
@@ -0,0 +1,436 @@
|
||||
/* 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 "got/game/boss2.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/game/status.h"
|
||||
#include "got/gfx/image.h"
|
||||
#include "got/sound.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
static const byte EXPLOSION[] = {
|
||||
61, 62, 65, 66, 69, 70, 73, 74, 77, 78,
|
||||
81, 82, 85, 86, 89, 90, 93, 94, 97, 98,
|
||||
101, 102, 105, 106, 109, 110, 113, 114, 117, 118,
|
||||
121, 122, 125, 126, 129, 130, 133, 134, 137, 138,
|
||||
141, 142, 145, 146, 149, 150, 153, 154, 157, 158,
|
||||
161, 162, 165, 166, 169, 170, 173, 174, 177, 178
|
||||
};
|
||||
|
||||
static bool expf[60];
|
||||
static byte numSkulls;
|
||||
static byte numSpikes;
|
||||
static bool dropFlag;
|
||||
static byte su[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
static int boss2MovementExplode(Actor *actor);
|
||||
static int boss2MovementShake(Actor *actor);
|
||||
static int boss2Die();
|
||||
static void bossSet(byte d, int x, int y);
|
||||
|
||||
int boss2Movement(Actor *actor) {
|
||||
switch (_G(setup)._difficultyLevel) {
|
||||
case 0:
|
||||
numSkulls = 3;
|
||||
numSpikes = 5;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
numSkulls = 6;
|
||||
numSpikes = 8;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
numSkulls = 9;
|
||||
numSpikes = 11;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (_G(bossDead))
|
||||
return boss2Die();
|
||||
|
||||
if (actor->_i1) {
|
||||
if (actor->_i1 == 1)
|
||||
return boss2MovementExplode(actor);
|
||||
|
||||
return boss2MovementShake(actor);
|
||||
}
|
||||
|
||||
byte d = actor->_lastDir;
|
||||
int x = actor->_x;
|
||||
|
||||
if (actor->_temp6)
|
||||
actor->_temp6--;
|
||||
|
||||
if (!actor->_temp6) {
|
||||
bool f = false;
|
||||
dropFlag = false;
|
||||
|
||||
if (actor->_temp5)
|
||||
actor->_temp5--;
|
||||
|
||||
if (!actor->_temp5)
|
||||
f = true;
|
||||
else {
|
||||
if (d == 2) {
|
||||
if (x > 18)
|
||||
actor->_x -= 2;
|
||||
else
|
||||
f = true;
|
||||
} else if (d == 3) {
|
||||
if (x < 272)
|
||||
actor->_x += 2;
|
||||
else
|
||||
f = true;
|
||||
}
|
||||
}
|
||||
if (f) {
|
||||
actor->_temp5 = _G(rand1) + 60;
|
||||
if (d == 2)
|
||||
d = 3;
|
||||
else
|
||||
d = 2;
|
||||
}
|
||||
}
|
||||
|
||||
const int count = actor->_frameCount - 1;
|
||||
|
||||
if (count <= 0) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 2)
|
||||
actor->_nextFrame = 0;
|
||||
actor->_frameCount = actor->_frameSpeed;
|
||||
} else
|
||||
actor->_frameCount = count;
|
||||
|
||||
x = actor->_x;
|
||||
if (actor->_currNumShots < numSkulls && !dropFlag) {
|
||||
if (x == 48 || x == 112 || x == 176 || x == 240) {
|
||||
dropFlag = true;
|
||||
_G(actor[3])._temp6 = 40;
|
||||
|
||||
actorAlwaysShoots(actor, 1);
|
||||
playSound(FALL, false);
|
||||
_G(actor[actor->_shotActor])._x = actor->_x + 12;
|
||||
_G(actor[actor->_shotActor])._y = actor->_y + 32;
|
||||
_G(actor[actor->_shotActor])._temp2 = 0;
|
||||
_G(actor[actor->_shotActor])._temp3 = 4;
|
||||
_G(actor[actor->_shotActor])._temp4 = 4;
|
||||
}
|
||||
}
|
||||
|
||||
bossSet(d, x, actor->_y);
|
||||
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
static void bossSet(const byte d, const int x, const int y) {
|
||||
_G(actor[4])._nextFrame = _G(actor[3])._nextFrame;
|
||||
_G(actor[5])._nextFrame = _G(actor[3])._nextFrame;
|
||||
_G(actor[6])._nextFrame = _G(actor[3])._nextFrame;
|
||||
_G(actor[3])._lastDir = d;
|
||||
_G(actor[4])._lastDir = d;
|
||||
_G(actor[5])._lastDir = d;
|
||||
_G(actor[6])._lastDir = d;
|
||||
_G(actor[4])._x = x + 16;
|
||||
_G(actor[4])._y = y;
|
||||
_G(actor[5])._x = x;
|
||||
_G(actor[5])._y = y + 16;
|
||||
_G(actor[6])._x = x + 16;
|
||||
_G(actor[6])._y = y + 16;
|
||||
}
|
||||
|
||||
void boss2CheckHit(Actor *actor) {
|
||||
if (!_G(actor[3])._vulnerableCountdown) {
|
||||
actorDamaged(&_G(actor[3]), _G(hammer)->_hitStrength);
|
||||
_G(actor[3])._health -= 10;
|
||||
if (_G(actor[3])._health == 50) {
|
||||
playSound(BOSS12, true);
|
||||
|
||||
g_events->send("Game", GameMessage("PAUSE", 40));
|
||||
|
||||
_G(actor[3])._i1 = 1;
|
||||
_G(actor[3])._i2 = 0;
|
||||
memset(expf, 0, sizeof(expf));
|
||||
|
||||
for (int rep = 7; rep < MAX_ACTORS; rep++) {
|
||||
if (_G(actor[rep])._active)
|
||||
actorDestroyed(&_G(actor[rep]));
|
||||
}
|
||||
_G(actor[3])._currNumShots = 0;
|
||||
} else
|
||||
playSound(BOSS13, true);
|
||||
|
||||
_G(actor[3])._moveCountdown = 75;
|
||||
_G(actor[3])._vulnerableCountdown = 75;
|
||||
_G(actor[3])._nextFrame = 1;
|
||||
|
||||
for (int rep = 4; rep < 7; rep++) {
|
||||
_G(actor[rep])._nextFrame = 1;
|
||||
_G(actor[rep])._moveCountdown = 50;
|
||||
}
|
||||
|
||||
if (_G(actor[3])._health == 0) {
|
||||
_G(bossDead) = true;
|
||||
for (int rep = 7; rep < MAX_ACTORS; rep++) {
|
||||
if (_G(actor[rep])._active)
|
||||
actorDestroyed(&_G(actor[rep]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void boss2SetupLevel() {
|
||||
setupBoss(2);
|
||||
_G(bossActive) = true;
|
||||
musicPause();
|
||||
playSound(BOSS11, true);
|
||||
|
||||
dropFlag = false;
|
||||
Common::fill(su, su + 18, 0);
|
||||
|
||||
g_events->send("Game", GameMessage("PAUSE", 40));
|
||||
musicPlay(7, true);
|
||||
}
|
||||
|
||||
static int boss2Die() {
|
||||
_G(thunderSnakeCounter) = 0;
|
||||
if (_G(bossDead)) {
|
||||
for (int rep = 0; rep < 4; rep++) {
|
||||
const int x1 = _G(actor[3 + rep])._lastX[_G(pge)];
|
||||
const int y1 = _G(actor[3 + rep])._lastY[_G(pge)];
|
||||
const int x = _G(actor[3 + rep])._x;
|
||||
const int y = _G(actor[3 + rep])._y;
|
||||
const int n = _G(actor[3 + rep])._actorNum;
|
||||
const int r = _G(actor[3 + rep])._dropRating;
|
||||
|
||||
_G(actor[3 + rep]) = _G(explosion);
|
||||
|
||||
_G(actor[3 + rep])._actorNum = n;
|
||||
_G(actor[3 + rep])._dropRating = r;
|
||||
_G(actor[3 + rep])._x = x;
|
||||
_G(actor[3 + rep])._y = y;
|
||||
_G(actor[3 + rep])._lastX[_G(pge)] = x1;
|
||||
_G(actor[3 + rep])._lastX[_G(pge) ^ 1] = x;
|
||||
_G(actor[3 + rep])._lastY[_G(pge)] = y1;
|
||||
_G(actor[3 + rep])._lastY[_G(pge) ^ 1] = y;
|
||||
_G(actor[3 + rep])._active = true;
|
||||
_G(actor[3 + rep])._vulnerableCountdown = 255;
|
||||
_G(actor[3 + rep])._moveType = 6;
|
||||
_G(actor[3 + rep])._nextFrame = rep;
|
||||
_G(actor[3 + rep])._speed = g_events->getRandomNumber(6, 8);
|
||||
_G(actor[3 + rep])._currNumShots = (10 - _G(actor[3 + rep])._speed) * 10;
|
||||
_G(actor[3 + rep])._moveCountdown = _G(actor[3 + rep])._speed;
|
||||
}
|
||||
|
||||
playSound(EXPLODE, true);
|
||||
_G(bossDead) = true;
|
||||
}
|
||||
|
||||
return _G(actor[3])._lastDir;
|
||||
}
|
||||
|
||||
// Boss - skull (explode)
|
||||
static int boss2MovementExplode(Actor *actor) {
|
||||
nextFrame(actor);
|
||||
_G(actor[4])._nextFrame = actor->_nextFrame;
|
||||
_G(actor[5])._nextFrame = actor->_nextFrame;
|
||||
_G(actor[6])._nextFrame = actor->_nextFrame;
|
||||
actor->_vulnerableCountdown = 20;
|
||||
|
||||
if (actor->_currNumShots || _G(actor[5])._currNumShots)
|
||||
return 0;
|
||||
|
||||
playSound(EXPLODE, true);
|
||||
actorAlwaysShoots(&_G(actor[5]), 0);
|
||||
const int an = _G(actor[5])._shotActor;
|
||||
_G(actor[an])._moveType = 9;
|
||||
|
||||
int r = _G(rand1) % 60;
|
||||
while (expf[r]) {
|
||||
r++;
|
||||
if (r > 59)
|
||||
r = 0;
|
||||
}
|
||||
expf[r] = true;
|
||||
const int x = (EXPLOSION[r] % 20) * 16;
|
||||
const int y = (EXPLOSION[r] / 20) * 16;
|
||||
_G(actor[an])._x = x;
|
||||
_G(actor[an])._y = y;
|
||||
|
||||
_G(scrn)._iconGrid[y / 16][x / 16] = _G(scrn)._backgroundColor;
|
||||
|
||||
_G(actor[3])._i2++;
|
||||
if (_G(actor[3])._i2 > 59) {
|
||||
_G(actor[3])._i1 = 2;
|
||||
_G(actor[3])._i2 = 0;
|
||||
_G(actor[3])._numMoves = 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Boss - skull - shake
|
||||
static int boss2MovementShake(Actor *actor) {
|
||||
int rep, hx;
|
||||
|
||||
if (_G(hammer)->_active && _G(hammer)->_moveType != 5) {
|
||||
hx = _G(hammer)->_x;
|
||||
const int hy = _G(hammer)->_y;
|
||||
for (rep = 7; rep < 15; rep++) {
|
||||
if (!_G(actor[rep])._active)
|
||||
continue;
|
||||
|
||||
if (overlap(hx + 1, hy + 1, hx + 10, hy + 10, _G(actor[rep])._x, _G(actor[rep])._y,
|
||||
_G(actor[rep])._x + _G(actor[rep])._sizeX - 1, _G(actor[rep])._y + _G(actor[rep])._sizeY - 1)) {
|
||||
_G(hammer)->_moveType = 5;
|
||||
_G(hammer)->_dir = reverseDirection(_G(hammer));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (actor->_i4) {
|
||||
actor->_i4--;
|
||||
if (!actor->_i4)
|
||||
_G(thunderSnakeCounter) = 0;
|
||||
}
|
||||
if (!actor->_i2) {
|
||||
if (actor->_x < 144)
|
||||
actor->_x += 2;
|
||||
else if (actor->_x > 144)
|
||||
actor->_x -= 2;
|
||||
else {
|
||||
actor->_i2 = 1;
|
||||
actor->_i3 = 0;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
if (_G(actor[4])._currNumShots)
|
||||
goto done;
|
||||
|
||||
if (!actor->_i3) {
|
||||
actor->_i3 = g_events->getRandomNumber(2, 3);
|
||||
}
|
||||
|
||||
if (actor->_i3 == 2)
|
||||
actor->_x -= 2;
|
||||
else
|
||||
actor->_x += 2;
|
||||
|
||||
if (actor->_x < 20 || actor->_x > 270) {
|
||||
_G(thunderSnakeCounter) = 100;
|
||||
actor->_i4 = 50;
|
||||
playSound(EXPLODE, true);
|
||||
actor->_i2 = 0;
|
||||
|
||||
Common::fill(su, su + 18, 0);
|
||||
actorAlwaysShoots(&_G(actor[4]), 1);
|
||||
int an = _G(actor[4])._shotActor;
|
||||
hx = (_G(thor)->_x / 16);
|
||||
_G(actor[an])._x = _G(thor)->_x; //hx*16;
|
||||
_G(actor[an])._y = g_events->getRandomNumber(15);
|
||||
|
||||
su[hx] = 1;
|
||||
_G(actor[an])._nextFrame = g_events->getRandomNumber(3);
|
||||
for (rep = 0; rep < numSpikes; rep++) {
|
||||
while (true) {
|
||||
hx = g_events->getRandomNumber(17);
|
||||
if (!su[hx])
|
||||
break;
|
||||
}
|
||||
su[hx] = 1;
|
||||
actorAlwaysShoots(&_G(actor[4]), 1);
|
||||
an = _G(actor[4])._shotActor;
|
||||
_G(actor[an])._nextFrame = g_events->getRandomNumber(3);
|
||||
_G(actor[an])._x = 16 + hx * 16;
|
||||
_G(actor[an])._y = g_events->getRandomNumber(15);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
nextFrame(actor);
|
||||
bossSet(actor->_dir, actor->_x, actor->_y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void boss2ClosingSequence1() {
|
||||
musicPlay(6, true);
|
||||
odinSpeaks(1001, 0, "CLOSING");
|
||||
}
|
||||
|
||||
void boss2ClosingSequence2() {
|
||||
_G(thorInfo)._armor = 10;
|
||||
loadNewThor();
|
||||
_G(thor)->_dir = 1;
|
||||
_G(thor)->_nextFrame = 0;
|
||||
|
||||
fillScore(20, "CLOSING");
|
||||
}
|
||||
|
||||
void boss2ClosingSequence3() {
|
||||
fillHealth();
|
||||
fillMagic();
|
||||
odinSpeaks(1002, 0, "CLOSING");
|
||||
}
|
||||
|
||||
void boss2ClosingSequence4() {
|
||||
for (int rep = 0; rep < 16; rep++)
|
||||
_G(scrn)._actorType[rep] = 0;
|
||||
|
||||
_G(bossDead) = false;
|
||||
_G(setup)._bossDead[1] = true;
|
||||
_G(gameOver) = true;
|
||||
_G(bossActive) = false;
|
||||
_G(scrn)._music = 6;
|
||||
|
||||
showLevel(BOSS_LEVEL2);
|
||||
|
||||
#ifdef USE_TTS
|
||||
_G(thorInfo)._previousScore = -1;
|
||||
#endif
|
||||
|
||||
playSound(ANGEL, true);
|
||||
placeTile(18, 10, 152);
|
||||
placeTile(19, 10, 202);
|
||||
actorVisible(1);
|
||||
actorVisible(2);
|
||||
_G(actor[7])._x = 288;
|
||||
_G(actor[7])._y = 160;
|
||||
_G(actor[8])._x = 304;
|
||||
_G(actor[8])._y = 160;
|
||||
|
||||
Level lvl;
|
||||
lvl.load(BOSS_LEVEL2);
|
||||
lvl._iconGrid[6][18] = 152;
|
||||
lvl._iconGrid[6][19] = 202;
|
||||
lvl.save(BOSS_LEVEL2);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
40
engines/got/game/boss2.h
Normal file
40
engines/got/game/boss2.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* 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 GOT_GAME_BOSS2_H
|
||||
#define GOT_GAME_BOSS2_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
// Boss 2 - Skull (Nognir)
|
||||
extern int boss2Movement(Actor *actor);
|
||||
extern void boss2CheckHit(Actor *actor);
|
||||
extern void boss2SetupLevel();
|
||||
extern void boss2ClosingSequence1();
|
||||
extern void boss2ClosingSequence2();
|
||||
extern void boss2ClosingSequence3();
|
||||
extern void boss2ClosingSequence4();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
666
engines/got/game/boss3.cpp
Normal file
666
engines/got/game/boss3.cpp
Normal file
@@ -0,0 +1,666 @@
|
||||
/* 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 "got/game/boss3.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/game/move_patterns.h"
|
||||
#include "got/game/status.h"
|
||||
#include "got/sound.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
#define LFC 10
|
||||
|
||||
static const byte EXPLOSION[4][8] = {
|
||||
{126, 127, 128, 129, 130, 131, 132, 133},
|
||||
{146, 147, 148, 149, 150, 151, 152, 153},
|
||||
{166, 167, 168, 169, 170, 171, 172, 173},
|
||||
{186, 187, 188, 189, 190, 191, 192, 193}
|
||||
};
|
||||
|
||||
static int bossMode;
|
||||
static int numPods1;
|
||||
static byte podSpeed;
|
||||
static bool explosionFlag[4][8];
|
||||
static byte explosionCounter;
|
||||
|
||||
static int bossDie();
|
||||
static void boss3CheckHit();
|
||||
static void bossChangeMode();
|
||||
|
||||
static void setBoss(Actor *actor) {
|
||||
_G(actor[4])._nextFrame = actor->_nextFrame;
|
||||
_G(actor[5])._nextFrame = actor->_nextFrame;
|
||||
_G(actor[6])._nextFrame = actor->_nextFrame;
|
||||
|
||||
_G(actor[4])._lastDir = actor->_dir;
|
||||
_G(actor[5])._lastDir = actor->_dir;
|
||||
_G(actor[6])._lastDir = actor->_dir;
|
||||
_G(actor[4])._dir = actor->_dir;
|
||||
_G(actor[5])._dir = actor->_dir;
|
||||
_G(actor[6])._dir = actor->_dir;
|
||||
|
||||
_G(actor[4])._x = actor->_x + 16;
|
||||
_G(actor[4])._y = actor->_y;
|
||||
_G(actor[5])._x = actor->_x;
|
||||
_G(actor[5])._y = actor->_y + 16;
|
||||
_G(actor[6])._x = actor->_x + 16;
|
||||
_G(actor[6])._y = actor->_y + 16;
|
||||
}
|
||||
|
||||
// Boss - Loki-2
|
||||
static int boss3Movement1(Actor *actor) {
|
||||
int rx, ry, i, numPods = 0;
|
||||
int fcount;
|
||||
|
||||
actor->_numMoves = 2;
|
||||
podSpeed = 2;
|
||||
|
||||
switch (_G(setup)._difficultyLevel) {
|
||||
case 0:
|
||||
numPods = 3;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
numPods = 5;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
numPods = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!actor->_temp1) {
|
||||
// Disappear
|
||||
actor->_dir = 1;
|
||||
actor->_frameCount = LFC;
|
||||
actor->_nextFrame = 0;
|
||||
actor->_temp1 = 1;
|
||||
actor->_i6 = 1;
|
||||
actor->_solid |= 128;
|
||||
_G(actor[4])._solid |= 128;
|
||||
_G(actor[5])._solid |= 128;
|
||||
_G(actor[6])._solid |= 128;
|
||||
playSound(EXPLODE, true);
|
||||
goto done;
|
||||
}
|
||||
if (actor->_i6) {
|
||||
// Fade out
|
||||
fcount = actor->_frameCount - 1;
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 2) {
|
||||
actor->_i6 = 0;
|
||||
actor->_temp3 = 160;
|
||||
}
|
||||
actor->_frameCount = 3;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
|
||||
goto done1;
|
||||
}
|
||||
if (actor->_temp3 > 1) {
|
||||
actor->_temp3--;
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (actor->_temp3) {
|
||||
for (i = 0; i < numPods1; i++)
|
||||
if (_G(actor[19 + i])._active)
|
||||
goto done1;
|
||||
|
||||
while (true) {
|
||||
rx = g_events->getRandomNumber(255) + 16;
|
||||
ry = g_events->getRandomNumber(143);
|
||||
if (!overlap(rx, ry, rx + 32, ry + 32, _G(thorX1), _G(thorY1), _G(thorX2), _G(thorY2)))
|
||||
break;
|
||||
}
|
||||
|
||||
actor->_x = rx;
|
||||
actor->_y = ry;
|
||||
actor->_frameCount = LFC;
|
||||
actor->_temp4 = 40;
|
||||
actor->_temp3 = 0;
|
||||
playSound(EXPLODE, true);
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (actor->_temp4) {
|
||||
// Fade in
|
||||
fcount = actor->_frameCount - 1;
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame--;
|
||||
if (actor->_nextFrame > 254) {
|
||||
actor->_nextFrame = 0;
|
||||
actor->_dir = 0;
|
||||
actor->_temp4 = 0;
|
||||
actor->_temp5 = 80;
|
||||
actor->_solid &= 0x7f;
|
||||
_G(actor[4])._solid &= 0x7f;
|
||||
_G(actor[5])._solid &= 0x7f;
|
||||
_G(actor[6])._solid &= 0x7f;
|
||||
}
|
||||
|
||||
actor->_frameCount = 3;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (actor->_temp5) {
|
||||
// Shoot
|
||||
actor->_temp5--;
|
||||
if (actor->_temp5 == 20) {
|
||||
actor->_nextFrame = 3;
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (!actor->_temp5) {
|
||||
if (_G(actor[4])._currNumShots < _G(actor[4])._numShotsAllowed) {
|
||||
actorAlwaysShoots(&_G(actor[4]), 0);
|
||||
const byte shot_actor = _G(actor[4])._shotActor;
|
||||
_G(actor[shot_actor])._numMoves = podSpeed;
|
||||
_G(actor[shot_actor])._x = actor->_x + 8;
|
||||
_G(actor[shot_actor])._y = actor->_y + 16;
|
||||
_G(actor[shot_actor])._temp5 = 0;
|
||||
for (i = 0; i < numPods; i++)
|
||||
_G(actor[20 + i]) = _G(actor[19]);
|
||||
|
||||
numPods1 = numPods;
|
||||
actor->_temp1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (actor->_temp5 < 31)
|
||||
goto done1;
|
||||
}
|
||||
|
||||
done:
|
||||
fcount = actor->_frameCount - 1;
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 2)
|
||||
actor->_nextFrame = 0;
|
||||
actor->_frameCount = LFC;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
|
||||
done1:
|
||||
setBoss(actor);
|
||||
return actor->_dir;
|
||||
}
|
||||
|
||||
// Boss - Loki-1
|
||||
int boss3Movement(Actor *actor) {
|
||||
int x1, y1, ox, oy;
|
||||
int fcount;
|
||||
|
||||
|
||||
if (actor->_temp2)
|
||||
actor->_temp2--;
|
||||
if (_G(bossDead))
|
||||
return bossDie();
|
||||
boss3CheckHit();
|
||||
|
||||
if (!bossMode)
|
||||
return boss3Movement1(actor);
|
||||
numPods1 = 10;
|
||||
switch (_G(setup)._difficultyLevel) {
|
||||
case 0:
|
||||
actor->_numMoves = 3;
|
||||
actor->_speed = 2;
|
||||
break;
|
||||
case 1:
|
||||
actor->_numMoves = 2;
|
||||
actor->_speed = 1;
|
||||
break;
|
||||
case 2:
|
||||
actor->_numMoves = 5;
|
||||
actor->_speed = 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int d = actor->_lastDir;
|
||||
actor->_temp3++;
|
||||
|
||||
int f = 0;
|
||||
if (actor->_temp4) {
|
||||
actor->_temp4--;
|
||||
if (!actor->_temp4) {
|
||||
actor->_temp3 = 0;
|
||||
_G(actor[3])._frameSpeed = 4;
|
||||
_G(actor[3])._dir = 0;
|
||||
_G(actor[3])._lastDir = 0;
|
||||
_G(actor[3])._nextFrame = 3;
|
||||
_G(actor[4])._dir = 0;
|
||||
_G(actor[4])._lastDir = 0;
|
||||
_G(actor[4])._nextFrame = 3;
|
||||
}
|
||||
goto skip_move;
|
||||
}
|
||||
|
||||
if (actor->_edgeCounter)
|
||||
actor->_edgeCounter--;
|
||||
else
|
||||
goto new_dir;
|
||||
|
||||
if (overlap(actor->_x + 2, actor->_y + 8, actor->_x + 30, actor->_y + 30, _G(thor)->_x, _G(thor)->_y + 4, _G(thor)->_x + 15, _G(thor)->_y + 15))
|
||||
thorDamaged(actor);
|
||||
|
||||
ox = actor->_x;
|
||||
oy = actor->_y;
|
||||
switch (actor->_temp5) {
|
||||
case 0:
|
||||
x1 = _G(actor[3])._x;
|
||||
y1 = _G(actor[3])._y - 2;
|
||||
if (!checkMove2(x1, y1, &_G(actor[3]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
if (!checkMove2(x1 + 16, y1, &_G(actor[4])))
|
||||
f = 1;
|
||||
actor->_y = oy - 2;
|
||||
break;
|
||||
case 1:
|
||||
x1 = _G(actor[5])._x;
|
||||
y1 = _G(actor[5])._y + 2;
|
||||
if (!checkMove2(x1, y1, &_G(actor[5]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
if (!checkMove2(x1 + 16, y1, &_G(actor[6])))
|
||||
f = 1;
|
||||
actor->_y = oy + 2;
|
||||
break;
|
||||
case 2:
|
||||
x1 = _G(actor[3])._x - 2;
|
||||
y1 = _G(actor[3])._y;
|
||||
if (!checkMove2(x1, y1, &_G(actor[3]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
if (!checkMove2(x1, y1 + 16, &_G(actor[5])))
|
||||
f = 1;
|
||||
actor->_x = ox - 2;
|
||||
break;
|
||||
case 3:
|
||||
x1 = _G(actor[4])._x + 2;
|
||||
y1 = _G(actor[4])._y;
|
||||
if (!checkMove2(x1, y1, &_G(actor[4]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
if (!checkMove2(x1, y1 + 16, &_G(actor[6])))
|
||||
f = 1;
|
||||
actor->_x = ox + 2;
|
||||
break;
|
||||
case 4: //ul
|
||||
x1 = _G(actor[3])._x - 2;
|
||||
y1 = _G(actor[3])._y - 2;
|
||||
if (!checkMove2(x1, y1, &_G(actor[3]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
actor->_x = ox - 2;
|
||||
actor->_y = oy - 2;
|
||||
break;
|
||||
case 5:
|
||||
x1 = _G(actor[4])._x + 2;
|
||||
y1 = _G(actor[4])._y - 2;
|
||||
if (!checkMove2(x1, y1, &_G(actor[4]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
actor->_x = ox + 2;
|
||||
actor->_y = oy - 2;
|
||||
break;
|
||||
case 6:
|
||||
x1 = _G(actor[6])._x + 2;
|
||||
y1 = _G(actor[6])._y + 2;
|
||||
if (!checkMove2(x1, y1, &_G(actor[6]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
actor->_x = ox + 2;
|
||||
actor->_y = oy + 2;
|
||||
break;
|
||||
case 7:
|
||||
x1 = _G(actor[5])._x - 2;
|
||||
y1 = _G(actor[5])._y + 2;
|
||||
if (!checkMove2(x1, y1, &_G(actor[5]))) {
|
||||
f = 1;
|
||||
break;
|
||||
}
|
||||
actor->_x = ox - 2;
|
||||
actor->_y = oy + 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
fcount = actor->_frameCount - 1;
|
||||
if (fcount) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 2)
|
||||
actor->_nextFrame = 0;
|
||||
actor->_frameCount = 30;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
|
||||
skip_move:
|
||||
|
||||
setBoss(actor);
|
||||
if (!f)
|
||||
goto done;
|
||||
|
||||
new_dir:
|
||||
if (actor->_temp3 < 120)
|
||||
goto new_dir1;
|
||||
|
||||
_G(actor[3])._frameSpeed = 8;
|
||||
_G(actor[3])._nextFrame = 3;
|
||||
_G(actor[4])._nextFrame = 3;
|
||||
actor->_temp4 = 120;
|
||||
actorAlwaysShoots(actor, 0);
|
||||
_G(actor[actor->_shotActor])._x = actor->_x + 8;
|
||||
_G(actor[actor->_shotActor])._y = actor->_y - 8;
|
||||
_G(actor[actor->_shotActor])._temp1 = g_events->getRandomNumber(90, 189);
|
||||
_G(actor[actor->_shotActor])._temp5 = 30;
|
||||
_G(actor[actor->_shotActor])._speed = 2;
|
||||
playSound(BOSS12, true);
|
||||
|
||||
new_dir1:
|
||||
actor->_temp5 = _G(rand1) % 8;
|
||||
actor->_edgeCounter = _G(rand2) + 60;
|
||||
|
||||
done:
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
static void boss3CheckHit() {
|
||||
if (_G(actor[3])._solid & 128) {
|
||||
for (int rep = 3; rep < 7; rep++)
|
||||
_G(actor[rep])._magicHit = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
if (_G(actor[3])._magicHit || _G(actor[4])._magicHit || _G(actor[5])._magicHit || _G(actor[6])._magicHit) {
|
||||
if (!_G(actor[3])._temp2) {
|
||||
actorDamaged(&_G(actor[3]), 10);
|
||||
|
||||
if (_G(cheat) && _G(keyFlag[GOT_Z]))
|
||||
_G(actor[3])._health -= 50;
|
||||
else
|
||||
_G(actor[3])._health -= 10;
|
||||
|
||||
_G(actor[3])._moveCountdown = 50;
|
||||
|
||||
_G(actor[3])._vulnerableCountdown = 50;
|
||||
playSound(BOSS13, true);
|
||||
|
||||
for (int rep = 4; rep < 7; rep++) {
|
||||
_G(actor[rep])._magicHit = 0;
|
||||
_G(actor[rep])._nextFrame = 1;
|
||||
_G(actor[rep])._moveCountdown = 50;
|
||||
}
|
||||
|
||||
if (_G(actor[3])._health == 0) {
|
||||
_G(bossDead) = true;
|
||||
for (int rep = 7; rep < MAX_ACTORS; rep++) {
|
||||
if (_G(actor[rep])._active)
|
||||
actorDestroyed(&_G(actor[rep]));
|
||||
}
|
||||
}
|
||||
|
||||
if (_G(actor[3])._health == 50) {
|
||||
bossChangeMode();
|
||||
_G(actor[3])._temp1 = 0;
|
||||
_G(actor[3])._temp2 = 0;
|
||||
_G(actor[3])._temp3 = 0;
|
||||
_G(actor[3])._temp4 = 0;
|
||||
_G(actor[3])._temp5 = 0;
|
||||
_G(actor[3])._i6 = 0;
|
||||
_G(actor[3])._moveCountdown = 2;
|
||||
} else {
|
||||
_G(actor[3])._temp2 = 40;
|
||||
}
|
||||
}
|
||||
for (int rep = 3; rep < 7; rep++)
|
||||
_G(actor[rep])._magicHit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void bossChangeMode() {
|
||||
if (!_G(bossIntro2)) {
|
||||
Gfx::Pics loki("FACE18", 262);
|
||||
executeScript(1003, loki);
|
||||
_G(bossIntro2) = true;
|
||||
}
|
||||
|
||||
bossMode = 0;
|
||||
}
|
||||
|
||||
void boss3SetupLevel() {
|
||||
setupBoss(3);
|
||||
_G(bossActive) = true;
|
||||
musicPause();
|
||||
playSound(BOSS11, true);
|
||||
|
||||
g_events->send("Game", GameMessage("PAUSE", 40));
|
||||
|
||||
if (!_G(bossIntro1)) {
|
||||
Gfx::Pics loki("FACE18", 262);
|
||||
executeScript(1002, loki);
|
||||
_G(bossIntro1) = true;
|
||||
}
|
||||
|
||||
musicPlay(7, true);
|
||||
_G(appleDropCounter) = 0;
|
||||
bossMode = 1;
|
||||
}
|
||||
|
||||
static int bossDie() {
|
||||
if (_G(bossDead)) {
|
||||
for (int rep = 0; rep < 4; rep++) {
|
||||
const int x1 = _G(actor[3 + rep])._lastX[_G(pge)];
|
||||
const int y1 = _G(actor[3 + rep])._lastY[_G(pge)];
|
||||
const int x = _G(actor[3 + rep])._x;
|
||||
const int y = _G(actor[3 + rep])._y;
|
||||
const int n = _G(actor[3 + rep])._actorNum;
|
||||
const int r = _G(actor[3 + rep])._dropRating;
|
||||
|
||||
_G(actor[3 + rep]) = _G(explosion);
|
||||
|
||||
_G(actor[3 + rep])._actorNum = n;
|
||||
_G(actor[3 + rep])._dropRating = r;
|
||||
_G(actor[3 + rep])._x = x;
|
||||
_G(actor[3 + rep])._y = y;
|
||||
_G(actor[3 + rep])._lastX[_G(pge)] = x1;
|
||||
_G(actor[3 + rep])._lastX[_G(pge) ^ 1] = x;
|
||||
_G(actor[3 + rep])._lastY[_G(pge)] = y1;
|
||||
_G(actor[3 + rep])._lastY[_G(pge) ^ 1] = y;
|
||||
_G(actor[3 + rep])._active = true;
|
||||
_G(actor[3 + rep])._vulnerableCountdown = 255;
|
||||
_G(actor[3 + rep])._moveType = 6;
|
||||
_G(actor[3 + rep])._nextFrame = rep;
|
||||
_G(actor[3 + rep])._speed = g_events->getRandomNumber(6, 8);
|
||||
_G(actor[3 + rep])._currNumShots = (10 - _G(actor[3 + rep])._speed) * 10;
|
||||
_G(actor[3 + rep])._moveCountdown = _G(actor[3 + rep])._speed;
|
||||
}
|
||||
|
||||
playSound(EXPLODE, true);
|
||||
_G(bossDead) = true;
|
||||
}
|
||||
|
||||
return _G(actor[3])._lastDir;
|
||||
}
|
||||
|
||||
void boss3ClosingSequence1() {
|
||||
musicPlay(6, true);
|
||||
odinSpeaks(1001, 0, "CLOSING");
|
||||
}
|
||||
|
||||
void boss3ClosingSequence2() {
|
||||
fillScore(20, "CLOSING");
|
||||
}
|
||||
|
||||
void boss3ClosingSequence3() {
|
||||
fillHealth();
|
||||
fillMagic();
|
||||
|
||||
for (int rep = 0; rep < 16; rep++)
|
||||
_G(scrn)._actorType[rep] = 0;
|
||||
|
||||
_G(bossDead) = false;
|
||||
_G(setup)._bossDead[2] = true;
|
||||
_G(gameOver) = true;
|
||||
_G(bossActive) = false;
|
||||
_G(scrn)._music = 6;
|
||||
showLevel(BOSS_LEVEL3);
|
||||
|
||||
#ifdef USE_TTS
|
||||
_G(thorInfo)._previousScore = -1;
|
||||
#endif
|
||||
|
||||
_G(exitFlag) = 0;
|
||||
musicPause();
|
||||
|
||||
_G(newLevel) = ENDING_SCREEN;
|
||||
_G(thor)->_x = 152;
|
||||
_G(thor)->_y = 160;
|
||||
_G(thor)->_dir = 1;
|
||||
}
|
||||
|
||||
void endingScreen() {
|
||||
for (int i = 3; i < MAX_ACTORS; i++)
|
||||
_G(actor[i])._moveType = 1;
|
||||
|
||||
musicPlay(6, true);
|
||||
|
||||
memset(explosionFlag, 0, sizeof(explosionFlag));
|
||||
_G(endGame) = 1;
|
||||
|
||||
_G(explosionRow) = 0;
|
||||
explosionCounter = 0;
|
||||
|
||||
_G(actor[34]) = _G(explosion);
|
||||
_G(actor[34])._active = false;
|
||||
_G(actor[34])._speed = 2;
|
||||
_G(actor[34])._moveCountdown = _G(actor[34])._speed;
|
||||
_G(actor[34])._currNumShots = 3; // Used to reverse explosion
|
||||
_G(actor[34])._vulnerableCountdown = 255;
|
||||
_G(actor[34])._i2 = 6;
|
||||
}
|
||||
|
||||
// Explode
|
||||
int endgame_one() {
|
||||
if (_G(actor[34])._i2) {
|
||||
_G(actor[34])._i2--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_G(actor[34])._i2 = 6;
|
||||
playSound(EXPLODE, true);
|
||||
|
||||
int r = _G(rand1) % 32;
|
||||
while (explosionFlag[r / 8][r % 8]) {
|
||||
r++;
|
||||
if (r > 31)
|
||||
r = 0;
|
||||
}
|
||||
explosionFlag[r / 8][r % 8] = true;
|
||||
int x = (EXPLOSION[r / 8][r % 8] % 20) * 16;
|
||||
int y = (EXPLOSION[r / 8][r % 8] / 20) * 16;
|
||||
_G(actor[34])._x = x;
|
||||
_G(actor[34])._y = y;
|
||||
_G(actor[34])._active = true;
|
||||
_G(actor[34])._nextFrame = 0;
|
||||
_G(actor[34])._currNumShots = 3;
|
||||
|
||||
_G(scrn)._iconGrid[y / 16][x / 16] = _G(scrn)._backgroundColor;
|
||||
|
||||
_G(endGame++);
|
||||
if (_G(endGame) > 32) {
|
||||
_G(actor[34])._active = false;
|
||||
_G(endGame) = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Explode
|
||||
int endGameMovement() {
|
||||
if (!_G(endGame))
|
||||
return 0;
|
||||
if (explosionCounter > 3) {
|
||||
endgame_one();
|
||||
return 0;
|
||||
}
|
||||
if (_G(actor[34])._i2) {
|
||||
_G(actor[34])._i2--;
|
||||
return 0;
|
||||
}
|
||||
_G(actor[34])._i2 = 6;
|
||||
playSound(EXPLODE, true);
|
||||
|
||||
int r = _G(rand1) % 8;
|
||||
while (explosionFlag[_G(explosionRow)][r]) {
|
||||
r++;
|
||||
if (r > 7)
|
||||
r = 0;
|
||||
}
|
||||
explosionFlag[_G(explosionRow)][r] = true;
|
||||
const int x = (EXPLOSION[_G(explosionRow)][r] % 20) * 16;
|
||||
const int y = (EXPLOSION[_G(explosionRow)][r] / 20) * 16;
|
||||
_G(actor[34])._x = x;
|
||||
_G(actor[34])._y = y;
|
||||
_G(actor[34])._active = true;
|
||||
_G(actor[34])._nextFrame = 0;
|
||||
_G(actor[34])._currNumShots = 3;
|
||||
|
||||
_G(scrn)._iconGrid[y / 16][x / 16] = _G(scrn)._backgroundColor;
|
||||
_G(scrn)._iconGrid[(y / 16) - 4][x / 16] = _G(scrn)._backgroundColor;
|
||||
|
||||
_G(endGame++);
|
||||
if (_G(endGame) > 8) {
|
||||
_G(endGame) = 1;
|
||||
_G(explosionRow++);
|
||||
explosionCounter++;
|
||||
if (explosionCounter > 3) {
|
||||
memset(explosionFlag, 0, sizeof(explosionFlag));
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
40
engines/got/game/boss3.h
Normal file
40
engines/got/game/boss3.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* 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 GOT_GAME_BOSS3_H
|
||||
#define GOT_GAME_BOSS3_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
// Boss 3 - Loki
|
||||
extern int boss3Movement(Actor *actor);
|
||||
extern void boss3SetupLevel();
|
||||
extern void endingScreen();
|
||||
extern void boss3ClosingSequence1();
|
||||
extern void boss3ClosingSequence2();
|
||||
extern void boss3ClosingSequence3();
|
||||
extern int endGameMovement();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
118
engines/got/game/init.cpp
Normal file
118
engines/got/game/init.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/* 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 "got/game/init.h"
|
||||
#include "common/memstream.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/gfx/image.h"
|
||||
#include "got/sound.h"
|
||||
#include "got/utils/file.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
void setupPlayer() {
|
||||
_G(thorInfo).clear();
|
||||
_G(thorInfo)._inventory = 0;
|
||||
if (_G(area) > 1)
|
||||
_G(thorInfo)._inventory |= APPLE_MAGIC + LIGHTNING_MAGIC;
|
||||
if (_G(area) > 2)
|
||||
_G(thorInfo)._inventory |= BOOTS_MAGIC + WIND_MAGIC;
|
||||
|
||||
_G(thor)->_health = 150;
|
||||
_G(thorInfo)._magic = _G(area) > 1 ? 150 : 0;
|
||||
_G(thorInfo)._jewels = 0;
|
||||
_G(thorInfo)._score = 0;
|
||||
_G(thorInfo)._keys = 0;
|
||||
_G(thorInfo)._lastItem = 0;
|
||||
_G(thorInfo)._object = 0;
|
||||
_G(thorInfo)._objectName = nullptr;
|
||||
_G(thor)->_lastX[0] = _G(thor)->_x;
|
||||
_G(thor)->_lastX[1] = _G(thor)->_x;
|
||||
_G(thor)->_lastY[0] = _G(thor)->_y;
|
||||
_G(thor)->_lastY[1] = _G(thor)->_y;
|
||||
_G(thorInfo)._lastIcon = (6 * 20) + 8;
|
||||
_G(thorInfo)._lastScreen = 23;
|
||||
_G(thor)->_dir = 1;
|
||||
|
||||
switch (_G(area)) {
|
||||
case 1:
|
||||
_G(thor)->_x = 152;
|
||||
_G(thor)->_y = 96;
|
||||
break;
|
||||
case 2:
|
||||
_G(thor)->_x = 32;
|
||||
_G(thor)->_y = 32;
|
||||
break;
|
||||
case 3:
|
||||
_G(thor)->_x = 272;
|
||||
_G(thor)->_y = 80;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void initGame() {
|
||||
if (_G(area) == 2)
|
||||
_G(thorInfo)._armor = 1;
|
||||
if (_G(area) == 3)
|
||||
_G(thorInfo)._armor = 10;
|
||||
loadStandardActors();
|
||||
setupPlayer();
|
||||
|
||||
if (_G(demo)) {
|
||||
g_vars->setArea(1);
|
||||
_G(thor)->_health = 100;
|
||||
_G(thorInfo)._magic = 100;
|
||||
_G(thorInfo)._jewels = 463;
|
||||
_G(thorInfo)._score = 12455;
|
||||
_G(setup)._difficultyLevel = 0;
|
||||
_G(thorInfo)._inventory = 1 + 2;
|
||||
_G(currentLevel) = 54;
|
||||
_G(thorInfo)._selectedItem = 2;
|
||||
|
||||
File f("DEMO");
|
||||
_G(demoKeys).clear();
|
||||
for (int i = 0; i < DEMO_LEN; ++i)
|
||||
_G(demoKeys).push(f.readByte());
|
||||
|
||||
// Drop the first six bytes off. This comprises of
|
||||
// the "part I" display in the original, and ScummVM
|
||||
// doesn't do demo key processing until the game view
|
||||
for (int i = 0; i < 6; ++i)
|
||||
_G(demoKeys).pop();
|
||||
}
|
||||
|
||||
_G(thor)->_moveCountdown = 6;
|
||||
|
||||
// Load level data
|
||||
_G(newLevel) = _G(currentLevel);
|
||||
_G(scrn).load(_G(currentLevel));
|
||||
showLevel(_G(currentLevel));
|
||||
|
||||
g_vars->resetEndGameFlags();
|
||||
_G(startup) = false;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
34
engines/got/game/init.h
Normal file
34
engines/got/game/init.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/* 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 GOT_GAME_INIT_H
|
||||
#define GOT_GAME_INIT_H
|
||||
|
||||
namespace Got {
|
||||
|
||||
/**
|
||||
* Handles in-game initialization the first time
|
||||
*/
|
||||
extern void initGame();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
80
engines/got/game/main.cpp
Normal file
80
engines/got/game/main.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/* 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/memstream.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/vars.h"
|
||||
#include "got/gfx/image.h" // loadNewThor
|
||||
|
||||
namespace Got {
|
||||
|
||||
void setupLoad() {
|
||||
_G(thor)->_active = true;
|
||||
_G(newLevel) = _G(thorInfo)._lastScreen;
|
||||
_G(thor)->_x = (_G(thorInfo)._lastIcon % 20) * 16;
|
||||
_G(thor)->_y = ((_G(thorInfo)._lastIcon / 20) * 16) - 1;
|
||||
if (_G(thor)->_x < 1)
|
||||
_G(thor)->_x = 1;
|
||||
if (_G(thor)->_y < 0)
|
||||
_G(thor)->_y = 0;
|
||||
_G(thor)->_lastX[0] = _G(thor)->_x;
|
||||
_G(thor)->_lastX[1] = _G(thor)->_x;
|
||||
_G(thor)->_lastY[0] = _G(thor)->_y;
|
||||
_G(thor)->_lastY[1] = _G(thor)->_y;
|
||||
_G(thor)->_dir = _G(thorInfo)._lastDir;
|
||||
_G(thor)->_lastDir = _G(thorInfo)._lastDir;
|
||||
_G(thor)->_health = _G(thorInfo)._lastHealth;
|
||||
_G(thorInfo)._magic = _G(thorInfo)._lastMagic;
|
||||
_G(thorInfo)._jewels = _G(thorInfo)._lastJewels;
|
||||
_G(thorInfo)._keys = _G(thorInfo)._lastKeys;
|
||||
_G(thorInfo)._score = _G(thorInfo)._lastScore;
|
||||
_G(thorInfo)._selectedItem = _G(thorInfo)._lastItem;
|
||||
_G(thorInfo)._inventory = _G(thorInfo)._lastInventory;
|
||||
_G(thorInfo)._object = _G(thorInfo)._lastObject;
|
||||
_G(thorInfo)._objectName = _G(thorInfo)._lastObjectName;
|
||||
_G(thor)->_numMoves = 1;
|
||||
_G(thor)->_vulnerableCountdown = 60;
|
||||
_G(thor)->_show = 60;
|
||||
_G(appleFlag) = false;
|
||||
_G(thunderSnakeCounter) = 0;
|
||||
_G(tornadoUsed) = false;
|
||||
_G(shieldOn) = false;
|
||||
_G(actor[1])._active = false;
|
||||
_G(actor[2])._active = false;
|
||||
_G(thor)->_moveCountdown = 6;
|
||||
|
||||
_G(scrn).load(_G(newLevel));
|
||||
|
||||
_G(currentLevel) = _G(newLevel);
|
||||
showLevel(_G(newLevel));
|
||||
|
||||
if (_G(area) == 2 && _G(currentLevel) == 105) { // Shovel Maze
|
||||
_G(thorInfo)._armor = 2; // eyeballs mode
|
||||
loadNewThor();
|
||||
_G(eyeballs) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void pause(int delay) {
|
||||
g_system->delayMillis(delay);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
32
engines/got/game/main.h
Normal file
32
engines/got/game/main.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* 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 GOT_GAME_MAIN_H
|
||||
#define GOT_GAME_MAIN_H
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern void setupLoad();
|
||||
extern void pause(int delay);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
380
engines/got/game/move.cpp
Normal file
380
engines/got/game/move.cpp
Normal file
@@ -0,0 +1,380 @@
|
||||
/* 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 "got/game/move.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/game/move_patterns.h"
|
||||
#include "got/game/shot_movement.h"
|
||||
#include "got/game/shot_pattern.h"
|
||||
#include "got/game/status.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
void nextFrame(Actor *actor) {
|
||||
const int fcount = actor->_frameCount - 1;
|
||||
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame++;
|
||||
|
||||
if (actor->_nextFrame > 3)
|
||||
actor->_nextFrame = 0;
|
||||
|
||||
actor->_frameCount = actor->_frameSpeed;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
}
|
||||
|
||||
bool pointWithin(int x, int y, int x1, int y1, int x2, int y2) {
|
||||
return ((x >= x1) && (x <= x2) && (y >= y1) && (y <= y2));
|
||||
}
|
||||
|
||||
bool overlap(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
if ((x1 >= x3) && (x1 <= x4) && (y1 >= y3) && (y1 <= y4))
|
||||
return true;
|
||||
if ((x2 >= x3) && (x2 <= x4) && (y2 >= y3) && (y2 <= y4))
|
||||
return true;
|
||||
if ((x1 >= x3) && (x1 <= x4) && (y2 >= y3) && (y2 <= y4))
|
||||
return true;
|
||||
if ((x2 >= x3) && (x2 <= x4) && (y1 >= y3) && (y1 <= y4))
|
||||
return true;
|
||||
if ((x3 >= x1) && (x3 <= x2) && (y3 >= y1) && (y3 <= y2))
|
||||
return true;
|
||||
if ((x4 >= x1) && (x4 <= x2) && (y4 >= y1) && (y4 <= y2))
|
||||
return true;
|
||||
if ((x3 >= x1) && (x3 <= x2) && (y4 >= y1) && (y4 <= y2))
|
||||
return true;
|
||||
if ((x4 >= x1) && (x4 <= x2) && (y3 >= y1) && (y3 <= y2))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int reverseDirection(Actor *actor) {
|
||||
if (actor->_dir == 1)
|
||||
return 0;
|
||||
if (actor->_dir == 2)
|
||||
return 3;
|
||||
if (actor->_dir == 3)
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void thorShoots() {
|
||||
if (!_G(hammer)->_active && (!_G(hammer)->_dead) && (!_G(thor)->_shotCountdown)) {
|
||||
playSound(SWISH, false);
|
||||
_G(thor)->_shotCountdown = 20;
|
||||
_G(hammer)->_active = true;
|
||||
_G(hammer)->_dir = _G(thor)->_dir;
|
||||
_G(hammer)->_lastDir = _G(thor)->_dir;
|
||||
_G(hammer)->_x = _G(thor)->_x;
|
||||
_G(hammer)->_y = _G(thor)->_y + 2;
|
||||
_G(hammer)->_moveType = 2;
|
||||
_G(hammer)->_nextFrame = 0;
|
||||
_G(hammer)->_lastX[0] = _G(hammer)->_x;
|
||||
_G(hammer)->_lastX[1] = _G(hammer)->_x;
|
||||
_G(hammer)->_lastY[0] = _G(hammer)->_y;
|
||||
_G(hammer)->_lastY[1] = _G(hammer)->_y;
|
||||
}
|
||||
}
|
||||
|
||||
int killGoodGuy() {
|
||||
if (!_G(killGoodGuyInform) && !_G(thunderSnakeCounter)) {
|
||||
odinSpeaks(2010, 0);
|
||||
_G(killGoodGuyInform) = true;
|
||||
}
|
||||
|
||||
addScore(-1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void actorDamaged(Actor *actor, int damage) {
|
||||
if (!_G(setup)._difficultyLevel)
|
||||
damage *= 2;
|
||||
else if (_G(setup)._difficultyLevel == 2)
|
||||
damage /= 2;
|
||||
|
||||
if (!actor->_vulnerableCountdown && actor->_type != 3 && (actor->_solid & 0x7f) != 2) {
|
||||
actor->_vulnerableCountdown = STAMINA;
|
||||
if (damage >= actor->_health) {
|
||||
if (actor->_type != 4) {
|
||||
addScore(actor->_initHealth * 10);
|
||||
|
||||
} else {
|
||||
killGoodGuy();
|
||||
}
|
||||
|
||||
actorDestroyed(actor);
|
||||
} else {
|
||||
actor->_show = 10;
|
||||
actor->_health -= damage;
|
||||
actor->_moveCountdown += 8;
|
||||
}
|
||||
} else if (!actor->_vulnerableCountdown) {
|
||||
actor->_vulnerableCountdown = STAMINA;
|
||||
|
||||
if (actor->_funcNum == 4) {
|
||||
switchIcons();
|
||||
}
|
||||
if (actor->_funcNum == 7) {
|
||||
rotateArrows();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void thorDamaged(Actor *actor) {
|
||||
actor->_hitThor = true;
|
||||
|
||||
// If we're invincible, ignore any damage
|
||||
if (_G(cheats)._freezeHealth)
|
||||
return;
|
||||
|
||||
if (GAME3 && actor->_funcNum == 11) {
|
||||
if (actor->_talkCounter) {
|
||||
actor->_talkCounter--;
|
||||
return;
|
||||
}
|
||||
|
||||
const int currType = actor->_type;
|
||||
actor->_type = 4;
|
||||
actorSpeaks(actor, 0, 0);
|
||||
actor->_type = currType;
|
||||
actor->_talkCounter = 30;
|
||||
return;
|
||||
}
|
||||
|
||||
int damage = actor->_hitStrength;
|
||||
if (damage != 255) {
|
||||
if (!_G(setup)._difficultyLevel)
|
||||
damage /= 2;
|
||||
else if (_G(setup)._difficultyLevel == 2)
|
||||
damage *= 2;
|
||||
}
|
||||
if ((!_G(thor)->_vulnerableCountdown && !_G(shieldOn)) || damage == 255) {
|
||||
if (damage >= _G(thor)->_health) {
|
||||
_G(thor)->_vulnerableCountdown = 40;
|
||||
_G(thor)->_show = 0;
|
||||
_G(thor)->_health = 0;
|
||||
_G(exitFlag) = 2;
|
||||
g_events->send(GameMessage("THOR_DIES"));
|
||||
} else if (damage) {
|
||||
_G(thor)->_vulnerableCountdown = 40;
|
||||
_G(sound).playSound(OW, false);
|
||||
_G(thor)->_show = 10;
|
||||
_G(thor)->_health -= damage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void actorDestroyed(Actor *actor) {
|
||||
if (actor->_actorNum > 2) {
|
||||
const int curPage = _G(pge);
|
||||
|
||||
const int x = actor->_lastX[curPage ^ 1];
|
||||
const int y = actor->_lastY[curPage ^ 1];
|
||||
const int x1 = actor->_lastX[curPage];
|
||||
const int y1 = actor->_lastY[curPage];
|
||||
const int r = actor->_dropRating;
|
||||
const int n = actor->_actorNum;
|
||||
const int t = actor->_type;
|
||||
|
||||
if (actor->_funcNum == 255)
|
||||
actor->copyFixedAndPics(_G(explosion));
|
||||
else
|
||||
actor->copyFixedAndPics(_G(sparkle));
|
||||
|
||||
actor->_type = t;
|
||||
actor->_actorNum = n;
|
||||
actor->_dropRating = r;
|
||||
actor->_x = x;
|
||||
actor->_y = y;
|
||||
actor->_lastX[curPage] = x1;
|
||||
actor->_lastX[curPage ^ 1] = x;
|
||||
actor->_lastY[curPage] = y1;
|
||||
actor->_lastY[curPage ^ 1] = y;
|
||||
actor->_moveCountdown = actor->_speed;
|
||||
actor->_active = true;
|
||||
actor->_currNumShots = 3; // used to reverse explosion
|
||||
actor->_vulnerableCountdown = 255;
|
||||
} else {
|
||||
actor->_dead = 2;
|
||||
actor->_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
int _actor_shoots(Actor *actor, int dir) {
|
||||
const int t = actor->_shotType - 1;
|
||||
for (int i = MAX_ENEMIES + 3; i < MAX_ACTORS; i++) {
|
||||
if ((!_G(actor[i])._active) && (!_G(actor[i])._dead)) {
|
||||
Actor *act = &_G(actor[i]);
|
||||
*act = _G(shot[t]);
|
||||
int cx, cy;
|
||||
|
||||
if (actor->_sizeY < act->_sizeY)
|
||||
cy = actor->_y - ((act->_sizeY - actor->_sizeY) / 2);
|
||||
else
|
||||
cy = actor->_y + ((actor->_sizeY - act->_sizeY) / 2);
|
||||
|
||||
if (actor->_sizeX < act->_sizeX)
|
||||
cx = actor->_x - ((act->_sizeX - actor->_sizeX) / 2);
|
||||
else
|
||||
cx = actor->_x + ((actor->_sizeX - act->_sizeX) / 2);
|
||||
|
||||
if (cy > 174)
|
||||
cy = 174;
|
||||
|
||||
if (cx > 304)
|
||||
cx = 304;
|
||||
|
||||
act->_x = cx;
|
||||
act->_y = cy;
|
||||
act->_lastDir = dir;
|
||||
act->_nextFrame = 0;
|
||||
act->_dir = dir;
|
||||
if (act->_directions == 1)
|
||||
act->_dir = 0;
|
||||
else if (act->_directions == 4 && act->_framesPerDirection == 1) {
|
||||
act->_nextFrame = dir;
|
||||
act->_dir = 0;
|
||||
}
|
||||
act->_frameCount = act->_frameSpeed;
|
||||
act->_moveCountdown = act->_speed;
|
||||
act->_lastX[0] = cx;
|
||||
act->_lastX[1] = cx;
|
||||
act->_lastX[0] = actor->_x;
|
||||
act->_lastX[1] = actor->_x;
|
||||
act->_lastY[0] = cy;
|
||||
act->_lastY[1] = cy;
|
||||
act->_active = true;
|
||||
act->_creator = actor->_actorNum;
|
||||
act->_moveCount = act->_numMoves;
|
||||
act->_dead = 0;
|
||||
actor->_shotActor = i;
|
||||
actor->_currNumShots++;
|
||||
actor->_shotCountdown = 20;
|
||||
_G(shotOk) = false;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void actorAlwaysShoots(Actor *actor, int dir) {
|
||||
_actor_shoots(actor, dir);
|
||||
}
|
||||
|
||||
int actorShoots(Actor *actor, int dir) {
|
||||
const int cx = (actor->_x + (actor->_sizeX / 2)) >> 4;
|
||||
const int cy = ((actor->_y + actor->_sizeY) - 2) >> 4;
|
||||
|
||||
const int tx = _G(thor)->_centerX;
|
||||
const int ty = _G(thor)->_centerY;
|
||||
|
||||
int icn = 140;
|
||||
|
||||
if (_G(shot[actor->_shotType - 1])._flying)
|
||||
icn = 80;
|
||||
|
||||
switch (dir) {
|
||||
case 0:
|
||||
for (int i = ty + 1; i <= cy; i++) {
|
||||
if (_G(scrn)._iconGrid[i][cx] < icn)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (int i = cy; i <= ty; i++) {
|
||||
if (_G(scrn)._iconGrid[i][cx] < icn)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (int i = tx; i < cx; i++) {
|
||||
if (_G(scrn)._iconGrid[cy][i] < icn)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
for (int i = cx; i < tx; i++) {
|
||||
if (_G(scrn)._iconGrid[cy][i] < icn)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return _actor_shoots(actor, dir);
|
||||
}
|
||||
|
||||
void moveActor(Actor *actor) {
|
||||
if (actor->_vulnerableCountdown != 0)
|
||||
actor->_vulnerableCountdown--;
|
||||
if (actor->_shotCountdown != 0)
|
||||
actor->_shotCountdown--;
|
||||
if (actor->_show != 0)
|
||||
actor->_show--;
|
||||
|
||||
if (!actor->_shotCountdown && _G(shotOk) && actor->_numShotsAllowed && actor->_currNumShots < actor->_numShotsAllowed) {
|
||||
shotPatternFunc[actor->_shotPattern](actor);
|
||||
}
|
||||
|
||||
const int scount = actor->_moveCountdown - 1;
|
||||
if (scount <= 0) {
|
||||
if (!actor->_moveCounter)
|
||||
actor->_moveCountdown = actor->_speed;
|
||||
else
|
||||
actor->_moveCountdown = (actor->_speed << 1);
|
||||
|
||||
int i;
|
||||
|
||||
if (actor->_type == 3)
|
||||
i = shotMovementFunc[actor->_moveType](actor);
|
||||
else
|
||||
i = _movementFunc[actor->_moveType](actor);
|
||||
|
||||
if (actor->_directions == 2)
|
||||
i &= 1;
|
||||
|
||||
if (i != actor->_dir)
|
||||
actor->_dir = i;
|
||||
|
||||
if (actor->_moveType == 0 && _G(currentLevel) != _G(newLevel) && _G(shieldOn)) {
|
||||
_G(actor[2])._x = actor->_x - 2;
|
||||
if (_G(actor[2])._x < 0)
|
||||
_G(actor[2])._x = 0;
|
||||
_G(actor[2])._y = actor->_y;
|
||||
_G(actor[2])._lastX[0] = _G(actor[2])._x;
|
||||
_G(actor[2])._lastX[1] = _G(actor[2])._x;
|
||||
_G(actor[2])._lastY[0] = _G(actor[2])._y;
|
||||
_G(actor[2])._lastY[1] = _G(actor[2])._y;
|
||||
}
|
||||
} else
|
||||
actor->_moveCountdown = scount;
|
||||
|
||||
actor->_x &= 0xfffe;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
43
engines/got/game/move.h
Normal file
43
engines/got/game/move.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* 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 GOT_GAME_MOVE_H
|
||||
#define GOT_GAME_MOVE_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern void nextFrame(Actor *actor);
|
||||
extern bool pointWithin(int x, int y, int x1, int y1, int x2, int y2);
|
||||
extern bool overlap(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
|
||||
extern int reverseDirection(Actor *actor);
|
||||
extern void thorShoots();
|
||||
extern void thorDamaged(Actor *actor);
|
||||
extern void actorDestroyed(Actor *actor);
|
||||
extern int actorShoots(Actor *actor, int dir);
|
||||
extern void actorAlwaysShoots(Actor *actor, int dir);
|
||||
extern void actorDamaged(Actor *actor, int damage);
|
||||
extern void moveActor(Actor *actor);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
2622
engines/got/game/move_patterns.cpp
Normal file
2622
engines/got/game/move_patterns.cpp
Normal file
File diff suppressed because it is too large
Load Diff
37
engines/got/game/move_patterns.h
Normal file
37
engines/got/game/move_patterns.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* 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 GOT_GAME_MOVE_PATTERNS_H
|
||||
#define GOT_GAME_MOVE_PATTERNS_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern int (*const _movementFunc[]) (Actor *actor);
|
||||
int checkMove2(int x, int y, Actor *actor);
|
||||
int checkMove3(int x, int y, Actor *actor);
|
||||
int checkMove4(int x, int y, Actor *actor);
|
||||
void setThorVars();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
437
engines/got/game/object.cpp
Normal file
437
engines/got/game/object.cpp
Normal file
@@ -0,0 +1,437 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property _G(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 _G(of) the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 _G(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 _G(of)
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy _G(of) the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "got/game/object.h"
|
||||
#include "got/data/flags.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/game/status.h"
|
||||
#include "got/gfx/image.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
void notEnoughMagic();
|
||||
void cannotCarryMore();
|
||||
|
||||
void showObjects() {
|
||||
Common::fill(_G(objectMap), _G(objectMap) + TILES_COUNT, 0);
|
||||
Common::fill(_G(objectIndex), _G(objectIndex) + TILES_COUNT, 0);
|
||||
|
||||
for (int i = 0; i < OBJECTS_COUNT; i++) {
|
||||
if (_G(scrn)._staticObject[i]) {
|
||||
const int p = _G(scrn)._staticX[i] + (_G(scrn)._staticY[i] * TILES_X);
|
||||
_G(objectIndex[p]) = i;
|
||||
_G(objectMap[p]) = _G(scrn)._staticObject[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pickUpObject(int p) {
|
||||
switch (_G(objectMap[p])) {
|
||||
case 1: // Red jewel
|
||||
if (_G(thorInfo)._jewels >= 999) {
|
||||
cannotCarryMore();
|
||||
return;
|
||||
}
|
||||
addJewels(10);
|
||||
break;
|
||||
case 2: // Blue jewel
|
||||
if (_G(thorInfo)._jewels >= 999) {
|
||||
cannotCarryMore();
|
||||
return;
|
||||
}
|
||||
addJewels(1);
|
||||
break;
|
||||
case 3: // Red potion
|
||||
if (_G(thorInfo)._magic >= 150) {
|
||||
cannotCarryMore();
|
||||
return;
|
||||
}
|
||||
addMagic(10);
|
||||
break;
|
||||
case 4: // Blue potion
|
||||
if (_G(thorInfo)._magic >= 150) {
|
||||
cannotCarryMore();
|
||||
return;
|
||||
}
|
||||
addMagic(3);
|
||||
break;
|
||||
case 5: // Good apple
|
||||
if (_G(thor)->_health >= 150) {
|
||||
cannotCarryMore();
|
||||
return;
|
||||
}
|
||||
playSound(GULP, false);
|
||||
addHealth(5);
|
||||
break;
|
||||
case 6: // Bad apple
|
||||
playSound(OW, false);
|
||||
addHealth(-10);
|
||||
break;
|
||||
case 7: // Key (reset on exit)
|
||||
addKeys(1);
|
||||
break;
|
||||
case 8: // Treasure
|
||||
if (_G(thorInfo)._jewels >= 999) {
|
||||
cannotCarryMore();
|
||||
return;
|
||||
}
|
||||
addJewels(50);
|
||||
break;
|
||||
case 9: // Trophy
|
||||
addScore(100);
|
||||
break;
|
||||
case 10: // Crown
|
||||
addScore(1000);
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
case 24:
|
||||
case 25:
|
||||
case 26:
|
||||
if (_G(objectMap[p]) == 13 && HERMIT_HAS_DOLL)
|
||||
return;
|
||||
_G(thor)->_numMoves = 1;
|
||||
_G(hammer)->_numMoves = 2;
|
||||
_G(actor[2])._active = false;
|
||||
_G(shieldOn) = false;
|
||||
_G(tornadoUsed) = false;
|
||||
_G(thorInfo)._inventory |= 64;
|
||||
_G(thorInfo)._selectedItem = 7;
|
||||
_G(thorInfo)._object = _G(objectMap[p]) - 11;
|
||||
_G(thorInfo)._objectName = OBJECT_NAMES[_G(thorInfo)._object - 1];
|
||||
odinSpeaks((_G(objectMap[p]) - 12) + 501, _G(objectMap[p]) - 1);
|
||||
break;
|
||||
case 27:
|
||||
case 28:
|
||||
case 29:
|
||||
case 30:
|
||||
case 31:
|
||||
case 32: {
|
||||
_G(thunderSnakeCounter) = 0;
|
||||
_G(shieldOn) = false;
|
||||
_G(tornadoUsed) = false;
|
||||
_G(hammer)->_numMoves = 2;
|
||||
_G(thor)->_numMoves = 1;
|
||||
_G(actor[2])._active = false;
|
||||
const int s = 1 << (_G(objectMap[p]) - 27);
|
||||
_G(thorInfo)._inventory |= s;
|
||||
odinSpeaks((_G(objectMap[p]) - 27) + 516, _G(objectMap[p]) - 1);
|
||||
_G(thorInfo)._selectedItem = _G(objectMap[p]) - 26;
|
||||
addMagic(150);
|
||||
fillScore(5);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
playSound(YAH, false);
|
||||
_G(objectMap[p]) = 0;
|
||||
|
||||
// Reset so it doesn't reappear on reentry to screen
|
||||
if (_G(objectIndex[p]) < 30)
|
||||
_G(scrn)._staticObject[_G(objectIndex[p])] = 0;
|
||||
|
||||
_G(objectIndex[p]) = 0;
|
||||
}
|
||||
|
||||
void dropRandomObject(Actor *actor) {
|
||||
int objId;
|
||||
|
||||
const int rnd1 = g_events->getRandomNumber(99);
|
||||
const int rnd2 = g_events->getRandomNumber(99);
|
||||
|
||||
if (rnd1 < 25)
|
||||
objId = 5; // Apple
|
||||
else if (rnd1 & 1) {
|
||||
// Jewels
|
||||
if (rnd2 < 10)
|
||||
objId = 1; // Red
|
||||
else
|
||||
objId = 2; // Blue
|
||||
} else {
|
||||
// Potion
|
||||
if (rnd2 < 10)
|
||||
objId = 3; // Red
|
||||
else
|
||||
objId = 4; // Blue
|
||||
}
|
||||
|
||||
dropObject(actor, objId);
|
||||
}
|
||||
|
||||
bool dropObject(Actor *actor, const int objId) {
|
||||
const int p = (actor->_x + (actor->_sizeX / 2)) / 16 + (((actor->_y + (actor->_sizeY / 2)) / 16) * 20);
|
||||
if (!_G(objectMap[p]) && _G(scrn)._iconGrid[p / 20][p % 20] >= 140) { //nothing there and solid
|
||||
_G(objectMap[p]) = objId;
|
||||
_G(objectIndex[p]) = 27 + actor->_actorNum; //actor is 3-15
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useApple(int flag) {
|
||||
if (_G(thor)->_health == 150)
|
||||
return false;
|
||||
|
||||
if (flag && _G(thorInfo)._magic > 0) {
|
||||
if (!_G(appleFlag)) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-2);
|
||||
addHealth(1);
|
||||
playSound(ANGEL, false);
|
||||
} else if (_G(magicCounter) > 8) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-2);
|
||||
addHealth(1);
|
||||
if (!soundPlaying())
|
||||
playSound(ANGEL, false);
|
||||
}
|
||||
_G(appleFlag) = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
_G(appleFlag) = false;
|
||||
if (flag)
|
||||
notEnoughMagic();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useThunder(int flag) {
|
||||
if (flag && _G(thorInfo)._magic > 29) {
|
||||
if (!_G(thunderSnakeCounter)) {
|
||||
addMagic(-30);
|
||||
playSound(THUNDER, false);
|
||||
_G(thunderSnakeCounter) = 60;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (flag && !_G(thunderSnakeCounter))
|
||||
notEnoughMagic();
|
||||
|
||||
if (_G(thunderSnakeCounter))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useBoots(int flag) {
|
||||
if (flag) {
|
||||
if (_G(thorInfo)._magic > 0) {
|
||||
if (_G(thor)->_numMoves == 1 || _G(magicCounter) > 8) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-1);
|
||||
}
|
||||
|
||||
_G(thor)->_numMoves = 2;
|
||||
_G(hammer)->_numMoves = 3;
|
||||
return true;
|
||||
}
|
||||
|
||||
notEnoughMagic();
|
||||
_G(thor)->_numMoves = 1;
|
||||
_G(hammer)->_numMoves = 2;
|
||||
|
||||
} else {
|
||||
_G(thor)->_numMoves = 1;
|
||||
_G(hammer)->_numMoves = 2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useShield(int flag) {
|
||||
if (flag) {
|
||||
if (_G(thorInfo)._magic) {
|
||||
if (!_G(shieldOn)) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-1);
|
||||
setupMagicItem(1);
|
||||
|
||||
_G(actor[2]) = _G(magicItem[1]);
|
||||
setupActor(&_G(actor[2]), 2, 0, _G(thor)->_x, _G(thor)->_y);
|
||||
_G(actor[2])._moveCountdown = 1;
|
||||
_G(actor[2])._speed = 1;
|
||||
_G(shieldOn) = true;
|
||||
} else if (_G(magicCounter) > 8) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
notEnoughMagic();
|
||||
}
|
||||
|
||||
if (_G(shieldOn)) {
|
||||
_G(actor[2])._dead = 2;
|
||||
_G(actor[2])._active = false;
|
||||
_G(shieldOn) = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useLightning(int flag) {
|
||||
if (flag) {
|
||||
if (_G(thorInfo)._magic > 14) {
|
||||
addMagic(-15);
|
||||
g_events->send("Game", GameMessage("THROW_LIGHTNING"));
|
||||
} else {
|
||||
notEnoughMagic();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool useTornado(int flag) {
|
||||
if (flag) {
|
||||
if (_G(thorInfo)._magic > 10) {
|
||||
if (!_G(tornadoUsed) && !_G(actor[2])._dead && _G(magicCounter) > 20) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-10);
|
||||
setupMagicItem(0);
|
||||
_G(actor[2]) = _G(magicItem[0]);
|
||||
|
||||
setupActor(&_G(actor[2]), 2, 0, _G(thor)->_x, _G(thor)->_y);
|
||||
_G(actor[2])._lastDir = _G(thor)->_dir;
|
||||
_G(actor[2])._moveType = 16;
|
||||
_G(tornadoUsed) = true;
|
||||
playSound(WIND, false);
|
||||
}
|
||||
} else if (!_G(tornadoUsed)) {
|
||||
notEnoughMagic();
|
||||
return false;
|
||||
}
|
||||
if (_G(magicCounter) > 8) {
|
||||
if (_G(tornadoUsed)) {
|
||||
_G(magicCounter) = 0;
|
||||
addMagic(-1);
|
||||
}
|
||||
}
|
||||
if (_G(thorInfo)._magic < 1) {
|
||||
actorDestroyed(&_G(actor[2]));
|
||||
_G(tornadoUsed) = false;
|
||||
notEnoughMagic();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useObject(int flag) {
|
||||
if (!flag || !(_G(thorInfo)._inventory & 64))
|
||||
return false;
|
||||
|
||||
odinSpeaks((_G(thorInfo)._object - 1) + 5501, _G(thorInfo)._object - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void useItem() {
|
||||
bool ret = false;
|
||||
|
||||
const int kf = _G(keyFlag[key_magic]);
|
||||
|
||||
if (!kf && _G(tornadoUsed)) {
|
||||
actorDestroyed(&_G(actor[2]));
|
||||
_G(tornadoUsed) = false;
|
||||
}
|
||||
|
||||
const bool mf = _G(magicMissingInform);
|
||||
switch (_G(thorInfo)._selectedItem) {
|
||||
case 1:
|
||||
ret = useApple(kf);
|
||||
break;
|
||||
case 2:
|
||||
ret = useLightning(kf);
|
||||
break;
|
||||
case 3:
|
||||
ret = useBoots(kf);
|
||||
break;
|
||||
case 4:
|
||||
ret = useTornado(kf);
|
||||
break;
|
||||
case 5:
|
||||
ret = useShield(kf);
|
||||
break;
|
||||
case 6:
|
||||
ret = useThunder(kf);
|
||||
break;
|
||||
case 7:
|
||||
ret = useObject(kf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (kf) {
|
||||
if (!ret && !_G(useItemFlag)) {
|
||||
if (mf)
|
||||
playSound(BRAAPP, false);
|
||||
_G(useItemFlag) = true;
|
||||
}
|
||||
} else {
|
||||
_G(useItemFlag) = false;
|
||||
}
|
||||
}
|
||||
|
||||
void notEnoughMagic() {
|
||||
if (_G(magicMissingInform))
|
||||
return;
|
||||
|
||||
odinSpeaks(2006, 0);
|
||||
_G(magicMissingInform) = true;
|
||||
}
|
||||
|
||||
void cannotCarryMore() {
|
||||
if (_G(cantCarryInform))
|
||||
return;
|
||||
|
||||
odinSpeaks(2007, 0);
|
||||
_G(cantCarryInform) = true;
|
||||
}
|
||||
|
||||
void deleteObject() {
|
||||
_G(thorInfo)._inventory &= 0xbf;
|
||||
_G(thorInfo)._selectedItem = 1;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
38
engines/got/game/object.h
Normal file
38
engines/got/game/object.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* 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 GOT_GAME_OBJECT_H
|
||||
#define GOT_GAME_OBJECT_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern void showObjects();
|
||||
extern void pickUpObject(int p);
|
||||
extern void dropRandomObject(Actor *actor);
|
||||
extern bool dropObject(Actor *actor, int objId);
|
||||
extern void deleteObject();
|
||||
extern void useItem();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
1265
engines/got/game/script.cpp
Normal file
1265
engines/got/game/script.cpp
Normal file
File diff suppressed because it is too large
Load Diff
127
engines/got/game/script.h
Normal file
127
engines/got/game/script.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/* 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 GOT_GAME_SCRIPT_H
|
||||
#define GOT_GAME_SCRIPT_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
#include "got/gfx/gfx_pics.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
typedef void (*ScriptEndFn)();
|
||||
|
||||
enum ScriptPause {
|
||||
SCRIPT_READY, SCRIPT_PAUSED, SCRIPT_RESUMING
|
||||
};
|
||||
|
||||
class Scripts {
|
||||
public:
|
||||
Scripts();
|
||||
~Scripts();
|
||||
|
||||
void executeScript(long index, const Gfx::Pics &speakerIcon, ScriptEndFn endFn = nullptr);
|
||||
void pause();
|
||||
void resume();
|
||||
void setAskResponse(int option);
|
||||
void runIfResuming();
|
||||
|
||||
private:
|
||||
ScriptEndFn _endFn = nullptr;
|
||||
long _numVar[26] = {}; // numeric variables
|
||||
char _strVar[26][81] = {}; // string vars
|
||||
char _lineLabel[32][9] = {}; // line label look up table
|
||||
char *_linePtr[32] = {}; // line label pointers
|
||||
char *_newPtr = nullptr;
|
||||
int _numLabels = 0; // number of labels
|
||||
char *_gosubStack[32] = {}; // stack for GOSUB return addresses
|
||||
int _gosubPtr = 0; // GOSUB stack pointer
|
||||
char *_forStack[11] = {}; // FOR stack
|
||||
long _forVal[11] = {}; // current FOR value
|
||||
int8 _forVar[11] = {}; // ending FOR value (target var)
|
||||
int8 _forPtr = 0; // FOR stack pointer
|
||||
char *_buffPtr = nullptr; // pointer to current command
|
||||
char *_buffEnd = nullptr; // pointer to end of buffer
|
||||
char *_buffer = nullptr; // buffer space (alloc'ed)
|
||||
long _scrIndex = 0;
|
||||
Gfx::Pics _scrPic;
|
||||
long _lValue = 0;
|
||||
long _lTemp = 0;
|
||||
char _tempS[255] = {};
|
||||
ScriptPause _paused = SCRIPT_READY;
|
||||
int _askVar = -1;
|
||||
|
||||
private:
|
||||
int readScriptFile();
|
||||
void scriptError(int err_num);
|
||||
int getCommand();
|
||||
int skipColon();
|
||||
int calcValue();
|
||||
int getNextValue();
|
||||
int calcString(int mode);
|
||||
void getStr();
|
||||
int getInternalVariable();
|
||||
int execCommand(int num);
|
||||
int getLine(char *src, char *dst);
|
||||
void scriptEntry() {}
|
||||
void scriptExit();
|
||||
|
||||
int cmd_goto();
|
||||
int cmd_if();
|
||||
int cmd_run();
|
||||
int cmd_addJewels();
|
||||
int cmd_addHealth();
|
||||
int cmd_addMagic();
|
||||
int cmd_addKeys();
|
||||
int cmd_addScore();
|
||||
int cmd_say(int mode, int type);
|
||||
int cmd_ask();
|
||||
int cmd_sound();
|
||||
int cmd_setTile();
|
||||
int cmd_itemGive();
|
||||
int cmd_itemTake();
|
||||
int cmd_setFlag();
|
||||
int cmd_ltoa();
|
||||
int cmd_pause();
|
||||
int cmd_visible();
|
||||
int cmd_random();
|
||||
int cmd_exec();
|
||||
|
||||
void scr_func1();
|
||||
void scr_func2();
|
||||
void scr_func3();
|
||||
void scr_func4();
|
||||
void scr_func5();
|
||||
|
||||
typedef void (Scripts:: *ScrFunction)();
|
||||
static ScrFunction scr_func[5];
|
||||
|
||||
void runScript(bool firstTime = true);
|
||||
void scriptLoop();
|
||||
|
||||
};
|
||||
|
||||
extern void executeScript(long index, const Gfx::Pics &speakerIcon,
|
||||
ScriptEndFn endFn = nullptr);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
734
engines/got/game/shot_movement.cpp
Normal file
734
engines/got/game/shot_movement.cpp
Normal file
@@ -0,0 +1,734 @@
|
||||
/* 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 "got/game/shot_movement.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/game/move_patterns.h"
|
||||
#include "got/game/object.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
int shotMovementNone(Actor *actor);
|
||||
int shotMovementOne(Actor *actor);
|
||||
int shotMovementTwo(Actor *actor);
|
||||
int shotMovementThree(Actor *actor);
|
||||
int shotMovementFour(Actor *actor);
|
||||
int shotMovementFive(Actor *actor);
|
||||
int shotMovementSix(Actor *actor);
|
||||
int shotMovementSeven(Actor *actor);
|
||||
int shotMovementEight(Actor *actor);
|
||||
int shotMovementNine(Actor *actor);
|
||||
int shotMovementTen(Actor *actor);
|
||||
int shotMovementEleven(Actor *actor);
|
||||
int shotMovementTwelve(Actor *actor);
|
||||
int shotMovementThirteen(Actor *actor);
|
||||
|
||||
int (*const shotMovementFunc[])(Actor *actor) = {
|
||||
shotMovementNone,
|
||||
shotMovementOne,
|
||||
shotMovementTwo,
|
||||
shotMovementThree,
|
||||
shotMovementFour,
|
||||
shotMovementFive,
|
||||
shotMovementSix,
|
||||
shotMovementSeven,
|
||||
shotMovementEight,
|
||||
shotMovementNine,
|
||||
shotMovementTen,
|
||||
shotMovementEleven,
|
||||
shotMovementTwelve,
|
||||
shotMovementThirteen
|
||||
};
|
||||
|
||||
void next_shot_frame(Actor *actor) {
|
||||
if (actor->_directions == 4 && actor->_framesPerDirection == 1) {
|
||||
actor->_nextFrame = actor->_lastDir;
|
||||
actor->_dir = 0;
|
||||
} else {
|
||||
const int fcount = actor->_frameCount - 1;
|
||||
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 3)
|
||||
actor->_nextFrame = 0;
|
||||
|
||||
actor->_frameCount = actor->_frameSpeed;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
}
|
||||
}
|
||||
|
||||
// Boss - snake
|
||||
int shotMovementNone(Actor *actor) {
|
||||
actor->_temp3--;
|
||||
if (!actor->_temp3) {
|
||||
actorDestroyed(actor);
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
}
|
||||
|
||||
next_shot_frame(actor);
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
int shotMovementOne(Actor *actor) {
|
||||
int x1 = 0, y1 = 0;
|
||||
|
||||
const int d = actor->_lastDir;
|
||||
|
||||
switch (d) {
|
||||
case 0:
|
||||
x1 = actor->_x;
|
||||
y1 = actor->_y - 2;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
x1 = actor->_x;
|
||||
y1 = actor->_y + 2;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
x1 = actor->_x - 2;
|
||||
y1 = actor->_y;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
x1 = actor->_x + 2;
|
||||
y1 = actor->_y;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!checkMove3(x1, y1, actor)) {
|
||||
actorDestroyed(actor);
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
} else {
|
||||
next_shot_frame(actor);
|
||||
actor->_lastDir = d;
|
||||
}
|
||||
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
if (actor->_directions == 4 && actor->_framesPerDirection == 1)
|
||||
return 0;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
int shotMovementTwo(Actor *actor) {
|
||||
int x1 = 0, y1 = 0;
|
||||
|
||||
const int d = actor->_lastDir;
|
||||
|
||||
switch (d) {
|
||||
case 0:
|
||||
x1 = actor->_x;
|
||||
y1 = actor->_y - 2;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
x1 = actor->_x;
|
||||
y1 = actor->_y + 2;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
x1 = actor->_x - 2;
|
||||
y1 = actor->_y;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
x1 = actor->_x + 2;
|
||||
y1 = actor->_y;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!checkMove4(x1, y1, actor)) {
|
||||
actorDestroyed(actor);
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
} else {
|
||||
next_shot_frame(actor);
|
||||
actor->_lastDir = d;
|
||||
}
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
if (actor->_directions == 4 && actor->_framesPerDirection == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
// Serpent fire
|
||||
int shotMovementThree(Actor *actor) {
|
||||
const int d = actor->_lastDir;
|
||||
|
||||
actor->_x -= 2;
|
||||
actor->_temp3--;
|
||||
actor->_temp4--;
|
||||
|
||||
if (overlap(_G(thorX1) - 1, _G(thorY1) - 1, _G(thorX2) + 1, _G(thorY2) + 1,
|
||||
actor->_x, actor->_y, actor->_x + 15, actor->_y + 15)) {
|
||||
actor->_moveType = 0;
|
||||
actor->_speed = 6;
|
||||
thorDamaged(actor);
|
||||
actor->_x += 2;
|
||||
}
|
||||
if (!actor->_temp4) {
|
||||
actor->_temp4 = actor->_temp5;
|
||||
actor->_speed++;
|
||||
if (actor->_speed > 6)
|
||||
actor->_moveType = 0;
|
||||
}
|
||||
if (!actor->_temp3) {
|
||||
actorDestroyed(actor);
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
} else {
|
||||
next_shot_frame(actor);
|
||||
actor->_lastDir = d;
|
||||
}
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
// Wraith balls
|
||||
int shotMovementFour(Actor *actor) {
|
||||
if (actor->_temp1) {
|
||||
actor->_temp1--;
|
||||
if (!actor->_temp1) {
|
||||
actorDestroyed(actor);
|
||||
_G(appleDropCounter++);
|
||||
if (_G(appleDropCounter) == 4) {
|
||||
if (dropObject(actor, 5))
|
||||
_G(appleDropCounter) = 0;
|
||||
else
|
||||
_G(appleDropCounter) = 3;
|
||||
} else
|
||||
dropObject(actor, 3);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (overlap(_G(thor)->_x - 1, _G(thor)->_y - 1, _G(thorX2) + 1, _G(thorY2) + 1,
|
||||
actor->_x, actor->_y, actor->_x + 15, actor->_y + 15)) {
|
||||
thorDamaged(actor);
|
||||
actorDestroyed(actor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int x1 = actor->_x;
|
||||
int y1 = actor->_y;
|
||||
int yd = 0;
|
||||
int xd = 0;
|
||||
int d = actor->_lastDir;
|
||||
|
||||
if ((x1 > (_G(thorX1)) + 1))
|
||||
xd = -2;
|
||||
else if ((x1 < (_G(thorX1)) - 1))
|
||||
xd = 2;
|
||||
|
||||
if (actor->_actorNum == 1) {
|
||||
if (y1 < (_G(thorY1) - 6))
|
||||
yd = 2;
|
||||
else if (y1 > (_G(thorY1) - 6))
|
||||
yd = -2;
|
||||
} else {
|
||||
if (y1 < (_G(thorRealY1) - 1))
|
||||
yd = 2;
|
||||
else if (y1 > (_G(thorRealY1) + 1))
|
||||
yd = -2;
|
||||
}
|
||||
|
||||
if (xd && yd) {
|
||||
if (xd == -2 && ABS(yd) == 2)
|
||||
d = 2;
|
||||
else if (xd == 2 && ABS(yd) == 2)
|
||||
d = 3;
|
||||
|
||||
x1 += xd;
|
||||
y1 += yd;
|
||||
if (checkMove3(x1, y1, actor)) {
|
||||
nextFrame(actor);
|
||||
actor->_lastDir = d;
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
} else if (xd == 0 && yd == 2)
|
||||
d = 1;
|
||||
else if (xd == 0 && yd == -2)
|
||||
d = 0;
|
||||
else if (xd == 2 && yd == 0)
|
||||
d = 3;
|
||||
else if (xd == -2 && yd == 0)
|
||||
d = 2;
|
||||
|
||||
x1 = actor->_x;
|
||||
y1 = actor->_y;
|
||||
actor->_toggle ^= 1;
|
||||
|
||||
if (actor->_toggle) {
|
||||
if (xd) {
|
||||
x1 += xd;
|
||||
if (checkMove3(x1, y1, actor)) {
|
||||
if (xd > 0)
|
||||
d = 3;
|
||||
else
|
||||
d = 2;
|
||||
nextFrame(actor);
|
||||
actor->_lastDir = d;
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
x1 = actor->_x;
|
||||
}
|
||||
if (yd) {
|
||||
y1 += yd;
|
||||
if (checkMove3(x1, y1, actor)) {
|
||||
if (yd > 0)
|
||||
d = 1;
|
||||
else
|
||||
d = 0;
|
||||
nextFrame(actor);
|
||||
actor->_lastDir = d;
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (yd) {
|
||||
y1 += yd;
|
||||
if (checkMove3(x1, y1, actor)) {
|
||||
if (yd > 0)
|
||||
d = 1;
|
||||
else
|
||||
d = 0;
|
||||
nextFrame(actor);
|
||||
actor->_lastDir = d;
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
y1 = actor->_y;
|
||||
}
|
||||
if (xd) {
|
||||
x1 += xd;
|
||||
if (checkMove3(x1, y1, actor)) {
|
||||
if (xd > 0)
|
||||
d = 3;
|
||||
else
|
||||
d = 2;
|
||||
nextFrame(actor);
|
||||
actor->_lastDir = d;
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
}
|
||||
}
|
||||
checkMove3(actor->_x, actor->_y, actor);
|
||||
nextFrame(actor);
|
||||
actor->_lastDir = d;
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
// No move, frame cycle
|
||||
int shotMovementFive(Actor *actor) {
|
||||
next_shot_frame(actor);
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
// Wraith spots
|
||||
int shotMovementSix(Actor *actor) {
|
||||
actor->_temp1--;
|
||||
if (!actor->_temp1) {
|
||||
actorDestroyed(actor);
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
} else
|
||||
next_shot_frame(actor);
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
#define YV actor->_i1
|
||||
#define YC actor->_i2
|
||||
#define BC actor->_i3
|
||||
#define YD actor->_i4
|
||||
#define XD actor->_i5
|
||||
#define XC actor->_i6
|
||||
#define IV 100
|
||||
#define IC 50
|
||||
|
||||
// Skull drop
|
||||
int shotMovementSeven(Actor *actor) {
|
||||
if (actor->_temp3) {
|
||||
actor->_temp3--;
|
||||
goto done;
|
||||
}
|
||||
if (overlap(actor->_x, actor->_y, actor->_x + actor->_sizeX, actor->_y + actor->_sizeY,
|
||||
_G(thor)->_x, _G(thor)->_y + 4, _G(thor)->_x + 15, _G(thor)->_y + 15))
|
||||
thorDamaged(actor);
|
||||
|
||||
actor->_temp2++;
|
||||
if (actor->_temp2 > 2) {
|
||||
if (actor->_temp4)
|
||||
actor->_temp4--;
|
||||
actor->_temp2 = 0;
|
||||
}
|
||||
actor->_temp3 = actor->_temp4;
|
||||
|
||||
actor->_y += 2;
|
||||
if (actor->_y > 160 - 36) {
|
||||
actor->_x += (4 - g_events->getRandomNumber(8));
|
||||
actor->_moveType = 8;
|
||||
YV = IV;
|
||||
YC = 0;
|
||||
BC = IC;
|
||||
YD = 0;
|
||||
XC = 3;
|
||||
if (actor->_x < 150)
|
||||
XD = 1;
|
||||
else
|
||||
XD = 0;
|
||||
}
|
||||
|
||||
done:
|
||||
next_shot_frame(actor);
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
// Skull bounce
|
||||
int shotMovementEight(Actor *actor) {
|
||||
int x = actor->_x;
|
||||
int y = actor->_y;
|
||||
|
||||
XC--;
|
||||
if (!XC) {
|
||||
XC = 3;
|
||||
if (XD)
|
||||
x += 2;
|
||||
else
|
||||
x -= 2;
|
||||
}
|
||||
YC += YV;
|
||||
if (YC > (IV - 1)) {
|
||||
if (!YD) {
|
||||
YV -= 8;
|
||||
YC -= IV;
|
||||
y -= 2;
|
||||
} else {
|
||||
YV += 8;
|
||||
YC -= IV;
|
||||
y += 2;
|
||||
}
|
||||
}
|
||||
if (YV < 0) {
|
||||
YV = 0;
|
||||
BC = 1;
|
||||
}
|
||||
if (YV > IV) {
|
||||
YV = IV;
|
||||
BC = 1;
|
||||
}
|
||||
BC--;
|
||||
if (!BC) {
|
||||
BC = IC;
|
||||
if (YD)
|
||||
YV = IV;
|
||||
YD ^= 1;
|
||||
}
|
||||
if (y > 164)
|
||||
y = 164;
|
||||
// 8 311
|
||||
if (x < 1 || x > (319 - actor->_sizeX)) {
|
||||
if (!actor->_dead)
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
actorDestroyed(actor);
|
||||
}
|
||||
if (overlap(actor->_x, actor->_y, actor->_x + actor->_sizeX, actor->_y + actor->_sizeY,
|
||||
_G(thor)->_x, _G(thor)->_y + 4, _G(thor)->_x + 15, _G(thor)->_y + 15))
|
||||
thorDamaged(actor);
|
||||
actor->_x = x;
|
||||
actor->_y = y;
|
||||
|
||||
//done:
|
||||
next_shot_frame(actor);
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
// Skull explode
|
||||
int shotMovementNine(Actor *actor) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame == 3) {
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
actorDestroyed(actor);
|
||||
return 0;
|
||||
}
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
// Skull - stalagtites
|
||||
int shotMovementTen(Actor *actor) {
|
||||
bool check = false;
|
||||
actor->_y += 2;
|
||||
|
||||
if (overlap(actor->_x, actor->_y, actor->_x + actor->_sizeX, actor->_y + actor->_sizeY,
|
||||
_G(thor)->_x, _G(thor)->_y + 4, _G(thor)->_x + 15, _G(thor)->_y + 15)) {
|
||||
thorDamaged(actor);
|
||||
check = true;
|
||||
}
|
||||
if (actor->_y > 160 || check) {
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
actorDestroyed(actor);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef YD
|
||||
#undef XD
|
||||
#define YA actor->_i1
|
||||
#define XA actor->_i2
|
||||
#define YD actor->_i3
|
||||
#define XD actor->_i4
|
||||
#define DIR actor->_i5
|
||||
#define CNT actor->_i6
|
||||
|
||||
void calc_angle(const int x1, const int y1, const int x2, const int y2, Actor *actor) {
|
||||
if (x1 < x2) {
|
||||
XA = -2;
|
||||
XD = x2 - x1;
|
||||
} else if (x1 > x2) {
|
||||
XA = 2;
|
||||
XD = x1 - x2;
|
||||
} else {
|
||||
XA = 0;
|
||||
XD = 0;
|
||||
}
|
||||
|
||||
if (y1 < y2) {
|
||||
YA = -2;
|
||||
YD = y2 - y1;
|
||||
} else if (y1 > y2) {
|
||||
YA = 2;
|
||||
YD = y1 - y2;
|
||||
} else {
|
||||
YA = 0;
|
||||
YD = 0;
|
||||
}
|
||||
|
||||
if (YD >= XD)
|
||||
DIR = 1;
|
||||
else
|
||||
DIR = 0;
|
||||
CNT = 0;
|
||||
}
|
||||
|
||||
// Angle throw
|
||||
int shotMovementEleven(Actor *actor) {
|
||||
int x1 = actor->_x;
|
||||
int y1 = actor->_y;
|
||||
|
||||
if (!actor->_temp1) {
|
||||
calc_angle(_G(thorX1), _G(thorRealY1), x1, y1, actor);
|
||||
actor->_temp1 = 1;
|
||||
}
|
||||
|
||||
if (DIR) {
|
||||
y1 += YA;
|
||||
CNT += XD;
|
||||
if (CNT >= YD) {
|
||||
x1 += XA;
|
||||
CNT -= YD;
|
||||
}
|
||||
} else {
|
||||
x1 += XA;
|
||||
CNT += YD;
|
||||
if (CNT >= XD) {
|
||||
y1 += YA;
|
||||
CNT -= XD;
|
||||
}
|
||||
}
|
||||
|
||||
if (!checkMove3(x1, y1, actor)) {
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
actorDestroyed(actor);
|
||||
} else
|
||||
nextFrame(actor);
|
||||
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
// Angle throw Loki
|
||||
int shotMovementTwelve(Actor *actor) {
|
||||
int x1 = actor->_x;
|
||||
int y1 = actor->_y;
|
||||
|
||||
if (!actor->_temp5) {
|
||||
calc_angle(_G(thorX1), _G(thorRealY1), x1, y1, actor);
|
||||
actor->_temp5 = 1;
|
||||
}
|
||||
|
||||
if (DIR) {
|
||||
y1 += YA;
|
||||
CNT += XD;
|
||||
if (CNT >= YD) {
|
||||
x1 += XA;
|
||||
CNT -= YD;
|
||||
}
|
||||
} else {
|
||||
x1 += XA;
|
||||
CNT += YD;
|
||||
if (CNT >= XD) {
|
||||
y1 += YA;
|
||||
CNT -= XD;
|
||||
}
|
||||
}
|
||||
|
||||
if (x1 < 16 || x1 > 287 || y1 < 16 || y1 > 159) {
|
||||
calc_angle(g_events->getRandomNumber(319),
|
||||
g_events->getRandomNumber(191), x1, y1, actor);
|
||||
actor->_moveType = 13;
|
||||
actor->_temp4 = 240;
|
||||
actor->_nextFrame = 2;
|
||||
} else {
|
||||
if (overlap(x1 + 2, y1 + 2, x1 + 14, y1 + 14, _G(thorX1), _G(thorY1), _G(thorX2), _G(thorY2))) {
|
||||
thorDamaged(actor);
|
||||
}
|
||||
actor->_x = x1;
|
||||
actor->_y = y1;
|
||||
}
|
||||
|
||||
const int fcount = actor->_frameCount - 1;
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 1)
|
||||
actor->_nextFrame = 0;
|
||||
actor->_frameCount = actor->_frameSpeed;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
// Angle throw Loki-2
|
||||
int shotMovementThirteen(Actor *actor) {
|
||||
int x1 = actor->_x;
|
||||
int y1 = actor->_y;
|
||||
|
||||
if (!actor->_temp5) {
|
||||
calc_angle(_G(thorX1), _G(thorRealY1), x1, y1, actor);
|
||||
actor->_temp5 = 1;
|
||||
}
|
||||
|
||||
if (DIR) {
|
||||
y1 += YA;
|
||||
CNT += XD;
|
||||
if (CNT >= YD) {
|
||||
x1 += XA;
|
||||
CNT -= YD;
|
||||
}
|
||||
} else {
|
||||
x1 += XA;
|
||||
CNT += YD;
|
||||
if (CNT >= XD) {
|
||||
y1 += YA;
|
||||
CNT -= XD;
|
||||
}
|
||||
}
|
||||
|
||||
if (actor->_temp4)
|
||||
actor->_temp4--;
|
||||
|
||||
if (!actor->_temp4) {
|
||||
if (_G(actor[actor->_creator])._currNumShots)
|
||||
_G(actor[actor->_creator])._currNumShots--;
|
||||
actorDestroyed(actor);
|
||||
_G(appleDropCounter++);
|
||||
if (_G(appleDropCounter) > 4) {
|
||||
if (dropObject(actor, 5))
|
||||
_G(appleDropCounter) = 0;
|
||||
else
|
||||
_G(appleDropCounter) = 4;
|
||||
} else
|
||||
dropObject(actor, 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (x1 < 16 || x1 > 287 || y1 < 16 || y1 > 159) {
|
||||
if (x1 < 16 || x1 > 287)
|
||||
XA = 0 - XA;
|
||||
else
|
||||
YA = 0 - YA;
|
||||
} else {
|
||||
if (overlap(x1 + 4, y1 + 4, x1 + 12, y1 + 12, _G(thorX1), _G(thorY1), _G(thorX2), _G(thorY2))) {
|
||||
thorDamaged(actor);
|
||||
}
|
||||
actor->_x = x1;
|
||||
actor->_y = y1;
|
||||
}
|
||||
|
||||
const int fcount = actor->_frameCount - 1;
|
||||
if (fcount <= 0) {
|
||||
actor->_nextFrame++;
|
||||
if (actor->_nextFrame > 3)
|
||||
actor->_nextFrame = 2;
|
||||
actor->_frameCount = actor->_frameSpeed;
|
||||
} else
|
||||
actor->_frameCount = fcount;
|
||||
|
||||
if (actor->_directions == 1)
|
||||
return 0;
|
||||
|
||||
return actor->_lastDir;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
33
engines/got/game/shot_movement.h
Normal file
33
engines/got/game/shot_movement.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* 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 GOT_GAME_SHOT_MOVEMENT_H
|
||||
#define GOT_GAME_SHOT_MOVEMENT_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern int (*const shotMovementFunc[]) (Actor *actor);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
222
engines/got/game/shot_pattern.cpp
Normal file
222
engines/got/game/shot_pattern.cpp
Normal file
@@ -0,0 +1,222 @@
|
||||
/* 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 "got/game/shot_pattern.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
int shotPatternNone(Actor *actor);
|
||||
int shotPatternOne(Actor *actor);
|
||||
int shotPatternTwo(Actor *actor);
|
||||
int shotPatternThree(Actor *actor);
|
||||
int shotPatternFour(Actor *actor);
|
||||
int shotPatternFive(Actor *actor);
|
||||
int shotPatternSix(Actor *actor);
|
||||
int shotPatternSeven(Actor *actor);
|
||||
int shotPatternEight(Actor *actor);
|
||||
|
||||
int (*const shotPatternFunc[])(Actor *actor) = {
|
||||
shotPatternNone,
|
||||
shotPatternOne,
|
||||
shotPatternTwo,
|
||||
shotPatternThree,
|
||||
shotPatternFour,
|
||||
shotPatternFive,
|
||||
shotPatternSix,
|
||||
shotPatternSeven,
|
||||
shotPatternEight,
|
||||
};
|
||||
|
||||
// No shooting
|
||||
int shotPatternNone(Actor *actor) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Uni-directional seek
|
||||
int shotPatternOne(Actor *actor) {
|
||||
switch (actor->_lastDir) {
|
||||
case 0:
|
||||
if (ABS(_G(thorX1) - actor->_x) < 8) {
|
||||
if (actor->_y > _G(thorRealY1)) { //r
|
||||
if (actorShoots(actor, 0))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (ABS(_G(thorX1) - actor->_x) < 8) {
|
||||
if (actor->_y < _G(thorRealY1)) { //r
|
||||
if (actorShoots(actor, 1))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (ABS(_G(thorRealY1) - actor->_y) < 8) { //r
|
||||
if (actor->_x > _G(thorX1)) {
|
||||
if (actorShoots(actor, 2))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (ABS(_G(thorRealY1) - actor->_y) < 8) { //r
|
||||
if (actor->_x < _G(thorX1)) {
|
||||
if (actorShoots(actor, 3))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Omni directional
|
||||
int shotPatternTwo(Actor *actor) {
|
||||
if (ABS(_G(thor)->_x - actor->_x) < 8) {
|
||||
if (_G(thor)->_y > actor->_y)
|
||||
actorShoots(actor, 1);
|
||||
else if (_G(thor)->_y < actor->_y)
|
||||
actorShoots(actor, 0);
|
||||
else
|
||||
return 0;
|
||||
} else if (ABS(_G(thor)->_y - actor->_y) < 8) {
|
||||
if (_G(thor)->_x > actor->_x)
|
||||
actorShoots(actor, 3);
|
||||
else if (_G(thor)->_x < actor->_x)
|
||||
actorShoots(actor, 2);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Uni directional (backwards)
|
||||
int shotPatternThree(Actor *actor) {
|
||||
const int oldDir = actor->_lastDir;
|
||||
if (shotPatternOne(actor)) {
|
||||
actor->_lastDir = reverseDirection(actor);
|
||||
return 1;
|
||||
}
|
||||
|
||||
actor->_lastDir = reverseDirection(actor);
|
||||
shotPatternOne(actor);
|
||||
actor->_lastDir = oldDir;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Omni-directional not solid shot
|
||||
int shotPatternFour(Actor *actor) {
|
||||
if (ABS(_G(thor)->_x - actor->_x) < 8) {
|
||||
if (_G(thor)->_y > actor->_y)
|
||||
actorAlwaysShoots(actor, 1);
|
||||
else if (_G(thor)->_y < actor->_y)
|
||||
actorAlwaysShoots(actor, 0);
|
||||
else
|
||||
return 0;
|
||||
} else if (ABS(_G(thor)->_y - actor->_y) < 8) {
|
||||
if (_G(thor)->_x > actor->_x)
|
||||
actorAlwaysShoots(actor, 3);
|
||||
else if (_G(thor)->_x < actor->_x)
|
||||
actorAlwaysShoots(actor, 2);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Boss - snake
|
||||
int shotPatternFive(Actor *actor) {
|
||||
if (_G(rand1) < 15 && (actor->_temp1 == 0) && (actor->_temp2 == 0)) {
|
||||
actor->_y += 16;
|
||||
actor->_numShotsAllowed = 3 + _G(setup)._difficultyLevel;
|
||||
actorShoots(actor, 2);
|
||||
playSound(BOSS12, false);
|
||||
|
||||
const int num = actor->_shotActor;
|
||||
actor->_shotCountdown = 50;
|
||||
_G(actor[num])._temp3 = 120;
|
||||
_G(actor[num])._temp4 = 5 + (_G(rand2) % 17);
|
||||
_G(actor[num])._temp5 = _G(actor[num])._temp4;
|
||||
actor->_y -= 16;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 4 surrounding squares
|
||||
int shotPatternSix(Actor *actor) {
|
||||
const int pos = ((actor->_x) / 16) + (((actor->_y) / 16) * 20);
|
||||
|
||||
if (_G(thorPos) == pos - 20)
|
||||
actorShoots(actor, 0);
|
||||
else if (_G(thorPos) == pos + 20)
|
||||
actorShoots(actor, 1);
|
||||
else if (_G(thorPos) == pos - 1)
|
||||
actorShoots(actor, 2);
|
||||
else if (_G(thorPos) == pos + 1)
|
||||
actorShoots(actor, 3);
|
||||
else
|
||||
return 0;
|
||||
|
||||
actor->_frameSequence[3] = 3;
|
||||
actor->_nextFrame = 3;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// none
|
||||
int shotPatternSeven(Actor *actor) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// random
|
||||
int shotPatternEight(Actor *actor) {
|
||||
if (!actor->_i2) {
|
||||
actor->_i1 = actor->_funcPass;
|
||||
actor->_i2 = 1;
|
||||
}
|
||||
|
||||
if (actor->_i1) {
|
||||
actor->_i1--;
|
||||
} else if (_G(rand1) < 10) {
|
||||
actor->_i1 = actor->_funcPass;
|
||||
actor->_i2 = _G(thorRealY1);
|
||||
actorShoots(actor, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
33
engines/got/game/shot_pattern.h
Normal file
33
engines/got/game/shot_pattern.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* 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 GOT_GAME_SHOT_PATTERN_H
|
||||
#define GOT_GAME_SHOT_PATTERN_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern int (*const shotPatternFunc[])(Actor *actor);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
290
engines/got/game/special_tile.cpp
Normal file
290
engines/got/game/special_tile.cpp
Normal file
@@ -0,0 +1,290 @@
|
||||
/* 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 "got/game/special_tile.h"
|
||||
#include "got/events.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/game/object.h"
|
||||
#include "got/gfx/image.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
int openDoor1(int y, int x);
|
||||
int cashDoor1(int y, int x, int amount);
|
||||
void eraseDoor(int x, int y);
|
||||
|
||||
int specialTileThor(const int x, const int y, const int icon) {
|
||||
int cx, cy;
|
||||
|
||||
int f = 0;
|
||||
switch (icon) {
|
||||
case 201:
|
||||
return openDoor1(x, y);
|
||||
case 202:
|
||||
if (GAME3) {
|
||||
if (_G(thorInfo)._inventory & 64) {
|
||||
if (_G(thorInfo)._object == 4) {
|
||||
eraseDoor(y, x);
|
||||
deleteObject();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_G(thor)->_x > 300)
|
||||
// Ending bridge
|
||||
_G(endTile) = true;
|
||||
return 1;
|
||||
case 203:
|
||||
if (!GAME1) {
|
||||
if ((_G(thorInfo)._inventory & 64) && _G(thorInfo)._object == 5) {
|
||||
odinSpeaks(2012, 0);
|
||||
deleteObject();
|
||||
_G(setup).f10 = true;
|
||||
} else if (!_G(setup).f10) {
|
||||
odinSpeaks(2011, 0);
|
||||
_G(setup).f10 = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
case 204:
|
||||
if (GAME2) {
|
||||
if (!_G(setup).f19)
|
||||
_G(slipFlag) = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (GAME3) {
|
||||
if (_G(thor)->_x < 4)
|
||||
_G(endTile) = true;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
case 205:
|
||||
if (!_G(diag) && _G(thor)->_dir != 1)
|
||||
return 1;
|
||||
break;
|
||||
case 206:
|
||||
if (!_G(diag) && _G(thor)->_dir != 0)
|
||||
return 1;
|
||||
break;
|
||||
case 207:
|
||||
if (!_G(diag) && _G(thor)->_dir != 3)
|
||||
return 1;
|
||||
break;
|
||||
case 208:
|
||||
if (!_G(diag) && _G(thor)->_dir != 2)
|
||||
return 1;
|
||||
break;
|
||||
case 209:
|
||||
return cashDoor1(x, y, 10);
|
||||
case 210:
|
||||
return cashDoor1(x, y, 100);
|
||||
case 211:
|
||||
if (GAME1) {
|
||||
placeTile(y, x, 79);
|
||||
_G(exitFlag) = 2;
|
||||
} else if (GAME2) {
|
||||
if (_G(thor)->_dir == 0 && _G(setup).f29 && _G(setup).f21 && !_G(setup).f22) {
|
||||
actorVisible(1);
|
||||
actorVisible(2);
|
||||
actorVisible(3);
|
||||
actorVisible(4);
|
||||
actorVisible(5);
|
||||
Common::fill(_G(scrn)._actorInvis, _G(scrn)._actorInvis + 16, 0);
|
||||
_G(thunderSnakeCounter) = 60;
|
||||
playSound(THUNDER, true);
|
||||
_G(setup).f22 = true;
|
||||
}
|
||||
} else {
|
||||
// Game 3
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
case 212:
|
||||
case 213:
|
||||
return 0;
|
||||
case 214: // Teleport tiles
|
||||
case 215:
|
||||
case 216:
|
||||
case 217:
|
||||
if ((GAME2 && icon == 217) || GAME3) {
|
||||
cx = (_G(thorX1) + 7) / 16;
|
||||
cy = (_G(thorRealY1) + 8) / 16;
|
||||
if (_G(scrn)._iconGrid[cy][cx] == icon) {
|
||||
_G(thor)->_vulnerableCountdown = STAMINA;
|
||||
playSound(WOOP, false);
|
||||
|
||||
const int nt = _G(scrn)._newLevelLocation[icon - 214];
|
||||
const int displayPage = _G(pge);
|
||||
const int drawPage = _G(pge) ^ 1;
|
||||
|
||||
_G(thor)->_lastX[displayPage] = _G(thor)->_x;
|
||||
_G(thor)->_lastY[displayPage] = _G(thor)->_y;
|
||||
_G(thor)->_x = (nt % 20) * 16;
|
||||
_G(thor)->_y = ((nt / 20) * 16) - 2;
|
||||
_G(thor)->_lastX[drawPage] = _G(thor)->_x;
|
||||
_G(thor)->_lastY[drawPage] = _G(thor)->_y;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
case 218:
|
||||
case 219:
|
||||
// Hole tiles
|
||||
f = 1;
|
||||
// fall through
|
||||
case 220:
|
||||
case 221:
|
||||
case 222:
|
||||
case 223:
|
||||
case 224:
|
||||
case 225:
|
||||
case 226:
|
||||
case 227:
|
||||
case 228:
|
||||
case 229:
|
||||
// Hole tiles
|
||||
cx = (_G(thorX1) + 7) / 16;
|
||||
cy = (_G(thorRealY1) + 8) / 16;
|
||||
if (_G(scrn)._iconGrid[cy][cx] == icon) {
|
||||
_G(thor)->_vulnerableCountdown = STAMINA;
|
||||
if (icon < 224 && icon > 219)
|
||||
playSound(FALL, false);
|
||||
|
||||
_G(newLevel) = _G(scrn)._newLevel[icon - 220 + (f * 6)];
|
||||
_G(warpScroll) = false;
|
||||
if (_G(newLevel) > 119) {
|
||||
_G(warpScroll) = true;
|
||||
_G(newLevel) -= 128;
|
||||
}
|
||||
|
||||
_G(newLevelTile) = _G(scrn)._newLevelLocation[icon - 220 + (f * 6)];
|
||||
_G(warpFlag) = true;
|
||||
|
||||
if (_G(warpScroll)) {
|
||||
if (_G(thor)->_dir == 0)
|
||||
_G(thor)->_y = 175;
|
||||
else if (_G(thor)->_dir == 1)
|
||||
_G(thor)->_y = 0;
|
||||
else if (_G(thor)->_dir == 2)
|
||||
_G(thor)->_x = 304;
|
||||
else if (_G(thor)->_dir == 3)
|
||||
_G(thor)->_x = 0;
|
||||
} else {
|
||||
_G(thor)->_x = (_G(newLevelTile) % 20) * 16;
|
||||
_G(thor)->_y = ((_G(newLevelTile) / 20) * 16) - 2;
|
||||
}
|
||||
_G(thor)->_lastX[0] = _G(thor)->_x;
|
||||
_G(thor)->_lastX[1] = _G(thor)->_x;
|
||||
_G(thor)->_lastY[0] = _G(thor)->_y;
|
||||
_G(thor)->_lastY[1] = _G(thor)->_y;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int specialTile(const Actor *actor, int x, int y, const int icon) {
|
||||
switch (icon) {
|
||||
case 201:
|
||||
case 202:
|
||||
case 203:
|
||||
case 204:
|
||||
break;
|
||||
case 205:
|
||||
case 206:
|
||||
case 207:
|
||||
case 208:
|
||||
return 1;
|
||||
case 209:
|
||||
case 210:
|
||||
case 214:
|
||||
case 215:
|
||||
case 216:
|
||||
case 217:
|
||||
return 0;
|
||||
case 224:
|
||||
case 225:
|
||||
case 226:
|
||||
case 227:
|
||||
if (!actor->_flying)
|
||||
return 0;
|
||||
return 1;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eraseDoor(const int x, const int y) {
|
||||
playSound(DOOR, false);
|
||||
_G(scrn)._iconGrid[y][x] = _G(scrn)._backgroundColor;
|
||||
}
|
||||
|
||||
int openDoor1(const int y, const int x) {
|
||||
if (_G(thorInfo)._keys > 0) {
|
||||
eraseDoor(x, y);
|
||||
_G(thorInfo)._keys--;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!_G(keyDoorInform)) {
|
||||
odinSpeaks(2003, 0);
|
||||
_G(keyDoorInform) = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashDoor1(const int y, const int x, const int amount) {
|
||||
if (_G(thorInfo)._jewels >= amount) {
|
||||
eraseDoor(x, y);
|
||||
_G(thorInfo)._jewels -= amount;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (amount == 10 && !_G(cashDoor1Inform)) {
|
||||
odinSpeaks(2005, 0);
|
||||
_G(cashDoor1Inform) = true;
|
||||
}
|
||||
|
||||
if (amount == 100 && !_G(cashDoor2Inform)) {
|
||||
odinSpeaks(2004, 0);
|
||||
_G(cashDoor2Inform) = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
34
engines/got/game/special_tile.h
Normal file
34
engines/got/game/special_tile.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/* 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 GOT_GAME_SPECIAL_TILE_H
|
||||
#define GOT_GAME_SPECIAL_TILE_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern int specialTileThor(int x, int y, int icon);
|
||||
extern int specialTile(const Actor *actor, int x, int y, int icon);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
67
engines/got/game/status.cpp
Normal file
67
engines/got/game/status.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/* 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 "got/game/status.h"
|
||||
#include "got/events.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
void addJewels(int num) {
|
||||
_G(thorInfo)._jewels = CLIP(_G(thorInfo)._jewels + num, 0, 999);
|
||||
}
|
||||
|
||||
void addScore(int num) {
|
||||
_G(thorInfo)._score = CLIP(_G(thorInfo)._score + num, 0l, 999999l);
|
||||
}
|
||||
|
||||
void addMagic(int num) {
|
||||
_G(thorInfo)._magic = CLIP(_G(thorInfo)._magic + num, 0, 150);
|
||||
}
|
||||
|
||||
void addHealth(int num) {
|
||||
_G(thor)->_health = CLIP(_G(thor)->_health + num, 0, 150);
|
||||
|
||||
if (_G(thor)->_health < 1)
|
||||
g_events->send(GameMessage("THOR_DIES"));
|
||||
}
|
||||
|
||||
void addKeys(int num) {
|
||||
_G(thorInfo)._keys = CLIP(_G(thorInfo)._keys + num, 0, 99);
|
||||
}
|
||||
|
||||
void fillHealth() {
|
||||
addHealth(150);
|
||||
}
|
||||
|
||||
void fillMagic() {
|
||||
addMagic(150);
|
||||
}
|
||||
|
||||
void fillScore(int num, const char *endMessage) {
|
||||
GameMessage msg("FILL_SCORE");
|
||||
if (endMessage)
|
||||
msg._stringValue = endMessage;
|
||||
msg._value = num;
|
||||
g_events->send("GameStatus", msg);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
38
engines/got/game/status.h
Normal file
38
engines/got/game/status.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* 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 GOT_GAME_STATUS_H
|
||||
#define GOT_GAME_STATUS_H
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern void addJewels(int num);
|
||||
extern void addScore(int num);
|
||||
extern void addMagic(int num);
|
||||
extern void addHealth(int num);
|
||||
extern void addKeys(int num);
|
||||
extern void fillHealth();
|
||||
extern void fillMagic();
|
||||
extern void fillScore(int num, const char *endMessage = nullptr);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
93
engines/got/gfx/font.cpp
Normal file
93
engines/got/gfx/font.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/* 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 "got/gfx/font.h"
|
||||
#include "common/file.h"
|
||||
#include "got/gfx/gfx_pics.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Gfx {
|
||||
|
||||
const byte DIALOG_COLOR[] = {14, 54, 120, 138, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
void Font::load() {
|
||||
Common::File f;
|
||||
if (!f.open("TEXT"))
|
||||
error("Could not open font");
|
||||
|
||||
_font.resize(f.size() / 72 + 32);
|
||||
|
||||
for (uint i = 32; i < _font.size(); ++i) {
|
||||
byte buff[8 * 9];
|
||||
f.read(buff, 8 * 9);
|
||||
|
||||
_font[i].create(8, 9);
|
||||
convertPaneDataToSurface(buff, _font[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Font::drawString(Graphics::ManagedSurface *src, const Common::Point &pos, const Common::String &text, int color) {
|
||||
const char *string = text.c_str();
|
||||
Common::Point pt = pos;
|
||||
|
||||
while (*string) {
|
||||
char ch = *string++;
|
||||
if (ch == '~' && Common::isXDigit(*string)) {
|
||||
ch = *string++;
|
||||
if (Common::isDigit(ch)) {
|
||||
ch -= 48;
|
||||
} else {
|
||||
ch = toupper(ch) - 55;
|
||||
}
|
||||
color = DIALOG_COLOR[(byte)ch];
|
||||
continue;
|
||||
}
|
||||
if (ch > 31 && ch < 127)
|
||||
drawChar(src, ch, pt.x, pt.y, color);
|
||||
|
||||
pt.x += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void Font::drawChar(Graphics::Surface *dst, const uint32 chr, const int x, const int y, const uint32 color) const {
|
||||
// Character drawing is done twice in the original:
|
||||
// first at y + 1 with color 0, then at y with the given color
|
||||
rawDrawChar(dst, chr, x, y + 1, 0);
|
||||
rawDrawChar(dst, chr, x, y, color);
|
||||
}
|
||||
|
||||
void Font::rawDrawChar(Graphics::Surface *dst, const uint32 chr, const int x, const int y, const uint32 color) const {
|
||||
const Graphics::ManagedSurface &glyph = _font[chr];
|
||||
|
||||
for (int yp = 0; yp < glyph.h; ++yp) {
|
||||
const int startY = y + yp;
|
||||
const byte *srcP = (const byte *)glyph.getBasePtr(0, yp);
|
||||
byte *destP = (byte *)dst->getBasePtr(x, startY);
|
||||
|
||||
for (int xp = 0; xp < glyph.w; ++xp, ++srcP, ++destP) {
|
||||
if (*srcP)
|
||||
*destP = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Gfx
|
||||
} // namespace Got
|
||||
63
engines/got/gfx/font.h
Normal file
63
engines/got/gfx/font.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/* 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 GOT_GFX_FONT_H
|
||||
#define GOT_GFX_FONT_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "graphics/font.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Gfx {
|
||||
|
||||
extern const byte DIALOG_COLOR[];
|
||||
|
||||
class Font : public Graphics::Font {
|
||||
private:
|
||||
Common::Array<Graphics::ManagedSurface> _font;
|
||||
|
||||
public:
|
||||
void load();
|
||||
|
||||
int getFontHeight() const override {
|
||||
return 9;
|
||||
}
|
||||
int getMaxCharWidth() const override {
|
||||
return 8;
|
||||
}
|
||||
int getCharWidth(uint32 chr) const override {
|
||||
return 8;
|
||||
}
|
||||
void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override;
|
||||
void drawChar(Graphics::ManagedSurface *dst, uint32 chr, int x, int y, uint32 color) const override {
|
||||
Graphics::Font::drawChar(dst, chr, x, y, color);
|
||||
}
|
||||
void rawDrawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const;
|
||||
|
||||
void drawString(Graphics::ManagedSurface *src, const Common::Point &pos,
|
||||
const Common::String &text, int color);
|
||||
};
|
||||
|
||||
} // namespace Gfx
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
146
engines/got/gfx/gfx_chunks.cpp
Normal file
146
engines/got/gfx/gfx_chunks.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
/* 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 "got/gfx/gfx_chunks.h"
|
||||
#include "common/file.h"
|
||||
#include "got/utils/compression.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Gfx {
|
||||
|
||||
void GraphicChunk::load(Common::SeekableReadStream *src, const byte *data) {
|
||||
_compressMode = src->readUint16LE();
|
||||
_offset = src->readUint32LE();
|
||||
_uncompressedSize = src->readUint16LE();
|
||||
_compressedSize = src->readUint16LE();
|
||||
_width = src->readUint16LE();
|
||||
_height = src->readUint16LE();
|
||||
|
||||
_data = data + _offset;
|
||||
}
|
||||
|
||||
void GraphicChunk::enable() {
|
||||
// Data already uncompressed, nothing further needed
|
||||
if (_compressMode == UNCOMPRESSED)
|
||||
return;
|
||||
|
||||
_decompressedData.resize(_uncompressedSize);
|
||||
|
||||
switch (_compressMode) {
|
||||
case LZSS:
|
||||
decompressLzss(_data, &_decompressedData[0], _uncompressedSize);
|
||||
break;
|
||||
|
||||
case RLE:
|
||||
decompressRle(_data, &_decompressedData[0], _uncompressedSize);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Unknown compression type %d", _compressMode);
|
||||
}
|
||||
|
||||
// Mark the entry as uncompressed, and point to the data
|
||||
_compressMode = UNCOMPRESSED;
|
||||
_data = &_decompressedData[0];
|
||||
}
|
||||
|
||||
GraphicChunk::operator const Graphics::ManagedSurface() const {
|
||||
Graphics::ManagedSurface s;
|
||||
s.w = s.pitch = _width;
|
||||
s.h = _height;
|
||||
s.format = Graphics::PixelFormat::createFormatCLUT8();
|
||||
s.setPixels(const_cast<byte *>(_data));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
GraphicChunk::operator const Gfx::Palette63() const {
|
||||
return Gfx::Palette63(_data);
|
||||
}
|
||||
|
||||
void GfxChunks::load() {
|
||||
// Get stream to access images
|
||||
Common::SeekableReadStream *f = getStream();
|
||||
|
||||
#if 0
|
||||
Common::DumpFile df;
|
||||
if (df.open("got.gfx")) {
|
||||
df.writeStream(f);
|
||||
f->seek(0);
|
||||
}
|
||||
df.close();
|
||||
#endif
|
||||
|
||||
// Keep a copy in memory for decoding images as needed
|
||||
_data = new byte[f->size()];
|
||||
f->read(_data, f->size());
|
||||
|
||||
// Set the number of images
|
||||
f->seek(0);
|
||||
_chunks.resize(f->readUint16LE());
|
||||
|
||||
// Iterate through loading the image metrics
|
||||
for (uint i = 0; i < _chunks.size(); ++i)
|
||||
_chunks[i].load(f, _data);
|
||||
|
||||
// Close the file
|
||||
delete f;
|
||||
|
||||
// Decompress two ranges of chunks by default
|
||||
for (uint i = 0; i < 34; ++i)
|
||||
_chunks[i].enable();
|
||||
}
|
||||
|
||||
GraphicChunk &GfxChunks::operator[](uint idx) {
|
||||
GraphicChunk &chunk = _chunks[idx];
|
||||
chunk.enable();
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *GfxChunks::getStream() const {
|
||||
// Check for stand-alone graphics file
|
||||
Common::File *f = new Common::File;
|
||||
if (f->open("got.gfx"))
|
||||
return f;
|
||||
delete f;
|
||||
|
||||
// Check for got.exe executable
|
||||
Common::File fExe;
|
||||
if (!fExe.open("got.exe"))
|
||||
error("Could not locate got graphics");
|
||||
|
||||
if (fExe.readUint16BE() != MKTAG16('M', 'Z'))
|
||||
error("Invalid exe header");
|
||||
|
||||
const int lastPageSize = fExe.readUint16LE();
|
||||
const int totalPages = fExe.readUint16LE();
|
||||
const int offset = lastPageSize ? ((totalPages - 1) << 9) + lastPageSize : totalPages << 9;
|
||||
|
||||
fExe.seek(offset);
|
||||
if (fExe.readUint16BE() != MKTAG16(0xe2, 0x4a))
|
||||
error("Invalid embedded graphics signature");
|
||||
|
||||
return fExe.readStream(fExe.size() - fExe.pos());
|
||||
}
|
||||
|
||||
} // namespace Gfx
|
||||
} // namespace Got
|
||||
109
engines/got/gfx/gfx_chunks.h
Normal file
109
engines/got/gfx/gfx_chunks.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/* 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 GOT_GFX_GFX_CHUNKS_H
|
||||
#define GOT_GFX_GFX_CHUNKS_H
|
||||
|
||||
#include "common/stream.h"
|
||||
#include "got/gfx/palette.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Gfx {
|
||||
|
||||
class GfxChunks;
|
||||
|
||||
enum CompressMode { UNCOMPRESSED = 0,
|
||||
LZSS = 1,
|
||||
RLE = 2 };
|
||||
|
||||
struct GraphicChunk {
|
||||
private:
|
||||
Common::Array<byte> _decompressedData;
|
||||
|
||||
public:
|
||||
int _compressMode = UNCOMPRESSED;
|
||||
uint32 _offset = 0;
|
||||
uint16 _uncompressedSize = 0;
|
||||
uint16 _compressedSize = 0;
|
||||
uint16 _width = 0;
|
||||
uint16 _height = 0;
|
||||
|
||||
const byte *_data = nullptr;
|
||||
|
||||
/**
|
||||
* Load the overall info for a chunk
|
||||
*/
|
||||
void load(Common::SeekableReadStream *src, const byte *data);
|
||||
|
||||
/**
|
||||
* Handles any decompression necessary for the entry
|
||||
*/
|
||||
void enable();
|
||||
|
||||
/**
|
||||
* Provides a managed surface wrapper for raw data
|
||||
*/
|
||||
operator const Graphics::ManagedSurface() const;
|
||||
|
||||
/**
|
||||
* Provides a data pointer, used for getting palette chunks
|
||||
*/
|
||||
operator const Gfx::Palette63() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface for accessing the graphics.got file.
|
||||
* In the release, this is embedded in the executable starting
|
||||
* at offset 18af2h onwards. The preceding two bytes should be E2 4A.
|
||||
* The collection is mostly images, but there are some palettes and
|
||||
* sounds included as well.
|
||||
*/
|
||||
class GfxChunks {
|
||||
private:
|
||||
Common::Array<GraphicChunk> _chunks;
|
||||
byte *_data = nullptr;
|
||||
|
||||
/**
|
||||
* Opens the graphics for access
|
||||
*/
|
||||
Common::SeekableReadStream *getStream() const;
|
||||
|
||||
public:
|
||||
~GfxChunks() {
|
||||
delete[] _data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the graphic data
|
||||
*/
|
||||
void load();
|
||||
|
||||
/**
|
||||
* Access a chunk
|
||||
*/
|
||||
GraphicChunk &operator[](uint idx);
|
||||
};
|
||||
|
||||
} // namespace Gfx
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
117
engines/got/gfx/gfx_pics.cpp
Normal file
117
engines/got/gfx/gfx_pics.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
/* 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 "got/gfx/gfx_pics.h"
|
||||
#include "common/file.h"
|
||||
#include "got/utils/file.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Gfx {
|
||||
|
||||
void convertPaneDataToSurface(const byte *src, Graphics::ManagedSurface &surf) {
|
||||
surf.setTransparentColor(0);
|
||||
|
||||
// It's split into 4 panes per 4 pixels, so we need
|
||||
// to juggle the pixels into their correct order
|
||||
for (int plane = 0; plane < 4; ++plane) {
|
||||
for (int y = 0; y < surf.h; ++y) {
|
||||
byte *dest = (byte *)surf.getBasePtr(plane, y);
|
||||
|
||||
for (int x = 0; x < (surf.w / 4); ++x, dest += 4, ++src) {
|
||||
// For some reason, both '0' and '15' are both hard-coded
|
||||
// as transparent colors in the graphics drawing. Simplify
|
||||
// this for ScummVM by changing all 15's to 0
|
||||
*dest = (*src == 15) ? 0 : *src;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GfxPics::clear() {
|
||||
delete[] _array;
|
||||
_array = nullptr;
|
||||
}
|
||||
|
||||
void GfxPics::resize(uint newSize) {
|
||||
assert(!_array); // Don't support multiple resizes
|
||||
_array = new Graphics::ManagedSurface[newSize];
|
||||
_size = newSize;
|
||||
}
|
||||
|
||||
void GfxPics::load(const Common::String &name, int blockSize) {
|
||||
File f(name);
|
||||
|
||||
// Set up array of images
|
||||
clear();
|
||||
if (blockSize == -1) {
|
||||
// Only a single image
|
||||
resize(1);
|
||||
blockSize = f.size();
|
||||
} else {
|
||||
resize(f.size() / blockSize);
|
||||
}
|
||||
|
||||
byte *buff = new byte[blockSize];
|
||||
|
||||
for (uint idx = 0; idx < size(); ++idx) {
|
||||
int w = f.readUint16LE() * 4;
|
||||
int h = f.readUint16LE();
|
||||
f.skip(2); // Unused transparent color. It's always 15
|
||||
f.read(buff, blockSize - 6);
|
||||
|
||||
Graphics::ManagedSurface &s = (*this)[idx];
|
||||
s.create(w, h);
|
||||
|
||||
convertPaneDataToSurface(buff, s);
|
||||
}
|
||||
|
||||
delete[] buff;
|
||||
}
|
||||
|
||||
GfxPics &GfxPics::operator=(const GfxPics &src) {
|
||||
clear();
|
||||
resize(src._size);
|
||||
|
||||
for (size_t i = 0; i < _size; ++i)
|
||||
_array[i].copyFrom(src._array[i]);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void BgPics::setArea(int area) {
|
||||
_area = area;
|
||||
load();
|
||||
}
|
||||
|
||||
void BgPics::load() {
|
||||
const Common::String name = Common::String::format("BPICS%d", _area);
|
||||
GfxPics::load(name, 262);
|
||||
|
||||
if (_area == 2) {
|
||||
// FIXME: Background tile 0xbe in part 2 is used for the invisible
|
||||
// maze in part 2 to get the shovel, but it's not drawing as black.
|
||||
// Manually set the transparent color for it so it's properly transparent
|
||||
(*this)[0xbe].setTransparentColor(31);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Gfx
|
||||
} // namespace Got
|
||||
98
engines/got/gfx/gfx_pics.h
Normal file
98
engines/got/gfx/gfx_pics.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/* 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 GOT_GFX_GFX_PICS_H
|
||||
#define GOT_GFX_GFX_PICS_H
|
||||
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Gfx {
|
||||
|
||||
/**
|
||||
* The original graphics screen was set up to use 4 panes,
|
||||
* where each pane had a single pixel, repeating every 4 pixels.
|
||||
* Because of this, graphics were stored with all the data for
|
||||
* each pane one at a time. This helper methods takes care of
|
||||
* "de-paneing" the graphics into a provided surface
|
||||
*/
|
||||
extern void convertPaneDataToSurface(const byte *src, Graphics::ManagedSurface &surf);
|
||||
|
||||
class GfxPics {
|
||||
private:
|
||||
Graphics::ManagedSurface *_array = nullptr;
|
||||
size_t _size = 0;
|
||||
|
||||
protected:
|
||||
public:
|
||||
~GfxPics() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear();
|
||||
void resize(uint newSize);
|
||||
void load(const Common::String &name, int blockSize);
|
||||
|
||||
Graphics::ManagedSurface &operator[](uint idx) {
|
||||
return _array[idx];
|
||||
}
|
||||
size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
GfxPics &operator=(const GfxPics &src);
|
||||
};
|
||||
|
||||
class BgPics : public GfxPics {
|
||||
private:
|
||||
int _area = 1;
|
||||
|
||||
public:
|
||||
void load();
|
||||
|
||||
bool getArea() const {
|
||||
return _area;
|
||||
}
|
||||
void setArea(int area);
|
||||
};
|
||||
|
||||
class Pics : public GfxPics {
|
||||
private:
|
||||
Common::String _resName;
|
||||
int _blockSize = -1;
|
||||
|
||||
public:
|
||||
Pics(const Common::String &resName, int blockSize = -1,
|
||||
bool immediateLoad = true) : _resName(resName), _blockSize(blockSize) {
|
||||
if (immediateLoad)
|
||||
load();
|
||||
}
|
||||
Pics() {}
|
||||
|
||||
void load() {
|
||||
GfxPics::load(_resName, _blockSize);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Gfx
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
42
engines/got/gfx/gfx_surface.cpp
Normal file
42
engines/got/gfx/gfx_surface.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/* 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 "got/gfx/gfx_surface.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Gfx {
|
||||
|
||||
void GfxSurface::print(const Common::Point &pos,
|
||||
const Common::String &text, int color) {
|
||||
_G(font).drawString(this, pos, text, color);
|
||||
}
|
||||
|
||||
void GfxSurface::printChar(uint32 chr, int x, int y, uint32 color) {
|
||||
_G(font).drawChar(this, chr, x, y, color);
|
||||
}
|
||||
|
||||
void GfxSurface::rawPrintChar(uint32 chr, int x, int y, uint32 color) {
|
||||
_G(font).rawDrawChar(surfacePtr(), chr, x, y, color);
|
||||
}
|
||||
|
||||
} // namespace Gfx
|
||||
} // namespace Got
|
||||
46
engines/got/gfx/gfx_surface.h
Normal file
46
engines/got/gfx/gfx_surface.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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 GOT_GFX_SURFACE_H
|
||||
#define GOT_GFX_SURFACE_H
|
||||
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Gfx {
|
||||
|
||||
class GfxSurface : public Graphics::ManagedSurface {
|
||||
public:
|
||||
GfxSurface() : Graphics::ManagedSurface() {}
|
||||
GfxSurface(Graphics::ManagedSurface &surf, const Common::Rect &bounds) : Graphics::ManagedSurface(surf, bounds) {}
|
||||
|
||||
/**
|
||||
* Write some text to the surface
|
||||
*/
|
||||
void print(const Common::Point &pos, const Common::String &text, int color);
|
||||
void printChar(uint32 chr, int x, int y, uint32 color);
|
||||
void rawPrintChar(uint32 chr, int x, int y, uint32 color);
|
||||
};
|
||||
|
||||
} // namespace Gfx
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
273
engines/got/gfx/image.cpp
Normal file
273
engines/got/gfx/image.cpp
Normal file
@@ -0,0 +1,273 @@
|
||||
/* 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 "got/gfx/image.h"
|
||||
#include "common/memstream.h"
|
||||
#include "got/events.h"
|
||||
#include "got/got.h"
|
||||
#include "got/utils/file.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
static void createSurface(Graphics::ManagedSurface &s, const byte *src) {
|
||||
s.create(16, 16);
|
||||
|
||||
// Both 0 and 15 are transparent colors, so as we load the
|
||||
// surface, standard on a single color
|
||||
byte *dest = (byte *)s.getPixels();
|
||||
for (int i = 0; i < 16 * 16; ++i, ++src, ++dest)
|
||||
*dest = (*src == 15) ? 0 : *src;
|
||||
|
||||
s.setTransparentColor(0);
|
||||
}
|
||||
|
||||
void setupActor(Actor *actor, const char num, const char dir, const int x, const int y) {
|
||||
actor->_nextFrame = 0; // Next frame to be shown
|
||||
actor->_frameCount = actor->_frameSpeed;
|
||||
actor->_dir = dir; // Direction of travel
|
||||
actor->_lastDir = dir; // Last direction of travel
|
||||
if (actor->_directions == 1)
|
||||
actor->_dir = 0;
|
||||
if (actor->_directions == 2)
|
||||
actor->_dir &= 1;
|
||||
if (actor->_directions == 4 && actor->_framesPerDirection == 1) {
|
||||
actor->_dir = 0;
|
||||
actor->_nextFrame = dir;
|
||||
}
|
||||
|
||||
actor->_x = x; // Actual X coordinates
|
||||
actor->_y = y; // Actual Y coordinates
|
||||
actor->_width = 16; // Actual X coordinates
|
||||
actor->_height = 16; // Actual Y coordinates
|
||||
actor->_center = 0; // Center of object
|
||||
actor->_lastX[0] = x; // Last X coordinates on each page
|
||||
actor->_lastX[1] = x;
|
||||
actor->_lastY[0] = y; // Last Y coordinates on each page
|
||||
actor->_lastY[1] = y;
|
||||
actor->_active = true; // true=active, false=not active
|
||||
actor->_moveCountdown = 8; // Count down to movement
|
||||
actor->_vulnerableCountdown = STAMINA; // Count down to vulnerability
|
||||
actor->_shotCountdown = 20; // Count down to another shot
|
||||
actor->_currNumShots = 0; // # of shots currently on screen
|
||||
actor->_creator = 0; // which actor # created this actor
|
||||
actor->_unpauseCountdown = 0; // Pause must be 0 to move
|
||||
actor->_show = 0;
|
||||
actor->_actorNum = num;
|
||||
actor->_counter = 0;
|
||||
actor->_moveCounter = 0;
|
||||
actor->_edgeCounter = 20;
|
||||
actor->_hitThor = false;
|
||||
actor->_rand = g_engine->getRandomNumber(99);
|
||||
actor->_temp1 = 0;
|
||||
actor->_initHealth = actor->_health;
|
||||
}
|
||||
|
||||
void make_actor_surface(Actor *actor) {
|
||||
assert(actor->_directions <= 4 && actor->_framesPerDirection <= 4);
|
||||
for (int d = 0; d < actor->_directions; d++) {
|
||||
for (int f = 0; f < actor->_framesPerDirection; f++) {
|
||||
Graphics::ManagedSurface &s = actor->pic[d][f];
|
||||
const byte *src = &_G(tmpBuff[256 * ((d * 4) + f)]);
|
||||
createSurface(s, src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int loadStandardActors() {
|
||||
loadActor(0, 100 + _G(thorInfo)._armor); // Load Thor
|
||||
_G(actor[0]).loadFixed(_G(tmpBuff) + 5120);
|
||||
setupActor(&_G(actor[0]), 0, 0, 100, 100);
|
||||
_G(thor) = &_G(actor[0]);
|
||||
|
||||
make_actor_surface(&_G(actor[0]));
|
||||
|
||||
_G(thorX1) = _G(thor)->_x + 2;
|
||||
_G(thorY1) = _G(thor)->_y + 2;
|
||||
_G(thorX2) = _G(thor)->_x + 14;
|
||||
_G(thorY2) = _G(thor)->_y + 14;
|
||||
|
||||
loadActor(0, 103 + _G(thorInfo)._armor); // Load hammer
|
||||
_G(actor[1]).loadFixed(_G(tmpBuff) + 5120);
|
||||
setupActor(&_G(actor[1]), 1, 0, 100, 100);
|
||||
_G(actor[1])._active = false;
|
||||
_G(hammer) = &_G(actor[1]);
|
||||
|
||||
make_actor_surface(&_G(actor[1]));
|
||||
|
||||
// Load sparkle
|
||||
loadActor(0, 106);
|
||||
_G(sparkle).loadFixed(_G(tmpBuff) + 5120);
|
||||
setupActor(&_G(sparkle), 20, 0, 100, 100);
|
||||
_G(sparkle)._active = false;
|
||||
make_actor_surface(&_G(sparkle));
|
||||
|
||||
// Load explosion
|
||||
loadActor(0, 107);
|
||||
_G(explosion).loadFixed(_G(tmpBuff) + 5120);
|
||||
setupActor(&_G(explosion), 21, 0, 100, 100);
|
||||
_G(explosion)._active = false;
|
||||
make_actor_surface(&_G(explosion));
|
||||
|
||||
// Load tornado
|
||||
loadActor(0, 108);
|
||||
_G(magicItem[0]).loadFixed((const byte *)_G(tmpBuff) + 5120);
|
||||
Common::copy(_G(tmpBuff), _G(tmpBuff) + 1024, _G(magicPic[0]));
|
||||
|
||||
setupActor(&_G(magicItem[0]), 20, 0, 0, 0);
|
||||
_G(magicItem[0])._active = false;
|
||||
|
||||
// Load shield
|
||||
loadActor(0, 109);
|
||||
_G(magicItem[1]).loadFixed((const byte *)_G(tmpBuff) + 5120);
|
||||
Common::copy(_G(tmpBuff), _G(tmpBuff) + 1024, _G(magicPic[1]));
|
||||
|
||||
setupActor(&_G(magicItem[1]), 20, 0, 0, 0);
|
||||
_G(magicItem[1])._active = false;
|
||||
|
||||
_G(actor[2])._active = false;
|
||||
|
||||
make_actor_surface(&_G(magicItem[0]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void showEnemies() {
|
||||
for (int i = 3; i < MAX_ACTORS; i++)
|
||||
_G(actor[i])._active = false;
|
||||
|
||||
for (int i = 0; i < MAX_ENEMIES; i++)
|
||||
_G(enemyType[i]) = 0;
|
||||
|
||||
for (int i = 0; i < MAX_ENEMIES; i++) {
|
||||
if (_G(scrn)._actorType[i] > 0) {
|
||||
const int id = loadEnemy(_G(scrn)._actorType[i]);
|
||||
if (id >= 0) {
|
||||
_G(actor[i + 3]) = _G(enemy[id]);
|
||||
|
||||
const int d = _G(scrn)._actorDir[i];
|
||||
|
||||
setupActor(&_G(actor[i + 3]), i + 3, d, (_G(scrn)._actorLoc[i] % 20) * 16,
|
||||
(_G(scrn)._actorLoc[i] / 20) * 16);
|
||||
_G(actor[i + 3])._initDir = _G(scrn)._actorDir[i];
|
||||
_G(actor[i + 3])._passValue = _G(scrn)._actorValue[i];
|
||||
|
||||
if (_G(actor[i + 3])._moveType == 23) {
|
||||
// Spinball
|
||||
if (_G(actor[i + 3])._passValue & 1)
|
||||
_G(actor[i + 3])._moveType = 24;
|
||||
}
|
||||
|
||||
if (_G(scrn)._actorInvis[i])
|
||||
_G(actor[i + 3])._active = false;
|
||||
}
|
||||
|
||||
_G(etype[i]) = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int loadEnemy(const int type) {
|
||||
for (int i = 0; i < MAX_ENEMIES; i++) {
|
||||
if (_G(enemyType[i]) == type)
|
||||
return i;
|
||||
}
|
||||
|
||||
if (!loadActor(1, type)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int e = -1;
|
||||
for (int i = 0; i < MAX_ENEMIES; i++) {
|
||||
if (!_G(enemyType[i])) {
|
||||
e = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (e == -1)
|
||||
return -1;
|
||||
|
||||
Common::MemoryReadStream inf(_G(tmpBuff) + 5120, 40);
|
||||
_G(enemy[e]).loadFixed(&inf);
|
||||
|
||||
make_actor_surface(&_G(enemy[e]));
|
||||
_G(enemyType[e]) = type;
|
||||
_G(enemy[e])._shotType = 0;
|
||||
|
||||
if (_G(enemy[e])._numShotsAllowed) {
|
||||
_G(enemy[e])._shotType = e + 1;
|
||||
|
||||
// Set up shot info
|
||||
_G(shot[e]).loadFixed(_G(tmpBuff) + 5160);
|
||||
|
||||
// Loop to set up graphics
|
||||
for (int d = 0; d < _G(shot[e])._directions; d++) {
|
||||
for (int f = 0; f < _G(shot[e])._framesPerDirection; f++) {
|
||||
if (_G(shot[e])._directions < _G(shot[e])._framesPerDirection) {
|
||||
Graphics::ManagedSurface &s = _G(shot[e]).pic[d][f];
|
||||
const byte *src = &_G(tmpBuff[4096 + (256 * ((d * 4) + f))]);
|
||||
createSurface(s, src);
|
||||
} else {
|
||||
Graphics::ManagedSurface &s = _G(shot[e]).pic[f][d];
|
||||
const byte *src = &_G(tmpBuff[4096 + (256 * ((f * 4) + d))]);
|
||||
createSurface(s, src);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
int actorVisible(const int invisNum) {
|
||||
for (int i = 0; i < MAX_ENEMIES; i++) {
|
||||
if (_G(scrn)._actorInvis[i] == invisNum) {
|
||||
const int etype = _G(etype[i]);
|
||||
if (etype >= 0 && !_G(actor[i + 3])._active) {
|
||||
_G(actor[i + 3]) = _G(enemy[etype]);
|
||||
|
||||
int d = _G(scrn)._actorDir[i];
|
||||
setupActor(&_G(actor[i + 3]), i + 3, d, (_G(scrn)._actorLoc[i] % 20) * 16,
|
||||
(_G(scrn)._actorLoc[i] / 20) * 16);
|
||||
_G(actor[i + 3])._initDir = _G(scrn)._actorDir[i];
|
||||
_G(actor[i + 3])._passValue = _G(scrn)._actorValue[i];
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void setupMagicItem(const int item) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
createSurface(_G(magicItem[item]).pic[i / 4][i % 4], &_G(magicPic[item][256 * i]));
|
||||
}
|
||||
}
|
||||
|
||||
void loadNewThor() {
|
||||
loadActor(0, 100 + _G(thorInfo)._armor); // Load Thor
|
||||
|
||||
make_actor_surface(&_G(actor[0]));
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
39
engines/got/gfx/image.h
Normal file
39
engines/got/gfx/image.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* 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 GOT_GFX_IMAGE_H
|
||||
#define GOT_GFX_IMAGE_H
|
||||
|
||||
#include "got/data/defines.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern void setupActor(Actor *actor, char num, char dir, int x, int y);
|
||||
extern int loadStandardActors();
|
||||
extern void showEnemies();
|
||||
extern int loadEnemy(int type);
|
||||
extern int actorVisible(int invisNum);
|
||||
extern void setupMagicItem(int item);
|
||||
extern void loadNewThor();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
144
engines/got/gfx/palette.cpp
Normal file
144
engines/got/gfx/palette.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/* 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 "got/gfx/palette.h"
|
||||
#include "common/events.h"
|
||||
#include "common/system.h"
|
||||
#include "got/got.h"
|
||||
#include "got/utils/file.h"
|
||||
#include "got/vars.h"
|
||||
#include "graphics/paletteman.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Gfx {
|
||||
|
||||
#define FADE_STEPS 10
|
||||
|
||||
static byte saved_palette[Graphics::PALETTE_SIZE];
|
||||
|
||||
Palette63::Palette63(const byte *pal) {
|
||||
for (uint i = 0; i < Graphics::PALETTE_SIZE; ++i)
|
||||
_pal[i] = pal[i] << 2;
|
||||
}
|
||||
|
||||
void loadPalette() {
|
||||
if (resourceRead("PALETTE", saved_palette) < 0)
|
||||
error("Cannot Read PALETTE");
|
||||
|
||||
g_system->getPaletteManager()->setPalette(saved_palette, 0, 256);
|
||||
}
|
||||
|
||||
void setScreenPal() {
|
||||
byte pal[3];
|
||||
|
||||
xGetPal(pal, 1, _G(scrn)._palColors[0]);
|
||||
xSetPal(251, pal[0], pal[1], pal[2]);
|
||||
xGetPal(pal, 1, _G(scrn)._palColors[1]);
|
||||
xSetPal(252, pal[0], pal[1], pal[2]);
|
||||
xGetPal(pal, 1, _G(scrn)._palColors[2]);
|
||||
xSetPal(253, pal[0], pal[1], pal[2]);
|
||||
}
|
||||
|
||||
void xSetPal(const byte color, const byte R, const byte G, const byte B) {
|
||||
byte rgb[3] = {R, G, B};
|
||||
g_system->getPaletteManager()->setPalette(rgb, color, 1);
|
||||
}
|
||||
|
||||
void xSetPal(const byte *pal) {
|
||||
g_system->getPaletteManager()->setPalette(pal, 0, Graphics::PALETTE_COUNT);
|
||||
}
|
||||
|
||||
void setPalette(const byte *pal) {
|
||||
xSetPal(pal);
|
||||
Common::copy(pal, pal + Graphics::PALETTE_SIZE, saved_palette);
|
||||
}
|
||||
|
||||
void xGetPal(byte *pal, const int numColors, const int startIndex) {
|
||||
g_system->getPaletteManager()->grabPalette(pal, startIndex, numColors);
|
||||
}
|
||||
|
||||
void fadeOut() {
|
||||
byte tempPal[Graphics::PALETTE_SIZE];
|
||||
const byte *srcP;
|
||||
byte *destP;
|
||||
int count;
|
||||
Common::Event evt;
|
||||
|
||||
xGetPal(saved_palette, Graphics::PALETTE_COUNT, 0);
|
||||
|
||||
for (int step = FADE_STEPS - 1; step >= 0; --step) {
|
||||
// Set each palette RGB proportionately
|
||||
for (srcP = &saved_palette[0], destP = &tempPal[0], count = 0;
|
||||
count < Graphics::PALETTE_SIZE; ++count, ++srcP, ++destP) {
|
||||
*destP = *srcP * step / FADE_STEPS;
|
||||
}
|
||||
|
||||
// Set new palette
|
||||
xSetPal(tempPal);
|
||||
|
||||
// Use up any pending events and update the screen
|
||||
while (g_system->getEventManager()->pollEvent(evt)) {
|
||||
if (evt.type == Common::EVENT_QUIT)
|
||||
return;
|
||||
}
|
||||
|
||||
g_events->getScreen()->update();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
}
|
||||
|
||||
void fadeIn(const byte *pal) {
|
||||
byte tempPal[Graphics::PALETTE_SIZE];
|
||||
const byte *srcP;
|
||||
byte *destP;
|
||||
int count;
|
||||
Common::Event evt;
|
||||
|
||||
if (pal)
|
||||
Common::copy(pal, pal + Graphics::PALETTE_SIZE, saved_palette);
|
||||
|
||||
// Start with a black palette
|
||||
Common::fill(tempPal, tempPal + Graphics::PALETTE_SIZE, 0);
|
||||
xSetPal(tempPal);
|
||||
|
||||
for (int step = 1; step <= FADE_STEPS; ++step) {
|
||||
// Set each palette RGB proportionately
|
||||
for (srcP = &saved_palette[0], destP = &tempPal[0], count = 0;
|
||||
count < Graphics::PALETTE_SIZE; ++count, ++srcP, ++destP) {
|
||||
*destP = *srcP * step / FADE_STEPS;
|
||||
}
|
||||
|
||||
// Set new palette
|
||||
xSetPal(tempPal);
|
||||
|
||||
// Use up any pending events and update the screen
|
||||
while (g_system->getEventManager()->pollEvent(evt)) {
|
||||
if (evt.type == Common::EVENT_QUIT)
|
||||
return;
|
||||
}
|
||||
|
||||
g_events->getScreen()->update();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Gfx
|
||||
} // namespace Got
|
||||
52
engines/got/gfx/palette.h
Normal file
52
engines/got/gfx/palette.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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 GOT_GFX_PALETTE_H
|
||||
#define GOT_GFX_PALETTE_H
|
||||
|
||||
#include "graphics/paletteman.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Gfx {
|
||||
|
||||
struct Palette63 {
|
||||
byte _pal[Graphics::PALETTE_SIZE] = {};
|
||||
Palette63() {}
|
||||
Palette63(const byte *pal);
|
||||
|
||||
operator const byte *() const {
|
||||
return _pal;
|
||||
}
|
||||
};
|
||||
|
||||
extern void loadPalette();
|
||||
extern void setScreenPal();
|
||||
extern void setPalette(const byte *pal);
|
||||
extern void xSetPal(byte color, byte R, byte G, byte B);
|
||||
extern void xSetPal(const byte *pal);
|
||||
extern void xGetPal(byte *pal, int numColors, int startIndex);
|
||||
extern void fadeOut();
|
||||
extern void fadeIn(const byte *pal = nullptr);
|
||||
|
||||
} // namespace Gfx
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
256
engines/got/got.cpp
Normal file
256
engines/got/got.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
/* 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 "got/got.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/system.h"
|
||||
#include "common/translation.h"
|
||||
#include "engines/util.h"
|
||||
#include "got/console.h"
|
||||
#include "got/game/init.h"
|
||||
#include "got/game/main.h"
|
||||
#include "got/game/move.h"
|
||||
#include "got/gfx/image.h"
|
||||
#include "got/utils/res_archive.h"
|
||||
#include "got/views/game_content.h"
|
||||
#include "graphics/paletteman.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
#define SAVEGAME_VERSION 1
|
||||
|
||||
GotEngine *g_engine;
|
||||
|
||||
GotEngine::GotEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
|
||||
_gameDescription(gameDesc), _randomSource("Got") {
|
||||
g_engine = this;
|
||||
}
|
||||
|
||||
GotEngine::~GotEngine() {
|
||||
_mixer->stopAll();
|
||||
}
|
||||
|
||||
uint32 GotEngine::getFeatures() const {
|
||||
return _gameDescription->flags;
|
||||
}
|
||||
|
||||
bool GotEngine::isDemo() const {
|
||||
return (_gameDescription->flags & ADGF_DEMO) != 0;
|
||||
}
|
||||
|
||||
Common::String GotEngine::getGameId() const {
|
||||
return _gameDescription->gameId;
|
||||
}
|
||||
|
||||
Common::Error GotEngine::run() {
|
||||
// Initialize 320x240 paletted graphics mode. Note that the original
|
||||
// main menu/dialogs ran at 320x200, but the game ran at 320x240.
|
||||
initGraphics(320, 240);
|
||||
|
||||
// Set the engine's debugger console
|
||||
setDebugger(new Console());
|
||||
|
||||
// Initialize resources and variables
|
||||
resInit();
|
||||
_vars.load();
|
||||
|
||||
// General initialization
|
||||
if (_G(demo))
|
||||
initGame();
|
||||
syncSoundSettings();
|
||||
|
||||
#ifdef USE_TTS
|
||||
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
|
||||
if (ttsMan) {
|
||||
ttsMan->enable(ConfMan.getBool("tts_enabled"));
|
||||
ttsMan->setLanguage(ConfMan.get("language"));
|
||||
}
|
||||
#endif
|
||||
|
||||
runGame();
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
Common::Error GotEngine::saveGameStream(Common::WriteStream *stream, bool isAutosave) {
|
||||
stream->writeByte(SAVEGAME_VERSION);
|
||||
Common::Serializer s(nullptr, stream);
|
||||
s.setVersion(SAVEGAME_VERSION);
|
||||
|
||||
return syncGame(s);
|
||||
}
|
||||
|
||||
Common::Error GotEngine::loadGameStream(Common::SeekableReadStream *stream) {
|
||||
byte version = stream->readByte();
|
||||
if (version != SAVEGAME_VERSION)
|
||||
error("Invalid savegame version");
|
||||
|
||||
Common::Serializer s(stream, nullptr);
|
||||
s.setVersion(version);
|
||||
|
||||
return syncGame(s);
|
||||
}
|
||||
|
||||
Common::Error GotEngine::syncGame(Common::Serializer &s) {
|
||||
char title[32];
|
||||
Common::fill(title, title + 32, 0);
|
||||
Common::strcpy_s(title, _G(playerName).c_str());
|
||||
s.syncBytes((byte *)title, 32);
|
||||
if (s.isLoading())
|
||||
_G(playerName) = title;
|
||||
|
||||
_G(setup).sync(s);
|
||||
|
||||
if (s.isLoading()) {
|
||||
// For savegames loaded directly from the ScummVM launcher,
|
||||
// take care of initializing game defaults before rest of loading
|
||||
if (!firstView() || firstView()->getName() != "Game")
|
||||
initGame();
|
||||
|
||||
int area = _G(setup)._areaNum;
|
||||
if (area == 0)
|
||||
area = 1;
|
||||
|
||||
if (area != _G(area)) {
|
||||
_G(area) = area;
|
||||
g_vars->loadArea();
|
||||
}
|
||||
}
|
||||
|
||||
_G(thorInfo).sync(s);
|
||||
_G(sdData).sync(s);
|
||||
|
||||
if (s.isLoading())
|
||||
savegameLoaded();
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
void GotEngine::savegameLoaded() {
|
||||
_G(currentArea) = _G(thorInfo)._lastScreen;
|
||||
|
||||
_G(thor)->_x = (_G(thorInfo)._lastIcon % 20) * 16;
|
||||
_G(thor)->_y = ((_G(thorInfo)._lastIcon / 20) * 16) - 1;
|
||||
if (_G(thor)->_x < 1)
|
||||
_G(thor)->_x = 1;
|
||||
if (_G(thor)->_y < 0)
|
||||
_G(thor)->_y = 0;
|
||||
_G(thor)->_dir = _G(thorInfo)._lastDir;
|
||||
_G(thor)->_lastDir = _G(thorInfo)._lastDir;
|
||||
_G(thor)->_health = _G(thorInfo)._lastHealth;
|
||||
_G(thor)->_numMoves = 1;
|
||||
_G(thor)->_vulnerableCountdown = 60;
|
||||
_G(thor)->_show = 60;
|
||||
_G(thor)->_moveCountdown = 6;
|
||||
if (_G(area) == 2)
|
||||
_G(thorInfo)._armor = 1;
|
||||
if (_G(area) == 3)
|
||||
_G(thorInfo)._armor = 10;
|
||||
loadNewThor();
|
||||
|
||||
g_vars->resetEndGameFlags();
|
||||
|
||||
_G(setup)._musicEnabled = _G(musicFlag);
|
||||
_G(setup)._digitalSound = _G(soundFlag);
|
||||
|
||||
if (_G(setup)._musicEnabled) {
|
||||
if (GAME1 && _G(currentArea) == 59) {
|
||||
musicPlay(5, true);
|
||||
} else {
|
||||
musicPlay(_G(levelMusic), true);
|
||||
}
|
||||
} else {
|
||||
_G(setup)._musicEnabled = true;
|
||||
musicPause();
|
||||
_G(setup)._musicEnabled = false;
|
||||
}
|
||||
|
||||
_G(gameOver) = _G(setup)._gameOver != 0;
|
||||
_G(slowMode) = _G(setup)._slowMode;
|
||||
|
||||
g_events->replaceView("Game", true);
|
||||
setupLoad();
|
||||
}
|
||||
|
||||
bool GotEngine::canLoadGameStateCurrently(Common::U32String *msg) {
|
||||
if (_G(demo)) {
|
||||
*msg = _("Savegames are not available in demo mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only allow if not in the middle of area transition, dying, etc.
|
||||
return _G(gameMode) == MODE_NORMAL;
|
||||
}
|
||||
|
||||
bool GotEngine::canSaveGameStateCurrently(Common::U32String *msg) {
|
||||
if (_G(demo)) {
|
||||
*msg = _("Savegames are not available in demo mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't allowing saving when not in-game
|
||||
if (!firstView() || firstView()->getName() != "Game" || _G(gameOver))
|
||||
return false;
|
||||
|
||||
// Only allow if not in the middle of area transition, dying, etc.
|
||||
return _G(gameMode) == MODE_NORMAL;
|
||||
}
|
||||
|
||||
void GotEngine::syncSoundSettings() {
|
||||
Engine::syncSoundSettings();
|
||||
|
||||
_G(sound).syncSoundSettings();
|
||||
}
|
||||
|
||||
void GotEngine::pauseEngineIntern(bool pause) {
|
||||
g_vars->clearKeyFlags();
|
||||
if (_G(gameMode) == MODE_LIGHTNING)
|
||||
_G(gameMode) = MODE_NORMAL;
|
||||
|
||||
if (_G(tornadoUsed)) {
|
||||
_G(tornadoUsed) = false;
|
||||
actorDestroyed(&_G(actor[2]));
|
||||
}
|
||||
|
||||
if (_G(shieldOn)) {
|
||||
_G(actor[2])._dead = 2;
|
||||
_G(actor[2])._active = false;
|
||||
_G(shieldOn) = false;
|
||||
}
|
||||
|
||||
_G(thunderSnakeCounter) = 0;
|
||||
|
||||
if (pause) {
|
||||
_G(sound).musicPause();
|
||||
}
|
||||
else {
|
||||
_G(sound).musicResume();
|
||||
}
|
||||
|
||||
Engine::pauseEngineIntern(pause);
|
||||
}
|
||||
|
||||
Common::String GotEngine::getHighScoresSaveName() const {
|
||||
return Common::String::format("%s-scores.dat", _targetName.c_str());
|
||||
}
|
||||
|
||||
} // End of namespace Got
|
||||
107
engines/got/got.h
Normal file
107
engines/got/got.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* 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 GOT_H
|
||||
#define GOT_H
|
||||
|
||||
#include "common/error.h"
|
||||
#include "common/random.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/serializer.h"
|
||||
#include "common/system.h"
|
||||
#include "engines/engine.h"
|
||||
#include "got/events.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
struct GotGameDescription;
|
||||
|
||||
class GotEngine : public Engine, public Events {
|
||||
private:
|
||||
const ADGameDescription *_gameDescription;
|
||||
Common::RandomSource _randomSource;
|
||||
|
||||
void savegameLoaded();
|
||||
|
||||
protected:
|
||||
// Engine APIs
|
||||
Common::Error run() override;
|
||||
|
||||
/**
|
||||
* Returns true if the game should quit
|
||||
*/
|
||||
bool shouldQuit() const override {
|
||||
return Engine::shouldQuit();
|
||||
}
|
||||
|
||||
public:
|
||||
Vars _vars;
|
||||
|
||||
public:
|
||||
GotEngine(OSystem *syst, const ADGameDescription *gameDesc);
|
||||
~GotEngine() override;
|
||||
|
||||
uint32 getFeatures() const;
|
||||
bool isDemo() const override;
|
||||
|
||||
/**
|
||||
* Returns the game Id
|
||||
*/
|
||||
Common::String getGameId() const;
|
||||
|
||||
/**
|
||||
* Gets a random number
|
||||
*/
|
||||
uint32 getRandomNumber(uint maxNum) {
|
||||
return _randomSource.getRandomNumber(maxNum);
|
||||
}
|
||||
|
||||
bool hasFeature(EngineFeature f) const override {
|
||||
return (f == kSupportsLoadingDuringRuntime) ||
|
||||
(f == kSupportsSavingDuringRuntime) ||
|
||||
(f == kSupportsReturnToLauncher);
|
||||
};
|
||||
|
||||
bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override;
|
||||
bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override;
|
||||
|
||||
/**
|
||||
* Uses a serializer to allow implementing savegame
|
||||
* loading and saving using a single method
|
||||
*/
|
||||
Common::Error syncGame(Common::Serializer &s);
|
||||
|
||||
Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
|
||||
Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
|
||||
|
||||
void syncSoundSettings() override;
|
||||
void pauseEngineIntern(bool pause) override;
|
||||
|
||||
Common::String getHighScoresSaveName() const;
|
||||
};
|
||||
|
||||
extern GotEngine *g_engine;
|
||||
#define SHOULD_QUIT ::Got::g_engine->shouldQuit()
|
||||
|
||||
} // End of namespace Got
|
||||
|
||||
#endif // GOT_H
|
||||
43
engines/got/messages.cpp
Normal file
43
engines/got/messages.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/* 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 "got/messages.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
MouseMessage::MouseMessage(Common::EventType type,
|
||||
const Common::Point &pos) : Message(), _pos(pos) {
|
||||
switch (type) {
|
||||
case Common::EVENT_RBUTTONDOWN:
|
||||
case Common::EVENT_RBUTTONUP:
|
||||
_button = MB_RIGHT;
|
||||
break;
|
||||
case Common::EVENT_MBUTTONDOWN:
|
||||
case Common::EVENT_MBUTTONUP:
|
||||
_button = MB_MIDDLE;
|
||||
break;
|
||||
default:
|
||||
_button = MB_LEFT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
99
engines/got/messages.h
Normal file
99
engines/got/messages.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/* 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 GOT_MESSAGES_H
|
||||
#define GOT_MESSAGES_H
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/str.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
class UIElement;
|
||||
|
||||
struct Message {};
|
||||
|
||||
struct FocusMessage : public Message {
|
||||
UIElement *_priorView = nullptr;
|
||||
FocusMessage() : Message() {}
|
||||
FocusMessage(UIElement *priorView) : Message(), _priorView(priorView) {}
|
||||
};
|
||||
|
||||
struct UnfocusMessage : public Message {};
|
||||
struct MouseEnterMessage : public Message {};
|
||||
struct MouseLeaveMessage : public Message {};
|
||||
|
||||
struct KeypressMessage : public Message, public Common::KeyState {
|
||||
KeypressMessage() : Message() {}
|
||||
KeypressMessage(const Common::KeyState &ks) : Message(), Common::KeyState(ks) {}
|
||||
};
|
||||
|
||||
struct MouseMessage : public Message {
|
||||
enum Button { MB_LEFT,
|
||||
MB_RIGHT,
|
||||
MB_MIDDLE };
|
||||
Button _button;
|
||||
Common::Point _pos;
|
||||
|
||||
MouseMessage() : Message(), _button(MB_LEFT) {}
|
||||
MouseMessage(Button btn, const Common::Point &pos) : Message(), _button(btn), _pos(pos) {}
|
||||
MouseMessage(Common::EventType type, const Common::Point &pos);
|
||||
};
|
||||
struct MouseDownMessage : public MouseMessage {
|
||||
MouseDownMessage() : MouseMessage() {}
|
||||
MouseDownMessage(Button btn, const Common::Point &pos) : MouseMessage(btn, pos) {}
|
||||
MouseDownMessage(Common::EventType type, const Common::Point &pos) : MouseMessage(type, pos) {}
|
||||
};
|
||||
struct MouseUpMessage : public MouseMessage {
|
||||
MouseUpMessage() : MouseMessage() {}
|
||||
MouseUpMessage(Button btn, const Common::Point &pos) : MouseMessage(btn, pos) {}
|
||||
MouseUpMessage(Common::EventType type, const Common::Point &pos) : MouseMessage(type, pos) {}
|
||||
};
|
||||
typedef MouseMessage MouseMoveMessage;
|
||||
|
||||
struct GameMessage : public Message {
|
||||
Common::String _name;
|
||||
int _value;
|
||||
Common::String _stringValue;
|
||||
|
||||
GameMessage() : Message(), _value(-1) {}
|
||||
GameMessage(const Common::String &name) : Message(), _name(name), _value(-1) {}
|
||||
GameMessage(const Common::String &name, int value) : Message(), _name(name), _value(value) {}
|
||||
GameMessage(const Common::String &name, const Common::String &value) : Message(), _name(name), _stringValue(value), _value(0) {}
|
||||
};
|
||||
|
||||
struct ValueMessage : public Message {
|
||||
int _value;
|
||||
|
||||
ValueMessage() : Message(), _value(0) {}
|
||||
ValueMessage(int value) : Message(), _value(value) {}
|
||||
};
|
||||
|
||||
struct ActionMessage : public Message {
|
||||
int _action;
|
||||
|
||||
ActionMessage() : Message(), _action(0) {}
|
||||
ActionMessage(int action) : Message(), _action(action) {}
|
||||
};
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
128
engines/got/metaengine.cpp
Normal file
128
engines/got/metaengine.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/* 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/translation.h"
|
||||
#include "backends/keymapper/action.h"
|
||||
#include "backends/keymapper/keymapper.h"
|
||||
#include "got/metaengine.h"
|
||||
#include "got/detection.h"
|
||||
#include "got/got.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
static const ADExtraGuiOptionsMap optionsList[] = {
|
||||
{
|
||||
GAMEOPTION_ORIGINAL_SAVELOAD,
|
||||
{
|
||||
_s("Use original save/load screens"),
|
||||
_s("Use the original save/load screens instead of the ScummVM ones"),
|
||||
"original_menus",
|
||||
false,
|
||||
0,
|
||||
0
|
||||
}
|
||||
},
|
||||
|
||||
#ifdef USE_TTS
|
||||
{
|
||||
GAMEOPTION_TTS,
|
||||
{
|
||||
_s("Enable Text to Speech"),
|
||||
_s("Use TTS to read text in the game (if TTS is available)"),
|
||||
"tts_enabled",
|
||||
false,
|
||||
0,
|
||||
0
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
AD_EXTRA_GUI_OPTIONS_TERMINATOR
|
||||
};
|
||||
|
||||
struct KeybindingRecord {
|
||||
KeybindingAction _action;
|
||||
const char *_id;
|
||||
const char *_desc;
|
||||
const char *_key;
|
||||
const char *_joy;
|
||||
};
|
||||
|
||||
static const KeybindingRecord GAME_KEYS[] = {
|
||||
{ KEYBIND_UP, "UP", _s("Up"), "UP", "JOY_UP"},
|
||||
{ KEYBIND_DOWN, "DOWN", _s("Down"), "DOWN", "JOY_DOWN"},
|
||||
{ KEYBIND_LEFT, "LEFT", _s("Left"), "LEFT", "JOY_LEFT"},
|
||||
{ KEYBIND_RIGHT, "RIGHT", _s("Right"), "RIGHT", "JOY_RIGHT"},
|
||||
{ KEYBIND_FIRE, "FIRE", _s("Fire"), "LALT", "JOY_A" },
|
||||
{ KEYBIND_MAGIC, "MAGIC", _s("Magic"), "LCTRL", "JOY_B" },
|
||||
{ KEYBIND_SELECT, "SELECT", _s("Select"), "SPACE", "JOY_X" },
|
||||
// I18N: ESC key
|
||||
{ KEYBIND_ESCAPE, "ESCAPE", _s("Escape"), "ESCAPE", "JOY_Y" },
|
||||
{ KEYBIND_THOR_DIES, "THOR_DIES", _s("Thor dies"), "d", nullptr },
|
||||
{ KEYBIND_NONE, nullptr, nullptr, nullptr, nullptr }
|
||||
};
|
||||
|
||||
} // End of namespace Got
|
||||
|
||||
const char *GotMetaEngine::getName() const {
|
||||
return "got";
|
||||
}
|
||||
|
||||
const ADExtraGuiOptionsMap *GotMetaEngine::getAdvancedExtraGuiOptions() const {
|
||||
return Got::optionsList;
|
||||
}
|
||||
|
||||
Common::Error GotMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
|
||||
*engine = new Got::GotEngine(syst, desc);
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
bool GotMetaEngine::hasFeature(MetaEngineFeature f) const {
|
||||
return checkExtendedSaves(f) ||
|
||||
(f == kSupportsLoadingDuringStartup);
|
||||
}
|
||||
|
||||
Common::Array<Common::Keymap *> GotMetaEngine::initKeymaps(const char *target) const {
|
||||
Common::KeymapArray keymapArray;
|
||||
Common::Keymap *keyMap = new Common::Keymap(Common::Keymap::kKeymapTypeGame, "got", _s("Game Keys"));
|
||||
keymapArray.push_back(keyMap);
|
||||
|
||||
for (const Got::KeybindingRecord *r = Got::GAME_KEYS; r->_id; ++r) {
|
||||
Common::Action *act = new Common::Action(r->_id, _(r->_desc));
|
||||
act->setCustomEngineActionEvent(r->_action);
|
||||
act->addDefaultInputMapping(r->_key);
|
||||
if (r->_joy)
|
||||
act->addDefaultInputMapping(r->_joy);
|
||||
if (r->_action == Got::KEYBIND_SELECT)
|
||||
act->addDefaultInputMapping("RETURN");
|
||||
|
||||
keyMap->addAction(act);
|
||||
}
|
||||
|
||||
return keymapArray;
|
||||
}
|
||||
|
||||
|
||||
#if PLUGIN_ENABLED_DYNAMIC(GOT)
|
||||
REGISTER_PLUGIN_DYNAMIC(GOT, PLUGIN_TYPE_ENGINE, GotMetaEngine);
|
||||
#else
|
||||
REGISTER_PLUGIN_STATIC(GOT, PLUGIN_TYPE_ENGINE, GotMetaEngine);
|
||||
#endif
|
||||
62
engines/got/metaengine.h
Normal file
62
engines/got/metaengine.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* 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 GOT_METAENGINE_H
|
||||
#define GOT_METAENGINE_H
|
||||
|
||||
#include "engines/advancedDetector.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
enum KeybindingAction {
|
||||
KEYBIND_NONE,
|
||||
KEYBIND_UP,
|
||||
KEYBIND_DOWN,
|
||||
KEYBIND_LEFT,
|
||||
KEYBIND_RIGHT,
|
||||
KEYBIND_SELECT,
|
||||
KEYBIND_FIRE,
|
||||
KEYBIND_MAGIC,
|
||||
KEYBIND_ESCAPE,
|
||||
KEYBIND_THOR_DIES
|
||||
};
|
||||
|
||||
} // namespace Got
|
||||
|
||||
class GotMetaEngine : public AdvancedMetaEngine<ADGameDescription> {
|
||||
public:
|
||||
const char *getName() const override;
|
||||
|
||||
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
|
||||
|
||||
/**
|
||||
* Determine whether the engine supports the specified MetaEngine feature.
|
||||
*
|
||||
* Used by e.g. the launcher to determine whether to enable the Load button.
|
||||
*/
|
||||
bool hasFeature(MetaEngineFeature f) const override;
|
||||
|
||||
const ADExtraGuiOptionsMap *getAdvancedExtraGuiOptions() const override;
|
||||
|
||||
Common::Array<Common::Keymap *> initKeymaps(const char *target) const override;
|
||||
};
|
||||
|
||||
#endif // GOT_METAENGINE_H
|
||||
80
engines/got/module.mk
Normal file
80
engines/got/module.mk
Normal file
@@ -0,0 +1,80 @@
|
||||
MODULE := engines/got
|
||||
|
||||
MODULE_OBJS = \
|
||||
got.o \
|
||||
console.o \
|
||||
events.o \
|
||||
messages.o \
|
||||
metaengine.o \
|
||||
musicdriver.o \
|
||||
musicdriver_adlib.o \
|
||||
musicparser.o \
|
||||
sound.o \
|
||||
vars.o \
|
||||
data/actor.o \
|
||||
data/highscores.o \
|
||||
data/level.o \
|
||||
data/sd_data.o \
|
||||
data/setup.o \
|
||||
data/thorinfo.o \
|
||||
game/boss1.o \
|
||||
game/boss2.o \
|
||||
game/boss3.o \
|
||||
game/back.o \
|
||||
game/init.o \
|
||||
game/main.o \
|
||||
game/move.o \
|
||||
game/move_patterns.o \
|
||||
game/object.o \
|
||||
game/script.o \
|
||||
game/shot_movement.o \
|
||||
game/shot_pattern.o \
|
||||
game/special_tile.o \
|
||||
game/status.o \
|
||||
gfx/font.o \
|
||||
gfx/gfx_chunks.o \
|
||||
gfx/gfx_pics.o \
|
||||
gfx/gfx_surface.o \
|
||||
gfx/image.o \
|
||||
gfx/palette.o \
|
||||
utils/compression.o \
|
||||
utils/file.o \
|
||||
utils/res_archive.o \
|
||||
views/view.o \
|
||||
views/credits.o \
|
||||
views/game.o \
|
||||
views/game_content.o \
|
||||
views/game_status.o \
|
||||
views/opening.o \
|
||||
views/part_title.o \
|
||||
views/splash_screen.o \
|
||||
views/story.o \
|
||||
views/title_background.o \
|
||||
views/dialogs/dialog.o \
|
||||
views/dialogs/select_option.o \
|
||||
views/dialogs/ask.o \
|
||||
views/dialogs/high_scores.o \
|
||||
views/dialogs/main_menu.o \
|
||||
views/dialogs/options_menu.o \
|
||||
views/dialogs/quit.o \
|
||||
views/dialogs/quit_game.o \
|
||||
views/dialogs/save_game.o \
|
||||
views/dialogs/say.o \
|
||||
views/dialogs/select_game.o \
|
||||
views/dialogs/select_item.o \
|
||||
views/dialogs/select_scroll.o \
|
||||
views/dialogs/select_slow.o \
|
||||
views/dialogs/set_music.o \
|
||||
views/dialogs/set_sound.o \
|
||||
views/dialogs/skill_level.o
|
||||
|
||||
# This module can be built as a plugin
|
||||
ifeq ($(ENABLE_GOT), DYNAMIC_PLUGIN)
|
||||
PLUGIN := 1
|
||||
endif
|
||||
|
||||
# Include common rules
|
||||
include $(srcdir)/rules.mk
|
||||
|
||||
# Detection objects
|
||||
DETECT_OBJS += $(MODULE)/detection.o
|
||||
88
engines/got/musicdriver.cpp
Normal file
88
engines/got/musicdriver.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/* 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 "got/musicdriver.h"
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/system.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
MusicDriver_Got::MusicDriver_Got(uint8 timerFrequency) : _isOpen(false), _timer_param(nullptr), _timer_proc(nullptr) {
|
||||
setTimerFrequency(timerFrequency);
|
||||
}
|
||||
|
||||
bool MusicDriver_Got::isOpen() const {
|
||||
return _isOpen;
|
||||
}
|
||||
|
||||
void MusicDriver_Got::setTimerFrequency(uint8 timerFrequency) {
|
||||
assert(timerFrequency > 0);
|
||||
|
||||
_timerFrequency = timerFrequency;
|
||||
}
|
||||
|
||||
void MusicDriver_Got::onTimer() {
|
||||
if (_timer_proc && _timer_param)
|
||||
_timer_proc(_timer_param);
|
||||
}
|
||||
|
||||
void MusicDriver_Got::setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) {
|
||||
_timer_param = timer_param;
|
||||
_timer_proc = timer_proc;
|
||||
}
|
||||
|
||||
int MusicDriver_Got_NULL::open() {
|
||||
// There is no output device, so register a timer to trigger the callbacks.
|
||||
g_system->getTimerManager()->installTimerProc(timerCallback, 1000000 / _timerFrequency, this, "MusicDriver_Got_NULL");
|
||||
|
||||
_isOpen = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MusicDriver_Got_NULL::close() {
|
||||
if (!_isOpen)
|
||||
return;
|
||||
|
||||
g_system->getTimerManager()->removeTimerProc(timerCallback);
|
||||
|
||||
_isOpen = false;
|
||||
}
|
||||
|
||||
void MusicDriver_Got_NULL::setTimerFrequency(uint8 timerFrequency) {
|
||||
if (timerFrequency == _timerFrequency)
|
||||
return;
|
||||
|
||||
MusicDriver_Got::setTimerFrequency(timerFrequency);
|
||||
|
||||
// Update the timer frequency.
|
||||
g_system->getTimerManager()->removeTimerProc(timerCallback);
|
||||
g_system->getTimerManager()->installTimerProc(timerCallback, 1000000 / _timerFrequency, this, "MusicDriver_Got_NULL");
|
||||
}
|
||||
|
||||
void MusicDriver_Got_NULL::timerCallback(void *data) {
|
||||
MusicDriver_Got_NULL *driver = (MusicDriver_Got_NULL *)data;
|
||||
driver->onTimer();
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
77
engines/got/musicdriver.h
Normal file
77
engines/got/musicdriver.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* 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 GOT_MUSICDRIVER_H
|
||||
#define GOT_MUSICDRIVER_H
|
||||
|
||||
#include "common/timer.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
class MusicDriver_Got {
|
||||
public:
|
||||
MusicDriver_Got(uint8 timerFrequency);
|
||||
virtual ~MusicDriver_Got() { };
|
||||
|
||||
virtual int open() = 0;
|
||||
bool isOpen() const;
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual void syncSoundSettings() = 0;
|
||||
|
||||
virtual void send(uint16 b) = 0;
|
||||
virtual void stopAllNotes() = 0;
|
||||
|
||||
virtual void setTimerFrequency(uint8 timerFrequency);
|
||||
void onTimer();
|
||||
void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc);
|
||||
|
||||
protected:
|
||||
// True if the driver has been successfully opened.
|
||||
bool _isOpen;
|
||||
// The number of timer callbacks per second.
|
||||
int _timerFrequency;
|
||||
|
||||
// External timer callback
|
||||
void *_timer_param;
|
||||
Common::TimerManager::TimerProc _timer_proc;
|
||||
};
|
||||
|
||||
class MusicDriver_Got_NULL : public MusicDriver_Got {
|
||||
public:
|
||||
MusicDriver_Got_NULL(uint8 timerFrequency) : MusicDriver_Got(timerFrequency) { };
|
||||
~MusicDriver_Got_NULL() { };
|
||||
|
||||
int open() override;
|
||||
void close() override;
|
||||
|
||||
void syncSoundSettings() override { };
|
||||
void send(uint16 b) override { };
|
||||
void stopAllNotes() override { };
|
||||
|
||||
void setTimerFrequency(uint8 timerFrequency) override;
|
||||
|
||||
static void timerCallback(void *data);
|
||||
};
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
289
engines/got/musicdriver_adlib.cpp
Normal file
289
engines/got/musicdriver_adlib.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
/* 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 "got/musicdriver_adlib.h"
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/debug.h"
|
||||
#include "audio/mididrv.h"
|
||||
|
||||
|
||||
namespace Got {
|
||||
|
||||
MusicDriver_Got_AdLib::MusicDriver_Got_AdLib(uint8 timerFrequency) : MusicDriver_Got(timerFrequency),
|
||||
_opl(nullptr),
|
||||
_userMusicVolume(256),
|
||||
_userMute(false) {
|
||||
Common::fill(_channelOp0LevelRegisterValues, _channelOp0LevelRegisterValues + ARRAYSIZE(_channelOp0LevelRegisterValues), 0);
|
||||
Common::fill(_channelOp1LevelRegisterValues, _channelOp1LevelRegisterValues + ARRAYSIZE(_channelOp1LevelRegisterValues), 0);
|
||||
Common::fill(_channelBxRegisterValues, _channelBxRegisterValues + ARRAYSIZE(_channelBxRegisterValues), 0);
|
||||
Common::fill(_channelConnectionValues, _channelConnectionValues + ARRAYSIZE(_channelConnectionValues), 0);
|
||||
}
|
||||
|
||||
MusicDriver_Got_AdLib::~MusicDriver_Got_AdLib() {
|
||||
close();
|
||||
}
|
||||
|
||||
int MusicDriver_Got_AdLib::open() {
|
||||
if (_isOpen)
|
||||
return MidiDriver::MERR_ALREADY_OPEN;
|
||||
|
||||
int8 detectResult = OPL::Config::detect(OPL::Config::kOpl2);
|
||||
if (detectResult == -1)
|
||||
return MidiDriver::MERR_DEVICE_NOT_AVAILABLE;
|
||||
|
||||
// Create the emulator / hardware interface.
|
||||
_opl = OPL::Config::create(OPL::Config::kOpl2);
|
||||
|
||||
if (_opl == nullptr)
|
||||
return MidiDriver::MERR_CANNOT_CONNECT;
|
||||
|
||||
// Initialize emulator / hardware interface.
|
||||
if (!_opl->init())
|
||||
return MidiDriver::MERR_CANNOT_CONNECT;
|
||||
|
||||
_isOpen = true;
|
||||
|
||||
// Set default OPL register values.
|
||||
initOpl();
|
||||
|
||||
// Start the emulator / hardware interface. This will also start the timer
|
||||
// callbacks.
|
||||
_opl->start(new Common::Functor0Mem<void, MusicDriver_Got_AdLib>(this, &MusicDriver_Got_AdLib::onTimer), _timerFrequency);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MusicDriver_Got_AdLib::close() {
|
||||
if (!_isOpen)
|
||||
return;
|
||||
|
||||
_isOpen = false;
|
||||
|
||||
stopAllNotes();
|
||||
|
||||
if (_opl) {
|
||||
_opl->stop();
|
||||
delete _opl;
|
||||
_opl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MusicDriver_Got_AdLib::syncSoundSettings() {
|
||||
// Get user volume settings.
|
||||
_userMusicVolume = MIN(256, ConfMan.getInt("music_volume"));
|
||||
_userMute = ConfMan.getBool("mute") || ConfMan.getBool("music_mute");
|
||||
|
||||
// Apply the user volume.
|
||||
recalculateVolumes();
|
||||
}
|
||||
|
||||
void MusicDriver_Got_AdLib::send(uint16 b) {
|
||||
uint8 oplRegister = b >> 8;
|
||||
uint8 value = b & 0xFF;
|
||||
|
||||
if (oplRegister >= OPL_REGISTER_BASE_LEVEL && oplRegister < OPL_REGISTER_BASE_LEVEL + 0x20) {
|
||||
// Write to a level register.
|
||||
|
||||
// Determine the channel and operator from the register number.
|
||||
uint8 regOffset = oplRegister - OPL_REGISTER_BASE_LEVEL;
|
||||
uint8 oplChannel = ((regOffset / 8) * 3) + ((regOffset % 8) % 3);
|
||||
uint8 oplOperator = (regOffset % 8) / 3;
|
||||
assert(oplChannel < OPL2_NUM_CHANNELS);
|
||||
assert(oplOperator < 2);
|
||||
|
||||
// Store the new register value.
|
||||
if (oplOperator == 0) {
|
||||
_channelOp0LevelRegisterValues[oplChannel] = value;
|
||||
} else {
|
||||
_channelOp1LevelRegisterValues[oplChannel] = value;
|
||||
}
|
||||
|
||||
// Apply user volume settings to the level.
|
||||
uint8 scaledLevel = calculateVolume(oplChannel, oplOperator);
|
||||
// Add the KSL bits to the new level value.
|
||||
value = (value & 0xC0) | scaledLevel;
|
||||
} else if ((oplRegister & 0xF0) == OPL_REGISTER_BASE_FNUMHIGH_BLOCK_KEYON) {
|
||||
// Write to an F-num high / block / key on register.
|
||||
|
||||
uint8 oplChannel = oplRegister & 0x0F;
|
||||
assert(oplChannel < OPL2_NUM_CHANNELS);
|
||||
|
||||
// Store the value, but clear the key on bit.
|
||||
_channelBxRegisterValues[oplChannel] = value & 0x1F;
|
||||
} else if ((oplRegister & 0xF0) == OPL_REGISTER_BASE_CONNECTION_FEEDBACK_PANNING) {
|
||||
// Write to a connection register.
|
||||
|
||||
uint8 oplChannel = oplRegister & 0x0F;
|
||||
assert(oplChannel < OPL2_NUM_CHANNELS);
|
||||
|
||||
// Store the connection bit.
|
||||
_channelConnectionValues[oplChannel] = value & 0x01;
|
||||
}
|
||||
|
||||
// Write the new register value to the OPL chip.
|
||||
writeRegister(oplRegister, value);
|
||||
}
|
||||
|
||||
void MusicDriver_Got_AdLib::stopAllNotes() {
|
||||
// Clear the key on bit on all OPL channels.
|
||||
for (int i = 0; i < OPL2_NUM_CHANNELS; i++) {
|
||||
writeRegister(0xB0 | i, _channelBxRegisterValues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void MusicDriver_Got_AdLib::initOpl() {
|
||||
// Clear test flags and enable waveform select.
|
||||
writeRegister(0x01, 0x20);
|
||||
|
||||
// Clear, stop and mask the timers and reset the interrupt.
|
||||
writeRegister(0x02, 0);
|
||||
writeRegister(0x03, 0);
|
||||
writeRegister(0x04, 0x60);
|
||||
writeRegister(0x04, 0x80);
|
||||
|
||||
// Set note select mode 0 and disable CSM mode.
|
||||
writeRegister(0x08, 0);
|
||||
|
||||
// Clear operator registers.
|
||||
for (int i = 0; i < 5; i++) {
|
||||
uint8 baseReg = 0;
|
||||
switch (i) {
|
||||
case 0:
|
||||
baseReg = OPL_REGISTER_BASE_FREQMULT_MISC;
|
||||
break;
|
||||
case 1:
|
||||
baseReg = OPL_REGISTER_BASE_LEVEL;
|
||||
break;
|
||||
case 2:
|
||||
baseReg = OPL_REGISTER_BASE_DECAY_ATTACK;
|
||||
break;
|
||||
case 3:
|
||||
baseReg = OPL_REGISTER_BASE_RELEASE_SUSTAIN;
|
||||
break;
|
||||
case 4:
|
||||
baseReg = OPL_REGISTER_BASE_WAVEFORMSELECT;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int j = 0; j < OPL2_NUM_CHANNELS; j++) {
|
||||
writeRegister(baseReg + determineOperatorRegisterOffset(j, 0), 0);
|
||||
writeRegister(baseReg + determineOperatorRegisterOffset(j, 1), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear channel registers.
|
||||
for (int i = 0; i < 3; i++) {
|
||||
uint8 baseReg = 0;
|
||||
switch (i) {
|
||||
case 0:
|
||||
baseReg = OPL_REGISTER_BASE_FNUMLOW;
|
||||
break;
|
||||
case 1:
|
||||
baseReg = OPL_REGISTER_BASE_FNUMHIGH_BLOCK_KEYON;
|
||||
break;
|
||||
case 2:
|
||||
baseReg = OPL_REGISTER_BASE_CONNECTION_FEEDBACK_PANNING;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int j = 0; j < OPL2_NUM_CHANNELS; j++) {
|
||||
writeRegister(baseReg + j, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Disable rhythm mode and set modulation and vibrato depth to low.
|
||||
writeRegister(0xBD, 0);
|
||||
}
|
||||
|
||||
void MusicDriver_Got_AdLib::recalculateVolumes() {
|
||||
// Determine the value for all level registers and write them out.
|
||||
for (int i = 0; i < OPL2_NUM_CHANNELS; i++) {
|
||||
uint8 oplRegister = OPL_REGISTER_BASE_LEVEL + determineOperatorRegisterOffset(i, 0);
|
||||
uint8 value = (_channelOp0LevelRegisterValues[i] & 0xC0) | calculateVolume(i, 0);
|
||||
writeRegister(oplRegister, value);
|
||||
|
||||
oplRegister = OPL_REGISTER_BASE_LEVEL + determineOperatorRegisterOffset(i, 1);
|
||||
value = (_channelOp1LevelRegisterValues[i] & 0xC0) | calculateVolume(i, 1);
|
||||
writeRegister(oplRegister, value);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 MusicDriver_Got_AdLib::calculateVolume(uint8 channel, uint8 operatorNum) {
|
||||
// Get the last written level for this operator.
|
||||
uint8 operatorDefVolume = (operatorNum == 0 ? _channelOp0LevelRegisterValues[channel] : _channelOp1LevelRegisterValues[channel]) & 0x3F;
|
||||
|
||||
// Determine if volume settings should be applied to this operator.
|
||||
if (!isVolumeApplicableToOperator(channel, operatorNum))
|
||||
// No need to apply volume settings; just use the level as written.
|
||||
return operatorDefVolume;
|
||||
|
||||
uint8 invertedVolume = 0x3F - operatorDefVolume;
|
||||
|
||||
// Scale by user volume.
|
||||
if (_userMute) {
|
||||
invertedVolume = 0;
|
||||
} else {
|
||||
invertedVolume = (invertedVolume * _userMusicVolume) >> 8;
|
||||
}
|
||||
uint8 scaledVolume = 0x3F - invertedVolume;
|
||||
|
||||
return scaledVolume;
|
||||
}
|
||||
|
||||
bool MusicDriver_Got_AdLib::isVolumeApplicableToOperator(uint8 channel, uint8 operatorNum) {
|
||||
// 2 operator instruments have 2 different operator connections:
|
||||
// additive (0x01) or FM (0x00) synthesis. Carrier operators in FM
|
||||
// synthesis and both operators in additive synthesis need to have
|
||||
// volume settings applied; modulator operators just use the level
|
||||
// as written. In FM synthesis connection, operator 1 is a carrier.
|
||||
return _channelConnectionValues[channel] == 0x01 || operatorNum == 1;
|
||||
}
|
||||
|
||||
uint16 MusicDriver_Got_AdLib::determineOperatorRegisterOffset(uint8 oplChannel, uint8 operatorNum) {
|
||||
// 2 operator register offset for each channel and operator:
|
||||
//
|
||||
// Channel | 0 | 1 | 2 | 0 | 1 | 2 | 3 | 4 | 5 | 3 | 4 | 5 | 6 | 7 | 8 | 6 | 7 | 8 |
|
||||
// Operator | 0 | 1 | 0 | 1 | 0 | 1 |
|
||||
// Register | 0 | 1 | 2 | 3 | 4 | 5 | 8 | 9 | A | B | C | D |10 |11 |12 |13 |14 |15 |
|
||||
return (oplChannel / 3 * 8) + (oplChannel % 3) + (operatorNum * 3);
|
||||
}
|
||||
|
||||
void MusicDriver_Got_AdLib::writeRegister(uint8 oplRegister, uint8 value) {
|
||||
//debug("Writing register %X %X", oplRegister, value);
|
||||
|
||||
_opl->writeReg(oplRegister, value);
|
||||
}
|
||||
|
||||
void MusicDriver_Got_AdLib::setTimerFrequency(uint8 timerFrequency) {
|
||||
if (timerFrequency == _timerFrequency)
|
||||
return;
|
||||
|
||||
MusicDriver_Got::setTimerFrequency(timerFrequency);
|
||||
|
||||
if (isOpen()) {
|
||||
// Update OPL timer frequency.
|
||||
_opl->stop();
|
||||
_opl->start(new Common::Functor0Mem<void, MusicDriver_Got_AdLib>(this, &MusicDriver_Got_AdLib::onTimer), _timerFrequency);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
120
engines/got/musicdriver_adlib.h
Normal file
120
engines/got/musicdriver_adlib.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/* 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 GOT_MUSICDRIVER_ADLIB_H
|
||||
#define GOT_MUSICDRIVER_ADLIB_H
|
||||
|
||||
#include "got/musicdriver.h"
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/timer.h"
|
||||
#include "audio/fmopl.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
class MusicDriver_Got_AdLib : public MusicDriver_Got {
|
||||
public:
|
||||
/**
|
||||
* The number of available channels on the OPL2 chip.
|
||||
*/
|
||||
static const uint8 OPL2_NUM_CHANNELS = 9;
|
||||
|
||||
/**
|
||||
* OPL operator base registers.
|
||||
*/
|
||||
static const uint8 OPL_REGISTER_BASE_FREQMULT_MISC = 0x20;
|
||||
static const uint8 OPL_REGISTER_BASE_LEVEL = 0x40;
|
||||
static const uint8 OPL_REGISTER_BASE_DECAY_ATTACK = 0x60;
|
||||
static const uint8 OPL_REGISTER_BASE_RELEASE_SUSTAIN = 0x80;
|
||||
static const uint8 OPL_REGISTER_BASE_WAVEFORMSELECT = 0xE0;
|
||||
|
||||
/**
|
||||
* OPL channel base registers.
|
||||
*/
|
||||
static const uint8 OPL_REGISTER_BASE_FNUMLOW = 0xA0;
|
||||
static const uint8 OPL_REGISTER_BASE_FNUMHIGH_BLOCK_KEYON = 0xB0;
|
||||
static const uint8 OPL_REGISTER_BASE_CONNECTION_FEEDBACK_PANNING = 0xC0;
|
||||
|
||||
MusicDriver_Got_AdLib(uint8 timerFrequency);
|
||||
~MusicDriver_Got_AdLib();
|
||||
|
||||
int open() override;
|
||||
void close() override;
|
||||
|
||||
void syncSoundSettings() override;
|
||||
|
||||
void send(uint16 b) override;
|
||||
void stopAllNotes() override;
|
||||
|
||||
void setTimerFrequency(uint8 timerFrequency) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Initializes the OPL registers to their default values.
|
||||
*/
|
||||
void initOpl();
|
||||
|
||||
void recalculateVolumes();
|
||||
uint8 calculateVolume(uint8 channel, uint8 operatorNum);
|
||||
/**
|
||||
* Determines if volume settings should be applied to the operator level.
|
||||
* This depends on the type of the operator (carrier or modulator), which
|
||||
* depends on the type of connection specified on the channel.
|
||||
*
|
||||
* @param oplChannel The OPL channel
|
||||
* @param operatorNum The number of the operator (0-1)
|
||||
* @return True if volume should be applied, false otherwise
|
||||
*/
|
||||
bool isVolumeApplicableToOperator(uint8 oplChannel, uint8 operatorNum);
|
||||
/**
|
||||
* Determines the offset from a base register for the specified operator of
|
||||
* the specified OPL channel.
|
||||
* Add the offset to the base register to get the correct register for this
|
||||
* operator and channel.
|
||||
*
|
||||
* @param oplChannel The OPL channel for which to determine the offset.
|
||||
* @param operatorNum The operator for which to determine the offset (0-1).
|
||||
* @return The offset to the base register for this operator.
|
||||
*/
|
||||
uint16 determineOperatorRegisterOffset(uint8 oplChannel, uint8 operatorNum);
|
||||
void writeRegister(uint8 oplRegister, uint8 value);
|
||||
|
||||
// The OPL emulator / hardware interface.
|
||||
OPL::OPL *_opl;
|
||||
|
||||
// Last written value to the operator 0 level register for each channel.
|
||||
uint8 _channelOp0LevelRegisterValues[OPL2_NUM_CHANNELS];
|
||||
// Last written value to the operator 1 level register for each channel.
|
||||
uint8 _channelOp1LevelRegisterValues[OPL2_NUM_CHANNELS];
|
||||
// Last written value to the F-num high / block / key on register for each
|
||||
// channel, with the key on bit cleared.
|
||||
uint8 _channelBxRegisterValues[OPL2_NUM_CHANNELS];
|
||||
// Last written value of the connection bit for each channel.
|
||||
uint8 _channelConnectionValues[OPL2_NUM_CHANNELS];
|
||||
|
||||
// User volume settings.
|
||||
uint16 _userMusicVolume;
|
||||
bool _userMute;
|
||||
};
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
195
engines/got/musicparser.cpp
Normal file
195
engines/got/musicparser.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
/* 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 "got/musicparser.h"
|
||||
|
||||
#include "common/endian.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
MusicParser_Got::MusicParser_Got() :
|
||||
_pause(false),
|
||||
_abortParse(false),
|
||||
_currentDelta(0),
|
||||
_driver(nullptr),
|
||||
_track(nullptr),
|
||||
_trackLength(0),
|
||||
_playPos(nullptr),
|
||||
_loopStart(-1) { }
|
||||
|
||||
MusicParser_Got::~MusicParser_Got() {
|
||||
stopPlaying();
|
||||
}
|
||||
|
||||
void MusicParser_Got::sendToDriver(uint16 b) {
|
||||
if (_driver == nullptr)
|
||||
return;
|
||||
|
||||
_driver->send(b);
|
||||
}
|
||||
|
||||
void MusicParser_Got::sendToDriver(byte reg, byte value) {
|
||||
// OPL register and value are sent as a uint16 to the driver.
|
||||
sendToDriver((reg << 8) | value);
|
||||
}
|
||||
|
||||
void MusicParser_Got::allNotesOff() {
|
||||
if (_driver == nullptr)
|
||||
return;
|
||||
|
||||
_driver->stopAllNotes();
|
||||
}
|
||||
|
||||
void MusicParser_Got::resetTracking() {
|
||||
_playPos = nullptr;
|
||||
}
|
||||
|
||||
bool MusicParser_Got::startPlaying() {
|
||||
if (_track == nullptr || _pause)
|
||||
return false;
|
||||
|
||||
if (_playPos == nullptr) {
|
||||
_playPos = _track;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MusicParser_Got::pausePlaying() {
|
||||
if (isPlaying() && !_pause) {
|
||||
_pause = true;
|
||||
allNotesOff();
|
||||
}
|
||||
}
|
||||
|
||||
void MusicParser_Got::resumePlaying() {
|
||||
_pause = false;
|
||||
}
|
||||
|
||||
void MusicParser_Got::stopPlaying() {
|
||||
if (isPlaying())
|
||||
allNotesOff();
|
||||
resetTracking();
|
||||
_pause = false;
|
||||
}
|
||||
|
||||
bool MusicParser_Got::isPlaying() {
|
||||
return _playPos != nullptr;
|
||||
}
|
||||
|
||||
void MusicParser_Got::setMusicDriver(MusicDriver_Got *driver) {
|
||||
_driver = driver;
|
||||
}
|
||||
|
||||
bool MusicParser_Got::loadMusic(byte* data, uint32 size) {
|
||||
assert(size >= 5);
|
||||
|
||||
// Data starts with a word defining the loop point.
|
||||
uint16 loopHeader = READ_LE_UINT16(data);
|
||||
data += 2;
|
||||
|
||||
// Rest of the data is music events.
|
||||
_track = data;
|
||||
_trackLength = size - 2;
|
||||
|
||||
if (loopHeader == 0) {
|
||||
// No loop point defined.
|
||||
_loopStart = -1;
|
||||
} else {
|
||||
// Loop point is defined as the number of words from the start of the
|
||||
// data (including the header).
|
||||
_loopStart = (loopHeader - 1) * 2;
|
||||
if ((uint32)_loopStart >= _trackLength) {
|
||||
warning("MusicParser_Got::loadMusic - Music data has loop start point after track end");
|
||||
_loopStart = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MusicParser_Got::unloadMusic() {
|
||||
if (_track == nullptr)
|
||||
// No music data loaded
|
||||
return;
|
||||
|
||||
stopPlaying();
|
||||
_abortParse = true;
|
||||
_track = nullptr;
|
||||
}
|
||||
|
||||
void MusicParser_Got::onTimer() {
|
||||
if (_playPos == nullptr || !_driver || _pause)
|
||||
return;
|
||||
|
||||
if (_currentDelta > 0) {
|
||||
_currentDelta--;
|
||||
if (_currentDelta > 0)
|
||||
// More ticks to go to the next event.
|
||||
return;
|
||||
}
|
||||
|
||||
_abortParse = false;
|
||||
while (!_abortParse && isPlaying() && _currentDelta == 0) {
|
||||
assert((_playPos + 3) < (_track + _trackLength));
|
||||
|
||||
// An event consists of a delta, followed by an OPL register / value pair.
|
||||
|
||||
// A delta consists of 1 or 2 bytes. Bit 7 in the first byte indicates
|
||||
// if a second byte is used.
|
||||
uint16 newDelta = *_playPos++;
|
||||
if ((newDelta & 0x80) > 0) {
|
||||
assert((_playPos + 3) < (_track + _trackLength));
|
||||
newDelta &= 0x7F;
|
||||
newDelta <<= 8;
|
||||
newDelta |= *_playPos++;
|
||||
}
|
||||
// The delta is the number of ticks from this event to the next event,
|
||||
// not the number of ticks preceding this event.
|
||||
_currentDelta = newDelta;
|
||||
|
||||
// Next, read the OPL register / value pair.
|
||||
byte oplRegister = *_playPos++;
|
||||
byte oplRegValue = *_playPos++;
|
||||
|
||||
if (oplRegister == 0 && oplRegValue == 0) {
|
||||
// End of track is indicated by an event with OPL register and value 0.
|
||||
if (_loopStart >= 0) {
|
||||
// Continue playback at the loop point.
|
||||
_playPos = _track + _loopStart;
|
||||
}
|
||||
else {
|
||||
stopPlaying();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Write the specified OPL register value.
|
||||
sendToDriver(oplRegister, oplRegValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MusicParser_Got::timerCallback(void *data) {
|
||||
((MusicParser_Got *)data)->onTimer();
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
77
engines/got/musicparser.h
Normal file
77
engines/got/musicparser.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* 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 GOT_MUSICPARSER_H
|
||||
#define GOT_MUSICPARSER_H
|
||||
|
||||
#include "got/musicdriver_adlib.h"
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
class MusicParser_Got {
|
||||
public:
|
||||
MusicParser_Got();
|
||||
~MusicParser_Got();
|
||||
|
||||
bool startPlaying();
|
||||
void pausePlaying();
|
||||
void resumePlaying();
|
||||
void stopPlaying();
|
||||
bool isPlaying();
|
||||
|
||||
void setMusicDriver(MusicDriver_Got *driver);
|
||||
|
||||
bool loadMusic(byte *data, uint32 size);
|
||||
void unloadMusic();
|
||||
|
||||
void onTimer();
|
||||
static void timerCallback(void *data);
|
||||
|
||||
protected:
|
||||
void allNotesOff();
|
||||
void sendToDriver(uint16 b);
|
||||
void sendToDriver(byte reg, byte value);
|
||||
void resetTracking();
|
||||
|
||||
bool _pause;
|
||||
bool _abortParse;
|
||||
// Number of ticks to the next event to process.
|
||||
uint16 _currentDelta;
|
||||
|
||||
MusicDriver_Got *_driver;
|
||||
|
||||
// Points to start of current track data, or nullptr if no track is loaded.
|
||||
byte *_track;
|
||||
// The length of the track data.
|
||||
uint32 _trackLength;
|
||||
// The current play position in the track data, or nullptr if the parser is
|
||||
// not playing.
|
||||
byte *_playPos;
|
||||
// The offset from the start of _track where playback should restart if the
|
||||
// track has reached the end. -1 if there is no (valid) loop point defined.
|
||||
int32 _loopStart;
|
||||
};
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
379
engines/got/sound.cpp
Normal file
379
engines/got/sound.cpp
Normal file
@@ -0,0 +1,379 @@
|
||||
/* 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 "got/sound.h"
|
||||
|
||||
#include "got/got.h"
|
||||
#include "got/musicdriver_adlib.h"
|
||||
#include "got/utils/file.h"
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/memstream.h"
|
||||
#include "audio/mididrv.h"
|
||||
#include "audio/decoders/raw.h"
|
||||
#include "audio/decoders/voc.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
static const byte SOUND_PRIORITY[] = {1, 2, 3, 3, 3, 1, 4, 4, 4, 5, 4, 3, 1, 2, 2, 5, 1, 3, 1};
|
||||
|
||||
static const char *MUSIC_MENU_DATA_FILENAME = "GOT.AUD";
|
||||
|
||||
Sound::Sound() {
|
||||
for (int i = 0; i < 3; i++)
|
||||
_bossSounds[i] = nullptr;
|
||||
}
|
||||
|
||||
Sound::~Sound() {
|
||||
delete[] _soundData;
|
||||
for (int i = 0; i < ARRAYSIZE(_bossSounds); i++) {
|
||||
delete[] _bossSounds[i];
|
||||
}
|
||||
|
||||
if (_musicParser != nullptr) {
|
||||
musicStop();
|
||||
}
|
||||
|
||||
if (_musicDriver != nullptr) {
|
||||
_musicDriver->setTimerCallback(nullptr, nullptr);
|
||||
_musicDriver->close();
|
||||
}
|
||||
|
||||
delete _musicParser;
|
||||
delete _musicDriver;
|
||||
delete[] _musicData;
|
||||
}
|
||||
|
||||
void Sound::load() {
|
||||
File f("DIGSOUND");
|
||||
|
||||
// Load index
|
||||
for (int i = 0; i < 16; ++i)
|
||||
_digiSounds[i].load(&f);
|
||||
|
||||
// Allocate memory and load sound data
|
||||
_soundData = new byte[f.size() - 16 * 8];
|
||||
f.read(_soundData, f.size() - 16 * 8);
|
||||
|
||||
// Initialize music.
|
||||
|
||||
// Check the type of music device that the user has configured.
|
||||
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_ADLIB);
|
||||
MusicType deviceType = MidiDriver::getMusicType(dev);
|
||||
|
||||
// Initialize the appropriate driver.
|
||||
switch (deviceType) {
|
||||
case MT_ADLIB:
|
||||
_musicDriver = new MusicDriver_Got_AdLib(MUSIC_TIMER_FREQUENCY_GAME);
|
||||
break;
|
||||
default:
|
||||
// No support for music other than AdLib.
|
||||
_musicDriver = new MusicDriver_Got_NULL(MUSIC_TIMER_FREQUENCY_GAME);
|
||||
break;
|
||||
}
|
||||
|
||||
// Initialize the parser.
|
||||
_musicParser = new MusicParser_Got();
|
||||
|
||||
// Open the driver.
|
||||
int returnCode = _musicDriver->open();
|
||||
if (returnCode != 0) {
|
||||
warning("Sound::load - Failed to open music driver - error code %d.", returnCode);
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply user volume settings.
|
||||
syncSoundSettings();
|
||||
|
||||
// Connect the driver and the parser.
|
||||
_musicParser->setMusicDriver(_musicDriver);
|
||||
_musicDriver->setTimerCallback(_musicParser, &_musicParser->timerCallback);
|
||||
}
|
||||
|
||||
void Sound::setupBoss(const int num) {
|
||||
if (_currentBossLoaded == num)
|
||||
// Boss sounds are already loaded
|
||||
return;
|
||||
|
||||
if (_currentBossLoaded) {
|
||||
// Boss sounds have already been loaded. Delete them to avoid memory leak
|
||||
for (int i = 0; i < 3; i++)
|
||||
delete(_bossSounds[i]);
|
||||
}
|
||||
|
||||
// Information concerning boss sounds is stored in _digiSounds 16 to 18, but the data is stored in _bossSounds
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
Common::String resourceName = Common::String::format("BOSSV%d%d", num, i + 1);
|
||||
File f(resourceName);
|
||||
const int size = f.size();
|
||||
_bossSounds[i] = new byte[size];
|
||||
_digiSounds[16 + i]._length = size;
|
||||
_digiSounds[16 + i]._offset = 0;
|
||||
f.read(_bossSounds[i], size);
|
||||
f.close();
|
||||
}
|
||||
|
||||
_currentBossLoaded = num;
|
||||
}
|
||||
|
||||
void Sound::playSound(const int index, const bool override) {
|
||||
if (index >= NUM_SOUNDS)
|
||||
return;
|
||||
|
||||
byte newPriority = SOUND_PRIORITY[index];
|
||||
|
||||
// If a sound is playing, stop it unless there is a priority override
|
||||
if (soundPlaying()) {
|
||||
if (!override && _currentPriority < newPriority)
|
||||
return;
|
||||
|
||||
g_engine->_mixer->stopHandle(_soundHandle);
|
||||
}
|
||||
|
||||
_currentPriority = newPriority;
|
||||
|
||||
Common::MemoryReadStream *stream;
|
||||
if (index >= 16) {
|
||||
// Boss sounds are not stored in the normal sound data, it's in 3 buffers in _bossSounds.
|
||||
stream = new Common::MemoryReadStream(_bossSounds[index - 16], _digiSounds[index]._length);
|
||||
} else {
|
||||
// Normal digital sound
|
||||
stream = new Common::MemoryReadStream(_soundData + _digiSounds[index]._offset, _digiSounds[index]._length);
|
||||
}
|
||||
// Play the new sound
|
||||
Audio::AudioStream *audioStream = Audio::makeVOCStream(stream, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);
|
||||
g_engine->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, audioStream);
|
||||
}
|
||||
|
||||
void Sound::playSound(const Gfx::GraphicChunk &src) {
|
||||
if (soundPlaying())
|
||||
g_engine->_mixer->stopHandle(_soundHandle);
|
||||
|
||||
// Play the new sound
|
||||
Common::MemoryReadStream *stream = new Common::MemoryReadStream(
|
||||
src._data, src._uncompressedSize);
|
||||
Audio::AudioStream *audioStream = Audio::makeVOCStream(stream, Audio::FLAG_UNSIGNED,
|
||||
DisposeAfterUse::YES);
|
||||
g_engine->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, audioStream);
|
||||
}
|
||||
|
||||
bool Sound::soundPlaying() const {
|
||||
return g_engine->_mixer->isSoundHandleActive(_soundHandle);
|
||||
}
|
||||
|
||||
void Sound::musicPlay(const char *name, bool override) {
|
||||
if (_currentMusic == nullptr || strcmp(name, _currentMusic) || override) {
|
||||
_musicParser->stopPlaying();
|
||||
_musicParser->unloadMusic();
|
||||
delete[] _musicData;
|
||||
|
||||
_currentMusic = name;
|
||||
|
||||
File file;
|
||||
if (!strcmp(name, "MENU")) {
|
||||
// Title menu music is embedded in the executable.
|
||||
// It has been extracted and included with ScummVM.
|
||||
if (!file.exists(MUSIC_MENU_DATA_FILENAME)) {
|
||||
warning("Could not find %s", MUSIC_MENU_DATA_FILENAME);
|
||||
return;
|
||||
}
|
||||
file.open(MUSIC_MENU_DATA_FILENAME);
|
||||
|
||||
// Title music uses an alternate timer frequency.
|
||||
_musicDriver->setTimerFrequency(MUSIC_TIMER_FREQUENCY_TITLE);
|
||||
} else {
|
||||
file.open(name);
|
||||
|
||||
_musicDriver->setTimerFrequency(MUSIC_TIMER_FREQUENCY_GAME);
|
||||
}
|
||||
|
||||
// Copy music data to local buffer and load it into the parser.
|
||||
_musicData = new byte[file.size()];
|
||||
file.read(_musicData, file.size());
|
||||
|
||||
if (!_musicParser->loadMusic(_musicData, file.size())) {
|
||||
warning("Could not load music track %s", name);
|
||||
return;
|
||||
}
|
||||
|
||||
//debug("Playing music track %s", name);
|
||||
_musicParser->startPlaying();
|
||||
}
|
||||
}
|
||||
|
||||
void Sound::musicPause() {
|
||||
_musicParser->pausePlaying();
|
||||
}
|
||||
|
||||
void Sound::musicResume() {
|
||||
_musicParser->resumePlaying();
|
||||
}
|
||||
|
||||
void Sound::musicStop() {
|
||||
_musicParser->stopPlaying();
|
||||
_currentMusic = nullptr;
|
||||
}
|
||||
|
||||
bool Sound::musicIsOn() const {
|
||||
return _musicParser->isPlaying();
|
||||
}
|
||||
|
||||
const char *Sound::getMusicName(const int num) const {
|
||||
const char *name = nullptr;
|
||||
|
||||
switch (_G(area)) {
|
||||
case 1:
|
||||
switch (num) {
|
||||
case 0:
|
||||
name = "SONG1";
|
||||
break;
|
||||
case 1:
|
||||
name = "SONG2";
|
||||
break;
|
||||
case 2:
|
||||
name = "SONG3";
|
||||
break;
|
||||
case 3:
|
||||
name = "SONG4";
|
||||
break;
|
||||
case 4:
|
||||
name = "WINSONG";
|
||||
break;
|
||||
case 5:
|
||||
name = "BOSSSONG";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
switch (num) {
|
||||
case 0:
|
||||
name = "SONG21";
|
||||
break;
|
||||
case 1:
|
||||
name = "SONG22";
|
||||
break;
|
||||
case 2:
|
||||
name = "SONG23";
|
||||
break;
|
||||
case 3:
|
||||
name = "SONG24";
|
||||
break;
|
||||
case 4:
|
||||
name = "SONG35";
|
||||
break;
|
||||
case 5:
|
||||
name = "SONG25";
|
||||
break;
|
||||
case 6:
|
||||
name = "WINSONG";
|
||||
break;
|
||||
case 7:
|
||||
name = "BOSSSONG";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
switch (num) {
|
||||
case 0:
|
||||
name = "SONG31";
|
||||
break;
|
||||
case 1:
|
||||
name = "SONG32";
|
||||
break;
|
||||
case 2:
|
||||
name = "SONG33";
|
||||
break;
|
||||
case 3:
|
||||
name = "SONG34";
|
||||
break;
|
||||
case 4:
|
||||
name = "SONG35";
|
||||
break;
|
||||
case 5:
|
||||
name = "SONG36";
|
||||
break;
|
||||
case 6:
|
||||
name = "WINSONG";
|
||||
break;
|
||||
case 7:
|
||||
name = "BOSSSONG";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!name)
|
||||
error("Invalid music");
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
void Sound::syncSoundSettings() {
|
||||
g_engine->_mixer->muteSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getBool("sfx_mute") || ConfMan.getBool("mute"));
|
||||
|
||||
if (_musicDriver)
|
||||
_musicDriver->syncSoundSettings();
|
||||
}
|
||||
|
||||
void playSound(const int index, const bool override) {
|
||||
_G(sound).playSound(index, override);
|
||||
}
|
||||
|
||||
void playSound(const Gfx::GraphicChunk &src) {
|
||||
_G(sound).playSound(src);
|
||||
}
|
||||
|
||||
bool soundPlaying() {
|
||||
return _G(sound).soundPlaying();
|
||||
}
|
||||
|
||||
void musicPlay(const int num, const bool override) {
|
||||
_G(sound).musicPlay(num, override);
|
||||
}
|
||||
|
||||
void musicPlay(const char *name, const bool override) {
|
||||
_G(sound).musicPlay(name, override);
|
||||
}
|
||||
|
||||
void musicPause() {
|
||||
_G(sound).musicPause();
|
||||
}
|
||||
|
||||
void musicResume() {
|
||||
_G(sound).musicResume();
|
||||
}
|
||||
|
||||
void setupBoss(int num) {
|
||||
_G(sound).setupBoss(num);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
111
engines/got/sound.h
Normal file
111
engines/got/sound.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* 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 GOT_SOUND_H
|
||||
#define GOT_SOUND_H
|
||||
|
||||
#include "got/musicdriver.h"
|
||||
#include "got/musicparser.h"
|
||||
#include "got/data/defines.h"
|
||||
#include "got/gfx/gfx_chunks.h"
|
||||
|
||||
#include "audio/mixer.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
enum {
|
||||
OW,
|
||||
GULP,
|
||||
SWISH,
|
||||
YAH,
|
||||
ELECTRIC,
|
||||
THUNDER,
|
||||
DOOR,
|
||||
FALL,
|
||||
ANGEL,
|
||||
WOOP,
|
||||
DEAD,
|
||||
BRAAPP,
|
||||
WIND,
|
||||
PUNCH1,
|
||||
CLANG,
|
||||
EXPLODE,
|
||||
BOSS11,
|
||||
BOSS12,
|
||||
BOSS13
|
||||
};
|
||||
|
||||
#define NUM_SOUNDS 19
|
||||
|
||||
class Sound {
|
||||
private:
|
||||
static const uint8 MUSIC_TIMER_FREQUENCY_GAME = 120;
|
||||
static const uint8 MUSIC_TIMER_FREQUENCY_TITLE = 140;
|
||||
|
||||
byte *_soundData = nullptr;
|
||||
byte *_bossSounds[3];
|
||||
Header _digiSounds[NUM_SOUNDS];
|
||||
Audio::SoundHandle _soundHandle;
|
||||
byte _currentPriority = 0;
|
||||
int8 _currentBossLoaded = 0;
|
||||
|
||||
const char *_currentMusic = nullptr;
|
||||
byte *_musicData = nullptr;
|
||||
MusicDriver_Got *_musicDriver = nullptr;
|
||||
MusicParser_Got *_musicParser = nullptr;
|
||||
|
||||
const char *getMusicName(int num) const;
|
||||
|
||||
public:
|
||||
Sound();
|
||||
~Sound();
|
||||
|
||||
void load();
|
||||
void setupBoss(int num);
|
||||
|
||||
void playSound(int index, bool override);
|
||||
void playSound(const Gfx::GraphicChunk &src);
|
||||
bool soundPlaying() const;
|
||||
|
||||
void musicPlay(const int num, const bool override) {
|
||||
musicPlay(getMusicName(num), override);
|
||||
}
|
||||
void musicPlay(const char *name, bool override);
|
||||
void musicPause();
|
||||
void musicResume();
|
||||
void musicStop();
|
||||
bool musicIsOn() const;
|
||||
|
||||
void syncSoundSettings();
|
||||
};
|
||||
|
||||
extern void playSound(int index, bool override);
|
||||
extern void playSound(const Gfx::GraphicChunk &src);
|
||||
extern bool soundPlaying();
|
||||
extern void musicPlay(int num, bool override);
|
||||
extern void musicPlay(const char *name, bool override);
|
||||
extern void musicPause();
|
||||
extern void musicResume();
|
||||
extern void setupBoss(int num);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
78
engines/got/utils/compression.cpp
Normal file
78
engines/got/utils/compression.cpp
Normal file
@@ -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 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 "got/utils/compression.h"
|
||||
#include "common/algorithm.h"
|
||||
#include "common/endian.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
void decompressLzss(const byte *src, byte *dest, const size_t destSize) {
|
||||
byte *endP = dest + destSize;
|
||||
|
||||
for (;;) {
|
||||
byte v = *src++;
|
||||
|
||||
for (int bits = 8; bits > 0; --bits) {
|
||||
if (endP == dest)
|
||||
return;
|
||||
|
||||
const bool bit = (v & 1) != 0;
|
||||
v >>= 1;
|
||||
if (bit) {
|
||||
*dest++ = *src++;
|
||||
} else {
|
||||
uint16 offset = READ_LE_UINT16(src);
|
||||
src += 2;
|
||||
const int count = (offset >> 12) + 2;
|
||||
offset &= 0xfff;
|
||||
|
||||
Common::copy(dest - offset, dest - offset + count, dest);
|
||||
dest += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decompressRle(const byte *src, byte *dest, const size_t destSize) {
|
||||
byte *endP = dest + destSize;
|
||||
|
||||
for (;;) {
|
||||
byte val = *src++;
|
||||
|
||||
if ((val & 0x80) != 0) {
|
||||
const byte rep = *src++;
|
||||
val &= 0x7f;
|
||||
Common::fill(dest, dest + val, rep);
|
||||
dest += val;
|
||||
} else if (val > 0) {
|
||||
Common::copy(src, src + val, dest);
|
||||
src += val;
|
||||
dest += val;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(dest == endP);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
41
engines/got/utils/compression.h
Normal file
41
engines/got/utils/compression.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* 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 GOT_UTILS_COMPRESSION_H
|
||||
#define GOT_UTILS_COMPRESSION_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
/**
|
||||
* LZSS decompressor
|
||||
*/
|
||||
void decompressLzss(const byte *src, byte *dest, size_t destSize);
|
||||
|
||||
/**
|
||||
* RLE decoding
|
||||
*/
|
||||
void decompressRle(const byte *src, byte *dest, size_t destSize);
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
132
engines/got/utils/file.cpp
Normal file
132
engines/got/utils/file.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
/* 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/file.h"
|
||||
#include "got/utils/file.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
bool File::open(const Common::Path &filename) {
|
||||
if (!Common::File::open(filename))
|
||||
error("Could not open - %s", filename.baseName().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool loadActor(int /*file*/, int num) {
|
||||
Common::String fname = Common::String::format("ACTOR%d", num);
|
||||
|
||||
if (resourceRead(fname, _G(tmpBuff), true) < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool loadSpeech(int index) {
|
||||
char tmps[5];
|
||||
|
||||
Common::String fname = Common::String::format("SPEAK%d", _G(area));
|
||||
char *sp = new char[30000];
|
||||
|
||||
if (resourceRead(fname, sp) < 0) {
|
||||
delete[] sp;
|
||||
return false;
|
||||
}
|
||||
|
||||
char *p = sp;
|
||||
|
||||
int cnt = 0;
|
||||
for (;;) {
|
||||
if (*p == ':') {
|
||||
p++;
|
||||
cnt++;
|
||||
strncpy(tmps, p, 4);
|
||||
tmps[4] = '\0';
|
||||
|
||||
if (atoi(tmps) == index) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p++;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
while (*p != 10)
|
||||
p++;
|
||||
p++;
|
||||
|
||||
char *pm = p;
|
||||
cnt = 0;
|
||||
|
||||
for (;;) {
|
||||
if (*p == 13)
|
||||
*p = 32;
|
||||
if (*p == ':') {
|
||||
if ((*(p + 1) == 'E') && (*(p + 2) == 'N') && (*(p + 3) == 'D'))
|
||||
break;
|
||||
}
|
||||
|
||||
p++;
|
||||
cnt++;
|
||||
|
||||
if (cnt > 5799) {
|
||||
delete[] sp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (*(p - 1) == 10)
|
||||
*(p - 1) = 0;
|
||||
*p = 0;
|
||||
|
||||
Common::copy(pm, pm + cnt, _G(tmpBuff));
|
||||
_G(tmpBuff)
|
||||
[cnt] = 0;
|
||||
|
||||
delete[] sp;
|
||||
return true;
|
||||
}
|
||||
|
||||
long resourceRead(const Common::String &name, void *buff, bool failAllowed) {
|
||||
Common::File f;
|
||||
if (f.open(Common::Path(name))) {
|
||||
return f.read(buff, f.size());
|
||||
}
|
||||
|
||||
if (!failAllowed)
|
||||
error("Could not load - %s", name.c_str());
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *resourceAllocRead(const Common::String &name) {
|
||||
Common::File f;
|
||||
if (f.open(Common::Path(name))) {
|
||||
byte *result = (byte *)malloc(f.size());
|
||||
f.read(result, f.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // End of namespace Got
|
||||
47
engines/got/utils/file.h
Normal file
47
engines/got/utils/file.h
Normal file
@@ -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 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 GOT_UTILS_FILE_H
|
||||
#define GOT_UTILS_FILE_H
|
||||
|
||||
#include "common/file.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
extern bool loadActor(int, int num);
|
||||
extern void setupFilenames(int level);
|
||||
extern bool loadSpeech(int index);
|
||||
extern long resourceRead(const Common::String &name, void *buff, bool failAllowed = false);
|
||||
extern void *resourceAllocRead(const Common::String &name);
|
||||
|
||||
class File : public Common::File {
|
||||
public:
|
||||
File() : Common::File() {}
|
||||
File(const Common::String &filename) : Common::File() {
|
||||
File::open(Common::Path(filename));
|
||||
}
|
||||
|
||||
bool open(const Common::Path &filename) override;
|
||||
};
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
147
engines/got/utils/res_archive.cpp
Normal file
147
engines/got/utils/res_archive.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
/* 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/file.h"
|
||||
#include "common/memstream.h"
|
||||
#include "got/utils/compression.h"
|
||||
#include "got/utils/res_archive.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
static const char *RES_FILENAME = "gotres.dat";
|
||||
|
||||
void resInit() {
|
||||
ResArchive *a = new ResArchive();
|
||||
SearchMan.add("Res", a);
|
||||
}
|
||||
|
||||
void ResHeader::load(Common::SeekableReadStream *src) {
|
||||
char buf[10];
|
||||
src->read(buf, 9);
|
||||
buf[9] = '\0';
|
||||
_name = buf;
|
||||
|
||||
_offset = src->readUint32LE();
|
||||
_size = src->readUint32LE();
|
||||
_originalSize = src->readUint32LE();
|
||||
_key = src->readUint16LE();
|
||||
}
|
||||
|
||||
ResArchive::ResArchive() {
|
||||
Common::File f;
|
||||
if (!f.open(RES_FILENAME))
|
||||
error("Could not open %s", RES_FILENAME);
|
||||
|
||||
// Read in header data and decrypt it
|
||||
byte buf[RES_MAX_ENTRIES * RES_HEADER_ENTRY_SIZE];
|
||||
if (f.read(buf, RES_MAX_ENTRIES * RES_HEADER_ENTRY_SIZE) !=
|
||||
(RES_MAX_ENTRIES * RES_HEADER_ENTRY_SIZE))
|
||||
error("Could not read in resource headers");
|
||||
|
||||
decrypt(buf, RES_MAX_ENTRIES * RES_HEADER_ENTRY_SIZE, 128);
|
||||
|
||||
// Load headers
|
||||
Common::MemoryReadStream hdrData(buf, RES_MAX_ENTRIES * RES_HEADER_ENTRY_SIZE);
|
||||
for (int i = 0; i < RES_MAX_ENTRIES; ++i) {
|
||||
ResHeader hdr;
|
||||
hdr.load(&hdrData);
|
||||
if (!(hdr._offset == 0 && hdr._size == 0))
|
||||
_headers.push_back(hdr);
|
||||
}
|
||||
}
|
||||
|
||||
void ResArchive::decrypt(byte *buf, size_t len, byte key) const {
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
*buf++ ^= key++;
|
||||
}
|
||||
|
||||
int ResArchive::indexOf(const Common::String &name) const {
|
||||
for (uint i = 0; i < _headers.size(); ++i) {
|
||||
if (_headers[i]._name.equalsIgnoreCase(name))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool ResArchive::hasFile(const Common::Path &path) const {
|
||||
return indexOf(path.baseName()) != -1;
|
||||
}
|
||||
|
||||
int ResArchive::listMembers(Common::ArchiveMemberList &list) const {
|
||||
int count = 0;
|
||||
|
||||
for (uint i = 0; i < _headers.size(); ++i) {
|
||||
list.push_back(Common::ArchiveMemberList::value_type(
|
||||
new Common::GenericArchiveMember(_headers[i]._name, *this)));
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
const Common::ArchiveMemberPtr ResArchive::getMember(const Common::Path &path) const {
|
||||
if (!hasFile(path))
|
||||
return Common::ArchiveMemberPtr();
|
||||
|
||||
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(path, *this));
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *ResArchive::createReadStreamForMember(const Common::Path &path) const {
|
||||
// Get the index of the header entry for this file
|
||||
const int hdrIndex = indexOf(path.baseName());
|
||||
if (hdrIndex == -1)
|
||||
return nullptr;
|
||||
|
||||
Common::File f;
|
||||
if (!f.open(RES_FILENAME))
|
||||
error("Error reading resource");
|
||||
|
||||
// Set up buffers
|
||||
const ResHeader &hdr = _headers[hdrIndex];
|
||||
byte *buf = (byte *)malloc(hdr._size);
|
||||
|
||||
f.seek(hdr._offset);
|
||||
if (f.read(buf, hdr._size) != hdr._size)
|
||||
error("Error reading resource");
|
||||
|
||||
// Decrypt if necessary
|
||||
if (hdr._key != 0) {
|
||||
byte *temp = buf;
|
||||
buf = (byte *)malloc(hdr._originalSize);
|
||||
|
||||
lzssDecompress(temp, buf);
|
||||
free(temp);
|
||||
}
|
||||
|
||||
return new Common::MemoryReadStream(buf, hdr._originalSize,
|
||||
DisposeAfterUse::YES);
|
||||
}
|
||||
|
||||
void ResArchive::lzssDecompress(const byte *src, byte *dest) const {
|
||||
const uint16 size = READ_LE_UINT16(src);
|
||||
assert(READ_LE_UINT16(src + 2) == 1);
|
||||
src += 4;
|
||||
|
||||
decompressLzss(src, dest, size);
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
102
engines/got/utils/res_archive.h
Normal file
102
engines/got/utils/res_archive.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/* 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 GOT_UTILS_RES_ARCHIVE_H
|
||||
#define GOT_UTILS_RES_ARCHIVE_H
|
||||
|
||||
#include "common/archive.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
struct ResHeader {
|
||||
Common::String _name;
|
||||
uint32 _offset = 0;
|
||||
uint32 _size = 0;
|
||||
uint32 _originalSize = 0;
|
||||
int _key = 0;
|
||||
|
||||
void load(Common::SeekableReadStream *src);
|
||||
};
|
||||
|
||||
#define RES_MAX_ENTRIES 256 // Max # of elements
|
||||
#define RES_HEADER_ENTRY_SIZE 23 // Size of a single header entry
|
||||
class ResArchive : public Common::Archive {
|
||||
private:
|
||||
Common::Array<ResHeader> _headers;
|
||||
|
||||
/**
|
||||
* Decrypts a passed buffer
|
||||
* @param buf Pointer to buffer
|
||||
* @param len Buffer size
|
||||
* @param key Starting key to use for decryption
|
||||
*/
|
||||
void decrypt(byte *buf, size_t len, byte key) const;
|
||||
|
||||
/**
|
||||
* Decodes a passed buffer
|
||||
*/
|
||||
void lzssDecompress(const byte *src, byte *dest) const;
|
||||
|
||||
/**
|
||||
* Returns the index of a header for a given filename
|
||||
*/
|
||||
int indexOf(const Common::String &name) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
ResArchive();
|
||||
|
||||
/**
|
||||
* Check if a member with the given name is present in the Archive.
|
||||
* Patterns are not allowed, as this is meant to be a quick File::exists()
|
||||
* replacement.
|
||||
*/
|
||||
bool hasFile(const Common::Path &path) const override;
|
||||
|
||||
/**
|
||||
* Add all members of the Archive to list.
|
||||
* Must only append to list, and not remove elements from it.
|
||||
*
|
||||
* @return the number of names added to list
|
||||
*/
|
||||
int listMembers(Common::ArchiveMemberList &list) const override;
|
||||
|
||||
/**
|
||||
* Returns a ArchiveMember representation of the given file.
|
||||
*/
|
||||
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
|
||||
|
||||
/**
|
||||
* Create a stream bound to a member with the specified name in the
|
||||
* archive. If no member with this name exists, 0 is returned.
|
||||
* @return the newly created input stream
|
||||
*/
|
||||
Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
|
||||
};
|
||||
|
||||
extern void resInit();
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
119
engines/got/vars.cpp
Normal file
119
engines/got/vars.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/* 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 "got/vars.h"
|
||||
#include "common/algorithm.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "got/gfx/palette.h"
|
||||
#include "got/got.h"
|
||||
#include "got/utils/file.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
Vars *g_vars;
|
||||
|
||||
Vars::Vars() : _hampic("HAMPIC", 262, false),
|
||||
_odin("ODINPIC", 262, false),
|
||||
_objects("OBJECTS", 262, false),
|
||||
_status("STATUS", -1, false) {
|
||||
g_vars = this;
|
||||
}
|
||||
|
||||
void Vars::load() {
|
||||
_bgPics.load();
|
||||
_font.load();
|
||||
_gfx.load();
|
||||
_hampic.load();
|
||||
_objects.load();
|
||||
_odin.load();
|
||||
_sdData.load();
|
||||
_sound.load();
|
||||
_status.load();
|
||||
_highScores.load();
|
||||
|
||||
_musicFlag = !ConfMan.getBool("music_mute");
|
||||
_soundFlag = !ConfMan.getBool("sfx_mute");
|
||||
|
||||
if (_currentLevel != 23)
|
||||
_storyFlag = false;
|
||||
|
||||
_setup._musicEnabled = _musicFlag;
|
||||
_setup._digitalSound = _soundFlag;
|
||||
_setup._speakerSound = false;
|
||||
_setup._scrollFlag = true;
|
||||
_setup._slowMode = _slowMode;
|
||||
_setup._difficultyLevel = 1;
|
||||
|
||||
_tmpBuff = new byte[TMP_SIZE];
|
||||
|
||||
Gfx::loadPalette();
|
||||
}
|
||||
|
||||
Vars::~Vars() {
|
||||
g_vars = nullptr;
|
||||
|
||||
delete[] _tmpBuff;
|
||||
}
|
||||
|
||||
void Vars::setArea(int areaNum) {
|
||||
_area = areaNum;
|
||||
_setup = Setup();
|
||||
loadArea();
|
||||
}
|
||||
|
||||
void Vars::loadArea() {
|
||||
int areaNum = _area;
|
||||
_setup._areaNum = areaNum;
|
||||
|
||||
_sdData.setArea(areaNum);
|
||||
_bgPics.setArea(areaNum);
|
||||
|
||||
switch (areaNum) {
|
||||
case 1:
|
||||
_currentLevel = 23;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
_currentLevel = 51;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
_currentLevel = 33;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Vars::clearKeyFlags() {
|
||||
Common::fill(_keyFlag, _keyFlag + 100, 0);
|
||||
}
|
||||
|
||||
void Vars::resetEndGameFlags() {
|
||||
_gameMode = MODE_NORMAL;
|
||||
_endTile = false;
|
||||
_bossDead = false;
|
||||
_gameOver = false;
|
||||
_bossIntro1 = _bossIntro2 = false;
|
||||
}
|
||||
|
||||
} // namespace Got
|
||||
214
engines/got/vars.h
Normal file
214
engines/got/vars.h
Normal file
@@ -0,0 +1,214 @@
|
||||
/* 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 GOT_VARS_H
|
||||
#define GOT_VARS_H
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/queue.h"
|
||||
#include "got/data/defines.h"
|
||||
#include "got/data/highscores.h"
|
||||
#include "got/data/level.h"
|
||||
#include "got/data/sd_data.h"
|
||||
#include "got/data/setup.h"
|
||||
#include "got/data/thorinfo.h"
|
||||
#include "got/game/script.h"
|
||||
#include "got/gfx/font.h"
|
||||
#include "got/gfx/gfx_chunks.h"
|
||||
#include "got/gfx/gfx_pics.h"
|
||||
#include "got/metaengine.h"
|
||||
#include "got/sound.h"
|
||||
#include "graphics/screen.h"
|
||||
|
||||
namespace Got {
|
||||
|
||||
#define TILE_SIZE 16
|
||||
#define TILES_X (320 / TILE_SIZE)
|
||||
#define TILES_Y (192 / TILE_SIZE)
|
||||
#define TILES_COUNT (TILES_X * TILES_Y)
|
||||
|
||||
class Vars;
|
||||
|
||||
extern Vars *g_vars;
|
||||
|
||||
enum Key {
|
||||
key_none = KEYBIND_NONE,
|
||||
key_up = KEYBIND_UP,
|
||||
key_down = KEYBIND_DOWN,
|
||||
key_left = KEYBIND_LEFT,
|
||||
key_right = KEYBIND_RIGHT,
|
||||
key_fire = KEYBIND_FIRE,
|
||||
key_magic = KEYBIND_MAGIC,
|
||||
key_select = KEYBIND_SELECT
|
||||
};
|
||||
|
||||
enum GameMode {
|
||||
MODE_NORMAL,
|
||||
MODE_AREA_CHANGE,
|
||||
MODE_THUNDER,
|
||||
MODE_THOR_DIES,
|
||||
MODE_ADD_SCORE,
|
||||
MODE_LIGHTNING,
|
||||
MODE_PAUSE,
|
||||
MODE_SCORE_INV
|
||||
};
|
||||
|
||||
enum TransitionDir {
|
||||
DIR_LEFT,
|
||||
DIR_RIGHT,
|
||||
DIR_UP,
|
||||
DIR_DOWN,
|
||||
DIR_PHASED
|
||||
};
|
||||
|
||||
struct Cheats {
|
||||
bool _freezeHealth = false;
|
||||
bool _freezeMagic = false;
|
||||
bool _freezeJewels = false;
|
||||
};
|
||||
|
||||
class Vars {
|
||||
public:
|
||||
Vars();
|
||||
~Vars();
|
||||
|
||||
void load();
|
||||
void setArea(int areaNum);
|
||||
void loadArea();
|
||||
void clearKeyFlags();
|
||||
void resetEndGameFlags();
|
||||
|
||||
Common::String _playerName = "ScummVM";
|
||||
Gfx::GfxChunks _gfx;
|
||||
Gfx::BgPics _bgPics;
|
||||
Gfx::Font _font;
|
||||
Gfx::Pics _hampic;
|
||||
Gfx::Pics _objects;
|
||||
Gfx::Pics _odin;
|
||||
Gfx::Pics _status;
|
||||
HighScores _highScores;
|
||||
SdData _sdData;
|
||||
Sound _sound;
|
||||
Scripts _scripts;
|
||||
GameMode _gameMode = MODE_NORMAL;
|
||||
TransitionDir _transitionDir = DIR_LEFT;
|
||||
Cheats _cheats;
|
||||
Common::Queue<byte> _demoKeys;
|
||||
bool _useItemFlag = false;
|
||||
bool _slipFlag = false;
|
||||
bool _slipping = false;
|
||||
int _slipCount = 0;
|
||||
bool _bossIntro1 = false;
|
||||
bool _bossIntro2 = false;
|
||||
|
||||
int8 _pge = 0;
|
||||
int _exitFlag = 0;
|
||||
|
||||
byte _keyFlag[100] = {};
|
||||
int8 _diag = 0;
|
||||
bool _diagFlag = false;
|
||||
bool _slowMode = false;
|
||||
bool _startup = true;
|
||||
bool _shotOk = false;
|
||||
int _thorX1 = 0;
|
||||
int _thorY1 = 0;
|
||||
int _thorX2 = 0;
|
||||
int _thorY2 = 0;
|
||||
int _thorRealY1 = 0;
|
||||
int _thorPos = 0;
|
||||
|
||||
uint _magicCounter = 0;
|
||||
|
||||
byte _objectMap[TILES_COUNT] = {};
|
||||
byte _objectIndex[TILES_COUNT] = {};
|
||||
int8 _thorIcon1 = 0;
|
||||
int8 _thorIcon2 = 0;
|
||||
int8 _thorIcon3 = 0;
|
||||
int8 _thorIcon4 = 0;
|
||||
int8 _levelMusic = 0;
|
||||
int8 _currentMusic = -1;
|
||||
int8 _appleDropCounter = 0;
|
||||
bool _cheat = false;
|
||||
int8 _area = 1;
|
||||
|
||||
Level _scrn;
|
||||
|
||||
Setup _setup;
|
||||
Setup _lastSetup;
|
||||
byte *_tmpBuff = nullptr;
|
||||
|
||||
Actor _actor[MAX_ACTORS] = {}; //current actors
|
||||
Actor _enemy[MAX_ENEMIES] = {}; //current enemies
|
||||
Actor _shot[MAX_ENEMIES] = {}; //current shots
|
||||
int8 _enemyType[MAX_ENEMIES] = {};
|
||||
int _etype[MAX_ENEMIES] = {};
|
||||
|
||||
Actor _magicItem[2] = {};
|
||||
byte _magicPic[2][1024] = {};
|
||||
bool _warpScroll = false;
|
||||
|
||||
Actor *_thor = nullptr;
|
||||
Actor *_hammer = nullptr;
|
||||
Actor _explosion;
|
||||
Actor _sparkle;
|
||||
ThorInfo _thorInfo;
|
||||
bool _bossDead = false;
|
||||
byte _endGame = 0;
|
||||
|
||||
bool _warpFlag = false;
|
||||
|
||||
int _rand1 = 0;
|
||||
int _rand2 = 0;
|
||||
int _thunderSnakeCounter = 0;
|
||||
bool _tornadoUsed = false;
|
||||
bool _shieldOn = false;
|
||||
bool _appleFlag = false;
|
||||
int _switchUsed = 0;
|
||||
|
||||
bool _musicFlag = false;
|
||||
bool _soundFlag = false;
|
||||
bool _cashDoor1Inform = false;
|
||||
bool _cashDoor2Inform = false;
|
||||
bool _keyDoorInform = false;
|
||||
bool _magicMissingInform = false;
|
||||
bool _cantCarryInform = false;
|
||||
bool _killGoodGuyInform = false;
|
||||
|
||||
bool _bossActive = false;
|
||||
bool _storyFlag = true;
|
||||
int8 *_scr = nullptr;
|
||||
bool _demo = false;
|
||||
bool _gameOver = false;
|
||||
bool _endTile = false;
|
||||
int _currentLevel = 23;
|
||||
int _newLevel = 0;
|
||||
int _newLevelTile = 0;
|
||||
int _currentArea = 0;
|
||||
bool _thorSpecialFlag = false;
|
||||
byte _explosionRow = 0;
|
||||
bool _eyeballs = 0;
|
||||
};
|
||||
|
||||
#define _G(X) (g_vars->_##X)
|
||||
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
158
engines/got/views/credits.cpp
Normal file
158
engines/got/views/credits.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/* 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 "got/views/credits.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
|
||||
#ifdef USE_TTS
|
||||
|
||||
static const char *creditsText[] = {
|
||||
"Programming: Ron Davis",
|
||||
"Graphics: Gary Sirois",
|
||||
"Level Design: Adam Pedersen",
|
||||
"Additional Programming: Jason Blochowiak",
|
||||
"Music: Roy Davis",
|
||||
"Title Screen Art: Wayne C. Timmerman",
|
||||
"Additional Level Design: Ron Davis, Doug Howell, Ken Heckbert, Evan Heckbert",
|
||||
"Play Testing: Ken Heckbert, Doug Howell, Tom King",
|
||||
"Play Testing: Kelly Rogers, Michael Smith, Rik Pierce"
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#define CREDITS_COUNT 9
|
||||
#define FADE_FRAMES 15
|
||||
#define DISPLAY_TIME 15
|
||||
#define CREDIT_TIME (FADE_FRAMES * 2 + DISPLAY_TIME)
|
||||
|
||||
bool Credits::msgFocus(const FocusMessage &msg) {
|
||||
_delayCtr = 0;
|
||||
_frameCtr = 0;
|
||||
|
||||
draw();
|
||||
const Gfx::Palette63 pal = _G(gfx[41]);
|
||||
fadeIn(pal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Credits::draw() {
|
||||
GfxSurface s = getSurface();
|
||||
|
||||
// Draw scroll background
|
||||
const Graphics::ManagedSurface &bg = _G(gfx[42]);
|
||||
s.clear(*(const byte *)bg.getPixels());
|
||||
s.simpleBlitFrom(bg, Common::Point(0, 24));
|
||||
|
||||
const int creditNum = _frameCtr / CREDIT_TIME;
|
||||
int subNum = _frameCtr % CREDIT_TIME;
|
||||
|
||||
if (subNum >= (FADE_FRAMES + DISPLAY_TIME)) {
|
||||
subNum = (FADE_FRAMES - 1) - (subNum - (FADE_FRAMES + DISPLAY_TIME));
|
||||
} else if (subNum >= FADE_FRAMES) {
|
||||
subNum = FADE_FRAMES - 1;
|
||||
}
|
||||
|
||||
if (creditNum < CREDITS_COUNT) {
|
||||
const int gfxNum1 = 43 + creditNum;
|
||||
const int gfxNum2 = 67 + creditNum;
|
||||
const int gfxNum3 = 52 + subNum;
|
||||
const int gfxNum4 = 76 + subNum;
|
||||
|
||||
drawCredit(s, gfxNum1, gfxNum3, 16, 40 + 24);
|
||||
drawCredit(s, gfxNum2, gfxNum4, 16, 40 + 24);
|
||||
|
||||
#ifdef USE_TTS
|
||||
sayText(creditsText[creditNum]);
|
||||
#endif
|
||||
}
|
||||
|
||||
s.markAllDirty();
|
||||
}
|
||||
|
||||
void Credits::drawCredit(GfxSurface &s, int gfxNum1, int gfxNum2, int x, int y) {
|
||||
const Gfx::GraphicChunk &data = _G(gfx[gfxNum1]);
|
||||
const Gfx::GraphicChunk &lookup = _G(gfx[gfxNum2]);
|
||||
const byte *lines = data._data;
|
||||
const byte *lineData = data._data + 2 * data._height;
|
||||
|
||||
assert(x >= 0 && (x + data._width) <= 320);
|
||||
assert(y >= 0 && (y + data._height) <= 200);
|
||||
|
||||
for (int yCtr = 0; yCtr < data._height; ++yCtr) {
|
||||
byte *dest = (byte *)s.getBasePtr(x, y + yCtr);
|
||||
uint16 lineParts = READ_LE_UINT16(lines);
|
||||
lines += 2;
|
||||
|
||||
if (lineParts == 0)
|
||||
// Nothing on line, move to next
|
||||
continue;
|
||||
|
||||
for (; lineParts > 0; --lineParts) {
|
||||
byte count = *lineData++;
|
||||
|
||||
if (count & 0x80) {
|
||||
// Shade a range of pixels using lookup table
|
||||
count &= 0x7f;
|
||||
for (int i = 0; i < count; ++i, ++dest)
|
||||
*dest = lookup._data[*dest];
|
||||
} else {
|
||||
dest += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Credits::tick() {
|
||||
if (++_delayCtr >= 3) {
|
||||
_delayCtr = 0;
|
||||
|
||||
if (_frameCtr == (CREDIT_TIME * CREDITS_COUNT) + 10) {
|
||||
replaceView("HighScores", true, true);
|
||||
} else {
|
||||
#ifdef USE_TTS
|
||||
// Pause credits progression until TTS is finished
|
||||
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
|
||||
if (_frameCtr % CREDIT_TIME < FADE_FRAMES + DISPLAY_TIME || !ttsMan || !ttsMan->isSpeaking())
|
||||
#endif
|
||||
++_frameCtr;
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Credits::msgAction(const ActionMessage &msg) {
|
||||
if (msg._action == KEYBIND_ESCAPE) {
|
||||
fadeOut();
|
||||
send("TitleBackground", GameMessage("MAIN_MENU"));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
50
engines/got/views/credits.h
Normal file
50
engines/got/views/credits.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* 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 GOT_VIEWS_CREDITS_H
|
||||
#define GOT_VIEWS_CREDITS_H
|
||||
|
||||
#include "got/views/view.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
|
||||
class Credits : public View {
|
||||
private:
|
||||
int _delayCtr = 0;
|
||||
int _frameCtr = 0;
|
||||
|
||||
void drawCredit(GfxSurface &s, int gfxNum1, int gfxNum2, int x, int y);
|
||||
|
||||
public:
|
||||
Credits() : View("Credits") {}
|
||||
virtual ~Credits() {}
|
||||
|
||||
bool msgFocus(const FocusMessage &msg) override;
|
||||
bool msgAction(const ActionMessage &msg) override;
|
||||
void draw() override;
|
||||
bool tick() override;
|
||||
};
|
||||
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
48
engines/got/views/dialogs/ask.cpp
Normal file
48
engines/got/views/dialogs/ask.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/* 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 "got/views/dialogs/ask.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
namespace Dialogs {
|
||||
|
||||
Ask::Ask() : SelectOption("Ask") {
|
||||
}
|
||||
|
||||
void Ask::show(const Common::String &title, const Common::StringArray &options) {
|
||||
Ask *view = (Ask *)g_events->findView("Ask");
|
||||
view->setContent(title, options);
|
||||
view->addView();
|
||||
}
|
||||
|
||||
void Ask::closed() {
|
||||
_G(scripts).setAskResponse(0);
|
||||
}
|
||||
|
||||
void Ask::selected() {
|
||||
_G(scripts).setAskResponse(_selectedItem + 1);
|
||||
}
|
||||
|
||||
} // namespace Dialogs
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
45
engines/got/views/dialogs/ask.h
Normal file
45
engines/got/views/dialogs/ask.h
Normal file
@@ -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 GOT_VIEWS_DIALOGS_ASK_H
|
||||
#define GOT_VIEWS_DIALOGS_ASK_H
|
||||
|
||||
#include "got/views/dialogs/select_option.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
namespace Dialogs {
|
||||
|
||||
class Ask : public SelectOption {
|
||||
public:
|
||||
Ask();
|
||||
virtual ~Ask() {}
|
||||
|
||||
static void show(const Common::String &title, const Common::StringArray &options);
|
||||
void closed() override;
|
||||
void selected() override;
|
||||
};
|
||||
|
||||
} // namespace Dialogs
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
62
engines/got/views/dialogs/dialog.cpp
Normal file
62
engines/got/views/dialogs/dialog.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/* 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 "got/views/dialogs/dialog.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
namespace Dialogs {
|
||||
|
||||
Dialog::Dialog(const Common::String &name) : View(name) {
|
||||
_bounds.setBorderSize(16);
|
||||
}
|
||||
|
||||
void Dialog::draw() {
|
||||
// Clear the inner content first
|
||||
GfxSurface s = getSurface(true);
|
||||
s.clear(215);
|
||||
|
||||
s = getSurface();
|
||||
assert((s.w % 16) == 0 && (s.h % 16) == 0);
|
||||
|
||||
// Draw four corners
|
||||
s.simpleBlitFrom(_G(bgPics[192]), Common::Point(0, 0));
|
||||
s.simpleBlitFrom(_G(bgPics[193]), Common::Point(_bounds.width() - 16, 0));
|
||||
s.simpleBlitFrom(_G(bgPics[194]), Common::Point(0, _bounds.height() - 16));
|
||||
s.simpleBlitFrom(_G(bgPics[195]), Common::Point(_bounds.width() - 16, _bounds.height() - 16));
|
||||
|
||||
// Draw top/bottom horizontal lines
|
||||
for (int x = 16; x < _bounds.width() - 16; x += 16) {
|
||||
s.simpleBlitFrom(_G(bgPics[196]), Common::Point(x, 0));
|
||||
s.simpleBlitFrom(_G(bgPics[197]), Common::Point(x, _bounds.height() - 16));
|
||||
}
|
||||
|
||||
// Draw left/right vertical lines
|
||||
for (int y = 16; y < _bounds.height() - 16; y += 16) {
|
||||
s.simpleBlitFrom(_G(bgPics[198]), Common::Point(0, y));
|
||||
s.simpleBlitFrom(_G(bgPics[199]), Common::Point(_bounds.width() - 16, y));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Dialogs
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
43
engines/got/views/dialogs/dialog.h
Normal file
43
engines/got/views/dialogs/dialog.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* 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 GOT_VIEWS_DIALOGS_DIALOG_H
|
||||
#define GOT_VIEWS_DIALOGS_DIALOG_H
|
||||
|
||||
#include "got/views/view.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
namespace Dialogs {
|
||||
|
||||
class Dialog : public View {
|
||||
public:
|
||||
Dialog(const Common::String &name);
|
||||
virtual ~Dialog() {}
|
||||
|
||||
void draw() override;
|
||||
};
|
||||
|
||||
} // namespace Dialogs
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
145
engines/got/views/dialogs/high_scores.cpp
Normal file
145
engines/got/views/dialogs/high_scores.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/* 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 "got/views/dialogs/high_scores.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
namespace Dialogs {
|
||||
|
||||
#define TIMEOUT 500
|
||||
|
||||
HighScores::HighScores() : Dialog("HighScores") {
|
||||
setBounds(Common::Rect(0, 0 + 24, 320, 192 + 24));
|
||||
}
|
||||
|
||||
void HighScores::draw() {
|
||||
// Draw background outside dialog
|
||||
GfxSurface s = GfxSurface(*g_events->getScreen(), Common::Rect(0, 0, 320, 240));
|
||||
|
||||
for (int col = 0, xp = 0; col < 10; ++col, xp += 32) {
|
||||
for (int yp = 0; yp < 240; yp += 32)
|
||||
s.simpleBlitFrom(_G(gfx[26]), Common::Point(xp, yp));
|
||||
}
|
||||
|
||||
// Draw the dialog frame
|
||||
Dialog::draw();
|
||||
|
||||
// Clear the inner content first
|
||||
s = getSurface(true);
|
||||
s.clear(215);
|
||||
|
||||
// Draw title
|
||||
Common::String title = "High Scores - Part I";
|
||||
for (int area = 2; area <= _currentArea; ++area)
|
||||
title += 'I';
|
||||
|
||||
const int titleStart = (s.w - title.size() * 8) / 2;
|
||||
s.print(Common::Point(titleStart, 4), title, 54);
|
||||
#ifdef USE_TTS
|
||||
sayText(title);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
const HighScore &hs = _G(highScores)._scores[_currentArea - 1][i];
|
||||
|
||||
// Draw frames for name and score
|
||||
s.frameRect(Common::Rect(10, 20 + i * 18, 210, 20 + i * 18 + 16), 206);
|
||||
s.frameRect(Common::Rect(220, 20 + i * 18, 280, 20 + i * 18 + 16), 206);
|
||||
|
||||
// Write out the name and scores
|
||||
s.print(Common::Point(15, 24 + i * 18), hs._name, 14);
|
||||
Common::String score = Common::String::format("%d", hs._total);
|
||||
s.print(Common::Point(275 - (score.size() * 8), 24 + i * 18), score, 14);
|
||||
|
||||
#ifdef USE_TTS
|
||||
sayText(Common::String::format("%s: %d", hs._name, hs._total), Common::TextToSpeechManager::QUEUE);
|
||||
_previousSaid.clear();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool HighScores::msgFocus(const FocusMessage &msg) {
|
||||
_currentArea = 1;
|
||||
_showAll = true;
|
||||
_timeoutCtr = TIMEOUT;
|
||||
|
||||
Gfx::loadPalette();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HighScores::msgGame(const GameMessage &msg) {
|
||||
if (msg._name == "HIGH_SCORES") {
|
||||
// Finished one of the parts of the game, so just
|
||||
// set the view to show only scores for that area
|
||||
replaceView("HighScores", true);
|
||||
_currentArea = msg._value;
|
||||
_showAll = false;
|
||||
|
||||
draw();
|
||||
fadeIn();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HighScores::msgAction(const ActionMessage &msg) {
|
||||
if (msg._action == KEYBIND_ESCAPE) {
|
||||
goToMainMenu();
|
||||
} else {
|
||||
goToNextArea();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void HighScores::goToMainMenu() {
|
||||
fadeOut();
|
||||
send("TitleBackground", GameMessage("MAIN_MENU"));
|
||||
}
|
||||
|
||||
void HighScores::goToNextArea() {
|
||||
if (_showAll && _currentArea < 3) {
|
||||
fadeOut();
|
||||
++_currentArea;
|
||||
draw();
|
||||
fadeIn();
|
||||
_timeoutCtr = TIMEOUT;
|
||||
|
||||
} else {
|
||||
// Done all the areas, so
|
||||
goToMainMenu();
|
||||
}
|
||||
}
|
||||
|
||||
bool HighScores::tick() {
|
||||
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
|
||||
if (--_timeoutCtr < 0 && (!ttsMan || !ttsMan->isSpeaking()))
|
||||
goToNextArea();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Dialogs
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
56
engines/got/views/dialogs/high_scores.h
Normal file
56
engines/got/views/dialogs/high_scores.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* 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 GOT_VIEWS_DIALOGS_HIGH_SCORES_H
|
||||
#define GOT_VIEWS_DIALOGS_HIGH_SCORES_H
|
||||
|
||||
#include "got/views/dialogs/dialog.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
namespace Dialogs {
|
||||
|
||||
class HighScores : public Dialog {
|
||||
private:
|
||||
int _currentArea = 0;
|
||||
bool _showAll = false;
|
||||
int _timeoutCtr = 0;
|
||||
|
||||
void goToMainMenu();
|
||||
void goToNextArea();
|
||||
|
||||
public:
|
||||
HighScores();
|
||||
virtual ~HighScores() {
|
||||
}
|
||||
|
||||
void draw() override;
|
||||
bool msgFocus(const FocusMessage &msg) override;
|
||||
bool msgAction(const ActionMessage &msg) override;
|
||||
bool msgGame(const GameMessage &msg) override;
|
||||
bool tick() override;
|
||||
};
|
||||
|
||||
} // namespace Dialogs
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
99
engines/got/views/dialogs/main_menu.cpp
Normal file
99
engines/got/views/dialogs/main_menu.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/* 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 "got/views/dialogs/main_menu.h"
|
||||
#include "got/game/init.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
namespace Dialogs {
|
||||
|
||||
static const char *OPTIONS[] = {"Play Game", "Load Game", "High Scores", "Credits", "Demo", "Quit", nullptr};
|
||||
static const char *OPTIONS_NO_DEMO[] = {"Play Game", "Load Game", "High Scores", "Credits", "Quit", nullptr};
|
||||
|
||||
MainMenu::MainMenu() : SelectOption("MainMenu", "God of Thunder Menu",
|
||||
gDebugLevel > 0 ? OPTIONS : OPTIONS_NO_DEMO) {
|
||||
}
|
||||
|
||||
bool MainMenu::msgFocus(const FocusMessage &msg) {
|
||||
g_vars->resetEndGameFlags();
|
||||
musicPlay("MENU", false);
|
||||
|
||||
return SelectOption::msgFocus(msg);
|
||||
}
|
||||
|
||||
void MainMenu::closed() {
|
||||
_selectedItem = 4; // Quit game
|
||||
selected();
|
||||
}
|
||||
|
||||
void MainMenu::selected() {
|
||||
switch (_selectedItem) {
|
||||
case 0:
|
||||
_G(demo) = false;
|
||||
|
||||
if (g_events->isDemo()) {
|
||||
// The shareware release only has part 1
|
||||
g_vars->setArea(1);
|
||||
initGame();
|
||||
replaceView("Story", true, true);
|
||||
} else {
|
||||
// Full game. Select the game part
|
||||
addView("SelectGame");
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (!g_engine->loadGameDialog())
|
||||
addView("SelectGame");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
replaceView("HighScores", true, true);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
addView("Credits");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (gDebugLevel > 0) {
|
||||
_G(demo) = true;
|
||||
initGame();
|
||||
replaceView("PartTitle", true, true);
|
||||
} else {
|
||||
addView("Quit");
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
addView("Quit");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Dialogs
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
45
engines/got/views/dialogs/main_menu.h
Normal file
45
engines/got/views/dialogs/main_menu.h
Normal file
@@ -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 GOT_VIEWS_DIALOGS_MAIN_MENU_H
|
||||
#define GOT_VIEWS_DIALOGS_MAIN_MENU_H
|
||||
|
||||
#include "got/views/dialogs/select_option.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
namespace Dialogs {
|
||||
|
||||
class MainMenu : public SelectOption {
|
||||
public:
|
||||
MainMenu();
|
||||
virtual ~MainMenu() {}
|
||||
|
||||
bool msgFocus(const FocusMessage &msg) override;
|
||||
void closed() override;
|
||||
void selected() override;
|
||||
};
|
||||
|
||||
} // namespace Dialogs
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
69
engines/got/views/dialogs/options_menu.cpp
Normal file
69
engines/got/views/dialogs/options_menu.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/* 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 "got/views/dialogs/options_menu.h"
|
||||
#include "got/game/back.h"
|
||||
#include "got/vars.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
namespace Dialogs {
|
||||
|
||||
static const char *OPTIONS[] = {"Sound/Music", "Skill Level", "Save Game", "Load Game", "Die", "Turbo Mode", "Help", "Quit", nullptr};
|
||||
|
||||
OptionsMenu::OptionsMenu() : SelectOption("OptionsMenu", "Options Menu", OPTIONS) {
|
||||
}
|
||||
|
||||
void OptionsMenu::selected() {
|
||||
switch (_selectedItem) {
|
||||
case 0:
|
||||
addView("SetSound");
|
||||
break;
|
||||
case 1:
|
||||
addView("SkillLevel");
|
||||
break;
|
||||
case 2:
|
||||
g_engine->saveGameDialog();
|
||||
break;
|
||||
case 3:
|
||||
g_engine->loadGameDialog();
|
||||
break;
|
||||
case 4:
|
||||
g_events->send(GameMessage("THOR_DIES"));
|
||||
break;
|
||||
case 5:
|
||||
addView("SelectSlow");
|
||||
break;
|
||||
case 6:
|
||||
// Help
|
||||
odinSpeaks(2008, -1);
|
||||
break;
|
||||
case 7:
|
||||
addView("QuitGame");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Dialogs
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
43
engines/got/views/dialogs/options_menu.h
Normal file
43
engines/got/views/dialogs/options_menu.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* 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 GOT_VIEWS_DIALOGS_OPTIONS_MENU_H
|
||||
#define GOT_VIEWS_DIALOGS_OPTIONS_MENU_H
|
||||
|
||||
#include "got/views/dialogs/select_option.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
namespace Dialogs {
|
||||
|
||||
class OptionsMenu : public SelectOption {
|
||||
public:
|
||||
OptionsMenu();
|
||||
virtual ~OptionsMenu() {}
|
||||
|
||||
void selected() override;
|
||||
};
|
||||
|
||||
} // namespace Dialogs
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
|
||||
#endif
|
||||
51
engines/got/views/dialogs/quit.cpp
Normal file
51
engines/got/views/dialogs/quit.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 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 "got/views/dialogs/quit.h"
|
||||
#include "got/got.h"
|
||||
|
||||
namespace Got {
|
||||
namespace Views {
|
||||
namespace Dialogs {
|
||||
|
||||
Quit::Quit() : SelectOption("Quit", "Quit Game?", YES_NO) {
|
||||
}
|
||||
|
||||
void Quit::selected() {
|
||||
switch (_selectedItem) {
|
||||
case 0:
|
||||
g_engine->quitGame();
|
||||
break;
|
||||
case 1:
|
||||
addView("MainMenu");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Quit::closed() {
|
||||
addView("MainMenu");
|
||||
}
|
||||
|
||||
} // namespace Dialogs
|
||||
} // namespace Views
|
||||
} // namespace Got
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user