oaf-boost/source/arm11/keyremix.c
2024-10-03 20:42:15 +08:00

232 lines
7.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <string.h>
#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/anopatch.h"
#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;
setBrightness(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<<holding_pos++;
uint16_t oldf = flags_holding;
if( now_release(now, prev_phykey, p->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;
}