diff options
Diffstat (limited to 'engines/titanic/star_control/star_control_sub5.cpp')
-rw-r--r-- | engines/titanic/star_control/star_control_sub5.cpp | 480 |
1 files changed, 386 insertions, 94 deletions
diff --git a/engines/titanic/star_control/star_control_sub5.cpp b/engines/titanic/star_control/star_control_sub5.cpp index 5023a59383..8c332975c6 100644 --- a/engines/titanic/star_control/star_control_sub5.cpp +++ b/engines/titanic/star_control/star_control_sub5.cpp @@ -26,6 +26,8 @@ namespace Titanic { +#define MKTAG_BE(a3,a2,a1,a0) ((uint32)((a3) | ((a2) << 8) | ((a1) << 16) | ((a0) << 24))) + void CStarControlSub5::SubEntry::clear() { _data1.clear(); _data2.clear(); @@ -37,7 +39,7 @@ bool CStarControlSub5::SineTable::setup() { if (_data.empty()) { _data.resize(1024); for (int idx = 0; idx < 1024; ++idx) - _data[idx] = sin((double)idx * 6.283185307179586 * 0.001953125); + _data[idx] = sin((double)idx * 2 * M_PI / 512.0); } return true; @@ -63,7 +65,7 @@ bool CStarControlSub5::setup() { bool CStarControlSub5::setup2(int val1, int val2) { // TODO: Original set an explicit random seed here. Could be // problematic if following random values need to be deterministic - const double FACTOR = 3.1415927 * 0.0055555557; + const double FACTOR = 2 * M_PI / 360.0; const int VALUES1[] = { 0x800, 0xC00, 0x1000, 0x1400, 0x1800 }; const int VALUES2[] = { 0xF95BCD, 0xA505A0, 0xFFAD43, 0x98F4EB, 0xF3EFA5, 0, @@ -76,9 +78,9 @@ bool CStarControlSub5::setup2(int val1, int val2) { for (int idx = 0; idx < 256; ++idx) { if (idx == 0) { e->_field0 = 0x4C8; - e->_field4 = 0x40; - e->_field5 = 0x40; - e->_field6 = 0x40; + e->_pixel1 = 0x40; + e->_pixel2 = 0x40; + e->_pixel3 = 0x40; e->_field8 = g_vm->getRandomNumber(3) + 3; e->_fieldC = g_vm->getRandomNumber(255); e->_field10 = FACTOR * 7.0; @@ -86,9 +88,9 @@ bool CStarControlSub5::setup2(int val1, int val2) { ++e; e->_field0 = 0x574; - e->_field4 = 0x7f; - e->_field5 = 0; - e->_field6 = 0; + e->_pixel1 = 0x7f; + e->_pixel2 = 0; + e->_pixel3 = 0; e->_field8 = g_vm->getRandomNumber(3) + 3; e->_fieldC = g_vm->getRandomNumber(255); e->_field10 = FACTOR * 3.0; @@ -96,9 +98,9 @@ bool CStarControlSub5::setup2(int val1, int val2) { ++e; e->_field0 = 0x603; - e->_field4 = 0; - e->_field5 = 0; - e->_field6 = 0xff; + e->_pixel1 = 0; + e->_pixel2 = 0; + e->_pixel3 = 0xff; e->_field8 = g_vm->getRandomNumber(3) + 3; e->_fieldC = g_vm->getRandomNumber(255); e->_field10 = 0; @@ -106,9 +108,9 @@ bool CStarControlSub5::setup2(int val1, int val2) { ++e; e->_field0 = 0x712; - e->_field4 = 0xff; - e->_field5 = 0; - e->_field6 = 0; + e->_pixel1 = 0xff; + e->_pixel2 = 0; + e->_pixel3 = 0; e->_field8 = g_vm->getRandomNumber(3) + 3; e->_fieldC = g_vm->getRandomNumber(255); e->_field10 = FACTOR * 2.0; @@ -116,9 +118,9 @@ bool CStarControlSub5::setup2(int val1, int val2) { ++e; e->_field0 = 0xe7f; - e->_field4 = 0xe6; - e->_field5 = 0xbe; - e->_field6 = 0; + e->_pixel1 = 0xe6; + e->_pixel2 = 0xbe; + e->_pixel3 = 0; e->_field8 = g_vm->getRandomNumber(3) + 3; e->_fieldC = g_vm->getRandomNumber(255); e->_field10 = FACTOR * 1.0; @@ -126,9 +128,9 @@ bool CStarControlSub5::setup2(int val1, int val2) { ++e; e->_field0 = 0x173f; - e->_field4 = 0xf0; - e->_field5 = 0xf0; - e->_field6 = 0xe6; + e->_pixel1 = 0xf0; + e->_pixel2 = 0xf0; + e->_pixel3 = 0xe6; e->_field8 = g_vm->getRandomNumber(3) + 3; e->_fieldC = g_vm->getRandomNumber(255); e->_field10 = FACTOR * 3.0; @@ -136,9 +138,9 @@ bool CStarControlSub5::setup2(int val1, int val2) { ++e; e->_field0 = 0x2ab8; - e->_field4 = 0x28; - e->_field5 = 0x32; - e->_field6 = 0x28; + e->_pixel1 = 0x28; + e->_pixel2 = 0x32; + e->_pixel3 = 0x28; e->_field8 = g_vm->getRandomNumber(3) + 3; e->_fieldC = g_vm->getRandomNumber(255); e->_field10 = FACTOR * 1.0; @@ -146,9 +148,9 @@ bool CStarControlSub5::setup2(int val1, int val2) { ++e; e->_field0 = 0x40ac; - e->_field4 = 0x0; - e->_field5 = 0xbe; - e->_field6 = 0xf0; + e->_pixel1 = 0x0; + e->_pixel2 = 0xbe; + e->_pixel3 = 0xf0; e->_field8 = g_vm->getRandomNumber(3) + 3; e->_fieldC = g_vm->getRandomNumber(255); e->_field10 = FACTOR * 2.0; @@ -156,27 +158,27 @@ bool CStarControlSub5::setup2(int val1, int val2) { ++e; e->_field0 = 0x539c; - e->_field4 = 0x20; - e->_field5 = 0x20; - e->_field6 = 0x20; + e->_pixel1 = 0x20; + e->_pixel2 = 0x20; + e->_pixel3 = 0x20; e->_field8 = g_vm->getRandomNumber(3) + 3; e->_fieldC = g_vm->getRandomNumber(255); e->_field10 = FACTOR * 17.0; - e->_field14 = 0.00390625; + e->_field14 = 1 / 256.0; } else { for (int ctr = 0; ctr < 5; ++ctr) { e->_field0 = static_cast<int>(g_vm->getRandomFloat() * 1350.0 - 675.0) + VALUES1[idx]; int val = VALUES2[g_vm->getRandomNumber(15)]; - e->_field4 = val & 0xff; - e->_field5 = (val >> 8) & 0xff; - e->_field6 = (val >> 16) & 0xff; + e->_pixel1 = val & 0xff; + e->_pixel2 = (val >> 8) & 0xff; + e->_pixel3 = (val >> 16) & 0xff; e->_field8 = g_vm->getRandomNumber(3) + 3; e->_fieldC = g_vm->getRandomNumber(255); e->_field10 = FACTOR * (double)g_vm->getRandomNumber(15); - e->_field14 = ((double)g_vm->getRandomNumber(0xffffffff) - * 50.0 * 0.000015259022) * 0.00390625; + e->_field14 = ((double)g_vm->getRandomNumber(0xfffffffe) + * 50.0 / 65536.0) / 256.0; } } } @@ -194,13 +196,23 @@ void CStarControlSub5::proc2(CStarControlSub6 *sub6, FVector *vector, double v1, const int VALUES[] = { 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4 }; double val1 = sub12->proc25(); int val2 = sub12->proc27(); + if (!_flag) + return; + + int f1, f3, size2, size1; + double f2, f4, f5, f6, f7, f8, f9; + double f10, f11, f12, f13, f14, f15, f16, f17, f18, f19; + double f20, f21, f22, f23, f24, f25, f26, f27, f28; + double f34, f35, f36, f37, f38, f39, f40; + double f41, f42, f43, f44, f45, f46; + FVector tempV; if (v3 >= 6.0e9) { int count, start; if (vector->_x != 0.0 && (vector->_y != 0.0 || vector->_z != 0.0)) { - // TODO: Non-sensical randSeed((int)vector->_x); + // WORKAROUND: Ignoring non-sensical randSeed((int)vector->_x); count = VALUES[g_vm->getRandomNumber(15)]; - start = g_vm->getRandomNumber(255); + start = 5 * g_vm->getRandomNumber(255); } else { count = 9; start = 0; @@ -208,45 +220,280 @@ void CStarControlSub5::proc2(CStarControlSub6 *sub6, FVector *vector, double v1, Entry *entryP = &_entries[start]; for (; count > 0; --count, ++entryP) { - //eax=sineIndex1, ecx=sineIndex2, - int sineIndex1 = (entryP->_field8 * _multiplier) & 0x1ff; - int sineIndex2 = (entryP->_fieldC * _multiplier + entryP->_fieldC) & 0x1ff; - - double t1 = _sineTable[sineIndex2]; - double t2 = sin(_sineTable[sineIndex1] * entryP->_field10); - double t3 = cos(_sineTable[sineIndex1] * entryP->_field10); - double t4 = _sineTable[sineIndex2 + 512]; - double t5 = t3 * t4; - t3 = t3 * t1; - double t6 = entryP->_field14 * t5; - double t7 = t2 * entryP->_field14; - double t8 = entryP->_field14 * t3; - double t9 = -(t2 * t4 * entryP->_field14); - double t10 = t3 * entryP->_field14; - double t11 = -(t2 * t1 * entryP->_field14); - t4 = -(t1 * entryP->_field14); - t1 = t4 * entryP->_field14; - - _sub1._row1._x = t6; - _sub1._row1._y = t2 * entryP->_field14; - _sub1._row1._z = entryP->_field14 * t3; - _sub1._row2._x = -(t2 * t4 * entryP->_field14); - _sub1._row2._y = t3 * entryP->_field14; - _sub1._row2._z = -(t2 * t1 * entryP->_field14); - _sub1._row3._x = -(t1 * entryP->_field14); - _sub1._row3._z = t4 * entryP->_field14; - - double t12 = entryP->_field0; - _sub1._vector._x = t12 * t5 + vector->_x; - _sub1._vector._y = t12 * t2 + vector->_y; - _sub1._vector._z = t12 * t3 + vector->_z; - - // TODO - warning("TODO: %f %f %f %f %f %f %d", t7, t8, t9, t10, t11, val1, val2); + f1 = _multiplier * entryP->_field8; + f2 = entryP->_field14; + f3 = (f1 + entryP->_fieldC) & 0x1FF; + f4 = _sineTable[f1 & 0x1FF] * entryP->_field10; + f5 = _sineTable[f3]; + f6 = cos(f4); + f7 = sin(f4); + f8 = _sineTable[f3 + 128]; + f9 = f7; + f10 = f6 * f8; + f11 = f6; + f12 = f6 * f5; + f13 = f2 * f10; + f14 = f8 * f2; + f15 = f9 * f2; + f16 = f2 * f12; + f17 = -(f7 * f8 * f2); + f18 = f11 * f2; + f19 = -(f9 * f5 * f2); + f20 = -(f5 * f2); + f21 = f14; + _sub1._row1._x = f13; + _sub1._row1._y = f15; + _sub1._row1._z = f16; + _sub1._row2._x = f17; + _sub1._row2._y = f18; + _sub1._row2._z = f19; + _sub1._row3._x = f20; + _sub1._row3._z = f14; + + f22 = (double)entryP->_field0; + _sub1._vector._x = f22 * f10 + vector->_x; + _sub1._vector._y = f9 * f22 + vector->_y; + _sub1._vector._z = f22 * f12 + vector->_z; + _sub2._row1._x = sub6->_row1._x * f13 + f16 * sub6->_row3._x + f15 * sub6->_row2._x; + _sub2._row1._y = f15 * sub6->_row2._y + f16 * sub6->_row3._y + f13 * sub6->_row1._y; + _sub2._row1._z = f16 * sub6->_row3._z + f13 * sub6->_row1._z + f15 * sub6->_row2._z; + _sub2._row2._x = sub6->_row1._x * f17 + f19 * sub6->_row3._x + f18 * sub6->_row2._x; + _sub2._row2._y = f18 * sub6->_row2._y + f17 * sub6->_row1._y + f19 * sub6->_row3._y; + _sub2._row2._z = f18 * sub6->_row2._z + f19 * sub6->_row3._z + f17 * sub6->_row1._z; + _sub2._row3._x = sub6->_row1._x * f20 + f21 * sub6->_row3._x; + _sub2._row3._y = f20 * sub6->_row1._y + f21 * sub6->_row3._y; + _sub2._row3._z = f20 * sub6->_row1._z + f21 * sub6->_row3._z; + + f23 = _sub1._vector._y; + f24 = _sub1._vector._z; + f25 = _sub1._vector._x; + f26 = _sub1._vector._z; + f27 = _sub1._vector._x; + + f28 = _sub1._vector._y; + _sub2._vector._x = sub6->_row1._x * _sub1._vector._x + + sub6->_row3._x * _sub1._vector._z + + sub6->_row2._x * f28 + + sub6->_vector._x; + _sub2._vector._y = f23 * sub6->_row2._y + + f24 * sub6->_row3._y + + f25 * sub6->_row1._y + + sub6->_vector._y; + _sub2._vector._z = f26 * sub6->_row3._z + + f27 * sub6->_row1._z + + f28 * sub6->_row2._z + + sub6->_vector._z; + + size2 = (int)_array[1]._data2.size(); + size1 = (int)_array[1]._data1.size(); + + if (size2 > 0) { + for (int ctr2 = 0; ctr2 < size2; ++ctr2) { + FVector &currVector = _array[1]._data2[ctr2]; + GridEntry &gridEntry = _grid[ctr2]; + + f34 = currVector._x; + f35 = currVector._y; + f36 = f35 * _sub2._row2._x; + f37 = currVector._z; + f38 = f37 * _sub2._row3._x + f36; + f39 = f38 + f34 * _sub2._row1._x; + f40 = f39 + _sub2._vector._x; + + gridEntry._x = f40; + gridEntry._y = f37 * _sub2._row3._y + + f35 * _sub2._row2._y + + f34 * _sub2._row1._y + + _sub2._vector._y; + gridEntry._z = f37 * _sub2._row3._z + + f35 * _sub2._row2._z + + f34 * _sub2._row1._z + + _sub2._vector._z; + } + } + + if (val2 <= 0) { + surfaceArea->setMode(SA_NONE); + surfaceArea->_pixel = MKTAG_BE(entryP->_pixel1, entryP->_pixel2, + entryP->_pixel3, 0); + surfaceArea->setColorFromPixel(); + + for (int ctr2 = 0; ctr2 < size2; ++ctr2) { + GridEntry &gridEntry = _grid[ctr2]; + sub12->proc28(2, gridEntry, tempV); + gridEntry._position._x = tempV._x; + gridEntry._position._y = tempV._y + v2; + } + + for (int ctr2 = 0; ctr2 < size1; ++ctr2) { + Data1 &d1 = _array[1]._data1[ctr2]; + GridEntry &grid1 = _grid[d1._index1]; + GridEntry &grid2 = _grid[d1._index2]; + + if (grid1._z > val1 && grid2._z > val1) { + surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y, + grid2._position._x, grid2._position._y)); + } + } + } else { + surfaceArea->setMode(SA_NONE); + surfaceArea->_pixel = entryP->_pixel1; + surfaceArea->setColorFromPixel(); + + for (int ctr2 = 0; ctr2 < size2; ++ctr2) { + GridEntry &gridEntry = _grid[ctr2]; + sub12->proc28(0, gridEntry, tempV); + gridEntry._position._x = tempV._x + v1; + gridEntry._position._y = tempV._y + v2; + } + + for (int ctr2 = 0; ctr2 < size1; ++ctr2) { + Data1 &d1 = _array[1]._data1[ctr2]; + GridEntry &grid1 = _grid[d1._index1]; + GridEntry &grid2 = _grid[d1._index2]; + + if (grid1._z > val1 && grid2._z > val1) { + surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y, + grid2._position._x, grid2._position._y)); + } + } + + surfaceArea->_pixel = entryP->_pixel3; + surfaceArea->setColorFromPixel(); + surfaceArea->setMode(SA_MODE2); + + for (int ctr2 = 0; ctr2 < size2; ++ctr2) { + GridEntry &gridEntry = _grid[ctr2]; + sub12->proc28(1, gridEntry, tempV); + gridEntry._position._x = tempV._x + v1; + gridEntry._position._y = tempV._y + v2; + } + + for (int ctr2 = 0; ctr2 < size1; ++ctr2) { + Data1 &d1 = _array[1]._data1[ctr2]; + GridEntry &grid1 = _grid[d1._index1]; + GridEntry &grid2 = _grid[d1._index2]; + + if (grid1._z > val1 && grid2._z > val1) { + surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y, + grid2._position._x, grid2._position._y)); + } + } + } + } + } + + uint pixel1 = 0x81EEF5, pixel2 = 0xF5, pixel3 = 0x810000; + int arrIndex = 0; + + if (v3 >= 200000000.0) { + if (v3 >= 900000000.0) { + if (v3 >= 6000000000.0) { + arrIndex = 3; + if (v3 >= 1.0e10) + arrIndex = 4; + } else { + arrIndex = 2; + } + } else { + arrIndex = 1; } + } else { + arrIndex = 0; } - // TODO + SubEntry &entry = _array[arrIndex]; + + for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) { + GridEntry &gridEntry = _grid[ctr]; + const FVector &d2v = entry._data2[ctr]; + FVector newV = d2v + *vector; + + f41 = sub6->_row1._x; + f42 = sub6->_row3._x; + f43 = sub6->_row2._x; + f44 = f43 * newV._y; + f45 = f41 * newV._x + f42 * newV._z + f44; + f46 = f45 + sub6->_vector._x; + + gridEntry._x = f46; + gridEntry._y = newV._y * sub6->_row2._y + + newV._z * sub6->_row3._y + + newV._x * sub6->_row1._y + + sub6->_vector._y; + gridEntry._z = newV._z * sub6->_row3._z + + newV._y * sub6->_row2._z + + newV._x * sub6->_row1._z + + sub6->_vector._z; + } + + if (val2 <= 0) { + surfaceArea->setMode(SA_NONE); + surfaceArea->_pixel = pixel1; + surfaceArea->setColorFromPixel(); + + for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) { + GridEntry &gridEntry = _grid[ctr]; + sub12->proc28(2, gridEntry, tempV); + gridEntry._position._x = tempV._x + v1; + gridEntry._position._y = tempV._y + v2; + } + + for (uint ctr = 0; ctr < entry._data1.size(); ++ctr) { + Data1 &d1 = entry._data1[ctr]; + GridEntry &grid1 = _grid[d1._index1]; + GridEntry &grid2 = _grid[d1._index2]; + + if (grid2._z > val1 && grid1._z > val1) { + surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y, + grid2._position._x, grid2._position._y)); + } + } + } else { + surfaceArea->setMode(SA_NONE); + surfaceArea->_pixel = pixel2; + surfaceArea->setColorFromPixel(); + + for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) { + GridEntry &gridEntry = _grid[ctr]; + sub12->proc28(2, gridEntry, tempV); + gridEntry._position._x = tempV._x + v1; + gridEntry._position._y = tempV._y + v2; + } + + for (uint ctr = 0; ctr < entry._data1.size(); ++ctr) { + Data1 &d1 = entry._data1[ctr]; + GridEntry &grid1 = _grid[d1._index1]; + GridEntry &grid2 = _grid[d1._index2]; + + if (grid2._z > val1 && grid1._z > val1) { + surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y, + grid2._position._x, grid2._position._y)); + } + } + + surfaceArea->_pixel = pixel3; + surfaceArea->setColorFromPixel(); + surfaceArea->setMode(SA_MODE2); + + for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) { + GridEntry &gridEntry = _grid[ctr]; + sub12->proc28(2, gridEntry, tempV); + gridEntry._position._x = tempV._x + v1; + gridEntry._position._y = tempV._y + v2; + } + + for (uint ctr = 0; ctr < entry._data1.size(); ++ctr) { + Data1 &d1 = entry._data1[ctr]; + GridEntry &grid1 = _grid[d1._index1]; + GridEntry &grid2 = _grid[d1._index2]; + + if (grid2._z > val1 && grid1._z > val1) { + surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y, + grid2._position._x, grid2._position._y)); + } + } + } } void CStarControlSub5::proc3(CErrorCode *errorCode) { @@ -259,40 +506,85 @@ void CStarControlSub5::fn1() { } bool CStarControlSub5::setupEntry(int width, int height, int index, double val) { - /* if (width < 2 || height < 3) return false; SubEntry &entry = _array[index]; entry.clear(); - int height2 = height - 2; - int height1 = height - 1; - entry._data1.resize((2 * height - 3) * width); - entry._data2.resize(width * height2 + 2); - entry._data2[0] = FVector(0.0, val, 0.0); + const double FACTOR = 2 * M_PI / 360.0; + int d1Count, d2Count, size3, height1; + int ctr, ctr2, idx, offset, f11; + double vx, vy, f5, f6, f7, f8, f9, f10; + + d1Count = width * (2 * height - 3); + d2Count = (height - 2) * width + 2; + entry._data1.resize(d1Count); + entry._data2.resize(d2Count); + + height1 = height - 1; + entry._data2[0]._y = val; + + vy = 180.0 / (double)height1; + vx = 360.0 / (double)width; + + for (ctr = height - 2, idx = 0; ctr > 0; --ctr, vy *= 2) { + f5 = 0.0; + f6 = cos(vy * FACTOR); + f7 = sin(vy * FACTOR); - index = 1; - double vy = 180.0 / (double)height1; - double vx = 360.0 / (double)width; - const double FACTOR = 3.1415927 * 0.0055555557; + if (width > 0) { + f8 = f6 * val; - if (height1 > 1) { - double yAmount = vy; - int width12 = width * 12; - for (int yCtr = height1 - 1; yCtr > 0; --yCtr, yAmount += vy) { - double sineVal = sin(yAmount * FACTOR); + for (int xp = width; xp > 0; --xp, ++idx, f5 += vx) { + f9 = f5 * FACTOR; + f10 = cos(f9) * f7 * val; + FVector &tempV = entry._data2[idx]; + tempV._x = sin(f9) * f7 * val; + tempV._y = f8; + tempV._z = f10; + } + } + } + entry._data2[idx] = FVector(0.0, -1.0, 0.0); + + size3 = width * (height - 3) + 1; + offset = 0; + Data1 *data1P = &entry._data1[0]; + for (ctr = 0; ctr < width; ++ctr, ++size3) { + data1P->_index1 = 0; + data1P->_index2 = size3 - width * (height - 3); + ++data1P; + + data1P->_index1 = d2Count - 1; + data1P->_index2 = size3; + ++data1P; + } - | 0.0 * FACTOR | - | cos(yAmount * FACTOR) * val | - | 0.0 | - |yAmount| + f11 = 1; + for (ctr = 1; ctr < height1; ++ctr, f11 += width) { + data1P = &entry._data1[offset]; + + for (ctr2 = 0; ctr2 < width; ++ctr2) { + data1P->_index1 = ctr2 + f11; + if (ctr2 == width - 1) + data1P->_index2 = f11; + else + data1P->_index2 = ctr2 + f11 + 1; + + ++offset; + ++data1P; + + if (ctr < height - 2) { + data1P->_index1 = ctr2 + f11; + ++offset; + data1P->_index2 = width + ctr2 + f11; + ++data1P; + } } } - // TODO - */ return true; } |