Merge branch 'main' into pr-fix

This commit is contained in:
Nan
2025-10-08 18:11:20 +02:00
committed by GitHub
22 changed files with 298 additions and 59 deletions
+9 -1
View File
@@ -4,6 +4,8 @@ on:
push:
branches:
- main
tags:
- "v*"
pull_request:
branches:
- main
@@ -19,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Get docker image cache
uses: actions/cache@v4
@@ -53,3 +55,9 @@ jobs:
- name: Build the project
run: docker compose -f docker-compose.yml run --rm balatro sh -c "make -j$(nproc)"
- uses: softprops/action-gh-release@v2
if: ${{ startsWith(github.ref, 'refs/tags/') }}
with:
files: |
build/balatro-gba.gba
+7 -1
View File
@@ -38,17 +38,23 @@ GRAPHICS := graphics
#---------------------------------------------------------------------------------
ARCH := -mthumb -mthumb-interwork
GIT_DIRTY := $(shell git diff-index --quiet HEAD -- || echo "-dirty")
GIT_HASH := $(shell git rev-parse --short HEAD || echo "undef")
GIT_C_FLAGS := -DGIT_HASH=\"$(GIT_HASH)\" -DGIT_DIRTY=\"$(GIT_DIRTY)\"
CFLAGS := -g -O3 -Wall -Werror\
-mcpu=arm7tdmi -mtune=arm7tdmi \
-ffast-math -fomit-frame-pointer -funroll-loops \
$(ARCH)
CFLAGS += $(GIT_C_FLAGS)
CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map),--undefined=balatro_version
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
+60 -9
View File
@@ -1,8 +1,9 @@
# Balatro-GBA
[![Build Status](https://img.shields.io/github/actions/workflow/status/cellos51/balatro-gba/build_ci_workflow.yml?style=flat&logo=github&branch=main&label=Builds&labelColor=gray&color=default&v=1)](https://github.com/cellos51/balatro-gba/actions)
[![Open Issues](https://custom-icon-badges.demolab.com/github/issues/cellos51/balatro-gba?logo=bug&style=flat&label=Issues&labelColor=gray&color=red&v=2)](https://github.com/cellos51/balatro-gba/issues)
[![Pull Requests](https://custom-icon-badges.demolab.com/github/issues-pr/cellos51/balatro-gba?logo=git-pull-request&style=flat&label=Pull%20Requests&labelColor=gray&color=indigo&v=3)](https://github.com/cellos51/balatro-gba/pulls)
[![Build Status](https://img.shields.io/github/actions/workflow/status/cellos51/balatro-gba/build_ci_workflow.yml?style=flat&logo=github&branch=main&label=Builds&labelColor=gray&color=default&maxAge=7200)](https://github.com/cellos51/balatro-gba/actions)
[![Open Issues](https://img.shields.io/github/issues/cellos51/balatro-gba?style=flat&color=red&label=Issues&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ij48cGF0aCBmaWxsPSJ3aGl0ZSIgZD0iTTggOS41YTEuNSAxLjUgMCAxIDAgMC0zIDEuNSAxLjUgMCAwIDAgMCAzWiI+PC9wYXRoPjxwYXRoIGZpbGw9IndoaXRlIiBkPSJNOCAwYTggOCAwIDEgMSAwIDE2QTggOCAwIDAgMSA4IDBaTTEuNSA4YTYuNSA2LjUgMCAxIDAgMTMgMCA2LjUgNi41IDAgMCAwLTEzIDBaIj48L3BhdGg+PC9zdmc+)](https://github.com/cellos51/balatro-gba/issues)
[![Pull Requests](https://img.shields.io/github/issues-pr/cellos51/balatro-gba?style=flat&color=indigo&label=Pull%20Requests&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ij48cGF0aCBmaWxsPSJ3aGl0ZSIgZD0iTTEuNSAzLjI1YTIuMjUgMi4yNSAwIDEgMSAzIDIuMTIydjUuMjU2YTIuMjUxIDIuMjUxIDAgMSAxLTEuNSAwVjUuMzcyQTIuMjUgMi4yNSAwIDAgMSAxLjUgMy4yNVptNS42NzctLjE3N0w5LjU3My42NzdBLjI1LjI1IDAgMCAxIDEwIC44NTRWMi41aDFBMi41IDIuNSAwIDAgMSAxMy41IDV2NS42MjhhMi4yNTEgMi4yNTEgMCAxIDEtMS41IDBWNWExIDEgMCAwIDAtMS0xaC0xdjEuNjQ2YS4yNS4yNSAwIDAgMS0uNDI3LjE3N0w3LjE3NyAzLjQyN2EuMjUuMjUgMCAwIDEgMC0uMzU0Wk0zLjc1IDIuNWEuNzUuNzUgMCAxIDAgMCAxLjUuNzUuNzUgMCAwIDAgMC0xLjVabTAgOS41YS43NS43NSAwIDEgMCAwIDEuNS43NS43NSAwIDAgMCAwLTEuNVptOC4yNS43NWEuNzUuNzUgMCAxIDAgMS41IDAgLjc1Ljc1IDAgMCAwLTEuNSAwWiI+PC9wYXRoPjwvc3ZnPg==)](https://github.com/cellos51/balatro-gba/pulls)
[![Discussions](https://img.shields.io/github/discussions/cellos51/balatro-gba?style=flat&color=blue&label=Discussions&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ij48cGF0aCBmaWxsPSJ3aGl0ZSIgZD0iTTEuNzUgMWg4LjVjLjk2NiAwIDEuNzUuNzg0IDEuNzUgMS43NXY1LjVBMS43NSAxLjc1IDAgMCAxIDEwLjI1IDEwSDcuMDYxbC0yLjU3NCAyLjU3M0ExLjQ1OCAxLjQ1OCAwIDAgMSAyIDExLjU0M1YxMGgtLjI1QTEuNzUgMS43NSAwIDAgMSAwIDguMjV2LTUuNUMwIDEuNzg0Ljc4NCAxIDEuNzUgMVpNMS41IDIuNzV2NS41YzAgLjEzOC4xMTIuMjUuMjUuMjVoMWEuNzUuNzUgMCAwIDEgLjc1Ljc1djIuMTlsMi43Mi0yLjcyYS43NDkuNzQ5IDAgMCAxIC41My0uMjJoMy41YS4yNS4yNSAwIDAgMCAuMjUtLjI1di01LjVhLjI1LjI1IDAgMCAwLS4yNS0uMjVoLTguNWEuMjUuMjUgMCAwIDAtLjI1LjI1Wm0xMyAyYS4yNS4yNSAwIDAgMC0uMjUtLjI1aC0uNWEuNzUuNzUgMCAwIDEgMC0xLjVoLjVjLjk2NiAwIDEuNzUuNzg0IDEuNzUgMS43NXY1LjVBMS43NSAxLjc1IDAgMCAxIDE0LjI1IDEySDE0djEuNTQzYTEuNDU4IDEuNDU4IDAgMCAxLTIuNDg3IDEuMDNMOS4yMiAxMi4yOGEuNzQ5Ljc0OSAwIDAgMSAuMzI2LTEuMjc1Ljc0OS43NDkgMCAwIDEgLjczNC4yMTVsMi4yMiAyLjIydi0yLjE5YS43NS43NSAwIDAgMSAuNzUtLjc1aDFhLjI1LjI1IDAgMCAwIC4yNS0uMjVaIj48L3BhdGg+PC9zdmc+)](https://github.com/cellos51/balatro-gba/discussions)
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 **tech-demo/proof of concept** is strictly limited in content to a minimal version of Balatro and will **NOT** recreate the full game. **This version is intended for people who already own and know how the official full game works.** Please refer to the Balatro Wiki if you need help understanding certain mechanics or abilities.
@@ -40,15 +41,36 @@ This **tech-demo/proof of concept** is strictly limited in content to a minimal
# **Build Instructions:**
## **-Docker-**
A docker compose file is provided to build this project.
A docker compose file is provided to build this project. It provides a standard build environment for this projects CI/CD and can also be used to build the ROM locally.
1.) Install [docker desktop](https://docs.docker.com/compose/install/).
_Some users may find this option to be the easiest way to build locally._
- _This option **avoids** setting up the development environment as described below._
- _No additional software besides **docker desktop** is required._
2.) Open a terminal to this projects directory:
- On **linux** run `UID=$(id -u) GID=$(id -g) docker compose up`
- On **windows** run `docker compose up`
### Step-by-Step
Docker will build the project and the ROM will be in the same location as step 7 describes below.
1.) Install [docker desktop](https://docs.docker.com/desktop/) for your operating system.
2.) Open a terminal to this project's directory:
- On **Linux** run `UID=$(id -u) GID=$(id -g) docker compose up`
- On **Windows** run `docker compose up`
<details>
<summary><i>How do I open a terminal in windows?</i></summary>
---
From the file explorer, you can open a folder in **powershell** (_a modern windows terminal_):
- **hold 'Shift'** and **Right Click** on the folder.
- Select **"Open PowerShell window here"** from the popup menu.
---
</details>
3.) Docker will build the project and the ROM will be in the same location as step 7 describes below.
## **-Windows-**
Video Tutorial: https://youtu.be/72Zzo1VDYzQ?si=UDmEdbST1Cx1zZV2
@@ -68,6 +90,35 @@ Video Tutorial: https://youtu.be/72Zzo1VDYzQ?si=UDmEdbST1Cx1zZV2
7.) 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.
### Without `Git`
Disregard Steps 3-4 and instead click the green code button on the main repository page and press `Download Zip`. Unzip the folder and place it wherever you like. Then continue from Step 5.
## **-Linux-**
1.) Add the devkitPro repository using these instructions https://devkitpro.org/wiki/devkitPro_pacman
2.) Install devkitPro by running `sudo pacman -S gba-dev` and accepting all packages.
3.) Activate the devkitPro environment by running `source /etc/profile.d/devkit-env.sh` or opening a new shell.
4.) Follow instructions from the Windows tutorial starting from Step 3
## **-macOS-**
1.) Install devkitPro installer using: https://github.com/devkitPro/installer and following https://devkitpro.org/wiki/devkitPro_pacman#macOS.
> Note: You may have to install the installers directly from their url in a browser, as the installer script may not install correctly due to Cloudflare checks on their server. You can use one of the following urls:
> Apple Silicon: https://pkg.devkitpro.org/packages/macos-installers/devkitpro-pacman-installer.arm64.pkg
> Intel: https://pkg.devkitpro.org/packages/macos-installers/devkitpro-pacman-installer.x86_64.pkg
2.) Verify that devkitPro is installed in '/opt/devkitpro'
3.) Add the following to your .bashrc or .zshrc (or export the variables in your shell session):
- export DEVKITPRO=/opt/devkitpro
- export DEVKITARM=$DEVKITPRO/devkitARM
- export PATH=$PATH:$DEVKITPRO/tools/bin:$DEVKITPRO/pacman/bin
4.) Follow instructions from Windows tutorial step 4
## **Common Issues:**
#### 1. **When I run `make` it errors out and won't compile!**
+2 -2
View File
@@ -1,8 +1,8 @@
services:
balatro:
image: devkitpro/devkitarm:latest
working_dir: /balatro
working_dir: /balatro-gba
volumes:
- ./:/balatro
- ./:/balatro-gba
user: "${UID-1000}:${GID-1000}"
command: ["sh", "-c", "make -j$(nproc)"]
+1
View File
@@ -0,0 +1 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

+1
View File
@@ -0,0 +1 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

+1
View File
@@ -0,0 +1 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+1
View File
@@ -0,0 +1 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

+1
View File
@@ -0,0 +1 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

+20
View File
@@ -0,0 +1,20 @@
DEF_JOKER_GFX(0)
DEF_JOKER_GFX(1)
DEF_JOKER_GFX(2)
DEF_JOKER_GFX(3)
DEF_JOKER_GFX(4)
DEF_JOKER_GFX(5)
DEF_JOKER_GFX(6)
DEF_JOKER_GFX(7)
DEF_JOKER_GFX(8)
DEF_JOKER_GFX(9)
DEF_JOKER_GFX(10)
DEF_JOKER_GFX(11)
DEF_JOKER_GFX(12)
DEF_JOKER_GFX(13)
DEF_JOKER_GFX(14)
DEF_JOKER_GFX(15)
DEF_JOKER_GFX(16)
DEF_JOKER_GFX(17)
DEF_JOKER_GFX(18)
DEF_JOKER_GFX(19)
+5
View File
@@ -16,5 +16,10 @@
#include "joker_gfx12.h"
#include "joker_gfx13.h"
#include "joker_gfx14.h"
#include "joker_gfx15.h"
#include "joker_gfx16.h"
#include "joker_gfx17.h"
#include "joker_gfx18.h"
#include "joker_gfx19.h"
#endif
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env python3
import sys
import re
def grep_binary_offsets(path, pattern):
with open(path, "rb") as f:
data = f.read()
results = []
for match in re.finditer(rb"[ -~]{4,}", data):
s = match.group()
if re.search(pattern.encode(), s):
results.append((match.start(), s.decode("utf-8", errors="ignore")))
return results
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python script.py <file>")
sys.exit(1)
file_path = sys.argv[1]
pattern = "GBALATRO_VERSION"
for offset, text in grep_binary_offsets(file_path, pattern):
version = text.split(":")[1]
print(f"git hash: {version}")
+15 -2
View File
@@ -851,8 +851,21 @@ void card_draw()
void hand_set_focus(int index)
{
if (index < 0 || index > hand_top || hand_state != HAND_SELECT) return;
selection_x = index;
if (hand_state != HAND_SELECT) return;
// Wrap around to the other side of the hand when going out of bounds on either side
if (index < 0)
{
selection_x = hand_top;
}
else if (index > hand_top)
{
selection_x = 0;
}
else
{
selection_x = index;
}
play_sfx(SFX_CARD_FOCUS, MM_BASE_PITCH_RATE + rand() % 512);
}
+12 -37
View File
@@ -14,8 +14,18 @@
#define JOKER_SCORE_TEXT_Y 48
#define NUM_JOKERS_PER_SPRITESHEET 2
const unsigned int **joker_gfxTiles;
const unsigned short **joker_gfxPal;
static const unsigned int *joker_gfxTiles[] =
{
#define DEF_JOKER_GFX(idx) joker_gfx##idx##Tiles,
#include "../include/def_joker_gfx_table.h"
#undef DEF_JOKER_GFX
};
static const unsigned short *joker_gfxPal[] =
{
#define DEF_JOKER_GFX(idx) joker_gfx##idx##Pal,
#include "../include/def_joker_gfx_table.h"
#undef DEF_JOKER_GFX
};
const static u8 edition_price_lut[MAX_EDITIONS] =
{
@@ -113,42 +123,7 @@ void joker_init()
{
// This should init once only so no need to free
int num_spritesheets = get_num_spritesheets();
joker_gfxTiles = (const unsigned int**)malloc((sizeof(unsigned int*) * num_spritesheets));
joker_gfxPal = (const unsigned short**)malloc((sizeof(unsigned int*) * num_spritesheets));
joker_spritesheet_pb_map = (int*)malloc(sizeof(int) * num_spritesheets);
// TODO: Automate this with the preprocessor somehow?
joker_gfxTiles[0] = joker_gfx0Tiles;
joker_gfxTiles[1] = joker_gfx1Tiles;
joker_gfxTiles[2] = joker_gfx2Tiles;
joker_gfxTiles[3] = joker_gfx3Tiles;
joker_gfxTiles[4] = joker_gfx4Tiles;
joker_gfxTiles[5] = joker_gfx5Tiles;
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_gfxTiles[12] = joker_gfx12Tiles;
joker_gfxTiles[13] = joker_gfx13Tiles;
joker_gfxTiles[14] = joker_gfx14Tiles;
joker_gfxPal[0] = joker_gfx0Pal;
joker_gfxPal[1] = joker_gfx1Pal;
joker_gfxPal[2] = joker_gfx2Pal;
joker_gfxPal[3] = joker_gfx3Pal;
joker_gfxPal[4] = joker_gfx4Pal;
joker_gfxPal[5] = joker_gfx5Pal;
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;
joker_gfxPal[12] = joker_gfx12Pal;
joker_gfxPal[13] = joker_gfx13Pal;
joker_gfxPal[14] = joker_gfx14Pal;
for (int i = 0; i < num_spritesheets; i++)
{
+126 -6
View File
@@ -304,9 +304,6 @@ static JokerEffect blue_joker_effect(Joker *joker, Card *scored_card) {
return effect;
}
// Using __attribute__((unused)) for jokers with no sprites yet to avoid warning
// Remove the attribute once they have sprites
__attribute__((unused))
static JokerEffect raised_fist_joker_effect(Joker *joker, Card *scored_card)
{
JokerEffect effect = {0};
@@ -331,7 +328,6 @@ static JokerEffect raised_fist_joker_effect(Joker *joker, Card *scored_card)
return effect;
}
__attribute__((unused))
static JokerEffect reserved_parking_joker_effect(Joker *joker, Card *scored_card) {
JokerEffect effect = {0};
if (scored_card != NULL)
@@ -397,7 +393,6 @@ static JokerEffect scary_face_joker_effect(Joker *joker, Card *scored_card) {
return effect;
}
__attribute__((unused))
static JokerEffect abstract_joker_effect(Joker *joker, Card *scored_card) {
JokerEffect effect = {0};
if (scored_card != NULL)
@@ -410,7 +405,6 @@ static JokerEffect abstract_joker_effect(Joker *joker, Card *scored_card) {
return effect;
}
__attribute__((unused))
static JokerEffect bull_joker_effect(Joker *joker, Card *scored_card) {
JokerEffect effect = {0};
if (scored_card != NULL)
@@ -480,6 +474,108 @@ static JokerEffect blueprint_joker_effect(Joker *joker, Card *scored_card) {
// JOKER_BLUEPRINT_ID (joker.h) will need to be updated
if (curr_joker_object->joke == joker)
trigger_next_joker = true;
static JokerEffect the_duo_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
// This is really inefficient but the only way at the moment to check for whole-hand conditions
u8 suits[NUM_SUITS];
u8 ranks[NUM_RANKS];
get_played_distribution(ranks, suits);
if (hand_contains_n_of_a_kind(ranks) >= 2)
effect.xmult = 2;
return effect;
}
static JokerEffect the_trio_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
// This is really inefficient but the only way at the moment to check for whole-hand conditions
u8 suits[NUM_SUITS];
u8 ranks[NUM_RANKS];
get_played_distribution(ranks, suits);
if (hand_contains_n_of_a_kind(ranks) >= 3)
effect.xmult = 3;
return effect;
}
static JokerEffect the_family_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
// This is really inefficient but the only way at the moment to check for whole-hand conditions
u8 suits[NUM_SUITS];
u8 ranks[NUM_RANKS];
get_played_distribution(ranks, suits);
if (hand_contains_n_of_a_kind(ranks) >= 4)
effect.xmult = 4;
return effect;
}
static JokerEffect the_order_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
u8 suits[NUM_SUITS];
u8 ranks[NUM_RANKS];
get_played_distribution(ranks, suits);
if (hand_contains_straight(ranks))
effect.xmult = 3;
return effect;
}
static JokerEffect the_tribe_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
u8 suits[NUM_SUITS];
u8 ranks[NUM_RANKS];
get_played_distribution(ranks, suits);
if (hand_contains_flush(suits))
effect.xmult = 2;
return effect;
}
// Using __attribute__((unused)) for jokers with no sprites yet to avoid warning
// Remove the attribute once they have sprites
// graphics available from @MathisMartin31
__attribute__((unused))
static JokerEffect bootstraps_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.mult = (get_money() / 5) * 2;
return effect;
}
// no graphics available but ready to be used if wanted when graphics available
__attribute__((unused))
static JokerEffect shoot_the_moon_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
CardObject** hand = get_hand_array();
int hand_size = hand_get_size();
for (int i = 0; i < hand_size; i++ )
{
if (hand[i]->card->rank == QUEEN)
{
effect.mult += 13;
}
}
return effect;
@@ -500,11 +596,24 @@ static JokerEffect brainstorm_joker_effect(Joker *joker, Card *scored_card) {
joker->processed = true;
effect = joker_get_score_effect(first_joker->joker, scored_card);
joker->processed = false;
// no graphics available but ready to be used if wanted when graphics available
__attribute__((unused))
static JokerEffect triboulet_joker_effect(Joker *joker, Card *scored_card) {
JokerEffect effect = {0};
if (scored_card == NULL)
return effect;
switch (scored_card->rank) {
case KING: case QUEEN:
effect.xmult = 2;
default:
break;
}
return effect;
}
/* The index of a joker in the registry matches its ID.
* The joker sprites are matched by ID so the position in the registry
* determines the joker's sprite.
@@ -546,6 +655,15 @@ const JokerInfo joker_registry[] = {
// Business card should be paired with Shortcut for palette optimization when it's added
{ COMMON_JOKER, 4, scary_face_joker_effect }, // 28
{ COMMON_JOKER, 4, smiley_face_joker_effect }, // 29
{ COMMON_JOKER, 5, raised_fist_joker_effect }, // 30
{ COMMON_JOKER, 6, reserved_parking_joker_effect }, // 31
{ COMMON_JOKER, 4, abstract_joker_effect }, // 32
{ UNCOMMON_JOKER, 6, bull_joker_effect}, // 33
{ RARE_JOKER, 8, the_duo_joker_effect}, // 34
{ RARE_JOKER, 8, the_trio_joker_effect}, // 35
{ RARE_JOKER, 8, the_family_joker_effect}, // 36
{ RARE_JOKER, 8, the_order_joker_effect}, // 37
{ RARE_JOKER, 8, the_tribe_joker_effect}, // 38
// The following jokers don't have sprites yet,
// uncomment them when their sprites are added.
@@ -558,6 +676,8 @@ const JokerInfo joker_registry[] = {
{ RARE_JOKER, 10, blueprint_joker_effect },
{ RARE_JOKER, 10, brainstorm_joker_effect },
{ UNCOMMON_JOKER, 7, bootstraps_joker_effect},
{ COMMON_JOKER, 5, shoot_the_moon_joker_effect},
#endif
};
-1
View File
@@ -98,7 +98,6 @@ void sprite_init()
void sprite_draw()
{
obj_copy(obj_mem, obj_buffer, MAX_SPRITES);
obj_aff_copy(obj_aff_mem, obj_aff_buffer, MAX_AFFINES);
oam_copy(oam_mem, obj_buffer, MAX_SPRITES);
}
+10
View File
@@ -0,0 +1,10 @@
#ifndef GIT_HASH
#define GIT_HASH "undef"
#endif
#ifndef GIT_DIRTY
#define GIT_DIRTY "-dirty"
#endif
__attribute__((section(".version"), used))
const char balatro_version[] = "GBALATRO_VERSION:" GIT_HASH GIT_DIRTY;