Merge branch 'cge'
This adds the CGE engine for the game Soltys. It is based on pull request https://github.com/scummvm/scummvm/pull/81 .
This commit is contained in:
commit
f6f8b456e7
36 changed files with 8734 additions and 0 deletions
|
@ -94,6 +94,9 @@ public:
|
|||
#if PLUGIN_ENABLED_STATIC(AGOS)
|
||||
LINK_PLUGIN(AGOS)
|
||||
#endif
|
||||
#if PLUGIN_ENABLED_STATIC(CGE)
|
||||
LINK_PLUGIN(CGE)
|
||||
#endif
|
||||
#if PLUGIN_ENABLED_STATIC(CINE)
|
||||
LINK_PLUGIN(CINE)
|
||||
#endif
|
||||
|
|
1
configure
vendored
1
configure
vendored
|
@ -83,6 +83,7 @@ add_engine he "HE71+ games" yes
|
|||
add_engine agi "AGI" yes
|
||||
add_engine agos "AGOS" yes "agos2"
|
||||
add_engine agos2 "AGOS 2 games" yes
|
||||
add_engine cge "CGE" no
|
||||
add_engine cine "Cinematique evo 1" yes
|
||||
add_engine composer "Magic Composer" no
|
||||
add_engine cruise "Cinematique evo 2" yes
|
||||
|
|
391
engines/cge/bitmap.cpp
Normal file
391
engines/cge/bitmap.cpp
Normal file
|
@ -0,0 +1,391 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#include "cge/bitmap.h"
|
||||
#include "cge/vga13h.h"
|
||||
#include "cge/cge_main.h"
|
||||
#include "common/system.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/debug-channels.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
Dac *Bitmap::_pal = NULL;
|
||||
|
||||
void Bitmap::init() {
|
||||
_pal = NULL;
|
||||
}
|
||||
|
||||
void Bitmap::deinit() {
|
||||
}
|
||||
|
||||
Bitmap::Bitmap(const char *fname) : _m(NULL), _v(NULL), _map(0) {
|
||||
debugC(1, kCGEDebugBitmap, "Bitmap::Bitmap(%s)", fname);
|
||||
|
||||
char pat[kMaxPath];
|
||||
forceExt(pat, fname, ".VBM");
|
||||
|
||||
if (_cat->exist(pat)) {
|
||||
VFile file(pat);
|
||||
if ((file._error == 0) && (!loadVBM(&file)))
|
||||
error("Bad VBM [%s]", fname);
|
||||
} else {
|
||||
error("Bad VBM [%s]", fname);
|
||||
}
|
||||
}
|
||||
|
||||
Bitmap::Bitmap(uint16 w, uint16 h, uint8 *map) : _w(w), _h(h), _m(map), _v(NULL), _map(0) {
|
||||
debugC(1, kCGEDebugBitmap, "Bitmap::Bitmap(%d, %d, map)", w, h);
|
||||
if (map)
|
||||
code();
|
||||
}
|
||||
|
||||
// following routine creates filled rectangle
|
||||
// immediately as VGA video chunks, in near memory as fast as possible,
|
||||
// especially for text line real time display
|
||||
Bitmap::Bitmap(uint16 w, uint16 h, uint8 fill)
|
||||
: _w((w + 3) & ~3), // only full uint32 allowed!
|
||||
_h(h),
|
||||
_m(NULL),
|
||||
_map(0) {
|
||||
debugC(1, kCGEDebugBitmap, "Bitmap::Bitmap(%d, %d, %d)", w, h, fill);
|
||||
|
||||
uint16 dsiz = _w >> 2; // data size (1 plane line size)
|
||||
uint16 lsiz = 2 + dsiz + 2; // uint16 for line header, uint16 for gap
|
||||
uint16 psiz = _h * lsiz; // - last gape, but + plane trailer
|
||||
uint8 *v = new uint8[4 * psiz + _h * sizeof(*_b)];// the same for 4 planes
|
||||
// + room for wash table
|
||||
assert(v != NULL);
|
||||
|
||||
*(uint16 *) v = TO_LE_16(kBmpCPY | dsiz); // data chunk hader
|
||||
memset(v + 2, fill, dsiz); // data bytes
|
||||
*(uint16 *)(v + lsiz - 2) = TO_LE_16(kBmpSKP | ((kScrWidth / 4) - dsiz)); // gap
|
||||
|
||||
// Replicate lines
|
||||
byte *destP;
|
||||
for (destP = v + lsiz; destP < (v + psiz); destP += lsiz)
|
||||
Common::copy(v, v + lsiz, destP);
|
||||
|
||||
*(uint16 *)(v + psiz - 2) = TO_LE_16(kBmpEOI); // plane trailer uint16
|
||||
|
||||
// Replicate planes
|
||||
for (destP = v + psiz; destP < (v + 4 * psiz); destP += psiz)
|
||||
Common::copy(v, v + psiz, destP);
|
||||
|
||||
HideDesc *b = (HideDesc *)(v + 4 * psiz);
|
||||
b->_skip = (kScrWidth - _w) >> 2;
|
||||
b->_hide = _w >> 2;
|
||||
|
||||
// Replicate across the entire table
|
||||
for (HideDesc *hdP = b + 1; hdP < (b + _h); hdP++)
|
||||
*hdP = *b;
|
||||
|
||||
b->_skip = 0; // fix the first entry
|
||||
_v = v;
|
||||
_b = b;
|
||||
}
|
||||
|
||||
Bitmap::Bitmap(const Bitmap &bmp) : _w(bmp._w), _h(bmp._h), _m(NULL), _v(NULL), _map(0) {
|
||||
debugC(1, kCGEDebugBitmap, "Bitmap::Bitmap(bmp)");
|
||||
uint8 *v0 = bmp._v;
|
||||
if (!v0)
|
||||
return;
|
||||
|
||||
uint16 vsiz = (uint8 *)(bmp._b) - (uint8 *)(v0);
|
||||
uint16 siz = vsiz + _h * sizeof(HideDesc);
|
||||
uint8 *v1 = new uint8[siz];
|
||||
assert(v1 != NULL);
|
||||
memcpy(v1, v0, siz);
|
||||
_b = (HideDesc *)((_v = v1) + vsiz);
|
||||
}
|
||||
|
||||
Bitmap::~Bitmap() {
|
||||
debugC(6, kCGEDebugBitmap, "Bitmap::~Bitmap()");
|
||||
|
||||
free(_m);
|
||||
delete[] _v;
|
||||
}
|
||||
|
||||
Bitmap &Bitmap::operator = (const Bitmap &bmp) {
|
||||
debugC(1, kCGEDebugBitmap, "&Bitmap::operator =");
|
||||
|
||||
uint8 *v0 = bmp._v;
|
||||
_w = bmp._w;
|
||||
_h = bmp._h;
|
||||
_m = NULL;
|
||||
_map = 0;
|
||||
delete[] _v;
|
||||
|
||||
if (v0 == NULL) {
|
||||
_v = NULL;
|
||||
} else {
|
||||
uint16 vsiz = (uint8 *)bmp._b - (uint8 *)v0;
|
||||
uint16 siz = vsiz + _h * sizeof(HideDesc);
|
||||
uint8 *v1 = (uint8 *)malloc(sizeof(uint8) * siz);
|
||||
assert(v1 != NULL);
|
||||
memcpy(v1, v0, siz);
|
||||
_b = (HideDesc *)((_v = v1) + vsiz);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint16 Bitmap::moveVmap(uint8 *buf) {
|
||||
debugC(1, kCGEDebugBitmap, "Bitmap::moveVmap(buf)");
|
||||
|
||||
if (!_v)
|
||||
return 0;
|
||||
|
||||
uint16 vsiz = (uint8 *)_b - (uint8 *)_v;
|
||||
uint16 siz = vsiz + _h * sizeof(HideDesc);
|
||||
memcpy(buf, _v, siz);
|
||||
delete[] _v;
|
||||
_b = (HideDesc *)((_v = buf) + vsiz);
|
||||
return siz;
|
||||
}
|
||||
|
||||
BitmapPtr Bitmap::code() {
|
||||
debugC(1, kCGEDebugBitmap, "Bitmap::code()");
|
||||
|
||||
if (!_m)
|
||||
return false;
|
||||
|
||||
uint16 cnt;
|
||||
|
||||
if (_v) { // old X-map exists, so remove it
|
||||
delete[] _v;
|
||||
_v = NULL;
|
||||
}
|
||||
|
||||
while (true) { // at most 2 times: for (V == NULL) & for allocated block;
|
||||
uint8 *im = _v + 2;
|
||||
uint16 *cp = (uint16 *) _v;
|
||||
int bpl;
|
||||
|
||||
if (_v) { // 2nd pass - fill the hide table
|
||||
for (uint16 i = 0; i < _h; i++) {
|
||||
_b[i]._skip = 0xFFFF;
|
||||
_b[i]._hide = 0x0000;
|
||||
}
|
||||
}
|
||||
for (bpl = 0; bpl < 4; bpl++) { // once per each bitplane
|
||||
uint8 *bm = _m;
|
||||
bool skip = (bm[bpl] == kPixelTransp);
|
||||
uint16 j;
|
||||
|
||||
cnt = 0;
|
||||
for (uint16 i = 0; i < _h; i++) { // once per each line
|
||||
uint8 pix;
|
||||
for (j = bpl; j < _w; j += 4) {
|
||||
pix = bm[j];
|
||||
if (_v && pix != kPixelTransp) {
|
||||
if (j < _b[i]._skip)
|
||||
_b[i]._skip = j;
|
||||
|
||||
if (j >= _b[i]._hide)
|
||||
_b[i]._hide = j + 1;
|
||||
}
|
||||
if ((pix == kPixelTransp) != skip || cnt >= 0x3FF0) { // end of block
|
||||
cnt |= (skip) ? kBmpSKP : kBmpCPY;
|
||||
if (_v)
|
||||
*cp = TO_LE_16(cnt); // store block description uint16
|
||||
|
||||
cp = (uint16 *) im;
|
||||
im += 2;
|
||||
skip = (pix == kPixelTransp);
|
||||
cnt = 0;
|
||||
}
|
||||
if (!skip) {
|
||||
if (_v)
|
||||
*im = pix;
|
||||
im++;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
|
||||
bm += _w;
|
||||
if (_w < kScrWidth) {
|
||||
if (skip) {
|
||||
cnt += (kScrWidth - j + 3) / 4;
|
||||
} else {
|
||||
cnt |= kBmpCPY;
|
||||
if (_v)
|
||||
*cp = TO_LE_16(cnt);
|
||||
|
||||
cp = (uint16 *) im;
|
||||
im += 2;
|
||||
skip = true;
|
||||
cnt = (kScrWidth - j + 3) / 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cnt && ! skip) {
|
||||
cnt |= kBmpCPY;
|
||||
if (_v)
|
||||
*cp = TO_LE_16(cnt);
|
||||
|
||||
cp = (uint16 *) im;
|
||||
im += 2;
|
||||
}
|
||||
if (_v)
|
||||
*cp = TO_LE_16(kBmpEOI);
|
||||
cp = (uint16 *) im;
|
||||
im += 2;
|
||||
}
|
||||
if (_v)
|
||||
break;
|
||||
|
||||
uint16 sizV = (uint16)(im - 2 - _v);
|
||||
_v = new uint8[sizV + _h * sizeof(*_b)];
|
||||
assert(_v != NULL);
|
||||
|
||||
_b = (HideDesc *)(_v + sizV);
|
||||
}
|
||||
cnt = 0;
|
||||
for (uint16 i = 0; i < _h; i++) {
|
||||
if (_b[i]._skip == 0xFFFF) { // whole line is skipped
|
||||
_b[i]._skip = (cnt + kScrWidth) >> 2;
|
||||
cnt = 0;
|
||||
} else {
|
||||
uint16 s = _b[i]._skip & ~3;
|
||||
uint16 h = (_b[i]._hide + 3) & ~3;
|
||||
_b[i]._skip = (cnt + s) >> 2;
|
||||
_b[i]._hide = (h - s) >> 2;
|
||||
cnt = kScrWidth - h;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
bool Bitmap::solidAt(int16 x, int16 y) {
|
||||
debugC(6, kCGEDebugBitmap, "Bitmap::solidAt(%d, %d)", x, y);
|
||||
|
||||
if ((x >= _w) || (y >= _h))
|
||||
return false;
|
||||
|
||||
uint8 *m = _v;
|
||||
uint16 r = static_cast<uint16>(x) % 4;
|
||||
uint16 n0 = (kScrWidth * y + x) / 4;
|
||||
uint16 n = 0;
|
||||
|
||||
while (r) {
|
||||
uint16 w, t;
|
||||
|
||||
w = READ_LE_UINT16(m);
|
||||
m += 2;
|
||||
t = w & 0xC000;
|
||||
w &= 0x3FFF;
|
||||
|
||||
switch (t) {
|
||||
case kBmpEOI:
|
||||
r--;
|
||||
case kBmpSKP:
|
||||
w = 0;
|
||||
break;
|
||||
case kBmpREP:
|
||||
w = 1;
|
||||
break;
|
||||
}
|
||||
m += w;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
uint16 w, t;
|
||||
|
||||
w = READ_LE_UINT16(m);
|
||||
m += 2;
|
||||
t = w & 0xC000;
|
||||
w &= 0x3FFF;
|
||||
|
||||
if (n > n0)
|
||||
return false;
|
||||
|
||||
n += w;
|
||||
switch (t) {
|
||||
case kBmpEOI:
|
||||
return false;
|
||||
case kBmpSKP:
|
||||
w = 0;
|
||||
break;
|
||||
case kBmpREP:
|
||||
case kBmpCPY:
|
||||
if (n - w <= n0 && n > n0)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
m += ((t == kBmpREP) ? 1 : w);
|
||||
}
|
||||
}
|
||||
|
||||
bool Bitmap::loadVBM(VFile *f) {
|
||||
debugC(5, kCGEDebugBitmap, "Bitmap::loadVBM(f)");
|
||||
|
||||
uint16 p = 0, n = 0;
|
||||
if (f->_error == 0)
|
||||
f->read((uint8 *)&p, sizeof(p));
|
||||
p = FROM_LE_16(p);
|
||||
|
||||
if (f->_error == 0)
|
||||
f->read((uint8 *)&n, sizeof(n));
|
||||
n = FROM_LE_16(n);
|
||||
|
||||
if (f->_error == 0)
|
||||
f->read((uint8 *)&_w, sizeof(_w));
|
||||
_w = FROM_LE_16(_w);
|
||||
|
||||
if (f->_error == 0)
|
||||
f->read((uint8 *)&_h, sizeof(_h));
|
||||
_h = FROM_LE_16(_h);
|
||||
|
||||
if (f->_error == 0) {
|
||||
if (p) {
|
||||
if (_pal) {
|
||||
// Read in the palette
|
||||
byte palData[kPalSize];
|
||||
f->read(palData, kPalSize);
|
||||
|
||||
const byte *srcP = palData;
|
||||
for (int idx = 0; idx < kPalCount; idx++, srcP += 3) {
|
||||
_pal[idx]._r = *srcP;
|
||||
_pal[idx]._g = *(srcP + 1);
|
||||
_pal[idx]._b = *(srcP + 2);
|
||||
}
|
||||
} else
|
||||
f->seek(f->mark() + kPalSize);
|
||||
}
|
||||
}
|
||||
if ((_v = new uint8[n]) == NULL)
|
||||
return false;
|
||||
|
||||
if (f->_error == 0)
|
||||
f->read(_v, n);
|
||||
|
||||
_b = (HideDesc *)(_v + n - _h * sizeof(HideDesc));
|
||||
return (f->_error == 0);
|
||||
}
|
||||
|
||||
} // End of namespace CGE
|
96
engines/cge/bitmap.h
Normal file
96
engines/cge/bitmap.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_BITMAP_H
|
||||
#define CGE_BITMAP_H
|
||||
|
||||
#include "cge/fileio.h"
|
||||
//#include "cge/general.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
#define kBmpEOI 0x0000
|
||||
#define kBmpSKP 0x4000
|
||||
#define kBmpREP 0x8000
|
||||
#define kBmpCPY 0xC000
|
||||
|
||||
#define kMaxPath 128
|
||||
|
||||
#include "common/pack-start.h"
|
||||
|
||||
struct Bgr4 {
|
||||
uint16 _b : 2;
|
||||
uint16 _B : 6;
|
||||
uint16 _g : 2;
|
||||
uint16 _G : 6;
|
||||
uint16 _r : 2;
|
||||
uint16 _R : 6;
|
||||
uint16 _Z : 8;
|
||||
};
|
||||
|
||||
|
||||
struct HideDesc {
|
||||
uint16 _skip;
|
||||
uint16 _hide;
|
||||
};
|
||||
|
||||
#include "common/pack-end.h"
|
||||
|
||||
class Bitmap {
|
||||
bool loadVBM(VFile *f);
|
||||
public:
|
||||
static Dac *_pal;
|
||||
uint16 _w;
|
||||
uint16 _h;
|
||||
uint8 *_m;
|
||||
uint8 *_v;
|
||||
int32 _map;
|
||||
HideDesc *_b;
|
||||
|
||||
Bitmap(const char *fname);
|
||||
Bitmap(uint16 w, uint16 h, uint8 *map);
|
||||
Bitmap(uint16 w, uint16 h, uint8 fill);
|
||||
Bitmap(const Bitmap &bmp);
|
||||
~Bitmap();
|
||||
|
||||
static void init();
|
||||
static void deinit();
|
||||
Bitmap *code();
|
||||
Bitmap &operator = (const Bitmap &bmp);
|
||||
void hide(int16 x, int16 y);
|
||||
void show(int16 x, int16 y);
|
||||
void xShow(int16 x, int16 y);
|
||||
bool solidAt(int16 x, int16 y);
|
||||
uint16 moveVmap(uint8 *buf);
|
||||
};
|
||||
|
||||
|
||||
typedef Bitmap *BitmapPtr;
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
226
engines/cge/cge.cpp
Normal file
226
engines/cge/cge.cpp
Normal file
|
@ -0,0 +1,226 @@
|
|||
/* 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 "common/EventRecorder.h"
|
||||
#include "common/file.h"
|
||||
#include "common/fs.h"
|
||||
#include "engines/util.h"
|
||||
#include "cge/cge.h"
|
||||
#include "cge/vga13h.h"
|
||||
#include "cge/cge_main.h"
|
||||
#include "cge/talk.h"
|
||||
#include "cge/text.h"
|
||||
#include "cge/walk.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
const int CGEEngine::_maxCaveArr[5] = {1, 8, 16, 23, 24};
|
||||
|
||||
CGEEngine::CGEEngine(OSystem *syst, const ADGameDescription *gameDescription)
|
||||
: Engine(syst), _gameDescription(gameDescription), _randomSource("cge") {
|
||||
|
||||
// Debug/console setup
|
||||
DebugMan.addDebugChannel(kCGEDebugBitmap, "bitmap", "CGE Bitmap debug channel");
|
||||
DebugMan.addDebugChannel(kCGEDebugFile, "file", "CGE IO debug channel");
|
||||
DebugMan.addDebugChannel(kCGEDebugEngine, "engine", "CGE Engine debug channel");
|
||||
|
||||
_startupMode = 1;
|
||||
_demoText = kDemo;
|
||||
_oldLev = 0;
|
||||
_pocPtr = 0;
|
||||
|
||||
}
|
||||
|
||||
void CGEEngine::initCaveValues() {
|
||||
for (int i = 0; i < kCaveMax; i++) {
|
||||
_heroXY[i].x = 0;
|
||||
_heroXY[i].y = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < kCaveMax + 1; i++) {
|
||||
_barriers[i]._horz = 0xFF;
|
||||
_barriers[i]._vert = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void CGEEngine::init() {
|
||||
debugC(1, kCGEDebugEngine, "CGEEngine::setup()");
|
||||
|
||||
// Initialise fields
|
||||
_lastFrame = 0;
|
||||
_lastTick = 0;
|
||||
_hero = NULL;
|
||||
_shadow = NULL;
|
||||
_miniCave = NULL;
|
||||
_miniShp = NULL;
|
||||
_miniShpList = NULL;
|
||||
_sprite = NULL;
|
||||
_dat = new CFile(kDatName, XCrypt);
|
||||
_cat = new BtFile(kCatName, XCrypt);
|
||||
|
||||
// Create debugger console
|
||||
_console = new CGEConsole(this);
|
||||
|
||||
// Initialise classes that have static members
|
||||
Bitmap::init();
|
||||
Talk::init();
|
||||
Cluster::init(this);
|
||||
|
||||
// Initialise engine objects
|
||||
_text = new Text(this, "CGE");
|
||||
_vga = new Vga();
|
||||
_sys = new System(this);
|
||||
_pocLight = new PocLight(this);
|
||||
for (int i = 0; i < kPocketNX; i++)
|
||||
_pocket[i] = NULL;
|
||||
_horzLine = new HorizLine(this);
|
||||
_infoLine = new InfoLine(this, kInfoW);
|
||||
_cavLight = new CavLight(this);
|
||||
_debugLine = new InfoLine(this, kScrWidth);
|
||||
_snail = new Snail(this, false);
|
||||
_snail_ = new Snail(this, true);
|
||||
|
||||
_mouse = new Mouse(this);
|
||||
_keyboard = new Keyboard(this);
|
||||
_eventManager = new EventManager();
|
||||
_fx = new Fx(16); // must precede SOUND!!
|
||||
_sound = new Sound(this);
|
||||
|
||||
_offUseCount = atoi(_text->getText(kOffUseCount));
|
||||
_music = true;
|
||||
|
||||
for (int i = 0; i < kPocketNX; i++)
|
||||
_pocref[i] = -1;
|
||||
_volume[0] = 0;
|
||||
_volume[1] = 0;
|
||||
|
||||
initCaveValues();
|
||||
|
||||
_maxCave = 0;
|
||||
_dark = false;
|
||||
_game = false;
|
||||
_finis = false;
|
||||
_now = 1;
|
||||
_lev = -1;
|
||||
_recentStep = -2;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
_flag[i] = false;
|
||||
|
||||
_mode = 0;
|
||||
_soundOk = 1;
|
||||
_sprTv = NULL;
|
||||
_gameCase2Cpt = 0;
|
||||
_offUseCount = 0;
|
||||
|
||||
_startGameSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
|
||||
}
|
||||
|
||||
void CGEEngine::deinit() {
|
||||
// Call classes with static members to clear them up
|
||||
Talk::deinit();
|
||||
Bitmap::deinit();
|
||||
Cluster::init(this);
|
||||
|
||||
// Remove all of our debug levels here
|
||||
DebugMan.clearAllDebugChannels();
|
||||
|
||||
delete _console;
|
||||
_midiPlayer.killMidi();
|
||||
|
||||
// Delete engine objects
|
||||
delete _vga;
|
||||
delete _sys;
|
||||
delete _sprite;
|
||||
delete _miniCave;
|
||||
delete _shadow;
|
||||
delete _horzLine;
|
||||
delete _infoLine;
|
||||
delete _cavLight;
|
||||
delete _debugLine;
|
||||
delete _text;
|
||||
delete _pocLight;
|
||||
delete _keyboard;
|
||||
delete _mouse;
|
||||
delete _eventManager;
|
||||
delete _fx;
|
||||
delete _sound;
|
||||
delete _snail;
|
||||
delete _snail_;
|
||||
delete _hero;
|
||||
delete _dat;
|
||||
delete _cat;
|
||||
|
||||
if (_miniShpList) {
|
||||
for (int i = 0; _miniShpList[i]; ++i)
|
||||
delete _miniShpList[i];
|
||||
delete[] _miniShpList;
|
||||
}
|
||||
}
|
||||
|
||||
CGEEngine::~CGEEngine() {
|
||||
debugC(1, kCGEDebugEngine, "CGEEngine::~CGEEngine()");
|
||||
}
|
||||
|
||||
Common::Error CGEEngine::run() {
|
||||
debugC(1, kCGEDebugEngine, "CGEEngine::run()");
|
||||
|
||||
if (_gameDescription->flags & ADGF_DEMO) {
|
||||
warning("Demos of Soltys are not supported.\nPlease get a free version on ScummVM download page");
|
||||
return Common::kUnsupportedGameidError;
|
||||
}
|
||||
|
||||
// Initialize graphics using following:
|
||||
initGraphics(320, 200, false);
|
||||
|
||||
// Setup necessary game objects
|
||||
init();
|
||||
// Run the game
|
||||
cge_main();
|
||||
|
||||
// Remove game objects
|
||||
deinit();
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
bool CGEEngine::hasFeature(EngineFeature f) const {
|
||||
return
|
||||
(f == kSupportsRTL) ||
|
||||
(f == kSupportsLoadingDuringRuntime) ||
|
||||
(f == kSupportsSavingDuringRuntime);
|
||||
}
|
||||
|
||||
bool CGEEngine::canLoadGameStateCurrently() {
|
||||
return (_startupMode == 0) && _mouse->_active;
|
||||
}
|
||||
|
||||
bool CGEEngine::canSaveGameStateCurrently() {
|
||||
return (_startupMode == 0) && _mouse->_active;
|
||||
}
|
||||
|
||||
} // End of namespace CGE
|
275
engines/cge/cge.h
Normal file
275
engines/cge/cge.h
Normal file
|
@ -0,0 +1,275 @@
|
|||
/* 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 CGE_H
|
||||
#define CGE_H
|
||||
|
||||
#include "cge/general.h"
|
||||
#include "common/random.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/serializer.h"
|
||||
#include "common/str.h"
|
||||
#include "common/rect.h"
|
||||
#include "engines/engine.h"
|
||||
#include "gui/debugger.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "engines/advancedDetector.h"
|
||||
#include "cge/console.h"
|
||||
#include "cge/bitmap.h"
|
||||
#include "cge/sound.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
class Console;
|
||||
class Sprite;
|
||||
|
||||
#define kSavegameVersion 2
|
||||
#define kSavegameStrSize 11
|
||||
#define kPocketX 174
|
||||
#define kPocketY 176
|
||||
#define kPocketDX 18
|
||||
#define kPocketDY 22
|
||||
#define kPocketNX 8
|
||||
#define kPocketNY 1
|
||||
#define kPocketSX 8
|
||||
#define kPocketSY 3
|
||||
#define kCaveDx 9
|
||||
#define kCaveDy 10
|
||||
#define kCaveNx 8
|
||||
#define kCaveNy 3
|
||||
#define kCaveMax kCaveNx * kCaveNy
|
||||
|
||||
|
||||
// our engine debug channels
|
||||
enum {
|
||||
kCGEDebugBitmap = 1 << 0,
|
||||
kCGEDebugFile = 1 << 1,
|
||||
kCGEDebugEngine = 1 << 2
|
||||
};
|
||||
|
||||
enum SnList {
|
||||
kNear, kTake
|
||||
};
|
||||
|
||||
enum CallbackType {
|
||||
kNullCB = 0, kQGame, kMiniStep, kXCave, kSndSetVolume
|
||||
};
|
||||
|
||||
struct SavegameHeader {
|
||||
uint8 version;
|
||||
Common::String saveName;
|
||||
Graphics::Surface *thumbnail;
|
||||
int saveYear, saveMonth, saveDay;
|
||||
int saveHour, saveMinutes;
|
||||
int totalFrames;
|
||||
};
|
||||
|
||||
extern const char *savegameStr;
|
||||
|
||||
struct Bar {
|
||||
uint8 _horz;
|
||||
uint8 _vert;
|
||||
};
|
||||
|
||||
class CGEEngine : public Engine {
|
||||
private:
|
||||
uint32 _lastFrame, _lastTick;
|
||||
void tick();
|
||||
void syncHeader(Common::Serializer &s);
|
||||
static void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header);
|
||||
void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream, bool tiny = false);
|
||||
bool savegameExists(int slotNumber);
|
||||
Common::String generateSaveName(int slot);
|
||||
public:
|
||||
CGEEngine(OSystem *syst, const ADGameDescription *gameDescription);
|
||||
~CGEEngine();
|
||||
virtual bool hasFeature(EngineFeature f) const;
|
||||
virtual bool canLoadGameStateCurrently();
|
||||
virtual bool canSaveGameStateCurrently();
|
||||
virtual Common::Error loadGameState(int slot);
|
||||
virtual Common::Error saveGameState(int slot, const Common::String &desc);
|
||||
|
||||
static const int _maxCaveArr[5];
|
||||
|
||||
const ADGameDescription *_gameDescription;
|
||||
int _startupMode;
|
||||
int _demoText;
|
||||
int _oldLev;
|
||||
int _pocPtr;
|
||||
bool _music;
|
||||
int _pocref[kPocketNX];
|
||||
uint8 _volume[2];
|
||||
int _maxCave;
|
||||
bool _flag[4];
|
||||
bool _dark;
|
||||
bool _game;
|
||||
bool _finis;
|
||||
int _now;
|
||||
int _lev;
|
||||
int _mode;
|
||||
int _soundOk;
|
||||
int _gameCase2Cpt;
|
||||
int _offUseCount;
|
||||
|
||||
Sprite *_sprTv;
|
||||
Sprite *_sprK1;
|
||||
Sprite *_sprK2;
|
||||
Sprite *_sprK3;
|
||||
|
||||
Common::Point _heroXY[kCaveMax];
|
||||
Bar _barriers[kCaveMax];
|
||||
|
||||
Common::RandomSource _randomSource;
|
||||
MusicPlayer _midiPlayer;
|
||||
BitmapPtr *_miniShp;
|
||||
BitmapPtr *_miniShpList;
|
||||
int _startGameSlot;
|
||||
|
||||
virtual Common::Error run();
|
||||
GUI::Debugger *getDebugger() {
|
||||
return _console;
|
||||
}
|
||||
|
||||
void cge_main();
|
||||
void switchCave(int cav);
|
||||
void startCountDown();
|
||||
void quit();
|
||||
void resetQSwitch();
|
||||
void optionTouch(int opt, uint16 mask);
|
||||
void resetGame();
|
||||
bool loadGame(int slotNumber, SavegameHeader *header = NULL, bool tiny = false);
|
||||
void setMapBrick(int x, int z);
|
||||
void switchMapping();
|
||||
void loadSprite(const char *fname, int ref, int cav, int col, int row, int pos);
|
||||
void loadScript(const char *fname);
|
||||
void loadUser();
|
||||
void runGame();
|
||||
bool showTitle(const char *name);
|
||||
void movie(const char *ext);
|
||||
void inf(const char *text);
|
||||
void selectSound();
|
||||
void dummy() {}
|
||||
void NONE();
|
||||
void SB();
|
||||
void caveDown();
|
||||
void caveUp();
|
||||
void xCave();
|
||||
void qGame();
|
||||
void SBM();
|
||||
void GUS();
|
||||
void GUSM();
|
||||
void MIDI();
|
||||
void AUTO();
|
||||
void setPortD();
|
||||
void setPortM();
|
||||
void setIRQ();
|
||||
void setDMA();
|
||||
void mainLoop();
|
||||
void handleFrame();
|
||||
void saveGame(int slotNumber, const Common::String &desc);
|
||||
static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
|
||||
void switchMusic();
|
||||
void selectPocket(int n);
|
||||
void expandSprite(Sprite *spr);
|
||||
void contractSprite(Sprite *spr);
|
||||
int findPocket(Sprite *spr);
|
||||
void feedSnail(Sprite *spr, SnList snq);
|
||||
void pocFul();
|
||||
void hide1(Sprite *spr);
|
||||
void loadMapping();
|
||||
void saveSound();
|
||||
void heroCover(int cvr);
|
||||
void trouble(int seq, int text);
|
||||
void offUse();
|
||||
void tooFar();
|
||||
void loadHeroXY();
|
||||
void keyClick();
|
||||
void switchColorMode();
|
||||
void killSprite();
|
||||
void switchDebug();
|
||||
void miniStep(int stp);
|
||||
void postMiniStep(int stp);
|
||||
void showBak(int ref);
|
||||
void initCaveValues();
|
||||
|
||||
void snBackPt(Sprite *spr, int stp);
|
||||
void snHBarrier(const int cave, const int barX);
|
||||
void snVBarrier(const int cave, const int barY);
|
||||
void snCover(Sprite *spr, int xref);
|
||||
void snFlag(int indx, bool v);
|
||||
void snFlash(bool on);
|
||||
void snGame(Sprite *spr, int num);
|
||||
void snGhost(Bitmap *bmp);
|
||||
void snGive(Sprite *spr, int stp);
|
||||
void snHide(Sprite *spr, int val);
|
||||
void snKeep(Sprite *spr, int stp);
|
||||
void snKill(Sprite *spr);
|
||||
void snLevel(Sprite *spr, int lev);
|
||||
void snLight(bool in);
|
||||
void snMouse(bool on);
|
||||
void snNNext(Sprite *spr, int p);
|
||||
void snPort(Sprite *spr, int port);
|
||||
void snReach(Sprite *spr, int mode);
|
||||
void snRelZ(Sprite *spr, int z);
|
||||
void snRNNext(Sprite *spr, int p);
|
||||
void snRTNext(Sprite *spr, int p);
|
||||
void snSend(Sprite *spr, int val);
|
||||
void snRelX(Sprite *spr, int x);
|
||||
void snRelY(Sprite *spr, int y);
|
||||
void snRmNear(Sprite *spr);
|
||||
void snRmTake(Sprite *spr);
|
||||
void snRSeq(Sprite *spr, int val);
|
||||
void snSeq(Sprite *spr, int val);
|
||||
void snSetRef(Sprite *spr, int nr);
|
||||
void snSetX(Sprite *spr, int x);
|
||||
void snSetX0(int cav, int x0);
|
||||
void snSetXY(Sprite *spr, uint16 xy);
|
||||
void snSetY(Sprite *spr, int y);
|
||||
void snSetY0(int cav, int y0);
|
||||
void snSetZ(Sprite *spr, int z);
|
||||
void snSlave(Sprite *spr, int ref);
|
||||
void snSound(Sprite *spr, int wav);
|
||||
void snSwap(Sprite *spr, int xref);
|
||||
void snTNext(Sprite *spr, int p);
|
||||
void snTrans(Sprite *spr, int trans);
|
||||
void snUncover(Sprite *spr, Sprite *xspr);
|
||||
void snWalk(Sprite *spr, int x, int y);
|
||||
void snZTrim(Sprite *spr);
|
||||
protected:
|
||||
int _recentStep;
|
||||
|
||||
private:
|
||||
CGEConsole *_console;
|
||||
void init();
|
||||
void deinit();
|
||||
};
|
||||
|
||||
// Example console class
|
||||
class Console : public GUI::Debugger {
|
||||
public:
|
||||
Console(CGEEngine *vm) {}
|
||||
virtual ~Console() {}
|
||||
};
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
1572
engines/cge/cge_main.cpp
Normal file
1572
engines/cge/cge_main.cpp
Normal file
File diff suppressed because it is too large
Load diff
140
engines/cge/cge_main.h
Normal file
140
engines/cge/cge_main.h
Normal file
|
@ -0,0 +1,140 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_CGEMAIN_H
|
||||
#define CGE_CGEMAIN_H
|
||||
|
||||
#include "cge/vga13h.h"
|
||||
#include "cge/events.h"
|
||||
#include "cge/sound.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
#define kCaveX 4
|
||||
#define kCaveY 166
|
||||
#define kCaveSX 0
|
||||
#define kCaveSY 0
|
||||
#define kInfoX 177
|
||||
#define kInfoY 164
|
||||
#define kInfoW 140
|
||||
#define kButtonX 151
|
||||
#define kButtonY 164
|
||||
#define kMiniX 86
|
||||
#define kMiniY 162
|
||||
#define kLineMax 512
|
||||
#define kDistMax 3
|
||||
#define kLgoExt ".LGO"
|
||||
#define kSvgExt ".SVG"
|
||||
#define kPaylistExt ".X00"
|
||||
#define kWinkExt ".X01"
|
||||
#define kIntroExt ".X02"
|
||||
#define kEndgExt ".X03"
|
||||
#define kWalkSide 10
|
||||
#define kBusyRef 500
|
||||
#define kSystemRate 6 // 12 Hz
|
||||
#define kHeroFun0 (40 * 12)
|
||||
#define kHeroFun1 ( 2 * 12)
|
||||
#define kGetNamePrompt 50
|
||||
#define kGetNameTitle 51
|
||||
#define kTSeq 96
|
||||
//Useless?
|
||||
//#define kBadSnd 97
|
||||
//#define kBadMidi 98
|
||||
#define kNoMusic 98
|
||||
#define kBadSVG 99
|
||||
#define kSeqHTalk (kTSeq + 4)
|
||||
#define kSeqTooFar (kTSeq + 5)
|
||||
#define kSeqNoWay (kTSeq + 5)
|
||||
#define kSeqPocketFull (kTSeq + 5)
|
||||
#define kSeqOffUse (kTSeq + 6)
|
||||
#define kQuitTitle 200
|
||||
#define kQuit 201
|
||||
#define kNoQuit 202
|
||||
#define kDemo 300
|
||||
#define kOffUseCount 600
|
||||
#define kOffUse 601
|
||||
#define kNoWay 671
|
||||
#define kTooFar 681
|
||||
#define kPocketFull 691
|
||||
#define kPanHeight 40
|
||||
#define kScrWidth 320
|
||||
#define kScrHeight 200
|
||||
#define kWorldHeight (kScrHeight - kPanHeight)
|
||||
#define kStackSize 2048
|
||||
#define kSavegameCheckSum (1956 + _now + _oldLev + _game + _music + _demoText)
|
||||
#define kSavegame0Name ("{{INIT}}" kSvgExt)
|
||||
#define kSavegame0File VFile
|
||||
#define kSavegameStrSize 11
|
||||
#define kGameFrameDelay (1000 / 50)
|
||||
#define kGameTickDelay (1000 / 62)
|
||||
|
||||
|
||||
|
||||
class System : public Sprite {
|
||||
public:
|
||||
int _funDel;
|
||||
|
||||
System(CGEEngine *vm);
|
||||
|
||||
void setPal();
|
||||
void funTouch();
|
||||
virtual void touch(uint16 mask, int x, int y);
|
||||
void tick();
|
||||
private:
|
||||
CGEEngine *_vm;
|
||||
};
|
||||
|
||||
class Square : public Sprite {
|
||||
public:
|
||||
Square(CGEEngine *vm);
|
||||
virtual void touch(uint16 mask, int x, int y);
|
||||
private:
|
||||
CGEEngine *_vm;
|
||||
};
|
||||
|
||||
extern Vga *_vga;
|
||||
extern System *_sys;
|
||||
extern Sprite *_pocLight;
|
||||
extern Keyboard *_keyboard;
|
||||
extern Mouse *_mouse;
|
||||
extern EventManager *_eventManager;
|
||||
extern Sprite *_pocket[];
|
||||
extern Sprite *_sprite;
|
||||
extern Sprite *_miniCave;
|
||||
extern Sprite *_shadow;
|
||||
extern HorizLine *_horzLine;
|
||||
extern InfoLine *_infoLine;
|
||||
extern Sprite *_cavLight;
|
||||
extern InfoLine *_debugLine;
|
||||
extern Snail *_snail;
|
||||
extern Snail *_snail_;
|
||||
extern Fx *_fx;
|
||||
extern Sound *_sound;
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
34
engines/cge/console.cpp
Normal file
34
engines/cge/console.cpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 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 "cge/console.h"
|
||||
#include "cge/cge.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
CGEConsole::CGEConsole(CGEEngine *vm) : GUI::Debugger(), _vm(vm) {
|
||||
}
|
||||
|
||||
CGEConsole::~CGEConsole() {
|
||||
}
|
||||
|
||||
} // End of namespace CGE
|
43
engines/cge/console.h
Normal file
43
engines/cge/console.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 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 CGE_CONSOLE_H
|
||||
#define CGE_CONSOLE_H
|
||||
|
||||
#include "gui/debugger.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
class CGEEngine;
|
||||
|
||||
class CGEConsole : public GUI::Debugger {
|
||||
public:
|
||||
CGEConsole(CGEEngine *vm);
|
||||
virtual ~CGEConsole();
|
||||
|
||||
private:
|
||||
CGEEngine *_vm;
|
||||
};
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
237
engines/cge/detection.cpp
Normal file
237
engines/cge/detection.cpp
Normal file
|
@ -0,0 +1,237 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 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/config-manager.h"
|
||||
#include "engines/advancedDetector.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/system.h"
|
||||
#include "base/plugins.h"
|
||||
#include "graphics/thumbnail.h"
|
||||
#include "cge/cge.h"
|
||||
|
||||
static const PlainGameDescriptor CGEGames[] = {
|
||||
{ "soltys", "Soltys" },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
namespace CGE {
|
||||
|
||||
using Common::GUIO_NONE;
|
||||
|
||||
static const ADGameDescription gameDescriptions[] = {
|
||||
|
||||
{
|
||||
"soltys", "",
|
||||
{
|
||||
{"vol.cat", 0, "0c33e2c304821a2444d297fc5e2d67c6", 50176},
|
||||
{"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437572},
|
||||
AD_LISTEND
|
||||
},
|
||||
Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO_NONE
|
||||
},
|
||||
{
|
||||
"soltys", "Soltys Freeware",
|
||||
{
|
||||
{"vol.cat", 0, "0c33e2c304821a2444d297fc5e2d67c6", 50176},
|
||||
{"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437676},
|
||||
AD_LISTEND
|
||||
},
|
||||
Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO_NONE
|
||||
},
|
||||
// English ScummVM version
|
||||
{
|
||||
"soltys", "",
|
||||
{
|
||||
{"vol.cat", 0, "bd08969b5f1acea0f92d195f750c17d5", 50176},
|
||||
{"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8428832},
|
||||
AD_LISTEND
|
||||
},
|
||||
Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO_NONE
|
||||
},
|
||||
{
|
||||
"soltys", "Soltys Demo (not supported)",
|
||||
{
|
||||
{"vol.cat", 0, "1e077c8ff58109a187f07ac54b0c873a", 18788},
|
||||
{"vol.dat", 0, "75d385a6074c58b69f7730481f256051", 1796710},
|
||||
AD_LISTEND
|
||||
},
|
||||
Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO , GUIO_NONE
|
||||
},
|
||||
{
|
||||
"soltys", "Soltys Demo (not supported)",
|
||||
{
|
||||
{"vol.cat", 0, "f17987487fab1ebddd781d8d02fedecc", 7168},
|
||||
{"vol.dat", 0, "c5d9b15863cab61dc125551576dece04", 1075272},
|
||||
AD_LISTEND
|
||||
},
|
||||
Common::PL_POL, Common::kPlatformPC, ADGF_DEMO , GUIO_NONE
|
||||
},
|
||||
AD_TABLE_END_MARKER
|
||||
};
|
||||
|
||||
static const ADFileBasedFallback fileBasedFallback[] = {
|
||||
{ &gameDescriptions[0], { "vol.cat", "vol.dat", 0 } },
|
||||
{ 0, { 0 } }
|
||||
};
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
class CGEMetaEngine : public AdvancedMetaEngine {
|
||||
public:
|
||||
CGEMetaEngine() : AdvancedMetaEngine(CGE::gameDescriptions, sizeof(ADGameDescription), CGEGames) {
|
||||
_singleid = "Soltys";
|
||||
}
|
||||
|
||||
virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
|
||||
return detectGameFilebased(allFiles, CGE::fileBasedFallback);
|
||||
}
|
||||
|
||||
virtual const char *getName() const {
|
||||
return "CGE";
|
||||
}
|
||||
|
||||
virtual const char *getOriginalCopyright() const {
|
||||
return "Soltys (c) 1994-1996 L.K. Avalon";
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual bool hasFeature(MetaEngineFeature f) const;
|
||||
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
|
||||
virtual int getMaximumSaveSlot() const;
|
||||
virtual SaveStateList listSaves(const char *target) const;
|
||||
SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
|
||||
virtual void removeSaveState(const char *target, int slot) const;
|
||||
};
|
||||
|
||||
bool CGEMetaEngine::hasFeature(MetaEngineFeature f) const {
|
||||
return
|
||||
(f == kSupportsListSaves) ||
|
||||
(f == kSupportsLoadingDuringStartup) ||
|
||||
(f == kSupportsDeleteSave) ||
|
||||
(f == kSavesSupportMetaInfo) ||
|
||||
(f == kSavesSupportThumbnail) ||
|
||||
(f == kSavesSupportCreationDate);
|
||||
}
|
||||
|
||||
void CGEMetaEngine::removeSaveState(const char *target, int slot) const {
|
||||
Common::String fileName = Common::String::format("%s.%03d", target, slot);
|
||||
g_system->getSavefileManager()->removeSavefile(fileName);
|
||||
}
|
||||
|
||||
int CGEMetaEngine::getMaximumSaveSlot() const {
|
||||
return 99;
|
||||
}
|
||||
|
||||
SaveStateList CGEMetaEngine::listSaves(const char *target) const {
|
||||
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
||||
Common::StringArray filenames;
|
||||
Common::String pattern = target;
|
||||
pattern += ".???";
|
||||
|
||||
filenames = saveFileMan->listSavefiles(pattern);
|
||||
sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
|
||||
|
||||
SaveStateList saveList;
|
||||
int slotNum = 0;
|
||||
for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) {
|
||||
// Obtain the last 3 digits of the filename, since they correspond to the save slot
|
||||
slotNum = atoi(filename->c_str() + filename->size() - 3);
|
||||
|
||||
if (slotNum >= 0 && slotNum <= 99) {
|
||||
|
||||
Common::InSaveFile *file = saveFileMan->openForLoading(*filename);
|
||||
if (file) {
|
||||
CGE::SavegameHeader header;
|
||||
|
||||
// Check to see if it's a ScummVM savegame or not
|
||||
char buffer[kSavegameStrSize + 1];
|
||||
file->read(buffer, kSavegameStrSize + 1);
|
||||
|
||||
if (!strncmp(buffer, CGE::savegameStr, kSavegameStrSize + 1)) {
|
||||
// Valid savegame
|
||||
if (CGE::CGEEngine::readSavegameHeader(file, header)) {
|
||||
saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
|
||||
delete header.thumbnail;
|
||||
}
|
||||
} else {
|
||||
// Must be an original format savegame
|
||||
saveList.push_back(SaveStateDescriptor(slotNum, "Unknown"));
|
||||
}
|
||||
|
||||
delete file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return saveList;
|
||||
}
|
||||
|
||||
SaveStateDescriptor CGEMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
|
||||
Common::String fileName = Common::String::format("%s.%03d", target, slot);
|
||||
Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName);
|
||||
assert(f);
|
||||
|
||||
CGE::SavegameHeader header;
|
||||
|
||||
// Check to see if it's a ScummVM savegame or not
|
||||
char buffer[kSavegameStrSize + 1];
|
||||
f->read(buffer, kSavegameStrSize + 1);
|
||||
|
||||
bool hasHeader = !strncmp(buffer, CGE::savegameStr, kSavegameStrSize + 1) &&
|
||||
CGE::CGEEngine::readSavegameHeader(f, header);
|
||||
delete f;
|
||||
|
||||
if (!hasHeader) {
|
||||
// Original savegame perhaps?
|
||||
SaveStateDescriptor desc(slot, "Unknown");
|
||||
return desc;
|
||||
} else {
|
||||
// Create the return descriptor
|
||||
SaveStateDescriptor desc(slot, header.saveName);
|
||||
desc.setDeletableFlag(true);
|
||||
desc.setWriteProtectedFlag(false);
|
||||
desc.setThumbnail(header.thumbnail);
|
||||
desc.setSaveDate(header.saveYear, header.saveMonth, header.saveDay);
|
||||
desc.setSaveTime(header.saveHour, header.saveMinutes);
|
||||
|
||||
// Slot 0 is used for the 'automatic save on exit' save in Soltys, thus
|
||||
// we prevent it from being deleted or overwritten by accident.
|
||||
desc.setDeletableFlag(slot != 0);
|
||||
desc.setWriteProtectedFlag(slot == 0);
|
||||
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
|
||||
bool CGEMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
|
||||
if (desc) {
|
||||
*engine = new CGE::CGEEngine(syst, desc);
|
||||
}
|
||||
return desc != 0;
|
||||
}
|
||||
|
||||
#if PLUGIN_ENABLED_DYNAMIC(CGE)
|
||||
REGISTER_PLUGIN_DYNAMIC(CGE, PLUGIN_TYPE_ENGINE, CGEMetaEngine);
|
||||
#else
|
||||
REGISTER_PLUGIN_STATIC(CGE, PLUGIN_TYPE_ENGINE, CGEMetaEngine);
|
||||
#endif
|
378
engines/cge/events.cpp
Normal file
378
engines/cge/events.cpp
Normal file
|
@ -0,0 +1,378 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#include "gui/saveload.h"
|
||||
#include "gui/about.h"
|
||||
#include "gui/message.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/events.h"
|
||||
#include "cge/events.h"
|
||||
#include "cge/events.h"
|
||||
#include "cge/text.h"
|
||||
#include "cge/cge_main.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
/*----------------- KEYBOARD interface -----------------*/
|
||||
|
||||
const uint16 Keyboard::_code[0x60] = {
|
||||
0, Esc, '1', '2', '3',
|
||||
'4', '5', '6', '7', '8',
|
||||
'9', '0', '-', '+', BSp,
|
||||
Tab, 'Q', 'W', 'E', 'R',
|
||||
'T', 'Y', 'U', 'I', 'O',
|
||||
'P', '[', ']', Enter, 0/*Ctrl*/,
|
||||
'A', 'S', 'D', 'F', 'G',
|
||||
'H', 'J', 'K', 'L', ';',
|
||||
'\'', '`', 0/*LShift*/, '\\', 'Z',
|
||||
'X', 'C', 'V', 'B', 'N',
|
||||
'M', ',', '.', '/', 0/*RShift*/,
|
||||
'*', 0/*Alt*/, ' ', 0/*Caps*/, F1,
|
||||
F2, F3, F4, F5, F6,
|
||||
F7, F8, F9, F10, 0/*NumLock*/,
|
||||
0/*ScrollLock*/, Home, Up, PgUp, '-',
|
||||
Left, Ctr, Right, '+', End,
|
||||
Down, PgDn, Ins, Del, 0 * 0x54,
|
||||
0 * 0x55, 0 * 0x56, F11, F12, 0 * 0x59,
|
||||
0 * 0x5A, 0 * 0x5B, 0 * 0x5C, 0 * 0x5D, 0 * 0x5E,
|
||||
0 * 0x5F
|
||||
};
|
||||
|
||||
const uint16 Keyboard::_scummVmCodes[0x60] = {
|
||||
0, Common::KEYCODE_ESCAPE, Common::KEYCODE_1, Common::KEYCODE_2, Common::KEYCODE_3,
|
||||
Common::KEYCODE_4, Common::KEYCODE_5, Common::KEYCODE_6, Common::KEYCODE_7, Common::KEYCODE_8,
|
||||
Common::KEYCODE_9, Common::KEYCODE_0, Common::KEYCODE_MINUS, Common::KEYCODE_PLUS, Common::KEYCODE_BACKSPACE,
|
||||
Common::KEYCODE_TAB, Common::KEYCODE_q, Common::KEYCODE_w, Common::KEYCODE_e, Common::KEYCODE_r,
|
||||
Common::KEYCODE_t, Common::KEYCODE_y, Common::KEYCODE_u, Common::KEYCODE_i, Common::KEYCODE_o,
|
||||
Common::KEYCODE_p, Common::KEYCODE_LEFTBRACKET, Common::KEYCODE_RIGHTBRACKET, Common::KEYCODE_RETURN, 0/*Ctrl*/,
|
||||
Common::KEYCODE_a, Common::KEYCODE_s, Common::KEYCODE_d, Common::KEYCODE_f, Common::KEYCODE_g,
|
||||
Common::KEYCODE_h, Common::KEYCODE_j, Common::KEYCODE_k, Common::KEYCODE_l, Common::KEYCODE_SEMICOLON,
|
||||
Common::KEYCODE_BACKSLASH, Common::KEYCODE_TILDE, Common::KEYCODE_LSHIFT, Common::KEYCODE_BACKSLASH, Common::KEYCODE_z,
|
||||
Common::KEYCODE_x, Common::KEYCODE_c, Common::KEYCODE_v, Common::KEYCODE_b, Common::KEYCODE_n,
|
||||
Common::KEYCODE_m, Common::KEYCODE_COMMA, Common::KEYCODE_PERIOD, Common::KEYCODE_SLASH, Common::KEYCODE_RSHIFT,
|
||||
Common::KEYCODE_KP_MULTIPLY, 0 /*Alt*/, Common::KEYCODE_SPACE, Common::KEYCODE_CAPSLOCK, Common::KEYCODE_F1,
|
||||
Common::KEYCODE_F2, Common::KEYCODE_F3, Common::KEYCODE_F4, Common::KEYCODE_F5, Common::KEYCODE_F6,
|
||||
Common::KEYCODE_F7, Common::KEYCODE_F8, Common::KEYCODE_F9, Common::KEYCODE_F10, Common::KEYCODE_NUMLOCK,
|
||||
Common::KEYCODE_SCROLLOCK, Common::KEYCODE_KP7, Common::KEYCODE_KP8, Common::KEYCODE_KP9, Common::KEYCODE_KP_MINUS,
|
||||
Common::KEYCODE_KP4, Common::KEYCODE_KP5, Common::KEYCODE_KP6, Common::KEYCODE_KP_PLUS, Common::KEYCODE_KP1,
|
||||
Common::KEYCODE_KP2, Common::KEYCODE_KP3, Common::KEYCODE_KP0, Common::KEYCODE_KP_PERIOD, 0,
|
||||
0, 0, Common::KEYCODE_F11, Common::KEYCODE_F12, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0
|
||||
};
|
||||
|
||||
Keyboard::Keyboard(CGEEngine *vm) : _client(NULL), _vm(vm) {
|
||||
Common::set_to(&_key[0], &_key[0x60], false);
|
||||
_current = 0;
|
||||
}
|
||||
|
||||
Keyboard::~Keyboard() {
|
||||
}
|
||||
|
||||
Sprite *Keyboard::setClient(Sprite *spr) {
|
||||
SWAP(_client, spr);
|
||||
return spr;
|
||||
}
|
||||
|
||||
bool Keyboard::getKey(Common::Event &event, int &cgeCode) {
|
||||
Common::KeyCode keycode = event.kbd.keycode;
|
||||
if ((keycode == Common::KEYCODE_LCTRL) || (keycode == Common::KEYCODE_RCTRL)) {
|
||||
cgeCode = kKeyCtrl;
|
||||
return true;
|
||||
}
|
||||
if ((keycode == Common::KEYCODE_LALT) || (keycode == Common::KEYCODE_RALT)) {
|
||||
cgeCode = kKeyAlt;
|
||||
return true;
|
||||
}
|
||||
if (keycode == Common::KEYCODE_KP_ENTER) {
|
||||
cgeCode = 28;
|
||||
return true;
|
||||
}
|
||||
if (keycode == Common::KEYCODE_F5) {
|
||||
warning("keycode %d", event.kbd.ascii);
|
||||
if (_vm->canSaveGameStateCurrently()) {
|
||||
const EnginePlugin *plugin = NULL;
|
||||
EngineMan.findGame(_vm->_gameDescription->gameid, &plugin);
|
||||
|
||||
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save");
|
||||
dialog->setSaveMode(true);
|
||||
int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
|
||||
Common::String savegameDescription = dialog->getResultString();
|
||||
delete dialog;
|
||||
_vm->saveGameState(savegameId, savegameDescription);
|
||||
}
|
||||
return false;
|
||||
} else if (keycode == Common::KEYCODE_F7) {
|
||||
if (_vm->canLoadGameStateCurrently()) {
|
||||
const EnginePlugin *plugin = NULL;
|
||||
EngineMan.findGame(_vm->_gameDescription->gameid, &plugin);
|
||||
|
||||
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore");
|
||||
dialog->setSaveMode(false);
|
||||
int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
|
||||
delete dialog;
|
||||
_vm->loadGameState(savegameId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Scan through the ScummVM mapping list
|
||||
for (int idx = 0; idx < 0x60; idx++) {
|
||||
if (_scummVmCodes[idx] == event.kbd.ascii) {
|
||||
cgeCode = idx;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Keyboard::newKeyboard(Common::Event &event) {
|
||||
int keycode;
|
||||
if (!getKey(event, keycode))
|
||||
return;
|
||||
|
||||
if (event.type == Common::EVENT_KEYUP) {
|
||||
// Key release
|
||||
_key[keycode] = false;
|
||||
} else if (event.type == Common::EVENT_KEYDOWN) {
|
||||
// Key press
|
||||
_key[keycode] = true;
|
||||
_current = Keyboard::_code[keycode];
|
||||
|
||||
if (_client) {
|
||||
CGEEvent &evt = _eventManager->getNextEvent();
|
||||
evt._x = _current; // Keycode
|
||||
evt._mask = kEventKeyb; // Event mask
|
||||
evt._spritePtr = _client; // Sprite pointer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16 Keyboard::lastKey() {
|
||||
uint16 cur = _current;
|
||||
_current = 0;
|
||||
return cur;
|
||||
}
|
||||
|
||||
/*----------------- MOUSE interface -----------------*/
|
||||
|
||||
Mouse::Mouse(CGEEngine *vm) : Sprite(vm, NULL), _busy(NULL), _hold(NULL), _hx(0), _vm(vm) {
|
||||
_hold = NULL;
|
||||
_hx = 0;
|
||||
_hy = 0;
|
||||
_exist = true;
|
||||
_buttons = 0;
|
||||
_busy = NULL;
|
||||
_active = false;
|
||||
_flags._kill = false;
|
||||
|
||||
const Seq ms[] = {
|
||||
{ 0, 0, 0, 0, 1 },
|
||||
{ 1, 1, 0, 0, 1 }
|
||||
};
|
||||
Seq *seq = (Seq *)malloc(2 * sizeof(Seq));
|
||||
Common::copy(ms, ms + 2, seq);
|
||||
setSeq(seq);
|
||||
|
||||
BitmapPtr *MC = new BitmapPtr[3];
|
||||
MC[0] = new Bitmap("MOUSE");
|
||||
MC[1] = new Bitmap("DUMMY");
|
||||
MC[2] = NULL;
|
||||
setShapeList(MC);
|
||||
|
||||
gotoxy(kScrWidth / 2, kScrHeight / 2);
|
||||
_z = 127;
|
||||
step(1);
|
||||
}
|
||||
|
||||
Mouse::~Mouse() {
|
||||
off();
|
||||
}
|
||||
|
||||
void Mouse::on() {
|
||||
if (_seqPtr && _exist) {
|
||||
_active = true;
|
||||
step(0);
|
||||
if (_busy)
|
||||
_busy->step(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Mouse::off() {
|
||||
if (_seqPtr == 0) {
|
||||
if (_exist) {
|
||||
_active = false;
|
||||
}
|
||||
|
||||
step(1);
|
||||
if (_busy)
|
||||
_busy->step(1);
|
||||
}
|
||||
}
|
||||
|
||||
void Mouse::newMouse(Common::Event &event) {
|
||||
if (!_active)
|
||||
return;
|
||||
|
||||
CGEEvent &evt = _eventManager->getNextEvent();
|
||||
evt._x = event.mouse.x;
|
||||
evt._y = event.mouse.y;
|
||||
evt._spritePtr = spriteAt(evt._x, evt._y);
|
||||
|
||||
switch (event.type) {
|
||||
case Common::EVENT_MOUSEMOVE:
|
||||
evt._mask = kMouseRoll;
|
||||
break;
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
evt._mask = kMouseLeftDown;
|
||||
_buttons |= 1;
|
||||
break;
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
evt._mask = kMouseLeftUp;
|
||||
_buttons &= ~1;
|
||||
break;
|
||||
case Common::EVENT_RBUTTONDOWN:
|
||||
evt._mask = kMouseRightDown;
|
||||
_buttons |= 2;
|
||||
break;
|
||||
case Common::EVENT_RBUTTONUP:
|
||||
evt._mask = kMouseRightUp;
|
||||
_buttons &= ~2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------- EventManager interface -----------------*/
|
||||
|
||||
EventManager::EventManager() {
|
||||
_quitFlag = false;
|
||||
_eventQueueHead = 0;
|
||||
_eventQueueTail = 0;
|
||||
memset(&_eventQueue, 0, kEventMax * sizeof(CGEEvent));
|
||||
memset(&_event, 0, sizeof(Common::Event));
|
||||
}
|
||||
|
||||
void EventManager::poll() {
|
||||
while (g_system->getEventManager()->pollEvent(_event)) {
|
||||
switch (_event.type) {
|
||||
case Common::EVENT_QUIT:
|
||||
// Signal to quit
|
||||
_quitFlag = true;
|
||||
return;
|
||||
case Common::EVENT_KEYDOWN:
|
||||
case Common::EVENT_KEYUP:
|
||||
// Handle keyboard events
|
||||
_keyboard->newKeyboard(_event);
|
||||
handleEvents();
|
||||
break;
|
||||
case Common::EVENT_MOUSEMOVE:
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
case Common::EVENT_RBUTTONDOWN:
|
||||
case Common::EVENT_RBUTTONUP:
|
||||
// Handle mouse events
|
||||
_mouse->newMouse(_event);
|
||||
handleEvents();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventManager::handleEvents() {
|
||||
while (_eventQueueTail != _eventQueueHead) {
|
||||
CGEEvent e = _eventQueue[_eventQueueTail];
|
||||
if (e._mask) {
|
||||
if (_mouse->_hold && e._spritePtr != _mouse->_hold)
|
||||
_mouse->_hold->touch(e._mask | kEventAttn, e._x - _mouse->_hold->_x, e._y - _mouse->_hold->_y);
|
||||
|
||||
// update mouse cursor position
|
||||
if (e._mask & kMouseRoll)
|
||||
_mouse->gotoxy(e._x, e._y);
|
||||
|
||||
// activate current touched SPRITE
|
||||
if (e._spritePtr) {
|
||||
if (e._mask & kEventKeyb)
|
||||
e._spritePtr->touch(e._mask, e._x, e._y);
|
||||
else
|
||||
e._spritePtr->touch(e._mask, e._x - e._spritePtr->_x, e._y - e._spritePtr->_y);
|
||||
} else if (_sys)
|
||||
_sys->touch(e._mask, e._x, e._y);
|
||||
|
||||
if (e._mask & kMouseLeftDown) {
|
||||
_mouse->_hold = e._spritePtr;
|
||||
if (_mouse->_hold) {
|
||||
_mouse->_hold->_flags._hold = true;
|
||||
|
||||
if (_mouse->_hold->_flags._drag) {
|
||||
_mouse->_hx = e._x - _mouse->_hold->_x;
|
||||
_mouse->_hy = e._y - _mouse->_hold->_y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (e._mask & kMouseLeftUp) {
|
||||
if (_mouse->_hold) {
|
||||
_mouse->_hold->_flags._hold = false;
|
||||
_mouse->_hold = NULL;
|
||||
}
|
||||
}
|
||||
///Touched = e.Ptr;
|
||||
|
||||
// discard Text if button released
|
||||
if (e._mask & (kMouseLeftUp | kMouseRightUp))
|
||||
killText();
|
||||
}
|
||||
_eventQueueTail = (_eventQueueTail + 1) % kEventMax;
|
||||
}
|
||||
if (_mouse->_hold) {
|
||||
if (_mouse->_hold->_flags._drag)
|
||||
_mouse->_hold->gotoxy(_mouse->_x - _mouse->_hx, _mouse->_y - _mouse->_hy);
|
||||
}
|
||||
}
|
||||
|
||||
void EventManager::clearEvent(Sprite *spr) {
|
||||
if (spr) {
|
||||
for (uint16 e = _eventQueueTail; e != _eventQueueHead; e = (e + 1) % kEventMax)
|
||||
if (_eventQueue[e]._spritePtr == spr)
|
||||
_eventQueue[e]._mask = 0;
|
||||
} else
|
||||
_eventQueueTail = _eventQueueHead;
|
||||
}
|
||||
|
||||
CGEEvent &EventManager::getNextEvent() {
|
||||
CGEEvent &evt = _eventQueue[_eventQueueHead];
|
||||
_eventQueueHead = (_eventQueueHead + 1) % kEventMax;
|
||||
|
||||
return evt;
|
||||
}
|
||||
|
||||
} // End of namespace CGE
|
155
engines/cge/events.h
Normal file
155
engines/cge/events.h
Normal file
|
@ -0,0 +1,155 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_EVENTS_H
|
||||
#define CGE_EVENTS_H
|
||||
|
||||
#include "common/events.h"
|
||||
#include "cge/game.h"
|
||||
#include "cge/talk.h"
|
||||
#include "cge/vga13h.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
/*----------------- KEYBOARD interface -----------------*/
|
||||
|
||||
#define kKeyCtrl 29
|
||||
#define kKeyAlt 56
|
||||
#define kEventMax 256
|
||||
|
||||
enum EventMask {
|
||||
kMouseRoll = 1 << 0,
|
||||
kMouseLeftDown = 1 << 1,
|
||||
kMouseLeftUp = 1 << 2,
|
||||
kMouseRightDown = 1 << 3,
|
||||
kMouseRightUp = 1 << 4,
|
||||
kEventAttn = 1 << 5,
|
||||
kEventKeyb = 1 << 7
|
||||
};
|
||||
|
||||
enum Keys {
|
||||
NoKey = 0, CtrlA, CtrlB, CtrlC, CtrlD, CtrlE, CtrlF, CtrlG, CtrlH,
|
||||
CtrlI, CtrlJ, CtrlK, CtrlL, CtrlM, CtrlN, CtrlO, CtrlP,
|
||||
CtrlQ, CtrlR, CtrlS, CtrlT, CtrlU, CtrlV, CtrlW, CtrlX,
|
||||
CtrlY, CtrlZ,
|
||||
BSp = 8, Tab,
|
||||
Enter = 13,
|
||||
Eof = 26, Esc,
|
||||
AltQ = 256 + 16, AltW, AltE, AltR, AltT, AltY, AltU, AltI, AltO, AltP,
|
||||
AltA = 256 + 30, AltS, AltD, AltF, AltG, AltH, AltJ, AltK, AltL,
|
||||
AltZ = 256 + 44, AltX, AltC, AltV, AltB, AltN, AltM,
|
||||
F11 = 256 + 87, F12,
|
||||
F1 = 256 + 59, F2, F3, F4, F5, F6, F7, F8, F9, F10,
|
||||
ShiftTab = 256 + 15,
|
||||
ShiftF1 = 256 + 84, ShiftF2, ShiftF3, ShiftF4, ShiftF5,
|
||||
ShiftF6, ShiftF7, ShiftF8, ShiftF9, ShiftF10,
|
||||
CtrlF1 = 256 + 94, CtrlF2, CtrlF3, CtrlF4, CtrlF5,
|
||||
CtrlF6, CtrlF7, CtrlF8, CtrlF9, CtrlF10,
|
||||
AltF1 = 256 + 104, AltF2, AltF3, AltF4, AltF5,
|
||||
AltF6, AltF7, AltF8, AltF9, AltF10,
|
||||
Home = 256 + 71, Up, PgUp,
|
||||
Left = 256 + 75, Ctr, Right,
|
||||
End = 256 + 79, Down, PgDn, Ins, Del,
|
||||
CtrlLeft = 256 + 115, CtrlRight, CtrlEnd, CtrlPgDn, CtrlHome,
|
||||
CtrlPgUp = 256 + 132,
|
||||
MouseLeft = 512 + 1, MouseRight,
|
||||
TwiceLeft = 512 + 256 + 1, TwiceRight
|
||||
};
|
||||
|
||||
class Keyboard {
|
||||
private:
|
||||
bool getKey(Common::Event &event, int &cgeCode);
|
||||
uint16 _current;
|
||||
CGEEngine *_vm;
|
||||
public:
|
||||
static const uint16 _code[0x60];
|
||||
static const uint16 _scummVmCodes[0x60];
|
||||
|
||||
Sprite *_client;
|
||||
bool _key[0x60];
|
||||
|
||||
void newKeyboard(Common::Event &event);
|
||||
uint16 lastKey();
|
||||
Sprite *setClient(Sprite *spr);
|
||||
|
||||
Keyboard(CGEEngine *vm);
|
||||
~Keyboard();
|
||||
};
|
||||
|
||||
/*----------------- MOUSE interface -----------------*/
|
||||
|
||||
extern Talk *_talk;
|
||||
|
||||
struct CGEEvent {
|
||||
uint16 _mask;
|
||||
uint16 _x;
|
||||
uint16 _y;
|
||||
Sprite *_spritePtr;
|
||||
};
|
||||
|
||||
class Mouse : public Sprite {
|
||||
public:
|
||||
Sprite *_hold;
|
||||
bool _active;
|
||||
int _hx;
|
||||
int _hy;
|
||||
bool _exist;
|
||||
int _buttons;
|
||||
Sprite *_busy;
|
||||
//Sprite *Touched;
|
||||
Mouse(CGEEngine *vm);
|
||||
~Mouse();
|
||||
void on();
|
||||
void off();
|
||||
void newMouse(Common::Event &event);
|
||||
private:
|
||||
CGEEngine *_vm;
|
||||
};
|
||||
|
||||
/*----------------- EventManager interface -----------------*/
|
||||
|
||||
class EventManager {
|
||||
private:
|
||||
Common::Event _event;
|
||||
CGEEvent _eventQueue[kEventMax];
|
||||
uint16 _eventQueueHead;
|
||||
uint16 _eventQueueTail;
|
||||
|
||||
void handleEvents();
|
||||
public:
|
||||
bool _quitFlag;
|
||||
|
||||
EventManager();
|
||||
void poll();
|
||||
void clearEvent(Sprite *spr);
|
||||
|
||||
CGEEvent &getNextEvent();
|
||||
};
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
420
engines/cge/fileio.cpp
Normal file
420
engines/cge/fileio.cpp
Normal file
|
@ -0,0 +1,420 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#include "common/system.h"
|
||||
#include "common/str.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/debug-channels.h"
|
||||
#include "common/memstream.h"
|
||||
#include "cge/cge.h"
|
||||
#include "cge/fileio.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* IOHand
|
||||
*-----------------------------------------------------------------------*/
|
||||
IoHand::IoHand(Crypt *crypt) : _error(0), _crypt(crypt), _seed(kCryptSeed) {
|
||||
_file = new Common::File();
|
||||
}
|
||||
|
||||
IoHand::IoHand(const char *name, Crypt *crypt)
|
||||
: _error(0), _crypt(crypt), _seed(kCryptSeed) {
|
||||
_file = new Common::File();
|
||||
_file->open(name);
|
||||
}
|
||||
|
||||
IoHand::~IoHand() {
|
||||
_file->close();
|
||||
delete _file;
|
||||
}
|
||||
|
||||
uint16 IoHand::read(void *buf, uint16 len) {
|
||||
if (!_file->isOpen())
|
||||
return 0;
|
||||
|
||||
uint16 bytesRead = _file->read(buf, len);
|
||||
if (!bytesRead)
|
||||
error("Read %s - %d bytes", _file->getName(), len);
|
||||
if (_crypt)
|
||||
_seed = _crypt(buf, len);
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
long IoHand::mark() {
|
||||
return _file->pos();
|
||||
}
|
||||
|
||||
long IoHand::seek(long pos) {
|
||||
_file->seek(pos, SEEK_SET);
|
||||
return _file->pos();
|
||||
}
|
||||
|
||||
long IoHand::size() {
|
||||
return _file->size();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* IoBuf
|
||||
*-----------------------------------------------------------------------*/
|
||||
IoBuf::IoBuf(Crypt *crypt)
|
||||
: IoHand(crypt),
|
||||
_bufMark(0),
|
||||
_ptr(0),
|
||||
_lim(0) {
|
||||
debugC(1, kCGEDebugFile, "IoBuf::IoBuf(crypt)");
|
||||
|
||||
_buff = (uint8 *)malloc(sizeof(uint8) * kBufferSize);
|
||||
assert(_buff != NULL);
|
||||
}
|
||||
|
||||
IoBuf::IoBuf(const char *name, Crypt *crypt)
|
||||
: IoHand(name, crypt),
|
||||
_bufMark(0),
|
||||
_ptr(0),
|
||||
_lim(0) {
|
||||
debugC(1, kCGEDebugFile, "IoBuf::IoBuf(%s, crypt)", name);
|
||||
|
||||
_buff = (uint8 *)malloc(sizeof(uint8) * kBufferSize);
|
||||
assert(_buff != NULL);
|
||||
}
|
||||
|
||||
IoBuf::~IoBuf() {
|
||||
debugC(6, kCGEDebugFile, "IoBuf::~IoBuf()");
|
||||
free(_buff);
|
||||
}
|
||||
|
||||
void IoBuf::readBuf() {
|
||||
debugC(4, kCGEDebugFile, "IoBuf::readBuf()");
|
||||
|
||||
_bufMark = IoHand::mark();
|
||||
_lim = IoHand::read(_buff, kBufferSize);
|
||||
_ptr = 0;
|
||||
}
|
||||
|
||||
uint16 IoBuf::read(void *buf, uint16 len) {
|
||||
debugC(4, kCGEDebugFile, "IoBuf::read(buf, %d)", len);
|
||||
|
||||
uint16 total = 0;
|
||||
while (len) {
|
||||
if (_ptr >= _lim)
|
||||
readBuf();
|
||||
uint16 n = _lim - _ptr;
|
||||
if (n) {
|
||||
if (len < n)
|
||||
n = len;
|
||||
memcpy(buf, _buff + _ptr, n);
|
||||
buf = (uint8 *)buf + n;
|
||||
len -= n;
|
||||
total += n;
|
||||
_ptr += n;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
uint16 IoBuf::read(uint8 *buf) {
|
||||
debugC(3, kCGEDebugFile, "IoBuf::read(buf)");
|
||||
|
||||
uint16 total = 0;
|
||||
|
||||
while (total < kLineMaxSize - 2) {
|
||||
if (_ptr >= _lim)
|
||||
readBuf();
|
||||
uint8 *p = _buff + _ptr;
|
||||
uint16 n = _lim - _ptr;
|
||||
if (n) {
|
||||
if (total + n >= kLineMaxSize - 2)
|
||||
n = kLineMaxSize - 2 - total;
|
||||
uint8 *eol = (uint8 *) memchr(p, '\r', n);
|
||||
if (eol)
|
||||
n = (uint16)(eol - p);
|
||||
uint8 *eof = (uint8 *) memchr(p, '\32', n);
|
||||
if (eof) { // end-of-file
|
||||
n = (uint16)(eof - p);
|
||||
_ptr = (uint16)(eof - _buff);
|
||||
}
|
||||
if (n)
|
||||
memcpy(buf, p, n);
|
||||
buf += n;
|
||||
total += n;
|
||||
if (eof)
|
||||
break;
|
||||
_ptr += n;
|
||||
if (eol) {
|
||||
_ptr++;
|
||||
*(buf++) = '\n';
|
||||
total++;
|
||||
if (_ptr >= _lim)
|
||||
readBuf();
|
||||
if (_ptr < _lim)
|
||||
if (_buff[_ptr] == '\n')
|
||||
++_ptr;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
break;
|
||||
}
|
||||
*buf = '\0';
|
||||
return total;
|
||||
}
|
||||
|
||||
int IoBuf::read() {
|
||||
debugC(1, kCGEDebugFile, "IoBuf::read()");
|
||||
|
||||
if (_ptr >= _lim) {
|
||||
readBuf();
|
||||
if (_lim == 0)
|
||||
return -1;
|
||||
}
|
||||
return _buff[_ptr++];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* CFile
|
||||
*-----------------------------------------------------------------------*/
|
||||
CFile::CFile(const char *name, Crypt *crypt) : IoBuf(name, crypt) {
|
||||
debugC(1, kCGEDebugFile, "CFile::CFile(%s, crypt)", name);
|
||||
}
|
||||
|
||||
CFile::~CFile() {
|
||||
}
|
||||
|
||||
long CFile::mark() {
|
||||
debugC(5, kCGEDebugFile, "CFile::mark()");
|
||||
|
||||
return _bufMark + _ptr;
|
||||
}
|
||||
|
||||
long CFile::seek(long pos) {
|
||||
debugC(1, kCGEDebugFile, "CFile::seek(%ld)", pos);
|
||||
|
||||
if (pos >= _bufMark && pos < _bufMark + _lim) {
|
||||
_ptr = (uint16)(pos - _bufMark);
|
||||
return pos;
|
||||
} else {
|
||||
_lim = 0;
|
||||
_ptr = 0;
|
||||
return _bufMark = IoHand::seek(pos);
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* BtPage
|
||||
*-----------------------------------------------------------------------*/
|
||||
void BtPage::read(Common::ReadStream &s) {
|
||||
_header._count = s.readUint16LE();
|
||||
_header._down = s.readUint16LE();
|
||||
|
||||
if (_header._down == kBtValNone) {
|
||||
// Leaf list
|
||||
for (int i = 0; i < kBtLeafCount; ++i) {
|
||||
s.read(_leaf[i]._key, kBtKeySize);
|
||||
_leaf[i]._mark = s.readUint32LE();
|
||||
_leaf[i]._size = s.readUint16LE();
|
||||
}
|
||||
} else {
|
||||
// Root index
|
||||
for (int i = 0; i < kBtInnerCount; ++i) {
|
||||
s.read(_inner[i]._key, kBtKeySize);
|
||||
_inner[i]._down = s.readUint16LE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* BtFile
|
||||
*-----------------------------------------------------------------------*/
|
||||
BtFile::BtFile(const char *name, Crypt *crpt)
|
||||
: IoHand(name, crpt) {
|
||||
debugC(1, kCGEDebugFile, "BtFile::BtFile(%s, crpt)", name);
|
||||
|
||||
for (int i = 0; i < kBtLevel; i++) {
|
||||
_buff[i]._page = new BtPage;
|
||||
_buff[i]._pgNo = kBtValNone;
|
||||
_buff[i]._indx = -1;
|
||||
assert(_buff[i]._page != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
BtFile::~BtFile() {
|
||||
debugC(1, kCGEDebugFile, "BtFile::~BtFile()");
|
||||
for (int i = 0; i < kBtLevel; i++)
|
||||
delete _buff[i]._page;
|
||||
}
|
||||
|
||||
BtPage *BtFile::getPage(int lev, uint16 pgn) {
|
||||
debugC(1, kCGEDebugFile, "BtFile::getPage(%d, %d)", lev, pgn);
|
||||
|
||||
if (_buff[lev]._pgNo != pgn) {
|
||||
int32 pos = pgn * kBtSize;
|
||||
_buff[lev]._pgNo = pgn;
|
||||
assert(size() > pos);
|
||||
// In the original, there was a check verifying if the
|
||||
// purpose was to write a new file. This should only be
|
||||
// to create a new file, thus it was removed.
|
||||
seek((uint32) pgn * kBtSize);
|
||||
|
||||
// Read in the page
|
||||
byte buffer[kBtSize];
|
||||
int bytesRead = read(buffer, kBtSize);
|
||||
|
||||
// Unpack it into the page structure
|
||||
Common::MemoryReadStream stream(buffer, bytesRead, DisposeAfterUse::NO);
|
||||
_buff[lev]._page->read(stream);
|
||||
|
||||
_buff[lev]._indx = -1;
|
||||
}
|
||||
return _buff[lev]._page;
|
||||
}
|
||||
|
||||
BtKeypack *BtFile::find(const char *key) {
|
||||
debugC(1, kCGEDebugFile, "BtFile::find(%s)", key);
|
||||
|
||||
int lev = 0;
|
||||
uint16 nxt = kBtValRoot;
|
||||
while (!_error) {
|
||||
BtPage *pg = getPage(lev, nxt);
|
||||
// search
|
||||
if (pg->_header._down != kBtValNone) {
|
||||
int i;
|
||||
for (i = 0; i < pg->_header._count; i++) {
|
||||
// Does this work, or does it have to compare the entire buffer?
|
||||
if (scumm_strnicmp((const char *)key, (const char*)pg->_inner[i]._key, kBtKeySize) < 0)
|
||||
break;
|
||||
}
|
||||
nxt = (i) ? pg->_inner[i - 1]._down : pg->_header._down;
|
||||
_buff[lev]._indx = i - 1;
|
||||
lev++;
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < pg->_header._count - 1; i++) {
|
||||
if (scumm_stricmp((const char *)key, (const char *)pg->_leaf[i]._key) <= 0)
|
||||
break;
|
||||
}
|
||||
_buff[lev]._indx = i;
|
||||
return &pg->_leaf[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool BtFile::exist(const char *name) {
|
||||
debugC(1, kCGEDebugFile, "BtFile::exist(%s)", name);
|
||||
|
||||
return scumm_stricmp(find(name)->_key, name) == 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* VFile
|
||||
*-----------------------------------------------------------------------*/
|
||||
VFile::VFile(const char *name) : IoBuf(NULL) {
|
||||
debugC(3, kCGEDebugFile, "VFile::VFile(%s)", name);
|
||||
|
||||
if (_dat->_error || _cat->_error)
|
||||
error("Bad volume data");
|
||||
BtKeypack *kp = _cat->find(name);
|
||||
if (scumm_stricmp(kp->_key, name) != 0)
|
||||
_error = 1;
|
||||
_endMark = (_bufMark = _begMark = kp->_mark) + kp->_size;
|
||||
}
|
||||
|
||||
VFile::~VFile() {
|
||||
}
|
||||
|
||||
void VFile::readBuf() {
|
||||
debugC(3, kCGEDebugFile, "VFile::readBuf()");
|
||||
|
||||
_dat->seek(_bufMark + _lim);
|
||||
_bufMark = _dat->mark();
|
||||
long n = _endMark - _bufMark;
|
||||
if (n > kBufferSize)
|
||||
n = kBufferSize;
|
||||
_lim = _dat->read(_buff, (uint16) n);
|
||||
_ptr = 0;
|
||||
}
|
||||
|
||||
long VFile::mark() {
|
||||
debugC(5, kCGEDebugFile, "VFile::mark()");
|
||||
|
||||
return (_bufMark + _ptr) - _begMark;
|
||||
}
|
||||
|
||||
long VFile::size() {
|
||||
debugC(1, kCGEDebugFile, "VFile::size()");
|
||||
|
||||
return _endMark - _begMark;
|
||||
}
|
||||
|
||||
long VFile::seek(long pos) {
|
||||
debugC(1, kCGEDebugFile, "VFile::seek(%ld)", pos);
|
||||
|
||||
_lim = 0;
|
||||
return (_bufMark = _begMark + pos);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* EncryptedStream
|
||||
*-----------------------------------------------------------------------*/
|
||||
EncryptedStream::EncryptedStream(const char *name) {
|
||||
debugC(3, kCGEDebugFile, "EncryptedStream::EncryptedStream(%s)", name);
|
||||
|
||||
_error = false;
|
||||
if (_dat->_error || _cat->_error)
|
||||
error("Bad volume data");
|
||||
BtKeypack *kp = _cat->find(name);
|
||||
if (scumm_stricmp(kp->_key, name) != 0)
|
||||
_error = true;
|
||||
|
||||
_dat->_file->seek(kp->_mark);
|
||||
byte *dataBuffer = (byte *)malloc(kp->_size);
|
||||
_dat->_file->read(dataBuffer, kp->_size);
|
||||
XCrypt(dataBuffer, kp->_size);
|
||||
_readStream = new Common::MemoryReadStream(dataBuffer, kp->_size, DisposeAfterUse::YES);
|
||||
}
|
||||
|
||||
uint32 EncryptedStream::read(void *dataPtr, uint32 dataSize) {
|
||||
return _readStream->read(dataPtr, dataSize);
|
||||
}
|
||||
|
||||
bool EncryptedStream::err() {
|
||||
return (_error & _readStream->err());
|
||||
}
|
||||
|
||||
bool EncryptedStream::eos() {
|
||||
return _readStream->eos();
|
||||
}
|
||||
|
||||
Common::String EncryptedStream::readLine() {
|
||||
return _readStream->readLine();
|
||||
}
|
||||
|
||||
EncryptedStream::~EncryptedStream() {
|
||||
}
|
||||
|
||||
} // End of namespace CGE
|
168
engines/cge/fileio.h
Normal file
168
engines/cge/fileio.h
Normal file
|
@ -0,0 +1,168 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_FILEIO_H
|
||||
#define CGE_FILEIO_H
|
||||
|
||||
#include "cge/general.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
#define kBtSize 1024
|
||||
#define kBtKeySize 13
|
||||
#define kBtLevel 2
|
||||
#define kBtInnerCount ((kBtSize - 4 /*sizeof(Hea) */) / (kBtKeySize + 2 /*sizeof(Inner) */))
|
||||
#define kBtLeafCount ((kBtSize - 4 /*sizeof(Hea) */) / (kBtKeySize + 4 + 2 /*sizeof(BtKeypack) */))
|
||||
#define kBtValNone 0xFFFF
|
||||
#define kBtValRoot 0
|
||||
#define kLineMaxSize 512
|
||||
#define kBufferSize 2048
|
||||
#define kCatName "VOL.CAT"
|
||||
#define kDatName "VOL.DAT"
|
||||
|
||||
struct BtKeypack {
|
||||
char _key[kBtKeySize];
|
||||
uint32 _mark;
|
||||
uint16 _size;
|
||||
};
|
||||
|
||||
struct Inner {
|
||||
uint8 _key[kBtKeySize];
|
||||
uint16 _down;
|
||||
};
|
||||
|
||||
struct Header {
|
||||
uint16 _count;
|
||||
uint16 _down;
|
||||
};
|
||||
|
||||
class IoHand {
|
||||
protected:
|
||||
uint16 _seed;
|
||||
Crypt *_crypt;
|
||||
public:
|
||||
Common::File *_file;
|
||||
uint16 _error;
|
||||
|
||||
IoHand(const char *name, Crypt crypt);
|
||||
IoHand(Crypt *crypt);
|
||||
virtual ~IoHand();
|
||||
uint16 read(void *buf, uint16 len);
|
||||
long mark();
|
||||
long size();
|
||||
long seek(long pos);
|
||||
};
|
||||
|
||||
class IoBuf : public IoHand {
|
||||
protected:
|
||||
uint8 *_buff;
|
||||
uint16 _ptr;
|
||||
uint16 _lim;
|
||||
long _bufMark;
|
||||
virtual void readBuf();
|
||||
public:
|
||||
IoBuf(Crypt *crpt);
|
||||
IoBuf(const char *name, Crypt *crpt);
|
||||
virtual ~IoBuf();
|
||||
uint16 read(void *buf, uint16 len);
|
||||
uint16 read(uint8 *buf);
|
||||
int read();
|
||||
};
|
||||
|
||||
|
||||
class CFile : public IoBuf {
|
||||
public:
|
||||
CFile(const char *name, Crypt *crpt);
|
||||
virtual ~CFile();
|
||||
long mark();
|
||||
long seek(long pos);
|
||||
};
|
||||
|
||||
struct BtPage {
|
||||
Header _header;
|
||||
union {
|
||||
// dummy filler to make proper size of union
|
||||
uint8 _data[kBtSize - 4]; /* 4 is the size of struct Header */
|
||||
// inner version of data: key + word-sized page link
|
||||
Inner _inner[kBtInnerCount];
|
||||
// leaf version of data: key + all user data
|
||||
BtKeypack _leaf[kBtLeafCount];
|
||||
};
|
||||
|
||||
void read(Common::ReadStream &s);
|
||||
};
|
||||
|
||||
class BtFile : public IoHand {
|
||||
struct {
|
||||
BtPage *_page;
|
||||
uint16 _pgNo;
|
||||
int _indx;
|
||||
} _buff[kBtLevel];
|
||||
|
||||
BtPage *getPage(int lev, uint16 pgn);
|
||||
public:
|
||||
BtFile(const char *name, Crypt *crpt);
|
||||
virtual ~BtFile();
|
||||
BtKeypack *find(const char *key);
|
||||
bool exist(const char *name);
|
||||
};
|
||||
|
||||
class VFile : public IoBuf {
|
||||
private:
|
||||
long _begMark;
|
||||
long _endMark;
|
||||
|
||||
void readBuf();
|
||||
public:
|
||||
VFile(const char *name);
|
||||
~VFile();
|
||||
|
||||
long mark();
|
||||
long size();
|
||||
long seek(long pos);
|
||||
};
|
||||
|
||||
class EncryptedStream {
|
||||
private:
|
||||
Common::SeekableReadStream *_readStream;
|
||||
bool _error;
|
||||
public:
|
||||
EncryptedStream(const char *name);
|
||||
~EncryptedStream();
|
||||
bool err();
|
||||
bool eos();
|
||||
uint32 read(void *dataPtr, uint32 dataSize);
|
||||
Common::String readLine();
|
||||
};
|
||||
|
||||
extern CFile *_dat;
|
||||
extern BtFile *_cat;
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
72
engines/cge/game.cpp
Normal file
72
engines/cge/game.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#include "cge/game.h"
|
||||
#include "cge/events.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
uint8 *glass(Dac *pal, uint8 r, uint8 g, uint8 b) {
|
||||
uint8 *x = (uint8 *)malloc(256);
|
||||
if (x) {
|
||||
uint16 i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
x[i] = closest(pal, mkDac(((uint16)(pal[i]._r) * r) / 255,
|
||||
((uint16)(pal[i]._g) * g) / 255,
|
||||
((uint16)(pal[i]._b) * b) / 255));
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
const int Fly::_l = 20,
|
||||
Fly::_t = 40,
|
||||
Fly::_r = 110,
|
||||
Fly::_b = 100;
|
||||
|
||||
Fly::Fly(CGEEngine *vm, Bitmap **shpl)
|
||||
: Sprite(vm, shpl), _tx(0), _ty(0), _vm(vm) {
|
||||
step(newRandom(2));
|
||||
gotoxy(_l + newRandom(_r - _l - _w), _t + newRandom(_b - _t - _h));
|
||||
}
|
||||
|
||||
void Fly::tick() {
|
||||
step();
|
||||
if (_flags._kept)
|
||||
return;
|
||||
if (newRandom(10) < 1) {
|
||||
_tx = newRandom(3) - 1;
|
||||
_ty = newRandom(3) - 1;
|
||||
}
|
||||
if (_x + _tx < _l || _x + _tx + _w > _r)
|
||||
_tx = -_tx;
|
||||
if (_y + _ty < _t || _y + _ty + _h > _b)
|
||||
_ty = -_ty;
|
||||
gotoxy(_x + _tx, _y + _ty);
|
||||
}
|
||||
|
||||
} // End of namespace CGE
|
52
engines/cge/game.h
Normal file
52
engines/cge/game.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_GAME_H
|
||||
#define CGE_GAME_H
|
||||
|
||||
#include "cge/vga13h.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
uint8 *glass(Dac *pal, uint8 r, uint8 g, uint8 b);
|
||||
|
||||
class Fly : public Sprite {
|
||||
static const int _l;
|
||||
static const int _t;
|
||||
static const int _r;
|
||||
static const int _b;
|
||||
public:
|
||||
int _tx, _ty;
|
||||
Fly(CGEEngine *vm, Bitmap **shpl);
|
||||
void tick();
|
||||
private:
|
||||
CGEEngine *_vm;
|
||||
};
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
99
engines/cge/general.cpp
Normal file
99
engines/cge/general.cpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#include "cge/cge.h"
|
||||
#include "cge/general.h"
|
||||
#include "cge/snddrv.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
uint16 XCrypt(void *buf, uint16 siz) {
|
||||
byte *b = static_cast<byte *>(buf);
|
||||
|
||||
for (uint16 i = 0; i < siz; i++)
|
||||
*b++ ^= kCryptSeed;
|
||||
|
||||
return kCryptSeed;
|
||||
}
|
||||
|
||||
char *mergeExt(char *buf, const char *name, const char *ext) {
|
||||
strcpy(buf, name);
|
||||
char *dot = strrchr(buf, '.');
|
||||
if (!dot)
|
||||
strcat(buf, ext);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *forceExt(char *buf, const char *name, const char *ext) {
|
||||
strcpy(buf, name);
|
||||
char *dot = strrchr(buf, '.');
|
||||
if (dot)
|
||||
*dot = '\0';
|
||||
strcat(buf, ext);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void sndSetVolume() {
|
||||
// USeless for ScummVM
|
||||
}
|
||||
|
||||
DataCk *loadWave(VFile *file) {
|
||||
byte *data = (byte *)malloc(file->size());
|
||||
file->read(data, file->size());
|
||||
|
||||
return new DataCk(data, file->size());
|
||||
}
|
||||
|
||||
int takeEnum(const char **tab, const char *text) {
|
||||
const char **e;
|
||||
if (text) {
|
||||
for (e = tab; *e; e++) {
|
||||
if (scumm_stricmp(text, *e) == 0) {
|
||||
return e - tab;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int newRandom(int range) {
|
||||
return ((CGEEngine *)g_engine)->_randomSource.getRandomNumber(range - 1);
|
||||
}
|
||||
|
||||
DataCk::DataCk(byte *buf, int bufSize) {
|
||||
_buf = buf;
|
||||
_ckSize = bufSize;
|
||||
}
|
||||
|
||||
DataCk::~DataCk() {
|
||||
free(_buf);
|
||||
}
|
||||
|
||||
} // End of namespace CGE
|
||||
|
59
engines/cge/general.h
Normal file
59
engines/cge/general.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_GENERAL_H
|
||||
#define CGE_GENERAL_H
|
||||
|
||||
#include "common/system.h"
|
||||
#include "common/file.h"
|
||||
#include "common/random.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "common/str.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
#define kCryptSeed 0xA5
|
||||
#define kMaxFile 128
|
||||
|
||||
struct Dac {
|
||||
uint8 _r;
|
||||
uint8 _g;
|
||||
uint8 _b;
|
||||
};
|
||||
|
||||
typedef uint16 Crypt(void *buf, uint16 siz);
|
||||
|
||||
uint16 XCrypt(void *buf, uint16 siz);
|
||||
int takeEnum(const char **tab, const char *text);
|
||||
uint16 chkSum(void *m, uint16 n);
|
||||
char *mergeExt(char *buf, const char *name, const char *ext);
|
||||
char *forceExt(char *buf, const char *name, const char *ext);
|
||||
int newRandom(int range);
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
31
engines/cge/module.mk
Normal file
31
engines/cge/module.mk
Normal file
|
@ -0,0 +1,31 @@
|
|||
MODULE := engines/cge
|
||||
|
||||
MODULE_OBJS := \
|
||||
bitmap.o \
|
||||
cge.o \
|
||||
cge_main.o \
|
||||
console.o \
|
||||
detection.o \
|
||||
events.o \
|
||||
fileio.o \
|
||||
game.o \
|
||||
general.o \
|
||||
snail.o \
|
||||
sound.o \
|
||||
talk.o \
|
||||
text.o \
|
||||
vga13h.o \
|
||||
vmenu.o \
|
||||
walk.o
|
||||
|
||||
MODULE_DIRS += \
|
||||
engines/cge
|
||||
|
||||
# This module can be built as a plugin
|
||||
ifeq ($(ENABLE_CGE), DYNAMIC_PLUGIN)
|
||||
PLUGIN := 1
|
||||
endif
|
||||
|
||||
# Include common rules
|
||||
include $(srcdir)/rules.mk
|
||||
|
1182
engines/cge/snail.cpp
Normal file
1182
engines/cge/snail.cpp
Normal file
File diff suppressed because it is too large
Load diff
84
engines/cge/snail.h
Normal file
84
engines/cge/snail.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_SNAIL_H
|
||||
#define CGE_SNAIL_H
|
||||
|
||||
#include "cge/cge.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
#define kSnailFrameRate 80
|
||||
#define kSnailFrameDelay (1000 / kSnailFrameRate)
|
||||
#define kDressed 3
|
||||
|
||||
enum SnCom {
|
||||
kSnLabel, kSnPause, kSnWait, kSnLevel, kSnHide,
|
||||
kSnSay, kSnInf, kSnTime, kSnCave, kSnKill,
|
||||
kSnRSeq, kSnSeq, kSnSend, kSnSwap, kSnKeep,
|
||||
kSnGive, kSnIf, kSnGame, kSnSetX0, kSnSetY0,
|
||||
kSnSlave, kSnSetXY, kSnRelX, kSnRelY, kSnRelZ,
|
||||
kSnSetX, kSnSetY, kSnSetZ, kSnTrans, kSnPort,
|
||||
kSnNext, kSnNNext, kSnTNext, kSnRNNext, kSnRTNext,
|
||||
kSnRMNear, kSnRmTake, kSnFlag, kSnSetRef, kSnBackPt,
|
||||
kSnFlash, kSnLight, kSnSetHBarrier, kSnSetVBarrier, kSnWalk,
|
||||
kSnReach, kSnCover, kSnUncover, kSnClear, kSnTalk,
|
||||
kSnMouse, kSnSound, kSnCount, kSnExec, kSnStep,
|
||||
kSnZTrim, kSnGhost
|
||||
};
|
||||
|
||||
class Snail {
|
||||
public:
|
||||
struct Com {
|
||||
SnCom _com;
|
||||
int _ref;
|
||||
int _val;
|
||||
void *_ptr;
|
||||
CallbackType _cbType;
|
||||
} *_snList;
|
||||
uint8 _head;
|
||||
uint8 _tail;
|
||||
bool _turbo;
|
||||
bool _busy;
|
||||
bool _textDelay;
|
||||
uint32 _timerExpiry;
|
||||
static const char *_comText[];
|
||||
bool _talkEnable;
|
||||
Snail(CGEEngine *vm, bool turbo);
|
||||
~Snail();
|
||||
void runCom();
|
||||
void addCom(SnCom com, int ref, int val, void *ptr);
|
||||
void addCom2(SnCom com, int ref, int val, CallbackType cbType);
|
||||
void insCom(SnCom com, int ref, int val, void *ptr);
|
||||
bool idle();
|
||||
private:
|
||||
CGEEngine *_vm;
|
||||
};
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
63
engines/cge/snddrv.h
Normal file
63
engines/cge/snddrv.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_SNDDRV_H
|
||||
#define CGE_SNDDRV_H
|
||||
|
||||
namespace CGE {
|
||||
|
||||
// ******************************************************
|
||||
// * Constants *
|
||||
// ******************************************************
|
||||
|
||||
// sample info
|
||||
struct SmpInfo {
|
||||
const uint8 *_saddr; // address
|
||||
uint16 _slen; // length
|
||||
uint16 _span; // left/right pan (0-15)
|
||||
int _counter; // number of time the sample should be played
|
||||
};
|
||||
|
||||
// ******************************************************
|
||||
// * Data *
|
||||
// ******************************************************
|
||||
|
||||
// midi player flag (1 means we are playing)
|
||||
extern uint16 _midiPlayFlag;
|
||||
|
||||
// midi song end flag (1 means we have crossed end mark)
|
||||
extern uint16 _midiEndFlag;
|
||||
|
||||
// ******************************************************
|
||||
// * Driver Code *
|
||||
// ******************************************************
|
||||
// Set Volume
|
||||
void sndSetVolume();
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
273
engines/cge/sound.cpp
Normal file
273
engines/cge/sound.cpp
Normal file
|
@ -0,0 +1,273 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#include "cge/general.h"
|
||||
#include "cge/sound.h"
|
||||
#include "cge/text.h"
|
||||
#include "cge/cge_main.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/memstream.h"
|
||||
#include "audio/decoders/raw.h"
|
||||
#include "audio/audiostream.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
Sound::Sound(CGEEngine *vm) : _vm(vm) {
|
||||
_audioStream = NULL;
|
||||
_soundRepeatCount = 1;
|
||||
open();
|
||||
}
|
||||
|
||||
Sound::~Sound() {
|
||||
close();
|
||||
}
|
||||
|
||||
void Sound::close() {
|
||||
_vm->_midiPlayer.killMidi();
|
||||
}
|
||||
|
||||
void Sound::open() {
|
||||
setRepeat(1);
|
||||
play((*_fx)[30000], 8);
|
||||
}
|
||||
|
||||
void Sound::setRepeat(int16 count) {
|
||||
_soundRepeatCount = count;
|
||||
}
|
||||
|
||||
int16 Sound::getRepeat() {
|
||||
return _soundRepeatCount;
|
||||
}
|
||||
|
||||
void Sound::play(DataCk *wav, int pan) {
|
||||
if (wav) {
|
||||
stop();
|
||||
_smpinf._saddr = &*(wav->addr());
|
||||
_smpinf._slen = (uint16)wav->size();
|
||||
_smpinf._span = pan;
|
||||
_smpinf._counter = getRepeat();
|
||||
sndDigiStart(&_smpinf);
|
||||
}
|
||||
}
|
||||
|
||||
void Sound::sndDigiStart(SmpInfo *PSmpInfo) {
|
||||
// Create an audio stream wrapper for sound
|
||||
Common::MemoryReadStream *stream = new Common::MemoryReadStream(PSmpInfo->_saddr,
|
||||
PSmpInfo->_slen, DisposeAfterUse::NO);
|
||||
_audioStream = Audio::makeWAVStream(stream, DisposeAfterUse::YES);
|
||||
|
||||
// Start the new sound
|
||||
_vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle,
|
||||
Audio::makeLoopingAudioStream(_audioStream, (uint)PSmpInfo->_counter));
|
||||
}
|
||||
|
||||
void Sound::stop() {
|
||||
sndDigiStop(&_smpinf);
|
||||
}
|
||||
|
||||
void Sound::sndDigiStop(SmpInfo *PSmpInfo) {
|
||||
if (_vm->_mixer->isSoundHandleActive(_soundHandle))
|
||||
_vm->_mixer->stopHandle(_soundHandle);
|
||||
_audioStream = NULL;
|
||||
}
|
||||
|
||||
Fx::Fx(int size) : _current(NULL) {
|
||||
_cache = new Handler[size];
|
||||
for (_size = 0; _size < size; _size++) {
|
||||
_cache[_size]._ref = 0;
|
||||
_cache[_size]._wav = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Fx::~Fx() {
|
||||
clear();
|
||||
delete[] _cache;
|
||||
}
|
||||
|
||||
void Fx::clear() {
|
||||
for (Handler *p = _cache, *q = p + _size; p < q; p++) {
|
||||
if (p->_ref) {
|
||||
p->_ref = 0;
|
||||
delete p->_wav;
|
||||
p->_wav = NULL;
|
||||
}
|
||||
}
|
||||
_current = NULL;
|
||||
}
|
||||
|
||||
int Fx::find(int ref) {
|
||||
int i = 0;
|
||||
for (Handler *p = _cache, *q = p + _size; p < q; p++) {
|
||||
if (p->_ref == ref)
|
||||
break;
|
||||
else
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void Fx::preload(int ref0) {
|
||||
Handler *cacheLim = _cache + _size;
|
||||
char filename[12];
|
||||
|
||||
for (int ref = ref0; ref < ref0 + 10; ref++) {
|
||||
sprintf(filename, "FX%05d.WAV", ref);
|
||||
VFile file = VFile(filename);
|
||||
DataCk *wav = loadWave(&file);
|
||||
if (wav) {
|
||||
Handler *p = &_cache[find(0)];
|
||||
if (p >= cacheLim)
|
||||
break;
|
||||
p->_wav = wav;
|
||||
p->_ref = ref;
|
||||
} else {
|
||||
warning("Unable to load %s", filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DataCk *Fx::load(int idx, int ref) {
|
||||
char filename[12];
|
||||
sprintf(filename, "FX%05d.WAV", ref);
|
||||
|
||||
VFile file = VFile(filename);
|
||||
DataCk *wav = loadWave(&file);
|
||||
if (wav) {
|
||||
Handler *p = &_cache[idx];
|
||||
p->_wav = wav;
|
||||
p->_ref = ref;
|
||||
} else {
|
||||
warning("Unable to load %s", filename);
|
||||
}
|
||||
return wav;
|
||||
}
|
||||
|
||||
DataCk *Fx::operator [](int ref) {
|
||||
int i;
|
||||
if ((i = find(ref)) < _size)
|
||||
_current = _cache[i]._wav;
|
||||
else {
|
||||
if ((i = find(0)) >= _size) {
|
||||
clear();
|
||||
i = 0;
|
||||
}
|
||||
_current = load(i, ref);
|
||||
}
|
||||
return _current;
|
||||
}
|
||||
|
||||
MusicPlayer::MusicPlayer() {
|
||||
_data = NULL;
|
||||
_isGM = false;
|
||||
|
||||
MidiPlayer::createDriver();
|
||||
|
||||
int ret = _driver->open();
|
||||
if (ret == 0) {
|
||||
if (_nativeMT32)
|
||||
_driver->sendMT32Reset();
|
||||
else
|
||||
_driver->sendGMReset();
|
||||
|
||||
// TODO: Load cmf.ins with the instrument table. It seems that an
|
||||
// interface for such an operation is supported for AdLib. Maybe for
|
||||
// this card, setting instruments is necessary.
|
||||
|
||||
_driver->setTimerCallback(this, &timerCallback);
|
||||
}
|
||||
}
|
||||
|
||||
MusicPlayer::~MusicPlayer() {
|
||||
killMidi();
|
||||
}
|
||||
|
||||
void MusicPlayer::killMidi() {
|
||||
Audio::MidiPlayer::stop();
|
||||
|
||||
free(_data);
|
||||
_data = NULL;
|
||||
}
|
||||
|
||||
void MusicPlayer::loadMidi(int ref) {
|
||||
// Work out the filename and check the given MIDI file exists
|
||||
Common::String filename = Common::String::format("%.2d.MID", ref);
|
||||
if (!_cat->exist(filename.c_str()))
|
||||
return;
|
||||
|
||||
// Stop any currently playing MIDI file
|
||||
killMidi();
|
||||
|
||||
// Read in the data for the file
|
||||
VFile mid(filename.c_str());
|
||||
_dataSize = mid.size();
|
||||
_data = (byte *)malloc(_dataSize);
|
||||
mid.read(_data, _dataSize);
|
||||
|
||||
// Start playing the music
|
||||
sndMidiStart();
|
||||
}
|
||||
|
||||
void MusicPlayer::sndMidiStart() {
|
||||
_isGM = true;
|
||||
|
||||
MidiParser *parser = MidiParser::createParser_SMF();
|
||||
if (parser->loadMusic(_data, _dataSize)) {
|
||||
parser->setTrack(0);
|
||||
parser->setMidiDriver(this);
|
||||
parser->setTimerRate(_driver->getBaseTempo());
|
||||
parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
|
||||
|
||||
_parser = parser;
|
||||
|
||||
syncVolume();
|
||||
|
||||
_isPlaying = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MusicPlayer::send(uint32 b) {
|
||||
if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
|
||||
b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
|
||||
}
|
||||
|
||||
Audio::MidiPlayer::send(b);
|
||||
}
|
||||
|
||||
void MusicPlayer::sendToChannel(byte channel, uint32 b) {
|
||||
if (!_channelsTable[channel]) {
|
||||
_channelsTable[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
|
||||
// If a new channel is allocated during the playback, make sure
|
||||
// its volume is correctly initialized.
|
||||
if (_channelsTable[channel])
|
||||
_channelsTable[channel]->volume(_channelsVolume[channel] * _masterVolume / 255);
|
||||
}
|
||||
|
||||
if (_channelsTable[channel])
|
||||
_channelsTable[channel]->send(b);
|
||||
}
|
||||
|
||||
} // End of namespace CGE
|
126
engines/cge/sound.h
Normal file
126
engines/cge/sound.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_SOUND_H
|
||||
#define CGE_SOUND_H
|
||||
|
||||
#include "cge/fileio.h"
|
||||
#include "cge/snddrv.h"
|
||||
#include "audio/audiostream.h"
|
||||
#include "audio/decoders/wave.h"
|
||||
#include "audio/fmopl.h"
|
||||
#include "audio/mididrv.h"
|
||||
#include "audio/midiparser.h"
|
||||
#include "audio/midiplayer.h"
|
||||
#include "audio/mixer.h"
|
||||
#include "common/memstream.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
class CGEEngine;
|
||||
|
||||
class DataCk {
|
||||
byte *_buf;
|
||||
int _ckSize;
|
||||
public:
|
||||
DataCk(byte *buf, int bufSize);
|
||||
~DataCk();
|
||||
inline const byte *addr() {
|
||||
return _buf;
|
||||
}
|
||||
inline int size() {
|
||||
return _ckSize;
|
||||
}
|
||||
};
|
||||
|
||||
DataCk *loadWave(VFile *file);
|
||||
|
||||
class Sound {
|
||||
public:
|
||||
SmpInfo _smpinf;
|
||||
Sound(CGEEngine *vm);
|
||||
~Sound();
|
||||
void open();
|
||||
void close();
|
||||
void play(DataCk *wav, int pan);
|
||||
int16 getRepeat();
|
||||
void setRepeat(int16 count);
|
||||
void stop();
|
||||
private:
|
||||
int _soundRepeatCount;
|
||||
CGEEngine *_vm;
|
||||
Audio::SoundHandle _soundHandle;
|
||||
Audio::RewindableAudioStream *_audioStream;
|
||||
|
||||
void sndDigiStart(SmpInfo *PSmpInfo);
|
||||
void sndDigiStop(SmpInfo *PSmpInfo);
|
||||
};
|
||||
|
||||
|
||||
class Fx {
|
||||
struct Handler {
|
||||
int _ref;
|
||||
DataCk *_wav;
|
||||
} *_cache;
|
||||
int _size;
|
||||
DataCk *load(int idx, int ref);
|
||||
int find(int ref);
|
||||
public:
|
||||
DataCk *_current;
|
||||
Fx(int size);
|
||||
~Fx();
|
||||
void clear();
|
||||
void preload(int ref0);
|
||||
DataCk *operator[](int ref);
|
||||
};
|
||||
|
||||
class MusicPlayer: public Audio::MidiPlayer {
|
||||
private:
|
||||
byte *_data;
|
||||
int _dataSize;
|
||||
bool _isGM;
|
||||
|
||||
// Start MIDI File
|
||||
void sndMidiStart();
|
||||
|
||||
// Stop MIDI File
|
||||
void sndMidiStop();
|
||||
public:
|
||||
MusicPlayer();
|
||||
~MusicPlayer();
|
||||
|
||||
void loadMidi(int ref);
|
||||
void killMidi();
|
||||
|
||||
virtual void send(uint32 b);
|
||||
virtual void sendToChannel(byte channel, uint32 b);
|
||||
};
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
||||
|
302
engines/cge/talk.cpp
Normal file
302
engines/cge/talk.cpp
Normal file
|
@ -0,0 +1,302 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#include "cge/general.h"
|
||||
#include "cge/talk.h"
|
||||
#include "cge/game.h"
|
||||
#include "cge/events.h"
|
||||
#include "cge/cge_main.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
Font::Font(const char *name) {
|
||||
_map = (uint8 *)malloc(kMapSize);
|
||||
_pos = (uint16 *)malloc(kPosSize * sizeof(uint16));
|
||||
_widthArr = (uint8 *)malloc(kWidSize);
|
||||
|
||||
assert((_map != NULL) && (_pos != NULL) && (_widthArr != NULL));
|
||||
mergeExt(_path, name, kFontExt);
|
||||
load();
|
||||
}
|
||||
|
||||
Font::~Font() {
|
||||
free(_map);
|
||||
free(_pos);
|
||||
free(_widthArr);
|
||||
}
|
||||
|
||||
void Font::load() {
|
||||
EncryptedStream f = _path;
|
||||
assert(!f.err());
|
||||
|
||||
f.read(_widthArr, kWidSize);
|
||||
assert(!f.err());
|
||||
|
||||
uint16 p = 0;
|
||||
for (uint16 i = 0; i < kPosSize; i++) {
|
||||
_pos[i] = p;
|
||||
p += _widthArr[i];
|
||||
}
|
||||
f.read(_map, p);
|
||||
}
|
||||
|
||||
uint16 Font::width(const char *text) {
|
||||
uint16 w = 0;
|
||||
if (!text)
|
||||
return 0;
|
||||
while (*text)
|
||||
w += _widthArr[(unsigned char)*(text++)];
|
||||
return w;
|
||||
}
|
||||
|
||||
Talk::Talk(CGEEngine *vm, const char *text, TextBoxStyle mode)
|
||||
: Sprite(vm, NULL), _mode(mode), _vm(vm) {
|
||||
_ts = NULL;
|
||||
_flags._syst = true;
|
||||
update(text);
|
||||
}
|
||||
|
||||
|
||||
Talk::Talk(CGEEngine *vm)
|
||||
: Sprite(vm, NULL), _mode(kTBPure), _vm(vm) {
|
||||
_ts = NULL;
|
||||
_flags._syst = true;
|
||||
}
|
||||
|
||||
Font *Talk::_font;
|
||||
|
||||
void Talk::init() {
|
||||
_font = new Font("CGE");
|
||||
}
|
||||
|
||||
void Talk::deinit() {
|
||||
delete _font;
|
||||
}
|
||||
|
||||
void Talk::update(const char *text) {
|
||||
const uint16 vmarg = (_mode) ? kTextVMargin : 0;
|
||||
const uint16 hmarg = (_mode) ? kTextHMargin : 0;
|
||||
uint16 mw = 0;
|
||||
uint16 ln = vmarg;
|
||||
uint8 *m;
|
||||
|
||||
if (!_ts) {
|
||||
uint16 k = 2 * hmarg;
|
||||
uint16 mh = 2 * vmarg + kFontHigh;
|
||||
for (const char *p = text; *p; p++) {
|
||||
if (*p == '|' || *p == '\n') {
|
||||
mh += kFontHigh + kTextLineSpace;
|
||||
if (k > mw)
|
||||
mw = k;
|
||||
k = 2 * hmarg;
|
||||
} else
|
||||
k += _font->_widthArr[(unsigned char)*p];
|
||||
}
|
||||
if (k > mw)
|
||||
mw = k;
|
||||
|
||||
_ts = new BitmapPtr[2];
|
||||
_ts[0] = box(mw, mh);
|
||||
_ts[1] = NULL;
|
||||
}
|
||||
|
||||
m = _ts[0]->_m + ln * mw + hmarg;
|
||||
|
||||
while (*text) {
|
||||
if (*text == '|' || *text == '\n') {
|
||||
m = _ts[0]->_m + (ln += kFontHigh + kTextLineSpace) * mw + hmarg;
|
||||
} else {
|
||||
int cw = _font->_widthArr[(unsigned char)*text];
|
||||
uint8 *f = _font->_map + _font->_pos[(unsigned char)*text];
|
||||
for (int i = 0; i < cw; i++) {
|
||||
uint8 *pp = m;
|
||||
uint16 n;
|
||||
uint16 b = *(f++);
|
||||
for (n = 0; n < kFontHigh; n++) {
|
||||
if (b & 1)
|
||||
*pp = kTextColFG;
|
||||
b >>= 1;
|
||||
pp += mw;
|
||||
}
|
||||
m++;
|
||||
}
|
||||
}
|
||||
text++;
|
||||
}
|
||||
_ts[0]->code();
|
||||
setShapeList(_ts);
|
||||
}
|
||||
|
||||
Bitmap *Talk::box(uint16 w, uint16 h) {
|
||||
if (w < 8)
|
||||
w = 8;
|
||||
if (h < 8)
|
||||
h = 8;
|
||||
uint16 n = w * h;
|
||||
uint8 *b = (uint8 *)malloc(n);
|
||||
assert(b != NULL);
|
||||
memset(b, kTextColBG, n);
|
||||
|
||||
if (_mode) {
|
||||
uint8 *p = b;
|
||||
uint8 *q = b + n - w;
|
||||
memset(p, kVgaColLightGray, w);
|
||||
memset(q, kVgaColDarkGray, w);
|
||||
while (p < q) {
|
||||
p += w;
|
||||
*(p - 1) = kVgaColDarkGray;
|
||||
*p = kVgaColLightGray;
|
||||
}
|
||||
p = b;
|
||||
const uint16 r = (_mode == kTBRound) ? kTextRoundCorner : 0;
|
||||
for (int i = 0; i < r; i++) {
|
||||
int j;
|
||||
for (j = 0; j < r - i; j++) {
|
||||
p[j] = kPixelTransp;
|
||||
p[w - j - 1] = kPixelTransp;
|
||||
q[j] = kPixelTransp;
|
||||
q[w - j - 1] = kPixelTransp;
|
||||
}
|
||||
p[j] = kVgaColLightGray;
|
||||
p[w - j - 1] = kVgaColDarkGray;
|
||||
q[j] = kVgaColLightGray;
|
||||
q[w - j - 1] = kVgaColDarkGray;
|
||||
p += w;
|
||||
q -= w;
|
||||
}
|
||||
}
|
||||
return new Bitmap(w, h, b);
|
||||
}
|
||||
|
||||
void Talk::putLine(int line, const char *text) {
|
||||
// Note: (_ts[0]._w % 4) must be 0
|
||||
uint16 w = _ts[0]->_w;
|
||||
uint16 h = _ts[0]->_h;
|
||||
uint8 *v = _ts[0]->_v;
|
||||
uint16 dsiz = w >> 2; // data size (1 plane line size)
|
||||
uint16 lsiz = 2 + dsiz + 2; // uint16 for line header, uint16 for gap
|
||||
uint16 psiz = h * lsiz; // - last gap, but + plane trailer
|
||||
uint16 size = 4 * psiz; // whole map size
|
||||
uint16 rsiz = kFontHigh * lsiz; // length of whole text row map
|
||||
|
||||
// set desired line pointer
|
||||
v += (kTextVMargin + (kFontHigh + kTextLineSpace) * line) * lsiz;
|
||||
uint8 *p = v; // assume blanked line above text
|
||||
|
||||
// clear whole rectangle
|
||||
assert((rsiz % lsiz) == 0);
|
||||
for (int planeCtr = 0; planeCtr < 4; planeCtr++, p += psiz) {
|
||||
for (byte *pDest = p; pDest < (p + (rsiz - lsiz)); pDest += lsiz)
|
||||
Common::copy(p - lsiz, p, pDest);
|
||||
}
|
||||
|
||||
// paint text line
|
||||
if (!text)
|
||||
return;
|
||||
p = v + 2 + (kTextHMargin / 4) + (kTextHMargin % 4) * psiz;
|
||||
uint8 *q = v + size;
|
||||
|
||||
while (*text) {
|
||||
uint16 cw = _font->_widthArr[(unsigned char)*text], i;
|
||||
uint8 *fp = _font->_map + _font->_pos[(unsigned char)*text];
|
||||
|
||||
for (i = 0; i < cw; i++) {
|
||||
uint16 b = fp[i];
|
||||
uint16 n;
|
||||
for (n = 0; n < kFontHigh; n++) {
|
||||
if (b & 1)
|
||||
*p = kTextColFG;
|
||||
b >>= 1;
|
||||
p += lsiz;
|
||||
}
|
||||
p = p - rsiz + psiz;
|
||||
if (p >= q)
|
||||
p = p - size + 1;
|
||||
}
|
||||
text++;
|
||||
}
|
||||
}
|
||||
|
||||
InfoLine::InfoLine(CGEEngine *vm, uint16 w) : Talk(vm), _oldText(NULL), _vm(vm) {
|
||||
if (!_ts) {
|
||||
_ts = new BitmapPtr[2];
|
||||
_ts[1] = NULL;
|
||||
}
|
||||
|
||||
_ts[0] = new Bitmap(w, kFontHigh, kTextColBG);
|
||||
setShapeList(_ts);
|
||||
}
|
||||
|
||||
void InfoLine::update(const char *text) {
|
||||
if (text == _oldText)
|
||||
return;
|
||||
|
||||
uint16 w = _ts[0]->_w;
|
||||
uint16 h = _ts[0]->_h;
|
||||
uint8 *v = (uint8 *)_ts[0]->_v;
|
||||
uint16 dsiz = w >> 2; // data size (1 plane line size)
|
||||
uint16 lsiz = 2 + dsiz + 2; // uint16 for line header, uint16 for gap
|
||||
uint16 psiz = h * lsiz; // - last gape, but + plane trailer
|
||||
uint16 size = 4 * psiz; // whole map size
|
||||
|
||||
// clear whole rectangle
|
||||
memset(v + 2, kTextColBG, dsiz); // data bytes
|
||||
for (byte *pDest = v + lsiz; pDest < (v + psiz); pDest += lsiz) {
|
||||
Common::copy(v, v + lsiz, pDest);
|
||||
}
|
||||
*(uint16 *)(v + psiz - 2) = TO_LE_16(kBmpEOI); // plane trailer uint16
|
||||
for (byte *pDest = v + psiz; pDest < (v + 4 * psiz); pDest += psiz) {
|
||||
Common::copy(v, v + psiz, pDest);
|
||||
}
|
||||
|
||||
// paint text line
|
||||
if (text) {
|
||||
uint8 *p = v + 2, * q = p + size;
|
||||
|
||||
while (*text) {
|
||||
uint16 cw = _font->_widthArr[(unsigned char)*text];
|
||||
uint8 *fp = _font->_map + _font->_pos[(unsigned char)*text];
|
||||
|
||||
for (uint16 i = 0; i < cw; i++) {
|
||||
uint16 b = fp[i];
|
||||
for (uint16 n = 0; n < kFontHigh; n++) {
|
||||
if (b & 1)
|
||||
*p = kTextColFG;
|
||||
b >>= 1;
|
||||
p += lsiz;
|
||||
}
|
||||
if (p >= q)
|
||||
p = p - size + 1;
|
||||
}
|
||||
text++;
|
||||
}
|
||||
}
|
||||
|
||||
_oldText = text;
|
||||
}
|
||||
|
||||
} // End of namespace CGE
|
96
engines/cge/talk.h
Normal file
96
engines/cge/talk.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_TALK_H
|
||||
#define CGE_TALK_H
|
||||
|
||||
#include "cge/general.h"
|
||||
#include "cge/vga13h.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
#define kTextColFG kVgaColDark // foreground color
|
||||
#define kTextColBG kVgaColGray // background color
|
||||
#define kTextHMargin (6&~1) // EVEN horizontal margins!
|
||||
#define kTextVMargin 5 // vertical margins
|
||||
#define kTextLineSpace 2 // line spacing
|
||||
#define kTextRoundCorner 3 // rounded corners
|
||||
#define kWidSize 256
|
||||
#define kPosSize 256
|
||||
#define kMapSize (256*8)
|
||||
#define kFontHigh 8
|
||||
#define kFontExt ".CFT"
|
||||
#define kPathMax 128
|
||||
|
||||
enum TextBoxStyle { kTBPure, kTBRect, kTBRound };
|
||||
|
||||
class Font {
|
||||
char _path[kPathMax];
|
||||
void load();
|
||||
public:
|
||||
uint8 *_widthArr;
|
||||
uint16 *_pos;
|
||||
uint8 *_map;
|
||||
Font(const char *name);
|
||||
~Font();
|
||||
uint16 width(const char *text);
|
||||
void save();
|
||||
};
|
||||
|
||||
class Talk : public Sprite {
|
||||
protected:
|
||||
TextBoxStyle _mode;
|
||||
BitmapPtr *_ts;
|
||||
Bitmap *box(uint16 w, uint16 h);
|
||||
public:
|
||||
Talk(CGEEngine *vm, const char *text, TextBoxStyle mode);
|
||||
Talk(CGEEngine *vm);
|
||||
//~TALK();
|
||||
|
||||
static Font *_font;
|
||||
static void init();
|
||||
static void deinit();
|
||||
|
||||
virtual void update(const char *text);
|
||||
virtual void update() {}
|
||||
void putLine(int line, const char *text);
|
||||
private:
|
||||
CGEEngine *_vm;
|
||||
};
|
||||
|
||||
class InfoLine : public Talk {
|
||||
const char *_oldText;
|
||||
public:
|
||||
InfoLine(CGEEngine *vm, uint16 wid);
|
||||
void update(const char *text);
|
||||
private:
|
||||
CGEEngine *_vm;
|
||||
};
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
215
engines/cge/text.cpp
Normal file
215
engines/cge/text.cpp
Normal file
|
@ -0,0 +1,215 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#include "cge/general.h"
|
||||
#include "cge/text.h"
|
||||
#include "cge/talk.h"
|
||||
#include "cge/game.h"
|
||||
#include "cge/snail.h"
|
||||
#include "cge/cge_main.h"
|
||||
#include "common/str.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
Text *_text;
|
||||
Talk *_talk = NULL;
|
||||
|
||||
Text::Text(CGEEngine *vm, const char *fname) : _vm(vm) {
|
||||
mergeExt(_fileName, fname, kSayExt);
|
||||
if (!_cat->exist(_fileName))
|
||||
error("No talk (%s)\n", _fileName);
|
||||
int16 txtCount = count() + 1;
|
||||
warning("Number of texts: %d", txtCount);
|
||||
|
||||
_cache = new Handler[txtCount];
|
||||
for (_size = 0; _size < txtCount; _size++) {
|
||||
_cache[_size]._ref = 0;
|
||||
_cache[_size]._text = NULL;
|
||||
}
|
||||
load();
|
||||
}
|
||||
|
||||
Text::~Text() {
|
||||
clear();
|
||||
delete[] _cache;
|
||||
}
|
||||
|
||||
int16 Text::count() {
|
||||
EncryptedStream tf = _fileName;
|
||||
if (tf.err())
|
||||
return NULL;
|
||||
|
||||
Common::String line;
|
||||
char tmpStr[kLineMax + 1];
|
||||
int n, count = 0;
|
||||
|
||||
for (line = tf.readLine(); !tf.eos(); line = tf.readLine()) {
|
||||
n = line.size();
|
||||
char *s;
|
||||
|
||||
strcpy(tmpStr, line.c_str());
|
||||
if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
|
||||
continue;
|
||||
if (!isdigit(*s))
|
||||
continue;
|
||||
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void Text::clear() {
|
||||
for (Handler *p = _cache, *q = p + _size; p < q; p++) {
|
||||
if (p->_ref) {
|
||||
p->_ref = 0;
|
||||
delete[] p->_text;
|
||||
p->_text = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Text::load() {
|
||||
EncryptedStream tf = _fileName;
|
||||
assert(!tf.err());
|
||||
|
||||
Common::String line;
|
||||
char tmpStr[kLineMax + 1];
|
||||
int idx;
|
||||
|
||||
for (idx = 0, line = tf.readLine(); !tf.eos(); line = tf.readLine()) {
|
||||
int n = line.size();
|
||||
char *s;
|
||||
|
||||
strcpy(tmpStr, line.c_str());
|
||||
if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
|
||||
continue;
|
||||
if (!isdigit(*s))
|
||||
continue;
|
||||
|
||||
int r = atoi(s);
|
||||
|
||||
s += strlen(s);
|
||||
if (s < tmpStr + n)
|
||||
++s;
|
||||
|
||||
_cache[idx]._ref = r;
|
||||
_cache[idx]._text = new char[strlen(s) + 1];
|
||||
strcpy(_cache[idx]._text, s);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
char *Text::getText(int ref) {
|
||||
int i;
|
||||
for (i = 0; (i < _size) && (_cache[i]._ref != ref); i++)
|
||||
;
|
||||
|
||||
if (i < _size)
|
||||
return _cache[i]._text;
|
||||
|
||||
warning("getText: Unable to find ref %d", ref);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Text::say(const char *text, Sprite *spr) {
|
||||
killText();
|
||||
_talk = new Talk(_vm, text, kTBRound);
|
||||
if (!_talk)
|
||||
return;
|
||||
|
||||
bool east = spr->_flags._east;
|
||||
int x = (east) ? (spr->_x + spr->_w - 2) : (spr->_x + 2);
|
||||
int y = spr->_y + 2;
|
||||
Sprite *spike = new Spike(_vm);
|
||||
uint16 sw = spike->_w;
|
||||
|
||||
if (east) {
|
||||
if (x + sw + kTextRoundCorner + 5 >= kScrWidth)
|
||||
east = false;
|
||||
} else {
|
||||
if (x <= 5 + kTextRoundCorner + sw)
|
||||
east = true;
|
||||
}
|
||||
x = (east) ? (spr->_x + spr->_w - 2) : (spr->_x + 2 - sw);
|
||||
if (spr->_ref == 1)
|
||||
x += ((east) ? -10 : 10); // Hero
|
||||
|
||||
_talk->_flags._kill = true;
|
||||
_talk->_flags._bDel = true;
|
||||
_talk->setName(_text->getText(kSayName));
|
||||
_talk->gotoxy(x - (_talk->_w - sw) / 2 - 3 + 6 * east, y - spike->_h - _talk->_h + 1);
|
||||
_talk->_z = 125;
|
||||
_talk->_ref = kSayRef;
|
||||
|
||||
spike->gotoxy(x, _talk->_y + _talk->_h - 1);
|
||||
spike->_z = 126;
|
||||
spike->_flags._slav = true;
|
||||
spike->_flags._kill = true;
|
||||
spike->setName(_text->getText(kSayName));
|
||||
spike->step(east);
|
||||
spike->_ref = kSayRef;
|
||||
|
||||
_vga->_showQ->insert(_talk, _vga->_showQ->last());
|
||||
_vga->_showQ->insert(spike, _vga->_showQ->last());
|
||||
}
|
||||
|
||||
void CGEEngine::inf(const char *text) {
|
||||
debugC(1, kCGEDebugEngine, "CGEEngine::inf(%s)", text);
|
||||
|
||||
killText();
|
||||
_talk = new Talk(this, text, kTBRect);
|
||||
if (!_talk)
|
||||
return;
|
||||
|
||||
_talk->_flags._kill = true;
|
||||
_talk->_flags._bDel = true;
|
||||
_talk->setName(_text->getText(kInfName));
|
||||
_talk->center();
|
||||
_talk->gotoxy(_talk->_x, _talk->_y - 20);
|
||||
_talk->_z = 126;
|
||||
_talk->_ref = kInfRef;
|
||||
_vga->_showQ->insert(_talk, _vga->_showQ->last());
|
||||
}
|
||||
|
||||
void Text::sayTime(Sprite *spr) {
|
||||
TimeDate curTime;
|
||||
_vm->_system->getTimeAndDate(curTime);
|
||||
|
||||
char t[6];
|
||||
sprintf(t, "%d:%02d", curTime.tm_hour, curTime.tm_min);
|
||||
say(t, spr);
|
||||
}
|
||||
|
||||
void killText() {
|
||||
if (!_talk)
|
||||
return;
|
||||
|
||||
_snail_->addCom(kSnKill, -1, 0, _talk);
|
||||
_talk = NULL;
|
||||
}
|
||||
|
||||
} // End of namespace CGE
|
71
engines/cge/text.h
Normal file
71
engines/cge/text.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_TEXT_H
|
||||
#define CGE_TEXT_H
|
||||
|
||||
#include "cge/talk.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
#define kSayExt ".SAY"
|
||||
#define kSysTextMax 1000
|
||||
#define kTextNoMouse 95
|
||||
#define kInfName 101
|
||||
#define kSayName 102
|
||||
#define kInfRef 301
|
||||
#define kSayRef 302
|
||||
|
||||
|
||||
class Text {
|
||||
struct Handler {
|
||||
int _ref;
|
||||
char *_text;
|
||||
} *_cache;
|
||||
int _size;
|
||||
char _fileName[kPathMax];
|
||||
void load();
|
||||
int16 count();
|
||||
public:
|
||||
Text(CGEEngine *vm, const char *fname);
|
||||
~Text();
|
||||
void clear();
|
||||
char *getText(int ref);
|
||||
void say(const char *text, Sprite *spr);
|
||||
void sayTime(Sprite *spr);
|
||||
private:
|
||||
CGEEngine *_vm;
|
||||
};
|
||||
|
||||
extern Talk *_talk;
|
||||
extern Text *_text;
|
||||
|
||||
void killText();
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
1011
engines/cge/vga13h.cpp
Normal file
1011
engines/cge/vga13h.cpp
Normal file
File diff suppressed because it is too large
Load diff
274
engines/cge/vga13h.h
Normal file
274
engines/cge/vga13h.h
Normal file
|
@ -0,0 +1,274 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_VGA13H_H
|
||||
#define CGE_VGA13H_H
|
||||
|
||||
#include "common/serializer.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "cge/general.h"
|
||||
#include "cge/bitmap.h"
|
||||
#include "cge/snail.h"
|
||||
#include "cge/cge.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
#define kFadeStep 2
|
||||
#define kVgaColDark 207
|
||||
#define kVgaColDarkGray 225 /*219*/
|
||||
#define kVgaColGray 231
|
||||
#define kVgaColLightGray 237
|
||||
#define kPixelTransp 0xFE
|
||||
#define kNoSeq (-1)
|
||||
#define kNoPtr ((uint8)-1)
|
||||
#define kSprExt ".SPR"
|
||||
#define kPalCount 256
|
||||
#define kPalSize (kPalCount * 3)
|
||||
|
||||
|
||||
struct Seq {
|
||||
uint8 _now;
|
||||
uint8 _next;
|
||||
int8 _dx;
|
||||
int8 _dy;
|
||||
int _dly;
|
||||
};
|
||||
|
||||
extern Seq _seq1[];
|
||||
extern Seq _seq2[];
|
||||
|
||||
class SprExt {
|
||||
public:
|
||||
int _x0;
|
||||
int _y0;
|
||||
int _x1;
|
||||
int _y1;
|
||||
BitmapPtr _b0;
|
||||
BitmapPtr _b1;
|
||||
BitmapPtr *_shpList;
|
||||
Seq *_seq;
|
||||
char *_name;
|
||||
Snail::Com *_near;
|
||||
Snail::Com *_take;
|
||||
SprExt() :
|
||||
_x0(0), _y0(0),
|
||||
_x1(0), _y1(0),
|
||||
_b0(NULL), _b1(NULL),
|
||||
_shpList(NULL), _seq(NULL),
|
||||
_name(NULL), _near(NULL), _take(NULL)
|
||||
{}
|
||||
};
|
||||
|
||||
class Sprite {
|
||||
protected:
|
||||
SprExt *_ext;
|
||||
public:
|
||||
int _ref;
|
||||
signed char _cave;
|
||||
struct Flags {
|
||||
uint16 _hide : 1; // general visibility switch
|
||||
uint16 _near : 1; // Near action lock
|
||||
uint16 _drag : 1; // sprite is moveable
|
||||
uint16 _hold : 1; // sprite is held with mouse
|
||||
uint16 _____ : 1; // intrrupt driven animation
|
||||
uint16 _slav : 1; // slave object
|
||||
uint16 _syst : 1; // system object
|
||||
uint16 _kill : 1; // dispose memory after remove
|
||||
uint16 _xlat : 1; // 2nd way display: xlat table
|
||||
uint16 _port : 1; // portable
|
||||
uint16 _kept : 1; // kept in pocket
|
||||
uint16 _east : 1; // talk to east (in opposite to west)
|
||||
uint16 _shad : 1; // shadow
|
||||
uint16 _back : 1; // 'send to background' request
|
||||
uint16 _bDel : 1; // delete bitmaps in ~SPRITE
|
||||
uint16 _tran : 1; // transparent (untouchable)
|
||||
} _flags;
|
||||
int _x;
|
||||
int _y;
|
||||
signed char _z;
|
||||
uint16 _w;
|
||||
uint16 _h;
|
||||
uint16 _time;
|
||||
uint8 _nearPtr;
|
||||
uint8 _takePtr;
|
||||
int _seqPtr;
|
||||
int _shpCnt;
|
||||
char _file[kMaxFile];
|
||||
Sprite *_prev;
|
||||
Sprite *_next;
|
||||
|
||||
bool works(Sprite *spr);
|
||||
bool seqTest(int n);
|
||||
inline bool active() {
|
||||
return _ext != NULL;
|
||||
}
|
||||
|
||||
Sprite(CGEEngine *vm, BitmapPtr *shp);
|
||||
virtual ~Sprite();
|
||||
BitmapPtr shp();
|
||||
BitmapPtr *setShapeList(BitmapPtr *shp);
|
||||
void moveShapes(uint8 *buf);
|
||||
Sprite *expand();
|
||||
Sprite *contract();
|
||||
Sprite *backShow(bool fast = false);
|
||||
void setName(char *newName);
|
||||
inline char *name() {
|
||||
return (_ext) ? _ext->_name : NULL;
|
||||
}
|
||||
void gotoxy(int x, int y);
|
||||
void center();
|
||||
void show();
|
||||
void hide();
|
||||
BitmapPtr ghost();
|
||||
void show(uint16 pg);
|
||||
void makeXlat(uint8 *x);
|
||||
void killXlat();
|
||||
void step(int nr = -1);
|
||||
Seq *setSeq(Seq *seq);
|
||||
Snail::Com *snList(SnList type);
|
||||
virtual void touch(uint16 mask, int x, int y);
|
||||
virtual void tick();
|
||||
void sync(Common::Serializer &s);
|
||||
private:
|
||||
CGEEngine *_vm;
|
||||
};
|
||||
|
||||
class Queue {
|
||||
Sprite *_head;
|
||||
Sprite *_tail;
|
||||
public:
|
||||
Queue(bool show);
|
||||
~Queue();
|
||||
|
||||
bool _show;
|
||||
|
||||
void append(Sprite *spr);
|
||||
void insert(Sprite *spr, Sprite *nxt);
|
||||
void insert(Sprite *spr);
|
||||
Sprite *remove(Sprite *spr);
|
||||
void forAll(void (*fun)(Sprite *));
|
||||
Sprite *first() {
|
||||
return _head;
|
||||
}
|
||||
Sprite *last() {
|
||||
return _tail;
|
||||
}
|
||||
Sprite *locate(int ref);
|
||||
void clear();
|
||||
};
|
||||
|
||||
class Vga {
|
||||
bool _setPal;
|
||||
Dac *_oldColors;
|
||||
Dac *_newColors;
|
||||
const char *_msg;
|
||||
const char *_name;
|
||||
|
||||
void updateColors();
|
||||
void setColors();
|
||||
void waitVR();
|
||||
public:
|
||||
uint32 _frmCnt;
|
||||
Queue *_showQ;
|
||||
Queue *_spareQ;
|
||||
int _mono;
|
||||
Graphics::Surface *_page[4];
|
||||
Dac *_sysPal;
|
||||
|
||||
Vga();
|
||||
~Vga();
|
||||
|
||||
void getColors(Dac *tab);
|
||||
void setColors(Dac *tab, int lum);
|
||||
void clear(uint8 color);
|
||||
void copyPage(uint16 d, uint16 s);
|
||||
void sunrise(Dac *tab);
|
||||
void sunset();
|
||||
void show();
|
||||
void update();
|
||||
|
||||
static void palToDac(const byte *palData, Dac *tab);
|
||||
static void dacToPal(const Dac *tab, byte *palData);
|
||||
};
|
||||
|
||||
class HorizLine: public Sprite {
|
||||
public:
|
||||
HorizLine(CGEEngine *vm);
|
||||
};
|
||||
|
||||
class CavLight: public Sprite {
|
||||
public:
|
||||
CavLight(CGEEngine *vm);
|
||||
};
|
||||
|
||||
class Spike: public Sprite {
|
||||
public:
|
||||
Spike(CGEEngine *vm);
|
||||
};
|
||||
|
||||
class PocLight: public Sprite {
|
||||
public:
|
||||
PocLight(CGEEngine *vm);
|
||||
};
|
||||
|
||||
Dac mkDac(uint8 r, uint8 g, uint8 b);
|
||||
|
||||
template <class CBLK>
|
||||
uint8 closest(CBLK *pal, CBLK x) {
|
||||
#define f(col, lum) ((((uint16)(col)) << 8) / lum)
|
||||
uint16 i, dif = 0xFFFF, found = 0;
|
||||
uint16 L = x._r + x._g + x._b;
|
||||
if (!L)
|
||||
L++;
|
||||
uint16 R = f(x._r, L), G = f(x._g, L), B = f(x._b, L);
|
||||
for (i = 0; i < 256; i++) {
|
||||
uint16 l = pal[i]._r + pal[i]._g + pal[i]._b;
|
||||
if (!l)
|
||||
l++;
|
||||
int r = f(pal[i]._r, l), g = f(pal[i]._g, l), b = f(pal[i]._b, l);
|
||||
uint16 D = ((r > R) ? (r - R) : (R - r)) +
|
||||
((g > G) ? (g - G) : (G - g)) +
|
||||
((b > B) ? (b - B) : (B - b)) +
|
||||
((l > L) ? (l - L) : (L - l)) * 10 ;
|
||||
|
||||
if (D < dif) {
|
||||
found = i;
|
||||
dif = D;
|
||||
if (D == 0)
|
||||
break; // exact!
|
||||
}
|
||||
}
|
||||
return found;
|
||||
#undef f
|
||||
}
|
||||
|
||||
Sprite *spriteAt(int x, int y);
|
||||
Sprite *locate(int ref);
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
142
engines/cge/vmenu.cpp
Normal file
142
engines/cge/vmenu.cpp
Normal file
|
@ -0,0 +1,142 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#include "cge/vmenu.h"
|
||||
#include "cge/events.h"
|
||||
#include "cge/cge_main.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
MenuBar::MenuBar(CGEEngine *vm, uint16 w) : Talk(vm), _vm(vm) {
|
||||
int h = kFontHigh + 2 * kMenuBarVM;
|
||||
int i = (w += 2 * kMenuBarHM) * h;
|
||||
uint8 *p = (uint8 *)malloc(sizeof(uint8) * i);
|
||||
|
||||
memset(p + w, kPixelTransp, i - 2 * w);
|
||||
memset(p, kMenuBarLT, w);
|
||||
memset(p + i - w, kMenuBarRB, w);
|
||||
uint8 *p1 = p;
|
||||
uint8 *p2 = p + i - 1;
|
||||
for (int cpt = 0; cpt < h; cpt++) {
|
||||
*p1 = kMenuBarLT;
|
||||
*p2 = kMenuBarRB;
|
||||
p1 += w;
|
||||
p2 -= w;
|
||||
}
|
||||
|
||||
_ts = new BitmapPtr[2];
|
||||
_ts[0] = new Bitmap(w, h, p);
|
||||
_ts[1] = NULL;
|
||||
setShapeList(_ts);
|
||||
|
||||
_flags._slav = true;
|
||||
_flags._tran = true;
|
||||
_flags._kill = true;
|
||||
_flags._bDel = true;
|
||||
}
|
||||
|
||||
Vmenu *Vmenu::_addr = NULL;
|
||||
int Vmenu::_recent = -1;
|
||||
|
||||
Vmenu::Vmenu(CGEEngine *vm, Choice *list, int x, int y)
|
||||
: Talk(vm, VMGather(list), kTBRect), _menu(list), _bar(NULL), _vm(vm) {
|
||||
Choice *cp;
|
||||
|
||||
_addr = this;
|
||||
delete[] _vmgt;
|
||||
_items = 0;
|
||||
for (cp = list; cp->_text; cp++)
|
||||
_items++;
|
||||
_flags._bDel = true;
|
||||
_flags._kill = true;
|
||||
if (x < 0 || y < 0)
|
||||
center();
|
||||
else
|
||||
gotoxy(x - _w / 2, y - (kTextVMargin + kFontHigh / 2));
|
||||
_vga->_showQ->insert(this, _vga->_showQ->last());
|
||||
_bar = new MenuBar(_vm, _w - 2 * kTextHMargin);
|
||||
_bar->gotoxy(_x + kTextHMargin - kMenuBarHM, _y + kTextVMargin - kMenuBarVM);
|
||||
_vga->_showQ->insert(_bar, _vga->_showQ->last());
|
||||
}
|
||||
|
||||
Vmenu::~Vmenu() {
|
||||
_addr = NULL;
|
||||
}
|
||||
|
||||
#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
|
||||
|
||||
void Vmenu::touch(uint16 mask, int x, int y) {
|
||||
if (!_items)
|
||||
return;
|
||||
|
||||
Sprite::touch(mask, x, y);
|
||||
|
||||
y -= kTextVMargin - 1;
|
||||
int n = 0;
|
||||
bool ok = false;
|
||||
uint16 h = kFontHigh + kTextLineSpace;
|
||||
|
||||
if (y >= 0) {
|
||||
n = y / h;
|
||||
if (n < _items)
|
||||
ok = (x >= kTextHMargin && x < _w - kTextHMargin/* && y % h < FONT_HIG*/);
|
||||
else
|
||||
n = _items - 1;
|
||||
}
|
||||
|
||||
_bar->gotoxy(_x + kTextHMargin - kMenuBarHM, _y + kTextVMargin + n * h - kMenuBarVM);
|
||||
|
||||
if (ok && (mask & kMouseLeftUp)) {
|
||||
_items = 0;
|
||||
_snail_->addCom(kSnKill, -1, 0, this);
|
||||
_recent = n;
|
||||
assert(_menu[n].Proc);
|
||||
CALL_MEMBER_FN(*_vm, _menu[n].Proc)();
|
||||
}
|
||||
}
|
||||
|
||||
char *Vmenu::VMGather(Choice *list) {
|
||||
Choice *cp;
|
||||
int len = 0, h = 0;
|
||||
|
||||
for (cp = list; cp->_text; cp++) {
|
||||
len += strlen(cp->_text);
|
||||
h++;
|
||||
}
|
||||
_vmgt = new char[len + h];
|
||||
if (_vmgt) {
|
||||
*_vmgt = '\0';
|
||||
for (cp = list; cp->_text; cp++) {
|
||||
if (*_vmgt)
|
||||
strcat(_vmgt, "|");
|
||||
strcat(_vmgt, cp->_text);
|
||||
h++;
|
||||
}
|
||||
}
|
||||
return _vmgt;
|
||||
}
|
||||
} // End of namespace CGE
|
74
engines/cge/vmenu.h
Normal file
74
engines/cge/vmenu.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_VMENU_H
|
||||
#define CGE_VMENU_H
|
||||
|
||||
#include "cge/talk.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
#define kMenuBarVM 1
|
||||
#define kMenuBarHM 3
|
||||
#define kMenuBarLT kVgaColLightGray
|
||||
#define kMenuBarRB kVgaColDarkGray
|
||||
|
||||
|
||||
struct Choice {
|
||||
const char *_text;
|
||||
void (CGEEngine::*Proc)();
|
||||
};
|
||||
|
||||
|
||||
class MenuBar : public Talk {
|
||||
public:
|
||||
MenuBar(CGEEngine *vm, uint16 w);
|
||||
private:
|
||||
CGEEngine *_vm;
|
||||
};
|
||||
|
||||
|
||||
class Vmenu : public Talk {
|
||||
public:
|
||||
static Vmenu *_addr;
|
||||
static int _recent;
|
||||
MenuBar *_bar;
|
||||
Vmenu(CGEEngine *vm, Choice *list, int x, int y);
|
||||
~Vmenu();
|
||||
virtual void touch(uint16 mask, int x, int y);
|
||||
private:
|
||||
char *_vmgt;
|
||||
CGEEngine *_vm;
|
||||
uint16 _items;
|
||||
Choice *_menu;
|
||||
|
||||
char *VMGather(Choice *list);
|
||||
};
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
269
engines/cge/walk.cpp
Normal file
269
engines/cge/walk.cpp
Normal file
|
@ -0,0 +1,269 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#include "cge/walk.h"
|
||||
#include "cge/cge_main.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
Walk *_hero;
|
||||
|
||||
uint8 Cluster::_map[kMapZCnt][kMapXCnt];
|
||||
CGEEngine *Cluster::_vm;
|
||||
|
||||
void Cluster::init(CGEEngine *vm) {
|
||||
_vm = vm;
|
||||
}
|
||||
|
||||
uint8 &Cluster::cell() {
|
||||
return _map[_pt.y][_pt.x];
|
||||
}
|
||||
|
||||
bool Cluster::isValid() const {
|
||||
return (_pt.x >= 0) && (_pt.x < kMapXCnt) && (_pt.y >= 0) && (_pt.y < kMapZCnt);
|
||||
}
|
||||
|
||||
Cluster XZ(int16 x, int16 y) {
|
||||
if (y < kMapTop)
|
||||
y = kMapTop;
|
||||
|
||||
if (y > kMapTop + kMapHig - kMapGridZ)
|
||||
y = kMapTop + kMapHig - kMapGridZ;
|
||||
|
||||
return Cluster(x / kMapGridX, (y - kMapTop) / kMapGridZ);
|
||||
}
|
||||
|
||||
Walk::Walk(CGEEngine *vm, BitmapPtr *shpl)
|
||||
: Sprite(vm, shpl), _dir(kDirNone), _tracePtr(-1), _level(0), _target(-1, -1), _findLevel(-1), _vm(vm) {
|
||||
}
|
||||
|
||||
void Walk::tick() {
|
||||
if (_flags._hide)
|
||||
return;
|
||||
|
||||
_here = XZ(_x + _w / 2, _y + _h);
|
||||
|
||||
if (_dir != kDirNone) {
|
||||
_sys->funTouch();
|
||||
for (Sprite *spr = _vga->_showQ->first(); spr; spr = spr->_next) {
|
||||
if (distance(spr) < 2) {
|
||||
if (!spr->_flags._near) {
|
||||
_vm->feedSnail(spr, kNear);
|
||||
spr->_flags._near = true;
|
||||
}
|
||||
} else {
|
||||
spr->_flags._near = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_flags._hold || _tracePtr < 0) {
|
||||
park();
|
||||
} else {
|
||||
if (_here._pt == _trace[_tracePtr]._pt) {
|
||||
if (--_tracePtr < 0)
|
||||
park();
|
||||
} else {
|
||||
Common::Point tmpPoint = _trace[_tracePtr]._pt - _here._pt;
|
||||
int16 dx = tmpPoint.x;
|
||||
int16 dz = tmpPoint.y;
|
||||
Dir d = (dx) ? ((dx > 0) ? kDirEast : kDirWest) : ((dz > 0) ? kDirSouth : kDirNorth);
|
||||
turn(d);
|
||||
}
|
||||
}
|
||||
|
||||
step();
|
||||
|
||||
if ((_dir == kDirWest && _x <= 0) ||
|
||||
(_dir == kDirEast && _x + _w >= kScrWidth) ||
|
||||
(_dir == kDirSouth && _y + _w >= kWorldHeight - 2)) {
|
||||
park();
|
||||
} else {
|
||||
// take current Z position
|
||||
_z = _here._pt.y;
|
||||
_snail_->addCom(kSnZTrim, -1, 0, this); // update Hero's pos in show queue
|
||||
}
|
||||
}
|
||||
|
||||
int Walk::distance(Sprite *spr) {
|
||||
int dx = spr->_x - (_x + _w - kWalkSide);
|
||||
if (dx < 0)
|
||||
dx = (_x + kWalkSide) - (spr->_x + spr->_w);
|
||||
|
||||
if (dx < 0)
|
||||
dx = 0;
|
||||
|
||||
dx /= kMapGridX;
|
||||
int dz = spr->_z - _z;
|
||||
if (dz < 0)
|
||||
dz = - dz;
|
||||
|
||||
dx = dx * dx + dz * dz;
|
||||
for (dz = 1; dz * dz < dx; dz++)
|
||||
;
|
||||
|
||||
return dz - 1;
|
||||
}
|
||||
|
||||
void Walk::turn(Dir d) {
|
||||
Dir dir = (_dir == kDirNone) ? kDirSouth : _dir;
|
||||
if (d != _dir) {
|
||||
step((d == dir) ? (1 + dir + dir) : (9 + 4 * dir + d));
|
||||
_dir = d;
|
||||
}
|
||||
}
|
||||
|
||||
void Walk::park() {
|
||||
if (_time == 0)
|
||||
_time++;
|
||||
|
||||
if (_dir != kDirNone) {
|
||||
step(9 + 4 * _dir + _dir);
|
||||
_dir = kDirNone;
|
||||
_tracePtr = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void Walk::findWay(Cluster c) {
|
||||
if (c._pt == _here._pt)
|
||||
return;
|
||||
|
||||
for (_findLevel = 1; _findLevel <= kMaxFindLevel; _findLevel++) {
|
||||
_target = _here._pt;
|
||||
int16 x = c._pt.x;
|
||||
int16 z = c._pt.y;
|
||||
|
||||
if (find1Way(Cluster(x, z)))
|
||||
break;
|
||||
}
|
||||
|
||||
_tracePtr = (_findLevel > kMaxFindLevel) ? -1 : (_findLevel - 1);
|
||||
if (_tracePtr < 0)
|
||||
noWay();
|
||||
_time = 1;
|
||||
}
|
||||
|
||||
void Walk::findWay(Sprite *spr) {
|
||||
if (!spr || spr == this)
|
||||
return;
|
||||
|
||||
int x = spr->_x;
|
||||
int z = spr->_z;
|
||||
if (spr->_flags._east)
|
||||
x += spr->_w + _w / 2 - kWalkSide;
|
||||
else
|
||||
x -= _w / 2 - kWalkSide;
|
||||
|
||||
findWay(Cluster((x / kMapGridX),
|
||||
((z < kMapZCnt - kDistMax) ? (z + 1)
|
||||
: (z - 1))));
|
||||
}
|
||||
|
||||
bool Walk::lower(Sprite *spr) {
|
||||
return (spr->_y > _y + (_h * 3) / 5);
|
||||
}
|
||||
|
||||
void Walk::reach(Sprite *spr, int mode) {
|
||||
if (spr) {
|
||||
_hero->findWay(spr);
|
||||
if (mode < 0) {
|
||||
mode = spr->_flags._east;
|
||||
if (lower(spr))
|
||||
mode += 2;
|
||||
}
|
||||
}
|
||||
// note: insert SNAIL commands in reverse order
|
||||
_snail->insCom(kSnPause, -1, 64, NULL);
|
||||
_snail->insCom(kSnSeq, -1, kTSeq + mode, this);
|
||||
if (spr) {
|
||||
_snail->insCom(kSnWait, -1, -1, _hero);
|
||||
//SNINSERT(SNWALK, -1, -1, spr);
|
||||
}
|
||||
// sequence is not finished,
|
||||
// now it is just at sprite appear (disappear) point
|
||||
}
|
||||
|
||||
void Walk::noWay() {
|
||||
_vm->trouble(kSeqNoWay, kNoWay);
|
||||
}
|
||||
|
||||
bool Cluster::chkBar() const {
|
||||
assert(_vm->_now <= kCaveMax);
|
||||
return (_pt.x == _vm->_barriers[_vm->_now]._horz) || (_pt.y == _vm->_barriers[_vm->_now]._vert);
|
||||
}
|
||||
|
||||
bool Walk::find1Way(Cluster c) {
|
||||
const Cluster tab[4] = { Cluster(-1, 0), Cluster(1, 0), Cluster(0, -1), Cluster(0, 1)};
|
||||
const int tabLen = 4;
|
||||
|
||||
if (c._pt == _target)
|
||||
// Found destination
|
||||
return true;
|
||||
|
||||
if (_level >= _findLevel)
|
||||
// Nesting limit
|
||||
return false;
|
||||
|
||||
// Look for barriers
|
||||
if (c.chkBar())
|
||||
return false;
|
||||
|
||||
if (c.cell())
|
||||
// Location is occupied
|
||||
return false;
|
||||
|
||||
// Loop through each direction
|
||||
Cluster start = c;
|
||||
for (int i = 0; i < tabLen; i++) {
|
||||
// Reset to starting position
|
||||
c = start;
|
||||
|
||||
do {
|
||||
c._pt += tab[i]._pt;
|
||||
if (!c.isValid())
|
||||
// Break to check next direction
|
||||
break;
|
||||
|
||||
// Recursively check for further paths
|
||||
++_level;
|
||||
++start.cell();
|
||||
bool foundPath = find1Way(c);
|
||||
--start.cell();
|
||||
--_level;
|
||||
|
||||
if (foundPath) {
|
||||
// Set route point
|
||||
_trace[_level] = start;
|
||||
return true;
|
||||
}
|
||||
} while (!c.chkBar() && !c.cell());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace CGE
|
95
engines/cge/walk.h
Normal file
95
engines/cge/walk.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on original Soltys source code
|
||||
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||
*/
|
||||
|
||||
#ifndef CGE_WALK_H
|
||||
#define CGE_WALK_H
|
||||
|
||||
#include "common/rect.h"
|
||||
#include "cge/vga13h.h"
|
||||
#include "cge/events.h"
|
||||
|
||||
namespace CGE {
|
||||
|
||||
#define kMapXCnt 40
|
||||
#define kMapZCnt 20
|
||||
#define kMapArrSize (kMapZCnt * kMapXCnt)
|
||||
#define kMapTop 80
|
||||
#define kMapHig 80
|
||||
#define kMapGridX (kScrWidth / kMapXCnt)
|
||||
#define kMapGridZ (kMapHig / kMapZCnt)
|
||||
#define kMaxFindLevel 3
|
||||
|
||||
enum Dir { kDirNone = -1, kDirNorth, kDirEast, kDirSouth, kDirWest };
|
||||
|
||||
class Cluster {
|
||||
public:
|
||||
static uint8 _map[kMapZCnt][kMapXCnt];
|
||||
static CGEEngine *_vm;
|
||||
Common::Point _pt;
|
||||
|
||||
static void init(CGEEngine *vm);
|
||||
public:
|
||||
uint8 &cell();
|
||||
Cluster(int16 a, int16 b) { _pt = Common::Point(a, b); }
|
||||
Cluster() { _pt = Common::Point(-1, -1); }
|
||||
bool chkBar() const;
|
||||
bool isValid() const;
|
||||
};
|
||||
|
||||
class Walk : public Sprite {
|
||||
private:
|
||||
CGEEngine *_vm;
|
||||
public:
|
||||
Cluster _here;
|
||||
int _tracePtr;
|
||||
int _level;
|
||||
int _findLevel;
|
||||
Common::Point _target;
|
||||
Cluster _trace[kMaxFindLevel];
|
||||
|
||||
Dir _dir;
|
||||
Walk(CGEEngine *vm, BitmapPtr *shpl);
|
||||
void tick();
|
||||
void findWay(Cluster c);
|
||||
void findWay(Sprite *spr);
|
||||
int distance(Sprite *spr);
|
||||
void turn(Dir d);
|
||||
void park();
|
||||
bool lower(Sprite *spr);
|
||||
void reach(Sprite *spr, int mode = -1);
|
||||
|
||||
void noWay();
|
||||
bool find1Way(Cluster c);
|
||||
};
|
||||
|
||||
Cluster XZ(int16 x, int16 y);
|
||||
|
||||
extern Walk *_hero;
|
||||
|
||||
} // End of namespace CGE
|
||||
|
||||
#endif
|
|
@ -26,6 +26,11 @@ DEFINES += -DENABLE_AGOS2
|
|||
endif
|
||||
endif
|
||||
|
||||
ifdef ENABLE_CGE
|
||||
DEFINES += -DENABLE_CGE=$(ENABLE_CGE)
|
||||
MODULES += engines/cge
|
||||
endif
|
||||
|
||||
ifdef ENABLE_CINE
|
||||
DEFINES += -DENABLE_CINE=$(ENABLE_CINE)
|
||||
MODULES += engines/cine
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue