添加菜单项选择金手指中间值

This commit is contained in:
anod 2023-03-11 10:33:12 +08:00
parent 93fce2dab6
commit 8bedce8a1e
3 changed files with 132 additions and 21 deletions

View File

@ -398,12 +398,13 @@ acl_error_t acl_select_entry( acl_entryid_t id, acl_elemlen_t *count)
if( gblcht.listc == 0 ) return ACHTLIB_INVALID; if( gblcht.listc == 0 ) return ACHTLIB_INVALID;
if( gblcht.setid == 0 ) return ACHTLIB_INVALID; if( gblcht.setid == 0 ) return ACHTLIB_INVALID;
FHandle fd; acl_error_t r = ACHTLIB_SUCCESS;
if( RES_OK != fOpen(&fd, gblcht.aclfile, FA_OPEN_EXISTING | FA_READ) )
return ACHTLIB_INVALID;
if( gblset.entry.entid != id ) if( gblset.entry.entid != id )
{ {
FHandle fd;
if( RES_OK != fOpen(&fd, gblcht.aclfile, FA_OPEN_EXISTING | FA_READ) )
return ACHTLIB_INVALID;
// update gblset.entry // update gblset.entry
if( RES_OK != fLseek(fd, gblset.seek + sizeof(uint16_t)) ) if( RES_OK != fLseek(fd, gblset.seek + sizeof(uint16_t)) )
{ {
@ -434,17 +435,17 @@ acl_error_t acl_select_entry( acl_entryid_t id, acl_elemlen_t *count)
} }
if( found ) break; if( found ) break;
} }
r = load_data(fd);
fClose( fd );
} }
if( count!=NULL ) *count = gblset.entry.datasz; if( count!=NULL ) *count = gblset.entry.datasz;
acl_error_t r = load_data(fd);
fClose( fd );
return r; return r;
} }
acl_error_t acl_entry_get_label( acl_index_t index, acl_text_t *label ) acl_error_t acl_entry_get_label( acl_index_t index, acl_text_t *label )
{ {
if( label == NULL ) return ACHTLIB_SUCCESS;
if( gblcht.serc == 0 ) return ACHTLIB_NOT_OPEN; if( gblcht.serc == 0 ) return ACHTLIB_NOT_OPEN;
if( gblcht.listc == 0 ) return ACHTLIB_INVALID; if( gblcht.listc == 0 ) return ACHTLIB_INVALID;
if( gblcht.setid == 0 ) return ACHTLIB_INVALID; if( gblcht.setid == 0 ) return ACHTLIB_INVALID;
@ -452,7 +453,7 @@ acl_error_t acl_entry_get_label( acl_index_t index, acl_text_t *label )
if( index < gblset.entry.datasz ) if( index < gblset.entry.datasz )
{ {
uint16_t *d = (uint16_t*)gblset.entdata; uint16_t *d = (uint16_t*)gblset.entdata;
*label = gblset.strings + d[index]; if( label != NULL ) *label = gblset.strings + d[index];
return ACHTLIB_SUCCESS; return ACHTLIB_SUCCESS;
} }
else return ACHTLIB_NOT_FOUND; else return ACHTLIB_NOT_FOUND;
@ -460,7 +461,6 @@ acl_error_t acl_entry_get_label( acl_index_t index, acl_text_t *label )
acl_error_t acl_entry_get_armcode( acl_index_t index, acl_armcode_t *code ) acl_error_t acl_entry_get_armcode( acl_index_t index, acl_armcode_t *code )
{ {
if( code == NULL ) return ACHTLIB_SUCCESS;
if( gblcht.serc == 0 ) return ACHTLIB_NOT_OPEN; if( gblcht.serc == 0 ) return ACHTLIB_NOT_OPEN;
if( gblcht.listc == 0 ) return ACHTLIB_INVALID; if( gblcht.listc == 0 ) return ACHTLIB_INVALID;
if( gblcht.setid == 0 ) return ACHTLIB_INVALID; if( gblcht.setid == 0 ) return ACHTLIB_INVALID;
@ -468,8 +468,8 @@ acl_error_t acl_entry_get_armcode( acl_index_t index, acl_armcode_t *code )
if( index < gblset.entry.datasz ) if( index < gblset.entry.datasz )
{ {
uint32_t *d = (uint32_t*)gblset.entdata; uint32_t *d = (uint32_t*)gblset.entdata;
*code = d[index]; if( code != NULL ) *code = d[index];
return ACHTLIB_SUCCESS; return ACHTLIB_SUCCESS;
} }
else return ACHTLIB_NOT_FOUND; else return ACHTLIB_NOT_FOUND;
} }

View File

@ -307,8 +307,22 @@ static atp_error_t select_holes( atp_callerdata_t, atp_counter_t index, atp_item
static atp_error_t select_onoff( atp_callerdata_t data, atp_counter_t index, atp_itemcfg_t *cfg ) 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; acl_entryid_t eid = (acl_entryid_t)data;
cfg->text = index == 0 ? "不开启" : "开启"; eid &= 0xffff;
cfg->value = index << 16 | eid; 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 // show saved information
if( CCHT_OK == include_current_cheat((acl_entryid_t)cfg->value) ) if( CCHT_OK == include_current_cheat((acl_entryid_t)cfg->value) )
@ -319,6 +333,87 @@ static atp_error_t select_onoff( atp_callerdata_t data, atp_counter_t index, atp
return ATP_SUCCESS; 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 mix, atp_counter_t index, atp_itemcfg_t *cfg )
{
static char number[8];
u16 max = mix & 0xffff;
u16 step = mix >> 16;
u16 res = step * (index+1);
ee_snprintf( number, 8, "%d", res < max ? res : max );
cfg->text = number;
cfg->value = res;
return ATP_SUCCESS;
}
static atp_error_t handle_onoff_entry( acl_entryid_t id, 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;
acl_elemlen_t codelen;
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 )
{
char title[24];
ee_snprintf( title, sizeof(title), "默认值:%d", targetval );
u16 step = calc_step( targetval );
atp_counter_t n = (targetval-1+step)/step;
res = atp_select(title, 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;
}
else return res;
}
static atp_error_t select_keys( atp_callerdata_t data, atp_counter_t index, atp_itemcfg_t *cfg ) static atp_error_t select_keys( atp_callerdata_t data, atp_counter_t index, atp_itemcfg_t *cfg )
{ {
acl_text_t text; acl_text_t text;
@ -423,6 +518,11 @@ static atp_pageopt_t serve_on_key( atp_callerdata_t data, atp_counter_t index, a
#define DISP_REGION 1 #define DISP_REGION 1
#define DISP_HOLES 2 #define DISP_HOLES 2
#define DISP_KEYS 3 #define DISP_KEYS 3
#define SAFE_CALLACL( r ) if( ACHTLIB_SUCCESS!=r ) \
{\
res = WAIT_ON_ERRPAGE( display_selcht );\
break;\
}
uint8_t status = DISP_REGION; uint8_t status = DISP_REGION;
atp_counter_t defi = 0; atp_counter_t defi = 0;
@ -441,9 +541,10 @@ static atp_pageopt_t serve_on_key( atp_callerdata_t data, atp_counter_t index, a
acl_chtid_t sid; acl_chtid_t sid;
acl_elemlen_t len; acl_elemlen_t len;
u32 ccid, cclen; u32 ccid, cclen;
acl_query_cheat_set((acl_index_t)item, &sid, NULL ); SAFE_CALLACL( acl_query_cheat_set((acl_index_t)item, &sid, NULL ) );
acl_select_cheat_set( sid ); SAFE_CALLACL( acl_select_cheat_set( sid ) );
acl_select_entry(0, &len); SAFE_CALLACL( acl_select_entry(0, &len) );
if( CCHT_OK == info_current_cheat(&ccid, &cclen) ) if( CCHT_OK == info_current_cheat(&ccid, &cclen) )
{ {
// SKIP the init process when id and len is the same // SKIP the init process when id and len is the same
@ -451,6 +552,7 @@ static atp_pageopt_t serve_on_key( atp_callerdata_t data, atp_counter_t index, a
init_current_cheat( sid, len ); init_current_cheat( sid, len );
} }
else init_current_cheat( sid, len ); else init_current_cheat( sid, len );
eid = 0; eid = 0;
status = DISP_HOLES; status = DISP_HOLES;
} }
@ -462,12 +564,11 @@ static atp_pageopt_t serve_on_key( atp_callerdata_t data, atp_counter_t index, a
} }
else if( status == DISP_HOLES ) else if( status == DISP_HOLES )
{ {
acl_select_entry(0, &cnt); SAFE_CALLACL( acl_select_entry(0, &cnt) );
res = atp_select("选择一个金手指项目", cnt, select_holes, NULL, NULL, eid > 0 ? (eid&0xffff)-1 : 0, 0, &item); res = atp_select("选择一个金手指项目", cnt, select_holes, NULL, NULL, eid > 0 ? (eid&0xffff)-1 : 0, 0, &item);
if( res == ATP_SUCCESS ) if( res == ATP_SUCCESS )
{ {
eid = (acl_entryid_t)item; eid = (acl_entryid_t)item;
acl_select_entry(eid, &cnt);
status = DISP_KEYS; status = DISP_KEYS;
} }
else if( res == ATP_NO_ACTION ) else if( res == ATP_NO_ACTION )
@ -478,7 +579,16 @@ static atp_pageopt_t serve_on_key( atp_callerdata_t data, atp_counter_t index, a
} }
else // DISP_KEYS else // DISP_KEYS
{ {
res = atp_select("选择此项目对应的设置", cnt==0 ? 2:cnt, cnt==0 ? select_onoff : select_keys, NULL, (atp_callerdata_t)eid, 0, 0, &item); SAFE_CALLACL( acl_select_entry( eid, &cnt ) );
if( cnt == 0 )
{
SAFE_CALLACL( acl_select_entry( 1<<16 | eid, NULL ) );
res = handle_onoff_entry( eid, &item );
}
else
{
res = atp_select("选择此项目对应的设置", cnt, select_keys, NULL, (atp_callerdata_t)eid, 0, 0, &item);
}
if( res == ATP_SUCCESS ) if( res == ATP_SUCCESS )
{ {
put_current_cheat( (acl_entryid_t)item ); put_current_cheat( (acl_entryid_t)item );

View File

@ -397,7 +397,8 @@ static Result loadGbaRom(const char *const path, u32 *const romSizeOut)
fClose(f); fClose(f);
// use the gbaatm cheat // use the gbaatm cheat
if( g_oafConfig.cheatMode != CHEAT_MODE_DISABLED && info_current_cheat(NULL, NULL) != CCHT_NOT_INIT ) if( g_oafConfig.cheatMode != CHEAT_MODE_DISABLED
&& info_current_cheat(NULL, NULL) == CCHT_OK )
{ {
char gamecode[5]; char gamecode[5];
memcpy( gamecode, ROM_LOC+0xac, 4 ); memcpy( gamecode, ROM_LOC+0xac, 4 );