// Kabufuda Solitaire / KBFDSLTR for the TI-84 Plus CE // Copyright (C) 2024 euphory // // 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 3 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, see . #include "input.h" #include #include #include "variables.h" #include "ops.h" #include "save.h" unsigned char down, left, right, up; bool doInput() { const bool prevSecond = kb_IsDown(kb_Key2nd); const bool prevEnter = kb_IsDown(kb_KeyEnter); const bool prevAlpha = kb_IsDown(kb_KeyAlpha); const bool prevClear = kb_IsDown(kb_KeyClear); kb_Scan(); up = kb_IsDown(kb_KeyUp) ? up + 1 : 0; down = kb_IsDown(kb_KeyDown) ? down + 1 : 0; left = kb_IsDown(kb_KeyLeft) ? left + 1 : 0; right = kb_IsDown(kb_KeyRight) ? right + 1 : 0; const bool select = (kb_IsDown(kb_Key2nd) && !prevSecond) || (kb_IsDown(kb_KeyEnter) && !prevEnter); const bool clear = (kb_IsDown(kb_KeyClear) && !prevClear) || (kb_IsDown(kb_KeyAlpha) && !prevAlpha); if (select) { if (cursorMode == SELECT && canGrabCard()) { orgStack = cursorStack; orgIndex = cursorIndex; cursorMode = DROP; } else if (canDropCard()) { dropCard(); cursorMode = SELECT; } else if (cursorStack == orgStack) { cursorMode = SELECT; } } else if (clear) cursorMode = SELECT; unsigned char prevCursorStack = cursorStack; if (down == 1 || down > HOLD_TIME) { cursorIndex++; } else if (left == 1 || left > HOLD_TIME) { do { if (cursorStack == 0) cursorStack = NUM_FREECELLS + NUM_TABLSLOTS - 1; // wrap else cursorStack--; } while (cursorOnCollapsed() || cursorOnLocked()); // skip useless stacks } else if (right == 1 || right > HOLD_TIME) { do { if (cursorStack > NUM_FREECELLS + NUM_TABLSLOTS - 2) cursorStack = 0; // wrap else cursorStack++; } while (cursorOnCollapsed() || cursorOnLocked()); // skip useless stacks } else if (up == 1 || up > HOLD_TIME) { if (cursorIndex > 0) cursorIndex--; } if (cursorStack < NUM_FREECELLS) { cursorIndex = 0; } else if (cursorMode == DROP) { // if dropping cards, the cursor should always be at the top of the stack it's on // except maxCursorIndex() doesn't work so well on empty tableau stacks if (cursorStack != orgStack) { if (tableau[cursorStack - NUM_FREECELLS][0] == 11) { cursorIndex = 0; } else { maxCursorIndex(); cursorIndex++; } } else cursorIndex = orgIndex; // also this makes it more clear if we are trying to drop // back on the original cards } else if (cursorStack != prevCursorStack) { maxCursorIndex(); } else { while (tableau[cursorStack - NUM_FREECELLS][cursorIndex] == 11 && cursorIndex > 0) cursorIndex--; } if (cursorMode == SELECT) { selectedQty = 1; if (cursorStack < NUM_FREECELLS) selectedCard = freeCells[cursorStack]; else { selectedCard = tableau[cursorStack - NUM_FREECELLS][cursorIndex]; for (int i = cursorIndex + 1; tableau[cursorStack - NUM_FREECELLS][i] == selectedCard; i++) selectedQty++; } if (selectedCard > 11) { selectedCard -= 12; selectedQty = 4; } } if (kb_IsDown(kb_KeyDel)) { deleteSave(); start(); } return !kb_On && progress < 10; }