Age | Commit message (Collapse) | Author |
|
Previously, calling `.right()` on a `Gfx::Rect` would return the last
column's coordinate still inside the rectangle, or `left + width - 1`.
This is called 'endpoint inclusive' and does not make a lot of sense for
`Gfx::Rect<float>` where a rectangle of width 5 at position (0, 0) would
return 4 as its right side. This same problem exists for `.bottom()`.
This changes `Gfx::Rect` to be endpoint exclusive, which gives us the
nice property that `width = right - left` and `height = bottom - top`.
It enables us to treat `Gfx::Rect<int>` and `Gfx::Rect<float>` exactly
the same.
All users of `Gfx::Rect` have been updated accordingly.
|
|
The graphics directory is a more suitable home for game assets.
Also, move card backs into their own subfolder in preparation for a
themes subfolder for card fronts.
|
|
|
|
This class had slightly confusing semantics and the added weirdness
doesn't seem worth it just so we can say "." instead of "->" when
iterating over a vector of NNRPs.
This patch replaces NonnullRefPtrVector<T> with Vector<NNRP<T>>.
|
|
The only remaining clients of this API are specific to bitmap fonts and
editing thereof.
|
|
This function returns a card stack that we might want to drop a card on,
so intuitively it should be a mutating function.
|
|
Having an alias function that only wraps another one is silly, and
keeping the more obvious name should flush out more uses of deprecated
strings.
No behavior change.
|
|
Those don't have any non-try counterpart, so we might as well just omit
it.
|
|
|
|
...and CardGame::pick_up_cards_from_stack() which is its only caller.
|
|
Also, be smarter about appending cards to the deck: we can
unchecked_append them to the deck, since we already ensured enough
capacity earlier.
|
|
|
|
Very few of these calls can propagate their errors yet, but one step at
a time. :^)
|
|
`a.move_to_stack(b)` sounded too much like it moves a's cards to b, when
it actually moves b's cards to a.
|
|
And while we're at it, handle the CardStack allocation (and failure
thereof) internally.
|
|
For example, in Solitaire, the vertical normal stacks cover the suit of
all but the topmost card in the stack. To see the suit of covered cards
the user currently has to move the cards on top of them out of the way.
This adds an API for games to set a card at a location to be previewed,
which will draw that card on top of all other cards without moving it.
|
|
Instead of indicating which individual cards should be highlighted, card
games now indicate which stack is highlighted. This lets the stack draw
empty stacks with a highlight (e.g. the Foundation stack in Solitaire).
If the stack is non-empty, the stack can delegate highlighting to the
top-most card.
|
|
Currently, the outside of the card highlight has rounded corners, but
the inside has square corners. It looks a bit more polished if they are
both rounded.
|
|
This is a useful shortcut to open the settings from within the game
rather than having to go through the system menu.
|
|
For example, in Solitaire, when dragging a card around, it's common for
other implementations to highlight the card underneath the dragged card
if that other card is a valid drop target. This implementation will draw
a rounded rectangle within the edges of the highlighted card, using a
rudimentary complementary color of the board background color.
|
|
This keeps some overloads that accept ints to avoid adding calls to
.to_type<float>() all over the place.
|
|
|
|
This is just two ints or 8 bytes or the size of the reference on
x86_64 or AArch64.
|
|
Gfx::Color is always 4 bytes (it's just a wrapper over u32) it's less
work just to pass the color directly.
This also updates IPCCompiler to prevent from generating
Gfx::Color const &, which makes replacement easier.
|
|
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
|
|
Otherwise, we end up propagating those dependencies into targets that
link against that library, which creates unnecessary link-time
dependencies.
Also included are changes to readd now missing dependencies to tools
that actually need them.
|
|
Even though the toolchain implicitly links against -lc, it does not know
where it should get LibC from except for the sysroot. In the case of
Clang this causes it to pick up the LibC stub instead, which might be
slightly outdated and feature missing symbols.
This is currently not an issue that manifests because we pass through
the dependency on LibC and other libraries by accident, which causes
CMake to link against the LibC target (instead of just the library),
and thus points the linker at the build output directory.
Since we are looking to fix that in the upcoming commits, let's make
sure that everything will still be able to find the proper LibC first.
|
|
This was only used for asking the stack if it is the one we are moving
cards from. We now have a better way to do that, by comparing against
`CardGame::moving_cards_source_stack()`, which doesn't require manually
telling a stack that it is/isn't focused.
|
|
Previously, dropping a card that overlapped multiple stacks that could
accept it, would always choose the stack that came first in the stacks
list, usually the leftmost one. This would feel very odd if the card
was only slightly overlapping the left stack, and 90% over the right
one. So now, we keep looking for closer stacks even once we've found a
valid one.
There may be an option that feels even better, based on the position of
the card being dragged and the card on top of the stack we're dropping
onto, but this already fixes the issue and feels very nice. :^)
|
|
Solitaire and Spider have almost identical code for dragging cards from
one stack to another, so it makes sense to move that here. But using
the term "moving" for them, instead of "focused" which (to me at least)
was not clear what it meant.
|
|
As part of this, made a const overload for `Card::rect()`. We need the
non-const one too as it's used for modifying the position of a card
that's being dragged. I plan on changing that soon but we'll see.
|
|
|
|
|
|
And while I'm at it, clarify the name of `associated_stack` to
`covered_stack`. It's used in exactly one way, so we can make the code
clearer by giving it a less generic name.
|
|
"Draw" is already a card-game term so using it for graphics was
confusing me a lot!
|
|
Just moving some code around really.
|
|
`create_standard_deck()` is the usual 52-card deck, but more custom
setups (such as Spider's multiples-of-one-suit) can be created by
passing suit counts to `create_deck()`.
|
|
This was giving wonky results with images that do not fill the entire
card - and it's also unnecessary, since the Buggie image we have been
using, and the two I will be adding, are all small enough to not need
scaling anyway. :^)
|
|
`CardPainter::set_background_image_path()` immediately repaints the card
back and inverted card back bitmaps if they exist, so users just need
to `update()` that part of the screen. This is handled automatically by
`CardGame`, but other users will have to do this manually.
|
|
Instead of each card being responsible for painting its own bitmaps, we
now have a CardPainter which is responsible for this. It paints a given
card the first time it is requested, and then re-uses that bitmap when
requested in the future. This saves memory for duplicate cards (such as
in Spider where several sets of the same suit are used) or unused ones
(for example, the inverted cards which are only used by Hearts). It
also means we don't throw away bitmaps and then re-create identical
ones when starting a new game.
We get some nice memory savings from this:
| | Before | After | Before (Virtual) | After (Virtual) |
|:----------|---------:|---------:|-----------------:|----------------:|
| Hearts | 12.2 MiB | 9.3 MiB | 25.1 MiB | 22.2 MiB |
| Spider | 12.1 MiB | 10.1 MiB | 29.2 MiB | 22.9 MiB |
| Solitaire | 16.4 MiB | 9.0 MiB | 25.0 MiB | 21.9 MiB |
All these measurements taken from x86_64 build, from a fresh launch of
each game after the animation has finished, but without making any
moves. The Hearts value will go up once inverted cards start being
requested.
|
|
Because `card->value() == 11` is a lot less clear than `card->rank() ==
Cards::Rank::Queen`, and also safer.
Put this, along with the `Suit` enum, in the `Cards` namespace directly
instead of inside `Cards::Card`. Slightly less typing that way.
|
|
For now, the only feature of this is that it sets the background colour
from the `Games::Cards::BackgroundColor` config value. Later, other
card game configuration and shared behaviour can go here, to save
duplicating it in each game.
|
|
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).
No functional changes.
|
|
|
|
|
|
Playing cards have a `suit` such as `hearts`/`diamonds`, not a
`type`. Make the internal naming consistent with the way playing cards
are typically named.
|
|
|
|
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cother-other-default-operation-rules
"The compiler is more likely to get the default semantics right and
you cannot implement these functions better than the compiler."
|
|
`CharacterBitmap` instances are generated at run-time and put on the
heap, but they can be created in a `constexpr` context and stored in
static memory.
Also, remove additional `width` and `height` `static` values in favor
of using the `constexpr` member functions of `CharacterBitmap`.
These changes also include the removal of some initialization code
which tests if the `CharacterBitmap` is created since it is always
created and removes function-local `static` values which cause
run-time branches to ensure it is initialized each time the function
is called.
|
|
This isn't a complete conversion to ErrorOr<void>, but a good chunk.
The end goal here is to propagate buffer allocation failures to the
caller, and allow the use of TRY() with formatting functions.
|