diff options
-rw-r--r-- | engines/sci/graphics/gui.cpp | 6 | ||||
-rw-r--r-- | engines/sci/graphics/portrait.cpp | 60 | ||||
-rw-r--r-- | engines/sci/graphics/portrait.h | 14 | ||||
-rw-r--r-- | engines/sci/graphics/screen.cpp | 7 | ||||
-rw-r--r-- | engines/sci/graphics/screen.h | 1 |
5 files changed, 86 insertions, 2 deletions
diff --git a/engines/sci/graphics/gui.cpp b/engines/sci/graphics/gui.cpp index 8d76ea064d..9a85f2cb1b 100644 --- a/engines/sci/graphics/gui.cpp +++ b/engines/sci/graphics/gui.cpp @@ -39,6 +39,7 @@ #include "sci/graphics/animate.h" #include "sci/graphics/controls.h" #include "sci/graphics/menu.h" +#include "sci/graphics/portrait.h" #include "sci/graphics/robot.h" #include "sci/graphics/text.h" #include "sci/graphics/transitions.h" @@ -827,10 +828,15 @@ void SciGui::syncWithFramebuffer() { } reg_t SciGui::portraitLoad(Common::String resourceName) { + //Portrait *myPortrait = new Portrait(_s->resMan, _screen, _palette, resourceName); return NULL_REG; } void SciGui::portraitShow(Common::String resourceName, Common::Point position, uint16 resourceNum, uint16 noun, uint16 verb, uint16 cond, uint16 seq) { + Portrait *myPortrait = new Portrait(_s->resMan, _screen, _palette, resourceName); + // TODO: cache portraits + myPortrait->draw(position); + delete myPortrait; } void SciGui::portraitUnload(uint16 portraitId) { diff --git a/engines/sci/graphics/portrait.cpp b/engines/sci/graphics/portrait.cpp index e348ec2dda..ec445b3b89 100644 --- a/engines/sci/graphics/portrait.cpp +++ b/engines/sci/graphics/portrait.cpp @@ -47,12 +47,13 @@ void Portrait::init() { // .BIN files are loaded from actors directory and from .\ directory // header: // 3 bytes "WIN" - // 2 bytes main height (should be the same as first bitmap header height) // 2 bytes main width (should be the same as first bitmap header width) + // 2 bytes main height (should be the same as first bitmap header height) // 2 bytes animation count // 2 bytes unknown // 2 bytes unknown // 4 bytes paletteSize (base 1) + // -> 17 bytes // paletteSize bytes paletteData // 14 bytes bitmap header // -> 4 bytes unknown @@ -61,6 +62,63 @@ void Portrait::init() { // -> 6 bytes unknown // height * width bitmap data // another animation count times bitmap header and data + Common::SeekableReadStream *file = 0; + _fileName = "actors/" + _resourceName + ".bin"; + file = SearchMan.createReadStreamForMember(_fileName); + if (!file) { + _fileName = _resourceName + ".bin"; + file = SearchMan.createReadStreamForMember(_fileName); + if (!file) + error("portrait %s.bin not found", _resourceName.c_str()); + } + _fileSize = file->size(); + _fileData = new byte[_fileSize]; + file->read(_fileData, _fileSize); + delete file; + + if (strncmp((char *)_fileData, "WIN", 3)) { + error("portrait %s doesn't have valid header", _resourceName.c_str()); + } + _width = READ_LE_UINT16(_fileData + 3); + _height = READ_LE_UINT16(_fileData + 5); + _animationCount = READ_LE_UINT16(_fileData + 7); + + _portraitPaletteSize = READ_LE_UINT16(_fileData + 13); + byte *data = _fileData + 17; + // Read palette + memset(&_portraitPalette, 0, sizeof(Palette)); + uint16 palSize = 0, palNr = 0; + while (palSize < _portraitPaletteSize) { + _portraitPalette.colors[palNr].b = *data++; + _portraitPalette.colors[palNr].g = *data++; + _portraitPalette.colors[palNr].r = *data++; + _portraitPalette.colors[palNr].used = 1; + _portraitPalette.intensity[palNr] = 100; + palNr++; palSize += 3; + } + + // Read main bitmap + assert(READ_LE_UINT16(data + 4) == _height); + assert(READ_LE_UINT16(data + 6) == _width); + data += 14; // Skip over bitmap header + _mainBitmapData = data; + data += _height * _width; + + // TODO: Read animation bitmaps +} + +void Portrait::draw(Common::Point position) { + byte *data = _mainBitmapData; + _palette->set(&_portraitPalette, 1); + for (int y = 0; y < _height; y++) { + for (int x = 0; x < _width; x++) { + _screen->putPixelOnDisplay(position.x + x, position.y + y, _portraitPalette.mapping[*data++]); + } + } + + Common::Rect mainBitmap = Common::Rect(_width, _height); + mainBitmap.moveTo(position.x, position.y); + _screen->copyDisplayRectToScreen(mainBitmap); } } // End of namespace Sci diff --git a/engines/sci/graphics/portrait.h b/engines/sci/graphics/portrait.h index 18a23ad189..41c4bfef72 100644 --- a/engines/sci/graphics/portrait.h +++ b/engines/sci/graphics/portrait.h @@ -33,6 +33,8 @@ public: Portrait(ResourceManager *resMan, Screen *screen, SciPalette *palette, Common::String resourceName); ~Portrait(); + void draw(Common::Point position); + private: void init(); @@ -41,7 +43,17 @@ private: SciPalette *_palette; Common::String _resourceName; - byte *_resourceData; + Common::String _fileName; + byte *_fileData; + int32 _fileSize; + + uint16 _height; + uint16 _width; + uint16 _animationCount; + uint16 _portraitPaletteSize; + Palette _portraitPalette; + + byte *_mainBitmapData; }; } // End of namespace Sci diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp index a78b049e5e..18bea149f8 100644 --- a/engines/sci/graphics/screen.cpp +++ b/engines/sci/graphics/screen.cpp @@ -106,6 +106,13 @@ void Screen::copyRectToScreen(const Common::Rect &rect) { } } +// This copies a rect to screen w/o scaling adjustment and is only meant to be used on hires graphics used in upscaled hires mode +void Screen::copyDisplayRectToScreen(const Common::Rect &rect) { + if (!_upscaledHires) + error("copyDisplayRectToScreen: not in upscaled hires mode"); + g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, rect.left, rect.top, rect.width(), rect.height()); +} + void Screen::copyRectToScreen(const Common::Rect &rect, int16 x, int16 y) { if (!_upscaledHires) { g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, x, y, rect.width(), rect.height()); diff --git a/engines/sci/graphics/screen.h b/engines/sci/graphics/screen.h index ba8d906631..881025cec0 100644 --- a/engines/sci/graphics/screen.h +++ b/engines/sci/graphics/screen.h @@ -57,6 +57,7 @@ public: void copyFromScreen(byte *buffer); void syncWithFramebuffer(); void copyRectToScreen(const Common::Rect &rect); + void copyDisplayRectToScreen(const Common::Rect &rect); void copyRectToScreen(const Common::Rect &rect, int16 x, int16 y); byte getDrawingMask(byte color, byte prio, byte control); |