temporary overwrite of previous merge. I've been working on this for 10 hours today and really do not have the patience to resolve the conflicts right now. I'll do it later 😭
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
# Balatro GBA
|
# 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 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 Balatro Steam demo.
|
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.
|
||||||

|

|
||||||
|
|
||||||
# **Build Instructions:**
|
# **Build Instructions:**
|
||||||
@@ -34,3 +35,6 @@ Example: `cd '/home/user/OneDrive/Documents/balatro-gba` or something like this.
|
|||||||
-Try a different emulator or if you are using original hardware, make sure the rom is not corrupted and try a different flashcart or SD Card. If this does not work, open an issue on the Github page because a recent commit may have broke the game.
|
-Try a different emulator or if you are using original hardware, make sure the rom is not corrupted and try a different flashcart or SD Card. If this does not work, open an issue on the Github page because a recent commit may have broke the game.
|
||||||
5. **It says I don't have `Git` or `Make` installed!**
|
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.
|
-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/**
|
||||||
|
|||||||
@@ -36,6 +36,9 @@
|
|||||||
#define SE_UP -1
|
#define SE_UP -1
|
||||||
#define SE_DOWN 1
|
#define SE_DOWN 1
|
||||||
|
|
||||||
|
// Tile size in pixels, both height and width as tiles are square
|
||||||
|
#define TILE_SIZE 8
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int left;
|
int left;
|
||||||
@@ -52,6 +55,19 @@ typedef struct
|
|||||||
*/
|
*/
|
||||||
u16 main_bg_se_get_tile(int x, int y);
|
u16 main_bg_se_get_tile(int x, int y);
|
||||||
|
|
||||||
|
INLINE int rect_width(const Rect* rect)
|
||||||
|
{
|
||||||
|
/* Extra parens to avoid issues in case compiler turns INLINE into macro
|
||||||
|
* Not sure if necessary, could be just paranoia
|
||||||
|
*/
|
||||||
|
return (((rect)->right) - ((rect)->left) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE int rect_height(const Rect* rect)
|
||||||
|
{
|
||||||
|
return (((rect)->bottom) - ((rect)->top) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Clears a rect in the main background.
|
/* Clears a rect in the main background.
|
||||||
* The se_rect dimensions need to be in number of tiles.
|
* The se_rect dimensions need to be in number of tiles.
|
||||||
*/
|
*/
|
||||||
@@ -74,6 +90,13 @@ void main_bg_se_copy_rect(Rect se_rect, int x, int y);
|
|||||||
* The tile is copied to the top left corner of the rect.
|
* The tile is copied to the top left corner of the rect.
|
||||||
*/
|
*/
|
||||||
void main_bg_se_copy_tile_to_rect(u16 tile, Rect se_rect);
|
void main_bg_se_copy_tile_to_rect(u16 tile, Rect se_rect);
|
||||||
|
/* Moves a rect in the main background vertically in direction by a single tile.
|
||||||
|
* Note that tiles in the previous location will be transparent (0x000)
|
||||||
|
* so maybe copy would be a better choice if you don't want to delete things
|
||||||
|
* direction must be either SE_UP or SE_DOWN.
|
||||||
|
* se_rect dimensions are in number of tiles.
|
||||||
|
*/
|
||||||
|
void main_bg_se_move_rect_1_tile_vert(Rect se_rect, int direction);
|
||||||
|
|
||||||
// A wrapper for tte_erase_rect that would use the rect struct
|
// A wrapper for tte_erase_rect that would use the rect struct
|
||||||
void tte_erase_rect_wrapper(Rect rect);
|
void tte_erase_rect_wrapper(Rect rect);
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "tonc_video.h"
|
#include "tonc_video.h"
|
||||||
|
|
||||||
#include "background_gfx.h"
|
#include "background_gfx.h"
|
||||||
#include "background_round_end_gfx.h"
|
|
||||||
#include "background_shop_gfx.h"
|
#include "background_shop_gfx.h"
|
||||||
#include "background_blind_select_gfx.h"
|
#include "background_blind_select_gfx.h"
|
||||||
|
|
||||||
|
|||||||
+25
-7
@@ -7,6 +7,7 @@
|
|||||||
const Rect FULL_SCREENBLOCK_RECT = { 0, 0, SE_ROW_LEN, SE_COL_LEN };
|
const Rect FULL_SCREENBLOCK_RECT = { 0, 0, SE_ROW_LEN, SE_COL_LEN };
|
||||||
|
|
||||||
// Clips a rect of screenblock entries to a specified rect
|
// Clips a rect of screenblock entries to a specified rect
|
||||||
|
// The bounding rect is not required to be within screenblock boundaries
|
||||||
static void clip_se_rect_to_bounding_rect(Rect* rect, const Rect* bounding_rect)
|
static void clip_se_rect_to_bounding_rect(Rect* rect, const Rect* bounding_rect)
|
||||||
{
|
{
|
||||||
rect->right = min(rect->right, bounding_rect->right);
|
rect->right = min(rect->right, bounding_rect->right);
|
||||||
@@ -17,7 +18,6 @@ static void clip_se_rect_to_bounding_rect(Rect* rect, const Rect* bounding_rect)
|
|||||||
|
|
||||||
// Can be unstaticed if needed
|
// Can be unstaticed if needed
|
||||||
// Clips a rect of screenblock entries to screenblock boundaries
|
// Clips a rect of screenblock entries to screenblock boundaries
|
||||||
// The bounding rect is not required to be within screenblock boundaries
|
|
||||||
static void clip_se_rect_to_screenblock(Rect* rect)
|
static void clip_se_rect_to_screenblock(Rect* rect)
|
||||||
{
|
{
|
||||||
clip_se_rect_to_bounding_rect(rect, &FULL_SCREENBLOCK_RECT);
|
clip_se_rect_to_bounding_rect(rect, &FULL_SCREENBLOCK_RECT);
|
||||||
@@ -28,6 +28,16 @@ u16 main_bg_se_get_tile(int x, int y)
|
|||||||
return se_mem[MAIN_BG_SBB][x + SE_ROW_LEN * y];
|
return se_mem[MAIN_BG_SBB][x + SE_ROW_LEN * y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clips a rect of screenblock entries to be within one step of
|
||||||
|
// screenblock boundaries vertically (1 step from top, 1 step from bottom.
|
||||||
|
static void clip_se_rect_within_step_of_full_screen_vert(Rect* se_rect)
|
||||||
|
{
|
||||||
|
Rect bounding_rect = FULL_SCREENBLOCK_RECT;
|
||||||
|
bounding_rect.top += 1;
|
||||||
|
bounding_rect.bottom -= -1;
|
||||||
|
clip_se_rect_to_bounding_rect(se_rect, &bounding_rect);
|
||||||
|
}
|
||||||
|
|
||||||
void main_bg_se_clear_rect(Rect se_rect)
|
void main_bg_se_clear_rect(Rect se_rect)
|
||||||
{
|
{
|
||||||
if (se_rect.left > se_rect.right)
|
if (se_rect.left > se_rect.right)
|
||||||
@@ -37,7 +47,7 @@ void main_bg_se_clear_rect(Rect se_rect)
|
|||||||
|
|
||||||
for (int y = se_rect.top; y < se_rect.bottom; y++)
|
for (int y = se_rect.top; y < se_rect.bottom; y++)
|
||||||
{
|
{
|
||||||
memset16(&(se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * y]), 0x0000, se_rect.right - se_rect.left + 1);
|
memset16(&(se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * y]), 0x0000, rect_width(&se_rect));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,13 +55,12 @@ void main_bg_se_copy_rect_1_tile_vert(Rect se_rect, int direction)
|
|||||||
{
|
{
|
||||||
if (se_rect.left > se_rect.right
|
if (se_rect.left > se_rect.right
|
||||||
|| (direction != SE_UP && direction != SE_DOWN))
|
|| (direction != SE_UP && direction != SE_DOWN))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Clip to avoid read/write overflow of the screenblock
|
// Clip to avoid read/write overflow of the screenblock
|
||||||
Rect bounding_rect = FULL_SCREENBLOCK_RECT;
|
clip_se_rect_within_step_of_full_screen_vert(&se_rect);
|
||||||
bounding_rect.top = 1;
|
|
||||||
bounding_rect.bottom = SE_COL_LEN - 1;
|
|
||||||
clip_se_rect_to_bounding_rect(&se_rect, &bounding_rect);
|
|
||||||
|
|
||||||
int start = (direction == SE_UP) ? se_rect.top : se_rect.bottom;
|
int start = (direction == SE_UP) ? se_rect.top : se_rect.bottom;
|
||||||
int end = (direction == SE_UP) ? se_rect.bottom : se_rect.top;
|
int end = (direction == SE_UP) ? se_rect.bottom : se_rect.top;
|
||||||
@@ -60,7 +69,16 @@ void main_bg_se_copy_rect_1_tile_vert(Rect se_rect, int direction)
|
|||||||
{
|
{
|
||||||
memcpy16(&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * (y + direction)],
|
memcpy16(&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * (y + direction)],
|
||||||
&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * y],
|
&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * y],
|
||||||
se_rect.right - se_rect.left + 1);
|
rect_width(&se_rect));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_bg_se_move_rect_1_tile_vert(Rect se_rect, int direction)
|
||||||
|
{
|
||||||
|
if (se_rect.left > se_rect.right
|
||||||
|
|| (direction != SE_UP && direction != SE_DOWN))
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
// Graphics
|
// Graphics
|
||||||
#include "deck_gfx.h"
|
#include "deck_gfx.h"
|
||||||
#include "background_gfx.h"
|
#include "background_gfx.h"
|
||||||
#include "background_play_gfx.h"
|
|
||||||
#include "affine_background_gfx.h"
|
#include "affine_background_gfx.h"
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
|
|||||||
Reference in New Issue
Block a user