From d49fb8f42db7b9776f1dc426ebe2c6d806ad4720 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 24 May 2010 17:21:11 +0000 Subject: Add support for showing the icon bar in SCI1.1 Mac. svn-id: r49196 --- engines/sci/engine/kmisc.cpp | 8 +++- engines/sci/engine/selector.cpp | 1 + engines/sci/engine/vm.h | 3 ++ engines/sci/graphics/maciconbar.cpp | 91 +++++++++++++++++++++++++++++++++++++ engines/sci/graphics/maciconbar.h | 55 ++++++++++++++++++++++ engines/sci/graphics/palette.cpp | 7 ++- engines/sci/graphics/screen.cpp | 13 +++++- engines/sci/module.mk | 1 + engines/sci/resource.cpp | 23 ++++++---- engines/sci/resource.h | 10 +++- engines/sci/sci.cpp | 5 ++ engines/sci/sci.h | 3 +- 12 files changed, 205 insertions(+), 15 deletions(-) create mode 100644 engines/sci/graphics/maciconbar.cpp create mode 100644 engines/sci/graphics/maciconbar.h (limited to 'engines/sci') diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index aee1d58357..6fc4b2fc1d 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -32,6 +32,7 @@ #include "sci/engine/kernel.h" #include "sci/engine/gc.h" #include "sci/graphics/gui.h" +#include "sci/graphics/maciconbar.h" namespace Sci { @@ -297,9 +298,12 @@ reg_t kMemory(EngineState *s, int argc, reg_t *argv) { reg_t kIconBar(EngineState *s, int argc, reg_t *argv) { // TODO... - if (argv[0].toUint16() == 4 && argv[1].toUint16() == 0) + if (argv[0].toUint16() == 4 && argv[1].toUint16() == 0) { for (int i = 0; i < argv[2].toUint16(); i++) - warning("kIconBar: Icon Object %d = %04x:%04x", i, PRINT_REG(argv[i + 3])); + g_sci->_macIconBar->addIcon(argv[i + 3]); + + g_sci->_macIconBar->drawIcons(); + } // Other calls seem to handle selecting/deselecting them diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index e226c4b574..aba134818b 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -158,6 +158,7 @@ void Kernel::mapSelectors() { FIND_SELECTOR(scaleSignal); FIND_SELECTOR(scaleX); FIND_SELECTOR(scaleY); + FIND_SELECTOR(iconIndex); #ifdef ENABLE_SCI32 FIND_SELECTOR(data); diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index 97a01051d6..f6151dfc9d 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -197,6 +197,9 @@ struct SelectorCache { Selector overlay; ///< Used to determine if a game is using old gfx functions or not Selector setCursor; ///< For cursor semantics autodetection + // SCI1.1 Mac icon bar selectors + Selector iconIndex; ///< Used to index icon bar objects + #ifdef ENABLE_SCI32 Selector data; // Used by Array()/String() Selector picture; // Used to hold the picture ID for SCI32 pictures diff --git a/engines/sci/graphics/maciconbar.cpp b/engines/sci/graphics/maciconbar.cpp new file mode 100644 index 0000000000..b2a0b0677d --- /dev/null +++ b/engines/sci/graphics/maciconbar.cpp @@ -0,0 +1,91 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "sci/sci.h" +#include "sci/engine/selector.h" +#include "sci/engine/state.h" +#include "sci/graphics/maciconbar.h" +#include "sci/graphics/palette.h" + +#include "common/stream.h" +#include "common/system.h" +#include "graphics/pict.h" +#include "graphics/surface.h" + +namespace Sci { + +void MacIconBar::addIcon(reg_t obj) { + _iconBarObjects.push_back(obj); +} + +void MacIconBar::drawIcons() { + // Draw the icons to the bottom of the screen + + byte *pal = new byte[256 * 4]; + Graphics::PictDecoder *pict = new Graphics::PictDecoder(Graphics::PixelFormat::createFormatCLUT8()); + uint32 lastX = 0; + + for (uint32 i = 0; i < _iconBarObjects.size(); i++) { + uint32 iconIndex = GET_SEL32V(g_sci->getEngineState()->_segMan, _iconBarObjects[i], SELECTOR(iconIndex)); + Resource *res = g_sci->getResMan()->findResource(ResourceId(kResourceTypeMacIconBarPictN, iconIndex + 1), false); + if (!res) + continue; + + Common::MemoryReadStream *stream = new Common::MemoryReadStream(res->data, res->size); + Graphics::Surface *surf = pict->decodeImage(stream, pal); + remapColors(surf, pal); + + g_system->copyRectToScreen((byte *)surf->pixels, surf->pitch, lastX, 200, MIN(surf->w, 320 - lastX), surf->h); + + lastX += surf->w; + surf->free(); + delete surf; + delete stream; + } + + delete pict; + delete[] pal; +} + +void MacIconBar::remapColors(Graphics::Surface *surf, byte *palette) { + byte *pixels = (byte *)surf->pixels; + + // Remap to the screen palette + for (uint16 i = 0; i < surf->w * surf->h; i++) { + byte color = *pixels; + + byte r = palette[color * 4]; + byte g = palette[color * 4 + 1]; + byte b = palette[color * 4 + 2]; + + // For black, make sure the index is 0 + if (r == 0 && g == 0 && b == 0) + *pixels++ = 0; + else + *pixels++ = g_sci->_gfxPalette->kernelFindColor(r, g, b); + } +} + +} // End of namespace Sci diff --git a/engines/sci/graphics/maciconbar.h b/engines/sci/graphics/maciconbar.h new file mode 100644 index 0000000000..668e033f6c --- /dev/null +++ b/engines/sci/graphics/maciconbar.h @@ -0,0 +1,55 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#ifndef SCI_GRAPHICS_MACICONBAR_H +#define SCI_GRAPHICS_MACICONBAR_H + +#include "common/array.h" + +#include "sci/engine/vm.h" + +namespace Graphics { + class Surface; +} + +namespace Sci { + +class MacIconBar { +public: + MacIconBar() {} + ~MacIconBar() {} + + void addIcon(reg_t obj); + void drawIcons(); + +private: + Common::Array _iconBarObjects; + + void remapColors(Graphics::Surface *surf, byte *palette); +}; + +} // End of namespace Sci + +#endif diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp index 96bdb42007..841202abce 100644 --- a/engines/sci/graphics/palette.cpp +++ b/engines/sci/graphics/palette.cpp @@ -30,8 +30,9 @@ #include "sci/sci.h" #include "sci/engine/state.h" -#include "sci/graphics/screen.h" +#include "sci/graphics/maciconbar.h" #include "sci/graphics/palette.h" +#include "sci/graphics/screen.h" namespace Sci { @@ -311,6 +312,10 @@ void GfxPalette::setOnScreen() { if (_resMan->isAmiga32color()) return; _screen->setPalette(&_sysPalette); + + // Redraw the Mac SCI1.1 Icon bar every palette change + if (g_sci->_macIconBar) + g_sci->_macIconBar->drawIcons(); } bool GfxPalette::kernelSetFromResource(GuiResourceId resourceId, bool force) { diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp index 7ca9e33509..0e054d5a76 100644 --- a/engines/sci/graphics/screen.cpp +++ b/engines/sci/graphics/screen.cpp @@ -93,7 +93,18 @@ GfxScreen::GfxScreen(ResourceManager *resMan, int16 width, int16 height, int ups } // Initialize the actual screen - initGraphics(_displayWidth, _displayHeight, _displayWidth > 320); + + if (_resMan->isSci11Mac() && getSciVersion() == SCI_VERSION_1_1) { + // For SCI1.1 Mac, we need to expand the screen to accommodate for + // the icon bar. Of course, both KQ6 and QFG1 VGA differ in size. + if (!scumm_stricmp(g_sci->getGameID(), "kq6")) + initGraphics(_displayWidth, _displayHeight + 26, _displayWidth > 320); + else if (!scumm_stricmp(g_sci->getGameID(), "qfg1")) + initGraphics(_displayWidth, _displayHeight + 20, _displayWidth > 320); + else + error("Unknown SCI1.1 Mac game"); + } else + initGraphics(_displayWidth, _displayHeight, _displayWidth > 320); } GfxScreen::~GfxScreen() { diff --git a/engines/sci/module.mk b/engines/sci/module.mk index 8c4d666ba7..26ae1c16b1 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -44,6 +44,7 @@ MODULE_OBJS := \ graphics/font.o \ graphics/fontsjis.o \ graphics/gui.o \ + graphics/maciconbar.o \ graphics/menu.o \ graphics/paint.o \ graphics/paint16.o \ diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index aa3b8019de..428e66ebe2 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -445,11 +445,10 @@ void ResourceManager::loadResource(Resource *res) { return; if (res->_source->source_type == kSourceMacResourceFork) { - //error("ResourceManager::loadResource(): TODO: Mac resource fork ;)"); Common::SeekableReadStream *stream = res->_source->macResMan.getResource(resTypeToMacTag(res->_id.type), res->_id.number); if (!stream) - error("Could not get Mac resource fork resource"); + error("Could not get Mac resource fork resource: %d %d", res->_id.type, res->_id.number); int error = decompress(res, stream); if (error) { @@ -1476,7 +1475,10 @@ struct { { MKID_BE('PAL '), kResourceTypePalette }, { MKID_BE('snd '), kResourceTypeAudio }, { MKID_BE('MSG '), kResourceTypeMessage }, - { MKID_BE('HEP '), kResourceTypeHeap } + { MKID_BE('HEP '), kResourceTypeHeap }, + { MKID_BE('IBIN'), kResourceTypeMacIconBarPictN }, + { MKID_BE('IBIS'), kResourceTypeMacIconBarPictS }, + { MKID_BE('PICT'), kResourceTypeMacPict } }; static uint32 resTypeToMacTag(ResourceType type) { @@ -1509,6 +1511,16 @@ int ResourceManager::readMacResourceFork(ResourceSource *source) { Common::MacResIDArray idArray = source->macResMan.getResIDArray(tagArray[i]); for (uint32 j = 0; j < idArray.size(); j++) { + // Get the size of the file + Common::SeekableReadStream *stream = source->macResMan.getResource(tagArray[i], idArray[j]); + + // Some IBIS resources have a size of 0, so we skip them + if (!stream) + continue; + + uint32 fileSize = stream->size(); + delete stream; + ResourceId resId = ResourceId(type, idArray[j]); Resource *newrsc = NULL; @@ -1520,11 +1532,6 @@ int ResourceManager::readMacResourceFork(ResourceSource *source) { } else newrsc = _resMap.getVal(resId); - // Get the size of the file - Common::SeekableReadStream *stream = source->macResMan.getResource(tagArray[i], idArray[j]); - uint32 fileSize = stream->size(); - delete stream; - // Overwrite everything newrsc->_id = resId; newrsc->_status = kResStatusNoMalloc; diff --git a/engines/sci/resource.h b/engines/sci/resource.h index befda072e0..8e83ed7bf0 100644 --- a/engines/sci/resource.h +++ b/engines/sci/resource.h @@ -108,7 +108,13 @@ enum ResourceType { kResourceTypeUnknown1, // Translation, currently unsupported kResourceTypeUnknown2, kResourceTypeRobot, - kResourceTypeInvalid + kResourceTypeInvalid, + + // Mac-only resources, these resource types are self-defined + // Numbers subject to change + kResourceTypeMacIconBarPictN = -1, // IBIN resources (icon bar, not selected) + kResourceTypeMacIconBarPictS = -2, // IBIS resources (icon bar, selected) + kResourceTypeMacPict = -3 // PICT resources (inventory) }; const char *getResourceTypeName(ResourceType restype); @@ -127,7 +133,7 @@ public: ResourceId(ResourceType type_, uint16 number_, uint32 tuple_ = 0) : type(type_), number(number_), tuple(tuple_) { - if ((type < kResourceTypeView) || (type > kResourceTypeInvalid)) + if (type < kResourceTypeMacPict || type > kResourceTypeInvalid) type = kResourceTypeInvalid; } diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index bb5124b88b..c9f201d1f5 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -43,6 +43,7 @@ #include "sci/sound/audio.h" #include "sci/sound/soundcmd.h" #include "sci/graphics/gui.h" +#include "sci/graphics/maciconbar.h" #include "sci/graphics/ports.h" #include "sci/graphics/palette.h" #include "sci/graphics/cursor.h" @@ -97,6 +98,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc) DebugMan.addDebugChannel(kDebugLevelOnStartup, "OnStartup", "Enter debugger at start of game"); _gamestate = 0; + _macIconBar = 0; const Common::FSNode gameDataDir(ConfMan.get("path")); @@ -170,6 +172,9 @@ Common::Error SciEngine::run() { else screen = new GfxScreen(_resMan, 320, 200, upscaledHires); + if (_resMan->isSci11Mac() && getSciVersion() == SCI_VERSION_1_1) + _macIconBar = new MacIconBar(); + GfxPalette *palette = new GfxPalette(_resMan, screen); GfxCache *cache = new GfxCache(_resMan, screen, palette); GfxCursor *cursor = new GfxCursor(_resMan, palette, screen); diff --git a/engines/sci/sci.h b/engines/sci/sci.h index fdd10bcd04..b785b256d7 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -65,7 +65,7 @@ class GfxPalette; class GfxPorts; class GfxScreen; class SciGui; - +class MacIconBar; #ifdef ENABLE_SCI32 class SciGui32; @@ -206,6 +206,7 @@ public: GfxPorts *_gfxPorts; // Port managment for 16-bit gfx GfxScreen *_gfxScreen; SciGui *_gui; /* Currently active Gui */ + MacIconBar *_macIconBar; // Mac Icon Bar manager #ifdef ENABLE_SCI32 SciGui32 *_gui32; // GUI for SCI32 games -- cgit v1.2.3