// // mouseWrapper.c // a2bejwld // // Created by Jeremy Rand on 2016-08-17. // Copyright © 2016 Jeremy Rand. All rights reserved. // #include #include #include #include #include "mouseWrapper.h" #include "game.h" #include "vbl.h" #include "drivers/a2_mouse_drv.h" // Globals static tMouseCallbacks *gMouseCallbacks = NULL; static bool gMouseInstalled = false; static bool gMouseInPoll = false; static struct mouse_callbacks gMouseDrvCallbacks; bool initMouse(tMouseCallbacks *callbacks) { if (!gMouseInstalled) { memcpy(&gMouseDrvCallbacks, &mouse_def_callbacks, sizeof(gMouseDrvCallbacks)); // This callback is here for the //c VBL which is only detectable // through the mouse interrupt. By registering this as our "draw" // function, we can ensure that we get called on our VBL interrupt // and can unblock our VBL wait function. gMouseDrvCallbacks.draw = vblIRQCallback; if (mouse_install(&gMouseDrvCallbacks, &a2_mouse_drv) == 0) { gMouseInstalled = true; } } gMouseCallbacks = callbacks; return gMouseInstalled; } void shutdownMouse(void) { if (gMouseInstalled) { mouse_uninstall(); gMouseInstalled = false; } } bool hasMouse(void) { return gMouseInstalled; } bool pollMouse(void) { static uint16_t mouseDownAtX = 0; static uint16_t mouseDownAtY = 0; static uint8_t oldX = 0; static uint8_t oldY = 0; static bool oldMouseDown = false; static bool handledMouseDown = false; struct mouse_info mouseInfo; bool newMouseDown; bool result = false; if (!gMouseInstalled) { return result; } gMouseInPoll = true; mouse_info(&mouseInfo); newMouseDown = (mouseInfo.buttons != 0); if ((oldMouseDown) && (!newMouseDown)) handledMouseDown = false; if ((!oldMouseDown) || (handledMouseDown)) { uint8_t newX; uint8_t newY; newX = mouseInfo.pos.x / 35; newY = mouseInfo.pos.y / 8; if (newX >= BOARD_SIZE) newX = BOARD_SIZE - 1; if (newY >= BOARD_SIZE) newY = BOARD_SIZE - 1; if ((oldX != newX) || (oldY != newY)) { result = gMouseCallbacks->mouseSelectSquare(XY_TO_SQUARE(newX, newY)); } oldX = newX; oldY = newY; } if ((!oldMouseDown) && (newMouseDown)) { mouseDownAtX = mouseInfo.pos.x; mouseDownAtY = mouseInfo.pos.y; } if ((newMouseDown) && (!handledMouseDown)) { if (mouseDownAtX + 35 < mouseInfo.pos.x) { result = gMouseCallbacks->mouseSwapSquare(DIR_RIGHT); handledMouseDown = true; } else if (mouseInfo.pos.x + 35 < mouseDownAtX) { result = gMouseCallbacks->mouseSwapSquare(DIR_LEFT); handledMouseDown = true; } else if (mouseDownAtY + 8 < mouseInfo.pos.y) { result = gMouseCallbacks->mouseSwapSquare(DIR_DOWN); handledMouseDown = true; } else if (mouseInfo.pos.y + 8 < mouseDownAtY) { result = gMouseCallbacks->mouseSwapSquare(DIR_UP); handledMouseDown = true; } } oldMouseDown = newMouseDown; gMouseInPoll = false; return result; } void moveMouseToSquare(tSquare square) { uint16_t newX; uint16_t newY; if (!gMouseInstalled) return; if (gMouseInPoll) return; newX = (SQUARE_TO_X(square) * 35) + 18; newY = (SQUARE_TO_Y(square) * 8) + 4; mouse_move(newX, newY); }