diff options
-rw-r--r-- | sol.c | 116 |
1 files changed, 94 insertions, 22 deletions
diff --git a/sol.c b/sol.c index 3a289b9..f0d9616 100644 --- a/sol.c +++ b/sol.c @@ -106,19 +106,47 @@ enum { + StackMarginY, }; -static SDL_Renderer *render; -static SDL_Texture *textures[Cards_Count]; +struct Item { + SDL_Rect rect; + uint tex; + Sint8 card; +}; + +struct Layout { + uint len; + struct Item items[52]; +}; + +static void layoutClear(struct Layout *list) { + list->len = 0; +} +static void layoutPush(struct Layout *list, struct Item item) { + assert(list->len < 52); + list->items[list->len++] = item; +} + +static struct { + struct Layout base; + struct Layout main; + struct Layout drag; + struct Item dragItem; +} layout; static uint cardBack = Cards_Back1; -static void renderCard(const SDL_Rect *rect, Sint8 card) { - uint i = (card > 0 ? card : cardBack); - SDL_RenderCopy(render, textures[i], NULL, rect); +static void layoutCard(struct Layout **list, SDL_Rect *rect, Sint8 card) { + if (card == layout.dragItem.card) { + *list = &layout.drag; + *rect = layout.dragItem.rect; + } + struct Item item = { *rect, (card > 0 ? card : cardBack), card }; + layoutPush(*list, item); } -static void renderStack(SDL_Rect *rect, const struct Stack *stack, uint depth) { +static void layoutStack(SDL_Rect *rect, const struct Stack *stack, uint depth) { + struct Layout *list = &layout.main; for (uint i = 0; i < stack->len; ++i) { - renderCard(rect, stack->cards[i]); + layoutCard(&list, rect, stack->cards[i]); if (i > 0 && i % (depth / 3) == 0) { rect->x += StackDeltaX; rect->y += StackDeltaY; @@ -126,39 +154,43 @@ static void renderStack(SDL_Rect *rect, const struct Stack *stack, uint depth) { } } -static void renderStock(void) { +static void layoutStock(void) { SDL_Rect rect = { StockX, StockY, Cards_Width, Cards_Height }; - SDL_RenderCopy(render, textures[Cards_O], NULL, &rect); - renderStack(&rect, &stacks[Stock], 24); + struct Item item = { rect, Cards_O, 0 }; + layoutPush(&layout.base, item); + layoutStack(&rect, &stacks[Stock], 24); } -static void renderWaste(void) { +static void layoutWaste(void) { SDL_Rect rect = { WasteX, WasteY, Cards_Width, Cards_Height }; - renderStack(&rect, &stacks[Waste1], 24); + layoutStack(&rect, &stacks[Waste1], 24); + struct Layout *list = &layout.main; for (uint i = 0; i < stacks[Waste3].len; ++i) { - renderCard(&rect, stacks[Waste3].cards[i]); + layoutCard(&list, &rect, stacks[Waste3].cards[i]); rect.x += Waste3DeltaX; rect.y += Waste3DeltaY; } } -static void renderFoundations(void) { +static void layoutFoundations(void) { SDL_Rect base = { FoundationX, FoundationY, Cards_Width, Cards_Height }; for (uint i = Foundation1; i <= Foundation4; ++i) { + struct Item item = { base, Cards_Empty, 0 }; + layoutPush(&layout.base, item); SDL_Rect rect = base; - SDL_RenderCopy(render, textures[Cards_Empty], NULL, &rect); - renderStack(&rect, &stacks[i], 13); + layoutStack(&rect, &stacks[i], 13); base.x += Cards_Width + StackMarginX; } } -static void renderTableau(void) { +static void layoutTableau(void) { SDL_Rect base = { TableauX, TableauY, Cards_Width, Cards_Height }; for (uint i = Tableau1; i <= Tableau7; ++i) { + struct Layout *list = &layout.main; SDL_Rect rect = base; for (uint j = 0; j < stacks[i].len; ++j) { Sint8 card = stacks[i].cards[j]; - renderCard(&rect, card); + layoutCard(&list, &rect, card); rect.x += TableauDeltaX; rect.y += (card > 0 ? TableauDeltaYFront : TableauDeltaYBack); } @@ -166,6 +198,19 @@ static void renderTableau(void) { } } +static SDL_Renderer *render; +static SDL_Texture *textures[Cards_Count]; + +static void renderLayout(const struct Layout *list) { + for (uint i = 0; i < list->len; ++i) { + SDL_RenderCopy( + render, + textures[list->items[i].tex], + NULL, &list->items[i].rect + ); + } +} + static void err(const char *prefix) { fprintf(stderr, "%s: %s\n", prefix, SDL_GetError()); exit(EXIT_FAILURE); @@ -238,13 +283,40 @@ int main(void) { } } + if (event.type == SDL_MOUSEBUTTONDOWN) { + struct SDL_Point point = { event.button.x, event.button.y }; + for (uint i = layout.main.len - 1; i < layout.main.len; --i) { + if (SDL_PointInRect(&point, &layout.main.items[i].rect)) { + layout.dragItem = layout.main.items[i]; + break; + } + } + } + + if (event.type == SDL_MOUSEBUTTONUP) { + layout.dragItem.card = 0; + } + + if (event.type == SDL_MOUSEMOTION && event.motion.state) { + layout.dragItem.rect.x += event.motion.xrel; + layout.dragItem.rect.y += event.motion.yrel; + } + + layoutClear(&layout.base); + layoutClear(&layout.main); + layoutClear(&layout.drag); + + layoutStock(); + layoutWaste(); + layoutFoundations(); + layoutTableau(); + SDL_SetRenderDrawColor(render, 0x00, 0xAA, 0x55, 0xFF); SDL_RenderClear(render); - renderStock(); - renderWaste(); - renderFoundations(); - renderTableau(); + renderLayout(&layout.base); + renderLayout(&layout.main); + renderLayout(&layout.drag); SDL_RenderPresent(render); } |