pokeemerald/src/wallclock.c

1143 lines
26 KiB
C
Raw Normal View History

2017-11-25 00:00:26 +01:00
#include "global.h"
#include "bg.h"
#include "clock.h"
2018-11-12 15:04:32 +01:00
#include "decompress.h"
2017-11-25 00:00:26 +01:00
#include "event_data.h"
2018-11-12 15:04:32 +01:00
#include "gpu_regs.h"
2017-11-25 00:00:26 +01:00
#include "graphics.h"
2018-11-12 15:04:32 +01:00
#include "main.h"
2017-11-25 00:00:26 +01:00
#include "menu.h"
2018-11-12 15:04:32 +01:00
#include "palette.h"
#include "rtc.h"
2018-01-29 17:47:12 +01:00
#include "scanline_effect.h"
2017-11-25 03:06:46 +01:00
#include "sound.h"
2018-11-12 15:04:32 +01:00
#include "strings.h"
#include "task.h"
#include "text.h"
#include "text_window.h"
2017-11-25 04:08:12 +01:00
#include "trig.h"
2018-11-12 15:04:32 +01:00
#include "wallclock.h"
#include "window.h"
2019-04-04 23:05:46 +02:00
#include "constants/rgb.h"
2018-11-12 15:04:32 +01:00
#include "constants/songs.h"
2017-11-25 04:43:05 +01:00
2017-11-25 00:00:26 +01:00
// static declarations
2017-12-16 16:23:05 +01:00
static void WallClockMainCallback(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);
2018-11-12 15:04:32 +01:00
static u16 CalcNewMinHandAngle(u16 angle, u8 direction, u8 speed);
static bool32 AdvanceClock(u8 taskId, u8 direction);
static void UpdateClockPeriod(u8 taskId, u8 direction);
2017-12-16 16:23:05 +01:00
static void InitClockWithRtc(u8 taskId);
static void SpriteCB_MinuteHand(struct Sprite *sprite);
static void SpriteCB_HourHand(struct Sprite *sprite);
static void SpriteCB_AMIndicator(struct Sprite *sprite);
static void SpriteCB_PMIndicator(struct Sprite *sprite);
2018-11-12 15:04:32 +01:00
#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]
#define TAG_GFX_WALL_CLOCK_HAND 0x1000
#define TAG_PAL_WALL_CLOCK_HAND 0x1000
enum
{
PERIOD_AM,
PERIOD_PM,
};
enum
{
MVMT_NONE,
MVMT_BACKWARD,
MVMT_FORWARD,
};
2017-11-25 00:00:26 +01:00
// rodata
2018-10-21 09:24:57 +02:00
static const u32 sUnknown_085B1F58[] = INCBIN_U32("graphics/wallclock/graphics_85b1f58.4bpp.lz");
2017-12-17 23:45:27 +01:00
static const u16 sUnknown_085B21D4[] = INCBIN_U16("graphics/wallclock/palette_85b21d4.gbapal");
2018-09-02 17:10:06 +02:00
2018-10-27 00:53:07 +02:00
static const struct WindowTemplate gUnknown_085B21DC[] =
2018-09-02 17:10:06 +02:00
{
{
2018-10-27 00:53:07 +02:00
.bg = 0,
2018-09-02 17:10:06 +02:00
.tilemapLeft = 3,
.tilemapTop = 17,
.width = 24,
.height = 2,
.paletteNum = 14,
.baseBlock = 512
},
{
2018-10-27 00:53:07 +02:00
.bg = 2,
2018-09-02 17:10:06 +02:00
.tilemapLeft = 24,
.tilemapTop = 16,
.width = 6,
.height = 2,
.paletteNum = 12,
.baseBlock = 560
},
2017-11-25 01:06:01 +01:00
DUMMY_WIN_TEMPLATE
};
2018-09-02 17:10:06 +02:00
static const struct WindowTemplate gUnknown_085B21F4 =
{
2018-10-27 00:53:07 +02:00
.bg = 0,
2018-09-02 17:10:06 +02:00
.tilemapLeft = 24,
.tilemapTop = 9,
.width = 5,
.height = 4,
.paletteNum = 14,
.baseBlock = 572
2017-11-25 01:06:01 +01:00
};
static const struct BgTemplate gUnknown_085B21FC[] =
{
2017-11-25 01:06:01 +01:00
{
.bg = 0,
.charBaseIndex = 2,
.mapBaseIndex = 31,
.priority = 0
},
{
.bg = 2,
.charBaseIndex = 1,
.mapBaseIndex = 8,
.priority = 1
},
{
.bg = 3,
.charBaseIndex = 0,
.mapBaseIndex = 7,
.priority = 2
}
};
static const struct CompressedSpriteSheet gUnknown_085B2208 =
{
2017-12-17 23:45:27 +01:00
sUnknown_085B1F58, 0x2000, TAG_GFX_WALL_CLOCK_HAND
2017-11-25 01:06:01 +01:00
};
static const u8 filler_85B2210[8] = {0};
static const struct SpritePalette gUnknown_085B2218[] =
{
{
.data = gWallclockMale_Pal,
.tag = TAG_PAL_WALL_CLOCK_HAND
},
{
.data = gWallclockFemale_Pal,
.tag = 0x1001
},
2017-11-25 01:06:01 +01:00
{}
};
static const struct OamData Unknown_085B2230 =
{
2018-11-12 15:04:32 +01:00
.y = 160,
.shape = SPRITE_SHAPE(64x64),
.size = SPRITE_SIZE(64x64),
2018-11-12 15:04:32 +01:00
.priority = 1,
};
static const union AnimCmd Unknown_085B2238[] =
{
ANIMCMD_FRAME(0, 30),
2018-11-12 15:04:32 +01:00
ANIMCMD_END,
};
static const union AnimCmd Unknown_085B2240[] =
{
ANIMCMD_FRAME(64, 30),
2018-11-12 15:04:32 +01:00
ANIMCMD_END,
};
static const union AnimCmd *const gUnknown_085B2248[] =
{
Unknown_085B2238
};
static const union AnimCmd *const gUnknown_085B224C[] =
{
Unknown_085B2240
};
2018-09-02 17:10:06 +02:00
static const struct SpriteTemplate gUnknown_085B2250 =
{
.tileTag = TAG_GFX_WALL_CLOCK_HAND,
.paletteTag = TAG_PAL_WALL_CLOCK_HAND,
.oam = &Unknown_085B2230,
.anims = gUnknown_085B2248,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-11-12 15:04:32 +01:00
.callback = SpriteCB_MinuteHand,
2018-09-02 17:10:06 +02:00
};
2018-09-02 17:10:06 +02:00
static const struct SpriteTemplate gUnknown_085B2268 =
{
.tileTag = TAG_GFX_WALL_CLOCK_HAND,
.paletteTag = TAG_PAL_WALL_CLOCK_HAND,
.oam = &Unknown_085B2230,
.anims = gUnknown_085B224C,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-11-12 15:04:32 +01:00
.callback = SpriteCB_HourHand,
};
static const struct OamData Unknown_085B2280 =
{
2018-11-12 15:04:32 +01:00
.y = 160,
.shape = SPRITE_SHAPE(16x16),
.size = SPRITE_SIZE(16x16),
2018-11-12 15:04:32 +01:00
.priority = 3,
};
static const union AnimCmd Unknown_085B2288[] =
{
2018-11-12 15:04:32 +01:00
ANIMCMD_FRAME(132, 30),
ANIMCMD_END,
};
static const union AnimCmd Unknown_085B2290[] =
{
2018-11-12 15:04:32 +01:00
ANIMCMD_FRAME(128, 30),
ANIMCMD_END,
};
static const union AnimCmd *const gUnknown_085B2298[] =
{
Unknown_085B2288
};
static const union AnimCmd *const gUnknown_085B229C[] =
{
Unknown_085B2290
};
2018-09-02 17:10:06 +02:00
static const struct SpriteTemplate gUnknown_085B22A0 =
{
.tileTag = TAG_GFX_WALL_CLOCK_HAND,
.paletteTag = TAG_PAL_WALL_CLOCK_HAND,
.oam = &Unknown_085B2280,
.anims = gUnknown_085B2298,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_AMIndicator
};
2018-09-02 17:10:06 +02:00
static const struct SpriteTemplate gUnknown_085B22B8 =
{
.tileTag = TAG_GFX_WALL_CLOCK_HAND,
.paletteTag = TAG_PAL_WALL_CLOCK_HAND,
.oam = &Unknown_085B2280,
.anims = gUnknown_085B229C,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_PMIndicator
};
static const s8 sClockHandCoords[][2] =
{
2017-11-25 02:46:29 +01:00
{ 0x00, -0x18},
{ 0x01, -0x19},
{ 0x01, -0x19},
{ 0x02, -0x19},
{ 0x02, -0x19},
{ 0x02, -0x19},
{ 0x03, -0x18},
{ 0x03, -0x19},
{ 0x04, -0x19},
{ 0x04, -0x19},
{ 0x04, -0x19},
{ 0x05, -0x19},
{ 0x05, -0x19},
{ 0x06, -0x18},
{ 0x06, -0x18},
{ 0x06, -0x18},
{ 0x07, -0x18},
{ 0x07, -0x18},
{ 0x07, -0x18},
{ 0x08, -0x18},
{ 0x08, -0x18},
{ 0x09, -0x18},
{ 0x09, -0x18},
{ 0x0a, -0x17},
{ 0x0a, -0x17},
{ 0x0b, -0x16},
{ 0x0b, -0x16},
{ 0x0b, -0x16},
{ 0x0c, -0x16},
{ 0x0c, -0x15},
{ 0x0d, -0x15},
{ 0x0d, -0x15},
{ 0x0d, -0x15},
{ 0x0e, -0x15},
{ 0x0e, -0x15},
{ 0x0e, -0x14},
{ 0x0e, -0x14},
{ 0x0f, -0x14},
{ 0x0f, -0x13},
{ 0x10, -0x13},
{ 0x10, -0x13},
{ 0x10, -0x13},
{ 0x10, -0x12},
{ 0x10, -0x12},
{ 0x11, -0x12},
{ 0x11, -0x11},
{ 0x11, -0x11},
{ 0x12, -0x11},
{ 0x12, -0x11},
{ 0x12, -0x10},
{ 0x12, -0x10},
{ 0x13, -0x10},
{ 0x13, -0x0f},
{ 0x13, -0x0f},
{ 0x14, -0x0f},
{ 0x14, -0x0e},
{ 0x14, -0x0e},
{ 0x14, -0x0d},
{ 0x14, -0x0d},
{ 0x15, -0x0d},
{ 0x15, -0x0d},
{ 0x15, -0x0c},
{ 0x16, -0x0c},
{ 0x16, -0x0c},
{ 0x16, -0x0b},
{ 0x16, -0x0b},
{ 0x16, -0x0a},
{ 0x17, -0x0a},
{ 0x17, -0x09},
{ 0x17, -0x09},
{ 0x17, -0x09},
{ 0x17, -0x09},
{ 0x17, -0x08},
{ 0x17, -0x08},
{ 0x17, -0x07},
{ 0x17, -0x07},
{ 0x17, -0x06},
{ 0x18, -0x06},
{ 0x18, -0x06},
{ 0x19, -0x05},
{ 0x19, -0x05},
{ 0x18, -0x04},
{ 0x19, -0x04},
{ 0x18, -0x03},
{ 0x19, -0x03},
{ 0x19, -0x03},
{ 0x19, -0x02},
{ 0x19, -0x02},
{ 0x18, -0x01},
{ 0x19, -0x01},
{ 0x18, 0x00},
{ 0x18, 0x00},
{ 0x18, 0x00},
{ 0x18, 0x01},
{ 0x18, 0x01},
{ 0x19, 0x02},
{ 0x18, 0x02},
{ 0x19, 0x02},
{ 0x18, 0x03},
{ 0x18, 0x03},
{ 0x19, 0x04},
{ 0x18, 0x04},
{ 0x18, 0x05},
{ 0x18, 0x05},
{ 0x18, 0x05},
{ 0x18, 0x06},
{ 0x17, 0x06},
{ 0x17, 0x06},
{ 0x17, 0x07},
{ 0x17, 0x08},
{ 0x17, 0x08},
{ 0x17, 0x08},
{ 0x17, 0x09},
{ 0x17, 0x09},
{ 0x17, 0x0a},
{ 0x16, 0x0a},
{ 0x16, 0x0a},
{ 0x16, 0x0b},
{ 0x16, 0x0b},
{ 0x16, 0x0b},
{ 0x16, 0x0c},
{ 0x15, 0x0c},
{ 0x15, 0x0c},
{ 0x15, 0x0d},
{ 0x14, 0x0d},
{ 0x14, 0x0d},
{ 0x13, 0x0d},
{ 0x13, 0x0d},
{ 0x13, 0x0e},
{ 0x13, 0x0e},
{ 0x13, 0x0f},
{ 0x13, 0x0f},
{ 0x12, 0x0f},
{ 0x12, 0x10},
{ 0x11, 0x10},
{ 0x11, 0x10},
{ 0x11, 0x11},
{ 0x11, 0x11},
{ 0x10, 0x11},
{ 0x10, 0x12},
{ 0x10, 0x12},
{ 0x0f, 0x12},
{ 0x0e, 0x12},
{ 0x0f, 0x13},
{ 0x0e, 0x13},
{ 0x0e, 0x13},
{ 0x0d, 0x13},
{ 0x0d, 0x14},
{ 0x0d, 0x14},
{ 0x0d, 0x14},
{ 0x0c, 0x14},
{ 0x0c, 0x14},
{ 0x0c, 0x15},
{ 0x0b, 0x15},
{ 0x0b, 0x15},
{ 0x0b, 0x15},
{ 0x0a, 0x15},
{ 0x0a, 0x16},
{ 0x0a, 0x16},
{ 0x09, 0x16},
{ 0x09, 0x16},
{ 0x08, 0x16},
{ 0x07, 0x16},
{ 0x07, 0x17},
{ 0x07, 0x17},
{ 0x06, 0x17},
{ 0x06, 0x17},
{ 0x05, 0x17},
{ 0x05, 0x17},
{ 0x05, 0x18},
{ 0x04, 0x18},
{ 0x04, 0x18},
{ 0x04, 0x18},
{ 0x03, 0x18},
{ 0x02, 0x18},
{ 0x02, 0x18},
{ 0x01, 0x18},
{ 0x01, 0x18},
{ 0x00, 0x18},
{ 0x00, 0x18},
{-0x01, 0x17},
{ 0x00, 0x18},
{ 0x00, 0x18},
{-0x01, 0x18},
{-0x01, 0x18},
{-0x02, 0x18},
{-0x02, 0x18},
{-0x03, 0x18},
{-0x03, 0x18},
{-0x04, 0x18},
{-0x04, 0x18},
{-0x05, 0x18},
{-0x05, 0x17},
{-0x05, 0x17},
{-0x06, 0x17},
{-0x06, 0x17},
{-0x07, 0x17},
{-0x07, 0x17},
{-0x07, 0x17},
{-0x08, 0x17},
{-0x08, 0x16},
{-0x09, 0x16},
{-0x09, 0x16},
{-0x0a, 0x16},
{-0x0a, 0x16},
{-0x0a, 0x15},
{-0x0b, 0x15},
{-0x0b, 0x15},
{-0x0b, 0x15},
{-0x0b, 0x14},
{-0x0c, 0x14},
{-0x0c, 0x14},
{-0x0d, 0x14},
{-0x0d, 0x14},
{-0x0d, 0x13},
{-0x0e, 0x13},
{-0x0e, 0x13},
{-0x0e, 0x13},
{-0x0e, 0x12},
{-0x0f, 0x12},
{-0x0f, 0x12},
{-0x0f, 0x11},
{-0x10, 0x11},
{-0x10, 0x11},
{-0x11, 0x11},
{-0x11, 0x10},
{-0x11, 0x10},
{-0x12, 0x10},
{-0x11, 0x0f},
{-0x12, 0x0f},
{-0x12, 0x0f},
{-0x13, 0x0f},
{-0x13, 0x0e},
{-0x13, 0x0e},
{-0x13, 0x0d},
{-0x13, 0x0d},
{-0x14, 0x0d},
{-0x14, 0x0c},
{-0x14, 0x0c},
{-0x15, 0x0c},
{-0x15, 0x0c},
{-0x15, 0x0b},
{-0x15, 0x0b},
{-0x15, 0x0a},
{-0x15, 0x0a},
{-0x15, 0x09},
{-0x16, 0x09},
{-0x16, 0x09},
{-0x16, 0x08},
{-0x16, 0x08},
{-0x16, 0x07},
{-0x17, 0x07},
{-0x17, 0x07},
{-0x17, 0x06},
{-0x17, 0x06},
{-0x17, 0x05},
{-0x18, 0x05},
{-0x17, 0x04},
{-0x17, 0x04},
{-0x18, 0x04},
{-0x18, 0x04},
{-0x18, 0x03},
{-0x18, 0x03},
{-0x18, 0x02},
{-0x18, 0x02},
{-0x18, 0x01},
{-0x18, 0x01},
{-0x18, 0x01},
{-0x18, 0x00},
{-0x19, 0x00},
{-0x18, -0x01},
{-0x19, -0x01},
{-0x18, -0x01},
{-0x18, -0x02},
{-0x18, -0x02},
{-0x18, -0x03},
{-0x18, -0x03},
{-0x18, -0x04},
{-0x18, -0x04},
{-0x18, -0x04},
{-0x18, -0x05},
{-0x18, -0x05},
{-0x18, -0x06},
{-0x18, -0x06},
{-0x17, -0x06},
{-0x17, -0x07},
{-0x17, -0x07},
{-0x17, -0x08},
{-0x17, -0x08},
{-0x17, -0x09},
{-0x17, -0x09},
{-0x16, -0x09},
{-0x16, -0x09},
{-0x16, -0x0a},
{-0x16, -0x0a},
{-0x15, -0x0a},
{-0x15, -0x0b},
{-0x16, -0x0b},
{-0x16, -0x0c},
{-0x15, -0x0c},
{-0x15, -0x0d},
{-0x15, -0x0d},
{-0x14, -0x0d},
{-0x15, -0x0e},
{-0x14, -0x0e},
{-0x14, -0x0e},
{-0x13, -0x0e},
{-0x13, -0x0f},
{-0x13, -0x0f},
{-0x12, -0x10},
{-0x12, -0x10},
{-0x12, -0x10},
{-0x12, -0x11},
{-0x12, -0x11},
{-0x11, -0x11},
{-0x11, -0x12},
{-0x11, -0x12},
{-0x10, -0x12},
{-0x10, -0x12},
{-0x10, -0x13},
{-0x10, -0x13},
{-0x0f, -0x13},
{-0x0f, -0x13},
{-0x0f, -0x14},
{-0x0e, -0x14},
{-0x0e, -0x14},
{-0x0e, -0x15},
{-0x0d, -0x15},
{-0x0d, -0x15},
{-0x0d, -0x15},
{-0x0c, -0x15},
{-0x0c, -0x16},
{-0x0b, -0x16},
{-0x0b, -0x16},
{-0x0b, -0x16},
{-0x0a, -0x16},
{-0x0a, -0x16},
{-0x09, -0x16},
{-0x09, -0x17},
{-0x09, -0x17},
{-0x08, -0x17},
{-0x08, -0x17},
{-0x07, -0x17},
{-0x07, -0x17},
{-0x07, -0x18},
{-0x06, -0x18},
{-0x06, -0x18},
{-0x05, -0x18},
{-0x05, -0x18},
{-0x04, -0x18},
{-0x04, -0x18},
{-0x04, -0x18},
{-0x04, -0x19},
{-0x03, -0x19},
{-0x02, -0x19},
{-0x02, -0x18},
{-0x02, -0x18},
{-0x01, -0x19},
{-0x01, -0x19},
{ 0x00, -0x19}
};
2017-11-25 00:00:26 +01:00
// text
2017-12-16 16:23:05 +01:00
static void WallClockVblankCallback(void)
2017-11-25 00:00:26 +01:00
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
2017-12-16 16:23:05 +01:00
static void LoadWallClockGraphics(void)
2017-11-25 00:00:26 +01:00
{
SetVBlankCallback(NULL);
2018-12-26 13:43:07 +01:00
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);
2017-11-25 00:00:26 +01:00
ChangeBgX(0, 0, 0);
ChangeBgY(0, 0, 0);
ChangeBgX(1, 0, 0);
ChangeBgY(1, 0, 0);
ChangeBgX(2, 0, 0);
ChangeBgY(2, 0, 0);
ChangeBgX(3, 0, 0);
ChangeBgY(3, 0, 0);
DmaFillLarge16(3, 0, (void *)VRAM, VRAM_SIZE, 0x1000);
DmaClear32(3, (void *)OAM, OAM_SIZE);
DmaClear16(3, (void *)PLTT, PLTT_SIZE);
2017-12-30 02:25:32 +01:00
LZ77UnCompVram(gWallclock_Gfx, (void *)VRAM);
2017-11-25 00:00:26 +01:00
if (gSpecialVar_0x8004 == 0)
{
2017-12-30 02:25:32 +01:00
LoadPalette(gWallclockMale_Pal, 0x00, 0x20);
2017-11-25 00:00:26 +01:00
}
else
{
2017-12-30 02:25:32 +01:00
LoadPalette(gWallclockFemale_Pal, 0x00, 0x20);
2017-11-25 00:00:26 +01:00
}
LoadPalette(GetOverworldTextboxPalettePtr(), 0xe0, 0x20);
2017-12-17 23:45:27 +01:00
LoadPalette(sUnknown_085B21D4, 0xc0, 0x08);
2017-11-25 00:00:26 +01:00
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, gUnknown_085B21FC, 3);
InitWindows(gUnknown_085B21DC);
DeactivateAllTextPrinters();
2018-07-15 13:23:38 +02:00
LoadUserWindowBorderGfx(0, 0x250, 0xd0);
2017-11-25 00:00:26 +01:00
clear_scheduled_bg_copies_to_vram();
2018-01-16 18:59:06 +01:00
ScanlineEffect_Stop();
2017-11-25 00:00:26 +01:00
ResetTasks();
ResetSpriteData();
ResetPaletteFade();
FreeAllSpritePalettes();
2018-12-17 23:00:08 +01:00
LoadCompressedSpriteSheet(&gUnknown_085B2208);
2017-11-25 01:06:01 +01:00
LoadSpritePalettes(gUnknown_085B2218);
2017-11-25 00:00:26 +01:00
}
2017-12-16 16:23:05 +01:00
static void WallClockInit(void)
{
2019-04-04 23:05:46 +02:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
EnableInterrupts(INTR_FLAG_VBLANK);
2017-12-16 16:23:05 +01:00
SetVBlankCallback(WallClockVblankCallback);
SetMainCallback2(WallClockMainCallback);
2018-12-26 13:43:07 +01:00
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
ShowBg(0);
ShowBg(2);
ShowBg(3);
}
void CB2_StartWallClock(void)
{
u8 taskId;
u8 spriteId;
LoadWallClockGraphics();
LZ77UnCompVram(gUnknown_08DCC648, (u16 *)BG_SCREEN_ADDR(7));
2017-12-16 16:23:05 +01:00
taskId = CreateTask(Task_SetClock1, 0);
gTasks[taskId].tHours = 10;
gTasks[taskId].tMinutes = 0;
gTasks[taskId].tMvmtDir = 0;
gTasks[taskId].tPeriod = 0;
gTasks[taskId].tMvmtSpeed = 0;
gTasks[taskId].tMinuteHandAngle = 0;
gTasks[taskId].tHourHandAngle = 300;
2018-11-12 15:04:32 +01:00
spriteId = CreateSprite(&gUnknown_085B2250, 120, 80, 1);
2017-12-16 03:04:25 +01:00
gSprites[spriteId].data[0] = taskId;
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
gSprites[spriteId].oam.matrixNum = 0;
2017-12-16 16:23:05 +01:00
2018-11-12 15:04:32 +01:00
spriteId = CreateSprite(&gUnknown_085B2268, 120, 80, 0);
2017-12-16 03:04:25 +01:00
gSprites[spriteId].data[0] = taskId;
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
gSprites[spriteId].oam.matrixNum = 1;
2017-12-16 16:23:05 +01:00
2018-11-12 15:04:32 +01:00
spriteId = CreateSprite(&gUnknown_085B22A0, 120, 80, 2);
2017-12-16 03:04:25 +01:00
gSprites[spriteId].data[0] = taskId;
gSprites[spriteId].data[1] = 45;
2017-12-16 16:23:05 +01:00
2018-11-12 15:04:32 +01:00
spriteId = CreateSprite(&gUnknown_085B22B8, 120, 80, 2);
2017-12-16 03:04:25 +01:00
gSprites[spriteId].data[0] = taskId;
gSprites[spriteId].data[1] = 90;
2017-12-16 16:23:05 +01:00
WallClockInit();
AddTextPrinterParameterized(1, 1, gText_Confirm3, 0, 1, 0, NULL);
PutWindowTilemap(1);
schedule_bg_copy_tilemap_to_vram(2);
}
2017-11-25 02:06:29 +01:00
void CB2_ViewWallClock(void)
2017-11-25 02:06:29 +01:00
{
u8 taskId;
u8 spriteId;
2017-12-16 16:23:05 +01:00
u8 angle1;
u8 angle2;
2017-11-25 02:06:29 +01:00
LoadWallClockGraphics();
LZ77UnCompVram(gUnknown_08DCC908, (u16 *)BG_SCREEN_ADDR(7));
2017-12-16 16:23:05 +01:00
taskId = CreateTask(Task_ViewClock1, 0);
InitClockWithRtc(taskId);
if (gTasks[taskId].tPeriod == 0)
2017-11-25 02:06:29 +01:00
{
2017-12-16 16:23:05 +01:00
angle1 = 45;
angle2 = 90;
2017-11-25 02:06:29 +01:00
}
else
{
2017-12-16 16:23:05 +01:00
angle1 = 90;
angle2 = 135;
2017-11-25 02:06:29 +01:00
}
2017-12-17 23:45:27 +01:00
2018-11-12 15:04:32 +01:00
spriteId = CreateSprite(&gUnknown_085B2250, 120, 80, 1);
2017-12-16 03:04:25 +01:00
gSprites[spriteId].data[0] = taskId;
2017-11-25 02:06:29 +01:00
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
gSprites[spriteId].oam.matrixNum = 0;
2017-12-17 23:45:27 +01:00
2018-11-12 15:04:32 +01:00
spriteId = CreateSprite(&gUnknown_085B2268, 120, 80, 0);
2017-12-16 03:04:25 +01:00
gSprites[spriteId].data[0] = taskId;
2017-11-25 02:06:29 +01:00
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
gSprites[spriteId].oam.matrixNum = 1;
2017-12-17 23:45:27 +01:00
2018-11-12 15:04:32 +01:00
spriteId = CreateSprite(&gUnknown_085B22A0, 120, 80, 2);
2017-12-16 03:04:25 +01:00
gSprites[spriteId].data[0] = taskId;
2017-12-16 16:23:05 +01:00
gSprites[spriteId].data[1] = angle1;
2017-12-17 23:45:27 +01:00
2018-11-12 15:04:32 +01:00
spriteId = CreateSprite(&gUnknown_085B22B8, 120, 80, 2);
2017-12-16 03:04:25 +01:00
gSprites[spriteId].data[0] = taskId;
2017-12-16 16:23:05 +01:00
gSprites[spriteId].data[1] = angle2;
2017-12-17 23:45:27 +01:00
2017-12-16 16:23:05 +01:00
WallClockInit();
2017-12-17 23:45:27 +01:00
AddTextPrinterParameterized(1, 1, gText_Cancel4, 0, 1, 0, NULL);
2017-11-25 02:06:29 +01:00
PutWindowTilemap(1);
schedule_bg_copy_tilemap_to_vram(2);
}
2017-11-25 02:46:29 +01:00
2017-12-16 16:23:05 +01:00
static void WallClockMainCallback(void)
2017-11-25 02:46:29 +01:00
{
RunTasks();
AnimateSprites();
BuildOamBuffer();
do_scheduled_bg_tilemap_copies_to_vram();
UpdatePaletteFade();
}
2017-12-16 16:23:05 +01:00
static void Task_SetClock1(u8 taskId)
2017-11-25 02:46:29 +01:00
{
if (!gPaletteFade.active)
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].func = Task_SetClock2;
2017-11-25 02:46:29 +01:00
}
}
2017-12-16 16:23:05 +01:00
static void Task_SetClock2(u8 taskId)
2017-11-25 02:46:29 +01:00
{
2017-12-16 16:23:05 +01:00
if (gTasks[taskId].tMinuteHandAngle % 6)
2017-11-25 02:46:29 +01:00
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tMinuteHandAngle = CalcNewMinHandAngle(gTasks[taskId].tMinuteHandAngle, gTasks[taskId].tMvmtDir, gTasks[taskId].tMvmtSpeed);
2017-11-25 02:46:29 +01:00
}
else
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tMinuteHandAngle = gTasks[taskId].tMinutes * 6;
gTasks[taskId].tHourHandAngle = (gTasks[taskId].tHours % 12) * 30 + (gTasks[taskId].tMinutes / 10) * 5;
2017-11-25 02:46:29 +01:00
if (gMain.newKeys & A_BUTTON)
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].func = Task_SetClock3;
2017-11-25 02:46:29 +01:00
}
else
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tMvmtDir = 0;
2017-11-25 02:46:29 +01:00
if (gMain.heldKeys & DPAD_LEFT)
{
2018-11-12 15:04:32 +01:00
gTasks[taskId].tMvmtDir = MVMT_BACKWARD;
2017-11-25 02:46:29 +01:00
}
if (gMain.heldKeys & DPAD_RIGHT)
{
2018-11-12 15:04:32 +01:00
gTasks[taskId].tMvmtDir = MVMT_FORWARD;
2017-11-25 02:46:29 +01:00
}
2017-12-16 16:23:05 +01:00
if (gTasks[taskId].tMvmtDir != 0)
2017-11-25 02:46:29 +01:00
{
2017-12-16 16:23:05 +01:00
if (gTasks[taskId].tMvmtSpeed < 0xFF)
2017-11-25 02:46:29 +01:00
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tMvmtSpeed++;
2017-11-25 02:46:29 +01:00
}
2017-12-16 16:23:05 +01:00
gTasks[taskId].tMinuteHandAngle = CalcNewMinHandAngle(gTasks[taskId].tMinuteHandAngle, gTasks[taskId].tMvmtDir, gTasks[taskId].tMvmtSpeed);
AdvanceClock(taskId, gTasks[taskId].tMvmtDir);
2017-11-25 02:46:29 +01:00
}
else
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tMvmtSpeed = 0;
2017-11-25 02:46:29 +01:00
}
}
}
}
2017-11-25 03:06:46 +01:00
2017-12-16 16:23:05 +01:00
static void Task_SetClock3(u8 taskId)
2017-11-25 03:06:46 +01:00
{
DrawStdFrameWithCustomTileAndPalette(0, FALSE, 0x250, 0x0d);
AddTextPrinterParameterized(0, 1, gText_IsThisTheCorrectTime, 0, 1, 0, NULL);
2017-11-25 03:06:46 +01:00
PutWindowTilemap(0);
schedule_bg_copy_tilemap_to_vram(0);
CreateYesNoMenu(&gUnknown_085B21F4, 0x250, 0x0d, 1);
2017-12-16 16:23:05 +01:00
gTasks[taskId].func = Task_SetClock4;
2017-11-25 03:06:46 +01:00
}
2017-12-16 16:23:05 +01:00
static void Task_SetClock4(u8 taskId)
2017-11-25 03:06:46 +01:00
{
2018-11-05 21:45:54 +01:00
switch (Menu_ProcessInputNoWrapClearOnChoose())
2017-11-25 03:06:46 +01:00
{
2018-11-12 15:04:32 +01:00
case 0: //YES
2017-11-25 03:06:46 +01:00
PlaySE(SE_SELECT);
2017-12-16 16:23:05 +01:00
gTasks[taskId].func = Task_SetClock5;
2017-11-25 03:06:46 +01:00
break;
2018-11-12 15:04:32 +01:00
case 1: //B button
case -1: //NO
2017-11-25 03:06:46 +01:00
PlaySE(SE_SELECT);
ClearStdWindowAndFrameToTransparent(0, FALSE);
2017-11-25 03:06:46 +01:00
ClearWindowTilemap(0);
2017-12-16 16:23:05 +01:00
gTasks[taskId].func = Task_SetClock2;
2017-11-25 03:06:46 +01:00
break;
}
}
2017-11-25 03:11:32 +01:00
2017-12-16 16:23:05 +01:00
static void Task_SetClock5(u8 taskId)
2017-11-25 03:11:32 +01:00
{
2017-12-16 16:23:05 +01:00
RtcInitLocalTimeOffset(gTasks[taskId].tHours, gTasks[taskId].tMinutes);
2019-04-04 23:05:46 +02:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
2017-12-16 16:23:05 +01:00
gTasks[taskId].func = Task_SetClock6;
2017-11-25 03:11:32 +01:00
}
2017-12-16 16:23:05 +01:00
static void Task_SetClock6(u8 taskId)
2017-11-25 03:11:32 +01:00
{
if (!gPaletteFade.active)
{
FreeAllWindowBuffers();
SetMainCallback2(gMain.savedCallback);
}
}
2017-11-25 03:17:50 +01:00
2017-12-16 16:23:05 +01:00
static void Task_ViewClock1(u8 taskId)
2017-11-25 03:17:50 +01:00
{
if (!gPaletteFade.active)
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].func = Task_ViewClock2;
2017-11-25 03:17:50 +01:00
}
}
2017-12-16 16:23:05 +01:00
static void Task_ViewClock2(u8 taskId)
2017-11-25 03:17:50 +01:00
{
2017-12-16 16:23:05 +01:00
InitClockWithRtc(taskId);
2017-11-25 03:17:50 +01:00
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].func = Task_ViewClock3;
2017-11-25 03:17:50 +01:00
}
}
2017-12-16 16:23:05 +01:00
static void Task_ViewClock3(u8 taskId)
2017-11-25 03:17:50 +01:00
{
2019-04-04 23:05:46 +02:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
2017-12-16 16:23:05 +01:00
gTasks[taskId].func = Task_ViewClock4;
2017-11-25 03:17:50 +01:00
}
2017-12-16 16:23:05 +01:00
static void Task_ViewClock4(u8 taskId)
2017-11-25 03:17:50 +01:00
{
if (!gPaletteFade.active)
{
SetMainCallback2(gMain.savedCallback);
}
}
2017-11-25 03:27:05 +01:00
2018-11-12 15:04:32 +01:00
static u8 CalcMinHandDelta(u16 speed)
2017-11-25 03:27:05 +01:00
{
2018-11-12 15:04:32 +01:00
if (speed > 60)
2017-11-25 03:27:05 +01:00
{
return 6;
}
2018-11-12 15:04:32 +01:00
if (speed > 30)
2017-11-25 03:27:05 +01:00
{
return 3;
}
2018-11-12 15:04:32 +01:00
if (speed > 10)
2017-11-25 03:27:05 +01:00
{
return 2;
}
return 1;
}
2018-11-12 15:04:32 +01:00
static u16 CalcNewMinHandAngle(u16 angle, u8 direction, u8 speed)
2017-11-25 03:27:05 +01:00
{
2018-11-12 15:04:32 +01:00
u8 delta = CalcMinHandDelta(speed);
switch (direction)
2017-11-25 03:27:05 +01:00
{
2018-11-12 15:04:32 +01:00
case MVMT_BACKWARD:
if (angle)
2018-12-09 04:32:58 +01:00
angle -= delta;
2018-11-12 15:04:32 +01:00
else
2018-12-09 04:32:58 +01:00
angle = 360 - delta;
2017-11-25 03:27:05 +01:00
break;
2018-11-12 15:04:32 +01:00
case MVMT_FORWARD:
2018-12-09 04:32:58 +01:00
if (angle < 360 - delta)
angle += delta;
2018-11-12 15:04:32 +01:00
else
angle = 0;
2017-11-25 03:27:05 +01:00
break;
}
2018-11-12 15:04:32 +01:00
return angle;
2017-11-25 03:27:05 +01:00
}
2017-11-25 03:37:42 +01:00
2018-11-12 15:04:32 +01:00
static bool32 AdvanceClock(u8 taskId, u8 direction)
2017-11-25 03:37:42 +01:00
{
2018-11-12 15:04:32 +01:00
switch (direction)
2017-11-25 03:37:42 +01:00
{
2018-11-12 15:04:32 +01:00
case MVMT_BACKWARD:
2017-12-16 16:23:05 +01:00
if (gTasks[taskId].tMinutes > 0)
2017-11-25 03:37:42 +01:00
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tMinutes--;
2017-11-25 03:37:42 +01:00
}
else
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tMinutes = 59;
if (gTasks[taskId].tHours > 0)
2017-11-25 03:37:42 +01:00
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tHours--;
2017-11-25 03:37:42 +01:00
}
else
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tHours = 23;
2017-11-25 03:37:42 +01:00
}
2018-11-12 15:04:32 +01:00
UpdateClockPeriod(taskId, direction);
2017-11-25 03:37:42 +01:00
}
break;
2018-11-12 15:04:32 +01:00
case MVMT_FORWARD:
2017-12-16 16:23:05 +01:00
if (gTasks[taskId].tMinutes < 59)
2017-11-25 03:37:42 +01:00
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tMinutes++;
2017-11-25 03:37:42 +01:00
}
else
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tMinutes = 0;
if (gTasks[taskId].tHours < 23)
2017-11-25 03:37:42 +01:00
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tHours++;
2017-11-25 03:37:42 +01:00
}
else
{
2017-12-16 16:23:05 +01:00
gTasks[taskId].tHours = 0;
2017-11-25 03:37:42 +01:00
}
2018-11-12 15:04:32 +01:00
UpdateClockPeriod(taskId, direction);
2017-11-25 03:37:42 +01:00
}
break;
}
return FALSE;
}
2017-11-25 03:52:22 +01:00
2018-11-12 15:04:32 +01:00
static void UpdateClockPeriod(u8 taskId, u8 direction)
2017-11-25 03:52:22 +01:00
{
2017-12-16 16:23:05 +01:00
u8 hours = gTasks[taskId].tHours;
2018-11-12 15:04:32 +01:00
switch (direction)
2017-11-25 03:52:22 +01:00
{
2018-11-12 15:04:32 +01:00
case MVMT_BACKWARD:
2017-11-25 03:52:22 +01:00
switch (hours)
{
case 11:
2018-11-12 15:04:32 +01:00
gTasks[taskId].tPeriod = PERIOD_AM;
2017-11-25 03:52:22 +01:00
break;
case 23:
2018-11-12 15:04:32 +01:00
gTasks[taskId].tPeriod = PERIOD_PM;
2017-11-25 03:52:22 +01:00
break;
}
break;
2018-11-12 15:04:32 +01:00
case MVMT_FORWARD:
2017-11-25 03:52:22 +01:00
switch (hours)
{
case 0:
2018-11-12 15:04:32 +01:00
gTasks[taskId].tPeriod = PERIOD_AM;
2017-11-25 03:52:22 +01:00
break;
case 12:
2018-11-12 15:04:32 +01:00
gTasks[taskId].tPeriod = PERIOD_PM;
2017-11-25 03:52:22 +01:00
break;
}
break;
}
}
2017-11-25 04:08:12 +01:00
2017-12-16 16:23:05 +01:00
static void InitClockWithRtc(u8 taskId)
2017-11-25 04:08:12 +01:00
{
RtcCalcLocalTime();
2017-12-16 16:23:05 +01:00
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;
2017-11-25 04:08:12 +01:00
if (gLocalTime.hours < 12)
{
2018-11-12 15:04:32 +01:00
gTasks[taskId].tPeriod = PERIOD_AM;
2017-11-25 04:08:12 +01:00
}
else
{
2018-11-12 15:04:32 +01:00
gTasks[taskId].tPeriod = PERIOD_PM;
2017-11-25 04:08:12 +01:00
}
}
2017-12-16 16:23:05 +01:00
static void SpriteCB_MinuteHand(struct Sprite *sprite)
2017-11-25 04:08:12 +01:00
{
2017-12-16 16:23:05 +01:00
u16 angle = gTasks[sprite->data[0]].tMinuteHandAngle;
2017-11-25 04:08:12 +01:00
s16 sin = Sin2(angle) / 16;
s16 cos = Cos2(angle) / 16;
2018-11-12 15:04:32 +01:00
u16 xhat, yhat;
2017-12-16 16:23:05 +01:00
2017-11-25 04:08:12 +01:00
SetOamMatrix(0, cos, sin, -sin, cos);
2017-11-25 04:43:05 +01:00
xhat = sClockHandCoords[angle][0];
yhat = sClockHandCoords[angle][1];
2017-12-16 16:23:05 +01:00
2017-11-25 04:08:12 +01:00
if (xhat > 0x80)
{
xhat |= 0xff00;
}
if (yhat > 0x80)
{
yhat |= 0xff00;
}
sprite->pos2.x = xhat;
sprite->pos2.y = yhat;
}
2017-11-25 04:28:13 +01:00
2017-12-16 16:23:05 +01:00
static void SpriteCB_HourHand(struct Sprite *sprite)
2017-11-25 04:28:13 +01:00
{
2017-12-16 16:23:05 +01:00
u16 angle = gTasks[sprite->data[0]].tHourHandAngle;
2017-11-25 04:28:13 +01:00
s16 sin = Sin2(angle) / 16;
s16 cos = Cos2(angle) / 16;
2018-11-12 15:04:32 +01:00
u16 xhat, yhat;
2017-12-16 16:23:05 +01:00
2017-11-25 04:28:13 +01:00
SetOamMatrix(1, cos, sin, -sin, cos);
2017-11-25 04:43:05 +01:00
xhat = sClockHandCoords[angle][0];
yhat = sClockHandCoords[angle][1];
2017-11-25 04:28:13 +01:00
if (xhat > 0x80)
{
xhat |= 0xff00;
}
if (yhat > 0x80)
{
yhat |= 0xff00;
}
sprite->pos2.x = xhat;
sprite->pos2.y = yhat;
}
2017-12-16 16:23:05 +01:00
static void SpriteCB_AMIndicator(struct Sprite *sprite)
2017-11-25 04:28:13 +01:00
{
2017-12-16 16:23:05 +01:00
if (gTasks[sprite->data[0]].tPeriod)
2017-11-25 04:28:13 +01:00
{
2017-12-16 03:04:25 +01:00
if (sprite->data[1] >= 60 && sprite->data[1] < 90)
2017-11-25 04:28:13 +01:00
{
2017-12-16 03:04:25 +01:00
sprite->data[1] += 5;
2017-11-25 04:28:13 +01:00
}
2017-12-16 03:04:25 +01:00
if (sprite->data[1] < 60)
2017-11-25 04:28:13 +01:00
{
2017-12-16 03:04:25 +01:00
sprite->data[1]++;
2017-11-25 04:28:13 +01:00
}
}
else
{
2017-12-16 03:04:25 +01:00
if (sprite->data[1] >= 46 && sprite->data[1] < 76)
2017-11-25 04:28:13 +01:00
{
2017-12-16 03:04:25 +01:00
sprite->data[1] -= 5;
2017-11-25 04:28:13 +01:00
}
2017-12-16 03:04:25 +01:00
if (sprite->data[1] > 75)
2017-11-25 04:28:13 +01:00
{
2017-12-16 03:04:25 +01:00
sprite->data[1]--;
2017-11-25 04:28:13 +01:00
}
}
2017-12-16 03:04:25 +01:00
sprite->pos2.x = Cos2(sprite->data[1]) * 30 / 0x1000;
sprite->pos2.y = Sin2(sprite->data[1]) * 30 / 0x1000;
2017-11-25 04:28:13 +01:00
}
2017-11-25 04:30:20 +01:00
2017-12-16 16:23:05 +01:00
static void SpriteCB_PMIndicator(struct Sprite *sprite)
2017-11-25 04:30:20 +01:00
{
2017-12-16 16:23:05 +01:00
if (gTasks[sprite->data[0]].tPeriod)
2017-11-25 04:30:20 +01:00
{
2017-12-16 03:04:25 +01:00
if (sprite->data[1] >= 105 && sprite->data[1] < 135)
2017-11-25 04:30:20 +01:00
{
2017-12-16 03:04:25 +01:00
sprite->data[1] += 5;
2017-11-25 04:30:20 +01:00
}
2017-12-16 03:04:25 +01:00
if (sprite->data[1] < 105)
2017-11-25 04:30:20 +01:00
{
2017-12-16 03:04:25 +01:00
sprite->data[1]++;
2017-11-25 04:30:20 +01:00
}
}
else
{
2017-12-16 03:04:25 +01:00
if (sprite->data[1] >= 91 && sprite->data[1] < 121)
2017-11-25 04:30:20 +01:00
{
2017-12-16 03:04:25 +01:00
sprite->data[1] -= 5;
2017-11-25 04:30:20 +01:00
}
2017-12-16 03:04:25 +01:00
if (sprite->data[1] > 120)
2017-11-25 04:30:20 +01:00
{
2017-12-16 03:04:25 +01:00
sprite->data[1]--;
2017-11-25 04:30:20 +01:00
}
}
2017-12-16 03:04:25 +01:00
sprite->pos2.x = Cos2(sprite->data[1]) * 30 / 0x1000;
sprite->pos2.y = Sin2(sprite->data[1]) * 30 / 0x1000;
2017-11-25 04:30:20 +01:00
}