aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/wii
diff options
context:
space:
mode:
authorAndre Heider2009-08-30 17:01:03 +0000
committerAndre Heider2009-08-30 17:01:03 +0000
commit7d71fbeea22e79560db7f09b5eb1c53aae5175a5 (patch)
treee9209f3d11cb499216756df16e0e31b86661dda2 /backends/platform/wii
parent7ae8c8e451deed9dd49beba190a2acb297a55165 (diff)
downloadscummvm-rg350-7d71fbeea22e79560db7f09b5eb1c53aae5175a5.tar.gz
scummvm-rg350-7d71fbeea22e79560db7f09b5eb1c53aae5175a5.tar.bz2
scummvm-rg350-7d71fbeea22e79560db7f09b5eb1c53aae5175a5.zip
Complete GFX rewrite with new features:
- Standard and Dual-strike (240p) video modes, both with or without AA - Distinct textures for the overlay, game buffer and the cursor - Support for HW paletted textures - Less pixel buffer conversions - Cursor scaling - Support for kFeatureAspectRatioCorrection and kFeatureOverlaySupportsAlpha svn-id: r43830
Diffstat (limited to 'backends/platform/wii')
-rw-r--r--backends/platform/wii/gfx.cpp611
-rw-r--r--backends/platform/wii/gfx.h101
-rw-r--r--backends/platform/wii/gx_supp.cpp287
-rw-r--r--backends/platform/wii/gx_supp.h46
-rw-r--r--backends/platform/wii/main.cpp4
-rw-r--r--backends/platform/wii/module.mk2
-rw-r--r--backends/platform/wii/osystem.cpp83
-rw-r--r--backends/platform/wii/osystem.h38
-rw-r--r--backends/platform/wii/osystem_events.cpp24
-rw-r--r--backends/platform/wii/osystem_gfx.cpp567
10 files changed, 1141 insertions, 622 deletions
diff --git a/backends/platform/wii/gfx.cpp b/backends/platform/wii/gfx.cpp
new file mode 100644
index 0000000000..f34e2b1cca
--- /dev/null
+++ b/backends/platform/wii/gfx.cpp
@@ -0,0 +1,611 @@
+/*
+ * Gamecube/Wii VIDEO/GX subsystem wrapper
+ *
+ * Copyright (C) 2008, 2009 Andre Heider "dhewg" <dhewg@wiibrew.org>
+ *
+ * This code is licensed to you under the terms of the GNU GPL, version 2;
+ * see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+ *
+ */
+
+#include <malloc.h>
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+
+#include "gfx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FIFO_SIZE (256 * 1024)
+#define ORIGIN_Z (-500)
+
+static GXRModeObj *_vm = NULL;
+static bool _dualstrike = false;
+
+static u32 *_fb[2] = { NULL, NULL };
+static u8 _fb_active = 0;
+
+static u8 *_fifo = NULL;
+
+static u16 _underscan_x = 0;
+static u16 _underscan_y = 0;
+static f32 _ar = 4.0 / 3.0;
+static bool _pillarboxing = false;
+static Mtx _view;
+
+static struct {
+ guVector pos;
+ guVector up;
+ guVector view;
+} _camera = {
+ { 0.0f, 0.0f, 0.0f },
+ { 0.0f, 0.5f, 0.0f },
+ { 0.0f, 0.0f, -0.5f }
+};
+
+// Standard, StandardAa, Ds, DsAa
+static GXRModeObj *mode_table[5][4] = {
+ { &TVNtsc480Prog, &TVNtsc480ProgAa, &TVNtsc240Ds, &TVNtsc240DsAa },
+ { &TVNtsc480IntDf, &TVNtsc480IntAa, &TVNtsc240Ds, &TVNtsc240DsAa },
+ { &TVPal528IntDf, &TVPal524IntAa, &TVPal264Ds, &TVPal264DsAa },
+ { &TVEurgb60Hz480IntDf, &TVEurgb60Hz480IntAa, &TVEurgb60Hz240Ds, &TVEurgb60Hz240DsAa },
+ { &TVMpal480IntDf, &TVMpal480IntAa, &TVMpal240Ds, &TVMpal240DsAa }
+};
+
+static gfx_video_mode_t _gfx_video_get_mode(void) {
+ gfx_video_mode_t mode;
+
+#ifdef HW_RVL
+ if ((CONF_GetProgressiveScan() > 0) && VIDEO_HaveComponentCable()) {
+ mode = GFX_MODE_PROGRESSIVE;
+ } else {
+ switch (CONF_GetVideo()) {
+ case CONF_VIDEO_PAL:
+ if (CONF_GetEuRGB60() > 0)
+ mode = GFX_MODE_EURGB60;
+ else
+ mode = GFX_MODE_PAL;
+ break;
+
+ case CONF_VIDEO_MPAL:
+ mode = GFX_MODE_MPAL;
+ break;
+
+ default:
+ mode = GFX_MODE_NTSC;
+ break;
+ }
+ }
+#else
+ switch (VIDEO_GetCurrentTvMode()) {
+ case VI_PAL:
+ mode = GFX_MODE_PAL;
+ break;
+ case VI_MPAL:
+ mode = GFX_MODE_MPAL;
+ break;
+ default:
+ mode = GFX_MODE_NTSC;
+ break;
+ }
+#endif
+
+ return mode;
+}
+
+void gfx_video_init(gfx_video_mode_t mode, gfx_video_setup_t setup) {
+ u8 i;
+
+ if (mode == GFX_MODE_AUTO)
+ mode = _gfx_video_get_mode();
+
+ _vm = mode_table[mode][setup];
+
+ _vm->viWidth = 672;
+ _vm->viXOrigin = (VI_MAX_WIDTH_NTSC - _vm->viWidth) / 2;
+
+ if (_vm)
+ VIDEO_WaitVSync();
+
+ VIDEO_Configure(_vm);
+
+ if (_fb[0])
+ free(MEM_K1_TO_K0(_fb[0]));
+ if (_fb[1])
+ free(MEM_K1_TO_K0(_fb[1]));
+
+ _fb[0] = (u32 *) MEM_K0_TO_K1(SYS_AllocateFramebuffer(_vm));
+ _fb[1] = (u32 *) MEM_K0_TO_K1(SYS_AllocateFramebuffer(_vm));
+
+ VIDEO_ClearFrameBuffer(_vm, _fb[0], COLOR_BLACK);
+ VIDEO_ClearFrameBuffer(_vm, _fb[1], COLOR_BLACK);
+
+ VIDEO_SetNextFramebuffer(_fb[_fb_active]);
+ VIDEO_SetBlack(FALSE);
+ VIDEO_Flush();
+
+ for (i = 0; i < 4; ++i)
+ VIDEO_WaitVSync();
+}
+
+void gfx_video_deinit(void) {
+ u8 i;
+
+ VIDEO_WaitVSync();
+ VIDEO_SetBlack(TRUE);
+ VIDEO_SetNextFramebuffer(NULL);
+ VIDEO_Flush();
+
+ for (i = 0; i < 4; ++i)
+ VIDEO_WaitVSync();
+
+ if (_fb[0]) {
+ free(MEM_K1_TO_K0(_fb[0]));
+ _fb[0] = NULL;
+ }
+
+ if (_fb[1]) {
+ free(MEM_K1_TO_K0(_fb[1]));
+ _fb[1] = NULL;
+ }
+}
+
+u16 gfx_video_get_width(void) {
+ return _vm->fbWidth;
+}
+
+u16 gfx_video_get_height(void) {
+ return _vm->efbHeight;
+}
+
+static void _update_viewport(void) {
+ f32 ar;
+ u16 correction;
+
+ u16 x1 = _underscan_x * 2;
+ u16 y1 = _underscan_y * 2;
+ u16 x2 = _vm->fbWidth - _underscan_x * 4;
+ u16 y2 = _vm->efbHeight - _underscan_y * 4;
+
+ if (_pillarboxing)
+ ar = 16.0 / 9.0;
+ else
+ ar = 4.0 / 3.0;
+
+ if (fabs(ar - _ar) > 0.01) {
+ if (ar > _ar) {
+ correction = _vm->viWidth -
+ (u16) round((f32) _vm->viWidth * _ar / ar);
+
+ x1 += correction / 2;
+ x2 -= correction;
+ } else {
+ correction = _vm->efbHeight -
+ (u16) round((f32) _vm->efbHeight * ar / _ar);
+
+ if (_dualstrike)
+ correction /= 2;
+
+ y1 += correction / 2;
+ y2 -= correction;
+ }
+ }
+
+ GX_SetViewport(x1, y1, x2, y2, 0, 1);
+ GX_SetScissor(x1, y1, x2, y2);
+}
+
+void gfx_init(void) {
+ Mtx44 p;
+ GXColor bg = { 0, 0, 0, 0xff };
+ f32 yscale;
+ u32 xfbHeight;
+
+ GX_AbortFrame();
+
+ if (!_fifo)
+ _fifo = (u8 *) memalign(32, FIFO_SIZE);
+
+ memset(_fifo, 0, FIFO_SIZE);
+ GX_Init(_fifo, FIFO_SIZE);
+
+ GX_SetCopyClear(bg, 0x00ffffff);
+
+ _update_viewport();
+
+ _dualstrike = _vm->viHeight == 2 * _vm->xfbHeight;
+ yscale = GX_GetYScaleFactor(_vm->efbHeight, _vm->xfbHeight);
+ xfbHeight = GX_SetDispCopyYScale(yscale);
+ GX_SetDispCopySrc(0, 0, _vm->fbWidth, _vm->efbHeight);
+ GX_SetDispCopyDst(_vm->fbWidth, xfbHeight);
+ GX_SetCopyFilter(_vm->aa, _vm->sample_pattern, GX_TRUE, _vm->vfilter);
+ GX_SetFieldMode(_vm->field_rendering, _dualstrike ? GX_ENABLE : GX_DISABLE);
+
+ if (_vm->aa)
+ GX_SetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR);
+ else
+ GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
+
+ GX_SetCullMode(GX_CULL_NONE);
+ GX_SetDispCopyGamma(GX_GM_1_0);
+
+ GX_ClearVtxDesc();
+ GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
+ GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
+ GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
+
+ GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
+ GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
+ GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
+
+ GX_InvVtxCache();
+ GX_InvalidateTexAll();
+
+ memset(&_view, 0, sizeof(Mtx));
+ guLookAt(_view, &_camera.pos, &_camera.up, &_camera.view);
+
+ guOrtho(p, 0, _vm->efbHeight, 0, _vm->fbWidth, 100, 1000);
+ GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC);
+
+ GX_Flush();
+}
+
+void gfx_deinit(void) {
+ GX_AbortFrame();
+
+ free(_fifo);
+ _fifo = NULL;
+}
+
+void gfx_set_underscan(u16 underscan_x, u16 underscan_y) {
+ _underscan_x = underscan_x;
+ _underscan_y = underscan_y;
+
+ if (_underscan_x > 32)
+ _underscan_x = 32;
+
+ if (_underscan_y > 32)
+ _underscan_y = 32;
+
+ _update_viewport();
+ GX_Flush();
+}
+
+void gfx_set_ar(f32 ar) {
+ _ar = ar;
+
+ if (ar < 16.0 / 480.0)
+ ar = 16.0 / 480.0;
+
+ if (ar > 640.0 / 16.0)
+ ar = 640.0 / 16.0;
+
+ _update_viewport();
+ GX_Flush();
+}
+
+void gfx_set_pillarboxing(bool enable) {
+ _pillarboxing = enable;
+
+ _update_viewport();
+ GX_Flush();
+}
+
+bool gfx_tex_init(gfx_tex_t *tex, gfx_tex_format_t format, u32 tlut_name,
+ u16 width, u16 height) {
+ u8 bpp;
+ u8 fmt_tex;
+ bool tlut;
+ u8 fmt_tlut;
+ u32 ax, ay;
+ u32 memsize;
+
+ if (!tex)
+ return false;
+
+ switch(format) {
+ case GFX_TF_RGB565:
+ bpp = 2;
+ fmt_tex = GX_TF_RGB565;
+ tlut = false;
+ fmt_tlut = 0;
+ ax = 3;
+ ay = 3;
+ break;
+
+ case GFX_TF_RGB5A3:
+ bpp = 2;
+ fmt_tex = GX_TF_RGB5A3;
+ tlut = false;
+ fmt_tlut = 0;
+ ax = 3;
+ ay = 3;
+ break;
+
+ case GFX_TF_PALETTE_RGB565:
+ bpp = 1;
+ fmt_tex = GX_TF_CI8;
+ tlut = true;
+ fmt_tlut = GX_TL_RGB565;
+ ax = 7;
+ ay = 3;
+ break;
+
+ case GFX_TF_PALETTE_RGB5A3:
+ bpp = 1;
+ fmt_tex = GX_TF_CI8;
+ tlut = true;
+ fmt_tlut = GX_TL_RGB5A3;
+ ax = 7;
+ ay = 3;
+ break;
+
+ default:
+ gfx_tex_deinit(tex);
+ return false;
+ }
+
+ if ((width & ax) || (height & ay)) {
+ gfx_tex_deinit(tex);
+ return false;
+ }
+
+ if (tlut) {
+ if (!tex->palette) {
+ tex->palette = (u16 *) memalign(32, 256 * 2);
+ if (!tex->palette) {
+ gfx_tex_deinit(tex);
+ return false;
+ }
+
+ memset(tex->palette, 0, 256 * 2);
+ DCFlushRange(tex->palette, 256 * 2);
+ }
+
+ tex->tlut_name = tlut_name;
+ GX_InitTlutObj(&tex->tlut, tex->palette, fmt_tlut, 256);
+ } else {
+ tex->tlut_name = 0;
+ free(tex->palette);
+ tex->palette = NULL;
+ }
+
+ if (!tex->pixels || (width != tex->width) || (height != tex->height ||
+ bpp != tex->bpp)) {
+ free(tex->pixels);
+
+ memsize = width * height * bpp;
+ tex->pixels = memalign(32, memsize);
+
+ if (!tex->pixels) {
+ gfx_tex_deinit(tex);
+ return false;
+ }
+
+ memset(tex->pixels, 0, memsize);
+ DCFlushRange(tex->pixels, memsize);
+ }
+
+ tex->format = format;
+ tex->width = width;
+ tex->height = height;
+ tex->bpp = bpp;
+
+ if (tlut) {
+ GX_LoadTlut(&tex->tlut, tlut_name);
+ GX_InitTexObjCI(&tex->obj, tex->pixels, width, height, fmt_tex,
+ GX_CLAMP, GX_CLAMP, GX_FALSE, tlut_name);
+ } else {
+ GX_InitTexObj(&tex->obj, tex->pixels, width, height, fmt_tex,
+ GX_CLAMP, GX_CLAMP, GX_FALSE);
+ }
+
+ return true;
+}
+
+void gfx_tex_deinit(gfx_tex_t *tex) {
+ if (!tex)
+ return;
+
+ free(tex->pixels);
+ free(tex->palette);
+ memset(tex, 0, sizeof(gfx_tex_t));
+}
+
+void gfx_coords(gfx_coords_t *coords, gfx_tex_t *tex, gfx_coord_t type) {
+ if (!coords || !tex)
+ return;
+
+ switch(type) {
+ case GFX_COORD_FULLSCREEN:
+ coords->x = 0.0;
+ coords->y = 0.0;
+ coords->w = _vm->fbWidth;
+ coords->h = _vm->efbHeight;
+ break;
+
+ case GFX_COORD_CENTER:
+ coords->x = (_vm->fbWidth - tex->width) / 2;
+ coords->y = (_vm->efbHeight - tex->height) / 2;
+ coords->w = tex->width;
+ coords->h = tex->height;
+ break;
+
+ default:
+ break;
+ }
+}
+
+bool gfx_tex_flush_texture(gfx_tex_t *tex) {
+ if (!tex)
+ return false;
+
+ DCFlushRange(tex->pixels, tex->width * tex->height * tex->bpp);
+ return true;
+}
+
+bool gfx_tex_flush_palette(gfx_tex_t *tex) {
+ if (!tex || !tex->palette)
+ return false;
+
+ DCFlushRange(tex->palette, 256 * 2);
+ GX_LoadTlut(&tex->tlut, tex->tlut_name);
+
+ return true;
+}
+
+bool gfx_tex_clear_palette(gfx_tex_t *tex) {
+ if (!tex || !tex->palette)
+ return false;
+
+ memset(tex->palette, 0, 256 * 2);
+ DCFlushRange(tex->palette, 256 * 2);
+ GX_LoadTlut(&tex->tlut, tex->tlut_name);
+
+ return true;
+}
+
+bool gfx_tex_convert(gfx_tex_t *tex, const void *src) {
+ bool ret;
+ u16 w, h, x, y;
+ u64 *dst, *src1, *src2, *src3, *src4;
+ u16 rowpitch;
+ u16 pitch;
+ const u8 *s = (const u8 *) src;
+
+ if (!tex)
+ return false;
+
+ ret = false;
+ w = tex->width;
+ h = tex->height;
+
+ switch(tex->format) {
+ case GFX_TF_RGB565:
+ case GFX_TF_RGB5A3:
+ pitch = w * 2;
+ dst = (u64 *) tex->pixels;
+ src1 = (u64 *) s;
+ src2 = (u64 *) (s + pitch);
+ src3 = (u64 *) (s + (pitch * 2));
+ src4 = (u64 *) (s + (pitch * 3));
+ rowpitch = (pitch >> 3) * 3 + pitch % 8;
+
+ for (y = 0; y < h; y += 4) {
+ for (x = 0; x < (w >> 2); x++) {
+ *dst++ = *src1++;
+ *dst++ = *src2++;
+ *dst++ = *src3++;
+ *dst++ = *src4++;
+ }
+
+ src1 += rowpitch;
+ src2 += rowpitch;
+ src3 += rowpitch;
+ src4 += rowpitch;
+ }
+
+ ret = true;
+ break;
+
+ case GFX_TF_PALETTE_RGB565:
+ case GFX_TF_PALETTE_RGB5A3:
+ pitch = w;
+ dst = (u64 *) tex->pixels;
+ src1 = (u64 *) s;
+ src2 = (u64 *) (s + pitch);
+ src3 = (u64 *) (s + (pitch * 2));
+ src4 = (u64 *) (s + (pitch * 3));
+ rowpitch = (pitch >> 3) * 3 + pitch % 8;
+
+ for (y = 0; y < h; y += 4) {
+ for (x = 0; x < (w >> 3); x++) {
+ *dst++ = *src1++;
+ *dst++ = *src2++;
+ *dst++ = *src3++;
+ *dst++ = *src4++;
+ }
+
+ src1 += rowpitch;
+ src2 += rowpitch;
+ src3 += rowpitch;
+ src4 += rowpitch;
+ }
+
+ ret = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if (ret)
+ DCFlushRange(tex->pixels, w * h * tex->bpp);
+
+ return ret;
+}
+
+void gfx_frame_start(void) {
+ GX_InvVtxCache();
+ GX_InvalidateTexAll();
+
+ GX_SetNumChans(1);
+ GX_SetNumTexGens(1);
+ GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
+
+ GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
+ GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
+
+ GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
+}
+
+void gfx_frame_end(void) {
+ GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
+ GX_SetColorUpdate(GX_TRUE);
+
+ GX_CopyDisp(_fb[_fb_active], GX_TRUE);
+ GX_Flush();
+ GX_DrawDone();
+
+ VIDEO_SetNextFramebuffer(_fb[_fb_active]);
+ VIDEO_Flush();
+ VIDEO_WaitVSync();
+
+ _fb_active ^= 1;
+}
+
+static void _tex_vert(f32 x, f32 y, f32 z, f32 s, f32 t, u32 c) {
+ GX_Position3f32(x, y, z);
+ GX_Color1u32(c);
+ GX_TexCoord2f32(s, t);
+}
+
+void gfx_draw_tex(gfx_tex_t *tex, gfx_coords_t *coords) {
+ Mtx m;
+ Mtx mv;
+
+ if (!tex || !coords)
+ return;
+
+ GX_LoadTexObj(&tex->obj, GX_TEXMAP0);
+
+ guMtxIdentity(m);
+ guMtxTrans(m, coords->x, coords->y, ORIGIN_Z);
+ guMtxConcat(_view, m, mv);
+ GX_LoadPosMtxImm(mv, GX_PNMTX0);
+
+ GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
+ _tex_vert(0.0, 0.0, 0.0, 0.0, 0.0, 0xffffffff);
+ _tex_vert(coords->w, 0.0, 0.0, 1.0, 0.0, 0xffffffff);
+ _tex_vert(coords->w, coords->h, 0.0, 1.0, 1.0, 0xffffffff);
+ _tex_vert(0.0, coords->h, 0.0, 0.0, 1.0, 0xffffffff);
+ GX_End();
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/backends/platform/wii/gfx.h b/backends/platform/wii/gfx.h
new file mode 100644
index 0000000000..f4c49653c5
--- /dev/null
+++ b/backends/platform/wii/gfx.h
@@ -0,0 +1,101 @@
+/*
+ * Gamecube/Wii VIDEO/GX subsystem wrapper
+ *
+ * Copyright (C) 2008, 2009 Andre Heider "dhewg" <dhewg@wiibrew.org>
+ *
+ * This code is licensed to you under the terms of the GNU GPL, version 2;
+ * see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+ *
+ */
+
+#ifndef __GFX_H__
+#define __GFX_H__
+
+#include <gccore.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ GFX_MODE_AUTO = -1,
+ GFX_MODE_PROGRESSIVE = 0,
+ GFX_MODE_NTSC,
+ GFX_MODE_PAL,
+ GFX_MODE_EURGB60,
+ GFX_MODE_MPAL
+} gfx_video_mode_t;
+
+typedef enum {
+ GFX_SETUP_STANDARD = 0,
+ GFX_SETUP_STANDARD_AA,
+ GFX_SETUP_DS,
+ GFX_SETUP_DS_AA
+} gfx_video_setup_t;
+
+typedef enum {
+ GFX_TF_RGB565 = 0,
+ GFX_TF_RGB5A3,
+ GFX_TF_PALETTE_RGB565,
+ GFX_TF_PALETTE_RGB5A3
+} gfx_tex_format_t;
+
+typedef struct {
+ void *pixels;
+ u16 *palette;
+
+ gfx_tex_format_t format;
+ u16 width;
+ u16 height;
+ u8 bpp;
+ GXTexObj obj;
+ GXTlutObj tlut;
+ u32 tlut_name;
+} gfx_tex_t;
+
+typedef enum {
+ GFX_COORD_FULLSCREEN = 0,
+ GFX_COORD_CENTER
+} gfx_coord_t;
+
+typedef struct {
+ f32 x, y;
+ f32 w, h;
+} gfx_coords_t;
+
+void gfx_video_init(gfx_video_mode_t mode, gfx_video_setup_t setup);
+void gfx_video_deinit(void);
+
+u16 gfx_video_get_width(void);
+u16 gfx_video_get_height(void);
+
+void gfx_init(void);
+void gfx_deinit(void);
+
+void gfx_set_underscan(u16 underscan_x, u16 underscan_y);
+void gfx_set_ar(f32 ar);
+void gfx_set_pillarboxing(bool enable);
+
+bool gfx_tex_init(gfx_tex_t *tex, gfx_tex_format_t format, u32 tlut_name,
+ u16 width, u16 height);
+void gfx_tex_deinit(gfx_tex_t *tex);
+
+void gfx_coords(gfx_coords_t *coords, gfx_tex_t *tex, gfx_coord_t type);
+
+bool gfx_tex_flush_texture(gfx_tex_t *tex);
+bool gfx_tex_flush_palette(gfx_tex_t *tex);
+bool gfx_tex_clear_palette(gfx_tex_t *tex);
+
+bool gfx_tex_convert(gfx_tex_t *tex, const void *src);
+
+void gfx_frame_start(void);
+void gfx_frame_end(void);
+
+void gfx_draw_tex(gfx_tex_t *tex, gfx_coords_t *coords);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/backends/platform/wii/gx_supp.cpp b/backends/platform/wii/gx_supp.cpp
deleted file mode 100644
index f33adae566..0000000000
--- a/backends/platform/wii/gx_supp.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/****************************************************************************
-* Generic GX Support for Emulators
-* softdev 2007
-* dhewg 2008
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*
-* NGC GX Video Functions
-*
-* These are pretty standard functions to setup and use GX scaling.
-****************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <malloc.h>
-
-#include "gx_supp.h"
-
-#define DEFAULT_FIFO_SIZE (256 * 1024)
-
-#define HASPECT 320
-#define VASPECT 240
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*** 2D ***/
-static u32 whichfb;
-static u32 *xfb[2];
-GXRModeObj *vmode = NULL;
-
-/*** 3D GX ***/
-static u8 *gp_fifo;
-
-/*** Texture memory ***/
-static u8 *texturemem = NULL;
-static u32 texturesize;
-
-static GXTexObj texobj;
-static Mtx view;
-static u16 vwidth, vheight, oldvwidth, oldvheight;
-static float tex_xT = 0.0f, tex_yT = 0.0f;
-
-/* New texture based scaler */
-typedef struct tagcamera {
- guVector pos;
- guVector up;
- guVector view;
-} camera;
-
-static s16 square[] ATTRIBUTE_ALIGN(32) = {
- -HASPECT, VASPECT, 0,
- HASPECT, VASPECT, 0,
- HASPECT, -VASPECT, 0,
- -HASPECT, -VASPECT, 0,
-};
-
-static camera cam = {
- { 0.0f, 0.0f, 370.0f },
- { 0.0f, 0.5f, 0.0f },
- { 0.0f, 0.0f, -0.5f }
-};
-
-void GX_InitVideo() {
- vmode = VIDEO_GetPreferredMode(NULL);
-
- vmode->viWidth = 688;
- vmode->viXOrigin = (VI_MAX_WIDTH_PAL - 688) / 2;
-
- VIDEO_Configure(vmode);
-
- xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer(vmode));
- xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer(vmode));
- gp_fifo = (u8 *) memalign(32, DEFAULT_FIFO_SIZE);
-
- VIDEO_ClearFrameBuffer(vmode, xfb[0], COLOR_BLACK);
- VIDEO_ClearFrameBuffer(vmode, xfb[1], COLOR_BLACK);
-
- whichfb = 0;
- VIDEO_SetNextFramebuffer(xfb[whichfb]);
- VIDEO_SetBlack(FALSE);
- VIDEO_Flush();
- VIDEO_WaitVSync();
-
- if (vmode->viTVMode & VI_NON_INTERLACE)
- VIDEO_WaitVSync();
-}
-
-void GX_SetTexTrans(float xT, float yT) {
- tex_xT = xT;
- tex_yT = yT;
-}
-
-void GX_SetCamPosZ(float f) {
- cam.pos.z = f;
-}
-
-/****************************************************************************
- * Scaler Support Functions
- ****************************************************************************/
-static void draw_init(void) {
- GX_ClearVtxDesc();
- GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
- GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX8);
- GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
-
- GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
- GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
- GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
-
- GX_SetArray(GX_VA_POS, square, 3 * sizeof(s16));
-
- GX_SetNumTexGens(1);
- GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
-
- GX_InvalidateTexAll();
-
- GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565,
- GX_CLAMP, GX_CLAMP, GX_FALSE);
-}
-
-static void draw_vert(u8 pos, u8 c, f32 s, f32 t) {
- GX_Position1x8(pos);
- GX_Color1x8(c);
- GX_TexCoord2f32(s, t);
-}
-
-static void draw_square(Mtx v) {
- Mtx m;
- Mtx mv;
-
- guMtxIdentity(m);
- guMtxTransApply(m, m, tex_xT, tex_yT, -100);
- guMtxConcat(v, m, mv);
-
- GX_LoadPosMtxImm(mv, GX_PNMTX0);
- GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
- draw_vert(0, 0, 0.0, 0.0);
- draw_vert(1, 0, 1.0, 0.0);
- draw_vert(2, 0, 1.0, 1.0);
- draw_vert(3, 0, 0.0, 1.0);
- GX_End();
-}
-
-/****************************************************************************
- * StartGX
- ****************************************************************************/
-void GX_Start(u16 width, u16 height, s16 haspect, s16 vaspect) {
- static bool inited = false;
- Mtx p;
- GXColor gxbackground = { 0, 0, 0, 0xff };
-
- /*** Set new aspect ***/
- square[0] = square[9] = -haspect;
- square[3] = square[6] = haspect;
- square[1] = square[4] = vaspect;
- square[7] = square[10] = -vaspect;
-
- /*** Allocate 32byte aligned texture memory ***/
- texturesize = (width * height) * 2;
-
- if (texturemem)
- free(texturemem);
-
- texturemem = (u8 *) memalign(32, texturesize);
- memset(texturemem, 0, texturesize);
-
- /*** Setup for first call to scaler ***/
- oldvwidth = oldvheight = 0;
-
- if (inited)
- return;
-
- inited = true;
-
- /*** Clear out FIFO area ***/
- memset(gp_fifo, 0, DEFAULT_FIFO_SIZE);
-
- /*** Initialise GX ***/
- GX_Init(gp_fifo, DEFAULT_FIFO_SIZE);
- GX_SetCopyClear(gxbackground, 0x00ffffff);
-
- GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
- GX_SetDispCopyYScale((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
- GX_SetScissor(0, 0, vmode->fbWidth, vmode->efbHeight);
- GX_SetDispCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight);
- GX_SetDispCopyDst(vmode->fbWidth, vmode->xfbHeight);
- GX_SetCopyFilter(vmode->aa, vmode->sample_pattern, GX_TRUE,
- vmode->vfilter);
- GX_SetFieldMode(vmode->field_rendering,
- ((vmode->viHeight == 2 * vmode->xfbHeight) ?
- GX_ENABLE : GX_DISABLE));
- GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
- GX_SetCullMode(GX_CULL_NONE);
- GX_CopyDisp(xfb[whichfb ^ 1], GX_TRUE);
- GX_SetDispCopyGamma(GX_GM_1_0);
-
- guPerspective(p, 60, 1.33f, 10.0f, 1000.0f);
- GX_LoadProjectionMtx(p, GX_PERSPECTIVE);
-
- GX_Flush();
-}
-
-/****************************************************************************
-* GX_Render
-*
-* Pass in a buffer, width and height to update as a tiled RGB565 texture
-****************************************************************************/
-void GX_Render(u16 width, u16 height, u8 *buffer, u16 pitch) {
- u16 h, w;
- u64 *dst = (u64 *) texturemem;
- u64 *src1 = (u64 *) buffer;
- u64 *src2 = (u64 *) (buffer + pitch);
- u64 *src3 = (u64 *) (buffer + (pitch * 2));
- u64 *src4 = (u64 *) (buffer + (pitch * 3));
- u16 rowpitch = (pitch >> 3) * 3 + pitch % 8;
-
- vwidth = width;
- vheight = height;
-
- whichfb ^= 1;
-
- if ((oldvheight != vheight) || (oldvwidth != vwidth)) {
- /** Update scaling **/
- oldvwidth = vwidth;
- oldvheight = vheight;
- draw_init();
- memset(&view, 0, sizeof(Mtx));
- guLookAt(view, &cam.pos, &cam.up, &cam.view);
- GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
- }
-
- GX_InvVtxCache();
- GX_InvalidateTexAll();
- GX_SetTevOp(GX_TEVSTAGE0, GX_DECAL);
- GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
-
- for (h = 0; h < vheight; h += 4) {
- for (w = 0; w < (vwidth >> 2); w++) {
- *dst++ = *src1++;
- *dst++ = *src2++;
- *dst++ = *src3++;
- *dst++ = *src4++;
- }
-
- src1 += rowpitch;
- src2 += rowpitch;
- src3 += rowpitch;
- src4 += rowpitch;
- }
-
- DCFlushRange(texturemem, texturesize);
-
- GX_SetNumChans(1);
- GX_LoadTexObj(&texobj, GX_TEXMAP0);
-
- draw_square(view);
-
- GX_DrawDone();
-
- GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
- GX_SetColorUpdate(GX_TRUE);
- GX_CopyDisp(xfb[whichfb], GX_TRUE);
- GX_Flush();
-
- VIDEO_SetNextFramebuffer(xfb[whichfb]);
- VIDEO_Flush();
-}
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/backends/platform/wii/gx_supp.h b/backends/platform/wii/gx_supp.h
deleted file mode 100644
index 3433ef8df5..0000000000
--- a/backends/platform/wii/gx_supp.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/****************************************************************************
-* Generic GX Scaler
-* softdev 2007
-* dhewg 2008
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*
-* NGC GX Video Functions
-*
-* These are pretty standard functions to setup and use GX scaling.
-****************************************************************************/
-#ifndef _WII_GX_SUPP_H_
-#define _WII_GX_SUPP_H_
-
-#include <gccore.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern GXRModeObj *vmode;
-
-void GX_InitVideo();
-void GX_SetTexTrans(float xT, float yT);
-void GX_SetCamPosZ(float f);
-
-void GX_Start(u16 width, u16 height, s16 haspect, s16 vaspect);
-void GX_Render(u16 width, u16 height, u8 *buffer, u16 pitch);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/backends/platform/wii/main.cpp b/backends/platform/wii/main.cpp
index c714a2a10e..801778395f 100644
--- a/backends/platform/wii/main.cpp
+++ b/backends/platform/wii/main.cpp
@@ -37,6 +37,8 @@
#include <debug.h>
#endif
+#include "gfx.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -153,6 +155,8 @@ int main(int argc, char *argv[]) {
printf("reloading\n");
+ gfx_video_deinit();
+
return res;
}
diff --git a/backends/platform/wii/module.mk b/backends/platform/wii/module.mk
index 912389902b..7a4d08b375 100644
--- a/backends/platform/wii/module.mk
+++ b/backends/platform/wii/module.mk
@@ -2,7 +2,7 @@ MODULE := backends/platform/wii
MODULE_OBJS := \
main.o \
- gx_supp.o \
+ gfx.o \
osystem.o \
osystem_gfx.o \
osystem_sfx.o \
diff --git a/backends/platform/wii/osystem.cpp b/backends/platform/wii/osystem.cpp
index 3f53605e85..50016db932 100644
--- a/backends/platform/wii/osystem.cpp
+++ b/backends/platform/wii/osystem.cpp
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "backends/fs/wii/wii-fs-factory.h"
#include "common/config-manager.h"
+#include "backends/fs/wii/wii-fs-factory.h"
#include "osystem.h"
@@ -32,68 +32,70 @@
OSystem_Wii::OSystem_Wii() :
_startup_time(0),
- _palette(NULL),
- _cursorPalette(NULL),
+ _cursorScale(1),
_cursorPaletteDisabled(true),
+ _cursorPalette(NULL),
+ _cursorPaletteDirty(false),
+ _gameRunning(false),
_gameWidth(0),
_gameHeight(0),
_gamePixels(NULL),
+ _gameDirty(false),
- _overlayVisible(false),
+ _overlayVisible(true),
_overlayWidth(0),
_overlayHeight(0),
_overlaySize(0),
_overlayPixels(NULL),
+ _overlayDirty(false),
_lastScreenUpdate(0),
- _texture(NULL),
_currentWidth(0),
_currentHeight(0),
+ _currentXScale(1),
+ _currentYScale(1),
- _activeGraphicsMode(0),
+ _configGraphicsMode(0),
+ _actualGraphicsMode(0),
#ifdef USE_RGB_COLOR
- _texturePF(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)),
- _screenPF(Graphics::PixelFormat::createFormatCLUT8()),
- _cursorPF(Graphics::PixelFormat::createFormatCLUT8()),
+ _pfRGB565(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)),
+ _pfRGB3444(Graphics::PixelFormat(2, 4, 4, 4, 3, 8, 4, 0, 12)),
+ _pfGame(Graphics::PixelFormat::createFormatCLUT8()),
+ _pfGameTexture(Graphics::PixelFormat::createFormatCLUT8()),
+ _pfCursor(Graphics::PixelFormat::createFormatCLUT8()),
#endif
_fullscreen(false),
+ _arCorrection(false),
_mouseVisible(false),
_mouseX(0),
_mouseY(0),
- _mouseWidth(0),
- _mouseHeight(0),
_mouseHotspotX(0),
_mouseHotspotY(0),
_mouseKeyColor(0),
- _mouseCursor(NULL),
_kbd_active(false),
_event_quit(false),
+ _lastPadCheck(0),
+
_savefile(NULL),
_mixer(NULL),
_timer(NULL) {
}
OSystem_Wii::~OSystem_Wii() {
- if (_savefile) {
- delete _savefile;
- _savefile = NULL;
- }
+ delete _savefile;
+ _savefile = NULL;
- if (_mixer) {
- delete _mixer;
- _mixer = NULL;
- }
+ delete _mixer;
+ _mixer = NULL;
- if (_timer) {
- delete _timer;
- _timer = NULL;
- }
+ delete _timer;
+ _timer = NULL;
}
void OSystem_Wii::initBackend() {
@@ -107,12 +109,13 @@ void OSystem_Wii::initBackend() {
_mixer = new Audio::MixerImpl(this);
_timer = new DefaultTimerManager();
- _fullscreen = ConfMan.getBool("fullscreen");
-
initGfx();
initSfx();
initEvents();
+ ConfMan.registerDefault("fullscreen", true);
+ ConfMan.registerDefault("aspect_ratio", true);
+
OSystem::initBackend();
}
@@ -125,16 +128,33 @@ void OSystem_Wii::quit() {
WiiFilesystemFactory::asyncHandler(false, NULL);
}
+void OSystem_Wii::engineInit() {
+ _gameRunning = true;
+ // umount not required filesystems for this game
+ WiiFilesystemFactory::asyncHandler(false, &ConfMan.get("path"));
+}
+
+void OSystem_Wii::engineDone() {
+ _gameRunning = false;
+ switchVideoMode(GFX_SETUP_STANDARD);
+ gfx_set_ar(4.0 / 3.0);
+}
+
bool OSystem_Wii::hasFeature(Feature f) {
return (f == kFeatureFullscreenMode) ||
- (f == kFeatureCursorHasPalette);
+ (f == kFeatureAspectRatioCorrection) ||
+ (f == kFeatureCursorHasPalette) ||
+ (f == kFeatureOverlaySupportsAlpha);
}
void OSystem_Wii::setFeatureState(Feature f, bool enable) {
switch (f) {
case kFeatureFullscreenMode:
_fullscreen = enable;
- setGraphicsMode(_activeGraphicsMode);
+ gfx_set_pillarboxing(!enable);
+ break;
+ case kFeatureAspectRatioCorrection:
+ _arCorrection = enable;
break;
default:
break;
@@ -145,6 +165,8 @@ bool OSystem_Wii::getFeatureState(Feature f) {
switch (f) {
case kFeatureFullscreenMode:
return _fullscreen;
+ case kFeatureAspectRatioCorrection:
+ return _arCorrection;
default:
return false;
}
@@ -220,8 +242,3 @@ void OSystem_Wii::getTimeAndDate(struct tm &t) const {
t = *localtime(&curTime);
}
-void OSystem_Wii::engineInit() {
- // umount not required filesystems for this game
- WiiFilesystemFactory::asyncHandler(false, &ConfMan.get("path"));
-}
-
diff --git a/backends/platform/wii/osystem.h b/backends/platform/wii/osystem.h
index 72263af5a8..8f8547c1dd 100644
--- a/backends/platform/wii/osystem.h
+++ b/backends/platform/wii/osystem.h
@@ -26,7 +26,6 @@
#include "common/fs.h"
#include "common/rect.h"
#include "common/events.h"
-
#include "backends/base-backend.h"
#include "backends/saves/default/default-saves.h"
#include "backends/timer/default/default-timer.h"
@@ -34,6 +33,8 @@
#include "graphics/surface.h"
#include "sound/mixer_intern.h"
+#include "gfx.h"
+
#include <gctypes.h>
#include <gccore.h>
#include <ogcsys.h>
@@ -57,38 +58,49 @@ class OSystem_Wii : public BaseBackend {
private:
s64 _startup_time;
- u16 *_palette;
- u16 *_cursorPalette;
+ int _cursorScale;
bool _cursorPaletteDisabled;
+ u16 *_cursorPalette;
+ bool _cursorPaletteDirty;
+ bool _gameRunning;
u16 _gameWidth, _gameHeight;
u8 *_gamePixels;
Graphics::Surface _surface;
+ gfx_coords_t _coordsGame;
+ gfx_tex_t _texGame;
+ bool _gameDirty;
bool _overlayVisible;
u16 _overlayWidth, _overlayHeight;
u32 _overlaySize;
OverlayColor *_overlayPixels;
+ gfx_coords_t _coordsOverlay;
+ gfx_tex_t _texOverlay;
+ bool _overlayDirty;
u32 _lastScreenUpdate;
- u16 *_texture;
u16 _currentWidth, _currentHeight;
+ f32 _currentXScale, _currentYScale;
- s32 _activeGraphicsMode;
+ s32 _configGraphicsMode;
+ s32 _actualGraphicsMode;
#ifdef USE_RGB_COLOR
- const Graphics::PixelFormat _texturePF;
- Graphics::PixelFormat _screenPF;
- Graphics::PixelFormat _cursorPF;
+ const Graphics::PixelFormat _pfRGB565;
+ const Graphics::PixelFormat _pfRGB3444;
+ Graphics::PixelFormat _pfGame;
+ Graphics::PixelFormat _pfGameTexture;
+ Graphics::PixelFormat _pfCursor;
#endif
bool _fullscreen;
+ bool _arCorrection;
bool _mouseVisible;
s32 _mouseX, _mouseY;
- u32 _mouseWidth, _mouseHeight;
s32 _mouseHotspotX, _mouseHotspotY;
u16 _mouseKeyColor;
- u8 *_mouseCursor;
+ gfx_tex_t _texMouse;
bool _kbd_active;
@@ -98,6 +110,8 @@ private:
void initGfx();
void deinitGfx();
+ void updateScreenResolution();
+ void switchVideoMode(int mode);
void initSfx();
void deinitSfx();
@@ -117,6 +131,8 @@ public:
virtual ~OSystem_Wii();
virtual void initBackend();
+ virtual void engineInit();
+ virtual void engineDone();
virtual bool hasFeature(Feature f);
virtual void setFeatureState(Feature f, bool enable);
@@ -182,8 +198,6 @@ public:
virtual Common::TimerManager *getTimerManager();
virtual FilesystemFactory *getFilesystemFactory();
virtual void getTimeAndDate(struct tm &t) const;
-
- virtual void engineInit();
};
#endif
diff --git a/backends/platform/wii/osystem_events.cpp b/backends/platform/wii/osystem_events.cpp
index 0967db1625..e8b25b3e7f 100644
--- a/backends/platform/wii/osystem_events.cpp
+++ b/backends/platform/wii/osystem_events.cpp
@@ -43,6 +43,7 @@
#define PADS_B (PAD_BUTTON_B | (WPAD_BUTTON_B << 16))
#define PADS_X (PAD_BUTTON_X | (WPAD_BUTTON_MINUS << 16))
#define PADS_Y (PAD_BUTTON_Y | (WPAD_BUTTON_PLUS << 16))
+#define PADS_R (PAD_TRIGGER_R | (WPAD_BUTTON_1 << 16))
#define PADS_Z (PAD_TRIGGER_Z | (WPAD_BUTTON_2 << 16))
#define PADS_START (PAD_BUTTON_START | (WPAD_BUTTON_HOME << 16))
#define PADS_UP (PAD_BUTTON_UP | (WPAD_BUTTON_UP << 16))
@@ -54,6 +55,7 @@
#define PADS_B PAD_BUTTON_B
#define PADS_X PAD_BUTTON_X
#define PADS_Y PAD_BUTTON_Y
+#define PADS_R PAD_TRIGGER_R
#define PADS_Z PAD_TRIGGER_Z
#define PADS_START PAD_BUTTON_START
#define PADS_UP PAD_BUTTON_UP
@@ -308,7 +310,6 @@ bool OSystem_Wii::pollEvent(Common::Event &event) {
s32 res = WPAD_Probe(0, NULL);
if (res == WPAD_ERR_NONE) {
-
bd |= WPAD_ButtonsDown(0) << 16;
bh |= WPAD_ButtonsHeld(0) << 16;
bu |= WPAD_ButtonsUp(0) << 16;
@@ -318,6 +319,27 @@ bool OSystem_Wii::pollEvent(Common::Event &event) {
if (bd || bu) {
byte flags = 0;
+ // TODO: add this to an option dialog
+ if (bh & PADS_R) {
+ static u16 vpo_x = 0;
+ static u16 vpo_y = 0;
+
+ if (bd & PADS_LEFT)
+ vpo_x = (vpo_x - 1) % 32;
+
+ if (bd & PADS_RIGHT)
+ vpo_x = (vpo_x + 1) % 32;
+
+ if (bd & PADS_UP)
+ vpo_y = (vpo_y - 1) % 32;
+
+ if (bd & PADS_DOWN)
+ vpo_y = (vpo_y + 1) % 32;
+
+ gfx_set_underscan(vpo_x, vpo_y);
+ return false;
+ }
+
if (bh & PADS_UP) {
PAD_EVENT(PADS_START, Common::KEYCODE_F5, Common::ASCII_F5, Common::KBD_CTRL);
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;
}