Table of Contents
- new files
- [root]/ld_script.ld
- [root]/sym_ewram.txt
- data/layouts/layouts.json
- data/specials.inc
- include/constants/flags.h
- include/constants/script_menu.h
- include/constants/vars.h
- include/gba/types.h
- include/strings.h
- include/tileset_anims.h
- src/data/script_menu.h
- src/data/tilesets/headers.h
- src/field_specials.c
- src/new_game.c
- src/strings.c
- src/tileset_anims.c
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.
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.
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);
}