mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-21 19:51:49 +00:00
CGE2: Implement FXP code. Still WIP, loadTab to be fixed
This commit is contained in:
parent
45f8bd755c
commit
207f3c8be2
@ -43,6 +43,7 @@ class Fx;
|
||||
class Sound;
|
||||
class Text;
|
||||
struct HeroTab;
|
||||
class FXP;
|
||||
class V3D;
|
||||
class V2D;
|
||||
struct Dac;
|
||||
|
@ -702,34 +702,23 @@ void CGE2Engine::loadTab() {
|
||||
for (int i = 0; i < kCaveMax; i++)
|
||||
*(_eyeTab[i]) = *_eye;
|
||||
|
||||
/*
|
||||
if (_resman->exist(kTabName)) {
|
||||
if (_resman->exist(kTabName)) {
|
||||
EncryptedStream f(this, kTabName);
|
||||
for (int i = 0; i < kCaveMax; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
signed b = f.readSint16BE();
|
||||
unsigned a = f.readUint16BE();
|
||||
uint16 round = uint16((long(a) << 16) / 100);
|
||||
|
||||
if (round > 0x7FFF)
|
||||
b++;
|
||||
|
||||
switch (j) {
|
||||
case 0:
|
||||
_eyeTab[i]->_x = b;
|
||||
break;
|
||||
case 1:
|
||||
_eyeTab[i]->_y = b;
|
||||
break;
|
||||
case 2:
|
||||
_eyeTab[i]->_z = b;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
int16 varI = f.readSint16LE();
|
||||
int16 varF = f.readUint16LE();
|
||||
_eyeTab[i]->_x = FXP(varI, varF);
|
||||
|
||||
varI = f.readSint16LE();
|
||||
varF = f.readUint16LE();
|
||||
_eyeTab[i]->_y = FXP(varI, varF);
|
||||
|
||||
varI = f.readSint16LE();
|
||||
varF = f.readUint16LE();
|
||||
_eyeTab[i]->_z = FXP(varI, varF);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
warning("STUB: CGE2Engine::loadTab()");
|
||||
}
|
||||
|
||||
|
@ -228,6 +228,10 @@ signed EncryptedStream::readSint16LE() {
|
||||
return _readStream->readSint16LE();
|
||||
}
|
||||
|
||||
signed EncryptedStream::readUint16LE() {
|
||||
return _readStream->readUint16LE();
|
||||
}
|
||||
|
||||
bool EncryptedStream::err() {
|
||||
return (_error & _readStream->err());
|
||||
}
|
||||
|
@ -125,6 +125,7 @@ public:
|
||||
unsigned readUint16BE();
|
||||
signed readSint16BE();
|
||||
signed readSint16LE();
|
||||
signed readUint16LE();
|
||||
Common::String readLine();
|
||||
int getLineCount() { return _lineCount; }
|
||||
|
||||
|
@ -205,8 +205,9 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
|
||||
}
|
||||
|
||||
void Hero::setCurrent() {
|
||||
double m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
|
||||
int h = -(V2D::trunc(m * _siz.y));
|
||||
FXP m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
|
||||
FXP tmp = m * _siz.y;
|
||||
int h = -(tmp.trunc());
|
||||
|
||||
int i = 0;
|
||||
for (; i < kDimMax; i++) {
|
||||
@ -243,15 +244,15 @@ void Hero::tick() {
|
||||
|
||||
int Hero::distance(V3D pos) {
|
||||
V3D di = _pos3D - pos;
|
||||
long x = V2D::round(di._x);
|
||||
long z = V2D::round(di._z);
|
||||
return (int)sqrt((long double)(x * x + z * z));
|
||||
int x = di._x.round();
|
||||
int z = di._z.round();
|
||||
return ((int)sqrt((long double)x * x + z * z));
|
||||
}
|
||||
|
||||
int Hero::distance(Sprite *spr) {
|
||||
V3D pos = spr->_pos3D;
|
||||
int mdx = (spr->_siz.x >> 1) + (_siz.x >> 1);
|
||||
int dx = V2D::round(_pos3D._x - spr->_pos3D._x);
|
||||
int dx = (_pos3D._x - spr->_pos3D._x).round();
|
||||
if (dx < 0) {
|
||||
mdx = -mdx;
|
||||
if (dx > mdx)
|
||||
@ -303,8 +304,8 @@ int Hero::len(V2D v) {
|
||||
}
|
||||
|
||||
bool Hero::findWay(){
|
||||
V2D p0(_vm, V2D::round(_pos3D._x), V2D::round(_pos3D._z));
|
||||
V2D p1(_vm, V2D::round(_trace[_tracePtr]._x), V2D::round(_trace[_tracePtr]._z));
|
||||
V2D p0(_vm, _pos3D._x.round(), _pos3D._z.round());
|
||||
V2D p1(_vm, _trace[_tracePtr]._x.round(), _trace[_tracePtr]._z.round());
|
||||
bool pvOk;
|
||||
bool phOk;
|
||||
V2D ph(_vm, p1.x, p0.y);
|
||||
@ -340,12 +341,12 @@ void Hero::walkTo(V3D pos) {
|
||||
if (distance(pos) <= _maxDist)
|
||||
return;
|
||||
int stp = stepSize();
|
||||
pos._x = snap(V2D::round(_pos3D._x), V2D::round(pos._x), stp);
|
||||
pos._x = snap(_pos3D._x.round(), pos._x.round(), stp);
|
||||
pos._y = 0;
|
||||
pos._z = snap(V2D::round(_pos3D._z), V2D::round(pos._z), stp);
|
||||
pos._z = snap(_pos3D._z.round(), pos._z.round(), stp);
|
||||
|
||||
V2D p0(_vm, V2D::round(_pos3D._x), V2D::round(_pos3D._z));
|
||||
V2D p1(_vm, V2D::round(pos._x), V2D::round(pos._z));
|
||||
V2D p0(_vm, _pos3D._x.round(), _pos3D._z.round());
|
||||
V2D p1(_vm, pos._x.round(), pos._z.round());
|
||||
resetFun();
|
||||
int cnt = mapCross(p0, p1);
|
||||
if ((cnt & 1) == 0) { // even == way exists
|
||||
@ -385,15 +386,15 @@ void Hero::walkTo(Sprite *spr) {
|
||||
}
|
||||
|
||||
V3D Hero::screenToGround(V2D pos) {
|
||||
double z = _vm->_eye->_z + (_vm->_eye->_y * _vm->_eye->_z) / (double(pos.y) - _vm->_eye->_y);
|
||||
double x = _vm->_eye->_x - ((double(pos.x) - _vm->_eye->_x) * (z - _vm->_eye->_z)) / _vm->_eye->_z;
|
||||
return V3D(V2D::round(x), 0, V2D::round(z));
|
||||
FXP z = _vm->_eye->_z + (_vm->_eye->_y * _vm->_eye->_z) / (FXP(pos.y) - _vm->_eye->_y);
|
||||
FXP x = _vm->_eye->_x - ((FXP(pos.x) - _vm->_eye->_x) * (z - _vm->_eye->_z)) / _vm->_eye->_z;
|
||||
return V3D(x.round(), 0, z.round());
|
||||
}
|
||||
|
||||
int Hero::cross(const V2D &a, const V2D &b) {
|
||||
int x = V2D::trunc(_pos3D._x);
|
||||
int z = V2D::trunc(_pos3D._z);
|
||||
int r = ((_siz.x / 3) * V2D::trunc(_vm->_eye->_z)) / (V2D::trunc(_vm->_eye->_z) - z);
|
||||
int x = _pos3D._x.trunc();
|
||||
int z = _pos3D._z.trunc();
|
||||
int r = ((_siz.x / 3) * _vm->_eye->_z.trunc()) / (_vm->_eye->_z.trunc()- z);
|
||||
return _vm->cross(a, b, V2D(_vm, x - r, z), V2D(_vm, x + r, z)) << 1;
|
||||
}
|
||||
|
||||
@ -433,7 +434,7 @@ int Hero::mapCross(const V2D &a, const V2D &b) {
|
||||
}
|
||||
|
||||
int Hero::mapCross(const V3D &a, const V3D &b) {
|
||||
return mapCross(V2D(_vm, V2D::round(a._x), V2D::round(a._z)), V2D(_vm, V2D::round(b._x), V2D::round(b._z)));
|
||||
return mapCross(V2D(_vm, a._x.round(), a._z.round()), V2D(_vm, b._x.round(), b._z.round()));
|
||||
}
|
||||
|
||||
int CGE2Engine::mapCross(const V2D &a, const V2D &b) {
|
||||
|
@ -145,7 +145,7 @@ void Text::say(const char *text, Sprite *spr) {
|
||||
if (!east)
|
||||
d.x = -d.x;
|
||||
if (_vm->isHero(spr))
|
||||
d = d.scale(V2D::trunc(spr->_pos3D._z));
|
||||
d = d.scale(spr->_pos3D._z.trunc());
|
||||
V2D pos = spr->_pos2D + d;
|
||||
uint16 sw = (speaker->_siz.x >> 1);
|
||||
if (!east)
|
||||
@ -168,7 +168,7 @@ void Text::say(const char *text, Sprite *spr) {
|
||||
_vm->_talk->setName(getText(kSayName));
|
||||
_vm->_talk->gotoxyz(pos.x, pos.y + speaker->_siz.y - 1, 0);
|
||||
|
||||
speaker->gotoxyz(pos.x, V2D::trunc(_vm->_talk->_pos3D._y) - speaker->_siz.y + 1, 0);
|
||||
speaker->gotoxyz(pos.x, _vm->_talk->_pos3D._y.trunc() - speaker->_siz.y + 1, 0);
|
||||
speaker->_flags._slav = true;
|
||||
speaker->_flags._kill = true;
|
||||
speaker->setName(getText(kSayName));
|
||||
|
@ -531,9 +531,9 @@ void Sprite::gotoxyz(V2D pos) {
|
||||
byte trim = 0;
|
||||
|
||||
if (_ref / 10 == 14) { // HERO
|
||||
int z = V2D::trunc(_pos3D._z);
|
||||
ctr = (ctr * V2D::trunc(_vm->_eye->_z) / (V2D::trunc(_vm->_eye->_z) - z));
|
||||
rem = (rem * V2D::trunc(_vm->_eye->_z) / (V2D::trunc(_vm->_eye->_z) - z));
|
||||
int z = _pos3D._z.trunc();
|
||||
ctr = (ctr * _vm->_eye->_z.trunc()) / (_vm->_eye->_z.trunc() - z);
|
||||
rem = (rem * _vm->_eye->_z.trunc()) / (_vm->_eye->_z.trunc() - z);
|
||||
ctr = (ctr * 3) / 4;
|
||||
rem = (rem * 3) / 4;
|
||||
}
|
||||
@ -561,10 +561,15 @@ void Sprite::gotoxyz(V2D pos) {
|
||||
_flags._trim = (trim != 0);
|
||||
|
||||
if (!_follow) {
|
||||
double m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
|
||||
_pos3D._x = V2D::round(_vm->_eye->_x + (_vm->_eye->_x - _pos2D.x) / m);
|
||||
if (!_constY)
|
||||
_pos3D._y = V2D::round(_vm->_eye->_y + (_vm->_eye->_y - _pos2D.y) / m);
|
||||
// CHECKME: Original was using Pos2d.Eye, which shouldn't make a difference (static var)
|
||||
FXP m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
|
||||
_pos3D._x = (_vm->_eye->_x + (_vm->_eye->_x - _pos2D.x) / m);
|
||||
_pos3D._x.round();
|
||||
|
||||
if (!_constY) {
|
||||
_pos3D._y = _vm->_eye->_y + (_vm->_eye->_y - _pos2D.y) / m;
|
||||
_pos3D._y.round();
|
||||
}
|
||||
}
|
||||
|
||||
if (_next && _next->_flags._slav)
|
||||
@ -685,9 +690,23 @@ void Sprite::sync(Common::Serializer &s) {
|
||||
s.syncAsUint16LE(flags);
|
||||
}
|
||||
|
||||
s.syncAsUint16LE(_pos3D._x);
|
||||
s.syncAsUint16LE(_pos3D._y);
|
||||
s.syncAsByte(_pos3D._z);
|
||||
int pos = 0;
|
||||
if (s.isLoading()) {
|
||||
s.syncAsSint16LE(pos);
|
||||
_pos3D._x = FXP(pos, 0);
|
||||
s.syncAsSint16LE(pos);
|
||||
_pos3D._y = pos;
|
||||
s.syncAsSint16LE(pos);
|
||||
_pos3D._z = pos;
|
||||
} else {
|
||||
pos = _pos3D._x.trunc();
|
||||
s.syncAsUint16LE(pos);
|
||||
pos = _pos3D._y.trunc();
|
||||
s.syncAsUint16LE(pos);
|
||||
pos = _pos3D._z.trunc();
|
||||
s.syncAsByte(pos);
|
||||
}
|
||||
|
||||
s.syncAsUint16LE(_time);
|
||||
s.syncAsSint16LE(_seqPtr);
|
||||
s.syncAsUint16LE(_shpCnt);
|
||||
|
@ -51,19 +51,74 @@ namespace CGE2 {
|
||||
#define kPalCount 256
|
||||
#define kPalSize (kPalCount * 3)
|
||||
|
||||
// From FXP.H
|
||||
class FXP // fixed point
|
||||
{
|
||||
uint16 f;
|
||||
int16 i;
|
||||
long& Joined (void) const { return *(long *)&f; }
|
||||
public:
|
||||
FXP (void) { }
|
||||
FXP (int i0, int f0 = 0) : i(i0), f((int) ((((long) f0) << 16)/100)) { }
|
||||
FXP& operator = (const int& x) { i = x; f = 0; return *this; }
|
||||
FXP operator + (const FXP& x) const { FXP y; y.Joined() = Joined()+x.Joined(); return y; }
|
||||
FXP operator - (const FXP& x) const { FXP y; y.Joined() = Joined()-x.Joined(); return y; }
|
||||
FXP operator * (const FXP& x) const {
|
||||
FXP y; long t;
|
||||
y.i = i * x.i;
|
||||
t = ((long) f * x.f) >> 16;
|
||||
t += ((long) i * x.f) + ((long) f * x.i);
|
||||
y.f = t & 0xFFFF;
|
||||
y.i += t >> 16;
|
||||
return y;
|
||||
}
|
||||
FXP operator / (const FXP& x) const {
|
||||
FXP y; bool sign = false;
|
||||
long j = Joined(), jx = x.Joined();
|
||||
if (j < 0) {
|
||||
j = -j;
|
||||
sign ^= 1;
|
||||
}
|
||||
if (jx < 0) {
|
||||
jx = -jx;
|
||||
sign ^= 1;
|
||||
}
|
||||
y.i = signed(j / jx);
|
||||
long r = j - jx * y.i;
|
||||
//-- binary division
|
||||
y.f = unsigned((r << 4) / (jx >> 12));
|
||||
//------------------
|
||||
if (sign)
|
||||
y.Joined() = -y.Joined();
|
||||
|
||||
return y;
|
||||
}
|
||||
//int& operator = (int& a, const FXP& b) { return a = b.i; }
|
||||
friend int& operator += (int& a, const FXP& b) { return a += b.i; }
|
||||
friend int& operator -= (int& a, const FXP& b) { return a -= b.i; }
|
||||
friend FXP& operator += (FXP& a, const int& b) { a.i += b; return a; }
|
||||
friend FXP& operator -= (FXP& a, const int& b) { a.i -= b; return a; }
|
||||
friend bool operator == (const FXP &a, const FXP &b) { return (a.i == b.i) && (a.f == b.f); }
|
||||
friend bool operator != (const FXP &a, const FXP &b) { return (a.i != b.i) || (a.f != b.f); }
|
||||
friend bool operator < (const FXP &a, const FXP &b) { return (a.i < b.i) || ((a.i == b.i) && (a.f < b.f)); }
|
||||
friend bool operator > (const FXP &a, const FXP &b) { return (a.i > b.i) || ((a.i == b.i) && (a.f > b.f)); }
|
||||
int trunc(void) const { return i; }
|
||||
int round(void) const { return i + (f > 0x7FFF); }
|
||||
};
|
||||
|
||||
// From CGETYPE.H:
|
||||
class V3D {
|
||||
public:
|
||||
double _x, _y, _z;
|
||||
FXP _x, _y, _z;
|
||||
V3D() { }
|
||||
V3D(double x, double y, double z = 0) : _x(x), _y(y), _z(z) { }
|
||||
V3D(FXP x, FXP y, FXP z = 0) : _x(x), _y(y), _z(z) { }
|
||||
V3D(const V3D &p) : _x(p._x), _y(p._y), _z(p._z) { }
|
||||
V3D operator+(const V3D &p) const { return V3D(_x + p._x, _y + p._y, _z + p._z); }
|
||||
V3D operator-(const V3D &p) const { return V3D(_x - p._x, _y - p._y, _z - p._z); }
|
||||
V3D operator*(long n) const { return V3D(_x * n, _y * n, _z * n); }
|
||||
V3D operator/ (long n) const { return V3D(_x / n, _y / n, _z / n); }
|
||||
bool operator==(V3D &p) const { return _x == p._x && _y == p._y && _z == p._z; }
|
||||
bool operator!=(V3D &p) const { return _x != p._x || _y != p._y || _z != p._z; }
|
||||
bool operator==(const V3D &p) const { return _x == p._x && _y == p._y && _z == p._z; }
|
||||
bool operator!=(const V3D &p) const { return _x != p._x || _y != p._y || _z != p._z; }
|
||||
V3D& operator+=(const V3D &x) { return *this = *this + x; }
|
||||
V3D& operator-=(const V3D &x) { return *this = *this - x; }
|
||||
};
|
||||
@ -72,11 +127,11 @@ class V2D : public Common::Point {
|
||||
CGE2Engine *_vm;
|
||||
public:
|
||||
V2D& operator=(const V3D &p3) {
|
||||
if (p3._z == 200)
|
||||
warning("");
|
||||
double m = _vm->_eye->_z / (p3._z - _vm->_eye->_z);
|
||||
x = round(_vm->_eye->_x + (_vm->_eye->_x - p3._x) * m);
|
||||
y = round(_vm->_eye->_y + (_vm->_eye->_y - p3._y) * m);
|
||||
FXP m = _vm->_eye->_z / (p3._z - _vm->_eye->_z);
|
||||
FXP posx = _vm->_eye->_x + (_vm->_eye->_x - p3._x) * m;
|
||||
x = posx.round();
|
||||
FXP posy = _vm->_eye->_y + (_vm->_eye->_y - p3._y) * m;
|
||||
y = posy.round();
|
||||
return *this;
|
||||
}
|
||||
V2D(CGE2Engine *vm) : _vm(vm) { }
|
||||
@ -88,14 +143,17 @@ public:
|
||||
bool operator>=(const V2D &p) const { return (x >= p.x) && (y >= p.y); }
|
||||
V2D operator+(const V2D &p) const { return V2D(_vm, x + p.x, y + p.y); }
|
||||
V2D operator-(const V2D &p) const { return V2D(_vm, x - p.x, y - p.y); }
|
||||
bool operator==(const V3D &p) const { V3D tmp(x, y); return tmp._x == p._x && tmp._y == p._y && tmp._z == p._z; }
|
||||
bool operator!=(const V3D &p) const { V3D tmp(x, y); return tmp._x != p._x || tmp._y != p._y || tmp._z == p._z; }
|
||||
uint16 area() { return x * y; }
|
||||
bool limited(const V2D &p) {
|
||||
return (uint16(x) < uint16(p.x)) && (uint16(y) < uint16(p.y));
|
||||
return ((x < p.x) && (y < p.y));
|
||||
}
|
||||
V2D scale(int z) {
|
||||
double m = _vm->_eye->_z / (_vm->_eye->_z - z);
|
||||
warning("scale: %f %f %f, x, y, m");
|
||||
return V2D(_vm, trunc(m * x), trunc(m * y));
|
||||
V2D scale (int z) {
|
||||
FXP m = _vm->_eye->_z / (_vm->_eye->_z - z);
|
||||
FXP posx = m * x;
|
||||
FXP posy = m * y;
|
||||
return V2D(_vm, posx.trunc(), posy.trunc());
|
||||
}
|
||||
static double trunc(double d) { return (d > 0) ? floor(d) : ceil(d); }
|
||||
static double round(double number) { return number < 0.0 ? ceil(number) : floor(number); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user