// Includes #include "global.h" #include "ewram.h" #include "overworld.h" #include "palette.h" #include "random.h" #include "main.h" #include "menu.h" #include "script.h" #include "task.h" #include "sound.h" #include "graphics.h" #include "constants/songs.h" #include "decompress.h" #include "field_weather.h" #include "event_object_movement.h" #include "scanline_effect.h" #include "event_data.h" #include "cable_car_util.h" #include "constants/event_objects.h" #include "constants/weather.h" extern u8 (*gMenuCallback)(void); // Static type declarations struct CableCarEwramStruct1 { u8 unk_0000; u8 unk_0001; u8 unk_0002; u8 unk_0003; u16 unk_0004; u16 unk_0006; u8 unk_0008; u8 unk_0009; u8 filler_000a[2]; u8 unk_000c; u8 unk_000d; u8 filler_0000e[6]; u8 unk_0014; u8 unk_0015; u8 unk_0016; u8 unk_0017; u8 unk_0018; u8 unk_0019; u8 unk_001a; u8 unk_001b; u8 unk_001c; u8 unk_001d; u8 unk_001e; u8 unk_001f; u8 unk_0020; u16 unk_0022[9][12]; u8 filler_00fa[2]; u16 unk_00fc[0x20][0x20]; u16 unk_08fc[0x20][0x20]; }; // size 0x10FC struct CableCarEwramStruct2 { /* 0x000 */ u16 mtChimneyTilemap[0xb4]; /* 0x168 */ u16 treeTilemap[0x1e0]; /* 0x528 */ u16 mountainTilemap[0x258]; /* 0x9d8 */ u16 pylonStemTilemap[0x628]; // size not actually known }; // Static RAM declarations EWRAM_DATA struct CableCarEwramStruct1 *sCableCarPtr = NULL; EWRAM_DATA u8 gUnknown_02039278 = 0; EWRAM_DATA u8 gUnknown_02039279 = 0; EWRAM_DATA u8 gUnknown_0203927A = 0; EWRAM_DATA u8 gUnknown_0203927B = 0; EWRAM_DATA u8 gUnknown_0203927C = 0; EWRAM_DATA u8 gUnknown_0203927D = 0; EWRAM_DATA u32 filler_02039280 = 0; // Static ROM declarations static void CableCarMainCallback_Setup(void); static void CableCarMainCallback_Run(void); static void sub_8123878(u8 taskId); static void sub_81239E4(u8 taskId); static void sub_8123AF8(u8 taskId); static void CableCarVblankCallback(void); static void nullsub_76(struct Sprite *sprite); static void sub_8123CB8(struct Sprite *sprite); static void sub_8123EB8(struct Sprite *sprite); static void sub_8123F44(struct Sprite *sprite); static void sub_8123FBC(u8); static void LoadSprites(void); static void sub_812453C(void); static void sub_8124598(void); static void sub_81245F4(void); static void sub_812476C(void); static void sub_81248AC(u8); // .rodata #if DEBUG void debug_sub_8138D74(void); void debug_sub_8138D8C(void); u8 debug_sub_8138C14(void); u8 debug_sub_8138C34(void); u8 debug_sub_810CD9C(void); const u8 Str_842DBD0[] = _("CABLE CAR U"); const u8 Str_842DBDC[] = _("CABLE CAR D"); const u8 Str_842DBE8[] = _("ROULETTE1"); const u8 Str_842DBF2[] = _("ROULETTE3"); const u8 Str_842DBFC[] = _("View a MAIL"); const struct MenuAction gUnkDebug4Menu[] = { {Str_842DBD0, (u8 (*)(void))debug_sub_8138D74}, // why do these two functions have a different prototype? {Str_842DBDC, (u8 (*)(void))debug_sub_8138D8C}, {Str_842DBE8, debug_sub_8138C14}, {Str_842DBF2, debug_sub_8138C34}, {Str_842DBFC, debug_sub_810CD9C}, }; #endif static const u8 gCableCarMtChimneyTilemap[] = INCBIN_U8("graphics/misc/cable_car_mt_chimney_map.bin.lz"); static const u8 gCableCarTreeTilemap[] = INCBIN_U8("graphics/misc/cable_car_tree_map.bin.lz"); static const u8 gCableCarMountainTilemap[] = INCBIN_U8("graphics/misc/cable_car_mountain_map.bin.lz"); static const u16 gCableCarPylonHookTilemapEntries[] = { 0x3000, 0x3001, 0x3002, 0x3003, 0x3004, 0x3005, 0x3006, 0x3007, 0x3008, 0x3009 }; static const u8 gCableCarPylonStemTilemap[] = INCBIN_U8("graphics/misc/cable_car_pylon_stem_map.bin.lz"); static const struct CompressedSpriteSheet gUnknown_08401CF8[] = { { gCableCar_Gfx, 0x800, 1 }, { gCableCarDoor_Gfx, 0x40, 2 }, { gCableCarCord_Gfx, 0x80, 3 }, { } }; static const struct SpritePalette gUnknown_08401D18[] = { { gCableCar_Pal, 1 }, { } }; static const struct OamData gOamData_8401D28 = { .affineMode = ST_OAM_AFFINE_DOUBLE, .size = 3, .priority = 2 }; static const struct OamData gOamData_8401D30 = { .affineMode = ST_OAM_AFFINE_DOUBLE, .shape = ST_OAM_H_RECTANGLE, .priority = 2 }; static const struct OamData gOamData_8401D38 = { .affineMode = ST_OAM_AFFINE_DOUBLE, .size = 1, .priority = 2 }; static const struct SpriteTemplate gSpriteTemplate_8401D40[] = { { .tileTag = 1, .paletteTag = 1, .oam = &gOamData_8401D28, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_8123CB8, }, { .tileTag = 2, .paletteTag = 1, .oam = &gOamData_8401D30, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_8123CB8, }, { .tileTag = 3, .paletteTag = 1, .oam = &gOamData_8401D38, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = nullsub_76, } }; #if DEBUG extern u8 unk_203955C; extern const u8 MauvilleCity_GameCorner_EventScript_1C407E[]; extern const u8 MauvilleCity_GameCorner_EventScript_1C40AC[]; u8 debug_sub_8138C14(void) { unk_203955C = 1; ScriptContext1_SetupScript(MauvilleCity_GameCorner_EventScript_1C407E); CloseMenu(); return 1; } u8 debug_sub_8138C34(void) { unk_203955C = 1; ScriptContext1_SetupScript(MauvilleCity_GameCorner_EventScript_1C40AC); CloseMenu(); return 1; } u8 debug_sub_8138C54(void) { if (gMain.newKeys == DPAD_UP) Menu_MoveCursor(-1); if (gMain.newKeys == DPAD_DOWN) Menu_MoveCursor(1); if (gMain.newKeys == A_BUTTON) return gUnkDebug4Menu[Menu_GetCursorPos()].func(); if (gMain.newKeys == (R_BUTTON | A_BUTTON)) { gSpecialVar_0x8004 = 1; return gUnkDebug4Menu[Menu_GetCursorPos()].func(); } if (gMain.newKeys == B_BUTTON) { CloseMenu(); return 1; } return 0; } u8 debug_sub_8138CC4(void) { gSpecialVar_0x8004 = 0; Menu_EraseScreen(); Menu_DrawStdWindowFrame(19, 0, 29, 12); Menu_PrintItems(20, 1, 5, gUnkDebug4Menu); InitMenu(0, 20, 1, 5, 0, 8); gMenuCallback = debug_sub_8138C54; return 0; } #endif 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)); } #if DEBUG void debug_sub_8138D74(void) { gSpecialVar_0x8004 = 0; CloseMenu(); CableCar(); } void debug_sub_8138D8C(void) { gSpecialVar_0x8004 = 1; CloseMenu(); CableCar(); } #endif static void CableCarMainCallback_Setup(void) { u8 i; u16 imebak; switch (gMain.state) { case 0: default: SetVBlankCallback(NULL); ScanlineEffect_Stop(); DmaFill16Large(3, 0, VRAM, VRAM_SIZE, 0x1000); DmaFill32Defvars(3, 0, OAM, OAM_SIZE); DmaFill16Defvars(3, 0, PLTT, PLTT_SIZE); sCableCarPtr = eCableCar1; DmaFill16Large(3, 0, eCableCar1, 0x10FC, 0x1000); gMain.state++; break; case 1: ResetSpriteData(); ResetTasks(); FreeAllSpritePalettes(); ResetPaletteFade(); StartWeather(); for (i = 0; i < 20; i++) { gWeatherPtr->sprites.s2.ashSprites[i] = NULL; } InitMapMusic(); ResetMapMusic(); gSpriteCoordOffsetX = gSpriteCoordOffsetY = 0; gMain.state++; break; case 2: for (i = 0; i < 3; i++) { LoadCompressedObjectPic(&gUnknown_08401CF8[i]); } LoadSpritePalettes(gUnknown_08401D18); LZDecompressWram(gCableCarMtChimneyTilemap, eCableCar2->mtChimneyTilemap); LZDecompressWram(gCableCarTreeTilemap, eCableCar2->treeTilemap); LZDecompressWram(gCableCarMountainTilemap, eCableCar2->mountainTilemap); LZDecompressWram(gCableCarPylonStemTilemap, eCableCar2->pylonStemTilemap); LoadPalette(gCableCarBG_Pal, 0, 0x80); LZ77UnCompVram(gCableCarBG_Gfx, (u16 *)BG_VRAM); gMain.state++; break; case 3: LoadSprites(); RunTasks(); gMain.state++; break; case 4: if (sCableCarPtr->unk_0002 == 7) { gMain.state++; } else if (gWeatherPtr->sprites.s2.ashSprites[0] != NULL) { for (i = 0; i < 20; i++) { if (gWeatherPtr->sprites.s2.ashSprites[i] != NULL) { gWeatherPtr->sprites.s2.ashSprites[i]->oam.priority = 0; } } gMain.state++; } break; case 5: CableCarUtil_CopyWrapped((void *)BG_SCREEN_ADDR(29), eCableCar2->treeTilemap, 0, 17, 32, 15); CableCarUtil_CopyWrapped((void *)BG_SCREEN_ADDR(30), eCableCar2->mountainTilemap, 0, 0, 30, 20); CableCarUtil_CopyWrapped(sCableCarPtr->unk_08fc, gCableCarPylonHookTilemapEntries, 0, 0, 5, 2); CableCarUtil_CopyWrapped(sCableCarPtr->unk_08fc, eCableCar2->pylonStemTilemap, 0, 2, 2, 20); gMain.state++; break; case 6: sub_81248AC(gSpecialVar_0x8004); CableCarUtil_CopyWrapped(sCableCarPtr->unk_00fc, eCableCar2->mtChimneyTilemap + 0x48, 0, 14, 12, 3); CableCarUtil_CopyWrapped(sCableCarPtr->unk_00fc, eCableCar2->mtChimneyTilemap + 0x6C, 12, 17, 12, 3); CableCarUtil_CopyWrapped(sCableCarPtr->unk_00fc, eCableCar2->mtChimneyTilemap + 0x90, 24, 20, 12, 3); CableCarUtil_CopyWrapped(sCableCarPtr->unk_00fc, eCableCar2->mtChimneyTilemap + 0x00, 0, 17, 12, 3); CableCarUtil_CopyWrapped(sCableCarPtr->unk_00fc, eCableCar2->mtChimneyTilemap + 0x24, 0, 20, 12, 3); CableCarUtil_CopyWrapped(sCableCarPtr->unk_00fc, eCableCar2->mtChimneyTilemap + 0x00, 12, 20, 12, 3); CableCarUtil_CopyWrapped(sCableCarPtr->unk_00fc, eCableCar2->mtChimneyTilemap + 0x24, 12, 23, 12, 3); CableCarUtil_CopyWrapped(sCableCarPtr->unk_00fc, eCableCar2->mtChimneyTilemap + 0x00, 24, 23, 12, 3); gMain.state++; break; case 7: BeginNormalPaletteFade(0xFFFFFFFF, 3, 16, 0, RGB(0, 0, 0)); FadeInNewBGM(MUS_CABLE_CAR, 1); sub_8123FBC(1); gMain.state++; break; case 8: imebak = REG_IME; REG_IME = 0; REG_IE |= INTR_FLAG_VBLANK; REG_IME = imebak; SetVBlankCallback(CableCarVblankCallback); SetMainCallback2(CableCarMainCallback_Run); CreateTask(sub_8123878, 0); if (gSpecialVar_0x8004 == 0) { sCableCarPtr->unk_0000 = CreateTask(sub_81239E4, 1); } else { sCableCarPtr->unk_0000 = CreateTask(sub_8123AF8, 1); } break; } } static void CableCarMainCallback_Run(void) { RunTasks(); AnimateSprites(); BuildOamBuffer(); UpdatePaletteFade(); MapMusicMain(); } static void sub_8123740(void) { u8 i; i = 0; sub_8123FBC(0); gSpriteCoordOffsetX = 0; sub_807C9B4(WEATHER_NONE); for (; i < 20; i++) { gWeatherPtr->sprites.s2.ashSprites[i] = NULL; } ResetTasks(); ResetSpriteData(); ResetPaletteFade(); DmaFill32Large(3, 0, gSharedMem, 0x20000, 0x1000); sCableCarPtr = NULL; DmaFill16Large(3, 0, VRAM, VRAM_SIZE, 0x1000); DmaFill32Defvars(3, 0, OAM, OAM_SIZE); DmaFill16Defvars(3, 0, PLTT, PLTT_SIZE); WarpIntoMap(); gFieldCallback = NULL; SetMainCallback2(CB2_LoadMap); } static void sub_8123878(u8 taskId) { u8 i; i = 0; sCableCarPtr->unk_0006++; switch (sCableCarPtr->unk_0001) { case 0: if (sCableCarPtr->unk_0006 == sCableCarPtr->unk_0004) { ChangeWeather(sCableCarPtr->unk_0002); sCableCarPtr->unk_0001 = 1; } break; case 1: switch (sCableCarPtr->unk_0002) { case 7: 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; } } sCableCarPtr->unk_0001 = 2; } break; case 2: if (gWeatherPtr->currWeather == 2) { sCableCarPtr->unk_0001 = 2; } else if (sCableCarPtr->unk_0006 >= sCableCarPtr->unk_0004 + 8) { for (; i < 20; i++) { if (gWeatherPtr->sprites.s2.ashSprites[i] != NULL) { gWeatherPtr->sprites.s2.ashSprites[i]->invisible ^= TRUE; } } } break; } break; case 2: if (sCableCarPtr->unk_0006 == 570) { sCableCarPtr->unk_0001 = 3; BeginNormalPaletteFade(0xFFFFFFFF, 3, 0, 16, RGB(0, 0, 0)); FadeOutBGM(4); } break; case 3: if (!gPaletteFade.active) { sCableCarPtr->unk_0001 = 255; } break; case 255: SetVBlankCallback(NULL); DestroyTask(taskId); DestroyTask(sCableCarPtr->unk_0000); SetMainCallback2(sub_8123740); break; } } static void sub_81239E4(u8 taskId) { if (sCableCarPtr->unk_0001 != 255) { sCableCarPtr->unk_0014--; if ((sCableCarPtr->unk_0006 % 2) == 0) { sCableCarPtr->unk_0015--; } if ((sCableCarPtr->unk_0006 % 8) == 0) { sCableCarPtr->unk_000c--; sCableCarPtr->unk_000d--; } switch (sCableCarPtr->unk_0014) { case 175: CableCarUtil_FillWrapped(sCableCarPtr->unk_08fc, 0, 0, 22, 2, 10); break; case 40: CableCarUtil_FillWrapped(sCableCarPtr->unk_08fc, 0, 3, 0, 2, 2); break; case 32: CableCarUtil_FillWrapped(sCableCarPtr->unk_08fc, 0, 2, 0, 1, 2); break; case 16: CableCarUtil_CopyWrapped(sCableCarPtr->unk_08fc, gCableCarPylonHookTilemapEntries, 0, 0, 5, 2); CableCarUtil_CopyWrapped(sCableCarPtr->unk_08fc, eCableCar2->pylonStemTilemap, 0, 2, 2, 30); sCableCarPtr->unk_0015 = 64; break; } } sub_812453C(); gSpriteCoordOffsetX = (gSpriteCoordOffsetX + 1) % 128; } static void sub_8123AF8(u8 taskId) { if (sCableCarPtr->unk_0001 != 255) { sCableCarPtr->unk_0014++; if ((sCableCarPtr->unk_0006 % 2) == 0) { sCableCarPtr->unk_0015++; } if ((sCableCarPtr->unk_0006 % 8) == 0) { sCableCarPtr->unk_000c++; sCableCarPtr->unk_000d++; } switch (sCableCarPtr->unk_0014) { case 176: CableCarUtil_CopyWrapped(sCableCarPtr->unk_08fc, eCableCar2->pylonStemTilemap, 0, 2, 2, 30); break; case 16: CableCarUtil_FillWrapped(sCableCarPtr->unk_08fc, 0, 2, 0, 3, 2); CableCarUtil_FillWrapped(sCableCarPtr->unk_08fc, 0, 0, 22, 2, 10); sCableCarPtr->unk_0015 = 192; break; case 32: sCableCarPtr->unk_08fc[0][2] = (gCableCarPylonHookTilemapEntries + 2)[0]; sCableCarPtr->unk_08fc[0][3] = (gCableCarPylonHookTilemapEntries + 2)[1]; sCableCarPtr->unk_08fc[1][2] = (gCableCarPylonHookTilemapEntries + 2)[5]; sCableCarPtr->unk_08fc[1][3] = (gCableCarPylonHookTilemapEntries + 2)[6]; break; case 40: sCableCarPtr->unk_08fc[0][4] = (gCableCarPylonHookTilemapEntries + 4)[0]; sCableCarPtr->unk_08fc[1][4] = (gCableCarPylonHookTilemapEntries + 4)[5]; break; } } sub_8124598(); if (sCableCarPtr->unk_0006 < sCableCarPtr->unk_0004) { gSpriteCoordOffsetX = (gSpriteCoordOffsetX + 247) % 248; } else { gWeatherPtr->unknown_6FC = (gWeatherPtr->unknown_6FC + 247) % 248; } } static void CableCarVblankCallback(void) { DmaCopy16(3, sCableCarPtr->unk_00fc, BG_SCREEN_ADDR(28), 0x800); DmaCopy16(3, sCableCarPtr->unk_08fc, BG_SCREEN_ADDR(31), 0x800); REG_BG3HOFS = sCableCarPtr->unk_0014; REG_BG3VOFS = sCableCarPtr->unk_0015; REG_BG1HOFS = sCableCarPtr->unk_000c; REG_BG1VOFS = sCableCarPtr->unk_000d; REG_BG0HOFS = sCableCarPtr->unk_0008; REG_BG0VOFS = sCableCarPtr->unk_0009; LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); } static void nullsub_76(struct Sprite *sprite) { } static void sub_8123CB8(struct Sprite *sprite) { if (sCableCarPtr->unk_0001 != 255) { if (gSpecialVar_0x8004 == 0) { sprite->x = sprite->data[0] - (u8)(0.14f * S16TOPOSFLOAT(sCableCarPtr->unk_0006)); sprite->y = sprite->data[1] - (u8)(0.067f * S16TOPOSFLOAT(sCableCarPtr->unk_0006)); } else { sprite->x = sprite->data[0] + (u8)(0.14f * S16TOPOSFLOAT(sCableCarPtr->unk_0006)); sprite->y = sprite->data[1] + (u8)(0.067f * S16TOPOSFLOAT(sCableCarPtr->unk_0006)); } } } static void sub_8123D98(struct Sprite *sprite) { if (sCableCarPtr->unk_0001 != 255) { if (gSpecialVar_0x8004 == 0) { sprite->x = sprite->data[0] - (u8)(0.14f * S16TOPOSFLOAT(sCableCarPtr->unk_0006)); sprite->y = sprite->data[1] - (u8)(0.067f * S16TOPOSFLOAT(sCableCarPtr->unk_0006)); } else { sprite->x = sprite->data[0] + (u8)(0.14f * S16TOPOSFLOAT(sCableCarPtr->unk_0006)); sprite->y = sprite->data[1] + (u8)(0.067f * S16TOPOSFLOAT(sCableCarPtr->unk_0006)); } switch (sprite->data[2]) { case 0: sprite->y2 = 17; if (sprite->data[3] ++ > 9) { sprite->data[3] = 0; sprite->data[2] ++; } break; default: sprite->y2 = 16; if (sprite->data[3] ++ > 9) { sprite->data[3] = 0; sprite->data[2] = 0; } break; } } } static void sub_8123EB8(struct Sprite *sprite) { if (sprite->data[0] == 0) { sprite->x += 2 * sprite->centerToCornerVecX; sprite->y += 16 + sprite->centerToCornerVecY; } if (++sprite->data[0] >= sprite->data[2]) { switch (sprite->data[1]) { case 0: sprite->x++; if ((sprite->data[0] % 4) == 0) { sprite->y++; } break; case 1: if ((sprite->data[0] % 2) != 0) { sprite->x++; if ((sprite->x % 4) == 0) { sprite->y++; } } break; } if (sprite->y > 0xa0) { DestroySprite(sprite); } } } static void sub_8123F44(struct Sprite *sprite) { if (sprite->data[0] == 0) { sprite->y += 16 + sprite->centerToCornerVecY; } if (++sprite->data[0] >= sprite->data[2]) { switch (sprite->data[1]) { case 0: sprite->x--; if ((sprite->data[0] % 4) == 0) { sprite->y--; } break; case 1: if ((sprite->data[0] % 2) != 0) { sprite->x--; if ((sprite->x % 4) == 0) { sprite->y--; } } break; } if (sprite->y < 0x50) { DestroySprite(sprite); } } } static void sub_8123FBC(bool8 which) { switch (which) { case FALSE: default: REG_WININ = 0; REG_WINOUT = 0; REG_WIN0H = 0; REG_WIN1H = 0; REG_WIN0V = 0; REG_WIN1V = 0; REG_DISPCNT = 0; REG_BG3CNT = 0; REG_BG2CNT = 0; REG_BG1CNT = 0; REG_BG0CNT = 0; REG_BG3HOFS = 0; REG_BG3VOFS = 0; REG_BG2HOFS = 0; REG_BG2VOFS = 0; REG_BG1HOFS = 0; REG_BG1VOFS = 0; REG_BG0HOFS = 0; REG_BG0VOFS = 0; REG_BLDCNT = 0; break; case TRUE: REG_WININ = 0; REG_WINOUT = 0; REG_WIN0H = 0; REG_WIN1H = 0; REG_WIN0V = 0; REG_WIN1V = 0; if (gSpecialVar_0x8004 == 0) { sCableCarPtr->unk_0014 = 0xb0; sCableCarPtr->unk_0015 = 0x10; sCableCarPtr->unk_000c = 0x00; sCableCarPtr->unk_000d = 0x50; sCableCarPtr->unk_0009 = 0; sCableCarPtr->unk_0009 = 0; } else { sCableCarPtr->unk_0014 = 0x60; sCableCarPtr->unk_0015 = 0xe8; sCableCarPtr->unk_000c = 0x00; sCableCarPtr->unk_000d = 0x04; sCableCarPtr->unk_0009 = 0; sCableCarPtr->unk_0009 = 0; } REG_BG3HOFS = sCableCarPtr->unk_0014; REG_BG3VOFS = sCableCarPtr->unk_0015; REG_BG2HOFS = 0; REG_BG2VOFS = 0; REG_BG1HOFS = sCableCarPtr->unk_000c; REG_BG1VOFS = sCableCarPtr->unk_000d; REG_BG0HOFS = sCableCarPtr->unk_0008; REG_BG0VOFS = sCableCarPtr->unk_0009; REG_BG0CNT = BGCNT_PRIORITY(1) | BGCNT_SCREENBASE(28) | BGCNT_WRAP; REG_BG1CNT = BGCNT_PRIORITY(2) | BGCNT_SCREENBASE(29) | BGCNT_WRAP; REG_BG2CNT = BGCNT_PRIORITY(3) | BGCNT_SCREENBASE(30) | BGCNT_WRAP; REG_BG3CNT = BGCNT_PRIORITY(0) | BGCNT_SCREENBASE(31) | BGCNT_WRAP; REG_DISPCNT = DISPCNT_OBJ_1D_MAP | DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON; REG_BLDCNT = 0x3f00; break; } } static void LoadSprites(void) { u8 spriteId; u8 i; u8 playerGraphicsIds[2] = { OBJ_EVENT_GFX_RIVAL_BRENDAN_NORMAL, OBJ_EVENT_GFX_RIVAL_MAY_NORMAL }; u16 rval = Random(); u8 hikerGraphicsIds[4] = { OBJ_EVENT_GFX_HIKER, OBJ_EVENT_GFX_CAMPER, OBJ_EVENT_GFX_PICNICKER, OBJ_EVENT_GFX_POOCHYENA }; s16 hikerCoords[2][2] = { { 0, 80 }, { 240, 146 } }; u8 hikerMovementDelayTable[4] = { 0, 60, 120, 170 }; void (*callbacks[2])(struct Sprite *) = { sub_8123EB8, sub_8123F44 }; switch (gSpecialVar_0x8004) { case 0: default: spriteId = AddPseudoObjectEvent(playerGraphicsIds[gSaveBlock2.playerGender], sub_8123D98, 0xc8, 0x49, 0x66); if (spriteId != MAX_SPRITES) { gSprites[spriteId].oam.priority = 2; gSprites[spriteId].x2 = 0x08; gSprites[spriteId].y2 = 0x10; gSprites[spriteId].data[0] = 0xc8; gSprites[spriteId].data[1] = 0x49; } spriteId = CreateSprite(&gSpriteTemplate_8401D40[0], 0xb0, 0x2b, 0x67); gSprites[spriteId].x2 = gSprites[spriteId].y2 = 0x20; gSprites[spriteId].data[0] = 0xb0; gSprites[spriteId].data[1] = 0x2b; spriteId = CreateSprite(&gSpriteTemplate_8401D40[1], 0xc8, 0x63, 0x65); gSprites[spriteId].x2 = 8; gSprites[spriteId].y2 = 4; gSprites[spriteId].data[0] = 0xc8; gSprites[spriteId].data[1] = 0x63; sCableCarPtr->unk_0002 = 7; sCableCarPtr->unk_0004 = 0x15e; sub_807C9B4(WEATHER_SUNNY); break; case 1: CableCarUtil_CopyWrapped(sCableCarPtr->unk_00fc, eCableCar2->mtChimneyTilemap + 0x24, 0x18, 0x1a, 0x0c, 0x03); spriteId = AddPseudoObjectEvent(playerGraphicsIds[gSaveBlock2.playerGender], sub_8123D98, 0x80, 0x27, 0x66); if (spriteId != MAX_SPRITES) { gSprites[spriteId].oam.priority = 2; gSprites[spriteId].x2 = 0x08; gSprites[spriteId].y2 = 0x10; gSprites[spriteId].data[0] = 0x80; gSprites[spriteId].data[1] = 0x27; } spriteId = CreateSprite(&gSpriteTemplate_8401D40[0], 0x68, 0x09, 0x67); gSprites[spriteId].x2 = gSprites[spriteId].y2 = 0x20; gSprites[spriteId].data[0] = 0x68; gSprites[spriteId].data[1] = 0x09; spriteId = CreateSprite(&gSpriteTemplate_8401D40[1], 0x80, 0x41, 0x65); gSprites[spriteId].x2 = 8; gSprites[spriteId].y2 = 4; gSprites[spriteId].data[0] = 0x80; gSprites[spriteId].data[1] = 0x41; sCableCarPtr->unk_0002 = 2; sCableCarPtr->unk_0004 = 0x109; sub_807C9B4(WEATHER_ASH); break; } for (i = 0; i < 9; i++) { spriteId = CreateSprite(&gSpriteTemplate_8401D40[2], 16 * i + 0x60, 8 * i - 8, 0x68); gSprites[spriteId].x2 = 8; gSprites[spriteId].y2 = 8; } if ((rval % 64) == 0) { spriteId = AddPseudoObjectEvent(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].x2 = -gSprites[spriteId].centerToCornerVecX; gSprites[spriteId].y2 = -gSprites[spriteId].centerToCornerVecY; if (gSpecialVar_0x8004 == 0) { if (rval % 2) { StartSpriteAnim(&gSprites[spriteId], 6); gSprites[spriteId].data[1] = 1; gSprites[spriteId].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].y += 2; } else { StartSpriteAnim(&gSprites[spriteId], 6); gSprites[spriteId].data[1] = 0; } } gSprites[spriteId].data[2] = hikerMovementDelayTable[rval % 4]; } } } static void sub_812446C(void) { u8 i; u8 j; u8 k; u8 offset; for (i = 0, k = 0, offset = 0x24 * (sCableCarPtr->unk_001b + 2); i < 3; i++) { for (j = 0; j < 12; j++) { sCableCarPtr->unk_0022[i][j] = *(eCableCar2->mtChimneyTilemap + (offset++)); sCableCarPtr->unk_0022[i + 3][j] = eCableCar2->mtChimneyTilemap[k]; sCableCarPtr->unk_0022[i + 6][j] = (eCableCar2->mtChimneyTilemap + 0x24)[k]; k++; } } sCableCarPtr->unk_001b = (sCableCarPtr->unk_001b + 1) % 3; } static void sub_812453C(void) { sCableCarPtr->unk_001c = (sCableCarPtr->unk_001c + 1) % 0x60; sCableCarPtr->unk_0008 = sCableCarPtr->unk_001f - sCableCarPtr->unk_001d; sCableCarPtr->unk_0009 = sCableCarPtr->unk_0020 - sCableCarPtr->unk_001e; sCableCarPtr->unk_001d++; if ((sCableCarPtr->unk_001d % 4) == 0) { sCableCarPtr->unk_001e++; } if (sCableCarPtr->unk_001d > 16) { sub_81245F4(); } } static void sub_8124598(void) { sCableCarPtr->unk_001c = (sCableCarPtr->unk_001c + 1) % 0x60; sCableCarPtr->unk_0008 = sCableCarPtr->unk_001f + sCableCarPtr->unk_001d; sCableCarPtr->unk_0009 = sCableCarPtr->unk_0020 + sCableCarPtr->unk_001e; sCableCarPtr->unk_001d++; if ((sCableCarPtr->unk_001d % 4) == 0) { sCableCarPtr->unk_001e++; } if (sCableCarPtr->unk_001d > 16) { sub_812476C(); } } static void sub_81245F4(void) { u8 i = 0; sCableCarPtr->unk_001d = sCableCarPtr->unk_001e = 0; sCableCarPtr->unk_001f = sCableCarPtr->unk_0008; sCableCarPtr->unk_0020 = sCableCarPtr->unk_0009; sCableCarPtr->unk_0019 = (sCableCarPtr->unk_0019 + 30) % 32; sCableCarPtr->unk_0018 -= 2; gUnknown_0203927A = (sCableCarPtr->unk_001a + 23) % 32; for (i = 0; i < 9; i++) { gUnknown_02039278 = sCableCarPtr->unk_0019; gUnknown_02039279 = (gUnknown_0203927A + i) % 32; sCableCarPtr->unk_00fc[gUnknown_02039279][gUnknown_02039278] = sCableCarPtr->unk_0022[i][sCableCarPtr->unk_0018]; gUnknown_02039278 = (gUnknown_02039278 + 1) % 32; sCableCarPtr->unk_00fc[gUnknown_02039279][gUnknown_02039278] = sCableCarPtr->unk_0022[i][sCableCarPtr->unk_0018 + 1]; } gUnknown_02039278 = (sCableCarPtr->unk_0019 + 30) % 32; CableCarUtil_FillWrapped(sCableCarPtr->unk_00fc, 0, gUnknown_02039278, 0, 2, 32); if (sCableCarPtr->unk_0018 == 0) { sCableCarPtr->unk_001a = (sCableCarPtr->unk_001a + 29) % 32; sCableCarPtr->unk_0018 = 12; sub_812446C(); gUnknown_02039278 = (sCableCarPtr->unk_001a + 1) % 32; CableCarUtil_FillWrapped(sCableCarPtr->unk_00fc, 0, 0, gUnknown_02039278, 32, 9); } } static void sub_812476C(void) { u8 i = 0; sCableCarPtr->unk_001d = sCableCarPtr->unk_001e = 0; sCableCarPtr->unk_001f = sCableCarPtr->unk_0008; sCableCarPtr->unk_0020 = sCableCarPtr->unk_0009; sCableCarPtr->unk_0019 = (sCableCarPtr->unk_0019 + 2) % 32; sCableCarPtr->unk_0018 += 2; gUnknown_0203927D = sCableCarPtr->unk_001a; for (i = 0; i < 9; i++) { gUnknown_0203927B = sCableCarPtr->unk_0019; gUnknown_0203927C = (gUnknown_0203927D + i) % 32; sCableCarPtr->unk_00fc[gUnknown_0203927C][gUnknown_0203927B] = sCableCarPtr->unk_0022[i][sCableCarPtr->unk_0018]; gUnknown_0203927B = (gUnknown_0203927B + 1) % 32; sCableCarPtr->unk_00fc[gUnknown_0203927C][gUnknown_0203927B] = sCableCarPtr->unk_0022[i][sCableCarPtr->unk_0018 + 1]; } gUnknown_0203927C = (sCableCarPtr->unk_001a + 23) % 32; CableCarUtil_FillWrapped(sCableCarPtr->unk_00fc, 0, sCableCarPtr->unk_0019, gUnknown_0203927C, 2, 9); if (sCableCarPtr->unk_0018 == 10) { sCableCarPtr->unk_001a = (sCableCarPtr->unk_001a + 3) % 32; sCableCarPtr->unk_0018 = 0xfe; sub_812446C(); } } static void sub_81248AC(u8 a0) { switch (a0) { case 0: default: sCableCarPtr->unk_001b = 2; sCableCarPtr->unk_0019 = 0; sCableCarPtr->unk_001a = 20; sCableCarPtr->unk_0018 = 12; sub_812446C(); sub_81245F4(); break; case 1: sCableCarPtr->unk_001b = 2; sCableCarPtr->unk_0019 = 28; sCableCarPtr->unk_001a = 20; sCableCarPtr->unk_0018 = 4; sub_812446C(); sub_812476C(); break; } sCableCarPtr->unk_001c = 0; }