/* Copyright (C) 2019 C. McEnroe * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #ifndef LAYOUT_H #define LAYOUT_H #include #include #include "stack.h" #ifndef LAYOUT_CAP #define LAYOUT_CAP 64 #endif typedef unsigned uint; struct Item { SDL_Rect rect; Card card; }; struct List { uint len; struct Item items[LAYOUT_CAP]; }; static inline void listClear(struct List *list) { list->len = 0; } static inline void listPush(struct List *list, const struct SDL_Rect *rect, Card card) { assert(list->len < LAYOUT_CAP); struct Item item = { *rect, card }; list->items[list->len++] = item; } static inline struct Item *listFind(struct List *list, const SDL_Point *point) { for (uint i = list->len - 1; i < list->len; --i) { if (SDL_PointInRect(point, &list->items[i].rect)) { return &list->items[i]; } } return NULL; } struct Layout { struct List main; struct List drag; struct Item dragItem; }; static inline void layoutClear(struct Layout *layout) { listClear(&layout->main); listClear(&layout->drag); } struct Style { uint increment; int deltaXBack; int deltaYBack; int deltaXFront; int deltaYFront; }; enum { SquareIncrement = 24 / 3, SquareDeltaX = 2, SquareDeltaY = 1, }; static const struct Style Flat = { 1, 0, 0, 0, 0 }; static const struct Style Square = { SquareIncrement, SquareDeltaX, SquareDeltaY, SquareDeltaX, SquareDeltaY, }; static inline void layoutStack( struct Layout *layout, SDL_Rect *rect, const struct Stack *stack, const struct Style *style ) { struct List *list = &layout->main; for (uint i = 0; i < stack->len; ++i) { Card card = stack->cards[i]; if (card == layout->dragItem.card) { list = &layout->drag; *rect = layout->dragItem.rect; } listPush(list, rect, card); if ((i + 1) % style->increment == 0) { rect->x += (card > 0 ? style->deltaXFront : style->deltaXBack); rect->y += (card > 0 ? style->deltaYFront : style->deltaYBack); } } } #endif