aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMartin Kiewitz2009-10-31 14:38:25 +0000
committerMartin Kiewitz2009-10-31 14:38:25 +0000
commitf36e9cbe4d40dc5235a2a1315eee28ab229bc6dc (patch)
treef449cc40e912cc93dc3dba2d87f77873eff92178 /engines
parent149d784d0b2be7c0a968f856557724b216cd8a95 (diff)
downloadscummvm-rg350-f36e9cbe4d40dc5235a2a1315eee28ab229bc6dc.tar.gz
scummvm-rg350-f36e9cbe4d40dc5235a2a1315eee28ab229bc6dc.tar.bz2
scummvm-rg350-f36e9cbe4d40dc5235a2a1315eee28ab229bc6dc.zip
SCI/newgui: UpscaledHires implemented including undithering support, cleanup
svn-id: r45562
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/gui/gui_cursor.cpp30
-rw-r--r--engines/sci/gui/gui_cursor.h2
-rw-r--r--engines/sci/gui/gui_screen.cpp154
-rw-r--r--engines/sci/gui/gui_screen.h12
-rw-r--r--engines/sci/sci.cpp13
-rw-r--r--engines/sci/sci.h2
6 files changed, 148 insertions, 65 deletions
diff --git a/engines/sci/gui/gui_cursor.cpp b/engines/sci/gui/gui_cursor.cpp
index e24e6e36b5..cad6b2178a 100644
--- a/engines/sci/gui/gui_cursor.cpp
+++ b/engines/sci/gui/gui_cursor.cpp
@@ -39,8 +39,9 @@ namespace Sci {
SciGuiCursor::SciGuiCursor(ResourceManager *resMan, SciGuiPalette *palette, SciGuiScreen *screen)
: _resMan(resMan), _palette(palette), _screen(screen) {
- setPosition(Common::Point(160, 150));
- setMoveZone(Common::Rect(0, 0, _screen->_displayWidth, _screen->_displayHeight));
+ _upscaledHires = _screen->getUpscaledHires();
+ setPosition(Common::Point(160, 150)); // TODO: how is that different in 640x400 games?
+ setMoveZone(Common::Rect(0, 0, 320, 200)); // TODO: hires games
}
SciGuiCursor::~SciGuiCursor() {
@@ -157,24 +158,21 @@ void SciGuiCursor::setView(GuiResourceId viewNum, int loopNum, int celNum, Commo
}
void SciGuiCursor::setPosition(Common::Point pos) {
- int scaleFactor = _screen->getScaleFactor();
-
- if (scaleFactor == 1)
+ if (!_upscaledHires) {
g_system->warpMouse(pos.x, pos.y);
- else
- g_system->warpMouse(pos.x * scaleFactor, pos.y * scaleFactor);
+ } else {
+ g_system->warpMouse(pos.x * 2, pos.y * 2);
+ }
}
Common::Point SciGuiCursor::getPosition() {
- int scaleFactor = _screen->getScaleFactor();
- Common::Point pos = g_system->getEventManager()->getMousePos();
-
- if (scaleFactor != 1) {
- pos.x /= scaleFactor;
- pos.y /= scaleFactor;
+ if (!_upscaledHires) {
+ return g_system->getEventManager()->getMousePos();
+ } else {
+ Common::Point mousePos = g_system->getEventManager()->getMousePos();
+ mousePos.x /= 2; mousePos.y /= 2;
+ return mousePos;
}
-
- return pos;
}
void SciGuiCursor::refreshPosition() {
@@ -199,7 +197,7 @@ void SciGuiCursor::refreshPosition() {
// FIXME: Do this only when mouse is grabbed?
if (clipped)
- setPosition(mousePoint);
+ g_system->warpMouse(mousePoint.x, mousePoint.y);
}
} // End of namespace Sci
diff --git a/engines/sci/gui/gui_cursor.h b/engines/sci/gui/gui_cursor.h
index a594f8a6c7..3cb9a3e537 100644
--- a/engines/sci/gui/gui_cursor.h
+++ b/engines/sci/gui/gui_cursor.h
@@ -69,6 +69,8 @@ private:
SciGuiScreen *_screen;
SciGuiPalette *_palette;
+ bool _upscaledHires;
+
Common::Rect _moveZone; // Rectangle in which the pointer can move
CursorCache _cachedCursors;
diff --git a/engines/sci/gui/gui_screen.cpp b/engines/sci/gui/gui_screen.cpp
index 3b05452d35..75360c0838 100644
--- a/engines/sci/gui/gui_screen.cpp
+++ b/engines/sci/gui/gui_screen.cpp
@@ -33,16 +33,17 @@
namespace Sci {
-SciGuiScreen::SciGuiScreen(ResourceManager *resMan, int16 width, int16 height, int16 scaleFactor) :
- _resMan(resMan), _width(width), _height(height), _scaleFactor(scaleFactor) {
+SciGuiScreen::SciGuiScreen(ResourceManager *resMan, int16 width, int16 height, bool upscaledHires) :
+ _resMan(resMan), _width(width), _height(height), _upscaledHires(upscaledHires) {
_pixels = _width * _height;
- if (scaleFactor != 1 && scaleFactor != 2)
- error("Only scaling factors of 1 or 2 are supported");
-
- _displayWidth = _width * scaleFactor;
- _displayHeight = _height * scaleFactor;
+ _displayWidth = _width;
+ _displayHeight = _height;
+ if (_upscaledHires) {
+ _displayWidth *= 2;
+ _displayHeight *= 2;
+ }
_displayPixels = _displayWidth * _displayHeight;
_visualScreen = (byte *)calloc(_pixels, 1);
@@ -90,11 +91,19 @@ void SciGuiScreen::copyFromScreen(byte *buffer) {
}
void SciGuiScreen::copyRectToScreen(const Common::Rect &rect) {
- g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, rect.left, rect.top, rect.width(), rect.height());
+ 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);
+ }
}
void SciGuiScreen::copyRectToScreen(const Common::Rect &rect, int16 x, int16 y) {
- g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, x, y, rect.width(), rect.height());
+ 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);
+ }
}
byte SciGuiScreen::getDrawingMask(byte color, byte prio, byte control) {
@@ -108,26 +117,20 @@ byte SciGuiScreen::getDrawingMask(byte color, byte prio, byte control) {
return flag;
}
-Common::Rect SciGuiScreen::getScaledRect(Common::Rect rect) {
- return Common::Rect(
- rect.left * _scaleFactor, rect.top * _scaleFactor,
- rect.left * _scaleFactor + rect.width() * _scaleFactor,
- rect.top * _scaleFactor + rect.height() * _scaleFactor);
-}
-
void SciGuiScreen::putPixel(int x, int y, byte drawMask, byte color, byte priority, byte control) {
int offset = y * _width + x;
+ int displayOffset;
if (drawMask & SCI_SCREEN_MASK_VISUAL) {
_visualScreen[offset] = color;
-
- if (_scaleFactor == 1) {
+ if (!_upscaledHires) {
_displayScreen[offset] = color;
} else {
- _displayScreen[y * _displayWidth * 2 + x * 2] = color; // the actual pixel
- _displayScreen[(y + 1) * _displayWidth * 2 + x * 2] = color; // one pixel down
- _displayScreen[y * _displayWidth * 2 + (x * 2) + 1] = color; // one pixel right
- _displayScreen[(y + 1) * _displayWidth * 2 + (x * 2) + 1] = color; // one pixel down and right
+ displayOffset = y * 2 * _displayWidth + x * 2;
+ _displayScreen[displayOffset] = color;
+ _displayScreen[displayOffset + 1] = color;
+ _displayScreen[displayOffset + _displayWidth] = color;
+ _displayScreen[displayOffset + _displayWidth + 1] = color;
}
}
if (drawMask & SCI_SCREEN_MASK_PRIORITY)
@@ -136,6 +139,13 @@ void SciGuiScreen::putPixel(int x, int y, byte drawMask, byte color, byte priori
_controlScreen[offset] = control;
}
+// This will just change a pixel directly on displayscreen. Its supposed to get only used on upscaled-Hires games where
+// hires content needs to get drawn ONTO the upscaled display screen (like japanese fonts, hires portraits, etc.)
+void SciGuiScreen::putPixelOnDisplay(int x, int y, byte color) {
+ int offset = y * _width + x;
+ _displayScreen[offset] = color;
+}
+
// Sierra's Bresenham line drawing
// WARNING: Do not just blindly replace this with Graphics::drawLine(), as it seems to create issues with flood fill
void SciGuiScreen::drawLine(Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control) {
@@ -228,11 +238,13 @@ byte SciGuiScreen::isFillMatch(int16 x, int16 y, byte screenMask, byte t_color,
int SciGuiScreen::bitsGetDataSize(Common::Rect rect, byte mask) {
int byteCount = sizeof(rect) + sizeof(mask);
int pixels = rect.width() * rect.height();
- Common::Rect scaledRect = getScaledRect(rect);
- int scaledPixels = scaledRect.width() * scaledRect.height();
if (mask & SCI_SCREEN_MASK_VISUAL) {
byteCount += pixels; // _visualScreen
- byteCount += scaledPixels; // _displayScreen
+ if (!_upscaledHires) {
+ byteCount += pixels; // _displayScreen
+ } else {
+ byteCount += pixels * 4; // _displayScreen (upscaled hires)
+ }
}
if (mask & SCI_SCREEN_MASK_PRIORITY) {
byteCount += pixels; // _priorityScreen
@@ -250,7 +262,7 @@ void SciGuiScreen::bitsSave(Common::Rect rect, byte mask, byte *memoryPtr) {
if (mask & SCI_SCREEN_MASK_VISUAL) {
bitsSaveScreen(rect, _visualScreen, memoryPtr);
- bitsSaveScreen(getScaledRect(rect), _displayScreen, memoryPtr);
+ bitsSaveDisplayScreen(rect, memoryPtr);
}
if (mask & SCI_SCREEN_MASK_PRIORITY) {
bitsSaveScreen(rect, _priorityScreen, memoryPtr);
@@ -272,6 +284,25 @@ void SciGuiScreen::bitsSaveScreen(Common::Rect rect, byte *screen, byte *&memory
}
}
+void SciGuiScreen::bitsSaveDisplayScreen(Common::Rect rect, byte *&memoryPtr) {
+ byte *screen = _displayScreen;
+ int width = rect.width();
+ int y;
+
+ if (!_upscaledHires) {
+ screen += (rect.top * _displayWidth) + rect.left;
+ } else {
+ screen += (rect.top * 2 * _displayWidth) + rect.left * 2;
+ width *= 2;
+ rect.top *= 2; rect.bottom *= 2;
+ }
+
+ for (y = rect.top; y < rect.bottom; y++) {
+ memcpy(memoryPtr, (void*)screen, width); memoryPtr += width;
+ screen += _displayWidth;
+ }
+}
+
void SciGuiScreen::bitsGetRect(byte *memoryPtr, Common::Rect *destRect) {
memcpy((void *)destRect, memoryPtr, sizeof(Common::Rect));
}
@@ -285,7 +316,7 @@ void SciGuiScreen::bitsRestore(byte *memoryPtr) {
if (mask & SCI_SCREEN_MASK_VISUAL) {
bitsRestoreScreen(rect, memoryPtr, _visualScreen);
- bitsRestoreScreen(getScaledRect(rect), memoryPtr, _displayScreen);
+ bitsRestoreDisplayScreen(rect, memoryPtr);
}
if (mask & SCI_SCREEN_MASK_PRIORITY) {
bitsRestoreScreen(rect, memoryPtr, _priorityScreen);
@@ -307,6 +338,25 @@ void SciGuiScreen::bitsRestoreScreen(Common::Rect rect, byte *&memoryPtr, byte *
}
}
+void SciGuiScreen::bitsRestoreDisplayScreen(Common::Rect rect, byte *&memoryPtr) {
+ byte *screen = _displayScreen;
+ int width = rect.width();
+ int y;
+
+ if (!_upscaledHires) {
+ screen += (rect.top * _displayWidth) + rect.left;
+ } else {
+ screen += (rect.top * 2 * _displayWidth) + rect.left * 2;
+ width *= 2;
+ rect.top *= 2; rect.bottom *= 2;
+ }
+
+ for (y = rect.top; y < rect.bottom; y++) {
+ memcpy((void*) screen, memoryPtr, width); memoryPtr += width;
+ screen += _displayWidth;
+ }
+}
+
void SciGuiScreen::setPalette(GuiPalette*pal) {
// just copy palette to system
byte bpal[4 * 256];
@@ -324,28 +374,40 @@ void SciGuiScreen::setPalette(GuiPalette*pal) {
}
void SciGuiScreen::setVerticalShakePos(uint16 shakePos) {
- g_system->setShakePos(shakePos);
+ if (!_upscaledHires)
+ g_system->setShakePos(shakePos);
+ else
+ g_system->setShakePos(shakePos * 2);
}
-// Currently not really done, its supposed to be possible to only dither _visualScreen
void SciGuiScreen::dither(bool addToFlag) {
int y, x;
- byte color;
- byte *screenPtr = _visualScreen;
+ byte color, ditheredColor;
+ byte *visualPtr = _visualScreen;
byte *displayPtr = _displayScreen;
if (!_unditherState) {
// Do dithering on visual and display-screen
for (y = 0; y < _height; y++) {
for (x = 0; x < _width; x++) {
- color = *screenPtr;
+ color = *visualPtr;
if (color & 0xF0) {
color ^= color << 4;
color = ((x^y) & 1) ? color >> 4 : color & 0x0F;
- *screenPtr = color; *displayPtr = color;
+ *displayPtr = color;
+ if (_upscaledHires) {
+ *(displayPtr + 1) = color;
+ *(displayPtr + _displayWidth) = color;
+ *(displayPtr + _displayWidth + 1) = color;
+ }
+ *visualPtr = color;
}
- screenPtr++; displayPtr++;
+ visualPtr++; displayPtr++;
+ if (_upscaledHires)
+ displayPtr++;
}
+ if (_upscaledHires)
+ displayPtr += _displayWidth;
}
} else {
if (!addToFlag)
@@ -353,7 +415,7 @@ void SciGuiScreen::dither(bool addToFlag) {
// Do dithering on visual screen and put decoded but undithered byte onto display-screen
for (y = 0; y < _height; y++) {
for (x = 0; x < _width; x++) {
- color = *screenPtr;
+ color = *visualPtr;
if (color & 0xF0) {
color ^= color << 4;
// remember dither combination for cel-undithering
@@ -361,15 +423,25 @@ void SciGuiScreen::dither(bool addToFlag) {
// if decoded color wants do dither with black on left side, we turn it around
// otherwise the normal ega color would get used for display
if (color & 0xF0) {
- *displayPtr = color;
+ ditheredColor = color;
} else {
- *displayPtr = color << 4;
+ ditheredColor = color << 4;
+ }
+ *displayPtr = ditheredColor;
+ if (_upscaledHires) {
+ *(displayPtr + 1) = ditheredColor;
+ *(displayPtr + _displayWidth) = ditheredColor;
+ *(displayPtr + _displayWidth + 1) = ditheredColor;
}
color = ((x^y) & 1) ? color >> 4 : color & 0x0F;
- *screenPtr = color;
+ *visualPtr = color;
}
- screenPtr++; displayPtr++;
+ visualPtr++; displayPtr++;
+ if (_upscaledHires)
+ displayPtr++;
}
+ if (_upscaledHires)
+ displayPtr += _displayWidth;
}
}
}
@@ -386,6 +458,10 @@ int16 *SciGuiScreen::unditherGetMemorial() {
}
void SciGuiScreen::debugShowMap(int mapNo) {
+ // We cannot really support changing maps when in upscaledHires mode
+ if (_upscaledHires)
+ return;
+
switch (mapNo) {
case 0:
_activeScreen = _visualScreen;
diff --git a/engines/sci/gui/gui_screen.h b/engines/sci/gui/gui_screen.h
index 583f9c41a4..d913210495 100644
--- a/engines/sci/gui/gui_screen.h
+++ b/engines/sci/gui/gui_screen.h
@@ -42,7 +42,7 @@ namespace Sci {
class SciGuiScreen {
public:
- SciGuiScreen(ResourceManager *resMan, int16 width = 320, int16 height = 200, int16 scaleFactor = 1);
+ SciGuiScreen(ResourceManager *resMan, int16 width = 320, int16 height = 200, bool upscaledHires = false);
~SciGuiScreen();
void copyToScreen();
@@ -52,10 +52,14 @@ public:
byte getDrawingMask(byte color, byte prio, byte control);
void putPixel(int x, int y, byte drawMask, byte color, byte prio, byte control);
+ void putPixelOnDisplay(int x, int y, byte color);
void drawLine(Common::Point startPoint, Common::Point endPoint, byte color, byte prio, byte control);
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() {
+ return _upscaledHires;
+ }
byte getVisual(int x, int y);
byte getPriority(int x, int y);
byte getControl(int x, int y);
@@ -76,8 +80,6 @@ public:
void debugShowMap(int mapNo);
- int getScaleFactor() { return _scaleFactor; }
-
uint16 _width;
uint16 _height;
uint _pixels;
@@ -92,7 +94,9 @@ public:
private:
void bitsRestoreScreen(Common::Rect rect, byte *&memoryPtr, byte *screen);
+ void bitsRestoreDisplayScreen(Common::Rect rect, byte *&memoryPtr);
void bitsSaveScreen(Common::Rect rect, byte *screen, byte *&memoryPtr);
+ void bitsSaveDisplayScreen(Common::Rect rect, byte *&memoryPtr);
bool _unditherState;
int16 _unditherMemorial[SCI_SCREEN_UNDITHERMEMORIAL_SIZE];
@@ -114,7 +118,7 @@ private:
// this is a pointer to the currently active screen (changing it only required for debug purposes)
byte *_activeScreen;
- int _scaleFactor;
+ bool _upscaledHires;
};
} // End of namespace Sci
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 4c0441e0f1..ae6f9a5599 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -105,14 +105,17 @@ Common::Error SciEngine::run() {
return Common::kNoGameDataFoundError;
}
- int scaleFactor = 1;
+ bool upscaledHires = false;
// Scale the screen, if needed
if (!strcmp(getGameID(), "kq6") && getPlatform() == Common::kPlatformWindows)
- scaleFactor = 2;
+ upscaledHires = true;
+
+ // TODO: Detect japanese editions and set upscaledHires on those as well
+ // TODO: Possibly look at first picture resource and determine if its hires or not
// Initialize graphics-related parts
- SciGuiScreen *screen = new SciGuiScreen(_resMan, 320, 200, scaleFactor); // invokes initGraphics()
+ SciGuiScreen *screen = new SciGuiScreen(_resMan, 320, 200, upscaledHires); // invokes initGraphics()
SciGuiPalette *palette = new SciGuiPalette(_resMan, screen);
SciGuiCursor *cursor = new SciGuiCursor(_resMan, palette, screen);
@@ -130,8 +133,8 @@ Common::Error SciEngine::run() {
#ifdef INCLUDE_OLDGFX
// Gui change
- //_gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor); // new
- _gamestate->_gui = new SciGui32(_gamestate, screen, palette, cursor); // old
+ _gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor); // new
+ //_gamestate->_gui = new SciGui32(_gamestate, screen, palette, cursor); // old
#else
_gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor);
#endif
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 12143fa9e9..ee4077212d 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -31,7 +31,7 @@
namespace Sci {
-#define INCLUDE_OLDGFX
+//#define INCLUDE_OLDGFX
class Console;
struct EngineState;