diff options
41 files changed, 466 insertions, 149 deletions
diff --git a/common/dcl.cpp b/common/dcl.cpp index 5993c218cb..66dfb76b2a 100644 --- a/common/dcl.cpp +++ b/common/dcl.cpp @@ -449,6 +449,8 @@ bool DecompressorDCL::unpack(SeekableReadStream *sourceStream, WriteStream *targ } if (_targetFixedSize) { + if (_bytesWritten != _targetSize) + warning("DCL-INFLATE Error: Inconsistent bytes written (%d) and target buffer size (%d)", _bytesWritten, _targetSize); return _bytesWritten == _targetSize; } return true; // For targets featuring dynamic size we always succeed diff --git a/common/dcl.h b/common/dcl.h index f90bc23c8d..ade7ebd985 100644 --- a/common/dcl.h +++ b/common/dcl.h @@ -25,6 +25,7 @@ * PKWARE DCL ("explode") ("PKWARE data compression library") decompressor used in engines: * - agos (exclusively for Simon 2 setup.shr file) * - mohawk + * - neverhood * - sci */ diff --git a/devtools/dist-scummvm.sh b/devtools/dist-scummvm.sh index ac411c55a3..56e6b4e05e 100755 --- a/devtools/dist-scummvm.sh +++ b/devtools/dist-scummvm.sh @@ -4,6 +4,7 @@ # # Largely based on dist-fink.sh, Copyright (c) 2001 Christoph Pfisterer. # Modified to use Subversion instead of CVS by Max Horn in 2007. +# Modified to use git by Eugene Sandulenko in 2015. # # ScummVM is the legal property of its developers, whose names # are too numerous to list here. Please refer to the COPYRIGHT @@ -26,25 +27,44 @@ ### configuration -svnroot='https://scummvm.svn.sourceforge.net/svnroot/scummvm' +scummvmrepo='https://github.com/scummvm/scummvm.git' +toolsrepo='https://github.com/scummvm/scummvm-tools.git' ### init if [ $# -lt 2 ]; then - echo "Usage: $0 <module> <version-number> [<temporary-directory> [<tag>]]" + echo "Usage: $0 <scummvm | scummvm-tools> <version-number> [<temporary-directory> [<tag>]]" exit 1 fi +echo_n() { + printf "$@" +} + module=$1 version=$2 tmpdir=${3:-/tmp} tag=$4 if [ -z "$tag" ]; then - tag=release-`echo $version | sed 's/\./-/g'` + tag="v$version" fi fullname="$module-$version" -echo "packaging $module release $version, SVN tag $tag" +# Check modules +case $module in +scummvm) + gitrepo=$scummvmrepo +;; +scummvm-tools) + gitrepo=$toolsrepo +;; +*) + echo "Unknown module $module. Only scummvm or scummvm-tools are supported" + exit 1 +esac + + +echo "packaging $module release $version, GIT tag $tag" ### setup temp directory @@ -54,25 +74,39 @@ umask 022 if [ -d $fullname ]; then echo "There is a left-over directory in $tmpdir." - echo "Remove $fullname, then try again." + echo "Remove $tmpdir/$fullname, then try again." exit 1 fi -### check code out from SVN -# TODO: Add support for making tarballs from trunk / branches? +### check code out from GIT -echo "Exporting module $module, tag $tag from SVN:" -svn export "$svnroot/$module/tags/$tag" $fullname +echo "Cloning module $module from GIT:" +git clone $gitrepo $fullname if [ ! -d $fullname ]; then - echo "SVN export failed, directory $fullname doesn't exist!" + echo "GIT clone failed, directory $fullname doesn't exist!" exit 1 fi +cd $tmpdir/$fullname + +echo_n "Checking out tag $tag..." +if git checkout $tag --quiet 2>/dev/null; then + echo done +else + echo "checking out tag $tag failed." + exit 1 +fi + +cd $tmpdir + +echo "Cleaning up .git directory" +rm -rf $fullname/.git + ### roll the tarball -echo "Creating tarball $fullname.tar:" +echo "Creating tarball $fullname.tar..." rm -f $fullname.tar $fullname.tar.gz -tar -cvf $fullname.tar $fullname +tar -cf $fullname.tar $fullname echo "Compressing (using gzip) tarball $fullname.tar.gz..." gzip -c9 $fullname.tar > $fullname.tar.gz @@ -88,8 +122,15 @@ if [ ! -f $fullname.tar.bz2 ]; then exit 1 fi +echo "Compressing (using xz) tarball $fullname.tar.xz..." +xz -c9 $fullname.tar > $fullname.tar.xz +if [ ! -f $fullname.tar.xz ]; then + echo "Packaging to xz failed, $fullname.tar.xz doesn't exist!" + # But do not exit +fi + echo "Zipping $fullname.zip..." -zip -r9 $fullname.zip $fullname +zip -r9 $fullname.zip $fullname >/dev/null if [ ! -f $fullname.zip ]; then echo "Packaging failed, $fullname.zip doesn't exist!" exit 1 @@ -99,6 +140,7 @@ fi ### finish up echo "Done:" -ls -l $fullname.tar.gz $fullname.tar.bz2 $fullname.zip +ls -l $fullname.tar.gz $fullname.tar.bz2 $fullname.tar.xz $fullname.zip +md5sum $fullname.tar.gz $fullname.tar.bz2 $fullname.tar.xz $fullname.zip exit 0 diff --git a/engines/bbvs/bbvs.cpp b/engines/bbvs/bbvs.cpp index 11e4b6cea7..1d668f9c34 100644 --- a/engines/bbvs/bbvs.cpp +++ b/engines/bbvs/bbvs.cpp @@ -39,6 +39,8 @@ #include "common/error.h" #include "common/fs.h" #include "common/timer.h" +#include "common/translation.h" +#include "engines/advancedDetector.h" #include "engines/util.h" #include "graphics/cursorman.h" #include "graphics/font.h" @@ -116,9 +118,15 @@ BbvsEngine::BbvsEngine(OSystem *syst, const ADGameDescription *gd) : Engine::syncSoundSettings(); + _oldGUILanguage = TransMan.getCurrentLanguage(); + + if (gd->flags & GF_GUILANGSWITCH) + TransMan.setLanguage(getLanguageLocale(gd->language)); } BbvsEngine::~BbvsEngine() { + if (TransMan.getCurrentLanguage() != _oldGUILanguage) + TransMan.setLanguage(_oldGUILanguage); delete _random; diff --git a/engines/bbvs/bbvs.h b/engines/bbvs/bbvs.h index bbd8046a8b..d098aaf90b 100644 --- a/engines/bbvs/bbvs.h +++ b/engines/bbvs/bbvs.h @@ -63,6 +63,10 @@ class SoundMan; #define BBVS_SAVEGAME_VERSION 0 enum { + GF_GUILANGSWITCH = (1 << 0) // If GUI language switch is required for menus +}; + +enum { kVerbLook = 0, kVerbUse = 1, kVerbTalk = 2, @@ -226,9 +230,12 @@ public: void continueGameFromQuickSave(); void setNewSceneNum(int newSceneNum); const Common::String getTargetName() { return _targetName; } -private: const ADGameDescription *_gameDescription; + +private: Graphics::PixelFormat _pixelFormat; + Common::String _oldGUILanguage; + public: Common::RandomSource *_random; diff --git a/engines/bbvs/configure.engine b/engines/bbvs/configure.engine index c1dc1ef924..8be3e078d9 100644 --- a/engines/bbvs/configure.engine +++ b/engines/bbvs/configure.engine @@ -1,3 +1,3 @@ # This file is included from the main "configure" script # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] -add_engine bbvs "Beavis and Butthead in Virtual Stupidity" no +add_engine bbvs "Beavis and Butthead in Virtual Stupidity" yes diff --git a/engines/bbvs/detection.cpp b/engines/bbvs/detection.cpp index 3e247aad99..d2e3ab8e42 100644 --- a/engines/bbvs/detection.cpp +++ b/engines/bbvs/detection.cpp @@ -30,7 +30,7 @@ #include "graphics/thumbnail.h" static const PlainGameDescriptor bbvsGames[] = { - { "bbvs", "Beavis and Butthead in Virtual Stupidity" }, + { "bbvs", "Beavis and Butt-head in Virtual Stupidity" }, { 0, 0 } }; @@ -40,10 +40,19 @@ static const ADGameDescription gameDescriptions[] = { { "bbvs", 0, - AD_ENTRY1s("game0001.vnm", "637e5411751c7065bc385dd73d224561", 64004), + AD_ENTRY1s("vspr0001.vnm", "7ffe9b9e7ca322db1d48e86f5130578e", 1166628), Common::EN_ANY, Common::kPlatformWindows, - ADGF_NO_FLAGS, + ADGF_NO_FLAGS | ADGF_TESTING, + GUIO0() + }, + { + "bbvs", + 0, + AD_ENTRY1s("vspr0001.vnm", "91c76b1048f93208cd7b1a05ebccb408", 1176976), + Common::RU_RUS, + Common::kPlatformWindows, + GF_GUILANGSWITCH | ADGF_TESTING, GUIO0() }, @@ -66,7 +75,7 @@ public: } virtual const char *getName() const { - return "MTV's Beavis and Butt-Head in Virtual Stupidity"; + return "MTV's Beavis and Butt-head in Virtual Stupidity"; } virtual const char *getOriginalCopyright() const { diff --git a/engines/bbvs/dialogs.cpp b/engines/bbvs/dialogs.cpp index af95f06c1e..ef7f3c9320 100644 --- a/engines/bbvs/dialogs.cpp +++ b/engines/bbvs/dialogs.cpp @@ -24,6 +24,7 @@ #include "common/events.h" #include "gui/gui-manager.h" #include "gui/ThemeEval.h" +#include "engines/advancedDetector.h" namespace Bbvs { @@ -53,6 +54,27 @@ static const MenuButton kMenuButtons[] = { {"Back ..", kCmdBack} }; +static const MenuButton kMenuButtonsRu[] = { + // Main menu + {"\xBD\xDE\xD2\xD0\xEF \xD8\xD3\xE0\xD0", kCmdNewGame}, + {"\xBF\xE0\xDE\xD4\xDE\xDB\xD6\xD8\xE2\xEC", kCmdContinue}, + {"\xB5\xE9\xD5 ..", kCmdOptions}, + {"\xBC\xD8\xDD\xD8 \xB8\xD3\xE0\xEB", kCmdMiniGames}, + {"\xB2\xEB\xE5\xDE\xD4", kCmdQuit}, + // Options + {"\xB4\xD5\xD8\xDD\xE1\xE2\xD0\xDB\xDB\xEF\xE6\xD8\xEF", kCmdUninstall}, + {"\xB0\xD2\xE2\xDE\xE0\xEB", kCmdCredits}, + {"\xBF\xE0\xDE\xDB\xDE\xD3", kCmdOpening}, + {"\xC0\xD5\xDA\xDB\xD0\xDC\xD0", kCmdChicksNStuff}, + {"\xBD\xD0\xD7\xD0\xD4 ..", kCmdBack}, + // Minigames + {"\xC1\xDD\xD0\xD9\xDF\xD5\xE0", kCmdHockALoogie}, + {"\xB6\xE3\xDA\xDE\xD6\xD0\xE0\xDA\xD0", kCmdBugJustice}, + {"\xBF\xE2\xD5\xDD\xD8\xE1", kCmdCourtChaos}, + {"\xB6\xD8\xD0\xDE\xD9 \xB7\xD2\xE3\xDA", kCmdAirGuitar}, + {"\xBD\xD0\xD7\xD0\xD4 ..", kCmdBack} +}; + MainMenu::MainMenu(BbvsEngine *vm) : Dialog(0, 0, 1, 1), _vm(vm) { init(); } @@ -160,7 +182,13 @@ void MainMenu::handleCommand(GUI::CommandSender *sender, uint32 command, uint32 void MainMenu::gotoMenuScreen(int screen) { for (int i = 0; i < 5; ++i) { - const MenuButton *btn = &kMenuButtons[screen * 5 + i]; + const MenuButton *btn; + + if (_vm->_gameDescription->language == Common::RU_RUS) { + btn = &kMenuButtonsRu[screen * 5 + i]; + } else { + btn = &kMenuButtons[screen * 5 + i]; + } _buttons[i]->setLabel(btn->label); _buttons[i]->setCmd(btn->cmd); _buttons[i]->setEnabled(btn->cmd != 0); diff --git a/engines/bbvs/minigames/bbtennis.cpp b/engines/bbvs/minigames/bbtennis.cpp index 7763548330..6c7d8cbf31 100644 --- a/engines/bbvs/minigames/bbtennis.cpp +++ b/engines/bbvs/minigames/bbtennis.cpp @@ -516,7 +516,7 @@ void MinigameBbTennis::updateObjs() { } obj->blinkCtr = _vm->getRandom(64) + 60; _tennisPlayerDelay = _vm->getRandom(128) + 400 - _playerDecrease; - if (_vm->getRandom(10) == 1 && !isAnySoundPlaying(kAllSounds, 0x11)) + if (_vm->getRandom(10) == 1 && !isAnySoundPlaying(kAllSounds, 11)) playSound(kYuppieEnteringCourtSounds[_vm->getRandom(2)]); } diff --git a/engines/bbvs/videoplayer.cpp b/engines/bbvs/videoplayer.cpp index 9ea73ad10b..1b721c434f 100644 --- a/engines/bbvs/videoplayer.cpp +++ b/engines/bbvs/videoplayer.cpp @@ -43,6 +43,8 @@ void BbvsEngine::playVideo(int videoNum) { return; } + debug(0, "Screen format: %s", _system->getScreenFormat().toString().c_str()); + Video::VideoDecoder *videoDecoder = new Video::AVIDecoder(); if (!videoDecoder->loadFile(videoFilename)) { delete videoDecoder; @@ -58,7 +60,14 @@ void BbvsEngine::playVideo(int videoNum) { if (videoDecoder->needsUpdate()) { const Graphics::Surface *frame = videoDecoder->decodeNextFrame(); if (frame) { - _system->copyRectToScreen(frame->getPixels(), frame->pitch, 0, 0, frame->w, frame->h); + if (frame->format.bytesPerPixel > 1) { + Graphics::Surface *frame1 = frame->convertTo(_system->getScreenFormat()); + _system->copyRectToScreen(frame1->getPixels(), frame1->pitch, 0, 0, frame1->w, frame1->h); + frame1->free(); + delete frame1; + } else { + _system->copyRectToScreen(frame->getPixels(), frame->pitch, 0, 0, frame->w, frame->h); + } _system->updateScreen(); } } diff --git a/engines/lure/res.cpp b/engines/lure/res.cpp index 6b2705463d..7a79f48b87 100644 --- a/engines/lure/res.cpp +++ b/engines/lure/res.cpp @@ -44,6 +44,10 @@ Resources::Resources() : _rnd(LureEngine::getReference().rnd()) { MemoryBlock *mb = Disk::getReference().getEntry(STRING_LIST_RESOURCE_ID); _stringList.load(mb); delete mb; + + // WORKAROUND: In Spanish the look "Obsevar" should be "Observar" + if (!Common::String(_stringList.getString(LOOK)).compareTo("Obsevar")) + _stringList.setString(LOOK, "Observar"); } Resources::~Resources() { diff --git a/engines/lure/res_struct.cpp b/engines/lure/res_struct.cpp index 5a4761c87b..ec1a546d05 100644 --- a/engines/lure/res_struct.cpp +++ b/engines/lure/res_struct.cpp @@ -1217,26 +1217,19 @@ void BarmanLists::loadFromStream(Common::ReadStream *stream) { // String list resource class void StringList::load(MemoryBlock *data) { - _data = Memory::allocate(data->size()); - _data->copyFrom(data); + // Get the number of entries + uint numEntries = READ_LE_UINT16(data->data()); - _numEntries = READ_LE_UINT16(_data->data()); - char *p = (char *) _data->data() + sizeof(uint16); - - _entries = (char **) Memory::alloc(_numEntries * sizeof(char *)); - - for (int index = 0; index < _numEntries; ++index) { - _entries[index] = p; + // Iterate through loading the strings one at a time + const char *p = (const char *)data->data() + sizeof(uint16); + for (uint index = 0; index < numEntries; ++index) { + _entries.push_back(p); p += strlen(p) + 1; } } void StringList::clear() { - if (_numEntries != 0) { - Memory::dealloc(_entries); - delete _data; - _numEntries = 0; - } + _entries.clear(); } // Field list and miscellaneous variables diff --git a/engines/lure/res_struct.h b/engines/lure/res_struct.h index 9190912f5b..685c55ab13 100644 --- a/engines/lure/res_struct.h +++ b/engines/lure/res_struct.h @@ -28,6 +28,7 @@ #include "common/list.h" #include "common/file.h" #include "common/ptr.h" +#include "common/str-array.h" #include "common/textconsole.h" namespace Lure { @@ -850,22 +851,19 @@ enum StringEnum {S_CREDITS = 25, S_RESTART_GAME = 26, S_SAVE_GAME = 27, S_RESTOR class StringList { private: - MemoryBlock *_data; - int _numEntries; - char **_entries; + Common::StringArray _entries; public: - StringList() { _numEntries = 0; } - ~StringList() { clear(); } + StringList() {} void load(MemoryBlock *data); void clear(); - int count() { return _numEntries; } + int count() { return _entries.size(); } const char *getString(int index) { - if ((index < 0) || (index >= _numEntries)) error("Invalid index specified to String List"); - return _entries[index]; + return _entries[index].c_str(); } const char *getString(Action action) { return getString((int) action - 1); } const char *getString(StringEnum sEnum) { return getString((int) sEnum); } + void setString(Action action, const Common::String &s) { _entries[(int)action - 1] = s; } }; // The following class holds the field list used by the script engine as diff --git a/engines/mads/configure.engine b/engines/mads/configure.engine index 60d833e9e8..412d65e180 100644 --- a/engines/mads/configure.engine +++ b/engines/mads/configure.engine @@ -1,3 +1,3 @@ # This file is included from the main "configure" script # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] -add_engine mads "Rex Nebular and the Cosmic Gender Bender" no +add_engine mads "Rex Nebular and the Cosmic Gender Bender" yes diff --git a/engines/mads/detection_tables.h b/engines/mads/detection_tables.h index 56df09577c..f0eb21f5d9 100644 --- a/engines/mads/detection_tables.h +++ b/engines/mads/detection_tables.h @@ -55,7 +55,7 @@ static const MADSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformDOS, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EASY_MOUSE, GAMEOPTION_ANIMATED_INVENTORY, GAMEOPTION_ANIMATED_INTERFACE, GAMEOPTION_NAUGHTY_MODE) }, GType_RexNebular, @@ -73,7 +73,7 @@ static const MADSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformDOS, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EASY_MOUSE, GAMEOPTION_ANIMATED_INVENTORY, GAMEOPTION_ANIMATED_INTERFACE, GAMEOPTION_NAUGHTY_MODE) }, GType_RexNebular, diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp index 6fe17f3beb..0520294b29 100644 --- a/engines/mads/nebular/menu_nebular.cpp +++ b/engines/mads/nebular/menu_nebular.cpp @@ -48,6 +48,7 @@ MainMenu::MainMenu(MADSEngine *vm): MenuView(vm) { _highlightedIndex = -1; _selectedIndex = -1; _buttonDown = false; + _showEvolve = _showSets = false; for (int i = 0; i < 7; ++i) _menuItems[i] = nullptr; @@ -137,12 +138,14 @@ void MainMenu::doFrame() { } _vm->_events->showCursor(); + showBonusItems(); } else { if ((_menuItemIndex == -1) || (_frameIndex == 0)) { if (++_menuItemIndex == 6) { // Reached end of display animation _vm->_events->showCursor(); + showBonusItems(); return; } else if (_menuItemIndex == 4 && !shouldShowQuotes()) { ++_menuItemIndex; @@ -180,6 +183,17 @@ void MainMenu::addSpriteSlot() { _redrawFlag = true; } +void MainMenu::showBonusItems() { + Scene &scene = _vm->_game->_scene; + _showEvolve = Common::File::exists("SECTION0.HAG") && Common::File::exists("evolve.res"); + _showSets = Common::File::exists("SECTION0.HAG") && Common::File::exists("sets.res"); + + if (_showSets) + scene._kernelMessages.add(Common::Point(290, 143), 0x4140, 0, 0, 0, "S"); + if (_showEvolve) + scene._kernelMessages.add(Common::Point(305, 143), 0x4140, 0, 0, 0, "E"); +} + bool MainMenu::onEvent(Common::Event &event) { Scene &scene = _vm->_game->_scene; if (_selectedIndex != -1) @@ -280,6 +294,10 @@ bool MainMenu::onEvent(Common::Event &event) { _selectedIndex = _highlightedIndex; unhighlightItem(); _frameIndex = 0; + } else if (_showSets && Common::Rect(290, 165, 300, 185).contains(event.mouse)) { + handleAction(SETS); + } else if (_showEvolve && Common::Rect(305, 165, 315, 185).contains(event.mouse)) { + handleAction(EVOLVE); } return true; @@ -334,6 +352,14 @@ void MainMenu::handleAction(MADSGameAction action) { TextView::execute(_vm, "quotes"); return; + case SETS: + AnimationView::execute(_vm, "sets"); + break; + + case EVOLVE: + AnimationView::execute(_vm, "evolve"); + break; + case EXIT: _vm->_dialogs->_pendingDialog = DIALOG_ADVERT; break; diff --git a/engines/mads/nebular/menu_nebular.h b/engines/mads/nebular/menu_nebular.h index 35af0bb34f..8a0cc3575d 100644 --- a/engines/mads/nebular/menu_nebular.h +++ b/engines/mads/nebular/menu_nebular.h @@ -35,7 +35,10 @@ class MADSEngine; namespace Nebular { -enum MADSGameAction { START_GAME, RESUME_GAME, SHOW_INTRO, CREDITS, QUOTES, EXIT }; +enum MADSGameAction { + START_GAME, RESUME_GAME, SHOW_INTRO, CREDITS, QUOTES, EXIT, + SETS, EVOLVE +}; class MainMenu: public MenuView { private: @@ -45,6 +48,7 @@ private: int _frameIndex; uint32 _delayTimeout; bool _skipFlag; + bool _showEvolve, _showSets; /** * Currently highlighted menu item @@ -81,7 +85,16 @@ private: */ void addSpriteSlot(); + /** + * Returns true if the Quotes item should be shown. + * i.e. if the player has completed the game + */ bool shouldShowQuotes(); + + /** + * Show the bonus item icons, if available + */ + void showBonusItems(); protected: /** * Display the menu diff --git a/engines/mads/nebular/sound_nebular.cpp b/engines/mads/nebular/sound_nebular.cpp index ab6bd8215c..4c360b23d5 100644 --- a/engines/mads/nebular/sound_nebular.cpp +++ b/engines/mads/nebular/sound_nebular.cpp @@ -2027,8 +2027,8 @@ const ASound4::CommandPtr ASound4::_commandList[61] = { &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::command43, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, - &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, - &ASound4::nullCommand, &ASound4::command57, &ASound4::nullCommand, &ASound4::command59, + &ASound4::command52, &ASound4::command53, &ASound4::command54, &ASound4::command55, + &ASound4::command56, &ASound4::command57, &ASound4::command58, &ASound4::command59, &ASound4::command60 }; diff --git a/engines/mads/resources.cpp b/engines/mads/resources.cpp index d5352fb205..3b7cf2cab0 100644 --- a/engines/mads/resources.cpp +++ b/engines/mads/resources.cpp @@ -151,7 +151,7 @@ void HagArchive::loadIndex(MADSEngine *vm) { Common::File hagFile; for (int sectionIndex = -1; sectionIndex < 11; ++sectionIndex) { - if (sectionIndex == 0) + if (sectionIndex == 0 && !Common::File::exists("SECTION0.HAG")) continue; // Dragonsphere does not have some sections - skip them @@ -239,7 +239,7 @@ Common::String HagArchive::getResourceFilename(const Common::String &resourceNam int value = atoi(resourceName.c_str() + 2); int hagFileNum = (resType == RESTYPE_ROOM) ? value / 100 : value; - if (hagFileNum > 0) + if (hagFileNum >= 0) outputFilename = Common::String::format("SECTION%d.HAG", hagFileNum); } diff --git a/engines/sherlock/configure.engine b/engines/sherlock/configure.engine index a56129a8f0..fd1c354e78 100644 --- a/engines/sherlock/configure.engine +++ b/engines/sherlock/configure.engine @@ -1,3 +1,3 @@ # This file is included from the main "configure" script # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] -add_engine sherlock "The Lost Files of Sherlock Holmes" no +add_engine sherlock "The Lost Files of Sherlock Holmes" yes diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index 6567369528..ce6eafcaca 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -32,7 +32,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_ENTRY1s("talk.lib", "ad0c4d6865edf15da4e9204c08815875", 238928), Common::EN_ANY, Common::kPlatformDOS, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO6(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_FADE_STYLE, GAMEOPTION_HELP_STYLE, GAMEOPTION_PORTRAITS_ON, GAMEOPTION_WINDOW_STYLE) }, @@ -50,7 +50,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_LISTEND}, Common::DE_DEU, Common::kPlatformDOS, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO6(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_FADE_STYLE, GAMEOPTION_HELP_STYLE, GAMEOPTION_PORTRAITS_ON, GAMEOPTION_WINDOW_STYLE) }, @@ -68,7 +68,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_LISTEND}, Common::DE_DEU, Common::kPlatformDOS, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO6(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_FADE_STYLE, GAMEOPTION_HELP_STYLE, GAMEOPTION_PORTRAITS_ON, GAMEOPTION_WINDOW_STYLE) }, @@ -86,7 +86,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_LISTEND }, Common::DE_DEU, Common::kPlatformDOS, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO6(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_FADE_STYLE, GAMEOPTION_HELP_STYLE, GAMEOPTION_PORTRAITS_ON, GAMEOPTION_WINDOW_STYLE) }, @@ -104,7 +104,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_LISTEND}, Common::ES_ESP, Common::kPlatformDOS, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO6(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_FADE_STYLE, GAMEOPTION_HELP_STYLE, GAMEOPTION_PORTRAITS_ON, GAMEOPTION_WINDOW_STYLE) }, @@ -134,7 +134,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_ENTRY1s("talk.lib", "dbdc8a20c96900aa7e4d02f3fe8a274c", 121102), Common::EN_ANY, Common::kPlatformDOS, - ADGF_TESTING | ADGF_DEMO, + ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, GType_SerratedScalpel, @@ -149,7 +149,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_ENTRY1s("music.lib", "ec19a09b7fef6fd90b1ab812ce6e9739", 38563), Common::EN_ANY, Common::kPlatformDOS, - ADGF_TESTING | ADGF_DEMO, + ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, GType_SerratedScalpel, @@ -164,7 +164,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_ENTRY1s("talk.lib", "22e8e6406dd2fbbb238c9898928df42e", 770756), Common::FR_FRA, Common::kPlatformDOS, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO3(GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_HELP_STYLE, GAMEOPTION_TRANSPARENT_WINDOWS) }, GType_RoseTattoo @@ -179,7 +179,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_ENTRY1s("talk.lib", "9639a756b0993ebd71cb5f4d8b78b2dc", 765134), Common::EN_ANY, Common::kPlatformDOS, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO3(GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_HELP_STYLE, GAMEOPTION_TRANSPARENT_WINDOWS) }, GType_RoseTattoo, @@ -194,7 +194,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_ENTRY1s("talk.lib", "5027aa72f0d263ed3b1c764a6c397911", 873864), Common::DE_DEU, Common::kPlatformDOS, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO3(GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_HELP_STYLE, GAMEOPTION_TRANSPARENT_WINDOWS) }, GType_RoseTattoo, @@ -209,7 +209,7 @@ static const SherlockGameDescription gameDescriptions[] = { AD_ENTRY1s("talk.lib", "4f3ccf50e1012445624569cd605d7449", 783713), Common::ES_ESP, Common::kPlatformDOS, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO3(GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_HELP_STYLE, GAMEOPTION_TRANSPARENT_WINDOWS) }, GType_RoseTattoo, diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 0856c226f1..e70b707404 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -620,6 +620,7 @@ void Sprite::clear() { _images = nullptr; _imageFrame = nullptr; _walkCount = 0; + _oldWalkSequence = 0; _allow = 0; _frameNumber = 0; _position.x = _position.y = 0; @@ -634,6 +635,7 @@ void Sprite::clear() { _misc = 0; _altImages = nullptr; _altSeq = 0; + _centerWalk = 0; Common::fill(&_stopFrames[0], &_stopFrames[8], (ImageFrame *)nullptr); } diff --git a/engines/sherlock/scalpel/scalpel_saveload.cpp b/engines/sherlock/scalpel/scalpel_saveload.cpp index 01ba149813..61830a56b2 100644 --- a/engines/sherlock/scalpel/scalpel_saveload.cpp +++ b/engines/sherlock/scalpel/scalpel_saveload.cpp @@ -39,7 +39,8 @@ const int ENV_POINTS[6][3] = { /*----------------------------------------------------------------*/ -ScalpelSaveManager::ScalpelSaveManager(SherlockEngine *vm, const Common::String &target) : SaveManager(vm, target) { +ScalpelSaveManager::ScalpelSaveManager(SherlockEngine *vm, const Common::String &target) : + SaveManager(vm, target), _envMode(SAVEMODE_NONE) { } void ScalpelSaveManager::drawInterface() { diff --git a/engines/sherlock/scalpel/tsage/logo.cpp b/engines/sherlock/scalpel/tsage/logo.cpp index 014470dcc8..273d26df74 100644 --- a/engines/sherlock/scalpel/tsage/logo.cpp +++ b/engines/sherlock/scalpel/tsage/logo.cpp @@ -163,6 +163,7 @@ Object::Object() { _angle = _changeCtr = 0; _walkStartFrame = 0; _majorDiff = _minorDiff = 0; + _updateStartFrame = 0; } void Object::setVisage(int visage, int strip) { diff --git a/engines/sherlock/tattoo/tattoo_darts.cpp b/engines/sherlock/tattoo/tattoo_darts.cpp index 274d80e3e1..512358933d 100644 --- a/engines/sherlock/tattoo/tattoo_darts.cpp +++ b/engines/sherlock/tattoo/tattoo_darts.cpp @@ -70,6 +70,7 @@ Darts::Darts(SherlockEngine *vm) : _vm(vm) { _handX = 0; _compPlay = 1; _escapePressed = false; + _spacing = 0; } void Darts::playDarts(GameType gameType) { diff --git a/engines/sherlock/tattoo/widget_base.cpp b/engines/sherlock/tattoo/widget_base.cpp index 9e10cee0d1..8f0649130a 100644 --- a/engines/sherlock/tattoo/widget_base.cpp +++ b/engines/sherlock/tattoo/widget_base.cpp @@ -33,6 +33,7 @@ namespace Tattoo { WidgetBase::WidgetBase(SherlockEngine *vm) : _vm(vm) { _scroll = false; _dialogTimer = 0; + _outsideMenu = false; } void WidgetBase::summonWindow() { diff --git a/engines/sherlock/tattoo/widget_files.cpp b/engines/sherlock/tattoo/widget_files.cpp index 0f5e6793c4..ca5e1bff93 100644 --- a/engines/sherlock/tattoo/widget_files.cpp +++ b/engines/sherlock/tattoo/widget_files.cpp @@ -143,19 +143,17 @@ void WidgetFiles::render(FilesRenderMode mode) { int yp = _surface.fontHeight() + 14; for (int idx = _savegameIndex; idx < (_savegameIndex + FILES_LINES_COUNT); ++idx) { - if (OP_NAMES || idx == _selector || idx == _oldSelector) { - if (idx == _selector && mode != RENDER_ALL) - color = COMMAND_HIGHLIGHTED; - else - color = INFO_TOP; + if (idx == _selector && mode != RENDER_ALL) + color = COMMAND_HIGHLIGHTED; + else + color = INFO_TOP; - if (mode == RENDER_NAMES_AND_SCROLLBAR) - _surface.fillRect(Common::Rect(4, yp, _surface.w() - BUTTON_SIZE - 9, yp + _surface.fontHeight()), TRANSPARENCY); + if (mode == RENDER_NAMES_AND_SCROLLBAR) + _surface.fillRect(Common::Rect(4, yp, _surface.w() - BUTTON_SIZE - 9, yp + _surface.fontHeight()), TRANSPARENCY); - Common::String numStr = Common::String::format("%d.", idx + 1); - _surface.writeString(numStr, Common::Point(_surface.widestChar(), yp), color); - _surface.writeString(_savegames[idx], Common::Point(xp, yp), color); - } + Common::String numStr = Common::String::format("%d.", idx + 1); + _surface.writeString(numStr, Common::Point(_surface.widestChar(), yp), color); + _surface.writeString(_savegames[idx], Common::Point(xp, yp), color); yp += _surface.fontHeight() + 1; } diff --git a/engines/sword25/detection_tables.h b/engines/sword25/detection_tables.h index a9f263b7d4..644b8ef366 100644 --- a/engines/sword25/detection_tables.h +++ b/engines/sword25/detection_tables.h @@ -129,6 +129,19 @@ static const ADGameDescription gameDescriptions[] = { GF_EXTRACTED | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, + + // Distributed by ScummVM + // Contains all language packs, English voice-overs and Hungarian version + { + "sword25", + "Latest version", + AD_ENTRY1s("data.b25c", "880a8a67faf4a4e7ab62cf114b771428", 827397764), + Common::EN_ANY, + Common::kPlatformUnknown, + ADGF_UNSTABLE, + GUIO1(GUIO_NOASPECT) + }, + AD_TABLE_END_MARKER }; diff --git a/engines/sword25/gfx/graphicengine.cpp b/engines/sword25/gfx/graphicengine.cpp index f887c3cd51..fd3b63aeee 100644 --- a/engines/sword25/gfx/graphicengine.cpp +++ b/engines/sword25/gfx/graphicengine.cpp @@ -60,13 +60,13 @@ enum { namespace Sword25 { -static const uint FRAMETIME_SAMPLE_COUNT = 5; // Anzahl der Framezeiten über die, die Framezeit gemittelt wird +static const uint FRAMETIME_SAMPLE_COUNT = 5; // Frame duration is averaged over FRAMETIME_SAMPLE_COUNT frames GraphicEngine::GraphicEngine(Kernel *pKernel) : _width(0), _height(0), _bitDepth(0), - _lastTimeStamp((uint) -1), // max. BS_INT64 um beim ersten Aufruf von _UpdateLastFrameDuration() einen Reset zu erzwingen + _lastTimeStamp((uint) -1), // force reset of _UpdateLastFrameDuration() on first call _lastFrameDuration(0), _timerActive(true), _frameTimeSampleSlot(0), @@ -87,19 +87,18 @@ GraphicEngine::~GraphicEngine() { } bool GraphicEngine::init(int width, int height, int bitDepth, int backbufferCount) { - // Warnung ausgeben, wenn eine nicht unterstützte Bittiefe gewählt wurde. + // Warn when an unsupported bit depth has been selected. if (bitDepth != BIT_DEPTH) { warning("Can't use a bit depth of %d (not supported). Falling back to %d.", bitDepth, BIT_DEPTH); _bitDepth = BIT_DEPTH; } - // Warnung ausgeben, wenn nicht genau ein Backbuffer gewählt wurde. + // Warn when wrong BackBuffer is specified. if (backbufferCount != BACKBUFFER_COUNT) { warning("Can't use %d backbuffers (not supported). Falling back to %d.", backbufferCount, BACKBUFFER_COUNT); backbufferCount = BACKBUFFER_COUNT; } - // Parameter in lokale Variablen kopieren _width = width; _height = height; _bitDepth = bitDepth; @@ -112,13 +111,13 @@ bool GraphicEngine::init(int width, int height, int bitDepth, int backbufferCoun _backSurface.create(width, height, format); - // Standardmäßig ist Vsync an. + // By default Vsync is on. setVsync(true); - // Layer-Manager initialisieren. + // Layer-Manager initialization _renderObjectManagerPtr.reset(new RenderObjectManager(width, height, backbufferCount + 1)); - // Hauptpanel erstellen + // Create the main panel _mainPanelPtr = _renderObjectManagerPtr->getTreeRoot()->addPanel(width, height, BS_ARGB(0, 0, 0, 0)); if (!_mainPanelPtr.isValid()) return false; @@ -128,11 +127,10 @@ bool GraphicEngine::init(int width, int height, int bitDepth, int backbufferCoun } bool GraphicEngine::startFrame(bool updateAll) { - // Berechnen, wie viel Zeit seit dem letzten Frame vergangen ist. - // Dieser Wert kann über GetLastFrameDuration() von Modulen abgefragt werden, die zeitabhängig arbeiten. + // Calculate how much time has elapsed since the last frame. updateLastFrameDuration(); - // Den Layer-Manager auf den nächsten Frame vorbereiten + // Prepare the Layer Manager for the next frame _renderObjectManagerPtr->startFrame(); return true; @@ -276,7 +274,7 @@ Resource *GraphicEngine::loadResource(const Common::String &filename) { PackageManager *pPackage = Kernel::getInstance()->getPackage(); assert(pPackage); - // Datei laden + // Loading data byte *pFileData; uint fileSize; pFileData = pPackage->getFile(filename, &fileSize); @@ -375,10 +373,10 @@ bool GraphicEngine::saveThumbnailScreenshot(const Common::String &filename) { void GraphicEngine::ARGBColorToLuaColor(lua_State *L, uint color) { lua_Number components[4] = { - (lua_Number)((color >> 16) & 0xff), // Rot - (lua_Number)((color >> 8) & 0xff), // Grün - (lua_Number)(color & 0xff), // Blau - (lua_Number)(color >> 24), // Alpha + (lua_Number)((color >> 16) & 0xff), // Red + (lua_Number)((color >> 8) & 0xff), // Green + (lua_Number)(color & 0xff), // Blue + (lua_Number)(color >> 24), // Alpha }; lua_newtable(L); @@ -395,11 +393,11 @@ uint GraphicEngine::luaColorToARGBColor(lua_State *L, int stackIndex) { int __startStackDepth = lua_gettop(L); #endif - // Sicherstellen, dass wir wirklich eine Tabelle betrachten + // Make sure that we really look at a table luaL_checktype(L, stackIndex, LUA_TTABLE); - // Größe der Tabelle auslesen + // getting table size uint n = luaL_getn(L, stackIndex); - // RGB oder RGBA Farben werden unterstützt und sonst keine + // only RGB or RGBA colors are supported if (n != 3 && n != 4) luaL_argcheck(L, 0, stackIndex, "at least 3 of the 4 color components have to be specified"); diff --git a/engines/sword25/gfx/image/vectorimage.cpp b/engines/sword25/gfx/image/vectorimage.cpp index 0e5dfb9c53..756d063d43 100644 --- a/engines/sword25/gfx/image/vectorimage.cpp +++ b/engines/sword25/gfx/image/vectorimage.cpp @@ -283,7 +283,18 @@ VectorImage::VectorImage(const byte *pFileData, uint fileSize, bool &success, co case 32: success = parseDefineShape(3, bs); return; + case 9: + // SetBackgroundColor + { + byte r, g, b; + r = bs.getByte(); + g = bs.getByte(); + b = bs.getByte(); + _bgColor = Graphics::ARGBToColor<Graphics::ColorMasks<8888> >(0xff, r, g, b); + } + break; default: + warning("Ignoring tag: %d, %d bytes", tagType, tagLength); // Ignore unknown tags bs.skipBytes(tagLength); } diff --git a/engines/sword25/gfx/image/vectorimage.h b/engines/sword25/gfx/image/vectorimage.h index 057064fc6a..b5c2100681 100644 --- a/engines/sword25/gfx/image/vectorimage.h +++ b/engines/sword25/gfx/image/vectorimage.h @@ -228,6 +228,7 @@ private: byte *_pixelData; Common::String _fname; + uint _bgColor; }; } // End of namespace Sword25 diff --git a/engines/sword25/gfx/screenshot.cpp b/engines/sword25/gfx/screenshot.cpp index 4b4f967f29..eeaece97f2 100644 --- a/engines/sword25/gfx/screenshot.cpp +++ b/engines/sword25/gfx/screenshot.cpp @@ -40,7 +40,7 @@ namespace Sword25 { bool Screenshot::saveToFile(Graphics::Surface *data, Common::WriteStream *stream) { // Convert the RGBA data to RGB - const byte *pSrc = (const byte *)data->getPixels(); + const uint32 *pSrc = (const uint32 *)data->getPixels(); // Write our own custom header stream->writeUint32BE(MKTAG('S','C','R','N')); // SCRN, short for "Screenshot" @@ -52,11 +52,12 @@ bool Screenshot::saveToFile(Graphics::Surface *data, Common::WriteStream *stream for (uint x = 0; x < data->w; x++) { // This is only called by createThumbnail below, which // provides a fake 'surface' with LE data in it. - uint32 srcPixel = READ_LE_UINT32(pSrc); - pSrc += sizeof(uint32); - stream->writeByte((srcPixel >> 16) & 0xff); // R - stream->writeByte((srcPixel >> 8) & 0xff); // G - stream->writeByte(srcPixel & 0xff); // B + byte a, r, g, b; + + data->format.colorToARGB(*pSrc++, a, r, g, b); + stream->writeByte(r); + stream->writeByte(g); + stream->writeByte(b); } } @@ -81,30 +82,27 @@ Common::SeekableReadStream *Screenshot::createThumbnail(Graphics::Surface *data) Graphics::Surface thumbnail; thumbnail.create(200, 125, g_system->getScreenFormat()); - // Über das Zielbild iterieren und einen Pixel zur Zeit berechnen. + // Uber das Zielbild iterieren und einen Pixel zur Zeit berechnen. uint x, y; x = y = 0; - for (byte *pDest = (byte *)thumbnail.getPixels(); pDest < ((byte *)thumbnail.getBasePtr(0, thumbnail.h)); ) { + for (uint32 *pDest = (uint32 *)thumbnail.getPixels(); pDest < thumbnail.getBasePtr(0, thumbnail.h); ) { // Get an average over a 4x4 pixel block in the source image int alpha, red, green, blue; alpha = red = green = blue = 0; for (int j = 0; j < 4; ++j) { const uint32 *srcP = (const uint32 *)data->getBasePtr(x * 4, y * 4 + j + 50); for (int i = 0; i < 4; ++i) { - uint32 pixel = READ_UINT32(srcP + i); - alpha += (pixel >> 24); - red += (pixel >> 16) & 0xff; - green += (pixel >> 8) & 0xff; - blue += pixel & 0xff; + byte a, r, g, b; + data->format.colorToARGB(*(srcP + i), a, r, g, b); + alpha += a; + red += r; + green += g; + blue += b; } } - // Write target pixel - *pDest++ = blue / 16; - *pDest++ = green / 16; - *pDest++ = red / 16; - *pDest++ = alpha / 16; + *pDest++ = thumbnail.format.ARGBToColor(alpha / 16, red / 16, green / 16, blue / 16); // Move to next block ++x; diff --git a/engines/sword25/gfx/staticbitmap.cpp b/engines/sword25/gfx/staticbitmap.cpp index 1a6c812508..7ab76e625e 100644 --- a/engines/sword25/gfx/staticbitmap.cpp +++ b/engines/sword25/gfx/staticbitmap.cpp @@ -124,6 +124,10 @@ uint StaticBitmap::getPixel(int x, int y) const { assert(pResource->getType() == Resource::TYPE_BITMAP); BitmapResource *pBitmapResource = static_cast<BitmapResource *>(pResource); uint result = pBitmapResource->getPixel(x, y); + // Convert to LUA-ready format + byte a; + a = result & 0xff; + result = (result >> 8) | (a << 24); pResource->release(); return result; } diff --git a/engines/sword25/gfx/text.cpp b/engines/sword25/gfx/text.cpp index 904435fcb0..d409c538c0 100644 --- a/engines/sword25/gfx/text.cpp +++ b/engines/sword25/gfx/text.cpp @@ -29,10 +29,6 @@ * */ -// TODO: -// Entweder Fontfile absolut abspeichern, oder Verzeichniswechseln verbieten -// Eine relative Fontfile-Angabe könnte verwandt werden nachdem das Verzeichnis bereits gewechselt wurde und die Datei würde nicht mehr gefunden - #include "sword25/kernel/kernel.h" #include "sword25/kernel/outputpersistenceblock.h" #include "sword25/kernel/inputpersistenceblock.h" @@ -99,7 +95,7 @@ void Text::setText(const Common::String &text) { } void Text::setColor(uint32 modulationColor) { - uint32 newModulationColor = (modulationColor & 0xffffff00) | (_modulationColor & 0x000000ff); + uint32 newModulationColor = (modulationColor & 0x00ffffff) | (_modulationColor & 0xff000000); if (newModulationColor != _modulationColor) { _modulationColor = newModulationColor; forceRefresh(); @@ -108,7 +104,7 @@ void Text::setColor(uint32 modulationColor) { void Text::setAlpha(int alpha) { assert(alpha >= 0 && alpha < 256); - uint32 newModulationColor = (_modulationColor & 0xffffff00) | alpha; + uint32 newModulationColor = (_modulationColor & 0xffffff) | (alpha << 24); if (newModulationColor != _modulationColor) { _modulationColor = newModulationColor; forceRefresh(); @@ -132,12 +128,12 @@ void Text::setAutoWrapThreshold(uint32 autoWrapThreshold) { } bool Text::doRender(RectangleList *updateRects) { - // Font-Resource locken. + // lock Font Resource FontResource *fontPtr = lockFontResource(); if (!fontPtr) return false; - // Charactermap-Resource locken. + // lock Character map resource ResourceManager *rmPtr = getResourceManager(); BitmapResource *charMapPtr; { @@ -154,18 +150,18 @@ bool Text::doRender(RectangleList *updateRects) { charMapPtr = static_cast<BitmapResource *>(pResource); } - // Framebufferobjekt holen. + // Getting frame buffer object GraphicEngine *gfxPtr = Kernel::getInstance()->getGfx(); assert(gfxPtr); bool result = true; Common::Array<Line>::iterator iter = _lines.begin(); for (; iter != _lines.end(); ++iter) { - // Feststellen, ob überhaupt Buchstaben der aktuellen Zeile vom Update betroffen sind. + // Determine whether any letters of the current line are affected by the update. Common::Rect checkRect = (*iter).bbox; checkRect.translate(_absoluteX, _absoluteY); - // Jeden Buchstaben einzeln Rendern. + // Render each letter individually. int curX = _absoluteX + (*iter).bbox.left; int curY = _absoluteY + (*iter).bbox.top; for (uint i = 0; i < (*iter).text.size(); ++i) { @@ -181,24 +177,24 @@ bool Text::doRender(RectangleList *updateRects) { } } - // Charactermap-Resource freigeben. + // Free Character map resource charMapPtr->release(); - // Font-Resource freigeben. + // Free Font resource fontPtr->release(); return result; } ResourceManager *Text::getResourceManager() { - // Pointer auf den Resource-Manager holen. + // Getting pointer to resource manager return Kernel::getInstance()->getResourceManager(); } FontResource *Text::lockFontResource() { ResourceManager *rmPtr = getResourceManager(); - // Font-Resource locken. + // Lock font resource FontResource *fontPtr; { Resource *resourcePtr = rmPtr->requestResource(_font); @@ -278,7 +274,7 @@ void Text::updateFormat() { i = lastSpace; } - // Bounding-Box der einzelnen Zeilen relativ zur ersten festlegen (vor allem zentrieren). + // Bounding box of each line relative to the first set (center aligned). _height = 0; Common::Array<Line>::iterator iter = _lines.begin(); for (; iter != _lines.end(); ++iter) { @@ -290,7 +286,7 @@ void Text::updateFormat() { _height += bbox.height(); } } else { - // Keine automatische Formatierung, also wird der gesamte Text in nur eine Zeile kopiert. + // No auto format, so all the text is copied to a single line. _lines[0].text = _text; _lines[0].bbox = Common::Rect(0, 0, _width, _height); } @@ -333,11 +329,11 @@ bool Text::unpersist(InputPersistenceBlock &reader) { result &= RenderObject::unpersist(reader); - // Farbe und Alpha einlesen. + // Read color and alpha reader.read(_modulationColor); - // Beim Laden der anderen Member werden die Set-Methoden benutzt statt der tatsächlichen Member. - // So wird das Layout automatisch aktualisiert und auch alle anderen notwendigen Methoden ausgeführt. + // Run all methods on loading relevant members. + // So, the layout is automatically updated and all necessary logic is executed. Common::String font; reader.readString(font); diff --git a/engines/sword25/util/lua/scummvm_file.cpp b/engines/sword25/util/lua/scummvm_file.cpp index c38aba004f..bdceff0c0c 100644 --- a/engines/sword25/util/lua/scummvm_file.cpp +++ b/engines/sword25/util/lua/scummvm_file.cpp @@ -183,7 +183,7 @@ Common::String Sword25FileProxy::getLanguage() { case Common::FR_FRA: return "fr"; case Common::HU_HUN: - return "hr"; + return "hu"; case Common::IT_ITA: return "it"; case Common::PL_POL: @@ -210,7 +210,7 @@ void Sword25FileProxy::setLanguage(const Common::String &lang) { ConfMan.set("language", Common::getLanguageCode(Common::ES_ESP)); else if (lang == "fr") ConfMan.set("language", Common::getLanguageCode(Common::FR_FRA)); - else if (lang == "hr") + else if (lang == "hu") ConfMan.set("language", Common::getLanguageCode(Common::HU_HUN)); else if (lang == "it") ConfMan.set("language", Common::getLanguageCode(Common::IT_ITA)); diff --git a/graphics/module.mk b/graphics/module.mk index 2705322c79..b6919cf1ab 100644 --- a/graphics/module.mk +++ b/graphics/module.mk @@ -12,6 +12,7 @@ MODULE_OBJS := \ fonts/ttf.o \ fonts/winfont.o \ maccursor.o \ + pixelformat.o \ primitives.o \ scaler.o \ scaler/thumbnail_intern.o \ diff --git a/graphics/pixelformat.cpp b/graphics/pixelformat.cpp new file mode 100644 index 0000000000..0a46411254 --- /dev/null +++ b/graphics/pixelformat.cpp @@ -0,0 +1,64 @@ +/* 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 "graphics/pixelformat.h" +#include "common/algorithm.h" + +namespace Graphics { + +Common::String PixelFormat::toString() const { + if (bytesPerPixel == 1) + return "CLUT8"; + + // We apply a trick to simplify the code here. We encode all the shift, + // loss, and component name in the component entry. By having the shift as + // highest entry we can sort according to shift. + // This works because in valid RGB PixelFormats shift values needs to be + // distinct except when the loss is 8. However, components with loss value + // of 8 are not printed, thus their position does not matter. + int component[4]; + component[0] = (rShift << 16) | (rLoss << 8) | 'R'; + component[1] = (gShift << 16) | (gLoss << 8) | 'G'; + component[2] = (bShift << 16) | (bLoss << 8) | 'B'; + component[3] = (aShift << 16) | (aLoss << 8) | 'A'; + + // Sort components according to descending shift value. + Common::sort(component, component + ARRAYSIZE(component), Common::Greater<int>()); + + Common::String letters, digits; + for (int i = 0; i < ARRAYSIZE(component); ++i) { + const int componentLoss = (component[i] >> 8) & 0xFF; + // A loss of 8 means that the component does not exist. + if (componentLoss == 8) { + continue; + } + + const char componentName = component[i] & 0xFF; + + letters += componentName; + digits += '0' + 8 - componentLoss; + } + + return letters + digits; +} + +} // End of namespace Graphics diff --git a/graphics/pixelformat.h b/graphics/pixelformat.h index 00db6702fc..9dd06241b7 100644 --- a/graphics/pixelformat.h +++ b/graphics/pixelformat.h @@ -24,6 +24,7 @@ #define GRAPHICS_PIXELFORMAT_H #include "common/scummsys.h" +#include "common/str.h" namespace Graphics { @@ -260,6 +261,8 @@ struct PixelFormat { // Unsupported return 0; } + + Common::String toString() const; }; } // End of namespace Graphics diff --git a/graphics/transparent_surface.cpp b/graphics/transparent_surface.cpp index f6e8cacb8b..992a5dc879 100644 --- a/graphics/transparent_surface.cpp +++ b/graphics/transparent_surface.cpp @@ -41,8 +41,6 @@ namespace Graphics { -static const int kAShift = 0;//img->format.aShift; - static const int kBModShift = 0;//img->format.bShift; static const int kGModShift = 8;//img->format.gShift; static const int kRModShift = 16;//img->format.rShift; @@ -118,7 +116,7 @@ void doBlitBinaryFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 in = ino; for (uint32 j = 0; j < width; j++) { uint32 pix = *(uint32 *)in; - int a = (pix >> kAShift) & 0xff; + int a = (pix >> kAModShift) & 0xff; if (a != 0) { // Full opacity (Any value not exactly 0 is Opaque here) *(uint32 *)out = pix; @@ -338,7 +336,7 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p retSize.setWidth(0); retSize.setHeight(0); // Check if we need to draw anything at all - int ca = (color >> 24) & 0xff; + int ca = (color >> kAModShift) & 0xff; if (ca == 0) { return retSize; diff --git a/image/codecs/msvideo1.cpp b/image/codecs/msvideo1.cpp index 25d7395363..439f219fc5 100644 --- a/image/codecs/msvideo1.cpp +++ b/image/codecs/msvideo1.cpp @@ -30,14 +30,15 @@ namespace Image { #define CHECK_STREAM_PTR(n) \ if ((stream.pos() + n) > stream.size() ) { \ - warning ("MS Video-1: Stream out of bounds (%d >= %d)", stream.pos() + n, stream.size()); \ + warning ("MS Video-1: Stream out of bounds (%d >= %d) d%d", stream.pos() + n, stream.size(), n); \ return; \ } MSVideo1Decoder::MSVideo1Decoder(uint16 width, uint16 height, byte bitsPerPixel) : Codec() { _surface = new Graphics::Surface(); - // TODO: Specify the correct pixel format for 2Bpp mode. - _surface->create(width, height, (bitsPerPixel == 8) ? Graphics::PixelFormat::createFormatCLUT8() : Graphics::PixelFormat(2, 0, 0, 0, 0, 0, 0, 0, 0)); + _surface->create(width, height, (bitsPerPixel == 8) ? Graphics::PixelFormat::createFormatCLUT8() : + Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)); + _bitsPerPixel = bitsPerPixel; } @@ -125,13 +126,98 @@ void MSVideo1Decoder::decode8(Common::SeekableReadStream &stream) { } } +void MSVideo1Decoder::decode16(Common::SeekableReadStream &stream) { + /* decoding parameters */ + uint16 colors[8]; + uint16 *pixels = (uint16 *)_surface->getPixels(); + int32 stride = _surface->w; + + int32 skip_blocks = 0; + int32 blocks_wide = _surface->w / 4; + int32 blocks_high = _surface->h / 4; + int32 total_blocks = blocks_wide * blocks_high; + int32 block_inc = 4; + int32 row_dec = stride + 4; + + for (int32 block_y = blocks_high; block_y > 0; block_y--) { + int32 block_ptr = ((block_y * 4) - 1) * stride; + for (int32 block_x = blocks_wide; block_x > 0; block_x--) { + /* check if this block should be skipped */ + if (skip_blocks) { + block_ptr += block_inc; + skip_blocks--; + total_blocks--; + continue; + } + + int32 pixel_ptr = block_ptr; + + /* get the next two bytes in the encoded data stream */ + CHECK_STREAM_PTR(2); + byte byte_a = stream.readByte(); + byte byte_b = stream.readByte(); + + /* check if the decode is finished */ + if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0)) { + return; + } else if ((byte_b & 0xFC) == 0x84) { + /* skip code, but don't count the current block */ + skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1; + } else if (byte_b < 0x80) { + /* 2- or 8-color encoding modes */ + uint16 flags = (byte_b << 8) | byte_a; + + CHECK_STREAM_PTR(4); + colors[0] = stream.readUint16LE(); + colors[1] = stream.readUint16LE(); + + if (colors[0] & 0x8000) { + /* 8-color encoding */ + CHECK_STREAM_PTR(12); + colors[2] = stream.readUint16LE(); + colors[3] = stream.readUint16LE(); + colors[4] = stream.readUint16LE(); + colors[5] = stream.readUint16LE(); + colors[6] = stream.readUint16LE(); + colors[7] = stream.readUint16LE(); + + for (int pixel_y = 0; pixel_y < 4; pixel_y++) { + for (int pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1) + pixels[pixel_ptr++] = + colors[((pixel_y & 0x2) << 1) + + (pixel_x & 0x2) + ((flags & 0x1) ^ 1)]; + pixel_ptr -= row_dec; + } + } else { + /* 2-color encoding */ + for (int pixel_y = 0; pixel_y < 4; pixel_y++) { + for (int pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1) + pixels[pixel_ptr++] = colors[(flags & 0x1) ^ 1]; + pixel_ptr -= row_dec; + } + } + } else { + /* otherwise, it's a 1-color block */ + colors[0] = (byte_b << 8) | byte_a; + + for (int pixel_y = 0; pixel_y < 4; pixel_y++) { + for (int pixel_x = 0; pixel_x < 4; pixel_x++) + pixels[pixel_ptr++] = colors[0]; + pixel_ptr -= row_dec; + } + } + + block_ptr += block_inc; + total_blocks--; + } + } +} + const Graphics::Surface *MSVideo1Decoder::decodeFrame(Common::SeekableReadStream &stream) { if (_bitsPerPixel == 8) decode8(stream); - else { - // decode16(stream); - error ("Unhandled MS Video-1 16bpp encoding"); - } + else + decode16(stream); return _surface; } diff --git a/image/codecs/msvideo1.h b/image/codecs/msvideo1.h index 2a6dcd0a9a..f52b1f3127 100644 --- a/image/codecs/msvideo1.h +++ b/image/codecs/msvideo1.h @@ -38,7 +38,7 @@ public: ~MSVideo1Decoder(); const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream); - Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); } + Graphics::PixelFormat getPixelFormat() const { return _surface->format; } private: byte _bitsPerPixel; @@ -46,7 +46,7 @@ private: Graphics::Surface *_surface; void decode8(Common::SeekableReadStream &stream); - //void decode16(Common::SeekableReadStream &stream); + void decode16(Common::SeekableReadStream &stream); }; } // End of namespace Image |