oaf-boost/source/arm11/keyremix.c
2023-04-29 23:32:48 +08:00

177 lines
5.3 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/lgy.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_status = 0;
static conkey_t blind_conkey;
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)
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;
}
void keyremix_freeze()
{
// 空白选项忽略填充blind_conkey金手指放首位
key_remix_t temp[KEY_REMIX_LIMIT+1];
int j=1, has_cheat=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 )
{
temp[j].remix_type = p->remix_type;
temp[j].device_keys = p->device_keys;
temp[j].game_keys = p->game_keys;
if( p->device_keys & CON_KEY_MASK )
blind_conkey |= p->device_keys;
++j;
}
}
memset( g_keyremixConfig, 0, sizeof(g_keyremixConfig) );
if( has_cheat )
{
memcpy( g_keyremixConfig, temp, sizeof(key_remix_t)*j );
frozen_start = &g_keyremixConfig[1];
frozen_end = &g_keyremixConfig[j];
}
else
{
memcpy( g_keyremixConfig, &temp[1], sizeof(key_remix_t)*(j-1) );
frozen_start = &g_keyremixConfig[0];
frozen_end = &g_keyremixConfig[j-1];
}
}
void keyremix_update( uint16_t active_cheatkey )
{
phykey_t now = hidKeysHeld();
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_status, VKEY_HOME) )
{
*hid_mode = active_cheatkey;
*hid_set = ~active_cheatkey;
}
else if( frozen_end == frozen_start )// 空白键位设置,走原来流程就好
{
LGY_handleOverrides();
}
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 )
{
uint16_t flag = 1<<holding_pos++;
uint16_t oldf = flags_holding;
if( now_release(now, prev_status, p->device_keys) )
flags_holding ^= flag;
if( flags_holding & flag )
{
// exclude console keys is up
res |= now_release(now, prev_status, 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_status = now;
}
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;
}