Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,11 @@ object AllSettings : SettingsRegistry() {
*/
val gamepadDeadZoneScale = intSetting("gamepadDeadZoneScale", 100, 50..200)

/**
* 手柄映射配置
*/
val gamepadMappingConfig = stringSetting("gamepadMappingConfig", "default")

/**
* 摇杆控制模式
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ fun GamepadKeyListener(
lastPressKey.remove(event.code)
}
} else {
gamepadViewModel.findByCode(event.code, inGame)?.let { targets ->
gamepadViewModel.currentMapping?.findByCode(event.code, inGame)?.let { targets ->
val currentEvents = targets.map { guessEvent(it) }
lastPressKey[event.code] = currentEvents
currentOnKeyEvent(currentEvents, true)
Expand All @@ -227,7 +227,7 @@ fun GamepadKeyListener(
lastPressDpad.remove(event.direction)
}
} else {
gamepadViewModel.findByDpad(event.direction, inGame)?.let { targets ->
gamepadViewModel.currentMapping?.findByDpad(event.direction, inGame)?.let { targets ->
val currentEvents = targets.map { guessEvent(it) }
lastPressDpad[event.direction] = currentEvents
currentOnKeyEvent(currentEvents, true)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package com.movtery.zalithlauncher.ui.control.gamepad

import android.os.Parcelable
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize

@Parcelize
class GamepadMappingList(
val name: String,
val list: MutableList<GamepadMapping>
) : Parcelable {
/**
* 手柄与键盘按键映射绑定
*/
@IgnoredOnParcel
private val allKeyMappings = mutableMapOf<Int, TargetKeys>()
@IgnoredOnParcel
private val allDpadMappings = mutableMapOf<DpadDirection, TargetKeys>()

/**
* 便于记录目标键盘映射的数据类
*/
data class TargetKeys(
val inGame: Set<String>,
val inMenu: Set<String>
) {
fun getKeys(isInGame: Boolean) = if (isInGame) inGame else inMenu
}

fun load() {
allKeyMappings.clear()
allDpadMappings.clear()

list.forEach { mapping ->
addInMappingsMap(mapping)
}
}

private fun addInMappingsMap(mapping: GamepadMapping) {
val target = TargetKeys(mapping.targetsInGame, mapping.targetsInMenu)
mapping.dpadDirection?.let {
allDpadMappings[it] = target
} ?: run {
allKeyMappings[mapping.key] = target
}
}

/**
* 重置手柄与键盘按键映射绑定
*/
fun resetMapping(gamepadMap: GamepadMap, inGame: Boolean) =
applyMapping(gamepadMap, inGame, useDefault = true)

/**
* 为指定手柄映射设置目标键盘映射
*/
fun saveMapping(gamepadMap: GamepadMap, targets: Set<String>, inGame: Boolean) =
applyMapping(gamepadMap, inGame, customTargets = targets)

/**
* 保存或重置手柄与键盘按键映射绑定
* @param gamepadMap 手柄映射对象
* @param inGame 是否为游戏内映射(true 为游戏内,false 为菜单内)
* @param customTargets 自定义目标键
* @param useDefault 是否使用默认按键
*/
private fun applyMapping(
gamepadMap: GamepadMap,
inGame: Boolean,
customTargets: Set<String>? = null,
useDefault: Boolean = false
) {
val dpad = gamepadMap.dpadDirection
val existing = if (dpad != null) allDpadMappings[dpad] else allKeyMappings[gamepadMap.gamepad]

val (targetsInGame, targetsInMenu) = if (inGame) {
val newTargets = customTargets ?: if (useDefault) gamepadMap.defaultKeysInGame else emptySet()
newTargets to (existing?.inMenu ?: emptySet())
} else {
(existing?.inGame ?: emptySet()) to (customTargets ?: if (useDefault) gamepadMap.defaultKeysInMenu else emptySet())
}

val mapping = GamepadMapping(
key = gamepadMap.gamepad,
dpadDirection = dpad,
targetsInGame = targetsInGame,
targetsInMenu = targetsInMenu
)
addInMappingsMap(mapping)
if (
list.removeIf { mapping0 ->
mapping0.key == mapping.key
}
) {
list.add(mapping)
}
save()
}

/**
* 根据手柄按键键值获取对应的键盘映射代码
* @return 若未找到,则返回null
*/
fun findByCode(key: Int, inGame: Boolean) =
allKeyMappings[key]?.getKeys(inGame)

/**
* 根据手柄方向键获取对应的键盘映射代码
* @return 若未找到,则返回null
*/
fun findByDpad(dir: DpadDirection, inGame: Boolean) =
allDpadMappings[dir]?.getKeys(inGame)

/**
* 根据手柄映射获取对应的键盘映射代码
* @return 若未找到,则返回null
*/
fun findByMap(map: GamepadMap, inGame: Boolean) =
(map.dpadDirection?.let { allDpadMappings[it] } ?: allKeyMappings[map.gamepad])
?.getKeys(inGame)

fun save() {
keyMappingListMMKV().encode(name, this)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,9 @@ fun remapperMMKV(): MMKV = MMKV.mmkvWithID("GamepadRemapper", MMKV.MULTI_PROCESS
*/
fun keyMappingMMKV(): MMKV = MMKV.mmkvWithID("GamepadKeyMapping", MMKV.MULTI_PROCESS_MODE)

/**
* 手柄按键映射配置列表保存 MMKV
*/
fun keyMappingListMMKV(): MMKV = MMKV.mmkvWithID("GamepadKeyMappingList", MMKV.MULTI_PROCESS_MODE)


Loading