diff --git a/source/arm11/acf.c b/source/arm11/acf.c index 9010652..770e709 100644 --- a/source/arm11/acf.c +++ b/source/arm11/acf.c @@ -9,6 +9,8 @@ #include "arm11/console.h" #include "fs.h" +extern Result fReadSize( FHandle file, void *buff, unsigned size, unsigned *readout ); + typedef struct { uint16_t start; @@ -109,16 +111,13 @@ acf_error_t acf_initialize(acf_text_t acfile) return ACFONT_MEM_EMPTY; } - int fill = 0; - do{ - Result res; - if( RES_OK != (res=fRead(font, fragments+fill, memfrag-fill < 256 ? memfrag-fill : 256, &readed)) ){ - free( fragments ); - fClose( font ); - return ACFONT_INVALID; - } - fill += readed; - } while( fill < memfrag ); + if( RES_OK != fReadSize(font, fragments, memfrag, &readed) + || readed != memfrag ) + { + free( fragments ); + fClose( font ); + return ACFONT_INVALID; + } // save filename for `fopen` int len = strlen(acfile); diff --git a/source/arm11/acl.c b/source/arm11/acl.c index a85a0a2..1c91f2b 100644 --- a/source/arm11/acl.c +++ b/source/arm11/acl.c @@ -1,6 +1,8 @@ #include "arm11/acl.h" #include "fs.h" +extern Result fReadSize( FHandle file, void *buff, unsigned size, unsigned *readout ); + typedef struct { uint32_t typeloc; @@ -129,7 +131,7 @@ static int32_t bin_search( acl_text_t game ) } uint32_t readed; - if( RES_OK != fRead(gblcht.fd, serials, size, &readed) + if( RES_OK != fReadSize(gblcht.fd, serials, size, &readed) || readed != size ) { free( serials ); @@ -278,7 +280,7 @@ static acl_error_t init_cheatset( uint32_t offset ) char *table = (char*)malloc( size ); if( !table ) return ACHTLIB_NOMEM; - if( RES_OK != fRead(gblcht.fd, table, size, &readed) // TODO: 多次read + if( RES_OK != fReadSize(gblcht.fd, table, size, &readed) || readed != size ) { free( table ); @@ -308,7 +310,7 @@ static acl_error_t load_data() return ACHTLIB_INVALID; uint32_t readed; - if( RES_OK != fRead(gblcht.fd, d, total, &readed) + if( RES_OK != fReadSize(gblcht.fd, d, total, &readed) || readed != total ) { free( d ); diff --git a/source/arm11/filebrowser.c b/source/arm11/filebrowser.c index 2008490..40229f2 100644 --- a/source/arm11/filebrowser.c +++ b/source/arm11/filebrowser.c @@ -28,6 +28,7 @@ #include "drivers/gfx.h" #include "arm11/acf.h" #include "arm11/atp.h" +#include "arm11/acl.h" #define screenClean() memset(consoleGet()->frameBuffer, 0, CWIDTH*CHEIGHT*sizeof(uint16_t)) @@ -140,6 +141,31 @@ scanEnd: return received > MAX_DIR_ENTRIES ? RES_OUT_OF_RANGE : res; } +static Result rom_get_serial( const char *file, const char serial[5] ) +{ + FHandle f; + Result res; + u32 readed; + serial[0] = serial[4] = '\0'; + if( RES_OK != (res=fOpen(&f, file, FA_OPEN_EXISTING | FA_READ)) ) + { + return res; + } + if( RES_OK != (res=fLseek(f, 0xac)) ) + { + fClose( f ); + return res; + } + if( RES_OK != (res=fRead(f, serial, 4, &readed)) + || readed != 4 ) + { + fClose(f); + return res; + } + fClose(f); + return RES_OK; +} + static atp_text_t folder_help[] = { "操 作 说 明", "~ ~ ~ ~ ~ ~ ~", @@ -175,7 +201,10 @@ static atp_error_t display_folder( atp_callerdata_t data, atp_counter_t index, a return ATP_SUCCESS; \ } -DECLARE_ERROR_PAGE( display_nocheat, "金手指功能还在制作中……" ) +DECLARE_ERROR_PAGE( display_openlib, "打开金手指文件出错" ) +DECLARE_ERROR_PAGE( display_selcht, "查找金手指配置出错" ) +DECLARE_ERROR_PAGE( display_noserial, "提取游戏识别码失败" ) +DECLARE_ERROR_PAGE( display_nocheat, "找不到对应的金手指配置" ) DECLARE_ERROR_PAGE( display_empty, "没有合适的文件" ) DECLARE_ERROR_PAGE( display_toolong, "路径过长,改名或移动文件后再试" ) DECLARE_ERROR_PAGE( display_pathfull, "游戏或目录过量,最多显示999个" ) @@ -198,25 +227,79 @@ atp_error_t help_page( atp_text_t *wording, atp_counter_t length ) return res; } +atp_error_t select_region( atp_callerdata_t dummy, atp_counter_t index, atp_itemcfg_t *config ) +{ + acl_chtid_t sid; + acl_region_t sreg; + acl_query_cheat_set(index, &sid, &sreg); + switch( sreg ) + { + case 'J': config->text = "日文版"; break; + case 'E': config->text = "英文版"; break; + case 'F': config->text = "法语版"; break; + case 'S': config->text = "西班牙语"; break; + case 'I': config->text = "意大利语"; break; + case 'D': config->text = "德语版"; break; + default: config->text = "其他语种"; break; + } + config->value = sid; + return ATP_SUCCESS; +} + extern atp_error_t oaf_config_page(); -static atp_pageopt_t serve_on_key( atp_callerdata_t data, atp_counter_t, atp_boolean_t x, atp_boolean_t y, atp_boolean_t l, atp_boolean_t r, atp_boolean_t start, atp_boolean_t select ) +#define WAIT_ON_ACT( act ) ( ATP_POWER_OFF == (act) ) ? ATP_POWER_OFF : ATP_PAGE_REFRESH +#define WAIT_ON_ERRPAGE( page ) WAIT_ON_ACT( atp_show(1, (page), NULL) ) + +static atp_pageopt_t serve_on_key( atp_callerdata_t data, atp_counter_t index, atp_boolean_t x, atp_boolean_t y, atp_boolean_t l, atp_boolean_t r, atp_boolean_t start, atp_boolean_t select ) { if( start ) { atp_tips( "", NULL ); - return ATP_POWER_OFF == help_page( folder_help, sizeof(folder_help)/sizeof(atp_text_t) ) - ? ATP_POWER_OFF : ATP_PAGE_REFRESH; + return WAIT_ON_ACT( help_page( folder_help, sizeof(folder_help)/sizeof(atp_text_t) ) ); } else if( select ) { - return ATP_POWER_OFF == oaf_config_page() ? ATP_POWER_OFF : ATP_PAGE_REFRESH; + return WAIT_ON_ACT( oaf_config_page() ); } else if( x ) { - atp_tips( "", NULL ); - return ATP_POWER_OFF == atp_show(1, display_nocheat, NULL) - ? ATP_POWER_OFF : ATP_PAGE_REFRESH; + DirList const *dList = (DirList*)data; + const char *file = &dList->ptrs[index][1]; + + // 确定game serial + char serial[5]; + if( RES_OK != rom_get_serial(file, serial) ) + { + return WAIT_ON_ERRPAGE( display_noserial ); + } + serial[4] = '\0'; + + acl_count_t len; + if( RES_OK != acl_open_lib( file ) ) + { + return WAIT_ON_ERRPAGE( display_openlib ); + } + if( RES_OK != acl_select_game( serial, 0, &len ) ) + { + acl_close_lib(); + return WAIT_ON_ERRPAGE( display_selcht ); + } + if( len == 0 ) + { + atp_tips( "", NULL ); + acl_close_lib(); + return WAIT_ON_ERRPAGE( display_nocheat ); + } + + // 显示配置页面 + atp_error_t res; + atp_itemval_t item; + atp_tips(NULL, "按B返回"); + res = atp_select("选择一个金手指配置", len, select_region, NULL, NULL, 0, 0, &item ); + + acl_close_lib(); + return ATP_PAGE_REFRESH; } return ATP_PAGE_NOOPTION; } diff --git a/source/arm11/main.c b/source/arm11/main.c index 70a4fe7..f43447a 100644 --- a/source/arm11/main.c +++ b/source/arm11/main.c @@ -47,6 +47,23 @@ static void setBacklight(void) else GFX_setBrightness(backlight, backlight); } +Result fReadSize( FHandle file, void *buff, unsigned size, unsigned *readout ) +{ + unsigned fill = 0; + unsigned readed; + do{ + Result res; + if( RES_OK != (res=fRead(file, buff+fill, size-fill < 256 ? size-fill : 256, &readed)) ){ + *readout = fill; + return res; + } + fill += readed; + } while( fill < size ); + + *readout = fill; + return RES_OK; +} + int main(void) { Result res = fMount(FS_DRIVE_SDMC);