I hope this fixes merge conflicts

This commit is contained in:
U-User-PC\User
2017-10-03 15:54:19 -04:00
753 changed files with 66515 additions and 88776 deletions

17
src/battle_1.c Normal file
View File

@@ -0,0 +1,17 @@
// Includes
#include "global.h"
// Static type declarations
// Static RAM declarations
IWRAM_DATA u32 gUnknown_03000DD4;
IWRAM_DATA u32 gUnknown_03000DD8;
IWRAM_DATA u32 gUnknown_03000DDC;
// Static ROM declarations
// .rodata
// .text

6408
src/battle_3.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,601 +0,0 @@
#include "global.h"
#include "battle.h"
#include "battle_move_effects.h"
#include "moves.h"
#include "abilities.h"
#include "item.h"
#include "items.h"
#include "hold_effects.h"
void atk00_attackcanceler(void);
void atk01_accuracycheck(void);
void atk02_attackstring(void);
void atk03_ppreduce(void);
void atk04_critcalc(void);
void atk05_damagecalc1(void);
void atk06_typecalc(void);
void atk07_dmg_adjustment(void);
void atk08_dmg_adjustment2(void);
void atk09_attackanimation(void);
void atk0A_waitanimation(void);
void atk0B_healthbarupdate(void);
void atk0C_datahpupdate(void);
void atk0D_critmessage(void);
void atk0E_effectiveness_sound(void);
void atk0F_resultmessage(void);
void atk10_printstring(void);
void atk11_printstring_playeronly(void);
void atk12_waitmessage(void);
void atk13_printfromtable(void);
void atk14_printfromtable_playeronly(void);
void atk15_seteffectwithchancetarget(void);
void atk16_seteffectprimary(void);
void atk17_seteffectsecondary(void);
void atk18_status_effect_clear(void);
void atk19_faint_pokemon(void);
void atk1A_faint_animation(void);
void atk1B_faint_effects_clear(void);
void atk1C_jumpifstatus(void);
void atk1D_jumpifstatus2(void);
void atk1E_jumpifability(void);
void atk1F_jumpifsideaffecting(void);
void atk20_jumpifstat(void);
void atk21_jumpifstatus3(void);
void atk22_jumpiftype(void);
void atk23_getexp(void);
void atk24(void);
void atk25_move_values_cleanup(void);
void atk26_set_multihit(void);
void atk27_decrement_multihit(void);
void atk28_goto(void);
void atk29_jumpifbyte(void);
void atk2A_jumpifhalfword(void);
void atk2B_jumpifword(void);
void atk2C_jumpifarrayequal(void);
void atk2D_jumpifarraynotequal(void);
void atk2E_setbyte(void);
void atk2F_addbyte(void);
void atk30_subbyte(void);
void atk31_copyarray(void);
void atk32_copyarray_withindex(void);
void atk33_orbyte(void);
void atk34_orhalfword(void);
void atk35_orword(void);
void atk36_bicbyte(void);
void atk37_bichalfword(void);
void atk38_bicword(void);
void atk39_pause(void);
void atk3A_waitstate(void);
void atk3B_healthbar_update(void);
void atk3C_return(void);
void atk3D_end(void);
void atk3E_end2(void);
void atk3F_end3(void);
void atk40_jump_if_move_affected_by_protect(void);
void atk41_call(void);
void atk42_jumpiftype2(void);
void atk43_jumpifabilitypresent(void);
void atk44(void);
void atk45_playanimation(void);
void atk46_playanimation2(void);
void atk47_setgraphicalstatchangevalues(void);
void atk48_playstatchangeanimation(void);
void atk49_moveendturn(void);
void atk4A_typecalc2(void);
void atk4B_return_atk_to_ball(void);
void atk4C_copy_poke_data(void);
void atk4D_switch_data_update(void);
void atk4E_switchin_anim(void);
void atk4F_jump_if_cannot_switch(void);
void atk50_openpartyscreen(void);
void atk51_switch_handle_order(void);
void atk52_switch_in_effects(void);
void atk53_trainer_slide(void);
void atk54_effectiveness_sound(void);
void atk55_play_sound(void);
void atk56_fainting_cry(void);
void atk57(void);
void atk58_return_to_ball(void);
void atk59_learnmove_inbattle(void);
void atk5A(void);
void atk5B_80256E0(void);
void atk5C_hitanimation(void);
void atk5D_getmoneyreward(void);
void atk5E_8025A70(void);
void atk5F_8025B24(void);
void atk60_increment_gamestat(void);
void atk61_8025BA4(void);
void atk62_08025C6C(void);
void atk63_jumptorandomattack(void);
void atk64_statusanimation(void);
void atk65_status2animation(void);
void atk66_chosenstatusanimation(void);
void atk67_8025ECC(void);
void atk68_80246A0(void);
void atk69_dmg_adjustment2(void);
void atk6A_removeitem(void);
void atk6B_atknameinbuff1(void);
void atk6C_lvlbox_display(void);
void atk6D_set_sentpokes_values(void);
void atk6E_set_atk_to_player0(void);
void atk6F_set_visible(void);
void atk70_record_ability(void);
void atk71_buffer_move_to_learn(void);
void atk72_jump_if_can_run_frombattle(void);
void atk73_hp_thresholds(void);
void atk74_hp_thresholds2(void);
void atk75_8026A58(void);
void atk76_various(void);
void atk77_setprotect(void);
void atk78_faintifabilitynotdamp(void);
void atk79_setatkhptozero(void);
void atk7A_jumpwhiletargetvalid(void);
void atk7B_healhalfHP_if_possible(void);
void atk7C_8025508(void);
void atk7D_set_rain(void);
void atk7E_setreflect(void);
void atk7F_setseeded(void);
void atk80_manipulatedamage(void);
void atk81_setrest(void);
void atk82_jumpifnotfirstturn(void);
void atk83_nop(void);
void atk84_jump_if_cant_sleep(void);
void atk85_stockpile(void);
void atk86_stockpiletobasedamage(void);
void atk87_stockpiletohpheal(void);
void atk88_negativedamage(void);
void atk89_statbuffchange(void);
void atk8A_normalisebuffs(void);
void atk8B_setbide(void);
void atk8C_confuseifrepeatingattackends(void);
void atk8D_setmultihit_counter(void);
void atk8E_prepare_multihit(void);
void atk8F_forcerandomswitch(void);
void atk90_conversion_type_change(void);
void atk91_givepaydaymoney(void);
void atk92_setlightscreen(void);
void atk93_ko_move(void);
void atk94_gethalfcurrentenemyhp(void);
void atk95_setsandstorm(void);
void atk96_weatherdamage(void);
void atk97_try_infatuation(void);
void atk98_status_icon_update(void);
void atk99_setmist(void);
void atk9A_set_focusenergy(void);
void atk9B_transformdataexecution(void);
void atk9C_set_substitute(void);
void atk9D_copyattack(void);
void atk9E_metronome(void);
void atk9F_dmgtolevel(void);
void atkA0_psywavedamageeffect(void);
void atkA1_counterdamagecalculator(void);
void atkA2_mirrorcoatdamagecalculator(void);
void atkA3_disablelastusedattack(void);
void atkA4_setencore(void);
void atkA5_painsplitdmgcalc(void);
void atkA6_settypetorandomresistance(void);
void atkA7_setalwayshitflag(void);
void atkA8_copymovepermanently(void);
void atkA9_sleeptalk_choose_move(void);
void atkAA_set_destinybond(void);
void atkAB_DestinyBondFlagUpdate(void);
void atkAC_remaininghptopower(void);
void atkAD_spite_ppreduce(void);
void atkAE_heal_party_status(void);
void atkAF_cursetarget(void);
void atkB0_set_spikes(void);
void atkB1_set_foresight(void);
void atkB2_setperishsong(void);
void atkB3_rolloutdamagecalculation(void);
void atkB4_jumpifconfusedandstatmaxed(void);
void atkB5_furycuttercalc(void);
void atkB6_happinesstodamagecalculation(void);
void atkB7_presentdamagecalculation(void);
void atkB8_set_safeguard(void);
void atkB9_magnitudedamagecalculation(void);
void atkBA_jumpifnopursuitswitchdmg(void);
void atkBB_setsunny(void);
void atkBC_maxattackhalvehp(void);
void atkBD_copyfoestats(void);
void atkBE_breakfree(void);
void atkBF_set_defense_curl(void);
void atkC0_recoverbasedonsunlight(void);
void atkC1_hidden_power(void);
void atkC2_selectnexttarget(void);
void atkC3_setfutureattack(void);
void atkC4_beat_up(void);
void atkC5_hidepreattack(void);
void atkC6_unhidepostattack(void);
void atkC7_setminimize(void);
void atkC8_sethail(void);
void atkC9_jumpifattackandspecialattackcannotfall(void);
void atkCA_setforcedtarget(void);
void atkCB_setcharge(void);
void atkCC_callterrainattack(void);
void atkCD_cureifburnedparalysedorpoisoned(void);
void atkCE_settorment(void);
void atkCF_jumpifnodamage(void);
void atkD0_settaunt(void);
void atkD1_set_helpinghand(void);
void atkD2_swap_items(void);
void atkD3_copy_ability(void);
void atkD4_wish_effect(void);
void atkD5_setroots(void);
void atkD6_doubledamagedealtifdamaged(void);
void atkD7_setyawn(void);
void atkD8_setdamagetohealthdifference(void);
void atkD9_scaledamagebyhealthratio(void);
void atkDA_abilityswap(void);
void atkDB_imprisoneffect(void);
void atkDC_setgrudge(void);
void atkDD_weightdamagecalculation(void);
void atkDE_asistattackselect(void);
void atkDF_setmagiccoat(void);
void atkE0_setstealstatchange(void);
void atkE1_intimidate_string_loader(void);
void atkE2_switchout_abilities(void);
void atkE3_jumpiffainted(void);
void atkE4_getsecretpowereffect(void);
void atkE5_pickup(void);
void atkE6_castform_change_animation(void);
void atkE7_castform_data_change(void);
void atkE8_settypebasedhalvers(void);
void atkE9_setweatherballtype(void);
void atkEA_recycleitem(void);
void atkEB_settypetoterrain(void);
void atkEC_pursuit_sth(void);
void atkED_802B4B4(void);
void atkEE_removelightscreenreflect(void);
void atkEF_pokeball_catch_calculation(void);
void atkF0_copy_caught_poke(void);
void atkF1_setpoke_as_caught(void);
void atkF2_display_dex_info(void);
void atkF3_nickname_caught_poke(void);
void atkF4_802BEF0(void);
void atkF5_removeattackerstatus1(void);
void atkF6_802BF48(void);
void atkF7_802BF54(void);
void sub_8056EF8(void);
void (* const gBattleScriptingCommandsTable[])(void) =
{
atk00_attackcanceler,
atk01_accuracycheck,
atk02_attackstring,
atk03_ppreduce,
atk04_critcalc,
atk05_damagecalc1,
atk06_typecalc,
atk07_dmg_adjustment,
atk08_dmg_adjustment2,
atk09_attackanimation,
atk0A_waitanimation,
atk0B_healthbarupdate,
atk0C_datahpupdate,
atk0D_critmessage,
atk0E_effectiveness_sound,
atk0F_resultmessage,
atk10_printstring,
atk11_printstring_playeronly,
atk12_waitmessage,
atk13_printfromtable,
atk14_printfromtable_playeronly,
atk15_seteffectwithchancetarget,
atk16_seteffectprimary,
atk17_seteffectsecondary,
atk18_status_effect_clear,
atk19_faint_pokemon,
atk1A_faint_animation,
atk1B_faint_effects_clear,
atk1C_jumpifstatus,
atk1D_jumpifstatus2,
atk1E_jumpifability,
atk1F_jumpifsideaffecting,
atk20_jumpifstat,
atk21_jumpifstatus3,
atk22_jumpiftype,
atk23_getexp,
atk24,
atk25_move_values_cleanup,
atk26_set_multihit,
atk27_decrement_multihit,
atk28_goto,
atk29_jumpifbyte,
atk2A_jumpifhalfword,
atk2B_jumpifword,
atk2C_jumpifarrayequal,
atk2D_jumpifarraynotequal,
atk2E_setbyte,
atk2F_addbyte,
atk30_subbyte,
atk31_copyarray,
atk32_copyarray_withindex,
atk33_orbyte,
atk34_orhalfword,
atk35_orword,
atk36_bicbyte,
atk37_bichalfword,
atk38_bicword,
atk39_pause,
atk3A_waitstate,
atk3B_healthbar_update,
atk3C_return,
atk3D_end,
atk3E_end2,
atk3F_end3,
atk40_jump_if_move_affected_by_protect,
atk41_call,
atk42_jumpiftype2,
atk43_jumpifabilitypresent,
atk44,
atk45_playanimation,
atk46_playanimation2,
atk47_setgraphicalstatchangevalues,
atk48_playstatchangeanimation,
atk49_moveendturn,
atk4A_typecalc2,
atk4B_return_atk_to_ball,
atk4C_copy_poke_data,
atk4D_switch_data_update,
atk4E_switchin_anim,
atk4F_jump_if_cannot_switch,
atk50_openpartyscreen,
atk51_switch_handle_order,
atk52_switch_in_effects,
atk53_trainer_slide,
atk54_effectiveness_sound,
atk55_play_sound,
atk56_fainting_cry,
atk57,
atk58_return_to_ball,
atk59_learnmove_inbattle,
atk5A,
atk5B_80256E0,
atk5C_hitanimation,
atk5D_getmoneyreward,
atk5E_8025A70,
atk5F_8025B24,
atk60_increment_gamestat,
atk61_8025BA4,
atk62_08025C6C,
atk63_jumptorandomattack,
atk64_statusanimation,
atk65_status2animation,
atk66_chosenstatusanimation,
atk67_8025ECC,
atk68_80246A0,
atk69_dmg_adjustment2,
atk6A_removeitem,
atk6B_atknameinbuff1,
atk6C_lvlbox_display,
atk6D_set_sentpokes_values,
atk6E_set_atk_to_player0,
atk6F_set_visible,
atk70_record_ability,
atk71_buffer_move_to_learn,
atk72_jump_if_can_run_frombattle,
atk73_hp_thresholds,
atk74_hp_thresholds2,
atk75_8026A58,
atk76_various,
atk77_setprotect,
atk78_faintifabilitynotdamp,
atk79_setatkhptozero,
atk7A_jumpwhiletargetvalid,
atk7B_healhalfHP_if_possible,
atk7C_8025508,
atk7D_set_rain,
atk7E_setreflect,
atk7F_setseeded,
atk80_manipulatedamage,
atk81_setrest,
atk82_jumpifnotfirstturn,
atk83_nop,
atk84_jump_if_cant_sleep,
atk85_stockpile,
atk86_stockpiletobasedamage,
atk87_stockpiletohpheal,
atk88_negativedamage,
atk89_statbuffchange,
atk8A_normalisebuffs,
atk8B_setbide,
atk8C_confuseifrepeatingattackends,
atk8D_setmultihit_counter,
atk8E_prepare_multihit,
atk8F_forcerandomswitch,
atk90_conversion_type_change,
atk91_givepaydaymoney,
atk92_setlightscreen,
atk93_ko_move,
atk94_gethalfcurrentenemyhp,
atk95_setsandstorm,
atk96_weatherdamage,
atk97_try_infatuation,
atk98_status_icon_update,
atk99_setmist,
atk9A_set_focusenergy,
atk9B_transformdataexecution,
atk9C_set_substitute,
atk9D_copyattack,
atk9E_metronome,
atk9F_dmgtolevel,
atkA0_psywavedamageeffect,
atkA1_counterdamagecalculator,
atkA2_mirrorcoatdamagecalculator,
atkA3_disablelastusedattack,
atkA4_setencore,
atkA5_painsplitdmgcalc,
atkA6_settypetorandomresistance,
atkA7_setalwayshitflag,
atkA8_copymovepermanently,
atkA9_sleeptalk_choose_move,
atkAA_set_destinybond,
atkAB_DestinyBondFlagUpdate,
atkAC_remaininghptopower,
atkAD_spite_ppreduce,
atkAE_heal_party_status,
atkAF_cursetarget,
atkB0_set_spikes,
atkB1_set_foresight,
atkB2_setperishsong,
atkB3_rolloutdamagecalculation,
atkB4_jumpifconfusedandstatmaxed,
atkB5_furycuttercalc,
atkB6_happinesstodamagecalculation,
atkB7_presentdamagecalculation,
atkB8_set_safeguard,
atkB9_magnitudedamagecalculation,
atkBA_jumpifnopursuitswitchdmg,
atkBB_setsunny,
atkBC_maxattackhalvehp,
atkBD_copyfoestats,
atkBE_breakfree,
atkBF_set_defense_curl,
atkC0_recoverbasedonsunlight,
atkC1_hidden_power,
atkC2_selectnexttarget,
atkC3_setfutureattack,
atkC4_beat_up,
atkC5_hidepreattack,
atkC6_unhidepostattack,
atkC7_setminimize,
atkC8_sethail,
atkC9_jumpifattackandspecialattackcannotfall,
atkCA_setforcedtarget,
atkCB_setcharge,
atkCC_callterrainattack,
atkCD_cureifburnedparalysedorpoisoned,
atkCE_settorment,
atkCF_jumpifnodamage,
atkD0_settaunt,
atkD1_set_helpinghand,
atkD2_swap_items,
atkD3_copy_ability,
atkD4_wish_effect,
atkD5_setroots,
atkD6_doubledamagedealtifdamaged,
atkD7_setyawn,
atkD8_setdamagetohealthdifference,
atkD9_scaledamagebyhealthratio,
atkDA_abilityswap,
atkDB_imprisoneffect,
atkDC_setgrudge,
atkDD_weightdamagecalculation,
atkDE_asistattackselect,
atkDF_setmagiccoat,
atkE0_setstealstatchange,
atkE1_intimidate_string_loader,
atkE2_switchout_abilities,
atkE3_jumpiffainted,
atkE4_getsecretpowereffect,
atkE5_pickup,
atkE6_castform_change_animation,
atkE7_castform_data_change,
atkE8_settypebasedhalvers,
atkE9_setweatherballtype,
atkEA_recycleitem,
atkEB_settypetoterrain,
atkEC_pursuit_sth,
atkED_802B4B4,
atkEE_removelightscreenreflect,
atkEF_pokeball_catch_calculation,
atkF0_copy_caught_poke,
atkF1_setpoke_as_caught,
atkF2_display_dex_info,
atkF3_nickname_caught_poke,
atkF4_802BEF0,
atkF5_removeattackerstatus1,
atkF6_802BF48,
atkF7_802BF54,
sub_8056EF8
};
struct statFractions
{
u8 dividend;
u8 divisor;
};
const struct statFractions gAccuracyStageRatios[] =
{
{ 33, 100}, // -6
{ 36, 100}, // -5
{ 43, 100}, // -4
{ 50, 100}, // -3
{ 60, 100}, // -2
{ 75, 100}, // -1
{ 1, 1}, // 0
{133, 100}, // +1
{166, 100}, // +2
{ 2, 1}, // +3
{233, 100}, // +4
{133, 50}, // +5
{ 3, 1}, // +6
};
// The chance is 1/N for each stage.
const u16 gCriticalHitChance[] = {16, 8, 4, 3, 2};
const u32 gStatusFlagsForMoveEffects[] =
{
0x00000000,
0x00000007,
0x00000008,
0x00000010,
0x00000020,
0x00000040,
0x00000080,
0x00000007,
0x00000008,
0x00000000,
0x00000070,
0x00000000,
0x00001000,
0x0000E000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00400000,
0x00000000,
0x00000000,
0x04000000,
0x08000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000C00,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000
};

View File

@@ -1,5 +1,5 @@
#include "global.h"
#include "battle_ai.h"
#include "battle_ai_script_commands.h"
#include "pokemon.h"
#include "battle.h"
#include "species.h"
@@ -73,10 +73,7 @@ extern const struct BaseStats gBaseStats[];
extern const u32 gBitTable[];
extern u8 * const gBattleAI_ScriptsTable[];
extern u8 GetBankIdentity(u8);
extern u8 b_first_side(u8, u8, u8);
extern u8 GetBankByPlayerAI(u8);
extern void TypeCalc(u16 move, u8 bankAtk, u8 bankDef);
extern void AI_CalcDmg(u8, u8);
extern u8 CheckMoveLimitations();
@@ -87,7 +84,7 @@ static u8 BattleAI_ChooseMoveOrAction_Singles(void);
static u8 BattleAI_ChooseMoveOrAction_Doubles(void);
static void RecordLastUsedMoveByTarget(void);
static void BattleAI_DoAIProcessing(void);
static void AIStackPushVar(u8 *);
static void AIStackPushVar(const u8 *);
static bool8 AIStackPop(void);
static void BattleAICmd_if_random_less_than(void);
@@ -192,7 +189,7 @@ static void BattleAICmd_if_holds_item(void);
// ewram
EWRAM_DATA u8 *gAIScriptPtr = NULL;
EWRAM_DATA const u8 *gAIScriptPtr = NULL;
EWRAM_DATA static u8 sBank_AI = 0;
// const rom data
@@ -1805,7 +1802,7 @@ static void BattleAICmd_count_alive_pokemon(void)
u32 status;
bankOnField1 = gBattlePartyID[index];
status = GetBankIdentity(index) ^ 2;
bankOnField2 = gBattlePartyID[GetBankByPlayerAI(status)];
bankOnField2 = gBattlePartyID[GetBankByIdentity(status)];
}
else // in singles there's only one bank by side
{
@@ -2902,7 +2899,7 @@ static void BattleAICmd_if_flash_fired(void)
gAIScriptPtr += 6;
}
static void AIStackPushVar(u8 *var)
static void AIStackPushVar(const u8 *var)
{
gBattleResources->AI_ScriptsStack->ptr[gBattleResources->AI_ScriptsStack->size++] = var;
}

430
src/battle_dome_cards.c Normal file
View File

@@ -0,0 +1,430 @@
// Includes
#include "global.h"
#include "sprite.h"
#include "window.h"
#include "malloc.h"
#include "species.h"
#include "palette.h"
#include "decompress.h"
#include "battle_dome_cards.h"
extern const struct CompressedSpriteSheet gMonFrontPicTable[NUM_SPECIES];
extern const struct CompressedSpriteSheet gMonBackPicTable[NUM_SPECIES];
extern const struct CompressedSpriteSheet gTrainerFrontPicTable[];
extern const struct CompressedSpriteSheet gTrainerBackPicTable[];
extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[];
extern const union AffineAnimCmd *const gUnknown_082FF618[];
extern const union AffineAnimCmd *const gUnknown_082FF694[];
extern const union AnimCmd *const gUnknown_082FF70C[];
extern const union AnimCmd *const *const gUnknown_08309AAC[NUM_SPECIES];
extern const union AnimCmd *const *const gUnknown_0830536C[];
extern const u8 gUnknown_0831F578[];
// Static type declarations
struct BattleDomeCard {
u8 *frames;
struct SpriteFrameImage *images;
u16 paletteTag;
u8 spriteId;
u8 active;
};
// Static RAM declarations
static EWRAM_DATA struct SpriteTemplate gUnknown_0203CCEC = {};
static EWRAM_DATA struct BattleDomeCard gUnknown_0203CD04[8] = {};
// Static ROM declarations
// .rodata
static const struct BattleDomeCard gUnknown_0860B058 = {};
static const struct OamData gUnknown_0860B064 = {
.size = 3
};
static const struct OamData gUnknown_0860B06C = {
.affineMode = 1, .size = 3
};
// .text
static void nullsub_122(struct Sprite *sprite)
{
}
bool16 dp13_810BB8C(void)
{
int i;
for (i = 0; i < 8; i ++)
{
gUnknown_0203CD04[i] = gUnknown_0860B058;
}
return FALSE;
}
static bool16 load_pokemon_image_TODO(u16 species, u32 personality, bool8 isFrontPic, u8 *dest, bool8 isTrainer, bool8 ignoreDeoxys)
{
if (!isTrainer)
{
if (isFrontPic)
{
if (!ignoreDeoxys)
{
LoadSpecialPokePic(&gMonFrontPicTable[species], dest, species, personality, isFrontPic);
}
else
{
LoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species], dest, species, personality, isFrontPic);
}
}
else
{
if (!ignoreDeoxys)
{
LoadSpecialPokePic(&gMonBackPicTable[species], dest, species, personality, isFrontPic);
}
else
{
LoadSpecialPokePic_DontHandleDeoxys(&gMonBackPicTable[species], dest, species, personality, isFrontPic);
}
}
}
else
{
if (isFrontPic)
{
DecompressPicFromTable(&gTrainerFrontPicTable[species], dest, species);
}
else
{
DecompressPicFromTable(&gTrainerBackPicTable[species], dest, species);
}
}
return FALSE;
}
static bool16 sub_818D09C(u16 species, u32 personality, bool8 isFrontPic, u8 *dest, bool8 isTrainer)
{
return load_pokemon_image_TODO(species, personality, isFrontPic, dest, isTrainer, FALSE);
}
static void sub_818D0C4(u16 species, u32 otId, u32 personality, u8 paletteSlot, u16 paletteTag, bool8 isTrainer)
{
if (!isTrainer)
{
if (paletteTag == 0xFFFF)
{
gUnknown_0203CCEC.paletteTag |= 0xFFFF;
LoadCompressedPalette(species_and_otid_get_pal(species, otId, personality), 0x100 + paletteSlot * 0x10, 0x20);
}
else
{
gUnknown_0203CCEC.paletteTag = paletteTag;
LoadCompressedObjectPalette(sub_806E7CC(species, otId, personality));
}
}
else
{
if (paletteTag == 0xFFFF)
{
gUnknown_0203CCEC.paletteTag |= 0xFFFF;
LoadCompressedPalette(gTrainerFrontPicPaletteTable[species].data, 0x100 + paletteSlot * 0x10, 0x20);
}
else
{
gUnknown_0203CCEC.paletteTag = paletteTag;
LoadCompressedObjectPalette(&gTrainerFrontPicPaletteTable[species]);
}
}
}
static void sub_818D180(u16 species, u32 otId, u32 personality, u8 paletteSlot, bool8 isTrainer)
{
if (!isTrainer)
{
LoadCompressedPalette(species_and_otid_get_pal(species, otId, personality), paletteSlot * 0x10, 0x20);
}
else
{
LoadCompressedPalette(gTrainerFrontPicPaletteTable[species].data, paletteSlot * 0x10, 0x20);
}
}
static void uns_builder_assign_animtable1(bool8 isTrainer)
{
if (!isTrainer)
{
gUnknown_0203CCEC.anims = gUnknown_082FF70C;
}
else
{
gUnknown_0203CCEC.anims = gUnknown_0830536C[0];
}
}
static u16 oamt_spawn_poke_or_trainer_picture(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer, bool8 ignoreDeoxys)
{
u8 i;
u8 *framePics;
struct SpriteFrameImage *images;
int j;
u8 spriteId;
for (i = 0; i < 8; i ++)
{
if (!gUnknown_0203CD04[i].active)
{
break;
}
}
if (i == 8)
{
return 0xFFFF;
}
framePics = Alloc(4 * 0x800);
if (!framePics)
{
return 0xFFFF;
}
images = Alloc(4 * sizeof(struct SpriteFrameImage));
if (!images)
{
Free(framePics);
return 0xFFFF;
}
if (load_pokemon_image_TODO(species, personality, isFrontPic, framePics, isTrainer, ignoreDeoxys))
{
// debug trap?
return 0xFFFF;
}
for (j = 0; j < 4; j ++)
{
images[j].data = framePics + 0x800 * j;
images[j].size = 0x800;
}
gUnknown_0203CCEC.tileTag = 0xFFFF;
gUnknown_0203CCEC.oam = &gUnknown_0860B064;
uns_builder_assign_animtable1(isTrainer);
gUnknown_0203CCEC.images = images;
gUnknown_0203CCEC.affineAnims = gDummySpriteAffineAnimTable;
gUnknown_0203CCEC.callback = nullsub_122;
sub_818D0C4(species, otId, personality, paletteSlot, paletteTag, isTrainer);
spriteId = CreateSprite(&gUnknown_0203CCEC, x, y, 0);
if (paletteTag == 0xFFFF)
{
gSprites[spriteId].oam.paletteNum = paletteSlot;
}
gUnknown_0203CD04[i].frames = framePics;
gUnknown_0203CD04[i].images = images;
gUnknown_0203CD04[i].paletteTag = paletteTag;
gUnknown_0203CD04[i].spriteId = spriteId;
gUnknown_0203CD04[i].active = TRUE;
return spriteId;
}
static u16 sub_818D384(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer)
{
return oamt_spawn_poke_or_trainer_picture(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, isTrainer, FALSE);
}
u16 sub_818D3E4(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
{
u8 *framePics;
struct SpriteFrameImage *images;
int j;
u8 i;
u8 spriteId;
u8 flags2;
for (i = 0; i < 8; i ++)
{
if (!gUnknown_0203CD04[i].active)
{
break;
}
}
if (i == 8)
{
return 0xFFFF;
}
framePics = Alloc(4 * 0x800);
if (!framePics)
{
return 0xFFFF;
}
if (flags & 0x80)
{
flags &= 0x7F;
flags2 = 3;
}
else
{
flags2 = flags;
}
images = Alloc(4 * sizeof(struct SpriteFrameImage));
if (!images)
{
Free(framePics);
return 0xFFFF;
}
if (load_pokemon_image_TODO(species, personality, flags, framePics, FALSE, FALSE))
{
// debug trap?
return 0xFFFF;
}
for (j = 0; j < 4; j ++)
{
images[j].data = framePics + 0x800 * j;
images[j].size = 0x800;
}
gUnknown_0203CCEC.tileTag = 0xFFFF;
gUnknown_0203CCEC.anims = gUnknown_08309AAC[species];
gUnknown_0203CCEC.images = images;
if (flags2 == 0x01)
{
gUnknown_0203CCEC.affineAnims = gUnknown_082FF694;
gUnknown_0203CCEC.oam = &gUnknown_0860B06C;
}
else if (flags2 == 0x00)
{
gUnknown_0203CCEC.affineAnims = gUnknown_082FF618;
gUnknown_0203CCEC.oam = &gUnknown_0860B06C;
}
else
{
gUnknown_0203CCEC.oam = &gUnknown_0860B064;
gUnknown_0203CCEC.affineAnims = gDummySpriteAffineAnimTable;
}
gUnknown_0203CCEC.callback = nullsub_122;
sub_818D0C4(species, otId, personality, paletteSlot, paletteTag, FALSE);
spriteId = CreateSprite(&gUnknown_0203CCEC, x, y, 0);
if (paletteTag == 0xFFFF)
{
gSprites[spriteId].oam.paletteNum = paletteSlot;
}
gUnknown_0203CD04[i].frames = framePics;
gUnknown_0203CD04[i].images = images;
gUnknown_0203CD04[i].paletteTag = paletteTag;
gUnknown_0203CD04[i].spriteId = spriteId;
gUnknown_0203CD04[i].active = TRUE;
return spriteId;
}
static u16 sub_818D5B0(u16 spriteId)
{
u8 i;
u8 *framePics;
struct SpriteFrameImage *images;
for (i = 0; i < 8; i ++)
{
if (gUnknown_0203CD04[i].spriteId == spriteId)
{
break;
}
}
if (i == 8)
{
return 0xFFFF;
}
framePics = gUnknown_0203CD04[i].frames;
images = gUnknown_0203CD04[i].images;
if (gUnknown_0203CD04[i].paletteTag != 0xFFFF)
{
FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(gSprites[spriteId].oam.paletteNum));
}
DestroySprite(&gSprites[spriteId]);
Free(framePics);
Free(images);
gUnknown_0203CD04[i] = gUnknown_0860B058;
return 0;
}
static u16 sub_818D65C(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId, bool8 isTrainer)
{
if (sub_818D09C(species, personality, isFrontPic, (u8 *)GetWindowAttribute(windowId, WINDOW_TILE_DATA), FALSE))
{
return 0xFFFF;
}
sub_818D180(species, otId, personality, paletteSlot, isTrainer);
return 0;
}
static u16 sub_818D6CC(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId, bool8 isTrainer)
{
u8 *framePics;
framePics = Alloc(4 * 0x800);
if (framePics && !sub_818D09C(species, personality, isFrontPic, framePics, isTrainer))
{
BlitBitmapRectToWindow(windowId, framePics, 0, 0, 0x40, 0x40, destX, destY, 0x40, 0x40);
sub_818D180(species, otId, personality, paletteSlot, isTrainer);
Free(framePics);
return 0;
}
return 0xFFFF;
}
static u16 sub_818D778(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 ignoreDeoxys)
{
return oamt_spawn_poke_or_trainer_picture(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE, ignoreDeoxys);
}
u16 sub_818D7D8(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
{
return sub_818D778(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE);
}
u16 sub_818D820(u16 spriteId)
{
return sub_818D5B0(spriteId);
}
u16 sub_818D834(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId)
{
return sub_818D65C(species, otId, personality, isFrontPic, paletteSlot, windowId, FALSE);
}
u16 sub_818D864(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId)
{
return sub_818D6CC(species, otId, personality, isFrontPic, destX, destY, paletteSlot, windowId, FALSE);
}
u16 sub_818D8AC(u16 species, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
{
return sub_818D384(species, 0, 0, isFrontPic, x, y, paletteSlot, paletteTag, TRUE);
}
u16 sub_818D8F0(u16 spriteId)
{
return sub_818D5B0(spriteId);
}
u16 sub_818D904(u16 species, bool8 isFrontPic, u8 paletteSlot, u8 windowId)
{
return sub_818D65C(species, 0, 0, isFrontPic, paletteSlot, windowId, TRUE);
}
u16 sub_818D938(u16 species, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId)
{
return sub_818D6CC(species, 0, 0, isFrontPic, destX, destY, paletteSlot, windowId, TRUE);
}
u8 sub_818D97C(u8 a0, u8 a1)
{
if (a1 == 1)
{
switch (a0)
{
default:
return gUnknown_0831F578[0x3F];
case 0:
return gUnknown_0831F578[0x3C];
}
}
return a0;
}

11415
src/battle_script_commands.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -17,7 +17,6 @@ extern bool8 sub_8092E9C(u8, u8, u8);
extern u16 gScriptItemId;
extern const u8 BerryTreeScript[];
extern const struct BerryTree gBlankBerryTree;
#define BERRY_NAME_LENGTH 6
@@ -804,10 +803,58 @@ const struct Berry gBerries[] =
},
};
const struct UnkStruct_0858AB24 gUnknown_0858AB24[] = {
{ 50, 20},
{ 50, 20},
{ 50, 20},
{ 50, 20},
{ 50, 20},
{ 50, 30},
{ 50, 30},
{ 50, 30},
{ 50, 30},
{ 50, 30},
{ 60, 50},
{ 60, 50},
{ 60, 50},
{ 60, 50},
{ 60, 50},
{ 80, 70},
{ 80, 70},
{ 80, 70},
{ 80, 70},
{ 80, 70},
{100, 100},
{100, 100},
{100, 100},
{100, 100},
{100, 100},
{130, 150},
{130, 150},
{130, 150},
{130, 150},
{130, 150},
{160, 250},
{160, 250},
{160, 250},
{160, 250},
{160, 250},
{180, 500},
{180, 500},
{180, 500},
{180, 500},
{180, 500},
{200, 750},
{200, 750},
{150, 200}
};
const struct BerryTree gBlankBerryTree = {};
// unused
void ClearEnigmaBerries(void)
{
CpuFill16(0, &gSaveBlock1Ptr->enigmaBerry, sizeof(gSaveBlock1Ptr->enigmaBerry));
CpuFill16(0, &gSaveBlock1Ptr->enigmaBerry, 52);
}
void SetEnigmaBerry(u8 *src)
@@ -815,7 +862,7 @@ void SetEnigmaBerry(u8 *src)
u32 i;
u8 *dest = (u8*)&gSaveBlock1Ptr->enigmaBerry;
for (i = 0; i < sizeof(gSaveBlock1Ptr->enigmaBerry); i++)
for (i = 0; i < 52; i++)
dest[i] = src[i];
}
@@ -827,7 +874,7 @@ u32 GetEnigmaBerryChecksum(struct EnigmaBerry *enigmaBerry)
dest = (u8*)enigmaBerry;
checksum = 0;
for (i = 0; i < sizeof(gSaveBlock1Ptr->enigmaBerry) - sizeof(gSaveBlock1Ptr->enigmaBerry.checksum); i++)
for (i = 0; i < 52 - sizeof(gSaveBlock1Ptr->enigmaBerry.checksum); i++)
{
checksum += dest[i];
}

18
src/berry_blender.c Normal file
View File

@@ -0,0 +1,18 @@
// Includes
#include "global.h"
// Static type declarations
// Static RAM declarations
IWRAM_DATA void *berry_blender_c_unused_03000de4;
IWRAM_DATA s16 gUnknown_03000DE8[8];
IWRAM_DATA s16 gUnknown_03000DF8[6];
IWRAM_DATA s16 gUnknown_03000E04;
IWRAM_DATA s16 gUnknown_03000E06;
// Static ROM declarations
// .rodata
// .text

530
src/berry_fix_program.c Normal file
View File

@@ -0,0 +1,530 @@
// Includes
#include "global.h"
#include "gpu_regs.h"
#include "multiboot.h"
#include "malloc.h"
#include "bg.h"
#include "main.h"
#include "sprite.h"
#include "task.h"
#include "unknown_task.h"
#include "window.h"
#include "menu.h"
#include "m4a.h"
// Static type declarations
typedef struct {
u8 state;
u8 unk1;
u16 unk2;
struct MultiBootParam mb;
} berryfix_t;
// Static RAM declarations
static berryfix_t *berry_fix_mb_manager;
// Static ROM declarations
static void berry_fix_main(void);
static void berry_fix_gpu_set(void);
static int berry_fix_text_update(int);
static void berry_fix_text_print(int);
static void berry_fix_bg_hide(void);
// .rodata
static const u8 gUnknown_08617E78[] = _("Berry Program Update");
static const u8 gUnknown_08617E8D[] = _("Ruby/Sapphire");
static const u8 gUnknown_08617E9B[] = _("Emerald");
static const u8 Unknown_08617EA3[] = _("The Berry Program on your POKéMON\nRuby/Sapphire Game Pak will be updated.\n{COLOR RED}{SHADOW LIGHT_RED}Press the A Button.");
static const u8 Unknown_08617F07[] = _("Please ensure the connection of your\nGame Boy Advance system matches this.\n{COLOR RED}{SHADOW LIGHT_RED}YES: Press the A Button.\nNO: Turn off the power and try again.");
static const u8 Unknown_08617F97[] = _("Please turn on the power of POKéMON\nRuby/Sapphire while holding START and\nSELECT simultaneously. Then, ensure\nthe picture above appears.");
static const u8 Unknown_08618020[] = _("Transmitting. Please wait.\n{COLOR RED}{SHADOW LIGHT_RED}Please do not turn off the power or\nunplug the Game Boy Advance Game\nLink Cable.");
static const u8 Unknown_08618092[] = _("Please follow the instructions on your\nPOKéMON Ruby/Sapphire screen.");
static const u8 Unknown_086180D7[] = _("Transmission failure.\n{COLOR RED}{SHADOW LIGHT_RED}Please try again.");
static const struct BgTemplate gUnknown_08618108[] = {
{
0, 0, 30, 0, 0, 0
}, {
1, 1, 31, 0, 0, 1
}
};
static const struct WindowTemplate gUnknown_08618110[] = {
{0, 2, 4, 26, 2, 15, 0x001},
{0, 1, 11, 28, 8, 15, 0x035},
{0, 0, 8, 30, 2, 15, 0x115},
{0, 8, 0, 14, 2, 15, 0x151},
{-1}
};
static const u16 gUnknown_08618138[] = {
0x7fff, 0x7fff, 0x318c, 0x675a,
0x043c, 0x3aff, 0x0664, 0x4bd2,
0x6546, 0x7b14, 0x7fff, 0x318c,
0x675a, 0x0000, 0x0000, 0x0000
};
static const u8 gUnknown_08618158[] = {10, 11, 12};
static const u8 gUnknown_0861815B[] = { 0, 10, 13};
static const u8 *const gUnknown_08618160[] = {
Unknown_08617F07,
Unknown_08617F97,
Unknown_08618020,
Unknown_08618092,
Unknown_086180D7,
Unknown_08617EA3
};
extern const u8 gUnknown_08DD87C0[];
extern const u8 gUnknown_08DD8EE0[];
extern const u8 gUnknown_08DD8780[];
extern const u8 gUnknown_08DD90E0[];
extern const u8 gUnknown_08DD9718[];
extern const u8 gUnknown_08DD9080[];
extern const u8 gUnknown_08DD98B4[];
extern const u8 gUnknown_08DD9E58[];
extern const u8 gUnknown_08DD9874[];
extern const u8 gUnknown_08DDA02C[];
extern const u8 gUnknown_08DDA63C[];
extern const u8 gUnknown_08DD9FEC[];
extern const u8 gUnknown_08DDA840[];
extern const u8 gUnknown_08DDAE40[];
extern const u8 gUnknown_08DDA800[];
extern const u8 gUnknown_08DDB020[];
extern const u8 gUnknown_08DDB2C4[];
extern const u8 gUnknown_08DDAFE0[];
static const u8 *const gUnknown_08618178[][3] = {
{
gUnknown_08DD87C0,
gUnknown_08DD8EE0,
gUnknown_08DD8780
}, {
gUnknown_08DD90E0,
gUnknown_08DD9718,
gUnknown_08DD9080
}, {
gUnknown_08DD98B4,
gUnknown_08DD9E58,
gUnknown_08DD9874
}, {
gUnknown_08DDA02C,
gUnknown_08DDA63C,
gUnknown_08DD9FEC
}, {
gUnknown_08DDA840,
gUnknown_08DDAE40,
gUnknown_08DDA800
}, {
gUnknown_08DDB020,
gUnknown_08DDB2C4,
gUnknown_08DDAFE0
},
};
extern const u8 gMultiBootProgram_BerryGlitchFix_Start[0x3BF4];
extern const u8 gMultiBootProgram_BerryGlitchFix_End[];
// .text
void InitBerryFixProgram(void)
{
DisableInterrupts(0xFFFF);
EnableInterrupts(0x0001);
m4aSoundVSyncOff();
SetVBlankCallback(NULL);
ResetSpriteData();
ResetTasks();
remove_some_task();
SetGpuReg(REG_OFFSET_DISPCNT, 0x0000);
berry_fix_mb_manager = AllocZeroed(0x50);
berry_fix_mb_manager->state = 0;
berry_fix_mb_manager->unk1 = 6;
SetMainCallback2(berry_fix_main);
}
static void berry_fix_main(void)
{
switch (berry_fix_mb_manager->state)
{
case 0:
berry_fix_gpu_set();
berry_fix_mb_manager->state = 1;
break;
case 1:
if (berry_fix_text_update(5) == 5 && (gMain.newKeys & A_BUTTON))
{
berry_fix_mb_manager->state = 2;
}
break;
case 2:
if (berry_fix_text_update(0) == 0 && (gMain.newKeys & A_BUTTON))
{
berry_fix_mb_manager->state = 3;
}
break;
case 3:
if (berry_fix_text_update(1) == 1)
{
berry_fix_mb_manager->mb.masterp = gMultiBootProgram_BerryGlitchFix_Start;
berry_fix_mb_manager->mb.server_type = 0;
MultiBootInit(&berry_fix_mb_manager->mb);
berry_fix_mb_manager->unk2 = 0;
berry_fix_mb_manager->state = 4;
}
break;
case 4:
MultiBootMain(&berry_fix_mb_manager->mb);
if (berry_fix_mb_manager->mb.probe_count != 0 || (!(berry_fix_mb_manager->mb.response_bit & 2) || !(berry_fix_mb_manager->mb.client_bit & 2)))
{
berry_fix_mb_manager->unk2 = 0;
}
else if (++ berry_fix_mb_manager->unk2 > 180)
{
MultiBootStartMaster(&berry_fix_mb_manager->mb, gMultiBootProgram_BerryGlitchFix_Start + ROM_HEADER_SIZE, (u32)(gMultiBootProgram_BerryGlitchFix_End - (gMultiBootProgram_BerryGlitchFix_Start + ROM_HEADER_SIZE)), 4, 1);
berry_fix_mb_manager->state = 5;
}
break;
case 5:
if (berry_fix_text_update(2) == 2) {
MultiBootMain(&berry_fix_mb_manager->mb);
if (MultiBootCheckComplete(&berry_fix_mb_manager->mb)) {
berry_fix_mb_manager->state = 6;
}
else if (!(berry_fix_mb_manager->mb.client_bit & 2)) {
berry_fix_mb_manager->state = 7;
}
}
break;
case 6:
if (berry_fix_text_update(3) == 3 && gMain.newKeys & A_BUTTON)
{
DoSoftReset();
}
break;
case 7:
if (berry_fix_text_update(4) == 4 && gMain.newKeys & A_BUTTON)
{
berry_fix_mb_manager->state = 1;
}
break;
}
}
#ifdef NONMATCHING
static void berry_fix_gpu_set(void)
{
s32 width;
SetGpuReg(REG_OFFSET_BG0CNT, 0x0000);
SetGpuReg(REG_OFFSET_BG1CNT, 0x0000);
SetGpuReg(REG_OFFSET_BG0HOFS, 0x0000);
SetGpuReg(REG_OFFSET_BG0VOFS, 0x0000);
SetGpuReg(REG_OFFSET_BG1HOFS, 0x0000);
SetGpuReg(REG_OFFSET_BG1VOFS, 0x0000);
SetGpuReg(REG_OFFSET_BLDCNT, 0x0000);
DmaFill32(3, 0, VRAM, VRAM_SIZE);
DmaFill32(3, 0, OAM, OAM_SIZE);
DmaFill32(3, 0, PLTT, PLTT_SIZE);
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, gUnknown_08618108, ARRAY_COUNT(gUnknown_08618108));
ChangeBgX(0, 0, 0);
ChangeBgY(0, 0, 0);
ChangeBgX(1, 0, 0);
ChangeBgY(1, 0, 0);
InitWindows(gUnknown_08618110);
DeactivateAllTextPrinters();
DmaCopy32(3, gUnknown_08618138, BG_PLTT + 0x1E0, 0x20);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP);
FillWindowPixelBuffer(2, 0);
FillWindowPixelBuffer(3, 0);
FillWindowPixelBuffer(0, 0xAA);
// This block is a meme among memes
width = (0x78 - GetStringWidth(0, gUnknown_08617E9B, 0)) / 2;
box_print(2, 0, width, 3, gUnknown_0861815B, -1, gUnknown_08617E9B);
width = (s32)(0x78 - GetStringWidth(0, gUnknown_08617E9B, 0)) / 2 + 0x78;
box_print(2, 0, width, 3, gUnknown_0861815B, -1, gUnknown_08617E8D);
width = (0x70 - GetStringWidth(0, gUnknown_08617E8D, 0)) / 2;
box_print(3, 0, width, 0, gUnknown_0861815B, -1, gUnknown_08617E8D);
width = (0xd0 - GetStringWidth(1, gUnknown_08617E78, 0)) / 2;
box_print(0, 1, width, 2, gUnknown_08618158, -1, gUnknown_08617E78);
CopyWindowToVram(2, 2);
CopyWindowToVram(3, 2);
CopyWindowToVram(0, 2);
}
#else
__attribute__((naked)) static void berry_fix_gpu_set(void)
{
asm(".syntax unified\n"
"\tpush {r4-r6,lr}\n"
"\tmov r6, r8\n"
"\tpush {r6}\n"
"\tsub sp, 0x10\n"
"\tmovs r0, 0x8\n"
"\tmovs r1, 0\n"
"\tbl SetGpuReg\n"
"\tmovs r0, 0xA\n"
"\tmovs r1, 0\n"
"\tbl SetGpuReg\n"
"\tmovs r0, 0x10\n"
"\tmovs r1, 0\n"
"\tbl SetGpuReg\n"
"\tmovs r0, 0x12\n"
"\tmovs r1, 0\n"
"\tbl SetGpuReg\n"
"\tmovs r0, 0x14\n"
"\tmovs r1, 0\n"
"\tbl SetGpuReg\n"
"\tmovs r0, 0x16\n"
"\tmovs r1, 0\n"
"\tbl SetGpuReg\n"
"\tmovs r0, 0x50\n"
"\tmovs r1, 0\n"
"\tbl SetGpuReg\n"
"\tmovs r1, 0\n"
"\tstr r1, [sp, 0xC]\n"
"\tldr r4, =0x040000d4\n"
"\tadd r0, sp, 0xC\n"
"\tstr r0, [r4]\n"
"\tmovs r0, 0xC0\n"
"\tlsls r0, 19\n"
"\tstr r0, [r4, 0x4]\n"
"\tldr r0, =0x85006000\n"
"\tstr r0, [r4, 0x8]\n"
"\tldr r0, [r4, 0x8]\n"
"\tstr r1, [sp, 0xC]\n"
"\tadd r0, sp, 0xC\n"
"\tstr r0, [r4]\n"
"\tmovs r0, 0xE0\n"
"\tlsls r0, 19\n"
"\tstr r0, [r4, 0x4]\n"
"\tldr r2, =0x85000100\n"
"\tstr r2, [r4, 0x8]\n"
"\tldr r0, [r4, 0x8]\n"
"\tstr r1, [sp, 0xC]\n"
"\tadd r0, sp, 0xC\n"
"\tstr r0, [r4]\n"
"\tmovs r0, 0xA0\n"
"\tlsls r0, 19\n"
"\tstr r0, [r4, 0x4]\n"
"\tstr r2, [r4, 0x8]\n"
"\tldr r0, [r4, 0x8]\n"
"\tmovs r0, 0\n"
"\tbl ResetBgsAndClearDma3BusyFlags\n"
"\tldr r1, =gUnknown_08618108\n"
"\tmovs r0, 0\n"
"\tmovs r2, 0x2\n"
"\tbl InitBgsFromTemplates\n"
"\tmovs r0, 0\n"
"\tmovs r1, 0\n"
"\tmovs r2, 0\n"
"\tbl ChangeBgX\n"
"\tmovs r0, 0\n"
"\tmovs r1, 0\n"
"\tmovs r2, 0\n"
"\tbl ChangeBgY\n"
"\tmovs r0, 0x1\n"
"\tmovs r1, 0\n"
"\tmovs r2, 0\n"
"\tbl ChangeBgX\n"
"\tmovs r0, 0x1\n"
"\tmovs r1, 0\n"
"\tmovs r2, 0\n"
"\tbl ChangeBgY\n"
"\tldr r0, =gUnknown_08618110\n"
"\tbl InitWindows\n"
"\tbl DeactivateAllTextPrinters\n"
"\tldr r0, =gUnknown_08618138\n"
"\tstr r0, [r4]\n"
"\tldr r0, =0x050001e0\n"
"\tstr r0, [r4, 0x4]\n"
"\tldr r0, =0x84000008\n"
"\tstr r0, [r4, 0x8]\n"
"\tldr r0, [r4, 0x8]\n"
"\tmovs r0, 0\n"
"\tmovs r1, 0x40\n"
"\tbl SetGpuReg\n"
"\tmovs r0, 0x2\n"
"\tmovs r1, 0\n"
"\tbl FillWindowPixelBuffer\n"
"\tmovs r0, 0x3\n"
"\tmovs r1, 0\n"
"\tbl FillWindowPixelBuffer\n"
"\tmovs r0, 0\n"
"\tmovs r1, 0xAA\n"
"\tbl FillWindowPixelBuffer\n"
"\tldr r5, =gUnknown_08617E9B\n"
"\tmovs r0, 0\n"
"\tadds r1, r5, 0\n"
"\tmovs r2, 0\n"
"\tbl GetStringWidth\n"
"\tadds r1, r0, 0\n"
"\tmovs r4, 0x78\n"
"\tsubs r0, r4, r1\n"
"\tlsrs r1, r0, 31\n"
"\tadds r0, r1\n"
"\tasrs r0, 1\n"
"\tlsls r2, r0, 24\n"
"\tlsrs r2, 24\n"
"\tldr r6, =gUnknown_0861815B\n"
"\tstr r6, [sp]\n"
"\tmovs r0, 0x1\n"
"\tnegs r0, r0\n"
"\tmov r8, r0\n"
"\tstr r0, [sp, 0x4]\n"
"\tstr r5, [sp, 0x8]\n"
"\tmovs r0, 0x2\n"
"\tmovs r1, 0\n"
"\tmovs r3, 0x3\n"
"\tbl box_print\n"
"\tldr r5, =gUnknown_08617E8D\n"
"\tmovs r0, 0\n"
"\tadds r1, r5, 0\n"
"\tmovs r2, 0\n"
"\tbl GetStringWidth\n"
"\tadds r1, r0, 0\n"
"\tsubs r4, r1\n"
"\tlsrs r0, r4, 31\n"
"\tadds r4, r0\n"
"\tasrs r4, 1\n"
"\tadds r0, r4, 0\n"
"\tadds r0, 0x78\n"
"\tlsls r2, r0, 24\n"
"\tlsrs r2, 24\n"
"\tstr r6, [sp]\n"
"\tmov r0, r8\n"
"\tstr r0, [sp, 0x4]\n"
"\tstr r5, [sp, 0x8]\n"
"\tmovs r0, 0x2\n"
"\tmovs r1, 0\n"
"\tmovs r3, 0x3\n"
"\tbl box_print\n"
"\tmovs r0, 0\n"
"\tadds r1, r5, 0\n"
"\tmovs r2, 0\n"
"\tbl GetStringWidth\n"
"\tadds r1, r0, 0\n"
"\tmovs r0, 0x70\n"
"\tsubs r0, r1\n"
"\tlsrs r1, r0, 31\n"
"\tadds r0, r1\n"
"\tasrs r0, 1\n"
"\tlsls r2, r0, 24\n"
"\tlsrs r2, 24\n"
"\tstr r6, [sp]\n"
"\tmov r0, r8\n"
"\tstr r0, [sp, 0x4]\n"
"\tstr r5, [sp, 0x8]\n"
"\tmovs r0, 0x3\n"
"\tmovs r1, 0\n"
"\tmovs r3, 0\n"
"\tbl box_print\n"
"\tldr r4, =gUnknown_08617E78\n"
"\tmovs r0, 0x1\n"
"\tadds r1, r4, 0\n"
"\tmovs r2, 0\n"
"\tbl GetStringWidth\n"
"\tadds r1, r0, 0\n"
"\tmovs r0, 0xD0\n"
"\tsubs r0, r1\n"
"\tlsrs r1, r0, 31\n"
"\tadds r0, r1\n"
"\tasrs r0, 1\n"
"\tlsls r2, r0, 24\n"
"\tlsrs r2, 24\n"
"\tldr r0, =gUnknown_08618158\n"
"\tstr r0, [sp]\n"
"\tmov r0, r8\n"
"\tstr r0, [sp, 0x4]\n"
"\tstr r4, [sp, 0x8]\n"
"\tmovs r0, 0\n"
"\tmovs r1, 0x1\n"
"\tmovs r3, 0x2\n"
"\tbl box_print\n"
"\tmovs r0, 0x2\n"
"\tmovs r1, 0x2\n"
"\tbl CopyWindowToVram\n"
"\tmovs r0, 0x3\n"
"\tmovs r1, 0x2\n"
"\tbl CopyWindowToVram\n"
"\tmovs r0, 0\n"
"\tmovs r1, 0x2\n"
"\tbl CopyWindowToVram\n"
"\tadd sp, 0x10\n"
"\tpop {r3}\n"
"\tmov r8, r3\n"
"\tpop {r4-r6}\n"
"\tpop {r0}\n"
"\tbx r0\n"
"\t.pool\n"
".syntax divided");
}
#endif
static int berry_fix_text_update(int checkval)
{
if (berry_fix_mb_manager->unk1 == checkval)
{
return checkval;
}
if (berry_fix_mb_manager->unk1 == 6)
{
berry_fix_text_print(checkval);
berry_fix_mb_manager->unk1 = checkval;
}
else
{
berry_fix_bg_hide();
berry_fix_mb_manager->unk1 = 6;
}
return berry_fix_mb_manager->unk1;
}
static void berry_fix_text_print(int scene)
{
FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32);
FillWindowPixelBuffer(1, 0xAA);
box_print(1, 1, 0, 0, gUnknown_08618158, -1, gUnknown_08618160[scene]);
PutWindowTilemap(1);
CopyWindowToVram(1, 2);
switch (scene)
{
case 0:
case 2:
case 3:
case 4:
PutWindowTilemap(2);
break;
case 1:
PutWindowTilemap(3);
break;
case 5:
PutWindowTilemap(0);
break;
}
CopyBgTilemapBufferToVram(0);
LZ77UnCompVram(gUnknown_08618178[scene][0], (void *)BG_CHAR_ADDR(1));
LZ77UnCompVram(gUnknown_08618178[scene][1], (void *)BG_SCREEN_ADDR(31));
CpuCopy32(gUnknown_08618178[scene][2], (void *)BG_PLTT, 0x100);
ShowBg(0);
ShowBg(1);
}
static void berry_fix_bg_hide()
{
HideBg(0);
HideBg(1);
}

501
src/bg.c

File diff suppressed because it is too large Load Diff

View File

@@ -19,7 +19,6 @@ extern struct BattleEnigmaBerry gEnigmaBerries[];
extern u16 gBattleMovePower;
extern u16 gTrainerBattleOpponent_A;
u8 CountAliveMonsInBattle(u8);
bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 bank);
extern const struct BattleMove gBattleMoves[];

View File

@@ -4,14 +4,13 @@
#include "window.h"
#include "text_window.h"
#include "string_util.h"
#include "menu.h"
#define MAX_COINS 9999
EWRAM_DATA u8 sCoinsWindowId = 0;
extern s32 GetStringRightAlignXOffset(u8 fontId, u8 *str, s32 totalWidth);
extern void SetWindowTemplateFields(struct WindowTemplate* template, u8 priority, u8 tilemapLeft, u8 tilemapTop, u8 width, u8 height, u8 palNum, u16 baseBlock);
extern void SetWindowBorderStyle(u8 windowId, bool8 copyToVram, s16 tileStart, s8 palette);
extern void sub_819746C(u8 windowId, bool8 copyToVram);
extern const u8 gText_Coins[];

View File

@@ -1,12 +1,23 @@
#include "global.h"
#include "dma3.h"
IWRAM_DATA struct {
/* 0x00 */ const u8 *src;
/* 0x04 */ u8 *dest;
/* 0x08 */ u16 size;
/* 0x0A */ u16 mode;
/* 0x0C */ u32 value;
} gDma3Requests[128];
static bool8 gDma3ManagerLocked;
static u8 gDma3RequestCursor;
void ClearDma3Requests(void)
{
int i;
gDma3ManagerLocked = TRUE;
gDma3RequestCursor = FALSE;
gDma3RequestCursor = 0;
for(i = 0; i < (u8)ARRAY_COUNT(gDma3Requests); i++)
{
@@ -14,7 +25,7 @@ void ClearDma3Requests(void)
gDma3Requests[i].src = 0;
gDma3Requests[i].dest = 0;
}
gDma3ManagerLocked = FALSE;
}
@@ -22,9 +33,8 @@ void ClearDma3Requests(void)
void ProcessDma3Requests(void)
{
// NOTE: the fillerA member of the DMA struct is actually u32 value;
// NOTE: gUnknown_0300001C is just a pointer inside the gDma3Requests structure, not a true symbol; feel free to remove
u16 total_size;
if (gDma3ManagerLocked)
return;
@@ -34,7 +44,7 @@ void ProcessDma3Requests(void)
while (gDma3Requests[gDma3RequestCursor].size)
{
total_size += gDma3Requests[gDma3RequestCursor].size;
if (total_size > 0xA000)
return; // don't do too much at once
@@ -90,14 +100,14 @@ void ProcessDma3Requests(void)
}
DmaFill16(3, gDma3Requests[gDma3RequestCursor].value, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size);
break;
}
gDma3Requests[gDma3RequestCursor].src = 0;
gDma3Requests[gDma3RequestCursor].dest = 0;
}
gDma3Requests[gDma3RequestCursor].src = NULL;
gDma3Requests[gDma3RequestCursor].dest = NULL;
gDma3Requests[gDma3RequestCursor].size = 0;
gDma3Requests[gDma3RequestCursor].mode = 0;
gDma3Requests[gDma3RequestCursor].value = 0;
gDma3RequestCursor++;
if (gDma3RequestCursor >= 128) // loop back to the first DMA request
gDma3RequestCursor = 0;
}
@@ -331,7 +341,7 @@ _08000DB2:\n\
mov r5, r12\n\
ldrb r0, [r5]\n\
lsls r0, 4\n\
ldr r3, =gUnknown_0300001C\n\
ldr r3, =gDma3Requests + 0x0C\n\
adds r0, r3\n\
ldr r0, [r0]\n\
strh r0, [r1]\n\
@@ -347,7 +357,7 @@ _08000DB2:\n\
bhi _08000DB2\n\
ldrb r0, [r5]\n\
lsls r0, 4\n\
ldr r5, =gUnknown_0300001C\n\
ldr r5, =gDma3Requests + 0x0C\n\
adds r0, r5\n\
ldr r0, [r0]\n\
strh r0, [r1]\n\
@@ -419,13 +429,13 @@ _08000E46:\n\
}
#endif
int RequestDma3Copy(void *src, void *dest, u16 size, u8 mode)
int RequestDma3Copy(const void *src, void *dest, u16 size, u8 mode)
{
int cursor;
int var = 0;
gDma3ManagerLocked = 1;
cursor = gDma3RequestCursor;
while(1)
{
@@ -434,12 +444,12 @@ int RequestDma3Copy(void *src, void *dest, u16 size, u8 mode)
gDma3Requests[cursor].src = src;
gDma3Requests[cursor].dest = dest;
gDma3Requests[cursor].size = size;
if(mode == 1)
gDma3Requests[cursor].mode = mode;
else
gDma3Requests[cursor].mode = 3;
gDma3ManagerLocked = FALSE;
return (s16)cursor;
}
@@ -460,10 +470,10 @@ int RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode)
{
int cursor;
int var = 0;
cursor = gDma3RequestCursor;
gDma3ManagerLocked = 1;
while(1)
{
if(!gDma3Requests[cursor].size)
@@ -477,7 +487,7 @@ int RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode)
gDma3Requests[cursor].mode = 2;
else
gDma3Requests[cursor].mode = 4;
gDma3ManagerLocked = FALSE;
return (s16)cursor;
}
@@ -503,9 +513,9 @@ int CheckForSpaceForDma3Request(s16 index)
for (; current < 0x80; current ++)
if (gDma3Requests[current].size)
return -1;
return 0;
}
}
if (gDma3Requests[index].size)
return -1;

893
src/egg_hatch.c Normal file
View File

@@ -0,0 +1,893 @@
#include "global.h"
#include "pokemon.h"
#include "pokedex.h"
#include "items.h"
#include "script.h"
#include "decompress.h"
#include "task.h"
#include "palette.h"
#include "main.h"
#include "event_data.h"
#include "sound.h"
#include "songs.h"
#include "text.h"
#include "text_window.h"
#include "string_util.h"
#include "menu.h"
#include "trig.h"
#include "rng.h"
#include "malloc.h"
#include "dma3.h"
#include "gpu_regs.h"
#include "bg.h"
#include "m4a.h"
#include "window.h"
#include "abilities.h"
#include "battle.h" // to get rid of later
struct EggHatchData
{
u8 eggSpriteID;
u8 pokeSpriteID;
u8 CB2_state;
u8 CB2_PalCounter;
u8 eggPartyID;
u8 unused_5;
u8 unused_6;
u8 eggShardVelocityID;
u8 windowId;
u8 unused_9;
u8 unused_A;
u16 species;
struct TextColor textColor;
};
extern struct SpriteTemplate gUnknown_0202499C;
extern void (*gFieldCallback)(void);
extern const struct CompressedSpriteSheet gMonFrontPicTable[];
extern const u8 gUnknown_08C00000[];
extern const u8 gUnknown_08C00524[];
extern const u8 gUnknown_08C004E0[];
extern const u16 gUnknown_08DD7300[]; // palette, gameboy advance
extern const u32 gUnknown_08DD7360[]; // tileset gameboy advance
extern const u32 gUnknown_08331F60[]; // tilemap gameboy circle
extern const u8 gText_HatchedFromEgg[];
extern const u8 gText_NickHatchPrompt[];
extern u8* GetMonNick(struct Pokemon* mon, u8* dst);
extern u8* GetBoxMonNick(struct BoxPokemon* boxMon, u8* dst);
extern u8 sav1_map_get_name(void);
extern s8 sub_8198C58(void);
extern void sub_81DB5E8(u8* str1, u8* str2, u8);
extern void sub_806A068(u16, u8);
extern void fade_screen(u8, u8);
extern void overworld_free_bg_tilemaps(void);
extern void sub_80AF168(void);
extern void init_uns_table_pokemon_copy(void);
extern void sub_805F094(void);
extern void remove_some_task(void);
extern void reset_temp_tile_data_buffers(void);
extern void c2_exit_to_overworld_2_switch(void);
extern void play_some_sound(void);
extern void copy_decompressed_tile_data_to_vram_autofree(u8 bg_id, const void* src, u16 size, u16 offset, u8 mode);
extern void CreateYesNoMenu(const struct WindowTemplate*, u16, u8, u8);
extern void DoNamingScreen(u8, const u8*, u16, u8, u32, MainCallback);
extern void AddTextPrinterParametrized2(u8 windowId, u8 fontId, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, struct TextColor* colors, s8 speed, u8 *str);
extern u16 sub_80D22D0(void);
extern u8 sub_80C7050(u8);
static void Task_EggHatch(u8 taskID);
static void CB2_EggHatch_0(void);
static void CB2_EggHatch_1(void);
static void SpriteCB_Egg_0(struct Sprite* sprite);
static void SpriteCB_Egg_1(struct Sprite* sprite);
static void SpriteCB_Egg_2(struct Sprite* sprite);
static void SpriteCB_Egg_3(struct Sprite* sprite);
static void SpriteCB_Egg_4(struct Sprite* sprite);
static void SpriteCB_Egg_5(struct Sprite* sprite);
static void SpriteCB_EggShard(struct Sprite* sprite);
static void EggHatchPrintMessage(u8 windowId, u8* string, u8 x, u8 y, u8 speed);
static void CreateRandomEggShardSprite(void);
static void CreateEggShardSprite(u8 x, u8 y, s16 data1, s16 data2, s16 data3, u8 spriteAnimIndex);
// IWRAM bss
static IWRAM_DATA struct EggHatchData* sEggHatchData;
// rom data
static const u16 sEggPalette[] = INCBIN_U16("graphics/pokemon/palettes/egg_palette.gbapal");
static const u8 sEggHatchTiles[] = INCBIN_U8("graphics/misc/egg_hatch.4bpp");
static const u8 sEggShardTiles[] = INCBIN_U8("graphics/misc/egg_shard.4bpp");
static const struct OamData sOamData_EggHatch =
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = 0,
.x = 0,
.matrixNum = 0,
.size = 2,
.tileNum = 0,
.priority = 1,
.paletteNum = 0,
.affineParam = 0,
};
static const union AnimCmd sSpriteAnim_EggHatch0[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_EggHatch1[] =
{
ANIMCMD_FRAME(16, 5),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_EggHatch2[] =
{
ANIMCMD_FRAME(32, 5),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_EggHatch3[] =
{
ANIMCMD_FRAME(48, 5),
ANIMCMD_END
};
static const union AnimCmd *const sSpriteAnimTable_EggHatch[] =
{
sSpriteAnim_EggHatch0,
sSpriteAnim_EggHatch1,
sSpriteAnim_EggHatch2,
sSpriteAnim_EggHatch3,
};
static const struct SpriteSheet sEggHatch_Sheet =
{
.data = sEggHatchTiles,
.size = 2048,
.tag = 12345,
};
static const struct SpriteSheet sEggShards_Sheet =
{
.data = sEggShardTiles,
.size = 128,
.tag = 23456,
};
static const struct SpritePalette sEgg_SpritePalette =
{
.data = sEggPalette,
.tag = 54321
};
static const struct SpriteTemplate sSpriteTemplate_EggHatch =
{
.tileTag = 12345,
.paletteTag = 54321,
.oam = &sOamData_EggHatch,
.anims = sSpriteAnimTable_EggHatch,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy
};
static const struct OamData sOamData_EggShard =
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = 0,
.x = 0,
.matrixNum = 0,
.size = 0,
.tileNum = 0,
.priority = 2,
.paletteNum = 0,
.affineParam = 0,
};
static const union AnimCmd sSpriteAnim_EggShard0[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_EggShard1[] =
{
ANIMCMD_FRAME(1, 5),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_EggShard2[] =
{
ANIMCMD_FRAME(2, 5),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_EggShard3[] =
{
ANIMCMD_FRAME(3, 5),
ANIMCMD_END
};
static const union AnimCmd *const sSpriteAnimTable_EggShard[] =
{
sSpriteAnim_EggShard0,
sSpriteAnim_EggShard1,
sSpriteAnim_EggShard2,
sSpriteAnim_EggShard3,
};
static const struct SpriteTemplate sSpriteTemplate_EggShard =
{
.tileTag = 23456,
.paletteTag = 54321,
.oam = &sOamData_EggShard,
.anims = sSpriteAnimTable_EggShard,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_EggShard
};
static const struct BgTemplate sBgTemplates_EggHatch[2] =
{
{
.bg = 0,
.charBaseIndex = 2,
.mapBaseIndex = 24,
.screenSize = 3,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
},
{
.bg = 1,
.charBaseIndex = 0,
.mapBaseIndex = 8,
.screenSize = 1,
.paletteMode = 0,
.priority = 2,
.baseTile = 0
},
};
static const struct WindowTemplate sWinTemplates_EggHatch[2] =
{
{0, 2, 0xF, 0x1A, 4, 0, 0x40},
DUMMY_WIN_TEMPLATE
};
static const struct WindowTemplate sYesNoWinTemplate =
{
0, 0x15, 9, 5, 4, 0xF, 0x1A8
};
static const s16 sEggShardVelocities[][2] =
{
{Q_8_8(-1.5), Q_8_8(-3.75)},
{Q_8_8(-5), Q_8_8(-3)},
{Q_8_8(3.5), Q_8_8(-3)},
{Q_8_8(-4), Q_8_8(-3.75)},
{Q_8_8(2), Q_8_8(-1.5)},
{Q_8_8(-0.5), Q_8_8(-6.75)},
{Q_8_8(5), Q_8_8(-2.25)},
{Q_8_8(-1.5), Q_8_8(-3.75)},
{Q_8_8(4.5), Q_8_8(-1.5)},
{Q_8_8(-1), Q_8_8(-6.75)},
{Q_8_8(4), Q_8_8(-2.25)},
{Q_8_8(-3.5), Q_8_8(-3.75)},
{Q_8_8(1), Q_8_8(-1.5)},
{Q_8_8(-3.515625), Q_8_8(-6.75)},
{Q_8_8(4.5), Q_8_8(-2.25)},
{Q_8_8(-0.5), Q_8_8(-7.5)},
{Q_8_8(1), Q_8_8(-4.5)},
{Q_8_8(-2.5), Q_8_8(-2.25)},
{Q_8_8(2.5), Q_8_8(-7.5)},
};
// code
static void CreatedHatchedMon(struct Pokemon *egg, struct Pokemon *temp)
{
u16 species;
u32 personality, pokerus;
u8 i, friendship, language, gameMet, markings, obedience;
u16 moves[4];
u32 ivs[6];
species = GetMonData(egg, MON_DATA_SPECIES);
for (i = 0; i < 4; i++)
{
moves[i] = GetMonData(egg, MON_DATA_MOVE1 + i);
}
personality = GetMonData(egg, MON_DATA_PERSONALITY);
for (i = 0; i < 6; i++)
{
ivs[i] = GetMonData(egg, MON_DATA_HP_IV + i);
}
language = GetMonData(egg, MON_DATA_LANGUAGE);
gameMet = GetMonData(egg, MON_DATA_MET_GAME);
markings = GetMonData(egg, MON_DATA_MARKINGS);
pokerus = GetMonData(egg, MON_DATA_POKERUS);
obedience = GetMonData(egg, MON_DATA_OBEDIENCE);
CreateMon(temp, species, 5, 32, TRUE, personality, 0, 0);
for (i = 0; i < 4; i++)
{
SetMonData(temp, MON_DATA_MOVE1 + i, &moves[i]);
}
for (i = 0; i < 6; i++)
{
SetMonData(temp, MON_DATA_HP_IV + i, &ivs[i]);
}
language = GAME_LANGUAGE;
SetMonData(temp, MON_DATA_LANGUAGE, &language);
SetMonData(temp, MON_DATA_MET_GAME, &gameMet);
SetMonData(temp, MON_DATA_MARKINGS, &markings);
friendship = 120;
SetMonData(temp, MON_DATA_FRIENDSHIP, &friendship);
SetMonData(temp, MON_DATA_POKERUS, &pokerus);
SetMonData(temp, MON_DATA_OBEDIENCE, &obedience);
*egg = *temp;
}
static void AddHatchedMonToParty(u8 id)
{
u8 isEgg = 0x46; // ?
u16 pokeNum;
u8 name[12];
u16 ball;
u16 caughtLvl;
u8 mapNameID;
struct Pokemon* mon = &gPlayerParty[id];
CreatedHatchedMon(mon, &gEnemyParty[0]);
SetMonData(mon, MON_DATA_IS_EGG, &isEgg);
pokeNum = GetMonData(mon, MON_DATA_SPECIES);
GetSpeciesName(name, pokeNum);
SetMonData(mon, MON_DATA_NICKNAME, name);
pokeNum = SpeciesToNationalPokedexNum(pokeNum);
GetSetPokedexFlag(pokeNum, FLAG_SET_SEEN);
GetSetPokedexFlag(pokeNum, FLAG_SET_CAUGHT);
GetMonNick(mon, gStringVar1);
ball = ITEM_POKE_BALL;
SetMonData(mon, MON_DATA_POKEBALL, &ball);
caughtLvl = 0;
SetMonData(mon, MON_DATA_MET_LEVEL, &caughtLvl);
mapNameID = sav1_map_get_name();
SetMonData(mon, MON_DATA_MET_LOCATION, &mapNameID);
MonRestorePP(mon);
CalculateMonStats(mon);
}
void ScriptHatchMon(void)
{
AddHatchedMonToParty(gSpecialVar_0x8004);
}
static bool8 sub_807158C(struct DaycareData* daycare, u8 daycareId)
{
u8 nick[0x20];
struct DaycareMon* daycareMon = &daycare->mons[daycareId];
GetBoxMonNick(&daycareMon->mon, nick);
if (daycareMon->mail.itemId != 0
&& (StringCompareWithoutExtCtrlCodes(nick, daycareMon->monName) != 0
|| StringCompareWithoutExtCtrlCodes(gSaveBlock2Ptr->playerName, daycareMon->OT_name) != 0))
{
StringCopy(gStringVar1, nick);
sub_81DB5E8(gStringVar2, daycareMon->OT_name, daycareMon->language_maybe);
sub_81DB5E8(gStringVar3, daycareMon->monName, daycareMon->unknown);
return TRUE;
}
return FALSE;
}
bool8 sub_8071614(void)
{
return sub_807158C(&gSaveBlock1Ptr->daycare, gSpecialVar_0x8004);
}
static u8 EggHatchCreateMonSprite(u8 a0, u8 switchID, u8 pokeID, u16* speciesLoc)
{
u8 r5 = 0;
u8 spriteID = 0;
struct Pokemon* mon = NULL;
if (a0 == 0)
{
mon = &gPlayerParty[pokeID];
r5 = 1;
}
if (a0 == 1)
{
mon = &gPlayerParty[pokeID];
r5 = 3;
}
switch (switchID)
{
case 0:
{
u16 species = GetMonData(mon, MON_DATA_SPECIES);
u32 pid = GetMonData(mon, MON_DATA_PERSONALITY);
HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species],
gBattleSpritesGfx->sprites[(a0 * 2) + 1],
species, pid);
LoadCompressedObjectPalette(sub_806E794(mon));
*speciesLoc = species;
}
break;
case 1:
sub_806A068(sub_806E794(mon)->tag, r5);
spriteID = CreateSprite(&gUnknown_0202499C, 120, 75, 6);
gSprites[spriteID].invisible = 1;
gSprites[spriteID].callback = SpriteCallbackDummy;
break;
}
return spriteID;
}
static void VBlankCB_EggHatch(void)
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
static void EggHatch(void)
{
ScriptContext2_Enable();
CreateTask(Task_EggHatch, 10);
fade_screen(1, 0);
}
static void Task_EggHatch(u8 taskID)
{
if (!gPaletteFade.active)
{
overworld_free_bg_tilemaps();
SetMainCallback2(CB2_EggHatch_0);
gFieldCallback = sub_80AF168;
DestroyTask(taskID);
}
}
static void CB2_EggHatch_0(void)
{
switch (gMain.state)
{
case 0:
SetGpuReg(REG_OFFSET_DISPCNT, 0);
sEggHatchData = Alloc(sizeof(struct EggHatchData));
init_uns_table_pokemon_copy();
sEggHatchData->eggPartyID = gSpecialVar_0x8004;
sEggHatchData->eggShardVelocityID = 0;
SetVBlankCallback(VBlankCB_EggHatch);
gSpecialVar_0x8005 = GetCurrentMapMusic();
reset_temp_tile_data_buffers();
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sBgTemplates_EggHatch, ARRAY_COUNT(sBgTemplates_EggHatch));
ChangeBgX(1, 0, 0);
ChangeBgY(1, 0, 0);
ChangeBgX(0, 0, 0);
ChangeBgY(0, 0, 0);
SetBgAttribute(1, BG_CTRL_ATTR_MOSAIC, 2);
SetBgTilemapBuffer(1, Alloc(0x1000));
SetBgTilemapBuffer(0, Alloc(0x2000));
DeactivateAllTextPrinters();
ResetPaletteFade();
FreeAllSpritePalettes();
ResetSpriteData();
ResetTasks();
remove_some_task();
m4aSoundVSyncOn();
gMain.state++;
break;
case 1:
InitWindows(sWinTemplates_EggHatch);
sEggHatchData->windowId = 0;
gMain.state++;
break;
case 2:
copy_decompressed_tile_data_to_vram_autofree(0, gUnknown_08C00000, 0, 0, 0);
CopyToBgTilemapBuffer(0, gUnknown_08C00524, 0, 0);
LoadCompressedPalette(gUnknown_08C004E0, 0, 0x20);
gMain.state++;
break;
case 3:
LoadSpriteSheet(&sEggHatch_Sheet);
LoadSpriteSheet(&sEggShards_Sheet);
LoadSpritePalette(&sEgg_SpritePalette);
gMain.state++;
break;
case 4:
CopyBgTilemapBufferToVram(0);
AddHatchedMonToParty(sEggHatchData->eggPartyID);
gMain.state++;
break;
case 5:
EggHatchCreateMonSprite(0, 0, sEggHatchData->eggPartyID, &sEggHatchData->species);
gMain.state++;
break;
case 6:
sEggHatchData->pokeSpriteID = EggHatchCreateMonSprite(0, 1, sEggHatchData->eggPartyID, &sEggHatchData->species);
gMain.state++;
break;
case 7:
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
LoadPalette(gUnknown_08DD7300, 0x10, 0xA0);
LoadBgTiles(1, gUnknown_08DD7360, 0x1420, 0);
CopyToBgTilemapBuffer(1, gUnknown_08331F60, 0x1000, 0);
CopyBgTilemapBufferToVram(1);
gMain.state++;
break;
case 8:
SetMainCallback2(CB2_EggHatch_1);
sEggHatchData->CB2_state = 0;
break;
}
RunTasks();
RunTextPrinters();
AnimateSprites();
BuildOamBuffer();
UpdatePaletteFade();
}
static void EggHatchSetMonNickname(void)
{
SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar3);
sub_805F094();
Free(sEggHatchData);
SetMainCallback2(c2_exit_to_overworld_2_switch);
}
static void Task_EggHatchPlayBGM(u8 taskID)
{
if (gTasks[taskID].data[0] == 0)
{
StopMapMusic();
play_some_sound();
}
if (gTasks[taskID].data[0] == 1)
PlayBGM(376);
if (gTasks[taskID].data[0] > 60)
{
PlayBGM(377);
DestroyTask(taskID);
// UB: task is destroyed, yet the value is incremented
}
gTasks[taskID].data[0]++;
}
static void CB2_EggHatch_1(void)
{
u16 species;
u8 gender;
u32 personality;
switch (sEggHatchData->CB2_state)
{
case 0:
BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
sEggHatchData->eggSpriteID = CreateSprite(&sSpriteTemplate_EggHatch, 120, 75, 5);
ShowBg(0);
ShowBg(1);
sEggHatchData->CB2_state++;
CreateTask(Task_EggHatchPlayBGM, 5);
break;
case 1:
if (!gPaletteFade.active)
{
FillWindowPixelBuffer(sEggHatchData->windowId, 0);
sEggHatchData->CB2_PalCounter = 0;
sEggHatchData->CB2_state++;
}
break;
case 2:
if (++sEggHatchData->CB2_PalCounter > 30)
{
sEggHatchData->CB2_state++;
gSprites[sEggHatchData->eggSpriteID].callback = SpriteCB_Egg_0;
}
break;
case 3:
if (gSprites[sEggHatchData->eggSpriteID].callback == SpriteCallbackDummy)
{
species = GetMonData(&gPlayerParty[sEggHatchData->eggPartyID], MON_DATA_SPECIES);
DoMonFrontSpriteAnimation(&gSprites[sEggHatchData->pokeSpriteID], species, FALSE, 1);
sEggHatchData->CB2_state++;
}
break;
case 4:
if (gSprites[sEggHatchData->pokeSpriteID].callback == SpriteCallbackDummy)
{
sEggHatchData->CB2_state++;
}
break;
case 5:
GetMonNick(&gPlayerParty[sEggHatchData->eggPartyID], gStringVar1);
StringExpandPlaceholders(gStringVar4, gText_HatchedFromEgg);
EggHatchPrintMessage(sEggHatchData->windowId, gStringVar4, 0, 3, 0xFF);
PlayFanfare(371);
sEggHatchData->CB2_state++;
PutWindowTilemap(sEggHatchData->windowId);
CopyWindowToVram(sEggHatchData->windowId, 3);
break;
case 6:
if (IsFanfareTaskInactive())
sEggHatchData->CB2_state++;
break;
case 7:
if (IsFanfareTaskInactive())
sEggHatchData->CB2_state++;
break;
case 8:
GetMonNick(&gPlayerParty[sEggHatchData->eggPartyID], gStringVar1);
StringExpandPlaceholders(gStringVar4, gText_NickHatchPrompt);
EggHatchPrintMessage(sEggHatchData->windowId, gStringVar4, 0, 2, 1);
sEggHatchData->CB2_state++;
break;
case 9:
if (!IsTextPrinterActive(sEggHatchData->windowId))
{
sub_809882C(sEggHatchData->windowId, 0x140, 0xE0);
CreateYesNoMenu(&sYesNoWinTemplate, 0x140, 0xE, 0);
sEggHatchData->CB2_state++;
}
break;
case 10:
switch (sub_8198C58())
{
case 0:
GetMonNick(&gPlayerParty[sEggHatchData->eggPartyID], gStringVar3);
species = GetMonData(&gPlayerParty[sEggHatchData->eggPartyID], MON_DATA_SPECIES);
gender = GetMonGender(&gPlayerParty[sEggHatchData->eggPartyID]);
personality = GetMonData(&gPlayerParty[sEggHatchData->eggPartyID], MON_DATA_PERSONALITY, 0);
DoNamingScreen(3, gStringVar3, species, gender, personality, EggHatchSetMonNickname);
break;
case 1:
case -1:
sEggHatchData->CB2_state++;
}
break;
case 11:
BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
sEggHatchData->CB2_state++;
break;
case 12:
if (!gPaletteFade.active)
{
sub_805F094();
RemoveWindow(sEggHatchData->windowId);
UnsetBgTilemapBuffer(0);
UnsetBgTilemapBuffer(1);
Free(sEggHatchData);
SetMainCallback2(c2_exit_to_overworld_2_switch);
}
break;
}
RunTasks();
RunTextPrinters();
AnimateSprites();
BuildOamBuffer();
UpdatePaletteFade();
}
static void SpriteCB_Egg_0(struct Sprite* sprite)
{
if (++sprite->data0 > 20)
{
sprite->callback = SpriteCB_Egg_1;
sprite->data0 = 0;
}
else
{
sprite->data1 = (sprite->data1 + 20) & 0xFF;
sprite->pos2.x = Sin(sprite->data1, 1);
if (sprite->data0 == 15)
{
PlaySE(SE_BOWA);
StartSpriteAnim(sprite, 1);
CreateRandomEggShardSprite();
}
}
}
static void SpriteCB_Egg_1(struct Sprite* sprite)
{
if (++sprite->data2 > 30)
{
if (++sprite->data0 > 20)
{
sprite->callback = SpriteCB_Egg_2;
sprite->data0 = 0;
sprite->data2 = 0;
}
else
{
sprite->data1 = (sprite->data1 + 20) & 0xFF;
sprite->pos2.x = Sin(sprite->data1, 2);
if (sprite->data0 == 15)
{
PlaySE(SE_BOWA);
StartSpriteAnim(sprite, 2);
}
}
}
}
static void SpriteCB_Egg_2(struct Sprite* sprite)
{
if (++sprite->data2 > 30)
{
if (++sprite->data0 > 38)
{
u16 species;
sprite->callback = SpriteCB_Egg_3;
sprite->data0 = 0;
species = GetMonData(&gPlayerParty[sEggHatchData->eggPartyID], MON_DATA_SPECIES);
gSprites[sEggHatchData->pokeSpriteID].pos2.x = 0;
gSprites[sEggHatchData->pokeSpriteID].pos2.y = 0;
}
else
{
sprite->data1 = (sprite->data1 + 20) & 0xFF;
sprite->pos2.x = Sin(sprite->data1, 2);
if (sprite->data0 == 15)
{
PlaySE(SE_BOWA);
StartSpriteAnim(sprite, 2);
CreateRandomEggShardSprite();
CreateRandomEggShardSprite();
}
if (sprite->data0 == 30)
PlaySE(SE_BOWA);
}
}
}
static void SpriteCB_Egg_3(struct Sprite* sprite)
{
if (++sprite->data0 > 50)
{
sprite->callback = SpriteCB_Egg_4;
sprite->data0 = 0;
}
}
static void SpriteCB_Egg_4(struct Sprite* sprite)
{
s16 i;
if (sprite->data0 == 0)
BeginNormalPaletteFade(-1, -1, 0, 0x10, 0xFFFF);
if (sprite->data0 < 4u)
{
for (i = 0; i <= 3; i++)
CreateRandomEggShardSprite();
}
sprite->data0++;
if (!gPaletteFade.active)
{
PlaySE(SE_TAMAGO);
sprite->invisible = 1;
sprite->callback = SpriteCB_Egg_5;
sprite->data0 = 0;
}
}
static void SpriteCB_Egg_5(struct Sprite* sprite)
{
if (sprite->data0 == 0)
{
gSprites[sEggHatchData->pokeSpriteID].invisible = 0;
StartSpriteAffineAnim(&gSprites[sEggHatchData->pokeSpriteID], 1);
}
if (sprite->data0 == 8)
BeginNormalPaletteFade(-1, -1, 0x10, 0, 0xFFFF);
if (sprite->data0 <= 9)
gSprites[sEggHatchData->pokeSpriteID].pos1.y -= 1;
if (sprite->data0 > 40)
sprite->callback = SpriteCallbackDummy;
sprite->data0++;
}
static void SpriteCB_EggShard(struct Sprite* sprite)
{
sprite->data4 += sprite->data1;
sprite->data5 += sprite->data2;
sprite->pos2.x = sprite->data4 / 256;
sprite->pos2.y = sprite->data5 / 256;
sprite->data2 += sprite->data3;
if (sprite->pos1.y + sprite->pos2.y > sprite->pos1.y + 20 && sprite->data2 > 0)
DestroySprite(sprite);
}
static void CreateRandomEggShardSprite(void)
{
u16 spriteAnimIndex;
s16 velocity1 = sEggShardVelocities[sEggHatchData->eggShardVelocityID][0];
s16 velocity2 = sEggShardVelocities[sEggHatchData->eggShardVelocityID][1];
sEggHatchData->eggShardVelocityID++;
spriteAnimIndex = Random() % 4;
CreateEggShardSprite(120, 60, velocity1, velocity2, 100, spriteAnimIndex);
}
static void CreateEggShardSprite(u8 x, u8 y, s16 data1, s16 data2, s16 data3, u8 spriteAnimIndex)
{
u8 spriteID = CreateSprite(&sSpriteTemplate_EggShard, x, y, 4);
gSprites[spriteID].data1 = data1;
gSprites[spriteID].data2 = data2;
gSprites[spriteID].data3 = data3;
StartSpriteAnim(&gSprites[spriteID], spriteAnimIndex);
}
static void EggHatchPrintMessage(u8 windowId, u8* string, u8 x, u8 y, u8 speed)
{
FillWindowPixelBuffer(windowId, 0xFF);
sEggHatchData->textColor.fgColor = 0;
sEggHatchData->textColor.bgColor = 5;
sEggHatchData->textColor.shadowColor = 6;
AddTextPrinterParametrized2(windowId, 1, x, y, 0, 0, &sEggHatchData->textColor, speed, string);
}
u8 GetEggStepsToSubtract(void)
{
u8 count, i;
for (count = CalculatePlayerPartyCount(), i = 0; i < count; i++)
{
if (!GetMonData(&gPlayerParty[i], MON_DATA_SANITY_BIT3))
{
u8 ability = GetMonAbility(&gPlayerParty[i]);
if (ability == ABILITY_MAGMA_ARMOR || ability == ABILITY_FLAME_BODY)
return 2;
}
}
return 1;
}
u16 sub_80722E0(void)
{
u16 value = sub_80D22D0();
value += sub_80C7050(6);
return value;
}

28
src/field_camera.c Normal file
View File

@@ -0,0 +1,28 @@
// Includes
#include "global.h"
// Static type declarations
struct FieldCameraUnknownStruct
{
u8 unk0;
u8 unk1;
u8 unk2;
u8 unk3;
bool8 unk4;
};
// Static RAM declarations
IWRAM_DATA struct FieldCameraUnknownStruct gUnknown_03000E20;
IWRAM_DATA s16 gUnknown_03000E28;
IWRAM_DATA s16 gUnknown_03000E2A;
IWRAM_DATA u8 gUnknown_03000E2C;
IWRAM_DATA void (*gUnknown_03000E30)(void);
// Static ROM declarations
// .rodata
// .text

15
src/field_effect.c Normal file
View File

@@ -0,0 +1,15 @@
// Includes
#include "global.h"
// Static type declarations
// Static RAM declarations
IWRAM_DATA u8 gUnknown_03000F58[32];
// Static ROM declarations
// .rodata
// .text

5118
src/field_map_obj.c Executable file

File diff suppressed because it is too large Load Diff

15
src/field_screen.c Normal file
View File

@@ -0,0 +1,15 @@
// Includes
#include "global.h"
// Static type declarations
// Static RAM declarations
IWRAM_DATA u8 *gUnknown_03000F50;
IWRAM_DATA u32 filler_03000f54;
// Static ROM declarations
// .rodata
// .text

363
src/field_special_scene.c Executable file
View File

@@ -0,0 +1,363 @@
#include "global.h"
#include "task.h"
#include "sprite.h"
#include "field_map_obj.h"
#include "songs.h"
#include "sound.h"
#include "palette.h"
#include "script.h"
#include "vars.h"
#include "event_data.h"
#include "main.h"
#define SECONDS(value) ((signed) (60.0 * value + 0.5))
extern u8 GetSSTidalLocation(s8 *, s8 *, s16 *, s16 *); // should be in field_specials.h
extern void warp1_set(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y);
extern bool8 sub_80D3340(u8, u8, u8);
extern bool32 CountSSTidalStep(u16);
extern bool8 exec_movement(u8, u8, u8, u8 *);
extern void copy_saved_warp2_bank_and_enter_x_to_warp1(u8 unused);
extern void sp13E_warp_to_last_warp(void);
extern void saved_warp2_set(int unused, s8 mapGroup, s8 mapNum, s8 warpId);
extern void sub_80AF8B8(void);
// porthole states
enum
{
INIT_PORTHOLE,
IDLE_CHECK,
EXECUTE_MOVEMENT,
EXIT_PORTHOLE,
};
extern void SetCameraPanning(s16 x, s16 y);
extern void SetCameraPanningCallback(void ( *callback)());
extern void InstallCameraPanAheadCallback();
extern void pal_fill_black(void);
extern void MapGridSetMetatileIdAt(s32 x, s32 y, u16 metatileId);
extern void DrawWholeMapView();
extern s8 gTruckCamera_HorizontalTable[];
extern u8 gUnknown_0858E8AB[];
extern u8 gUnknown_0858E8AD[];
void Task_Truck3(u8);
s16 GetTruckCameraBobbingY(int a1)
{
if (!(a1 % 120))
return -1;
else if ((a1 % 10) <= 4)
return 1;
return 0;
}
s16 GetTruckBoxMovement(int a1) // for the box movement?
{
if (!((a1 + 120) % 180))
return -1;
return 0;
}
// smh STILL BROKEN IN EMERALD
void Task_Truck1(u8 taskId)
{
s16 *data = gTasks[taskId].data;
s16 cameraYpan;
s16 box1 = 0;
s16 box2 = 0;
s16 box3 = 0;
u8 mapNum, mapGroup;
register s16 zero asm("r4");
box1 = GetTruckBoxMovement(data[0] + 30) * 4; // top box.
sub_808E82C(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 3, box1 + 3);
box2 = GetTruckBoxMovement(data[0]) * 2; // bottom left box.
sub_808E82C(2, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 0, box2 - 3);
box3 = GetTruckBoxMovement(data[0]) * 4; // bottom right box.
mapNum = gSaveBlock1Ptr->location.mapNum;
mapGroup = gSaveBlock1Ptr->location.mapGroup;
zero = 0;
sub_808E82C(3, mapNum, mapGroup, -3, box3);
if (++data[0] == SECONDS(500)) // this will never run
data[0] = zero; // reset the timer if it gets stuck.
cameraYpan = GetTruckCameraBobbingY(data[0]);
SetCameraPanning(0, cameraYpan);
}
void Task_Truck2(u8 taskId)
{
s16 *data = gTasks[taskId].data;
s16 cameraYpan;
s16 cameraXpan;
s16 box1;
s16 box2;
s16 box3;
data[0]++;
data[2]++;
if (data[0] > 5)
{
data[0] = 0;
data[1]++;
}
if ((u16)data[1] == 19)
{
DestroyTask(taskId);
}
else
{
if (gTruckCamera_HorizontalTable[data[1]] == 2)
gTasks[taskId].func = Task_Truck3;
cameraXpan = gTruckCamera_HorizontalTable[data[1]];
cameraYpan = GetTruckCameraBobbingY(data[2]);
SetCameraPanning(cameraXpan, cameraYpan);
box1 = GetTruckBoxMovement(data[2] + 30) * 4;
sub_808E82C(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 3 - cameraXpan, box1 + 3);
box2 = GetTruckBoxMovement(data[2]) * 2;
sub_808E82C(2, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -cameraXpan, box2 - 3);
box3 = GetTruckBoxMovement(data[2]) * 4;
sub_808E82C(3, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -3 - cameraXpan, box3);
}
}
void Task_Truck3(u8 taskId)
{
s16 *data = gTasks[taskId].data;
s16 cameraXpan;
s16 cameraYpan;
data[0]++;
if (data[0] > 5)
{
data[0] = 0;
data[1]++;
}
if ((u16)data[1] == 19)
{
DestroyTask(taskId);
}
else
{
cameraXpan = gTruckCamera_HorizontalTable[data[1]];
cameraYpan = 0;
SetCameraPanning(cameraXpan, 0);
sub_808E82C(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 3 - cameraXpan, cameraYpan + 3);
sub_808E82C(2, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -cameraXpan, cameraYpan - 3);
sub_808E82C(3, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -3 - cameraXpan, cameraYpan);
}
}
void Task_HandleTruckSequence(u8 taskId)
{
s16 *data = gTasks[taskId].data;
switch (data[0])
{
/*
Each case has a timer which is handled with data[1], incrementing
until it reaches the if function's condition, which sets the next task up.
*/
case 0:
data[1]++;
if (data[1] == SECONDS(1.5))
{
SetCameraPanningCallback(NULL);
data[1] = 0; // reset the timer.
data[2] = CreateTask(Task_Truck1, 0xA);
data[0] = 1; // run the next case.
PlaySE(SE_TRACK_MOVE);
}
break;
case 1:
data[1]++;
if (data[1] == SECONDS(2.5))
{
pal_fill_black();
data[1] = 0;
data[0] = 2;
}
break;
case 2:
data[1]++;
if (!gPaletteFade.active && data[1] > SECONDS(5))
{
data[1] = 0;
DestroyTask(data[2]);
data[3] = CreateTask(Task_Truck2, 0xA);
data[0] = 3;
PlaySE(SE_TRACK_STOP);
}
break;
case 3:
if (!gTasks[data[3]].isActive) // is Truck2 no longer active (is Truck3 active?)
{
InstallCameraPanAheadCallback();
data[1] = 0;
data[0] = 4;
}
break;
case 4:
data[1]++;
if (data[1] == 90)
{
PlaySE(SE_TRACK_HAIK);
data[1] = 0;
data[0] = 5;
}
break;
case 5:
data[1]++;
if (data[1] == 120)
{
MapGridSetMetatileIdAt(11, 8, 520);
MapGridSetMetatileIdAt(11, 9, 528);
MapGridSetMetatileIdAt(11, 10, 536);
DrawWholeMapView();
PlaySE(SE_TRACK_DOOR);
DestroyTask(taskId);
ScriptContext2_Disable();
}
break;
}
}
void ExecuteTruckSequence(void)
{
MapGridSetMetatileIdAt(11, 8, 525);
MapGridSetMetatileIdAt(11, 9, 533);
MapGridSetMetatileIdAt(11, 10, 541);
DrawWholeMapView();
ScriptContext2_Enable();
CpuFastFill(0, gPlttBufferFaded, 0x400);
CreateTask(Task_HandleTruckSequence, 0xA);
}
void EndTruckSequence(u8 taskId)
{
if (!FuncIsActiveTask(Task_HandleTruckSequence))
{
sub_808E82C(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 3, 3);
sub_808E82C(2, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 0, -3);
sub_808E82C(3, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -3, 0);
}
}
bool8 sub_80FB59C(void)
{
s8 mapGroup, mapNum;
s16 x, y;
if (GetSSTidalLocation(&mapGroup, &mapNum, &x, &y))
{
return FALSE;
}
else
{
warp1_set(mapGroup, mapNum, -1, x, y);
return TRUE;
}
}
void Task_HandlePorthole(u8 taskId)
{
s16 *data = gTasks[taskId].data;
u16 *var = GetVarPointer(VAR_PORTHOLE);
struct WarpData *location = &gSaveBlock1Ptr->location;
switch (data[0])
{
case INIT_PORTHOLE: // finish fading before making porthole finish.
if (!gPaletteFade.active)
{
data[1] = 0;
data[0] = EXECUTE_MOVEMENT; // execute movement before checking if should be exited. strange?
}
break;
case IDLE_CHECK: // idle and move.
if (gMain.newKeys & A_BUTTON)
data[1] = 1;
if (!sub_80D3340(0xFF, location->mapNum, location->mapGroup))
return;
if (CountSSTidalStep(1) == TRUE)
{
if (*var == 2)
*var = 9;
else
*var = 10;
data[0] = 3;
return;
}
data[0] = 2;
case EXECUTE_MOVEMENT: // execute movement.
if (data[1])
{
data[0] = EXIT_PORTHOLE; // exit porthole.
return;
}
// run this once.
if (*var == 2) // which direction?
{
exec_movement(0xFF, location->mapNum, location->mapGroup, gUnknown_0858E8AB);
data[0] = IDLE_CHECK; // run case 1.
}
else
{
exec_movement(0xFF, location->mapNum, location->mapGroup, gUnknown_0858E8AD);
data[0] = IDLE_CHECK; // run case 1.
}
break;
case EXIT_PORTHOLE: // exit porthole.
FlagReset(0x4001);
FlagReset(0x4000);
copy_saved_warp2_bank_and_enter_x_to_warp1(0);
sp13E_warp_to_last_warp();
DestroyTask(taskId);
break;
}
}
void sub_80FB6EC(void)
{
u8 spriteId = AddPseudoFieldObject(0x8C, SpriteCallbackDummy, 112, 80, 0);
gSprites[spriteId].coordOffsetEnabled = FALSE;
if (VarGet(0x40B4) == 2)
{
StartSpriteAnim(&gSprites[spriteId], FieldObjectDirectionToImageAnimId(4));
}
else
{
StartSpriteAnim(&gSprites[spriteId], FieldObjectDirectionToImageAnimId(3));
}
}
void sub_80FB768(void)
{
sub_80FB6EC();
gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = TRUE;
pal_fill_black();
CreateTask(Task_HandlePorthole, 80);
ScriptContext2_Enable();
}
void sub_80FB7A4(void)
{
FlagSet(SYS_CRUISE_MODE);
FlagSet(0x4001);
FlagSet(0x4000);
saved_warp2_set(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1);
sub_80FB59C();
sub_80AF8B8();
}

19
src/fldeff_cut.c Normal file
View File

@@ -0,0 +1,19 @@
// Includes
#include "global.h"
// Static type declarations
// Static RAM declarations
IWRAM_DATA u8 gUnknown_03001100;
IWRAM_DATA u8 gUnknown_03001101;
IWRAM_DATA u8 gUnknown_03001102;
IWRAM_DATA u32 fldeff_cut_unused_03001104;
IWRAM_DATA u8 gUnknown_03001108[25];
// Static ROM declarations
// .rodata
// .text

View File

@@ -1,4 +1,5 @@
#include "global.h"
#include "gpu_regs.h"
#define GPU_REG_BUF_SIZE 0x60
@@ -14,14 +15,15 @@ static bool8 sShouldSyncRegIE;
static u16 sRegIE;
static void CopyBufferedValueToGpuReg(u8 regOffset);
static void SyncRegIE();
static void SyncRegIE(void);
static void UpdateRegDispstatIntrBits(u16 regIE);
void InitGpuRegManager()
void InitGpuRegManager(void)
{
s32 i;
for (i = 0; i < GPU_REG_BUF_SIZE; i++) {
for (i = 0; i < GPU_REG_BUF_SIZE; i++)
{
sGpuRegBuffer[i] = 0;
sGpuRegWaitingList[i] = EMPTY_SLOT;
}
@@ -33,20 +35,25 @@ void InitGpuRegManager()
static void CopyBufferedValueToGpuReg(u8 regOffset)
{
if (regOffset == REG_OFFSET_DISPSTAT) {
if (regOffset == REG_OFFSET_DISPSTAT)
{
REG_DISPSTAT &= ~(DISPSTAT_HBLANK_INTR | DISPSTAT_VBLANK_INTR);
REG_DISPSTAT |= GPU_REG_BUF(REG_OFFSET_DISPSTAT);
} else {
}
else
{
GPU_REG(regOffset) = GPU_REG_BUF(regOffset);
}
}
void CopyBufferedValuesToGpuRegs()
void CopyBufferedValuesToGpuRegs(void)
{
if (!sGpuRegBufferLocked) {
if (!sGpuRegBufferLocked)
{
s32 i;
for (i = 0; i < GPU_REG_BUF_SIZE; i++) {
for (i = 0; i < GPU_REG_BUF_SIZE; i++)
{
u8 regOffset = sGpuRegWaitingList[i];
if (regOffset == EMPTY_SLOT)
return;
@@ -135,7 +142,7 @@ void ClearGpuRegBits(u8 regOffset, u16 mask)
SetGpuReg(regOffset, regValue & ~mask);
}
static void SyncRegIE()
static void SyncRegIE(void)
{
if (sShouldSyncRegIE) {
u16 temp = REG_IME;

4
src/hall_of_fame.c Normal file
View File

@@ -0,0 +1,4 @@
#include "global.h"
#include "hall_of_fame.h"

View File

@@ -8,9 +8,9 @@
extern void ApplyNewEncyprtionKeyToHword(u16* hword, u32 newKey);
extern bool8 InBattlePyramid(void);
extern const u8 gOtherText_PokeBalls[];
extern const u8 gOtherText_Berries[];
extern const u8 gOtherText_Berry[];
extern const u8 gText_PokeBalls[];
extern const u8 gText_Berries[];
extern const u8 gText_Berry[];
extern const u8 gUnknown_085897E4[][28]; // not sure what this one is
bool8 CheckPyramidBagHasItem(u16 itemId, u16 count);
@@ -92,7 +92,7 @@ void CopyItemNameHandlePlural(u16 itemId, u8 *string, u32 quantity)
if (quantity < 2)
StringCopy(string, ItemId_GetItem(ITEM_POKE_BALL)->name);
else
StringCopy(string, gOtherText_PokeBalls);
StringCopy(string, gText_PokeBalls);
}
else
{
@@ -109,9 +109,9 @@ void GetBerryCountString(u8* dst, const u8* berryName, u32 quantity)
u8* txtPtr;
if (quantity < 2)
berryString = gOtherText_Berry;
berryString = gText_Berry;
else
berryString = gOtherText_Berries;
berryString = gText_Berries;
txtPtr = StringCopy(dst, berryName);
*txtPtr = CHAR_SPACE;
StringCopy(txtPtr + 1, berryString);

1101
src/lilycove_lady.c Normal file

File diff suppressed because it is too large Load Diff

56
src/link.c Normal file
View File

@@ -0,0 +1,56 @@
// Includes
#include "global.h"
// Static type declarations
struct BlockTransfer
{
u16 pos;
u16 size;
void *src;
bool8 active;
u8 multiplayerId;
};
struct LinkTestBGInfo
{
u32 screenBaseBlock;
u32 paletteNum;
u32 dummy_8;
u32 dummy_C;
};
// Static RAM declarations
IWRAM_DATA struct BlockTransfer gUnknown_03000D10;
IWRAM_DATA u32 link_c_unused_03000d1c;
IWRAM_DATA struct BlockTransfer gUnknown_03000D20[4];
IWRAM_DATA u32 gUnknown_03000D50;
IWRAM_DATA u32 gUnknown_03000D54;
IWRAM_DATA u8 gUnknown_03000D58;
IWRAM_DATA u32 gUnknown_03000D5C;
IWRAM_DATA u32 gUnknown_03000D60;
IWRAM_DATA u8 gUnknown_03000D64[4]; // not really, but won't match otherwise
IWRAM_DATA u8 gUnknown_03000D68[4];
IWRAM_DATA u8 gUnknown_03000D6C;
IWRAM_DATA bool8 gUnknown_03000D6D;
IWRAM_DATA u16 gUnknown_03000D6E;
IWRAM_DATA u16 gUnknown_03000D70;
IWRAM_DATA u8 gUnknown_03000D72;
IWRAM_DATA u8 gUnknown_03000D73;
IWRAM_DATA u8 gUnknown_03000D74[4]; // not really, but won't match otherwise
IWRAM_DATA u8 gUnknown_03000D78[8]; // not really, but won't match otherwise
IWRAM_DATA u8 gUnknown_03000D80[16];
IWRAM_DATA u16 gUnknown_03000D90[8];
IWRAM_DATA u32 gUnknown_03000DA0;
IWRAM_DATA u32 gUnknown_03000DA4;
IWRAM_DATA void *gUnknown_03000DA8;
IWRAM_DATA void *gUnknown_03000DAC;
IWRAM_DATA bool32 gUnknown_03000DB0;
// Static ROM declarations
// .rodata
// .text

View File

@@ -6,15 +6,11 @@
#include "rng.h"
#include "malloc.h"
extern u8 gPlayerPartyCount;
extern struct PokemonStorage* gPokemonStoragePtr;
extern void* gUnknown_0203CF5C;
extern u8 gHeap[0x1C000];
extern bool16 IdentifyFlash(void);
extern void SetBagItemsPointers(void);
extern void SetDecorationInventoriesPointers(void);
extern void InitHeap(void *heapStart, u32 heapSize);
void ApplyNewEncyprtionKeyToAllEncryptedData(u32 encryptionKey);

View File

@@ -77,7 +77,7 @@ const IntrFunc gIntrTableTemplate[] =
#define INTR_COUNT ((int)(sizeof(gIntrTableTemplate)/sizeof(IntrFunc)))
extern u16 gUnknown_03000000;
static u16 gUnknown_03000000;
extern u16 gKeyRepeatStartDelay;
extern u8 gUnknown_030022B4;

15
src/main_menu.c Normal file
View File

@@ -0,0 +1,15 @@
// Includes
#include "global.h"
// Static type declarations
// Static RAM declarations
IWRAM_DATA u8 gUnknown_03000DD0;
// Static ROM declarations
// .rodata
// .text

View File

@@ -2,6 +2,7 @@
static void *sHeapStart;
static u32 sHeapSize;
static u32 malloc_c_unused_0300000c; // needed to align dma3_manager.o(.bss)
#define MALLOC_SYSTEM_ID 0xA3A3
@@ -38,7 +39,7 @@ void PutMemBlockHeader(void *block, struct MemBlock *prev, struct MemBlock *next
void PutFirstMemBlockHeader(void *block, u32 size)
{
PutMemBlockHeader(block, (struct MemBlock *)block, (struct MemBlock *)block, size - 16);
PutMemBlockHeader(block, (struct MemBlock *)block, (struct MemBlock *)block, size - sizeof(struct MemBlock));
}
void *AllocInternal(void *heapStart, u32 size)
@@ -48,6 +49,7 @@ void *AllocInternal(void *heapStart, u32 size)
struct MemBlock *splitBlock;
u32 foundBlockSize;
// Alignment
if (size & 3)
size = 4 * ((size / 4) + 1);
@@ -58,7 +60,7 @@ void *AllocInternal(void *heapStart, u32 size)
foundBlockSize = pos->size;
if (foundBlockSize >= size) {
if (foundBlockSize - size <= 31) {
if (foundBlockSize - size < 2 * sizeof(struct MemBlock)) {
// The block isn't much bigger than the requested size,
// so just use it.
pos->flag = TRUE;

1436
src/metatile_behavior.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,77 @@
#include "global.h"
#include "money.h"
#include "event_data.h"
#include "string_util.h"
#include "text.h"
#include "menu.h"
#include "window.h"
#include "sprite.h"
#include "decompress.h"
extern const u8 gText_PokedollarVar1[];
extern const u8 gMenuMoneyGfx[];
extern const u8 gMenuMoneyPal[];
#define MAX_MONEY 999999
EWRAM_DATA static u8 sMoneyBoxWindowId = 0;
EWRAM_DATA static u8 sMoneyLabelSpriteId = 0;
#define MONEY_LABEL_TAG 0x2722
static const struct OamData sOamData_MoneyLabel =
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = 1,
.x = 0,
.matrixNum = 0,
.size = 2,
.tileNum = 0,
.priority = 0,
.paletteNum = 0,
.affineParam = 0,
};
static const union AnimCmd sSpriteAnim_MoneyLabel[] =
{
ANIMCMD_FRAME(0, 0),
ANIMCMD_END
};
static const union AnimCmd *const sSpriteAnimTable_MoneyLabel[] =
{
sSpriteAnim_MoneyLabel,
};
static const struct SpriteTemplate sSpriteTemplate_MoneyLabel =
{
.tileTag = MONEY_LABEL_TAG,
.paletteTag = MONEY_LABEL_TAG,
.oam = &sOamData_MoneyLabel,
.anims = sSpriteAnimTable_MoneyLabel,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy
};
static const struct CompressedSpriteSheet sSpriteSheet_MoneyLabel =
{
.data = gMenuMoneyGfx,
.size = 256,
.tag = MONEY_LABEL_TAG,
};
static const struct CompressedSpritePalette sSpritePalette_MoneyLabel =
{
.data = gMenuMoneyPal,
.tag = MONEY_LABEL_TAG
};
u32 GetMoney(u32* moneyPtr)
{
return *moneyPtr ^ gSaveBlock2Ptr->encryptionKey;
@@ -53,3 +122,79 @@ void SubtractMoney(u32* moneyPtr, u32 toSub)
SetMoney(moneyPtr, toSet);
}
bool8 IsEnoughForCostInVar0x8005(void)
{
return IsEnoughMoney(&gSaveBlock1Ptr->money, gSpecialVar_0x8005);
}
void SubtractMoneyFromVar0x8005(void)
{
SubtractMoney(&gSaveBlock1Ptr->money, gSpecialVar_0x8005);
}
void PrintMoneyAmountInMoneyBox(u8 windowId, int amount, u8 speed)
{
PrintMoneyAmount(windowId, 0x26, 1, amount, speed);
}
void PrintMoneyAmount(u8 windowId, u8 x, u8 y, int amount, u8 speed)
{
u8 *txtPtr;
s32 strLength;
ConvertIntToDecimalStringN(gStringVar1, amount, STR_CONV_MODE_LEFT_ALIGN, 6);
strLength = 6 - StringLength(gStringVar1);
txtPtr = gStringVar4;
while (strLength-- > 0)
*(txtPtr++) = 0x77;
StringExpandPlaceholders(txtPtr, gText_PokedollarVar1);
PrintTextOnWindow(windowId, 1, gStringVar4, x, y, speed, NULL);
}
void PrintMoneyAmountInMoneyBoxWithBorder(u8 windowId, u16 tileStart, u8 pallete, int amount)
{
SetWindowBorderStyle(windowId, FALSE, tileStart, pallete);
PrintMoneyAmountInMoneyBox(windowId, amount, 0);
}
void ChangeAmountInMoneyBox(int amount)
{
PrintMoneyAmountInMoneyBox(sMoneyBoxWindowId, amount, 0);
}
void DrawMoneyBox(int amount, u8 x, u8 y)
{
struct WindowTemplate template;
SetWindowTemplateFields(&template, 0, x + 1, y + 1, 10, 2, 15, 8);
sMoneyBoxWindowId = AddWindow(&template);
FillWindowPixelBuffer(sMoneyBoxWindowId, 0);
PutWindowTilemap(sMoneyBoxWindowId);
CopyWindowToVram(sMoneyBoxWindowId, 1);
PrintMoneyAmountInMoneyBoxWithBorder(sMoneyBoxWindowId, 0x214, 14, amount);
AddMoneyLabelObject((8 * x) + 19, (8 * y) + 11);
}
void HideMoneyBox(void)
{
RemoveMoneyLabelObject();
sub_8198070(sMoneyBoxWindowId, FALSE);
CopyWindowToVram(sMoneyBoxWindowId, 2);
RemoveWindow(sMoneyBoxWindowId);
}
void AddMoneyLabelObject(u16 x, u16 y)
{
LoadCompressedObjectPic(&sSpriteSheet_MoneyLabel);
LoadCompressedObjectPalette(&sSpritePalette_MoneyLabel);
sMoneyLabelSpriteId = CreateSprite(&sSpriteTemplate_MoneyLabel, x, y, 0);
}
void RemoveMoneyLabelObject(void)
{
DestroySpriteAndFreeResources(&gSprites[sMoneyLabelSpriteId]);
}

View File

@@ -316,7 +316,7 @@ void MultiBootStartProbe(struct MultiBootParam *mp)
mp->probe_count = 1;
}
void MultiBootStartMaster(struct MultiBootParam *mp, u8 *srcp, int length, u8 palette_color, s8 palette_speed)
void MultiBootStartMaster(struct MultiBootParam *mp, const u8 *srcp, int length, u8 palette_color, s8 palette_speed)
{
int i = 0;

View File

@@ -18,6 +18,7 @@
#include "event_data.h"
#include "money.h"
#include "coins.h"
#include "text.h"
extern u8 gPlayerPartyCount;
extern u8 gDifferentSaveFile;
@@ -104,7 +105,10 @@ void ClearPokedexFlags(void)
memset(&gSaveBlock2Ptr->pokedex.seen, 0, sizeof(gSaveBlock2Ptr->pokedex.seen));
}
extern const struct ContestWinner gContestWinnerPicDummy;
const struct ContestWinner gContestWinnerPicDummy = {
.monName = _(""),
.trainerName = _("")
};
void ClearAllContestWinnerPics(void)
{

View File

@@ -1,5 +1,8 @@
#include "global.h"
#include "blend_palette.h"
#include "palette.h"
#include "decompress.h"
#include "gpu_regs.h"
#include "task.h"
enum
@@ -28,7 +31,7 @@ struct PaletteStructTemplate
struct PaletteStruct
{
struct PaletteStructTemplate *base;
const struct PaletteStructTemplate *base;
u32 ps_field_4_0:1;
u16 ps_field_4_1:1;
u32 baseDestOffset:9;
@@ -38,31 +41,6 @@ struct PaletteStruct
u8 ps_field_9;
};
extern void LZDecompressWram(const void *src, void *dest);
extern void SetGpuReg(u8 regOffset, u16 value);
extern void sub_8149DFC(u8 a1);
extern void sub_80A1670(u16 a1);
extern void sub_80A2D54(u8 a1);
extern void SetWordTaskArg(u8 taskId, u8 dataElem, u32 value);
extern void _call_via_r1(u32 a1, void *a2);
extern void BlendPalette(u16, u16, u8, u16);
EWRAM_DATA u16 gPlttBufferUnfaded[0x200] = {0};
EWRAM_DATA u16 gPlttBufferFaded[0x200] = {0};
EWRAM_DATA struct PaletteStruct sPaletteStructs[0x10] = {0};
EWRAM_DATA struct PaletteFadeControl gPaletteFade = {0};
EWRAM_DATA u32 gFiller_2037FE0 = 0;
EWRAM_DATA u32 sPlttBufferTransferPending = 0;
EWRAM_DATA u8 gPaletteDecompressionBuffer[0x400] = {0};
extern struct PaletteStructTemplate gDummyPaletteStructTemplate;
extern void *gUnknown_0852487C;
extern u8 gUnknown_0852489C[];
extern u16 gUnknown_03000F3C;
extern void *gUnknown_03000F44;
static void unused_sub_80A1CDC(struct PaletteStruct *, u32 *);
static void unused_sub_80A1E40(struct PaletteStruct *, u32 *);
static void unused_sub_80A1F00(struct PaletteStruct *);
@@ -73,32 +51,29 @@ static u8 UpdateFastPaletteFade(void);
static u8 UpdateHardwarePaletteFade(void);
static void UpdateBlendRegisters(void);
static bool8 IsSoftwarePaletteFadeFinishing(void);
static void sub_80A2D54(u8 taskId);
void sub_80A1818(u16 a1)
{
void **v1 = &gUnknown_0852487C;
CpuSet(v1[a1 & 0x3], gPlttBufferUnfaded + 0x80, 0x10);
BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF);
if ((u8)FindTaskIdByFunc(sub_8149DFC) != 0xFF )
{
gUnknown_03000F44 = sub_80A1670;
gUnknown_03000F3C = 0x20;
}
return;
}
EWRAM_DATA u16 gPlttBufferUnfaded[0x200] = {0};
EWRAM_DATA u16 gPlttBufferFaded[0x200] = {0};
EWRAM_DATA struct PaletteStruct sPaletteStructs[0x10] = {0};
EWRAM_DATA struct PaletteFadeControl gPaletteFade = {0};
static EWRAM_DATA u32 gFiller_2037FE0 = 0;
static EWRAM_DATA u32 sPlttBufferTransferPending = 0;
EWRAM_DATA u8 gPaletteDecompressionBuffer[0x400] = {0};
void sub_80A1884(u16 a1)
{
void **v1 = &gUnknown_0852487C;
CpuSet(v1[a1 & 0x3], gPlttBufferUnfaded + 0x80, 0x10);
if ((u8)FindTaskIdByFunc(sub_8149DFC) == 0xFF )
{
BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF);
if (!--gUnknown_03000F3C)
gUnknown_03000F44 = 0;
}
return;
}
static const struct PaletteStructTemplate gDummyPaletteStructTemplate = {
.uid = 0xFFFF,
.pst_field_B_5 = 1
};
static const u8 gUnknown_0852489C[] = {
0, 0, 0, 0, 0,
5, 5, 5, 5, 5,
11, 11, 11, 11, 11,
16, 16, 16, 16, 16,
21, 21, 21, 21, 21,
27, 27, 27, 27, 27,
31, 31
};
void LoadCompressedPalette(const void *src, u16 offset, u16 size)
{

View File

@@ -31,11 +31,11 @@ extern const union AnimCmd* gUnknown_082FF70C[];
extern const union AnimCmd* const * const gUnknown_08309AAC[];
extern const union AnimCmd* const * const gUnknown_08305D0C[];
extern const union AnimCmd* const * const gUnknown_0830536C[];
extern const u8 gBadEggNickname[];
extern const u8 gText_BadEgg[];
extern const u8 gText_EggNickname[];
extern u8 GetBankSide(u8 bank);
extern u8 GetBankByPlayerAI(u8 bank);
extern u8 GetBankByIdentity(u8 bank);
extern u8 GetBankIdentity(u8 bank);
u8 CountAliveMonsInBattle(u8 caseId)
@@ -90,7 +90,7 @@ u8 sub_8069F34(u8 bank)
status ^= 1;
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
return GetBankByPlayerAI(status);
return GetBankByIdentity(status);
if (CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) > 1)
{
u8 val;
@@ -99,14 +99,14 @@ u8 sub_8069F34(u8 bank)
val = status ^ 2;
else
val = status;
return GetBankByPlayerAI(val);
return GetBankByIdentity(val);
}
else
{
if ((gAbsentBankFlags & gBitTable[status]))
return GetBankByPlayerAI(status ^ 2);
return GetBankByIdentity(status ^ 2);
else
return GetBankByPlayerAI(status);
return GetBankByIdentity(status);
}
}
@@ -409,8 +409,8 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data)
if (boxMon->isBadEgg)
{
for (retVal = 0;
retVal < POKEMON_NAME_LENGTH && gBadEggNickname[retVal] != EOS;
data[retVal] = gBadEggNickname[retVal], retVal++) {}
retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS;
data[retVal] = gText_BadEgg[retVal], retVal++) {}
data[retVal] = EOS;
}
@@ -1308,10 +1308,9 @@ void sub_805EF84(u8 bank, bool8);
extern struct BattlePokemon gBattleMons[4];
/*
void CopyPlayerPartyMonToBattleData(u8 bank, u8 partyIndex)
{
u16* hpSwitchout;
s32 i;
u8 nickname[POKEMON_NAME_LENGTH * 2];
@@ -1352,15 +1351,9 @@ void CopyPlayerPartyMonToBattleData(u8 bank, u8 partyIndex)
GetMonData(&gPlayerParty[partyIndex], MON_DATA_NICKNAME, nickname);
StringCopy10(gBattleMons[bank].nickname, nickname);
GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_NAME, gBattleMons[bank].otName);
// ewram memes from Ruby return
#ifdef NONMATCHING
gBattleStruct->hpOnSwitchout[GetBankSide(bank)] = gBattleMons[bank].hp;
#else
{
u32 side = GetBankSide(bank);
*(u16*)((void*)(gBattleStruct) + side) = gBattleMons[bank].hp;
}
#endif // NONMATCHING
hpSwitchout = &gBattleStruct->hpOnSwitchout[GetBankSide(bank)];
*hpSwitchout = gBattleMons[bank].hp;
for (i = 0; i < 8; i++)
gBattleMons[bank].statStages[i] = 6;
@@ -1369,4 +1362,3 @@ void CopyPlayerPartyMonToBattleData(u8 bank, u8 partyIndex)
sub_803FA70(bank);
sub_805EF84(bank, FALSE);
}
*/

View File

@@ -46,16 +46,16 @@ extern const struct SpindaSpot gSpindaSpotGraphics[];
extern const u8* const gStatNamesTable[];
extern const u8 gSpeciesNames[][11];
extern const u8 gUnknown_08329EC8[];
extern const u8 gUnknown_085CB38A[];
extern const u8 gUnknown_085CB3AA[];
extern const u8 gUnknown_085CA459[];
extern const u8 gUnknown_085CA424[];
extern const u8 gText_StatRose[];
extern const u8 gText_PkmnsStatChanged2[];
extern const u8 gText_PkmnGettingPumped[];
extern const u8 gText_PkmnShroudedInMist[];
extern const s8 gNatureStatTable[][5];
extern const s8 gUnknown_08329ECE[][3];
extern const u32 gBitTable[];
extern const u32 gTMHMLearnsets[][2];
extern const u8 BattleText_Wally[];
extern const u8 BattleText_PreventedSwitch[];
extern const u8 gText_BattleWallyName[];
extern const u8 gText_PkmnsXPreventsSwitching[];
extern const struct CompressedSpritePalette gMonPaletteTable[];
extern const struct CompressedSpritePalette gMonShinyPaletteTable[];
extern const u16 gHMMoves[];
@@ -215,8 +215,8 @@ void sub_806CF24(s32 stat)
{
gBankTarget = gBankInMenu;
StringCopy(gBattleTextBuff1, gStatNamesTable[gUnknown_08329EC8[stat]]);
StringCopy(gBattleTextBuff2, gUnknown_085CB38A);
StrCpyDecodeToDisplayedStringBattle(gUnknown_085CB3AA);
StringCopy(gBattleTextBuff2, gText_StatRose);
BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnsStatChanged2);
}
u8 *sub_806CF78(u16 itemId)
@@ -251,7 +251,7 @@ u8 *sub_806CF78(u16 itemId)
else
{
gBankAttacker = gBankInMenu;
StrCpyDecodeToDisplayedStringBattle(gUnknown_085CA459);
BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnGettingPumped);
}
}
}
@@ -259,7 +259,7 @@ u8 *sub_806CF78(u16 itemId)
if (itemEffect[3] & 0x80)
{
gBankAttacker = gBankInMenu;
StrCpyDecodeToDisplayedStringBattle(gUnknown_085CA424);
BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnShroudedInMist);
}
return gDisplayedStringBattle;
@@ -601,9 +601,9 @@ bool8 sub_806D7EC(void)
return retVal;
}
bool8 sub_806D82C(u8 id)
bool16 sub_806D82C(u8 id)
{
bool8 retVal = FALSE;
bool16 retVal = FALSE;
switch (gLinkPlayers[id].lp_field_18)
{
case 0:
@@ -1177,7 +1177,7 @@ u16 GetBattleBGM(void)
case CLASS_PKMN_TRAINER_RIVAL:
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
return 0x1E1;
if (!StringCompare(gTrainers[gTrainerBattleOpponent_A].trainerName, BattleText_Wally))
if (!StringCompare(gTrainers[gTrainerBattleOpponent_A].trainerName, gText_BattleWallyName))
return 0x1DC;
return 0x1E1;
case CLASS_ELITE_FOUR:
@@ -1361,20 +1361,20 @@ void BoxMonRestorePP(struct BoxPokemon *boxMon)
void sub_806E994(void)
{
gLastUsedAbility = gBattleStruct->field_B0;
gBattleTextBuff1[0] = 0xFD;
gBattleTextBuff1[1] = 4;
gBattleTextBuff1[0] = B_BUFF_PLACEHOLDER_BEGIN;
gBattleTextBuff1[1] = B_BUFF_MON_NICK_WITH_PREFIX;
gBattleTextBuff1[2] = gBattleStruct->field_49;
gBattleTextBuff1[4] = EOS;
gBattleTextBuff1[4] = B_BUFF_EOS;
if (!GetBankSide(gBattleStruct->field_49))
gBattleTextBuff1[3] = pokemon_order_func(gBattlePartyID[gBattleStruct->field_49]);
else
gBattleTextBuff1[3] = gBattlePartyID[gBattleStruct->field_49];
gBattleTextBuff2[0] = 0xFD;
gBattleTextBuff2[1] = 4;
gBattleTextBuff2[2] = gBankInMenu;
gBattleTextBuff2[3] = pokemon_order_func(gBattlePartyID[gBankInMenu]);
gBattleTextBuff2[4] = EOS;
StrCpyDecodeBattle(BattleText_PreventedSwitch, gStringVar4);
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff2, gBankInMenu, pokemon_order_func(gBattlePartyID[gBankInMenu]))
BattleStringExpandPlaceholders(gText_PkmnsXPreventsSwitching, gStringVar4);
}
struct PokeItem
@@ -1388,7 +1388,7 @@ extern const struct PokeItem gAlteringCaveWildMonHeldItems[9];
static s32 GetWildMonTableIdInAlteringCave(u16 species)
{
s32 i;
for (i = 0; i < 9; i++)
for (i = 0; i < (s32) ARRAY_COUNT(gAlteringCaveWildMonHeldItems); i++)
if (gAlteringCaveWildMonHeldItems[i].species == species)
return i;
return 0;
@@ -1511,8 +1511,6 @@ static void Task_PokemonSummaryAnimateAfterDelay(u8 taskId)
}
}
void DoMonFrontSpriteAnimation(struct Sprite* sprite, u16 species, bool8 noCry, u8 arg3);
void BattleAnimateFrontSprite(struct Sprite* sprite, u16 species, bool8 noCry, u8 arg3)
{
if (gHitMarker & HITMARKER_NO_ANIMATIONS && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)))

View File

@@ -45,8 +45,8 @@ static const u8 sGiftRibbonsMonDataIds[] =
MON_DATA_GIFT_RIBBON_7
};
extern const u8 gOtherText_DecimalPoint[];
extern const u8 gOtherText_Marco[];
extern const u8 gText_DecimalPoint[];
extern const u8 gText_Marco[];
extern const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1];
#define CM_PER_INCH 2.54
@@ -103,7 +103,7 @@ static void FormatMonSizeRecord(u8 *string, u32 size)
#endif
string = ConvertIntToDecimalStringN(string, size / 10, 0, 8);
string = StringAppend(string, gOtherText_DecimalPoint);
string = StringAppend(string, gText_DecimalPoint);
ConvertIntToDecimalStringN(string, size % 10, 0, 1);
}
@@ -152,7 +152,7 @@ static void GetMonSizeRecordInfo(u16 species, u16 *sizeRecord)
FormatMonSizeRecord(gStringVar3, size);
StringCopy(gStringVar1, gSpeciesNames[species]);
if (*sizeRecord == DEFAULT_MAX_SIZE)
StringCopy(gStringVar2, gOtherText_Marco);
StringCopy(gStringVar2, gText_Marco);
else
StringCopy(gStringVar2, gSaveBlock2Ptr->playerName);
}

View File

@@ -0,0 +1,15 @@
// Includes
#include "global.h"
// Static type declarations
// Static RAM declarations
IWRAM_DATA u8 gUnknown_03000F78[0x188];
// Static ROM declarations
// .rodata
// .text

28
src/record_mixing.c Normal file
View File

@@ -0,0 +1,28 @@
// Includes
#include "global.h"
// Static type declarations
// Static RAM declarations
IWRAM_DATA bool8 gUnknown_03001130;
IWRAM_DATA struct SecretBaseRecord *gUnknown_03001134;
IWRAM_DATA TVShow *gUnknown_03001138;
IWRAM_DATA struct UnknownSaveStruct2ABC *gUnknown_0300113C;
IWRAM_DATA OldMan *gUnknown_03001140;
IWRAM_DATA struct EasyChatPair *gUnknown_03001144;
IWRAM_DATA struct DaycareData *gUnknown_03001148;
IWRAM_DATA void *gUnknown_0300114C; // gSaveBlock2Ptr->field_64C
IWRAM_DATA LilycoveLady *gUnknown_03001150;
IWRAM_DATA void *gUnknown_03001154; // gSaveBlock2Ptr->field_0DC;
IWRAM_DATA void *gUnknown_03001158; // gSaveBlock2Ptr->field_64C
IWRAM_DATA u32 gUnknown_0300115C;
IWRAM_DATA u8 gUnknown_03001160[8];
IWRAM_DATA u32 gUnknown_03001168[3];
// Static ROM declarations
// .rodata
// .text

32
src/reset_save_heap.c Normal file
View File

@@ -0,0 +1,32 @@
#include "global.h"
#include "main.h"
#include "gpu_regs.h"
#include "m4a.h"
#include "load_save.h"
#include "save.h"
#include "new_game.h"
#include "rom4.h"
#include "malloc.h"
void sub_81700F8(void)
{
u16 imeBackup;
imeBackup = REG_IME;
REG_IME = 0;
RegisterRamReset(0x00000001);
ClearGpuRegBits(REG_OFFSET_DISPCNT, 0x80);
REG_IME = imeBackup;
gMain.inBattle = FALSE;
SetSaveBlocksPointers(sub_815355C());
sub_808447C();
ResetSaveCounters();
sub_81534D0(0);
if (gSaveFileStatus == 0 || gSaveFileStatus == 2)
{
Sav2_ClearSetDefault();
}
SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound);
InitHeap(gHeap, 0x1c000);
SetMainCallback2(sub_8086230);
}

218
src/roamer.c Normal file
View File

@@ -0,0 +1,218 @@
#include "global.h"
#include "roamer.h"
#include "pokemon.h"
#include "rng.h"
#include "species.h"
#include "event_data.h"
enum
{
MAP_GRP = 0, // map group
MAP_NUM = 1, // map number
};
EWRAM_DATA static u8 sLocationHistory[3][2] = {0};
EWRAM_DATA static u8 sRoamerLocation[2] = {0};
static const u8 sRoamerLocations[][6] =
{
{ 0x19, 0x1A, 0x20, 0x21, 0x31, 0xFF },
{ 0x1A, 0x19, 0x20, 0x21, 0xFF, 0xFF },
{ 0x20, 0x1A, 0x19, 0x21, 0xFF, 0xFF },
{ 0x21, 0x20, 0x19, 0x1A, 0x22, 0x26 },
{ 0x22, 0x21, 0x23, 0xFF, 0xFF, 0xFF },
{ 0x23, 0x22, 0x24, 0xFF, 0xFF, 0xFF },
{ 0x24, 0x23, 0x25, 0x26, 0xFF, 0xFF },
{ 0x25, 0x24, 0x26, 0xFF, 0xFF, 0xFF },
{ 0x26, 0x25, 0x21, 0xFF, 0xFF, 0xFF },
{ 0x27, 0x24, 0x28, 0x29, 0xFF, 0xFF },
{ 0x28, 0x27, 0x2A, 0xFF, 0xFF, 0xFF },
{ 0x29, 0x27, 0x2A, 0xFF, 0xFF, 0xFF },
{ 0x2A, 0x28, 0x29, 0x2B, 0xFF, 0xFF },
{ 0x2B, 0x2A, 0x2C, 0xFF, 0xFF, 0xFF },
{ 0x2C, 0x2B, 0x2D, 0xFF, 0xFF, 0xFF },
{ 0x2D, 0x2C, 0x2E, 0xFF, 0xFF, 0xFF },
{ 0x2E, 0x2D, 0x2F, 0xFF, 0xFF, 0xFF },
{ 0x2F, 0x2E, 0x30, 0xFF, 0xFF, 0xFF },
{ 0x30, 0x2F, 0x31, 0xFF, 0xFF, 0xFF },
{ 0x31, 0x30, 0x19, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
};
void ClearRoamerData(void)
{
memset(&gSaveBlock1Ptr->roamer, 0, sizeof(struct Roamer));
(&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIAS;
}
void ClearRoamerLocationData(void)
{
u8 i;
for (i = 0; i < 3; i++)
{
sLocationHistory[i][MAP_GRP] = 0;
sLocationHistory[i][MAP_NUM] = 0;
}
sRoamerLocation[MAP_GRP] = 0;
sRoamerLocation[MAP_NUM] = 0;
}
static void CreateInitialRoamerMon(bool16 createLatios)
{
if (!createLatios)
(&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIAS;
else
(&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIOS;
CreateMon(&gEnemyParty[0], (&gSaveBlock1Ptr->roamer)->species, 40, 0x20, 0, 0, 0, 0);
(&gSaveBlock1Ptr->roamer)->level = 40;
(&gSaveBlock1Ptr->roamer)->status = 0;
(&gSaveBlock1Ptr->roamer)->active = TRUE;
(&gSaveBlock1Ptr->roamer)->ivs = GetMonData(&gEnemyParty[0], MON_DATA_IVS);
(&gSaveBlock1Ptr->roamer)->personality = GetMonData(&gEnemyParty[0], MON_DATA_PERSONALITY);
(&gSaveBlock1Ptr->roamer)->hp = GetMonData(&gEnemyParty[0], MON_DATA_MAX_HP);
(&gSaveBlock1Ptr->roamer)->cool = GetMonData(&gEnemyParty[0], MON_DATA_COOL);
(&gSaveBlock1Ptr->roamer)->beauty = GetMonData(&gEnemyParty[0], MON_DATA_BEAUTY);
(&gSaveBlock1Ptr->roamer)->cute = GetMonData(&gEnemyParty[0], MON_DATA_CUTE);
(&gSaveBlock1Ptr->roamer)->smart = GetMonData(&gEnemyParty[0], MON_DATA_SMART);
(&gSaveBlock1Ptr->roamer)->tough = GetMonData(&gEnemyParty[0], MON_DATA_TOUGH);
sRoamerLocation[MAP_GRP] = 0;
sRoamerLocation[MAP_NUM] = sRoamerLocations[Random() % 20][0];
}
void InitRoamer(void)
{
ClearRoamerData();
ClearRoamerLocationData();
CreateInitialRoamerMon(gSpecialVar_0x8004);
}
void UpdateLocationHistoryForRoamer(void)
{
sLocationHistory[2][MAP_GRP] = sLocationHistory[1][MAP_GRP];
sLocationHistory[2][MAP_NUM] = sLocationHistory[1][MAP_NUM];
sLocationHistory[1][MAP_GRP] = sLocationHistory[0][MAP_GRP];
sLocationHistory[1][MAP_NUM] = sLocationHistory[0][MAP_NUM];
sLocationHistory[0][MAP_GRP] = gSaveBlock1Ptr->location.mapGroup;
sLocationHistory[0][MAP_NUM] = gSaveBlock1Ptr->location.mapNum;
}
void RoamerMoveToOtherLocationSet(void)
{
u8 val = 0;
struct Roamer *roamer = &gSaveBlock1Ptr->roamer;
if (!roamer->active)
return;
sRoamerLocation[MAP_GRP] = val;
while (1)
{
val = sRoamerLocations[Random() % 20][0];
if (sRoamerLocation[MAP_NUM] != val)
{
sRoamerLocation[MAP_NUM] = val;
return;
}
}
}
void RoamerMove(void)
{
u8 locSet = 0;
if ((Random() % 16) == 0)
{
RoamerMoveToOtherLocationSet();
}
else
{
struct Roamer *roamer = &gSaveBlock1Ptr->roamer;
if (!roamer->active)
return;
while (locSet < 20)
{
if (sRoamerLocation[MAP_NUM] == sRoamerLocations[locSet][0])
{
u8 mapNum;
while (1)
{
mapNum = sRoamerLocations[locSet][(Random() % 5) + 1];
if (!(sLocationHistory[2][MAP_GRP] == 0 && sLocationHistory[2][MAP_NUM] == mapNum) && mapNum != 0xFF)
break;
}
sRoamerLocation[MAP_NUM] = mapNum;
return;
}
locSet++;
}
}
}
bool8 IsRoamerAt(u8 mapGroup, u8 mapNum)
{
struct Roamer *roamer = &gSaveBlock1Ptr->roamer;
if (roamer->active && mapGroup == sRoamerLocation[MAP_GRP] && mapNum == sRoamerLocation[MAP_NUM])
return TRUE;
else
return FALSE;
}
void CreateRoamerMonInstance(void)
{
struct Pokemon *mon;
struct Roamer *roamer;
mon = &gEnemyParty[0];
ZeroEnemyPartyMons();
roamer = &gSaveBlock1Ptr->roamer;
CreateMonWithIVsPersonality(mon, roamer->species, roamer->level, roamer->ivs, roamer->personality);
SetMonData(mon, MON_DATA_STATUS, &gSaveBlock1Ptr->roamer.status);
SetMonData(mon, MON_DATA_HP, &gSaveBlock1Ptr->roamer.hp);
SetMonData(mon, MON_DATA_COOL, &gSaveBlock1Ptr->roamer.cool);
SetMonData(mon, MON_DATA_BEAUTY, &gSaveBlock1Ptr->roamer.beauty);
SetMonData(mon, MON_DATA_CUTE, &gSaveBlock1Ptr->roamer.cute);
SetMonData(mon, MON_DATA_SMART, &gSaveBlock1Ptr->roamer.smart);
SetMonData(mon, MON_DATA_TOUGH, &gSaveBlock1Ptr->roamer.tough);
}
bool8 TryStartRoamerEncounter(void)
{
if (IsRoamerAt(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum) == TRUE && (Random() % 4) == 0)
{
CreateRoamerMonInstance();
return TRUE;
}
else
{
return FALSE;
}
}
void UpdateRoamerHPStatus(struct Pokemon *mon)
{
(&gSaveBlock1Ptr->roamer)->hp = GetMonData(mon, MON_DATA_HP);
(&gSaveBlock1Ptr->roamer)->status = GetMonData(mon, MON_DATA_STATUS);
RoamerMoveToOtherLocationSet();
}
void SetRoamerInactive(void)
{
struct Roamer *roamer = &gSaveBlock1Ptr->roamer;
roamer->active = FALSE;
}
void GetRoamerLocation(u8 *mapGroup, u8 *mapNum)
{
*mapGroup = sRoamerLocation[MAP_GRP];
*mapNum = sRoamerLocation[MAP_NUM];
}

19
src/rom4.c Normal file
View File

@@ -0,0 +1,19 @@
// Includes
#include "global.h"
// Static type declarations
// Static RAM declarations
IWRAM_DATA void *gUnknown_03000E0C;
IWRAM_DATA u8 gUnknown_03000E10[4];
IWRAM_DATA u8 (*gUnknown_03000E14)(u32);
IWRAM_DATA u8 gUnknown_03000E18;
IWRAM_DATA u8 gUnknown_03000E19;
IWRAM_DATA void *rom4_c_unused_03000e1c;
// Static ROM declarations
// .rodata
// .text

View File

@@ -18,7 +18,7 @@ struct PokeblockFeeder
#define NUM_POKEBLOCK_FEEDERS 10
extern u8 gBattleOutcome;
extern void* gUnknown_03005DAC;
extern void* gFieldCallback;
extern u8 gUnknown_082A4B8A[];
extern u8 gUnknown_082A4B6F[];
@@ -118,7 +118,7 @@ void sub_80FC190(void)
{
ScriptContext2_RunNewScript(gUnknown_082A4B4C);
warp_in();
gUnknown_03005DAC = sub_80AF6F0;
gFieldCallback = sub_80AF6F0;
SetMainCallback2(c2_load_new_map);
}
else if (gBattleOutcome == BATTLE_CAUGHT)

View File

@@ -2,12 +2,15 @@
#include "gba/flash_internal.h"
#include "save.h"
#include "game_stat.h"
#include "task.h"
extern struct SaveSectionOffsets gSaveSectionOffsets[0xE];
extern struct SaveSectionLocation gRamSaveSectionLocations[0xE];
extern u8 gDecompressionBuffer[];
extern u32 gFlashMemoryPresent;
extern u16 gUnknown_03006294;
extern bool8 gSoftResetDisabled;
extern const struct SaveSectionOffsets gSaveSectionOffsets[0xE];
extern void DoSaveFailedScreen(u8); // save_failed_screen
extern void LoadSerializedGame(void); // load_save
@@ -576,84 +579,27 @@ u16 CalculateChecksum(void *data, u16 size)
return ((checksum >> 16) + checksum);
}
#ifdef NONMATCHING
// the initial allocation of the pointer and toAdd variable doesnt match up with the original function. however, forcing it is impossible since gRamSaveSectionLocations is loaded first.
void UpdateSaveAddresses(void)
{
int i = 0;
gRamSaveSectionLocations[i].data = gSaveBlock2Ptr + gSaveSectionOffsets[0].toAdd;
gRamSaveSectionLocations[i].size = gSaveSectionOffsets[0].size;
for(i = 1; i < 5; i++)
gRamSaveSectionLocations[i].data = (void*)(gSaveBlock2Ptr) + gSaveSectionOffsets[i].toAdd;
gRamSaveSectionLocations[i].size = gSaveSectionOffsets[i].size;
for (i = 1; i < 5; i++)
{
gRamSaveSectionLocations[i].data = gSaveBlock1Ptr + gSaveSectionOffsets[i].toAdd;
gRamSaveSectionLocations[i].data = (void*)(gSaveBlock1Ptr) + gSaveSectionOffsets[i].toAdd;
gRamSaveSectionLocations[i].size = gSaveSectionOffsets[i].size;
}
for(i = 5; i < 14; i++)
for (i = 5; i < 14; i++)
{
gRamSaveSectionLocations[i].data = gPokemonStoragePtr + gSaveSectionOffsets[i].toAdd;
gRamSaveSectionLocations[i].data = (void*)(gPokemonStoragePtr) + gSaveSectionOffsets[i].toAdd;
gRamSaveSectionLocations[i].size = gSaveSectionOffsets[i].size;
i++;i--; // needed to match
}
}
#else
__attribute__((naked))
void UpdateSaveAddresses(void)
{
asm(".syntax unified\n\
push {r4,r5,lr}\n\
ldr r3, =gRamSaveSectionLocations\n\
ldr r0, =gSaveBlock2Ptr\n\
ldr r2, =gSaveSectionOffsets\n\
ldrh r1, [r2]\n\
ldr r0, [r0]\n\
adds r0, r1\n\
str r0, [r3]\n\
ldrh r0, [r2, 0x2]\n\
strh r0, [r3, 0x4]\n\
ldr r5, =gSaveBlock1Ptr\n\
adds r3, 0x8\n\
adds r2, 0x4\n\
movs r4, 0x3\n\
_081531AC:\n\
ldrh r0, [r2]\n\
ldr r1, [r5]\n\
adds r1, r0\n\
str r1, [r3]\n\
ldrh r0, [r2, 0x2]\n\
strh r0, [r3, 0x4]\n\
adds r3, 0x8\n\
adds r2, 0x4\n\
subs r4, 0x1\n\
cmp r4, 0\n\
bge _081531AC\n\
movs r4, 0x5\n\
ldr r1, =gRamSaveSectionLocations\n\
ldr r5, =gPokemonStoragePtr\n\
ldr r0, =gSaveSectionOffsets\n\
adds r3, r1, 0\n\
adds r3, 0x28\n\
adds r2, r0, 0\n\
adds r2, 0x14\n\
_081531D2:\n\
ldrh r0, [r2]\n\
ldr r1, [r5]\n\
adds r1, r0\n\
str r1, [r3]\n\
ldrh r0, [r2, 0x2]\n\
strh r0, [r3, 0x4]\n\
adds r3, 0x8\n\
adds r2, 0x4\n\
adds r4, 0x1\n\
cmp r4, 0xD\n\
ble _081531D2\n\
pop {r4,r5}\n\
pop {r0}\n\
bx r0\n\
.pool\n\
.syntax divided");
}
#endif
extern u32 GetGameStat(u8 index); // rom4
extern void IncrementGameStat(u8 index); // rom4
@@ -894,3 +840,85 @@ u32 sub_8153634(u8 sector, u8* src)
return 0xFF;
return 1;
}
extern void save_serialize_map(void);
extern void sub_8076D5C(void);
extern void sav2_gender2_inplace_and_xFE(void);
extern void sub_800ADF8(void);
extern bool8 sub_800A520(void);
void sub_8153688(u8 taskId)
{
s16* taskData = gTasks[taskId].data;
switch (taskData[0])
{
case 0:
gSoftResetDisabled = TRUE;
taskData[0] = 1;
break;
case 1:
sub_800ADF8();
taskData[0] = 2;
break;
case 2:
if (sub_800A520())
{
if (taskData[2] == 0)
save_serialize_map();
taskData[0] = 3;
}
break;
case 3:
if (taskData[2] == 0)
sub_8076D5C();
sub_8153380();
taskData[0] = 4;
break;
case 4:
if (++taskData[1] == 5)
{
taskData[1] = 0;
taskData[0] = 5;
}
break;
case 5:
if (sub_81533AC())
taskData[0] = 6;
else
taskData[0] = 4;
break;
case 6:
sub_81533E0();
taskData[0] = 7;
break;
case 7:
if (taskData[2] == 0)
sav2_gender2_inplace_and_xFE();
sub_800ADF8();
taskData[0] = 8;
break;
case 8:
if (sub_800A520())
{
sub_8153408();
taskData[0] = 9;
}
break;
case 9:
sub_800ADF8();
taskData[0] = 10;
break;
case 10:
if (sub_800A520())
taskData[0]++;
break;
case 11:
if (++taskData[1] > 5)
{
gSoftResetDisabled = FALSE;
DestroyTask(taskId);
}
break;
}
}

15
src/scrcmd.c Normal file
View File

@@ -0,0 +1,15 @@
// Includes
#include "global.h"
// Static type declarations
// Static RAM declarations
IWRAM_DATA u8 gUnknown_03000F30;
// Static ROM declarations
// .rodata
// .text

16
src/script_menu.c Normal file
View File

@@ -0,0 +1,16 @@
// Includes
#include "global.h"
// Static type declarations
// Static RAM declarations
IWRAM_DATA u8 gUnknown_03001124[6];
IWRAM_DATA u32 filler_0300112c;
// Static ROM declarations
// .rodata
// .text

View File

@@ -151,7 +151,7 @@ static void BuildStartMenuActions_MultiBattleRoom(void)
extern const struct WindowTemplate gSafariBallsWindowTemplate;
extern const struct WindowTemplate gPyramidFloorWindowTemplate_1;
extern const struct WindowTemplate gPyramidFloorWindowTemplate_2;
extern const u8 gOtherText_SafariStock[];
extern const u8 gText_SafariBallStock[];
void DisplaySafariBallsWindow(void)
{
@@ -159,13 +159,13 @@ void DisplaySafariBallsWindow(void)
PutWindowTilemap(sSafariBallsWindowId);
sub_81973FC(sSafariBallsWindowId, 0);
ConvertIntToDecimalStringN(gStringVar1, gNumSafariBalls, STR_CONV_MODE_RIGHT_ALIGN, 2);
StringExpandPlaceholders(gStringVar4, gOtherText_SafariStock);
StringExpandPlaceholders(gStringVar4, gText_SafariBallStock);
PrintTextOnWindow(sSafariBallsWindowId, 1, gStringVar4, 0, 1, 0xFF, NULL);
CopyWindowToVram(sSafariBallsWindowId, 2);
}
extern const u8* const gUnknown_08510510[];
extern const u8 gOtherText_BattlePyramid_X[];
extern const u8 gText_BattlePyramidFloor[];
void DisplayPyramidFloorWindow(void)
{
@@ -177,7 +177,7 @@ void DisplayPyramidFloorWindow(void)
PutWindowTilemap(sBattlePyramidFloorWindowId);
sub_81973FC(sBattlePyramidFloorWindowId, 0);
StringCopy(gStringVar1, gUnknown_08510510[*(u16*)(&gSaveBlock2Ptr->field_CAA[8])]);
StringExpandPlaceholders(gStringVar4, gOtherText_BattlePyramid_X);
StringExpandPlaceholders(gStringVar4, gText_BattlePyramidFloor);
PrintTextOnWindow(sBattlePyramidFloorWindowId, 1, gStringVar4, 0, 1, 0xFF, NULL);
CopyWindowToVram(sBattlePyramidFloorWindowId, 2);
}

View File

@@ -1,9 +1,9 @@
#include "global.h"
#include "text.h"
#include "main.h"
#include "palette.h"
#include "string_util.h"
#include "window.h"
#include "text.h"
extern void FillBitmapRect4Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue);
extern void FillWindowPixelRect(u8 windowId, u8 fillValue, u16 x, u16 y, u16 width, u16 height);
@@ -32,11 +32,7 @@ u8 gUnknown_03002FB0[0x20];
u8 gUnknown_03002FD0[0x20];
u8 gUnknown_03002FF0[0x20];
u8 gGlyphDimensions[0x2];
struct {
u8 flag_0:1;
u8 flag_1:1;
u8 flag_2:1;
} gTextFlags;
TextFlags gTextFlags;
const u8 gFontHalfRowOffsets[] = {
0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00,
@@ -244,12 +240,11 @@ void RunTextPrinters(void)
}
}
bool8 IsTextPrinterActive(u8 id)
bool16 IsTextPrinterActive(u8 id)
{
return gTextPrinters[id].sub_union.sub.active;
}
u32 RenderFont(struct TextPrinter *textPrinter)
{
u32 ret;
@@ -1973,7 +1968,7 @@ bool8 TextPrinterWaitAutoMode(struct TextPrinter *textPrinter)
}
}
bool8 TextPrinterWaitWithDownArrow(struct TextPrinter *textPrinter)
bool16 TextPrinterWaitWithDownArrow(struct TextPrinter *textPrinter)
{
bool8 result = FALSE;
if (gTextFlags.flag_2 != 0)
@@ -1992,9 +1987,9 @@ bool8 TextPrinterWaitWithDownArrow(struct TextPrinter *textPrinter)
return result;
}
bool8 TextPrinterWait(struct TextPrinter *textPrinter)
bool16 TextPrinterWait(struct TextPrinter *textPrinter)
{
bool8 result = FALSE;
bool16 result = FALSE;
if (gTextFlags.flag_2 != 0)
{
result = TextPrinterWaitAutoMode(textPrinter);
@@ -2779,7 +2774,7 @@ _08005D6E:\n\
bx r1");
}
u32 GetStringWidthFixedWidthFont(u8 *str, u8 fontId, u8 letterSpacing)
u32 GetStringWidthFixedWidthFont(const u8 *str, u8 fontId, u8 letterSpacing)
{
int i;
u8 width;
@@ -2788,7 +2783,7 @@ u32 GetStringWidthFixedWidthFont(u8 *str, u8 fontId, u8 letterSpacing)
u8 line;
int strPos;
u8 lineWidths[8];
u8 *strLocal;
const u8 *strLocal;
for (i = 0; i < 8; i++)
{
@@ -2883,7 +2878,7 @@ u32 (*GetFontWidthFunc(u8 glyphId))(u16, bool32)
return 0;
}
s32 GetStringWidth(u8 fontId, u8 *str, s16 letterSpacing)
u32 GetStringWidth(u8 fontId, const u8 *str, s16 letterSpacing)
{
bool8 isJapanese;
int minGlyphWidth;

1411
src/tileset_anims.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,6 @@
#include "global.h"
#include "trig.h"
// Converts a number to Q8.8 fixed-point format
#define Q_8_8(n) ((s16)((n) * 256))
// Converts a number to Q4.12 fixed-point format
#define Q_4_12(n) ((s16)((n) * 4096))
// Values of sin(x*(π/128)) as Q8.8 fixed-point numbers from x = 0 to x = 319
const s16 gSineTable[] =
{

219
src/unk_text_util_2.c Normal file
View File

@@ -0,0 +1,219 @@
#include "global.h"
#include "main.h"
#include "window.h"
#include "text.h"
#include "sound.h"
static const u8 gUnknown_08616124[] = {1, 2, 4};
static const u16 gFont6BrailleGlyphs[] = INCBIN_U16("data/graphics/fonts/font6.fwjpnfont");
static void DecompressGlyphFont6(u16);
u16 Font6Func(struct TextPrinter *textPrinter)
{
u16 char_;
struct TextPrinterSubStruct *sub;
sub = &textPrinter->sub_union.sub;
switch (textPrinter->state)
{
case 0:
if (gMain.heldKeys & (A_BUTTON | B_BUTTON) && sub->font_type_upper)
{
textPrinter->delayCounter = 0;
}
if (textPrinter->delayCounter && textPrinter->text_speed)
{
textPrinter->delayCounter --;
if (gTextFlags.flag_0 && gMain.newKeys & (A_BUTTON | B_BUTTON))
{
sub->font_type_upper = TRUE;
textPrinter->delayCounter = 0;
}
return 3;
}
if (gTextFlags.flag_2)
{
textPrinter->delayCounter = 3;
}
else
{
textPrinter->delayCounter = textPrinter->text_speed;
}
char_ = *textPrinter->subPrinter.current_text_offset ++;
switch (char_)
{
case EOS:
return 1;
case CHAR_NEWLINE:
textPrinter->subPrinter.currentX = textPrinter->subPrinter.x;
textPrinter->subPrinter.currentY += gFonts[textPrinter->subPrinter.fontId].maxLetterHeight + textPrinter->subPrinter.lineSpacing;
return 2;
case PLACEHOLDER_BEGIN:
textPrinter->subPrinter.current_text_offset ++;
return 2;
case EXT_CTRL_CODE_BEGIN:
char_ = *textPrinter->subPrinter.current_text_offset ++;
switch (char_)
{
case 1:
textPrinter->subPrinter.fontColor_h = *textPrinter->subPrinter.current_text_offset ++;
GenerateFontHalfRowLookupTable(textPrinter->subPrinter.fontColor_h, textPrinter->subPrinter.bgColor, textPrinter->subPrinter.shadowColor);
return 2;
case 2:
textPrinter->subPrinter.bgColor = *textPrinter->subPrinter.current_text_offset ++;
GenerateFontHalfRowLookupTable(textPrinter->subPrinter.fontColor_h, textPrinter->subPrinter.bgColor, textPrinter->subPrinter.shadowColor);
return 2;
case 3:
textPrinter->subPrinter.shadowColor = *textPrinter->subPrinter.current_text_offset ++;
GenerateFontHalfRowLookupTable(textPrinter->subPrinter.fontColor_h, textPrinter->subPrinter.bgColor, textPrinter->subPrinter.shadowColor);
return 2;
case 4:
textPrinter->subPrinter.fontColor_h = *textPrinter->subPrinter.current_text_offset;
textPrinter->subPrinter.bgColor = *++ textPrinter->subPrinter.current_text_offset;
textPrinter->subPrinter.shadowColor = *++ textPrinter->subPrinter.current_text_offset;
textPrinter->subPrinter.current_text_offset ++;
GenerateFontHalfRowLookupTable(textPrinter->subPrinter.fontColor_h, textPrinter->subPrinter.bgColor, textPrinter->subPrinter.shadowColor);
return 2;
case 5:
textPrinter->subPrinter.current_text_offset ++;
return 2;
case 6:
sub->font_type = *textPrinter->subPrinter.current_text_offset;
textPrinter->subPrinter.current_text_offset ++;
return 2;
case 7:
return 2;
case 8:
textPrinter->delayCounter = *textPrinter->subPrinter.current_text_offset ++;
textPrinter->state = 6;
return 2;
case 9:
textPrinter->state = 1;
if (gTextFlags.flag_2)
{
sub->frames_visible_counter = 0;
}
return 3;
case 10:
textPrinter->state = 5;
return 3;
case 11:
case 16:
textPrinter->subPrinter.current_text_offset += 2;
return 2;
case 12:
char_ = *++textPrinter->subPrinter.current_text_offset;
break;
case 13:
textPrinter->subPrinter.currentX = textPrinter->subPrinter.x + *textPrinter->subPrinter.current_text_offset ++;
return 2;
case 14:
textPrinter->subPrinter.currentY = textPrinter->subPrinter.y + *textPrinter->subPrinter.current_text_offset ++;
return 2;
case 15:
FillWindowPixelBuffer(textPrinter->subPrinter.windowId, textPrinter->subPrinter.bgColor | (textPrinter->subPrinter.bgColor << 4));
return 2;
}
break;
case CHAR_PROMPT_CLEAR:
textPrinter->state = 2;
TextPrinterInitDownArrowCounters(textPrinter);
return 3;
case CHAR_PROMPT_SCROLL:
textPrinter->state = 3;
TextPrinterInitDownArrowCounters(textPrinter);
return 3;
case 0xF9:
char_ = *textPrinter->subPrinter.current_text_offset ++ | 0x100;
break;
case 0xF8:
textPrinter->subPrinter.current_text_offset ++;
return 0;
}
DecompressGlyphFont6(char_);
CopyGlyphToWindow(textPrinter);
textPrinter->subPrinter.currentX += gUnknown_03002F90[0x80] + textPrinter->subPrinter.letterSpacing;
return 0;
case 1:
if (TextPrinterWait(textPrinter))
{
textPrinter->state = 0;
}
return 3;
case 2:
if (TextPrinterWaitWithDownArrow(textPrinter))
{
FillWindowPixelBuffer(textPrinter->subPrinter.windowId, textPrinter->subPrinter.bgColor | (textPrinter->subPrinter.bgColor << 4));
textPrinter->subPrinter.currentX = textPrinter->subPrinter.x;
textPrinter->subPrinter.currentY = textPrinter->subPrinter.y;
textPrinter->state = 0;
}
return 3;
case 3:
if (TextPrinterWaitWithDownArrow(textPrinter))
{
TextPrinterClearDownArrow(textPrinter);
textPrinter->scrollDistance = gFonts[textPrinter->subPrinter.fontId].maxLetterHeight + textPrinter->subPrinter.lineSpacing;
textPrinter->subPrinter.currentX = textPrinter->subPrinter.x;
textPrinter->state = 4;
}
return 3;
case 4:
if (textPrinter->scrollDistance)
{
if (textPrinter->scrollDistance < gUnknown_08616124[gSaveBlock2Ptr->optionsTextSpeed])
{
ScrollWindow(textPrinter->subPrinter.windowId, 0, textPrinter->scrollDistance, textPrinter->subPrinter.bgColor | (textPrinter->subPrinter.bgColor << 4));
textPrinter->scrollDistance = 0;
}
else
{
ScrollWindow(textPrinter->subPrinter.windowId, 0, gUnknown_08616124[gSaveBlock2Ptr->optionsTextSpeed], textPrinter->subPrinter.bgColor | (textPrinter->subPrinter.bgColor << 4));
textPrinter->scrollDistance -= gUnknown_08616124[gSaveBlock2Ptr->optionsTextSpeed];
}
CopyWindowToVram(textPrinter->subPrinter.windowId, 2);
}
else
{
textPrinter->state = 0;
}
return 3;
case 5:
if (!IsSEPlaying())
{
textPrinter->state = 0;
}
return 3;
case 6:
if (textPrinter->delayCounter)
{
textPrinter->delayCounter --;
}
else
{
textPrinter->state = 0;
}
return 3;
}
return 1;
}
static void DecompressGlyphFont6(u16 glyph)
{
const u16 *glyphs;
glyphs = gFont6BrailleGlyphs + 0x100 * (glyph / 8) + 0x10 * (glyph % 8);
DecompressGlyphTile(glyphs, (u16 *)gUnknown_03002F90);
DecompressGlyphTile(glyphs + 0x8, (u16 *)(gUnknown_03002F90 + 0x20));
DecompressGlyphTile(glyphs + 0x80, (u16 *)(gUnknown_03002F90 + 0x40));
DecompressGlyphTile(glyphs + 0x88, (u16 *)(gUnknown_03002F90 + 0x60));
gUnknown_03002F90[0x80] = 0x10;
gUnknown_03002F90[0x81] = 0x10;
}
u8 GetGlyphWidthFont6(void)
{
return 0x10;
}

View File

@@ -35,7 +35,7 @@ static void nullsub_8(void)
}
bool16 InitWindows(struct WindowTemplate *templates)
bool16 InitWindows(const struct WindowTemplate *templates)
{
int i;
void *bgTilemapBuffer;
@@ -451,7 +451,7 @@ void FillWindowPixelRect(u8 windowId, u8 fillValue, u16 x, u16 y, u16 width, u16
FillBitmapRect4Bit(&pixelRect, x, y, width, height, fillValue);
}
void CopyToWindowPixelBuffer(u8 windowId, u8 *src, u16 size, u16 tileOffset)
void CopyToWindowPixelBuffer(u8 windowId, const u8 *src, u16 size, u16 tileOffset)
{
if (size != 0)
CpuCopy16(src, gWindows[windowId].tileData + (0x20 * tileOffset), size);