#include #include "fs.h" #include "fsutil.h" #include "drivers/gfx.h" #include "arm11/drivers/mcu.h" // @MERGE 231006 START #include "drivers/lgy11.h" // @MERGE 231006 END #include "arm11/keyremix.h" key_remix_t g_keyremixConfig[KEY_REMIX_LIMIT]; static key_remix_t *frozen_start, *frozen_end; static phykey_t prev_phykey = 0; static conkey_t prev_conkey = 0; static conkey_t blind_conkey; static u8 val_3dslider; static u16 flags_holding = 0; #define DIR_SEPARATOR "/" #define OUTPUT_DIR (KEYREMIX_OUTPUT_DIR DIR_SEPARATOR) #define VKEY_HOME (1u<<21) #define now_release( now, prev, key ) ((~(now))&(prev)&(key)) #define CON_KEY_MASK (KEY_A|KEY_B|KEY_L|KEY_R|KEY_SELECT|KEY_START|KEY_DUP|KEY_DDOWN|KEY_DLEFT|KEY_DRIGHT|KEY_ZL|KEY_ZR) uint16_t keyremix_cheatkey() { for(int i=0; i < KEY_REMIX_LIMIT; ++i) { if( g_keyremixConfig[i].remix_type == REMIX_TYPE_CHEAT ) return g_keyremixConfig[i].game_keys; } return DEFAULT_CHEATKEY; } static void update_brightness() { u16 backlightNow; u16 val = (u16)MCU_get3dSliderPosition(); u16 n = val < val_3dslider ? val_3dslider - val : val - val_3dslider; if( n > 5 ) // 峰哥反馈说有精度问题,所以改下,给个最小精度范围,范围外才进行修改 { val_3dslider = val; backlightNow = 48000 * val / 256; backlightNow = (backlightNow%50) > 50 ? 101+backlightNow/100 : 100+backlightNow/100; GFX_setBrightness(backlightNow, backlightNow); } } void keyremix_freeze() { // 空白选项忽略,填充blind_conkey,金手指放首位,REMAP紧跟金手指,HOLD在后面 key_remix_t temp[KEY_REMIX_LIMIT+1]; // 第一次循环:扫描得到各remix_type数量,用于定位在数组的位置 int has_cheat=0, rem_count=0, valid_count=0; blind_conkey = 0; for( int i=0; i < KEY_REMIX_LIMIT; ++i ) { key_remix_t *p = &g_keyremixConfig[i]; if( p->remix_type == REMIX_TYPE_CHEAT ) { temp[0].remix_type = REMIX_TYPE_CHEAT; temp[0].device_keys = p->device_keys; temp[0].game_keys = p->game_keys; has_cheat = 1; } else if( p->remix_type != REMIX_TYPE_NONE && p->device_keys != 0 && p->game_keys != 0 ) { valid_count++; if( p->remix_type == REMIX_TYPE_REMAP ) rem_count++; if( p->device_keys & CON_KEY_MASK ) blind_conkey |= p->device_keys; } } // 第二次循环:根据remix_type放置到数组特定位置 int j=has_cheat; int k=j+rem_count; for( int i=0; i < KEY_REMIX_LIMIT; ++i ) { key_remix_t *p = &g_keyremixConfig[i]; if( p->remix_type == REMIX_TYPE_REMAP && p->device_keys != 0 && p->game_keys != 0 ) { temp[j].remix_type = p->remix_type; temp[j].device_keys = p->device_keys; temp[j].game_keys = p->game_keys; ++j; } else if( p->remix_type == REMIX_TYPE_HOLD && p->device_keys != 0 && p->game_keys != 0 ) { temp[k].remix_type = p->remix_type; temp[k].device_keys = p->device_keys; temp[k].game_keys = p->game_keys; ++k; } } memcpy( g_keyremixConfig, temp, sizeof(g_keyremixConfig) ); frozen_start = &g_keyremixConfig[has_cheat]; frozen_end = &g_keyremixConfig[has_cheat+valid_count]; val_3dslider = MCU_get3dSliderPosition(); } void keyremix_update( uint16_t active_cheatkey ) { phykey_t now = hidKeysHeld(); conkey_t cur = 0; u8 init_cur = 0; vu16 *hid_set = (vu16*)0x10141112; vu16 *hid_mode = (vu16*)0x10141110; if( hidGetExtraKeys(0) & KEY_HOME ) now |= VKEY_HOME; if( active_cheatkey && now_release(now, prev_phykey, VKEY_HOME) ) { *hid_mode = active_cheatkey; *hid_set = ~active_cheatkey; } else if( frozen_end == frozen_start )// 空白键位设置,走原来流程就好 { // @MERGE 231006 START if( now & KEY_CPAD_MASK ){ *hid_set = (now>>24) ^ KEY_DPAD_MASK; *hid_mode = KEY_DPAD_MASK; } else *hid_mode = 0; // @MERGE 231006 END } else { conkey_t res = now & CON_KEY_MASK; // LGY_handleOverrides if(now & KEY_CPAD_MASK) res |= (now>>24) & KEY_DPAD_MASK; // unlink the blind console keys res &= ~blind_conkey; int holding_pos = 0; for( key_remix_t *p=frozen_start; p !=frozen_end; ++p ) { if( p->remix_type == REMIX_TYPE_REMAP ) { if( now & p->device_keys ) { res |= p->game_keys; } } else if( p->remix_type == REMIX_TYPE_HOLD ) { if( init_cur == 0 ) { init_cur = 1; cur = res; } uint16_t flag = 1<device_keys) ) flags_holding ^= flag; if( flags_holding & flag ) { // exclude console keys is up res |= now_release(cur, prev_conkey, p->game_keys) ^ p->game_keys; } else if( oldf != flags_holding )// release { res &= ~(p->game_keys); } } } *hid_mode = CON_KEY_MASK; *hid_set = ~res; } prev_phykey = now; prev_conkey = cur; update_brightness(); } const char* keyremix_load( const char *file ) { char output[512]; int len = strlen( file ) + strlen(OUTPUT_DIR); if( len+1 > 512 ) return "文件名太长,无法打开"; strcpy( output, OUTPUT_DIR ); strcpy( &output[strlen(OUTPUT_DIR)], file ); output[len] = '\0'; output[len-1] = 'm'; output[len-2] = 'r'; output[len-3] = 'k'; FILINFO fi; const char *retval = NULL; if( fStat(output, &fi) == RES_OK ) { u8 dat[sizeof(g_keyremixConfig)]; if( RES_OK == fsQuickRead(output, dat, sizeof(dat) ) ) memcpy( g_keyremixConfig, dat, sizeof(g_keyremixConfig) ); else retval = "读文件失败"; } else retval = "文件不存在"; return retval; } const char* keyremix_dump( const char *file ) { char output[512]; int len = strlen( file ) + strlen(OUTPUT_DIR); if( len+1 > 512 ) return "文件名太长,无法保存"; strcpy( output, OUTPUT_DIR ); strcpy( &output[strlen(OUTPUT_DIR)], file ); output[len] = '\0'; output[len-1] = 'm'; output[len-2] = 'r'; output[len-3] = 'k'; const char *retval = NULL; if( RES_OK != fsQuickWrite(output, g_keyremixConfig, sizeof(g_keyremixConfig)) ) retval = "保存失败"; return retval; }