diff options
Diffstat (limited to '')
-rw-r--r-- | layout.h | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/layout.h b/layout.h new file mode 100644 index 0000000..cbff6df --- /dev/null +++ b/layout.h @@ -0,0 +1,110 @@ +/* Copyright (C) 2019 C. McEnroe <june@causal.agency> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifndef LAYOUT_H +#define LAYOUT_H + +#include <SDL_rect.h> +#include <assert.h> + +#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 |