mirror of
https://github.com/pret/pokefirered.git
synced 2026-04-25 07:19:36 -05:00
Add revision 10 changes (#722)
* revision 10 changes * add rev10 to github actions * add no-intro entry for leafgreen rev10
This commit is contained in:
parent
0a86141109
commit
8f00ac8fe6
13
.github/workflows/build.yml
vendored
13
.github/workflows/build.yml
vendored
|
|
@ -55,6 +55,12 @@ jobs:
|
|||
run: |
|
||||
make -j${nproc} all syms
|
||||
|
||||
- name: Compare FireRed rev10
|
||||
env:
|
||||
GAME_REVISION: 10
|
||||
run: |
|
||||
make -j${nproc} all syms
|
||||
|
||||
- name: Compare LeafGreen
|
||||
env:
|
||||
GAME_VERSION: LEAFGREEN
|
||||
|
|
@ -68,6 +74,13 @@ jobs:
|
|||
run: |
|
||||
make -j${nproc} all syms
|
||||
|
||||
- name: Compare LeafGreen rev10
|
||||
env:
|
||||
GAME_VERSION: LEAFGREEN
|
||||
GAME_REVISION: 10
|
||||
run: |
|
||||
make -j${nproc} all syms
|
||||
|
||||
- name: Build Modern
|
||||
env:
|
||||
MODERN: 1
|
||||
|
|
|
|||
20
Makefile
20
Makefile
|
|
@ -129,7 +129,7 @@ MAKEFLAGS += --no-print-directory
|
|||
# Delete files that weren't built properly
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
ALL_BUILDS := firered firered_rev1 leafgreen leafgreen_rev1
|
||||
ALL_BUILDS := firered firered_rev1 firered_rev10 leafgreen leafgreen_rev1 leafgreen_rev10
|
||||
ALL_BUILDS += $(ALL_BUILDS:%=%_modern)
|
||||
|
||||
RULES_NO_SCAN += clean clean-assets tidy generated clean-generated
|
||||
|
|
@ -224,13 +224,17 @@ tidy:
|
|||
# "friendly" target names for convenience sake
|
||||
firered: ; @$(MAKE) GAME_VERSION=FIRERED
|
||||
firered_rev1: ; @$(MAKE) GAME_VERSION=FIRERED GAME_REVISION=1
|
||||
firered_switch: ; @$(MAKE) GAME_VERSION=FIRERED GAME_REVISION=10
|
||||
leafgreen: ; @$(MAKE) GAME_VERSION=LEAFGREEN
|
||||
leafgreen_rev1: ; @$(MAKE) GAME_VERSION=LEAFGREEN GAME_REVISION=1
|
||||
leafgreen_switch: ; @$(MAKE) GAME_VERSION=LEAFGREEN GAME_REVISION=10
|
||||
|
||||
compare_firered: ; @$(MAKE) GAME_VERSION=FIRERED COMPARE=1
|
||||
compare_firered_rev1: ; @$(MAKE) GAME_VERSION=FIRERED GAME_REVISION=1 COMPARE=1
|
||||
compare_firered_switch: ; @$(MAKE) GAME_VERSION=FIRERED GAME_REVISION=10 COMPARE=1
|
||||
compare_leafgreen: ; @$(MAKE) GAME_VERSION=LEAFGREEN COMPARE=1
|
||||
compare_leafgreen_rev1: ; @$(MAKE) GAME_VERSION=LEAFGREEN GAME_REVISION=1 COMPARE=1
|
||||
compare_leafgreen_switch:; @$(MAKE) GAME_VERSION=LEAFGREEN GAME_REVISION=10 COMPARE=1
|
||||
|
||||
firered_modern: ; @$(MAKE) GAME_VERSION=FIRERED MODERN=1
|
||||
firered_rev1_modern: ; @$(MAKE) GAME_VERSION=FIRERED GAME_REVISION=1 MODERN=1
|
||||
|
|
@ -348,16 +352,30 @@ endif
|
|||
$(OBJ_DIR)/sym_bss.ld: sym_bss.txt
|
||||
$(RAMSCRGEN) .bss $< ENGLISH > $@
|
||||
|
||||
$(OBJ_DIR)/sym_bss_rev10.ld: sym_bss_rev10.txt
|
||||
$(RAMSCRGEN) .bss $< ENGLISH > $@
|
||||
|
||||
$(OBJ_DIR)/sym_common.ld: sym_common.txt $(C_OBJS) $(wildcard common_syms/*.txt)
|
||||
$(RAMSCRGEN) COMMON $< ENGLISH -c $(C_BUILDDIR),common_syms > $@
|
||||
|
||||
$(OBJ_DIR)/sym_common_rev10.ld: sym_common_rev10.txt $(C_OBJS) $(wildcard common_syms/*.txt)
|
||||
$(RAMSCRGEN) COMMON $< ENGLISH -c $(C_BUILDDIR),common_syms > $@
|
||||
|
||||
$(OBJ_DIR)/sym_ewram.ld: sym_ewram.txt
|
||||
$(RAMSCRGEN) ewram_data $< ENGLISH > $@
|
||||
|
||||
$(OBJ_DIR)/sym_ewram_rev10.ld: sym_ewram_rev10.txt
|
||||
$(RAMSCRGEN) ewram_data $< ENGLISH > $@
|
||||
|
||||
# Linker script
|
||||
ifeq ($(MODERN),0)
|
||||
ifeq ($(GAME_REVISION),10)
|
||||
LD_SCRIPT := ld_script_rev10.ld
|
||||
LD_SCRIPT_DEPS := $(OBJ_DIR)/sym_bss_rev10.ld $(OBJ_DIR)/sym_common_rev10.ld $(OBJ_DIR)/sym_ewram_rev10.ld
|
||||
else
|
||||
LD_SCRIPT := ld_script.ld
|
||||
LD_SCRIPT_DEPS := $(OBJ_DIR)/sym_bss.ld $(OBJ_DIR)/sym_common.ld $(OBJ_DIR)/sym_ewram.ld
|
||||
endif
|
||||
else
|
||||
LD_SCRIPT := ld_script_modern.ld
|
||||
LD_SCRIPT_DEPS :=
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ It builds the following ROM images:
|
|||
* [**pokeleafgreen.gba**](https://datomatic.no-intro.org/?page=show_record&s=23&n=1617) `sha1: 574fa542ffebb14be69902d1d36f1ec0a4afd71e`
|
||||
* [**pokefirered_rev1.gba**](https://datomatic.no-intro.org/?page=show_record&s=23&n=1672) `sha1: dd5945db9b930750cb39d00c84da8571feebf417`
|
||||
* [**pokeleafgreen_rev1.gba**](https://datomatic.no-intro.org/index.php?page=show_record&s=23&n=1668) `sha1: 7862c67bdecbe21d1d69ce082ce34327e1c6ed5e`
|
||||
* [**pokefirered_switch.gba**](https://datomatic.no-intro.org/index.php?page=show_record&s=23&n=x550) `sha1: baa452d0b24629dd7782cfc07a8984085dde1311`
|
||||
* [**pokeleafgreen_switch.gba**](https://datomatic.no-intro.org/index.php?page=show_record&s=23&n=x551) `sha1: 62b9fc77549dbc67032eb6cbd0ea6ad3b825690f`
|
||||
|
||||
To set up the repository, see [INSTALL.md](INSTALL.md).
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@ ifeq ($(GAME_REVISION),1)
|
|||
BUILD_NAME := $(BUILD_NAME)_rev1
|
||||
endif
|
||||
|
||||
ifeq ($(GAME_REVISION),10)
|
||||
BUILD_NAME := $(BUILD_NAME)_switch
|
||||
endif
|
||||
|
||||
# Modern GCC
|
||||
ifeq ($(MODERN),1)
|
||||
BUILD_NAME := $(BUILD_NAME)_modern
|
||||
|
|
|
|||
|
|
@ -1664,7 +1664,11 @@ RisingWaterHitEffect:
|
|||
|
||||
Move_EXPLOSION:
|
||||
loadspritegfx ANIM_TAG_EXPLOSION
|
||||
.if REVISION >= 0xA
|
||||
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 8, 9, RGB(26, 8, 8), 8, RGB_BLACK, 5
|
||||
.else
|
||||
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 8, 9, RGB(26, 8, 8), 8, RGB_BLACK, 8
|
||||
.endif
|
||||
createvisualtask AnimTask_ShakeMon2, 5, 4, 8, 0, 40, 1
|
||||
createvisualtask AnimTask_ShakeMon2, 5, 5, 8, 0, 40, 1
|
||||
createvisualtask AnimTask_ShakeMon2, 5, 6, 8, 0, 40, 1
|
||||
|
|
|
|||
1
firered_switch.sha1
Normal file
1
firered_switch.sha1
Normal file
|
|
@ -0,0 +1 @@
|
|||
baa452d0b24629dd7782cfc07a8984085dde1311 pokefirered_switch.gba
|
||||
|
|
@ -23,8 +23,13 @@
|
|||
#define PCSWITCH_FORCE_SP_START 0x09
|
||||
|
||||
// Period for which parent-child switching search specified
|
||||
#if REVISION >= 0xA
|
||||
#define PCSWITCH_ALL_PERIOD 180 // Entire cycle 180 frames
|
||||
#define PCSWITCH_SP_PERIOD 65 // Child period 40 frames
|
||||
#else
|
||||
#define PCSWITCH_ALL_PERIOD 180 // Entire cycle 180 frames
|
||||
#define PCSWITCH_SP_PERIOD 40 // Child period 40 frames
|
||||
#endif
|
||||
|
||||
// Error code returned by Link Manager API (rfu_LMAN_...return value of function)
|
||||
#define LMAN_ERROR_MANAGER_BUSY 1 // Link Manager is already running.
|
||||
|
|
@ -165,6 +170,9 @@ typedef struct linkManagerTag
|
|||
/* 0x014 */ u16 param[2];
|
||||
/* 0x018 */ u16 NI_failCounter_limit;
|
||||
/* 0x01a */ u16 connect_period;
|
||||
#if REVISION >= 0xA
|
||||
/* 0x01c */ u16 connect_period_initial; // pushes next offsets up by 2
|
||||
#endif
|
||||
/* 0x01c */ u16 pcswitch_period_bak;
|
||||
/* 0x01e */ u16 work;
|
||||
/* 0x020 */ u16 *acceptable_serialNo_list;
|
||||
|
|
@ -190,6 +198,10 @@ u8 rfu_LMAN_setLinkRecovery(u8 enable_flag, u16 recovery_period);
|
|||
void rfu_LMAN_manager_entity(u32 rand);
|
||||
void rfu_LMAN_syncVBlank(void);
|
||||
u8 rfu_LMAN_initializeManager(void (*LMAN_callback_p)(u8, u8), void (*MSC_callback_p)(u16));
|
||||
#if REVISION >= 0xA
|
||||
void rfu_LMAN_forceChangeSP(bool8 child);
|
||||
#else
|
||||
void rfu_LMAN_forceChangeSP(void);
|
||||
#endif
|
||||
|
||||
#endif //GUARD_LINKMANAGER_H
|
||||
|
|
|
|||
|
|
@ -8,12 +8,17 @@
|
|||
// still has them in the ROM. This is because the developers forgot
|
||||
// to define NDEBUG before release, however this has been changed as
|
||||
// Ruby's actual debug build does not use the AGBPrint features.
|
||||
// #define NDEBUG
|
||||
|
||||
// Revision 10 disabled asserts in some other way, comment out NDEBUG there to bring them back.
|
||||
#if REVISION >= 0xA
|
||||
#define NDEBUG
|
||||
#endif
|
||||
|
||||
// Fire Red likely forgot to define NDEBUG/NOAGBPRN before release, leading
|
||||
// to the inclusion of asserts in the retail ROM.
|
||||
// Revision 10 disabled asserts in some other way, but isagbprint/etc is still present there.
|
||||
|
||||
#ifndef NDEBUG
|
||||
#if !defined(NDEBUG) || REVISION >= 0xA
|
||||
#define PRETTY_PRINT_OFF (0)
|
||||
#define PRETTY_PRINT_MINI_PRINTF (1)
|
||||
#define PRETTY_PRINT_LIBC (2)
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@
|
|||
// exceed RFU_CHILD_MAX (4), for a total of 5 including the player.
|
||||
#define MAX_UNION_ROOM_LEADERS 8
|
||||
|
||||
#define UNION_ROOM_SPAWN_NONE 0
|
||||
#define UNION_ROOM_SPAWN_IN 1
|
||||
#define UNION_ROOM_SPAWN_OUT 2
|
||||
#define UNION_ROOM_SPAWN_NONE 0
|
||||
#define UNION_ROOM_SPAWN_IN 1
|
||||
#define UNION_ROOM_SPAWN_OUT 2
|
||||
#define UNION_ROOM_SPAWN_OUT_SOON 3 // Equivalent to SPAWN_OUT in revision 10 - probably SPAWN_OUT means disconnected in a "connection reset" way?
|
||||
|
||||
#define UNION_ROOM_MAX_LEVEL 30
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#define MGBA_LOG_INFO (3)
|
||||
#define MGBA_LOG_DEBUG (4)
|
||||
|
||||
#ifdef NDEBUG
|
||||
#if defined(NDEBUG) && !(REVISION >= 0xA)
|
||||
#define DebugPrintf(pBuf, ...)
|
||||
#define DebugPrintfLevel(level, pBuf, ...)
|
||||
#define MgbaOpen()
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
|
||||
#if REVISION >= 0xA
|
||||
#define LIBRFU_VERSION 1028
|
||||
#else
|
||||
#define LIBRFU_VERSION 1024
|
||||
#endif
|
||||
|
||||
/* TODOs:
|
||||
* - documentation
|
||||
|
|
|
|||
|
|
@ -294,6 +294,7 @@ bool32 WaitRfuState(bool32 force);
|
|||
bool32 HasTrainerLeftPartnersList(u16 trainerId, const u8 *trainerName);
|
||||
void SendRfuStatusToPartner(u8 status, u16 trainerId, const u8 *name);
|
||||
u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name);
|
||||
s32 GetJoinGroupStatus(void);
|
||||
void SetHostRfuGameData(u8 activity, u32 partnerInfo, bool32 startedActivity);
|
||||
void InitializeRfuLinkManager_LinkLeader(u32 availSlots);
|
||||
void RequestDisconnectSlotByTrainerNameAndId(const u8 *trainerName, u16 trainerId);
|
||||
|
|
@ -322,6 +323,17 @@ void RfuSetNormalDisconnectMode(void);
|
|||
void SetUnionRoomChatPlayerData(u32 numPlayers);
|
||||
void ClearRecvCommands(void);
|
||||
|
||||
void PkmnStrToASCII(u8 *dest, const u8 *src);
|
||||
void ASCIIToPkmnStr(u8 *dest, const u8 *src);
|
||||
|
||||
#if REVISION >= 0xA
|
||||
u16 RfuGetErrorInfo(void);
|
||||
void LinkRfu_ForceChangeSpParent(void);
|
||||
void DestroyTask_RfuReconnectWithParent(void);
|
||||
void RfuReloadSave(void);
|
||||
void RfuSoftReset(void);
|
||||
#endif
|
||||
|
||||
#include "mystery_gift_server.h"
|
||||
extern const struct MysteryGiftServerCmd gServerScript_ClientCanceledCard[];
|
||||
|
||||
|
|
|
|||
|
|
@ -180,6 +180,10 @@ void UpdateEscapeWarp(s16 x, s16 y);
|
|||
bool8 SetDiveWarpEmerge(u16 x, u16 y);
|
||||
bool8 SetDiveWarpDive(u16 x, u16 y);
|
||||
|
||||
#if REVISION >= 0xA
|
||||
void ClearFieldCallback(void);
|
||||
#endif
|
||||
|
||||
extern u16 *gBGTilemapBuffers1;
|
||||
extern u16 *gBGTilemapBuffers2;
|
||||
extern u16 *gBGTilemapBuffers3;
|
||||
|
|
|
|||
36
include/sloopsvc.h
Normal file
36
include/sloopsvc.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef GUARD_SLOOPSVC_H
|
||||
#define GUARD_SLOOPSVC_H
|
||||
|
||||
#if REVISION >= 0xA
|
||||
|
||||
#define SVC4B_EXIT_EARLY (1 << 0)
|
||||
#define SVC4B_RESEED_RNG (1 << 1)
|
||||
|
||||
void svc_40(void);
|
||||
void svc_41(void);
|
||||
|
||||
void svc_47(void);
|
||||
void svc_42(void);
|
||||
u32 svc_49(void);
|
||||
void svc_45_rfu_link_status(void);
|
||||
u32 svc_4a(void);
|
||||
void svc_43(u16 pid);
|
||||
void svc_44(void);
|
||||
u32 svc_53(void);
|
||||
u32 svc_51(void);
|
||||
u32 svc_4b(void);
|
||||
void svc_WriteSector(u8 sector, u8* data);
|
||||
void svc_ReplaceSector(u8 sector, u8* data);
|
||||
void svc_FinishSave(void);
|
||||
u32 svc_CommsAllowedByParentalControls(void);
|
||||
u32 svc_BadWordCheck(u8* str);
|
||||
void svc_4f(u32 arg);
|
||||
u32 svc_50(void);
|
||||
void svc_SetSaveBlock2(struct SaveBlock2* saveBlock2);
|
||||
void svc_stubbed(void);
|
||||
void svc_SetStarter(u32 species);
|
||||
void svc_SetActivity(u32 activity);
|
||||
void svc_IncrementLinkError(void);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -64,6 +64,7 @@ SECTIONS {
|
|||
src/window_8bpp.o(.text);
|
||||
src/text.o(.text);
|
||||
src/sprite.o(.text);
|
||||
src/sloopsvc.o(.text);
|
||||
src/string_util.o(.text);
|
||||
src/link.o(.text);
|
||||
src/multiboot.o(.text);
|
||||
|
|
@ -405,6 +406,7 @@ SECTIONS {
|
|||
src/text.o(.rodata);
|
||||
src/sprite.o(.rodata);
|
||||
src/bg_regs.o(.rodata);
|
||||
src/sloopsvc.o(.rodata);
|
||||
src/string_util.o(.rodata);
|
||||
src/link.o(.rodata);
|
||||
src/main_menu.o(.rodata);
|
||||
|
|
|
|||
1062
ld_script_rev10.ld
Normal file
1062
ld_script_rev10.ld
Normal file
File diff suppressed because it is too large
Load Diff
1
leafgreen_switch.sha1
Normal file
1
leafgreen_switch.sha1
Normal file
|
|
@ -0,0 +1 @@
|
|||
62b9fc77549dbc67032eb6cbd0ea6ad3b825690f pokeleafgreen_switch.gba
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
#include "global.h"
|
||||
#include "librfu.h"
|
||||
#include "AgbRfu_LinkManager.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
#define RN_ACCEPT 0x01
|
||||
#define RN_NAME_TIMER_CLEAR 0x02
|
||||
|
|
@ -176,6 +177,9 @@ u8 rfu_LMAN_establishConnection(u8 parent_child, u16 connect_period, u16 name_ac
|
|||
}
|
||||
lman.parent_child = parent_child;
|
||||
lman.connect_period = connect_period;
|
||||
#if REVISION >= 0xA
|
||||
lman.connect_period_initial = 0;
|
||||
#endif
|
||||
lman.nameAcceptTimer.count_max = name_accept_period;
|
||||
lman.acceptable_serialNo_list = acceptable_serialNo_list;
|
||||
return 0;
|
||||
|
|
@ -222,6 +226,9 @@ u8 rfu_LMAN_CHILD_connectParent(u16 parentId, u16 connect_period)
|
|||
}
|
||||
lman.work = parentId;
|
||||
lman.connect_period = connect_period;
|
||||
#if REVISION >= 0xA
|
||||
lman.connect_period_initial = 0;
|
||||
#endif
|
||||
if (lman.pcswitch_flag != 0)
|
||||
{
|
||||
lman.pcswitch_flag = PCSWITCH_CP;
|
||||
|
|
@ -560,6 +567,9 @@ static void rfu_LMAN_settingPCSWITCH(u32 rand)
|
|||
lman.parent_child = MODE_PARENT;
|
||||
lman.state = LMAN_STATE_START_SEARCH_CHILD;
|
||||
lman.connect_period = lman.pcswitch_period_bak;
|
||||
#if REVISION >= 0xA
|
||||
lman.connect_period_initial = 0;
|
||||
#endif
|
||||
if (lman.connect_period)
|
||||
{
|
||||
lman.pcswitch_flag = PCSWITCH_3RD_SC;
|
||||
|
|
@ -573,8 +583,14 @@ static void rfu_LMAN_settingPCSWITCH(u32 rand)
|
|||
{
|
||||
lman.parent_child = MODE_PARENT;
|
||||
lman.state = LMAN_STATE_START_SEARCH_CHILD;
|
||||
#if REVISION >= 0xA
|
||||
lman.connect_period = rand % 285;
|
||||
lman.pcswitch_period_bak = 285 - lman.connect_period;
|
||||
lman.connect_period_initial = 0;
|
||||
#else
|
||||
lman.connect_period = rand % 140;
|
||||
lman.pcswitch_period_bak = 140 - lman.connect_period;
|
||||
#endif
|
||||
if (lman.connect_period)
|
||||
{
|
||||
lman.pcswitch_flag = PCSWITCH_1ST_SC;
|
||||
|
|
@ -588,6 +604,9 @@ static void rfu_LMAN_settingPCSWITCH(u32 rand)
|
|||
{
|
||||
lman.parent_child = MODE_CHILD;
|
||||
lman.connect_period = PCSWITCH_SP_PERIOD;
|
||||
#if REVISION >= 0xA
|
||||
lman.connect_period_initial = 0;
|
||||
#endif
|
||||
lman.pcswitch_flag = PCSWITCH_2ND_SP;
|
||||
lman.state = LMAN_STATE_START_SEARCH_PARENT;
|
||||
}
|
||||
|
|
@ -632,11 +651,27 @@ static void rfu_LMAN_REQ_callback(u16 reqCommandId, u16 reqResult)
|
|||
}
|
||||
break;
|
||||
case ID_SC_POLL_REQ:
|
||||
#if REVISION >= 0xA
|
||||
if (lman.connect_period)
|
||||
{
|
||||
if (svc_49() != 0 && lman.connect_period_initial < 300)
|
||||
{
|
||||
if (lman.connect_period > 1) lman.connect_period--;
|
||||
else lman.connect_period_initial++;
|
||||
}
|
||||
else if (--lman.connect_period == 0)
|
||||
{
|
||||
lman.state = LMAN_STATE_END_SEARCH_CHILD;
|
||||
lman.next_state = LMAN_STATE_WAIT_RECV_CHILD_NAME;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (lman.connect_period && --lman.connect_period == 0)
|
||||
{
|
||||
lman.state = LMAN_STATE_END_SEARCH_CHILD;
|
||||
lman.next_state = LMAN_STATE_WAIT_RECV_CHILD_NAME;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ID_SC_END_REQ:
|
||||
if (reqResult == 0)
|
||||
|
|
@ -679,11 +714,27 @@ static void rfu_LMAN_REQ_callback(u16 reqCommandId, u16 reqResult)
|
|||
lman.fastSearchParent_flag = FSP_ON;
|
||||
}
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
if (lman.connect_period)
|
||||
{
|
||||
if (svc_4a() != 0 && lman.connect_period_initial < 300)
|
||||
{
|
||||
if (lman.connect_period > 1) lman.connect_period--;
|
||||
else lman.connect_period_initial++;
|
||||
}
|
||||
else if (--lman.connect_period == 0)
|
||||
{
|
||||
lman.state = LMAN_STATE_END_SEARCH_PARENT;
|
||||
lman.next_state = LMAN_STATE_READY;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (lman.connect_period && --lman.connect_period == 0)
|
||||
{
|
||||
lman.state = LMAN_STATE_END_SEARCH_PARENT;
|
||||
lman.next_state = LMAN_STATE_READY;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ID_SP_END_REQ:
|
||||
if (reqResult == 0)
|
||||
|
|
@ -1302,15 +1353,30 @@ static void rfu_LMAN_setLMANCallback(void (*func)(u8, u8))
|
|||
|
||||
u8 rfu_LMAN_setLinkRecovery(u8 enable_flag, u16 recovery_period)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
u16 imeNew = 0;
|
||||
#endif
|
||||
u16 imeBak;
|
||||
#if REVISION >= 0xA
|
||||
|
||||
imeBak = REG_IME;
|
||||
REG_IME = imeNew;
|
||||
|
||||
lman.linkRecovery_enable = FALSE;
|
||||
lman.linkRecoveryTimer.count_max = recovery_period;
|
||||
#else
|
||||
|
||||
if (lman.linkRecovery_enable && enable_flag == 0 && lman.linkRecoveryTimer.active)
|
||||
{
|
||||
return LMAN_ERROR_NOW_LINK_RECOVERY;
|
||||
}
|
||||
|
||||
imeBak = REG_IME;
|
||||
REG_IME = 0;
|
||||
|
||||
lman.linkRecovery_enable = enable_flag;
|
||||
lman.linkRecoveryTimer.count_max = recovery_period;
|
||||
#endif
|
||||
REG_IME = imeBak;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1367,7 +1433,11 @@ void rfu_LMAN_requestChangeAgbClockMaster(void)
|
|||
}
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
void rfu_LMAN_forceChangeSP(bool8 child)
|
||||
#else
|
||||
void rfu_LMAN_forceChangeSP(void)
|
||||
#endif
|
||||
{
|
||||
if (lman.pcswitch_flag)
|
||||
{
|
||||
|
|
@ -1387,10 +1457,22 @@ void rfu_LMAN_forceChangeSP(void)
|
|||
break;
|
||||
case LMAN_STATE_START_SEARCH_PARENT:
|
||||
case LMAN_STATE_POLL_SEARCH_PARENT:
|
||||
#if REVISION >= 0xA
|
||||
if (!child) break;
|
||||
#endif
|
||||
lman.connect_period = PCSWITCH_SP_PERIOD;
|
||||
#if REVISION >= 0xA
|
||||
lman.connect_period_initial = 0;
|
||||
#endif
|
||||
break;
|
||||
case LMAN_STATE_END_SEARCH_PARENT:
|
||||
#if REVISION >= 0xA
|
||||
if (!child) break;
|
||||
#endif
|
||||
lman.connect_period = PCSWITCH_SP_PERIOD;
|
||||
#if REVISION >= 0xA
|
||||
lman.connect_period_initial = 0;
|
||||
#endif
|
||||
lman.state = LMAN_STATE_POLL_SEARCH_PARENT;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -819,10 +819,16 @@ static void SetLinkBattleEndCallbacks(void)
|
|||
|
||||
void SetBattleEndCallbacks(void)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
if (!gPaletteFade.active)
|
||||
#endif
|
||||
{
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
if (!IsLinkTaskFinished() || gPaletteFade.active) return;
|
||||
#endif
|
||||
if (gWirelessCommType == 0)
|
||||
SetCloseLinkCallback();
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1160,7 +1160,11 @@ static void CB2_PreInitMultiBattle(void)
|
|||
}
|
||||
break;
|
||||
case 2:
|
||||
#if REVISION >= 0xA
|
||||
if (IsLinkTaskFinished() && !gPaletteFade.active)
|
||||
#else
|
||||
if (!gPaletteFade.active)
|
||||
#endif
|
||||
{
|
||||
gBattleCommunication[MULTIUSE_STATE]++;
|
||||
if (gWirelessCommType)
|
||||
|
|
@ -3923,8 +3927,8 @@ static void ReturnFromBattleToOverworld(void)
|
|||
if (gBattleTypeFlags & BATTLE_TYPE_ROAMER)
|
||||
{
|
||||
UpdateRoamerHPStatus(&gEnemyParty[0]);
|
||||
#ifdef BUGFIX
|
||||
if ((gBattleOutcome == B_OUTCOME_WON) || gBattleOutcome == B_OUTCOME_CAUGHT)
|
||||
#if defined(BUGFIX) || REVISION >= 0xA
|
||||
if ((gBattleOutcome == B_OUTCOME_WON) || gBattleOutcome == B_OUTCOME_CAUGHT || gBattleOutcome == B_OUTCOME_DREW)
|
||||
#else
|
||||
if ((gBattleOutcome & B_OUTCOME_WON) || gBattleOutcome == B_OUTCOME_CAUGHT) // Bug: When Roar is used by roamer, gBattleOutcome is B_OUTCOME_PLAYER_TELEPORTED (5).
|
||||
#endif // & with B_OUTCOME_WON (1) will return TRUE and deactivates the roamer.
|
||||
|
|
|
|||
|
|
@ -1789,10 +1789,17 @@ static const u8 *TryGetStatusString(u8 *src)
|
|||
u8 *statusPtr;
|
||||
|
||||
statusPtr = status;
|
||||
#if REVISION >= 0xA
|
||||
for (i = 0; i < 8 && *src != EOS; i++)
|
||||
#else
|
||||
for (i = 0; i < 8; i++)
|
||||
#endif
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
if (*src == EOS)
|
||||
break;
|
||||
#endif
|
||||
*statusPtr = *src;
|
||||
src++;
|
||||
statusPtr++;
|
||||
|
|
|
|||
|
|
@ -718,6 +718,9 @@ static void Task_StartWirelessCableClubBattle(u8 taskId)
|
|||
tState = 5;
|
||||
break;
|
||||
case 5:
|
||||
#if REVISION >= 0xA
|
||||
if (!IsLinkTaskFinished()) break;
|
||||
#endif
|
||||
SetLinkStandbyCallback();
|
||||
tState = 6;
|
||||
break;
|
||||
|
|
@ -920,6 +923,9 @@ static void Task_StartWirelessTrade(u8 taskId)
|
|||
tState++;
|
||||
break;
|
||||
case 2:
|
||||
#if REVISION >= 0xA
|
||||
if (!IsLinkTaskFinished()) break;
|
||||
#endif
|
||||
gSelectedTradeMonPositions[TRADE_PLAYER] = 0;
|
||||
gSelectedTradeMonPositions[TRADE_PARTNER] = 0;
|
||||
m4aMPlayAllStop();
|
||||
|
|
@ -996,7 +1002,11 @@ bool32 GetSeeingLinkPlayerCardMsg(u8 linkPlayerIndex)
|
|||
void Task_WaitForLinkPlayerConnection(u8 taskId)
|
||||
{
|
||||
struct Task *task = &gTasks[taskId];
|
||||
#if REVISION >= 0xA
|
||||
if (++task->tTimer > 480)
|
||||
#else
|
||||
if (++task->tTimer > 300)
|
||||
#endif
|
||||
{
|
||||
CloseLink();
|
||||
SetMainCallback2(CB2_LinkError);
|
||||
|
|
|
|||
|
|
@ -1495,10 +1495,18 @@ static bool8 GetAvailableObjectEventId(u16 localId, u8 mapNum, u8 mapGroup, u8 *
|
|||
{
|
||||
u8 i = 0;
|
||||
|
||||
#if REVISION >= 0xA
|
||||
for (i = 0; i < OBJECT_EVENTS_COUNT && gObjectEvents[i].active; i++)
|
||||
#else
|
||||
for (i = 0; i < OBJECT_EVENTS_COUNT; i++)
|
||||
#endif
|
||||
{
|
||||
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
if (!gObjectEvents[i].active)
|
||||
break;
|
||||
#endif
|
||||
if (gObjectEvents[i].localId == localId && gObjectEvents[i].mapNum == mapNum && gObjectEvents[i].mapGroup == mapGroup)
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,6 +207,9 @@ static void Task_ReturnToFieldRecordMixing(u8 taskId)
|
|||
switch (task->data[0])
|
||||
{
|
||||
case 0:
|
||||
#if REVISION >= 0xA
|
||||
if (!IsLinkTaskFinished()) break;
|
||||
#endif
|
||||
SetLinkStandbyCallback();
|
||||
task->data[0]++;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,11 @@ static void Task_FieldPoisonEffect(u8 taskId)
|
|||
switch (data[0])
|
||||
{
|
||||
case 0:
|
||||
#if REVISION >= 0xA
|
||||
data[1] += 2;
|
||||
#else
|
||||
data[1] += 1;
|
||||
#endif
|
||||
if (data[1] > 4)
|
||||
data[0]++;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -922,7 +922,12 @@ static bool8 SetUpCopyrightScreen(void)
|
|||
SetGpuReg(REG_OFFSET_BLDCNT, 0);
|
||||
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
|
||||
SetGpuReg(REG_OFFSET_BLDY, 0);
|
||||
// "Fade from white" instead is just pure black in Revision 10.
|
||||
#if REVISION >= 0xA
|
||||
((vu16*)PLTT)[0] = RGB_BLACK;
|
||||
#else
|
||||
((vu16*)PLTT)[0] = RGB_WHITE;
|
||||
#endif
|
||||
SetGpuReg(REG_OFFSET_DISPCNT, 0);
|
||||
SetGpuReg(REG_OFFSET_BG0HOFS, 0);
|
||||
SetGpuReg(REG_OFFSET_BG0VOFS, 0);
|
||||
|
|
@ -935,7 +940,11 @@ static bool8 SetUpCopyrightScreen(void)
|
|||
ResetTasks();
|
||||
ResetSpriteData();
|
||||
FreeAllSpritePalettes();
|
||||
#if REVISION >= 0xA
|
||||
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
|
||||
#else
|
||||
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_WHITEALPHA);
|
||||
#endif
|
||||
SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(7));
|
||||
EnableInterrupts(INTR_FLAG_VBLANK);
|
||||
SetVBlankCallback(VBlankCB_Copyright);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ struct AGBPrintStruct
|
|||
|
||||
typedef void (*LPFN_PRINT_FLUSH)(void);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Revision 10 still has this code present, despite only the init function ever being used.
|
||||
#if !defined(NDEBUG) || REVISION >= 0xA
|
||||
|
||||
// AGBPrint print functions
|
||||
#if (LOG_HANDLER == LOG_HANDLER_AGB_PRINT)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include <limits.h>
|
||||
#include "librfu.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
struct LLSFStruct
|
||||
{
|
||||
|
|
@ -381,6 +382,9 @@ void rfu_REQ_stopMode(void)
|
|||
REG_SIOCNT = SIO_MULTI_MODE;
|
||||
rfu_STC_REQ_callback(ID_STOP_MODE_REQ, 0);
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
svc_44();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -461,6 +465,9 @@ void rfu_REQ_configGameData(u8 mbootFlag, u16 serialNo, const u8 *gname, const u
|
|||
packet[14] = 0;
|
||||
STWI_set_Callback_M(rfu_CB_configGameData);
|
||||
STWI_send_GameConfigREQ(packet, uname);
|
||||
#if REVISION >= 0xA
|
||||
svc_47();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rfu_CB_configGameData(u8 reqCommand, u16 reqResult)
|
||||
|
|
@ -519,6 +526,9 @@ void rfu_REQ_startSearchChild(void)
|
|||
}
|
||||
STWI_set_Callback_M(rfu_CB_startSearchChild);
|
||||
STWI_send_SC_StartREQ();
|
||||
#if REVISION >= 0xA
|
||||
svc_42();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rfu_CB_startSearchChild(u8 reqCommand, u16 reqResult)
|
||||
|
|
@ -630,7 +640,11 @@ static void rfu_STC_readChildList(void)
|
|||
gRfuStatic->cidBak[bm_slot_id] = gRfuLinkStatus->partner[bm_slot_id].id;
|
||||
}
|
||||
#else
|
||||
#if REVISION >= 0xA
|
||||
gRfuStatic->lsFixedCount[bm_slot_id] = 0x3C;
|
||||
#else
|
||||
gRfuStatic->lsFixedCount[bm_slot_id] = 0xF0;
|
||||
#endif
|
||||
gRfuLinkStatus->strength[bm_slot_id] = 16;
|
||||
gRfuLinkStatus->connSlotFlag |= 1 << bm_slot_id;
|
||||
++gRfuLinkStatus->connCount;
|
||||
|
|
@ -649,6 +663,9 @@ void rfu_REQ_startSearchParent(void)
|
|||
{
|
||||
STWI_set_Callback_M(rfu_CB_startSearchParent);
|
||||
STWI_send_SP_StartREQ();
|
||||
#if REVISION >= 0xA
|
||||
svc_45_rfu_link_status();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rfu_CB_startSearchParent(u8 reqCommand, u16 reqResult)
|
||||
|
|
@ -703,8 +720,13 @@ static void rfu_STC_readParentCandidateList(void)
|
|||
}
|
||||
if (my_check_sum == check_sum)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
target = &gRfuLinkStatus->partner[gRfuLinkStatus->findParentCount];
|
||||
packet_p -= 28;
|
||||
#else
|
||||
packet_p -= 28;
|
||||
target = &gRfuLinkStatus->partner[gRfuLinkStatus->findParentCount];
|
||||
#endif
|
||||
target->id = *(u16 *)packet_p;
|
||||
packet_p += 2;
|
||||
target->slot = *packet_p;
|
||||
|
|
@ -723,6 +745,9 @@ static void rfu_STC_readParentCandidateList(void)
|
|||
++gRfuLinkStatus->findParentCount;
|
||||
}
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
svc_45_rfu_link_status();
|
||||
#endif
|
||||
}
|
||||
|
||||
void rfu_REQ_startConnectParent(u16 pid)
|
||||
|
|
@ -738,6 +763,9 @@ void rfu_REQ_startConnectParent(u16 pid)
|
|||
gRfuStatic->tryPid = pid;
|
||||
STWI_set_Callback_M(rfu_STC_REQ_callback);
|
||||
STWI_send_CP_StartREQ(pid);
|
||||
#if REVISION >= 0xA
|
||||
svc_43(pid);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -756,7 +784,11 @@ static void rfu_CB_pollConnectParent(u8 reqCommand, u16 reqResult)
|
|||
u16 id;
|
||||
u8 slot;
|
||||
u8 bm_slot_flag, i;
|
||||
#if REVISION >= 0xA
|
||||
struct RfuTgtData *target_p = NULL;
|
||||
#else
|
||||
struct RfuTgtData *target_p;
|
||||
#endif
|
||||
struct RfuTgtData target_local;
|
||||
|
||||
if (reqResult == 0)
|
||||
|
|
@ -1392,7 +1424,11 @@ static u16 rfu_STC_setSendData_org(u8 ni_or_uni, u8 bmSendSlot, u8 subFrameSize,
|
|||
{
|
||||
u8 bm_slot_id, sendSlotFlag;
|
||||
u8 frameSize;
|
||||
#if REVISION >= 0xA
|
||||
u8 *llFrameSize_p = NULL;
|
||||
#else
|
||||
u8 *llFrameSize_p;
|
||||
#endif
|
||||
u8 sending;
|
||||
u8 i;
|
||||
u16 imeBak;
|
||||
|
|
|
|||
100
src/link.c
100
src/link.c
|
|
@ -24,6 +24,7 @@
|
|||
#include "reset_save_heap.h"
|
||||
#include "constants/battle.h"
|
||||
#include "constants/songs.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
extern u16 gHeldKeyCodeToSend;
|
||||
|
||||
|
|
@ -67,7 +68,10 @@ COMMON_DATA u32 gLinkDebugSeed = 0;
|
|||
COMMON_DATA struct LinkPlayerBlock gLocalLinkPlayerBlock = {0};
|
||||
COMMON_DATA bool8 gLinkErrorOccurred = 0;
|
||||
COMMON_DATA u32 gLinkDebugFlags = 0;
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
COMMON_DATA u32 gLinkFiller1 = 0;
|
||||
#endif
|
||||
COMMON_DATA bool8 gRemoteLinkPlayersNotReceived[MAX_LINK_PLAYERS] = {0};
|
||||
COMMON_DATA u8 gBlockReceivedStatus[MAX_LINK_PLAYERS] = {0};
|
||||
COMMON_DATA u32 gLinkFiller2 = 0;
|
||||
|
|
@ -85,14 +89,21 @@ COMMON_DATA u8 gSavedLinkPlayerCount = 0;
|
|||
COMMON_DATA u16 gSendCmd[CMD_LENGTH] = {0};
|
||||
COMMON_DATA u8 gSavedMultiplayerId = 0;
|
||||
COMMON_DATA bool8 gReceivedRemoteLinkPlayers = 0;
|
||||
#if REVISION >= 0xA
|
||||
// all references to this are gone anyway
|
||||
#else
|
||||
COMMON_DATA struct LinkTestBGInfo gLinkTestBGInfo = {0};
|
||||
#endif
|
||||
COMMON_DATA void (*gLinkCallback)(void) = NULL;
|
||||
COMMON_DATA u8 gShouldAdvanceLinkState = 0;
|
||||
COMMON_DATA u16 gLinkTestBlockChecksums[MAX_LINK_PLAYERS] = {0};
|
||||
COMMON_DATA u8 gBlockRequestType = 0;
|
||||
COMMON_DATA u32 gLinkFiller3 = 0; // file
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
COMMON_DATA u32 gLinkFiller4 = 0; // boundary
|
||||
COMMON_DATA u32 gLinkFiller5 = 0; // here?
|
||||
#endif
|
||||
COMMON_DATA u8 gLastSendQueueCount = 0;
|
||||
COMMON_DATA struct Link gLink = {0};
|
||||
COMMON_DATA u8 gLastRecvQueueCount = 0;
|
||||
|
|
@ -118,6 +129,9 @@ EWRAM_DATA struct {
|
|||
static EWRAM_DATA u16 sReadyCloseLinkAttempts = 0; // never read
|
||||
static EWRAM_DATA void *sLinkErrorBgTilemapBuffer = NULL;
|
||||
|
||||
void Task_WirelessCommunicationScreen(u8 taskId);
|
||||
void Task_MysteryGift(u8 taskId);
|
||||
|
||||
static void InitLocalLinkPlayer(void);
|
||||
static void VBlankCB_LinkError(void);
|
||||
static void CB2_LinkTest(void);
|
||||
|
|
@ -131,7 +145,6 @@ static void LinkCB_BlockSendEnd(void);
|
|||
static void SetBerryBlenderLinkCallback(void);
|
||||
static void SetBlockReceivedFlag(u8 id);
|
||||
static u16 LinkTestCalcBlockChecksum(const u16 *src, u16 size);
|
||||
static void LinkTest_PrintHex(u32 pos, u8 a0, u8 a1, u8 a2);
|
||||
static void LinkCB_RequestPlayerDataExchange(void);
|
||||
static void Task_PrintTestData(u8 taskId);
|
||||
static void LinkCB_ReadyCloseLink(void);
|
||||
|
|
@ -155,11 +168,19 @@ static void DoSend(void);
|
|||
static void StopTimer(void);
|
||||
static void SendRecvDone(void);
|
||||
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
static void LinkTest_PrintHex(u32 pos, u8 a0, u8 a1, u8 a2);
|
||||
#endif
|
||||
|
||||
static const u16 sWirelessLinkDisplayPal[] = INCBIN_U16("graphics/link/wireless_display.gbapal");
|
||||
static const u16 sWirelessLinkDisplayGfx[] = INCBIN_U16("graphics/link/wireless_display.4bpp.lz");
|
||||
static const u16 sWirelessLinkDisplayTilemap[] = INCBIN_U16("graphics/link/wireless_display.bin.lz");
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
static const u16 sLinkTestFontPal[] = INCBIN_U16("graphics/link/test_font.gbapal");
|
||||
static const u16 sLinkTestFontGfx[] = INCBIN_U16("graphics/link/test_font.4bpp");
|
||||
#endif
|
||||
|
||||
static const struct BlockRequest sBlockRequests[] = {
|
||||
[BLOCK_REQ_SIZE_NONE] = { gBlockSendBuffer, 200 },
|
||||
|
|
@ -169,7 +190,11 @@ static const struct BlockRequest sBlockRequests[] = {
|
|||
[BLOCK_REQ_SIZE_40] = { gBlockSendBuffer, 40 }
|
||||
};
|
||||
static const char sASCIIGameFreakInc[] = "GameFreak inc.";
|
||||
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
static const char sASCIITestPrint[] = "TEST PRINT\nP0\nP1\nP2\nP3";
|
||||
#endif
|
||||
|
||||
static const struct BgTemplate sLinkErrorBgTemplates[] = {
|
||||
{
|
||||
|
|
@ -240,6 +265,9 @@ void Task_DestroySelf(u8 taskId)
|
|||
DestroyTask(taskId);
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
// Gone in this rev.
|
||||
#else
|
||||
void InitLinkTestBG(u8 paletteNum, u8 bgNum, u8 screenBaseBlock, u8 charBaseBlock, u16 baseChar)
|
||||
{
|
||||
LoadPalette(sLinkTestFontPal, BG_PLTT_ID(paletteNum), PLTT_SIZE_4BPP);
|
||||
|
|
@ -273,6 +301,7 @@ static void LoadLinkTestBgGfx(u8 paletteNum, u8 bgNum, u8 screenBaseBlock, u8 ch
|
|||
gLinkTestBGInfo.baseChar = 0;
|
||||
SetGpuReg(gBGControlRegOffsets[bgNum], BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_CHARBASE(charBaseBlock));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Unused
|
||||
static void LinkTestScreen(void)
|
||||
|
|
@ -290,7 +319,10 @@ static void LinkTestScreen(void)
|
|||
for (i = 0; i < TRAINER_ID_LENGTH; i++)
|
||||
gSaveBlock2Ptr->playerTrainerId[i] = Random() % 256;
|
||||
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
InitLinkTestBG(0, 2, 4, 0, 0);
|
||||
#endif
|
||||
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_ON);
|
||||
CreateTask(Task_DestroySelf, 0);
|
||||
RunTasks();
|
||||
|
|
@ -400,14 +432,20 @@ static void TestBlockTransfer(u8 unused0, u8 unused1, u8 unused2)
|
|||
|
||||
if (sLinkTestLastBlockSendPos != sBlockSend.pos)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
LinkTest_PrintHex(sBlockSend.pos, 2, 3, 2);
|
||||
#endif
|
||||
sLinkTestLastBlockSendPos = sBlockSend.pos;
|
||||
}
|
||||
for (i = 0; i < MAX_LINK_PLAYERS; i++)
|
||||
{
|
||||
if (sLinkTestLastBlockRecvPos[i] != sBlockRecv[i].pos)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
LinkTest_PrintHex(sBlockRecv[i].pos, 2, i + 4, 2);
|
||||
#endif
|
||||
sLinkTestLastBlockRecvPos[i] = sBlockRecv[i].pos;
|
||||
}
|
||||
}
|
||||
|
|
@ -450,8 +488,11 @@ static void LinkTestProcessKeyInput(void)
|
|||
if (JOY_NEW(SELECT_BUTTON))
|
||||
SetCloseLinkCallback();
|
||||
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
if (sLinkTestDebugValuesEnabled)
|
||||
SetLinkDebugValues(gMain.vblankCounter2, gLinkCallback ? gLinkVSyncDisabled : gLinkVSyncDisabled | 0x10);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void CB2_LinkTest(void)
|
||||
|
|
@ -1025,6 +1066,8 @@ static u16 LinkTestCalcBlockChecksum(const u16 *src, u16 size)
|
|||
return checksum;
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
static void LinkTest_PrintNumChar(char val, u8 x, u8 y)
|
||||
{
|
||||
u16 *vAddr;
|
||||
|
|
@ -1080,6 +1123,7 @@ static void LinkTest_PrintString(const char *str, u8 x, u8 y)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void LinkCB_RequestPlayerDataExchange(void)
|
||||
{
|
||||
|
|
@ -1091,6 +1135,9 @@ static void LinkCB_RequestPlayerDataExchange(void)
|
|||
|
||||
static void Task_PrintTestData(u8 taskId)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
// This function performs no operation in this revision.
|
||||
#else
|
||||
char testTitle[32];
|
||||
int i;
|
||||
|
||||
|
|
@ -1113,13 +1160,17 @@ static void Task_PrintTestData(u8 taskId)
|
|||
|
||||
for (i = 0; i < MAX_LINK_PLAYERS; i++)
|
||||
LinkTest_PrintHex(gLinkTestBlockChecksums[i], 10, 4 + i, 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
void SetLinkDebugValues(u32 seed, u32 flags)
|
||||
{
|
||||
gLinkDebugSeed = seed;
|
||||
gLinkDebugFlags = flags;
|
||||
}
|
||||
#endif
|
||||
|
||||
u8 GetSavedLinkPlayerCountAsBitFlags(void)
|
||||
{
|
||||
|
|
@ -1374,6 +1425,9 @@ void CB2_LinkError(void)
|
|||
{
|
||||
u8 *tilemapBuffer;
|
||||
|
||||
#if REVISION >= 0xA
|
||||
ClearFieldCallback();
|
||||
#endif
|
||||
SetGpuReg(REG_OFFSET_DISPCNT, 0);
|
||||
m4aMPlayStop(&gMPlayInfo_SE1);
|
||||
m4aMPlayStop(&gMPlayInfo_SE2);
|
||||
|
|
@ -1387,8 +1441,11 @@ void CB2_LinkError(void)
|
|||
ScanlineEffect_Stop();
|
||||
if (gWirelessCommType)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
if (!sLinkErrorBuffer.disconnected)
|
||||
gWirelessCommType = 3;
|
||||
#endif
|
||||
|
||||
ResetLinkRfuGFLayer();
|
||||
}
|
||||
|
|
@ -1457,7 +1514,15 @@ static void CB2_PrintErrorMessage(void)
|
|||
case 0:
|
||||
// Below is only true for the RFU, so the other error
|
||||
// type is inferred to be from a wired connection
|
||||
#if REVISION >= 0xA
|
||||
svc_IncrementLinkError();
|
||||
#endif
|
||||
|
||||
#if REVISION >= 0xA
|
||||
if (sLinkErrorBuffer.disconnected || gWirelessCommType != 0)
|
||||
#else
|
||||
if (sLinkErrorBuffer.disconnected)
|
||||
#endif
|
||||
ErrorMsg_MoveCloserToPartner();
|
||||
else
|
||||
ErrorMsg_CheckConnections();
|
||||
|
|
@ -1472,7 +1537,11 @@ static void CB2_PrintErrorMessage(void)
|
|||
PlaySE(SE_BOO);
|
||||
break;
|
||||
case 130:
|
||||
#if REVISION >= 0xA
|
||||
if (gWirelessCommType == 2 || gWirelessCommType == 3)
|
||||
#else
|
||||
if (gWirelessCommType == 2)
|
||||
#endif
|
||||
AddTextPrinterParameterized3(0, FONT_NORMAL_COPY_2, 2, 20, sLinkErrorTextColor, 0, gText_ABtnTitleScreen);
|
||||
else if (gWirelessCommType == 1)
|
||||
AddTextPrinterParameterized3(0, FONT_NORMAL_COPY_2, 2, 20, sLinkErrorTextColor, 0, gText_ABtnRegistrationCounter);
|
||||
|
|
@ -1491,7 +1560,11 @@ static void CB2_PrintErrorMessage(void)
|
|||
ReloadSave();
|
||||
}
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
else if (gWirelessCommType == 2 || gWirelessCommType == 3)
|
||||
#else
|
||||
else if (gWirelessCommType == 2)
|
||||
#endif
|
||||
{
|
||||
if (JOY_NEW(A_BUTTON))
|
||||
{
|
||||
|
|
@ -1576,8 +1649,33 @@ bool8 HandleLinkConnection(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
bool32 reloadOrReset = FALSE;
|
||||
if (svc_51())
|
||||
{
|
||||
// Documentation issue:
|
||||
// Rfu_IsMaster supposedly returns bool8, but just returns gRfu.ParentChild
|
||||
// That value has three states, see librfu.h. One of those states is MODE_NEUTRAL (0xFF) which means init.
|
||||
// So the last condition basically means "rfu link status is connected, not initialising".
|
||||
// As in, it's true if value is MODE_CHILD or MODE_PARENT but not MODE_NEUTRAL (because unsigned cmp).
|
||||
if (!FuncIsActiveTask(Task_WirelessCommunicationScreen) && (InUnionRoom() || gReceivedRemoteLinkPlayers != 0 || Rfu_IsMaster() <= MODE_PARENT))
|
||||
{
|
||||
reloadOrReset = TRUE;
|
||||
}
|
||||
CloseLink();
|
||||
}
|
||||
#endif
|
||||
main1Failed = RfuMain1(); // Always returns FALSE
|
||||
main2Failed = RfuMain2();
|
||||
#if REVISION >= 0xA
|
||||
if (reloadOrReset)
|
||||
{
|
||||
// If active task is mystery gift then soft reset, otherwise reload the save.
|
||||
if (FuncIsActiveTask(Task_MysteryGift)) RfuSoftReset();
|
||||
else RfuReloadSave();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (IsSendingKeysOverCable() == TRUE)
|
||||
{
|
||||
// This will never be reached.
|
||||
|
|
|
|||
162
src/link_rfu_2.c
162
src/link_rfu_2.c
|
|
@ -11,6 +11,12 @@
|
|||
#include "task.h"
|
||||
#include "constants/union_room.h"
|
||||
|
||||
#include "sloopsvc.h"
|
||||
#include "help_system.h"
|
||||
#include "reset_save_heap.h"
|
||||
#include "m4a.h"
|
||||
#include "gba/m4a_internal.h"
|
||||
|
||||
enum {
|
||||
RFUSTATE_INIT,
|
||||
RFUSTATE_INIT_END,
|
||||
|
|
@ -71,14 +77,25 @@ struct RfuDebug
|
|||
static EWRAM_DATA INIT_PARAM sRfuReqConfig = {};
|
||||
static EWRAM_DATA struct RfuDebug sRfuDebug = {};
|
||||
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
static u32 sRfuAPIBuffer[RFU_API_BUFF_SIZE_RAM / 4];
|
||||
#endif
|
||||
static u8 sResendBlock8[CMD_LENGTH * 2];
|
||||
static u16 sResendBlock16[CMD_LENGTH];
|
||||
|
||||
#if REVISION >= 0xA
|
||||
COMMON_DATA u32 sRfuAPIBuffer[RFU_API_BUFF_SIZE_RAM / 4] = {0};
|
||||
#endif
|
||||
COMMON_DATA struct RfuGameData gHostRfuGameData = {0};
|
||||
COMMON_DATA struct RfuManager gRfu = {0};
|
||||
COMMON_DATA u8 gHostRfuUsername[PLAYER_NAME_LENGTH + 1] = {0};
|
||||
|
||||
#if REVISION >= 0xA
|
||||
u16 ReadU16(const void* ptr);
|
||||
#else
|
||||
static u16 ReadU16(const void *ptr);
|
||||
#endif
|
||||
static void InitChildRecvBuffers(void);
|
||||
static void InitParentSendData(void);
|
||||
static void MscCallback_Child(u16 REQ_commandID);
|
||||
|
|
@ -92,7 +109,6 @@ static void SendNextBlock(void);
|
|||
static void SendLastBlock(void);
|
||||
static void CallRfuFunc(void);
|
||||
static void UpdateChildStatuses(void);
|
||||
static s32 GetJoinGroupStatus(void);
|
||||
static void Task_PlayerExchange(u8 taskId);
|
||||
static void ClearSelectedLinkPlayerIds(u16 disconnectMask);
|
||||
static void ValidateAndReceivePokemonSioInfo(void *recvBuffer);
|
||||
|
|
@ -118,8 +134,13 @@ static const INIT_PARAM sRfuReqConfigTemplate = {
|
|||
.userName = gHostRfuUsername,
|
||||
.fastSearchParent_flag = TRUE,
|
||||
.linkRecovery_enable = FALSE,
|
||||
#if REVISION >= 0xA
|
||||
.linkRecovery_period = 720,
|
||||
.NI_failCounter_limit = 480
|
||||
#else
|
||||
.linkRecovery_period = 600,
|
||||
.NI_failCounter_limit = 300
|
||||
#endif
|
||||
};
|
||||
|
||||
static const u8 sAvailSlots[] = {
|
||||
|
|
@ -317,7 +338,11 @@ static void Task_ParentSearchForChildren(u8 taskId)
|
|||
case RFUSTATE_INIT_END:
|
||||
break;
|
||||
case RFUSTATE_PARENT_CONNECT:
|
||||
#if REVISION >= 0xA
|
||||
rfu_LMAN_establishConnection(gRfu.parentChild, 0, 360, (u16 *)sAcceptedSerialNos);
|
||||
#else
|
||||
rfu_LMAN_establishConnection(gRfu.parentChild, 0, 240, (u16 *)sAcceptedSerialNos);
|
||||
#endif
|
||||
gRfu.state = RFUSTATE_PARENT_CONNECT_END;
|
||||
gTasks[taskId].data[1] = 6;
|
||||
break;
|
||||
|
|
@ -404,7 +429,11 @@ static void Task_ChildSearchForParent(u8 taskId)
|
|||
case RFUSTATE_INIT_END:
|
||||
break;
|
||||
case RFUSTATE_CHILD_CONNECT:
|
||||
#if REVISION >= 0xA
|
||||
rfu_LMAN_establishConnection(gRfu.parentChild, 0, 360, (u16 *)sAcceptedSerialNos);
|
||||
#else
|
||||
rfu_LMAN_establishConnection(gRfu.parentChild, 0, 240, (u16 *)sAcceptedSerialNos);
|
||||
#endif
|
||||
gRfu.state = RFUSTATE_CHILD_CONNECT_END;
|
||||
gTasks[taskId].data[1] = 7;
|
||||
break;
|
||||
|
|
@ -491,7 +520,11 @@ static void Task_UnionRoomListen(u8 taskId)
|
|||
case RFUSTATE_INIT_END:
|
||||
break;
|
||||
case RFUSTATE_UR_CONNECT:
|
||||
#if REVISION >= 0xA
|
||||
rfu_LMAN_establishConnection(MODE_P_C_SWITCH, 0, 360, (u16 *)sAcceptedSerialNos);
|
||||
#else
|
||||
rfu_LMAN_establishConnection(MODE_P_C_SWITCH, 0, 240, (u16 *)sAcceptedSerialNos);
|
||||
#endif
|
||||
rfu_LMAN_setMSCCallback(MscCallback_Child);
|
||||
gRfu.state = RFUSTATE_UR_CONNECT_END;
|
||||
break;
|
||||
|
|
@ -532,7 +565,11 @@ static void Task_UnionRoomListen(u8 taskId)
|
|||
|
||||
void LinkRfu_CreateConnectionAsParent(void)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
rfu_LMAN_establishConnection(MODE_PARENT, 0, 360, (u16 *)sAcceptedSerialNos);
|
||||
#else
|
||||
rfu_LMAN_establishConnection(MODE_PARENT, 0, 240, (u16 *)sAcceptedSerialNos);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LinkRfu_StopManagerBeforeEnteringChat(void)
|
||||
|
|
@ -540,6 +577,14 @@ void LinkRfu_StopManagerBeforeEnteringChat(void)
|
|||
rfu_LMAN_stopManager(FALSE);
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
void LinkRfu_ForceChangeSpParent(void)
|
||||
{
|
||||
if (gRfu.parentId != 0) return;
|
||||
rfu_LMAN_forceChangeSP(FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Argument is provided by the RFU and is unused.
|
||||
static void MscCallback_Child(u16 REQ_commandID)
|
||||
{
|
||||
|
|
@ -576,6 +621,9 @@ void LinkRfu_Shutdown(void)
|
|||
return;
|
||||
|
||||
rfu_LMAN_powerDownRFU();
|
||||
#if REVISION >= 0xA
|
||||
svc_44();
|
||||
#endif
|
||||
if (gRfu.parentChild == MODE_PARENT)
|
||||
{
|
||||
// Stop parent searching for children
|
||||
|
|
@ -629,7 +677,11 @@ static bool8 CanTryReconnectParent(void)
|
|||
|
||||
static bool32 TryReconnectParent(void)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
if (gRfu.state == RFUSTATE_CHILD_CONNECT_END && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[gRfu.reconnectParentId].id, 360))
|
||||
#else
|
||||
if (gRfu.state == RFUSTATE_CHILD_CONNECT_END && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[gRfu.reconnectParentId].id, 240))
|
||||
#endif
|
||||
{
|
||||
gRfu.state = RFUSTATE_RECONNECTED;
|
||||
return TRUE;
|
||||
|
|
@ -823,14 +875,25 @@ static bool32 RfuMain2_Parent(void)
|
|||
{
|
||||
if (gRfu.childRecvBuffer[i][1])
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
u8* childRecvBuffer = gRfu.childRecvBuffer[i];
|
||||
u8 newChildRecvId = childRecvBuffer[0] / 32;
|
||||
u8* oldChildRecvId = &gRfu.childRecvIds[i];
|
||||
if (*oldChildRecvId != 0xFF && newChildRecvId != ((*oldChildRecvId + 1) & 7))
|
||||
#else
|
||||
if (gRfu.childRecvIds[i] != 0xFF && (gRfu.childRecvBuffer[i][0] >> 5) != ((gRfu.childRecvIds[i] + 1) & 7))
|
||||
#endif
|
||||
{
|
||||
if (++gRfu.numChildRecvErrors[i] > 4)
|
||||
RfuSetErrorParams(F_RFU_ERROR_8 | F_RFU_ERROR_1);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
gRfu.childRecvIds[i] = newChildRecvId;
|
||||
#else
|
||||
gRfu.childRecvIds[i] = gRfu.childRecvBuffer[i][0] / 32;
|
||||
#endif
|
||||
gRfu.numChildRecvErrors[i] = 0;
|
||||
gRfu.childRecvBuffer[i][0] &= 0x1f;
|
||||
r0 = gRfu.linkPlayerIdx[i];
|
||||
|
|
@ -1386,6 +1449,9 @@ static void TryDisconnectRfu(void)
|
|||
{
|
||||
rfu_LMAN_requestChangeAgbClockMaster();
|
||||
gRfu.disconnectMode = RFU_DISCONNECT_NORMAL;
|
||||
#if REVISION >= 0xA
|
||||
svc_44();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
gRfu.callback = DisconnectRfu;
|
||||
|
|
@ -1396,6 +1462,9 @@ void LinkRfu_FatalError(void)
|
|||
rfu_LMAN_requestChangeAgbClockMaster();
|
||||
gRfu.disconnectMode = RFU_DISCONNECT_ERROR;
|
||||
gRfu.disconnectSlots = gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag;
|
||||
#if REVISION >= 0xA
|
||||
svc_44();
|
||||
#endif
|
||||
}
|
||||
|
||||
// RFU equivalent of LinkCB_WaitCloseLink
|
||||
|
|
@ -1547,7 +1616,11 @@ u8 Rfu_SetLinkRecovery(bool32 enable)
|
|||
{
|
||||
if (!enable)
|
||||
return rfu_LMAN_setLinkRecovery(FALSE, 0);
|
||||
#if REVISION >= 0xA
|
||||
rfu_LMAN_setLinkRecovery(TRUE, 720);
|
||||
#else
|
||||
rfu_LMAN_setLinkRecovery(TRUE, 600);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1586,8 +1659,11 @@ static bool8 CheckForLeavingGroupMembers(void)
|
|||
bool8 memberLeft = FALSE;
|
||||
for (i = 0; i < RFU_CHILD_MAX; i++)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
if (gRfu.partnerSendStatuses[i] < RFU_STATUS_JOIN_GROUP_OK
|
||||
|| gRfu.partnerSendStatuses[i] > RFU_STATUS_JOIN_GROUP_NO)
|
||||
#endif
|
||||
{
|
||||
if (gRfuSlotStatusNI[i]->recv.state == SLOT_STATE_RECV_SUCCESS
|
||||
|| gRfuSlotStatusNI[i]->recv.state == SLOT_STATE_RECV_SUCCESS_AND_SENDSIDE_UNKNOWN)
|
||||
|
|
@ -1596,7 +1672,11 @@ static bool8 CheckForLeavingGroupMembers(void)
|
|||
{
|
||||
gRfu.partnerSendStatuses[i] = RFU_STATUS_LEAVE_GROUP;
|
||||
gRfu.partnerRecvStatuses[i] = RFU_STATUS_CHILD_LEAVE_READY;
|
||||
#if REVISION >= 0xA
|
||||
rfu_clearSlot(TYPE_NI_SEND | TYPE_NI_RECV, i);
|
||||
#else
|
||||
rfu_clearSlot(TYPE_NI_RECV, i);
|
||||
#endif
|
||||
rfu_NI_setSendData(1 << i, 8, &gRfu.partnerSendStatuses[i], 1);
|
||||
memberLeft = TRUE;
|
||||
}
|
||||
|
|
@ -1624,6 +1704,12 @@ bool32 RfuTryDisconnectLeavingChildren(void)
|
|||
childrenLeaving |= (1 << i);
|
||||
gRfu.partnerRecvStatuses[i] = RFU_STATUS_OK;
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
if (((gRfuLinkStatus->connSlotFlag >> i) & 1) == 0)
|
||||
{
|
||||
gRfu.partnerRecvStatuses[i] = RFU_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Disconnect any leaving children
|
||||
|
|
@ -1665,6 +1751,9 @@ void SendLeaveGroupNotice(void)
|
|||
{
|
||||
gRfu.sendStatus = RFU_STATUS_LEAVE_GROUP_NOTICE;
|
||||
rfu_clearSlot(TYPE_NI_SEND, gRfu.childSlot);
|
||||
#if REVISION >= 0xA
|
||||
gRfuLinkStatus->remainLLFrameSizeChild[gRfu.childSlot] = 16;
|
||||
#endif
|
||||
rfu_NI_setSendData(1 << gRfu.childSlot, 8, &gRfu.sendStatus, 1);
|
||||
}
|
||||
|
||||
|
|
@ -1695,7 +1784,7 @@ static void UpdateChildStatuses(void)
|
|||
}
|
||||
}
|
||||
|
||||
static s32 GetJoinGroupStatus(void)
|
||||
s32 GetJoinGroupStatus(void)
|
||||
{
|
||||
s32 status = RFU_STATUS_OK;
|
||||
if (gRfu.sendStatus == RFU_STATUS_LEAVE_GROUP_NOTICE)
|
||||
|
|
@ -1789,7 +1878,11 @@ static void Task_PlayerExchange(u8 taskId)
|
|||
DestroyTask(taskId);
|
||||
gReceivedRemoteLinkPlayers = TRUE;
|
||||
gRfu.playerExchangeActive = FALSE;
|
||||
#if REVISION >= 0xA
|
||||
rfu_LMAN_setLinkRecovery(1, 720);
|
||||
#else
|
||||
rfu_LMAN_setLinkRecovery(1, 600);
|
||||
#endif
|
||||
if (gRfu.newChildQueue)
|
||||
{
|
||||
for (i = 0; i < RFU_CHILD_MAX; i++)
|
||||
|
|
@ -2017,6 +2110,12 @@ bool32 RfuMain1(void)
|
|||
{
|
||||
bool32 retval = FALSE;
|
||||
gRfu.parentId = 0;
|
||||
#if REVISION >= 0xA
|
||||
if ((svc_4b() & SVC4B_RESEED_RNG) != 0)
|
||||
{
|
||||
SeedRng(ReadU16( & GetHostRfuGameData()->compatibility.playerTrainerId ));
|
||||
}
|
||||
#endif
|
||||
rfu_LMAN_manager_entity(Random());
|
||||
if (!gRfu.isShuttingDown)
|
||||
{
|
||||
|
|
@ -2510,6 +2609,13 @@ u8 RfuGetStatus(void)
|
|||
return gRfu.status;
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
u16 RfuGetErrorInfo(void)
|
||||
{
|
||||
return gRfu.errorInfo;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool32 RfuHasErrored(void)
|
||||
{
|
||||
u32 status = RfuGetStatus();
|
||||
|
|
@ -2627,15 +2733,23 @@ void InitializeRfuLinkManager_EnterUnionRoom(void)
|
|||
rfu_LMAN_initializeManager(LinkManagerCB_UnionRoom, NULL);
|
||||
sRfuReqConfig = sRfuReqConfigTemplate;
|
||||
sRfuReqConfig.linkRecovery_enable = 0;
|
||||
#if REVISION >= 0xA
|
||||
sRfuReqConfig.linkRecovery_period = 720;
|
||||
#else
|
||||
sRfuReqConfig.linkRecovery_period = 600;
|
||||
#endif
|
||||
gRfu.searchTaskId = CreateTask(Task_UnionRoomListen, 1);
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
// (what used to be) ReadAsU16 from union_room.c is used instead.
|
||||
#else
|
||||
static u16 ReadU16(const void *ptr)
|
||||
{
|
||||
const u8 *ptr_ = ptr;
|
||||
return (ptr_[1] << 8) | (ptr_[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ================================================================
|
||||
|
|
@ -2775,7 +2889,11 @@ static void Task_RfuReconnectWithParent(u8 taskId)
|
|||
tTime++;
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
if (tTime > 360)
|
||||
#else
|
||||
if (tTime > 240)
|
||||
#endif
|
||||
{
|
||||
// Timeout error
|
||||
RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7);
|
||||
|
|
@ -2797,6 +2915,13 @@ void CreateTask_RfuReconnectWithParent(const u8 *name, u16 trainerId)
|
|||
data[8] = trainerId;
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
void DestroyTask_RfuReconnectWithParent(void)
|
||||
{
|
||||
DestroyTask(FindTaskIdByFunc(Task_RfuReconnectWithParent));
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool32 IsPartnerActivityIncompatible(s16 activity, struct RfuGameData *partner)
|
||||
{
|
||||
if (GetHostRfuGameData()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM))
|
||||
|
|
@ -2841,7 +2966,11 @@ static void Task_TryConnectToUnionRoomParent(u8 taskId)
|
|||
if (gRfu.status == RFU_STATUS_NEW_CHILD_DETECTED)
|
||||
DestroyTask(taskId);
|
||||
|
||||
#if REVISION >= 0xA
|
||||
if (++gTasks[taskId].data[0] > 480)
|
||||
#else
|
||||
if (++gTasks[taskId].data[0] > 300)
|
||||
#endif
|
||||
{
|
||||
// Timeout error
|
||||
RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7);
|
||||
|
|
@ -2859,7 +2988,11 @@ static void Task_TryConnectToUnionRoomParent(u8 taskId)
|
|||
// Parent found, try to connect
|
||||
if (!IsPartnerActivityIncompatible(gTasks[taskId].data[1], (struct RfuGameData *)&gRfuLinkStatus->partner[id].gname))
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
if (gRfuLinkStatus->partner[id].slot != 0xFF && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[id].id, 150))
|
||||
#else
|
||||
if (gRfuLinkStatus->partner[id].slot != 0xFF && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[id].id, 90))
|
||||
#endif
|
||||
{
|
||||
// Succesfully connected to parent
|
||||
gRfu.state = RFUSTATE_CONNECTED;
|
||||
|
|
@ -2884,7 +3017,11 @@ void TryConnectToUnionRoomParent(const u8 *name, struct RfuGameData *parent, u8
|
|||
gRfu.status = RFU_STATUS_OK;
|
||||
StringCopy(gRfu.parent.uname, name);
|
||||
memcpy(gRfu.parent.gname, parent, RFU_GAME_NAME_LENGTH);
|
||||
#if REVISION >= 0xA
|
||||
rfu_LMAN_forceChangeSP(TRUE);
|
||||
#else
|
||||
rfu_LMAN_forceChangeSP();
|
||||
#endif
|
||||
taskId = CreateTask(Task_TryConnectToUnionRoomParent, 2);
|
||||
gTasks[taskId].tActivity = activity;
|
||||
listenTaskId = FindTaskIdByFunc(Task_UnionRoomListen);
|
||||
|
|
@ -2999,6 +3136,27 @@ u32 GetRfuRecvQueueLength(void)
|
|||
return gRfu.recvQueue.count;
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
static inline void RfuReloadCommon(void) {
|
||||
m4aMPlayStop(&gMPlayInfo_SE1);
|
||||
m4aMPlayStop(&gMPlayInfo_SE2);
|
||||
m4aMPlayStop(&gMPlayInfo_SE3);
|
||||
StopMapMusic();
|
||||
gMain.callback1 = NULL;
|
||||
HelpSystem_Enable();
|
||||
}
|
||||
|
||||
void RfuReloadSave(void) {
|
||||
RfuReloadCommon();
|
||||
ReloadSave();
|
||||
}
|
||||
|
||||
void RfuSoftReset(void) {
|
||||
RfuReloadCommon();
|
||||
DoSoftReset();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void Task_Idle(u8 taskId)
|
||||
{
|
||||
|
||||
|
|
|
|||
204
src/link_rfu_3.c
204
src/link_rfu_3.c
|
|
@ -35,6 +35,204 @@ static const u16 sWirelessLinkIconPalette[] = INCBIN_U16("graphics/link/wireless
|
|||
static const u32 sWirelessLinkIconPic[] = INCBIN_U32("graphics/link/wireless_icon.4bpp.lz");
|
||||
|
||||
// Most of the below two tables won't make sense with ASCII encoding.
|
||||
#if REVISION >= 0xA
|
||||
// The tables have been changed to overload some control characters onto ASCII characters.
|
||||
static const u8 sWireless_ASCIItoRSETable[] = {
|
||||
EOS,
|
||||
0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x37,
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
[' '] = CHAR_SPACE,
|
||||
['!'] = CHAR_EXCL_MARK,
|
||||
0xb5, 0xb6, 0xb1, 0xf7, 0xf8, 0xf9,
|
||||
0xfa, 0xfb, 0xb2, 0xf1, 0xfc,
|
||||
['-'] = 0xfd,
|
||||
['.'] = 0xfe,
|
||||
['/'] = CHAR_SLASH,
|
||||
['0'] = CHAR_0,
|
||||
['1'] = CHAR_1,
|
||||
['2'] = CHAR_2,
|
||||
['3'] = CHAR_3,
|
||||
['4'] = CHAR_4,
|
||||
['5'] = CHAR_5,
|
||||
['6'] = CHAR_6,
|
||||
['7'] = CHAR_7,
|
||||
['8'] = CHAR_8,
|
||||
['9'] = CHAR_9,
|
||||
CHAR_CURRENCY, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, CHAR_BLACK_TRIANGLE,
|
||||
['A'] = CHAR_A,
|
||||
['B'] = CHAR_B,
|
||||
['C'] = CHAR_C,
|
||||
['D'] = CHAR_D,
|
||||
['E'] = CHAR_E,
|
||||
['F'] = CHAR_F,
|
||||
['G'] = CHAR_G,
|
||||
['H'] = CHAR_H,
|
||||
['I'] = CHAR_I,
|
||||
['J'] = CHAR_J,
|
||||
['K'] = CHAR_K,
|
||||
['L'] = CHAR_L,
|
||||
['M'] = CHAR_M,
|
||||
['N'] = CHAR_N,
|
||||
['O'] = CHAR_O,
|
||||
['P'] = CHAR_P,
|
||||
['Q'] = CHAR_Q,
|
||||
['R'] = CHAR_R,
|
||||
['S'] = CHAR_S,
|
||||
['T'] = CHAR_T,
|
||||
['U'] = CHAR_U,
|
||||
['V'] = CHAR_V,
|
||||
['W'] = CHAR_W,
|
||||
['X'] = CHAR_X,
|
||||
['Y'] = CHAR_Y,
|
||||
['Z'] = CHAR_Z,
|
||||
0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf0,
|
||||
['a'] = CHAR_a,
|
||||
['b'] = CHAR_b,
|
||||
['c'] = CHAR_c,
|
||||
['d'] = CHAR_d,
|
||||
['e'] = CHAR_e,
|
||||
['f'] = CHAR_f,
|
||||
['g'] = CHAR_g,
|
||||
['h'] = CHAR_h,
|
||||
['i'] = CHAR_i,
|
||||
['j'] = CHAR_j,
|
||||
['k'] = CHAR_k,
|
||||
['l'] = CHAR_l,
|
||||
['m'] = CHAR_m,
|
||||
['n'] = CHAR_n,
|
||||
['o'] = CHAR_o,
|
||||
['p'] = CHAR_p,
|
||||
['q'] = CHAR_q,
|
||||
['r'] = CHAR_r,
|
||||
['s'] = CHAR_s,
|
||||
['t'] = CHAR_t,
|
||||
['u'] = CHAR_u,
|
||||
['v'] = CHAR_v,
|
||||
['w'] = CHAR_w,
|
||||
['x'] = CHAR_x,
|
||||
['y'] = CHAR_y,
|
||||
['z'] = CHAR_z,
|
||||
0x2d, 0x2f, 0x30, 0x31, 0x32,
|
||||
0x33, 0x34, 0x35, 0x36, 0x50, 0x00, 0x01, 0x02,
|
||||
0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
|
||||
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
|
||||
0x1b, 0xad, 0xb3, 0xb4, 0xb8, 0xaf, 0x7d, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xa0,
|
||||
0xae, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
||||
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7e, 0xb0, 0xac,
|
||||
0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
|
||||
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
|
||||
0x2c, 0x2e, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c,
|
||||
0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94
|
||||
};
|
||||
|
||||
static const u8 sWireless_RSEtoASCIITable[] = {
|
||||
[CHAR_SPACE] = ' ',
|
||||
0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d,
|
||||
0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95,
|
||||
0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d,
|
||||
0x9e, 0x9f, 0xa0, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4,
|
||||
0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec,
|
||||
0xed, 0xee, 0xef, 0xf0, 0x7b, 0xf1, 0x7c, 0x7d,
|
||||
0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x07, 0x08,
|
||||
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x84,
|
||||
0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
|
||||
0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
|
||||
0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
|
||||
0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
|
||||
0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
|
||||
0xd9, 0xda, 0xdb, 0xdc, 0xa6, 0xdd, 0xa7, 0xa8,
|
||||
0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xf2, 0xf3,
|
||||
0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
|
||||
0xfc, 0xfd, 0xfe, 0xff, 0x01, 0x02, 0x03, 0x04,
|
||||
0x05, 0x06, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0xaf,
|
||||
[CHAR_0] = '0',
|
||||
[CHAR_1] = '1',
|
||||
[CHAR_2] = '2',
|
||||
[CHAR_3] = '3',
|
||||
[CHAR_4] = '4',
|
||||
[CHAR_5] = '5',
|
||||
[CHAR_6] = '6',
|
||||
[CHAR_7] = '7',
|
||||
[CHAR_8] = '8',
|
||||
[CHAR_9] = '9',
|
||||
[CHAR_EXCL_MARK] = '!',
|
||||
0xdf, 0xa1, 0xb0, 0xa5, 0xde, 0x24, 0x2a,
|
||||
0xa2, 0xa3, 0x22, 0x23, ':', 0xa4, 0x20,
|
||||
[CHAR_SLASH] = '/',
|
||||
[CHAR_A] = 'A',
|
||||
[CHAR_B] = 'B',
|
||||
[CHAR_C] = 'C',
|
||||
[CHAR_D] = 'D',
|
||||
[CHAR_E] = 'E',
|
||||
[CHAR_F] = 'F',
|
||||
[CHAR_G] = 'G',
|
||||
[CHAR_H] = 'H',
|
||||
[CHAR_I] = 'I',
|
||||
[CHAR_J] = 'J',
|
||||
[CHAR_K] = 'K',
|
||||
[CHAR_L] = 'L',
|
||||
[CHAR_M] = 'M',
|
||||
[CHAR_N] = 'N',
|
||||
[CHAR_O] = 'O',
|
||||
[CHAR_P] = 'P',
|
||||
[CHAR_Q] = 'Q',
|
||||
[CHAR_R] = 'R',
|
||||
[CHAR_S] = 'S',
|
||||
[CHAR_T] = 'T',
|
||||
[CHAR_U] = 'U',
|
||||
[CHAR_V] = 'V',
|
||||
[CHAR_W] = 'W',
|
||||
[CHAR_X] = 'X',
|
||||
[CHAR_Y] = 'Y',
|
||||
[CHAR_Z] = 'Z',
|
||||
[CHAR_a] = 'a',
|
||||
[CHAR_b] = 'b',
|
||||
[CHAR_c] = 'c',
|
||||
[CHAR_d] = 'd',
|
||||
[CHAR_e] = 'e',
|
||||
[CHAR_f] = 'f',
|
||||
[CHAR_g] = 'g',
|
||||
[CHAR_h] = 'h',
|
||||
[CHAR_i] = 'i',
|
||||
[CHAR_j] = 'j',
|
||||
[CHAR_k] = 'k',
|
||||
[CHAR_l] = 'l',
|
||||
[CHAR_m] = 'm',
|
||||
[CHAR_n] = 'n',
|
||||
[CHAR_o] = 'o',
|
||||
[CHAR_p] = 'p',
|
||||
[CHAR_q] = 'q',
|
||||
[CHAR_r] = 'r',
|
||||
[CHAR_s] = 's',
|
||||
[CHAR_t] = 't',
|
||||
[CHAR_u] = 'u',
|
||||
[CHAR_v] = 'v',
|
||||
[CHAR_w] = 'w',
|
||||
[CHAR_x] = 'x',
|
||||
[CHAR_y] = 'y',
|
||||
[CHAR_z] = 'z',
|
||||
0x40, 0x60, 0x2b, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
[CHAR_DYNAMIC] = '%',
|
||||
[CHAR_KEYPAD_ICON] = '&',
|
||||
[CHAR_EXTRA_SYMBOL] = '\'',
|
||||
[CHAR_PROMPT_SCROLL] = '(',
|
||||
[CHAR_PROMPT_CLEAR] = ')',
|
||||
[EXT_CTRL_CODE_BEGIN] = ',',
|
||||
[PLACEHOLDER_BEGIN] = '-',
|
||||
[CHAR_NEWLINE] = '.',
|
||||
[EOS] = 0
|
||||
};
|
||||
#else
|
||||
static const u8 sWireless_ASCIItoRSETable[] = {
|
||||
EOS,
|
||||
0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x37,
|
||||
|
|
@ -231,6 +429,8 @@ static const u8 sWireless_RSEtoASCIITable[] = {
|
|||
[EOS] = 0
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static const struct OamData sWirelessStatusIndicatorOamData =
|
||||
{
|
||||
.y = 0,
|
||||
|
|
@ -595,7 +795,7 @@ static void PopulateArrayWithSequence(u8 *arr, u8 mode)
|
|||
}
|
||||
}
|
||||
|
||||
static void PkmnStrToASCII(u8 *dest, const u8 *src)
|
||||
void PkmnStrToASCII(u8 *dest, const u8 *src)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
|
|
@ -604,7 +804,7 @@ static void PkmnStrToASCII(u8 *dest, const u8 *src)
|
|||
dest[i] = 0;
|
||||
}
|
||||
|
||||
static void ASCIIToPkmnStr(u8 *dest, const u8 *src)
|
||||
void ASCIIToPkmnStr(u8 *dest, const u8 *src)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "berry_powder.h"
|
||||
#include "overworld.h"
|
||||
#include "quest_log.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
#define SAVEBLOCK_MOVE_RANGE 128
|
||||
|
||||
|
|
@ -125,6 +126,9 @@ void MoveSaveBlocks_ResetHeap(void)
|
|||
encryptionKey = (Random() << 0x10) + (Random());
|
||||
ApplyNewEncryptionKeyToAllEncryptedData(encryptionKey);
|
||||
gSaveBlock2Ptr->encryptionKey = encryptionKey;
|
||||
#if REVISION >= 0xA
|
||||
svc_SetSaveBlock2(gSaveBlock2Ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
u32 UseContinueGameWarp(void)
|
||||
|
|
|
|||
37
src/main.c
37
src/main.c
|
|
@ -15,6 +15,7 @@
|
|||
#include "scanline_effect.h"
|
||||
#include "save_failed_screen.h"
|
||||
#include "quest_log.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
extern u32 intr_main[];
|
||||
|
||||
|
|
@ -24,6 +25,14 @@ static void VCountIntr(void);
|
|||
static void SerialIntr(void);
|
||||
static void IntrDummy(void);
|
||||
|
||||
#if REVISION >= 0xA && !MODERN
|
||||
const char OtherBuildDateTime[] = "2025 12 19 16:01";
|
||||
#endif
|
||||
|
||||
#if REVISION >= 0xA
|
||||
// OtherBuildDateTime is probably in some other file?
|
||||
__attribute__((aligned(4)))
|
||||
#endif
|
||||
const u8 gGameVersion = GAME_VERSION;
|
||||
|
||||
const u8 gGameLanguage = GAME_LANGUAGE;
|
||||
|
|
@ -33,8 +42,10 @@ const char BuildDateTime[] = __DATE__ " " __TIME__;
|
|||
#else
|
||||
#if REVISION == 0
|
||||
const char BuildDateTime[] = "2004 04 26 11:20";
|
||||
#else
|
||||
#elif REVISION == 1
|
||||
const char BuildDateTime[] = "2004 07 20 09:30";
|
||||
#elif REVISION == 0xA
|
||||
const char BuildDateTime[] = "2025 12 19 15:38 22afedd9";
|
||||
#endif //REVISION
|
||||
#endif //MODERN
|
||||
|
||||
|
|
@ -88,6 +99,9 @@ void EnableVCountIntrAtLine150(void);
|
|||
|
||||
void AgbMain()
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
svc_stubbed();
|
||||
#endif
|
||||
#if MODERN
|
||||
// Modern compilers are liberal with the stack on entry to this function,
|
||||
// so RegisterRamReset may crash if it resets IWRAM.
|
||||
|
|
@ -119,7 +133,12 @@ void AgbMain()
|
|||
#else
|
||||
RegisterRamReset(RESET_ALL);
|
||||
#endif //MODERN
|
||||
|
||||
#if REVISION >= 0xA
|
||||
*(vu16 *)BG_PLTT = RGB_BLACK;
|
||||
#else
|
||||
*(vu16 *)BG_PLTT = RGB_WHITE;
|
||||
#endif
|
||||
InitGpuRegManager();
|
||||
REG_WAITCNT = WAITCNT_PREFETCH_ENABLE | WAITCNT_WS0_S_1 | WAITCNT_WS0_N_3;
|
||||
InitKeys();
|
||||
|
|
@ -140,7 +159,8 @@ void AgbMain()
|
|||
|
||||
SetNotInSaveFailedScreen();
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Revision 10 has no calls into libisagbprn except this one.
|
||||
#if !defined(NDEBUG) || REVISION >= 0xA
|
||||
#if (LOG_HANDLER == LOG_HANDLER_MGBA_PRINT)
|
||||
(void) MgbaOpen();
|
||||
#elif (LOG_HANDLER == LOG_HANDLER_AGB_PRINT)
|
||||
|
|
@ -148,7 +168,7 @@ void AgbMain()
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if REVISION == 1
|
||||
#if REVISION >= 1
|
||||
if (gFlashMemoryPresent != TRUE)
|
||||
SetMainCallback2(NULL);
|
||||
#endif
|
||||
|
|
@ -164,7 +184,9 @@ void AgbMain()
|
|||
&& (gMain.heldKeysRaw & B_START_SELECT) == B_START_SELECT)
|
||||
{
|
||||
rfu_REQ_stopMode();
|
||||
#if REVISION < 0xA
|
||||
rfu_waitREQComplete();
|
||||
#endif
|
||||
DoSoftReset();
|
||||
}
|
||||
|
||||
|
|
@ -211,6 +233,9 @@ static void InitMainCallbacks(void)
|
|||
gSaveBlock1Ptr = &gSaveBlock1;
|
||||
gSaveBlock2.encryptionKey = 0;
|
||||
gQuestLogPlaybackState = QL_PLAYBACK_STATE_STOPPED;
|
||||
#if REVISION >= 0xA
|
||||
svc_SetSaveBlock2(&gSaveBlock2);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void CallCallbacks(void)
|
||||
|
|
@ -375,11 +400,11 @@ static void VBlankIntr(void)
|
|||
|
||||
gPcmDmaCounter = gSoundInfo.pcmDmaCounter;
|
||||
|
||||
#ifndef NDEBUG
|
||||
#if !defined(NDEBUG) || REVISION >= 0xA
|
||||
sVcountBeforeSound = REG_VCOUNT;
|
||||
#endif
|
||||
m4aSoundMain();
|
||||
#ifndef NDEBUG
|
||||
#if !defined(NDEBUG) || REVISION >= 0xA
|
||||
sVcountAfterSound = REG_VCOUNT;
|
||||
#endif
|
||||
|
||||
|
|
@ -408,7 +433,7 @@ static void HBlankIntr(void)
|
|||
|
||||
static void VCountIntr(void)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
#if !defined(NDEBUG) || REVISION >= 0xA
|
||||
sVcountAtIntr = REG_VCOUNT;
|
||||
#endif
|
||||
m4aSoundVSync();
|
||||
|
|
|
|||
|
|
@ -567,8 +567,14 @@ s8 Menu_ProcessInputNoWrapClearOnChoose(void)
|
|||
|
||||
void DestroyYesNoMenu(void)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
if (sYesNoWindowId == 0xFF) return;
|
||||
#endif
|
||||
ClearStdWindowAndFrameToTransparent(sYesNoWindowId, TRUE);
|
||||
RemoveWindow(sYesNoWindowId);
|
||||
#if REVISION >= 0xA
|
||||
sYesNoWindowId = 0xFF;
|
||||
#endif
|
||||
}
|
||||
|
||||
void MultichoiceGrid_PrintItems(u8 windowId, u8 fontId, u8 itemWidth, u8 itemHeight, u8 cols, u8 rows, const struct MenuAction *strs)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ EWRAM_DATA u8 sDownArrowCounterAndYCoordIdx[8] = {};
|
|||
EWRAM_DATA bool8 gGiftIsFromEReader = FALSE;
|
||||
|
||||
static void CreateMysteryGiftTask(void);
|
||||
static void Task_MysteryGift(u8 taskId);
|
||||
void Task_MysteryGift(u8 taskId);
|
||||
extern void CreateEReaderTask(void);
|
||||
|
||||
static const u16 sTextboxBorder_Pal[] = INCBIN_U16("graphics/interface/mystery_gift_textbox_border.gbapal");
|
||||
|
|
@ -1110,7 +1110,7 @@ static void CreateMysteryGiftTask(void)
|
|||
data->clientMsg = AllocZeroed(CLIENT_MAX_MSG_SIZE);
|
||||
}
|
||||
|
||||
static void Task_MysteryGift(u8 taskId)
|
||||
void Task_MysteryGift(u8 taskId)
|
||||
{
|
||||
struct MysteryGiftTaskData * data = (void *)gTasks[taskId].data;
|
||||
bool32 successMsg, input;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "constants/help_system.h"
|
||||
#include "constants/songs.h"
|
||||
#include "constants/event_objects.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
enum {
|
||||
INPUT_NONE,
|
||||
|
|
@ -680,7 +681,15 @@ static bool8 MainState_MoveToOKButton(void)
|
|||
|
||||
static bool8 MainState_PressedOKButton(void)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
// If the input text matched against the Switch bad words list, do not use it.
|
||||
if (!svc_BadWordCheck(sNamingScreen->textBuffer))
|
||||
{
|
||||
SaveInputText();
|
||||
}
|
||||
#else
|
||||
SaveInputText();
|
||||
#endif
|
||||
SetInputState(INPUT_STATE_DISABLED);
|
||||
SetCursorFlashing(FALSE);
|
||||
TryStartButtonFlash(BUTTON_COUNT, FALSE, TRUE);
|
||||
|
|
|
|||
|
|
@ -1512,6 +1512,13 @@ static bool8 RunFieldCallback(void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
void ClearFieldCallback(void)
|
||||
{
|
||||
gFieldCallback = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CB2_NewGame(void)
|
||||
{
|
||||
FieldClearVBlankHBlankCallbacks();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@
|
|||
#include "overworld.h"
|
||||
#include "hall_of_fame.h"
|
||||
#include "load_save.h"
|
||||
#include "item.h"
|
||||
#include "constants/heal_locations.h"
|
||||
#include "constants/items.h"
|
||||
|
||||
bool8 EnterHallOfFame(void)
|
||||
{
|
||||
|
|
@ -46,6 +48,20 @@ bool8 EnterHallOfFame(void)
|
|||
{
|
||||
IncrementGameStat(GAME_STAT_RECEIVED_RIBBONS);
|
||||
FlagSet(FLAG_SYS_RIBBON_GET);
|
||||
#if REVISION >= 0xA
|
||||
// The player has entered the Hall of Fame for the first time.
|
||||
// (At least, this is probably what was intended, except giving at least one Champion Ribbon does not imply first Hall of Fame entry)
|
||||
// Give the event tickets, and the flags for obtaining them, if required.
|
||||
if (!CheckBagHasItem(ITEM_AURORA_TICKET, 1))
|
||||
{
|
||||
AddBagItem(ITEM_AURORA_TICKET, 1);
|
||||
FlagSet(FLAG_ENABLE_SHIP_BIRTH_ISLAND);
|
||||
FlagSet(FLAG_RECEIVED_AURORA_TICKET);
|
||||
AddBagItem(ITEM_MYSTIC_TICKET, 1);
|
||||
FlagSet(FLAG_ENABLE_SHIP_NAVEL_ROCK);
|
||||
FlagSet(FLAG_RECEIVED_MYSTIC_TICKET);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
SetMainCallback2(CB2_DoHallOfFameScreen);
|
||||
return FALSE;
|
||||
|
|
|
|||
28
src/save.c
28
src/save.c
|
|
@ -9,6 +9,7 @@
|
|||
#include "fieldmap.h"
|
||||
#include "pokemon_storage_system.h"
|
||||
#include "gba/flash_internal.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
static u8 HandleWriteSector(u16 sectorId, const struct SaveSectorLocation *locations);
|
||||
static u8 TryWriteSector(u8 sectorNum, u8 *data);
|
||||
|
|
@ -212,6 +213,11 @@ static u8 HandleWriteSectorNBytes(u8 sectorId, u8 *data, u16 size)
|
|||
|
||||
static u8 TryWriteSector(u8 sectorNum, u8 *data)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
svc_WriteSector(sectorNum, data);
|
||||
SetDamagedSectorBits(DISABLE, sectorNum);
|
||||
return SAVE_STATUS_OK;
|
||||
#else
|
||||
if (ProgramFlashSectorAndVerify(sectorNum, data)) // is damaged?
|
||||
{
|
||||
SetDamagedSectorBits(ENABLE, sectorNum); // set damaged sector bits.
|
||||
|
|
@ -222,6 +228,7 @@ static u8 TryWriteSector(u8 sectorNum, u8 *data)
|
|||
SetDamagedSectorBits(DISABLE, sectorNum); // unset damaged sector bits. it's safe now.
|
||||
return SAVE_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static u32 RestoreSaveBackupVarsAndIncrement(const struct SaveSectorLocation *locations)
|
||||
|
|
@ -312,6 +319,11 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
|
|||
|
||||
gSaveDataBufferPtr->checksum = CalculateChecksum(data, size);
|
||||
|
||||
#if REVISION >= 0xA
|
||||
svc_ReplaceSector(sectorNum, (u8*)gSaveDataBufferPtr);
|
||||
SetDamagedSectorBits(DISABLE, sectorNum);
|
||||
return SAVE_STATUS_OK;
|
||||
#else
|
||||
// erase old save data
|
||||
EraseFlashSector(sectorNum);
|
||||
|
||||
|
|
@ -358,6 +370,7 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
|
|||
return SAVE_STATUS_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static u8 CopySectorSignatureByte(u16 sectorId, const struct SaveSectorLocation *locations)
|
||||
|
|
@ -679,6 +692,9 @@ u8 HandleSavingData(u8 saveType)
|
|||
break;
|
||||
}
|
||||
gMain.vblankCounter1 = backupPtr;
|
||||
#if REVISION >= 0xA
|
||||
svc_FinishSave();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -872,6 +888,9 @@ void Task_LinkFullSave(u8 taskId)
|
|||
gTasks[taskId].data[0] = 1;
|
||||
break;
|
||||
case 1:
|
||||
#if REVISION >= 0xA
|
||||
if (!IsLinkTaskFinished()) break;
|
||||
#endif
|
||||
SetLinkStandbyCallback();
|
||||
gTasks[taskId].data[0] = 2;
|
||||
break;
|
||||
|
|
@ -905,6 +924,9 @@ void Task_LinkFullSave(u8 taskId)
|
|||
gTasks[taskId].data[0] = 7;
|
||||
break;
|
||||
case 7:
|
||||
#if REVISION >= 0xA
|
||||
if (!IsLinkTaskFinished()) break;
|
||||
#endif
|
||||
ClearContinueGameWarpStatus2();
|
||||
SetLinkStandbyCallback();
|
||||
gTasks[taskId].data[0] = 8;
|
||||
|
|
@ -913,10 +935,16 @@ void Task_LinkFullSave(u8 taskId)
|
|||
if (IsLinkTaskFinished())
|
||||
{
|
||||
LinkFullSave_SetLastSectorSignature();
|
||||
#if REVISION >= 0xA
|
||||
svc_FinishSave();
|
||||
#endif
|
||||
gTasks[taskId].data[0] = 9;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
#if REVISION >= 0xA
|
||||
if (!IsLinkTaskFinished()) break;
|
||||
#endif
|
||||
SetLinkStandbyCallback();
|
||||
gTasks[taskId].data[0] = 10;
|
||||
break;
|
||||
|
|
|
|||
25
src/scrcmd.c
25
src/scrcmd.c
|
|
@ -37,6 +37,7 @@
|
|||
#include "constants/event_objects.h"
|
||||
#include "constants/maps.h"
|
||||
#include "constants/sound.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
extern u16 (*const gSpecials[])(void);
|
||||
extern u16 (*const gSpecialsEnd[])(void);
|
||||
|
|
@ -1732,12 +1733,24 @@ bool8 ScrCmd_bufferboxname(struct ScriptContext * ctx)
|
|||
|
||||
bool8 ScrCmd_givemon(struct ScriptContext * ctx)
|
||||
{
|
||||
u16 species = VarGet(ScriptReadHalfword(ctx));
|
||||
u8 level = ScriptReadByte(ctx);
|
||||
u16 item = VarGet(ScriptReadHalfword(ctx));
|
||||
u32 unkParam1 = ScriptReadWord(ctx);
|
||||
u32 unkParam2 = ScriptReadWord(ctx);
|
||||
u8 unkParam3 = ScriptReadByte(ctx);
|
||||
u16 species;
|
||||
u8 level;
|
||||
u16 item;
|
||||
u32 unkParam1;
|
||||
u32 unkParam2;
|
||||
u8 unkParam3;
|
||||
species = VarGet(ScriptReadHalfword(ctx));
|
||||
#if REVISION >= 0xA
|
||||
// If the player party count is zero, this "must" be giving the starter.
|
||||
// Notify the emulator of what starter was picked, for telemetry purposes.
|
||||
if (gSaveBlock1Ptr->playerPartyCount == 0)
|
||||
svc_SetStarter(species);
|
||||
#endif
|
||||
level = ScriptReadByte(ctx);
|
||||
item = VarGet(ScriptReadHalfword(ctx));
|
||||
unkParam1 = ScriptReadWord(ctx);
|
||||
unkParam2 = ScriptReadWord(ctx);
|
||||
unkParam3 = ScriptReadByte(ctx);
|
||||
|
||||
gSpecialVar_Result = ScriptGiveMon(species, level, item, unkParam1, unkParam2, unkParam3);
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -338,8 +338,14 @@ static const struct MenuAction sMultichoiceList_TradeCenter_Colosseum[] = {
|
|||
};
|
||||
|
||||
static const struct MenuAction sMultichoiceList_Link_Wireless[] = {
|
||||
#if REVISION >= 0xA
|
||||
// The default is wireless here as it's always emulated by Sloop
|
||||
{ gText_Wireless },
|
||||
{ gText_GameLinkCable },
|
||||
#else
|
||||
{ gText_GameLinkCable },
|
||||
{ gText_Wireless },
|
||||
#endif
|
||||
{ gOtherText_Exit }
|
||||
};
|
||||
|
||||
|
|
|
|||
294
src/sloopsvc.c
Normal file
294
src/sloopsvc.c
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
#include "global.h"
|
||||
#include "librfu.h"
|
||||
#include "link_rfu.h"
|
||||
#include "link.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
#if REVISION >= 0xA
|
||||
|
||||
typedef struct _SloopSvc47Params {
|
||||
// BUGBUG: gHostRfuGameData certainly didn't change size, ResetHostRfuGameData still zeroes 13 bytes
|
||||
u8 HostRfuGameData[0x10];
|
||||
u8 HostRfuUsername[RFU_USER_NAME_LENGTH];
|
||||
} SloopSvc47Params;
|
||||
|
||||
static u8 sBadWordAsciiString[256];
|
||||
|
||||
COMMON_DATA SloopSvc47Params gSvc47Params = {0};
|
||||
COMMON_DATA struct RfuLinkStatus *gSloopRfuLinkStatus = NULL;
|
||||
|
||||
// Syscall functions for the extra syscalls handled by the Sloop emulator.
|
||||
#define SLOOP_SVC_CLOBBERS "r0", "r1", "r2", "r3", "memory"
|
||||
|
||||
// Unreferenced. Sets a flag to true (default true) (svc_41 sets it to false)
|
||||
void svc_40(void) {
|
||||
asm volatile("swi 0x40");
|
||||
}
|
||||
|
||||
// Unreferenced. Sets a flag to false (default true) (svc_40 sets it to true)
|
||||
void svc_41(void) {
|
||||
asm volatile("swi 0x41");
|
||||
}
|
||||
|
||||
// Called by rfu_REQ_configGameData.
|
||||
void svc_47(void) {
|
||||
u8* params = gSvc47Params.HostRfuGameData;
|
||||
memcpy(params, &gHostRfuGameData, sizeof(gSvc47Params.HostRfuGameData));
|
||||
memcpy(¶ms[sizeof(gSvc47Params.HostRfuGameData)], gHostRfuUsername, sizeof(gSvc47Params.HostRfuUsername));
|
||||
asm volatile(
|
||||
"movs r0, %0 \n"
|
||||
"swi 0x47 \n"
|
||||
:
|
||||
: "l"(params)
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
gSloopRfuLinkStatus = gRfuLinkStatus;
|
||||
}
|
||||
|
||||
// Called by rfu_REQ_startSearchChild.
|
||||
void svc_42(void) {
|
||||
asm volatile("swi 0x42");
|
||||
}
|
||||
|
||||
// Called from rfu_LMAN_manager_entity.
|
||||
u32 svc_49(void) {
|
||||
u32 ret;
|
||||
asm volatile(
|
||||
"swi 0x49 \n"
|
||||
"movs %0, r0 \n"
|
||||
: "=l"(ret)
|
||||
:
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Called by rfu_REQ_startSearchParent and rfu_STC_readParentCandidateList.
|
||||
void svc_45_rfu_link_status(void) {
|
||||
asm volatile(
|
||||
"movs r0, %0 \n"
|
||||
"swi 0x45 \n"
|
||||
:
|
||||
: "l"(gRfuLinkStatus)
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
}
|
||||
|
||||
// Called by rfu_LMAN_REQ_callback
|
||||
u32 svc_4a(void) {
|
||||
u32 ret;
|
||||
asm volatile(
|
||||
"swi 0x4a \n"
|
||||
"movs %0, r0 \n"
|
||||
: "=l"(ret)
|
||||
:
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Called by rfu_REQ_startConnectParent
|
||||
void svc_43(u16 pid) {
|
||||
asm volatile(
|
||||
"movs r0, %0 \n"
|
||||
"swi 0x43 \n"
|
||||
:
|
||||
: "l"(pid)
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
}
|
||||
|
||||
// Called by rfu_REQ_stopMode, ...
|
||||
void svc_44(void) {
|
||||
asm volatile("swi 0x44");
|
||||
}
|
||||
|
||||
// Called by Task_WirelessCommunicationScreen
|
||||
u32 svc_53(void) {
|
||||
u32 ret;
|
||||
asm volatile(
|
||||
"swi 0x53 \n"
|
||||
"movs %0, r0 \n"
|
||||
: "=l"(ret)
|
||||
:
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Called by HandleLinkConnection
|
||||
u32 svc_51(void) {
|
||||
u32 ret;
|
||||
asm volatile(
|
||||
"swi 0x51 \n"
|
||||
"movs %0, r0 \n"
|
||||
: "=l"(ret)
|
||||
:
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Called by RfuMain1 and SpawnGroupLeaderAndMembers.
|
||||
// SpawnGroupLeaderAndMembers will exit early in the SpawnGroupLeader case if retval has bit 0 unset.
|
||||
// RfuMain1 will reseed the RNG by gHostRfuGameData->compatibility.playerTrainerId if retval has bit 1 set.
|
||||
u32 svc_4b(void) {
|
||||
u32 ret;
|
||||
asm volatile(
|
||||
"swi 0x4b \n"
|
||||
"movs %0, r0 \n"
|
||||
: "=l"(ret)
|
||||
:
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Called by TryWriteSector.
|
||||
void svc_WriteSector(u8 sector, u8* data) {
|
||||
asm volatile(
|
||||
"movs r0, %0 \n"
|
||||
"movs r1, %1 \n"
|
||||
"swi 0x48 \n"
|
||||
:
|
||||
: "l"(sector), "l"(data)
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
}
|
||||
|
||||
// Called by HandleReplaceSector.
|
||||
void svc_ReplaceSector(u8 sector, u8* data) {
|
||||
asm volatile(
|
||||
"movs r0, %0 \n"
|
||||
"movs r1, %1 \n"
|
||||
"swi 0x56 \n"
|
||||
:
|
||||
: "l"(sector), "l"(data)
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
}
|
||||
|
||||
// Called by various save-related functions.
|
||||
// This writes the save out (handler calls a function using fopen/fwrite/fclose)
|
||||
void svc_FinishSave(void) {
|
||||
asm volatile("swi 0x4c");
|
||||
}
|
||||
|
||||
// Called by Task_RunUnionRoom and ListMenuHandler_AllItemsAvailable.
|
||||
// This handler calls functions from the parental controls library.
|
||||
// ListMenuHandler_AllItemsAvailable returns -2 if this returns zero.
|
||||
// The Task_RunUnionRoom case auto-declines if this returns zero.
|
||||
// Probably returns zero if "free communication" is denied by parental control settings.
|
||||
u32 svc_CommsAllowedByParentalControls(void) {
|
||||
u32 ret;
|
||||
asm volatile(
|
||||
"swi 0x54 \n"
|
||||
"movs %0, r0 \n"
|
||||
: "=l"(ret)
|
||||
:
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u32 call_svc_BadWordCheck(u8* string, int arg2) {
|
||||
u32 ret;
|
||||
asm volatile(
|
||||
"movs r0, %1\n"
|
||||
"movs r1, %2\n"
|
||||
"swi 0x4d\n"
|
||||
"movs %0, r0\n"
|
||||
: "=l" (ret)
|
||||
: "l" (string), "l" (arg2)
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
// Called by naming screen MainState_PressedOKButton,
|
||||
// ChatEntryRoutine_SendMessage and union room RegisterTextAtRow.
|
||||
// This does the bad word checks.
|
||||
// The text buffer passed in is sanitised, and zero returned if sanitisation occured(?)/badwords present(?)
|
||||
u32 svc_BadWordCheck(u8* str) {
|
||||
u32 ret;
|
||||
PkmnStrToASCII((u8*)sBadWordAsciiString, str);
|
||||
ret = call_svc_BadWordCheck((u8*)sBadWordAsciiString, 0);
|
||||
ASCIIToPkmnStr(str, (u8*)sBadWordAsciiString);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Called by various cases of Task_TryJoinLinkGroup and Task_TryBecomeLinkLeader.
|
||||
void svc_4f(u32 arg) {
|
||||
asm volatile(
|
||||
"movs r0, %0 \n"
|
||||
"swi 0x4f \n"
|
||||
:
|
||||
: "l"(arg)
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
}
|
||||
|
||||
// Called by a wrapper function called by Task_TryBecomeLinkLeader.
|
||||
// The wrapper function is equivalent to "return !svc_50();"
|
||||
// Return value is ORed with gReceivedRemoteLinkPlayers.
|
||||
u32 svc_50(void) {
|
||||
u32 ret;
|
||||
asm volatile(
|
||||
"swi 0x50 \n"
|
||||
"movs %0, r0 \n"
|
||||
: "=l"(ret)
|
||||
:
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Called by InitMainCallbacks and MoveSaveBlocks_ResetHeap.
|
||||
// Lets the emulator know where SaveBlock2 is located in memory.
|
||||
// Emulator appears to use this to get saveBlock2->optionsButtonMode to check against L_EQUALS_A.
|
||||
void svc_SetSaveBlock2(struct SaveBlock2* saveBlock2) {
|
||||
asm volatile(
|
||||
"movs r0, %0 \n"
|
||||
"swi 0x55 \n"
|
||||
:
|
||||
: "l"(saveBlock2)
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
}
|
||||
|
||||
// Called by AgbMain, as its first action before RegisterRamReset.
|
||||
void svc_stubbed(void) {
|
||||
// No operation.
|
||||
}
|
||||
|
||||
// Called by ScrCmd_givemon when the party is empty.
|
||||
// This lets the emulator know what starter was picked (saved in play report / telemetry data)
|
||||
void svc_SetStarter(u32 species) {
|
||||
asm volatile(
|
||||
"movs r0, %0 \n"
|
||||
"swi 0x57 \n"
|
||||
:
|
||||
: "l"(species)
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
}
|
||||
|
||||
// Called by Task_StartActivity
|
||||
// This lets the emulator know the current union room activity.
|
||||
void svc_SetActivity(u32 activity) {
|
||||
asm volatile(
|
||||
"movs r0, %0 \n"
|
||||
"swi 0x61 \n"
|
||||
:
|
||||
: "l"(activity)
|
||||
: SLOOP_SVC_CLOBBERS
|
||||
);
|
||||
}
|
||||
|
||||
// Called by CB2_PrintErrorMessage.
|
||||
// This causes the emulator to increment some variable (link error counter, probably).
|
||||
void svc_IncrementLinkError(void) {
|
||||
asm volatile("swi 0x62");
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
#include "help_system.h"
|
||||
#include "constants/songs.h"
|
||||
#include "constants/field_weather.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
enum StartMenuOption
|
||||
{
|
||||
|
|
@ -935,6 +936,9 @@ static void task50_after_link_battle_save(u8 taskId)
|
|||
if (WriteSaveBlock1Sector())
|
||||
{
|
||||
ClearContinueGameWarpStatus2();
|
||||
#if REVISION >= 0xA
|
||||
svc_FinishSave();
|
||||
#endif
|
||||
data[0] = 3;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ EWRAM_DATA u8 gStringVar1[32] = {};
|
|||
EWRAM_DATA u8 gStringVar2[20] = {};
|
||||
EWRAM_DATA u8 gStringVar3[20] = {};
|
||||
EWRAM_DATA u8 gStringVar4[1000] = {};
|
||||
#if REVISION >= 0xA
|
||||
EWRAM_DATA u8 gUnknownStringVar[12] = {0};
|
||||
#else
|
||||
EWRAM_DATA u8 gUnknownStringVar[16] = {0};
|
||||
#endif
|
||||
|
||||
static const u8 sDigits[] = __("0123456789ABCDEF");
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,10 @@ static void InsertTask(u8 newTaskId)
|
|||
|
||||
void DestroyTask(u8 taskId)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
// Bounds check on the task ID.
|
||||
if (taskId >= NUM_TASKS) return;
|
||||
#endif
|
||||
if (gTasks[taskId].isActive)
|
||||
{
|
||||
gTasks[taskId].isActive = FALSE;
|
||||
|
|
|
|||
|
|
@ -634,12 +634,16 @@ static void SetTitleScreenScene_Run(s16 *data)
|
|||
DestroyTask(FindTaskIdByFunc(Task_TitleScreenMain));
|
||||
SetMainCallback2(CB2_FadeOutTransitionToSaveClearScreen);
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
// Berry fix trigger has been removed.
|
||||
#else
|
||||
else if (JOY_HELD(KEYSTROKE_BERRY_FIX) == KEYSTROKE_BERRY_FIX)
|
||||
{
|
||||
DeactivateSlashSprite(tSlashSpriteId);
|
||||
DestroyTask(FindTaskIdByFunc(Task_TitleScreenMain));
|
||||
SetMainCallback2(CB2_FadeOutTransitionToBerryFix);
|
||||
}
|
||||
#endif
|
||||
else if (JOY_NEW(A_BUTTON | START_BUTTON))
|
||||
{
|
||||
SetTitleScreenScene(data, TITLESCREENSCENE_CRY);
|
||||
|
|
|
|||
|
|
@ -2116,7 +2116,11 @@ static void CB_HandleTradeCanceled(void)
|
|||
|
||||
static void CB_InitExitCanceledTrade(void)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
if (IsLinkTaskFinished() && !gPaletteFade.active)
|
||||
#else
|
||||
if (!gPaletteFade.active)
|
||||
#endif
|
||||
{
|
||||
if (gWirelessCommType)
|
||||
SetLinkStandbyCallback();
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "constants/songs.h"
|
||||
#include "constants/region_map_sections.h"
|
||||
#include "constants/moves.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
// Values for signaling to/from the link partner
|
||||
enum {
|
||||
|
|
@ -2608,25 +2609,37 @@ static void CB2_SaveAndEndTrade(void)
|
|||
MysteryGift_TryIncrementStat(CARD_STAT_NUM_TRADES, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId);
|
||||
SetContinueGameWarpStatusToDynamicWarp();
|
||||
LinkFullSave_Init();
|
||||
#if REVISION >= 0xA
|
||||
// No need to wait for a save when the emulator does it fast and synchronously
|
||||
gMain.state = 52;
|
||||
#else
|
||||
gMain.state++;
|
||||
#endif
|
||||
sTradeAnim->timer = 0;
|
||||
break;
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
case 51:
|
||||
if (++sTradeAnim->timer == 5)
|
||||
gMain.state++;
|
||||
break;
|
||||
#endif
|
||||
case 52:
|
||||
if (LinkFullSave_WriteSector())
|
||||
{
|
||||
ClearContinueGameWarpStatus2();
|
||||
gMain.state = 4;
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
// Save delay is gone, just write the next sector if save isn't finished
|
||||
#else
|
||||
else
|
||||
{
|
||||
// Save isn't finished, delay again
|
||||
sTradeAnim->timer = 0;
|
||||
gMain.state = 51;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 4:
|
||||
LinkFullSave_ReplaceLastSector();
|
||||
|
|
@ -2654,6 +2667,26 @@ static void CB2_SaveAndEndTrade(void)
|
|||
sTradeAnim->timer--;
|
||||
}
|
||||
break;
|
||||
#if REVISION >= 0xA
|
||||
case 42:
|
||||
if (IsLinkTaskFinished())
|
||||
{
|
||||
gMain.state = 43;
|
||||
}
|
||||
break;
|
||||
case 43:
|
||||
SetLinkStandbyCallback();
|
||||
gMain.state = 44;
|
||||
break;
|
||||
case 44:
|
||||
if (IsLinkTaskFinished())
|
||||
{
|
||||
LinkFullSave_SetLastSectorSignature();
|
||||
svc_FinishSave();
|
||||
gMain.state = 5;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case 42:
|
||||
if (IsLinkTaskFinished())
|
||||
{
|
||||
|
|
@ -2661,6 +2694,7 @@ static void CB2_SaveAndEndTrade(void)
|
|||
gMain.state = 5;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 5:
|
||||
if (++sTradeAnim->timer > 60)
|
||||
{
|
||||
|
|
|
|||
495
src/union_room.c
495
src/union_room.c
|
|
@ -48,6 +48,7 @@
|
|||
#include "constants/field_weather.h"
|
||||
#include "constants/trainer_card.h"
|
||||
#include "constants/union_room.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
// States for Task_RunUnionRoom
|
||||
enum {
|
||||
|
|
@ -143,7 +144,11 @@ enum {
|
|||
LL_STATE_FAILED,
|
||||
LL_STATE_TRY_START_ACTIVITY = 26,
|
||||
LL_STATE_MEMBER_DISCONNECTED = 29,
|
||||
LL_STATE_CANCEL_WITH_MSG
|
||||
LL_STATE_CANCEL_WITH_MSG,
|
||||
#if REVISION >= 0xA
|
||||
LL_STATE_CONFIRM_MEMBERS_SLOOP,
|
||||
LL_STATE_DISCONNECT_CHILD_SLOOP
|
||||
#endif
|
||||
};
|
||||
|
||||
// States for Task_TryJoinLinkGroup
|
||||
|
|
@ -205,9 +210,19 @@ EWRAM_DATA u16 gUnionRoomOfferedSpecies = SPECIES_NONE;
|
|||
EWRAM_DATA u8 gUnionRoomRequestedMonType = TYPE_NORMAL;
|
||||
static EWRAM_DATA struct UnionRoomTrade sUnionRoomTrade = {};
|
||||
|
||||
#if REVISION >= 0xA
|
||||
COMMON_DATA struct WirelessLink_Leader * sLeader = NULL;
|
||||
COMMON_DATA struct WirelessLink_URoom * sURoom = NULL;
|
||||
COMMON_DATA struct WirelessLink_Group * sGroup = NULL;
|
||||
#else
|
||||
static struct WirelessLink_Leader * sLeader;
|
||||
static struct WirelessLink_Group * sGroup;
|
||||
static struct WirelessLink_URoom * sURoom;
|
||||
#endif
|
||||
|
||||
#if REVISION >= 0xA
|
||||
static void Leader_DisconnectOnState(struct WirelessLink_Leader * data, u8 state);
|
||||
#endif
|
||||
|
||||
static void Task_TryBecomeLinkLeader(u8);
|
||||
static void Leader_DestroyResources(struct WirelessLink_Leader *);
|
||||
|
|
@ -227,7 +242,12 @@ static void Task_SendMysteryGift(u8);
|
|||
static void Task_CardOrNewsWithFriend(u8);
|
||||
static void Task_CardOrNewsOverWireless(u8);
|
||||
static void Task_RunUnionRoom(u8);
|
||||
#if REVISION >= 0xA
|
||||
u16 ReadU16(const u8 *);
|
||||
#define ReadAsU16(x) ReadU16(x)
|
||||
#else
|
||||
static u16 ReadAsU16(const u8 *);
|
||||
#endif
|
||||
static void ReceiveUnionRoomActivityPacket(struct WirelessLink_URoom *);
|
||||
static bool32 HandleContactFromOtherPlayer(struct WirelessLink_URoom *);
|
||||
static void Task_InitUnionRoom(u8);
|
||||
|
|
@ -422,6 +442,9 @@ static void Task_TryBecomeLinkLeader(u8 taskId)
|
|||
CopyBgTilemapBufferToVram(0);
|
||||
data->playerCount = 1;
|
||||
data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT;
|
||||
#if REVISION >= 0xA
|
||||
svc_4f(0);
|
||||
#endif
|
||||
break;
|
||||
case LL_STATE_GET_AWAITING_PLAYERS_TEXT:
|
||||
StringCopy(gStringVar1, sLinkGroupActivityNameTexts[sPlayerCurrActivity]);
|
||||
|
|
@ -439,19 +462,28 @@ static void Task_TryBecomeLinkLeader(u8 taskId)
|
|||
|
||||
PrintNumPlayersWaitingForMsg(data->nPlayerModeWindowId, sPlayerActivityGroupSize, data->playerCount);
|
||||
data->state = LL_STATE_PRINT_AWAITING_PLAYERS;
|
||||
#if REVISION >= 0xA
|
||||
Leader_SetStateIfMemberListChanged(data, LL_STATE_ACCEPT_NEW_MEMBER_PROMPT, LL_STATE_MEMBER_LEFT);
|
||||
#endif
|
||||
break;
|
||||
case LL_STATE_PRINT_AWAITING_PLAYERS:
|
||||
if (PrintOnTextbox(&data->textState, gStringVar4))
|
||||
data->state = LL_STATE_AWAIT_PLAYERS;
|
||||
break;
|
||||
case LL_STATE_AWAIT_PLAYERS:
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
Leader_SetStateIfMemberListChanged(data, LL_STATE_ACCEPT_NEW_MEMBER_PROMPT, LL_STATE_MEMBER_LEFT);
|
||||
#endif
|
||||
if (JOY_NEW(B_BUTTON))
|
||||
{
|
||||
if (data->playerCount == 1)
|
||||
data->state = LL_STATE_SHUTDOWN_AND_FAIL;
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
else if (GROUP_MIN2(sPlayerActivityGroupSize) != 0)
|
||||
data->state = LL_STATE_CANCEL_WITH_MSG;
|
||||
#endif
|
||||
else
|
||||
data->state = LL_STATE_CANCEL_PROMPT;
|
||||
}
|
||||
|
|
@ -462,30 +494,54 @@ static void Task_TryBecomeLinkLeader(u8 taskId)
|
|||
&& JOY_NEW(START_BUTTON))
|
||||
{
|
||||
data->state = LL_STATE_MEMBERS_OK_PROMPT;
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
LinkRfu_StopManagerAndFinalizeSlots();
|
||||
#endif
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
if (data->state == LL_STATE_AWAIT_PLAYERS)
|
||||
{
|
||||
Leader_SetStateIfMemberListChanged(data, LL_STATE_ACCEPT_NEW_MEMBER_PROMPT, LL_STATE_MEMBER_LEFT);
|
||||
}
|
||||
Leader_DisconnectOnState(data, LL_STATE_AWAIT_PLAYERS);
|
||||
#else
|
||||
if (data->state == LL_STATE_AWAIT_PLAYERS && RfuTryDisconnectLeavingChildren())
|
||||
{
|
||||
// At least 1 group member has left or is trying to leave
|
||||
data->state = LL_STATE_WAIT_DISCONNECT_CHILD;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case LL_STATE_WAIT_DISCONNECT_CHILD:
|
||||
// Resume after ensuring all members trying to leave have left
|
||||
if (!RfuTryDisconnectLeavingChildren())
|
||||
{
|
||||
data->state = LL_STATE_AWAIT_PLAYERS;
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
data->playerCount = LeaderPrunePlayerList(data->playerList);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case LL_STATE_MEMBER_LEFT:
|
||||
#if REVISION >= 0xA
|
||||
id = (GROUP_MAX(sPlayerActivityGroupSize) != 2) ? 1 : 0;
|
||||
#else
|
||||
id = (GROUP_MAX(sPlayerCurrActivity) == 2) ? 1 : 0;
|
||||
#endif
|
||||
if (PrintOnTextbox(&data->textState, gTexts_UR_PlayerUnavailable[id]))
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
data->playerCount = LeaderPrunePlayerList(data->playerList);
|
||||
RedrawListMenu(data->listTaskId);
|
||||
#endif
|
||||
data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT;
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
Leader_DisconnectOnState(data, LL_STATE_MEMBER_LEFT);
|
||||
#endif
|
||||
break;
|
||||
case LL_STATE_MEMBER_DISCONNECTED:
|
||||
id = (GROUP_MAX(sPlayerActivityGroupSize) == 2) ? 0 : 1;
|
||||
|
|
@ -495,6 +551,9 @@ static void Task_TryBecomeLinkLeader(u8 taskId)
|
|||
case LL_STATE_ACCEPT_NEW_MEMBER_PROMPT:
|
||||
if (PrintOnTextbox(&data->textState, gStringVar4))
|
||||
data->state = LL_STATE_ACCEPT_NEW_MEMBER_PROMPT_HANDLE_INPUT;
|
||||
#if REVISION >= 0xA
|
||||
Leader_DisconnectOnState(data, LL_STATE_ACCEPT_NEW_MEMBER_PROMPT);
|
||||
#endif
|
||||
break;
|
||||
case LL_STATE_ACCEPT_NEW_MEMBER_PROMPT_HANDLE_INPUT:
|
||||
switch (UnionRoomHandleYesNo(&data->textState, HasTrainerLeftPartnersList(
|
||||
|
|
@ -518,6 +577,9 @@ static void Task_TryBecomeLinkLeader(u8 taskId)
|
|||
data->state = LL_STATE_WAIT_DISCONNECT_CHILD;
|
||||
break;
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
Leader_DisconnectOnState(data, LL_STATE_ACCEPT_NEW_MEMBER_PROMPT_HANDLE_INPUT);
|
||||
#endif
|
||||
break;
|
||||
case LL_STATE_UPDATE_AFTER_JOIN_REQUEST:
|
||||
val = WaitSendRfuStatusToPartner(ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name);
|
||||
|
|
@ -542,7 +604,10 @@ static void Task_TryBecomeLinkLeader(u8 taskId)
|
|||
data->state = LL_STATE_ACCEPTED_FINAL_MEMBER;
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
LinkRfu_StopManagerAndFinalizeSlots();
|
||||
#endif
|
||||
PrintNumPlayersWaitingForMsg(data->nPlayerModeWindowId, sPlayerActivityGroupSize, data->playerCount);
|
||||
}
|
||||
else
|
||||
|
|
@ -554,7 +619,11 @@ static void Task_TryBecomeLinkLeader(u8 taskId)
|
|||
{
|
||||
RequestDisconnectSlotByTrainerNameAndId(data->playerList->players[data->playerCount].rfu.name, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId));
|
||||
data->playerList->players[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE;
|
||||
#if REVISION >= 0xA
|
||||
data->playerCount = LeaderPrunePlayerList(data->playerList);
|
||||
#else
|
||||
LeaderPrunePlayerList(data->playerList);
|
||||
#endif
|
||||
RedrawListMenu(data->listTaskId);
|
||||
data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT;
|
||||
}
|
||||
|
|
@ -570,59 +639,159 @@ static void Task_TryBecomeLinkLeader(u8 taskId)
|
|||
break;
|
||||
case LL_STATE_ACCEPTED_FINAL_MEMBER:
|
||||
if (PrintOnTextbox(&data->textState, gStringVar4))
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
data->state = LL_STATE_CONFIRM_MEMBERS_SLOOP;
|
||||
svc_4f(1);
|
||||
data->delayTimerAfterOk = 0;
|
||||
#else
|
||||
data->state = LL_STATE_WAIT_AND_CONFIRM_MEMBERS;
|
||||
#endif
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
Leader_DisconnectOnState(data, LL_STATE_ACCEPTED_FINAL_MEMBER);
|
||||
#endif
|
||||
break;
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
case LL_STATE_WAIT_AND_CONFIRM_MEMBERS:
|
||||
if (++data->delayTimerAfterOk > 120)
|
||||
data->state = LL_STATE_CONFIRMED_MEMBERS;
|
||||
break;
|
||||
#endif
|
||||
case LL_STATE_MEMBERS_OK_PROMPT:
|
||||
if (PrintOnTextbox(&data->textState, gText_UR_AreTheseMembersOK))
|
||||
data->state = LL_STATE_MEMBERS_OK_PROMPT_HANDLE_INPUT;
|
||||
#if REVISION >= 0xA
|
||||
Leader_DisconnectOnState(data, LL_STATE_MEMBERS_OK_PROMPT);
|
||||
#endif
|
||||
break;
|
||||
case LL_STATE_MEMBERS_OK_PROMPT_HANDLE_INPUT:
|
||||
switch (UnionRoomHandleYesNo(&data->textState, FALSE))
|
||||
{
|
||||
case 0: // YES
|
||||
#if REVISION >= 0xA
|
||||
data->state = LL_STATE_CONFIRM_MEMBERS_SLOOP;
|
||||
svc_4f(1);
|
||||
data->delayTimerAfterOk = 0;
|
||||
#else
|
||||
data->state = LL_STATE_CONFIRMED_MEMBERS;
|
||||
#endif
|
||||
break;
|
||||
case 1: // NO
|
||||
case MENU_B_PRESSED:
|
||||
#if REVISION >= 0xA
|
||||
data->state = LL_STATE_CANCEL_PROMPT;
|
||||
#else
|
||||
if (GROUP_MIN2(sPlayerActivityGroupSize) != 0)
|
||||
data->state = LL_STATE_CANCEL_WITH_MSG;
|
||||
else
|
||||
data->state = LL_STATE_CANCEL_PROMPT;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
Leader_DisconnectOnState(data, LL_STATE_MEMBERS_OK_PROMPT_HANDLE_INPUT);
|
||||
#endif
|
||||
break;
|
||||
#if REVISION >= 0xA
|
||||
case LL_STATE_CONFIRM_MEMBERS_SLOOP:
|
||||
switch (LeaderUpdateGroupMembership(data->playerList))
|
||||
{
|
||||
case UNION_ROOM_SPAWN_IN:
|
||||
data->joinRequestAnswer = RFU_STATUS_CONNECTION_ERROR;
|
||||
SendRfuStatusToPartner(RFU_STATUS_CONNECTION_ERROR, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name);
|
||||
data->state = LL_STATE_DISCONNECT_CHILD_SLOOP;
|
||||
return;
|
||||
case UNION_ROOM_SPAWN_OUT:
|
||||
RfuSetStatus(RFU_STATUS_OK, 0);
|
||||
data->playerCount = LeaderPrunePlayerList(data->playerList);
|
||||
RedrawListMenu(data->listTaskId);
|
||||
svc_4f(0);
|
||||
data->state = LL_STATE_MEMBER_LEFT;
|
||||
return;
|
||||
case UNION_ROOM_SPAWN_OUT_SOON:
|
||||
RfuSetStatus(RFU_STATUS_OK, 0);
|
||||
data->playerCount = LeaderPrunePlayerList(data->playerList);
|
||||
RedrawListMenu(data->listTaskId);
|
||||
return;
|
||||
}
|
||||
if (++data->delayTimerAfterOk > 40)
|
||||
{
|
||||
data->state = LL_STATE_FINAL_MEMBER_CHECK;
|
||||
LinkRfu_StopManagerAndFinalizeSlots();
|
||||
}
|
||||
Leader_DisconnectOnState(data, LL_STATE_CONFIRM_MEMBERS_SLOOP);
|
||||
break;
|
||||
case LL_STATE_DISCONNECT_CHILD_SLOOP:
|
||||
val = WaitSendRfuStatusToPartner(ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name);
|
||||
if (val == 1)
|
||||
{
|
||||
// Send complete
|
||||
RequestDisconnectSlotByTrainerNameAndId(data->playerList->players[data->playerCount].rfu.name, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId));
|
||||
data->playerList->players[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE;
|
||||
data->playerCount = LeaderPrunePlayerList(data->playerList);
|
||||
RedrawListMenu(data->listTaskId);
|
||||
} else if (val == 2)
|
||||
{
|
||||
// Disconnect
|
||||
RfuSetStatus(RFU_STATUS_OK, 0);
|
||||
} else break;
|
||||
data->state = LL_STATE_CONFIRM_MEMBERS_SLOOP;
|
||||
break;
|
||||
#endif
|
||||
case LL_STATE_CANCEL_PROMPT:
|
||||
if (PrintOnTextbox(&data->textState, gText_UR_CancelModeWithTheseMembers))
|
||||
data->state = LL_STATE_CANCEL_PROMPT_HANDLE_INPUT;
|
||||
#if REVISION >= 0xA
|
||||
Leader_DisconnectOnState(data, LL_STATE_CANCEL_PROMPT);
|
||||
#endif
|
||||
break;
|
||||
case LL_STATE_CANCEL_PROMPT_HANDLE_INPUT:
|
||||
switch (UnionRoomHandleYesNo(&data->textState, FALSE))
|
||||
{
|
||||
case 0: // YES
|
||||
#if REVISION >= 0xA
|
||||
data->state = LL_STATE_CANCEL_WITH_MSG;
|
||||
#else
|
||||
data->state = LL_STATE_SHUTDOWN_AND_FAIL;
|
||||
#endif
|
||||
break;
|
||||
case 1: // NO
|
||||
case MENU_B_PRESSED:
|
||||
#if REVISION >= 0xA
|
||||
if (GROUP_MIN2(sPlayerActivityGroupSize) == 0 && data->playerCount == GROUP_MAX(sPlayerActivityGroupSize))
|
||||
data->state = LL_STATE_MEMBERS_OK_PROMPT;
|
||||
#else
|
||||
if (GROUP_MIN2(sPlayerActivityGroupSize) != 0)
|
||||
data->state = LL_STATE_MEMBERS_OK_PROMPT;
|
||||
else if (data->playerCount == GROUP_MAX(sPlayerActivityGroupSize))
|
||||
data->state = LL_STATE_MEMBERS_OK_PROMPT;
|
||||
#endif
|
||||
else
|
||||
data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT;
|
||||
break;
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
Leader_DisconnectOnState(data, LL_STATE_CANCEL_PROMPT_HANDLE_INPUT);
|
||||
#endif
|
||||
break;
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
case LL_STATE_CONFIRMED_MEMBERS:
|
||||
if (!Leader_SetStateIfMemberListChanged(data, LL_STATE_ACCEPT_NEW_MEMBER_PROMPT, LL_STATE_SHUTDOWN_AND_FAIL))
|
||||
data->state = LL_STATE_FINAL_MEMBER_CHECK;
|
||||
break;
|
||||
#endif
|
||||
case LL_STATE_FINAL_MEMBER_CHECK:
|
||||
if (LmanAcceptSlotFlagIsNotZero())
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
if (RfuGetStatus() == RFU_STATUS_CONNECTION_ERROR && RfuGetErrorInfo() == LMAN_MSG_LINK_LOSS_DETECTED_AND_DISCONNECTED)
|
||||
{
|
||||
RfuSetStatus(RFU_STATUS_OK, 0);
|
||||
}
|
||||
#endif
|
||||
if (WaitRfuState(FALSE))
|
||||
{
|
||||
data->state = LL_STATE_TRY_START_ACTIVITY;
|
||||
|
|
@ -770,6 +939,18 @@ static void GetGroupLeaderSentAnOKMessage(u8 *dst, u8 caseId)
|
|||
}
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
static void Leader_DisconnectOnState(struct WirelessLink_Leader * data, u8 state)
|
||||
{
|
||||
if (data->state != state) return;
|
||||
if (!RfuTryDisconnectLeavingChildren()) return;
|
||||
data->state = LL_STATE_WAIT_DISCONNECT_CHILD;
|
||||
DestroyYesNoMenu();
|
||||
svc_4f(0);
|
||||
data->textState = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool8 Leader_SetStateIfMemberListChanged(struct WirelessLink_Leader * data, u32 joinedState, u32 droppedState)
|
||||
{
|
||||
switch (LeaderUpdateGroupMembership(data->playerList))
|
||||
|
|
@ -780,11 +961,23 @@ static bool8 Leader_SetStateIfMemberListChanged(struct WirelessLink_Leader * dat
|
|||
CopyAndTranslatePlayerName(gStringVar2, data->playerList->players[data->playerCount]);
|
||||
Leader_GetAcceptNewMemberPrompt(gStringVar4, sPlayerCurrActivity);
|
||||
data->state = joinedState;
|
||||
#if REVISION >= 0xA
|
||||
svc_4f(0);
|
||||
#endif
|
||||
break;
|
||||
case UNION_ROOM_SPAWN_OUT:
|
||||
#if REVISION >= 0xA
|
||||
case UNION_ROOM_SPAWN_OUT_SOON:
|
||||
#endif
|
||||
RfuSetStatus(RFU_STATUS_OK, 0);
|
||||
#if REVISION >= 0xA
|
||||
data->playerCount = LeaderPrunePlayerList(data->playerList);
|
||||
#endif
|
||||
RedrawListMenu(data->listTaskId);
|
||||
data->state = droppedState;
|
||||
#if REVISION >= 0xA
|
||||
svc_4f(0);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -813,9 +1006,13 @@ static void ItemPrintFunc_PossibleGroupMembers(u8 windowId, u32 id, u8 y)
|
|||
static u8 LeaderUpdateGroupMembership(struct RfuPlayerList * list)
|
||||
{
|
||||
struct WirelessLink_Leader * data = sWirelessLinkMain.leader;
|
||||
u8 ret = UNION_ROOM_SPAWN_NONE;
|
||||
u8 i;
|
||||
#if REVISION >= 0xA
|
||||
s32 id;
|
||||
#else
|
||||
u8 ret = UNION_ROOM_SPAWN_NONE;
|
||||
s32 id;
|
||||
#endif
|
||||
u8 i;
|
||||
|
||||
for (i = 1; i < MAX_RFU_PLAYERS; i++)
|
||||
{
|
||||
|
|
@ -833,7 +1030,10 @@ static u8 LeaderUpdateGroupMembership(struct RfuPlayerList * list)
|
|||
{
|
||||
// No new incoming player
|
||||
data->playerList->players[i].groupScheduledAnim = UNION_ROOM_SPAWN_OUT;
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
ret = UNION_ROOM_SPAWN_OUT;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -841,6 +1041,31 @@ static u8 LeaderUpdateGroupMembership(struct RfuPlayerList * list)
|
|||
for (id = 0; id < RFU_CHILD_MAX; id++)
|
||||
TryAddIncomingPlayerToList(data->playerList->players, &data->incomingPlayerList->players[id], MAX_RFU_PLAYERS);
|
||||
|
||||
#if REVISION >= 0xA
|
||||
id = 1;
|
||||
{
|
||||
struct RfuPlayerList* playerList = data->playerList;
|
||||
// spawning out, and countdown = 0 => SPAWN_OUT
|
||||
for (; id < MAX_RFU_PLAYERS; id++)
|
||||
{
|
||||
if (playerList->players[id].groupScheduledAnim == UNION_ROOM_SPAWN_OUT && playerList->players[id].newPlayerCountdown == 0)
|
||||
return UNION_ROOM_SPAWN_OUT;
|
||||
}
|
||||
// spawning out, and countdown != 0 => SPAWN_OUT_SOON
|
||||
for (id = 1; id < MAX_RFU_PLAYERS; id++)
|
||||
{
|
||||
if (playerList->players[id].groupScheduledAnim == UNION_ROOM_SPAWN_OUT && playerList->players[id].newPlayerCountdown != 0)
|
||||
return UNION_ROOM_SPAWN_OUT_SOON;
|
||||
}
|
||||
// spawning in, and countdown != 0 => SPAWN_IN
|
||||
for (id = 0; id < MAX_RFU_PLAYERS; id++)
|
||||
{
|
||||
if (playerList->players[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && playerList->players[id].newPlayerCountdown != 0)
|
||||
return UNION_ROOM_SPAWN_IN;
|
||||
}
|
||||
}
|
||||
return UNION_ROOM_SPAWN_NONE;
|
||||
#else
|
||||
if (ret != UNION_ROOM_SPAWN_OUT)
|
||||
{
|
||||
for (id = 0; id < MAX_RFU_PLAYERS; id++)
|
||||
|
|
@ -851,6 +1076,7 @@ static u8 LeaderUpdateGroupMembership(struct RfuPlayerList * list)
|
|||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
static u8 LeaderPrunePlayerList(struct RfuPlayerList * list)
|
||||
|
|
@ -911,9 +1137,20 @@ void TryJoinLinkGroup(void)
|
|||
gSpecialVar_Result = LINKUP_ONGOING;
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
static u8 svc_50_wrapper() {
|
||||
return svc_50() == TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void Task_TryJoinLinkGroup(u8 taskId)
|
||||
{
|
||||
s32 id;
|
||||
#if REVISION >= 0xA
|
||||
u8 RfuStatus;
|
||||
bool8 RfuStatusIsGroup;
|
||||
u8 handleYN;
|
||||
#endif
|
||||
struct WirelessLink_Group * data = sWirelessLinkMain.group;
|
||||
|
||||
switch (data->state)
|
||||
|
|
@ -1011,7 +1248,10 @@ static void Task_TryJoinLinkGroup(u8 taskId)
|
|||
GetYouAskedToJoinGroupPleaseWaitMessage(gStringVar4, sPlayerCurrActivity);
|
||||
if (PrintOnTextbox(&data->textState, gStringVar4))
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
CopyAndTranslatePlayerName(gStringVar1, data->playerList->players[data->leaderId]);
|
||||
#endif
|
||||
data->state = LG_STATE_MAIN;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1038,71 +1278,158 @@ static void Task_TryJoinLinkGroup(u8 taskId)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (RfuGetStatus())
|
||||
#if REVISION >= 0xA
|
||||
else
|
||||
#endif
|
||||
{
|
||||
case RFU_STATUS_FATAL_ERROR:
|
||||
data->state = LG_STATE_RFU_ERROR;
|
||||
break;
|
||||
case RFU_STATUS_CONNECTION_ERROR:
|
||||
case RFU_STATUS_JOIN_GROUP_NO:
|
||||
case RFU_STATUS_LEAVE_GROUP:
|
||||
data->state = LG_STATE_DISCONNECTED;
|
||||
break;
|
||||
case RFU_STATUS_JOIN_GROUP_OK:
|
||||
GetGroupLeaderSentAnOKMessage(gStringVar4, sPlayerCurrActivity);
|
||||
if (PrintOnTextbox(&data->textState, gStringVar4))
|
||||
{
|
||||
RfuSetStatus(RFU_STATUS_WAIT_ACK_JOIN_GROUP, 0);
|
||||
StringCopy(gStringVar1, sLinkGroupActivityNameTexts[sPlayerCurrActivity]);
|
||||
StringExpandPlaceholders(gStringVar4, gText_UR_AwaitingOtherMembers);
|
||||
}
|
||||
break;
|
||||
case RFU_STATUS_WAIT_ACK_JOIN_GROUP:
|
||||
if (data->delayBeforePrint > 240)
|
||||
|
||||
switch (RfuGetStatus())
|
||||
{
|
||||
case RFU_STATUS_FATAL_ERROR:
|
||||
data->state = LG_STATE_RFU_ERROR;
|
||||
break;
|
||||
case RFU_STATUS_CONNECTION_ERROR:
|
||||
case RFU_STATUS_JOIN_GROUP_NO:
|
||||
case RFU_STATUS_LEAVE_GROUP:
|
||||
data->state = LG_STATE_DISCONNECTED;
|
||||
break;
|
||||
case RFU_STATUS_JOIN_GROUP_OK:
|
||||
#if REVISION >= 0xA
|
||||
CopyAndTranslatePlayerName(gStringVar1, data->playerList->players[data->leaderId]);
|
||||
#endif
|
||||
GetGroupLeaderSentAnOKMessage(gStringVar4, sPlayerCurrActivity);
|
||||
if (PrintOnTextbox(&data->textState, gStringVar4))
|
||||
{
|
||||
RfuSetStatus(RFU_STATUS_ACK_JOIN_GROUP, 0);
|
||||
data->delayBeforePrint = 0;
|
||||
RfuSetStatus(RFU_STATUS_WAIT_ACK_JOIN_GROUP, 0);
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
StringCopy(gStringVar1, sLinkGroupActivityNameTexts[sPlayerCurrActivity]);
|
||||
StringExpandPlaceholders(gStringVar4, gText_UR_AwaitingOtherMembers);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case RFU_STATUS_WAIT_ACK_JOIN_GROUP:
|
||||
if (data->delayBeforePrint > 240)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
StringCopy(gStringVar1, sLinkGroupActivityNameTexts[sPlayerCurrActivity]);
|
||||
StringExpandPlaceholders(gStringVar4, gText_UR_AwaitingOtherMembers);
|
||||
#endif
|
||||
if (PrintOnTextbox(&data->textState, gStringVar4))
|
||||
{
|
||||
RfuSetStatus(RFU_STATUS_ACK_JOIN_GROUP, 0);
|
||||
data->delayBeforePrint = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data->delayBeforePrint++;
|
||||
#if REVISION >= 0xA
|
||||
// fallthrough, to not duplicate code
|
||||
case RFU_STATUS_CHILD_LEAVE_READY:
|
||||
case RFU_STATUS_CHILD_LEAVE:
|
||||
case RFU_STATUS_ACK_JOIN_GROUP:
|
||||
default:
|
||||
if (JOY_NEW(B_BUTTON))
|
||||
{
|
||||
u8 syscallPlayers = svc_50_wrapper(taskId);
|
||||
bool8 noPlayers = FALSE;
|
||||
noPlayers = (syscallPlayers | gReceivedRemoteLinkPlayers) == 0;
|
||||
if (noPlayers)
|
||||
{
|
||||
data->state = LG_STATE_ASK_LEAVE_GROUP;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
if (RfuGetStatus() == RFU_STATUS_OK && JOY_NEW(B_BUTTON))
|
||||
data->state = LG_STATE_ASK_LEAVE_GROUP;
|
||||
#endif
|
||||
break;
|
||||
case LG_STATE_ASK_LEAVE_GROUP:
|
||||
if (PrintOnTextbox(&data->textState, gText_UR_QuitBeingMember))
|
||||
data->state = LG_STATE_ASK_LEAVE_GROUP_HANDLE_INPUT;
|
||||
break;
|
||||
case LG_STATE_ASK_LEAVE_GROUP_HANDLE_INPUT:
|
||||
#if REVISION >= 0xA
|
||||
RfuStatus = RfuGetStatus();
|
||||
RfuStatusIsGroup = (RfuStatus == RFU_STATUS_JOIN_GROUP_OK || RfuStatus == RFU_STATUS_WAIT_ACK_JOIN_GROUP || RfuStatus == RFU_STATUS_ACK_JOIN_GROUP);
|
||||
handleYN = gReceivedRemoteLinkPlayers | svc_50_wrapper();
|
||||
switch (UnionRoomHandleYesNo(&data->textState, handleYN))
|
||||
#else
|
||||
switch (UnionRoomHandleYesNo(&data->textState, RfuGetStatus()))
|
||||
#endif
|
||||
{
|
||||
case 0: // YES
|
||||
SendLeaveGroupNotice();
|
||||
data->state = LG_STATE_WAIT_LEAVE_GROUP;
|
||||
#if REVISION >= 0xA
|
||||
if (RfuStatusIsGroup)
|
||||
#endif
|
||||
{
|
||||
SendLeaveGroupNotice();
|
||||
data->state = LG_STATE_WAIT_LEAVE_GROUP;
|
||||
#if REVISION >= 0xA
|
||||
data->delayBeforePrint = 0;
|
||||
#endif
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
else
|
||||
{
|
||||
data->state = LG_STATE_CANCEL_CHOOSE_LEADER;
|
||||
}
|
||||
#endif
|
||||
RedrawListMenu(data->listTaskId);
|
||||
break;
|
||||
case 1: // NO
|
||||
case MENU_B_PRESSED:
|
||||
data->state = LG_STATE_ASK_JOIN_GROUP;
|
||||
#if REVISION >= 0xA
|
||||
if (RfuStatusIsGroup)
|
||||
{
|
||||
data->state = LG_STATE_MAIN;
|
||||
if (RfuStatus >= RFU_STATUS_WAIT_ACK_JOIN_GROUP)
|
||||
{
|
||||
data->delayBeforePrint = -15;
|
||||
RfuSetStatus(RFU_STATUS_WAIT_ACK_JOIN_GROUP, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
data->state = LG_STATE_ASK_JOIN_GROUP;
|
||||
}
|
||||
RedrawListMenu(data->listTaskId);
|
||||
break;
|
||||
case -3:
|
||||
data->state = LG_STATE_MAIN;
|
||||
#if REVISION >= 0xA
|
||||
if (RfuStatus == RFU_STATUS_WAIT_ACK_JOIN_GROUP)
|
||||
RfuSetStatus(RFU_STATUS_ACK_JOIN_GROUP, 0);
|
||||
#endif
|
||||
RedrawListMenu(data->listTaskId);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LG_STATE_WAIT_LEAVE_GROUP:
|
||||
#if REVISION >= 0xA
|
||||
switch (GetJoinGroupStatus())
|
||||
{
|
||||
case RFU_STATUS_LEAVE_GROUP:
|
||||
data->state = LG_STATE_DISCONNECTED;
|
||||
break;
|
||||
case RFU_STATUS_JOIN_GROUP_NO:
|
||||
data->state = LG_STATE_CANCEL_CHOOSE_LEADER;
|
||||
break;
|
||||
}
|
||||
if (data->delayBeforePrint > 240)
|
||||
data->state = LG_STATE_CANCEL_CHOOSE_LEADER;
|
||||
++data->delayBeforePrint;
|
||||
#else
|
||||
if (RfuGetStatus())
|
||||
data->state = LG_STATE_MAIN;
|
||||
#endif
|
||||
break;
|
||||
case LG_STATE_CANCEL_CHOOSE_LEADER: // next: LG_STATE_CANCELED
|
||||
case LG_STATE_RFU_ERROR: // next: LG_STATE_RFU_ERROR_SHUTDOWN
|
||||
|
|
@ -1155,6 +1482,9 @@ static void Task_TryJoinLinkGroup(u8 taskId)
|
|||
}
|
||||
break;
|
||||
case LG_STATE_SHUTDOWN:
|
||||
#if REVISION >= 0xA
|
||||
DestroyTask_RfuReconnectWithParent();
|
||||
#endif
|
||||
DestroyTask(taskId);
|
||||
JoinGroup_EnableScriptContexts();
|
||||
LinkRfu_Shutdown();
|
||||
|
|
@ -1557,6 +1887,10 @@ static void Task_StartActivity(u8 taskId)
|
|||
break;
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
svc_SetActivity(sPlayerCurrActivity);
|
||||
#endif
|
||||
|
||||
switch (sPlayerCurrActivity)
|
||||
{
|
||||
case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM:
|
||||
|
|
@ -1658,7 +1992,11 @@ static void Task_RunScriptAndFadeToActivity(u8 taskId)
|
|||
}
|
||||
break;
|
||||
case 2:
|
||||
#if REVISION >= 0xA
|
||||
if (IsLinkTaskFinished() && !gPaletteFade.active)
|
||||
#else
|
||||
if (!gPaletteFade.active)
|
||||
#endif
|
||||
{
|
||||
SetLinkStandbyCallback();
|
||||
data[0]++;
|
||||
|
|
@ -2261,7 +2599,11 @@ void RunUnionRoom(void)
|
|||
ListMenuLoadStdPalAt(BG_PLTT_ID(13), 1);
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
u16 ReadU16(const u8 *ptr)
|
||||
#else
|
||||
static u16 ReadAsU16(const u8 *ptr)
|
||||
#endif
|
||||
{
|
||||
return (ptr[1] << 8) | (ptr[0]);
|
||||
}
|
||||
|
|
@ -2281,6 +2623,9 @@ static void ScheduleFieldMessageAndExit(const u8 *src)
|
|||
struct WirelessLink_URoom * uroom = sWirelessLinkMain.uRoom;
|
||||
|
||||
uroom->state = UR_STATE_PRINT_AND_EXIT;
|
||||
#if REVISION >= 0xA
|
||||
uroom->textState = 0;
|
||||
#endif
|
||||
if (src != gStringVar4)
|
||||
StringExpandPlaceholders(gStringVar4, src);
|
||||
}
|
||||
|
|
@ -2478,21 +2823,37 @@ static void Task_RunUnionRoom(u8 taskId)
|
|||
break;
|
||||
case UR_STATE_TRY_COMMUNICATING:
|
||||
UR_RunTextPrinters();
|
||||
#if REVISION >= 0xA
|
||||
LinkRfu_ForceChangeSpParent();
|
||||
#endif
|
||||
switch (RfuGetStatus())
|
||||
{
|
||||
case RFU_STATUS_NEW_CHILD_DETECTED:
|
||||
HandleCancelActivity(TRUE);
|
||||
uroom->state = UR_STATE_MAIN;
|
||||
#if REVISION >= 0xA
|
||||
return;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case RFU_STATUS_FATAL_ERROR:
|
||||
case RFU_STATUS_CONNECTION_ERROR:
|
||||
if (IsUnionRoomListenTaskActive() == TRUE)
|
||||
ScheduleFieldMessageAndExit(gText_UR_TrainerAppearsBusy);
|
||||
else
|
||||
{
|
||||
ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_ACTIVITY_LINK_ERROR, gText_UR_TrainerAppearsBusy);
|
||||
#if REVISION >= 0xA
|
||||
gReceivedRemoteLinkPlayers = FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
sPlayerCurrActivity = IN_UNION_ROOM;
|
||||
#if REVISION >= 0xA
|
||||
return;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (gReceivedRemoteLinkPlayers)
|
||||
|
|
@ -2503,6 +2864,14 @@ static void Task_RunUnionRoom(u8 taskId)
|
|||
}
|
||||
break;
|
||||
case UR_STATE_COMMUNICATING_WAIT_FOR_DATA:
|
||||
#if REVISION >= 0xA
|
||||
if (!gReceivedRemoteLinkPlayers || RfuHasErrored())
|
||||
{
|
||||
DestroyTask(FindTaskIdByFunc(Task_ExchangeCards));
|
||||
uroom->state = UR_STATE_TRAINER_APPEARS_BUSY;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (!FuncIsActiveTask(Task_ExchangeCards))
|
||||
{
|
||||
if (sPlayerCurrActivity == (ACTIVITY_TRADE | IN_UNION_ROOM))
|
||||
|
|
@ -2593,7 +2962,10 @@ static void Task_RunUnionRoom(u8 taskId)
|
|||
case UR_STATE_WAIT_FOR_RESPONSE_TO_REQUEST:
|
||||
if (!gReceivedRemoteLinkPlayers)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
StringCopy(gStringVar4, gText_UR_TrainerBattleBusy);
|
||||
#endif
|
||||
uroom->state = UR_STATE_TRAINER_APPEARS_BUSY;
|
||||
}
|
||||
else
|
||||
|
|
@ -2625,6 +2997,9 @@ static void Task_RunUnionRoom(u8 taskId)
|
|||
ScheduleFieldMessageWithFollowupState(UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT, gTexts_UR_HiDoSomething[id][playerGender]);
|
||||
break;
|
||||
case UR_STATE_PRINT_CARD_INFO:
|
||||
#if REVISION >= 0xA
|
||||
svc_SetActivity(IN_UNION_ROOM | ACTIVITY_CARD);
|
||||
#endif
|
||||
if (PrintOnTextbox(&uroom->textState, gStringVar4))
|
||||
{
|
||||
uroom->state = UR_STATE_WAIT_FINISH_READING_CARD;
|
||||
|
|
@ -2653,6 +3028,15 @@ static void Task_RunUnionRoom(u8 taskId)
|
|||
switch (UnionRoomHandleYesNo(&uroom->textState, FALSE))
|
||||
{
|
||||
case 0: // YES
|
||||
#if REVISION >= 0xA
|
||||
// If not allowed by parental controls, act as if user chose No.
|
||||
if (!svc_CommsAllowedByParentalControls())
|
||||
{
|
||||
playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList);
|
||||
ScheduleFieldMessageAndExit(gTexts_UR_DeclineChat[playerGender]);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
CopyBgTilemapBufferToVram(0);
|
||||
sPlayerCurrActivity = ACTIVITY_CHAT | IN_UNION_ROOM;
|
||||
UpdateGameData_SetActivity(ACTIVITY_CHAT | IN_UNION_ROOM, 0, TRUE);
|
||||
|
|
@ -2705,7 +3089,15 @@ static void Task_RunUnionRoom(u8 taskId)
|
|||
if (IsUnionRoomListenTaskActive() == TRUE)
|
||||
ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]);
|
||||
else
|
||||
{
|
||||
ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_ACTIVITY_LINK_ERROR, gTexts_UR_ChatDeclined[playerGender]);
|
||||
#if REVISION >= 0xA
|
||||
gReceivedRemoteLinkPlayers = FALSE;
|
||||
#endif
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (gReceivedRemoteLinkPlayers)
|
||||
uroom->state = UR_STATE_START_ACTIVITY_FREE_UROOM;
|
||||
|
|
@ -2760,6 +3152,19 @@ static void Task_RunUnionRoom(u8 taskId)
|
|||
switch (UnionRoomHandleYesNo(&uroom->textState, FALSE))
|
||||
{
|
||||
case 0: // ACCEPT
|
||||
#if REVISION >= 0xA
|
||||
// If this is union room chat:
|
||||
// Tell the emulator to check if Switch parental controls allow free communication.
|
||||
// If it is not allowed, then act as if the user selected to deny the request.
|
||||
if (sPlayerCurrActivity == (IN_UNION_ROOM | ACTIVITY_CHAT) && !svc_CommsAllowedByParentalControls())
|
||||
{
|
||||
uroom->playerSendBuffer[0] = ACTIVITY_DECLINE | IN_UNION_ROOM;
|
||||
Rfu_SendPacket(uroom->playerSendBuffer);
|
||||
uroom->state = UR_STATE_DECLINE_ACTIVITY_REQUEST;
|
||||
GetYouDeclinedTheOfferMessage(gStringVar4, sPlayerCurrActivity);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
uroom->playerSendBuffer[0] = ACTIVITY_ACCEPT | IN_UNION_ROOM;
|
||||
if (sPlayerCurrActivity == (ACTIVITY_CHAT | IN_UNION_ROOM))
|
||||
UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetLinkPlayerInfoFlags(1), FALSE);
|
||||
|
|
@ -3112,6 +3517,9 @@ void InitUnionRoom(void)
|
|||
struct WirelessLink_URoom * data;
|
||||
|
||||
sUnionRoomPlayerName[0] = EOS;
|
||||
#if REVISION >= 0xA
|
||||
// The rest of this function is stubbed out, as if QL_IS_PLAYBACK_STATE is always true.
|
||||
#else
|
||||
if (QL_IS_PLAYBACK_STATE)
|
||||
return;
|
||||
CreateTask(Task_InitUnionRoom, 0);
|
||||
|
|
@ -3123,6 +3531,7 @@ void InitUnionRoom(void)
|
|||
data->unknown = 0;
|
||||
data->unreadPlayerId = 0;
|
||||
sUnionRoomPlayerName[0] = EOS;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void Task_InitUnionRoom(u8 taskId)
|
||||
|
|
@ -3264,9 +3673,13 @@ static u8 HandlePlayerListUpdate(void)
|
|||
}
|
||||
else if (data->playerList->players[j].groupScheduledAnim != UNION_ROOM_SPAWN_OUT)
|
||||
{
|
||||
// Person may have disconnected. Give them 10 seconds.
|
||||
// Person may have disconnected. Give them 10 seconds. (15 seconds in rev 10)
|
||||
data->playerList->players[j].timeoutCounter++;
|
||||
#if REVISION >= 0xA
|
||||
if (data->playerList->players[j].timeoutCounter >= 900)
|
||||
#else
|
||||
if (data->playerList->players[j].timeoutCounter >= 600)
|
||||
#endif
|
||||
{
|
||||
data->playerList->players[j].groupScheduledAnim = UNION_ROOM_SPAWN_OUT;
|
||||
retVal = PLIST_RECENT_UPDATE;
|
||||
|
|
@ -3274,9 +3687,13 @@ static u8 HandlePlayerListUpdate(void)
|
|||
}
|
||||
else if (data->playerList->players[j].groupScheduledAnim == UNION_ROOM_SPAWN_OUT)
|
||||
{
|
||||
// Person dropped. Wait 15 seconds, then remove them.
|
||||
// Person dropped. Wait 15 seconds (20 seconds in rev 10), then remove them.
|
||||
data->playerList->players[j].timeoutCounter++;
|
||||
#if REVISION >= 0xA
|
||||
if (data->playerList->players[j].timeoutCounter >= 1200)
|
||||
#else
|
||||
if (data->playerList->players[j].timeoutCounter >= 900)
|
||||
#endif
|
||||
{
|
||||
ClearRfuPlayerList(&data->playerList->players[j], 1);
|
||||
}
|
||||
|
|
@ -3520,6 +3937,14 @@ static s32 ListMenuHandler_AllItemsAvailable(u8 *state, u8 *windowId, u8 *listMe
|
|||
ClearStdWindowAndFrame(*windowId, TRUE);
|
||||
RemoveWindow(*windowId);
|
||||
*state = 0;
|
||||
#if REVISION >= 0xA
|
||||
// If this is the union room chat, and Switch parental controls disallow free communication,
|
||||
// always act as if Cancel was pressed.
|
||||
if ((input & 0xFF) == (ACTIVITY_CHAT | IN_UNION_ROOM) && !svc_CommsAllowedByParentalControls())
|
||||
{
|
||||
return LIST_CANCEL;
|
||||
}
|
||||
#endif
|
||||
return input;
|
||||
}
|
||||
else if (JOY_NEW(B_BUTTON))
|
||||
|
|
|
|||
|
|
@ -179,16 +179,32 @@ void CB2_UnionRoomBattle(void)
|
|||
case 50:
|
||||
if (!UpdatePaletteFade())
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
#else
|
||||
SetLinkStandbyCallback();
|
||||
#endif
|
||||
gMain.state++;
|
||||
}
|
||||
break;
|
||||
case 51:
|
||||
if (IsLinkTaskFinished())
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
SetLinkStandbyCallback();
|
||||
gMain.state++;
|
||||
#else
|
||||
SetMainCallback2(SetUpPartiesAndStartBattle);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#if REVISION >= 0xA
|
||||
case 52:
|
||||
if (IsLinkTaskFinished())
|
||||
{
|
||||
SetMainCallback2(SetUpPartiesAndStartBattle);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 6:
|
||||
if (!gReceivedRemoteLinkPlayers)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "union_room_chat_display.h"
|
||||
#include "keyboard_text.h"
|
||||
#include "constants/songs.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
#define MESSAGE_BUFFER_NCHAR 15
|
||||
|
||||
|
|
@ -806,6 +807,9 @@ static void ChatEntryRoutine_SendMessage(void)
|
|||
switch (sWork->routineState)
|
||||
{
|
||||
case 0:
|
||||
#if REVISION >= 0xA
|
||||
svc_BadWordCheck(sWork->messageEntryBuffer);
|
||||
#endif
|
||||
if (!gReceivedRemoteLinkPlayers)
|
||||
{
|
||||
GoToRoutine(CHATNETRYROUTINE_HANDLE_INPUT);
|
||||
|
|
@ -1162,6 +1166,9 @@ static void RegisterTextAtRow(void)
|
|||
{
|
||||
u8 *src = UnionRoomChat_GetEndOfMessageEntryBuffer();
|
||||
StringCopy(sWork->registeredTexts[sWork->currentRow], src);
|
||||
#if REVISION >= 0xA
|
||||
svc_BadWordCheck(sWork->registeredTexts[sWork->currentRow]);
|
||||
#endif
|
||||
sWork->changedRegisteredTexts = TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "constants/event_object_movement.h"
|
||||
#include "constants/union_room.h"
|
||||
#include "constants/event_objects.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
#define UR_SPRITE_START_ID (MAX_SPRITES - MAX_UNION_ROOM_LEADERS)
|
||||
|
||||
|
|
@ -513,6 +514,14 @@ static void SpawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData * gameDa
|
|||
{
|
||||
case ACTIVITY_NONE | IN_UNION_ROOM:
|
||||
case ACTIVITY_PLYRTALK | IN_UNION_ROOM:
|
||||
#if REVISION >= 0xA
|
||||
if ((svc_4b() & SVC4B_EXIT_EARLY) != 0)
|
||||
{
|
||||
DespawnGroupLeader(leaderId);
|
||||
AssembleGroup(leaderId, gameData);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
SpawnGroupLeader(leaderId, gameData->playerGender, gameData->compatibility.playerTrainerId[0]);
|
||||
for (i = 0; i < MAX_RFU_PLAYERS; i++)
|
||||
DespawnGroupMember(leaderId, i);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "union_room.h"
|
||||
#include "constants/songs.h"
|
||||
#include "constants/union_room.h"
|
||||
#include "sloopsvc.h"
|
||||
|
||||
enum {
|
||||
COLOR_NONE,
|
||||
|
|
@ -41,8 +42,8 @@ static struct
|
|||
u8 filler[10];
|
||||
} * sStatusScreen;
|
||||
|
||||
void Task_WirelessCommunicationScreen(u8 taskId);
|
||||
static void CB2_InitWirelessCommunicationScreen(void);
|
||||
static void Task_WirelessCommunicationScreen(u8 taskId);
|
||||
static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 palIdx);
|
||||
static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * activities, u8 taskId);
|
||||
|
||||
|
|
@ -134,7 +135,7 @@ static const u8 *const sHeaderTexts[NUM_GROUPTYPES + 1] = {
|
|||
// Activity, group type, number of players
|
||||
// 0 players means the number of players can change and should be counted dynamically
|
||||
// GROUPTYPE_TOTAL have no unique group and are simply counted in the total of "people communicating".
|
||||
// A handful use NUM_GROUPTYPES, which is invalid, and are changed to GROUPTYPE_TOTAL in Emerald.
|
||||
// A handful use NUM_GROUPTYPES, which is invalid, and are changed to GROUPTYPE_TOTAL in Emerald (and Revision 10)
|
||||
// UB: GROUPTYPE_NONE (-1) can potentially be used as an index into a u8[4] in CountPlayersInGroupAndGetActivity.
|
||||
static const u8 sActivityGroupInfo[][3] = {
|
||||
{ACTIVITY_BATTLE_SINGLE, GROUPTYPE_BATTLE, 2},
|
||||
|
|
@ -143,13 +144,23 @@ static const u8 sActivityGroupInfo[][3] = {
|
|||
{ACTIVITY_TRADE, GROUPTYPE_TRADE, 2},
|
||||
{ACTIVITY_WONDER_CARD, GROUPTYPE_TOTAL, 2},
|
||||
{ACTIVITY_WONDER_NEWS, GROUPTYPE_TOTAL, 2},
|
||||
#if REVISION >= 0xA
|
||||
{ACTIVITY_POKEMON_JUMP, GROUPTYPE_TOTAL, 0},
|
||||
{ACTIVITY_BERRY_CRUSH, GROUPTYPE_TOTAL, 0},
|
||||
{ACTIVITY_BERRY_PICK, GROUPTYPE_TOTAL, 0},
|
||||
#else
|
||||
{ACTIVITY_POKEMON_JUMP, NUM_GROUPTYPES, 0},
|
||||
{ACTIVITY_BERRY_CRUSH, NUM_GROUPTYPES, 0},
|
||||
{ACTIVITY_BERRY_PICK, NUM_GROUPTYPES, 0},
|
||||
#endif
|
||||
{ACTIVITY_SEARCH, GROUPTYPE_NONE, 0},
|
||||
{ACTIVITY_SPIN_TRADE, GROUPTYPE_TRADE, 0},
|
||||
{ACTIVITY_ITEM_TRADE, GROUPTYPE_NONE, 0},
|
||||
#if REVISION >= 0xA
|
||||
{ACTIVITY_RECORD_CORNER, GROUPTYPE_TOTAL, 0},
|
||||
#else
|
||||
{ACTIVITY_RECORD_CORNER, NUM_GROUPTYPES, 0},
|
||||
#endif
|
||||
{ACTIVITY_BERRY_BLENDER, GROUPTYPE_NONE, 0},
|
||||
{ACTIVITY_NONE | IN_UNION_ROOM, GROUPTYPE_UNION, 1},
|
||||
{ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM, GROUPTYPE_UNION, 2},
|
||||
|
|
@ -278,7 +289,7 @@ static void PrintHeaderTexts(void)
|
|||
|
||||
#define tState data[0]
|
||||
|
||||
static void Task_WirelessCommunicationScreen(u8 taskId)
|
||||
void Task_WirelessCommunicationScreen(u8 taskId)
|
||||
{
|
||||
s32 i;
|
||||
switch (gTasks[taskId].tState)
|
||||
|
|
@ -313,7 +324,11 @@ static void Task_WirelessCommunicationScreen(u8 taskId)
|
|||
PutWindowTilemap(2);
|
||||
CopyWindowToVram(2, COPYWIN_FULL);
|
||||
}
|
||||
#if REVISION >= 0xA
|
||||
if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON) || svc_53())
|
||||
#else
|
||||
if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON))
|
||||
#endif
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
gTasks[sStatusScreen->rfuTaskId].data[15] = 0xFF;
|
||||
|
|
@ -372,6 +387,40 @@ static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *
|
|||
|
||||
static u32 CountPlayersInGroupAndGetActivity(struct RfuPlayer * player, u32 * groupCounts)
|
||||
{
|
||||
#if REVISION >= 0xA
|
||||
u32 activity = player->rfu.data.activity;
|
||||
if (player->groupScheduledAnim == UNION_ROOM_SPAWN_IN)
|
||||
{
|
||||
|
||||
u32 i = 0;
|
||||
const u8 * group_info = &sActivityGroupInfo[0][0];
|
||||
const u8 * group_players = &group_info[2];
|
||||
const u8 * group_activity = group_info;
|
||||
s32 offset = 0;
|
||||
for (; i < ARRAY_COUNT(sActivityGroupInfo); i++)
|
||||
{
|
||||
const u8 * group_type = &group_info[1];
|
||||
u8 type = ((u8*)offset)[(u32)group_type]; // needed to match, but nobody would write this???
|
||||
if (type < MAX_LINK_PLAYERS && activity == *group_activity)
|
||||
{
|
||||
u8 k = *group_players;
|
||||
if (k == 0)
|
||||
{
|
||||
s32 j;
|
||||
for (j = 0; j < RFU_CHILD_MAX; j++)
|
||||
if (player->rfu.data.partnerInfo[j] != 0) k++;
|
||||
k++;
|
||||
}
|
||||
groupCounts[type] += k;
|
||||
break;
|
||||
}
|
||||
group_players += sizeof(sActivityGroupInfo[0]);
|
||||
group_activity += sizeof(sActivityGroupInfo[0]);
|
||||
offset += (u8)sizeof(sActivityGroupInfo[0]);
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
u32 activity = player->rfu.data.activity;
|
||||
s32 i, j, k;
|
||||
|
||||
|
|
@ -398,11 +447,13 @@ static u32 CountPlayersInGroupAndGetActivity(struct RfuPlayer * player, u32 * gr
|
|||
}
|
||||
}
|
||||
|
||||
return activity;
|
||||
|
||||
#undef group_activity
|
||||
#undef group_type
|
||||
#undef group_players
|
||||
#endif
|
||||
|
||||
return activity;
|
||||
|
||||
}
|
||||
|
||||
static bool32 HaveCountsChanged(const u32 * curCounts, const u32 * prevCounts)
|
||||
|
|
@ -435,6 +486,9 @@ static bool32 UpdateCommunicationCounts(u32 * groupCounts, u32 * prevGroupCounts
|
|||
}
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
if (HaveCountsChanged(groupCountBuffer, prevGroupCounts))
|
||||
#else
|
||||
if (!HaveCountsChanged(groupCountBuffer, prevGroupCounts))
|
||||
{
|
||||
if (activitiesUpdated == TRUE)
|
||||
|
|
@ -442,16 +496,27 @@ static bool32 UpdateCommunicationCounts(u32 * groupCounts, u32 * prevGroupCounts
|
|||
else
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
memcpy(groupCounts, groupCountBuffer, sizeof(groupCountBuffer));
|
||||
memcpy(prevGroupCounts, groupCountBuffer, sizeof(groupCountBuffer));
|
||||
|
||||
memcpy(groupCounts, groupCountBuffer, sizeof(groupCountBuffer));
|
||||
memcpy(prevGroupCounts, groupCountBuffer, sizeof(groupCountBuffer));
|
||||
|
||||
groupCounts[GROUPTYPE_TOTAL] = groupCounts[GROUPTYPE_TRADE]
|
||||
+ groupCounts[GROUPTYPE_BATTLE]
|
||||
+ groupCounts[GROUPTYPE_UNION]
|
||||
#ifdef BUGFIX
|
||||
+ groupCounts[GROUPTYPE_TOTAL] // Missing count for activities not in above groups
|
||||
#endif
|
||||
;
|
||||
groupCounts[GROUPTYPE_TOTAL] = groupCounts[GROUPTYPE_TRADE]
|
||||
+ groupCounts[GROUPTYPE_BATTLE]
|
||||
+ groupCounts[GROUPTYPE_UNION]
|
||||
#if defined(BUGFIX) || REVISION >= 0xA
|
||||
+ groupCounts[GROUPTYPE_TOTAL] // Missing count for activities not in above groups
|
||||
#endif
|
||||
;
|
||||
|
||||
#if REVISION >= 0xA
|
||||
activitiesUpdated = TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if REVISION >= 0xA
|
||||
return activitiesUpdated;
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
.include "src/malloc.o"
|
||||
.include "src/text_printer.o"
|
||||
.include "src/sprite.o"
|
||||
.include "src/sloopsvc.o"
|
||||
.include "src/link.o"
|
||||
.include "src/multiboot.o"
|
||||
.include "src/daycare.o"
|
||||
|
|
|
|||
38
sym_bss_rev10.txt
Normal file
38
sym_bss_rev10.txt
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
.include "src/gpu_regs.o"
|
||||
.include "src/dma3_manager.o"
|
||||
.include "src/bg.o"
|
||||
.include "src/malloc.o"
|
||||
.include "src/text_printer.o"
|
||||
.include "src/librfu_stwi.o"
|
||||
.include "src/librfu_rfu.o"
|
||||
.include "src/sprite.o"
|
||||
.include "src/sloopsvc.o"
|
||||
.include "src/link.o"
|
||||
.include "src/multiboot.o"
|
||||
.include "src/daycare.o"
|
||||
.include "src/trade.o"
|
||||
.include "src/play_time.o"
|
||||
.include "src/overworld.o"
|
||||
.include "src/field_camera.o"
|
||||
.include "src/script.o"
|
||||
.include "src/start_menu.o"
|
||||
.include "src/tileset_anims.o"
|
||||
.include "src/sound.o"
|
||||
.include "src/field_effect.o"
|
||||
.include "src/pokemon_storage_system_misc.o"
|
||||
.include "src/easy_chat.o"
|
||||
.include "src/link_rfu_2.o"
|
||||
.include "src/link_rfu_3.o"
|
||||
.include "src/quest_log.o"
|
||||
.include "src/union_room.o"
|
||||
.include "src/pokemon_special_anim_scene.o"
|
||||
.include "src/wireless_communication_status_screen.o"
|
||||
.include "src/dodrio_berry_picking.o"
|
||||
.include "src/ereader_helpers.o"
|
||||
.include "src/digit_obj_util.o"
|
||||
.include "src/m4a_1.o"
|
||||
.include "data/sound_data.o"
|
||||
.include "src/agb_flash.o"
|
||||
.include "*libgcc.a:dp-bit.o"
|
||||
.include "*libgcc.a:fp-bit.o"
|
||||
.include "*libc.a:syscalls.o"
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
.include "window.o"
|
||||
.include "text.o"
|
||||
.include "sprite.o"
|
||||
.include "sloopsvc.o"
|
||||
.include "link.o"
|
||||
.align 4
|
||||
.include "battle_main.o"
|
||||
|
|
|
|||
56
sym_common_rev10.txt
Normal file
56
sym_common_rev10.txt
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
.include "main.o"
|
||||
.include "bg.o"
|
||||
.include "text_printer.o"
|
||||
.align 4
|
||||
.include "window.o"
|
||||
.include "librfu_stwi.o"
|
||||
.align 4
|
||||
.include "librfu_rfu.o"
|
||||
.include "text.o"
|
||||
.include "sprite.o"
|
||||
.align 4
|
||||
.include "sloopsvc.o"
|
||||
.include "link.o"
|
||||
.align 4
|
||||
.include "battle_main.o"
|
||||
.include "random.o"
|
||||
.include "load_save.o"
|
||||
.include "overworld.o"
|
||||
.align 4
|
||||
.include "fieldmap.o"
|
||||
.align 4
|
||||
.include "field_camera.o"
|
||||
.include "scrcmd.o"
|
||||
.include "field_control_avatar.o"
|
||||
.include "event_data.o"
|
||||
.include "sound.o"
|
||||
.include "task.o"
|
||||
.include "cable_club.o"
|
||||
.include "image_processing_effects.o"
|
||||
.include "field_specials.o"
|
||||
.include "evolution_scene.o"
|
||||
.include "save.o"
|
||||
.include "battle_anim_special.o"
|
||||
.include "save_failed_screen.o"
|
||||
.align 4
|
||||
.include "link_rfu_2.o"
|
||||
.align 4
|
||||
.include "AgbRfu_LinkManager.o"
|
||||
.align 4
|
||||
.include "list_menu.o"
|
||||
.include "quest_log.o"
|
||||
.include "union_room.o"
|
||||
.include "party_menu.o"
|
||||
.include "help_system.o"
|
||||
.align 4
|
||||
.include "fame_checker.o"
|
||||
.include "help_system_util.o"
|
||||
.align 4
|
||||
.include "ereader_screen.o"
|
||||
.align 4
|
||||
.include "battle_controller_pokedude.o"
|
||||
.align 4
|
||||
.include "berry_fix_program.o"
|
||||
.include "m4a.o"
|
||||
.include "agb_flash.o"
|
||||
.include "librfu_sio32id.o"
|
||||
137
sym_ewram_rev10.txt
Normal file
137
sym_ewram_rev10.txt
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
.include "src/main.o"
|
||||
.include "src/malloc.o"
|
||||
.include "src/text_printer.o"
|
||||
.include "src/window.o"
|
||||
.include "src/window_8bpp.o"
|
||||
.include "src/sprite.o"
|
||||
.include "src/string_util.o"
|
||||
.include "src/link.o"
|
||||
.space 8
|
||||
.include "src/battle_controllers.o"
|
||||
.include "src/battle_main.o"
|
||||
.include "src/pokemon.o"
|
||||
.include "src/daycare.o"
|
||||
.include "src/load_save.o"
|
||||
.include "src/trade.o"
|
||||
.include "src/trade_scene.o"
|
||||
.include "src/new_game.o"
|
||||
.include "src/overworld.o"
|
||||
.include "src/fieldmap.o"
|
||||
.include "src/field_camera.o"
|
||||
.include "src/field_player_avatar.o"
|
||||
.include "src/event_object_movement.o"
|
||||
.include "src/field_message_box.o"
|
||||
.include "src/script.o"
|
||||
.include "src/scrcmd.o"
|
||||
.include "src/event_data.o"
|
||||
.include "src/start_menu.o"
|
||||
.include "src/tileset_anims.o"
|
||||
.include "src/palette.o"
|
||||
.include "src/sound.o"
|
||||
.include "src/battle_anim.o"
|
||||
.include "src/battle_anim_mons.o"
|
||||
.include "src/title_screen.o"
|
||||
.include "src/field_weather.o"
|
||||
.include "src/battle_setup.o"
|
||||
.include "src/wild_encounter.o"
|
||||
.include "src/field_effect.o"
|
||||
.include "src/scanline_effect.o"
|
||||
.include "src/option_menu.o"
|
||||
.include "src/trainer_card.o"
|
||||
.include "src/pokemon_storage_system_menu.o"
|
||||
.include "src/pokemon_storage_system_tasks.o"
|
||||
.include "src/pokemon_storage_system_data.o"
|
||||
.include "src/pokemon_storage_system_misc.o"
|
||||
.include "src/script_movement.o"
|
||||
.include "src/fldeff_cut.o"
|
||||
.include "src/item_menu_icons.o"
|
||||
.include "src/item.o"
|
||||
.include "src/shop.o"
|
||||
.include "src/special_field_anim.o"
|
||||
.include "src/script_menu.o"
|
||||
.include "src/naming_screen.o"
|
||||
.include "src/money.o"
|
||||
.include "src/safari_zone.o"
|
||||
.include "src/item_use.o"
|
||||
.include "src/battle_anim_effects_1.o"
|
||||
.include "src/battle_anim_dragon.o"
|
||||
.include "src/battle_anim_utility_funcs.o"
|
||||
.include "src/battle_intro.o"
|
||||
.include "src/easy_chat.o"
|
||||
.include "src/mon_markings.o"
|
||||
.include "src/mail.o"
|
||||
.include "src/menu_helpers.o"
|
||||
.include "src/region_map.o"
|
||||
.include "src/battle_ai_script_commands.o"
|
||||
.include "src/fldeff_rocksmash.o"
|
||||
.include "src/field_specials.o"
|
||||
.include "src/battle_records.o"
|
||||
.include "src/evolution_scene.o"
|
||||
.include "src/coins.o"
|
||||
.include "src/battle_transition.o"
|
||||
.include "src/battle_message.o"
|
||||
.include "src/save.o"
|
||||
.include "src/mystery_event_script.o"
|
||||
.include "src/fldeff_sweetscent.o"
|
||||
.include "src/learn_move.o"
|
||||
.include "src/battle_tower.o"
|
||||
.include "src/player_pc.o"
|
||||
.include "src/intro.o"
|
||||
.include "src/hall_of_fame.o"
|
||||
.include "src/credits.o"
|
||||
.include "src/diploma.o"
|
||||
.include "src/save_failed_screen.o"
|
||||
.include "src/clear_save_data_screen.o"
|
||||
.include "src/new_menu_helpers.o"
|
||||
.include "src/tilemap_util.o"
|
||||
.include "src/map_preview_screen.o"
|
||||
.include "src/link_rfu_2.o"
|
||||
.include "src/link_rfu_3.o"
|
||||
.include "src/easy_chat_2.o"
|
||||
.include "src/easy_chat_3.o"
|
||||
.include "src/pokedex_screen.o"
|
||||
.include "src/list_menu.o"
|
||||
.include "src/item_menu.o"
|
||||
.include "src/bag.o"
|
||||
.include "src/trainer_pokemon_sprites.o"
|
||||
.include "src/vs_seeker.o"
|
||||
.include "src/item_pc.o"
|
||||
.include "src/mailbox_pc.o"
|
||||
.include "src/menu.o"
|
||||
.include "src/quest_log.o"
|
||||
.include "src/help_message.o"
|
||||
.include "src/quest_log_events.o"
|
||||
.include "src/union_room.o"
|
||||
.include "src/union_room_player_avatar.o"
|
||||
.include "src/union_room_battle.o"
|
||||
.include "src/pokemon_special_anim.o"
|
||||
.include "src/party_menu.o"
|
||||
.include "src/union_room_chat.o"
|
||||
.include "src/union_room_chat_display.o"
|
||||
.include "src/union_room_chat_objects.o"
|
||||
.include "src/help_system.o"
|
||||
.include "src/fame_checker.o"
|
||||
.include "src/oak_speech.o"
|
||||
.include "src/tm_case.o"
|
||||
.include "src/menu_indicators.o"
|
||||
.include "src/pokemon_summary_screen.o"
|
||||
.include "src/help_system_util.o"
|
||||
.include "src/dynamic_placeholder_text_util.o"
|
||||
.include "src/berry_pouch.o"
|
||||
.include "src/slot_machine.o"
|
||||
.include "src/roamer.o"
|
||||
.include "src/mystery_gift_menu.o"
|
||||
.include "src/mystery_gift.o"
|
||||
.include "src/mystery_gift_link.o"
|
||||
.include "src/mystery_gift_client.o"
|
||||
.include "src/mystery_gift_server.o"
|
||||
.include "src/mystery_gift_show_card.o"
|
||||
.include "src/mystery_gift_show_news.o"
|
||||
.include "src/seagallop.o"
|
||||
.include "src/pokemon_jump.o"
|
||||
.include "src/berry_crush.o"
|
||||
.include "src/dodrio_berry_picking.o"
|
||||
.include "src/teachy_tv.o"
|
||||
.include "src/digit_obj_util.o"
|
||||
.include "src/trainer_tower.o"
|
||||
.include "src/berry_powder.o"
|
||||
Loading…
Reference in New Issue
Block a user