void CheatMenu()

in cores/genesis/gx/gui/cheats.c [801:1389]


void CheatMenu(void)
{
  int i, update = 0;
  int digit_cnt = 0;
  int max = 0;
  char temp[256];
  char *str = NULL;
  gui_menu *m = &menu_cheats;

  /* clear existing ROM patches */
  clear_cheats();

  /* reset scrolling */
  string_offset = 0;

  /* background overlay */
  if (config.bg_overlay)
  {
    bg_cheats[1].state |= IMAGE_VISIBLE;
  }
  else
  {
    bg_cheats[1].state &= ~IMAGE_VISIBLE;
  }
  
  /* additional textures */
  star.texture = gxTextureOpenPNG(Star_full_png,0);
  bar_over.texture = gxTextureOpenPNG(Overlay_bar_png,0);
  key_switch.texture = gxTextureOpenPNG(Key_DPAD_png,0);
#ifdef HW_RVL
  key_enable.texture = gxTextureOpenPNG(Key_Plus_wii_png,0);
  key_delete.texture = gxTextureOpenPNG(Key_Minus_wii_png,0);
#else
  key_enable.texture = gxTextureOpenPNG(Key_L_gcn_png,0);
  key_delete.texture = gxTextureOpenPNG(Key_R_gcn_png,0);
#endif

  /* selected item */
  m->selected = selection;

  /* slide-in menu */
  GUI_InitMenu(m);
  GUI_DrawMenuFX(m,30,0);

  /* lock background elements */
  m->bg_images[2].state &= ~IMAGE_SLIDE_TOP;
  m->bg_images[3].state &= ~IMAGE_SLIDE_BOTTOM;
  m->bg_images[4].state &= ~IMAGE_SLIDE_TOP;

  while (update != -1)
  {
    /* update arrows buttons */
    if (offset > 0)
      m->arrows[0]->state |= BUTTON_VISIBLE;
    else
      m->arrows[0]->state &= ~BUTTON_VISIBLE;
    if (((offset + 10) < (maxcheats + 1)) && ((offset + 10) < MAX_CHEATS))
      m->arrows[1]->state |= BUTTON_VISIBLE;
    else
      m->arrows[1]->state &= ~BUTTON_VISIBLE;

    /* draw menu */
    GUI_DrawMenu(m);

    /* check if browsing cheats list */
    if (!(m->bg_images[6].state & IMAGE_VISIBLE))
    {
      /* restore scrolling list settings */
      m->offset = offset;
      m->max_items = (maxcheats < MAX_CHEATS) ? (maxcheats + 1) : MAX_CHEATS;
      m->max_buttons = 10;
      m->helpers[1] = NULL;

      /* check if arrow button is high-lighted */
      if (m->selected >= 30)
      {
        /* adjust selected button index */
        m->selected -= 20;
      }
    }

#ifdef HW_RVL
    if (Shutdown)
    {
      /* close additional textures */
      gxTextureClose(&star.texture);
      gxTextureClose(&bar_over.texture);
      gxTextureClose(&key_switch.texture);
      gxTextureClose(&key_enable.texture);
      gxTextureClose(&key_delete.texture);

      /* restore default GUI settings */
      m->max_items = m->max_buttons = 30;
      m->helpers[1] = &action_select;
    }
#endif

    /* update menu */
    update = GUI_UpdateMenu(m);

    /* check if browsing cheats list */
    if (!(m->bg_images[6].state & IMAGE_VISIBLE))
    {
      if (m->selected < 10)
      {
        /* update selected cheat */
        if (selection != m->selected)
        {
          selection = m->selected;
          string_offset = 0;
        }
      }
      else
      {
        /* arrow button is selected */
        m->selected += 20;
      }

      /* save cheats list offset */
      if (offset != m->offset)
      {
        offset = m->offset;
        string_offset = 0;
      }

      /* restore default GUI settings */
      m->offset = 0;
      m->max_items = m->max_buttons = 30;
      m->helpers[1] = &action_select;
    }


    /* handle pressed buttons */
    if (update > 0)
    {
      switch (m->selected)
      {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9: /* Edit cheat */
        {
          if (type && ((selection + offset) != maxcheats))
          {
            /* cheat description */
            str = cheatlist[offset + selection].text;
            strcpy(temp, str);
            max = MAX_DESC_LENGTH - 2;
            digit_cnt = strlen(str);
            if (digit_cnt <= max)
            {
              str[digit_cnt] = '*';
              str[digit_cnt+1] = 0;
            }

            /* init specific characters */
            m->items[10].text[0] = '6';
            m->items[27].text[0] = ' ';
            strcpy(m->items[27].comment,"Add White Space");
            switch_chars();
          }
          else
          {
            /* cheat code */
            str = cheatlist[offset + selection].code;
            strcpy(temp, str);
            if ((offset + selection) == maxcheats)
            {
              /* initialize code */
              max = 0;
              digit_cnt = 0;
              str[0] = '*';
              str[1] = 0;
            }
            else
            {
              /* code type */
              if (str[6] == ':')
              {
                /* Action Replay code */
                if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
                {
                  /* 16-bit code */
                  max = 10;
                }
                else
                {
                  /* 8-bit code */
                  max = 8;
                }
              }
              else if (str[4] == '-')
              {
                /* 16-bit Game Genie code */
                max = 8;
              }
              else
              {
                /* 8-bit Game Genie code */
                max = 10;
              }

              /* set cursor to end of code */
              digit_cnt = max + 1;
            }

            /* init specific characters */
            m->items[10].text[0] = 'G';
            m->items[27].text[0] = ':';
            strcpy(m->items[27].comment,"Add Code Separator");
            switch_chars();
          }

          /* show digit buttons */
          for (i=10; i<30; i++)
            m->buttons[i].state |= BUTTON_VISIBLE;

          /* show right window */
          m->bg_images[6].state |= IMAGE_VISIBLE;

          /* disable left buttons */
          for (i=0; i<10; i++)
            m->buttons[i].state &= ~BUTTON_ACTIVE;

          /* disable arrow buttons */
          m->arrows[0]->state &= ~BUTTON_ACTIVE;
          m->arrows[1]->state &= ~BUTTON_ACTIVE;

          /* slide in right window */
          GUI_DrawMenuFX(m,20,0);

          /* update helper */
          strcpy(action_cancel.comment,"Cancel");

          /* select first digit */
          m->selected = 10;
          
          /* reset scrolling */
          string_offset = 0;
          break;
        }

        case 26:  /* Backspace */
        {
          if (digit_cnt > 0)
          {
            /* delete last character */
            str[digit_cnt--] = 0;

            /* code separator is being deleted */
            if ((str[digit_cnt] == ':') || (str[digit_cnt] == '-'))
            {
              /* reset detected code type (except 8-bit Game Genie code using 2 separators) */
              if (((system_hw & SYSTEM_PBC) == SYSTEM_MD) || (digit_cnt != 7))
              {
                max = 0;
              }
            }

            /* edit mark */
            str[digit_cnt] = '*';

            /* update scroll value if necessary */
            if (string_offset > 0)
              string_offset--;
          }
          break;
        }

        case 27:
        {
          if (type && ((offset + selection) != maxcheats))
          {
            /* SPACE character */
            if (digit_cnt <= max)
            {
              str[digit_cnt++] = ' ';
              str[digit_cnt] = 0;
              if (digit_cnt <= max)
              {
                str[digit_cnt] = '*';
                str[digit_cnt+1] = 0;
              }
            }
          }
          else
          {
            /* Separator character */
            if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
            {
              /* 16-bit codes */
              if (digit_cnt == 4)
              {
                /* Game Genie code */
                max = 8;
                str[4] = '-';
              }
              else if ((digit_cnt == 6) && (max != 8))
              {
                /* Action Replay code */
                max = 10;
                str[6] = ':';
              }
              else
              {
                break;
              }
            }
            else
            {
              /* 8-bit codes */
              if (digit_cnt == 3)
              {
                /* Game Genie code */
                max = 10;
                str[3] = '-';
              }
              else if ((digit_cnt == 7) && (max == 10))
              {
                /* Game Genie code (last part) */
                str[7] = '-';
              }
              else if ((digit_cnt == 6) && (max != 10))
              {
                /* Action Replay code */
                max = 8;
                str[6] = ':';
              }
              else
              {
                break;
              }
            }

            digit_cnt++;
            str[digit_cnt] = '*';
            str[digit_cnt+1] = 0;
          }
          break;
        }

        case 28:  /* Next character set */
        {
          GUI_DrawMenuFX(m,40,1);
          switch_chars();
          GUI_DrawMenuFX(m,40,0);
          break;
        }

        case 29:  /* Validate entry */
        {
          /* finalize cheat description */  
          if (type && ((offset + selection) != maxcheats))
          {
            str[digit_cnt] = 0;
            update = -1;
          }
          
          /* finalize cheat code edition */
          else if (max && (digit_cnt > max))
          {
            /* check if cheat code is valid */
            if (decode_cheat(cheatlist[offset + selection].code, offset + selection))
            {
              /* new cheat ? */
              if ((offset + selection) == maxcheats)
              {
                /* increase cheat count */
                maxcheats++;

                /* enable cheat by default */
                cheatlist[offset + selection].enable = 1;

                /* no description by default */
                strcpy(cheatlist[offset + selection].text,"No Description");
              }

              /* return to cheat selection */
              update = -1;
            }
            else
            {
              GUI_WaitPrompt("Error", "Invalid Cheat Code");
            }
          }
          break;
        }

        default:  /* Add Character */
        {
          /* force code separator if none has been set yet */
          if ((max == 0) && (digit_cnt == 6))
            break;

          /* force 8-bit Game Genie code last separator */
          if (((system_hw & SYSTEM_PBC) != SYSTEM_MD) && (max == 10) && (digit_cnt == 7))
            break;

          /* add character */
          if ((digit_cnt <= max) || (max == 0))
          {
            str[digit_cnt++] = m->items[m->selected].text[0];
            str[digit_cnt] = 0;
            if ((digit_cnt <= max) || (max == 0))
            {
              str[digit_cnt] = '*';
              str[digit_cnt+1] = 0;
            }

            if (string_offset > 0)
              string_offset ++;
          }
          break;
        }
      }
    }
    else if (update < 0)
    {
      /* cancel */
      if (m->bg_images[6].state & IMAGE_VISIBLE)
      {
        /* Restore old entry */
        strcpy(str, temp);
      }
    }
    else
    {
      /* check other buttons pressed while browsing cheats list */
      if (maxcheats && !(m->bg_images[6].state & IMAGE_VISIBLE))
      {
        if ((m_input.keys & PAD_BUTTON_LEFT) || (m_input.keys & PAD_BUTTON_RIGHT))
        {
          /* Switch between cheat code & description */
          type ^= 1;

          /* reset scrolling */
          string_offset = 0;
        }
        else if ((offset + selection) < maxcheats)
        {
          /* Delete selected cheat code*/
          if (m_input.keys & PAD_TRIGGER_R)
          {
            if (GUI_WaitConfirm("Warning","Delete Cheat Entry ?"))
            {
              /* shift cheat list up to selected entry */
              for (i = offset + selection + 1; i < maxcheats; i++)
              {
                strcpy(cheatlist[i-1].text,cheatlist[i].text);
                strcpy(cheatlist[i-1].code,cheatlist[i].code);
                cheatlist[i-1].address = cheatlist[i].address;
                cheatlist[i-1].data = cheatlist[i].data;
                cheatlist[i-1].enable = cheatlist[i].enable;
              }

              /* clear last cheat */
              cheatlist[maxcheats-1].text[0] = 0;
              cheatlist[maxcheats-1].code[0] = 0;
              cheatlist[maxcheats-1].address = 0;
              cheatlist[maxcheats-1].data = 0;
              cheatlist[maxcheats-1].enable = 0;

              /* adjust scrolling list */
              if (maxcheats < 10)
              {
                /* disable next button */
                m->buttons[maxcheats].state &= ~BUTTON_ACTIVE;
                m->buttons[maxcheats-1].shift[1] = 0;
              }
              else 
              {
                /* scroll down cheat list if there is less than 10 visible entries */
                if ((maxcheats < (offset + 10)) && (maxcheats < MAX_CHEATS))
                {
                  offset--;
                }
              }

              /* decrease cheat count */
              maxcheats--;

              /* reset scrolling */
              string_offset = 0;
            }
          }
          else if (m_input.keys & PAD_TRIGGER_L)
          {
            /* Enable/Disable selected cheat code */
            cheatlist[offset + selection].enable ^= 1;
          }
        }
      }
    }

    if (update < 0)
    {
      if (m->bg_images[6].state & IMAGE_VISIBLE)
      {
        /* slide out right window */
        GUI_DrawMenuFX(m,20,1);

        /* hide digit buttons */
        for (i=10; i<30; i++)
          m->buttons[i].state &= ~BUTTON_VISIBLE;

        /* hide right window */
        m->bg_images[6].state &= ~IMAGE_VISIBLE;

        /* enable left buttons */
        for (i=0; i<10; i++)
        {
          if (i < maxcheats)
          {
            menu_cheats.buttons[i].state |= BUTTON_ACTIVE;
            menu_cheats.buttons[i].shift[1] = 1;
          }
          else if (i == maxcheats)
          {
            menu_cheats.buttons[i].state |= BUTTON_ACTIVE;
            menu_cheats.buttons[i].shift[1] = 0;
          }
          else
          {
            menu_cheats.buttons[i].state &= ~BUTTON_ACTIVE;
            menu_cheats.buttons[i].shift[1] = 0;
          }
        }

        /* enable arrow buttons */
        m->arrows[0]->state |= BUTTON_ACTIVE;
        m->arrows[1]->state |= BUTTON_ACTIVE;

        /* restore helper */
        strcpy(action_cancel.comment,"Back");

        /* select current cheat */
        m->selected = selection;

        /* stay in menu */
        update = 0;
      }
    }
  }

  /* apply ROM patches */
  apply_cheats();

  /* save cheats to file */
  sprintf(temp, "%s/cheats/%s.pat", DEFAULT_PATH, rom_filename);

  if (maxcheats)
  {
    /* open file */
    FILE *f = fopen(temp, "w");

    /* write cheats */
    if (f)
    {
      for (i=0; i<maxcheats; i++)
      {
        fprintf(f, "%s\t%s\n", cheatlist[i].code, cheatlist[i].text);
        fprintf(f, "%s\n", cheatlist[i].enable ? "ON" : "OFF");
      }
      fclose(f);
    }
  }

  /* unlock background elements */
  m->bg_images[2].state |= IMAGE_SLIDE_TOP;
  m->bg_images[3].state |= IMAGE_SLIDE_BOTTOM;
  m->bg_images[4].state |= IMAGE_SLIDE_TOP;
  
  /* leave menu */
  GUI_DrawMenuFX(m,30,1);
  GUI_DeleteMenu(m);

  /* close additional textures */
  gxTextureClose(&star.texture);
  gxTextureClose(&bar_over.texture);
  gxTextureClose(&key_switch.texture);
  gxTextureClose(&key_enable.texture);
  gxTextureClose(&key_delete.texture);
}