diff options
author | Filippos Karapetis | 2016-10-04 02:27:22 +0300 |
---|---|---|
committer | Filippos Karapetis | 2016-10-04 02:27:22 +0300 |
commit | 19dab45c8c8bbca6aedce0574ffa44ab27715172 (patch) | |
tree | 9759cf8c7e6dc98fb542450baaf19c5594e6c4a6 | |
parent | cec2799c64d996dba247669c6eedfbffacc5f384 (diff) | |
download | scummvm-rg350-19dab45c8c8bbca6aedce0574ffa44ab27715172.tar.gz scummvm-rg350-19dab45c8c8bbca6aedce0574ffa44ab27715172.tar.bz2 scummvm-rg350-19dab45c8c8bbca6aedce0574ffa44ab27715172.zip |
CHEWY: Initial support for in-game texts (game dialog texts)
-rw-r--r-- | engines/chewy/chewy.cpp | 3 | ||||
-rw-r--r-- | engines/chewy/chewy.h | 2 | ||||
-rw-r--r-- | engines/chewy/console.cpp | 41 | ||||
-rw-r--r-- | engines/chewy/console.h | 1 | ||||
-rw-r--r-- | engines/chewy/graphics.cpp | 1 | ||||
-rw-r--r-- | engines/chewy/module.mk | 1 | ||||
-rw-r--r-- | engines/chewy/resource.cpp | 77 | ||||
-rw-r--r-- | engines/chewy/resource.h | 21 | ||||
-rw-r--r-- | engines/chewy/text.cpp | 160 | ||||
-rw-r--r-- | engines/chewy/text.h | 105 |
10 files changed, 305 insertions, 107 deletions
diff --git a/engines/chewy/chewy.cpp b/engines/chewy/chewy.cpp index 0f2e9c30a8..3845bfd4d1 100644 --- a/engines/chewy/chewy.cpp +++ b/engines/chewy/chewy.cpp @@ -35,6 +35,7 @@ #include "chewy/graphics.h" #include "chewy/resource.h" #include "chewy/sound.h" +#include "chewy/text.h" namespace Chewy { @@ -56,6 +57,7 @@ ChewyEngine::ChewyEngine(OSystem *syst, const ChewyGameDescription *gameDesc) ChewyEngine::~ChewyEngine() { delete _events; + delete _text; delete _sound; delete _graphics; delete _console; @@ -65,6 +67,7 @@ void ChewyEngine::initialize() { _console = new Console(this); _graphics = new Graphics(this); _sound = new Sound(_mixer); + _text = new Text(); _events = new Events(this, _graphics, _console); _curCursor = 0; diff --git a/engines/chewy/chewy.h b/engines/chewy/chewy.h index 34a3d5f4ba..7caed6ed75 100644 --- a/engines/chewy/chewy.h +++ b/engines/chewy/chewy.h @@ -41,6 +41,7 @@ class Console; class Events; class Graphics; class Sound; +class Text; class ChewyEngine : public Engine { public: @@ -59,6 +60,7 @@ public: Graphics *_graphics; Sound *_sound; + Text *_text; protected: // Engine APIs diff --git a/engines/chewy/console.cpp b/engines/chewy/console.cpp index a681c8997e..7fefe45ad0 100644 --- a/engines/chewy/console.cpp +++ b/engines/chewy/console.cpp @@ -27,19 +27,21 @@ #include "chewy/graphics.h" #include "chewy/resource.h" #include "chewy/sound.h" +#include "chewy/text.h" namespace Chewy { Console::Console(ChewyEngine *vm) : GUI::Debugger(), _vm(vm) { - registerCmd("dump", WRAP_METHOD(Console, Cmd_Dump)); - registerCmd("dump_bg", WRAP_METHOD(Console, Cmd_DumpBg)); - registerCmd("draw", WRAP_METHOD(Console, Cmd_Draw)); - registerCmd("play_sound", WRAP_METHOD(Console, Cmd_PlaySound)); - registerCmd("play_speech", WRAP_METHOD(Console, Cmd_PlaySpeech)); - registerCmd("play_music", WRAP_METHOD(Console, Cmd_PlayMusic)); - registerCmd("play_video", WRAP_METHOD(Console, Cmd_PlayVideo)); - registerCmd("video_info", WRAP_METHOD(Console, Cmd_VideoInfo)); + registerCmd("dump", WRAP_METHOD(Console, Cmd_Dump)); + registerCmd("dump_bg", WRAP_METHOD(Console, Cmd_DumpBg)); + registerCmd("draw", WRAP_METHOD(Console, Cmd_Draw)); + registerCmd("play_sound", WRAP_METHOD(Console, Cmd_PlaySound)); + registerCmd("play_speech", WRAP_METHOD(Console, Cmd_PlaySpeech)); + registerCmd("play_music", WRAP_METHOD(Console, Cmd_PlayMusic)); + registerCmd("play_video", WRAP_METHOD(Console, Cmd_PlayVideo)); + registerCmd("video_info", WRAP_METHOD(Console, Cmd_VideoInfo)); registerCmd("error_message", WRAP_METHOD(Console, Cmd_ErrorMessage)); + registerCmd("dialog", WRAP_METHOD(Console, Cmd_Dialog)); } Console::~Console() { @@ -178,7 +180,7 @@ bool Console::Cmd_VideoInfo(int argc, const char **argv) { } bool Console::Cmd_ErrorMessage(int argc, const char **argv) { - if (argc < 2) { + if (argc < 3) { debugPrintf("Usage: error_message <file> <message number>\n"); return true; } @@ -194,4 +196,25 @@ bool Console::Cmd_ErrorMessage(int argc, const char **argv) { return true; } +bool Console::Cmd_Dialog(int argc, const char **argv) { + if (argc < 3) { + debugPrintf("Usage: dialog <dialog> <entry>\n"); + return true; + } + + int dialogNum = atoi(argv[1]); + int entryNum = atoi(argv[2]); + uint cur = 0; + DialogList *d = _vm->_text->getDialog(dialogNum, entryNum); + + for (DialogList::iterator it = d->begin(); it != d->end(); ++it) { + this->debugPrintf("Entry %d: speech %d, text '%s'\n", cur, (*it).speechId, (*it).text.c_str()); + } + + d->clear(); + delete d; + + return true; +} + } // End of namespace Chewy diff --git a/engines/chewy/console.h b/engines/chewy/console.h index a4ffbe8ada..122f79cf51 100644 --- a/engines/chewy/console.h +++ b/engines/chewy/console.h @@ -46,6 +46,7 @@ private: bool Cmd_PlayVideo(int argc, const char **argv); bool Cmd_VideoInfo(int argc, const char **argv); bool Cmd_ErrorMessage(int argc, const char **argv); + bool Cmd_Dialog(int argc, const char **argv); }; } // End of namespace Chewy diff --git a/engines/chewy/graphics.cpp b/engines/chewy/graphics.cpp index 6f72d04a21..de95b11440 100644 --- a/engines/chewy/graphics.cpp +++ b/engines/chewy/graphics.cpp @@ -28,6 +28,7 @@ #include "chewy/graphics.h" #include "chewy/resource.h" +#include "chewy/text.h" #include "chewy/video/cfo_decoder.h" namespace Chewy { diff --git a/engines/chewy/module.mk b/engines/chewy/module.mk index bc82a3f299..38b4265d41 100644 --- a/engines/chewy/module.mk +++ b/engines/chewy/module.mk @@ -8,6 +8,7 @@ MODULE_OBJS = \ graphics.o \ resource.o \ sound.o \ + text.o \ video/cfo_decoder.o # This module can be built as a plugin diff --git a/engines/chewy/resource.cpp b/engines/chewy/resource.cpp index 352e2f11d7..07af79825c 100644 --- a/engines/chewy/resource.cpp +++ b/engines/chewy/resource.cpp @@ -21,7 +21,6 @@ */ #include "common/debug.h" -#include "common/rect.h" #include "common/stream.h" #include "common/substream.h" #include "common/textconsole.h" @@ -283,24 +282,6 @@ SoundChunk *SoundResource::getSound(uint num) { return sound; } -Common::String ErrorMessage::getErrorMessage(uint num) { - assert(num < _chunkList.size()); - - Chunk *chunk = &_chunkList[num]; - Common::String str; - byte *data = new byte[chunk->size]; - - _stream.seek(chunk->pos, SEEK_SET); - _stream.read(data, chunk->size); - if (_encrypted) - decrypt(data, chunk->size); - - str = (char *)data; - delete[] data; - - return str; -} - VideoChunk *VideoResource::getVideoHeader(uint num) { assert(num < _chunkList.size()); @@ -329,62 +310,4 @@ Common::SeekableReadStream *VideoResource::getVideoStream(uint num) { return new Common::SeekableSubReadStream(&_stream, chunk->pos, chunk->pos + chunk->size); } -Font::Font(Common::String filename) { - const uint32 headerFont = MKTAG('T', 'F', 'F', '\0'); - Common::File stream; - - stream.open(filename); - - uint32 header = stream.readUint32BE(); - - if (header != headerFont) - error("Invalid resource - %s", filename.c_str()); - - stream.skip(4); // total memory - _count = stream.readUint16LE(); - _first = stream.readUint16LE(); - _last = stream.readUint16LE(); - _width = stream.readUint16LE(); - _height = stream.readUint16LE(); - - _fontSurface.create(_width * _count, _height, ::Graphics::PixelFormat::createFormatCLUT8()); - - byte cur; - int bitIndex = 7; - byte *p; - - cur = stream.readByte(); - - for (uint n = 0; n < _count; n++) { - for (uint y = 0; y < _height; y++) { - for (uint x = n * _width; x < n * _width + _width; x++) { - p = (byte *)_fontSurface.getBasePtr(x, y); - *p = (cur & (1 << bitIndex)) ? 0 : 0xFF; - - bitIndex--; - if (bitIndex < 0) { - bitIndex = 7; - cur = stream.readByte(); - } - } - } - } -} - -Font::~Font() { - _fontSurface.free(); -} - -::Graphics::Surface *Font::getLine(Common::String text) { - ::Graphics::Surface *line = new ::Graphics::Surface(); - line->create(text.size() * _width, _height, ::Graphics::PixelFormat::createFormatCLUT8()); - - for (uint i = 0; i < text.size(); i++) { - uint x = (text[i] - _first) * _width; - line->copyRectToSurface(_fontSurface, i * _width, 0, Common::Rect(x, 0, x + _width, _height)); - } - - return line; -} - } // End of namespace Chewy diff --git a/engines/chewy/resource.h b/engines/chewy/resource.h index 7a79beb269..abccc9680d 100644 --- a/engines/chewy/resource.h +++ b/engines/chewy/resource.h @@ -170,14 +170,6 @@ public: SoundChunk *getSound(uint num); }; -class ErrorMessage : public Resource { -public: - ErrorMessage(Common::String filename) : Resource(filename) {} - virtual ~ErrorMessage() {} - - Common::String getErrorMessage(uint num); -}; - class VideoResource : public Resource { public: VideoResource(Common::String filename) : Resource(filename) {} @@ -187,19 +179,6 @@ public: Common::SeekableReadStream *getVideoStream(uint num); }; -class Font { -public: - Font(Common::String filename); - virtual ~Font(); - - ::Graphics::Surface *getLine(Common::String text); - -private: - uint16 _count, _first, _last, _width, _height; - - ::Graphics::Surface _fontSurface; -}; - } // End of namespace Chewy #endif diff --git a/engines/chewy/text.cpp b/engines/chewy/text.cpp new file mode 100644 index 0000000000..da7b2279f4 --- /dev/null +++ b/engines/chewy/text.cpp @@ -0,0 +1,160 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/rect.h" +#include "common/system.h" + +#include "chewy/resource.h" +#include "chewy/text.h" + +namespace Chewy { + +Text::Text() : Resource("atds.tap") { +} + +Text::~Text() { +} + +DialogList *Text::getDialog(uint dialogNum, uint entryNum) { + DialogList *l = new DialogList(); + + if (dialogNum >= kADSTextMax) + error("getDialog(): Invalid entry number requested, %d (max %d)", dialogNum, kADSTextMax); + + byte *data = getChunkData(dialogNum); + byte *ptr = data; + + ptr += 2; // entry number + ptr += 2; // number of persons + ptr += 2; // automove count + ptr += 2; // cursor number + ptr += 13; // misc data + + for (uint i = 0; i <= entryNum; i++) { + do { + Dialog curDialog; + ptr++; // current entry + ptr += 2; + curDialog.speechId = READ_LE_UINT16(ptr) - VOICE_OFFSET; ptr += 2; + + do { + curDialog.text += *ptr++; + + if (*ptr == 0 && *(ptr + 1) != kEndText) { + // TODO: Split lines + *ptr = ' '; + } + } while (*ptr != kEndText); + + if (i == entryNum) + l->push_back(curDialog); + + } while (*(ptr + 1) != kEndEntry); + + ptr += 2; // kEndText, kEndEntry + + if (*ptr == kEndBlock) // not found + break; + } + + delete[] data; + + return l; +} + +Font::Font(Common::String filename) { + const uint32 headerFont = MKTAG('T', 'F', 'F', '\0'); + Common::File stream; + + stream.open(filename); + + uint32 header = stream.readUint32BE(); + + if (header != headerFont) + error("Invalid resource - %s", filename.c_str()); + + stream.skip(4); // total memory + _count = stream.readUint16LE(); + _first = stream.readUint16LE(); + _last = stream.readUint16LE(); + _width = stream.readUint16LE(); + _height = stream.readUint16LE(); + + _fontSurface.create(_width * _count, _height, ::Graphics::PixelFormat::createFormatCLUT8()); + + byte cur; + int bitIndex = 7; + byte *p; + + cur = stream.readByte(); + + for (uint n = 0; n < _count; n++) { + for (uint y = 0; y < _height; y++) { + for (uint x = n * _width; x < n * _width + _width; x++) { + p = (byte *)_fontSurface.getBasePtr(x, y); + *p = (cur & (1 << bitIndex)) ? 0 : 0xFF; + + bitIndex--; + if (bitIndex < 0) { + bitIndex = 7; + cur = stream.readByte(); + } + } + } + } +} + +Font::~Font() { + _fontSurface.free(); +} + +::Graphics::Surface *Font::getLine(Common::String text) { + ::Graphics::Surface *line = new ::Graphics::Surface(); + line->create(text.size() * _width, _height, ::Graphics::PixelFormat::createFormatCLUT8()); + + for (uint i = 0; i < text.size(); i++) { + uint x = (text[i] - _first) * _width; + line->copyRectToSurface(_fontSurface, i * _width, 0, Common::Rect(x, 0, x + _width, _height)); + } + + return line; +} + +Common::String ErrorMessage::getErrorMessage(uint num) { + assert(num < _chunkList.size()); + + Chunk *chunk = &_chunkList[num]; + Common::String str; + byte *data = new byte[chunk->size]; + + _stream.seek(chunk->pos, SEEK_SET); + _stream.read(data, chunk->size); + if (_encrypted) + decrypt(data, chunk->size); + + str = (char *)data; + delete[] data; + + return str; +} + +} // End of namespace Chewy diff --git a/engines/chewy/text.h b/engines/chewy/text.h new file mode 100644 index 0000000000..fe3e1da8b9 --- /dev/null +++ b/engines/chewy/text.h @@ -0,0 +1,105 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef CHEWY_TEXT_H +#define CHEWY_TEXT_H + +#include "common/list.h" +#include "chewy/chewy.h" +#include "chewy/resource.h" + +namespace Chewy { + +/** + * Game texts are contained in txt/atds.tap, and contain the following (in that order): + * ADS (Adventure Dialog System) - dialogs, 500 entries max + * ATS (Adventure Text System) - text descriptions, 100 entries max + * AAD (Adventure Auto Dialog System) - automatic dialogs, 100 entries max + * INV - inventory text descriptions, 100 entries max + * USE - use action texts, 100 entries max + */ +enum MaxTextTypes { + kADSTextMax = 500, + kATSTextMax = 100, + kAADTextMax = 100, + kINVTextMax = 100, + kUSETextMax = 100 +}; + +/** + * Markers for text entries + */ +enum TextEntryMarkers { + kEndRow = 0x00, + kEndBlock = 0x0b, + kEndEntry = 0x0c, + kEndText = 0x0d, + kEndChunk = 0x0e + // There's also 0x0f, block end, which we don't use +}; + +#define VOICE_OFFSET 20 + +struct Dialog { + uint16 speechId; + Common::String text; +}; + +typedef Common::List<Dialog> DialogList; + + +class Text : public Resource { +public: + Text(); + virtual ~Text(); + + DialogList *getDialog(uint dialogNum, uint entryNum); + // TODO: getText() + // TODO: getAutoDialog() + // TODO: getInvDesc() + // TODO: getUseText() +}; + +class ErrorMessage : public Resource { +public: + ErrorMessage(Common::String filename) : Resource(filename) {} + virtual ~ErrorMessage() {} + + Common::String getErrorMessage(uint num); +}; + +class Font { +public: + Font(Common::String filename); + virtual ~Font(); + + ::Graphics::Surface *getLine(Common::String text); + +private: + uint16 _count, _first, _last, _width, _height; + + ::Graphics::Surface _fontSurface; +}; + +} // End of namespace Chewy + +#endif |