diff options
author | Martin Kiewitz | 2010-05-15 14:17:50 +0000 |
---|---|---|
committer | Martin Kiewitz | 2010-05-15 14:17:50 +0000 |
commit | eb2b3f352ed03dc7299ff6202e68a68116476aa9 (patch) | |
tree | be15aec31d9d077ffc9760d4ee707d5e22d6503c /engines | |
parent | 59a255226f95d395cb73119ae2e04a3494d404a5 (diff) | |
download | scummvm-rg350-eb2b3f352ed03dc7299ff6202e68a68116476aa9.tar.gz scummvm-rg350-eb2b3f352ed03dc7299ff6202e68a68116476aa9.tar.bz2 scummvm-rg350-eb2b3f352ed03dc7299ff6202e68a68116476aa9.zip |
SCI: adding upscaled hires mode 640x480 for kq6 and gk1, fixing valgrind error in GfxPortrait class, not using priority anymore when drawing hires cels (shouldnt be needed for kq6)
svn-id: r49040
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/graphics/cursor.cpp | 14 | ||||
-rw-r--r-- | engines/sci/graphics/cursor.h | 2 | ||||
-rw-r--r-- | engines/sci/graphics/gui.cpp | 2 | ||||
-rw-r--r-- | engines/sci/graphics/paint16.cpp | 15 | ||||
-rw-r--r-- | engines/sci/graphics/portrait.cpp | 2 | ||||
-rw-r--r-- | engines/sci/graphics/screen.cpp | 73 | ||||
-rw-r--r-- | engines/sci/graphics/screen.h | 17 | ||||
-rw-r--r-- | engines/sci/graphics/transitions.cpp | 4 | ||||
-rw-r--r-- | engines/sci/graphics/view.cpp | 14 | ||||
-rw-r--r-- | engines/sci/sci.cpp | 10 |
10 files changed, 98 insertions, 55 deletions
diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp index d0f8538955..5ffb233566 100644 --- a/engines/sci/graphics/cursor.cpp +++ b/engines/sci/graphics/cursor.cpp @@ -44,7 +44,7 @@ GfxCursor::GfxCursor(ResourceManager *resMan, GfxPalette *palette, GfxScreen *sc _upscaledHires = _screen->getUpscaledHires(); // center mouse cursor - setPosition(Common::Point(_screen->getDisplayWidth() / 2, _screen->getDisplayHeight() / 2)); + setPosition(Common::Point(_screen->getWidth() / 2, _screen->getHeight() / 2)); kernelSetMoveZone(Common::Rect(0, 0, _screen->getDisplayWidth(), _screen->getDisplayHeight())); _isVisible = true; @@ -209,16 +209,24 @@ void GfxCursor::setPosition(Common::Point pos) { if (!_upscaledHires) { g_system->warpMouse(pos.x, pos.y); } else { - g_system->warpMouse(pos.x * 2, pos.y * 2); + _screen->adjustToUpscaledCoordinates(pos.y, pos.x); + g_system->warpMouse(pos.x, pos.y); } } Common::Point GfxCursor::getPosition() { Common::Point mousePos = g_system->getEventManager()->getMousePos(); - if (_upscaledHires) { + switch (_upscaledHires) { + case GFX_SCREEN_UPSCALED_640x400: mousePos.x /= 2; mousePos.y /= 2; + break; + case GFX_SCREEN_UPSCALED_640x480: + mousePos.x /= 2; + mousePos.y = (mousePos.y * 5) / 12; + default: + break; } return mousePos; diff --git a/engines/sci/graphics/cursor.h b/engines/sci/graphics/cursor.h index a32df21a1b..c0b5f9a478 100644 --- a/engines/sci/graphics/cursor.h +++ b/engines/sci/graphics/cursor.h @@ -75,7 +75,7 @@ private: GfxCoordAdjuster *_coordAdjuster; SciEvent *_event; - bool _upscaledHires; + int _upscaledHires; Common::Rect _moveZone; // Rectangle in which the pointer can move diff --git a/engines/sci/graphics/gui.cpp b/engines/sci/graphics/gui.cpp index 3316fadb56..46f7fcd689 100644 --- a/engines/sci/graphics/gui.cpp +++ b/engines/sci/graphics/gui.cpp @@ -128,7 +128,7 @@ void SciGui::portraitShow(Common::String resourceName, Common::Point position, u // adjust given coordinates to curPort (but dont adjust coordinates on upscaledHires_Save_Box and give us hires coordinates // on kDrawCel, yeah this whole stuff makes sense) position.x += _ports->getPort()->left; position.y += _ports->getPort()->top; - position.x *= 2; position.y *= 2; + _screen->adjustToUpscaledCoordinates(position.y, position.x); myPortrait->doit(position, resourceId, noun, verb, cond, seq); delete myPortrait; } diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp index b829071f74..5f78b18b1e 100644 --- a/engines/sci/graphics/paint16.cpp +++ b/engines/sci/graphics/paint16.cpp @@ -152,15 +152,18 @@ void GfxPaint16::drawHiresCelAndShow(GuiResourceId viewId, int16 loopNo, int16 c // adjust curPort to upscaled hires clipRect = celRect; curPortRect = _ports->_curPort->rect; - curPortRect.top *= 2; curPortRect.bottom *= 2; curPortRect.bottom++; - curPortRect.left *= 2; curPortRect.right *= 2; curPortRect.right++; + _screen->adjustToUpscaledCoordinates(curPortRect.top, curPortRect.left); + _screen->adjustToUpscaledCoordinates(curPortRect.bottom, curPortRect.right); + curPortRect.bottom++; + curPortRect.right++; clipRect.clip(curPortRect); if (clipRect.isEmpty()) // nothing to draw return; clipRectTranslated = clipRect; if (!upscaledHiresHack) { - curPortPos.x = _ports->_curPort->left * 2; curPortPos.y = _ports->_curPort->top * 2; + curPortPos.x = _ports->_curPort->left; curPortPos.y = _ports->_curPort->top; + _screen->adjustToUpscaledCoordinates(curPortPos.y, curPortPos.x); clipRectTranslated.top += curPortPos.y; clipRectTranslated.bottom += curPortPos.y; clipRectTranslated.left += curPortPos.x; clipRectTranslated.right += curPortPos.x; } @@ -308,8 +311,10 @@ reg_t GfxPaint16::bitsSave(const Common::Rect &rect, byte screenMask) { if (screenMask == GFX_SCREEN_MASK_DISPLAY) { // Adjust rect to upscaled hires, but dont adjust according to port - workerRect.top *= 2; workerRect.bottom *= 2; workerRect.bottom++; - workerRect.left *= 2; workerRect.right *= 2; workerRect.right++; + _screen->adjustToUpscaledCoordinates(workerRect.top, workerRect.left); + _screen->adjustToUpscaledCoordinates(workerRect.bottom, workerRect.right); + workerRect.bottom++; + workerRect.right++; } else { _ports->offsetRect(workerRect); } diff --git a/engines/sci/graphics/portrait.cpp b/engines/sci/graphics/portrait.cpp index 0012aece95..1208f8ed65 100644 --- a/engines/sci/graphics/portrait.cpp +++ b/engines/sci/graphics/portrait.cpp @@ -45,7 +45,7 @@ Portrait::Portrait(ResourceManager *resMan, SciEvent *event, SciGui *gui, GfxScr Portrait::~Portrait() { delete[] _bitmaps; - delete _fileData; + delete[] _fileData; } void Portrait::init() { diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp index 7a67936ebf..8d20dca3a2 100644 --- a/engines/sci/graphics/screen.cpp +++ b/engines/sci/graphics/screen.cpp @@ -35,23 +35,29 @@ namespace Sci { -GfxScreen::GfxScreen(ResourceManager *resMan, int16 width, int16 height, bool upscaledHires) : +GfxScreen::GfxScreen(ResourceManager *resMan, int16 width, int16 height, int upscaledHires) : _resMan(resMan), _width(width), _height(height), _upscaledHires(upscaledHires) { _pixels = _width * _height; - _displayWidth = _width; - _displayHeight = _height; - - if (_upscaledHires) { - _displayWidth *= 2; - _displayHeight *= 2; - -#ifdef ENABLE_SCI32 - // SCI32 also corrects the aspect ratio when upscaling the resolution. - // This is especially needed in GK1, as the credits video is 640x480. - if (getSciVersion() >= SCI_VERSION_2) - _displayHeight = _displayHeight * 6 / 5; -#endif + + switch (_upscaledHires) { + case GFX_SCREEN_UPSCALED_640x400: + _displayWidth = 640; + _displayHeight = 400; + for (int i = 0; i <= _height; i++) + _upscaledMapping[i] = i * 2; + break; + case GFX_SCREEN_UPSCALED_640x480: + _displayWidth = 640; + _displayHeight = 480; + for (int i = 0; i <= _height; i++) + _upscaledMapping[i] = (i * 12) / 5; + break; + default: + _displayWidth = _width; + _displayHeight = _height; + memset(&_upscaledMapping, 0, sizeof(_upscaledMapping) ); + break; } _displayPixels = _displayWidth * _displayHeight; @@ -98,7 +104,7 @@ void GfxScreen::copyToScreen() { void GfxScreen::copyFromScreen(byte *buffer) { Graphics::Surface *screen; screen = g_system->lockScreen(); - memcpy(buffer, screen->pixels, _displayWidth * _displayHeight); + memcpy(buffer, screen->pixels, _displayPixels); g_system->unlockScreen(); } @@ -113,7 +119,8 @@ void GfxScreen::copyRectToScreen(const Common::Rect &rect) { if (!_upscaledHires) { g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, rect.left, rect.top, rect.width(), rect.height()); } else { - g_system->copyRectToScreen(_activeScreen + rect.top * 2 * _displayWidth + rect.left * 2, _displayWidth, rect.left * 2, rect.top * 2, rect.width() * 2, rect.height() * 2); + int rectHeight = _upscaledMapping[rect.bottom] - _upscaledMapping[rect.top]; + g_system->copyRectToScreen(_activeScreen + _upscaledMapping[rect.top] * _displayWidth + rect.left * 2, _displayWidth, rect.left * 2, _upscaledMapping[rect.top], rect.width() * 2, rectHeight); } } @@ -128,7 +135,8 @@ void GfxScreen::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()); } else { - g_system->copyRectToScreen(_activeScreen + rect.top * 2 * _displayWidth + rect.left * 2, _displayWidth, x * 2, y * 2, rect.width() * 2, rect.height() * 2); + int rectHeight = _upscaledMapping[rect.bottom] - _upscaledMapping[rect.top]; + g_system->copyRectToScreen(_activeScreen + _upscaledMapping[rect.top] * _displayWidth + rect.left * 2, _displayWidth, x * 2, _upscaledMapping[y], rect.width() * 2, rectHeight); } } @@ -151,11 +159,14 @@ void GfxScreen::putPixel(int x, int y, byte drawMask, byte color, byte priority, if (!_upscaledHires) { _displayScreen[offset] = color; } else { - int displayOffset = y * 2 * _displayWidth + x * 2; - _displayScreen[displayOffset] = color; - _displayScreen[displayOffset + 1] = color; - _displayScreen[displayOffset + _displayWidth] = color; - _displayScreen[displayOffset + _displayWidth + 1] = color; + int displayOffset = _upscaledMapping[y] * _displayWidth + x * 2; + int heightOffsetBreak = (_upscaledMapping[y + 1] - _upscaledMapping[y]) * _displayWidth; + int heightOffset = 0; + do { + _displayScreen[displayOffset + heightOffset] = color; + _displayScreen[displayOffset + heightOffset + 1] = color; + heightOffset += _displayWidth; + } while (heightOffset != heightOffsetBreak); } } if (drawMask & GFX_SCREEN_MASK_PRIORITY) @@ -275,7 +286,8 @@ int GfxScreen::bitsGetDataSize(Common::Rect rect, byte mask) { if (!_upscaledHires) { byteCount += pixels; // _displayScreen } else { - byteCount += pixels * 4; // _displayScreen (upscaled hires) + int rectHeight = _upscaledMapping[rect.bottom] - _upscaledMapping[rect.top]; + byteCount += rectHeight * rect.width() * 2; // _displayScreen (upscaled hires) } } if (mask & GFX_SCREEN_MASK_PRIORITY) { @@ -334,9 +346,10 @@ void GfxScreen::bitsSaveDisplayScreen(Common::Rect rect, byte *&memoryPtr) { if (!_upscaledHires) { screen += (rect.top * _displayWidth) + rect.left; } else { - screen += (rect.top * 2 * _displayWidth) + rect.left * 2; + screen += (_upscaledMapping[rect.top] * _displayWidth) + rect.left * 2; width *= 2; - rect.top *= 2; rect.bottom *= 2; + rect.top = _upscaledMapping[rect.top]; + rect.bottom = _upscaledMapping[rect.bottom]; } for (y = rect.top; y < rect.bottom; y++) { @@ -393,9 +406,10 @@ void GfxScreen::bitsRestoreDisplayScreen(Common::Rect rect, byte *&memoryPtr) { if (!_upscaledHires) { screen += (rect.top * _displayWidth) + rect.left; } else { - screen += (rect.top * 2 * _displayWidth) + rect.left * 2; + screen += (_upscaledMapping[rect.top] * _displayWidth) + rect.left * 2; width *= 2; - rect.top *= 2; rect.bottom *= 2; + rect.top = _upscaledMapping[rect.top]; + rect.bottom = _upscaledMapping[rect.bottom]; } for (y = rect.top; y < rect.bottom; y++) { @@ -542,6 +556,11 @@ void GfxScreen::scale2x(byte *src, byte *dst, int16 srcWidth, int16 srcHeight) { } } +void GfxScreen::adjustToUpscaledCoordinates(int16 &y, int16 &x) { + x *= 2; + y = _upscaledMapping[y]; +} + int16 GfxScreen::kernelPicNotValid(int16 newPicNotValid) { int16 oldPicNotValid; diff --git a/engines/sci/graphics/screen.h b/engines/sci/graphics/screen.h index f73b23a55d..bb8d1231d5 100644 --- a/engines/sci/graphics/screen.h +++ b/engines/sci/graphics/screen.h @@ -33,7 +33,7 @@ namespace Sci { -#define SCI_SCREEN_MAXHEIGHT 400 +#define SCI_SCREEN_UPSCALEDMAXHEIGHT 200 enum GfxScreenUpscaledMode { GFX_SCREEN_UPSCALED_DISABLED = 0, @@ -58,7 +58,7 @@ enum GfxScreenMasks { */ class GfxScreen { public: - GfxScreen(ResourceManager *resMan, int16 width = 320, int16 height = 200, bool upscaledHires = false); + GfxScreen(ResourceManager *resMan, int16 width = 320, int16 height = 200, int upscaledHires = GFX_SCREEN_UPSCALED_DISABLED); ~GfxScreen(); uint16 getWidth() { return _width; } @@ -82,7 +82,7 @@ public: void drawLine(int16 left, int16 top, int16 right, int16 bottom, byte color, byte prio, byte control) { drawLine(Common::Point(left, top), Common::Point(right, bottom), color, prio, control); } - bool getUpscaledHires() { + int getUpscaledHires() { return _upscaledHires; } void putKanjiChar(Graphics::FontSJIS *commonFont, int16 x, int16 y, uint16 chr, byte color); @@ -102,6 +102,8 @@ public: void scale2x(byte *src, byte *dst, int16 srcWidth, int16 srcHeight); + void adjustToUpscaledCoordinates(int16 &y, int16 &x); + void dither(bool addToFlag); void debugUnditherSetState(bool flag); int16 *unditherGetMemorial(); @@ -138,7 +140,7 @@ private: byte *_priorityScreen; byte *_controlScreen; - // this screen is the one that is actually displayed to the user. It may be 640x480 for japanese SCI1 games + // this screen is the one that is actually displayed to the user. It may be 640x400 for japanese SCI1 games // SCI0 games may be undithered in here. Only read from this buffer for Save/ShowBits usage. byte *_displayScreen; @@ -148,7 +150,12 @@ private: // this is a pointer to the currently active screen (changing it only required for debug purposes) byte *_activeScreen; - bool _upscaledHires; + + // this variable defines, if upscaled hires is active and what upscaled mode is used + int _upscaledHires; + + // this here holds a translation for vertical coordinates between native (visual) and actual (display) screen + int _upscaledMapping[SCI_SCREEN_UPSCALEDMAXHEIGHT + 1]; }; } // End of namespace Sci diff --git a/engines/sci/graphics/transitions.cpp b/engines/sci/graphics/transitions.cpp index 8acbebcb30..1976326aa9 100644 --- a/engines/sci/graphics/transitions.cpp +++ b/engines/sci/graphics/transitions.cpp @@ -269,8 +269,8 @@ void GfxTransitions::copyRectToScreen(const Common::Rect rect, bool blackoutFlag surface->fillRect(rect, 0); } else { Common::Rect upscaledRect = rect; - upscaledRect.top *= 2; upscaledRect.bottom *= 2; - upscaledRect.left *= 2; upscaledRect.right *= 2; + _screen->adjustToUpscaledCoordinates(upscaledRect.top, upscaledRect.left); + _screen->adjustToUpscaledCoordinates(upscaledRect.bottom, upscaledRect.right); surface->fillRect(upscaledRect, 0); } g_system->unlockScreen(); diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp index aa1ad10c75..5ce323751c 100644 --- a/engines/sci/graphics/view.cpp +++ b/engines/sci/graphics/view.cpp @@ -524,12 +524,16 @@ void GfxView::draw(Common::Rect rect, Common::Rect clipRect, Common::Rect clipRe for (y = 0; y < height; y++, bitmap += celWidth) { for (x = 0; x < width; x++) { color = bitmap[x]; - if (color != clearKey && priority >= _screen->getPriority(clipRectTranslated.left + x, clipRectTranslated.top + y)) { - // UpscaledHires means view is hires and is supposed to get drawn onto lowres screen - if (!upscaledHires) - _screen->putPixel(clipRectTranslated.left + x, clipRectTranslated.top + y, drawMask, palette->mapping[color], priority, 0); - else + if (color != clearKey) { + if (!upscaledHires) { + if (priority >= _screen->getPriority(clipRectTranslated.left + x, clipRectTranslated.top + y)) + _screen->putPixel(clipRectTranslated.left + x, clipRectTranslated.top + y, drawMask, palette->mapping[color], priority, 0); + } else { + // UpscaledHires means view is hires and is supposed to get drawn onto lowres screen + // FIXME(?): we can't read priority directly with the hires coordinates. may not be needed at all + // in kq6 _screen->putPixelOnDisplay(clipRectTranslated.left + x, clipRectTranslated.top + y, palette->mapping[color]); + } } } } diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 36318e1a32..49546fe4c8 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -141,30 +141,30 @@ Common::Error SciEngine::run() { } // Scale the screen, if needed - bool upscaledHires = false; + int upscaledHires = GFX_SCREEN_UPSCALED_DISABLED; // King's Quest 6 and Gabriel Knight 1 have hires content, gk1/cd was able to provide that under DOS as well, but as // gk1/floppy does support upscaled hires scriptswise, but doesn't actually have the hires content we need to limit // it to platform windows. if (getPlatform() == Common::kPlatformWindows) { if (!strcmp(getGameID(), "kq6")) - upscaledHires = true; + upscaledHires = GFX_SCREEN_UPSCALED_640x480; #ifdef ENABLE_SCI32 if (!strcmp(getGameID(), "gk1")) - upscaledHires = true; + upscaledHires = GFX_SCREEN_UPSCALED_640x480; #endif } // Japanese versions of games use hi-res font on upscaled version of the game if ((getLanguage() == Common::JA_JPN) && (getSciVersion() <= SCI_VERSION_1_1)) - upscaledHires = true; + upscaledHires = GFX_SCREEN_UPSCALED_640x400; // Initialize graphics-related parts GfxScreen *screen = 0; // invokes initGraphics() if (_resMan->detectHires()) - screen = new GfxScreen(_resMan, 640, 480, false); + screen = new GfxScreen(_resMan, 640, 480); else screen = new GfxScreen(_resMan, 320, 200, upscaledHires); |