Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
target remote 192.168.123.101:5656
info threads
bt

View File

@@ -0,0 +1,3 @@
target remote /dev/ttyUSB0
info threads
bt

View File

@@ -0,0 +1,275 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_EXCEPTION_chdir
#define FORBIDDEN_SYMBOL_EXCEPTION_getcwd
#define FORBIDDEN_SYMBOL_EXCEPTION_printf
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include "osystem.h"
#include "backends/plugins/wii/wii-provider.h"
#include <ogc/machine/processor.h>
#include <ogc/libversion.h>
#include <fat.h>
#ifndef GAMECUBE
#include <wiiuse/wpad.h>
#endif
#ifdef USE_WII_DI
#include <di/di.h>
#endif
#if defined(DEBUG_WII_GDB) || defined(DEBUG_WII_GDB_NETWORK)
#include <debug.h>
#endif
#include <gxflux/gfx_con.h>
#ifdef __cplusplus
extern "C" {
#endif
bool reset_btn_pressed = false;
bool power_btn_pressed = false;
#if ((_V_MAJOR_ > 1) || \
(_V_MAJOR_ == 1 && _V_MINOR_ > 8 ) || \
(_V_MAJOR_ == 1 && _V_MINOR_ == 8 && _V_PATCH_ >= 18))
void reset_cb(u32, void *) {
#else
void reset_cb(void) {
#endif
#if defined(DEBUG_WII_GDB) || defined(DEBUG_WII_GDB_NETWORK)
printf("attach gdb now\n");
_break();
#else
reset_btn_pressed = true;
#endif
}
void power_cb(void) {
power_btn_pressed = true;
}
static void show_console(int code) {
u32 i, b;
printf("ScummVM exited abnormally (%d).\n", code);
gfx_frame_abort();
gfx_init();
if (!gfx_frame_start())
return;
gfx_con_draw();
gfx_frame_end();
for (i = 0; i < 60 * 3; ++i)
VIDEO_WaitVSync();
#if defined(DEBUG_WII_GDB) || defined(DEBUG_WII_GDB_NETWORK)
printf("attach gdb now\n");
_break();
#endif
printf("Press any key to continue.\n");
if (!gfx_frame_start())
return;
gfx_con_draw();
gfx_frame_end();
VIDEO_WaitVSync();
while (true) {
b = 0;
if (PAD_ScanPads() & 1)
b = PAD_ButtonsDown(0);
#ifndef GAMECUBE
WPAD_ScanPads();
if (WPAD_Probe(0, NULL) == WPAD_ERR_NONE)
b |= WPAD_ButtonsDown(0);
#endif
if (b)
break;
VIDEO_WaitVSync();
}
printf("\n\nExiting...\n");
if (!gfx_frame_start())
return;
gfx_con_draw();
gfx_frame_end();
VIDEO_WaitVSync();
}
s32 reset_func(s32 final) {
static bool done = false;
if (!done) {
show_console(-127);
done = true;
}
return 1;
}
static sys_resetinfo resetinfo = {
{ NULL, NULL },
reset_func,
1
};
#ifdef DEBUG_WII_MEMSTATS
#define FORBIDDEN_SYMBOL_EXCEPTION_fprintf
#define FORBIDDEN_SYMBOL_EXCEPTION_stderr
void wii_memstats(void) {
static u32 min_free = UINT_MAX;
static u32 temp_free;
static u32 level;
_CPU_ISR_Disable(level);
#ifdef GAMECUBE
temp_free = (u32) SYS_GetArenaHi() - (u32) SYS_GetArenaLo();
#else
temp_free = (u32) SYS_GetArena1Hi() - (u32) SYS_GetArena1Lo() +
(u32) SYS_GetArena2Hi() - (u32) SYS_GetArena2Lo();
#endif
_CPU_ISR_Restore(level);
if (temp_free < min_free) {
min_free = temp_free;
fprintf(stderr, "free: %8u\n", min_free);
}
}
#endif
#ifdef DEBUG_WII_GDB_NETWORK
#define GDBSTUB_NETWORK_TCP_PORT 5656
const char *tcp_localip = "192.168.123.101";
const char *tcp_netmask = "255.255.255.0";
const char *tcp_gateway = "192.168.123.100";
#endif
int main(int argc, char *argv[]) {
s32 res;
#if defined(USE_WII_DI) && !defined(GAMECUBE)
DI_Init();
#endif
VIDEO_Init();
PAD_Init();
DSP_Init();
AUDIO_Init(NULL);
gfx_video_init(NULL);
gfx_init();
gfx_con_init(NULL);
#ifdef DEBUG_WII_GDB
DEBUG_Init(GDBSTUB_DEVICE_USB, 1);
#endif
#ifdef DEBUG_WII_GDB_NETWORK
DEBUG_Init(GDBSTUB_DEVICE_TCP, GDBSTUB_NETWORK_TCP_PORT);
#endif
printf("startup as ");
if (argc > 0)
printf("'%s'\n", argv[0]);
else
printf("<unknown>\n");
SYS_RegisterResetFunc(&resetinfo);
SYS_SetResetCallback(reset_cb);
#ifndef GAMECUBE
SYS_SetPowerCallback(power_cb);
#endif
if (!fatInitDefault()) {
printf("fatInitDefault failed\n");
} else {
// set the default path if libfat couldnt set it
// this allows loading over tcp/usbgecko
char cwd[MAXPATHLEN];
if (getcwd(cwd, MAXPATHLEN)) {
size_t len = strlen(cwd);
if (len > 2 && (cwd[len - 1] == ':' || cwd[len - 2] == ':')) {
printf("chdir to default\n");
chdir("/apps/scummvm");
}
}
}
g_system = new OSystem_Wii();
assert(g_system);
#ifdef DYNAMIC_MODULES
PluginManager::instance().addPluginProvider(new WiiPluginProvider());
#endif
res = scummvm_main(argc, argv);
g_system->quit();
g_system->destroy();
g_system = nullptr;
printf("shutdown\n");
SYS_UnregisterResetFunc(&resetinfo);
fatUnmount("usb:/");
fatUnmount("sd:/");
if (res)
show_console(res);
if (power_btn_pressed) {
printf("shutting down\n");
SYS_ResetSystem(SYS_POWEROFF, 0, 0);
}
printf("reloading\n");
gfx_con_deinit();
gfx_deinit();
gfx_video_deinit();
return res;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,14 @@
MODULE := backends/platform/wii
MODULE_OBJS := \
main.o \
options.o \
osystem.o \
osystem_gfx.o \
osystem_sfx.o \
osystem_events.o
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
OBJS := $(MODULE_OBJS) $(OBJS)
MODULE_DIRS += $(sort $(dir $(MODULE_OBJS)))

View File

@@ -0,0 +1,316 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include <errno.h>
#include <network.h>
#include <gxflux/gfx.h>
#include "common/config-manager.h"
#include "gui/dialog.h"
#include "backends/fs/wii/wii-fs-factory.h"
#include "common/translation.h"
#include "options.h"
WiiOptionsDialog::WiiOptionsDialog(bool doubleStrike) :
Dialog((640 - 400) / 2, (480 - 340) / 2, 400, 340),
_doubleStrike(doubleStrike) {
if (_doubleStrike) {
_strUnderscanX = "wii_video_ds_underscan_x";
_strUnderscanY = "wii_video_ds_underscan_y";
} else {
_strUnderscanX = "wii_video_default_underscan_x";
_strUnderscanY = "wii_video_default_underscan_y";
}
new ButtonWidget(this, _w - 108 - 16, _h - 24 - 16, 108, 24, _("OK"), U32String(), 'k');
new ButtonWidget(this, _w - 216 - 32, _h - 24 - 16, 108, 24, _("Cancel"), U32String(), 'c');
_tab = new TabWidget(this, 0, 0, _w, _h - 54);
_tabVideo = _tab->addTab(_("Video"), "");
new StaticTextWidget(_tab, 16, 16, 128, 16,
_("Current video mode:"), Graphics::kTextAlignRight);
new StaticTextWidget(_tab, 160, 16, 128, 16,
_doubleStrike ? _("Double-strike") : _("Default"),
Graphics::kTextAlignLeft);
new StaticTextWidget(_tab, 16, 48, 128, 16,
_("Horizontal underscan:"), Graphics::kTextAlignRight);
_sliderUnderscanX = new SliderWidget(_tab, 160, 47, 128, 18, U32String(), 'x');
_sliderUnderscanX->setMinValue(0);
_sliderUnderscanX->setMaxValue(32);
new StaticTextWidget(_tab, 16, 80, 128, 16,
_("Vertical underscan:"), Graphics::kTextAlignRight);
_sliderUnderscanY = new SliderWidget(_tab, 160, 79, 128, 18, U32String(), 'y');
_sliderUnderscanY->setMinValue(0);
_sliderUnderscanY->setMaxValue(32);
_tabInput = _tab->addTab(_("Input"), "");
new StaticTextWidget(_tab, 16, 16, 128, 16,
_("GC Pad sensitivity:"), Graphics::kTextAlignRight);
_sliderPadSensitivity = new SliderWidget(_tab, 160, 15, 128, 18, U32String(), 'x');
_sliderPadSensitivity->setMinValue(0);
_sliderPadSensitivity->setMaxValue(64);
new StaticTextWidget(_tab, 16, 44, 128, 16,
_("GC Pad acceleration:"), Graphics::kTextAlignRight);
_sliderPadAcceleration = new SliderWidget(_tab, 160, 43, 128, 18, U32String(), 'y');
_sliderPadAcceleration->setMinValue(0);
_sliderPadAcceleration->setMaxValue(8);
#ifdef USE_WII_DI
_tabDVD = _tab->addTab(_("DVD"), "");
new StaticTextWidget(_tab, 16, 16, 64, 16,
_("Status:"), Graphics::kTextAlignRight);
_textDVDStatus = new StaticTextWidget(_tab, 96, 16, 272, 16, _("Unknown"),
Graphics::kTextAlignLeft);
new ButtonWidget(_tab, 16, 48, 108, 24, _("Mount DVD"), U32String(), 'mdvd');
new ButtonWidget(_tab, 140, 48, 108, 24, _("Unmount DVD"), U32String(), 'udvd');
#endif
#ifdef USE_WII_SMB
_tabSMB = _tab->addTab(_("SMB"), "");
new StaticTextWidget(_tab, 16, 16, 64, 16,
_("Status:"), Graphics::kTextAlignRight);
_textSMBStatus = new StaticTextWidget(_tab, 96, 16, 272, 16, _("Unknown"),
Graphics::kTextAlignLeft);
new StaticTextWidget(_tab, 16, 52, 64, 16,
_("Server:"), Graphics::kTextAlignRight);
_editSMBServer = new EditTextWidget(_tab, 96, 48, _w - 96 - 32, 24, U32String());
new StaticTextWidget(_tab, 16, 92, 64, 16,
_("Share:"), Graphics::kTextAlignRight);
_editSMBShare = new EditTextWidget(_tab, 96, 88, _w - 96 - 32, 24, U32String());
new StaticTextWidget(_tab, 16, 132, 64, 16,
_("Username:"), Graphics::kTextAlignRight);
_editSMBUsername = new EditTextWidget(_tab, 96, 128, _w - 96 - 32, 24, U32String());
new StaticTextWidget(_tab, 16, 172, 64, 16,
_("Password:"), Graphics::kTextAlignRight);
_editSMBPassword = new EditTextWidget(_tab, 96, 168, _w - 96 - 32, 24, U32String());
new ButtonWidget(_tab, 16, 208, 108, 24, _("Init network"), U32String(), 'net');
new ButtonWidget(_tab, 140, 208, 108, 24, _("Mount SMB"), U32String(), 'msmb');
new ButtonWidget(_tab, 264, 208, 108, 24, _("Unmount SMB"), U32String(), 'usmb');
#endif
_tab->setActiveTab(_tabVideo);
load();
}
WiiOptionsDialog::~WiiOptionsDialog() {
}
void WiiOptionsDialog::handleTickle() {
WiiFilesystemFactory &fsf = WiiFilesystemFactory::instance();
int tab = _tab->getActiveTab();
#ifdef USE_WII_DI
if (tab == _tabDVD) {
if (fsf.isMounted(WiiFilesystemFactory::kDVD)) {
_textDVDStatus->setLabel(_("DVD Mounted successfully"));
} else {
if (fsf.failedToMount(WiiFilesystemFactory::kDVD))
_textDVDStatus->setLabel(_("Error while mounting the DVD"));
else
_textDVDStatus->setLabel(_("DVD not mounted"));
}
}
#endif
#ifdef USE_WII_SMB
if (tab == _tabSMB) {
s32 status = net_get_status();
U32String label;
switch (status) {
case 0:
if (fsf.isMounted(WiiFilesystemFactory::kSMB)) {
label = _("Network up, share mounted");
} else {
label = _("Network up");
if (fsf.failedToMount(WiiFilesystemFactory::kSMB))
label += _(", error while mounting the share");
else
label += _(", share not mounted");
}
break;
case -ENETDOWN:
label = _("Network down");
break;
case -EBUSY:
label = _("Initializing network");
break;
case -ETIMEDOUT:
label = _("Timeout while initializing network");
break;
default:
label = U32String::format(_("Network not initialized (%d)"), status);
break;
}
_textSMBStatus->setLabel(label);
}
#endif
Dialog::handleTickle();
}
void WiiOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd,
uint32 data) {
WiiFilesystemFactory &fsf = WiiFilesystemFactory::instance();
switch (cmd) {
case 'x':
case 'y':
gfx_set_underscan(_sliderUnderscanX->getValue(),
_sliderUnderscanY->getValue());
break;
case 'k':
save();
close();
break;
case 'c':
revert();
close();
break;
#ifdef USE_WII_DI
case 'mdvd':
fsf.mount(WiiFilesystemFactory::kDVD);
break;
case 'udvd':
fsf.umount(WiiFilesystemFactory::kDVD);
break;
#endif
#ifdef USE_WII_SMB
case 'net':
fsf.asyncInitNetwork();
break;
case 'msmb':
fsf.setSMBLoginData(_editSMBServer->getEditString(),
_editSMBShare->getEditString(),
_editSMBUsername->getEditString(),
_editSMBPassword->getEditString());
fsf.mount(WiiFilesystemFactory::kSMB);
break;
case 'usmb':
fsf.umount(WiiFilesystemFactory::kSMB);
break;
#endif
default:
Dialog::handleCommand(sender, cmd, data);
break;
}
}
void WiiOptionsDialog::revert() {
gfx_set_underscan(ConfMan.getInt(_strUnderscanX,
Common::ConfigManager::kApplicationDomain),
ConfMan.getInt(_strUnderscanY,
Common::ConfigManager::kApplicationDomain));
}
void WiiOptionsDialog::load() {
int i;
i = ConfMan.getInt(_strUnderscanX,
Common::ConfigManager::kApplicationDomain);
_sliderUnderscanX->setValue(i);
i = ConfMan.getInt(_strUnderscanY,
Common::ConfigManager::kApplicationDomain);
_sliderUnderscanY->setValue(i);
i = ConfMan.getInt("wii_pad_sensitivity",
Common::ConfigManager::kApplicationDomain);
_sliderPadSensitivity->setValue(i);
i = ConfMan.getInt("wii_pad_acceleration",
Common::ConfigManager::kApplicationDomain);
_sliderPadAcceleration->setValue(i);
#ifdef USE_WII_SMB
_editSMBServer->setEditString(ConfMan.get("wii_smb_server",
Common::ConfigManager::kApplicationDomain));
_editSMBShare->setEditString(ConfMan.get("wii_smb_share",
Common::ConfigManager::kApplicationDomain));
_editSMBUsername->setEditString(ConfMan.get("wii_smb_username",
Common::ConfigManager::kApplicationDomain));
_editSMBPassword->setEditString(ConfMan.get("wii_smb_password",
Common::ConfigManager::kApplicationDomain));
#endif
}
void WiiOptionsDialog::save() {
ConfMan.setInt(_strUnderscanX,
_sliderUnderscanX->getValue(),
Common::ConfigManager::kApplicationDomain);
ConfMan.setInt(_strUnderscanY,
_sliderUnderscanY->getValue(),
Common::ConfigManager::kApplicationDomain);
ConfMan.setInt("wii_pad_sensitivity",
_sliderPadSensitivity->getValue(),
Common::ConfigManager::kApplicationDomain);
ConfMan.setInt("wii_pad_acceleration",
_sliderPadAcceleration->getValue(),
Common::ConfigManager::kApplicationDomain);
#ifdef USE_WII_SMB
ConfMan.set("wii_smb_server", _editSMBServer->getEditString(),
Common::ConfigManager::kApplicationDomain);
ConfMan.set("wii_smb_share", _editSMBShare->getEditString(),
Common::ConfigManager::kApplicationDomain);
ConfMan.set("wii_smb_username", _editSMBUsername->getEditString(),
Common::ConfigManager::kApplicationDomain);
ConfMan.set("wii_smb_password", _editSMBPassword->getEditString(),
Common::ConfigManager::kApplicationDomain);
#endif
ConfMan.flushToDisk();
}

View File

@@ -0,0 +1,80 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _WII_OPTIONS_H_
#define _WII_OPTIONS_H_
#include "common/str.h"
#include "common/ustr.h"
#include "gui/dialog.h"
#include "gui/widgets/tab.h"
#include "gui/widgets/edittext.h"
using namespace GUI;
class WiiOptionsDialog final : public GUI::Dialog {
typedef Common::String String;
typedef Common::U32String U32String;
public:
WiiOptionsDialog(bool doubleStrike);
virtual ~WiiOptionsDialog();
protected:
void handleTickle() override;
void handleCommand(CommandSender *sender, uint32 cmd, uint32 data) override;
private:
bool _doubleStrike;
String _strUnderscanX;
String _strUnderscanY;
TabWidget *_tab;
int _tabVideo;
SliderWidget *_sliderUnderscanX;
SliderWidget *_sliderUnderscanY;
int _tabInput;
SliderWidget *_sliderPadSensitivity;
SliderWidget *_sliderPadAcceleration;
#ifdef USE_WII_DI
int _tabDVD;
StaticTextWidget *_textDVDStatus;
#endif
#ifdef USE_WII_SMB
int _tabSMB;
StaticTextWidget *_textNetworkStatus;
StaticTextWidget *_textSMBStatus;
EditTextWidget *_editSMBServer;
EditTextWidget *_editSMBShare;
EditTextWidget *_editSMBUsername;
EditTextWidget *_editSMBPassword;
#endif
void revert();
void load();
void save();
};
#endif

View File

@@ -0,0 +1,349 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include <unistd.h>
#include <ogc/conf.h>
#include <ogc/lwp_watchdog.h>
#include "common/config-manager.h"
#include "common/textconsole.h"
#include "backends/fs/wii/wii-fs-factory.h"
#include "backends/mutex/wii/wii-mutex.h"
#include "backends/saves/default/default-saves.h"
#include "backends/timer/default/default-timer.h"
#include "osystem.h"
#include "options.h"
OSystem_Wii::OSystem_Wii() :
_startup_time(0),
_overlayInGUI(false),
_cursorDontScale(true),
_cursorPaletteDisabled(true),
_cursorPalette(NULL),
_cursorPaletteDirty(false),
_gameRunning(false),
_gameWidth(0),
_gameHeight(0),
_gamePixels(NULL),
_gameDirty(false),
_overlayVisible(true),
_overlayWidth(0),
_overlayHeight(0),
_overlaySize(0),
_overlayPixels(NULL),
_overlayDirty(false),
_lastScreenUpdate(0),
_currentWidth(0),
_currentHeight(0),
_currentXScale(1),
_currentYScale(1),
_configGraphicsMode(0),
_actualGraphicsMode(0),
_bilinearFilter(false),
_pfRGB565(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)),
_pfRGB3444(Graphics::PixelFormat(2, 4, 4, 4, 3, 8, 4, 0, 12)),
#ifdef USE_RGB_COLOR
_pfGame(Graphics::PixelFormat::createFormatCLUT8()),
_pfGameTexture(Graphics::PixelFormat::createFormatCLUT8()),
_pfCursor(Graphics::PixelFormat::createFormatCLUT8()),
#endif
_optionsDlgActive(false),
_consoleVisible(false),
_fullscreen(false),
_arCorrection(false),
_mouseVisible(false),
_mouseX(0),
_mouseY(0),
_mouseHotspotX(0),
_mouseHotspotY(0),
_mouseKeyColor(0),
_kbd_active(false),
_event_quit(false),
_lastPadCheck(0),
_padSensitivity(16),
_padAcceleration(4),
_mixer(NULL) {
}
OSystem_Wii::~OSystem_Wii() {
delete _mixer;
_mixer = NULL;
}
void OSystem_Wii::initBackend() {
_startup_time = gettime();
ConfMan.registerDefault("fullscreen", true);
ConfMan.registerDefault("aspect_ratio", true);
ConfMan.registerDefault("wii_video_default_underscan_x", 16);
ConfMan.registerDefault("wii_video_default_underscan_y", 16);
ConfMan.registerDefault("wii_video_ds_underscan_x", 16);
ConfMan.registerDefault("wii_video_ds_underscan_y", 16);
ConfMan.registerDefault("wii_pad_sensitivity", 48);
ConfMan.registerDefault("wii_pad_acceleration", 5);
ConfMan.registerDefault("wii_smb_server", "");
ConfMan.registerDefault("wii_smb_share", "");
ConfMan.registerDefault("wii_smb_username", "");
ConfMan.registerDefault("wii_smb_password", "");
WiiFilesystemFactory &fsf = WiiFilesystemFactory::instance();
#ifdef USE_WII_SMB
fsf.setSMBLoginData(ConfMan.get("wii_smb_server"),
ConfMan.get("wii_smb_share"),
ConfMan.get("wii_smb_username"),
ConfMan.get("wii_smb_password"));
#endif
fsf.asyncInit();
char buf[MAXPATHLEN];
if (!getcwd(buf, MAXPATHLEN))
Common::strcpy_s(buf, "/");
_savefileManager = new DefaultSaveFileManager(buf);
_timerManager = new DefaultTimerManager();
initGfx();
initSfx();
initEvents();
EventsBaseBackend::initBackend();
}
void OSystem_Wii::quit() {
/* Delete _timerManager before deinitializing events as it's tied */
delete _timerManager;
_timerManager = nullptr;
deinitEvents();
/* Delete _eventManager before destroying FS to avoid problems when releasing virtual keyboard data */
delete _eventManager;
_eventManager = nullptr;
deinitSfx();
deinitGfx();
WiiFilesystemFactory::instance().asyncDeinit();
}
void OSystem_Wii::engineInit() {
_gameRunning = true;
WiiFilesystemFactory::instance().umountUnused(ConfMan.getPath("path").toString(Common::Path::kNativeSeparator));
}
void OSystem_Wii::engineDone() {
_gameRunning = false;
switchVideoMode(gmStandard);
gfx_set_ar(4.0 / 3.0);
}
bool OSystem_Wii::hasFeature(Feature f) {
return (f == kFeatureFullscreenMode) ||
(f == kFeatureAspectRatioCorrection) ||
(f == kFeatureCursorPalette) ||
(f == kFeatureCursorAlpha) ||
(f == kFeatureOverlaySupportsAlpha) ||
(f == kFeatureTouchscreen);
}
void OSystem_Wii::setFeatureState(Feature f, bool enable) {
switch (f) {
case kFeatureFullscreenMode:
_fullscreen = enable;
gfx_set_pillarboxing(!enable);
break;
case kFeatureAspectRatioCorrection:
_arCorrection = enable;
break;
case kFeatureCursorPalette:
_cursorPaletteDisabled = !enable;
updateMousePalette();
break;
default:
break;
}
}
bool OSystem_Wii::getFeatureState(Feature f) {
switch (f) {
case kFeatureFullscreenMode:
return _fullscreen;
case kFeatureAspectRatioCorrection:
return _arCorrection;
case kFeatureCursorPalette:
return !_cursorPaletteDisabled;
default:
return false;
}
}
uint32 OSystem_Wii::getMillis(bool skipRecord) {
return ticks_to_millisecs(diff_ticks(_startup_time, gettime()));
}
void OSystem_Wii::delayMillis(uint msecs) {
usleep(msecs * 1000);
}
Common::MutexInternal *OSystem_Wii::createMutex() {
return createWiiMutexInternal();
}
Audio::Mixer *OSystem_Wii::getMixer() {
assert(_mixer);
return _mixer;
}
FilesystemFactory *OSystem_Wii::getFilesystemFactory() {
return &WiiFilesystemFactory::instance();
}
void OSystem_Wii::getTimeAndDate(TimeDate &td, bool skipRecord) const {
time_t curTime = time(0);
struct tm t = *localtime(&curTime);
td.tm_sec = t.tm_sec;
td.tm_min = t.tm_min;
td.tm_hour = t.tm_hour;
td.tm_mday = t.tm_mday;
td.tm_mon = t.tm_mon;
td.tm_year = t.tm_year;
td.tm_wday = t.tm_wday;
}
void OSystem_Wii::showOptionsDialog() {
if (_optionsDlgActive)
return;
bool ds = (_actualGraphicsMode == gmDoubleStrike) ||
(_actualGraphicsMode == gmDoubleStrikeFiltered);
_optionsDlgActive = true;
WiiOptionsDialog dlg(ds);
dlg.runModal();
_optionsDlgActive = false;
_padSensitivity = 64 - ConfMan.getInt("wii_pad_sensitivity");
_padAcceleration = 9 - ConfMan.getInt("wii_pad_acceleration");
}
void OSystem_Wii::logMessage(LogMessageType::Type type, const char *message) {
FILE *output = 0;
if (type == LogMessageType::kInfo || type == LogMessageType::kDebug)
output = stdout;
else
output = stderr;
fputs(message, output);
fflush(output);
}
#ifndef GAMECUBE
Common::String OSystem_Wii::getSystemLanguage() const {
const char *wiiCountries[] = {
"JP", // CONF_AREA_JPN Japan
"US", // CONF_AREA_USA United States of America
"", // CONF_AREA_EUR Europe?
"AU", // CONF_AREA_AUS Australia, Commonwealth of
"BR", // CONF_AREA_BRA Brazil, Federative Republic of
"TW", // CONF_AREA_TWN Taiwan, Province of China
"", // CONF_AREA_ROC Republic of China (Taiwan)
"KR", // CONF_AREA_KOR Korea, Republic of
"HK", // CONF_AREA_HKG Hong Kong, Special Administrative Region of China
"", // CONF_AREA_ASI Asia?
"", // CONF_AREA_LTN Lithuania?
"", // CONF_AREA_SAF South-Africa?
"CN" // CONF_AREA_CHN China, People's Republic of
};
// Start by detecting the country, since we can deduce some languages not
// supported on the Wii from it.
Common::String country;
// TODO: Can we get more fine-grained country setting?
int32 areaID = CONF_GetArea();
if ((areaID >= CONF_AREA_JPN) && (areaID <= CONF_AREA_CHN)) {
// It's a known area.
if (areaID == CONF_AREA_BRA) {
// Portuguese isn't available on the Wii, but we know it's the
// official language in Brazil, so we handle it separately.
return "pt_BR";
} else {
// Let's use our manual area to country mapping.
country = wiiCountries[areaID];
}
} else {
// This will only happen when new areas are added to the API.
warning("WII: Unknown system area: %d", areaID);
}
const char *wiiLanguages[] = {
"ja", // CONF_LANG_JAPANESE Japanese
"en", // CONF_LANG_ENGLISH English
"de", // CONF_LANG_GERMAN German
"fr", // CONF_LANG_FRENCH French
"es", // CONF_LANG_SPANISH Spanish
"it", // CONF_LANG_ITALIAN Italian
"nl", // CONF_LANG_DUTCH Dutch
"zh", // CONF_LANG_SIMP_CHINESE Simplified Chinese
"zh", // CONF_LANG_TRAD_CHINESE Traditional Chinese
"ko" // CONF_LANG_KOREAN Korean
};
// Now let's read the system language.
Common::String lang;
int32 langID = CONF_GetLanguage();
if ((langID >= CONF_LANG_JAPANESE) && (langID <= CONF_LANG_KOREAN)) {
// It's a known language, let's use our manual language mapping.
lang = wiiLanguages[langID];
if (country.empty()) {
// We don't know how to improve the detection,
// let's return the language alone.
return lang;
} else {
// Return the complete language_country string.
return lang + "_" + country;
}
} else {
// This will only happen when new languages are added to the API.
warning("WII: Unknown system language: %d", langID);
return EventsBaseBackend::getSystemLanguage();
}
}
#endif // !GAMECUBE

View File

@@ -0,0 +1,218 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _WII_OSYSTEM_H_
#define _WII_OSYSTEM_H_
#include <gctypes.h>
#include <gccore.h>
#include <gxflux/gfx.h>
#include "base/main.h"
#include "common/fs.h"
#include "common/rect.h"
#include "common/events.h"
#include "backends/base-backend.h"
#include "graphics/paletteman.h"
#include "graphics/surface.h"
#include "audio/mixer_intern.h"
#ifdef __cplusplus
extern "C" {
#endif
extern bool reset_btn_pressed;
extern bool power_btn_pressed;
#ifdef DEBUG_WII_MEMSTATS
extern void wii_memstats(void);
#endif
#ifdef __cplusplus
}
#endif
class OSystem_Wii final : public EventsBaseBackend, public PaletteManager {
private:
s64 _startup_time;
bool _cursorDontScale;
bool _cursorPaletteDisabled;
u16 *_cursorPalette;
bool _cursorPaletteDirty;
bool _gameRunning;
u16 _gameWidth, _gameHeight;
u8 *_gamePixels;
Graphics::Surface _surface;
gfx_screen_coords_t _coordsGame;
gfx_tex_t _texGame;
bool _gameDirty;
bool _overlayVisible;
u16 _overlayWidth, _overlayHeight;
u32 _overlaySize;
uint16 *_overlayPixels;
gfx_screen_coords_t _coordsOverlay;
gfx_tex_t _texOverlay;
bool _overlayDirty;
bool _overlayInGUI;
u32 _lastScreenUpdate;
u16 _currentWidth, _currentHeight;
f32 _currentXScale, _currentYScale;
s32 _configGraphicsMode;
s32 _actualGraphicsMode;
bool _bilinearFilter;
const Graphics::PixelFormat _pfRGB565;
const Graphics::PixelFormat _pfRGB3444;
#ifdef USE_RGB_COLOR
Graphics::PixelFormat _pfGame;
Graphics::PixelFormat _pfGameTexture;
Graphics::PixelFormat _pfCursor;
#endif
bool _consoleVisible;
bool _optionsDlgActive;
bool _fullscreen;
bool _arCorrection;
bool _mouseVisible;
s32 _mouseX, _mouseY;
s32 _mouseHotspotX, _mouseHotspotY;
u16 _mouseKeyColor;
gfx_tex_t _texMouse;
bool _kbd_active;
bool _event_quit;
u32 _lastPadCheck;
u8 _padSensitivity;
u8 _padAcceleration;
void initGfx();
void deinitGfx();
void updateScreenResolution();
void switchVideoMode(int mode);
bool needsScreenUpdate();
void updateMousePalette();
void initSfx();
void deinitSfx();
void initEvents();
void deinitEvents();
void updateEventScreenResolution();
bool pollKeyboard(Common::Event &event);
void showOptionsDialog();
protected:
Audio::MixerImpl *_mixer;
public:
enum {
gmStandard = 0,
gmStandardFiltered,
gmDoubleStrike,
gmDoubleStrikeFiltered
};
OSystem_Wii();
virtual ~OSystem_Wii();
void initBackend() override;
void engineInit() override;
void engineDone() override;
bool hasFeature(Feature f) override;
void setFeatureState(Feature f, bool enable) override;
bool getFeatureState(Feature f) override;
const GraphicsMode *getSupportedGraphicsModes() const override;
int getDefaultGraphicsMode() const override;
bool setGraphicsMode(int mode, uint flags = kGfxModeNoFlags) override;
#ifdef USE_RGB_COLOR
Graphics::PixelFormat getScreenFormat() const override;
Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
#endif
int getGraphicsMode() const override;
virtual void initSize(uint width, uint height,
const Graphics::PixelFormat *format) override;
int16 getWidth() override;
int16 getHeight() override;
PaletteManager *getPaletteManager() override { return this; }
protected:
void setPalette(const byte *colors, uint start, uint num) override;
void grabPalette(byte *colors, uint start, uint num) const override;
public:
void setCursorPalette(const byte *colors, uint start, uint num) override;
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y,
int w, int h) override;
void updateScreen() override;
Graphics::Surface *lockScreen() override;
void unlockScreen() override;
void setShakePos(int shakeXOffset, int shakeYOffset) override;
void showOverlay(bool inGUI) override;
void hideOverlay() override;
bool isOverlayVisible() const override { return _overlayVisible; }
void clearOverlay() override;
void grabOverlay(Graphics::Surface &surface) override;
virtual void copyRectToOverlay(const void *buf, int pitch,
int x, int y, int w, int h) override;
int16 getOverlayWidth() const override;
int16 getOverlayHeight() const override;
Graphics::PixelFormat getOverlayFormat() const override;
bool showMouse(bool visible) override;
void warpMouse(int x, int y) override;
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX,
int hotspotY, uint32 keycolor,
bool dontScale,
const Graphics::PixelFormat *format, const byte *mask) override;
bool pollEvent(Common::Event &event) override;
uint32 getMillis(bool skipRecord = false) override;
void delayMillis(uint msecs) override;
Common::MutexInternal *createMutex() override;
typedef void (*SoundProc)(void *param, byte *buf, int len);
void quit() override;
Audio::Mixer *getMixer() override;
FilesystemFactory *getFilesystemFactory() override;
void getTimeAndDate(TimeDate &td, bool skipRecord = false) const override;
void logMessage(LogMessageType::Type type, const char *message) override;
#ifndef GAMECUBE
Common::String getSystemLanguage() const override;
#endif // GAMECUBE
};
#endif

View File

@@ -0,0 +1,456 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_EXCEPTION_printf
#include <unistd.h>
#include <malloc.h>
#include "osystem.h"
#include <ogc/lwp_watchdog.h>
#ifndef GAMECUBE
#include <wiiuse/wpad.h>
#endif
#ifdef USE_WII_KBD
#include <wiikeyboard/keyboard.h>
#endif
#include "common/config-manager.h"
#include "backends/timer/default/default-timer.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_R (PAD_TRIGGER_R | (WPAD_BUTTON_1 << 16))
#define PADS_Z (PAD_TRIGGER_Z | (WPAD_BUTTON_2 << 16))
#define PADS_START (PAD_BUTTON_START | (WPAD_BUTTON_HOME << 16))
#define PADS_UP (PAD_BUTTON_UP | (WPAD_BUTTON_UP << 16))
#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_R PAD_TRIGGER_R
#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
#ifdef USE_WII_KBD
static int keymap[][3] = {
{ KS_Return, Common::KEYCODE_RETURN, Common::ASCII_RETURN },
{ KS_Up, Common::KEYCODE_UP, 0 },
{ KS_Down, Common::KEYCODE_DOWN, 0 },
{ KS_Left, Common::KEYCODE_LEFT, 0 },
{ KS_Right, Common::KEYCODE_RIGHT, 0 },
{ KS_Shift_L, Common::KEYCODE_LSHIFT, 0 },
{ KS_Shift_R, Common::KEYCODE_RSHIFT, 0 },
{ KS_Control_L, Common::KEYCODE_LCTRL, 0 },
{ KS_Control_R, Common::KEYCODE_RCTRL, 0 },
{ KS_Alt_L, Common::KEYCODE_LALT, 0 },
{ KS_Alt_R, Common::KEYCODE_RALT, 0 },
{ KS_Meta_L, Common::KEYCODE_LMETA, 0 },
{ KS_Meta_R, Common::KEYCODE_RMETA, 0 },
{ KS_KP_0, Common::KEYCODE_KP0, '0' },
{ KS_KP_1, Common::KEYCODE_KP1, '1' },
{ KS_KP_2, Common::KEYCODE_KP2, '2' },
{ KS_KP_3, Common::KEYCODE_KP3, '3' },
{ KS_KP_4, Common::KEYCODE_KP4, '4' },
{ KS_KP_5, Common::KEYCODE_KP5, '5' },
{ KS_KP_6, Common::KEYCODE_KP6, '6' },
{ KS_KP_7, Common::KEYCODE_KP7, '7' },
{ KS_KP_8, Common::KEYCODE_KP8, '8' },
{ KS_KP_9, Common::KEYCODE_KP9, '9' },
{ KS_Home, Common::KEYCODE_HOME, 0 },
{ KS_Insert, Common::KEYCODE_INSERT, 0 },
{ KS_End, Common::KEYCODE_END, 0 },
{ KS_Prior, Common::KEYCODE_PAGEUP, 0 },
{ KS_Next, Common::KEYCODE_PAGEDOWN, 0 },
{ KS_f1, Common::KEYCODE_F1, Common::ASCII_F1 },
{ KS_f2, Common::KEYCODE_F2, Common::ASCII_F2 },
{ KS_f3, Common::KEYCODE_F3, Common::ASCII_F3 },
{ KS_f4, Common::KEYCODE_F4, Common::ASCII_F4 },
{ KS_f5, Common::KEYCODE_F5, Common::ASCII_F5 },
{ KS_f6, Common::KEYCODE_F6, Common::ASCII_F6 },
{ KS_f7, Common::KEYCODE_F7, Common::ASCII_F7 },
{ KS_f8, Common::KEYCODE_F8, Common::ASCII_F8 },
{ KS_f9, Common::KEYCODE_F9, Common::ASCII_F9 },
{ KS_f10, Common::KEYCODE_F10, Common::ASCII_F10 },
{ KS_f11, Common::KEYCODE_F11, Common::ASCII_F11 },
{ KS_f12, Common::KEYCODE_F12, Common::ASCII_F12 },
{ KS_f13, Common::KEYCODE_F13, 0 },
{ KS_f14, Common::KEYCODE_F14, 0 },
{ KS_f15, Common::KEYCODE_F15, 0 },
{ KS_F1, Common::KEYCODE_F1, Common::ASCII_F1 },
{ KS_F2, Common::KEYCODE_F2, Common::ASCII_F2 },
{ KS_F3, Common::KEYCODE_F3, Common::ASCII_F3 },
{ KS_F4, Common::KEYCODE_F4, Common::ASCII_F4 },
{ KS_F5, Common::KEYCODE_F5, Common::ASCII_F5 },
{ KS_F6, Common::KEYCODE_F6, Common::ASCII_F6 },
{ KS_F7, Common::KEYCODE_F7, Common::ASCII_F7 },
{ KS_F8, Common::KEYCODE_F8, Common::ASCII_F8 },
{ KS_F9, Common::KEYCODE_F9, Common::ASCII_F9 },
{ KS_F10, Common::KEYCODE_F10, Common::ASCII_F10 },
{ KS_F11, Common::KEYCODE_F11, Common::ASCII_F11 },
{ KS_F12, Common::KEYCODE_F12, Common::ASCII_F12 },
{ KS_F13, Common::KEYCODE_F13, 0 },
{ KS_F14, Common::KEYCODE_F14, 0 },
{ KS_F15, Common::KEYCODE_F15, 0 },
{ KS_KP_Separator, Common::KEYCODE_KP_PERIOD, '.' },
{ KS_KP_Divide, Common::KEYCODE_KP_DIVIDE, '/' },
{ KS_KP_Multiply, Common::KEYCODE_KP_MULTIPLY, '*' },
{ KS_KP_Add, Common::KEYCODE_KP_PLUS, '+' },
{ KS_KP_Subtract, Common::KEYCODE_KP_MINUS, '-' },
{ KS_KP_Equal, Common::KEYCODE_KP_EQUALS, '=' },
{ KS_KP_Enter, Common::KEYCODE_KP_ENTER, Common::ASCII_RETURN },
{ 0, 0, 0 }
};
#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);
if (timer_stack) {
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
_padSensitivity = 64 - ConfMan.getInt("wii_pad_sensitivity");
_padAcceleration = 9 - ConfMan.getInt("wii_pad_acceleration");
#ifdef USE_WII_KBD
_kbd_active = KEYBOARD_Init(NULL) >= 0;
#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);
free(timer_stack);
timer_thread_running = false;
}
#ifdef USE_WII_KBD
if (_kbd_active)
KEYBOARD_Deinit();
#endif
#ifndef GAMECUBE
WPAD_Shutdown();
#endif
}
void OSystem_Wii::updateEventScreenResolution() {
#ifndef GAMECUBE
WPAD_SetVRes(WPAD_CHAN_0, _currentWidth + _currentWidth / 5,
_currentHeight + _currentHeight / 5);
#endif
}
#ifdef USE_WII_KBD
bool OSystem_Wii::pollKeyboard(Common::Event &event) {
int i;
keyboard_event kbdEvent;
s32 res = KEYBOARD_GetEvent(&kbdEvent);
if (!res)
return false;
switch (kbdEvent.type) {
case KEYBOARD_PRESSED:
event.type = Common::EVENT_KEYDOWN;
break;
case KEYBOARD_RELEASED:
event.type = Common::EVENT_KEYUP;
break;
case KEYBOARD_CONNECTED:
printf("keyboard connected\n");
return false;
case KEYBOARD_DISCONNECTED:
printf("keyboard disconnected\n");
return false;
default:
return false;
}
if (MOD_ONESET(kbdEvent.modifiers, MOD_ANYSHIFT))
event.kbd.flags |= Common::KBD_SHIFT;
if (MOD_ONESET(kbdEvent.modifiers, MOD_ANYCONTROL))
event.kbd.flags |= Common::KBD_CTRL;
if (MOD_ONESET(kbdEvent.modifiers, MOD_ANYMETA))
event.kbd.flags |= Common::KBD_ALT;
i = 0;
while (keymap[i][0] != 0) {
if (keymap[i][0] == kbdEvent.symbol) {
event.kbd.keycode = static_cast<Common::KeyCode>(keymap[i][1]);
event.kbd.ascii = keymap[i][2];
return true;
}
i++;
}
// skip unmapped special keys
if (kbdEvent.symbol > 0xff)
return false;
event.kbd.keycode = static_cast<Common::KeyCode>(kbdEvent.symbol);
event.kbd.ascii = kbdEvent.symbol;
return true;
}
#endif
#define PAD_EVENT(pad_button, kbd_keycode, kbd_ascii, modifier) \
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; \
event.kbd.flags = modifier; \
return true; \
} \
} while (0)
bool OSystem_Wii::pollEvent(Common::Event &event) {
if ((reset_btn_pressed || power_btn_pressed) && !_event_quit) {
_event_quit = true;
event.type = Common::EVENT_QUIT;
printf("quit event\n");
return true;
}
if (needsScreenUpdate())
updateScreen();
u32 bd = 0, bh = 0, bu = 0;
if (PAD_ScanPads() & 1) {
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) {
byte flags = 0;
if (bh & PADS_UP) {
PAD_EVENT(PADS_START, Common::KEYCODE_F5, Common::ASCII_F5,
Common::KBD_CTRL);
if (bd & PADS_R) {
_consoleVisible = !_consoleVisible;
printf("Console %s...\n", _consoleVisible ? "Shown" : "Hidden");
return false;
}
flags = Common::KBD_SHIFT;
}
if (bd & PADS_R) {
showOptionsDialog();
return false;
}
if (bd & PADS_RIGHT) {
event.type = Common::EVENT_PREDICTIVE_DIALOG;
return true;
}
PAD_EVENT(PADS_Z, Common::KEYCODE_RETURN, Common::ASCII_RETURN, flags);
PAD_EVENT(PADS_X, Common::KEYCODE_ESCAPE, Common::ASCII_ESCAPE, flags);
PAD_EVENT(PADS_Y, Common::KEYCODE_PERIOD, '.', flags);
PAD_EVENT(PADS_START, Common::KEYCODE_F5, Common::ASCII_F5, flags);
PAD_EVENT(PADS_UP, Common::KEYCODE_LSHIFT, 0, flags);
PAD_EVENT(PADS_DOWN, Common::KEYCODE_F7, Common::ASCII_F7, Common::KBD_CTRL);
//PAD_EVENT(PADS_LEFT, Common::KEYCODE_F8, Common::ASCII_F8, Common::KBD_CTRL);
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 = s32(ir.x) - _currentWidth / 10;
my = s32(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)) > _padSensitivity)
mx += PAD_StickX(0) /
(_padAcceleration * _overlayWidth / _currentWidth);
if (abs (PAD_StickY(0)) > _padSensitivity)
my -= PAD_StickY(0) /
(_padAcceleration * _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;
}
}
#ifdef USE_WII_KBD
if (_kbd_active && pollKeyboard(event))
return true;
#endif
return false;
}

View File

@@ -0,0 +1,789 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_EXCEPTION_printf
#define FORBIDDEN_SYMBOL_EXCEPTION_abort
#include <malloc.h>
#include <gxflux/gfx_con.h>
#include "common/config-manager.h"
#include "graphics/blit.h"
#include "backends/fs/wii/wii-fs-factory.h"
#include "osystem.h"
// Uncomment this to enable debug output to console
//#define PLATFORM_WII_OSYSTEM_GFX_DEBUG
#define ROUNDUP(x,n) (-(-(x) & -(n)))
#define MAX_FPS 30
#define TLUT_GAME GX_TLUT0
#define TLUT_MOUSE GX_TLUT1
static const OSystem::GraphicsMode _supportedGraphicsModes[] = {
{
"default",
"Default",
OSystem_Wii::gmStandard
},
{
"defaultbilinear",
"Default, bilinear filtering",
OSystem_Wii::gmStandardFiltered
},
{
"ds",
"Double-strike",
OSystem_Wii::gmDoubleStrike
},
{
"dsbilinear",
"Double-strike, bilinear filtering",
OSystem_Wii::gmDoubleStrikeFiltered
},
{ 0, 0, 0 }
};
void OSystem_Wii::initGfx() {
gfx_set_underscan(ConfMan.getInt("wii_video_default_underscan_x"),
ConfMan.getInt("wii_video_default_underscan_y"));
_overlayWidth = gfx_video_get_width();
_overlayHeight = gfx_video_get_height();
#ifndef GAMECUBE
if (CONF_GetAspectRatio() && _fullscreen)
_overlayHeight = 400;
#endif
_overlaySize = _overlayWidth * _overlayHeight * 2;
_overlayPixels = (uint16 *) memalign(32, _overlaySize);
memset(&_texMouse, 0, sizeof(gfx_tex_t));
memset(&_texOverlay, 0, sizeof(gfx_tex_t));
memset(&_texGame, 0, sizeof(gfx_tex_t));
_cursorPalette = (u16 *) malloc(256 * 2);
if (!_cursorPalette) {
printf("could not alloc palette buffer\n");
::abort();
}
memset(_cursorPalette, 0, 256 * 2);
if (!gfx_tex_init(&_texOverlay, GFX_TF_RGB5A3, 0,
_overlayWidth, _overlayHeight)) {
printf("could not init the overlay texture\n");
::abort();
}
gfx_coords(&_coordsOverlay, &_texOverlay, GFX_COORD_FULLSCREEN);
}
void OSystem_Wii::deinitGfx() {
gfx_tex_deinit(&_texMouse);
gfx_tex_deinit(&_texGame);
gfx_tex_deinit(&_texOverlay);
free(_cursorPalette);
_cursorPalette = NULL;
free(_gamePixels);
_gamePixels = NULL;
free(_overlayPixels);
_overlayPixels = NULL;
}
void OSystem_Wii::updateScreenResolution() {
if (_overlayInGUI) {
_currentWidth = _overlayWidth;
_currentHeight = _overlayHeight;
} else {
_currentWidth = _gameWidth;
_currentHeight = _gameHeight;
}
if (_currentWidth > 0)
_currentXScale = f32(gfx_video_get_width()) / f32(_currentWidth);
else
_currentXScale = 1.0;
if (_currentHeight > 0)
_currentYScale = f32(gfx_video_get_height()) / f32(_currentHeight);
else
_currentYScale = 1.0;
updateEventScreenResolution();
}
void OSystem_Wii::switchVideoMode(int mode) {
static const struct {
gfx_video_mode_t mode;
bool filter;
} map[] = {
{ GFX_MODE_DEFAULT, false },
{ GFX_MODE_DEFAULT, true },
{ GFX_MODE_DS, false },
{ GFX_MODE_DS, true }
};
if (_gameHeight > 240) {
if (mode == gmDoubleStrike)
mode = gmStandard;
else if (mode == gmDoubleStrikeFiltered)
mode = gmStandardFiltered;
}
printf("switchVideoMode %d\n", mode);
if (map[_actualGraphicsMode].mode != map[mode].mode) {
GXRModeObj obj;
gfx_video_deinit();
gfx_video_get_modeobj(&obj, GFX_STANDARD_AUTO, map[mode].mode);
gfx_video_init(&obj);
gfx_init();
gfx_con_init(NULL);
}
_actualGraphicsMode = mode;
_bilinearFilter = map[mode].filter;
gfx_tex_set_bilinear_filter(&_texGame, _bilinearFilter);
gfx_tex_set_bilinear_filter(&_texMouse, _bilinearFilter);
u16 usx, usy;
if (map[mode].mode == GFX_MODE_DS) {
usx = ConfMan.getInt("wii_video_ds_underscan_x",
Common::ConfigManager::kApplicationDomain);
usy = ConfMan.getInt("wii_video_ds_underscan_y",
Common::ConfigManager::kApplicationDomain);
} else {
usx = ConfMan.getInt("wii_video_default_underscan_x",
Common::ConfigManager::kApplicationDomain);
usy = ConfMan.getInt("wii_video_default_underscan_y",
Common::ConfigManager::kApplicationDomain);
}
gfx_set_underscan(usx, usy);
gfx_coords(&_coordsOverlay, &_texOverlay, GFX_COORD_FULLSCREEN);
gfx_coords(&_coordsGame, &_texGame, GFX_COORD_FULLSCREEN);
updateScreenResolution();
}
const OSystem::GraphicsMode* OSystem_Wii::getSupportedGraphicsModes() const {
return _supportedGraphicsModes;
}
int OSystem_Wii::getDefaultGraphicsMode() const {
return gmStandard;
}
bool OSystem_Wii::setGraphicsMode(int mode, uint flags) {
_configGraphicsMode = mode;
return true;
}
int OSystem_Wii::getGraphicsMode() const {
return _configGraphicsMode;
}
#ifdef USE_RGB_COLOR
Graphics::PixelFormat OSystem_Wii::getScreenFormat() const {
return _pfGame;
}
Common::List<Graphics::PixelFormat> OSystem_Wii::getSupportedFormats() const {
Common::List<Graphics::PixelFormat> res;
res.push_back(_pfRGB565);
res.push_back(Graphics::PixelFormat::createFormatCLUT8());
return res;
}
#endif
void OSystem_Wii::initSize(uint width, uint height,
const Graphics::PixelFormat *format) {
bool update = false;
gfx_tex_format_t tex_format;
#ifdef USE_RGB_COLOR
Graphics::PixelFormat newFormat;
if (format)
newFormat = *format;
else
newFormat = Graphics::PixelFormat::createFormatCLUT8();
if (newFormat.bytesPerPixel > 2)
newFormat = Graphics::PixelFormat::createFormatCLUT8();
if (_pfGame != newFormat) {
_pfGame = newFormat;
update = true;
}
#endif
uint newWidth, newHeight;
#ifdef USE_RGB_COLOR
if (_pfGame.bytesPerPixel > 1) {
newWidth = ROUNDUP(width, 4);
newHeight = ROUNDUP(height, 4);
} else {
#endif
newWidth = ROUNDUP(width, 8);
newHeight = ROUNDUP(height, 4);
#ifdef USE_RGB_COLOR
}
#endif
if (_gameWidth != newWidth || _gameHeight != newHeight) {
assert((newWidth <= 640) && (newHeight <= 480));
if (width != newWidth || height != newHeight)
printf("extending texture for compatibility: %ux%u -> %ux%u\n",
width, height, newWidth, newHeight);
_gameWidth = newWidth;
_gameHeight = newHeight;
update = true;
}
if (_gameRunning) {
switchVideoMode(_configGraphicsMode);
if (_arCorrection && (_gameWidth == 320) && (_gameHeight == 200))
gfx_set_ar(320.0 / 240.0);
else
gfx_set_ar(f32(_gameWidth) / f32(_gameHeight));
}
if (update) {
free(_gamePixels);
tex_format = GFX_TF_PALETTE_RGB565;
#ifdef USE_RGB_COLOR
if (_pfGame.bytesPerPixel > 1) {
tex_format = GFX_TF_RGB565;
_pfGameTexture = _pfRGB565;
}
printf("initSize %u*%u*%u (%u%u%u -> %u%u%u match: %d)\n",
_gameWidth, _gameHeight, _pfGame.bytesPerPixel * 8,
8 - _pfGame.rLoss, 8 - _pfGame.gLoss, 8 - _pfGame.bLoss,
8 - _pfGameTexture.rLoss, 8 - _pfGameTexture.gLoss,
8 - _pfGameTexture.bLoss, _pfGame == _pfGameTexture);
_gamePixels = (u8 *) memalign(32, _gameWidth * _gameHeight *
_pfGame.bytesPerPixel);
memset(_gamePixels, 0, _gameWidth * _gameHeight *
_pfGame.bytesPerPixel);
#else
printf("initSize %u*%u\n", _gameWidth, _gameHeight);
_gamePixels = (u8 *) memalign(32, _gameWidth * _gameHeight);
memset(_gamePixels, 0, _gameWidth * _gameHeight);
#endif
if (!gfx_tex_init(&_texGame, tex_format, TLUT_GAME,
_gameWidth, _gameHeight)) {
printf("could not init the game texture\n");
::abort();
}
gfx_tex_set_bilinear_filter(&_texGame, _bilinearFilter);
gfx_coords(&_coordsGame, &_texGame, GFX_COORD_FULLSCREEN);
updateScreenResolution();
}
}
int16 OSystem_Wii::getWidth() {
return _gameWidth;
}
int16 OSystem_Wii::getHeight() {
return _gameHeight;
}
void OSystem_Wii::updateMousePalette() {
#ifdef PLATFORM_WII_OSYSTEM_GFX_DEBUG
printf("%s() _cursorPaletteDisabled:%d\n", __func__, _cursorPaletteDisabled);
#endif
if (_texMouse.palette) {
if (!_cursorPaletteDisabled) {
memcpy(_texMouse.palette, _cursorPalette, 256 * 2);
#ifdef USE_RGB_COLOR
} else if (_pfGame.bytesPerPixel != 1) {
// When restoring the palette, there may be cases where game doesn't have any palette
// In this case, clear the palette
memset(_texMouse.palette, 0, 256 * 2);
#endif
} else {
memcpy(_texMouse.palette, _texGame.palette, 256 * 2);
}
_cursorPaletteDirty = true;
}
}
void OSystem_Wii::setPalette(const byte *colors, uint start, uint num) {
#ifdef PLATFORM_WII_OSYSTEM_GFX_DEBUG
printf("%s(%p, %d, %d) _cursorPaletteDisabled:%d\n", __func__, colors, start, num, _cursorPaletteDisabled);
#endif
#ifdef USE_RGB_COLOR
assert(_pfGame.bytesPerPixel == 1);
#endif
const byte *s = colors;
u16 *d = _texGame.palette;
for (uint i = 0; i < num; ++i, s +=3)
d[start + i] = _pfRGB565.RGBToColor(s[0], s[1], s[2]);
gfx_tex_flush_palette(&_texGame);
updateMousePalette();
}
void OSystem_Wii::grabPalette(byte *colors, uint start, uint num) const {
#ifdef USE_RGB_COLOR
assert(_pfGame.bytesPerPixel == 1);
#endif
u16 *s = _texGame.palette;
byte *d = colors;
u8 r, g, b;
for (uint i = 0; i < num; ++i, d += 3) {
_pfRGB565.colorToRGB(s[start + i], r, g, b);
d[0] = r;
d[1] = g;
d[2] = b;
}
}
void OSystem_Wii::setCursorPalette(const byte *colors, uint start, uint num) {
#ifdef PLATFORM_WII_OSYSTEM_GFX_DEBUG
printf("%s(%p,%u,%u) _cursorPaletteDisabled:%d\n", __func__, colors, start, num, _cursorPaletteDisabled);
#endif
if (!_texMouse.palette) {
printf("switching to palette based cursor\n");
if (!gfx_tex_init(&_texMouse, GFX_TF_PALETTE_RGB5A3, TLUT_MOUSE,
16, 16)) {
printf("could not init the mouse texture\n");
::abort();
}
gfx_tex_set_bilinear_filter(&_texMouse, _bilinearFilter);
}
_cursorPaletteDisabled = false;
const byte *s = colors;
u16 *d = _cursorPalette;
for (uint i = 0; i < num; ++i, s += 3) {
d[start + i] = _pfRGB3444.ARGBToColor(0xff, s[0], s[1], s[2]);
}
updateMousePalette();
}
void OSystem_Wii::copyRectToScreen(const void *buf, int pitch, int x, int y,
int w, int h) {
assert(x >= 0 && x < _gameWidth);
assert(y >= 0 && y < _gameHeight);
assert(w > 0 && x + w <= _gameWidth);
assert(h > 0 && y + h <= _gameHeight);
#ifdef USE_RGB_COLOR
if (_pfGame.bytesPerPixel > 1) {
if (!Graphics::crossBlit(_gamePixels +
y * _gameWidth * _pfGame.bytesPerPixel +
x * _pfGame.bytesPerPixel,
(const byte *)buf, _gameWidth * _pfGame.bytesPerPixel,
pitch, w, h, _pfGameTexture, _pfGame)) {
printf("crossBlit failed\n");
::abort();
}
} else {
#endif
byte *dst = _gamePixels + y * _gameWidth + x;
if (_gameWidth == pitch && pitch == w) {
memcpy(dst, buf, h * w);
} else {
const byte *src = (const byte *)buf;
do {
memcpy(dst, src, w);
src += pitch;
dst += _gameWidth;
} while (--h);
}
#ifdef USE_RGB_COLOR
}
#endif
_gameDirty = true;
}
bool OSystem_Wii::needsScreenUpdate() {
if (getMillis() - _lastScreenUpdate < 1000 / MAX_FPS)
return false;
if (_gameRunning && _gameDirty)
return true;
if (_overlayVisible && _overlayDirty)
return true;
if (_mouseVisible && _texMouse.palette && _cursorPaletteDirty)
return true;
return false;
}
void OSystem_Wii::updateScreen() {
static f32 ar;
static gfx_screen_coords_t cc;
static f32 csx, csy;
u32 now = getMillis();
if (now - _lastScreenUpdate < 1000 / MAX_FPS)
return;
if (!gfx_frame_start()) {
printf("last frame not done!\n");
return;
}
#ifdef DEBUG_WII_MEMSTATS
wii_memstats();
#endif
_lastScreenUpdate = now;
if (_overlayVisible || _consoleVisible)
gfx_set_colorop(COLOROP_SIMPLEFADE, gfx_color_none, gfx_color_none);
if (_gameRunning) {
if (_gameDirty) {
gfx_tex_convert(&_texGame, _gamePixels);
_gameDirty = false;
}
gfx_draw_tex(&_texGame, &_coordsGame);
}
if (_overlayVisible) {
if (!_consoleVisible)
gfx_set_colorop(COLOROP_NONE, gfx_color_none, gfx_color_none);
if (_gameRunning)
ar = gfx_set_ar(4.0 / 3.0);
if (_overlayDirty) {
gfx_tex_convert(&_texOverlay, _overlayPixels);
_overlayDirty = false;
}
gfx_draw_tex(&_texOverlay, &_coordsOverlay);
}
if (_mouseVisible) {
if (_cursorDontScale) {
csx = 1.0f / _currentXScale;
csy = 1.0f / _currentYScale;
} else {
csx = 1.0f;
csy = 1.0f;
}
cc.x = f32(_mouseX - csx * _mouseHotspotX) * _currentXScale;
cc.y = f32(_mouseY - csy * _mouseHotspotY) * _currentYScale;
cc.w = f32(_texMouse.width) * _currentXScale * csx;
cc.h = f32(_texMouse.height) * _currentYScale * csy;
if (_texMouse.palette && _cursorPaletteDirty) {
_texMouse.palette[_mouseKeyColor] = 0;
gfx_tex_flush_palette(&_texMouse);
_cursorPaletteDirty = false;
}
#ifdef PLATFORM_WII_OSYSTEM_GFX_DEBUG
//printf("%s() cc.x:%f cc.y:%f cc.w:%f cc.h:%f xscale:%f yscale:%f\n", __func__, cc.x, cc.y, cc.w, cc.h, _currentXScale, _currentYScale);
#endif
gfx_draw_tex(&_texMouse, &cc);
}
if (_consoleVisible)
gfx_con_draw();
if (_overlayVisible && _gameRunning)
gfx_set_ar(ar);
gfx_frame_end();
}
Graphics::Surface *OSystem_Wii::lockScreen() {
_surface.init(_gameWidth, _gameHeight,
#ifdef USE_RGB_COLOR
_gameWidth * _pfGame.bytesPerPixel, _gamePixels, _pfGame
#else
_gameWidth, _gamePixels, Graphics::PixelFormat::createFormatCLUT8()
#endif
);
return &_surface;
}
void OSystem_Wii::unlockScreen() {
_gameDirty = true;
}
void OSystem_Wii::setShakePos(int shakeXOffset, int shakeYOffset) {
gfx_coords(&_coordsGame, &_texGame, GFX_COORD_FULLSCREEN);
_coordsGame.x -= f32(shakeXOffset) * _currentXScale;
_coordsGame.y -= f32(shakeYOffset) * _currentYScale;
}
void OSystem_Wii::showOverlay(bool inGUI) {
if (inGUI) {
_mouseX = _overlayWidth / 2;
_mouseY = _overlayHeight / 2;
}
_overlayInGUI = inGUI;
_overlayVisible = true;
updateScreenResolution();
gfx_tex_set_bilinear_filter(&_texMouse, true);
}
void OSystem_Wii::hideOverlay() {
if (_overlayInGUI) {
_mouseX = _gameWidth / 2;
_mouseY = _gameHeight / 2;
}
_overlayInGUI = false;
_overlayVisible = false;
updateScreenResolution();
gfx_tex_set_bilinear_filter(&_texMouse, _bilinearFilter);
}
void OSystem_Wii::clearOverlay() {
memset(_overlayPixels, 0, _overlaySize);
_overlayDirty = true;
}
void OSystem_Wii::grabOverlay(Graphics::Surface &surface) {
assert(surface.w >= _overlayWidth);
assert(surface.h >= _overlayHeight);
assert(surface.format.bytesPerPixel == sizeof(uint16));
byte *src = (byte *)_overlayPixels;
byte *dst = (byte *)surface.getPixels();
Graphics::copyBlit(dst, src, surface.pitch, _overlayWidth * sizeof(uint16),
_overlayWidth, _overlayHeight, sizeof(uint16));
}
void OSystem_Wii::copyRectToOverlay(const void *buf, int pitch, int x,
int y, int w, int h) {
const byte *src = (const byte *)buf;
if (x < 0) {
w += x;
src -= x * sizeof(uint16);
x = 0;
}
if (y < 0) {
h += y;
src -= y * pitch;
y = 0;
}
if (w > _overlayWidth - x)
w = _overlayWidth - x;
if (h > _overlayHeight - y)
h = _overlayHeight - y;
if (w <= 0 || h <= 0)
return;
uint16 *dst = _overlayPixels + (y * _overlayWidth + x);
if (_overlayWidth == (uint16)w && (uint16)pitch == _overlayWidth * sizeof(uint16)) {
memcpy(dst, src, h * pitch);
} else {
do {
memcpy(dst, src, w * sizeof(uint16));
src += pitch;
dst += _overlayWidth;
} while (--h);
}
_overlayDirty = true;
}
int16 OSystem_Wii::getOverlayWidth() const {
return _overlayWidth;
}
int16 OSystem_Wii::getOverlayHeight() const {
return _overlayHeight;
}
Graphics::PixelFormat OSystem_Wii::getOverlayFormat() const {
return _pfRGB3444;
}
bool OSystem_Wii::showMouse(bool visible) {
bool last = _mouseVisible;
_mouseVisible = visible;
#ifdef PLATFORM_WII_OSYSTEM_GFX_DEBUG
if (_mouseVisible != last) {
printf("%s(%d)\n", __func__, _mouseVisible);
}
#endif
return last;
}
void OSystem_Wii::warpMouse(int x, int y) {
_mouseX = x;
_mouseY = y;
}
void OSystem_Wii::setMouseCursor(const void *buf, uint w, uint h, int hotspotX,
int hotspotY, uint32 keycolor,
bool dontScale,
const Graphics::PixelFormat *format, const byte *mask) {
#ifdef PLATFORM_WII_OSYSTEM_GFX_DEBUG
printf("%s(%p, w:%u, h:%u, hsX:%d, hsY:%d, kc:%u, dontScale:%d, %p, %p)\n", __func__, buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format, mask);
#endif
if (mask)
printf("OSystem_Wii::setMouseCursor: Masks are not supported\n");
gfx_tex_format_t tex_format = GFX_TF_PALETTE_RGB5A3;
uint tw, th;
uint32 oldKeycolor = _mouseKeyColor;
#ifdef USE_RGB_COLOR
if (!format)
_pfCursor = Graphics::PixelFormat::createFormatCLUT8();
else
_pfCursor = *format;
if (_pfCursor.bytesPerPixel > 1) {
tex_format = GFX_TF_RGB5A3;
_mouseKeyColor = keycolor & 0xffff;
tw = ROUNDUP(w, 4);
th = ROUNDUP(h, 4);
} else {
#endif
_mouseKeyColor = keycolor & 0xff;
tw = ROUNDUP(w, 8);
th = ROUNDUP(h, 4);
#ifdef USE_RGB_COLOR
}
#endif
if (!gfx_tex_init(&_texMouse, tex_format, TLUT_MOUSE, tw, th)) {
printf("could not init the mouse texture\n");
::abort();
}
gfx_tex_set_bilinear_filter(&_texMouse, _bilinearFilter);
u8 bpp = _texMouse.bpp >> 3;
byte *tmp = (byte *) malloc(tw * th * bpp);
if (!tmp) {
printf("could not alloc temp cursor buffer\n");
::abort();
}
if (bpp > 1)
memset(tmp, 0, tw * th * bpp);
else
memset(tmp, _mouseKeyColor, tw * th);
#ifdef USE_RGB_COLOR
if (bpp > 1) {
if (!Graphics::crossBlit(tmp, (const byte *)buf,
tw * _pfRGB3444.bytesPerPixel,
w * _pfCursor.bytesPerPixel,
tw, th, _pfRGB3444, _pfCursor)) {
printf("crossBlit failed (cursor)\n");
::abort();
}
// nasty, shouldn't the frontend set the alpha channel?
const u16 *s = (const u16 *) buf;
u16 *d = (u16 *) tmp;
for (u16 y = 0; y < h; ++y) {
for (u16 x = 0; x < w; ++x) {
if (*s++ == _mouseKeyColor)
*d++ &= ~(7 << 12);
else
d++;
}
d += tw - w;
}
} else {
#endif
const byte *s = (const byte *)buf;
byte *d = (byte *) tmp;
for (u16 y = 0; y < h; ++y) {
for (u16 x = 0; x < w; ++x) {
*d++ = *s++;
}
d += tw - w;
}
#ifdef USE_RGB_COLOR
}
#endif
gfx_tex_convert(&_texMouse, tmp);
free(tmp);
_mouseHotspotX = hotspotX;
_mouseHotspotY = hotspotY;
_cursorDontScale = dontScale;
if (_pfCursor.bytesPerPixel == 1 && oldKeycolor != _mouseKeyColor)
updateMousePalette();
}

View File

@@ -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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_EXCEPTION_printf
#include <malloc.h>
#include "osystem.h"
#define SFX_THREAD_STACKSIZE (1024 * 128)
#define SFX_THREAD_PRIO 80
#define SFX_THREAD_FRAG_SIZE (1024 * 8)
#define SFX_BUFFERS 3
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 u32 sb_hw;
static u8 *sound_buffer[SFX_BUFFERS];
static void audio_switch_buffers() {
sb_hw = (sb_hw + 1) % SFX_BUFFERS;
AUDIO_InitDMA((u32) sound_buffer[sb_hw], SFX_THREAD_FRAG_SIZE);
LWP_ThreadSignal(sfx_queue);
}
static void * sfx_thread_func(void *arg) {
Audio::MixerImpl *mixer = (Audio::MixerImpl *) arg;
u8 sb_sw;
while (true) {
LWP_ThreadSleep(sfx_queue);
if (sfx_thread_quit)
break;
// the hardware uses two buffers: a front and a back buffer
// we use 3 buffers here: two are being pushed to the DSP,
// and the free one is where our mixer writes to
// thus the latency of our stream is:
// 8192 [frag size] / 48000 / 2 [16bit] / 2 [stereo] * 2 [hw buffers]
// -> 85.3ms
sb_sw = (sb_hw + 1) % SFX_BUFFERS;
mixer->mixCallback(sound_buffer[sb_sw], SFX_THREAD_FRAG_SIZE);
DCFlushRange(sound_buffer[sb_sw], SFX_THREAD_FRAG_SIZE);
}
return NULL;
}
void OSystem_Wii::initSfx() {
_mixer = new Audio::MixerImpl(48000);
sfx_thread_running = false;
sfx_thread_quit = false;
sfx_stack = (u8 *) memalign(32, SFX_THREAD_STACKSIZE);
if (sfx_stack) {
memset(sfx_stack, 0, SFX_THREAD_STACKSIZE);
LWP_InitQueue(&sfx_queue);
s32 res = LWP_CreateThread(&sfx_thread, sfx_thread_func, _mixer, 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;
}
for (u32 i = 0; i < SFX_BUFFERS; ++i) {
sound_buffer[i] = (u8 *) memalign(32, SFX_THREAD_FRAG_SIZE);
memset(sound_buffer[i], 0, SFX_THREAD_FRAG_SIZE);
DCFlushRange(sound_buffer[i], SFX_THREAD_FRAG_SIZE);
}
_mixer->setReady(true);
sb_hw = 0;
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ);
AUDIO_RegisterDMACallback(audio_switch_buffers);
AUDIO_InitDMA((u32) sound_buffer[sb_hw], SFX_THREAD_FRAG_SIZE);
AUDIO_StartDMA();
}
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);
free(sfx_stack);
sfx_thread_running = false;
for (u32 i = 0; i < SFX_BUFFERS; ++i)
free(sound_buffer[i]);
}
}

View File

@@ -0,0 +1,59 @@
WII_EXE_STRIPPED := scummvm_stripped$(EXEEXT)
all: $(WII_EXE_STRIPPED)
$(WII_EXE_STRIPPED): $(EXECUTABLE)
$(STRIP) $< -o $@
clean: wiiclean
wiiclean:
$(RM) $(WII_EXE_STRIPPED)
wiiload: $(WII_EXE_STRIPPED)
$(DEVKITPPC)/bin/wiiload $<
geckoupload: $(WII_EXE_STRIPPED)
$(DEVKITPPC)/bin/geckoupload $<
wiigdb:
$(DEVKITPPC)/bin/powerpc-eabi-gdb -n $(EXECUTABLE)
wiidebug:
$(DEVKITPPC)/bin/powerpc-eabi-gdb -n $(EXECUTABLE) -x $(srcdir)/backends/platform/wii/gdb.txt
wiidebug_network:
$(DEVKITPPC)/bin/powerpc-eabi-gdb -n $(EXECUTABLE) -x $(srcdir)/backends/platform/wii/gdb-network.txt
# target to create a Wii snapshot
wiidist: all
$(MKDIR) wiidist/scummvm
ifeq ($(GAMECUBE),1)
$(DEVKITPPC)/bin/elf2dol $(EXECUTABLE) wiidist/scummvm/scummvm.dol
else
$(STRIP) $(EXECUTABLE) -o wiidist/scummvm/boot.elf
$(CP) $(srcdir)/dists/wii/icon.png wiidist/scummvm/
sed "s/@REVISION@/$(VER_REV)/;s/@TIMESTAMP@/`date +%Y%m%d%H%M%S`/" < $(srcdir)/dists/wii/meta.xml > wiidist/scummvm/meta.xml
endif
ifeq ($(DYNAMIC_MODULES),1)
$(MKDIR) wiidist/scummvm/plugins
for i in $(PLUGINS); do $(STRIP) --strip-debug $$i -o wiidist/scummvm/plugins/`basename $$i`; done
endif
sed 's/$$/\r/' < $(srcdir)/dists/wii/READMII > wiidist/scummvm/READMII.txt
for i in $(DIST_FILES_DOCS); do sed 's/$$/\r/' < $$i > wiidist/scummvm/`basename $$i`.txt; done
$(CP) $(DIST_FILES_THEMES) wiidist/scummvm/
ifneq ($(DIST_FILES_ENGINEDATA),)
$(CP) $(DIST_FILES_ENGINEDATA) wiidist/scummvm/
endif
ifneq ($(DIST_FILES_NETWORKING),)
$(CP) $(DIST_FILES_NETWORKING) wiidist/scummvm/
endif
ifneq ($(DIST_FILES_VKEYBD),)
$(CP) $(DIST_FILES_VKEYBD) wiidist/scummvm/
endif
wiiloaddist: wiidist
cd wiidist && zip -9r scummvm.zip scummvm/
$(DEVKITPPC)/bin/wiiload wiidist/scummvm.zip
.PHONY: wiiclean wiiload geckoupload wiigdb wiidebug wiidist wiiloaddist