bool DrasculaEngine::runCurrentChapter() { int n; rightMouseButton = 0; previousMusic = -1; if (currentChapter != 2) { int soc = 0; for (n = 0; n < 6; n++) { soc = soc + CHARACTER_WIDTH; _frameX[n] = soc; } } for (n = 1; n < ARRAYSIZE(inventoryObjects); n++) inventoryObjects[n] = 0; for (n = 0; n < NUM_FLAGS; n++) flags[n] = 0; if (currentChapter == 2) { flags[16] = 1; flags[17] = 1; flags[27] = 1; } for (n = 1; n < 7; n++) inventoryObjects[n] = n; if (currentChapter == 1) { pickObject(28); if (loadedDifferentChapter == 0) animation_1_1(); selectVerb(kVerbNone); loadPic("2aux62.alg", drawSurface2); trackProtagonist = 1; objExit = 104; if (loadedDifferentChapter != 0) { if (!loadGame(saveName)) { return true; } } else { enterRoom(62); curX = -20; curY = 56; gotoObject(65, 145); } } else if (currentChapter == 2) { addObject(kItemPhone); trackProtagonist = 3; objExit = 162; if (loadedDifferentChapter == 0) enterRoom(14); else { if (!loadGame(saveName)) { return true; } } } else if (currentChapter == 3) { addObject(kItemPhone); addObject(kItemEarplugs); addObject(kItemSickle); addObject(kItemHandbag); addObject(kItemCross); addObject(kItemReefer); addObject(kItemOneCoin); flags[1] = 1; trackProtagonist = 1; objExit = 99; if (loadedDifferentChapter == 0) enterRoom(20); else { if (!loadGame(saveName)) { return true; } } // From here onwards the items have different IDs } else if (currentChapter == 4) { addObject(kItemPhone2); addObject(kItemCross2); addObject(kItemReefer2); addObject(kItemOneCoin2); objExit = 100; if (loadedDifferentChapter == 0) { enterRoom(21); trackProtagonist = 0; curX = 235; curY = 164; } else { if (!loadGame(saveName)) { return true; } } } else if (currentChapter == 5) { addObject(28); addObject(7); addObject(9); addObject(11); addObject(13); addObject(14); addObject(15); addObject(17); addObject(20); trackProtagonist = 1; objExit = 100; if (loadedDifferentChapter == 0) { enterRoom(45); } else { if (!loadGame(saveName)) { return true; } } } else if (currentChapter == 6) { addObject(28); addObject(9); trackProtagonist = 1; objExit = 104; if (loadedDifferentChapter == 0) { enterRoom(58); animation_1_6(); } else { if (!loadGame(saveName)) { return true; } loadPic("auxdr.alg", drawSurface2); } } showCursor(); while (!shouldQuit()) { if (characterMoved == 0) { stepX = STEP_X; stepY = STEP_Y; } if (characterMoved == 0 && walkToObject == 1) { trackProtagonist = trackFinal; walkToObject = 0; } if (currentChapter == 2) { // NOTE: the checks for room number 14 below are a hack used in the original // game, and move the character to a place where his feet are not drawn above // the pianist's head. Originally, walkToObject was not updated properly, which // lead to an incorrect setting of the protagonist's tracking flag (above). This // made the character start walking off screen, as his actual position was // different than the displayed one if (roomNumber == 3 && (curX == 279) && (curY + curHeight == 101)) { gotoObject(178, 121); gotoObject(169, 135); } else if (roomNumber == 14 && (curX == 214) && (curY + curHeight == 121)) { walkToObject = 1; gotoObject(190, 130); } else if (roomNumber == 14 && (curX == 246) && (curY + curHeight == 112)) { walkToObject = 1; gotoObject(190, 130); } } moveCursor(); updateScreen(); if (currentChapter == 2) { if (musicStatus() == 0 && roomMusic != 0) playMusic(roomMusic); } else { if (musicStatus() == 0) playMusic(roomMusic); } delay(25); #ifndef _WIN32_WCE // FIXME // This and the following #ifndefs disable the excess updateEvents() calls *within* the game loop. // Events such as keypresses or mouse clicks are dropped on the ground with no processing // by these calls. They are properly handled by the implicit call through getScan() below. // It is not a good practice to not process events and indeed this created problems with synthesized // events in the wince port. updateEvents(); #endif if (!_menuScreen && takeObject == 1) checkObjects(); #ifdef _WIN32_WCE if (rightMouseButton) if (_menuScreen) { #else if (rightMouseButton == 1 && _menuScreen) { #endif rightMouseButton = 0; delay(100); if (currentChapter == 2) { loadPic(menuBackground, cursorSurface); loadPic(menuBackground, backSurface); } else { loadPic(99, cursorSurface); loadPic(99, backSurface); } setPalette((byte *)&gamePalette); _menuScreen = false; #ifndef _WIN32_WCE // FIXME: This call here is in hope that it will catch the rightmouseup event so the // next if block won't be executed. This too is not a good coding practice. I've recoded it // with a mutual exclusive if block for the menu. I would commit this properly but I cannot test // for other (see Desktop) ports right now. updateEvents(); #endif #ifdef _WIN32_WCE } else { #else } // Do not show the inventory screen in chapter 5, if the right mouse button is clicked // while the plug (object 16) is held // Fixes bug #2059621 - "DRASCULA: Plug bug" if (rightMouseButton == 1 && !_menuScreen && !(currentChapter == 5 && pickedObject == 16)) { #endif rightMouseButton = 0; delay(100); characterMoved = 0; if (trackProtagonist == 2) trackProtagonist = 1; if (currentChapter == 4) { loadPic("icons2.alg", backSurface); loadPic("icons2.alg", cursorSurface); } else if (currentChapter == 5) { loadPic("icons3.alg", backSurface); loadPic("icons3.alg", cursorSurface); } else if (currentChapter == 6) { loadPic("iconsp.alg", backSurface); loadPic("iconsp.alg", cursorSurface); } else { loadPic("icons.alg", backSurface); loadPic("icons.alg", cursorSurface); } _menuScreen = true; #ifndef _WIN32_WCE updateEvents(); #endif selectVerb(kVerbNone); } if (leftMouseButton == 1 && _menuBar) { delay(100); selectVerbFromBar(); } else if (leftMouseButton == 1 && takeObject == 0) { delay(100); if (verify1()) return true; } else if (leftMouseButton == 1 && takeObject == 1) { if (verify2()) return true; } _menuBar = (mouseY < 24 && !_menuScreen) ? true : false; Common::KeyCode key = getScan(); if (key == Common::KEYCODE_F1 && !_menuScreen) { selectVerb(kVerbLook); } else if (key == Common::KEYCODE_F2 && !_menuScreen) { selectVerb(kVerbPick); } else if (key == Common::KEYCODE_F3 && !_menuScreen) { selectVerb(kVerbOpen); } else if (key == Common::KEYCODE_F4 && !_menuScreen) { selectVerb(kVerbClose); } else if (key == Common::KEYCODE_F5 && !_menuScreen) { selectVerb(kVerbTalk); } else if (key == Common::KEYCODE_F6 && !_menuScreen) { selectVerb(kVerbMove); } else if (key == Common::KEYCODE_F9) { volumeControls(); } else if (key == Common::KEYCODE_F10) { if (!saveLoadScreen()) return true; } else if (key == Common::KEYCODE_F8) { selectVerb(kVerbNone); } else if (key == Common::KEYCODE_v) { _subtitlesDisabled = true; ConfMan.setBool("subtitles", !_subtitlesDisabled); print_abc(_textsys[2], 96, 86); updateScreen(); delay(1410); } else if (key == Common::KEYCODE_t) { _subtitlesDisabled = false; ConfMan.setBool("subtitles", !_subtitlesDisabled); print_abc(_textsys[3], 94, 86); updateScreen(); delay(1460); } else if (key == Common::KEYCODE_ESCAPE) { if (!confirmExit()) return false; } else if (key == Common::KEYCODE_TILDE || key == Common::KEYCODE_BACKQUOTE) { _console->attach(); _console->onFrame(); } else if (currentChapter == 6 && key == Common::KEYCODE_0 && roomNumber == 61) { loadPic("alcbar.alg", bgSurface, 255); } if (leftMouseButton != 0 || rightMouseButton != 0 || key != 0) if (currentChapter != 3) framesWithoutAction = 0; if (framesWithoutAction == 15000) { screenSaver(); if (currentChapter != 3) framesWithoutAction = 0; } if (currentChapter != 3) framesWithoutAction++; } return false; } bool DrasculaEngine::verify1() { int l; if (_menuScreen) removeObject(); else { for (l = 0; l < numRoomObjs; l++) { if (mouseX >= x1[l] && mouseY >= y1[l] && mouseX <= x2[l] && mouseY <= y2[l] && doBreak == 0) { if (exitRoom(l)) return true; if (doBreak == 1) break; } } if (mouseX > curX && mouseY > curY && mouseX < curX + curWidth && mouseY < curY + curHeight) doBreak = 1; for (l = 0; l < numRoomObjs; l++) { if (mouseX > x1[l] && mouseY > y1[l] && mouseX < x2[l] && mouseY < y2[l] && doBreak == 0) { roomX = roomObjX[l]; roomY = roomObjY[l]; trackFinal = trackObj[l]; doBreak = 1; walkToObject = 1; startWalking(); } } if (doBreak == 0) { roomX = CLIP(mouseX, floorX1, floorX2); roomY = CLIP(mouseY, floorY1 + feetHeight, floorY2); startWalking(); } doBreak = 0; } return false; }
void DrasculaEngine::converse(int index) { debug(4, "converse(%d)", index); char fileName[20]; sprintf(fileName, "op_%d.cal", index); Common::SeekableReadStream *stream = _archives.open(fileName); if (!stream) error("missing data file %s", fileName); int game1 = kDialogOptionUnselected, game2 = kDialogOptionUnselected, game3 = kDialogOptionUnselected; char phrase1[128], phrase2[128], phrase3[128], phrase4[128]; char sound1[13], sound2[13], sound3[13], sound4[13]; int phrase1_bottom, phrase2_bottom, phrase3_bottom, phrase4_bottom; int answer1, answer2, answer3; breakOut = 0; selectVerb(kVerbNone); TextResourceParser p(stream, DisposeAfterUse::YES); p.parseString(phrase1); p.parseString(phrase2); p.parseString(phrase3); p.parseString(phrase4); p.parseString(sound1); p.parseString(sound2); p.parseString(sound3); p.parseString(sound4); p.parseInt(answer1); p.parseInt(answer2); p.parseInt(answer3); // no need to delete the stream, since TextResourceParser takes ownership // delete stream; if (currentChapter == 2 && !strcmp(fileName, "op_5.cal") && flags[38] == 1 && flags[33] == 1) { Common::strlcpy(phrase3, _text[405], 128); strcpy(sound3, "405.als"); answer3 = 31; } if (currentChapter == 6 && !strcmp(fileName, "op_12.cal") && flags[7] == 1) { Common::strlcpy(phrase3, _text[273], 128); strcpy(sound3, "273.als"); answer3 = 14; } if (currentChapter == 6 && !strcmp(fileName, "op_12.cal") && flags[10] == 1) { Common::strlcpy(phrase3, _text[274], 128); strcpy(sound3, "274.als"); answer3 = 15; } cleanupString(phrase1); cleanupString(phrase2); cleanupString(phrase3); cleanupString(phrase4); loadPic("car.alg", backSurface); // TODO code here should limit y position for mouse in dialog menu, // but we can't implement this as there is lack in backend functionality // from 1(top) to 31 color_abc(kColorLightGreen); while (breakOut == 0 && !shouldQuit()) { updateRoom(); if (musicStatus() == 0 && roomMusic != 0) { if (currentChapter == 3 || currentChapter == 5) { playMusic(roomMusic); } else { // chapters 1, 2, 4, 6 if (flags[11] == 0) playMusic(roomMusic); } } updateEvents(); flushKeyBuffer(); phrase1_bottom = 8 * print_abc_opc(phrase1, 2, game1); phrase2_bottom = phrase1_bottom + 8 * print_abc_opc(phrase2, phrase1_bottom + 2, game2); phrase3_bottom = phrase2_bottom + 8 * print_abc_opc(phrase3, phrase2_bottom + 2, game3); phrase4_bottom = phrase3_bottom + 8 * print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionUnselected); if (_mouseY > 0 && _mouseY < phrase1_bottom) { if (game1 == kDialogOptionClicked && _color != kColorWhite) color_abc(kColorWhite); else if (game1 != kDialogOptionClicked && _color != kColorLightGreen) color_abc(kColorLightGreen); print_abc_opc(phrase1, 2, kDialogOptionSelected); if (_leftMouseButton == 1) { delay(100); game1 = kDialogOptionClicked; talk(phrase1, sound1); response(answer1); } } else if (_mouseY > phrase1_bottom && _mouseY < phrase2_bottom) { if (game2 == kDialogOptionClicked && _color != kColorWhite) color_abc(kColorWhite); else if (game2 != kDialogOptionClicked && _color != kColorLightGreen) color_abc(kColorLightGreen); print_abc_opc(phrase2, phrase1_bottom + 2, kDialogOptionSelected); if (_leftMouseButton == 1) { delay(100); game2 = kDialogOptionClicked; talk(phrase2, sound2); response(answer2); } } else if (_mouseY > phrase2_bottom && _mouseY < phrase3_bottom) { if (game3 == kDialogOptionClicked && _color != kColorWhite) color_abc(kColorWhite); else if (game3 != kDialogOptionClicked && _color != kColorLightGreen) color_abc(kColorLightGreen); print_abc_opc(phrase3, phrase2_bottom + 2, kDialogOptionSelected); if (_leftMouseButton == 1) { delay(100); game3 = kDialogOptionClicked; talk(phrase3, sound3); response(answer3); } } else if (_mouseY > phrase3_bottom && _mouseY < phrase4_bottom) { print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionSelected); if (_leftMouseButton == 1) { delay(100); talk(phrase4, sound4); breakOut = 1; } } else if (_color != kColorLightGreen) color_abc(kColorLightGreen); _system->delayMillis(10); updateScreen(); } // while (breakOut == 0) if (currentChapter == 2) loadPic(menuBackground, backSurface); else loadPic(99, backSurface); }