package main import ( "embed" "fmt" "image" "image/color" "io" "github.com/clktmr/n64/drivers/cartfs" "github.com/clktmr/n64/drivers/controller" "github.com/clktmr/n64/drivers/display" "github.com/clktmr/n64/drivers/draw" "github.com/clktmr/n64/drivers/rspq/mixer" "github.com/clktmr/n64/fonts/gomono12" _ "github.com/clktmr/n64/machine" "github.com/clktmr/n64/rcp/audio" "github.com/clktmr/n64/rcp/serial/joybus" "github.com/clktmr/n64/rcp/texture" "github.com/clktmr/n64/rcp/video" ) var ( //go:embed gopher-anim.CI8 squeak.pcm_s16be _tutorialFiles embed.FS tutorialFiles cartfs.FS = cartfs.Embed(_tutorialFiles) ) var face = gomono12.NewFace() var background = &image.Uniform{color.RGBA{0x7f, 0x7f, 0xaf, 0x0}} func main() { // Enable video output video.Setup(false) // Allocate framebuffer display := display.NewDisplay(image.Pt(320, 240), video.BPP16) controllers := make(chan [4]controller.Controller) go func() { var states [4]controller.Controller for { controller.Poll(&states) controllers <- states } }() gopherFile, err := tutorialFiles.Open("gopher-anim.CI8") if err != nil { panic(err) } gopherTexture, err := texture.Load(gopherFile) if err != nil { panic(err) } gopherRect := image.Rect(0, 0, 128, 128) blows := 0 audio.Start(48000) mixer.Init() go func() { audio.Buffer.ReadFrom(mixer.Output) }() squeakFile, err := tutorialFiles.Open("squeak.pcm_s16be") if err != nil { panic(err) } squeakReader := squeakFile.(io.ReadSeeker) squeakSource := mixer.NewSource(squeakReader, 16000) for { fb := display.Swap() // Blocks until next VBlank input := <-controllers textarea := fb.Bounds().Inset(15) pt := textarea.Min.Add(image.Pt(0, int(face.Ascent))) draw.Src.Draw(fb, fb.Bounds(), background, fb.Bounds().Min) text := fmt.Appendln(nil, "N⁶⁴ - Get N or Get Out ♫") text = fmt.Appendln(text, input[0].Down()) text = fmt.Appendf(text, "blows: %v/8\n", blows) pt = draw.DrawText(fb, textarea, face, pt, image.Black, nil, text) gopherFrame := image.Point{} if blows < 8 { if input[0].Pressed()&joybus.ButtonA != 0 { blows++ squeakReader.Seek(0, io.SeekStart) mixer.SetSource(0, squeakSource) } if input[0].Down()&joybus.ButtonA != 0 { gopherFrame.X += 128 // blowing gopher } } else { gopherFrame.X += 256 // happy gopher } draw.Over.Draw(fb, gopherRect.Add(pt), gopherTexture, gopherFrame) draw.Flush() // Blocks until everything is drawn } }