Merged RGB color API and support in from /scummvm/branches/gsoc2009-16bit/
svn-id: r43577
This commit is contained in:
commit
3084919b32
59 changed files with 1911 additions and 720 deletions
|
@ -26,6 +26,9 @@
|
|||
#include "backends/platform/sdl/sdl.h"
|
||||
#include "common/mutex.h"
|
||||
#include "common/util.h"
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
#include "common/list.h"
|
||||
#endif
|
||||
#include "graphics/font.h"
|
||||
#include "graphics/fontman.h"
|
||||
#include "graphics/scaler.h"
|
||||
|
@ -97,6 +100,9 @@ void OSystem_SDL::beginGFXTransaction(void) {
|
|||
_transactionDetails.needUpdatescreen = false;
|
||||
|
||||
_transactionDetails.normal1xScaler = false;
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
_transactionDetails.formatChanged = false;
|
||||
#endif
|
||||
|
||||
_oldVideoMode = _videoMode;
|
||||
}
|
||||
|
@ -120,6 +126,13 @@ OSystem::TransactionError OSystem_SDL::endGFXTransaction(void) {
|
|||
|
||||
_videoMode.mode = _oldVideoMode.mode;
|
||||
_videoMode.scaleFactor = _oldVideoMode.scaleFactor;
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
} else if (_videoMode.format != _oldVideoMode.format) {
|
||||
errors |= kTransactionFormatNotSupported;
|
||||
|
||||
_videoMode.format = _oldVideoMode.format;
|
||||
_screenFormat = _videoMode.format;
|
||||
#endif
|
||||
} else if (_videoMode.screenWidth != _oldVideoMode.screenWidth || _videoMode.screenHeight != _oldVideoMode.screenHeight) {
|
||||
errors |= kTransactionSizeChangeFailed;
|
||||
|
||||
|
@ -143,7 +156,11 @@ OSystem::TransactionError OSystem_SDL::endGFXTransaction(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
if (_transactionDetails.sizeChanged || _transactionDetails.formatChanged) {
|
||||
#else
|
||||
if (_transactionDetails.sizeChanged) {
|
||||
#endif
|
||||
unloadGFXMode();
|
||||
if (!loadGFXMode()) {
|
||||
if (_oldVideoMode.setup) {
|
||||
|
@ -186,12 +203,94 @@ OSystem::TransactionError OSystem_SDL::endGFXTransaction(void) {
|
|||
} else if (_transactionDetails.needUpdatescreen) {
|
||||
setGraphicsModeIntern();
|
||||
internUpdateScreen();
|
||||
}
|
||||
}
|
||||
|
||||
_transactionMode = kTransactionNone;
|
||||
return (TransactionError)errors;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
const Graphics::PixelFormat RGBList[] = {
|
||||
#ifdef ENABLE_32BIT
|
||||
// RGBA8888, ARGB8888, RGB888
|
||||
Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0),
|
||||
Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24),
|
||||
Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0),
|
||||
#endif
|
||||
// RGB565, XRGB1555, RGB555, RGBA4444, ARGB4444
|
||||
Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0),
|
||||
Graphics::PixelFormat(2, 5, 5, 5, 1, 10, 5, 0, 15),
|
||||
Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0),
|
||||
Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0),
|
||||
Graphics::PixelFormat(2, 4, 4, 4, 4, 8, 4, 0, 12)
|
||||
};
|
||||
const Graphics::PixelFormat BGRList[] = {
|
||||
#ifdef ENABLE_32BIT
|
||||
// ABGR8888, BGRA8888, BGR888
|
||||
Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24),
|
||||
Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0),
|
||||
Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0),
|
||||
#endif
|
||||
// BGR565, XBGR1555, BGR555, ABGR4444, BGRA4444
|
||||
Graphics::PixelFormat(2, 5, 6, 5, 0, 0, 5, 11, 0),
|
||||
Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15),
|
||||
Graphics::PixelFormat(2, 5, 5, 5, 0, 0, 5, 10, 0),
|
||||
Graphics::PixelFormat(2, 4, 4, 4, 4, 0, 4, 8, 12),
|
||||
Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0)
|
||||
};
|
||||
|
||||
// TODO: prioritize matching alpha masks
|
||||
Common::List<Graphics::PixelFormat> OSystem_SDL::getSupportedFormats() {
|
||||
static Common::List<Graphics::PixelFormat> list;
|
||||
static bool inited = false;
|
||||
|
||||
if (inited)
|
||||
return list;
|
||||
|
||||
bool BGR = false;
|
||||
int listLength = ARRAYSIZE(RGBList);
|
||||
|
||||
Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();
|
||||
if (_hwscreen) {
|
||||
// Get our currently set hardware format
|
||||
format = Graphics::PixelFormat(_hwscreen->format->BytesPerPixel,
|
||||
8 - _hwscreen->format->Rloss, 8 - _hwscreen->format->Gloss,
|
||||
8 - _hwscreen->format->Bloss, 8 - _hwscreen->format->Aloss,
|
||||
_hwscreen->format->Rshift, _hwscreen->format->Gshift,
|
||||
_hwscreen->format->Bshift, _hwscreen->format->Ashift);
|
||||
|
||||
// Workaround to MacOSX SDL not providing an accurate Aloss value.
|
||||
if (_hwscreen->format->Amask == 0)
|
||||
format.aLoss = 8;
|
||||
|
||||
// Push it first, as the prefered format.
|
||||
list.push_back(format);
|
||||
|
||||
if (format.bShift > format.rShift)
|
||||
BGR = true;
|
||||
|
||||
// Mark that we don't need to do this any more.
|
||||
inited = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < listLength; i++) {
|
||||
if (inited && (RGBList[i].bytesPerPixel > format.bytesPerPixel))
|
||||
continue;
|
||||
if (BGR) {
|
||||
if (BGRList[i] != format)
|
||||
list.push_back(BGRList[i]);
|
||||
list.push_back(RGBList[i]);
|
||||
} else {
|
||||
if (RGBList[i] != format)
|
||||
list.push_back(RGBList[i]);
|
||||
list.push_back(BGRList[i]);
|
||||
}
|
||||
}
|
||||
list.push_back(Graphics::PixelFormat::createFormatCLUT8());
|
||||
return list;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool OSystem_SDL::setGraphicsMode(int mode) {
|
||||
Common::StackLock lock(_graphicsMutex);
|
||||
|
||||
|
@ -340,9 +439,27 @@ int OSystem_SDL::getGraphicsMode() const {
|
|||
return _videoMode.mode;
|
||||
}
|
||||
|
||||
void OSystem_SDL::initSize(uint w, uint h) {
|
||||
void OSystem_SDL::initSize(uint w, uint h, const Graphics::PixelFormat *format) {
|
||||
assert(_transactionMode == kTransactionActive);
|
||||
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
//avoid redundant format changes
|
||||
Graphics::PixelFormat newFormat;
|
||||
if (!format)
|
||||
newFormat = Graphics::PixelFormat::createFormatCLUT8();
|
||||
else
|
||||
newFormat = *format;
|
||||
|
||||
assert(newFormat.bytesPerPixel > 0);
|
||||
|
||||
if (newFormat != _videoMode.format)
|
||||
{
|
||||
_videoMode.format = newFormat;
|
||||
_transactionDetails.formatChanged = true;
|
||||
_screenFormat = newFormat;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Avoid redundant res changes
|
||||
if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight)
|
||||
return;
|
||||
|
@ -426,9 +543,21 @@ bool OSystem_SDL::loadGFXMode() {
|
|||
//
|
||||
// Create the surface that contains the 8 bit game data
|
||||
//
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight,
|
||||
_screenFormat.bytesPerPixel << 3,
|
||||
((1 << _screenFormat.rBits()) - 1) << _screenFormat.rShift ,
|
||||
((1 << _screenFormat.gBits()) - 1) << _screenFormat.gShift ,
|
||||
((1 << _screenFormat.bBits()) - 1) << _screenFormat.bShift ,
|
||||
((1 << _screenFormat.aBits()) - 1) << _screenFormat.aShift );
|
||||
if (_screen == NULL)
|
||||
error("allocating _screen failed");
|
||||
|
||||
#else
|
||||
_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
|
||||
if (_screen == NULL)
|
||||
error("allocating _screen failed");
|
||||
#endif
|
||||
|
||||
//
|
||||
// Create the surface that contains the scaled graphics in 16 bit mode
|
||||
|
@ -571,8 +700,8 @@ bool OSystem_SDL::hotswapGFXMode() {
|
|||
// Keep around the old _screen & _overlayscreen so we can restore the screen data
|
||||
// after the mode switch.
|
||||
SDL_Surface *old_screen = _screen;
|
||||
SDL_Surface *old_overlayscreen = _overlayscreen;
|
||||
_screen = NULL;
|
||||
SDL_Surface *old_overlayscreen = _overlayscreen;
|
||||
_overlayscreen = NULL;
|
||||
|
||||
// Release the HW screen surface
|
||||
|
@ -878,8 +1007,19 @@ void OSystem_SDL::copyRectToScreen(const byte *src, int pitch, int x, int y, int
|
|||
if (SDL_LockSurface(_screen) == -1)
|
||||
error("SDL_LockSurface failed: %s", SDL_GetError());
|
||||
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth * _screenFormat.bytesPerPixel + x * _screenFormat.bytesPerPixel;
|
||||
if (_videoMode.screenWidth == w && pitch == w * _screenFormat.bytesPerPixel) {
|
||||
memcpy(dst, src, h*w*_screenFormat.bytesPerPixel);
|
||||
} else {
|
||||
do {
|
||||
memcpy(dst, src, w * _screenFormat.bytesPerPixel);
|
||||
src += pitch;
|
||||
dst += _videoMode.screenWidth * _screenFormat.bytesPerPixel;
|
||||
} while (--h);
|
||||
}
|
||||
#else
|
||||
byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
|
||||
|
||||
if (_videoMode.screenWidth == pitch && pitch == w) {
|
||||
memcpy(dst, src, h*w);
|
||||
} else {
|
||||
|
@ -889,6 +1029,7 @@ void OSystem_SDL::copyRectToScreen(const byte *src, int pitch, int x, int y, int
|
|||
dst += _videoMode.screenWidth;
|
||||
} while (--h);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Unlock the screen surface
|
||||
SDL_UnlockSurface(_screen);
|
||||
|
@ -912,7 +1053,11 @@ Graphics::Surface *OSystem_SDL::lockScreen() {
|
|||
_framebuffer.w = _screen->w;
|
||||
_framebuffer.h = _screen->h;
|
||||
_framebuffer.pitch = _screen->pitch;
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
_framebuffer.bytesPerPixel = _screenFormat.bytesPerPixel;
|
||||
#else
|
||||
_framebuffer.bytesPerPixel = 1;
|
||||
#endif
|
||||
|
||||
return &_framebuffer;
|
||||
}
|
||||
|
@ -1096,6 +1241,11 @@ int16 OSystem_SDL::getWidth() {
|
|||
void OSystem_SDL::setPalette(const byte *colors, uint start, uint num) {
|
||||
assert(colors);
|
||||
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
if (_screenFormat.bytesPerPixel > 1)
|
||||
return; //not using a paletted pixel format
|
||||
#endif
|
||||
|
||||
// Setting the palette before _screen is created is allowed - for now -
|
||||
// since we don't actually set the palette until the screen is updated.
|
||||
// But it could indicate a programming error, so let's warn about it.
|
||||
|
@ -1149,10 +1299,10 @@ void OSystem_SDL::setCursorPalette(const byte *colors, uint start, uint num) {
|
|||
}
|
||||
|
||||
_cursorPaletteDisabled = false;
|
||||
|
||||
blitCursor();
|
||||
}
|
||||
|
||||
|
||||
void OSystem_SDL::setShakePos(int shake_pos) {
|
||||
assert (_transactionMode == kTransactionNone);
|
||||
|
||||
|
@ -1357,7 +1507,17 @@ void OSystem_SDL::warpMouse(int x, int y) {
|
|||
}
|
||||
}
|
||||
|
||||
void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale) {
|
||||
void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
if (!format)
|
||||
_cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
|
||||
else if (format->bytesPerPixel <= _screenFormat.bytesPerPixel)
|
||||
_cursorFormat = *format;
|
||||
keycolor &= (1 << (_cursorFormat.bytesPerPixel << 3)) - 1;
|
||||
#else
|
||||
keycolor &= 0xFF;
|
||||
#endif
|
||||
|
||||
if (w == 0 || h == 0)
|
||||
return;
|
||||
|
||||
|
@ -1391,16 +1551,26 @@ void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x,
|
|||
}
|
||||
|
||||
free(_mouseData);
|
||||
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
_mouseData = (byte *)malloc(w * h * _cursorFormat.bytesPerPixel);
|
||||
memcpy(_mouseData, buf, w * h * _cursorFormat.bytesPerPixel);
|
||||
#else
|
||||
_mouseData = (byte *)malloc(w * h);
|
||||
memcpy(_mouseData, buf, w * h);
|
||||
#endif
|
||||
|
||||
blitCursor();
|
||||
}
|
||||
|
||||
void OSystem_SDL::blitCursor() {
|
||||
byte *dstPtr;
|
||||
const byte *srcPtr = _mouseData;
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
uint32 color;
|
||||
uint32 colormask = (1 << (_cursorFormat.bytesPerPixel << 3)) - 1;
|
||||
#else
|
||||
byte color;
|
||||
#endif
|
||||
int w, h, i, j;
|
||||
|
||||
if (!_mouseOrigSurface || !_mouseData)
|
||||
|
@ -1434,13 +1604,29 @@ void OSystem_SDL::blitCursor() {
|
|||
|
||||
for (i = 0; i < h; i++) {
|
||||
for (j = 0; j < w; j++) {
|
||||
color = *srcPtr;
|
||||
if (color != _mouseKeyColor) { // transparent, don't draw
|
||||
*(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format,
|
||||
palette[color].r, palette[color].g, palette[color].b);
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
if (_cursorFormat.bytesPerPixel > 1) {
|
||||
color = (*(uint32 *) srcPtr) & colormask;
|
||||
if (color != _mouseKeyColor) { // transparent, don't draw
|
||||
uint8 r,g,b;
|
||||
_cursorFormat.colorToRGB(color,r,g,b);
|
||||
*(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format,
|
||||
r, g, b);
|
||||
}
|
||||
dstPtr += 2;
|
||||
srcPtr += _cursorFormat.bytesPerPixel;
|
||||
} else {
|
||||
#endif
|
||||
color = *srcPtr;
|
||||
if (color != _mouseKeyColor) { // transparent, don't draw
|
||||
*(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format,
|
||||
palette[color].r, palette[color].g, palette[color].b);
|
||||
}
|
||||
dstPtr += 2;
|
||||
srcPtr++;
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
}
|
||||
dstPtr += 2;
|
||||
srcPtr++;
|
||||
#endif
|
||||
}
|
||||
dstPtr += _mouseOrigSurface->pitch - w * 2;
|
||||
}
|
||||
|
|
|
@ -222,6 +222,10 @@ OSystem_SDL::OSystem_SDL()
|
|||
_osdSurface(0), _osdAlpha(SDL_ALPHA_TRANSPARENT), _osdFadeStartTime(0),
|
||||
#endif
|
||||
_hwscreen(0), _screen(0), _tmpscreen(0),
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
_screenFormat(Graphics::PixelFormat::createFormatCLUT8()),
|
||||
_cursorFormat(Graphics::PixelFormat::createFormatCLUT8()),
|
||||
#endif
|
||||
_overlayVisible(false),
|
||||
_overlayscreen(0), _tmpscreen2(0),
|
||||
_samplesPerSec(0),
|
||||
|
|
|
@ -93,9 +93,17 @@ public:
|
|||
void beginGFXTransaction(void);
|
||||
TransactionError endGFXTransaction(void);
|
||||
|
||||
// Set the size of the video bitmap.
|
||||
// Typically, 320x200
|
||||
virtual void initSize(uint w, uint h); // overloaded by CE backend
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
// Game screen
|
||||
virtual Graphics::PixelFormat getScreenFormat() const { return _screenFormat; }
|
||||
|
||||
// Highest supported
|
||||
virtual Common::List<Graphics::PixelFormat> getSupportedFormats();
|
||||
#endif
|
||||
|
||||
// Set the size and format of the video bitmap.
|
||||
// Typically, 320x200 CLUT8
|
||||
virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format); // overloaded by CE backend
|
||||
|
||||
virtual int getScreenChangeID() const { return _screenChangeCount; }
|
||||
|
||||
|
@ -124,7 +132,7 @@ public:
|
|||
virtual void warpMouse(int x, int y); // overloaded by CE backend (FIXME)
|
||||
|
||||
// Set the bitmap that's used when drawing the cursor.
|
||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale); // overloaded by CE backend (FIXME)
|
||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend (FIXME)
|
||||
|
||||
// Set colors of cursor palette
|
||||
void setCursorPalette(const byte *colors, uint start, uint num);
|
||||
|
@ -186,6 +194,7 @@ public:
|
|||
|
||||
// Overlay
|
||||
virtual Graphics::PixelFormat getOverlayFormat() const { return _overlayFormat; }
|
||||
|
||||
virtual void showOverlay();
|
||||
virtual void hideOverlay();
|
||||
virtual void clearOverlay();
|
||||
|
@ -239,6 +248,10 @@ protected:
|
|||
|
||||
// unseen game screen
|
||||
SDL_Surface *_screen;
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
Graphics::PixelFormat _screenFormat;
|
||||
Graphics::PixelFormat _cursorFormat;
|
||||
#endif
|
||||
|
||||
// temporary screen (for scalers)
|
||||
SDL_Surface *_tmpscreen;
|
||||
|
@ -272,6 +285,9 @@ protected:
|
|||
bool needHotswap;
|
||||
bool needUpdatescreen;
|
||||
bool normal1xScaler;
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
bool formatChanged;
|
||||
#endif
|
||||
};
|
||||
TransactionDetails _transactionDetails;
|
||||
|
||||
|
@ -288,6 +304,9 @@ protected:
|
|||
int screenWidth, screenHeight;
|
||||
int overlayWidth, overlayHeight;
|
||||
int hardwareWidth, hardwareHeight;
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
Graphics::PixelFormat format;
|
||||
#endif
|
||||
};
|
||||
VideoState _videoMode, _oldVideoMode;
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ enum Error {
|
|||
kInvalidPathError, //!< Engine initialization: Invalid game path was passed
|
||||
kNoGameDataFoundError, //!< Engine initialization: No game data was found in the specified location
|
||||
kUnsupportedGameidError, //!< Engine initialization: Gameid not supported by this (Meta)Engine
|
||||
kUnsupportedColorMode, //!< Engine initialization: Engine does not support backend's color mode
|
||||
|
||||
|
||||
kReadPermissionDenied, //!< Unable to read data due to missing read permission
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
#include "common/rect.h"
|
||||
|
||||
#include "graphics/pixelformat.h"
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
#include "graphics/conversion.h"
|
||||
#endif
|
||||
|
||||
namespace Audio {
|
||||
class Mixer;
|
||||
|
@ -347,8 +350,52 @@ public:
|
|||
*/
|
||||
virtual int getGraphicsMode() const = 0;
|
||||
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
/**
|
||||
* Set the size of the virtual screen. Typical sizes include:
|
||||
* Determine the pixel format currently in use for screen rendering.
|
||||
* @return the active screen pixel format.
|
||||
* @see Graphics::PixelFormat
|
||||
*/
|
||||
virtual Graphics::PixelFormat getScreenFormat() const = 0;
|
||||
|
||||
/**
|
||||
* Returns a list of all pixel formats supported by the backend.
|
||||
* The first item in the list must be directly supported by hardware,
|
||||
* and provide the largest color space of those formats with direct
|
||||
* hardware support. It is also strongly recommended that remaining
|
||||
* formats should be placed in order of descending preference for the
|
||||
* backend to use.
|
||||
*
|
||||
* EG: a backend that supports 32-bit ABGR and 16-bit 555 BGR in hardware
|
||||
* and provides conversion from equivalent RGB(A) modes should order its list
|
||||
* 1) Graphics::PixelFormat(4, 0, 0, 0, 0, 0, 8, 16, 24)
|
||||
* 2) Graphics::PixelFormat(2, 3, 3, 3, 8, 0, 5, 10, 0)
|
||||
* 3) Graphics::PixelFormat(4, 0, 0, 0, 0, 24, 16, 8, 0)
|
||||
* 4) Graphics::PixelFormat(2, 3, 3, 3, 8, 10, 5, 0, 0)
|
||||
* 5) Graphics::PixelFormat::createFormatCLUT8()
|
||||
*
|
||||
* @see Graphics::PixelFormat
|
||||
*
|
||||
* @note Backends supporting RGB color should accept game data in RGB color
|
||||
* order, even if hardware uses BGR or some other color order.
|
||||
*
|
||||
* @see convertScreenRect
|
||||
*/
|
||||
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() = 0;
|
||||
#else
|
||||
inline Graphics::PixelFormat getScreenFormat() const {
|
||||
return Graphics::PixelFormat::createFormatCLUT8();
|
||||
};
|
||||
|
||||
inline Common::List<Graphics::PixelFormat> getSupportedFormats() const {
|
||||
Common::List<Graphics::PixelFormat> list;
|
||||
list.push_back(Graphics::PixelFormat::createFormatCLUT8());
|
||||
return list;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set the size and color format of the virtual screen. Typical sizes include:
|
||||
* - 320x200 (e.g. for most SCUMM games, and Simon)
|
||||
* - 320x240 (e.g. for FM-TOWN SCUMM games)
|
||||
* - 640x480 (e.g. for Curse of Monkey Island)
|
||||
|
@ -359,10 +406,21 @@ public:
|
|||
* GraphicsMode); stretch the data to perform aspect ratio correction;
|
||||
* or shrink it to fit on small screens (in cell phones).
|
||||
*
|
||||
* Typical formats include:
|
||||
* CLUT8 (e.g. 256 color, for most games)
|
||||
* RGB555 (e.g. 16-bit color, for later SCUMM HE games)
|
||||
* RGB565 (e.g. 16-bit color, for Urban Runner)
|
||||
*
|
||||
* This is the pixel format for which the client code generates data;
|
||||
* this is not necessarily equal to the hardware pixel format. For example,
|
||||
* a backend may perform color lookup of 8-bit graphics before pushing
|
||||
* a screen to hardware, or correct the ARGB color order via convertScreenRect.
|
||||
*
|
||||
* @param width the new virtual screen width
|
||||
* @param height the new virtual screen height
|
||||
* @param format the new virtual screen pixel format
|
||||
*/
|
||||
virtual void initSize(uint width, uint height) = 0;
|
||||
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) = 0;
|
||||
|
||||
/**
|
||||
* Return an int value which is changed whenever any screen
|
||||
|
@ -411,7 +469,8 @@ public:
|
|||
kTransactionAspectRatioFailed = (1 << 0), /**< Failed switching aspect ratio correction mode */
|
||||
kTransactionFullscreenFailed = (1 << 1), /**< Failed switching fullscreen mode */
|
||||
kTransactionModeSwitchFailed = (1 << 2), /**< Failed switching the GFX graphics mode (setGraphicsMode) */
|
||||
kTransactionSizeChangeFailed = (1 << 3) /**< Failed switching the screen dimensions (initSize) */
|
||||
kTransactionSizeChangeFailed = (1 << 3), /**< Failed switching the screen dimensions (initSize) */
|
||||
kTransactionFormatNotSupported = (1 << 4) /**< Failed setting the color format */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -705,8 +764,9 @@ public:
|
|||
* @param hotspotY vertical offset from the top side to the hotspot
|
||||
* @param keycolor transparency color index
|
||||
* @param cursorTargetScale scale factor which cursor is designed for
|
||||
* @param format pointer to the pixel format which cursor graphic uses
|
||||
*/
|
||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1) = 0;
|
||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 0xFFFFFFFF, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) = 0;
|
||||
|
||||
/**
|
||||
* Replace the specified range of cursor the palette with new colors.
|
||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -110,7 +110,7 @@ _alsa=auto
|
|||
_zlib=auto
|
||||
_mpeg2=no
|
||||
_fluidsynth=auto
|
||||
_readline=auto
|
||||
_16bit=yes_readline=auto
|
||||
# Default option behaviour yes/no
|
||||
_text_console=no
|
||||
_mt32emu=yes
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
DisableSpecificWarnings="4068;4100;4103;4121;4127;4189;4201;4221;4244;4250;4310;4351;4355;4510;4511;4512;4610;4701;4702;4706;4800;4996"
|
||||
AdditionalIncludeDirectories="../..;../../engines"
|
||||
PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;ENABLE_AGI;ENABLE_AGOS;ENABLE_AGOS2;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE"
|
||||
PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;ENABLE_AGI;ENABLE_AGOS;ENABLE_AGOS2;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE;;ENABLE_RGB_COLOR"
|
||||
ExceptionHandling="0"
|
||||
RuntimeTypeInfo="false"
|
||||
WarningLevel="4"
|
||||
|
|
|
@ -1,48 +1,244 @@
|
|||
<?xml version="1.0" encoding="windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8,00"
|
||||
Version="8.00"
|
||||
Name="groovie"
|
||||
ProjectGUID="{2C1EA540-0B09-11DD-BD00-000000000000}"
|
||||
RootNamespace="groovie"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform Name="Win32" />
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration Name="Debug|Win32" ConfigurationType="4" InheritedPropertySheets=".\ScummVM_Debug.vsprops" />
|
||||
<Configuration Name="Release|Win32" ConfigurationType="4" InheritedPropertySheets=".\ScummVM_Release.vsprops" />
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets=".\ScummVM_Debug.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="GROOVIE_EXPERIMENTAL"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets=".\ScummVM_Release.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File RelativePath="..\..\engines\groovie\cell.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\cell.h" />
|
||||
<File RelativePath="..\..\engines\groovie\cursor.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\cursor.h" />
|
||||
<File RelativePath="..\..\engines\groovie\debug.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\debug.h" />
|
||||
<File RelativePath="..\..\engines\groovie\detection.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\font.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\font.h" />
|
||||
<File RelativePath="..\..\engines\groovie\graphics.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\graphics.h" />
|
||||
<File RelativePath="..\..\engines\groovie\groovie.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\groovie.h" />
|
||||
<File RelativePath="..\..\engines\groovie\lzss.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\lzss.h" />
|
||||
<File RelativePath="..\..\engines\groovie\music.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\music.h" />
|
||||
<File RelativePath="..\..\engines\groovie\player.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\player.h" />
|
||||
<File RelativePath="..\..\engines\groovie\resource.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\resource.h" />
|
||||
<File RelativePath="..\..\engines\groovie\roq.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\roq.h" />
|
||||
<File RelativePath="..\..\engines\groovie\saveload.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\saveload.h" />
|
||||
<File RelativePath="..\..\engines\groovie\script.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\script.h" />
|
||||
<File RelativePath="..\..\engines\groovie\vdx.cpp" />
|
||||
<File RelativePath="..\..\engines\groovie\vdx.h" />
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\cell.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\cell.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\cursor.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\cursor.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\debug.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\debug.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\detection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\font.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\font.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\graphics.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\graphics.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\groovie.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\groovie.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\lzss.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\lzss.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\music.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\music.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\player.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\player.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\resource.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\resource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\roq.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\roq.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\saveload.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\saveload.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\script.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\script.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\vdx.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\groovie\vdx.h"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8,00"
|
||||
Version="8.00"
|
||||
Name="sci"
|
||||
ProjectGUID="{53F17B2B-0412-4EC3-A999-ED0537BB5223}"
|
||||
RootNamespace="sci"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8,00"
|
||||
Version="8.00"
|
||||
Name="scumm"
|
||||
ProjectGUID="{B6AFD548-63D2-40CD-A652-E87095AFCBAF}"
|
||||
RootNamespace="scumm"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8,00"
|
||||
Version="8.00"
|
||||
Name="scummvm"
|
||||
ProjectGUID="{8434CB15-D08F-427D-9E6D-581AE5B28440}"
|
||||
RootNamespace="scummvm"
|
||||
|
@ -47,6 +47,9 @@
|
|||
<File RelativePath="..\..\common\debug.h" />
|
||||
<File RelativePath="..\..\common\endian.h" />
|
||||
<File RelativePath="..\..\common\error.h" />
|
||||
<File RelativePath="..\..\common\EventDispatcher.cpp" />
|
||||
<File RelativePath="..\..\common\EventRecorder.cpp" />
|
||||
<File RelativePath="..\..\common\EventRecorder.h" />
|
||||
<File RelativePath="..\..\common\events.h" />
|
||||
<File RelativePath="..\..\common\file.cpp" />
|
||||
<File RelativePath="..\..\common\file.h" />
|
||||
|
@ -347,6 +350,8 @@
|
|||
</Filter>
|
||||
<Filter Name="graphics">
|
||||
<File RelativePath="..\..\graphics\colormasks.h" />
|
||||
<File RelativePath="..\..\graphics\conversion.cpp" />
|
||||
<File RelativePath="..\..\graphics\conversion.h" />
|
||||
<File RelativePath="..\..\graphics\cursorman.cpp" />
|
||||
<File RelativePath="..\..\graphics\cursorman.h" />
|
||||
<File RelativePath="..\..\graphics\dither.cpp" />
|
||||
|
@ -357,6 +362,8 @@
|
|||
<File RelativePath="..\..\graphics\fontman.h" />
|
||||
<File RelativePath="..\..\graphics\iff.cpp" />
|
||||
<File RelativePath="..\..\graphics\iff.h" />
|
||||
<File RelativePath="..\..\graphics\jpeg.cpp" />
|
||||
<File RelativePath="..\..\graphics\jpeg.h" />
|
||||
<File RelativePath="..\..\graphics\imagedec.cpp" />
|
||||
<File RelativePath="..\..\graphics\imagedec.h" />
|
||||
<File RelativePath="..\..\graphics\pixelformat.h" />
|
||||
|
|
|
@ -36,7 +36,8 @@ namespace Cine {
|
|||
#define kLowPalNumBytes ((kLowPalNumColors) * (kLowPalBytesPerColor))
|
||||
|
||||
/*! \brief Low resolution (9-bit) color format used in Cine's 16-color modes. */
|
||||
static const Graphics::PixelFormat kLowPalFormat = {kLowPalBytesPerColor, 5, 5, 5, 8, 8, 4, 0, 0};
|
||||
static const Graphics::PixelFormat kLowPalFormat(kLowPalBytesPerColor, 5, 5, 5, 8, 8, 4, 0, 0);
|
||||
|
||||
|
||||
// Constants related to kHighPalFormat
|
||||
#define kHighPalBytesPerColor 3
|
||||
|
@ -44,10 +45,10 @@ static const Graphics::PixelFormat kLowPalFormat = {kLowPalBytesPerColor, 5, 5,
|
|||
#define kHighPalNumBytes ((kHighPalNumColors) * (kHighPalBytesPerColor))
|
||||
|
||||
/*! \brief High resolution (24-bit) color format used in Cine's 256-color modes. */
|
||||
static const Graphics::PixelFormat kHighPalFormat = {kHighPalBytesPerColor, 0, 0, 0, 8, 0, 8, 16, 0};
|
||||
static const Graphics::PixelFormat kHighPalFormat(kHighPalBytesPerColor, 0, 0, 0, 8, 0, 8, 16, 0);
|
||||
|
||||
/*! \brief The color format used by OSystem's setPalette-function. */
|
||||
static const Graphics::PixelFormat kSystemPalFormat = {4, 0, 0, 0, 8, 0, 8, 16, 0};
|
||||
static const Graphics::PixelFormat kSystemPalFormat(4, 0, 0, 0, 8, 0, 8, 16, 0);
|
||||
|
||||
/*! \brief Endian types. Used at least by Palette class's load and save functions.
|
||||
* TODO: Move somewhere more general as this is definitely not Cine-engine specific
|
||||
|
|
|
@ -125,11 +125,21 @@ void initCommonGFX(bool defaultTo1XScaler) {
|
|||
g_system->setFeatureState(OSystem::kFeatureFullscreenMode, ConfMan.getBool("fullscreen"));
|
||||
}
|
||||
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler) {
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler, const Graphics::PixelFormat *format) {
|
||||
|
||||
g_system->beginGFXTransaction();
|
||||
|
||||
initCommonGFX(defaultTo1xScaler);
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
if (format)
|
||||
g_system->initSize(width, height, format);
|
||||
else {
|
||||
Graphics::PixelFormat Format = g_system->getSupportedFormats().front();
|
||||
g_system->initSize(width, height, &Format);
|
||||
}
|
||||
#else
|
||||
g_system->initSize(width, height);
|
||||
#endif
|
||||
|
||||
OSystem::TransactionError gfxError = g_system->endGFXTransaction();
|
||||
|
||||
|
@ -150,6 +160,15 @@ void initGraphics(int width, int height, bool defaultTo1xScaler) {
|
|||
}
|
||||
|
||||
// Just show warnings then these occur:
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
if (gfxError & OSystem::kTransactionFormatNotSupported) {
|
||||
Common::String message = "Could not initialize color format.";
|
||||
|
||||
GUI::MessageDialog dialog(message);
|
||||
dialog.runModal();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gfxError & OSystem::kTransactionModeSwitchFailed) {
|
||||
Common::String message = "Could not switch to video mode: '";
|
||||
message += ConfMan.get("gfx_mode");
|
||||
|
@ -169,6 +188,14 @@ void initGraphics(int width, int height, bool defaultTo1xScaler) {
|
|||
dialog.runModal();
|
||||
}
|
||||
}
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler, const Common::List<Graphics::PixelFormat> &formatList) {
|
||||
Graphics::PixelFormat format = Graphics::findCompatibleFormat(g_system->getSupportedFormats(),formatList);
|
||||
initGraphics(width,height,defaultTo1xScaler,&format);
|
||||
}
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler) {
|
||||
Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();
|
||||
initGraphics(width,height,defaultTo1xScaler,&format);
|
||||
}
|
||||
|
||||
void GUIErrorMessage(const Common::String msg) {
|
||||
g_system->setWindowCaption("Error");
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "common/error.h"
|
||||
#include "common/fs.h"
|
||||
#include "common/str.h"
|
||||
#include "graphics/pixelformat.h"
|
||||
|
||||
class OSystem;
|
||||
|
||||
|
@ -58,8 +59,14 @@ void initCommonGFX(bool defaultTo1XScaler);
|
|||
*
|
||||
* Errors out when backend is not able to switch to the specified
|
||||
* mode.
|
||||
*
|
||||
* Defaults to 256 color paletted mode if no graphics format is provided.
|
||||
* Uses the backend's preferred format if graphics format pointer is NULL.
|
||||
* Finds the best compatible format if a list of graphics formats is provided.
|
||||
*/
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler);
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler, const Graphics::PixelFormat *format);
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler, const Common::List<Graphics::PixelFormat> &formatList);
|
||||
|
||||
/**
|
||||
* Initializes graphics and shows error message.
|
||||
|
|
|
@ -27,18 +27,19 @@
|
|||
#include "common/system.h"
|
||||
#include "graphics/cursorman.h"
|
||||
#include "graphics/primitives.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
#include "sci/sci.h"
|
||||
#include "sci/gfx/gfx_driver.h"
|
||||
#include "sci/gfx/gfx_tools.h"
|
||||
|
||||
|
||||
namespace Sci {
|
||||
|
||||
GfxDriver::GfxDriver(int xfact, int yfact, int bytespp) {
|
||||
GfxDriver::GfxDriver(int xfact, int yfact, Graphics::PixelFormat format) {
|
||||
int i;
|
||||
|
||||
Graphics::PixelFormat format = { bytespp, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
_mode = gfx_new_mode(xfact, yfact, format, new Palette(256), 0);
|
||||
_mode = gfx_new_mode(xfact, yfact, format, format.bytesPerPixel == 1 ? new Palette(256) : 0, 0);
|
||||
_mode->xsize = xfact * 320;
|
||||
_mode->ysize = yfact * 200;
|
||||
|
||||
|
@ -51,14 +52,15 @@ GfxDriver::GfxDriver(int xfact, int yfact, int bytespp) {
|
|||
// create the visual buffers
|
||||
for (i = 0; i < 2; i++) {
|
||||
_visual[i] = NULL;
|
||||
_visual[i] = new byte[_mode->xsize * _mode->ysize];
|
||||
_visual[i] = new byte[_mode->xsize * _mode->ysize * _mode->bytespp];
|
||||
if (!_visual[i]) {
|
||||
error("Out of memory: Could not allocate visual buffers! (%dx%d)\n", _mode->xsize, _mode->ysize);
|
||||
}
|
||||
memset(_visual[i], 0, _mode->xsize * _mode->ysize);
|
||||
memset(_visual[i], 0, _mode->xsize * _mode->ysize * _mode->bytespp);
|
||||
}
|
||||
|
||||
_mode->palette->name = "global";
|
||||
if (_mode->palette)
|
||||
_mode->palette->name = "global";
|
||||
}
|
||||
|
||||
GfxDriver::~GfxDriver() {
|
||||
|
@ -77,10 +79,12 @@ GfxDriver::~GfxDriver() {
|
|||
|
||||
// Drawing operations
|
||||
|
||||
template<int COPY_BYTES, typename SIZETYPE, int EXTRA_BYTE_OFFSET>
|
||||
static void drawProc(int x, int y, int c, void *data) {
|
||||
GfxDriver *drv = (GfxDriver *)data;
|
||||
byte *p = drv->getVisual0();
|
||||
p[y * 320* drv->getMode()->xfact + x] = c;
|
||||
SIZETYPE col = c << (EXTRA_BYTE_OFFSET * 8);
|
||||
memcpy(p + (y * 320* drv->getMode()->xfact + x) * COPY_BYTES, &col, COPY_BYTES);
|
||||
}
|
||||
|
||||
int GfxDriver::drawLine(Common::Point start, Common::Point end, gfx_color_t color,
|
||||
|
@ -91,6 +95,28 @@ int GfxDriver::drawLine(Common::Point start, Common::Point end, gfx_color_t colo
|
|||
int xsize = _mode->xsize;
|
||||
int ysize = _mode->ysize;
|
||||
|
||||
void (*modeDrawProc)(int,int,int,void*);
|
||||
switch (_mode->bytespp) {
|
||||
case 1:
|
||||
modeDrawProc = drawProc<1, uint8, 0>;
|
||||
break;
|
||||
case 2:
|
||||
modeDrawProc = drawProc<2, uint16, 0>;
|
||||
break;
|
||||
case 3:
|
||||
#ifdef SCUMM_BIG_ENDIAN
|
||||
modeDrawProc = drawProc<3, uint32, 1>;
|
||||
#else
|
||||
modeDrawProc = drawProc<3, uint32, 0>;
|
||||
#endif
|
||||
break;
|
||||
case 4:
|
||||
modeDrawProc = drawProc<4, uint32, 0>;
|
||||
break;
|
||||
default:
|
||||
error("Invalid mode->bytespp=%d", _mode->bytespp);
|
||||
}
|
||||
|
||||
if (color.mask & GFX_MASK_VISUAL) {
|
||||
Common::Point nstart, nend;
|
||||
|
||||
|
@ -102,7 +128,7 @@ int GfxDriver::drawLine(Common::Point start, Common::Point end, gfx_color_t colo
|
|||
nend.x = CLIP<int16>(end.x + xc, 0, xsize - 1);
|
||||
nend.y = CLIP<int16>(end.y + yc, 0, ysize - 1);
|
||||
|
||||
Graphics::drawLine(nstart.x, nstart.y, nend.x, nend.y, scolor, drawProc, this);
|
||||
Graphics::drawLine(nstart.x, nstart.y, nend.x, nend.y, scolor, modeDrawProc, this);
|
||||
|
||||
if (color.mask & GFX_MASK_PRIORITY) {
|
||||
gfx_draw_line_pixmap_i(_priority[0], nstart, nend, color.priority);
|
||||
|
@ -118,7 +144,8 @@ int GfxDriver::drawFilledRect(rect_t rect, gfx_color_t color1, gfx_color_t color
|
|||
gfx_rectangle_fill_t shade_mode) {
|
||||
if (color1.mask & GFX_MASK_VISUAL) {
|
||||
for (int i = rect.y; i < rect.y + rect.height; i++) {
|
||||
memset(_visual[0] + i * _mode->xsize + rect.x, color1.visual.parent_index, rect.width);
|
||||
memset(_visual[0] + (i * _mode->xsize + rect.x) * _mode->bytespp,
|
||||
color1.visual.parent_index, rect.width * _mode->bytespp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,8 +165,10 @@ int GfxDriver::drawPixmap(gfx_pixmap_t *pxm, int priority, rect_t src, rect_t de
|
|||
return GFX_ERROR;
|
||||
}
|
||||
|
||||
gfx_crossblit_pixmap(_mode, pxm, priority, src, dest, _visual[bufnr], _mode->xsize,
|
||||
_priority[bufnr]->index_data, _priority[bufnr]->index_width, 1, 0);
|
||||
gfx_crossblit_pixmap(_mode, pxm, priority, src, dest, _visual[bufnr],
|
||||
_mode->xsize * _mode->bytespp,
|
||||
_priority[bufnr]->index_data,
|
||||
_priority[bufnr]->index_width, 1, 0);
|
||||
|
||||
return GFX_OK;
|
||||
}
|
||||
|
@ -161,7 +190,9 @@ int GfxDriver::grabPixmap(rect_t src, gfx_pixmap_t *pxm, gfx_map_mask_t map) {
|
|||
pxm->width = src.width;
|
||||
pxm->height = src.height;
|
||||
for (int i = 0; i < src.height; i++) {
|
||||
memcpy(pxm->data + i * src.width, _visual[0] + (i + src.y) * _mode->xsize + src.x, src.width);
|
||||
memcpy(pxm->data + i * src.width * _mode->bytespp,
|
||||
_visual[0] + _mode->bytespp * ((i + src.y) * _mode->xsize + src.x),
|
||||
src.width * _mode->bytespp);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -193,17 +224,18 @@ int GfxDriver::update(rect_t src, Common::Point dest, gfx_buffer_t buffer) {
|
|||
switch (buffer) {
|
||||
case GFX_BUFFER_BACK:
|
||||
for (int i = 0; i < src.height; i++) {
|
||||
memcpy(_visual[0] + (dest.y + i) * _mode->xsize + dest.x,
|
||||
_visual[1] + (src.y + i) * _mode->xsize + src.x, src.width);
|
||||
memcpy(_visual[0] + _mode->bytespp * ( (dest.y + i) * _mode->xsize + dest.x),
|
||||
_visual[1] + _mode->bytespp * ( (src.y + i) * _mode->xsize + src.x), src.width * _mode->bytespp );
|
||||
}
|
||||
|
||||
if ((src.x == dest.x) && (src.y == dest.y))
|
||||
gfx_copy_pixmap_box_i(_priority[0], _priority[1], src);
|
||||
break;
|
||||
case GFX_BUFFER_FRONT:
|
||||
g_system->copyRectToScreen(_visual[0] + src.x + src.y * _mode->xsize, _mode->xsize, dest.x, dest.y, src.width, src.height);
|
||||
case GFX_BUFFER_FRONT: {
|
||||
g_system->copyRectToScreen(_visual[0] + _mode->bytespp * (src.x + src.y * _mode->xsize), _mode->xsize * _mode->bytespp, dest.x, dest.y, src.width, src.height);
|
||||
g_system->updateScreen();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
error("Invalid buffer %d in update", buffer);
|
||||
return GFX_ERROR;
|
||||
|
@ -213,7 +245,7 @@ int GfxDriver::update(rect_t src, Common::Point dest, gfx_buffer_t buffer) {
|
|||
}
|
||||
|
||||
int GfxDriver::setStaticBuffer(gfx_pixmap_t *pic, gfx_pixmap_t *priority) {
|
||||
memcpy(_visual[1], pic->data, _mode->xsize * _mode->ysize);
|
||||
memcpy(_visual[1], pic->data, _mode->xsize * _mode->ysize * _mode->bytespp);
|
||||
gfx_copy_pixmap_box_i(_priority[1], priority, gfx_rect(0, 0, _mode->xsize, _mode->ysize));
|
||||
|
||||
return GFX_OK;
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "sci/gfx/gfx_system.h"
|
||||
#include "sci/uinput.h"
|
||||
|
||||
#include "graphics/pixelformat.h"
|
||||
|
||||
namespace Sci {
|
||||
|
||||
enum gfx_buffer_t {
|
||||
|
@ -85,7 +87,7 @@ public:
|
|||
* not be set, or GFX_FATAL if the graphics target
|
||||
* is unuseable.
|
||||
*/
|
||||
GfxDriver(int xfact, int yfact, int bytespp);
|
||||
GfxDriver(int xfact, int yfact, Graphics::PixelFormat mode);
|
||||
|
||||
/**
|
||||
* Uninitializes the current graphics mode.
|
||||
|
|
|
@ -70,14 +70,11 @@ void _gfx_xlate_pixmap_unfiltered(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale
|
|||
// Calculate all colors
|
||||
for (i = 0; i < pxm->colors_nr(); i++) {
|
||||
int col;
|
||||
|
||||
const PaletteEntry& color = pxm->palette->getColor(i);
|
||||
if (mode->palette)
|
||||
col = color.parent_index;
|
||||
else {
|
||||
col = mode->red_mask & ((EXTEND_COLOR(color.r)) >> mode->red_shift);
|
||||
col |= mode->green_mask & ((EXTEND_COLOR(color.g)) >> mode->green_shift);
|
||||
col |= mode->blue_mask & ((EXTEND_COLOR(color.b)) >> mode->blue_shift);
|
||||
col = mode->format.ARGBToColor(0, color.r, color.g, color.b);
|
||||
col |= alpha_ormask;
|
||||
}
|
||||
result_colors[i] = col;
|
||||
|
|
|
@ -269,7 +269,8 @@ void GfxResManager::setStaticPalette(Palette *newPalette)
|
|||
_staticPalette = newPalette;
|
||||
_staticPalette->name = "static palette";
|
||||
|
||||
_staticPalette->mergeInto(_driver->getMode()->palette);
|
||||
if (_driver->getMode()->palette)
|
||||
_staticPalette->mergeInto(_driver->getMode()->palette);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -320,7 +321,8 @@ gfx_mode_t mode_1x1_color_index = { /* Fake 1x1 mode */
|
|||
/* palette */ NULL,
|
||||
|
||||
/* color masks */ 0, 0, 0, 0,
|
||||
/* color shifts */ 0, 0, 0, 0
|
||||
/* color shifts */ 0, 0, 0, 0,
|
||||
Graphics::PixelFormat()
|
||||
};
|
||||
|
||||
gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_palette, bool scaled) {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "common/rect.h"
|
||||
#include "sci/tools.h"
|
||||
#include "sci/gfx/palette.h"
|
||||
#include "graphics/pixelformat.h"
|
||||
|
||||
namespace Sci {
|
||||
|
||||
|
@ -74,8 +75,10 @@ struct gfx_mode_t {
|
|||
*/
|
||||
Palette *palette;
|
||||
|
||||
// TODO: remove those
|
||||
uint32 red_mask, green_mask, blue_mask, alpha_mask;
|
||||
short red_shift, green_shift, blue_shift, alpha_shift;
|
||||
Graphics::PixelFormat format;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ gfx_mode_t *gfx_new_mode(int xfact, int yfact, const Graphics::PixelFormat &form
|
|||
mode->xfact = xfact;
|
||||
mode->yfact = yfact;
|
||||
mode->bytespp = format.bytesPerPixel;
|
||||
mode->format = format;
|
||||
|
||||
// FIXME: I am not sure whether the following assignments are quite right.
|
||||
// The only code using these are the built-in scalers of the SCI engine.
|
||||
|
@ -60,10 +61,10 @@ gfx_mode_t *gfx_new_mode(int xfact, int yfact, const Graphics::PixelFormat &form
|
|||
mode->green_mask = format.ARGBToColor(0, 0, 0xFF, 0);
|
||||
mode->blue_mask = format.ARGBToColor(0, 0, 0, 0xFF);
|
||||
mode->alpha_mask = format.ARGBToColor(0xFF, 0, 0, 0);
|
||||
mode->red_shift = format.rLoss;
|
||||
mode->green_shift = format.gLoss;
|
||||
mode->blue_shift = format.bLoss;
|
||||
mode->alpha_shift = format.aLoss;
|
||||
mode->red_shift = format.rShift;
|
||||
mode->green_shift = format.gShift;
|
||||
mode->blue_shift = format.bShift;
|
||||
mode->alpha_shift = format.aShift;
|
||||
} else {
|
||||
mode->red_mask = mode->green_mask = mode->blue_mask = 0;
|
||||
mode->alpha_mask = 0;
|
||||
|
|
|
@ -404,8 +404,9 @@ static void init_aux_pixmap(gfx_pixmap_t **pixmap) {
|
|||
(*pixmap)->palette = new Palette(default_colors, DEFAULT_COLORS_NR);
|
||||
}
|
||||
|
||||
int gfxop_init(int version, GfxState *state, gfx_options_t *options, ResourceManager *resManager,
|
||||
int xfact, int yfact, gfx_color_mode_t bpp) {
|
||||
int gfxop_init(int version, GfxState *state,
|
||||
gfx_options_t *options, ResourceManager *resManager,
|
||||
Graphics::PixelFormat mode, int xfact, int yfact) {
|
||||
//int color_depth = bpp ? bpp : 1;
|
||||
//int initialized = 0;
|
||||
|
||||
|
@ -421,7 +422,7 @@ int gfxop_init(int version, GfxState *state, gfx_options_t *options, ResourceMan
|
|||
state->pic_port_bounds = gfx_rect(0, 10, 320, 190);
|
||||
state->_dirtyRects.clear();
|
||||
|
||||
state->driver = new GfxDriver(xfact, yfact, bpp);
|
||||
state->driver = new GfxDriver(xfact, yfact, mode);
|
||||
|
||||
state->gfxResMan = new GfxResManager(state->options, state->driver, resManager);
|
||||
|
||||
|
@ -1131,8 +1132,10 @@ static int _gfxop_set_pointer(GfxState *state, gfx_pixmap_t *pxm, Common::Point
|
|||
// may change when a new PIC is loaded. The cursor has to be regenerated
|
||||
// from this pxm at that point. (An alternative might be to ensure the
|
||||
// cursor only uses colours in the static part of the palette?)
|
||||
if (pxm && pxm->palette)
|
||||
if (pxm && state->driver->getMode()->palette) {
|
||||
assert(pxm->palette);
|
||||
pxm->palette->mergeInto(state->driver->getMode()->palette);
|
||||
}
|
||||
state->driver->setPointer(pxm, hotspot);
|
||||
|
||||
return GFX_OK;
|
||||
|
@ -1736,7 +1739,7 @@ int gfxop_new_pic(GfxState *state, int nr, int flags, int default_palette) {
|
|||
if (state->driver->getMode()->xfact == 1 && state->driver->getMode()->yfact == 1) {
|
||||
state->pic_unscaled = state->pic;
|
||||
} else {
|
||||
state->pic = state->gfxResMan->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, false);
|
||||
state->pic_unscaled = state->gfxResMan->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, false);
|
||||
}
|
||||
|
||||
if (!state->pic || !state->pic_unscaled) {
|
||||
|
|
|
@ -138,17 +138,16 @@ struct GfxState {
|
|||
* @param[in] state The state to initialize
|
||||
* @param[in] xfact Horizontal scale factor
|
||||
* @param[in] yfact Vertical scale factors
|
||||
* @param[in] bpp Bytes per pixel to initialize with, or 0
|
||||
* (GFX_COLOR_MODE_AUTO) to auto-detect
|
||||
* @param[in] mode Graphics mode to use
|
||||
* @param[in] options Rendering options
|
||||
* @param[in] resManager Resource manager to use
|
||||
* @return GFX_OK on success, GFX_ERROR if that particular mode
|
||||
* is unavailable, or GFX_FATAL if the graphics driver
|
||||
* is unable to provide any useful graphics support
|
||||
*/
|
||||
int gfxop_init(int version, GfxState *state, gfx_options_t *options,
|
||||
ResourceManager *resManager, int xfact = 1, int yfact = 1,
|
||||
gfx_color_mode_t bpp = GFX_COLOR_MODE_INDEX);
|
||||
int gfxop_init(int version, GfxState *state,
|
||||
gfx_options_t *options, ResourceManager *resManager,
|
||||
Graphics::PixelFormat mode, int xfact = 1, int yfact = 1);
|
||||
|
||||
/**
|
||||
* Deinitializes a currently active driver.
|
||||
|
|
|
@ -1552,7 +1552,7 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size,
|
|||
view->index_height = CLIP<int>(view->index_height, 0, portBounds.height());
|
||||
|
||||
// Set up mode structure for resizing the view
|
||||
Graphics::PixelFormat format = { 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // 1byte/p, which handles masks and the rest for us
|
||||
Graphics::PixelFormat format(1, 0, 0, 0, 0, 0, 0, 0, 0); // 1byte/p, which handles masks and the rest for us
|
||||
gfx_mode_t *mode = gfx_new_mode(pic->visual_map->index_width / 320,
|
||||
pic->visual_map->index_height / 200, format, view->palette, 0);
|
||||
|
||||
|
@ -1658,7 +1658,7 @@ void gfxr_draw_pic11(gfxr_pic_t *pic, int flags, int default_palette, int size,
|
|||
view->palette = pic->visual_map->palette->getref();
|
||||
|
||||
// Set up mode structure for resizing the view
|
||||
Graphics::PixelFormat format = { 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // 1 byte/p, which handles masks and the rest for us
|
||||
Graphics::PixelFormat format(1, 0, 0, 0, 0, 0, 0, 0, 0); // 1 byte/p, which handles masks and the rest for us
|
||||
gfx_mode_t *mode = gfx_new_mode(pic->visual_map->index_width / 320, pic->visual_map->index_height / 200, format, view->palette, 0);
|
||||
|
||||
gfx_xlate_pixmap(view, mode, GFX_XLATE_FILTER_NONE);
|
||||
|
|
|
@ -111,7 +111,13 @@ SciEngine::~SciEngine() {
|
|||
}
|
||||
|
||||
Common::Error SciEngine::run() {
|
||||
Graphics::PixelFormat gfxmode;
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
initGraphics(320, 200, false, NULL);
|
||||
#else
|
||||
initGraphics(320, 200, false);
|
||||
#endif
|
||||
gfxmode = _system->getScreenFormat();
|
||||
|
||||
// Create debugger console. It requires GFX to be initialized
|
||||
_console = new Console(this);
|
||||
|
@ -190,7 +196,7 @@ Common::Error SciEngine::run() {
|
|||
// Default config ends
|
||||
#endif
|
||||
|
||||
if (gfxop_init(_resmgr->sciVersion(), &gfx_state, &gfx_options, _resmgr)) {
|
||||
if (gfxop_init(_resmgr->sciVersion(), &gfx_state, &gfx_options, _resmgr, gfxmode, 1, 1)) {
|
||||
warning("Graphics initialization failed. Aborting...");
|
||||
return Common::kUnknownError;
|
||||
}
|
||||
|
|
|
@ -2451,7 +2451,7 @@ void ScummEngine_v71he::postProcessAuxQueue() {
|
|||
uint8 *dst2 = pvs->getBackPixels(0, pvs->topline);
|
||||
switch (comp) {
|
||||
case 1:
|
||||
Wiz::copyAuxImage(dst1, dst2, axfd + 10, pvs->w, pvs->h, x, y, w, h);
|
||||
Wiz::copyAuxImage(dst1, dst2, axfd + 10, pvs->pitch, pvs->h, x, y, w, h, _bitDepth);
|
||||
break;
|
||||
default:
|
||||
error("unimplemented compression type %d", comp);
|
||||
|
@ -2551,9 +2551,10 @@ void Actor::saveLoadWithSerializer(Serializer *ser) {
|
|||
MKLINE(Actor, _flip, sleByte, VER(32)),
|
||||
MKLINE(Actor, _heSkipLimbs, sleByte, VER(32)),
|
||||
|
||||
// Actor palette grew from 64 to 256 bytes
|
||||
// Actor palette grew from 64 to 256 bytes and switched to uint16 in HE games
|
||||
MKARRAY_OLD(Actor, _palette[0], sleByte, 64, VER(8), VER(9)),
|
||||
MKARRAY(Actor, _palette[0], sleByte, 256, VER(10)),
|
||||
MKARRAY_OLD(Actor, _palette[0], sleByte, 256, VER(10), VER(79)),
|
||||
MKARRAY(Actor, _palette[0], sleUint16, 256, VER(80)),
|
||||
|
||||
MK_OBSOLETE(Actor, _mask, sleByte, VER(8), VER(9)),
|
||||
MKLINE(Actor, _shadowMode, sleByte, VER(8)),
|
||||
|
|
|
@ -157,7 +157,7 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
byte _palette[256];
|
||||
uint16 _palette[256];
|
||||
int _elevation;
|
||||
uint16 _facing;
|
||||
uint16 _targetFacing;
|
||||
|
|
|
@ -289,7 +289,7 @@ void AkosCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
|
|||
} while ((uint16)mask);
|
||||
}
|
||||
|
||||
void AkosRenderer::setPalette(byte *new_palette) {
|
||||
void AkosRenderer::setPalette(uint16 *new_palette) {
|
||||
uint size, i;
|
||||
|
||||
size = _vm->getResourceDataSize(akpl);
|
||||
|
@ -299,22 +299,23 @@ void AkosRenderer::setPalette(byte *new_palette) {
|
|||
if (size > 256)
|
||||
error("akos_setPalette: %d is too many colors", size);
|
||||
|
||||
if (_vm->_game.heversion >= 99 && _paletteNum) {
|
||||
for (i = 0; i < size; i++)
|
||||
_palette[i] = (byte)_vm->_hePalettes[_paletteNum * 1024 + 768 + akpl[i]];
|
||||
} else if ((_vm->_game.features & GF_16BIT_COLOR) && rgbs) {
|
||||
for (i = 0; i < size; i++) {
|
||||
if (new_palette[i] == 0xFF) {
|
||||
uint8 col = akpl[i];
|
||||
uint8 r = rgbs[col * 3 + 0];
|
||||
uint8 g = rgbs[col * 3 + 1];
|
||||
uint8 b = rgbs[col * 3 + 2];
|
||||
|
||||
_palette[i] = _vm->remapPaletteColor(r, g, b, -1);
|
||||
} else {
|
||||
_palette[i] = new_palette[i];
|
||||
if (_vm->_game.features & GF_16BIT_COLOR) {
|
||||
if (_paletteNum) {
|
||||
for (i = 0; i < size; i++)
|
||||
_palette[i] = READ_LE_UINT16(_vm->_hePalettes + _paletteNum * _vm->_hePaletteSlot + 768 + akpl[i] * 2);
|
||||
} else if (rgbs) {
|
||||
for (i = 0; i < size; i++) {
|
||||
if (new_palette[i] == 0xFF) {
|
||||
uint8 col = akpl[i];
|
||||
_palette[i] = _vm->get16BitColor(rgbs[col * 3 + 0], rgbs[col * 3 + 1], rgbs[col * 3 + 2]);
|
||||
} else {
|
||||
_palette[i] = new_palette[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (_vm->_game.heversion >= 99 && _paletteNum) {
|
||||
for (i = 0; i < size; i++)
|
||||
_palette[i] = (byte)_vm->_hePalettes[_paletteNum * _vm->_hePaletteSlot + 768 + akpl[i]];
|
||||
} else {
|
||||
for (i = 0; i < size; i++) {
|
||||
_palette[i] = new_palette[i] != 0xFF ? new_palette[i] : akpl[i];
|
||||
|
@ -545,7 +546,7 @@ void AkosRenderer::codec1_genericDecode(Codec1 &v1) {
|
|||
byte *dst;
|
||||
byte len, maskbit;
|
||||
int y;
|
||||
uint color, height, pcolor;
|
||||
uint16 color, height, pcolor;
|
||||
const byte *scaleytab;
|
||||
bool masked;
|
||||
bool skip_column = false;
|
||||
|
@ -589,7 +590,11 @@ void AkosRenderer::codec1_genericDecode(Codec1 &v1) {
|
|||
} else if (_shadow_mode == 2) {
|
||||
error("codec1_spec2"); // TODO
|
||||
} else if (_shadow_mode == 3) {
|
||||
if (_vm->_game.heversion >= 90) {
|
||||
if (_vm->_game.features & GF_16BIT_COLOR) {
|
||||
uint16 srcColor = (pcolor >> 1) & 0x7DEF;
|
||||
uint16 dstColor = (READ_UINT16(dst) >> 1) & 0x7DEF;
|
||||
pcolor = srcColor + dstColor;
|
||||
} else if (_vm->_game.heversion >= 90) {
|
||||
pcolor = (pcolor << 8) + *dst;
|
||||
pcolor = xmap[pcolor];
|
||||
} else if (pcolor < 8) {
|
||||
|
@ -597,7 +602,11 @@ void AkosRenderer::codec1_genericDecode(Codec1 &v1) {
|
|||
pcolor = _shadow_table[pcolor];
|
||||
}
|
||||
}
|
||||
*dst = pcolor;
|
||||
if (_vm->_bitDepth == 2) {
|
||||
WRITE_UINT16(dst, pcolor);
|
||||
} else {
|
||||
*dst = pcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
dst += _out.pitch;
|
||||
|
@ -617,7 +626,7 @@ void AkosRenderer::codec1_genericDecode(Codec1 &v1) {
|
|||
if (v1.x < 0 || v1.x >= v1.boundsRect.right)
|
||||
return;
|
||||
maskbit = revBitMask(v1.x & 7);
|
||||
v1.destptr += v1.scaleXstep;
|
||||
v1.destptr += v1.scaleXstep * _vm->_bitDepth;
|
||||
skip_column = false;
|
||||
} else
|
||||
skip_column = true;
|
||||
|
@ -987,7 +996,7 @@ byte AkosRenderer::codec1(int xmoveCur, int ymoveCur) {
|
|||
if (_draw_bottom < rect.bottom)
|
||||
_draw_bottom = rect.bottom;
|
||||
|
||||
v1.destptr = (byte *)_out.pixels + v1.y * _out.pitch + v1.x;
|
||||
v1.destptr = (byte *)_out.pixels + v1.y * _out.pitch + v1.x * _vm->_bitDepth;
|
||||
|
||||
codec1_genericDecode(v1);
|
||||
|
||||
|
@ -1056,7 +1065,12 @@ byte AkosRenderer::codec5(int xmoveCur, int ymoveCur) {
|
|||
bdd.shadowMode = _shadow_mode;
|
||||
bdd.shadowPalette = _vm->_shadowPalette;
|
||||
|
||||
bdd.actorPalette = _useBompPalette ? _palette : 0;
|
||||
bdd.actorPalette = 0;
|
||||
if (_useBompPalette) {
|
||||
for (uint i = 0; i < 256; i++)
|
||||
bdd.actorPalette[i] = _palette[i];
|
||||
}
|
||||
|
||||
bdd.mirror = !_mirror;
|
||||
|
||||
drawBomp(bdd);
|
||||
|
@ -1176,6 +1190,8 @@ void AkosRenderer::akos16Decompress(byte *dest, int32 pitch, const byte *src, in
|
|||
}
|
||||
|
||||
byte AkosRenderer::codec16(int xmoveCur, int ymoveCur) {
|
||||
assert(_vm->_bitDepth == 1);
|
||||
|
||||
Common::Rect clip;
|
||||
int32 minx, miny, maxw, maxh;
|
||||
int32 skip_x, skip_y, cur_x, cur_y;
|
||||
|
@ -1278,7 +1294,7 @@ byte AkosRenderer::codec16(int xmoveCur, int ymoveCur) {
|
|||
int32 numskip_before = skip_x + (skip_y * _width);
|
||||
int32 numskip_after = _width - cur_x;
|
||||
|
||||
byte *dst = (byte *)_out.pixels + width_unk + height_unk * _out.pitch;
|
||||
byte *dst = (byte *)_out.pixels + height_unk * _out.pitch + width_unk * _vm->_bitDepth;
|
||||
|
||||
akos16Decompress(dst, _out.pitch, _srcptr, cur_x, out_height, dir, numskip_before, numskip_after, transparency, clip.left, clip.top, _zbuf);
|
||||
return 0;
|
||||
|
@ -1335,18 +1351,27 @@ byte AkosRenderer::codec32(int xmoveCur, int ymoveCur) {
|
|||
_draw_bottom = dst.bottom;
|
||||
|
||||
const uint8 *palPtr = NULL;
|
||||
if (_vm->_game.heversion >= 99) {
|
||||
palPtr = _vm->_hePalettes + 1792;
|
||||
if (_vm->_game.features & GF_16BIT_COLOR) {
|
||||
palPtr = _vm->_hePalettes + _vm->_hePaletteSlot + 768;
|
||||
if (_paletteNum) {
|
||||
palPtr = _vm->_hePalettes + _paletteNum * _vm->_hePaletteSlot + 768;
|
||||
} else if (rgbs) {
|
||||
for (uint i = 0; i < 256; i++)
|
||||
WRITE_LE_UINT16(_palette + i, _vm->get16BitColor(rgbs[i * 3 + 0], rgbs[i * 3 + 1], rgbs[i * 3 + 2]));
|
||||
palPtr = (uint8 *)_palette;
|
||||
}
|
||||
} else if (_vm->_game.heversion >= 99) {
|
||||
palPtr = _vm->_hePalettes + _vm->_hePaletteSlot + 768;
|
||||
}
|
||||
|
||||
byte *dstPtr = (byte *)_out.pixels + dst.left + dst.top * _out.pitch;
|
||||
byte *dstPtr = (byte *)_out.pixels + dst.top * _out.pitch + dst.left * _vm->_bitDepth;
|
||||
if (_shadow_mode == 3) {
|
||||
Wiz::decompressWizImage<kWizXMap>(dstPtr, _out.pitch, _srcptr, src, 0, palPtr, xmap);
|
||||
Wiz::decompressWizImage<kWizXMap>(dstPtr, _out.pitch, kDstScreen, _srcptr, src, 0, palPtr, xmap, _vm->_bitDepth);
|
||||
} else {
|
||||
if (palPtr != NULL) {
|
||||
Wiz::decompressWizImage<kWizRMap>(dstPtr, _out.pitch, _srcptr, src, 0, palPtr);
|
||||
Wiz::decompressWizImage<kWizRMap>(dstPtr, _out.pitch, kDstScreen, _srcptr, src, 0, palPtr, NULL, _vm->_bitDepth);
|
||||
} else {
|
||||
Wiz::decompressWizImage<kWizCopy>(dstPtr, _out.pitch, _srcptr, src, 0);
|
||||
Wiz::decompressWizImage<kWizCopy>(dstPtr, _out.pitch, kDstScreen, _srcptr, src, 0, NULL, NULL, _vm->_bitDepth);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -60,7 +60,7 @@ protected:
|
|||
uint16 _codec;
|
||||
|
||||
// actor _palette
|
||||
byte _palette[256];
|
||||
uint16 _palette[256];
|
||||
bool _useBompPalette;
|
||||
|
||||
// pointer to various parts of the costume resource
|
||||
|
@ -107,7 +107,7 @@ public:
|
|||
int16 _actorHitX, _actorHitY;
|
||||
bool _actorHitResult;
|
||||
|
||||
void setPalette(byte *_palette);
|
||||
void setPalette(uint16 *_palette);
|
||||
void setFacing(const Actor *a);
|
||||
void setCostume(int costume, int shadow);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ byte BaseCostumeRenderer::drawCostume(const VirtScreen &vs, int numStrips, const
|
|||
_out.pixels = vs.getPixels(0, 0);
|
||||
|
||||
_actorX += _vm->_virtscr[kMainVirtScreen].xstart & 7;
|
||||
_out.w = _out.pitch;
|
||||
_out.w = _out.pitch / _vm->_bitDepth;
|
||||
_out.pixels = (byte *)_out.pixels - (_vm->_virtscr[kMainVirtScreen].xstart & 7);
|
||||
|
||||
_numStrips = numStrips;
|
||||
|
|
|
@ -145,7 +145,7 @@ public:
|
|||
}
|
||||
virtual ~BaseCostumeRenderer() {}
|
||||
|
||||
virtual void setPalette(byte *palette) = 0;
|
||||
virtual void setPalette(uint16 *palette) = 0;
|
||||
virtual void setFacing(const Actor *a) = 0;
|
||||
virtual void setCostume(int costume, int shadow) = 0;
|
||||
|
||||
|
|
|
@ -819,9 +819,9 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr,
|
|||
byte imagePalette[256];
|
||||
memset(imagePalette, 0, sizeof(imagePalette));
|
||||
memcpy(imagePalette, _vm->_charsetColorMap, 4);
|
||||
Wiz::copyWizImage(dstPtr, charPtr, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen, 0, imagePalette);
|
||||
Wiz::copyWizImage(dstPtr, charPtr, vs->pitch, kDstScreen, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen, 0, imagePalette, NULL, _vm->_bitDepth);
|
||||
} else {
|
||||
Wiz::copyWizImage(dstPtr, charPtr, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen);
|
||||
Wiz::copyWizImage(dstPtr, charPtr, vs->pitch, kDstScreen, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen, 0, NULL, NULL, _vm->_bitDepth);
|
||||
}
|
||||
|
||||
if (_blitAlso && vs->hasTwoBuffers) {
|
||||
|
|
|
@ -791,7 +791,7 @@ byte ClassicCostumeRenderer::drawLimb(const Actor *a, int limb) {
|
|||
|
||||
}
|
||||
|
||||
void NESCostumeRenderer::setPalette(byte *palette) {
|
||||
void NESCostumeRenderer::setPalette(uint16 *palette) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
@ -874,17 +874,20 @@ void ClassicCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask)
|
|||
} while (mask&0xFFFF);
|
||||
}
|
||||
|
||||
void ClassicCostumeRenderer::setPalette(byte *palette) {
|
||||
void ClassicCostumeRenderer::setPalette(uint16 *palette) {
|
||||
int i;
|
||||
byte color;
|
||||
|
||||
if (_loaded._format == 0x57) {
|
||||
memcpy(_palette, palette, 13);
|
||||
for (i = 0; i < 13; i++)
|
||||
_palette[i] = palette[i];
|
||||
} else if (_vm->_game.features & GF_OLD_BUNDLE) {
|
||||
if (_vm->getCurrentLights() & LIGHTMODE_actor_use_colors) {
|
||||
memcpy(_palette, palette, 16);
|
||||
for (i = 0; i < 16; i++)
|
||||
_palette[i] = palette[i];
|
||||
} else {
|
||||
memset(_palette, 8, 16);
|
||||
for (i = 0; i < 16; i++)
|
||||
_palette[i] = 8;
|
||||
_palette[12] = 0;
|
||||
}
|
||||
_palette[_loaded._palette[0]] = _palette[0];
|
||||
|
|
|
@ -98,7 +98,7 @@ protected:
|
|||
public:
|
||||
ClassicCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
|
||||
|
||||
void setPalette(byte *palette);
|
||||
void setPalette(uint16 *palette);
|
||||
void setFacing(const Actor *a);
|
||||
void setCostume(int costume, int shadow);
|
||||
|
||||
|
@ -120,7 +120,7 @@ protected:
|
|||
public:
|
||||
NESCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
|
||||
|
||||
void setPalette(byte *palette);
|
||||
void setPalette(uint16 *palette);
|
||||
void setFacing(const Actor *a);
|
||||
void setCostume(int costume, int shadow);
|
||||
|
||||
|
@ -135,7 +135,7 @@ protected:
|
|||
public:
|
||||
C64CostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
|
||||
|
||||
void setPalette(byte *palette) {}
|
||||
void setPalette(uint16 *palette) {}
|
||||
void setFacing(const Actor *a) {}
|
||||
void setCostume(int costume, int shadow);
|
||||
|
||||
|
|
|
@ -111,11 +111,20 @@ void ScummEngine_v6::setCursorTransparency(int a) {
|
|||
}
|
||||
|
||||
void ScummEngine::updateCursor() {
|
||||
const int transColor = (_game.heversion >= 80) ? 5 : 255;
|
||||
int transColor = (_game.heversion >= 80) ? 5 : 255;
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
Graphics::PixelFormat format = _system->getScreenFormat();
|
||||
CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
|
||||
_cursor.hotspotX, _cursor.hotspotY,
|
||||
(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
|
||||
(_game.heversion == 70 ? 2 : 1),
|
||||
&format);
|
||||
#else
|
||||
CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
|
||||
_cursor.hotspotX, _cursor.hotspotY,
|
||||
(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
|
||||
(_game.heversion == 70 ? 2 : 1));
|
||||
#endif
|
||||
}
|
||||
|
||||
void ScummEngine_v6::grabCursor(int x, int y, int w, int h) {
|
||||
|
@ -138,7 +147,7 @@ void ScummEngine::setCursorFromBuffer(const byte *ptr, int width, int height, in
|
|||
uint size;
|
||||
byte *dst;
|
||||
|
||||
size = width * height;
|
||||
size = width * height * _bitDepth;
|
||||
if (size > sizeof(_grabbedCursor))
|
||||
error("grabCursor: grabbed cursor too big");
|
||||
|
||||
|
@ -148,8 +157,8 @@ void ScummEngine::setCursorFromBuffer(const byte *ptr, int width, int height, in
|
|||
|
||||
dst = _grabbedCursor;
|
||||
for (; height; height--) {
|
||||
memcpy(dst, ptr, width);
|
||||
dst += width;
|
||||
memcpy(dst, ptr, width * _bitDepth);
|
||||
dst += width * _bitDepth;
|
||||
ptr += pitch;
|
||||
}
|
||||
|
||||
|
@ -166,8 +175,13 @@ void ScummEngine_v70he::setDefaultCursor() {
|
|||
static const byte palette[] = {0, 0, 0, 0,
|
||||
0xff, 0xff, 0xff, 0,
|
||||
0, 0, 0, 0};
|
||||
|
||||
memset(_grabbedCursor, 5, sizeof(_grabbedCursor));
|
||||
|
||||
if (_bitDepth == 2) {
|
||||
for (i = 0; i < 1024; i++)
|
||||
WRITE_UINT16(_grabbedCursor + i * 2, 5);
|
||||
} else {
|
||||
memset(_grabbedCursor, 5, sizeof(_grabbedCursor));
|
||||
}
|
||||
|
||||
_cursor.hotspotX = _cursor.hotspotY = 2;
|
||||
src = default_he_cursor;
|
||||
|
@ -180,10 +194,16 @@ void ScummEngine_v70he::setDefaultCursor() {
|
|||
for (j = 0; j < 32; j++) {
|
||||
switch ((p & (0x3 << 14)) >> 14) {
|
||||
case 1:
|
||||
_grabbedCursor[32 * i + j] = 0xfe;
|
||||
if (_bitDepth == 2)
|
||||
WRITE_UINT16(_grabbedCursor + 64 * i + j * 2, get16BitColor(palette[4], palette[5], palette[6]));
|
||||
else
|
||||
_grabbedCursor[32 * i + j] = 0xfe;
|
||||
break;
|
||||
case 2:
|
||||
_grabbedCursor[32 * i + j] = 0xfd;
|
||||
if (_bitDepth == 2)
|
||||
WRITE_UINT16(_grabbedCursor + 64 * i + j * 2, get16BitColor(palette[0], palette[1], palette[2]));
|
||||
else
|
||||
_grabbedCursor[32 * i + j] = 0xfd;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -195,9 +215,11 @@ void ScummEngine_v70he::setDefaultCursor() {
|
|||
}
|
||||
}
|
||||
|
||||
// Since white color position is not guaranteed
|
||||
// we setup our own palette if supported by backend
|
||||
CursorMan.replaceCursorPalette(palette, 0xfd, 3);
|
||||
if (_bitDepth == 1) {
|
||||
// Since white color position is not guaranteed
|
||||
// we setup our own palette if supported by backend
|
||||
CursorMan.replaceCursorPalette(palette, 0xfd, 3);
|
||||
}
|
||||
|
||||
updateCursor();
|
||||
}
|
||||
|
|
|
@ -43,12 +43,12 @@ extern "C" void asmCopy8Col(byte* dst, int dstPitch, const byte* src, int height
|
|||
|
||||
namespace Scumm {
|
||||
|
||||
static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h);
|
||||
static void fill(byte *dst, int dstPitch, byte color, int w, int h);
|
||||
static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h, uint8 bitDepth);
|
||||
static void fill(byte *dst, int dstPitch, uint16 color, int w, int h, uint8 bitDepth);
|
||||
#ifndef USE_ARM_GFX_ASM
|
||||
static void copy8Col(byte *dst, int dstPitch, const byte *src, int height);
|
||||
static void copy8Col(byte *dst, int dstPitch, const byte *src, int height, uint8 bitDepth);
|
||||
#endif
|
||||
static void clear8Col(byte *dst, int dstPitch, int height);
|
||||
static void clear8Col(byte *dst, int dstPitch, int height, uint8 bitDepth);
|
||||
|
||||
static void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *width, int *height);
|
||||
static void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h);
|
||||
|
@ -231,6 +231,9 @@ GdiV2::~GdiV2() {
|
|||
free(_roomStrips);
|
||||
}
|
||||
|
||||
Gdi16Bit::Gdi16Bit(ScummEngine *vm) : Gdi(vm) {
|
||||
}
|
||||
|
||||
void Gdi::init() {
|
||||
_numStrips = _vm->_screenWidth / 8;
|
||||
|
||||
|
@ -341,8 +344,8 @@ void ScummEngine::initVirtScreen(VirtScreenNumber slot, int top, int width, int
|
|||
vs->hasTwoBuffers = twobufs;
|
||||
vs->xstart = 0;
|
||||
vs->backBuf = NULL;
|
||||
vs->bytesPerPixel = 1;
|
||||
vs->pitch = width;
|
||||
vs->bytesPerPixel = (_game.features & GF_16BIT_COLOR) ? 2 : 1;
|
||||
vs->pitch = width * vs->bytesPerPixel;
|
||||
|
||||
if (_game.version >= 7) {
|
||||
// Increase the pitch by one; needed to accomodate the extra screen
|
||||
|
@ -586,7 +589,7 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
|
|||
vsPitch = _screenWidth * m - width * m;
|
||||
|
||||
} else {
|
||||
vsPitch = vs->pitch - width;
|
||||
vsPitch = vs->pitch - width * vs->bytesPerPixel;
|
||||
}
|
||||
|
||||
|
||||
|
@ -612,36 +615,49 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
|
|||
#else
|
||||
// We blit four pixels at a time, for improved performance.
|
||||
const uint32 *src32 = (const uint32 *)src;
|
||||
const uint32 *text32 = (const uint32 *)text;
|
||||
uint32 *dst32 = (uint32 *)_compositeBuf;
|
||||
|
||||
vsPitch >>= 2;
|
||||
const int textPitch = (_textSurface.pitch - width * m) >> 2;
|
||||
for (int h = height * m; h > 0; --h) {
|
||||
for (int w = width*m; w > 0; w-=4) {
|
||||
uint32 temp = *text32++;
|
||||
|
||||
// Generate a byte mask for those text pixels (bytes) with
|
||||
// value CHARSET_MASK_TRANSPARENCY. In the end, each byte
|
||||
// in mask will be either equal to 0x00 or 0xFF.
|
||||
// Doing it this way avoids branches and bytewise operations,
|
||||
// at the cost of readability ;).
|
||||
uint32 mask = temp ^ CHARSET_MASK_TRANSPARENCY_32;
|
||||
mask = (((mask & 0x7f7f7f7f) + 0x7f7f7f7f) | mask) & 0x80808080;
|
||||
mask = ((mask >> 7) + 0x7f7f7f7f) ^ 0x80808080;
|
||||
|
||||
// The following line is equivalent to this code:
|
||||
// *dst32++ = (*src32++ & mask) | (temp & ~mask);
|
||||
// However, some compilers can generate somewhat better
|
||||
// machine code for this equivalent statement:
|
||||
*dst32++ = ((temp ^ *src32++) & mask) ^ temp;
|
||||
if (_bitDepth == 2) {
|
||||
// Sprites always seem to be used for subtitles in 16Bit color HE games, and not
|
||||
// the charset renderer, so charset masking isn't required.
|
||||
for (int h = height * m; h > 0; --h) {
|
||||
for (int w = width * m; w > 0; w -= 4) {
|
||||
*dst32++ = *src32++;
|
||||
*dst32++ = *src32++;
|
||||
}
|
||||
src32 += vsPitch;
|
||||
}
|
||||
} else {
|
||||
const uint32 *text32 = (const uint32 *)text;
|
||||
const int textPitch = (_textSurface.pitch - width * m) >> 2;
|
||||
for (int h = height * m; h > 0; --h) {
|
||||
for (int w = width * m; w > 0; w -= 4) {
|
||||
uint32 temp = *text32++;
|
||||
|
||||
// Generate a byte mask for those text pixels (bytes) with
|
||||
// value CHARSET_MASK_TRANSPARENCY. In the end, each byte
|
||||
// in mask will be either equal to 0x00 or 0xFF.
|
||||
// Doing it this way avoids branches and bytewise operations,
|
||||
// at the cost of readability ;).
|
||||
uint32 mask = temp ^ CHARSET_MASK_TRANSPARENCY_32;
|
||||
mask = (((mask & 0x7f7f7f7f) + 0x7f7f7f7f) | mask) & 0x80808080;
|
||||
mask = ((mask >> 7) + 0x7f7f7f7f) ^ 0x80808080;
|
||||
|
||||
// The following line is equivalent to this code:
|
||||
// *dst32++ = (*src32++ & mask) | (temp & ~mask);
|
||||
// However, some compilers can generate somewhat better
|
||||
// machine code for this equivalent statement:
|
||||
*dst32++ = ((temp ^ *src32++) & mask) ^ temp;
|
||||
}
|
||||
src32 += vsPitch;
|
||||
text32 += textPitch;
|
||||
}
|
||||
src32 += vsPitch;
|
||||
text32 += textPitch;
|
||||
}
|
||||
#endif
|
||||
src = _compositeBuf;
|
||||
pitch = width;
|
||||
pitch = width * vs->bytesPerPixel;
|
||||
|
||||
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
|
||||
ditherHerc(_compositeBuf, _herculesBuf, width, &x, &y, &width, &height);
|
||||
|
@ -986,13 +1002,13 @@ void ScummEngine::restoreBackground(Common::Rect rect, byte backColor) {
|
|||
return;
|
||||
|
||||
if (vs->hasTwoBuffers && _currentRoom != 0 && isLightOn()) {
|
||||
blit(screenBuf, vs->pitch, vs->getBackPixels(rect.left, rect.top), vs->pitch, width, height);
|
||||
blit(screenBuf, vs->pitch, vs->getBackPixels(rect.left, rect.top), vs->pitch, width, height, vs->bytesPerPixel);
|
||||
if (vs->number == kMainVirtScreen && _charset->_hasMask) {
|
||||
byte *mask = (byte *)_textSurface.getBasePtr(rect.left, rect.top - _screenTop);
|
||||
fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height);
|
||||
fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height, _textSurface.bytesPerPixel);
|
||||
}
|
||||
} else {
|
||||
fill(screenBuf, vs->pitch, backColor, width, height);
|
||||
fill(screenBuf, vs->pitch, backColor, width, height, vs->bytesPerPixel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1021,7 +1037,7 @@ void ScummEngine::restoreCharsetBg() {
|
|||
if (vs->number != kMainVirtScreen) {
|
||||
// Restore from back buffer
|
||||
const byte *backBuf = vs->getBackPixels(0, 0);
|
||||
blit(screenBuf, vs->pitch, backBuf, vs->pitch, vs->w, vs->h);
|
||||
blit(screenBuf, vs->pitch, backBuf, vs->pitch, vs->w, vs->h, vs->bytesPerPixel);
|
||||
}
|
||||
} else {
|
||||
// Clear area
|
||||
|
@ -1057,34 +1073,42 @@ byte *Gdi::getMaskBuffer(int x, int y, int z) {
|
|||
#pragma mark --- Misc ---
|
||||
#pragma mark -
|
||||
|
||||
static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) {
|
||||
static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h, uint8 bitDepth) {
|
||||
assert(w > 0);
|
||||
assert(h > 0);
|
||||
assert(src != NULL);
|
||||
assert(dst != NULL);
|
||||
|
||||
if (w == srcPitch && w == dstPitch) {
|
||||
memcpy(dst, src, w*h);
|
||||
if ((w * bitDepth == srcPitch) && (w * bitDepth == dstPitch)) {
|
||||
memcpy(dst, src, w * h * bitDepth);
|
||||
} else {
|
||||
do {
|
||||
memcpy(dst, src, w);
|
||||
memcpy(dst, src, w * bitDepth);
|
||||
dst += dstPitch;
|
||||
src += srcPitch;
|
||||
} while (--h);
|
||||
}
|
||||
}
|
||||
|
||||
static void fill(byte *dst, int dstPitch, byte color, int w, int h) {
|
||||
static void fill(byte *dst, int dstPitch, uint16 color, int w, int h, uint8 bitDepth) {
|
||||
assert(h > 0);
|
||||
assert(dst != NULL);
|
||||
|
||||
if (w == dstPitch) {
|
||||
memset(dst, color, w*h);
|
||||
} else {
|
||||
if (bitDepth == 2) {
|
||||
do {
|
||||
memset(dst, color, w);
|
||||
for (int i = 0; i < w; i++)
|
||||
WRITE_UINT16(dst + i * 2, color);
|
||||
dst += dstPitch;
|
||||
} while (--h);
|
||||
} else {
|
||||
if (w == dstPitch) {
|
||||
memset(dst, color, w * h);
|
||||
} else {
|
||||
do {
|
||||
memset(dst, color, w);
|
||||
dst += dstPitch;
|
||||
} while (--h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1094,14 +1118,18 @@ static void fill(byte *dst, int dstPitch, byte color, int w, int h) {
|
|||
|
||||
#else
|
||||
|
||||
static void copy8Col(byte *dst, int dstPitch, const byte *src, int height) {
|
||||
static void copy8Col(byte *dst, int dstPitch, const byte *src, int height, uint8 bitDepth) {
|
||||
|
||||
do {
|
||||
#if defined(SCUMM_NEED_ALIGNMENT)
|
||||
memcpy(dst, src, 8);
|
||||
memcpy(dst, src, 8 * bitDepth);
|
||||
#else
|
||||
((uint32 *)dst)[0] = ((const uint32 *)src)[0];
|
||||
((uint32 *)dst)[1] = ((const uint32 *)src)[1];
|
||||
if (bitDepth == 2) {
|
||||
((uint32 *)dst)[2] = ((const uint32 *)src)[2];
|
||||
((uint32 *)dst)[3] = ((const uint32 *)src)[3];
|
||||
}
|
||||
#endif
|
||||
dst += dstPitch;
|
||||
src += dstPitch;
|
||||
|
@ -1110,13 +1138,17 @@ static void copy8Col(byte *dst, int dstPitch, const byte *src, int height) {
|
|||
|
||||
#endif /* USE_ARM_GFX_ASM */
|
||||
|
||||
static void clear8Col(byte *dst, int dstPitch, int height) {
|
||||
static void clear8Col(byte *dst, int dstPitch, int height, uint8 bitDepth) {
|
||||
do {
|
||||
#if defined(SCUMM_NEED_ALIGNMENT)
|
||||
memset(dst, 0, 8);
|
||||
memset(dst, 0, 8 * bitDepth);
|
||||
#else
|
||||
((uint32 *)dst)[0] = 0;
|
||||
((uint32 *)dst)[1] = 0;
|
||||
if (bitDepth == 2) {
|
||||
((uint32 *)dst)[2] = 0;
|
||||
((uint32 *)dst)[3] = 0;
|
||||
}
|
||||
#endif
|
||||
dst += dstPitch;
|
||||
} while (--height);
|
||||
|
@ -1181,41 +1213,41 @@ void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) {
|
|||
if (color == -1) {
|
||||
if (vs->number != kMainVirtScreen)
|
||||
error("can only copy bg to main window");
|
||||
blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
|
||||
blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->bytesPerPixel);
|
||||
if (_charset->_hasMask) {
|
||||
byte *mask = (byte *)_textSurface.getBasePtr(x * _textSurfaceMultiplier, (y - _screenTop) * _textSurfaceMultiplier);
|
||||
fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier);
|
||||
fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.bytesPerPixel);
|
||||
}
|
||||
} else if (_game.heversion >= 72) {
|
||||
// Flags are used for different methods in HE games
|
||||
uint32 flags = color;
|
||||
if ((flags & 0x2000) || (flags & 0x4000000)) {
|
||||
blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
|
||||
blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->bytesPerPixel);
|
||||
} else if ((flags & 0x4000) || (flags & 0x2000000)) {
|
||||
blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height);
|
||||
blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height, vs->bytesPerPixel);
|
||||
} else if ((flags & 0x8000) || (flags & 0x1000000)) {
|
||||
flags &= (flags & 0x1000000) ? 0xFFFFFF : 0x7FFF;
|
||||
fill(backbuff, vs->pitch, flags, width, height);
|
||||
fill(bgbuff, vs->pitch, flags, width, height);
|
||||
fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel);
|
||||
fill(bgbuff, vs->pitch, flags, width, height, vs->bytesPerPixel);
|
||||
} else {
|
||||
fill(backbuff, vs->pitch, flags, width, height);
|
||||
fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel);
|
||||
}
|
||||
} else if (_game.heversion >= 60) {
|
||||
// Flags are used for different methods in HE games
|
||||
uint16 flags = color;
|
||||
if (flags & 0x2000) {
|
||||
blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
|
||||
blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->bytesPerPixel);
|
||||
} else if (flags & 0x4000) {
|
||||
blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height);
|
||||
blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height, vs->bytesPerPixel);
|
||||
} else if (flags & 0x8000) {
|
||||
flags &= 0x7FFF;
|
||||
fill(backbuff, vs->pitch, flags, width, height);
|
||||
fill(bgbuff, vs->pitch, flags, width, height);
|
||||
fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel);
|
||||
fill(bgbuff, vs->pitch, flags, width, height, vs->bytesPerPixel);
|
||||
} else {
|
||||
fill(backbuff, vs->pitch, flags, width, height);
|
||||
fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel);
|
||||
}
|
||||
} else {
|
||||
fill(backbuff, vs->pitch, color, width, height);
|
||||
fill(backbuff, vs->pitch, color, width, height, vs->bytesPerPixel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1253,7 +1285,7 @@ void ScummEngine_v5::drawFlashlight() {
|
|||
_flashlight.y, _flashlight.y + _flashlight.h, USAGE_BIT_DIRTY);
|
||||
|
||||
if (_flashlight.buffer) {
|
||||
fill(_flashlight.buffer, vs->pitch, 0, _flashlight.w, _flashlight.h);
|
||||
fill(_flashlight.buffer, vs->pitch, 0, _flashlight.w, _flashlight.h, vs->bytesPerPixel);
|
||||
}
|
||||
_flashlight.isDrawn = false;
|
||||
}
|
||||
|
@ -1300,7 +1332,7 @@ void ScummEngine_v5::drawFlashlight() {
|
|||
_flashlight.buffer = vs->getPixels(_flashlight.x, _flashlight.y);
|
||||
bgbak = vs->getBackPixels(_flashlight.x, _flashlight.y);
|
||||
|
||||
blit(_flashlight.buffer, vs->pitch, bgbak, vs->pitch, _flashlight.w, _flashlight.h);
|
||||
blit(_flashlight.buffer, vs->pitch, bgbak, vs->pitch, _flashlight.w, _flashlight.h, vs->bytesPerPixel);
|
||||
|
||||
// Round the corners. To do so, we simply hard-code a set of nicely
|
||||
// rounded corners.
|
||||
|
@ -1609,7 +1641,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
|
|||
warning("Gdi::drawBitmap, strip drawn to %d below window bottom %d", y + height, vs->h);
|
||||
}
|
||||
|
||||
_vertStripNextInc = height * vs->pitch - 1;
|
||||
_vertStripNextInc = height * vs->pitch - 1 * vs->bytesPerPixel;
|
||||
|
||||
_objectMode = (flag & dbObjectMode) == dbObjectMode;
|
||||
prepareDrawBitmap(ptr, vs, x, y, width, height, stripnr, numstrip);
|
||||
|
@ -1642,9 +1674,9 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
|
|||
// In the case of a double buffered virtual screen, we draw to
|
||||
// the backbuffer, otherwise to the primary surface memory.
|
||||
if (vs->hasTwoBuffers)
|
||||
dstPtr = vs->backBuf + y * vs->pitch + x * 8;
|
||||
dstPtr = vs->backBuf + y * vs->pitch + (x * 8 * vs->bytesPerPixel);
|
||||
else
|
||||
dstPtr = (byte *)vs->pixels + y * vs->pitch + x * 8;
|
||||
dstPtr = (byte *)vs->pixels + y * vs->pitch + (x * 8 * vs->bytesPerPixel);
|
||||
|
||||
transpStrip = drawStrip(dstPtr, vs, x, y, width, height, stripnr, smap_ptr);
|
||||
|
||||
|
@ -1653,11 +1685,11 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
|
|||
transpStrip = true;
|
||||
|
||||
if (vs->hasTwoBuffers) {
|
||||
byte *frontBuf = (byte *)vs->pixels + y * vs->pitch + x * 8;
|
||||
byte *frontBuf = (byte *)vs->pixels + y * vs->pitch + (x * 8 * vs->bytesPerPixel);
|
||||
if (lightsOn)
|
||||
copy8Col(frontBuf, vs->pitch, dstPtr, height);
|
||||
copy8Col(frontBuf, vs->pitch, dstPtr, height, vs->bytesPerPixel);
|
||||
else
|
||||
clear8Col(frontBuf, vs->pitch, height);
|
||||
clear8Col(frontBuf, vs->pitch, height, vs->bytesPerPixel);
|
||||
}
|
||||
|
||||
decodeMask(x, y, width, height, stripnr, numzbuf, zplane_list, transpStrip, flag, tmsk_ptr);
|
||||
|
@ -1885,7 +1917,7 @@ void Gdi::drawBMAPBg(const byte *ptr, VirtScreen *vs) {
|
|||
drawStripHE(dst, vs->pitch, bmap_ptr, vs->w, vs->h, true);
|
||||
break;
|
||||
case 150:
|
||||
fill(dst, vs->pitch, *bmap_ptr, vs->w, vs->h);
|
||||
fill(dst, vs->pitch, *bmap_ptr, vs->w, vs->h, vs->bytesPerPixel);
|
||||
break;
|
||||
default:
|
||||
// Alternative russian freddi3 uses badly formatted bitmaps
|
||||
|
@ -1941,12 +1973,12 @@ void Gdi::drawBMAPObject(const byte *ptr, VirtScreen *vs, int obj, int x, int y,
|
|||
assert(bmap_ptr);
|
||||
|
||||
byte code = *bmap_ptr++;
|
||||
int scrX = _vm->_screenStartStrip * 8;
|
||||
int scrX = _vm->_screenStartStrip * 8 * _vm->_bitDepth;
|
||||
|
||||
if (code == 8 || code == 9) {
|
||||
Common::Rect rScreen(0, 0, vs->w, vs->h);
|
||||
byte *dst = (byte *)_vm->_virtscr[kMainVirtScreen].backBuf + scrX;
|
||||
Wiz::copyWizImage(dst, bmap_ptr, vs->w, vs->h, x - scrX, y, w, h, &rScreen);
|
||||
Wiz::copyWizImage(dst, bmap_ptr, vs->pitch, kDstScreen, vs->w, vs->h, x - scrX, y, w, h, &rScreen, 0, 0, 0, _vm->_bitDepth);
|
||||
}
|
||||
|
||||
Common::Rect rect1(x, y, x + w, y + h);
|
||||
|
@ -1996,7 +2028,7 @@ void ScummEngine_v70he::restoreBackgroundHE(Common::Rect rect, int dirtybit) {
|
|||
|
||||
assert(rw <= _screenWidth && rw > 0);
|
||||
assert(rh <= _screenHeight && rh > 0);
|
||||
blit(dst, _virtscr[kMainVirtScreen].pitch, src, _virtscr[kMainVirtScreen].pitch, rw, rh);
|
||||
blit(dst, _virtscr[kMainVirtScreen].pitch, src, _virtscr[kMainVirtScreen].pitch, rw, rh, vs->bytesPerPixel);
|
||||
markRectAsDirty(kMainVirtScreen, rect, dirtybit);
|
||||
}
|
||||
#endif
|
||||
|
@ -2026,15 +2058,15 @@ void Gdi::resetBackground(int top, int bottom, int strip) {
|
|||
if (bottom > vs->bdirty[strip])
|
||||
vs->bdirty[strip] = bottom;
|
||||
|
||||
bgbak_ptr = (byte *)vs->backBuf + top * vs->pitch + (strip + vs->xstart/8) * 8;
|
||||
backbuff_ptr = (byte *)vs->pixels + top * vs->pitch + (strip + vs->xstart/8) * 8;
|
||||
bgbak_ptr = (byte *)vs->backBuf + top * vs->pitch + (strip + vs->xstart/8) * 8 * vs->bytesPerPixel;
|
||||
backbuff_ptr = (byte *)vs->pixels + top * vs->pitch + (strip + vs->xstart/8) * 8 * vs->bytesPerPixel;
|
||||
|
||||
numLinesToProcess = bottom - top;
|
||||
if (numLinesToProcess) {
|
||||
if (_vm->isLightOn()) {
|
||||
copy8Col(backbuff_ptr, vs->pitch, bgbak_ptr, numLinesToProcess);
|
||||
copy8Col(backbuff_ptr, vs->pitch, bgbak_ptr, numLinesToProcess, vs->bytesPerPixel);
|
||||
} else {
|
||||
clear8Col(backbuff_ptr, vs->pitch, numLinesToProcess);
|
||||
clear8Col(backbuff_ptr, vs->pitch, numLinesToProcess, vs->bytesPerPixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2785,12 +2817,12 @@ void Gdi::drawStripHE(byte *dst, int dstPitch, const byte *src, int width, int h
|
|||
int x = width;
|
||||
while (1) {
|
||||
if (!transpCheck || color != _transparentColor)
|
||||
*dst = _roomPalette[color];
|
||||
dst++;
|
||||
writeRoomColor(dst, color);
|
||||
dst += _vm->_bitDepth;
|
||||
--x;
|
||||
if (x == 0) {
|
||||
x = width;
|
||||
dst += dstPitch - width;
|
||||
dst += dstPitch - width * _vm->_bitDepth;
|
||||
--height;
|
||||
if (height == 0)
|
||||
return;
|
||||
|
@ -2874,8 +2906,8 @@ void Gdi::drawStripComplex(byte *dst, int dstPitch, const byte *src, int height,
|
|||
do {
|
||||
FILL_BITS;
|
||||
if (!transpCheck || color != _transparentColor)
|
||||
*dst = _roomPalette[color] + _paletteMod;
|
||||
dst++;
|
||||
writeRoomColor(dst, color);
|
||||
dst += _vm->_bitDepth;
|
||||
|
||||
againPos:
|
||||
if (!READ_BIT) {
|
||||
|
@ -2896,13 +2928,13 @@ void Gdi::drawStripComplex(byte *dst, int dstPitch, const byte *src, int height,
|
|||
do {
|
||||
if (!--x) {
|
||||
x = 8;
|
||||
dst += dstPitch - 8;
|
||||
dst += dstPitch - 8 * _vm->_bitDepth;
|
||||
if (!--height)
|
||||
return;
|
||||
}
|
||||
if (!transpCheck || color != _transparentColor)
|
||||
*dst = _roomPalette[color] + _paletteMod;
|
||||
dst++;
|
||||
writeRoomColor(dst, color);
|
||||
dst += _vm->_bitDepth;
|
||||
} while (--reps);
|
||||
bits >>= 8;
|
||||
bits |= (*src++) << (cl - 8);
|
||||
|
@ -2910,7 +2942,7 @@ void Gdi::drawStripComplex(byte *dst, int dstPitch, const byte *src, int height,
|
|||
}
|
||||
}
|
||||
} while (--x);
|
||||
dst += dstPitch - 8;
|
||||
dst += dstPitch - 8 * _vm->_bitDepth;
|
||||
} while (--height);
|
||||
}
|
||||
|
||||
|
@ -2926,8 +2958,8 @@ void Gdi::drawStripBasicH(byte *dst, int dstPitch, const byte *src, int height,
|
|||
do {
|
||||
FILL_BITS;
|
||||
if (!transpCheck || color != _transparentColor)
|
||||
*dst = _roomPalette[color] + _paletteMod;
|
||||
dst++;
|
||||
writeRoomColor(dst, color);
|
||||
dst += _vm->_bitDepth;
|
||||
if (!READ_BIT) {
|
||||
} else if (!READ_BIT) {
|
||||
FILL_BITS;
|
||||
|
@ -2942,7 +2974,7 @@ void Gdi::drawStripBasicH(byte *dst, int dstPitch, const byte *src, int height,
|
|||
color += inc;
|
||||
}
|
||||
} while (--x);
|
||||
dst += dstPitch - 8;
|
||||
dst += dstPitch - 8 * _vm->_bitDepth;
|
||||
} while (--height);
|
||||
}
|
||||
|
||||
|
@ -2959,7 +2991,7 @@ void Gdi::drawStripBasicV(byte *dst, int dstPitch, const byte *src, int height,
|
|||
do {
|
||||
FILL_BITS;
|
||||
if (!transpCheck || color != _transparentColor)
|
||||
*dst = _roomPalette[color] + _paletteMod;
|
||||
writeRoomColor(dst, color);
|
||||
dst += dstPitch;
|
||||
if (!READ_BIT) {
|
||||
} else if (!READ_BIT) {
|
||||
|
@ -3027,7 +3059,7 @@ void Gdi::drawStripRaw(byte *dst, int dstPitch, const byte *src, int height, con
|
|||
for (x = 0; x < 8; x ++) {
|
||||
byte color = *src++;
|
||||
if (!transpCheck || color != _transparentColor)
|
||||
dst[x] = _roomPalette[color] + _paletteMod;
|
||||
writeRoomColor(dst + x * _vm->_bitDepth, color);
|
||||
}
|
||||
dst += dstPitch;
|
||||
} while (--height);
|
||||
|
@ -3150,6 +3182,14 @@ void Gdi::unkDecode11(byte *dst, int dstPitch, const byte *src, int height) cons
|
|||
#undef NEXT_ROW
|
||||
#undef READ_BIT_256
|
||||
|
||||
void Gdi16Bit::writeRoomColor(byte *dst, byte color) const {
|
||||
WRITE_UINT16(dst, READ_LE_UINT16(_vm->_hePalettes + 2048 + color * 2));
|
||||
}
|
||||
|
||||
void Gdi::writeRoomColor(byte *dst, byte color) const {
|
||||
*dst = _roomPalette[color] + _paletteMod;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark --- Transition effects ---
|
||||
|
|
|
@ -155,11 +155,11 @@ struct VirtScreen : Graphics::Surface {
|
|||
}
|
||||
|
||||
byte *getPixels(int x, int y) const {
|
||||
return (byte *)pixels + xstart + y * pitch + x;
|
||||
return (byte *)pixels + y * pitch + (xstart + x) * bytesPerPixel;
|
||||
}
|
||||
|
||||
byte *getBackPixels(int x, int y) const {
|
||||
return (byte *)backBuf + xstart + y * pitch + x;
|
||||
return (byte *)backBuf + y * pitch + (xstart + x) * bytesPerPixel;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -215,6 +215,7 @@ protected:
|
|||
void drawStrip3DO(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const;
|
||||
|
||||
void drawStripHE(byte *dst, int dstPitch, const byte *src, int width, int height, const bool transpCheck) const;
|
||||
virtual void writeRoomColor(byte *dst, byte color) const;
|
||||
|
||||
/* Mask decompressors */
|
||||
void decompressTMSK(byte *dst, const byte *tmsk, const byte *src, int height) const;
|
||||
|
@ -361,6 +362,13 @@ public:
|
|||
virtual void roomChanged(byte *roomptr);
|
||||
};
|
||||
|
||||
class Gdi16Bit : public Gdi {
|
||||
protected:
|
||||
virtual void writeRoomColor(byte *dst, byte color) const;
|
||||
public:
|
||||
Gdi16Bit(ScummEngine *vm);
|
||||
};
|
||||
|
||||
} // End of namespace Scumm
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,6 +66,32 @@ int MoviePlayer::load(const char *filename, int flags, int image) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void MoviePlayer::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
|
||||
uint h = getHeight();
|
||||
uint w = getWidth();
|
||||
|
||||
byte *src = _videoFrameBuffer;
|
||||
|
||||
if (_vm->_game.features & GF_16BIT_COLOR) {
|
||||
dst += y * pitch + x * 2;
|
||||
do {
|
||||
for (uint i = 0; i < w; i++) {
|
||||
uint16 col = READ_LE_UINT16(_vm->_hePalettes + _vm->_hePaletteSlot + 768 + src[i] * 2);
|
||||
WRITE_UINT16(dst + i * 2, col);
|
||||
}
|
||||
dst += pitch;
|
||||
src += w;
|
||||
} while (--h);
|
||||
} else {
|
||||
dst += y * pitch + x;
|
||||
do {
|
||||
memcpy(dst, src, w);
|
||||
dst += pitch;
|
||||
src += w;
|
||||
} while (--h);
|
||||
}
|
||||
}
|
||||
|
||||
void MoviePlayer::handleNextFrame() {
|
||||
if (!isVideoLoaded()) {
|
||||
return;
|
||||
|
@ -80,14 +106,14 @@ void MoviePlayer::handleNextFrame() {
|
|||
assert(dstPtr);
|
||||
uint8 *dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0);
|
||||
assert(dst);
|
||||
copyFrameToBuffer(dst, 0, 0, _vm->_screenWidth);
|
||||
copyFrameToBuffer(dst, 0, 0, _vm->_screenWidth * _vm->_bitDepth);
|
||||
} else if (_flags & 1) {
|
||||
copyFrameToBuffer(pvs->getBackPixels(0, 0), 0, 0, _vm->_screenWidth);
|
||||
copyFrameToBuffer(pvs->getBackPixels(0, 0), 0, 0, pvs->pitch);
|
||||
|
||||
Common::Rect imageRect(getWidth(), getHeight());
|
||||
_vm->restoreBackgroundHE(imageRect);
|
||||
} else {
|
||||
copyFrameToBuffer(pvs->getPixels(0, 0), 0, 0, _vm->_screenWidth);
|
||||
copyFrameToBuffer(pvs->getPixels(0, 0), 0, 0, pvs->pitch);
|
||||
|
||||
Common::Rect imageRect(getWidth(), getHeight());
|
||||
_vm->markRectAsDirty(kMainVirtScreen, imageRect);
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
int getImageNum();
|
||||
int load(const char *filename, int flags, int image = 0);
|
||||
|
||||
void copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch);
|
||||
void handleNextFrame();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -458,6 +458,7 @@ protected:
|
|||
uint8 *getHEPaletteIndex(int palSlot);
|
||||
int getHEPaletteColor(int palSlot, int color);
|
||||
int getHEPaletteSimilarColor(int palSlot, int red, int green, int start, int end);
|
||||
int getHEPalette16BitColorComponent(int component, int type);
|
||||
int getHEPaletteColorComponent(int palSlot, int color, int component);
|
||||
void setHEPaletteColor(int palSlot, uint8 color, uint8 r, uint8 g, uint8 b);
|
||||
void setHEPaletteFromPtr(int palSlot, const uint8 *palData);
|
||||
|
@ -466,7 +467,7 @@ protected:
|
|||
void setHEPaletteFromRoom(int palSlot, int resId, int state);
|
||||
void restoreHEPalette(int palSlot);
|
||||
void copyHEPalette(int dstPalSlot, int srcPalSlot);
|
||||
void copyHEPaletteColor(int palSlot, uint8 dstColor, uint8 srcColor);
|
||||
void copyHEPaletteColor(int palSlot, uint8 dstColor, uint16 srcColor);
|
||||
|
||||
protected:
|
||||
/* HE version 90 script opcodes */
|
||||
|
|
|
@ -40,7 +40,7 @@ void ScummEngine_v71he::remapHEPalette(const uint8 *src, uint8 *dst) {
|
|||
src += 30;
|
||||
|
||||
if (_game.heversion >= 99) {
|
||||
palPtr = _hePalettes + 1024 + 30;
|
||||
palPtr = _hePalettes + _hePaletteSlot + 30;
|
||||
} else {
|
||||
palPtr = _currentPalette + 30;
|
||||
}
|
||||
|
@ -75,9 +75,9 @@ void ScummEngine_v71he::remapHEPalette(const uint8 *src, uint8 *dst) {
|
|||
uint8 *ScummEngine_v90he::getHEPaletteIndex(int palSlot) {
|
||||
if (palSlot) {
|
||||
assert(palSlot >= 1 && palSlot <= _numPalettes);
|
||||
return _hePalettes + palSlot * 1024;
|
||||
return _hePalettes + palSlot * _hePaletteSlot;
|
||||
} else {
|
||||
return _hePalettes + 1024;
|
||||
return _hePalettes + _hePaletteSlot;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ int ScummEngine_v90he::getHEPaletteSimilarColor(int palSlot, int red, int green,
|
|||
assertRange(0, start, 255, "start palette slot");
|
||||
assertRange(0, end, 255, "pend alette slot");
|
||||
|
||||
uint8 *pal = _hePalettes + palSlot * 1024 + start * 3;
|
||||
uint8 *pal = _hePalettes + palSlot * _hePaletteSlot + start * 3;
|
||||
|
||||
int bestsum = 0x7FFFFFFF;
|
||||
int bestitem = start;
|
||||
|
@ -107,39 +107,83 @@ int ScummEngine_v90he::getHEPaletteSimilarColor(int palSlot, int red, int green,
|
|||
return bestitem;
|
||||
}
|
||||
|
||||
int ScummEngine_v90he::getHEPalette16BitColorComponent(int component, int type) {
|
||||
uint16 col;
|
||||
if (type == 2) {
|
||||
col = (((component & 0xFFFF) >> 0) & 0x1F) << 3;;
|
||||
} else if (type == 1) {
|
||||
col = (((component & 0xFFFF) >> 5) & 0x1F) << 3;
|
||||
} else {
|
||||
col = (((component & 0xFFFF) >> 10) & 0x1F) << 3;
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
int ScummEngine_v90he::getHEPaletteColorComponent(int palSlot, int color, int component) {
|
||||
assertRange(1, palSlot, _numPalettes, "palette");
|
||||
assertRange(0, color, 255, "palette slot");
|
||||
|
||||
return _hePalettes[palSlot * 1024 + color * 3 + component % 3];
|
||||
return _hePalettes[palSlot * _hePaletteSlot + color * 3 + component % 3];
|
||||
}
|
||||
|
||||
int ScummEngine_v90he::getHEPaletteColor(int palSlot, int color) {
|
||||
assertRange(1, palSlot, _numPalettes, "palette");
|
||||
assertRange(0, color, 255, "palette slot");
|
||||
|
||||
return _hePalettes[palSlot * 1024 + 768 + color];
|
||||
if (_game.features & GF_16BIT_COLOR)
|
||||
return READ_LE_UINT16(_hePalettes + palSlot * _hePaletteSlot + 768 + color * 2);
|
||||
else
|
||||
return _hePalettes[palSlot * _hePaletteSlot + 768 + color];
|
||||
}
|
||||
|
||||
void ScummEngine_v90he::setHEPaletteColor(int palSlot, uint8 color, uint8 r, uint8 g, uint8 b) {
|
||||
debug(7, "setHEPaletteColor(%d, %d, %d, %d, %d)", palSlot, color, r, g, b);
|
||||
assertRange(1, palSlot, _numPalettes, "palette");
|
||||
uint8 *p = _hePalettes + palSlot * 1024 + color * 3;
|
||||
|
||||
uint8 *p = _hePalettes + palSlot * _hePaletteSlot + color * 3;
|
||||
*(p + 0) = r;
|
||||
*(p + 1) = g;
|
||||
*(p + 2) = b;
|
||||
_hePalettes[palSlot * 1024 + 768 + color] = color;
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
WRITE_LE_UINT16(_hePalettes + palSlot * _hePaletteSlot + 768 + color * 2, get16BitColor(r, g, b));
|
||||
} else {
|
||||
_hePalettes[palSlot * _hePaletteSlot + 768 + color] = color;
|
||||
}
|
||||
}
|
||||
|
||||
void ScummEngine_v90he::setHEPaletteFromPtr(int palSlot, const uint8 *palData) {
|
||||
assertRange(1, palSlot, _numPalettes, "palette");
|
||||
uint8 *pc = _hePalettes + palSlot * 1024;
|
||||
|
||||
uint8 *pc = _hePalettes + palSlot * _hePaletteSlot;
|
||||
uint8 *pi = pc + 768;
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
*pc++ = *palData++;
|
||||
*pc++ = *palData++;
|
||||
*pc++ = *palData++;
|
||||
*pi++ = i;
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
uint8 r = *pc++ = *palData++;
|
||||
uint8 g = *pc++ = *palData++;
|
||||
uint8 b = *pc++ = *palData++;
|
||||
WRITE_LE_UINT16(pi, get16BitColor(r, g, b)); pi += 2;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
*pc++ = *palData++;
|
||||
*pc++ = *palData++;
|
||||
*pc++ = *palData++;
|
||||
*pi++ = i;
|
||||
}
|
||||
}
|
||||
|
||||
int i;
|
||||
uint8 *palPtr = _hePalettes + palSlot * _hePaletteSlot + 768;
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
for (i = 0; i < 10; ++i)
|
||||
WRITE_LE_UINT16(palPtr + i * 2, i);
|
||||
for (i = 246; i < 256; ++i)
|
||||
WRITE_LE_UINT16(palPtr + i * 2, i);
|
||||
} else {
|
||||
for (i = 0; i < 10; ++i)
|
||||
*(palPtr + i) = i;
|
||||
for (i = 246; i < 256; ++i)
|
||||
*(palPtr + i) = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,8 +222,9 @@ void ScummEngine_v90he::setHEPaletteFromRoom(int palSlot, int resId, int state)
|
|||
void ScummEngine_v90he::restoreHEPalette(int palSlot) {
|
||||
debug(7, "restoreHEPalette(%d)", palSlot);
|
||||
assertRange(1, palSlot, _numPalettes, "palette");
|
||||
|
||||
if (palSlot != 1) {
|
||||
memcpy(_hePalettes + palSlot * 1024, _hePalettes + 1024, 1024);
|
||||
memcpy(_hePalettes + palSlot * _hePaletteSlot, _hePalettes + _hePaletteSlot, _hePaletteSlot);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,18 +232,27 @@ void ScummEngine_v90he::copyHEPalette(int dstPalSlot, int srcPalSlot) {
|
|||
debug(7, "copyHEPalette(%d, %d)", dstPalSlot, srcPalSlot);
|
||||
assert(dstPalSlot >= 1 && dstPalSlot <= _numPalettes);
|
||||
assert(srcPalSlot >= 1 && srcPalSlot <= _numPalettes);
|
||||
|
||||
if (dstPalSlot != srcPalSlot) {
|
||||
memcpy(_hePalettes + dstPalSlot * 1024, _hePalettes + srcPalSlot * 1024, 1024);
|
||||
memcpy(_hePalettes + dstPalSlot * _hePaletteSlot, _hePalettes + srcPalSlot * _hePaletteSlot, _hePaletteSlot);
|
||||
}
|
||||
}
|
||||
|
||||
void ScummEngine_v90he::copyHEPaletteColor(int palSlot, uint8 dstColor, uint8 srcColor) {
|
||||
void ScummEngine_v90he::copyHEPaletteColor(int palSlot, uint8 dstColor, uint16 srcColor) {
|
||||
debug(7, "copyHEPaletteColor(%d, %d, %d)", palSlot, dstColor, srcColor);
|
||||
assertRange(1, palSlot, _numPalettes, "palette");
|
||||
uint8 *dstPal = _hePalettes + palSlot * 1024 + dstColor * 3;
|
||||
uint8 *srcPal = _hePalettes + 1024 + srcColor * 3;
|
||||
memcpy(dstPal, srcPal, 3);
|
||||
_hePalettes[palSlot * 1024 + 768 + dstColor] = srcColor;
|
||||
|
||||
uint8 *dstPal = _hePalettes + palSlot * _hePaletteSlot + dstColor * 3;
|
||||
uint8 *srcPal = _hePalettes + _hePaletteSlot + srcColor * 3;
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
dstPal[0] = (srcColor >> 10) << 3;
|
||||
dstPal[1] = (srcColor >> 5) << 3;
|
||||
dstPal[2] = (srcColor >> 0) << 3;
|
||||
WRITE_LE_UINT16(_hePalettes + palSlot * _hePaletteSlot + 768 + dstColor * 2, srcColor);
|
||||
} else {
|
||||
memcpy(dstPal, srcPal, 3);
|
||||
_hePalettes[palSlot * _hePaletteSlot + 768 + dstColor] = srcColor;
|
||||
}
|
||||
}
|
||||
|
||||
void ScummEngine_v99he::setPaletteFromPtr(const byte *ptr, int numcolor) {
|
||||
|
@ -211,7 +265,7 @@ void ScummEngine_v99he::setPaletteFromPtr(const byte *ptr, int numcolor) {
|
|||
|
||||
assertRange(0, numcolor, 256, "setPaletteFromPtr: numcolor");
|
||||
|
||||
dest = _hePalettes + 1024;
|
||||
dest = _hePalettes + _hePaletteSlot;
|
||||
|
||||
for (i = 0; i < numcolor; i++) {
|
||||
r = *ptr++;
|
||||
|
@ -222,48 +276,63 @@ void ScummEngine_v99he::setPaletteFromPtr(const byte *ptr, int numcolor) {
|
|||
*dest++ = r;
|
||||
*dest++ = g;
|
||||
*dest++ = b;
|
||||
_hePalettes[1792 + i] = i;
|
||||
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
WRITE_LE_UINT16(_hePalettes + 2048 + i * 2, get16BitColor(r, g, b));
|
||||
} else {
|
||||
_hePalettes[1792 + i] = i;
|
||||
}
|
||||
} else {
|
||||
dest += 3;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(_hePalettes, _hePalettes + 1024, 768);
|
||||
|
||||
for (i = 0; i < 10; ++i)
|
||||
_hePalettes[1792 + i] = i;
|
||||
for (i = 246; i < 256; ++i)
|
||||
_hePalettes[1792 + i] = i;
|
||||
memcpy(_hePalettes, _hePalettes + _hePaletteSlot, 768);
|
||||
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
for (i = 0; i < 10; ++i)
|
||||
WRITE_LE_UINT16(_hePalettes + 2048 + i * 2, i);
|
||||
for (i = 246; i < 256; ++i)
|
||||
WRITE_LE_UINT16(_hePalettes + 2048 + i * 2, i);
|
||||
} else {
|
||||
for (i = 0; i < 10; ++i)
|
||||
_hePalettes[1792 + i] = i;
|
||||
for (i = 246; i < 256; ++i)
|
||||
_hePalettes[1792 + i] = i;
|
||||
}
|
||||
setDirtyColors(0, numcolor - 1);
|
||||
}
|
||||
|
||||
void ScummEngine_v99he::darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor) {
|
||||
uint8 *src, *dst;
|
||||
int color, j;
|
||||
int j, r, g, b;
|
||||
|
||||
src = _hePalettes + startColor * 3;
|
||||
dst = _hePalettes + 1024 + startColor * 3;
|
||||
dst = _hePalettes + _hePaletteSlot + startColor * 3;
|
||||
for (j = startColor; j <= endColor; j++) {
|
||||
color = *src++;
|
||||
color = color * redScale / 0xFF;
|
||||
if (color > 255)
|
||||
color = 255;
|
||||
*dst++ = color;
|
||||
r = *src++;
|
||||
r = r * redScale / 0xFF;
|
||||
if (r > 255)
|
||||
r = 255;
|
||||
*dst++ = r;
|
||||
|
||||
color = *src++;
|
||||
color = color * greenScale / 0xFF;
|
||||
if (color > 255)
|
||||
color = 255;
|
||||
*dst++ = color;
|
||||
g = *src++;
|
||||
g = g * greenScale / 0xFF;
|
||||
if (g > 255)
|
||||
g = 255;
|
||||
*dst++ = g;
|
||||
|
||||
color = *src++;
|
||||
color = color * blueScale / 0xFF;
|
||||
if (color > 255)
|
||||
color = 255;
|
||||
*dst++ = color;
|
||||
b = *src++;
|
||||
b = b * blueScale / 0xFF;
|
||||
if (b > 255)
|
||||
b = 255;
|
||||
*dst++ = b;
|
||||
|
||||
_hePalettes[1792 + j] = j;
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
WRITE_LE_UINT16(_hePalettes + 2048 + j * 2, get16BitColor(r, g, b));
|
||||
} else {
|
||||
_hePalettes[1792 + j] = j;
|
||||
}
|
||||
setDirtyColors(j, endColor);
|
||||
}
|
||||
}
|
||||
|
@ -274,26 +343,39 @@ void ScummEngine_v99he::copyPalColor(int dst, int src) {
|
|||
if ((uint) dst >= 256 || (uint) src >= 256)
|
||||
error("copyPalColor: invalid values, %d, %d", dst, src);
|
||||
|
||||
dp = &_hePalettes[1024 + dst * 3];
|
||||
sp = &_hePalettes[1024 + src * 3];
|
||||
dp = &_hePalettes[_hePaletteSlot + dst * 3];
|
||||
sp = &_hePalettes[_hePaletteSlot + src * 3];
|
||||
|
||||
dp[0] = sp[0];
|
||||
dp[1] = sp[1];
|
||||
dp[2] = sp[2];
|
||||
_hePalettes[1792 + dst] = dst;
|
||||
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
WRITE_LE_UINT16(_hePalettes + 2048 + dst * 2, get16BitColor(sp[0], sp[1], sp[2]));
|
||||
} else {
|
||||
_hePalettes[1792 + dst] = dst;
|
||||
}
|
||||
|
||||
setDirtyColors(dst, dst);
|
||||
}
|
||||
|
||||
void ScummEngine_v99he::setPalColor(int idx, int r, int g, int b) {
|
||||
_hePalettes[1024 + idx * 3 + 0] = r;
|
||||
_hePalettes[1024 + idx * 3 + 1] = g;
|
||||
_hePalettes[1024 + idx * 3 + 2] = b;
|
||||
_hePalettes[1792 + idx] = idx;
|
||||
_hePalettes[_hePaletteSlot + idx * 3 + 0] = r;
|
||||
_hePalettes[_hePaletteSlot + idx * 3 + 1] = g;
|
||||
_hePalettes[_hePaletteSlot + idx * 3 + 2] = b;
|
||||
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
WRITE_LE_UINT16(_hePalettes + 2048 + idx * 2, get16BitColor(r, g, b));
|
||||
} else {
|
||||
_hePalettes[1792 + idx] = idx;
|
||||
}
|
||||
setDirtyColors(idx, idx);
|
||||
}
|
||||
|
||||
void ScummEngine_v99he::updatePalette() {
|
||||
if (_game.features & GF_16BIT_COLOR)
|
||||
return;
|
||||
|
||||
if (_palDirtyMax == -1)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1576,7 +1576,10 @@ void ScummEngine_v100he::o100_roomOps() {
|
|||
case 130:
|
||||
a = pop();
|
||||
b = pop();
|
||||
copyPalColor(a, b);
|
||||
if (_game.features & GF_16BIT_COLOR)
|
||||
copyHEPaletteColor(1, a, b);
|
||||
else
|
||||
copyPalColor(a, b);
|
||||
break;
|
||||
|
||||
case 131: // SO_ROOM_FADE
|
||||
|
@ -2153,8 +2156,9 @@ void ScummEngine_v100he::o100_systemOps() {
|
|||
}
|
||||
|
||||
void ScummEngine_v100he::o100_cursorCommand() {
|
||||
int a, i;
|
||||
int a, b, i;
|
||||
int args[16];
|
||||
|
||||
byte subOp = fetchScriptByte();
|
||||
|
||||
switch (subOp) {
|
||||
|
@ -2169,12 +2173,12 @@ void ScummEngine_v100he::o100_cursorCommand() {
|
|||
case 0x80:
|
||||
case 0x81:
|
||||
a = pop();
|
||||
_wiz->loadWizCursor(a);
|
||||
_wiz->loadWizCursor(a, 0);
|
||||
break;
|
||||
case 0x82:
|
||||
pop();
|
||||
b = pop();
|
||||
a = pop();
|
||||
_wiz->loadWizCursor(a);
|
||||
_wiz->loadWizCursor(a, b);
|
||||
break;
|
||||
case 0x86: // SO_CURSOR_ON Turn cursor on
|
||||
_cursor.state = 1;
|
||||
|
@ -2577,7 +2581,8 @@ void ScummEngine_v100he::o100_getWizData() {
|
|||
}
|
||||
|
||||
void ScummEngine_v100he::o100_getPaletteData() {
|
||||
int b, c, d, e;
|
||||
int c, d, e;
|
||||
int r, g, b;
|
||||
int palSlot, color;
|
||||
|
||||
byte subOp = fetchScriptByte();
|
||||
|
@ -2586,7 +2591,10 @@ void ScummEngine_v100he::o100_getPaletteData() {
|
|||
case 13:
|
||||
c = pop();
|
||||
b = pop();
|
||||
push(getHEPaletteColorComponent(1, b, c));
|
||||
if (_game.features & GF_16BIT_COLOR)
|
||||
push(getHEPalette16BitColorComponent(b, c));
|
||||
else
|
||||
push(getHEPaletteColorComponent(1, b, c));
|
||||
break;
|
||||
case 20:
|
||||
color = pop();
|
||||
|
@ -2597,20 +2605,26 @@ void ScummEngine_v100he::o100_getPaletteData() {
|
|||
e = pop();
|
||||
d = pop();
|
||||
palSlot = pop();
|
||||
pop();
|
||||
c = pop();
|
||||
b = pop();
|
||||
push(getHEPaletteSimilarColor(palSlot, b, c, d, e));
|
||||
g = pop();
|
||||
r = pop();
|
||||
push(getHEPaletteSimilarColor(palSlot, r, g, d, e));
|
||||
break;
|
||||
case 53:
|
||||
pop();
|
||||
c = pop();
|
||||
c = MAX(0, c);
|
||||
c = MIN(c, 255);
|
||||
b = pop();
|
||||
b = MAX(0, b);
|
||||
b = MIN(b, 255);
|
||||
push(getHEPaletteSimilarColor(1, b, c, 10, 245));
|
||||
g = pop();
|
||||
g = MAX(0, g);
|
||||
g = MIN(g, 255);
|
||||
r = pop();
|
||||
r = MAX(0, r);
|
||||
r = MIN(r, 255);
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
push(get16BitColor(r, g, b));
|
||||
} else {
|
||||
push(getHEPaletteSimilarColor(1, r, g, 10, 245));
|
||||
}
|
||||
break;
|
||||
case 73:
|
||||
c = pop();
|
||||
|
|
|
@ -122,6 +122,8 @@ int ScummEngine_v60he::convertFilePath(byte *dst, int dstSize) {
|
|||
} else if (dst[0] == '.' && dst[1] == '/') { // Game Data Path
|
||||
// The default game data path is set to './' by ScummVM
|
||||
r = 2;
|
||||
} else if (dst[2] == 'b' && dst[5] == 'k') { // Backyard Basketball INI
|
||||
r = 13;
|
||||
} else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (HE72 - HE100)
|
||||
// The default save game path is set to '*/' by ScummVM
|
||||
r = 2;
|
||||
|
|
|
@ -1484,6 +1484,7 @@ void ScummEngine_v72he::o72_readFile() {
|
|||
fetchScriptByte();
|
||||
size = pop();
|
||||
slot = pop();
|
||||
assert(_hInFileTable[slot]);
|
||||
val = readFileToArray(slot, size);
|
||||
push(val);
|
||||
break;
|
||||
|
@ -1573,7 +1574,7 @@ void ScummEngine_v72he::o72_rename() {
|
|||
}
|
||||
|
||||
void ScummEngine_v72he::o72_getPixel() {
|
||||
byte area;
|
||||
uint16 area;
|
||||
|
||||
int y = pop();
|
||||
int x = pop();
|
||||
|
@ -1588,11 +1589,17 @@ void ScummEngine_v72he::o72_getPixel() {
|
|||
switch (subOp) {
|
||||
case 9: // HE 100
|
||||
case 218:
|
||||
area = *vs->getBackPixels(x, y - vs->topline);
|
||||
if (_game.features & GF_16BIT_COLOR)
|
||||
area = READ_UINT16(vs->getBackPixels(x, y - vs->topline));
|
||||
else
|
||||
area = *vs->getBackPixels(x, y - vs->topline);
|
||||
break;
|
||||
case 8: // HE 100
|
||||
case 219:
|
||||
area = *vs->getPixels(x, y - vs->topline);
|
||||
if (_game.features & GF_16BIT_COLOR)
|
||||
area = READ_UINT16(vs->getPixels(x, y - vs->topline));
|
||||
else
|
||||
area = *vs->getPixels(x, y - vs->topline);
|
||||
break;
|
||||
default:
|
||||
error("o72_getPixel: default case %d", subOp);
|
||||
|
@ -1805,9 +1812,7 @@ void ScummEngine_v72he::o72_readINI() {
|
|||
switch (subOp) {
|
||||
case 43: // HE 100
|
||||
case 6: // number
|
||||
if (!strcmp((char *)option, "NoFontsInstalled")) {
|
||||
push(1);
|
||||
} else if (!strcmp((char *)option, "NoPrinting")) {
|
||||
if (!strcmp((char *)option, "NoPrinting")) {
|
||||
push(1);
|
||||
} else if (!strcmp((char *)option, "TextOn")) {
|
||||
push(ConfMan.getBool("subtitles"));
|
||||
|
|
|
@ -243,7 +243,7 @@ void ScummEngine_v80he::o80_writeConfigFile() {
|
|||
}
|
||||
|
||||
void ScummEngine_v80he::o80_cursorCommand() {
|
||||
int a, i;
|
||||
int a, b, i;
|
||||
int args[16];
|
||||
|
||||
byte subOp = fetchScriptByte();
|
||||
|
@ -252,12 +252,12 @@ void ScummEngine_v80he::o80_cursorCommand() {
|
|||
case 0x13:
|
||||
case 0x14:
|
||||
a = pop();
|
||||
_wiz->loadWizCursor(a);
|
||||
_wiz->loadWizCursor(a, 0);
|
||||
break;
|
||||
case 0x3C:
|
||||
pop();
|
||||
b = pop();
|
||||
a = pop();
|
||||
_wiz->loadWizCursor(a);
|
||||
_wiz->loadWizCursor(a, b);
|
||||
break;
|
||||
case 0x90: // SO_CURSOR_ON Turn cursor on
|
||||
_cursor.state = 1;
|
||||
|
|
|
@ -1255,7 +1255,7 @@ void ScummEngine_v90he::o90_setSpriteGroupInfo() {
|
|||
|
||||
void ScummEngine_v90he::o90_getWizData() {
|
||||
byte filename[4096];
|
||||
int state, resId;
|
||||
int resId, state, type;
|
||||
int32 w, h;
|
||||
int32 x, y;
|
||||
|
||||
|
@ -1319,9 +1319,10 @@ void ScummEngine_v90he::o90_getWizData() {
|
|||
push(computeWizHistogram(resId, state, x, y, w, h));
|
||||
break;
|
||||
case 139:
|
||||
pop();
|
||||
pop();
|
||||
push(0);
|
||||
type = pop();
|
||||
state = pop();
|
||||
resId = pop();
|
||||
push(_wiz->getWizImageData(resId, state, type));
|
||||
break;
|
||||
case 141:
|
||||
pop();
|
||||
|
@ -2101,7 +2102,8 @@ void ScummEngine_v90he::o90_getObjectData() {
|
|||
}
|
||||
|
||||
void ScummEngine_v90he::o90_getPaletteData() {
|
||||
int b, c, d, e;
|
||||
int c, d, e;
|
||||
int r, g, b;
|
||||
int palSlot, color;
|
||||
|
||||
byte subOp = fetchScriptByte();
|
||||
|
@ -2111,10 +2113,10 @@ void ScummEngine_v90he::o90_getPaletteData() {
|
|||
e = pop();
|
||||
d = pop();
|
||||
palSlot = pop();
|
||||
pop();
|
||||
c = pop();
|
||||
b = pop();
|
||||
push(getHEPaletteSimilarColor(palSlot, b, c, d, e));
|
||||
g = pop();
|
||||
r = pop();
|
||||
push(getHEPaletteSimilarColor(palSlot, r, g, d, e));
|
||||
break;
|
||||
case 52:
|
||||
c = pop();
|
||||
|
@ -2130,17 +2132,27 @@ void ScummEngine_v90he::o90_getPaletteData() {
|
|||
case 132:
|
||||
c = pop();
|
||||
b = pop();
|
||||
push(getHEPaletteColorComponent(1, b, c));
|
||||
if (_game.features & GF_16BIT_COLOR)
|
||||
push(getHEPalette16BitColorComponent(b, c));
|
||||
else
|
||||
push(getHEPaletteColorComponent(1, b, c));
|
||||
break;
|
||||
case 217:
|
||||
pop();
|
||||
c = pop();
|
||||
c = MAX(0, c);
|
||||
c = MIN(c, 255);
|
||||
b = pop();
|
||||
b = MAX(0, b);
|
||||
b = MIN(b, 255);
|
||||
push(getHEPaletteSimilarColor(1, b, c, 10, 245));
|
||||
g = pop();
|
||||
g = MAX(0, g);
|
||||
g = MIN(g, 255);
|
||||
r = pop();
|
||||
r = MAX(0, r);
|
||||
r = MIN(r, 255);
|
||||
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
push(get16BitColor(r, g, b));
|
||||
} else {
|
||||
push(getHEPaletteSimilarColor(1, r, g, 10, 245));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error("o90_getPaletteData: Unknown case %d", subOp);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -142,6 +142,12 @@ enum {
|
|||
kWizCopy
|
||||
};
|
||||
|
||||
enum DstSurface {
|
||||
kDstScreen = 0,
|
||||
kDstMemory = 1,
|
||||
kDstResource = 2
|
||||
};
|
||||
|
||||
class ScummEngine_v71he;
|
||||
|
||||
class Wiz {
|
||||
|
@ -188,27 +194,37 @@ public:
|
|||
void flushWizBuffer();
|
||||
|
||||
void getWizImageSpot(int resId, int state, int32 &x, int32 &y);
|
||||
void loadWizCursor(int resId);
|
||||
void loadWizCursor(int resId, int palette);
|
||||
|
||||
void captureWizImage(int resNum, const Common::Rect& r, bool frontBuffer, int compType);
|
||||
void captureImage(uint8 *src, int srcPitch, int srcw, int srch, int resNum, const Common::Rect& r, int compType);
|
||||
void captureWizPolygon(int resNum, int maskNum, int maskState, int id1, int id2, int compType);
|
||||
void displayWizComplexImage(const WizParameters *params);
|
||||
void displayWizImage(WizImage *pwi);
|
||||
void processWizImage(const WizParameters *params);
|
||||
|
||||
uint8 *drawWizImage(int resNum, int state, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, int palette);
|
||||
uint8 *drawWizImage(int resNum, int state, int maskNum, int maskState, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr);
|
||||
void drawWizPolygon(int resNum, int state, int id, int flags, int shadow, int dstResNum, int palette);
|
||||
void drawWizComplexPolygon(int resNum, int state, int po_x, int po_y, int shadow, int angle, int zoom, const Common::Rect *r, int flags, int dstResNum, int palette);
|
||||
void drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int flags, int shadow, int dstResNum, int palette);
|
||||
void drawWizPolygonImage(uint8 *dst, const uint8 *src, const uint8 *mask, int dstpitch, int dstType, int dstw, int dsth, int wizW, int wizH, Common::Rect &bound, Common::Point *wp, uint8 bitDepth);
|
||||
|
||||
static void copyMaskWizImage(uint8 *dst, const uint8 *src, const uint8 *mask, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr);
|
||||
|
||||
static void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, uint8 bitdepth);
|
||||
static void copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstPitch, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int maskT, int maskP);
|
||||
static void copyWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitdepth);
|
||||
static void copyRawWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor, uint8 bitdepth);
|
||||
static void copy16BitWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *xmapPtr);
|
||||
static void copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, int transColor);
|
||||
template<int type> static void decompress16BitWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *xmapPtr = NULL);
|
||||
template<int type> static void decompressWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitdepth);
|
||||
template<int type> static void decompressRawWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, int srcPitch, int w, int h, int transColor, const uint8 *palPtr, uint8 bitdepth);
|
||||
|
||||
template<int type> static void write16BitColor(uint8 *dst, const uint8 *src, int dstType, const uint8 *xmapPtr);
|
||||
template<int type> static void write8BitColor(uint8 *dst, const uint8 *src, int dstType, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth);
|
||||
static void writeColor(uint8 *dstPtr, int dstType, uint16 color);
|
||||
|
||||
static void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch);
|
||||
static void copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags = 0, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
|
||||
static void copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int maskT, int maskP);
|
||||
void copy16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags = 0, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
|
||||
static void copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor);
|
||||
void copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor);
|
||||
template<int type> static void decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
|
||||
template<int type> void decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
|
||||
template<int type> static void decompressRawWizImage(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h, int transColor, const uint8 *palPtr = NULL);
|
||||
int isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h, uint8 bitdepth);
|
||||
uint16 getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 bitDepth, uint16 color);
|
||||
uint16 getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 bitDepth, uint16 color);
|
||||
|
|
|
@ -33,6 +33,27 @@
|
|||
|
||||
namespace Scumm {
|
||||
|
||||
uint8 *ScummEngine::getHEPaletteSlot(uint16 palSlot) {
|
||||
assertRange(0, palSlot, _numPalettes, "palette");
|
||||
|
||||
if (_game.heversion >= 99) {
|
||||
if (palSlot)
|
||||
return _hePalettes + palSlot * _hePaletteSlot + 768;
|
||||
else
|
||||
return _hePalettes + _hePaletteSlot + 768;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint16 ScummEngine::get16BitColor(uint8 r, uint8 g, uint8 b) {
|
||||
uint16 ar = (r >> 3) << 10;
|
||||
uint16 ag = (g >> 3) << 5;
|
||||
uint16 ab = (b >> 3) << 0;
|
||||
uint16 col = ar | ag | ab;
|
||||
return col;
|
||||
}
|
||||
|
||||
void ScummEngine::resetPalette() {
|
||||
if (_game.version <= 1) {
|
||||
if (_game.platform == Common::kPlatformApple2GS) {
|
||||
|
@ -310,9 +331,6 @@ void ScummEngine::setDirtyColors(int min, int max) {
|
|||
_palDirtyMin = min;
|
||||
if (_palDirtyMax < max)
|
||||
_palDirtyMax = max;
|
||||
|
||||
if (_hePaletteCache)
|
||||
memset(_hePaletteCache, -1, 65536);
|
||||
}
|
||||
|
||||
void ScummEngine::initCycl(const byte *ptr) {
|
||||
|
@ -799,16 +817,6 @@ void ScummEngine_v8::desaturatePalette(int hueScale, int satScale, int lightScal
|
|||
#endif
|
||||
|
||||
|
||||
int ScummEngine::convert16BitColor(uint16 color, uint8 r, uint8 g, uint8 b) {
|
||||
// HACK: Find the closest matching color, and store in
|
||||
// cache for faster access.
|
||||
if (_hePaletteCache[color] == -1) {
|
||||
_hePaletteCache[color] = remapPaletteColor(r, g, b, -1);
|
||||
}
|
||||
|
||||
return _hePaletteCache[color];
|
||||
}
|
||||
|
||||
int ScummEngine::remapPaletteColor(int r, int g, int b, int threshold) {
|
||||
byte *pal;
|
||||
int ar, ag, ab, i;
|
||||
|
|
|
@ -919,7 +919,11 @@ bool ScummEngine::isResourceInUse(int type, int i) const {
|
|||
case rtCostume:
|
||||
return isCostumeInUse(i);
|
||||
case rtSound:
|
||||
return _sound->isSoundInUse(i);
|
||||
// Sound resource 1 is used for queued speech
|
||||
if (_game.heversion >= 60 && i == 1)
|
||||
return true;
|
||||
else
|
||||
return _sound->isSoundInUse(i);
|
||||
case rtCharset:
|
||||
return _charset->getCurID() == i;
|
||||
case rtImage:
|
||||
|
|
|
@ -1553,7 +1553,7 @@ void ScummEngine_v90he::saveOrLoad(Serializer *s) {
|
|||
void ScummEngine_v99he::saveOrLoad(Serializer *s) {
|
||||
ScummEngine_v90he::saveOrLoad(s);
|
||||
|
||||
s->saveLoadArrayOf(_hePalettes, (_numPalettes + 1) * 1024, sizeof(_hePalettes[0]), sleUint8);
|
||||
s->saveLoadArrayOf(_hePalettes, (_numPalettes + 1) * _hePaletteSlot, sizeof(_hePalettes[0]), sleUint8);
|
||||
}
|
||||
|
||||
void ScummEngine_v100he::saveOrLoad(Serializer *s) {
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace Scumm {
|
|||
* only saves/loads those which are valid for the version of the savegame
|
||||
* which is being loaded/saved currently.
|
||||
*/
|
||||
#define CURRENT_VER 79
|
||||
#define CURRENT_VER 80
|
||||
|
||||
/**
|
||||
* An auxillary macro, used to specify savegame versions. We use this instead
|
||||
|
|
|
@ -110,7 +110,9 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
|
|||
_currentScript(0xFF), // Let debug() work on init stage
|
||||
_messageDialog(0), _pauseDialog(0), _scummMenuDialog(0), _versionDialog(0) {
|
||||
|
||||
if (_game.platform == Common::kPlatformNES) {
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
_gdi = new Gdi16Bit(this);
|
||||
} else if (_game.platform == Common::kPlatformNES) {
|
||||
_gdi = new GdiNES(this);
|
||||
} else if (_game.version <= 1) {
|
||||
_gdi = new GdiV1(this);
|
||||
|
@ -251,6 +253,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
|
|||
_switchRoomEffect2 = 0;
|
||||
_switchRoomEffect = 0;
|
||||
|
||||
_bitDepth = 0;
|
||||
_doEffect = false;
|
||||
_snapScroll = false;
|
||||
_currentLights = 0;
|
||||
|
@ -267,8 +270,8 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
|
|||
_palManipPalette = NULL;
|
||||
_palManipIntermediatePal = NULL;
|
||||
memset(gfxUsageBits, 0, sizeof(gfxUsageBits));
|
||||
_hePaletteCache = NULL;
|
||||
_hePalettes = NULL;
|
||||
_hePaletteSlot = 0;
|
||||
_shadowPalette = NULL;
|
||||
_shadowPaletteSize = 0;
|
||||
memset(_currentPalette, 0, sizeof(_currentPalette));
|
||||
|
@ -523,9 +526,11 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
|
|||
_screenHeight = 200;
|
||||
}
|
||||
|
||||
_bitDepth = (_game.features & GF_16BIT_COLOR) ? 2 : 1;
|
||||
|
||||
// Allocate gfx compositing buffer (not needed for V7/V8 games).
|
||||
if (_game.version < 7)
|
||||
_compositeBuf = (byte *)malloc(_screenWidth * _screenHeight);
|
||||
_compositeBuf = (byte *)malloc(_screenWidth * _screenHeight * _bitDepth);
|
||||
else
|
||||
_compositeBuf = 0;
|
||||
|
||||
|
@ -830,7 +835,6 @@ ScummEngine_v90he::~ScummEngine_v90he() {
|
|||
delete _logicHE;
|
||||
}
|
||||
if (_game.heversion >= 99) {
|
||||
free(_hePaletteCache);
|
||||
free(_hePalettes);
|
||||
}
|
||||
}
|
||||
|
@ -1095,6 +1099,15 @@ Common::Error ScummEngine::init() {
|
|||
// CJK FT and DIG use usual NUT fonts, not FM-TOWNS ROM, so
|
||||
// there is no text surface for them. This takes that into account
|
||||
(_screenWidth * _textSurfaceMultiplier > 320));
|
||||
} else if (_game.features & GF_16BIT_COLOR) {
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
Graphics::PixelFormat format = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
|
||||
initGraphics(_screenWidth, _screenHeight, _screenWidth > 320, &format);
|
||||
if (format != _system->getScreenFormat())
|
||||
return Common::kUnsupportedColorMode;
|
||||
#else
|
||||
error("16bit color support is required for this game");
|
||||
#endif
|
||||
} else {
|
||||
initGraphics(_screenWidth, _screenHeight, _screenWidth > 320);
|
||||
}
|
||||
|
@ -1198,7 +1211,7 @@ void ScummEngine::setupScumm() {
|
|||
int maxHeapThreshold = -1;
|
||||
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
// 16Bit color games require double the memory, due to increased resource sizes.
|
||||
// 16bit color games require double the memory, due to increased resource sizes.
|
||||
maxHeapThreshold = 12 * 1024 * 1024;
|
||||
} else if (_game.features & GF_NEW_COSTUMES) {
|
||||
// Since the new costumes are very big, we increase the heap limit, to avoid having
|
||||
|
@ -1220,7 +1233,7 @@ void ScummEngine::setupScumm() {
|
|||
}
|
||||
|
||||
free(_compositeBuf);
|
||||
_compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier);
|
||||
_compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier * _bitDepth);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SCUMM_7_8
|
||||
|
@ -1562,11 +1575,9 @@ void ScummEngine_v99he::resetScumm() {
|
|||
|
||||
ScummEngine_v90he::resetScumm();
|
||||
|
||||
_hePaletteCache = (int16 *)malloc(65536);
|
||||
memset(_hePaletteCache, -1, 65536);
|
||||
|
||||
_hePalettes = (uint8 *)malloc((_numPalettes + 1) * 1024);
|
||||
memset(_hePalettes, 0, (_numPalettes + 1) * 1024);
|
||||
_hePaletteSlot = (_game.features & GF_16BIT_COLOR) ? 1280 : 1024;
|
||||
_hePalettes = (uint8 *)malloc((_numPalettes + 1) * _hePaletteSlot);
|
||||
memset(_hePalettes, 0, (_numPalettes + 1) * _hePaletteSlot);
|
||||
|
||||
// Array 129 is set to base name
|
||||
len = strlen(_filenamePattern.pattern);
|
||||
|
|
|
@ -963,6 +963,7 @@ public:
|
|||
int _screenTop;
|
||||
|
||||
Common::RenderMode _renderMode;
|
||||
uint8 _bitDepth;
|
||||
|
||||
protected:
|
||||
ColorCycle _colorCycle[16]; // Palette cycles
|
||||
|
@ -982,7 +983,10 @@ protected:
|
|||
byte animate, animateIndex;
|
||||
int8 state;
|
||||
} _cursor;
|
||||
byte _grabbedCursor[8192];
|
||||
|
||||
// HACK Double the array size to handle 16-bit images.
|
||||
// this should be dynamically allocated based on game depth instead.
|
||||
byte _grabbedCursor[16384];
|
||||
byte _currentCursor;
|
||||
|
||||
byte _newEffect, _switchRoomEffect2, _switchRoomEffect;
|
||||
|
@ -1048,7 +1052,8 @@ protected:
|
|||
virtual void palManipulateInit(int resID, int start, int end, int time);
|
||||
void palManipulate();
|
||||
public:
|
||||
int convert16BitColor(uint16 color, uint8 r, uint8 g, uint8 b);
|
||||
uint8 *getHEPaletteSlot(uint16 palSlot);
|
||||
uint16 get16BitColor(uint8 r, uint8 g, uint8 b);
|
||||
int remapPaletteColor(int r, int g, int b, int threshold); // Used by Actor::remapActorPalette
|
||||
protected:
|
||||
void moveMemInPalRes(int start, int end, byte direction);
|
||||
|
@ -1124,7 +1129,7 @@ public:
|
|||
// HE specific
|
||||
byte _HEV7ActorPalette[256];
|
||||
uint8 *_hePalettes;
|
||||
int16 *_hePaletteCache;
|
||||
uint16 _hePaletteSlot;
|
||||
|
||||
protected:
|
||||
int _shadowPaletteSize;
|
||||
|
|
|
@ -57,14 +57,14 @@ bool CursorManager::showMouse(bool visible) {
|
|||
return g_system->showMouse(visible);
|
||||
}
|
||||
|
||||
void CursorManager::pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int targetScale) {
|
||||
Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale);
|
||||
void CursorManager::pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) {
|
||||
Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale, format);
|
||||
|
||||
cur->_visible = isVisible();
|
||||
_cursorStack.push(cur);
|
||||
|
||||
if (buf) {
|
||||
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale);
|
||||
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale, format);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ void CursorManager::popCursor() {
|
|||
|
||||
if (!_cursorStack.empty()) {
|
||||
cur = _cursorStack.top();
|
||||
g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_targetScale);
|
||||
g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_targetScale, &cur->_format);
|
||||
}
|
||||
|
||||
g_system->showMouse(isVisible());
|
||||
|
@ -100,15 +100,24 @@ void CursorManager::popAllCursors() {
|
|||
g_system->showMouse(isVisible());
|
||||
}
|
||||
|
||||
void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) {
|
||||
|
||||
void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int targetScale) {
|
||||
if (_cursorStack.empty()) {
|
||||
pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale);
|
||||
pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale, format);
|
||||
return;
|
||||
}
|
||||
|
||||
Cursor *cur = _cursorStack.top();
|
||||
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
uint size;
|
||||
if (!format)
|
||||
size = w * h;
|
||||
else
|
||||
size = w * h * format->bytesPerPixel;
|
||||
#else
|
||||
uint size = w * h;
|
||||
#endif
|
||||
|
||||
if (cur->_size < size) {
|
||||
delete[] cur->_data;
|
||||
|
@ -125,8 +134,14 @@ void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX,
|
|||
cur->_hotspotY = hotspotY;
|
||||
cur->_keycolor = keycolor;
|
||||
cur->_targetScale = targetScale;
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
if (format)
|
||||
cur->_format = *format;
|
||||
else
|
||||
cur->_format = Graphics::PixelFormat::createFormatCLUT8();
|
||||
#endif
|
||||
|
||||
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale);
|
||||
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale, format);
|
||||
}
|
||||
|
||||
bool CursorManager::supportsCursorPalettes() {
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
#include "common/scummsys.h"
|
||||
#include "common/stack.h"
|
||||
#include "common/singleton.h"
|
||||
#include "graphics/pixelformat.h"
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
#include "common/system.h"
|
||||
#endif
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
|
@ -59,18 +63,19 @@ public:
|
|||
* safely freed afterwards.
|
||||
*
|
||||
* @param buf the new cursor data
|
||||
* @param w the width
|
||||
* @param h the height
|
||||
* @param w the width
|
||||
* @param h the height
|
||||
* @param hotspotX the hotspot X coordinate
|
||||
* @param hotspotY the hotspot Y coordinate
|
||||
* @param keycolor the index for the transparent color
|
||||
* @param targetScale the scale for which the cursor is designed
|
||||
*
|
||||
* @param format a pointer to the pixel format which the cursor graphic uses,
|
||||
* CLUT8 will be used if this is NULL or not specified.
|
||||
* @note It is ok for the buffer to be a NULL pointer. It is sometimes
|
||||
* useful to push a "dummy" cursor and modify it later. The
|
||||
* cursor will be added to the stack, but not to the backend.
|
||||
*/
|
||||
void pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int targetScale = 1);
|
||||
void pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 0xFFFFFFFF, int targetScale = 1, const Graphics::PixelFormat *format = NULL);
|
||||
|
||||
/**
|
||||
* Pop a cursor from the stack, and restore the previous one to the
|
||||
|
@ -90,8 +95,10 @@ public:
|
|||
* @param hotspotY the hotspot Y coordinate
|
||||
* @param keycolor the index for the transparent color
|
||||
* @param targetScale the scale for which the cursor is designed
|
||||
* @param format a pointer to the pixel format which the cursor graphic uses,
|
||||
* CLUT8 will be used if this is NULL or not specified.
|
||||
*/
|
||||
void replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int targetScale = 1);
|
||||
void replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 0xFFFFFFFF, int targetScale = 1, const Graphics::PixelFormat *format = NULL);
|
||||
|
||||
/**
|
||||
* Pop all of the cursors and cursor palettes from their respective stacks.
|
||||
|
@ -166,13 +173,24 @@ private:
|
|||
uint _height;
|
||||
int _hotspotX;
|
||||
int _hotspotY;
|
||||
byte _keycolor;
|
||||
uint32 _keycolor;
|
||||
Graphics::PixelFormat _format;
|
||||
byte _targetScale;
|
||||
|
||||
uint _size;
|
||||
|
||||
Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int targetScale = 1) {
|
||||
Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 0xFFFFFFFF, int targetScale = 1, const Graphics::PixelFormat *format = NULL) {
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
if (!format)
|
||||
_format = Graphics::PixelFormat::createFormatCLUT8();
|
||||
else
|
||||
_format = *format;
|
||||
_size = w * h * _format.bytesPerPixel;
|
||||
_keycolor &= ((1 << (_format.bytesPerPixel << 3)) - 1);
|
||||
#else
|
||||
_format = Graphics::PixelFormat::createFormatCLUT8();
|
||||
_size = w * h;
|
||||
_keycolor &= 0xFF;
|
||||
#endif
|
||||
_data = new byte[_size];
|
||||
if (data && _data)
|
||||
memcpy(_data, data, _size);
|
||||
|
@ -180,7 +198,6 @@ private:
|
|||
_height = h;
|
||||
_hotspotX = hotspotX;
|
||||
_hotspotY = hotspotY;
|
||||
_keycolor = keycolor;
|
||||
_targetScale = targetScale;
|
||||
}
|
||||
|
||||
|
@ -216,7 +233,6 @@ private:
|
|||
delete[] _data;
|
||||
}
|
||||
};
|
||||
|
||||
Common::Stack<Cursor *> _cursorStack;
|
||||
Common::Stack<Palette *> _cursorPaletteStack;
|
||||
};
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#define GRAPHICS_PIXELFORMAT_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/list.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
|
@ -50,6 +51,24 @@ struct PixelFormat {
|
|||
byte rLoss, gLoss, bLoss, aLoss; /**< Precision loss of each color component. */
|
||||
byte rShift, gShift, bShift, aShift; /**< Binary left shift of each color component in the pixel value. */
|
||||
|
||||
inline PixelFormat() {
|
||||
bytesPerPixel =
|
||||
rLoss = gLoss = bLoss = aLoss =
|
||||
rShift = gShift = bShift = aShift = 0;
|
||||
}
|
||||
|
||||
inline PixelFormat(byte BytesPerPixel,
|
||||
byte RBits, byte GBits, byte BBits, byte ABits,
|
||||
byte RShift, byte GShift, byte BShift, byte AShift) {
|
||||
bytesPerPixel = BytesPerPixel;
|
||||
rLoss = 8 - RBits, gLoss = 8 - GBits, bLoss = 8 - BBits, aLoss = 8 - ABits;
|
||||
rShift = RShift, gShift = GShift, bShift = BShift, aShift = AShift;
|
||||
}
|
||||
|
||||
static inline PixelFormat createFormatCLUT8() {
|
||||
return PixelFormat(1, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
inline bool operator==(const PixelFormat &fmt) const {
|
||||
// TODO: If aLoss==8, then the value of aShift is irrelevant, and should be ignored.
|
||||
return 0 == memcmp(this, &fmt, sizeof(PixelFormat));
|
||||
|
@ -129,6 +148,26 @@ struct PixelFormat {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines the first matching format between two lists.
|
||||
*
|
||||
* @param backend The higher priority list, meant to be a list of formats supported by the backend
|
||||
* @param frontend The lower priority list, meant to be a list of formats supported by the engine
|
||||
* @return The first item on the backend list that also occurs on the frontend list
|
||||
* or PixelFormat::createFormatCLUT8() if no matching formats were found.
|
||||
*/
|
||||
inline PixelFormat findCompatibleFormat(Common::List<PixelFormat> backend, Common::List<PixelFormat> frontend) {
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
for (Common::List<PixelFormat>::iterator i = backend.begin(); i != backend.end(); ++i) {
|
||||
for (Common::List<PixelFormat>::iterator j = frontend.begin(); j != frontend.end(); ++j) {
|
||||
if (*i == *j)
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return PixelFormat::createFormatCLUT8();
|
||||
}
|
||||
|
||||
} // end of namespace Graphics
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,18 +30,17 @@
|
|||
|
||||
int gBitFormat = 565;
|
||||
|
||||
static const Graphics::PixelFormat gPixelFormat555 = {
|
||||
static const Graphics::PixelFormat gPixelFormat555(
|
||||
2,
|
||||
3, 3, 3, 8,
|
||||
10, 5, 0, 0
|
||||
};
|
||||
);
|
||||
|
||||
static const Graphics::PixelFormat gPixelFormat565 = {
|
||||
static const Graphics::PixelFormat gPixelFormat565(
|
||||
2,
|
||||
3, 2, 3, 8,
|
||||
11, 5, 0, 0
|
||||
};
|
||||
|
||||
);
|
||||
|
||||
|
||||
#ifndef DISABLE_HQ_SCALERS
|
||||
|
|
|
@ -1234,6 +1234,12 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
|
|||
if (!cursor)
|
||||
return false;
|
||||
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
_cursorFormat.bytesPerPixel = 1;
|
||||
_cursorFormat.rLoss = _cursorFormat.gLoss = _cursorFormat.bLoss = _cursorFormat.aLoss = 8;
|
||||
_cursorFormat.rShift = _cursorFormat.gShift = _cursorFormat.bShift = _cursorFormat.aShift = 0;
|
||||
#endif
|
||||
|
||||
// Set up the cursor parameters
|
||||
_cursorHotspotX = hotspotX;
|
||||
_cursorHotspotY = hotspotY;
|
||||
|
|
|
@ -612,6 +612,9 @@ protected:
|
|||
|
||||
ImagesMap _bitmaps;
|
||||
Graphics::PixelFormat _overlayFormat;
|
||||
#ifdef ENABLE_RGB_COLOR
|
||||
Graphics::PixelFormat _cursorFormat;
|
||||
#endif
|
||||
|
||||
/** List of all the dirty screens that must be blitted to the overlay. */
|
||||
Common::List<Common::Rect> _dirtyScreen;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue