
// Includes
#include "global.h"
#include "alloc.h"
#include "constants/songs.h"
#include "sound.h"
#include "overworld.h"
#include "task.h"
#include "main.h"
#include "link.h"
#include "field_weather.h"
#include "window.h"
#include "palette.h"
#include "event_data.h"
#include "easy_chat.h"
#include "string_util.h"

// Static type declarations

#define EZCHAT_TASK_STATE        0
#define EZCHAT_TASK_KIND         1
#define EZCHAT_TASK_WORDS        2
#define EZCHAT_TASK_MAINCALLBACK 4
#define EZCHAT_TASK_UNK06        6
#define EZCHAT_TASK_SIZE         7

// Static RAM declarations

EWRAM_DATA struct
{
    u8 kind;
    u8 unk_01;
    u8 unk_02;
    u8 unk_03;
    u8 unk_04;
    s8 unk_05;
    s8 unk_06;
    u8 unk_07;
    u8 unk_08;
    u8 unk_09;
    u8 unk_0a;
    u8 unk_0b;
    u8 unk_0c;
    u8 unk_0d;
    u8 unk_0e[0x4];
    u8 sizeParam;
    u8 unk_13;
    u8 unk_14[0x20];
    const u8 *src;
    const u16 *words;
    u16 ecWordBuffer[9];
} *gUnknown_0203A118 = NULL;

EWRAM_DATA void *gUnknown_0203A11C = 0;
EWRAM_DATA void *gUnknown_0203A120 = 0;

// Static ROM declarations

static void sub_811A2C0(u8);
static void sub_811A278(void);
static bool8 sub_811A428(u8);
static void sub_811A2FC(u8);
static void sub_811A4D0(MainCallback);
static bool32 sub_811A88C(u16);
static void sub_811A8A4(u16);
void sub_811A8F0(void);
static bool8 EasyChat_AllocateResources(u8, u16 *, u8);
static void EasyChat_FreeResources(void);
static u16 sub_811AAAC(void);
static u16 sub_811AB68(void);
u16 sub_811ACDC(void);
u16 sub_811AE44(void);
u16 sub_811AF00(void);
u16 sub_811AF8C(void);
u16 sub_811AFEC(void);
u16 sub_811B040(void);
u16 sub_811B08C(void);
u16 sub_811B0BC(void);
u16 sub_811B0E8(void);
u16 sub_811B0F8(void);
u16 sub_811B150(void);
u16 sub_811B1B4(void);
u8 sub_811BA68(void);
u8 sub_811BCC8(u8);
void sub_811BDF0(u8 *);
void sub_811BF78(void);
bool8 sub_811BF8C(void);
bool8 sub_811BFA4(void);
void sub_811C13C(void);
/*static*/ void sub_811C158(u16);
/*static*/ bool8 sub_811C170(void);
bool8 sub_811F28C(void);
void sub_811F2B8(void);
u8 sub_811F3AC(void);

// .rodata

extern const struct {
    u16 word;
    MainCallback callback;
} gUnknown_08597530[4];
extern const struct {
    u8 unk_00;
    u8 unk_01;
    u8 unk_02;
    u8 unk_03;
    u8 *data;
    u8 filler_08[16];
} gUnknown_08597550[];

// .text

void sub_811A20C(u8 kind, u16 *words, MainCallback callback, u8 sizeParam)
{
    u8 taskId;

    ResetTasks();
    taskId = CreateTask(sub_811A2C0, 0);
    gTasks[taskId].data[EZCHAT_TASK_KIND] = kind;
    gTasks[taskId].data[EZCHAT_TASK_SIZE] = sizeParam;
    SetWordTaskArg(taskId, EZCHAT_TASK_WORDS, (u32)words);
    SetWordTaskArg(taskId, EZCHAT_TASK_MAINCALLBACK, (u32)callback);
    SetMainCallback2(sub_811A278);
}

static void sub_811A278(void)
{
    RunTasks();
    AnimateSprites();
    BuildOamBuffer();
    UpdatePaletteFade();
}

static void sub_811A290(void)
{
    TransferPlttBuffer();
    LoadOam();
    ProcessSpriteCopyRequests();
}

static void sub_811A2A4(u8 taskId, TaskFunc taskFunc)
{
    gTasks[taskId].func = taskFunc;
    gTasks[taskId].data[EZCHAT_TASK_STATE] = 0;
}

static void sub_811A2C0(u8 taskId)
{
    if (!is_c1_link_related_active())
    {
        while (sub_811A428(taskId));
    }
    else
    {
        if (sub_811A428(taskId) == TRUE)
        {
            return;
        }
    }
    sub_811A2A4(taskId, sub_811A2FC);
}

static void sub_811A2FC(u8 taskId)
{
    u16 v0;
    s16 *data;

    data = gTasks[taskId].data;
    switch (data[EZCHAT_TASK_STATE])
    {
    case 0:
        SetVBlankCallback(sub_811A290);
        BlendPalettes(0xFFFFFFFF, 16, 0);
        BeginNormalPaletteFade(-1, -1, 16, 0, 0);
        data[EZCHAT_TASK_STATE] = 5;
        break;
    case 1:
        v0 = sub_811AAAC();
        if (sub_811A88C(v0))
        {
            BeginNormalPaletteFade(-1, -2, 0, 16, 0);
            data[EZCHAT_TASK_STATE] = 3;
            data[EZCHAT_TASK_UNK06] = v0;
        }
        else if (v0 == 0x18)
        {
            BeginNormalPaletteFade(-1, -1, 0, 16, 0);
            data[EZCHAT_TASK_STATE] = 4;
        }
        else if (v0 != 0)
        {
            PlaySE(SE_SELECT);
            sub_811C158(v0);
            data[EZCHAT_TASK_STATE] ++;
        }
        break;
    case 2:
        if (!sub_811C170())
        {
            data[EZCHAT_TASK_STATE] = 1;
        }
        break;
    case 3:
        if (!gPaletteFade.active)
        {
            sub_811A8A4(data[EZCHAT_TASK_UNK06]);
        }
        break;
    case 4:
        if (!gPaletteFade.active)
        {
            sub_811A4D0((MainCallback)GetWordTaskArg(taskId, EZCHAT_TASK_MAINCALLBACK));
        }
        break;
    case 5:
        if (!gPaletteFade.active)
        {
            data[EZCHAT_TASK_STATE] = 1;
        }
        break;
    }
}

static bool8 sub_811A428(u8 taskId)
{
    s16 *data;

    data = gTasks[taskId].data;
    switch (data[EZCHAT_TASK_STATE])
    {
    case 0:
        SetVBlankCallback(NULL);
        ResetSpriteData();
        FreeAllSpritePalettes();
        ResetPaletteFade();
        break;
    case 1:
        if (!sub_811F28C())
        {
            sub_811A4D0((MainCallback)GetWordTaskArg(taskId, EZCHAT_TASK_MAINCALLBACK));
        }
        break;
    case 2:
        if (!EasyChat_AllocateResources(data[EZCHAT_TASK_KIND], (u16 *)GetWordTaskArg(taskId, EZCHAT_TASK_WORDS), data[EZCHAT_TASK_SIZE]))
        {
            sub_811A4D0((MainCallback)GetWordTaskArg(taskId, EZCHAT_TASK_MAINCALLBACK));
        }
        break;
    case 3:
        if (!sub_811BF8C())
        {
            sub_811A4D0((MainCallback)GetWordTaskArg(taskId, EZCHAT_TASK_MAINCALLBACK));
        }
        break;
    case 4:
        if (sub_811BFA4())
        {
            return TRUE;
        }
        break;
    default:
        return FALSE;
    }
    data[EZCHAT_TASK_STATE] ++;
    return TRUE;
}

static void sub_811A4D0(MainCallback callback)
{
    sub_811C13C();
    EasyChat_FreeResources();
    sub_811F2B8();
    FreeAllWindowBuffers();
    SetMainCallback2(callback);
}

void easy_chat_input_maybe(void)
{
    int i;
    u16 *words;
    struct MauvilleManBard *bard;
    u8 sizeParam = 3;
    switch (gSpecialVar_0x8004)
    {
    case 0:
        words = gSaveBlock1Ptr->unk2BB0;
        break;
    case 1:
        words = gSaveBlock1Ptr->unk2BBC;
        break;
    case 2:
        words = gSaveBlock1Ptr->unk2BC8;
        break;
    case 3:
        words = gSaveBlock1Ptr->unk2BD4;
        break;
    case 4:
        words = gSaveBlock1Ptr->mail[gSpecialVar_0x8005].words;
        break;
    case 6:
        bard = &gSaveBlock1Ptr->oldMan.bard;
        for (i = 0; i < 6; i ++)
        {
            bard->temporaryLyrics[i] = bard->songLyrics[i];
        }
        words = bard->temporaryLyrics;
        break;
    case 5:
        words = gSaveBlock1Ptr->tvShows[gSpecialVar_0x8005].bravoTrainer.words;
        sizeParam = gSpecialVar_0x8006;
        break;
    case 7:
        words = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8005].fanclubOpinions.words[gSpecialVar_0x8006];
        sizeParam = 1;
        break;
    case 8:
        words = gSaveBlock1Ptr->tvShows[gSpecialVar_0x8005].unkShow04.words;
        sizeParam = 0;
        break;
    case 9:
        words = (u16 *)gStringVar3;
        words[0] = gSaveBlock1Ptr->easyChatPairs[0].words[0];
        words[1] = gSaveBlock1Ptr->easyChatPairs[0].words[1];
        break;
    case 10:
        words = gSaveBlock1Ptr->gabbyAndTyData.quote;
        *words = -1;
        sizeParam = 1;
        break;
    case 11:
        words = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8005].bravoTrainer.words[gSpecialVar_0x8006];
        sizeParam = 0;
        break;
    case 12:
        words = gSaveBlock1Ptr->tvShows[gSpecialVar_0x8005].fanclubOpinions.words18;
        sizeParam = 1;
        break;
    case 13:
        words = (u16 *)gStringVar3;
        InitializeEasyChatWordArray(words, 2);
        break;
    case 14:
        words = gSaveBlock1Ptr->tvShows[gSpecialVar_0x8005].fanClubSpecial.words;
        words[0] = -1;
        sizeParam = 2;
        break;
    case 15:
        words = &gSaveBlock1Ptr->lilycoveLady.quiz.unk_016;
        break;
    case 16:
        return;
    case 17:
        words = gSaveBlock1Ptr->lilycoveLady.quiz.unk_002;
        break;
    case 18:
        words = &gSaveBlock1Ptr->lilycoveLady.quiz.unk_014;
        break;
    case 19:
        words = gSaveBlock2Ptr->apprentices[0].easyChatWords;
        break;
    case 20:
        words = sub_801B058();
        break;
    default:
        return;
    }
    CleanupOverworldWindowsAndTilemaps();
    sub_811A20C(gSpecialVar_0x8004, words, CB2_ReturnToFieldContinueScript, sizeParam);
}

static void sub_811A7E4(void)
{
    LilycoveLady *lilycoveLady;

    UpdatePaletteFade();
    switch (gMain.state)
    {
    case 0:
        FadeScreen(1, 0);
        break;
    case 1:
        if (!gPaletteFade.active)
        {
            lilycoveLady = &gSaveBlock1Ptr->lilycoveLady;
            lilycoveLady->quiz.unk_016 = -1;
            CleanupOverworldWindowsAndTilemaps();
            sub_811A8F0();
        }
        return;
    }
    gMain.state ++;
}

void sub_811A858(void)
{
    SetMainCallback2(sub_811A7E4);
}

static int sub_811A868(u16 word)
{
    int i;

    for (i = 0; i < ARRAY_COUNT(gUnknown_08597530); i ++)
    {
        if (word == gUnknown_08597530[i].word)
            return i;
    }
    return -1;
}

static bool32 sub_811A88C(u16 word)
{
    return sub_811A868(word) == -1 ? FALSE : TRUE;
}

static void sub_811A8A4(u16 word)
{
    int i;

    i = sub_811A868(word);
    ResetTasks();
    sub_811A4D0(gUnknown_08597530[i].callback);
}

void sub_811A8CC(void)
{
    sub_811A20C(0xF, &gSaveBlock1Ptr->lilycoveLady.quiz.unk_016, CB2_ReturnToFieldContinueScript, 3);
}

void sub_811A8F0(void)
{
    sub_811A20C(0x10, gSaveBlock1Ptr->lilycoveLady.quiz.unk_002, CB2_ReturnToFieldContinueScript, 3);
}

void sub_811A914(void)
{
    sub_811A20C(0x12, &gSaveBlock1Ptr->lilycoveLady.quiz.unk_014, CB2_ReturnToFieldContinueScript, 3);
}

void sub_811A938(void)
{
    sub_811A20C(0x11, gSaveBlock1Ptr->lilycoveLady.quiz.unk_002, CB2_ReturnToFieldContinueScript, 3);
}

static bool8 EasyChat_AllocateResources(u8 kind, u16 *words, u8 sizeParam)
{
    u8 r6;
    int i;

    gUnknown_0203A118 = malloc(sizeof(*gUnknown_0203A118));
    if (gUnknown_0203A118 == NULL)
    {
        return FALSE;
    }
    gUnknown_0203A118->kind = kind;
    gUnknown_0203A118->words = words;
    gUnknown_0203A118->unk_05 = 0;
    gUnknown_0203A118->unk_06 = 0;
    gUnknown_0203A118->unk_09 = 0;
    gUnknown_0203A118->sizeParam = sizeParam;
    gUnknown_0203A118->unk_13 = 0;
    r6 = sub_811BCC8(kind);
    if (kind == 0x10)
    {
        sub_811BDF0(gUnknown_0203A118->unk_14);
        gUnknown_0203A118->src = gUnknown_0203A118->unk_14;
        gUnknown_0203A118->unk_04 = 7;
    }
    else
    {
        gUnknown_0203A118->unk_04 = 0;
        gUnknown_0203A118->src = gUnknown_08597550[r6].data;
    }
    gUnknown_0203A118->unk_02 = gUnknown_08597550[r6].unk_01;
    gUnknown_0203A118->unk_03 = gUnknown_08597550[r6].unk_02;
    gUnknown_0203A118->unk_07 = gUnknown_0203A118->unk_02 * gUnknown_0203A118->unk_03;
    gUnknown_0203A118->unk_01 = r6;
    if (gUnknown_0203A118->unk_07 > 9)
    {
        gUnknown_0203A118->unk_07 = 9;
    }
    if (words != NULL)
    {
        CpuCopy16(words, gUnknown_0203A118->ecWordBuffer, gUnknown_0203A118->unk_07 * sizeof(u16));
    }
    else
    {
        for (i = 0; i < gUnknown_0203A118->unk_07; i ++)
        {
            gUnknown_0203A118->ecWordBuffer[i] = -1;
        }
        gUnknown_0203A118->words = gUnknown_0203A118->ecWordBuffer;
    }
    gUnknown_0203A118->unk_0d = (sub_811F3AC() - 1) / 2 + 1;
    return TRUE;
}

static void EasyChat_FreeResources(void)
{
    if (gUnknown_0203A118 != NULL)
        FREE_AND_SET_NULL(gUnknown_0203A118);
}

static u16 sub_811AAAC(void)
{
    switch (gUnknown_0203A118->unk_04)
    {
    case 0:
        return sub_811AB68();
    case 1:
        return sub_811ACDC();
    case 2:
        return sub_811AE44();
    case 3:
        return sub_811AF00();
    case 4:
        return sub_811AF8C();
    case 5:
        return sub_811B040();
    case 6:
        return sub_811AFEC();
    case 7:
        return sub_811B08C();
    case 8:
        return sub_811B0BC();
    case 9:
        return sub_811B0E8();
    case 10:
        return sub_811B0F8();
    }
    return 0;
}

bool32 sub_811AB44(void)
{
    switch (sub_811BA68())
    {
    case 2:
    case 7:
    case 8:
        return TRUE;
    }
    return FALSE;
}

#ifdef NONMATCHING
static u16 sub_811AB68(void)
{
    if (gMain.newKeys & A_BUTTON)
    {
        sub_811BF78();
        gUnknown_0203A118->unk_04 = 2;
        gUnknown_0203A118->unk_0a = 0;
        gUnknown_0203A118->unk_0b = 0;
        gUnknown_0203A118->unk_0c = 0;
        return 9;
    }
    else if (gMain.newKeys & B_BUTTON)
    { // FIXME: See note below
        return sub_811B150();
    }
    else if (gMain.newKeys & START_BUTTON)
    { // FIXME: See note below
        return sub_811B1B4();
    }
    else if (gMain.newKeys & DPAD_UP)
    {
        gUnknown_0203A118->unk_06--;
    }
    else if (gMain.newKeys & DPAD_LEFT)
    { // FIXME: See note below
        gUnknown_0203A118->unk_05--;
    }
    else if (gMain.newKeys & DPAD_DOWN)
    { // FIXME: See note below
        gUnknown_0203A118->unk_06++;
    }
    else if (gMain.newKeys & DPAD_RIGHT)
    { // FIXME: See note below
        gUnknown_0203A118->unk_05++;
    }
    else
    {
        return 0;
    }
    if (gUnknown_0203A118->unk_06 < 0)
    {
        gUnknown_0203A118->unk_06 = gUnknown_08597550[gUnknown_0203A118->unk_01].unk_02;
    }
    if (gUnknown_0203A118->unk_06 > gUnknown_08597550[gUnknown_0203A118->unk_01].unk_02)
    {
        gUnknown_0203A118->unk_06 = 0;
    }
    if (gUnknown_0203A118->unk_06 == gUnknown_08597550[gUnknown_0203A118->unk_01].unk_02)
    {
        if (gUnknown_0203A118->unk_05 > 2)
        {
            gUnknown_0203A118->unk_05 = 2;
        }
        gUnknown_0203A118->unk_04 = 1;
        return 3;
    }
    /*
     * FIXME: right, down, left, b, and start
     * should be inserted here, but aren't
     */
    if (gUnknown_0203A118->unk_05 < 0)
    {
        gUnknown_0203A118->unk_05 = gUnknown_08597550[gUnknown_0203A118->unk_01].unk_01 - 1;
    }
    if (gUnknown_0203A118->unk_05 >= gUnknown_08597550[gUnknown_0203A118->unk_01].unk_01)
    {
        gUnknown_0203A118->unk_05 = 0;
    }
    if (sub_811AB44() && gUnknown_0203A118->unk_05 == 1 && gUnknown_0203A118->unk_06 == 4)
    {
        gUnknown_0203A118->unk_05 = 0;
    }
    return 2;
}
#else
__attribute__((naked)) static u16 sub_811AB68(void)
{
    asm_unified("\tpush {r4-r7,lr}\n"
                    "\tldr r0, =gMain\n"
                    "\tldrh r1, [r0, 0x2E]\n"
                    "\tmovs r0, 0x1\n"
                    "\tands r0, r1\n"
                    "\tcmp r0, 0\n"
                    "\tbeq _0811ABB8\n"
                    "\tbl sub_811BF78\n"
                    "\tldr r1, =gUnknown_0203A118\n"
                    "\tldr r3, [r1]\n"
                    "\tmovs r2, 0\n"
                    "\tmovs r0, 0x2\n"
                    "\tstrb r0, [r3, 0x4]\n"
                    "\tldr r0, [r1]\n"
                    "\tstrb r2, [r0, 0xA]\n"
                    "\tldr r0, [r1]\n"
                    "\tstrb r2, [r0, 0xB]\n"
                    "\tldr r0, [r1]\n"
                    "\tstrb r2, [r0, 0xC]\n"
                    "\tmovs r0, 0x9\n"
                    "\tb _0811ACCC_return_r0\n"
                    "\t.pool\n"
                    "_0811AB9C:\n"
                    "\tmovs r0, 0x20\n"
                    "\tands r0, r1\n"
                    "\tcmp r0, 0\n"
                    "\tbne _0811AC68_dpad_left\n"
                    "\tmovs r0, 0x80\n"
                    "\tands r0, r1\n"
                    "\tcmp r0, 0\n"
                    "\tbne _0811AC58_dpad_down\n"
                    "\tmovs r0, 0x10\n"
                    "\tands r0, r1\n"
                    "\tcmp r0, 0\n"
                    "\tbne _0811AC48_dpad_right\n"
                    "\tmovs r0, 0\n"
                    "\tb _0811ACCC_return_r0\n"
                    "_0811ABB8:\n"
                    "\tmovs r0, 0x2\n"
                    "\tands r0, r1\n"
                    "\tcmp r0, 0\n"
                    "\tbne _0811AC78_b_button\n"
                    "\tmovs r0, 0x8\n"
                    "\tands r0, r1\n"
                    "\tcmp r0, 0\n"
                    "\tbne _0811AC7E_start_button\n"
                    "\tmovs r0, 0x40\n"
                    "\tands r0, r1\n"
                    "\tcmp r0, 0\n"
                    "\tbeq _0811AB9C\n"
                    "\tldr r2, =gUnknown_0203A118\n"
                    "\tldr r1, [r2]\n"
                    "\tldrb r0, [r1, 0x6]\n"
                    "\tsubs r0, 0x1\n"
                    "_0811ABD8:\n"
                    "\tstrb r0, [r1, 0x6]\n"
                    "_0811ABDA:\n"
                    "\tadds r7, r2, 0\n"
                    "\tadds r4, r7, 0\n"
                    "\tldr r2, [r4]\n"
                    "\tmovs r0, 0x6\n"
                    "\tldrsb r0, [r2, r0]\n"
                    "\tldr r6, =gUnknown_08597550\n"
                    "\tcmp r0, 0\n"
                    "\tbge _0811ABF8\n"
                    "\tldrb r0, [r2, 0x1]\n"
                    "\tlsls r1, r0, 1\n"
                    "\tadds r1, r0\n"
                    "\tlsls r1, 3\n"
                    "\tadds r1, r6\n"
                    "\tldrb r0, [r1, 0x2]\n"
                    "\tstrb r0, [r2, 0x6]\n"
                    "_0811ABF8:\n"
                    "\tldr r3, [r4]\n"
                    "\tmovs r2, 0x6\n"
                    "\tldrsb r2, [r3, r2]\n"
                    "\tadds r5, r6, 0\n"
                    "\tldrb r1, [r3, 0x1]\n"
                    "\tlsls r0, r1, 1\n"
                    "\tadds r0, r1\n"
                    "\tlsls r0, 3\n"
                    "\tadds r0, r5\n"
                    "\tldrb r0, [r0, 0x2]\n"
                    "\tcmp r2, r0\n"
                    "\tble _0811AC14\n"
                    "\tmovs r0, 0\n"
                    "\tstrb r0, [r3, 0x6]\n"
                    "_0811AC14:\n"
                    "\tldr r3, [r4]\n"
                    "\tmovs r2, 0x6\n"
                    "\tldrsb r2, [r3, r2]\n"
                    "\tldrb r1, [r3, 0x1]\n"
                    "\tlsls r0, r1, 1\n"
                    "\tadds r0, r1\n"
                    "\tlsls r0, 3\n"
                    "\tadds r1, r0, r5\n"
                    "\tldrb r0, [r1, 0x2]\n"
                    "\tcmp r2, r0\n"
                    "\tbne _0811AC88\n"
                    "\tmovs r0, 0x5\n"
                    "\tldrsb r0, [r3, r0]\n"
                    "\tcmp r0, 0x2\n"
                    "\tble _0811AC36\n"
                    "\tmovs r0, 0x2\n"
                    "\tstrb r0, [r3, 0x5]\n"
                    "_0811AC36:\n"
                    "\tldr r1, [r4]\n"
                    "\tmovs r0, 0x1\n"
                    "\tstrb r0, [r1, 0x4]\n"
                    "\tmovs r0, 0x3\n"
                    "\tb _0811ACCC_return_r0\n"
                    "\t.pool\n"
                    "_0811AC48_dpad_right:\n"
                    "\tldr r2, =gUnknown_0203A118\n"
                    "\tldr r1, [r2]\n"
                    "\tldrb r0, [r1, 0x5]\n"
                    "\tadds r0, 0x1\n"
                    "\tstrb r0, [r1, 0x5]\n"
                    "\tb _0811ABDA\n"
                    "\t.pool\n"
                    "_0811AC58_dpad_down:\n"
                    "\tldr r2, =gUnknown_0203A118\n"
                    "\tldr r1, [r2]\n"
                    "\tldrb r0, [r1, 0x6]\n"
                    "\tadds r0, 0x1\n"
                    "\tb _0811ABD8\n"
                    "\t.pool\n"
                    "_0811AC68_dpad_left:\n"
                    "\tldr r2, =gUnknown_0203A118\n"
                    "\tldr r1, [r2]\n"
                    "\tldrb r0, [r1, 0x5]\n"
                    "\tsubs r0, 0x1\n"
                    "\tstrb r0, [r1, 0x5]\n"
                    "\tb _0811ABDA\n"
                    "\t.pool\n"
                    "_0811AC78_b_button:\n"
                    "\tbl sub_811B150\n"
                    "\tb _0811AC82\n"
                    "_0811AC7E_start_button:\n"
                    "\tbl sub_811B1B4\n"
                    "_0811AC82:\n"
                    "\tlsls r0, 16\n"
                    "\tlsrs r0, 16\n"
                    "\tb _0811ACCC_return_r0\n"
                    "_0811AC88:\n"
                    "\tmovs r0, 0x5\n"
                    "\tldrsb r0, [r3, r0]\n"
                    "\tcmp r0, 0\n"
                    "\tbge _0811AC96\n"
                    "\tldrb r0, [r1, 0x1]\n"
                    "\tsubs r0, 0x1\n"
                    "\tstrb r0, [r3, 0x5]\n"
                    "_0811AC96:\n"
                    "\tldr r3, [r4]\n"
                    "\tmovs r2, 0x5\n"
                    "\tldrsb r2, [r3, r2]\n"
                    "\tldrb r1, [r3, 0x1]\n"
                    "\tlsls r0, r1, 1\n"
                    "\tadds r0, r1\n"
                    "\tlsls r0, 3\n"
                    "\tadds r0, r6\n"
                    "\tldrb r0, [r0, 0x1]\n"
                    "\tcmp r2, r0\n"
                    "\tblt _0811ACB0\n"
                    "\tmovs r0, 0\n"
                    "\tstrb r0, [r3, 0x5]\n"
                    "_0811ACB0:\n"
                    "\tbl sub_811AB44\n"
                    "\tcmp r0, 0\n"
                    "\tbeq _0811ACCA\n"
                    "\tldr r2, [r7]\n"
                    "\tldr r0, [r2, 0x4]\n"
                    "\tldr r1, =0x00ffff00\n"
                    "\tands r0, r1\n"
                    "\tldr r1, =0x00040100\n"
                    "\tcmp r0, r1\n"
                    "\tbne _0811ACCA\n"
                    "\tmovs r0, 0\n"
                    "\tstrb r0, [r2, 0x5]\n"
                    "_0811ACCA:\n"
                    "\tmovs r0, 0x2\n"
                    "_0811ACCC_return_r0:\n"
                    "\tpop {r4-r7}\n"
                    "\tpop {r1}\n"
                    "\tbx r1\n"
                    "\t.pool");
}
#endif
