diff --git a/README.md b/README.md index 0270f47..1e8f868 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,26 @@ # Balatro GBA This is an attempt to recreate the game 'Balatro' as accurately as possible, including all of the visual effects that make Balatro feel satisfying to play. -This port is strictly limited to the content that was available in the January 2024 Balatro Steam demo. -### **Disclaimer: This project is NOT endorsed or supported by Playstack or LocalThunk** -#### This project is solely aimed to recreate Balatro's old demo on the Game Boy Advance and is not meant to infringe or draw sales away from the full game's release or any of the established works by Playstack and LocalThunk. All rights are reserved to their respective holders. +This port is strictly limited in content to a minimal version of Balatro and will not recreate the full game. +### **Disclaimer: This project is NOT endorsed by or affiliated with Playstack or LocalThunk** +#### This is a non-profit community fan project solely aimed to recreate a minimal version of Balatro on the Game Boy Advance as a tribute to the full Balatro and is not meant to infringe or draw sales away from the full game's release or any of the established works by Playstack and LocalThunk. +#### All rights are reserved to their respective holders. +This version is meant for people who already own and know the official full game. + +Buy the official full version + +[Balatro on Steam](https://store.steampowered.com/app/2379780/Balatro/) + +[Balatro on Google Play](https://play.google.com/store/apps/details?id=com.playstack.balatro.android) + +[Balatro on Apple App Store](https://apps.apple.com/us/app/balatro/id6502453075) + +[Balatro on Switch](https://www.nintendo.com/us/store/products/balatro-switch/) + +[Balatro on PlayStation Store](https://store.playstation.com/en-us/concept/10010334) + +[Balatro on Xbox](https://www.xbox.com/games/store/balatro/9PK087LNGJC5) + ![Example](https://github.com/cellos51/balatro-gba/blob/main/example.gif) # **Build Instructions:** @@ -22,7 +39,7 @@ Example: `cd '/home/user/OneDrive/Documents/balatro-gba` or something like this. 9. After it completes, navigate through the `build` directory in the project folder and look for `balatro-gba.gba` and load it on an emulator or flashcart. ## **-Linux-** -[Not Available] +[No Instructions Available] ### **Common Issues:** 1. **When I drag the folder into the window and press enter, it doesn't work!** @@ -36,5 +53,3 @@ Example: `cd '/home/user/OneDrive/Documents/balatro-gba` or something like this. 5. **It says I don't have `Git` or `Make` installed!** -Use `pacman -S git` or `pacman -S make` although it should already be installed if you followed the instructions correctly. -#### Purchasing the official game is highly recommended and almost mandatory in order for this project to have a chance of staying up due to copyright issues and potential legal action. -**Purchase the Steam Version here: https://store.steampowered.com/app/2379780/Balatro/** diff --git a/graphics/deck_gfx.png b/graphics/deck_gfx.png index 1b77526..98c61d9 100644 Binary files a/graphics/deck_gfx.png and b/graphics/deck_gfx.png differ diff --git a/graphics/joker_gfx10.grit b/graphics/joker_gfx10.grit new file mode 100644 index 0000000..a8ac3f6 --- /dev/null +++ b/graphics/joker_gfx10.grit @@ -0,0 +1 @@ +-gB4 -Mw4 -Mh4 -m! -pn 16 \ No newline at end of file diff --git a/graphics/joker_gfx10.png b/graphics/joker_gfx10.png new file mode 100644 index 0000000..8d5cbc1 Binary files /dev/null and b/graphics/joker_gfx10.png differ diff --git a/graphics/joker_gfx11.grit b/graphics/joker_gfx11.grit new file mode 100644 index 0000000..a8ac3f6 --- /dev/null +++ b/graphics/joker_gfx11.grit @@ -0,0 +1 @@ +-gB4 -Mw4 -Mh4 -m! -pn 16 \ No newline at end of file diff --git a/graphics/joker_gfx11.png b/graphics/joker_gfx11.png new file mode 100644 index 0000000..07b537c Binary files /dev/null and b/graphics/joker_gfx11.png differ diff --git a/graphics/joker_gfx2.png b/graphics/joker_gfx2.png index b848ff0..bbdf59b 100644 Binary files a/graphics/joker_gfx2.png and b/graphics/joker_gfx2.png differ diff --git a/graphics/joker_gfx3.png b/graphics/joker_gfx3.png index 673aa12..3f70877 100644 Binary files a/graphics/joker_gfx3.png and b/graphics/joker_gfx3.png differ diff --git a/graphics/joker_gfx4.png b/graphics/joker_gfx4.png index e2074c6..f492a3f 100644 Binary files a/graphics/joker_gfx4.png and b/graphics/joker_gfx4.png differ diff --git a/graphics/joker_gfx5.png b/graphics/joker_gfx5.png index c220cf3..620086a 100644 Binary files a/graphics/joker_gfx5.png and b/graphics/joker_gfx5.png differ diff --git a/graphics/joker_gfx6.png b/graphics/joker_gfx6.png index 7620341..2a86ee5 100644 Binary files a/graphics/joker_gfx6.png and b/graphics/joker_gfx6.png differ diff --git a/graphics/joker_gfx8.png b/graphics/joker_gfx8.png index 01dbbdd..eaf2fbc 100644 Binary files a/graphics/joker_gfx8.png and b/graphics/joker_gfx8.png differ diff --git a/graphics/joker_gfx9.grit b/graphics/joker_gfx9.grit new file mode 100644 index 0000000..a8ac3f6 --- /dev/null +++ b/graphics/joker_gfx9.grit @@ -0,0 +1 @@ +-gB4 -Mw4 -Mh4 -m! -pn 16 \ No newline at end of file diff --git a/graphics/joker_gfx9.png b/graphics/joker_gfx9.png new file mode 100644 index 0000000..d220413 Binary files /dev/null and b/graphics/joker_gfx9.png differ diff --git a/include/affine_background.h b/include/affine_background.h new file mode 100644 index 0000000..8e5f78f --- /dev/null +++ b/include/affine_background.h @@ -0,0 +1,17 @@ +#ifndef AFFINE_BACKGROUND_H +#define AFFINE_BACKGROUND_H + +#include + +#include "graphic_utils.h" + +#define AFFINE_BG_PAL_LEN 5 +#define AFFINE_BG_PB (PAL_ROW_LEN * 15) // This isn't really a palette bank, just the starting index of the palette + +void affine_background_init(); +void affine_background_update(); +void affine_background_set_color(COLOR color); +// Must be called with an array of size at least AFFINE_BG_PAL_LEN +void affine_background_load_palette(const u16 *src); + +#endif // AFFINE_BACKGROUND_H diff --git a/include/game.h b/include/game.h index 6fdaec1..55e8730 100644 --- a/include/game.h +++ b/include/game.h @@ -6,6 +6,8 @@ #define MAX_JOKERS_HELD_SIZE 5 // This doesn't account for negatives right now. #define MAX_SHOP_JOKERS 2 // TODO: Make this dynamic and allow for other items besides jokers #define MAX_SELECTION_SIZE 5 +#define MAX_CARD_SCORE_DIGITS 2 // Current digit limit for score received from cards including mult etc. from jokers +#define MAX_CARD_SCORE_STR_LEN (MAX_CARD_SCORE_DIGITS + 1) // For the '+' or 'X' #define FRAMES(x) (((x) + game_speed - 1) / game_speed) // TODO: Turn into enum? @@ -77,9 +79,12 @@ typedef struct CardObject CardObject; // forward declaration, actually declared typedef struct JokerObject JokerObject; CardObject** get_hand_array(void); int get_hand_top(void); +int hand_get_size(void); CardObject** get_played_array(void); int get_played_top(void); JokerObject** get_jokers(void); int get_jokers_top(void); +int get_num_discards_remaining(void); + #endif // GAME_H \ No newline at end of file diff --git a/include/graphic_utils.h b/include/graphic_utils.h index 6c169c7..2e80828 100644 --- a/include/graphic_utils.h +++ b/include/graphic_utils.h @@ -43,6 +43,9 @@ // Tile size in pixels, both height and width as tiles are square #define TILE_SIZE 8 +// By default TTE characters occupy a single tile +#define TTE_CHAR_SIZE TILE_SIZE + typedef struct { int left; @@ -117,4 +120,22 @@ void tte_erase_rect_wrapper(Rect rect); */ void update_text_rect_to_right_align_num(Rect* rect, int num, int overflow_direction); -#endif //GRAPHIC_UTILS_H \ No newline at end of file +/*Copies 16 bit data from src to dst, applying a palette offset to the data. + * This is intended solely for use with tile8/8bpp data for dst and src. + * The palette offset allows the tiles to use a different location in the palette + * memory + * This is useful because grit always loads the palette to the beginning of + * pal_bg_mem[] + */ +void memcpy16_tile8_with_palette_offset(u16* dst, const u16* src, uint hwcount, u8 palette_offset); + +/*Copies 32 bit data from src to dst, applying a palette offset to the data. + * This is intended solely for use with tile8/8bpp data for dst and src. + * The palette offset allows the tiles to use a different location in the palette + * memory + * This is useful because grit always loads the palette to the beginning of + * pal_bg_mem[] + */ +void memcpy32_tile8_with_palette_offset(u32* dst, const u32* src, uint wcount, u8 palette_offset); + +#endif //GRAPHIC_UTILS_H diff --git a/include/joker_gfx.h b/include/joker_gfx.h index 92c3edc..75cfbbc 100644 --- a/include/joker_gfx.h +++ b/include/joker_gfx.h @@ -10,5 +10,8 @@ #include "joker_gfx6.h" #include "joker_gfx7.h" #include "joker_gfx8.h" +#include "joker_gfx9.h" +#include "joker_gfx10.h" +#include "joker_gfx11.h" #endif \ No newline at end of file diff --git a/include/util.h b/include/util.h index 5b3160e..7d9b915 100644 --- a/include/util.h +++ b/include/util.h @@ -37,6 +37,8 @@ static inline int get_digits_even(int n) #define NUM_ELEM_IN_ARR(arr) (sizeof(arr) / sizeof((arr)[0])) +#define INT_MAX_DIGITS 10 // strlen(str(INT_MAX)) = strlen("2147483647") + int int_arr_max(int int_arr[], int size); #endif // UTIL_H \ No newline at end of file diff --git a/source/affine_background.c b/source/affine_background.c new file mode 100644 index 0000000..f9e15e7 --- /dev/null +++ b/source/affine_background.c @@ -0,0 +1,46 @@ +#include "affine_background.h" +#include "affine_background_gfx.h" + +#include "graphic_utils.h" + +BG_AFFINE bgaff; +AFF_SRC_EX asx = {32<<8, 64<<8, 120, 80, 0x0100, 0x0100, 0}; + +void affine_background_init() +{ + memcpy32_tile8_with_palette_offset((u32*)&tile8_mem[AFFINE_BG_CBB], (const u32*)affine_background_gfxTiles, affine_background_gfxTilesLen/4, AFFINE_BG_PB); + GRIT_CPY(&se_mem[AFFINE_BG_SBB], affine_background_gfxMap); + affine_background_load_palette(affine_background_gfxPal); + + bgaff = bg_aff_default; +} + +void affine_background_update() +{ + static uint timer = 0; + timer++; + + // These values are not permament, just the current configuration for the affine background + asx.tex_x += 5; + asx.tex_y += 12; + asx.sx = (lu_sin(timer * 100)) >> 8; // Scale the sine value to fit in a s16 + asx.sx += 256; // Add 256 to the sine value to make it positive + asx.sy = (lu_sin(timer * 100 + 0x4000)) >> 8; // Scale the sine value to fit in a s16 + asx.sy += 256; // Add 256 to the sine value to make it positive + bg_rotscale_ex(&bgaff, &asx); + REG_BG_AFFINE[2] = bgaff; +} + +void affine_background_set_color(COLOR color) +{ + memcpy16(&pal_bg_mem[AFFINE_BG_PB], affine_background_gfxPal, AFFINE_BG_PAL_LEN); + for (int i = 0; i < AFFINE_BG_PAL_LEN; i++) + { + clr_rgbscale(&pal_bg_mem[AFFINE_BG_PB] + i, &pal_bg_mem[AFFINE_BG_PB] + i, 1, color); + } +} + +void affine_background_load_palette(const u16 *src) +{ + memcpy16(&pal_bg_mem[AFFINE_BG_PB], src, AFFINE_BG_PAL_LEN); +} \ No newline at end of file diff --git a/source/game.c b/source/game.c index 6fbb685..05f7a94 100644 --- a/source/game.c +++ b/source/game.c @@ -11,6 +11,7 @@ #include "hand_analysis.h" #include "blind.h" #include "joker.h" +#include "affine_background.h" #include "graphic_utils.h" #include "tonc_video.h" #include "audio_utils.h" @@ -18,6 +19,7 @@ #include "background_gfx.h" #include "background_shop_gfx.h" #include "background_blind_select_gfx.h" +#include "affine_background_gfx.h" #include "soundbank.h" @@ -148,6 +150,11 @@ int get_hand_top(void) { return hand_top; } +int hand_get_size(void) +{ + return hand_top + 1; +} + CardObject **get_played_array(void) { return played; } @@ -239,6 +246,10 @@ static const Rect SHOP_REROLL_RECT = {88, 96, UNDEFINED, UNDEFI #define PITCH_STEP_UNDISCARD_SFX 2*PITCH_STEP_DRAW_SFX // Naming the stage where cards return from the discard pile to the deck "undiscard" +int get_num_discards_remaining(void) { + return discards; +} + // General functions void set_seed(int seed) { @@ -428,6 +439,8 @@ void change_background(int id) else if (current_blind == BOSS_BLIND) { main_bg_se_copy_rect(BOSS_BLIND_TITLE_SRC_RECT, TOP_LEFT_BLIND_TITLE_POINT); + + affine_background_set_color(blind_get_color(BOSS_BLIND, BLIND_SHADOW_COLOR_INDEX)); } bg_copy_current_item_to_top_left_panel(); @@ -849,11 +862,6 @@ void hand_change_sort() sort_cards(); } -int hand_get_size() -{ - return hand_top + 1; -} - int hand_get_max_size() { return hand_size; @@ -1615,7 +1623,7 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection tte_set_special(0xD000); // Set text color to blue from background memory // Write the score to a character buffer variable - char score_buffer[5]; // Assuming the maximum score is 99, we need 4 characters (2 digits + null terminator) + char score_buffer[INT_MAX_DIGITS + 2]; // for '+' and null terminator snprintf(score_buffer, sizeof(score_buffer), "+%d", card_get_value(played[j]->card)); tte_write(score_buffer); @@ -1986,6 +1994,7 @@ void game_round_end() tte_erase_rect_wrapper(BLIND_REWARD_RECT); tte_erase_rect_wrapper(BLIND_REQ_TEXT_RECT); obj_hide(playing_blind_token->obj); + affine_background_load_palette(affine_background_gfxPal); state = 5; timer = 0; } diff --git a/source/graphic_utils.c b/source/graphic_utils.c index 5311711..b568442 100644 --- a/source/graphic_utils.c +++ b/source/graphic_utils.c @@ -168,3 +168,22 @@ void update_text_rect_to_right_align_num(Rect* rect, int num, int overflow_direc } } +void memcpy16_tile8_with_palette_offset(u16* dst, const u16* src, uint hwcount, u8 palette_offset) +{ + const u16 offset = (((palette_offset) << 8) | (palette_offset)); + for (int i = 0; i < hwcount; i++) + { + // Copying u8 data twice across u16 data + dst[i] = src[i] + offset; + } +} + +void memcpy32_tile8_with_palette_offset(u32* dst, const u32* src, uint wcount, u8 palette_offset) +{ + const u32 offset = (palette_offset << 24) | (palette_offset << 16) | (palette_offset << 8) | palette_offset; + for (int i = 0; i < wcount; i++) + { + // Copying u8 data 4 times across u32 data + dst[i] = src[i] + offset; + } +} \ No newline at end of file diff --git a/source/joker.c b/source/joker.c index de376b0..6b30061 100644 --- a/source/joker.c +++ b/source/joker.c @@ -127,6 +127,9 @@ void joker_init() joker_gfxTiles[6] = joker_gfx6Tiles; joker_gfxTiles[7] = joker_gfx7Tiles; joker_gfxTiles[8] = joker_gfx8Tiles; + joker_gfxTiles[9] = joker_gfx9Tiles; + joker_gfxTiles[10] = joker_gfx10Tiles; + joker_gfxTiles[11] = joker_gfx11Tiles; joker_gfxPal[0] = joker_gfx0Pal; joker_gfxPal[1] = joker_gfx1Pal; @@ -137,6 +140,9 @@ void joker_init() joker_gfxPal[6] = joker_gfx6Pal; joker_gfxPal[7] = joker_gfx7Pal; joker_gfxPal[8] = joker_gfx8Pal; + joker_gfxPal[9] = joker_gfx9Pal; + joker_gfxPal[10] = joker_gfx10Pal; + joker_gfxPal[11] = joker_gfx11Pal; for (int i = 0; i < num_spritesheets; i++) { @@ -264,33 +270,47 @@ bool joker_object_score(JokerObject *joker_object, Card* scored_card, int *chips *money += joker_effect.money; // TODO: Retrigger - tte_set_pos(fx2int(joker_object->sprite_object->x) + 8, JOKER_SCORE_TEXT_Y); // Offset of 16 pixels to center the text on the card - - char score_buffer[12]; + const int joker_score_display_offset_px = (MAX_CARD_SCORE_STR_LEN + 1)*TTE_CHAR_SIZE; + // + 1 For space + int cursorPosX = fx2int(joker_object->sprite_object->x) + 8; // Offset of 16 pixels to center the text on the card if (joker_effect.chips > 0) { + char score_buffer[INT_MAX_DIGITS + 2]; // For '+' and null terminator + tte_set_pos(cursorPosX, JOKER_SCORE_TEXT_Y); tte_set_special(0xD000); // Blue snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.chips); + tte_write(score_buffer); + cursorPosX += joker_score_display_offset_px; } - else if (joker_effect.mult > 0) + if (joker_effect.mult > 0) { + char score_buffer[INT_MAX_DIGITS + 2]; + tte_set_pos(cursorPosX, JOKER_SCORE_TEXT_Y); tte_set_special(0xE000); // Red snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.mult); + tte_write(score_buffer); + cursorPosX += joker_score_display_offset_px; } - else if (joker_effect.xmult > 0) + if (joker_effect.xmult > 0) { + char score_buffer[INT_MAX_DIGITS + 2]; + tte_set_pos(cursorPosX, JOKER_SCORE_TEXT_Y); tte_set_special(0xE000); // Red snprintf(score_buffer, sizeof(score_buffer), "X%d", joker_effect.xmult); + tte_write(score_buffer); + cursorPosX += joker_score_display_offset_px; } - else if (joker_effect.money > 0) + if (joker_effect.money > 0) { + char score_buffer[INT_MAX_DIGITS + 2]; + tte_set_pos(cursorPosX, JOKER_SCORE_TEXT_Y); tte_set_special(0xC000); // Yellow snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.money); + tte_write(score_buffer); + cursorPosX += joker_score_display_offset_px; } - tte_write(score_buffer); - joker_object->joker->processed = true; // Mark the joker as processed joker_object_shake(joker_object, SFX_CARD_SELECT); // TODO: Add a sound effect for scoring the joker diff --git a/source/joker_effects.c b/source/joker_effects.c index 5e934ee..bab4512 100644 --- a/source/joker_effects.c +++ b/source/joker_effects.c @@ -1,3 +1,4 @@ +#include "game.h" #include "joker.h" #include "util.h" #include "hand_analysis.h" @@ -178,7 +179,8 @@ static JokerEffect half_joker_effect(Joker *joker, Card *scored_card) { if (scored_card != NULL) return effect; // if card != null, we are not at the end-phase of scoring yet - if (get_played_top() + 1 <= 3) // game.c has hand_get_size() but it's not accesible here + int played_size = get_played_top() + 1; + if (played_size <= 3) effect.mult = 20; return effect; @@ -190,12 +192,13 @@ static JokerEffect joker_stencil_effect(Joker *joker, Card *scored_card) { return effect; // if card != null, we are not at the end-phase of scoring yet // +1 xmult per empty joker slot... - int jokers_top = get_jokers_top(); - effect.xmult = (MAX_JOKERS_HELD_SIZE-1) - jokers_top; + int num_jokers = get_jokers_top() + 1; + + effect.xmult = (MAX_JOKERS_HELD_SIZE) - num_jokers; // ...and also each stencil_joker adds +1 xmult JokerObject** jokers = get_jokers(); - for (int i = 0; i < jokers_top; i++ ) + for (int i = 0; i < num_jokers; i++ ) { if (jokers[i]->joker->id == JOKER_STENCIL_ID) effect.xmult++; @@ -215,6 +218,78 @@ static JokerEffect misprint_joker_effect(Joker *joker, Card *scored_card) { return effect; } +static JokerEffect walkie_talkie_joker_effect(Joker *joker, Card *scored_card) { + JokerEffect effect = {0}; + if (scored_card == NULL) + return effect; + + if (scored_card->rank == TEN || scored_card->rank == FOUR) { + effect.chips = 10; + effect.mult = 4; + } + + return effect; +} + +static JokerEffect fibonnaci_joker_effect(Joker *joker, Card *scored_card) { + JokerEffect effect = {0}; + if (scored_card == NULL) + return effect; + + switch (scored_card->rank) { + case ACE: case TWO: case THREE: case FIVE: case EIGHT: + effect.mult = 8; + default: + break; + } + + return effect; +} + +static JokerEffect banner_joker_effect(Joker *joker, Card *scored_card) { + JokerEffect effect = {0}; + if (scored_card != NULL) + return effect; // if card != null, we are not at the end-phase of scoring yet + + effect.chips = 30 * get_num_discards_remaining(); + + return effect; +} + +static JokerEffect mystic_summit_joker_effect(Joker *joker, Card *scored_card) { + JokerEffect effect = {0}; + if (scored_card != NULL) + return effect; // if card != null, we are not at the end-phase of scoring yet + + if (get_num_discards_remaining() == 0) + effect.mult = 15; + + return effect; +} + +static JokerEffect blackboard_joker_effect(Joker *joker, Card *scored_card) { + JokerEffect effect = {0}; + if (scored_card != NULL) + return effect; // if card != null, we are not at the end-phase of scoring yet + + bool all_cards_are_spades_or_clubs = true; + CardObject** hand = get_hand_array(); + int hand_size = hand_get_size(); + for (int i = 0; i < hand_size; i++ ) + { + u8 suit = hand[i]->card->suit; + if (suit == HEARTS || suit == DIAMONDS) { + all_cards_are_spades_or_clubs = false; + break; + } + } + + if (all_cards_are_spades_or_clubs) + effect.xmult = 3; + + return effect; +} + const JokerInfo joker_registry[] = { { COMMON_JOKER, 2, default_joker_effect }, // DEFAULT_JOKER_ID = 0 { COMMON_JOKER, 5, greedy_joker_effect }, // GREEDY_JOKER_ID = 1 @@ -233,6 +308,11 @@ const JokerInfo joker_registry[] = { { COMMON_JOKER, 4, crafty_joker_effect }, { COMMON_JOKER, 5, half_joker_effect }, { UNCOMMON_JOKER, 8, joker_stencil_effect }, + { COMMON_JOKER, 5, banner_joker_effect }, + { COMMON_JOKER, 4, walkie_talkie_joker_effect }, + { UNCOMMON_JOKER, 8, fibonnaci_joker_effect }, + { UNCOMMON_JOKER, 6, blackboard_joker_effect }, + { COMMON_JOKER, 5, mystic_summit_joker_effect }, { COMMON_JOKER, 4, misprint_joker_effect }, }; diff --git a/source/main.c b/source/main.c index bd7b046..76abc07 100644 --- a/source/main.c +++ b/source/main.c @@ -7,6 +7,7 @@ #include "game.h" #include "blind.h" #include "joker.h" +#include "affine_background.h" #include "graphic_utils.h" // Graphics @@ -17,29 +18,6 @@ #include "soundbank.h" #include "soundbank_bin.h" -#define MAP_AFF_SIZE 0x0100 -BG_AFFINE bgaff; -AFF_SRC_EX asx = {32<<8, 64<<8, 120, 80, 0x0100, 0x0100, 0}; - - -void init_map() // Temp function derived from libtonc example -{ - // Grit is fucking garbage and doesn't allow you to have a palette offset, they all get loaded at 0x0000. I have to manually change each tile's palette bank - - unsigned int correctedTiles[affine_background_gfxTilesLen / 4]; - for (int i = 0; i < affine_background_gfxTilesLen / 4; i++) - { - correctedTiles[i] = affine_background_gfxTiles[i] | 0xF0F0F0F0; // I brute forced this. I have no idea how this would and does work, but it does. We'll just leave this here for now. - // Actually for future reference, each number seems to equate to an XY on the palette, so 0xF0F0F0F0 would just push everything down 15 colors, since the second number isn't set. - } - - memcpy(&tile8_mem[AFFINE_BG_CBB], correctedTiles, affine_background_gfxTilesLen); - GRIT_CPY(&se_mem[AFFINE_BG_SBB], affine_background_gfxMap); - memcpy16(&pal_bg_mem[16 * 15], affine_background_gfxPal, 5); - - bgaff = bg_aff_default; -} - void init() { irq_init(NULL); @@ -93,9 +71,8 @@ void init() REG_DISPCNT = DCNT_MODE1 | DCNT_OBJ_1D | DCNT_BG0 | DCNT_BG1 | DCNT_BG2 | DCNT_OBJ | DCNT_WIN0 | DCNT_WIN1; - init_map(); // Initialize the map for the background - // Initialize subsystems + affine_background_init(); sprite_init(); card_init(); blind_init(); @@ -103,24 +80,9 @@ void init() game_init(); } -void background_update() // This needs to be called before update() and draw() because setting REG_BG_AFFINE during an HBlank can cause issues -{ - static uint timer = 0; - timer++; - - // These values are not permament, just the current configuration for the affine background - asx.tex_x += 5; - asx.tex_y += 12; - asx.sx = (lu_sin(timer * 100)) >> 8; // Scale the sine value to fit in a s16 - asx.sx += 256; // Add 256 to the sine value to make it positive - asx.sy = (lu_sin(timer * 100 + 0x4000)) >> 8; // Scale the sine value to fit in a s16 - asx.sy += 256; // Add 256 to the sine value to make it positive - bg_rotscale_ex(&bgaff, &asx); - REG_BG_AFFINE[2]= bgaff; -} - void update() { + affine_background_update(); game_update(); } @@ -138,7 +100,6 @@ int main() VBlankIntrWait(); mmFrame(); key_poll(); - background_update(); update(); draw(); }