trngaje / SDL_drastic

Simple Directmedia Layer
https://libsdl.org
zlib License
0 stars 0 forks source link

hook create_menu_extra_controls #4

Open trngaje opened 2 months ago

trngaje commented 2 months ago

unsigned char ** sdl_create_menu_extra_controls(long param_1,unsigned long param_2,code *param_3)
{
    int iVar1;
    long lVar2;
    uint uVar3;
    unsigned int uVar4;
    unsigned char **ppcVar5;
    unsigned char *pcVar6;
    unsigned long *puVar7;
    char **ppcVar8;
    char **ppcVar9;
    long lVar10;
    long lVar11;
    unsigned char *puVar12;
    long lVar13;

    lVar11 = *(long *)(param_1 + 8);
    ppcVar5 = (unsigned char **)malloc(0x30);
    *(unsigned long *)((long)ppcVar5 + 0x14) = 0x18;
    *ppcVar5 = draw_menu_controls;
    ppcVar5[1] = focus_menu_none;
    lVar13 = 0;
    ppcVar5[5] = param_3;
    pcVar6 = (unsigned char *)malloc(0xc0);
    ppcVar5[4] = pcVar6;
    do {
        while( true ) {
            uVar3 = (&options_to_config_map.11558)[lVar13];
            iVar1 = (int)lVar13 + 0x1e;
            puVar12 = (&input_names.11557)[lVar13];
            puVar7 = (unsigned long *)malloc(0x50);
            lVar10 = ((ulong)uVar3 + 0x262) * 2;
            lVar2 = lVar11 + lVar10;
            lVar10 = lVar11 + lVar10 + 0x52;
            if (puVar7 != (unsigned long *)0x0) break;
            puVar7 = (unsigned long *)malloc(0x30);
            *(unsigned long *)(pcVar6 + lVar13 * 8) = 0;
            lVar13 = lVar13 + 1;
            *puVar7 = puVar12;
            *(int *)(puVar7 + 1) = iVar1;
            puVar7[4] = 0;
            puVar7[5] = 0;
            puVar7[2] = draw_button_config;
            puVar7[3] = action_button_config;
                    /* WARNING: Read-only address (ram,0x00000038) is written */
                    /* WARNING: Read-only address (ram,0x00000040) is written */
                    /* WARNING: Read-only address (ram,0x00000048) is written */
            Elf64_Phdr_ARRAY_00000040[0].p_offset._0_1_ = 0;
            Elf64_Ehdr_00000000._56_8_ = lVar2;
            Elf64_Phdr_ARRAY_00000040[0]._0_8_ = lVar10;
            if (lVar13 == 0x14) goto LAB_00092358;
        }
        *(unsigned long **)(pcVar6 + lVar13 * 8) = puVar7;
        lVar13 = lVar13 + 1;
        *puVar7 = puVar12;
        *(int *)(puVar7 + 1) = iVar1;
        puVar7[4] = 0;
        puVar7[5] = 0;
        puVar7[7] = lVar2;
        puVar7[8] = lVar10;
        puVar7[2] = draw_button_config;
        puVar7[3] = action_button_config;
        *(unsigned char *)(puVar7 + 9) = 0;
    } while (lVar13 != 0x14);
    LAB_00092358:
    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *ppcVar9 = "Restore default controls";
    *(unsigned int *)(ppcVar9 + 1) = 0x33;
    ppcVar9[2] = (char *)draw_menu_option;
    ppcVar9[3] = (char *)action_select;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar8[6] = (char *)select_restore_default_controls;
    *(char ***)(pcVar6 + 0xa0) = ppcVar8;
    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *ppcVar9 = "Delete game-specific config";
    *(unsigned int *)(ppcVar9 + 1) = 0x34;
    ppcVar9[2] = (char *)draw_menu_option;
    ppcVar9[3] = (char *)action_select;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar8[6] = (char *)select_delete_config_local;
    *(char ***)(pcVar6 + 0xa8) = ppcVar8;
    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *ppcVar9 = "Exit: save for all games";
    *(unsigned int *)(ppcVar9 + 1) = 0x36;
    ppcVar9[2] = (char *)draw_menu_option;
    ppcVar9[3] = (char *)action_select;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar8[6] = (char *)select_save_config_global;
    *(char ***)(pcVar6 + 0xb0) = ppcVar8;
    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *(char ***)(pcVar6 + 0xb8) = ppcVar8;
    *ppcVar9 = "Exit without saving";
    *(unsigned int *)(ppcVar9 + 1) = 0x37;
    ppcVar9[2] = (char *)draw_menu_option;
    ppcVar9[3] = (char *)action_select;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar8[6] = (char *)select_exit_current_menu;
    *(unsigned int *)(param_1 + 0x164) = 0;
    uVar4 = 0xd8;
    if (*(int *)(param_1 + 0x40) != 0) {
        uVar4 = 0x38;
    }
    *(unsigned int *)(ppcVar5 + 2) = uVar4;
    return ppcVar5;
}
trngaje commented 2 months ago

32bit 는 아래와 같음

menu_struct *
create_menu_extra_controls
          (menu_state_struct *menu_state,menu_struct *parent_menu,menu_struct *grandparent_menu)

{
  menu_struct *pmVar1;
  menu_struct *menu;
  void *pvVar2;
  undefined4 *puVar3;
  undefined4 *puVar4;
  char **ppcVar5;
  char **ppcVar6;
  undefined4 uVar7;
  int iVar8;
  u32 config_index;
  int *piVar9;
  void **ppvVar10;
  undefined4 *puVar11;
  config_struct *config;
  config_struct *pcVar12;
  int iVar13;
  u32 uVar14;

  pcVar12 = menu_state->config;
  piVar9 = (int *)&DAT_0813f3bc;
  iVar13 = 0x1e;
  pmVar1 = (menu_struct *)malloc(0x20);
  *(code **)pmVar1 = draw_menu_controls;
  *(code **)&pmVar1->field_0x4 = focus_menu_none;
  *(undefined4 *)&pmVar1->field_0xc = 0x17;
  puVar11 = (undefined4 *)&UNK_0813f40c;
  *(undefined4 *)&pmVar1->field_0x10 = 0;
  *(menu_struct **)&pmVar1->field_0x1c = grandparent_menu;
  pvVar2 = malloc(0x5c);
  ppvVar10 = (void **)((int)pvVar2 + -4);
  *(void **)&pmVar1->field_0x18 = pvVar2;
  do {
    piVar9 = piVar9 + 1;
    iVar8 = *piVar9;
    puVar11 = puVar11 + 1;
    uVar7 = *puVar11;
    puVar3 = (undefined4 *)malloc(0x28);
    puVar4 = puVar3;
    if (puVar3 == (undefined4 *)0x0) {
      puVar4 = (undefined4 *)malloc(0x18);
    }
    ppvVar10 = ppvVar10 + 1;
    *ppvVar10 = puVar3;
    *puVar4 = uVar7;
    puVar4[1] = iVar13;
    iVar13 = iVar13 + 1;
    puVar4[2] = draw_button_config;
    puVar4[4] = 0;
    puVar4[5] = 0;
    puVar4[3] = action_button_config;
    puVar3[7] = pcVar12->controls_a + iVar8;
    puVar3[8] = pcVar12->controls_b + iVar8;
    *(undefined *)(puVar3 + 9) = 0;
  } while (iVar13 != 0x31);
  ppcVar5 = (char **)malloc(0x1c);
  ppcVar6 = ppcVar5;
  if (ppcVar5 == (char **)0x0) {
    ppcVar6 = (char **)malloc(0x18);
  }
  *ppcVar6 = "Restore default controls";
  *(char ***)((int)pvVar2 + 0x4c) = ppcVar5;
  ppcVar6[1] = (char *)0x32;
  ppcVar6[2] = (char *)draw_menu_option;
  ppcVar6[3] = (char *)action_select;
  ppcVar6[4] = (char *)0x0;
  ppcVar6[5] = (char *)0x0;
  ppcVar5[6] = (char *)select_restore_default_controls;
  ppcVar5 = (char **)malloc(0x1c);
  ppcVar6 = ppcVar5;
  if (ppcVar5 == (char **)0x0) {
    ppcVar6 = (char **)malloc(0x18);
  }
  ppcVar6[3] = (char *)action_select;
  *ppcVar6 = "Delete game-specific config";
  ppcVar6[1] = (char *)0x33;
  ppcVar6[2] = (char *)draw_menu_option;
  ppcVar6[4] = (char *)0x0;
  ppcVar6[5] = (char *)0x0;
  ppcVar5[6] = (char *)select_delete_config_local;
  *(char ***)((int)pvVar2 + 0x50) = ppcVar5;
  ppcVar5 = (char **)malloc(0x1c);
  ppcVar6 = ppcVar5;
  if (ppcVar5 == (char **)0x0) {
    ppcVar6 = (char **)malloc(0x18);
  }
  ppcVar6[3] = (char *)action_select;
  *ppcVar6 = "Exit: save for all games";
  ppcVar6[1] = (char *)0x35;
  ppcVar6[2] = (char *)draw_menu_option;
  ppcVar6[4] = (char *)0x0;
  ppcVar6[5] = (char *)0x0;
  ppcVar5[6] = (char *)select_save_config_global;
  *(char ***)((int)pvVar2 + 0x54) = ppcVar5;
  ppcVar5 = (char **)malloc(0x1c);
  ppcVar6 = ppcVar5;
  if (ppcVar5 == (char **)0x0) {
    ppcVar6 = (char **)malloc(0x18);
  }
  *ppcVar6 = "Exit without saving";
  *(char ***)((int)pvVar2 + 0x58) = ppcVar5;
  uVar14 = menu_state->game_loaded_on_entry;
  menu_state->column_select = 0;
  ppcVar6[1] = (char *)0x36;
  ppcVar6[2] = (char *)draw_menu_option;
  ppcVar6[3] = (char *)action_select;
  ppcVar6[4] = (char *)0x0;
  ppcVar6[5] = (char *)0x0;
  if (uVar14 == 0) {
    uVar7 = 0xd8;
  }
  else {
    uVar7 = 0x38;
  }
  ppcVar5[6] = (char *)select_exit_current_menu;
  *(undefined4 *)&pmVar1->field_0x8 = uVar7;
  *(undefined4 *)&pmVar1->field_0xc = 0x17;
  return pmVar1;
}
trngaje commented 2 months ago
                                 LAB_000925d0                                            XREF[2]:       000925a0(j), 00092638(j)  
           000925d0 33 7b 7b b8       ldr          w19,[x25, x27, LSL #0x2]=>options_to_config_map.11575    = 00000001h
           000925d4 00 0a 80 d2       mov          x0,#0x50
           000925d8 76 7b 00 11       add          w22,w27,#0x1e
           000925dc 57 7b 7b f8       ldr          x23,[x26, x27, LSL #0x3]=>input_names.11574              = 00135ec0
                                                                                                            = 00135ed8
           000925e0 30 ee fd 97       bl           <EXTERNAL>::malloc                                       void * malloc(size_t __size)
           000925e4 e1 03 00 aa       mov          x1,x0
           000925e8 73 8a 09 91       add          x19,x19,#0x262
           000925ec 73 fa 7f d3       lsl          x19,x19,#0x1
           000925f0 74 4a 01 91       add          x20,x19,#0x52
           000925f4 b3 02 13 8b       add          x19,x21,x19
           000925f8 b4 02 14 8b       add          x20,x21,x20
           000925fc 40 fd ff b5       cbnz         x0,LAB_000925a4
           00092600 00 06 80 d2       mov          x0,#0x30
           00092604 a1 43 00 f9       str          x1,[x29, #local_10]
           00092608 26 ee fd 97       bl           <EXTERNAL>::malloc                                       void * malloc(size_t __size)
           0009260c a1 47 40 f9       ldr          x1,[x29, #local_8]
           00092610 1f 7b 3b f8       str          xzr,[x24, x27, LSL #0x3]
           00092614 7b 07 00 91       add          x27,x27,#0x1
           00092618 17 00 00 f9       str          x23=>s_D-Pad_Up_00135ec0,[x0]                            = "D-Pad Up            "
           0009261c 7f 4b 00 f1       cmp          x27,#0x12
           00092620 16 08 00 b9       str          w22,[x0, #0x8]
           00092624 1f 7c 02 a9       stp          xzr,xzr,[x0, #0x20]
           00092628 1c 04 01 a9       stp          x28=>draw_button_config,x1=>action_button_config,[x0, 
           0009262c a1 43 40 f9       ldr          x1,[x29, #local_10]
           00092630 33 d0 03 a9       stp          x19,x20,[x1, #0x38]
           00092634 3f 20 01 39       strb         wzr,[x1, #0x48]
           00092638 c1 fc ff 54       b.ne         LAB_000925d0
           0009263c 1f 20 03 d5       nop
trngaje commented 2 months ago

중복된 부분 제거하면

unsigned char ** sdl_create_menu_extra_controls(long param_1,unsigned long param_2,code *param_3)
{
    int iVar1;
    long lVar2;
    uint uVar3;
    unsigned int uVar4;
    unsigned char **ppcVar5;
    unsigned char *pcVar6;
    unsigned long *puVar7;
    char **ppcVar8;
    char **ppcVar9;
    long lVar10;
    long lVar11;
    unsigned char *puVar12;
    long lVar13;

    lVar11 = *(long *)(param_1 + 8);
    ppcVar5 = (unsigned char **)malloc(0x30);
    *(unsigned long *)((long)ppcVar5 + 0x14) = 0x18;
    *ppcVar5 = draw_menu_controls;
    ppcVar5[1] = focus_menu_none;
    lVar13 = 0;
    ppcVar5[5] = param_3;
    pcVar6 = (unsigned char *)malloc(0xc0);
    ppcVar5[4] = pcVar6;
    do {
        uVar3 = (&options_to_config_map.11558)[lVar13];
        iVar1 = (int)lVar13 + 0x1e;
        puVar12 = (&input_names.11557)[lVar13];
        puVar7 = (unsigned long *)malloc(0x50); // 80
        lVar10 = ((ulong)uVar3 + 0x262) * 2;
        lVar2 = lVar11 + lVar10;
        lVar10 = lVar11 + lVar10 + 0x52;
        if (puVar7 == 0) {
            puVar7 = (unsigned long *)malloc(0x30);
        }
        *(unsigned long *)(pcVar6 + lVar13 * 8) = 0;
        lVar13 = lVar13 + 1;
        *puVar7 = puVar12;
        *(int *)(puVar7 + 1) = iVar1;
        *(unsigned long **)(pcVar6 + lVar13 * 8) = puVar7;

        puVar7[4] = 0;
        puVar7[5] = 0;
        puVar7[7] = lVar2;
        puVar7[8] = lVar10;
        puVar7[2] = draw_button_config;
        puVar7[3] = action_button_config;
        *(unsigned char *)(puVar7 + 9) = 0;
    } while (lVar13 != 0x14);
    LAB_00092358:
    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *ppcVar9 = "Restore default controls";
    *(unsigned int *)(ppcVar9 + 1) = 0x33;
    ppcVar9[2] = (char *)draw_menu_option;
    ppcVar9[3] = (char *)action_select;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar8[6] = (char *)select_restore_default_controls;
    *(char ***)(pcVar6 + 0xa0) = ppcVar8;
    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *ppcVar9 = "Delete game-specific config";
    *(unsigned int *)(ppcVar9 + 1) = 0x34;
    ppcVar9[2] = (char *)draw_menu_option;
    ppcVar9[3] = (char *)action_select;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar8[6] = (char *)select_delete_config_local;
    *(char ***)(pcVar6 + 0xa8) = ppcVar8;
    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *ppcVar9 = "Exit: save for all games";
    *(unsigned int *)(ppcVar9 + 1) = 0x36;
    ppcVar9[2] = (char *)draw_menu_option;
    ppcVar9[3] = (char *)action_select;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar8[6] = (char *)select_save_config_global;
    *(char ***)(pcVar6 + 0xb0) = ppcVar8;
    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *(char ***)(pcVar6 + 0xb8) = ppcVar8;
    *ppcVar9 = "Exit without saving";
    *(unsigned int *)(ppcVar9 + 1) = 0x37;
    ppcVar9[2] = (char *)draw_menu_option;
    ppcVar9[3] = (char *)action_select;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar8[6] = (char *)select_exit_current_menu;
    *(unsigned int *)(param_1 + 0x164) = 0;
    uVar4 = 0xd8;
    if (*(int *)(param_1 + 0x40) != 0) {
        uVar4 = 0x38;
    }
    *(unsigned int *)(ppcVar5 + 2) = uVar4;
    return ppcVar5;
}
trngaje commented 2 months ago

*(unsigned long *)(pcVar6 + lVar13 8) = puVar7; 은 assembly 코드 상에서 찾을 수가 없음

trngaje commented 2 months ago

수정된 코드는 아래와 같음

/*
[trngaje] 0, Enter Menu          , 0x12
[trngaje] 1, Save State          , 0x13
[trngaje] 2, Load State          , 0x14
[trngaje] 3, Toggle Fast Forward , 0x15
[trngaje] 4, Swap Screens        , 0x16
[trngaje] 5, Swap Orientation A  , 0x17
[trngaje] 6, Swap Orientation B  , 0x18
[trngaje] 7, Load New Game       , 0x19
[trngaje] 8, Quit                , 0x1a
[trngaje] 9, Fake Microphone     , 0x1b
[trngaje] 10, Menu Cursor Up      , 0x1f
[trngaje] 11, Menu Cursor Down    , 0x20
[trngaje] 12, Menu Cursor Left    , 0x21
[trngaje] 13, Menu Cursor Right   , 0x22
[trngaje] 14, Menu Select         , 0x23
[trngaje] 15, Menu Exit Menu      , 0x24
[trngaje] 16, Menu Up Directory   , 0x25
[trngaje] 17, Menu Page Up        , 0x26
[trngaje] 18, Menu Page Down      , 0x27
[trngaje] 19, Menu Switch View    , 0x28
*/
unsigned char ** sdl_create_menu_extra_controls(long param_1, unsigned long param_2, unsigned char *param_3)
{
    int iVar1;
    long lVar2;
    uint uVar3;
    unsigned int uVar4;
    unsigned char **ppcVar5;
    unsigned char *pcVar6;
    unsigned long *puVar7;
    char **ppcVar8;
    char **ppcVar9;
    long lVar10;
    long lVar11;
    unsigned char *puVar12;
    long lVar13;

    nds_draw_button_config  draw_button_config;
    nds_action_button_config    action_button_config;
    nds_select_restore_default_controls select_restore_default_controls;
    nds_select_delete_config_local  select_delete_config_local;
    nds_select_save_config_global   select_save_config_global;
    nds_select_exit_current_menu    select_exit_current_menu;
    nds_draw_menu_option    draw_menu_option;
    nds_action_select   action_select;
    nds_draw_menu_controls  draw_menu_controls;
    nds_focus_menu_none focus_menu_none;

    draw_button_config = (nds_draw_button_config)FUN_DRAW_BUTTON_CONFIG;
    action_button_config = (nds_action_button_config)FUN_ACTION_BUTTON_CONFIG;
    select_restore_default_controls = (nds_select_restore_default_controls)FUN_SELECT_RESTORE_DEFAULT_CONTROLS;
    select_delete_config_local = (nds_select_delete_config_local)FUN_SELECT_DELETE_CONFIG_LOCAL;
    select_save_config_global = (nds_select_save_config_global)FUN_SELECT_SAVE_CONFIG_GLOBAL;
    select_exit_current_menu = (nds_select_exit_current_menu)FUN_SELECT_EXIT_CURRENT_MENU;
    draw_menu_option = (nds_draw_menu_option)FUN_DRAW_MENU_OPTION;
    action_select = (nds_action_select)FUN_ACTION_SELECT;   
    draw_menu_controls = (nds_draw_menu_controls)FUN_DRAW_MENU_CONTROLS;
    focus_menu_none = (nds_focus_menu_none)FUN_FOCUS_MENU_NONE;

    lVar11 = *(long *)(param_1 + 8);
    ppcVar5 = (unsigned char **)malloc(0x30);
    *(unsigned long *)((long)ppcVar5 + 0x14) = 0x18;
    *ppcVar5 = draw_menu_controls;
    ppcVar5[1] = focus_menu_none;
    lVar13 = 0;
    ppcVar5[5] = param_3;
    pcVar6 = (unsigned char *)malloc(0xc0);
    ppcVar5[4] = pcVar6;
    do {
        //uVar3 = (&options_to_config_map.11558)[lVar13];
        //uVar3 = ((uint32_t **)(base_addr_rx + 0x001350b0))[lVar13];
        uVar3 = *(uint32_t *)(base_addr_rx + 0x001350b0 + lVar13*4);
        iVar1 = (int)lVar13 + 0x1e;
        //puVar12 = (&input_names.11557)[lVar13];
        //puVar12 = ((uint32_t **)(base_addr_rx + 0x00158cf0))[lVar13];
        puVar12 = *(uint64_t *)(base_addr_rx + 0x00158cf0+lVar13*8);
        //printf("[trngaje] %d, %s, 0x%x\n", lVar13, puVar12, uVar3);
        puVar7 = (unsigned long *)malloc(0x50);
        if (puVar7 == 0) {
            puVar7 = (unsigned long *)malloc(0x30);
        }

        lVar10 = ((ulong)uVar3 + 0x262) * 2;
        lVar2 = lVar11 + lVar10;
        lVar10 = lVar11 + lVar10 + 0x52;

        *(unsigned long *)(pcVar6 + lVar13 * 8) = 0;
        *(unsigned long **)(pcVar6 + lVar13 * 8) = puVar7;
        lVar13 = lVar13 + 1;
        *puVar7 = puVar12;
        *(int *)(puVar7 + 1) = iVar1;
        puVar7[4] = 0;
        puVar7[5] = 0;
        puVar7[7] = lVar2;
        puVar7[8] = lVar10;
        puVar7[2] = draw_button_config;
        puVar7[3] = action_button_config;
        *(unsigned char *)(puVar7 + 9) = 0;
    } while (lVar13 != 0x14);
    LAB_00092358:
    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *ppcVar9 = "Restore default controls";
    *(unsigned int *)(ppcVar9 + 1) = 0x33;
    ppcVar9[2] = (char *)draw_menu_option;
    ppcVar9[3] = (char *)action_select;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar8[6] = (char *)select_restore_default_controls;
    *(char ***)(pcVar6 + 0xa0) = ppcVar8;
    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *ppcVar9 = "Delete game-specific config";
    *(unsigned int *)(ppcVar9 + 1) = 0x34;
    ppcVar9[2] = (char *)draw_menu_option;
    ppcVar9[3] = (char *)action_select;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar8[6] = (char *)select_delete_config_local;
    *(char ***)(pcVar6 + 0xa8) = ppcVar8;
    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *ppcVar9 = "Exit: save for all games";
    *(unsigned int *)(ppcVar9 + 1) = 0x36;
    ppcVar9[2] = (char *)draw_menu_option;
    ppcVar9[3] = (char *)action_select;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar8[6] = (char *)select_save_config_global;
    *(char ***)(pcVar6 + 0xb0) = ppcVar8;
    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *(char ***)(pcVar6 + 0xb8) = ppcVar8;
    *ppcVar9 = "Exit without saving";
    *(unsigned int *)(ppcVar9 + 1) = 0x37;
    ppcVar9[2] = (char *)draw_menu_option;
    ppcVar9[3] = (char *)action_select;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar8[6] = (char *)select_exit_current_menu;
    *(unsigned int *)(param_1 + 0x164) = 0;
    uVar4 = 0xd8;
    if (*(int *)(param_1 + 0x40) != 0) {
        uVar4 = 0x38;
    }
    *(unsigned int *)(ppcVar5 + 2) = uVar4;
    return ppcVar5;
}
trngaje commented 2 months ago
                                 PTR_s_Save_State_00158cf8                               XREF[1]:       create_menu_extra_controls:000922f4(R)  
           00158cf8 88 60 13 00       addr         s_Save_State_00136088                                    = "Save State          "
                    00 00 00 00
           00158d00 a0 60 13 00       addr         s_Load_State_001360a0                                    = "Load State          "
                    00 00 00 00
           00158d08 b8 60 13 00       addr         s_Toggle_Fast_Forward_001360b8                           = "Toggle Fast Forward "
                    00 00 00 00
           00158d10 d0 60 13 00       addr         s_Swap_Screens_001360d0                                  = "Swap Screens        "
                    00 00 00 00
           00158d18 e8 60 13 00       addr         s_Swap_Orientation_A_001360e8                            = "Swap Orientation A  "
                    00 00 00 00
           00158d20 00 61 13 00       addr         s_Swap_Orientation_B_00136100                            = "Swap Orientation B  "
                    00 00 00 00
           00158d28 18 61 13 00       addr         s_Load_New_Game_00136118                                 = "Load New Game       "
                    00 00 00 00
           00158d30 30 61 13 00       addr         s_Quit_00136130                                          = "Quit                "
                    00 00 00 00
           00158d38 48 61 13 00       addr         s_Fake_Microphone_00136148                               = "Fake Microphone     "
                    00 00 00 00
           00158d40 60 61 13 00       addr         s_Menu_Cursor_Up_00136160                                = "Menu Cursor Up      "
                    00 00 00 00
           00158d48 78 61 13 00       addr         s_Menu_Cursor_Down_00136178                              = "Menu Cursor Down    "
                    00 00 00 00
           00158d50 90 61 13 00       addr         s_Menu_Cursor_Left_00136190                              = "Menu Cursor Left    "
                    00 00 00 00
           00158d58 a8 61 13 00       addr         s_Menu_Cursor_Right_001361a8                             = "Menu Cursor Right   "
                    00 00 00 00
           00158d60 c0 61 13 00       addr         s_Menu_Select_001361c0                                   = "Menu Select         "
                    00 00 00 00
           00158d68 d8 61 13 00       addr         s_Menu_Exit_Menu_001361d8                                = "Menu Exit Menu      "
                    00 00 00 00
           00158d70 f0 61 13 00       addr         s_Menu_Up_Directory_001361f0                             = "Menu Up Directory   "
                    00 00 00 00
           00158d78 08 62 13 00       addr         s_Menu_Page_Up_00136208                                  = "Menu Page Up        "
                    00 00 00 00
           00158d80 20 62 13 00       addr         s_Menu_Page_Down_00136220                                = "Menu Page Down      "
                    00 00 00 00
           00158d88 38 62 13 00       addr         s_Menu_Switch_View_00136238                              = "Menu Switch View    "
                    00 00 00 00
trngaje commented 2 months ago

uVar4 = 0x38; 이 값이 메뉴 갯수인가? if ((int )(param_1 + 0x40) != 0) { 조건은 무엇일까?

아래와 같이 hotkey 버튼 메뉴 추가 필요함

    unsigned short usinput1;
    unsigned short usinput2;

    ppcVar8 = (char **)malloc(0x38);
    ppcVar9 = ppcVar8;
    if (ppcVar8 == (char **)0x0) {
        ppcVar9 = (char **)malloc(0x30);
    }
    *ppcVar9 = "Hot key";
    *(unsigned int *)(ppcVar9 + 1) = 0x33;
    ppcVar9[2] = (char *)draw_button_config;
    ppcVar9[3] = (char *)action_button_config;
    ppcVar9[4] = (char *)0x0;
    ppcVar9[5] = (char *)0x0;
    ppcVar9[7] = (char *)0x0;
    ppcVar9[8] = (char *)0x0;
    *(char ***)(pcVar6 + 0xa0) = ppcVar8;

pcVar6 = (unsigned char )malloc(0xc0+8); 로 할당되어 있음 (unsigned long *)(pcVar6 + lVar13 8) = puVar7;

trngaje commented 1 month ago

구현되 화면

Image

trngaje commented 1 month ago

마지막 줄이 표시되지 않는 이유는 아래 코드 재 확인 필요함


static int draw_drastic_menu_controller2(void)
{
    int y = 0;
    int w = 0;
    int cc = 0;
    int cnt = 0;
    int div = 1;
    int cursor = 0;
    SDL_Rect rt = {0};
    int s0 = 0, s1 = 0;
    CUST_MENU_SUB *p = NULL;
    char buf[MAX_PATH] = {0};

#if defined(TRIMUI)
    div = 2;
#endif

    cursor = 0;
    for (cc=0; cc<drastic_menu.cnt;) {
        printf("[trngaje] y=%d, %s\n", drastic_menu.item[cc].y, drastic_menu.item[cc].msg);
        if ((drastic_menu.item[cc].y >= 240) && (drastic_menu.item[cc].y <= 408/*392*/ /*NDS_Hx2*/)) {
            if ((drastic_menu.item[cc + 1].bg > 0) || (drastic_menu.item[cc + 2].bg > 0)) {
                break;
            }
            cc+= 3;
        }
        else {
            if (drastic_menu.item[cc].bg > 0) {
                break;
            }
            cc+= 1;
        }
        cursor+= 1;
    }

    if (cursor <= 6) {
        s0 = 0;
        s1 = 13;
    }
    else if (cursor >= (23 - 7)) {
        s0 = 23 - 13;
        s1 = 23;
    }
    else {
        s0 = cursor - 6;
        s1 = cursor + 7;
    }

    cnt = 0;
    for (cc=0; cc<drastic_menu.cnt; cc++) {
        w = LINE_H / div;
        p = &drastic_menu.item[cc];

        if ((p->y == 224) || (p->y == 232) || (p->y == 201)) {
            continue;
        }

        memset(buf, 0, sizeof(buf));
        if ((cnt >= s0) && (cnt < s1)) {
            y = (25 / div) + ((cnt - s0) * w);

            if ((p->y >= 240) && (p->y <= 408/*392*//*NDS_Hx2*/)) {
                if (drastic_menu.item[cc + 1].bg || drastic_menu.item[cc + 2].bg) {
                    int sum = drastic_menu.item[cc + 1].bg + drastic_menu.item[cc + 2].bg;
                    uint32_t c = sum > 500 ? 0xff0000 : nds.menu.c2;

                    rt.x = 5 / div;
                    rt.y = y - (3 / div);
                    rt.w = FB_W - (10 / div);
                    rt.h = w;
                    SDL_FillRect(nds.menu.drastic.main, &rt, SDL_MapRGB(nds.menu.drastic.main->format, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff));
                }
                draw_info(nds.menu.drastic.main, p->msg, 20 / div, y, p->bg ? nds.menu.c0 : nds.menu.c1, 0);
                if ((p->y >= 240) && (p->y <= 432/*408*//*392*//*NDS_Hx2*/)) {
                    if (nds.enable_752x560) {
                        draw_info(nds.menu.drastic.main, to_lang(drastic_menu.item[cc + 1].msg), 320 / div, y, drastic_menu.item[cc + 1].bg ? nds.menu.c0 : nds.menu.c1, 0);
                        draw_info(nds.menu.drastic.main, to_lang(drastic_menu.item[cc + 2].msg), 550 / div, y, drastic_menu.item[cc + 2].bg ? nds.menu.c0 : nds.menu.c1, 0);
                    }
                    else {
                        draw_info(nds.menu.drastic.main, to_lang(drastic_menu.item[cc + 1].msg), 300 / div, y, drastic_menu.item[cc + 1].bg ? nds.menu.c0 : nds.menu.c1, 0);
                        draw_info(nds.menu.drastic.main, to_lang(drastic_menu.item[cc + 2].msg), 480 / div, y, drastic_menu.item[cc + 2].bg ? nds.menu.c0 : nds.menu.c1, 0);
                    }
                }
            }
            else {
                if (p->bg) {
                    rt.x = 5 / div;
                    rt.y = y - (3 / div);
                    rt.w = FB_W - (10 / div);
                    rt.h = w;
                    SDL_FillRect(nds.menu.drastic.main, &rt, SDL_MapRGB(nds.menu.drastic.main->format, 
                        (nds.menu.c2 >> 16) & 0xff, (nds.menu.c2 >> 8) & 0xff, nds.menu.c2 & 0xff));
                }
                draw_info(nds.menu.drastic.main, to_lang(p->msg), 20 / div, y, p->bg ? nds.menu.c0 : nds.menu.c1, 0);
            }
        }

        cnt+= 1;
        if ((p->y >= 240) && (p->y <= 408/*392*//*NDS_Hx2*/)) {
            cc+= 2;
        }
    }
    return 0;
}
trngaje commented 1 month ago
1.일단은 마지막 라인 표시되지 않는 문제점 개선할 것
2.라인 수 수동으로 지정(예, 408)하는 루틴 개선 필요함

static int draw_drastic_menu_controller2(void)
{
    int y = 0;
    int w = 0;
    int cc = 0;
    int cnt = 0;
    int div = 1;
    int cursor = 0;
    SDL_Rect rt = {0};
    int s0 = 0, s1 = 0;
    CUST_MENU_SUB *p = NULL;
    char buf[MAX_PATH] = {0};

#if defined(TRIMUI)
    div = 2;
#endif

    cursor = 0;
    for (cc=0; cc<drastic_menu.cnt;) {
        printf("[trngaje] y=%d, %s\n", drastic_menu.item[cc].y, drastic_menu.item[cc].msg);
        if ((drastic_menu.item[cc].y >= 240) && (drastic_menu.item[cc].y <= 408/*392*/ /*NDS_Hx2*/)) {
            if ((drastic_menu.item[cc + 1].bg > 0) || (drastic_menu.item[cc + 2].bg > 0)) {
                break;
            }
            cc+= 3;
        }
        else {
            if (drastic_menu.item[cc].bg > 0) {
                break;
            }
            cc+= 1;
        }
        cursor+= 1;
    }

    if (cursor <= 6) { // 첫 페이지
        s0 = 0;
        s1 = 13;
    }
    else if (cursor >= (23 - 7)) { 마지막 페이지, 23 값을 cc<drastic_menu.cnt에 연동해서 계산해야 하지 않을 까?
        s0 = 23 - 13;
        s1 = 23;
    }
    else { // 중간
        s0 = cursor - 6;
        s1 = cursor + 7;
    }

    cnt = 0;
    for (cc=0; cc<drastic_menu.cnt; cc++) {
        w = LINE_H / div;
        p = &drastic_menu.item[cc];

        if ((p->y == 224) || (p->y == 232) || (p->y == 201)) { // 표시 하지 않을 라인 제거
            continue;
        }

        memset(buf, 0, sizeof(buf));
        if ((cnt >= s0) && (cnt < s1)) {
            y = (25 / div) + ((cnt - s0) * w);

            if ((p->y >= 240) && (p->y <= 408/*392*//*NDS_Hx2*/)) {
                if (drastic_menu.item[cc + 1].bg || drastic_menu.item[cc + 2].bg) {
                    int sum = drastic_menu.item[cc + 1].bg + drastic_menu.item[cc + 2].bg;
                    uint32_t c = sum > 500 ? 0xff0000 : nds.menu.c2;

                    rt.x = 5 / div;
                    rt.y = y - (3 / div);
                    rt.w = FB_W - (10 / div);
                    rt.h = w;
                    SDL_FillRect(nds.menu.drastic.main, &rt, SDL_MapRGB(nds.menu.drastic.main->format, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff));
                }
                draw_info(nds.menu.drastic.main, p->msg, 20 / div, y, p->bg ? nds.menu.c0 : nds.menu.c1, 0);
                if ((p->y >= 240) && (p->y <= 432/*408*//*392*//*NDS_Hx2*/)) {
                    if (nds.enable_752x560) {
                        draw_info(nds.menu.drastic.main, to_lang(drastic_menu.item[cc + 1].msg), 320 / div, y, drastic_menu.item[cc + 1].bg ? nds.menu.c0 : nds.menu.c1, 0);
                        draw_info(nds.menu.drastic.main, to_lang(drastic_menu.item[cc + 2].msg), 550 / div, y, drastic_menu.item[cc + 2].bg ? nds.menu.c0 : nds.menu.c1, 0);
                    }
                    else {
                        draw_info(nds.menu.drastic.main, to_lang(drastic_menu.item[cc + 1].msg), 300 / div, y, drastic_menu.item[cc + 1].bg ? nds.menu.c0 : nds.menu.c1, 0);
                        draw_info(nds.menu.drastic.main, to_lang(drastic_menu.item[cc + 2].msg), 480 / div, y, drastic_menu.item[cc + 2].bg ? nds.menu.c0 : nds.menu.c1, 0);
                    }
                }
            }
            else {
                if (p->bg) {
                    rt.x = 5 / div;
                    rt.y = y - (3 / div);
                    rt.w = FB_W - (10 / div);
                    rt.h = w;
                    SDL_FillRect(nds.menu.drastic.main, &rt, SDL_MapRGB(nds.menu.drastic.main->format, 
                        (nds.menu.c2 >> 16) & 0xff, (nds.menu.c2 >> 8) & 0xff, nds.menu.c2 & 0xff));
                }
                draw_info(nds.menu.drastic.main, to_lang(p->msg), 20 / div, y, p->bg ? nds.menu.c0 : nds.menu.c1, 0);
            }
        }

        cnt+= 1;
        if ((p->y >= 240) && (p->y <= 408/*392*//*NDS_Hx2*/)) {
            cc+= 2;
        }
    }
    return 0;
}
trngaje commented 1 month ago

다음과 같이 코드 변경하는 것이 바람직함

    cursor = 0;
    y = -1;
    for (cc=0; cc<drastic_menu.cnt;) {
        printf("[trngaje] y=%d, %s\n", drastic_menu.item[cc].y, drastic_menu.item[cc].msg);

        if (drastic_menu.item[cc].bg > 0) {
            break;
        }           
        if (y == -1) {
            y = drastic_menu.item[cc].y; // 초기 값 등록
        }
        else (y != drastic_menu.item[cc].y) { // 라인이 변경된 경우에만 커서 위치 증가
            cursor+= 1;
        }
    }

    if (cursor <= 6) { // 첫 페이지
        s0 = 0;
        s1 = 13;
    }
    else if (cursor >= (drastic_menu.cnt - 7)) { 마지막 페이지
        s0 = drastic_menu.cnt - 13;
        s1 = drastic_menu.cnt;
    }
    else { // 중간
        s0 = cursor - 6;
        s1 = cursor + 7;
    }
trngaje commented 1 month ago

정리된 소스는 아래와 같음


static int draw_drastic_menu_controller2(void)
{
    int y = 0;
    int w = 0;
    int cc = 0;
    int cnt = 0;
    int div = 1;
    int cursor = 0;
    SDL_Rect rt = {0};
    int s0 = 0, s1 = 0;
    CUST_MENU_SUB *p = NULL;

    int yy;
    int itemcnt;
    int cc2;

    cursor = 0;
    y = -1;
    for (cc=0; cc<drastic_menu.cnt;) {
        printf("[trngaje] y=%d, %s\n", drastic_menu.item[cc].y, drastic_menu.item[cc].msg);

        if (drastic_menu.item[cc].bg > 0) {
            break;
        }           
        if (y == -1) {
            y = drastic_menu.item[cc].y; // 초기 값 등록
        }
        else (y != drastic_menu.item[cc].y) { // 라인이 변경된 경우에만 커서 위치 증가
            cursor+= 1;
        }
    }

    if (cursor <= 6) { // 첫 페이지
        s0 = 0;
        s1 = 13;
    }
    else if (cursor >= (drastic_menu.cnt - 7)) { 마지막 페이지
        s0 = drastic_menu.cnt - 13;
        s1 = drastic_menu.cnt;
    }
    else { // 중간
        s0 = cursor - 6;
        s1 = cursor + 7;
    }

    cnt = 0;
    for (cc=0; cc<drastic_menu.cnt; cc++) {
        w = LINE_H / div;
        p = &drastic_menu.item[cc];

        if ((p->y == 224) || (p->y == 232) || (p->y == 201)) { // 표시 하지 않을 라인 제거
            continue;
        }

        //memset(buf, 0, sizeof(buf));
        if ((cnt >= s0) && (cnt < s1)) {
            y = (25 / div) + ((cnt - s0) * w);

            // get item count
            yy = -1;
            itemcnt = 0;
            for (cc2=cc; cc2<drastic_menu.cnt; cc2++) {
                if (yy == -1) {
                    yy = drastic_menu.item[cc2].y; // 초기 값 등록
                    itemcnt++;
                }
                else (yy != drastic_menu.item[cc2].y) { // 라인이 변경되면 검색 중지
                    break;
                }         
                else {
                    itemcnt++;
                }
            }

            //if ((p->y >= 240) && (p->y <= 408)) {
            if (itemcnt > 1) {
                if (drastic_menu.item[cc + 1].bg || drastic_menu.item[cc + 2].bg) {
                    int sum = drastic_menu.item[cc + 1].bg + drastic_menu.item[cc + 2].bg;
                    uint32_t c = sum > 500 ? 0xff0000 : nds.menu.c2;

                    rt.x = 5 / div;
                    rt.y = y - (3 / div);
                    rt.w = FB_W - (10 / div);
                    rt.h = w;
                    SDL_FillRect(nds.menu.drastic.main, &rt, SDL_MapRGB(nds.menu.drastic.main->format, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff));
                }
                draw_info(nds.menu.drastic.main, p->msg, 20 / div, y, p->bg ? nds.menu.c0 : nds.menu.c1, 0);

                draw_info(nds.menu.drastic.main, to_lang(drastic_menu.item[cc + 1].msg), 300 / div, y, drastic_menu.item[cc + 1].bg ? nds.menu.c0 : nds.menu.c1, 0);
                draw_info(nds.menu.drastic.main, to_lang(drastic_menu.item[cc + 2].msg), 480 / div, y, drastic_menu.item[cc + 2].bg ? nds.menu.c0 : nds.menu.c1, 0);

                cc+= 2;
            }
            else {
                if (p->bg) {
                    rt.x = 5 / div;
                    rt.y = y - (3 / div);
                    rt.w = FB_W - (10 / div);
                    rt.h = w;
                    SDL_FillRect(nds.menu.drastic.main, &rt, SDL_MapRGB(nds.menu.drastic.main->format, 
                        (nds.menu.c2 >> 16) & 0xff, (nds.menu.c2 >> 8) & 0xff, nds.menu.c2 & 0xff));
                }
                draw_info(nds.menu.drastic.main, to_lang(p->msg), 20 / div, y, p->bg ? nds.menu.c0 : nds.menu.c1, 0);
            }
        }

        cnt+= 1;
/*
        if ((p->y >= 240) && (p->y <= 408)) {
            cc+= 2;
        }
        */
    }
    return 0;
}
trngaje commented 1 month ago

수정 코드 등록


static int draw_drastic_menu_controller2(void)
{
    int y = 0;
    int w = 0;
    int cc = 0;
    int cnt = 0;
    int cursor = 0;
    SDL_Rect rt = {0};
    int s0 = 0, s1 = 0;
    CUST_MENU_SUB *p = NULL;

    int yy;
    int itemcnt;
    int cc2;

    cursor = 0;
    y = -1;
    for (cc=0; cc<drastic_menu.cnt;) {
        printf("[trngaje] y=%d, %s\n", drastic_menu.item[cc].y, drastic_menu.item[cc].msg);

        if (drastic_menu.item[cc].bg > 0) {
            break;
        }           
        if (y == -1) {
            y = drastic_menu.item[cc].y; // 초기 값 등록
        }
        else (y != drastic_menu.item[cc].y) { // 라인이 변경된 경우에만 커서 위치 증가
            cursor+= 1;
        }
    }

    if (cursor <= 6) { // 첫 페이지
        s0 = 0;
        s1 = 13;
    }
    else if (cursor >= (drastic_menu.cnt - 7)) { 마지막 페이지
        s0 = drastic_menu.cnt - 13;
        s1 = drastic_menu.cnt;
    }
    else { // 중간
        s0 = cursor - 6;
        s1 = cursor + 7;
    }

    cnt = 0;
    for (cc=0; cc<drastic_menu.cnt; cc++) {
        w = LINE_H;
        p = &drastic_menu.item[cc];

        if ((p->y == 224) || (p->y == 232) || (p->y == 201)) { // 표시 하지 않을 라인 제거
            continue;
        }

        //memset(buf, 0, sizeof(buf));
        if ((cnt >= s0) && (cnt < s1)) {
            y = 25 + ((cnt - s0) * w);

            // get item count
            yy = -1;
            itemcnt = 0;
            for (cc2=cc; cc2<drastic_menu.cnt; cc2++) {
                if (yy == -1) {
                    yy = drastic_menu.item[cc2].y; // 초기 값 등록
                    itemcnt++;
                }
                else (yy != drastic_menu.item[cc2].y) { // 라인이 변경된 경우까지 검색
                    break;
                }         
                else {
                    itemcnt++;
                }
            }

            //if ((p->y >= 240) && (p->y <= 408)) {
            if (itemcnt > 1) {
                if (drastic_menu.item[cc + 1].bg || drastic_menu.item[cc + 2].bg) {
                    int sum = drastic_menu.item[cc + 1].bg + drastic_menu.item[cc + 2].bg;
                    uint32_t c = sum > 500 ? 0xff0000 : nds.menu.c2;

                    rt.x = 5;
                    rt.y = y - 3;
                    rt.w = FB_W - 10;
                    rt.h = w;
                    SDL_FillRect(nds.menu.drastic.main, &rt, SDL_MapRGB(nds.menu.drastic.main->format, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff));
                }
                draw_info(nds.menu.drastic.main, p->msg, 20, y, p->bg ? nds.menu.c0 : nds.menu.c1, 0);

                draw_info(nds.menu.drastic.main, to_lang(drastic_menu.item[cc + 1].msg), 300, y, drastic_menu.item[cc + 1].bg ? nds.menu.c0 : nds.menu.c1, 0);
                draw_info(nds.menu.drastic.main, to_lang(drastic_menu.item[cc + 2].msg), 480, y, drastic_menu.item[cc + 2].bg ? nds.menu.c0 : nds.menu.c1, 0);

                cc+= 2;
            }
            else {
                if (p->bg) {
                    rt.x = 5;
                    rt.y = y - 3;
                    rt.w = FB_W - 10;
                    rt.h = w;
                    SDL_FillRect(nds.menu.drastic.main, &rt, SDL_MapRGB(nds.menu.drastic.main->format, 
                        (nds.menu.c2 >> 16) & 0xff, (nds.menu.c2 >> 8) & 0xff, nds.menu.c2 & 0xff));
                }
                draw_info(nds.menu.drastic.main, to_lang(p->msg), 20, y, p->bg ? nds.menu.c0 : nds.menu.c1, 0);
            }
        }

        cnt+= 1;
    }
    return 0;
}