diff options
author | Torbjörn Andersson | 2006-09-30 11:55:50 +0000 |
---|---|---|
committer | Torbjörn Andersson | 2006-09-30 11:55:50 +0000 |
commit | 30ac033dc0783afc00473dd3cc34617f7371f5de (patch) | |
tree | 82e16178ef8d2fe691d27eff401ec6423a5ac98a /engines | |
parent | 79e07ad97bfbe58c46a294f2add7ac055b6eadd9 (diff) | |
download | scummvm-rg350-30ac033dc0783afc00473dd3cc34617f7371f5de.tar.gz scummvm-rg350-30ac033dc0783afc00473dd3cc34617f7371f5de.tar.bz2 scummvm-rg350-30ac033dc0783afc00473dd3cc34617f7371f5de.zip |
Added a couple of functions which seem to define the rules for some kind of
"blocks" game. This looks like it could be cleaned up quite a bit.
svn-id: r24038
Diffstat (limited to 'engines')
-rw-r--r-- | engines/agos/agos.h | 10 | ||||
-rw-r--r-- | engines/agos/module.mk | 1 | ||||
-rw-r--r-- | engines/agos/rules.cpp | 481 |
3 files changed, 492 insertions, 0 deletions
diff --git a/engines/agos/agos.h b/engines/agos/agos.h index c15f5a4d11..eec15a1045 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -635,6 +635,16 @@ protected: void mouseOff(); void mouseOn(); + bool block0Supported(int i, int y); + bool block1Supported(int i, int y); + void stopBlock(int a, int b); + void remove0Block(int i); + void remove1Block(int i); + void pairCheck(); + void dropBlock(int a, int b, int c); + void gravityCheck(); + bool hasBlockLanded(int16 yofs, int16 block, int16 priority, int16 type, int16 x, int16 y, int16 z); + bool loadTablesIntoMem(uint subr_id); bool loadTablesOldIntoMem(uint subr_id); bool loadTablesNewIntoMem(uint subr_id); diff --git a/engines/agos/module.mk b/engines/agos/module.mk index d58c545866..61e54e5ea1 100644 --- a/engines/agos/module.mk +++ b/engines/agos/module.mk @@ -17,6 +17,7 @@ MODULE_OBJS := \ oracle.o \ res.o \ rooms.o \ + rules.o \ saveload.o \ sound.o \ string.o \ diff --git a/engines/agos/rules.cpp b/engines/agos/rules.cpp new file mode 100644 index 0000000000..c9709ba98c --- /dev/null +++ b/engines/agos/rules.cpp @@ -0,0 +1,481 @@ +/* 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 |