CfgUSBLoader/source/cfg.c

3991 lines
108 KiB
C

// by oggzee, usptactical & Dr. Clipper
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <ctype.h>
#include <ogcsys.h>
#include <dirent.h>
#include <malloc.h>
#include <sys/types.h>
#include <fcntl.h>
#include "dir.h"
#include "cfg.h"
#include "wpad.h"
#include "gui.h"
#include "video.h"
#include "fat.h"
#include "net.h"
#include "xml.h"
#include "gettext.h"
#include "menu.h"
#include "console.h"
#include "sys.h"
#include "menu.h"
#include "wbfs.h"
#include "wgui.h"
char FAT_DRIVE[8] = SDHC_DRIVE;
char USBLOADER_PATH[200] = "sd:/usb-loader";
char APPS_DIR[200] = "";
char LAST_CFG_PATH[200];
char direct_start_id_buf[] = "#GAMEID\0\0\0\0\0CFGUSB0000000000";
char DIOS_MIOS_INFO[200] = "";
/* configurable fields */
int ENTRIES_PER_PAGE = 12;
int MAX_CHARACTERS = 30;
int CONSOLE_XCOORD = 258;
int CONSOLE_YCOORD = 112;
int CONSOLE_WIDTH = 354;
int CONSOLE_HEIGHT = 304;
int CONSOLE_FG_COLOR = 15;
int CONSOLE_BG_COLOR = 0;
int COVER_XCOORD = 24;
int COVER_YCOORD = 104;
struct CFG CFG;
int COVER_WIDTH_FRONT;
int COVER_HEIGHT_FRONT;
#define TITLE_MAX 64
struct ID_Title
{
u8 id[8];
char title[TITLE_MAX];
int hnext; // linked list next with same hash
};
// renamed titles
int num_title = 0; //number of titles
struct ID_Title *cfg_title = NULL;
HashTable title_hash_id6;
HashTable title_hash_id4;
#define MAX_CFG_GAME 500
int num_cfg_game = 0;
struct Game_CFG_2 cfg_game[MAX_CFG_GAME];
struct TextMap map_video[] =
{
{ "system", CFG_VIDEO_SYS },
{ "game", CFG_VIDEO_GAME },
{ "auto", CFG_VIDEO_AUTO },
{ "pal50", CFG_VIDEO_PAL50 },
{ "pal60", CFG_VIDEO_PAL60 },
{ "ntsc", CFG_VIDEO_NTSC },
{ "pal480p",CFG_VIDEO_NUM },
{ NULL, -1 }
};
struct TextMap map_video_patch[] =
{
{ "0", CFG_VIDEO_PATCH_OFF },
{ "1", CFG_VIDEO_PATCH_ON },
{ "all", CFG_VIDEO_PATCH_ALL },
{ "sneek", CFG_VIDEO_PATCH_SNEEK },
{ "sneek+all", CFG_VIDEO_PATCH_SNEEK_ALL },
{ NULL, -1 }
};
char *names_vpatch[CFG_VIDEO_PATCH_NUM] =
{
gts("Off"),
gts("On"),
gts("All"),
"sneek",
"sneek+all",
};
struct TextMap map_language[] =
{
{ "console", CFG_LANG_CONSOLE },
{ "japanese", CFG_LANG_JAPANESE },
{ "english", CFG_LANG_ENGLISH },
{ "german", CFG_LANG_GERMAN },
{ "french", CFG_LANG_FRENCH },
{ "spanish", CFG_LANG_SPANISH },
{ "italian", CFG_LANG_ITALIAN },
{ "dutch", CFG_LANG_DUTCH },
{ "s.chinese", CFG_LANG_S_CHINESE },
{ "t.chinese", CFG_LANG_T_CHINESE },
{ "korean", CFG_LANG_KOREAN },
{ NULL, -1 }
};
struct TextMap map_layout[] =
{
{ "original", CFG_LAYOUT_ORIG },
{ "original1", CFG_LAYOUT_ORIG },
{ "original2", CFG_LAYOUT_ORIG_12 },
{ "small", CFG_LAYOUT_SMALL },
{ "medium", CFG_LAYOUT_MEDIUM },
{ "large", CFG_LAYOUT_LARGE },
{ "large2", CFG_LAYOUT_LARGE_2 },
{ "large3", CFG_LAYOUT_LARGE_3 },
{ "ultimate1", CFG_LAYOUT_ULTIMATE1 },
{ "ultimate2", CFG_LAYOUT_ULTIMATE2 },
{ "ultimate3", CFG_LAYOUT_ULTIMATE3 },
{ "kosaic", CFG_LAYOUT_KOSAIC },
{ NULL, -1 }
};
struct TextMap map_ios[] =
{
{ "245", CFG_IOS_245 },
{ "246", CFG_IOS_246 },
{ "247", CFG_IOS_247 },
{ "248", CFG_IOS_248 },
{ "249", CFG_IOS_249 },
{ "250", CFG_IOS_250 },
{ "251", CFG_IOS_251 },
{ "252", CFG_IOS_252 },
{ "222-mload", CFG_IOS_222_MLOAD },
{ "223-mload", CFG_IOS_223_MLOAD },
{ "224-mload", CFG_IOS_224_MLOAD },
{ "222-yal", CFG_IOS_222_YAL },
{ "223-yal", CFG_IOS_223_YAL },
{ "Auto", CFG_IOS_AUTO },
{ NULL, -1 }
};
u8 cIOS_base[11];
struct TextMap map_gui_style[] =
{
{ "grid", GUI_STYLE_GRID },
{ "flow", GUI_STYLE_FLOW },
{ "flow-z", GUI_STYLE_FLOW_Z },
{ "coverflow3d", GUI_STYLE_COVERFLOW + coverflow3d },
{ "coverflow2d", GUI_STYLE_COVERFLOW + coverflow2d },
{ "frontrow", GUI_STYLE_COVERFLOW + frontrow },
{ "vertical", GUI_STYLE_COVERFLOW + vertical },
{ "carousel", GUI_STYLE_COVERFLOW + carousel },
{ NULL, -1 }
};
struct TextMap map_button[] =
{
{ "-", CFG_BTN_M },
{ "+", CFG_BTN_P },
{ "A", CFG_BTN_A },
{ "B", CFG_BTN_B },
{ "H", CFG_BTN_H },
{ "1", CFG_BTN_1 },
{ "2", CFG_BTN_2 },
{ "nothing", CFG_BTN_NOTHING },
{ "options", CFG_BTN_OPTIONS },
{ "gui", CFG_BTN_GUI },
{ "reboot", CFG_BTN_REBOOT },
{ "exit", CFG_BTN_EXIT },
{ "hbc", CFG_BTN_HBC },
{ "screenshot", CFG_BTN_SCREENSHOT },
{ "install", CFG_BTN_INSTALL },
{ "remove", CFG_BTN_REMOVE },
{ "main_menu", CFG_BTN_MAIN_MENU },
{ "global_ops", CFG_BTN_GLOBAL_OPS },
{ "favorites", CFG_BTN_FAVORITES },
{ "boot_game", CFG_BTN_BOOT_GAME },
{ "boot_disc", CFG_BTN_BOOT_DISC },
{ "theme", CFG_BTN_THEME },
{ "profile", CFG_BTN_PROFILE },
{ "unlock", CFG_BTN_UNLOCK },
{ "sort", CFG_BTN_SORT },
{ "filter", CFG_BTN_FILTER },
{ "priiloader", CFG_BTN_PRIILOADER },
{ "channel", CFG_BTN_CHANNEL },
{ "wii_menu", CFG_BTN_WII_MENU },
{ "random", CFG_BTN_RANDOM },
{ NULL, -1 }
};
struct TextMap map_button_menu[] =
{
//{ "A", NUM_BUTTON_A },
{ "B", NUM_BUTTON_B },
{ "1", NUM_BUTTON_1 },
{ "2", NUM_BUTTON_2 },
{ "-", NUM_BUTTON_MINUS },
{ "M", NUM_BUTTON_MINUS },
{ "+", NUM_BUTTON_PLUS },
{ "P", NUM_BUTTON_PLUS },
{ "H", NUM_BUTTON_HOME },
{ "X", NUM_BUTTON_X },
{ "Y", NUM_BUTTON_Y },
{ "Z", NUM_BUTTON_Z },
{ "C", NUM_BUTTON_C },
{ "L", NUM_BUTTON_L },
{ "R", NUM_BUTTON_R },
{ NULL, -1 }
};
struct TextMap map_hook[] =
{
{ "nohooks", 0 },
{ "vbi", 1 },
{ "wiipad", 2 },
{ "gcpad", 3 },
{ "gxdraw", 4 },
{ "gxflush", 5 },
{ "ossleep", 6 },
{ "axframe", 7 },
{ NULL, -1 }
};
char *hook_name[NUM_HOOK] =
{
"No Hooks",
"VBI",
"Wii Pad",
"GC Pad",
"GXDraw",
"GXFlush",
"OSSleepThread",
"AXNextFrame"
};
struct TextMap map_nand_emu[] =
{
{ "off", 0 },
{ "partitial", 1 },
{ "full", 2 },
{ NULL, -1 }
};
struct TextMap map_boot_method[] = //combination of map_channel_boot and map_gc_boot
{
{ "Mighty Plugin", 0 },
{ "Neek2o Plugin", 1 },
{ "Default", 0 },
{ "DIOS MIOS", 1 },
{ "Devolution", 2 },
{ "Nintendont", 3 },
{ NULL, -1 }
};
struct TextMap map_channel_boot[] =
{
{ "Mighty Plugin", 0 },
{ "Neek2o Plugin", 1 },
{ NULL, -1 }
};
struct TextMap map_gc_boot[] =
{
{ "Default", 0 },
{ "DIOS MIOS", 1 },
{ "Devolution", 2 },
{ "Nintendont", 3 },
{ NULL, -1 }
};
struct playStat {
char id[7];
s32 playCount;
time_t playTime;
};
bool playStatsRead = false;
int playStatsSize = 0;
struct playStat *playStats;
int CFG_IOS_MAX = MAP_NUM(map_ios) - 1;
int CURR_IOS_IDX = -1;
// theme
//#define MAX_THEME 100
int num_theme = 0;
int cur_theme = -1;
char theme_list[MAX_THEME][MAX_THEME_NAME];
char theme_path[200];
void game_set(char *name, char *val);
void load_theme(char *theme);
void cfg_setup1();
void cfg_setup2();
void cfg_setup3();
void cfg_direct_start(int argc, char **argv);
void cfg_layout()
{
// CFG_LAYOUT_ORIG (1.0 - base for most)
ENTRIES_PER_PAGE = 6;
MAX_CHARACTERS = 30;
CONSOLE_XCOORD = 260;
CONSOLE_YCOORD = 115;
CONSOLE_WIDTH = 340;
CONSOLE_HEIGHT = 218;
CONSOLE_FG_COLOR = 15;
CONSOLE_BG_COLOR = 0;
// orig 1.2
COVER_XCOORD = 24;
COVER_YCOORD = 104;
//COVER_WIDTH = 160; // set by cover_style
//COVER_HEIGHT = 225; // set by cover_style
// widescreen
CFG.W_CONSOLE_XCOORD = CONSOLE_XCOORD;
CFG.W_CONSOLE_YCOORD = CONSOLE_YCOORD;
CFG.W_CONSOLE_WIDTH = CONSOLE_WIDTH;
CFG.W_CONSOLE_HEIGHT = CONSOLE_HEIGHT;
CFG.W_COVER_XCOORD = COVER_XCOORD;
CFG.W_COVER_YCOORD = COVER_YCOORD;
//CFG.W_COVER_WIDTH = 0; // auto
//CFG.W_COVER_HEIGHT = 0; // auto
switch (CFG.layout) {
case CFG_LAYOUT_ORIG: // 1.0+
ENTRIES_PER_PAGE = 6;
MAX_CHARACTERS = 30;
CONSOLE_XCOORD = 260;
CONSOLE_YCOORD = 115;
CONSOLE_WIDTH = 340;
CONSOLE_HEIGHT = 218;
CONSOLE_FG_COLOR = 15;
CONSOLE_BG_COLOR = 0;
break;
case CFG_LAYOUT_ORIG_12: // 1.2+
ENTRIES_PER_PAGE = 12;
MAX_CHARACTERS = 30;
CONSOLE_XCOORD = 258;
CONSOLE_YCOORD = 112;
CONSOLE_WIDTH = 354;
CONSOLE_HEIGHT = 304;
CONSOLE_FG_COLOR = 15;
CONSOLE_BG_COLOR = 0;
COVER_XCOORD = 24;
COVER_YCOORD = 104;
break;
case CFG_LAYOUT_SMALL: // same as 1.0 + use more space
ENTRIES_PER_PAGE = 9;
MAX_CHARACTERS = 38;
break;
case CFG_LAYOUT_MEDIUM:
ENTRIES_PER_PAGE = 19; //17;
MAX_CHARACTERS = 38;
CONSOLE_YCOORD = 50;
CONSOLE_HEIGHT = 380;
COVER_XCOORD = 28;
COVER_YCOORD = 175;
break;
// nixx:
case CFG_LAYOUT_LARGE:
ENTRIES_PER_PAGE = 21;
MAX_CHARACTERS = 38;
CONSOLE_YCOORD = 40;
CONSOLE_HEIGHT = 402;
COVER_XCOORD = 28;
COVER_YCOORD = 175;
break;
// usptactical:
case CFG_LAYOUT_LARGE_2:
ENTRIES_PER_PAGE = 21;
MAX_CHARACTERS = 38;
CONSOLE_YCOORD = 40;
CONSOLE_HEIGHT = 402;
COVER_XCOORD = 30;
COVER_YCOORD = 180;
break;
// oggzee
case CFG_LAYOUT_LARGE_3:
ENTRIES_PER_PAGE = 21;
MAX_CHARACTERS = 38;
CONSOLE_YCOORD = 40;
CONSOLE_WIDTH = 344;
CONSOLE_HEIGHT = 402;
COVER_XCOORD = 42;
COVER_YCOORD = 102;
CFG.W_CONSOLE_XCOORD = CONSOLE_XCOORD;
CFG.W_CONSOLE_YCOORD = CONSOLE_YCOORD;
CFG.W_CONSOLE_WIDTH = CONSOLE_WIDTH;
CFG.W_CONSOLE_HEIGHT = CONSOLE_HEIGHT;
CFG.W_COVER_XCOORD = COVER_XCOORD+14;
CFG.W_COVER_YCOORD = COVER_YCOORD;
break;
// Ultimate1: (WiiShizza) white background
case CFG_LAYOUT_ULTIMATE1:
ENTRIES_PER_PAGE = 12;
MAX_CHARACTERS = 37;
CONSOLE_YCOORD = 30;
CONSOLE_HEIGHT = 290;
CONSOLE_FG_COLOR = 0;
CONSOLE_BG_COLOR = 15;
COVER_XCOORD = 28;
COVER_YCOORD = 105;
break;
// Ultimate2: (jservs7 / hungyip84)
case CFG_LAYOUT_ULTIMATE2:
ENTRIES_PER_PAGE = 12;
MAX_CHARACTERS = 37;
CONSOLE_YCOORD = 30;
CONSOLE_HEIGHT = 290;
CONSOLE_FG_COLOR = 15;
CONSOLE_BG_COLOR = 0;
COVER_XCOORD = 28;
COVER_YCOORD = 105;
break;
// Ultimate3: (WiiShizza) white background, covers on right
case CFG_LAYOUT_ULTIMATE3:
ENTRIES_PER_PAGE = 12;
MAX_CHARACTERS = 37;
CONSOLE_XCOORD = 40;
CONSOLE_YCOORD = 71;
CONSOLE_WIDTH = 344;
CONSOLE_HEIGHT = 290;
CONSOLE_FG_COLOR = 0;
CONSOLE_BG_COLOR = 15;
COVER_XCOORD = 446;
COVER_YCOORD = 109;
CFG.W_CONSOLE_XCOORD = CONSOLE_XCOORD;
CFG.W_CONSOLE_YCOORD = CONSOLE_YCOORD;
CFG.W_CONSOLE_WIDTH = CONSOLE_WIDTH;
CFG.W_CONSOLE_HEIGHT = CONSOLE_HEIGHT;
CFG.W_COVER_XCOORD = 482;
CFG.W_COVER_YCOORD = 110;
break;
// Kosaic (modified U3)
case CFG_LAYOUT_KOSAIC:
ENTRIES_PER_PAGE = 12;
MAX_CHARACTERS = 37;
CONSOLE_XCOORD = 40;
CONSOLE_YCOORD = 71;
CONSOLE_WIDTH = 344;
CONSOLE_HEIGHT = 290;
CONSOLE_FG_COLOR = 15;
CONSOLE_BG_COLOR = 0;
COVER_XCOORD = 446;
COVER_YCOORD = 109;
CFG.W_CONSOLE_XCOORD = 34;
CFG.W_CONSOLE_YCOORD = 71;
CFG.W_CONSOLE_WIDTH = CONSOLE_WIDTH;
CFG.W_CONSOLE_HEIGHT = CONSOLE_HEIGHT;
CFG.W_COVER_XCOORD = 444;
CFG.W_COVER_YCOORD = 109;
break;
}
}
void set_colors(int x)
{
switch(x) {
case CFG_COLORS_MONO:
CFG.color_header =
CFG.color_inactive =
CFG.color_footer =
CFG.color_help =
CFG.color_selected_bg = CONSOLE_FG_COLOR;
CFG.color_selected_fg = CONSOLE_BG_COLOR;
break;
case CFG_COLORS_DARK:
CFG.color_header = 14;
CFG.color_selected_fg = 11;
CFG.color_selected_bg = 12;
CFG.color_inactive = 8;
CFG.color_footer = 6;
CFG.color_help = 2;
break;
case CFG_COLORS_BRIGHT:
CFG.color_header = 6;
CFG.color_selected_fg = 11;
CFG.color_selected_bg = 12;
CFG.color_inactive = 7;
CFG.color_footer = 4;
CFG.color_help = 2;
break;
}
}
void cfg_set_covers_path()
{
//STRCOPY(CFG.covers_path_2d, CFG.covers_path);
snprintf(D_S(CFG.covers_path_2d), "%s/%s", CFG.covers_path, "2d");
snprintf(D_S(CFG.covers_path_3d), "%s/%s", CFG.covers_path, "3d");
snprintf(D_S(CFG.covers_path_disc), "%s/%s", CFG.covers_path, "disc");
snprintf(D_S(CFG.covers_path_full), "%s/%s", CFG.covers_path, "full");
snprintf(D_S(CFG.covers_path_cache), "%s/%s", CFG.covers_path, "cache");
CFG.covers_path_2d_set = 0;
}
char *cfg_get_covers_path(int style)
{
switch (style) {
default:
case CFG_COVER_STYLE_2D:
if (CFG.covers_path_2d_set) {
return CFG.covers_path_2d;
} else {
return CFG.covers_path;
}
case CFG_COVER_STYLE_3D:
return CFG.covers_path_3d;
case CFG_COVER_STYLE_DISC:
return CFG.covers_path_disc;
case CFG_COVER_STYLE_FULL:
case CFG_COVER_STYLE_HQ:
return CFG.covers_path_full;
case CFG_COVER_STYLE_CACHE:
return CFG.covers_path_cache;
}
return NULL;
}
void cfg_set_cover_style(int style)
{
CFG.cover_style = style;
CFG.W_COVER_WIDTH = 0; // auto
CFG.W_COVER_HEIGHT = 0; // auto
switch (style) {
case CFG_COVER_STYLE_2D:
COVER_WIDTH = 160;
COVER_HEIGHT = 225;
break;
case CFG_COVER_STYLE_3D:
COVER_WIDTH = 160;
COVER_HEIGHT = 225;
break;
case CFG_COVER_STYLE_DISC:
COVER_WIDTH = 160;
COVER_HEIGHT = 160;
break;
case CFG_COVER_STYLE_FULL:
COVER_WIDTH = 512;
if (CFG.gui_compress_covers)
COVER_HEIGHT = 336;
else
COVER_HEIGHT = 340;
//Calculate the width of the front cover only, given the cover dimensions above.
// Divide the height by 1.4, which is the 2d cover height:width ratio (225x160 = 1.4)
// and then divide by 4 and multiply by 4 so it's divisible. This makes it easier if
// we want to change the fullcover dimensions in the future.
COVER_WIDTH_FRONT = (int)(COVER_HEIGHT / 1.4) >> 2 << 2;
COVER_HEIGHT_FRONT = COVER_HEIGHT;
break;
}
}
void cfg_set_cover_style_str(char *val)
{
if (strcmp(val, "standard")==0) {
cfg_set_cover_style(CFG_COVER_STYLE_2D);
} else if (strcmp(val, "3d")==0) {
cfg_set_cover_style(CFG_COVER_STYLE_3D);
} else if (strcmp(val, "disc")==0) {
cfg_set_cover_style(CFG_COVER_STYLE_DISC);
} else if (strcmp(val, "full")==0) {
cfg_set_cover_style(CFG_COVER_STYLE_FULL);
}
}
// setup cover style: path & url
/*
void cfg_setup_cover_style()
{
switch (CFG.cover_style) {
case CFG_COVER_STYLE_3D:
STRCOPY(CFG.covers_path, CFG.covers_path_3d);
STRCOPY(CFG.cover_url, CFG.cover_url_3d);
break;
case CFG_COVER_STYLE_DISC:
STRCOPY(CFG.covers_path, CFG.covers_path_disc);
STRCOPY(CFG.cover_url, CFG.cover_url_disc);
break;
case CFG_COVER_STYLE_FULL:
STRCOPY(CFG.covers_path, CFG.covers_path_full);
STRCOPY(CFG.cover_url, CFG.cover_url_full);
break;
default:
case CFG_COVER_STYLE_2D:
STRCOPY(CFG.covers_path, CFG.covers_path_2d);
STRCOPY(CFG.cover_url, CFG.cover_url_2d);
break;
}
}
*/
void cfg_default_url()
{
CFG.download_id_len = 6;
CFG.download_all = 1;
//strcpy(CFG.download_cc_pal, "EN");
*CFG.download_cc_pal = 0; // means AUTO - console language
*CFG.cover_url_2d = 0;
*CFG.cover_url_3d = 0;
*CFG.cover_url_disc = 0;
*CFG.cover_url_full = 0;
*CFG.cover_url_hq = 0;
STRCOPY(CFG.cover_url_2d,
" http://art.gametdb.com/wii/cover/{CC}/{ID6}.png"
//" http://www.wiiboxart.com/artwork/cover/{ID6}.png"
//" http://boxart.rowdyruff.net/flat/{ID6}.png"
//" http://www.muntrue.nl/covers/ALL/160/225/boxart/{ID6}.png"
//" http://wiicover.gateflorida.com/sites/default/files/cover/2D%20Cover/{ID6}.png"
//" http://awiibit.com/BoxArt160x224/{ID6}.png"
);
STRCOPY(CFG.cover_url_3d,
" http://art.gametdb.com/wii/cover3D/{CC}/{ID6}.png"
//" http://www.wiiboxart.com/artwork/cover3D/{ID6}.png"
//" http://boxart.rowdyruff.net/3d/{ID6}.png"
//" http://www.muntrue.nl/covers/ALL/160/225/3D/{ID6}.png"
//" http://wiicover.gateflorida.com/sites/default/files/cover/3D%20Cover/{ID6}.png"
//" http://awiibit.com/3dBoxArt176x248/{ID6}.png"
);
STRCOPY(CFG.cover_url_disc,
" http://art.gametdb.com/wii/disc/{CC}/{ID6}.png"
" http://art.gametdb.com/wii/disccustom/{CC}/{ID6}.png"
//" http://www.wiiboxart.com/artwork/disc/{ID6}.png"
//" http://www.wiiboxart.com/artwork/disccustom/{ID6}.png"
//" http://boxart.rowdyruff.net/fulldisc/{ID6}.png"
//" http://www.muntrue.nl/covers/ALL/160/160/disc/{ID6}.png"
//" http://wiicover.gateflorida.com/sites/default/files/cover/Disc%20Cover/{ID6}.png"
//" http://awiibit.com/WiiDiscArt/{ID6}.png"
);
STRCOPY(CFG.cover_url_full,
" http://art.gametdb.com/wii/coverfull/{CC}/{ID6}.png"
//" http://www.wiiboxart.com/artwork/coverfull/{ID6}.png"
//" http://www.muntrue.nl/covers/ALL/512/340/fullcover/{ID6}.png"
//" http://wiicover.gateflorida.com/sites/default/files/cover/Full%20Cover/{ID6}.png"
);
STRCOPY(CFG.cover_url_hq,
" http://art.gametdb.com/wii/coverfullHQ/{CC}/{ID6}.png"
);
STRCOPY(CFG.gamercard_url,
" http://www.wiinnertag.com/wiinnertag_scripts/update_sign.php?key={KEY}&game_id={ID6}"
" http://www.messageboardchampion.com/ncard/API/?cmd=tdbupdate&key={KEY}&game={ID6}"
" http://tag.darkumbra.net/{KEY}.update={ID6}"
);
*CFG.gamercard_key = 0;
}
/**
* Method that populates the coverflow global settings structure
* @return void
*/
void CFG_Default_Coverflow()
{
CFG_cf_global.covers_3d = true;
CFG_cf_global.number_of_covers = 7;
CFG_cf_global.selected_cover = 1;
CFG_cf_global.theme = coverflow3d; // default to coverflow 3D
CFG_cf_global.cover_back_xpos = 0;
CFG_cf_global.cover_back_ypos = 0;
CFG_cf_global.cover_back_zpos = -45;
CFG_cf_global.cover_back_xrot = 0;
CFG_cf_global.cover_back_yrot = 0;
CFG_cf_global.cover_back_zrot = 0;
CFG_cf_global.screen_fade_alpha = 210;
}
/**
* Method that populates the coverflow theme settings structure
* @return void
*/
void CFG_Default_Coverflow_Themes()
{
int i = 0;
//allocate the structure array
//SAFE_FREE(CFG_cf_theme);
//CFG_cf_theme = malloc(5 * sizeof *CFG_cf_theme);
// coverflow 3D
CFG_cf_theme[i].rotation_frames = 40;
CFG_cf_theme[i].rotation_frames_fast = 7;
CFG_cf_theme[i].cam_pos_x = 0.0;
CFG_cf_theme[i].cam_pos_y = 0.0;
CFG_cf_theme[i].cam_pos_z = 0.0;
CFG_cf_theme[i].cam_look_x = 0.0;
CFG_cf_theme[i].cam_look_y = 0.0;
CFG_cf_theme[i].cam_look_z = -1.0;
if (CFG.widescreen)
CFG_cf_theme[i].number_of_side_covers = 4;
else
CFG_cf_theme[i].number_of_side_covers = 3;
CFG_cf_theme[i].reflections_color_bottom = 0x666666FF;
CFG_cf_theme[i].reflections_color_top = 0xAAAAAA33;
CFG_cf_theme[i].alpha_rolloff = 0;
CFG_cf_theme[i].floating_cover = false;
CFG_cf_theme[i].title_text_xpos = -1;
CFG_cf_theme[i].title_text_ypos = 434;
CFG_cf_theme[i].cover_rolloff_x = 0;
CFG_cf_theme[i].cover_rolloff_y = 0;
CFG_cf_theme[i].cover_rolloff_z = 0;
CFG_cf_theme[i].cover_center_xpos = 0;
CFG_cf_theme[i].cover_center_ypos = 0;
CFG_cf_theme[i].cover_center_zpos = -70;
CFG_cf_theme[i].cover_center_xrot = 0;
CFG_cf_theme[i].cover_center_yrot = 0;
CFG_cf_theme[i].cover_center_zrot = 0;
CFG_cf_theme[i].cover_center_reflection_used = true;
CFG_cf_theme[i].cover_distance_from_center_left_x = -21;
CFG_cf_theme[i].cover_distance_from_center_left_y = 0;
CFG_cf_theme[i].cover_distance_from_center_left_z = 0;
CFG_cf_theme[i].cover_distance_between_covers_left_x = -10;
CFG_cf_theme[i].cover_distance_between_covers_left_y = 0;
CFG_cf_theme[i].cover_distance_between_covers_left_z = 0;
CFG_cf_theme[i].cover_left_xpos = 0;
CFG_cf_theme[i].cover_left_ypos = 0;
CFG_cf_theme[i].cover_left_zpos = -93;
CFG_cf_theme[i].cover_left_xrot = 0;
CFG_cf_theme[i].cover_left_yrot = 70;
CFG_cf_theme[i].cover_left_zrot = 0;
CFG_cf_theme[i].cover_distance_from_center_right_x = 21;
CFG_cf_theme[i].cover_distance_from_center_right_y = 0;
CFG_cf_theme[i].cover_distance_from_center_right_z = 0;
CFG_cf_theme[i].cover_distance_between_covers_right_x = 10;
CFG_cf_theme[i].cover_distance_between_covers_right_y = 0;
CFG_cf_theme[i].cover_distance_between_covers_right_z = 0;
CFG_cf_theme[i].cover_right_xpos = 0;
CFG_cf_theme[i].cover_right_ypos = 0;
CFG_cf_theme[i].cover_right_zpos = -93;
CFG_cf_theme[i].cover_right_xrot = 0;
CFG_cf_theme[i].cover_right_yrot = -70;
CFG_cf_theme[i].cover_right_zrot = 0;
// coverflow 2D
i++;
CFG_cf_theme[i].rotation_frames = 40;
CFG_cf_theme[i].rotation_frames_fast = 7;
CFG_cf_theme[i].cam_pos_x = 0.0;
CFG_cf_theme[i].cam_pos_y = 0.0;
CFG_cf_theme[i].cam_pos_z = 0.0;
CFG_cf_theme[i].cam_look_x = 0.0;
CFG_cf_theme[i].cam_look_y = 0.0;
CFG_cf_theme[i].cam_look_z = -1.0;
if (CFG.widescreen)
CFG_cf_theme[i].number_of_side_covers = 4;
else
CFG_cf_theme[i].number_of_side_covers = 3;
CFG_cf_theme[i].reflections_color_bottom = 0x666666FF;
CFG_cf_theme[i].reflections_color_top = 0xAAAAAA33;
CFG_cf_theme[i].alpha_rolloff = 0;
CFG_cf_theme[i].floating_cover = false;
CFG_cf_theme[i].title_text_xpos = -1;
CFG_cf_theme[i].title_text_ypos = 434;
CFG_cf_theme[i].cover_rolloff_x = 0;
CFG_cf_theme[i].cover_rolloff_y = 0;
CFG_cf_theme[i].cover_rolloff_z = 0;
CFG_cf_theme[i].cover_center_xpos = 0;
CFG_cf_theme[i].cover_center_ypos = 0;
CFG_cf_theme[i].cover_center_zpos = -70;
CFG_cf_theme[i].cover_center_xrot = 0;
CFG_cf_theme[i].cover_center_yrot = 0;
CFG_cf_theme[i].cover_center_zrot = 0;
CFG_cf_theme[i].cover_center_reflection_used = true;
CFG_cf_theme[i].cover_distance_from_center_left_x = -36;
CFG_cf_theme[i].cover_distance_from_center_left_y = 0;
CFG_cf_theme[i].cover_distance_from_center_left_z = 0;
CFG_cf_theme[i].cover_distance_between_covers_left_x = -22;
CFG_cf_theme[i].cover_distance_between_covers_left_y = 0;
CFG_cf_theme[i].cover_distance_between_covers_left_z = 0;
CFG_cf_theme[i].cover_left_xpos = 0;
CFG_cf_theme[i].cover_left_ypos = 0;
CFG_cf_theme[i].cover_left_zpos = -167;
CFG_cf_theme[i].cover_left_xrot = 0;
CFG_cf_theme[i].cover_left_yrot = 0;
CFG_cf_theme[i].cover_left_zrot = 0;
CFG_cf_theme[i].cover_distance_from_center_right_x = 36;
CFG_cf_theme[i].cover_distance_from_center_right_y = 0;
CFG_cf_theme[i].cover_distance_from_center_right_z = 0;
CFG_cf_theme[i].cover_distance_between_covers_right_x = 22;
CFG_cf_theme[i].cover_distance_between_covers_right_y = 0;
CFG_cf_theme[i].cover_distance_between_covers_right_z = 0;
CFG_cf_theme[i].cover_right_xpos = 0;
CFG_cf_theme[i].cover_right_ypos = 0;
CFG_cf_theme[i].cover_right_zpos = -167;
CFG_cf_theme[i].cover_right_xrot = 0;
CFG_cf_theme[i].cover_right_yrot = 0;
CFG_cf_theme[i].cover_right_zrot = 0;
// frontrow
i++;
CFG_cf_theme[i].rotation_frames = 40;
CFG_cf_theme[i].rotation_frames_fast = 7;
CFG_cf_theme[i].cam_pos_x = 0.0;
CFG_cf_theme[i].cam_pos_y = 0.0;
CFG_cf_theme[i].cam_pos_z = 0.0;
CFG_cf_theme[i].cam_look_x = 0.0;
CFG_cf_theme[i].cam_look_y = 0.0;
CFG_cf_theme[i].cam_look_z = -1.0;
CFG_cf_theme[i].number_of_side_covers = 4;
CFG_cf_theme[i].reflections_color_bottom = 0x666666FF;
CFG_cf_theme[i].reflections_color_top = 0xAAAAAA33;
CFG_cf_theme[i].alpha_rolloff = 0;
CFG_cf_theme[i].floating_cover = false;
CFG_cf_theme[i].title_text_xpos = -1;
CFG_cf_theme[i].title_text_ypos = 434;
CFG_cf_theme[i].cover_rolloff_x = 0;
CFG_cf_theme[i].cover_rolloff_y = 0;
CFG_cf_theme[i].cover_rolloff_z = 0;
CFG_cf_theme[i].cover_center_xpos = 0;
CFG_cf_theme[i].cover_center_ypos = 0;
CFG_cf_theme[i].cover_center_zpos = -70;
CFG_cf_theme[i].cover_center_xrot = 0;
CFG_cf_theme[i].cover_center_yrot = 0;
CFG_cf_theme[i].cover_center_zrot = 0;
CFG_cf_theme[i].cover_center_reflection_used = true;
CFG_cf_theme[i].cover_distance_from_center_left_x = -27;
CFG_cf_theme[i].cover_distance_from_center_left_y = 0;
CFG_cf_theme[i].cover_distance_from_center_left_z = 47;
CFG_cf_theme[i].cover_distance_between_covers_left_x = -35;
CFG_cf_theme[i].cover_distance_between_covers_left_y = 0;
CFG_cf_theme[i].cover_distance_between_covers_left_z = 80;
CFG_cf_theme[i].cover_left_xpos = 0;
CFG_cf_theme[i].cover_left_ypos = 0;
CFG_cf_theme[i].cover_left_zpos = -87;
CFG_cf_theme[i].cover_left_xrot = 0;
CFG_cf_theme[i].cover_left_yrot = 0;
CFG_cf_theme[i].cover_left_zrot = 0;
if (CFG.widescreen) {
CFG_cf_theme[i].cover_distance_from_center_right_x = 37;
CFG_cf_theme[i].cover_distance_from_center_right_y = 0;
CFG_cf_theme[i].cover_distance_from_center_right_z = -30;
CFG_cf_theme[i].cover_distance_between_covers_right_x = 45;
CFG_cf_theme[i].cover_distance_between_covers_right_y = 0;
CFG_cf_theme[i].cover_distance_between_covers_right_z = -50;
} else {
CFG_cf_theme[i].cover_distance_from_center_right_x = 34;
CFG_cf_theme[i].cover_distance_from_center_right_y = 0;
CFG_cf_theme[i].cover_distance_from_center_right_z = -37;
CFG_cf_theme[i].cover_distance_between_covers_right_x = 50;
CFG_cf_theme[i].cover_distance_between_covers_right_y = 0;
CFG_cf_theme[i].cover_distance_between_covers_right_z = -80;
}
CFG_cf_theme[i].cover_right_xpos = 0;
CFG_cf_theme[i].cover_right_ypos = 0;
CFG_cf_theme[i].cover_right_zpos = -87;
CFG_cf_theme[i].cover_right_xrot = 0;
CFG_cf_theme[i].cover_right_yrot = 0;
CFG_cf_theme[i].cover_right_zrot = 0;
// vertical
i++;
CFG_cf_theme[i].rotation_frames = 40;
CFG_cf_theme[i].rotation_frames_fast = 7;
CFG_cf_theme[i].cam_pos_x = 0.0;
CFG_cf_theme[i].cam_pos_y = 0.0;
CFG_cf_theme[i].cam_pos_z = 0.0;
CFG_cf_theme[i].cam_look_x = 0.0;
CFG_cf_theme[i].cam_look_y = 0.0;
CFG_cf_theme[i].cam_look_z = -1.0;
CFG_cf_theme[i].number_of_side_covers = 4;
CFG_cf_theme[i].reflections_color_bottom = 0xFFFFFF00;
CFG_cf_theme[i].reflections_color_top = 0xFFFFFF00;
CFG_cf_theme[i].alpha_rolloff = 0;
CFG_cf_theme[i].floating_cover = true;
CFG_cf_theme[i].title_text_xpos = -1;
CFG_cf_theme[i].title_text_ypos = 434;
CFG_cf_theme[i].cover_rolloff_x = 0;
CFG_cf_theme[i].cover_rolloff_y = 0;
CFG_cf_theme[i].cover_rolloff_z = 0;
CFG_cf_theme[i].cover_center_xpos = 8;
CFG_cf_theme[i].cover_center_ypos = 0;
CFG_cf_theme[i].cover_center_zpos = -85;
CFG_cf_theme[i].cover_center_xrot = 0;
CFG_cf_theme[i].cover_center_yrot = 0;
CFG_cf_theme[i].cover_center_zrot = 0;
CFG_cf_theme[i].cover_center_reflection_used = false;
CFG_cf_theme[i].cover_distance_from_center_left_x = 0;
CFG_cf_theme[i].cover_distance_from_center_left_y = -25;
CFG_cf_theme[i].cover_distance_from_center_left_z = 0;
CFG_cf_theme[i].cover_distance_between_covers_left_x = -25;
CFG_cf_theme[i].cover_distance_between_covers_left_y = -5;
CFG_cf_theme[i].cover_distance_between_covers_left_z = 0;
CFG_cf_theme[i].cover_left_xpos = -15;
CFG_cf_theme[i].cover_left_ypos = 0;
CFG_cf_theme[i].cover_left_zpos = -130;
CFG_cf_theme[i].cover_left_xrot = 0;
CFG_cf_theme[i].cover_left_yrot = 0;
CFG_cf_theme[i].cover_left_zrot = 0;
CFG_cf_theme[i].cover_distance_from_center_right_x = 0;
CFG_cf_theme[i].cover_distance_from_center_right_y = 25;
CFG_cf_theme[i].cover_distance_from_center_right_z = 0;
CFG_cf_theme[i].cover_distance_between_covers_right_x = -25;
CFG_cf_theme[i].cover_distance_between_covers_right_y = 5;
CFG_cf_theme[i].cover_distance_between_covers_right_z = 0;
CFG_cf_theme[i].cover_right_xpos = -15;
CFG_cf_theme[i].cover_right_ypos = 0;
CFG_cf_theme[i].cover_right_zpos = -130;
CFG_cf_theme[i].cover_right_xrot = 0;
CFG_cf_theme[i].cover_right_yrot = 0;
CFG_cf_theme[i].cover_right_zrot = 0;
// carousel
i++;
CFG_cf_theme[i].rotation_frames = 40;
CFG_cf_theme[i].rotation_frames_fast = 7;
CFG_cf_theme[i].cam_pos_x = 0.0;
CFG_cf_theme[i].cam_pos_y = 0.0;
CFG_cf_theme[i].cam_pos_z = 0.0;
CFG_cf_theme[i].cam_look_x = 0.0;
CFG_cf_theme[i].cam_look_y = 0.0;
CFG_cf_theme[i].cam_look_z = -1.0;
CFG_cf_theme[i].number_of_side_covers = 4;
CFG_cf_theme[i].reflections_color_bottom = 0x666666FF;
CFG_cf_theme[i].reflections_color_top = 0xAAAAAA33;
CFG_cf_theme[i].alpha_rolloff = 0;
CFG_cf_theme[i].floating_cover = false;
CFG_cf_theme[i].title_text_xpos = -1;
CFG_cf_theme[i].title_text_ypos = 434;
CFG_cf_theme[i].cover_rolloff_x = 0;
CFG_cf_theme[i].cover_rolloff_y = 17;
CFG_cf_theme[i].cover_rolloff_z = 0;
CFG_cf_theme[i].cover_center_xpos = 0;
CFG_cf_theme[i].cover_center_ypos = 0;
CFG_cf_theme[i].cover_center_zpos = -122;
CFG_cf_theme[i].cover_center_xrot = 0;
CFG_cf_theme[i].cover_center_yrot = 0;
CFG_cf_theme[i].cover_center_zrot = 0;
CFG_cf_theme[i].cover_center_reflection_used = true;
CFG_cf_theme[i].cover_distance_from_center_left_x = -22;
CFG_cf_theme[i].cover_distance_from_center_left_y = 0;
CFG_cf_theme[i].cover_distance_from_center_left_z = 0;
CFG_cf_theme[i].cover_distance_between_covers_left_x = -22;
CFG_cf_theme[i].cover_distance_between_covers_left_y = 0;
CFG_cf_theme[i].cover_distance_between_covers_left_z = 0;
CFG_cf_theme[i].cover_left_xpos = 0;
CFG_cf_theme[i].cover_left_ypos = 0;
CFG_cf_theme[i].cover_left_zpos = -120;
CFG_cf_theme[i].cover_left_xrot = 0;
CFG_cf_theme[i].cover_left_yrot = 12;
CFG_cf_theme[i].cover_left_zrot = 0;
CFG_cf_theme[i].cover_distance_from_center_right_x = 22;
CFG_cf_theme[i].cover_distance_from_center_right_y = 0;
CFG_cf_theme[i].cover_distance_from_center_right_z = 0;
CFG_cf_theme[i].cover_distance_between_covers_right_x = 22;
CFG_cf_theme[i].cover_distance_between_covers_right_y = 0;
CFG_cf_theme[i].cover_distance_between_covers_right_z = 0;
CFG_cf_theme[i].cover_right_xpos = 0;
CFG_cf_theme[i].cover_right_ypos = 0;
CFG_cf_theme[i].cover_right_zpos = -120;
CFG_cf_theme[i].cover_right_xrot = 0;
CFG_cf_theme[i].cover_right_yrot = -12;
CFG_cf_theme[i].cover_right_zrot = 0;
/*
// Bookshelf
i++;
CFG_cf_theme[i].rotation_frames = 17;
CFG_cf_theme[i].rotation_frames_fast = 6;
CFG_cf_theme[i].cam_pos_x = 0.0;
CFG_cf_theme[i].cam_pos_y = 0.0;
CFG_cf_theme[i].cam_pos_z = 0.0;
CFG_cf_theme[i].cam_look_x = 0.0;
CFG_cf_theme[i].cam_look_y = 0.0;
CFG_cf_theme[i].cam_look_z = -1.0;
if (CFG.widescreen)
CFG_cf_theme[i].number_of_side_covers = 5;
else
CFG_cf_theme[i].number_of_side_covers = 5;
CFG_cf_theme[i].reflections_color_bottom = 0x666666FF;
CFG_cf_theme[i].reflections_color_top = 0xAAAAAA33;
CFG_cf_theme[i].alpha_rolloff = 0;
CFG_cf_theme[i].floating_cover = false;
CFG_cf_theme[i].title_text_xpos = -1;
CFG_cf_theme[i].title_text_ypos = 434;
CFG_cf_theme[i].cover_rolloff_x = 0;
CFG_cf_theme[i].cover_rolloff_y = 0;
CFG_cf_theme[i].cover_rolloff_z = 0;
CFG_cf_theme[i].cover_center_xpos = 1;
CFG_cf_theme[i].cover_center_ypos = 0;
CFG_cf_theme[i].cover_center_zpos = -75;
CFG_cf_theme[i].cover_center_xrot = 0;
CFG_cf_theme[i].cover_center_yrot = 0;
CFG_cf_theme[i].cover_center_zrot = 0;
CFG_cf_theme[i].cover_center_reflection_used = true;
CFG_cf_theme[i].cover_distance_from_center_left_x = -13;
CFG_cf_theme[i].cover_distance_from_center_left_y = 0;
CFG_cf_theme[i].cover_distance_from_center_left_z = 0;
CFG_cf_theme[i].cover_distance_between_covers_left_x = -2;
CFG_cf_theme[i].cover_distance_between_covers_left_y = 0;
CFG_cf_theme[i].cover_distance_between_covers_left_z = 0;
CFG_cf_theme[i].cover_left_xpos = 0;
CFG_cf_theme[i].cover_left_ypos = 0;
CFG_cf_theme[i].cover_left_zpos = -75;
CFG_cf_theme[i].cover_left_xrot = 0;
CFG_cf_theme[i].cover_left_yrot = 90;
CFG_cf_theme[i].cover_left_zrot = 0;
CFG_cf_theme[i].cover_distance_from_center_right_x = 13;
CFG_cf_theme[i].cover_distance_from_center_right_y = 0;
CFG_cf_theme[i].cover_distance_from_center_right_z = 0;
CFG_cf_theme[i].cover_distance_between_covers_right_x = 2;
CFG_cf_theme[i].cover_distance_between_covers_right_y = 0;
CFG_cf_theme[i].cover_distance_between_covers_right_z = 0;
CFG_cf_theme[i].cover_right_xpos = 0;
CFG_cf_theme[i].cover_right_ypos = 0;
CFG_cf_theme[i].cover_right_zpos = -75;
CFG_cf_theme[i].cover_right_xrot = 0;
CFG_cf_theme[i].cover_right_yrot = 90;
CFG_cf_theme[i].cover_right_zrot = 0;
*/
}
// theme controls the looks, not behaviour
void CFG_Default_Theme()
{
CFG_Default_Coverflow_Themes();
*CFG.theme = 0;
snprintf(D_S(CFG.background), "%s/%s", USBLOADER_PATH, "background.png");
snprintf(D_S(CFG.w_background), "%s/%s", USBLOADER_PATH, "background_wide.png");
snprintf(D_S(CFG.bg_gui), "%s/%s", USBLOADER_PATH, "bg_gui.png");
STRCOPY(CFG.theme_path, USBLOADER_PATH);
*CFG.bg_gui_wide = 0;
CFG.covers = 1;
CFG.hide_header = 0;
CFG.hide_hddinfo = CFG_HIDE_HDDINFO;
CFG.hide_footer = 0;
CFG.console_transparent = 0;
//CFG.buttons = CFG_BTN_OPTIONS_1;
strcpy(CFG.cursor, ">>");
strcpy(CFG.cursor_space, " ");
strcpy(CFG.menu_plus, "[+] ");
strcpy(CFG.menu_plus_s, " ");
strcpy(CFG.favorite, "*");
strcpy(CFG.saved, "#");
CFG.gui_text_cfg.color = 0x000000FF; // black
CFG.gui_text_cfg.outline = 0xFF; //0;
CFG.gui_text_cfg.outline_auto = 1; //0;
CFG.gui_text_cfg.shadow = 0;
CFG.gui_text_cfg.shadow_auto = 0;
CFG.gui_text2_cfg.color = 0xFFFFFFFF; // white
CFG.gui_text2_cfg.outline = 0xFF;
CFG.gui_text2_cfg.outline_auto = 1;
CFG.gui_text2_cfg.shadow = 0;
CFG.gui_text2_cfg.shadow_auto = 0;
CFG.gui_tc[GUI_TC_MENU] = wgui_fc;
CFG.gui_tc[GUI_TC_TITLE] =
CFG.gui_tc[GUI_TC_BUTTON] =
CFG.gui_tc[GUI_TC_RADIO] =
CFG.gui_tc[GUI_TC_CHECKBOX] =
CFG.gui_tc[GUI_TC_MENU];
CFG.gui_tc[GUI_TC_INFO] = text_fc;
CFG.gui_tc[GUI_TC_ABOUT] = about_fc;
CFG.gui_window_color[GUI_COLOR_BASE] = 0xFFFFFF80;
CFG.gui_window_color[GUI_COLOR_POPUP] = 0xFFFFFFB0;
memset(CFG.gui_button, 0, sizeof(CFG.gui_button));
CFG.gui_bar = 1;
CFG.gui_title_top = 0;
//set cover and console postition defaults
CFG.layout = CFG_LAYOUT_LARGE_3;
cfg_layout();
//set cover height and width
cfg_set_cover_style(CFG_COVER_STYLE_2D);
set_colors(CFG_COLORS_DARK);
//set theme preview image size and pos
CFG.theme_previewX = -1;
CFG.theme_previewY = -1;
CFG.theme_previewW = 0;
CFG.theme_previewH = 0;
CFG.w_theme_previewX = -1;
CFG.w_theme_previewY = -1;
CFG.w_theme_previewW = 0;
CFG.w_theme_previewH = 0;
//set up button mappings
CFG.button_A = CFG_BTN_BOOT_GAME;
CFG.button_B = CFG_BTN_GUI;
CFG.button_1 = CFG_BTN_OPTIONS;
CFG.button_2 = CFG_BTN_FAVORITES;
CFG.button_H = CFG_BTN_REBOOT;
CFG.button_P = CFG_BTN_INSTALL;
CFG.button_M = CFG_BTN_MAIN_MENU;
CFG.button_X = CFG_BTN_2;
CFG.button_Y = CFG_BTN_1;
CFG.button_Z = CFG_BTN_B;
CFG.button_C = CFG_BTN_A;
CFG.button_L = CFG_BTN_M;
CFG.button_R = CFG_BTN_P;
CFG.home = CFG_HOME_REBOOT;
CFG.button_gui = NUM_BUTTON_B;
CFG.button_opt = NUM_BUTTON_1;
CFG.button_fav = NUM_BUTTON_2;
CFG.button_confirm.mask = WPAD_BUTTON_A;
CFG.button_confirm.num = NUM_BUTTON_A;
CFG.button_cancel.mask = WPAD_BUTTON_B;
CFG.button_cancel.num = NUM_BUTTON_B;
CFG.button_exit.mask = WPAD_BUTTON_HOME;
CFG.button_exit.num = NUM_BUTTON_HOME;
CFG.button_other.mask = WPAD_BUTTON_1;
CFG.button_other.num = NUM_BUTTON_1;
CFG.button_save.mask = WPAD_BUTTON_2;
CFG.button_save.num = NUM_BUTTON_2;
memset(&CFG.gui_cover_area, 0, sizeof(CFG.gui_cover_area));
memset(&CFG.gui_title_area, 0, sizeof(CFG.gui_title_area));
CFG.gui_clock_pos.x = -1;
CFG.gui_page_pos.x = -1;
}
void CFG_default_path()
{
snprintf(D_S(CFG.covers_path), "%s/%s", USBLOADER_PATH, "covers");
cfg_set_covers_path();
CFG_Default_Theme();
snprintf(D_S(CFG.bg_gui_wide), "%s/%s", USBLOADER_PATH, "bg_gui_wide.png");
}
void CFG_Default()
{
memset(&CFG, 0, sizeof(CFG));
// set coverflow defaults
CFG_Default_Coverflow();
CFG_default_path();
cfg_default_url();
//STRCOPY(CFG.gui_font, "font.png");
STRCOPY(CFG.gui_font, "font_uni.png");
//CFG.home = CFG_HOME_REBOOT;
#ifdef BUILD_DBG
CFG.debug = BUILD_DBG;
CFG.home = CFG_HOME_SCRSHOT;
#else
CFG.debug = 0;
CFG.home = CFG_HOME_REBOOT;
#endif
CFG.device = CFG_DEV_ASK;
STRCOPY(CFG.partition, CFG_DEFAULT_PARTITION);
CFG.confirm_start = 1;
CFG.install_partitions = CFG_INSTALL_GAME; //CFG_INSTALL_ALL;
CFG.disable_format = 0;
CFG.disable_remove = 0;
CFG.disable_install = 0;
CFG.disable_options = 0;
CFG.music = 1;
CFG.widescreen = CFG_WIDE_AUTO;
CFG.gui = CFG_GUI_START_WGUI;
CFG.gui_menu = 1;
CFG.gui_start = 1;
CFG.gui_rows = 2;
CFG.admin_lock = 1;
CFG.admin_mode_locked = 1;
STRCOPY(CFG.unlock_password, CFG_UNLOCK_PASSWORD);
CFG.gui_antialias = 4;
CFG.gui_compress_covers = 1;
CFG.gui_pointer_scroll = 1;
// default game settings
CFG.game.video = CFG_VIDEO_AUTO;
CFG.game.hooktype = 1; // VBI
CFG.game.wide_screen = 0; // WIDE IS OFF
CFG.game.ntsc_j_patch = 0;
CFG.game.channel_boot = 0;
CFG.game.nodisc = 0;
CFG.game.screenshot = 0;
CFG.game.block_ios_reload = 2; // 2=auto
CFG.game.alt_controller_cfg = 0;
cfg_ios_set_idx(DEFAULT_IOS_IDX);
// all other game settings are 0 (memset(0) above)
STRCOPY(CFG.sort_ignore, "A,An,The");
CFG.clock_style = 24;
// profiles
CFG.num_profiles = 1;
//CFG.current_profile = 0;
STRCOPY(CFG.profile_names[0], "default");
STRCOPY(CFG.titles_url, "http://www.gametdb.com/titles.txt?LANG={DBL}");
CFG.intro = 4;
CFG.fat_install_dir = 1;
CFG.fat_split_size = 4;
CFG.db_show_info = 1;
//CFG.db_ignore_titles = 0;
//CFG.write_playlog = 0;
CFG.write_playstats = 1;
STRCOPY(CFG.db_url, "http://www.gametdb.com/wiitdb.zip?LANG={DBL}&FALLBACK=true&GAMECUBE=true&WIIWARE=true");
STRCOPY(CFG.db_language, auto_cc());
STRCOPY(CFG.translation, getLang(CONF_GetLanguage()));
STRCOPY(CFG.sort, "title-asc");
CFG.delay_patch = 1;
CFG.theme_previews = 1;
// dvd slot check is handled properly now by all cios
// so the patch is disabled by default
CFG.disable_dvd_patch = 1;
//CFG.dml = CFG_DM_2_2;
STRCOPY(CFG.nand_emu_path, "usb:/nand");
STRCOPY(CFG.wbfs_fat_dir, "/wbfs");
CFG.game.nand_emu = 0;
}
bool map_auto_token(char *name, char *name2, char *val, struct TextMap *map, struct MenuButton *var)
{
int single, all;
char *next;
char buf[12];
if (strcmp(name, name2) != 0) return 0;
next = val;
all = 0;
while ((next = split_tokens(buf, next, ",", 12)))
{
int res;
buf[1]=0;
res = map_auto_i(name, name2, buf, map, &single);
if (res >= 0 && !all) var->num = single;
if (res >= 0) all |= buttonmap[MASTER][single];
}
if (all) {
var->mask = all;
return 1;
} else return 0;
}
bool cfg_map_auto_token(char *name, struct TextMap *map, struct MenuButton *var)
{
return map_auto_token(name, cfg_name, cfg_val, map, var);
}
u32 hash_id4(void *cb, void *id)
{
// id4 is usually unique, except for customs
return hash_string_n(id, 4);
}
u32 hash_id6(void *cb, void *id)
{
return hash_string_n(id, 6);
}
bool title_cmp_id6(void *cb, void *key, int i)
{
if (i < 0 || i >= num_title) return false;
return strncmp((char*)cfg_title[i].id, (char*)key, 6) == 0;
}
bool title_cmp_id4(void *cb, void *key, int i)
{
if (i < 0 || i >= num_title) return false;
return strncmp((char*)cfg_title[i].id, (char*)key, 4) == 0;
}
int* title_get_hnext(void *cb, int i)
{
if (i < 0 || i >= num_title) return NULL;
return &cfg_title[i].hnext;
}
struct ID_Title* cfg_get_id_title(u8 *id)
{
// check ID6 first
int i = hash_get(&title_hash_id6, id);
if (i < 0) {
// if not found try ID4
i = hash_get(&title_hash_id4, id);
}
if (i >= 0 && i < num_title) return &cfg_title[i];
return NULL;
}
char *cfg_get_title(u8 *id)
{
// titles.txt
struct ID_Title *idt = cfg_get_id_title(id);
if (idt) return idt->title;
// wiitdb
if (!CFG.db_ignore_titles) {
gameXMLinfo *g = get_game_info_id(id);
if (!g) return NULL;
if (g->title[0] != 0) return g->title;
}
return NULL;
}
char *get_title(struct discHdr *header)
{
// titles.txt or wiitdb
char *title;
if ((memcmp("G",(char*)header->id,1)==0) && (strlen((char*)header->id)>6))
title = header->title;
else
title = cfg_get_title(header->id);
if (title) return title;
// disc header
return header->title;
}
void title_set(char *id, char *title)
{
struct ID_Title *idt = cfg_get_id_title((u8*)id);
if (idt && strncmp(id, (char*)idt->id, 6) == 0) {
// replace
mbs_copy(idt->title, title, TITLE_MAX);
} else {
cfg_title = mem1_realloc(cfg_title, (num_title+1) * sizeof(struct ID_Title));
if (!cfg_title) {
// error
num_title = 0;
return;
}
// add
memset(&cfg_title[num_title], 0, sizeof(cfg_title[num_title]));
strcopy((char*)cfg_title[num_title].id, id, 7);
mbs_copy(cfg_title[num_title].title, title, TITLE_MAX);
num_title++;
// update hash
if (id[3] == 0 || id[4] == 0) {
// id3 or id4
hash_check_init(&title_hash_id4, 0, NULL, &hash_id4, &title_cmp_id4, &title_get_hnext);
hash_add(&title_hash_id4, id, num_title - 1);
} else {
// id6
hash_check_init(&title_hash_id6, 0, NULL, &hash_id6, &title_cmp_id6, &title_get_hnext);
hash_add(&title_hash_id6, id, num_title - 1);
}
}
}
#define COPY_PATH(D,S) copy_path(D,S,sizeof(D))
void copy_path(char *dest, char *val, int size)
{
if (strchr(val, ':')) {
// absolute path with drive (sd:/images/...)
strcopy(dest, val, size);
} else if (val[0] == '/') {
// absolute path without drive (/images/...)
snprintf(dest, size, "%s%s", FAT_DRIVE, val);
} else {
snprintf(dest, size, "%s/%s", USBLOADER_PATH, val);
}
}
bool copy_theme_path(char *dest, char *val, int size)
{
// check if it's an absolute path (contains : as in sd:/...)
if (strchr(val, ':')) {
// absolute path with drive (sd:/images/...)
strcopy(dest, val, size);
return true;
} else if (val[0] == '/') {
// absolute path without drive (/images/...)
snprintf(dest, size, "%s%s", FAT_DRIVE, val);
return true;
} else if (*theme_path) {
struct stat st;
snprintf(dest, size, "%s/%s", theme_path, val);
if (stat(dest, &st) == 0) return true;
}
snprintf(dest, size, "%s/%s", USBLOADER_PATH, val);
return false;
}
int find_in_hdr_list(char *id, struct discHdr *list, int num)
{
int i;
for (i=0; i<num; i++) {
if (memcmp(id, list[i].id, 4) == 0) return i;
}
return -1;
}
int find_in_game_list(u8 *id, char list[][8], int num)
{
int i;
for (i=0; i<num; i++) {
if (memcmp(id, list[i], 4) == 0) return i;
}
return -1;
}
void remove_from_list(int i, char list[][8], int *num)
{
memset( list[i], 0, sizeof(list[i]) );
if (i < *num - 1) {
memmove( &list[i], &list[i+1], (*num - i - 1) * sizeof(list[0]) );
}
*num -= 1;
}
bool add_to_list(u8 *id, char list[][8], int *num, int maxn)
{
if (*num >= maxn) return false;
// add
memset(list[*num], 0, sizeof(list[0]));
memcpy(list[*num], id, 4);
*num += 1;
return true;
}
bool is_in_game_list(u8 *id, char list[][8], int num)
{
int i = find_in_game_list(id, list, num);
return (i >= 0);
}
bool is_in_hide_list(struct discHdr *game)
{
return is_in_game_list(game->id, CFG.hide_game, CFG.num_hide_game);
}
void cfg_id_list(char *name, char list[][8], int *num_list, int max_list)
{
int i;
if (strcmp(name, cfg_name)==0) {
char id[8], *next = cfg_val;
while (next) {
*id = 0;
next = split_token(id, next, ',', sizeof(id));
if (strcmp(id, "0")==0) {
// reset list
*num_list = 0;
}
if (strlen(id) == 4) {
if (*num_list >= max_list) continue;
// add id to hide list.
i = find_in_game_list((u8*)id, list, *num_list);
if (i < 0) {
strcopy(list[*num_list], id, 8);
(*num_list)++;
}
}
}
}
}
bool cfg_color(char *name, u32 *var)
{
if (cfg_map(name, "black", (int*)var, 0x000000FF)) return true;
if (cfg_map(name, "white", (int*)var, 0xFFFFFFFF)) return true;
if (cfg_int_hex(name, (int*)var)) return true;
return false;
}
// text color
void font_color_cfg_set(char *base_name, struct FontColor_CFG *fc)
{
if (strncmp(cfg_name, base_name, strlen(base_name)) != 0) return;
char name[100];
char *old_name;
STRCOPY(name, cfg_name);
str_replace(name, base_name, "gui_text_", sizeof(name));
old_name = cfg_name;
cfg_name = name;
cfg_color("gui_text_color", &fc->color);
if (cfg_color("gui_text_outline", &fc->outline)) {
if (strlen(cfg_val) == 2) fc->outline_auto = 1;
else fc->outline_auto = 0;
}
if (cfg_color("gui_text_shadow", &fc->shadow)) {
if (strlen(cfg_val) == 2) fc->shadow_auto = 1;
else fc->shadow_auto = 0;
}
cfg_name = old_name;
}
bool font_color_set(char *name, struct FontColor *fc)
{
if (strcmp(name, cfg_name)) return false;
char color_val[16];
char *old_val = cfg_val;
char *next = cfg_val;
u32 *c = &fc->color;
int i = 0;
memset(fc, 0, sizeof(*fc));
while ((next = split_tokens(color_val, next, "/", sizeof(color_val)))) {
cfg_val = color_val;
if (!cfg_color(name, c+i)) break;
i++;
if (i >= 3) break;
}
cfg_val = old_val;
return true;
}
int get_outline_color(int text_color, int outline_color, int outline_auto)
{
unsigned color, alpha;
if (!outline_color) return 0;
if (outline_auto) {
// only alpha specified
int avg;
avg = ( ((text_color>>8) & 0xFF)
+ ((text_color>>16) & 0xFF)
+ ((text_color>>24) & 0xFF) ) / 3;
if (avg > 0x80) {
color = 0x00000000;
} else {
color = 0xFFFFFF00;
}
} else {
// full color specified
color = outline_color;
}
// apply text alpha to outline alpha
alpha = (outline_color & 0xFF) * (text_color & 0xFF) / 0xFF;
color = (color & 0xFFFFFF00) | alpha;
return color;
}
void expand_font_color_cfg(FontColor *fc, FontColor_CFG *fcc)
{
fc->color = fcc->color;
fc->outline = get_outline_color( fcc->color, fcc->outline, fcc->outline_auto);
fc->shadow = get_outline_color( fcc->color, fcc->shadow, fcc->shadow_auto);
}
int cfg_pos_xy(char *name, struct PosCoords *pos)
{
if (strcmp(name, cfg_name)) return 0;
int i, x, y;
pos->x = -1;
pos->y = -1;
i = sscanf(cfg_val, "%d,%d", &x, &y);
if (i == 2) {
// check for valid range
if (x >= 0 && y >= 0 && x < 640 && y < 480) {
pos->x = x;
pos->y = y;
return 1;
}
}
return -1;
}
int cfg_pos_area(char *name, struct RectCoords *pos, int min_w, int min_h)
{
if (strcmp(name, cfg_name)) return 0;
int i, x, y, w, h;
memset(pos, 0, sizeof(*pos));
i = sscanf(cfg_val, "%d,%d,%d,%d", &x, &y, &w, &h);
if (i == 4) {
// check for valid range
// min w * h : 480 * 320
if (x >= 0 && y >= 0 && w >= min_w && h >= min_h && x+w <= 640 && y+h <= 480) {
pos->x = x;
pos->y = y;
pos->w = w / 2 * 2;
pos->h = h / 2 * 2;
return 1;
}
}
return -1;
}
char *custom_button_name(int i);
char *strtolower(char *s)
{
char *ss = s;
int c;
while (*ss) {
c = (unsigned char)*ss;
*ss = tolower(c);
ss++;
}
return s;
}
// n starts at 0
char* get_token_n(char *dest, int size, char *src, char *delim, int n)
{
int i;
char *next = src;
*dest = 0;
for (i=0; i<=n; i++) {
next = split_tokens(dest, next, delim, size);
if (!next) break;
}
//dbg_printf("==== tok %d : %s.\n", n, dest);
return next;
}
bool cfg_gui_button(int i)
{
int ret;
char token[64];
char *save_val = cfg_val;
struct CfgButton *bb = &CFG.gui_button[i];
memset(bb, 0, sizeof(*bb));
ret = cfg_pos_area(cfg_name, &bb->pos, 4, 4);
if (ret <= 0) return false;
bb->enabled = 1;
// defaults:
CFG.gui_tc[GUI_TC_CBUTTON + i] = wgui_fc;
bb->hover_zoom = 10;
if (get_token_n(token, sizeof(token), cfg_val, ",", 4)) {
cfg_val = token;
font_color_set(cfg_name, &CFG.gui_tc[GUI_TC_CBUTTON + i]);
cfg_val = save_val;
}
if (get_token_n(token, sizeof(token), cfg_val, ",", 5)) {
STRCOPY(bb->image, token);
}
if (get_token_n(token, sizeof(token), cfg_val, ",", 6)) {
cfg_val = token;
cfg_map(cfg_name, "button", &bb->type, 0);
cfg_map(cfg_name, "icon", &bb->type, 1);
cfg_val = save_val;
}
if (get_token_n(token, sizeof(token), cfg_val, ",", 7)) {
cfg_val = token;
cfg_int_max(cfg_name, &bb->hover_zoom, 50);
cfg_val = save_val;
}
return true;
}
bool cfg_gui_custom_buttons()
{
int i;
// gui_button_main
// gui_button_quit ...
char *opt = "gui_button_";
int len = strlen(opt);
char *name = cfg_name + len;
char bname[32];
if (strncmp(cfg_name, opt, len) == 0) {
for (i=0; i<GUI_BUTTON_NUM; i++) {
STRCOPY(bname, custom_button_name(i));
strtolower(bname);
if (strcmp(name, bname) == 0) {
cfg_gui_button(i);
return true;
}
}
}
return false;
}
// theme options, these can be overriden in config.txt
void theme_set_base(char *name, char *val)
{
cfg_name = name;
cfg_val = val;
cfg_bool("hide_header", &CFG.hide_header);
cfg_bool("hide_hddinfo", &CFG.hide_hddinfo);
cfg_bool("hide_footer", &CFG.hide_footer);
/*cfg_map("buttons", "original", &CFG.buttons, CFG_BTN_ORIGINAL);
cfg_map("buttons", "options", &CFG.buttons, CFG_BTN_OPTIONS_1);
cfg_map("buttons", "options_1", &CFG.buttons, CFG_BTN_OPTIONS_1);
cfg_map("buttons", "options_B", &CFG.buttons, CFG_BTN_OPTIONS_B);*/
if (strcmp(name, "home")==0) {
if (strcmp(val, "exit")==0) {
CFG.button_H = CFG_BTN_EXIT;
CFG.home = CFG_HOME_EXIT;
} else if (strcmp(val, "reboot")==0) {
CFG.button_H = CFG_BTN_REBOOT;
CFG.home = CFG_HOME_REBOOT;
} else if (strcmp(val, "hbc")==0) {
CFG.button_H = CFG_BTN_HBC;
CFG.home = CFG_HOME_HBC;
} else if (strcmp(val, "screenshot")==0) {
CFG.button_H = CFG_BTN_SCREENSHOT;
CFG.home = CFG_HOME_SCRSHOT;
} else if (strcmp(val, "priiloader")==0) {
CFG.button_H = CFG_BTN_PRIILOADER;
CFG.home = CFG_HOME_PRIILOADER;
} else if (strcmp(val, "channel")==0) {
CFG.button_H = CFG_BTN_CHANNEL;
CFG.home = CFG_HOME_CHANNEL;
} else if (strcmp(val, "wii_menu")==0) {
CFG.button_H = CFG_BTN_WII_MENU;
CFG.home = CFG_HOME_WII_MENU;
} else if (strlen(val) == 4) {
CFG.button_H = *((int *)val);
CFG.home = *((int *)val);
} else if (strlen(val) == 8) {
sscanf(val, "%X", &CFG.button_H);
sscanf(val, "%X", &CFG.home);
}
}
if (strcmp(name, "buttons")==0) {
if (strcmp(val, "original")==0) {
CFG.button_1 = CFG_BTN_OPTIONS;
CFG.button_B = CFG_BTN_NOTHING;
} else if ((strcmp(val, "options")==0) || strcmp(val, "options_1")==0) {
CFG.button_1 = CFG_BTN_OPTIONS;
CFG.button_B = CFG_BTN_GUI;
} else if (strcmp(val, "options_B")==0) {
CFG.button_B = CFG_BTN_OPTIONS;
CFG.button_1 = CFG_BTN_GUI;
}
}
/*if (strcmp(name, "button_A") && !cfg_map_auto("button_A", map_button, &CFG.button_A) && strlen(val) == 4)
CFG.button_A = *((int *)val);*/
if (strcmp(name, "button_B") == 0 && !cfg_map_auto("button_B", map_button, &CFG.button_B)) {
if (strlen(val) == 4)
CFG.button_B = *((int *)val);
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.button_B);
}
if (strcmp(name, "button_1") == 0 && !cfg_map_auto("button_1", map_button, &CFG.button_1)) {
if (strlen(val) == 4)
CFG.button_1 = *((int *)val);
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.button_1);
}
if (strcmp(name, "button_2") == 0 && !cfg_map_auto("button_2", map_button, &CFG.button_2)) {
if (strlen(val) == 4)
CFG.button_2 = *((int *)val);
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.button_2);
}
if (strcmp(name, "button_H") == 0 && !cfg_map_auto("button_H", map_button, &CFG.button_H)) {
if (strlen(val) == 4)
CFG.button_H = *((int *)val);
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.button_H);
}
if (strcmp(name, "button_-") == 0 && !cfg_map_auto("button_-", map_button, &CFG.button_M)) {
if (strlen(val) == 4)
CFG.button_M = *((int *)val);
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.button_M);
}
if (strcmp(name, "button_+") == 0 && !cfg_map_auto("button_+", map_button, &CFG.button_P)) {
if (strlen(val) == 4)
CFG.button_P = *((int *)val);
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.button_P);
}
if (strcmp(name, "button_Z") == 0 && !cfg_map_auto("button_Z", map_button, &CFG.button_Z)) {
if (strlen(val) == 4)
CFG.button_Z = *((int *)val);
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.button_Z);
}
if (strcmp(name, "button_C") == 0 && !cfg_map_auto("button_C", map_button, &CFG.button_C)) {
if (strlen(val) == 4)
CFG.button_C = *((int *)val);
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.button_C);
}
if (strcmp(name, "button_Y") == 0 && !cfg_map_auto("button_Y", map_button, &CFG.button_Y)) {
if (strlen(val) == 4)
CFG.button_Y = *((int *)val);
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.button_Y);
}
if (strcmp(name, "button_X") == 0 && !cfg_map_auto("button_X", map_button, &CFG.button_X)) {
if (strlen(val) == 4)
CFG.button_X = *((int *)val);
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.button_X);
}
if (strcmp(name, "button_L") == 0 && !cfg_map_auto("button_L", map_button, &CFG.button_L)) {
if (strlen(val) == 4)
CFG.button_L = *((int *)val);
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.button_L);
}
if (strcmp(name, "button_R") == 0 && !cfg_map_auto("button_R", map_button, &CFG.button_R)) {
if (strlen(val) == 4)
CFG.button_R = *((int *)val);
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.button_R);
}
//cfg_map_auto_token("button_confirm", map_button_menu, &CFG.button_confirm);
cfg_map_auto_token("button_cancel", map_button_menu, &CFG.button_cancel);
cfg_map_auto_token("button_exit", map_button_menu, &CFG.button_exit);
cfg_map_auto_token("button_other", map_button_menu, &CFG.button_other);
cfg_map_auto_token("button_save", map_button_menu, &CFG.button_save);
// if simple is specified in theme it only affects the looks,
// does not lock down admin modes
int simpl;
if (cfg_bool("simple", &simpl)) {
if (simpl == 1) {
if (CFG_HIDE_HDDINFO == 0) {
// normal version affects hddinfo
// fat version does not change it.
CFG.hide_hddinfo = 1;
}
CFG.hide_hddinfo = 1;
CFG.hide_footer = 1;
} else { // simple == 0
if (CFG_HIDE_HDDINFO == 0) {
// normal version affects hddinfo
// fat version does not change it.
CFG.hide_hddinfo = 0;
}
CFG.hide_footer = 0;
}
}
if (strcmp(name, "cover_style")==0) {
cfg_set_cover_style_str(val);
}
if (strcmp(name, "cursor")==0) {
//unquote(CFG.cursor, val, 2+1);
unquote(CFG.cursor, val, sizeof(CFG.cursor));
mbs_trunc(CFG.cursor, 2);
int len = mbs_len(CFG.cursor);
memset(CFG.cursor_space, ' ', len);
CFG.cursor_space[len] = 0;
}
if (strcmp(name, "menu_plus")==0) {
unquote(CFG.menu_plus, val, sizeof(CFG.menu_plus));
mbs_trunc(CFG.menu_plus, 4);
int len = mbs_len(CFG.menu_plus);
memset(CFG.menu_plus_s, ' ', len);
CFG.menu_plus_s[len] = 0;
}
font_color_cfg_set("gui_text_", &CFG.gui_text_cfg);
font_color_cfg_set("gui_text2_", &CFG.gui_text2_cfg);
font_color_set("gui_text_color_info", &CFG.gui_tc[GUI_TC_INFO]);
if (font_color_set("gui_text_color_menu", &CFG.gui_tc[GUI_TC_MENU])) {
CFG.gui_tc[GUI_TC_TITLE] = CFG.gui_tc[GUI_TC_BUTTON] = CFG.gui_tc[GUI_TC_RADIO] =
CFG.gui_tc[GUI_TC_CHECKBOX] = CFG.gui_tc[GUI_TC_MENU];
}
font_color_set("gui_text_color_title", &CFG.gui_tc[GUI_TC_TITLE]);
if (font_color_set("gui_text_color_button", &CFG.gui_tc[GUI_TC_BUTTON])) {
CFG.gui_tc[GUI_TC_RADIO] = CFG.gui_tc[GUI_TC_CHECKBOX] = CFG.gui_tc[GUI_TC_BUTTON];
}
font_color_set("gui_text_color_radio", &CFG.gui_tc[GUI_TC_RADIO]);
font_color_set("gui_text_color_checkbox", &CFG.gui_tc[GUI_TC_CHECKBOX]);
cfg_color("gui_window_color_base", &CFG.gui_window_color[GUI_COLOR_BASE]);
cfg_color("gui_window_color_popup", &CFG.gui_window_color[GUI_COLOR_POPUP]);
cfg_bool("gui_title_top", &CFG.gui_title_top);
if (strcmp(name, "covers_size")==0) {
int w,h;
if (sscanf(val, "%d,%d", &w, &h) == 2) {
COVER_WIDTH = w / 2 * 2;
COVER_HEIGHT = h;
}
}
if (strcmp(name, "wcovers_size")==0) {
int w,h;
if (sscanf(val, "%d,%d", &w, &h) == 2) {
CFG.W_COVER_WIDTH = w / 2 * 2;
CFG.W_COVER_HEIGHT = h;
}
}
}
// theme options, these can not be overriden in config.txt
void theme_set(char *name, char *val)
{
cfg_name = name;
cfg_val = val;
theme_set_base(name, val);
if (cfg_map_auto("layout", map_layout, &CFG.layout)) {
cfg_layout();
}
cfg_bool("covers", &CFG.covers);
cfg_bool("console_transparent", &CFG.console_transparent);
cfg_int_max("color_header", &CFG.color_header, 15);
cfg_int_max("color_selected_fg", &CFG.color_selected_fg, 15);
cfg_int_max("color_selected_bg", &CFG.color_selected_bg, 15);
cfg_int_max("color_inactive", &CFG.color_inactive, 15);
cfg_int_max("color_footer", &CFG.color_footer, 15);
cfg_int_max("color_help", &CFG.color_help, 15);
int colors = 0;
cfg_map("colors", "mono", &colors, CFG_COLORS_MONO);
cfg_map("colors", "dark", &colors, CFG_COLORS_DARK);
cfg_map("colors", "light", &colors, CFG_COLORS_BRIGHT);
cfg_map("colors", "bright", &colors, CFG_COLORS_BRIGHT);
if (colors) set_colors(colors);
if (strcmp(name, "background")==0
|| strcmp(name, "background_base")==0)
{
if (strcmp(val, "0")==0) {
*CFG.background = 0;
} else {
copy_theme_path(CFG.background, val, sizeof(CFG.background));
}
}
if (strcmp(name, "wbackground")==0
|| strcmp(name, "wbackground_base")==0)
{
if (strcmp(val, "0")==0) {
*CFG.w_background = 0;
} else {
copy_theme_path(CFG.w_background, val, sizeof(CFG.w_background));
}
}
if (strcmp(name, "background_gui")==0)
{
if (strcmp(val, "0")==0) {
*CFG.bg_gui = 0;
} else {
copy_theme_path(CFG.bg_gui, val, sizeof(CFG.bg_gui));
}
}
if (strcmp(name, "wbackground_gui")==0)
{
if (strcmp(val, "0")==0) {
*CFG.bg_gui_wide = 0;
} else {
copy_theme_path(CFG.bg_gui_wide, val, sizeof(CFG.bg_gui_wide));
}
}
if (strcmp(name, "console_coords")==0) {
int x,y,w,h;
if (sscanf(val, "%d,%d,%d,%d", &x, &y, &w, &h) == 4) {
// round x coords to even values
CONSOLE_XCOORD = x / 2 * 2;
CONSOLE_YCOORD = y;
CONSOLE_WIDTH = w / 2 * 2;
CONSOLE_HEIGHT = h;
}
}
if (strcmp(name, "wconsole_coords")==0) {
int x,y,w,h;
if (sscanf(val, "%d,%d,%d,%d", &x, &y, &w, &h) == 4) {
// round x coords to even values
CFG.W_CONSOLE_XCOORD = x / 2 * 2;
CFG.W_CONSOLE_YCOORD = y;
CFG.W_CONSOLE_WIDTH = w / 2 * 2;
CFG.W_CONSOLE_HEIGHT = h;
}
}
if (strcmp(name, "console_color")==0) {
int fg,bg;
if (sscanf(val, "%d,%d", &fg, &bg) == 2) {
CONSOLE_FG_COLOR = fg;
CONSOLE_BG_COLOR = bg;
}
}
if (strcmp(name, "console_entries")==0) {
int n;
if (sscanf(val, "%d", &n) == 1) {
ENTRIES_PER_PAGE = n;
}
}
if (strcmp(name, "covers_coords")==0) {
int x,y;
if (sscanf(val, "%d,%d", &x, &y) == 2) {
COVER_XCOORD = x / 2 * 2;
COVER_YCOORD = y;
}
}
if (strcmp(name, "wcovers_coords")==0) {
int x,y;
if (sscanf(val, "%d,%d", &x, &y) == 2) {
CFG.W_COVER_XCOORD = x / 2 * 2;
CFG.W_COVER_YCOORD = y;
}
}
if (strcmp(name, "preview_coords")==0) {
int x,y,w,h;
if (sscanf(val, "%d,%d,%d,%d", &x, &y, &w, &h) == 4) {
CFG.theme_previewX = x;
CFG.theme_previewY = y;
CFG.theme_previewW = w / 2 * 2;
CFG.theme_previewH = h;
}
}
if (strcmp(name, "wpreview_coords")==0) {
int x,y,w,h;
if (sscanf(val, "%d,%d,%d,%d", &x, &y, &w, &h) == 4) {
CFG.w_theme_previewX = x;
CFG.w_theme_previewY = y;
CFG.w_theme_previewW = w / 2 * 2;
CFG.w_theme_previewH = h;
}
}
// coverflow reflection
if (strcmp(name, "coverflow_reflection")==0) {
int i, top=0, bot=0;
i = sscanf(val, "%x,%x", &top, &bot);
if (i > 0) {
if (i == 1) bot = top;
for (i=0; i<CF_THEME_NUM; i++) {
if (CFG_cf_theme[i].cover_center_reflection_used) {
CFG_cf_theme[i].reflections_color_bottom = top;
CFG_cf_theme[i].reflections_color_top = bot;
}
}
}
}
cfg_pos_area("gui_cover_area", &CFG.gui_cover_area, 480, 320);
cfg_pos_area("gui_title_area", &CFG.gui_title_area, 320, 10);
cfg_pos_xy("gui_clock_pos", &CFG.gui_clock_pos);
cfg_pos_xy("gui_page_pos", &CFG.gui_page_pos);
cfg_gui_custom_buttons();
cfg_bool("gui_bar", &CFG.gui_bar);
cfg_map("gui_bar", "top", &CFG.gui_bar, 2);
cfg_map("gui_bar", "bottom", &CFG.gui_bar, 3);
}
// global options
char *ios_str(int idx)
{
return map_ios[idx].name;
}
void set_recommended_cIOS_idx(u8 ios, bool onlyD2x) {
if (ios == cIOS_base[0]) {
cfg_ios_set_idx(CFG_IOS_245);
} else if (ios == cIOS_base[1]) {
cfg_ios_set_idx(CFG_IOS_246);
} else if (ios == cIOS_base[2]) {
cfg_ios_set_idx(CFG_IOS_247);
} else if (ios == cIOS_base[3]) {
cfg_ios_set_idx(CFG_IOS_248);
} else if (ios == cIOS_base[4]) {
cfg_ios_set_idx(CFG_IOS_249);
} else if (ios == cIOS_base[5]) {
cfg_ios_set_idx(CFG_IOS_250);
} else if (ios == cIOS_base[6]) {
cfg_ios_set_idx(CFG_IOS_251);
} else if (ios == cIOS_base[7]) {
cfg_ios_set_idx(CFG_IOS_252);
} else if (ios == cIOS_base[8] && !onlyD2x) {
cfg_ios_set_idx(CFG_IOS_222_MLOAD);
} else if (ios == cIOS_base[9] && !onlyD2x) {
cfg_ios_set_idx(CFG_IOS_223_MLOAD);
} else if (ios == cIOS_base[10] && !onlyD2x) {
cfg_ios_set_idx(CFG_IOS_224_MLOAD);
} else {
int i = 0;
for (i = 0; i < 11; i++) {
if (cIOS_base[i] == 56) {
cfg_ios_set_idx(i);
return;
}
}
cfg_ios_set_idx(CFG_IOS_249);
}
}
void cfg_ios_set_idx(int ios_idx)
{
CFG.ios = 249;
CFG.ios_yal = 0;
CFG.ios_mload = 0;
switch (ios_idx) {
case CFG_IOS_245:
CFG.ios = 245;
break;
case CFG_IOS_246:
CFG.ios = 246;
break;
case CFG_IOS_247:
CFG.ios = 247;
break;
case CFG_IOS_248:
CFG.ios = 248;
break;
case CFG_IOS_249:
CFG.ios = 249;
break;
case CFG_IOS_250:
CFG.ios = 250;
break;
case CFG_IOS_251:
CFG.ios = 251;
break;
case CFG_IOS_252:
CFG.ios = 252;
break;
case CFG_IOS_222_MLOAD:
CFG.ios = 222;
CFG.ios_yal = 1;
CFG.ios_mload = 1;
break;
case CFG_IOS_223_MLOAD:
CFG.ios = 223;
CFG.ios_yal = 1;
CFG.ios_mload = 1;
break;
case CFG_IOS_224_MLOAD:
CFG.ios = 224;
CFG.ios_yal = 1;
CFG.ios_mload = 1;
break;
case CFG_IOS_222_YAL:
CFG.ios = 222;
CFG.ios_yal = 1;
break;
case CFG_IOS_223_YAL:
CFG.ios = 223;
CFG.ios_yal = 1;
break;
default:
ios_idx = CFG_IOS_AUTO;
}
CFG.game.ios_idx = ios_idx;
}
bool cfg_ios_idx(char *name, char *val, int *idx)
{
int i, id;
i = map_auto_i("ios", name, val, map_ios, &id);
if (i < 0) return false;
if (i > CFG_IOS_MAX) return false;
if (i != id) return false; // safety check for correct defines
*idx = i;
return true;
}
void cfg_ios(char *name, char *val)
{
int i;
if (!cfg_ios_idx(name, val, &i)) return;
cfg_ios_set_idx(i);
/*
int ios;
if (sscanf(val, "%d", &ios) != 1) return;
CFG.game.ios_idx = i;
CFG.ios = ios;
CFG.ios_yal = 0;
CFG.ios_mload = 0;
if (strstr(val, "-yal")) {
CFG.ios_yal = 1;
}
if (strstr(val, "-mload")) {
CFG.ios_yal = 1;
CFG.ios_mload = 1;
}
*/
}
bool is_ios_idx_mload(int ios_idx)
{
switch (ios_idx) {
case CFG_IOS_222_MLOAD:
case CFG_IOS_223_MLOAD:
case CFG_IOS_224_MLOAD:
return true;
}
return false;
}
int get_ios_idx_type(int ios_idx)
{
switch (ios_idx) {
case CFG_IOS_245:
case CFG_IOS_246:
case CFG_IOS_247:
case CFG_IOS_248:
case CFG_IOS_249:
case CFG_IOS_250:
case CFG_IOS_251:
case CFG_IOS_252:
return IOS_TYPE_WANIN;
case CFG_IOS_222_MLOAD:
case CFG_IOS_223_MLOAD:
case CFG_IOS_224_MLOAD:
return IOS_TYPE_HERMES;
case CFG_IOS_222_YAL:
case CFG_IOS_223_YAL:
return IOS_TYPE_KWIIRK;
}
return IOS_TYPE_UNK;
}
void cfg_set_game(char *name, char *val, struct Game_CFG *game_cfg)
{
cfg_name = name;
cfg_val = val;
cfg_map_auto("language", map_language, &game_cfg->language);
cfg_map_auto("video", map_video, &game_cfg->video);
if (strcmp("video", name) == 0 && strcmp("vidtv", val) == 0)
{
game_cfg->video = CFG_VIDEO_AUTO;
game_cfg->vidtv = 1;
}
if (strcmp("video", name) == 0 && strcmp("patch", val) == 0)
{
game_cfg->video = CFG_VIDEO_AUTO;
game_cfg->video_patch = 1;
}
cfg_map_auto("video_patch", map_video_patch, &game_cfg->video_patch);
cfg_map_auto("nand_emu", map_nand_emu, &game_cfg->nand_emu);
cfg_map_auto("channel_boot", map_boot_method, &game_cfg->channel_boot);
cfg_bool("vidtv", &game_cfg->vidtv);
cfg_bool("country_patch", &game_cfg->country_patch);
cfg_bool("clear_patches", &game_cfg->clean);
cfg_map("clear_patches", "all", &game_cfg->clean, CFG_CLEAN_ALL);
cfg_bool("fix_002", &game_cfg->fix_002);
cfg_bool("wide_screen", &game_cfg->wide_screen);
cfg_bool("ntsc_j_patch", &game_cfg->ntsc_j_patch);
cfg_bool("nodisc", &game_cfg->nodisc);
cfg_bool("screenshot", &game_cfg->screenshot);
cfg_ios_idx(name, val, &game_cfg->ios_idx);
cfg_bool("block_ios_reload", &game_cfg->block_ios_reload);
cfg_map("block_ios_reload", "auto", &game_cfg->block_ios_reload, 2);
cfg_bool("alt_controller_cfg", &game_cfg->alt_controller_cfg);
if (strcmp("alt_dol", name) == 0) {
int set = 0;
if (cfg_bool("alt_dol", &game_cfg->alt_dol)) set = 1;
if (cfg_map ("alt_dol", "sd", &game_cfg->alt_dol, 1)) set = 1;
if (cfg_map ("alt_dol", "disc", &game_cfg->alt_dol, 2)) set = 1;
if (cfg_int_max("alt_dol", &game_cfg->alt_dol, 100)) set = 1;
if (!set) {
// name specified
game_cfg->alt_dol = 2;
STRCOPY(game_cfg->dol_name, val);
}
}
if (strcmp("dol_name", name) == 0 && *val) {
STRCOPY(game_cfg->dol_name, val);
}
cfg_bool("ocarina", &game_cfg->ocarina);
cfg_map_auto("hooktype", map_hook, &game_cfg->hooktype);
cfg_int_max("write_playlog", &game_cfg->write_playlog, 3);
}
bool cfg_set_gbl(char *name, char *val)
{
if (cfg_map("device", "ask", &CFG.device, CFG_DEV_ASK)) return true;
if (cfg_map("device", "usb", &CFG.device, CFG_DEV_USB)) return true;
if (cfg_map("device", "sdhc", &CFG.device, CFG_DEV_SDHC)) return true;
CFG_STR("partition", CFG.partition);
if (cfg_map_auto("gui_style", map_gui_style, &CFG.gui_style)) return true;
//if (cfg_int_max("dml", &CFG.dml, 6)) return true;
cfg_int_max("devo", &CFG.default_gc_loader,2);
cfg_bool("old_button_color", &CFG.old_button_color);
int rows = 0;
if (cfg_int_max("gui_rows", &rows, 4)) {
if (rows > 0) {
CFG.gui_rows = rows;
return true;
}
}
CFG_STR("profile", CFG.current_profile_name);
// theme must be last, because it changes cfg_name, cfg_val
if (strcmp(name, "theme")==0) {
if (*val) {
load_theme(val);
int i;
for (i=0; i<num_theme; i++) {
if (stricmp(val, theme_list[i]) == 0) {
cur_theme = i;
break;
}
}
return true;
}
}
return false;
}
void cfg_set_early(char *name, char *val)
{
cfg_name = name;
cfg_val = val;
cfg_int_max("debug", &CFG.debug, 255);
if (CFG.debug & 16) {
CFG.time_launch = 1;
CFG.debug &= ~16;
}
cfg_int_max("debug_gecko", &CFG.debug_gecko, 255);
cfg_bool("widescreen", &CFG.widescreen);
cfg_map("widescreen", "auto", &CFG.widescreen, CFG_WIDE_AUTO);
cfg_ios(name, val);
CFG_STR("partition", CFG.partition);
cfg_int_max("intro", &CFG.intro, 100);
}
void cfg_set(char *name, char *val)
{
cfg_name = name;
cfg_val = val;
theme_set(name, val);
cfg_set_early(name, val);
cfg_bool("start_favorites", &CFG.start_favorites);
cfg_bool("confirm_start", &CFG.confirm_start);
cfg_bool("confirm_ocarina", &CFG.confirm_ocarina);
cfg_bool("disable_format", &CFG.disable_format);
cfg_bool("disable_remove", &CFG.disable_remove);
cfg_bool("disable_install", &CFG.disable_install);
cfg_bool("disable_options", &CFG.disable_options);
cfg_bool("admin_lock", &CFG.admin_lock);
cfg_bool("admin_unlock", &CFG.admin_lock);
if (strcmp(name, "unlock_password")==0) {
STRCOPY(CFG.unlock_password, val);
}
cfg_int_max("cursor_jump", &CFG.cursor_jump, 50);
cfg_bool("console_mark_page", &CFG.console_mark_page);
cfg_bool("console_mark_favorite", &CFG.console_mark_favorite);
cfg_bool("console_mark_saved", &CFG.console_mark_saved);
// db options - Lustar
if (!strcmp(name, "db_url"))
strcpy(CFG.db_url,val);
if (!strcmp(name, "db_language")) {
if (strcmp(val, "auto") == 0 || strcmp(val, "AUTO") == 0) {
STRCOPY(CFG.db_language, auto_cc());
} else {
strcpy(CFG.db_language,val);
}
}
if (!strcmp(name, "sort"))
strcpy(CFG.sort,val);
if (!strcmp(name, "translation")) {
if (strcmp(val, "auto") == 0 || strcmp(val, "AUTO") == 0) {
STRCOPY(CFG.translation, getLang(CONF_GetLanguage()));
} else {
strcpy(CFG.translation,val);
}
}
cfg_bool("load_unifont", &CFG.load_unifont);
cfg_bool("gui_compress_covers", &CFG.gui_compress_covers);
cfg_int_max("gui_antialias", &CFG.gui_antialias, 4);
if (CFG.gui_antialias==0 || !CFG.gui_compress_covers) CFG.gui_antialias = 1;
if (CFG.gui_antialias > 1) CFG.gui_compress_covers = 1;
cfg_bool("gui_pointer_scroll", &CFG.gui_pointer_scroll);
if (cfg_set_gbl(name, val)) {
return;
}
cfg_set_game(name, val, &CFG.game);
if (!CFG.direct_launch) {
*CFG.game.dol_name = 0;
}
// covers path
if (strcmp(name, "covers_path")==0) {
COPY_PATH(CFG.covers_path, val);
cfg_set_covers_path();
}
if (strcmp(name, "covers_path_2d")==0) {
COPY_PATH(CFG.covers_path_2d, val);
CFG.covers_path_2d_set = 1;
}
if (strcmp(name, "covers_path_3d")==0) {
COPY_PATH(CFG.covers_path_3d, val);
}
if (strcmp(name, "covers_path_disc")==0) {
COPY_PATH(CFG.covers_path_disc, val);
}
if (strcmp(name, "covers_path_full")==0) {
COPY_PATH(CFG.covers_path_full, val);
}
CFG_STR_LIST("gamercard_url", CFG.gamercard_url);
CFG_STR_LIST("gamercard_key", CFG.gamercard_key);
// urls
CFG_STR("titles_url", CFG.titles_url);
CFG_STR("nand_emu_path", CFG.nand_emu_path);
CFG_STR("wbfs_fat_dir", CFG.wbfs_fat_dir);
CFG_STR_LIST("cover_url", CFG.cover_url_2d);
CFG_STR_LIST("cover_url_3d", CFG.cover_url_3d);
CFG_STR_LIST("cover_url_disc", CFG.cover_url_disc);
CFG_STR_LIST("cover_url_full", CFG.cover_url_full);
CFG_STR_LIST("cover_url_hq", CFG.cover_url_hq);
// download options
cfg_bool("download_all_styles", &CFG.download_all);
cfg_map("download_id_len", "4", &CFG.download_id_len, 4);
cfg_map("download_id_len", "6", &CFG.download_id_len, 6);
if (strcmp("download_cc_pal", name) == 0) {
if (strcmp(val, "auto") == 0 || strcmp(val, "AUTO") == 0) {
*CFG.download_cc_pal = 0;
} else if (strlen(val) == 2) {
strcpy(CFG.download_cc_pal, val);
}
}
// gui
if (cfg_int_max("gui", &CFG.gui, CFG_GUI_START_WGUI) ||
cfg_map("gui", "start", &CFG.gui, CFG_GUI_START_WGUI))
{
if (CFG.gui == CFG_GUI_START || CFG.gui == CFG_GUI_START_WGUI) {
CFG.gui_start = 1;
} else {
CFG.gui_start = 0;
}
if (CFG.gui > CFG_GUI_START) {
CFG.gui_menu = 1;
} else {
CFG.gui_menu = 0;
}
}
cfg_map("gui_transition", "scroll", &CFG.gui_transit, 0);
cfg_map("gui_transition", "fade", &CFG.gui_transit, 1);
CFG_STR("gui_font", CFG.gui_font);
cfg_bool("gui_lock", &CFG.gui_lock);
// simple changes dependant options
int simpl;
if (cfg_bool("simple", &simpl)) {
if (simpl == 1) {
CFG.confirm_start = 0;
//if (CFG_HIDE_HDDINFO == 0) {
// // normal version affects hddinfo
// // fat version does not change it.
// CFG.hide_hddinfo = 1;
//}
CFG.hide_footer = 1;
CFG.disable_remove = 1;
CFG.disable_install = 1;
CFG.disable_options = 1;
CFG.disable_format = 1;
} else { // simple == 0
CFG.confirm_start = 1;
//if (CFG_HIDE_HDDINFO == 0) {
// // normal version affects hddinfo
// // fat version does not change it.
// CFG.hide_hddinfo = 0;
//}
CFG.hide_footer = 0;
CFG.disable_remove = 0;
CFG.disable_install = 0;
CFG.disable_options = 0;
CFG.disable_format = 0;
}
}
cfg_map("install_partitions", "only_game",
&CFG.install_partitions, CFG_INSTALL_GAME);
cfg_map("install_partitions", "all",
&CFG.install_partitions, CFG_INSTALL_ALL);
cfg_map("install_partitions", "1:1",
&CFG.install_partitions, CFG_INSTALL_1_1);
cfg_map("install_partitions", "iso",
&CFG.install_partitions, CFG_INSTALL_ISO);
cfg_int_max("fat_split_size", &CFG.fat_split_size, 4);
//cfg_bool("write_playlog", &CFG.write_playlog);
cfg_int_max("fat_install_dir", &CFG.fat_install_dir, 3);
cfg_int_max("fs_install_layout", &CFG.fat_install_dir, 3);
cfg_bool("ntfs_write", &CFG.ntfs_write);
cfg_map("ntfs_write", "norecover", &CFG.ntfs_write, 2);
cfg_bool("disable_nsmb_patch", &CFG.disable_nsmb_patch);
cfg_bool("disable_pop_patch", &CFG.disable_pop_patch);
cfg_bool("disable_dvd_patch", &CFG.disable_dvd_patch);
cfg_bool("disable_wip", &CFG.disable_wip);
cfg_bool("disable_bca", &CFG.disable_bca);
//cfg_int_max("dml", &CFG.dml, 6);
cfg_int_max("devo", &CFG.default_gc_loader,2);
cfg_bool("old_button_color", &CFG.old_button_color);
cfg_id_list("hide_game", CFG.hide_game, &CFG.num_hide_game, MAX_HIDE_GAME);
cfg_id_list("pref_game", CFG.pref_game, &CFG.num_pref_game, MAX_PREF_GAME);
cfg_id_list("favorite_game", CFG.favorite_game,
&CFG.num_favorite_game, MAX_FAVORITE_GAME);
CFG_STR("sort_ignore", CFG.sort_ignore);
cfg_map("clock_style", "0", &CFG.clock_style, 0);
cfg_map("clock_style", "24", &CFG.clock_style, 24);
cfg_map("clock_style", "12", &CFG.clock_style, 12);
cfg_map("clock_style", "12am", &CFG.clock_style, 13);
if (strcmp(name, "music")==0) {
if (cfg_bool("music", &CFG.music)) {
*CFG.music_file = 0;
} else {
COPY_PATH(CFG.music_file, val);
}
}
cfg_bool("delay_patch", &CFG.delay_patch);
if (strncmp(name, "title:", 6)==0) {
char id[8];
trimcopy(id, name+6, sizeof(id));
title_set(id, val);
}
if (strncmp(name, "game:", 5)==0) {
game_set(name, val);
}
if (strcmp(name, "profile_names")==0) {
char *next;
next = val;
CFG.num_profiles = 0;
while ((next = split_tokens(
CFG.profile_names[CFG.num_profiles],
next, ",", sizeof(CFG.profile_names[0]))
))
{
if (*CFG.profile_names[CFG.num_profiles] == 0) break;
CFG.num_profiles++;
if (CFG.num_profiles >= MAX_PROFILES) break;
}
if (CFG.num_profiles == 0) {
CFG.num_profiles = 1;
STRCOPY(CFG.profile_names[0], "default");
}
}
if (strcmp(name, "profile_start_favorites")==0) {
int i;
char token[25];
for (i=0; i<MAX_PROFILES; i++) {
if (get_token_n(token, sizeof(token), val, " ", i)) {
cfg_val = token;
cfg_bool("profile_start_favorites", &CFG.profile_start_favorites[i]);
}
}
}
cfg_int_max("wiird", &CFG.wiird, 2);
if (strcmp(name, "return_to_channel")==0) {
if (strcmp(val, "0")== 0)
CFG.return_to = 0;
else if (strcmp(val, "auto")== 0)
CFG.return_to = 1;
else if (strlen(val) == 4)
CFG.return_to = *(int *)val;
else if (strlen(val) == 8)
sscanf(val, "%X", &CFG.return_to);
}
cfg_bool("db_show_info", &CFG.db_show_info);
cfg_bool("db_ignore_titles", &CFG.db_ignore_titles);
cfg_bool("write_playstats", &CFG.write_playstats);
cfg_bool("adult_themes", &CFG.adult_themes);
cfg_bool("theme_previews", &CFG.theme_previews);
cfg_map("select", "previous", &CFG.select, CFG_SELECT_PREVIOUS);
cfg_map("select", "start", &CFG.select, CFG_SELECT_START);
cfg_map("select", "middle", &CFG.select, CFG_SELECT_MIDDLE);
cfg_map("select", "end", &CFG.select, CFG_SELECT_END);
cfg_map("select", "most", &CFG.select, CFG_SELECT_MOST);
cfg_map("select", "least", &CFG.select, CFG_SELECT_LEAST);
cfg_map("select", "random", &CFG.select, CFG_SELECT_RANDOM);
}
int CFG_hide_games(struct discHdr *list, int cnt)
{
int i;
int kept_cnt = 0;
for (i=0; i<cnt; i++) {
if (!is_in_hide_list(list+i)) {
if (kept_cnt != i)
list[kept_cnt] = list[i];
kept_cnt++;
}
}
cnt = kept_cnt;
return cnt;
}
void CFG_sort_pref(struct discHdr *list, int cnt)
{
int i, j, tmp_cnt = 0;
struct discHdr *tmp_list;
tmp_list = malloc(sizeof(struct discHdr)*cnt);
if (tmp_list == NULL) return;
for (i=0; i<CFG.num_pref_game; i++) {
j = find_in_hdr_list(CFG.pref_game[i], list, cnt);
if (j < 0) continue;
// move entry to tmp
memcpy(&tmp_list[tmp_cnt], &list[j], sizeof(struct discHdr));
tmp_cnt++;
// move remaining entries over
memcpy(list+j, list+j+1, (cnt-j-1) * sizeof(struct discHdr));
cnt--;
}
// append remaining list to tmp
memcpy(&tmp_list[tmp_cnt], list, sizeof(struct discHdr)*cnt);
// move everything back to list
memcpy(list, tmp_list, sizeof(struct discHdr)*(cnt+tmp_cnt));
free(tmp_list);
}
bool is_favorite(u8 *id)
{
return is_in_game_list(id, CFG.favorite_game,
CFG.num_favorite_game);
}
bool set_favorite(u8 *id, bool fav)
{
int i;
bool ret;
i = find_in_game_list(id, CFG.favorite_game, CFG.num_favorite_game);
if (i >= 0) {
// alerady on the list
if (fav) return true;
// remove
remove_from_list(i, CFG.favorite_game, &CFG.num_favorite_game);
return CFG_Save_Settings(0);
}
// not on list
if (!fav) return true;
// add
ret = add_to_list(id, CFG.favorite_game, &CFG.num_favorite_game, MAX_FAVORITE_GAME);
if (!ret) return ret;
return CFG_Save_Settings(0);
}
int CFG_filter_favorite(struct discHdr *list, int cnt)
{
int i;
int kept_cnt = 0;
//printf("f filter %p %d\n", list, cnt); sleep(2);
for (i=0; i<cnt; i++) {
//printf("%d %s %d\n", i, list[i].id, is_favorite(list[i].id));
if (is_favorite(list[i].id)) {
if (kept_cnt != i)
list[kept_cnt] = list[i];
kept_cnt++;
}
}
cnt = kept_cnt;
//printf("e filter %p %d\n", list, cnt); sleep(5);
return cnt;
}
bool is_hide_game(u8 *id)
{
return is_in_game_list(id, CFG.hide_game,
CFG.num_hide_game);
}
bool set_hide_game(u8 *id, bool hide)
{
int i;
bool ret;
i = find_in_game_list(id, CFG.hide_game, CFG.num_hide_game);
if (i >= 0) {
// already in the list
if (hide) return true;
// remove
remove_from_list(i, CFG.hide_game, &CFG.num_hide_game);
return CFG_Save_Settings(0);
}
// not on list
if (!hide) return true;
// add
ret = add_to_list(id, CFG.hide_game, &CFG.num_hide_game, MAX_HIDE_GAME);
if (!ret) return ret;
return CFG_Save_Settings(0);
}
void cfg_parsearg(int argc, char **argv)
{
int i;
char pathname[200];
bool is_opt;
for (i=1; i<argc; i++) {
//printf("arg[%d]: %s\n", i, argv[i]);
is_opt = *argv[i] != '#' && (strchr(argv[i], '=') || strchr(argv[i], '['));
if (is_opt) {
cfg_parseline(argv[i], &cfg_set);
}
else if (argv[i][0] != '#') {
char *p = strrchr(argv[i], '.');
if (p && (stricmp(p, ".txt")==0 || stricmp(p,".cfg")==0)) {
if (strchr(argv[i], ':')) {
// absolute path
cfg_parsefile(pathname, &cfg_set);
} else {
// relative path
snprintf(pathname, sizeof(pathname), "%s/%s", USBLOADER_PATH, argv[i]);
cfg_parsefile(pathname, &cfg_set);
}
}
}
}
}
void cfg_parsearg_early(int argc, char **argv)
{
int i;
char *eq;
// setup defaults
CFG_Default();
// check for direct start
cfg_direct_start(argc, argv);
// parse the rest
for (i=1; i<argc; i++) {
eq = strchr(argv[i], '=');
if (eq) {
cfg_parseline(argv[i], &cfg_set_early);
}
}
}
// SETTINGS.CFG
int cfg_find_profile(char *pname)
{
int i;
for (i=0; i<CFG.num_profiles; i++) {
if (strcasecmp(CFG.profile_names[i], pname) == 0) {
return i;
}
}
if (strcasecmp(pname, "default") == 0) return 0;
return -1;
}
int profile_tag_index = 0;
void settings_set(char *name, char *val)
{
cfg_name = name;
cfg_val = val;
//printf("s: %s : %s\n", name, val);
if (strcmp(name, "[profile]") == 0) {
int i = cfg_find_profile(val);
CFG.current_profile = i >= 0 ? i : 0;
profile_tag_index = i;
//printf("%s : %s : %d\n", name, val, i);
}
if (profile_tag_index >= 0) {
if (strcmp(name, "profile_theme") == 0) {
int i;
for (i=0; i<num_theme; i++) {
if (stricmp(val, theme_list[i]) == 0) {
CFG.profile_theme[profile_tag_index] = i;
break;
}
}
}
}
if (profile_tag_index >= 0) {
cfg_id_list("favorite_game", CFG.favorite_game,
&CFG.num_favorite_game, MAX_FAVORITE_GAME);
}
cfg_id_list("hide_game", CFG.hide_game,
&CFG.num_hide_game, MAX_HIDE_GAME);
game_set(name, val);
if (cfg_set_gbl(name, val)) {
CFG.saved_global = 1;
}
}
// save current state
bool CFG_Save_Global_Settings()
{
CFG.saved_global = 1;
STRCOPY(CFG.saved_theme, CFG.theme);
CFG.saved_device = wbfsDev;
CFG.saved_gui_rows = grid_rows;
CFG.saved_gui_style = gui_style;
if (gui_style == GUI_STYLE_COVERFLOW) {
CFG.saved_gui_style += CFG_cf_global.theme;
}
STRCOPY(CFG.saved_partition, CFG.partition);
CFG.saved_profile = CFG.current_profile;
return CFG_Save_Settings(1);
}
bool CFG_Load_Settings()
{
char pathname[200];
bool ret;
int i;
snprintf(pathname, sizeof(pathname), "%s/%s", USBLOADER_PATH, "settings.cfg");
// reset
CFG.num_favorite_game = 0;
CFG.saved_global = 0;
CFG.current_profile = 0;
profile_tag_index = 0;
memset(&CFG.profile_favorite, 0, sizeof(CFG.profile_favorite));
memset(&CFG.profile_num_favorite, 0, sizeof(CFG.profile_num_favorite));
for (i = 0; i < MAX_PROFILES; i++)
CFG.profile_theme[i] = -1;
// load settings
ret = cfg_parsefile(pathname, &settings_set);
// set current profile
i = cfg_find_profile(CFG.current_profile_name);
CFG.current_profile = i >= 0 ? i : 0;
// always hide uloader's cfg entry
i = find_in_game_list((u8*)"__CF", CFG.hide_game, CFG.num_hide_game);
if (i < 0)
add_to_list((u8*)"__CF", CFG.hide_game, &CFG.num_hide_game, MAX_HIDE_GAME);
// remember saved values
STRCOPY(CFG.saved_theme, CFG.theme);
CFG.saved_device = CFG.device;
CFG.saved_gui_style = CFG.gui_style;
CFG.saved_gui_rows = CFG.gui_rows;
STRCOPY(CFG.saved_partition, CFG.partition);
CFG.saved_profile = CFG.current_profile;
return ret;
}
bool CFG_Save_Settings(int verbose)
{
FILE *f;
int i, j;
struct stat st;
char pathname[200];
snprintf(D_S(pathname), "%s/", FAT_DRIVE);
if (stat(pathname, &st) == -1) {
printf(gt("ERROR: %s is not accessible"), pathname);
printf("\n");
sleep(1);
return false;
}
if (stat(USBLOADER_PATH, &st) == -1) {
//mkpath("sd:/usb-loader", 0777);
printf(gt("ERROR: %s is not accessible"), USBLOADER_PATH);
printf("\n");
sleep(1);
return false;
}
snprintf(D_S(pathname), "%s/%s", USBLOADER_PATH, "settings.cfg");
f = fopen(pathname, "wb");
if (!f) {
printf(gt("Error saving %s"), pathname);
printf("\n");
sleep(1);
return false;
}
fprintf(f, "# CFG USB Loader settings file %s\n", CFG_VERSION);
fprintf(f, "# Note: This file is automatically generated\n");
fprintf(f, "\n# Global Settings:\n");
#define SAVE_OPT(FMT, VAL) do { \
fprintf(f,FMT,VAL); \
if (verbose) printf_(FMT,VAL); } while(0)
if (CFG.saved_global) {
if (*CFG.saved_theme) {
SAVE_OPT("theme = %s\n", CFG.saved_theme);
}
char *dev_str[] = { "ask", "usb", "sdhc" };
if (CFG.saved_device >= 0 && CFG.saved_device <= 2) {
SAVE_OPT("device = %s\n", dev_str[CFG.saved_device]);
}
SAVE_OPT("partition = %s\n", CFG.saved_partition);
char *s = map_get_name(map_gui_style, CFG.saved_gui_style);
if (s) {
SAVE_OPT("gui_style = %s\n", s);
}
if (CFG.saved_gui_rows > 0 && CFG.saved_gui_rows <= 4 ) {
SAVE_OPT("gui_rows = %d\n", CFG.saved_gui_rows);
}
//SAVE_OPT("dml = %d\n", CFG.dml);
SAVE_OPT("devo = %d\n", CFG.default_gc_loader);
SAVE_OPT("old_button_color = %d", CFG.old_button_color);
}
fprintf(f, "\n# Profiles: %d\n", CFG.num_profiles);
int save_prof = CFG.current_profile;
for (j=0; j<CFG.num_profiles; j++) {
CFG.current_profile = j;
fprintf(f, "[profile=%s]\n", CFG.profile_names[j]);
//fprintf(f, "# Profile: [%d] %s\n", j+1, CFG.profile_names[j]);
if (CFG.profile_theme[j] != -1) {
fprintf(f, "profile_theme = %s\n", theme_list[CFG.profile_theme[j]]);
}
fprintf(f, "# Favorite Games: %d\n", CFG.num_favorite_game);
for (i=0; i<CFG.num_favorite_game; i++) {
fprintf(f, "favorite_game = %.4s\n", CFG.favorite_game[i]);
}
}
CFG.current_profile = save_prof;
fprintf(f, "# Current profile: %d\n", CFG.saved_profile + 1);
fprintf(f, "profile = %s\n", CFG.profile_names[CFG.saved_profile]);
fprintf(f, "\n# Hidden Games: %d\n", CFG.num_hide_game);
for (i=0; i<CFG.num_hide_game; i++) {
fprintf(f, "hide_game = %.4s\n", CFG.hide_game[i]);
}
int saved_cfg_game = 0;
for (i=0; i<num_cfg_game; i++) {
if (cfg_game[i].is_saved) saved_cfg_game++;
}
fprintf(f, "\n# Game Options: %d\n", saved_cfg_game);
for (i=0; i<num_cfg_game; i++) {
if (!cfg_game[i].is_saved) continue;
struct Game_CFG *game_cfg = &cfg_game[i].save;
char *s;
fprintf(f, "game:%s = ", cfg_game[i].id);
#define SAVE_STR(N, S) \
if (S) fprintf(f, "%s:%s; ", N, S)
#define SAVE_NUM(N) \
fprintf(f, "%s:%d; ", #N, game_cfg->N)
#define SAVE_BOOL(N) SAVE_NUM(N)
s = map_get_name(map_language, game_cfg->language);
SAVE_STR("language", s);
s = map_get_name(map_video, game_cfg->video);
SAVE_STR("video", s);
s = map_get_name(map_video_patch, game_cfg->video_patch);
SAVE_STR("video_patch", s);
s = map_get_name(map_nand_emu, game_cfg->nand_emu);
SAVE_STR("nand_emu", s);
if (strlen((char*)cfg_game[i].id) == 4)
s = map_get_name(map_channel_boot, game_cfg->channel_boot);
else
s = map_get_name(map_gc_boot, game_cfg->channel_boot);
SAVE_STR("channel_boot", s);
SAVE_BOOL(vidtv);
SAVE_BOOL(wide_screen);
SAVE_BOOL(ntsc_j_patch);
SAVE_BOOL(nodisc);
SAVE_BOOL(screenshot);
SAVE_BOOL(country_patch);
SAVE_BOOL(fix_002);
s = ios_str(game_cfg->ios_idx);
SAVE_STR("ios", s);
if (game_cfg->block_ios_reload == 2) {
SAVE_STR("block_ios_reload", "auto");
} else {
SAVE_BOOL(block_ios_reload);
}
if (game_cfg->alt_dol < ALT_DOL_DISC) {
SAVE_BOOL(alt_dol);
} else {
if (game_cfg->alt_dol == ALT_DOL_DISC) {
SAVE_STR("alt_dol", "disc");
} else {
SAVE_NUM(alt_dol);
}
if (*game_cfg->dol_name) {
SAVE_STR("dol_name", game_cfg->dol_name);
}
}
SAVE_BOOL(ocarina);
s = map_get_name(map_hook, game_cfg->hooktype);
SAVE_STR("hooktype", s);
SAVE_NUM(write_playlog);
SAVE_BOOL(alt_controller_cfg);
if (game_cfg->clean == CFG_CLEAN_OFF) {
SAVE_STR("clear_patches", "0");
} else if (game_cfg->clean == CFG_CLEAN_ON) {
SAVE_STR("clear_patches", "1");
} else {
SAVE_STR("clear_patches", "all");
}
fprintf(f, "\n");
}
fprintf(f, "# END\n");
fclose(f);
return true;
}
// PER-GAME options
// find game cfg
struct Game_CFG_2* CFG_find_game(u8 *id)
{
int i;
for (i=0; i<num_cfg_game; i++) {
if (strncmp((char*)id, (char*)cfg_game[i].id, 6) == 0) {
return &cfg_game[i];
}
}
return NULL;
}
// find game cfg by id
struct Game_CFG CFG_read_active_game_setting(u8 *id)
{
struct Game_CFG_2 *game = CFG_find_game(id);
if (game != NULL)
return game->curr;
else
return CFG.game;
}
// current options to game
void cfg_init_game(struct Game_CFG_2 *game, u8 *id)
{
memset(game, 0, sizeof(*game));
game->curr = CFG.game;
game->save = CFG.game;
memcpy((char*)game->id, (char*)id, 6);
game->id[6] = 0;
game->is_saved = 0;
}
// return existing or new
struct Game_CFG_2* CFG_get_game(u8 *id)
{
struct Game_CFG_2 *game = CFG_find_game(id);
if (game) return game;
if (num_cfg_game >= MAX_CFG_GAME) return NULL;
game = &cfg_game[num_cfg_game];
num_cfg_game++;
cfg_init_game(game, id);
return game;
}
// free game opt slot
void cfg_free_game(struct Game_CFG_2* game)
{
int i;
if (num_cfg_game == 0 || !game) return;
// move entries down
num_cfg_game--;
for (i=game-cfg_game; i<num_cfg_game; i++) {
cfg_game[i] = cfg_game[i+1];
}
memset(&cfg_game[num_cfg_game], 0, sizeof(struct Game_CFG_2));
}
void game_set(char *name, char *val)
{
// sample line:
// game:RTNP41 = video:game; language:english; ocarina:0;
// game:RYWP01 = video:patch; language:console; ocarina:1;
//printf("GAME: '%s=%s'\n", name, val);
u8 id[8];
struct Game_CFG_2 *game;
if (strncmp(name, "game:", 5) != 0) return;
split_token((char*)id, name+5, ' ', sizeof(id));
if ((strlen((char*)id) != 6) && (strlen((char*)id) != 4)) return;
game = CFG_get_game(id);
// set id and current options as default
cfg_init_game(game, id);
//printf("GAME(%s) '%s'\n", id, val); sleep(1);
// parse val
// first split options by ;
char opt[100], *p;
p = val;
while(p) {
p = split_token(opt, p, ';', sizeof(opt));
//printf("GAME(%s) (%s)\n", id, opt); sleep(1);
// parse opt 'language:english'
char opt_name[100], opt_val[100];
if (trimsplit(opt, opt_name, opt_val, ':', sizeof(opt_name))){
//printf("GAME(%s) (%s=%s)\n", id, opt_name, opt_val); sleep(1);
cfg_set_game(opt_name, opt_val, &game->save);
}
}
game->curr = game->save;
game->is_saved = 1;
}
bool CFG_is_saved(u8 *id)
{
struct Game_CFG_2 *game;
game = CFG_find_game(id);
if (game == NULL) return false;
//return true;
return game->is_saved;
}
// clean up so it's suitable for binary compare
void cfg_game_clean(struct Game_CFG *src, struct Game_CFG *dest)
{
*dest = *src;
memset(dest->dol_name, 0, sizeof(dest->dol_name));
if (dest->alt_dol == ALT_DOL_DISC) {
STRCOPY(dest->dol_name, src->dol_name);
}
}
// return true if differ
bool cfg_game_differ(struct Game_CFG *g1, struct Game_CFG *g2)
{
// first make clean
struct Game_CFG gg1, gg2;
cfg_game_clean(g1, &gg1);
cfg_game_clean(g2, &gg2);
return memcmp(&gg1, &gg2, sizeof(gg1));
}
bool cfg_game_changed(struct Game_CFG_2 *game)
{
if (game->is_saved) {
// compare curr vs saved
return cfg_game_differ(&game->curr, &game->save);
}
// curr vs global
return cfg_game_differ(&game->curr, &CFG.game);
}
bool CFG_is_changed(u8 *id)
{
struct Game_CFG_2 *game = CFG_find_game(id);
if (!game) return false;
return cfg_game_changed(game);
}
bool CFG_save_game_opt(u8 *id)
{
struct Game_CFG_2 *game = CFG_get_game(id);
if (!game) return false;
game->save = game->curr;
game->is_saved = 1;
if (CFG_Save_Settings(0)) return true;
return false;
}
bool CFG_discard_game_opt(u8 *id)
{
struct Game_CFG_2 *game = CFG_find_game(id);
if (!game) return false;
// reset options
cfg_init_game(game, id);
return CFG_Save_Settings(0);
}
void CFG_release_game(struct Game_CFG_2 *game)
{
if (game->is_saved) return;
if (cfg_game_changed(game)) return;
// not saved and not changed - free slot
cfg_free_game(game);
}
// theme
void get_theme_list()
{
//DIR *dir;
DIR_ITER *dir;
//struct dirent *dent;
struct stat st;
char fname[1024] = "";
char theme_base[200] = "";
char theme_dir[200] = "";
char theme_file[200] = "";
int i;
//dbg_time1();
snprintf(theme_base, sizeof(theme_base), "%s/themes", USBLOADER_PATH);
//dir = opendir(theme_base);
dir = diropen(theme_base);
if (!dir) return;
//while ((dent = readdir(dir)) != NULL) {
while (dirnext(dir, fname, &st) == 0) {
//if (strlen(dent->d_name) >= sizeof(theme_list[0]) || dent->d_name[0] == '.') continue;
if (strlen(fname) >= sizeof(theme_list[0]) || fname[0] == '.') continue;
//snprintf(theme_dir, sizeof(theme_dir), "%s/%s", theme_base, dent->d_name);
snprintf(theme_dir, sizeof(theme_dir), "%s/%s", theme_base, fname);
//if (stat(theme_dir, &st) != 0) continue;
if (!S_ISDIR(st.st_mode)) continue;
snprintf(theme_file, sizeof(theme_file), "%s/theme.txt", theme_dir);
if (stat(theme_file, &st) != 0) continue;
if(S_ISREG(st.st_mode)) {
// theme found
//printf("Theme: %s\n", dent->d_name);
if (num_theme >= MAX_THEME) break;
//strcopy(theme_list[num_theme], dent->d_name, sizeof(theme_list[num_theme]));
strcopy(theme_list[num_theme], fname, sizeof(theme_list[num_theme]));
num_theme++;
}
}
//closedir(dir);
dirclose(dir);
if (!num_theme) return;
qsort(theme_list, num_theme, sizeof(*theme_list),
(int(*)(const void*, const void*))stricmp);
// define current
if (!*CFG.theme) return;
for (i=0; i<num_theme; i++) {
if (stricmp(CFG.theme, theme_list[i]) == 0) {
cur_theme = i;
strcopy(CFG.theme, theme_list[i], sizeof(CFG.theme));
break;
}
}
}
int find_button(int value) {
if (CFG.button_A == value) return NUM_BUTTON_A;
if (CFG.button_B == value) return NUM_BUTTON_B;
if (CFG.button_1 == value) return NUM_BUTTON_1;
if (CFG.button_2 == value) return NUM_BUTTON_2;
if (CFG.button_M == value) return NUM_BUTTON_MINUS;
if (CFG.button_P == value) return NUM_BUTTON_PLUS;
if (CFG.button_H == value) return NUM_BUTTON_HOME;
if (CFG.button_X == value) return NUM_BUTTON_X;
if (CFG.button_Y == value) return NUM_BUTTON_Y;
if (CFG.button_Z == value) return NUM_BUTTON_Z;
if (CFG.button_C == value) return NUM_BUTTON_C;
if (CFG.button_L == value) return NUM_BUTTON_L;
if (CFG.button_R == value) return NUM_BUTTON_R;
return 0;
}
void set_chars(void) {
CFG.button_gui = find_button(CFG_BTN_GUI);
CFG.button_opt = find_button(CFG_BTN_OPTIONS);
CFG.button_fav = find_button(CFG_BTN_FAVORITES);
}
void load_theme(char *theme)
{
char pathname[200];
struct stat st;
if (!*theme) return;
snprintf(D_S(theme_path), "%s/themes/%s", USBLOADER_PATH, theme);
snprintf(D_S(pathname), "%s/theme.txt", theme_path);
if (stat(pathname, &st) == 0) {
CFG_Default_Theme();
STRCOPY(CFG.theme, theme);
copy_theme_path(CFG.background, "background.png", sizeof(CFG.background));
if (!copy_theme_path(CFG.w_background, "background_wide.png",
sizeof(CFG.w_background)))
{
// if not found use normal
*CFG.w_background = 0;
}
copy_theme_path(CFG.bg_gui, "bg_gui.png", sizeof(CFG.bg_gui));
if (!copy_theme_path(CFG.bg_gui_wide, "bg_gui_wide.png",
sizeof(CFG.bg_gui_wide)))
{
// if themed bg_gui_wide.png not found, use themed bg_gui.png
// instead of global bg_gui_wide.png
*CFG.bg_gui_wide = 0;
}
cfg_parsefile(pathname, &theme_set);
// override some theme options with config.txt:
snprintf(D_S(pathname), "%s/config.txt", USBLOADER_PATH);
cfg_parsefile(pathname, &theme_set_base);
if (strcmp(USBLOADER_PATH, APPS_DIR) != 0) {
snprintf(D_S(pathname), "%s/config.txt", APPS_DIR);
cfg_parsefile(pathname, &theme_set_base);
}
STRCOPY(CFG.theme_path, theme_path);
makeButtonMap();
set_chars();
}
*theme_path = 0;
}
void CFG_switch_theme(int theme_i)
{
if (num_theme <= 0) return;
if (cur_theme == -1) theme_i = 0;
if (theme_i < 0) theme_i = num_theme - 1;
if (theme_i >= num_theme) theme_i = 0;
load_theme(theme_list[theme_i]);
cur_theme = theme_i;
__console_flush(0);
cfg_setup2();
//Gui_DrawBackground();
Gui_LoadBackground();
Gui_InitConsole();
cfg_setup3();
wgui_inited = 0;
}
char *get_clock_str(time_t t)
{
static char clock_str[16];
char *fmt = "%H:%M";
if (CFG.clock_style == 12) fmt = "%I:%M";
if (CFG.clock_style == 13) fmt = "%I:%M %p";
strftime(clock_str, sizeof(clock_str), fmt, localtime(&t));
return clock_str;
}
//extern u8 __text_start[];
//extern u8 __Arena1Lo[], __Arena1Hi[];
//extern u8 __Arena2Lo[], __Arena2Hi[];
void test_unicode()
{
wchar_t wc;
char mb[32*6+1];
int i, k, len=0, count=0;
printf("\n");
for (i=0; i<512; i++) {
wc = i;
switch (wc) {
case '\n': strcat(mb, "n"); k=1; break;
case '\r': strcat(mb, "r"); k=1; break;
case '\b': strcat(mb, "b"); k=1; break;
case '\f': strcat(mb, "f"); k=1; break;
case '\t': strcat(mb, "t"); k=1; break;
case 0x1b: strcat(mb, "e"); k=1; break; // esc
default:
k = wctomb(mb+len, wc);
if (k < 1 || mb[len] == 0) {
if (wc < 128) {
mb[len] = '!'; //wc;
} else {
mb[len] = '?';
}
k = 1;
}
}
len += k;
mb[len] = 0;
count++;
if (count >= 32) {
printf("%03x: %s |\n", (unsigned)i-31, mb);
len = 0;
count = 0;
}
}
printf("\n");
Menu_PrintWait();
printf("\n");
}
/*
debug codes:
1 : basic
2 : unicode
3 : coverflow
4 : banner sound
8 : io benchmark
*/
void cfg_debug(int argc, char **argv)
{
InitDebug();
if (CFG.debug) {
Gui_Console_Enable();
__console_scroll = 1;
}
dbg_printf("debug: %d %d\n", CFG.debug, CFG.debug_gecko);
dbg_printf("base_path: %s\n", USBLOADER_PATH);
dbg_printf("apps_path: %s\n", APPS_DIR);
//dbg_printf("bg_path: %s\n", *CFG.background ? CFG.background : "builtin");
dbg_printf("covers: %s\n", CFG.covers_path);
dbg_printf("theme: %s\n", CFG.theme_path);
/*
dbg_printf("theme: %s \n", CFG.theme);
dbg_printf("covers: %d ", CFG.covers);
dbg_printf("w: %d ", COVER_WIDTH);
dbg_printf("h: %d ", COVER_HEIGHT);
dbg_printf("layout: %d ", CFG.layout);
dbg_printf("video: %d ", CFG.game.video);
dbg_printf("home: %d ", CFG.home);
dbg_printf("ocarina: %d ", CFG.game.ocarina);
dbg_printf("titles: %d ", num_title);
dbg_printf("maxc: %d ", MAX_CHARACTERS);
dbg_printf("ent: %d ", ENTRIES_PER_PAGE);
*/
dbg_printf("url: %s\n", CFG.cover_url_2d);
//dbg_printf("t[%.6s]=%s\n", cfg_title[0].id, cfg_title[0].title);
//dbg_printf("hide_hdd: %d\n", CFG.hide_hddinfo);
//dbg_printf("text start: %p\n", __text_start);
//dbg_printf("M1: %p - %p\n", __Arena1Lo, __Arena1Hi);
//dbg_printf("M2: %p - %p\n", __Arena2Lo, __Arena2Hi);
int i;
dbg_printf("hide: %d", CFG.num_hide_game);
for (i=0; i<CFG.num_hide_game; i++) {
dbg_printf(" %.4s", CFG.hide_game[i]);
}
dbg_printf("\n");
dbg_printf("args[%d]:", argc);
for (i=0; i<argc; i++) {
dbg_printf(" [%d]=%s", i, argv[i]);
}
dbg_printf("\n");
dbg_printf("music: %d ", CFG.music);
dbg_printf("gui: %d ", CFG.gui);
extern char *get_cc();
dbg_printf("CC: %s ", get_cc());
dbg_printf("\n");
dbg_printf("device: %d ", CFG.device);
dbg_printf("partition: %s\n", CFG.partition);
if (CFG.debug) {
Menu_PrintWait();
}
if (CFG.debug & 2) test_unicode();
dbg_printf("\n");
}
void chdir_app(char *arg)
{
char *pos;
struct stat st;
int default_try = 0;
if (arg == NULL) goto default_dir;
// replace fat: with sd:
if (strncmp(arg, "fat", strlen("fat")) == 0) {
pos = strchr(arg, ':');
if (!pos) goto default_dir;
STRCOPY(APPS_DIR, SDHC_MOUNT);
strcat(APPS_DIR, pos);
}
// check if starts with sd: usb: or ntfs:
else if (strncmp(arg, SDHC_MOUNT, strlen(SDHC_MOUNT)) == 0
|| strncmp(arg, USB_MOUNT, strlen(USB_MOUNT)) == 0
|| strncmp(arg, NTFS_MOUNT, strlen(NTFS_MOUNT)) == 0)
{
STRCOPY(APPS_DIR, arg);
// trim possible drive number
pos = strchr(APPS_DIR, ':');
if (!pos) goto default_dir;
pos--;
if (ISDIGIT(*pos)) {
memmove(pos, pos+1, strlen(pos));
}
} else {
goto default_dir;
}
// trim /boot.dol
pos = strrchr(APPS_DIR, '/');
if (!pos) goto default_dir;
*pos = 0;
// still a valid path?
pos = strchr(APPS_DIR, '/');
if (!pos) goto default_dir;
goto try_chdir;
// no path in arg, try the default APPS_DIR
default_dir:
snprintf(D_S(APPS_DIR), "%s%s", FAT_DRIVE, "/apps/USBLoader");
default_try = 1;
try_chdir:
if (stat(APPS_DIR, &st) == 0) {
chdir(APPS_DIR);
} else {
if (!default_try) goto default_dir;
*APPS_DIR = 0;
}
}
void setup_theme_preview_coords()
{
//theme preview settings
if (CFG.widescreen) {
//if width and height not set then use cover width
if ((CFG.w_theme_previewW < 1) && (CFG.w_theme_previewH < 1)) CFG.w_theme_previewW = COVER_WIDTH;
CFG.theme_previewX = (CFG.w_theme_previewX < 0) ? COVER_XCOORD : CFG.w_theme_previewX;
CFG.theme_previewY = (CFG.w_theme_previewY < 0) ? COVER_YCOORD : CFG.w_theme_previewY;
CFG.theme_previewW = (CFG.w_theme_previewW > 0) ? CFG.w_theme_previewW : (CFG.w_theme_previewH * 16 / 13);
CFG.theme_previewH = (CFG.w_theme_previewH > 0) ? CFG.w_theme_previewH : (CFG.w_theme_previewW * 13 / 16);
} else {
//if width and height not set then use cover width
if ((CFG.theme_previewW < 1) && (CFG.theme_previewH < 1)) CFG.theme_previewW = COVER_WIDTH;
CFG.theme_previewX = (CFG.theme_previewX < 0) ? COVER_XCOORD : CFG.theme_previewX;
CFG.theme_previewY = (CFG.theme_previewY < 0) ? COVER_YCOORD : CFG.theme_previewY;
CFG.theme_previewW = (CFG.theme_previewW > 0) ? CFG.theme_previewW : (CFG.theme_previewH * 4 / 3);
CFG.theme_previewH = (CFG.theme_previewH > 0) ? CFG.theme_previewH : (CFG.theme_previewW * 3 / 4);
}
}
// after cfg load
void cfg_setup1()
{
// widescreen
if (CFG.widescreen == CFG_WIDE_AUTO) {
int widescreen = CONF_GetAspectRatio();
if (widescreen) {
CFG.widescreen = 1;
} else {
CFG.widescreen = 0;
}
}
// set current profile
int i = cfg_find_profile(CFG.current_profile_name);
CFG.current_profile = i >= 0 ? i : 0;
}
// before video & console init
void cfg_setup2()
{
// setup cover style: path & url
//cfg_setup_cover_style();
// setup cover dimensions
CFG.N_COVER_WIDTH = COVER_WIDTH;
CFG.N_COVER_HEIGHT = COVER_HEIGHT;
// setup widescreen coords
if (CFG.widescreen) {
// copy over
CONSOLE_XCOORD = CFG.W_CONSOLE_XCOORD;
CONSOLE_YCOORD = CFG.W_CONSOLE_YCOORD;
CONSOLE_WIDTH = CFG.W_CONSOLE_WIDTH;
CONSOLE_HEIGHT = CFG.W_CONSOLE_HEIGHT;
COVER_XCOORD = CFG.W_COVER_XCOORD;
COVER_YCOORD = CFG.W_COVER_YCOORD;
if (*CFG.w_background) {
STRCOPY(CFG.background, CFG.w_background);
}
if (!CFG.W_COVER_WIDTH || !CFG.W_COVER_HEIGHT) {
// if either wide val is 0: automatic resize
// normal (4:3): COVER_WIDTH = 160;
// wide (16:9): COVER_WIDTH = 130;
// ratio: *13/16
// although true 4:3 -> 16:9 should be
// 4:3=12:9 -> 16:9 => *12/16,
// but it looks too compressed
// and align to multiple of 2
CFG.W_COVER_WIDTH = (COVER_WIDTH * 13 / 16) / 2 * 2;
// height is same
CFG.W_COVER_HEIGHT = COVER_HEIGHT;
}
COVER_WIDTH = CFG.W_COVER_WIDTH;
COVER_HEIGHT = CFG.W_COVER_HEIGHT;
}
setup_theme_preview_coords();
expand_font_color_cfg(&CFG.gui_text, &CFG.gui_text_cfg);
expand_font_color_cfg(&CFG.gui_text2, &CFG.gui_text2_cfg);
}
// This has to be called AFTER video & console init
void cfg_setup3()
{
// auto set max_chars & entries
int cols, rows;
CON_GetMetrics(&cols, &rows);
//MAX_CHARACTERS = cols - 4;
MAX_CHARACTERS = cols - 2 - strlen(CFG.cursor);
if (CFG.console_mark_saved) MAX_CHARACTERS--;
ENTRIES_PER_PAGE = rows - 5;
// correct ENTRIES_PER_PAGE
if (CFG.db_show_info) { // lustar
ENTRIES_PER_PAGE -= 2;
}
if (CFG.hide_header) ENTRIES_PER_PAGE++;
if (CFG.hide_hddinfo) ENTRIES_PER_PAGE++;
//if (CFG.buttons == CFG_BTN_OPTIONS_1 || CFG.buttons == CFG_BTN_OPTIONS_B) {
if (CFG.hide_footer) ENTRIES_PER_PAGE++;
//} else {
// ENTRIES_PER_PAGE--;
// if (CFG.hide_footer) ENTRIES_PER_PAGE+=2;
//}
}
void cfg_direct_start(int argc, char **argv)
{
// loadstructor
// patched buffer in binary
char *direct_start_arg = NULL;
//if (strcmp(direct_start_id_buf, "#GAMEID") != 0)
// we can't compare "#GAMEID" directly because
// it has to be a unique string inside the binary
char *p = direct_start_id_buf;
if (p[0] != '#' ||
p[1] != 'G' ||
p[2] != 'A' ||
p[3] != 'M' ||
p[4] != 'E' ||
p[5] != 'I' ||
p[6] != 'D' )
{
direct_start_arg = direct_start_id_buf + 1;
}
// uloader forwarder arg variant
// argv[1] = "#RHAP01" or "#RHAP01-2"
if(argc>1 && argv && argv[1]) {
if(argv[1][0] == '#') {
direct_start_arg = argv[1] + 1;
} else {
extern bool is_gameid(char *id);
if ((strlen(argv[1]) == 6) && is_gameid(argv[1])) {
direct_start_arg = argv[1];
}
}
}
// is direct start?
if (direct_start_arg) {
char *t = direct_start_arg;
// game id
memcpy(CFG.launch_discid, t, 6);
t += 6;
if (t[0] == '-') {
int part_num = t[1] - '0';
//CFG.current_partition = t[1] - 48;
//CFG.current_partition &= 3;
if (part_num < 4) {
sprintf(CFG.partition, "WBFS%d", part_num + 1);
} else {
sprintf(CFG.partition, "FAT%d", part_num - 4 + 1);
}
}
// setup cfg for auto-start
CFG.direct_launch = 1;
CFG_Default_Theme();
CFG.device = CFG_DEV_USB;
*CFG.background = 0;
*CFG.w_background = 0;
CFG.covers = 0;
CFG.gui = 0;
CFG.music = 0;
CFG.confirm_start = 0;
//CFG.debug = 0;
}
}
int CFG_MountUSB()
{
static int first_time = 1;
int ret;
if (!first_time) return -1;
ret = MountUSB();
if (ret == 0) return 0; // OK
ret = Retry_Init_Dev(WBFS_DEVICE_USB, 0);
if (ret != 0) return -1;
return MountUSB();
}
// This has to be called BEFORE video & console init
void CFG_Load(int argc, char **argv)
{
char *arg0 = NULL;
char filename[200];
struct stat st;
bool try_sd = true;
bool try_usb = false;
bool try_ntfs = false;
bool ret;
strcpy(FAT_DRIVE, SDHC_DRIVE);
// are we started from usb? then check usb first.
// also if wiiload supplied first argument is USB_DRIVE, start with usb.
if (argc && argv && argv[0]) {
arg0 = argv[0];
// verify that argv[0] is an actual full pathname
if (strstr(argv[0], ":/") == NULL) {
// it's not, check argv[1] instead
// can be useful when running from wiiload
if (argc > 1 && argv[1] && strchr(argv[1], ':')
&& !strchr(argv[1], '=')) // not an option
{
arg0 = argv[1];
dbg_printf("a1:%s\n", arg0);
}
}
// ignore : in case it's numbered
if (strncmp(arg0, USB_MOUNT, strlen(USB_MOUNT)) == 0)
{
if (CFG_MountUSB() == 0 && mount_find(USB_DRIVE)) {
strcpy(FAT_DRIVE, USB_DRIVE);
try_usb = true;
try_sd = false;
}
}
// same logic applies to ntfs:
else if (strncmp(arg0, NTFS_MOUNT, strlen(NTFS_MOUNT)) == 0)
{
if (CFG_MountUSB() == 0 && mount_find(NTFS_DRIVE)) {
strcpy(FAT_DRIVE, NTFS_DRIVE);
try_ntfs = true;
try_sd = false;
}
}
}
retry:
snprintf(D_S(USBLOADER_PATH), "%s%s", FAT_DRIVE, "/usb-loader");
// Set current working directory to app path
chdir_app(arg0);
// setup defaults
//CFG_Default(); // already called by cfg_parsearg_early
CFG_default_path();
// load global config
snprintf(D_S(filename), "%s/%s", USBLOADER_PATH, "config.txt");
ret = cfg_parsefile(filename, &cfg_set);
// try old location if default fails
/*
if (!ret) {
char pathname[200];
snprintf(D_S(pathname), "%s%s", FAT_DRIVE, "/USBLoader");
snprintf(D_S(filename), "%s/%s", pathname, "config.txt");
if (stat(filename, &st) == 0) {
// exists, use old base path
STRCOPY(USBLOADER_PATH, pathname);
CFG_default_path(); // reset defaults with old path
ret = cfg_parsefile(filename, &cfg_set);
}
}
*/
// still no luck? try APPS_DIR
if (!ret && *APPS_DIR) {
snprintf(D_S(filename), "%s/%s", APPS_DIR, "config.txt");
if (stat(filename, &st) == 0) {
// exists, use APPS_DIR as base
STRCOPY(USBLOADER_PATH, APPS_DIR);
CFG_default_path(); // reset defaults with APPS_DIR
ret = cfg_parsefile(filename, &cfg_set);
}
}
// still no luck? try USB
if (!ret) {
if (!try_usb) {
try_usb = true;
if (CFG_MountUSB() == 0) {
strcpy(FAT_DRIVE, USB_DRIVE);
goto retry;
}
}
if (!try_ntfs) {
try_ntfs = true;
if (CFG_MountUSB() == 0) {
strcpy(FAT_DRIVE, NTFS_DRIVE);
goto retry;
}
}
if (!try_sd) {
try_sd = true;
strcpy(FAT_DRIVE, SDHC_DRIVE);
goto retry;
} else {
// still no dir found, just reset to sd:
if (strcmp(FAT_DRIVE, SDHC_DRIVE) != 0) {
strcpy(FAT_DRIVE, SDHC_DRIVE);
goto retry;
}
}
}
STRCOPY(LAST_CFG_PATH, USBLOADER_PATH);
// load renamed titles
snprintf(filename, sizeof(filename), "%s/%s", USBLOADER_PATH, "titles.txt");
cfg_parsefile(filename, &title_set);
// load per-app local config and titles
// (/apps/USBLoader/config.txt and titles.txt if run from HBC)
if (strcmp(USBLOADER_PATH, APPS_DIR) != 0) {
if (cfg_parsefile("config.txt", &cfg_set)) {
STRCOPY(LAST_CFG_PATH, APPS_DIR);
}
cfg_parsefile("titles.txt", &title_set);
}
// load custom titles
snprintf(filename, sizeof(filename), "%s/%s", USBLOADER_PATH, "custom-titles.txt");
cfg_parsefile(filename, &title_set);
// get theme list
get_theme_list();
// load per-game settings
CFG_Load_Settings();
// loadstructor direct start support
cfg_direct_start(argc, argv);
// parse commandline arguments (wiiload)
cfg_parsearg(argc, argv);
// setup dependant and calculated parameters
cfg_setup1();
cfg_setup2();
// remount NTFS if write was enabled
RemountNTFS();
}
void CFG_Setup(int argc, char **argv)
{
get_time(&TIME.misc1);
cfg_setup3();
if (CFG.debug) Gui_Console_Enable();
char language_file[255];
snprintf(language_file, sizeof(language_file), "%s/languages/%s.lang", USBLOADER_PATH, CFG.translation);
FILE * f;
f = fopen(language_file,"r");
if (f) {
fclose(f);
gettextLoadLanguage(language_file);
}
button_names[NUM_BUTTON_LEFT] = gt("LEFT");
button_names[NUM_BUTTON_RIGHT] = gt("RIGHT");
button_names[NUM_BUTTON_UP] = gt("UP");
button_names[NUM_BUTTON_DOWN] = gt("DOWN");
// read playstats
if (!playStatsRead) {
readPlayStats();
}
// load unifont
char fname[200];
char * dbl = ((strlen(CFG.db_language) == 2) ? VerifyLangCode(CFG.db_language) : ConvertLangTextToCode(CFG.db_language));
if ((!strncmp(CFG.translation,"JA",2))
||(!strncmp(CFG.translation,"KO",2))
||(!strncmp(CFG.translation,"ZH",2))
||(!strncmp(dbl,"JA",2))
||(!strncmp(dbl,"KO",2))
||(!strncmp(dbl,"ZH",2)))
CFG.load_unifont = true; //all require unifont
if (CFG.load_unifont) {
snprintf(D_S(fname), "%s/unifont.dat", USBLOADER_PATH);
console_load_unifont(fname);
}
get_time(&TIME.misc2);
// load database
get_time(&TIME.wiitdb1);
ReloadXMLDatabase(USBLOADER_PATH, CFG.db_language, 0);
get_time(&TIME.wiitdb2);
cfg_debug(argc, argv);
}
u32 getPlayCount(u8 *id) {
int n;
for (n=0; n<playStatsSize; n++) {
if (!strcmp(playStats[n].id, (char *)id))
return playStats[n].playCount;
}
return 0;
}
time_t getLastPlay(u8 *id) {
int n;
for (n=0; n<playStatsSize; n++) {
if (!strcmp(playStats[n].id, (char *)id))
return playStats[n].playTime;
}
return 0;
}
int readPlayStats() {
int n = 0;
char filepath[MAXPATHLEN];
snprintf(filepath, sizeof(filepath), "%s/playstats.txt", USBLOADER_PATH);
time_t start;
int count;
char id[7];
FILE *f;
f = fopen(filepath, "r");
if (!f) {
return -1;
}
while (fscanf(f, "%[^:]:%d:%ld\n", id, &count, &start) == 3) {
if (n >= playStatsSize) {
playStatsSize++;
playStats = (struct playStat*)realloc(playStats, (playStatsSize * sizeof(struct playStat)));
if (!playStats)
return -1;
}
strncpy(playStats[n].id, id, 7);
playStats[n].playCount = count;
playStats[n].playTime = start;
n++;
}
fclose(f);
playStatsRead = true;
return 0;
}
int setPlayStat(u8 *id) {
if (CFG.write_playstats == 0)
return 0;
char filepath[MAXPATHLEN];
time_t now;
int n = 0;
int count = 0;
snprintf(filepath, sizeof(filepath), "%s/playstats.txt", USBLOADER_PATH);
FILE *f;
if (!playStatsRead) {
readPlayStats();
}
f = fopen(filepath, "w");
if (!f) return -1;
for (n=0; n<playStatsSize; n++) {
if (strcmp(playStats[n].id, (char *)id)) {
fprintf(f, "%s:%d:%ld\n", playStats[n].id, playStats[n].playCount, playStats[n].playTime);
} else {
count = playStats[n].playCount;
}
}
now = time(NULL);
fprintf(f, "%s:%d:%ld\n", (char *)id, count+1, now);
fclose(f);
return 1;
}