static void UpdateWarpType(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
{
    warptype_t new_warptype;
    const iwad_t *iwad;

    // Get the selected IWAD

    iwad = GetCurrentIWAD();

    // Find the new warp type

    if (D_IsEpisodeMap(iwad->mission))
    {
        new_warptype = WARP_ExMy;
    }
    else
    {
        new_warptype = WARP_MAPxy;
    }

    // Reset to E1M1 / MAP01 when the warp type is changed.

    if (new_warptype != warptype)
    {
        warpepisode = 1;
        warpmap = 1;
    }

    warptype = new_warptype;

    UpdateWarpButton();
    UpdateSkillButton();
}
static void IWADSelected(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
{
    iwad_t *iwad;

    // Find the iwad_t selected

    iwad = GetCurrentIWAD();

    // Update iwadfile

    iwadfile = iwad->filename;
}
static void UpdateSkillButton(void)
{
    iwad_t *iwad = GetCurrentIWAD();

    if (iwad->mask == IWAD_CHEX)
    {
        skillbutton->values = chex_skills;
    }
    else
    {
        skillbutton->values = skills;
    }
}
static void UpdateSkillButton(void)
{
    const iwad_t *iwad = GetCurrentIWAD();

    if (IsChexQuest(iwad))
    {
        skillbutton->values = chex_skills;
    }
    else switch(gamemission)
    {
        default:
        case doom:
            skillbutton->values = doom_skills;
            break;

        case heretic:
            skillbutton->values = heretic_skills;
            break;

        case hexen:
            if (character_class == 0)
            {
                skillbutton->values = hexen_fighter_skills;
            }
            else if (character_class == 1)
            {
                skillbutton->values = hexen_cleric_skills;
            }
            else
            {
                skillbutton->values = hexen_mage_skills;
            }
            break;

        case strife:
            skillbutton->values = strife_skills;
            break;
    }
}
static void LevelSelectDialog(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(user_data))
{
    txt_window_t *window;
    txt_table_t *table;
    txt_button_t *button;
    iwad_t *iwad;
    char buf[10];
    int x, y;
    int l;
    int i;

    window = TXT_NewWindow("Select level");

    table = TXT_NewTable(4);

    TXT_AddWidget(window, table);

    if (warptype == WARP_DOOM1)
    {
        // ExMy levels
        
        iwad = GetCurrentIWAD();

        for (i=0; i<4 * 9; ++i)
        {
            x = (i % 4) + 1;
            y = (i / 4) + 1;

            // chex.wad only has E1M1-E1M5.

            if (iwad->mask == IWAD_CHEX && (x > 1 || y > 5))
            {
                continue;
            }

            // doom1.wad only has E1

            if (iwad->mask == IWAD_DOOM1 && x > 1)
            {
                continue;
            }

            sprintf(buf, " E%iM%i ", x, y);
            button = TXT_NewButton(buf);
            TXT_SignalConnect(button, "pressed",
                              SetDoom1Warp, (void *) (x * 10 + y));
            TXT_SignalConnect(button, "pressed",
                              CloseLevelSelectDialog, window);
            TXT_AddWidget(table, button);

            if (warpepisode == x && warpmap == y)
            {
                TXT_SelectWidget(table, button);
            }
        }
    }
    else
    {
        for (i=0; i<32; ++i)
        {
            x = i % 4;
            y = i / 4;

            l = x * 8 + y + 1;
          
            sprintf(buf, " MAP%02i ", l);
            button = TXT_NewButton(buf);
            TXT_SignalConnect(button, "pressed", 
                              SetDoom2Warp, (void *) l);
            TXT_SignalConnect(button, "pressed",
                              CloseLevelSelectDialog, window);
            TXT_AddWidget(table, button);

            if (warpmap == l)
            {
                TXT_SelectWidget(table, button);
            }
        }
    }
}
static void LevelSelectDialog(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(user_data))
{
    txt_window_t *window;
    txt_button_t *button;
    const iwad_t *iwad;
    char buf[10];
    int episodes;
    intptr_t x, y;
    intptr_t l;
    int i;

    window = TXT_NewWindow("Select level");
    iwad = GetCurrentIWAD();

    if (warptype == WARP_ExMy)
    {
        episodes = D_GetNumEpisodes(iwad->mission, iwad->mode);
        TXT_SetTableColumns(window, episodes);

        // ExMy levels

        for (y=1; y<10; ++y)
        {
            for (x=1; x<=episodes; ++x)
            {
                if (IsChexQuest(iwad) && (x > 1 || y > 5))
                {
                    continue;
                }

                if (!D_ValidEpisodeMap(iwad->mission, iwad->mode, x, y))
                {
                    TXT_AddWidget(window, NULL);
                    continue;
                }

                M_snprintf(buf, sizeof(buf),
                           " E%" PRIiPTR "M%" PRIiPTR " ", x, y);
                button = TXT_NewButton(buf);
                TXT_SignalConnect(button, "pressed",
                                  SetExMyWarp, (void *) (x * 10 + y));
                TXT_SignalConnect(button, "pressed",
                                  CloseLevelSelectDialog, window);
                TXT_AddWidget(window, button);

                if (warpepisode == x && warpmap == y)
                {
                    TXT_SelectWidget(window, button);
                }
            }
        }
    }
    else
    {
        TXT_SetTableColumns(window, 6);

        for (i=0; i<60; ++i)
        {
            x = i % 6;
            y = i / 6;

            l = x * 10 + y + 1;

            if (!D_ValidEpisodeMap(iwad->mission, iwad->mode, 1, l))
            {
                TXT_AddWidget(window, NULL);
                continue;
            }

            M_snprintf(buf, sizeof(buf), " MAP%02" PRIiPTR " ", l);
            button = TXT_NewButton(buf);
            TXT_SignalConnect(button, "pressed", 
                              SetMAPxyWarp, (void *) l);
            TXT_SignalConnect(button, "pressed",
                              CloseLevelSelectDialog, window);
            TXT_AddWidget(window, button);

            if (warpmap == l)
            {
                TXT_SelectWidget(window, button);
            }
        }
    }
}