Add swapping order of Owned Jokers (#258)

* swap Jokers

* Hide score properly

* add key_released to inputs triggering selection_grid process input

* format code

* Add suggestions and bug fixes from @MeirGavish

* Add comment

* format selection_grid

* toto

* format

* format

* Turned clang-format off for selection grid rows

* revert reroll bug fix, already adressed

* format selection_grid.c

* Move conditions around in game.c

* typo

* Attempt at fixing braced initializer indent format

---------

Co-authored-by: MathisMartin31 <mathis.martin31@gmail.com>
Co-authored-by: MeirGavish <meir.gavish@gmail.com>
This commit is contained in:
Geralt
2025-12-07 11:58:50 +01:00
committed by GitHub
parent a82bd671de
commit bf66f96844
4 changed files with 89 additions and 48 deletions
+2
View File
@@ -52,3 +52,5 @@ SpacesInLineCommentPrefix:
PenaltyReturnTypeOnItsOwnLine: 99999999
AlignEscapedNewlines: Left
BracedInitializerIndentWidth: 0
+2 -2
View File
@@ -15,14 +15,14 @@ typedef void (*RowOnSelectionChangedFunc)(SelectionGrid* selection_grid, int row
typedef int (*RowGetSizeFunc)();
// Called for any non-directional key hit
// The key will not be passed, the function will have to check key_hit() etc. for the key it wants to check
typedef void (*RowOnKeyHitFunc)(SelectionGrid* selection_grid, Selection* selection);
typedef void (*RowOnKeyTransitFunc)(SelectionGrid* selection_grid, Selection* selection);
struct SelectionGridRow
{
int row_idx;
RowGetSizeFunc get_size;
RowOnSelectionChangedFunc on_selection_changed;
RowOnKeyHitFunc on_key_hit;
RowOnKeyTransitFunc on_key_transit;
};
struct SelectionGrid
+59 -20
View File
@@ -241,7 +241,7 @@ static bool check_and_score_joker_for_event(
);
static int calculate_interest_reward(void);
static void game_over_anim_frame(void);
static void shop_reroll_row_on_key_hit(SelectionGrid* selection_grid, Selection* selection);
static void shop_reroll_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection);
static void shop_reroll_row_on_selection_changed(
SelectionGrid* selection_grid,
int row_idx,
@@ -255,9 +255,9 @@ static void shop_top_row_on_selection_changed(
const Selection* prev_selection,
const Selection* new_selection
);
static void shop_top_row_on_key_hit(SelectionGrid* selection_grid, Selection* selection);
static void shop_top_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection);
static int shop_top_row_get_size(void);
static void jokers_sel_row_on_key_hit(SelectionGrid* selection_grid, Selection* selection);
static void jokers_sel_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection);
static void jokers_sel_row_on_selection_changed(
SelectionGrid* selection_grid,
int row_idx,
@@ -389,9 +389,9 @@ static StateInfo state_info[] = {
};
SelectionGridRow shop_selection_rows[] = {
{0, jokers_sel_row_get_size, jokers_sel_row_on_selection_changed, jokers_sel_row_on_key_hit },
{1, shop_top_row_get_size, shop_top_row_on_selection_changed, shop_top_row_on_key_hit },
{2, shop_reroll_row_get_size, shop_reroll_row_on_selection_changed, shop_reroll_row_on_key_hit}
{0, jokers_sel_row_get_size, jokers_sel_row_on_selection_changed, jokers_sel_row_on_key_transit },
{1, shop_top_row_get_size, shop_top_row_on_selection_changed, shop_top_row_on_key_transit },
{2, shop_reroll_row_get_size, shop_reroll_row_on_selection_changed, shop_reroll_row_on_key_transit}
};
static const Selection SHOP_INIT_SEL = {-1, 1};
@@ -3675,11 +3675,16 @@ static void jokers_sel_row_on_selection_changed(
const Selection* new_selection
)
{
// swap Jokers if the A button is held down and all Jokers are on the same row
bool swapping =
key_is_down(SELECT_CARD) && new_selection->y == row_idx && prev_selection->y == row_idx;
if (prev_selection->y == row_idx)
{
JokerObject* joker_object =
(JokerObject*)list_get_at_idx(&_owned_jokers_list, prev_selection->x);
if (joker_object != NULL)
// Don't change focus from current Joker if swapping
if (joker_object != NULL && !swapping)
{
erase_price_under_sprite_object(joker_object->sprite_object);
sprite_object_set_focus(joker_object->sprite_object, false);
@@ -3692,13 +3697,31 @@ static void jokers_sel_row_on_selection_changed(
(JokerObject*)list_get_at_idx(&_owned_jokers_list, new_selection->x);
if (joker_object != NULL)
{
sprite_object_set_focus(joker_object->sprite_object, true);
print_price_under_sprite_object(
joker_object->sprite_object,
joker_get_sell_value(joker_object->joker)
);
if (!swapping)
{
sprite_object_set_focus(joker_object->sprite_object, true);
}
// If we land on this row while the A button is being held, we are in swapping mode
// This means that we need to hide the price, whether we were already
// on this row or if we come from another
if (!key_is_down(SELECT_CARD))
{
print_price_under_sprite_object(
joker_object->sprite_object,
joker_get_sell_value(joker_object->joker)
);
}
}
}
if (swapping)
{
list_swap(
&_owned_jokers_list,
(unsigned int)prev_selection->x,
(unsigned int)new_selection->x
);
}
}
static inline void joker_start_discard_animation(JokerObject* joker_object)
@@ -3723,14 +3746,30 @@ static inline void game_sell_joker(int joker_idx)
joker_start_discard_animation(joker_object);
}
static void jokers_sel_row_on_key_hit(SelectionGrid* selection_grid, Selection* selection)
static void jokers_sel_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection)
{
if (!key_hit(SELL_KEY))
return;
JokerObject* joker_object = (JokerObject*)list_get_at_idx(&_owned_jokers_list, selection->x);
if (joker_object != NULL)
{
if (key_hit(SELECT_CARD))
{
erase_price_under_sprite_object(joker_object->sprite_object);
}
else if (key_released(SELECT_CARD))
{
print_price_under_sprite_object(
joker_object->sprite_object,
joker_get_sell_value(joker_object->joker)
);
}
}
game_sell_joker(selection->x);
// Move the selection away from the jokers so it doesn't point to an invalid place
selection_grid_move_selection_vert(selection_grid, SCREEN_DOWN);
if (key_hit(SELL_KEY))
{
game_sell_joker(selection->x);
// Move the selection away from the jokers so it doesn't point to an invalid place
selection_grid_move_selection_vert(selection_grid, SCREEN_DOWN);
}
}
// Shop input
@@ -3758,7 +3797,7 @@ static inline void game_shop_buy_joker(int shop_joker_idx)
list_remove_at_idx(&_shop_jokers_list, shop_joker_idx); // Remove the joker from the shop
}
static void shop_top_row_on_key_hit(SelectionGrid* selection_grid, Selection* selection)
static void shop_top_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection)
{
if (!key_hit(SELECT_CARD))
return;
@@ -3914,7 +3953,7 @@ static inline void game_shop_reroll(int* reroll_cost)
);
}
static void shop_reroll_row_on_key_hit(SelectionGrid* selection_grid, Selection* selection)
static void shop_reroll_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection)
{
if (!key_hit(SELECT_CARD))
{
+26 -26
View File
@@ -1,57 +1,56 @@
#include "selection_grid.h"
static void selection_grid_process_directional_input(SelectionGrid *selection_grid)
static void selection_grid_process_directional_input(SelectionGrid* selection_grid)
{
int horz_tri_input = bit_tribool(key_hit(KEY_ANY), KI_RIGHT, KI_LEFT);
if (horz_tri_input != 0)
{
selection_grid_move_selection_horz(selection_grid, horz_tri_input);
/* Avoid handling both vertical and horizontal input at the same time,
/* Avoid handling both vertical and horizontal input at the same time,
* it creates all sorts of difficult edge cases.
*/
return;
return;
}
int vert_tri_input = bit_tribool(key_hit(KEY_ANY), KI_DOWN, KI_UP);
if (vert_tri_input != 0)
{
selection_grid_move_selection_vert(selection_grid, vert_tri_input);
}
}
void selection_grid_move_selection_horz(SelectionGrid* selection_grid,
int direction_tribool)
void selection_grid_move_selection_horz(SelectionGrid* selection_grid, int direction_tribool)
{
Selection new_selection = selection_grid->selection;
new_selection.x += direction_tribool;
if( selection_grid->selection.y >= 0
&& selection_grid->selection.y < selection_grid->num_rows
&& new_selection.x >= 0
&& new_selection.x < selection_grid->rows[new_selection.y].get_size())
if (selection_grid->selection.y >= 0 &&
selection_grid->selection.y < selection_grid->num_rows && new_selection.x >= 0 &&
new_selection.x < selection_grid->rows[new_selection.y].get_size())
{
selection_grid->rows[new_selection.y].on_selection_changed(selection_grid, new_selection.y, &selection_grid->selection, &new_selection);
selection_grid->rows[new_selection.y].on_selection_changed(
selection_grid,
new_selection.y,
&selection_grid->selection,
&new_selection
);
selection_grid->selection = new_selection;
}
}
void selection_grid_move_selection_vert(SelectionGrid *selection_grid, int direction_tribool)
void selection_grid_move_selection_vert(SelectionGrid* selection_grid, int direction_tribool)
{
Selection selection = selection_grid->selection;
Selection new_selection = selection;
new_selection.y += direction_tribool;
if (new_selection.y >= 0
&& new_selection.y < selection_grid->num_rows)
if (new_selection.y >= 0 && new_selection.y < selection_grid->num_rows)
{
int new_row_size = selection_grid->rows[new_selection.y].get_size();
if (new_row_size <= 0)
return;
return;
if (selection.x >= new_row_size)
{
// TODO: Maintain relative horizontal position
@@ -60,14 +59,16 @@ void selection_grid_move_selection_vert(SelectionGrid *selection_grid, int direc
}
if (selection.y >= 0 && selection.y < selection_grid->num_rows)
{
selection_grid->rows[selection.y].on_selection_changed(selection_grid, selection.y, &selection, &new_selection);
selection_grid->rows[selection.y]
.on_selection_changed(selection_grid, selection.y, &selection, &new_selection);
}
selection_grid->rows[new_selection.y].on_selection_changed(selection_grid, new_selection.y, &selection, &new_selection);
selection_grid->rows[new_selection.y]
.on_selection_changed(selection_grid, new_selection.y, &selection, &new_selection);
selection_grid->selection = new_selection;
}
}
void selection_grid_process_input(SelectionGrid *selection_grid)
void selection_grid_process_input(SelectionGrid* selection_grid)
{
if (selection_grid == NULL || selection_grid->rows == NULL)
return;
@@ -75,11 +76,10 @@ void selection_grid_process_input(SelectionGrid *selection_grid)
selection_grid_process_directional_input(selection_grid);
u32 non_directional_key = KEY_ANY & ~KEY_DIR;
if (key_hit(non_directional_key))
if (key_transit(non_directional_key))
{
Selection* selection = &selection_grid->selection; // To make the next line shorter and more readable
selection_grid->rows[selection->y].on_key_hit(selection_grid, selection);
// To make the next line shorter and more readable
Selection* selection = &selection_grid->selection;
selection_grid->rows[selection->y].on_key_transit(selection_grid, selection);
}
}