Files
midi-hid/config.go

149 lines
3.2 KiB
Go

package main
import (
"fmt"
"os"
"github.com/goccy/go-yaml"
"github.com/bendahl/uinput"
)
type Config struct {
Controller []ControllerConfig `yaml:"controller"`
}
type ControllerConfig struct {
PortName string `yaml:"portName"`
VendorID uint16 `yaml:"vendorID"`
ProductID uint16 `yaml:"productID"`
Mappings []MappingConfig `yaml:"mappings"`
}
type MappingConfig struct {
Comment string `yaml:"comment"`
Type MappingType `yaml:"type"`
MidiChannel uint8 `yaml:"midiChannel"`
MidiKey uint8 `yaml:"midiKey"`
MidiController uint8 `yaml:"midiController"`
Button ButtonName `yaml:"button"`
Axis AxisName `yaml:"axis"`
IsSigned bool `yaml:"isSigned"`
}
type MappingType string
type ButtonName string
type AxisName string
const (
ButtonMappingType MappingType = "button"
ControlMappingType MappingType = "control"
ButtonNorth ButtonName = "north"
ButtonEast ButtonName = "east"
ButtonSouth ButtonName = "south"
ButtonWest ButtonName = "west"
AxisLeftX AxisName = "left-x"
AxisLeftY AxisName = "left-y"
AxisRightX AxisName = "right-x"
AxisRightY AxisName = "right-y"
)
func ParseConfig(path string) (Config, error) {
var config Config
buffer, err := os.ReadFile(path)
if err != nil {
return config, err
}
err = yaml.Unmarshal(buffer, &config)
if err != nil {
return config, err
}
return config, nil
}
func (config Config) Construct() (ControllerList, error) {
var controllerList ControllerList
for _, controllerConfig := range config.Controller {
actualController, err := controllerConfig.Construct()
if err != nil {
return nil, err
}
controllerList = append(controllerList, actualController)
}
return controllerList, nil
}
func (cc ControllerConfig) Construct() (*Controller, error) {
actualController, err := NewController(cc.PortName, cc.VendorID, cc.ProductID)
if err != nil {
return actualController, err
}
for _, mappingConfig := range cc.Mappings {
actualMapping, err := mappingConfig.Construct()
if err != nil {
return nil, err
}
actualController.AddMapping(actualMapping)
}
return actualController, nil
}
func (mc MappingConfig) Construct() (Mapping, error) {
switch mc.Type {
case ButtonMappingType:
button, err := mc.Button.Construct()
if err != nil {
return ButtonMapping{}, err
}
return ButtonMapping{mc.Comment, mc.MidiChannel, mc.MidiKey, button}, nil
case ControlMappingType:
axis, err := mc.Axis.Construct()
if err != nil {
return ControlMapping{}, err
}
return ControlMapping{mc.Comment, mc.MidiChannel, mc.MidiController, axis, mc.IsSigned}, nil
default:
return ButtonMapping{}, fmt.Errorf("Invalid mapping type")
}
}
func (bn ButtonName) Construct() (int, error) {
switch bn {
case ButtonNorth:
return uinput.ButtonNorth, nil
case ButtonEast:
return uinput.ButtonEast, nil
case ButtonSouth:
return uinput.ButtonSouth, nil
case ButtonWest:
return uinput.ButtonWest, nil
default:
return -1, fmt.Errorf("Invalid button name \"%s\"", bn)
}
}
func (an AxisName) Construct() (ControllerAxis, error) {
switch an {
case AxisLeftX:
return LeftX, nil
case AxisLeftY:
return LeftY, nil
case AxisRightX:
return RightX, nil
case AxisRightY:
return RightY, nil
default:
return -1, fmt.Errorf("Invalid axis name \"%s\"", an)
}
}