diff options
author | dhewg | 2011-03-05 18:21:35 +0100 |
---|---|---|
committer | dhewg | 2011-03-05 18:47:05 +0100 |
commit | 94db3403a3fbe228aa25cdde310e2a8daa5c33eb (patch) | |
tree | 3872223dcf94d33fdd28dce21f3fe6f6a1f300a5 | |
parent | 7d506ef853a66cc35816926fe739785c2fd1f2d1 (diff) | |
download | scummvm-rg350-94db3403a3fbe228aa25cdde310e2a8daa5c33eb.tar.gz scummvm-rg350-94db3403a3fbe228aa25cdde310e2a8daa5c33eb.tar.bz2 scummvm-rg350-94db3403a3fbe228aa25cdde310e2a8daa5c33eb.zip |
ANDROID: Add initial 16bit gfx support
Supported pixel formats: 565, 5551, 4444
Missing: 555 (doesn't exist on GLES)
-rw-r--r-- | backends/platform/android/android.cpp | 8 | ||||
-rw-r--r-- | backends/platform/android/android.h | 19 | ||||
-rw-r--r-- | backends/platform/android/gfx.cpp | 193 | ||||
-rw-r--r-- | backends/platform/android/texture.cpp | 17 | ||||
-rw-r--r-- | backends/platform/android/texture.h | 34 | ||||
-rwxr-xr-x | configure | 2 |
6 files changed, 235 insertions, 38 deletions
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp index 43b618d37b..0cfe7c9a22 100644 --- a/backends/platform/android/android.cpp +++ b/backends/platform/android/android.cpp @@ -110,6 +110,8 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) : _game_texture(0), _overlay_texture(0), _mouse_texture(0), + _mouse_texture_palette(0), + _mouse_texture_rgb(0), _use_mouse_palette(false), _show_mouse(false), _show_overlay(false), @@ -328,7 +330,8 @@ void OSystem_Android::initBackend() { _game_texture = new GLESPalette888Texture(); _overlay_texture = new GLES4444Texture(); - _mouse_texture = new GLESPalette8888Texture(); + _mouse_texture_palette = new GLESPalette8888Texture(); + _mouse_texture = _mouse_texture_palette; // renice this thread to boost the audio thread if (setpriority(PRIO_PROCESS, 0, 19) < 0) @@ -591,7 +594,8 @@ void OSystem_Android::quit() { delete _game_texture; delete _overlay_texture; - delete _mouse_texture; + delete _mouse_texture_palette; + delete _mouse_texture_rgb; deinitSurface(); } diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h index 3ccc84bc7e..2c0641f789 100644 --- a/backends/platform/android/android.h +++ b/backends/platform/android/android.h @@ -103,7 +103,7 @@ private: bool _force_redraw; // Game layer - GLESPalette888Texture *_game_texture; + GLESTexture *_game_texture; int _shake_offset; Common::Rect _focus_rect; @@ -112,7 +112,9 @@ private: bool _show_overlay; // Mouse layer - GLESPalette8888Texture *_mouse_texture; + GLESTexture *_mouse_texture; + GLESPaletteTexture *_mouse_texture_palette; + GLESTexture *_mouse_texture_rgb; Common::Point _mouse_hotspot; int _mouse_targetscale; bool _show_mouse; @@ -144,6 +146,12 @@ private: void deinitSurface(); void initViewport(); +#ifdef USE_RGB_COLOR + Common::String getPixelFormatName(const Graphics::PixelFormat &format) const; + void initTexture(GLESTexture **texture, uint width, uint height, + const Graphics::PixelFormat *format, bool alphaPalette); +#endif + void setupKeymapper(); void _setCursorPalette(const byte *colors, uint start, uint num); @@ -158,11 +166,18 @@ public: virtual bool hasFeature(Feature f); virtual void setFeatureState(Feature f, bool enable); virtual bool getFeatureState(Feature f); + virtual const GraphicsMode *getSupportedGraphicsModes() const; virtual int getDefaultGraphicsMode() const; bool setGraphicsMode(const char *name); virtual bool setGraphicsMode(int mode); virtual int getGraphicsMode() const; + +#ifdef USE_RGB_COLOR + virtual Graphics::PixelFormat getScreenFormat() const; + virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const; +#endif + virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format); virtual int getScreenChangeID() const; diff --git a/backends/platform/android/gfx.cpp b/backends/platform/android/gfx.cpp index c71ee178ee..1b7679d0e5 100644 --- a/backends/platform/android/gfx.cpp +++ b/backends/platform/android/gfx.cpp @@ -62,6 +62,92 @@ int OSystem_Android::getGraphicsMode() const { return 1; } +#ifdef USE_RGB_COLOR +Graphics::PixelFormat OSystem_Android::getScreenFormat() const { + return _game_texture->getPixelFormat(); +} + +Common::List<Graphics::PixelFormat> OSystem_Android::getSupportedFormats() const { + Common::List<Graphics::PixelFormat> res; + res.push_back(GLES565Texture::getPixelFormat()); + res.push_back(GLES5551Texture::getPixelFormat()); + res.push_back(GLES4444Texture::getPixelFormat()); + res.push_back(Graphics::PixelFormat::createFormatCLUT8()); + + return res; +} + +Common::String OSystem_Android::getPixelFormatName(const Graphics::PixelFormat &format) const { + if (format.bytesPerPixel == 1) + return "CLUT8"; + + if (format.aLoss == 8) + return Common::String::format("RGB%u%u%u", + 8 - format.rLoss, + 8 - format.gLoss, + 8 - format.bLoss); + + return Common::String::format("RGBA%u%u%u%u", + 8 - format.rLoss, + 8 - format.gLoss, + 8 - format.bLoss, + 8 - format.aLoss); +} + +void OSystem_Android::initTexture(GLESTexture **texture, + uint width, uint height, + const Graphics::PixelFormat *format, + bool alphaPalette) { + assert(texture); + Graphics::PixelFormat format_clut8 = + Graphics::PixelFormat::createFormatCLUT8(); + Graphics::PixelFormat format_current; + Graphics::PixelFormat format_new; + + if (*texture) + format_current = (*texture)->getPixelFormat(); + else + format_current = Graphics::PixelFormat(); + + if (format) + format_new = *format; + else + format_new = format_clut8; + + if (format_current != format_new) { + if (*texture) + LOGD("switching pixel format from: %s", + getPixelFormatName((*texture)->getPixelFormat()).c_str()); + + delete *texture; + + if (format_new == GLES565Texture::getPixelFormat()) + *texture = new GLES565Texture(); + else if (format_new == GLES5551Texture::getPixelFormat()) + *texture = new GLES5551Texture(); + else if (format_new == GLES4444Texture::getPixelFormat()) + *texture = new GLES4444Texture(); + else { + // TODO what now? + if (format_new != format_clut8) + LOGE("unsupported pixel format: %s", + getPixelFormatName(format_new).c_str()); + + if (alphaPalette) + *texture = new GLESPalette8888Texture; + else + *texture = new GLESPalette888Texture; + } + + LOGD("new pixel format: %s", + getPixelFormatName((*texture)->getPixelFormat()).c_str()); + } + + (*texture)->allocBuffer(width, height); + (*texture)->fillBuffer(0); +} +#endif + void OSystem_Android::initSurface() { LOGD("initializing surface"); @@ -151,9 +237,6 @@ void OSystem_Android::initSize(uint width, uint height, GLTHREADCHECK; - _game_texture->allocBuffer(width, height); - _game_texture->fillBuffer(0); - int overlay_width = _egl_surface_width; int overlay_height = _egl_surface_height; @@ -172,11 +255,17 @@ void OSystem_Android::initSize(uint width, uint height, _overlay_texture->allocBuffer(overlay_width, overlay_height); +#ifdef USE_RGB_COLOR + initTexture(&_game_texture, width, height, format, false); +#else + _game_texture->allocBuffer(width, height); + _game_texture->fillBuffer(0); +#endif // Don't know mouse size yet - it gets reallocated in // setMouseCursor. We need the palette allocated before // setMouseCursor however, so just take a guess at the desired // size (it's small). - _mouse_texture->allocBuffer(20, 20); + _mouse_texture_palette->allocBuffer(20, 20); } int OSystem_Android::getScreenChangeID() const { @@ -194,20 +283,30 @@ int16 OSystem_Android::getWidth() { void OSystem_Android::setPalette(const byte *colors, uint start, uint num) { ENTER("%p, %u, %u", colors, start, num); +#ifdef USE_RGB_COLOR + assert(_game_texture->getPixelFormat().bytesPerPixel == 1); +#endif + GLTHREADCHECK; + memcpy(((GLESPaletteTexture *)_game_texture)->palette() + start * 3, + colors, num * 3); + if (!_use_mouse_palette) _setCursorPalette(colors, start, num); - - memcpy(_game_texture->palette() + start * 3, colors, num * 3); } void OSystem_Android::grabPalette(byte *colors, uint start, uint num) { ENTER("%p, %u, %u", colors, start, num); +#ifdef USE_RGB_COLOR + assert(_game_texture->getPixelFormat().bytesPerPixel == 1); +#endif + GLTHREADCHECK; - memcpy(colors, _game_texture->palette_const() + start * 3, num * 3); + memcpy(colors, ((GLESPaletteTexture *)_game_texture)->palette() + start * 3, + num * 3); } void OSystem_Android::copyRectToScreen(const byte *buf, int pitch, @@ -325,6 +424,7 @@ Graphics::Surface *OSystem_Android::lockScreen() { GLTHREADCHECK; + // TODO this doesn't return any pixel data for non CLUT8 Graphics::Surface *surface = _game_texture->surface(); assert(surface->pixels); @@ -353,6 +453,7 @@ void OSystem_Android::fillScreen(uint32 col) { GLTHREADCHECK; + // TODO FIXME rgb colors assert(col < 256); _game_texture->fillBuffer(col); } @@ -472,19 +573,39 @@ void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h, assert(keycolor < 256); - _mouse_texture->allocBuffer(w, h); +#ifdef USE_RGB_COLOR + if (format && format->bytesPerPixel > 1) { + if (_mouse_texture != _mouse_texture_rgb) + LOGD("switching to rgb mouse cursor"); - // Update palette alpha based on keycolor - byte *palette = _mouse_texture->palette(); - uint i = 256; + initTexture(&_mouse_texture_rgb, w, h, format, true); - do { - palette[3] = 0xff; - palette += 4; - } while (--i); + _mouse_texture = _mouse_texture_rgb; + } else { + if (_mouse_texture != _mouse_texture_palette) + LOGD("switching to paletted mouse cursor"); + + initTexture((GLESTexture **)&_mouse_texture_palette, w, h, format, + true); + + _mouse_texture = _mouse_texture_palette; + + delete _mouse_texture_rgb; + _mouse_texture_rgb = 0; + } +#else + _mouse_texture_palette->allocBuffer(w, h); +#endif + + if (_mouse_texture->getPixelFormat().bytesPerPixel == 1) { + // Update palette alpha based on keycolor + byte *palette = _mouse_texture_palette->palette(); - palette = _mouse_texture->palette(); - palette[keycolor * 4 + 3] = 0x00; + for (uint i = 0; i < 256; ++i, palette += 4) + palette[3] = 0xff; + + _mouse_texture_palette->palette()[keycolor * 4 + 3] = 0x00; + } if (w == 0 || h == 0) return; @@ -497,17 +618,14 @@ void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h, void OSystem_Android::_setCursorPalette(const byte *colors, uint start, uint num) { - byte *palette = _mouse_texture->palette() + start * 4; - - do { - for (int i = 0; i < 3; ++i) - palette[i] = colors[i]; + byte *palette = _mouse_texture_palette->palette() + start * 4; + for (uint i = 0; i < num; ++i, palette += 4, colors += 3) { + palette[0] = colors[0]; + palette[1] = colors[1]; + palette[2] = colors[2]; // Leave alpha untouched to preserve keycolor - - palette += 4; - colors += 3; - } while (--num); + } } void OSystem_Android::setCursorPalette(const byte *colors, @@ -516,6 +634,15 @@ void OSystem_Android::setCursorPalette(const byte *colors, GLTHREADCHECK; + if (_mouse_texture->getPixelFormat().bytesPerPixel != 1) { + LOGD("switching to paletted mouse cursor"); + + _mouse_texture = _mouse_texture_palette; + + delete _mouse_texture_rgb; + _mouse_texture_rgb = 0; + } + _setCursorPalette(colors, start, num); _use_mouse_palette = true; } @@ -523,6 +650,20 @@ void OSystem_Android::setCursorPalette(const byte *colors, void OSystem_Android::disableCursorPalette(bool disable) { ENTER("%d", disable); + // when disabling the cursor palette, and we're running a clut8 game, + // it expects the game palette to be used for the cursor + if (disable && _game_texture->getPixelFormat().bytesPerPixel == 1) { + byte *src = ((GLESPaletteTexture *)_game_texture)->palette(); + byte *dst = _mouse_texture_palette->palette(); + + for (uint i = 0; i < 256; ++i, src += 3, dst += 4) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + // Leave alpha untouched to preserve keycolor + } + } + _use_mouse_palette = !disable; } diff --git a/backends/platform/android/texture.cpp b/backends/platform/android/texture.cpp index 05c551803b..e4c98e3ce0 100644 --- a/backends/platform/android/texture.cpp +++ b/backends/platform/android/texture.cpp @@ -83,11 +83,12 @@ void GLESTexture::initGLExtensions() { } GLESTexture::GLESTexture(byte bytesPerPixel, GLenum glFormat, GLenum glType, - size_t paletteSize) : + size_t paletteSize, Graphics::PixelFormat pixelFormat) : _bytesPerPixel(bytesPerPixel), _glFormat(glFormat), _glType(glType), _paletteSize(paletteSize), + _pixelFormat(pixelFormat), _texture_width(0), _texture_height(0), _all_dirty(true) @@ -279,14 +280,21 @@ void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) { } GLES4444Texture::GLES4444Texture() : - GLESTexture(2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 0) { + GLESTexture(2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 0, getPixelFormat()) { } GLES4444Texture::~GLES4444Texture() { } +GLES5551Texture::GLES5551Texture() : + GLESTexture(2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 0, getPixelFormat()) { +} + +GLES5551Texture::~GLES5551Texture() { +} + GLES565Texture::GLES565Texture() : - GLESTexture(2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0) { + GLESTexture(2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0, getPixelFormat()) { } GLES565Texture::~GLES565Texture() { @@ -294,7 +302,8 @@ GLES565Texture::~GLES565Texture() { GLESPaletteTexture::GLESPaletteTexture(byte bytesPerPixel, GLenum glFormat, GLenum glType, size_t paletteSize) : - GLESTexture(bytesPerPixel, glFormat, glType, paletteSize), + GLESTexture(bytesPerPixel, glFormat, glType, paletteSize, + Graphics::PixelFormat::createFormatCLUT8()), _texture(0) { } diff --git a/backends/platform/android/texture.h b/backends/platform/android/texture.h index 38a6228076..14eea44914 100644 --- a/backends/platform/android/texture.h +++ b/backends/platform/android/texture.h @@ -31,6 +31,7 @@ #include <GLES/gl.h> #include "graphics/surface.h" +#include "graphics/pixelformat.h" #include "common/rect.h" #include "common/array.h" @@ -41,10 +42,11 @@ public: protected: GLESTexture(byte bytesPerPixel, GLenum glFormat, GLenum glType, - size_t paletteSize); - virtual ~GLESTexture(); + size_t paletteSize, Graphics::PixelFormat pixelFormat); public: + virtual ~GLESTexture(); + void release(); void reinit(); void initSize(); @@ -82,6 +84,10 @@ public: return _all_dirty || !_dirty_rect.isEmpty(); } + inline Graphics::PixelFormat getPixelFormat() const { + return _pixelFormat; + } + protected: inline void setDirty() { _all_dirty = true; @@ -110,6 +116,8 @@ protected: // Covers dirty area Common::Rect _dirty_rect; + + Graphics::PixelFormat _pixelFormat; }; // RGBA4444 texture @@ -117,6 +125,21 @@ class GLES4444Texture : public GLESTexture { public: GLES4444Texture(); virtual ~GLES4444Texture(); + + static inline Graphics::PixelFormat getPixelFormat() { + return Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0); + } +}; + +// RGBA5551 texture +class GLES5551Texture : public GLESTexture { +public: + GLES5551Texture(); + virtual ~GLES5551Texture(); + + static inline Graphics::PixelFormat getPixelFormat() { + return Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0); + } }; // RGB565 texture @@ -124,15 +147,20 @@ class GLES565Texture : public GLESTexture { public: GLES565Texture(); virtual ~GLES565Texture(); + + static inline Graphics::PixelFormat getPixelFormat() { + return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); + } }; class GLESPaletteTexture : public GLESTexture { protected: GLESPaletteTexture(byte bytesPerPixel, GLenum glFormat, GLenum glType, size_t paletteSize); - virtual ~GLESPaletteTexture(); public: + virtual ~GLESPaletteTexture(); + virtual void allocBuffer(GLuint width, GLuint height); virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height, const void *buf, int pitch); @@ -2104,7 +2104,7 @@ fi # Enable 16bit support only for backends which support it # case $_backend in - dingux | dreamcast | gph | openpandora | psp | samsungtv | sdl | wii) + android | dingux | dreamcast | gph | openpandora | psp | samsungtv | sdl | wii) if test "$_16bit" = auto ; then _16bit=yes else |