aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/wii/osystem_gfx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/platform/wii/osystem_gfx.cpp')
-rw-r--r--backends/platform/wii/osystem_gfx.cpp567
1 files changed, 325 insertions, 242 deletions
diff --git a/backends/platform/wii/osystem_gfx.cpp b/backends/platform/wii/osystem_gfx.cpp
index b0e3f112c1..6f9e8a04e8 100644
--- a/backends/platform/wii/osystem_gfx.cpp
+++ b/backends/platform/wii/osystem_gfx.cpp
@@ -21,43 +21,32 @@
#include <malloc.h>
+#include "common/config-manager.h"
#include "graphics/conversion.h"
+#include "backends/fs/wii/wii-fs-factory.h"
#include "osystem.h"
-#include "gx_supp.h"
+#include "gfx.h"
+#define ROUNDUP(x,n) (-(-(x) & -(n)))
#define MAX_FPS 30
-
-enum GraphicModeID {
- GM_DEFAULT = 0,
- GM_OVERSCAN1,
- GM_OVERSCAN2,
- GM_OVERSCAN3,
- GM_OVERSCAN4,
- GM_OVERSCAN5
-};
+#define TLUT_GAME GX_TLUT0
+#define TLUT_MOUSE GX_TLUT1
static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
- { "standard", "Standard", GM_DEFAULT },
- { "overscan1", "Overscan 1", GM_OVERSCAN1 },
- { "overscan2", "Overscan 2", GM_OVERSCAN2 },
- { "overscan3", "Overscan 3", GM_OVERSCAN3 },
- { "overscan4", "Overscan 4", GM_OVERSCAN4 },
- { "overscan5", "Overscan 5", GM_OVERSCAN5 },
+ { "standard", "Standard", GFX_SETUP_STANDARD },
+ { "standardaa", "Standard antialiased", GFX_SETUP_STANDARD_AA },
+ { "ds", "Double-strike", GFX_SETUP_DS },
+ { "dsaa", "Double-strike antialiased", GFX_SETUP_DS_AA },
{ 0, 0, 0 }
};
void OSystem_Wii::initGfx() {
- _surface.w = 0;
- _surface.h = 0;
- _surface.pitch = 0;
- _surface.pixels = NULL;
- _surface.bytesPerPixel = 0;
-
- GX_InitVideo();
+ gfx_video_init(GFX_MODE_AUTO, GFX_SETUP_STANDARD);
+ gfx_init();
- _overlayWidth = 640;
- _overlayHeight = 480;
+ _overlayWidth = gfx_video_get_width();
+ _overlayHeight = gfx_video_get_height();
#ifndef GAMECUBE
if (CONF_GetAspectRatio() && _fullscreen)
@@ -67,49 +56,89 @@ void OSystem_Wii::initGfx() {
_overlaySize = _overlayWidth * _overlayHeight * 2;
_overlayPixels = (OverlayColor *) memalign(32, _overlaySize);
- _palette = (u16 *) memalign(32, 256 * 2);
- memset(_palette, 0, 256 * 2);
+ memset(&_texMouse, 0, sizeof(gfx_tex_t));
+ memset(&_texOverlay, 0, sizeof(gfx_tex_t));
+ memset(&_texGame, 0, sizeof(gfx_tex_t));
+
+ _cursorPalette = (u16 *) malloc(256 * 2);
+ if (!_cursorPalette) {
+ printf("could not alloc palette buffer\n");
+ ::abort();
+ }
- _cursorPalette = (u16 *) memalign(32, 256 * 2);
memset(_cursorPalette, 0, 256 * 2);
- _texture = (u16 *) memalign(32, 640 * 480 * 2);
+ if (!gfx_tex_init(&_texOverlay, GFX_TF_RGB5A3, 0,
+ _overlayWidth, _overlayHeight)) {
+ printf("could not init the overlay texture\n");
+ ::abort();
+ }
- setGraphicsMode(_activeGraphicsMode);
+ gfx_coords(&_coordsOverlay, &_texOverlay, GFX_COORD_FULLSCREEN);
}
void OSystem_Wii::deinitGfx() {
- GX_AbortFrame();
+ gfx_deinit();
- if (_gamePixels) {
- free(_gamePixels);
- _gamePixels = NULL;
- }
+ gfx_tex_deinit(&_texMouse);
+ gfx_tex_deinit(&_texGame);
+ gfx_tex_deinit(&_texOverlay);
- if (_palette) {
- free(_palette);
- _palette = NULL;
- }
+ free(_cursorPalette);
+ _cursorPalette = NULL;
- if (_overlayPixels) {
- free(_overlayPixels);
- _overlayPixels = NULL;
- }
+ free(_gamePixels);
+ _gamePixels = NULL;
- if (_mouseCursor) {
- free(_mouseCursor);
- _mouseCursor = NULL;
- }
+ free(_overlayPixels);
+ _overlayPixels = NULL;
+}
- if (_cursorPalette) {
- free(_cursorPalette);
- _cursorPalette = NULL;
+void OSystem_Wii::updateScreenResolution() {
+ if (_overlayVisible) {
+ _currentWidth = _overlayWidth;
+ _currentHeight = _overlayHeight;
+ } else {
+ _currentWidth = _gameWidth;
+ _currentHeight = _gameHeight;
}
- if (_texture) {
- free(_texture);
- _texture = NULL;
+ if (_currentWidth > 0)
+ _currentXScale = f32(gfx_video_get_width()) / f32(_currentWidth);
+ else
+ _currentXScale = 1.0;
+
+ if (_currentHeight > 0)
+ _currentYScale = f32(gfx_video_get_height()) / f32(_currentHeight);
+ else
+ _currentYScale = 1.0;
+
+ updateEventScreenResolution();
+}
+
+void OSystem_Wii::switchVideoMode(int mode) {
+ if (_gameHeight > 240) {
+ if (mode == GFX_SETUP_DS)
+ mode = GFX_SETUP_STANDARD;
+ else if (mode == GFX_SETUP_DS_AA)
+ mode = GFX_SETUP_STANDARD_AA;
}
+
+ if (_actualGraphicsMode == mode)
+ return;
+
+ printf("switchVideoMode %d\n", mode);
+
+ gfx_video_setup_t setup = static_cast<gfx_video_setup_t> (mode);
+ gfx_video_deinit();
+ gfx_video_init(GFX_MODE_AUTO, setup);
+ gfx_init();
+
+ _actualGraphicsMode = mode;
+
+ gfx_coords(&_coordsOverlay, &_texOverlay, GFX_COORD_FULLSCREEN);
+ gfx_coords(&_coordsGame, &_texGame, GFX_COORD_FULLSCREEN);
+ updateScreenResolution();
}
const OSystem::GraphicsMode* OSystem_Wii::getSupportedGraphicsModes() const {
@@ -117,42 +146,26 @@ const OSystem::GraphicsMode* OSystem_Wii::getSupportedGraphicsModes() const {
}
int OSystem_Wii::getDefaultGraphicsMode() const {
- return GM_DEFAULT;
+ return GFX_SETUP_STANDARD;
}
bool OSystem_Wii::setGraphicsMode(int mode) {
- s16 xar, yar;
-
- printf("setGraphicsMode %d\n", mode);
-
- xar = vmode->viWidth / 2;
- yar = vmode->xfbHeight / 2;
-
-#ifndef GAMECUBE
- if (CONF_GetAspectRatio() && !_fullscreen)
- xar = s16(float(xar) / 1.33f);
-#endif
-
- GX_SetCamPosZ(400 - mode * 10);
- GX_Start(640, 480, xar, yar);
-
- _activeGraphicsMode = mode;
-
+ _configGraphicsMode = mode;
return true;
}
int OSystem_Wii::getGraphicsMode() const {
- return _activeGraphicsMode;
+ return _configGraphicsMode;
}
#ifdef USE_RGB_COLOR
Graphics::PixelFormat OSystem_Wii::getScreenFormat() const {
- return _screenPF;
+ return _pfGame;
}
Common::List<Graphics::PixelFormat> OSystem_Wii::getSupportedFormats() {
Common::List<Graphics::PixelFormat> res;
- res.push_back(_texturePF);
+ res.push_back(_pfRGB565);
res.push_back(Graphics::PixelFormat::createFormatCLUT8());
return res;
@@ -162,9 +175,11 @@ Common::List<Graphics::PixelFormat> OSystem_Wii::getSupportedFormats() {
void OSystem_Wii::initSize(uint width, uint height,
const Graphics::PixelFormat *format) {
bool update = false;
+ gfx_tex_format_t tex_format;
#ifdef USE_RGB_COLOR
Graphics::PixelFormat newFormat;
+
if (format)
newFormat = *format;
else
@@ -173,8 +188,8 @@ void OSystem_Wii::initSize(uint width, uint height,
if (newFormat.bytesPerPixel > 2)
newFormat = Graphics::PixelFormat::createFormatCLUT8();
- if (_screenPF != newFormat) {
- _screenPF = newFormat;
+ if (_pfGame != newFormat) {
+ _pfGame = newFormat;
update = true;
}
#endif
@@ -187,83 +202,147 @@ void OSystem_Wii::initSize(uint width, uint height,
update = true;
}
- if (update) {
-#ifdef USE_RGB_COLOR
- printf("initSize %u*%u*%u (%u,%u,%u)\n",
- _gameWidth, _gameHeight,
- _screenPF.bytesPerPixel * 8,
- _screenPF.rShift, _screenPF.gShift, _screenPF.bShift);
-#else
- printf("initSize %u*%u\n", _gameWidth, _gameHeight);
-#endif
+ if (_gameRunning) {
+ switchVideoMode(_configGraphicsMode);
+
+ if (_arCorrection && (_gameWidth == 320) && (_gameHeight == 200))
+ gfx_set_ar(320.0 / 240.0);
+ else
+ gfx_set_ar(f32(_gameWidth) / f32(_gameHeight));
+ }
+ if (update) {
if(_gamePixels)
free(_gamePixels);
+ tex_format = GFX_TF_PALETTE_RGB565;
+
#ifdef USE_RGB_COLOR
+ if (_pfGame.bytesPerPixel > 1) {
+ tex_format = GFX_TF_RGB565;
+ _pfGameTexture = _pfRGB565;
+ }
+
+ printf("initSize %u*%u*%u (%u%u%u -> %u%u%u match: %d)\n",
+ _gameWidth, _gameHeight, _pfGame.bytesPerPixel * 8,
+ 8 - _pfGame.rLoss, 8 - _pfGame.gLoss, 8 - _pfGame.bLoss,
+ 8 - _pfGameTexture.rLoss, 8 - _pfGameTexture.gLoss,
+ 8 - _pfGameTexture.bLoss, _pfGame == _pfGameTexture);
+
_gamePixels = (u8 *) memalign(32, _gameWidth * _gameHeight *
- _screenPF.bytesPerPixel);
+ _pfGame.bytesPerPixel);
memset(_gamePixels, 0, _gameWidth * _gameHeight *
- _screenPF.bytesPerPixel);
+ _pfGame.bytesPerPixel);
#else
+ printf("initSize %u*%u\n", _gameWidth, _gameHeight);
+
_gamePixels = (u8 *) memalign(32, _gameWidth * _gameHeight);
memset(_gamePixels, 0, _gameWidth * _gameHeight);
#endif
- if (!_overlayVisible) {
- _currentWidth = _gameWidth;
- _currentHeight = _gameHeight;
- updateEventScreenResolution();
+
+ if (!gfx_tex_init(&_texGame, tex_format, TLUT_GAME,
+ _gameWidth, _gameHeight)) {
+ printf("could not init the game texture\n");
+ ::abort();
}
- setGraphicsMode(_activeGraphicsMode);
+ gfx_coords(&_coordsGame, &_texGame, GFX_COORD_FULLSCREEN);
+
+ updateScreenResolution();
}
}
int16 OSystem_Wii::getWidth() {
- return _gameWidth;
+ return _currentWidth;
}
int16 OSystem_Wii::getHeight() {
- return _gameHeight;
+ return _currentHeight;
}
void OSystem_Wii::setPalette(const byte *colors, uint start, uint num) {
#ifdef USE_RGB_COLOR
- assert(_screenPF.bytesPerPixel == 1);
+ assert(_pfGame.bytesPerPixel == 1);
#endif
- const byte *p = colors;
+ const byte *s = colors;
+ u16 *d = _texGame.palette;
+
for (uint i = 0; i < num; ++i) {
- _palette[start + i] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(p[0], p[1], p[2]);
- p += 4;
+ d[start + i] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(s[0], s[1], s[2]);
+ s += 4;
+ }
+
+ gfx_tex_flush_palette(&_texGame);
+
+ if (_cursorPaletteDisabled) {
+ assert(_texMouse.palette);
+
+ s = colors;
+ d = _texMouse.palette;
+
+ for (uint i = 0; i < num; ++i) {
+ d[start + i] = Graphics::ARGBToColor<Graphics::ColorMasks<3444> >(0xff, s[0], s[1], s[2]);
+ s += 4;
+ }
+
+ _cursorPaletteDirty = true;
}
}
void OSystem_Wii::grabPalette(byte *colors, uint start, uint num) {
- byte *p = colors;
+#ifdef USE_RGB_COLOR
+ assert(_pfGame.bytesPerPixel == 1);
+#endif
+
+ u16 *s = _texGame.palette;
+ byte *d = colors;
+
u8 r, g, b;
for (uint i = 0; i < num; ++i) {
- Graphics::colorToRGB<Graphics::ColorMasks<565> >(_palette[start + i], r, g, b);
- p[0] = r;
- p[1] = g;
- p[2] = b;
- p[3] = 0xff;
- p += 4;
+ Graphics::colorToRGB<Graphics::ColorMasks<565> >(s[start + i], r, g, b);
+ d[0] = r;
+ d[1] = g;
+ d[2] = b;
+ d[3] = 0xff;
+ d += 4;
}
}
void OSystem_Wii::setCursorPalette(const byte *colors, uint start, uint num) {
- const byte *p = colors;
+ if (!_texMouse.palette) {
+ printf("switching to palette based cursor\n");
+
+ if (!gfx_tex_init(&_texMouse, GFX_TF_PALETTE_RGB5A3, TLUT_MOUSE,
+ 16, 16)) {
+ printf("could not init the mouse texture\n");
+ ::abort();
+ }
+ }
+
+ if (_cursorPaletteDisabled) {
+ memcpy(_cursorPalette, _texMouse.palette, 256 * 2);
+ _cursorPaletteDisabled = false;
+ }
+
+ const byte *s = colors;
+ u16 *d = _texMouse.palette;
+
for (uint i = 0; i < num; ++i) {
- _cursorPalette[start + i] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(p[0], p[1], p[2]);
- p += 4;
+ d[start + i] = Graphics::ARGBToColor<Graphics::ColorMasks<3444> >(0xff, s[0], s[1], s[2]);
+ s += 4;
}
- _cursorPaletteDisabled = false;
+ _cursorPaletteDirty = true;
}
void OSystem_Wii::disableCursorPalette(bool disable) {
_cursorPaletteDisabled = disable;
+
+ if (_texMouse.palette && disable) {
+ memcpy(_texMouse.palette, _cursorPalette, 256 * 2);
+ _cursorPaletteDirty = true;
+ }
}
void OSystem_Wii::copyRectToScreen(const byte *buf, int pitch, int x, int y,
@@ -274,12 +353,12 @@ void OSystem_Wii::copyRectToScreen(const byte *buf, int pitch, int x, int y,
assert(h > 0 && y + h <= _gameHeight);
#ifdef USE_RGB_COLOR
- if (_screenPF.bytesPerPixel > 1) {
+ if (_pfGame.bytesPerPixel > 1) {
if (!Graphics::crossBlit(_gamePixels +
- y * _gameWidth * _screenPF.bytesPerPixel +
- x * _screenPF.bytesPerPixel,
- buf, _gameWidth * _screenPF.bytesPerPixel,
- pitch, w, h, _texturePF, _screenPF)) {
+ y * _gameWidth * _pfGame.bytesPerPixel +
+ x * _pfGame.bytesPerPixel,
+ buf, _gameWidth * _pfGame.bytesPerPixel,
+ pitch, w, h, _pfGameTexture, _pfGame)) {
printf("crossBlit failed\n");
::abort();
}
@@ -298,17 +377,13 @@ void OSystem_Wii::copyRectToScreen(const byte *buf, int pitch, int x, int y,
#ifdef USE_RGB_COLOR
}
#endif
+
+ _gameDirty = true;
}
void OSystem_Wii::updateScreen() {
- static u32 x, y, h, skip;
- static s16 msx, msy, mox, moy, mskip;
- static u16 mpx, mpy;
- static u8 *s;
-#ifdef USE_RGB_COLOR
- static u16 *s2;
-#endif
- static u16 *d, *p;
+ static gfx_coords_t cc;
+ static int cs;
u32 now = getMillis();
if (now - _lastScreenUpdate < 1000 / MAX_FPS)
@@ -318,111 +393,52 @@ void OSystem_Wii::updateScreen() {
wii_memstats();
#endif
+ cs = _cursorScale;
_lastScreenUpdate = now;
- h = 0;
- if (_overlayVisible) {
- memcpy(_texture, _overlayPixels, _overlaySize);
- } else {
-#ifdef USE_RGB_COLOR
- if (_screenPF.bytesPerPixel > 1) {
- memcpy(_texture, _gamePixels,
- _gameWidth * _gameHeight * _screenPF.bytesPerPixel);
- } else {
-#endif
- for (y = 0; y < _gameHeight; ++y) {
- for (x = 0; x < _gameWidth; ++x)
- _texture[h + x] = _palette[_gamePixels[h + x]];
+ gfx_frame_start();
- h += _gameWidth;
- }
-#ifdef USE_RGB_COLOR
+
+ if (_gameRunning) {
+ if (_gameDirty) {
+ gfx_tex_convert(&_texGame, _gamePixels);
+ _gameDirty = false;
}
-#endif
+
+ gfx_draw_tex(&_texGame, &_coordsGame);
}
- if (_mouseVisible) {
- msx = _mouseX - _mouseHotspotX;
- msy = _mouseY - _mouseHotspotY;
- mox = 0;
- moy = 0;
- mpx = _mouseWidth;
- mpy = _mouseHeight;
-
- if (msx < 0) {
- mox = -msx;
- mpx -= mox;
- msx = 0;
- } else
- if (msx + mpx > _currentWidth - 1)
- mpx = _currentWidth - msx - 1;
-
- if (msy < 0) {
- moy = -msy;
- mpy -= moy;
- msy = 0;
- } else
- if (msy + mpy + 1 > _currentHeight - 1)
- mpy = _currentHeight - msy - 1;
-
-
- if (_cursorPaletteDisabled)
- p = _palette;
+ if (_overlayVisible) {
+ // ugly, but the modern theme sets a factor of 3, only god knows why
+ if (cs > 2)
+ cs = 1;
else
- p = _cursorPalette;
-
- skip = _currentWidth - mpx;
- mskip = _mouseWidth - mpx;
-
-#ifdef USE_RGB_COLOR
- if (_cursorPF.bytesPerPixel > 1) {
- s2 = (u16 *) _mouseCursor + moy * _mouseWidth + mox;
- d = _texture + (msy * _currentWidth + msx);
-
- for (y = 0; y < mpy; ++y) {
- for (x = 0; x < mpx; ++x) {
- if (*s2 == _mouseKeyColor) {
- s2++;
- d++;
-
- continue;
- }
+ cs *= 2;
- *d++ = *s2;
- s2++;
- }
-
- d += skip;
- s2 += mskip;
- }
- } else {
-#endif
- s = _mouseCursor + moy * _mouseWidth + mox;
- d = _texture + (msy * _currentWidth + msx);
-
- for (y = 0; y < mpy; ++y) {
- for (x = 0; x < mpx; ++x) {
- if (*s == _mouseKeyColor) {
- s++;
- d++;
-
- continue;
- }
+ if (_overlayDirty) {
+ gfx_tex_convert(&_texOverlay, _overlayPixels);
+ _overlayDirty = false;
+ }
- *d++ = p[*s];
- s++;
- }
+ gfx_draw_tex(&_texOverlay, &_coordsOverlay);
+ }
- d += skip;
- s += mskip;
- }
-#ifdef USE_RGB_COLOR
+ if (_mouseVisible) {
+ cc.x = f32(_mouseX - cs * _mouseHotspotX) * _currentXScale;
+ cc.y = f32(_mouseY - cs * _mouseHotspotY) * _currentYScale;
+ cc.w = f32(_texMouse.width) * _currentXScale * cs;
+ cc.h = f32(_texMouse.height) * _currentYScale * cs;
+
+ if (_texMouse.palette && _cursorPaletteDirty) {
+ _texMouse.palette[_mouseKeyColor] = 0;
+ gfx_tex_flush_palette(&_texMouse);
+ _cursorPaletteDirty = false;
}
-#endif
+
+ gfx_draw_tex(&_texMouse, &cc);
}
- GX_Render(_currentWidth, _currentHeight, (u8 *) _texture,
- _currentWidth * 2);
+ gfx_frame_end();
}
Graphics::Surface *OSystem_Wii::lockScreen() {
@@ -431,7 +447,7 @@ Graphics::Surface *OSystem_Wii::lockScreen() {
_surface.h = _gameHeight;
_surface.pitch = _gameWidth;
#ifdef USE_RGB_COLOR
- _surface.bytesPerPixel = _screenPF.bytesPerPixel;
+ _surface.bytesPerPixel = _pfGame.bytesPerPixel;
#else
_surface.bytesPerPixel = 1;
#endif
@@ -440,35 +456,31 @@ Graphics::Surface *OSystem_Wii::lockScreen() {
}
void OSystem_Wii::unlockScreen() {
+ _gameDirty = true;
}
void OSystem_Wii::setShakePos(int shakeOffset) {
- GX_SetTexTrans(0, (float) -shakeOffset * ((float) vmode->efbHeight /
- (float) _currentHeight));
+ gfx_coords(&_coordsGame, &_texGame, GFX_COORD_FULLSCREEN);
+ _coordsGame.y -= f32(shakeOffset) * _currentYScale;
}
void OSystem_Wii::showOverlay() {
_mouseX = _overlayWidth / 2;
_mouseY = _overlayHeight / 2;
_overlayVisible = true;
- _currentWidth = _overlayWidth;
- _currentHeight = _overlayHeight;
-
- updateEventScreenResolution();
+ updateScreenResolution();
}
void OSystem_Wii::hideOverlay() {
_mouseX = _gameWidth / 2;
_mouseY = _gameHeight / 2;
_overlayVisible = false;
- _currentWidth = _gameWidth;
- _currentHeight = _gameHeight;
-
- updateEventScreenResolution();
+ updateScreenResolution();
}
void OSystem_Wii::clearOverlay() {
memset(_overlayPixels, 0, _overlaySize);
+ _overlayDirty = true;
}
void OSystem_Wii::grabOverlay(OverlayColor *buf, int pitch) {
@@ -515,6 +527,8 @@ void OSystem_Wii::copyRectToOverlay(const OverlayColor *buf, int pitch, int x,
dst += _overlayWidth;
} while (--h);
}
+
+ _overlayDirty = true;
}
int16 OSystem_Wii::getOverlayWidth() {
@@ -526,7 +540,7 @@ int16 OSystem_Wii::getOverlayHeight() {
}
Graphics::PixelFormat OSystem_Wii::getOverlayFormat() const {
- return Graphics::createPixelFormat<565>();
+ return Graphics::createPixelFormat<3444>();
}
bool OSystem_Wii::showMouse(bool visible) {
@@ -545,34 +559,103 @@ void OSystem_Wii::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
int hotspotY, uint32 keycolor,
int cursorTargetScale,
const Graphics::PixelFormat *format) {
- (void) cursorTargetScale; // TODO
+ gfx_tex_format_t tex_format = GFX_TF_PALETTE_RGB5A3;
+ uint tw, th;
+ bool tmpBuf = false;
+ uint32 oldKeycolor = _mouseKeyColor;
#ifdef USE_RGB_COLOR
if (!format)
- _cursorPF = Graphics::PixelFormat::createFormatCLUT8();
+ _pfCursor = Graphics::PixelFormat::createFormatCLUT8();
else
- _cursorPF = *format;
+ _pfCursor = *format;
- if (_cursorPF.bytesPerPixel > 1)
+ if (_pfCursor.bytesPerPixel > 1) {
+ tex_format = GFX_TF_RGB5A3;
_mouseKeyColor = keycolor & 0xffff;
- else
+ tw = ROUNDUP(w, 4);
+ th = ROUNDUP(h, 4);
+
+ if (_pfCursor != _pfRGB3444)
+ tmpBuf = true;
+ } else {
#endif
_mouseKeyColor = keycolor & 0xff;
+ tw = ROUNDUP(w, 8);
+ th = ROUNDUP(h, 4);
+#ifdef USE_RGB_COLOR
+ }
+#endif
- _mouseWidth = w;
- _mouseHeight = h;
- _mouseHotspotX = hotspotX;
- _mouseHotspotY = hotspotY;
+ if (!gfx_tex_init(&_texMouse, tex_format, TLUT_MOUSE, tw, th)) {
+ printf("could not init the mouse texture\n");
+ ::abort();
+ }
+
+ if ((tw != w) || (th != h))
+ tmpBuf = true;
- if (_mouseCursor)
- free(_mouseCursor);
+ if (!tmpBuf) {
+ gfx_tex_convert(&_texMouse, buf);
+ } else {
+ u8 bpp = _texMouse.bpp;
+ byte *tmp = (byte *) malloc(tw * th * bpp);
+
+ if (!tmp) {
+ printf("could not alloc temp cursor buffer\n");
+ ::abort();
+ }
+
+ if (bpp > 1)
+ memset(tmp, 0, tw * th * bpp);
+ else
+ memset(tmp, _mouseKeyColor, tw * th);
#ifdef USE_RGB_COLOR
- _mouseCursor = (u8 *) memalign(32, w * h * _cursorPF.bytesPerPixel);
- memcpy(_mouseCursor, buf, w * h * _cursorPF.bytesPerPixel);
-#else
- _mouseCursor = (u8 *) memalign(32, w * h);
- memcpy(_mouseCursor, buf, w * h);
+ if (bpp > 1) {
+ if (!Graphics::crossBlit(tmp, buf,
+ tw * _pfRGB3444.bytesPerPixel,
+ w * _pfCursor.bytesPerPixel,
+ tw, th, _pfRGB3444, _pfCursor)) {
+ printf("crossBlit failed\n");
+ ::abort();
+ }
+
+ // nasty, shouldn't the frontend set the alpha channel?
+ u16 *s = (u16 *) buf;
+ u16 *d = (u16 *) tmp;
+ for (u16 y = 0; y < h; ++y) {
+ for (u16 x = 0; x < w; ++x) {
+ if (*s++ != _mouseKeyColor)
+ *d++ |= 7 << 12;
+ else
+ d++;
+ }
+
+ d += tw - w;
+ }
+ } else {
#endif
+ byte *dst = tmp;
+
+ do {
+ memcpy(dst, buf, w * bpp);
+ buf += w * bpp;
+ dst += tw * bpp;
+ } while (--h);
+#ifdef USE_RGB_COLOR
+ }
+#endif
+
+ gfx_tex_convert(&_texMouse, tmp);
+ free(tmp);
+ }
+
+ _mouseHotspotX = hotspotX;
+ _mouseHotspotY = hotspotY;
+ _cursorScale = cursorTargetScale;
+
+ if ((_texMouse.palette) && (oldKeycolor != _mouseKeyColor))
+ _cursorPaletteDirty = true;
}