diff options
author | Eugene Sandulenko | 2008-06-04 20:28:20 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2008-06-04 20:28:20 +0000 |
commit | 5e666ef774d11d030ea9957ecc64a197de2abcd8 (patch) | |
tree | 0d7e9e8c78dd31c25127f7498c2e2955641ceefa /backends/platform | |
parent | 1869141f0448621b19ab25d3ca338a134500a049 (diff) | |
download | scummvm-rg350-5e666ef774d11d030ea9957ecc64a197de2abcd8.tar.gz scummvm-rg350-5e666ef774d11d030ea9957ecc64a197de2abcd8.tar.bz2 scummvm-rg350-5e666ef774d11d030ea9957ecc64a197de2abcd8.zip |
Patch #1971285: "Nintendo Wii port"
svn-id: r32547
Diffstat (limited to 'backends/platform')
-rw-r--r-- | backends/platform/wii/Makefile | 156 | ||||
-rw-r--r-- | backends/platform/wii/gecko_console.cpp | 91 | ||||
-rw-r--r-- | backends/platform/wii/gecko_console.h | 14 | ||||
-rw-r--r-- | backends/platform/wii/gx_supp.cpp | 264 | ||||
-rw-r--r-- | backends/platform/wii/gx_supp.h | 39 | ||||
-rw-r--r-- | backends/platform/wii/main.cpp | 88 | ||||
-rw-r--r-- | backends/platform/wii/osystem.cpp | 188 | ||||
-rw-r--r-- | backends/platform/wii/osystem.h | 163 | ||||
-rw-r--r-- | backends/platform/wii/osystem_events.cpp | 262 | ||||
-rw-r--r-- | backends/platform/wii/osystem_gfx.cpp | 453 | ||||
-rw-r--r-- | backends/platform/wii/osystem_sfx.cpp | 133 |
11 files changed, 1851 insertions, 0 deletions
diff --git a/backends/platform/wii/Makefile b/backends/platform/wii/Makefile new file mode 100644 index 0000000000..0654fa254d --- /dev/null +++ b/backends/platform/wii/Makefile @@ -0,0 +1,156 @@ +DEBUG_WII = 1 + +ENABLE_SCUMM = 1 +ENABLE_SCUMM_7_8 = 1 +ENABLE_HE = 1 +# ENABLE_AGI = 1 +ENABLE_AGOS = 1 +ENABLE_CINE = 1 +ENABLE_CRUISE = 1 +ENABLE_DRASCULA = 1 +ENABLE_GOB = 1 +ENABLE_IGOR = 1 +ENABLE_KYRA = 1 +ENABLE_LURE = 1 +ENABLE_M4 = 1 +ENABLE_MADE = 1 +ENABLE_PARALLACTION = 1 +ENABLE_QUEEN = 1 +ENABLE_SAGA = 1 +ENABLE_SKY = 1 +ENABLE_SWORD1 = 1 +ENABLE_SWORD2 = 1 +ENABLE_TOUCHE = 1 + +DISABLE_HQ_SCALERS = 1 +DISABLE_SCALERS = 1 + +USE_ZLIB = 1 +USE_MAD = 1 +USE_TREMOR = 1 +USE_FLAC = 1 +USE_MPEG2 = 1 +USE_MT32EMU = 1 + +srcdir = ../../.. +VPATH = $(srcdir) +HAVE_GCC3 = 1 + +DISTPATH = $(srcdir)/dists/wii + +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC") +endif + +PREFIX = $(DEVKITPPC)/bin/powerpc-gekko- +CXX = $(PREFIX)g++ +AS = $(PREFIX)gcc +LD = $(PREFIX)gcc +AR = $(PREFIX)ar cru +RANLIB = $(PREFIX)ranlib +STRIP = $(PREFIX)strip -g +OBJCOPY = $(PREFIX)objcopy +MKDIR = mkdir -p +RM = rm -f +CP = cp -f + +TARGET = scummvm-wii + +MACHDEP = -DGEKKO -mrvl -mcpu=750 -meabi -mhard-float \ + -ffunction-sections -fdata-sections -fmodulo-sched + +INCDIR = $(srcdir) . $(srcdir)/engines/ $(DEVKITPRO)/libogc/include +LIBDIR = $(DEVKITPRO)/libogc/lib/wii + +CXXFLAGS = -g -Os -Wall $(MACHDEP) -D__WII__ \ + -Wno-multichar -fno-exceptions -fno-rtti + +CXXFLAGS += $(addprefix -I,$(INCDIR)) +LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(TARGET).elf.map +LDFLAGS += $(addprefix -L,$(LIBDIR)) +LIBS = -lstdc++ -lfat -lwiiuse -lbte -logc -lm + +CXXFLAGS += -I$(DEVKITPRO)/3rd/wii/include +LDFLAGS += -L$(DEVKITPRO)/3rd/wii/lib + +ifdef DEBUG_WII +CXXFLAGS += -DDEBUG_WII +LIBS += -ldb +endif + +ifdef USE_ZLIB +CXXFLAGS += -DUSE_ZLIB +LIBS += -lz +endif + +ifdef USE_MAD +CXXFLAGS += -DUSE_MAD -I$(DEVKITPRO)/libogc/include/mad +LIBS += -lmad +endif + +ifdef USE_TREMOR +CXXFLAGS += -DUSE_VORBIS -DUSE_TREMOR +LIBS += -lvorbisidec +endif + +ifdef USE_FLAC +CXXFLAGS += -DUSE_FLAC +LIBS += -lFLAC +endif + +ifdef USE_MPEG2 +CXXFLAGS += -DUSE_MPEG2 +LIBS += -lmpeg2 +endif + +ifdef USE_MT32EMU +CXXFLAGS += -DUSE_MT32EMU +endif + +OBJS := backends/platform/wii/main.o \ + backends/platform/wii/gecko_console.o \ + backends/platform/wii/gx_supp.o \ + backends/platform/wii/osystem.o \ + backends/platform/wii/osystem_gfx.o \ + backends/platform/wii/osystem_sfx.o \ + backends/platform/wii/osystem_events.o + +include $(srcdir)/Makefile.common + +.PHONY: clean-wii distclean-wii upload dist + +all: $(TARGET).dol + +$(TARGET).dol: $(TARGET).elf + $(OBJCOPY) -O binary $< $@ + +$(TARGET).elf: $(OBJS) + $(LD) $^ $(LDFLAGS) $(LIBS) -o $@ + +clean: clean-wii + +clean-wii: + @-$(RM) $(TARGET).elf $(TARGET).elf.map $(TARGET).dol + +distclean: distclean-wii + +distclean-wii: + @-$(RM) dist + +upload: + $(DEVKITPPC)/bin/wiiload $(TARGET).dol + +dist: + $(MKDIR) dist/apps/scummvm + $(CP) $(TARGET).dol dist/apps/scummvm/boot.dol + $(CP) $(DISTPATH)/meta.xml dist/apps/scummvm/ + $(CP) $(DISTPATH)/icon.png dist/apps/scummvm/ + $(CP) $(DISTPATH)/READMII dist/apps/scummvm/ + $(CP) $(srcdir)/AUTHORS dist/apps/scummvm/ + $(CP) $(srcdir)/COPYING dist/apps/scummvm/ + $(CP) $(srcdir)/COPYRIGHT dist/apps/scummvm/ + $(CP) $(srcdir)/NEWS dist/apps/scummvm/ + $(CP) $(srcdir)/README dist/apps/scummvm/ + $(CP) $(DIST_FILES_THEMES) dist/apps/scummvm/ + $(CP) $(DIST_FILES_ENGINEDATA) dist/apps/scummvm/ + diff --git a/backends/platform/wii/gecko_console.cpp b/backends/platform/wii/gecko_console.cpp new file mode 100644 index 0000000000..c419f6e7e5 --- /dev/null +++ b/backends/platform/wii/gecko_console.cpp @@ -0,0 +1,91 @@ +/*------------------------------------------------------------- + +Copyright (C) 2008 +Hector Martin (marcan) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you +must not claim that you wrote the original software. If you use +this software in a product, an acknowledgment in the product +documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. + +-------------------------------------------------------------*/ + +#include <stdio.h> +#include <sys/iosupport.h> +#include <ogcsys.h> +#include <gccore.h> +#include <reent.h> + +#include "gecko_console.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static const devoptab_t *dotab_console; +int usb_sendbuffer_safe(s32 chn,const void *buffer,int size); +int usb_sendbuffer(s32 chn,const void *buffer,int size); + +int __gecko_write(struct _reent *r,int fd,const char *ptr,int len) { + char *tmp = (char*)ptr; + u32 level; + if(dotab_console) + dotab_console->write_r(r,fd,ptr,len); + + if(!tmp || len<=0) + return -1; + level = IRQ_Disable(); + usb_sendbuffer(1, ptr, len); + IRQ_Restore(level); + return len; +} + +const devoptab_t dotab_gecko = { + "stdout", // device name + 0, // size of file structure + NULL, // device open + NULL, // device close + __gecko_write, // device write + NULL, // device read + NULL, // device seek + NULL, // device fstat + NULL, // device stat + NULL, // device link + NULL, // device unlink + NULL, // device chdir + NULL, // device rename + NULL, // device mkdir + 0, // dirStateSize + NULL, // device diropen_r + NULL, // device dirreset_r + NULL, // device dirnext_r + NULL, // device dirclose_r + NULL // device statvfs_r +}; + +void gecko_console_init(int chain) { + dotab_console = NULL; + if(chain) + dotab_console = devoptab_list[STD_OUT]; + devoptab_list[STD_OUT] = &dotab_gecko; + devoptab_list[STD_ERR] = &dotab_gecko; +} + +#ifdef __cplusplus +} +#endif + diff --git a/backends/platform/wii/gecko_console.h b/backends/platform/wii/gecko_console.h new file mode 100644 index 0000000000..ba7c393add --- /dev/null +++ b/backends/platform/wii/gecko_console.h @@ -0,0 +1,14 @@ +#ifndef _WII_GECKO_CONSOLE_H_ +#define _WII_GECKO_CONSOLE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void gecko_console_init(int chain); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/backends/platform/wii/gx_supp.cpp b/backends/platform/wii/gx_supp.cpp new file mode 100644 index 0000000000..4c7b8ed58a --- /dev/null +++ b/backends/platform/wii/gx_supp.cpp @@ -0,0 +1,264 @@ +/**************************************************************************** +* Generic GX Support for Emulators +* softdev 2007 +* +* 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 <gccore.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <malloc.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]; +static GXRModeObj *vmode; + +/*** 3D GX ***/ +static u8 *gp_fifo; + +/*** Texture memory ***/ +static u8 *texturemem; +static u32 texturesize; + +GXTexObj texobj; +static Mtx view; +static u16 vwidth, vheight, oldvwidth, oldvheight; + +/* New texture based scaler */ +typedef struct tagcamera { + Vector pos; + Vector up; + Vector 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); + 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(); +} + +/**************************************************************************** + * 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, 0, 0, -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) { + Mtx p; + + GX_AbortFrame(); + + /*** 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; + texturemem = (u8 *) memalign(32, texturesize); + + GXColor gxbackground = { 0, 0, 0, 0xff }; + + /*** 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); + memset(texturemem, 0, texturesize); + + GX_Flush(); + + /*** Setup for first call to scaler ***/ + vwidth = vheight = -1; +} + +/**************************************************************************** +* 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 new file mode 100644 index 0000000000..9393e93a26 --- /dev/null +++ b/backends/platform/wii/gx_supp.h @@ -0,0 +1,39 @@ +/**************************************************************************** +* Generic GX Scaler +* softdev 2007 +* +* 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_ + +#ifdef __cplusplus +extern "C" { +#endif + +void GX_InitVideo(); + +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 new file mode 100644 index 0000000000..7529df6de3 --- /dev/null +++ b/backends/platform/wii/main.cpp @@ -0,0 +1,88 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + */ + +#include <fat.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <errno.h> +#include <unistd.h> + +#include "osystem.h" + +#ifdef DEBUG_WII +#include <debug.h> +#include <gecko_console.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +int main(int argc, char *argv[]) { + s32 res; + + VIDEO_Init(); + PAD_Init(); + AUDIO_Init(NULL); + +#ifdef DEBUG_WII + gecko_console_init(0); + //DEBUG_Init(GDBSTUB_DEVICE_USB, 1); +#endif + + printf("startup\n"); + + if (!fatInitDefault()) { + printf("fatInitDefault failed\n"); + } else { + // set the default path if libfat couldnt set it + // this allows loading over tcp/usbgecko + char buf[MAXPATHLEN]; + + getcwd(buf, MAXPATHLEN); + if (!strcmp(buf, "fat:/")) + chdir("/apps/scummvm"); + + //fatEnableReadAhead(PI_DEFAULT, 32, 128); + } + + g_system = new OSystem_Wii(); + assert(g_system); + + res = scummvm_main(argc, argv); + g_system->quit(); + + printf("shutdown\n"); + + if (!fatUnmount(PI_DEFAULT)) { + printf("fatUnmount failed\n"); + fatUnsafeUnmount(PI_DEFAULT); + } + + printf("reloading\n"); + + return res; +} + +#ifdef __cplusplus +} +#endif + diff --git a/backends/platform/wii/osystem.cpp b/backends/platform/wii/osystem.cpp new file mode 100644 index 0000000000..97bee24d0f --- /dev/null +++ b/backends/platform/wii/osystem.cpp @@ -0,0 +1,188 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + */ + +#include "osystem.h" +#include "backends/fs/wii/wii-fs-factory.h" + +#include <unistd.h> + +#include <ogc/mutex.h> +#include <ogc/lwp_watchdog.h> + +OSystem_Wii::OSystem_Wii() : + _startup_time(0), + _alarm(-1), + + _palette(NULL), + _cursorPalette(NULL), + _cursorPaletteDisabled(true), + + _gameWidth(0), + _gameHeight(0), + _gamePixels(NULL), + + _overlayVisible(false), + _overlayWidth(0), + _overlayHeight(0), + _overlaySize(0), + _overlayPixels(NULL), + + _lastScreenUpdate(0), + _texture(NULL), + _currentWidth(0), + _currentHeight(0), + + _supportedGraphicsModes(NULL), + _activeGraphicsMode(-1), + + _mouseVisible(false), + _mouseX(0), + _mouseY(0), + _mouseWidth(0), + _mouseHeight(0), + _mouseHotspotX(0), + _mouseHotspotY(0), + _mouseKeyColor(0), + _mouseCursor(NULL), + + _savefile(NULL), + _mixer(NULL), + _timer(NULL) { +} + +OSystem_Wii::~OSystem_Wii() { + if (_savefile) { + delete _savefile; + _savefile = NULL; + } + + if (_mixer) { + delete _mixer; + _mixer = NULL; + } + + if (_timer) { + delete _timer; + _timer = NULL; + } +} + +void OSystem_Wii::initBackend() { + _startup_time = gettime(); + + _savefile = new DefaultSaveFileManager(); + _mixer = new Audio::Mixer(); + _timer = new DefaultTimerManager(); + + initGfx(); + initSfx(); + initEvents(); + + OSystem::initBackend(); +} + +void OSystem_Wii::quit() { + deinitEvents(); + deinitSfx(); + deinitGfx(); +} + +bool OSystem_Wii::hasFeature(Feature f) { + return f == kFeatureCursorHasPalette; +} + +void OSystem_Wii::setFeatureState(Feature f, bool enable) { +} + +bool OSystem_Wii::getFeatureState(Feature f) { + return false; +} + +uint32 OSystem_Wii::getMillis() { + return ticks_to_millisecs(diff_ticks(_startup_time, gettime())); +} + +void OSystem_Wii::delayMillis(uint msecs) { + usleep(msecs * 1000); +} + +OSystem::MutexRef OSystem_Wii::createMutex() { + mutex_t *mutex = (mutex_t *) malloc(sizeof(mutex_t)); + s32 res = LWP_MutexInit(mutex, false); + + if (res) { + printf("ERROR creating mutex\n"); + delete mutex; + return NULL; + } + + return (MutexRef) mutex; +} + +void OSystem_Wii::lockMutex(MutexRef mutex) { + s32 res = LWP_MutexLock(*(mutex_t *) mutex); + + if (res) + printf("ERROR locking mutex %p (%d)\n", mutex, res); +} + +void OSystem_Wii::unlockMutex(MutexRef mutex) { + s32 res = LWP_MutexUnlock(*(mutex_t *) mutex); + + if (res) + printf("ERROR unlocking mutex %p (%d)\n", mutex, res); +} + +void OSystem_Wii::deleteMutex(MutexRef mutex) { + s32 res = LWP_MutexDestroy(*(mutex_t *) mutex); + + if (res) + printf("ERROR destroying mutex %p (%d)\n", mutex, res); +} + +void OSystem_Wii::setWindowCaption(const char *caption) { + printf("window caption: %s\n", caption); +} + +Common::SaveFileManager *OSystem_Wii::getSavefileManager() { + assert(_savefile); + return _savefile; +} + +Audio::Mixer *OSystem_Wii::getMixer() { + assert(_mixer); + return _mixer; +} + +Common::TimerManager *OSystem_Wii::getTimerManager() { + assert(_timer); + return _timer; +} + +FilesystemFactory *OSystem_Wii::getFilesystemFactory() { + return &WiiFilesystemFactory::instance(); +} + +void OSystem_Wii::getTimeAndDate(struct tm &t) const { + time_t curTime = time(0); + t = *localtime(&curTime); +} + diff --git a/backends/platform/wii/osystem.h b/backends/platform/wii/osystem.h new file mode 100644 index 0000000000..f65310bada --- /dev/null +++ b/backends/platform/wii/osystem.h @@ -0,0 +1,163 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + */ + +#ifndef _WII_OSYSTEM_H_ +#define _WII_OSYSTEM_H_ + +#include "common/system.h" +#include "base/main.h" + +#include "common/rect.h" +#include "common/events.h" + +#include "backends/saves/default/default-saves.h" +#include "backends/timer/default/default-timer.h" +#include "graphics/surface.h" +#include "sound/mixer.h" + +#include <gctypes.h> +#include <gccore.h> +#include <ogcsys.h> + +class OSystem_Wii : public OSystem { +private: + s64 _startup_time; + syswd_t _alarm; + + u16 *_palette; + u16 *_cursorPalette; + bool _cursorPaletteDisabled; + + u16 _gameWidth, _gameHeight; + u8 *_gamePixels; + Graphics::Surface _surface; + + bool _overlayVisible; + u16 _overlayWidth, _overlayHeight; + u32 _overlaySize; + OverlayColor *_overlayPixels; + + u32 _lastScreenUpdate; + u16 *_texture; + u16 _currentWidth, _currentHeight; + + OSystem::GraphicsMode *_supportedGraphicsModes; + s32 _activeGraphicsMode; + + bool _mouseVisible; + s32 _mouseX, _mouseY; + u32 _mouseWidth, _mouseHeight; + s32 _mouseHotspotX, _mouseHotspotY; + u8 _mouseKeyColor; + u8 *_mouseCursor; + + u32 _lastPadCheck; + + void initGfx(); + void deinitGfx(); + + void initSfx(); + void deinitSfx(); + + void initEvents(); + void deinitEvents(); + void updateEventScreenResolution(); + +protected: + Common::SaveFileManager *_savefile; + Audio::Mixer *_mixer; + DefaultTimerManager *_timer; + +public: + OSystem_Wii(); + virtual ~OSystem_Wii(); + + virtual void initBackend(); + + 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; + virtual void initSize(uint width, uint height); + virtual int16 getWidth(); + virtual int16 getHeight(); + virtual void setPalette(const byte *colors, uint start, uint num); + virtual void grabPalette(byte *colors, uint start, uint num); + virtual void setCursorPalette(const byte *colors, uint start, uint num); + virtual void disableCursorPalette(bool disable); + virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, + int w, int h); + virtual void updateScreen(); + virtual Graphics::Surface *lockScreen(); + virtual void unlockScreen(); + virtual void setShakePos(int shakeOffset); + + virtual void showOverlay(); + virtual void hideOverlay(); + virtual void clearOverlay(); + virtual void grabOverlay(OverlayColor *buf, int pitch); + virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, + int x, int y, int w, int h); + virtual int16 getOverlayWidth(); + virtual int16 getOverlayHeight(); + + virtual OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b); + virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b); + virtual OverlayColor ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b); + virtual void colorToARGB(OverlayColor color, uint8 &a, uint8 &r, + uint8 &g, uint8 &b); + + virtual bool showMouse(bool visible); + + virtual void warpMouse(int x, int y); + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, + int hotspotY, byte keycolor = 255, + int cursorTargetScale = 1); + + virtual bool pollEvent(Common::Event &event); + virtual uint32 getMillis(); + virtual void delayMillis(uint msecs); + + virtual MutexRef createMutex(); + virtual void lockMutex(MutexRef mutex); + virtual void unlockMutex(MutexRef mutex); + virtual void deleteMutex(MutexRef mutex); + + typedef void (*SoundProc)(void *param, byte *buf, int len); + virtual int getOutputSampleRate() const; + + virtual void quit(); + + virtual void setWindowCaption(const char *caption); + + virtual Common::SaveFileManager *getSavefileManager(); + virtual Audio::Mixer *getMixer(); + virtual Common::TimerManager *getTimerManager(); + FilesystemFactory *getFilesystemFactory(); + void getTimeAndDate(struct tm &t) const; +}; + +#endif + diff --git a/backends/platform/wii/osystem_events.cpp b/backends/platform/wii/osystem_events.cpp new file mode 100644 index 0000000000..09dfb5e96b --- /dev/null +++ b/backends/platform/wii/osystem_events.cpp @@ -0,0 +1,262 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + */ + +#include <unistd.h> +#include <malloc.h> + +#ifndef GAMECUBE +#include <wiiuse/wpad.h> +#endif + +#include <ogc/lwp_watchdog.h> + +#include "osystem.h" + +#define TIMER_THREAD_STACKSIZE (1024 * 32) +#define TIMER_THREAD_PRIO 64 + +#define PAD_CHECK_TIME 40 + +#ifndef GAMECUBE +#define PADS_A (PAD_BUTTON_A | (WPAD_BUTTON_A << 16)) +#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_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)) +#define PADS_DOWN (PAD_BUTTON_DOWN | (WPAD_BUTTON_DOWN << 16)) +#define PADS_LEFT (PAD_BUTTON_LEFT | (WPAD_BUTTON_LEFT << 16)) +#define PADS_RIGHT (PAD_BUTTON_RIGHT | (WPAD_BUTTON_RIGHT << 16)) +#else +#define PADS_A PAD_BUTTON_A +#define PADS_B PAD_BUTTON_B +#define PADS_X PAD_BUTTON_X +#define PADS_Y PAD_BUTTON_Y +#define PADS_Z PAD_TRIGGER_Z +#define PADS_START PAD_BUTTON_START +#define PADS_UP PAD_BUTTON_UP +#define PADS_DOWN PAD_BUTTON_DOWN +#define PADS_LEFT PAD_BUTTON_LEFT +#define PADS_RIGHT PAD_BUTTON_RIGHT +#endif + +static lwpq_t timer_queue; +static lwp_t timer_thread; +static u8 *timer_stack; +static bool timer_thread_running = false; +static bool timer_thread_quit = false; + +static void * timer_thread_func(void *arg) { + while (!timer_thread_quit) { + DefaultTimerManager *tm = + (DefaultTimerManager *) g_system->getTimerManager(); + tm->handler(); + + usleep(1000 * 10); + } + + return NULL; +} + +void OSystem_Wii::initEvents() { + timer_thread_quit = false; + + timer_stack = (u8 *) memalign(32, TIMER_THREAD_STACKSIZE); + memset(timer_stack, 0, TIMER_THREAD_STACKSIZE); + + LWP_InitQueue(&timer_queue); + + s32 res = LWP_CreateThread(&timer_thread, timer_thread_func, NULL, + timer_stack, TIMER_THREAD_STACKSIZE, + TIMER_THREAD_PRIO); + + if (res) { + printf("ERROR creating timer thread: %d\n", res); + LWP_CloseQueue(timer_queue); + } + + timer_thread_running = res == 0; + +#ifndef GAMECUBE + WPAD_Init(); + WPAD_SetDataFormat(WPAD_CHAN_0, WPAD_FMT_BTNS_ACC_IR); + WPAD_SetIdleTimeout(120); +#endif +} + +void OSystem_Wii::deinitEvents() { + if (timer_thread_running) { + timer_thread_quit = true; + LWP_ThreadBroadcast(timer_queue); + + LWP_JoinThread(timer_thread, NULL); + LWP_CloseQueue(timer_queue); + + timer_thread_running = false; + } + +#ifndef GAMECUBE + WPAD_Shutdown(); +#endif +} + +void OSystem_Wii::updateEventScreenResolution() { +#ifndef GAMECUBE + WPAD_SetVRes(WPAD_CHAN_0, _currentWidth + _currentWidth / 5, + _currentHeight + _currentHeight / 5); +#endif +} + +#define KBD_EVENT(pad_button, kbd_keycode, kbd_ascii) \ + do { \ + if ((bd | bu) & pad_button) { \ + if (bd & pad_button) \ + event.type = Common::EVENT_KEYDOWN; \ + else \ + event.type = Common::EVENT_KEYUP; \ + event.kbd.keycode = kbd_keycode; \ + event.kbd.ascii = kbd_ascii; \ + return true; \ + } \ + } while (0) + +bool OSystem_Wii::pollEvent(Common::Event &event) { + u32 bd, bh, bu; + + PAD_ScanPads(); + + bd = PAD_ButtonsDown(0); + bh = PAD_ButtonsHeld(0); + bu = PAD_ButtonsUp(0); + +#ifndef GAMECUBE + WPAD_ScanPads(); + + 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; + } +#endif + + if (bd || bu) { + if (bh & PADS_UP) + event.kbd.flags = Common::KBD_SHIFT; + + KBD_EVENT(PADS_Z, Common::KEYCODE_RETURN, Common::ASCII_RETURN); + KBD_EVENT(PADS_X, Common::KEYCODE_ESCAPE, Common::ASCII_ESCAPE); + KBD_EVENT(PADS_Y, Common::KEYCODE_PERIOD, '.'); + KBD_EVENT(PADS_START, Common::KEYCODE_F5, Common::ASCII_F5); + KBD_EVENT(PADS_UP, Common::KEYCODE_LSHIFT, 0); + KBD_EVENT(PADS_DOWN, Common::KEYCODE_0, '0'); + KBD_EVENT(PADS_LEFT, Common::KEYCODE_y, 'y'); + KBD_EVENT(PADS_RIGHT, Common::KEYCODE_n, 'n'); + + if ((bd | bu) & (PADS_A | PADS_B)) { + if (bd & PADS_A) + event.type = Common::EVENT_LBUTTONDOWN; + else if (bu & PADS_A) + event.type = Common::EVENT_LBUTTONUP; + else if (bd & PADS_B) + event.type = Common::EVENT_RBUTTONDOWN; + else if (bu & PADS_B) + event.type = Common::EVENT_RBUTTONUP; + + event.mouse.x = _mouseX; + event.mouse.y = _mouseY; + + return true; + } + } + + s32 mx = _mouseX; + s32 my = _mouseY; + +#ifndef GAMECUBE + if (res == WPAD_ERR_NONE) { + struct ir_t ir; + + WPAD_IR(0, &ir); + + if (ir.valid) { + mx = ir.x - _currentWidth / 10; + my = ir.y - _currentHeight / 10; + + if (mx < 0) + mx = 0; + + if (mx >= _currentWidth) + mx = _currentWidth - 1; + + if (my < 0) + my = 0; + + if (my >= _currentHeight) + my = _currentHeight - 1; + + if ((mx != _mouseX) || (my != _mouseY)) { + event.type = Common::EVENT_MOUSEMOVE; + event.mouse.x = _mouseX = mx; + event.mouse.y = _mouseY = my; + + return true; + } + } + } +#endif + + uint32 time = getMillis(); + if (time - _lastPadCheck > PAD_CHECK_TIME) { + _lastPadCheck = time; + + if (abs (PAD_StickX(0)) > 16) + mx += PAD_StickX(0) / (4 * _overlayWidth / _currentWidth); + if (abs (PAD_StickY(0)) > 16) + my -= PAD_StickY(0) / (4 * _overlayHeight / _currentHeight); + + if (mx < 0) + mx = 0; + + if (mx >= _currentWidth) + mx = _currentWidth - 1; + + if (my < 0) + my = 0; + + if (my >= _currentHeight) + my = _currentHeight - 1; + + if ((mx != _mouseX) || (my != _mouseY)) { + event.type = Common::EVENT_MOUSEMOVE; + event.mouse.x = _mouseX = mx; + event.mouse.y = _mouseY = my; + + return true; + } + } + + return false; +} + diff --git a/backends/platform/wii/osystem_gfx.cpp b/backends/platform/wii/osystem_gfx.cpp new file mode 100644 index 0000000000..1e54233c93 --- /dev/null +++ b/backends/platform/wii/osystem_gfx.cpp @@ -0,0 +1,453 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + */ + +#include <malloc.h> + +#include "osystem.h" +#include "gx_supp.h" + +#define MAX_FPS 30 + +enum GraphicModeID { + GM_DEFAULT +}; + +void OSystem_Wii::initGfx() { + _surface.w = 0; + _surface.h = 0; + _surface.pitch = 0; + _surface.pixels = NULL; + _surface.bytesPerPixel = 0; + + GX_InitVideo(); + + _overlayWidth = 640; + _overlayHeight = 480; + + _overlaySize = _overlayWidth * _overlayHeight * 2; + _overlayPixels = (OverlayColor *) memalign(32, _overlaySize); + + _palette = (u16 *) memalign(32, 256 * 2); + memset(_palette, 0, 256 * 2); + + _cursorPalette = (u16 *) memalign(32, 256 * 2); + memset(_cursorPalette, 0, 256 * 2); + + _supportedGraphicsModes = new OSystem::GraphicsMode[2]; + _supportedGraphicsModes[0].name = strdup("gx"); + _supportedGraphicsModes[0].description = strdup("wii hardware scaler"); + _supportedGraphicsModes[0].id = GM_DEFAULT; + _supportedGraphicsModes[1].name = 0; + _supportedGraphicsModes[1].description = 0; + _supportedGraphicsModes[1].id = 0; + + _texture = (u16 *) memalign(32, _overlaySize); + + GX_Start(_overlayWidth, _overlayHeight, 320, 240); +} + +void OSystem_Wii::deinitGfx() { + GX_AbortFrame(); + + if (_supportedGraphicsModes) { + delete[] _supportedGraphicsModes; + _supportedGraphicsModes = NULL; + } + + if (_gamePixels) { + free(_gamePixels); + _gamePixels = NULL; + } + + if (_palette) { + free(_palette); + _palette = NULL; + } + + if (_overlayPixels) { + free(_overlayPixels); + _overlayPixels = NULL; + } + + if (_mouseCursor) { + free(_mouseCursor); + _mouseCursor = NULL; + } + + if (_cursorPalette) { + free(_cursorPalette); + _cursorPalette = NULL; + } + + if (_texture) { + free(_texture); + _texture = NULL; + } +} + +const OSystem::GraphicsMode* OSystem_Wii::getSupportedGraphicsModes() const { + return _supportedGraphicsModes; +} + +int OSystem_Wii::getDefaultGraphicsMode() const { + return GM_DEFAULT; +} + +bool OSystem_Wii::setGraphicsMode(const char *mode) { + setGraphicsMode(GM_DEFAULT); + + return true; +} + +bool OSystem_Wii::setGraphicsMode(int mode) { + return true; +} + +int OSystem_Wii::getGraphicsMode() const { + return _activeGraphicsMode; +} + +void OSystem_Wii::initSize(uint width, uint height) { + if (_gameWidth != width || _gameHeight != height) { + printf("initSize %u %u\n", width, height); + + _gameWidth = width; + _gameHeight = height; + + if(_gamePixels) + free(_gamePixels); + + _gamePixels = (u8 *) memalign(32, _gameWidth * _gameHeight); + + if (!_overlayVisible) { + _currentWidth = _gameWidth; + _currentHeight = _gameHeight; + updateEventScreenResolution(); + } + } +} + +int16 OSystem_Wii::getWidth() { + return _gameWidth; +} + +int16 OSystem_Wii::getHeight() { + return _gameHeight; +} + +void OSystem_Wii::setPalette(const byte *colors, uint start, uint num) { + const byte *p = colors; + for (uint i = 0; i < num; ++i) { + _palette[start + i] = RGBToColor(p[0], p[1], p[2]); + p += 4; + } +} + +void OSystem_Wii::grabPalette(byte *colors, uint start, uint num) { + byte *p = colors; + u8 r, g, b; + for (uint i = 0; i < num; ++i) { + colorToRGB(_palette[start + i], r, g, b); + p[0] = r; + p[1] = g; + p[2] = b; + p[3] = 0xff; + p += 4; + } +} + +void OSystem_Wii::setCursorPalette(const byte *colors, uint start, uint num) { + const byte *p = colors; + for (uint i = 0; i < num; ++i) { + _cursorPalette[start + i] = RGBToColor(p[0], p[1], p[2]); + p += 4; + } + + _cursorPaletteDisabled = false; +} + +void OSystem_Wii::disableCursorPalette(bool disable) { + _cursorPaletteDisabled = disable; +} + +void OSystem_Wii::copyRectToScreen(const byte *buf, int pitch, int x, int y, + int w, int h) { + if (x < 0) { + w += x; + buf -= x; + x = 0; + } + + if (y < 0) { + h += y; + buf -= y * pitch; + y = 0; + } + + if (w > _gameWidth - x) + w = _gameWidth - x; + + if (h > _gameHeight - y) + h = _gameHeight - y; + + if (w <= 0 || h <= 0) + return; + + byte *dst = _gamePixels + y * _gameWidth + x; + if (_gameWidth == pitch && pitch == w) { + memcpy(dst, buf, h * w); + } else { + do { + memcpy(dst, buf, w); + buf += pitch; + dst += _gameWidth; + } while (--h); + } +} + +void OSystem_Wii::updateScreen() { + static u32 x, y, h, skip; + static s16 msx, msy, mox, moy, mskip; + static u16 mpx, mpy; + static u8 *s; + static u16 *d, *p; + + u32 now = getMillis(); + if (now - _lastScreenUpdate < 1000 / MAX_FPS) + return; + + _lastScreenUpdate = now; + + h = 0; + if (_overlayVisible) { + memcpy(_texture, _overlayPixels, _overlaySize); + } else { + for (y = 0; y < _gameHeight; ++y) { + for (x = 0; x < _gameWidth; ++x) + _texture[h + x] = _palette[_gamePixels[h + x]]; + + h += _gameWidth; + } + } + + 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; + else + p = _cursorPalette; + + skip = _currentWidth - mpx; + mskip = _mouseWidth - mpx; + + 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; + } + + *d++ = p[*s]; + s++; + } + + d += skip; + s += mskip; + } + } + + GX_Render(_currentWidth, _currentHeight, (u8 *) _texture, + _currentWidth * 2); +} + +Graphics::Surface *OSystem_Wii::lockScreen() { + _surface.pixels = _gamePixels; + _surface.w = _gameWidth; + _surface.h = _gameHeight; + _surface.pitch = _gameWidth; + _surface.bytesPerPixel = 1; + + return &_surface; +} + +void OSystem_Wii::unlockScreen() { +} + +void OSystem_Wii::setShakePos(int shakeOffset) { +} + +void OSystem_Wii::showOverlay() { + _mouseX = _overlayWidth / 2; + _mouseY = _overlayHeight / 2; + _overlayVisible = true; + _currentWidth = _overlayWidth; + _currentHeight = _overlayHeight; + + updateEventScreenResolution(); +} + +void OSystem_Wii::hideOverlay() { + _mouseX = _gameWidth / 2; + _mouseY = _gameHeight / 2; + _overlayVisible = false; + _currentWidth = _gameWidth; + _currentHeight = _gameHeight; + + updateEventScreenResolution(); +} + +void OSystem_Wii::clearOverlay() { + memset(_overlayPixels, 0, _overlaySize); +} + +void OSystem_Wii::grabOverlay(OverlayColor *buf, int pitch) { + int h = _overlayHeight; + OverlayColor *src = _overlayPixels; + + do { + memcpy(buf, src, _overlayWidth * sizeof(OverlayColor)); + src += _overlayWidth; + buf += pitch; + } while (--h); +} + +void OSystem_Wii::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, + int y, int w, int h) { + if (x < 0) { + w += x; + buf -= x; + x = 0; + } + + if (y < 0) { + h += y; + buf -= y * pitch; + y = 0; + } + + if (w > _overlayWidth - x) + w = _overlayWidth - x; + + if (h > _overlayHeight - y) + h = _overlayHeight - y; + + if (w <= 0 || h <= 0) + return; + + OverlayColor *dst = _overlayPixels + (y * _overlayWidth + x); + if (_overlayWidth == pitch && pitch == w) { + memcpy(dst, buf, h * w * sizeof(OverlayColor)); + } else { + do { + memcpy(dst, buf, w * sizeof(OverlayColor)); + buf += pitch; + dst += _overlayWidth; + } while (--h); + } +} + +int16 OSystem_Wii::getOverlayWidth() { + return _overlayWidth; +} + +int16 OSystem_Wii::getOverlayHeight() { + return _overlayHeight; +} + +OverlayColor OSystem_Wii::RGBToColor(uint8 r, uint8 g, uint8 b) { + return (((r >> 3) & 0x1f) << 11) | (((g >> 2) & 0x3f) << 5 ) | + ((b >> 3) & 0x1f); +} + +void OSystem_Wii::colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b) { + r = ((color >> 11) & 0x1f) << 3; + g = ((color >> 5) & 0x3f) << 2; + b = (color & 0x1f) << 3; +} + +OverlayColor OSystem_Wii::ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) { + return RGBToColor(r, g, b); +} + +void OSystem_Wii::colorToARGB(OverlayColor color, uint8 &a, uint8 &r, uint8 &g, + uint8 &b) { + a = 0xff; + colorToRGB(color, r, g, b); +} + +bool OSystem_Wii::showMouse(bool visible) { + bool last = _mouseVisible; + _mouseVisible = visible; + + return last; +} + +void OSystem_Wii::warpMouse(int x, int y) { + _mouseX = x; + _mouseY = y; +} + +void OSystem_Wii::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, + int hotspotY, byte keycolor, + int cursorTargetScale) { + (void) cursorTargetScale; // TODO + + _mouseWidth = w; + _mouseHeight = h; + _mouseHotspotX = hotspotX; + _mouseHotspotY = hotspotY; + _mouseKeyColor = keycolor; + + if (_mouseCursor) + free(_mouseCursor); + + _mouseCursor = (u8 *) memalign(32, w * h); + memcpy(_mouseCursor, buf, w * h); +} + diff --git a/backends/platform/wii/osystem_sfx.cpp b/backends/platform/wii/osystem_sfx.cpp new file mode 100644 index 0000000000..16b2f3b055 --- /dev/null +++ b/backends/platform/wii/osystem_sfx.cpp @@ -0,0 +1,133 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + */ + +#include <malloc.h> + +#include "osystem.h" + +#define SFX_THREAD_STACKSIZE (1024 * 128) +#define SFX_THREAD_PRIO 80 +#define SFX_THREAD_FRAG_SIZE 4096 + +static lwpq_t sfx_queue; +static lwp_t sfx_thread; +static u8 *sfx_stack; +static bool sfx_thread_running = false; +static bool sfx_thread_quit = false; + +static u8 sb = 0; +static u8 *sound_buffer[2]; + +static OSystem_Wii::SoundProc sound_proc = NULL; +static void *proc_param = NULL; + +static void audio_switch_buffers() { + AUDIO_StopDMA(); + AUDIO_InitDMA((u32) sound_buffer[sb], SFX_THREAD_FRAG_SIZE); + AUDIO_StartDMA(); + + LWP_ThreadSignal(sfx_queue); +} + +static void * sfx_thread_func(void *arg) { + u8 next_sb; + + while (true) { + LWP_ThreadSleep(sfx_queue); + + if (sfx_thread_quit) + break; + + next_sb = sb ^ 1; + sound_proc(proc_param, sound_buffer[next_sb], SFX_THREAD_FRAG_SIZE); + DCFlushRange(sound_buffer[next_sb], SFX_THREAD_FRAG_SIZE); + + sb = next_sb; + } + + return NULL; +} + +void OSystem_Wii::initSfx() { + sfx_thread_running = false; + sfx_thread_quit = false; + + sfx_stack = (u8 *) memalign(32, SFX_THREAD_STACKSIZE); + memset(sfx_stack, 0, SFX_THREAD_STACKSIZE); + + LWP_InitQueue(&sfx_queue); + + s32 res = LWP_CreateThread(&sfx_thread, sfx_thread_func, NULL, sfx_stack, + SFX_THREAD_STACKSIZE, SFX_THREAD_PRIO); + + if (res) { + printf("ERROR creating sfx thread: %d\n", res); + LWP_CloseQueue(sfx_queue); + return; + } + + sfx_thread_running = true; + + sound_buffer[0] = (u8 *) memalign(32, SFX_THREAD_FRAG_SIZE); + sound_buffer[1] = (u8 *) memalign(32, SFX_THREAD_FRAG_SIZE); + + memset(sound_buffer[0], 0, SFX_THREAD_FRAG_SIZE); + memset(sound_buffer[1], 0, SFX_THREAD_FRAG_SIZE); + + DCFlushRange(sound_buffer[0], SFX_THREAD_FRAG_SIZE); + DCFlushRange(sound_buffer[1], SFX_THREAD_FRAG_SIZE); + + sound_proc = Audio::Mixer::mixCallback; + proc_param = _mixer; + + _mixer->setReady(true); + + AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); + AUDIO_RegisterDMACallback(audio_switch_buffers); + + audio_switch_buffers(); +} + +void OSystem_Wii::deinitSfx() { + if (_mixer) + _mixer->setReady(false); + + AUDIO_StopDMA(); + AUDIO_RegisterDMACallback(NULL); + + if (sfx_thread_running) { + sfx_thread_quit = true; + LWP_ThreadBroadcast(sfx_queue); + + LWP_JoinThread(sfx_thread, NULL); + LWP_CloseQueue(sfx_queue); + + sfx_thread_running = false; + + free(sound_buffer[0]); + free(sound_buffer[1]); + } +} + +int OSystem_Wii::getOutputSampleRate() const { + return 48000; +} + |