diff options
Diffstat (limited to 'src/wallclock.c')
-rw-r--r-- | src/wallclock.c | 1046 |
1 files changed, 1046 insertions, 0 deletions
diff --git a/src/wallclock.c b/src/wallclock.c new file mode 100644 index 000000000..1f743a61a --- /dev/null +++ b/src/wallclock.c @@ -0,0 +1,1046 @@ +#include "global.h" +#include "wallclock.h" +#include "decompress.h" +#include "main.h" +#include "menu.h" +#include "palette.h" +#include "rtc.h" +#include "constants/songs.h" +#include "sound.h" +#include "strings2.h" +#include "task.h" +#include "trig.h" +#include "scanline_effect.h" + +extern u16 gSpecialVar_0x8004; +extern u8 gMiscClock_Gfx[]; +extern u8 gUnknown_08E95774[]; +extern u8 gUnknown_08E954B0[]; +extern u16 gMiscClockMale_Pal[]; +extern u16 gMiscClockFemale_Pal[]; + +//-------------------------------------------------- +// Graphics Data +//-------------------------------------------------- + +static const u8 ClockGfx_Misc[] = INCBIN_U8("graphics/misc/clock_misc.4bpp.lz"); +static const struct CompressedSpriteSheet gUnknown_083F7A90[] = +{ + {ClockGfx_Misc, 0x2000, 0x1000}, + {NULL}, +}; +static const struct SpritePalette gUnknown_083F7AA0[] = +{ + {gMiscClockMale_Pal, 0x1000}, + {gMiscClockFemale_Pal, 0x1001}, + {NULL}, +}; +static const struct OamData gOamData_83F7AB8 = +{ + .y = 160, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 3, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, +}; +static const union AnimCmd gSpriteAnim_83F7AC0[] = +{ + ANIMCMD_FRAME(0, 30), + ANIMCMD_END, +}; +static const union AnimCmd gSpriteAnim_83F7AC8[] = +{ + ANIMCMD_FRAME(64, 30), + ANIMCMD_END, +}; +static const union AnimCmd *const gSpriteAnimTable_83F7AD0[] = +{ + gSpriteAnim_83F7AC0, +}; +static const union AnimCmd *const gSpriteAnimTable_83F7AD4[] = +{ + gSpriteAnim_83F7AC8, +}; +static void sub_810B05C(struct Sprite *sprite); +static const struct SpriteTemplate gSpriteTemplate_83F7AD8 = +{ + .tileTag = 0x1000, + .paletteTag = 0x1000, + .oam = &gOamData_83F7AB8, + .anims = gSpriteAnimTable_83F7AD0, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_810B05C, +}; +static void sub_810B0F4(struct Sprite *sprite); +static const struct SpriteTemplate gSpriteTemplate_83F7AF0 = +{ + .tileTag = 0x1000, + .paletteTag = 0x1000, + .oam = &gOamData_83F7AB8, + .anims = gSpriteAnimTable_83F7AD4, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_810B0F4, +}; +static const struct OamData gOamData_83F7B08 = +{ + .y = 160, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 1, + .tileNum = 0, + .priority = 2, + .paletteNum = 0, + .affineParam = 0, +}; +static const union AnimCmd gSpriteAnim_83F7B10[] = +{ + ANIMCMD_FRAME(132, 30), + ANIMCMD_END, +}; +static const union AnimCmd gSpriteAnim_83F7B18[] = +{ + ANIMCMD_FRAME(128, 30), + ANIMCMD_END, +}; +static const union AnimCmd *const gSpriteAnimTable_83F7B20[] = +{ + gSpriteAnim_83F7B10, +}; +static const union AnimCmd *const gSpriteAnimTable_83F7B24[] = +{ + gSpriteAnim_83F7B18, +}; +static void sub_810B18C(struct Sprite *sprite); +static const struct SpriteTemplate gSpriteTemplate_83F7B28 = +{ + .tileTag = 0x1000, + .paletteTag = 0x1000, + .oam = &gOamData_83F7B08, + .anims = gSpriteAnimTable_83F7B20, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_810B18C, +}; +static void sub_810B230(struct Sprite *sprite); +static const struct SpriteTemplate gSpriteTemplate_83F7B40 = +{ + .tileTag = 0x1000, + .paletteTag = 0x1000, + .oam = &gOamData_83F7B08, + .anims = gSpriteAnimTable_83F7B24, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_810B230, +}; + +static void WallClockVblankCallback(void); +static void LoadWallClockGraphics(void); +static void WallClockMainCallback(void); +static void WallClockInit(void); +static void Task_SetClock1(u8 taskId); +static void Task_SetClock2(u8 taskId); +static void Task_SetClock3(u8 taskId); +static void Task_SetClock4(u8 taskId); +static void Task_SetClock5(u8 taskId); +static void Task_SetClock6(u8 taskId); +static void Task_ViewClock1(u8 taskId); +static void Task_ViewClock2(u8 taskId); +static void Task_ViewClock3(u8 taskId); +static void Task_ViewClock4(u8 taskId); +static u8 CalcMinHandDelta(u16 speed); +static u16 CalcNewMinHandAngle(u16 angle, u8 direction, u8 speed); +static u8 AdvanceClock(u8 taskId, u8 direction); +static void UpdateClockPeriod(u8 taskId, u8 direction); +static void InitClockWithRtc(u8 taskId); + +enum +{ + PERIOD_AM, + PERIOD_PM, +}; + +enum +{ + MVMT_NONE, + MVMT_BACKWARD, + MVMT_FORWARD, +}; + +static void WallClockVblankCallback(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void LoadWallClockGraphics(void) +{ + SetVBlankCallback(NULL); + 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; + + DmaFill16Large(3, 0, (void *)(VRAM + 0x0), 0x18000, 0x1000); + DmaClear32(3, OAM, OAM_SIZE); + DmaClear16(3, PLTT, PLTT_SIZE); + + LZ77UnCompVram(gMiscClock_Gfx, (void *)VRAM); + if (gSpecialVar_0x8004 == MALE) + LoadPalette(gMiscClockMale_Pal, 0, 32); + else + LoadPalette(gMiscClockFemale_Pal, 0, 32); + ScanlineEffect_Stop(); + ResetTasks(); + ResetSpriteData(); + ResetPaletteFade(); + FreeAllSpritePalettes(); + LoadCompressedObjectPic(&gUnknown_083F7A90[0]); + LoadSpritePalettes(gUnknown_083F7AA0); + Text_LoadWindowTemplate(&gWindowTemplate_81E6C3C); + InitMenuWindow(&gWindowTemplate_81E6CE4); +} + +static void WallClockInit(void) +{ + u16 ime; + + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); + ime = REG_IME; + REG_IME = 0; + REG_IE |= INTR_FLAG_VBLANK; + REG_IME = ime; + REG_DISPSTAT |= DISPSTAT_VBLANK_INTR; + SetVBlankCallback(WallClockVblankCallback); + SetMainCallback2(WallClockMainCallback); + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + REG_BLDY = 0; + REG_BG3CNT = BGCNT_PRIORITY(1) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(7) | BGCNT_16COLOR | BGCNT_TXT256x256; + REG_BG0CNT = BGCNT_PRIORITY(0) | BGCNT_CHARBASE(2) | BGCNT_SCREENBASE(31) | BGCNT_16COLOR | BGCNT_TXT256x256; + REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | + DISPCNT_BG3_ON | DISPCNT_OBJ_ON; +} + +#define tMinuteHandAngle data[0] +#define tHourHandAngle data[1] +#define tHours data[2] +#define tMinutes data[3] +#define tMvmtDir data[4] +#define tPeriod data[5] +#define tMvmtSpeed data[6] + +//Allow player to set the clock +void CB2_StartWallClock(void) +{ + u8 taskId; + u8 spriteId; + + LoadWallClockGraphics(); + LZ77UnCompVram(&gUnknown_08E954B0, (void *)(VRAM + 0x3800)); + + taskId = CreateTask(Task_SetClock1, 0); + gTasks[taskId].tHours = 10; + gTasks[taskId].tMinutes = 0; + gTasks[taskId].tMvmtDir = MVMT_NONE; + gTasks[taskId].tPeriod = PERIOD_AM; + gTasks[taskId].tMvmtSpeed = 0; + gTasks[taskId].tMinuteHandAngle = 0; + gTasks[taskId].tHourHandAngle = 300; + + spriteId = CreateSprite(&gSpriteTemplate_83F7AD8, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, 1); + gSprites[spriteId].data[0] = taskId; + gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL; + gSprites[spriteId].oam.matrixNum = 0; + + spriteId = CreateSprite(&gSpriteTemplate_83F7AF0, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, 0); + gSprites[spriteId].data[0] = taskId; + gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL; + gSprites[spriteId].oam.matrixNum = 1; + + spriteId = CreateSprite(&gSpriteTemplate_83F7B28, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, 2); + gSprites[spriteId].data[0] = taskId; + gSprites[spriteId].data[1] = 45; + + spriteId = CreateSprite(&gSpriteTemplate_83F7B40, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, 2); + gSprites[spriteId].data[0] = taskId; + gSprites[spriteId].data[1] = 90; + + WallClockInit(); +} + +//View, but don't set, the clock +void CB2_ViewWallClock(void) +{ + u8 taskId; + s16 angle1; + s16 angle2; + u8 spriteId; + + LoadWallClockGraphics(); + LZ77UnCompVram(gUnknown_08E95774, (void *)(VRAM + 0x3800)); + + taskId = CreateTask(Task_ViewClock1, 0); + InitClockWithRtc(taskId); + if (gTasks[taskId].tPeriod == PERIOD_AM) + { + angle1 = 45; + angle2 = 90; + } + else + { + angle1 = 90; + angle2 = 135; + } + + spriteId = CreateSprite(&gSpriteTemplate_83F7AD8, 120, 80, 1); + gSprites[spriteId].data[0] = taskId; + gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL; + gSprites[spriteId].oam.matrixNum = 0; + + spriteId = CreateSprite(&gSpriteTemplate_83F7AF0, 120, 80, 0); + gSprites[spriteId].data[0] = taskId; + gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL; + gSprites[spriteId].oam.matrixNum = 1; + + spriteId = CreateSprite(&gSpriteTemplate_83F7B28, 120, 80, 2); + gSprites[spriteId].data[0] = taskId; + gSprites[spriteId].data[1] = angle1; + + spriteId = CreateSprite(&gSpriteTemplate_83F7B40, 120, 80, 2); + gSprites[spriteId].data[0] = taskId; + gSprites[spriteId].data[1] = angle2; + + WallClockInit(); +} + +static void WallClockMainCallback(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static void Task_SetClock1(u8 taskId) +{ + if (!gPaletteFade.active) + gTasks[taskId].func = Task_SetClock2; +} + +//Handle keypresses when setting clock +static void Task_SetClock2(u8 taskId) +{ + if (gTasks[taskId].tMinuteHandAngle % 6) + { + gTasks[taskId].tMinuteHandAngle = CalcNewMinHandAngle( + gTasks[taskId].tMinuteHandAngle, + gTasks[taskId].tMvmtDir, + gTasks[taskId].tMvmtSpeed); + } + else + { + gTasks[taskId].tMinuteHandAngle = gTasks[taskId].tMinutes * 6; + gTasks[taskId].tHourHandAngle = (gTasks[taskId].tHours % 12) * 30 + (gTasks[taskId].tMinutes / 10) * 5; + if (gMain.newKeys & A_BUTTON) + { + gTasks[taskId].func = Task_SetClock3; + return; + } + else + { + gTasks[taskId].tMvmtDir = gMain.newKeys & A_BUTTON; + if (gMain.heldKeys & DPAD_LEFT) + gTasks[taskId].tMvmtDir = MVMT_BACKWARD; + if (gMain.heldKeys & DPAD_RIGHT) + gTasks[taskId].tMvmtDir = MVMT_FORWARD; + if (gTasks[taskId].tMvmtDir) + { + if (gTasks[taskId].tMvmtSpeed < 0xFF) + gTasks[taskId].tMvmtSpeed++; + gTasks[taskId].tMinuteHandAngle = CalcNewMinHandAngle( + gTasks[taskId].tMinuteHandAngle, + gTasks[taskId].tMvmtDir, + gTasks[taskId].tMvmtSpeed); + AdvanceClock(taskId, gTasks[taskId].tMvmtDir); + } + else + { + gTasks[taskId].tMvmtSpeed = 0; + } + } + } +} + +//Ask player "Is this the correct time?" +static void Task_SetClock3(u8 taskId) +{ + Menu_DrawStdWindowFrame(2, 16, 27, 19); + Menu_PrintText(gOtherText_CorrectTimePrompt, 3, 17); + Menu_DrawStdWindowFrame(23, 8, 29, 13); + Menu_PrintItems(24, 9, 2, gMenuYesNoItems); + InitMenu(0, 24, 9, 2, 1, 5); + gTasks[taskId].func = Task_SetClock4; +} + +//Get menu selection +static void Task_SetClock4(u8 taskId) +{ + switch (Menu_ProcessInputNoWrap_()) + { + case 0: //YES + PlaySE(SE_SELECT); + gTasks[taskId].func = Task_SetClock5; //Move on + return; + case -1: //B button + case 1: //NO + Menu_DestroyCursor(); + PlaySE(SE_SELECT); + Menu_EraseWindowRect(23, 8, 29, 13); + Menu_EraseWindowRect(2, 16, 27, 19); + gTasks[taskId].func = Task_SetClock2; //Go back and let player adjust clock + } +} + +//Set the time offset based on the wall clock's time +static void Task_SetClock5(u8 taskId) +{ + RtcInitLocalTimeOffset(gTasks[taskId].tHours, gTasks[taskId].tMinutes); + BeginNormalPaletteFade(-1, 0, 0, 16, 0); + gTasks[taskId].func = Task_SetClock6; +} + +static void Task_SetClock6(u8 taskId) +{ + if (!gPaletteFade.active) + SetMainCallback2((MainCallback)gMain.savedCallback); +} + +static void Task_ViewClock1(u8 taskId) +{ + if (!gPaletteFade.active) + gTasks[taskId].func = Task_ViewClock2; +} + +//Wait for A or B press +static void Task_ViewClock2(u8 taskId) +{ + InitClockWithRtc(taskId); + if (gMain.newKeys & (A_BUTTON | B_BUTTON)) + gTasks[taskId].func = Task_ViewClock3; +} + +static void Task_ViewClock3(u8 taskId) +{ + BeginNormalPaletteFade(-1, 0, 0, 16, 0); + gTasks[taskId].func = Task_ViewClock4; +} + +static void Task_ViewClock4(u8 taskId) +{ + if (!gPaletteFade.active) + SetMainCallback2((MainCallback)gMain.savedCallback); +} + +static u8 CalcMinHandDelta(u16 speed) +{ + if (speed > 60) + return 6; + else if (speed > 30) + return 3; + else if (speed > 10) + return 2; + else + return 1; +} + +//Calculates the new angle of the minute hand when setting the clock +static u16 CalcNewMinHandAngle(u16 angle, u8 direction, u8 speed) +{ + u8 delta = CalcMinHandDelta(speed); + + switch (direction) + { + case MVMT_BACKWARD: + if (angle) + angle = angle - delta; + else + angle = 360 - delta; + break; + case MVMT_FORWARD: + if (angle < 360 - delta) + angle = angle + delta; + else + angle = 0; + break; + } + return angle; +} + +//Advances clock forward or backward by 1 minute +static u8 AdvanceClock(u8 taskId, u8 direction) +{ + switch (direction) + { + case MVMT_BACKWARD: + if (gTasks[taskId].tMinutes > 0) + gTasks[taskId].tMinutes--; + else + { + gTasks[taskId].tMinutes = 59; + if (gTasks[taskId].tHours > 0) + gTasks[taskId].tHours--; + else + gTasks[taskId].tHours = 23; + UpdateClockPeriod(taskId, direction); + } + break; + case MVMT_FORWARD: + if (gTasks[taskId].tMinutes < 59) + gTasks[taskId].tMinutes++; + else + { + gTasks[taskId].tMinutes = 0; + if (gTasks[taskId].tHours < 23) + gTasks[taskId].tHours++; + else + gTasks[taskId].tHours = 0; + UpdateClockPeriod(taskId, direction); + } + break; + } + return 0; +} + +//Updates the clock period (AM/PM) if it needs to change +static void UpdateClockPeriod(u8 taskId, u8 direction) +{ + u8 hours = gTasks[taskId].tHours; + + switch (direction) + { + case MVMT_BACKWARD: + switch (hours) + { + case 11: + gTasks[taskId].tPeriod = PERIOD_AM; + break; + case 23: + gTasks[taskId].tPeriod = PERIOD_PM; + break; + } + break; + case MVMT_FORWARD: + switch (hours) + { + case 0: + gTasks[taskId].tPeriod = PERIOD_AM; + break; + case 12: + gTasks[taskId].tPeriod = PERIOD_PM; + break; + } + break; + } +} + +static void InitClockWithRtc(u8 taskId) +{ + RtcCalcLocalTime(); + gTasks[taskId].tHours = gLocalTime.hours; + gTasks[taskId].tMinutes = gLocalTime.minutes; + gTasks[taskId].tMinuteHandAngle = gTasks[taskId].tMinutes * 6; + gTasks[taskId].tHourHandAngle = (gTasks[taskId].tHours % 12) * 30 + (gTasks[taskId].tMinutes / 10) * 5; + if (gLocalTime.hours <= 11) + gTasks[taskId].tPeriod = PERIOD_AM; + else + gTasks[taskId].tPeriod = PERIOD_PM; +} + +static const s8 gClockHandCoords[][2] = +{ + { 0, -24}, + { 1, -25}, + { 1, -25}, + { 2, -25}, + { 2, -25}, + { 2, -25}, + { 3, -24}, + { 3, -25}, + { 4, -25}, + { 4, -25}, + { 4, -25}, + { 5, -25}, + { 5, -25}, + { 6, -24}, + { 6, -24}, + { 6, -24}, + { 7, -24}, + { 7, -24}, + { 7, -24}, + { 8, -24}, + { 8, -24}, + { 9, -24}, + { 9, -24}, + { 10, -23}, + { 10, -23}, + { 11, -22}, + { 11, -22}, + { 11, -22}, + { 12, -22}, + { 12, -21}, + { 13, -21}, + { 13, -21}, + { 13, -21}, + { 14, -21}, + { 14, -21}, + { 14, -20}, + { 14, -20}, + { 15, -20}, + { 15, -19}, + { 16, -19}, + { 16, -19}, + { 16, -19}, + { 16, -18}, + { 16, -18}, + { 17, -18}, + { 17, -17}, + { 17, -17}, + { 18, -17}, + { 18, -17}, + { 18, -16}, + { 18, -16}, + { 19, -16}, + { 19, -15}, + { 19, -15}, + { 20, -15}, + { 20, -14}, + { 20, -14}, + { 20, -13}, + { 20, -13}, + { 21, -13}, + { 21, -13}, + { 21, -12}, + { 22, -12}, + { 22, -12}, + { 22, -11}, + { 22, -11}, + { 22, -10}, + { 23, -10}, + { 23, -9}, + { 23, -9}, + { 23, -9}, + { 23, -9}, + { 23, -8}, + { 23, -8}, + { 23, -7}, + { 23, -7}, + { 23, -6}, + { 24, -6}, + { 24, -6}, + { 25, -5}, + { 25, -5}, + { 24, -4}, + { 25, -4}, + { 24, -3}, + { 25, -3}, + { 25, -3}, + { 25, -2}, + { 25, -2}, + { 24, -1}, + { 25, -1}, + { 24, 0}, + { 24, 0}, + { 24, 0}, + { 24, 1}, + { 24, 1}, + { 25, 2}, + { 24, 2}, + { 25, 2}, + { 24, 3}, + { 24, 3}, + { 25, 4}, + { 24, 4}, + { 24, 5}, + { 24, 5}, + { 24, 5}, + { 24, 6}, + { 23, 6}, + { 23, 6}, + { 23, 7}, + { 23, 8}, + { 23, 8}, + { 23, 8}, + { 23, 9}, + { 23, 9}, + { 23, 10}, + { 22, 10}, + { 22, 10}, + { 22, 11}, + { 22, 11}, + { 22, 11}, + { 22, 12}, + { 21, 12}, + { 21, 12}, + { 21, 13}, + { 20, 13}, + { 20, 13}, + { 19, 13}, + { 19, 13}, + { 19, 14}, + { 19, 14}, + { 19, 15}, + { 19, 15}, + { 18, 15}, + { 18, 16}, + { 17, 16}, + { 17, 16}, + { 17, 17}, + { 17, 17}, + { 16, 17}, + { 16, 18}, + { 16, 18}, + { 15, 18}, + { 14, 18}, + { 15, 19}, + { 14, 19}, + { 14, 19}, + { 13, 19}, + { 13, 20}, + { 13, 20}, + { 13, 20}, + { 12, 20}, + { 12, 20}, + { 12, 21}, + { 11, 21}, + { 11, 21}, + { 11, 21}, + { 10, 21}, + { 10, 22}, + { 10, 22}, + { 9, 22}, + { 9, 22}, + { 8, 22}, + { 7, 22}, + { 7, 23}, + { 7, 23}, + { 6, 23}, + { 6, 23}, + { 5, 23}, + { 5, 23}, + { 5, 24}, + { 4, 24}, + { 4, 24}, + { 4, 24}, + { 3, 24}, + { 2, 24}, + { 2, 24}, + { 1, 24}, + { 1, 24}, + { 0, 24}, + { 0, 24}, + { -1, 23}, + { 0, 24}, + { 0, 24}, + { -1, 24}, + { -1, 24}, + { -2, 24}, + { -2, 24}, + { -3, 24}, + { -3, 24}, + { -4, 24}, + { -4, 24}, + { -5, 24}, + { -5, 23}, + { -5, 23}, + { -6, 23}, + { -6, 23}, + { -7, 23}, + { -7, 23}, + { -7, 23}, + { -8, 23}, + { -8, 22}, + { -9, 22}, + { -9, 22}, + {-10, 22}, + {-10, 22}, + {-10, 21}, + {-11, 21}, + {-11, 21}, + {-11, 21}, + {-11, 20}, + {-12, 20}, + {-12, 20}, + {-13, 20}, + {-13, 20}, + {-13, 19}, + {-14, 19}, + {-14, 19}, + {-14, 19}, + {-14, 18}, + {-15, 18}, + {-15, 18}, + {-15, 17}, + {-16, 17}, + {-16, 17}, + {-17, 17}, + {-17, 16}, + {-17, 16}, + {-18, 16}, + {-17, 15}, + {-18, 15}, + {-18, 15}, + {-19, 15}, + {-19, 14}, + {-19, 14}, + {-19, 13}, + {-19, 13}, + {-20, 13}, + {-20, 12}, + {-20, 12}, + {-21, 12}, + {-21, 12}, + {-21, 11}, + {-21, 11}, + {-21, 10}, + {-21, 10}, + {-21, 9}, + {-22, 9}, + {-22, 9}, + {-22, 8}, + {-22, 8}, + {-22, 7}, + {-23, 7}, + {-23, 7}, + {-23, 6}, + {-23, 6}, + {-23, 5}, + {-24, 5}, + {-23, 4}, + {-23, 4}, + {-24, 4}, + {-24, 4}, + {-24, 3}, + {-24, 3}, + {-24, 2}, + {-24, 2}, + {-24, 1}, + {-24, 1}, + {-24, 1}, + {-24, 0}, + {-25, 0}, + {-24, -1}, + {-25, -1}, + {-24, -1}, + {-24, -2}, + {-24, -2}, + {-24, -3}, + {-24, -3}, + {-24, -4}, + {-24, -4}, + {-24, -4}, + {-24, -5}, + {-24, -5}, + {-24, -6}, + {-24, -6}, + {-23, -6}, + {-23, -7}, + {-23, -7}, + {-23, -8}, + {-23, -8}, + {-23, -9}, + {-23, -9}, + {-22, -9}, + {-22, -9}, + {-22, -10}, + {-22, -10}, + {-21, -10}, + {-21, -11}, + {-22, -11}, + {-22, -12}, + {-21, -12}, + {-21, -13}, + {-21, -13}, + {-20, -13}, + {-21, -14}, + {-20, -14}, + {-20, -14}, + {-19, -14}, + {-19, -15}, + {-19, -15}, + {-18, -16}, + {-18, -16}, + {-18, -16}, + {-18, -17}, + {-18, -17}, + {-17, -17}, + {-17, -18}, + {-17, -18}, + {-16, -18}, + {-16, -18}, + {-16, -19}, + {-16, -19}, + {-15, -19}, + {-15, -19}, + {-15, -20}, + {-14, -20}, + {-14, -20}, + {-14, -21}, + {-13, -21}, + {-13, -21}, + {-13, -21}, + {-12, -21}, + {-12, -22}, + {-11, -22}, + {-11, -22}, + {-11, -22}, + {-10, -22}, + {-10, -22}, + { -9, -22}, + { -9, -23}, + { -9, -23}, + { -8, -23}, + { -8, -23}, + { -7, -23}, + { -7, -23}, + { -7, -24}, + { -6, -24}, + { -6, -24}, + { -5, -24}, + { -5, -24}, + { -4, -24}, + { -4, -24}, + { -4, -24}, + { -4, -25}, + { -3, -25}, + { -2, -25}, + { -2, -24}, + { -2, -24}, + { -1, -25}, + { -1, -25}, + { 0, -25}, +}; + +static void sub_810B05C(struct Sprite *sprite) +{ + u16 angle; + s16 sin; + s16 cos; + u16 x; + u16 y; + + angle = gTasks[sprite->data[0]].tMinuteHandAngle; + sin = Sin2(angle) / 16; + cos = Cos2(angle) / 16; + SetOamMatrix(0, cos, sin, -sin, cos); + x = gClockHandCoords[angle][0]; + y = gClockHandCoords[angle][1]; + + //Manual sign extension + if (x > 0x80) + x |= 0xFF00; + if (y > 0x80) + y |= 0xFF00; + + sprite->pos2.x = x; + sprite->pos2.y = y; +} + +static void sub_810B0F4(struct Sprite *sprite) +{ + u16 angle; + s16 sin; + s16 cos; + u16 x; + u16 y; + + angle = gTasks[sprite->data[0]].tHourHandAngle; + sin = Sin2(angle) / 16; + cos = Cos2(angle) / 16; + SetOamMatrix(1, cos, sin, -sin, cos); + x = gClockHandCoords[angle][0]; + y = gClockHandCoords[angle][1]; + + //Manual sign extension + if (x > 0x80) + x |= 0xFF00; + if (y > 0x80) + y |= 0xFF00; + + sprite->pos2.x = x; + sprite->pos2.y = y; +} + +static void sub_810B18C(struct Sprite *sprite) +{ + s16 sin; + s16 cos; + + if (gTasks[sprite->data[0]].tPeriod != PERIOD_AM) + { + if (sprite->data[1] >= 60 && sprite->data[1] < 90) + sprite->data[1] += 5; + if (sprite->data[1] < 60) + sprite->data[1]++; + } + else + { + if (sprite->data[1] > 45 && sprite->data[1] <= 75) + sprite->data[1] -= 5; + if (sprite->data[1] > 75) + sprite->data[1]--; + } + cos = Cos2((u16)sprite->data[1]); + sprite->pos2.x = cos * 30 / 4096; + sin = Sin2((u16)sprite->data[1]); + sprite->pos2.y = sin * 30 / 4096; +} + +static void sub_810B230(struct Sprite *sprite) +{ + s16 sin; + s16 cos; + + if (gTasks[sprite->data[0]].tPeriod != PERIOD_AM) + { + if (sprite->data[1] >= 105 && sprite->data[1] < 135) + sprite->data[1] += 5; + if (sprite->data[1] < 105) + sprite->data[1]++; + } + else + { + if (sprite->data[1] > 90 && sprite->data[1] <= 120) + sprite->data[1] -= 5; + if (sprite->data[1] > 120) + sprite->data[1]--; + } + cos = Cos2((u16)sprite->data[1]); + sprite->pos2.x = cos * 30 / 4096; + sin = Sin2((u16)sprite->data[1]); + sprite->pos2.y = sin * 30 / 4096; +} |