123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- /* MegaZeux
- *
- * Copyright (C) 2016 Adrian Siekierka <asiekierka@gmail.com>
- *
- * 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 "../../src/event.h"
- #include "../../src/graphics.h"
- #include "../../src/platform.h"
- #include "../../src/util.h"
- #include <3ds.h>
- #include "event.h"
- #include "keyboard.h"
- extern struct input_status input;
- static enum bottom_screen_mode b_mode;
- static enum focus_mode allow_focus_changes = FOCUS_ALLOW;
- static boolean is_dragging = false;
- boolean update_hid(void);
- enum focus_mode get_allow_focus_changes(void)
- {
- return allow_focus_changes;
- }
- enum bottom_screen_mode get_bottom_screen_mode(void)
- {
- return b_mode;
- }
- boolean __update_event_status(void)
- {
- boolean retval = false;
- retval |= aptMainLoop();
- retval |= update_hid();
- return retval;
- }
- void __wait_event(void)
- {
- while(!__update_event_status())
- gspWaitForVBlank();
- }
- // Convert the 3DS axis ranges to the MZX axis ranges. The 3DS uses values in
- // (roughly) the -150 to 150 range, but MZX uses the full range of a Sint16.
- // The 3DS Y axis is also inverted from the typical axis direction, but that
- // is fixed in check_circle below.
- static inline Sint16 axis_convert(s16 value)
- {
- int new_value = ((int)value) * 32768 / 150;
- return (Sint16)CLAMP(new_value, -32768, 32767);
- }
- static inline boolean check_circle(struct buffered_status *status,
- circlePosition *current, circlePosition *prev, Uint32 axis_x, Uint32 axis_y)
- {
- boolean rval = false;
- if(current->dx != prev->dx)
- {
- joystick_axis_update(status, 0, axis_x, axis_convert(current->dx));
- rval = true;
- }
- if(current->dy != prev->dy)
- {
- // 3DS has an inverted Y axis on the circle pad vs. most controllers.
- joystick_axis_update(status, 0, axis_y, axis_convert(-current->dy));
- rval = true;
- }
- return rval;
- }
- static inline boolean check_hat(struct buffered_status *status,
- Uint32 down, Uint32 up, Uint32 key, enum joystick_hat dir)
- {
- if(down & key)
- {
- joystick_hat_update(status, 0, dir, true);
- return true;
- }
- else
- if(up & key)
- {
- joystick_hat_update(status, 0, dir, false);
- return true;
- }
- return false;
- }
- static inline boolean check_joy(struct buffered_status *status,
- Uint32 down, Uint32 up, Uint32 key, Uint32 button)
- {
- if(down & key)
- {
- joystick_button_press(status, 0, button);
- return true;
- }
- else
- if(up & key)
- {
- joystick_button_release(status, 0, button);
- return true;
- }
- return false;
- }
- static inline boolean ctr_is_mouse_area(touchPosition *touch)
- {
- int mx, my;
- if(b_mode == BOTTOM_SCREEN_MODE_KEYBOARD)
- {
- mx = touch->px * 4 - 320;
- my = touch->py * 4 - (13 * 4);
- if(mx < 0 || mx >= 640 || my < 0 || my >= 350)
- return false;
- else
- return true;
- }
- else
- {
- return true;
- }
- }
- static inline boolean ctr_update_touch(struct buffered_status *status,
- touchPosition *touch)
- {
- int mx, my;
- if(b_mode == BOTTOM_SCREEN_MODE_KEYBOARD)
- {
- mx = touch->px * 4 - 320;
- my = touch->py * 4 - (13 * 4);
- if(mx < 0 || mx >= 640 || my < 0 || my >= 350)
- return false;
- }
- else
- {
- mx = touch->px * 2;
- my = touch->py * 2 - 64;
- if(mx < 0) mx = 0;
- if(mx >= 640) mx = 639;
- if(my < 0) my = 0;
- if(my >= 350) my = 349;
- }
- if((Uint32) mx != status->real_mouse_x || (Uint32) my != status->real_mouse_y)
- {
- status->real_mouse_x = mx;
- status->real_mouse_y = my;
- status->mouse_x = mx / 8;
- status->mouse_y = my / 14;
- status->mouse_moved = true;
- allow_focus_changes = FOCUS_PASS;
- focus_pixel(mx, my);
- allow_focus_changes = FOCUS_FORBID;
- return true;
- }
- else
- {
- return false;
- }
- }
- static inline boolean ctr_update_cstick(struct buffered_status *status)
- {
- circlePosition pos;
- int dmx, dmy, nmx, nmy;
- hidCstickRead(&pos);
- dmx = pos.dx / 3;
- dmy = pos.dy / 3;
- if(dmx != 0 || dmy != 0)
- {
- nmx = status->real_mouse_x + dmx;
- nmy = status->real_mouse_y + dmy;
- if(nmx < 0) nmx = 0;
- if(nmx >= 640) nmx = 639;
- if(nmy < 0) nmy = 0;
- if(nmy >= 350) nmy = 349;
- if((Uint32) nmx != status->real_mouse_x ||
- (Uint32) nmy != status->real_mouse_y)
- {
- status->real_mouse_x = nmx;
- status->real_mouse_y = nmy;
- status->mouse_x = nmx / 8;
- status->mouse_y = nmy / 14;
- status->mouse_moved = true;
- focus_pixel(nmx, nmy);
- return true;
- }
- }
- return false;
- }
- boolean update_hid(void)
- {
- struct buffered_status *status = store_status();
- Uint32 down, held, up;
- boolean retval = false;
- touchPosition touch;
- circlePosition cpad;
- static circlePosition last_cpad;
- hidScanInput();
- hidCircleRead(&cpad);
- down = hidKeysDown();
- held = hidKeysHeld();
- up = hidKeysUp();
- retval |= check_circle(status, &cpad, &last_cpad, 0, 1);
- retval |= check_hat(status, down, up, KEY_DUP, JOYHAT_UP);
- retval |= check_hat(status, down, up, KEY_DDOWN, JOYHAT_DOWN);
- retval |= check_hat(status, down, up, KEY_DLEFT, JOYHAT_LEFT);
- retval |= check_hat(status, down, up, KEY_DRIGHT, JOYHAT_RIGHT);
- retval |= check_joy(status, down, up, KEY_A, 0);
- retval |= check_joy(status, down, up, KEY_B, 1);
- retval |= check_joy(status, down, up, KEY_X, 2);
- retval |= check_joy(status, down, up, KEY_Y, 3);
- retval |= check_joy(status, down, up, KEY_L, 4);
- retval |= check_joy(status, down, up, KEY_SELECT, 6);
- retval |= check_joy(status, down, up, KEY_START, 7);
- retval |= check_joy(status, down, up, KEY_ZL, 8);
- retval |= check_joy(status, down, up, KEY_ZR, 9);
- last_cpad = cpad;
- if(down & KEY_R)
- {
- b_mode = (b_mode + 1) % BOTTOM_SCREEN_MODE_MAX;
- retval = true;
- }
- if((down | held | up) & KEY_TOUCH)
- {
- hidTouchRead(&touch);
- if((down & KEY_TOUCH) && ctr_is_mouse_area(&touch))
- {
- status->mouse_button = MOUSE_BUTTON_LEFT;
- status->mouse_repeat = MOUSE_BUTTON_LEFT;
- status->mouse_button_state |= MOUSE_BUTTON(MOUSE_BUTTON_LEFT);
- status->mouse_repeat_state = 1;
- status->mouse_drag_state = -1;
- status->mouse_time = get_ticks();
- is_dragging = true;
- allow_focus_changes = FOCUS_FORBID;
- retval = true;
- }
- if(is_dragging)
- {
- if(up & KEY_TOUCH)
- {
- status->mouse_button_state &= ~MOUSE_BUTTON(MOUSE_BUTTON_LEFT);
- status->mouse_repeat = 0;
- status->mouse_repeat_state = 0;
- status->mouse_drag_state = -0;
- allow_focus_changes = FOCUS_ALLOW;
- is_dragging = false;
- retval = true;
- }
- else
- {
- retval |= ctr_update_touch(status, &touch);
- }
- }
- retval |= ctr_keyboard_update(status);
- }
- // retval |= ctr_update_cstick(status);
- return retval;
- }
|