mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-04 16:26:53 +00:00
1261 lines
34 KiB
C++
1261 lines
34 KiB
C++
/* 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 "hopkins/computer.h"
|
|
|
|
#include "hopkins/font.h"
|
|
#include "hopkins/files.h"
|
|
#include "hopkins/globals.h"
|
|
#include "hopkins/graphics.h"
|
|
#include "hopkins/hopkins.h"
|
|
#include "hopkins/objects.h"
|
|
|
|
#include "common/system.h"
|
|
#include "common/file.h"
|
|
#include "common/textconsole.h"
|
|
|
|
namespace Hopkins {
|
|
|
|
ComputerManager::ComputerManager(HopkinsEngine *vm) {
|
|
_vm = vm;
|
|
|
|
for (int i = 0; i < ARRAYSIZE(_menuText); i++) {
|
|
_menuText[i]._lineSize = 0;
|
|
memset(_menuText[i]._line, 0, ARRAYSIZE(_menuText[0]._line));
|
|
}
|
|
Common::fill(&_inputBuf[0], &_inputBuf[200], '\0');
|
|
_breakoutSpr = NULL;
|
|
_textColor = 0;
|
|
_breakoutLevel = (int16 *)NULL;
|
|
_breakoutBrickNbr = 0;
|
|
_breakoutScore = 0;
|
|
_breakoutLives = 0;
|
|
_breakoutSpeed = 0;
|
|
_ballRightFl = false;
|
|
_ballUpFl = false;
|
|
_breakoutLevelNbr = 0;
|
|
_padPositionX = 0;
|
|
_minBreakoutMoveSpeed = 0;
|
|
_maxBreakoutMoveSpeed = 0;
|
|
_lastBreakoutMoveSpeed = 0;
|
|
_lowestHiScore = 0;
|
|
}
|
|
|
|
/**
|
|
* Sets up textual entry mode. Used by the code for Hopkins computer.
|
|
*/
|
|
void ComputerManager::setVideoMode() {
|
|
setTextMode();
|
|
}
|
|
|
|
/**
|
|
* Sets up Textual entry mode
|
|
*/
|
|
void ComputerManager::setTextMode() {
|
|
_vm->_graphicsMan->clearPalette();
|
|
_vm->_graphicsMan->clearScreen();
|
|
|
|
_vm->_graphicsMan->_lineNbr = SCREEN_WIDTH;
|
|
_vm->_fontMan->_font = _vm->_globals->freeMemory(_vm->_fontMan->_font);
|
|
|
|
Common::String filename = "STFONT.SPR";
|
|
Common::File f;
|
|
if (!f.exists(filename))
|
|
filename = "FONTE.SPR"; // Used by the BeOS and OS/2 versions as an alternative
|
|
_vm->_fontMan->_font = _vm->_fileIO->loadFile(filename);
|
|
_vm->_fontMan->_fontFixedWidth = 8;
|
|
_vm->_fontMan->_fontFixedHeight = 8;
|
|
|
|
_vm->_graphicsMan->loadImage("WINTEXT");
|
|
_vm->_graphicsMan->fadeInLong();
|
|
loadMenu();
|
|
_vm->_events->_mouseFl = false;
|
|
}
|
|
|
|
/**
|
|
* Clear the screen
|
|
*/
|
|
void ComputerManager::clearScreen() {
|
|
_vm->_graphicsMan->loadImage("WINTEXT");
|
|
_vm->_graphicsMan->fadeInLong();
|
|
}
|
|
|
|
/**
|
|
* Sets the text mode color
|
|
*/
|
|
void ComputerManager::setTextColor(int col) {
|
|
_textColor = col;
|
|
}
|
|
|
|
/**
|
|
* Sets the text position.
|
|
* @param yp Y position
|
|
* @param xp X position
|
|
* @remarks Yes, the reverse co-ordinate pair is really like that in the original game.
|
|
*/
|
|
void ComputerManager::setTextPosition(int yp, int xp) {
|
|
_textPosition.x = xp << 3;
|
|
_textPosition.y = yp << 4;
|
|
}
|
|
|
|
/**
|
|
* Show a computer in the FBI office
|
|
* @param mode Which computer to display
|
|
*/
|
|
void ComputerManager::showComputer(ComputerEnum mode) {
|
|
_vm->_events->_escKeyFl = false;
|
|
_vm->_graphicsMan->resetDirtyRects();
|
|
setVideoMode();
|
|
setTextColor(4);
|
|
setTextPosition(2, 4);
|
|
if (mode == COMPUTER_HOPKINS)
|
|
outText(Common::String(_menuText[0]._line));
|
|
else if (mode == COMPUTER_SAMANTHA)
|
|
outText(Common::String(_menuText[1]._line));
|
|
else // COMPUTER_PUBLIC
|
|
outText(Common::String(_menuText[2]._line));
|
|
|
|
setTextColor(1);
|
|
if (mode == COMPUTER_PUBLIC) {
|
|
setTextPosition(10, 8);
|
|
outText(Common::String(_menuText[3]._line));
|
|
}
|
|
setTextPosition(12, 28);
|
|
outText(Common::String(_menuText[4]._line));
|
|
setTextPosition(14, 35);
|
|
|
|
displayMessage(280, 224, 8);
|
|
bool passwordMatch = false;
|
|
if ((mode == COMPUTER_HOPKINS) && !strcmp(_inputBuf, "HOPKINS"))
|
|
passwordMatch = true;
|
|
else if ((mode == COMPUTER_SAMANTHA) && !strcmp(_inputBuf, "328MHZA"))
|
|
passwordMatch = true;
|
|
else if ((mode == COMPUTER_PUBLIC) && !strcmp(_inputBuf, "ALLFREE"))
|
|
passwordMatch = true;
|
|
|
|
if (passwordMatch) {
|
|
while (!_vm->shouldQuit()) {
|
|
_vm->_events->_escKeyFl = false;
|
|
clearScreen();
|
|
setTextColor(4);
|
|
setTextPosition(2, 4);
|
|
if (mode == COMPUTER_HOPKINS)
|
|
outText(Common::String(_menuText[0]._line));
|
|
else if (mode == COMPUTER_SAMANTHA)
|
|
outText(Common::String(_menuText[1]._line));
|
|
else if (mode == COMPUTER_PUBLIC)
|
|
outText(Common::String(_menuText[2]._line));
|
|
setTextColor(15);
|
|
setTextPosition(8, 25);
|
|
setTextColor(15);
|
|
outText2(Common::String(_menuText[6]._line));
|
|
setTextPosition(20, 25);
|
|
outText2(Common::String(_menuText[7]._line));
|
|
if (mode == COMPUTER_HOPKINS) {
|
|
setTextPosition(10, 25);
|
|
outText2(Common::String(_menuText[8]._line));
|
|
setTextPosition(12, 25);
|
|
outText2(Common::String(_menuText[9]._line));
|
|
setTextPosition(14, 25);
|
|
outText2(Common::String(_menuText[10]._line));
|
|
setTextPosition(16, 25);
|
|
outText2(Common::String(_menuText[11]._line));
|
|
} else if (mode == COMPUTER_SAMANTHA) {
|
|
setTextPosition(10, 25);
|
|
// outText2(Common::String(_menuText[0x95A])); <=== CHECKME: Unexpected value! replaced by the following line, for consistancy
|
|
outText2(Common::String(_menuText[12]._line));
|
|
setTextPosition(12, 25);
|
|
outText2(Common::String(_menuText[13]._line));
|
|
setTextPosition(14, 25);
|
|
outText2(Common::String(_menuText[14]._line));
|
|
setTextPosition(16, 25);
|
|
outText2(Common::String(_menuText[15]._line));
|
|
setTextPosition(18, 25);
|
|
outText2(Common::String(_menuText[16]._line));
|
|
}
|
|
|
|
bool numericFlag = false;
|
|
char keyPressed;
|
|
do {
|
|
keyPressed = _vm->_events->waitKeyPress();
|
|
if (_vm->shouldQuit())
|
|
return;
|
|
|
|
if ((keyPressed >= '0') && (keyPressed <= '9'))
|
|
numericFlag = true;
|
|
} while (!numericFlag);
|
|
|
|
// 0 - Quit
|
|
if (keyPressed == '0')
|
|
break;
|
|
// 1 - Games
|
|
if (keyPressed == '1') {
|
|
displayGamesSubMenu();
|
|
} else if (mode == COMPUTER_HOPKINS) {
|
|
clearScreen();
|
|
setTextColor(4);
|
|
setTextPosition(2, 4);
|
|
outText(Common::String(_menuText[0]._line));
|
|
setTextColor(15);
|
|
switch (keyPressed) {
|
|
case '2':
|
|
readText(1);
|
|
break;
|
|
case '3':
|
|
readText(2);
|
|
break;
|
|
case '4':
|
|
readText(3);
|
|
break;
|
|
case '5':
|
|
readText(4);
|
|
break;
|
|
}
|
|
} else if (mode == COMPUTER_SAMANTHA) {
|
|
clearScreen();
|
|
setTextColor(4);
|
|
setTextPosition(2, 4);
|
|
outText(Common::String(_menuText[1]._line));
|
|
setTextColor(15);
|
|
switch (keyPressed) {
|
|
case '2':
|
|
readText(6);
|
|
break;
|
|
case '3':
|
|
readText(7);
|
|
break;
|
|
case '4':
|
|
readText(8);
|
|
break;
|
|
case '5':
|
|
readText(9);
|
|
break;
|
|
case '6':
|
|
readText(10);
|
|
_vm->_globals->_saveData->_data[svField270] = 4;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
_vm->_graphicsMan->clearScreen();
|
|
_vm->_graphicsMan->updateScreen();
|
|
restoreFBIRoom();
|
|
} else {
|
|
// Password doesn't match - Access Denied
|
|
setTextColor(4);
|
|
setTextPosition(16, 25);
|
|
outText(Common::String(_menuText[5]._line));
|
|
_vm->_events->refreshScreenAndEvents();
|
|
_vm->_events->delay(1000);
|
|
|
|
memset(_vm->_graphicsMan->_frontBuffer, 0, 307199);
|
|
_vm->_graphicsMan->clearScreen();
|
|
_vm->_graphicsMan->updateScreen();
|
|
restoreFBIRoom();
|
|
_vm->_events->mouseOff();
|
|
}
|
|
|
|
if (mode == COMPUTER_HOPKINS)
|
|
_vm->_globals->_exitId = 13;
|
|
else // Free access or Samantha
|
|
_vm->_globals->_exitId = 14;
|
|
|
|
_vm->_graphicsMan->resetDirtyRects();
|
|
}
|
|
|
|
static const char _englishText[] =
|
|
"% ****** FBI COMPUTER NUMBER 4985 ****** J.HOPKINS COMPUTER ******\n"
|
|
"% ****** FBI COMPUTER NUMBER 4998 ****** S.COLLINS COMPUTER ******\n"
|
|
"% ****** FBI COMPUTER NUMBER 4997 ****** ACCES FREE COMPUTER ******\n"
|
|
"% PASSWORD IS: ALLFREE\n% ENTER CURRENT PASSWORD\n"
|
|
"% ****** ACCES DENIED ******\n"
|
|
"% 1) *** GAME ***\n"
|
|
"% 0) QUIT COMPUTER\n"
|
|
"% 2) STRANGE CADAVER\n"
|
|
"% 3) STRANGE CADAVER\n"
|
|
"% 4) SENATOR FERGUSSON\n"
|
|
"% 5) DOG KILLER\n"
|
|
"% 2) SCIENTIST KIDNAPPED.\n"
|
|
"% 3) SCIENTIST KIDNAPPED (next).\n"
|
|
"% 4) SCIENTIST KIDNAPPED (next).\n"
|
|
"% 5) SCIENTIST KIDNAPPED (next).\n"
|
|
"% 6) SCIENTIST KIDNAPPED (next).\n"
|
|
"%% fin\n";
|
|
|
|
static const char _frenchText[] =
|
|
"% ****** FBI COMPUTER NUMBER 4985 ****** J.HOPKINS COMPUTER ******\n"
|
|
"% ****** FBI COMPUTER NUMBER 4998 ****** S.COLLINS COMPUTER ******\n"
|
|
"% ****** FBI COMPUTER NUMBER 4997 ****** ACCES FREE COMPUTER ******\n"
|
|
"% PASSWORD IS: ALLFREE\n"
|
|
"% ENTER CURRENT PASSWORD\n"
|
|
"% ****** ACCES DENIED ******\n"
|
|
"% 1) *** CASSE BRIQUE ***\n"
|
|
"% 0) QUITTER L'ORDINATEUR\n"
|
|
"% 2) CADAVRE SANS TETE\n"
|
|
"% 3) CADAVRE SANS TETE\n"
|
|
"% 4) AGRESSION DU SENATEUR\n"
|
|
"% 5) LES CHIENS TUEURS\n"
|
|
"% 2) DISPARITIONS DE CHERCHEURS.\n"
|
|
"% 3) DISPARITIONS (suite).\n"
|
|
"% 4) DISPARITIONS (suite).\n"
|
|
"% 5) DISPARITIONS (suite).\n"
|
|
"% 6) DISPARITIONS (suite).\n"
|
|
"%% fin\n";
|
|
|
|
static const char _spanishText[] =
|
|
"% **** ORDENADOR DEL FBI NUMERO 4985 **** ORDENADOR J.HOPKINS *****\n"
|
|
"% **** ORDENADOR DEL FBI NUMERO 4998 **** ORDENADOR S.COLLINS *****\n"
|
|
"% *** ORDENADOR DEL FBI NUMERO 4997 *** ORDENADOR DE ACCESO LIBRE ***\n"
|
|
"% LA CONTRASE\xA5" "A ES: ALLFREE\n"
|
|
"% ESCRIBE CONTRASE\xA5" "A ACTUAL\n"
|
|
"% **** ACCESO DENEGADO ****\n"
|
|
"% 1) *** JUEGO ***\n"
|
|
"% 0) SALIR DEL ORDENADOR\n"
|
|
"% 2) CADAVER EXTRA\xA5" "O\n"
|
|
"% 3) CADAVER EXTRA\xA5" "O\n"
|
|
"% 4) SENADOR FERGUSSON\n"
|
|
"% 5) MATAPERROS\n"
|
|
"% 2) CIENTIFICO SECUESTRADO.\n"
|
|
"% 3) CIENTIFICO SECUESTRADO (siguiente).\n"
|
|
"% 4) CIENTIFICO SECUESTRADO (siguiente).\n"
|
|
"% 5) CIENTIFICO SECUESTRADO (siguiente).\n"
|
|
"% 6) CIENTIFICO SECUESTRADO (siguiente).\n"
|
|
"%% fin\n";
|
|
|
|
/**
|
|
* Load Menu data
|
|
*/
|
|
void ComputerManager::loadMenu() {
|
|
debug(9, "ComputerManager::loadMenu()");
|
|
char *ptr;
|
|
if (_vm->_fileIO->fileExists("COMPUTAN.TXT")) {
|
|
ptr = (char *)_vm->_fileIO->loadFile("COMPUTAN.TXT");
|
|
} else {
|
|
switch (_vm->_globals->_language) {
|
|
case LANG_FR:
|
|
ptr = (char *)_vm->_globals->allocMemory(sizeof(_frenchText));
|
|
Common::strlcpy(ptr, _frenchText, sizeof(_frenchText));
|
|
break;
|
|
case LANG_SP:
|
|
ptr = (char *)_vm->_globals->allocMemory(sizeof(_spanishText));
|
|
Common::strlcpy(ptr, _spanishText, sizeof(_spanishText));
|
|
break;
|
|
default:
|
|
ptr = (char *)_vm->_globals->allocMemory(sizeof(_englishText));
|
|
Common::strlcpy(ptr, _englishText, sizeof(_englishText));
|
|
break;
|
|
}
|
|
}
|
|
|
|
char *tmpPtr = ptr;
|
|
int lineNum = 0;
|
|
|
|
const char lineSep = tmpPtr[0];
|
|
|
|
while (tmpPtr[0] != '\0' && lineNum < ARRAYSIZE(_menuText)) {
|
|
if (tmpPtr[0] == '%' && tmpPtr[1] == '%') {
|
|
// End of file marker found - Break out of parse loop
|
|
break;
|
|
}
|
|
|
|
if (tmpPtr[0] == lineSep) {
|
|
int strPos = 0;
|
|
while (strPos < ARRAYSIZE(_menuText[0]._line)) {
|
|
char curChar = tmpPtr[strPos + 2];
|
|
if (curChar == '\0' || curChar == lineSep || curChar == 0x0a) // Line Feed
|
|
break;
|
|
_menuText[lineNum]._line[strPos++] = curChar;
|
|
}
|
|
|
|
if (strPos < ARRAYSIZE(_menuText[0]._line)) {
|
|
_menuText[lineNum]._line[strPos] = 0;
|
|
_menuText[lineNum]._lineSize = strPos - 1;
|
|
}
|
|
|
|
if (strPos != 0) {
|
|
debug(9, "_menuText[%d]._line (size: %d): \"%s\"", lineNum, _menuText[lineNum]._lineSize, _menuText[lineNum]._line);
|
|
++lineNum;
|
|
}
|
|
}
|
|
++tmpPtr;
|
|
}
|
|
|
|
_vm->_globals->freeMemory((byte *)ptr);
|
|
}
|
|
|
|
void ComputerManager::displayMessage(int xp, int yp, int textIdx) {
|
|
char curChar;
|
|
|
|
int x1 = xp;
|
|
int x2 = 0;
|
|
|
|
int textIndex = 0;
|
|
bool oldMouseFlag = _vm->_events->_mouseFl;
|
|
_vm->_events->_mouseFl = false;
|
|
|
|
_vm->_fontMan->displayTextVesa(xp, yp, "_", 252);
|
|
do {
|
|
curChar = _vm->_events->waitKeyPress();
|
|
if (_vm->shouldQuit())
|
|
return;
|
|
|
|
char mappedChar = '*';
|
|
|
|
if ((curChar == '-') || ((curChar >= '0') && (curChar <= '9')) || ((curChar >= 'A') && (curChar <= 'Z')))
|
|
mappedChar = curChar;
|
|
else if ((curChar >= 'a') && (curChar <= 'z'))
|
|
mappedChar = curChar - 32;
|
|
|
|
// BackSpace
|
|
if (curChar == 8 && textIndex > 0) {
|
|
_inputBuf[textIndex--] = 0;
|
|
x1 -= _vm->_fontMan->_fontFixedWidth;
|
|
x2 = x1 + 2 * _vm->_fontMan->_fontFixedWidth;
|
|
_vm->_graphicsMan->copyRect(_vm->_graphicsMan->_backBuffer, x1, yp, 3 * _vm->_fontMan->_fontFixedWidth, 12, _vm->_graphicsMan->_frontBuffer, x1, yp);
|
|
_vm->_graphicsMan->addDirtyRect(x1, yp, x2, yp + 12);
|
|
_vm->_fontMan->displayTextVesa(x1, yp, "_", 252);
|
|
}
|
|
if (mappedChar != '*') {
|
|
char newChar = mappedChar;
|
|
_vm->_graphicsMan->copyRect(_vm->_graphicsMan->_backBuffer, x1, yp, _vm->_fontMan->_fontFixedWidth, 12, _vm->_graphicsMan->_frontBuffer, x1, yp);
|
|
_vm->_graphicsMan->addDirtyRect(x1, yp, _vm->_fontMan->_fontFixedWidth + x1, yp + 12);
|
|
_inputBuf[textIndex] = newChar;
|
|
|
|
Common::String charString = Common::String::format("%c_", newChar);
|
|
_vm->_fontMan->displayTextVesa(x1, yp, charString, 252);
|
|
++textIndex;
|
|
x1 += _vm->_fontMan->_fontFixedWidth;
|
|
}
|
|
_vm->_events->refreshScreenAndEvents();
|
|
} while (textIndex != textIdx && curChar != 13);
|
|
|
|
_vm->_graphicsMan->copyRect(_vm->_graphicsMan->_backBuffer, x1, yp, _vm->_fontMan->_fontFixedWidth, 12, _vm->_graphicsMan->_frontBuffer, x1, yp);
|
|
_vm->_graphicsMan->addDirtyRect(x1, yp, _vm->_fontMan->_fontFixedWidth + x1, yp + 12);
|
|
|
|
_vm->_events->refreshScreenAndEvents();
|
|
_inputBuf[textIndex] = 0;
|
|
_vm->_events->_mouseFl = oldMouseFlag;
|
|
}
|
|
|
|
/**
|
|
* Outputs a text string
|
|
*/
|
|
void ComputerManager::outText(const Common::String &msg) {
|
|
_vm->_fontMan->renderTextDisplay(_textPosition.x, _textPosition.y, msg, _textColor);
|
|
}
|
|
|
|
/**
|
|
* Outputs a text string
|
|
*/
|
|
void ComputerManager::outText2(const Common::String &msg) {
|
|
_vm->_fontMan->displayTextVesa(_textPosition.x, _textPosition.y, msg, _textColor);
|
|
}
|
|
|
|
/**
|
|
* Restores the scene for the FBI headquarters room
|
|
*/
|
|
void ComputerManager::restoreFBIRoom() {
|
|
_vm->_graphicsMan->fadeOutShort();
|
|
|
|
_vm->_globals->freeMemory(_vm->_fontMan->_font);
|
|
_vm->_fontMan->_font = _vm->_fileIO->loadFile("FONTE3.SPR");
|
|
_vm->_fontMan->_fontFixedWidth = 12;
|
|
_vm->_fontMan->_fontFixedHeight = 21;
|
|
|
|
_vm->_events->_mouseFl = true;
|
|
}
|
|
|
|
/**
|
|
* Display texts for the given menu entry
|
|
*/
|
|
void ComputerManager::readText(int idx) {
|
|
_vm->_events->_escKeyFl = false;
|
|
|
|
Common::String filename;
|
|
switch (_vm->_globals->_language) {
|
|
case LANG_EN:
|
|
filename = "THOPKAN.TXT";
|
|
break;
|
|
case LANG_FR:
|
|
filename = "THOPK.TXT";
|
|
break;
|
|
case LANG_SP:
|
|
filename = "THOPKES.TXT";
|
|
break;
|
|
}
|
|
|
|
byte *ptr = _vm->_fileIO->loadFile(filename);
|
|
uint16 fileSize = _vm->_fileIO->fileSize(filename);
|
|
int pos;
|
|
for (pos = 0; pos < fileSize; pos++) {
|
|
if (ptr[pos] == '%') {
|
|
Common::String numStr = Common::String::format("%c%c", ptr[pos + 1], ptr[pos + 2]);
|
|
if (idx == atol(numStr.c_str()))
|
|
break;
|
|
}
|
|
}
|
|
if (pos > fileSize - 3)
|
|
error("Error with Hopkins computer file");
|
|
|
|
pos += 3;
|
|
int lineNum = 5;
|
|
Common::String curStr = "";
|
|
byte curChar;
|
|
do {
|
|
curChar = ptr[pos];
|
|
if (curChar == 13) {
|
|
setTextPosition(lineNum, 1);
|
|
outText(curStr);
|
|
|
|
++lineNum;
|
|
_vm->_events->refreshScreenAndEvents();
|
|
curStr = "";
|
|
} else if (curChar != '%') {
|
|
curStr += curChar;
|
|
}
|
|
++pos;
|
|
assert(pos <= fileSize);
|
|
} while (curChar != '%');
|
|
|
|
_vm->_events->waitKeyPress();
|
|
ptr = _vm->_globals->freeMemory(ptr);
|
|
}
|
|
|
|
/**
|
|
* Display breakout when Games sub-menu is selected
|
|
*/
|
|
void ComputerManager::displayGamesSubMenu() {
|
|
const byte *oldSpriteData = _vm->_objectsMan->_sprite[0]._spriteData;
|
|
uint oldSpeed = _vm->_globals->_speed;
|
|
|
|
_vm->_globals->_speed = 1;
|
|
_vm->_events->changeMouseCursor(0);
|
|
_breakoutSpr = NULL;
|
|
_vm->_events->_breakoutFl = true;
|
|
_breakoutLevel = (int16 *)NULL;
|
|
_breakoutBrickNbr = 0;
|
|
_breakoutScore = 0;
|
|
_breakoutLives = 5;
|
|
_breakoutSpeed = 1;
|
|
_ballRightFl = false;
|
|
_ballUpFl = false;
|
|
_breakoutLevelNbr = 0;
|
|
_vm->_graphicsMan->_minY = 0;
|
|
_vm->_graphicsMan->_maxX = 320;
|
|
_vm->_graphicsMan->_maxY = 200;
|
|
_vm->_soundMan->loadSample(1, "SOUND37.WAV");
|
|
_vm->_soundMan->loadSample(2, "SOUND38.WAV");
|
|
_vm->_soundMan->loadSample(3, "SOUND39.WAV");
|
|
_breakoutSpr = _vm->_fileIO->loadFile("CASSE.SPR");
|
|
loadHiscore();
|
|
setModeVGA256();
|
|
|
|
newLevel();
|
|
_vm->_graphicsMan->updateScreen();
|
|
|
|
playBreakout();
|
|
_vm->_graphicsMan->resetDirtyRects();
|
|
_breakoutSpr = _vm->_globals->freeMemory(_breakoutSpr);
|
|
_breakoutLevel = (int16 *)_vm->_globals->freeMemory((byte *)_breakoutLevel);
|
|
_vm->_objectsMan->_sprite[0]._spriteData = oldSpriteData;
|
|
|
|
_vm->_soundMan->removeSample(1);
|
|
_vm->_soundMan->removeSample(2);
|
|
_vm->_soundMan->removeSample(3);
|
|
_vm->_globals->_speed = oldSpeed;
|
|
_vm->_events->_breakoutFl = false;
|
|
setVideoMode();
|
|
setTextColor(15);
|
|
clearScreen();
|
|
_vm->_graphicsMan->_maxX = 680;
|
|
_vm->_graphicsMan->_minY = 0;
|
|
_vm->_graphicsMan->_maxY = 460;
|
|
}
|
|
|
|
/**
|
|
* Load Highscore from file
|
|
*/
|
|
void ComputerManager::loadHiscore() {
|
|
byte *ptr = _vm->_globals->allocMemory(100);
|
|
memset(ptr, 0, 100);
|
|
|
|
if (_vm->_saveLoad->saveExists(_vm->getTargetName() + "-highscore.dat"))
|
|
_vm->_saveLoad->load(_vm->getTargetName() + "-highscore.dat", ptr);
|
|
|
|
for (int scoreIndex = 0; scoreIndex < 6; ++scoreIndex) {
|
|
_score[scoreIndex]._name = " ";
|
|
_score[scoreIndex]._score = " ";
|
|
|
|
for (int i = 0; i < 6; ++i) {
|
|
char nextChar = ptr[(16 * scoreIndex) + i];
|
|
if (!nextChar)
|
|
nextChar = ' ';
|
|
_score[scoreIndex]._name.setChar(nextChar, i);
|
|
}
|
|
|
|
for (int i = 0; i < 9; ++i) {
|
|
char nextChar = ptr[(scoreIndex * 16) + 6 + i];
|
|
if (!nextChar)
|
|
nextChar = '0';
|
|
_score[scoreIndex]._score.setChar(nextChar, i);
|
|
}
|
|
}
|
|
|
|
_lowestHiScore = atol(_score[5]._score.c_str());
|
|
_vm->_globals->freeMemory(ptr);
|
|
}
|
|
|
|
/**
|
|
* VGA 256 col
|
|
*/
|
|
void ComputerManager::setModeVGA256() {
|
|
_vm->_graphicsMan->clearScreen();
|
|
_vm->_graphicsMan->clearPalette();
|
|
_vm->_graphicsMan->setScreenWidth(320);
|
|
}
|
|
|
|
/**
|
|
* Load new level
|
|
*/
|
|
void ComputerManager::newLevel() {
|
|
_vm->_objectsMan->removeSprite(0);
|
|
_vm->_objectsMan->removeSprite(1);
|
|
++_breakoutLives;
|
|
if (_breakoutLives > 11)
|
|
_breakoutLives = 11;
|
|
_vm->_graphicsMan->loadVgaImage("CASSEF.PCX");
|
|
displayLives();
|
|
_breakoutLevel = (int16 *)_vm->_globals->freeMemory((byte *)_breakoutLevel);
|
|
|
|
++_breakoutLevelNbr;
|
|
Common::String file;
|
|
Common::File f;
|
|
while (!_vm->shouldQuit()) {
|
|
file = Common::String::format("TAB%d.TAB", _breakoutLevelNbr);
|
|
if (f.open(file))
|
|
break;
|
|
|
|
_breakoutLevelNbr = 1;
|
|
}
|
|
f.close();
|
|
|
|
_breakoutLevel = (int16 *)_vm->_fileIO->loadFile(file);
|
|
displayBricks();
|
|
|
|
_vm->_objectsMan->addStaticSprite(_breakoutSpr, Common::Point(150, 192), 0, 13, 0, false, 0, 0);
|
|
_vm->_objectsMan->addStaticSprite(_breakoutSpr, Common::Point(164, 187), 1, 14, 0, false, 0, 0);
|
|
|
|
_ballPosition = Common::Point(164, 187);
|
|
_padPositionX = 150;
|
|
_vm->_objectsMan->animateSprite(0);
|
|
_vm->_objectsMan->animateSprite(1);
|
|
|
|
_vm->_events->mouseOn();
|
|
_vm->_soundMan->playSample(3, 5);
|
|
}
|
|
|
|
/**
|
|
* Display bricks in breakout game
|
|
*/
|
|
void ComputerManager::displayBricks() {
|
|
_breakoutBrickNbr = 0;
|
|
_breakoutSpeed = 1;
|
|
int16 *level = _breakoutLevel;
|
|
|
|
for (int levelIdx = 0; ; levelIdx += 6) {
|
|
int cellLeft = (int16)FROM_LE_16(level[levelIdx]);
|
|
if (cellLeft == -1)
|
|
break;
|
|
int cellTop = FROM_LE_16(level[levelIdx + 1]);
|
|
int cellType = FROM_LE_16(level[levelIdx + 4]);
|
|
|
|
if (cellType <= 6)
|
|
++_breakoutBrickNbr;
|
|
|
|
switch (cellType) {
|
|
case 1:
|
|
_vm->_graphicsMan->fastDisplay2(_breakoutSpr, cellLeft, cellTop, 21);
|
|
break;
|
|
case 2:
|
|
_vm->_graphicsMan->fastDisplay2(_breakoutSpr, cellLeft, cellTop, 22);
|
|
break;
|
|
case 3:
|
|
_vm->_graphicsMan->fastDisplay2(_breakoutSpr, cellLeft, cellTop, 17);
|
|
break;
|
|
case 4:
|
|
_vm->_graphicsMan->fastDisplay2(_breakoutSpr, cellLeft, cellTop, 20);
|
|
break;
|
|
case 5:
|
|
_vm->_graphicsMan->fastDisplay2(_breakoutSpr, cellLeft, cellTop, 19);
|
|
break;
|
|
case 6:
|
|
_vm->_graphicsMan->fastDisplay2(_breakoutSpr, cellLeft, cellTop, 18);
|
|
break;
|
|
case 31:
|
|
_vm->_graphicsMan->fastDisplay2(_breakoutSpr, cellLeft, cellTop, 23);
|
|
break;
|
|
}
|
|
}
|
|
|
|
displayScore();
|
|
|
|
// Refresh the entire screen
|
|
_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
_vm->_graphicsMan->updateScreen();
|
|
}
|
|
|
|
/**
|
|
* Display Lives in breakout game
|
|
*/
|
|
void ComputerManager::displayLives() {
|
|
for (int i = 0, xp = 10; i <= 11; i++, xp += 7)
|
|
_vm->_graphicsMan->fastDisplay2(_breakoutSpr, xp, 10, 15);
|
|
|
|
for (int i = 0, xp = 10; i < _breakoutLives - 1; i++, xp += 7)
|
|
_vm->_graphicsMan->fastDisplay2(_breakoutSpr, xp, 10, 14);
|
|
|
|
_vm->_graphicsMan->updateScreen();
|
|
}
|
|
|
|
/**
|
|
* Main function for breakout game
|
|
*/
|
|
void ComputerManager::playBreakout() {
|
|
int lastBreakoutEvent = 0;
|
|
while (!_vm->shouldQuit()) {
|
|
while (!_vm->shouldQuit()) {
|
|
// Set up the racket and ball
|
|
_vm->_events->mouseOff();
|
|
_ballPosition = Common::Point(_padPositionX + 14, 187);
|
|
_vm->_objectsMan->setSpriteY(1, 187);
|
|
_vm->_objectsMan->setSpriteX(1, _ballPosition.x);
|
|
|
|
_vm->_graphicsMan->resetDirtyRects();
|
|
_vm->_events->refreshScreenAndEvents();
|
|
_vm->_graphicsMan->fadeInBreakout();
|
|
|
|
// Wait for mouse press to start playing
|
|
do {
|
|
_padPositionX = _vm->_events->getMouseX();
|
|
if (_vm->_events->_mousePos.x <= 4)
|
|
_padPositionX = 5;
|
|
if (_padPositionX > 282)
|
|
_padPositionX = 282;
|
|
_vm->_objectsMan->setSpriteX(0, _padPositionX);
|
|
_vm->_objectsMan->setSpriteX(1, _padPositionX + 14);
|
|
_vm->_objectsMan->setSpriteY(1, 187);
|
|
_vm->_events->refreshScreenAndEvents();
|
|
} while (!_vm->shouldQuit() && _vm->_events->getMouseButton() != 1);
|
|
|
|
_breakoutSpeed = 1;
|
|
_ballPosition = Common::Point(_padPositionX + 14, 187);
|
|
_ballRightFl = (_padPositionX > 135);
|
|
_ballUpFl = false;
|
|
|
|
// Play loop
|
|
do {
|
|
_vm->_soundMan->checkSounds();
|
|
|
|
_padPositionX = _vm->_events->getMouseX();
|
|
if (_vm->_events->_mousePos.x <= 4)
|
|
_padPositionX = 5;
|
|
if (_padPositionX > 282)
|
|
_padPositionX = 282;
|
|
_vm->_objectsMan->setSpriteX(0, _padPositionX);
|
|
lastBreakoutEvent = moveBall();
|
|
_vm->_events->refreshScreenAndEvents();
|
|
} while (!_vm->shouldQuit() && !lastBreakoutEvent);
|
|
if (lastBreakoutEvent != 1)
|
|
break;
|
|
|
|
--_breakoutLives;
|
|
|
|
if (_breakoutLives) {
|
|
displayLives();
|
|
if (_breakoutLives)
|
|
continue;
|
|
}
|
|
|
|
_vm->_graphicsMan->fadeOutBreakout();
|
|
_vm->_events->mouseOn();
|
|
_vm->_objectsMan->removeSprite(0);
|
|
_vm->_objectsMan->removeSprite(1);
|
|
if (_breakoutScore > _lowestHiScore)
|
|
getScoreName();
|
|
if (displayHiscores() != 1)
|
|
break;
|
|
|
|
_breakoutBrickNbr = 0;
|
|
_breakoutScore = 0;
|
|
_breakoutLives = 4;
|
|
_breakoutSpeed = 1;
|
|
_ballRightFl = false;
|
|
_ballUpFl = false;
|
|
_breakoutLevelNbr = 0;
|
|
loadHiscore();
|
|
newLevel();
|
|
}
|
|
if (lastBreakoutEvent != 2)
|
|
return;
|
|
_vm->_graphicsMan->fadeOutBreakout();
|
|
newLevel();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show the high scores for the Breakout game
|
|
* @return The selected button index: 1 = Game, 2 = Quit
|
|
*/
|
|
int ComputerManager::displayHiscores() {
|
|
_vm->_graphicsMan->resetDirtyRects();
|
|
loadHiscore();
|
|
_vm->_graphicsMan->loadVgaImage("HISCORE.PCX");
|
|
byte *ptr = _vm->_fileIO->loadFile("ALPHA.SPR");
|
|
_vm->_graphicsMan->setColorPercentage(252, 100, 100, 100);
|
|
_vm->_graphicsMan->setColorPercentage(253, 100, 100, 100);
|
|
_vm->_graphicsMan->setColorPercentage(251, 100, 100, 100);
|
|
_vm->_graphicsMan->setColorPercentage(254, 0, 0, 0);
|
|
|
|
int yp;
|
|
// Loop for displaying the scores
|
|
for (int scoreIndex = 0; scoreIndex <= 5; scoreIndex++) {
|
|
yp = 19 * scoreIndex;
|
|
yp += 46;
|
|
|
|
// Display the characters of the name
|
|
for (int i = 0; i < 6; i++)
|
|
displayHiscoreLine(ptr, 9 * i + 69, yp, _score[scoreIndex]._name[i]);
|
|
|
|
// Display the digits of the score
|
|
for (int i = 0; i < 9; i++)
|
|
displayHiscoreLine(ptr, 9 * i + 199, yp, _score[scoreIndex]._score[i]);
|
|
}
|
|
|
|
_vm->_graphicsMan->fadeInBreakout();
|
|
_vm->_graphicsMan->resetDirtyRects();
|
|
int buttonIndex = 0;
|
|
do {
|
|
_vm->_events->refreshEvents();
|
|
int xp = _vm->_events->getMouseX();
|
|
yp = _vm->_events->getMouseY();
|
|
|
|
if (_vm->_events->getMouseButton() == 1 && ABS(xp - 79) <= 33 && ABS(yp - 396) <= 13)
|
|
buttonIndex = 1;
|
|
else if (_vm->_events->getMouseButton() == 1 && ABS(xp - 583) <= 32 && ABS(yp - 396) <= 13)
|
|
buttonIndex = 2;
|
|
|
|
_vm->_events->refreshScreenAndEvents();
|
|
} while (!buttonIndex && !_vm->shouldQuit());
|
|
|
|
_vm->_events->mouseOff();
|
|
_vm->_graphicsMan->fadeOutBreakout();
|
|
_vm->_globals->freeMemory(ptr);
|
|
return buttonIndex;
|
|
}
|
|
|
|
/**
|
|
* Display a screen to enter player name in the case of a new hiscore
|
|
*/
|
|
void ComputerManager::getScoreName() {
|
|
_vm->_graphicsMan->loadVgaImage("NAME.PCX");
|
|
_vm->_graphicsMan->setColorPercentage(252, 100, 100, 100);
|
|
_vm->_graphicsMan->setColorPercentage(253, 100, 100, 100);
|
|
_vm->_graphicsMan->setColorPercentage(251, 100, 100, 100);
|
|
_vm->_graphicsMan->setColorPercentage(254, 0, 0, 0);
|
|
byte *ptr = _vm->_fileIO->loadFile("ALPHA.SPR");
|
|
_vm->_graphicsMan->fadeInBreakout();
|
|
|
|
// Figure out the line to put the new high score on
|
|
int scoreLine = 0;
|
|
while (scoreLine < 5 && _breakoutScore < atol(_score[scoreLine]._score.c_str()))
|
|
++scoreLine;
|
|
|
|
// If it's not the lasat line, move the lines down
|
|
for (int line = 5; line > scoreLine; --line) {
|
|
_score[line]._name = _score[line - 1]._name;
|
|
_score[line]._score = _score[line - 1]._score;
|
|
}
|
|
|
|
// Get the name for the new high score
|
|
for (int strPos = 0; strPos <= 4; strPos++) {
|
|
displayHiscoreLine(ptr, 9 * strPos + 140, 78, 1);
|
|
|
|
char curChar = toupper(_vm->_events->waitKeyPress());
|
|
if ((curChar < '0') || (curChar > 'Z'))
|
|
curChar = ' ';
|
|
if ((curChar > '9') && (curChar < 'A'))
|
|
curChar = ' ';
|
|
|
|
_score[scoreLine]._name.setChar(curChar, strPos);
|
|
displayHiscoreLine(ptr, 9 * strPos + 140, 78, curChar);
|
|
|
|
for (int idx = 0; idx < 12; ++idx)
|
|
_vm->_events->refreshScreenAndEvents();
|
|
}
|
|
|
|
// Set up the new score
|
|
_score[scoreLine]._score = " ";
|
|
|
|
char score[16];
|
|
sprintf(score, "%d", _breakoutScore);
|
|
int scoreLen = 0;
|
|
do
|
|
++scoreLen;
|
|
while (score[scoreLen]);
|
|
|
|
for (int i = scoreLen - 1, scorePos = 8; i >= 0; i--) {
|
|
_score[scoreLine]._score.setChar(score[i], scorePos--);
|
|
}
|
|
_vm->_graphicsMan->fadeOutBreakout();
|
|
_vm->_globals->freeMemory(ptr);
|
|
saveScore();
|
|
}
|
|
|
|
/**
|
|
* Display current score
|
|
*/
|
|
void ComputerManager::displayScore() {
|
|
Common::String scoreStr = Common::String::format("%d", _breakoutScore);
|
|
int strSize = scoreStr.size();
|
|
for (int i = strSize - 1, idx = 0; i >= 0; i--) {
|
|
displayScoreChar(idx++, scoreStr[i]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Display a character of the score
|
|
*/
|
|
void ComputerManager::displayScoreChar(int charPos, int charDisp) {
|
|
int xp;
|
|
switch (charPos) {
|
|
case 1:
|
|
xp = 190;
|
|
break;
|
|
case 2:
|
|
xp = 180;
|
|
break;
|
|
case 3:
|
|
xp = 167;
|
|
break;
|
|
case 4:
|
|
xp = 157;
|
|
break;
|
|
case 5:
|
|
xp = 147;
|
|
break;
|
|
case 9:
|
|
xp = 134;
|
|
break;
|
|
default:
|
|
xp = 200;
|
|
break;
|
|
}
|
|
|
|
int idx = 3;
|
|
if (charDisp >= '0' && charDisp <= '9')
|
|
idx = charDisp - 45;
|
|
|
|
_vm->_graphicsMan->fastDisplay2(_breakoutSpr, xp, 11, idx);
|
|
}
|
|
|
|
/**
|
|
* Save Hiscore in file
|
|
*/
|
|
void ComputerManager::saveScore() {
|
|
int scores[6];
|
|
// Load high scores in an array
|
|
for (int i = 0; i <= 5; i++) {
|
|
scores[i] = atol(_score[i]._score.c_str());
|
|
if (!scores[i])
|
|
scores[i] = 5;
|
|
}
|
|
|
|
int scorePlace[6];
|
|
// order high scores
|
|
for (int scorePlaceIdx = 0; scorePlaceIdx <= 5; scorePlaceIdx++) {
|
|
for(int i = 0;;i++) {
|
|
int curScore = scores[i];
|
|
if (curScore && scores[0] <= curScore && scores[1] <= curScore && scores[2] <= curScore && scores[3] <= curScore
|
|
&& scores[4] <= curScore && scores[5] <= curScore) {
|
|
scorePlace[scorePlaceIdx] = i;
|
|
scores[i] = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
byte *ptr = _vm->_globals->allocMemory(100);
|
|
memset(ptr, 0, 100);
|
|
for (int scorePlaceIdx = 0; scorePlaceIdx <= 5; scorePlaceIdx++) {
|
|
int curBufPtr = 16 * scorePlaceIdx;
|
|
for (int namePos = 0; namePos < 6; namePos++) {
|
|
char curChar = _score[scorePlace[scorePlaceIdx]]._name[namePos];
|
|
if (!curChar)
|
|
curChar = ' ';
|
|
ptr[curBufPtr + namePos] = curChar;
|
|
};
|
|
|
|
ptr[curBufPtr + 5] = 0;
|
|
|
|
for (int scorePos = 0; scorePos <= 8; scorePos++) {
|
|
char curChar = _score[scorePlace[scorePlaceIdx]]._score[scorePos];
|
|
if (!curChar)
|
|
curChar = '0';
|
|
ptr[curBufPtr + 6 + scorePos] = curChar;
|
|
};
|
|
ptr[curBufPtr + 15] = 0;
|
|
}
|
|
|
|
_vm->_saveLoad->saveFile(_vm->getTargetName() + "-highscore.dat", ptr, 100);
|
|
_vm->_globals->freeMemory(ptr);
|
|
}
|
|
|
|
/**
|
|
* Display parts of the hiscore line
|
|
*/
|
|
void ComputerManager::displayHiscoreLine(const byte *objectData, int x, int y, int curChar) {
|
|
int idx = 36;
|
|
|
|
if (curChar == 100)
|
|
idx = 0;
|
|
else if (curChar >= '0' && curChar <= '9')
|
|
idx = curChar - '0';
|
|
else if (curChar >= 'A' && curChar <= 'Z')
|
|
idx = curChar - 'A' + 10;
|
|
else if (curChar == 1)
|
|
idx = 37;
|
|
_vm->_graphicsMan->fastDisplay2(objectData, x, y, idx);
|
|
}
|
|
|
|
/**
|
|
* Handle ball moves
|
|
*/
|
|
int ComputerManager::moveBall() {
|
|
//(signed int)(6.0 * (long double)_vm->getRandomNumber( rand() / 2147483648.0) + 1;
|
|
// TODO: Figure out random number
|
|
int randVal = _vm->getRandomNumber(6);
|
|
switch (_breakoutSpeed) {
|
|
case 1:
|
|
_minBreakoutMoveSpeed = 1;
|
|
_maxBreakoutMoveSpeed = 1;
|
|
break;
|
|
case 2:
|
|
_minBreakoutMoveSpeed = 1;
|
|
_maxBreakoutMoveSpeed = 2;
|
|
break;
|
|
case 3:
|
|
_minBreakoutMoveSpeed = 2;
|
|
_maxBreakoutMoveSpeed = 2;
|
|
break;
|
|
case 4:
|
|
_minBreakoutMoveSpeed = 3;
|
|
_maxBreakoutMoveSpeed = 2;
|
|
break;
|
|
}
|
|
|
|
int moveSpeed = _minBreakoutMoveSpeed;
|
|
if (_lastBreakoutMoveSpeed == _minBreakoutMoveSpeed)
|
|
moveSpeed = _maxBreakoutMoveSpeed;
|
|
|
|
if (_ballUpFl)
|
|
_ballPosition.y += moveSpeed;
|
|
else
|
|
_ballPosition.y -= moveSpeed;
|
|
|
|
if (_ballRightFl)
|
|
_ballPosition.x += moveSpeed;
|
|
else
|
|
_ballPosition.x -= moveSpeed;
|
|
|
|
_lastBreakoutMoveSpeed = moveSpeed;
|
|
if (_ballPosition.x <= 6) {
|
|
_vm->_soundMan->playSample(2, 6);
|
|
_ballPosition.x = randVal + 6;
|
|
_ballRightFl = !_ballRightFl;
|
|
} else if (_ballPosition.x > 307) {
|
|
_vm->_soundMan->playSample(2, 6);
|
|
_ballPosition.x = 307 - randVal;
|
|
_ballRightFl = !_ballRightFl;
|
|
}
|
|
|
|
if (_ballPosition.y <= 6) {
|
|
_vm->_soundMan->playSample(2, 6);
|
|
_ballPosition.y = randVal + 7;
|
|
_ballUpFl = !_ballUpFl;
|
|
} else if (_ballPosition.y >= 186 && _ballPosition.y <= 194) {
|
|
_vm->_soundMan->playSample(2, 6);
|
|
int ballPosXRight = _ballPosition.x + 6;
|
|
if ((_ballPosition.x > _padPositionX - 2) && (ballPosXRight < _padPositionX + 36)) {
|
|
_ballUpFl = false;
|
|
if (ballPosXRight <= _padPositionX + 15) {
|
|
_ballRightFl = false;
|
|
if (_ballPosition.x >= _padPositionX && ballPosXRight <= _padPositionX + 5)
|
|
_ballPosition.x -= 4;
|
|
if (_ballPosition.x >= _padPositionX + 5 && _ballPosition.x + 6 <= _padPositionX + 10)
|
|
_ballPosition.x -= 2;
|
|
}
|
|
if (_ballPosition.x >= _padPositionX + 19 && _ballPosition.x + 6 <= _padPositionX + 36) {
|
|
_ballRightFl = true;
|
|
if (_ballPosition.x >= _padPositionX + 29)
|
|
_ballPosition.x += 4;
|
|
if (_ballPosition.x >= _padPositionX + 24 && _ballPosition.x + 6 <= _padPositionX + 29)
|
|
_ballPosition.x += 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
int retVal = 0;
|
|
if (_ballPosition.y > 194)
|
|
retVal = 1;
|
|
checkBallCollisions();
|
|
_vm->_objectsMan->setSpriteX(1, _ballPosition.x);
|
|
_vm->_objectsMan->setSpriteY(1, _ballPosition.y);
|
|
if (!_breakoutBrickNbr)
|
|
retVal = 2;
|
|
return retVal;
|
|
}
|
|
|
|
/**
|
|
* Check ball collision with bricks
|
|
*/
|
|
void ComputerManager::checkBallCollisions() {
|
|
int cellLeft;
|
|
|
|
bool brickDestroyedFl = false;
|
|
// TODO: Check if correct
|
|
int randVal = _vm->getRandomNumber(6) + 1;
|
|
int ballLeft = _ballPosition.x;
|
|
int ballTop = _ballPosition.y;
|
|
int ballRight = _ballPosition.x + 6;
|
|
int ballBottom = _ballPosition.y + 6;
|
|
int16 *level = _breakoutLevel;
|
|
uint16 levelIdx = 0;
|
|
do {
|
|
cellLeft = level[levelIdx];
|
|
int cellUp = level[levelIdx + 1];
|
|
int cellRight = level[levelIdx + 2];
|
|
int cellBottom = level[levelIdx + 3];
|
|
int cellType = level[levelIdx + 4];
|
|
if (level[levelIdx + 5] == 1 && cellLeft != -1) {
|
|
bool collisionFl = false;
|
|
if (ballTop <= cellBottom && ballBottom >= cellBottom) {
|
|
if (ballLeft >= cellLeft && ballRight <= cellRight) {
|
|
collisionFl = true;
|
|
_ballUpFl = true;
|
|
}
|
|
if ((ballRight >= cellLeft) && (ballLeft <= cellLeft)) {
|
|
collisionFl = true;
|
|
_ballUpFl = true;
|
|
_ballRightFl = false;
|
|
if (cellType == 31)
|
|
_ballPosition.x -= randVal;
|
|
}
|
|
if ((ballLeft <= cellRight) && (ballRight >= cellRight)) {
|
|
collisionFl = true;
|
|
_ballUpFl = true;
|
|
_ballRightFl = true;
|
|
if (cellType == 31)
|
|
_ballPosition.x += randVal;
|
|
}
|
|
}
|
|
if (ballBottom >= cellUp && ballTop <= cellUp) {
|
|
if (ballLeft >= cellLeft && ballRight <= cellRight) {
|
|
collisionFl = true;
|
|
_ballUpFl = false;
|
|
}
|
|
if ((ballRight >= cellLeft) && (ballLeft <= cellLeft)) {
|
|
collisionFl = true;
|
|
_ballUpFl = false;
|
|
_ballRightFl = false;
|
|
if (cellType == 31)
|
|
_ballPosition.x -= 2;
|
|
}
|
|
if ((ballLeft <= cellRight) && (ballRight >= cellRight)) {
|
|
collisionFl = true;
|
|
_ballUpFl = false;
|
|
_ballRightFl = true;
|
|
if (cellType == 31)
|
|
_ballPosition.x += randVal;
|
|
}
|
|
}
|
|
if ((ballTop >= cellUp) && (ballBottom <= cellBottom)) {
|
|
if ((ballRight >= cellLeft) && (ballLeft <= cellLeft)) {
|
|
collisionFl = true;
|
|
_ballRightFl = false;
|
|
if (cellType == 31)
|
|
_ballPosition.x -= randVal;
|
|
}
|
|
if ((ballLeft <= cellRight) && (ballRight >= cellRight)) {
|
|
collisionFl = true;
|
|
_ballRightFl = true;
|
|
if (cellType == 31)
|
|
_ballPosition.x += randVal;
|
|
}
|
|
}
|
|
if (collisionFl) {
|
|
if (cellType == 31) {
|
|
_vm->_soundMan->playSample(2, 6);
|
|
} else {
|
|
_vm->_soundMan->playSample(1, 5);
|
|
_vm->_graphicsMan->fastDisplay2(_breakoutSpr, cellLeft, cellUp, 16);
|
|
switch (cellType) {
|
|
case 1:
|
|
_breakoutScore += 10;
|
|
break;
|
|
case 2:
|
|
_breakoutScore += 5;
|
|
break;
|
|
case 3:
|
|
_breakoutScore += 50;
|
|
if (_breakoutSpeed <= 1)
|
|
_breakoutSpeed = 2;
|
|
if (_breakoutBrickNbr <= 19)
|
|
_breakoutSpeed = 3;
|
|
break;
|
|
case 4:
|
|
_breakoutScore += 20;
|
|
break;
|
|
case 5:
|
|
_breakoutScore += 30;
|
|
if (_breakoutSpeed <= 1)
|
|
_breakoutSpeed = 2;
|
|
break;
|
|
case 6:
|
|
_breakoutScore += 40;
|
|
break;
|
|
}
|
|
displayScore();
|
|
--_breakoutBrickNbr;
|
|
level[levelIdx + 5] = 0;
|
|
brickDestroyedFl = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (brickDestroyedFl)
|
|
cellLeft = -1;
|
|
levelIdx += 6;
|
|
} while (cellLeft != -1);
|
|
}
|
|
|
|
} // End of namespace Hopkins
|