Merge remote-tracking branch 'pret/master' into baserom_extraction

This commit is contained in:
Diegoisawesome
2017-10-09 13:32:26 -05:00
408 changed files with 11246 additions and 23108 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

5653
src/battle_2.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -73,7 +73,7 @@ extern const struct BaseStats gBaseStats[];
extern const u32 gBitTable[];
extern u8 * const gBattleAI_ScriptsTable[];
extern u8 b_first_side(u8, u8, u8);
extern u8 GetWhoStrikesFirst(u8, u8, u8);
extern void AI_CalcDmg(u8, u8);
extern u8 CheckMoveLimitations();
@@ -1756,7 +1756,7 @@ static void BattleAICmd_if_arg_not_equal(void)
static void BattleAICmd_if_would_go_first(void)
{
if (b_first_side(sBank_AI, gBankTarget, 1) == gAIScriptPtr[1])
if (GetWhoStrikesFirst(sBank_AI, gBankTarget, 1) == gAIScriptPtr[1])
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
@@ -1764,7 +1764,7 @@ static void BattleAICmd_if_would_go_first(void)
static void BattleAICmd_if_would_not_go_first(void)
{
if (b_first_side(sBank_AI, gBankTarget, 1) != gAIScriptPtr[1])
if (GetWhoStrikesFirst(sBank_AI, gBankTarget, 1) != gAIScriptPtr[1])
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;

View File

@@ -47,8 +47,8 @@ extern u8 gActiveBank;
extern u32 gBattleExecBuffer;
extern u8 gNoOfAllBanks;
extern u16 gBattlePartyID[BATTLE_BANKS_COUNT];
extern u8 gTurnOrder[BATTLE_BANKS_COUNT];
extern u8 gUnknown_0202407A[BATTLE_BANKS_COUNT];
extern u8 gBanksByTurnOrder[BATTLE_BANKS_COUNT];
extern u8 gActionsByTurnOrder[BATTLE_BANKS_COUNT];
extern u16 gCurrentMove;
extern u8 gLastUsedAbility;
extern u16 gBattleWeather;
@@ -67,7 +67,7 @@ extern u8 gBankAttacker;
extern u8 gBankTarget;
extern const u8* gBattlescriptCurrInstr;
extern u8 gCurrMovePos;
extern u8 gFightStateTracker;
extern u8 gCurrentActionFuncId;
extern u32 gHitMarker;
extern u8 gBattleMoveFlags;
extern u8 gBattleCommunication[];
@@ -92,7 +92,7 @@ extern u16 gMoveToLearn;
extern u16 gRandomMove;
extern u8 gBankInMenu;
extern u8 gActionForBanks[BATTLE_BANKS_COUNT];
extern u8 gCurrentMoveTurn;
extern u8 gCurrentTurnActionNumber;
extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200];
extern u16 gLockedMoves[BATTLE_BANKS_COUNT];
extern u16 gPartnerTrainerId;
@@ -145,8 +145,7 @@ extern u16 GetBattlePyramidPickupItemId(void);
extern u8 sav1_map_get_light_level(void);
extern u8 sub_813B21C(void);
extern u16 get_unknown_box_id(void);
extern void c2_berry_program_update_menu(void);
extern void sub_8035AA4(void);
extern void sub_80356D0(void);
// BattleScripts
extern const u8 BattleScript_MoveEnd[];
@@ -332,7 +331,7 @@ static void atk40_jump_if_move_affected_by_protect(void);
static void atk41_call(void);
static void atk42_jumpiftype2(void);
static void atk43_jumpifabilitypresent(void);
static void atk44(void);
static void atk44_end_selection_script(void);
static void atk45_playanimation(void);
static void atk46_playanimation2(void);
static void atk47_setgraphicalstatchangevalues(void);
@@ -361,7 +360,7 @@ static void atk5D_getmoneyreward(void);
static void atk5E_8025A70(void);
static void atk5F_8025B24(void);
static void atk60_increment_gamestat(void);
static void atk61_8025BA4(void);
static void atk61_draw_party_status_summary(void);
static void atk62_08025C6C(void);
static void atk63_jumptorandomattack(void);
static void atk64_statusanimation(void);
@@ -378,7 +377,7 @@ static void atk6E_set_atk_to_player0(void);
static void atk6F_set_visible(void);
static void atk70_record_last_used_ability(void);
static void atk71_buffer_move_to_learn(void);
static void atk72_jump_if_can_run_frombattle(void);
static void atk72_jump_if_run_attempt_success(void);
static void atk73_hp_thresholds(void);
static void atk74_hp_thresholds2(void);
static void atk75_item_effect_on_opponent(void);
@@ -510,8 +509,8 @@ static void atkF2_display_dex_info(void);
static void atkF3_nickname_caught_poke(void);
static void atkF4_subattackerhpbydmg(void);
static void atkF5_removeattackerstatus1(void);
static void atkF6_802BF48(void);
static void atkF7_802BF54(void);
static void atkF6_action_finished(void);
static void atkF7_turn_finished(void);
static void atkF8_trainer_slide_back(void);
void (* const gBattleScriptingCommandsTable[])(void) =
@@ -584,7 +583,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
atk41_call,
atk42_jumpiftype2,
atk43_jumpifabilitypresent,
atk44,
atk44_end_selection_script,
atk45_playanimation,
atk46_playanimation2,
atk47_setgraphicalstatchangevalues,
@@ -613,7 +612,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
atk5E_8025A70,
atk5F_8025B24,
atk60_increment_gamestat,
atk61_8025BA4,
atk61_draw_party_status_summary,
atk62_08025C6C,
atk63_jumptorandomattack,
atk64_statusanimation,
@@ -630,7 +629,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
atk6F_set_visible,
atk70_record_last_used_ability,
atk71_buffer_move_to_learn,
atk72_jump_if_can_run_frombattle,
atk72_jump_if_run_attempt_success,
atk73_hp_thresholds,
atk74_hp_thresholds2,
atk75_item_effect_on_opponent,
@@ -762,8 +761,8 @@ void (* const gBattleScriptingCommandsTable[])(void) =
atkF3_nickname_caught_poke,
atkF4_subattackerhpbydmg,
atkF5_removeattackerstatus1,
atkF6_802BF48,
atkF7_802BF54,
atkF6_action_finished,
atkF7_turn_finished,
atkF8_trainer_slide_back
};
@@ -1098,9 +1097,9 @@ static void atk00_attackcanceler(void)
{
s32 i;
if (gBattleOutcome)
if (gBattleOutcome != 0)
{
gFightStateTracker = 0xC;
gCurrentActionFuncId = ACTION_FINISHED;
return;
}
if (gBattleMons[gBankAttacker].hp == 0 && !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
@@ -1152,11 +1151,11 @@ static void atk00_attackcanceler(void)
for (i = 0; i < gNoOfAllBanks; i++)
{
if ((gProtectStructs[gTurnOrder[i]].stealMove) && gBattleMoves[gCurrentMove].flags & FLAG_SNATCH_AFFECTED)
if ((gProtectStructs[gBanksByTurnOrder[i]].stealMove) && gBattleMoves[gCurrentMove].flags & FLAG_SNATCH_AFFECTED)
{
PressurePPLose(gBankAttacker, gTurnOrder[i], MOVE_SNATCH);
gProtectStructs[gTurnOrder[i]].stealMove = 0;
gBattleScripting.bank = gTurnOrder[i];
PressurePPLose(gBankAttacker, gBanksByTurnOrder[i], MOVE_SNATCH);
gProtectStructs[gBanksByTurnOrder[i]].stealMove = 0;
gBattleScripting.bank = gBanksByTurnOrder[i];
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SnatchedMove;
return;
@@ -1601,7 +1600,7 @@ static void atk06_typecalc(void)
RecordAbilityBattle(gBankTarget, gLastUsedAbility);
}
if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED)
gProtectStructs[gBankAttacker].notEffective = 1;
gProtectStructs[gBankAttacker].targetNotAffected = 1;
gBattlescriptCurrInstr++;
}
@@ -1640,14 +1639,14 @@ static void CheckWonderGuardAndLevitate(void)
if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 0)
{
gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED;
gProtectStructs[gBankAttacker].notEffective = 1;
gProtectStructs[gBankAttacker].targetNotAffected = 1;
}
if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 &&
gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 &&
gTypeEffectiveness[i + 2] == TYPE_MUL_NO_EFFECT)
{
gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED;
gProtectStructs[gBankAttacker].notEffective = 1;
gProtectStructs[gBankAttacker].targetNotAffected = 1;
}
// check super effective
@@ -2379,7 +2378,7 @@ u8 BankGetTurnOrder(u8 bank)
s32 i;
for (i = 0; i < gNoOfAllBanks; i++)
{
if (gTurnOrder[i] == bank)
if (gBanksByTurnOrder[i] == bank)
break;
}
return i;
@@ -2737,7 +2736,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
}
else
{
if (BankGetTurnOrder(gEffectBank) > gCurrentMoveTurn)
if (BankGetTurnOrder(gEffectBank) > gCurrentTurnActionNumber)
gBattleMons[gEffectBank].status2 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]];
gBattlescriptCurrInstr++;
}
@@ -3209,7 +3208,7 @@ static void atk19_faint_pokemon(void)
&& gBattleMons[gBankAttacker].hp != 0
&& gCurrentMove != MOVE_STRUGGLE)
{
u8 moveIndex = *(gBattleStruct->chosenMovesIds + gBankAttacker);
u8 moveIndex = *(gBattleStruct->chosenMovePositions + gBankAttacker);
gBattleMons[gBankAttacker].pp[moveIndex] = 0;
BattleScriptPush(gBattlescriptCurrInstr);
@@ -3252,7 +3251,7 @@ static void atk1B_faint_effects_clear(void)
MarkBufferBankForExecution(gActiveBank);
}
UndoEffectsAfterFainting(); // Effects like attractions, trapping, etc.
FaintClearSetData(); // Effects like attractions, trapping, etc.
gBattlescriptCurrInstr += 2;
}
}
@@ -4422,13 +4421,13 @@ static void atk3D_end(void)
gBattleMoveFlags = 0;
gActiveBank = 0;
gFightStateTracker = 0xB;
gCurrentActionFuncId = 0xB;
}
static void atk3E_end2(void)
{
gActiveBank = 0;
gFightStateTracker = 0xB;
gCurrentActionFuncId = 0xB;
}
static void atk3F_end3(void) // pops the main function stack
@@ -4463,9 +4462,9 @@ static void atk43_jumpifabilitypresent(void)
gBattlescriptCurrInstr += 6;
}
static void atk44(void)
static void atk44_end_selection_script(void)
{
*(gBankAttacker + gBattleStruct->field_54) = 1;
*(gBankAttacker + gBattleStruct->selectionScriptFinished) = TRUE;
}
static void atk45_playanimation(void)
@@ -5067,7 +5066,7 @@ static void atk49_moveend(void)
case 9: // make attacker sprite visible
if (gBattleMoveFlags & MOVESTATUS_NOEFFECT
|| !(gStatuses3[gBankAttacker] & (STATUS3_SEMI_INVULNERABLE))
|| HasMoveFailed(gBankAttacker))
|| WasUnableToUseMove(gBankAttacker))
{
gActiveBank = gBankAttacker;
EmitSpriteInvisibility(0, FALSE);
@@ -5298,7 +5297,7 @@ static void atk4A_typecalc2(void)
RecordAbilityBattle(gBankTarget, gLastUsedAbility);
}
if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED)
gProtectStructs[gBankAttacker].notEffective = 1;
gProtectStructs[gBankAttacker].targetNotAffected = 1;
gBattlescriptCurrInstr++;
}
@@ -5367,7 +5366,7 @@ static void atk4D_switch_data_update(void)
gBattleMons[gActiveBank].status2 = oldData.status2;
}
SwitchInClearStructs();
SwitchInClearSetData();
if (gBattleTypeFlags & BATTLE_TYPE_PALACE && gBattleMons[gActiveBank].maxHP / 2 >= gBattleMons[gActiveBank].hp
&& gBattleMons[gActiveBank].hp != 0 && !(gBattleMons[gActiveBank].status1 & STATUS_SLEEP))
@@ -5904,15 +5903,15 @@ static void atk51_switch_handle_order(void)
gBattleCommunication[0] = gBattleBufferB[gActiveBank][1];
*(gBattleStruct->field_5C + gActiveBank) = gBattleBufferB[gActiveBank][1];
if ((gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_LINK)) == (BATTLE_TYPE_MULTI | BATTLE_TYPE_LINK))
if (gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
*(gActiveBank * 3 + (u8*)(gBattleStruct->field_60) + 0) &= 0xF;
*(gActiveBank * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleBufferB[gActiveBank][2] & 0xF0);
*(gActiveBank * 3 + (u8*)(gBattleStruct->field_60) + 1) = gBattleBufferB[gActiveBank][3];
*((gActiveBank ^ 2) * 3 + (u8*)(gBattleStruct->field_60) + 0) &= (0xF0);
*((gActiveBank ^ 2) * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleBufferB[gActiveBank][2] & 0xF0) >> 4;
*((gActiveBank ^ 2) * 3 + (u8*)(gBattleStruct->field_60) + 2) = gBattleBufferB[gActiveBank][3];
*((gActiveBank ^ BIT_MON) * 3 + (u8*)(gBattleStruct->field_60) + 0) &= (0xF0);
*((gActiveBank ^ BIT_MON) * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleBufferB[gActiveBank][2] & 0xF0) >> 4;
*((gActiveBank ^ BIT_MON) * 3 + (u8*)(gBattleStruct->field_60) + 2) = gBattleBufferB[gActiveBank][3];
}
else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
{
@@ -5984,8 +5983,8 @@ static void atk52_switch_in_effects(void)
for (i = 0; i < gNoOfAllBanks; i++)
{
if (gTurnOrder[i] == gActiveBank)
gUnknown_0202407A[i] = 0xC;
if (gBanksByTurnOrder[i] == gActiveBank)
gActionsByTurnOrder[i] = ACTION_CANCEL_PARTNER;
}
for (i = 0; i < gNoOfAllBanks; i++)
@@ -6412,7 +6411,7 @@ static void atk60_increment_gamestat(void)
gBattlescriptCurrInstr += 2;
}
static void atk61_8025BA4(void)
static void atk61_draw_party_status_summary(void)
{
s32 i;
struct Pokemon* party;
@@ -6443,7 +6442,7 @@ static void atk61_8025BA4(void)
}
}
EmitCmd48(0, hpStatuses, 1);
EmitDrawPartyStatusSummary(0, hpStatuses, 1);
MarkBufferBankForExecution(gActiveBank);
gBattlescriptCurrInstr += 2;
@@ -6570,7 +6569,7 @@ static void atk68_80246A0(void)
s32 i;
for (i = 0; i < gNoOfAllBanks; i++)
gUnknown_0202407A[i] = 0xC;
gActionsByTurnOrder[i] = ACTION_CANCEL_PARTNER;
gBattlescriptCurrInstr++;
}
@@ -6957,9 +6956,9 @@ static void atk71_buffer_move_to_learn(void)
gBattlescriptCurrInstr++;
}
static void atk72_jump_if_can_run_frombattle(void)
static void atk72_jump_if_run_attempt_success(void)
{
if (CanRunFromBattle(gBank1))
if (TryRunFromBattle(gBank1))
gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
else
gBattlescriptCurrInstr += 5;
@@ -7046,7 +7045,7 @@ static void atk76_various(void)
else
gBankTarget = gActiveBank;
break;
case 2:
case VARIOUS_CAN_RUN_FROM_BATTLE:
gBattleCommunication[0] = IsRunningFromBattleImpossible();
break;
case VARIOUS_GET_MOVE_TARGET:
@@ -7197,7 +7196,7 @@ static void atk76_various(void)
gBattleOutcome = BATTLE_OPPONENT_TELEPORTED;
break;
case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC:
EmitPlaySound(0, 0x19C, 1);
EmitPlaySound(0, BGM_KACHI1, 1);
MarkBufferBankForExecution(gActiveBank);
break;
}
@@ -7213,7 +7212,7 @@ static void atk77_set_protect_like(void) // protect and endure
if (lastMove != MOVE_PROTECT && lastMove != MOVE_DETECT && lastMove != MOVE_ENDURE)
gDisableStructs[gBankAttacker].protectUses = 0;
if (gCurrentMoveTurn == (gNoOfAllBanks - 1))
if (gCurrentTurnActionNumber == (gNoOfAllBanks - 1))
notLastTurn = FALSE;
if (sProtectSuccessRates[gDisableStructs[gBankAttacker].protectUses] >= Random() && notLastTurn)
@@ -9519,19 +9518,19 @@ static void atkB3_rolloutdamagecalculation(void)
if (!(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) // first hit
{
gDisableStructs[gBankAttacker].rolloutTimer1 = 5;
gDisableStructs[gBankAttacker].rolloutTimer2 = 5;
gDisableStructs[gBankAttacker].rolloutCounter1 = 5;
gDisableStructs[gBankAttacker].rolloutCounter2 = 5;
gBattleMons[gBankAttacker].status2 |= STATUS2_MULTIPLETURNS;
gLockedMoves[gBankAttacker] = gCurrentMove;
}
if (--gDisableStructs[gBankAttacker].rolloutTimer1 == 0) // last hit
if (--gDisableStructs[gBankAttacker].rolloutCounter1 == 0) // last hit
{
gBattleMons[gBankAttacker].status2 &= ~(STATUS2_MULTIPLETURNS);
}
gDynamicBasePower = gBattleMoves[gCurrentMove].power;
for (i = 1; i < (5 - gDisableStructs[gBankAttacker].rolloutTimer1); i++)
for (i = 1; i < (5 - gDisableStructs[gBankAttacker].rolloutCounter1); i++)
gDynamicBasePower *= 2;
if (gBattleMons[gBankAttacker].status2 & STATUS2_DEFENSE_CURL)
@@ -9711,12 +9710,12 @@ static void atkBA_jumpifnopursuitswitchdmg(void)
for (i = 0; i < gNoOfAllBanks; i++)
{
if (gTurnOrder[i] == gBankTarget)
gUnknown_0202407A[i] = 11;
if (gBanksByTurnOrder[i] == gBankTarget)
gActionsByTurnOrder[i] = 11;
}
gCurrentMove = MOVE_PURSUIT;
gCurrMovePos = gUnknown_020241E9 = *(gBattleStruct->chosenMovesIds + gBankTarget);
gCurrMovePos = gUnknown_020241E9 = *(gBattleStruct->chosenMovePositions + gBankTarget);
gBattlescriptCurrInstr += 5;
gBattleScripting.animTurn = 1;
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
@@ -10632,7 +10631,7 @@ static void atkDF_setmagiccoat(void)
{
gBankTarget = gBankAttacker;
gSpecialStatuses[gBankAttacker].flag20 = 1;
if (gCurrentMoveTurn == gNoOfAllBanks - 1) // moves last turn
if (gCurrentTurnActionNumber == gNoOfAllBanks - 1) // moves last turn
{
gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
}
@@ -10646,7 +10645,7 @@ static void atkDF_setmagiccoat(void)
static void atkE0_setstealstatchange(void) // snatch
{
gSpecialStatuses[gBankAttacker].flag20 = 1;
if (gCurrentMoveTurn == gNoOfAllBanks - 1) // moves last turn
if (gCurrentTurnActionNumber == gNoOfAllBanks - 1) // moves last turn
{
gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
}
@@ -10943,7 +10942,7 @@ static void atkEC_pursuit_sth(void)
&& gActionForBanks[gActiveBank] == 0
&& gChosenMovesByBanks[gActiveBank] == MOVE_PURSUIT)
{
gUnknown_0202407A[gActiveBank] = 11;
gActionsByTurnOrder[gActiveBank] = 11;
gCurrentMove = MOVE_PURSUIT;
gBattlescriptCurrInstr += 5;
gBattleScripting.animTurn = 1;
@@ -11217,8 +11216,8 @@ static void atkF2_display_dex_info(void)
}
break;
case 3:
c2_berry_program_update_menu();
sub_8035AA4();
sub_80356D0();
LoadBattleTextboxAndBackground();
gBattle_BG3_X = 0x100;
gBattleCommunication[0]++;
break;
@@ -11394,15 +11393,15 @@ static void atkF5_removeattackerstatus1(void)
gBattlescriptCurrInstr++;
}
static void atkF6_802BF48(void)
static void atkF6_action_finished(void)
{
gFightStateTracker = 0xC;
gCurrentActionFuncId = ACTION_FINISHED;
}
static void atkF7_802BF54(void)
static void atkF7_turn_finished(void)
{
gFightStateTracker = 0xC;
gCurrentMoveTurn = gNoOfAllBanks;
gCurrentActionFuncId = ACTION_FINISHED;
gCurrentTurnActionNumber = gNoOfAllBanks;
}
static void atkF8_trainer_slide_back(void)

View File

@@ -17,9 +17,10 @@
#include "battle_controllers.h"
#include "event_data.h"
#include "calculate_base_damage.h"
#include "link.h"
extern const u8* gBattlescriptCurrInstr;
extern const u8* gUnknown_02024220[BATTLE_BANKS_COUNT];
extern const u8* gBattlescriptPtrsForSelection[BATTLE_BANKS_COUNT];
extern const u8* gUnknown_02024230[BATTLE_BANKS_COUNT];
extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
extern u8 gActiveBank;
@@ -32,8 +33,8 @@ extern u8 gBankAttacker;
extern u8 gBankTarget;
extern u8 gAbsentBankFlags;
extern u16 gBattleWeather;
extern u8 gTurnOrder[BATTLE_BANKS_COUNT];
extern u16 gSideAffecting[];
extern u8 gBanksByTurnOrder[BATTLE_BANKS_COUNT];
extern u16 gSideAffecting[2];
extern u8 gBattleCommunication[];
extern void (*gBattleMainFunc)(void);
extern s32 gBattleMoveDamage;
@@ -45,16 +46,17 @@ extern u32 gHitMarker;
extern u8 gEffectBank;
extern u16 gBattlePartyID[BATTLE_BANKS_COUNT];
extern u8 gBank1;
extern u16 gChosenMovesByBanks[];
extern u16 gChosenMovesByBanks[BATTLE_BANKS_COUNT];
extern u8 gBattleMoveFlags;
extern s32 gTakenDmg[BATTLE_BANKS_COUNT];
extern u8 gTakenDmgBanks[BATTLE_BANKS_COUNT];
extern u8 gLastUsedAbility;
extern u8 gFightStateTracker;
extern u8 gCurrentActionFuncId;
extern u32 gBattleExecBuffer;
extern u16 gRandomMove;
extern u8 gCurrMovePos;
extern u8 gUnknown_020241E9;
extern u8 gSentPokesToOpponent[2];
extern const struct BattleMove gBattleMoves[];
@@ -169,24 +171,278 @@ extern const u8 gUnknown_082DB6A5[]; //disobedient, uses a random move
extern const u8 gUnknown_082DB6D9[]; //disobedient, went to sleep
extern const u8 gUnknown_082DB6F0[]; //disobedient, hits itself
extern const u8 gStatusConditionString_PoisonJpn[];
extern const u8 gStatusConditionString_SleepJpn[];
extern const u8 gStatusConditionString_ParalysisJpn[];
extern const u8 gStatusConditionString_BurnJpn[];
extern const u8 gStatusConditionString_IceJpn[];
extern const u8 gStatusConditionString_ConfusionJpn[];
extern const u8 gStatusConditionString_LoveJpn[];
extern const u16 gSoundMovesTable[];
extern u8 b_first_side(u8, u8, u8);
extern void sub_803CEDC(u8, u8);
extern void BattleTurnPassed(void);
extern void sub_803F9EC();
extern bool8 sub_80423F4(u8 bank, u8, u8);
extern u8 weather_get_current(void);
extern void sub_803E08C(void);
extern void bc_move_exec_returning(void);
extern s8 GetFlavourRelationByPersonality(u32 personality, u8 flavor);
// rom const data
static const u16 sSoundMovesTable[] =
{
MOVE_GROWL, MOVE_ROAR, MOVE_SING, MOVE_SUPERSONIC, MOVE_SCREECH, MOVE_SNORE,
MOVE_UPROAR, MOVE_METAL_SOUND, MOVE_GRASS_WHISTLE, MOVE_HYPER_VOICE, 0xFFFF
};
u8 GetBattleBank(u8 caseId)
{
u8 ret = 0;
switch (caseId)
{
case BS_GET_TARGET:
ret = gBankTarget;
break;
case BS_GET_ATTACKER:
ret = gBankAttacker;
break;
case BS_GET_EFFECT_BANK:
ret = gEffectBank;
break;
case 7:
ret = 0;
break;
case BS_GET_SCRIPTING_BANK:
ret = gBattleScripting.bank;
break;
case 3:
ret = gBank1;
break;
case 5:
ret = gBank1;
break;
case 4:
case 6:
case 8:
case 9:
case BS_GET_PLAYER1:
ret = GetBankByIdentity(IDENTITY_PLAYER_MON1);
break;
case BS_GET_OPPONENT1:
ret = GetBankByIdentity(IDENTITY_OPPONENT_MON1);
break;
case BS_GET_PLAYER2:
ret = GetBankByIdentity(IDENTITY_PLAYER_MON2);
break;
case BS_GET_OPPONENT2:
ret = GetBankByIdentity(IDENTITY_OPPONENT_MON2);
break;
}
return ret;
}
void PressurePPLose(u8 bankDef, u8 bankAtk, u16 move)
{
s32 i;
if (gBattleMons[bankDef].ability != ABILITY_PRESSURE)
return;
for (i = 0; i < 4; i++)
{
if (gBattleMons[bankAtk].moves[i] == move)
break;
}
if (i == 4) // mons don't share any moves
return;
if (gBattleMons[bankAtk].pp[i] != 0)
gBattleMons[bankAtk].pp[i]--;
if (!(gBattleMons[bankAtk].status2 & STATUS2_TRANSFORMED)
&& !(gDisableStructs[bankAtk].unk18_b & gBitTable[i]))
{
gActiveBank = bankAtk;
EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + i, 0, 1, &gBattleMons[gActiveBank].pp[i]);
MarkBufferBankForExecution(gActiveBank);
}
}
void PressurePPLoseOnUsingImprision(u8 bankAtk)
{
s32 i, j;
s32 imprisionPos = 4;
u8 atkSide = GetBankSide(bankAtk);
for (i = 0; i < gNoOfAllBanks; i++)
{
if (atkSide != GetBankSide(i) && gBattleMons[i].ability == ABILITY_PRESSURE)
{
for (j = 0; j < 4; j++)
{
if (gBattleMons[bankAtk].moves[j] == MOVE_IMPRISON)
break;
}
if (j != 4)
{
imprisionPos = j;
if (gBattleMons[bankAtk].pp[j] != 0)
gBattleMons[bankAtk].pp[j]--;
}
}
}
if (imprisionPos != 4
&& !(gBattleMons[bankAtk].status2 & STATUS2_TRANSFORMED)
&& !(gDisableStructs[bankAtk].unk18_b & gBitTable[imprisionPos]))
{
gActiveBank = bankAtk;
EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + imprisionPos, 0, 1, &gBattleMons[gActiveBank].pp[imprisionPos]);
MarkBufferBankForExecution(gActiveBank);
}
}
void PressurePPLoseOnUsingPerishSong(u8 bankAtk)
{
s32 i, j;
s32 perishSongPos = 4;
for (i = 0; i < gNoOfAllBanks; i++)
{
if (gBattleMons[i].ability == ABILITY_PRESSURE && i != bankAtk)
{
for (j = 0; j < 4; j++)
{
if (gBattleMons[bankAtk].moves[j] == MOVE_PERISH_SONG)
break;
}
if (j != 4)
{
perishSongPos = j;
if (gBattleMons[bankAtk].pp[j] != 0)
gBattleMons[bankAtk].pp[j]--;
}
}
}
if (perishSongPos != 4
&& !(gBattleMons[bankAtk].status2 & STATUS2_TRANSFORMED)
&& !(gDisableStructs[bankAtk].unk18_b & gBitTable[perishSongPos]))
{
gActiveBank = bankAtk;
EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + perishSongPos, 0, 1, &gBattleMons[gActiveBank].pp[perishSongPos]);
MarkBufferBankForExecution(gActiveBank);
}
}
void MarkAllBufferBanksForExecution(void) // unused
{
s32 i;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{
for (i = 0; i < gNoOfAllBanks; i++)
gBattleExecBuffer |= gBitTable[i] << 0x1C;
}
else
{
for (i = 0; i < gNoOfAllBanks; i++)
gBattleExecBuffer |= gBitTable[i];
}
}
void MarkBufferBankForExecution(u8 bank)
{
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{
gBattleExecBuffer |= gBitTable[bank] << 0x1C;
}
else
{
gBattleExecBuffer |= gBitTable[bank];
}
}
void sub_803F850(u8 arg0)
{
s32 i;
for (i = 0; i < sub_8009FCC(); i++)
gBattleExecBuffer |= gBitTable[arg0] << (i << 2);
gBattleExecBuffer &= ~(0x10000000 << arg0);
}
void CancelMultiTurnMoves(u8 bank)
{
gBattleMons[bank].status2 &= ~(STATUS2_MULTIPLETURNS);
gBattleMons[bank].status2 &= ~(STATUS2_LOCK_CONFUSE);
gBattleMons[bank].status2 &= ~(STATUS2_UPROAR);
gBattleMons[bank].status2 &= ~(STATUS2_BIDE);
gStatuses3[bank] &= ~(STATUS3_SEMI_INVULNERABLE);
gDisableStructs[bank].rolloutCounter1 = 0;
gDisableStructs[bank].furyCutterCounter = 0;
}
bool8 WasUnableToUseMove(u8 bank)
{
if (gProtectStructs[bank].prlzImmobility
|| gProtectStructs[bank].targetNotAffected
|| gProtectStructs[bank].usedImprisionedMove
|| gProtectStructs[bank].loveImmobility
|| gProtectStructs[bank].usedDisabledMove
|| gProtectStructs[bank].usedTauntedMove
|| gProtectStructs[bank].flag2Unknown
|| gProtectStructs[bank].flinchImmobility
|| gProtectStructs[bank].confusionSelfDmg)
return TRUE;
else
return FALSE;
}
void PrepareStringBattle(u16 stringId, u8 bank)
{
gActiveBank = bank;
EmitPrintString(0, stringId);
MarkBufferBankForExecution(gActiveBank);
}
void ResetSentPokesToOpponentValue(void)
{
s32 i;
u32 bits = 0;
gSentPokesToOpponent[0] = 0;
gSentPokesToOpponent[1] = 0;
for (i = 0; i < gNoOfAllBanks; i += 2)
bits |= gBitTable[gBattlePartyID[i]];
for (i = 1; i < gNoOfAllBanks; i += 2)
gSentPokesToOpponent[(i & BIT_MON) >> 1] = bits;
}
void sub_803F9EC(u8 bank)
{
s32 i = 0;
u32 bits = 0;
if (GetBankSide(bank) == SIDE_OPPONENT)
{
u8 id = ((bank & BIT_MON) >> 1);
gSentPokesToOpponent[id] = 0;
for (i = 0; i < gNoOfAllBanks; i += 2)
{
if (!(gAbsentBankFlags & gBitTable[i]))
bits |= gBitTable[gBattlePartyID[i]];
}
gSentPokesToOpponent[id] = bits;
}
}
void sub_803FA70(u8 bank)
{
if (GetBankSide(bank) == SIDE_OPPONENT)
{
sub_803F9EC(bank);
}
else
{
s32 i;
for (i = 1; i < gNoOfAllBanks; i++)
gSentPokesToOpponent[(i & BIT_MON) >> 1] |= gBitTable[gBattlePartyID[bank]];
}
}
void BattleScriptPush(const u8* bsPtr)
{
@@ -203,7 +459,7 @@ void BattleScriptPop(void)
gBattlescriptCurrInstr = BATTLESCRIPTS_STACK->ptr[--BATTLESCRIPTS_STACK->size];
}
u8 sub_803FB4C(void) // msg, can't select a move
u8 TrySetCantSelectMoveBattleScript(void)
{
u8 limitations = 0;
u16 move = gBattleMons[gActiveBank].moves[gBattleBufferB[gActiveBank][2]];
@@ -221,7 +477,7 @@ u8 sub_803FB4C(void) // msg, can't select a move
}
else
{
gUnknown_02024220[gActiveBank] = gUnknown_082DAE1F;
gBattlescriptPtrsForSelection[gActiveBank] = gUnknown_082DAE1F;
limitations = 1;
}
}
@@ -236,7 +492,7 @@ u8 sub_803FB4C(void) // msg, can't select a move
}
else
{
gUnknown_02024220[gActiveBank] = gUnknown_082DB089;
gBattlescriptPtrsForSelection[gActiveBank] = gUnknown_082DB089;
limitations++;
}
}
@@ -251,7 +507,7 @@ u8 sub_803FB4C(void) // msg, can't select a move
}
else
{
gUnknown_02024220[gActiveBank] = gUnknown_082DB0A0;
gBattlescriptPtrsForSelection[gActiveBank] = gUnknown_082DB0A0;
limitations++;
}
}
@@ -266,7 +522,7 @@ u8 sub_803FB4C(void) // msg, can't select a move
}
else
{
gUnknown_02024220[gActiveBank] = gUnknown_082DB181;
gBattlescriptPtrsForSelection[gActiveBank] = gUnknown_082DB181;
limitations++;
}
}
@@ -288,7 +544,7 @@ u8 sub_803FB4C(void) // msg, can't select a move
}
else
{
gUnknown_02024220[gActiveBank] = gUnknown_082DB812;
gBattlescriptPtrsForSelection[gActiveBank] = gUnknown_082DB812;
limitations++;
}
}
@@ -301,7 +557,7 @@ u8 sub_803FB4C(void) // msg, can't select a move
}
else
{
gUnknown_02024220[gActiveBank] = gUnknown_082DB076;
gBattlescriptPtrsForSelection[gActiveBank] = gUnknown_082DB076;
limitations++;
}
}
@@ -352,7 +608,7 @@ bool8 AreAllMovesUnusable(void)
if (unusable == 0xF) // all moves are unusable
{
gProtectStructs[gActiveBank].onlyStruggle = 1;
gUnknown_02024220[gActiveBank] = BattleScript_NoMovesLeft;
gBattlescriptPtrsForSelection[gActiveBank] = BattleScript_NoMovesLeft;
}
else
{
@@ -407,15 +663,15 @@ u8 UpdateTurnCounters(void)
case 0:
for (i = 0; i < gNoOfAllBanks; i++)
{
gTurnOrder[i] = i;
gBanksByTurnOrder[i] = i;
}
for (i = 0; i < gNoOfAllBanks - 1; i++)
{
s32 j;
for (j = i + 1; j < gNoOfAllBanks; j++)
{
if (b_first_side(gTurnOrder[i], gTurnOrder[j], 0))
sub_803CEDC(i, j);
if (GetWhoStrikesFirst(gBanksByTurnOrder[i], gBanksByTurnOrder[j], 0))
SwapTurnOrder(i, j);
}
}
@@ -540,7 +796,7 @@ u8 UpdateTurnCounters(void)
case 5:
while (gBattleStruct->turnSideTracker < gNoOfAllBanks)
{
gActiveBank = gTurnOrder[gBattleStruct->turnSideTracker];
gActiveBank = gBanksByTurnOrder[gBattleStruct->turnSideTracker];
if (gWishFutureKnock.wishCounter[gActiveBank] != 0
&& --gWishFutureKnock.wishCounter[gActiveBank] == 0
&& gBattleMons[gActiveBank].hp != 0)
@@ -652,7 +908,7 @@ u8 TurnBasedEffects(void)
gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20);
while (gBattleStruct->turnEffectsBank < gNoOfAllBanks && gBattleStruct->turnEffectsTracker <= TURNBASED_MAX_CASE)
{
gActiveBank = gBankAttacker = gTurnOrder[gBattleStruct->turnEffectsBank];
gActiveBank = gBankAttacker = gBanksByTurnOrder[gBattleStruct->turnEffectsBank];
if (gAbsentBankFlags & gBitTable[gActiveBank])
{
gBattleStruct->turnEffectsBank++;
@@ -833,7 +1089,7 @@ u8 TurnBasedEffects(void)
{
gBankAttacker = gActiveBank;
gBattleMons[gActiveBank].status2 -= 0x10; // uproar timer goes down
if (HasMoveFailed(gActiveBank))
if (WasUnableToUseMove(gActiveBank))
{
CancelMultiTurnMoves(gActiveBank);
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
@@ -859,7 +1115,7 @@ u8 TurnBasedEffects(void)
if (gBattleMons[gActiveBank].status2 & STATUS2_LOCK_CONFUSE)
{
gBattleMons[gActiveBank].status2 -= 0x400;
if (HasMoveFailed(gActiveBank))
if (WasUnableToUseMove(gActiveBank))
CancelMultiTurnMoves(gActiveBank);
else if (!(gBattleMons[gActiveBank].status2 & STATUS2_LOCK_CONFUSE)
&& (gBattleMons[gActiveBank].status2 & STATUS2_MULTIPLETURNS))
@@ -1021,7 +1277,7 @@ bool8 sub_8041364(void)
case 1:
while (gBattleStruct->field_1A1 < gNoOfAllBanks)
{
gActiveBank = gBankAttacker = gTurnOrder[gBattleStruct->field_1A1];
gActiveBank = gBankAttacker = gBanksByTurnOrder[gBattleStruct->field_1A1];
if (gAbsentBankFlags & gBitTable[gActiveBank])
{
gBattleStruct->field_1A1++;
@@ -1130,7 +1386,7 @@ bool8 sub_8041728(void)
case 4:
do
{
gBank1 = gBankTarget = gBattleStruct->field_4E; //or should banks be switched?
gBank1 = gBankTarget = gBattleStruct->field_4E;
if (gBattleMons[gBattleStruct->field_4E].hp == 0
&& !(gAbsentBankFlags & gBitTable[gBattleStruct->field_4E]))
{
@@ -1159,7 +1415,7 @@ bool8 sub_8041728(void)
return FALSE;
}
void b_clear_atk_up_if_hit_flag_unless_enraged(void)
void TryClearRageStatuses(void)
{
int i;
for (i = 0; i < gNoOfAllBanks; i++)
@@ -1667,7 +1923,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg)
gBankAttacker = bank;
switch (gLastUsedAbility)
{
case 0xFF: //weather from overworld
case ABILITYEFFECT_SWITCH_IN_WEATHER:
//_08042A86
switch (weather_get_current())
{
@@ -1850,12 +2106,12 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg)
//_08042EF8
if (gLastUsedAbility == ABILITY_SOUNDPROOF)
{
for (i = 0; gSoundMovesTable[i] != 0xFFFF; i++)
for (i = 0; sSoundMovesTable[i] != 0xFFFF; i++)
{
if (gSoundMovesTable[i] == move)
if (sSoundMovesTable[i] == move)
break;
}
if (gSoundMovesTable[i] != 0xFFFF)
if (sSoundMovesTable[i] != 0xFFFF)
{
if (gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)
gHitMarker |= HITMARKER_NO_PPDEDUCT;
@@ -3156,7 +3412,7 @@ _08042EF8:\n\
bl _0804441E\n\
_08042F02:\n\
movs r4, 0\n\
ldr r0, =gSoundMovesTable\n\
ldr r0, =sSoundMovesTable\n\
ldrh r2, [r0]\n\
ldr r3, =0x0000ffff\n\
adds r1, r0, 0\n\
@@ -5444,8 +5700,8 @@ void BattleScriptExecute(const u8* BS_ptr)
{
gBattlescriptCurrInstr = BS_ptr;
BATTLE_CALLBACKS_STACK->function[BATTLE_CALLBACKS_STACK->size++] = gBattleMainFunc;
gBattleMainFunc = bc_move_exec_returning;
gFightStateTracker = 0;
gBattleMainFunc = RunBattleScriptCommands_PopCallbacksStack;
gCurrentActionFuncId = 0;
}
void BattleScriptPushCursorAndCallback(const u8* BS_ptr)
@@ -5453,7 +5709,7 @@ void BattleScriptPushCursorAndCallback(const u8* BS_ptr)
BattleScriptPushCursor();
gBattlescriptCurrInstr = BS_ptr;
BATTLE_CALLBACKS_STACK->function[BATTLE_CALLBACKS_STACK->size++] = gBattleMainFunc;
gBattleMainFunc = sub_803E08C;
gBattleMainFunc = RunBattleScriptCommands;
}
enum
@@ -5523,7 +5779,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn)
switch (caseID)
{
case 0:
case ITEMEFFECT_ON_SWITCH_IN:
switch (bankHoldEffect)
{
case HOLD_EFFECT_DOUBLE_PRIZE:
@@ -6188,14 +6444,14 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn)
return effect;
}
void sub_8045868(u8 bank)
void ClearFuryCutterDestinyBondGrudge(u8 bank)
{
gDisableStructs[bank].furyCutterCounter = 0;
gBattleMons[bank].status2 &= ~(STATUS2_DESTINY_BOND);
gStatuses3[bank] &= ~(STATUS3_GRUDGE);
}
void sub_80458B4(void)
void HandleAction_RunBattleScript(void) // identical to RunBattleScriptCommands
{
if (gBattleExecBuffer == 0)
gBattleScriptingCommandsTable[*gBattlescriptCurrInstr]();

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

583
src/braille_puzzles.c Executable file
View File

@@ -0,0 +1,583 @@
#include "global.h"
#include "event_data.h"
#include "songs.h"
#include "sound.h"
#include "script.h"
#include "species.h"
#include "task.h"
#include "field_effect.h"
#include "flags.h"
extern void MapGridSetMetatileIdAt(s32 x, s32 y, u16 metatileId); // fieldmap
extern void DrawWholeMapView(); // field_camera
extern void SetCameraPanningCallback(void ( *callback)()); // field_camera
extern void InstallCameraPanAheadCallback(void);
extern void SetCameraPanning(s16 x, s16 y);
extern u8 brm_get_pokemon_selection(void);
extern void FieldEffectActiveListRemove(u8 id); // field_effect
extern u8 oei_task_add(void);
// why do this, GF?
enum
{
STRENGTH_PUZZLE,
FLY_PUZZLE
};
extern u8 gBraillePuzzleCallbackFlag;
extern u8 gUnknown_085EFE74[][2];
void SealedChamberShakingEffect(u8);
void sub_8179860(void);
void sub_8179944(void);
bool8 ShouldDoBrailleDigEffect(void)
{
if (!FlagGet(SYS_BRAILLE_DIG)
&& (gSaveBlock1Ptr->location.mapGroup == 0x18
&& gSaveBlock1Ptr->location.mapNum == 0x47))
{
if (gSaveBlock1Ptr->pos.x == 10 && gSaveBlock1Ptr->pos.y == 3)
return TRUE;
if (gSaveBlock1Ptr->pos.x == 9 && gSaveBlock1Ptr->pos.y == 3)
return TRUE;
if (gSaveBlock1Ptr->pos.x == 11 && gSaveBlock1Ptr->pos.y == 3)
return TRUE;
}
return FALSE;
}
void DoBrailleDigEffect(void)
{
MapGridSetMetatileIdAt(16, 8, 554);
MapGridSetMetatileIdAt(17, 8, 555);
MapGridSetMetatileIdAt(18, 8, 556);
MapGridSetMetatileIdAt(16, 9, 3634);
MapGridSetMetatileIdAt(17, 9, 563);
MapGridSetMetatileIdAt(18, 9, 3636);
DrawWholeMapView();
PlaySE(SE_BAN);
FlagSet(SYS_BRAILLE_DIG);
ScriptContext2_Disable();
}
bool8 CheckRelicanthWailord(void)
{
// Emerald change: why did they flip it?
// First comes Wailord
if (GetMonData(&gPlayerParty[0], MON_DATA_SPECIES2, 0) == SPECIES_WAILORD)
{
CalculatePlayerPartyCount();
// Last comes Relicanth
if (GetMonData(&gPlayerParty[gPlayerPartyCount - 1], MON_DATA_SPECIES2, 0) == SPECIES_RELICANTH)
return TRUE;
}
return FALSE;
}
// THEORY: this was caused by block commenting out all of the older R/S braille functions but leaving the call to it itself, which creates the nullsub.
// the code is shown below to show what this might look like.
void ShouldDoBrailleStrengthEffectOld(void)
{
/*
if (!FlagGet(SYS_BRAILLE_STRENGTH) && (gSaveBlock1.location.mapGroup == MAP_GROUP_DESERT_RUINS && gSaveBlock1.location.mapNum == MAP_ID_DESERT_RUINS))
{
if (gSaveBlock1.pos.x == 10 && gSaveBlock1.pos.y == 23)
return TRUE;
else if (gSaveBlock1.pos.x == 9 && gSaveBlock1.pos.y == 23)
return TRUE;
else if (gSaveBlock1.pos.x == 11 && gSaveBlock1.pos.y == 23)
return TRUE;
}
return FALSE;
}
void DoBrailleStrengthEffect(void)
{
FieldEffectActiveListRemove(FLDEFF_USE_STRENGTH);
MapGridSetMetatileIdAt(14, 26, 554);
MapGridSetMetatileIdAt(15, 26, 555);
MapGridSetMetatileIdAt(16, 26, 556);
MapGridSetMetatileIdAt(14, 27, 3634);
MapGridSetMetatileIdAt(15, 27, 563);
MapGridSetMetatileIdAt(16, 27, 3636);
DrawWholeMapView();
PlaySE(SE_BAN);
FlagSet(SYS_BRAILLE_STRENGTH);
ScriptContext2_Disable();
}
bool8 ShouldDoBrailleFlyEffect(void)
{
if (!FlagGet(SYS_BRAILLE_FLY) && (gSaveBlock1.location.mapGroup == MAP_GROUP_ANCIENT_TOMB && gSaveBlock1.location.mapNum == MAP_ID_ANCIENT_TOMB))
{
if (gSaveBlock1.pos.x == 8 && gSaveBlock1.pos.y == 25)
return TRUE;
}
return FALSE;
}
void DoBrailleFlyEffect(void)
{
gFieldEffectArguments[0] = gLastFieldPokeMenuOpened;
FieldEffectStart(FLDEFF_USE_FLY_ANCIENT_TOMB);
}
bool8 FldEff_UseFlyAncientTomb(void)
{
u8 taskId = oei_task_add();
gTasks[taskId].data[8] = (u32)UseFlyAncientTomb_Callback >> 16;
gTasks[taskId].data[9] = (u32)UseFlyAncientTomb_Callback;
return FALSE;
}
void UseFlyAncientTomb_Callback(void)
{
FieldEffectActiveListRemove(FLDEFF_USE_FLY_ANCIENT_TOMB);
UseFlyAncientTomb_Finish();
}
void UseFlyAncientTomb_Finish(void)
{
MapGridSetMetatileIdAt(14, 26, 554);
MapGridSetMetatileIdAt(15, 26, 555);
MapGridSetMetatileIdAt(16, 26, 556);
MapGridSetMetatileIdAt(14, 27, 3634);
MapGridSetMetatileIdAt(15, 27, 563);
MapGridSetMetatileIdAt(16, 27, 3636);
DrawWholeMapView();
PlaySE(SE_BAN);
FlagSet(SYS_BRAILLE_FLY);
ScriptContext2_Disable();
}
*/
}
void DoSealedChamberShakingEffect1(void)
{
u8 taskId = CreateTask(SealedChamberShakingEffect, 9);
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = 0;
gTasks[taskId].data[4] = 2;
gTasks[taskId].data[5] = 5;
gTasks[taskId].data[6] = 50;
SetCameraPanningCallback(0);
}
void DoSealedChamberShakingEffect2(void)
{
u8 taskId = CreateTask(SealedChamberShakingEffect, 9);
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = 0;
gTasks[taskId].data[4] = 3;
gTasks[taskId].data[5] = 5;
gTasks[taskId].data[6] = 2;
SetCameraPanningCallback(0);
}
void SealedChamberShakingEffect(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[1]++;
if (!(task->data[1] % task->data[5]))
{
task->data[1] = 0;
task->data[2]++;
task->data[4] = -task->data[4];
SetCameraPanning(0, task->data[4]);
if (task->data[2] == task->data[6])
{
DestroyTask(taskId);
EnableBothScriptContexts();
InstallCameraPanAheadCallback();
}
}
}
// moved later in the function because it was rewritten.
bool8 ShouldDoBrailleStrengthEffect(void)
{
if (!FlagGet(SYS_BRAILLE_STRENGTH) && (gSaveBlock1Ptr->location.mapGroup == 0x18 && gSaveBlock1Ptr->location.mapNum == 0x06))
{
if (gSaveBlock1Ptr->pos.x == 6 && gSaveBlock1Ptr->pos.y == 23)
{ gBraillePuzzleCallbackFlag = STRENGTH_PUZZLE; return TRUE; }
else if (gSaveBlock1Ptr->pos.x == 5 && gSaveBlock1Ptr->pos.y == 23)
{ gBraillePuzzleCallbackFlag = STRENGTH_PUZZLE; return TRUE; }
else if (gSaveBlock1Ptr->pos.x == 7 && gSaveBlock1Ptr->pos.y == 23)
{ gBraillePuzzleCallbackFlag = STRENGTH_PUZZLE; return TRUE; }
}
return FALSE;
}
void sub_8179834(void)
{
gFieldEffectSpawnParams[0] = brm_get_pokemon_selection();
FieldEffectStart(FLDEFF_USE_FLY_ANCIENT_TOMB);
}
void UseStrengthDesertRuins_Callback(void)
{
FieldEffectActiveListRemove(FLDEFF_USE_FLY_ANCIENT_TOMB);
sub_8179860();
}
void sub_8179860(void)
{
MapGridSetMetatileIdAt(14, 26, 554);
MapGridSetMetatileIdAt(15, 26, 555);
MapGridSetMetatileIdAt(16, 26, 556);
MapGridSetMetatileIdAt(14, 27, 3634);
MapGridSetMetatileIdAt(15, 27, 563);
MapGridSetMetatileIdAt(16, 27, 3636);
DrawWholeMapView();
PlaySE(SE_BAN);
FlagSet(SYS_BRAILLE_STRENGTH);
ScriptContext2_Disable();
}
bool8 ShouldDoBrailleFlyEffect(void)
{
if (!FlagGet(SYS_BRAILLE_FLY) && (gSaveBlock1Ptr->location.mapGroup == 0x18 && gSaveBlock1Ptr->location.mapNum == 0x44))
{
if (gSaveBlock1Ptr->pos.x == 8 && gSaveBlock1Ptr->pos.y == 25)
{ gBraillePuzzleCallbackFlag = FLY_PUZZLE; return TRUE; }
}
return FALSE;
}
void sub_8179918(void)
{
gFieldEffectSpawnParams[0] = brm_get_pokemon_selection();
FieldEffectStart(FLDEFF_USE_FLY_ANCIENT_TOMB);
}
void UseFlyAncientTomb_Callback(void)
{
FieldEffectActiveListRemove(FLDEFF_USE_FLY_ANCIENT_TOMB);
sub_8179944();
}
void sub_8179944(void)
{
MapGridSetMetatileIdAt(14, 26, 554);
MapGridSetMetatileIdAt(15, 26, 555);
MapGridSetMetatileIdAt(16, 26, 556);
MapGridSetMetatileIdAt(14, 27, 3634);
MapGridSetMetatileIdAt(15, 27, 563);
MapGridSetMetatileIdAt(16, 27, 3636);
DrawWholeMapView();
PlaySE(SE_BAN);
FlagSet(SYS_BRAILLE_FLY);
ScriptContext2_Disable();
}
// theory: another commented out DoBrailleWait and Task_BrailleWait.
void DoBrailleWait(void)
{
/*
if (!FlagGet(SYS_BRAILLE_WAIT))
CreateTask(Task_BrailleWait, 0x50);
}
void Task_BrailleWait(u8 taskId)
{
s16 *data = gTasks[taskId].data;
switch (data[0])
{
case 0:
data[1] = 7200;
data[0] = 1;
break;
case 1:
if (BrailleWait_CheckButtonPress() != FALSE)
{
MenuZeroFillScreen();
PlaySE(SE_SELECT);
data[0] = 2;
}
else
{
data[1] = data[1] - 1;
if (data[1] == 0)
{
MenuZeroFillScreen();
data[0] = 3;
data[1] = 30;
}
}
break;
case 2:
if (BrailleWait_CheckButtonPress() == FALSE)
{
data[1] = data[1] - 1;
if (data[1] == 0)
data[0] = 4;
break;
}
sub_8064E2C();
DestroyTask(taskId);
ScriptContext2_Disable();
break;
case 3:
data[1] = data[1] - 1;
if (data[1] == 0)
data[0] = 4;
break;
case 4:
sub_8064E2C();
ScriptContext1_SetupScript(S_OpenRegiceChamber);
DestroyTask(taskId);
break;
}
}
bool32 BrailleWait_CheckButtonPress(void)
{
u16 keyMask = A_BUTTON | B_BUTTON | START_BUTTON | SELECT_BUTTON | DPAD_ANY;
if (gSaveBlock2.optionsButtonMode == OPTIONS_BUTTON_MODE_LR)
keyMask |= L_BUTTON | R_BUTTON;
if (gSaveBlock2.optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A)
keyMask |= L_BUTTON;
if (gMain.newKeys & keyMask)
return TRUE;
else
return FALSE;
*/
}
// this used to be FldEff_UseFlyAncientTomb . why did GF merge the 2 functions?
bool8 FldEff_UsePuzzleEffect(void)
{
u8 taskId = oei_task_add();
if (gBraillePuzzleCallbackFlag == FLY_PUZZLE)
{
gTasks[taskId].data[8] = (u32)UseFlyAncientTomb_Callback >> 16;
gTasks[taskId].data[9] = (u32)UseFlyAncientTomb_Callback;
}
else
{
gTasks[taskId].data[8] = (u32)UseStrengthDesertRuins_Callback >> 16;
gTasks[taskId].data[9] = (u32)UseStrengthDesertRuins_Callback;
}
return FALSE;
}
// can't get this one to match due to the weird macro-like varsets with strange bitshifting.
// to note: 0x10000 is loaded in, and its obviously supposed to be 1, but i cant get 0x80 << 9 to be loaded in without using it directly.
// maybe there's some way of writing it that works?
#ifdef NONMATCHING
// ShouldDoBrailleRegicePuzzle
bool8 ShouldDoBrailleRegicePuzzle(void)
{
u8 i;
if (gSaveBlock1Ptr->location.mapGroup == 0x18 && gSaveBlock1Ptr->location.mapNum == 0x43)
{
// _08179A1A
if (FlagGet(SYS_BRAILLE_WAIT) != FALSE)
return FALSE;
if (FlagGet(2) == FALSE)
return FALSE;
if (FlagGet(3) == TRUE)
return FALSE;
for (i = 0; i < 36; i++)
{
if (gSaveBlock1Ptr->pos.x == gUnknown_085EFE74[i][0] && gSaveBlock1Ptr->pos.y == gUnknown_085EFE74[i][1])
{
if (i < 16)
VarSet(0x403B, (0x10000 << i | VarGet(0x403B) << 16) >> 16); // correct
else if (i < 32)
VarSet(0x403C, (0x10000 << (i - 16) | VarGet(0x403C) << 16) >> 16); // hmm?
else
VarSet(0x403D, (0x10000 << (i - 32) | VarGet(0x403D) << 16) >> 16); // hmm?
if (VarGet(0x403B) != 0xFFFF || VarGet(0x403C) != 0xFF || VarGet(0x403D) != 0xF)
return FALSE;
if (gSaveBlock1Ptr->pos.x == 8 && gSaveBlock1Ptr->pos.y == 21)
return TRUE;
else
return FALSE;
}
}
}
// TODO: Find what flags 2 and 3 are.
FlagSet(3);
FlagReset(2);
return FALSE;
}
#else
__attribute__((naked))
bool8 ShouldDoBrailleRegicePuzzle(void)
{
asm(".syntax unified\n\
push {r4-r7,lr}\n\
mov r7, r9\n\
mov r6, r8\n\
push {r6,r7}\n\
ldr r4, =gSaveBlock1Ptr\n\
ldr r0, [r4]\n\
ldrh r1, [r0, 0x4]\n\
ldr r0, =0x00004318\n\
cmp r1, r0\n\
beq _08179A1A\n\
b _08179B5A\n\
_08179A1A:\n\
ldr r0, =0x000008b1\n\
bl FlagGet\n\
lsls r0, 24\n\
cmp r0, 0\n\
beq _08179A28\n\
b _08179B5A\n\
_08179A28:\n\
movs r0, 0x2\n\
bl FlagGet\n\
lsls r0, 24\n\
cmp r0, 0\n\
bne _08179A36\n\
b _08179B5A\n\
_08179A36:\n\
movs r0, 0x3\n\
bl FlagGet\n\
lsls r0, 24\n\
lsrs r0, 24\n\
cmp r0, 0x1\n\
bne _08179A58\n\
b _08179B5A\n\
.pool\n\
_08179A54:\n\
movs r0, 0x1\n\
b _08179B5C\n\
_08179A58:\n\
movs r5, 0\n\
mov r8, r4\n\
ldr r4, =gUnknown_085EFE74\n\
adds r0, r4, 0x1\n\
mov r12, r0\n\
ldr r6, =0x0000403b\n\
ldr r1, =0x0000403c\n\
mov r9, r1\n\
_08179A68:\n\
lsls r0, r5, 1\n\
adds r1, r0, r4\n\
add r0, r12\n\
ldrb r3, [r0]\n\
mov r7, r8\n\
ldr r2, [r7]\n\
movs r7, 0\n\
ldrsh r0, [r2, r7]\n\
ldrb r1, [r1]\n\
cmp r0, r1\n\
bne _08179B44\n\
movs r1, 0x2\n\
ldrsh r0, [r2, r1]\n\
cmp r0, r3\n\
bne _08179B44\n\
cmp r5, 0xF\n\
bhi _08179AB0\n\
adds r0, r6, 0\n\
bl VarGet\n\
lsls r0, 16\n\
movs r1, 0x80\n\
lsls r1, 9\n\
lsls r1, r5\n\
orrs r1, r0\n\
lsrs r1, 16\n\
adds r0, r6, 0\n\
bl VarSet\n\
b _08179AF0\n\
.pool\n\
_08179AB0:\n\
cmp r5, 0x1F\n\
bhi _08179AD2\n\
mov r0, r9\n\
bl VarGet\n\
lsls r0, 16\n\
adds r2, r5, 0\n\
subs r2, 0x10\n\
movs r1, 0x80\n\
lsls r1, 9\n\
lsls r1, r2\n\
orrs r1, r0\n\
lsrs r1, 16\n\
mov r0, r9\n\
bl VarSet\n\
b _08179AF0\n\
_08179AD2:\n\
ldr r4, =0x0000403d\n\
adds r0, r4, 0\n\
bl VarGet\n\
lsls r0, 16\n\
adds r2, r5, 0\n\
subs r2, 0x20\n\
movs r1, 0x80\n\
lsls r1, 9\n\
lsls r1, r2\n\
orrs r1, r0\n\
lsrs r1, 16\n\
adds r0, r4, 0\n\
bl VarSet\n\
_08179AF0:\n\
ldr r0, =0x0000403b\n\
bl VarGet\n\
lsls r0, 16\n\
lsrs r4, r0, 16\n\
ldr r0, =0x0000ffff\n\
cmp r4, r0\n\
bne _08179B5A\n\
ldr r0, =0x0000403c\n\
bl VarGet\n\
lsls r0, 16\n\
lsrs r0, 16\n\
cmp r0, r4\n\
bne _08179B5A\n\
ldr r0, =0x0000403d\n\
bl VarGet\n\
lsls r0, 16\n\
lsrs r0, 16\n\
cmp r0, 0xF\n\
bne _08179B5A\n\
ldr r0, =gSaveBlock1Ptr\n\
ldr r0, [r0]\n\
ldr r1, [r0]\n\
ldr r0, =0x00150008\n\
cmp r1, r0\n\
beq _08179A54\n\
b _08179B5A\n\
.pool\n\
_08179B44:\n\
adds r0, r5, 0x1\n\
lsls r0, 24\n\
lsrs r5, r0, 24\n\
cmp r5, 0x23\n\
bls _08179A68\n\
movs r0, 0x3\n\
bl FlagSet\n\
movs r0, 0x2\n\
bl FlagReset\n\
_08179B5A:\n\
movs r0, 0\n\
_08179B5C:\n\
pop {r3,r4}\n\
mov r8, r3\n\
mov r9, r4\n\
pop {r4-r7}\n\
pop {r1}\n\
bx r1\n\
.syntax divided");
}
#endif

218
src/diploma.c Executable file
View File

@@ -0,0 +1,218 @@
#include "global.h"
#include "palette.h"
#include "main.h"
#include "gpu_regs.h"
#include "unknown_task.h"
#include "task.h"
#include "malloc.h"
#include "decompress.h"
#include "bg.h"
#include "window.h"
#include "string_util.h"
#include "text.h"
extern void reset_temp_tile_data_buffers(void);
extern int decompress_and_copy_tile_data_to_vram(u8 bg_id, void *src, int size, u16 offset, u8 mode);
extern bool8 free_temp_tile_data_buffers_if_possible(void);
extern void sub_80861E8(void); // rom4
extern bool16 sub_80C0944(void);
extern void AddTextPrinterParametrized2(u8 windowId, u8 fontId, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, struct TextColor *color, s8 speed, u8 *str);
extern u16 gUnknown_0860F074[];
extern u8 gText_DexNational[];
extern u8 gText_DexHoenn[];
extern u8 gText_PokedexDiploma[];
static void MainCB2(void);
static void Task_DiplomaFadeIn(u8);
static void Task_DiplomaWaitForKeyPress(u8);
static void Task_DiplomaFadeOut(u8);
static void DisplayDiplomaText(void);
static void InitDiplomaBg(void);
static void InitDiplomaWindow(void);
static void PrintDiplomaText(u8 *, u8, u8);
EWRAM_DATA void **gDiplomaTilemapPtr = {NULL};
static void VBlankCB(void)
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
static const u16 gDiplomaPalettes[][16] =
{
INCBIN_U16("graphics/misc/diploma_national.gbapal"),
INCBIN_U16("graphics/misc/diploma_hoenn.gbapal"),
};
static const u8 gDiplomaTilemap[] = INCBIN_U8("graphics/misc/diploma_map.bin.lz");
static const u8 gDiplomaTiles[] = INCBIN_U8("graphics/misc/diploma.4bpp.lz");
void CB2_ShowDiploma(void)
{
SetVBlankCallback(NULL);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG3CNT, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG2CNT, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG1CNT, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG0CNT, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG3HOFS, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG3VOFS, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG2HOFS, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG2VOFS, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG1HOFS, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG1VOFS, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG0HOFS, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG0VOFS, DISPCNT_MODE_0);
// why doesn't this one use the dma manager either?
DmaFill16(3, 0, VRAM, VRAM_SIZE);
DmaFill32(3, 0, OAM, OAM_SIZE);
DmaFill16(3, 0, PLTT, PLTT_SIZE);
remove_some_task();
ResetTasks();
ResetSpriteData();
ResetPaletteFade();
FreeAllSpritePalettes();
LoadPalette(gDiplomaPalettes, 0, 64);
gDiplomaTilemapPtr = malloc(0x1000);
InitDiplomaBg();
InitDiplomaWindow();
reset_temp_tile_data_buffers();
decompress_and_copy_tile_data_to_vram(1, &gDiplomaTiles, 0, 0, 0);
while (free_temp_tile_data_buffers_if_possible())
;
LZDecompressWram(&gDiplomaTilemap, gDiplomaTilemapPtr);
CopyBgTilemapBufferToVram(1);
DisplayDiplomaText();
BlendPalettes(-1, 16, 0);
BeginNormalPaletteFade(-1, 0, 16, 0, 0);
EnableInterrupts(1);
SetVBlankCallback(VBlankCB);
SetMainCallback2(MainCB2);
CreateTask(Task_DiplomaFadeIn, 0);
}
static void MainCB2(void)
{
RunTasks();
AnimateSprites();
BuildOamBuffer();
UpdatePaletteFade();
}
static void Task_DiplomaFadeIn(u8 taskId)
{
if (!gPaletteFade.active)
gTasks[taskId].func = Task_DiplomaWaitForKeyPress;
}
static void Task_DiplomaWaitForKeyPress(u8 taskId)
{
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
{
BeginNormalPaletteFade(-1, 0, 0, 16, 0);
gTasks[taskId].func = Task_DiplomaFadeOut;
}
}
static void Task_DiplomaFadeOut(u8 taskId)
{
if (!gPaletteFade.active)
{
Free(gDiplomaTilemapPtr);
FreeAllWindowBuffers();
DestroyTask(taskId);
SetMainCallback2(sub_80861E8);
}
}
static void DisplayDiplomaText(void)
{
if (sub_80C0944())
{
SetGpuReg(REG_OFFSET_BG1HOFS, DISPCNT_BG0_ON);
StringCopy(gStringVar1, gText_DexNational);
}
else
{
SetGpuReg(REG_OFFSET_BG1HOFS, DISPCNT_MODE_0);
StringCopy(gStringVar1, gText_DexHoenn);
}
StringExpandPlaceholders(gStringVar4, gText_PokedexDiploma);
PrintDiplomaText(gStringVar4, 0, 1);
PutWindowTilemap(0);
CopyWindowToVram(0, 3);
}
static const struct BgTemplate gDiplomaBgTemplates[2] =
{
{
.bg = 0,
.charBaseIndex = 1,
.mapBaseIndex = 31,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0,
},
{
.bg = 1,
.charBaseIndex = 0,
.mapBaseIndex = 6,
.screenSize = 1,
.paletteMode = 0,
.priority = 1,
.baseTile = 0,
},
};
static void InitDiplomaBg(void)
{
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, gDiplomaBgTemplates, 2);
SetBgTilemapBuffer(1, gDiplomaTilemapPtr);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
ShowBg(0);
ShowBg(1);
SetGpuReg(REG_OFFSET_BLDCNT, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BLDALPHA, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BLDY, DISPCNT_MODE_0);
}
static const struct WindowTemplate gDiplomaWinTemplates[2] =
{
{
.priority = 0,
.tilemapLeft = 5,
.tilemapTop = 2,
.width = 20,
.height = 16,
.paletteNum = 15,
.baseBlock = 1,
},
DUMMY_WIN_TEMPLATE,
};
static void InitDiplomaWindow(void)
{
InitWindows(gDiplomaWinTemplates);
DeactivateAllTextPrinters();
LoadPalette(gUnknown_0860F074, 0xF0, 0x20);
FillWindowPixelBuffer(0, 0);
PutWindowTilemap(0);
}
static void PrintDiplomaText(u8 *text, u8 var1, u8 var2)
{
struct TextColor color =
{
.fgColor = 0,
.bgColor = 2,
.shadowColor = 3,
};
AddTextPrinterParametrized2(0, 1, var1, var2, 0, 0, &color, -1, text);
}

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++)
{
@@ -22,7 +33,6 @@ 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)
@@ -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\

View File

@@ -64,8 +64,8 @@ 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 AllocateMonSpritesGfx(void);
extern void FreeMonSpritesGfx(void);
extern void remove_some_task(void);
extern void reset_temp_tile_data_buffers(void);
extern void c2_exit_to_overworld_2_switch(void);
@@ -439,7 +439,7 @@ static u8 EggHatchCreateMonSprite(u8 a0, u8 switchID, u8 pokeID, u16* speciesLoc
u16 species = GetMonData(mon, MON_DATA_SPECIES);
u32 pid = GetMonData(mon, MON_DATA_PERSONALITY);
HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species],
gBattleSpritesGfx->sprites[(a0 * 2) + 1],
gMonSpritesGfxPtr->sprites[(a0 * 2) + 1],
species, pid);
LoadCompressedObjectPalette(sub_806E794(mon));
*speciesLoc = species;
@@ -488,7 +488,7 @@ static void CB2_EggHatch_0(void)
SetGpuReg(REG_OFFSET_DISPCNT, 0);
sEggHatchData = Alloc(sizeof(struct EggHatchData));
init_uns_table_pokemon_copy();
AllocateMonSpritesGfx();
sEggHatchData->eggPartyID = gSpecialVar_0x8004;
sEggHatchData->eggShardVelocityID = 0;
@@ -570,7 +570,7 @@ static void CB2_EggHatch_0(void)
static void EggHatchSetMonNickname(void)
{
SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar3);
sub_805F094();
FreeMonSpritesGfx();
Free(sEggHatchData);
SetMainCallback2(c2_exit_to_overworld_2_switch);
}
@@ -691,7 +691,7 @@ static void CB2_EggHatch_1(void)
case 12:
if (!gPaletteFade.active)
{
sub_805F094();
FreeMonSpritesGfx();
RemoveWindow(sEggHatchData->windowId);
UnsetBgTilemapBuffer(0);
UnsetBgTilemapBuffer(1);

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

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

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

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

@@ -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

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

@@ -152,8 +152,8 @@ u8 GetGenderFromSpeciesAndPersonality(u16 species, u32 personality)
void sub_806A068(u16 species, u8 bankIdentity)
{
if (gBattleSpritesGfx != NULL)
gUnknown_0202499C = gBattleSpritesGfx->templates[bankIdentity];
if (gMonSpritesGfxPtr != NULL)
gUnknown_0202499C = gMonSpritesGfxPtr->templates[bankIdentity];
else if (gUnknown_020249B4[0])
gUnknown_0202499C = gUnknown_020249B4[0]->templates[bankIdentity];
else if (gUnknown_020249B4[1])
@@ -180,8 +180,8 @@ void sub_806A12C(u16 trainerSpriteId, u8 bankIdentity)
}
else
{
if (gBattleSpritesGfx != NULL)
gUnknown_0202499C = gBattleSpritesGfx->templates[bankIdentity];
if (gMonSpritesGfxPtr != NULL)
gUnknown_0202499C = gMonSpritesGfxPtr->templates[bankIdentity];
else
gUnknown_0202499C = gUnknown_08329D98[bankIdentity];
gUnknown_0202499C.anims = gUnknown_0830536C[trainerSpriteId];
@@ -190,8 +190,8 @@ void sub_806A12C(u16 trainerSpriteId, u8 bankIdentity)
void sub_806A1C0(u16 arg0, u8 bankIdentity)
{
if (gBattleSpritesGfx != NULL)
gUnknown_0202499C = gBattleSpritesGfx->templates[bankIdentity];
if (gMonSpritesGfxPtr != NULL)
gUnknown_0202499C = gMonSpritesGfxPtr->templates[bankIdentity];
else
gUnknown_0202499C = gUnknown_08329D98[bankIdentity];
gUnknown_0202499C.paletteTag = arg0;

View File

@@ -486,8 +486,8 @@ u16 SpeciesToCryId(u16 species)
void sub_806D544(u16 species, u32 personality, u8 *dest)
{
if (species == SPECIES_SPINDA
&& dest != gBattleSpritesGfx->sprites[0]
&& dest != gBattleSpritesGfx->sprites[2])
&& dest != gMonSpritesGfxPtr->sprites[0]
&& dest != gMonSpritesGfxPtr->sprites[2])
{
int i;
for (i = 0; i < 4; i++)
@@ -1519,8 +1519,6 @@ void BattleAnimateFrontSprite(struct Sprite* sprite, u16 species, bool8 noCry, u
DoMonFrontSpriteAnimation(sprite, species, noCry, arg3);
}
bool8 HasTwoFramesAnimation(u16 species);
extern void SpriteCallbackDummy_2(struct Sprite*);
extern void sub_817F60C(struct Sprite*);

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

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

@@ -15,7 +15,6 @@ extern const struct SaveSectionOffsets gSaveSectionOffsets[0xE];
extern void DoSaveFailedScreen(u8); // save_failed_screen
extern void LoadSerializedGame(void); // load_save
extern bool32 ProgramFlashSectorAndVerify(u8 sector, u8 *data);
extern void ReadFlash(u8 sector, u32 arg1, void* data, u32 size);
// iwram common
u16 gLastWrittenSector;
@@ -806,7 +805,7 @@ u32 sub_81535DC(u8 sector, u8* dst)
if (sector != 30 && sector != 31)
return 0xFF;
ReadFlash(sector, 0, &gSaveDataBuffer, sizeof(struct SaveSection));
ReadFlash(sector, 0, (u8 *)&gSaveDataBuffer, sizeof(struct SaveSection));
if (*(u32*)(&gSaveDataBuffer.data[0]) != 0xB39D)
return 0xFF;
// copies whole save section except u32 counter

426
src/save_failed_screen.c Executable file
View File

@@ -0,0 +1,426 @@
#include "global.h"
#include "text.h"
#include "main.h"
#include "palette.h"
#include "gpu_regs.h"
#include "bg.h"
#include "task.h"
#include "window.h"
#include "menu.h"
#include "save.h"
#include "gba/flash_internal.h"
#define MSG_WIN_TOP 12
#define CLOCK_WIN_TOP (MSG_WIN_TOP - 4)
extern void AddTextPrinterParametrized2(u8 windowId, u8 fontId, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, struct TextColor *color, s8 speed, u8 *str);
extern void (*gGameContinueCallback)(void);
extern u32 gDamagedSaveSectors;
extern const u8 gBirchHelpGfx[];
extern const u8 gBirchBagTilemap[];
extern const u8 gBirchGrassTilemap[];
extern const u16 gBirchBagGrassPal[];
extern const u16 gUnknown_0850FEFC[];
extern const u16 gUnknown_0860F074[];
extern const u32 gUnknown_0850E87C[];
extern struct SaveSection gSaveDataBuffer;
extern u8 gText_SaveFailedCheckingBackup[];
extern u8 gText_BackupMemoryDamaged[];
extern u8 gText_CheckCompleted[];
extern u8 gText_SaveCompleteGameCannotContinue[];
extern u8 gText_SaveCompletePressA[];
extern u8 gText_GamePlayCannotBeContinued[];
extern u8 gDecompressionBuffer[];
// gSaveFailedClockInfo enum
enum
{
CLOCK_RUNNING,
DEBUG_TIMER
};
// gSaveFailedWindowIds enum
enum
{
TEXT_WIN_ID,
CLOCK_WIN_ID
};
EWRAM_DATA u16 gSaveFailedType = {0};
EWRAM_DATA u16 gSaveFailedClockInfo[2] = {0};
EWRAM_DATA u8 gSaveFailedUnused1[12] = {0};
EWRAM_DATA u8 gSaveFailedWindowIds[2] = {0};
EWRAM_DATA u8 gSaveFailedUnused2[4] = {0};
static const struct OamData sClockOamData =
{
160, // Y
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0
};
static const struct BgTemplate gUnknown_085EFD88[3] =
{
{
.bg = 0,
.charBaseIndex = 2,
.mapBaseIndex = 31,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0,
},
{
.bg = 2,
.charBaseIndex = 0,
.mapBaseIndex = 14,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0,
},
{
.bg = 3,
.charBaseIndex = 0,
.mapBaseIndex = 15,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0,
},
};
static const struct WindowTemplate gUnknown_085EFD94[] =
{
{
.priority = 255,
.tilemapLeft = 0,
.tilemapTop = 0,
.width = 0,
.height = 0,
.paletteNum = 0,
.baseBlock = 0,
}
};
static const struct WindowTemplate gUnknown_085EFD9C[] =
{
{
.priority = 0,
.tilemapLeft = 1,
.tilemapTop = 13,
.width = 28,
.height = 6,
.paletteNum = 15,
.baseBlock = 1,
}
};
static const struct WindowTemplate gUnknown_085EFDA4[] =
{
{
.priority = 0,
.tilemapLeft = 14,
.tilemapTop = 9,
.width = 2,
.height = 2,
.paletteNum = 15,
.baseBlock = 169,
}
};
static const u8 sClockFrames[8][3] =
{
{ 1, 0, 0 },
{ 5, 0, 0 },
{ 9, 0, 0 },
{ 5, 0, 1 },
{ 1, 0, 1 },
{ 5, 1, 1 },
{ 9, 1, 0 },
{ 5, 1, 0 },
};
static const u8 gSaveFailedClockPal[] = INCBIN_U8("graphics/misc/clock_small.gbapal");
static const u8 gSaveFailedClockGfx[] = INCBIN_U8("graphics/misc/clock_small.4bpp.lz");
static void CB2_SaveFailedScreen(void);
static void CB2_WipeSave(void);
static void CB2_GameplayCannotBeContinued(void);
static void CB2_FadeAndReturnToTitleScreen(void);
static void CB2_ReturnToTitleScreen(void);
static void VBlankCB_UpdateClockGraphics(void);
static bool8 VerifySectorWipe(u16 sector);
static bool8 WipeSectors(u32);
// although this is a general text printer, it's only used in this file.
static void SaveFailedScreenTextPrint(u8 *text, u8 var1, u8 var2)
{
struct TextColor color;
color.fgColor = 0;
color.bgColor = 15;
color.shadowColor = 3;
AddTextPrinterParametrized2(gSaveFailedWindowIds[TEXT_WIN_ID], 1, var1 * 8, var2 * 8 + 1, 0, 0, &color, 0, text);
}
void DoSaveFailedScreen(u8 saveType)
{
SetMainCallback2(CB2_SaveFailedScreen);
gSaveFailedType = saveType;
gSaveFailedClockInfo[CLOCK_RUNNING] = FALSE;
gSaveFailedClockInfo[DEBUG_TIMER] = 0;
gSaveFailedWindowIds[TEXT_WIN_ID] = 0;
gSaveFailedWindowIds[CLOCK_WIN_ID] = 0;
}
static void VBlankCB(void)
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
static void CB2_SaveFailedScreen(void)
{
switch (gMain.state)
{
case 0:
default:
SetVBlankCallback(NULL);
SetGpuReg(REG_OFFSET_DISPCNT, 0);
SetGpuReg(REG_OFFSET_BG3CNT, 0);
SetGpuReg(REG_OFFSET_BG2CNT, 0);
SetGpuReg(REG_OFFSET_BG1CNT, 0);
SetGpuReg(REG_OFFSET_BG0CNT, 0);
SetGpuReg(REG_OFFSET_BG3HOFS, 0);
SetGpuReg(REG_OFFSET_BG3VOFS, 0);
SetGpuReg(REG_OFFSET_BG2HOFS, 0);
SetGpuReg(REG_OFFSET_BG2VOFS, 0);
SetGpuReg(REG_OFFSET_BG1HOFS, 0);
SetGpuReg(REG_OFFSET_BG1VOFS, 0);
SetGpuReg(REG_OFFSET_BG0HOFS, 0);
SetGpuReg(REG_OFFSET_BG0VOFS, 0);
// how come this doesnt use the Dma manager?
DmaFill16(3, 0, VRAM, VRAM_SIZE);
DmaFill32(3, 0, OAM, OAM_SIZE);
DmaFill16(3, 0, PLTT, PLTT_SIZE);
LZ77UnCompVram(gBirchHelpGfx, (void *)VRAM);
LZ77UnCompVram(gBirchBagTilemap, (void *)(VRAM + 0x7000));
LZ77UnCompVram(gBirchGrassTilemap, (void *)(VRAM + 0x7800));
LZ77UnCompVram(gSaveFailedClockGfx, (void *)(VRAM + 0x10020));
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, gUnknown_085EFD88, 3);
SetBgTilemapBuffer(0, (void *)&gDecompressionBuffer[0x2000]);
CpuFill32(0, &gDecompressionBuffer[0x2000], 0x800);
LoadBgTiles(0, gUnknown_0850E87C, 0x120, 0x214);
InitWindows(gUnknown_085EFD94);
// AddWindowWithoutTileMap returns a u16/integer, but the info is clobbered into a u8 here resulting in lost info. Bug?
gSaveFailedWindowIds[TEXT_WIN_ID] = AddWindowWithoutTileMap(gUnknown_085EFD9C);
SetWindowAttribute(gSaveFailedWindowIds[TEXT_WIN_ID], 7, (u32)&gDecompressionBuffer[0x2800]);
gSaveFailedWindowIds[CLOCK_WIN_ID] = AddWindowWithoutTileMap(gUnknown_085EFDA4);
SetWindowAttribute(gSaveFailedWindowIds[CLOCK_WIN_ID], 7, (u32)&gDecompressionBuffer[0x3D00]);
DeactivateAllTextPrinters();
ResetSpriteData();
ResetTasks();
ResetPaletteFade();
LoadPalette(gBirchBagGrassPal, 0, 0x40);
LoadPalette(gSaveFailedClockPal, 0x100, 0x20);
LoadPalette(gUnknown_0850FEFC, 0xE0, 0x20);
LoadPalette(gUnknown_0860F074, 0xF0, 0x20);
SetWindowBorderStyle(gSaveFailedWindowIds[TEXT_WIN_ID], FALSE, 0x214, 0xE);
SetWindowBorderStyle(gSaveFailedWindowIds[CLOCK_WIN_ID], FALSE, 0x214, 0xE);
FillWindowPixelBuffer(gSaveFailedWindowIds[CLOCK_WIN_ID], 0x11); // backwards?
FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], 0x11);
CopyWindowToVram(gSaveFailedWindowIds[CLOCK_WIN_ID], 2); // again?
CopyWindowToVram(gSaveFailedWindowIds[TEXT_WIN_ID], 1);
SaveFailedScreenTextPrint(gText_SaveFailedCheckingBackup, 1, 0);
BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, 0);
EnableInterrupts(1);
SetVBlankCallback(VBlankCB);
SetGpuReg(0, 0x1040);
ShowBg(0);
ShowBg(2);
ShowBg(3);
gMain.state++;
break;
case 1:
if (!UpdatePaletteFade())
{
SetMainCallback2(CB2_WipeSave);
SetVBlankCallback(VBlankCB_UpdateClockGraphics);
}
break;
}
}
static void CB2_WipeSave(void)
{
u8 wipeTries = 0;
gSaveFailedClockInfo[CLOCK_RUNNING] = TRUE;
while (gDamagedSaveSectors != 0 && wipeTries < 3)
{
if (WipeSectors(gDamagedSaveSectors) != FALSE)
{
FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], 0x11);
SaveFailedScreenTextPrint(gText_BackupMemoryDamaged, 1, 0);
SetMainCallback2(CB2_GameplayCannotBeContinued);
return;
}
FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], 0x11);
SaveFailedScreenTextPrint(gText_CheckCompleted, 1, 0);
HandleSavingData(gSaveFailedType);
if (gDamagedSaveSectors != 0)
{
FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], 0x11);
SaveFailedScreenTextPrint(gText_SaveFailedCheckingBackup, 1, 0);
}
wipeTries++;
}
if (wipeTries == 3)
{
FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], 0x11);
SaveFailedScreenTextPrint(gText_BackupMemoryDamaged, 1, 0);
}
else
{
FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], 0x11);
if (gGameContinueCallback == NULL)
SaveFailedScreenTextPrint(gText_SaveCompleteGameCannotContinue, 1, 0);
else
SaveFailedScreenTextPrint(gText_SaveCompletePressA, 1, 0);
}
SetMainCallback2(CB2_FadeAndReturnToTitleScreen);
}
static void CB2_GameplayCannotBeContinued(void)
{
gSaveFailedClockInfo[CLOCK_RUNNING] = FALSE;
if (gMain.newKeys & A_BUTTON)
{
FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], 0x11);
SaveFailedScreenTextPrint(gText_GamePlayCannotBeContinued, 1, 0);
SetVBlankCallback(VBlankCB);
SetMainCallback2(CB2_FadeAndReturnToTitleScreen);
}
}
static void CB2_FadeAndReturnToTitleScreen(void)
{
gSaveFailedClockInfo[CLOCK_RUNNING] = FALSE;
if (gMain.newKeys & A_BUTTON)
{
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
SetVBlankCallback(VBlankCB);
SetMainCallback2(CB2_ReturnToTitleScreen);
}
}
static void CB2_ReturnToTitleScreen(void)
{
if (!UpdatePaletteFade())
{
if (gGameContinueCallback == NULL) // no callback exists, so do a soft reset.
{
DoSoftReset();
}
else
{
SetMainCallback2((MainCallback)gGameContinueCallback);
gGameContinueCallback = NULL;
}
}
}
static void VBlankCB_UpdateClockGraphics(void)
{
unsigned int n = (gMain.vblankCounter2 >> 3) & 7;
gMain.oamBuffer[0] = sClockOamData;
gMain.oamBuffer[0].x = 112;
gMain.oamBuffer[0].y = (CLOCK_WIN_TOP + 1) * 8;;
if (gSaveFailedClockInfo[CLOCK_RUNNING] != FALSE)
{
gMain.oamBuffer[0].tileNum = sClockFrames[n][0];
gMain.oamBuffer[0].matrixNum = (sClockFrames[n][2] << 4) | (sClockFrames[n][1] << 3);
}
else
{
gMain.oamBuffer[0].tileNum = 1;
}
CpuFastCopy(gMain.oamBuffer, (void *)OAM, 4);
if (gSaveFailedClockInfo[DEBUG_TIMER])
gSaveFailedClockInfo[DEBUG_TIMER]--;
}
static bool8 VerifySectorWipe(u16 sector)
{
u32 *ptr = (u32 *)&gSaveDataBuffer;
u16 i;
ReadFlash(sector, 0, (u8 *)ptr, 4096);
for (i = 0; i < 0x400; i++, ptr++)
if (*ptr)
return TRUE;
return FALSE;
}
static bool8 WipeSector(u16 sector)
{
u16 i, j;
bool8 failed = TRUE;
for (i = 0; failed && i < 130; i++)
{
for (j = 0; j < 0x1000; j++)
ProgramFlashByte(sector, j, 0);
failed = VerifySectorWipe(sector);
}
return failed;
}
static bool8 WipeSectors(u32 sectorBits)
{
u16 i;
for (i = 0; i < 0x20; i++)
if ((sectorBits & (1 << i)) && !WipeSector(i))
sectorBits &= ~(1 << i);
if (sectorBits == 0)
return FALSE;
else
return TRUE;
}

145
src/save_location.c Executable file
View File

@@ -0,0 +1,145 @@
#include "global.h"
#include "map_constants.h"
// used to make the list defines a little less ugly.
#define MAP(name) ((MAP_GROUP_##name << 8) + (MAP_ID_##name))
// specialSaveWarp flags
#define POKECENTER_SAVEWARP (1 << 1)
#define LOBBY_SAVEWARP (1 << 2)
#define UNK_SPECIAL_SAVE_WARP_FLAG_3 (1 << 3)
static bool32 IsCurMapInLocationList(const u16 *list)
{
u16 locSum = (gSaveBlock1Ptr->location.mapGroup << 8) + (gSaveBlock1Ptr->location.mapNum);
// im sure it was written a different way, but for the love of christ I cant figure out how to write it different where it still matches.
if (*list != 0xFFFF)
{
u16 termValue = 0xFFFF;
const u16 *localList;
for (localList = list; *localList != termValue; localList++)
if (*localList == locSum)
return TRUE;
}
return FALSE;
}
// TODO: Not require a packed u16 array for these lists
static const u16 gSaveLocationPokeCenterList[] =
{
MAP(OLDALE_TOWN_POKEMON_CENTER_1F),
MAP(OLDALE_TOWN_POKEMON_CENTER_2F),
MAP(DEWFORD_TOWN_POKEMON_CENTER_1F),
MAP(DEWFORD_TOWN_POKEMON_CENTER_2F),
MAP(LAVARIDGE_TOWN_POKEMON_CENTER_1F),
MAP(LAVARIDGE_TOWN_POKEMON_CENTER_2F),
MAP(FALLARBOR_TOWN_POKEMON_CENTER_1F),
MAP(FALLARBOR_TOWN_POKEMON_CENTER_2F),
MAP(VERDANTURF_TOWN_POKEMON_CENTER_1F),
MAP(VERDANTURF_TOWN_POKEMON_CENTER_2F),
MAP(PACIFIDLOG_TOWN_POKEMON_CENTER_1F),
MAP(PACIFIDLOG_TOWN_POKEMON_CENTER_2F),
MAP(PETALBURG_CITY_POKEMON_CENTER_1F),
MAP(PETALBURG_CITY_POKEMON_CENTER_2F),
MAP(SLATEPORT_CITY_POKEMON_CENTER_1F),
MAP(SLATEPORT_CITY_POKEMON_CENTER_2F),
MAP(MAUVILLE_CITY_POKEMON_CENTER_1F),
MAP(MAUVILLE_CITY_POKEMON_CENTER_2F),
MAP(RUSTBORO_CITY_POKEMON_CENTER_1F),
MAP(RUSTBORO_CITY_POKEMON_CENTER_2F),
MAP(FORTREE_CITY_POKEMON_CENTER_1F),
MAP(FORTREE_CITY_POKEMON_CENTER_2F),
MAP(LILYCOVE_CITY_POKEMON_CENTER_1F),
MAP(LILYCOVE_CITY_POKEMON_CENTER_2F),
MAP(MOSSDEEP_CITY_POKEMON_CENTER_1F),
MAP(MOSSDEEP_CITY_POKEMON_CENTER_2F),
MAP(SOOTOPOLIS_CITY_POKEMON_CENTER_1F),
MAP(SOOTOPOLIS_CITY_POKEMON_CENTER_2F),
MAP(EVER_GRANDE_CITY_POKEMON_CENTER_1F),
MAP(EVER_GRANDE_CITY_POKEMON_CENTER_2F),
MAP(EVER_GRANDE_CITY_POKEMON_LEAGUE_1F),
MAP(EVER_GRANDE_CITY_POKEMON_LEAGUE_2F),
MAP(BATTLE_FRONTIER_POKEMON_CENTER_1F),
MAP(BATTLE_FRONTIER_POKEMON_CENTER_2F),
MAP(SINGLE_BATTLE_COLOSSEUM),
MAP(TRADE_CENTER),
MAP(RECORD_CORNER),
MAP(DOUBLE_BATTLE_COLOSSEUM),
0xFFFF,
};
static bool32 IsCurMapPokeCenter(void)
{
return IsCurMapInLocationList(gSaveLocationPokeCenterList);
}
static const u16 gSaveLocationReloadLocList[] = // there's only 1 location, and it's presumed its for the save reload feature for battle tower
{
MAP(BATTLE_TOWER_LOBBY),
0xFFFF,
};
static bool32 IsCurMapReloadLocation(void)
{
return IsCurMapInLocationList(gSaveLocationReloadLocList);
}
// nulled out list. unknown what this would have been
static const u16 gUnknown_0861440E[] =
{
0xFFFF,
};
bool32 sub_81AFCEC(void)
{
return IsCurMapInLocationList(gUnknown_0861440E);
}
static void TrySetPokeCenterWarpStatus(void)
{
if (IsCurMapPokeCenter() == FALSE)
gSaveBlock2Ptr->specialSaveWarp &= ~(POKECENTER_SAVEWARP);
else
gSaveBlock2Ptr->specialSaveWarp |= POKECENTER_SAVEWARP;
}
static void TrySetReloadWarpStatus(void)
{
if (!IsCurMapReloadLocation())
gSaveBlock2Ptr->specialSaveWarp &= ~(LOBBY_SAVEWARP);
else
gSaveBlock2Ptr->specialSaveWarp |= LOBBY_SAVEWARP;
}
// this function definitely sets a warp status, but because the list is empty, it's unknown what this does yet.
static void sub_81AFD5C(void)
{
if (!sub_81AFCEC())
gSaveBlock2Ptr->specialSaveWarp &= ~(UNK_SPECIAL_SAVE_WARP_FLAG_3);
else
gSaveBlock2Ptr->specialSaveWarp |= UNK_SPECIAL_SAVE_WARP_FLAG_3;
}
void TrySetMapSaveWarpStatus(void)
{
TrySetPokeCenterWarpStatus();
TrySetReloadWarpStatus();
sub_81AFD5C();
}
void sub_81AFDA0(void)
{
gSaveBlock2Ptr->field_A8 |= 0x8000;
gSaveBlock2Ptr->field_A8 |= 0x1;
gSaveBlock2Ptr->field_A8 |= 0x2;
gSaveBlock2Ptr->field_A8 |= 0x4;
gSaveBlock2Ptr->field_A8 |= 0x10;
gSaveBlock2Ptr->field_A8 |= 0x20;
gSaveBlock2Ptr->field_A8 |= 0x8;
}
void sub_81AFDD0(void)
{
gSaveBlock2Ptr->specialSaveWarp |= 0x80;
}

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

@@ -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,
@@ -1972,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)
@@ -1991,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);

1411
src/tileset_anims.c Normal file

File diff suppressed because it is too large Load Diff

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

@@ -190,7 +190,7 @@ u16 AddWindow(const struct WindowTemplate *template)
return win;
}
int AddWindowWithoutTileMap(struct WindowTemplate *template)
int AddWindowWithoutTileMap(const struct WindowTemplate *template)
{
u16 win;
u8 bgLayer;