All pastes #1736316 Raw Edit

Anonymous

public c v1 · immutable
#1736316 ·published 2010-01-03 16:39 UTC
rendered paste body
/*  Copyright 2009, Ifcaro & volca  Licenced under Academic Free License version 3.0  Review OpenUsbLd README & LICENSE files for further details.  */#include "include/usbld.h"#include "include/lang.h"extern void *usbhdfsd_irx;extern int size_usbhdfsd_irx;extern void *ps2dev9_irx;extern int size_ps2dev9_irx;extern void *ps2atad_irx;extern int size_ps2atad_irx;extern void *poweroff_irx;extern int size_poweroff_irx;extern void *ps2hdd_irx;extern int size_ps2hdd_irx;extern void *smbman_irx;extern int size_smbman_irx;extern void *smsutils_irx;extern int size_smsutils_irx;extern void *smstcpip_irx;extern int size_smstcpip_irx;extern void *smsmap_irx;extern int size_smsmap_irx;#define IPCONFIG_MAX_LEN        64char g_ipconfig[IPCONFIG_MAX_LEN] __attribute__((aligned(64)));int g_ipconfig_len;extern void set_ipconfig(void);// language idint gLanguageID = 0;int eth_inited = 0;// frames since button was pressedint inactiveFrames;// minimal inactive frames for hint display#define HINT_FRAMES_MIN 64// --------------------------- Dialogs ---------------------------// Dialog definition for IP configurationstruct UIItem diaIPConfig[] = {	{UI_LABEL, 0, NULL, {.label = {"", _STR_IPCONFIG}}},		{UI_SPLITTER},	// ---- IP address ----	{UI_LABEL, 0, NULL, {.label = {"- PS2 -", -1}}}, {UI_BREAK},		{UI_LABEL, 0, NULL, {.label = {"IP", -1}}}, {UI_SPACER}, 		{UI_INT, 2, NULL, {.intvalue = {192, 192, 0, 255}}}, {UI_LABEL, 0, NULL, {.label = {".", -1}}},	{UI_INT, 3, NULL, {.intvalue = {168, 168, 0, 255}}}, {UI_LABEL, 0, NULL, {.label = {".", -1}}},	{UI_INT, 4, NULL, {.intvalue = {0, 0, 0, 255}}}, {UI_LABEL, 0, NULL, {.label = {".", -1}}},	{UI_INT, 5, NULL, {.intvalue = {10, 10, 0, 255}}},	{UI_BREAK},	//  ---- Netmask ----	{UI_LABEL, 0, NULL, {.label = {"MASK", -1}}},	{UI_SPACER}, 		{UI_INT, 6, NULL, {.intvalue = {255, 255, 0, 255}}}, {UI_LABEL, 0, NULL, {.label = {".", -1}}},	{UI_INT, 7, NULL, {.intvalue = {255, 255, 0, 255}}}, {UI_LABEL, 0, NULL, {.label = {".", -1}}},	{UI_INT, 8, NULL, {.intvalue = {255, 255, 0, 255}}}, {UI_LABEL, 0, NULL, {.label = {".", -1}}},	{UI_INT, 9, NULL, {.intvalue = {0, 0, 0, 255}}},		{UI_BREAK},		//  ---- Gateway ----	{UI_LABEL, 0, NULL, {.label = {"GW", -1}}},	{UI_SPACER}, 		{UI_INT, 10, NULL, {.intvalue = {192, 192, 0, 255}}}, 	{UI_LABEL, 0, NULL, {.label = {".", -1}}},	{UI_INT, 11, NULL, {.intvalue = {168, 168, 0, 255}}}, {UI_LABEL, 0, NULL, {.label = {".", -1}}},	{UI_INT, 12, NULL, {.intvalue = {0, 0, 0, 255}}}, 	{UI_LABEL, 0, NULL, {.label = {".", -1}}},	{UI_INT, 13, NULL, {.intvalue = {1, 1, 0, 255}}},		{UI_SPLITTER},		//  ---- PC ----	{UI_LABEL, 0, NULL, {.label = {"- PC -", -1}}},	{UI_BREAK},		{UI_LABEL, 0, NULL, {.label = {"IP", -1}}},	{UI_SPACER}, 		{UI_INT, 14, NULL, {.intvalue = {192, 192, 0, 255}}},	{UI_LABEL, 0, NULL, {.label = {".", -1}}},	{UI_INT, 15, NULL, {.intvalue = {168, 168, 0, 255}}},	{UI_LABEL, 0, NULL, {.label = {".", -1}}},	{UI_INT, 16, NULL, {.intvalue = {0, 0, 0, 255}}},	{UI_LABEL, 0, NULL, {.label = {".", -1}}},	{UI_INT, 17, NULL, {.intvalue = {1, 1, 0, 255}}},		{UI_BREAK},		{UI_LABEL, 0, NULL, {.label = {"PORT", -1}}},	{UI_SPACER}, {UI_INT, 18, NULL, {.intvalue = {445, 445, 0, 1024}}},		{UI_BREAK},		//  ---- PC share name ----	{UI_LABEL, 0, NULL, {.label = {"SHARE NAME", -1}}}, {UI_SPACER}, {UI_STRING, 19, NULL, {.stringvalue = {"PS2SMB", "PS2SMB"}}}, {UI_BREAK},		{UI_LABEL, 0, NULL, {.label = {"", _STR_NETWORK_AUTOSTART}}}, {UI_SPACER}, {UI_BOOL, 20, NULL, {.intvalue = {0, 0}}}, {UI_BREAK},		//  ---- Ok ----	{UI_SPLITTER},	{UI_OK},		// end of dialogue	{UI_TERMINATOR}};// Dialog for per-game compatibility settings#define COMPAT_SAVE 100#define COMPAT_TEST 101#define COMPAT_REMOVE 102#define COMPAT_LOADFROMDISC 104#define COMPAT_MODE_BASE 10#define COMPAT_GAMEID 50#define COMPAT_MODE_COUNT 5struct UIItem diaCompatConfig[] = {	{UI_LABEL, 110, NULL, {.label = {"<Game Label>", -1}}},		{UI_SPLITTER},		{UI_LABEL, 111, NULL, {.label = {"", _STR_COMPAT_SETTINGS}}}, {UI_BREAK}, {UI_BREAK}, {UI_BREAK},	{UI_LABEL, 0, NULL, {.label = {"Mode 1", -1}}}, {UI_SPACER}, {UI_BOOL, COMPAT_MODE_BASE    , "Load alt. core", {.intvalue = {0, 0}}}, {UI_BREAK},	{UI_LABEL, 0, NULL, {.label = {"Mode 2", -1}}}, {UI_SPACER}, {UI_BOOL, COMPAT_MODE_BASE + 1, "Alternative data read method", {.intvalue = {0, 0}}}, {UI_BREAK},	{UI_LABEL, 0, NULL, {.label = {"Mode 3", -1}}}, {UI_SPACER}, {UI_BOOL, COMPAT_MODE_BASE + 2, "Unhook Syscalls", {.intvalue = {0, 0}}}, {UI_BREAK},	{UI_LABEL, 0, NULL, {.label = {"Mode 4", -1}}}, {UI_SPACER}, {UI_BOOL, COMPAT_MODE_BASE + 3, "0 PSS mode", {.intvalue = {0, 0}}}, {UI_BREAK},	{UI_LABEL, 0, NULL, {.label = {"Mode 5", -1}}}, {UI_SPACER}, {UI_BOOL, COMPAT_MODE_BASE + 4, "Disable DVD-DL", {.intvalue = {0, 0}}}, {UI_BREAK},		{UI_SPLITTER},		{UI_LABEL, 0, NULL, {.label = {"Game ID", -1}}}, {UI_SPACER}, {UI_STRING, COMPAT_GAMEID, NULL, {.stringvalue = {"", ""}}}, {UI_BREAK},	{UI_BUTTON, COMPAT_LOADFROMDISC, NULL, {.label = {NULL, _STR_LOAD_FROM_DISC}}},		{UI_SPLITTER},		{UI_OK}, {UI_SPACER}, {UI_BUTTON, COMPAT_SAVE, NULL, {.label = {"", _STR_SAVE_CHANGES}}}, 		 {UI_SPACER}, {UI_BUTTON, COMPAT_TEST, NULL, {.label = {"Test", -1}}},		{UI_SPLITTER},		{UI_BUTTON, COMPAT_REMOVE, NULL, {.label = {"", _STR_REMOVE_ALL_SETTINGS}}},		// end of dialogue	{UI_TERMINATOR}};// Dialog for ui settings#define UICFG_THEME 10#define UICFG_LANG 11#define UICFG_SCROLL 12#define UICFG_MENU 13#define UICFG_BGCOL 14#define UICFG_TXTCOL 15#define UICFG_EXITTO 16#define UICFG_DEFDEVICE 17#define UICFG_SAVE 114struct UIItem diaUIConfig[] = {	{UI_LABEL, 111, NULL, {.label = {"", _STR_SETTINGS}}},	{UI_SPLITTER},	{UI_LABEL, 0, NULL, {.label = {"", _STR_THEME}}}, {UI_SPACER}, {UI_ENUM, UICFG_THEME, NULL, {.intvalue = {0, 0}}}, {UI_BREAK},	{UI_LABEL, 0, NULL, {.label = {"", _STR_LANGUAGE}}}, {UI_SPACER}, {UI_ENUM, UICFG_LANG,  NULL,{.intvalue = {0, 0}}}, {UI_BREAK},	{UI_LABEL, 0, NULL, {.label = {"", _STR_SCROLLING}}}, {UI_SPACER}, {UI_ENUM, UICFG_SCROLL, NULL, {.intvalue = {0, 0}}}, {UI_BREAK},	{UI_LABEL, 0, NULL, {.label = {"", _STR_MENUTYPE}}}, {UI_SPACER}, {UI_ENUM, UICFG_MENU, NULL, {.intvalue = {0, 0}}}, {UI_BREAK},	{UI_LABEL, 0, NULL, {.label = {"", _STR_DEFDEVICE}}}, {UI_SPACER}, {UI_ENUM, UICFG_DEFDEVICE, NULL, {.intvalue = {0, 0}}}, {UI_BREAK},		{UI_SPLITTER},		{UI_LABEL, 0, NULL, {.label = {"Bg. col", -1}}}, {UI_SPACER}, {UI_COLOUR, UICFG_BGCOL, NULL, {.colourvalue = {0, 0}}}, {UI_BREAK},	{UI_LABEL, 0, NULL, {.label = {"Txt. col", -1}}}, {UI_SPACER}, {UI_COLOUR, UICFG_TXTCOL, NULL, {.colourvalue = {0, 0}}}, {UI_BREAK},		{UI_SPLITTER},		{UI_LABEL, 0, NULL, {.label = {"Exit to", -1}}}, {UI_SPACER}, {UI_ENUM, UICFG_EXITTO, NULL, {.intvalue = {0, 0}}}, {UI_BREAK},		{UI_SPLITTER},		{UI_OK}, {UI_SPACER}, {UI_BUTTON, UICFG_SAVE, NULL, {.label = {"", _STR_SAVE_CHANGES}}}, 		{UI_SPLITTER},		// end of dialogue	{UI_TERMINATOR}};// Renders the IP dialog, stores the values if result is okvoid showIPConfig() {	size_t i;	// upload current values	for (i = 0; i < 4; ++i) {		diaSetInt(diaIPConfig, 2 + i, ps2_ip[i]);		diaSetInt(diaIPConfig, 6 + i, ps2_netmask[i]);		diaSetInt(diaIPConfig, 10 + i, ps2_gateway[i]);		diaSetInt(diaIPConfig, 14 + i, pc_ip[i]);	}		diaSetInt(diaIPConfig, 18, gPCPort);	diaSetString(diaIPConfig, 19, gPCShareName);	diaSetInt(diaIPConfig, 20, gNetAutostart);		// show dialog	if (diaExecuteDialog(diaIPConfig)) {		// sanitize the values		// Ok pressed, store values		for (i = 0; i < 4; ++i) {			diaGetInt(diaIPConfig, 2 + i, &ps2_ip[i]);			diaGetInt(diaIPConfig, 6 + i, &ps2_netmask[i]);			diaGetInt(diaIPConfig, 10 + i, &ps2_gateway[i]);			diaGetInt(diaIPConfig, 14 + i, &pc_ip[i]);		}				diaGetInt(diaIPConfig, 18, &gPCPort);		diaGetString(diaIPConfig, 19, gPCShareName);		diaGetInt(diaIPConfig, 20, &gNetAutostart);				// has to be non-empty		if (strlen(gPCShareName) == 0) {			strncpy(gPCShareName, "PS2SMB", 32);		}				gIPConfigChanged = 1;	}}int getImageCompatMask(const char* image, int ntype) {	char gkey[255];	unsigned int modemask;		snprintf(gkey, 255, "%s_%d", image, ntype);		if (!getConfigInt(&gConfig, gkey, &modemask))		modemask = 0;		return modemask;}void setImageCompatMask(const char* image, int ntype, int mask) {	char gkey[255];		snprintf(gkey, 255, "%s_%d", image, ntype);		setConfigInt(&gConfig, gkey, mask);}char *getImageGameID(const char* image) {	char gkey[255];	char *gid;		snprintf(gkey, 255, "gameid_%s", image);		if (!getConfigStr(&gConfig, gkey, &gid))		gid = "";		return gid;}// dst has to have 5 bytes spacevoid getImageGameIDBin(const char* image, void* dst) {	char gkey[255];	char *gid;		snprintf(gkey, 255, "gameid_%s", image);		if (!getConfigStr(&gConfig, gkey, &gid))		gid = "";		// convert from hex to binary	memset(dst, 0, 5);	char* cdst = dst;	int p = 0;	while (*gid && p < 10) {		int dv = -1;				while (dv < 0 && *gid) // skip spaces, etc			dv = fromHex(*(gid++));				if (dv < 0)			break;				*cdst = *cdst * 16 + dv;		if ((++p & 1) == 0)			cdst++;	}}void setImageGameID(const char* image, const char *gid) {	char gkey[255];		snprintf(gkey, 255, "gameid_%s", image);	setConfigStr(&gConfig, gkey, gid);}// returns COMPAT_TEST on testing requestint showCompatConfig(const char* game, const char* prefix, int ntype) {	char gkey[255];	char *hexid;	int modes = getImageCompatMask(prefix, ntype);		int i;		diaSetLabel(diaCompatConfig, 110, game);		for (i = 0; i < COMPAT_MODE_COUNT; ++i) {		diaSetInt(diaCompatConfig, COMPAT_MODE_BASE + i, (modes & (1 << i)) > 0 ? 1 : 0);	}		// Find out the current game ID	hexid = getImageGameID(prefix);	diaSetString(diaCompatConfig, COMPAT_GAMEID, hexid);		// show dialog	int result = 0;		do {		result = diaExecuteDialog(diaCompatConfig);				if (result == COMPAT_LOADFROMDISC) {			// Draw "please wait..." screen			DrawBackground();			DrawHint(_l(_STR_PLEASE_WAIT), -1);			Flip();						// load game ID, inject			char discID[5];			memset(discID, 0, 5);						if (getDiscID(discID) >= 0) {				// convert to hexadecimal string				char nhexid[16];								unsigned int n;				// this may seem stupid but it seems snprintf handles %X as signed...				for(n = 0; n < 5; ++n) {					nhexid[n*3    ] = toHex(discID[n] >> 4);					nhexid[n*3 + 1] = toHex(discID[n] & 0x0f);					nhexid[n*3 + 2] = ' ';				}								nhexid[14] = '\0';								diaSetString(diaCompatConfig, COMPAT_GAMEID, nhexid);			} else {				MsgBox(_l(_STR_ERROR_LOADING_ID));			}		}	} while (result == COMPAT_LOADFROMDISC);		if (result == COMPAT_REMOVE) {		configRemoveKey(&gConfig, gkey);		MsgBox(_l(_STR_REMOVED_ALL_SETTINGS));	} else if (result > 0) { // okay pressed or other button		modes = 0;		for (i = 0; i < COMPAT_MODE_COUNT; ++i) {			int mdpart;			diaGetInt(diaCompatConfig, COMPAT_MODE_BASE + i, &mdpart);			modes |= (mdpart ? 1 : 0) << i;		}				setImageCompatMask(prefix, ntype, modes);				diaGetString(diaCompatConfig, COMPAT_GAMEID, hexid);		setImageGameID(prefix, hexid);				if (result == COMPAT_SAVE) // write the config			storeConfig();	}		return result;}void showUIConfig() {	// configure the enumerations	const char* scrollSpeeds[] = {		_l(_STR_SLOW),		_l(_STR_MEDIUM),		_l(_STR_FAST),		NULL	};		// Theme list update	ListDir("mass:USBLD/");		const char* menuTypes[] = {		_l(_STR_STATIC),		_l(_STR_DYNAMIC),		NULL	};		const char* exitTypes[] = {		"Browser",		"mc0:/BOOT/BOOT.ELF",		"mc0:/APPS/BOOT.ELF",		NULL	};	const char* deviceNames[] = {		_l(_STR_USB_GAMES),		_l(_STR_NET_GAMES),		_l(_STR_HDD_GAMES),		NULL	};	// search for the theme index in the current theme list	size_t i;	size_t themeid = 0;	for(i = 0; i < max_theme_dir; ++i)  {		if (strcmp(theme_dir[i], theme) == 0) {			themeid = i;			break;		}	}		diaSetEnum(diaUIConfig, UICFG_SCROLL, scrollSpeeds);	diaSetEnum(diaUIConfig, UICFG_THEME, (const char **)theme_dir);	diaSetEnum(diaUIConfig, UICFG_LANG, getLanguageList());	diaSetEnum(diaUIConfig, UICFG_MENU, menuTypes);	diaSetEnum(diaUIConfig, UICFG_EXITTO, exitTypes);	diaSetEnum(diaUIConfig, UICFG_DEFDEVICE, deviceNames);		// and the current values	diaSetInt(diaUIConfig, UICFG_SCROLL, scroll_speed);	diaSetInt(diaUIConfig, UICFG_THEME, themeid);	diaSetInt(diaUIConfig, UICFG_LANG, gLanguageID);	diaSetInt(diaUIConfig, UICFG_MENU, dynamic_menu);	diaSetColour(diaUIConfig, UICFG_BGCOL, default_bg_color);	diaSetColour(diaUIConfig, UICFG_TXTCOL, default_text_color);	diaSetInt(diaUIConfig, UICFG_EXITTO, exit_mode);	diaSetInt(diaUIConfig, UICFG_DEFDEVICE, default_device);		int ret = diaExecuteDialog(diaUIConfig);	if (ret) {		// transfer values back into config		diaGetInt(diaUIConfig, UICFG_SCROLL, &scroll_speed);		diaGetInt(diaUIConfig, UICFG_THEME, &themeid);		diaGetInt(diaUIConfig, UICFG_LANG, &gLanguageID);		diaGetInt(diaUIConfig, UICFG_MENU, &dynamic_menu);		diaGetColour(diaUIConfig, UICFG_BGCOL, default_bg_color);		diaGetColour(diaUIConfig, UICFG_TXTCOL, default_text_color);		diaGetInt(diaUIConfig, UICFG_EXITTO, &exit_mode);		diaGetInt(diaUIConfig, UICFG_DEFDEVICE, &default_device);			// update the value interpretation		setLanguage(gLanguageID);		UpdateScrollSpeed();		SetMenuDynamic(dynamic_menu);		LoadTheme(themeid);		infotxt = _l(_STR_WELCOME);				if (ret == UICFG_SAVE)			storeConfig();	}}// --------------------- Configuration handling --------------------int loadConfig(const char* fname, int clearFirst) {	if (clearFirst)		clearConfig(&gConfig);		// fill the config from file	int result = readConfig(&gConfig, fname);		if (!result)		return 0;		gfxRestoreConfig();		infotxt = _l(_STR_WELCOME);		char *temp;		// restore non-graphics settings as well	if (getConfigStr(&gConfig, "pc_ip", &temp))		sscanf(temp, "%d.%d.%d.%d", &pc_ip[0], &pc_ip[1], &pc_ip[2], &pc_ip[3]);		getConfigInt(&gConfig, "pc_port", &gPCPort);	getConfigInt(&gConfig, "net_auto", &gNetAutostart);		if (getConfigStr(&gConfig, "pc_share", &temp))		strncpy(gPCShareName, temp, 32);		if (gPCPort < 0)		gPCPort = 445;		return 1;}int saveConfig(const char* fname) {	gfxStoreConfig();		if (gPCPort < 0)		gPCPort = 445;		char temp[255];		sprintf(temp, "%d.%d.%d.%d", pc_ip[0], pc_ip[1], pc_ip[2], pc_ip[3]);		setConfigStr(&gConfig, "pc_ip", temp);	setConfigInt(&gConfig, "pc_port", gPCPort);	setConfigInt(&gConfig, "net_auto", gNetAutostart);	setConfigStr(&gConfig, "pc_share", gPCShareName);	// Not writing the IP config, too dangerous to change it by accident...	return writeConfig(&gConfig, fname);}int restoreConfig() {	readIPConfig();	// look for mc0 and mc1 first, then mass	// the first to load succesfully will store the config location	const char* configLocations[] = {		"mc0:/SYS-CONF/usbld.cfg",		"mc1:/SYS-CONF/usbld.cfg",		"mass:/USBLD/usbld.cfg",		NULL	};		unsigned int loc = 0;	gConfigPath = NULL;	const char *curPath;		while ((curPath = configLocations[loc++]) != NULL) {		if (loadConfig(curPath, 1) != 0) {			gConfigPath = curPath;			break;		}	}		return gConfigPath == NULL ? 0 : 1;}int storeConfig() {	// use the global path if found, else default to mc0	const char *confPath = gConfigPath;	if (gIPConfigChanged)		writeIPConfig();		if (!confPath) // default to SYS-CONF on mc0		confPath = "mc0:/SYS-CONF/usbld.cfg";		int result = saveConfig(confPath);		if (result) {		MsgBox(_l(_STR_SETTINGS_SAVED));	} else {		MsgBox(_l(_STR_ERROR_SAVING_SETTINGS));	}			return result;}// --------------------- Menu variables, handling & initialization --------------------// Submenu items variant of the game list... keeped in sync with the game item liststruct TSubMenuList* usb_submenu = NULL;struct TSubMenuList* eth_submenu = NULL;/// List of usb gamesstruct TMenuItem usb_games_item;/// List of network gamesstruct TMenuItem eth_games_item;/// scroll speed selectorstruct TSubMenuList* speed_item = NULL;/// menu type selectorstruct TSubMenuList* menutype_item = NULL;unsigned int scroll_speed_txt[3] = {_STR_SCROLL_SLOW, _STR_SCROLL_MEDIUM, _STR_SCROLL_FAST};unsigned int menu_type_txt[2] = { _STR_MENU_DYNAMIC,  _STR_MENU_STATIC};void ClearSubMenu(struct TSubMenuList** submenu, struct TMenuItem* mi) {	DestroySubMenu(submenu);		if ((submenu != &eth_submenu) || (eth_inited || gNetAutostart))		AppendSubMenu(submenu, &disc_icon, "", -1, _STR_NO_ITEMS);	else		AppendSubMenu(submenu, &netconfig_icon, "", -1, _STR_START_NETWORK);	mi->submenu = *submenu;	mi->current = *submenu;}void RefreshGameList(TGame **list, int* max_games, const char* prefix, struct TSubMenuList** submenu, struct TMenuItem* mi) {	int fd, size;	char buffer[0x040];	char path[64];	snprintf(path, 64, "%sul.cfg", prefix);	fd=fioOpen(path, O_RDONLY);		if(fd<0) { // file could not be opened. reset menu		free(*list);		*list = NULL;		ClearSubMenu(submenu, mi);		return;	}	// only refresh if the list is empty	if (*max_games==0) {		DestroySubMenu(submenu);		*submenu = NULL;		mi->submenu = *submenu;		mi->current = *submenu;		size = fioLseek(fd, 0, SEEK_END);  		fioLseek(fd, 0, SEEK_SET); 				size_t count = size / 0x040;		*max_games = count;				*list = (TGame*)malloc(sizeof(TGame) * count);				int id;		for(id = 1; id <= count; ++id) {			fioRead(fd, buffer, 0x40);						TGame *g = &(*list)[id-1];						// to ensure no leaks happen, we copy manually and pad the strings			memcpy(g->Name, buffer, 32);			g->Name[32] = '\0';			memcpy(g->Image, &buffer[32], 16);			g->Image[16] = '\0';			memcpy(&g->parts, &buffer[47], 1);			memcpy(&g->media, &buffer[48], 1);						AppendSubMenu(submenu, &disc_icon, g->Name, id, -1);		}				mi->submenu = *submenu;		mi->current = *submenu;	}	fioClose(fd);}void FindUSBPartition(){	int i, fd;	char path[64];		snprintf(USB_prefix,8,"mass0:");		for(i=0;i<5;i++){		snprintf(path, 64, "mass%d:/ul.cfg", i);		fd=fioOpen(path, O_RDONLY);				if(fd>=0) {			snprintf(USB_prefix,8,"mass%d:",i);			fioClose(fd);			break;		}		fioClose(fd);	}		return;}void ClearUSBSubMenu() {	ClearSubMenu(&usb_submenu, &usb_games_item);}void RefreshUSBGameList() {	if(usbdelay<=100)  {		usbdelay++;		return;	}	  	usbdelay = 0;	RefreshGameList(&usbGameList, &usb_max_games, USB_prefix, &usb_submenu, &usb_games_item);}// --------------------- USB Menu item callbacks --------------------void ExecUSBGameSelection(struct TMenuItem* self, int id) {	if (id == -1)		return;		padPortClose(0, 0);	padPortClose(1, 0);	padReset();		// find the compat mask	int cmask = getImageCompatMask(usbGameList[id - 1].Image, USB_MODE);		char* gid[5];	getImageGameIDBin(usbGameList[id - 1].Image, gid);		LaunchGame(&usbGameList[id - 1], USB_MODE, cmask, gid);}void AltExecUSBGameSelection(struct TMenuItem* self, int id) {	if (id == -1)		return;		if (showCompatConfig(usbGameList[id - 1].Name, usbGameList[id - 1].Image, USB_MODE) == COMPAT_TEST)		ExecUSBGameSelection(self, id);}void ClearETHSubMenu() {	ClearSubMenu(&eth_submenu, &eth_games_item);}void RefreshETHGameList() {	if(ethdelay<=100)  {		ethdelay++;		return;	}	  	ethdelay = 0;	RefreshGameList(&ethGameList, &eth_max_games, "smb0:\\", &eth_submenu, &eth_games_item);}// --------------------- Network Menu item callbacks --------------------// Forward decl.void LoadNetworkModules(void);void StartNetwork() {	if (0) // left here if we find a way to let it work without issues (see bug no. 16)		Start_LoadNetworkModules_Thread();	else		LoadNetworkModules();}void ExecETHGameSelection(struct TMenuItem* self, int id) {	if (id == -1) {		if (!eth_inited) {			StartNetwork();			eth_inited = 1;			ClearETHSubMenu();		}		return;	}		padPortClose(0, 0);	padPortClose(1, 0);	padReset();		int cmask = getImageCompatMask(ethGameList[id - 1].Image, ETH_MODE);		char* gid[5];	getImageGameIDBin(ethGameList[id - 1].Image, gid);		LaunchGame(&ethGameList[id - 1], ETH_MODE, cmask, gid);}void AltExecETHGameSelection(struct TMenuItem* self, int id) {	if (id == -1)		return;		if (showCompatConfig(ethGameList[id - 1].Name,  ethGameList[id - 1].Image, ETH_MODE) == COMPAT_TEST)		ExecETHGameSelection(self, id);}// --------------------- Exit/Settings Menu item callbacks --------------------/// menu item selection callbacksvoid ExecExit(struct TMenuItem* self, int vorder) {	if(exit_mode==0){		__asm__ __volatile__(			"	li $3, 0x04;"			"	syscall;"			"	nop;"		);	}else if(exit_mode==1){		ExecElf("mc0:/BOOT/BOOT.ELF");		MsgBox("Error launching mc0:/BOOT/BOOT.ELF");	}else if(exit_mode==2){		ExecElf("mc0:/APPS/BOOT.ELF");		MsgBox("Error launching mc0:/APPS/BOOT.ELF");	}}void ChangeScrollSpeed() {	scroll_speed = (scroll_speed + 1) % 3;	speed_item->item.text_id = scroll_speed_txt[scroll_speed];		UpdateScrollSpeed();}void ChangeMenuType() {	SwapMenu();		menutype_item->item.text_id = menu_type_txt[dynamic_menu ? 0 : 1];}void ExecSettings(struct TMenuItem* self, int id) {	if (id == 1) {		showUIConfig();	} else if (id == 3) {		// ipconfig		showIPConfig();	} else if (id == 7) {		storeConfig();	}}// --------------------- Menu initialization --------------------struct TSubMenuList *settings_submenu = NULL;struct TMenuItem exit_item = {	&exit_icon, "Exit", _STR_EXIT, NULL, NULL, NULL, &ExecExit, NULL, NULL};struct TMenuItem settings_item = {	&config_icon, "Settings", _STR_SETTINGS, NULL, NULL, NULL, &ExecSettings, NULL, NULL};struct TMenuItem usb_games_item  = {	&usb_icon, "USB Games", _STR_USB_GAMES, NULL, NULL, NULL, &ExecUSBGameSelection, &RefreshUSBGameList, &AltExecUSBGameSelection};struct TMenuItem hdd_games_item = {	&games_icon, "HDD Games", _STR_HDD_GAMES, NULL, NULL, NULL};struct TMenuItem eth_games_item = {	&network_icon, "Network Games", _STR_NET_GAMES, NULL, NULL, NULL, &ExecETHGameSelection, &RefreshETHGameList, &AltExecETHGameSelection};struct TMenuItem apps_item = {	&apps_icon, "Apps", _STR_APPS, NULL, NULL, NULL};void InitMenuItems() {	ClearUSBSubMenu();	ClearETHSubMenu();		// initialize the menu	AppendSubMenu(&settings_submenu, &theme_icon, "Theme", 1, _STR_THEME);	AppendSubMenu(&settings_submenu, &netconfig_icon, "Network config", 3, _STR_IPCONFIG);	AppendSubMenu(&settings_submenu, &save_icon, "Save Changes", 7, _STR_SAVE_CHANGES);		settings_item.submenu = settings_submenu;		// add all menu items	menu = NULL;	AppendMenuItem(&exit_item);	AppendMenuItem(&settings_item);	AppendMenuItem(&usb_games_item);	AppendMenuItem(&hdd_games_item);	AppendMenuItem(&eth_games_item);	AppendMenuItem(&apps_item);}// main initialization functionvoid init() {	Reset();	InitGFX();		theme_dir[0] = NULL;	usb_max_games = 0;	eth_max_games = 0;	ps2_ip[0] = 192; ps2_ip[1] = 168; ps2_ip[2] =  0; ps2_ip[3] =  10;	ps2_netmask[0] = 255; ps2_netmask[1] = 255; ps2_netmask[2] =  255; ps2_netmask[3] =  0;	ps2_gateway[0] = 192; ps2_gateway[1] = 168; ps2_gateway[2] = 0; ps2_gateway[3] = 1;	pc_ip[0] = 192;pc_ip[1] = 168; pc_ip[2] = 0; pc_ip[3] = 2;		// SMB port on pc	gPCPort = 445;	// loading progress of the network	gNetworkStartup = 0;	// autostart network?	gNetAutostart = 0;	// no change to the ipconfig was done	gIPConfigChanged = 0;	// Default PC share name	strncpy(gPCShareName, "PS2SMB", 32);	//Default exit mode	exit_mode=0;	// default device USB	default_device = 0;		// default to english	gLanguageID = _LANG_ID_ENGLISH;	setLanguage(gLanguageID);	gConfig.head = NULL;	gConfig.tail = NULL;		SifInitRpc(0);		SifLoadModule("rom0:SIO2MAN",0,0);	SifLoadModule("rom0:MCMAN",0,0);	SifLoadModule("rom0:MCSERV",0,0);	SifLoadModule("rom0:PADMAN",0,0);	mcInit(MC_TYPE_MC);	int ret, id;			LoadUSBD();	id=SifExecModuleBuffer(&usbhdfsd_irx, size_usbhdfsd_irx, 0, NULL, &ret);		delay(3);	// try to restore config	// if successful, it will remember the config location for further writes	restoreConfig();		InitMenu();		delay(1);		/// Init custom menu items	InitMenuItems();		// first column is usb games	switch (default_device) {		case 1:	MenuSetSelectedItem(&eth_games_item);			break;		case 2:	MenuSetSelectedItem(&hdd_games_item);			break;		case 0:		default:			MenuSetSelectedItem(&usb_games_item);	}						StartPad();	usb_max_games=0;	eth_max_games=0;		usbdelay=0;	ethdelay=0;	frame=0;	inactiveFrames = 0;		usbGameList = NULL;	ethGameList = NULL;		// these seem to matter. Without them, something tends to crush into itself	delay(1);}int netLoadInfo() {	char txt[64];		// display network status in lower left corner	if (gNetworkStartup > 0) {		snprintf(txt, 64, _l(_STR_NETWORK_LOADING), gNetworkStartup);		DrawHint(txt, -1);		return 1;	}	return 0;}void netLoadDisplay() {	DrawBackground();	netLoadInfo();	Flip();}void LoadNetworkModules() {		int ret, id;			set_ipconfig();	if (!gDev9_loaded) {		gNetworkStartup = 5;		netLoadDisplay();    	id=SifExecModuleBuffer(&ps2dev9_irx, size_ps2dev9_irx, 0, NULL, &ret);		if ((id < 0) || ret) {			gNetworkStartup = -1;			return;		}		gDev9_loaded = 1;	}		gNetworkStartup = 4;	netLoadDisplay();		id=SifExecModuleBuffer(&smsutils_irx, size_smsutils_irx, 0, NULL, &ret);	if ((id < 0) || ret) {		gNetworkStartup = -1;		return;	}	gNetworkStartup = 3;	netLoadDisplay();		id=SifExecModuleBuffer(&smstcpip_irx, size_smstcpip_irx, 0, NULL, &ret);	if ((id < 0) || ret) {		gNetworkStartup = -1;		return;	}		gNetworkStartup = 2;	netLoadDisplay();		id=SifExecModuleBuffer(&smsmap_irx, size_smsmap_irx, g_ipconfig_len, g_ipconfig, &ret);		if ((id < 0) || ret) {		gNetworkStartup = -1;		return;	}		gNetworkStartup = 1;	netLoadDisplay();		id=SifExecModuleBuffer(&smbman_irx, size_smbman_irx, 0, NULL, &ret);	if ((id < 0) || ret) {		gNetworkStartup = -1;		return;	}	gNetworkStartup = 0; // ok, all loaded}void LoadHddModules(void){		int ret, id;	static char hddarg[] = "-o" "\0" "4" "\0" "-n" "\0" "20";	if (!gDev9_loaded) {		gHddStartup = 4;    	id=SifExecModuleBuffer(&ps2dev9_irx, size_ps2dev9_irx, 0, NULL, &ret);		if ((id < 0) || ret) {			gHddStartup = -1;			return;		}		gDev9_loaded = 1;	}	gHddStartup = 3;    id=SifExecModuleBuffer(&ps2atad_irx, size_ps2atad_irx, 0, NULL, &ret);	if ((id < 0) || ret) {		gHddStartup = -1;		return;	}	gHddStartup = 2;    id=SifExecModuleBuffer(&poweroff_irx, size_poweroff_irx, 0, NULL, &ret);	if ((id < 0) || ret) {		gHddStartup = -1;		return;	}	gHddStartup = 1;    id=SifExecModuleBuffer(&ps2hdd_irx, size_ps2hdd_irx, sizeof(hddarg), hddarg, &ret);			if ((id < 0) || ret) {		gHddStartup = -1;		return;	}	gHddStartup = 0;}// --------------------- Main --------------------int main(void){	init();		Intro();		// these seem to matter. Without them, something tends to crush into itself	delay(1);		FindUSBPartition();	ReadPad();		// If automatic network startup is selected, start it now	if ((!GetKeyOn(KEY_L1)) && (gNetAutostart != 0)) {		StartNetwork();		eth_inited = 1;	}		// For Testing HDD		int ret;    LoadHddModules();        //init_scr();    //scr_clear();        ret = hddCheck();    //scr_printf("\n\t hddCheck ret=%d\n", ret);    if (ret == 0) {    	ret = hddGetTotalSectors();    	//scr_printf("\t hddGetTotalSectors ret=%d\n", ret);    	hdl_games_list_t *games;    	ret = hddGetHDLGamelist(&games);    	//scr_printf("\t hddGetHDLGamelist ret=%d\n", ret);    	if (ret == 0) {    		hdd_transfer_mode_t transfer_mode;    		transfer_mode.type = UDMA_MODE;    		transfer_mode.mode = 4;    		int i;    		for (i=0; i<games->count; i++){				hdl_game_info_t *game = &games->games[i];				//scr_printf("\t %s type=%x sector=%08x compat=%x sizeMB=%d\n", game->name, game->disctype, game->start_sector, game->compat_flags, game->total_size_in_kb/1024);				//scr_printf("\t %s - %s\n", game->name, game->startup);				if (!strcmp(game->name, "SomeGameName"))					LaunchHDDGame(game, 0, 0, &transfer_mode);			}		}	}			TextColor(0x80,0x80,0x80,0x80);		while(1)	{		if (ReadPad())			inactiveFrames = 0;		else			inactiveFrames++;		DrawScreen();						// L1 - page up/down modifier (5 instead of 1 item skip)		int pgmod = GetKeyPressed(KEY_L1);				if(GetKey(KEY_LEFT)){			MenuPrevH();		}else if(GetKey(KEY_RIGHT)){			MenuNextH();		}else if(GetKey(KEY_UP)){			int i;			for (i = 0; i < 4*(pgmod ? 1 : 0) + 1; ++i)				MenuPrevV();		}else if(GetKey(KEY_DOWN)){			int i;			for (i = 0; i < 4*(pgmod ? 1 : 0) + 1; ++i)				MenuNextV();		}				// home		if (GetKeyOn(KEY_L2)) {			struct TMenuItem* cur = MenuGetCurrent();						if ((cur == &usb_games_item) || (cur == &eth_games_item)) {				cur->current = cur->submenu;			}		}				// end		if (GetKeyOn(KEY_R2)) {			struct TMenuItem* cur = MenuGetCurrent();						if ((cur == &usb_games_item) || (cur == &eth_games_item)) {				if (!cur->current)					cur->current = cur->submenu;								if (cur->current)					while (cur->current->next)						cur->current = cur->current->next;			}		}				if(GetKeyOn(KEY_CROSS)){			// handle via callback in the menuitem			MenuItemExecute();		} else if(GetKeyOn(KEY_TRIANGLE)){			// handle via callback in the menuitem			MenuItemAltExecute();		}				// sort the list on SELECT press		if (GetKeyOn(KEY_SELECT)) {			struct TMenuItem* cur = MenuGetCurrent();						if ((cur == &usb_games_item) || (cur == &eth_games_item)) {				SortSubMenu(&cur->submenu);				cur->current = cur->submenu;			}		}						if (!netLoadInfo()) {			// see the inactivity			if (inactiveFrames >= HINT_FRAMES_MIN) {				struct TMenuItem* cur = MenuGetCurrent();				// show hint (depends on the current menu item)				if ((cur == &usb_games_item) && (usb_max_games > 0)) 					DrawHint(_l(_STR_COMPAT_SETTINGS), KEY_TRIANGLE);				else if ((cur == &eth_games_item) && (eth_max_games > 0))					DrawHint(_l(_STR_COMPAT_SETTINGS), KEY_TRIANGLE);				else if (cur == &settings_item)					DrawHint(_l(_STR_SETTINGS), KEY_CROSS);			}		}		Flip();				RefreshSubMenu();				// if error starting network happened, message out and disable		if (gNetworkStartup < 0) {			MsgBox(_l(_STR_NETWORK_STARTUP_ERROR));			gNetworkStartup = 0;		}	}	return 0;}