Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,196 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "chewy/dialogs/cinema.h"
#include "chewy/cursor.h"
#include "chewy/events.h"
#include "chewy/font.h"
#include "chewy/globals.h"
#include "chewy/main.h"
#include "chewy/mcga_graphics.h"
#include "chewy/sound.h"
namespace Chewy {
namespace Dialogs {
static constexpr int CINEMA_LINES = 12;
static const uint8 CINEMA_FLICS[35] = {
FCUT_000, FCUT_002, FCUT_006, FCUT_009, FCUT_015,
FCUT_012, FCUT_011, FCUT_SPACECHASE_18, FCUT_003, FCUT_048,
FCUT_031, FCUT_044, FCUT_055, FCUT_058, FCUT_045,
FCUT_065, FCUT_067, FCUT_068, FCUT_069, FCUT_080,
FCUT_074, FCUT_083, FCUT_084, FCUT_088, FCUT_093,
FCUT_087, FCUT_106, FCUT_108, FCUT_107, FCUT_113,
FCUT_110, FCUT_121, FCUT_123, FCUT_122, FCUT_117
};
void Cinema::execute() {
int topIndex = 0;
int selected = 0;
bool flag = true;
int delay = 0;
Common::Array<int> cutscenes;
Common::String cutsceneName;
getCutscenes(cutscenes);
_G(fontMgr)->setFont(_G(font6));
_G(room)->load_tgp(4, &_G(room_blk), 1, false, GBOOK);
showCur();
EVENTS_CLEAR;
g_events->_kbInfo._scanCode = 0;
for (bool endLoop = false; !endLoop;) {
_G(out)->setPointer(_G(workptr));
_G(out)->map_spr2screen(_G(ablage)[_G(room_blk).AkAblage], 0, 0);
if (!cutscenes.empty()) {
// Render cut-scene list
for (int i = 0; i < CINEMA_LINES; ++i) {
if ((topIndex + i) >= (int)cutscenes.size())
continue;
cutsceneName = _G(atds)->getTextEntry(98,
546 + cutscenes[topIndex + i] - 1, ATS_DATA);
int yp = i * 10 + 68;
if (i == selected)
_G(out)->boxFill(37, yp, 308, yp + 10, 42);
_G(out)->printxy(40, yp, 14, 300, 0, cutsceneName.c_str());
}
} else {
// No cut-scene seen yet
cutsceneName = _G(atds)->getTextEntry(98, 545, ATS_DATA);
_G(out)->printxy(40, 68, 14, 300, _G(scr_width), cutsceneName.c_str());
}
if (_G(minfo).button == 1 && !flag) {
flag = true;
switch (_G(out)->findHotspot(_G(cinematicsHotspots))) {
case 0:
g_events->_kbInfo._scanCode = Common::KEYCODE_UP;
break;
case 1:
g_events->_kbInfo._scanCode = Common::KEYCODE_DOWN;
break;
case 2: {
int selLine = (g_events->_mousePos.y - 68) / 10;
int selIndex = topIndex + selLine;
if (selIndex < (int)cutscenes.size()) {
selected = selLine;
g_events->_kbInfo._scanCode = Common::KEYCODE_RETURN;
}
break;
}
default:
break;
}
} else if (_G(minfo).button == 2 && !flag) {
g_events->_kbInfo._scanCode = Common::KEYCODE_ESCAPE;
flag = true;
} else if (_G(minfo).button != 1) {
delay = 0;
} else if (flag) {
g_events->update();
if (--delay <= 0)
flag = false;
}
switch (g_events->_kbInfo._scanCode) {
case Common::KEYCODE_ESCAPE:
endLoop = true;
g_events->_kbInfo._scanCode = 0;
break;
case Common::KEYCODE_UP:
case Common::KEYCODE_KP8:
if (selected > 0) {
--selected;
} else if (topIndex > 0) {
--topIndex;
}
g_events->_kbInfo._scanCode = 0;
break;
case Common::KEYCODE_DOWN:
case Common::KEYCODE_KP2:
{
int newIndex = selected + 1;
if (selected >= 11) {
if ((topIndex + newIndex) < (int)cutscenes.size())
++topIndex;
} else {
if ((topIndex + newIndex) < (int)cutscenes.size())
++selected;
}
g_events->_kbInfo._scanCode = 0;
break;
}
case Common::KEYCODE_RETURN:
hideCur();
_G(out)->cls();
_G(out)->setPointer((byte *)g_screen->getPixels());
_G(fx)->blende1(_G(workptr), _G(pal), 0, 0);
flic_cut(CINEMA_FLICS[cutscenes[topIndex + selected] - 1]);
_G(fontMgr)->setFont(_G(font6));
showCur();
delay = 0;
flag = false;
break;
default:
break;
}
// The below are hacks to get the dialog to work in ScummVM
g_events->_kbInfo._scanCode = 0;
_G(minfo).button = 0;
_G(cur)->updateCursor();
if (flag) {
flag = false;
_G(out)->setPointer((byte *)g_screen->getPixels());
_G(room)->set_ak_pal(&_G(room_blk));
_G(fx)->blende1(_G(workptr), _G(pal), 0, 0);
} else {
_G(out)->copyToScreen();
}
g_events->update();
SHOULD_QUIT_RETURN;
}
_G(room)->set_ak_pal(&_G(room_blk));
hideCur();
_G(uhr)->resetTimer(0, 5);
}
} // namespace Dialogs
} // namespace Chewy

View File

@@ -0,0 +1,38 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CHEWY_DIALOGS_CINEMA_H
#define CHEWY_DIALOGS_CINEMA_H
#include "common/scummsys.h"
namespace Chewy {
namespace Dialogs {
class Cinema {
public:
static void execute();
};
} // namespace Dialogs
} // namespace Chewy
#endif

View File

@@ -0,0 +1,271 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "chewy/dialogs/credits.h"
#include "chewy/events.h"
#include "chewy/font.h"
#include "chewy/globals.h"
#include "chewy/mcga_graphics.h"
#include "chewy/text.h"
namespace Chewy {
namespace Dialogs {
static const int16 CREDITS_POS[65][2] = {
{40, 160}, {80, 170}, {40, 190}, {80, 200}, {80, 210},
{40, 230}, {80, 240}, {80, 250}, {80, 260}, {40, 280},
{80, 290}, {80, 300}, {80, 310}, {80, 320}, {40, 340},
{80, 350}, {80, 360}, {40, 380}, {80, 390}, {40, 410},
{80, 420}, {40, 440}, {80, 450}, {40, 470}, {80, 480},
{80, 490}, {80, 500}, {80, 510}, {80, 520}, {40, 540},
{80, 550}, {80, 560}, {80, 570}, {80, 580}, {40, 600},
{80, 610}, {80, 620}, {80, 630}, {80, 640}, {80, 650},
{80, 660}, {80, 670}, {80, 680}, {80, 690}, {80, 700},
{80, 710}, {80, 720}, {80, 730}, {80, 740}, {80, 750},
{80, 760}, {40, 780}, {40, 790}, {40, 800}, {40, 810},
{40, 820}, {40, 840}, {80, 850}, {40, 870}, {80, 880},
{80, 890}, {80, 910}, {80, 920}, {80, 930}, {80, 940}
};
static const bool CREDITS_TYPE[65] = {
true, false, true, false, false, true, false, false, false, true,
false, false, false, false, true, false, false, true, false, true,
false, true, false, true, false, false, false, false, false, true,
false, false, false, false, true, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false,
false, true, true, true, true, true, true, false, true, false,
false, true, true, true, true
};
static const char *CREDITS_TEXT_EN[65] = {
"Idea & Story:",
"Carsten Wieland",
"Programming:",
"Helmut Theuerkauf",
"Alexander Diessner",
"Graphics & Animation:",
"Carsten Wieland",
"Nihat Keesen",
"Stefan Frank",
"Text & Dialogues:",
"Helmut Theuerkauf",
"Alexander Diessner",
"Carsten Wieland",
"Wolfgang Walk",
"Music:",
"Carsten Wieland",
"Stelter Studios",
"Sound FX:",
"Helmut Theuerkauf",
"Producer & Lecturer:",
"Wolfgang Walk",
"Minister of financial affairs:",
"Carsten (Dagobert) Korte",
"Testers:",
"Lutz Rafflenbeul",
"Thomas Friedmann",
"Bernhard Ewers",
"Christian von der Hotline",
"Carsten Korte",
"The voices:",
"Chewy......Renier Baaken",
"Howard.....Wolfgang Walk",
"Nichelle...Indhira Mohammed",
"Clint......Alexander Schottky",
"Also cast:",
"Renier Baaken",
"Guido B\x94sherz",
"Gerhard Fehn",
"Alice Krause",
"Reinhard Lie\xE1",
"Willi Meyer",
"Nicole Meister",
"Lutz Rafflenbeul",
"Alexander Schottky",
"Bernd Schulze",
"Susanne Simenec",
"Helmut Theuerkauf",
"Andreas Vogelpoth",
"Mark Wagener",
"Wolfgang Walk",
"Thomas Piet Wiesenm\x81ller",
"Speech recorded by",
"tmp Studio, Moers by Willi Meyer",
"Cut by Hartmut Stelter",
"Studios Hamburg and",
"Carsten Wieland",
"Soundsystem:",
"AIL (c) Miles Design",
"Adventure Engine:",
"I.C.M. developed by",
"New Generation Software",
"Song Boo Boo Ba Baby composed",
"by Haiko Ruttmann,",
"Lyrics Wolfgang Walk,",
"featuring Indhira Mohammed."
};
static const char *CREDITS_TEXT_DE[65] = {
"Idee & Story:",
"Carsten Wieland",
"Programmierung:",
"Helmut Theuerkauf",
"Alexander Diessner",
"Grafiken & Animationen:",
"Carsten Wieland",
"Nihat Keesen",
"Stefan Frank",
"Text & Dialoge:",
"Helmut Theuerkauf",
"Alexander Diessner",
"Carsten Wieland",
"Wolfgang Walk",
"Musik:",
"Carsten Wieland",
"Stelter Studios",
"Soundeffekte:",
"Helmut Theuerkauf",
"Produzent & Lektor:",
"Wolfgang Walk",
"Minister f\x81r Finanzen",
"Carsten (Dagobert) Korte",
"Tester:",
"Lutz Rafflenbeul",
"Thomas Friedmann",
"Bernhard Ewers",
"Christian von der Hotline",
"Carsten Korte",
"Die Stimmen:",
"Chewy......Renier Baaken",
"Howard.....Wolfgang Walk",
"Nichelle...Indhira Mohammed",
"Clint......Alexander Schottky",
"In weiteren Rollen:",
"Renier Baaken",
"Guido B\x94sherz",
"Gerhard Fehn",
"Alice Krause",
"Reinhard Lie\xE1",
"Willi Meyer",
"Nicole Meister",
"Lutz Rafflenbeul",
"Alexander Schottky",
"Bernd Schulze",
"Susanne Simenec",
"Helmut Theuerkauf",
"Andreas Vogelpoth",
"Mark Wagener",
"Wolfgang Walk",
"Thomas Piet Wiesenm\x81ller",
"Die Sprache wurde aufgenommen",
"im tmp Studio, Moers von Willi Meyer",
"Nachbearbeitung in den Hartmut Stelter",
"Studios Hamburg und",
"Carsten Wieland",
"Soundsystem:",
"AIL (c) Miles Design",
"Adventure Engine:",
"I.C.M. entwickelt von",
"New Generation Software",
"Song Boo Boo Ba Baby komponiert",
"von Haiko Ruttmann,",
"Text Wolfgang Walk,",
"Gesang Indhira Mohammed."
};
void Credits::execute() {
int lineScrolled = 0;
int fontCol;
_G(room)->load_tgp(5, &_G(room_blk), 1, false, GBOOK);
_G(gameState).scrollx = 0;
_G(gameState).scrolly = 0;
_G(out)->setPointer((byte *)g_screen->getPixels());
_G(room)->set_ak_pal(&_G(room_blk));
_G(fx)->blende1(_G(workptr), _G(pal), 0, 0);
for (int16 i = 0; i < 6; ++i) {
int color = 63 - (6 * i);
_G(out)->raster_col(6 - i, color, 0, 0);
_G(out)->raster_col(7 + i, color, 0, 0);
color = 63 - (4 * i);
_G(out)->raster_col(37 - i, color, color, color);
_G(out)->raster_col(38 + i, color, color, color);
}
_G(gameState).DelaySpeed = 2;
for (;;) {
if (g_events->getSwitchCode() == Common::KEYCODE_ESCAPE || SHOULD_QUIT)
break;
// Display the starfield background
_G(out)->setPointer(_G(workptr));
_G(out)->map_spr2screen(_G(ablage)[_G(room_blk).AkAblage],
_G(gameState).scrollx, _G(gameState).scrolly);
// Animate moving the background
if (++_G(gameState).scrollx >= 320)
_G(gameState).scrollx = 0;
if (g_events->getSwitchCode() == Common::KEYCODE_ESCAPE)
break;
++lineScrolled;
g_events->delay(50);
bool stillScrolling = false;
for (int i = 0; i < 65; ++i) {
int destY = CREDITS_POS[i][1] - lineScrolled;
if (destY >= 160 || destY <= 40)
continue;
if (CREDITS_TYPE[i]) {
fontCol = 32;
_G(fontMgr)->setFont(_G(font6));
} else {
fontCol = 1;
_G(fontMgr)->setFont(_G(font8));
}
stillScrolling = true;
int fgCol = fontCol + (160 - destY) / 10;
_G(out)->printxy(CREDITS_POS[i][0], destY, fgCol, 300, _G(scr_width), g_engine->getLanguage() == Common::Language::DE_DEU ? CREDITS_TEXT_DE[i] : CREDITS_TEXT_EN[i]);
}
if (!stillScrolling)
break;
_G(out)->setPointer(nullptr);
_G(out)->copyToScreen();
}
_G(fontMgr)->setFont(_G(font8));
_G(room)->set_ak_pal(&_G(room_blk));
hideCur();
_G(uhr)->resetTimer(0, 5);
}
} // namespace Dialogs
} // namespace Chewy

View File

@@ -0,0 +1,36 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CHEWY_DIALOGS_CREDITS_H
#define CHEWY_DIALOGS_CREDITS_H
namespace Chewy {
namespace Dialogs {
class Credits {
public:
static void execute();
};
} // namespace Dialogs
} // namespace Chewy
#endif

View File

@@ -0,0 +1,309 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/config-manager.h"
#include "chewy/dialogs/files.h"
#include "chewy/dialogs/options.h"
#include "chewy/cursor.h"
#include "chewy/events.h"
#include "chewy/globals.h"
#include "chewy/mcga_graphics.h"
#include "chewy/memory.h"
namespace Chewy {
namespace Dialogs {
#define NUM_VISIBLE_SLOTS 6
enum Widget {
SCROLL_UP = 0, SCROLL_DOWN = 1, SAVE = 2, LOAD = 3,
GAME = 4, QUIT = 5, OPTIONS = 6, W7 = 7, W8 = 8
};
// Returns true if the game should exit to main menu
bool Files::execute(bool isInGame) {
int16 key = 0;
Common::Point pt[8];
int16 mode[9];
bool visibility[8];
bool ret = false;
bool flag = false;
if (!ConfMan.getBool("original_menus")) {
g_engine->showGmm(isInGame);
_G(flags).mainMouseFlag = false;
_G(minfo).button = 0;
const int16 roomNum = _G(gameState)._personRoomNr[P_CHEWY];
return isInGame ? false : (roomNum == 98);
}
TafInfo *ti = _G(mem)->taf_adr(OPTION_TAF);
EVENTS_CLEAR;
_G(room)->load_tgp(1, &_G(room_blk), GBOOK_TGP, false, GBOOK);
_G(out)->setPointer(_G(workptr));
_G(out)->map_spr2screen(_G(ablage)[_G(room_blk).AkAblage], 0, 0);
_G(out)->setPointer((byte *)g_screen->getPixels());
_G(room)->set_ak_pal(&_G(room_blk));
_G(fx)->blende1(_G(workptr), _G(pal), 0, 0);
_G(out)->setPointer(_G(workptr));
showCur();
pt[SCROLL_UP] = pt[SCROLL_DOWN] = Common::Point(1, 0);
for (int16 i = SAVE; i <= W7; i++)
pt[i] = Common::Point(5, 5);
Common::fill(visibility, visibility + 8, true);
Common::fill(mode, mode + 8, 0);
mode[W8] = 1;
if (!isInGame) {
visibility[SAVE] = false;
visibility[GAME] = false;
mode[LOAD] = 1;
mode[W8] = 0;
}
int16 text_off = 0; // Top visible save slot
int16 active_slot = 0; // Currently selected slot
SaveStateList saveList = g_engine->listSaves();
while (key != Common::KEYCODE_ESCAPE && !SHOULD_QUIT) {
// Draw the dialog background
_G(out)->map_spr2screen(_G(ablage)[_G(room_blk).AkAblage], 0, 0);
// Draw the buttons at the bottom
for (int16 i = 28, j = SCROLL_UP; j <= OPTIONS; i++, j++) {
if (visibility[j]) {
if (!mode[j])
// Not pressed
_G(out)->spriteSet(
ti->image[i], 16 + ti->correction[i << 1] + pt[j].x,
76 + ti->correction[(i << 1) + 1] + pt[j].y, 0);
else
// Pressed
_G(out)->spriteSet(ti->image[i], 16 + ti->correction[i << 1],
76 + ti->correction[(i << 1) + 1], 0);
}
}
// Write the list of savegame slots
for (int16 i = 0; i < NUM_VISIBLE_SLOTS; i++) {
if (i + text_off >= (int16) saveList.size())
break;
// TODO: This implementation disallows gaps in the save list
if (saveList[i + text_off].getSaveSlot() != i + text_off)
continue;
Common::String slot = Common::String::format("%2d.", text_off + i);
Common::String saveName = saveList[i + text_off].getDescription();
if (i != active_slot) {
_G(out)->printxy(40, 68 + (i * 10), 14, 300, 0, slot.c_str());
_G(out)->printxy(70, 68 + (i * 10), 14, 300, 0, saveName.c_str());
} else {
_G(out)->boxFill(40, 68 + (i * 10), 308, 68 + 8 + (i * 10), 42);
_G(out)->printxy(40, 68 + (i * 10), 255, 300, 0, slot.c_str());
_G(out)->printxy(70, 68 + (i * 10), 255, 300, 0, saveName.c_str());
}
}
key = g_events->getSwitchCode();
if (mode[SCROLL_UP])
--mode[SCROLL_UP];
if (mode[SCROLL_DOWN])
--mode[SCROLL_DOWN];
if (mode[GAME])
--mode[GAME];
if (mode[GAME] == 1)
key = Common::KEYCODE_ESCAPE;
if (mode[QUIT])
--mode[QUIT];
if (mode[QUIT] == 1) {
_G(out)->printxy(120, 138, 255, 300, 0, g_engine->getLanguage() == Common::Language::DE_DEU ? QUIT_MSG_DE : QUIT_MSG_EN);
_G(out)->copyToScreen();
key = getch();
if (key == 'j' || key == 'J' || key == 'y' || key == 'Y' || key == 'z' || key == 'Z') {
ret = true;
key = Common::KEYCODE_ESCAPE;
} else {
key = 0;
}
}
if (mode[OPTIONS])
--mode[OPTIONS];
if (mode[OPTIONS] == 1) {
Dialogs::Options::execute(ti);
}
if (!flag && _G(minfo).button == 1) {
int16 rect = _G(out)->findHotspot(_G(fileHotspots));
flag = true;
key = 0;
switch (rect) {
case 0:
key = Common::KEYCODE_UP;
break;
case 1:
key = Common::KEYCODE_DOWN;
break;
case 2: {
int16 line = (g_events->_mousePos.y - 68) / 10;
if (line == active_slot)
key = Common::KEYCODE_RETURN;
else
active_slot = line;
if (active_slot > 5)
active_slot = 5;
if (!isInGame)
goto enter;
}
break;
case 3:
key = Common::KEYCODE_F1;
break;
case 4:
key = Common::KEYCODE_F2;
break;
case 5:
key = Common::KEYCODE_F3;
break;
case 6:
key = Common::KEYCODE_F4;
break;
case 7:
key = Common::KEYCODE_F5;
break;
default:
break;
}
} else if (flag && _G(minfo).button == 0) {
flag = false;
}
switch (key) {
case Common::KEYCODE_F1:
if (visibility[SAVE]) {
mode[LOAD] = 0;
mode[SAVE] = 1;
mode[W8] = 0;
goto enter;
}
break;
case Common::KEYCODE_F2:
mode[LOAD] = 1;
mode[SAVE] = 0;
mode[W8] = 0;
goto enter;
break;
case Common::KEYCODE_F3:
if (visibility[GAME])
mode[GAME] = 10;
break;
case Common::KEYCODE_F4:
mode[QUIT] = 10;
break;
case Common::KEYCODE_F5:
mode[OPTIONS] = 10;
break;
case Common::KEYCODE_UP:
mode[SCROLL_UP] = 10;
if (active_slot > 0)
--active_slot;
else if (text_off > 0)
--text_off;
break;
case Common::KEYCODE_DOWN:
mode[SCROLL_DOWN] = 10;
if (active_slot < (NUM_VISIBLE_SLOTS - 1))
++active_slot;
else if (text_off < (999 - NUM_VISIBLE_SLOTS))
++text_off;
break;
case Common::KEYCODE_RETURN:
case Common::KEYCODE_RETURN + ALT:
enter:
if (mode[LOAD]) {
const int16 slotNum = text_off + active_slot;
for (uint j = 0; j < saveList.size(); ++j) {
if (saveList[j].getSaveSlot() == slotNum) {
_G(cur)->hideCursor();
g_engine->loadGameState(slotNum);
key = Common::KEYCODE_ESCAPE;
break;
}
}
} else if (mode[SAVE]) {
_G(out)->copyToScreen();
_G(out)->setPointer((byte *)g_screen->getPixels());
char slotName[81];
slotName[0] = '\0';
key = _G(out)->scanxy(70, 68 + (active_slot * 10),
255, 42, 14, 0, "%36s36", slotName);
_G(out)->setPointer(_G(workptr));
if (key != Common::KEYCODE_ESCAPE) {
g_engine->saveGameState(text_off + active_slot, slotName);
saveList = g_engine->listSaves();
}
key = Common::KEYCODE_ESCAPE;
}
break;
default:
break;
}
_G(cur)->updateCursor();
_G(out)->copyToScreen();
EVENTS_UPDATE;
}
free(ti);
_G(room)->load_tgp(_G(gameState)._personRoomNr[P_CHEWY], &_G(room_blk), EPISODE1_TGP, true, EPISODE1);
_G(fx_blend) = BLEND1;
_G(room)->set_ak_pal(&_G(room_blk));
return ret;
}
} // namespace Dialogs
} // namespace Chewy

View File

@@ -0,0 +1,44 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CHEWY_DIALOGS_FILES_H
#define CHEWY_DIALOGS_FILES_H
#include "common/scummsys.h"
namespace Chewy {
namespace Dialogs {
class Files {
public:
/**
* Shows the file dialog
* @param isInGame True when called in-game,
* false when called from the main menu
* @returns Returns true if quit was selected
*/
static bool execute(bool isInGame);
};
} // namespace Dialogs
} // namespace Chewy
#endif

View File

@@ -0,0 +1,725 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "chewy/dialogs/inventory.h"
#include "chewy/rooms/room44.h"
#include "chewy/rooms/room58.h"
#include "chewy/cursor.h"
#include "chewy/events.h"
#include "chewy/font.h"
#include "chewy/globals.h"
#include "chewy/menus.h"
#include "chewy/sound.h"
namespace Chewy {
namespace Dialogs {
int16 Inventory::inv_rand_x;
int16 Inventory::inv_rand_y;
void Inventory::plot_menu() {
_G(out)->setPointer(_G(workptr));
buildMenu(WIN_INVENTORY);
// Draw inventory slots grid
for (int16 j = 0; j < 3; j++) {
for (int16 i = 0; i < 5; i++) {
_G(out)->boxFill(
WIN_INF_X + 14 + i * 54,
WIN_INF_Y + 6 + 30 + j * 32,
WIN_INF_X + 14 + i * 54 + 40,
WIN_INF_Y + 6 + 30 + j * 32 + 24,
12
);
}
}
int16 y;
int16 hotspotId = _G(out)->findHotspot(_G(inventoryHotspots));
// Highlight hotspots
if (hotspotId != -1) {
if (hotspotId < 5) {
_G(out)->boxFill(
_G(inventoryHotspots)[hotspotId].left,
_G(inventoryHotspots)[hotspotId].top,
_G(inventoryHotspots)[hotspotId].right + 1,
_G(inventoryHotspots)[hotspotId].bottom + 5,
41
);
} else {
const int16 x = (g_events->_mousePos.x - (WIN_INF_X)) / 54;
y = (g_events->_mousePos.y - (WIN_INF_Y + 4 + 30)) / 30;
hotspotId = x + (y * 5);
hotspotId += _G(gameState).InventY * 5;
if (hotspotId < (_G(gameState).InventY + 3) * 5) {
_G(out)->boxFill(
WIN_INF_X + 14 + x * 54,
WIN_INF_Y + 6 + 30 + y * 32,
WIN_INF_X + 14 + x * 54 + 40,
WIN_INF_Y + 6 + 30 + y * 32 + 24,
41
);
}
}
}
if (inv_rand_x != -1) {
_G(out)->boxFill(
WIN_INF_X + 14 + inv_rand_x * 54,
WIN_INF_Y + 6 + 30 + inv_rand_y * 32,
WIN_INF_X + 14 + inv_rand_x * 54 + 40,
WIN_INF_Y + 6 + 30 + inv_rand_y * 32 + 24,
41
);
_G(out)->box(
WIN_INF_X + 14 + inv_rand_x * 54 - 1,
WIN_INF_Y + 6 + 30 + inv_rand_y * 32 - 1,
WIN_INF_X + 14 + inv_rand_x * 54 + 40 + 1,
WIN_INF_Y + 6 + 30 + inv_rand_y * 32 + 24 + 1,
14
);
}
const int16 ANI_INVENT_END[3] = {7, 16, 24};
// Draw inventory action icons (look and use, to the left of the dialog)
for (int16 i = 0; i < 2; i++) {
_G(ani_invent_delay)[i][0] -= 1;
if (_G(ani_invent_delay)[i][0] <= 0) {
_G(ani_invent_delay)[i][0] = _G(ani_invent_delay)[i][1];
++_G(ani_count)[i];
if (_G(ani_count)[i] > ANI_INVENT_END[i]) {
_G(ani_count)[i] = _G(ani_invent_anf)[i];
_G(ani_invent_delay)[i][0] = 30000;
}
}
y = (i == 2) ? 3 : 0;
_G(out)->spriteSet(
_G(cur)->getCursorSprite(_G(ani_count)[i]),
WIN_INF_X + 8 + i * 32,
WIN_INF_Y + 12 - y,
_G(scr_width),
_G(cur)->getCursorWidth(_G(ani_count)[i]),
_G(cur)->getCursorHeight(_G(ani_count)[i])
);
}
// Draw inventory arrows (up and down, to the right of the dialog)
for (int16 i = 0; i < 2; i++) {
_G(out)->spriteSet(
_G(menutaf)->image[ARROW_UP + i],
WIN_INF_X + 200 + i * 40,
WIN_INF_Y + 12,
_G(scr_width)
);
}
y = WIN_INF_Y + 6 + 30;
// Draw inventory items
for (int16 j = 0; j < 3; j++) {
for (int16 i = 0; i < 5; i++) {
const int slot = (_G(gameState).InventY + j) * 5 + i;
const int16 invSlot = _G(gameState).InventSlot[slot];
if (invSlot != -1) {
const int16 *xy = (const int16 *)_G(inv_spr)[invSlot];
const int16 x1 = (40 - xy[0]) / 2;
const int16 y1 = (24 - xy[1]) / 2;
_G(out)->spriteSet(
_G(inv_spr)[invSlot],
x1 + WIN_INF_X + 14 + i * 54,
y1 + y + 32 * j,
_G(scr_width)
);
}
}
}
// Show up arrow, if needed
if (_G(gameState).InventY) {
const char c[2] = { 24, 0 };
_G(out)->printxy(225, 32, 19, 300, _G(scr_width), c);
}
// Show down arrow, if needed
for (int i = 5 * (_G(gameState).InventY + 3); i < 140; ++i) {
if (_G(gameState).InventSlot[i] != -1) {
const char c[2] = { 25, 0 };
_G(out)->printxy(265, 29, 19, 300, _G(scr_width), c);
break;
}
}
}
bool checkInventorykey() {
return g_events->_kbInfo._scanCode == Common::KEYCODE_RETURN ||
g_events->_kbInfo._scanCode == Common::KEYCODE_F1 ||
g_events->_kbInfo._scanCode == Common::KEYCODE_F2;
}
void Inventory::menu() {
_G(flags).InventMenu = true;
const int16 oldDispFlag = _G(gameState).DispFlag;
_G(gameState).DispFlag = false;
const uint16 oldAutoAniPlay = _G(flags).AutoAniPlay;
_G(flags).AutoAniPlay = true;
_G(flags).StopAutoObj = true;
_G(menu_display) = 0;
_G(cur)->move(152, 92);
g_events->_mousePos.x = 152;
g_events->_mousePos.y = 92;
_G(invent_cur_mode) = CUR_USE;
if (!_G(cur)->usingInventoryCursor()) {
_G(invent_cur_mode) = CUR_USE;
cursorChoice(CUR_USE);
}
int16 menu_flag1 = MENU_DISPLAY;
int16 taste_flag = 28;
_G(minfo).button = 0;
g_events->_kbInfo._keyCode = '\0';
g_events->_kbInfo._scanCode = '\0';
for (int16 i = 0; i < 3; i++) {
_G(ani_invent_delay)[i][0] = 30000;
_G(ani_count)[i] = _G(ani_invent_anf)[i];
}
int16 ret_look = -1;
bool menuFirstFl = false;
_G(show_invent_menu) = 1;
while (_G(show_invent_menu) == 1 && !SHOULD_QUIT) {
if (_G(minfo).button == 1 || checkInventorykey()) {
int16 k = _G(out)->findHotspot(_G(inventoryHotspots));
if (g_events->_kbInfo._scanCode == Common::KEYCODE_F1)
k = 0;
else if (g_events->_kbInfo._scanCode == Common::KEYCODE_F2)
k = 1;
else if (g_events->_kbInfo._scanCode == Common::KEYCODE_RETURN)
k = 5;
_G(minfo).button = 0;
g_events->_kbInfo._keyCode = '\0';
g_events->_kbInfo._scanCode = '\0';
switch (k) {
case 0:
_G(invent_cur_mode) = CUR_USE;
_G(menu_item) = CUR_USE;
if (!_G(cur)->usingInventoryCursor()) {
cursorChoice(CUR_USE);
}
break;
case 1:
if (_G(cur)->usingInventoryCursor()) {
inv_rand_x = -1;
inv_rand_y = -1;
ret_look = look(_G(cur)->getInventoryCursor(), INV_ATS_MODE, -1);
taste_flag = Common::KEYCODE_ESCAPE;
} else {
_G(invent_cur_mode) = CUR_LOOK;
_G(menu_item) = CUR_LOOK;
cursorChoice(CUR_LOOK);
}
break;
case 3:
g_events->setHotKey(Common::KEYCODE_PAGEUP);
break;
case 4:
g_events->setHotKey(Common::KEYCODE_PAGEDOWN);
break;
case 5:
inv_rand_x = (g_events->_mousePos.x - (WIN_INF_X)) / 54;
inv_rand_y = (g_events->_mousePos.y - (WIN_INF_Y + 4 + 30)) / 30;
k = inv_rand_x + (inv_rand_y * 5);
k += _G(gameState).InventY * 5;
if (_G(invent_cur_mode) == CUR_USE) {
if (!_G(cur)->usingInventoryCursor()) {
if (_G(gameState).InventSlot[k] != -1 && calc_use_invent(_G(gameState).InventSlot[k]) == false) {
_G(menu_item) = CUR_USE;
_G(cur)->setInventoryCursor(_G(gameState).InventSlot[k]);
del_invent_slot(_G(gameState).InventSlot[k]);
}
} else if (_G(gameState).InventSlot[k] != -1)
evaluateObj(_G(gameState).InventSlot[k], INVENTORY_NORMAL);
else {
_G(gameState).InventSlot[k] = _G(cur)->getInventoryCursor();
_G(obj)->sort();
_G(cur)->setInventoryCursor(-1);
_G(menu_item) = _G(invent_cur_mode);
cursorChoice(_G(invent_cur_mode));
}
} else if (_G(invent_cur_mode) == CUR_LOOK && _G(gameState).InventSlot[k] != -1 && calc_use_invent(_G(gameState).InventSlot[k]) == false) {
ret_look = look(_G(gameState).InventSlot[k], INV_ATS_MODE, -1);
cursorChoice(_G(invent_cur_mode));
taste_flag = Common::KEYCODE_ESCAPE;
}
break;
default:
break;
}
} else if (_G(minfo).button == 2 || g_events->_kbInfo._keyCode == Common::KEYCODE_ESCAPE) {
// Set virtual key
g_events->setHotKey(Common::KEYCODE_ESCAPE);
_G(minfo).button = 0;
g_events->_kbInfo._keyCode = '\0';
g_events->_kbInfo._scanCode = '\0';
}
if (ret_look == 0) {
_G(invent_cur_mode) = CUR_USE;
_G(menu_item) = CUR_USE;
if (!_G(cur)->usingInventoryCursor())
cursorChoice(CUR_USE);
} else if (ret_look == 5) {
taste_flag = false;
_G(minfo).button = 1;
}
ret_look = -1;
int16 keyCode = g_events->getSwitchCode();
// The original hid the cursor here
if (taste_flag) {
if (keyCode != taste_flag)
taste_flag = 0;
} else {
switch (keyCode) {
case Common::KEYCODE_ESCAPE:
if (!menuFirstFl) {
_G(cur)->showCursor();
while (g_events->getSwitchCode() == Common::KEYCODE_ESCAPE) {
SHOULD_QUIT_RETURN;
setupScreen(NO_SETUP);
inv_rand_x = -1;
inv_rand_y = -1;
plot_menu();
_G(cur)->updateCursor();
_G(out)->copyToScreen();
}
} else {
if (menu_flag1 != MENU_DISPLAY) {
menu_flag1 = MENU_HIDE;
_G(show_invent_menu) = false;
}
}
break;
case Common::KEYCODE_RIGHT:
if (g_events->_mousePos.x < 320 - _G(cur)->getCursorWidth())
g_events->_mousePos.x += 3;
break;
case Common::KEYCODE_LEFT:
if (g_events->_mousePos.x > 2)
g_events->_mousePos.x -= 3;
break;
case Common::KEYCODE_UP:
if (g_events->_mousePos.y > 2)
g_events->_mousePos.y -= 3;
break;
case Common::KEYCODE_DOWN:
if (g_events->_mousePos.y < 197 - _G(cur)->getCursorHeight())
g_events->_mousePos.y += 3;
break;
case Common::KEYCODE_PAGEUP:
if (_G(gameState).InventY > 0)
--_G(gameState).InventY;
g_events->_kbInfo._keyCode = '\0';
g_events->_kbInfo._scanCode = '\0';
break;
case Common::KEYCODE_PAGEDOWN:
if (_G(gameState).InventY < (MAX_MOV_OBJ / 5) - 3)
++_G(gameState).InventY;
g_events->_kbInfo._keyCode = '\0';
g_events->_kbInfo._scanCode = '\0';
break;
default:
break;
}
menuFirstFl = true;
}
if (_G(show_invent_menu) != 2) {
setupScreen(NO_SETUP);
if (menu_flag1 != MENU_HIDE) {
inv_rand_x = -1;
inv_rand_y = -1;
plot_menu();
}
if (menu_flag1 == false)
_G(cur)->updateCursor();
_G(out)->setPointer(nullptr);
if (menu_flag1 == MENU_DISPLAY) {
_G(fx)->blende1(_G(workptr), nullptr, 0, 300);
} else if (menu_flag1 == MENU_HIDE)
_G(fx)->blende1(_G(workptr), nullptr, 1, 300);
menu_flag1 = false;
_G(out)->copyToScreen();
} else {
showCur();
}
}
_G(cur)->move(_G(maus_old_x), _G(maus_old_y));
g_events->_mousePos.x = _G(maus_old_x);
g_events->_mousePos.y = _G(maus_old_y);
_G(minfo).button = 0;
while (g_events->getSwitchCode() == Common::KEYCODE_ESCAPE && !SHOULD_QUIT) {
setupScreen(NO_SETUP);
_G(cur)->updateCursor();
_G(out)->copyToScreen();
}
_G(flags).InventMenu = false;
_G(flags).AutoAniPlay = oldAutoAniPlay;
_G(gameState).DispFlag = oldDispFlag;
_G(menu_display) = _G(tmp_menu);
_G(flags).StopAutoObj = false;
}
int16 Inventory::look(int16 invent_nr, int16 mode, int16 ats_nr) {
int16 lineCount = 0;
int16 xoff = 0;
int16 yoff = 0;
int16 visibleCount = 0;
Common::String itemName;
Common::StringArray itemDesc;
char c[2] = { 0 };
int16 ret = -1;
bool endLoop = false;
int16 startLine = 0;
bool mouseFl = true;
bool firstTime = true;
if (mode == INV_ATS_MODE) {
itemName = _G(atds)->getTextEntry(invent_nr, TXT_MARK_NAME, INV_ATS_DATA);
itemDesc = _G(atds)->getTextArray(invent_nr, TXT_MARK_LOOK, INV_ATS_DATA);
lineCount = itemDesc.size();
xoff = itemName.size();
xoff *= _G(font8)->getDataWidth();
xoff = (254 - xoff) / 2;
visibleCount = 2;
yoff = 10;
} else if (mode == INV_USE_ATS_MODE) {
visibleCount = 3;
yoff = 0;
if (ats_nr >= 15000)
itemDesc = _G(atds)->getTextArray(0, ats_nr - 15000, INV_USE_DEF, -1);
else
itemDesc = _G(atds)->getTextArray(0, ats_nr, INV_USE_DATA, -1);
lineCount = itemDesc.size();
if (itemDesc.size() == 0)
endLoop = true;
} else {
endLoop = true;
}
const int16 speechId = _G(atds)->getLastSpeechId();
while (!endLoop) {
int16 rect = _G(out)->findHotspot(_G(inventoryHotspots));
if (_G(minfo).button) {
if (_G(minfo).button == 2) {
if (!mouseFl)
g_events->_kbInfo._scanCode = Common::KEYCODE_ESCAPE;
} else if (_G(minfo).button == 1) {
if (!mouseFl) {
switch (rect) {
case 0:
endLoop = true;
ret = 0;
break;
case 1:
endLoop = true;
ret = 1;
break;
case 3:
case 6:
g_events->_kbInfo._scanCode = Common::KEYCODE_UP;
break;
case 4:
case 7:
g_events->_kbInfo._scanCode = Common::KEYCODE_DOWN;
break;
case 5:
ret = 5;
endLoop = true;
break;
default:
break;
}
}
}
mouseFl = true;
} else {
mouseFl = false;
}
switch (g_events->_kbInfo._scanCode) {
case Common::KEYCODE_F1:
g_events->setHotKey(Common::KEYCODE_F1);
break;
case Common::KEYCODE_F2:
g_events->setHotKey(Common::KEYCODE_F2);
break;
case Common::KEYCODE_ESCAPE:
endLoop = true;
break;
case Common::KEYCODE_UP:
if (startLine > 0)
--startLine;
break;
case Common::KEYCODE_DOWN:
if (startLine < lineCount - visibleCount)
++startLine;
break;
default:
break;
}
g_events->_kbInfo._scanCode = Common::KEYCODE_INVALID;
setupScreen(NO_SETUP);
plot_menu();
if (mode == INV_ATS_MODE) {
_G(fontMgr)->setFont(_G(font8));
_G(out)->printxy(WIN_LOOK_X + xoff, WIN_LOOK_Y, 255, 300,
_G(scr_width), itemName.c_str());
}
_G(fontMgr)->setFont(_G(font6));
if (lineCount > visibleCount) {
if (startLine > 0) {
if (rect == 6)
_G(out)->boxFill(WIN_INF_X + 262, WIN_INF_Y + 136, WIN_INF_X + 272,
WIN_INF_Y + 136 + 14, 41);
c[0] = 24;
_G(out)->printxy(WIN_LOOK_X + 250, WIN_LOOK_Y + 4, 14, 300,
_G(scr_width), c);
}
if (startLine < lineCount - visibleCount) {
if (rect == 7)
_G(out)->boxFill(WIN_INF_X + 262, WIN_INF_Y + 156, WIN_INF_X + 272,
WIN_INF_Y + 156 + 14, 41);
c[0] = 25;
_G(out)->printxy(WIN_LOOK_X + 250, WIN_LOOK_Y + 24, 14, 300, _G(scr_width), c);
}
}
int16 k = 0;
if (itemDesc.size() > 0) {
for (int16 i = startLine; i < lineCount && i < startLine + visibleCount; i++) {
_G(out)->printxy(WIN_LOOK_X, WIN_LOOK_Y + yoff + k * 10, 14, 300,
_G(scr_width), itemDesc[i].c_str());
++k;
}
if (g_engine->_sound->speechEnabled() && speechId >= 0 && firstTime) {
g_engine->_sound->playSpeech(speechId, false);
firstTime = false;
}
}
_G(cur)->updateCursor();
_G(out)->copyToScreen();
SHOULD_QUIT_RETURN0;
}
while (g_events->getSwitchCode() == Common::KEYCODE_ESCAPE) {
setupScreen(NO_SETUP);
plot_menu();
_G(cur)->updateCursor();
_G(out)->copyToScreen();
SHOULD_QUIT_RETURN0;
}
return ret;
}
void Inventory::look_screen(int16 txt_mode, int16 txt_nr) {
int16 ok;
int16 m_mode = 0;
if (!_G(flags).AtsAction) {
if (txt_nr != -1) {
switch (txt_mode) {
case INVENTORY_NORMAL:
case INVENTORY_STATIC:
ok = true;
switch (_G(menu_item)) {
case CUR_LOOK:
m_mode = TXT_MARK_LOOK;
break;
case CUR_USE:
case CUR_USER:
case CUR_HOWARD:
case CUR_NICHELLE:
m_mode = TXT_MARK_USE;
if (_G(cur)->usingInventoryCursor())
ok = false;
break;
case CUR_WALK:
m_mode = TXT_MARK_WALK;
break;
case CUR_TALK:
m_mode = TXT_MARK_TALK;
break;
default:
break;
}
if (_G(atds)->getControlBit(txt_nr, ATS_ACTION_BIT)) {
atsAction(txt_nr, m_mode, ATS_ACTION_VOR);
}
if (ok) {
startAtsWait(txt_nr, m_mode, 14, ATS_DATA);
}
if (_G(atds)->getControlBit(txt_nr, ATS_ACTION_BIT))
atsAction(txt_nr, m_mode, ATS_ACTION_NACH);
if (_G(menu_item) == CUR_USE)
_G(flags).StaticUseTxt = true;
break;
default:
break;
}
}
}
}
bool Inventory::calc_use_invent(int16 invNr) {
bool retVal = false;
if (_G(menu_item) == CUR_LOOK) {
switch (invNr) {
case ZEITUNG_INV:
Rooms::Room44::look_news();
break;
case CUTMAG_INV:
_G(show_invent_menu) = 2;
retVal = true;
Rooms::Room58::look_cut_mag(58);
break;
case SPARK_INV:
_G(show_invent_menu) = 2;
retVal = true;
save_person_rnr();
Rooms::Room58::look_cut_mag(60);
break;
case DIARY_INV:
showDiary();
retVal = true;
break;
default:
break;
}
} else if (_G(menu_item) == CUR_USE && invNr == NOTEBOOK_INV) {
int16 id = del_invent_slot(NOTEBOOK_INV);
_G(gameState).InventSlot[id] = NOTEBOOK_OPEN_INV;
_G(obj)->changeInventory(NOTEBOOK_INV, NOTEBOOK_OPEN_INV, &_G(room_blk));
retVal = true;
}
return retVal;
}
// Shows the Hermit's diary
void Inventory::showDiary() {
int16 scrollx = _G(gameState).scrollx,
scrolly = _G(gameState).scrolly;
_G(gameState).scrollx = 0;
_G(gameState).scrolly = 0;
_G(cur)->hideCursor();
_G(room)->load_tgp(DIARY_START, &_G(room_blk), GBOOK_TGP, false, GBOOK);
_G(out)->setPointer(_G(workptr));
_G(out)->map_spr2screen(_G(ablage)[_G(room_blk).AkAblage], _G(gameState).scrollx, _G(gameState).scrolly);
_G(out)->copyToScreen();
_G(room)->set_ak_pal(&_G(room_blk));
_G(out)->setPointer(nullptr);
_G(fx)->blende1(_G(workptr), _G(pal), 0, 0);
while (g_events->getSwitchCode() != Common::KEYCODE_ESCAPE) {
g_events->update();
SHOULD_QUIT_RETURN;
}
_G(room)->load_tgp(_G(gameState)._personRoomNr[P_CHEWY], &_G(room_blk), EPISODE1_TGP, true, EPISODE1);
_G(gameState).scrollx = scrollx;
_G(gameState).scrolly = scrolly;
setupScreen(NO_SETUP);
plot_menu();
_G(out)->setPointer(nullptr);
_G(room)->set_ak_pal(&_G(room_blk));
_G(fx)->blende1(_G(workptr), _G(pal), 0, 0);
_G(cur)->showCursor();
}
} // namespace Dialogs
} // namespace Chewy

View File

@@ -0,0 +1,47 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CHEWY_DIALOGS_INVENTORY_H
#define CHEWY_DIALOGS_INVENTORY_H
#include "chewy/ngstypes.h"
namespace Chewy {
namespace Dialogs {
class Inventory {
private:
static int16 inv_rand_x;
static int16 inv_rand_y;
static bool calc_use_invent(int16 invNr);
static void showDiary();
public:
static void plot_menu();
static void menu();
static int16 look(int16 invent_nr, int16 mode, int16 ats_nr);
static void look_screen(int16 txt_mode, int16 txt_nr);
};
} // namespace Dialogs
} // namespace Chewy
#endif

View File

@@ -0,0 +1,257 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/config-manager.h"
#include "chewy/dialogs/main_menu.h"
#include "chewy/dialogs/cinema.h"
#include "chewy/dialogs/credits.h"
#include "chewy/dialogs/files.h"
#include "chewy/cursor.h"
#include "chewy/events.h"
#include "chewy/font.h"
#include "chewy/globals.h"
#include "chewy/main.h"
#include "chewy/mcga_graphics.h"
#include "chewy/sound.h"
namespace Chewy {
namespace Dialogs {
int MainMenu::_selection;
int MainMenu::_personAni[3];
void MainMenu::execute() {
// Convenience during testing to not keep showing title sequence
if (!ConfMan.getBool("skip_title")) {
g_engine->_sound->playMusic(17);
// NOTE: Originally, this was set to play video 200, but this actually
// jumped to the very last video in the file, so we play it explicitly
flic_cut(g_engine->getLanguage() == Common::Language::DE_DEU ? FCUT_155 : FCUT_160);
g_engine->_sound->stopMusic();
}
show_intro();
_G(cur)->move(152, 92);
g_events->_mousePos.x = 152;
g_events->_mousePos.y = 92;
_G(cur)->setInventoryCursor(-1);
_G(menu_display) = 0;
bool done = false;
while (!done && !SHOULD_QUIT) {
g_engine->_sound->stopAllSounds();
_G(SetUpScreenFunc) = screenFunc;
cursorChoice(CUR_POINT);
_selection = -1;
_G(gameState).scrollx = _G(gameState).scrolly = 0;
_G(gameState)._personRoomNr[P_CHEWY] = 98;
_G(room)->loadRoom(&_G(room_blk), 98, &_G(gameState));
g_engine->_sound->playRoomMusic(98);
_G(fx)->border(_G(workpage), 0, 0);
_G(out)->setPalette(_G(pal));
_G(gameState)._personHide[P_CHEWY] = true;
showCur();
// Wait for a selection to be made on the main menu
do {
animate();
if (SHOULD_QUIT)
return;
} while (_selection == -1);
switch (_selection) {
case MM_START_GAME:
EVENTS_CLEAR;
startGame();
playGame();
break;
case MM_VIEW_INTRO:
_G(fx)->border(_G(workpage), 0, 0);
_G(out)->setPointer(_G(workptr));
_G(flags).NoPalAfterFlc = true;
flic_cut(FCUT_135);
break;
case MM_LOAD_GAME:
if (loadGame())
playGame();
break;
case MM_CINEMA:
cursorChoice(CUR_SAVE);
_G(cur)->move(152, 92);
g_events->_mousePos.x = 152;
g_events->_mousePos.y = 92;
Dialogs::Cinema::execute();
break;
case MM_QUIT:
_G(out)->setPointer(nullptr);
_G(out)->cls();
done = true;
break;
case MM_CREDITS:
_G(fx)->border(_G(workpage), 0, 0);
_G(flags).NoPalAfterFlc = true;
flic_cut(FCUT_159);
_G(fx)->border(_G(workpage), 0, 0);
Dialogs::Credits::execute();
break;
default:
break;
}
}
}
void MainMenu::screenFunc() {
int vec = _G(det)->maus_vector(g_events->_mousePos.x + _G(gameState).scrollx, g_events->_mousePos.y + _G(gameState).scrolly);
if (g_events->getSwitchCode() == 28 || _G(minfo).button == 1) {
_selection = vec;
}
}
void MainMenu::animate() {
if (_G(ani_timer)->_timeFlag) {
_G(uhr)->resetTimer(0, 0);
_G(gameState).DelaySpeed = _G(FrameSpeed) / _G(gameState).FramesPerSecond;
_G(moveState)->Delay = _G(gameState).DelaySpeed + _G(spz_delay)[0];
_G(FrameSpeed) = 0;
_G(det)->set_global_delay(_G(gameState).DelaySpeed);
}
++_G(FrameSpeed);
_G(out)->setPointer(_G(workptr));
_G(out)->map_spr2screen(_G(ablage)[_G(room_blk).AkAblage],
_G(gameState).scrollx, _G(gameState).scrolly);
if (_G(SetUpScreenFunc) && !_G(menu_display) && !_G(flags).InventMenu) {
_G(SetUpScreenFunc)();
_G(out)->setPointer(_G(workptr));
}
spriteEngine();
kb_mov(1);
calcMouseText(g_events->_mousePos.x, g_events->_mousePos.y, 1);
_G(cur)->updateCursor();
_G(mouseLeftClick) = false;
_G(out)->setPointer(nullptr);
_G(out)->copyToScreen();
g_screen->update();
g_events->update();
}
void MainMenu::startGame() {
hideCur();
animate();
exit_room(-1);
uint8 framesPerSecond = _G(gameState).FramesPerSecond;
var_init();
_G(gameState).FramesPerSecond = framesPerSecond;
_G(gameState)._personRoomNr[P_CHEWY] = 0;
_G(room)->loadRoom(&_G(room_blk), 0, &_G(gameState));
_G(moveState)[P_CHEWY].Phase = 6;
_G(moveState)[P_CHEWY].PhAnz = _G(chewy_ph_nr)[6];
setPersonPos(160, 80, P_CHEWY, P_RIGHT);
_G(fx_blend) = BLEND3;
_G(gameState)._personHide[P_CHEWY] = false;
_G(menu_item) = CUR_WALK;
cursorChoice(CUR_WALK);
enter_room(-1);
_G(auto_obj) = 0;
}
bool MainMenu::loadGame() {
_G(flags).SaveMenu = true;
savePersonAni();
_G(out)->setPointer((byte *)g_screen->getPixels());
_G(fontMgr)->setFont(_G(font6));
cursorChoice(CUR_SAVE);
_G(cur)->move(152, 92);
g_events->_mousePos.x = 152;
g_events->_mousePos.y = 92;
_G(savegameFlag) = true;
int result = Files::execute(false);
cursorChoice((_G(cur)->usingInventoryCursor() && _G(menu_item) == CUR_USE) ? 8 : 0);
restorePersonAni();
_G(flags).SaveMenu = false;
if (result == 0) {
_G(fx_blend) = BLEND1;
return true;
} else {
return false;
}
}
void MainMenu::playGame() {
// unused1 = 0;
_G(inv_disp_ok) = false;
_G(tmp_menu_item) = 0;
_G(mouseLeftClick) = false;
g_events->_kbInfo._scanCode = Common::KEYCODE_INVALID;
_G(flags).mainMouseFlag = false;
_G(flags).MainInput = true;
_G(flags).ShowAtsInvTxt = true;
_G(cur)->showCursor();
_G(moveState)[P_CHEWY].Count = 0;
_G(uhr)->resetTimer(0, 0);
while (!SHOULD_QUIT && !mainLoop(1)) {
}
_G(auto_obj) = 0;
}
void MainMenu::savePersonAni() {
for (int i = 0; i < MAX_PERSON; ++i) {
_personAni[i] = _G(PersonAni)[i];
_G(PersonAni)[i] = -1;
delete _G(PersonTaf)[i];
_G(PersonTaf)[i] = nullptr;
}
}
void MainMenu::restorePersonAni() {
for (int i = 0; i < MAX_PERSON; ++i) {
load_person_ani(_personAni[i], i);
}
}
} // namespace Dialogs
} // namespace Chewy

View File

@@ -0,0 +1,90 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CHEWY_MAIN_MENU_H
#define CHEWY_MAIN_MENU_H
#include "chewy/events.h"
namespace Chewy {
namespace Dialogs {
enum MainMenuSelection {
MM_START_GAME = 0,
MM_VIEW_INTRO = 1,
MM_LOAD_GAME = 2,
MM_CINEMA = 3,
MM_QUIT = 4,
MM_CREDITS = 5
};
class MainMenu {
private:
static int _selection;
static int _personAni[3];
/**
* Screen rendering function for the main menu
*/
static void screenFunc();
/**
* Animates the contents of the main menu,
* and checks for any option selection
*/
static void animate();
/**
* Starts a new game
*/
static void startGame();
/**
* Starts a new game
*/
static bool loadGame();
/**
* Saves the personAni array
*/
static void savePersonAni();
/**
* Restores the personAni array
*/
static void restorePersonAni();
public:
/**
* Displays the menu
*/
static void execute();
/**
* Plays the game
*/
static void playGame();
};
} // namespace Dialogs
} // namespace Chewy
#endif

View File

@@ -0,0 +1,263 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "chewy/dialogs/options.h"
#include "chewy/cursor.h"
#include "chewy/events.h"
#include "chewy/globals.h"
#include "chewy/mcga_graphics.h"
#include "chewy/sound.h"
#include "common/config-manager.h"
namespace Chewy {
namespace Dialogs {
#define SURIMY_START 0
#define SURIMY_END 7
#define SCHNULLER 8
#define SCHNULL_BAND 22
#define MUND_START 9
#define MUND_END 11
#define SCHNULL_OFF 23
#define TDISP_START 12
#define TDISP_END 13
#define TDISP_EIN 20
#define TDISP_AUS 21
#define MUSIC_OFF 24
#define MUSIC_ON1 25
#define MUSIC_ON2 26
#define EXIT 27
void Options::execute(TafInfo *ti) {
long akt_clock = 0, stop_clock = 0;
_G(room)->load_tgp(0, &_G(room_blk), GBOOK_TGP, false, GBOOK);
_G(out)->setPointer(_G(workptr));
_G(out)->map_spr2screen(_G(ablage)[_G(room_blk).AkAblage], 0, 0);
_G(out)->setPointer((byte *)g_screen->getPixels());
_G(room)->set_ak_pal(&_G(room_blk));
_G(fx)->blende1(_G(workptr), _G(pal), 0, 0);
_G(out)->setPointer(_G(workptr));
int16 key = 0;
int16 surimy_ani = SURIMY_START;
int16 mund_ani = MUND_START;
int16 mund_delay = 3;
int16 mund_count = mund_delay;
_G(FrameSpeed) = 0;
int16 delay_count = _G(gameState).DelaySpeed;
//warning("stop_clock = (clock() / CLK_TCK) + 1;");
while (key != Common::KEYCODE_ESCAPE) {
_G(out)->map_spr2screen(_G(ablage)[_G(room_blk).AkAblage], 0, 0);
++_G(FrameSpeed);
//warning("akt_clock = clock() / CLK_TCK;");
if (akt_clock >= stop_clock) {
//TmpFrame = _G(FrameSpeed);
_G(gameState).DelaySpeed = (_G(FrameSpeed) >> 1) / _G(gameState).FramesPerSecond;
_G(FrameSpeed) = 0;
//warning("stop_clock = (clock() / CLK_TCK) + 1;");
}
_G(out)->spriteSet(ti->image[surimy_ani], 18 + ti->correction[surimy_ani << 1],
8 + ti->correction[(surimy_ani << 1) + 1], 0);
short bar_off = (_G(gameState).FramesPerSecond - 6) * 16;
_G(out)->boxFill(33 + bar_off, 65, 33 + 17 + bar_off, 65 + 8, 0);
Common::String fps = Common::String::format("%d", _G(gameState).FramesPerSecond << 1);
_G(out)->printxy(36 + bar_off, 65, 255, 300, 0, fps.c_str());
if (g_engine->_sound->speechEnabled()) {
_G(out)->spriteSet(ti->image[mund_ani],
18 + ti->correction[mund_ani << 1],
8 + ti->correction[(mund_ani << 1) + 1], 0);
_G(out)->spriteSet(ti->image[SCHNULL_OFF],
18 + ti->correction[SCHNULL_OFF << 1],
8 + ti->correction[(SCHNULL_OFF << 1) + 1], 0);
} else {
_G(out)->spriteSet(ti->image[SCHNULLER],
18 + ti->correction[SCHNULLER << 1],
8 + ti->correction[(SCHNULLER << 1) + 1], 0);
_G(out)->spriteSet(ti->image[SCHNULL_BAND],
18 + ti->correction[SCHNULL_BAND << 1],
8 + ti->correction[(SCHNULL_BAND << 1) + 1], 0);
}
const int soundVolume = MAX(1, g_engine->_sound->getUserSoundVolume() * 32 / Audio::Mixer::kMaxMixerVolume);
_G(out)->pop_box(32 - 2, 104 - 12, 42 + 4, 136 + 2, 192, 183, 182);
_G(out)->printxy(32 + 3, 104 - 10, 15, 300, 0, "S");
_G(out)->boxFill(33, 136 - soundVolume, 42, 136, 15);
const int musicVolume = MAX(1, g_engine->_sound->getUserMusicVolume() * 32 / Audio::Mixer::kMaxMixerVolume);
_G(out)->pop_box(52 - 2, 104 - 12, 62 + 4, 136 + 2, 192, 183, 182);
_G(out)->printxy(52 + 3, 104 - 10, 31, 300, 0, "M");
_G(out)->boxFill(53, 136 - musicVolume, 62, 136, 31);
if (g_engine->_sound->musicEnabled()) {
_G(out)->spriteSet(ti->image[MUSIC_ON1],
18 + ti->correction[MUSIC_ON1 << 1],
8 + ti->correction[(MUSIC_ON1 << 1) + 1], 0);
_G(out)->spriteSet(ti->image[MUSIC_ON2],
18 + ti->correction[MUSIC_ON2 << 1],
8 + ti->correction[(MUSIC_ON2 << 1) + 1], 0);
} else
_G(out)->spriteSet(ti->image[MUSIC_OFF],
18 + ti->correction[MUSIC_OFF << 1],
8 + ti->correction[(MUSIC_OFF << 1) + 1], 0);
if (g_engine->_sound->soundEnabled()) {
_G(out)->spriteSet(ti->image[TDISP_START],
ti->correction[TDISP_START << 1],
ti->correction[(TDISP_START << 1) + 1], 0);
_G(out)->spriteSet(ti->image[TDISP_EIN],
18 + ti->correction[TDISP_EIN << 1],
8 + ti->correction[(TDISP_EIN << 1) + 1], 0);
} else {
_G(out)->spriteSet(ti->image[TDISP_END],
ti->correction[TDISP_END << 1],
ti->correction[(TDISP_END << 1) + 1], 0);
_G(out)->spriteSet(ti->image[TDISP_AUS],
18 + ti->correction[TDISP_AUS << 1],
8 + ti->correction[(TDISP_AUS << 1) + 1], 0);
}
_G(out)->spriteSet(ti->image[EXIT],
18 + ti->correction[EXIT << 1],
8 + ti->correction[(EXIT << 1) + 1], 0);
key = g_events->getSwitchCode();
if ((_G(minfo).button == 1) || (key == Common::KEYCODE_RETURN)) {
// TODO This line breaks screen updates. Not sure what it does
// otherwise; options screen seems to work without it.
//WAIT_TASTE_LOS
int16 rect = _G(out)->findHotspot(_G(optionHotspots));
switch (rect) {
case 0: // Hamster wheel arrow left (speed down)
if (_G(gameState).FramesPerSecond > 6)
--_G(gameState).FramesPerSecond;
break;
case 1: // Hamster wheel arrow right (speed up)
if (_G(gameState).FramesPerSecond < 10)
++_G(gameState).FramesPerSecond;
break;
case 2: // Mouth (speech/subtitles)
if (!g_engine->_sound->speechEnabled()) {
g_engine->_sound->toggleSubtitles(false);
g_engine->_sound->toggleSpeech(true);
} else {
g_engine->_sound->toggleSubtitles(true);
g_engine->_sound->toggleSpeech(false);
}
g_engine->syncSoundSettings();
break;
case 3:
case 4: // Speaker (sound)
if (g_engine->_sound->soundEnabled()) {
g_engine->_sound->toggleSound(false);
} else {
g_engine->_sound->toggleSound(true);
}
g_engine->syncSoundSettings();
break;
case 5: // Guitarist (music)
if (g_engine->_sound->musicEnabled()) {
g_engine->_sound->toggleMusic(false);
g_engine->_sound->stopMusic();
} else {
g_engine->_sound->toggleMusic(true);
g_engine->_sound->playRoomMusic(_G(gameState)._personRoomNr[P_CHEWY]);
}
g_engine->syncSoundSettings();
break;
case 6: // Door (exit)
key = Common::KEYCODE_ESCAPE;
break;
case 7: // S volume gauge
g_engine->_sound->setUserSoundVolume(MIN(32, 136 - g_events->_mousePos.y) * Audio::Mixer::kMaxMixerVolume / 32);
g_engine->syncSoundSettings();
break;
case 8: // M volume gauge
g_engine->_sound->setUserMusicVolume(MIN(32, 136 - g_events->_mousePos.y) * Audio::Mixer::kMaxMixerVolume / 32);
g_engine->syncSoundSettings();
break;
default:
break;
}
_G(minfo).button = 0;
}
switch (key) {
case Common::KEYCODE_UP:
_G(cur)->move(g_events->_mousePos.x, --g_events->_mousePos.y);
break;
case Common::KEYCODE_DOWN:
_G(cur)->move(g_events->_mousePos.x, ++g_events->_mousePos.y);
break;
case Common::KEYCODE_LEFT:
_G(cur)->move(--g_events->_mousePos.x, g_events->_mousePos.y);
break;
case Common::KEYCODE_RIGHT:
_G(cur)->move(++g_events->_mousePos.x, g_events->_mousePos.y);
break;
default:
break;
}
_G(cur)->updateCursor();
_G(out)->copyToScreen();
EVENTS_UPDATE;
SHOULD_QUIT_RETURN;
if (!delay_count) {
if (surimy_ani < SURIMY_END)
++surimy_ani;
else
surimy_ani = SURIMY_START;
if (mund_count > 0)
--mund_count;
else {
if (mund_ani < MUND_END)
++mund_ani;
else
mund_ani = MUND_START;
mund_count = mund_delay;
}
delay_count = _G(gameState).DelaySpeed;
} else
--delay_count;
}
_G(room)->load_tgp(1, &_G(room_blk), GBOOK_TGP, false, GBOOK);
_G(out)->setPointer(_G(workptr));
_G(out)->map_spr2screen(_G(ablage)[_G(room_blk).AkAblage], 0, 0);
_G(out)->setPointer((byte *)g_screen->getPixels());
_G(room)->set_ak_pal(&_G(room_blk));
_G(fx)->blende1(_G(workptr), _G(pal), 0, 0);
_G(out)->setPointer(_G(workptr));
}
} // namespace Dialogs
} // namespace Chewy

View File

@@ -0,0 +1,38 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CHEWY_DIALOGS_OPTIONS_H
#define CHEWY_DIALOGS_OPTIONS_H
#include "chewy/ngstypes.h"
namespace Chewy {
namespace Dialogs {
class Options {
public:
static void execute(TafInfo *ti);
};
} // namespace Dialogs
} // namespace Chewy
#endif