diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/cable_car.c | 1006 | ||||
-rw-r--r-- | src/overworld.c | 1 |
2 files changed, 1006 insertions, 1 deletions
diff --git a/src/cable_car.c b/src/cable_car.c new file mode 100755 index 000000000..00606c905 --- /dev/null +++ b/src/cable_car.c @@ -0,0 +1,1006 @@ +#include "global.h" +#include "bg.h" +#include "decompress.h" +#include "event_data.h" +#include "event_object_movement.h" +#include "field_weather.h" +#include "gpu_regs.h" +#include "graphics.h" +#include "alloc.h" +#include "main.h" +#include "menu.h" +#include "overworld.h" +#include "palette.h" +#include "random.h" +#include "scanline_effect.h" +#include "script.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "constants/event_objects.h" +#include "constants/rgb.h" +#include "constants/songs.h" +#include "constants/weather.h" + +struct CableCar +{ + u8 taskId; + u8 state; + u8 weather; + u16 unk4; + u16 timer; + u8 bg0HorizontalOffset; + u8 bg0VerticalOffset; + u8 fillerA[0x2]; + u8 bg1HorizontalOffset; + u8 bg1VerticalOffset; + u8 fillerE[0x6]; + u8 bg3HorizontalOffset; + u8 bg3VerticalOffset; + u8 filler16[0x2]; + u8 unk18; + u8 unk19; + u8 unk1A; + u8 unk1B; + u8 unk1C; + u8 unk1D; + u8 unk1E; + u8 unk1F; + u8 unk20; + u16 unk22[9][12]; + u8 fillerFA[0x2]; + /*0x00FC*/ u16 bgTilemapBuffers[4][0x800]; + /*0x40FC*/ u16 *mtChimneyTilemap; + /*0x4100*/ u16 *treeTilemap; + /*0x4104*/ u16 *mountainTilemap; + /*0x4108*/ const u16 *pylonHookTilemapEntries; + /*0x410C*/ u8 *pylonStemTilemap; +}; + +static EWRAM_DATA struct CableCar *sCableCar = NULL; +EWRAM_DATA u8 gUnknown_0203ABB0 = 0; +EWRAM_DATA u8 gUnknown_0203ABB1 = 0; +EWRAM_DATA u8 gUnknown_0203ABB2 = 0; +EWRAM_DATA u8 gUnknown_0203ABB3 = 0; +EWRAM_DATA u8 gUnknown_0203ABB4 = 0; +EWRAM_DATA u8 gUnknown_0203ABB5 = 0; + +static void CableCarMainCallback_Setup(void); +static void sub_8150B6C(u8); +static void LoadCableCarSprites(void); +static void sub_81514C8(u8); +static void sub_81503E4(u8); +static void sub_8150550(u8); +static void sub_8150664(u8); +static void CableCarVblankCallback(void); +static void CableCarMainCallback_Run(void); +static void sub_815115C(void); +static void sub_81511B8(void); +static void sub_8150868(struct Sprite *); +static void nullsub_58(struct Sprite *); +static void sub_8151214(void); +static void sub_8151388(void); + +const struct BgTemplate gCableCarBgTemplates[4] = { + { + .bg = 0, + .charBaseIndex = 0, + .mapBaseIndex = 28, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 0 + }, + { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 29, + .screenSize = 0, + .paletteMode = 0, + .priority = 2, + .baseTile = 0 + }, + { + .bg = 2, + .charBaseIndex = 0, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0 + }, + { + .bg = 3, + .charBaseIndex = 0, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0 + }, +}; + +const u8 gCableCarMtChimneyTilemap[] = INCBIN_U8("graphics/misc/cable_car_mt_chimney_map.bin.lz"); +const u8 gCableCarTreeTilemap[] = INCBIN_U8("graphics/misc/cable_car_tree_map.bin.lz"); +const u8 gCableCarMountainTilemap[] = INCBIN_U8("graphics/misc/cable_car_mountain_map.bin.lz"); + +const u16 gCableCarPylonHookTilemapEntries[] = { + 0x3000, + 0x3001, + 0x3002, + 0x3003, + 0x3004, + 0x3005, + 0x3006, + 0x3007, + 0x3008, + 0x3009, +}; + +const u8 gCableCarPylonStemTilemap[] = INCBIN_U8("graphics/misc/cable_car_pylon_stem_map.bin.lz"); + +const struct CompressedSpriteSheet gUnknown_085CDB54[] = { + { gCableCar_Gfx, 0x800, 1 }, + { gCableCarDoor_Gfx, 0x40, 2 }, + { gCableCarCord_Gfx, 0x80, 3 }, + { }, +}; + +const struct SpritePalette gUnknown_085CDB74[] = { + { gCableCar_Pal, 1 }, + { } +}; + +const struct OamData gOamData_85CDB84 = { + .affineMode = ST_OAM_AFFINE_DOUBLE, + .size = 3, + .priority = 2 +}; + +const struct OamData gOamData_85CDB8C = { + .affineMode = ST_OAM_AFFINE_DOUBLE, + .shape = ST_OAM_H_RECTANGLE, + .priority = 2 +}; + +const struct OamData gOamData_85CDB94 = { + .affineMode = ST_OAM_AFFINE_DOUBLE, + .size = 1, + .priority = 2 +}; + +const struct SpriteTemplate gSpriteTemplate_85CDB9C[] = +{ + { + .tileTag = 1, + .paletteTag = 1, + .oam = &gOamData_85CDB84, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8150868, + }, + { + .tileTag = 2, + .paletteTag = 1, + .oam = &gOamData_85CDB8C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8150868, + }, +}; + +const struct SpriteTemplate gSpriteTemplate_85CDBCC = { + .tileTag = 3, + .paletteTag = 1, + .oam = &gOamData_85CDB94, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = nullsub_58, +}; + +static void CableCarTask1(u8 taskId) +{ + if (!gPaletteFade.active) + { + SetMainCallback2(CableCarMainCallback_Setup); + DestroyTask(taskId); + } +} + +void CableCar(void) +{ + ScriptContext2_Enable(); + CreateTask(CableCarTask1, 1); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); +} + +static void CableCarMainCallback_Setup(void) +{ + u16 imebak; + u8 i = 0; + int sizeOut = 0; + + switch (gMain.state) + { + case 0: + default: + SetVBlankCallback(NULL); + sub_8150B6C(0); + ScanlineEffect_Stop(); + DmaFillLarge16(3, 0, (void *)VRAM, VRAM_SIZE, 0x1000); + DmaFill32Defvars(3, 0, (void *)OAM, OAM_SIZE); + DmaFill16Defvars(3, 0, (void *)PLTT, PLTT_SIZE); + sCableCar = AllocZeroed(sizeof(*sCableCar)); + gMain.state++; + break; + case 1: + ResetSpriteData(); + ResetTasks(); + FreeAllSpritePalettes(); + ResetPaletteFade(); + reset_temp_tile_data_buffers(); + StartWeather(); + for (i = 0; i < 20; i++) + gWeatherPtr->sprites.s2.ashSprites[i] = NULL; + + InitMapMusic(); + ResetMapMusic(); + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, gCableCarBgTemplates, ARRAY_COUNT(gCableCarBgTemplates)); + SetBgTilemapBuffer(0, sCableCar->bgTilemapBuffers[0]); + SetBgTilemapBuffer(1, sCableCar->bgTilemapBuffers[1]); + SetBgTilemapBuffer(2, sCableCar->bgTilemapBuffers[2]); + SetBgTilemapBuffer(3, sCableCar->bgTilemapBuffers[3]); + gSpriteCoordOffsetX = gSpriteCoordOffsetY = 0; + gMain.state++; + break; + case 2: + for (i = 0; i < 3; i++) + LoadCompressedObjectPic(&gUnknown_085CDB54[i]); + + LoadSpritePalettes(gUnknown_085CDB74); + sCableCar->mtChimneyTilemap = malloc_and_decompress(gCableCarMtChimneyTilemap, &sizeOut); + sCableCar->treeTilemap = malloc_and_decompress(gCableCarTreeTilemap, &sizeOut); + sCableCar->mountainTilemap = malloc_and_decompress(gCableCarMountainTilemap, &sizeOut); + sCableCar->pylonStemTilemap = malloc_and_decompress(gCableCarPylonStemTilemap, &sizeOut); + sCableCar->pylonHookTilemapEntries = gCableCarPylonHookTilemapEntries; + decompress_and_copy_tile_data_to_vram(0, gUnknown_08DBA5B8, 0, 0, 0); + gMain.state++; + break; + case 3: + if (!free_temp_tile_data_buffers_if_possible()) + { + LoadPalette(gUnknown_08DBA518, 0, 0x80); + gMain.state++; + } + break; + case 4: + LoadCableCarSprites(); + RunTasks(); + gMain.state++; + break; + case 5: + if (sCableCar->weather == WEATHER_ASH) + { + gMain.state++; + } + else if (gWeatherPtr->sprites.s2.ashSprites[0]) + { + for (i = 0; i < 20; i++) + { + if (gWeatherPtr->sprites.s2.ashSprites[i]) + gWeatherPtr->sprites.s2.ashSprites[i]->oam.priority = 0; + } + + gMain.state++; + } + break; + case 6: + CopyToBgTilemapBufferRect_ChangePalette(1, sCableCar->treeTilemap, 0, 17, 32, 15, 17); + CopyToBgTilemapBufferRect_ChangePalette(2, sCableCar->mountainTilemap, 0, 0, 30, 20, 17); + CopyToBgTilemapBufferRect_ChangePalette(3, sCableCar->pylonHookTilemapEntries, 0, 0, 5, 2, 17); + CopyToBgTilemapBufferRect_ChangePalette(3, sCableCar->pylonStemTilemap, 0, 2, 2, 20, 17); + gMain.state++; + break; + case 7: + sub_81514C8(gSpecialVar_0x8004); + CopyToBgTilemapBufferRect_ChangePalette(0, sCableCar->mtChimneyTilemap + 0x48, 0, 14, 12, 3, 17); + CopyToBgTilemapBufferRect_ChangePalette(0, sCableCar->mtChimneyTilemap + 0x6C, 12, 17, 12, 3, 17); + CopyToBgTilemapBufferRect_ChangePalette(0, sCableCar->mtChimneyTilemap + 0x90, 24, 20, 12, 3, 17); + CopyToBgTilemapBufferRect_ChangePalette(0, sCableCar->mtChimneyTilemap + 0x0, 0, 17, 12, 3, 17); + CopyToBgTilemapBufferRect_ChangePalette(0, sCableCar->mtChimneyTilemap + 0x24, 0, 20, 12, 3, 17); + CopyToBgTilemapBufferRect_ChangePalette(0, sCableCar->mtChimneyTilemap + 0x0, 12, 20, 12, 3, 17); + CopyToBgTilemapBufferRect_ChangePalette(0, sCableCar->mtChimneyTilemap + 0x24, 12, 23, 12, 3, 17); + CopyToBgTilemapBufferRect_ChangePalette(0, sCableCar->mtChimneyTilemap + 0x0, 24, 23, 12, 3, 17); + gMain.state++; + break; + case 8: + BeginNormalPaletteFade(0xFFFFFFFF, 3, 16, 0, RGB(0, 0, 0)); + FadeInNewBGM(MUS_ROPEWAY, 1); + sub_8150B6C(1); + gMain.state++; + break; + case 9: + imebak = REG_IME; + REG_IME = 0; + REG_IE |= INTR_FLAG_VBLANK; + REG_IME = imebak; + SetVBlankCallback(CableCarVblankCallback); + SetMainCallback2(CableCarMainCallback_Run); + CreateTask(sub_81503E4, 0); + if (gSpecialVar_0x8004 == 0) + sCableCar->taskId = CreateTask(sub_8150550, 1); + else + sCableCar->taskId = CreateTask(sub_8150664, 1); + break; + } +} + +static void CableCarMainCallback_Run(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + MapMusicMain(); +} + +static void CleanupCableCar(void) +{ + u8 i = 0; + + HideBg(0); + HideBg(1); + HideBg(2); + HideBg(3); + sub_8150B6C(0); + gSpriteCoordOffsetX = 0; + sub_80AB130(WEATHER_NONE); + for (i = 0; i < 20; i++) + gWeatherPtr->sprites.s2.ashSprites[i] = NULL; + + ResetTasks(); + ResetSpriteData(); + ResetPaletteFade(); + UnsetBgTilemapBuffer(0); + UnsetBgTilemapBuffer(1); + UnsetBgTilemapBuffer(2); + UnsetBgTilemapBuffer(3); + ResetBgsAndClearDma3BusyFlags(0); + sCableCar->pylonHookTilemapEntries = NULL; + FREE_AND_SET_NULL(sCableCar->pylonStemTilemap); + FREE_AND_SET_NULL(sCableCar->mountainTilemap); + FREE_AND_SET_NULL(sCableCar->treeTilemap); + FREE_AND_SET_NULL(sCableCar->mtChimneyTilemap); + FREE_AND_SET_NULL(sCableCar); + DmaFillLarge16(3, 0, (void *)VRAM, VRAM_SIZE, 0x1000); + DmaFill32Defvars(3, 0, (void *)OAM, OAM_SIZE); + DmaFill16Defvars(3, 0, (void *)PLTT, PLTT_SIZE); + WarpIntoMap(); + gFieldCallback = NULL; + SetMainCallback2(CB2_LoadMap); +} + +static void sub_81503E4(u8 taskId) +{ + u8 i = 0; + + sCableCar->timer++; + switch (sCableCar->state) + { + case 0: + if (sCableCar->timer == sCableCar->unk4) + { + ChangeWeather(sCableCar->weather); + sCableCar->state = 1; + } + break; + case 1: + switch (sCableCar->weather) + { + case WEATHER_ASH: + if (gWeatherPtr->sprites.s2.ashSprites[0] != NULL && gWeatherPtr->sprites.s2.ashSprites[0]->oam.priority != 0) + { + for (; i < 20; i++) + { + if (gWeatherPtr->sprites.s2.ashSprites[i] != NULL) + { + gWeatherPtr->sprites.s2.ashSprites[i]->oam.priority = 0; + } + } + sCableCar->state = 2; + } + break; + case WEATHER_SUNNY: + if (gWeatherPtr->currWeather == WEATHER_SUNNY) + { + sCableCar->state = 2; + } + else if (sCableCar->timer >= sCableCar->unk4 + 8) + { + for (; i < 20; i++) + { + if (gWeatherPtr->sprites.s2.ashSprites[i] != NULL) + { + gWeatherPtr->sprites.s2.ashSprites[i]->invisible ^= TRUE; + } + } + } + break; + } + break; + case 2: + if (sCableCar->timer == 570) + { + sCableCar->state = 3; + BeginNormalPaletteFade(0xFFFFFFFF, 3, 0, 16, RGB(0, 0, 0)); + FadeOutBGM(4); + } + break; + case 3: + if (!gPaletteFade.active) + { + sCableCar->state = 0xFF; + } + break; + case 0xFF: + SetVBlankCallback(NULL); + DestroyTask(taskId); + DestroyTask(sCableCar->taskId); + SetMainCallback2(CleanupCableCar); + break; + } +} + +static void sub_8150550(u8 taskId) +{ + if (sCableCar->state != 0xFF) + { + sCableCar->bg3HorizontalOffset--; + if ((sCableCar->timer % 2) == 0) + sCableCar->bg3VerticalOffset--; + + if ((sCableCar->timer % 8) == 0) + { + sCableCar->bg1HorizontalOffset--; + sCableCar->bg1VerticalOffset--; + } + + switch (sCableCar->bg3HorizontalOffset) + { + case 175: + FillBgTilemapBufferRect(3, 0, 0, 22, 2, 10, 17); + break; + case 40: + FillBgTilemapBufferRect(3, 0, 3, 0, 2, 2, 17); + break; + case 32: + FillBgTilemapBufferRect(3, 0, 2, 0, 1, 2, 17); + break; + case 16: + CopyToBgTilemapBufferRect_ChangePalette(3, sCableCar->pylonHookTilemapEntries, 0, 0, 5, 2, 17); + CopyToBgTilemapBufferRect_ChangePalette(3, sCableCar->pylonStemTilemap, 0, 2, 2, 30, 17); + sCableCar->bg3VerticalOffset = 64; + break; + } + } + + sub_815115C(); + gSpriteCoordOffsetX = (gSpriteCoordOffsetX + 1) % 128; +} + +static void sub_8150664(u8 taskId) +{ + if (sCableCar->state != 0xFF) + { + sCableCar->bg3HorizontalOffset++; + if ((sCableCar->timer % 2) == 0) + sCableCar->bg3VerticalOffset++; + + if ((sCableCar->timer % 8) == 0) + { + sCableCar->bg1HorizontalOffset++; + sCableCar->bg1VerticalOffset++; + } + + switch (sCableCar->bg3HorizontalOffset) + { + case 176: + CopyToBgTilemapBufferRect_ChangePalette(3, sCableCar->pylonStemTilemap, 0, 2, 2, 30, 17); + break; + case 16: + FillBgTilemapBufferRect(3, 0, 2, 0, 3, 2, 17); + FillBgTilemapBufferRect(3, 0, 0, 22, 2, 10, 17); + sCableCar->bg3VerticalOffset = 192; + break; + case 32: + FillBgTilemapBufferRect(3, sCableCar->pylonHookTilemapEntries[2], 2, 0, 1, 1, 17); + FillBgTilemapBufferRect(3, sCableCar->pylonHookTilemapEntries[3], 3, 0, 1, 1, 17); + FillBgTilemapBufferRect(3, sCableCar->pylonHookTilemapEntries[7], 2, 1, 1, 1, 17); + FillBgTilemapBufferRect(3, sCableCar->pylonHookTilemapEntries[8], 3, 1, 1, 1, 17); + break; + case 40: + FillBgTilemapBufferRect(3, sCableCar->pylonHookTilemapEntries[4], 4, 0, 1, 1, 17); + FillBgTilemapBufferRect(3, sCableCar->pylonHookTilemapEntries[9], 4, 1, 1, 1, 17); + break; + } + } + + sub_81511B8(); + if (sCableCar->timer < sCableCar->unk4) + gSpriteCoordOffsetX = (gSpriteCoordOffsetX + 247) % 248; + else + gWeatherPtr->unknown_6FC = (gWeatherPtr->unknown_6FC + 247) % 248; +} + +static void CableCarVblankCallback(void) +{ + CopyBgTilemapBufferToVram(0); + CopyBgTilemapBufferToVram(3); + SetGpuReg(REG_OFFSET_BG3HOFS, sCableCar->bg3HorizontalOffset); + SetGpuReg(REG_OFFSET_BG3VOFS, sCableCar->bg3VerticalOffset); + SetGpuReg(REG_OFFSET_BG1HOFS, sCableCar->bg1HorizontalOffset); + SetGpuReg(REG_OFFSET_BG1VOFS, sCableCar->bg1VerticalOffset); + SetGpuReg(REG_OFFSET_BG0HOFS, sCableCar->bg0HorizontalOffset); + SetGpuReg(REG_OFFSET_BG0VOFS, sCableCar->bg0VerticalOffset); + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void nullsub_58(struct Sprite *sprite) +{ +} + +static void sub_8150868(struct Sprite *sprite) +{ + if (sCableCar->state != 0xFF) + { + if (gSpecialVar_0x8004 == 0) + { + sprite->pos1.x = sprite->data[0] - (u8)(0.14f * S16TOPOSFLOAT(sCableCar->timer)); + sprite->pos1.y = sprite->data[1] - (u8)(0.067f * S16TOPOSFLOAT(sCableCar->timer)); + } + else + { + sprite->pos1.x = sprite->data[0] + (u8)(0.14f * S16TOPOSFLOAT(sCableCar->timer)); + sprite->pos1.y = sprite->data[1] + (u8)(0.067f * S16TOPOSFLOAT(sCableCar->timer)); + } + } +} + +void sub_8150948(struct Sprite *sprite) +{ + if (sCableCar->state != 255) + { + if (!gSpecialVar_0x8004) + { + sprite->pos1.x = sprite->data[0] - (u8)(0.14f * S16TOPOSFLOAT(sCableCar->timer)); + sprite->pos1.y = sprite->data[1] - (u8)(0.067f * S16TOPOSFLOAT(sCableCar->timer)); + } + else + { + sprite->pos1.x = sprite->data[0] + (u8)(0.14f * S16TOPOSFLOAT(sCableCar->timer)); + sprite->pos1.y = sprite->data[1] + (u8)(0.067f * S16TOPOSFLOAT(sCableCar->timer)); + } + + switch (sprite->data[2]) + { + case 0: + sprite->pos2.y = 17; + if (sprite->data[3] ++ > 9) + { + sprite->data[3] = 0; + sprite->data[2] ++; + } + break; + default: + sprite->pos2.y = 16; + if (sprite->data[3] ++ > 9) + { + sprite->data[3] = 0; + sprite->data[2] = 0; + } + break; + } + } +} + +static void sub_8150A68(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + sprite->pos1.x += 2 * sprite->centerToCornerVecX; + sprite->pos1.y += 16 + sprite->centerToCornerVecY; + } + + if (++sprite->data[0] >= sprite->data[2]) + { + switch (sprite->data[1]) + { + case 0: + sprite->pos1.x++; + if ((sprite->data[0] % 4) == 0) + sprite->pos1.y++; + break; + case 1: + if ((sprite->data[0] % 2) != 0) + { + sprite->pos1.x++; + if ((sprite->pos1.x % 4) == 0) + sprite->pos1.y++; + } + break; + } + + if (sprite->pos1.y > 160) + DestroySprite(sprite); + } +} + +static void sub_8150AF4(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + sprite->pos1.y += 16 + sprite->centerToCornerVecY; + + if (++sprite->data[0] >= sprite->data[2]) + { + switch (sprite->data[1]) + { + case 0: + sprite->pos1.x--; + if ((sprite->data[0] % 4) == 0) + sprite->pos1.y--; + break; + case 1: + if ((sprite->data[0] % 2) != 0) + { + sprite->pos1.x--; + if ((sprite->pos1.x % 4) == 0) + sprite->pos1.y--; + } + break; + } + + if (sprite->pos1.y < 80) + DestroySprite(sprite); + } +} + +static void sub_8150B6C(bool8 which) +{ + switch (which) + { + case FALSE: + default: + SetGpuReg(REG_OFFSET_WININ, 0); + SetGpuReg(REG_OFFSET_WINOUT, 0); + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN1H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WIN1V, 0); + SetGpuReg(REG_OFFSET_DISPCNT, 0); + SetGpuReg(REG_OFFSET_BG3CNT, 0); + SetGpuReg(REG_OFFSET_BG2CNT, 0); + SetGpuReg(REG_OFFSET_BG1CNT, 0); + SetGpuReg(REG_OFFSET_BG0CNT, 0); + SetGpuReg(REG_OFFSET_BG3HOFS, 0); + SetGpuReg(REG_OFFSET_BG3VOFS, 0); + SetGpuReg(REG_OFFSET_BG2HOFS, 0); + SetGpuReg(REG_OFFSET_BG2VOFS, 0); + SetGpuReg(REG_OFFSET_BG1HOFS, 0); + SetGpuReg(REG_OFFSET_BG1VOFS, 0); + SetGpuReg(REG_OFFSET_BG0HOFS, 0); + SetGpuReg(REG_OFFSET_BG0VOFS, 0); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + break; + case TRUE: + SetGpuReg(REG_OFFSET_WININ, 0); + SetGpuReg(REG_OFFSET_WINOUT, 0); + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN1H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WIN1V, 0); + if (gSpecialVar_0x8004 == 0) + { + sCableCar->bg3HorizontalOffset = 176; + sCableCar->bg3VerticalOffset = 16; + sCableCar->bg1HorizontalOffset = 0; + sCableCar->bg1VerticalOffset = 80; + sCableCar->bg0VerticalOffset = 0; + sCableCar->bg0VerticalOffset = 0; + } + else + { + sCableCar->bg3HorizontalOffset = 96; + sCableCar->bg3VerticalOffset = 232; + sCableCar->bg1HorizontalOffset = 0; + sCableCar->bg1VerticalOffset = 4; + sCableCar->bg0VerticalOffset = 0; + sCableCar->bg0VerticalOffset = 0; + } + + SetGpuReg(REG_OFFSET_BG3HOFS, sCableCar->bg3HorizontalOffset); + SetGpuReg(REG_OFFSET_BG3VOFS, sCableCar->bg3VerticalOffset); + SetGpuReg(REG_OFFSET_BG2HOFS, 0); + SetGpuReg(REG_OFFSET_BG2VOFS, 0); + SetGpuReg(REG_OFFSET_BG1HOFS, sCableCar->bg1HorizontalOffset); + SetGpuReg(REG_OFFSET_BG1VOFS, sCableCar->bg1VerticalOffset); + SetGpuReg(REG_OFFSET_BG0HOFS, sCableCar->bg0HorizontalOffset); + SetGpuReg(REG_OFFSET_BG0VOFS, sCableCar->bg0VerticalOffset); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + CopyBgTilemapBufferToVram(1); + CopyBgTilemapBufferToVram(2); + ShowBg(0); + ShowBg(1); + ShowBg(2); + ShowBg(3); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL); + break; + } +} + +static void LoadCableCarSprites(void) +{ + u8 spriteId; + u8 i; + + u8 playerGraphicsIds[2] = { + EVENT_OBJ_GFX_RIVAL_BRENDAN_NORMAL, + EVENT_OBJ_GFX_RIVAL_MAY_NORMAL + }; + u16 rval = Random(); + u8 hikerGraphicsIds[4] = { + EVENT_OBJ_GFX_HIKER, + EVENT_OBJ_GFX_CAMPER, + EVENT_OBJ_GFX_PICNICKER, + EVENT_OBJ_GFX_ZIGZAGOON_1 + }; + s16 hikerCoords[2][2] = { + { 0, 80 }, + { 240, 146 } + }; + u8 hikerMovementDelayTable[4] = { + 0, + 60, + 120, + 170 + }; + void (*callbacks[2])(struct Sprite *) = { + sub_8150A68, + sub_8150AF4 + }; + + switch (gSpecialVar_0x8004) + { + case 0: + default: + spriteId = AddPseudoEventObject(playerGraphicsIds[gSaveBlock2Ptr->playerGender], sub_8150948, 200, 73, 102); + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].oam.priority = 2; + gSprites[spriteId].pos2.x = 8; + gSprites[spriteId].pos2.y = 16; + gSprites[spriteId].data[0] = 0xc8; + gSprites[spriteId].data[1] = 0x49; + } + spriteId = CreateSprite(&gSpriteTemplate_85CDB9C[0], 176, 43, 0x67); + gSprites[spriteId].pos2.x = gSprites[spriteId].pos2.y = 32; + gSprites[spriteId].data[0] = 176; + gSprites[spriteId].data[1] = 43; + spriteId = CreateSprite(&gSpriteTemplate_85CDB9C[1], 200, 99, 0x65); + gSprites[spriteId].pos2.x = 8; + gSprites[spriteId].pos2.y = 4; + gSprites[spriteId].data[0] = 200; + gSprites[spriteId].data[1] = 99; + sCableCar->weather = WEATHER_ASH; + sCableCar->unk4 = 0x15e; + sub_80AB130(WEATHER_SUNNY); + break; + case 1: + CopyToBgTilemapBufferRect_ChangePalette(0, sCableCar->mtChimneyTilemap + 0x24, 24, 26, 12, 3, 17); + spriteId = AddPseudoEventObject(playerGraphicsIds[gSaveBlock2Ptr->playerGender], sub_8150948, 128, 39, 102); + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].oam.priority = 2; + gSprites[spriteId].pos2.x = 8; + gSprites[spriteId].pos2.y = 16; + gSprites[spriteId].data[0] = 0x80; + gSprites[spriteId].data[1] = 0x27; + } + spriteId = CreateSprite(&gSpriteTemplate_85CDB9C[0], 104, 9, 0x67); + gSprites[spriteId].pos2.x = gSprites[spriteId].pos2.y = 0x20; + gSprites[spriteId].data[0] = 104; + gSprites[spriteId].data[1] = 9; + spriteId = CreateSprite(&gSpriteTemplate_85CDB9C[1], 128, 65, 0x65); + gSprites[spriteId].pos2.x = 8; + gSprites[spriteId].pos2.y = 4; + gSprites[spriteId].data[0] = 0x80; + gSprites[spriteId].data[1] = 0x41; + sCableCar->weather = WEATHER_SUNNY; + sCableCar->unk4 = 0x109; + sub_80AB130(WEATHER_ASH); + break; + } + for (i = 0; i < 9; i++) + { + spriteId = CreateSprite(&gSpriteTemplate_85CDBCC, 16 * i + 96, 8 * i - 8, 0x68); + gSprites[spriteId].pos2.x = 8; + gSprites[spriteId].pos2.y = 8; + } + if ((rval % 64) == 0) + { + spriteId = AddPseudoEventObject(hikerGraphicsIds[rval % 3], callbacks[gSpecialVar_0x8004], hikerCoords[gSpecialVar_0x8004][0], hikerCoords[gSpecialVar_0x8004][1], 0x6a); + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].oam.priority = 2; + gSprites[spriteId].pos2.x = -gSprites[spriteId].centerToCornerVecX; + gSprites[spriteId].pos2.y = -gSprites[spriteId].centerToCornerVecY; + if (gSpecialVar_0x8004 == 0) + { + if (rval % 2) + { + StartSpriteAnim(&gSprites[spriteId], 6); + gSprites[spriteId].data[1] = 1; + gSprites[spriteId].pos1.y += 2; + } + else + { + StartSpriteAnim(&gSprites[spriteId], 7); + gSprites[spriteId].data[1] = 0; + } + } + else + { + if (rval % 2) + { + StartSpriteAnim(&gSprites[spriteId], 7); + gSprites[spriteId].data[1] = 1; + gSprites[spriteId].pos1.y += 2; + } + else + { + StartSpriteAnim(&gSprites[spriteId], 6); + gSprites[spriteId].data[1] = 0; + } + } + gSprites[spriteId].data[2] = hikerMovementDelayTable[rval % 4]; + } + } +} + +void sub_8151088(void) +{ + u8 i; + u8 j; + u8 k; + u8 offset; + + for (i = 0, k = 0, offset = 0x24 * (sCableCar->unk1B + 2); i < 3; i++) + { + for (j = 0; j < 12; j++) + { + sCableCar->unk22[i][j] = sCableCar->mtChimneyTilemap[offset++]; + sCableCar->unk22[i + 3][j] = sCableCar->mtChimneyTilemap[k]; + sCableCar->unk22[i + 6][j] = (sCableCar->mtChimneyTilemap + 0x24)[k]; + k++; + } + } + + sCableCar->unk1B = (sCableCar->unk1B + 1) % 3; +} + +static void sub_815115C(void) +{ + sCableCar->unk1C = (sCableCar->unk1C + 1) % 0x60; + sCableCar->bg0HorizontalOffset = sCableCar->unk1F - sCableCar->unk1D; + sCableCar->bg0VerticalOffset = sCableCar->unk20 - sCableCar->unk1E; + sCableCar->unk1D++; + if ((sCableCar->unk1D % 4) == 0) + sCableCar->unk1E++; + + if (sCableCar->unk1D > 16) + sub_8151214(); +} + +static void sub_81511B8(void) +{ + sCableCar->unk1C = (sCableCar->unk1C + 1) % 0x60; + sCableCar->bg0HorizontalOffset = sCableCar->unk1F + sCableCar->unk1D; + sCableCar->bg0VerticalOffset = sCableCar->unk20 + sCableCar->unk1E; + sCableCar->unk1D++; + if ((sCableCar->unk1D % 4) == 0) + sCableCar->unk1E++; + + if (sCableCar->unk1D > 16) + sub_8151388(); +} + +static void sub_8151214(void) +{ + u8 i = 0; + + sCableCar->unk1D = sCableCar->unk1E = 0; + sCableCar->unk1F = sCableCar->bg0HorizontalOffset; + sCableCar->unk20 = sCableCar->bg0VerticalOffset; + sCableCar->unk19 = (sCableCar->unk19 + 30) % 32; + sCableCar->unk18 -= 2; + gUnknown_0203ABB2 = (sCableCar->unk1A + 23) % 32; + for (i = 0; i < 9; i++) + { + gUnknown_0203ABB0 = sCableCar->unk19; + gUnknown_0203ABB1 = (gUnknown_0203ABB2 + i) % 32; + FillBgTilemapBufferRect(0, sCableCar->unk22[i][sCableCar->unk18], gUnknown_0203ABB0, gUnknown_0203ABB1, 1, 1, 17); + gUnknown_0203ABB0 = (gUnknown_0203ABB0 + 1) % 32; + FillBgTilemapBufferRect(0, sCableCar->unk22[i][sCableCar->unk18 + 1], gUnknown_0203ABB0, gUnknown_0203ABB1, 1, 1, 17); + } + + gUnknown_0203ABB0 = (sCableCar->unk19 + 30) % 32; + FillBgTilemapBufferRect(0, 0, gUnknown_0203ABB0, 0, 2, 32, 17); + if (sCableCar->unk18 == 0) + { + sCableCar->unk1A = (sCableCar->unk1A + 29) % 32; + sCableCar->unk18 = 12; + sub_8151088(); + gUnknown_0203ABB0 = (sCableCar->unk1A + 1) % 32; + FillBgTilemapBufferRect(0, 0, 0, gUnknown_0203ABB0, 32, 9, 17); + } +} + +static void sub_8151388(void) +{ + u8 i = 0; + + sCableCar->unk1D = sCableCar->unk1E = 0; + sCableCar->unk1F = sCableCar->bg0HorizontalOffset; + sCableCar->unk20 = sCableCar->bg0VerticalOffset; + sCableCar->unk19 = (sCableCar->unk19 + 2) % 32; + sCableCar->unk18 += 2; + gUnknown_0203ABB5 = sCableCar->unk1A; + for (i = 0; i < 9; i++) + { + gUnknown_0203ABB3 = sCableCar->unk19; + gUnknown_0203ABB4 = (gUnknown_0203ABB5 + i) % 32; + FillBgTilemapBufferRect(0, sCableCar->unk22[i][sCableCar->unk18], gUnknown_0203ABB3, gUnknown_0203ABB4, 1, 1, 17); + gUnknown_0203ABB3 = (gUnknown_0203ABB3 + 1) % 32; + FillBgTilemapBufferRect(0, sCableCar->unk22[i][sCableCar->unk18 + 1], gUnknown_0203ABB3, gUnknown_0203ABB4, 1, 1, 17); + } + + gUnknown_0203ABB4 = (sCableCar->unk1A + 23) % 32; + FillBgTilemapBufferRect(0, 0, sCableCar->unk19, gUnknown_0203ABB4, 2, 9, 17); + if (sCableCar->unk18 == 10) + { + sCableCar->unk1A = (sCableCar->unk1A + 3) % 32; + sCableCar->unk18 = 0xfe; + sub_8151088(); + } +} + +static void sub_81514C8(u8 arg0) +{ + switch (arg0) + { + case 0: + default: + sCableCar->unk1B = 2; + sCableCar->unk19 = 0; + sCableCar->unk1A = 20; + sCableCar->unk18 = 12; + sub_8151088(); + sub_8151214(); + break; + case 1: + sCableCar->unk1B = 2; + sCableCar->unk19 = 28; + sCableCar->unk1A = 20; + sCableCar->unk18 = 4; + sub_8151088(); + sub_8151388(); + break; + } + + sCableCar->unk1C = 0; +} diff --git a/src/overworld.c b/src/overworld.c index 417c52a9e..6998c9d98 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -147,7 +147,6 @@ extern void ResetAllPicSprites(void); extern void FieldEffectActiveListClear(void); extern void SetUpFieldTasks(void); extern void sub_81BE6B8(void); -extern void StartWeather(void); extern void ShowStartMenu(void); extern void sub_80AEE84(void); extern void mapldr_default(void); |