#include #include #include "types.h" #include "arm11/pages.h" #include "arm11/drivers/mcu.h" atp_error_t disp_str( atp_callerdata_t data, atp_counter_t, atp_linecfg_t *cfg ) { cfg->text = (atp_text_t)data; cfg->text_color = ATP_COLOR_RED; return ATP_SUCCESS; } /// @brief base process for helping page /// @param table /// @param index /// @param config /// @return static atp_error_t display_help( atp_callerdata_t table, atp_counter_t index, atp_linecfg_t *config ) { atp_text_t *list = (atp_text_t*)table; config->text_align = ATP_PLACEMENT_CENTER; config->text_color = index == 0 ? ATP_COLOR_MAGENTA : ATP_COLOR_LIGHT; config->text = list[index]; return ATP_SUCCESS; } /// @brief display a static page for help /// @param wording static string array /// @param length the size of array /// @return atp_error_t help_page( atp_text_t *wording, atp_counter_t length ) { atp_text_t current; atp_tips( "返回:按A/B", ¤t ); atp_error_t res = atp_show( length, display_help, (atp_callerdata_t)wording ); atp_tips( current, NULL ); return res; } // -------------------------- // code for oaf config page // -------------------------- atp_text_t config_help[] = { "全局参数编辑操作指引", "~ ~ ~ ~ ~ ~ ~", "-修改后的全局参数保存在config.ini ", "保存修改时,存档方案的修改不会保存", "-金手指组合键为下方向+L+R+SELECT", " 也可以使用HOME键直接代替组合键 ", "~ ~ ~ ~ ~ ~ ~", "上下方向键      切换参数项目", "左右方向键          翻页", "L键和R键      调整当前参数", "A键         应用修改退出", "B键         放弃修改退出", "X键       应用修改保存退出", // X做保存,选中后走A键流程 }; atp_text_t CONFIG_OUTPUT = "[general]\n" \ "backlight=%d\n" \ "directBoot=%s\n" \ "useGbaDb=%s\n\n" \ "[video]\n" \ "scaler=%d\n" \ "gbaGamma=%1.2f\n" \ "lcdGamma=%1.2f\n" \ "contrast=%1.2f\n" \ "brightness=%1.2f\n\n" \ "[advanced]\n" \ "saveOverride=false\n" \ "defaultSave=%d\n\n" \ "[boost]\n" \ "cheatMode=%d\n"; typedef struct global_oaf_config OafConfig; static char page_strbuf[512]; #define LIGHT_MIN (MCU_getSystemModel() > 3 ? 50 : 20) #define LIGHT_MAX (MCU_getSystemModel() > 3 ? 800 : 500) #define SCALER_SIZE 4 static atp_error_t config_item( atp_callerdata_t gblcfg, atp_counter_t index, atp_itemcfg_t *cfg ) { //static char buf[16]; OafConfig *g_oafConfig = (OafConfig*)gblcfg; const char *scaler_val[] = {"上屏无缩放", "上屏GPU放大", "上屏DMA放大", "下屏无缩放"}; const char *savetype_name[] = {"和卡带序列号一致", "读取ROM的特定标记", "汉化带SRAM补丁", "自行决定"}; const char *cheatmode_name[] = {"关闭金手指", "全程激活", "组合键单次激活", "组合键激活/关闭"}; cfg->extra_text_color = ATP_COLOR_GREEN; if( index == 0 ) { ee_snprintf(page_strbuf, sizeof(page_strbuf), "%d", g_oafConfig->backlight); cfg->text = "屏幕亮度"; cfg->extra_text = page_strbuf; if( g_oafConfig->backlight == LIGHT_MIN || g_oafConfig->backlight == LIGHT_MAX ) cfg->extra_text_color = ATP_COLOR_RED; } else if( index == 1 ) { cfg->text = "GAME BOY画面"; cfg->extra_text = g_oafConfig->directBoot ? "跳过" : "显示"; } else if( index == 2 ) { cfg->text = "画面输出"; cfg->extra_text = scaler_val[g_oafConfig->scaler]; } else if( index == 3 ) { cfg->text = "存档方案"; cfg->extra_text = savetype_name[g_oafConfig->savePolicy]; } else if( index == 4 ) { cfg->text = "激活金手指"; cfg->extra_text = cheatmode_name[g_oafConfig->cheatMode]; } cfg->value = index; return ATP_SUCCESS; } static atp_pageopt_t config_adjust( atp_callerdata_t gblcfg, atp_counter_t index, atp_boolean_t x, atp_boolean_t, atp_boolean_t l, atp_boolean_t r, atp_boolean_t start, atp_boolean_t ) { OafConfig *g_oafConfig = (OafConfig*)gblcfg; if( l || r ) { if( index == 0 ) { u16 light = g_oafConfig->backlight; if( l ) { light -= 10; if( light % 10 ) light += 10 - light%10; } else if( r ) { light += 10; if( light % 10 ) light -= light % 10; } if( light > LIGHT_MAX ) light = LIGHT_MAX; else if( light < LIGHT_MIN ) light = LIGHT_MIN; g_oafConfig->backlight = light; } else if( index == 1 ) g_oafConfig->directBoot = !g_oafConfig->directBoot; else if( index == 2 ) g_oafConfig->scaler = ( SCALER_SIZE + ( g_oafConfig->scaler+(l?-1:1) ) ) % SCALER_SIZE; else if( index == 3 ) g_oafConfig->savePolicy = ( SAVE_POLICY_SIZE + ( g_oafConfig->savePolicy+(l?-1:1) ) ) % SAVE_POLICY_SIZE; else if( index == 4 ) g_oafConfig->cheatMode = ( CHEAT_MODE_SIZE + (g_oafConfig->cheatMode+(l?-1:1) ) ) % CHEAT_MODE_SIZE; } else if( start ) { return ATP_POWER_OFF == help_page( config_help, sizeof(config_help)/sizeof(atp_text_t) ) ? ATP_POWER_OFF : ATP_PAGE_REFRESH; } else if( x ) { int len = strlen(CONFIG_OUTPUT) + 40; char *data = malloc( len ); if( data == NULL ) return ATP_PAGE_DOSELECT; // only ignore this save len = ee_snprintf( data, len, CONFIG_OUTPUT, g_oafConfig->backlight, g_oafConfig->directBoot ? "true":"false", g_oafConfig->useGbaDb ? "true" : "false", g_oafConfig->scaler, g_oafConfig->gbaGamma, g_oafConfig->lcdGamma, g_oafConfig->contrast, g_oafConfig->brightness, g_oafConfig->defaultSave, g_oafConfig->cheatMode ); fsQuickWrite("config.ini", data, len); free( data ); return ATP_PAGE_DOSELECT; } return ATP_PAGE_UPDATE; } atp_error_t use_config_page( OafConfig *g_oafConfig ) { u8 base[sizeof(OafConfig)]; memcpy( base, g_oafConfig, sizeof(OafConfig) ); OafConfig *prev = (OafConfig*)&base[0]; atp_text_t oldtips; atp_tips("保存X/确定A/返回B", &oldtips); ee_snprintf( page_strbuf, sizeof(page_strbuf), "参数配置           当前电量:%3d%%" "每次开机存档方案重置为“和卡带序列号一致”,这个方案会优先使用游戏最后一次启动时设置的存档类型", MCU_getBatteryLevel()); atp_error_t res = atp_select( page_strbuf, 5, config_item, config_adjust, g_oafConfig, 0, 0, NULL ); atp_tips( oldtips, NULL ); if( res == ATP_NO_ACTION ) { memcpy( g_oafConfig, prev, sizeof(OafConfig) ); return ATP_SUCCESS; } else if( res == ATP_SUCCESS ) { if( prev->backlight != g_oafConfig->backlight ) GFX_setBrightness(g_oafConfig->backlight, g_oafConfig->backlight); } return res; } // -------------------------- // code for oaf cheat page // -------------------------- #define DISP_DONE 0 #define DISP_REGION 1 #define DISP_HOLES 2 #define DISP_KEYS 3 #define SAFE_CALLACL( r ) if( ACHTLIB_SUCCESS!=r ) \ {\ res = WAIT_ON_ERRPAGE( display_selcht );\ break;\ } DECLARE_ERROR_PAGE( display_selcht, "查找金手指配置出错" ) DECLARE_ERROR_PAGE( display_openlib, "打开金手指文件出错" ) DECLARE_ERROR_PAGE( display_nocheat, "找不到对应的金手指配置" ) static atp_error_t select_region( atp_callerdata_t, atp_counter_t index, atp_itemcfg_t *config ) { acl_region_t sreg; acl_chtid_t sid, id; if( ACHTLIB_SUCCESS != acl_query_cheat_set(index, &sid, &sreg) ) { config->text = "导出文件"; config->value = index; return ATP_SUCCESS; } char *t; switch( sreg ) { case 'C': t = "官方中文"; break; case 'J': t = "日文版"; break; case 'E': t = "英文版"; break; case 'F': t = "法语版"; break; case 'S': t = "西班牙语"; break; case 'I': t = "意大利语"; break; case 'D': t = "德语版"; break; case 'K': t = "韩文版"; break; case 'X': case 'P': t = "欧洲语种"; break; default: t = "其他语种"; break; } ee_sprintf(page_strbuf, "%c-%s", 'A'+(char)index, t); if( CCHT_NOT_INIT == info_current_cheat( &id, NULL ) ) id = 0; config->text = page_strbuf; config->value = index; // show saved information if( sid == id ) { config->extra_text = "已启用"; config->extra_text_color = ATP_COLOR_GREEN; } return ATP_SUCCESS; } static atp_error_t select_holes( atp_callerdata_t, atp_counter_t index, atp_itemcfg_t *cfg ) { acl_text_t text; acl_error_t res = acl_entry_get_label(index, &text); if( res == ACHTLIB_SUCCESS ) cfg->text = text; else cfg->text = "无效数据"; cfg->value = 1+index; // show saved information acl_entryid_t id; if( CCHT_OK == get_current_cheat( index, &id ) && ENT_USING(id) ) { cfg->extra_text = "开"; cfg->extra_text_color = ATP_COLOR_GREEN; } return ATP_SUCCESS; } static atp_error_t select_keys( atp_callerdata_t data, atp_counter_t index, atp_itemcfg_t *cfg ) { acl_text_t text; if( index == 0 ) { cfg->text = "不开启"; } else { acl_error_t res = acl_entry_get_label(index-1, &text); if( res == ACHTLIB_SUCCESS ) cfg->text = text; else cfg->text = "无效数据"; } acl_entryid_t eid = (acl_entryid_t)data; cfg->value = index<<16 | eid; if( CCHT_OK == include_current_cheat((acl_entryid_t)cfg->value) ) { cfg->extra_text = "选中"; cfg->extra_text_color = ATP_COLOR_GREEN; } return ATP_SUCCESS; } static atp_error_t select_onoff( atp_callerdata_t data, atp_counter_t index, atp_itemcfg_t *cfg ) { acl_entryid_t eid = (acl_entryid_t)data; eid &= 0xffff; if( index == 0 ) { cfg->text = "不开启"; cfg->value = eid; } else if( index == 1 ) { cfg->text = "开启"; cfg->value = 1<<16 | eid; } else { cfg->text = "调整数值开启[结果未知]"; cfg->value = 0; } // show saved information if( CCHT_OK == include_current_cheat((acl_entryid_t)cfg->value) ) { cfg->extra_text = "选中"; cfg->extra_text_color = ATP_COLOR_GREEN; } return ATP_SUCCESS; } ALWAYS_INLINE u16 calc_step( u16 value ) { u16 n = value / 50; if( n == 0 ) return 1; else { u16 base = 1; while( n > 10 ) { n = n/10; base *= 10; } if( n < 5 ) return base * 5; else return base * 10; } } static atp_error_t step_provider( atp_callerdata_t mixid, atp_counter_t index, atp_itemcfg_t *cfg ) { u32 mix = (u32)mixid; u16 max = mix & 0xffff; u16 step = mix >> 16; u16 res = step * (index+1); ee_snprintf( page_strbuf, 8, "%d", res < max ? res : max ); cfg->text = page_strbuf; cfg->value = res < max ? res : max; return ATP_SUCCESS; } static atp_error_t handle_onoff_entry( acl_entryid_t id, acl_elemlen_t codelen, atp_itemval_t *item ) { #define DEFAULT_ONOFF_HANDLER atp_select("选择此项目对应的设置", 2, select_onoff, NULL, (atp_callerdata_t)id, 0, 0, item); #define ONOFF_SAFE_CALLACL( statement ) if( ACHTLIB_SUCCESS != statement ) return DEFAULT_ONOFF_HANDLER; if( codelen > 4 )// more than 2 address return DEFAULT_ONOFF_HANDLER; u16 targetval = 0; acl_armcode_t code; // one address if( codelen == 2 ) { ONOFF_SAFE_CALLACL( acl_entry_get_armcode(1, &code) ); targetval = code & 0xff; } // two addresses else if( codelen == 4 ) { u32 addr0, addr1; ONOFF_SAFE_CALLACL( acl_entry_get_armcode(0, &addr0) ); ONOFF_SAFE_CALLACL( acl_entry_get_armcode(2, &addr1) ); if( (addr0 & 1) || (addr0 | 1) != addr1 ) // valid u16 address return DEFAULT_ONOFF_HANDLER; ONOFF_SAFE_CALLACL( acl_entry_get_armcode(1, &code) ); targetval = code & 0xff; ONOFF_SAFE_CALLACL( acl_entry_get_armcode(3, &code) ); targetval |= (code & 0xff) << 8; } // more than two address, should not overwrite values else return DEFAULT_ONOFF_HANDLER; atp_error_t res = atp_select( "选择此项目对应的设置", 3, select_onoff, NULL, targetval << 16 | id, 0, 0, item ); if( res == ATP_SUCCESS && *item == 0 ) { ee_snprintf( page_strbuf, sizeof(page_strbuf), "默认值:%d", targetval ); u16 step = calc_step( targetval ); atp_counter_t n = (targetval-1+step)/step; res = atp_select(page_strbuf, n, step_provider, NULL, (atp_callerdata_t)(step<<16|targetval), n, 0, item ); if( res == ATP_SUCCESS && *item != targetval ) overwrite_current_cheat( 1<<16|id, *item ); *item = 1<<16 | id; } return res; } atp_error_t use_cheat_page( const char *serial ) { acl_count_t len; if( ACHTLIB_SUCCESS != acl_open_lib( "gba.acl" ) ) { return WAIT_ON_ERRPAGE( display_openlib ); } if( ACHTLIB_SUCCESS != acl_select_game( serial, 0, &len ) ) { acl_close_lib(); return WAIT_ON_ERRPAGE( display_selcht ); } if( len == 0 ) { acl_close_lib(); return WAIT_ON_ERRPAGE( display_nocheat ); } // 显示配置页面 atp_error_t res; atp_itemval_t item; acl_elemlen_t cnt; uint8_t status = DISP_REGION; atp_counter_t defi = 0; acl_entryid_t eid = 0; atp_text_t oldtips; atp_tips("确定A/返回B", &oldtips); while( status != DISP_DONE ) { if( status == DISP_REGION ) { #ifdef NDEBUG res = atp_select("请谨慎使用金手指!金手指可能会引起卡顿、死机、损坏存档等现象。           " "选择一个金手指配置:", len, select_region, NULL, NULL, defi, 0, &item ); #else res = atp_select("请谨慎使用金手指!金手指可能会引起卡顿、死机、损坏存档等现象。           " "选择一个金手指配置:", len+1, select_region, NULL, NULL, defi, 0, &item ); #endif if( res == ATP_SUCCESS ) { #ifndef NDEBUG if( item == len ) { extern u8 dump_patched_rom; dump_patched_rom = 1; break; } #endif defi = item; acl_chtid_t sid; acl_elemlen_t len; u32 ccid, cclen; SAFE_CALLACL( acl_query_cheat_set((acl_index_t)item, &sid, NULL ) ); SAFE_CALLACL( acl_select_cheat_set( sid ) ); SAFE_CALLACL( acl_select_entry(0, &len) ); if( CCHT_OK == info_current_cheat(&ccid, &cclen) ) { // SKIP the init process when id and len is the same if( ccid != sid || cclen != len ) init_current_cheat( sid, len ); } else init_current_cheat( sid, len ); eid = 0; status = DISP_HOLES; } else if( res == ATP_NO_ACTION) { status = DISP_DONE; } else break; } else if( status == DISP_HOLES ) { SAFE_CALLACL( acl_select_entry(0, &cnt) ); res = atp_select("选择一个金手指项目", cnt, select_holes, NULL, NULL, eid > 0 ? (eid&0xffff)-1 : 0, 0, &item); if( res == ATP_SUCCESS ) { eid = (acl_entryid_t)item; status = DISP_KEYS; } else if( res == ATP_NO_ACTION ) { status = DISP_REGION; } else break; } else // DISP_KEYS { SAFE_CALLACL( acl_select_entry( eid, &cnt ) ); if( cnt == 0 ) { SAFE_CALLACL( acl_select_entry( 1<<16 | eid, &cnt ) ); res = handle_onoff_entry( eid, cnt, &item ); } else { res = atp_select("选择此项目对应的设置", cnt, select_keys, NULL, (atp_callerdata_t)eid, 0, 0, &item); } if( res == ATP_SUCCESS ) { put_current_cheat( (acl_entryid_t)item ); status = DISP_HOLES; } else if( res == ATP_NO_ACTION ) { status = DISP_HOLES; } else break; } } acl_close_lib(); atp_tips( oldtips, NULL ); return res; } // -------------------------- // code for oaf cheat page // -------------------------- #define DISP_KPOS 1 #define DISP_SETK 2 // SET KEY #define DISP_KMAP 3 // REMUX TYPE #define DISP_3DSK 4 // 3DS KEY #define DISP_GBAK 5 // GBA KEY #define KCP_OPTION_BASE 1000 #define KRFIELD_REMIX 0 #define KRFIELD_DEVICE 1 #define KRFIELD_GAME 2 DECLARE_ERROR_PAGE( display_conflictkey, "和已有键位产生冲突" ) const char *key_name[] = { "上", "下", "左", "右", "A", "B", "L", "R", "SELECT", "START", "X", "Y", "ZL", "ZR" }; const u16 key_val[] = { KEY_DUP, KEY_DDOWN, KEY_DLEFT, KEY_DRIGHT, KEY_A, KEY_B, KEY_L, KEY_R, KEY_SELECT, KEY_START, KEY_X, KEY_Y, KEY_ZL, KEY_ZR }; #define key_val_len (sizeof(key_val)/sizeof(u16)) static inline void key_tips( key_remix_t *p, atp_boolean_t checking, atp_itemcfg_t *cfg ) { if( p->remix_type == REMIX_TYPE_NONE ) { cfg->extra_text = "未添加"; cfg->extra_text_color = ATP_COLOR_LIGHT; } else { if( p->remix_type == REMIX_TYPE_CHEAT ) { if( checking && p->game_keys == 0) { cfg->extra_text = "配置不齐"; cfg->extra_text_color = ATP_COLOR_RED; } else { cfg->extra_text = "金手指键"; cfg->extra_text_color = ATP_COLOR_GREEN; } } else if( p->remix_type == REMIX_TYPE_REMAP ) { if( checking && (p->game_keys==0 || p->device_keys==0) ) { cfg->extra_text = "配置不齐"; cfg->extra_text_color = ATP_COLOR_RED; } else { cfg->extra_text = "键位映射"; cfg->extra_text_color = ATP_COLOR_GREEN; } } else if( p->remix_type == REMIX_TYPE_HOLD ) { if( checking && (p->game_keys==0 || p->device_keys==0) ) { cfg->extra_text = "配置不齐"; cfg->extra_text_color = ATP_COLOR_RED; } else { cfg->extra_text = "模拟长按"; cfg->extra_text_color = ATP_COLOR_GREEN; } } } } static atp_error_t select_krp( atp_callerdata_t, atp_counter_t index, atp_itemcfg_t *cfg ) { if( index < KEY_REMIX_LIMIT ) { ee_snprintf(page_strbuf, sizeof(page_strbuf), "键位配置项%ld", index+1); cfg->text = page_strbuf; cfg->value = index; key_remix_t *p = &g_keyremixConfig[index]; key_tips(p, 1, cfg); } else { cfg->text = index == KEY_REMIX_LIMIT ? "保存当前配置到SD卡" : "从SD卡加载已保存的配置"; cfg->value = KCP_OPTION_BASE + index-KEY_REMIX_LIMIT; } return ATP_SUCCESS; } static atp_error_t select_kcf( atp_callerdata_t p, atp_counter_t index, atp_itemcfg_t *cfg ) { key_remix_t *kcfg = (key_remix_t*)p; if( index == KRFIELD_REMIX ) { cfg->text = "选择键位功能"; key_tips(kcfg, 0, cfg); } else if( index == KRFIELD_DEVICE ) { cfg->text = "选择实机键位"; if( kcfg->device_keys ) { for( u8 i=0; i < key_val_len; ++i) { if( key_val[i] == kcfg->device_keys ) { cfg->extra_text = key_name[i]; cfg->extra_text_color = ATP_COLOR_GREEN; } } } else if( kcfg->remix_type == REMIX_TYPE_CHEAT ) { cfg->extra_text = "HOME"; cfg->extra_text_color = ATP_COLOR_GREEN; } else { cfg->extra_text = "未设置"; cfg->extra_text_color = ATP_COLOR_LIGHT; } } else if( index == KRFIELD_GAME ) { cfg->text = "游戏中对应键位"; if( kcfg->game_keys == 0 ) { cfg->extra_text = "未设置"; cfg->extra_text_color = ATP_COLOR_LIGHT; } else { cfg->extra_text = "已设置"; cfg->extra_text_color = ATP_COLOR_GREEN; } } cfg->value = index; return ATP_SUCCESS; } static atp_error_t select_remixtype( atp_callerdata_t, atp_counter_t index, atp_itemcfg_t *cfg ) { if( index == REMIX_TYPE_NONE ) cfg->text = "停用设置"; else if( index == REMIX_TYPE_REMAP ) cfg->text = "键位映射"; else if( index == REMIX_TYPE_CHEAT ) cfg->text = "金手指键"; else if( index == REMIX_TYPE_HOLD ) cfg->text = "模拟长按"; cfg->value = index; return ATP_SUCCESS; } static atp_error_t select_unikey( atp_callerdata_t str, atp_counter_t, atp_itemcfg_t *cfg ) { cfg->text = (atp_text_t)str; cfg->value = 0; return ATP_SUCCESS; } static atp_error_t select_hostkey( atp_callerdata_t dat, atp_counter_t index, atp_itemcfg_t *cfg ) { phykey_t k = (phykey_t)dat; cfg->text = key_name[index]; cfg->value = key_val[index]; if( k == key_val[index] ) { cfg->extra_text = "选中"; cfg->extra_text_color = ATP_COLOR_GREEN; } return ATP_SUCCESS; } static atp_error_t select_gbakey( atp_callerdata_t p_curkey, atp_counter_t index, atp_itemcfg_t *cfg ) { conkey_t key = *(conkey_t*)p_curkey; cfg->text = key_name[index]; cfg->value = key_val[index]; if( key & key_val[index] ) { cfg->extra_text = "选中"; cfg->extra_text_color = ATP_COLOR_GREEN; } return ATP_SUCCESS; } static atp_error_t active_gbakey( atp_callerdata_t p_curkey, 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 ) { conkey_t *pkey = (conkey_t*)p_curkey; if( x ) { conkey_t res = *pkey & key_val[index]; if( res ) *pkey &= ~key_val[index]; else *pkey |= key_val[index]; return ATP_PAGE_UPDATE; } else return ATP_PAGE_NOOPTION; } atp_error_t use_keyremix_page( char *file ) { atp_itemval_t position=0, field=0, value; atp_error_t res; atp_text_t oldtips; atp_tips( "确定A/返回B", &oldtips ); uint8_t status = DISP_KPOS; while ( status != DISP_DONE ) { if ( status == DISP_KPOS) { res = atp_select( "选择配置项后,按A进行键位配置", KEY_REMIX_LIMIT+2, select_krp, NULL, NULL, position, 0, &position ); if( res == ATP_SUCCESS ) { if( position < KEY_REMIX_LIMIT ) { status = DISP_SETK; field = 0; } else if( position == KCP_OPTION_BASE ) { const char *err = keyremix_dump( file ); if( !err ) status = DISP_DONE; else atp_show( 1, disp_str, err ); } else { const char *err = keyremix_load( file ); if( !err ) position = 0; else atp_show( 1, disp_str, err ); } } else break; } else if( status == DISP_SETK ) { ee_snprintf(page_strbuf, sizeof(page_strbuf), "编辑配置项%ld", position+1); key_remix_t *cur = &g_keyremixConfig[position]; res = atp_select( page_strbuf, 3, select_kcf, NULL, cur, field, 0, &field ); if( res == ATP_SUCCESS ) { status = field == KRFIELD_REMIX ? DISP_KMAP : (field == KRFIELD_DEVICE ? DISP_3DSK : DISP_GBAK); } else if( res == ATP_NO_ACTION ) { int fault = 0; for( int i=0; i < KEY_REMIX_LIMIT; ++i ) { if( i!=position ) { if( g_keyremixConfig[i].remix_type == cur->remix_type && g_keyremixConfig[i].device_keys == cur->device_keys ) { fault = 1; break; } } } if( fault && cur->remix_type != REMIX_TYPE_NONE ) atp_show(1, display_conflictkey, NULL); else status = DISP_KPOS; } else break; } else if( status == DISP_KMAP ) { key_remix_t *cur = &g_keyremixConfig[position]; res = atp_select( "配置键位功能", REMIX_TYPE_COUNT, select_remixtype, NULL, cur->remix_type, 0, 0, &value ); if( res == ATP_SUCCESS ) { if( cur->remix_type != value ) { cur->remix_type = value; cur->device_keys = 0; cur->game_keys = value == REMIX_TYPE_CHEAT ? DEFAULT_CHEATKEY : 0; } status = DISP_SETK; } else if( res == ATP_NO_ACTION ) { status = DISP_SETK; } else break; } else if( status == DISP_3DSK ) { key_remix_t *cur = &g_keyremixConfig[position]; atp_counter_t keys_count = 12; // old 3ds, old 3dsLL, 2ds u8 host = MCU_getSystemModel();// 0=3ds 1=3dsll 2=n3ds 3=2ds 4=n3dsll 5=n2dsll atp_text_t text; if( cur->remix_type == REMIX_TYPE_CHEAT ) { keys_count = 1; text = "HOME"; } else if( host > 1 && host != 3 ) // N3DS/N3DSLL/N2DSLL { keys_count = 14; } u8 selected = 31; for( u8 i=0; i < key_val_len; ++i ) { if( key_val[i] == cur->device_keys ) { selected = i; break; } } if( keys_count == 1 ) res = atp_select("选择实机键位(单选)", 1, select_unikey, NULL, text, 0, 0, &value); else res = atp_select( "选择实机键位(单选)", keys_count, select_hostkey, NULL, cur->device_keys, selected>keys_count?0:selected, 0, &value); if( res == ATP_SUCCESS ) { cur->device_keys = value; status = DISP_SETK; } else if( res == ATP_NO_ACTION ) { status = DISP_SETK; } else break; } else if( status == DISP_GBAK ) { key_remix_t *cur = &g_keyremixConfig[position]; conkey_t key_editing = cur->game_keys; atp_text_t current; atp_tips("选择X/确定A/返回B", ¤t); res = atp_select( "选择游戏中对应键位[多选,按X键设置选中]", 10, select_gbakey, active_gbakey, &key_editing, 0, 0, &value); atp_tips( current, NULL ); if( res == ATP_SUCCESS ) { cur->game_keys = key_editing; status = DISP_SETK; } else if( res == ATP_NO_ACTION ) { status = DISP_SETK; } else break; } } atp_tips( oldtips, NULL ); return res; }