2024-03-29 05:17:16 +01:00
|
|
|
// Copyright 2024 The Ebitengine Authors
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
//go:build ignore
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"bytes"
|
|
|
|
_ "embed"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
"text/template"
|
|
|
|
)
|
|
|
|
|
|
|
|
const license = `// Copyright 2024 The Ebitengine Authors
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
`
|
|
|
|
|
|
|
|
// gamecontrollerdb.txt is downloaded at https://github.com/mdqinc/SDL_GameControllerDB.
|
|
|
|
|
|
|
|
// To update the database file, run:
|
|
|
|
//
|
|
|
|
// curl --location --remote-name https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/master/gamecontrollerdb.txt
|
|
|
|
|
|
|
|
//go:embed gamecontrollerdb.txt
|
|
|
|
var gameControllerDB []byte
|
|
|
|
|
|
|
|
const dbTemplate string = `{{.License}}
|
|
|
|
|
|
|
|
{{.DoNotEdit}}
|
|
|
|
|
|
|
|
{{.BuildConstraints}}
|
|
|
|
|
|
|
|
package gamepaddb
|
|
|
|
|
|
|
|
import (
|
|
|
|
_ "embed"
|
|
|
|
)
|
|
|
|
|
|
|
|
//go:embed gamecontrollerdb_{{.FileNameSuffix}}.txt
|
|
|
|
var controllerBytes []byte
|
|
|
|
|
2024-04-18 07:15:54 +02:00
|
|
|
{{if .HasGLFWGamepads}}
|
|
|
|
var additionalGLFWGamepads = []byte(` + "`" + `
|
|
|
|
78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
|
|
|
|
78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
|
|
|
|
78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
|
|
|
|
78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
|
|
|
|
78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
|
|
|
|
78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
|
|
|
|
78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
|
|
|
|
` + "`" + `)
|
|
|
|
{{end}}
|
|
|
|
|
2024-03-29 05:17:16 +01:00
|
|
|
func init() {
|
|
|
|
if err := Update(controllerBytes); err != nil {
|
|
|
|
panic(err)
|
2024-04-18 07:15:54 +02:00
|
|
|
}{{if .HasGLFWGamepads}}
|
|
|
|
if err := Update(additionalGLFWGamepads); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}{{end}}
|
|
|
|
}
|
|
|
|
`
|
2024-03-29 05:17:16 +01:00
|
|
|
|
|
|
|
func main() {
|
|
|
|
if err := run(); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func run() error {
|
2024-03-29 05:18:13 +01:00
|
|
|
// doNotEditor is a special comment for generated files.
|
|
|
|
// This follows the standard comment rule (https://pkg.go.dev/cmd/go#hdr-Generate_Go_files_by_processing_source).
|
|
|
|
const doNotEdit = "// Code generated by gen.go using 'go generate'. DO NOT EDIT."
|
2024-03-29 05:17:16 +01:00
|
|
|
|
|
|
|
type gamePadPlatform struct {
|
|
|
|
filenameSuffix string
|
|
|
|
buildConstraints string
|
2024-04-18 07:15:54 +02:00
|
|
|
hasGLFWGamepads bool
|
2024-03-29 05:17:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
platforms := map[string]gamePadPlatform{
|
|
|
|
"Windows": {
|
|
|
|
filenameSuffix: "windows",
|
|
|
|
buildConstraints: "//go:build !microsoftgdk",
|
2024-04-18 07:15:54 +02:00
|
|
|
hasGLFWGamepads: true,
|
2024-03-29 05:17:16 +01:00
|
|
|
},
|
|
|
|
"Mac OS X": {
|
2024-10-12 07:07:13 +02:00
|
|
|
filenameSuffix: "macos",
|
2024-10-26 12:05:39 +02:00
|
|
|
buildConstraints: "//go:build darwin && !ios",
|
2024-03-29 05:17:16 +01:00
|
|
|
},
|
|
|
|
"Linux": {
|
|
|
|
filenameSuffix: "linbsd",
|
|
|
|
buildConstraints: "//go:build (freebsd || (linux && !android) || netbsd || openbsd) && !nintendosdk && !playstation5",
|
|
|
|
},
|
|
|
|
"iOS": {
|
|
|
|
filenameSuffix: "ios",
|
|
|
|
},
|
|
|
|
"Android": {
|
|
|
|
filenameSuffix: "android",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-03-29 05:18:13 +01:00
|
|
|
controllerDBs, err := splitDBsByPlatform(gameControllerDB)
|
2024-03-29 05:17:16 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for sdlPlatformName, platform := range platforms {
|
|
|
|
controllerDB, ok := controllerDBs[sdlPlatformName]
|
|
|
|
if !ok {
|
2024-03-29 05:18:13 +01:00
|
|
|
return fmt.Errorf("failed to find controller db for platform %s in gamecontrollerdb.txt", sdlPlatformName)
|
2024-03-29 05:17:16 +01:00
|
|
|
}
|
|
|
|
|
2024-03-29 05:18:13 +01:00
|
|
|
// Write each chunk into separate text file for embedding into respective generated files.
|
|
|
|
if err = os.WriteFile(fmt.Sprintf("gamecontrollerdb_%s.txt", platform.filenameSuffix), []byte(controllerDB), 0666); err != nil {
|
2024-03-29 05:17:16 +01:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
path := fmt.Sprintf("db_%s.go", platform.filenameSuffix)
|
|
|
|
tmpl, err := template.New(path).Parse(dbTemplate)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
f, err := os.Create(path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
2024-07-29 09:29:50 +02:00
|
|
|
w := bufio.NewWriter(f)
|
|
|
|
if err := tmpl.Execute(w, struct {
|
2024-03-29 05:17:16 +01:00
|
|
|
License string
|
|
|
|
DoNotEdit string
|
|
|
|
BuildConstraints string
|
|
|
|
FileNameSuffix string
|
2024-04-18 07:15:54 +02:00
|
|
|
HasGLFWGamepads bool
|
2024-03-29 05:17:16 +01:00
|
|
|
}{
|
|
|
|
License: license,
|
|
|
|
DoNotEdit: doNotEdit,
|
|
|
|
BuildConstraints: platform.buildConstraints,
|
|
|
|
FileNameSuffix: platform.filenameSuffix,
|
2024-04-18 07:15:54 +02:00
|
|
|
HasGLFWGamepads: platform.hasGLFWGamepads,
|
2024-03-29 05:18:13 +01:00
|
|
|
}); err != nil {
|
2024-03-29 05:17:16 +01:00
|
|
|
return err
|
|
|
|
}
|
2024-07-29 09:29:50 +02:00
|
|
|
if err := w.Flush(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-03-29 05:17:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-03-29 05:18:13 +01:00
|
|
|
func splitDBsByPlatform(controllerDB []byte) (map[string]string, error) {
|
2024-03-29 05:17:16 +01:00
|
|
|
s := bufio.NewScanner(bytes.NewReader(controllerDB))
|
|
|
|
dbs := map[string]string{}
|
|
|
|
|
|
|
|
for s.Scan() {
|
|
|
|
line := s.Text()
|
|
|
|
if strings.HasPrefix(line, "#") {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, part := range strings.Split(line, ",") {
|
|
|
|
if platform, found := strings.CutPrefix(part, "platform:"); found {
|
|
|
|
dbs[platform] += line + "\n"
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err := s.Err(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return dbs, nil
|
|
|
|
}
|