diff options
Diffstat (limited to 'backends/platform/wii/osystem_events.cpp')
-rw-r--r-- | backends/platform/wii/osystem_events.cpp | 262 |
1 files changed, 262 insertions, 0 deletions
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; +} + |