mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-11 21:55:27 +00:00
30ac033dc0
"blocks" game. This looks like it could be cleaned up quite a bit. svn-id: r24038
482 lines
10 KiB
C++
482 lines
10 KiB
C++
/* ScummVM - Scumm Interpreter
|
|
* Copyright (C) 2001 Ludvig Strigeus
|
|
* Copyright (C) 2001-2006 The ScummVM project
|
|
*
|
|
* 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.
|
|
*
|
|
* $URL$
|
|
* $Id: vga.cpp 24023 2006-09-30 02:15:02Z kirben $
|
|
*
|
|
*/
|
|
|
|
#include "common/stdafx.h"
|
|
|
|
#include "common/system.h"
|
|
|
|
#include "agos/agos.h"
|
|
|
|
namespace AGOS {
|
|
|
|
bool AGOSEngine::block0Supported(int i, int y) {
|
|
if (y == 0) {
|
|
// Always supported at bottom level
|
|
return true;
|
|
}
|
|
|
|
int a = _variableArray[i];
|
|
|
|
while(1) {
|
|
if (_variableArray[i - 8] != 0) {
|
|
// Supported
|
|
return true;
|
|
}
|
|
|
|
i++;
|
|
|
|
if (_variableArray[i] != a) {
|
|
// Got to end of block and found no support
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool AGOSEngine::block1Supported(int i, int y)
|
|
{
|
|
if (y == 0) {
|
|
// Always supported at bottom level
|
|
return true;
|
|
}
|
|
|
|
int a = _variableArray[i];
|
|
|
|
while(1) {
|
|
if(_variableArray[i - 8] != 0) {
|
|
// Supported
|
|
return true;
|
|
}
|
|
|
|
i += 128;
|
|
|
|
if (_variableArray[i] != a) {
|
|
// Got to end of block and found no support
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void AGOSEngine::stopBlock(int a, int b) {
|
|
}
|
|
|
|
void AGOSEngine::remove0Block(int i)
|
|
{
|
|
int a = _variableArray[i];
|
|
if(a == 0)
|
|
return;
|
|
while (_variableArray[i] == a)
|
|
_variableArray[i++] = 0;
|
|
stopBlock(a, 0);
|
|
a = a & 0xff80; // Point to flags 420 - 425 containing counts
|
|
a = a / 128; // For each colour block
|
|
a += 419;
|
|
_variableArray[a]--;
|
|
}
|
|
|
|
void AGOSEngine::remove1Block(int i)
|
|
{
|
|
int a = _variableArray[i];
|
|
int b = -1;
|
|
if (a == 0)
|
|
return;
|
|
while (_variableArray[i] == a) {
|
|
_variableArray[i] = 0;
|
|
i += 128;
|
|
b++;
|
|
}
|
|
stopBlock(a, b);
|
|
a = a & 0xff80; // Point to flags 420 - 425 containing counts
|
|
a -= 1024;
|
|
a = a / 128; // for each colour block
|
|
a += 419;
|
|
_variableArray[a]--;
|
|
}
|
|
|
|
void AGOSEngine::pairCheck()
|
|
{
|
|
int i, j, j1, k;
|
|
int x, y, z;
|
|
int flag;
|
|
int block;
|
|
int blockColour;
|
|
int pairsList0[50][2];
|
|
int pairsList1[50][2];
|
|
|
|
j = 0;
|
|
|
|
// For each level
|
|
|
|
for (y = 0; y < 16; y++) {
|
|
// Check Type 0 blocks - blocks totally covered by others
|
|
// further away along Z axis
|
|
|
|
for (z = 0; z < 7; z++) {
|
|
flag = 1000 + z * 128 + y * 8;
|
|
// This assumes minimum block length of 3
|
|
for (x = 0; x < 6; x++) {
|
|
block = _variableArray[flag + x];
|
|
blockColour = block & 0xff80;
|
|
if (block < 999 && block != 0) {
|
|
i = x;
|
|
while (1) {
|
|
// Not same colour?
|
|
if (((_variableArray[flag + x + 128]) & 0xff80) != blockColour) {
|
|
// To end of block
|
|
x++;
|
|
while (_variableArray[flag + x] == block)
|
|
x++;
|
|
x--;
|
|
break;
|
|
}
|
|
x++;
|
|
if (_variableArray[flag + x] != block) {
|
|
// Got a pair
|
|
i += flag;
|
|
k = i + 128;
|
|
block = _variableArray[k];
|
|
// Back to start of covering block
|
|
k--;
|
|
while (_variableArray[k] == block)
|
|
k--;
|
|
k++;
|
|
if (block0Supported(i, y) && block0Supported(k, y)) {
|
|
// Form a list and remove blocks when finished check
|
|
pairsList0[j][0] = i;
|
|
pairsList0[j++][1] = k;
|
|
}
|
|
x--;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check Type 0 blocks - blocks totally covered by others
|
|
// further towards along Z axis
|
|
|
|
for (z = 7; z > 0; z--) {
|
|
flag = 1000 + z * 128 + y * 8;
|
|
// This assumes minimum block length of 3
|
|
for (x = 0; x < 6; x++) {
|
|
block = _variableArray[flag + x];
|
|
blockColour = block & 0xff80;
|
|
if (block < 999 && block != 0) {
|
|
i = x;
|
|
while (1) {
|
|
// Not same colour
|
|
if (((_variableArray[flag + x - 128]) & 0xff80) != blockColour) {
|
|
// To end of block
|
|
x++;
|
|
while (_variableArray[flag + x] == block)
|
|
x++;
|
|
x--;
|
|
break;
|
|
}
|
|
x++;
|
|
if (_variableArray[flag + x] != block) {
|
|
// Got a pair
|
|
i += flag;
|
|
k = i - 128;
|
|
block = _variableArray[k];
|
|
// Back to start of covering block
|
|
k--;
|
|
while (_variableArray[k]==block)
|
|
k--;
|
|
k++;
|
|
if (block0Supported(i, y) && block0Supported(k, y)) {
|
|
// Form a list and remove blocks when finished check
|
|
pairsList0[j][0] = i;
|
|
pairsList0[j++][1] = k;
|
|
}
|
|
x--;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
j1 = 0;
|
|
|
|
// For each level
|
|
for (y = 0; y < 16; y++) {
|
|
// Check Type 1 blocks - blocks totally covered by others
|
|
// further right along X axis
|
|
|
|
for (x = 0; x < 7; x++) {
|
|
flag = 1000 + x + y * 8;
|
|
// This assumes minimum block length of 3
|
|
for (z = 0; z < (6 * 128); z += 128) {
|
|
block = _variableArray[flag + z];
|
|
blockColour = block & 0xff80;
|
|
if (block > 999) {
|
|
i = z;
|
|
while (1) {
|
|
// Not the same colour?
|
|
if (((_variableArray[flag + z + 1]) & 0xff80) != blockColour) {
|
|
z += 128;
|
|
// To end of block
|
|
while (_variableArray[flag + z] == block)
|
|
z += 128;
|
|
z -= 128;
|
|
break;
|
|
}
|
|
z += 128;
|
|
if (_variableArray[flag + z] != block) {
|
|
// Got a pair
|
|
i += flag;
|
|
k = i + 1;
|
|
block = _variableArray[k];
|
|
k -= 128;
|
|
// Back to start of covering block
|
|
while (_variableArray[k] == block)
|
|
k -= 128;
|
|
k += 128;
|
|
if (block1Supported(i, y) && block1Supported(k, y)) {
|
|
// Form a list and remove blocks when finished check
|
|
pairsList1[j1][0] = i;
|
|
pairsList1[j1++][1] = k;
|
|
}
|
|
z -= 128;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check Type 1 blocks - blocks totally covered by others
|
|
// further left along X axis
|
|
|
|
for (x = 7; x > 0; x--) {
|
|
flag = 1000 + x + y * 8;
|
|
// This assumes minimum block length of 3
|
|
for (z = 0; z < (6 * 128); z += 128) {
|
|
block = _variableArray[flag + z];
|
|
blockColour = block & 0xff80;
|
|
if (block > 999) {
|
|
i = z;
|
|
while (1) {
|
|
// Not same colour?
|
|
if (((_variableArray[flag + z - 1]) & 0xff80) != blockColour)
|
|
{
|
|
z += 128;
|
|
// To end of block
|
|
while (_variableArray[flag + z] == block)
|
|
z += 128;
|
|
z -= 128;
|
|
break;
|
|
}
|
|
z += 128;
|
|
if (_variableArray[flag + z] != block) {
|
|
// Got a pair
|
|
i += flag;
|
|
k = i - 1;
|
|
block = _variableArray[k];
|
|
k -= 128;
|
|
// Back to start of covering block
|
|
while (_variableArray[k] == block)
|
|
k -= 128;
|
|
k += 128;
|
|
if (block1Supported(i, y) && block1Supported(k, y)) {
|
|
// Form a list and remove blocks when finished check
|
|
pairsList1[j1][0] = i;
|
|
pairsList1[j1++][1] = k;
|
|
}
|
|
z -= 128;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove any pairs
|
|
|
|
if (j != 0) {
|
|
for (i = 0; i < j; i++) {
|
|
remove0Block(pairsList0[i][0]);
|
|
remove0Block(pairsList0[i][1]);
|
|
}
|
|
}
|
|
|
|
if (j1 != 0) {
|
|
for (i = 0; i < j1; i++) {
|
|
remove1Block(pairsList1[i][0]);
|
|
remove1Block(pairsList1[i][1]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void AGOSEngine::dropBlock(int a, int b, int c) {
|
|
}
|
|
|
|
void AGOSEngine::gravityCheck()
|
|
{
|
|
int i, j, k;
|
|
int x, y, z;
|
|
int flag;
|
|
int block;
|
|
|
|
// For each level
|
|
for (y = 1; y < 16; y++) {
|
|
// Check Type 0 blocks
|
|
for (z = 0; z < 8; z++) {
|
|
flag = 1000 + z * 128 + y * 8;
|
|
// This assumes minimum block length of 3
|
|
for (x = 0; x < 6; x++) {
|
|
block = _variableArray[flag + x];
|
|
if (block < 999 && block != 0) {
|
|
i = x;
|
|
while (1) {
|
|
// Can't drop?
|
|
if (_variableArray[flag + x - 8] != 0) {
|
|
x++;
|
|
// To end of block
|
|
while (_variableArray[flag + x] == block)
|
|
;
|
|
x--;
|
|
break;
|
|
}
|
|
x++;
|
|
// Can drop?
|
|
if (_variableArray[flag + x] != block) {
|
|
x = i;
|
|
while (_variableArray[flag + x] == block) {
|
|
_variableArray[flag + x] = 0;
|
|
_variableArray[flag + x - 8] = block;
|
|
x++;
|
|
}
|
|
dropBlock(block, (y - 1) * 64 + (8 - z) * 8 + i, 0);
|
|
x--;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check Type 1 blocks
|
|
|
|
for (x = 0; x < 8; x++) {
|
|
flag = 1000 + y * 8 + x;
|
|
for (z = 0; z < (6 * 128); z += 128) {
|
|
block = _variableArray[flag + z];
|
|
if (block > 999) {
|
|
i = z;
|
|
while (1) {
|
|
// Can't drop?
|
|
if (_variableArray[flag + z - 8] != 0) {
|
|
z += 128;
|
|
// To end of block
|
|
while (_variableArray[flag + z] == block)
|
|
z += 128;
|
|
z -= 128;
|
|
break;
|
|
}
|
|
z += 128;
|
|
// Can drop?
|
|
if (_variableArray[flag + z] != block) {
|
|
z = i;
|
|
k = -1;
|
|
while (_variableArray[flag + z] == block) {
|
|
_variableArray[flag + z] = 0;
|
|
_variableArray[flag + z - 8] = block;
|
|
z += 128;
|
|
k++;
|
|
}
|
|
dropBlock(block, (y - 1) * 64 + (8 - i / 128) * 8 + x, k);
|
|
z -= 128;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool AGOSEngine::hasBlockLanded(int16 yofs, int16 block, int16 priority, int16 type, int16 x, int16 y, int16 z)
|
|
{
|
|
if (type == 1) {
|
|
x++;
|
|
z--;
|
|
}
|
|
|
|
if (y > 15)
|
|
return true;
|
|
|
|
bool fail = false;
|
|
|
|
if (y == 15) {
|
|
// Failed if land on top level, or ceiling dropped to one level
|
|
fail = true;
|
|
}
|
|
|
|
if (_variableArray[432] > 2 && y + _variableArray[432] > 16) {
|
|
// above landed block
|
|
fail = true;
|
|
}
|
|
|
|
int flag = 1000 + z * 128 + y * 8 + x;
|
|
|
|
if (type == 0) {
|
|
if (y != 0 && _variableArray[flag - 8] == 0 && _variableArray[flag + 1 - 8] == 0 && _variableArray[flag + 2 - 8] == 0) {
|
|
return true;
|
|
}
|
|
|
|
_variableArray[flag] = block;
|
|
_variableArray[flag + 1] = block;
|
|
_variableArray[flag + 2] = block;
|
|
|
|
if (fail) {
|
|
_variableArray[254] = 6070;
|
|
} else {
|
|
// Start next block
|
|
sendSync(6007);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
if (y != 0 && _variableArray[flag - 8] == 0 && _variableArray[flag + 128 - 8] == 0 && _variableArray[flag + 256 - 8] == 0) {
|
|
return true;
|
|
}
|
|
|
|
_variableArray[flag] = block;
|
|
_variableArray[flag +128] = block;
|
|
_variableArray[flag + 256] = block;
|
|
|
|
if (fail) {
|
|
_variableArray[254] = 6070;
|
|
} else {
|
|
// Start next block
|
|
sendSync(6007);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
} // End of namespace AGOS
|