Add inital pause code for Elvira 1/2 & WW, and cleanup

svn-id: r24723
This commit is contained in:
Travis Howell 2006-11-15 13:11:53 +00:00
parent 7b0e6f1489
commit f55320f988
11 changed files with 443 additions and 144 deletions

View File

@ -698,10 +698,6 @@ protected:
// Waxworks specific
void moveDirn_ww(Item *i, uint x);
int16 levelOf(Item *item);
int16 moreText(Item *i);
void lobjFunc(Item *i, const char *f);
int canPlace(Item *x, Item *y);
int contains(Item *a, Item *b);
int sizeContents(Item *x);
@ -779,6 +775,7 @@ protected:
void closeWindow(uint a);
void setTextColor(uint color);
void windowPutChar(WindowBlock *window, byte c, byte b = 0);
void waitWindow(WindowBlock *window);
HitArea *findBox(uint hitarea_id);
void boxController(uint x, uint y, uint mode);
@ -1068,7 +1065,6 @@ public:
void o_setAdjNoun();
void o_saveUserGame();
void o_loadUserGame();
void o_pauseGame();
void o_copysf();
void o_restoreIcons();
void o_freezeZones();
@ -1130,9 +1126,16 @@ public:
void oe1_stopTune();
void oe1_printPlayerDamage();
void oe1_printMonsterDamage();
void oe1_pauseGame();
void oe1_printPlayerHit();
void oe1_printMonsterHit();
int16 levelOf(Item *item);
int16 moreText(Item *i);
void lobjFunc(Item *i, const char *f);
uint confirmQuit();
uint continueOrQuit();
void printScroll();
void synchChain(Item *i);
// Opcodes, Elvira 2
@ -1142,6 +1145,7 @@ public:
void oe2_loadGame();
void oe2_drawItem();
void oe2_doTable();
void oe2_pauseGame();
void oe2_setDoorOpen();
void oe2_setDoorClosed();
void oe2_setDoorLocked();
@ -1186,6 +1190,7 @@ public:
void oww_whereTo();
void oww_menu();
void oww_textMenu();
void oww_pauseGame();
void oww_boxMessage();
void oww_boxMsg();
void oww_boxLongText();
@ -1198,6 +1203,7 @@ public:
void oww_printLongText();
void os1_animate();
void os1_playTune();
void os1_pauseGame();
void os1_screenTextBox();
void os1_screenTextMsg();
void os1_playEffect();
@ -1376,7 +1382,7 @@ protected:
void fillBackFromFront(uint x, uint y, uint w, uint h);
void print_char_helper_1(const byte *src, uint len);
void print_char_helper_5(WindowBlock *window);
void clsCheck(WindowBlock *window);
void quickLoadOrSave();
void shutdown();

View File

@ -72,7 +72,7 @@ void AGOSEngine::print_char_helper_1(const byte *src, uint len) {
}
}
void AGOSEngine::print_char_helper_5(WindowBlock *window) {
void AGOSEngine::clsCheck(WindowBlock *window) {
uint index = getWindowNum(window);
tidyIconArray(index);
_fcsData1[index] = 0;
@ -311,6 +311,13 @@ void AGOSEngine::showMessageFormat(const char *s, ...) {
va_end(va);
if (!_fcsData1[_curWindow]) {
if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
if (_showMessageFlag) {
if (_windowArray[_curWindow]->flags & 128) {
haltAnimation();
}
}
}
openTextWindow();
if (!_showMessageFlag) {
_windowArray[0] = _textWindow;
@ -343,7 +350,7 @@ void AGOSEngine::justifyOutPut(byte chr) {
_printCharCurPos = 0;
_printCharPixelCount = 0;
print_char_helper_1(&chr, 1);
print_char_helper_5(_textWindow);
clsCheck(_textWindow);
} else if (chr == 0 || chr == ' ' || chr == 10) {
bool fit;

View File

@ -426,16 +426,35 @@ void AGOSEngine::hitarea_stuff_helper_2() {
}
void AGOSEngine::permitInput() {
if (!_mortalFlag) {
_mortalFlag = true;
justifyOutPut(0);
_curWindow = 0;
if (_windowArray[0] != 0) {
_textWindow = _windowArray[0];
justifyStart();
if (!_mortalFlag)
return;
_mortalFlag = true;
justifyOutPut(0);
if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
int n = 0;
while (n < 8) {
if ((_fcsData1[n]) && (_windowArray[n]) && (_windowArray[n]->flags & 128)) {
_textWindow = _windowArray[n];
waitWindow(_textWindow);
clsCheck(_textWindow);
}
_fcsData1[n]=0;
n++;
}
_mortalFlag = false;
restartAnimation();
}
_curWindow = 0;
if (_windowArray[0] != 0) {
_textWindow = _windowArray[0];
justifyStart();
}
_mortalFlag = false;
}
bool AGOSEngine::processSpecialKeys() {

View File

@ -465,119 +465,89 @@ void AGOSEngine::userGameBackSpace(WindowBlock *window, int x, byte b) {
}
void AGOSEngine::fileError(WindowBlock *window, bool save_error) {
HitArea *ha;
const char *string1, *string2;
const char *message1, *message2;
if (save_error) {
switch (_language) {
case Common::RU_RUS:
if (getGameType() == GType_SIMON2) {
string1 = "\r Mf sowrap+fts+.";
string2 = "\r Nzjb#a ejs#a.";
message1 = "\r Mf sowrap+fts+.";
message2 = "\r Nzjb#a ejs#a.";
} else {
string1 = "\r Mf sowrap]fts].";
string2 = "\r Nzjb_a ejs_a.";
message1 = "\r Mf sowrap]fts].";
message2 = "\r Nzjb_a ejs_a.";
}
break;
case Common::PL_POL:
string1 = "\r Blad zapisu. ";
string2 = "\rBlad dysku. ";
message1 = "\r Blad zapisu. ";
message2 = "\rBlad dysku. ";
break;
case Common::ES_ESP:
string1 = "\r Error al salvar";
string2 = "\r Intenta con otro disco";
message1 = "\r Error al salvar";
message2 = "\r Intenta con otro disco";
break;
case Common::IT_ITA:
string1 = "\r Salvataggio non riuscito";
string2 = "\r Prova un""\x27""altro disco";
message1 = "\r Salvataggio non riuscito";
message2 = "\r Prova un""\x27""altro disco";
break;
case Common::FR_FRA:
string1 = "\r Echec sauvegarde";
string2 = "\rEssayez une autre disquette";
message1 = "\r Echec sauvegarde";
message2 = "\rEssayez une autre disquette";
break;
case Common::DE_DEU:
string1 = "\r Sicherung erfolglos.";
string2 = "\rVersuche eine andere Diskette.";
message1 = "\r Sicherung erfolglos.";
message2 = "\rVersuche eine andere Diskette.";
break;
default:
string1 = "\r Save failed.";
string2 = "\r Disk error.";
message1 = "\r Save failed.";
message2 = "\r Disk error.";
break;
}
} else {
switch (_language) {
case Common::RU_RUS:
if (getGameType() == GType_SIMON2) {
string1 = "\r Mf ^adruhafts+.";
string2 = "\r Takm pf pakefp.";
message1 = "\r Mf ^adruhafts+.";
message2 = "\r Takm pf pakefp.";
} else {
string1 = "\r Mf ^adruhafts].";
string2 = "\r Takm pf pakefp.";
message1 = "\r Mf ^adruhafts].";
message2 = "\r Takm pf pakefp.";
}
break;
case Common::PL_POL:
string1 = "\r Blad odczytu. ";
string2 = "\r Nie znaleziono pliku.";
message1 = "\r Blad odczytu. ";
message2 = "\r Nie znaleziono pliku.";
break;
case Common::ES_ESP:
string1 = "\r Error al cargar";
string2 = "\r Archivo no encontrado";
message1 = "\r Error al cargar";
message2 = "\r Archivo no encontrado";
break;
case Common::IT_ITA:
string1 = "\r Caricamento non riuscito";
string2 = "\r File non trovato";
message1 = "\r Caricamento non riuscito";
message2 = "\r File non trovato";
break;
case Common::FR_FRA:
string1 = "\r Echec chargement";
string2 = "\r Fichier introuvable";
message1 = "\r Echec chargement";
message2 = "\r Fichier introuvable";
break;
case Common::DE_DEU:
string1 = "\r Laden erfolglos.";
string2 = "\r Datei nicht gefunden.";
message1 = "\r Laden erfolglos.";
message2 = "\r Datei nicht gefunden.";
break;
default:
string1 = "\r Load failed.";
string2 = "\r File not found.";
message1 = "\r Load failed.";
message2 = "\r File not found.";
break;
}
}
windowPutChar(window, 0xC);
for (; *string1; string1++)
windowPutChar(window, *string1);
for (; *string2; string2++)
windowPutChar(window, *string2);
for (; *message1; message1++)
windowPutChar(window, *message1);
for (; *message2; message2++)
windowPutChar(window, *message2);
window->textColumn = (window->width / 2) - 3;
window->textRow = window->height - 1;
window->textLength = 0;
string1 = "[ OK ]";
for (; *string1; string1++)
windowPutChar(window, *string1);
ha = findEmptyHitArea();
ha->x = ((window->width / 2) + (window->x - 3)) * 8;
ha->y = (window->height * 8) + window->y - 8;
ha->width = 48;
ha->height = 8;
ha->flags = kBFBoxInUse;
ha->id = 0x7FFF;
ha->priority = 0x3EF;
loop:;
_lastHitArea = _lastHitArea3 = 0;
do {
delay(1);
} while (_lastHitArea3 == 0);
ha = _lastHitArea;
if (ha == NULL || ha->id != 0x7FFF)
goto loop;
// Return
undefineBox(0x7FFF);
waitWindow(window);
}
uint16 readItemID(Common::SeekableReadStream *f) {

View File

@ -122,7 +122,6 @@ void AGOSEngine::setupCommonOpcodes(OpcodeProc *op) {
op[130] = &AGOSEngine::o_setAdjNoun;
op[132] = &AGOSEngine::o_saveUserGame;
op[133] = &AGOSEngine::o_loadUserGame;
op[135] = &AGOSEngine::o_pauseGame;
op[136] = &AGOSEngine::o_copysf;
op[137] = &AGOSEngine::o_restoreIcons;
op[138] = &AGOSEngine::o_freezeZones;
@ -851,60 +850,6 @@ void AGOSEngine::o_loadUserGame() {
_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
}
void AGOSEngine::o_pauseGame() {
// 135: pause game
_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
// If all else fails, use English as fallback.
byte keyYes = 'y';
byte keyNo = 'n';
switch (_language) {
case Common::RU_RUS:
break;
case Common::PL_POL:
keyYes = 't';
break;
case Common::HB_ISR:
keyYes = 'f';
break;
case Common::ES_ESP:
keyYes = 's';
break;
case Common::IT_ITA:
keyYes = 's';
break;
case Common::FR_FRA:
keyYes = 'o';
break;
case Common::DE_DEU:
keyYes = 'j';
break;
default:
break;
}
for (;;) {
delay(1);
#ifdef _WIN32_WCE
if (isSmartphone()) {
if (_keyPressed) {
if (_keyPressed == 13)
shutdown();
else
break;
}
}
#endif
if (_keyPressed == keyYes || _keyPressed == (keyYes - 32))
shutdown();
else if (_keyPressed == keyNo || _keyPressed == (keyNo - 32))
break;
}
_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
}
void AGOSEngine::o_copysf() {
// 136: set var to item unk3
Item *item = getNextItemPtr();
@ -1056,7 +1001,6 @@ int AGOSEngine::runScript() {
if (opcode == 0xFF)
return 0;
}
debug(1, "runScript: opcode %d", opcode);
if (_runScriptReturn1)
return 1;
@ -1067,7 +1011,6 @@ int AGOSEngine::runScript() {
if (opcode == 203) {
flag = true;
opcode = getVarOrWord();
debug(1, "runScript: opcode %d", opcode);
if (opcode == 10000)
return 0;
}
@ -1075,8 +1018,6 @@ int AGOSEngine::runScript() {
if (opcode == 0) {
flag = true;
opcode = getByte();
debug(1, "runScript: opcode %d", opcode);
if (opcode == 0xFF)
return 0;
}

View File

@ -24,6 +24,7 @@
#include "common/stdafx.h"
#include "agos/agos.h"
#include "agos/vga.h"
namespace AGOS {
@ -161,7 +162,7 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) {
op[271] = &AGOSEngine::oe1_stopTune;
op[272] = &AGOSEngine::oe1_printPlayerDamage;
op[273] = &AGOSEngine::oe1_printMonsterDamage;
op[274] = &AGOSEngine::o_pauseGame;
op[274] = &AGOSEngine::oe1_pauseGame;
op[275] = &AGOSEngine::o_copysf;
op[276] = &AGOSEngine::o_restoreIcons;
op[277] = &AGOSEngine::oe1_printPlayerHit;
@ -716,6 +717,77 @@ void AGOSEngine::oe1_printMonsterDamage() {
mouseOn();
}
void AGOSEngine::oe1_pauseGame() {
// 274: pause game
WindowBlock *window = _windowArray[4];
const char *message1, *message2;
time_t pauseTime = time(NULL);
haltAnimation();
restart:
printScroll();
window->textColumn = 0;
window->textRow = 0;
window->textColumnOffset = 0;
switch (_language) {
case Common::FR_FRA:
message1 = " Jeu interrompu.\r\r\r";
message2 = " Reprendre Quitter";
break;
case Common::DE_DEU:
message1 = " Pause.\r\r\r";
message2 = " Weiter Ende";
break;
default:
message1 = " Game Paused\r\r\r";
message2 = " Continue Quit";
break;
}
for (; *message1; message1++)
windowPutChar(window, *message1);
for (; *message2; message2++)
windowPutChar(window, *message2);
if (continueOrQuit() == 0x7FFE) {
printScroll();
window->textColumn = 0;
window->textRow = 0;
window->textColumnOffset = 0;
switch (_language) {
case Common::FR_FRA:
message1 = " Etes-vous s<r ?\r\r\r";
message2 = " Oui Non";
break;
case Common::DE_DEU:
message1 = " Bist Du sicher ?\r\r\r";
message2 = " Ja Nein";
break;
default:
message1 = " Are you sure ?\r\r\r";
message2 = " Yes No";
break;
}
for (; *message1; message1++)
windowPutChar(window, *message1);
for (; *message2; message2++)
windowPutChar(window, *message2);
if (confirmQuit() == 0x7FFF) {
shutdown();
} else {
goto restart;
}
}
restartAnimation();
_gameStoppedClock = time(NULL) - pauseTime + _gameStoppedClock;
}
void AGOSEngine::oe1_printPlayerHit() {
// 277: print player hit
WindowBlock *window = _dummyWindow;
@ -792,4 +864,129 @@ l1: i = derefItem(i->next);
}
}
uint AGOSEngine::confirmQuit() {
HitArea *ha;
ha = findEmptyHitArea();
ha->x = 120;
ha->y = 62;
ha->width = 30;
ha->height = 12;
ha->flags = kBFBoxInUse;
ha->id = 0x7FFF;
ha->priority = 999;
ha->window = 0;
ha = findEmptyHitArea();
ha->x = 180;
ha->y = 62;
ha->width = 24;
ha->height = 12;
ha->flags = kBFBoxInUse;
ha->id = 0x7FFE;
ha->priority = 999;
ha->window = 0;
for (;;) {
_lastHitArea = NULL;
_lastHitArea3 = NULL;
for (;;) {
if (_lastHitArea3 != 0)
break;
delay(1);
}
ha = _lastHitArea;
if (ha == NULL) {
} else if (ha->id == 0x7FFE) {
break;
} else if (ha->id == 0x7FFF) {
break;
}
}
undefineBox(0x7FFF);
undefineBox(0x7FFE);
return ha->id;
}
uint AGOSEngine::continueOrQuit() {
HitArea *ha;
ha = findEmptyHitArea();
ha->x = 96;
ha->y = 62;
ha->width = 60;
ha->height = 12;
ha->flags = kBFBoxInUse;
ha->id = 0x7FFF;
ha->priority = 999;
ha->window = 0;
ha = findEmptyHitArea();
ha->x = 180;
ha->y = 62;
ha->width = 36;
ha->height = 12;
ha->flags = kBFBoxInUse;
ha->id = 0x7FFE;
ha->priority = 999;
ha->window = 0;
for (;;) {
_lastHitArea = NULL;
_lastHitArea3 = NULL;
for (;;) {
if (_lastHitArea3 != 0)
break;
delay(1);
}
ha = _lastHitArea;
if (ha == NULL) {
} else if (ha->id == 0x7FFE) {
break;
} else if (ha->id == 0x7FFF) {
break;
}
}
undefineBox(0x7FFF);
undefineBox(0x7FFE);
return ha->id;
}
void AGOSEngine::printScroll() {
VC10_state state;
VgaPointersEntry *vpe = &_vgaBufferPointers[1];
state.depack_src = vpe->vgaFile2 + READ_BE_UINT32(vpe->vgaFile2 + 9 * 8);
state.palette = 0;
state.x = 10;
state.y = 32;
state.width = state.draw_width = 10;
state.height = state.draw_height = 72;
state.flags = kDFCompressed | kDFUseFrontBuf;
_windowNum = 3;
state.depack_cont = -0x80;
state.x_skip = 0;
state.y_skip = 0;
state.surf2_addr = getFrontBuf();
state.surf2_pitch = _dxSurfacePitch;
state.surf_addr = getBackBuf();
state.surf_pitch = _dxSurfacePitch;
drawImages(&state);
}
} // End of namespace AGOS

View File

@ -57,6 +57,7 @@ void AGOSEngine::setupElvira2Opcodes(OpcodeProc *op) {
op[123] = &AGOSEngine::oe1_setTime;
op[124] = &AGOSEngine::oe1_ifTime;
op[127] = &AGOSEngine::os1_playTune;
op[135] = &AGOSEngine::oe2_pauseGame;
op[144] = &AGOSEngine::oe2_setDoorOpen;
op[145] = &AGOSEngine::oe2_setDoorClosed;
op[146] = &AGOSEngine::oe2_setDoorLocked;
@ -171,6 +172,35 @@ void AGOSEngine::oe2_doTable() {
}
}
void AGOSEngine::oe2_pauseGame() {
// 135: pause game
HitArea *ha;
time_t pauseTime = time(NULL);
haltAnimation();
for (;;) {
_lastHitArea = NULL;
_lastHitArea3 = NULL;
for (;;) {
if (processSpecialKeys() != 0 || _lastHitArea3 != 0)
break;
delay(1);
}
ha = _lastHitArea;
if (ha == NULL) {
} else if (ha->id == 201) {
break;
}
}
restartAnimation();
_gameStoppedClock = time(NULL) - pauseTime + _gameStoppedClock;
}
void AGOSEngine::oe2_setDoorOpen() {
// 144: set door open
Item *i = getNextItemPtr();

View File

@ -42,6 +42,7 @@ void AGOSEngine::setupSimon1Opcodes(OpcodeProc *op) {
op[98] = &AGOSEngine::os1_animate;
op[99] = &AGOSEngine::oe1_stopAnimate;
op[127] = &AGOSEngine::os1_playTune;
op[135] = &AGOSEngine::os1_pauseGame;
op[161] = &AGOSEngine::os1_screenTextBox;
op[162] = &AGOSEngine::os1_screenTextMsg;
op[163] = &AGOSEngine::os1_playEffect;
@ -99,6 +100,60 @@ void AGOSEngine::os1_playTune() {
}
}
void AGOSEngine::os1_pauseGame() {
// 135: pause game
_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
// If all else fails, use English as fallback.
byte keyYes = 'y';
byte keyNo = 'n';
switch (_language) {
case Common::RU_RUS:
break;
case Common::PL_POL:
keyYes = 't';
break;
case Common::HB_ISR:
keyYes = 'f';
break;
case Common::ES_ESP:
keyYes = 's';
break;
case Common::IT_ITA:
keyYes = 's';
break;
case Common::FR_FRA:
keyYes = 'o';
break;
case Common::DE_DEU:
keyYes = 'j';
break;
default:
break;
}
for (;;) {
delay(1);
#ifdef _WIN32_WCE
if (isSmartphone()) {
if (_keyPressed) {
if (_keyPressed == 13)
shutdown();
else
break;
}
}
#endif
if (_keyPressed == keyYes || _keyPressed == (keyYes - 32))
shutdown();
else if (_keyPressed == keyNo || _keyPressed == (keyNo - 32))
break;
}
_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
}
void AGOSEngine::os1_screenTextBox() {
// 161: setup text
TextLocation *tl = getTextLocation(getVarOrByte());

View File

@ -40,6 +40,7 @@ void AGOSEngine::setupSimon2Opcodes(OpcodeProc *op) {
op[98] = &AGOSEngine::os2_animate;
op[99] = &AGOSEngine::os2_stopAnimate;
op[127] = &AGOSEngine::os2_playTune;
op[135] = &AGOSEngine::os1_pauseGame;
op[161] = &AGOSEngine::os1_screenTextBox;
op[162] = &AGOSEngine::os1_screenTextMsg;
op[163] = &AGOSEngine::os1_playEffect;

View File

@ -59,6 +59,7 @@ void AGOSEngine::setupWaxworksOpcodes(OpcodeProc *op) {
op[105] = &AGOSEngine::oww_menu;
op[106] = &AGOSEngine::oww_textMenu;
op[127] = &AGOSEngine::os1_playTune;
op[135] = &AGOSEngine::oww_pauseGame;
op[144] = &AGOSEngine::oe2_setDoorOpen;
op[145] = &AGOSEngine::oe2_setDoorClosed;
op[146] = &AGOSEngine::oe2_setDoorLocked;
@ -168,6 +169,37 @@ void AGOSEngine::oww_textMenu() {
_textMenu[slot] = getVarOrByte();
}
void AGOSEngine::oww_pauseGame() {
// 135: pause game
HitArea *ha;
time_t pauseTime = time(NULL);
haltAnimation();
for (;;) {
_lastHitArea = NULL;
_lastHitArea3 = NULL;
for (;;) {
if (_lastHitArea3 != 0)
break;
delay(1);
}
ha = _lastHitArea;
if (ha == NULL) {
} else if (ha->id == 200) {
break;
} else if (ha->id == 201) {
break;
}
}
restartAnimation();
_gameStoppedClock = time(NULL) - pauseTime + _gameStoppedClock;
}
void AGOSEngine::oww_boxMessage() {
// 184: print message to box
boxTextMessage((const char *)getStringPtrByID(getNextStringID()));

View File

@ -196,4 +196,45 @@ void AGOSEngine::windowPutChar(uint a) {
windowPutChar(_textWindow, a);
}
void AGOSEngine::waitWindow(WindowBlock *window) {
HitArea *ha;
const char *message;
window->textColumn = (window->width / 2) - 3;
window->textRow = window->height - 1;
window->textLength = 0;
message = "[ OK ]";
for (; *message; message++)
windowPutChar(window, *message);
ha = findEmptyHitArea();
ha->x = 96;
ha->y = 62;
ha->width = 48;
ha->height = 8;
ha->flags = kBFBoxInUse;
ha->id = 0x7FFF;
ha->priority = 999;
for (;;) {
_lastHitArea = NULL;
_lastHitArea3 = NULL;
for (;;) {
if (_lastHitArea3 != 0)
break;
delay(1);
}
ha = _lastHitArea;
if (ha == NULL) {
} else if (ha->id == 0x7FFF) {
break;
}
}
undefineBox(0x7FFF);
}
} // End of namespace AGOS