Merge pull request #892 from Retro-Junk/cryo

CRYO: New engine
This commit is contained in:
Eugene Sandulenko 2017-02-07 21:19:22 +01:00 committed by GitHub
commit b3784db8d5
28 changed files with 14727 additions and 0 deletions

View File

@ -0,0 +1,105 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include <stdio.h>
#include "eden.h"
#include "eden_icons.h"
#include "eden_rooms.h"
template <typename T>
static void writeLE(FILE *f, T value) {
for (int i = 0; i < sizeof(value); i++, value >>= 8) {
unsigned char b = value & 0xFF;
fwrite(&b, 1, 1, f);
}
}
struct _icon_t : icon_t {
void write(FILE *f) {
writeLE<int16>(f, sx);
writeLE<int16>(f, sy);
writeLE<int16>(f, ex);
writeLE<int16>(f, ey);
writeLE<uint16>(f, cursor_id);
writeLE<unsigned int>(f, action_id);
writeLE<unsigned int>(f, object_id);
}
};
static void emitIcons(FILE *f) {
_icon_t *icons = (_icon_t*)gameIcons;
for (int i = 0; i < kNumIcons; i++)
icons[i].write(f);
}
struct _room_t : room_t {
void write(FILE *f) {
writeLE<byte>(f, ff_0);
writeLE<byte>(f, exits[0]);
writeLE<byte>(f, exits[1]);
writeLE<byte>(f, exits[2]);
writeLE<byte>(f, exits[3]);
writeLE<byte>(f, flags);
writeLE<uint16>(f, bank);
writeLE<uint16>(f, party);
writeLE<byte>(f, level);
writeLE<byte>(f, video);
writeLE<byte>(f, location);
writeLE<byte>(f, background);
}
};
static void emitRooms(FILE *f) {
_room_t *rooms = (_room_t*)gameRooms;
for (int i = 0; i < kNumRooms; i++)
rooms[i].write(f);
}
static int emitData(char *outputFilename) {
FILE *f = fopen(outputFilename, "w+b");
if (!f) {
printf("ERROR: Unable to create output file %s\n", outputFilename);
return 1;
}
printf("Generating %s...\n", outputFilename);
emitIcons(f);
emitRooms(f);
fclose(f);
printf("Done!\n");
return 0;
}
int main(int argc, char **argv) {
if (argc > 1)
return emitData(argv[1]);
else
printf("Usage: %s <output.dat>\n", argv[0]);
return 0;
}

View File

@ -0,0 +1,51 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#pragma once
typedef unsigned char byte;
typedef short int16;
typedef unsigned short uint16;
struct icon_t {
int16 sx;
int16 sy;
int16 ex;
int16 ey;
uint16 cursor_id; // & 0x8000 - inactive/hidden
unsigned int action_id;
unsigned int object_id;
};
#define END_ICONS {-1, -1, -1, -1, 0, 0, 0}
struct room_t {
byte ff_0;
byte exits[4];
byte flags;
uint16 bank;
uint16 party;
byte level;
byte video;
byte location;
byte background;
};
#define END_ROOMS {0xFF, {0xFF, 0xFF, 0xFF, 0xFF}, 0xFF, 0xFFFF, 0xFFFF, 0xFF, 0xFF, 0xFF, 0xFF}

View File

@ -0,0 +1,236 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#pragma once
#include "eden.h"
// Note: the following data can be found in the original game's executable
// NB! this enum must match kActionCursors[] array
enum kCursors { // offset in the executable
cuNone = 0, // 0x51F
cu1 = 1, // 0x563
cu2 = 2, // 0x556
cu3 = 3, // 0x549
cu4 = 4, // 0x570
cu5 = 5, // 0x57D
cuHand = 6, // 0x502
cu7 = 7, // 0x52C
cu8 = 8, // 0x58A
cu9 = 9, // 0x539
cuFa = 0xF, // 0x50F
cuFinger = 53, // 0x541
ICON_HIDDEN = 0x8000
};
// NB! this enum must match EdenGame::*mouse_actions[] array
enum kActions { // offset in the executable
ac_ret = 27, // 0xD651
ac_clicplanval = 139, // 0xE068
ac_endFrescoes = 140, // 0xB12A
ac_choisir = 141, // 0xDD68
ac_parle_moi = 246, // 0xBFE
ac_adam = 247, // 0x9E4
ac_takeobject = 248, // 0xE66B
ac_putobject = 249, // 0xE681
ac_clictimbre = 250, // 0xE03F
ac_dinaparle = 251, // 0xDF32
ac_close_perso = 252, // 0x13EC
ac_generique = 260, // 0xAF51
ac_choixsubtitle = 261, // 0xACBF
ac_EdenQuit = 262, // 0xAF6D
ac_restart = 263, // 0xAEE7
ac_cancel2 = 264, // 0xACE8
ac_testvoice = 265, // 0xACF8
ac_reglervol = 266, // 0xAB9E
ac_load = 267, // 0xAD76
ac_save = 268, // 0xAD40
ac_cliccurstape = 269, // 0xB004
ac_playtape = 270, // 0x19DB
ac_stoptape = 271, // 0xB095
ac_rewindtape = 272, // 0xB0C9
ac_forwardtape = 273, // 0xB0E3
ac_confirmyes = 274, // 0xADAE
ac_confirmno = 275, // 0xADC1
ac_gotocarte = 276 // 0xE07E
};
// Indicies in to gotos[] array for World map areas
enum kTravel { // offset in the executable
goMo = 24, // 0x324D
goChamaar = 40, // 0x3287
goUluru = 51, // 0x32AF
goKoto = 65, // 0x32E3
goNarim = 70, // 0x32F5
goTamara = 75, // 0x3307
goCantura = 84, // 0x3329
goShandovra = 93, // 0x334B
goEmbalmers = 102, // 0x336D
goWhiteArch = 111, // 0x338F
goMoorkusLair = 120 // 0x33B1
};
const int kNumIcons = 136;
const icon_t gameIcons[kNumIcons] = {
{90, 50, 220, 150, cu8, ac_parle_moi, 0},
{0, 0, 319, 178, cuNone, ac_close_perso, 0},
END_ICONS,
{220, 16, 310, 176, cu5, ac_adam, 0},
{0, 0, 320, 200, cu8, ac_parle_moi, 0},
END_ICONS,
{215, 140, 245, 176, cuHand, ac_choisir, 0},
{245, 140, 275, 176, cuHand, ac_choisir, 1},
{275, 140, 305, 176, cuHand, ac_choisir, 2},
END_ICONS,
{245, 140, 275, 176, cuHand, ac_choisir, 0},
{275, 140, 305, 176, cuHand, ac_choisir, 1},
END_ICONS,
{0, 0, 320, 165, cuFa, ac_dinaparle, 0},
{0, 165, 320, 200, cu2, ac_endFrescoes, 0},
END_ICONS,
{0, 176, 319, 200, ICON_HIDDEN|cu9, ac_putobject, 0},
{120, 0, 200, 16, cuFinger, ac_clictimbre, 0},
{266, 0, 320, 16, ICON_HIDDEN|cuFinger, ac_clicplanval, 0},
// Inventory bar items
// Mac version displays only 9 items, with extra margins
{0, 178, 28, 200, cuHand, ac_takeobject, 0}, // Not on Mac
{30, 178, 57, 200, cuHand, ac_takeobject, 0},
{59, 178, 86, 200, cuHand, ac_takeobject, 0},
{88, 178, 115, 200, cuHand, ac_takeobject, 0},
{117, 178, 144, 200, cuHand, ac_takeobject, 0},
{146, 178, 173, 200, cuHand, ac_takeobject, 0},
{175, 178, 202, 200, cuHand, ac_takeobject, 0},
{204, 178, 231, 200, cuHand, ac_takeobject, 0},
{233, 178, 260, 200, cuHand, ac_takeobject, 0},
{262, 178, 289, 200, cuHand, ac_takeobject, 0},
{290, 178, 317, 200, cuHand, ac_takeobject, 0}, // Not on Mac
// reserve for room's icons
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
END_ICONS,
// Menu icons
{0, 0, 319, 15, cuFinger, ac_generique, 32},
{8, 42, 86, 51, cuFinger, ac_choixsubtitle, 16},
{8, 51, 86, 60, cuFinger, ac_choixsubtitle, 17},
{8, 60, 86, 69, cuFinger, ac_choixsubtitle, 18},
{8, 69, 86, 78, cuFinger, ac_choixsubtitle, 19},
{8, 78, 86, 87, cuFinger, ac_choixsubtitle, 20},
{8, 87, 86, 96, cuFinger, ac_choixsubtitle, 21},
{16, 137, 79, 148, cuFinger, ac_EdenQuit, 34},
{129, 137, 192, 148, cuFinger, ac_restart, 35},
{239, 137, 302, 148, cuFinger, ac_cancel2, 36},
{130, 112, 193, 123, cuFinger, ac_testvoice, 37},
{114, 40, 121, 110, cuFinger, ac_reglervol, 48},
{121, 40, 128, 110, cuFinger, ac_reglervol, 56},
{128, 40, 136, 110, cuFinger, ac_reglervol, 49},
{147, 40, 154, 110, cuFinger, ac_reglervol, 50},
{154, 40, 161, 110, cuFinger, ac_reglervol, 58},
{161, 40, 169, 110, cuFinger, ac_reglervol, 51},
{179, 40, 186, 110, cuFinger, ac_reglervol, 52},
{186, 40, 193, 110, cuFinger, ac_reglervol, 60},
{193, 40, 201, 110, cuFinger, ac_reglervol, 53},
{249, 42, 307, 51, cuFinger, ac_load, 65},
{249, 51, 307, 60, cuFinger, ac_load, 66},
{249, 60, 307, 69, cuFinger, ac_load, 67},
{231, 69, 307, 78, cuFinger, ac_load, 68},
{230, 104, 307, 112, cuFinger, ac_save, 81},
{230, 113, 307, 121, cuFinger, ac_save, 82},
{230, 122, 307, 130, cuFinger, ac_save, 83},
{0, 176, 0, 185, cuFinger, ac_cliccurstape, 100},
{149, 185, 166, 200, cuFinger, ac_playtape, 96},
{254, 185, 269, 200, cuFinger, ac_stoptape, 97},
{85, 185, 111, 200, cuFinger, ac_rewindtape, 98},
{204, 185, 229, 200, cuFinger, ac_forwardtape, 99},
{0, 0, 320, 200, cuFinger, ac_ret, 0},
END_ICONS,
// Yes/No dialog icons
{129, 84, 157, 98, cuFinger, ac_confirmyes, 0},
{165, 84, 188, 98, cuFinger, ac_confirmno, 113},
{0, 0, 320, 200, cuFinger, ac_ret, 0},
END_ICONS,
// World map hotspots
{136, 100, 160, 124, cu5, ac_gotocarte, goMo},
{150, 55, 174, 79, cu5, ac_gotocarte, goChamaar},
{186, 29, 210, 53, ICON_HIDDEN|cu5, ac_gotocarte, goUluru},
{217, 20, 241, 44, ICON_HIDDEN|cu5, ac_gotocarte, goKoto},
{248, 45, 272, 69, ICON_HIDDEN|cu5, ac_gotocarte, goNarim},
{233, 68, 257, 92, ICON_HIDDEN|cu5, ac_gotocarte, goTamara},
{235, 109, 259, 133, ICON_HIDDEN|cu5, ac_gotocarte, goCantura},
{163, 137, 187, 161, ICON_HIDDEN|cu5, ac_gotocarte, goEmbalmers},
{93, 145, 117, 169, ICON_HIDDEN|cu5, ac_gotocarte, goWhiteArch},
{70, 39, 94, 63, ICON_HIDDEN|cu5, ac_gotocarte, goShandovra},
{99, 8, 123, 32, ICON_HIDDEN|cu5, ac_gotocarte, goMoorkusLair},
{0, 0, 319, 199, cuNone, ac_close_perso, 0},
END_ICONS,
};

View File

@ -0,0 +1,465 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#pragma once
#include "eden.h"
// Note: the following data can be found in the original game's executable
const int kNumRooms = 424;
const room_t gameRooms[kNumRooms] = {
// Mo
{ 1, {255, 0, 0, 0}, 0, 66, 0xFFFF,29, 93, 1, 4},
{ 7, { 4, 0, 6, 0}, 4, 72, 0xFFFF, 8,143, 2, 2},
{ 3, { 24, 0, 5, 0}, 6, 99, 1, 6, 6, 3, 0},
{ 3, { 24, 0, 5, 0}, 6, 68, 0x21, 6,146, 3, 0},
{30, { 24, 0, 5, 0}, 2, 97, 9, 6,147, 3, 0},
{ 4, { 24, 0, 5, 0}, 2, 69, 0x29, 6,147, 3, 0},
{31, { 24, 0, 5, 0}, 2, 98, 8, 6,147, 3, 0},
{ 2, { 24, 0, 5, 0}, 2, 67, 0, 6,147, 3, 0},
{ 5, { 5, 20, 2, 8}, 4, 70, 0xFFFF, 7, 64, 4, 72},
{ 6, { 3, 7, 4, 9}, 4, 71, 0xFFFF, 5, 4, 5, 6},
{ 8, { 1, 0, 23, 2}, 4, 73, 0x400,23,145, 6, 2},
{29, { 1, 0, 0, 2}, 4, 96, 0, 0, 0, 6, 2},
{ 9, { 0, 0, 5, 0}, 0, 74, 0, 0,112, 7, 8},
{10, { 0, 0, 5, 0}, 0, 75, 0x20, 0,112, 7, 8},
{28, { 0, 0, 4, 0}, 0, 95, 0, 0, 0, 8, 10},
{11, { 0, 0, 4, 0}, 0, 76, 0x10, 5,110, 8, 10},
{27, { 11, 0, 5, 0}, 4, 94, 0,37,152, 9, 12},
{12, { 11, 0, 5, 0}, 4, 77, 8, 6, 5, 9, 12},
{27, { 11, 0, 5, 0}, 4, 94, 0xFFFF,37,152, 9, 12},
{13, { 13, 0, 12, 0}, 6, 78, 0,15, 10, 10, 48},
{14, { 12, 0, 9, 0}, 4, 79, 0,12, 9, 11, 12},
{15, { 10, 0, 11, 0}, 6, 80, 0,14, 12, 12, 16},
{16, { 14, 0, 10, 0}, 6, 81, 0,13, 11, 13, 14},
{17, { 15, 0, 13, 0}, 4, 82, 0, 0, 0, 14, 16},
{18, { 16, 0, 14, 0}, 4, 83, 0,17, 13, 15, 16},
{19, { 17, 0, 13, 0}, 0, 84, 0,18, 15, 16, 16},
{20, { 18, 0, 9, 0}, 4, 85, 0,19, 16, 17, 16},
{21, { 0, 1, 17, 0}, 0, 86, 0,20, 0, 18, 70},
{21, { 0, 1, 17, 0}, 6, 87, 2,20, 14, 18, 70},
{37, { 0, 0, 9, 0}, 0, 34, 0xFFFF, 0, 0, 19, 12},
{ 6, { 0, 0, 4, 0}, 4, 53, 0xFFFF, 5,156, 20, 72},
{22, {130, 0, 4, 0}, 0, 88, 0, 1, 0, 22, 46},
{22, {130, 0, 4, 0}, 4, 89, 2, 5, 8, 22, 46},
{23, { 6, 0, 0, 0}, 4, 90, 0xFFFF, 0, 0, 23, 2},
{24, {103, 25, 3, 0}, 6, 91, 0, 3, 1, 24, 0},
{25, { 0, 26, 3, 24}, 4, 92, 0,24, 2, 25, 0},
{26, { 0, 0, 3, 25}, 4, 93, 0,25, 3, 26, 0},
{32, { 0, 0, 89, 0}, 6,100, 0xFFFF, 0, 75, 32, 18},
{33, { 0, 0, 50, 0}, 6,105, 0xFFFF, 0, 26, 33, 20},
{33, { 0, 0, 51, 0}, 6,105, 0xFFFF, 0, 26, 34, 20},
{33, { 0, 0, 52, 0}, 6,105, 0xFFFF, 0, 26, 35, 20},
{33, { 0, 68, 53, 85}, 6,107, 0xFFFF, 0, 28, 36, 20},
{33, { 33, 0, 54, 86}, 6,109, 0xFFFF, 0, 30, 37, 20},
{33, { 34, 0, 55, 87}, 6,109, 0xFFFF, 0, 30, 38, 20},
{33, { 35, 71, 56, 88}, 6,106, 0xFFFF, 0, 27, 39, 20},
{33, { 36, 0, 57, 90}, 6,109, 0xFFFF, 0, 30, 40, 20},
{33, { 37, 74, 58, 91}, 6,106, 0xFFFF, 0, 27, 41, 20},
{33, { 0, 0, 59, 0}, 6,105, 0xFFFF, 0, 26, 42, 20},
{33, { 0, 0, 60, 0}, 6,105, 0xFFFF, 0, 26, 43, 20},
{33, { 0, 0, 61, 0}, 6,105, 0xFFFF, 0, 26, 44, 20},
{33, { 0, 0, 62, 0}, 6,105, 0xFFFF, 0, 26, 45, 20},
{33, { 42, 0, 63, 97}, 6,109, 0xFFFF, 0, 30, 46, 20},
{33, { 43, 80, 64, 0}, 6,108, 0xFFFF, 0, 29, 47, 20},
{33, { 44, 81, 65, 0}, 6,108, 0xFFFF, 0, 29, 48, 20},
{33, { 46, 83, 66,101}, 6,106, 0xFFFF, 0, 27, 49, 20},
{33, { 54, 86, 33, 0}, 6,108, 0xFFFF, 0, 29, 50, 20},
{33, { 55, 87, 34, 0}, 6,108, 0xFFFF, 0, 29, 51, 20},
{33, { 56, 88, 35, 71}, 6,106, 0xFFFF, 0, 27, 52, 20},
{33, { 57, 90, 36, 0}, 6,108, 0xFFFF, 0, 29, 53, 20},
{33, { 58, 91, 37, 74}, 6,106, 0xFFFF, 0, 27, 54, 20},
{33, { 0, 92, 38, 75}, 6,107, 0xFFFF, 0, 28, 55, 20},
{33, { 0, 93, 39, 76}, 6,107, 0xFFFF, 0, 28, 56, 20},
{33, { 0, 95, 40, 78}, 6,107, 0xFFFF, 0, 28, 57, 20},
{33, { 0, 96, 41, 79}, 6,110, 0xFFFF, 0, 59, 58, 20},
{33, { 63, 97, 42, 0}, 6,108, 0xFFFF, 0, 29, 59, 20},
{33, { 64, 0, 43, 80}, 6,109, 0xFFFF, 0, 30, 60, 20},
{33, { 65, 0, 44, 81}, 6,109, 0xFFFF, 0, 30, 61, 20},
{33, { 0, 99, 45, 82}, 6,107, 0xFFFF, 0, 28, 62, 20},
{33, { 66,100, 46, 83}, 6,106, 0xFFFF, 0, 27, 63, 20},
{33, { 0,101, 47, 84}, 6,107, 0xFFFF, 0, 28, 64, 20},
{33, { 3, 0, 48, 0}, 6,104, 0xFFFF, 0, 74, 65, 20},
{33, { 3, 0, 49, 0}, 6,104, 0xFFFF, 0, 74, 66, 20},
{33, { 68, 53, 85, 0}, 6,108, 0xFFFF, 0, 29, 67, 20},
{33, { 0, 54, 86, 33}, 6,107, 0xFFFF, 0, 28, 68, 20},
{33, { 0, 55, 87, 34}, 6,107, 0xFFFF, 0, 28, 69, 20},
{33, { 71, 56, 88, 35}, 6,106, 0xFFFF, 0, 27, 70, 20},
{33, { 32, 0, 89, 0}, 6,104, 0xFFFF, 0, 74, 71, 20},
{33, { 0, 57, 90, 36}, 6,107, 0xFFFF, 0, 28, 72, 20},
{33, { 74, 58, 91, 37}, 6,106, 0xFFFF, 0, 27, 73, 20},
{33, { 75, 0, 92, 38}, 6,109, 0xFFFF, 0, 30, 74, 20},
{33, { 76, 0, 93, 39}, 6,109, 0xFFFF, 0, 30, 75, 20},
{33, { 0, 0, 94, 0}, 6,105, 0xFFFF, 0, 26, 76, 20},
{33, { 78, 0, 95, 40}, 6,109, 0xFFFF, 0, 30, 77, 20},
{33, { 79, 0, 96, 41}, 6,112, 0xFFFF, 0, 61, 78, 20},
{33, { 0, 63, 97, 42}, 6,107, 0xFFFF, 0, 28, 79, 20},
{33, { 0, 0, 98, 0}, 6,105, 0xFFFF, 0, 26, 80, 20},
{33, { 82, 0, 99, 45}, 6,109, 0xFFFF, 0, 30, 81, 20},
{33, { 83, 66,100, 46}, 6,106, 0xFFFF, 0, 27, 82, 20},
{33, { 84, 0,101, 47}, 6,109, 0xFFFF, 0, 30, 83, 20},
{33, { 0, 0,102, 0}, 6,105, 0xFFFF, 0, 26, 84, 20},
{33, { 0, 0, 67, 0}, 6,105, 0xFFFF, 0, 26, 85, 20},
{33, { 85, 0, 68, 53}, 6,109, 0xFFFF, 0, 30, 86, 20},
{33, { 0, 0, 69, 0}, 6,105, 0xFFFF, 0, 26, 87, 20},
{33, { 0, 0, 70, 0}, 6,105, 0xFFFF, 0, 26, 88, 20},
{33, { 88, 35, 71, 56}, 6,106, 0xFFFF, 0, 27, 89, 20},
{33, { 0, 0, 72, 0}, 6,105, 0xFFFF, 0, 26, 90, 20},
{33, { 0, 0, 73, 0}, 6,105, 0xFFFF, 0, 26, 91, 20},
{33, { 91, 37, 74, 58}, 6,106, 0xFFFF, 0, 27, 92, 20},
{33, { 92, 38, 75, 0}, 6,108, 0xFFFF, 0, 29, 93, 20},
{33, { 93, 39, 76, 0}, 6,108, 0xFFFF, 0, 29, 94, 20},
{33, { 0, 0, 77, 0}, 6,105, 0xFFFF, 0, 26, 95, 20},
{33, { 95, 40, 78, 0}, 6,108, 0xFFFF, 0, 29, 96, 20},
{33, { 96, 41, 79, 0}, 6,111, 0xFFFF, 0, 60, 97, 20},
{33, { 0, 43, 80, 64}, 6,107, 0xFFFF, 0, 28, 98, 20},
{33, { 0, 44, 81, 65}, 6,107, 0xFFFF, 0, 28, 99, 20},
{33, { 99, 45, 82, 0}, 6,108, 0xFFFF, 0, 29,100, 20},
{33, {100, 46, 83, 66}, 6,106, 0xFFFF, 0, 27,101, 20},
{33, {101, 47, 84, 0}, 6,108, 0xFFFF, 0, 29,102, 20},
{34, { 49, 0, 3,104}, 0,101, 0xFFFF, 0, 0,103, 20},
{35, {105, 0,103, 0}, 0,102, 0xFFFF, 0, 0,104, 20},
{36, { 48, 0,104, 0}, 0,103, 0xFFFF, 0, 0,105, 20},
END_ROOMS,
// Tau's
{ 1, {2, 0,129, 0}, 4, 118, 0xFFFF, 22, 0, 1, 74},
{ 2, {0, 0, 1, 0}, 6, 119, 0xFFFF, 1, 34, 2, 56},
END_ROOMS,
// Narim's
{ 1, {2, 0,255, 0}, 4, 321, 0xFFFF, 1, 0, 1, 24},
{ 2, {0, 0, 1, 0}, 6, 324, 0xFFFF, 1, 32, 2, 66},
END_ROOMS,
// Embalmers
{ 1, {2, 0,129, 0}, 6, 243, 0xFFFF, 1, 0, 1, 62},
{ 2, {0, 0, 1, 0}, 4, 244, 0x200, 1, 49, 2, 58},
{ 2, {0, 0, 1, 0}, 0, 245, 0, 1, 0, 2, 58},
END_ROOMS,
// White Arch
{ 1, {0, 0,255, 0}, 6, 120, 0xFFFF, 1, 0, 1, 42},
{ 2, {3, 0, 0, 0}, 0, 231, 0xFFFF, 0, 0, 2, 20},
{ 3, {0, 0, 2, 0}, 6, 232, 0xFFFF, 0, 50, 3, 20},
{ 4, {0, 0, 0, 0}, 6, 233, 0xFFFF, 0, 96, 4, 44},
END_ROOMS,
// Moorkus Lair
{ 1, {255, 2, 0, 0}, 4, 121, 0x588, 1, 0, 1, 64},
{ 1, {255, 2, 0, 0}, 4, 323, 0xFFFF, 1, 0, 1, 64},
{ 2, { 3, 4, 0, 0}, 0, 122, 0xFFFF, 1, 90, 2, 60},
{ 3, { 0, 0, 0, 0}, 4, 123, 0xFFFF, 2, 91, 3, 60},
{ 4, { 0, 0, 2, 0}, 4, 320, 0xFFFF, 2,150, 4, 60},
END_ROOMS,
// Chamaar
{ 1, {255, 0, 0, 0}, 0x18, 17, 0xFFFF, 1, 0, 1, 68},
{ 2, {255, 0, 0, 0}, 0x18, 17, 0xFFFF, 0, 0, 1, 68},
{ 3, { 0, 17, 32, 0}, 0x81, 124, 0xFFFF, 0, 0, 16, 22},
{ 3, { 0, 18, 33, 16}, 0x81, 125, 0xFFFF, 0, 0, 17, 22},
{ 3, { 0, 19, 34, 17}, 0x81, 126, 0xFFFF, 0, 0, 18, 22},
{ 3, { 0, 20, 35, 18}, 0x86, 143, 0xFFFF, 0, 0, 19, 22},
{ 3, { 0, 21, 36, 19}, 0x81, 127, 0xFFFF, 0, 0, 20, 22},
{ 3, { 0, 22, 37, 20}, 0x81, 128, 0xFFFF, 0, 0, 21, 22},
{ 3, { 0, 23, 38, 21}, 0x81, 129, 0xFFFF, 0, 0, 22, 22},
{ 3, { 0, 24, 39, 22}, 0x81, 130, 0xFFFF, 0, 0, 23, 22},
{ 3, { 0, 25, 40, 23}, 0x81, 131, 0xFFFF, 0, 0, 24, 22},
{ 3, { 0, 26, 41, 24}, 0x81, 132, 0xFFFF, 0, 0, 25, 22},
{ 3, { 0, 27, 42, 25}, 0x81, 133, 0xFFFF, 0, 0, 26, 22},
{ 3, { 0, 0, 43, 26}, 0x81, 134, 0xFFFF, 0, 0, 27, 22},
{ 3, {16, 33, 48, 0}, 0xC1, 193, 0xFFFF, 0, 0, 32, 26},
{ 3, {17, 34, 49, 32}, 0x81, 135, 0xFFFF, 0, 0, 33, 22},
{ 3, {18, 35, 50, 33}, 0x81, 136, 0xFFFF, 0, 0, 34, 22},
{ 3, {19, 36, 51, 34}, 0x81, 137, 0xFFFF, 0, 0, 35, 22},
{ 3, {20, 37, 52, 35}, 0x81, 138, 0xFFFF, 0, 0, 36, 22},
{ 3, {21, 38, 53, 36}, 0x81, 139, 0xFFFF, 0, 0, 37, 22},
{ 3, {22, 39, 54, 37}, 0x81, 140, 0xFFFF, 0, 0, 38, 22},
{ 3, {23, 40, 55, 38}, 0x81, 141, 0xFFFF, 0, 0, 39, 22},
{ 3, {24, 41, 56, 39}, 0x81, 142, 0xFFFF, 0, 0, 40, 22},
{ 3, {25, 42, 57, 40}, 0x81, 143, 0xFFFF, 0, 0, 41, 22},
{ 3, {26, 43, 58, 41}, 0x81, 144, 0xFFFF, 0, 0, 42, 22},
{ 3, {27, 0, 59, 42}, 0x81, 145, 0xFFFF, 0, 0, 43, 22},
{ 3, {32, 49, 64, 0}, 0xC0, 235, 0, 0, 0, 48, 26},
{ 4, {32, 49, 64, 0}, 0xC6, 234, 0x200, 0,31, 48, 26},
{ 9, {33, 50, 65, 48}, 0xC0, 277, 0xFFFF, 0, 0, 49, 26},
{10, { 0, 0, 49, 0}, 0xC4, 278, 0xFFFF, 0,52, 49, 26},
{ 3, {34, 51, 66, 49}, 0xC1, 197, 0xFFFF, 0, 0, 50, 26},
{ 3, {35, 52, 67, 50}, 0xC1, 202, 0xFFFF, 0, 0, 51, 26},
{ 3, {36, 53, 68, 51}, 0x81, 146, 0xFFFF, 0, 0, 52, 22},
{ 3, {37, 54, 69, 52}, 1, 173, 0xFFFF, 0, 0, 53, 28},
{ 3, {38, 55, 70, 53}, 1, 174, 0xFFFF, 0, 0, 54, 28},
{ 3, {39, 56, 71, 54}, 1, 175, 0xFFFF, 0, 0, 55, 28},
{ 3, {40, 57, 72, 55}, 1, 176, 0xFFFF, 0, 0, 56, 28},
{ 3, {41, 58, 73, 56}, 1, 177, 0xFFFF, 0, 0, 57, 28},
{ 3, {42, 59, 74, 57}, 1, 178, 0xFFFF, 0, 0, 58, 28},
{ 3, {43, 0, 75, 58}, 1, 181, 0xFFFF, 0, 0, 59, 28},
{ 5, {48, 65, 1, 0}, 0xC0, 276, 0xFFFF, 0, 0, 64, 26},
{ 3, {49, 66, 1, 64}, 0xC1, 194, 0xFFFF, 0, 0, 65, 26},
{ 3, {50, 67, 1, 65}, 0xC1, 200, 0xFFFF, 0, 0, 66, 26},
{ 3, {51, 68, 1, 66}, 0xC1, 195, 0xFFFF, 0, 0, 67, 26},
{ 9, {52, 69, 1, 67}, 0xC0, 279, 0xFFFF, 0, 0, 68, 26},
{10, { 0, 0, 68, 0}, 0xC4, 280, 0xFFFF, 0,78, 68, 26},
{ 3, {53, 70, 1, 68}, 1, 163, 0xFFFF, 0, 0, 69, 28},
{ 3, {54, 71, 1, 69}, 1, 170, 0xFFFF, 0, 0, 70, 28},
{ 3, {55, 72, 1, 70}, 1, 171, 0xFFFF, 0, 0, 71, 28},
{ 3, {56, 73, 1, 71}, 1, 167, 0xFFFF, 0, 0, 72, 28},
{11, {57, 74, 1, 72}, 0x40, 223, 0xFFFF, 0, 0, 73, 32},
{12, {58, 75, 1, 73}, 0x40, 215, 0xFFFF, 0, 0, 74, 32},
{ 3, {59, 0, 1, 74}, 1, 166, 0xFFFF, 0, 0, 75, 28},
END_ROOMS,
// Uluru
{ 1, {255, 0, 0, 0}, 0x18, 41, 0xFFFF, 1, 0, 1, 36},
{ 2, {255, 0, 0, 0}, 0x18, 41, 0xFFFF, 0, 0, 1, 36},
{ 3, { 0, 17, 32, 0}, 0x81, 149, 0xFFFF, 0, 0, 16, 24},
{ 3, { 0, 18, 33, 16}, 0x81, 150, 0xFFFF, 0, 0, 17, 24},
{ 3, { 0, 19, 34, 17}, 0x81, 151, 0xFFFF, 0, 0, 18, 24},
{ 3, { 0, 20, 35, 18}, 0x81, 152, 0xFFFF, 0, 0, 19, 24},
{ 3, { 0, 21, 36, 19}, 0x81, 153, 0xFFFF, 0, 0, 20, 24},
{ 3, { 0, 22, 37, 20}, 0x81, 149, 0xFFFF, 0, 0, 21, 24},
{ 3, { 0, 23, 38, 21}, 0x81, 154, 0xFFFF, 0, 0, 22, 24},
{ 3, { 0, 24, 39, 22}, 0x81, 155, 0xFFFF, 0, 0, 23, 24},
{ 3, { 0, 25, 40, 23}, 0x81, 156, 0xFFFF, 0, 0, 24, 24},
{ 3, { 0, 26, 41, 24}, 0x81, 157, 0xFFFF, 0, 0, 25, 24},
{ 3, { 0, 27, 42, 25}, 0x81, 158, 0xFFFF, 0, 0, 26, 24},
{ 4, { 0, 0, 43, 26}, 0x86, 238, 0xA00, 0,47, 27, 52},
{ 4, { 0, 0, 43, 26}, 0x80, 239, 0x800, 0, 0, 27, 52},
{ 9, { 16, 33, 48, 0}, 0xC0, 277, 0xFFFF, 0, 0, 32, 26},
{10, { 0, 0, 32, 0}, 0xC4, 278, 0xFFFF, 0,52, 32, 26},
{ 3, { 17, 34, 49, 32}, 1, 191, 0xFFFF, 0, 0, 33, 30},
{ 3, { 18, 35, 50, 33}, 1, 184, 0xFFFF, 0, 0, 34, 30},
{ 3, { 19, 36, 51, 34}, 1, 185, 0xFFFF, 0, 0, 35, 30},
{ 3, { 20, 37, 52, 35}, 1, 186, 0xFFFF, 0, 0, 36, 30},
{ 3, { 21, 38, 53, 36}, 0x81, 161, 0xFFFF, 0, 0, 37, 24},
{ 3, { 22, 39, 54, 37}, 1, 189, 0xFFFF, 0, 0, 38, 30},
{ 3, { 23, 40, 55, 38}, 1, 186, 0xFFFF, 0, 0, 39, 30},
{ 3, { 24, 41, 56, 39}, 1, 185, 0xFFFF, 0, 0, 40, 30},
{13, { 25, 42, 57, 40}, 1, 192, 0xFFFF, 0, 0, 41, 30},
{ 3, { 26, 43, 58, 41}, 0x81, 159, 0xFFFF, 0, 0, 42, 24},
{ 3, { 27, 0, 59, 42}, 0x81, 160, 0xFFFF, 0, 0, 43, 24},
{12, { 32, 49, 0, 0}, 0x40, 205, 0xFFFF, 0, 0, 48, 34},
{11, { 33, 50, 0, 48}, 0x40, 210, 0xFFFF, 0, 0, 49, 34},
{11, { 34, 51, 0, 49}, 0x40, 212, 0xFFFF, 0, 0, 50, 34},
{11, { 35, 52, 0, 50}, 0x40, 211, 0xFFFF, 0, 0, 51, 34},
{11, { 36, 53, 68, 51}, 0x40, 207, 0xFFFF, 0, 0, 52, 34},
{ 3, { 37, 54, 69, 52}, 0xC1, 195, 0xFFFF, 0, 0, 53, 26},
{ 3, { 38, 55, 70, 53}, 1, 190, 0xFFFF, 0, 0, 54, 30},
{ 3, { 39, 56, 71, 54}, 1, 182, 0xFFFF, 0, 0, 55, 30},
{ 3, { 40, 57, 72, 55}, 1, 187, 0xFFFF, 0, 0, 56, 30},
{ 3, { 41, 58, 73, 56}, 1, 188, 0xFFFF, 0, 0, 57, 30},
{ 3, { 42, 59, 74, 57}, 1, 190, 0xFFFF, 0, 0, 58, 30},
{ 3, { 43, 0, 75, 58}, 0xC1, 197, 0xFFFF, 0, 0, 59, 26},
{11, { 52, 69, 1, 0}, 0x40, 208, 0xFFFF, 0, 0, 68, 34},
{ 3, { 53, 70, 1, 68}, 1, 182, 0xFFFF, 0, 0, 69, 30},
{ 3, { 54, 71, 1, 69}, 1, 187, 0xFFFF, 0, 0, 70, 30},
{ 3, { 55, 72, 1, 70}, 1, 188, 0xFFFF, 0, 0, 71, 30},
{ 3, { 56, 73, 1, 71}, 1, 190, 0xFFFF, 0, 0, 72, 30},
{ 3, { 57, 74, 1, 72}, 1, 187, 0xFFFF, 0, 0, 73, 30},
{ 3, { 58, 75, 1, 73}, 1, 182, 0xFFFF, 0, 0, 74, 30},
{ 6, { 59, 0, 1, 74}, 0xC0, 276, 0xFFFF, 0, 0, 75, 26},
END_ROOMS,
// Koto
{ 1, {255, 0, 0, 0}, 0x18, 42, 0xFFFF, 1, 0, 1, 40},
{ 2, {255, 0, 0, 0}, 0x18, 42, 0xFFFF, 0, 0, 1, 40},
{13, { 0, 17, 32, 0}, 0x86, 283, 0xFFFF, 0,57, 16, 50},
{ 3, { 0, 18, 33, 16}, 0x81, 125, 0xFFFF, 0, 0, 17, 22},
{ 3, { 0, 19, 34, 17}, 0x81, 126, 0xFFFF, 0, 0, 18, 22},
{ 3, { 0, 20, 35, 18}, 0x81, 127, 0xFFFF, 0, 0, 19, 22},
{ 3, { 0, 21, 36, 19}, 0x81, 128, 0xFFFF, 0, 0, 20, 22},
{ 3, { 0, 22, 37, 20}, 0x81, 131, 0xFFFF, 0, 0, 21, 22},
{ 3, { 0, 23, 38, 21}, 0x81, 129, 0xFFFF, 0, 0, 22, 22},
{ 3, { 0, 24, 39, 22}, 0x81, 126, 0xFFFF, 0, 0, 23, 22},
{ 3, { 0, 25, 40, 23}, 0x81, 125, 0xFFFF, 0, 0, 24, 22},
{ 3, { 0, 26, 41, 24}, 0x81, 127, 0xFFFF, 0, 0, 25, 22},
{ 3, { 0, 27, 42, 25}, 0x81, 133, 0xFFFF, 0, 0, 26, 22},
{ 3, { 0, 0, 43, 26}, 0x81, 132, 0xFFFF, 0, 0, 27, 22},
{ 3, { 16, 33, 48, 0}, 0x81, 133, 0xFFFF, 0, 0, 32, 22},
{ 3, { 17, 34, 49, 32}, 0x81, 124, 0xFFFF, 0, 0, 33, 22},
{ 3, { 18, 35, 50, 33}, 0x81, 132, 0xFFFF, 0, 0, 34, 22},
{ 3, { 19, 36, 51, 34}, 0x81, 131, 0xFFFF, 0, 0, 35, 22},
{ 3, { 20, 37, 52, 35}, 0x81, 126, 0xFFFF, 0, 0, 36, 22},
{ 3, { 21, 38, 53, 36}, 0x81, 125, 0xFFFF, 0, 0, 37, 22},
{ 3, { 22, 39, 54, 37}, 0x81, 126, 0xFFFF, 0, 0, 38, 22},
{ 3, { 23, 40, 55, 38}, 0x81, 128, 0xFFFF, 0, 0, 39, 22},
{ 3, { 24, 41, 56, 39}, 0x81, 127, 0xFFFF, 0, 0, 40, 22},
{ 3, { 25, 42, 57, 40}, 0x81, 133, 0xFFFF, 0, 0, 41, 22},
{ 3, { 26, 43, 58, 41}, 0x81, 124, 0xFFFF, 0, 0, 42, 22},
{ 3, { 27, 0, 59, 42}, 0x81, 129, 0xFFFF, 0, 0, 43, 22},
{11, { 32, 49, 0, 0}, 0x40, 221, 0xFFFF, 0, 0, 48, 32},
{12, { 33, 50, 0, 48}, 0x40, 215, 0xFFFF, 0, 0, 49, 32},
{11, { 34, 51, 66, 49}, 0x40, 217, 0xFFFF, 0, 0, 50, 32},
{11, { 35, 52, 67, 50}, 0x40, 223, 0xFFFF, 0, 0, 51, 32},
{ 3, { 36, 53, 68, 51}, 1, 179, 0xFFFF, 0, 0, 52, 28},
{ 3, { 37, 54, 69, 52}, 1, 180, 0xFFFF, 0, 0, 53, 28},
{ 3, { 38, 55, 70, 53}, 1, 178, 0xFFFF, 0, 0, 54, 28},
{ 3, { 39, 56, 71, 54}, 1, 177, 0xFFFF, 0, 0, 55, 28},
{ 3, { 40, 57, 72, 55}, 0xC1, 196, 0xFFFF, 0, 0, 56, 26},
{ 3, { 41, 58, 73, 56}, 0xC1, 197, 0xFFFF, 0, 0, 57, 26},
{ 9, { 42, 59, 74, 57}, 0xC0, 279, 0xFFFF, 0, 0, 58, 26},
{10, { 0, 0, 58, 0}, 0xC4, 280, 0xFFFF, 0,78, 58, 26},
{ 3, { 43, 0, 75, 58}, 0xC0, 237, 0, 0, 0, 59, 26},
{ 4, { 43, 0, 75, 58}, 0xC6, 236, 0x200, 0,46, 59, 26},
{11, { 50, 67, 1, 0}, 0x40, 218, 0xFFFF, 0, 0, 66, 32},
{11, { 51, 68, 1, 66}, 0x40, 217, 0xFFFF, 0, 0, 67, 32},
{ 3, { 52, 69, 1, 67}, 1, 168, 0xFFFF, 0, 0, 68, 28},
{ 3, { 53, 70, 1, 68}, 1, 172, 0xFFFF, 0, 0, 69, 28},
{ 3, { 54, 71, 1, 69}, 1, 170, 0xFFFF, 0, 0, 70, 28},
{ 3, { 55, 72, 1, 70}, 0xC1, 201, 0xFFFF, 0, 0, 71, 26},
{ 7, { 56, 73, 1, 71}, 0xC0, 276, 0xFFFF, 0, 0, 72, 26},
{ 3, { 57, 74, 1, 72}, 0xC1, 194, 0xFFFF, 0, 0, 73, 26},
{ 3, { 58, 75, 1, 73}, 0xC1, 195, 0xFFFF, 0, 0, 74, 26},
{ 9, { 59, 0, 1, 74}, 0xC0, 277, 0xFFFF, 0, 0, 75, 26},
{10, { 0, 0, 75, 0}, 0xC4, 278, 0xFFFF, 0,52, 75, 26},
END_ROOMS,
// Tamara
{ 1, {255, 0, 0, 0}, 0x1A, 43, 0xFFFF, 1, 0, 1, 36},
{ 2, {255, 0, 0, 0}, 0x1A, 43, 0xFFFF, 0, 0, 1, 36},
{ 3, { 0, 17, 32, 0}, 0x81, 147, 0xFFFF, 0, 0, 16, 24},
{ 3, { 0, 18, 33, 16}, 0x81, 148, 0xFFFF, 0, 0, 17, 24},
{ 3, { 0, 19, 34, 17}, 0x81, 149, 0xFFFF, 0, 0, 18, 24},
{ 3, { 0, 20, 35, 18}, 0x81, 150, 0xFFFF, 0, 0, 19, 24},
{ 3, { 0, 21, 36, 19}, 0x81, 151, 0xFFFF, 0, 0, 20, 24},
{ 3, { 0, 22, 37, 20}, 0x81, 152, 0xFFFF, 0, 0, 21, 24},
{ 3, { 0, 23, 38, 21}, 0x81, 153, 0xFFFF, 0, 0, 22, 24},
{ 3, { 0, 24, 39, 22}, 0x81, 154, 0xFFFF, 0, 0, 23, 24},
{ 3, { 0, 0, 40, 23}, 0x81, 155, 0xFFFF, 0, 0, 24, 24},
{ 3, { 16, 33, 48, 0}, 0x81, 154, 0xFFFF, 0, 0, 32, 24},
{ 3, { 17, 34, 49, 32}, 0x81, 156, 0xFFFF, 0, 0, 33, 24},
{ 3, { 18, 35, 50, 33}, 0x81, 157, 0xFFFF, 0, 0, 34, 24},
{ 3, { 19, 36, 51, 34}, 0x81, 158, 0xFFFF, 0, 0, 35, 24},
{ 3, { 20, 37, 52, 35}, 0x81, 159, 0xFFFF, 0, 0, 36, 24},
{ 3, { 21, 38, 53, 36}, 0x81, 160, 0xFFFF, 0, 0, 37, 24},
{ 3, { 22, 39, 54, 37}, 0x81, 161, 0xFFFF, 0, 0, 38, 24},
{ 3, { 23, 40, 55, 38}, 0x81, 162, 0xFFFF, 0, 0, 39, 24},
{ 4, { 24, 41, 56, 39}, 0xC0, 248, 0x280, 0, 0, 40, 26},
{ 4, { 24, 41, 56, 39}, 0xC0, 247, 0x200, 0, 0, 40, 26},
{ 4, { 24, 41, 56, 39}, 0xC0, 246, 0xFFFF, 0, 0, 40, 26},
{11, { 0, 0, 57, 40}, 0x40, 207, 0xFFFF, 0, 0, 41, 34},
{ 3, { 32, 49, 64, 0}, 0xC1, 193, 0xFFFF, 0, 0, 48, 26},
{ 3, { 33, 50, 65, 48}, 0xC1, 200, 0xFFFF, 0, 0, 49, 26},
{ 3, { 34, 51, 66, 49}, 1, 184, 0xFFFF, 0, 0, 50, 30},
{ 3, { 35, 52, 67, 50}, 1, 185, 0xFFFF, 0, 0, 51, 30},
{ 3, { 36, 53, 68, 51}, 0x81, 189, 0xFFFF, 0, 0, 52, 30},
{ 3, { 37, 54, 69, 52}, 1, 192, 0xFFFF, 0, 0, 53, 30},
{ 3, { 38, 55, 70, 53}, 1, 191, 0xFFFF, 0, 0, 54, 30},
{ 9, { 39, 56, 71, 54}, 0xC0, 277, 0xFFFF, 0, 0, 55, 26},
{10, { 0, 0, 55, 0}, 0xC4, 278, 0xFFFF, 0,52, 55, 26},
{ 3, { 40, 57, 72, 55}, 0xC1, 195, 0xFFFF, 0, 0, 56, 26},
{11, { 41, 58, 0, 56}, 0x40, 208, 0xFFFF, 0, 0, 57, 34},
{11, { 0, 0, 0, 57}, 0x40, 212, 0xFFFF, 0, 0, 58, 34},
{ 8, { 48, 65, 1, 0}, 0xC1, 276, 0xFFFF, 0, 0, 64, 26},
{ 3, { 49, 66, 1, 64}, 1, 187, 0xFFFF, 0, 0, 65, 30},
{ 3, { 50, 67, 1, 65}, 1, 188, 0xFFFF, 0, 0, 66, 30},
{ 3, { 51, 68, 1, 66}, 1, 190, 0xFFFF, 0, 0, 67, 30},
{12, { 52, 69, 1, 67}, 0x40, 205, 0xFFFF, 0, 0, 68, 34},
{11, { 53, 70, 1, 68}, 0x40, 203, 0xFFFF, 0, 0, 69, 34},
{11, { 54, 71, 1, 69}, 0x40, 211, 0xFFFF, 0, 0, 70, 34},
{14, { 55, 72, 1, 70}, 0x40, 213, 2, 0, 0, 71, 34},
{11, { 55, 72, 1, 70}, 0x40, 210, 0xFFFF, 0, 0, 71, 34},
{11, { 56, 0, 1, 71}, 0x40, 207, 0xFFFF, 0, 0, 72, 34},
END_ROOMS,
// Cantura
{ 1, {255, 0, 0, 0}, 0x18, 44, 0xFFFF, 1, 0, 1, 38},
{ 2, {255, 0, 0, 0}, 0x18, 44, 0xFFFF, 0, 0, 1, 38},
{ 4, { 0, 0, 18, 0}, 0x86, 240, 0xA00, 0,48, 17, 54},
{13, { 0, 0, 18, 0}, 0x80, 241, 0xA80, 0, 0, 17, 54},
{14, { 0, 0, 18, 0}, 0x80, 242, 0xA02, 0, 0, 17, 54},
{14, { 0, 0, 18, 0}, 0x80, 242, 0xFFFF, 0, 0, 17, 54},
{15, { 17, 19, 0, 0}, 0x40, 224, 0xFFFF, 0, 0, 18, 32},
{ 3, { 0, 20, 0, 18}, 0x40, 225, 0xFFFF, 0, 0, 19, 32},
{ 3, { 0, 21, 0, 19}, 0x40, 226, 0xFFFF, 0, 0, 20, 32},
{ 3, { 0, 22, 0, 20}, 0x40, 227, 0xFFFF, 0, 0, 21, 32},
{ 9, { 0, 23, 38, 21}, 0xC0, 277, 0xFFFF, 0, 0, 22, 26},
{10, { 0, 0, 22, 0}, 0xC4, 278, 0xFFFF, 0,52, 22, 26},
{ 5, { 0, 24, 39, 22}, 0xC0, 276, 0xFFFF, 0, 0, 23, 26},
{ 3, { 0, 25, 40, 23}, 0x81, 125, 0xFFFF, 0, 0, 24, 22},
{ 3, { 0, 26, 41, 24}, 0x81, 131, 0xFFFF, 0, 0, 25, 22},
{ 3, { 0, 27, 42, 25}, 0x81, 133, 0xFFFF, 0, 0, 26, 22},
{ 3, { 0, 0, 43, 26}, 0x81, 132, 0xFFFF, 0, 0, 27, 22},
{11, { 22, 39, 54, 0}, 0x40, 223, 0xFFFF, 0, 0, 38, 32},
{ 3, { 23, 40, 55, 38}, 1, 167, 0xFFFF, 0, 0, 39, 28},
{ 3, { 24, 41, 56, 39}, 0x81, 126, 0xFFFF, 0, 0, 40, 22},
{ 3, { 25, 42, 57, 40}, 1, 172, 0xFFFF, 0, 0, 41, 28},
{ 3, { 26, 43, 58, 41}, 1, 163, 0xFFFF, 0, 0, 42, 28},
{ 3, { 27, 0, 59, 42}, 1, 168, 0xFFFF, 0, 0, 43, 28},
{ 3, { 38, 55, 70, 0}, 1, 164, 0xFFFF, 0, 0, 54, 28},
{ 3, { 39, 56, 71, 54}, 1, 165, 0xFFFF, 0, 0, 55, 28},
{ 3, { 40, 57, 72, 55}, 1, 163, 0xFFFF, 0, 0, 56, 28},
{ 3, { 41, 58, 73, 56}, 1, 167, 0xFFFF, 0, 0, 57, 28},
{ 3, { 42, 59, 74, 57}, 1, 166, 0xFFFF, 0, 0, 58, 28},
{ 3, { 43, 0, 75, 58}, 1, 171, 0xFFFF, 0, 0, 59, 28},
{12, { 0, 70, 1, 0}, 0x40, 215, 0xFFFF, 0, 0, 69, 32},
{ 3, { 54, 71, 1, 69}, 1, 173, 0xFFFF, 0, 0, 70, 28},
{ 3, { 55, 72, 1, 70}, 1, 168, 0xFFFF, 0, 0, 71, 28},
{ 3, { 56, 73, 1, 71}, 1, 169, 0xFFFF, 0, 0, 72, 28},
{ 3, { 57, 74, 1, 72}, 1, 170, 0xFFFF, 0, 0, 73, 28},
{ 3, { 58, 75, 1, 73}, 1, 172, 0xFFFF, 0, 0, 74, 28},
{ 3, { 59, 0, 1, 74}, 1, 175, 0xFFFF, 0, 0, 75, 28},
END_ROOMS,
// Shandovra
{ 1, {255, 0, 0, 0}, 0x18, 45, 0xFFFF, 1, 0, 1, 40},
{ 2, {255, 0, 0, 0}, 0x18, 45, 0xFFFF, 0, 0, 1, 40},
{ 3, { 0, 17, 32, 0}, 0xC1, 193, 0xFFFF, 0, 0, 16, 26},
{ 3, { 0, 18, 33, 16}, 0x81, 125, 0xFFFF, 0, 0, 17, 22},
{ 3, { 0, 19, 34, 17}, 0x81, 126, 0xFFFF, 0, 0, 18, 22},
{ 3, { 0, 20, 35, 18}, 0x81, 127, 0xFFFF, 0, 0, 19, 22},
{ 3, { 0, 21, 36, 19}, 0x81, 128, 0xFFFF, 0, 0, 20, 22},
{ 3, { 0, 22, 37, 20}, 0x81, 131, 0xFFFF, 0, 0, 21, 22},
{ 3, { 0, 23, 38, 21}, 0x81, 129, 0xFFFF, 0, 0, 22, 22},
{ 3, { 0, 24, 39, 22}, 0x81, 130, 0xFFFF, 0, 0, 23, 22},
{ 3, { 0, 25, 40, 23}, 0x81, 125, 0xFFFF, 0, 0, 24, 22},
{ 3, { 0, 26, 41, 24}, 0x81, 124, 0xFFFF, 0, 0, 25, 22},
{ 4, { 0, 27, 42, 25}, 0x80, 250, 0x100, 0, 0, 26, 22},
{ 4, { 0, 27, 42, 25}, 0x80, 250, 0x300, 0, 0, 26, 22},
{ 4, { 0, 27, 42, 25}, 0x80, 251, 0x200, 0, 0, 26, 22},
{ 4, { 0, 27, 42, 25}, 0x80, 249, 0xFFFF, 0, 0, 26, 22},
{ 3, { 0, 0, 43, 26}, 0x81, 132, 0xFFFF, 0, 0, 27, 22},
{ 3, {16, 33, 48, 0}, 0xC1, 193, 0xFFFF, 0, 0, 32, 26},
{ 3, {17, 34, 49, 32}, 0xC1, 193, 0xFFFF, 0, 0, 33, 26},
{ 3, {18, 35, 50, 33}, 0xC1, 201, 0xFFFF, 0, 0, 34, 26},
{ 3, {19, 36, 51, 34}, 1, 170, 0xFFFF, 0, 0, 35, 28},
{ 3, {20, 37, 52, 35}, 1, 165, 0xFFFF, 0, 0, 36, 28},
{ 3, {21, 38, 53, 36}, 1, 164, 0xFFFF, 0, 0, 37, 28},
{ 3, {22, 39, 54, 37}, 0x81, 126, 0xFFFF, 0, 0, 38, 22},
{ 3, {23, 40, 55, 38}, 1, 167, 0xFFFF, 0, 0, 39, 28},
{ 3, {24, 41, 56, 39}, 0x81, 126, 0xFFFF, 0, 0, 40, 22},
{ 3, {25, 42, 0, 40}, 0x81, 132, 0xFFFF, 0, 0, 41, 22},
{ 3, {26, 43, 58, 41}, 0x81, 124, 0xFFFF, 0, 0, 42, 22},
{ 3, {27, 0, 59, 42}, 0x81, 129, 0xFFFF, 0, 0, 43, 22},
{ 6, {32, 49, 64, 0}, 0xC0, 276, 0xFFFF, 0, 0, 48, 26},
{ 9, {33, 50, 65, 48}, 0xC0, 279, 0xFFFF, 0, 0, 49, 26},
{10, { 0, 0, 49, 0}, 0xC4, 280, 0xFFFF, 0, 78, 49, 26},
{ 3, {34, 51, 66, 49}, 0xC1, 197, 0xFFFF, 0, 0, 50, 26},
{ 3, {35, 52, 67, 50}, 0xC1, 202, 0xFFFF, 0, 0, 51, 26},
{ 3, {36, 53, 68, 51}, 1, 177, 0xFFFF, 0, 0, 52, 28},
{ 3, {37, 54, 69, 52}, 0x81, 124, 0xFFFF, 0, 0, 53, 22},
{ 3, {38, 55, 70, 53}, 0x81, 125, 0xFFFF, 0, 0, 54, 22},
{ 3, {39, 56, 71, 54}, 1, 180, 0xFFFF, 0, 0, 55, 28},
{12, {40, 0, 72, 55}, 0x40, 215, 0xFFFF, 0, 0, 56, 32},
{11, {42, 59, 0, 0}, 0x40, 218, 0xFFFF, 0, 0, 58, 32},
{11, {43, 0, 75, 58}, 0x40, 216, 0xFFFF, 0, 0, 59, 32},
{ 9, {48, 65, 1, 0}, 0xC0, 277, 0xFFFF, 0, 0, 64, 26},
{10, { 0, 0, 64, 0}, 0xC4, 278, 0xFFFF, 0, 52, 64, 26},
{ 3, {49, 66, 1, 64}, 0xC1, 197, 0xFFFF, 0, 0, 65, 26},
{ 3, {50, 67, 1, 65}, 0xC1, 200, 0xFFFF, 0, 0, 66, 26},
{ 3, {51, 68, 1, 66}, 0x81, 125, 0xFFFF, 0, 0, 67, 22},
{ 3, {52, 69, 1, 67}, 0x81, 129, 0xFFFF, 0, 0, 68, 22},
{ 3, {53, 70, 1, 68}, 0x81, 133, 0xFFFF, 0, 0, 69, 22},
{ 3, {54, 71, 1, 69}, 1, 179, 0xFFFF, 0, 0, 70, 28},
{ 3, {55, 72, 1, 70}, 1, 181, 0xFFFF, 0, 0, 71, 28},
{11, {56, 0, 1, 71}, 0x40, 214, 0xFFFF, 0, 0, 72, 32},
{11, {59, 0, 1, 0}, 0x40, 223, 0xFFFF, 0, 0, 75, 32},
END_ROOMS
};

View File

@ -0,0 +1,11 @@
MODULE := devtools/create_cryo
MODULE_OBJS := \
create_led_dat.o
# Set the name of the executable
TOOL_EXECUTABLE := create_led_dat
# Include common rules
include $(srcdir)/rules.mk

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 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ResourceManager.h"
namespace Cryo {
ResourceManager::ResourceManager() {
}
ResourceManager::ResourceManager(const Common::String &datFileName) {
LoadDatFile(datFileName);
}
ResourceManager::~ResourceManager() {
}
bool ResourceManager::LoadDatFile(const Common::String &datFileName) {
if (_datFile.isOpen()) {
_datFile.close();
_files.clear();
}
assert(_datFile.open(datFileName));
uint16 numFiles = _datFile.readUint16LE();
for (uint16 i = 0; i < numFiles; i++) {
DatFileEntry entry;
_datFile.read(entry._name, sizeof(entry._name));
entry._size = _datFile.readUint32LE();
entry._offset = _datFile.readUint32LE();
entry._flag = _datFile.readByte();
_files.push_back(entry);
}
return true;
}
Common::SeekableReadStream *ResourceManager::GetFile(const Common::String &resName, unsigned int hintIndex) {
// First, try raw disk file so we can support modding/patching
if (Common::File::exists(resName)) {
debug("Loading %s from disk", resName);
Common::File *resource = new Common::File();
resource->open(resName);
return resource;
}
// Look inside .dat file
if (_datFile.isOpen()) {
for (unsigned int i = hintIndex; i < _files.size(); i++) {
if (!resName.compareToIgnoreCase(_files[i]._name)) {
debug("Loading %s from dat file", resName);
Common::SeekableSubReadStream *resource = new Common::SeekableSubReadStream(&_datFile, _files[i]._offset, _files[i]._offset + _files[i]._size);
return resource;
}
}
}
debug("Unable to load %s - does't exists", resName);
return nullptr;
}
Common::SeekableReadStream *ResourceManager::GetFile(unsigned int resIndex) {
if (_files.size() > resIndex) {
return GetFile(Common::String(_files[resIndex]._name), resIndex);
}
return nullptr;
}
void *ResourceManager::StreamToBuffer(Common::SeekableReadStream *stream, unsigned int *size) {
if (!stream)
return nullptr;
unsigned int readSize = stream->size();
byte *data = new byte[readSize + 1];
readSize = stream->read(data, readSize);
if (size)
*size = readSize;
return data;
}
void *ResourceManager::GetData(const Common::String &resName, unsigned int *size) {
Common::SeekableReadStream *resource = GetFile(resName);
void *data = StreamToBuffer(resource, size);
delete resource;
return data;
}
void *ResourceManager::GetData(int resIndex, unsigned int *size) {
Common::SeekableReadStream *resource = GetFile(resIndex);
void *data = StreamToBuffer(resource, size);
delete resource;
return data;
}
}

View File

@ -0,0 +1,92 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#pragma once
#include "common/array.h"
#include "common/file.h"
#include "common/fs.h"
#include "common/str.h"
#include "common/substream.h"
#include "common/debug.h"
namespace Cryo {
template<typename T>
class CryoArray {
private:
byte *_data;
bool _ownData;
uint16 ElementOffset(int num) {
assert(_data && num < Count())
return (static_cast<uint16 *>_data)[num];
}
public:
CryoArray(void *data, bool ownData) : _data(data), _ownData(ownData) {
}
~CryoArray() {
if (_ownData)
delete data;
}
uint16 Count() {
return ElementOffset(0) / 2;
}
const T *operator[](int index) {
return static_cast<T *>(_data + ElementOffset(num));
}
};
class ResourceManager {
private:
struct DatFileEntry {
char _name[16];
unsigned int _size;
unsigned int _offset;
byte _flag;
};
Common::Array<DatFileEntry> _files;
Common::File _datFile;
static void *StreamToBuffer(Common::SeekableReadStream *stream, unsigned int *size);
public:
ResourceManager(const Common::String &datFileName);
ResourceManager();
~ResourceManager();
bool LoadDatFile(const Common::String &datFileName);
// Load resource as a seekable stream
Common::SeekableReadStream *GetFile(const Common::String &resName, unsigned int hintIndex = 0);
Common::SeekableReadStream *GetFile(unsigned int resIndex);
// Load resource as a buffer
void *GetData(const Common::String &resName, unsigned int *size = nullptr);
void *GetData(int resIndex, unsigned int *size = nullptr);
void *operator[](int resIndex) {
return GetData(resIndex);
}
};
}

19
engines/cryo/bugs.txt Normal file
View File

@ -0,0 +1,19 @@
1. Open menu and replay last dialog, then press stop. hover over buttons - hint text will be misplaced
2. During valley location change some junk appears in the bottom half of screen for a brief time (broken transition effect?)
3. Transitions often show a lot of red colors (bad palette fadein/out?)
4. After game load in some areas (White Arch) top bar and inventory not redrawn due to (DrawFlags?) initialized incorrectly
5. Mac reload feature uses hardcoded savefile from eden.dat
6. First time in Tau's cave, try to take knife. When Dina objects, click on her - Tau's dialog will start (maybe it's original bug?)
7. Mouse clipping may be lost during FMV scenes
8. Screen doubling feature probably doesn't work (not really needed, can be replaced with built-in SCUMMVM scaler)
9. Tons of debug messages spam when hover mouse over party icons or menu buttons
A. King's bread drawn over inventory bar
B. PC cursor clipped too agressively
C. PC logos and credits videos won't play because encoded in old HNM format
D. Eye blinking works incorrectly?
E. Bogus hitbox in upper right corner of mirror screen (under mini-map)
F. Wrong frescoes cursor on PC
G. Junk on a valley entrance screen on PC
H. On PC, no sound during first Mungo's dialogue, memory corruption after that
J. PC intro video is lagging behind of background voice

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]
add_engine cryo "Lost Eden" no "" "" ""

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

@ -0,0 +1,116 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/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 "graphics/palette.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) {
// Put your engine in a sane state, but do nothing big yet;
// in particular, do not load data from files; rather, if you
// need to do such things, do them from run().
// Do not initialize graphics here
// Do not initialize audio devices here
// However this is the place to specify all default directories
// const Common::FSNode gameDataDir(ConfMan.get("path"));
// SearchMan.addSubDirectoryMatching(gameDataDir, "sound");
// Here is the right place to set up the engine specific debug channels
DebugMan.addDebugChannel(kCryoDebugExample, "example", "this is just an example for a engine specific debug channel");
DebugMan.addDebugChannel(kCryoDebugExample2, "example2", "also an example");
// Don't forget to register your random source
_rnd = new Common::RandomSource("cryo");
_debugger = nullptr;
_game = nullptr;
_video = nullptr;
_screenView = nullptr;
_showHotspots = false;
g_ed = this;
}
CryoEngine::~CryoEngine() {
debug("CryoEngine::~CryoEngine");
// Dispose your resources here
delete _rnd;
delete _game;
delete _video;
delete _screenView;
delete _debugger;
// Remove all of our debug levels here
DebugMan.clearAllDebugChannels();
}
Common::Error CryoEngine::run() {
_game = new EdenGame(this);
_video = new HnmPlayer(this);
_screenView = new View(320, 200);
_debugger = new Debugger(this);
///// CLTimer
_timerTicks = 0; // incremented in realtime
// Initialize graphics using following:
initGraphics(320, 200, false);
_screen.create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
// Additional setup.
debug("CryoEngine::init");
// Your main even loop should be (invoked from) here.
debug("CryoEngine::go: Hello, World!");
// This test will show up if -d1 and --debugflags=example are specified on the commandline
debugC(1, kCryoDebugExample, "Example debug call");
// This test will show up if --debugflags=example or --debugflags=example2 or both of them and -d3 are specified on the commandline
debugC(3, kCryoDebugExample | kCryoDebugExample2, "Example debug call two");
_game->run();
return Common::kNoError;
}
} // End of namespace Cryo

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

@ -0,0 +1,100 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef CRYO_CRYO_H
#define CRYO_CRYO_H
#include "common/scummsys.h"
#include "common/config-manager.h"
#include "engines/advancedDetector.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/video.h"
#include "cryo/debugger.h"
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();
virtual Common::Error run();
// 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;
HnmPlayer *_video;
Debugger *_debugger;
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();
};
extern CryoEngine *g_ed;
// Example console class
class Console : public GUI::Debugger {
public:
Console(CryoEngine *vm) {}
virtual ~Console(void) {}
};
} // End of namespace Cryo
#endif

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

@ -0,0 +1,433 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/system.h"
#include "common/events.h"
#include "common/timer.h"
#include "graphics/palette.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
uint16 gIntervalLast, gIntervalFirst, gIntervalSet;
int16 gMacintize = 0;
color_t black_palette[256];
color_t last_palette[256];
void CLPalette_Init() {
for (int16 i = 0; i < 256; i++)
black_palette[i].r = black_palette[i].g = black_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_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
int _mouseButton;
byte _keyState[256];
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_RTL:
return;
case Common::EVENT_KEYDOWN:
// Check for debugger
if ((event.kbd.keycode == Common::KEYCODE_d) && (event.kbd.flags & Common::KBD_CTRL)) {
// Attach to the debugger
_debugger->attach();
_debugger->onFrame();
}
return;
case Common::EVENT_KEYUP:
// _keyState[(byte)toupper(event.kbd.ascii)] = false;
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;
}
///// CLSound
// base sound
Sound::Sound(int16 length, float rate, int16 sampleSize, int16 mode) {
_sndHandle = nullptr;
_headerLen = 0;
_headerOffset = 0;
_length = 0;
_mode = 0;
_volume = 0;
_maxLength = length;
_rate = rate;
_sampleSize = sampleSize;
_buffer = nullptr;
// sndHandle = CLMemory_AllocHandle(arg1 + 100);
// if(!sndHandle)
// error("CLSoundRaw_New - Not enough memory");
// else
prepareSample(mode);
}
Sound::~Sound() {
}
void CLSoundRaw_AssignBuffer(Sound *sound, void *buffer, int bufferOffs, int length) {
sound->_length = length;
char *buf = bufferOffs + (char *)buffer;
// if(CLSound_GetWantsDesigned())
// CLSound_Signed2NonSigned(buf, length);
sound->_buffer = buf;
// if(sound->reversed && sound->sampleSize == 16)
// ReverseBlock16(buf, length);
}
void Sound::prepareSample(int16 mode) {
_mode = mode;
_volume = 255;
}
void Sound::setWantsDesigned(int16 designed) {
}
///// CLSoundChannel
/// sound output device that plays queue of sounds
SoundChannel::SoundChannel(int arg1) {
_volumeLeft = _volumeRight = 255;
_numSounds = 0;
for (int16 i = 0; i < kCryoMaxChSounds; i++)
_sounds[i] = nullptr;
}
SoundChannel::~SoundChannel() {
}
void SoundChannel::stop() {
// _vm->_mixer->stopHandle(this);
}
void SoundChannel::play(Sound *sound) {
}
int16 SoundChannel::getVolume() {
return (_volumeLeft + _volumeRight) / 2;
}
void SoundChannel::setVolume(int16 volume) {
if (volume < 0 || volume > 255)
return;
_volumeLeft = volume;
_volumeRight = volume;
}
void SoundChannel::setVolumeRight(int16 volume) {
if (volume < 0 || volume > 255)
return;
_volumeRight = volume;
}
void SoundChannel::setVolumeLeft(int16 volume) {
if (volume < 0 || volume > 255)
return;
_volumeLeft = volume;
}
///// CLTimer
void CLTimer_Action(void *arg) {
// long& counter = *((long*)arg);
// counter++;
g_ed->_timerTicks++;
}
///// CRYOLib
void CRYOLib_ManagersInit() {
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

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

@ -0,0 +1,175 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef CRYO_CRYOLIB_H
#define CRYO_CRYOLIB_H
#include "audio/mixer.h"
#include "common/system.h"
#include "cryo/platdefs.h"
namespace Cryo {
class CryoEngine;
#define SW16(n) ( (((n) & 0xFF) << 8) | (((n) >> 8) & 0xFF) )
#define SW32(n) ( (((n) & 0xFF) << 24) | (((n) >> 24) & 0xFF) | (((n) & 0xFF00) << 8) | (((n) >> 8) & 0xFF00))
#ifdef SCUMM_BIG_ENDIAN
//big-endian host
#define LE16(n) SW16(n)
#define LE32(n) SW32(n)
#define BE16(n) (n)
#define BE32(n) (n)
#else
//little-endian host
#define LE16(n) (n)
#define LE32(n) (n)
#define BE16(n) SW16(n)
#define BE32(n) SW32(n)
#endif
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;
};
struct HNMHeader {
int32 _signature;
uint16 _width;
uint16 _height;
int32 _numbFrame;
int32 _bufferSize;
};
class Sound {
private:
int32 _headerOffset;
int16 _mode;
int16 _volume;
public:
Sound(int16 length, float rate, int16 sampleSize, int16 mode);
~Sound();
void assignBuffer(void *buffer, int bufferOffs, int length);
void prepareSample(int16 mode);
void setWantsDesigned(int16 designed);
char *_sndHandle;
char *_buffer;
float _rate;
int16 _maxLength;
int16 _headerLen;
int16 _sampleSize;
int _length;
};
#define kCryoMaxChSounds 10
class SoundChannel {
private:
int16 _volumeLeft;
int16 _volumeRight;
int16 _numSounds;
Sound *_sounds[kCryoMaxChSounds];
public:
SoundChannel(int arg1);
~SoundChannel();
void stop();
void play(Sound *sound);
int16 getVolume();
void setVolume(int16 volume);
void setVolumeRight(int16 volume);
void setVolumeLeft(int16 volume);
};
void SysBeep(int x);
void FlushEvents(int16 arg1, int16 arg2);
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

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

@ -0,0 +1,64 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/coroutines.h"
#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

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

@ -0,0 +1,48 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#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);
virtual ~Debugger() {}
protected:
bool Cmd_ShowHotspots(int argc, const char **argv);
bool Cmd_FullInventory(int argc, const char **argv);
};
} // End of namespace Cryo
#endif

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

@ -0,0 +1,852 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "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
};
}
#pragma pack(push, 1)
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 kPersoRoomBankTable 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
};
class EdenGame;
struct phase_t {
int16 _id;
void (EdenGame::*disp)();
};
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 kObjectLocations
uint16 _itemMask;
uint16 _powerMask; // object of power bitmask
int16 _count;
};
namespace DialogFlags {
enum DialogFlags {
df20 = 0x20,
dfRepeatable = 0x40,
dfSpoken = 0x80
};
}
namespace DialogType {
enum DialogType {
dtTalk = 0,
dtDinoAction,
dtDinoItem,
dtItem,
dtEvent,
dtInspect,
dtHint
};
}
struct Dialog {
char _flags; // 0-3 - action index, 4 - highest bit of contidion index, rest is DialogFlags
char _condNumLow; // condition index low bits
char _textCondHiMask; // 0-1 text index hi bits, 2-5 - perso mask num, 6-7 condition index hi bits
char _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
char _id; // character
char _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;
};
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
};
struct PakHeaderItem {
Common::String _name; //[16];
int32 _size;
int32 _offs;
char _flag;
};
class PakHeaderNode {
public:
PakHeaderNode(int count);
~PakHeaderNode();
uint16 _count;
PakHeaderItem* _files;
};
#pragma pack(pop)
struct Citadel {
int16 _id;
int16 _bank[8];
int16 _video[8];
};
/////////////// vars
extern Follower followerList[];
/*
Labyrinth of Mo
| | | | | | | |
*/
enum {
LAB_N = 1,
LAB_E,
LAB_S,
LAB_W
};
extern byte kLabyrinthPath[];
extern char kDinoSpeedForCitaLevel[16];
extern char kTabletView[];
// special character backgrounds for specific rooms
extern char kPersoRoomBankTable[];
// area transition descriptors
extern Goto gotos[];
extern object_t _objects[];
extern uint16 kObjectLocations[100];
extern perso_t kPersons[];
extern Citadel _citadelList[];
struct prect_t {
int16 left, top, right, bottom;
};
extern prect_t _characterRects[];
extern byte _characterArray[][5];
extern Area kAreasTable[];
extern int16 tab_2CEF0[64];
extern int16 tab_2CF70[64];
extern int16 kActionCursors[299];
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;
};
extern float _translationZ;
extern float flt_2DF80;
extern float flt_2DF84;
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

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

@ -0,0 +1,166 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "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; }
}
static const PlainGameDescriptor cryoGames[] = {
{"losteden", "Lost Eden"},
{0, 0}
};
namespace Cryo {
static const ADGameDescription gameDescriptions[] = {
// Lost Eden PC non-interactive demo version
// Probably not worth it
{
"losteden",
0,
AD_ENTRY1s("EDEN6.HSQ", 0, 17093),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_DEMO,
GUIO1(GUIO_NONE)
},
// Lost Eden PC interactive demo version
{
"losteden",
0,
AD_ENTRY1s("EDEN.DAT", 0, 205473728),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_DEMO,
GUIO1(GUIO_NONE)
},
// Lost Eden PC version
{
"losteden",
0,
AD_ENTRY1s("EDEN.DAT", 0, 449853776),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO1(GUIO_NONE)
},
// Lost Eden EN PC version
// Added by Strangerke
{
"losteden",
0,
AD_ENTRY1s("EDEN.DAT", "2126f14fe38b47c7a132f7937c79a2f0", 451205552),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO1(GUIO_NONE)
},
// Lost Eden FR PC version
// Added by Strangerke
{
"losteden",
0,
AD_ENTRY1s("EDEN.DAT", "378b1260ac400ecf35f8843357adcca6", 448040496),
Common::FR_FRA,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO1(GUIO_NONE)
},
// Lost Eden DE PC version
{
"losteden",
0,
AD_ENTRY1s("EDEN.DAT", 0, 457719104),
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO1(GUIO_NONE)
},
// Lost Eden Mac version
{
"losteden",
0,
AD_ENTRY1s("EDEN.DAT", 0, 489739536),
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
GUIO1(GUIO_NONE)
},
AD_TABLE_END_MARKER
};
} // End of namespace Cryo
class CryoMetaEngine : public AdvancedMetaEngine {
public:
CryoMetaEngine() : AdvancedMetaEngine(Cryo::gameDescriptions, sizeof(ADGameDescription), cryoGames) {
_singleId = "losteden";
}
virtual const char *getName() const {
return "Cryo Engine";
}
virtual const char *getOriginalCopyright() const {
return "Cryo Engine (C) Cryo Interactive";
}
virtual bool hasFeature(MetaEngineFeature f) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
};
bool CryoMetaEngine::hasFeature(MetaEngineFeature f) const {
return false;
}
bool CryoMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
if (desc) {
*engine = new Cryo::CryoEngine(syst, desc);
}
return desc != 0;
}
#if PLUGIN_ENABLED_DYNAMIC(CRYO)
REGISTER_PLUGIN_DYNAMIC(CRYO, PLUGIN_TYPE_ENGINE, CryoMetaEngine);
#else
REGISTER_PLUGIN_STATIC(CRYO, PLUGIN_TYPE_ENGINE, CryoMetaEngine);
#endif

9364
engines/cryo/eden.cpp Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,742 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef CRYO_EDEN_H
#define CRYO_EDEN_H
#include "cryo/sound.h"
#include "cryo/defs.h"
enum Direction {
kCryoNorth = 0,
kCryoEast = 1,
kCryoSouth = 2,
kCryoWest = 3
};
namespace Cryo {
class CryoEngine;
class EdenGame {
private:
CryoEngine *_vm;
public:
EdenGame(CryoEngine *vm);
void run();
object_t *getObjectPtr(int16 id);
void showObjects();
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 display();
void afficher128();
void saveFriezes();
void saveTopFrieze(int16 x);
void saveBottomFrieze();
void restoreFriezes();
void restoreTopFrieze();
void restoreBottomFrieze();
void useMainBank();
void useCharacterBank();
void useBank(int16 bank);
void sundcurs(int16 x, int16 y);
void rundcurs();
void noclipax(int16 index, int16 x, int16 y);
void noclipax_avecnoir(int16 index, int16 x, int16 y);
void getglow(int16 x, int16 y, int16 w, int16 h);
void unglow();
void glow(int16 index);
void readPalette(byte *ptr);
void spriteOnSubtitle(int16 index, int16 x, int16 y);
void hideBars();
void showBars();
void saveMouthBackground();
void restoreMouthBackground();
void drawBlackBars();
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 displayImage();
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 displaySubtitles();
void saveUnderSubtitles(int16 y);
void restoreUnderSubtitles();
void displayHNMSubtitle();
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 dialoscansvmas(Dialog *dial);
bool dialogEvent(perso_t *perso);
void characterStayHere();
void endDeath(int16 vid);
void chronoEvent();
void setChrono(int16 t);
void preloadDialogs(int16 vid);
void displayEffect1();
void displayEffect2();
void displayEffect3();
void displayEffect4();
void clearScreen();
void colimacon(int16 pattern[16]);
void fadeToBlack(int delay);
void fadeToBlackLowPalette(int delay);
void fadeFromBlackLowPalette(int delay);
void blackRect32();
void setSrcRect(int16 sx, int16 sy, int16 ex, int16 ey);
void setDestRect(int16 sx, int16 sy, int16 ex, int16 ey);
void wait(int howlong);
void effetpix();
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);
void loadHnm(uint16 num);
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 initRects();
void closeRoom();
void displaySingleRoom(Room *room);
void displayRoom();
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 openWindow();
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 showMovie(char arg1);
void playHNM(int16 num);
void handleHNMSubtitles();
void musique();
void startmusique(byte num);
void musicspy();
int loadmusicfile(int16 num);
void persovox();
void endCharacterSpeech();
void fademusicup();
void fademusica0(int16 delay);
void countObjects();
void winObject(int16 id);
void loseObject(int16 id);
void lostObject();
bool isObjectHere(int16 id);
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 depcurstape();
void affcurstape();
void forwardtape();
void stoptape();
void cliccurstape();
void paneltobuf();
void cursbuftopanel();
void langbuftopanel();
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 vavaoffsetout();
void vavaoffsetin();
void lieuoffsetout();
void lieuoffsetin();
void bandeoffsetout();
void bandeoffsetin();
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);
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);
int16 OpenDialog(void *arg1, void *arg2);
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];
Common::Point _cursKeepPos;
bool _torchCursor;
int16 _curBankNum;
int16 _glowX;
int16 _glowY;
int16 _glowW;
int16 _glowH;
bool _paletteUpdateRequired;
bool _cursorSaved;
bool _showBlackBars;
bool _backgroundSaved;
byte *_bankData;
color_t _globalPalette[256]; //TODO palette_t
perso_t *_tyranPtr;
int _lastAnimFrameNumb;
int _curAnimFrameNumb;
int _lastAnimTicks;
prect_t *_curCharacterRect;
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;
bool _savedUnderSubtitles;
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;
color3_t newColor;
color_t oldPalette[256]; // TODO palette_t ?
color_t newPalette[256];
Common::Rect rect_dst, rect_src;
byte *_voiceSamplesBuffer; //TODO: sound sample buffer
Common::File _bigfile;
byte _infoList[16];
bool _needToFade;
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 *_mainViewBuf;
byte *_view2Buf;
byte *_gameFont; //TODO: rename to font?
byte *_subtitlesViewBuf;
byte *_underSubtitlesViewBuf; // CHECKME: Useless?
global_t *_globals;
uint16 _mouseCenterX;
uint16 _mouseCenterY;
bool _bufferAllocationErrorFl;
bool _quitFlag2;
bool _quitFlag3;
bool _gameStarted;
bool _soundAllocated;
CSoundChannel *_musicChannel;
CSoundChannel *_voiceChannel;
CSoundChannel *_hnmSoundChannel;
Sound *_voiceSound;
View *_view2;
View *_underSubtitlesView;
View *_subtitlesView;
View *_underBarsView;
View *_mainView;
View *_hnmView;
Common::Rect _underSubtitlesBackupRect;
Common::Rect _underSubtitlesScreenRect;
Common::Rect _underBottomBarBackupRect;
Common::Rect _underBottomBarScreenRect;
Common::Rect _underTopBarBackupRect;
Common::Rect _underTopBarScreenRect;
int _demoCurrentTicks;
int _demoStartTicks;
int _currentTime;
int16 _cirsorPanX;
int16 _inventoryScrollDelay;
int16 _cursorPosX;
int16 _cursorPosY;
int16 _currCursor;
Icon *_currSpot;
Icon *_curSpot2;
bool _keyboardHeld;
bool _mouseHeld;
bool _normalCursor;
byte *_hnmViewBuf;
bool _showVideoSubtitle;
bool _videoCanceledFlag; //TODO: hnm_canceled
bool _specialTextMode;
int _hnmFrameNum;
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
};
}
#endif

24
engines/cryo/gameflow.txt Normal file
View File

@ -0,0 +1,24 @@
game phases
0 - game start
10 - enter throne room
20 - heard talk of eloi and father
30 - in prince's room
40 - met dina
41 - talking to tau room: 202
50 - tau died
60 - talked to jabber
70 - got a gift from jabber
71 - part with dina at secret crypt
80 - learned about fresques / got flute
81 - convinced monk to help
82 - enter throne room
90 - got king's permission
A0 - met chong
A1 - chong joins party
B0 - on valley screen after citadel build complete
C0 - met ulan
D0 - build citadel in uluru
E0 - got gift from ulan
...

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

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

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

@ -0,0 +1,48 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef CRYO_PLATDEFS_H
#define CRYO_PLATDEFS_H
#if 1
#include "common/file.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;
#endif
} // End of namespace Cryo
#endif

72
engines/cryo/readme.txt Normal file
View File

@ -0,0 +1,72 @@
Citadel of Mo, the last remaining place where humans can be safe from army
of vicious Tyrannosaurus led by allmighty Morkus Rex. What awaits young Adam,
prince of Mo, who just came of age and want to travel across the world?
Will he be able to restore long lost friendship between dinosaurus and humans?
This is SCUMMVM reimplementation of Cryo's Lost Eden game engine. In order to
stay as close as possible to original game and minimize number of bugs
introduced during code reconstruction, in its current state this project is
a straight reverse-engineered game code hooked up to SCUMMVM framework.
Because of that, this code in no way represent the quality or coding practices
of SCUMMVM itself. Essentially, this is how the game was originally written.
There are several Lost Eden game versions known to exists.
- Non-interactive PC demo version. Basically, a number of video files played
in a loop with FM music in background. Google for "ANCIBUR2.HNM" file to
find it.
- Interactive PC demo version. Allows to play through whole Citadel of Mo
then shows "Coming Soon" banner.
Can be found here: http://www.ag.ru/games/lost-eden/demos/2677
Download is a self-extracting archive, unpack it with 7zip or similar tool.
- PC version. Main version of the game. Written in assembly and partially based
on Dune's game code.
Runs in real-mode DOS environment, uses VGA 320x200 graphics and digitized
sounds/music. Allows to select several languages for in-game subtitles. It is
rumored that bootleg Russian translation also exists. Has 3 predefined slots
for game save/load. Uses two different video codecs for HNM files.
- MAC version. Almost identical to PC version. Has slightly modified UI. Such
as exta spaces on the inventory bar, resized subtitles overlay and different
implementation of mouse cursor (which is worse than the original one). Looks
like screen transition effects are also changed / rearranged. Also comes with
updated game script.
This version has no limit on save game slots. Standard system file selection
dialogs are used instead. All screen hot-spots coordinates loaded from the
main resource file instead of hard-coded values used in PC version.
- 3DO version. Uses completely different resource formats.
- CDI version. Uses completely different resource formats.
- CD32 version. Mentioned in PC demo version, but never released?
This reimplementation project is based on MAC version, since it's much easier
to work with than any other versions.
At this moment Mac version of the game is fully playabe/completeable. List of
currently discovered bugs can be found in bugs.txt file. None of those are
critical or game-breaking. Only single game save/load slot is supported and
saves are not cross-platform compatible. Also, no game restart feature work
due to the way it's implemented.
PC versions (Demo and Full) are supported as well, but have a number of more
severe glitches.
Because of limited development environment, this code is only tested on
MSVS2013 32-bit compiler. There may be some issues with GCC/LLVM compilers
or on 64-bit platforms. As mentioned above, this code is neither pretty or
bug-free (aka it's a can of worms). Several original bugs, various oddities
and problematic areas are marked with TODO comment in the source code. There
are number of variables with non-descripitve names like byte_1234, those
purpose is yet to be clearly understood. To make code debugging easier,
some commands have been added in the debugger. Some parts, like image
drawing routines, can be simplified/generalized.
Because parts of this code (mainly decompression and video playback) used
by other Cryo's games, it might be worthy to make them reusable by future
engines.

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

@ -0,0 +1,113 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "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);
}
}

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

@ -0,0 +1,70 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#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);
};
}

495
engines/cryo/staticdata.cpp Normal file
View File

@ -0,0 +1,495 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "cryo/defs.h"
#include "cryo/cryolib.h"
namespace Cryo {
Follower followerList[] = {
// char, X, sx, sy, ex, ey,bank,
{ PersonId::pidGregor, 5, 211, 9, 320, 176, 228, 0, 0 },
{ PersonId::pidEloi, 4, 162, 47, 223, 176, 228, 112, 78 },
{ PersonId::pidDina, 3, 55, 0, 172, 176, 228, 90, 16 },
{ PersonId::pidChongOfChamaar, 4, 0, 5, 114, 176, 229, 0, 16 },
{ PersonId::pidKommalaOfKoto, 3, 0, 15, 102, 176, 229, 0, 16 },
{ PersonId::pidUlanOfUlele, 1, 0, 0, 129, 176, 230, 0, 16 },
{ PersonId::pidCabukaOfCantura, 2, 0, 0, 142, 176, 230, 0, 16 },
{ PersonId::pidFuggOfTamara, 0, 0, 17, 102, 176, 230, 0, 16 },
{ PersonId::pidJabber, 2, 0, 6, 134, 176, 228, 0, 16 },
{ PersonId::pidShazia, 1, 90, 17, 170, 176, 228, 50, 22 },
{ PersonId::pidThugg, 0, 489, 8, 640, 176, 228, 160, 24 },
{ PersonId::pidMungo, 5, 361, 0, 517, 176, 229, 0, 16 },
{ PersonId::pidMonk, 0, 419, 22, 569, 176, 229, 100, 30 },
{ PersonId::pidEve, 1, 300, 28, 428, 176, 229, 0, 38 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1 }
};
/*
Labyrinth of Mo
| | | | | | | |
*/
byte kLabyrinthPath[] = {
// each nibble tells which direction to choose to exit the labyrinth
0x11, 0x11, 0x11, 0x22, 0x33, 0x55, 0x25, 0x44, 0x25, 0x11, 0x11, 0x11,
0x11, 0x35, 0x55, 0x45, 0x45, 0x44, 0x44, 0x34, 0x44, 0x34, 0x32, 0x52,
0x33, 0x23, 0x24, 0x44, 0x24, 0x22, 0x54, 0x22, 0x54, 0x54, 0x44, 0x22,
0x22, 0x42, 0x45, 0x22, 0x42, 0x45, 0x35, 0x11, 0x44, 0x34, 0x52, 0x11,
0x44, 0x32, 0x55, 0x11, 0x11, 0x33, 0x11, 0x11, 0x53, 0x11, 0x11, 0x53,
0x54, 0x24, 0x11, 0x22, 0x25, 0x33, 0x53, 0x54, 0x23, 0x44
};
char kDinoSpeedForCitaLevel[16] = { 1, 2, 3, 4, 4, 5, 6, 7, 8, 9 };
char kTabletView[] = { //TODO: make as struct?
// opposite tablet id, video id
Objects::obUnused10, 83,
Objects::obUnused10, 84,
Objects::obTablet4, 85,
Objects::obTablet3, 86,
Objects::obTablet6, 87,
Objects::obTablet5, 85
};
// special character backgrounds for specific rooms
char kPersoRoomBankTable[] = {
// first entry is default bank, then pairs of [roomNum, bankNum], terminated by -1
0, 3, 33, -1,
21, 17, 35, -1,
0, 2, 36, -1,
22, 9, 38, 3, 39, -1,
23, 8, 40, -1,
0, 3, 41, 7, 42, -1,
25, -1,
27, 17, 45, -1,
28, 26, 46, -1,
29, 51, 48, -1,
30, 53, 49, -1,
0, 27, 50, -1,
32, 17, 51, -1,
52, 2, 52, -1,
-3, 3, -3, -1,
31, -1,
24, 6, 43, -1,
47, -1,
0, 2, 64, -1,
54, 3, 54, -1,
27, -1,
26, 17, 45, -1
};
// area transition descriptors
Goto gotos[] = {
// area, oldarea, vid, time, valleyVid
{ 0, 1, 0, 2, 20 },
{ 0, 1, 162, 3, 168 },
{ 0, 2, 0, 2, 21 },
{ 0, 6, 0, 3, 108 },
{ 0, 9, 151, 3, 0 },
{ 0, 7, 106, 2, 101 },
{ 0, 10, 79, 3, 102 },
{ 0, 12, 0, 3, 0 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 1, 3, 58, 2, 104 },
{ 1, 4, 100, 4, 104 },
{ 1, 5, 107, 6, 104 },
{ 1, 6, 155, 8, 104 },
{ 1, 7, 165, 6, 104 },
{ 1, 8, 169, 6, 104 },
{ 1, 10, 111, 2, 104 },
{ 1, 11, 164, 4, 104 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 1, 3, 161, 3, 102 },
{ 1, 4, 163, 6, 102 },
{ 1, 5, 157, 9, 102 },
{ 1, 9, 160, 9, 102 },
{ 1, 10, 79, 3, 102 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 1, 3, 0, 3, 153 }, // 24
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 3, 1, 154, 2, 103 },
{ 3, 4, 100, 2, 103 },
{ 3, 5, 107, 4, 103 },
{ 3, 6, 155, 6, 103 },
{ 3, 7, 165, 8, 103 },
{ 3, 8, 169, 6, 103 },
{ 3, 10, 111, 4, 103 },
{ 3, 11, 164, 6, 103 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 3, 1, 162, 3, 22 },
{ 3, 4, 163, 6, 22 },
{ 3, 5, 157, 9, 22 },
{ 3, 9, 160, 9, 22 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 3, 1, 0, 3, 166 }, // 40
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 4, 1, 154, 4, 51 },
{ 4, 3, 58, 2, 51 },
{ 4, 5, 107, 2, 51 },
{ 4, 6, 155, 4, 51 },
{ 4, 7, 165, 6, 51 },
{ 4, 8, 169, 8, 51 },
{ 4, 10, 111, 6, 51 },
{ 4, 11, 164, 8, 51 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 4, 1, 162, 3, 109 }, // 51
{ 4, 3, 161, 6, 109 },
{ 4, 5, 157, 9, 109 },
{ 4, 9, 160, 9, 109 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 5, 1, 154, 6, 33 },
{ 5, 3, 58, 4, 33 },
{ 5, 4, 100, 2, 33 },
{ 5, 6, 155, 2, 33 },
{ 5, 7, 165, 4, 33 },
{ 5, 8, 169, 8, 33 },
{ 5, 10, 111, 8, 33 },
{ 5, 11, 164, 8, 33 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 5, 1, 162, 3, 99 }, // 65
{ 5, 3, 161, 6, 99 },
{ 5, 4, 163, 9, 99 },
{ 5, 9, 160, 9, 99 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 9, 1, 162, 3, 167 }, // 70
{ 9, 3, 161, 6, 167 },
{ 9, 4, 163, 9, 167 },
{ 9, 5, 157, 9, 167 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 6, 1, 154, 8, 105 }, // 75
{ 6, 3, 58, 6, 105 },
{ 6, 4, 100, 4, 105 },
{ 6, 5, 107, 2, 105 },
{ 6, 7, 165, 2, 105 },
{ 6, 8, 169, 10, 105 },
{ 6, 10, 111, 6, 105 },
{ 6, 11, 164, 8, 105 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 7, 1, 154, 4, 158 }, // 84
{ 7, 3, 58, 6, 158 },
{ 7, 4, 100, 6, 158 },
{ 7, 5, 107, 4, 158 },
{ 7, 6, 155, 2, 158 },
{ 7, 8, 169, 8, 158 },
{ 7, 10, 111, 4, 158 },
{ 7, 11, 164, 6, 158 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 8, 1, 154, 2, 159 }, // 93
{ 8, 3, 58, 4, 159 },
{ 8, 4, 100, 6, 159 },
{ 8, 5, 107, 8, 159 },
{ 8, 6, 155, 10, 159 },
{ 8, 7, 165, 8, 159 },
{ 8, 10, 111, 6, 159 },
{ 8, 11, 164, 4, 159 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 10, 1, 154, 2, 77 }, // 102
{ 10, 3, 58, 4, 77 },
{ 10, 4, 100, 6, 77 },
{ 10, 5, 107, 8, 77 },
{ 10, 6, 155, 6, 77 },
{ 10, 7, 165, 4, 77 },
{ 10, 8, 169, 6, 77 },
{ 10, 11, 164, 4, 77 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 11, 1, 154, 2, 80 }, // 111
{ 11, 3, 58, 4, 80 },
{ 11, 4, 100, 6, 80 },
{ 11, 5, 107, 8, 80 },
{ 11, 6, 155, 8, 80 },
{ 11, 7, 165, 6, 80 },
{ 11, 8, 169, 2, 80 },
{ 11, 10, 111, 4, 80 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 12, 1, 154, 8, 56 }, // 120
{ 12, 3, 58, 4, 56 },
{ 12, 4, 100, 4, 56 },
{ 12, 5, 107, 6, 56 },
{ 12, 6, 155, 8, 56 },
{ 12, 7, 165, 10, 56 },
{ 12, 8, 169, 4, 56 },
{ 12, 10, 111, 10, 56 },
{ 12, 11, 164, 6, 56 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
};
object_t _objects[] = {
//id,fl,loc,masklow,maskhi,ct
{ 1, 0, 3, 1, 0, 0}, // Eve's Way Stone
{ 2, 0, 3, 2, 0, 0}, // Thau's Seashell
{ 3, 0, 3, 4, 0, 0}, // Talisman of bravery
{ 4, 0, 3, 8, 0, 0}, // An old tooth. Very old! Whoever lost it most certainly has no further use for it!
{ 5, 0, 0, 0x10, 0, 0}, // Prism
{ 6, 0, 3, 0, 0, 0}, // Flute
{ 7, 0, 3, 0x4000, 0, 0}, // Apple
{ 8, 0, 4, 0x1000, 0, 0}, // Egg of Destiny
{ 9, 0, 3, 0x800, 0, 0}, // Root
{ 10, 0, 3, 0, 0, 0}, // ???
{ 11, 0, 6, 0, 0, 0}, // Mushroom
{ 12, 0, 13, 0, 0, 0}, // Poisonous Mushroom
{ 13, 0, 2, 0x400, 0, 0}, // Graa's Knife
{ 14, 0, 22, 0, 0, 0}, // Empty Nest
{ 15, 0, 26, 0, 0, 0}, // Full Nest
{ 16, 0, 33, 0x20, 0, 0}, // Gold
{ 17, 0, 3, 0, 0, 0}, // Sign of Shadow Mistress (moon stone)
{ 18, 0, 3, 0, 0, 0}, // Sign of Mother of all (bag of soil)
{ 19, 0, 40, 0, 0, 0}, // Sign of the life-giving (sun star)
{ 20, 0, 20, 0x200, 0, 0}, // King's Horn
{ 21, 0, 3, 0, 0, 0}, // Golden Sword of Mashaar
// Masks
{ 22, 0, 3, 0x40, 0, 0}, // Mask of Death
{ 23, 0, 3, 0x80, 0, 0}, // Mask of Bonding
{ 24, 0, 3, 0x100, 0, 0}, // Mask of Birth
// Objects of power
{ 25, 0, 3, 0, 1, 0}, // Eye in the Storm
{ 26, 0, 3, 0, 2, 0}, // Sky Hammer
{ 27, 0, 3, 0, 4, 0}, // Fire in the Clouds
{ 28, 0, 3, 0, 8, 0}, // Within and Without
{ 29, 0, 3, 0, 0x10, 0}, // Eye in the Cyclone
{ 30, 0, 3, 0, 0x20, 0}, // River that Winds
// Musical instruments
{ 31, 0, 3, 0, 0x40, 0}, // Trumpet
{ 32, 0, 3, 0, 0x80, 0}, // -- unused (but still has a dialog line)
{ 33, 0, 3, 0, 0x100, 0}, // Drum
{ 34, 0, 3, 0, 0x200, 0}, // -- unused (but still has a dialog line)
{ 35, 0, 3, 0, 0x400, 0}, // -- unused (but still has a dialog line)
{ 36, 0, 3, 0, 0x800, 0}, // Ring
// Tablets
{ 37, 0, 3, 0, 0, 0}, // Tablet #1 (Mo)
{ 38, 0, 42, 0x2000, 0, 0}, // Tablet #2 (Morkus' Lair)
{ 39, 0, 3, 0, 0, 0}, // Tablet #3 (White Arch?)
{ 40, 0, 3, 0, 0, 0}, // Tablet #4
{ 41, 0, 3, 0, 0, 0}, // Tablet #5
{ 42, 0, 3, 0x8000, 0, 0} // Tablet #6 (Castra)
};
uint16 kObjectLocations[100] = {
0x112, 0xFFFF,
0x202, 0xFFFF,
0x120, 0xFFFF,
0x340, 0x44B, 0x548, 0x640, 0x717, 0x830, 0xFFFF,
0x340, 0x44B, 0x548, 0x640, 0x717, 0x830, 0xFFFF,
0, 0xFFFF,
0x344, 0x53A, 0x831, 0xFFFF,
0x331, 0x420, 0x54B, 0x637, 0x716, 0x840, 0xFFFF,
0x834A, 0x8430, 0x8531, 0x644, 0x745, 0x838, 0xFFFF,
0x510, 0xFFFF,
0xC04, 0xFFFF,
0xFFFF
};
perso_t kPersons[] = {
// room, aid, party mask, id, flags, X,bank,X, X,sprId,sprX,speed, X
{ 0x103, 230, PersonMask::pmGregor, PersonId::pidGregor , 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0x116, 231, PersonMask::pmDina , PersonId::pidDina , 0, 4, 2, 0, 0, 3, 9, 0, 0 },
{ 0x202, 232, PersonMask::pmTau , PersonId::pidTau , 0, 8, 3, 0, 0, 0, 0, 0, 0 },
{ 0x109, 233, PersonMask::pmMonk , PersonId::pidMonk , 0, 12, 4, 0, 0, 6, 52, 0, 0 },
{ 0x108, 234, PersonMask::pmJabber, PersonId::pidJabber , 0, 18, 5, 0, 0, 2, 0, 0, 0 },
{ 0x103, 235, PersonMask::pmEloi , PersonId::pidEloi , 0, 22, 6, 0, 0, 4, 20, 0, 0 },
{ 0x301, 236, PersonMask::pmMungo , PersonId::pidMungo , 0, 28, 8, 0, 0, 11, 45, 0, 0 },
{ 0x628, 237, PersonMask::pmEve , PersonId::pidEve , 0, 30, 10, 0, 0, 7, 35, 0, 0 },
{ 0x81A, 238, PersonMask::pmShazia, PersonId::pidShazia , 0, 34, 11, 0, 0, 1, 11, 0, 0 },
{ 0x330, 239, PersonMask::pmLeader, PersonId::pidChongOfChamaar , 0, 38, 13, 0, 0, 10, 0, 0, 0 },
{ 0x41B, 239, PersonMask::pmLeader, PersonId::pidUlanOfUlele , 0, 46, 15, 0, 0, 13, 0, 0, 0 },
{ 0x53B, 239, PersonMask::pmLeader, PersonId::pidKommalaOfKoto , 0, 42, 14, 0, 0, 9, 0, 0, 0 },
{ 0x711, 239, PersonMask::pmLeader, PersonId::pidCabukaOfCantura , 0, 50, 16, 0, 0, 14, 0, 0, 0 },
{ 0xA02, 239, PersonMask::pmLeader, PersonId::pidMarindaOfEmbalmers, 0, 54, 17, 0, 0, 0, 0, 0, 0 },
{ 0x628, 239, PersonMask::pmLeader, PersonId::pidFuggOfTamara , 0, 62, 18, 0, 0, 12, 0, 0, 0 },
{ 0x801, 239, PersonMask::pmLeader, PersonId::pidChongOfChamaar , 0, 38, 13, 0, 0, 10, 0, 0, 0 },
{ 0x41B, 10, PersonMask::pmQuest , PersonId::pidUlanOfUlele , PersonFlags::pfType2 , 46, 15, 0, 0, 13, 0, 0, 0 },
{ 0x711, 11, PersonMask::pmQuest , PersonId::pidCabukaOfCantura , PersonFlags::pfType2 , 50, 16, 0, 0, 14, 0, 0, 0 },
{ 0x106, 240, PersonMask::pmThugg , PersonId::pidThugg , 0, 64, 7, 0, 0, 0, 61, 0, 0 },
{ 0, 13, 0, PersonId::pidNarrator , 0, 68, 12, 0, 0, 0, 0, 0, 0 },
{ 0x902, 241, PersonMask::pmQuest , PersonId::pidNarrim , 0, 70, 19, 0, 0, 0, 0, 0, 0 },
{ 0xC03, 244, PersonMask::pmMorkus, PersonId::pidMorkus , 0, 74, 20, 0, 0, 0, 0, 0, 0 },
// dinos in each valley
{ 0x332, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pfType8 , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x329, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pfType8 , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x33B, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftTriceraptor , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x317, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftVelociraptor, 0, 0, 0, 0, 0, 0, 1, 0 },
{ 0x320, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pfType12 , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x349, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftMosasaurus , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x429, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pfType8 , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x43B, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftTriceraptor , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x422, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftVelociraptor, 0, 0, 0, 0, 0, 0, 1, 0 },
{ 0x432, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftMosasaurus , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x522, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pfType8 , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x534, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftTriceraptor , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x515, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pftVelociraptor , 0, 0, 0, 0, 0, 0, 1, 0 },
{ 0x533, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftMosasaurus , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x622, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pfType8 , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x630, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftTriceraptor , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x643, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftVelociraptor, 0, 0, 0, 0, 0, 0, 1, 0 },
{ 0x63A, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftMosasaurus , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x737, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pfType8 , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x739, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftTriceraptor , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x74A, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftVelociraptor, 0, 0, 0, 0, 0, 0, 1, 0 },
{ 0x726, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftMosasaurus , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x842, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pfType8 , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x822, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftTriceraptor , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x828, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pftVelociraptor , 0, 0, 0, 0, 0, 0, 1, 0 },
{ 0x84B, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pf80 | PersonFlags::pftMosasaurus , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0xB03, 242, PersonMask::pmDino , PersonId::pidDinosaur , PersonFlags::pfType8 , 58, 252, 0, 0, 0, 0, 0, 0 },
// enemy dinos
{ 0x311, 243, PersonMask::pmEnemy , PersonId::pidEnemy , PersonFlags::pf80 | PersonFlags::pftTyrann , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x410, 243, PersonMask::pmEnemy , PersonId::pidEnemy , PersonFlags::pf80 | PersonFlags::pftTyrann , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x51B, 243, PersonMask::pmEnemy , PersonId::pidEnemy , PersonFlags::pf80 | PersonFlags::pftTyrann , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x618, 243, PersonMask::pmEnemy , PersonId::pidEnemy , PersonFlags::pf80 | PersonFlags::pftTyrann , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x71B, 243, PersonMask::pmEnemy , PersonId::pidEnemy , PersonFlags::pf80 | PersonFlags::pftTyrann , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x81B, 243, PersonMask::pmEnemy , PersonId::pidEnemy , PersonFlags::pf80 | PersonFlags::pftTyrann , 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0xFFFF, 0xFFFF, 0xFFFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFFFF, 0xFFFF, 0xFF, 0xFF, 0xFF, 0xFF},
{ 0x628, 237, PersonMask::pmEve , PersonId::pidEve , 0, 80, 9, 0, 0, 8, 35, 0, 0 },
{ 0x628, 237, PersonMask::pmEve , PersonId::pidEve , 0, 78, 10, 0, 0, 7, 35, 0, 0 }
};
Citadel _citadelList[] = {
{ 1, { 163, 182, 0, 0, 124, 147, 193, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 } },
{ 48, { 285, 286, 0, 0, 287, 288, 284, 0 }, { 114, 115, 0, 0, 116, 117, 113, 0 } },
{ 63, { 290, 291, 0, 0, 292, 293, 289, 0 }, { 119, 120, 0, 0, 121, 122, 118, 0 } },
{ 95, { 295, 296, 0, 0, 297, 298, 294, 0 }, { 124, 125, 0, 0, 126, 127, 123, 0 } },
{ 127, { 300, 301, 0, 0, 302, 303, 299, 0 }, { 129, 130, 0, 0, 131, 132, 128, 0 } },
{ 159, { 305, 306, 0, 0, 307, 308, 304, 0 }, { 134, 135, 0, 0, 136, 137, 133, 0 } },
{ 255, { 310, 311, 0, 0, 312, 313, 309, 0 }, { 139, 140, 0, 0, 141, 142, 138, 0 } }
};
prect_t _characterRects[] = { //TODO: just an array of int16s?
{ 93, 69, 223, 176},
{ 102, 86, 162, 126},
{ 88, 103, 168, 163},
{ 116, 66, 192, 176},
{ 129, 92, 202, 153},
{ 60, 95, 160, 176},
{ 155, 97, 230, 145},
{ 100, 77, 156, 145},
{ 110, 78, 170, 156},
{ 84, 76, 166, 162},
{ 57, 77, 125, 114},
{ 93, 69, 223, 175},
{ 93, 69, 223, 176},
{ 93, 69, 223, 176},
{ 154, 54, 245, 138},
{ 200, 50, 261, 116},
{ 70, 84, 162, 176},
{ 125, 101, 222, 172},
{ 188, 83, 251, 158}
};
byte _characterArray[][5] = { //TODO: struc?
{ 8, 15, 23, 25, 0xFF},
{ 0, 9, 0xFF },
{ 0, 9, 0xFF },
{ 0, 9, 0xFF },
{ 0, 13, 0xFF },
{ 16, 21, 0xFF },
{ 11, 20, 0xFF },
{ 0, 12, 0xFF },
{ 0, 9, 0xFF },
{ 0, 9, 0xFF },
{ 5, 13, 0xFF },
{ 0xFF },
{ 0, 8, 0xFF },
{ 0xFF },
{ 0, 7, 0xFF },
{ 0, 8, 0xFF },
{ 8, 12, 0xFF },
{ 0, 5, 0xFF },
{ 0, 4, 0xFF },
{ 0xFF }
};
Area kAreasTable[] = {
{ Areas::arMo , AreaType::atCitadel, 0, 0, 0, 1, 0, 0},
{ Areas::arTausCave , AreaType::atCave , 0, 112, 0, 2, 0, 0},
{ Areas::arChamaar , AreaType::atValley , 0, 133, 0, 3, 0, 0},
{ Areas::arUluru , AreaType::atValley , 0, 187, 0, 4, 0, 0},
{ Areas::arKoto , AreaType::atValley , AreaFlags::HasVelociraptors, 236, 0, 5, 0, 0},
{ Areas::arTamara , AreaType::atValley , 0, 288, 0, 6, 0, 0},
{ Areas::arCantura , AreaType::atValley , 0, 334, 0, 7, 0, 0},
{ Areas::arShandovra , AreaType::atValley , 0, 371, 0, 8, 0, 0},
{ Areas::arNarimsCave , AreaType::atCave , 0, 115, 0, 9, 0, 0},
{ Areas::arEmbalmersCave, AreaType::atCave , 0, 118, 0, 10, 0, 0},
{ Areas::arWhiteArch , AreaType::atCave , 0, 122, 0, 11, 0, 0},
{ Areas::arMoorkusLair , AreaType::atCave , 0, 127, 0, 12, 0, 0}
};
int16 tab_2CEF0[64] = {
25, 257, 0, 0, 37, 258, 38, 259, 0, 0, 24, 260, 0, 0, 0, 0,
0, 0, 53, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39, 261, 0, 0, 40, 262, 62, 263, 0, 0, 63, 264, 0, 0, 0, 0,
18, 275, 0, 0, 35, 254, 36, 255, 19, 318, 23, 256, 0, 0, 0, 0
};
int16 tab_2CF70[64] = {
65, 266, 0, 0, 66, 267, 67, 268, 0, 0, 68, 269, 0, 0, 0, 0,
0, 0, 73, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
69, 270, 0, 0, 70, 271, 71, 272, 0, 0, 72, 273, 0, 0, 0, 0,
18, 275, 0, 0, 35, 254, 36, 255, 19, 318, 23, 256, 0, 0, 0, 0,
};
int16 kActionCursors[299] = {
3, 1, 2, 4, 5, 5, 5, 0, 5, 5,
5, 5, 5, 3, 2, 5, 5, 5, 3, 2,
4, 5, 7, 7, 4, 5, 5, 0, 0, 0,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 0, 0, 0, 0, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 0, 0,
0, 0, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 0, 0, 0, 0, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 0, 5, 6,
6, 1, 6, 6, 0, 0, 6, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 6, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 0, 0, 6, 6,
53, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0
};
float _translationZ = -3400;
float flt_2DF80 = -3400;
float flt_2DF84 = 200;
} // End of namespace Cryo

616
engines/cryo/video.cpp Normal file
View File

@ -0,0 +1,616 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "cryo/cryo.h"
#include "cryo/video.h"
namespace Cryo {
HnmPlayer::HnmPlayer(CryoEngine *vm) : _vm(vm) {
_soundStarted = false;
_pendingSounds = 0;
_timeDrift = 0.0;
_nextFrameTime = 0.0;
_expectedFrameTime = 0.0;
_rate = 0.0;
_useSoundSync = false;
_useSound = true;
_soundChannel = nullptr;
_prevRight = _prevLeft = 0;
_useAdpcm = false;
_customChunkHandler = nullptr;
_preserveColor0 = false;
_safePalette = false;
for (int i = 0; i < 256; i++)
decompTable[i] = 0;
}
// Original name: CLHNM_New
void HnmPlayer::resetInternals() {
_frameNum = 0;
_file = nullptr;
_tmpBuffer[0] = nullptr;
_tmpBuffer[1] = nullptr;
_finalBuffer = nullptr;
_readBuffer = nullptr;
for (int i = 0; i < 256; i++) {
_palette[i].a = 0;
_palette[i].r = 0;
_palette[i].g = 0;
_palette[i].b = 0;
}
}
// Original name: CLHNM_SetFile
void HnmPlayer::setFile(Common::File *file) {
_file = file;
}
// Original name: CLHNM_SetupTimer
void HnmPlayer::setupTimer(float rate) {
_rate = 100.0 / rate;
}
// Original name: CLHNM_ResetInternalTimer
void HnmPlayer::resetInternalTimer() {
_timeDrift = 0.0;
_nextFrameTime = _expectedFrameTime = _vm->_timerTicks;
}
// Original name: CLHNM_Reset
void HnmPlayer::reset() {
_frameNum = 0;
_soundStarted = false;
_pendingSounds = 0;
resetInternalTimer();
}
// Original name: CLHNM_Init
void HnmPlayer::init() {
_customChunkHandler = nullptr;
_preserveColor0 = false;
_useSound = true;
}
// Original name: CLHNM_SetForceZero2Black
void HnmPlayer::setForceZero2Black(bool forceblack) {
_preserveColor0 = forceblack;
}
// Original name: CLHNM_WaitLoop
void HnmPlayer::waitLoop() {
_expectedFrameTime += _rate;
_nextFrameTime = _expectedFrameTime - _timeDrift;
if (_useSoundSync && _vm->_timerTicks > 1000.0 + _nextFrameTime)
_useSound = false;
while (_vm->_timerTicks < _nextFrameTime) ; // waste time
_timeDrift = _vm->_timerTicks - _nextFrameTime;
}
// Original name: CLHNM_WantsSound
void HnmPlayer::wantsSound(bool sound) {
_useSound = sound;
}
// Original name: CLHNM_SetupSound
void HnmPlayer::setupSound(unsigned int rate, bool stereo, bool is16bits) {
_soundChannel = new CSoundChannel(_vm->_mixer, rate, stereo, is16bits);
}
// Original name: CLHNM_CloseSound
void HnmPlayer::closeSound() {
if (_soundChannel) {
_soundChannel->stop();
delete(_soundChannel);
_soundChannel = nullptr;
}
}
// Original name: CLHNM_LoadDecompTable
void HnmPlayer::loadDecompTable(int16 *buffer) {
for (int16 i = 0; i < 256; i++) {
int16 e = *buffer++;
decompTable[i] = LE16(e);
}
}
// Original name: CLHNM_DecompADPCM
void HnmPlayer::decompADPCM(byte *buffer, int16 *output, int size) {
int16 l = _prevLeft;
int16 r = _prevRight;
size &= ~1;
while (size--) {
*output++ = l += decompTable[*buffer++];
*output++ = r += decompTable[*buffer++];
if (l > 512 || r > 512)
error("decompADPCM - Unexpected values");
}
_prevLeft = l;
_prevRight = r;
}
// Original name: CLHNM_ReadHeader
void HnmPlayer::readHeader() {
_header._signature = _file->readUint32BE();
_file->skip(4);
_header._width = _file->readUint16LE();
_header._height = _file->readUint16LE();
_file->skip(4);
_header._numbFrame = _file->readSint32LE();
_file->skip(8);
_header._bufferSize = _file->readSint32LE();
_file->skip(32);
_header._bufferSize += 4096; //TODO: checkme
}
// Original name: CLHNM_GetVersion
int16 HnmPlayer::getVersion() {
if (_header._signature == MKTAG('H','N','M','4'))
return 4;
return -1;
}
// Original name: CLHNM_AllocMemory
void HnmPlayer::allocMemory() {
// TODO: rework this code
_tmpBuffer[0] = (byte *)malloc(_header._bufferSize + 2);
if (!_tmpBuffer[0])
return;
_tmpBuffer[1] = (byte *)malloc(_header._bufferSize + 2);
if (!_tmpBuffer[1]) {
free(_tmpBuffer[0]);
_tmpBuffer[0] = nullptr;
return;
}
_readBuffer = (byte *)malloc(_header._bufferSize + 2);
if (!_readBuffer) {
free(_tmpBuffer[0]);
_tmpBuffer[0] = nullptr;
free(_tmpBuffer[1]);
_tmpBuffer[1] = nullptr;
}
}
// Original name: CLHNM_DeallocMemory
void HnmPlayer::deallocMemory() {
free(_tmpBuffer[0]);
free(_tmpBuffer[1]);
free(_readBuffer);
_tmpBuffer[0] = nullptr;
_tmpBuffer[1] = nullptr;
_readBuffer = nullptr;
}
// Original name: CLHNM_SetFinalBuffer
void HnmPlayer::setFinalBuffer(byte *buffer) {
_finalBuffer = buffer;
}
// Original name: CLHNM_GetFrameNum
int HnmPlayer::getFrameNum() {
return _frameNum;
}
// Original name: CLHNM_TryRead
void HnmPlayer::tryRead(int size) {
_file->read(_readBuffer, size);
}
// Original name: CLHNM_LoadFrame
bool HnmPlayer::loadFrame() {
tryRead(4);
int chunk = *(int *)_readBuffer;
chunk = LE32(chunk);
chunk &= 0xFFFFFF; // upper bit - keyframe mark?
if (!chunk)
return false;
if (chunk - 4 > _header._bufferSize)
error("loadFrame - Chunk size");
tryRead(chunk - 4);
_dataPtr = _readBuffer;
return true;
}
// Original name CLHNM_DecompLempelZiv
void HnmPlayer::decompLempelZiv(byte *buffer, byte *output) {
byte *inp = buffer;
byte *out = output;
unsigned int queue = 0;
int qpos = -1;
//TODO: fix for BE
#define GetBit() ( 1 & ( (qpos >= 0) ? (queue >> qpos--) : (queue = *(unsigned int*)((inp += 4) - 4)) >> ((qpos = 30) + 1) ) )
for (;;) {
if (GetBit()) {
*out++ = *inp++;
} else {
int l, o;
if (GetBit()) {
l = *inp & 7;
o = *(uint16 *)inp >> 3;
inp += 2;
o -= 8192;
if (!l)
l = *inp++;
if (!l)
break;
} else {
l = GetBit() * 2 + GetBit();
o = *(inp++) - 256;
}
l += 2;
while (l--) {
*out = *(out + o);
out++;
}
}
}
#undef GetBit
return;
}
// Original name: CLHNM_Desentrelace320
void HnmPlayer::desentrelace320(byte *frame_buffer, byte *final_buffer, uint16 height) {
unsigned int *input = (unsigned int *)frame_buffer;
unsigned int *line0 = (unsigned int *)final_buffer;
unsigned int *line1 = (unsigned int *)(final_buffer + 320);
int count = (height) / 2;
while (count--) {
int16 i;
for (i = 0; i < 320 / 4; i++) {
unsigned int p0 = *input++;
unsigned int p4 = *input++;
#if 0
*line0++ = ((p4 & 0xFF00) >> 8) | ((p4 & 0xFF000000) >> 16) | ((p0 & 0xFF00) << 8) | (p0 & 0xFF000000);
// *line0++ = (p0 & 0xFF000000) | ((p0 & 0xFF00) << 8) | ((p4 & 0xFF000000) >> 16) | ((p4 & 0xFF00) >> 8);
*line1++ = ((p0 & 0xFF0000) << 8) | ((p0 & 0xFF) << 16) | ((p4 & 0xFF0000) >> 8) | (p4 & 0xFF);
#else
*line0++ = (p0 & 0xFF) | ((p0 & 0xFF0000) >> 8) | ((p4 & 0xFF) << 16) | ((p4 & 0xFF0000) << 8);
*line1++ = ((p0 & 0xFF00) >> 8) | ((p0 & 0xFF000000) >> 16) | ((p4 & 0xFF00) << 8) | (p4 & 0xFF000000);
#endif
}
line0 += 320 / 4;
line1 += 320 / 4;
}
}
// Original name: CLHNM_Desentrelace
void HnmPlayer::desentrelace() {
switch (_header._width) {
case 320:
desentrelace320(_newFrameBuffer, _finalBuffer, _header._height);
break;
// case 480:
// CLHNM_Desentrelace480(_newFrameBuffer, finalBuffer, _header._height);
// break;
default:
error("desentrelace - Unexpected width");
}
}
// Original name: CLHNM_DecompUBA
void HnmPlayer::decompUBA(byte *output, byte *curr_buffer, byte *prev_buffer, byte *input, int width, char flags) {
// return;
byte *out_start = output;
byte count;
unsigned int code;
uint16 offs;
byte mode;
byte swap;
if ((flags & 1) == 0) {
//HNM4 classic
int twolinesabove = -(width * 2);
for (;;) {
code = READ_LE_UINT32(input) & 0xFFFFFF; //input++;
count = code & 0x1F;
if (count) {
input += 3;
offs = code >> 9;
//
mode = (code >> 5) & 0xF;
swap = mode >> 3;
byte *ref = ((mode & 1) ? prev_buffer : curr_buffer) + (output - out_start) + (offs * 2) - 32768;
int shft1, shft2;
if (mode & 2) {
// ref += twolinesabove;
shft1 = twolinesabove + 1;
shft2 = 0;
//swap ^= 1;
} else {
shft1 = 0;
shft2 = 1;
}
while (count--) {
byte b0 = ref[shft1];
byte b1 = ref[shft2];
output[swap] = b0;
output[swap ^ 1] = b1;
output += 2;
ref += (mode & 4) ? -2 : 2;
}
} else {
input++;
mode = code & 0xFF; // bits 0..4 are zero
switch (mode) {
case 0:
*(output++) = *(input++);
*(output++) = *(input++);
break;
case 0x20:
output += 2 * *(input++);
break;
case 0x40:
output += 2 * (code >> 8);
input += 2;
break;
case 0x60: {
count = *(input++);
byte color = *(input++);
while (count--) {
*(output++) = color;
*(output++) = color;
}
break;
}
default:
return;
}
}
}
} else {
assert(0);
//HNM4 hires
for (;;) {
code = READ_LE_UINT32(input) & 0xFFFFFF;
input++;
count = code & 0x3F;
if (count) {
mode = (code >> 5) & 0xF;
offs = code >> 9;
//
} else {
mode = code & 0xFF; // bits 0..5 are zero
switch (mode) {
case 0x00:
output += *input++;
break;
case 0x40:
*output++ = *input++;
*(output++ + width) = *input++;
break;
case 0x80:
output += width;
break;
default:
return;
}
}
}
}
}
// Original name: CLHNM_NextElement
bool HnmPlayer::nextElement() {
if (_frameNum == 0) {
resetInternalTimer();
_prevLeft = _prevRight = 0;
}
if (_frameNum == _header._numbFrame)
return false;
if (!loadFrame())
return false;
for (;;) {
int sz = READ_LE_UINT32(_dataPtr) & 0xFFFFFF;
_dataPtr += 4;
int16 id = READ_LE_UINT16(_dataPtr);
_dataPtr += 2;
char h6 = *_dataPtr;
_dataPtr += 1;
char h7 = *_dataPtr;
_dataPtr += 1;
switch (id) {
case MKTAG16('L', 'P'):
changePalette();
_dataPtr += sz - 8;
break;
case MKTAG16('Z', 'I'):
_frameNum++;
selectBuffers();
decompLempelZiv(_dataPtr + 4, _newFrameBuffer);
#if 0
switch (_header._width) {
case 320:
CLBlitter_RawCopy320ASM(_newFrameBuffer, _oldFrameBuffer, _header._height);
break;
case 480:
CLBlitter_RawCopy480ASM(_newFrameBuffer, _oldFrameBuffer, _header._height);
break;
case 640:
CLBlitter_RawCopy640ASM(_newFrameBuffer, _oldFrameBuffer, _header._height);
break;
default:
memcpy(_oldFrameBuffer, _newFrameBuffer, _header._width * _header._height);
}
#else
memcpy(_oldFrameBuffer, _newFrameBuffer, _header._bufferSize); //TODO strange buffer size here
#endif
if (!(h6 & 1))
desentrelace();
else {
// if(_header._width == 640)
// CLBlitter_RawCopy640(_newFrameBuffer, finalBuffer, _header._height);
// else
memcpy(_finalBuffer, _newFrameBuffer, _header._height); //TODO: wrong size?
}
if (!_soundStarted) {
_soundChannel->play();
_soundStarted = true;
}
return true;
case MKTAG16('U', 'I'):
_frameNum++;
selectBuffers();
decompUBA(_newFrameBuffer, _newFrameBuffer, _oldFrameBuffer, _dataPtr, _header._width, h6);
if (!(h6 & 1))
desentrelace();
else {
// if(_header._width == 640)
// CLBlitter_RawCopy640(_newFrameBuffer, _finalBuffer, _header._height);
// else
memcpy(_finalBuffer, _newFrameBuffer, _header._width * _header._height);
}
return true;
case MKTAG16('d', 's'):
case MKTAG16('D', 'S'):
if (_useSound) {
if (!h6) {
int sound_size = sz - 8;
if (!_useAdpcm) {
_soundChannel->queueBuffer(_dataPtr, sound_size - 2, false, _soundStarted);
} else {
#if 0
// Not used in Lost Eden
int16 *sound_buffer = (int16 *)_soundGroup->getNextBuffer();
if (!_pendingSounds) {
const int kDecompTableSize = 256 * sizeof(int16);
loadDecompTable((int16 *)_dataPtr);
decompADPCM(_dataPtr + kDecompTableSize, sound_buffer, sound_size - kDecompTableSize);
_soundGroup->assignDatas(sound_buffer, (sound_size - kDecompTableSize) * 2, false);
} else {
decompADPCM(_dataPtr, sound_buffer, sound_size);
_soundGroup->assignDatas(sound_buffer, sound_size * 2, false);
}
_pendingSounds++;
if (_soundStarted)
_soundGroup->playNextSample(_soundChannel);
#endif
}
} else
error("nextElement - unexpected flag");
}
_dataPtr += sz - 8;
break;
default:
if (_customChunkHandler)
_customChunkHandler(_dataPtr, sz - 8, id, h6, h7);
_dataPtr += sz - 8;
}
}
return true;
}
// Original name: CLHNM_GetSoundChannel
CSoundChannel *HnmPlayer::getSoundChannel() {
return _soundChannel;
}
// Original name: CLHNM_ChangePalette
void HnmPlayer::changePalette() {
CLPalette_GetLastPalette(_palette);
byte *pal = _dataPtr;
if (*(uint16 *)pal == 0xFFFF)
return;
int16 mincolor = 255;
int16 maxcolor = 0;
do {
uint16 fst = *pal++;
uint16 cnt = *pal++;
if (cnt == 0)
cnt = 256;
debug("hnm: setting palette, fst = %d, cnt = %d, last = %d", fst, cnt, fst + cnt - 1);
assert(fst + cnt <= 256);
if (mincolor > fst)
mincolor = fst;
if (maxcolor < fst + cnt)
maxcolor = fst + cnt;
color_t *color = _palette + fst;
if (_safePalette) {
while (cnt--) {
byte r = *pal++;
byte g = *pal++;
byte b = *pal++;
int16 rr = r << 10;
int16 gg = g << 10;
int16 bb = b << 10;
if (color->r != rr || color->g != gg || color->b != bb)
CLBlitter_OneBlackFlash();
color->r = rr;
color->g = gg;
color->b = bb;
color++;
}
} else {
while (cnt--) {
byte r = *pal++;
byte g = *pal++;
byte b = *pal++;
color->r = r << 10;
color->g = g << 10;
color->b = b << 10;
color++;
}
}
} while (*(uint16 *)pal != 0xFFFF);
#if 0
if (preserve_color0) {
_palette[0].r = 0;
_palette[0].g = 0;
_palette[0].b = 0;
}
#endif
// CLBlitter_Send2ScreenNextCopy(_palette, mincolor, maxcolor - mincolor);
CLBlitter_Send2ScreenNextCopy(_palette, 0, 256);
}
// Original name: CLHNM_SelectBuffers
void HnmPlayer::selectBuffers() {
if (_frameNum % 2) {
_newFrameBuffer = _tmpBuffer[1];
_oldFrameBuffer = _tmpBuffer[0];
} else {
_newFrameBuffer = _tmpBuffer[0];
_oldFrameBuffer = _tmpBuffer[1];
}
}
} // namespace Cryo

106
engines/cryo/video.h Normal file
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 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef CRYO_VIDEO_H
#define CRYO_VIDEO_H
#include "cryo/sound.h"
namespace Cryo {
class CryoEngine;
class HnmPlayer {
public:
Common::File *_file;
HNMHeader _header;
private:
CryoEngine *_vm;
void resetInternalTimer();
void wantsSound(bool sound);
void decompADPCM(byte *buffer, int16 *output, int size);
void loadDecompTable(int16 *buffer);
bool loadFrame();
void tryRead(int size);
void changePalette();
void selectBuffers();
void decompLempelZiv(byte *buffer, byte *output);
void desentrelace320(byte *frame_buffer, byte *final_buffer, uint16 height);
void desentrelace();
void decompUBA(byte *output, byte *curr_buffer, byte *prev_buffer, byte *input, int width, char flags);
void setupSoundADPCM(int16 numSounds, int16 length, int16 sampleSize, float rate, int16 mode);
void init();
bool _soundStarted;
int16 _pendingSounds;
float _timeDrift;
float _nextFrameTime;
float _expectedFrameTime;
float _rate;
bool _useSoundSync;
bool _useSound;
int16 _prevRight;
int16 _prevLeft;
bool _useAdpcm;
bool _preserveColor0;
int16 decompTable[256];
bool _safePalette;
int _frameNum;
byte *_tmpBuffer[2];
byte *_finalBuffer;
byte *_newFrameBuffer;
byte *_oldFrameBuffer;
byte *_readBuffer;
byte *_dataPtr;
color_t _palette[256];
int _totalRead;
void (*_customChunkHandler)(byte *buffer, int size, int16 id, char h6, char h7);
CSoundChannel *_soundChannel;
public:
HnmPlayer(CryoEngine *vm);
void allocMemory();
void closeSound();
void deallocMemory();
int getFrameNum();
CSoundChannel *getSoundChannel();
int16 getVersion();
bool nextElement();
void reset();
void readHeader();
void resetInternals();
void setFile(Common::File *file);
void setFinalBuffer(byte *buffer);
void setForceZero2Black(bool forceblack);
void setupSound(unsigned int rate, bool stereo, bool is16bits);
void setupTimer(float rate);
void waitLoop();
};
} // End of namespace Cryo
#endif