···2233This is a card solitaire game for the TI-84 Plus CE and TI-83 Premium CE.
4455-## How to Play
66-77-This is calculation. There are four foundation piles, each of which start with one card at the beginning of the game: the first pile starts with an ace, the second with a two, and so on. Each foundation is built on in multiples of the initial card (i.e. its position). So the first pile is built A, 2, 3, 4...; the second 2, 4, 6, 8...; the third 3, 6, 9, Q...; and the fourth 4, 8, Q, 3.... The card after K is A, though once a foundation has a king played to it, that is its thirteenth card and it is now complete, and no more cards may be played to it.
88-99-Additionally, there are four tableau piles beneath the foundation piles. A card can always be placed on the top of a tableau pile, but it can only be removed from the pile by playing it to a foundation. Therefore, the clever placement of cards in the tableau is key to victory.
1010-1111-Cards may be drawn one at a time from the deck by pressing `alpha` or picked up from the selected tableau pile with `2nd`. The card held in the player's hand may be played to the selected pile with `2nd` or returned to its origin pile in the tableau with `clear`. When interacting with tableau and foundation piles, the selected pile is marked with the cursor, which can be moved with the arrow keys. Moving the cursor all the way to the left or right causes it to wrap around from the tableau to the foundations or vice versa.
1212-1313-Once all four foundations are completed, the game is over. The game can be reset at any point by pressing `del`.
1414-155## Roadmap
1661717-As more and more of the core game logic is made generic, the goal is to spin out the rules of the game to an interpreted script, and then allow the play of multiple solitaire games with one program and set of graphical assets.
77+This branch is still heavily under development! Check back later for more information.
188199## Dependencies
2010
···11-// Calculation Solitaire / CALCSLTR for the TI-84 Plus CE
22-// Copyright (C) 2025 euphory
33-//
44-// This program is free software: you can redistribute it and/or modify
55-// it under the terms of the GNU General Public License as published by
66-// the Free Software Foundation, either version 3 of the License, or
77-// (at your option) any later version.
88-//
99-// This program is distributed in the hope that it will be useful,
1010-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1111-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212-// GNU General Public License for more details.
1313-//
1414-// You should have received a copy of the GNU General Public License
1515-// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616-1717-#include "drawing.h"
1818-1919-#include <graphx.h>
2020-#include <time.h>
2121-#include "gfx/gfx.h"
2222-#include "variables.h"
2323-#include "ops.h"
2424-2525-// these are used for placing pips on cards
2626-const unsigned char segments[] = {
2727- 0x01, 0x24, 0x25, 0x48, 0x49, 0x4a, 0xa8, 0x90, 0x91, 0xb4
2828-};
2929-const unsigned char pipCode[] = {
3030- 0x04, 07, 02, 15, 02, 07, 12, 15, 12,
3131- 0x02, 07, 07, 15, 07,
3232- 0x01, 11, 07,
3333- 0x84, 12, 29, 20, 29, 12, 39, 20, 39,
3434- 0x82, 12, 34, 20, 34,
3535- 0x81, 16, 34,
3636- 0x02, 07, 17, 15, 17,
3737- 0x01, 11, 17
3838-};
3939-4040-void drawMask(const unsigned char *data, unsigned char rows, unsigned int x, unsigned char y)
4141-{
4242- unsigned char yy = y;
4343-4444- for (unsigned char row = 0; row < rows; row++)
4545- {
4646- unsigned char row_data = data[row];
4747-4848- for (unsigned int xx = x; xx < x + 8; xx++)
4949- {
5050- if (row_data & 0x80)
5151- {
5252- gfx_SetPixel(xx, yy);
5353- }
5454-5555- row_data <<= 1;
5656- }
5757-5858- yy++;
5959- }
6060-}
6161-6262-void drawMaskInverted(const unsigned char *data, unsigned char rows, unsigned int x, unsigned char y)
6363-{
6464- unsigned char yy = y - rows;
6565-6666- for (unsigned char row = 1; row <= rows; row++)
6767- {
6868- unsigned char row_data = data[rows - row];
6969-7070- for (unsigned int xx = x - 8; xx < x; xx++)
7171- {
7272- if (row_data & 0x01)
7373- {
7474- gfx_SetPixel(xx, yy);
7575- }
7676-7777- row_data >>= 1;
7878- }
7979-8080- yy++;
8181- }
8282-}
8383-8484-unsigned int getCursorX()
8585-{
8686- if (cursorStack < NUM_FREECELLS) return FC_HPOS + cursorStack * (CARD_WIDTH + CARD_SPACING);
8787- else return TABL_HPOS + (cursorStack - NUM_FREECELLS) * (CARD_WIDTH + CARD_SPACING);
8888-}
8989-9090-unsigned char getCursorY()
9191-{
9292- if (cursorStack < NUM_FREECELLS) return FC_VPOS;
9393- else return TABL_VPOS + cursorIndex * CARD_VOFFSET;
9494-}
9595-9696-void drawCursor()
9797-{
9898- const unsigned int X = getCursorX();
9999- const unsigned char Y = getCursorY();
100100-101101- gfx_SetColor(cursorMode == SELECT ? BLACK_COLOR : RED_COLOR);
102102-103103- drawMask(selcorner_tile_0_data, 6, X - 2, Y - 2);
104104- drawMask(selcorner_tile_1_data, 6, X + CARD_WIDTH - 4, Y - 2);
105105- drawMaskInverted(selcorner_tile_1_data, 6, X + 4, Y + CARD_HEIGHT + 2);
106106- drawMaskInverted(selcorner_tile_0_data, 6, X + CARD_WIDTH + 2, Y + CARD_HEIGHT + 2);
107107-}
108108-109109-#include <debug.h>
110110-111111-void drawCardBlank(unsigned int x, unsigned char y)
112112-{
113113- gfx_SetColor(CARD_COLOR);
114114- gfx_HorizLine(x + 1, y, CARD_WIDTH - 2);
115115- gfx_HorizLine(x + 1, y + CARD_HEIGHT - 1, CARD_WIDTH - 2);
116116- gfx_FillRectangle(x, y + 1, CARD_WIDTH, CARD_HEIGHT - 2);
117117-118118- gfx_SetColor(BLACK_COLOR);
119119- gfx_SetPixel(x, y + CARD_HEIGHT - 1);
120120- gfx_SetPixel(x + CARD_WIDTH - 1, y + CARD_HEIGHT - 1);
121121- gfx_HorizLine(x + 1, y + CARD_HEIGHT, CARD_WIDTH - 2);
122122-}
123123-124124-void drawCard(card_t toDraw, unsigned int x, unsigned char y, bool useCutoff)
125125-{
126126- if (!(toDraw & CARD_EXISTS)) return;
127127-128128- const unsigned char cardNumber = toDraw & CARD_NUMBER;
129129- const unsigned char cardSuit = (toDraw & CARD_SUIT) >> 4;
130130-131131- drawCardBlank(x, y);
132132-133133- if (cardNumber >= 10)
134134- {
135135- // this is a face card
136136- const unsigned char tileIndex = cardSuit * 3 + cardNumber - 10;
137137- const gfx_sprite_t *faceSprite = faces_tiles[tileIndex];
138138-139139- gfx_TempSprite(bottomSprite, CARD_FACE_WIDTH, CARD_FACE_HEIGHT);
140140- gfx_RotateSpriteHalf(faceSprite, bottomSprite);
141141-142142- gfx_Sprite(faceSprite, x + CARD_FACE_HOFFSET, y + CARD_FACE_VOFFSET);
143143- gfx_Sprite(bottomSprite, x + CARD_FACE_HOFFSET, y + CARD_HEIGHT / 2);
144144-145145- gfx_SetColor(BLACK_COLOR);
146146- gfx_VertLine(x + 3, y + 12, 26);
147147- gfx_VertLine(x + 23, y + 3, 26);
148148- gfx_HorizLine(x + 6, y + 3, 17);
149149- gfx_HorizLine(x + 4, y + 37, 17);
150150-151151- if (toDraw & CARD_RED) gfx_SetColor(RED_COLOR);
152152- }
153153- else
154154- {
155155- // this is a number card (A-10) and should have pips
156156- dbg_printf("drawing pips for card with value %u at (%u, %u)...\n", cardNumber, x, y);
157157- gfx_SetColor((toDraw & CARD_RED) ? RED_COLOR : BLACK_COLOR);
158158- const unsigned char *pipMask = medium_suits_tiles_data[cardSuit];
159159- dbg_printf("located pip mask at %p...\n", pipMask);
160160- const unsigned char *codePtr = pipCode;
161161- for (unsigned char pipMap = segments[cardNumber]; pipMap != 0x00; pipMap <<= 1)
162162- {
163163- dbg_printf("current pip map is %x...\n", pipMap);
164164- unsigned char counter = *codePtr & 0x0f;
165165- if (pipMap & 0x80)
166166- {
167167- dbg_printf("executing instruction at %p...\n", codePtr);
168168- const bool isNegative = *codePtr & 0x80;
169169- if (isNegative) dbg_printf("pip is inverted...\n");
170170- codePtr++;
171171-172172- while (counter-- > 0)
173173- {
174174- if (isNegative) drawMaskInverted(pipMask, 6, x + codePtr[0], y + codePtr[1]);
175175- else drawMask(pipMask, 6, x + codePtr[0], y + codePtr[1]);
176176-177177- codePtr += 2;
178178- }
179179- }
180180- else
181181- {
182182- codePtr += counter * 2 + 1;
183183- }
184184- }
185185- }
186186-187187- // no matter what, we need numerals and suit icons
188188- drawMask(numerals_tiles_data[cardNumber], 5, x + CARD_NUMERAL_HOFFSET, y + CARD_NUMERAL_VOFFSET);
189189- drawMask(small_suits_tiles_data[cardSuit], 4, x + CARD_FSUIT_HOFFSET, y + CARD_FSUIT_VOFFSET);
190190-191191- if (!useCutoff)
192192- {
193193- drawMaskInverted(numerals_tiles_data[cardNumber], 5, x + CARD_WIDTH - CARD_NUMERAL_HOFFSET, y + CARD_HEIGHT - CARD_NUMERAL_VOFFSET);
194194- drawMaskInverted(small_suits_tiles_data[cardSuit], 4, x + CARD_WIDTH - CARD_FSUIT_HOFFSET, y + CARD_HEIGHT - CARD_FSUIT_VOFFSET);
195195- }
196196-}
197197-198198-void drawCardBack(unsigned int x, unsigned char y)
199199-{
200200- drawCardBlank(x, y);
201201-202202- gfx_SetColor(BLACK_COLOR);
203203- for (unsigned char i = 0; i < 3; i++)
204204- {
205205- drawMask(card_back_tiles_data[i], 20, x + 8 * i + 1, y + 1);
206206- drawMaskInverted(card_back_tiles_data[i], 20, x - 8 * i + 26, y + 40);
207207- }
208208-209209- gfx_VertLine(x + 1, y + 21, 19);
210210- gfx_VertLine(x + 25, y + 1, 19);
211211-}
212212-213213-void drawDeck()
214214-{
215215- if (deckCards == 0) return;
216216- unsigned char y = DECK_VPOS;
217217- for (unsigned char x = 0; x <= deckCards; x += DECK_CARDS_PER_HEIGHT)
218218- {
219219- drawCardBack(DECK_HPOS, y);
220220- y -= 2;
221221- }
222222-}
223223-224224-void drawStack(unsigned char stackIndex)
225225-{
226226- for (unsigned char j = 0; j < TABL_STACK_SIZE; j++)
227227- {
228228- unsigned char cardX = TABL_HPOS + stackIndex * (CARD_WIDTH + CARD_SPACING);
229229- unsigned char cardY = TABL_VPOS + j * CARD_VOFFSET;
230230-231231- drawCard(tableau[stackIndex][j], cardX, cardY, tableau[stackIndex][j + 1] & CARD_EXISTS);
232232- }
233233-}
234234-235235-void drawBar()
236236-{
237237- gfx_SetColor(BORDER_COLOR);
238238- gfx_FillRectangle(0, 0, GFX_LCD_WIDTH, TOP_BORDER);
239239-240240- gfx_SetTextFGColor(BLACK_COLOR);
241241-242242- if (progress < PROGRESS_COMPLETE)
243243- {
244244- if (cursorMode == SELECT) gfx_PrintStringXY("SELECT", GFX_LCD_WIDTH / 2 - 3 * TEXT_CHAR_WIDTH, SELCARD_DISP_Y);
245245- else gfx_PrintStringXY("DROP", GFX_LCD_WIDTH / 2 - 2 * TEXT_CHAR_WIDTH, SELCARD_DISP_Y);
246246- }
247247-248248- else gfx_PrintStringXY("COMPLETE", GFX_LCD_WIDTH / 2 - 4 * TEXT_CHAR_WIDTH, SELCARD_DISP_Y);
249249-250250- gfx_SetTextXY(NUMWINS_DISP_X, SELCARD_DISP_Y);
251251- gfx_PrintUInt(*numWins, 3);
252252-}
253253-254254-void drawFrame(bool drawSelected)
255255-{
256256- gfx_FillScreen(BKGND_COLOR);
257257-258258- for (unsigned char i = 0; i < NUM_FREECELLS; i++) drawCard(freeCells[i], FC_HPOS + i * (CARD_WIDTH + CARD_SPACING), FC_VPOS, false);
259259- for (unsigned char i = 0; i < NUM_TABLSLOTS; i++) drawStack(i);
260260- if (drawSelected && (selectedCard & CARD_EXISTS) && cursorMode == DROP) drawCard(selectedCard, SELCARD_XPOS, SELCARD_YPOS, false);
261261-262262- drawDeck();
263263- drawBar();
264264- drawCursor();
265265-266266- gfx_BlitBuffer();
267267-}
268268-269269-void animateMoveInternal(bool flipX, bool flipY, unsigned int x0, unsigned char y0, unsigned int x1, unsigned char y1, bool faceDown)
270270-{
271271- gfx_TempSprite(spriteBuffer, CARD_WIDTH, CARD_HEIGHT + 1);
272272-273273- const unsigned int Dx = x1 - x0;
274274- const unsigned char Dy = y1 - y0;
275275- const clock_t duration = MOVE_ANIM_LENGTH * (Dy + Dx);
276276-277277- const clock_t startTime = clock();
278278-279279- while (true)
280280- {
281281- const clock_t nowTime = clock();
282282- const clock_t elapsed = nowTime - startTime;
283283-284284- const bool lastIteration = nowTime - startTime > duration;
285285-286286- const unsigned int dx = lastIteration ? Dx : Dx * elapsed / duration;
287287- const unsigned char dy = lastIteration ? Dy : Dy * elapsed / duration;
288288-289289- const unsigned int cardX = flipX ? x1 - dx : x0 + dx;
290290- const unsigned char cardY = flipY ? y1 - dy : y0 + dy;
291291-292292- gfx_GetSprite(spriteBuffer, cardX, cardY);
293293- if (faceDown)
294294- {
295295- drawCardBack(cardX, cardY);
296296- }
297297- else
298298- {
299299- drawCard(selectedCard, cardX, cardY, false);
300300- }
301301- gfx_BlitBuffer();
302302- gfx_Sprite(spriteBuffer, cardX, cardY);
303303-304304- if (lastIteration) break;
305305- }
306306-}
307307-308308-void animateMove(unsigned int x0, unsigned char y0, unsigned int x1, unsigned char y1, bool faceDown)
309309-{
310310- const bool flipX = x0 > x1;
311311- const bool flipY = y0 > y1;
312312-313313- if (flipX)
314314- {
315315- x0 ^= x1;
316316- x1 ^= x0;
317317- x0 ^= x1;
318318- }
319319- if (flipY)
320320- {
321321- y0 ^= y1;
322322- y1 ^= y0;
323323- y0 ^= y1;
324324- }
325325-326326- drawFrame(false);
327327- animateMoveInternal(flipX, flipY, x0, y0, x1, y1, faceDown);
328328-}
329329-330330-void animateDeal()
331331-{
332332- gfx_FillScreen(BKGND_COLOR);
333333- drawDeck();
334334- drawBar();
335335- gfx_BlitBuffer();
336336-337337- for (unsigned char i = NUM_FREECELLS - 1; i < NUM_FREECELLS; i--)
338338- {
339339- selectedCard = freeCells[i];
340340-341341- const unsigned int targetX = FC_HPOS + i * (CARD_WIDTH + CARD_SPACING);
342342-343343- animateMoveInternal(false, false, DECK_HPOS, DECK_VPOS, targetX, FC_VPOS, false);
344344- drawCard(selectedCard, targetX, FC_VPOS, false);
345345- }
346346-347347- selectedCard = CARD_EMPTY;
348348- drawFrame(false);
349349-}
11+#include "drawing.h"
22+#include "gfx/gfx.h"
33+#include "card.h"
44+#include <graphx.h>
55+66+#define CARD_WIDTH 27
77+#define CARD_HEIGHT 41
88+#define CARD_NUMERAL_HOFFSET 1
99+#define CARD_NUMERAL_VOFFSET 1
1010+#define CARD_FSUIT_HOFFSET 1
1111+#define CARD_FSUIT_VOFFSET 7
1212+#define CARD_FACE_HOFFSET 4
1313+#define CARD_FACE_VOFFSET 4
1414+#define CARD_FACE_WIDTH 19
1515+#define CARD_FACE_HEIGHT 17
1616+1717+#define CARD_COLOR 0
1818+#define BLACK_COLOR 1
1919+#define RED_COLOR 2
2020+2121+// these are used for placing pips on cards
2222+const uint8_t segments[] = {
2323+ 0x01, 0x24, 0x25, 0x48, 0x49, 0x4a, 0xa8, 0x90, 0x91, 0xb4
2424+};
2525+const uint8_t pip_code[] = {
2626+ 0x04, 07, 02, 15, 02, 07, 12, 15, 12,
2727+ 0x02, 07, 07, 15, 07,
2828+ 0x01, 11, 07,
2929+ 0x84, 12, 29, 20, 29, 12, 39, 20, 39,
3030+ 0x82, 12, 34, 20, 34,
3131+ 0x81, 16, 34,
3232+ 0x02, 07, 17, 15, 17,
3333+ 0x01, 11, 17
3434+};
3535+3636+void draw_mask(const uint8_t *data, uint8_t rows, uint24_t x, uint8_t y)
3737+{
3838+ uint8_t yy = y;
3939+4040+ for (uint8_t row = 0; row < rows; row++)
4141+ {
4242+ uint8_t row_data = data[row];
4343+4444+ for (uint24_t xx = x; xx < x + 8; xx++)
4545+ {
4646+ if (row_data & 0x80)
4747+ {
4848+ gfx_SetPixel(xx, yy);
4949+ }
5050+5151+ row_data <<= 1;
5252+ }
5353+5454+ yy++;
5555+ }
5656+}
5757+5858+void draw_mask_inverted(const uint8_t *data, uint8_t rows, uint24_t x, uint8_t y)
5959+{
6060+ uint8_t yy = y - rows;
6161+6262+ for (uint8_t row = 1; row <= rows; row++)
6363+ {
6464+ uint8_t row_data = data[rows - row];
6565+6666+ for (uint24_t xx = x - 8; xx < x; xx++)
6767+ {
6868+ if (row_data & 0x01)
6969+ {
7070+ gfx_SetPixel(xx, yy);
7171+ }
7272+7373+ row_data >>= 1;
7474+ }
7575+7676+ yy++;
7777+ }
7878+}
7979+8080+void draw_card_blank(uint24_t x, uint8_t y)
8181+{
8282+ gfx_SetColor(CARD_COLOR);
8383+ gfx_HorizLine(x + 1, y, CARD_WIDTH - 2);
8484+ gfx_HorizLine(x + 1, y + CARD_HEIGHT - 1, CARD_WIDTH - 2);
8585+ gfx_FillRectangle(x, y + 1, CARD_WIDTH, CARD_HEIGHT - 2);
8686+8787+ gfx_SetColor(BLACK_COLOR);
8888+ gfx_SetPixel(x, y + CARD_HEIGHT - 1);
8989+ gfx_SetPixel(x + CARD_WIDTH - 1, y + CARD_HEIGHT - 1);
9090+ gfx_HorizLine(x + 1, y + CARD_HEIGHT, CARD_WIDTH - 2);
9191+}
9292+9393+void draw_card(uint24_t x, uint8_t y, card_t card)
9494+{
9595+ if (!EXISTS(card)) return;
9696+9797+ const uint8_t card_num = NUMBER(card);
9898+ const uint24_t card_suit = SUIT(card);
9999+100100+ draw_card_blank(x, y);
101101+102102+ if (card_num >= 10)
103103+ {
104104+ // this is a face card
105105+ const uint8_t tile_index = card_suit * 3 + card_num - 10;
106106+ const gfx_sprite_t *face_sprite = faces_tiles[tile_index];
107107+108108+ gfx_TempSprite(bottom_sprite, CARD_FACE_WIDTH, CARD_FACE_HEIGHT);
109109+ gfx_RotateSpriteHalf(face_sprite, bottom_sprite);
110110+111111+ gfx_Sprite(face_sprite, x + CARD_FACE_HOFFSET, y + CARD_FACE_VOFFSET);
112112+ gfx_Sprite(bottom_sprite, x + CARD_FACE_HOFFSET, y + CARD_HEIGHT / 2);
113113+114114+ gfx_SetColor(BLACK_COLOR);
115115+ gfx_VertLine(x + 3, y + 12, 26);
116116+ gfx_VertLine(x + 23, y + 3, 26);
117117+ gfx_HorizLine(x + 6, y + 3, 17);
118118+ gfx_HorizLine(x + 4, y + 37, 17);
119119+120120+ if (IS_RED(card)) gfx_SetColor(RED_COLOR);
121121+ }
122122+ else
123123+ {
124124+ // this is a number card (A-10) and should have pips
125125+ gfx_SetColor(IS_RED(card) ? RED_COLOR : BLACK_COLOR);
126126+ const uint8_t *pip_mask = medium_suits_tiles_data[card_suit];
127127+ const uint8_t *code_ptr = pip_code;
128128+ for (uint8_t pip_map = segments[card_num]; pip_map != 0x00; pip_map <<= 1)
129129+ {
130130+ uint8_t counter = *code_ptr & 0x0f;
131131+ if (pip_map & 0x80)
132132+ {
133133+ const uint8_t is_negative = *code_ptr & 0x80;
134134+ code_ptr++;
135135+136136+ while (counter-- > 0)
137137+ {
138138+ if (is_negative) draw_mask_inverted(pip_mask, 6, x + code_ptr[0], y + code_ptr[1]);
139139+ else draw_mask(pip_mask, 6, x + code_ptr[0], y + code_ptr[1]);
140140+141141+ code_ptr += 2;
142142+ }
143143+ }
144144+ else
145145+ {
146146+ code_ptr += counter * 2 + 1;
147147+ }
148148+ }
149149+ }
150150+151151+ draw_mask(numerals_tiles_data[card_num], 5, x + CARD_NUMERAL_HOFFSET, y + CARD_NUMERAL_VOFFSET);
152152+ draw_mask(small_suits_tiles_data[card_suit], 4, x + CARD_FSUIT_HOFFSET, y + CARD_FSUIT_VOFFSET);
153153+ draw_mask_inverted(numerals_tiles_data[card_num], 5, x + CARD_WIDTH - CARD_NUMERAL_HOFFSET, y + CARD_HEIGHT - CARD_NUMERAL_VOFFSET);
154154+ draw_mask_inverted(small_suits_tiles_data[card_suit], 4, x + CARD_WIDTH - CARD_FSUIT_HOFFSET, y + CARD_HEIGHT - CARD_FSUIT_VOFFSET);
155155+}
156156+157157+void draw_stack(stack_t *stack)
158158+{
159159+ uint24_t x = stack->x;
160160+ uint8_t y = stack->y;
161161+162162+ for (uint8_t i = 0; i < stack->max_cards; i++)
163163+ {
164164+ if (!EXISTS(stack->cards[i])) return;
165165+166166+ draw_card(x, y, stack->cards[i]);
167167+168168+ x += stack->dx;
169169+ y += stack->dy;
170170+ }
171171+}
172172+173173+void draw_stacks()
174174+{
175175+ for (uint8_t i = 0; i < num_stacks; i++)
176176+ {
177177+ draw_stack(&stacks[i]);
178178+ }
179179+}
+10-86
src/drawing.h
···11-// Calculation Solitaire / CALCSLTR for the TI-84 Plus CE
22-// Copyright (C) 2025 euphory
33-//
44-// This program is free software: you can redistribute it and/or modify
55-// it under the terms of the GNU General Public License as published by
66-// the Free Software Foundation, either version 3 of the License, or
77-// (at your option) any later version.
88-//
99-// This program is distributed in the hope that it will be useful,
1010-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1111-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212-// GNU General Public License for more details.
1313-//
1414-// You should have received a copy of the GNU General Public License
1515-// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616-1717-#ifndef drawing_include_file
1818-#define drawing_include_file
1919-2020-#include <graphx.h>
2121-#include <gfx/gfx.h>
2222-#include "variables.h"
2323-2424-#define CARD_HEIGHT 41
2525-#define CARD_WIDTH 27
2626-#define CARD_SPACING 5
2727-#define CARD_VOFFSET 7
2828-2929-#define CARD_NUMERAL_HOFFSET 1
3030-#define CARD_NUMERAL_VOFFSET 1
3131-#define CARD_FACE_HOFFSET 4
3232-#define CARD_FACE_VOFFSET 4
3333-#define CARD_FACE_WIDTH 19
3434-#define CARD_FACE_HEIGHT 17
3535-#define CARD_FSUIT_HOFFSET 1
3636-#define CARD_FSUIT_VOFFSET 7
3737-#define LOCK_ICON_VOFFSET 17
3838-#define LOCK_ICON_HOFFSET 9
3939-#define FC_VPOS 50
4040-#define TABL_VPOS 100
4141-#define FC_HPOS 98
4242-#define TABL_HPOS 98
4343-4444-#define TEXT_CHAR_WIDTH 8
4545-#define SELCARD_DISP_X 5
4646-#define SELCARD_DISP_Y 9
4747-#define NUMWINS_DISP_X (GFX_LCD_WIDTH - 5 - 3 * TEXT_CHAR_WIDTH)
4848-4949-#define BKGND_COLOR 3
5050-#define BORDER_COLOR 0
5151-#define CARD_COLOR 0
5252-#define BLACK_COLOR 1
5353-#define RED_COLOR 2
5454-5555-#define TOP_BORDER 25
5656-5757-#define DECK_VPOS FC_VPOS
5858-#define DECK_HPOS (FC_HPOS - CARD_WIDTH - CARD_SPACING)
5959-#define DECK_CARDS_PER_HEIGHT 9
6060-6161-#define SELCARD_XPOS 147
6262-#define SELCARD_YPOS 210
6363-6464-#define MOVE_ANIM_LENGTH 40
6565-6666-extern gfx_sprite_t* cardSprite[11];
6767-6868-unsigned int getCursorX();
6969-unsigned char getCursorY();
7070-void drawCursor();
7171-void drawCard(card_t toDraw, unsigned int x, unsigned char y, bool useCutoff);
7272-void drawStack(unsigned char stackIndex);
7373-void drawBar();
7474-void drawFrame(bool drawSelected);
7575-void animateMove(unsigned int x0, unsigned char y0, unsigned int x1, unsigned char y1, bool faceDown);
7676-void animateDeal();
7777-7878-#define getOrgX() (TABL_HPOS + (orgStack - NUM_FREECELLS) * (CARD_WIDTH + CARD_SPACING))
7979-#define getOrgY() (TABL_VPOS + orgIndex * CARD_VOFFSET)
8080-8181-#define animateGrab() animateMove(getCursorX(), getCursorY(), SELCARD_XPOS, SELCARD_YPOS, false)
8282-#define animateDrop() animateMove(SELCARD_XPOS, SELCARD_YPOS, getCursorX(), getCursorY(), false)
8383-#define animateDraw() animateMove(DECK_HPOS, DECK_VPOS, SELCARD_XPOS, SELCARD_YPOS, true)
8484-#define animateClear() animateMove(SELCARD_XPOS, SELCARD_YPOS, getOrgX(), getOrgY(), false)
8585-8686-#endif
11+#ifndef DRAWING_H
22+#define DRAWING_H
33+44+#include "card.h"
55+66+void draw_card(uint24_t x, uint8_t y, card_t card);
77+void draw_stack(stack_t *stack);
88+void draw_stacks();
99+1010+#endif
···11-// Calculation Solitaire / CALCSLTR for the TI-84 Plus CE
22-// Copyright (C) 2025 euphory
33-//
44-// This program is free software: you can redistribute it and/or modify
55-// it under the terms of the GNU General Public License as published by
66-// the Free Software Foundation, either version 3 of the License, or
77-// (at your option) any later version.
88-//
99-// This program is distributed in the hope that it will be useful,
1010-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1111-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212-// GNU General Public License for more details.
1313-//
1414-// You should have received a copy of the GNU General Public License
1515-// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616-1717-#include "input.h"
1818-1919-#include <stdlib.h>
2020-#include <keypadc.h>
2121-#include "variables.h"
2222-#include "ops.h"
2323-#include "save.h"
2424-2525-unsigned char down, left, right, up;
2626-2727-bool doInput()
2828-{
2929- const bool prevSecond = kb_IsDown(kb_Key2nd);
3030- const bool prevAlpha = kb_IsDown(kb_KeyAlpha);
3131- const bool prevClear = kb_IsDown(kb_KeyClear);
3232-3333- kb_Scan();
3434-3535- up = kb_IsDown(kb_KeyUp) ? up + 1 : 0;
3636- down = kb_IsDown(kb_KeyDown) ? down + 1 : 0;
3737- left = kb_IsDown(kb_KeyLeft) ? left + 1 : 0;
3838- right = kb_IsDown(kb_KeyRight) ? right + 1 : 0;
3939-4040- const bool select = (kb_IsDown(kb_Key2nd) && !prevSecond);
4141- const bool draw = (kb_IsDown(kb_KeyAlpha) && !prevAlpha);
4242- const bool clear = (kb_IsDown(kb_KeyClear) && !prevClear);
4343-4444- if (select)
4545- {
4646- if (cursorMode == SELECT)
4747- {
4848- if (canGrabCard())
4949- {
5050- grabCard();
5151- cursorMode = DROP;
5252- }
5353- }
5454- else if (canDropCard())
5555- {
5656- dropCard();
5757- cursorMode = SELECT;
5858- }
5959- }
6060- else if (clear)
6161- {
6262- if (canClearCard())
6363- {
6464- clearCard();
6565- cursorMode = SELECT;
6666- }
6767- }
6868- else if (draw)
6969- {
7070- if (cursorMode == SELECT && deckCards > 0)
7171- {
7272- getNewCard();
7373- orgStack = DECK_ORG;
7474- cursorMode = DROP;
7575- }
7676- }
7777-7878- unsigned char prevCursorStack = cursorStack;
7979-8080- if (down == 1 || down > HOLD_TIME)
8181- {
8282- if (cursorStack < NUM_FREECELLS || !(tableau[cursorStack][cursorIndex + 1] & CARD_EXISTS)) cursorIndex++;
8383- }
8484- else if (left == 1 || left > HOLD_TIME)
8585- {
8686- if (cursorStack == 0) cursorStack = NUM_FREECELLS + NUM_TABLSLOTS - 1; // wrap
8787- else cursorStack--;
8888- }
8989- else if (right == 1 || right > HOLD_TIME)
9090- {
9191- if (cursorStack > NUM_FREECELLS + NUM_TABLSLOTS - 2) cursorStack = 0; // wrap
9292- else cursorStack++;
9393- }
9494- else if (up == 1 || up > HOLD_TIME)
9595- {
9696- if (cursorIndex > 0) cursorIndex--;
9797- }
9898-9999- if (cursorStack < NUM_FREECELLS)
100100- {
101101- cursorIndex = 0;
102102- }
103103- else if (cursorMode == DROP)
104104- {
105105- maxCursorIndex();
106106- if (cursorStack >= NUM_FREECELLS && (tableau[cursorStack - NUM_FREECELLS][0] & CARD_EXISTS)) cursorIndex++;
107107- }
108108- else if (cursorStack != prevCursorStack)
109109- {
110110- maxCursorIndex();
111111- }
112112-113113- if (kb_IsDown(kb_KeyDel))
114114- {
115115- deleteSave();
116116- start();
117117- }
118118-119119- return !kb_On && progress < 10;
120120-}
-24
src/input.h
···11-// Calculation Solitaire / CALCSLTR for the TI-84 Plus CE
22-// Copyright (C) 2025 euphory
33-//
44-// This program is free software: you can redistribute it and/or modify
55-// it under the terms of the GNU General Public License as published by
66-// the Free Software Foundation, either version 3 of the License, or
77-// (at your option) any later version.
88-//
99-// This program is distributed in the hope that it will be useful,
1010-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1111-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212-// GNU General Public License for more details.
1313-//
1414-// You should have received a copy of the GNU General Public License
1515-// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616-1717-#ifndef input_include_file
1818-#define input_include_file
1919-2020-#include <stdbool.h>
2121-2222-bool doInput();
2323-2424-#endif
+30-92
src/main.c
···11-// Calculation Solitaire / CALCSLTR for the TI-84 Plus CE
22-// Copyright (C) 2025 euphory
33-//
44-// This program is free software: you can redistribute it and/or modify
55-// it under the terms of the GNU General Public License as published by
66-// the Free Software Foundation, either version 3 of the License, or
77-// (at your option) any later version.
88-//
99-// This program is distributed in the hope that it will be useful,
1010-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1111-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212-// GNU General Public License for more details.
1313-//
1414-// You should have received a copy of the GNU General Public License
1515-// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616-1717-#include <fileioc.h>
1818-#include <stdlib.h>
1919-#include <math.h>
2020-#include <time.h>
2121-#include <sys/rtc.h>
2222-#include <keypadc.h>
2323-2424-#include "variables.h"
2525-#include "input.h"
2626-#include "drawing.h"
2727-#include "save.h"
2828-#include "ops.h"
2929-3030-card_t tableau[NUM_TABLSLOTS][TABL_STACK_SIZE];
3131-card_t freeCells[NUM_FREECELLS];
3232-unsigned char progress;
3333-3434-bool run()
3535-{
3636- start();
3737-3838- while (doInput())
3939- {
4040- clock_t frameTimer = clock();
4141-4242- drawFrame(true);
4343-4444- while (clock() - frameTimer < FRAME_TIME);
4545- }
4646-4747- if (progress == PROGRESS_COMPLETE)
4848- {
4949- // this way we know not to try to resume
5050- deleteSave();
5151-5252- drawFrame(true);
5353-5454- while (kb_AnyKey());
5555-5656- while (true)
5757- {
5858- kb_Scan();
5959- if (kb_On) return false;
6060- if (kb_IsDown(kb_Key2nd) || kb_IsDown(kb_KeyEnter)) return true;
6161- }
6262- }
6363- else
6464- {
6565- // user exited mid-game
6666- save();
6767- return false;
6868- }
6969-}
7070-7171-int main(void)
7272-{
7373- srand(rtc_Time());
7474-7575- gfx_Begin();
7676- gfx_SetDrawBuffer();
7777- gfx_SetPalette(global_palette, sizeof_global_palette, 0);
7878- gfx_SetTransparentColor(3);
7979-8080- kb_EnableOnLatch();
8181- kb_ClearOnLatch();
8282-8383- loadWins();
8484-8585- while (run());
8686-8787- gfx_End();
8888-8989- kb_ClearOnLatch();
9090-9191- return 0;
9292-}
11+#include "card.h"
22+#include "drawing.h"
33+#include "gfx/gfx.h"
44+#include <graphx.h>
55+#include <ti/getcsc.h>
66+77+int main(void)
88+{
99+ gfx_Begin();
1010+ gfx_SetPalette(&global_palette, sizeof(global_palette), 0);
1111+ gfx_SetDrawBuffer();
1212+ gfx_FillScreen(3);
1313+1414+ alloc_stacks(2);
1515+ make_stack(0, 5, 100, 50, 5, 2);
1616+ stacks[0].cards[0] = 0x8c;
1717+ stacks[0].cards[1] = 0x9b;
1818+1919+ while (!boot_CheckOnPressed())
2020+ {
2121+ gfx_SetColor(7);
2222+2323+ draw_stacks();
2424+ gfx_BlitBuffer();
2525+2626+ os_GetCSC();
2727+ }
2828+2929+ gfx_End();
3030+}
-146
src/ops.c
···11-// Calculation Solitaire / CALCSLTR for the TI-84 Plus CE
22-// Copyright (C) 2025 euphory
33-//
44-// This program is free software: you can redistribute it and/or modify
55-// it under the terms of the GNU General Public License as published by
66-// the Free Software Foundation, either version 3 of the License, or
77-// (at your option) any later version.
88-//
99-// This program is distributed in the hope that it will be useful,
1010-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1111-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212-// GNU General Public License for more details.
1313-//
1414-// You should have received a copy of the GNU General Public License
1515-// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616-1717-#include "ops.h"
1818-1919-#include <stdlib.h>
2020-#include <fileioc.h>
2121-2222-#include "variables.h"
2323-#include "save.h"
2424-#include "drawing.h"
2525-2626-unsigned char cursorStack;
2727-unsigned char cursorIndex;
2828-enum cursorMode_t cursorMode;
2929-unsigned char selectedCard;
3030-unsigned char selectedQty;
3131-unsigned char orgStack;
3232-unsigned char orgIndex;
3333-3434-void start()
3535-{
3636- loadWins();
3737- load(); // will call deal() as well if necessary
3838-3939- // set initial variables
4040- cursorMode = SELECT;
4141- cursorStack = NUM_FREECELLS;
4242- maxCursorIndex();
4343- selectedCard = CARD_EMPTY;
4444-}
4545-4646-bool canGrabCard()
4747-{
4848- if (cursorStack < NUM_FREECELLS) return false;
4949- else if (tableau[cursorStack - NUM_FREECELLS][cursorIndex + 1] & CARD_EXISTS) return false;
5050- else return tableau[cursorStack - NUM_FREECELLS][cursorIndex] & CARD_EXISTS;
5151-}
5252-5353-bool canDropCard()
5454-{
5555- if (cursorStack < NUM_FREECELLS)
5656- {
5757- if ((freeCells[cursorStack] & CARD_NUMBER) == CARD_KING) return false;
5858- else return (selectedCard & CARD_NUMBER) == (cursorStack + (freeCells[cursorStack] & CARD_NUMBER) + 1) % 13;
5959- }
6060- else if (orgStack != DECK_ORG)
6161- {
6262- return cursorStack == orgStack;
6363- }
6464- else if (cursorIndex == 0)
6565- {
6666- return true;
6767- }
6868- else
6969- {
7070- return !(tableau[cursorStack - NUM_FREECELLS][cursorIndex + 1] & CARD_EXISTS);
7171- }
7272-}
7373-7474-bool canClearCard()
7575-{
7676- if (orgStack == DECK_ORG) return false;
7777- else return selectedCard & CARD_EXISTS;
7878-}
7979-8080-void getNewCard()
8181-{
8282- while (true)
8383- {
8484- selectedCard = (rand() & CARD_SUIT) | (rand() % 13) | CARD_EXISTS;
8585- if (!removeFromDeck(selectedCard)) break;
8686- }
8787-8888- animateDraw();
8989-}
9090-9191-bool removeFromDeck(card_t toRemove)
9292-{
9393- unsigned char cardIndex = ((toRemove & CARD_SUIT) >> 4) * 13 + (toRemove & CARD_NUMBER);
9494- unsigned char *deckByte = deck + (cardIndex / 8);
9595- unsigned char pokeByte = 0x01 << (cardIndex % 8);
9696- if (*deckByte & pokeByte) return true;
9797-9898- *deckByte |= pokeByte;
9999- deckCards--;
100100- return false;
101101-}
102102-103103-void grabCard()
104104-{
105105- orgStack = cursorStack;
106106- orgIndex = cursorIndex;
107107-108108- selectedCard = tableau[cursorStack - NUM_FREECELLS][cursorIndex];
109109- tableau[cursorStack - NUM_FREECELLS][cursorIndex] = CARD_EMPTY;
110110-111111- animateGrab();
112112-}
113113-114114-void dropCard()
115115-{
116116- animateDrop();
117117-118118- unsigned char const prevProgress = progress;
119119-120120- if (cursorStack < NUM_FREECELLS)
121121- {
122122- freeCells[cursorStack] = selectedCard;
123123- if ((selectedCard & CARD_NUMBER) == CARD_KING) progress++;
124124- }
125125- else
126126- {
127127- tableau[cursorStack - NUM_FREECELLS][cursorIndex] = selectedCard;
128128- }
129129-130130- if (progress == PROGRESS_COMPLETE && prevProgress < PROGRESS_COMPLETE) (*numWins)++;
131131-}
132132-133133-void clearCard()
134134-{
135135- animateClear();
136136- tableau[orgStack - NUM_FREECELLS][orgIndex] = selectedCard;
137137- selectedCard = CARD_EMPTY;
138138-}
139139-140140-void maxCursorIndex()
141141-{
142142- if (cursorStack < NUM_FREECELLS) return;
143143-144144- cursorIndex = 0;
145145- while (tableau[cursorStack - NUM_FREECELLS][cursorIndex + 1] & CARD_EXISTS) cursorIndex++;
146146-}
-41
src/ops.h
···11-// Calculation Solitaire / CALCSLTR for the TI-84 Plus CE
22-// Copyright (C) 2025 euphory
33-//
44-// This program is free software: you can redistribute it and/or modify
55-// it under the terms of the GNU General Public License as published by
66-// the Free Software Foundation, either version 3 of the License, or
77-// (at your option) any later version.
88-//
99-// This program is distributed in the hope that it will be useful,
1010-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1111-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212-// GNU General Public License for more details.
1313-//
1414-// You should have received a copy of the GNU General Public License
1515-// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616-1717-#ifndef ops_include_file
1818-#define ops_include_file
1919-2020-#include <stdbool.h>
2121-#include "variables.h"
2222-2323-#define canPress2nd() (cursorMode == SELECT ? canGrabCard() : canDropCard())
2424-#define canPressAlpha() (!(selectedCard & CARD_EXISTS))
2525-#define canPressClear() (canClearCard())
2626-#define canPressDel() (true)
2727-2828-void start();
2929-3030-bool canGrabCard();
3131-bool canDropCard();
3232-bool canClearCard();
3333-3434-void getNewCard();
3535-bool removeFromDeck(card_t toRemove); // returns true iff card not in deck
3636-void grabCard();
3737-void dropCard();
3838-void clearCard();
3939-void maxCursorIndex();
4040-4141-#endif
-152
src/save.c
···11-// Calculation Solitaire / CALCSLTR for the TI-84 Plus CE
22-// Copyright (C) 2025 euphory
33-//
44-// This program is free software: you can redistribute it and/or modify
55-// it under the terms of the GNU General Public License as published by
66-// the Free Software Foundation, either version 3 of the License, or
77-// (at your option) any later version.
88-//
99-// This program is distributed in the hope that it will be useful,
1010-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1111-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212-// GNU General Public License for more details.
1313-//
1414-// You should have received a copy of the GNU General Public License
1515-// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616-1717-#include "save.h"
1818-1919-#include <sys/rtc.h>
2020-#include <fileioc.h>
2121-#include <stdlib.h>
2222-2323-#include "variables.h"
2424-#include "drawing.h"
2525-#include "ops.h"
2626-2727-unsigned char deck[7];
2828-unsigned char deckCards;
2929-3030-unsigned int *numWins;
3131-unsigned char *saveData;
3232-3333-void deal()
3434-{
3535- progress = 0;
3636- deckCards = 52;
3737-3838- for (unsigned char i = 0; i < 7; i++)
3939- {
4040- deck[i] = 0x00;
4141- }
4242-4343- for (unsigned char i = 0; i < NUM_TABLSLOTS; i++)
4444- {
4545- for (unsigned char j = 0; j < TABL_STACK_SIZE; j++)
4646- {
4747- tableau[i][j] = CARD_EMPTY;
4848- }
4949- }
5050-5151- for (unsigned char i = 0; i < NUM_FREECELLS; i++)
5252- {
5353- freeCells[i] = CARD_EXISTS | i | (unsigned char)(rand() & CARD_SUIT);
5454- removeFromDeck(freeCells[i]);
5555- }
5656-5757- animateDeal();
5858-}
5959-6060-void loadWins()
6161-{
6262- unsigned char winsHandle = ti_Open(WINS_VAR_NAME, "r+");
6363-6464- if (winsHandle == 0)
6565- {
6666- // create a new blank file
6767- winsHandle = ti_Open(WINS_VAR_NAME, "w");
6868- ti_PutC(0, winsHandle);
6969- ti_Seek(0, SEEK_SET, winsHandle);
7070- }
7171-7272- // is there already an entry for this game?
7373- unsigned char *length = ti_GetDataPtr(winsHandle);
7474- highscore_t *entries = (highscore_t *)length + sizeof(char);
7575- for (unsigned char i = 0; i < *length; i++)
7676- {
7777- if (entries[i].gameId == GAME_ID)
7878- {
7979- numWins = &(entries[i].score);
8080- goto found_wins;
8181- }
8282- }
8383-8484- // add a new blank entry
8585- (*length)++;
8686- ti_Seek(sizeof(char) + *length * sizeof(highscore_t), SEEK_SET, winsHandle);
8787- const highscore_t newHighScore = { GAME_ID, 0 };
8888- highscore_t *entry = (highscore_t *)ti_GetDataPtr(winsHandle);
8989- ti_Write(&newHighScore, sizeof(highscore_t), 1, winsHandle);
9090- numWins = &(entry->score);
9191-9292-found_wins:
9393- ti_Close(winsHandle);
9494-}
9595-9696-void load()
9797-{
9898- unsigned char saveHandle = ti_Open(SAVE_VAR_NAME, "r");
9999-100100- if (saveHandle == 0)
101101- {
102102- // no save present
103103- deal();
104104- }
105105- else
106106- {
107107- unsigned char magicNumber = ti_GetC(saveHandle);
108108- if (magicNumber != GAME_ID)
109109- {
110110- // this is from a different solitaire game
111111- deal();
112112- }
113113- else
114114- {
115115- // load save
116116- ti_Read(freeCells, 1, NUM_FREECELLS, saveHandle);
117117- ti_Read(tableau, 1, NUM_TABLSLOTS * TABL_STACK_SIZE, saveHandle);
118118-119119- // how far along does that make us?
120120- progress = 0;
121121- for (unsigned char i = 0; i < NUM_FREECELLS; i++)
122122- {
123123- if ((freeCells[i] & CARD_NUMBER) == CARD_KING) progress++;
124124- }
125125-126126- ti_Read(&deckCards, 1, 1, saveHandle);
127127- ti_Read(deck, 1, 7, saveHandle);
128128- ti_Read(&selectedCard, 1, 1, saveHandle);
129129- }
130130- }
131131-132132- ti_Close(saveHandle);
133133-}
134134-135135-void save()
136136-{
137137- unsigned char saveHandle = ti_Open(SAVE_VAR_NAME, "w");
138138-139139- ti_PutC(GAME_ID, saveHandle);
140140- ti_Write(freeCells, 1, NUM_FREECELLS, saveHandle);
141141- ti_Write(tableau, 1, NUM_TABLSLOTS * TABL_STACK_SIZE, saveHandle);
142142- ti_Write(&deckCards, 1, 1, saveHandle);
143143- ti_Write(deck, 1, 7, saveHandle);
144144- ti_Write(&selectedCard, 1, 1, saveHandle);
145145-146146- ti_Close(saveHandle);
147147-}
148148-149149-void deleteSave()
150150-{
151151- ti_Delete(SAVE_VAR_NAME);
152152-}
-31
src/save.h
···11-// Calculation Solitaire / CALCSLTR for the TI-84 Plus CE
22-// Copyright (C) 2025 euphory
33-//
44-// This program is free software: you can redistribute it and/or modify
55-// it under the terms of the GNU General Public License as published by
66-// the Free Software Foundation, either version 3 of the License, or
77-// (at your option) any later version.
88-//
99-// This program is distributed in the hope that it will be useful,
1010-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1111-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212-// GNU General Public License for more details.
1313-//
1414-// You should have received a copy of the GNU General Public License
1515-// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616-1717-#ifndef save_include_file
1818-#define save_include_file
1919-2020-typedef struct {
2121- unsigned char gameId;
2222- unsigned int score;
2323-} highscore_t;
2424-2525-void deal();
2626-void load();
2727-void save();
2828-void deleteSave();
2929-void loadWins();
3030-3131-#endif
-59
src/variables.h
···11-// Calculation Solitaire / CALCSLTR for the TI-84 Plus CE
22-// Copyright (C) 2025 euphory
33-//
44-// This program is free software: you can redistribute it and/or modify
55-// it under the terms of the GNU General Public License as published by
66-// the Free Software Foundation, either version 3 of the License, or
77-// (at your option) any later version.
88-//
99-// This program is distributed in the hope that it will be useful,
1010-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1111-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212-// GNU General Public License for more details.
1313-//
1414-// You should have received a copy of the GNU General Public License
1515-// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616-1717-#ifndef variables_include_file
1818-#define variables_include_file
1919-2020-#define WINS_VAR_NAME "SLTRWINS"
2121-#define SAVE_VAR_NAME "SLTRSAVE"
2222-#define GAME_ID 0x02
2323-2424-#define FRAME_TIME 3277
2525-#define HOLD_TIME 2
2626-2727-#define NUM_FREECELLS 4
2828-#define NUM_TABLSLOTS 4
2929-#define TABL_STACK_SIZE 12
3030-3131-#define PROGRESS_COMPLETE 4
3232-#define DECK_ORG 0xff
3333-3434-#define CARD_RED 0x20
3535-#define CARD_SUIT 0x30
3636-#define CARD_NUMBER 0x0f
3737-#define CARD_KING 12
3838-#define CARD_EMPTY 0x00
3939-#define CARD_EXISTS 0x80
4040-4141-typedef unsigned char card_t;
4242-4343-extern card_t tableau[NUM_TABLSLOTS][TABL_STACK_SIZE];
4444-extern card_t freeCells[NUM_FREECELLS];
4545-4646-extern unsigned char cursorStack;
4747-extern unsigned char cursorIndex;
4848-extern enum cursorMode_t { SELECT, DROP } cursorMode;
4949-extern card_t selectedCard;
5050-extern unsigned char orgStack;
5151-extern unsigned char orgIndex;
5252-5353-extern unsigned char progress;
5454-extern unsigned int *numWins;
5555-5656-extern unsigned char deck[7];
5757-extern unsigned char deckCards;
5858-5959-#endif