Added kUnsupportedColorMode error code brought Scumm engine and SDL backend into compliance with API outlined in http://scummvmupthorn09.wordpress.com/2009/06/14/how-this-is-going-to-work/
Provided convenient Graphics::PixelFormat constructors for ColorMode enums, and bitformat integers. Removed last vestiges (I think) of initial cursor hack. svn-id: r41539
This commit is contained in:
parent
e6f874ee95
commit
8d306ebccf
11 changed files with 142 additions and 141 deletions
|
@ -352,34 +352,6 @@ int OSystem_SDL::getGraphicsMode() const {
|
|||
return _videoMode.mode;
|
||||
}
|
||||
#ifdef ENABLE_16BIT
|
||||
Graphics::ColorMode OSystem_SDL::findCompatibleFormat(Common::List<Graphics::ColorMode> formatList) {
|
||||
bool typeAccepted = false;
|
||||
Graphics::ColorMode format;
|
||||
|
||||
while (!formatList.empty()) {
|
||||
typeAccepted = false;
|
||||
format = formatList.front();
|
||||
|
||||
//no need to keep searching if the screen
|
||||
//is already in one of the desired formats
|
||||
if (getPixelFormat(format) == _videoMode.format)
|
||||
return format;
|
||||
|
||||
formatList.pop_front();
|
||||
switch (format) {
|
||||
case Graphics::kFormatCLUT8:
|
||||
if (format == Graphics::kFormatCLUT8)
|
||||
return format;
|
||||
break;
|
||||
case Graphics::kFormatRGB555:
|
||||
case Graphics::kFormatRGB565:
|
||||
return format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Graphics::kFormatCLUT8;
|
||||
}
|
||||
|
||||
void OSystem_SDL::initFormat(Graphics::PixelFormat format) {
|
||||
assert(_transactionMode == kTransactionActive);
|
||||
|
||||
|
@ -391,66 +363,6 @@ void OSystem_SDL::initFormat(Graphics::PixelFormat format) {
|
|||
_transactionDetails.formatChanged = true;
|
||||
_screenFormat = format;
|
||||
}
|
||||
|
||||
//TODO: Move this out of OSystem and into Graphics, where engine can access it.
|
||||
//TODO: ABGR support
|
||||
Graphics::PixelFormat OSystem_SDL::getPixelFormat(Graphics::ColorMode format) {
|
||||
Graphics::PixelFormat result;
|
||||
switch (format) {
|
||||
case Graphics::kFormatRGB555:
|
||||
result.aLoss = 8;
|
||||
result.bytesPerPixel = 2;
|
||||
result.rLoss = result.gLoss = result.bLoss = 3;
|
||||
break;
|
||||
case Graphics::kFormatRGB565:
|
||||
result.bytesPerPixel = 2;
|
||||
result.aLoss = 8;
|
||||
result.gLoss = 2;
|
||||
result.rLoss = result.bLoss = 3;
|
||||
break;
|
||||
case Graphics::kFormatXRGB1555:
|
||||
//Special case, alpha bit is always high in this mode.
|
||||
result.aLoss = 7;
|
||||
result.bytesPerPixel = 2;
|
||||
result.rLoss = result.gLoss = result.bLoss = 3;
|
||||
result.bShift = 0;
|
||||
result.gShift = result.bShift + result.bBits();
|
||||
result.rShift = result.gShift + result.gBits();
|
||||
result.aShift = result.rShift + result.rBits();
|
||||
//HACK: there should be a clean way to handle setting
|
||||
//up the color order without prematurely returning
|
||||
return result;
|
||||
case Graphics::kFormatRGBA4444:
|
||||
result.bytesPerPixel = 2;
|
||||
result.aLoss = result.gLoss = result.rLoss = result.bLoss = 4;
|
||||
break;
|
||||
case Graphics::kFormatRGB888:
|
||||
result.bytesPerPixel = 3;
|
||||
result.aLoss = 8;
|
||||
result.gLoss = result.rLoss = result.bLoss = 0;
|
||||
break;
|
||||
case Graphics::kFormatRGBA6666:
|
||||
result.bytesPerPixel = 3;
|
||||
result.aLoss = result.gLoss = result.rLoss = result.bLoss = 2;
|
||||
break;
|
||||
case Graphics::kFormatRGBA8888:
|
||||
result.bytesPerPixel = 4;
|
||||
result.aLoss = result.gLoss = result.rLoss = result.bLoss = 0;
|
||||
break;
|
||||
case Graphics::kFormatCLUT8:
|
||||
default:
|
||||
result.bytesPerPixel = 1;
|
||||
result.rShift = result.gShift = result.bShift = result.aShift = 0;
|
||||
result.rLoss = result.gLoss = result.bLoss = result.aLoss = 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
result.aShift = 0;
|
||||
result.bShift = result.aBits();
|
||||
result.gShift = result.bShift + result.bBits();
|
||||
result.rShift = result.gShift + result.gBits();
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
void OSystem_SDL::initSize(uint w, uint h) {
|
||||
|
|
|
@ -197,8 +197,8 @@ OSystem_SDL::OSystem_SDL()
|
|||
#endif
|
||||
_hwscreen(0), _screen(0), _tmpscreen(0),
|
||||
#ifdef ENABLE_16BIT
|
||||
_screenFormat(getPixelFormat(Graphics::kFormatCLUT8)),
|
||||
_cursorBitDepth(8),
|
||||
_screenFormat(Graphics::kFormatCLUT8),
|
||||
_cursorFormat(Graphics::kFormatCLUT8),
|
||||
#endif
|
||||
_overlayVisible(false),
|
||||
_overlayscreen(0), _tmpscreen2(0),
|
||||
|
|
|
@ -82,19 +82,12 @@ public:
|
|||
TransactionError endGFXTransaction(void);
|
||||
|
||||
#ifdef ENABLE_16BIT
|
||||
// Find a compatible format from the list of formats supported by the engine
|
||||
// Fallback to CLUT8 if none found
|
||||
virtual Graphics::ColorMode findCompatibleFormat(Common::List<Graphics::ColorMode> formatList);
|
||||
|
||||
// Set the depth and format of the video bitmap
|
||||
// Typically, CLUT8
|
||||
virtual void initFormat(Graphics::PixelFormat format);
|
||||
|
||||
// Game screen
|
||||
virtual Graphics::PixelFormat getScreenFormat() const { return _screenFormat; }
|
||||
|
||||
//Create a Graphics::PixelFormat to describe the requested color mode
|
||||
virtual Graphics::PixelFormat getPixelFormat(Graphics::ColorMode format);
|
||||
#endif
|
||||
|
||||
// Set the size of the video bitmap.
|
||||
|
@ -379,9 +372,6 @@ protected:
|
|||
MousePos _mouseCurState;
|
||||
byte _mouseKeyColor;
|
||||
int _cursorTargetScale;
|
||||
#ifdef ENABLE_16BIT
|
||||
uint8 _cursorBitDepth;
|
||||
#endif
|
||||
bool _cursorPaletteDisabled;
|
||||
SDL_Surface *_mouseOrigSurface;
|
||||
SDL_Surface *_mouseSurface;
|
||||
|
|
|
@ -227,7 +227,7 @@ static void setupGraphics(OSystem &system) {
|
|||
system.setGraphicsMode(ConfMan.get("gfx_mode").c_str());
|
||||
|
||||
#ifdef ENABLE_16BIT
|
||||
system.initFormat(system.getPixelFormat(Graphics::kFormatCLUT8));
|
||||
system.initFormat(Graphics::kFormatCLUT8);
|
||||
#endif
|
||||
system.initSize(320, 200);
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@ 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
|
||||
#ifdef ENABLE_16BIT
|
||||
kUnsupportedColorMode, //!< Engine initialization: Engine does not support backend's color mode
|
||||
#endif
|
||||
|
||||
|
||||
kReadPermissionDenied, //!< Unable to read data due to missing read permission
|
||||
|
|
|
@ -344,23 +344,6 @@ public:
|
|||
virtual int getGraphicsMode() const = 0;
|
||||
|
||||
#ifdef ENABLE_16BIT
|
||||
/**
|
||||
* Find a supported color format from a list of requested formats. Typical formats include:
|
||||
* CLUT8 (e.g. 256 color, for most games), all backends must provide support for this format
|
||||
* RGB555 (e.g. 16-bit color, for later SCUMM HE games)
|
||||
* RGB565 (e.g. 16-bit color, for Urban Runner)
|
||||
*
|
||||
* These are the pixel formats for which the client code can generates data;
|
||||
* they are not necessarily equal to the hardware pixel format. For example,
|
||||
* a backend may perform color lookup of 8-bit graphics before pushing the
|
||||
* screen buffer to hardware, or perform transformations of the ARGB color order.
|
||||
*
|
||||
* @param formatList A list of requested pixel formats, ordered by priority
|
||||
*
|
||||
* @return a supported ColorMode from the list, or kFormatCLUT8 if no supported format was found
|
||||
*/
|
||||
virtual Graphics::ColorMode findCompatibleFormat(Common::List<Graphics::ColorMode> formatList) = 0;
|
||||
|
||||
/**
|
||||
* Set the color format of the virtual screen. Typical formats include:
|
||||
* CLUT8 (e.g. 256 color, for most games)
|
||||
|
@ -381,13 +364,6 @@ public:
|
|||
* @see Graphics::PixelFormat
|
||||
*/
|
||||
virtual Graphics::PixelFormat getScreenFormat() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the pixel format description of the requested color mode
|
||||
* @see Graphics::PixelFormat
|
||||
*/
|
||||
virtual Graphics::PixelFormat getPixelFormat(Graphics::ColorMode format) = 0;
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
@ -126,20 +126,17 @@ void initCommonGFX(bool defaultTo1XScaler) {
|
|||
}
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler) {
|
||||
#ifdef ENABLE_16BIT
|
||||
Common::List<Graphics::ColorMode> formatList;
|
||||
formatList.push_back(Graphics::kFormatCLUT8);
|
||||
initGraphics(width,height,defaultTo1xScaler, formatList);
|
||||
Graphics::PixelFormat format = Graphics::kFormatCLUT8;
|
||||
initGraphics(width,height,defaultTo1xScaler, format);
|
||||
}
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler, Common::List<Graphics::ColorMode> formatList) {
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler, Graphics::PixelFormat format) {
|
||||
#endif
|
||||
|
||||
g_system->beginGFXTransaction();
|
||||
|
||||
initCommonGFX(defaultTo1xScaler);
|
||||
#ifdef ENABLE_16BIT
|
||||
Graphics::ColorMode format = g_system->findCompatibleFormat(formatList);
|
||||
debug("%X",format); //TODO: set up the pixelFormat here
|
||||
g_system->initFormat(g_system->getPixelFormat(format));
|
||||
g_system->initFormat(format);
|
||||
#endif
|
||||
g_system->initSize(width, height);
|
||||
|
||||
|
@ -161,16 +158,16 @@ void initGraphics(int width, int height, bool defaultTo1xScaler, Common::List<Gr
|
|||
error("%s", message.c_str());
|
||||
}
|
||||
|
||||
// Just show warnings then these occur:
|
||||
#ifdef ENABLE_16BIT
|
||||
if (gfxError & OSystem::kTransactionPixelFormatNotSupported) {
|
||||
Common::String message = "Could not initialize color format.";
|
||||
|
||||
GUIErrorMessage(message);
|
||||
error("%s", message.c_str());
|
||||
GUI::MessageDialog dialog(message);
|
||||
dialog.runModal();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Just show warnings then these occur:
|
||||
if (gfxError & OSystem::kTransactionModeSwitchFailed) {
|
||||
Common::String message = "Could not switch to video mode: '";
|
||||
message += ConfMan.get("gfx_mode");
|
||||
|
|
|
@ -63,7 +63,7 @@ void initCommonGFX(bool defaultTo1XScaler);
|
|||
* mode.
|
||||
*/
|
||||
#ifdef ENABLE_16BIT
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler, Common::List<Graphics::ColorMode> formatList);
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler, Graphics::PixelFormat format);
|
||||
#endif
|
||||
void initGraphics(int width, int height, bool defaultTo1xScaler);
|
||||
|
||||
|
|
|
@ -1085,11 +1085,10 @@ Common::Error ScummEngine::init() {
|
|||
(_screenWidth * _textSurfaceMultiplier > 320));
|
||||
#ifdef ENABLE_16BIT
|
||||
} else if (_game.features & GF_16BIT_COLOR) {
|
||||
int format = Graphics::kFormatRGB555;
|
||||
Common::List<Graphics::ColorMode> formatList;
|
||||
formatList.push_back((Graphics::ColorMode) format);
|
||||
formatList.push_back(Graphics::kFormatCLUT8);
|
||||
initGraphics(_screenWidth, _screenHeight, _screenWidth > 320, formatList);
|
||||
Graphics::PixelFormat format = Graphics::kFormatRGB555;
|
||||
initGraphics(_screenWidth, _screenHeight, _screenWidth > 320, format);
|
||||
if (format != _system->getScreenFormat())
|
||||
return Common::kUnsupportedColorMode;
|
||||
#endif
|
||||
} else {
|
||||
initGraphics(_screenWidth, _screenHeight, _screenWidth > 320);
|
||||
|
|
|
@ -76,6 +76,116 @@ 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. */
|
||||
|
||||
#ifdef ENABLE_16BIT
|
||||
inline PixelFormat() {
|
||||
bytesPerPixel =
|
||||
rLoss = gLoss = bLoss = aLoss =
|
||||
rShift = gShift = bShift = aShift = 0;
|
||||
}
|
||||
|
||||
inline PixelFormat(int BytesPerPixel,
|
||||
int RLoss, int GLoss, int BLoss, int ALoss,
|
||||
int RShift, int GShift, int BShift, int AShift) {
|
||||
bytesPerPixel = BytesPerPixel;
|
||||
rLoss = RLoss, gLoss = GLoss, bLoss = BLoss, aLoss = ALoss;
|
||||
rShift = RShift, gShift = GShift, bShift = BShift, aShift = AShift;
|
||||
}
|
||||
|
||||
//Copy constructor
|
||||
//Is this necessary?
|
||||
inline PixelFormat(const PixelFormat &format) {
|
||||
bytesPerPixel = format.bytesPerPixel;
|
||||
|
||||
rLoss = format.rLoss;
|
||||
gLoss = format.gLoss;
|
||||
bLoss = format.bLoss;
|
||||
aLoss = format.aLoss;
|
||||
|
||||
rShift = format.rShift;
|
||||
gShift = format.gShift;
|
||||
bShift = format.bShift;
|
||||
aShift = format.aShift;
|
||||
}
|
||||
|
||||
//Convenience constructor from bitformat number
|
||||
//TODO: BGR support
|
||||
//TODO: Specify alpha position
|
||||
/* PixelFormat(int bitFormat) {
|
||||
bytesPerPixel = ColorMasks<bitFormat>::kBytesPerPixel;
|
||||
|
||||
rLoss = 8 - ColorMasks<bitFormat>::kRedBits;
|
||||
gLoss = 8 - ColorMasks<bitFormat>::kGreenBits;
|
||||
bLoss = 8 - ColorMasks<bitFormat>::kBlueBits;
|
||||
aLoss = 8 - ColorMasks<bitFormat>::kAlphaBits;
|
||||
|
||||
rShift = ColorMasks<bitFormat>::kRedShift;
|
||||
gShift = ColorMasks<bitFormat>::kGreenShift;
|
||||
bShift = ColorMasks<bitFormat>::kBlueShift;
|
||||
aShift = ColorMasks<bitFormat>::kAlphaShift;
|
||||
};*/
|
||||
|
||||
//Convenience constructor from enum type
|
||||
//TODO: BGR support
|
||||
//TODO: Specify alpha position
|
||||
inline PixelFormat(ColorMode mode) {
|
||||
switch (mode) {
|
||||
case kFormatRGB555:
|
||||
aLoss = 8;
|
||||
bytesPerPixel = 2;
|
||||
rLoss = gLoss = bLoss = 3;
|
||||
break;
|
||||
case kFormatXRGB1555:
|
||||
//Special case, alpha bit is always high in this mode.
|
||||
aLoss = 7;
|
||||
bytesPerPixel = 2;
|
||||
rLoss = gLoss = bLoss = 3;
|
||||
bShift = 0;
|
||||
gShift = bShift + bBits();
|
||||
rShift = gShift + gBits();
|
||||
aShift = rShift + rBits();
|
||||
//FIXME: there should be a clean way to handle setting
|
||||
//up the color order without prematurely returning.
|
||||
//This will probably be handled when alpha position specification is possible
|
||||
return;
|
||||
case kFormatRGB565:
|
||||
bytesPerPixel = 2;
|
||||
aLoss = 8;
|
||||
gLoss = 2;
|
||||
rLoss = bLoss = 3;
|
||||
break;
|
||||
case kFormatRGBA4444:
|
||||
bytesPerPixel = 2;
|
||||
aLoss = gLoss = rLoss = bLoss = 4;
|
||||
break;
|
||||
case kFormatRGB888:
|
||||
bytesPerPixel = 3;
|
||||
aLoss = 8;
|
||||
gLoss = rLoss = bLoss = 0;
|
||||
break;
|
||||
case kFormatRGBA6666:
|
||||
bytesPerPixel = 3;
|
||||
aLoss = gLoss = rLoss = bLoss = 2;
|
||||
break;
|
||||
case kFormatRGBA8888:
|
||||
bytesPerPixel = 4;
|
||||
aLoss = gLoss = rLoss = bLoss = 0;
|
||||
break;
|
||||
case kFormatCLUT8:
|
||||
default:
|
||||
bytesPerPixel = 1;
|
||||
rShift = gShift = bShift = aShift = 0;
|
||||
rLoss = gLoss = bLoss = aLoss = 8;
|
||||
return;
|
||||
}
|
||||
|
||||
aShift = 0;
|
||||
bShift = aBits();
|
||||
gShift = bShift + bBits();
|
||||
rShift = gShift + gBits();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
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));
|
||||
|
|
|
@ -30,17 +30,31 @@
|
|||
|
||||
int gBitFormat = 565;
|
||||
|
||||
#ifdef ENABLE_16BIT
|
||||
static const Graphics::PixelFormat gPixelFormat555(
|
||||
#else
|
||||
static const Graphics::PixelFormat gPixelFormat555 = {
|
||||
#endif
|
||||
2,
|
||||
3, 3, 3, 8,
|
||||
10, 5, 0, 0
|
||||
#ifdef ENABLE_16BIT
|
||||
);
|
||||
|
||||
static const Graphics::PixelFormat gPixelFormat565(
|
||||
#else
|
||||
};
|
||||
|
||||
static const Graphics::PixelFormat gPixelFormat565 = {
|
||||
#endif
|
||||
2,
|
||||
3, 2, 3, 8,
|
||||
11, 5, 0, 0
|
||||
#ifdef ENABLE_16BIT
|
||||
);
|
||||
#else
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue