Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,311 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#include "common/random.h"
#include "common/stream.h"
#include "gob/surface.h"
#include "gob/video.h"
#include "gob/pregob/gctfile.h"
namespace Gob {
GCTFile::Chunk::Chunk() : type(kChunkTypeNone) {
}
GCTFile::GCTFile(Common::SeekableReadStream &gct, Common::RandomSource &rnd) : _rnd(&rnd),
_areaLeft(0), _areaTop(0), _areaRight(0), _areaBottom(0), _currentItem(0xFFFF) {
load(gct);
}
GCTFile::~GCTFile() {
}
void GCTFile::load(Common::SeekableReadStream &gct) {
gct.skip(4); // Required buffer size
gct.skip(2); // Unknown
// Read the selector and line counts for each item
const uint16 itemCount = gct.readUint16LE();
_items.resize(itemCount);
for (auto &item : _items) {
const uint16 selector = gct.readUint16LE();
const uint16 lineCount = gct.readUint16LE();
item.selector = selector;
item.lines.resize(lineCount);
}
// Read all item lines
for (auto &item : _items) {
for (auto &line : item.lines) {
const uint16 lineSize = gct.readUint16LE();
readLine(gct, line, lineSize);
}
}
if (gct.err())
error("GCTFile::load(): Failed reading GCT");
}
void GCTFile::readLine(Common::SeekableReadStream &gct, Line &line, uint16 lineSize) const {
line.chunks.push_back(Chunk());
while (lineSize > 0) {
byte c = gct.readByte();
lineSize--;
if (c == 0) {
// Command byte
if (lineSize == 0)
break;
byte cmd = gct.readByte();
lineSize--;
// Line end command
if (cmd == 0)
break;
// Item reference command
if (cmd == 1) {
if (lineSize < 2) {
warning("GCTFile::readLine(): Item reference command is missing parameters");
break;
}
const uint32 itemRef = gct.readUint16LE();
lineSize -= 2;
line.chunks.push_back(Chunk());
line.chunks.back().type = kChunkTypeItem;
line.chunks.back().item = itemRef;
line.chunks.push_back(Chunk());
continue;
}
warning("GCTFile::readLine(): Invalid command 0x%02X", cmd);
break;
}
// Text
line.chunks.back().type = kChunkTypeString;
line.chunks.back().text += (char)c;
}
// Skip bytes we didn't read (because of errors)
gct.skip(lineSize);
// Remove empty chunks from the end of the list
while (!line.chunks.empty() && (line.chunks.back().type == kChunkTypeNone))
line.chunks.pop_back();
}
uint16 GCTFile::getLineCount(uint item) const {
if (item >= _items.size())
return 0;
return _items[item].lines.size();
}
void GCTFile::selectLine(uint item, uint16 line) {
if ((item >= _items.size()) && (item != kSelectorAll) && (item != kSelectorRandom))
return;
_items[item].selector = line;
}
void GCTFile::setText(uint item, uint16 line, const Common::String &text) {
if ((item >= _items.size()) || (line >= _items[item].lines.size()))
return;
_items[item].lines[line].chunks.clear();
_items[item].lines[line].chunks.push_back(Chunk());
_items[item].lines[line].chunks.back().type = kChunkTypeString;
_items[item].lines[line].chunks.back().text = text;
}
void GCTFile::setText(uint item, const Common::String &text) {
if (item >= _items.size())
return;
_items[item].selector = 0;
_items[item].lines.resize(1);
setText(item, 0, text);
}
void GCTFile::reset() {
_currentItem = 0xFFFF;
_currentText.clear();
}
Common::String GCTFile::getLineText(const Line &line) const {
Common::String text;
// Go over all chunks in this line
for (const auto &chunk : line.chunks) {
// A chunk is either a direct string, or a reference to another item
if (chunk.type == kChunkTypeItem) {
Common::List<Common::String> lines;
getItemText(chunk.item, lines);
if (lines.empty())
continue;
if (lines.size() > 1)
warning("GCTFile::getLineText(): Referenced item has multiple lines");
text += lines.front();
} else if (chunk.type == kChunkTypeString)
text += chunk.text;
}
return text;
}
void GCTFile::getItemText(uint item, Common::List<Common::String> &text) const {
text.clear();
if ((item >= _items.size()) || _items[item].lines.empty())
return;
uint16 line = _items[item].selector;
// Draw all lines
if (line == kSelectorAll) {
for (Lines::const_iterator l = _items[item].lines.begin(); l != _items[item].lines.end(); ++l)
text.push_back(getLineText(*l));
return;
}
// Draw random line
if (line == kSelectorRandom)
line = _rnd->getRandomNumber(_items[item].lines.size() - 1);
if (line >= _items[item].lines.size())
return;
text.push_back(getLineText(_items[item].lines[line]));
}
void GCTFile::setArea(int16 left, int16 top, int16 right, int16 bottom) {
trashBuffer();
_hasArea = false;
const int16 width = right - left + 1;
const int16 height = bottom - top + 1;
if ((width <= 0) || (height <= 0))
return;
_areaLeft = left;
_areaTop = top;
_areaRight = right;
_areaBottom = bottom;
_hasArea = true;
resizeBuffer(width, height);
}
bool GCTFile::clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) {
return restoreScreen(dest, left, top, right, bottom);
}
bool GCTFile::fill(Surface &dest, uint8 color, int16 &left, int16 &top, int16 &right, int16 &bottom) {
left = _areaLeft;
top = _areaTop;
right = _areaRight;
bottom = _areaBottom;
if (!hasSavedBackground())
saveScreen(dest, left, top, right, bottom);
dest.fillRect(left, top, right, bottom, color);
return true;
}
bool GCTFile::finished() const {
return (_currentItem != 0xFFFF) && _currentText.empty();
}
bool GCTFile::draw(Surface &dest, uint16 item, const Font &font, uint8 color,
int16 &left, int16 &top, int16 &right, int16 &bottom) {
if ((item >= _items.size()) || !_hasArea)
return false;
left = _areaLeft;
top = _areaTop;
right = _areaRight;
bottom = _areaBottom;
const int16 width = right - left + 1;
const int16 height = bottom - top + 1;
const uint lineCount = height / font.getCharHeight();
if (lineCount == 0)
return false;
if (!hasSavedBackground())
saveScreen(dest, left, top, right, bottom);
if (item != _currentItem) {
_currentItem = item;
getItemText(_currentItem, _currentText);
}
if (_currentText.empty())
return false;
int16 y = top;
for (uint i = 0; (i < lineCount) && !_currentText.empty(); i++, y += font.getCharHeight()) {
const Common::String &line = _currentText.front();
const int16 x = left + ((width - (line.size() * font.getCharWidth())) / 2);
font.drawString(line, x, y, color, 0, true, dest);
_currentText.pop_front();
}
return true;
}
} // End of namespace Gob

View File

@@ -0,0 +1,154 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_GCTFILE_H
#define GOB_PREGOB_GCTFILE_H
#include "common/str.h"
#include "common/array.h"
#include "common/list.h"
#include "gob/backbuffer.h"
namespace Common {
class RandomSource;
class SeekableReadStream;
}
namespace Gob {
class Surface;
class Font;
class GCTFile : public BackBuffer {
public:
static const uint16 kSelectorAll = 0xFFFE; ///< Print all lines.
static const uint16 kSelectorRandom = 0xFFFF; ///< Print a random line.
GCTFile(Common::SeekableReadStream &gct, Common::RandomSource &rnd);
~GCTFile();
/** Return the number of lines in an item. */
uint16 getLineCount(uint item) const;
/** Set the area the text will be printed in. */
void setArea(int16 left, int16 top, int16 right, int16 bottom);
/** Set which line of this item should be printed. */
void selectLine(uint item, uint16 line);
/** Change the text of an items' line. */
void setText(uint item, uint16 line, const Common::String &text);
/** Change the item into one one line and set that line's text. */
void setText(uint item, const Common::String &text);
/** Reset the item drawing state. */
void reset();
/** Clear the drawn text, restoring the original content. */
bool clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom);
/** Fill the text area with a color. */
bool fill(Surface &dest, uint8 color, int16 &left, int16 &top, int16 &right, int16 &bottom);
/** Draw an item onto the surface, until all text has been drawn or the area is filled. */
bool draw(Surface &dest, uint16 item, const Font &font, uint8 color,
int16 &left, int16 &top, int16 &right, int16 &bottom);
/** Did we draw all text? */
bool finished() const;
private:
/** The type of a chunk. */
enum ChunkType {
kChunkTypeNone = 0, ///< Do nothing.
kChunkTypeString , ///< A direct string.
kChunkTypeItem ///< A reference to an item to print instead.
};
/** A chunk in an item text line. */
struct Chunk {
ChunkType type; ///< The type of the chunk.
Common::String text; ///< Text to print.
int item; ///< Item to print instead.
Chunk();
};
typedef Common::List<Chunk> Chunks;
/** A line in an item. */
struct Line {
Chunks chunks; ///< The chunks that make up the line.
};
typedef Common::Array<Line> Lines;
/** A GCT item. */
struct Item {
Lines lines; ///< The text lines in the item
uint16 selector; ///< Which line to print.
};
typedef Common::Array<Item> Items;
Common::RandomSource *_rnd;
Items _items; ///< All GCT items.
// The area on which to print
bool _hasArea;
int16 _areaLeft;
int16 _areaTop;
int16 _areaRight;
int16 _areaBottom;
/** Index of the current item we're drawing. */
uint16 _currentItem;
/** Text left to draw. */
Common::List<Common::String> _currentText;
// -- Loading helpers --
void load(Common::SeekableReadStream &gct);
void readLine(Common::SeekableReadStream &gct, Line &line, uint16 lineSize) const;
// -- Draw helpers --
Common::String getLineText(const Line &line) const;
void getItemText(uint item, Common::List<Common::String> &text) const;
};
} // End of namespace Gob
#endif // GOB_PREGOB_GCTFILE_H

View File

@@ -0,0 +1,142 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#include "common/textconsole.h"
#include "gob/gob.h"
#include "gob/pregob/onceupon/abracadabra.h"
static const uint8 kCopyProtectionColors[7] = {
14, 11, 13, 1, 7, 12, 2
};
static const uint8 kCopyProtectionShapes[7 * 20] = {
3, 4, 3, 0, 1, 2, 0, 2, 2, 0, 2, 4, 0, 3, 4, 1, 1, 4, 1, 3,
0, 2, 0, 4, 2, 4, 4, 2, 3, 0, 1, 1, 1, 1, 3, 0, 4, 2, 3, 4,
0, 0, 1, 2, 1, 1, 2, 4, 3, 1, 4, 2, 4, 4, 2, 4, 1, 2, 3, 3,
1, 0, 2, 3, 4, 2, 3, 2, 2, 0, 0, 0, 4, 2, 3, 4, 4, 0, 4, 1,
4, 2, 1, 1, 1, 1, 4, 3, 4, 2, 3, 0, 0, 3, 0, 2, 3, 0, 2, 4,
4, 2, 4, 3, 0, 4, 0, 2, 3, 1, 4, 1, 3, 1, 0, 0, 2, 1, 3, 2,
3, 1, 0, 3, 1, 3, 4, 2, 4, 4, 3, 2, 0, 2, 0, 1, 2, 0, 1, 4
};
static const uint8 kCopyProtectionObfuscate[4] = {
1, 0, 2, 3
};
namespace Gob {
namespace OnceUpon {
const OnceUpon::MenuButton Abracadabra::kAnimalsButtons = {
true, 131, 127, 183, 164, 193, 0, 243, 35, 132, 128, 0
};
const OnceUpon::MenuButton Abracadabra::kAnimalButtons[] = {
{false, 37, 89, 95, 127, 37, 89, 95, 127, 131, 25, 0},
{false, 114, 65, 172, 111, 114, 65, 172, 111, 131, 25, 1},
{false, 186, 72, 227, 96, 186, 72, 227, 96, 139, 25, 2},
{false, 249, 87, 282, 112, 249, 87, 282, 112, 143, 25, 3},
{false, 180, 102, 234, 138, 180, 102, 234, 138, 133, 25, 4},
{false, 197, 145, 242, 173, 197, 145, 242, 173, 137, 25, 5},
{false, 113, 151, 171, 176, 113, 151, 171, 176, 131, 25, 6},
{false, 114, 122, 151, 150, 114, 122, 151, 150, 141, 25, 7},
{false, 36, 136, 94, 176, 36, 136, 94, 176, 131, 25, 8},
{false, 243, 123, 295, 155, 243, 123, 295, 155, 136, 25, 9}
};
const char *Abracadabra::kAnimalNames[] = {
"loup",
"drag",
"arai",
"crap",
"crab",
"mous",
"saut",
"guep",
"rhin",
"scor"
};
// The houses where the stork can drop a bundle
const OnceUpon::MenuButton Abracadabra::kStorkHouses[] = {
{false, 16, 80, 87, 125, 0, 0, 0, 0, 0, 0, 0}, // Castle , Lord & Lady
{false, 61, 123, 96, 149, 0, 0, 0, 0, 0, 0, 1}, // Cottage, Farmers
{false, 199, 118, 226, 137, 0, 0, 0, 0, 0, 0, 2}, // Hut , Woodcutters
{false, 229, 91, 304, 188, 0, 0, 0, 0, 0, 0, 3} // Palace , King & Queen
};
// The stork bundle drop parameters
const Stork::BundleDrop Abracadabra::kStorkBundleDrops[] = {
{ 14, 65, 127, true },
{ 14, 76, 152, true },
{ 14, 204, 137, true },
{ 11, 275, 179, false }
};
// Parameters for the stork section.
const OnceUpon::StorkParam Abracadabra::kStorkParam = {
"present.cmp", ARRAYSIZE(kStorkHouses), kStorkHouses, kStorkBundleDrops
};
Abracadabra::Abracadabra(GobEngine *vm) : OnceUpon(vm) {
}
Abracadabra::~Abracadabra() {
}
void Abracadabra::run() {
init();
// Copy protection
bool correctCP = doCopyProtection(kCopyProtectionColors, kCopyProtectionShapes, kCopyProtectionObfuscate);
if (_vm->shouldQuit() || !correctCP)
return;
// Show the intro
showIntro();
if (_vm->shouldQuit())
return;
// Handle the start menu
doStartMenu(&kAnimalsButtons, ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames);
if (_vm->shouldQuit())
return;
// Play the actual game
playGame();
}
const OnceUpon::StorkParam &Abracadabra::getStorkParameters() const {
return kStorkParam;
}
} // End of namespace OnceUpon
} // End of namespace Gob

View 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_ONCEUPON_ABRACADABRA_H
#define GOB_PREGOB_ONCEUPON_ABRACADABRA_H
#include "gob/pregob/onceupon/onceupon.h"
namespace Gob {
namespace OnceUpon {
class Abracadabra : public OnceUpon {
public:
Abracadabra(GobEngine *vm);
~Abracadabra() override;
void run() override;
protected:
const StorkParam &getStorkParameters() const override;
private:
/** Definition of the menu button that leads to the animal names screen. */
static const MenuButton kAnimalsButtons;
/** Definition of the buttons that make up the animals in the animal names screen. */
static const MenuButton kAnimalButtons[];
/** File prefixes for the name of each animal. */
static const char *kAnimalNames[];
// Parameters for the stork section.
static const MenuButton kStorkHouses[];
static const Stork::BundleDrop kStorkBundleDrops[];
static const struct StorkParam kStorkParam;
};
} // End of namespace OnceUpon
} // End of namespace Gob
#endif // GOB_PREGOB_ONCEUPON_ABRACADABRA_H

View File

@@ -0,0 +1,142 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#include "common/textconsole.h"
#include "gob/gob.h"
#include "gob/pregob/onceupon/babayaga.h"
static const uint8 kCopyProtectionColors[7] = {
14, 11, 13, 1, 7, 12, 2
};
static const uint8 kCopyProtectionShapes[7 * 20] = {
0, 0, 1, 2, 1, 1, 2, 4, 3, 1, 4, 2, 4, 4, 2, 4, 1, 2, 3, 3,
3, 1, 0, 3, 1, 3, 4, 2, 4, 4, 3, 2, 0, 2, 0, 1, 2, 0, 1, 4,
1, 0, 2, 3, 4, 2, 3, 2, 2, 0, 0, 0, 4, 2, 3, 4, 4, 0, 4, 1,
0, 2, 0, 4, 2, 4, 4, 2, 3, 0, 1, 1, 1, 1, 3, 0, 4, 2, 3, 4,
3, 4, 3, 0, 1, 2, 0, 2, 2, 0, 2, 4, 0, 3, 4, 1, 1, 4, 1, 3,
4, 2, 1, 1, 1, 1, 4, 3, 4, 2, 3, 0, 0, 3, 0, 2, 3, 0, 2, 4,
4, 2, 4, 3, 0, 4, 0, 2, 3, 1, 4, 1, 3, 1, 0, 0, 2, 1, 3, 2
};
static const uint8 kCopyProtectionObfuscate[4] = {
0, 1, 2, 3
};
namespace Gob {
namespace OnceUpon {
const OnceUpon::MenuButton BabaYaga::kAnimalsButtons = {
true, 131, 127, 183, 164, 193, 0, 245, 37, 131, 127, 0
};
const OnceUpon::MenuButton BabaYaga::kAnimalButtons[] = {
{false, 34, 84, 92, 127, 34, 84, 92, 127, 131, 25, 0},
{false, 114, 65, 172, 111, 114, 65, 172, 111, 131, 25, 1},
{false, 186, 72, 227, 96, 186, 72, 227, 96, 139, 25, 2},
{false, 249, 87, 282, 112, 249, 87, 282, 112, 143, 25, 3},
{false, 180, 97, 234, 138, 180, 97, 234, 138, 133, 25, 4},
{false, 197, 145, 242, 173, 197, 145, 242, 173, 137, 25, 5},
{false, 113, 156, 171, 176, 113, 156, 171, 176, 131, 25, 6},
{false, 114, 127, 151, 150, 114, 127, 151, 150, 141, 25, 7},
{false, 36, 136, 94, 176, 36, 136, 94, 176, 131, 25, 8},
{false, 245, 123, 293, 155, 245, 123, 293, 155, 136, 25, 9}
};
const char *BabaYaga::kAnimalNames[] = {
"vaut",
"drag",
"arai",
"gren",
"fauc",
"abei",
"serp",
"tort",
"sang",
"rena"
};
// The houses where the stork can drop a bundle
const OnceUpon::MenuButton BabaYaga::kStorkHouses[] = {
{false, 16, 80, 87, 125, 0, 0, 0, 0, 0, 0, 0}, // Castle , Lord & Lady
{false, 61, 123, 96, 149, 0, 0, 0, 0, 0, 0, 1}, // Cottage, Farmers
{false, 199, 118, 226, 137, 0, 0, 0, 0, 0, 0, 2}, // Hut , Woodcutters
{false, 229, 91, 304, 188, 0, 0, 0, 0, 0, 0, 3} // Palace , King & Queen
};
// The stork bundle drop parameters
const Stork::BundleDrop BabaYaga::kStorkBundleDrops[] = {
{ 14, 35, 129, true },
{ 14, 70, 148, true },
{ 14, 206, 136, true },
{ 11, 260, 225, false }
};
// Parameters for the stork section.
const OnceUpon::StorkParam BabaYaga::kStorkParam = {
"present2.cmp", ARRAYSIZE(kStorkHouses), kStorkHouses, kStorkBundleDrops
};
BabaYaga::BabaYaga(GobEngine *vm) : OnceUpon(vm) {
}
BabaYaga::~BabaYaga() {
}
void BabaYaga::run() {
init();
// Copy protection
bool correctCP = doCopyProtection(kCopyProtectionColors, kCopyProtectionShapes, kCopyProtectionObfuscate);
if (_vm->shouldQuit() || !correctCP)
return;
// Show the intro
showIntro();
if (_vm->shouldQuit())
return;
// Handle the start menu
doStartMenu(&kAnimalsButtons, ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames);
if (_vm->shouldQuit())
return;
// Play the actual game
playGame();
}
const OnceUpon::StorkParam &BabaYaga::getStorkParameters() const {
return kStorkParam;
}
} // End of namespace OnceUpon
} // End of namespace Gob

View 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_ONCEUPON_BABAYAGA_H
#define GOB_PREGOB_ONCEUPON_BABAYAGA_H
#include "gob/pregob/onceupon/onceupon.h"
namespace Gob {
namespace OnceUpon {
class BabaYaga : public OnceUpon {
public:
BabaYaga(GobEngine *vm);
~BabaYaga() override;
void run() override;
protected:
const StorkParam &getStorkParameters() const override;
private:
/** Definition of the menu button that leads to the animal names screen. */
static const MenuButton kAnimalsButtons;
/** Definition of the buttons that make up the animals in the animal names screen. */
static const MenuButton kAnimalButtons[];
/** File prefixes for the name of each animal. */
static const char *kAnimalNames[];
// Parameters for the stork section.
static const MenuButton kStorkHouses[];
static const Stork::BundleDrop kStorkBundleDrops[];
static const struct StorkParam kStorkParam;
};
} // End of namespace OnceUpon
} // End of namespace Gob
#endif // GOB_PREGOB_ONCEUPON_BABAYAGA_H

View File

@@ -0,0 +1,65 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_ONCEUPON_BROKENSTRINGS_H
#define GOB_PREGOB_ONCEUPON_BROKENSTRINGS_H
struct BrokenString {
const char *wrong;
const char *correct;
};
struct BrokenStringLanguage {
const BrokenString *strings;
uint count;
};
static const BrokenString kBrokenStringsGerman[] = {
{ "Zeichungen von Kaki," , "Zeichnungen von Kaki," },
{ "die es in seine Wachtr\204ume", "die es in seine Tagtr\204ume" },
{ " Spielerfahrung" , " Spielerfahren" },
{ " Fortgeschrittene" , " Fortgeschritten" },
{ "die Vespe" , "die Wespe" },
{ "das Rhinoceros" , "das Rhinozeros" },
{ "die Heusschrecke" , "die Heuschrecke" },
{ "Das, von Drachen gebrachte" , "Das vom Drachen gebrachte" },
{ "Am Waldesrand es sieht" , "Am Waldesrand sieht es" },
{ " das Kind den Palast." , "das Kind den Palast." },
{ "Am Waldessaum sieht" , "Am Waldesrand sieht" },
{ "tipp auf ESC!" , "dr\201cke ESC!" },
{ "Wohin fliegt der Drachen?" , "Wohin fliegt der Drache?" }
};
static const BrokenStringLanguage kBrokenStrings[kLanguageCount] = {
{ 0, 0 }, // French
{ kBrokenStringsGerman, ARRAYSIZE(kBrokenStringsGerman) }, // German
{ 0, 0 }, // English
{ 0, 0 }, // Spanish
{ 0, 0 }, // Italian
};
#endif // GOB_PREGOB_ONCEUPON_BROKENSTRINGS_H

View File

@@ -0,0 +1,125 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#include "gob/surface.h"
#include "gob/anifile.h"
#include "gob/pregob/onceupon/chargenchild.h"
enum Animation {
kAnimWalkLeft = 0,
kAnimWalkRight = 1,
kAnimJumpLeft = 2,
kAnimJumpRight = 3,
kAnimTapFoot = 14
};
namespace Gob {
namespace OnceUpon {
CharGenChild::CharGenChild(const ANIFile &ani) : ANIObject(ani) {
setPosition(265, 110);
setAnimation(kAnimWalkLeft);
setVisible(true);
setPause(false);
}
CharGenChild::~CharGenChild() {
}
void CharGenChild::advance() {
bool wasLastFrame = lastFrame();
ANIObject::advance();
int16 x, y, left, top, width, height;
getPosition(x, y);
getFramePosition(left, top);
getFrameSize(width, height);
const int16 right = left + width - 1;
switch (getAnimation()) {
case kAnimWalkLeft:
if (left <= 147)
setAnimation(kAnimWalkRight);
break;
case kAnimWalkRight:
if (right >= 290) {
setAnimation(kAnimJumpLeft);
setPosition(x, y - 14);
}
break;
case kAnimJumpLeft:
if (wasLastFrame) {
setAnimation(kAnimTapFoot);
setPosition(x, y - 10);
}
break;
case kAnimTapFoot:
if (wasLastFrame) {
setAnimation(kAnimJumpRight);
setPosition(x, y + 10);
}
break;
case kAnimJumpRight:
if (wasLastFrame) {
setAnimation(kAnimWalkLeft);
setPosition(x, y + 14);
}
break;
default:
break;
}
}
CharGenChild::Sound CharGenChild::shouldPlaySound() const {
const uint16 anim = getAnimation();
const uint16 frame = getFrame();
if (((anim == kAnimWalkLeft) || (anim == kAnimWalkRight)) && ((frame == 1) || (frame == 6)))
return kSoundWalk;
if (((anim == kAnimJumpLeft) || (anim == kAnimJumpRight)) && (frame == 0))
return kSoundJump;
return kSoundNone;
}
} // End of namespace OnceUpon
} // End of namespace Gob

View File

@@ -0,0 +1,65 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_ONCEUPON_CHARGENCHILD_H
#define GOB_PREGOB_ONCEUPON_CHARGENCHILD_H
#include "common/system.h"
#include "gob/aniobject.h"
namespace Gob {
class Surface;
class ANIFile;
namespace OnceUpon {
/** The child running around on the character generator screen. */
class CharGenChild : public ANIObject {
public:
enum Sound {
kSoundNone = 0,
kSoundWalk ,
kSoundJump
};
CharGenChild(const ANIFile &ani);
~CharGenChild() override;
/** Advance the animation to the next frame. */
void advance() override;
/** Should we play a sound right now? */
Sound shouldPlaySound() const;
};
} // End of namespace OnceUpon
} // End of namespace Gob
#endif // GOB_PREGOB_ONCEUPON_CHARGENCHILD_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,349 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_ONCEUPON_ONCEUPON_H
#define GOB_PREGOB_ONCEUPON_ONCEUPON_H
#include "common/system.h"
#include "common/str.h"
#include "gob/pregob/pregob.h"
#include "gob/pregob/onceupon/stork.h"
namespace Gob {
class Surface;
class Font;
class ANIObject;
namespace OnceUpon {
class OnceUpon : public PreGob {
public:
/** Number of languages we support. */
static const uint kLanguageCount = 5;
OnceUpon(GobEngine *vm);
~OnceUpon() override;
protected:
/** A description of a menu button. */
struct MenuButton {
bool needDraw; ///< Does the button need drawing?
int16 left; ///< Left coordinate of the button.
int16 top; ///< Top coordinate of the button.
int16 right; ///< Right coordinate of the button.
int16 bottom; ///< Bottom coordinate of the button.
int16 srcLeft; ///< Left coordinate of the button's sprite.
int16 srcTop; ///< Top coordinate of the button's sprite.
int16 srcRight; ///< Right coordinate of the button's sprite.
int16 srcBottom; ///< Right coordinate of the button's sprite.
int16 dstX; ///< Destination X coordinate of the button's sprite.
int16 dstY; ///< Destination Y coordinate of the button's sprite.
uint id; ///< The button's ID.
};
/** Parameters for the stork section. */
struct StorkParam {
const char *backdrop; ///< Backdrop image file.
uint houseCount; ///< Number of houses.
const MenuButton *houses; ///< House button definitions.
const Stork::BundleDrop *drops; ///< The bundle drop parameters.
};
void init();
void deinit();
/** Handle the copy protection.
*
* @param colors Colors the copy protection animals can be.
* @param shapes The shape that's the correct answer for each animal in each color.
* @param obfuscate Extra obfuscate table. correctShape = shapes[colors][obfuscate[animal]].
* @return true if the user guessed the correct shape, false otherwise.
*/
bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]);
/** Show the intro. */
void showIntro();
/** Handle the start menu.
*
* @param animalsButton Definition of the menu button that leads to the animal names screen. Can be 0.
* @param animalCount Number of animals in the animal names screen.
* @param animalButtons Definition of the buttons that make up the animals in the animal names screen.
* @param animalNames File prefixes for the name of each animal.
*/
void doStartMenu(const MenuButton *animalsButton, uint animalCount,
const MenuButton *animalButtons, const char * const *animalNames);
/** Play the game proper. */
void playGame();
/** Return the parameters for the stork section. */
virtual const StorkParam &getStorkParameters() const = 0;
private:
/** All actions a user can request in a menu. */
enum MenuAction {
kMenuActionNone = 0, ///< No action.
kMenuActionAnimals , ///< Do the animal names.
kMenuActionPlay , ///< Play the game.
kMenuActionRestart , ///< Restart the section.
kMenuActionMainMenu, ///< Go to the main menu.
kMenuActionQuit ///< Quit the game.
};
/** Difficulty levels. */
enum Difficulty {
kDifficultyBeginner = 0,
kDifficultyIntermediate = 1,
kDifficultyAdvanced = 2,
kDifficultyCount
};
/** The different sounds common in the game. */
enum Sound {
kSoundClick = 0,
kSoundStork ,
kSoundJump ,
kSoundCount
};
/** Action the character generation wants us to take. */
enum CharGenAction {
kCharGenDone = 0, ///< Created a character, move on.
kCharGenAbort , ///< Aborted the character generation.
kCharGenRestart ///< Restart the character generation.
};
/** A complete screen backup. */
struct ScreenBackup {
Surface *screen; ///< Screen contents.
int palette; ///< Screen palette.
bool changedCursor; ///< Did we change the cursor?
bool cursorVisible; ///< Was the cursor visible?
ScreenBackup();
~ScreenBackup();
};
/** The number of game sections. */
static const int kSectionCount = 15;
static const MenuButton kMainMenuDifficultyButton[]; ///< Difficulty buttons.
static const MenuButton kSectionButtons[]; ///< Section buttons.
static const MenuButton kIngameButtons[]; ///< Ingame menu buttons.
static const MenuButton kAnimalNamesBack; ///< "Back" button in the animal names screens.
static const MenuButton kLanguageButtons[]; ///< Language buttons in the animal names screen.
static const MenuButton kSectionStorkHouses[];
static const MenuButton kCharGenHeadButtons[];
static const MenuButton kCharGenHeads[];
static const MenuButton kCharGenHairButtons[];
static const MenuButton kCharGenJacketButtons[];
static const MenuButton kCharGenTrousersButtons[];
static const MenuButton kCharGenNameEntry[];
/** All general game sounds we know about. */
static const char *kSound[kSoundCount];
static const AnimProperties kClownAnimations[];
static const AnimProperties kTitleAnimation;
static const AnimProperties kSectionStorkAnimations[];
static const AnimProperties kSectionEndAnimations[];
/** Function pointer type for a section handler. */
typedef bool (OnceUpon::*SectionFunc)();
/** Section handler function. */
static const SectionFunc kSectionFuncs[kSectionCount];
/** Did we open the game archives? */
bool _openedArchives;
// Fonts
Font *_jeudak;
Font *_lettre;
Font *_plettre;
Font *_glettre;
/** The current palette. */
int _palette;
bool _quit; ///< Did the user request a normal game quit?
Difficulty _difficulty; ///< The current difficulty.
int _section; ///< The current game section.
Common::String _name; ///< The name of the child.
uint8 _house;
uint8 _head;
uint8 _colorHair;
uint8 _colorJacket;
uint8 _colorTrousers;
// -- General helpers --
void setGamePalette(uint palette); ///< Set a game palette.
void setGameCursor(); ///< Set the default game cursor.
/** Draw this sprite in a fancy, animated line-by-line way. */
void drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom,
int16 x, int16 y) const;
/** Backup the screen contents. */
void backupScreen(ScreenBackup &backup, bool setDefaultCursor = false);
/** Restore the screen contents with a previously made backup. */
void restoreScreen(ScreenBackup &backup);
Common::String fixString(const Common::String &str) const; ///< Fix a string if necessary.
void fixTXTStrings(TXTFile &txt) const override; ///< Fix all strings in a TXT.
// -- Copy protection helpers --
/** Set up the copy protection. */
int8 cpSetup(const uint8 colors[7], const uint8 shapes[7 * 20],
const uint8 obfuscate[4], const Surface sprites[2]);
/** Find the shape under these coordinates. */
int8 cpFindShape(int16 x, int16 y) const;
/** Display the "You are wrong" screen. */
void cpWrong();
// -- Show different game screens --
void showWait(uint palette = 0xFFFF); ///< Show the wait / loading screen.
void showQuote(); ///< Show the quote about fairytales.
void showTitle(); ///< Show the Once Upon A Time title.
void showChapter(int chapter); ///< Show a chapter intro text.
void showByeBye(); ///< Show the "bye bye" screen.
/** Handle the "listen to animal names" part. */
void handleAnimalNames(uint count, const MenuButton *buttons, const char * const *names);
// -- Menu helpers --
MenuAction handleStartMenu(const MenuButton *animalsButton); ///< Handle the start menu.
MenuAction handleMainMenu(); ///< Handle the main menu.
MenuAction handleIngameMenu(); ///< Handle the ingame menu.
void drawStartMenu(const MenuButton *animalsButton); ///< Draw the start menu.
void drawMainMenu(); ///< Draw the main menu.
void drawIngameMenu(); ///< Draw the ingame menu.
/** Draw the difficulty label. */
void drawMenuDifficulty();
/** Clear the ingame menu in an animated way. */
void clearIngameMenu(const Surface &background);
/** Handle the whole ingame menu. */
MenuAction doIngameMenu();
/** Handle the whole ingame menu if ESC or right mouse button was pressed. */
MenuAction doIngameMenu(int16 &key, MouseButtons &mouseButtons);
// -- Menu button helpers --
/** Find the button under these coordinates. */
int checkButton(const MenuButton *buttons, uint count, int16 x, int16 y, int failValue = -1) const;
/** Draw a menu button. */
void drawButton (Surface &dest, const Surface &src, const MenuButton &button, int transp = -1) const;
/** Draw multiple menu buttons. */
void drawButtons(Surface &dest, const Surface &src, const MenuButton *buttons, uint count, int transp = -1) const;
/** Draw a border around a button. */
void drawButtonBorder(const MenuButton &button, uint8 color);
// -- Animal names helpers --
/** Set up the animal chooser. */
void anSetupChooser();
/** Set up the language chooser for one animal. */
void anSetupNames(const MenuButton &animal);
/** Play / Display the name of an animal in one language. */
void anPlayAnimalName(const Common::String &animal, uint language);
// -- Game sections --
bool playSection();
bool sectionStork();
bool sectionChapter1();
bool sectionParents();
bool sectionChapter2();
bool sectionForest0();
bool sectionChapter3();
bool sectionEvilCastle();
bool sectionChapter4();
bool sectionForest1();
bool sectionChapter5();
bool sectionBossFight();
bool sectionChapter6();
bool sectionForest2();
bool sectionChapter7();
bool sectionEnd();
CharGenAction characterGenerator();
void charGenSetup(uint stage);
void charGenDrawName();
static bool enterString(Common::String &name, int16 key, uint maxLength, const Font &font);
};
} // End of namespace OnceUpon
} // End of namespace Gob
#endif // GOB_PREGOB_ONCEUPON_ONCEUPON_H

View File

@@ -0,0 +1,416 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_ONCEUPON_PALETTES_H
#define GOB_PREGOB_ONCEUPON_PALETTES_H
static const int kPaletteSize = 16;
static const uint kPaletteCount = 20;
static const byte kCopyProtectionPalette[3 * kPaletteSize] = {
0x00, 0x00, 0x00,
0x19, 0x00, 0x19,
0x00, 0x3F, 0x00,
0x00, 0x2A, 0x2A,
0x2A, 0x00, 0x00,
0x2A, 0x00, 0x2A,
0x2A, 0x15, 0x00,
0x00, 0x19, 0x12,
0x00, 0x00, 0x00,
0x15, 0x15, 0x3F,
0x15, 0x3F, 0x15,
0x00, 0x20, 0x3F,
0x3F, 0x00, 0x00,
0x3F, 0x00, 0x20,
0x3F, 0x3F, 0x00,
0x3F, 0x3F, 0x3F
};
static const byte kGamePalettes[kPaletteCount][3 * kPaletteSize] = {
{
0x00, 0x00, 0x00,
0x00, 0x00, 0x10,
0x00, 0x00, 0x18,
0x00, 0x00, 0x3C,
0x1C, 0x28, 0x00,
0x10, 0x18, 0x00,
0x1C, 0x1C, 0x20,
0x14, 0x14, 0x14,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x3C,
0x14, 0x20, 0x04,
0x3C, 0x2C, 0x00,
0x02, 0x00, 0x18,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x38, 0x20, 0x3C,
0x2C, 0x10, 0x30,
0x20, 0x08, 0x28,
0x14, 0x00, 0x1C,
0x20, 0x20, 0x38,
0x18, 0x18, 0x2C,
0x10, 0x10, 0x24,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x3C, 0x20, 0x20,
0x24, 0x14, 0x14,
0x1C, 0x10, 0x10,
0x14, 0x0C, 0x0C,
0x1C, 0x1C, 0x1C,
0x18, 0x18, 0x18,
0x10, 0x10, 0x10,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x10, 0x28, 0x1C,
0x10, 0x1C, 0x10,
0x10, 0x14, 0x0C,
0x1C, 0x1C, 0x3C,
0x24, 0x24, 0x3C,
0x18, 0x18, 0x24,
0x10, 0x10, 0x18,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x3F, 0x26, 0x3F,
0x36, 0x1C, 0x36,
0x2C, 0x12, 0x2A,
0x27, 0x0C, 0x24,
0x22, 0x07, 0x1E,
0x1D, 0x03, 0x18,
0x16, 0x00, 0x10,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x3A,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x3F, 0x39, 0x26,
0x38, 0x34, 0x1C,
0x30, 0x2F, 0x13,
0x27, 0x29, 0x0C,
0x1D, 0x22, 0x07,
0x14, 0x1B, 0x03,
0x0C, 0x14, 0x00,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x3A,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x24, 0x3C, 0x3C,
0x1C, 0x34, 0x38,
0x14, 0x2C, 0x30,
0x0C, 0x20, 0x2C,
0x08, 0x18, 0x28,
0x04, 0x10, 0x20,
0x00, 0x08, 0x1C,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x38,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x24,
0x38, 0x24, 0x1C,
0x30, 0x1C, 0x14,
0x28, 0x18, 0x0C,
0x20, 0x10, 0x04,
0x1C, 0x0C, 0x00,
0x14, 0x08, 0x00,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x38,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x3C, 0x34, 0x24,
0x38, 0x2C, 0x1C,
0x30, 0x24, 0x14,
0x2C, 0x1C, 0x10,
0x30, 0x30, 0x3C,
0x1C, 0x1C, 0x38,
0x0C, 0x0C, 0x38,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x00, 0x00, 0x0C,
0x02, 0x03, 0x14,
0x07, 0x07, 0x1D,
0x0E, 0x0E, 0x25,
0x17, 0x17, 0x2E,
0x21, 0x22, 0x36,
0x2F, 0x2F, 0x3F,
0x3F, 0x3F, 0x3F,
0x3F, 0x3B, 0x0D,
0x3A, 0x31, 0x0A,
0x35, 0x28, 0x07,
0x30, 0x21, 0x04,
0x2B, 0x19, 0x02,
0x26, 0x12, 0x01,
0x16, 0x0B, 0x00
},
{
0x00, 0x00, 0x00,
0x18, 0x00, 0x00,
0x21, 0x01, 0x00,
0x2A, 0x02, 0x00,
0x33, 0x03, 0x00,
0x3D, 0x06, 0x00,
0x2A, 0x19, 0x05,
0x15, 0x14, 0x14,
0x22, 0x1F, 0x1E,
0x2F, 0x2C, 0x28,
0x3F, 0x3C, 0x29,
0x3F, 0x38, 0x0B,
0x3B, 0x30, 0x0A,
0x37, 0x29, 0x08,
0x33, 0x23, 0x07,
0x2F, 0x1D, 0x06
},
{
0x00, 0x00, 0x00,
0x00, 0x1C, 0x38,
0x34, 0x30, 0x28,
0x2C, 0x24, 0x1C,
0x24, 0x18, 0x10,
0x1C, 0x10, 0x08,
0x14, 0x04, 0x04,
0x10, 0x00, 0x00,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x38,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x00, 0x1C, 0x38,
0x34, 0x30, 0x28,
0x2C, 0x24, 0x1C,
0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x38,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x1A, 0x30, 0x37,
0x14, 0x28, 0x31,
0x10, 0x20, 0x2C,
0x0C, 0x19, 0x27,
0x08, 0x12, 0x21,
0x05, 0x0C, 0x1C,
0x03, 0x07, 0x16,
0x01, 0x03, 0x11,
0x00, 0x00, 0x0C,
0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x34, 0x30, 0x34,
0x30, 0x24, 0x30,
0x28, 0x1C, 0x28,
0x24, 0x14, 0x24,
0x1C, 0x0C, 0x1C,
0x18, 0x08, 0x18,
0x14, 0x04, 0x14,
0x0C, 0x04, 0x0C,
0x08, 0x00, 0x08,
0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x2C, 0x24, 0x0C,
0x34, 0x34, 0x28,
0x2C, 0x2C, 0x1C,
0x24, 0x24, 0x10,
0x1C, 0x18, 0x08,
0x14, 0x14, 0x08,
0x10, 0x10, 0x04,
0x0C, 0x0C, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x38,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x14, 0x28, 0x31,
0x10, 0x20, 0x2C,
0x0C, 0x19, 0x27,
0x08, 0x12, 0x21,
0x05, 0x0C, 0x1C,
0x03, 0x07, 0x16,
0x01, 0x03, 0x11,
0x00, 0x3C, 0x00,
0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x10, 0x28, 0x1C,
0x10, 0x1C, 0x10,
0x10, 0x14, 0x0C,
0x1C, 0x1C, 0x3C,
0x24, 0x24, 0x3C,
0x18, 0x18, 0x24,
0x10, 0x10, 0x18,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
},
{
0x00, 0x00, 0x00,
0x10, 0x28, 0x1C,
0x10, 0x1C, 0x10,
0x10, 0x14, 0x0C,
0x1C, 0x1C, 0x3C,
0x24, 0x24, 0x3C,
0x18, 0x18, 0x24,
0x10, 0x10, 0x18,
0x14, 0x20, 0x04,
0x00, 0x00, 0x24,
0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00,
0x3C, 0x2C, 0x00,
0x3C, 0x18, 0x00,
0x3C, 0x04, 0x00,
0x1C, 0x00, 0x00
}
};
#endif // GOB_PREGOB_ONCEUPON_PALETTES_H

View File

@@ -0,0 +1,225 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#include "gob/gob.h"
#include "gob/global.h"
#include "gob/dataio.h"
#include "gob/palanim.h"
#include "gob/draw.h"
#include "gob/video.h"
#include "gob/sound/sound.h"
#include "gob/pregob/gctfile.h"
#include "gob/pregob/onceupon/palettes.h"
#include "gob/pregob/onceupon/parents.h"
namespace Gob {
namespace OnceUpon {
const char *Parents::kSound[kSoundCount] = {
"rire.snd", // kSoundCackle
"tonn.snd" // kSoundThunder
};
// So that every GCT line is displayed for 12 seconds
const uint16 Parents::kLoop[kLoopCount][3] = {
{ 72, 77, 33},
{105, 109, 38},
{141, 145, 38},
{446, 454, 23},
{456, 464, 23},
{466, 474, 23},
{476, 484, 23}
};
Parents::Parents(GobEngine *vm, const Common::String &seq, const Common::String &gct,
const Common::String &childName, uint8 house, const Font &font,
const byte *normalPalette, const byte *brightPalette, uint paletteSize) :
SEQFile(vm, seq),
_gct(nullptr), _house(house), _font(&font),
_paletteSize(paletteSize), _normalPalette(normalPalette), _brightPalette(brightPalette) {
// Load sounds
for (int i = 0; i < kSoundCount; i++)
_vm->_sound->sampleLoad(&_sounds[i], SOUND_SND, kSound[i]);
// Load GCT
Common::SeekableReadStream *gctStream = _vm->_dataIO->getFile(gct);
if (gctStream) {
_gct = new GCTFile(*gctStream, _vm->_rnd);
delete gctStream;
} else
error("Parents::Parents(): Failed to open \"%s\"", gct.c_str());
_gct->setArea(17, 18, 303, 41);
_gct->setText(1, childName);
_gct->selectLine(2, _house);
_gct->selectLine(4, _house);
for (uint i = 0; i < kLoopCount; i++)
_loopID[i] = addLoop(kLoop[i][0], kLoop[i][1], kLoop[i][2]);
}
Parents::~Parents() {
delete _gct;
}
void Parents::play() {
_currentLoop = 0;
SEQFile::play(true, 496, 15);
// After playback, fade out
if (!_vm->shouldQuit())
_vm->_palAnim->fade(nullptr, 0, 0);
}
void Parents::handleFrameEvent() {
switch (getFrame()) {
case 0:
// On fame 0, fade in
_vm->_draw->forceBlit();
_vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0);
break;
case 4:
drawGCT(0);
break;
case 55:
drawGCT(3, 0);
break;
case 79:
drawGCT(_house + 5, 1);
break;
case 110:
drawGCT(_house + 9, 2);
break;
case 146:
drawGCT(17);
break;
case 198:
drawGCT(13);
break;
case 445:
drawGCT(14, 3);
break;
case 455:
drawGCT(18, 4);
break;
case 465:
drawGCT(19, 5);
break;
case 475:
drawGCT(20, 6);
break;
case 188:
case 228:
case 237:
case 257:
case 275:
case 426:
lightningEffect();
break;
case 203:
case 243:
case 252:
case 272:
case 290:
case 441:
playSound(kSoundThunder);
break;
case 340:
playSound(kSoundCackle);
break;
default:
break;
}
}
void Parents::handleInput(int16 key, int16 mouseX, int16 mouseY, MouseButtons mouseButtons) {
if ((key == kKeyEscape) || (mouseButtons == kMouseButtonsRight))
abortPlay();
if (((key == kKeySpace) || (mouseButtons == kMouseButtonsLeft)) && (_currentLoop < kLoopCount))
skipLoop(_loopID[_currentLoop]);
}
void Parents::playSound(Sound sound) {
_vm->_sound->blasterStop(0);
_vm->_sound->blasterPlay(&_sounds[sound], 0, 0);
}
void Parents::lightningEffect() {
for (int i = 0; (i < 5) && !_vm->shouldQuit(); i++) {
setPalette(_brightPalette, _paletteSize);
_vm->_util->delay(5);
setPalette(_normalPalette, _paletteSize);
_vm->_util->delay(5);
}
}
void Parents::setPalette(const byte *palette, uint size) {
memcpy(_vm->_draw->_vgaPalette, palette, 3 * size);
_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
_vm->_video->retrace();
}
void Parents::drawGCT(uint item, uint loop) {
int16 left, top, right, bottom;
if (_gct->clear(*_vm->_draw->_backSurface, left, top, right, bottom))
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
if (_gct->draw(*_vm->_draw->_backSurface, item, *_font, 10, left, top, right, bottom))
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
_currentLoop = loop;
}
} // End of namespace OnceUpon
} // End of namespace Gob

View 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_ONCEUPON_PARENTS_H
#define GOB_PREGOB_ONCEUPON_PARENTS_H
#include "gob/sound/sounddesc.h"
#include "gob/pregob/seqfile.h"
namespace Gob {
class Font;
class GCTFile;
namespace OnceUpon {
/** The home / parents animation sequence. */
class Parents : public SEQFile {
public:
Parents(GobEngine *vm, const Common::String &seq, const Common::String &gct,
const Common::String &childName, uint8 house, const Font &font,
const byte *normalPalette, const byte *brightPalette, uint paletteSize);
~Parents() override;
void play();
protected:
void handleFrameEvent() override;
void handleInput(int16 key, int16 mouseX, int16 mouseY, MouseButtons mouseButtons) override;
private:
static const uint kLoopCount = 7;
static const uint16 kLoop[kLoopCount][3];
enum Sound {
kSoundCackle = 0,
kSoundThunder ,
kSoundCount
};
static const char *kSound[kSoundCount];
uint8 _house;
const Font *_font;
uint _paletteSize;
const byte *_normalPalette;
const byte *_brightPalette;
SoundDesc _sounds[kSoundCount];
GCTFile *_gct;
uint _loopID[kLoopCount];
uint _currentLoop;
void lightningEffect();
void playSound(Sound sound);
void setPalette(const byte *palette, uint size);
void drawGCT(uint item, uint loop = 0xFFFF);
};
} // End of namespace OnceUpon
} // End of namespace Gob
#endif // GOB_PREGOB_ONCEUPON_PARENTS_H

View File

@@ -0,0 +1,239 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#include "common/str.h"
#include "gob/gob.h"
#include "gob/surface.h"
#include "gob/anifile.h"
#include "gob/video.h"
#include "gob/pregob/onceupon/stork.h"
enum Animation {
kAnimFlyNearWithBundle = 9,
kAnimFlyFarWithBundle = 12,
kAnimFlyNearWithoutBundle = 10,
kAnimFlyFarWithoutBundle = 13,
kAnimBundleNear = 11,
kAnimBundleFar = 14
};
namespace Gob {
namespace OnceUpon {
Stork::Stork(GobEngine *vm, const ANIFile &ani) : ANIObject(ani), _shouldDrop(false) {
_frame = new Surface(320, 200, 1);
vm->_video->drawPackedSprite("cadre.cmp", *_frame);
_bundle = new ANIObject(ani);
_bundle->setVisible(false);
_bundle->setPause(true);
setState(kStateFlyNearWithBundle, kAnimFlyNearWithBundle, -80);
}
Stork::~Stork() {
delete _frame;
delete _bundle;
}
bool Stork::hasBundleLanded() const {
if (!_shouldDrop || !_bundle->isVisible() || _bundle->isPaused())
return false;
int16 x, y, width, height;
_bundle->getFramePosition(x, y);
_bundle->getFrameSize(width, height);
return (y + height) >= _bundleDrop.landY;
}
void Stork::dropBundle(const BundleDrop &drop) {
if (_shouldDrop)
return;
_shouldDrop = true;
_bundleDrop = drop;
}
bool Stork::draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) {
left = 0x7FFF;
top = 0x7FFF;
right = 0x0000;
bottom = 0x0000;
bool drawn = ANIObject::draw(dest, left, top, right, bottom);
if (drawn) {
// Left frame edge
if (left <= 15)
dest.blit(*_frame, left, top, MIN<int16>(15, right), bottom, left, top);
// Right frame edge
if (right >= 304)
dest.blit(*_frame, MAX<int16>(304, left), top, right, bottom, MAX<int16>(304, left), top);
}
int16 bLeft, bTop, bRight, bBottom;
if (_bundle->draw(dest, bLeft, bTop, bRight, bBottom)) {
// Bottom frame edge
if (bBottom >= 188)
dest.blit(*_frame, bLeft, MAX<int16>(188, bTop), bRight, bBottom, bLeft, MAX<int16>(188, bTop));
left = MIN(left , bLeft );
top = MIN(top , bTop );
right = MAX(right , bRight );
bottom = MAX(bottom, bBottom);
drawn = true;
}
return drawn;
}
bool Stork::clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) {
left = 0x7FFF;
top = 0x7FFF;
right = 0x0000;
bottom = 0x0000;
bool cleared = _bundle->clear(dest, left, top, right, bottom);
int16 sLeft, sTop, sRight, sBottom;
if (ANIObject::clear(dest, sLeft, sTop, sRight, sBottom)) {
left = MIN(left , sLeft );
top = MIN(top , sTop );
right = MAX(right , sRight );
bottom = MAX(bottom, sBottom);
cleared = true;
}
return cleared;
}
void Stork::advance() {
_bundle->advance();
ANIObject::advance();
int16 curX, curY, curWidth, curHeight;
getFramePosition(curX, curY, 0);
getFrameSize(curWidth, curHeight, 0);
const int16 curRight = curX + curWidth - 1;
int16 nextX, nextY, nextWidth, nextHeight;
getFramePosition(nextX, nextY, 1);
getFrameSize(nextWidth, nextHeight, 1);
const int16 nextRight = nextX + nextWidth - 1;
switch (_state) {
case kStateFlyNearWithBundle:
if (curX >= 330)
setState(kStateFlyFarWithBundle, kAnimFlyFarWithBundle, 330);
if ((curRight <= _bundleDrop.dropX) &&
(nextRight >= _bundleDrop.dropX) && _shouldDrop && !_bundleDrop.dropWhileFar)
dropBundle(kStateFlyNearWithoutBundle, kAnimFlyNearWithoutBundle);
break;
case kStateFlyFarWithBundle:
if (curX <= -80)
setState(kStateFlyNearWithBundle, kAnimFlyNearWithBundle, -80);
if ((curX >= _bundleDrop.dropX) &&
(nextX <= _bundleDrop.dropX) && _shouldDrop && _bundleDrop.dropWhileFar)
dropBundle(kStateFlyFarWithoutBundle, kAnimFlyFarWithoutBundle);
break;
case kStateFlyNearWithoutBundle:
if (curX >= 330)
setState(kStateFlyFarWithoutBundle, kAnimFlyFarWithoutBundle, 330);
break;
case kStateFlyFarWithoutBundle:
if (curX <= -80)
setState(kStateFlyNearWithoutBundle, kAnimFlyNearWithoutBundle, -80);
break;
default:
break;
}
}
void Stork::dropBundle(State state, uint16 anim) {
setState(state, anim);
int16 x, y, width, height;
getFramePosition(x, y);
getFrameSize(width, height);
_bundle->setAnimation(_bundleDrop.anim);
_bundle->setPause(false);
_bundle->setVisible(true);
int16 bWidth, bHeight;
_bundle->getFrameSize(bWidth, bHeight);
// Drop position
x = _bundleDrop.dropX;
y = y + height - bHeight;
// If the stork is flying near (from left to right), drop the bundle at the right edge
if (!_bundleDrop.dropWhileFar)
x = x - bWidth;
_bundle->setPosition(x, y);
}
void Stork::setState(State state, uint16 anim) {
setAnimation(anim);
setVisible(true);
setPause(false);
_state = state;
}
void Stork::setState(State state, uint16 anim, int16 x) {
setState(state, anim);
setPosition();
int16 pX, pY;
getPosition(pX, pY);
setPosition( x, pY);
}
} // End of namespace OnceUpon
} // End of namespace Gob

View 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_ONCEUPON_STORK_H
#define GOB_PREGOB_ONCEUPON_STORK_H
#include "common/system.h"
#include "gob/aniobject.h"
namespace Common {
class String;
}
namespace Gob {
class GobEngine;
class Surface;
class ANIFile;
namespace OnceUpon {
/** The stork in Baba Yaga / dragon in Abracadabra. */
class Stork : public ANIObject {
public:
/** Information on how to drop the bundle. */
struct BundleDrop {
int16 anim; ///< Animation of the bundle floating down
int16 dropX; ///< X position the stork drops the bundle
int16 landY; ///< Y position the bundle lands
bool dropWhileFar; ///< Does the stork drop the bundle while far instead of near?
};
Stork(GobEngine *vm, const ANIFile &ani);
~Stork() override;
/** Has the bundle landed? */
bool hasBundleLanded() const;
/** Drop the bundle. */
void dropBundle(const BundleDrop &drop);
/** Draw the current frame onto the surface and return the affected rectangle. */
bool draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) override;
/** Draw the current frame from the surface and return the affected rectangle. */
bool clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) override;
/** Advance the animation to the next frame. */
void advance() override;
private:
enum State {
kStateFlyNearWithBundle = 0,
kStateFlyFarWithBundle ,
kStateFlyNearWithoutBundle ,
kStateFlyFarWithoutBundle
};
Surface *_frame;
ANIObject *_bundle;
State _state;
bool _shouldDrop;
BundleDrop _bundleDrop;
void setState(State state, uint16 anim);
void setState(State state, uint16 anim, int16 x);
void dropBundle(State state, uint16 anim);
};
} // End of namespace OnceUpon
} // End of namespace Gob
#endif // GOB_PREGOB_ONCEUPON_STORK_H

View 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#include "gob/gob.h"
#include "gob/global.h"
#include "gob/palanim.h"
#include "gob/draw.h"
#include "gob/sound/sound.h"
#include "gob/pregob/onceupon/title.h"
namespace Gob {
namespace OnceUpon {
Title::Title(GobEngine *vm) : SEQFile(vm, "ville.seq") {
}
Title::~Title() {
}
void Title::play() {
SEQFile::play(true, 0xFFFF, 15);
// After playback, fade out and stop the music
if (!_vm->shouldQuit())
_vm->_palAnim->fade(nullptr, 0, 0);
stopMusic();
}
void Title::handleFrameEvent() {
// On fame 0, start the music and fade in
if (getFrame() == 0) {
playMusic();
_vm->_draw->forceBlit();
_vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0);
}
}
void Title::playMusic() {
// Look at what platform this is and play the appropriate music type
if (_vm->getPlatform() == Common::kPlatformDOS)
playMusicDOS();
else if (_vm->getPlatform() == Common::kPlatformAmiga)
playMusicAmiga();
else if (_vm->getPlatform() == Common::kPlatformAtariST)
playMusicAtariST();
}
void Title::playMusicDOS() {
// Play an AdLib track
_vm->_sound->adlibLoadTBR("babayaga.tbr");
_vm->_sound->adlibLoadMDY("babayaga.mdy");
_vm->_sound->adlibSetRepeating(-1);
_vm->_sound->adlibPlay();
}
void Title::playMusicAmiga() {
// Play a Protracker track
_vm->_sound->protrackerPlay("mod.babayaga");
}
void Title::playMusicAtariST() {
// Play a Soundblaster composition
static const int16 titleMusic[21] = { 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, -1};
static const char * const titleFiles[ 3] = {"baba1.snd", "baba2.snd", "baba3.snd"};
for (uint i = 0; i < ARRAYSIZE(titleFiles); i++)
_vm->_sound->sampleLoad(_vm->_sound->sampleGetBySlot(i), SOUND_SND, titleFiles[i]);
_vm->_sound->blasterPlayComposition(titleMusic, 0);
_vm->_sound->blasterRepeatComposition(-1);
}
void Title::stopMusic() {
// Just stop everything
_vm->_sound->adlibSetRepeating(0);
_vm->_sound->blasterRepeatComposition(0);
_vm->_sound->adlibStop();
_vm->_sound->blasterStopComposition();
_vm->_sound->protrackerStop();
for (int i = 0; i < ::Gob::Sound::kSoundsCount; i++)
_vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(i));
}
} // End of namespace OnceUpon
} // End of namespace Gob

View File

@@ -0,0 +1,60 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_ONCEUPON_TITLE_H
#define GOB_PREGOB_ONCEUPON_TITLE_H
#include "gob/pregob/seqfile.h"
namespace Gob {
namespace OnceUpon {
/** The Once Upon A Time title animation sequence. */
class Title : public SEQFile {
public:
Title(GobEngine *vm);
~Title() override;
void play();
protected:
void handleFrameEvent() override;
private:
void playMusic(); ///< Play the title music.
void playMusicDOS(); ///< Play the title music of the DOS version.
void playMusicAmiga(); ///< Play the title music of the Amiga version.
void playMusicAtariST(); ///< Play the title music of the Atari ST version.
void stopMusic(); ///< Stop the title music.
};
} // End of namespace OnceUpon
} // End of namespace Gob
#endif // GOB_PREGOB_ONCEUPON_TITLE_H

View File

@@ -0,0 +1,356 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#include "graphics/cursorman.h"
#include "gob/gob.h"
#include "gob/global.h"
#include "gob/util.h"
#include "gob/surface.h"
#include "gob/dataio.h"
#include "gob/palanim.h"
#include "gob/draw.h"
#include "gob/video.h"
#include "gob/aniobject.h"
#include "gob/sound/sound.h"
#include "gob/pregob/pregob.h"
#include "gob/pregob/gctfile.h"
namespace Gob {
const char PreGob::kLanguageSuffixShort[5] = { 't', 'g', 'a', 'e', 'i'};
const char *PreGob::kLanguageSuffixLong [5] = {"fr", "al", "an", "it", "es"};
PreGob::PreGob(GobEngine *vm) : _vm(vm), _fadedOut(false) {
}
PreGob::~PreGob() {
}
void PreGob::fadeOut() {
if (_fadedOut || _vm->shouldQuit())
return;
// Fade to black
_vm->_palAnim->fade(nullptr, 0, 0);
_fadedOut = true;
}
void PreGob::fadeIn() {
if (!_fadedOut || _vm->shouldQuit())
return;
// Fade to palette
_vm->_draw->blitInvalidated();
_vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0);
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199);
_fadedOut = false;
}
void PreGob::clearScreen() {
_vm->_draw->_backSurface->clear();
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199);
_vm->_draw->blitInvalidated();
_vm->_video->retrace();
}
void PreGob::initScreen() {
_vm->_util->setFrameRate(15);
_fadedOut = true;
_vm->_draw->initScreen();
_vm->_draw->_backSurface->clear();
_vm->_util->clearPalette();
_vm->_draw->forceBlit();
_vm->_video->retrace();
_vm->_util->processInput();
}
void PreGob::setPalette(const byte *palette, uint16 size) {
memcpy(_vm->_draw->_vgaPalette, palette, 3 * size);
// If we didn't fade out prior, immediately set the palette
if (!_fadedOut)
_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
}
void PreGob::addCursor() {
CursorMan.pushCursor(nullptr, 0, 0, 0, 0, 0);
}
void PreGob::removeCursor() {
CursorMan.popCursor();
}
void PreGob::setCursor(Surface &sprite, int16 hotspotX, int16 hotspotY) {
CursorMan.replaceCursor(sprite.getData(), sprite.getWidth(), sprite.getHeight(), hotspotX, hotspotY, 0);
}
void PreGob::setCursor(Surface &sprite, int16 left, int16 top, int16 right, int16 bottom,
int16 hotspotX, int16 hotspotY) {
const int width = right - left + 1;
const int height = bottom - top + 1;
if ((width <= 0) || (height <= 0))
return;
Surface cursor(width, height, 1);
cursor.blit(sprite, left, top, right, bottom, 0, 0);
setCursor(cursor, hotspotX, hotspotX);
}
void PreGob::showCursor() {
CursorMan.showMouse(true);
_vm->_draw->_showCursor = 4;
}
void PreGob::hideCursor() {
CursorMan.showMouse(false);
_vm->_draw->_showCursor = 0;
}
bool PreGob::isCursorVisible() const {
return CursorMan.isVisible();
}
void PreGob::loadSounds(const char * const *sounds, uint soundCount) {
freeSounds();
_sounds.resize(soundCount);
for (uint i = 0; i < soundCount; i++)
loadSound(_sounds[i], sounds[i]);
}
void PreGob::freeSounds() {
_sounds.clear();
}
bool PreGob::loadSound(SoundDesc &sound, const Common::String &file) const {
return _vm->_sound->sampleLoad(&sound, SOUND_SND, file.c_str());
}
void PreGob::playSound(uint sound, int16 frequency, int16 repCount) {
if (sound >= _sounds.size())
return;
_vm->_sound->blasterPlay(&_sounds[sound], repCount, frequency);
}
void PreGob::stopSound() {
_vm->_sound->blasterStop(0);
}
void PreGob::playSoundFile(const Common::String &file, int16 frequency, int16 repCount, bool interruptible) {
stopSound();
SoundDesc sound;
if (!loadSound(sound, file))
return;
_vm->_sound->blasterPlay(&sound, repCount, frequency);
_vm->_util->forceMouseUp();
bool finished = false;
while (!_vm->shouldQuit() && !finished && _vm->_sound->blasterPlayingSound()) {
endFrame(true);
finished = hasInput();
}
_vm->_util->forceMouseUp();
stopSound();
}
void PreGob::beep(int16 frequency, int32 length) {
_vm->_sound->speakerOn(frequency, length);
}
void PreGob::endFrame(bool doInput) {
_vm->_draw->blitInvalidated();
_vm->_util->waitEndFrame();
if (doInput)
_vm->_util->processInput();
}
int16 PreGob::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) {
_vm->_util->getMouseState(&mouseX, &mouseY, &mouseButtons);
_vm->_util->forceMouseUp();
return _vm->_util->checkKey();
}
int16 PreGob::waitInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) {
bool finished = false;
int16 key = 0;
while (!_vm->shouldQuit() && !finished) {
endFrame(true);
key = checkInput(mouseX, mouseY, mouseButtons);
finished = (mouseButtons != kMouseButtonsNone) || (key != 0);
}
return key;
}
int16 PreGob::waitInput() {
int16 mouseX, mouseY;
MouseButtons mouseButtons;
return waitInput(mouseX, mouseY, mouseButtons);
}
bool PreGob::hasInput() {
int16 mouseX, mouseY;
MouseButtons mouseButtons;
return checkInput(mouseX, mouseY, mouseButtons) || (mouseButtons != kMouseButtonsNone);
}
void PreGob::clearAnim(ANIObject &anim) {
int16 left, top, right, bottom;
if (anim.clear(*_vm->_draw->_backSurface, left, top, right, bottom))
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
}
void PreGob::drawAnim(ANIObject &anim) {
int16 left, top, right, bottom;
if (anim.draw(*_vm->_draw->_backSurface, left, top, right, bottom))
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
anim.advance();
}
void PreGob::redrawAnim(ANIObject &anim) {
clearAnim(anim);
drawAnim(anim);
}
void PreGob::clearAnim(const ANIList &anims) {
for (int i = (anims.size() - 1); i >= 0; i--)
clearAnim(*anims[i]);
}
void PreGob::drawAnim(const ANIList &anims) {
for (ANIList::const_iterator a = anims.begin(); a != anims.end(); ++a)
drawAnim(**a);
}
void PreGob::redrawAnim(const ANIList &anims) {
clearAnim(anims);
drawAnim(anims);
}
void PreGob::loadAnims(ANIList &anims, ANIFile &ani, uint count, const AnimProperties *props) const {
freeAnims(anims);
anims.resize(count);
for (uint i = 0; i < count; i++) {
anims[i] = new ANIObject(ani);
setAnim(*anims[i], props[i]);
}
}
void PreGob::freeAnims(ANIList &anims) const {
for (ANIList::iterator a = anims.begin(); a != anims.end(); ++a)
delete *a;
anims.clear();
}
void PreGob::setAnim(ANIObject &anim, const AnimProperties &props) const {
anim.setAnimation(props.animation);
anim.setFrame(props.frame);
anim.setMode(props.mode);
anim.setPause(props.paused);
anim.setVisible(props.visible);
if (props.hasPosition)
anim.setPosition(props.x, props.y);
else
anim.setPosition();
}
Common::String PreGob::getLocFile(const Common::String &file) const {
if (_vm->_global->_language >= ARRAYSIZE(kLanguageSuffixShort))
return file;
return file + kLanguageSuffixShort[_vm->_global->_language];
}
TXTFile *PreGob::loadTXT(const Common::String &txtFile, TXTFile::Format format) const {
Common::SeekableReadStream *txtStream = _vm->_dataIO->getFile(txtFile);
if (!txtStream)
error("PreGob::loadTXT(): Failed to open \"%s\"", txtFile.c_str());
TXTFile *txt = new TXTFile(*txtStream, format);
delete txtStream;
fixTXTStrings(*txt);
return txt;
}
void PreGob::fixTXTStrings(TXTFile &txt) const {
}
GCTFile *PreGob::loadGCT(const Common::String &gctFile) const {
Common::SeekableReadStream *gctStream = _vm->_dataIO->getFile(gctFile);
if (!gctStream)
error("PreGob::loadGCT(): Failed to open \"%s\"", gctFile.c_str());
GCTFile *gct = new GCTFile(*gctStream, _vm->_rnd);
delete gctStream;
return gct;
}
} // End of namespace Gob

199
engines/gob/pregob/pregob.h Normal file
View File

@@ -0,0 +1,199 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_PREGOB_H
#define GOB_PREGOB_PREGOB_H
#include "common/str.h"
#include "common/array.h"
#include "gob/util.h"
#include "gob/aniobject.h"
#include "gob/pregob/txtfile.h"
namespace Gob {
class GobEngine;
class ANIFile;
class Surface;
class SoundDesc;
class GCTFile;
class PreGob {
public:
PreGob(GobEngine *vm);
virtual ~PreGob();
virtual void run() = 0;
struct AnimProperties {
uint16 animation;
uint16 frame;
ANIObject::Mode mode;
bool visible;
bool paused;
bool hasPosition;
int16 x;
int16 y;
};
protected:
typedef Common::Array<ANIObject *> ANIList;
static const char kLanguageSuffixShort[5];
static const char *kLanguageSuffixLong [5];
GobEngine *_vm;
// -- Graphics --
/** Initialize the game screen. */
void initScreen();
void fadeOut(); ///< Fade to black.
void fadeIn(); ///< Fade to the current palette.
void clearScreen();
/** Change the palette.
*
* @param palette The palette to change to.
* @param size Size of the palette in colors.
*/
void setPalette(const byte *palette, uint16 size); ///< Change the palette
/** Add a new cursor that can be manipulated to the stack. */
void addCursor();
/** Remove the top-most cursor from the stack. */
void removeCursor();
/** Set the current cursor. */
void setCursor(Surface &sprite, int16 hotspotX, int16 hotspotY);
/** Set the current cursor. */
void setCursor(Surface &sprite, int16 left, int16 top, int16 right, int16 bottom,
int16 hotspotX, int16 hotspotY);
/** Show the cursor. */
void showCursor();
/** Hide the cursor. */
void hideCursor();
/** Is the cursor currently visible? */
bool isCursorVisible() const;
/** Remove an animation from the screen. */
void clearAnim(ANIObject &anim);
/** Draw an animation to the screen, advancing it. */
void drawAnim(ANIObject &anim);
/** Clear and draw an animation to the screen, advancing it. */
void redrawAnim(ANIObject &anim);
/** Remove animations from the screen. */
void clearAnim(const ANIList &anims);
/** Draw animations to the screen, advancing them. */
void drawAnim(const ANIList &anims);
/** Clear and draw animations to the screen, advancing them. */
void redrawAnim(const ANIList &anims);
void loadAnims(ANIList &anims, ANIFile &ani, uint count, const AnimProperties *props) const;
void freeAnims(ANIList &anims) const;
void setAnim(ANIObject &anim, const AnimProperties &props) const;
/** Wait for the frame to end, handling screen updates and optionally update input. */
void endFrame(bool doInput);
// -- Sound --
/** Load all sounds that can be played interactively in the game. */
void loadSounds(const char * const *sounds, uint soundCount);
/** Free all loaded sound. */
void freeSounds();
/** Play a loaded sound. */
void playSound(uint sound, int16 frequency = 0, int16 repCount = 0);
/** Stop all sound playback. */
void stopSound();
/** Play a sound until it ends or is interrupted by a keypress. */
void playSoundFile(const Common::String &file, int16 frequency = 0, int16 repCount = 0, bool interruptible = true);
/** Beep the PC speaker. */
void beep(int16 frequency, int32 length);
// -- Input --
/** Check mouse and keyboard input. */
int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons);
/** Wait for mouse or keyboard input. */
int16 waitInput (int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons);
/** Wait for mouse or keyboard input, but don't care about what was done with the mouse. */
int16 waitInput();
/** Did we have mouse or keyboard input? */
bool hasInput();
// -- TXT helpers --
/** Get the name of a localized file. */
Common::String getLocFile(const Common::String &file) const;
/** Open a TXT file. */
TXTFile *loadTXT(const Common::String &txtFile, TXTFile::Format format) const;
/** Called by loadTXT() to fix strings within the TXT file. */
virtual void fixTXTStrings(TXTFile &txt) const;
// -- GCT helpers --
GCTFile *loadGCT(const Common::String &gctFile) const;
private:
/** Did we fade out? */
bool _fadedOut;
/** All loaded sounds. */
Common::Array<SoundDesc> _sounds;
/** Load a sound file. */
bool loadSound(SoundDesc &sound, const Common::String &file) const;
};
} // End of namespace Gob
#endif // GOB_PREGOB_PREGOB_H

View File

@@ -0,0 +1,389 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#include "common/str.h"
#include "common/stream.h"
#include "gob/gob.h"
#include "gob/dataio.h"
#include "gob/draw.h"
#include "gob/decfile.h"
#include "gob/anifile.h"
#include "gob/aniobject.h"
#include "gob/pregob/seqfile.h"
namespace Gob {
SEQFile::SEQFile(GobEngine *vm, const Common::String &fileName) : _vm(vm) {
for (uint i = 0; i < kObjectCount; i++)
_objects[i].object = nullptr;
Common::SeekableReadStream *seq = _vm->_dataIO->getFile(Util::setExtension(fileName, ".SEQ"));
if (!seq) {
warning("SEQFile::SEQFile(): No such file \"%s\"", fileName.c_str());
return;
}
load(*seq);
delete seq;
}
SEQFile::~SEQFile() {
for (uint i = 0; i < kObjectCount; i++)
delete _objects[i].object;
for (Backgrounds::iterator b = _backgrounds.begin(); b != _backgrounds.end(); ++b)
delete *b;
for (Animations::iterator a = _animations.begin(); a != _animations.end(); ++a)
delete *a;
}
void SEQFile::load(Common::SeekableReadStream &seq) {
const uint16 decCount = (uint16)seq.readByte() + 1;
const uint16 aniCount = (uint16)seq.readByte() + 1;
// Load backgrounds
_backgrounds.reserve(decCount);
for (uint i = 0; i < decCount; i++) {
const Common::String dec = Util::readString(seq, 13);
if (!_vm->_dataIO->hasFile(dec)) {
warning("SEQFile::load(): No such background \"%s\"", dec.c_str());
return;
}
_backgrounds.push_back(new DECFile(_vm, dec, 320, 200));
}
// Load animations
_animations.reserve(aniCount);
for (uint i = 0; i < aniCount; i++) {
const Common::String ani = Util::readString(seq, 13);
if (!_vm->_dataIO->hasFile(ani)) {
warning("SEQFile::load(): No such animation \"%s\"", ani.c_str());
return;
}
_animations.push_back(new ANIFile(_vm, ani));
}
_frameRate = seq.readUint16LE();
// Load background change keys
const uint16 bgKeyCount = seq.readUint16LE();
_bgKeys.resize(bgKeyCount);
for (uint16 i = 0; i < bgKeyCount; i++) {
const uint16 frame = seq.readUint16LE();
const uint16 index = seq.readUint16LE();
_bgKeys[i].frame = frame;
_bgKeys[i].background = index < _backgrounds.size() ? _backgrounds[index] : 0;
}
// Load animation keys for all 4 objects
for (uint i = 0; i < kObjectCount; i++) {
const uint16 animKeyCount = seq.readUint16LE();
_animKeys.reserve(_animKeys.size() + animKeyCount);
for (uint16 j = 0; j < animKeyCount; j++) {
_animKeys.push_back(AnimationKey());
const uint16 frame = seq.readUint16LE();
const uint16 index = seq.readUint16LE();
uint16 animation;
const ANIFile *ani = findANI(index, animation);
_animKeys.back().object = i;
_animKeys.back().frame = frame;
_animKeys.back().ani = ani;
_animKeys.back().animation = animation;
_animKeys.back().x = seq.readSint16LE();
_animKeys.back().y = seq.readSint16LE();
_animKeys.back().order = seq.readSint16LE();
}
}
}
const ANIFile *SEQFile::findANI(uint16 index, uint16 &animation) {
animation = 0xFFFF;
// 0xFFFF = remove animation
if (index == 0xFFFF)
return nullptr;
for (const auto &anim : _animations) {
if (index < anim->getAnimationCount()) {
animation = index;
return anim;
}
index -= anim->getAnimationCount();
}
return nullptr;
}
void SEQFile::play(bool abortable, uint16 endFrame, uint16 frameRate) {
if (_bgKeys.empty() && _animKeys.empty())
// Nothing to do
return;
// Init
_frame = 0;
_abortPlay = false;
for (uint i = 0; i < kObjectCount; i++) {
delete _objects[i].object;
_objects[i].object = nullptr;
_objects[i].order = 0;
}
for (Loops::iterator l = _loops.begin(); l != _loops.end(); ++l)
l->currentLoop = 0;
// Set the frame rate
int16 frameRateBack = _vm->_util->getFrameRate();
if (frameRate == 0)
frameRate = _frameRate;
_vm->_util->setFrameRate(frameRate);
_abortable = abortable;
while (!_vm->shouldQuit() && !_abortPlay) {
// Handle the frame contents
playFrame();
// Handle extra frame events
handleFrameEvent();
// Wait for the frame to end
_vm->_draw->blitInvalidated();
_vm->_util->waitEndFrame();
// Handle input
_vm->_util->processInput();
int16 key = _vm->_util->checkKey();
int16 mouseX, mouseY;
MouseButtons mouseButtons;
_vm->_util->getMouseState(&mouseX, &mouseY, &mouseButtons);
_vm->_util->forceMouseUp();
handleInput(key, mouseX, mouseY, mouseButtons);
// Loop
bool looped = false;
for (auto &loop : _loops) {
if ((loop.endFrame == _frame) && (loop.currentLoop < loop.loopCount)) {
_frame = loop.startFrame;
loop.currentLoop++;
looped = true;
}
}
// If we didn't loop, advance the frame and look if we should end here
if (!looped) {
_frame++;
if (_frame >= endFrame)
break;
}
}
// Restore the frame rate
_vm->_util->setFrameRate(frameRateBack);
}
void SEQFile::playFrame() {
// Remove the current animation frames
clearAnims();
// Handle background keys, directly updating the background
for (const auto &bg : _bgKeys) {
if (!bg.background || (bg.frame != _frame))
continue;
bg.background->draw(*_vm->_draw->_backSurface);
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199);
}
// Handle the animation keys, updating the objects
for (const auto &anim : _animKeys) {
if (anim.frame != _frame)
continue;
Object &object = _objects[anim.object];
delete object.object;
object.object = nullptr;
// No valid animation => remove
if ((anim.animation == 0xFFFF) || !anim.ani)
continue;
// Change the animation
object.object = new ANIObject(*anim.ani);
object.object->setAnimation(anim.animation);
object.object->setPosition(anim.x, anim.y);
object.object->setVisible(true);
object.object->setPause(false);
object.order = anim.order;
}
// Draw the animations
drawAnims();
}
// NOTE: This is really not at all efficient. However, since there's only a
// small number of objects, it should matter. We really do need a stable
// sort, though, so Common::sort() is out.
SEQFile::Objects SEQFile::getOrderedObjects() {
int16 minOrder = (int16)0x7FFF;
int16 maxOrder = (int16)0x8000;
Objects objects;
// Find the span of order values
for (uint i = 0; i < kObjectCount; i++) {
if (!_objects[i].object)
continue;
minOrder = MIN(minOrder, _objects[i].order);
maxOrder = MAX(maxOrder, _objects[i].order);
}
// Stably sort the objects by order value
for (int16 o = minOrder; o <= maxOrder; o++)
for (uint i = 0; i < kObjectCount; i++)
if (_objects[i].object && (_objects[i].order == o))
objects.push_back(_objects[i]);
return objects;
}
void SEQFile::clearAnims() {
Objects objects = getOrderedObjects();
// Remove the animation frames, in reverse drawing order
for (Objects::iterator o = objects.reverse_begin(); o != objects.end(); --o) {
int16 left, top, right, bottom;
if (o->object->clear(*_vm->_draw->_backSurface, left, top, right, bottom))
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
}
}
void SEQFile::drawAnims() {
Objects objects = getOrderedObjects();
// Draw the animation frames and advance the animation
for (auto &obj : objects) {
int16 left, top, right, bottom;
if (obj.object->draw(*_vm->_draw->_backSurface, left, top, right, bottom))
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
obj.object->advance();
}
}
uint16 SEQFile::getFrame() const {
return _frame;
}
void SEQFile::seekFrame(uint16 frame) {
_frame = frame;
}
uint SEQFile::addLoop(uint16 startFrame, uint16 endFrame, uint16 loopCount) {
_loops.resize(_loops.size() + 1);
_loops.back().startFrame = startFrame;
_loops.back().endFrame = endFrame;
_loops.back().loopCount = loopCount;
_loops.back().currentLoop = 0;
_loops.back().empty = false;
return _loops.size() - 1;
}
void SEQFile::skipLoop(uint loopID) {
if (loopID >= _loops.size())
return;
_loops[loopID].currentLoop = 0xFFFF;
}
void SEQFile::delLoop(uint loopID) {
if (loopID >= _loops.size())
return;
_loops[loopID].empty = true;
cleanLoops();
}
void SEQFile::cleanLoops() {
while (!_loops.empty() && _loops.back().empty)
_loops.pop_back();
}
void SEQFile::abortPlay() {
_abortPlay = true;
}
void SEQFile::handleFrameEvent() {
}
void SEQFile::handleInput(int16 key, int16 mouseX, int16 mouseY, MouseButtons mouseButtons) {
if (_abortable && ((key != 0) || (mouseButtons != kMouseButtonsNone)))
abortPlay();
}
} // End of namespace Gob

View File

@@ -0,0 +1,198 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_SEQFILE_H
#define GOB_PREGOB_SEQFILE_H
#include "common/system.h"
#include "common/array.h"
#include "common/list.h"
#include "gob/util.h"
namespace Common {
class String;
class SeekableReadStream;
}
namespace Gob {
class GobEngine;
class DECFile;
class ANIFile;
class ANIObject;
/** A SEQ file, describing a complex animation sequence.
*
* Used in early hardcoded gob games.
* The principle is similar to the Mult class (see mult.h), but instead
* of depending on all the externally loaded animations, backgrounds and
* objects, a SEQ file references animation and background directly by
* filename.
*/
class SEQFile {
public:
SEQFile(GobEngine *vm, const Common::String &fileName);
virtual ~SEQFile();
/** Play the SEQ.
*
* @param abortable If true, end playback on any user input.
* @param endFrame The frame on where to end, or 0xFFFF for infinite playback.
* @param frameRate The frame rate at which to play the SEQ, or 0 for playing at
* the speed the SEQ itself wants to.
*/
void play(bool abortable = true, uint16 endFrame = 0xFFFF, uint16 frameRate = 0);
protected:
GobEngine *_vm;
/** Returns the current frame number. */
uint16 getFrame() const;
/** Seek to a specific frame. */
void seekFrame(uint16 frame);
/** Add a frame loop. */
uint addLoop(uint16 startFrame, uint16 endFrame, uint16 loopCount);
/** Skip a frame loop. */
void skipLoop(uint loopID);
/** Delete a frame loop. */
void delLoop(uint loopID);
/** Ends SEQ playback. */
void abortPlay();
/** Callback for special frame events. */
virtual void handleFrameEvent();
/** Callback for special user input handling. */
virtual void handleInput(int16 key, int16 mouseX, int16 mouseY, MouseButtons mouseButtons);
private:
/** Number of animation objects that are visible at the same time. */
static const uint kObjectCount = 4;
/** A key for changing the background. */
struct BackgroundKey {
uint16 frame; ///< Frame the change is to happen.
const DECFile *background; ///< The background to use.
};
/** A key for playing an object animation. */
struct AnimationKey {
uint object; ///< The object this key belongs to.
uint16 frame; ///< Frame the change is to happen.
const ANIFile *ani; ///< The ANI to use.
uint16 animation; ///< The animation to use.
int16 x; ///< X position of the animation.
int16 y; ///< Y position of the animation.
int16 order; ///< Used to determine in which order to draw the objects.
};
/** A managed animation object. */
struct Object {
ANIObject *object; ///< The actual animation object.
int16 order; ///< The current drawing order.
};
/** A frame loop. */
struct Loop {
uint16 startFrame;
uint16 endFrame;
uint16 loopCount;
uint16 currentLoop;
bool empty;
};
typedef Common::Array<DECFile *> Backgrounds;
typedef Common::Array<ANIFile *> Animations;
typedef Common::Array<BackgroundKey> BackgroundKeys;
typedef Common::Array<AnimationKey> AnimationKeys;
typedef Common::List<Object> Objects;
typedef Common::Array<Loop> Loops;
uint16 _frame; ///< The current frame.
bool _abortPlay; ///< Was the end of the playback requested?
uint16 _frameRate;
Backgrounds _backgrounds; ///< All backgrounds in this SEQ.
Animations _animations; ///< All animations in this SEQ.
BackgroundKeys _bgKeys; ///< The background change keyframes.
AnimationKeys _animKeys; ///< The animation change keyframes.
Object _objects[kObjectCount]; ///< The managed animation objects.
Loops _loops;
/** Whether the playback should be abortable by user input. */
bool _abortable;
// -- Loading helpers --
void load(Common::SeekableReadStream &seq);
const ANIFile *findANI(uint16 index, uint16 &animation);
// -- Playback helpers --
void playFrame();
/** Get a list of objects ordered by drawing order. */
Objects getOrderedObjects();
void clearAnims(); ///< Remove all animation frames.
void drawAnims(); ///< Draw the animation frames.
/** Look if we can compact the loop array. */
void cleanLoops();
};
} // End of namespace Gob
#endif // GOB_PREGOB_SEQFILE_H

View File

@@ -0,0 +1,237 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#include "common/stream.h"
#include "gob/draw.h"
#include "gob/pregob/txtfile.h"
namespace Gob {
TXTFile::TXTFile(Common::SeekableReadStream &txt, Format format) {
load(txt, format);
}
TXTFile::~TXTFile() {
}
TXTFile::LineArray &TXTFile::getLines() {
return _lines;
}
void TXTFile::load(Common::SeekableReadStream &txt, Format format) {
if (format == kFormatStringPositionColorFont) {
int numLines = getInt(txt);
_lines.reserve(numLines);
}
while (!txt.eos()) {
Line line;
line.text = getStr(txt);
line.x = (format >= kFormatStringPosition) ? getInt(txt) : 0;
line.y = (format >= kFormatStringPosition) ? getInt(txt) : 0;
line.color = (format >= kFormatStringPositionColor) ? getInt(txt) : 0;
line.font = (format >= kFormatStringPositionColorFont) ? getInt(txt) : 0;
_lines.push_back(line);
}
while (!_lines.empty() && _lines.back().text.empty())
_lines.pop_back();
}
bool TXTFile::draw(Surface &surface, int16 &left, int16 &top, int16 &right, int16 &bottom,
const Font * const *fonts, uint fontCount, int color) {
trashBuffer();
if (!getArea(left, top, right, bottom, fonts, fontCount))
return false;
resizeBuffer(right - left + 1, bottom - top + 1);
saveScreen(surface, left, top, right, bottom);
for (const auto &line : _lines) {
if (line.font >= fontCount)
continue;
fonts[line.font]->drawString(line.text, line.x, line.y, (color < 0) ? line.color : color, 0, true, surface);
}
return true;
}
bool TXTFile::draw(uint line, Surface &surface, int16 &left, int16 &top, int16 &right, int16 &bottom,
const Font * const *fonts, uint fontCount, int color) {
trashBuffer();
if (!getArea(line, left, top, right, bottom, fonts, fontCount))
return false;
resizeBuffer(right - left + 1, bottom - top + 1);
saveScreen(surface, left, top, right, bottom);
const Line &l = _lines[line];
fonts[l.font]->drawString(l.text, l.x, l.y, (color < 0) ? l.color : color, 0, true, surface);
return true;
}
bool TXTFile::draw(Surface &surface, const Font * const *fonts, uint fontCount, int color) {
int16 left, top, right, bottom;
return draw(surface, left, top, right, bottom, fonts, fontCount, color);
}
bool TXTFile::draw(uint line, Surface &surface, const Font * const *fonts, uint fontCount, int color) {
int16 left, top, right, bottom;
return draw(line, surface, left, top, right, bottom, fonts, fontCount, color);
}
bool TXTFile::clear(Surface &surface, int16 &left, int16 &top, int16 &right, int16 &bottom) {
return restoreScreen(surface, left, top, right, bottom);
}
bool TXTFile::getArea(int16 &left, int16 &top, int16 &right, int16 &bottom,
const Font * const *fonts, uint fontCount) const {
bool hasLine = false;
left = 0x7FFF;
top = 0x7FFF;
right = 0x0000;
bottom = 0x0000;
for (uint i = 0; i < _lines.size(); i++) {
int16 lLeft, lTop, lRight, lBottom;
if (getArea(i, lLeft, lTop, lRight, lBottom, fonts, fontCount)) {
left = MIN(left , lLeft );
top = MIN(top , lTop );
right = MAX(right , lRight );
bottom = MAX(bottom, lBottom);
hasLine = true;
}
}
return hasLine;
}
bool TXTFile::getArea(uint line, int16 &left, int16 &top, int16 &right, int16 &bottom,
const Font * const *fonts, uint fontCount) const {
if ((line >= _lines.size()) || (_lines[line].font >= fontCount))
return false;
const Line &l = _lines[line];
left = l.x;
top = l.y;
right = l.x + l.text.size() * fonts[l.font]->getCharWidth() - 1;
bottom = l.y + fonts[l.font]->getCharHeight() - 1;
return true;
}
Common::String TXTFile::getStr(Common::SeekableReadStream &txt) {
// Skip all ' ', '\n' and '\r'
while (!txt.eos()) {
char c = txt.readByte();
if (txt.eos())
break;
if ((c != ' ') && (c != '\n') && (c != '\r')) {
txt.seek(-1, SEEK_CUR);
break;
}
}
if (txt.eos())
return "";
// Read string until ' ', '\n' or '\r'
Common::String string;
while (!txt.eos()) {
char c = txt.readByte();
if ((c == ' ') || (c == '\n') || (c == '\r'))
break;
string += c;
}
// Replace all '#' with ' ' and throw out non-printables
Common::String cleanString;
for (uint i = 0; i < string.size(); i++) {
if (string[i] == '#')
cleanString += ' ';
else if ((unsigned char)string[i] >= ' ')
cleanString += string[i];
}
return cleanString;
}
int TXTFile::getInt(Common::SeekableReadStream &txt) {
// Skip all [^-0-9]
while (!txt.eos()) {
char c = txt.readByte();
if (txt.eos())
break;
if ((c == '-') || ((c >= '0') && (c <= '9'))) {
txt.seek(-1, SEEK_CUR);
break;
}
}
if (txt.eos())
return 0;
// Read until [^-0-9]
Common::String string;
while (!txt.eos()) {
char c = txt.readByte();
if ((c != '-') && ((c < '0') || (c > '9')))
break;
string += c;
}
// Convert to integer
return atoi(string.c_str());
}
} // End of namespace Gob

View File

@@ -0,0 +1,96 @@
/* 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/>.
*
*
* This file is dual-licensed.
* In addition to the GPLv3 license mentioned above, this code is also
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
* full text of the license.
*
*/
#ifndef GOB_PREGOB_TXTFILE_H
#define GOB_PREGOB_TXTFILE_H
#include "common/system.h"
#include "common/str.h"
#include "common/array.h"
#include "gob/backbuffer.h"
namespace Common {
class SeekableReadStream;
}
namespace Gob {
class Surface;
class Font;
class TXTFile : public BackBuffer {
public:
enum Format {
kFormatString,
kFormatStringPosition,
kFormatStringPositionColor,
kFormatStringPositionColorFont
};
struct Line {
Common::String text;
int x, y;
int color;
uint font;
};
typedef Common::Array<Line> LineArray;
TXTFile(Common::SeekableReadStream &txt, Format format);
~TXTFile();
LineArray &getLines();
bool draw( Surface &surface, const Font * const *fonts, uint fontCount, int color = -1);
bool draw(uint line, Surface &surface, const Font * const *fonts, uint fontCount, int color = -1);
bool draw( Surface &surface, int16 &left, int16 &top, int16 &right, int16 &bottom,
const Font * const *fonts, uint fontCount, int color = -1);
bool draw(uint line, Surface &surface, int16 &left, int16 &top, int16 &right, int16 &bottom,
const Font * const *fonts, uint fontCount, int color = -1);
bool clear(Surface &surface, int16 &left, int16 &top, int16 &right, int16 &bottom);
private:
LineArray _lines;
void load(Common::SeekableReadStream &txt, Format format);
Common::String getStr(Common::SeekableReadStream &txt);
int getInt(Common::SeekableReadStream &txt);
bool getArea( int16 &left, int16 &top, int16 &right, int16 &bottom,
const Font * const *fonts, uint fontCount) const;
bool getArea(uint line, int16 &left, int16 &top, int16 &right, int16 &bottom,
const Font * const *fonts, uint fontCount) const;
};
} // End of namespace Gob
#endif // GOB_PREGOB_TXTFILE_H