Merge branch 'master' of https://github.com/pret/pokeemerald into decompile_item_menu

This commit is contained in:
golem galvanize
2018-01-31 00:29:38 -05:00
42 changed files with 1694 additions and 3277 deletions

View File

@@ -64,7 +64,7 @@ void HandleLinkBattleSetup(void)
if (gLinkVSyncDisabled)
sub_800B488();
if (!gReceivedRemoteLinkPlayers)
sub_8009734();
OpenLink();
CreateTask(task00_08081A90, 0);
CreateTasksForSendRecvLinkBuffers();
}
@@ -793,9 +793,9 @@ static void Task_HandleSendLinkBuffersData(u8 taskId)
else
var = (gBattleTypeFlags & BATTLE_TYPE_MULTI) ? 4 : 2;
if (sub_800ABAC() >= var)
if (GetLinkPlayerCount_2() >= var)
{
if (sub_800ABBC())
if (IsLinkMaster())
{
sub_800A620();
gTasks[taskId].data[11]++;

119
src/coord_event_weather.c Normal file
View File

@@ -0,0 +1,119 @@
#include "global.h"
#include "constants/weather.h"
#include "coord_event_weather.h"
#include "field_weather.h"
struct CoordEventWeather
{
u8 coordEventWeather;
void (*func)(void);
};
static void CoordEventWeather_Clouds(void);
static void CoordEventWeather_Sunny(void);
static void CoordEventWeather_LightRain(void);
static void CoordEventWeather_Snow(void);
static void CoordEventWeather_Thunderstorm(void);
static void CoordEventWeather_Fog(void);
static void CoordEventWeather_DiagonalFog(void);
static void CoordEventWeather_Ash(void);
static void CoordEventWeather_Sandstorm(void);
static void CoordEventWeather_Dark(void);
static void CoordEventWeather_Drought(void);
static void CoordEventWeather_Route119Cycle(void);
static void CoordEventWeather_Route123Cycle(void);
static const struct CoordEventWeather sCoordEventWeatherFuncs[] =
{
{ COORD_EVENT_WEATHER_CLOUDS, CoordEventWeather_Clouds },
{ COORD_EVENT_WEATHER_SUNNY, CoordEventWeather_Sunny },
{ COORD_EVENT_WEATHER_RAIN_LIGHT, CoordEventWeather_LightRain },
{ COORD_EVENT_WEATHER_SNOW, CoordEventWeather_Snow },
{ COORD_EVENT_WEATHER_RAIN_MED, CoordEventWeather_Thunderstorm },
{ COORD_EVENT_WEATHER_FOG_1, CoordEventWeather_Fog },
{ COORD_EVENT_WEATHER_FOG_2, CoordEventWeather_DiagonalFog },
{ COORD_EVENT_WEATHER_ASH, CoordEventWeather_Ash },
{ COORD_EVENT_WEATHER_SANDSTORM, CoordEventWeather_Sandstorm },
{ COORD_EVENT_WEATHER_SHADE, CoordEventWeather_Dark },
{ COORD_EVENT_WEATHER_DROUGHT, CoordEventWeather_Drought },
{ COORD_EVENT_WEATHER_ROUTE119_CYCLE, CoordEventWeather_Route119Cycle },
{ COORD_EVENT_WEATHER_ROUTE123_CYCLE, CoordEventWeather_Route123Cycle },
};
static void CoordEventWeather_Clouds(void)
{
SetWeather(WEATHER_CLOUDS);
}
static void CoordEventWeather_Sunny(void)
{
SetWeather(WEATHER_SUNNY);
}
static void CoordEventWeather_LightRain(void)
{
SetWeather(WEATHER_RAIN_LIGHT);
}
static void CoordEventWeather_Snow(void)
{
SetWeather(WEATHER_SNOW);
}
static void CoordEventWeather_Thunderstorm(void)
{
SetWeather(WEATHER_RAIN_MED);
}
static void CoordEventWeather_Fog(void)
{
SetWeather(WEATHER_FOG_1);
}
static void CoordEventWeather_DiagonalFog(void)
{
SetWeather(WEATHER_FOG_2);
}
static void CoordEventWeather_Ash(void)
{
SetWeather(WEATHER_ASH);
}
static void CoordEventWeather_Sandstorm(void)
{
SetWeather(WEATHER_SANDSTORM);
}
static void CoordEventWeather_Dark(void)
{
SetWeather(WEATHER_SHADE);
}
static void CoordEventWeather_Drought(void)
{
SetWeather(WEATHER_DROUGHT);
}
static void CoordEventWeather_Route119Cycle(void)
{
SetWeather(WEATHER_ROUTE119_CYCLE);
}
static void CoordEventWeather_Route123Cycle(void)
{
SetWeather(WEATHER_ROUTE123_CYCLE);
}
void DoCoordEventWeather(u8 coordEventWeather)
{
u8 i;
for (i = 0; i < ARRAY_COUNT(sCoordEventWeatherFuncs); i++)
{
if (sCoordEventWeatherFuncs[i].coordEventWeather == coordEventWeather)
{
sCoordEventWeatherFuncs[i].func();
return;
}
}
}

View File

@@ -14,7 +14,7 @@
#include "rom_818CFC8.h"
#include "rom_81BE66C.h"
#include "field_ground_effect.h"
#include "map_obj_8097404.h"
#include "field_map_obj_helpers.h"
#include "mauville_old_man.h"
#include "metatile_behavior.h"
#include "field_effect.h"

844
src/field_map_obj_helpers.c Executable file
View File

@@ -0,0 +1,844 @@
#include "global.h"
#include "field_ground_effect.h"
#include "field_map_obj.h"
#include "field_effect.h"
#include "field_map_obj_helpers.h"
#include "malloc.h"
#include "task.h"
#include "util.h"
typedef void (*SpriteStepFunc)(struct Sprite *sprite, u8 dir);
extern const struct Coords16 gUnknown_0850DB7C[4];
extern s16 gUnknown_0850E768[];
extern SpriteStepFunc *const gUnknown_0850E754[];
extern const s8 gUnknown_0850E772[];
extern const s8 gUnknown_0850E7BA[];
extern const s8 *const gUnknown_0850E834[];
extern s16 gUnknown_0850E840[];
extern u8 gUnknown_0850E846[];
extern s16 gUnknown_0850E84A[];
extern u8 gUnknown_0850E850[];
void sub_8097D68(struct Sprite *sprite);
void sub_8097FE4(u8);
bool8 FreezeMapObject(struct MapObject *mapObject)
{
if (mapObject->mapobj_bit_6 || mapObject->mapobj_bit_8)
{
return TRUE;
}
else
{
mapObject->mapobj_bit_8 = 1;
mapObject->mapobj_bit_23 = gSprites[mapObject->spriteId].animPaused;
mapObject->mapobj_bit_24 = gSprites[mapObject->spriteId].affineAnimPaused;
gSprites[mapObject->spriteId].animPaused = 1;
gSprites[mapObject->spriteId].affineAnimPaused = 1;
return FALSE;
}
}
void FreezeMapObjects(void)
{
u8 i;
for (i = 0; i < MAP_OBJECTS_COUNT; i++)
if (gMapObjects[i].active && i != gPlayerAvatar.mapObjectId)
FreezeMapObject(&gMapObjects[i]);
}
void FreezeMapObjectsExceptOne(u8 a1)
{
u8 i;
for (i = 0; i < MAP_OBJECTS_COUNT; i++)
if (i != a1 && gMapObjects[i].active && i != gPlayerAvatar.mapObjectId)
FreezeMapObject(&gMapObjects[i]);
}
void npc_sync_anim_pause_bits(struct MapObject *mapObject)
{
if (mapObject->active && mapObject->mapobj_bit_8)
{
mapObject->mapobj_bit_8 = 0;
gSprites[mapObject->spriteId].animPaused = mapObject->mapobj_bit_23;
gSprites[mapObject->spriteId].affineAnimPaused = mapObject->mapobj_bit_24;
}
}
void UnfreezeMapObjects(void)
{
u8 i;
for (i = 0; i < MAP_OBJECTS_COUNT; i++)
if (gMapObjects[i].active)
npc_sync_anim_pause_bits(&gMapObjects[i]);
}
void little_step(struct Sprite *sprite, u8 dir)
{
sprite->pos1.x += gUnknown_0850DB7C[dir].x;
sprite->pos1.y += gUnknown_0850DB7C[dir].y;
}
void double_little_steps(struct Sprite *sprite, u8 dir)
{
sprite->pos1.x += 2 * (u16) gUnknown_0850DB7C[dir].x;
sprite->pos1.y += 2 * (u16) gUnknown_0850DB7C[dir].y;
}
void triple_little_steps(struct Sprite *sprite, u8 dir)
{
sprite->pos1.x += 2 * (u16) gUnknown_0850DB7C[dir].x + (u16) gUnknown_0850DB7C[dir].x;
sprite->pos1.y += 2 * (u16) gUnknown_0850DB7C[dir].y + (u16) gUnknown_0850DB7C[dir].y;
}
void quad_little_steps(struct Sprite *sprite, u8 dir)
{
sprite->pos1.x += 4 * (u16) gUnknown_0850DB7C[dir].x;
sprite->pos1.y += 4 * (u16) gUnknown_0850DB7C[dir].y;
}
void oct_little_steps(struct Sprite *sprite, u8 dir)
{
sprite->pos1.x += 8 * (u16) gUnknown_0850DB7C[dir].x;
sprite->pos1.y += 8 * (u16) gUnknown_0850DB7C[dir].y;
}
void oamt_npc_ministep_reset(struct Sprite *sprite, u8 a2, u8 a3)
{
sprite->data[3] = a2;
sprite->data[4] = a3;
sprite->data[5] = 0;
}
bool8 obj_npc_ministep(struct Sprite *sprite)
{
if (sprite->data[5] >= gUnknown_0850E768[sprite->data[4]])
return FALSE;
gUnknown_0850E754[sprite->data[4]][sprite->data[5]](sprite, sprite->data[3]);
sprite->data[5]++;
if (sprite->data[5] < gUnknown_0850E768[sprite->data[4]])
return FALSE;
return TRUE;
}
void sub_80976DC(struct Sprite *sprite, u8 a2)
{
sprite->data[3] = a2;
sprite->data[4] = 0;
sprite->data[5] = 0;
}
bool8 sub_80976EC(struct Sprite *sprite)
{
if (!(sprite->data[4] & 1))
{
little_step(sprite, sprite->data[3]);
sprite->data[5]++;
}
sprite->data[4]++;
if (sprite->data[5] > 15)
return TRUE;
else
return FALSE;
}
// new helper added here in the middle. Perhaps Game Freak kept these organized in alphebetical order or some other heirarchy?
s16 sub_8097728(s16 a1)
{
return gUnknown_0850E7BA[a1];
}
s16 sub_809773C(s16 a1)
{
return gUnknown_0850E772[a1];
}
void sub_8097750(struct Sprite *sprite)
{
sprite->data[6] = 0;
sprite->data[7] = 0;
}
bool8 sub_8097758(struct Sprite *sprite)
{
bool8 result = FALSE;
switch(sprite->data[7])
{
case 0:
sprite->pos2.x += sub_809773C(sprite->data[6]);
sprite->pos2.y += sub_8097728(sprite->data[6]);
break;
case 1:
sprite->pos2.x -= sub_809773C(0x47 - sprite->data[6]);
sprite->pos2.y += sub_8097728(0x47 - sprite->data[6]);
break;
case 2:
sprite->pos2.x -= sub_809773C(sprite->data[6]);
sprite->pos2.y += sub_8097728(sprite->data[6]);
break;
case 3:
sprite->pos2.x += sub_809773C(0x47 - sprite->data[6]);
sprite->pos2.y += sub_8097728(0x47 - sprite->data[6]);
break;
}
if(++sprite->data[6] == 0x48)
{
sprite->data[6] = 0;
sprite->data[7]++;
}
if(sprite->data[7] == 0x4)
{
sprite->pos2.y = 0;
sprite->pos2.x = 0;
result = TRUE;
}
return result;
}
s16 sub_8097820(s16 a1, u8 a2)
{
return gUnknown_0850E834[a2][a1];
}
void sub_809783C(struct Sprite *sprite, u8 a2, u8 a3, u8 a4)
{
sprite->data[3] = a2;
sprite->data[4] = a3;
sprite->data[5] = a4;
sprite->data[6] = 0;
}
u8 sub_809785C(struct Sprite *sprite)
{
s16 v5[3];
u8 v6[3];
u8 v2;
memcpy(v5, gUnknown_0850E840, 6); // TODO: get rid of memcpy
memcpy(v6, gUnknown_0850E846, 3);
v2 = 0;
if (sprite->data[4])
little_step(sprite, sprite->data[3]);
sprite->pos2.y = sub_8097820(sprite->data[6] >> v6[sprite->data[4]], sprite->data[5]);
sprite->data[6]++;
if (sprite->data[6] == (v5[sprite->data[4]] >> 1))
v2 = 1;
if (sprite->data[6] >= v5[sprite->data[4]])
{
sprite->pos2.y = 0;
v2 = -1;
}
return v2;
}
u8 sub_80978E4(struct Sprite *sprite)
{
s16 v5[3];
u8 v6[3];
u8 v2;
memcpy(v5, gUnknown_0850E84A, 6);
memcpy(v6, gUnknown_0850E850, 3);
v2 = 0;
if (sprite->data[4] && !(sprite->data[6] & 1))
little_step(sprite, sprite->data[3]);
sprite->pos2.y = sub_8097820(sprite->data[6] >> v6[sprite->data[4]], sprite->data[5]);
sprite->data[6]++;
if (sprite->data[6] == (v5[sprite->data[4]] >> 1))
v2 = 1;
if (sprite->data[6] >= v5[sprite->data[4]])
{
sprite->pos2.y = 0;
v2 = -1;
}
return v2;
}
void SetFieldObjectStepTimer(struct Sprite *sprite, u16 timer)
{
sprite->data[3] = timer;
}
bool8 RunFieldObjectStepTimer(struct Sprite *sprite)
{
sprite->data[3]--;
if (sprite->data[3] == 0)
return TRUE;
else
return FALSE;
}
void obj_anim_image_set_and_seek(struct Sprite *sprite, u8 a2, u8 a3)
{
sprite->animNum = a2;
sprite->animPaused = 0 ;
SeekSpriteAnim(sprite, a3);
}
bool8 sub_80979BC(struct Sprite *sprite)
{
if (sprite->animEnded)
return TRUE;
else
return FALSE;
}
void sub_80979D4(struct Sprite *sprite, bool8 invisible)
{
u16 x, y;
s16 x2, y2;
sprite->invisible = invisible;
if (sprite->coordOffsetEnabled)
{
x = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX + gSpriteCoordOffsetX;
y = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY;
}
else
{
x = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX;
y = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY;
}
x2 = x - (sprite->centerToCornerVecX >> 1);
y2 = y - (sprite->centerToCornerVecY >> 1);
if ((s16)x > 255 || x2 < -16)
sprite->invisible = 1;
if ((s16)y > 175 || y2 < -16)
sprite->invisible = 1;
}
void sub_8097AC8(struct Sprite *sprite)
{
sub_8097D68(sprite);
SetObjectSubpriorityByZCoord(sprite->data[1], sprite, 1);
sub_80979D4(sprite, sprite->data[2]);
}
void sub_8097AF0(void)
{
int i;
for(i = 0; i < MAX_SPRITES; i++)
{
struct Sprite *sprite = &gSprites[i];
if(sprite->inUse && sprite->callback == sub_8097AC8)
DestroySprite(sprite);
}
}
int sub_8097B2C(u8 var) // this should return a u8, because all that call this shifts to u8, but it wont match because it doesnt shift u8 at the end.
{
int i;
for(i = 0; i < MAX_SPRITES; i++)
{
struct Sprite *sprite = &gSprites[i];
if(sprite->inUse && sprite->callback == sub_8097AC8 && (u8)sprite->data[0] == var)
return i;
}
return MAX_SPRITES;
}
void sub_8097B78(u8 var1, u8 var2)
{
u8 spriteId = sub_8097B2C(var1);
if(spriteId != MAX_SPRITES)
StartSpriteAnim(&gSprites[spriteId], FieldObjectDirectionToImageAnimId(var2));
}
void sub_8097BB4(u8 var1, u8 var2)
{
int spriteId = sub_8097B2C(var1);
if(spriteId != MAX_SPRITES)
{
struct Sprite *sprite = &gSprites[spriteId];
const struct MapObjectGraphicsInfo *gfxInfo = GetFieldObjectGraphicsInfo(var2);
u16 tileNum = sprite->oam.tileNum;
sprite->oam = *gfxInfo->oam;
sprite->oam.tileNum = tileNum;
sprite->oam.paletteNum = gfxInfo->paletteSlot;
sprite->images = gfxInfo->images;
if(gfxInfo->subspriteTables == NULL)
{
sprite->subspriteTables = NULL;
sprite->subspriteTableNum = 0;
sprite->subspriteMode = 0;
}
else
{
SetSubspriteTables(sprite, gfxInfo->subspriteTables);
sprite->subspriteMode = 2;
}
StartSpriteAnim(sprite, 0);
}
}
void sub_8097C44(u8 var, bool32 var2)
{
u8 spriteId = sub_8097B2C(var);
if(spriteId == MAX_SPRITES)
return;
if(var2)
gSprites[spriteId].data[2] = 1;
else
gSprites[spriteId].data[2] = 0;
}
bool32 sub_8097C8C(u8 var)
{
u8 spriteId = sub_8097B2C(var);
if(spriteId == MAX_SPRITES)
return FALSE;
return (gSprites[spriteId].data[2] == TRUE);
}
void sub_8097CC4(u8 var1, u8 var2)
{
u8 spriteId = sub_8097B2C(var1);
if(spriteId != MAX_SPRITES)
{
gSprites[spriteId].data[3] = var2;
gSprites[spriteId].data[4] = 0;
}
}
void sub_8097CF4(struct Sprite *sprite)
{
switch(sprite->data[4])
{
case 0:
sprite->pos2.y = 0;
sprite->data[4]++;
case 1:
sprite->pos2.y -= 8;
if(sprite->pos2.y == -160)
{
sprite->pos2.y = 0;
sprite->data[2] = 1;
sprite->data[3] = 0;
sprite->data[4] = 0;
}
}
}
void sub_8097D30(struct Sprite *sprite)
{
switch(sprite->data[4])
{
case 0:
sprite->pos2.y = -160;
sprite->data[4]++;
case 1:
sprite->pos2.y += 8;
if(sprite->pos2.y == 0)
{
sprite->data[3] = 0;
sprite->data[4] = 0;
}
}
}
void sub_8097D68(struct Sprite *sprite)
{
switch(sprite->data[3])
{
case 1:
sub_8097D30(sprite);
break;
case 2:
sub_8097CF4(sprite);
break;
case 0:
break;
default:
sprite->data[3] = 0;
break;
}
}
bool32 sub_8097D9C(u8 var)
{
u8 spriteId = sub_8097B2C(var);
if(spriteId == MAX_SPRITES)
return FALSE;
if(gSprites[spriteId].data[3] != FALSE)
return TRUE;
return FALSE;
}
u32 oe_exec_and_other_stuff(u8 fieldEffectId, struct MapObject *mapObject)
{
FieldObjectGetLocalIdAndMap(mapObject, &gFieldEffectArguments[0], &gFieldEffectArguments[1], &gFieldEffectArguments[2]);
return FieldEffectStart(fieldEffectId);
}
void DoShadowFieldEffect(struct MapObject *mapObject)
{
if (!mapObject->mapobj_bit_22)
{
mapObject->mapobj_bit_22 = 1;
oe_exec_and_other_stuff(FLDEFF_SHADOW, mapObject);
}
}
void DoRippleFieldEffect(struct MapObject *mapObject, struct Sprite *sprite)
{
const struct MapObjectGraphicsInfo *gfxInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
gFieldEffectArguments[0] = sprite->pos1.x;
gFieldEffectArguments[1] = sprite->pos1.y + (gfxInfo->height >> 1) - 2;
gFieldEffectArguments[2] = 151;
gFieldEffectArguments[3] = 3;
FieldEffectStart(FLDEFF_RIPPLE);
}
#ifdef NONMATCHING
bool32 sub_8097E50(struct MapObject *mapObject, struct Sprite *sprite)
{
bool32 ableToStore = FALSE;
if (gUnknown_020375B8 == NULL)
{
gUnknown_020375B8 = AllocZeroed(0x14);
gUnknown_020375B8[0] = mapObject->localId;
gUnknown_020375B8[16] = 1;
ableToStore = TRUE;
}
else
{
u8 i;
u8 firstFreeSlot;
bool32 found;
for (firstFreeSlot = 16, found = FALSE, i = 0; i < 16; i++)
{
if (firstFreeSlot == 16 && gUnknown_020375B8[i] == 0)
firstFreeSlot = i;
if (gUnknown_020375B8[i] == mapObject->localId)
{
found = TRUE;
break;
}
}
if (!found && firstFreeSlot != 16)
{
gUnknown_020375B8[firstFreeSlot] = mapObject->localId;
gUnknown_020375B8[16]++;
ableToStore = TRUE; // the nonmatching problem is that ableToStore == TRUE isnt being merged with the above ableToStore = TRUE assignment.
}
}
if (ableToStore == TRUE)
{
mapObject->mapobj_bit_12 = TRUE;
mapObject->mapobj_bit_9 = TRUE;
}
sprite->data[2] = 1;
return TRUE;
}
#else
__attribute__((naked))
bool32 sub_8097E50(struct MapObject *mapObject, struct Sprite *sprite)
{
asm(".syntax unified\n\
push {r4-r7,lr}\n\
mov r7, r8\n\
push {r7}\n\
adds r4, r0, 0\n\
mov r8, r1\n\
movs r0, 0\n\
mov r12, r0\n\
ldr r0, =gUnknown_020375B8\n\
ldr r1, [r0]\n\
adds r6, r0, 0\n\
cmp r1, 0\n\
bne _08097E80\n\
movs r0, 0x14\n\
bl AllocZeroed\n\
str r0, [r6]\n\
ldrb r1, [r4, 0x8]\n\
strb r1, [r0]\n\
ldr r1, [r6]\n\
movs r0, 0x1\n\
strb r0, [r1, 0x10]\n\
b _08097ECC\n\
.pool\n\
_08097E80:\n\
movs r2, 0x10\n\
movs r5, 0\n\
movs r1, 0\n\
adds r3, r6, 0\n\
b _08097E90\n\
_08097E8A:\n\
adds r0, r1, 0x1\n\
lsls r0, 24\n\
lsrs r1, r0, 24\n\
_08097E90:\n\
cmp r1, 0xF\n\
bhi _08097EB2\n\
cmp r2, 0x10\n\
bne _08097EA4\n\
ldr r0, [r3]\n\
adds r0, r1\n\
ldrb r0, [r0]\n\
cmp r0, 0\n\
bne _08097EA4\n\
adds r2, r1, 0\n\
_08097EA4:\n\
ldr r0, [r3]\n\
adds r0, r1\n\
ldrb r0, [r0]\n\
ldrb r7, [r4, 0x8]\n\
cmp r0, r7\n\
bne _08097E8A\n\
movs r5, 0x1\n\
_08097EB2:\n\
cmp r5, 0\n\
bne _08097ECE\n\
cmp r2, 0x10\n\
beq _08097ECE\n\
ldr r0, [r6]\n\
adds r0, r2\n\
ldrb r1, [r4, 0x8]\n\
strb r1, [r0]\n\
ldr r1, [r6]\n\
ldrb r0, [r1, 0x10]\n\
adds r0, 0x1\n\
strb r0, [r1, 0x10]\n\
movs r0, 0x1\n\
_08097ECC:\n\
mov r12, r0\n\
_08097ECE:\n\
mov r1, r12\n\
cmp r1, 0x1\n\
bne _08097EE0\n\
ldrb r0, [r4, 0x1]\n\
movs r1, 0x10\n\
orrs r0, r1\n\
movs r1, 0x2\n\
orrs r0, r1\n\
strb r0, [r4, 0x1]\n\
_08097EE0:\n\
movs r0, 0x1\n\
mov r7, r8\n\
strh r0, [r7, 0x32]\n\
pop {r3}\n\
mov r8, r3\n\
pop {r4-r7}\n\
pop {r1}\n\
bx r1\n\
.syntax divided");
}
#endif
// this function is very similar to the above one and I don't want to decompile this one until the above is matching.
__attribute__((naked))
bool32 sub_8097EF0(struct MapObject *mapObject, struct Sprite *sprite)
{
asm(".syntax unified\n\
push {r4-r7,lr}\n\
mov r7, r8\n\
push {r7}\n\
adds r6, r0, 0\n\
mov r8, r1\n\
movs r0, 0x1\n\
strh r0, [r1, 0x32]\n\
ldr r5, =gUnknown_020375B8\n\
ldr r0, [r5]\n\
cmp r0, 0\n\
beq _08097F68\n\
movs r7, 0\n\
adds r0, r6, 0\n\
bl sub_8097F78\n\
lsls r0, 24\n\
lsrs r1, r0, 24\n\
cmp r1, 0x10\n\
beq _08097F28\n\
ldr r0, [r5]\n\
adds r0, r1\n\
movs r1, 0\n\
strb r1, [r0]\n\
ldr r1, [r5]\n\
ldrb r0, [r1, 0x10]\n\
subs r0, 0x1\n\
strb r0, [r1, 0x10]\n\
movs r7, 0x1\n\
_08097F28:\n\
ldr r0, [r5]\n\
ldrb r4, [r0, 0x10]\n\
cmp r4, 0\n\
bne _08097F36\n\
bl Free\n\
str r4, [r5]\n\
_08097F36:\n\
cmp r7, 0x1\n\
bne _08097F68\n\
ldrb r0, [r6, 0x5]\n\
bl GetFieldObjectGraphicsInfo\n\
ldrb r1, [r0, 0xC]\n\
lsls r1, 25\n\
lsrs r1, 31\n\
lsls r1, 4\n\
ldrb r2, [r6, 0x1]\n\
movs r0, 0x11\n\
negs r0, r0\n\
ands r0, r2\n\
orrs r0, r1\n\
movs r1, 0x3\n\
negs r1, r1\n\
ands r0, r1\n\
strb r0, [r6, 0x1]\n\
mov r2, r8\n\
adds r2, 0x2C\n\
ldrb r1, [r2]\n\
movs r0, 0x41\n\
negs r0, r0\n\
ands r0, r1\n\
strb r0, [r2]\n\
_08097F68:\n\
movs r0, 0x1\n\
pop {r3}\n\
mov r8, r3\n\
pop {r4-r7}\n\
pop {r1}\n\
bx r1\n\
.pool\n\
.syntax divided");
}
u8 sub_8097F78(struct MapObject *mapObject)
{
u8 i;
for(i = 0; i < MAP_OBJECTS_COUNT; i++)
{
if(gUnknown_020375B8[i] == mapObject->localId)
return i;
}
return MAP_OBJECTS_COUNT;
}
void sub_8097FA4(struct MapObject *mapObject)
{
u8 taskId = CreateTask(sub_8097FE4, 0xFF);
struct Task *task = &gTasks[taskId];
StoreWordInTwoHalfwords(&task->data[0], (u32)mapObject);
mapObject->mapobj_unk_1B = taskId;
task->data[3] = 0xFFFF;
}
void sub_8097FE4(u8 taskId)
{
struct MapObject *mapObject;
struct Sprite *sprite;
struct Task *task = &gTasks[taskId];
LoadWordFromTwoHalfwords(&task->data[0], (u32 *)&mapObject); // load the map object pointer.
sprite = &gSprites[mapObject->spriteId];
if(!(task->data[2] & 0x3))
sprite->pos2.y += task->data[3];
if(!(task->data[2] & 0xF))
task->data[3] = -task->data[3];
task->data[2]++;
}
void sub_8098044(u8 taskId)
{
u32 word;
struct Task *task = &gTasks[taskId];
LoadWordFromTwoHalfwords(&task->data[0], &word); // huh??? why does it load a word that never gets used???
DestroyTask(taskId);
}
void sub_8098074(u8 var1, u8 var2)
{
u8 i;
for(i = 0; i < MAP_OBJECTS_COUNT; i++)
{
if(i != var1 && i != var2 &&
gMapObjects[i].active && i != gPlayerAvatar.mapObjectId)
FreezeMapObject(&gMapObjects[i]);
}
}
bool32 sub_80980C0(struct MapObject *mapObject, struct Sprite *sprite)
{
sprite->pos2.y = 0;
sprite->data[2]++;
return FALSE;
}
bool32 sub_80980D0(struct MapObject *mapObject, struct Sprite *sprite)
{
sprite->pos2.y -= 8;
if(sprite->pos2.y == -160)
sprite->data[2]++;
return FALSE;
}
bool32 sub_80980F4(struct MapObject *mapObject, struct Sprite *sprite)
{
sprite->pos2.y = -160;
sprite->data[2]++;
return FALSE;
}
bool32 sub_8098108(struct MapObject *mapObject, struct Sprite *sprite)
{
sprite->pos2.y += 8;
if(!sprite->pos2.y)
sprite->data[2]++;
return FALSE;
}
// though this function returns TRUE without doing anything, this header is required due to being in an array of functions which needs it.
bool32 sub_8098124(struct MapObject *mapObject, struct Sprite *sprite)
{
return TRUE;
}

154
src/field_message_box.c Executable file
View File

@@ -0,0 +1,154 @@
#include "global.h"
#include "new_menu_helpers.h"
#include "string.h"
#include "string_util.h"
#include "task.h"
#include "text.h"
EWRAM_DATA u8 gUnknown_020375BC = 0;
void textbox_fdecode_auto_and_task_add(u8*, int);
void textbox_auto_and_task_add(void);
void sub_8098128(void)
{
gUnknown_020375BC = 0;
gTextFlags.flag_0 = 0;
gTextFlags.flag_1 = 0;
gTextFlags.flag_2 = 0;
gTextFlags.flag_3 = 0;
}
void sub_8098154(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
sub_81973A4();
task->data[0]++;
break;
case 1:
sub_81973C4(0, 1);
task->data[0]++;
break;
case 2:
if (sub_8197224() != 1)
{
gUnknown_020375BC = 0;
DestroyTask(taskId);
}
}
}
void task_add_textbox(void)
{
CreateTask(sub_8098154, 0x50);
}
void task_del_textbox(void)
{
u8 taskId = FindTaskIdByFunc(sub_8098154);
if (taskId != 0xFF)
DestroyTask(taskId);
}
bool8 ShowFieldMessage(u8 *str)
{
if (gUnknown_020375BC != 0)
return FALSE;
textbox_fdecode_auto_and_task_add(str, 1);
gUnknown_020375BC = 2;
return TRUE;
}
void sub_8098214(u8 taskId)
{
if (sub_8196094() == 0)
{
gUnknown_020375BC = 0;
DestroyTask(taskId);
}
}
bool8 sub_8098238(u8 *str)
{
if (gUnknown_020375BC != 0)
return FALSE;
StringExpandPlaceholders(gStringVar4, str);
CreateTask(sub_8098214, 0);
sub_8196080(str);
gUnknown_020375BC = 2;
return TRUE;
}
bool8 ShowFieldAutoScrollMessage(u8 *str)
{
if (gUnknown_020375BC != 0)
return FALSE;
gUnknown_020375BC = 3;
textbox_fdecode_auto_and_task_add(str, 0);
return TRUE;
}
bool8 sub_80982A0(u8 *str)
{
gUnknown_020375BC = 3;
textbox_fdecode_auto_and_task_add(str, 1);
return TRUE;
}
bool8 sub_80982B8(void)
{
if (gUnknown_020375BC != 0)
return FALSE;
gUnknown_020375BC = 2;
textbox_auto_and_task_add();
return TRUE;
}
void textbox_fdecode_auto_and_task_add(u8* str, int a)
{
StringExpandPlaceholders(gStringVar4, str);
AddTextPrinterForMessage(a);
task_add_textbox();
}
void textbox_auto_and_task_add(void)
{
AddTextPrinterForMessage(1);
task_add_textbox();
}
void HideFieldMessageBox(void)
{
task_del_textbox();
sub_8197434(0, 1);
gUnknown_020375BC = 0;
}
u8 textbox_any_visible(void)
{
return gUnknown_020375BC;
}
bool8 IsFieldMessageBoxHidden(void)
{
if (gUnknown_020375BC == 0)
return TRUE;
return FALSE;
}
void sub_8098358(void)
{
task_del_textbox();
sub_81973FC(0, 1);
gUnknown_020375BC = 0;
}
void sub_8098374(void)
{
task_del_textbox();
gUnknown_020375BC = 0;
}

View File

@@ -15,7 +15,7 @@
#include "field_screen.h"
#include "field_weather.h"
#include "item.h"
#include "map_obj_8097404.h"
#include "field_map_obj_helpers.h"
#include "mail.h"
#include "metatile_behavior.h"
#include "overworld.h"

303
src/mystery_event_menu.c Normal file
View File

@@ -0,0 +1,303 @@
#include "global.h"
#include "mystery_event_menu.h"
#include "link.h"
#include "main.h"
#include "menu.h"
#include "mystery_event_script.h"
#include "palette.h"
#include "save.h"
#include "constants/songs.h"
#include "sound.h"
#include "sprite.h"
#include "string_util.h"
#include "strings.h"
#include "task.h"
#include "text.h"
#include "bg.h"
#include "window.h"
#include "gpu_regs.h"
#include "text_window.h"
#include "new_menu_helpers.h"
#include "decompress.h"
// this file's functions
static void CB2_MysteryEventMenu(void);
static void PrintMysteryMenuText(u8 windowId, const u8 *text, u8 x, u8 y, s32 speed);
// EWRAM vars
static EWRAM_DATA u8 sUnknown_0203BCF8 = 0; // set but unused
// const rom data
static const struct BgTemplate sBgTemplates[] =
{
{
.bg = 0,
.charBaseIndex = 2,
.mapBaseIndex = 31,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
}
};
static const struct WindowTemplate sWindowTemplates[] =
{
{0, 4, 15, 22, 4, 14, 20},
{0, 7, 6, 16, 4, 14, 0x6C},
DUMMY_WIN_TEMPLATE
};
// code
static void VBlankCB(void)
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
static bool8 CheckLanguageMatch(void)
{
return (gLinkPlayers[0].language == gLinkPlayers[1].language);
}
void CB2_InitMysteryEventMenu(void)
{
ResetSpriteData();
FreeAllSpritePalettes();
ResetTasks();
SetVBlankCallback(VBlankCB);
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates));
if (InitWindows(sWindowTemplates))
{
s32 i;
DeactivateAllTextPrinters();
for (i = 0; i < 2; i++)
FillWindowPixelBuffer(i, 0);
FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x1E, 0x14);
sub_809882C(0, 1u, 0xD0u);
sub_81978B0(0xE0);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
CreateTask(Task_DestroySelf, 0);
StopMapMusic();
RunTasks();
AnimateSprites();
BuildOamBuffer();
RunTextPrinters();
UpdatePaletteFade();
FillPalette(0, 0, 2);
SetMainCallback2(CB2_MysteryEventMenu);
}
}
static bool8 GetEventLoadMessage(u8 *dest, u32 status)
{
bool8 retVal = TRUE;
if (status == 0)
{
StringCopy(dest, gText_EventSafelyLoaded);
retVal = FALSE;
}
if (status == 2)
retVal = FALSE;
if (status == 1)
StringCopy(dest, gText_LoadErrorEndingSession);
return retVal;
}
static void CB2_MysteryEventMenu(void)
{
switch (gMain.state)
{
case 0:
SetWindowBorderStyle(0, 1, 1, 0xD);
PutWindowTilemap(0);
CopyWindowToVram(0, 3);
ShowBg(0);
BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
gMain.state++;
break;
case 1:
if (!gPaletteFade.active)
{
PrintMysteryMenuText(0, gText_LinkStandby2, 1, 2, 1);
gMain.state++;
}
break;
case 2:
if (!IsTextPrinterActive(0))
{
gMain.state++;
gLinkType = 21761;
OpenLink();
}
break;
case 3:
if ((gLinkStatus & 0x20) && (gLinkStatus & 0x1C) > 4)
{
PlaySE(SE_PIN);
PrintMysteryMenuText(0, gText_PressAToLoadEvent, 1, 2, 1);
gMain.state++;
}
if (gMain.newKeys & B_BUTTON)
{
PlaySE(SE_SELECT);
CloseLink();
gMain.state = 15;
}
break;
case 4:
if (!IsTextPrinterActive(0))
gMain.state++;
break;
case 5:
if (GetLinkPlayerCount_2() == 2)
{
if (gMain.newKeys & A_BUTTON)
{
PlaySE(SE_SELECT);
sub_800A620();
SetWindowBorderStyle(1, 1, 1, 0xD);
PrintMysteryMenuText(1, gText_LoadingEvent, 1, 2, 0);
PutWindowTilemap(1);
CopyWindowToVram(1, 3);
gMain.state++;
}
else if (gMain.newKeys & B_BUTTON)
{
PlaySE(SE_SELECT);
CloseLink();
gMain.state = 15;
}
}
else
{
GetEventLoadMessage(gStringVar4, 1);
PrintMysteryMenuText(0, gStringVar4, 1, 2, 1);
gMain.state = 13;
}
break;
case 6:
if (IsLinkConnectionEstablished())
{
if (gReceivedRemoteLinkPlayers != 0)
{
if (sub_800A0C8(2, 2) == 3)
{
sub_800AC34();
GetEventLoadMessage(gStringVar4, 1);
PrintMysteryMenuText(0, gStringVar4, 1, 2, 1);
gMain.state = 13;
}
else if (CheckLanguageMatch())
{
PrintMysteryMenuText(0, gText_DontRemoveCableTurnOff, 1, 2, 1);
gMain.state++;
}
else
{
CloseLink();
GetEventLoadMessage(gStringVar4, 1);
PrintMysteryMenuText(0, gStringVar4, 1, 2, 1);
gMain.state = 13;
}
}
}
else if (gMain.newKeys & B_BUTTON)
{
PlaySE(SE_SELECT);
CloseLink();
gMain.state = 15;
}
break;
case 7:
if (!IsTextPrinterActive(0))
gMain.state++;
break;
case 8:
if (GetBlockReceivedStatus())
{
ResetBlockReceivedFlags();
gMain.state++;
}
break;
case 9:
gMain.state++;
break;
case 10:
sub_800AC34();
gMain.state++;
break;
case 11:
if (gReceivedRemoteLinkPlayers == 0)
{
u16 unkVal = RunMysteryEventScript(gDecompressionBuffer);
CpuFill32(0, gDecompressionBuffer, 0x7D4);
if (!GetEventLoadMessage(gStringVar4, unkVal))
TrySavingData(NORMAL_SAVE);
gMain.state++;
}
break;
case 12:
PrintMysteryMenuText(0, gStringVar4, 1, 2, 1);
gMain.state++;
break;
case 13:
if (!IsTextPrinterActive(0))
{
gMain.state++;
sUnknown_0203BCF8 = 0;
}
break;
case 14:
if (gMain.newKeys & A_BUTTON)
{
PlaySE(SE_SELECT);
gMain.state++;
}
break;
case 15:
BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
gMain.state++;
break;
case 16:
if (!gPaletteFade.active)
DoSoftReset();
break;
}
if (gLinkStatus & 0x40 && !IsLinkMaster())
{
CloseLink();
GetEventLoadMessage(gStringVar4, 1);
PrintMysteryMenuText(0, gStringVar4, 1, 2, 1);
gMain.state = 13;
}
RunTasks();
AnimateSprites();
BuildOamBuffer();
RunTextPrinters();
UpdatePaletteFade();
}
static void PrintMysteryMenuText(u8 windowId, const u8 *text, u8 x, u8 y, s32 speed)
{
struct TextColor textColor;
u8 letterSpacing = 0;
u8 lineSpacing = 1;
textColor.fgColor = 1;
textColor.bgColor = 2;
textColor.shadowColor = 3;
FillWindowPixelBuffer(windowId, (textColor.fgColor) | (textColor.fgColor << 4));
AddTextPrinterParameterized2(windowId, 1, x, y, letterSpacing, lineSpacing, &textColor, speed, text);
}

View File

@@ -6,7 +6,7 @@
#include "field_effect.h"
#include "field_map_obj.h"
#include "field_player_avatar.h"
#include "map_obj_8097404.h"
#include "field_map_obj_helpers.h"
#include "pokenav.h"
#include "task.h"
#include "util.h"
@@ -639,7 +639,7 @@ void sub_80B45D0(void)
gApproachingTrainerId++;
gSpecialVar_Result = 1;
UnfreezeMapObjects();
sub_80974D0(gApproachingTrainers[1].mapObjectId);
FreezeMapObjectsExceptOne(gApproachingTrainers[1].mapObjectId);
}
else
{