/* 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 #include #ifndef GAMECUBE #include #endif #include #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) { if ((reset_btn_pressed || power_btn_pressed) && !_event_quit) { _event_quit = true; event.type = Common::EVENT_QUIT; printf("quit event\n"); return true; } 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; }