diff --git a/.clang-format-ignore b/.clang-format-ignore index ac3296aac..ecf58787b 100644 --- a/.clang-format-ignore +++ b/.clang-format-ignore @@ -2,3 +2,4 @@ ./modules/isofs/lz4.h ./modules/network/lwNBD ./thirdparty/clang-format-lint-action +./src/hdd.c diff --git a/include/appsupport.h b/include/appsupport.h index 66a6074eb..0f04e6a34 100644 --- a/include/appsupport.h +++ b/include/appsupport.h @@ -1,30 +1,6 @@ #ifndef __APP_SUPPORT_H #define __APP_SUPPORT_H -#define APP_MODE_UPDATE_DELAY 240 - -#define APP_TITLE_MAX 128 -#define APP_PATH_MAX 128 -#define APP_BOOT_MAX 64 -#define APP_ARGV1_MAX 128 - -#define APP_CONFIG_TITLE "title" -#define APP_CONFIG_BOOT "boot" -#define APP_CONFIG_ARGV1 "argv1" - -#define APP_TITLE_CONFIG_FILE "title.cfg" - -typedef struct -{ - char title[APP_TITLE_MAX + 1]; - char path[APP_PATH_MAX + 1]; - char boot[APP_BOOT_MAX + 1]; - char argv1[APP_ARGV1_MAX + 1]; - u8 legacy; -} app_info_t; - -void appInit(); item_list_t *appGetObject(int initOnly); -void appPostUpdateCallback(int mode); #endif diff --git a/include/audio.h b/include/audio.h index 6ae700325..a983b7ff4 100644 --- a/include/audio.h +++ b/include/audio.h @@ -3,6 +3,7 @@ void audioInit(void); void audioEnd(void); -void audioSetVolume(int sfx); +void audioSetVolume(); +void audioSetSfxVolume(int sfx); #endif \ No newline at end of file diff --git a/include/bdmsupport.h b/include/bdmsupport.h index c4ac9489a..265b18437 100644 --- a/include/bdmsupport.h +++ b/include/bdmsupport.h @@ -1,24 +1,6 @@ #ifndef __BDM_SUPPORT_H #define __BDM_SUPPORT_H -#define BDM_MODE_UPDATE_DELAY MENU_UPD_DELAY_GENREFRESH - -typedef struct -{ - int active; /* Activation flag */ - u64 start_sector; /* Start sector of vmc file */ - int flags; /* Card flag */ - vmc_spec_t specs; /* Card specifications */ -} bdm_vmc_infos_t; - -#define MAX_BDM_DEVICES 5 - -#define BDM_TYPE_UNKNOWN -1 -#define BDM_TYPE_USB 0 -#define BDM_TYPE_ILINK 1 -#define BDM_TYPE_SDC 2 -#define BDM_TYPE_ATA 3 - typedef struct { int massDeviceIndex; // Underlying device index backing the mass fs partition, ex: usb0 = 0, usb1 = 1, etc. @@ -38,10 +20,10 @@ typedef struct unsigned char ForceRefresh; } bdm_device_data_t; -void bdmInit(); +extern bdm_device_data_t *gAutoLaunchDeviceData; + int bdmFindPartition(char *target, const char *name, int write); void bdmLoadModules(void); -void bdmLaunchGame(item_list_t *itemList, int id, config_set_t *configSet); void bdmInitSemaphore(); void bdmEnumerateDevices(); diff --git a/include/config.h b/include/config.h index 3cf4be790..e733a206c 100644 --- a/include/config.h +++ b/include/config.h @@ -166,7 +166,6 @@ int configSetColor(config_set_t *configSet, const char *key, unsigned char *colo int configGetColor(config_set_t *configSet, const char *key, unsigned char *color); int configRemoveKey(config_set_t *configSet, const char *key); void configMerge(config_set_t *dest, const config_set_t *source); - void configGetDiscIDBinary(config_set_t *configSet, void *dst); int configRead(config_set_t *configSet); @@ -183,4 +182,9 @@ void configRemoveVMC(config_set_t *configSet, int slot); char *configGetDir(void); void configPrepareNotifications(char *prefix); +int configCheckBDM(int types); +int configCheckHDD(int types); + +int configCheckMC(int types); + #endif diff --git a/include/ethsupport.h b/include/ethsupport.h index 64a5b1378..d1781342e 100644 --- a/include/ethsupport.h +++ b/include/ethsupport.h @@ -12,13 +12,11 @@ typedef struct vmc_spec_t specs; /* Card specifications */ } smb_vmc_infos_t; -void ethInit(item_list_t *itemList); // Full initialization (Start ETH + SMB and apply configuration). GUI must be already initialized, used by GUI to start SMB mode. -void ethDeinitModules(void); // Module-only deinitialization, without the GUI's knowledge (for specific reasons, otherwise unused). -int ethLoadInitModules(void); // Initializes Ethernet and applies configuration. -void ethDisplayErrorStatus(void); // Displays the current error status (if any). GUI must be already initialized. +void ethDeinitModules(void); // Module-only deinitialization, without the GUI's knowledge (for specific reasons, otherwise unused). +int ethLoadInitModules(void); // Initializes Ethernet and applies configuration. +void ethDisplayErrorStatus(void); // Displays the current error status (if any). GUI must be already initialized. int ethGetNetConfig(u8 *ip_address, u8 *netmask, u8 *gateway); int ethApplyConfig(void); -int ethGetDHCPStatus(void); item_list_t *ethGetObject(int initOnly); #endif diff --git a/include/hdd.h b/include/hdd.h index 8704ca7a0..6df1a23c4 100644 --- a/include/hdd.h +++ b/include/hdd.h @@ -3,6 +3,11 @@ #include +#define HDL_GAME_NAME_MAX 64 + +// APA Partition +#define APA_IOCTL2_GETHEADER 0x6836 + typedef struct { u32 start; // Sector address @@ -11,49 +16,24 @@ typedef struct typedef struct { - u8 unused; - u8 sec; - u8 min; - u8 hour; - u8 day; - u8 month; - u16 year; -} ps2time_t; + char partition_name[APA_IDMAX + 1]; + char name[HDL_GAME_NAME_MAX + 1]; + char startup[8 + 1 + 3 + 1]; + u8 hdl_compat_flags; + u8 ops2l_compat_flags; + u8 dma_type; + u8 dma_mode; + u8 disctype; + u32 layer_break; + u32 start_sector; + u32 total_size_in_kb; +} hdl_game_info_t; typedef struct { - u32 checksum; - u32 magic; // APA_MAGIC - u32 next; - u32 prev; - char id[APA_IDMAX]; - char rpwd[APA_PASSMAX]; - char fpwd[APA_PASSMAX]; - u32 start; - u32 length; - u16 type; - u16 flags; - u32 nsub; - ps2time_t created; - u32 main; - u32 number; - u32 modver; - u32 pading1[7]; - char pading2[128]; - struct - { - char magic[32]; - u32 version; - u32 nsector; - ps2time_t created; - u32 osdStart; - u32 osdSize; - char pading3[200]; - } mbr; - apa_sub_t subs[APA_MAXSUB]; -} apa_header_t; - -#define PFS_INODE_MAX_BLOCKS 114 + u32 count; + hdl_game_info_t *games; +} hdl_games_list_t; typedef struct { @@ -62,29 +42,7 @@ typedef struct u16 count; } pfs_blockinfo_t; -typedef struct -{ - u32 checksum; - u32 magic; - pfs_blockinfo_t inode_block; - pfs_blockinfo_t next_segment; - pfs_blockinfo_t last_segment; - pfs_blockinfo_t unused; - pfs_blockinfo_t data[PFS_INODE_MAX_BLOCKS]; - u16 mode; - u16 attr; - u16 uid; - u16 gid; - ps2time_t atime; - ps2time_t ctime; - ps2time_t mtime; - u64 size; - u32 number_blocks; - u32 number_data; - u32 number_segdesg; - u32 subpart; - u32 reserved[4]; -} pfs_inode_t; +extern hdl_game_info_t *gAutoLaunchGame; int hddReadSectors(u32 lba, u32 nsectors, void *buf); @@ -94,4 +52,16 @@ int hddGetPartitionInfo(const char *name, apa_sub_t *parts); // Array should be max entries. int hddGetFileBlockInfo(const char *name, const apa_sub_t *subs, pfs_blockinfo_t *blocks, int max); +int hddCheck(void); +u32 hddGetTotalSectors(void); +int hddIs48bit(void); +int hddSetTransferMode(int type, int mode); +void hddSetIdleTimeout(int timeout); +void hddSetIdleImmediate(void); +int hddGetHDLGamelist(hdl_games_list_t *game_list); +void hddFreeHDLGamelist(hdl_games_list_t *game_list); +int hddSetHDLGameInfo(hdl_game_info_t *ginfo); +int hddDeleteHDLGame(hdl_game_info_t *ginfo); + + #endif diff --git a/include/hddsupport.h b/include/hddsupport.h index ef36032a2..698015f78 100644 --- a/include/hddsupport.h +++ b/include/hddsupport.h @@ -1,36 +1,6 @@ #ifndef __HDD_SUPPORT_H #define __HDD_SUPPORT_H -#include "include/hdd.h" - -#define HDD_MODE_UPDATE_DELAY MENU_UPD_DELAY_NOUPDATE - -#define HDL_GAME_NAME_MAX 64 - -// APA Partition -#define APA_IOCTL2_GETHEADER 0x6836 - -typedef struct -{ - char partition_name[APA_IDMAX + 1]; - char name[HDL_GAME_NAME_MAX + 1]; - char startup[8 + 1 + 3 + 1]; - u8 hdl_compat_flags; - u8 ops2l_compat_flags; - u8 dma_type; - u8 dma_mode; - u8 disctype; - u32 layer_break; - u32 start_sector; - u32 total_size_in_kb; -} hdl_game_info_t; - -typedef struct -{ - u32 count; - hdl_game_info_t *games; -} hdl_games_list_t; - typedef struct { u32 start; @@ -46,17 +16,6 @@ typedef struct vmc_spec_t specs; /* Card specifications */ } hdd_vmc_infos_t; -int hddCheck(void); -u32 hddGetTotalSectors(void); -int hddIs48bit(void); -int hddSetTransferMode(int type, int mode); -void hddSetIdleTimeout(int timeout); -void hddSetIdleImmediate(void); -int hddGetHDLGamelist(hdl_games_list_t *game_list); -void hddFreeHDLGamelist(hdl_games_list_t *game_list); -int hddSetHDLGameInfo(hdl_game_info_t *ginfo); -int hddDeleteHDLGame(hdl_game_info_t *ginfo); - void hddInit(); item_list_t *hddGetObject(int initOnly); void hddLoadModules(void); diff --git a/include/iosupport.h b/include/iosupport.h index e8c905a73..b480934ff 100644 --- a/include/iosupport.h +++ b/include/iosupport.h @@ -1,8 +1,6 @@ #ifndef __IOSUPPORT_H #define __IOSUPPORT_H -#include "include/config.h" - #define IO_MODE_SELECTED_NONE -1 #define IO_MODE_SELECTED_ALL MODE_COUNT diff --git a/include/opl.h b/include/opl.h index d480a5d7d..0f636ce20 100644 --- a/include/opl.h +++ b/include/opl.h @@ -3,23 +3,21 @@ #include #include -#include #include #include #include #include #include #include -#include #include #include #include +#include "include/config.h" #include "include/iosupport.h" +#include "include/submenu.h" +#include "include/menu.h" #include "include/mcemu.h" -#include "include/hddsupport.h" -#include "include/supportbase.h" -#include "include/bdmsupport.h" // Master password for disabling the parental lock. #define OPL_PARENTAL_LOCK_MASTER_PASS "989765" @@ -38,13 +36,6 @@ #define OPL_VMODE_CHANGE_CONFIRMATION_TIMEOUT_MS 10000 -int oplPath2Mode(const char *path); -int oplGetAppImage(const char *device, char *folder, int isRelative, char *value, char *suffix, GSTEXTURE *resultTex, short psm); -int oplScanApps(int (*callback)(const char *path, config_set_t *appConfig, void *arg), void *arg); -int oplShouldAppsUpdate(void); -config_set_t *oplGetLegacyAppsConfig(void); -config_set_t *oplGetLegacyAppsInfo(char *name); - void setErrorMessage(int strId); void setErrorMessageWithCode(int strId, int error); int loadConfig(int types); @@ -185,9 +176,6 @@ extern unsigned char gDefaultSelTextColor[3]; extern unsigned char gDefaultUITextColor[3]; // Launching games with args -extern hdl_game_info_t *gAutoLaunchGame; -extern base_game_info_t *gAutoLaunchBDMGame; -extern bdm_device_data_t *gAutoLaunchDeviceData; extern char *gHDDPrefix; extern char gOPLPart[128]; @@ -197,9 +185,6 @@ void setDefaultColors(void); #define MENU_ITEM_HEIGHT 19 -#include "include/submenu.h" -#include "include/menu.h" - typedef struct { item_list_t *support; @@ -211,11 +196,4 @@ typedef struct submenu_list_t *subMenu; } opl_io_module_t; -/* -BLURT output char blurttext[128]; -#define BLURT \ - snprintf(blurttext, sizeof(blurttext), "%s\\%s(%d)", __FILE__, __func__, __LINE__); \ - delay(10); -#define BLURT snprintf(blurttext, sizeof(blurttext), "%s(%d)", blurttext, __LINE__); -*/ #endif diff --git a/include/supportbase.h b/include/supportbase.h index 95a57ae02..59dea01ab 100644 --- a/include/supportbase.h +++ b/include/supportbase.h @@ -37,14 +37,35 @@ typedef struct u8 unknown2[10]; // Always zero } USBExtreme_game_entry_t; +typedef struct +{ + int fd; + int mode; + char *buffer; + unsigned int size; + unsigned int available; + char *lastPtr; + short allocResult; +} file_buffer_t; + +extern base_game_info_t *gAutoLaunchBDMGame; + int isValidIsoName(char *name, int *pNameLen); +int sbGetmcID(void); +void sbCheckMCFolder(void); + int sbIsSameSize(const char *prefix, int prevSize); +int sbGetFileSize(int fd); int sbCreateSemaphore(void); int sbReadList(base_game_info_t **list, const char *prefix, int *fsize, int *gamecount); +int sbListDir(char *path, const char *separator, int maxElem, int (*readEntry)(int index, const char *path, const char *separator, const char *name, unsigned char d_type)); int sbPrepare(base_game_info_t *game, config_set_t *configSet, int size_cdvdman, void **cdvdman_irx, int *patchindex); void sbUnprepare(void *pCommon); void sbRebuildULCfg(base_game_info_t **list, const char *prefix, int gamecount, int excludeID); +int sbCheckFile(char *path, int mode); void sbCreatePath(const base_game_info_t *game, char *path, const char *prefix, const char *sep, int part); +int sbOpenFile(char *path, int mode); +void *sbReadFile(char *path, int align, int *size); void sbDelete(base_game_info_t **list, const char *prefix, const char *sep, int gamecount, int id); void sbRename(base_game_info_t **list, const char *prefix, const char *sep, int gamecount, int id, char *newname); config_set_t *sbPopulateConfig(base_game_info_t *game, const char *prefix, const char *sep); @@ -57,4 +78,20 @@ int sbProbeISO9660_64(const char *path, base_game_info_t *game, u32 layer1_offse int sbLoadCheats(const char *path, const char *file); +/* File buffer IO functions */ + +/* size will be the maximum line size possible */ +file_buffer_t *sbOpenFileBuffer(char *fpath, int mode, short allocResult, unsigned int size); + +/* size will be the maximum line size possible */ +file_buffer_t *sbOpenFileBufferBuffer(short allocResult, const void *buffer, unsigned int size); + +int sbReadFileBuffer(file_buffer_t *fileBuffer, char **outBuf); + +void sbWriteFileBuffer(file_buffer_t *fileBuffer, char *inBuf, int size); + +void sbCloseFileBuffer(file_buffer_t *fileBuffer); + +int sbDeleteFolder(const char *folder); + #endif diff --git a/include/themes.h b/include/themes.h index 64ceb0f25..2aa5bd9af 100644 --- a/include/themes.h +++ b/include/themes.h @@ -3,6 +3,7 @@ #include "include/textures.h" #include "include/texcache.h" +#include "include/submenu.h" #include "include/menu.h" #define THM_MAX_FILES 64 diff --git a/include/util.h b/include/util.h index 5daad02c4..c8056217d 100644 --- a/include/util.h +++ b/include/util.h @@ -1,31 +1,6 @@ #ifndef __UTIL_H #define __UTIL_H -int getmcID(void); -int getFileSize(int fd); -void checkMCFolder(void); -int openFile(char *path, int mode); -void *readFile(char *path, int align, int *size); -int listDir(char *path, const char *separator, int maxElem, - int (*readEntry)(int index, const char *path, const char *separator, const char *name, unsigned char d_type)); - -typedef struct -{ - int fd; - int mode; - char *buffer; - unsigned int size; - unsigned int available; - char *lastPtr; - short allocResult; -} file_buffer_t; - -file_buffer_t *openFileBufferBuffer(short allocResult, const void *buffer, unsigned int size); -file_buffer_t *openFileBuffer(char *fpath, int mode, short allocResult, unsigned int size); -int readFileBuffer(file_buffer_t *readContext, char **outBuf); -void writeFileBuffer(file_buffer_t *fileBuffer, char *inBuf, int size); -void closeFileBuffer(file_buffer_t *fileBuffer); - int max(int a, int b); int min(int a, int b); int fromHex(char digit); @@ -44,7 +19,6 @@ enum CONSOLE_REGIONS { int InitConsoleRegionData(void); const char *GetSystemDataPath(void); char GetSystemFolderLetter(void); -int sysDeleteFolder(const char *folder); int CheckPS2Logo(int fd, u32 lba); diff --git a/src/appsupport.c b/src/appsupport.c index c454feca6..b1c635edc 100644 --- a/src/appsupport.c +++ b/src/appsupport.c @@ -1,20 +1,38 @@ #include "include/opl.h" #include "include/lang.h" +#include "include/submenu.h" +#include "include/menu.h" #include "include/gui.h" #include "include/appsupport.h" #include "include/themes.h" #include "include/system.h" #include "include/ioman.h" -#include "include/util.h" +#include "include/supportbase.h" #include "include/sound.h" #include -static int appForceUpdate = 1; -static int appItemCount = 0; +#define APP_MODE_UPDATE_DELAY 240 -static config_set_t *configApps; -static app_info_t *appsList; +#define APP_TITLE_MAX 128 +#define APP_PATH_MAX 128 +#define APP_BOOT_MAX 64 +#define APP_ARGV1_MAX 128 + +#define APP_CONFIG_TITLE "title" +#define APP_CONFIG_BOOT "boot" +#define APP_CONFIG_ARGV1 "argv1" + +#define APP_TITLE_CONFIG_FILE "title.cfg" + +typedef struct +{ + char title[APP_TITLE_MAX + 1]; + char path[APP_PATH_MAX + 1]; + char boot[APP_BOOT_MAX + 1]; + char argv1[APP_ARGV1_MAX + 1]; + u8 legacy; +} app_info_t; struct app_info_linked { @@ -22,11 +40,28 @@ struct app_info_linked app_info_t app; }; +static int appForceUpdate = 1; +static int appItemCount = 0; + +static int shouldAppsUpdate; + +static config_set_t *configApps; +static app_info_t *appsList; + // forward declaration static item_list_t appItemList; static void appFreeList(void); +static void appInit(); + +static int appPath2Mode(const char *path); +static int appGetConfigImage(const char *device, char *folder, int isRelative, char *value, char *suffix, GSTEXTURE *resultTex, short psm); +static int appScan(int (*callback)(const char *path, config_set_t *appConfig, void *arg), void *arg); +static int appShouldUpdate(void); +static config_set_t *appGetLegacyConfig(void); +static config_set_t *appGetLegacyConfigInfo(char *name); + static struct config_value_t *appGetConfigValue(int id) { struct config_value_t *cur = configApps->head; @@ -62,7 +97,7 @@ static float appGetELFSize(char *path) return 0.0f; } - size = getFileSize(fd); + size = sbGetFileSize(fd); close(fd); // Return size in MiB @@ -94,12 +129,12 @@ static char *appGetBoot(char *device, int max, char *path) return path; } -void appInit(item_list_t *itemList) +static void appInit(item_list_t *itemList) { LOG("APPSUPPORT Init\n"); appForceUpdate = 1; configGetInt(configGetByType(CONFIG_OPL), "app_frames_delay", &appItemList.delay); - configApps = oplGetLegacyAppsConfig(); + configApps = appGetLegacyConfig(); appsList = NULL; appItemList.enabled = 1; } @@ -120,11 +155,11 @@ static int appNeedsUpdate(item_list_t *itemList) appForceUpdate = 0; update = 1; } - if (oplShouldAppsUpdate()) + if (appShouldUpdate()) update = 1; if (update) - configApps = oplGetLegacyAppsConfig(); + configApps = appGetLegacyConfig(); return update; } @@ -247,7 +282,7 @@ static int appUpdateItemList(item_list_t *itemList) appItemCount += addAppsLegacyList(&appsLinkedList); // Scan devices for apps. - appItemCount += oplScanApps(&appScanCallback, &appsLinkedList); + appItemCount += appScan(&appScanCallback, &appsLinkedList); // Generate apps list if (appItemCount > 0) { @@ -317,7 +352,7 @@ static void appDeleteItem(item_list_t *itemList, int id) configApps->modified = 1; configWrite(configApps); } else { - sysDeleteFolder(appsList[id].path); + sbDeleteFolder(appsList[id].path); } appForceUpdate = 1; @@ -397,7 +432,7 @@ static void appLaunchItem(item_list_t *itemList, int id, config_set_t *configSet strcpy(partition, ""); // To keep the necessary device accessible, we will assume the mode that owns the device which contains the file to boot. - mode = oplPath2Mode(filename); + mode = appPath2Mode(filename); if (mode < 0) mode = APP_MODE; // Legacy apps mode on memory card (mc?:/*) @@ -422,7 +457,7 @@ static config_set_t *appGetConfig(item_list_t *itemList, int id) if (appsList[id].legacy) { struct config_value_t *cur = appGetConfigValue(id); - config = oplGetLegacyAppsInfo(appGetELFName(cur->val)); + config = appGetLegacyConfigInfo(appGetELFName(cur->val)); configRead(config); configSetStr(config, CONFIG_ITEM_NAME, appGetELFName(cur->val)); @@ -461,9 +496,9 @@ static int appGetImage(item_list_t *itemList, char *folder, int isRelative, char startup = appGetBoot(device, sizeof(device), value); if (!strcmp(folder, "ART")) - return oplGetAppImage(device, folder, isRelative, startup, suffix, resultTex, psm); + return appGetConfigImage(device, folder, isRelative, startup, suffix, resultTex, psm); else - return oplGetAppImage(device, folder, isRelative, value, suffix, resultTex, psm); + return appGetConfigImage(device, folder, isRelative, value, suffix, resultTex, psm); } static int appGetTextId(item_list_t *itemList) @@ -496,7 +531,223 @@ static void appShutdown(item_list_t *itemList) } } +extern opl_io_module_t list_support[MODE_COUNT]; /* TODO: Modularize apps support. */ + +// For resolving the mode, given an app's path +static int appPath2Mode(const char *path) +{ + char appsPath[APP_PATH_MAX]; + const char *blkdevnameend; + int i, blkdevnamelen; + item_list_t *listSupport; + + for (i = 0; i < MODE_COUNT; i++) { + opl_io_module_t *mod = &list_support[i]; + listSupport = mod->support; + if ((listSupport != NULL) && (listSupport->itemGetPrefix != NULL)) { + char *prefix = listSupport->itemGetPrefix(listSupport); + snprintf(appsPath, sizeof(appsPath), "%sAPPS", prefix); + + blkdevnameend = strchr(appsPath, ':'); + if (blkdevnameend != NULL) { + blkdevnamelen = (int)(blkdevnameend - appsPath); + + if (strncmp(path, appsPath, blkdevnamelen) == 0) + return listSupport->mode; + } + } + } + + return -1; +} + +static int appGetConfigImage(const char *device, char *folder, int isRelative, char *value, char *suffix, GSTEXTURE *resultTex, short psm) +{ + int i, remaining, elfbootmode; + char priority; + item_list_t *listSupport; + elfbootmode = -1; + if (device != NULL) { + elfbootmode = appPath2Mode(device); + if (elfbootmode >= 0) { + opl_io_module_t *mod = &list_support[elfbootmode]; + listSupport = mod->support; + + if ((listSupport != NULL) && (listSupport->enabled)) { + if (listSupport->itemGetImage(listSupport, folder, isRelative, value, suffix, resultTex, psm) >= 0) + return 0; + } + } + } + + // We search on ever devices from fatest to slowest. + for (remaining = MODE_COUNT, priority = 0; remaining > 0 && priority < 4; priority++) { + for (i = 0; i < MODE_COUNT; i++) { + opl_io_module_t *mod = &list_support[i]; + listSupport = mod->support; + + if (i == elfbootmode) + continue; + + if ((listSupport != NULL) && (listSupport->enabled) && (listSupport->appsPriority == priority)) { + if (listSupport->itemGetImage(listSupport, folder, isRelative, value, suffix, resultTex, psm) >= 0) + return 0; + remaining--; + } + } + } + + return -1; +} + +static int scanApps(int (*callback)(const char *path, config_set_t *appConfig, void *arg), void *arg, char *appsPath, int exception) +{ + struct dirent *pdirent; + DIR *pdir; + int count, ret; + config_set_t *appConfig; + char dir[APP_PATH_MAX]; + char path[APP_PATH_MAX]; + + count = 0; + if ((pdir = opendir(appsPath)) != NULL) { + while ((pdirent = readdir(pdir)) != NULL) { + if (exception && strchr(pdirent->d_name, '_') == NULL) + continue; + + if (strcmp(pdirent->d_name, ".") == 0 || strcmp(pdirent->d_name, "..") == 0) + continue; + + snprintf(dir, sizeof(dir), "%s/%s", appsPath, pdirent->d_name); + if (pdirent->d_type != DT_DIR) + continue; + + snprintf(path, sizeof(path), "%s/%s", dir, APP_TITLE_CONFIG_FILE); + appConfig = configAlloc(0, NULL, path); + if (appConfig != NULL) { + configRead(appConfig); + + ret = callback(dir, appConfig, arg); + configFree(appConfig); + + if (ret == 0) + count++; + else if (ret < 0) { // Stopped because of unrecoverable error. + break; + } + } + } + + closedir(pdir); + } else + LOG("APPS failed to open dir %s\n", appsPath); + + return count; +} + +static int appScan(int (*callback)(const char *path, config_set_t *appConfig, void *arg), void *arg) +{ + int i, count; + item_list_t *listSupport; + char appsPath[APP_PATH_MAX]; + count = 0; + for (i = 0; i < MODE_COUNT; i++) { + opl_io_module_t *mod = &list_support[i]; + listSupport = mod->support; + if ((listSupport != NULL) && (listSupport->enabled) && (listSupport->itemGetPrefix != NULL)) { + char *prefix = listSupport->itemGetPrefix(listSupport); + snprintf(appsPath, sizeof(appsPath), "%sAPPS", prefix); + count += scanApps(callback, arg, appsPath, 0); + } + } + + for (i = 0; i < 2; i++) { + snprintf(appsPath, sizeof(appsPath), "mc%d:", i); + count += scanApps(callback, arg, appsPath, 1); + } + + return count; +} + +static int appShouldUpdate(void) +{ + int result; + + result = shouldAppsUpdate; + shouldAppsUpdate = 0; + + return result; +} + +static config_set_t *appGetLegacyConfig(void) +{ + int i, fd; + item_list_t *listSupport; + config_set_t *appConfig; + char appsPath[128]; + + snprintf(appsPath, sizeof(appsPath), "mc?:OPL/conf_apps.cfg"); + fd = sbOpenFile(appsPath, O_RDONLY); + if (fd >= 0) { + appConfig = configAlloc(CONFIG_APPS, NULL, appsPath); + close(fd); + return appConfig; + } + + for (i = MODE_COUNT - 1; i >= 0; i--) { + opl_io_module_t *mod = &list_support[i]; + listSupport = mod->support; + if ((listSupport != NULL) && (listSupport->enabled) && (listSupport->itemGetPrefix != NULL)) { + char *prefix = listSupport->itemGetPrefix(listSupport); + snprintf(appsPath, sizeof(appsPath), "%sconf_apps.cfg", prefix); + + fd = sbOpenFile(appsPath, O_RDONLY); + if (fd >= 0) { + appConfig = configAlloc(CONFIG_APPS, NULL, appsPath); + close(fd); + return appConfig; + } + } + } + + /* Apps config not found on any device, go with last tested device. + Does not matter if the config file could be loaded or not */ + appConfig = configAlloc(CONFIG_APPS, NULL, appsPath); + + return appConfig; +} + +static config_set_t *appGetLegacyConfigInfo(char *name) +{ + int i, fd; + item_list_t *listSupport; + config_set_t *appConfig; + char appsPath[128]; + + for (i = MODE_COUNT - 1; i >= 0; i--) { + opl_io_module_t *mod = &list_support[i]; + listSupport = mod->support; + if ((listSupport != NULL) && (listSupport->enabled) && (listSupport->itemGetPrefix != NULL)) { + char *prefix = listSupport->itemGetPrefix(listSupport); + snprintf(appsPath, sizeof(appsPath), "%sCFG%s%s.cfg", prefix, i == ETH_MODE ? "\\" : "/", name); + + fd = sbOpenFile(appsPath, O_RDONLY); + if (fd >= 0) { + appConfig = configAlloc(0, NULL, appsPath); + close(fd); + return appConfig; + } + } + } + + /* Apps config not found on any device, go with last tested device. + Does not matter if the config file could be loaded or not */ + appConfig = configAlloc(0, NULL, appsPath); + + return appConfig; +} + static item_list_t appItemList = { APP_MODE, -1, 0, MODE_FLAG_NO_COMPAT | MODE_FLAG_NO_UPDATE, MENU_MIN_INACTIVE_FRAMES, APP_MODE_UPDATE_DELAY, NULL, NULL, &appGetTextId, NULL, &appInit, &appNeedsUpdate, &appUpdateItemList, &appGetItemCount, NULL, &appGetItemName, &appGetItemNameLength, &appGetItemStartup, &appDeleteItem, &appRenameItem, &appLaunchItem, - &appGetConfig, &appGetImage, &appCleanUp, &appShutdown, NULL, &appGetIconId}; + &appGetConfig, &appGetImage, &appCleanUp, &appShutdown, NULL, &appGetIconId}; \ No newline at end of file diff --git a/src/audio.c b/src/audio.c index fb3160a13..63ed017c7 100644 --- a/src/audio.c +++ b/src/audio.c @@ -7,34 +7,59 @@ #include -#include "include/audio.h" #include "include/opl.h" +#include "include/audio.h" #include "include/ioman.h" +extern int audio_initialized; /*-- General Audio ------------------------------------------------------------------------------------------------------ -----------------------------------------------------------------------------------------------------------------------------*/ void audioInit(void) { - if (audsrv_init() != 0) { - LOG("AUDIO: Failed to initialize audsrv\n"); - LOG("AUDIO: Audsrv returned error string: %s\n", audsrv_get_error_string()); - return; + if (!audio_initialized) { + if (audsrv_init() != 0) { + LOG("AUDIO: Failed to initialize audsrv\n"); + LOG("AUDIO: Audsrv returned error string: %s\n", audsrv_get_error_string()); + return; + } else { + audsrv_adpcm_init(); + } + audio_initialized = 1; } } void audioEnd(void) { + if (!audio_initialized) { + LOG("AUDIO: %s: ERROR: not initialized!\n", __FUNCTION__); + return; + } + audsrv_quit(); + audio_initialized = 0; } -void audioSetVolume(int sfx) +void audioSetVolume() { - int i; - - for (i = 1; i < sfx; i++) - audsrv_adpcm_set_volume(i, gSFXVolume); + if (!audio_initialized) { + LOG("AUDIO: %s: ERROR: not initialized!\n", __FUNCTION__); + return; + } audsrv_adpcm_set_volume(0, gBootSndVolume); audsrv_set_volume(gBGMVolume); } + +void audioSetSfxVolume(int sfx) +{ + int i; + + if (!audio_initialized) { + LOG("AUDIO: %s: ERROR: not initialized!\n", __FUNCTION__); + return; + } + + for (i = 1; i < sfx; i++) + audsrv_adpcm_set_volume(i, gSFXVolume); +} \ No newline at end of file diff --git a/src/bdmsupport.c b/src/bdmsupport.c index 9633100ad..745f7592b 100644 --- a/src/bdmsupport.c +++ b/src/bdmsupport.c @@ -1,5 +1,11 @@ #include "include/opl.h" +#include "include/hdd.h" +#include "include/hddsupport.h" +#include "include/supportbase.h" +#include "include/bdmsupport.h" #include "include/lang.h" +#include "include/submenu.h" +#include "include/menu.h" #include "include/gui.h" #include "include/util.h" #include "include/themes.h" @@ -18,15 +24,35 @@ #define NEWLIB_PORT_AWARE #include // fileXioIoctl, fileXioDevctl +#define MAX_BDM_DEVICES 5 + +#define BDM_TYPE_UNKNOWN -1 +#define BDM_TYPE_USB 0 +#define BDM_TYPE_ILINK 1 +#define BDM_TYPE_SDC 2 +#define BDM_TYPE_ATA 3 + +#define BDM_MODE_UPDATE_DELAY MENU_UPD_DELAY_GENREFRESH + +typedef struct +{ + int active; /* Activation flag */ + u64 start_sector; /* Start sector of vmc file */ + int flags; /* Card flag */ + vmc_spec_t specs; /* Card specifications */ +} bdm_vmc_infos_t; + static int iLinkModLoaded = 0; static int mx4sioModLoaded = 0; static int hddModLoaded = 0; static s32 bdmLoadModuleLock; -int bdmDeviceModeStarted; +static int bdmDeviceModeStarted; static item_list_t bdmDeviceList[MAX_BDM_DEVICES]; static int bdmDeviceListInitialized = 0; +bdm_device_data_t *gAutoLaunchDeviceData; + void bdmInitDevicesData(); int bdmUpdateDeviceData(item_list_t *itemList); diff --git a/src/config.c b/src/config.c index b38b40411..971e0af9c 100644 --- a/src/config.c +++ b/src/config.c @@ -5,9 +5,16 @@ */ #include "include/opl.h" +#include "include/submenu.h" +#include "include/menu.h" +#include "include/supportbase.h" #include "include/util.h" +#include "include/hdd.h" +#include "include/hddsupport.h" +#include "include/bdmsupport.h" #include "include/ioman.h" #include "include/sound.h" +#include "include/system.h" // FIXME: We should not need this function. // Use newlib's 'stat' to get GMT time. @@ -26,6 +33,8 @@ static const char *configFilenames[CONFIG_INDEX_COUNT] = { "conf_game.cfg", }; +static u8 isLoaded = 0; + static int strToColor(const char *string, unsigned char *color) { int cnt = 0, n = 0; @@ -164,7 +173,7 @@ static char cfgDevice[8]; char *configGetDir(void) { if (!strncmp(cfgDevice, "mc", 2)) { - cfgDevice[2] = getmcID(); + cfgDevice[2] = sbGetmcID(); } char *path = cfgDevice; @@ -410,10 +419,10 @@ static int configReadLegacyIP(void) config_set_t *configSet; char temp[16]; - int fd = openFile(legacyNetConfigPath, O_RDONLY); + int fd = sbOpenFile(legacyNetConfigPath, O_RDONLY); if (fd >= 0) { char ipconfig[256]; - int size = getFileSize(fd); + int size = sbGetFileSize(fd); read(fd, &ipconfig, size); close(fd); @@ -472,7 +481,7 @@ static int configReadFileBuffer(file_buffer_t *fileBuffer, config_set_t *configS char prefix[CONFIG_KEY_NAME_LEN]; memset(prefix, 0, sizeof(prefix)); - while (readFileBuffer(fileBuffer, &line)) { + while (sbReadFileBuffer(fileBuffer, &line)) { lineno++; char key[CONFIG_KEY_NAME_LEN], val[CONFIG_KEY_VALUE_LEN]; @@ -509,7 +518,7 @@ static int configReadFileBuffer(file_buffer_t *fileBuffer, config_set_t *configS int configReadBuffer(config_set_t *configSet, const void *buffer, int size) { int ret; - file_buffer_t *fileBuffer = openFileBufferBuffer(0, buffer, size); + file_buffer_t *fileBuffer = sbOpenFileBufferBuffer(0, buffer, size); if (!fileBuffer) { configSet->modified = 0; return 0; @@ -517,14 +526,14 @@ int configReadBuffer(config_set_t *configSet, const void *buffer, int size) ret = configReadFileBuffer(fileBuffer, configSet); - closeFileBuffer(fileBuffer); + sbCloseFileBuffer(fileBuffer); return ret; } int configRead(config_set_t *configSet) { int ret; - file_buffer_t *fileBuffer = openFileBuffer(configSet->filename, O_RDONLY, 0, 4096); + file_buffer_t *fileBuffer = sbOpenFileBuffer(configSet->filename, O_RDONLY, 0, 4096); if (!fileBuffer) { LOG("CONFIG No file %s.\n", configSet->filename); configSet->modified = 0; @@ -533,32 +542,33 @@ int configRead(config_set_t *configSet) ret = configReadFileBuffer(fileBuffer, configSet); - closeFileBuffer(fileBuffer); + sbCloseFileBuffer(fileBuffer); return ret; } int configWrite(config_set_t *configSet) { if (configSet->modified) { - file_buffer_t *fileBuffer = openFileBuffer(configSet->filename, O_WRONLY | O_CREAT | O_TRUNC, 0, 4096); + file_buffer_t *fileBuffer = sbOpenFileBuffer(configSet->filename, O_WRONLY | O_CREAT | O_TRUNC, 0, 4096); if (fileBuffer) { char line[512]; - bgmIsMuted(1); struct config_value_t *cur = configSet->head; while (cur) { + bgmIsMuted(1); if ((cur->key[0] != '\0') && (cur->key[0] != '#')) { snprintf(line, sizeof(line), "%s=%s\r\n", cur->key, cur->val); // add windows CR+LF (0x0D 0x0A) - writeFileBuffer(fileBuffer, line, strlen(line)); + sbWriteFileBuffer(fileBuffer, line, strlen(line)); } // and advance cur = cur->next; + bgmIsMuted(0); } - closeFileBuffer(fileBuffer); + sbCloseFileBuffer(fileBuffer); configSet->modified = 0; - bgmIsMuted(0); + return 1; } return 0; @@ -645,3 +655,76 @@ void configRemoveVMC(config_set_t *configSet, int slot) snprintf(gkey, sizeof(gkey), "%s_%d", CONFIG_ITEM_VMC, slot); configRemoveKey(configSet, gkey); } + +int configCheckBDM(int types) +{ + char path[64]; + int value; + + // check USB + if (bdmFindPartition(path, "conf_opl.cfg", 0)) { + if (!isLoaded) { + configEnd(); + configInit(path); + value = configReadMulti(types); + config_set_t *configOPL = configGetByType(CONFIG_OPL); + configSetInt(configOPL, CONFIG_OPL_BDM_MODE, START_MODE_AUTO); + return value; + } else { + configSetMove(path); + return configWriteMulti(types); + } + } + + return -ENOENT; +} + +int configCheckHDD(int types) +{ + int value; + char path[64]; + + hddLoadModules(); + if (!isLoaded) { + hddLoadSupportModules(); + + snprintf(path, sizeof(path), "%sconf_opl.cfg", gHDDPrefix); + value = open(path, O_RDONLY); + if (value >= 0) { + close(value); + configEnd(); + configInit(gHDDPrefix); + value = configReadMulti(types); + config_set_t *configOPL = configGetByType(CONFIG_OPL); + configSetInt(configOPL, CONFIG_OPL_HDD_MODE, START_MODE_AUTO); + return value; + } + } else { + // Check that the formatted & usable HDD is connected. + if (hddCheck() == 0) { + configSetMove(gHDDPrefix); + return configWriteMulti(types); + } + } + + return -ENOENT; +} + +int configCheckMC(int types) +{ + if (!isLoaded) { + // At this point, the user has no loadable config files on any supported device, so try to find a device to save on. + // We don't want to get users into alternate mode for their very first launch of OPL (i.e no config file at all, but still want to save on MC) + // Check for a memory card inserted. + if (sysCheckMC() >= 0) { + configPrepareNotifications(gBaseMCDir); + showCfgPopup = 0; + return 0; + } + } else { + configSetMove(NULL); + return configWriteMulti(types); + } + + return -ENOENT; +} \ No newline at end of file diff --git a/src/dia.c b/src/dia.c index 2936201dd..27e688c45 100644 --- a/src/dia.c +++ b/src/dia.c @@ -5,7 +5,10 @@ */ #include "include/opl.h" +#include "include/dia.h" #include "include/dialogs.h" +#include "include/submenu.h" +#include "include/menu.h" #include "include/gui.h" #include "include/lang.h" #include "include/pad.h" diff --git a/src/dialogs.c b/src/dialogs.c index 344469ccc..d7c2d312a 100644 --- a/src/dialogs.c +++ b/src/dialogs.c @@ -1,6 +1,9 @@ #include "include/opl.h" +#include "include/dia.h" #include "include/dialogs.h" #include "include/lang.h" +#include "include/submenu.h" +#include "include/menu.h" #include "include/gui.h" #include "include/guigame.h" diff --git a/src/ethsupport.c b/src/ethsupport.c index 02dfb7bda..2cd29271d 100644 --- a/src/ethsupport.c +++ b/src/ethsupport.c @@ -1,6 +1,9 @@ #include "include/opl.h" +#include "include/supportbase.h" #include "include/mcemu.h" #include "include/lang.h" +#include "include/submenu.h" +#include "include/menu.h" #include "include/gui.h" #include "include/util.h" #include "include/renderman.h" @@ -162,6 +165,22 @@ static int ethSMBDisconnect(void) return 0; } +int ethGetDHCPStatus(void) +{ + t_ip_info ip_info; + int result; + + if ((result = ps2ip_getconfig("sm0", &ip_info)) >= 0) { + if (ip_info.dhcp_enabled) { + result = (ip_info.dhcp_status == DHCP_STATE_BOUND || (ip_info.dhcp_status == DHCP_STATE_OFF)); + } else + result = -1; + } + + return result; +} + + static void EthStatusCheckCb(s32 alarm_id, u16 time, void *common) { iSignalSema(*(int *)common); @@ -924,19 +943,4 @@ static int ethApplyIPConfig(void) } return result; -} - -int ethGetDHCPStatus(void) -{ - t_ip_info ip_info; - int result; - - if ((result = ps2ip_getconfig("sm0", &ip_info)) >= 0) { - if (ip_info.dhcp_enabled) { - result = (ip_info.dhcp_status == DHCP_STATE_BOUND || (ip_info.dhcp_status == DHCP_STATE_OFF)); - } else - result = -1; - } - - return result; -} +} \ No newline at end of file diff --git a/src/fntsys.c b/src/fntsys.c index f0ddd558f..ec0059a82 100644 --- a/src/fntsys.c +++ b/src/fntsys.c @@ -9,6 +9,7 @@ #include "include/renderman.h" #include "include/ioman.h" #include "include/utf8.h" +#include "include/supportbase.h" #include "include/util.h" #include "include/atlas.h" #include "include/imports.h" @@ -236,7 +237,7 @@ static int fntLoadSlot(font_t *font, char *path, int fontSize) fntInitSlot(font); if (path) { - buffer = readFile(path, -1, &bufferSize); + buffer = sbReadFile(path, -1, &bufferSize); if (!buffer) { LOG("FNTSYS Font file loading failed: %s\n", path); return FNT_ERROR; diff --git a/src/gui.c b/src/gui.c index 2b7361e1a..1dd57a810 100644 --- a/src/gui.c +++ b/src/gui.c @@ -5,6 +5,9 @@ */ #include "include/opl.h" +#include "include/submenu.h" +#include "include/menu.h" +#include "include/dia.h" #include "include/dialogs.h" #include "include/gui.h" #include "include/renderman.h" @@ -34,6 +37,7 @@ static int gCompletedOps; static int gTerminate; static int gInitComplete; + static gui_callback_t gFrameHook; static s32 gSemaId; @@ -713,6 +717,7 @@ void guiShowUIConfig(void) applyConfig(themeID, langID, 1); sfxInit(0); + audioInit(); if (gEnableBGM && !isBgmPlaying()) bgmStart(); @@ -883,7 +888,8 @@ static void guiSetAudioSettingsState(void) diaGetInt(diaAudioConfig, CFG_BOOT_SND_VOLUME, &gBootSndVolume); diaGetInt(diaAudioConfig, CFG_BGM_VOLUME, &gBGMVolume); diaGetString(diaAudioConfig, CFG_DEFAULT_BGM_PATH, gDefaultBGMPath, sizeof(gDefaultBGMPath)); - audioSetVolume(SFX_COUNT); + + audioSetVolume(); if (gEnableBGM && !isBgmPlaying()) bgmStart(); diff --git a/src/hdd.c b/src/hdd.c index 2b6130eaa..46bc22297 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -2,12 +2,58 @@ #include "include/opl.h" #include "include/hdd.h" #include "include/ioman.h" -#include "include/hddsupport.h" #define NEWLIB_PORT_AWARE #include +#include #include "opl-hdd-ioctl.h" +hdl_game_info_t *gAutoLaunchGame; + +typedef struct +{ + u8 unused; + u8 sec; + u8 min; + u8 hour; + u8 day; + u8 month; + u16 year; +} ps2time_t; + +typedef struct +{ + u32 checksum; + u32 magic; // APA_MAGIC + u32 next; + u32 prev; + char id[APA_IDMAX]; + char rpwd[APA_PASSMAX]; + char fpwd[APA_PASSMAX]; + u32 start; + u32 length; + u16 type; + u16 flags; + u32 nsub; + ps2time_t created; + u32 main; + u32 number; + u32 modver; + u32 pading1[7]; + char pading2[128]; + struct + { + char magic[32]; + u32 version; + u32 nsector; + ps2time_t created; + u32 osdStart; + u32 osdSize; + char pading3[200]; + } mbr; + apa_sub_t subs[APA_MAXSUB]; +} apa_header_t; + typedef struct // size = 1024 { u32 checksum; // HDL uses 0xdeadfeed magic here @@ -29,6 +75,33 @@ typedef struct // size = 1024 } part_specs[65]; } hdl_apa_header; +#define PFS_INODE_MAX_BLOCKS 114 + +typedef struct +{ + u32 checksum; + u32 magic; + pfs_blockinfo_t inode_block; + pfs_blockinfo_t next_segment; + pfs_blockinfo_t last_segment; + pfs_blockinfo_t unused; + pfs_blockinfo_t data[PFS_INODE_MAX_BLOCKS]; + u16 mode; + u16 attr; + u16 uid; + u16 gid; + ps2time_t atime; + ps2time_t ctime; + ps2time_t mtime; + u64 size; + u32 number_blocks; + u32 number_data; + u32 number_segdesg; + u32 subpart; + u32 reserved[4]; +} pfs_inode_t; + + #define HDL_GAME_DATA_OFFSET 0x100000 // Sector 0x800 in the extended attribute area. #define HDL_FS_MAGIC 0x1337 diff --git a/src/hddsupport.c b/src/hddsupport.c index 828031785..66ecdeeff 100644 --- a/src/hddsupport.c +++ b/src/hddsupport.c @@ -1,5 +1,8 @@ #include "include/opl.h" + #include "include/lang.h" +#include "include/submenu.h" +#include "include/menu.h" #include "include/gui.h" #include "include/supportbase.h" #include "include/util.h" @@ -20,7 +23,11 @@ #include #include "opl-hdd-ioctl.h" +#include "include/hdd.h" +#include "include/hddsupport.h" + #define OPL_HDD_MODE_PS2LOGO_OFFSET 0x17F8 +#define HDD_MODE_UPDATE_DELAY MENU_UPD_DELAY_NOUPDATE #include "../modules/isofs/zso.h" diff --git a/src/lang.c b/src/lang.c index 22ca90b01..a14079ece 100644 --- a/src/lang.c +++ b/src/lang.c @@ -1,6 +1,6 @@ #include "include/opl.h" #include "include/lang.h" -#include "include/util.h" +#include "include/supportbase.h" #include "include/fntsys.h" #include "include/ioman.h" #include "include/themes.h" @@ -56,17 +56,17 @@ static int lngLoadFromFile(char *path, char *name) { char dir[128]; - file_buffer_t *fileBuffer = openFileBuffer(path, O_RDONLY, 1, 1024); + file_buffer_t *fileBuffer = sbOpenFileBuffer(path, O_RDONLY, 1, 1024); if (fileBuffer) { // file exists, try to read it and load the custom lang char **curL = lang_strs; char **newL = (char **)calloc(LANG_STR_COUNT, sizeof(char *)); int strId = 0; - while (strId < LANG_STR_COUNT && readFileBuffer(fileBuffer, &newL[strId])) { + while (strId < LANG_STR_COUNT && sbReadFileBuffer(fileBuffer, &newL[strId])) { strId++; } - closeFileBuffer(fileBuffer); + sbCloseFileBuffer(fileBuffer); LOG("LANG Loaded %d entries\n", strId); @@ -154,7 +154,7 @@ int lngAddLanguages(char *path, const char *separator, int mode) { int result; - result = listDir(path, separator, MAX_LANGUAGE_FILES - nLanguages, &lngReadEntry); + result = sbListDir(path, separator, MAX_LANGUAGE_FILES - nLanguages, &lngReadEntry); nLanguages += result; lngRebuildLangNames(); diff --git a/src/menu.c b/src/menu.c index 47db6b27c..1f625594f 100644 --- a/src/menu.c +++ b/src/menu.c @@ -6,6 +6,9 @@ #include "include/opl.h" #include "include/dia.h" +#include "include/submenu.h" +#include "include/menu.h" +#include "include/supportbase.h" #include "include/renderman.h" #include "include/fntsys.h" #include "include/lang.h" diff --git a/src/opl.c b/src/opl.c index 926be5b3d..ee68516b9 100644 --- a/src/opl.c +++ b/src/opl.c @@ -6,12 +6,15 @@ #include "include/opl.h" #include "include/ioman.h" +#include "include/submenu.h" +#include "include/menu.h" #include "include/gui.h" #include "include/guigame.h" #include "include/renderman.h" #include "include/lang.h" #include "include/themes.h" #include "include/pad.h" +#include "include/dia.h" #include "include/dialogs.h" #include "include/system.h" #include "include/config.h" @@ -19,9 +22,13 @@ #include "include/compatupd.h" #include "include/imports.h" #include "httpclient.h" +#include "include/supportbase.h" #include "include/ethsupport.h" #include "include/appsupport.h" - +#include "include/bdmsupport.h" +#include "include/hdd.h" +#include "include/hddsupport.h" +#include "include/supportbase.h" #include "include/cheatman.h" #include "include/audio.h" #include "include/sound.h" @@ -107,7 +114,7 @@ static unsigned int frameCounter; static char errorMessage[256]; -static opl_io_module_t list_support[MODE_COUNT]; +opl_io_module_t list_support[MODE_COUNT]; // Global data char *gBaseMCDir; @@ -183,9 +190,6 @@ unsigned char gDefaultBgColor[3]; unsigned char gDefaultTextColor[3]; unsigned char gDefaultSelTextColor[3]; unsigned char gDefaultUITextColor[3]; -hdl_game_info_t *gAutoLaunchGame; -base_game_info_t *gAutoLaunchBDMGame; -bdm_device_data_t *gAutoLaunchDeviceData; char gOPLPart[128]; char *gHDDPrefix; char gExportName[32]; @@ -434,216 +438,6 @@ static void deinitAllSupport(int exception, int modeSelected) } } -// For resolving the mode, given an app's path -int oplPath2Mode(const char *path) -{ - char appsPath[64]; - const char *blkdevnameend; - int i, blkdevnamelen; - item_list_t *listSupport; - - for (i = 0; i < MODE_COUNT; i++) { - listSupport = list_support[i].support; - if ((listSupport != NULL) && (listSupport->itemGetPrefix != NULL)) { - char *prefix = listSupport->itemGetPrefix(listSupport); - snprintf(appsPath, sizeof(appsPath), "%sAPPS", prefix); - - blkdevnameend = strchr(appsPath, ':'); - if (blkdevnameend != NULL) { - blkdevnamelen = (int)(blkdevnameend - appsPath); - - if (strncmp(path, appsPath, blkdevnamelen) == 0) - return listSupport->mode; - } - } - } - - return -1; -} - -int oplGetAppImage(const char *device, char *folder, int isRelative, char *value, char *suffix, GSTEXTURE *resultTex, short psm) -{ - int i, remaining, elfbootmode; - char priority; - item_list_t *listSupport; - - elfbootmode = -1; - if (device != NULL) { - elfbootmode = oplPath2Mode(device); - if (elfbootmode >= 0) { - listSupport = list_support[elfbootmode].support; - - if ((listSupport != NULL) && (listSupport->enabled)) { - if (listSupport->itemGetImage(listSupport, folder, isRelative, value, suffix, resultTex, psm) >= 0) - return 0; - } - } - } - - // We search on ever devices from fatest to slowest. - for (remaining = MODE_COUNT, priority = 0; remaining > 0 && priority < 4; priority++) { - for (i = 0; i < MODE_COUNT; i++) { - listSupport = list_support[i].support; - - if (i == elfbootmode) - continue; - - if ((listSupport != NULL) && (listSupport->enabled) && (listSupport->appsPriority == priority)) { - if (listSupport->itemGetImage(listSupport, folder, isRelative, value, suffix, resultTex, psm) >= 0) - return 0; - remaining--; - } - } - } - - return -1; -} - -static int scanApps(int (*callback)(const char *path, config_set_t *appConfig, void *arg), void *arg, char *appsPath, int exception) -{ - struct dirent *pdirent; - DIR *pdir; - int count, ret; - config_set_t *appConfig; - char dir[128]; - char path[128]; - - count = 0; - if ((pdir = opendir(appsPath)) != NULL) { - while ((pdirent = readdir(pdir)) != NULL) { - if (exception && strchr(pdirent->d_name, '_') == NULL) - continue; - - if (strcmp(pdirent->d_name, ".") == 0 || strcmp(pdirent->d_name, "..") == 0) - continue; - - snprintf(dir, sizeof(dir), "%s/%s", appsPath, pdirent->d_name); - if (pdirent->d_type != DT_DIR) - continue; - - snprintf(path, sizeof(path), "%s/%s", dir, APP_TITLE_CONFIG_FILE); - appConfig = configAlloc(0, NULL, path); - if (appConfig != NULL) { - configRead(appConfig); - - ret = callback(dir, appConfig, arg); - configFree(appConfig); - - if (ret == 0) - count++; - else if (ret < 0) { // Stopped because of unrecoverable error. - break; - } - } - } - - closedir(pdir); - } else - LOG("APPS failed to open dir %s\n", appsPath); - - return count; -} - -int oplScanApps(int (*callback)(const char *path, config_set_t *appConfig, void *arg), void *arg) -{ - int i, count; - item_list_t *listSupport; - char appsPath[64]; - - count = 0; - for (i = 0; i < MODE_COUNT; i++) { - listSupport = list_support[i].support; - if ((listSupport != NULL) && (listSupport->enabled) && (listSupport->itemGetPrefix != NULL)) { - char *prefix = listSupport->itemGetPrefix(listSupport); - snprintf(appsPath, sizeof(appsPath), "%sAPPS", prefix); - count += scanApps(callback, arg, appsPath, 0); - } - } - - for (i = 0; i < 2; i++) { - snprintf(appsPath, sizeof(appsPath), "mc%d:", i); - count += scanApps(callback, arg, appsPath, 1); - } - - return count; -} - -int oplShouldAppsUpdate(void) -{ - int result; - - result = (int)shouldAppsUpdate; - shouldAppsUpdate = 0; - - return result; -} - -config_set_t *oplGetLegacyAppsConfig(void) -{ - int i, fd; - item_list_t *listSupport; - config_set_t *appConfig; - char appsPath[128]; - - snprintf(appsPath, sizeof(appsPath), "mc?:OPL/conf_apps.cfg"); - fd = openFile(appsPath, O_RDONLY); - if (fd >= 0) { - appConfig = configAlloc(CONFIG_APPS, NULL, appsPath); - close(fd); - return appConfig; - } - - for (i = MODE_COUNT - 1; i >= 0; i--) { - listSupport = list_support[i].support; - if ((listSupport != NULL) && (listSupport->enabled) && (listSupport->itemGetPrefix != NULL)) { - char *prefix = listSupport->itemGetPrefix(listSupport); - snprintf(appsPath, sizeof(appsPath), "%sconf_apps.cfg", prefix); - - fd = openFile(appsPath, O_RDONLY); - if (fd >= 0) { - appConfig = configAlloc(CONFIG_APPS, NULL, appsPath); - close(fd); - return appConfig; - } - } - } - - /* Apps config not found on any device, go with last tested device. - Does not matter if the config file could be loaded or not */ - appConfig = configAlloc(CONFIG_APPS, NULL, appsPath); - - return appConfig; -} - -config_set_t *oplGetLegacyAppsInfo(char *name) -{ - int i, fd; - item_list_t *listSupport; - config_set_t *appConfig; - char appsPath[128]; - - for (i = MODE_COUNT - 1; i >= 0; i--) { - listSupport = list_support[i].support; - if ((listSupport != NULL) && (listSupport->enabled) && (listSupport->itemGetPrefix != NULL)) { - char *prefix = listSupport->itemGetPrefix(listSupport); - snprintf(appsPath, sizeof(appsPath), "%sCFG%s%s.cfg", prefix, i == ETH_MODE ? "\\" : "/", name); - - fd = openFile(appsPath, O_RDONLY); - if (fd >= 0) { - appConfig = configAlloc(0, NULL, appsPath); - close(fd); - return appConfig; - } - } - } - - /* Apps config not found on any device, go with last tested device. - Does not matter if the config file could be loaded or not */ - appConfig = configAlloc(0, NULL, appsPath); - - return appConfig; -} - // ---------------------------------------------------------- // ----------------------- Updaters ------------------------- // ---------------------------------------------------------- @@ -771,47 +565,6 @@ void setErrorMessage(int strId) static int lscstatus = CONFIG_ALL; static int lscret = 0; -static int checkLoadConfigBDM(int types) -{ - char path[64]; - int value; - - // check USB - if (bdmFindPartition(path, "conf_opl.cfg", 0)) { - configEnd(); - configInit(path); - value = configReadMulti(types); - config_set_t *configOPL = configGetByType(CONFIG_OPL); - configSetInt(configOPL, CONFIG_OPL_BDM_MODE, START_MODE_AUTO); - return value; - } - - return 0; -} - -static int checkLoadConfigHDD(int types) -{ - int value; - char path[64]; - - hddLoadModules(); - hddLoadSupportModules(); - - snprintf(path, sizeof(path), "%sconf_opl.cfg", gHDDPrefix); - value = open(path, O_RDONLY); - if (value >= 0) { - close(value); - configEnd(); - configInit(gHDDPrefix); - value = configReadMulti(types); - config_set_t *configOPL = configGetByType(CONFIG_OPL); - configSetInt(configOPL, CONFIG_OPL_HDD_MODE, START_MODE_AUTO); - return value; - } - - return 0; -} - // When this function is called, the current device for loading/saving config is the memory card. static int tryAlternateDevice(int types) { @@ -823,29 +576,26 @@ static int tryAlternateDevice(int types) // First, try the device that OPL booted from. if (!strncmp(pwd, "mass", 4) && (pwd[4] == ':' || pwd[5] == ':')) { - if ((value = checkLoadConfigBDM(types)) != 0) + if ((value = configCheckBDM(types)) != 0) return value; } else if (!strncmp(pwd, "hdd", 3) && (pwd[3] == ':' || pwd[4] == ':')) { - if ((value = checkLoadConfigHDD(types)) != 0) + if ((value = configCheckHDD(types)) != 0) return value; } // Config was not found on the boot device. Check all supported devices. // Check USB device - if ((value = checkLoadConfigBDM(types)) != 0) + if ((value = configCheckBDM(types)) != 0) return value; // Check HDD - if ((value = checkLoadConfigHDD(types)) != 0) + if ((value = configCheckHDD(types)) != 0) return value; // At this point, the user has no loadable config files on any supported device, so try to find a device to save on. // We don't want to get users into alternate mode for their very first launch of OPL (i.e no config file at all, but still want to save on MC) // Check for a memory card inserted. - if (sysCheckMC() >= 0) { - configPrepareNotifications(gBaseMCDir); - showCfgPopup = 0; - return 0; - } + configCheckMC(types); + // No memory cards? Try a USB device... dir = opendir("mass0:"); if (dir != NULL) { @@ -989,37 +739,6 @@ static void _loadConfig() showCfgPopup = 1; } -static int trySaveConfigBDM(int types) -{ - char path[64]; - - // check USB - if (bdmFindPartition(path, "conf_opl.cfg", 1)) { - configSetMove(path); - return configWriteMulti(types); - } - - return -ENOENT; -} - -static int trySaveConfigHDD(int types) -{ - hddLoadModules(); - // Check that the formatted & usable HDD is connected. - if (hddCheck() == 0) { - configSetMove(gHDDPrefix); - return configWriteMulti(types); - } - - return -ENOENT; -} - -static int trySaveConfigMC(int types) -{ - configSetMove(NULL); - return configWriteMulti(types); -} - static int trySaveAlternateDevice(int types) { char pwd[8]; @@ -1029,24 +748,24 @@ static int trySaveAlternateDevice(int types) // First, try the device that OPL booted from. if (!strncmp(pwd, "mass", 4) && (pwd[4] == ':' || pwd[5] == ':')) { - if ((value = trySaveConfigBDM(types)) > 0) + if ((value = configCheckBDM(types)) > 0) return value; } else if (!strncmp(pwd, "hdd", 3) && (pwd[3] == ':' || pwd[4] == ':')) { - if ((value = trySaveConfigHDD(types)) > 0) + if ((value = configCheckHDD(types)) > 0) return value; } // Config was not saved to the boot device. Try all supported devices. // Try memory cards if (sysCheckMC() >= 0) { - if ((value = trySaveConfigMC(types)) > 0) + if ((value = configCheckMC(types)) > 0) return value; } // Try a USB device - if ((value = trySaveConfigBDM(types)) > 0) + if ((value = configCheckBDM(types)) > 0) return value; // Try the HDD - if ((value = trySaveConfigHDD(types)) > 0) + if ((value = configCheckHDD(types)) > 0) return value; // We tried everything, but... @@ -1135,7 +854,7 @@ static void _saveConfig() char *path = configGetDir(); if (!strncmp(path, "mc", 2)) { - checkMCFolder(); + sbCheckMCFolder(); configPrepareNotifications(gBaseMCDir); } @@ -1860,9 +1579,9 @@ static void miniInit(int mode) if (CONFIG_ALL & CONFIG_OPL) { if (!(ret & CONFIG_OPL)) { if (mode == BDM_MODE) - ret = checkLoadConfigBDM(CONFIG_ALL); + ret = configCheckBDM(CONFIG_ALL); else if (mode == HDD_MODE) - ret = checkLoadConfigHDD(CONFIG_ALL); + ret = configCheckHDD(CONFIG_ALL); } if (ret & CONFIG_OPL) { @@ -1914,6 +1633,8 @@ static void autoLaunchHDDGame(char *argv[]) hddLaunchGame(NULL, -1, configSet); } +static item_list_t *itemLaunchBDM; + static void autoLaunchBDMGame(char *argv[]) { char path[256]; @@ -1974,7 +1695,7 @@ static void autoLaunchBDMGame(char *argv[]) configSet = configAlloc(0, NULL, path); configRead(configSet); - bdmLaunchGame(NULL, -1, configSet); + itemLaunchBDM->itemLaunch(NULL, -1, configSet); } // --------------------- Main -------------------- diff --git a/src/sound.c b/src/sound.c index 24cdf2eea..7171bbbc8 100644 --- a/src/sound.c +++ b/src/sound.c @@ -37,7 +37,7 @@ static struct sfxEffect sfx_files[SFX_COUNT] = { }; static struct audsrv_adpcm_t sfx[SFX_COUNT]; -static int audio_initialized = 0; +int audio_initialized = 0; /*-- Theme Background Music ------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------*/ @@ -165,14 +165,8 @@ int sfxInit(int bootSnd) int thmSfxEnabled = 0; int i = 1; - if (!audio_initialized) { - LOG("SFX: %s: ERROR: not initialized!\n", __FUNCTION__); - return -1; - } - - audsrv_adpcm_init(); sfxInitDefaults(); - audioSetVolume(SFX_COUNT); + audioSetSfxVolume(SFX_COUNT); // Check default theme is not current theme int themeID = thmGetGuiValue(); diff --git a/src/submenu.c b/src/submenu.c index 0edd63990..edf47f674 100644 --- a/src/submenu.c +++ b/src/submenu.c @@ -6,6 +6,7 @@ */ #include "include/opl.h" +#include "submenu.h" #include "include/lang.h" #include "include/themes.h" diff --git a/src/supportbase.c b/src/supportbase.c index a31ad6f8f..9e5e3d2c4 100644 --- a/src/supportbase.c +++ b/src/supportbase.c @@ -1,4 +1,6 @@ #include "include/opl.h" +#include "include/hdd.h" +#include "include/supportbase.h" #include "include/util.h" #include "include/system.h" #include "include/ioman.h" @@ -6,7 +8,11 @@ #include "include/cheatman.h" #include "include/pggsm.h" #include "include/ps2cnf.h" +#include "include/submenu.h" +#include "include/menu.h" #include "include/gui.h" +#include "include/imports.h" + #define NEWLIB_PORT_AWARE #include // fileXioMount("iso:", ***), fileXioUmount("iso:") @@ -15,6 +21,8 @@ #include "../modules/isofs/zso.h" +base_game_info_t *gAutoLaunchBDMGame; + /// internal linked list used to populate the list from directory listing struct game_list_t { @@ -28,21 +36,129 @@ struct game_cache_list base_game_info_t *games; }; +static int mcID = -1; + +static int checkMC() +{ + int mc0_is_ps2card, mc1_is_ps2card; + int mc0_has_folder, mc1_has_folder; + + if (mcID == -1) { + mc0_is_ps2card = 0; + DIR *mc0_root_dir = opendir("mc0:/"); + if (mc0_root_dir != NULL) { + closedir(mc0_root_dir); + mc0_is_ps2card = 1; + } + + mc1_is_ps2card = 0; + DIR *mc1_root_dir = opendir("mc1:/"); + if (mc1_root_dir != NULL) { + closedir(mc1_root_dir); + mc1_is_ps2card = 1; + } + + mc0_has_folder = 0; + DIR *mc0_opl_dir = opendir("mc0:OPL/"); + if (mc0_opl_dir != NULL) { + closedir(mc0_opl_dir); + mc0_has_folder = 1; + } + + mc1_has_folder = 0; + DIR *mc1_opl_dir = opendir("mc1:OPL/"); + if (mc1_opl_dir != NULL) { + closedir(mc1_opl_dir); + mc1_has_folder = 1; + } + + if (mc0_has_folder) { + mcID = '0'; + return mcID; + } + + if (mc1_has_folder) { + mcID = '1'; + return mcID; + } + + if (mc0_is_ps2card) { + mcID = '0'; + return mcID; + } + + if (mc1_is_ps2card) { + mcID = '1'; + return mcID; + } + } + return mcID; +} + +int sbGetmcID(void) +{ + return mcID; +} + +void sbCheckMCFolder(void) +{ + char path[32]; + int fd; + + if (checkMC() < 0) { + return; + } + + snprintf(path, sizeof(path), "mc%d:OPL/", mcID & 1); + mkdir(path, 0777); + + snprintf(path, sizeof(path), "mc%d:OPL/opl.icn", mcID & 1); + fd = open(path, O_RDONLY); + if (fd < 0) { + fd = sbOpenFile(path, O_WRONLY | O_CREAT | O_TRUNC); + if (fd >= 0) { + write(fd, &icon_icn, size_icon_icn); + close(fd); + } + } else { + close(fd); + } + + snprintf(path, sizeof(path), "mc%d:OPL/icon.sys", mcID & 1); + fd = open(path, O_RDONLY); + if (fd < 0) { + fd = sbOpenFile(path, O_WRONLY | O_CREAT | O_TRUNC); + if (fd >= 0) { + write(fd, icon_sys, size_icon_sys); + close(fd); + } + } else { + close(fd); + } +} + int sbIsSameSize(const char *prefix, int prevSize) { int size = -1; char path[256]; snprintf(path, sizeof(path), "%sul.cfg", prefix); - int fd = openFile(path, O_RDONLY); + int fd = sbOpenFile(path, O_RDONLY); if (fd >= 0) { - size = getFileSize(fd); + size = sbGetFileSize(fd); close(fd); } return size == prevSize; } +int sbGetFileSize(int fd) +{ + int size = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + return size; +} + int sbCreateSemaphore(void) { ee_sema_t sema; @@ -391,13 +507,13 @@ int sbReadList(base_game_info_t **list, const char *prefix, int *fsize, int *gam // count and process games in ul.cfg snprintf(path, sizeof(path), "%sul.cfg", prefix); - fd = openFile(path, O_RDONLY); + fd = sbOpenFile(path, O_RDONLY); if (fd >= 0) { USBExtreme_game_entry_t GameEntry; if (count < 0) count = 0; - size = getFileSize(fd); + size = sbGetFileSize(fd); *fsize = size; count += size / sizeof(USBExtreme_game_entry_t); @@ -466,6 +582,27 @@ int sbReadList(base_game_info_t **list, const char *prefix, int *fsize, int *gam return count; } +int sbListDir(char *path, const char *separator, int maxElem, + int (*readEntry)(int index, const char *path, const char *separator, const char *name, unsigned char d_type)) +{ + int index = 0; + char filename[128]; + + if (sbCheckFile(path, O_RDONLY)) { + DIR *dir = opendir(path); + struct dirent *dirent; + if (dir != NULL) { + while (index < maxElem && (dirent = readdir(dir)) != NULL) { + snprintf(filename, 128, "%s/%s", path, dirent->d_name); + index = readEntry(index, path, separator, dirent->d_name, dirent->d_type); + } + + closedir(dir); + } + } + return index; +} + extern int probed_fd; extern u32 probed_lba; extern u8 IOBuffer[2048]; @@ -714,6 +851,80 @@ void sbCreatePath(const base_game_info_t *game, char *path, const char *prefix, sbCreatePath_name(game, path, prefix, sep, part, game->name); } +int sbCheckFile(char *path, int mode) +{ + // check if it is mc + if (strncmp(path, "mc", 2) == 0) { + + // if user didn't explicitly asked for a MC (using '?' char) + if (path[2] == 0x3F) { + + // Use default detected card + if (checkMC() >= 0) + path[2] = mcID; + else + return 0; + } + + // in create mode, we check that the directory exist, or create it + if (mode & O_CREAT) { + char dirPath[256]; + char *pos = strrchr(path, '/'); + if (pos) { + memcpy(dirPath, path, (pos - path)); + dirPath[(pos - path)] = '\0'; + DIR *dir = opendir(dirPath); + if (dir == NULL) { + int res = mkdir(dirPath, 0777); + if (res != 0) + return 0; + } else + closedir(dir); + } + } + } + return 1; +} + +int sbOpenFile(char *path, int mode) +{ + if (sbCheckFile(path, mode)) + return open(path, mode, 0666); + else + return -1; +} + +void *sbReadFile(char *path, int align, int *size) +{ + void *buffer = NULL; + + int fd = sbOpenFile(path, O_RDONLY); + if (fd >= 0) { + unsigned int realSize = sbGetFileSize(fd); + + if ((*size > 0) && (*size != realSize)) { + LOG("UTIL Invalid filesize, expected: %d, got: %d\n", *size, realSize); + close(fd); + return NULL; + } + + if (align > 0) + buffer = memalign(64, realSize); // The allocation is aligned to aid the DMA transfers + else + buffer = malloc(realSize); + + if (!buffer) { + LOG("UTIL ReadFile: Failed allocation of %d bytes", realSize); + *size = 0; + } else { + read(fd, buffer, realSize); + close(fd); + *size = realSize; + } + } + return buffer; +} + void sbDelete(base_game_info_t **list, const char *prefix, const char *sep, int gamecount, int id) { int part; @@ -830,3 +1041,265 @@ int sbLoadCheats(const char *path, const char *file) return cheatMode; } + +/* size will be the maximum line size possible */ +file_buffer_t *sbOpenFileBuffer(char *fpath, int mode, short allocResult, unsigned int size) +{ + file_buffer_t *fileBuffer = NULL; + unsigned char bom[3]; + + int fd = sbOpenFile(fpath, mode); + if (fd >= 0) { + fileBuffer = (file_buffer_t *)malloc(sizeof(file_buffer_t)); + fileBuffer->size = size; + fileBuffer->available = 0; + fileBuffer->buffer = (char *)malloc(size * sizeof(char)); + if (mode == O_RDONLY) { + fileBuffer->lastPtr = NULL; + + // Check for and skip the UTF-8 BOM sequence. + if ((read(fd, bom, sizeof(bom)) != 3) || + (bom[0] != 0xEF || bom[1] != 0xBB || bom[2] != 0xBF)) { + // Not BOM, so rewind. + lseek(fd, 0, SEEK_SET); + } + } else + fileBuffer->lastPtr = fileBuffer->buffer; + fileBuffer->allocResult = allocResult; + fileBuffer->fd = fd; + fileBuffer->mode = mode; + } + + return fileBuffer; +} + +/* size will be the maximum line size possible */ +file_buffer_t *sbOpenFileBufferBuffer(short allocResult, const void *buffer, unsigned int size) +{ + file_buffer_t *fileBuffer = NULL; + + fileBuffer = (file_buffer_t *)malloc(sizeof(file_buffer_t)); + fileBuffer->size = size; + fileBuffer->available = size; + fileBuffer->buffer = (char *)malloc((size + 1) * sizeof(char)); + fileBuffer->lastPtr = fileBuffer->buffer; // O_RDONLY, but with the data in the buffer. + fileBuffer->allocResult = allocResult; + fileBuffer->fd = -1; + fileBuffer->mode = O_RDONLY; + + memcpy(fileBuffer->buffer, buffer, size); + fileBuffer->buffer[size] = '\0'; + + return fileBuffer; +} + +int sbReadFileBuffer(file_buffer_t *fileBuffer, char **outBuf) +{ + int lineSize = 0, readSize, length; + char *posLF = NULL; + + while (1) { + // if lastPtr is set, then we continue the read from this point as reference + if (fileBuffer->lastPtr) { + // Calculate the remaining chars to the right of lastPtr + lineSize = fileBuffer->available - (fileBuffer->lastPtr - fileBuffer->buffer); + /* LOG("##### Continue read, position: %X (total: %d) line size (\\0 not inc.): %d end: %x\n", + fileBuffer->lastPtr - fileBuffer->buffer, fileBuffer->available, lineSize, fileBuffer->lastPtr[lineSize]); */ + posLF = strchr(fileBuffer->lastPtr, '\n'); + } + + if (!posLF) { // We can come here either when the buffer is empty, or if the remaining chars don't have a LF + + // if available, we shift the remaining chars to the left ... + if (lineSize) { + // LOG("##### LF not found, Shift %d characters from end to beginning\n", lineSize); + memmove(fileBuffer->buffer, fileBuffer->lastPtr, lineSize); + } + + // ... and complete the buffer if we're not at EOF + if (fileBuffer->fd >= 0) { + + // Load as many characters necessary to fill the buffer + length = fileBuffer->size - lineSize - 1; + // LOG("##### Asking for %d characters to complete buffer\n", length); + readSize = read(fileBuffer->fd, fileBuffer->buffer + lineSize, length); + fileBuffer->buffer[lineSize + readSize] = '\0'; + + // Search again (from the lastly added chars only), the result will be "analyzed" in next if + posLF = strchr(fileBuffer->buffer + lineSize, '\n'); + + // Now update read context info + lineSize = lineSize + readSize; + // LOG("##### %d characters really read, line size now (\\0 not inc.): %d\n", read, lineSize); + + // If buffer not full it means we are at EOF + if (fileBuffer->size != lineSize + 1) { + // LOG("##### Reached EOF\n"); + close(fileBuffer->fd); + fileBuffer->fd = -1; + } + } + + fileBuffer->lastPtr = fileBuffer->buffer; + fileBuffer->available = lineSize; + } + + if (posLF) + lineSize = posLF - fileBuffer->lastPtr; + + // Check the previous char (on Windows there are CR/LF instead of single linux LF) + if (lineSize) + if (*(fileBuffer->lastPtr + lineSize - 1) == '\r') + lineSize--; + + fileBuffer->lastPtr[lineSize] = '\0'; + *outBuf = fileBuffer->lastPtr; + + // LOG("##### Result line is \"%s\" size: %d avail: %d pos: %d\n", fileBuffer->lastPtr, lineSize, fileBuffer->available, fileBuffer->lastPtr - fileBuffer->buffer); + + // If we are at EOF and no more chars available to scan, then we are finished + if (!lineSize && !fileBuffer->available && fileBuffer->fd == -1) + return 0; + + if (fileBuffer->lastPtr[0] == '#') { // '#' for comment lines + if (posLF) + fileBuffer->lastPtr = posLF + 1; + else + fileBuffer->lastPtr = NULL; + continue; + } + + if (lineSize && fileBuffer->allocResult) { + *outBuf = (char *)malloc((lineSize + 1) * sizeof(char)); + memcpy(*outBuf, fileBuffer->lastPtr, lineSize + 1); + } + + // Either move the pointer to next chars, or set it to null to force a whole buffer read (if possible) + if (posLF) + fileBuffer->lastPtr = posLF + 1; + else { + fileBuffer->lastPtr = NULL; + } + + return 1; + } +} + +void sbWriteFileBuffer(file_buffer_t *fileBuffer, char *inBuf, int size) +{ + LOG("writeFileBuffer avail: %d size: %d\n", fileBuffer->available, size); + if (fileBuffer->available && fileBuffer->available + size > fileBuffer->size) { + LOG("writeFileBuffer flushing: %d\n", fileBuffer->available); + write(fileBuffer->fd, fileBuffer->buffer, fileBuffer->available); + fileBuffer->lastPtr = fileBuffer->buffer; + fileBuffer->available = 0; + } + + if (size > fileBuffer->size) { + LOG("writeFileBuffer direct write: %d\n", size); + write(fileBuffer->fd, inBuf, size); + } else { + memcpy(fileBuffer->lastPtr, inBuf, size); + fileBuffer->lastPtr += size; + fileBuffer->available += size; + + LOG("writeFileBuffer lastPrt: %d\n", (fileBuffer->lastPtr - fileBuffer->buffer)); + } +} + +void sbCloseFileBuffer(file_buffer_t *fileBuffer) +{ + if (fileBuffer->fd >= 0) { + if (fileBuffer->mode != O_RDONLY && fileBuffer->available) { + // LOG("writeFileBuffer final write: %d\n", fileBuffer->available); + write(fileBuffer->fd, fileBuffer->buffer, fileBuffer->available); + } + close(fileBuffer->fd); + } + free(fileBuffer->buffer); + free(fileBuffer); +} + +struct DirentToDelete +{ + struct DirentToDelete *next; + char *filename; +}; + +int sbDeleteFolder(const char *folder) +{ + int result; + char *path; + struct dirent *dirent; + DIR *dir; + struct DirentToDelete *head, *start; + + result = 0; + start = head = NULL; + if ((dir = opendir(folder)) != NULL) { + /* Generate a list of files in the directory. */ + while ((dirent = readdir(dir)) != NULL) { + if ((strcmp(dirent->d_name, ".") == 0) || ((strcmp(dirent->d_name, "..") == 0))) + continue; + + path = malloc(strlen(folder) + strlen(dirent->d_name) + 2); + sprintf(path, "%s/%s", folder, dirent->d_name); + + if (dirent->d_type == DT_DIR) { + /* Recursive, delete all subfolders */ + result = sbDeleteFolder(path); + free(path); + } else { + free(path); + if (start == NULL) { + head = malloc(sizeof(struct DirentToDelete)); + if (head == NULL) + break; + start = head; + } else { + if ((head->next = malloc(sizeof(struct DirentToDelete))) == NULL) + break; + + head = head->next; + } + + head->next = NULL; + + if ((head->filename = malloc(strlen(dirent->d_name) + 1)) != NULL) + strcpy(head->filename, dirent->d_name); + else + break; + } + } + + closedir(dir); + } else + result = 0; + + if (result >= 0) { + /* Delete the files. */ + for (head = start; head != NULL; head = start) { + if (head->filename != NULL) { + if ((path = malloc(strlen(folder) + strlen(head->filename) + 2)) != NULL) { + sprintf(path, "%s/%s", folder, head->filename); + result = unlink(path); + if (result < 0) + LOG("sysDeleteFolder: failed to remove %s: %d\n", path, result); + + free(path); + } + free(head->filename); + } + + start = head->next; + free(head); + } + + if (result >= 0) { + result = rmdir(folder); + LOG("sysDeleteFolder: failed to rmdir %s: %d\n", folder, result); + } + } + + return result; +} \ No newline at end of file diff --git a/src/system.c b/src/system.c index fb945e7b7..2332b29b2 100644 --- a/src/system.c +++ b/src/system.c @@ -9,7 +9,11 @@ #endif #include "include/opl.h" +#include "include/submenu.h" +#include "include/menu.h" #include "include/gui.h" +#include "include/supportbase.h" +#include "include/bdmsupport.h" #include "include/ethsupport.h" #include "include/util.h" #include "include/pad.h" @@ -37,7 +41,7 @@ #include #include #include - +#include typedef struct { diff --git a/src/texcache.c b/src/texcache.c index 2fa32db46..fe3ea7da8 100644 --- a/src/texcache.c +++ b/src/texcache.c @@ -1,6 +1,8 @@ #include "include/opl.h" #include "include/texcache.h" #include "include/textures.h" +#include "include/submenu.h" +#include "include/menu.h" #include "include/ioman.h" #include "include/gui.h" #include "include/renderman.h" diff --git a/src/themes.c b/src/themes.c index 07494da06..425b694af 100644 --- a/src/themes.c +++ b/src/themes.c @@ -1,6 +1,6 @@ #include "include/opl.h" #include "include/themes.h" -#include "include/util.h" +#include "include/supportbase.h" #include "include/gui.h" #include "include/renderman.h" #include "include/ioman.h" @@ -1406,7 +1406,7 @@ int thmAddElements(char *path, const char *separator, int forceRefresh) { int result, i; - result = listDir(path, separator, THM_MAX_FILES - nThemes, &thmReadEntry); + result = sbListDir(path, separator, THM_MAX_FILES - nThemes, &thmReadEntry); nThemes += result; thmRebuildGuiNames(); diff --git a/src/util.c b/src/util.c index f23a5f271..471bcbb8d 100644 --- a/src/util.c +++ b/src/util.c @@ -8,12 +8,7 @@ #include "include/util.h" #include "include/ioman.h" #include "include/system.h" -#include -#include -#include -#include #include -#include "include/imports.h" #include "include/hdd.h" #include "../modules/isofs/zso.h" @@ -21,388 +16,10 @@ extern int probed_fd; extern u32 probed_lba; -static int mcID = -1; void guiWarning(const char *text, int count); -int getmcID(void) -{ - return mcID; -} - -int getFileSize(int fd) -{ - int size = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); - return size; -} - -static int checkMC() -{ - int mc0_is_ps2card, mc1_is_ps2card; - int mc0_has_folder, mc1_has_folder; - - if (mcID == -1) { - mc0_is_ps2card = 0; - DIR *mc0_root_dir = opendir("mc0:/"); - if (mc0_root_dir != NULL) { - closedir(mc0_root_dir); - mc0_is_ps2card = 1; - } - - mc1_is_ps2card = 0; - DIR *mc1_root_dir = opendir("mc1:/"); - if (mc1_root_dir != NULL) { - closedir(mc1_root_dir); - mc1_is_ps2card = 1; - } - - mc0_has_folder = 0; - DIR *mc0_opl_dir = opendir("mc0:OPL/"); - if (mc0_opl_dir != NULL) { - closedir(mc0_opl_dir); - mc0_has_folder = 1; - } - - mc1_has_folder = 0; - DIR *mc1_opl_dir = opendir("mc1:OPL/"); - if (mc1_opl_dir != NULL) { - closedir(mc1_opl_dir); - mc1_has_folder = 1; - } - - if (mc0_has_folder) { - mcID = '0'; - return mcID; - } - - if (mc1_has_folder) { - mcID = '1'; - return mcID; - } - - if (mc0_is_ps2card) { - mcID = '0'; - return mcID; - } - - if (mc1_is_ps2card) { - mcID = '1'; - return mcID; - } - } - return mcID; -} - -void checkMCFolder(void) -{ - char path[32]; - int fd; - - if (checkMC() < 0) { - return; - } - - snprintf(path, sizeof(path), "mc%d:OPL/", mcID & 1); - mkdir(path, 0777); - - snprintf(path, sizeof(path), "mc%d:OPL/opl.icn", mcID & 1); - fd = open(path, O_RDONLY); - if (fd < 0) { - fd = openFile(path, O_WRONLY | O_CREAT | O_TRUNC); - if (fd >= 0) { - write(fd, &icon_icn, size_icon_icn); - close(fd); - } - } else { - close(fd); - } - - snprintf(path, sizeof(path), "mc%d:OPL/icon.sys", mcID & 1); - fd = open(path, O_RDONLY); - if (fd < 0) { - fd = openFile(path, O_WRONLY | O_CREAT | O_TRUNC); - if (fd >= 0) { - write(fd, &icon_sys, size_icon_sys); - close(fd); - } - } else { - close(fd); - } -} - -static int checkFile(char *path, int mode) -{ - // check if it is mc - if (strncmp(path, "mc", 2) == 0) { - - // if user didn't explicitly asked for a MC (using '?' char) - if (path[2] == 0x3F) { - - // Use default detected card - if (checkMC() >= 0) - path[2] = mcID; - else - return 0; - } - - // in create mode, we check that the directory exist, or create it - if (mode & O_CREAT) { - char dirPath[256]; - char *pos = strrchr(path, '/'); - if (pos) { - memcpy(dirPath, path, (pos - path)); - dirPath[(pos - path)] = '\0'; - DIR *dir = opendir(dirPath); - if (dir == NULL) { - int res = mkdir(dirPath, 0777); - if (res != 0) - return 0; - } else - closedir(dir); - } - } - } - return 1; -} - -int openFile(char *path, int mode) -{ - if (checkFile(path, mode)) - return open(path, mode, 0666); - else - return -1; -} - -void *readFile(char *path, int align, int *size) -{ - void *buffer = NULL; - - int fd = openFile(path, O_RDONLY); - if (fd >= 0) { - unsigned int realSize = getFileSize(fd); - - if ((*size > 0) && (*size != realSize)) { - LOG("UTIL Invalid filesize, expected: %d, got: %d\n", *size, realSize); - close(fd); - return NULL; - } - - if (align > 0) - buffer = memalign(64, realSize); // The allocation is aligned to aid the DMA transfers - else - buffer = malloc(realSize); - - if (!buffer) { - LOG("UTIL ReadFile: Failed allocation of %d bytes", realSize); - *size = 0; - } else { - read(fd, buffer, realSize); - close(fd); - *size = realSize; - } - } - return buffer; -} - -int listDir(char *path, const char *separator, int maxElem, - int (*readEntry)(int index, const char *path, const char *separator, const char *name, unsigned char d_type)) -{ - int index = 0; - char filename[128]; - - if (checkFile(path, O_RDONLY)) { - DIR *dir = opendir(path); - struct dirent *dirent; - if (dir != NULL) { - while (index < maxElem && (dirent = readdir(dir)) != NULL) { - snprintf(filename, 128, "%s/%s", path, dirent->d_name); - index = readEntry(index, path, separator, dirent->d_name, dirent->d_type); - } - - closedir(dir); - } - } - return index; -} - -/* size will be the maximum line size possible */ -file_buffer_t *openFileBuffer(char *fpath, int mode, short allocResult, unsigned int size) -{ - file_buffer_t *fileBuffer = NULL; - unsigned char bom[3]; - - int fd = openFile(fpath, mode); - if (fd >= 0) { - fileBuffer = (file_buffer_t *)malloc(sizeof(file_buffer_t)); - fileBuffer->size = size; - fileBuffer->available = 0; - fileBuffer->buffer = (char *)malloc(size * sizeof(char)); - if (mode == O_RDONLY) { - fileBuffer->lastPtr = NULL; - // Check for and skip the UTF-8 BOM sequence. - if ((read(fd, bom, sizeof(bom)) != 3) || - (bom[0] != 0xEF || bom[1] != 0xBB || bom[2] != 0xBF)) { - // Not BOM, so rewind. - lseek(fd, 0, SEEK_SET); - } - } else - fileBuffer->lastPtr = fileBuffer->buffer; - fileBuffer->allocResult = allocResult; - fileBuffer->fd = fd; - fileBuffer->mode = mode; - } - - return fileBuffer; -} - -/* size will be the maximum line size possible */ -file_buffer_t *openFileBufferBuffer(short allocResult, const void *buffer, unsigned int size) -{ - file_buffer_t *fileBuffer = NULL; - - fileBuffer = (file_buffer_t *)malloc(sizeof(file_buffer_t)); - fileBuffer->size = size; - fileBuffer->available = size; - fileBuffer->buffer = (char *)malloc((size + 1) * sizeof(char)); - fileBuffer->lastPtr = fileBuffer->buffer; // O_RDONLY, but with the data in the buffer. - fileBuffer->allocResult = allocResult; - fileBuffer->fd = -1; - fileBuffer->mode = O_RDONLY; - - memcpy(fileBuffer->buffer, buffer, size); - fileBuffer->buffer[size] = '\0'; - - return fileBuffer; -} - -int readFileBuffer(file_buffer_t *fileBuffer, char **outBuf) -{ - int lineSize = 0, readSize, length; - char *posLF = NULL; - - while (1) { - // if lastPtr is set, then we continue the read from this point as reference - if (fileBuffer->lastPtr) { - // Calculate the remaining chars to the right of lastPtr - lineSize = fileBuffer->available - (fileBuffer->lastPtr - fileBuffer->buffer); - /* LOG("##### Continue read, position: %X (total: %d) line size (\\0 not inc.): %d end: %x\n", - fileBuffer->lastPtr - fileBuffer->buffer, fileBuffer->available, lineSize, fileBuffer->lastPtr[lineSize]); */ - posLF = strchr(fileBuffer->lastPtr, '\n'); - } - - if (!posLF) { // We can come here either when the buffer is empty, or if the remaining chars don't have a LF - - // if available, we shift the remaining chars to the left ... - if (lineSize) { - // LOG("##### LF not found, Shift %d characters from end to beginning\n", lineSize); - memmove(fileBuffer->buffer, fileBuffer->lastPtr, lineSize); - } - - // ... and complete the buffer if we're not at EOF - if (fileBuffer->fd >= 0) { - - // Load as many characters necessary to fill the buffer - length = fileBuffer->size - lineSize - 1; - // LOG("##### Asking for %d characters to complete buffer\n", length); - readSize = read(fileBuffer->fd, fileBuffer->buffer + lineSize, length); - fileBuffer->buffer[lineSize + readSize] = '\0'; - - // Search again (from the lastly added chars only), the result will be "analyzed" in next if - posLF = strchr(fileBuffer->buffer + lineSize, '\n'); - - // Now update read context info - lineSize = lineSize + readSize; - // LOG("##### %d characters really read, line size now (\\0 not inc.): %d\n", read, lineSize); - - // If buffer not full it means we are at EOF - if (fileBuffer->size != lineSize + 1) { - // LOG("##### Reached EOF\n"); - close(fileBuffer->fd); - fileBuffer->fd = -1; - } - } - - fileBuffer->lastPtr = fileBuffer->buffer; - fileBuffer->available = lineSize; - } - - if (posLF) - lineSize = posLF - fileBuffer->lastPtr; - - // Check the previous char (on Windows there are CR/LF instead of single linux LF) - if (lineSize) - if (*(fileBuffer->lastPtr + lineSize - 1) == '\r') - lineSize--; - - fileBuffer->lastPtr[lineSize] = '\0'; - *outBuf = fileBuffer->lastPtr; - - // LOG("##### Result line is \"%s\" size: %d avail: %d pos: %d\n", fileBuffer->lastPtr, lineSize, fileBuffer->available, fileBuffer->lastPtr - fileBuffer->buffer); - - // If we are at EOF and no more chars available to scan, then we are finished - if (!lineSize && !fileBuffer->available && fileBuffer->fd == -1) - return 0; - - if (fileBuffer->lastPtr[0] == '#') { // '#' for comment lines - if (posLF) - fileBuffer->lastPtr = posLF + 1; - else - fileBuffer->lastPtr = NULL; - continue; - } - - if (lineSize && fileBuffer->allocResult) { - *outBuf = (char *)malloc((lineSize + 1) * sizeof(char)); - memcpy(*outBuf, fileBuffer->lastPtr, lineSize + 1); - } - - // Either move the pointer to next chars, or set it to null to force a whole buffer read (if possible) - if (posLF) - fileBuffer->lastPtr = posLF + 1; - else { - fileBuffer->lastPtr = NULL; - } - - return 1; - } -} - -void writeFileBuffer(file_buffer_t *fileBuffer, char *inBuf, int size) -{ - // LOG("writeFileBuffer avail: %d size: %d\n", fileBuffer->available, size); - if (fileBuffer->available && fileBuffer->available + size > fileBuffer->size) { - // LOG("writeFileBuffer flushing: %d\n", fileBuffer->available); - write(fileBuffer->fd, fileBuffer->buffer, fileBuffer->available); - fileBuffer->lastPtr = fileBuffer->buffer; - fileBuffer->available = 0; - } - - if (size > fileBuffer->size) { - // LOG("writeFileBuffer direct write: %d\n", size); - write(fileBuffer->fd, inBuf, size); - } else { - memcpy(fileBuffer->lastPtr, inBuf, size); - fileBuffer->lastPtr += size; - fileBuffer->available += size; - - // LOG("writeFileBuffer lastPrt: %d\n", (fileBuffer->lastPtr - fileBuffer->buffer)); - } -} - -void closeFileBuffer(file_buffer_t *fileBuffer) -{ - if (fileBuffer->fd >= 0) { - if (fileBuffer->mode != O_RDONLY && fileBuffer->available) { - // LOG("writeFileBuffer final write: %d\n", fileBuffer->available); - write(fileBuffer->fd, fileBuffer->buffer, fileBuffer->available); - } - close(fileBuffer->fd); - } - free(fileBuffer->buffer); - free(fileBuffer); -} // a simple maximum of two int max(int a, int b) @@ -494,19 +111,6 @@ int GetSystemRegion(void) return ConsoleRegion; } -void logfile(char *text) -{ - int fd = open("mass:/opl_log.txt", O_APPEND | O_CREAT | O_WRONLY); - write(fd, text, strlen(text)); - close(fd); -} - -void logbuffer(char *path, void *buf, size_t size) -{ - int fd = open(path, O_CREAT | O_TRUNC | O_WRONLY); - write(fd, buf, size); - close(fd); -} int CheckPS2Logo(int fd, u32 lba) { @@ -573,89 +177,6 @@ int CheckPS2Logo(int fd, u32 lba) return ValidPS2Logo; } -struct DirentToDelete -{ - struct DirentToDelete *next; - char *filename; -}; - -int sysDeleteFolder(const char *folder) -{ - int result; - char *path; - struct dirent *dirent; - DIR *dir; - struct DirentToDelete *head, *start; - - result = 0; - start = head = NULL; - if ((dir = opendir(folder)) != NULL) { - /* Generate a list of files in the directory. */ - while ((dirent = readdir(dir)) != NULL) { - if ((strcmp(dirent->d_name, ".") == 0) || ((strcmp(dirent->d_name, "..") == 0))) - continue; - - path = malloc(strlen(folder) + strlen(dirent->d_name) + 2); - sprintf(path, "%s/%s", folder, dirent->d_name); - - if (dirent->d_type == DT_DIR) { - /* Recursive, delete all subfolders */ - result = sysDeleteFolder(path); - free(path); - } else { - free(path); - if (start == NULL) { - head = malloc(sizeof(struct DirentToDelete)); - if (head == NULL) - break; - start = head; - } else { - if ((head->next = malloc(sizeof(struct DirentToDelete))) == NULL) - break; - - head = head->next; - } - - head->next = NULL; - - if ((head->filename = malloc(strlen(dirent->d_name) + 1)) != NULL) - strcpy(head->filename, dirent->d_name); - else - break; - } - } - - closedir(dir); - } else - result = 0; - - if (result >= 0) { - /* Delete the files. */ - for (head = start; head != NULL; head = start) { - if (head->filename != NULL) { - if ((path = malloc(strlen(folder) + strlen(head->filename) + 2)) != NULL) { - sprintf(path, "%s/%s", folder, head->filename); - result = unlink(path); - if (result < 0) - LOG("sysDeleteFolder: failed to remove %s: %d\n", path, result); - - free(path); - } - free(head->filename); - } - - start = head->next; - free(head); - } - - if (result >= 0) { - result = rmdir(folder); - LOG("sysDeleteFolder: failed to rmdir %s: %d\n", folder, result); - } - } - - return result; -} /*----------------------------------------------------------------------------------------*/ /* NOP delay. */ @@ -669,4 +190,4 @@ void delay(int count) while (ret--) asm("nop\nnop\nnop\nnop"); } -} +} \ No newline at end of file