aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/wii/osystem_events.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/platform/wii/osystem_events.cpp')
-rw-r--r--backends/platform/wii/osystem_events.cpp262
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;
+}
+