diff --git a/.clang-format b/.clang-format index 5bc0fca..74e70ad 100644 --- a/.clang-format +++ b/.clang-format @@ -52,3 +52,5 @@ SpacesInLineCommentPrefix: PenaltyReturnTypeOnItsOwnLine: 99999999 AlignEscapedNewlines: Left + +BracedInitializerIndentWidth: 0 \ No newline at end of file diff --git a/include/selection_grid.h b/include/selection_grid.h index 40ea950..2294a38 100644 --- a/include/selection_grid.h +++ b/include/selection_grid.h @@ -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 diff --git a/source/game.c b/source/game.c index 481ad79..77ba055 100644 --- a/source/game.c +++ b/source/game.c @@ -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)) { diff --git a/source/selection_grid.c b/source/selection_grid.c index 1cb1012..1a9d4bf 100644 --- a/source/selection_grid.c +++ b/source/selection_grid.c @@ -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); } } - -