Initial commit
This commit is contained in:
296
engines/glk/comprehend/comprehend.cpp
Normal file
296
engines/glk/comprehend/comprehend.cpp
Normal file
@@ -0,0 +1,296 @@
|
||||
/* 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 "glk/comprehend/comprehend.h"
|
||||
#include "glk/comprehend/debugger.h"
|
||||
#include "glk/comprehend/draw_surface.h"
|
||||
#include "glk/comprehend/game.h"
|
||||
#include "glk/comprehend/game_cc.h"
|
||||
#include "glk/comprehend/game_data.h"
|
||||
#include "glk/comprehend/game_oo.h"
|
||||
#include "glk/comprehend/game_tm.h"
|
||||
#include "glk/comprehend/game_tr1.h"
|
||||
#include "glk/comprehend/game_tr2.h"
|
||||
#include "glk/comprehend/pics.h"
|
||||
#include "glk/quetzal.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/ustr.h"
|
||||
#include "engines/util.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace Comprehend {
|
||||
|
||||
// Even with no ScummVM scaling, internally we do a 2x scaling to
|
||||
// render on a 640x480 window, to allow for better looking text
|
||||
#define SCALE_FACTOR 2
|
||||
|
||||
Comprehend *g_comprehend;
|
||||
|
||||
Comprehend::Comprehend(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
|
||||
_topWindow(nullptr), _bottomWindow(nullptr), _roomDescWindow(nullptr),
|
||||
_drawSurface(nullptr), _game(nullptr), _pics(nullptr), _saveSlot(-1),
|
||||
_graphicsEnabled(true), _drawFlags(0), _disableSaves(false) {
|
||||
g_comprehend = this;
|
||||
}
|
||||
|
||||
Comprehend::~Comprehend() {
|
||||
delete _drawSurface;
|
||||
delete _game;
|
||||
SearchMan.remove("Pics"); // This also deletes it
|
||||
|
||||
g_comprehend = nullptr;
|
||||
}
|
||||
|
||||
void Comprehend::initGraphicsMode() {
|
||||
Graphics::PixelFormat pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
|
||||
initGraphics(640, 400, &pixelFormat);
|
||||
}
|
||||
|
||||
void Comprehend::createConfiguration() {
|
||||
GlkAPI::createConfiguration();
|
||||
switchToWhiteOnBlack();
|
||||
}
|
||||
|
||||
void Comprehend::runGame() {
|
||||
initialize();
|
||||
|
||||
// Lookup game
|
||||
createGame();
|
||||
|
||||
_game->loadGame();
|
||||
_game->playGame();
|
||||
|
||||
deinitialize();
|
||||
}
|
||||
|
||||
void Comprehend::initialize() {
|
||||
_bottomWindow = (TextBufferWindow *)glk_window_open(nullptr, 0, 0, wintype_TextBuffer, 1);
|
||||
glk_set_window(_bottomWindow);
|
||||
|
||||
showGraphics();
|
||||
_topWindow->fillRect(0, Rect(0, 0, _topWindow->_w, _topWindow->_h));
|
||||
|
||||
// Initialize drawing surface, and the archive that abstracts
|
||||
// the room and item graphics as as individual files
|
||||
_drawSurface = new DrawSurface();
|
||||
_pics = new Pics();
|
||||
SearchMan.add("Pics", _pics, 99, true);
|
||||
|
||||
// Check for savegame to load
|
||||
_saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
|
||||
}
|
||||
|
||||
void Comprehend::deinitialize() {
|
||||
glk_window_close(_topWindow);
|
||||
glk_window_close(_bottomWindow);
|
||||
glk_window_close(_roomDescWindow);
|
||||
}
|
||||
|
||||
void Comprehend::createDebugger() {
|
||||
setDebugger(new Debugger());
|
||||
}
|
||||
|
||||
void Comprehend::createGame() {
|
||||
if (_gameDescription._gameId == "crimsoncrown")
|
||||
_game = new CrimsonCrownGame();
|
||||
else if (_gameDescription._gameId == "ootopos")
|
||||
_game = new OOToposGame();
|
||||
else if (_gameDescription._gameId == "talisman")
|
||||
_game = new TalismanGame();
|
||||
else if (_gameDescription._gameId == "transylvania")
|
||||
_game = new TransylvaniaGame1();
|
||||
else if (_gameDescription._gameId == "transylvaniav2")
|
||||
_game = new TransylvaniaGame2();
|
||||
else
|
||||
error("Unknown game");
|
||||
}
|
||||
|
||||
void Comprehend::print(const char *fmt, ...) {
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
Common::String msg = Common::String::vformat(fmt, argp);
|
||||
va_end(argp);
|
||||
|
||||
glk_put_string_stream(glk_window_get_stream(_bottomWindow), msg.c_str());
|
||||
}
|
||||
|
||||
void Comprehend::print_u32_internal(const Common::U32String *fmt, ...) {
|
||||
Common::U32String outputMsg;
|
||||
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
Common::U32String::vformat(fmt->begin(), fmt->end(), outputMsg, argp);
|
||||
va_end(argp);
|
||||
|
||||
glk_put_string_stream_uni(glk_window_get_stream(_bottomWindow), outputMsg.u32_str());
|
||||
}
|
||||
|
||||
void Comprehend::printRoomDesc(const Common::String &desc) {
|
||||
if (_roomDescWindow) {
|
||||
glk_window_clear(_roomDescWindow);
|
||||
|
||||
// Get the grid width and do a word wrap
|
||||
uint width;
|
||||
glk_window_get_size(_roomDescWindow, &width, nullptr);
|
||||
Common::String str = desc;
|
||||
str.wordWrap(width - 2);
|
||||
str += '\n';
|
||||
|
||||
// Display the room description
|
||||
while (!str.empty()) {
|
||||
size_t idx = str.findFirstOf('\n');
|
||||
Common::String line = Common::String::format(" %s", Common::String(str.c_str(), str.c_str() + idx + 1).c_str());
|
||||
glk_put_string_stream(glk_window_get_stream(_roomDescWindow), line.c_str());
|
||||
|
||||
str = Common::String(str.c_str() + idx + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Comprehend::readLine(char *buffer, size_t maxLen) {
|
||||
event_t ev;
|
||||
|
||||
glk_request_line_event(_bottomWindow, buffer, maxLen - 1, 0);
|
||||
|
||||
for (;;) {
|
||||
glk_select(&ev);
|
||||
if (ev.type == evtype_Quit) {
|
||||
glk_cancel_line_event(_bottomWindow, &ev);
|
||||
return;
|
||||
} else if (ev.type == evtype_LineInput)
|
||||
break;
|
||||
}
|
||||
|
||||
buffer[ev.val1] = 0;
|
||||
debug(1, "\n> %s", buffer);
|
||||
}
|
||||
|
||||
int Comprehend::readChar() {
|
||||
glk_request_char_event(_bottomWindow);
|
||||
setDisableSaves(true);
|
||||
|
||||
event_t ev;
|
||||
while (ev.type != evtype_CharInput) {
|
||||
glk_select(&ev);
|
||||
|
||||
if (ev.type == evtype_Quit) {
|
||||
glk_cancel_char_event(_bottomWindow);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
setDisableSaves(false);
|
||||
return ev.val1;
|
||||
}
|
||||
|
||||
Common::Error Comprehend::readSaveData(Common::SeekableReadStream *rs) {
|
||||
Common::Serializer s(rs, nullptr);
|
||||
_game->synchronizeSave(s);
|
||||
|
||||
_game->_updateFlags = UPDATE_ALL;
|
||||
|
||||
if (isInputLineActive()) {
|
||||
// Restored game using GMM, so update grpahics and print room description
|
||||
g_comprehend->print("\n");
|
||||
_game->update();
|
||||
|
||||
g_comprehend->print("> ");
|
||||
}
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
Common::Error Comprehend::writeGameData(Common::WriteStream *ws) {
|
||||
Common::Serializer s(nullptr, ws);
|
||||
_game->synchronizeSave(s);
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
bool Comprehend::loadLauncherSavegameIfNeeded() {
|
||||
if (_saveSlot != -1) {
|
||||
return loadGameState(_saveSlot).getCode() == Common::kNoError;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Comprehend::drawPicture(uint pictureNum) {
|
||||
if (_topWindow) {
|
||||
// Clear the picture cache before each drawing in OO-Topos. Wearing the goggles
|
||||
// can producing different versions of the same scene, so we can't cache it
|
||||
if (_gameDescription._gameId == "ootopos")
|
||||
_pictures->clear();
|
||||
|
||||
glk_image_draw_scaled(_topWindow, pictureNum,
|
||||
20 * SCALE_FACTOR, 0, G_RENDER_WIDTH * SCALE_FACTOR, G_RENDER_HEIGHT * SCALE_FACTOR);
|
||||
}
|
||||
}
|
||||
|
||||
void Comprehend::drawLocationPicture(int pictureNum, bool clearBg) {
|
||||
drawPicture(pictureNum + (clearBg ? LOCATIONS_OFFSET : LOCATIONS_NO_BG_OFFSET));
|
||||
}
|
||||
|
||||
void Comprehend::drawItemPicture(int pictureNum) {
|
||||
drawPicture(pictureNum + ITEMS_OFFSET);
|
||||
}
|
||||
|
||||
void Comprehend::clearScreen(bool isBright) {
|
||||
drawPicture(isBright ? BRIGHT_ROOM : DARK_ROOM);
|
||||
}
|
||||
|
||||
bool Comprehend::toggleGraphics() {
|
||||
if (_topWindow) {
|
||||
// Remove the picture window
|
||||
glk_window_close(_topWindow);
|
||||
_topWindow = nullptr;
|
||||
_graphicsEnabled = false;
|
||||
|
||||
// Add the room description window
|
||||
_roomDescWindow = (TextGridWindow *)glk_window_open(_bottomWindow,
|
||||
winmethod_Above | winmethod_Fixed, 5, wintype_TextGrid, 1);
|
||||
return false;
|
||||
|
||||
} else {
|
||||
glk_window_close(_roomDescWindow);
|
||||
_roomDescWindow = nullptr;
|
||||
|
||||
// Create the window again
|
||||
showGraphics();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void Comprehend::showGraphics() {
|
||||
if (!_topWindow) {
|
||||
_topWindow = (GraphicsWindow *)glk_window_open(_bottomWindow,
|
||||
winmethod_Above | winmethod_Fixed,
|
||||
160 * SCALE_FACTOR, wintype_Graphics, 2);
|
||||
_graphicsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Comprehend::isInputLineActive() const {
|
||||
return _bottomWindow->_lineRequest || _bottomWindow->_lineRequestUni;
|
||||
}
|
||||
|
||||
} // namespace Comprehend
|
||||
} // namespace Glk
|
||||
Reference in New Issue
Block a user