Solitaire for the TI-84 Plus CE!
at calculation 146 lines 3.6 kB view raw
1// Calculation Solitaire / CALCSLTR for the TI-84 Plus CE 2// Copyright (C) 2025 euphory 3// 4// This program is free software: you can redistribute it and/or modify 5// it under the terms of the GNU General Public License as published by 6// the Free Software Foundation, either version 3 of the License, or 7// (at your option) any later version. 8// 9// This program is distributed in the hope that it will be useful, 10// but WITHOUT ANY WARRANTY; without even the implied warranty of 11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12// GNU General Public License for more details. 13// 14// You should have received a copy of the GNU General Public License 15// along with this program. If not, see <https://www.gnu.org/licenses/>. 16 17#include "ops.h" 18 19#include <stdlib.h> 20#include <fileioc.h> 21 22#include "variables.h" 23#include "save.h" 24#include "drawing.h" 25 26unsigned char cursorStack; 27unsigned char cursorIndex; 28enum cursorMode_t cursorMode; 29unsigned char selectedCard; 30unsigned char selectedQty; 31unsigned char orgStack; 32unsigned char orgIndex; 33 34void start() 35{ 36 loadWins(); 37 load(); // will call deal() as well if necessary 38 39 // set initial variables 40 cursorMode = SELECT; 41 cursorStack = NUM_FREECELLS; 42 maxCursorIndex(); 43 selectedCard = CARD_EMPTY; 44} 45 46bool canGrabCard() 47{ 48 if (cursorStack < NUM_FREECELLS) return false; 49 else if (tableau[cursorStack - NUM_FREECELLS][cursorIndex + 1] & CARD_EXISTS) return false; 50 else return tableau[cursorStack - NUM_FREECELLS][cursorIndex] & CARD_EXISTS; 51} 52 53bool canDropCard() 54{ 55 if (cursorStack < NUM_FREECELLS) 56 { 57 if ((freeCells[cursorStack] & CARD_NUMBER) == CARD_KING) return false; 58 else return (selectedCard & CARD_NUMBER) == (cursorStack + (freeCells[cursorStack] & CARD_NUMBER) + 1) % 13; 59 } 60 else if (orgStack != DECK_ORG) 61 { 62 return cursorStack == orgStack; 63 } 64 else if (cursorIndex == 0) 65 { 66 return true; 67 } 68 else 69 { 70 return !(tableau[cursorStack - NUM_FREECELLS][cursorIndex + 1] & CARD_EXISTS); 71 } 72} 73 74bool canClearCard() 75{ 76 if (orgStack == DECK_ORG) return false; 77 else return selectedCard & CARD_EXISTS; 78} 79 80void getNewCard() 81{ 82 while (true) 83 { 84 selectedCard = (rand() & CARD_SUIT) | (rand() % 13) | CARD_EXISTS; 85 if (!removeFromDeck(selectedCard)) break; 86 } 87 88 animateDraw(); 89} 90 91bool removeFromDeck(card_t toRemove) 92{ 93 unsigned char cardIndex = ((toRemove & CARD_SUIT) >> 4) * 13 + (toRemove & CARD_NUMBER); 94 unsigned char *deckByte = deck + (cardIndex / 8); 95 unsigned char pokeByte = 0x01 << (cardIndex % 8); 96 if (*deckByte & pokeByte) return true; 97 98 *deckByte |= pokeByte; 99 deckCards--; 100 return false; 101} 102 103void grabCard() 104{ 105 orgStack = cursorStack; 106 orgIndex = cursorIndex; 107 108 selectedCard = tableau[cursorStack - NUM_FREECELLS][cursorIndex]; 109 tableau[cursorStack - NUM_FREECELLS][cursorIndex] = CARD_EMPTY; 110 111 animateGrab(); 112} 113 114void dropCard() 115{ 116 animateDrop(); 117 118 unsigned char const prevProgress = progress; 119 120 if (cursorStack < NUM_FREECELLS) 121 { 122 freeCells[cursorStack] = selectedCard; 123 if ((selectedCard & CARD_NUMBER) == CARD_KING) progress++; 124 } 125 else 126 { 127 tableau[cursorStack - NUM_FREECELLS][cursorIndex] = selectedCard; 128 } 129 130 if (progress == PROGRESS_COMPLETE && prevProgress < PROGRESS_COMPLETE) (*numWins)++; 131} 132 133void clearCard() 134{ 135 animateClear(); 136 tableau[orgStack - NUM_FREECELLS][orgIndex] = selectedCard; 137 selectedCard = CARD_EMPTY; 138} 139 140void maxCursorIndex() 141{ 142 if (cursorStack < NUM_FREECELLS) return; 143 144 cursorIndex = 0; 145 while (tableau[cursorStack - NUM_FREECELLS][cursorIndex + 1] & CARD_EXISTS) cursorIndex++; 146}