⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gui.c

📁 psp上的GBA模拟器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* gameplaySP * * Copyright (C) 2006 Exophase <exophase@gmail.com> * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public Licens e as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#include <sys/stat.h>#include <unistd.h>#include <ctype.h>#include <dirent.h>#include "common.h"#define MAX_PATH 1024// Blatantly stolen and trimmed from MZX (megazeux.sourceforge.net)#define FILE_LIST_ROWS 25#define FILE_LIST_POSITION 5#define DIR_LIST_POSITION 360#ifdef PSP_BUILD#define color16(red, green, blue)                                             \  (blue << 11) | (green << 5) | red                                           \#else#define color16(red, green, blue)                                             \  (red << 11) | (green << 5) | blue                                           \#endif#define COLOR_BG            color16(2, 8, 10)#define COLOR_ROM_INFO      color16(22, 36, 26)#define COLOR_ACTIVE_ITEM   color16(31, 63, 31)#define COLOR_INACTIVE_ITEM color16(13, 40, 18)#define COLOR_FRAMESKIP_BAR color16(15, 31, 31)#define COLOR_HELP_TEXT     color16(16, 40, 24)int sort_function(const void *dest_str_ptr, const void *src_str_ptr){  char *dest_str = *((char **)dest_str_ptr);  char *src_str = *((char **)src_str_ptr);  if(src_str[0] == '.')    return 1;  if(dest_str[0] == '.')    return -1;  return strcasecmp(dest_str, src_str);}s32 load_file(u8 **wildcards, u8 *result){  DIR *current_dir;  struct dirent *current_file;  struct stat file_info;  u8 current_dir_name[MAX_PATH];  u8 current_dir_short[81];  u32 current_dir_length;  u32 total_filenames_allocated;  u32 total_dirnames_allocated;  u8 **file_list;  u8 **dir_list;  u32 num_files;  u32 num_dirs;  u8 *file_name;  u32 file_name_length;  u32 ext_pos = -1;  u32 chosen_file, chosen_dir;  u32 dialog_result = 1;  s32 return_value = 1;  u32 current_file_selection;  u32 current_file_scroll_value;  u32 current_dir_selection;  u32 current_dir_scroll_value;  u32 current_file_in_scroll;  u32 current_dir_in_scroll;  u32 current_file_number, current_dir_number;  u32 current_column = 0;  u32 repeat;  u32 i;  gui_action_type gui_action;  while(return_value == 1)  {    current_file_selection = 0;    current_file_scroll_value = 0;    current_dir_selection = 0;    current_dir_scroll_value = 0;    current_file_in_scroll = 0;    current_dir_in_scroll = 0;    total_filenames_allocated = 32;    total_dirnames_allocated = 32;    file_list = (u8 **)malloc(sizeof(u8 *) * 32);    dir_list = (u8 **)malloc(sizeof(u8 *) * 32);    memset(file_list, 0, sizeof(u8 *) * 32);    memset(dir_list, 0, sizeof(u8 *) * 32);    num_files = 0;    num_dirs = 0;    chosen_file = 0;    chosen_dir = 0;    getcwd(current_dir_name, MAX_PATH);    current_dir = opendir(current_dir_name);    do    {      if(current_dir)        current_file = readdir(current_dir);      else        current_file = NULL;      if(current_file)      {        file_name = current_file->d_name;        file_name_length = strlen(file_name);        if((stat(file_name, &file_info) >= 0) &&         ((file_name[0] != '.') || (file_name[1] == '.')))        {          if(S_ISDIR(file_info.st_mode))          {            dir_list[num_dirs] =             (u8 *)malloc(file_name_length + 1);            strcpy(dir_list[num_dirs], file_name);            num_dirs++;          }          else          {            // Must match one of the wildcards, also ignore the .            if(file_name_length >= 4)            {              if(file_name[file_name_length - 4] == '.')                ext_pos = file_name_length - 4;              else              if(file_name[file_name_length - 3] == '.')                ext_pos = file_name_length - 3;              else                ext_pos = 0;              for(i = 0; wildcards[i] != NULL; i++)              {                if(!strcasecmp((file_name + ext_pos),                 wildcards[i]))                {                  file_list[num_files] =                   (u8 *)malloc(file_name_length + 1);                  strcpy(file_list[num_files], file_name);                  num_files++;                  break;                }              }            }          }        }        if(num_files == total_filenames_allocated)        {          file_list = (u8 **)realloc(file_list, sizeof(u8 *) *           total_filenames_allocated * 2);          memset(file_list + total_filenames_allocated, 0,           sizeof(u8 *) * total_filenames_allocated);          total_filenames_allocated *= 2;        }        if(num_dirs == total_dirnames_allocated)        {          dir_list = (u8 **)realloc(dir_list, sizeof(u8 *) *           total_dirnames_allocated * 2);          memset(dir_list + total_dirnames_allocated, 0,           sizeof(u8 *) * total_dirnames_allocated);          total_dirnames_allocated *= 2;        }      }    } while(current_file);    qsort((void *)file_list, num_files, sizeof(u8 *), sort_function);    qsort((void *)dir_list, num_dirs, sizeof(u8 *), sort_function);    closedir(current_dir);    current_dir_length = strlen(current_dir_name);    if(current_dir_length > 80)    {      memcpy(current_dir_short, "...", 3);      memcpy(current_dir_short + 3,       current_dir_name + current_dir_length - 77, 77);      current_dir_short[80] = 0;    }    else    {      memcpy(current_dir_short, current_dir_name,       current_dir_length + 1);    }    repeat = 1;    if(num_files == 0)      current_column = 1;    clear_screen(COLOR_BG);    u8 print_buffer[81];    while(repeat)    {      flip_screen();      print_string(current_dir_short, COLOR_ACTIVE_ITEM, COLOR_BG, 0, 0);      print_string("Press X to return to the main menu.",       COLOR_HELP_TEXT, COLOR_BG, 20, 260);      for(i = 0, current_file_number = i + current_file_scroll_value;       i < FILE_LIST_ROWS; i++, current_file_number++)      {        if(current_file_number < num_files)        {          if((current_file_number == current_file_selection) &&           (current_column == 0))          {            print_string(file_list[current_file_number], COLOR_ACTIVE_ITEM,             COLOR_BG, FILE_LIST_POSITION, ((i + 1) * 10));          }          else          {            print_string(file_list[current_file_number], COLOR_INACTIVE_ITEM,             COLOR_BG, FILE_LIST_POSITION, ((i + 1) * 10));          }        }      }      for(i = 0, current_dir_number = i + current_dir_scroll_value;       i < FILE_LIST_ROWS; i++, current_dir_number++)      {        if(current_dir_number < num_dirs)        {          if((current_dir_number == current_dir_selection) &&           (current_column == 1))          {            print_string(dir_list[current_dir_number], COLOR_ACTIVE_ITEM,             COLOR_BG, DIR_LIST_POSITION, ((i + 1) * 10));          }          else          {            print_string(dir_list[current_dir_number], COLOR_INACTIVE_ITEM,             COLOR_BG, DIR_LIST_POSITION, ((i + 1) * 10));          }        }      }      gui_action = get_gui_input();      switch(gui_action)      {        case CURSOR_DOWN:          if(current_column == 0)          {            if(current_file_selection < (num_files - 1))            {              current_file_selection++;              if(current_file_in_scroll == (FILE_LIST_ROWS - 1))              {                clear_screen(COLOR_BG);                current_file_scroll_value++;              }              else              {                current_file_in_scroll++;              }            }          }          else          {            if(current_dir_selection < (num_dirs - 1))            {              current_dir_selection++;              if(current_dir_in_scroll == (FILE_LIST_ROWS - 1))              {                clear_screen(COLOR_BG);                current_dir_scroll_value++;              }              else              {                current_dir_in_scroll++;              }            }          }          break;        case CURSOR_UP:          if(current_column == 0)          {            if(current_file_selection)            {              current_file_selection--;              if(current_file_in_scroll == 0)              {                clear_screen(COLOR_BG);                current_file_scroll_value--;              }              else              {                current_file_in_scroll--;              }            }          }          else          {            if(current_dir_selection)            {              current_dir_selection--;              if(current_dir_in_scroll == 0)              {                clear_screen(COLOR_BG);                current_dir_scroll_value--;              }              else              {                current_dir_in_scroll--;              }            }          }          break;        case CURSOR_RIGHT:          if(current_column == 0)          {            if(num_dirs != 0)              current_column = 1;          }          break;        case CURSOR_LEFT:          if(current_column == 1)          {            if(num_files != 0)              current_column = 0;          }          break;        case CURSOR_SELECT:          if(current_column == 1)          {            repeat = 0;            chdir(dir_list[current_dir_selection]);          }          else          {            if(num_files != 0)            {              repeat = 0;              return_value = 0;              strcpy(result, file_list[current_file_selection]);            }          }          break;        case CURSOR_BACK:#ifdef PSP_BUILD          if(!strcmp(current_dir_name, "ms0:/PSP"))            break;#endif          repeat = 0;          chdir("..");          break;        case CURSOR_EXIT:          return_value = -1;          repeat = 0;          break;      }    }    for(i = 0; i < num_files; i++)    {      free(file_list[i]);    }    free(file_list);    for(i = 0; i < num_dirs; i++)    {      free(dir_list[i]);    }    free(dir_list);  }  clear_screen(COLOR_BG);  return return_value;}typedef enum{  NUMBER_SELECTION_OPTION = 0x01,  STRING_SELECTION_OPTION = 0x02,  SUBMENU_OPTION          = 0x04,  ACTION_OPTION           = 0x08} menu_option_type_enum;struct _menu_type{  void (* init_function)();  void (* passive_function)();  struct _menu_option_type *options;  u32 num_options;};struct _menu_option_type{  void (* action_function)();  void (* passive_function)();  struct _menu_type *sub_menu;  char *display_string;  void *options;  u32 *current_option;  u32 num_options;  char *help_string;  u32 line_number;  menu_option_type_enum option_type;};typedef struct _menu_option_type menu_option_type;typedef struct _menu_type menu_type;#define make_menu(name, init_function, passive_function)                      \  menu_type name##_menu =                                                     \  {                                                                           \    init_function,                                                            \    passive_function,                                                         \    name##_options,                                                           \    sizeof(name##_options) / sizeof(menu_option_type)                         \  }                                                                           \#define gamepad_config_option(display_string, number)                         \{                                                                             \  NULL,                                                                       \  menu_fix_gamepad_help,                                                      \  NULL,                                                                       \  display_string ": %s",                                                      \  gamepad_config_buttons,                                                     \  gamepad_config_map + gamepad_config_line_to_psp_button[number],             \  sizeof(gamepad_config_buttons) / sizeof(gamepad_config_buttons[0]),         \  gamepad_help[gamepad_config_map[                                            \   gamepad_config_line_to_psp_button[number]]],                               \  number,                                                                     \  STRING_SELECTION_OPTION                                                     \}                                                                             \#define analog_config_option(display_string, number)                          \{                                                                             \  NULL,                                                                       \  menu_fix_gamepad_help,                                                      \  NULL,                                                                       \  display_string ": %s",                                                      \  gamepad_config_buttons,                                                     \  gamepad_config_map + number + 12,                                           \  sizeof(gamepad_config_buttons) / sizeof(gamepad_config_buttons[0]),         \  gamepad_help[gamepad_config_map[number + 12]],                              \  number + 2,                                                                 \  STRING_SELECTION_OPTION                                                     \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -