From b502f1ea5542ecb4e7bd09ccebcae0753e2eb053 Mon Sep 17 00:00:00 2001 From: hrmorley34 Date: Sun, 16 Jul 2023 12:22:12 +0100 Subject: [PATCH] Separate classes into headers --- images/scripts/imagedata.hpp | 4 +- src/card.hpp | 14 +- src/cardclasses.cpp | 4 + src/cardcolumn.c.hpp | 95 ++++++ src/cardcolumn.hpp | 104 +------ src/cardll.c.hpp | 197 ++++++++++++ src/cardll.hpp | 206 ++----------- ...dcollectionutils.hpp => cardllpointer.hpp} | 11 +- src/cardselection.hpp | 11 +- src/controls.cpp | 224 ++++++++++++++ src/controls.hpp | 225 +------------- src/game.cpp | 281 +++++++++++++++++ src/game.hpp | 285 +----------------- src/gen/imagedata.hpp | 4 +- src/imageclasses.cpp | 36 +++ src/imageclasses.hpp | 34 +-- src/imagedata.cpp | 1 + src/imagedata.hpp | 11 + src/main.cpp | 1 + src/save.cpp | 40 +++ src/save.hpp | 47 +-- src/savedata.cpp | 3 + src/savedata.hpp | 2 +- src/visuals.cpp | 27 ++ src/visuals.hpp | 24 +- tests/Makefile | 17 +- tests/{card.hpp => card.cpp} | 0 tests/{cardll.hpp => cardll.cpp} | 0 tests/{game.hpp => game.cpp} | 0 tests/tests.cpp | 3 - 30 files changed, 1016 insertions(+), 895 deletions(-) create mode 100644 src/cardclasses.cpp create mode 100644 src/cardcolumn.c.hpp create mode 100644 src/cardll.c.hpp rename src/{cardcollectionutils.hpp => cardllpointer.hpp} (68%) create mode 100644 src/controls.cpp create mode 100644 src/game.cpp create mode 100644 src/imageclasses.cpp create mode 100644 src/imagedata.cpp create mode 100644 src/imagedata.hpp create mode 100644 src/save.cpp create mode 100644 src/savedata.cpp create mode 100644 src/visuals.cpp rename tests/{card.hpp => card.cpp} (100%) rename tests/{cardll.hpp => cardll.cpp} (100%) rename tests/{game.hpp => game.cpp} (100%) delete mode 100644 tests/tests.cpp diff --git a/images/scripts/imagedata.hpp b/images/scripts/imagedata.hpp index cb2f306..1d76818 100644 --- a/images/scripts/imagedata.hpp +++ b/images/scripts/imagedata.hpp @@ -1,8 +1,8 @@ #include "../imageclasses.hpp" #include "../card.hpp" -#ifndef IMAGEDATA_H -#define IMAGEDATA_H +#ifndef GEN_IMAGEDATA_H +#define GEN_IMAGEDATA_H #pragma region IMAGEDATA const Image CardImage; diff --git a/src/card.hpp b/src/card.hpp index 6e75cf9..1ef099f 100644 --- a/src/card.hpp +++ b/src/card.hpp @@ -18,7 +18,7 @@ enum Colour : uint8_t Black = 1 }; -Colour GetSuitColour(const Suit suit) +inline Colour GetSuitColour(const Suit suit) { return (Colour)(suit >> 1); } @@ -30,17 +30,11 @@ struct Card private: uint8_t ivalue; // 0bssrrrr for suit (0-3), rank (1-13) - void SetInternal(const Suit suit, const Rank rank) - { - ivalue = (uint8_t)suit << 4 | (uint8_t)rank; - } - public: - Card() : ivalue(0) {} + Card() + : ivalue(0) {} Card(const Suit suit, const Rank rank) - { - SetInternal(suit, rank); - } + : ivalue((uint8_t)suit << 4 | (uint8_t)rank) {} bool operator==(const Card c) const { diff --git a/src/cardclasses.cpp b/src/cardclasses.cpp new file mode 100644 index 0000000..edf5d51 --- /dev/null +++ b/src/cardclasses.cpp @@ -0,0 +1,4 @@ +#include "card.hpp" +#include "cardcolumn.c.hpp" +#include "cardll.c.hpp" +#include "cardllpointer.hpp" diff --git a/src/cardcolumn.c.hpp b/src/cardcolumn.c.hpp new file mode 100644 index 0000000..4260ff8 --- /dev/null +++ b/src/cardcolumn.c.hpp @@ -0,0 +1,95 @@ +#include "cardcolumn.hpp" + +CardColumn::CardColumn() {} + +void CardColumn::PushLeft(const Card card) +{ + revealed.PushLeft(card); +} + +void CardColumn::PushUnrevealed(const Card card) +{ + unrevealed.PushLeft(card); +} + +void CardColumn::Reveal() +{ + if (!revealed.empty()) + return; + if (unrevealed.empty()) + return; + revealed.PushRight(unrevealed.PopLeft()); +} + +void CardColumn::MoveMany(int count, CardColumn *dest) +{ + revealed.MoveMany(count, &(dest->revealed)); + Reveal(); +} +// void CardColumn::MoveMany(int count, CardLL *dest) +// { +// revealed.MoveMany(count, dest); +// Reveal(); +// } +// void CardColumn::MoveManyFrom(int count, CardLL *src) +// { +// src->MoveMany(count, &revealed); +// } + +Card CardColumn::PopLeft() +{ + if (revealed.empty()) + Reveal(); + Card c = revealed.PopLeft(); + Reveal(); + return c; +} + +Card CardColumn::Peek() const +{ + // if (revealed.empty()) + // Reveal(); + return revealed.Peek(); +} + +Card CardColumn::PeekAt(const int index) const +{ + // if (revealed.empty()) + // Reveal(); + return revealed.PeekAt(index); +} + +int CardColumn::revealedlength() const +{ + return revealed.length(); +} + +int CardColumn::unrevealedlength() const +{ + return unrevealed.length(); +} + +bool CardColumn::empty() const +{ + return revealed.empty() && unrevealed.empty(); +} + +int CardColumn::WriteToArray(SaveData *const arr) const +{ + int length = unrevealed.WriteToArray(arr); + length += revealed.WriteToArray(arr + length); + return length; +} + +int CardColumn::GetWriteLength() const +{ + return unrevealed.GetWriteLength() + + revealed.GetWriteLength(); +} + +int CardColumn::ReadFromArray(const SaveData *const arr) +{ + int length = unrevealed.ReadFromArray(arr); + length += revealed.ReadFromArray(arr + length); + return length; +} diff --git a/src/cardcolumn.hpp b/src/cardcolumn.hpp index e07208d..5c20ece 100644 --- a/src/cardcolumn.hpp +++ b/src/cardcolumn.hpp @@ -12,99 +12,27 @@ class CardColumn CardLL unrevealed; public: - CardColumn() {} + CardColumn(); - void PushLeft(const Card card) - { - revealed.PushLeft(card); - } + void PushLeft(const Card card); + void PushUnrevealed(const Card card); + void Reveal(); - void PushUnrevealed(const Card card) - { - unrevealed.PushLeft(card); - } + void MoveMany(int count, CardColumn *dest); + // void MoveMany(int count, CardLL *dest); + // void MoveManyFrom(int count, CardLL *src); - void Reveal() - { - if (!revealed.empty()) - return; - if (unrevealed.empty()) - return; - revealed.PushRight(unrevealed.PopLeft()); - } + Card PopLeft(); + Card Peek() const; + Card PeekAt(const int index) const; - void MoveMany(int count, CardColumn *dest) - { - revealed.MoveMany(count, &(dest->revealed)); - Reveal(); - } - // void MoveMany(int count, CardLL *dest) - // { - // revealed.MoveMany(count, dest); - // Reveal(); - // } - // void MoveManyFrom(int count, CardLL *src) - // { - // src->MoveMany(count, &revealed); - // } + int revealedlength() const; + int unrevealedlength() const; + bool empty() const; - Card PopLeft() - { - if (revealed.empty()) - Reveal(); - Card c = revealed.PopLeft(); - Reveal(); - return c; - } - - Card Peek() const - { - // if (revealed.empty()) - // Reveal(); - return revealed.Peek(); - } - - Card PeekAt(const int index) const - { - // if (revealed.empty()) - // Reveal(); - return revealed.PeekAt(index); - } - - int revealedlength() const - { - return revealed.length(); - } - - int unrevealedlength() const - { - return unrevealed.length(); - } - - bool empty() const - { - return revealed.empty() && unrevealed.empty(); - } - - int WriteToArray(SaveData *const arr) const - { - int length = unrevealed.WriteToArray(arr); - length += revealed.WriteToArray(arr + length); - return length; - } - - int GetWriteLength() const - { - return unrevealed.GetWriteLength() + - revealed.GetWriteLength(); - } - - int ReadFromArray(const SaveData *const arr) - { - int length = unrevealed.ReadFromArray(arr); - length += revealed.ReadFromArray(arr + length); - return length; - } + int WriteToArray(SaveData *const arr) const; + int GetWriteLength() const; + int ReadFromArray(const SaveData *const arr); }; #endif diff --git a/src/cardll.c.hpp b/src/cardll.c.hpp new file mode 100644 index 0000000..fb036f4 --- /dev/null +++ b/src/cardll.c.hpp @@ -0,0 +1,197 @@ +#include "cardll.hpp" + +CardLLPointer pointers[52] = {}; + +CardLL::CardLL() : head(nullptr), tail(nullptr) {} + +// CardLL::~CardLL() +// { +// // DeleteQueuePointers(head); +// } + +void CardLL::PushLeft(const Card card) +{ + // head = new CardLLPointer(card, head); + CardLLPointer *lasthead = head; + // head = (CardLLPointer *)malloc(sizeof(CardLLPointer)); + head = &pointers[card.GetPIndex()]; + *head = CardLLPointer(card, lasthead); + if (tail == nullptr) + tail = head; +} + +void CardLL::PushRight(const Card card) +{ + if (head == nullptr) + { + // head = tail = new CardLLPointer(card); + // head = tail = (CardLLPointer *)malloc(sizeof(CardLLPointer)); + head = tail = &pointers[card.GetPIndex()]; + *head = CardLLPointer(card); + } + else + { + // tail->next = new CardLLPointer(card); + // tail->next = (CardLLPointer *)malloc(sizeof(CardLLPointer)); + tail->next = &pointers[card.GetPIndex()]; + *(tail->next) = CardLLPointer(card); + tail = tail->next; + } +} + +Card CardLL::PopLeft() +{ + if (head == nullptr) + return Card(); + CardLLPointer *p = head; + Card c = p->card; + head = p->next; + // delete p; + // free(p); + if (head == nullptr) + tail = nullptr; + return c; +} + +Card CardLL::PopAt(const int index) +{ + if (index < 0 || head == nullptr) + return Card(); + if (index == 0) + return PopLeft(); + CardLLPointer *prev = nullptr; + CardLLPointer *p = head; + for (int i = 0; i < index; i++) + { + prev = p; + p = p->next; + if (p == nullptr) + return Card(); + } + Card c = p->card; + prev->next = p->next; + // delete p; + // free(p); + return c; +} + +Card CardLL::Peek() const +{ + if (head == nullptr) + return Card(); + return head->card; +} + +Card CardLL::PeekAt(const int index) const +{ + CardLLPointer *p = GetAtIndex(head, index); + if (p == nullptr) + return Card(); + return p->card; +} + +void CardLL::MoveMany(int count, CardLL *const dest) +{ + if (count <= 0) + return; + if (count > this->length()) + count = this->length(); + CardLLPointer *move_head = head; + CardLLPointer *move_tail = GetAtIndex(head, count - 1); + // move_tail is not null, because of length check + CardLLPointer *new_head = move_tail->next; + move_tail->next = dest->head; + dest->head = move_head; + this->head = new_head; +} + +int CardLL::length() const +{ + int i = 0; + CardLLPointer *p = head; + while (p != nullptr) + { + i += 1; + p = p->next; + } + return i; +} + +bool CardLL::empty() const +{ + return head == nullptr; +} + +#define SHUFFLE_ITERATIONS 256 +void CardLL::ShuffleCards() +{ + int length = this->length(); + for (int i = 0; i < SHUFFLE_ITERATIONS; i++) + { + this->PushRight(this->PopAt( +#ifdef __sh__ + sys_rand() +#else + rand() +#endif + % (length - 1))); + } +} + +int CardLL::WriteToArray(SaveData *arr) const +{ + uint8_t *sizeloc = &arr->value; + *sizeloc = 0; + arr++; + + CardLLPointer *p = head; + while (p != nullptr) + { + arr->card = p->card; + arr++; + (*sizeloc)++; + p = p->next; + } + + return (*sizeloc) + 1; +} + +int CardLL::GetWriteLength() const +{ + return length() + 1; +} + +int CardLL::ReadFromArray(const SaveData *arr) +{ + uint8_t length = arr->value; + arr++; + + CardLLPointer *p = head = tail = nullptr; + for (int i = 0; i < length; i++) + { + Card c = arr->card; + tail = &pointers[c.GetPIndex()]; + *tail = CardLLPointer(c); + if (i == 0) + head = tail; + else + p->next = tail; + p = tail; + arr++; + } + + return length + 1; +} + +void FillCardDeck(CardLL *const cs) +{ + for (uint8_t i = 0; i < SUIT_COUNT; i++) + { + for (uint8_t j = 1; j <= 13; j++) + { + Card c = Card((Suit)i, (Rank)j); + pointers[c.GetPIndex()] = CardLLPointer(c); + cs->PushRight(pointers[c.GetPIndex()].card); + } + } +} diff --git a/src/cardll.hpp b/src/cardll.hpp index 2cb0b4b..38a3d36 100644 --- a/src/cardll.hpp +++ b/src/cardll.hpp @@ -2,14 +2,12 @@ #include "stdint.h" #include "card.hpp" -#include "cardcollectionutils.hpp" +#include "cardllpointer.hpp" #include "savedata.hpp" #ifndef CARDLL_H #define CARDLL_H -CardLLPointer pointers[52] = {}; - class CardLL { private: @@ -17,199 +15,29 @@ class CardLL CardLLPointer *tail; public: - CardLL() : head(nullptr), tail(nullptr) {} - - // ~CardLL() - // { - // // DeleteQueuePointers(head); - // } - - void PushLeft(const Card card) - { - // head = new CardLLPointer(card, head); - CardLLPointer *lasthead = head; - // head = (CardLLPointer *)malloc(sizeof(CardLLPointer)); - head = &pointers[card.GetPIndex()]; - *head = CardLLPointer(card, lasthead); - if (tail == nullptr) - tail = head; - } - - void PushRight(const Card card) - { - if (head == nullptr) - { - // head = tail = new CardLLPointer(card); - // head = tail = (CardLLPointer *)malloc(sizeof(CardLLPointer)); - head = tail = &pointers[card.GetPIndex()]; - *head = CardLLPointer(card); - } - else - { - // tail->next = new CardLLPointer(card); - // tail->next = (CardLLPointer *)malloc(sizeof(CardLLPointer)); - tail->next = &pointers[card.GetPIndex()]; - *(tail->next) = CardLLPointer(card); - tail = tail->next; - } - } + CardLL(); + // ~CardLL(); - Card PopLeft() - { - if (head == nullptr) - return Card(); - CardLLPointer *p = head; - Card c = p->card; - head = p->next; - // delete p; - // free(p); - if (head == nullptr) - tail = nullptr; - return c; - } + void PushLeft(const Card card); + void PushRight(const Card card); - Card PopAt(const int index) - { - if (index < 0 || head == nullptr) - return Card(); - if (index == 0) - return PopLeft(); - CardLLPointer *prev = nullptr; - CardLLPointer *p = head; - for (int i = 0; i < index; i++) - { - prev = p; - p = p->next; - if (p == nullptr) - return Card(); - } - Card c = p->card; - prev->next = p->next; - // delete p; - // free(p); - return c; - } + Card PopLeft(); + Card PopAt(const int index); + Card Peek() const; + Card PeekAt(const int index) const; - Card Peek() const - { - if (head == nullptr) - return Card(); - return head->card; - } + void MoveMany(int count, CardLL *const dest); - Card PeekAt(const int index) const - { - CardLLPointer *p = GetAtIndex(head, index); - if (p == nullptr) - return Card(); - return p->card; - } + int length() const; + bool empty() const; - void MoveMany(int count, CardLL *const dest) - { - if (count <= 0) - return; - if (count > this->length()) - count = this->length(); - CardLLPointer *move_head = head; - CardLLPointer *move_tail = GetAtIndex(head, count - 1); - // move_tail is not null, because of length check - CardLLPointer *new_head = move_tail->next; - move_tail->next = dest->head; - dest->head = move_head; - this->head = new_head; - } - - int length() const - { - int i = 0; - CardLLPointer *p = head; - while (p != nullptr) - { - i += 1; - p = p->next; - } - return i; - } - - bool empty() const - { - return head == nullptr; - } - -#define SHUFFLE_ITERATIONS 256 - void ShuffleCards() - { - int length = this->length(); - for (int i = 0; i < SHUFFLE_ITERATIONS; i++) - { - this->PushRight(this->PopAt( -#ifdef __sh__ - sys_rand() -#else - rand() -#endif - % (length - 1))); - } - } + void ShuffleCards(); - int WriteToArray(SaveData *arr) const - { - uint8_t *sizeloc = &arr->value; - *sizeloc = 0; - arr++; - - CardLLPointer *p = head; - while (p != nullptr) - { - arr->card = p->card; - arr++; - (*sizeloc)++; - p = p->next; - } - - return (*sizeloc) + 1; - } - - int GetWriteLength() const - { - return length() + 1; - } - - int ReadFromArray(const SaveData *arr) - { - uint8_t length = arr->value; - arr++; - - CardLLPointer *p = head = tail = nullptr; - for (int i = 0; i < length; i++) - { - Card c = arr->card; - tail = &pointers[c.GetPIndex()]; - *tail = CardLLPointer(c); - if (i == 0) - head = tail; - else - p->next = tail; - p = tail; - arr++; - } - - return length + 1; - } + int WriteToArray(SaveData *arr) const; + int GetWriteLength() const; + int ReadFromArray(const SaveData *arr); }; -void FillCardDeck(CardLL *const cs) -{ - for (uint8_t i = 0; i < SUIT_COUNT; i++) - { - for (uint8_t j = 1; j <= 13; j++) - { - Card c = Card((Suit)i, (Rank)j); - pointers[c.GetPIndex()] = CardLLPointer(c); - cs->PushRight(pointers[c.GetPIndex()].card); - } - } -} +void FillCardDeck(CardLL *const cs); #endif diff --git a/src/cardcollectionutils.hpp b/src/cardllpointer.hpp similarity index 68% rename from src/cardcollectionutils.hpp rename to src/cardllpointer.hpp index fa0a880..5d7552b 100644 --- a/src/cardcollectionutils.hpp +++ b/src/cardllpointer.hpp @@ -1,17 +1,16 @@ #include #include "card.hpp" -#ifndef CARDCOLLECTIONUTILS_H -#define CARDCOLLECTIONUTILS_H +#ifndef CARDLLPOINTER_H +#define CARDLLPOINTER_H struct CardLLPointer { public: - Card card; + Card card = Card(); CardLLPointer *next = nullptr; - CardLLPointer() {} - CardLLPointer(const Card card, CardLLPointer *next = nullptr) + CardLLPointer(const Card card = Card(), CardLLPointer *next = nullptr) : card(card), next(next) {} }; @@ -27,7 +26,7 @@ struct CardLLPointer // } // } -CardLLPointer *GetAtIndex(CardLLPointer *p, const int index) +inline CardLLPointer *GetAtIndex(CardLLPointer *p, const int index) { for (int i = 0; i < index && p != nullptr; i++) { diff --git a/src/cardselection.hpp b/src/cardselection.hpp index fc63ba1..0823efb 100644 --- a/src/cardselection.hpp +++ b/src/cardselection.hpp @@ -21,16 +21,9 @@ struct CardSelection int depth; CardSelection() - { - col = 0; - depth = 0; - } - + : col(0), depth(0) {} CardSelection(const int col, const int depth) - { - this->col = col; - this->depth = depth; - } + : col(col), depth(depth) {} }; #define SUIT_COLUMN(suit) (-SUIT_COUNT + suit) diff --git a/src/controls.cpp b/src/controls.cpp new file mode 100644 index 0000000..78f2ba1 --- /dev/null +++ b/src/controls.cpp @@ -0,0 +1,224 @@ +#include "controls.hpp" + +void Controls::SelectSrc() +{ + src = sel; + // sel is left unchanged +} + +Controls::Controls(Game *const game) +{ + this->game = game; + + src = CardSelection(0, 0); + sel = CardSelection(PILE_COLUMN, 1); +} + +void Controls::ClearScreen() const +{ + DrawBackground(0, LCD_HEIGHT_PX, 0, LCD_WIDTH_PX); +} + +void Controls::DrawScreenTop() const +{ + DrawBackground( + TOP_Y - MARGIN / 2, CARD_HEIGHT + MARGIN + 1, + PILE_X - MARGIN / 2, GAME_WIDTH + MARGIN); + + if (!game->pile.empty()) + DrawCardBack(PILE_X, TOP_Y); + int discardcount = game->pilediscard.length(); + if (discardcount > DEAL_COUNT) + discardcount = DEAL_COUNT; + for (int c = 0; c < discardcount; c++) + DrawCard( + game->pilediscard.PeekAt(discardcount - c - 1), + PILEDISCARD_X(c), TOP_Y); + for (int suit = 0; suit < SUIT_COUNT; suit++) + { + Card c = game->suits[suit].Peek(); + if (c.NonNull()) + DrawCard(c, SUIT_X(suit), TOP_Y); + } + + if (src.depth > 0) + DrawScreenTopShine(src); + DrawScreenTopShine(sel); +} + +void Controls::DrawScreenTopShine(CardSelection sel) const +{ + if (sel.col >= 0) + return; + if (sel.col >= SUIT_COLUMN(0)) + DrawCardShine(SUIT_X(SUIT_FROM_COLUMN(sel.col)), TOP_Y); + if (sel.col == PILEDISCARD_COLUMN) + { + int discardcount = game->pilediscard.length(); + if (discardcount > DEAL_COUNT) + discardcount = DEAL_COUNT; + if (discardcount < 1) + discardcount = 1; + DrawCardShine(PILEDISCARD_X(discardcount - 1), TOP_Y); + } + if (sel.col == PILE_COLUMN) + DrawCardShine(PILE_X, TOP_Y); +} + +void Controls::DrawScreenCol(int col) const +{ +#define cold game->columns[col] + const int colx = COLUMN_X(col); + + DrawBackground( + COLUMNS_TOP_Y - MARGIN / 2, COLUMNS_HEIGHT + MARGIN, + colx - MARGIN / 2, CARD_WIDTH + MARGIN); + + const int unlen = cold.unrevealedlength(); + const int relen = cold.revealedlength(); + int unoff, reoff; + calculate_squash(unlen, relen, &unoff, &reoff); + + int shinec = 0; + if (src.col == col && src.depth > shinec) + shinec = src.depth; + if (sel.col == col && sel.depth > shinec) + shinec = sel.depth; + int shinefirst = relen - shinec; + if (shinefirst < 0) + shinefirst = 0; + + for (int c = 0; c < unlen; c++) + DrawCardBack(colx, COLUMN_CARD_Y(c, unoff, 0, reoff)); + for (int c = 0; c < shinefirst; c++) + DrawCard( + cold.PeekAt(relen - c - 1), + colx, COLUMN_CARD_Y(unlen, unoff, c, reoff)); + for (int c = shinefirst; c < relen; c++) + { + const int y = COLUMN_CARD_Y(unlen, unoff, c, reoff); + DrawCard(cold.PeekAt(relen - c - 1), colx, y); + DrawCardShine(colx, y); + } + + if (unlen == 0 && relen == 0 && shinec > 0) + DrawCardShine(colx, COLUMNS_TOP_Y); +#undef cold +} + +void Controls::DrawScreen() const +{ + DrawScreenTop(); + for (int col = 0; col < COLUMN_COUNT; col++) + DrawScreenCol(col); +} + +void Controls::MoveSelection(const int dx, const int dy) +{ + // const int prev_col = sel.col; + + sel.col += dx; + if (sel.col < PILE_COLUMN) + sel.col = COLUMN_COUNT - 1; + if (sel.col >= COLUMN_COUNT) + sel.col = PILE_COLUMN; + + if (sel.col < 0) + { + sel.depth = 1; + if (dy != 0) + { + switch (sel.col) + { + case PILE_COLUMN: + sel.col = 0; + break; + case PILEDISCARD_COLUMN: + sel.col = 1; + break; + default: + sel.col += COLUMN_COUNT; + break; + } + } + } + else + { + CardColumn *col = game->GetSelectionColumn(sel); + int length = col->revealedlength(); + if (length < 1) + length = 1; + if (sel.depth < 1) + sel.depth = 1; + if (sel.depth > length) + sel.depth = length; + sel.depth -= dy; + if (sel.depth < 1 || sel.depth > length) + { + sel.depth = 1; + // move up/down (same thing) + if (sel.col >= COLUMN_COUNT - SUIT_COUNT) + sel.col -= COLUMN_COUNT; + else if (sel.col >= 1) + sel.col = PILEDISCARD_COLUMN; + else + sel.col = PILE_COLUMN; + } + } + + // if (prev_col < 0 || sel.col < 0) + // DrawScreenTop(); + // if (prev_col > 0) + // DrawScreenCol(prev_col); + // if (sel.col > 0 && sel.col != prev_col) + // DrawScreenCol(sel.col); +} + +void Controls::DoSelect() +{ + if (src.depth == 0) + { + if (game->TryStackAuto(sel)) + { + // preserve current selection for next move + } + else + { + src = sel; + } + } + else + { + if (game->TryStackOnSel(sel, src)) + { + // do nothing - may react with colour here + } + src = CardSelection(0, 0); + } + + // DrawScreen(); +} + +void Controls::HandleKey(const int key) +{ + switch (key) + { + case KEY_CTRL_UP: + MoveSelection(0, -1); + break; + case KEY_CTRL_DOWN: + MoveSelection(0, 1); + break; + case KEY_CTRL_LEFT: + MoveSelection(-1, 0); + break; + case KEY_CTRL_RIGHT: + MoveSelection(1, 0); + break; + case KEY_CTRL_EXE: + DoSelect(); + break; + } + // ClearScreen(); + DrawScreen(); +} diff --git a/src/controls.hpp b/src/controls.hpp index f62544d..520a5f8 100644 --- a/src/controls.hpp +++ b/src/controls.hpp @@ -4,7 +4,7 @@ #include "game.hpp" #include "cardselection.hpp" #include "visuals.hpp" -#include "gen/imagedata.hpp" +#include "imagedata.hpp" #ifndef CONTROLS_H #define CONTROLS_H @@ -20,229 +20,26 @@ class Controls */ CardSelection src, sel; - void SelectSrc() - { - src = sel; - // sel is left unchanged - } + void SelectSrc(); public: - Controls(Game *const game) - { - this->game = game; + Controls(Game *const game); - src = CardSelection(0, 0); - sel = CardSelection(PILE_COLUMN, 1); - } + void ClearScreen() const; - void ClearScreen() const - { - DrawBackground(0, LCD_HEIGHT_PX, 0, LCD_WIDTH_PX); - } + void DrawScreenTop() const; - void DrawScreenTop() const - { - DrawBackground( - TOP_Y - MARGIN / 2, CARD_HEIGHT + MARGIN + 1, - PILE_X - MARGIN / 2, GAME_WIDTH + MARGIN); + void DrawScreenTopShine(CardSelection sel) const; - if (!game->pile.empty()) - DrawCardBack(PILE_X, TOP_Y); - int discardcount = game->pilediscard.length(); - if (discardcount > DEAL_COUNT) - discardcount = DEAL_COUNT; - for (int c = 0; c < discardcount; c++) - DrawCard( - game->pilediscard.PeekAt(discardcount - c - 1), - PILEDISCARD_X(c), TOP_Y); - for (int suit = 0; suit < SUIT_COUNT; suit++) - { - Card c = game->suits[suit].Peek(); - if (c.NonNull()) - DrawCard(c, SUIT_X(suit), TOP_Y); - } + void DrawScreenCol(int col) const; - if (src.depth > 0) - DrawScreenTopShine(src); - DrawScreenTopShine(sel); - } + void DrawScreen() const; - void DrawScreenTopShine(CardSelection sel) const - { - if (sel.col >= 0) - return; - if (sel.col >= SUIT_COLUMN(0)) - DrawCardShine(SUIT_X(SUIT_FROM_COLUMN(sel.col)), TOP_Y); - if (sel.col == PILEDISCARD_COLUMN) - { - int discardcount = game->pilediscard.length(); - if (discardcount > DEAL_COUNT) - discardcount = DEAL_COUNT; - if (discardcount < 1) - discardcount = 1; - DrawCardShine(PILEDISCARD_X(discardcount - 1), TOP_Y); - } - if (sel.col == PILE_COLUMN) - DrawCardShine(PILE_X, TOP_Y); - } + void MoveSelection(const int dx, const int dy); - void DrawScreenCol(int col) const - { -#define cold game->columns[col] - const int colx = COLUMN_X(col); + void DoSelect(); - DrawBackground( - COLUMNS_TOP_Y - MARGIN / 2, COLUMNS_HEIGHT + MARGIN, - colx - MARGIN / 2, CARD_WIDTH + MARGIN); - - const int unlen = cold.unrevealedlength(); - const int relen = cold.revealedlength(); - int unoff, reoff; - calculate_squash(unlen, relen, &unoff, &reoff); - - int shinec = 0; - if (src.col == col && src.depth > shinec) - shinec = src.depth; - if (sel.col == col && sel.depth > shinec) - shinec = sel.depth; - int shinefirst = relen - shinec; - if (shinefirst < 0) - shinefirst = 0; - - for (int c = 0; c < unlen; c++) - DrawCardBack(colx, COLUMN_CARD_Y(c, unoff, 0, reoff)); - for (int c = 0; c < shinefirst; c++) - DrawCard( - cold.PeekAt(relen - c - 1), - colx, COLUMN_CARD_Y(unlen, unoff, c, reoff)); - for (int c = shinefirst; c < relen; c++) - { - const int y = COLUMN_CARD_Y(unlen, unoff, c, reoff); - DrawCard(cold.PeekAt(relen - c - 1), colx, y); - DrawCardShine(colx, y); - } - - if (unlen == 0 && relen == 0 && shinec > 0) - DrawCardShine(colx, COLUMNS_TOP_Y); -#undef cold - } - - void DrawScreen() const - { - DrawScreenTop(); - for (int col = 0; col < COLUMN_COUNT; col++) - DrawScreenCol(col); - } - - void MoveSelection(const int dx, const int dy) - { - // const int prev_col = sel.col; - - sel.col += dx; - if (sel.col < PILE_COLUMN) - sel.col = COLUMN_COUNT - 1; - if (sel.col >= COLUMN_COUNT) - sel.col = PILE_COLUMN; - - if (sel.col < 0) - { - sel.depth = 1; - if (dy != 0) - { - switch (sel.col) - { - case PILE_COLUMN: - sel.col = 0; - break; - case PILEDISCARD_COLUMN: - sel.col = 1; - break; - default: - sel.col += COLUMN_COUNT; - break; - } - } - } - else - { - CardColumn *col = game->GetSelectionColumn(sel); - int length = col->revealedlength(); - if (length < 1) - length = 1; - if (sel.depth < 1) - sel.depth = 1; - if (sel.depth > length) - sel.depth = length; - sel.depth -= dy; - if (sel.depth < 1 || sel.depth > length) - { - sel.depth = 1; - // move up/down (same thing) - if (sel.col >= COLUMN_COUNT - SUIT_COUNT) - sel.col -= COLUMN_COUNT; - else if (sel.col >= 1) - sel.col = PILEDISCARD_COLUMN; - else - sel.col = PILE_COLUMN; - } - } - - // if (prev_col < 0 || sel.col < 0) - // DrawScreenTop(); - // if (prev_col > 0) - // DrawScreenCol(prev_col); - // if (sel.col > 0 && sel.col != prev_col) - // DrawScreenCol(sel.col); - } - - void DoSelect() - { - if (src.depth == 0) - { - if (game->TryStackAuto(sel)) - { - // preserve current selection for next move - } - else - { - src = sel; - } - } - else - { - if (game->TryStackOnSel(sel, src)) - { - // do nothing - may react with colour here - } - src = CardSelection(0, 0); - } - - // DrawScreen(); - } - - void HandleKey(const int key) - { - switch (key) - { - case KEY_CTRL_UP: - MoveSelection(0, -1); - break; - case KEY_CTRL_DOWN: - MoveSelection(0, 1); - break; - case KEY_CTRL_LEFT: - MoveSelection(-1, 0); - break; - case KEY_CTRL_RIGHT: - MoveSelection(1, 0); - break; - case KEY_CTRL_EXE: - DoSelect(); - break; - } - // ClearScreen(); - DrawScreen(); - } + void HandleKey(const int key); }; #endif diff --git a/src/game.cpp b/src/game.cpp new file mode 100644 index 0000000..e72574a --- /dev/null +++ b/src/game.cpp @@ -0,0 +1,281 @@ +#include "game.hpp" + +const int DEAL_COUNT = 3; + +Game::Game() +{ + FillCardDeck(&pile); + pile.ShuffleCards(); + for (int i = 0; i < COLUMN_COUNT; i++) + { + for (int j = 0; j < i; j++) + { + columns[i].PushUnrevealed(pile.PopLeft()); + } + columns[i].PushLeft(pile.PopLeft()); + } +} + +void Game::DealToPile() +{ + if (pile.length() == 0) + { + Card c = pilediscard.PopLeft(); + while (c.NonNull()) + { + pile.PushLeft(c); + c = pilediscard.PopLeft(); + } + } + for (int i = 0; i < DEAL_COUNT; i++) + { + Card c = pile.PopLeft(); + if (!c.NonNull()) + break; + pilediscard.PushLeft(c); + } +} + +bool Game::TryMoveToColumn( + const int from, const int count, + const int to, const bool checkStacks) +{ + if (from < 0 || from >= COLUMN_COUNT || + to < 0 || to >= COLUMN_COUNT || + from == to || count <= 0) + return false; +#define srccol columns[from] +#define destcol columns[to] + Card src = srccol.PeekAt(count - 1); + if (!src.NonNull()) + return false; + if (checkStacks) + { + if (!CanStackOn(destcol.Peek(), src)) + return false; + } + srccol.MoveMany(count, &destcol); + srccol.Reveal(); + return true; +#undef srccol +#undef destcol +} + +bool Game::TryMovePileToColumn(const int column, const bool checkStacks) +{ + if (column < 0 || column >= COLUMN_COUNT) + return false; +#define destcol columns[column] + Card src = pilediscard.Peek(); + if (!src.NonNull()) + return false; + if (checkStacks) + { + if (!CanStackOn(destcol.Peek(), src)) + return false; + } + destcol.PushLeft(pilediscard.PopLeft()); + return true; +#undef destcol +} + +bool Game::CanStackOn(const Card base, const Card top) +{ + return top.NonNull() && + ((!base.NonNull() && top.GetRank() == 13) || + (base.GetColour() != top.GetColour() && + base.GetRank() == top.GetRank() + 1)); +} + +bool Game::CanStackOnCol(const Card top, const int column) +{ + if (column < 0 || column >= COLUMN_COUNT) + return false; + return CanStackOn(columns[column].Peek(), top); +} + +bool Game::CanStackOnSuit(const Card top, const Suit suit) +{ + if (suit < 0 || suit >= SUIT_COUNT) + return false; + if (top.GetSuit() != suit) + return false; + return suits[suit].Peek().GetRank() == top.GetRank() + 1; +} + +CardColumn *Game::GetSelectionColumn(const CardSelection sel) +{ + if (sel.col >= COLUMN_COUNT) + return nullptr; + if (sel.col >= 0) + return &columns[sel.col]; + return nullptr; +} + +CardLL *Game::GetSelectionLL(const CardSelection sel) +{ + if (sel.col >= 0) + return nullptr; + if (sel.col >= SUIT_COLUMN(0)) + return &suits[SUIT_FROM_COLUMN(sel.col)]; + if (sel.col == PILEDISCARD_COLUMN) + return &pilediscard; + if (sel.col == PILE_COLUMN) + return &pile; + return nullptr; +} + +bool Game::TryStackOnSel(CardSelection dest, CardSelection src) +{ + if (src.col == PILE_COLUMN && dest.col == PILEDISCARD_COLUMN) + { + DealToPile(); + return true; + } + if (src.col < PILEDISCARD_COLUMN || src.col >= COLUMN_COUNT) + return false; + if (dest.col < SUIT_COLUMN(0) || dest.col >= COLUMN_COUNT) + return false; + if (src.col == dest.col) + return false; + if (src.col < 0) + { + src.depth = 1; + CardLL *srcl = GetSelectionLL(src); + if (srcl == nullptr) + return false; + Card movecard = srcl->Peek(); + if (!movecard.NonNull()) + return false; + + if (dest.col < 0) + { + CardLL *destl = GetSelectionLL(dest); + if (destl == nullptr) + return false; + if (!CanStackOnSuit(movecard, (Suit)(dest.col + SUIT_COUNT))) + return false; + destl->PushLeft(srcl->PopLeft()); + return true; + } + else + { + CardColumn *destl = GetSelectionColumn(dest); + if (destl == nullptr) + return false; + if (!CanStackOnCol(movecard, dest.col)) + return false; + destl->PushLeft(srcl->PopLeft()); + return true; + } + } + else + { + int count = dest.col < 0 ? 1 : src.depth; + CardColumn *srcc = GetSelectionColumn(src); + if (srcc == nullptr) + return false; + Card movecard = srcc->PeekAt(count - 1); + if (!movecard.NonNull()) + return false; + + if (dest.col < 0) + { + CardLL *destl = GetSelectionLL(dest); + if (destl == nullptr) + return false; + if (!CanStackOnSuit(movecard, SUIT_FROM_COLUMN(dest.col))) + return false; + destl->PushLeft(srcc->PopLeft()); + return true; + } + else + { + CardColumn *destc = GetSelectionColumn(dest); + if (destc == nullptr) + return false; + if (!CanStackOnCol(movecard, dest.col)) + return false; + srcc->MoveMany(count, destc); + return true; + } + } +} + +bool Game::TryStackAuto(CardSelection src) +{ + if (src.col == PILE_COLUMN) + { + DealToPile(); + return true; + } + if (src.col == PILEDISCARD_COLUMN || + (src.col >= 0 && src.col < COLUMN_COUNT && src.depth == 1)) + { + Card c; + if (src.col == PILEDISCARD_COLUMN) + c = pilediscard.Peek(); + else + c = columns[src.col].Peek(); + // Works even for no card, because blank rank is 0, so ace - 1 = 0 + if (suits[c.GetSuit()].Peek().GetRank() == c.GetRank() - 1) + { + if (src.col == PILEDISCARD_COLUMN) + c = pilediscard.PopLeft(); + else + c = columns[src.col].PopLeft(); + suits[c.GetSuit()].PushLeft(c); + return true; + } + } + // if (src.col < 0 || src.col >= COLUMN_COUNT) + return false; +} + +int Game::WriteToArray(SaveData *const arr) const +{ + arr->value = SUIT_COUNT; + (arr + 1)->value = COLUMN_COUNT; + int length = 2; + length += pile.WriteToArray(arr + length); + length += pilediscard.WriteToArray(arr + length); + for (int i = 0; i < SUIT_COUNT; i++) + { + length += suits[i].WriteToArray(arr + length); + } + for (int i = 0; i < COLUMN_COUNT; i++) + { + length += columns[i].WriteToArray(arr + length); + } + return length; +} + +int Game::GetWriteLength() const +{ + int length = 2; + length += pile.GetWriteLength(); + length += pilediscard.GetWriteLength(); + for (int i = 0; i < SUIT_COUNT; i++) + length += suits[i].GetWriteLength(); + for (int i = 0; i < COLUMN_COUNT; i++) + length += columns[i].GetWriteLength(); + return length; +} + +int Game::ReadFromArray(const SaveData *const arr) +{ + if (arr->value != SUIT_COUNT || (arr + 1)->value != COLUMN_COUNT) + return -1; + int length = 2; + length += pile.ReadFromArray(arr + length); + length += pilediscard.ReadFromArray(arr + length); + for (int i = 0; i < SUIT_COUNT; i++) + { + length += suits[i].ReadFromArray(arr + length); + } + for (int i = 0; i < COLUMN_COUNT; i++) + { + length += columns[i].ReadFromArray(arr + length); + } + return length; +} diff --git a/src/game.hpp b/src/game.hpp index c398bfe..c662609 100644 --- a/src/game.hpp +++ b/src/game.hpp @@ -7,7 +7,7 @@ #ifndef GAME_H #define GAME_H -const int DEAL_COUNT = 3; +extern const int DEAL_COUNT; #define COLUMN_COUNT 7 class Game @@ -18,283 +18,28 @@ class Game CardLL suits[SUIT_COUNT]; CardColumn columns[COLUMN_COUNT]; - Game() - { - FillCardDeck(&pile); - pile.ShuffleCards(); - for (int i = 0; i < COLUMN_COUNT; i++) - { - for (int j = 0; j < i; j++) - { - columns[i].PushUnrevealed(pile.PopLeft()); - } - columns[i].PushLeft(pile.PopLeft()); - } - } + Game(); - void DealToPile() - { - if (pile.length() == 0) - { - Card c = pilediscard.PopLeft(); - while (c.NonNull()) - { - pile.PushLeft(c); - c = pilediscard.PopLeft(); - } - } - for (int i = 0; i < DEAL_COUNT; i++) - { - Card c = pile.PopLeft(); - if (!c.NonNull()) - break; - pilediscard.PushLeft(c); - } - } + void DealToPile(); bool TryMoveToColumn( const int from, const int count, - const int to, const bool checkStacks) - { - if (from < 0 || from >= COLUMN_COUNT || - to < 0 || to >= COLUMN_COUNT || - from == to || count <= 0) - return false; -#define srccol columns[from] -#define destcol columns[to] - Card src = srccol.PeekAt(count - 1); - if (!src.NonNull()) - return false; - if (checkStacks) - { - if (!CanStackOn(destcol.Peek(), src)) - return false; - } - srccol.MoveMany(count, &destcol); - srccol.Reveal(); - return true; -#undef srccol -#undef destcol - } + const int to, const bool checkStacks); + bool TryMovePileToColumn(const int column, const bool checkStacks); - bool TryMovePileToColumn(const int column, const bool checkStacks) - { - if (column < 0 || column >= COLUMN_COUNT) - return false; -#define destcol columns[column] - Card src = pilediscard.Peek(); - if (!src.NonNull()) - return false; - if (checkStacks) - { - if (!CanStackOn(destcol.Peek(), src)) - return false; - } - destcol.PushLeft(pilediscard.PopLeft()); - return true; -#undef destcol - } + static bool CanStackOn(const Card base, const Card top); + bool CanStackOnCol(const Card top, const int column); + bool CanStackOnSuit(const Card top, const Suit suit); - static bool CanStackOn(const Card base, const Card top) - { - return top.NonNull() && - ((!base.NonNull() && top.GetRank() == 13) || - (base.GetColour() != top.GetColour() && - base.GetRank() == top.GetRank() + 1)); - } + CardColumn *GetSelectionColumn(const CardSelection sel); + CardLL *GetSelectionLL(const CardSelection sel); - bool CanStackOnCol(const Card top, const int column) - { - if (column < 0 || column >= COLUMN_COUNT) - return false; - return CanStackOn(columns[column].Peek(), top); - } + bool TryStackOnSel(CardSelection dest, CardSelection src); + bool TryStackAuto(CardSelection src); - bool CanStackOnSuit(const Card top, const Suit suit) - { - if (suit < 0 || suit >= SUIT_COUNT) - return false; - if (top.GetSuit() != suit) - return false; - return suits[suit].Peek().GetRank() == top.GetRank() + 1; - } - - CardColumn *GetSelectionColumn(const CardSelection sel) - { - if (sel.col >= COLUMN_COUNT) - return nullptr; - if (sel.col >= 0) - return &columns[sel.col]; - return nullptr; - } - - CardLL *GetSelectionLL(const CardSelection sel) - { - if (sel.col >= 0) - return nullptr; - if (sel.col >= SUIT_COLUMN(0)) - return &suits[SUIT_FROM_COLUMN(sel.col)]; - if (sel.col == PILEDISCARD_COLUMN) - return &pilediscard; - if (sel.col == PILE_COLUMN) - return &pile; - return nullptr; - } - - bool TryStackOnSel(CardSelection dest, CardSelection src) - { - if (src.col == PILE_COLUMN && dest.col == PILEDISCARD_COLUMN) - { - DealToPile(); - return true; - } - if (src.col < PILEDISCARD_COLUMN || src.col >= COLUMN_COUNT) - return false; - if (dest.col < SUIT_COLUMN(0) || dest.col >= COLUMN_COUNT) - return false; - if (src.col == dest.col) - return false; - if (src.col < 0) - { - src.depth = 1; - CardLL *srcl = GetSelectionLL(src); - if (srcl == nullptr) - return false; - Card movecard = srcl->Peek(); - if (!movecard.NonNull()) - return false; - - if (dest.col < 0) - { - CardLL *destl = GetSelectionLL(dest); - if (destl == nullptr) - return false; - if (!CanStackOnSuit(movecard, (Suit)(dest.col + SUIT_COUNT))) - return false; - destl->PushLeft(srcl->PopLeft()); - return true; - } - else - { - CardColumn *destl = GetSelectionColumn(dest); - if (destl == nullptr) - return false; - if (!CanStackOnCol(movecard, dest.col)) - return false; - destl->PushLeft(srcl->PopLeft()); - return true; - } - } - else - { - int count = dest.col < 0 ? 1 : src.depth; - CardColumn *srcc = GetSelectionColumn(src); - if (srcc == nullptr) - return false; - Card movecard = srcc->PeekAt(count - 1); - if (!movecard.NonNull()) - return false; - - if (dest.col < 0) - { - CardLL *destl = GetSelectionLL(dest); - if (destl == nullptr) - return false; - if (!CanStackOnSuit(movecard, SUIT_FROM_COLUMN(dest.col))) - return false; - destl->PushLeft(srcc->PopLeft()); - return true; - } - else - { - CardColumn *destc = GetSelectionColumn(dest); - if (destc == nullptr) - return false; - if (!CanStackOnCol(movecard, dest.col)) - return false; - srcc->MoveMany(count, destc); - return true; - } - } - } - - bool TryStackAuto(CardSelection src) - { - if (src.col == PILE_COLUMN) - { - DealToPile(); - return true; - } - if (src.col == PILEDISCARD_COLUMN || - (src.col >= 0 && src.col < COLUMN_COUNT && src.depth == 1)) - { - Card c; - if (src.col == PILEDISCARD_COLUMN) - c = pilediscard.Peek(); - else - c = columns[src.col].Peek(); - // Works even for no card, because blank rank is 0, so ace - 1 = 0 - if (suits[c.GetSuit()].Peek().GetRank() == c.GetRank() - 1) - { - if (src.col == PILEDISCARD_COLUMN) - c = pilediscard.PopLeft(); - else - c = columns[src.col].PopLeft(); - suits[c.GetSuit()].PushLeft(c); - return true; - } - } - // if (src.col < 0 || src.col >= COLUMN_COUNT) - return false; - } - - int WriteToArray(SaveData *const arr) const - { - arr->value = SUIT_COUNT; - (arr + 1)->value = COLUMN_COUNT; - int length = 2; - length += pile.WriteToArray(arr + length); - length += pilediscard.WriteToArray(arr + length); - for (int i = 0; i < SUIT_COUNT; i++) - { - length += suits[i].WriteToArray(arr + length); - } - for (int i = 0; i < COLUMN_COUNT; i++) - { - length += columns[i].WriteToArray(arr + length); - } - return length; - } - - int GetWriteLength() const - { - int length = 2; - length += pile.GetWriteLength(); - length += pilediscard.GetWriteLength(); - for (int i = 0; i < SUIT_COUNT; i++) - length += suits[i].GetWriteLength(); - for (int i = 0; i < COLUMN_COUNT; i++) - length += columns[i].GetWriteLength(); - return length; - } - - int ReadFromArray(const SaveData *const arr) - { - if (arr->value != SUIT_COUNT || (arr + 1)->value != COLUMN_COUNT) - return -1; - int length = 2; - length += pile.ReadFromArray(arr + length); - length += pilediscard.ReadFromArray(arr + length); - for (int i = 0; i < SUIT_COUNT; i++) - { - length += suits[i].ReadFromArray(arr + length); - } - for (int i = 0; i < COLUMN_COUNT; i++) - { - length += columns[i].ReadFromArray(arr + length); - } - return length; - } + int WriteToArray(SaveData *const arr) const; + int GetWriteLength() const; + int ReadFromArray(const SaveData *const arr); }; #endif diff --git a/src/gen/imagedata.hpp b/src/gen/imagedata.hpp index d341de1..2d12fcb 100644 --- a/src/gen/imagedata.hpp +++ b/src/gen/imagedata.hpp @@ -1,8 +1,8 @@ #include "../imageclasses.hpp" #include "../card.hpp" -#ifndef IMAGEDATA_H -#define IMAGEDATA_H +#ifndef GEN_IMAGEDATA_H +#define GEN_IMAGEDATA_H #pragma region IMAGEDATA diff --git a/src/imageclasses.cpp b/src/imageclasses.cpp new file mode 100644 index 0000000..77ff09b --- /dev/null +++ b/src/imageclasses.cpp @@ -0,0 +1,36 @@ +#include "imageclasses.hpp" + +// color_t *const VRAM = (color_t *)GetVRAMAddress(); +color_t *VRAM; + +void Palette::Draw(int colour, color_t *dest) const +{ + // if (colour < 0 || colour >= len(colours)) + // return 0; + if (colour == transparent) + return; + *dest = colours[colour]; +} + +void Image::CopySprite(int dest_x, int dest_y, bool upsidedown) const +{ + const unsigned char *d = data; + color_t *v = VRAM + dest_y * LCD_WIDTH_PX + dest_x; + int vinc = upsidedown ? -1 : 1; + int vlineinc = vinc * (LCD_WIDTH_PX - width); + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x += palette->pixels_per_byte) + { + for (int dx = 0; dx < palette->pixels_per_byte && x + dx < width; dx++) + { + unsigned char pcolour = (*d) >> (8 - (dx + 1) * palette->width); + pcolour &= palette->bitmask; + palette->Draw(pcolour, v); + v += vinc; + } + d++; + } + v += vlineinc; + } +} diff --git a/src/imageclasses.hpp b/src/imageclasses.hpp index 66c9760..7cf5446 100644 --- a/src/imageclasses.hpp +++ b/src/imageclasses.hpp @@ -4,7 +4,7 @@ #define IMAGE_H // color_t *const VRAM = (color_t *)GetVRAMAddress(); -color_t *VRAM; +extern color_t *VRAM; struct Palette { @@ -14,14 +14,7 @@ struct Palette const int bitmask; const int transparent = -1; - void write(int colour, color_t *dest) const - { - // if (colour < 0 || colour >= len(colours)) - // return 0; - if (colour == transparent) - return; - *dest = colours[colour]; - } + void Draw(int colour, color_t *dest) const; }; struct Image @@ -30,28 +23,7 @@ struct Image const Palette *const palette; const int width, height; - void CopySprite(int dest_x, int dest_y, bool upsidedown = false) const - { - const unsigned char *d = data; - color_t *v = VRAM + dest_y * LCD_WIDTH_PX + dest_x; - int vinc = upsidedown ? -1 : 1; - int vlineinc = vinc * (LCD_WIDTH_PX - width); - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x += palette->pixels_per_byte) - { - for (int dx = 0; dx < palette->pixels_per_byte && x + dx < width; dx++) - { - unsigned char pcolour = (*d) >> (8 - (dx + 1) * palette->width); - pcolour &= palette->bitmask; - palette->write(pcolour, v); - v += vinc; - } - d++; - } - v += vlineinc; - } - } + void CopySprite(int dest_x, int dest_y, bool upsidedown = false) const; }; #endif diff --git a/src/imagedata.cpp b/src/imagedata.cpp new file mode 100644 index 0000000..1bfdea4 --- /dev/null +++ b/src/imagedata.cpp @@ -0,0 +1 @@ +#include "gen/imagedata.hpp" diff --git a/src/imagedata.hpp b/src/imagedata.hpp new file mode 100644 index 0000000..c4391ee --- /dev/null +++ b/src/imagedata.hpp @@ -0,0 +1,11 @@ +#include "card.hpp" + +#ifndef IMAGEDATA_H +#define IMAGEDATA_H + +void DrawCard(Card card, int x, int y); +void DrawCardBack(int x, int y); +void DrawCardShine(int x, int y); +void DrawBackground(int miny, int yrange, int minx, int xrange); + +#endif diff --git a/src/main.cpp b/src/main.cpp index 5683a4c..e6e04d0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,7 @@ #include "game.hpp" #include "controls.hpp" #include "save.hpp" +#include "imageclasses.hpp" void setup() { diff --git a/src/save.cpp b/src/save.cpp new file mode 100644 index 0000000..e9fc40d --- /dev/null +++ b/src/save.cpp @@ -0,0 +1,40 @@ +#include + +#include "save.hpp" + +unsigned char StateFileDir[] = "solitare"; +unsigned char StateFileItem[] = "state"; +#define StateFile StateFileDir, StateFileItem + +SaveData savebuffer[SAVESTATE_LEN]; + +bool SaveState(const Game *const g) +{ + MCS_CreateDirectory(StateFileDir); // can fail silently + if (MCS_WriteItem(StateFile, 0, (SAVESTATE_LEN / 4 + 1) * 4, 0) != 0) + return false; + + if (g->WriteToArray(savebuffer) < 0) + return false; + if (MCSOvwDat2(StateFile, SAVESTATE_LEN, savebuffer, 0) != 0) + return false; + return true; +} + +bool DeleteState() +{ + return MCSDelVar2(StateFile) == 0; +} + +bool ReadState(Game *const g) +{ + int len; + MCSGetDlen2(StateFile, &len); + if (len < SAVESTATE_LEN) + return false; + if (MCSGetData1(0, SAVESTATE_LEN, savebuffer) != 0) + return false; + if (g->ReadFromArray(savebuffer) < 0) + return false; + return true; +} diff --git a/src/save.hpp b/src/save.hpp index c54f91c..ea3508a 100644 --- a/src/save.hpp +++ b/src/save.hpp @@ -1,7 +1,3 @@ -#ifdef __sh__ -#include -#endif - #include "game.hpp" #include "savedata.hpp" @@ -17,45 +13,8 @@ COLUMN_COUNT * 2 COMMENT("each column has two lists") + \ 52 COMMENT("total number of cards - there will be no more pointers than this")) -#ifdef __sh__ - -unsigned char StateFileDir[] = "solitare"; -unsigned char StateFileItem[] = "state"; -#define StateFile StateFileDir, StateFileItem - -SaveData savebuffer[SAVESTATE_LEN]; - -bool SaveState(const Game *const g) -{ - MCS_CreateDirectory(StateFileDir); // can fail silently - if (MCS_WriteItem(StateFile, 0, (SAVESTATE_LEN / 4 + 1) * 4, 0) != 0) - return false; - - if (g->WriteToArray(savebuffer) < 0) - return false; - if (MCSOvwDat2(StateFile, SAVESTATE_LEN, savebuffer, 0) != 0) - return false; - return true; -} - -bool DeleteState() -{ - return MCSDelVar2(StateFile) == 0; -} - -bool ReadState(Game *const g) -{ - int len; - MCSGetDlen2(StateFile, &len); - if (len < SAVESTATE_LEN) - return false; - if (MCSGetData1(0, SAVESTATE_LEN, savebuffer) != 0) - return false; - if (g->ReadFromArray(savebuffer) < 0) - return false; - return true; -} - -#endif // __sh__ +bool SaveState(const Game *const g); +bool DeleteState(); +bool ReadState(Game *const g); #endif diff --git a/src/savedata.cpp b/src/savedata.cpp new file mode 100644 index 0000000..098e486 --- /dev/null +++ b/src/savedata.cpp @@ -0,0 +1,3 @@ +#include "savedata.hpp" + +SaveData::SaveData() { value = 0; } diff --git a/src/savedata.hpp b/src/savedata.hpp index 072da11..be8f5c6 100644 --- a/src/savedata.hpp +++ b/src/savedata.hpp @@ -10,7 +10,7 @@ union SaveData uint8_t value; Card card; - SaveData() { value = 0; } + SaveData(); }; #endif diff --git a/src/visuals.cpp b/src/visuals.cpp new file mode 100644 index 0000000..fd4853f --- /dev/null +++ b/src/visuals.cpp @@ -0,0 +1,27 @@ +#include "visuals.hpp" + +void calculate_squash( + const int unrevealed, const int revealed, + int *const unoffset, int *const reoffset) +{ + *unoffset = CARD_UNREVEALED_OFFSET_Y; + *reoffset = CARD_REVEALED_OFFSET_Y; +#define CALCSQ_MAX_Y (COLUMN_CARD_Y(unrevealed, *unoffset, revealed - 1, *reoffset) + CARD_HEIGHT) + while (*unoffset > 0) + { + if (CALCSQ_MAX_Y <= COLUMNS_BOTTOM_Y) + return; + *unoffset -= 1; + if (CALCSQ_MAX_Y <= COLUMNS_BOTTOM_Y) + return; + *reoffset -= 1; + } + while (*reoffset > 0) + { + if (CALCSQ_MAX_Y <= COLUMNS_BOTTOM_Y) + return; + *reoffset -= 1; + } + return; // unoffset = 0; reoffset = 0 +#undef CALCSQ_MAX_Y +} diff --git a/src/visuals.hpp b/src/visuals.hpp index 7f924e0..cb866a7 100644 --- a/src/visuals.hpp +++ b/src/visuals.hpp @@ -47,28 +47,6 @@ void calculate_squash( const int unrevealed, const int revealed, - int *const unoffset, int *const reoffset) -{ - *unoffset = CARD_UNREVEALED_OFFSET_Y; - *reoffset = CARD_REVEALED_OFFSET_Y; -#define CALCSQ_MAX_Y (COLUMN_CARD_Y(unrevealed, *unoffset, revealed - 1, *reoffset) + CARD_HEIGHT) - while (*unoffset > 0) - { - if (CALCSQ_MAX_Y <= COLUMNS_BOTTOM_Y) - return; - *unoffset -= 1; - if (CALCSQ_MAX_Y <= COLUMNS_BOTTOM_Y) - return; - *reoffset -= 1; - } - while (*reoffset > 0) - { - if (CALCSQ_MAX_Y <= COLUMNS_BOTTOM_Y) - return; - *reoffset -= 1; - } - return; // unoffset = 0; reoffset = 0 -#undef CALCSQ_MAX_Y -} + int *const unoffset, int *const reoffset); #endif diff --git a/tests/Makefile b/tests/Makefile index 0738386..4071f5f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -11,6 +11,12 @@ $(BUILD_DIR): $(BUILD_DIR)/%.o: %.cpp $(CXX) -MMD -MP -MF $(BUILD_DIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER) +SRC_DIR := ../src +SRC_PREFIX := src_ + +$(BUILD_DIR)/$(SRC_PREFIX)%.o: $(SRC_DIR)/%.cpp + $(CXX) -MMD -MP -MF $(BUILD_DIR)/$(SRC_PREFIX)$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER) + $(BUILD_DIR)/catch.o: catch2/catch_amalgamated.cpp $(CXX) -MMD -MP -MF $*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER) @@ -21,9 +27,14 @@ EXECUTABLE := runtests endif SOURCES := . -CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) - -OFILES := $(addprefix $(BUILD_DIR)/,$(CPPFILES:.cpp=.o)) $(BUILD_DIR)/catch.o +# Test .cpp files +TESTCPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +# .cpp files in ../src/ +SRCCPPFILES = cardclasses.cpp game.cpp savedata.cpp + +OFILES := $(addprefix $(BUILD_DIR)/,$(TESTCPPFILES:.cpp=.o)) +OFILES += $(addprefix $(BUILD_DIR)/$(SRC_PREFIX),$(SRCCPPFILES:.cpp=.o)) +OFILES += $(BUILD_DIR)/catch.o DEPENDS := $(OFILES:.o=.d) $(EXECUTABLE): $(OFILES) diff --git a/tests/card.hpp b/tests/card.cpp similarity index 100% rename from tests/card.hpp rename to tests/card.cpp diff --git a/tests/cardll.hpp b/tests/cardll.cpp similarity index 100% rename from tests/cardll.hpp rename to tests/cardll.cpp diff --git a/tests/game.hpp b/tests/game.cpp similarity index 100% rename from tests/game.hpp rename to tests/game.cpp diff --git a/tests/tests.cpp b/tests/tests.cpp deleted file mode 100644 index d1bb07d..0000000 --- a/tests/tests.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "card.hpp" -#include "cardll.hpp" -#include "game.hpp"