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,3 @@
# This file is included from the main "configure" script
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] [components]
add_engine cryo "Lost Eden" no "" "" "hnm"

6
engines/cryo/credits.pl Normal file
View File

@@ -0,0 +1,6 @@
begin_section("Cryo");
add_person("Arnaud Boutonné", "Strangerke", "");
add_person("Filippos Karapetis", "bluegr", "");
add_person("Retro-Junk;", "bambarbee", "");
add_person("Eugene Sandulenko", "sev", "");
end_section();

80
engines/cryo/cryo.cpp Normal file
View File

@@ -0,0 +1,80 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/scummsys.h"
#include "common/config-manager.h"
#include "common/debug.h"
#include "common/debug-channels.h"
#include "common/error.h"
#include "graphics/surface.h"
#include "graphics/screen.h"
#include "common/system.h"
#include "engines/util.h"
#include "cryo/cryo.h"
#include "cryo/eden.h"
namespace Cryo {
CryoEngine *g_ed = nullptr;
CryoEngine::CryoEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
_rnd = new Common::RandomSource("cryo");
_game = nullptr;
_screenView = nullptr;
_showHotspots = false;
_timerTicks = 0;
_mouseButton = 0;
g_ed = this;
}
CryoEngine::~CryoEngine() {
delete _rnd;
delete _game;
delete _screenView;
}
Common::Error CryoEngine::run() {
_game = new EdenGame(this);
_screenView = new View(320, 200);
setDebugger(new Debugger(this));
///// CLTimer
_timerTicks = 0; // incremented in realtime
// Initialize graphics using following:
initGraphics(320, 200);
_screen.create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
_game->run();
return Common::kNoError;
}
bool CryoEngine::hasFeature(EngineFeature f) const {
return (f == kSupportsReturnToLauncher);
}
} // End of namespace Cryo

94
engines/cryo/cryo.h Normal file
View File

@@ -0,0 +1,94 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYO_CRYO_H
#define CRYO_CRYO_H
#include "common/scummsys.h"
#include "common/config-manager.h"
#include "common/debug.h"
#include "common/debug-channels.h"
#include "common/error.h"
#include "common/random.h"
#include "engines/engine.h"
#include "gui/debugger.h"
#include "graphics/surface.h"
#include "graphics/screen.h"
#include "cryo/eden.h"
#include "cryo/debugger.h"
struct ADGameDescription;
namespace Cryo {
class Console;
// our engine debug channels
enum {
kCryoDebugExample = 1 << 0,
kCryoDebugExample2 = 1 << 1
// next new channel must be 1 << 2 (4)
// the current limitation is 32 debug channels (1 << 31 is the last one)
};
class CryoEngine : public Engine {
public:
CryoEngine(OSystem *syst, const ADGameDescription *gameDesc);
~CryoEngine() override;
Common::Error run() override;
bool hasFeature(EngineFeature f) const override;
// Detection related functions
const ADGameDescription *_gameDescription;
const char *getGameId() const;
Common::Platform getPlatform() const;
bool isDemo() const;
// We need random numbers
Common::RandomSource *_rnd;
Graphics::Surface _screen;
EdenGame *_game;
View *_screenView;
volatile int32 _timerTicks;
bool _showHotspots;
void pollEvents();
void hideMouse();
void showMouse();
void getMousePosition(int16 *x, int16 *y);
void setMousePosition(int16 x, int16 y);
bool isMouseButtonDown();
private:
int _mouseButton;
};
extern CryoEngine *g_ed;
} // End of namespace Cryo
#endif

346
engines/cryo/cryolib.cpp Normal file
View File

@@ -0,0 +1,346 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/system.h"
#include "common/events.h"
#include "common/timer.h"
#include "graphics/paletteman.h"
#include "cryo/cryo.h"
#include "cryo/cryolib.h"
namespace Cryo {
///// Mac APIs
void SysBeep(int x) {
}
void FlushEvents(int16 arg1, int16 arg2) {
}
///// CLView
View::View(int w, int h) {
void *buffer = (byte *)malloc(w * h);
if (buffer)
initDatas(w, h, buffer);
else
error("Unable to allocate view buffer");
}
View::~View() {
if (_bufferPtr)
free(_bufferPtr);
}
// Original name: CLView_SetSrcZoomValues
void View::setSrcZoomValues(int x, int y) {
_zoom._srcLeft = x;
_zoom._srcTop = y;
}
// Original name: CLView_SetDisplayZoomValues
void View::setDisplayZoomValues(int w, int h) {
_zoom._width = w;
_zoom._height = h;
}
// Original name: CLView_InitDatas
void View::initDatas(int w, int h, void *buffer) {
_bufferPtr = (byte *)buffer;
_width = w;
_height = h;
_pitch = w;
_normal._srcLeft = 0;
_normal._srcTop = 0;
_normal._dstLeft = 0;
_normal._dstTop = 0;
_normal._width = w;
_normal._height = h;
_zoom._srcLeft = 0;
_zoom._srcTop = 0;
_zoom._dstLeft = 0;
_zoom._dstTop = 0;
_zoom._width = w;
_zoom._height = h;
}
// Original name: CLView_CenterIn
void View::centerIn(View *parent) {
_normal._dstLeft = (parent->_width - _normal._width) / 2;
_normal._dstTop = (parent->_height - _normal._height) / 2;
_zoom._dstLeft = (parent->_width - _zoom._width) / 2;
_zoom._dstTop = (parent->_height - _zoom._height) / 2;
}
///// CLPalette
static uint16 gIntervalLast, gIntervalFirst, gIntervalSet;
static int16 gMacintize;
static color_t last_palette[256];
void CLPalette_Init() {
gIntervalLast = 0;
gIntervalFirst = 0;
gIntervalSet = 0;
gMacintize = 0;
for (int16 i = 0; i < 256; i++)
last_palette[i].r = last_palette[i].g = last_palette[i].b = 0;
}
void CLPalette_SetLastPalette(color_t *palette, int16 first, int16 count) {
for (int16 i = first; i < first + count; i++)
last_palette[i] = palette[i];
}
void CLPalette_GetLastPalette(color_t *palette) {
for (int16 i = 0; i < 256; i++)
palette[i] = last_palette[i];
}
void CLPalette_SetRGBColor(color_t *palette, uint16 index, color3_t *rgb) {
palette[index].r = rgb->r;
palette[index].g = rgb->g;
palette[index].b = rgb->b;
palette[index].a = 0;
}
void CLPalette_Macintize(int16 macintize) {
gMacintize = macintize;
}
void CLPalette_SetInterval(uint16 first, uint16 last) {
gIntervalFirst = first;
gIntervalSet = 1;
gIntervalLast = last;
}
void CLPalette_DeactivateInterval() {
gIntervalSet = 0;
}
void CLPalette_Send2Screen(struct color_t *palette, uint16 first, uint16 count) {
if (gMacintize) {
palette[0].r = palette[0].g = palette[0].b = 0xFFFF;
palette[255].r = palette[255].g = palette[255].b = 0;
}
if (gIntervalSet) {
if (first < gIntervalFirst)
first = gIntervalFirst;
if (first + count > gIntervalLast)
count = gIntervalLast - first;
}
byte buffer[256 * 3];
for (int i = 0; i < 256; i++) {
buffer[i * 3] = palette[i].r >> 8;
buffer[i * 3 + 1] = palette[i].g >> 8;
buffer[i * 3 + 2] = palette[i].b >> 8;
}
g_system->getPaletteManager()->setPalette(buffer, first, count);
g_system->updateScreen();
CLPalette_SetLastPalette(palette, first, count);
}
void CLPalette_BeSystem() {
}
///// CLBlitter
static uint16 newPaletteCount, newPaletteFirst;
static color_t *pNewPalette;
static bool useNewPalette;
void CLBlitter_Init() {
newPaletteCount = 0;
newPaletteFirst = 0;
pNewPalette = nullptr;
useNewPalette = false;
}
void CLBlitter_CopyViewRect(View *view1, View *view2, Common::Rect *rect1, Common::Rect *rect2) {
int dy = rect2->top;
int w = rect1->right - rect1->left + 1;
// debug("- Copy rect %3d:%3d-%3d:%3d -> %3d:%3d-%3d:%3d - %s",
// rect1->sx, rect1->sy, rect1->ex, rect1->ey,
// rect2->sx, rect2->sy, rect2->ex, rect2->ey,
// (rect1->ex - rect1->sx == rect2->ex - rect2->sx && rect1->ey - rect1->sy == rect2->ey - rect2->sy) ? "ok" : "BAD");
assert(rect1->right - rect1->left == rect2->right - rect2->left && rect1->bottom - rect1->top == rect2->bottom - rect2->top);
for (int sy = rect1->top; sy <= rect1->bottom; sy++, dy++) {
byte *s = view1->_bufferPtr + sy * view1->_pitch + rect1->left;
byte *d = view2->_bufferPtr + dy * view2->_pitch + rect2->left;
for (int x = 0; x < w; x++)
*d++ = *s++;
}
}
void CLBlitter_Send2ScreenNextCopy(color_t *palette, uint16 first, uint16 count) {
pNewPalette = palette;
useNewPalette = true;
newPaletteFirst = first;
newPaletteCount = count;
}
void CLBlitter_OneBlackFlash() {
}
void CLBlitter_CopyView2ViewSimpleSize(byte *src, int16 srcw, int16 srcp, int16 srch,
byte *dst, int16 dstw, int16 dstp, int16 dsth) {
for (int16 y = 0; y < srch; y++) {
for (int16 x = 0; x < srcw; x++)
*dst++ = *src++;
src += srcp - srcw;
dst += dstp - dstw;
}
}
void CLBlitter_CopyView2ScreenCUSTOM(View *view) {
View *dest = g_ed->_screenView;
int16 srcpitch = view->_pitch;
int16 dstpitch = dest->_pitch;
CLBlitter_CopyView2ViewSimpleSize(view->_bufferPtr + view->_normal._srcTop * srcpitch + view->_normal._srcLeft,
view->_normal._width, srcpitch, view->_normal._height,
dest->_bufferPtr + (dest->_normal._dstTop + view->_normal._dstTop) * dstpitch + dest->_normal._dstLeft + view->_normal._dstLeft,
dest->_normal._width, dstpitch, dest->_normal._height);
}
void CLBlitter_CopyView2Screen(View *view) {
if (useNewPalette) {
color_t palette[256];
CLPalette_GetLastPalette(palette);
CLPalette_Send2Screen(pNewPalette, newPaletteFirst, newPaletteCount);
useNewPalette = false;
}
//HACK: Quick hack to force screen update
if (view)
CLBlitter_CopyView2ScreenCUSTOM(view);
g_system->copyRectToScreen(g_ed->_screenView->_bufferPtr, g_ed->_screenView->_pitch, 0, 0, g_ed->_screenView->_width, g_ed->_screenView->_height);
g_system->updateScreen();
}
void CLBlitter_UpdateScreen() {
CLBlitter_CopyView2Screen(nullptr);
}
void CLBlitter_FillView(View *view, unsigned int fill) {
byte *d = view->_bufferPtr;
assert((fill & 0xFF) * 0x01010101 == fill);
for (int16 y = 0; y < view->_height; y++) {
for (int16 x = 0; x < view->_width; x++)
*d++ = fill;
d += view->_pitch - view->_width;
}
}
void CLBlitter_FillScreenView(unsigned int fill) {
CLBlitter_FillView(g_ed->_screenView, fill);
}
///// events wrapper
void CryoEngine::pollEvents() {
g_system->delayMillis(10);
Common::Event event;
while (g_system->getEventManager()->pollEvent(event)) {
// Handle keypress
switch (event.type) {
case Common::EVENT_QUIT:
case Common::EVENT_RETURN_TO_LAUNCHER:
return;
case Common::EVENT_KEYDOWN:
return;
case Common::EVENT_KEYUP:
return;
case Common::EVENT_LBUTTONDOWN:
_mouseButton = 1;
return;
case Common::EVENT_RBUTTONDOWN:
_mouseButton = 2;
return;
case Common::EVENT_LBUTTONUP:
case Common::EVENT_RBUTTONUP:
_mouseButton = 0;
return;
default:
break;
}
}
}
void CryoEngine::hideMouse() {
}
void CryoEngine::showMouse() {
}
void CryoEngine::getMousePosition(int16 *x, int16 *y) {
*x = g_system->getEventManager()->getMousePos().x;
*y = g_system->getEventManager()->getMousePos().y;
}
void CryoEngine::setMousePosition(int16 x, int16 y) {
g_system->warpMouse(x, y);
}
bool CryoEngine::isMouseButtonDown() {
pollEvents();
return _mouseButton != 0;
}
///// CLTimer
void CLTimer_Action(void *arg) {
// long& counter = *((long*)arg);
// counter++;
g_ed->_timerTicks++;
}
///// CRYOLib
void CRYOLib_ManagersInit() {
CLPalette_Init();
CLBlitter_Init();
g_system->getTimerManager()->installTimerProc(CLTimer_Action, 10000, nullptr, "100hz timer");
g_ed->_screenView->initDatas(g_ed->_screen.w, g_ed->_screen.h, g_ed->_screen.getPixels());
}
void CRYOLib_ManagersDone() {
g_system->getTimerManager()->removeTimerProc(CLTimer_Action);
}
PakHeaderNode::PakHeaderNode(int count) {
_count = count;
_files = new PakHeaderItem[count];
}
PakHeaderNode::~PakHeaderNode() {
_count = 0;
delete[] _files;
}
} // End of namespace Cryo

103
engines/cryo/cryolib.h Normal file
View File

@@ -0,0 +1,103 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYO_CRYOLIB_H
#define CRYO_CRYOLIB_H
#include "audio/mixer.h"
#include "common/system.h"
#include "cryo/platdefs.h"
namespace Cryo {
class CryoEngine;
enum {
fsFromStart = 1
};
struct BlitView{
int _srcLeft;
int _srcTop;
int _dstLeft;
int _dstTop;
int _width;
int _height;
};
class View {
public:
View(int w, int h);
~View();
void setSrcZoomValues(int x, int y);
void setDisplayZoomValues(int w, int h);
void initDatas(int w, int h, void *buffer);
void centerIn(View *parent);
int _width;
int _height;
byte *_bufferPtr;
int16 _pitch;
BlitView _normal;
BlitView _zoom;
};
struct color3_t {
uint16 r, g, b;
};
struct color_t {
uint16 a, r, g, b;
};
void SysBeep(int x);
void FlushEvents(int16 arg1, int16 arg2);
void CLBlitter_Init();
void CLBlitter_CopyViewRect(View *view1, View *view2, Common::Rect *rect1, Common::Rect *rect2);
void CLBlitter_Send2ScreenNextCopy(color_t *palette, uint16 first, uint16 count);
void CLBlitter_OneBlackFlash();
void CLBlitter_CopyView2ViewSimpleSize(byte *src, int16 srcw, int16 srcp, int16 srch,
byte *dst, int16 dstw, int16 dstp, int16 dsth);
void CLBlitter_CopyView2ScreenCUSTOM(View *view);
void CLBlitter_CopyView2Screen(View *view);
void CLBlitter_UpdateScreen();
void CLBlitter_FillView(View *view, unsigned int fill);
void CLBlitter_FillScreenView(unsigned int fill);
void CLPalette_Init();
void CLPalette_SetLastPalette(color_t *palette, int16 first, int16 count);
void CLPalette_GetLastPalette(color_t *palette);
void CLPalette_SetRGBColor(color_t *palette, uint16 index, color3_t *rgb);
void CLPalette_Macintize(int16 macintize);
void CLPalette_SetInterval(uint16 first, uint16 last);
void CLPalette_DeactivateInterval();
void CLPalette_Send2Screen(struct color_t *palette, uint16 first, uint16 count);
void CLPalette_BeSystem();
void CRYOLib_ManagersInit();
void CRYOLib_ManagersDone();
} // End of namespace Cryo
#endif

62
engines/cryo/debugger.cpp Normal file
View File

@@ -0,0 +1,62 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "cryo/debugger.h"
#include "cryo/cryo.h"
namespace Cryo {
Debugger::Debugger(CryoEngine *vm) : GUI::Debugger(), _vm(vm) {
registerCmd("showHotspots", WRAP_METHOD(Debugger, Cmd_ShowHotspots));
registerCmd("fullInventory", WRAP_METHOD(Debugger, Cmd_FullInventory));
}
/**
* This command enables/disables hotspot display
*/
bool Debugger::Cmd_ShowHotspots(int argc, const char **argv) {
if (argc != 1) {
debugPrintf("Usage: %s\n", argv[0]);
return true;
}
_vm->_showHotspots ^= 1;
return false;
}
bool Debugger::Cmd_FullInventory(int argc, const char **argv) {
if (argc != 1) {
debugPrintf("Usage: %s\n", argv[0]);
return true;
}
for (int i = 0; i < MAX_OBJECTS; i++) {
object_t *object = _vm->_game->getObjectPtr(i);
object->_flags |= ObjectFlags::ofFlag1;
object->_count++;
}
_vm->_game->showObjects();
return false;
}
} // End of namespace Cryo

47
engines/cryo/debugger.h Normal file
View File

@@ -0,0 +1,47 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYO_DEBUGGER_H
#define CRYO_DEBUGGER_H
#include "common/scummsys.h"
#include "gui/debugger.h"
namespace Cryo {
class CryoEngine;
class Debugger : public GUI::Debugger {
private:
CryoEngine *_vm;
public:
Debugger(CryoEngine *vm);
~Debugger() override {}
protected:
bool Cmd_ShowHotspots(int argc, const char **argv);
bool Cmd_FullInventory(int argc, const char **argv);
};
} // End of namespace Cryo
#endif

840
engines/cryo/defs.h Normal file
View File

@@ -0,0 +1,840 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "cryo/cryolib.h"
#ifndef CRYO_DEFS_H
#define CRYO_DEFS_H
namespace Cryo {
#define getElem(array, idx) \
( (char *)(array) + READ_LE_UINT16((idx) * 2 + (char *)(array)) )
///////////////// Game defs
#define FONT_HEIGHT 9
/*
Glossary
room - a single game world's screen. referenced by 16-bit number 0xAALL, where AA - area# and LL - location#
area - geographic area - Mo, Chamaar, etc
location - coordinates of particular room in an area. usually in form of 0xXY, where X - map row, Y - map column
character - an unique character (human or dino.) Has their own voice/dialog lines
person - instance of a character. Usually tied to specific room, but some may travel with you
party - a group of characters that travel with you
object - inventory item
icon - clickable rectangle with some action tied to it
dialog - a set of of dialog lines for character. further divided by categories and each entry may have associated
condition to be validated
global - game-wide storage area. must be preserved when saving/loading
phase - current story progress. Incremented by 1 for minor events, by 0x10 for major advancements
*/
enum Phases {
phNewGame = 0
};
namespace Areas {
enum Areas {
arMo = 1,
arTausCave,
arChamaar,
arUluru,
arKoto,
arTamara,
arCantura,
arShandovra,
arNarimsCave,
arEmbalmersCave,
arWhiteArch,
arMoorkusLair
};
}
#define MKRM(a,l) (((a) << 8) | (l))
enum OBJECT {
OBJ_0,
OBJ_1,
OBJ_2,
OBJ_3,
OBJ_4,
OBJ_PRISME, // 5
OBJ_6,
OBJ_7,
OBJ_OEUF, // 8
OBJ_9,
OBJ_10,
OBJ_CHAMPB, // 11
OBJ_CHAMPM, // 12
OBJ_COUTEAU, // 13
OBJ_NIDV, // 14
OBJ_NIDO, // 15
OBJ_OR, // 16
OBJ_17,
OBJ_18,
OBJ_SOLEIL, // 19
OBJ_CORNE, // 20
OBJ_21,
OBJ_22,
OBJ_23,
OBJ_24,
OBJ_25,
OBJ_26,
OBJ_27,
OBJ_28,
OBJ_29,
OBJ_30,
OBJ_31,
OBJ_32,
OBJ_33,
OBJ_34,
OBJ_35,
OBJ_36, // 36 is 1st plaque, 6 total
OBJ_37,
OBJ_PLAQUE, // 38
OBJ_39,
OBJ_40,
OBJ_41
};
namespace Objects {
enum Objects {
obNone,
obWayStone,
obShell,
obTalisman,
obTooth,
obPrism, // 5
obFlute,
obApple,
obEgg, // 8
obRoot,
obUnused10,
obShroom, // 11
obBadShroom, // 12
obKnife, // 13
obNest, // 14
obFullNest, // 15
obGold, // 16
obMoonStone,
obBag,
obSunStone, // 19
obHorn, // 20
obSword,
obMaskOfDeath,
obMaskOfBonding,
obMaskOfBirth,
obEyeInTheStorm, // 25
obSkyHammer,
obFireInTheClouds,
obWithinAndWithout,
obEyeInTheCyclone,
obRiverThatWinds,
obTrumpet, // 31
obUnused32,
obDrum,
obUnused34,
obUnused35,
obRing,
obTablet1, // 37 is 1st plaque, 6 total
obTablet2,
obTablet3, // 39
obTablet4,
obTablet5,
obTablet6
};
}
enum PERSO {
PER_KING = 0,
PER_DINA, // 0x12
PER_TAU, // 0x24
PER_MONK, // 0x36
PER_JABBER, // 0x48
PER_ELOI, // 0x5A
PER_MUNGO, // 0x6C
PER_EVE, // 0x7E
PER_SHAZIA, // 0x90
PER_MAMMI, // 0xA2
PER_MAMMI_1, // 0xB4
PER_MAMMI_2, // 0xC6
PER_MAMMI_3, // 0xD8
PER_MAMMI_4, // 0xEA
PER_MAMMI_5, // 0xFC
PER_MAMMI_6, // 0x10E
PER_BAMBOO, // 0x120
PER_KABUKA, // 0x132
PER_GUARDS, // 0x144
PER_UNKN_156, // 0x156
PER_FISHER, // 0x168
PER_MORKUS, // 0x17A
PER_UNKN_18C, // 0x18C
PER_UNKN_19E, // 0x19E
PER_UNKN_1B0, // 0x1B0
PER_UNKN_1C2, // 0x1C2
PER_UNKN_1D4, // 0x1D4
PER_UNKN_1E6, // 0x1E6
PER_UNKN_1F8, // 0x1F8
PER_UNKN_20A, // 0x20A
PER_UNKN_21C, // 0x21C
PER_UNKN_22E, // 0x22E
PER_UNKN_240, // 0x240
PER_UNKN_252, // 0x252
PER_UNKN_264, // 0x264
PER_UNKN_276, // 0x276
PER_UNKN_288, // 0x288
PER_UNKN_29A, // 0x29A
PER_UNKN_2AC, // 0x2AC
PER_UNKN_2BE, // 0x2BE
PER_UNKN_2D0, // 0x2D0
PER_UNKN_2E2, // 0x2E2
PER_UNKN_2F4, // 0x2F4
PER_UNKN_306, // 0x306
PER_UNKN_318, // 0x318
PER_UNKN_32A, // 0x32A
PER_UNKN_33C, // 0x33C
PER_UNKN_34E, // 0x34E
PER_UNKN_360, // 0x360
PER_UNKN_372, // 0x372
PER_UNKN_384, // 0x384
PER_UNKN_396, // 0x396
PER_UNKN_3A8, // 0x3A8
PER_UNKN_3BA, // 0x3BA
PER_UNKN_3CC, // 0x3CC
PER_UNKN_3DE, // 0x3DE
PER_UNKN_3F0, // 0x3F0
PER_UNKN_402 // 0x402
};
namespace PersonId {
enum PersonId {
pidGregor = 0, // The King
pidDina, // Pink dino
pidTau, // Late grandpa
pidMonk, // Old wizard
pidJabber, // Executioner
pidEloi, // Evergreen ptero
pidMungo, // Dina's husband
pidEve, // Blonde girl
pidShazia, // Big boobs sis
pidLeadersBegin, // 9
pidChongOfChamaar = pidLeadersBegin, // Dogface
pidKommalaOfKoto, // Clones
pidUlanOfUlele, // Shaman
pidCabukaOfCantura, // Stone people
pidMarindaOfEmbalmers, // Gods
pidFuggOfTamara, // Boar-like
pidThugg, // Bodyguard
pidNarrator, // 16, Old Eloi, also BGM
pidNarrim, // Sea snake
pidMorkus, // Vicious tyran
pidDinosaur, // different species of friendly dino
pidEnemy // different species of enemy dino
};
}
// person in room mask bits
namespace PersonMask {
enum PersonMask {
pmGregor = 1,
pmDina = 2,
pmTau = 4,
pmMonk = 8,
pmJabber = 0x10,
pmEloi = 0x20,
pmMungo = 0x40,
pmEve = 0x80,
pmShazia = 0x100,
pmLeader = 0x200, // valley tribe leader
pmThugg = 0x400,
pmQuest = 0x800, // special quest person
pmDino = 0x1000,
pmEnemy = 0x2000,
pmMorkus = 0x4000
};
}
namespace PersonFlags {
enum PersonFlags {
pfType0 = 0,
pftTyrann,
pfType2,
pfType3,
pfType4,
pfType5,
pfType6,
pfType7,
pfType8,
pftMosasaurus,
pftTriceraptor,
pftVelociraptor,
pfType12,
pfType13,
pfType14,
pfType15,
pfTypeMask = 0xF,
pf10 = 0x10,
pf20 = 0x20,
pfInParty = 0x40,
pf80 = 0x80
};
}
#include "common/pack-start.h"
struct perso_t {
uint16 _roomNum; // room this person currently in
uint16 _actionId; // TODO: checkme
uint16 _partyMask; // party bit mask
byte _id; // character
byte _flags; // flags and kind
byte _roomBankId;// index in _personRoomBankTable for specific room banks
byte _spriteBank; // sprite bank
uint16 _items; // inventory
uint16 _powers; // obj of power bitmask
byte _targetLoc; // For party member this is mini sprite index
byte _lastLoc; // For party member this is mini sprite x offset
byte _speed; // num ticks per step
byte _steps; // current ticks
void clear() {
_roomNum = _actionId = _partyMask = 0;
_id = _flags = _roomBankId = _spriteBank = 0;
_items = _powers = 0;
_targetLoc = _lastLoc = _speed = _steps = 0;
}
};
namespace ObjectFlags {
enum ObjectFlags {
ofFlag1 = 1,
ofInHands = 2 // Currently holding this object in hands
};
}
#define MAX_OBJECTS 42
struct object_t {
byte _id;
byte _flags;
int _locations; // index in _objectLocations
uint16 _itemMask;
uint16 _powerMask; // object of power bitmask
int16 _count;
void clear() {
_id = _flags = 0;
_locations = 0;
_itemMask = _powerMask = 0;
_count = 0;
}
};
namespace DialogFlags {
enum DialogFlags {
df20 = 0x20,
dfRepeatable = 0x40,
dfSpoken = 0x80
};
}
namespace DialogType {
enum DialogType {
dtTalk = 0,
dtDinoAction,
dtDinoItem,
dtItem,
dtEvent,
dtInspect,
dtHint
};
}
struct Dialog {
int8 _flags; // 0-3 - action index, 4 - highest bit of contidion index, rest is DialogFlags
int8 _condNumLow; // condition index low bits
int8 _textCondHiMask; // 0-1 text index hi bits, 2-5 - perso mask num, 6-7 condition index hi bits
int8 _textNumLow; // text line index low bits
};
struct tape_t {
int16 _textNum;
perso_t *_perso;
int16 _party;
int16 _roomNum;
int16 _backgroundBankNum;
Dialog *_dialog;
};
struct Follower { // Characters on Mirror screen
int8 _id; // character
int8 _spriteNum; // sprite number
int16 sx;
int16 sy;
int16 ex;
int16 ey;
int16 _spriteBank;
int16 ff_C;
int16 ff_E;
};
struct Icon {
int16 sx;
int16 sy;
int16 ex;
int16 ey;
uint16 _cursorId; // & 0x8000 - inactive/hidden
uint32 _actionId;
uint32 _objectId;
};
struct Goto {
byte _areaNum; // target area
byte _curAreaNum; // current area
byte _enterVideoNum;
byte _travelTime; // time to skip while in travel
byte _arriveVideoNum;
};
namespace RoomFlags {
enum RoomFlags {
rf01 = 1,
rf02 = 2,
rf04 = 4,
rf08 = 8,
rfPanable = 0x10,
rfHasCitadel = 0x20,
rf40 = 0x40,
rf80 = 0x80
};
}
struct Room {
byte _id;
byte _exits[4]; //TODO: signed?
byte _flags;
uint16 _bank;
uint16 _party;
byte _level; // Citadel level
byte _video;
byte _location;
byte _backgroundBankNum; // bg/mirror image number (relative)
};
namespace AreaFlags {
enum AreaFlags {
afFlag1 = 1,
afFlag2 = 2,
afFlag4 = 4,
afFlag8 = 8,
afGaveGold = 0x10,
afFlag20 = 0x20,
HasTriceraptors = 0x100,
HasVelociraptors = 0x200,
HasTyrann = 0x400,
TyrannSighted = 0x4000,
afFlag8000 = 0x8000
};
}
namespace AreaType {
enum AreaType {
atCitadel = 1,
atValley = 2,
atCave = 3
};
}
struct Area {
byte _num;
byte _type;
uint16 _flags;
uint16 _firstRoomIdx;
byte _citadelLevel;
byte _placeNum;
Room *_citadelRoomPtr;
int16 _visitCount;
void clear() {
_num = _type = 0;
_flags = _firstRoomIdx = 0;
_citadelLevel = _placeNum = 0;
_citadelRoomPtr = nullptr;
_visitCount = 0;
}
};
namespace ValleyNews {
enum ValleyNews {
vnAreaMask = 0xF,
vnTriceraptorsIn = 0x10,
vnVelociraptorsIn = 0x20,
vnTyrannIn = 0x30,
vnTyrannLost = 0x40,
vnCitadelLost = 0x50,
vnVelociraptorsLost = 0x60,
vnFree = 0,
vnHidden = 0x80,
vnEnd = 0xFF
};
}
namespace DisplayFlags {
enum DisplayFlags {
dfFlag1 = 1,
dfFlag2 = 2,
dfMirror = 4,
dfPerson = 8,
dfFrescoes = 0x10,
dfPanable = 0x20,
dfFlag40 = 0x40,
dfFlag80 = 0x80
};
}
namespace DrawFlags {
enum DrawFlags {
drDrawInventory = 1,
drDrawFlag2 = 2,
drDrawTopScreen = 4,
drDrawFlag8 = 8,
drDrawMenu = 0x10,
drDrawFlag20 = 0x20
};
}
namespace MenuFlags {
enum MenuFlags {
mfFlag1 = 1,
mfFlag2 = 2,
mfFlag4 = 4,
mfFlag8 = 8,
mfFlag10 = 0x10
};
}
namespace MusicType {
enum MusicType { //TODO: same as DialogType?
mtDontChange = 0,
mtNormal = 1,
mt2 = 2,
mtEvent = 4,
mtFF = 0xFF
};
}
namespace EventType {
enum EventType {
etEvent1 = 1,
etEvent2 = 2,
etEvent3 = 3,
etEvent4 = 4,
etEvent5 = 5,
etEvent6 = 6,
etEvent7 = 7,
etEvent8 = 8,
etEvent9 = 9,
etEventB = 11,
etEventC = 12,
etEventD = 13,
etEventE = 14,
etEventF = 15,
etEvent10 = 16,
etEvent12 = 18,
etGotoArea = 0x80 // + area id
};
}
namespace GameFlags {
enum GameFlags {
gfNone = 0,
gfMummyOpened = 1,
gfFlag2 = 2,
gfFlag4 = 4,
gfFlag8 = 8,
gfFlag10 = 0x10,
gfFlag20 = 0x20,
gfFlag40 = 0x40,
gfFlag80 = 0x80,
gfFlag100 = 0x100,
gfFlag200 = 0x200,
gfFlag400 = 0x400,
gfPrismAndMonk = 0x800,
gfFlag1000 = 0x1000,
gfFlag2000 = 0x2000,
gfFlag4000 = 0x4000,
gfFlag8000 = 0x8000
};
}
struct global_t {
byte _areaNum;
byte _areaVisitCount;
byte _menuItemIdLo;
byte _menuItemIdHi; //TODO: pad?
uint16 _randomNumber; //TODO: this is randomized in pc ver and used by some conds. always zero on mac
uint16 _gameTime;
uint16 _gameDays;
uint16 _chrono;
uint16 _eloiDepartureDay;
uint16 _roomNum; // current room number
uint16 _newRoomNum; // target room number selected on world map
uint16 _phaseNum;
uint16 _metPersonsMask1;
uint16 _party;
uint16 _partyOutside;
uint16 _metPersonsMask2;
uint16 _var1C; //TODO: write-only?
uint16 _phaseActionsCount;
uint16 _curAreaFlags;
uint16 _curItemsMask;
uint16 _curPowersMask;
uint16 _curPersoItems;
uint16 _curCharacterPowers;
uint16 _wonItemsMask;
uint16 _wonPowersMask;
uint16 _stepsToFindAppleFast;
uint16 _stepsToFindAppleNormal;
uint16 _roomPersoItems; //TODO: write-only?
uint16 _roomCharacterPowers; //TODO: write-only?
uint16 _gameFlags;
uint16 _curVideoNum;
uint16 _morkusSpyVideoNum1; //TODO: pad?
uint16 _morkusSpyVideoNum2; //TODO: pad?
uint16 _morkusSpyVideoNum3; //TODO: pad?
uint16 _morkusSpyVideoNum4; //TODO: pad?
byte _newMusicType;
byte _var43;
byte _videoSubtitleIndex;
byte _partyInstruments; // &1 - Bell for Monk, &2 - Drum for Thugg
byte _monkGotRing;
byte _chronoFlag;
byte _curRoomFlags;
byte _endGameFlag;
byte _lastInfo;
bool _autoDialog;
byte _worldTyranSighted;
byte _var4D;
byte _var4E;
byte _worldGaveGold;
byte _worldHasTriceraptors;
byte _worldHasVelociraptors;
byte _worldHasTyran;
byte _var53;
byte _var54; //CHEKME: Used?
byte _var55; //TODO: pad?
byte _gameHours;
byte _textToken1;
byte _textToken2; //TODO: pad?
byte _eloiHaveNews;
byte _dialogFlags;
byte _curAreaType;
byte _curCitadelLevel;
byte _newLocation;
byte _prevLocation;
byte _curPersoFlags;
byte _var60;
byte _eventType;
byte _var62; //TODO: pad?
byte _curObjectId;
byte _curObjectFlags;
byte _var65; //TODO: pad?
byte _roomCharacterType;
byte _roomCharacterFlags;
byte _narratorSequence;
byte _var69;
byte _var6A;
byte _frescoNumber;
byte _var6C; //TODO: pad?
byte _var6D; //TODO: pad?
byte _labyrinthDirections;
byte _labyrinthRoom;
Dialog *_dialogPtr;
tape_t *_tapePtr;
Dialog *_nextDialogPtr;
Dialog *_narratorDialogPtr;
Dialog *_lastDialogPtr;
Icon *_nextRoomIcon;
byte *_sentenceBufferPtr;
Room *_roomPtr;
Area *_areaPtr;
Area *_lastAreaPtr;
Area *_curAreaPtr;
Room *_citaAreaFirstRoom;
perso_t *_characterPtr;
perso_t *_roomCharacterPtr;
byte _lastInfoIdx;
byte _nextInfoIdx;
byte *_persoSpritePtr;
byte *_persoSpritePtr2;
byte *_curCharacterAnimPtr;
byte *_varC2; //TODO: image desc arr
int16 _iconsIndex;
int16 _curObjectCursor; // TODO: useless?
int16 _varCA;
int16 _varCC; //TODO: unused/pad
int16 _characterImageBank; //TODO: unsigned?
uint16 _roomImgBank;
uint16 _characterBackgroundBankIdx;
uint16 _varD4; //TODO: unsigned?
uint16 _frescoeWidth;
uint16 _frescoeImgBank;
uint16 _varDA; //TODO: pad?
uint16 _varDC; //TODO: pad?
uint16 _roomBaseX;
uint16 _varE0; //TODO: pad?
uint16 _dialogType;
uint16 _varE4; //TODO: pad?
uint16 _currMusicNum;
int16 _textNum;
uint16 _travelTime;
uint16 _varEC; //TODO: pad?
byte _displayFlags;
byte _oldDisplayFlags;
byte _drawFlags;
byte _varF1;
byte _varF2;
byte _menuFlags;
byte _varF4; //TODO: write-only?
byte _varF5;
byte _varF6;
byte _varF7;
byte _varF8; //TODO: pad?
byte _varF9; //TODO: pad?
byte _varFA; //TODO: pad?
byte _animationFlags;
byte _giveObj1;
byte _giveObj2;
byte _giveObj3;
byte _var100;
byte _roomVidNum;
byte _mirrorEffect;
byte _var103;
byte _roomBackgroundBankNum;
byte _valleyVidNum;
byte _updatePaletteFlag;
byte _inventoryScrollPos;
byte _objCount;
byte _textBankIndex;
byte _prefLanguage;
byte _prefMusicVol[2];
byte _prefVoiceVol[2];
byte _prefSoundVolume[2];
byte _citadelAreaNum;
byte _var113;
byte _lastPlaceNum;
byte _saveEnd; // TODO: This has to be removed
int16 _textWidthLimit;
byte _numGiveObjs;
byte _var119; // unused
};
#include "common/pack-end.h"
struct PakHeaderItem {
Common::String _name; //[16];
int32 _size;
int32 _offs;
char _flag;
};
class PakHeaderNode {
public:
PakHeaderNode(int count);
~PakHeaderNode();
uint16 _count;
PakHeaderItem* _files;
};
struct Citadel {
int16 _id;
int16 _bank[8];
int16 _video[8];
void clear() {
_id = 0;
for (int i = 0; i < 8; ++i) {
_bank[i] = 0;
_video[i] = 0;
}
}
};
/*
Labyrinth of Mo
| | | | | | | |
*/
enum {
LAB_N = 1,
LAB_E,
LAB_S,
LAB_W
};
struct CubeFace {
int tri;
char ff_4;
char ff_5;
byte *_texturePtr;
uint16 *_indices;
int16 *_uv;
};
struct Point3D {
int16 x;
int16 y;
int16 z;
};
struct Cube {
int _num;
CubeFace **_faces;
Point3D *_projection; // projected XYZ coords
Point3D *_vertices;
};
struct XYZ {
signed short x, y, z;
};
struct CubeCursor {
uint8 _sides[6]; // spr idx for each side
uint8 _kind;
int8 _speed;
};
} // End of namespace Cryo
#endif

152
engines/cryo/detection.cpp Normal file
View File

@@ -0,0 +1,152 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "base/plugins.h"
#include "engines/advancedDetector.h"
static const PlainGameDescriptor cryoGames[] = {
{"losteden", "Lost Eden"},
{nullptr, nullptr}
};
namespace Cryo {
static const ADGameDescription gameDescriptions[] = {
// Lost Eden PC non-interactive demo version
// Probably not worth it
{
"losteden",
nullptr,
AD_ENTRY1s("EDEN6.HSQ", "00b43c44cf2ac50b1a45dfad5fa5360d", 17093),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_DEMO | ADGF_UNSTABLE,
GUIO1(GUIO_NOMIDI)
},
// Lost Eden PC interactive demo version
{
"losteden",
nullptr,
AD_ENTRY1s("EDEN.DAT", nullptr, 205473728),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_DEMO | ADGF_UNSTABLE,
GUIO1(GUIO_NOMIDI)
},
// Lost Eden PC version
{
"losteden",
nullptr,
AD_ENTRY1s("EDEN.DAT", nullptr, 449853776),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO1(GUIO_NOMIDI)
},
// Lost Eden EN PC version
// Added by Strangerke
{
"losteden",
nullptr,
AD_ENTRY1s("EDEN.DAT", "2126f14fe38b47c7a132f7937c79a2f0", 451205552),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO1(GUIO_NOMIDI)
},
// Lost Eden FR PC version
// Added by Strangerke
{
"losteden",
nullptr,
AD_ENTRY1s("EDEN.DAT", "378b1260ac400ecf35f8843357adcca6", 448040496),
Common::FR_FRA,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO1(GUIO_NOMIDI)
},
// Lost Eden DE PC version
{
"losteden",
nullptr,
AD_ENTRY1s("EDEN.DAT", nullptr, 457719104),
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO1(GUIO_NOMIDI)
},
// Lost Eden Mac version
{
"losteden",
nullptr,
AD_ENTRY1s("EDEN.DAT", nullptr, 489739536),
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
GUIO1(GUIO_NOMIDI)
},
// Lost Eden PC-9821 version
// English with JP/EN subtitles
// PC-9801-86/PC-9821A or PC-9821X/N/C audio
{
"losteden",
nullptr,
AD_ENTRY1s("EDEN.DAT", "5f8817a58e6a7729bcd5ebeabe17640e", 450052416),
Common::EN_ANY,
Common::kPlatformPC98,
ADGF_UNSTABLE,
GUIO1(GUIO_NOMIDI)
},
AD_TABLE_END_MARKER
};
} // End of namespace Cryo
class CryoMetaEngineDetection : public AdvancedMetaEngineDetection<ADGameDescription> {
public:
CryoMetaEngineDetection() : AdvancedMetaEngineDetection(Cryo::gameDescriptions, cryoGames) {
}
const char *getName() const override {
return "cryo";
}
const char *getEngineName() const override {
return "Cryo";
}
const char *getOriginalCopyright() const override {
return "Cryo Engine (C) Cryo Interactive";
}
};
REGISTER_PLUGIN_STATIC(CRYO_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, CryoMetaEngineDetection);

7887
engines/cryo/eden.cpp Normal file

File diff suppressed because it is too large Load Diff

760
engines/cryo/eden.h Normal file
View File

@@ -0,0 +1,760 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYO_EDEN_H
#define CRYO_EDEN_H
#include "common/file.h"
#include "common/savefile.h"
#include "common/serializer.h"
#include "cryo/sound.h"
#include "cryo/defs.h"
enum Direction {
kCryoNorth = 0,
kCryoEast = 1,
kCryoSouth = 2,
kCryoWest = 3
};
namespace Cryo {
class CryoEngine;
class EdenGraphics;
class EdenGame {
private:
EdenGraphics *_graphics;
public:
EdenGame(CryoEngine *vm);
~EdenGame();
void run();
object_t *getObjectPtr(int16 id);
void showObjects();
void saveFriezes();
void useBank(int16 bank);
void musicspy();
void fademusica0(int16 delay);
void wait(int howlong);
bool isObjectHere(int16 id);
void display();
void setMouseCenterX(uint16 xpos);
void setMouseCenterY(uint16 ypos);
void stopMusic();
uint16 getMouseCenterX();
uint16 getMouseCenterY();
bool dialoscansvmas(Dialog *dial);
void musique();
void preloadDialogs(int16 vid);
Common::SeekableReadStream *loadSubStream(uint16 num);
bool personIsTalking();
bool animationIsActive();
byte *getImageDesc();
byte *getPlaceRawBuf();
byte getActionCursor(byte value);
int16 getNumTextLines();
int16 getScrollPos();
/*
* Identify person based on current video number
*/
perso_t *personSubtitles();
int16 getGameIconY(int16 index);
int16 getGameIconX(int16 index);
byte *getGameDialogs();
bool getSpecialTextMode();
void setSpecialTextMode(bool value);
void setCursorSaved(bool cursorSaved);
bool getCursorSaved();
bool getNoPalette();
int16 getCurBankNum();
byte *getCurKeepBuf();
byte *getBankData();
int16 getCurPosX();
void setCurPosX(int16 xpos);
int16 getCurPosY();
void setCurPosY(int16 ypos);
byte *getGlowBuffer();
void setMusicFade(byte value);
bool isMouseHeld();
void setMouseHeld();
void setMouseNotHeld();
global_t *_globals; // TODO: Make private and use getters
CryoEngine *_vm;
private:
void removeConsole();
void scroll();
void resetScroll();
void scrollFrescoes();
void displayFrescoes();
void gametofresques();
void doFrescoes();
void actionEndFrescoes();
void scrollMirror();
void scrollPanel();
void displayFollower(Follower *follower, int16 x, int16 y);
void characterInMirror();
void gameToMirror(byte arg1);
void flipMode();
void quitMirror();
void clictimbre();
void actionClickValleyPlan();
void gotoPlace(Goto *go);
void deplaval(uint16 roomNum);
void move(Direction dir);
void move2(Direction dir);
void actionDinoBlow();
void actionPlateMonk();
void actionGraaFrescoe();
void actionLascFrescoe();
void actionPushStone();
void actionMummyHead();
void actionSkelettonHead();
void actionSkelettonMoorkong();
void actionChoose();
void handleDinaDialog();
void handleKingDialog();
void actionKingDialog1();
void actionKingDialog2();
void actionKingDialog3();
void actionGetKnife();
void actionGetPrism();
void actionGetMushroom();
void actionGetBadMushroom();
void actionGetGold();
void actionGetFullNest();
void actionGetEmptyNest();
void actionGetHorn();
void actionGetSunStone();
void actionGetEgg();
void actionGetTablet();
void actionLookLake();
void actionGotoHall();
void actionLabyrinthTurnAround();
void actionGotoFullNest();
void actionGotoVal();
void actionVisit();
void actionFinal();
void actionMoveNorth();
void actionMoveEast();
void actionMoveSouth();
void actionMoveWest();
void afficher128();
void restoreFriezes();
void useMainBank();
void useCharacterBank();
void drawTopScreen();
void displayValleyMap();
void displayMapMark(int16 index, int16 location);
void displayAdamMapMark(int16 location);
void restoreAdamMapMark();
void saveAdamMapMark(int16 x, int16 y);
bool istrice(int16 roomNum);
bool istyran(int16 roomNum);
void istyranval(Area *area);
char getDirection(perso_t *perso);
bool canMoveThere(char loc, perso_t *perso);
void scramble1(uint8 elem[4]);
void scramble2(uint8 elem[4]);
void scrambleDirections();
bool naitredino(char persoType);
void newCitadel(char area, int16 level, Room *room);
void evolveCitadel(int16 level);
void destroyCitadelRoom(int16 roomNum);
void narratorBuildCitadel();
void citadelFalls(char level);
void buildCitadel();
void moveDino(perso_t *perso);
void moveAllDino();
void newValley();
char whereIsCita();
bool isCita(int16 loc);
void placeVava(Area *area);
void vivredino();
void vivreval(int16 areaNum);
void handleDay();
void addTime(int16 t);
void animCharacter();
void getanimrnd();
void addanim();
void removeMouthSprite();
void AnimEndCharacter();
void setCharacterSprite(byte *spr);
void displayCharacter1();
void displayCharacter();
void ef_perso();
void loadCharacter(perso_t *perso);
void loadCurrCharacter();
void fin_perso();
void no_perso();
void closeCharacterScreen();
void displayBackgroundFollower();
void displayNoFollower(int16 bank);
void displayCharacterBackground1();
void displayCharacterBackground();
void setCharacterIcon();
void showCharacter();
void displayCharacterPanel();
void getDataSync();
int16 readFrameNumber();
void waitEndSpeak();
void my_bulle();
void my_pr_bulle();
void drawSubtitleChar(byte c, byte color, int16 width);
void patchSentence();
void vavapers();
void citadelle();
void selectZone();
void showEvents1();
void showEvents();
void parle_mfin();
void parlemoi_normal();
void parle_moi();
void initCharacterPointers(perso_t *perso);
void perso1(perso_t *perso);
void perso_normal(perso_t *perso);
void handleCharacterDialog(int16 pers);
void actionKing();
void actionDina();
void actionThoo();
void actionMonk();
void actionTormentor();
void actionMessenger();
void actionMango();
void actionEve();
void actionAzia();
void actionMammi();
void actionGuards();
void actionBamboo();
void actionKabuka();
void actionFisher();
void actionDino();
void actionTyran();
void actionMorkus();
void comment();
void actionAdam();
void setChoiceYes();
void setChoiceNo();
bool isAnswerYes();
void specialMushroom(perso_t *perso);
void specialEmptyNest(perso_t *perso);
void specialNestWithEggs(perso_t *perso);
void specialApple(perso_t *perso);
void specialGold(perso_t *perso);
void specialPrism(perso_t *perso);
void specialTalisman(perso_t *perso);
void specialMask(perso_t *perso);
void specialBag(perso_t *perso);
void specialTrumpet(perso_t *perso);
void specialWeapons(perso_t *perso);
void specialInstrument(perso_t *perso);
void specialEgg(perso_t *perso);
void tyranDies(perso_t *perso);
void specialObjects(perso_t *perso, char objid);
void dialautoon();
void dialautooff();
void follow();
void dialonfollow();
void abortDialogue();
void subHandleNarrator();
void handleNarrator();
void checkPhraseFile();
byte *getPhrase(int16 id);
void actionGotoMap();
void record();
bool dial_scan(Dialog *dial);
bool dialogEvent(perso_t *perso);
void characterStayHere();
void endDeath(int16 vid);
void chronoEvent();
void setChrono(int16 t);
void verifh(byte *ptr);
void openbigfile();
void closebigfile();
void loadRawFile(uint16 num, byte *buffer);
void loadIconFile(uint16 num, Icon *buffer);
void loadRoomFile(uint16 num, Room *buffer);
int loadSound(uint16 num);
void convertMacToPC();
void loadpermfiles();
bool ReadDataSyncVOC(unsigned int num);
bool ReadDataSync(uint16 num);
void loadpartoffile(uint16 num, void *buffer, int32 pos, int32 len);
void expandHSQ(byte *input, byte *output);
void addInfo(byte info);
void unlockInfo();
void nextInfo();
void removeInfo(byte info);
void updateInfoList();
void initGlobals();
void closeRoom();
void displayPlace();
void loadPlace(int16 num);
void specialoutside();
void specialout();
void specialin();
void animpiece();
void getdino(Room *room);
Room *getRoom(int16 loc);
void initPlace(int16 roomNum);
void maj2();
void updateRoom1(int16 roomNum);
void updateRoom(uint16 roomNum);
void allocateBuffers();
void freebuf();
void EmergencyExit();
void edmain();
void intro();
void enterGame();
void signon(const char *s);
void FRDevents();
Icon *scan_icon_list(int16 x, int16 y, int16 index);
void updateCursor();
void mouse();
void startmusique(byte num);
int loadmusicfile(int16 num);
void persovox();
void endCharacterSpeech();
void fademusicup();
void countObjects();
void winObject(int16 id);
void loseObject(int16 id);
void lostObject();
void objectmain(int16 id);
void getObject(int16 id);
void putObject();
void newObject(int16 id, int16 arg2);
void giveobjectal(int16 id);
void giveObject();
void actionTakeObject();
void newMushroom();
void newEmptyNest();
void newNestWithEggs();
void newGold();
void gotoPanel();
void noclicpanel();
void generique();
void cancel2();
void testvoice();
void load();
void initafterload();
void save();
void desktopcolors();
void panelrestart();
void reallyquit();
void confirmer(char mode, char yesId);
void confirmYes();
void confirmNo();
void restart();
void edenQuit();
void choseSubtitleOption();
void changeVolume();
void changervol();
void newvol(byte *volptr, int16 delta);
void playtape();
void rewindtape();
void moveTapeCursor();
void displayTapeCursor();
void forwardTape();
void stopTape();
void clickTapeCursor();
void displayPanel();
void displayLanguage();
void displayVolCursor(int16 x, int16 vol1, int16 vol2);
void displayCursors();
void selectCursor(int itemId);
void displayTopPanel();
void displayResult();
void restrictCursorArea(int16 xmin, int16 xmax, int16 ymin, int16 ymax);
void edenShudown();
void habitants(perso_t *perso);
void suiveurs(perso_t *perso);
void evenements(perso_t *perso);
void followme(perso_t *perso);
void rangermammi(perso_t *perso, Room *room);
void perso_ici(int16 action);
void setCharacterHere();
void faire_suivre(int16 roomNum);
void AddCharacterToParty();
void addToParty(int16 index);
void removeCharacterFromParty();
void removeFromParty(int16 index);
void handleEloiDeparture();
bool checkEloiReturn();
void handleEloiReturn();
void incPhase();
void phase113();
void phase130();
void phase161();
void phase226();
void phase257();
void phase353();
void phase369();
void phase371();
void phase385();
void phase418();
void phase433();
void phase434();
void phase513();
void phase514();
void phase529();
void phase545();
void phase561();
void bigphase1();
void bigphase();
void phase16();
void phase32();
void phase48();
void phase64();
void phase80();
void phase96();
void phase112();
void phase128();
void phase144();
void phase160();
void phase176();
void phase192();
void phase208();
void phase224();
void phase240();
void phase256();
void phase272();
void phase288();
void phase304();
void phase320();
void phase336();
void phase352();
void phase368();
void phase384();
void phase400();
void phase416();
void phase432();
void phase448();
void phase464();
void phase480();
void phase496();
void phase512();
void phase528();
void phase544();
void phase560();
void saveGame(char *name);
void loadrestart();
void loadgame(char *name);
void syncGame(Common::Serializer s);
void syncGlobalPointers(Common::Serializer s);
void syncGlobalValues(Common::Serializer s);
void syncCitadelRoomPointers(Common::Serializer s);
void syncTapePointers(Common::Serializer s);
char testCondition(int16 index);
uint16 operAdd(uint16 v1, uint16 v2);
uint16 operSub(uint16 v1, uint16 v2);
uint16 operLogicalAnd(uint16 v1, uint16 v2);
uint16 operLogicalOr(uint16 v1, uint16 v2);
uint16 operIsEqual(uint16 v1, uint16 v2);
uint16 operIsSmaller(uint16 v1, uint16 v2);
uint16 operIsGreater(uint16 v1, uint16 v2);
uint16 operIsDifferent(uint16 v1, uint16 v2);
uint16 operIsSmallerOrEqual(uint16 v1, uint16 v2);
uint16 operIsGreaterOrEqual(uint16 v1, uint16 v2);
uint16 operFalse(uint16 v1, uint16 v2);
uint16 operation(byte op, uint16 v1, uint16 v2);
uint16 fetchValue();
uint8 getByteVar(uint16 offset);
uint16 getWordVar(uint16 offset);
void actionNop();
void initSinCosTable();
void makeMatriceFix();
void projectionFix(Cube *cube, int n);
void initCubeMac();
void engineMac();
void displayObject(Cube *cube);
void loadMap(int file_id, byte *buffer);
void NEWcharge_objet_mob(Cube *cube, int fileNum, byte *texturePtr);
void DELETEcharge_objet_mob(Cube *cubep);
static int nextVal(char **ptr, char *error);
void selectMap(int16 num);
void Eden_dep_and_rot();
void restoreZDEP();
void displayPolygoneMapping(Cube *cube, CubeFace *face);
void drawMappingLine(int16 r3, int16 r4, int16 r5, int16 r6, int16 r7, int16 r8, int16 r9, int16 r10, int16 *lines);
void displayMappingLine(int16 r3, int16 r4, byte *target, byte *texture);
void LostEdenMac_InitPrefs();
void initCubePC();
void enginePC();
void selectPCMap(int16 num);
void makeTables();
void getSinCosTables(unsigned short angle, signed char **cos_table, signed char **sin_table);
void rotatePoint(XYZ *point, XYZ *rpoint);
void mapPoint(XYZ *point, short *x, short *y);
short calcFaceArea(XYZ *face);
void paintPixel(XYZ *point, unsigned char pixel);
void paintFace0(XYZ *point);
void paintFace1(XYZ *point);
void paintFace2(XYZ *point);
void paintFace3(XYZ *point);
void paintFace4(XYZ *point);
void paintFace5(XYZ *point);
void paintFaces();
void renderCube();
void incAngleX(int step);
void decAngleX();
void incAngleY(int step);
void decAngleY();
void incZoom();
void decZoom();
CubeCursor *_pcCursor;
int16 tab1[30];
int16 tab2[30];
int8 tab3[36][71];
int16 _angleX, _angleY, _angleZ, _zoomZ, _zoomZStep;
int8 *_cosX, *_sinX;
int8 *_cosY, *_sinY;
int8 *_cosZ, *_sinZ;
uint8 *_face[6], *_newface[6];
int16 _faceSkip;
uint8 _cursor[40 * 40];
uint8 *_cursorCenter;
byte _ownObjects[128];
private:
int16 _scrollPos;
int16 _oldScrollPos;
bool _frescoTalk;
byte _oldPix[8];
Common::Point _adamMapMarkPos;
byte _cursKeepBuf[2500];
bool _torchCursor;
int16 _curBankNum;
bool _paletteUpdateRequired;
bool _cursorSaved;
bool _backgroundSaved;
byte *_bankData;
perso_t *_tyranPtr;
int _lastAnimFrameNumb;
int _curAnimFrameNumb;
int _lastAnimTicks;
int16 _numAnimFrames;
int16 _maxPersoDesc;
int16 _numImgDesc;
bool _restartAnimation;
bool _animationActive;
byte _animationDelay;
byte _animationIndex;
byte _lastAnimationIndex;
byte *dword_30724;
byte *dword_30728; //TODO: rename - something amim-related
byte *_mouthAnimations;
byte *_animationTable;
byte _imageDesc[512];
byte *_characterBankData;
int16 _numTextLines;
byte _sentenceBuffer[400];
byte phraseIconsBuffer[10];
byte _sentenceCoordsBuffer[22];
byte *_textOutPtr;
byte *textout;
object_t *_curSpecialObject;
bool _lastDialogChoice;
bool parlemoiNormalFlag;
bool _closeCharacterDialog;
int dword_30B04;
char _lastPhrasesFile;
byte _dialogSkipFlags;
byte *_voiceSamplesBuffer; //TODO: sound sample buffer
Common::File _bigfile;
byte _infoList[16];
byte *_mainBankBuf;
byte *_musicBuf;
byte *_gameLipsync;
byte *_gamePhrases;
byte *_gameDialogs; //TODO: rename to dialogs?
byte *_gameConditions;
byte *_placeRawBuf; //TODO: fixme
byte *_bankDataBuf;
Icon *_gameIcons;
Room *_gameRooms;
PakHeaderNode *_bigfileHeader;
byte *_glowBuffer;
byte *_gameFont; //TODO: rename to font?
uint16 _mouseCenterX;
uint16 _mouseCenterY;
bool _bufferAllocationErrorFl;
bool _quitFlag2;
bool _quitFlag3;
bool _gameStarted;
bool _soundAllocated;
CSoundChannel *_musicChannel;
CSoundChannel *_voiceChannel;
int _demoCurrentTicks;
int _demoStartTicks;
int _currentTime;
int16 _cirsorPanX;
int16 _inventoryScrollDelay;
int16 _cursorPosX;
int16 _cursorPosY;
int16 _currCursor;
Icon *_currSpot;
Icon *_curSpot2;
bool _mouseHeld;
bool _normalCursor;
bool _specialTextMode;
int _voiceSamplesSize; //TODO: perso vox sample data len
int16 _musicRightVol;
int16 _musicLeftVol;
bool _animateTalking;
bool _personTalking;
byte _musicFadeFlag;
char _musicSequencePos;
bool _musicPlayingFlag;
byte *_musicSamplesPtr;
byte *_musicPatternsPtr; //TODO: sndblock_t ?
byte *_musSequencePtr;
bool _musicEnabledFlag;
uint16 *_currentObjectLocation;
bool byte_31D64;
bool _noPalette;
bool _gameLoaded;
#define MAX_TAPES 16
tape_t _tapes[MAX_TAPES];
byte _confirmMode;
byte *_curSliderValuePtr;
byte _lastMenuItemIdLo;
int16 _lastTapeRoomNum;
int16 _curSliderX;
int16 _curSliderY;
int16 _destinationRoom;
int16 word_31E7A; // CHECKME: Unused?
int16 word_378CC; // TODO: set by CLComputer_Init to 0
int16 word_378CE; // CHECKME: Unused
int _invIconsCount;
int _invIconsBase;
int _roomIconsBase;
//// cube.c
int16 _cosTable[361];
int16 _sinTable[361];
int _passMat31, _passMat21, _passMat11;
int _passMat32, _passMat22, _passMat12;
int _passMat33, _passMat23, _passMat13;
int16 _rotationAngleY; // CHECKME: USeless?
int16 _rotationAngleX, _rotationAngleZ;
float _translationY, _translationX; // CHECKME: Useless?
Cube _cube;
int16 _cursCurPCMap;
int16 _lines[200 * 8];
byte _cubeTexture[0x4000];
int _cubeFaces;
uint32 _cursorOldTick, _cursorNewTick;
byte *_codePtr;
uint8 tab_2CB1E[8][4];
const unsigned int kMaxMusicSize; // largest .mus file size
// Loaded from cryo.dat
Follower _followerList[15];
byte _labyrinthPath[70];
char _dinoSpeedForCitadelLevel[16];
char _tabletView[12];
char _personRoomBankTable[84]; // special character backgrounds for specific rooms
// Loaded from cryo.dat - Area transition descriptors
Goto _gotos[130];
object_t _objects[42];
uint16 _objectLocations[45];
perso_t _persons[58];
Citadel _citadelList[7];
// Loaded from cryo.dat
Common::Rect _characterRects[19];
byte _characterArray[20][5];
Area _areasTable[12];
int16 tab_2CEF0[64];
int16 tab_2CF70[64];
byte _actionCursors[299];
byte _mapMode[12];
byte _cubeTextureCoords[3][6 * 2 * 3 * 2];
int32 _translationZ;
int8 _zDirection; // 1 (up) or -1 (down)
// Torch/glow related
int16 _torchTick;
int16 _glowIndex;
int16 _torchCurIndex;
int _cursCenter;
};
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,245 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYO_EDEN_GRAPHICS_H
#define CRYO_EDEN_GRAPHICS_H
#include "cryo/defs.h" // Room
namespace Cryo {
class EdenGame;
class HnmPlayer;
class EdenGraphics {
public:
EdenGraphics(EdenGame *game);
~EdenGraphics();
// Original name: noclipax
void drawSprite(int16 index, int16 x, int16 y, bool withBlack = false, bool onSubtitle = false);
// Original name: af_subtitle
void displaySubtitles();
// Original name: bars_in
void showBars();
void sundcurs(int16 x, int16 y);
void rundcurs();
void unglow();
void glow(int16 index);
void setGlowX(int16 value);
void setGlowY(int16 value);
// Original name : blackbars
void drawBlackBars();
// Original name: bars_out
void hideBars();
// Original name: afsalle
void displayRoom();
// Original name: af_image
void displayImage();
void effetpix();
// Original name: effet1
void displayEffect1();
// Original name: effet2
void displayEffect2();
void setShowBlackBars(bool value);
bool getShowBlackBars();
void paneltobuf();
void cursbuftopanel();
void langbuftopanel();
View *getSubtitlesView();
View *getMainView();
byte *getHnmViewBuf();
void setCurCharRect(Common::Rect *charRect);
void setPaletteColor(byte *buffer);
// Original name: sauvefondbouche
void saveMouthBackground();
// Original name: restaurefondbouche
void restoreMouthBackground();
void openWindow();
bool _savedUnderSubtitles;
void setSavedUnderSubtitles(bool value);
byte *getSubtitlesViewBuf();
View *getUnderBarsView();
void SendPalette2Screen(int16 value);
void setFade(bool value);
bool getFade();
// Original name: effet3
void displayEffect3();
void setDestRect(int16 sx, int16 sy, int16 ex, int16 ey);
void setSrcRect(int16 sx, int16 sy, int16 ex, int16 ey);
void fadeToBlack(int delay);
// Original name: fadetoblack128
void fadeToBlackLowPalette(int delay);
// Original name: fadefromblack128
void fadeFromBlackLowPalette(int delay);
void clearScreen();
void playHNM(int16 num);
void setCursKeepPos(int16 x, int16 y);
void restoreUnderSubtitles();
void initRects();
void initGlobals();
void saveTopFrieze(int16 x);
void saveBottomFrieze();
void restoreTopFrieze();
void restoreBottomFrieze();
private:
EdenGame *_game;
int16 _glowX;
int16 _glowY;
int16 _glowW;
int16 _glowH;
bool _showVideoSubtitle;
Common::Point _cursKeepPos;
View *_mainView;
View *_underSubtitlesView;
View *_subtitlesView;
View *_underBarsView;
Common::Rect _underSubtitlesScreenRect;
Common::Rect _underSubtitlesBackupRect;
Common::Rect _underTopBarScreenRect;
Common::Rect _underBottomBarBackupRect;
Common::Rect _underBottomBarScreenRect;
Common::Rect _underTopBarBackupRect;
byte *_underSubtitlesViewBuf; // CHECKME: Useless?
byte *_mainViewBuf;
View *_hnmView;
byte *_hnmViewBuf;
byte *_view2Buf;
Common::Rect *_curCharacterRect;
Common::Rect _rect_dst, _rect_src;
View *_view2;
int _hnmFrameNum;
bool _videoCanceledFlag; //TODO: hnm_canceled
color_t _globalPalette[256]; //TODO palette_t
byte *_subtitlesViewBuf;
bool _needToFade;
int _eff2pat;
color3_t _newColor;
color_t _oldPalette[256]; // TODO palette_t ?
color_t _newPalette[256];
bool _showBlackBars;
void saveUnderSubtitles(int16 y);
void displayHNMSubtitle();
void readPalette(byte *ptr);
void getglow(int16 x, int16 y, int16 w, int16 h);
void loadMouthRectFromCurChar();
// Original name afsalle1
void displaySingleRoom(Room *room);
// Original name: effet4
void displayEffect4();
void colimacon(const int16 pattern[]);
// Original name: rectanglenoir32
void blackRect32();
////// film.c
// Original name: showfilm
void showMovie(int16 num, char arg1);
// Original name bullehnm
void handleHNMSubtitles();
};
} // namespace Cryo
#endif // CRYO_EDEN_GRAPHICS_H

View File

@@ -0,0 +1,61 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "base/plugins.h"
#include "engines/advancedDetector.h"
#include "common/file.h"
#include "cryo/cryo.h"
namespace Cryo {
const char *CryoEngine::getGameId() const { return _gameDescription->gameId; }
bool CryoEngine::isDemo() const { return _gameDescription->flags & ADGF_DEMO; }
Common::Platform CryoEngine::getPlatform() const { return _gameDescription->platform; }
} // End of namespace Cryo
class CryoMetaEngine : public AdvancedMetaEngine<ADGameDescription> {
public:
const char *getName() const override {
return "cryo";
}
bool hasFeature(MetaEngineFeature f) const override;
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
};
bool CryoMetaEngine::hasFeature(MetaEngineFeature f) const {
return false;
}
Common::Error CryoMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
*engine = new Cryo::CryoEngine(syst, desc);
return Common::kNoError;
}
#if PLUGIN_ENABLED_DYNAMIC(CRYO)
REGISTER_PLUGIN_DYNAMIC(CRYO, PLUGIN_TYPE_ENGINE, CryoMetaEngine);
#else
REGISTER_PLUGIN_STATIC(CRYO, PLUGIN_TYPE_ENGINE, CryoMetaEngine);
#endif

22
engines/cryo/module.mk Normal file
View File

@@ -0,0 +1,22 @@
MODULE := engines/cryo
MODULE_OBJS = \
cryo.o \
cryolib.o \
debugger.o \
eden.o \
eden_graphics.o \
metaengine.o \
resource.o \
sound.o
# This module can be built as a plugin
ifeq ($(ENABLE_CRYO), DYNAMIC_PLUGIN)
PLUGIN := 1
endif
# Include common rules
include $(srcdir)/rules.mk
# Detection objects
DETECT_OBJS += $(MODULE)/detection.o

42
engines/cryo/platdefs.h Normal file
View File

@@ -0,0 +1,42 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYO_PLATDEFS_H
#define CRYO_PLATDEFS_H
namespace Cryo {
#if 1
const int _subtitlesXMargin = 16; //PC
const int _subtitlesXScrMargin = 16;
const int _spaceWidth = 6;
#define FAKE_DOS_VERSION
#else
const int _subtitlesXMargin = 16; //MAC
const int _subtitlesXScrMargin = 16; //MAC
const int _spaceWidth = 4;
#endif
const int _subtitlesXWidth = (320 - _subtitlesXMargin * 2);
const int _subtitlesXCenter = _subtitlesXWidth / 2;
} // End of namespace Cryo
#endif

550
engines/cryo/resource.cpp Normal file
View File

@@ -0,0 +1,550 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "cryo/defs.h"
#include "cryo/cryo.h"
#include "cryo/cryolib.h"
#include "cryo/eden.h"
#include "common/substream.h"
namespace Cryo {
#define CRYO_DAT_VER 1 // 32-bit integer
// Original name: prechargephrases
void EdenGame::preloadDialogs(int16 vid) {
perso_t *perso = &_persons[PER_MORKUS];
if (vid == 170)
perso = &_persons[PER_UNKN_156];
_globals->_characterPtr = perso;
_globals->_dialogType = DialogType::dtInspect;
int num = (perso->_id << 3) | _globals->_dialogType;
Dialog *dial = (Dialog *)getElem(_gameDialogs, num);
dialoscansvmas(dial);
}
////// datfile.c
void EdenGame::verifh(byte *ptr) {
byte sum = 0;
byte *head = ptr;
for (int8 i = 0; i < 6; i++)
sum += *head++;
if (sum != 0xAB)
return;
debug("* Begin unpacking resource");
head -= 6;
uint16 h0 = READ_LE_UINT16(head);
// 3 = 2 bytes for the uint16 and 1 byte for an unused char
head += 3;
uint16 h3 = READ_LE_UINT16(head);
head += 2;
byte *data = h0 + head + 26;
h3 -= 6;
head += h3;
for (; h3; h3--)
*data-- = *head--;
head = data + 1;
data = ptr;
expandHSQ(head, data);
}
void EdenGame::openbigfile() {
_bigfile.open("EDEN.DAT");
char buf[16];
int count = _bigfile.readUint16LE();
_bigfileHeader = new PakHeaderNode(count);
for (int j = 0; j < count; j++) {
for (int k = 0; k < 16; k++)
buf[k] = _bigfile.readByte();
_bigfileHeader->_files[j]._name = Common::String(buf);
_bigfileHeader->_files[j]._size = _bigfile.readUint32LE();
_bigfileHeader->_files[j]._offs = _bigfile.readUint32LE();
_bigfileHeader->_files[j]._flag = _bigfile.readByte();
}
}
void EdenGame::closebigfile() {
_bigfile.close();
}
int EdenGame::loadmusicfile(int16 num) {
PakHeaderItem *file = &_bigfileHeader->_files[num + 435];
int32 size = file->_size;
int32 offs = file->_offs;
_bigfile.seek(offs, SEEK_SET);
uint32 numread = size;
if (numread > kMaxMusicSize)
error("Music file %s is too big", file->_name.c_str());
_bigfile.read(_musicBuf, numread);
return size;
}
void EdenGame::loadRawFile(uint16 num, byte *buffer) {
if (_vm->getPlatform() == Common::kPlatformDOS) {
if ((_vm->isDemo() && num > 2204) || num > 2472)
error("Trying to read invalid game resource");
}
assert(num < _bigfileHeader->_count);
PakHeaderItem *file = &_bigfileHeader->_files[num];
int32 size = file->_size;
int32 offs = file->_offs;
_bigfile.seek(offs, SEEK_SET);
_bigfile.read(buffer, size);
}
void EdenGame::loadIconFile(uint16 num, Icon *buffer) {
if (_vm->getPlatform() == Common::kPlatformDOS) {
if ((_vm->isDemo() && num > 2204) || num > 2472)
error("Trying to read invalid game resource");
}
assert(num < _bigfileHeader->_count);
PakHeaderItem *file = &_bigfileHeader->_files[num];
int32 size = file->_size;
int32 offs = file->_offs;
debug("* Loading icon - Resource %d (%s) at 0x%X, %d bytes", num, file->_name.c_str(), offs, size);
_bigfile.seek(offs, SEEK_SET);
int count = size / 18; // sizeof(Icon)
for (int i = 0; i < count; i++) {
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
buffer[i].sx = _bigfile.readSint16BE();
buffer[i].sy = _bigfile.readSint16BE();
buffer[i].ex = _bigfile.readSint16BE();
buffer[i].ey = _bigfile.readSint16BE();
buffer[i]._cursorId = _bigfile.readUint16BE();
buffer[i]._actionId = _bigfile.readUint32BE();
buffer[i]._objectId = _bigfile.readUint32BE();
}
else {
buffer[i].sx = _bigfile.readSint16LE();
buffer[i].sy = _bigfile.readSint16LE();
buffer[i].ex = _bigfile.readSint16LE();
buffer[i].ey = _bigfile.readSint16LE();
buffer[i]._cursorId = _bigfile.readUint16LE();
buffer[i]._actionId = _bigfile.readUint32LE();
buffer[i]._objectId = _bigfile.readUint32LE();
}
}
}
void EdenGame::loadRoomFile(uint16 num, Room *buffer) {
if (_vm->getPlatform() == Common::kPlatformDOS) {
if ((_vm->isDemo() && num > 2204) || num > 2472)
error("Trying to read invalid game resource");
}
assert(num < _bigfileHeader->_count);
PakHeaderItem *file = &_bigfileHeader->_files[num];
int32 size = file->_size;
int32 offs = file->_offs;
debug("* Loading room - Resource %d (%s) at 0x%X, %d bytes", num, file->_name.c_str(), offs, size);
_bigfile.seek(offs, SEEK_SET);
int count = size / 14; // sizeof(Room)
for (int i = 0; i < count; i++) {
buffer[i]._id = _bigfile.readByte();
for (int j = 0; j < 4; j++)
buffer[i]._exits[j] = _bigfile.readByte();
buffer[i]._flags = _bigfile.readByte();
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
buffer[i]._bank = _bigfile.readUint16BE();
buffer[i]._party = _bigfile.readUint16BE();
}
else {
buffer[i]._bank = _bigfile.readUint16LE();
buffer[i]._party = _bigfile.readUint16LE();
}
buffer[i]._level = _bigfile.readByte();
buffer[i]._video = _bigfile.readByte();
buffer[i]._location = _bigfile.readByte();
buffer[i]._backgroundBankNum = _bigfile.readByte();
}
}
Common::SeekableReadStream *EdenGame::loadSubStream(uint16 resNum) {
assert(resNum < _bigfileHeader->_count);
PakHeaderItem *file = &_bigfileHeader->_files[resNum];
int size = file->_size;
int offs = file->_offs;
debug("* Loading file %s at 0x%X, %d bytes", file->_name.c_str(), (uint)offs, size);
return new Common::SafeSeekableSubReadStream(&_bigfile, offs, offs + size, DisposeAfterUse::NO);
}
// Original name: ssndfl
int EdenGame::loadSound(uint16 num) {
unsigned int resNum = num - 1 + ((_vm->getPlatform() == Common::kPlatformDOS && _vm->isDemo()) ? 656 : 661);
assert(resNum < _bigfileHeader->_count);
PakHeaderItem *file = &_bigfileHeader->_files[resNum];
int32 size = file->_size;
int32 offs = file->_offs;
debug("* Loading sound %d (%s) at 0x%X, %d bytes", num, file->_name.c_str(), (uint)offs, size);
if (_soundAllocated) {
free(_voiceSamplesBuffer);
_voiceSamplesBuffer = nullptr;
_soundAllocated = false; //TODO: bug??? no alloc
}
else {
_voiceSamplesBuffer = (byte *)malloc(size);
_soundAllocated = true;
}
_bigfile.seek(offs, SEEK_SET);
//For PC loaded data is a VOC file, on Mac version this is a raw samples
if (_vm->getPlatform() == Common::kPlatformMacintosh)
_bigfile.read(_voiceSamplesBuffer, size);
else {
// VOC files also include extra information for lipsync
// 1. Standard VOC header
_bigfile.read(_voiceSamplesBuffer, 0x1A);
// 2. Lipsync?
unsigned char chunkType = _bigfile.readByte();
uint32 val = 0;
_bigfile.read(&val, 3);
unsigned int chunkLen = FROM_LE_32(val);
if (chunkType == 5) {
_bigfile.read(_gameLipsync + 7260, chunkLen);
chunkType = _bigfile.readByte();
_bigfile.read(&val, 3);
chunkLen = FROM_LE_32(val);
}
// 3. Normal sound data
if (chunkType == 1) {
_bigfile.readUint16LE();
size = chunkLen - 2;
_bigfile.read(_voiceSamplesBuffer, size);
}
}
return size;
}
void EdenGame::convertMacToPC() {
// Convert all mac (big-endian) resources to native format
// Array of longs
int *p = (int *)_gameLipsync;
for (int i = 0; i < 7240 / 4; i++)
p[i] = FROM_BE_32(p[i]);
}
void EdenGame::loadpermfiles() {
Common::File f;
const int kNumIcons = 136;
const int kNumRooms = 424;
const int kNumFollowers = 15;
const int kNumLabyrinthPath = 70;
const int kNumDinoSpeedForCitaLevel = 16;
const int kNumTabletView = 12;
const int kNumPersoRoomBankTable = 84;
const int kNumGotos = 130;
const int kNumObjects = 42;
const int kNumObjectLocations = 45;
const int kNumPersons = 58;
const int kNumCitadel = 7;
const int kNumCharacterRects = 19;
const int kNumCharacters = 20;
const int kNumAreas = 12;
// tab_2CEF0
// tab_2CF70
const int kNumActionCursors = 299;
const int expectedDataSize =
kNumIcons * 18 + // sizeof(Icon)
kNumRooms * 14 + // sizeof(Room)
kNumFollowers * 16 + // sizeof(Follower)
kNumLabyrinthPath +
kNumDinoSpeedForCitaLevel +
kNumTabletView +
kNumPersoRoomBankTable +
kNumGotos * 5 + // sizeof(Goto)
kNumObjects * 12 + // sizeof(object_t)
kNumObjectLocations * 2 +
kNumPersons * 18 + // sizeof(perso_t)
kNumCitadel * 34 + // sizeof(Citadel)
kNumCharacterRects * 8 +
kNumCharacters * 5 +
kNumAreas * 10 + // (sizeof(Area) - 4)
64 * 2 +
64 * 2 +
kNumActionCursors +
12 +
3 * 6 * 2 * 3 * 2;
if (f.open("cryo.dat")) {
const int dataSize = f.size() - 8 - 4; // CRYODATA + version
char headerId[9];
f.read(headerId, 8);
headerId[8] = '\0';
if (strcmp(headerId, "CRYODATA"))
error("Invalid cryo.dat aux data file");
if (f.readUint32LE() != CRYO_DAT_VER)
error("Incorrect data version for cryo.dat");
if (dataSize != expectedDataSize)
error("Mismatching data in cryo.dat aux data file (got %d, expected %d)", dataSize, expectedDataSize);
}
else
error("Can not load cryo.dat");
switch (_vm->getPlatform()) {
case Common::kPlatformDOS:
// Since PC version stores hotspots and rooms info in the executable, load them from premade resource file
for (int i = 0; i < kNumIcons; i++) {
_gameIcons[i].sx = f.readSint16LE();
_gameIcons[i].sy = f.readSint16LE();
_gameIcons[i].ex = f.readSint16LE();
_gameIcons[i].ey = f.readSint16LE();
_gameIcons[i]._cursorId = f.readUint16LE();
_gameIcons[i]._actionId = f.readUint32LE();
_gameIcons[i]._objectId = f.readUint32LE();
}
for (int i = 0; i < kNumRooms; i++) {
_gameRooms[i]._id = f.readByte();
for (int j = 0; j < 4; j++)
_gameRooms[i]._exits[j] = f.readByte();
_gameRooms[i]._flags = f.readByte();
_gameRooms[i]._bank = f.readUint16LE();
_gameRooms[i]._party = f.readUint16LE();
_gameRooms[i]._level = f.readByte();
_gameRooms[i]._video = f.readByte();
_gameRooms[i]._location = f.readByte();
_gameRooms[i]._backgroundBankNum = f.readByte();
}
break;
case Common::kPlatformMacintosh:
loadIconFile(2498, _gameIcons);
loadRoomFile(2497, _gameRooms);
loadRawFile(2486, _gameLipsync);
convertMacToPC();
// Skip the icons and rooms of the DOS version
f.skip(kNumIcons * 14 + kNumRooms * 11);
break;
default:
error("Unsupported platform");
}
// Read the common static data
for (int i = 0; i < kNumFollowers; i++) {
_followerList[i]._id = f.readSByte();
_followerList[i]._spriteNum = f.readSByte();
_followerList[i].sx = f.readSint16LE();
_followerList[i].sy = f.readSint16LE();
_followerList[i].ex = f.readSint16LE();
_followerList[i].ey = f.readSint16LE();
_followerList[i]._spriteBank = f.readSint16LE();
_followerList[i].ff_C = f.readSint16LE();
_followerList[i].ff_E = f.readSint16LE();
}
f.read(_labyrinthPath, kNumLabyrinthPath);
f.read(_dinoSpeedForCitadelLevel, kNumDinoSpeedForCitaLevel);
f.read(_tabletView, kNumTabletView);
f.read(_personRoomBankTable, kNumPersoRoomBankTable);
f.read(_gotos, kNumGotos * 5); // sizeof(Goto)
for (int i = 0; i < kNumObjects; i++) {
_objects[i]._id = f.readByte();
_objects[i]._flags = f.readByte();
_objects[i]._locations = f.readUint32LE();
_objects[i]._itemMask = f.readUint16LE();
_objects[i]._powerMask = f.readUint16LE();
_objects[i]._count = f.readSint16LE();
}
for (int i = 0; i < kNumObjectLocations; i++) {
_objectLocations[i] = f.readUint16LE();
}
for (int i = 0; i < kNumPersons; i++) {
_persons[i]._roomNum = f.readUint16LE();
_persons[i]._actionId = f.readUint16LE();
_persons[i]._partyMask = f.readUint16LE();
_persons[i]._id = f.readByte();
_persons[i]._flags = f.readByte();
_persons[i]._roomBankId = f.readByte();
_persons[i]._spriteBank = f.readByte();
_persons[i]._items = f.readUint16LE();
_persons[i]._powers = f.readUint16LE();
_persons[i]._targetLoc = f.readByte();
_persons[i]._lastLoc = f.readByte();
_persons[i]._speed = f.readByte();
_persons[i]._steps = f.readByte();
}
for (int i = 0; i < kNumCitadel; i++) {
_citadelList[i]._id = f.readSint16LE();
for (int j = 0; j < 8; j++)
_citadelList[i]._bank[j] = f.readSint16LE();
for (int j = 0; j < 8; j++)
_citadelList[i]._video[j] = f.readSint16LE();
}
for (int i = 0; i < kNumCharacterRects; i++) {
_characterRects[i].left = f.readSint16LE();
_characterRects[i].top = f.readSint16LE();
_characterRects[i].right = f.readSint16LE();
_characterRects[i].bottom = f.readSint16LE();
}
f.read(_characterArray, kNumCharacters * 5);
for (int i = 0; i < kNumAreas; i++) {
_areasTable[i]._num = f.readByte();
_areasTable[i]._type = f.readByte();
_areasTable[i]._flags = f.readUint16LE();
_areasTable[i]._firstRoomIdx = f.readUint16LE();
_areasTable[i]._citadelLevel = f.readByte();
_areasTable[i]._placeNum = f.readByte();
_areasTable[i]._citadelRoomPtr = nullptr;
_areasTable[i]._visitCount = f.readSint16LE();
}
for (int i = 0; i < 64; i++) {
tab_2CEF0[i] = f.readSint16LE();
}
for (int i = 0; i < 64; i++) {
tab_2CF70[i] = f.readSint16LE();
}
f.read(_actionCursors, kNumActionCursors);
f.read(_mapMode, 12);
f.read(_cubeTextureCoords, 3 * 6 * 2 * 3 * 2);
f.close();
loadRawFile(0, _mainBankBuf);
loadRawFile(402, _gameFont);
loadRawFile(404, _gameDialogs);
loadRawFile(403, _gameConditions);
}
bool EdenGame::ReadDataSyncVOC(unsigned int num) {
unsigned int resNum = num - 1 + ((_vm->getPlatform() == Common::kPlatformDOS && _vm->isDemo()) ? 656 : 661);
unsigned char vocHeader[0x1A];
int filePos = 0;
loadpartoffile(resNum, vocHeader, filePos, sizeof(vocHeader));
filePos += sizeof(vocHeader);
unsigned char chunkType = 0;
loadpartoffile(resNum, &chunkType, sizeof(vocHeader), 1);
filePos++;
if (chunkType == 5) {
uint32 chunkLen = 0;
loadpartoffile(resNum, &chunkLen, filePos, 3);
filePos += 3;
chunkLen = FROM_LE_32(chunkLen);
loadpartoffile(resNum, _gameLipsync + 7260, filePos, chunkLen);
return true;
}
return false;
}
bool EdenGame::ReadDataSync(uint16 num) {
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
long pos = READ_LE_UINT32(_gameLipsync + num * 4);
if (pos != -1) {
long len = 1024;
loadpartoffile(1936, _gameLipsync + 7260, pos, len);
return true;
}
}
else
return ReadDataSyncVOC(num + 1); //TODO: remove -1 in caller
return false;
}
void EdenGame::loadpartoffile(uint16 num, void *buffer, int32 pos, int32 len) {
assert(num < _bigfileHeader->_count);
PakHeaderItem *file = &_bigfileHeader->_files[num];
int32 offs = READ_LE_UINT32(&file->_offs);
debug("* Loading partial resource %d (%s) at 0x%X(+0x%X), %d bytes", num, file->_name.c_str(), offs, pos, len);
_bigfile.seek(offs + pos, SEEK_SET);
_bigfile.read(buffer, len);
}
void EdenGame::expandHSQ(byte *input, byte *output) {
byte *src = input;
byte *dst = output;
byte *ptr;
uint16 bit; // bit
uint16 queue = 0; // queue
uint16 len = 0;
int16 ofs;
#define GetBit \
bit = queue & 1; \
queue >>= 1; \
if (!queue) { \
queue = (src[1] << 8) | src[0]; src += 2; \
bit = queue & 1; \
queue = (queue >> 1) | 0x8000; \
}
for (;;) {
GetBit;
if (bit)
*dst++ = *src++;
else {
len = 0;
GetBit;
if (!bit) {
GetBit;
len = (len << 1) | bit;
GetBit;
len = (len << 1) | bit;
ofs = 0xFF00 | *src++; //TODO: -256
}
else {
ofs = (src[1] << 8) | src[0];
src += 2;
len = ofs & 7;
ofs = (ofs >> 3) | 0xE000;
if (!len) {
len = *src++;
if (!len)
break;
}
}
ptr = dst + ofs;
len += 2;
while (len--)
*dst++ = *ptr++;
}
}
}
} // namespace Cryo

112
engines/cryo/sound.cpp Normal file
View File

@@ -0,0 +1,112 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "cryo/sound.h"
#include "audio/audiostream.h"
#include "audio/mixer.h"
#include "audio/decoders/raw.h"
namespace Cryo {
CSoundChannel::CSoundChannel(Audio::Mixer *mixer, unsigned int sampleRate, bool stereo, bool is16bits) : _mixer(mixer), _sampleRate(sampleRate), _stereo(stereo) {
_bufferFlags = is16bits ? (Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_16BITS) : Audio::FLAG_UNSIGNED;
if (stereo)
_bufferFlags |= Audio::FLAG_STEREO;
_audioStream = nullptr;
_volumeLeft = _volumeRight = Audio::Mixer::kMaxChannelVolume;
}
CSoundChannel::~CSoundChannel() {
stop();
if (_audioStream)
delete _audioStream;
}
void CSoundChannel::queueBuffer(byte *buffer, unsigned int size, bool playNow, bool playQueue, bool buffering) {
if (playNow)
stop();
if (!buffer || !size)
return;
if (!_audioStream)
_audioStream = Audio::makeQueuingAudioStream(_sampleRate, _stereo);
if (buffering) {
byte *localBuffer = (byte*)malloc(size);
memcpy(localBuffer, buffer, size);
_audioStream->queueBuffer(localBuffer, size, DisposeAfterUse::YES, _bufferFlags);
} else
_audioStream->queueBuffer(buffer, size, DisposeAfterUse::NO, _bufferFlags);
if (playNow || playQueue)
play();
}
void CSoundChannel::play() {
if (!_audioStream)
return;
if (!_mixer->isSoundHandleActive(_soundHandle)) {
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, _audioStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
applyVolumeChange();
}
}
void CSoundChannel::stop() {
if (_mixer->isSoundHandleActive(_soundHandle))
_mixer->stopHandle(_soundHandle);
if (_audioStream) {
_audioStream->finish();
delete _audioStream;
_audioStream = nullptr;
}
}
unsigned int CSoundChannel::numQueued() {
return _audioStream ? _audioStream->numQueuedStreams() : 0;
}
unsigned int CSoundChannel::getVolume() {
return (_volumeRight + _volumeLeft) / 2;
}
void CSoundChannel::setVolume(unsigned int volumeLeft, unsigned int volumeRight) {
_volumeLeft = volumeLeft;
_volumeRight = volumeRight;
applyVolumeChange();
}
void CSoundChannel::setVolumeLeft(unsigned int volume) {
setVolume(volume, _volumeRight);
}
void CSoundChannel::setVolumeRight(unsigned int volume) {
setVolume(_volumeLeft, volume);
}
void CSoundChannel::applyVolumeChange() {
unsigned int volume = (_volumeRight + _volumeLeft) / 2;
int balance = (signed int)(_volumeRight - _volumeLeft) / 2;
_mixer->setChannelVolume(_soundHandle, volume);
_mixer->setChannelBalance(_soundHandle, balance);
}
}

69
engines/cryo/sound.h Normal file
View File

@@ -0,0 +1,69 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "audio/audiostream.h"
#include "audio/mixer.h"
#include "audio/decoders/raw.h"
#include "cryo/cryolib.h"
namespace Cryo {
class CryoEngine;
class CSoundChannel {
private:
Audio::Mixer *_mixer;
Audio::QueuingAudioStream *_audioStream;
Audio::SoundHandle _soundHandle;
unsigned int _sampleRate;
bool _stereo;
unsigned int _bufferFlags;
void applyVolumeChange();
public:
CSoundChannel(Audio::Mixer *mixer, unsigned int sampleRate, bool stereo, bool is16bits = false);
~CSoundChannel();
// Queue a new buffer, cancel any previously queued buffers if playNow is set
void queueBuffer(byte *buffer, unsigned int size, bool playNow = false, bool playQueue = true, bool buffering = true);
// Play any queued buffers
void play();
// Stop playing and purge play queue
void stop();
// How many buffers in queue (including currently playing one)
unsigned int numQueued();
// Volume control
int _volumeLeft, _volumeRight;
unsigned int getVolume();
void setVolume(unsigned int volumeLeft, unsigned int volumeRight);
void setVolumeLeft(unsigned int volume);
void setVolumeRight(unsigned int volume);
};
}