diff options
Diffstat (limited to 'backends/platform')
| -rw-r--r-- | backends/platform/ds/arm9/makefile | 2 | ||||
| -rw-r--r-- | backends/platform/sdl/events.cpp | 2 | ||||
| -rw-r--r-- | backends/platform/sdl/sdl.cpp | 2 | ||||
| -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 | 
14 files changed, 1854 insertions, 3 deletions
diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 1a4d61113e..7472a32218 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -182,7 +182,7 @@ endif  LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -Wl,--wrap,time -mno-fpu -Wl,-Map,map.txt -INCLUDES= -I./ -I$(portdir)/$(BUILD) -I$(srcdir) -I$(srcdir)/common -I$(portdir)/source -I$(portdir)/source/fat \ +INCLUDES= -I./ -I$(portdir)/$(BUILD) -I$(srcdir) -I$(srcdir)/common -I$(portdir)/source \  			-I$(portdir)/data -I$(libndsdir)/include -I$(portdir)/../commoninclude\  			-I$(libndsdir)/include -I$(libndsdir)/include/nds -I$(srcdir)/engines -I$(portdir)/source/mad\  			-I$(portdir)/source/libcartreset -include $(srcdir)/common/scummsys.h diff --git a/backends/platform/sdl/events.cpp b/backends/platform/sdl/events.cpp index 9a0a33f45c..a4a72ca380 100644 --- a/backends/platform/sdl/events.cpp +++ b/backends/platform/sdl/events.cpp @@ -148,7 +148,7 @@ void OSystem_SDL::handleKbdMouse() {  				_km.y_down_count = 1;  			} -			SDL_WarpMouse(_km.x, _km.y); +			SDL_WarpMouse((Uint16)_km.x, (Uint16)_km.y);  		}  	}  } diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index b750864ad8..be3aaad926 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -406,7 +406,7 @@ bool OSystem_SDL::setSoundCallback(SoundProc proc, void *param) {  	// about 1/32th of a second. Note that it must be a power of two.  	// So e.g. at 22050 Hz, we request a sample buffer size of 2048.  	int samples = 8192; -	while (32 * samples >= _samplesPerSec) { +	while (16 * samples >= _samplesPerSec) {  		samples >>= 1;  	} 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; +} +  | 
