diff options
Diffstat (limited to 'src/field')
| -rw-r--r-- | src/field/field_weather.c | 325 | ||||
| -rw-r--r-- | src/field/field_weather_2.c | 1511 | ||||
| -rw-r--r-- | src/field/field_weather_effects.c | 2383 | ||||
| -rw-r--r-- | src/field/overworld.c | 6 | ||||
| -rw-r--r-- | src/field/scrcmd.c | 2 | 
5 files changed, 2551 insertions, 1676 deletions
| diff --git a/src/field/field_weather.c b/src/field/field_weather.c index 80fe21c4b..ff7c2e4c4 100644 --- a/src/field/field_weather.c +++ b/src/field/field_weather.c @@ -28,10 +28,10 @@ struct WeatherPaletteData  struct WeatherCallbacks  { -    void (*func0)(void); -    void (*func1)(void); -    void (*func2)(void); -    u8 (*func3)(void); +    void (*initVars)(void); +    void (*main)(void); +    void (*initAll)(void); +    bool8 (*finish)(void);  };  extern struct Weather gWeather; @@ -48,7 +48,7 @@ const u8 DroughtPaletteData_5[] = INCBIN_U8("graphics/weather/drought5.bin.lz");  extern u8 (*gUnknown_0202FC48)[32];  extern u8 gUnknown_0202F9E8[32]; -const u8 *const gUnknown_08396FA8[] = +static const u8 *const sCompressedDroughtPalettes[] =  {      DroughtPaletteData_0,      DroughtPaletteData_1, @@ -65,83 +65,83 @@ const u8 *const gUnknown_08396FA8[] =  // this file produces the same result as accessing gWeather directly.  struct Weather *const gWeatherPtr = &gWeather; -void sub_807CAE8(void); -void nullsub_38(void); -u8 sub_807CB0C(void); -void sub_807DE78(void); -void sub_807DEF4(void); -void sub_807DEC4(void); -u8 sub_807DF54(void); -void sub_807DF9C(void); -void nullsub_55(void); -void sub_807DFC0(void); -u8 sub_807DFD0(void); +void None_Init(void); +void None_Main(void); +bool8 None_Finish(void); +void Clouds_InitVars(void); +void Clouds_Main(void); +void Clouds_InitAll(void); +bool8 Clouds_Finish(void); +void Weather2_InitVars(void); +void Weather2_Main(void); +void Weather2_InitAll(void); +bool8 Weather2_Finish(void);  void LightRain_InitVars(void); -void sub_807E400(void); -void sub_807E3D0(void); -u8 sub_807E460(void); +void LightRain_Main(void); +void LightRain_InitAll(void); +bool8 LightRain_Finish(void);  void Snow_InitVars(void); -void snowflakes_progress2(void); -void sub_807EA18(void); -u8 sub_807EAC0(void); -void sub_807EE80(void); -void sub_807EFC0(void); -void sub_807EEF4(void); -u8 sub_807F34C(void); -void sub_807F49C(void); -void sub_807F52C(void); -void sub_807F4FC(void); -u8 sub_807F5EC(void); -void sub_807F7F8(void); -void sub_807F888(void); -void sub_807F858(void); -u8 sub_807F934(void); -void sub_807FE9C(void); -void sub_807FF4C(void); -void sub_807FF1C(void); -u8 sub_807FFC8(void); -void sub_807FB24(void); -void sub_807FBD8(void); -void sub_807FBA8(void); -u8 sub_807FC3C(void); -void sub_807F49C(void); -void sub_807F52C(void); -void sub_807F4FC(void); -u8 sub_807F5EC(void); -void sub_8080430(void); -void nullsub_56(void); -void sub_8080460(void); -u8 sub_8080470(void); -void sub_807E110(void); -void sub_807E174(void); -void sub_807E144(void); -u8 sub_807E258(void); -void sub_807EF24(void); -void sub_807EFC0(void); -void sub_807EF90(void); -u8 sub_807F34C(void); -void sub_8080474(void); -void sub_80804F8(void); -void sub_80804C8(void); -u8 sub_808056C(void); - -const struct WeatherCallbacks gUnknown_08396FC8[] = +void Snow_Main(void); +void Snow_InitAll(void); +bool8 Snow_Finish(void); +void MedRain_InitVars(void); +void Rain_Main(void); +void MedRain_InitAll(void); +bool8 Rain_Finish(void); +void Fog1_InitVars(void); +void Fog1_Main(void); +void Fog1_InitAll(void); +bool8 Fog1_Finish(void); +void Ash_InitVars(void); +void Ash_Main(void); +void Ash_InitAll(void); +bool8 Ash_Finish(void); +void Sandstorm_InitVars(void); +void Sandstorm_Main(void); +void Sandstorm_InitAll(void); +bool8 Sandstorm_Finish(void); +void Fog2_InitVars(void); +void Fog2_Main(void); +void Fog2_InitAll(void); +bool8 Fog2_Finish(void); +void Fog1_InitVars(void); +void Fog1_Main(void); +void Fog1_InitAll(void); +bool8 Fog1_Finish(void); +void Weather11_InitVars(void); +void Weather11_Main(void); +void Weather11_InitAll(void); +bool8 Weather11_Finish(void); +void Drought_InitVars(void); +void Drought_Main(void); +void Drought_InitAll(void); +bool8 Drought_Finish(void); +void HeavyRain_InitVars(void); +void Rain_Main(void); +void HeavyRain_InitAll(void); +bool8 Rain_Finish(void); +void Bubbles_InitVars(void); +void Bubbles_Main(void); +void Bubbles_InitAll(void); +bool8 Bubbles_Finish(void); + +static const struct WeatherCallbacks sWeatherFuncs[] =  { -    {sub_807CAE8, nullsub_38, sub_807CAE8, sub_807CB0C}, -    {sub_807DE78, sub_807DEF4, sub_807DEC4, sub_807DF54}, -    {sub_807DF9C, nullsub_55, sub_807DFC0, sub_807DFD0}, -    {LightRain_InitVars, sub_807E400, sub_807E3D0, sub_807E460},           // light rain -    {Snow_InitVars, snowflakes_progress2, sub_807EA18, sub_807EAC0},  // snow -    {sub_807EE80, sub_807EFC0, sub_807EEF4, sub_807F34C}, -    {sub_807F49C, sub_807F52C, sub_807F4FC, sub_807F5EC}, -    {sub_807F7F8, sub_807F888, sub_807F858, sub_807F934}, -    {sub_807FE9C, sub_807FF4C, sub_807FF1C, sub_807FFC8}, -    {sub_807FB24, sub_807FBD8, sub_807FBA8, sub_807FC3C}, -    {sub_807F49C, sub_807F52C, sub_807F4FC, sub_807F5EC}, -    {sub_8080430, nullsub_56, sub_8080460, sub_8080470}, -    {sub_807E110, sub_807E174, sub_807E144, sub_807E258}, -    {sub_807EF24, sub_807EFC0, sub_807EF90, sub_807F34C}, -    {sub_8080474, sub_80804F8, sub_80804C8, sub_808056C}, +    {None_Init,          None_Main,      None_Init,         None_Finish}, +    {Clouds_InitVars,    Clouds_Main,    Clouds_InitAll,    Clouds_Finish}, +    {Weather2_InitVars,  Weather2_Main,  Weather2_InitAll,  Weather2_Finish}, +    {LightRain_InitVars, LightRain_Main, LightRain_InitAll, LightRain_Finish},           // light rain +    {Snow_InitVars,      Snow_Main,      Snow_InitAll,      Snow_Finish}, +    {MedRain_InitVars,   Rain_Main,      MedRain_InitAll,   Rain_Finish}, +    {Fog1_InitVars,      Fog1_Main,      Fog1_InitAll,      Fog1_Finish}, +    {Ash_InitVars,       Ash_Main,       Ash_InitAll,       Ash_Finish}, +    {Sandstorm_InitVars, Sandstorm_Main, Sandstorm_InitAll, Sandstorm_Finish}, +    {Fog2_InitVars,      Fog2_Main,      Fog2_InitAll,      Fog2_Finish}, +    {Fog1_InitVars,      Fog1_Main,      Fog1_InitAll,      Fog1_Finish}, +    {Weather11_InitVars, Weather11_Main, Weather11_InitAll, Weather11_Finish}, +    {Drought_InitVars,   Drought_Main,   Drought_InitAll,   Drought_Finish}, +    {HeavyRain_InitVars, Rain_Main,      HeavyRain_InitAll, Rain_Finish}, +    {Bubbles_InitVars,   Bubbles_Main,   Bubbles_InitAll,   Bubbles_Finish},  };  void (*const gUnknown_083970B8[])(void) = @@ -190,33 +190,33 @@ const u8 gUnknown_083970C8[] =  const u16 gUnknown_083970E8[] = INCBIN_U16("graphics/weather/0.gbapal"); -void sub_807C828(void) +void StartWeather(void)  {      u8 index; -    if (!FuncIsActiveTask(sub_807CA34)) +    if (!FuncIsActiveTask(Task_WeatherMain))      {          index = AllocSpritePalette(0x1200);          CpuCopy32(gUnknown_083970E8, &gPlttBufferUnfaded[0x100 + index * 16], 32);          sub_807CB10();          gWeatherPtr->unknown_6D5 = index;          gWeatherPtr->unknown_6D4 = AllocSpritePalette(0x1201); -        gWeatherPtr->unknown_6DA = 0; +        gWeatherPtr->rainSpriteCount = 0;          gWeatherPtr->unknown_6D8 = 0; -        gWeatherPtr->unknown_6DE = 0; -        gWeatherPtr->unknown_6E4 = 0; -        gWeatherPtr->unknown_700 = 0; -        gWeatherPtr->unknown_6FB = 0; -        gWeatherPtr->unknown_724 = 0; -        gWeatherPtr->unknown_716 = 0; -        gWeatherPtr->unknown_717 = 0; +        gWeatherPtr->cloudSpritesCreated = 0; +        gWeatherPtr->snowflakeSpriteCount = 0; +        gWeatherPtr->ashSpritesCreated = 0; +        gWeatherPtr->fog1SpritesCreated = 0; +        gWeatherPtr->fog2SpritesCreated = 0; +        gWeatherPtr->sandstormSprites1Created = 0; +        gWeatherPtr->sandstormSprites2Created = 0;          gWeatherPtr->unknown_72E = 0;          gWeatherPtr->unknown_6FA = 0; -        sub_807DB64(16, 0); +        Weather_SetBlendCoeffs(16, 0);          gWeatherPtr->currWeather = 0;          gWeatherPtr->unknown_6C6 = 3;          gWeatherPtr->unknown_6C8 = 0;          gWeatherPtr->unknown_6D3 = 1; -        gWeatherPtr->unknown_6C9 = CreateTask(sub_807C9E4, 80); +        gWeatherPtr->unknown_6C9 = CreateTask(Task_WeatherInit, 80);      }  } @@ -226,72 +226,70 @@ void DoWeatherEffect(u8 effect)      {          PlayRainSoundEffect();      } -    if (gWeatherPtr->unknown_6D1 != effect && gWeatherPtr->currWeather == effect) +    if (gWeatherPtr->nextWeather != effect && gWeatherPtr->currWeather == effect)      { -        gUnknown_08396FC8[effect].func0(); +        sWeatherFuncs[effect].initVars();      }      gWeatherPtr->unknown_6D3 = 0; -    gWeatherPtr->unknown_6D1 = effect; -    gWeatherPtr->unknown_6CE = 0; +    gWeatherPtr->nextWeather = effect; +    gWeatherPtr->finishStep = 0;  }  void sub_807C988(u8 effect)  {      PlayRainSoundEffect();      gWeatherPtr->currWeather = effect; -    gWeatherPtr->unknown_6D1 = effect; +    gWeatherPtr->nextWeather = effect;  }  void sub_807C9B4(u8 effect)  {      PlayRainSoundEffect();      gWeatherPtr->currWeather = effect; -    gWeatherPtr->unknown_6D1 = effect; +    gWeatherPtr->nextWeather = effect;      gWeatherPtr->unknown_6C8 = 1;  } -void sub_807C9E4(u8 taskId) +void Task_WeatherInit(u8 taskId)  {      if (gWeatherPtr->unknown_6C8)      { -        gUnknown_08396FC8[gWeatherPtr->currWeather].func2(); -        gTasks[taskId].func = sub_807CA34; +        sWeatherFuncs[gWeatherPtr->currWeather].initAll(); +        gTasks[taskId].func = Task_WeatherMain;      }  } -void sub_807CA34(u8 task) +void Task_WeatherMain(u8 taskId)  { -    u8 v1; -    if (gWeatherPtr->currWeather != gWeatherPtr->unknown_6D1) +    if (gWeatherPtr->currWeather != gWeatherPtr->nextWeather)      { -        v1 = gUnknown_08396FC8[gWeatherPtr->currWeather].func3(); -        if (!v1) +        if (!sWeatherFuncs[gWeatherPtr->currWeather].finish())          { -            gUnknown_08396FC8[gWeatherPtr->unknown_6D1].func0(); -            gWeatherPtr->unknown_6C3 = 0; // compiler reuses v1 -            gWeatherPtr->unknown_6C6 = 0; // compiler reuses v1 -            gWeatherPtr->currWeather = gWeatherPtr->unknown_6D1; +            sWeatherFuncs[gWeatherPtr->nextWeather].initVars(); +            gWeatherPtr->unknown_6C3 = 0; +            gWeatherPtr->unknown_6C6 = 0; +            gWeatherPtr->currWeather = gWeatherPtr->nextWeather;              gWeatherPtr->unknown_6D3 = 1;          }      }      else      { -        gUnknown_08396FC8[gWeatherPtr->currWeather].func1(); +        sWeatherFuncs[gWeatherPtr->currWeather].main();      }      gUnknown_083970B8[gWeatherPtr->unknown_6C6]();  } -void sub_807CAE8(void) +void None_Init(void)  {      gWeatherPtr->unknown_6C1 = 0;      gWeatherPtr->unknown_6C2 = 0;  } -void nullsub_38(void) +void None_Main(void)  {  } -u8 sub_807CB0C(void) +u8 None_Finish(void)  {      return 0;  } @@ -627,14 +625,14 @@ void sub_807D1BC(u8 a1, u8 a2, s8 c, u8 d, u16 e)      }  } -void sub_807D304(s8 a, u8 arg2, u16 c) +void sub_807D304(s8 a, u8 coeff, u16 c)  {      struct RGBColor color;      u8 r_;      u8 g_;      u8 b_;      u16 r4; -    u16 r5; +    u16 palOffset;      u16 r12;      a = -a - 1; @@ -642,13 +640,13 @@ void sub_807D304(s8 a, u8 arg2, u16 c)      r_ = color.r;      g_ = color.g;      b_ = color.b; -    r5 = 0; +    palOffset = 0;      for (r4 = 0; r4 < 32; r4++)      {          if (gUnknown_030006DC[r4] == 0)          { -            BlendPalette(r5, 16, arg2, c); -            r5 += 16; +            BlendPalette(palOffset, 16, coeff, c); +            palOffset += 16;          }          else          { @@ -660,7 +658,7 @@ void sub_807D304(s8 a, u8 arg2, u16 c)                  u8 r1, g1, b1;                  u8 r2, g2, b2; -                color1 = *(struct RGBColor *)&gPlttBufferUnfaded[r5]; +                color1 = *(struct RGBColor *)&gPlttBufferUnfaded[palOffset];                  r1 = color1.r;                  g1 = color1.g;                  b1 = color1.b; @@ -671,11 +669,11 @@ void sub_807D304(s8 a, u8 arg2, u16 c)                  g2 = color2.g;                  b2 = color2.b; -                r2 += ((r_ - r2) * arg2) >> 4; -                g2 += ((g_ - g2) * arg2) >> 4; -                b2 += ((b_ - b2) * arg2) >> 4; +                r2 += ((r_ - r2) * coeff) >> 4; +                g2 += ((g_ - g2) * coeff) >> 4; +                b2 += ((b_ - b2) * coeff) >> 4; -                gPlttBufferFaded[r5++] = (b2 << 10) | (g2 << 5) | r2; +                gPlttBufferFaded[palOffset++] = (b2 << 10) | (g2 << 5) | r2;              }          }      } @@ -775,28 +773,28 @@ void sub_807D5F0(u8 a, u8 b, u8 c)      }  } -void fade_screen(u8 a, u8 b) +void fade_screen(u8 a, u8 delay)  { -    u32 r4; +    u32 fadeColor;      u32 r1;      u32 r2;      switch (a)      {      case 0: -        r4 = 0; +        fadeColor = 0;          r1 = 0;          break;      case 2: -        r4 = 0xFFFF; +        fadeColor = 0xFFFF;          r1 = 0;          break;      case 1: -        r4 = 0; +        fadeColor = 0;          r1 = 1;          break;      case 3: -        r4 = 0xFFFF; +        fadeColor = 0xFFFF;          r1 = 1;          break;      default: @@ -823,20 +821,20 @@ void fade_screen(u8 a, u8 b)      {          if (r2 != 0)              CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, 0x400); -        BeginNormalPaletteFade(0xFFFFFFFF, b, 0, 16, r4); +        BeginNormalPaletteFade(0xFFFFFFFF, delay, 0, 16, fadeColor);          gWeatherPtr->unknown_6C6 = 2;      }      else      { -        gWeatherPtr->unknown_6C4 = r4; +        gWeatherPtr->unknown_6C4 = fadeColor;          if (r2 != 0)              gWeatherPtr->unknown_6C7 = 0;          else -            BeginNormalPaletteFade(0xFFFFFFFF, b, 16, 0, r4); +            BeginNormalPaletteFade(0xFFFFFFFF, delay, 16, 0, fadeColor);          gWeatherPtr->unknown_6C6 = 1;          gWeatherPtr->unknown_6CA = 1;          gWeatherPtr->unknown_6CB = 0; -        sub_807DB64(gWeatherPtr->unknown_730, gWeatherPtr->unknown_732); +        Weather_SetBlendCoeffs(gWeatherPtr->currBlendEVA, gWeatherPtr->currBlendEVB);          gWeatherPtr->unknown_6C8 = 1;      }  } @@ -909,7 +907,7 @@ void sub_807D8F0(u8 *a, u8 *b)      if (r4 < 7)      {          r4--; -        LZ77UnCompWram(gUnknown_08396FA8[r4], eWeatherPaletteData.data[r4]); +        LZ77UnCompWram(sCompressedDroughtPalettes[r4], eWeatherPaletteData.data[r4]);          if (r4 == 0)          {              eWeatherPaletteData.data[r4][0] = 0x421; @@ -921,8 +919,7 @@ void sub_807D8F0(u8 *a, u8 *b)              for (i = 0; i < 0x1000; i++)                  eWeatherPaletteData.data[r4][i] += eWeatherPaletteData.data[r4 - 1][i];          } -        (*a)++; -        if (*a == 7) +        if (++(*a) == 7)          {              *a = 32;              *b = 32; @@ -997,52 +994,58 @@ void sub_807DA4C(void)      }  } -void sub_807DB64(u8 a, u8 b) +void Weather_SetBlendCoeffs(u8 eva, u8 evb)  { -    gWeatherPtr->unknown_730 = a; -    gWeatherPtr->unknown_732 = b; -    gWeatherPtr->unknown_734 = a; -    gWeatherPtr->unknown_736 = b; -    REG_BLDALPHA = (b << 8) | a; +    gWeatherPtr->currBlendEVA = eva; +    gWeatherPtr->currBlendEVB = evb; +    gWeatherPtr->targetBlendEVA = eva; +    gWeatherPtr->targetBlendEVB = evb; +    REG_BLDALPHA = BLDALPHA_BLEND(eva, evb);  } -void sub_807DBA4(u8 a, u8 b, int c) +void Weather_SetTargetBlendCoeffs(u8 eva, u8 evb, int delay)  { -    gWeatherPtr->unknown_734 = a; -    gWeatherPtr->unknown_736 = b; -    gWeatherPtr->unknown_73A = c; +    gWeatherPtr->targetBlendEVA = eva; +    gWeatherPtr->targetBlendEVB = evb; +    gWeatherPtr->blendDelay = delay;      gWeatherPtr->unknown_739 = 0;      gWeatherPtr->unknown_738 = 0;  } -bool8 sub_807DBE8(void) +bool8 Weather_UpdateBlend(void)  { -    if (gWeatherPtr->unknown_730 == gWeatherPtr->unknown_734 -     && gWeatherPtr->unknown_732 == gWeatherPtr->unknown_736) +    if (gWeatherPtr->currBlendEVA == gWeatherPtr->targetBlendEVA +     && gWeatherPtr->currBlendEVB == gWeatherPtr->targetBlendEVB)          return TRUE; -    if (++gWeatherPtr->unknown_739 > gWeatherPtr->unknown_73A) + +    if (++gWeatherPtr->unknown_739 > gWeatherPtr->blendDelay)      {          gWeatherPtr->unknown_739 = 0;          gWeatherPtr->unknown_738++; + +        // Update currBlendEVA and currBlendEVB on alternate frames          if (gWeatherPtr->unknown_738 & 1)          { -            if (gWeatherPtr->unknown_730 < gWeatherPtr->unknown_734) -                gWeatherPtr->unknown_730++; -            else if (gWeatherPtr->unknown_730 > gWeatherPtr->unknown_734) -                gWeatherPtr->unknown_730--; +            if (gWeatherPtr->currBlendEVA < gWeatherPtr->targetBlendEVA) +                gWeatherPtr->currBlendEVA++; +            else if (gWeatherPtr->currBlendEVA > gWeatherPtr->targetBlendEVA) +                gWeatherPtr->currBlendEVA--;          }          else          { -            if (gWeatherPtr->unknown_732 < gWeatherPtr->unknown_736) -                gWeatherPtr->unknown_732++; -            else if (gWeatherPtr->unknown_732 > gWeatherPtr->unknown_736) -                gWeatherPtr->unknown_732--; +            if (gWeatherPtr->currBlendEVB < gWeatherPtr->targetBlendEVB) +                gWeatherPtr->currBlendEVB++; +            else if (gWeatherPtr->currBlendEVB > gWeatherPtr->targetBlendEVB) +                gWeatherPtr->currBlendEVB--;          }      } -    REG_BLDALPHA = (gWeatherPtr->unknown_732 << 8) | gWeatherPtr->unknown_730; -    if (gWeatherPtr->unknown_730 == gWeatherPtr->unknown_734 -     && gWeatherPtr->unknown_732 == gWeatherPtr->unknown_736) + +    REG_BLDALPHA = BLDALPHA_BLEND(gWeatherPtr->currBlendEVA, gWeatherPtr->currBlendEVB); + +    if (gWeatherPtr->currBlendEVA == gWeatherPtr->targetBlendEVA +     && gWeatherPtr->currBlendEVB == gWeatherPtr->targetBlendEVB)          return TRUE; +      return FALSE;  } diff --git a/src/field/field_weather_2.c b/src/field/field_weather_2.c deleted file mode 100644 index 64a5c5dc5..000000000 --- a/src/field/field_weather_2.c +++ /dev/null @@ -1,1511 +0,0 @@ -#include "global.h" -#include "field_map_obj.h" -#include "field_weather.h" -#include "random.h" -#include "script.h" -#include "songs.h" -#include "sound.h" -#include "sprite.h" -#include "task.h" -#include "trig.h" - -extern struct Weather *const gWeatherPtr; - -//extern const s16 gUnknown_0839A9C8[][2]; -extern const struct SpriteSheet gWeatherCloudSpriteSheet; -extern const struct SpriteTemplate gSpriteTemplate_839A9F0; -extern const struct SpriteTemplate gSpriteTemplate_839AAA4; -extern const struct SpriteTemplate gSpriteTemplate_839AB04; - -const u16 gUnknown_08397108[] = INCBIN_U16("graphics/weather/1.gbapal"); -const u16 gUnknown_08397128[] = INCBIN_U16("graphics/weather/2.gbapal"); -const u8 WeatherFog0Tiles[] = INCBIN_U8("graphics/weather/fog0.4bpp"); -const u8 gWeatherFog1Tiles[] = INCBIN_U8("graphics/weather/fog1.4bpp"); -const u8 WeatherCloudTiles[] = INCBIN_U8("graphics/weather/cloud.4bpp"); -const u8 gSpriteImage_8398948[] = INCBIN_U8("graphics/weather/snow0.4bpp"); -const u8 gSpriteImage_8398968[] = INCBIN_U8("graphics/weather/snow1.4bpp"); -const u8 WeatherBubbleTiles[] = INCBIN_U8("graphics/weather/bubble.4bpp"); -const u8 WeatherAshTiles[] = INCBIN_U8("graphics/weather/ash.4bpp"); -const u8 WeatherRainTiles[] = INCBIN_U8("graphics/weather/rain.4bpp"); -const u8 WeatherSandstormTiles[] = INCBIN_U8("graphics/weather/sandstorm.4bpp"); - -const struct Coords16 gUnknown_0839A9C8[] = -{ -    { 0, 66}, -    { 5, 73}, -    {10, 78}, -}; - -const struct SpriteSheet gWeatherCloudSpriteSheet = {WeatherCloudTiles, 0x800, 0x1200}; - -const struct OamData gOamData_839A9DC = -{ -    .y = 0, -    .affineMode = 0, -    .objMode = 1, -    .mosaic = 0, -    .bpp = 0, -    .shape = 0, -    .x = 0, -    .matrixNum = 0, -    .size = 3, -    .tileNum = 0, -    .priority = 3, -    .paletteNum = 0, -    .affineParam = 0, -}; - -const union AnimCmd gSpriteAnim_839A9E4[] = -{ -    ANIMCMD_FRAME(0, 16), -    ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_839A9EC[] = -{ -    gSpriteAnim_839A9E4, -}; - -void sub_807E0F4(struct Sprite *); -const struct SpriteTemplate gSpriteTemplate_839A9F0 = -{ -    .tileTag = 4608, -    .paletteTag = 4609, -    .oam = &gOamData_839A9DC, -    .anims = gSpriteAnimTable_839A9EC, -    .images = NULL, -    .affineAnims = gDummySpriteAffineAnimTable, -    .callback = sub_807E0F4, -}; - -extern void sub_807D5BC(s8 a); -extern void sub_807D8C0(const u16 *palette); -extern void sub_807D9A8(void); -extern bool8 sub_807D9C8(void); -extern void sub_807DA14(void); -extern void sub_807DA4C(void); -extern void sub_807DBA4(u8 a, u8 b, int c); -extern bool8 sub_807DBE8(void); -extern void SetRainStrengthFromSoundEffect(u16 sndEff); -extern void sub_807D5F0(u8 a, u8 b, u8 c); - -//------------------------------------------------------------------------------ -// Clouds -//------------------------------------------------------------------------------ - -void sub_807DE78(void) -{ -    gWeatherPtr->unknown_6C1 = 0; -    gWeatherPtr->unknown_6C2 = 20; -    gWeatherPtr->unknown_6D2 = 0; -    gWeatherPtr->unknown_6CC = 0; -    if (gWeatherPtr->unknown_6DE == 0) -        sub_807DB64(0, 16); -} - -void sub_807DEF4(void); - -void sub_807DEC4(void) -{ -    sub_807DE78(); -    while (gWeatherPtr->unknown_6D2 == 0) -        sub_807DEF4(); -} - -void sub_807DFD4(void); - -void sub_807DEF4(void) -{ -    switch (gWeatherPtr->unknown_6CC) -    { -    case 0: -        sub_807DFD4(); -        gWeatherPtr->unknown_6CC++; -        break; -    case 1: -        sub_807DBA4(12, 8, 1); -        gWeatherPtr->unknown_6CC++; -        break; -    case 2: -        if (sub_807DBE8()) -        { -            gWeatherPtr->unknown_6D2 = 1; -            gWeatherPtr->unknown_6CC++; -        } -        break; -    } -} - -void sub_807E0A0(void); - -bool8 sub_807DF54(void) -{ -    switch (gWeatherPtr->unknown_6CE) -    { -    case 0: -        sub_807DBA4(0, 16, 1); -        gWeatherPtr->unknown_6CE++; -        return TRUE; -    case 1: -        if (sub_807DBE8()) -        { -            sub_807E0A0(); -            gWeatherPtr->unknown_6CE++; -        } -        return TRUE; -    } -    return FALSE; -} - -void sub_807DF9C(void) -{ -    gWeatherPtr->unknown_6C1 = 0; -    gWeatherPtr->unknown_6C2 = 20; -} - -void sub_807DFC0(void) -{ -    sub_807DF9C(); -} - -void nullsub_55(void) -{ -} - -int sub_807DFD0(void) -{ -    return 0; -} - -void sub_807DFD4(void) -{ -    u16 i; - -    if (gWeatherPtr->unknown_6DE == 1) -        return; -    LoadSpriteSheet(&gWeatherCloudSpriteSheet); -    sub_807D8C0(gUnknown_08397108); -    for (i = 0; i < 3; i++) -    { -        u8 spriteId = CreateSprite(&gSpriteTemplate_839A9F0, 0, 0, 0xFF); - -        if (spriteId != 64) -        { -            struct Sprite *sprite; - -            gWeatherPtr->cloudSprites[i] = &gSprites[spriteId]; -            sprite = gWeatherPtr->cloudSprites[i]; -            sub_80603CC(gUnknown_0839A9C8[i].x + 7, gUnknown_0839A9C8[i].y + 7, &sprite->pos1.x, &sprite->pos1.y); -            sprite->coordOffsetEnabled = TRUE; -        } -        else -        { -            gWeatherPtr->cloudSprites[i] = NULL; -        } -    } -    gWeatherPtr->unknown_6DE = 1; -} - -void sub_807E0A0(void) -{ -    u16 i; - -    if (gWeatherPtr->unknown_6DE == 0) -        return; -    for (i = 0; i < 3; i++) -    { -        if (gWeatherPtr->cloudSprites[i] != NULL) -            DestroySprite(gWeatherPtr->cloudSprites[i]); -    } -    FreeSpriteTilesByTag(0x1200); -    gWeatherPtr->unknown_6DE = 0; -} - -void sub_807E0F4(struct Sprite *sprite) -{ -    sprite->data[0] = (sprite->data[0] + 1) & 1; -    if (sprite->data[0] != 0) -        sprite->pos1.x--; -} - -void sub_807E110(void) -{ -    gWeatherPtr->unknown_6CC = 0; -    gWeatherPtr->unknown_6D2 = 0; -    gWeatherPtr->unknown_6C1 = 0; -    gWeatherPtr->unknown_6C2 = 0; -} - -void sub_807E174(void); - -void sub_807E144(void) -{ -    sub_807E110(); -    while (gWeatherPtr->unknown_6D2 == 0) -        sub_807E174(); -} - -void sub_807E174(void) -{ -    switch (gWeatherPtr->unknown_6CC) -    { -    case 0: -        if (gWeatherPtr->unknown_6C6 != 0) -            gWeatherPtr->unknown_6CC++; -        break; -    case 1: -        sub_807D9A8(); -        gWeatherPtr->unknown_6CC++; -        break; -    case 2: -        if (sub_807D9C8() == FALSE) -            gWeatherPtr->unknown_6CC++; -        break; -    case 3: -        sub_807DA14(); -        gWeatherPtr->unknown_6CC++; -        break; -    case 4: -        sub_807DA4C(); -        if (gWeatherPtr->unknown_73C == 6) -        { -            gWeatherPtr->unknown_6D2 = 1; -            gWeatherPtr->unknown_6CC++; -        } -        break; -    default: -        sub_807DA4C(); -        break; -    } -} - -int sub_807E258(void) -{ -    return 0; -} - -void task50_0807B6D4(u8); - -void sub_807E25C(void) -{ -    CreateTask(task50_0807B6D4, 0x50); -} - -#define tState      data[0] -#define tBlendY     data[1] -#define tBlendDelay data[2] -#define tWinRange   data[3] - -void task50_0807B6D4(u8 taskId) -{ -    struct Task *task = &gTasks[taskId]; - -    switch (task->tState) -    { -    case 0: -        task->tBlendY = 0; -        task->tBlendDelay = 0; -        task->tWinRange = REG_WININ; -        REG_WININ = WIN_RANGE(63, 63); -        REG_BLDCNT = 0x9E; -        REG_BLDY = 0; -        task->tState++; -        // fall through -    case 1: -        task->tBlendY += 3; -        if (task->tBlendY > 16) -            task->tBlendY = 16; -        REG_BLDY = task->tBlendY; -        if (task->tBlendY >= 16) -            task->tState++; -        break; -    case 2: -        task->tBlendDelay++; -        if (task->tBlendDelay > 9) -        { -            task->tBlendDelay = 0; -            task->tBlendY--; -            if (task->tBlendY <= 0) -            { -                task->tBlendY = 0; -                task->tState++; -            } -            REG_BLDY = task->tBlendY; -        } -        break; -    case 3: -        REG_BLDCNT = 0; -        REG_BLDY = 0; -        REG_WININ = task->tWinRange; -        task->tState++; -        break; -    case 4: -        EnableBothScriptContexts(); -        DestroyTask(taskId); -        break; -    } -} - -#undef tState -#undef tBlendY -#undef tBlendDelay -#undef tWinRange - -//------------------------------------------------------------------------------ -// Light Rain -//------------------------------------------------------------------------------ - -void LightRain_InitVars(void) -{ -    gWeatherPtr->unknown_6CC = 0; -    gWeatherPtr->unknown_6D2 = 0; -    gWeatherPtr->unknown_6D6 = 0; -    gWeatherPtr->unknown_6DB = 8; -    gWeatherPtr->unknown_6DC = 0; -    gWeatherPtr->unknown_6D9 = 10; -    gWeatherPtr->unknown_6C1 = 3; -    gWeatherPtr->unknown_6C2 = 20; -    SetRainStrengthFromSoundEffect(SE_T_KOAME); -} - -void sub_807E400(void); - -void sub_807E3D0(void) -{ -    LightRain_InitVars(); -    while (gWeatherPtr->unknown_6D2 == 0) -        sub_807E400(); -} - -void sub_807E7A4(void); -u8 sub_807E7B4(void); -u8 sub_807E8E8(void); - -void sub_807E400(void) -{ -    switch (gWeatherPtr->unknown_6CC) -    { -    case 0: -        sub_807E7A4(); -        gWeatherPtr->unknown_6CC++; -        break; -    case 1: -        if (sub_807E7B4() == 0) -            gWeatherPtr->unknown_6CC++; -        break; -    case 2: -        if (sub_807E8E8() == FALSE) -        { -            gWeatherPtr->unknown_6D2 = 1; -            gWeatherPtr->unknown_6CC++; -        } -        break; -    } -} - -void sub_807E974(void); - -bool8 sub_807E460(void) -{ -    switch (gWeatherPtr->unknown_6CE) -    { -    case 0: -        if (gWeatherPtr->unknown_6D1 == 3 -         || gWeatherPtr->unknown_6D1 == 5 -         || gWeatherPtr->unknown_6D1 == 13) -        { -            gWeatherPtr->unknown_6CE = 0xFF; -            return FALSE; -        } -        else -        { -            gWeatherPtr->unknown_6D9 = 0; -            gWeatherPtr->unknown_6CE++; -        } -        // fall through -    case 1: -        if (sub_807E8E8() == FALSE) -        { -            sub_807E974(); -            gWeatherPtr->unknown_6CE++; -            return FALSE; -        } -        return TRUE; -    } -    return FALSE; -} - -// defined below -extern const s16 gUnknown_0839AABC[][2]; -extern const u16 gUnknown_0839AAC4[][2]; - -void sub_807E4EC(struct Sprite *sprite) -{ -    u32 randVal; -    u16 r6; -    s32 r4; -    s32 r0; - -    if (sprite->data[1] == 0) -        sprite->data[1] = 361; -    randVal = sprite->data[1] * 1103515245 + 12345; -    sprite->data[1] = ((randVal & 0x7FFF0000) >> 16) % 600; - -    r6 = gUnknown_0839AAC4[gWeatherPtr->unknown_6DC][0]; - -    r4 = sprite->data[1] % 30; -    sprite->data[2] = r4 * 8;  // useless assignment - -    r0 = sprite->data[1] / 30; -    sprite->data[3] = r0 * 8;  // useless assignment - -    sprite->data[2] = r4; -    sprite->data[2] <<= 7; - -    sprite->data[3] = r0; -    sprite->data[3] <<= 7; - -    sprite->data[2] -= gUnknown_0839AABC[gWeatherPtr->unknown_6DC][0] * r6; -    sprite->data[3] -= gUnknown_0839AABC[gWeatherPtr->unknown_6DC][1] * r6; - -    StartSpriteAnim(sprite, 0); -    sprite->data[4] = 0; -    sprite->coordOffsetEnabled = FALSE; -    sprite->data[0] = r6; -} - -void sub_807E5C0(struct Sprite *sprite) -{ -    if (sprite->data[4] == 0) -    { -        sprite->data[2] += gUnknown_0839AABC[gWeatherPtr->unknown_6DC][0]; -        sprite->data[3] += gUnknown_0839AABC[gWeatherPtr->unknown_6DC][1]; -        sprite->pos1.x = sprite->data[2] >> 4; -        sprite->pos1.y = sprite->data[3] >> 4; - -        if (sprite->data[5] != 0 -         && (sprite->pos1.x >= -8 && sprite->pos1.x <= 248) -         && sprite->pos1.y >= -16 && sprite->pos1.y <= 176) -            sprite->invisible = FALSE; -        else -            sprite->invisible = TRUE; - -        sprite->data[0]--; -        if (sprite->data[0] == 0) -        { -            StartSpriteAnim(sprite, gWeatherPtr->unknown_6DC + 1); -            sprite->data[4] = 1; -            sprite->pos1.x -= gSpriteCoordOffsetX; -            sprite->pos1.y -= gSpriteCoordOffsetY; -            sprite->coordOffsetEnabled = TRUE; -        } -    } -    else if (sprite->animEnded) -    { -        sprite->invisible = TRUE; -        sub_807E4EC(sprite); -    } -} - -void sub_807E6C4(struct Sprite *sprite) -{ -    if (sprite->data[0] == 0) -    { -        sub_807E4EC(sprite); -        sprite->callback = sub_807E5C0; -    } -    else -    { -        sprite->data[0]--; -    } -} - -void sub_807E6F0(struct Sprite *sprite, u16 b) -{ -    u16 r8 = gUnknown_0839AAC4[gWeatherPtr->unknown_6DC][0]; -    u16 r6 = b / (gUnknown_0839AAC4[gWeatherPtr->unknown_6DC][1] + r8); -    u16 r4 = b % (gUnknown_0839AAC4[gWeatherPtr->unknown_6DC][1] + r8); - -    while (--r6 != 0xFFFF) -        sub_807E4EC(sprite); -    if (r4 < r8) -    { -        while (--r4 != 0xFFFF) -            sub_807E5C0(sprite); -        sprite->data[6] = 0; -    } -    else -    { -        sprite->data[0] = r4 - r8; -        sprite->invisible = TRUE; -        sprite->data[6] = 1; -    } -} - -extern const struct SpriteSheet gUnknown_0839AACC;  // defined below - -void sub_807E7A4(void) -{ -    LoadSpriteSheet(&gUnknown_0839AACC); -} - -const struct Coords16 gUnknown_0839AA08[] = -{ -    {  0,   0}, -    {  0, 160}, -    {  0,  64}, -    {144, 224}, -    {144, 128}, -    { 32,  32}, -    { 32, 192}, -    { 32,  96}, -    { 72, 128}, -    { 72,  32}, -    { 72, 192}, -    {216,  96}, -    {216,   0}, -    {104, 160}, -    {104,  64}, -    {104, 224}, -    {144,   0}, -    {144, 160}, -    {144,  64}, -    { 32, 224}, -    { 32, 128}, -    { 72,  32}, -    { 72, 192}, -    { 48,  96}, -}; - -const struct OamData gOamData_839AA68 = -{ -    .y = 0, -    .affineMode = 0, -    .objMode = 0, -    .mosaic = 0, -    .bpp = 0, -    .shape = 2, -    .x = 0, -    .matrixNum = 0, -    .size = 2, -    .tileNum = 0, -    .priority = 1, -    .paletteNum = 2, -    .affineParam = 0, -}; - -const union AnimCmd gSpriteAnim_839AA70[] = -{ -    ANIMCMD_FRAME(0, 16), -    ANIMCMD_JUMP(0), -}; - -const union AnimCmd gSpriteAnim_839AA78[] = -{ -    ANIMCMD_FRAME(8, 3), -    ANIMCMD_FRAME(32, 2), -    ANIMCMD_FRAME(40, 2), -    ANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_839AA88[] = -{ -    ANIMCMD_FRAME(8, 3), -    ANIMCMD_FRAME(16, 3), -    ANIMCMD_FRAME(24, 4), -    ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_839AA98[] = -{ -    gSpriteAnim_839AA70, -    gSpriteAnim_839AA78, -    gSpriteAnim_839AA88, -}; - -const struct SpriteTemplate gSpriteTemplate_839AAA4 = -{ -    .tileTag = 4614, -    .paletteTag = 4608, -    .oam = &gOamData_839AA68, -    .anims = gSpriteAnimTable_839AA98, -    .images = NULL, -    .affineAnims = gDummySpriteAffineAnimTable, -    .callback = sub_807E5C0, -}; - - -const s16 gUnknown_0839AABC[][2] = -{ -	{-104, 208}, -	{-160, 320}, -}; - -const u16 gUnknown_0839AAC4[][2] = -{ -    {18, 7}, -    {12, 10}, -}; - -const struct SpriteSheet gUnknown_0839AACC = {WeatherRainTiles, sizeof(WeatherRainTiles), 0x1206}; - -const struct OamData gOamData_839AAD4 = -{ -    .y = 0, -    .affineMode = 0, -    .objMode = 0, -    .mosaic = 0, -    .bpp = 0, -    .shape = 0, -    .x = 0, -    .matrixNum = 0, -    .size = 0, -    .tileNum = 0, -    .priority = 1, -    .paletteNum = 0, -    .affineParam = 0, -}; - -const struct SpriteFrameImage gSpriteImageTable_839AADC[] = -{ -    {gSpriteImage_8398948, sizeof(gSpriteImage_8398948)}, -    {gSpriteImage_8398968, sizeof(gSpriteImage_8398968)}, -}; - -const union AnimCmd gSpriteAnim_839AAEC[] = -{ -    ANIMCMD_FRAME(0, 16), -    ANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_839AAF4[] = -{ -    ANIMCMD_FRAME(1, 16), -    ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_839AAFC[] = -{ -    gSpriteAnim_839AAEC, -    gSpriteAnim_839AAF4, -}; - -void sub_807ED48(struct Sprite *); -const struct SpriteTemplate gSpriteTemplate_839AB04 = -{ -    .tileTag = 0xFFFF, -    .paletteTag = 4608, -    .oam = &gOamData_839AAD4, -    .anims = gSpriteAnimTable_839AAFC, -    .images = gSpriteImageTable_839AADC, -    .affineAnims = gDummySpriteAffineAnimTable, -    .callback = sub_807ED48, -}; - -// unused data -const u16 unusedData_839AB1C[] = {0, 6, 6, 12, 18, 42, 300, 300}; - -const struct OamData gOamData_839AB2C = -{ -    .y = 0, -    .affineMode = 0, -    .objMode = 1, -    .mosaic = 0, -    .bpp = 0, -    .shape = 0, -    .x = 0, -    .matrixNum = 0, -    .size = 3, -    .tileNum = 0, -    .priority = 2, -    .paletteNum = 0, -    .affineParam = 0, -}; - -const union AnimCmd gSpriteAnim_839AB34[] = -{ -    ANIMCMD_FRAME(0, 16), -    ANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_839AB3C[] = -{ -    ANIMCMD_FRAME(32, 16), -    ANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_839AB44[] = -{ -    ANIMCMD_FRAME(64, 16), -    ANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_839AB4C[] = -{ -    ANIMCMD_FRAME(96, 16), -    ANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_839AB54[] = -{ -    ANIMCMD_FRAME(128, 16), -    ANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_839AB5C[] = -{ -    ANIMCMD_FRAME(160, 16), -    ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_839AB64[] = -{ -    gSpriteAnim_839AB34, -    gSpriteAnim_839AB3C, -    gSpriteAnim_839AB44, -    gSpriteAnim_839AB4C, -    gSpriteAnim_839AB54, -    gSpriteAnim_839AB5C, -}; - -const union AffineAnimCmd gSpriteAffineAnim_839AB7C[] = -{ -    AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0), -    AFFINEANIMCMD_END, -}; - -const union AffineAnimCmd *const gSpriteAffineAnimTable_839AB8C[] = -{ -    gSpriteAffineAnim_839AB7C, -}; - -void sub_807F688(struct Sprite *); -const struct SpriteTemplate gSpriteTemplate_839AB90 = -{ -    .tileTag = 4609, -    .paletteTag = 4608, -    .oam = &gOamData_839AB2C, -    .anims = gSpriteAnimTable_839AB64, -    .images = NULL, -    .affineAnims = gSpriteAffineAnimTable_839AB8C, -    .callback = sub_807F688, -}; - -const struct SpriteSheet gWeatherFog1SpriteSheet = {gWeatherFog1Tiles, sizeof(gWeatherFog1Tiles), 0x1201}; -const struct SpriteSheet gWeatherAshSpriteSheet = {WeatherAshTiles, sizeof(WeatherAshTiles), 0x1202}; - -const struct OamData gOamData_839ABB8 = -{ -    .y = 0, -    .affineMode = 0, -    .objMode = 1, -    .mosaic = 0, -    .bpp = 0, -    .shape = 0, -    .x = 0, -    .matrixNum = 0, -    .size = 3, -    .tileNum = 0, -    .priority = 1, -    .paletteNum = 15, -    .affineParam = 0, -}; - -const union AnimCmd gSpriteAnim_839ABC0[] = -{ -    ANIMCMD_FRAME(0, 60), -    ANIMCMD_FRAME(64, 60), -    ANIMCMD_JUMP(0), -}; - -const union AnimCmd *const gSpriteAnimTable_839ABCC[] = -{ -    gSpriteAnim_839ABC0, -}; - -void sub_807FAA8(struct Sprite *); -const struct SpriteTemplate gSpriteTemplate_839ABD0 = -{ -    .tileTag = 4610, -    .paletteTag = 4608, -    .oam = &gOamData_839ABB8, -    .anims = gSpriteAnimTable_839ABCC, -    .images = NULL, -    .affineAnims = gDummySpriteAffineAnimTable, -    .callback = sub_807FAA8, -}; - -const struct SpriteSheet gWeatherFog0SpriteSheet = {WeatherFog0Tiles, sizeof(WeatherFog0Tiles), 0x1203}; - -const struct OamData gOamData_839ABF0 = -{ -    .y = 0, -    .affineMode = 0, -    .objMode = 1, -    .mosaic = 0, -    .bpp = 0, -    .shape = 0, -    .x = 0, -    .matrixNum = 0, -    .size = 3, -    .tileNum = 0, -    .priority = 2, -    .paletteNum = 0, -    .affineParam = 0, -}; - -const union AnimCmd gSpriteAnim_839ABF8[] = -{ -    ANIMCMD_FRAME(0, 16), -    ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_839AC00[] = -{ -    gSpriteAnim_839ABF8, -}; - -void sub_807FE3C(struct Sprite *); -const struct SpriteTemplate gSpriteTemplate_839AC04 = -{ -    .tileTag = 4611, -    .paletteTag = 4608, -    .oam = &gOamData_839ABF0, -    .anims = gSpriteAnimTable_839AC00, -    .images = NULL, -    .affineAnims = gDummySpriteAffineAnimTable, -    .callback = sub_807FE3C, -}; - -const struct OamData gOamData_839AC1C = -{ -    .y = 0, -    .affineMode = 0, -    .objMode = 1, -    .mosaic = 0, -    .bpp = 0, -    .shape = 0, -    .x = 0, -    .matrixNum = 0, -    .size = 3, -    .tileNum = 0, -    .priority = 1, -    .paletteNum = 0, -    .affineParam = 0, -}; - -const union AnimCmd gSpriteAnim_839AC24[] = -{ -    ANIMCMD_FRAME(0, 3), -    ANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_839AC2C[] = -{ -    ANIMCMD_FRAME(64, 3), -    ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_839AC34[] = -{ -    gSpriteAnim_839AC24, -    gSpriteAnim_839AC2C, -}; - -void sub_8080338(struct Sprite *); -const struct SpriteTemplate gSpriteTemplate_839AC3C = -{ -    .tileTag = 4612, -    .paletteTag = 4609, -    .oam = &gOamData_839AC1C, -    .anims = gSpriteAnimTable_839AC34, -    .images = NULL, -    .affineAnims = gDummySpriteAffineAnimTable, -    .callback = sub_8080338, -}; - -const struct SpriteSheet gWeatherSandstormSpriteSheet = {WeatherSandstormTiles, sizeof(WeatherSandstormTiles), 0x1204}; - -bool8 sub_807E7B4(void) -{ -    u8 r7; -    u8 spriteId; - -    if (gWeatherPtr->unknown_6DA == 24) -        return FALSE; - -    r7 = gWeatherPtr->unknown_6DA; -    spriteId = CreateSpriteAtEnd(&gSpriteTemplate_839AAA4, -      gUnknown_0839AA08[r7].x, gUnknown_0839AA08[r7].y, 78); -    if (spriteId != 64) -    { -        gSprites[spriteId].data[5] = 0; -        gSprites[spriteId].data[1] = r7 * 145; -        while (gSprites[spriteId].data[1] >= 600) -            gSprites[spriteId].data[1] -= 600; -        sub_807E4EC(&gSprites[spriteId]); -        sub_807E6F0(&gSprites[spriteId], r7 * 9); -        gSprites[spriteId].invisible = TRUE; -        gWeatherPtr->unknown_0[r7] = &gSprites[spriteId]; -    } -    else -    { -        gWeatherPtr->unknown_0[r7] = NULL; -    } - -    if (++gWeatherPtr->unknown_6DA == 24) -    { -        u16 i; - -        for (i = 0; i < 24; i++) -        { -            if (gWeatherPtr->unknown_0[i] != NULL) -            { -                if (gWeatherPtr->unknown_0[i]->data[6] == 0) -                    gWeatherPtr->unknown_0[i]->callback = sub_807E5C0; -                else -                    gWeatherPtr->unknown_0[i]->callback = sub_807E6C4; -            } -        } -        return FALSE; -    } -    return TRUE; -} - -bool8 sub_807E8E8(void) -{ -    if (gWeatherPtr->unknown_6D8 == gWeatherPtr->unknown_6D9) -        return FALSE; - -    if (++gWeatherPtr->unknown_6D6 > gWeatherPtr->unknown_6DB) -    { -        gWeatherPtr->unknown_6D6 = 0; -        if (gWeatherPtr->unknown_6D8 < gWeatherPtr->unknown_6D9) -        { -            gWeatherPtr->unknown_0[gWeatherPtr->unknown_6D8++]->data[5] = 1; -        } -        else -        { -            gWeatherPtr->unknown_6D8--; -            gWeatherPtr->unknown_0[gWeatherPtr->unknown_6D8]->data[5] = 0; -            gWeatherPtr->unknown_0[gWeatherPtr->unknown_6D8]->invisible = TRUE; -        } -    } -    return TRUE; -} - -void sub_807E974(void) -{ -    u16 i; - -    for (i = 0; i < gWeatherPtr->unknown_6DA; i++) -    { -        if (gWeatherPtr->unknown_0[i] != NULL) -            DestroySprite(gWeatherPtr->unknown_0[i]); -    } -    gWeatherPtr->unknown_6DA = 0; -    FreeSpriteTilesByTag(0x1206); -} - -//------------------------------------------------------------------------------ -// Snow -//------------------------------------------------------------------------------ - -void Snow_InitVars(void) -{ -    gWeatherPtr->unknown_6CC = 0; -    gWeatherPtr->unknown_6D2 = 0; -    gWeatherPtr->unknown_6C1 = 3; -    gWeatherPtr->unknown_6C2 = 20; -    gWeatherPtr->unknown_6E5 = 16; -    gWeatherPtr->unknown_6E0 = 0; -} - -void snowflakes_progress2(void); -void sub_807ED48(struct Sprite *); - -void sub_807EA18(void) -{ -    Snow_InitVars(); -    while (gWeatherPtr->unknown_6D2 == 0) -    { -        u16 i; - -        snowflakes_progress2(); -        for (i = 0; i < gWeatherPtr->unknown_6E4; i++) -        { -            sub_807ED48(gWeatherPtr->snowflakeSprites[i]); -        } -    } -} - -u8 snowflakes_progress(void); - -void snowflakes_progress2(void) -{ -    if (gWeatherPtr->unknown_6CC == 0 && snowflakes_progress() == FALSE) -    { -        gWeatherPtr->unknown_6D2 = 1; -        gWeatherPtr->unknown_6CC++; -    } -} - -bool8 sub_807EAC0(void) -{ -    switch (gWeatherPtr->unknown_6CE) -    { -    case 0: -        gWeatherPtr->unknown_6E5 = 0; -        gWeatherPtr->unknown_6E0 = 0; -        gWeatherPtr->unknown_6CE++; -        // fall through -    case 1: -        if (snowflakes_progress() == FALSE) -        { -            gWeatherPtr->unknown_6CE++; -            return FALSE; -        } -        return TRUE; -    } -    return FALSE; -} - -bool8 snowflake_add(void); -bool8 snowflake_remove(void); - -bool8 snowflakes_progress(void) -{ -    if (gWeatherPtr->unknown_6E4 == gWeatherPtr->unknown_6E5) -        return FALSE; - -    gWeatherPtr->unknown_6E0++; -    if (gWeatherPtr->unknown_6E0 > 36) -    { -        gWeatherPtr->unknown_6E0 = 0; -        if (gWeatherPtr->unknown_6E4 < gWeatherPtr->unknown_6E5) -            snowflake_add(); -        else -            snowflake_remove(); -    } -    return (gWeatherPtr->unknown_6E4 != gWeatherPtr->unknown_6E5); -} - -void sub_807EC40(struct Sprite *); - -bool8 snowflake_add(void) -{ -    u8 spriteId = CreateSpriteAtEnd(&gSpriteTemplate_839AB04, 0, 0, 78); - -    if (spriteId == 64) -        return FALSE; -    gSprites[spriteId].data[4] = gWeatherPtr->unknown_6E4; -    sub_807EC40(&gSprites[spriteId]); -    gSprites[spriteId].coordOffsetEnabled = TRUE; -    gWeatherPtr->snowflakeSprites[gWeatherPtr->unknown_6E4++] = &gSprites[spriteId]; -    return TRUE; -} - -bool8 snowflake_remove(void) -{ -    if (gWeatherPtr->unknown_6E4 != 0) -    { -        DestroySprite(gWeatherPtr->snowflakeSprites[--gWeatherPtr->unknown_6E4]); -        return TRUE; -    } -    return FALSE; -} - -void sub_807EC40(struct Sprite *sprite) -{ -    u16 r4 = ((sprite->data[4] * 5) & 7) * 30 + (Random() % 30); -    u16 r6; - -    sprite->pos1.y = -3 - (gSpriteCoordOffsetY + sprite->centerToCornerVecY); -    sprite->pos1.x = r4 - (gSpriteCoordOffsetX + sprite->centerToCornerVecX); -    sprite->data[0] = sprite->pos1.y * 128; -    sprite->pos2.x = 0; -    r6 = Random(); -    sprite->data[1] = (r6 & 3) * 5 + 64; -    sprite->data[7] = (r6 & 3) * 5 + 64; -    StartSpriteAnim(sprite, (r6 & 1) ? 0 : 1); -    sprite->data[3] = 0; -    sprite->data[2] = ((r6 & 3) == 0) ? 2 : 1; -    sprite->data[6] = (r6 & 0x1F) + 210; -    sprite->data[5] = 0; -} - -void sub_807ECEC(struct Sprite *sprite) -{ -    if (gWeatherPtr->unknown_6E2 > 18) -    { -        sprite->invisible = FALSE; -        sprite->callback = sub_807ED48; -        sprite->pos1.y = 0xFA - (gSpriteCoordOffsetY + sprite->centerToCornerVecY); -        sprite->data[0] = sprite->pos1.y * 128; -        gWeatherPtr->unknown_6E2 = 0; -    } -} - -void sub_807ED48(struct Sprite *sprite) -{ -    s16 r3; -    s16 r2; - -    sprite->data[0] += sprite->data[1]; -    sprite->pos1.y = sprite->data[0] >> 7; -    sprite->data[3] = (sprite->data[3] + sprite->data[2]) & 0xFF; -    sprite->pos2.x = gSineTable[sprite->data[3]] / 64; - -    r3 = (sprite->pos1.x + sprite->centerToCornerVecX + gSpriteCoordOffsetX) & 0x1FF; -    if (r3 & 0x100) -        r3 = -0x100 | r3;  // hmm... what is this? -    if (r3 < -3) -        sprite->pos1.x = 242 - (gSpriteCoordOffsetX + sprite->centerToCornerVecX); -    else if (r3 > 242) -        sprite->pos1.x = -3 - (gSpriteCoordOffsetX + sprite->centerToCornerVecX); - -    r2 = (sprite->pos1.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY) & 0xFF; -    if (r2 > 163 && r2 < 171) -    { -        sprite->pos1.y = 250 - (gSpriteCoordOffsetY + sprite->centerToCornerVecY); -        sprite->data[0] = sprite->pos1.y * 128; -        sprite->data[5] = 0; -        sprite->data[6] = 220; -    } -    else if (r2 > 242 && r2 < 250) -    { -        sprite->pos1.y = 163; -        sprite->data[0] = sprite->pos1.y * 128; -        sprite->data[5] = 0; -        sprite->data[6] = 220; -        sprite->invisible = TRUE; -        sprite->callback = sub_807ECEC; -    } - -    sprite->data[5]++; -    if (sprite->data[5] == sprite->data[6]) -    { -        sub_807EC40(sprite); -        sprite->pos1.y = 250; -        sprite->invisible = TRUE; -        sprite->callback = sub_807ECEC; -    } -} - -//------------------------------------------------------------------------------ -// Medium Rain -//------------------------------------------------------------------------------ - -void sub_807EE80(void) -{ -    gWeatherPtr->unknown_6CC = 0; -    gWeatherPtr->unknown_6D2 = 0; -    gWeatherPtr->unknown_6D6 = 0; -    gWeatherPtr->unknown_6DB = 4; -    gWeatherPtr->unknown_6DC = 0; -    gWeatherPtr->unknown_6D9 = 16; -    gWeatherPtr->unknown_6C1 = 3; -    gWeatherPtr->unknown_6C2 = 20; -    gWeatherPtr->unknown_6D2 = 0;  // duplicate assignment -    gWeatherPtr->unknown_6ED = 0; -    SetRainStrengthFromSoundEffect(SE_T_AME); -} - -void sub_807EFC0(void); - -void sub_807EEF4(void) -{ -    sub_807EE80(); -    while (gWeatherPtr->unknown_6D2 == 0) -        sub_807EFC0(); -} - -//------------------------------------------------------------------------------ -// Heavy Rain -//------------------------------------------------------------------------------ - -void sub_807EF24(void) -{ -    gWeatherPtr->unknown_6CC = 0; -    gWeatherPtr->unknown_6D2 = 0; -    gWeatherPtr->unknown_6D6 = 0; -    gWeatherPtr->unknown_6DB = 4; -    gWeatherPtr->unknown_6DC = 1; -    gWeatherPtr->unknown_6D9 = 24; -    gWeatherPtr->unknown_6C1 = 3; -    gWeatherPtr->unknown_6C2 = 20; -    gWeatherPtr->unknown_6D2 = 0;  // duplicate assignment -    SetRainStrengthFromSoundEffect(SE_T_OOAME); -} - -void sub_807EF90(void) -{ -    sub_807EF24(); -    while (gWeatherPtr->unknown_6D2 == 0) -        sub_807EFC0(); -} - -void sub_807F434(void); -void sub_807F3F8(u16); - -void sub_807EFC0(void) -{ -    sub_807F434(); -    switch (gWeatherPtr->unknown_6CC) -    { -    case 0: -        sub_807E7A4(); -        gWeatherPtr->unknown_6CC++; -        break; -    case 1: -        if (sub_807E7B4()) -            break; -        gWeatherPtr->unknown_6CC++; -        break; -    case 2: -        if (sub_807E8E8()) -            break; -        gWeatherPtr->unknown_6D2 = 1; -        gWeatherPtr->unknown_6CC++; -        break; -    case 3: -        if (gWeatherPtr->unknown_6C6 == 0) -            break; -        gWeatherPtr->unknown_6CC = 6; -        break; -    case 4: -        gWeatherPtr->unknown_6EA = 1; -        gWeatherPtr->unknown_6E6 = (Random() % 360) + 360; -        gWeatherPtr->unknown_6CC++; -        // fall through -    case 5: -        if (--gWeatherPtr->unknown_6E6 != 0) -            break; -        gWeatherPtr->unknown_6CC++; -        break; -    case 6: -        gWeatherPtr->unknown_6EA = 1; -        gWeatherPtr->unknown_6EB = Random() % 2; -        gWeatherPtr->unknown_6CC++; -        break; -    case 7: -        gWeatherPtr->unknown_6EC = (Random() & 1) + 1; -        gWeatherPtr->unknown_6CC++; -        // fall through -    case 8: -        sub_807D5BC(19); -        if (gWeatherPtr->unknown_6EB == 0 && gWeatherPtr->unknown_6EC == 1) -            sub_807F3F8(20); -        gWeatherPtr->unknown_6E6 = (Random() % 3) + 6; -        gWeatherPtr->unknown_6CC++; -        break; -    case 9: -        if (--gWeatherPtr->unknown_6E6 != 0) -            break; -        sub_807D5BC(3); -        gWeatherPtr->unknown_6EA = 1; -        if (--gWeatherPtr->unknown_6EC != 0) -        { -            gWeatherPtr->unknown_6E6 = (Random() % 16) + 60; -            gWeatherPtr->unknown_6CC = 10; -        } -        else if (gWeatherPtr->unknown_6EB == 0) -        { -            gWeatherPtr->unknown_6CC = 4; -        } -        else -        { -            gWeatherPtr->unknown_6CC = 11; -        } -        break; -    case 10: -        if (--gWeatherPtr->unknown_6E6 != 0) -            break; -        gWeatherPtr->unknown_6CC = 8; -        break; -    case 11: -        gWeatherPtr->unknown_6E6 = (Random() % 16) + 60; -        gWeatherPtr->unknown_6CC++; -        break; -    case 12: -        if (--gWeatherPtr->unknown_6E6 != 0) -            break; -        sub_807F3F8(100); -        sub_807D5BC(19); -        // Why use "% 16" everywhere else and "& 0xF" here. So dumb. -        gWeatherPtr->unknown_6E6 = (Random() & 0xF) + 30; -        gWeatherPtr->unknown_6CC++; -        break; -    case 13: -        if (--gWeatherPtr->unknown_6E6 != 0) -            break; -        sub_807D5F0(19, 3, 5); -        gWeatherPtr->unknown_6CC++; -        break; -    case 14: -        if (gWeatherPtr->unknown_6C6 != 3) -            break; -        gWeatherPtr->unknown_6EA = 1; -        gWeatherPtr->unknown_6CC = 4; -        break; -    } -} - -bool8 sub_807F34C(void) -{ -    switch (gWeatherPtr->unknown_6CE) -    { -    case 0: -        gWeatherPtr->unknown_6EA = 0; -        gWeatherPtr->unknown_6CE++; -        // fall through -    case 1: -        sub_807EFC0(); -        if (gWeatherPtr->unknown_6EA != 0) -        { -            if (gWeatherPtr->unknown_6D1 == 3 -             || gWeatherPtr->unknown_6D1 == 5 -             || gWeatherPtr->unknown_6D1 == 13) -                return FALSE; -            gWeatherPtr->unknown_6D9 = 0; -            gWeatherPtr->unknown_6CE++; -        } -        break; -    case 2: -        if (sub_807E8E8()) -            break; -        sub_807E974(); -        gWeatherPtr->unknown_6ED = 0; -        gWeatherPtr->unknown_6CE++; -        return FALSE; -    default: -        return FALSE; -    } -    return TRUE; -} - -void sub_807F3F8(u16 a) -{ -    if (gWeatherPtr->unknown_6ED == 0) -    { -        gWeatherPtr->unknown_6E8 = Random() % a; -        gWeatherPtr->unknown_6ED = 1; -    } -} - -void sub_807F434(void) -{ -    if (gWeatherPtr->unknown_6ED == 1) -    { -        if (gWeatherPtr->unknown_6E8 == 0) -        { -            if (IsSEPlaying()) -                return; -            if (Random() & 1) -                PlaySE(SE_T_KAMI); -            else -                PlaySE(SE_T_KAMI2); -            gWeatherPtr->unknown_6ED = 0; -        } -        else -        { -            gWeatherPtr->unknown_6E8--; -        } -    } -} - -void sub_807F49C(void) -{ -    gWeatherPtr->unknown_6CC = 0; -    gWeatherPtr->unknown_6D2 = 0; -    gWeatherPtr->unknown_6C1 = 0; -    gWeatherPtr->unknown_6C2 = 20; -    if (gWeatherPtr->unknown_6FB == 0) -    { -        gWeatherPtr->unknown_6F0 = 0; -        gWeatherPtr->unknown_6F2 = 0; -        gWeatherPtr->unknown_6EE = 0; -        sub_807DB64(0, 16); -    } -} - -void sub_807F52C(void); - -void sub_807F4FC(void) -{ -    sub_807F49C(); -    while (gWeatherPtr->unknown_6D2 == 0) -        sub_807F52C(); -} - -void sub_807F6E8(void); - -void sub_807F52C(void) -{ -    gWeatherPtr->unknown_6EE = (gSpriteCoordOffsetX - gWeatherPtr->unknown_6F2) & 0xFF; -    if (++gWeatherPtr->unknown_6F0 > 3) -    { -        gWeatherPtr->unknown_6F0 = 0; -        gWeatherPtr->unknown_6F2++; -    } -    switch (gWeatherPtr->unknown_6CC) -    { -    case 0: -        sub_807F6E8(); -        if (gWeatherPtr->currWeather == 6) -            sub_807DBA4(12, 8, 3); -        else -            sub_807DBA4(4, 16, 0); -        gWeatherPtr->unknown_6CC++; -        break; -    case 1: -        if (sub_807DBE8()) -        { -            gWeatherPtr->unknown_6D2 = 1; -            gWeatherPtr->unknown_6CC++; -        } -        break; -    } -} - -void sub_807F7A4(void); - -bool8 sub_807F5EC(void) -{ -    gWeatherPtr->unknown_6EE = (gSpriteCoordOffsetX - gWeatherPtr->unknown_6F2) & 0xFF; -    if (++gWeatherPtr->unknown_6F0 > 3) -    { -        gWeatherPtr->unknown_6F0 = 0; -        gWeatherPtr->unknown_6F2++; -    } -    switch (gWeatherPtr->unknown_6CE) -    { -    case 0: -        sub_807DBA4(0, 16, 3); -        gWeatherPtr->unknown_6CE++; -        break; -    case 1: -        if (!sub_807DBE8()) -            break; -        gWeatherPtr->unknown_6CE++; -        break; -    case 2: -        sub_807F7A4(); -        gWeatherPtr->unknown_6CE++; -        break; -    default: -        return FALSE; -    } -    return TRUE; -} - -void sub_807F688(struct Sprite *sprite) -{ -    sprite->pos2.y = (u8)gSpriteCoordOffsetY; -    sprite->pos1.x = gWeatherPtr->unknown_6EE + 32 + sprite->data[0] * 64; -    if (sprite->pos1.x > 0x10F) -    { -        sprite->pos1.x = 480 + gWeatherPtr->unknown_6EE - (4 - sprite->data[0]) * 64; -        sprite->pos1.x &= 0x1FF; -    } -} diff --git a/src/field/field_weather_effects.c b/src/field/field_weather_effects.c new file mode 100644 index 000000000..b1dca6396 --- /dev/null +++ b/src/field/field_weather_effects.c @@ -0,0 +1,2383 @@ +#include "global.h" +#include "field_map_obj.h" +#include "field_weather.h" +#include "overworld.h" +#include "random.h" +#include "script.h" +#include "songs.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "trig.h" + +extern struct Weather *const gWeatherPtr; + +const u16 gUnknown_08397108[] = INCBIN_U16("graphics/weather/1.gbapal"); +const u16 gUnknown_08397128[] = INCBIN_U16("graphics/weather/2.gbapal"); +const u8 gWeatherFog2Tiles[] = INCBIN_U8("graphics/weather/fog2.4bpp"); +const u8 gWeatherFog1Tiles[] = INCBIN_U8("graphics/weather/fog1.4bpp"); +const u8 gWeatherCloudTiles[] = INCBIN_U8("graphics/weather/cloud.4bpp"); +const u8 gWeatherSnow1Tiles[] = INCBIN_U8("graphics/weather/snow0.4bpp"); +const u8 gWeatherSnow2Tiles[] = INCBIN_U8("graphics/weather/snow1.4bpp"); +const u8 gWeatherBubbleTiles[] = INCBIN_U8("graphics/weather/bubble.4bpp"); +const u8 gWeatherAshTiles[] = INCBIN_U8("graphics/weather/ash.4bpp"); +const u8 gWeatherRainTiles[] = INCBIN_U8("graphics/weather/rain.4bpp"); +const u8 gWeatherSandstormTiles[] = INCBIN_U8("graphics/weather/sandstorm.4bpp"); + +static const struct Coords16 gUnknown_0839A9C8[] = +{ +    { 0, 66}, +    { 5, 73}, +    {10, 78}, +}; + +static const struct SpriteSheet sCloudSpriteSheet = {gWeatherCloudTiles, sizeof(gWeatherCloudTiles), 0x1200}; + +static const struct OamData gOamData_839A9DC = +{ +    .y = 0, +    .affineMode = 0, +    .objMode = 1, +    .mosaic = 0, +    .bpp = 0, +    .shape = 0, +    .x = 0, +    .matrixNum = 0, +    .size = 3, +    .tileNum = 0, +    .priority = 3, +    .paletteNum = 0, +    .affineParam = 0, +}; + +static const union AnimCmd gSpriteAnim_839A9E4[] = +{ +    ANIMCMD_FRAME(0, 16), +    ANIMCMD_END, +}; + +static const union AnimCmd *const gSpriteAnimTable_839A9EC[] = +{ +    gSpriteAnim_839A9E4, +}; + +void sub_807E0F4(struct Sprite *); +static const struct SpriteTemplate sCloudSpriteTemplate = +{ +    .tileTag = 4608, +    .paletteTag = 4609, +    .oam = &gOamData_839A9DC, +    .anims = gSpriteAnimTable_839A9EC, +    .images = NULL, +    .affineAnims = gDummySpriteAffineAnimTable, +    .callback = sub_807E0F4, +}; + +extern void sub_807D5BC(s8 a); +extern void sub_807D8C0(const u16 *palette); +extern void sub_807D9A8(void); +extern bool8 sub_807D9C8(void); +extern void sub_807DA14(void); +extern void sub_807DA4C(void); +extern void Weather_SetTargetBlendCoeffs(u8 a, u8 b, int c); +extern bool8 Weather_UpdateBlend(void); +extern void SetRainStrengthFromSoundEffect(u16 sndEff); +extern void sub_807D5F0(u8 a, u8 b, u8 c); + +//------------------------------------------------------------------------------ +// Clouds +//------------------------------------------------------------------------------ + +void Clouds_InitVars(void) +{ +    gWeatherPtr->unknown_6C1 = 0; +    gWeatherPtr->unknown_6C2 = 20; +    gWeatherPtr->weatherGfxLoaded = FALSE; +    gWeatherPtr->initStep = 0; +    if (gWeatherPtr->cloudSpritesCreated == FALSE) +        Weather_SetBlendCoeffs(0, 16); +} + +void Clouds_Main(void); + +void Clouds_InitAll(void) +{ +    Clouds_InitVars(); +    while (gWeatherPtr->weatherGfxLoaded == FALSE) +        Clouds_Main(); +} + +void CreateCloudSprites(void); + +void Clouds_Main(void) +{ +    switch (gWeatherPtr->initStep) +    { +    case 0: +        CreateCloudSprites(); +        gWeatherPtr->initStep++; +        break; +    case 1: +        Weather_SetTargetBlendCoeffs(12, 8, 1); +        gWeatherPtr->initStep++; +        break; +    case 2: +        if (Weather_UpdateBlend()) +        { +            gWeatherPtr->weatherGfxLoaded = TRUE; +            gWeatherPtr->initStep++; +        } +        break; +    } +} + +void sub_807E0A0(void); + +bool8 Clouds_Finish(void) +{ +    switch (gWeatherPtr->finishStep) +    { +    case 0: +        Weather_SetTargetBlendCoeffs(0, 16, 1); +        gWeatherPtr->finishStep++; +        return TRUE; +    case 1: +        if (Weather_UpdateBlend()) +        { +            sub_807E0A0(); +            gWeatherPtr->finishStep++; +        } +        return TRUE; +    } +    return FALSE; +} + +//------------------------------------------------------------------------------ +// Weather 2 +//------------------------------------------------------------------------------ + +void Weather2_InitVars(void) +{ +    gWeatherPtr->unknown_6C1 = 0; +    gWeatherPtr->unknown_6C2 = 20; +} + +void Weather2_InitAll(void) +{ +    Weather2_InitVars(); +} + +void Weather2_Main(void) +{ +} + +int Weather2_Finish(void) +{ +    return 0; +} + +void CreateCloudSprites(void) +{ +    u16 i; + +    if (gWeatherPtr->cloudSpritesCreated == TRUE) +        return; +    LoadSpriteSheet(&sCloudSpriteSheet); +    sub_807D8C0(gUnknown_08397108); +    for (i = 0; i < 3; i++) +    { +        u8 spriteId = CreateSprite(&sCloudSpriteTemplate, 0, 0, 0xFF); + +        if (spriteId != 64) +        { +            struct Sprite *sprite; + +            gWeatherPtr->sprites.s1.cloudSprites[i] = &gSprites[spriteId]; +            sprite = gWeatherPtr->sprites.s1.cloudSprites[i]; +            sub_80603CC(gUnknown_0839A9C8[i].x + 7, gUnknown_0839A9C8[i].y + 7, &sprite->pos1.x, &sprite->pos1.y); +            sprite->coordOffsetEnabled = TRUE; +        } +        else +        { +            gWeatherPtr->sprites.s1.cloudSprites[i] = NULL; +        } +    } +    gWeatherPtr->cloudSpritesCreated = TRUE; +} + +void sub_807E0A0(void) +{ +    u16 i; + +    if (gWeatherPtr->cloudSpritesCreated == FALSE) +        return; +    for (i = 0; i < 3; i++) +    { +        if (gWeatherPtr->sprites.s1.cloudSprites[i] != NULL) +            DestroySprite(gWeatherPtr->sprites.s1.cloudSprites[i]); +    } +    FreeSpriteTilesByTag(0x1200); +    gWeatherPtr->cloudSpritesCreated = FALSE; +} + +void sub_807E0F4(struct Sprite *sprite) +{ +    sprite->data[0] = (sprite->data[0] + 1) & 1; +    if (sprite->data[0] != 0) +        sprite->pos1.x--; +} + +//------------------------------------------------------------------------------ +// Drought +//------------------------------------------------------------------------------ + +void Drought_InitVars(void) +{ +    gWeatherPtr->initStep = 0; +    gWeatherPtr->weatherGfxLoaded = FALSE; +    gWeatherPtr->unknown_6C1 = 0; +    gWeatherPtr->unknown_6C2 = 0; +} + +void Drought_Main(void); + +void Drought_InitAll(void) +{ +    Drought_InitVars(); +    while (gWeatherPtr->weatherGfxLoaded == FALSE) +        Drought_Main(); +} + +void Drought_Main(void) +{ +    switch (gWeatherPtr->initStep) +    { +    case 0: +        if (gWeatherPtr->unknown_6C6 != 0) +            gWeatherPtr->initStep++; +        break; +    case 1: +        sub_807D9A8(); +        gWeatherPtr->initStep++; +        break; +    case 2: +        if (sub_807D9C8() == FALSE) +            gWeatherPtr->initStep++; +        break; +    case 3: +        sub_807DA14(); +        gWeatherPtr->initStep++; +        break; +    case 4: +        sub_807DA4C(); +        if (gWeatherPtr->unknown_73C == 6) +        { +            gWeatherPtr->weatherGfxLoaded = TRUE; +            gWeatherPtr->initStep++; +        } +        break; +    default: +        sub_807DA4C(); +        break; +    } +} + +int Drought_Finish(void) +{ +    return 0; +} + +void task50_0807B6D4(u8); + +void sub_807E25C(void) +{ +    CreateTask(task50_0807B6D4, 0x50); +} + +#define tState      data[0] +#define tBlendY     data[1] +#define tBlendDelay data[2] +#define tWinRange   data[3] + +void task50_0807B6D4(u8 taskId) +{ +    struct Task *task = &gTasks[taskId]; + +    switch (task->tState) +    { +    case 0: +        task->tBlendY = 0; +        task->tBlendDelay = 0; +        task->tWinRange = REG_WININ; +        REG_WININ = WIN_RANGE(63, 63); +        REG_BLDCNT = BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ +                   | BLDCNT_EFFECT_LIGHTEN; +        REG_BLDY = 0; +        task->tState++; +        // fall through +    case 1: +        task->tBlendY += 3; +        if (task->tBlendY > 16) +            task->tBlendY = 16; +        REG_BLDY = task->tBlendY; +        if (task->tBlendY >= 16) +            task->tState++; +        break; +    case 2: +        task->tBlendDelay++; +        if (task->tBlendDelay > 9) +        { +            task->tBlendDelay = 0; +            task->tBlendY--; +            if (task->tBlendY <= 0) +            { +                task->tBlendY = 0; +                task->tState++; +            } +            REG_BLDY = task->tBlendY; +        } +        break; +    case 3: +        REG_BLDCNT = 0; +        REG_BLDY = 0; +        REG_WININ = task->tWinRange; +        task->tState++; +        break; +    case 4: +        EnableBothScriptContexts(); +        DestroyTask(taskId); +        break; +    } +} + +#undef tState +#undef tBlendY +#undef tBlendDelay +#undef tWinRange + +//------------------------------------------------------------------------------ +// Light Rain +//------------------------------------------------------------------------------ + +void LightRain_InitVars(void) +{ +    gWeatherPtr->initStep = 0; +    gWeatherPtr->weatherGfxLoaded = FALSE; +    gWeatherPtr->unknown_6D6 = 0; +    gWeatherPtr->unknown_6DB = 8; +    gWeatherPtr->unknown_6DC = 0; +    gWeatherPtr->unknown_6D9 = 10; +    gWeatherPtr->unknown_6C1 = 3; +    gWeatherPtr->unknown_6C2 = 20; +    SetRainStrengthFromSoundEffect(SE_T_KOAME); +} + +void LightRain_Main(void); + +void LightRain_InitAll(void) +{ +    LightRain_InitVars(); +    while (gWeatherPtr->weatherGfxLoaded == FALSE) +        LightRain_Main(); +} + +void LoadRainSpriteSheet(void); +u8 CreateRainSprite(void); +u8 sub_807E8E8(void); + +void LightRain_Main(void) +{ +    switch (gWeatherPtr->initStep) +    { +    case 0: +        LoadRainSpriteSheet(); +        gWeatherPtr->initStep++; +        break; +    case 1: +        if (CreateRainSprite() == 0) +            gWeatherPtr->initStep++; +        break; +    case 2: +        if (sub_807E8E8() == FALSE) +        { +            gWeatherPtr->weatherGfxLoaded = TRUE; +            gWeatherPtr->initStep++; +        } +        break; +    } +} + +void DestroyRainSprites(void); + +bool8 LightRain_Finish(void) +{ +    switch (gWeatherPtr->finishStep) +    { +    case 0: +        if (gWeatherPtr->nextWeather == WEATHER_RAIN_LIGHT +         || gWeatherPtr->nextWeather == WEATHER_RAIN_MED +         || gWeatherPtr->nextWeather == WEATHER_RAIN_HEAVY) +        { +            gWeatherPtr->finishStep = 0xFF; +            return FALSE; +        } +        else +        { +            gWeatherPtr->unknown_6D9 = 0; +            gWeatherPtr->finishStep++; +        } +        // fall through +    case 1: +        if (sub_807E8E8() == FALSE) +        { +            DestroyRainSprites(); +            gWeatherPtr->finishStep++; +            return FALSE; +        } +        return TRUE; +    } +    return FALSE; +} + +// defined below +extern const s16 gUnknown_0839AABC[][2]; +extern const u16 gUnknown_0839AAC4[][2]; + +void sub_807E4EC(struct Sprite *sprite) +{ +    u32 randVal; +    u16 r6; +    s32 r4; +    s32 r0; + +    if (sprite->data[1] == 0) +        sprite->data[1] = 361; +    randVal = sprite->data[1] * 1103515245 + 12345; +    sprite->data[1] = ((randVal & 0x7FFF0000) >> 16) % 600; + +    r6 = gUnknown_0839AAC4[gWeatherPtr->unknown_6DC][0]; + +    r4 = sprite->data[1] % 30; +    sprite->data[2] = r4 * 8;  // useless assignment + +    r0 = sprite->data[1] / 30; +    sprite->data[3] = r0 * 8;  // useless assignment + +    sprite->data[2] = r4; +    sprite->data[2] <<= 7; + +    sprite->data[3] = r0; +    sprite->data[3] <<= 7; + +    sprite->data[2] -= gUnknown_0839AABC[gWeatherPtr->unknown_6DC][0] * r6; +    sprite->data[3] -= gUnknown_0839AABC[gWeatherPtr->unknown_6DC][1] * r6; + +    StartSpriteAnim(sprite, 0); +    sprite->data[4] = 0; +    sprite->coordOffsetEnabled = FALSE; +    sprite->data[0] = r6; +} + +void sub_807E5C0(struct Sprite *sprite) +{ +    if (sprite->data[4] == 0) +    { +        sprite->data[2] += gUnknown_0839AABC[gWeatherPtr->unknown_6DC][0]; +        sprite->data[3] += gUnknown_0839AABC[gWeatherPtr->unknown_6DC][1]; +        sprite->pos1.x = sprite->data[2] >> 4; +        sprite->pos1.y = sprite->data[3] >> 4; + +        if (sprite->data[5] != 0 +         && (sprite->pos1.x >= -8 && sprite->pos1.x <= 248) +         && sprite->pos1.y >= -16 && sprite->pos1.y <= 176) +            sprite->invisible = FALSE; +        else +            sprite->invisible = TRUE; + +        sprite->data[0]--; +        if (sprite->data[0] == 0) +        { +            StartSpriteAnim(sprite, gWeatherPtr->unknown_6DC + 1); +            sprite->data[4] = 1; +            sprite->pos1.x -= gSpriteCoordOffsetX; +            sprite->pos1.y -= gSpriteCoordOffsetY; +            sprite->coordOffsetEnabled = TRUE; +        } +    } +    else if (sprite->animEnded) +    { +        sprite->invisible = TRUE; +        sub_807E4EC(sprite); +    } +} + +void sub_807E6C4(struct Sprite *sprite) +{ +    if (sprite->data[0] == 0) +    { +        sub_807E4EC(sprite); +        sprite->callback = sub_807E5C0; +    } +    else +    { +        sprite->data[0]--; +    } +} + +void sub_807E6F0(struct Sprite *sprite, u16 b) +{ +    u16 r8 = gUnknown_0839AAC4[gWeatherPtr->unknown_6DC][0]; +    u16 r6 = b / (gUnknown_0839AAC4[gWeatherPtr->unknown_6DC][1] + r8); +    u16 r4 = b % (gUnknown_0839AAC4[gWeatherPtr->unknown_6DC][1] + r8); + +    while (--r6 != 0xFFFF) +        sub_807E4EC(sprite); +    if (r4 < r8) +    { +        while (--r4 != 0xFFFF) +            sub_807E5C0(sprite); +        sprite->data[6] = 0; +    } +    else +    { +        sprite->data[0] = r4 - r8; +        sprite->invisible = TRUE; +        sprite->data[6] = 1; +    } +} + +extern const struct SpriteSheet sRainSpriteSheet;  // defined below + +void LoadRainSpriteSheet(void) +{ +    LoadSpriteSheet(&sRainSpriteSheet); +} + +static const struct Coords16 sRainSpriteCoords[] = +{ +    {  0,   0}, +    {  0, 160}, +    {  0,  64}, +    {144, 224}, +    {144, 128}, +    { 32,  32}, +    { 32, 192}, +    { 32,  96}, +    { 72, 128}, +    { 72,  32}, +    { 72, 192}, +    {216,  96}, +    {216,   0}, +    {104, 160}, +    {104,  64}, +    {104, 224}, +    {144,   0}, +    {144, 160}, +    {144,  64}, +    { 32, 224}, +    { 32, 128}, +    { 72,  32}, +    { 72, 192}, +    { 48,  96}, +}; + +static const struct OamData gOamData_839AA68 = +{ +    .y = 0, +    .affineMode = 0, +    .objMode = 0, +    .mosaic = 0, +    .bpp = 0, +    .shape = 2, +    .x = 0, +    .matrixNum = 0, +    .size = 2, +    .tileNum = 0, +    .priority = 1, +    .paletteNum = 2, +    .affineParam = 0, +}; + +static const union AnimCmd gSpriteAnim_839AA70[] = +{ +    ANIMCMD_FRAME(0, 16), +    ANIMCMD_JUMP(0), +}; + +static const union AnimCmd gSpriteAnim_839AA78[] = +{ +    ANIMCMD_FRAME(8, 3), +    ANIMCMD_FRAME(32, 2), +    ANIMCMD_FRAME(40, 2), +    ANIMCMD_END, +}; + +static const union AnimCmd gSpriteAnim_839AA88[] = +{ +    ANIMCMD_FRAME(8, 3), +    ANIMCMD_FRAME(16, 3), +    ANIMCMD_FRAME(24, 4), +    ANIMCMD_END, +}; + +static const union AnimCmd *const gSpriteAnimTable_839AA98[] = +{ +    gSpriteAnim_839AA70, +    gSpriteAnim_839AA78, +    gSpriteAnim_839AA88, +}; + +static const struct SpriteTemplate sRainSpriteTemplate = +{ +    .tileTag = 4614, +    .paletteTag = 4608, +    .oam = &gOamData_839AA68, +    .anims = gSpriteAnimTable_839AA98, +    .images = NULL, +    .affineAnims = gDummySpriteAffineAnimTable, +    .callback = sub_807E5C0, +}; + + +const s16 gUnknown_0839AABC[][2] = +{ +	{-104, 208}, +	{-160, 320}, +}; + +const u16 gUnknown_0839AAC4[][2] = +{ +    {18, 7}, +    {12, 10}, +}; + +static const struct SpriteSheet sRainSpriteSheet = {gWeatherRainTiles, sizeof(gWeatherRainTiles), 0x1206}; + +static const struct OamData gOamData_839AAD4 = +{ +    .y = 0, +    .affineMode = 0, +    .objMode = 0, +    .mosaic = 0, +    .bpp = 0, +    .shape = 0, +    .x = 0, +    .matrixNum = 0, +    .size = 0, +    .tileNum = 0, +    .priority = 1, +    .paletteNum = 0, +    .affineParam = 0, +}; + +static const struct SpriteFrameImage gSpriteImageTable_839AADC[] = +{ +    {gWeatherSnow1Tiles, sizeof(gWeatherSnow1Tiles)}, +    {gWeatherSnow2Tiles, sizeof(gWeatherSnow2Tiles)}, +}; + +static const union AnimCmd gSpriteAnim_839AAEC[] = +{ +    ANIMCMD_FRAME(0, 16), +    ANIMCMD_END, +}; + +static const union AnimCmd gSpriteAnim_839AAF4[] = +{ +    ANIMCMD_FRAME(1, 16), +    ANIMCMD_END, +}; + +static const union AnimCmd *const gSpriteAnimTable_839AAFC[] = +{ +    gSpriteAnim_839AAEC, +    gSpriteAnim_839AAF4, +}; + +void sub_807ED48(struct Sprite *); +static const struct SpriteTemplate sSnowflakeSpriteTemplate = +{ +    .tileTag = 0xFFFF, +    .paletteTag = 4608, +    .oam = &gOamData_839AAD4, +    .anims = gSpriteAnimTable_839AAFC, +    .images = gSpriteImageTable_839AADC, +    .affineAnims = gDummySpriteAffineAnimTable, +    .callback = sub_807ED48, +}; + +// unused data +static const u16 unusedData_839AB1C[] = {0, 6, 6, 12, 18, 42, 300, 300}; + +static const struct OamData gOamData_839AB2C = +{ +    .y = 0, +    .affineMode = 0, +    .objMode = 1, +    .mosaic = 0, +    .bpp = 0, +    .shape = 0, +    .x = 0, +    .matrixNum = 0, +    .size = 3, +    .tileNum = 0, +    .priority = 2, +    .paletteNum = 0, +    .affineParam = 0, +}; + +static const union AnimCmd gSpriteAnim_839AB34[] = +{ +    ANIMCMD_FRAME(0, 16), +    ANIMCMD_END, +}; + +static const union AnimCmd gSpriteAnim_839AB3C[] = +{ +    ANIMCMD_FRAME(32, 16), +    ANIMCMD_END, +}; + +static const union AnimCmd gSpriteAnim_839AB44[] = +{ +    ANIMCMD_FRAME(64, 16), +    ANIMCMD_END, +}; + +static const union AnimCmd gSpriteAnim_839AB4C[] = +{ +    ANIMCMD_FRAME(96, 16), +    ANIMCMD_END, +}; + +static const union AnimCmd gSpriteAnim_839AB54[] = +{ +    ANIMCMD_FRAME(128, 16), +    ANIMCMD_END, +}; + +static const union AnimCmd gSpriteAnim_839AB5C[] = +{ +    ANIMCMD_FRAME(160, 16), +    ANIMCMD_END, +}; + +static const union AnimCmd *const gSpriteAnimTable_839AB64[] = +{ +    gSpriteAnim_839AB34, +    gSpriteAnim_839AB3C, +    gSpriteAnim_839AB44, +    gSpriteAnim_839AB4C, +    gSpriteAnim_839AB54, +    gSpriteAnim_839AB5C, +}; + +static const union AffineAnimCmd gSpriteAffineAnim_839AB7C[] = +{ +    AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0), +    AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gSpriteAffineAnimTable_839AB8C[] = +{ +    gSpriteAffineAnim_839AB7C, +}; + +static void Fog1SpriteCallback(struct Sprite *); +static const struct SpriteTemplate sFog1SpriteTemplate = +{ +    .tileTag = 4609, +    .paletteTag = 4608, +    .oam = &gOamData_839AB2C, +    .anims = gSpriteAnimTable_839AB64, +    .images = NULL, +    .affineAnims = gSpriteAffineAnimTable_839AB8C, +    .callback = Fog1SpriteCallback, +}; + +bool8 CreateRainSprite(void) +{ +    u8 spriteNum; +    u8 spriteId; + +    if (gWeatherPtr->rainSpriteCount == 24) +        return FALSE; + +    spriteNum = gWeatherPtr->rainSpriteCount; +    spriteId = CreateSpriteAtEnd(&sRainSpriteTemplate, +      sRainSpriteCoords[spriteNum].x, sRainSpriteCoords[spriteNum].y, 78); +    if (spriteId != 64) +    { +        gSprites[spriteId].data[5] = 0; +        gSprites[spriteId].data[1] = spriteNum * 145; +        while (gSprites[spriteId].data[1] >= 600) +            gSprites[spriteId].data[1] -= 600; +        sub_807E4EC(&gSprites[spriteId]); +        sub_807E6F0(&gSprites[spriteId], spriteNum * 9); +        gSprites[spriteId].invisible = TRUE; +        gWeatherPtr->sprites.s1.rainSprites[spriteNum] = &gSprites[spriteId]; +    } +    else +    { +        gWeatherPtr->sprites.s1.rainSprites[spriteNum] = NULL; +    } + +    if (++gWeatherPtr->rainSpriteCount == 24) +    { +        u16 i; + +        for (i = 0; i < 24; i++) +        { +            if (gWeatherPtr->sprites.s1.rainSprites[i] != NULL) +            { +                if (gWeatherPtr->sprites.s1.rainSprites[i]->data[6] == 0) +                    gWeatherPtr->sprites.s1.rainSprites[i]->callback = sub_807E5C0; +                else +                    gWeatherPtr->sprites.s1.rainSprites[i]->callback = sub_807E6C4; +            } +        } +        return FALSE; +    } +    return TRUE; +} + +bool8 sub_807E8E8(void) +{ +    if (gWeatherPtr->unknown_6D8 == gWeatherPtr->unknown_6D9) +        return FALSE; + +    if (++gWeatherPtr->unknown_6D6 > gWeatherPtr->unknown_6DB) +    { +        gWeatherPtr->unknown_6D6 = 0; +        if (gWeatherPtr->unknown_6D8 < gWeatherPtr->unknown_6D9) +        { +            gWeatherPtr->sprites.s1.rainSprites[gWeatherPtr->unknown_6D8++]->data[5] = 1; +        } +        else +        { +            gWeatherPtr->unknown_6D8--; +            gWeatherPtr->sprites.s1.rainSprites[gWeatherPtr->unknown_6D8]->data[5] = 0; +            gWeatherPtr->sprites.s1.rainSprites[gWeatherPtr->unknown_6D8]->invisible = TRUE; +        } +    } +    return TRUE; +} + +void DestroyRainSprites(void) +{ +    u16 i; + +    for (i = 0; i < gWeatherPtr->rainSpriteCount; i++) +    { +        if (gWeatherPtr->sprites.s1.rainSprites[i] != NULL) +            DestroySprite(gWeatherPtr->sprites.s1.rainSprites[i]); +    } +    gWeatherPtr->rainSpriteCount = 0; +    FreeSpriteTilesByTag(0x1206); +} + +//------------------------------------------------------------------------------ +// Snow +//------------------------------------------------------------------------------ + +void Snow_InitVars(void) +{ +    gWeatherPtr->initStep = 0; +    gWeatherPtr->weatherGfxLoaded = FALSE; +    gWeatherPtr->unknown_6C1 = 3; +    gWeatherPtr->unknown_6C2 = 20; +    gWeatherPtr->unknown_6E5 = 16; +    gWeatherPtr->unknown_6E0 = 0; +} + +void Snow_Main(void); +void sub_807ED48(struct Sprite *); + +void Snow_InitAll(void) +{ +    Snow_InitVars(); +    while (gWeatherPtr->weatherGfxLoaded == FALSE) +    { +        u16 i; + +        Snow_Main(); +        for (i = 0; i < gWeatherPtr->snowflakeSpriteCount; i++) +        { +            sub_807ED48(gWeatherPtr->sprites.s1.snowflakeSprites[i]); +        } +    } +} + +u8 snowflakes_progress(void); + +void Snow_Main(void) +{ +    if (gWeatherPtr->initStep == 0 && snowflakes_progress() == FALSE) +    { +        gWeatherPtr->weatherGfxLoaded = TRUE; +        gWeatherPtr->initStep++; +    } +} + +bool8 Snow_Finish(void) +{ +    switch (gWeatherPtr->finishStep) +    { +    case 0: +        gWeatherPtr->unknown_6E5 = 0; +        gWeatherPtr->unknown_6E0 = 0; +        gWeatherPtr->finishStep++; +        // fall through +    case 1: +        if (snowflakes_progress() == FALSE) +        { +            gWeatherPtr->finishStep++; +            return FALSE; +        } +        return TRUE; +    } +    return FALSE; +} + +bool8 CreateSnowflakeSprite(void); +bool8 RemoveSnowflakeSprite(void); + +bool8 snowflakes_progress(void) +{ +    if (gWeatherPtr->snowflakeSpriteCount == gWeatherPtr->unknown_6E5) +        return FALSE; + +    gWeatherPtr->unknown_6E0++; +    if (gWeatherPtr->unknown_6E0 > 36) +    { +        gWeatherPtr->unknown_6E0 = 0; +        if (gWeatherPtr->snowflakeSpriteCount < gWeatherPtr->unknown_6E5) +            CreateSnowflakeSprite(); +        else +            RemoveSnowflakeSprite(); +    } +    return (gWeatherPtr->snowflakeSpriteCount != gWeatherPtr->unknown_6E5); +} + +void sub_807EC40(struct Sprite *); + +bool8 CreateSnowflakeSprite(void) +{ +    u8 spriteId = CreateSpriteAtEnd(&sSnowflakeSpriteTemplate, 0, 0, 78); + +    if (spriteId == 64) +        return FALSE; +    gSprites[spriteId].data[4] = gWeatherPtr->snowflakeSpriteCount; +    sub_807EC40(&gSprites[spriteId]); +    gSprites[spriteId].coordOffsetEnabled = TRUE; +    gWeatherPtr->sprites.s1.snowflakeSprites[gWeatherPtr->snowflakeSpriteCount++] = &gSprites[spriteId]; +    return TRUE; +} + +bool8 RemoveSnowflakeSprite(void) +{ +    if (gWeatherPtr->snowflakeSpriteCount != 0) +    { +        DestroySprite(gWeatherPtr->sprites.s1.snowflakeSprites[--gWeatherPtr->snowflakeSpriteCount]); +        return TRUE; +    } +    return FALSE; +} + +void sub_807EC40(struct Sprite *sprite) +{ +    u16 r4 = ((sprite->data[4] * 5) & 7) * 30 + (Random() % 30); +    u16 r6; + +    sprite->pos1.y = -3 - (gSpriteCoordOffsetY + sprite->centerToCornerVecY); +    sprite->pos1.x = r4 - (gSpriteCoordOffsetX + sprite->centerToCornerVecX); +    sprite->data[0] = sprite->pos1.y * 128; +    sprite->pos2.x = 0; +    r6 = Random(); +    sprite->data[1] = (r6 & 3) * 5 + 64; +    sprite->data[7] = (r6 & 3) * 5 + 64; +    StartSpriteAnim(sprite, (r6 & 1) ? 0 : 1); +    sprite->data[3] = 0; +    sprite->data[2] = ((r6 & 3) == 0) ? 2 : 1; +    sprite->data[6] = (r6 & 0x1F) + 210; +    sprite->data[5] = 0; +} + +void sub_807ECEC(struct Sprite *sprite) +{ +    if (gWeatherPtr->unknown_6E2 > 18) +    { +        sprite->invisible = FALSE; +        sprite->callback = sub_807ED48; +        sprite->pos1.y = 0xFA - (gSpriteCoordOffsetY + sprite->centerToCornerVecY); +        sprite->data[0] = sprite->pos1.y * 128; +        gWeatherPtr->unknown_6E2 = 0; +    } +} + +void sub_807ED48(struct Sprite *sprite) +{ +    s16 r3; +    s16 r2; + +    sprite->data[0] += sprite->data[1]; +    sprite->pos1.y = sprite->data[0] >> 7; +    sprite->data[3] = (sprite->data[3] + sprite->data[2]) & 0xFF; +    sprite->pos2.x = gSineTable[sprite->data[3]] / 64; + +    r3 = (sprite->pos1.x + sprite->centerToCornerVecX + gSpriteCoordOffsetX) & 0x1FF; +    if (r3 & 0x100) +        r3 = -0x100 | r3;  // hmm... what is this? +    if (r3 < -3) +        sprite->pos1.x = 242 - (gSpriteCoordOffsetX + sprite->centerToCornerVecX); +    else if (r3 > 242) +        sprite->pos1.x = -3 - (gSpriteCoordOffsetX + sprite->centerToCornerVecX); + +    r2 = (sprite->pos1.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY) & 0xFF; +    if (r2 > 163 && r2 < 171) +    { +        sprite->pos1.y = 250 - (gSpriteCoordOffsetY + sprite->centerToCornerVecY); +        sprite->data[0] = sprite->pos1.y * 128; +        sprite->data[5] = 0; +        sprite->data[6] = 220; +    } +    else if (r2 > 242 && r2 < 250) +    { +        sprite->pos1.y = 163; +        sprite->data[0] = sprite->pos1.y * 128; +        sprite->data[5] = 0; +        sprite->data[6] = 220; +        sprite->invisible = TRUE; +        sprite->callback = sub_807ECEC; +    } + +    sprite->data[5]++; +    if (sprite->data[5] == sprite->data[6]) +    { +        sub_807EC40(sprite); +        sprite->pos1.y = 250; +        sprite->invisible = TRUE; +        sprite->callback = sub_807ECEC; +    } +} + +//------------------------------------------------------------------------------ +// Medium Rain +//------------------------------------------------------------------------------ + +void MedRain_InitVars(void) +{ +    gWeatherPtr->initStep = 0; +    gWeatherPtr->weatherGfxLoaded = FALSE; +    gWeatherPtr->unknown_6D6 = 0; +    gWeatherPtr->unknown_6DB = 4; +    gWeatherPtr->unknown_6DC = 0; +    gWeatherPtr->unknown_6D9 = 16; +    gWeatherPtr->unknown_6C1 = 3; +    gWeatherPtr->unknown_6C2 = 20; +    gWeatherPtr->weatherGfxLoaded = FALSE;  // duplicate assignment +    gWeatherPtr->unknown_6ED = 0; +    SetRainStrengthFromSoundEffect(SE_T_AME); +} + +void Rain_Main(void); + +void MedRain_InitAll(void) +{ +    MedRain_InitVars(); +    while (gWeatherPtr->weatherGfxLoaded == FALSE) +        Rain_Main(); +} + +//------------------------------------------------------------------------------ +// Heavy Rain +//------------------------------------------------------------------------------ + +void HeavyRain_InitVars(void) +{ +    gWeatherPtr->initStep = 0; +    gWeatherPtr->weatherGfxLoaded = FALSE; +    gWeatherPtr->unknown_6D6 = 0; +    gWeatherPtr->unknown_6DB = 4; +    gWeatherPtr->unknown_6DC = 1; +    gWeatherPtr->unknown_6D9 = 24; +    gWeatherPtr->unknown_6C1 = 3; +    gWeatherPtr->unknown_6C2 = 20; +    gWeatherPtr->weatherGfxLoaded = FALSE;  // duplicate assignment +    SetRainStrengthFromSoundEffect(SE_T_OOAME); +} + +void HeavyRain_InitAll(void) +{ +    HeavyRain_InitVars(); +    while (gWeatherPtr->weatherGfxLoaded == FALSE) +        Rain_Main(); +} + +void UpdateThunderSound(void); +void SetThunderCounter(u16); + +void Rain_Main(void) +{ +    UpdateThunderSound(); +    switch (gWeatherPtr->initStep) +    { +    case 0: +        LoadRainSpriteSheet(); +        gWeatherPtr->initStep++; +        break; +    case 1: +        if (CreateRainSprite()) +            break; +        gWeatherPtr->initStep++; +        break; +    case 2: +        if (sub_807E8E8()) +            break; +        gWeatherPtr->weatherGfxLoaded = TRUE; +        gWeatherPtr->initStep++; +        break; +    case 3: +        if (gWeatherPtr->unknown_6C6 == 0) +            break; +        gWeatherPtr->initStep = 6; +        break; +    case 4: +        gWeatherPtr->unknown_6EA = 1; +        gWeatherPtr->unknown_6E6 = (Random() % 360) + 360; +        gWeatherPtr->initStep++; +        // fall through +    case 5: +        if (--gWeatherPtr->unknown_6E6 != 0) +            break; +        gWeatherPtr->initStep++; +        break; +    case 6: +        gWeatherPtr->unknown_6EA = 1; +        gWeatherPtr->unknown_6EB = Random() % 2; +        gWeatherPtr->initStep++; +        break; +    case 7: +        gWeatherPtr->unknown_6EC = (Random() & 1) + 1; +        gWeatherPtr->initStep++; +        // fall through +    case 8: +        sub_807D5BC(19); +        if (gWeatherPtr->unknown_6EB == 0 && gWeatherPtr->unknown_6EC == 1) +            SetThunderCounter(20); +        gWeatherPtr->unknown_6E6 = (Random() % 3) + 6; +        gWeatherPtr->initStep++; +        break; +    case 9: +        if (--gWeatherPtr->unknown_6E6 != 0) +            break; +        sub_807D5BC(3); +        gWeatherPtr->unknown_6EA = 1; +        if (--gWeatherPtr->unknown_6EC != 0) +        { +            gWeatherPtr->unknown_6E6 = (Random() % 16) + 60; +            gWeatherPtr->initStep = 10; +        } +        else if (gWeatherPtr->unknown_6EB == 0) +        { +            gWeatherPtr->initStep = 4; +        } +        else +        { +            gWeatherPtr->initStep = 11; +        } +        break; +    case 10: +        if (--gWeatherPtr->unknown_6E6 != 0) +            break; +        gWeatherPtr->initStep = 8; +        break; +    case 11: +        gWeatherPtr->unknown_6E6 = (Random() % 16) + 60; +        gWeatherPtr->initStep++; +        break; +    case 12: +        if (--gWeatherPtr->unknown_6E6 != 0) +            break; +        SetThunderCounter(100); +        sub_807D5BC(19); +        // Why use "% 16" everywhere else and "& 0xF" here. So dumb. +        gWeatherPtr->unknown_6E6 = (Random() & 0xF) + 30; +        gWeatherPtr->initStep++; +        break; +    case 13: +        if (--gWeatherPtr->unknown_6E6 != 0) +            break; +        sub_807D5F0(19, 3, 5); +        gWeatherPtr->initStep++; +        break; +    case 14: +        if (gWeatherPtr->unknown_6C6 != 3) +            break; +        gWeatherPtr->unknown_6EA = 1; +        gWeatherPtr->initStep = 4; +        break; +    } +} + +bool8 Rain_Finish(void) +{ +    switch (gWeatherPtr->finishStep) +    { +    case 0: +        gWeatherPtr->unknown_6EA = 0; +        gWeatherPtr->finishStep++; +        // fall through +    case 1: +        Rain_Main(); +        if (gWeatherPtr->unknown_6EA != 0) +        { +            if (gWeatherPtr->nextWeather == WEATHER_RAIN_LIGHT +             || gWeatherPtr->nextWeather == WEATHER_RAIN_MED +             || gWeatherPtr->nextWeather == WEATHER_RAIN_HEAVY) +                return FALSE; +            gWeatherPtr->unknown_6D9 = 0; +            gWeatherPtr->finishStep++; +        } +        break; +    case 2: +        if (sub_807E8E8()) +            break; +        DestroyRainSprites(); +        gWeatherPtr->unknown_6ED = 0; +        gWeatherPtr->finishStep++; +        return FALSE; +    default: +        return FALSE; +    } +    return TRUE; +} + +void SetThunderCounter(u16 max) +{ +    if (gWeatherPtr->unknown_6ED == 0) +    { +        gWeatherPtr->thunderCounter = Random() % max; +        gWeatherPtr->unknown_6ED = 1; +    } +} + +void UpdateThunderSound(void) +{ +    if (gWeatherPtr->unknown_6ED == 1) +    { +        if (gWeatherPtr->thunderCounter == 0) +        { +            if (IsSEPlaying()) +                return; +            if (Random() & 1) +                PlaySE(SE_T_KAMI); +            else +                PlaySE(SE_T_KAMI2); +            gWeatherPtr->unknown_6ED = 0; +        } +        else +        { +            gWeatherPtr->thunderCounter--; +        } +    } +} + +//------------------------------------------------------------------------------ +// Fog 1 +//------------------------------------------------------------------------------ + +void Fog1_Main(void); +static void CreateFog1Sprites(void); +static void DestroyFog1Sprites(void); + +void Fog1_InitVars(void) +{ +    gWeatherPtr->initStep = 0; +    gWeatherPtr->weatherGfxLoaded = FALSE; +    gWeatherPtr->unknown_6C1 = 0; +    gWeatherPtr->unknown_6C2 = 20; +    if (gWeatherPtr->fog1SpritesCreated == 0) +    { +        gWeatherPtr->unknown_6F0 = 0; +        gWeatherPtr->unknown_6F2 = 0; +        gWeatherPtr->fog1ScrollPosX = 0; +        Weather_SetBlendCoeffs(0, 16); +    } +} + +void Fog1_InitAll(void) +{ +    Fog1_InitVars(); +    while (gWeatherPtr->weatherGfxLoaded == FALSE) +        Fog1_Main(); +} + +void Fog1_Main(void) +{ +    gWeatherPtr->fog1ScrollPosX = (gSpriteCoordOffsetX - gWeatherPtr->unknown_6F2) & 0xFF; +    if (++gWeatherPtr->unknown_6F0 > 3) +    { +        gWeatherPtr->unknown_6F0 = 0; +        gWeatherPtr->unknown_6F2++; +    } +    switch (gWeatherPtr->initStep) +    { +    case 0: +        CreateFog1Sprites(); +        if (gWeatherPtr->currWeather == WEATHER_FOG_1) +            Weather_SetTargetBlendCoeffs(12, 8, 3); +        else +            Weather_SetTargetBlendCoeffs(4, 16, 0); +        gWeatherPtr->initStep++; +        break; +    case 1: +        if (Weather_UpdateBlend()) +        { +            gWeatherPtr->weatherGfxLoaded = TRUE; +            gWeatherPtr->initStep++; +        } +        break; +    } +} + +bool8 Fog1_Finish(void) +{ +    gWeatherPtr->fog1ScrollPosX = (gSpriteCoordOffsetX - gWeatherPtr->unknown_6F2) & 0xFF; +    if (++gWeatherPtr->unknown_6F0 > 3) +    { +        gWeatherPtr->unknown_6F0 = 0; +        gWeatherPtr->unknown_6F2++; +    } +    switch (gWeatherPtr->finishStep) +    { +    case 0: +        Weather_SetTargetBlendCoeffs(0, 16, 3); +        gWeatherPtr->finishStep++; +        break; +    case 1: +        if (!Weather_UpdateBlend()) +            break; +        gWeatherPtr->finishStep++; +        break; +    case 2: +        DestroyFog1Sprites(); +        gWeatherPtr->finishStep++; +        break; +    default: +        return FALSE; +    } +    return TRUE; +} + +#define sprColumn data[0] + +static void Fog1SpriteCallback(struct Sprite *sprite) +{ +    sprite->pos2.y = (u8)gSpriteCoordOffsetY; +    sprite->pos1.x = gWeatherPtr->fog1ScrollPosX + 32 + sprite->sprColumn * 64; +    if (sprite->pos1.x > 0x10F) +    { +        sprite->pos1.x = 480 + gWeatherPtr->fog1ScrollPosX - (4 - sprite->sprColumn) * 64; +        sprite->pos1.x &= 0x1FF; +    } +} + +static void CreateFog1Sprites(void) +{ +    u16 i; + +    if (!gWeatherPtr->fog1SpritesCreated) +    { +        struct SpriteSheet fog1SpriteSheet = {gWeatherFog1Tiles, sizeof(gWeatherFog1Tiles), 0x1201}; + +        LoadSpriteSheet(&fog1SpriteSheet); +        for (i = 0; i < 20; i++) +        { +            u8 spriteId = CreateSpriteAtEnd(&sFog1SpriteTemplate, 0, 0, 0xFF); + +            if (spriteId != MAX_SPRITES) +            { +                struct Sprite *sprite = &gSprites[spriteId]; + +                sprite->sprColumn = i % 5; +                sprite->pos1.x = (i % 5) * 64 + 32; +                sprite->pos1.y = (i / 5) * 64 + 32; +                gWeatherPtr->sprites.s2.fog1Sprites[i] = sprite; +            } +            else +            { +                gWeatherPtr->sprites.s2.fog1Sprites[i] = NULL; +            } +        } +        gWeatherPtr->fog1SpritesCreated = TRUE; +    } +} + +#undef sprColumn + +static void DestroyFog1Sprites(void) +{ +    u16 i; + +    if (gWeatherPtr->fog1SpritesCreated) +    { +        for (i = 0; i < 20; i++) +        { +            if (gWeatherPtr->sprites.s2.fog1Sprites[i] != NULL) +                DestroySprite(gWeatherPtr->sprites.s2.fog1Sprites[i]); +        } +        FreeSpriteTilesByTag(0x1201); +        gWeatherPtr->fog1SpritesCreated = 0; +    } +} + +//------------------------------------------------------------------------------ +// Volcanic ash +//------------------------------------------------------------------------------ + +void Ash_Main(void); +void LoadAshSpriteSheet(void); +void CreateAshSprites(void); +void DestroyAshSprites(void); + +void Ash_InitVars(void) +{ +    gWeatherPtr->initStep = 0; +    gWeatherPtr->weatherGfxLoaded = FALSE; +    gWeatherPtr->unknown_6C1 = 0; +    gWeatherPtr->unknown_6C2 = 20; +    gWeatherPtr->unknown_6FE = 20; +    if (!gWeatherPtr->ashSpritesCreated) +    { +        Weather_SetBlendCoeffs(0, 16); +        REG_BLDALPHA = BLDALPHA_BLEND(64, 63);  // Those aren't even valid coefficients! +    } +} + +void Ash_InitAll(void) +{ +    Ash_InitVars(); +    while (gWeatherPtr->weatherGfxLoaded == FALSE) +        Ash_Main(); +} + +void Ash_Main(void) +{ +    gWeatherPtr->unknown_6FC = gSpriteCoordOffsetX & 0x1FF; +    while (gWeatherPtr->unknown_6FC > 0xEF) +        gWeatherPtr->unknown_6FC -= 0xF0; +    switch (gWeatherPtr->initStep) +    { +    case 0: +        LoadAshSpriteSheet(); +        gWeatherPtr->initStep++; +        break; +    case 1: +        if (!gWeatherPtr->ashSpritesCreated) +            CreateAshSprites(); +        Weather_SetTargetBlendCoeffs(16, 0, 1); +        gWeatherPtr->initStep++; +        break; +    case 2: +        if (!Weather_UpdateBlend()) +            break; +        gWeatherPtr->weatherGfxLoaded = TRUE; +        gWeatherPtr->initStep++; +        break; +    default: +        Weather_UpdateBlend(); +        break; +    } +} + +bool8 Ash_Finish(void) +{ +    switch (gWeatherPtr->finishStep) +    { +    case 0: +        Weather_SetTargetBlendCoeffs(0, 16, 1); +        gWeatherPtr->finishStep++; +        break; +    case 1: +        if (!Weather_UpdateBlend()) +            break; +        DestroyAshSprites(); +        gWeatherPtr->finishStep++; +        break; +    case 2: +        REG_BLDALPHA = 0; +        gWeatherPtr->finishStep++; +        return FALSE; +    default: +        return FALSE; +    } +    return TRUE; +} + +static const struct SpriteSheet sAshSpriteSheet = {gWeatherAshTiles, sizeof(gWeatherAshTiles), 0x1202}; + +void LoadAshSpriteSheet(void) +{ +    LoadSpriteSheet(&sAshSpriteSheet); +} + +const struct OamData gOamData_839ABB8 = +{ +    .y = 0, +    .affineMode = 0, +    .objMode = 1, +    .mosaic = 0, +    .bpp = 0, +    .shape = 0, +    .x = 0, +    .matrixNum = 0, +    .size = 3, +    .tileNum = 0, +    .priority = 1, +    .paletteNum = 15, +    .affineParam = 0, +}; + +const union AnimCmd gSpriteAnim_839ABC0[] = +{ +    ANIMCMD_FRAME(0, 60), +    ANIMCMD_FRAME(64, 60), +    ANIMCMD_JUMP(0), +}; + +const union AnimCmd *const gSpriteAnimTable_839ABCC[] = +{ +    gSpriteAnim_839ABC0, +}; + +void sub_807FAA8(struct Sprite *); +static const struct SpriteTemplate sAshSpriteTemplate = +{ +    .tileTag = 4610, +    .paletteTag = 4608, +    .oam = &gOamData_839ABB8, +    .anims = gSpriteAnimTable_839ABCC, +    .images = NULL, +    .affineAnims = gDummySpriteAffineAnimTable, +    .callback = sub_807FAA8, +}; + +void CreateAshSprites(void) +{ +    u8 i; + +    if (!gWeatherPtr->ashSpritesCreated) +    { +        for (i = 0; i < 20; i++) +        { +            u8 spriteId = CreateSpriteAtEnd(&sAshSpriteTemplate, 0, 0, 0x4E); + +            if (spriteId != MAX_SPRITES) +            { +                struct Sprite *sprite = &gSprites[spriteId]; + +                sprite->data[1] = 0; +                sprite->data[2] = (u8)(i % 5); +                sprite->data[3] = (u8)(i / 5); +                sprite->data[0] = sprite->data[3] * 64 + 32; +                gWeatherPtr->sprites.s2.ashSprites[i] = sprite; +            } +            else +            { +                gWeatherPtr->sprites.s2.ashSprites[i] = NULL; +            } +        } +        gWeatherPtr->ashSpritesCreated = TRUE; +    } +} + +void DestroyAshSprites(void) +{ +    u16 i; + +    if (gWeatherPtr->ashSpritesCreated) +    { +        for (i = 0; i < 20; i++) +        { +            if (gWeatherPtr->sprites.s2.ashSprites[i] != NULL) +                DestroySprite(gWeatherPtr->sprites.s2.ashSprites[i]); +        } +        FreeSpriteTilesByTag(0x1202); +        gWeatherPtr->ashSpritesCreated = FALSE; +    } +} + +void sub_807FAA8(struct Sprite *sprite) +{ +    sprite->data[1]++; +    if (sprite->data[1] > 5) +    { +        sprite->data[1] = 0; +        sprite->data[0]++; +    } +    sprite->pos1.y = gSpriteCoordOffsetY + sprite->data[0]; +    sprite->pos1.x = gWeatherPtr->unknown_6FC + 32 + sprite->data[2] * 64; +    if (sprite->pos1.x > 271) +    { +        sprite->pos1.x = gWeatherPtr->unknown_6FC + 0x1E0 - (4 - sprite->data[2]) * 64; +        sprite->pos1.x &= 0x1FF; +    } +} + +//------------------------------------------------------------------------------ +// Fog 2 +//------------------------------------------------------------------------------ + +void Fog2_InitVars(void) +{ +    gWeatherPtr->initStep = 0; +    gWeatherPtr->weatherGfxLoaded = 0; +    gWeatherPtr->unknown_6C1 = 0; +    gWeatherPtr->unknown_6C2 = 20; +    gWeatherPtr->unknown_6F0 = 0; +    gWeatherPtr->unknown_6F2 = 1; +    if (gWeatherPtr->fog2SpritesCreated == 0) +    { +        gWeatherPtr->unknown_71C = 0; +        gWeatherPtr->unknown_71E = 0; +        gWeatherPtr->unknown_720 = 0; +        gWeatherPtr->unknown_722 = 0; +        gWeatherPtr->unknown_718 = 0; +        gWeatherPtr->unknown_71A = 0; +        Weather_SetBlendCoeffs(0, 16); +    } +} + +void Fog2_Main(void); + +void Fog2_InitAll(void) +{ +    Fog2_InitVars(); +    while (gWeatherPtr->weatherGfxLoaded == FALSE) +        Fog2_Main(); +} + +void sub_807FC9C(void); +void CreateFog2Sprites(void); + +void Fog2_Main(void) +{ +    sub_807FC9C(); +    switch (gWeatherPtr->initStep) +    { +    case 0: +        CreateFog2Sprites(); +        gWeatherPtr->initStep++; +        break; +    case 1: +        Weather_SetTargetBlendCoeffs(12, 8, 8); +        gWeatherPtr->initStep++; +        break; +    case 2: +        if (!Weather_UpdateBlend()) +            break; +        gWeatherPtr->weatherGfxLoaded = TRUE; +        gWeatherPtr->initStep++; +        break; +    } +} + +void DestroyFog2Sprites(void); + +bool8 Fog2_Finish(void) +{ +    sub_807FC9C(); +    switch (gWeatherPtr->finishStep) +    { +    case 0: +        Weather_SetTargetBlendCoeffs(0, 16, 1); +        gWeatherPtr->finishStep++; +        break; +    case 1: +        if (!Weather_UpdateBlend()) +            break; +        gWeatherPtr->finishStep++; +        break; +    case 2: +        DestroyFog2Sprites(); +        gWeatherPtr->finishStep++; +        break; +    default: +        return FALSE; +    } +    return TRUE; +} + +void sub_807FC9C(void) +{ +    if (++gWeatherPtr->unknown_71C > 2) +    { +        gWeatherPtr->unknown_720++; +        gWeatherPtr->unknown_71C = 0; +    } + +    if (++gWeatherPtr->unknown_71E > 4) +    { +        gWeatherPtr->unknown_722++; +        gWeatherPtr->unknown_71E = 0; +    } + +    gWeatherPtr->unknown_718 = (gSpriteCoordOffsetX - gWeatherPtr->unknown_720) & 0xFF; +    gWeatherPtr->unknown_71A = gSpriteCoordOffsetY + gWeatherPtr->unknown_722; +} + +extern const struct SpriteTemplate sFog2SpriteTemplate;  // defined below + +void CreateFog2Sprites(void) +{ +    u16 i; + +    if (!gWeatherPtr->fog2SpritesCreated) +    { +        struct SpriteSheet fog2SpriteSheet = {gWeatherFog2Tiles, sizeof(gWeatherFog2Tiles), 0x1203}; + +        LoadSpriteSheet(&fog2SpriteSheet); +        for (i = 0; i < 20; i++) +        { +            u8 spriteId = CreateSpriteAtEnd(&sFog2SpriteTemplate, 0, (i / 5) * 64, 0xFF); + +            if (spriteId != MAX_SPRITES) +            { +                struct Sprite *sprite = &gSprites[spriteId]; + +                sprite->data[0] = i % 5; +                sprite->data[1] = i / 5; +                gWeatherPtr->sprites.s2.fog2Sprites[i] = sprite; +            } +            else +            { +                gWeatherPtr->sprites.s2.fog2Sprites[i] = NULL; +            } +        } +        gWeatherPtr->fog2SpritesCreated = TRUE; +    } +} + +const struct OamData gOamData_839ABF0 = +{ +    .y = 0, +    .affineMode = 0, +    .objMode = 1, +    .mosaic = 0, +    .bpp = 0, +    .shape = 0, +    .x = 0, +    .matrixNum = 0, +    .size = 3, +    .tileNum = 0, +    .priority = 2, +    .paletteNum = 0, +    .affineParam = 0, +}; + +const union AnimCmd gSpriteAnim_839ABF8[] = +{ +    ANIMCMD_FRAME(0, 16), +    ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_839AC00[] = +{ +    gSpriteAnim_839ABF8, +}; + +void Fog2SpriteCallback(struct Sprite *); +const struct SpriteTemplate sFog2SpriteTemplate = +{ +    .tileTag = 4611, +    .paletteTag = 4608, +    .oam = &gOamData_839ABF0, +    .anims = gSpriteAnimTable_839AC00, +    .images = NULL, +    .affineAnims = gDummySpriteAffineAnimTable, +    .callback = Fog2SpriteCallback, +}; + +void DestroyFog2Sprites(void) +{ +    u16 i; + +    if (gWeatherPtr->fog2SpritesCreated) +    { +        for (i = 0; i < 20; i++) +        { +            if (gWeatherPtr->sprites.s2.fog2Sprites[i] != NULL) +                DestroySprite(gWeatherPtr->sprites.s2.fog2Sprites[i]); +        } +        FreeSpriteTilesByTag(0x1203); +        gWeatherPtr->fog2SpritesCreated = FALSE; +    } +} + +void Fog2SpriteCallback(struct Sprite *sprite) +{ +    sprite->pos2.y = gWeatherPtr->unknown_71A; +    sprite->pos1.x = gWeatherPtr->unknown_718 + 32 + sprite->data[0] * 64; +    if (sprite->pos1.x > 271) +    { +        sprite->pos1.x = gWeatherPtr->unknown_718 + 0x1E0 - (4 - sprite->data[0]) * 64; +        sprite->pos1.x &= 0x1FF; +    } +} + +//------------------------------------------------------------------------------ +// Sandstorm +//------------------------------------------------------------------------------ + +void Sandstorm_InitVars(void) +{ +    gWeatherPtr->initStep = 0; +    gWeatherPtr->weatherGfxLoaded = 0; +    gWeatherPtr->unknown_6C1 = 0; +    gWeatherPtr->unknown_6C2 = 20; +    if (gWeatherPtr->sandstormSprites1Created == 0) +    { +        gWeatherPtr->unknown_704 = gWeatherPtr->unknown_708 = 0; +        gWeatherPtr->unknown_712 = 8; +        gWeatherPtr->unknown_714 = 0; +        // Dead code. How does the compiler not optimize this out? +        if (gWeatherPtr->unknown_712 > 0x5F) +            gWeatherPtr->unknown_712 = 0x80 - gWeatherPtr->unknown_712; +        Weather_SetBlendCoeffs(0, 16); +    } +} + +void Sandstorm_Main(void); + +void Sandstorm_InitAll(void) +{ +    Sandstorm_InitVars(); +    while (gWeatherPtr->weatherGfxLoaded == FALSE) +        Sandstorm_Main(); +} + +void sub_808002C(void); +void sub_8080064(void); +void CreateSandstormSprites_1(void); +void CreateSandstormSprites_2(void); + +void Sandstorm_Main(void) +{ +    sub_8080064(); +    sub_808002C(); +    if (gWeatherPtr->unknown_712 > 0x5F) +        gWeatherPtr->unknown_712 = 32; +    switch (gWeatherPtr->initStep) +    { +    case 0: +        CreateSandstormSprites_1(); +        CreateSandstormSprites_2(); +        gWeatherPtr->initStep++; +        break; +    case 1: +        Weather_SetTargetBlendCoeffs(16, 0, 0); +        gWeatherPtr->initStep++; +        break; +    case 2: +        if (!Weather_UpdateBlend()) +            break; +        gWeatherPtr->weatherGfxLoaded = TRUE; +        gWeatherPtr->initStep++; +        break; +    } +} + +void sub_80800E4(void); + +bool8 Sandstorm_Finish(void) +{ +    sub_8080064(); +    sub_808002C(); +    switch (gWeatherPtr->finishStep) +    { +    case 0: +        Weather_SetTargetBlendCoeffs(0, 16, 0); +        gWeatherPtr->finishStep++; +        break; +    case 1: +        if (!Weather_UpdateBlend()) +            break; +        gWeatherPtr->finishStep++; +        break; +    case 2: +        sub_80800E4(); +        gWeatherPtr->finishStep++; +        break; +    default: +        return FALSE; +    } +    return TRUE; +} + +void sub_808002C(void) +{ +    if (gWeatherPtr->unknown_714++ > 4) +    { +        gWeatherPtr->unknown_712++; +        gWeatherPtr->unknown_714 = 0; +    } +} + +void sub_8080064(void) +{ +    gWeatherPtr->unknown_704 -= gSineTable[gWeatherPtr->unknown_712] * 4; +    gWeatherPtr->unknown_708 -= gSineTable[gWeatherPtr->unknown_712]; +    gWeatherPtr->unknown_70E = (gSpriteCoordOffsetX + (gWeatherPtr->unknown_704 >> 8)) & 0xFF; +    gWeatherPtr->unknown_710 = gSpriteCoordOffsetY + (gWeatherPtr->unknown_708 >> 8); +} + +void sub_80800E4(void) +{ +    u16 i; + +    if (gWeatherPtr->sandstormSprites1Created) +    { +        for (i = 0; i < 20; i++) +        { +            if (gWeatherPtr->sprites.s2.sandstormSprites1[i] != NULL) +                DestroySprite(gWeatherPtr->sprites.s2.sandstormSprites1[i]); +        } +        gWeatherPtr->sandstormSprites1Created = FALSE; +        FreeSpriteTilesByTag(0x1204); +    } + +    if (gWeatherPtr->sandstormSprites2Created) +    { +        for (i = 0; i < 5; i++) +        { +            if (gWeatherPtr->sprites.s2.sandstormSprites2[i] != NULL) +                DestroySprite(gWeatherPtr->sprites.s2.sandstormSprites2[i]); +        } +        gWeatherPtr->sandstormSprites2Created = FALSE; +    } +} + +const struct OamData gOamData_839AC1C = +{ +    .y = 0, +    .affineMode = 0, +    .objMode = 1, +    .mosaic = 0, +    .bpp = 0, +    .shape = 0, +    .x = 0, +    .matrixNum = 0, +    .size = 3, +    .tileNum = 0, +    .priority = 1, +    .paletteNum = 0, +    .affineParam = 0, +}; + +const union AnimCmd gSpriteAnim_839AC24[] = +{ +    ANIMCMD_FRAME(0, 3), +    ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_839AC2C[] = +{ +    ANIMCMD_FRAME(64, 3), +    ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_839AC34[] = +{ +    gSpriteAnim_839AC24, +    gSpriteAnim_839AC2C, +}; + +void SandstormSpriteCallback1(struct Sprite *); +const struct SpriteTemplate sSandstormSpriteTemplate = +{ +    .tileTag = 4612, +    .paletteTag = 4609, +    .oam = &gOamData_839AC1C, +    .anims = gSpriteAnimTable_839AC34, +    .images = NULL, +    .affineAnims = gDummySpriteAffineAnimTable, +    .callback = SandstormSpriteCallback1, +}; + +static const struct SpriteSheet sSandstormSpriteSheet = {gWeatherSandstormTiles, sizeof(gWeatherSandstormTiles), 0x1204}; + +void CreateSandstormSprites_1(void) +{ +    u16 i; + +    if (!gWeatherPtr->sandstormSprites1Created) +    { +        LoadSpriteSheet(&sSandstormSpriteSheet); +        sub_807D8C0(gUnknown_08397128); +        for (i = 0; i < 20; i++) +        { +            u8 spriteId = CreateSpriteAtEnd(&sSandstormSpriteTemplate, 0, (i / 5) * 64, 1); + +            if (spriteId != MAX_SPRITES) +            { +                gWeatherPtr->sprites.s2.sandstormSprites1[i] = &gSprites[spriteId]; +                gWeatherPtr->sprites.s2.sandstormSprites1[i]->data[0] = i % 5; +                gWeatherPtr->sprites.s2.sandstormSprites1[i]->data[1] = i / 5; +            } +            else +            { +                gWeatherPtr->sprites.s2.sandstormSprites1[i] = NULL; +            } +        } +        gWeatherPtr->sandstormSprites1Created = TRUE; +    } +} + +const u16 gUnknown_0839AC5C[] = {0,	120, 80, 160, 40, 0}; + +void SandstormSpriteCallback2(struct Sprite *); + +void CreateSandstormSprites_2(void) +{ +    u16 i; + +    if (!gWeatherPtr->sandstormSprites2Created) +    { +        for (i = 0; i < 5; i++) +        { +            u8 spriteId = CreateSpriteAtEnd(&sSandstormSpriteTemplate, i * 48 + 0x18, 0xD0, 1); + +            if (spriteId != MAX_SPRITES) +            { +                gWeatherPtr->sprites.s2.sandstormSprites2[i] = &gSprites[spriteId]; +                gWeatherPtr->sprites.s2.sandstormSprites2[i]->oam.size = 2; +                gWeatherPtr->sprites.s2.sandstormSprites2[i]->data[1] = i * 51; +                gWeatherPtr->sprites.s2.sandstormSprites2[i]->data[0] = 8; +                gWeatherPtr->sprites.s2.sandstormSprites2[i]->data[2] = 0; +                gWeatherPtr->sprites.s2.sandstormSprites2[i]->data[4] = 0x6730; +                gWeatherPtr->sprites.s2.sandstormSprites2[i]->data[3] = gUnknown_0839AC5C[i]; +                StartSpriteAnim(gWeatherPtr->sprites.s2.sandstormSprites2[i], 1); +                CalcCenterToCornerVec(gWeatherPtr->sprites.s2.sandstormSprites2[i], 0, 2, 0); +                gWeatherPtr->sprites.s2.sandstormSprites2[i]->callback = SandstormSpriteCallback2; +            } +            else +            { +                gWeatherPtr->sprites.s2.sandstormSprites2[i] = NULL; +            } +            gWeatherPtr->sandstormSprites2Created = TRUE; +        } +    } +} + +void SandstormSpriteCallback1(struct Sprite *sprite) +{ +    sprite->pos2.y = gWeatherPtr->unknown_710; +    sprite->pos1.x = gWeatherPtr->unknown_70E + 32 + sprite->data[0] * 64; +    if (sprite->pos1.x > 271) +    { +        sprite->pos1.x = gWeatherPtr->unknown_70E + 0x1E0 - (4 - sprite->data[0]) * 64; +        sprite->pos1.x &= 0x1FF; +    } +} + +void SandstormSpriteCallback3(struct Sprite *); + +void SandstormSpriteCallback2(struct Sprite *sprite) +{ +    if (--sprite->data[3] == -1) +        sprite->callback = SandstormSpriteCallback3; +} + +void SandstormSpriteCallback3(struct Sprite *sprite) +{ +    u32 x; +    u32 y; + +    if (--sprite->pos1.y < -48) +    { +        sprite->pos1.y = 208; +        sprite->data[0] = 4; +    } +    x = sprite->data[0] * gSineTable[sprite->data[1]]; +    y = sprite->data[0] * gSineTable[sprite->data[1] + 64]; +    sprite->pos2.x = x >> 8; +    sprite->pos2.y = y >> 8; +    sprite->data[1] = (sprite->data[1] + 10) & 0xFF; +    if (++sprite->data[2] > 8) +    { +        sprite->data[2] = 0; +        sprite->data[0]++; +    } +} + +//------------------------------------------------------------------------------ +// Weather 11 +//------------------------------------------------------------------------------ + +void Weather11_InitVars(void) +{ +    gWeatherPtr->initStep = 0; +    gWeatherPtr->unknown_6C1 = 3; +    gWeatherPtr->unknown_6C2 = 20; +} + +void Weather11_InitAll(void) +{ +    Weather11_InitVars(); +} + +void Weather11_Main(void) +{ +} + +bool8 Weather11_Finish(void) +{ +    return FALSE; +} + +//------------------------------------------------------------------------------ +// Weather 14 +//------------------------------------------------------------------------------ + +const u8 gUnknown_0839AC68[] = {40, 90, 60, 90, 2, 60, 40, 30}; + +const struct SpriteSheet gWeatherBubbleSpriteSheet = {gWeatherBubbleTiles, sizeof(gWeatherBubbleTiles), 0x1205}; + +void Bubbles_InitVars(void) +{ +    Fog1_InitVars(); +    if (gWeatherPtr->unknown_72E == 0) +    { +        LoadSpriteSheet(&gWeatherBubbleSpriteSheet); +        gWeatherPtr->unknown_728 = 0; +        gWeatherPtr->unknown_726 = gUnknown_0839AC68[0]; +        gWeatherPtr->unknown_72A = 0; +        gWeatherPtr->unknown_72C = 0; +    } +} + +void Bubbles_Main(void); + +void Bubbles_InitAll(void) +{ +    Bubbles_InitVars(); +    while (gWeatherPtr->weatherGfxLoaded == FALSE) +        Bubbles_Main(); +} + +void sub_8080588(u16); + +void Bubbles_Main(void) +{ +    Fog1_Main(); +    if (++gWeatherPtr->unknown_726 > gUnknown_0839AC68[gWeatherPtr->unknown_728]) +    { +        gWeatherPtr->unknown_726 = 0; +        if (++gWeatherPtr->unknown_728 > 7) +            gWeatherPtr->unknown_728 = 0; +        sub_8080588(gWeatherPtr->unknown_72A); +        if (++gWeatherPtr->unknown_72A > 12) +            gWeatherPtr->unknown_72A = 0; +    } +} + +void sub_8080610(void); + +bool8 Bubbles_Finish(void) +{ +    if (!Fog1_Finish()) +    { +        sub_8080610(); +        return FALSE; +    } +    return TRUE; +} + +const s16 gUnknown_0839AC78[][2] = +{ +    {120, 160}, +    {376, 160}, +    { 40, 140}, +    {296, 140}, +    {180, 130}, +    {436, 130}, +    { 60, 160}, +    {436, 160}, +    {220, 180}, +    {476, 180}, +    { 10,  90}, +    {266,  90}, +    {256, 160}, +}; + +const union AnimCmd gSpriteAnim_839ACAC[] = +{ +    ANIMCMD_FRAME(0, 16), +    ANIMCMD_FRAME(1, 16), +    ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_839ACB8[] = +{ +    gSpriteAnim_839ACAC, +}; + +extern const struct OamData gOamData_837DF24; + +void unc_0807DAB4(struct Sprite *); +const struct SpriteTemplate gSpriteTemplate_839ACBC = +{ +    .tileTag = 4613, +    .paletteTag = 4608, +    .oam = &gOamData_837DF24, +    .anims = gSpriteAnimTable_839ACB8, +    .images = NULL, +    .affineAnims = gDummySpriteAffineAnimTable, +    .callback = unc_0807DAB4, +}; + +void sub_8080588(u16 a) +{ +    s16 x = gUnknown_0839AC78[a][0]; +    s16 y = gUnknown_0839AC78[a][1] - gSpriteCoordOffsetY; +    u8 spriteId = CreateSpriteAtEnd( +      &gSpriteTemplate_839ACBC, +      x, +      y, +      0); + +    if (spriteId != MAX_SPRITES) +    { +        gSprites[spriteId].oam.priority = 1; +        gSprites[spriteId].coordOffsetEnabled = TRUE; +        gSprites[spriteId].data[0] = 0; +        gSprites[spriteId].data[1] = 0; +        gSprites[spriteId].data[2] = 0; +        gWeatherPtr->unknown_72C++; +    } +} + +void sub_8080610(void) +{ +    u16 i; + +    for (i = 0; i < 64; i++) +    { +        if (gSprites[i].template == &gSpriteTemplate_839ACBC) +            DestroySprite(&gSprites[i]); +    } +    FreeSpriteTilesByTag(0x1205); +} + +void unc_0807DAB4(struct Sprite *sprite) +{ +    ++sprite->data[0]; +    if (++sprite->data[0] > 8)  // double increment +    { +        sprite->data[0] = 0; +        if (sprite->data[1] == 0) +        { +            if (++sprite->pos2.x > 4) +                sprite->data[1] = 1; +        } +        else +        { +            if (--sprite->pos2.x <= 0) +                sprite->data[1] = 0; +        } +    } +    sprite->pos1.y -= 3; +    if (++sprite->data[2] > 0x77) +        DestroySprite(sprite); +} + +//------------------------------------------------------------------------------ + +u8 TranslateWeatherNum(u8); +void UpdateRainCounter(u8, u8); + +void SetSav1Weather(u32 weather) +{ +    u8 oldWeather = gSaveBlock1.weather; + +    gSaveBlock1.weather = TranslateWeatherNum(weather); +    UpdateRainCounter(gSaveBlock1.weather, oldWeather); +} + +u8 GetSav1Weather(void) +{ +    return gSaveBlock1.weather; +} + +void SetSav1WeatherFromCurrMapHeader(void) +{ +    u8 oldWeather = gSaveBlock1.weather; + +    gSaveBlock1.weather = TranslateWeatherNum(gMapHeader.weather); +    UpdateRainCounter(gSaveBlock1.weather, oldWeather); +} + +void SetWeather(u32 weather) +{ +    SetSav1Weather(weather); +    DoWeatherEffect(GetSav1Weather()); +} + +void SetWeather_Unused(u32 weather) +{ +    SetSav1Weather(weather); +    sub_807C988(GetSav1Weather()); +} + +void DoCurrentWeather(void) +{ +    DoWeatherEffect(GetSav1Weather()); +} + +void sub_8080750(void) +{ +    sub_807C988(GetSav1Weather()); +} + +static const u8 sWeatherCycle1[] = {2, 3, 5, 3}; +static const u8 sWeatherCycle2[] = {2, 2, 3, 2}; + +u8 TranslateWeatherNum(u8 weather) +{ +    switch (weather) +    { +    case 0:  return 0; +    case 1:  return 1; +    case 2:  return 2; +    case 3:  return 3; +    case 4:  return 4; +    case 5:  return 5; +    case 6:  return 6; +    case 7:  return 7; +    case 8:  return 8; +    case 9:  return 9; +    case 10: return 10; +    case 11: return 11; +    case 12: return 12; +    case 13: return 13; +    case 14: return 14; +    case 20: return sWeatherCycle1[gSaveBlock1.filler_2F]; +    case 21: return sWeatherCycle2[gSaveBlock1.filler_2F]; +    default: return 0; +    } +} + +void UpdateWeatherPerDay(u16 increment) +{ +    u16 weatherStage = gSaveBlock1.filler_2F + increment; +    weatherStage %= 4; +    gSaveBlock1.filler_2F = weatherStage; +} + +void UpdateRainCounter(u8 newWeather, u8 oldWeather) +{ +    if (newWeather != oldWeather +     && (newWeather == WEATHER_RAIN_LIGHT || newWeather == WEATHER_RAIN_MED)) +        IncrementGameStat(0x28); +} diff --git a/src/field/overworld.c b/src/field/overworld.c index e6a6a9f11..ca59426fa 100644 --- a/src/field/overworld.c +++ b/src/field/overworld.c @@ -602,7 +602,7 @@ void sub_80538F0(u8 mapGroup, u8 mapNum)      prev_quest_postbuffer_cursor_backup_reset();      sub_8082BD0(mapGroup, mapNum);      DoTimeBasedEvents(); -    sub_80806E4(); +    SetSav1WeatherFromCurrMapHeader();      ChooseAmbientCrySpecies();      SetDefaultFlashLevel();      Overworld_ClearSavedMusic(); @@ -638,7 +638,7 @@ void sub_8053994(u32 a1)      sub_8082BD0(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum);      if (a1 != 1)          DoTimeBasedEvents(); -    sub_80806E4(); +    SetSav1WeatherFromCurrMapHeader();      ChooseAmbientCrySpecies();      if (v2)          FlagClear(SYS_USE_FLASH); @@ -1737,7 +1737,7 @@ void sub_8054D4C(u32 a1)      sub_805C7C4(0);      FieldEffectActiveListClear();      InitFieldMessageBox(); -    sub_807C828(); +    StartWeather();      sub_8080750();      if (!a1)          SetUpFieldTasks(); diff --git a/src/field/scrcmd.c b/src/field/scrcmd.c index 28aa3355a..e6305d9c4 100644 --- a/src/field/scrcmd.c +++ b/src/field/scrcmd.c @@ -692,7 +692,7 @@ bool8 ScrCmd_setweather(struct ScriptContext *ctx)  bool8 ScrCmd_resetweather(struct ScriptContext *ctx)  { -    sub_80806E4(); +    SetSav1WeatherFromCurrMapHeader();      return FALSE;  } | 
