diff --git a/cmd/pi/README.md b/cmd/pi/README.md new file mode 100644 index 00000000..95f398f7 --- /dev/null +++ b/cmd/pi/README.md @@ -0,0 +1,13 @@ +# pi command line interface + +## Install + +```sh +go install github.com/elgopher/pi/cmd/pi +``` + +## Run + +```shell +pi [global options] command [command options] [arguments...] +``` \ No newline at end of file diff --git a/cmd/pi/cli.go b/cmd/pi/cli.go new file mode 100644 index 00000000..9c555fbc --- /dev/null +++ b/cmd/pi/cli.go @@ -0,0 +1,57 @@ +// (c) 2022-2023 Jacek Olszak +// This code is licensed under MIT license (see LICENSE for details) + +package main + +import ( + "fmt" + "os" + + "github.com/urfave/cli/v2" + + "github.com/elgopher/pi/cmd/pi/internal/convert" +) + +func main() { + app := cli.App{ + Usage: "Pi Command Line Interface", + Commands: []*cli.Command{ + convertCmd(), + }, + } + err := app.Run(os.Args) + if err != nil { + _, _ = os.Stderr.WriteString(err.Error()) + } +} + +func convertCmd() *cli.Command { + return &cli.Command{ + Name: "convert", + Usage: "Converts one file format into another one", + Description: "Format of input and output file is deducted based on files extension.", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "format", + Aliases: []string{"f"}, + Usage: "Format of input file. Overrides what CLI deducted based on input file extension. For now, the only supported input format is p8.", + }, + }, + ArgsUsage: "input.file output.file", + Action: func(context *cli.Context) error { + inputFile := context.Args().Get(0) + outputFile := context.Args().Get(1) + + if context.Args().Len() > 2 { + return fmt.Errorf("too many arguments") + } + + command := convert.Command{ + InputFormat: convert.InputFormat(context.String("format")), + InputFile: inputFile, + OutputFile: outputFile, + } + return command.Run() + }, + } +} diff --git a/cmd/pi/go.mod b/cmd/pi/go.mod new file mode 100644 index 00000000..af22c67e --- /dev/null +++ b/cmd/pi/go.mod @@ -0,0 +1,14 @@ +module github.com/elgopher/pi/cmd/pi + +go 1.20 + +require ( + github.com/icza/bitio v1.1.0 + github.com/urfave/cli/v2 v2.25.7 +) + +require ( + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect +) diff --git a/cmd/pi/go.sum b/cmd/pi/go.sum new file mode 100644 index 00000000..eccf5c88 --- /dev/null +++ b/cmd/pi/go.sum @@ -0,0 +1,12 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/icza/bitio v1.1.0 h1:ysX4vtldjdi3Ygai5m1cWy4oLkhWTAi+SyO6HC8L9T0= +github.com/icza/bitio v1.1.0/go.mod h1:0jGnlLAx8MKMr9VGnn/4YrvZiprkvBelsVIbA9Jjr9A= +github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6 h1:8UsGZ2rr2ksmEru6lToqnXgA8Mz1DP11X4zSJ159C3k= +github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6/go.mod h1:xQig96I1VNBDIWGCdTt54nHt6EeI639SmHycLYL7FkA= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= diff --git a/cmd/pi/internal/convert/convert.go b/cmd/pi/internal/convert/convert.go new file mode 100644 index 00000000..c5353c5b --- /dev/null +++ b/cmd/pi/internal/convert/convert.go @@ -0,0 +1,63 @@ +// (c) 2022-2023 Jacek Olszak +// This code is licensed under MIT license (see LICENSE for details) + +package convert + +import ( + "fmt" + "strings" + + "github.com/elgopher/pi/cmd/pi/internal/convert/internal/p8" +) + +type InputFormat string + +const ( + InputFormatP8 = "p8" +) + +type Command struct { + InputFormat + InputFile string + OutputFile string +} + +func (o Command) Run() error { + if o.InputFile == "" { + return fmt.Errorf("input file not provided") + } + + if o.InputFormat != "" && o.InputFormat != InputFormatP8 { + return fmt.Errorf("input format %s not supported", o.InputFormat) + } + + if o.InputFormat == "" { + if strings.HasSuffix(o.InputFile, ".p8") { + o.InputFormat = InputFormatP8 + } else { + return fmt.Errorf("cannot deduct the format of %s input file", o.InputFile) + } + } + + if o.OutputFile == "" { + return fmt.Errorf("output file not provided") + } + + fmt.Printf("Converting %s to %s... ", o.InputFile, o.OutputFile) + fmt.Printf("Using %s input format... ", o.InputFormat) + if err := o.convert(); err != nil { + return err + } + fmt.Println("Done") + return nil +} + +func (o Command) convert() error { + if o.InputFormat == InputFormatP8 { + if err := p8.ConvertToAudioSfx(o.InputFile, o.OutputFile); err != nil { + return err + } + } + + return nil +} diff --git a/cmd/pi/internal/convert/internal/p8/p8.go b/cmd/pi/internal/convert/internal/p8/p8.go new file mode 100644 index 00000000..8c226e36 --- /dev/null +++ b/cmd/pi/internal/convert/internal/p8/p8.go @@ -0,0 +1,134 @@ +package p8 + +import ( + "bytes" + "encoding/hex" + "fmt" + "os" + + "github.com/icza/bitio" + + "github.com/elgopher/pi/audio" +) + +func ConvertToAudioSfx(inputFile, outputFile string) error { + parser := Parser{} + file, err := parser.Parse(inputFile) + if err != nil { + return fmt.Errorf("error parsing p8 file %s: %w", inputFile, err) + } + + for _, section := range file.Sections { + if section.Name == "__sfx__" { + sfx, err := decodeSfx(section.Lines) + if err != nil { + return fmt.Errorf("error decoding __sfx__ section from p8 file %s: %w", inputFile, err) + } + audio.Sfx = sfx + } + } + + bytes, err := audio.Save() + if err != nil { + return fmt.Errorf("saving audio failed: %w", err) + } + + err = os.WriteFile(outputFile, bytes, 0644) + if err != nil { + return fmt.Errorf("writing %s failed: %w", outputFile, err) + } + + return nil +} + +func decodeSfx(lines []string) (sfx [64]audio.SoundEffect, err error) { + // each line is a sound effect + for no, line := range lines { + decoded, err := hex.DecodeString(line) + if err != nil { + return sfx, err + } + + notes, err := decodeSfxNotes(decoded[4:]) + if err != nil { + return sfx, err + } + + editorModeAndFilters := bitio.NewReader(bytes.NewReader(decoded[0:1])) + editorMode, err := editorModeAndFilters.ReadBool() + if err != nil { + return sfx, err + } + _ = editorMode + + noiz, err := editorModeAndFilters.ReadBool() + if err != nil { + return sfx, err + } + + buzz, err := editorModeAndFilters.ReadBool() + if err != nil { + return sfx, err + } + + detune, err := editorModeAndFilters.ReadBits(2) + if err != nil { + return sfx, err + } + + reverb, err := editorModeAndFilters.ReadBits(2) + if err != nil { + return sfx, err + } + + dampen, err := editorModeAndFilters.ReadBits(2) + if err != nil { + return sfx, err + } + + sfx[no] = audio.SoundEffect{ + Speed: decoded[1], + LoopStart: decoded[2], + LoopStop: decoded[3], + Notes: notes, + Noiz: noiz, + Buzz: buzz, + Detune: byte(detune), + Reverb: byte(reverb), + Dampen: byte(dampen), + } + } + + return +} + +func decodeSfxNotes(b []byte) (notes [32]audio.Note, err error) { + reader := bitio.NewReader(bytes.NewBuffer(b)) + for i := 0; i < 32; i++ { + pitch, err := reader.ReadByte() + if err != nil { + return notes, err + } + notes[i].Pitch = audio.Pitch(pitch) + + waveform, err := reader.ReadBits(4) + if err != nil { + return notes, err + } + notes[i].Instrument = audio.Instrument(waveform) + + volume, err := reader.ReadBits(4) + if err != nil { + return notes, err + } + notes[i].Volume = audio.Volume(volume) + + effect, err := reader.ReadBits(4) + if err != nil { + return notes, err + } + notes[i].Effect = audio.Effect(effect) + } + + return +} diff --git a/cmd/pi/internal/convert/internal/p8/parser.go b/cmd/pi/internal/convert/internal/p8/parser.go new file mode 100644 index 00000000..57d1f170 --- /dev/null +++ b/cmd/pi/internal/convert/internal/p8/parser.go @@ -0,0 +1,123 @@ +package p8 + +import ( + "bufio" + "fmt" + "io" + "os" + "strconv" + "strings" +) + +type Parser struct { + currentSectionName string +} + +func (p *Parser) Parse(file string) (File, error) { + f, err := os.Open(file) + if err != nil { + return File{}, err + } + + scanner := bufio.NewScanner(bufio.NewReader(f)) + var version int + if version, err = p.readHeader(scanner); err != nil { + return File{}, err + } + + var sections []Section + + for { + section, err := p.readSection(scanner) + sections = append(sections, section) + if err == io.EOF { + break + } else if err != nil { + return File{}, err + } + } + + return File{ + Version: version, + Sections: sections, + }, nil +} + +func (p *Parser) readHeader(scanner *bufio.Scanner) (version int, err error) { + if !scanner.Scan() { + return 0, fmt.Errorf("error reading first line from p8 file header: %w", scanner.Err()) + } + + firstLine := scanner.Text() + + if firstLine != "pico-8 cartridge // http://www.pico-8.com" { + return 0, fmt.Errorf("input file is not p8 cartridge file. Header expected") + } + + if !scanner.Scan() { + return 0, fmt.Errorf("error reading second line from p8 file header: %w", scanner.Err()) + } + + versionLine := scanner.Text() + if !strings.HasPrefix(versionLine, "version ") { + return 0, fmt.Errorf("input file is not p8 cartridge file. Version in header expected, but not found") + } + + versionString := strings.SplitN(versionLine, " ", 2)[1] + + version, err = strconv.Atoi(versionString) + if err != nil { + return 0, fmt.Errorf("input file is not p8 cartridge file. Version number in header expected, but found %s", versionString) + } + + return version, nil +} + +func (p *Parser) readSection(scanner *bufio.Scanner) (Section, error) { + if p.currentSectionName == "" { + if !scanner.Scan() { + return Section{}, fmt.Errorf("error reading section name") + } + p.currentSectionName = scanner.Text() + } + + sectionName := p.currentSectionName + + var lines []string + for { + scanOk := scanner.Scan() + line := scanner.Text() + if p.isSectionName(line) { + p.currentSectionName = line + return Section{ + Name: sectionName, + Lines: lines, + }, nil + } + lines = append(lines, line) + if !scanOk { + if scanner.Err() == nil { + return Section{ + Name: sectionName, + Lines: lines, + }, io.EOF + } + return Section{}, fmt.Errorf("error readling section line: %w", scanner.Err()) + } + } + +} + +func (p *Parser) isSectionName(line string) bool { + return line == "__sfx__" || line == "__gfx__" || line == "__lua__" || line == "__music__" +} + +type File struct { + Version int + Sections []Section +} + +type Section struct { + Name string + Lines []string +} diff --git a/cmd/pi/internal/convert/internal/test/code.p8 b/cmd/pi/internal/convert/internal/test/code.p8 new file mode 100644 index 00000000..b58552ac --- /dev/null +++ b/cmd/pi/internal/convert/internal/test/code.p8 @@ -0,0 +1,13 @@ +pico-8 cartridge // http://www.pico-8.com +version 41 +__lua__ +function _draw() +end +function _lua +__gfx__ +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/cmd/pi/internal/convert/internal/test/minimal.p8 b/cmd/pi/internal/convert/internal/test/minimal.p8 new file mode 100644 index 00000000..2c2226ca --- /dev/null +++ b/cmd/pi/internal/convert/internal/test/minimal.p8 @@ -0,0 +1,9 @@ +pico-8 cartridge // http://www.pico-8.com +version 41 +__gfx__ +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/cmd/pi/internal/convert/internal/test/music.p8 b/cmd/pi/internal/convert/internal/test/music.p8 new file mode 100644 index 00000000..a7cb36c4 --- /dev/null +++ b/cmd/pi/internal/convert/internal/test/music.p8 @@ -0,0 +1,15 @@ +pico-8 cartridge // http://www.pico-8.com +version 41 +__gfx__ +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +__sfx__ +000100000000027050270502705027050260502605026050260502605026050260502605026050260502605026050260502605027050270502705027050280500000000000000000000000000000000000000000 +00100000000000000000000000003505032050310502e0502d0502b0502a050290502805027050260502505024050240502305000000000000000000000000000000000000000000000000000000000000000000 +__music__ +00 01424344 + diff --git a/cmd/pi/internal/convert/internal/test/sfx.p8 b/cmd/pi/internal/convert/internal/test/sfx.p8 new file mode 100644 index 00000000..d3955428 --- /dev/null +++ b/cmd/pi/internal/convert/internal/test/sfx.p8 @@ -0,0 +1,74 @@ +pico-8 cartridge // http://www.pico-8.com +version 41 +__gfx__ +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +__sfx__ +000100003075000000000002805000000000000000000000000000000000000000002b05000000000000000000000000000000000000310500000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000700000000000000157501575017750187501b7501f750257502d750317502c75026750217501e7501b750167501475013750157501a7501e7502275025750227501d75019750187503475000000000001b750 diff --git a/go.work b/go.work new file mode 100644 index 00000000..ebd36b85 --- /dev/null +++ b/go.work @@ -0,0 +1,6 @@ +go 1.20 + +use ( + . + ./cmd/pi +) diff --git a/go.work.sum b/go.work.sum new file mode 100644 index 00000000..4a542fb8 --- /dev/null +++ b/go.work.sum @@ -0,0 +1,37 @@ +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= +github.com/go-text/typesetting v0.0.0-20230905121921-abdbcca6e0eb h1:4GpJirtA8yY24aqbU3uppiXGYiVpWfLIrqc2NNKKk9s= +github.com/go-text/typesetting v0.0.0-20230905121921-abdbcca6e0eb/go.mod h1:evDBbvNR/KaVFZ2ZlDSOWWXIUKq0wCOEtzLxRM8SG3k= +github.com/hajimehoshi/bitmapfont/v2 v2.2.3 h1:jmq/TMNj352V062Tr5e3hAoipkoxCbY1JWTzor0zNps= +github.com/hajimehoshi/bitmapfont/v2 v2.2.3/go.mod h1:sWM8ejdkGSXaQGlZcegMRx4DyEPOWYyXqsBKIs+Yhzk= +github.com/hajimehoshi/bitmapfont/v3 v3.0.0 h1:r2+6gYK38nfztS/et50gHAswb9hXgxXECYgE8Nczmi4= +github.com/hajimehoshi/bitmapfont/v3 v3.0.0/go.mod h1:+CxxG+uMmgU4mI2poq944i3uZ6UYFfAkj9V6WqmuvZA= +github.com/hajimehoshi/go-mp3 v0.3.4 h1:NUP7pBYH8OguP4diaTZ9wJbUbk3tC0KlfzsEpWmYj68= +github.com/hajimehoshi/go-mp3 v0.3.4/go.mod h1:fRtZraRFcWb0pu7ok0LqyFhCUrPeMsGRSVop0eemFmo= +github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6 h1:8UsGZ2rr2ksmEru6lToqnXgA8Mz1DP11X4zSJ159C3k= +github.com/jakecoffman/cp v1.2.1 h1:zkhc2Gpo9l4NLUZfeG3j33+3bQD7MkqPa+n5PdX+5mI= +github.com/jakecoffman/cp v1.2.1/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg= +github.com/jfreymuth/oggvorbis v1.0.5 h1:u+Ck+R0eLSRhgq8WTmffYnrVtSztJcYrl588DM4e3kQ= +github.com/jfreymuth/oggvorbis v1.0.5/go.mod h1:1U4pqWmghcoVsCJJ4fRBKv9peUJMBHixthRlBeD6uII= +github.com/jfreymuth/vorbis v1.0.2 h1:m1xH6+ZI4thH927pgKD8JOH4eaGRm18rEE9/0WKjvNE= +github.com/jfreymuth/vorbis v1.0.2/go.mod h1:DoftRo4AznKnShRl1GxiTFCseHr4zR9BN3TWXyuzrqQ= +github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63 h1:3AGKexOYqL+ztdWdkB1bDwXgPBuTS/S8A4WzuTvJ8Cg= +golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63/go.mod h1:UH99kUObWAZkDnWqppdQe5ZhPYESUw8I0zVV1uWBR+0= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60 h1:o4bs4seAAlSiZQAZbO6/RP5XBCZCooQS3Pgc0AUjWts= +golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=