Clone
1
Expanded Game Corner
judicornadamsfoster edited this page 2026-07-31 18:37:52 +01:00

original source: heyopc's branch

heyopc's readme:
Hello! This is an an all-in-one package to expand the Mauville Game Corner, that, in its current state, isn't configurable. It uses several unused Emerald flags, vars, and FR/LG tracks to make things work... Please keep this in mind if you would like to use this for your own hack.

More specifically, this adds 4 pinball mini-games, Flappy Bird, Block Stacker, Snake, Blackjack, Voltorb Flip, Plinko, Mauville Derby, and Gacha Machines into the Game Corner.

THIS IS CURRENTLY NOT COMPATIBLE WITH EMERALD EXPANSION!

Big thank you to huderlem (Pokemon Pinball to Emerald), and Pokeabbie (Voltorb Flip from Emerald Rogue). All I really did for these was some graphics, music, and code to work with coins. They deserve the real credits here. Also thank you to Viperio, who made an initial Snake for Pokemon Emerald that I based my code on.

pokeemerald-0 pokeemerald-1 pokeemerald-2 pokeemerald-3 pokeemerald-4 pokeemerald-6 pokeemerald-8 pokeemerald-12 pokeemerald-16 pokeemerald-17 pokeemerald-18 pokeemerald-19

Judicorn's note: I couldn't get the Gacha machines working on up-to-date pokeemerald code, so I had to block off access to them. not working


to add to your hack:

pull the branch:

git remote add tenaya15 https://github.com/tenaya15/tenaya15emerald.git
git pull tenaya15 game_corner_expansion

or see below on how to add manually


new files

first, unzip and copy these files into your hack, overwriting any files

Important note: if you have made any changes specifically to data/maps/MauvilleCity_GameCorner, data/tilesets/secondary/mauville_game_corner, you will need to port these to the new files accordingly


[root]/ld_script.ld

add after src/international_string_util.o(.text); but before } > ROM =0

        src/game_corner_gacha.o(.text);
		src/rogue_voltorbflip.o(.text);
		src/pinball.o(.text);
		src/pachinko.o(.text);
		src/block_stacker.o(.text);
		src/derby.o(.text);
		src/snake.o(.text);
		src/flappybird.o(.text);

then add after data/sound_data.o(.rodata); but before } > ROM =0

        src/game_corner_gacha.o(.rodata);
		src/rogue_voltorbflip.o(.rodata);
		src/pinball.o(.rodata);
		src/pachinko.o(.rodata);
		src/block_stacker.o(.rodata);
		src/derby.o(.rodata);
		src/snake.o(.rodata);
		src/flappybird.o(.rodata);

[root]/sym_ewram.txt

add at the end of the file after .include "src/rayquaza_scene.o"

    .include "src/game_corner_gacha.o"
	.include "src/rogue_voltorbflip.o"
	.include "src/pinball.o"
	.include "src/pachinko.o"
	.include "src/block_stacker.o"
	.include "src/derby.o"
	.include "src/snake.o"
	.include "src/flappybird.o"


data/layouts/layouts.json

search for "id": "LAYOUT_MAUVILLE_CITY_GAME_CORNER", (at line 905)
change width and height to:

      "width": 30,
      "height": 22,

so the section should be:

      "id": "LAYOUT_MAUVILLE_CITY_GAME_CORNER",
      "name": "MauvilleCity_GameCorner_Layout",
      "width": 30,
      "height": 22,
      "primary_tileset": "gTileset_Building",
      "secondary_tileset": "gTileset_MauvilleGameCorner",
      "border_filepath": "data/layouts/MauvilleCity_GameCorner/border.bin",
      "blockdata_filepath": "data/layouts/MauvilleCity_GameCorner/map.bin"

data/specials.inc

add these to the end of the file

	def_special StartBlackJack
	def_special StartGacha
	def_special StartBlockStacker
	def_special StartDerby
	def_special GetNewDerby
	def_special StartSnake
	def_special StartFlappyBird
	def_special Special_ViewVoltorbFlip
	

include/constants/flags.h

rename 3 flags
eg:

#define FLAG_INSURANCE	     0x20 // Unused Flag
#define FLAG_RESET_BJ	     0x21 // Unused Flag
#define FLAG_BLACKJACK	     0x22 // Unused Flag

include/constants/script_menu.h

rename 2 unused "multi" #defines
eg:

#define MULTI_GAMECORNER_NEW2              21
#define MULTI_GAMECORNER_NEW               22 // New Prizes

include/constants/vars.h

rename 25 unused vars

#define VAR_RACER_NAME_1                                 0x4064 // Used for Race Names
#define VAR_RACER_NAME_2                                 0x4065 
#define VAR_RACER_NAME_3                                 0x4066 
#define VAR_RACER_NAME_4                                 0x4067 
#define VAR_RACER_NAME_5                                 0x4068 

#define VAR_RACER_NAME_6                                 0x406A 
#define VAR_NICKNAME_TOGGLE                              0x406B // Confirms if Nicknames were Set
#define VAR_FLAPPY_HISCORE                               0x406C // For Hi Scores
#define VAR_TRAINER_ID_CHECK                             0x406D // Game Corner Gag

#define VAR_RACER_1		                                 0x4075 // Race Values (Species, Shiny, Condition)
#define VAR_RACER_2 	                                 0x4076 // Race Var
#define VAR_RACER_3        	   	                         0x4077 // Race Var
#define VAR_RACER_4     	                             0x4078 // Race Var
#define VAR_RACER_5        		                         0x4079 // Race Var
#define VAR_RACER_6            		                     0x407A // Race Var

#define VAR_NEW_DERBY	                                 0x407C // Check for Derby Reset

#define VAR_PLAYER_BJ	                                 0x40F7 // Unused Var
#define VAR_DEALER_BJ	                                 0x40F8 // Unused Var
#define VAR_BET_BJ		                                 0x40F9 // Unused Var
#define VAR_OPTIONS_BJ	                                 0x40FA // Unused Var
#define VAR_OPTION1_TILENUM                              0x40FB // Unused Var
#define VAR_OPTION2_TILENUM                              0x40FC // Unused Var
#define VAR_OPTION3_TILENUM                              0x40FD // Unused Var
#define VAR_FLIP_LEVEL	                                 0x40FE // Unused Var
#define VAR_FLIP_WINNINGS                                0x40FF // Unused Var

include/gba/types.h

add after #define SPRITE_SIZE_32x64 ((ST_OAM_SIZE_3 << 2) | (ST_OAM_V_RECTANGLE))

#define SPRITE_SIZE_64x16   ((ST_OAM_SIZE_3 << 2) | (ST_OAM_H_RECTANGLE))


include/strings.h

add to end of file after the extern entries but before #endif // GUARD_STRINGS_H

extern const u8 gText_RareCandy[];
extern const u8 gText_WStone[];
extern const u8 gText_FStone[];
extern const u8 gText_LStone[];
extern const u8 gText_TStone[];
extern const u8 gText_MStone[];
extern const u8 gText_SStone[];
extern const u8 gText_ChoiceB[];
extern const u8 gText_BrightP[];

// Blackjack
extern const u8 gText_Bust[];
extern const u8 gText_YouLose[];
extern const u8 gText_YouWin[];
extern const u8 gText_Push[];
extern const u8 gText_BlackJack[];

extern const u8 gText_Betting[];
extern const u8 gText_NoBetting[];
extern const u8 gText_NoMoney[];


include/tileset_anims.h

add to end of file but before #endif // GUARD_TILESET_ANIMS_H

void InitTilesetAnim_MauvilleGameCorner(void);

src/data/script_menu.h

note: items should match the items chosen in `data/maps/MauvilleCity_GameCorner/scripts.inc

add after section static const struct MenuAction MultichoiceList_Exit[] =

static const struct MenuAction MultichoiceList_GCNew[] =
{
    {gText_RareCandy},
	{gText_SStone},
	{gText_MStone},
	{gText_ChoiceB},
	{gText_BrightP},
	{gText_Exit},
};

static const struct MenuAction MultichoiceList_GCNew2[] =
{
	{gText_FStone},
	{gText_TStone},
	{gText_WStone},
	{gText_LStone},
	{gText_Exit},
};

__

add to static const struct MultichoiceListStruct sMultichoiceLists[] =
(replace the 2 unused "multi" that was changed in include/constants/script_menu.h)

    [MULTI_GAMECORNER_NEW2]            = MULTICHOICE(MultichoiceList_GCNew2),
    [MULTI_GAMECORNER_NEW]             = MULTICHOICE(MultichoiceList_GCNew),

src/data/tilesets/headers.h

search for const struct Tileset gTileset_MauvilleGameCorner = (at line 529)
change .callback = NULL, to

    .callback = InitTilesetAnim_MauvilleGameCorner,

src/field_specials.c

add near the top, at the end of the #include section

#include "rogue_voltorbflip.h"

__

add after section void Special_ShowDiploma(void)


void Special_ViewVoltorbFlip(void)
{
    gMain.savedCallback = CB2_ReturnToField;
    SetMainCallback2(CB2_ShowVoltorbFlip);
    LockPlayerFieldControls();
}

src/new_game.c

add near the top, at the end of the #include section

#include "derby.h"

__

in section void NewGameInitData(void)
add after SetCoins(0);

    GetNewDerby();

src/strings.c

add to the end of the file

note: items and price should match the items chosen in `data/maps/MauvilleCity_GameCorner/scripts.inc

const u8 gText_RareCandy[] = _("RARE CANDY{CLEAR_TO 0x48}4,000 COINS");
const u8 gText_WStone[] = _("WATER STONE{CLEAR_TO 0x48}2,000 COINS");
const u8 gText_FStone[] = _("FIRE STONE{CLEAR_TO 0x48}2,000 COINS");
const u8 gText_LStone[] = _("LEAF STONE{CLEAR_TO 0x48}2,000 COINS");
const u8 gText_TStone[] = _("THUNDERSTONE{CLEAR_TO 0x48}2,000 COINS");
const u8 gText_MStone[] = _("MOON STONE{CLEAR_TO 0x48}2,000 COINS");
const u8 gText_SStone[] = _("SUN STONE{CLEAR_TO 0x48}2,000 COINS");
const u8 gText_ChoiceB[] = _("CHOICE BAND{CLEAR_TO 0x48}4,500 COINS");
const u8 gText_BrightP[] = _("BRIGHTPOWDER{CLEAR_TO 0x48}4,500 COINS");

const u8 gText_FromGacha[] = _("You got {STR_VAR_1}!");
const u8 gText_NicknameGacha[] = _("Would you like to give {STR_VAR_1}\na nickname?");

//BlackJack
const u8 gText_Bust[] = _("BUST!");
const u8 gText_YouLose[] = _("You lose!");
const u8 gText_YouWin[] = _("You win!");
const u8 gText_Push[] = _("PUSH!");
const u8 gText_BlackJack[] = _("BLACKJACK!");

const u8 gText_Betting[] = _("Your current\nbet is ¥{STR_VAR_1}.");
const u8 gText_NoBetting[] = _("Your current\nbet is ¥0.");
const u8 gText_NoMoney[] = _("You do not have\nenough COINS.");

src/tileset_anims.c

add at the end of file

static void TilesetAnim_Mauville_Game_Corner(u16);

static void QueueAnimTiles_Mauville_Game_Corner_Lights(u16);

const u16 gTilesetAnims_MauvilleGameCorner_Lights_Frame0[] = INCBIN_U16("data/tilesets/secondary/mauville_game_corner/anim/lights/light_anim_0.4bpp");
const u16 gTilesetAnims_MauvilleGameCorner_Lights_Frame1[] = INCBIN_U16("data/tilesets/secondary/mauville_game_corner/anim/lights/light_anim_1.4bpp");
const u16 gTilesetAnims_MauvilleGameCorner_Lights_Frame2[] = INCBIN_U16("data/tilesets/secondary/mauville_game_corner/anim/lights/light_anim_2.4bpp");
const u16 gTilesetAnims_MauvilleGameCorner_Lights_Frame3[] = INCBIN_U16("data/tilesets/secondary/mauville_game_corner/anim/lights/light_anim_3.4bpp");
const u16 gTilesetAnims_MauvilleGameCorner_Lights_Frame4[] = INCBIN_U16("data/tilesets/secondary/mauville_game_corner/anim/lights/light_anim_4.4bpp");
const u16 gTilesetAnims_MauvilleGameCorner_Lights_Frame5[] = INCBIN_U16("data/tilesets/secondary/mauville_game_corner/anim/lights/light_anim_5.4bpp");

const u16 *const gTilesetAnims_Mauville_Game_Corner_Lights[] = {
    gTilesetAnims_MauvilleGameCorner_Lights_Frame0,
    gTilesetAnims_MauvilleGameCorner_Lights_Frame1,
    gTilesetAnims_MauvilleGameCorner_Lights_Frame2,
    gTilesetAnims_MauvilleGameCorner_Lights_Frame3,
    gTilesetAnims_MauvilleGameCorner_Lights_Frame4,
    gTilesetAnims_MauvilleGameCorner_Lights_Frame5
};

static void QueueAnimTiles_Mauville_Game_Corner_Lights(u16 timer)
{
    u16 i = timer % 6; 
    AppendTilesetAnimToBuffer(gTilesetAnims_Mauville_Game_Corner_Lights[i], (u16 *)(BG_VRAM + TILE_OFFSET_4BPP(521)), 0x40);
}

void InitTilesetAnim_MauvilleGameCorner(void)
{
    sSecondaryTilesetAnimCounter = 0;
    sSecondaryTilesetAnimCounterMax = 128;
    sSecondaryTilesetAnimCallback = TilesetAnim_Mauville_Game_Corner;
}

static void TilesetAnim_Mauville_Game_Corner(u16 timer)
{
    if (timer % 16 == 0)
        QueueAnimTiles_Mauville_Game_Corner_Lights(timer / 16);
}