Added rendering stuff, updated go mod
This commit is contained in:
parent
f7eaa0d08d
commit
d426892e6a
|
@ -0,0 +1,11 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sshpong/internal/renderer"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Starting renderer")
|
||||||
|
renderer.Render()
|
||||||
|
}
|
55
flake.lock
55
flake.lock
|
@ -18,6 +18,45 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-utils_2": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1694529238,
|
||||||
|
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gomod2nix": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils_2",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1722589758,
|
||||||
|
"narHash": "sha256-sbbA8b6Q2vB/t/r1znHawoXLysCyD4L/6n6/RykiSnA=",
|
||||||
|
"owner": "tweag",
|
||||||
|
"repo": "gomod2nix",
|
||||||
|
"rev": "4e08ca09253ef996bd4c03afa383b23e35fe28a1",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "tweag",
|
||||||
|
"repo": "gomod2nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1722421184,
|
"lastModified": 1722421184,
|
||||||
|
@ -37,6 +76,7 @@
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
|
"gomod2nix": "gomod2nix",
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -54,6 +94,21 @@
|
||||||
"repo": "default",
|
"repo": "default",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"systems_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|
|
@ -2,15 +2,22 @@
|
||||||
description = "An example project using flutter";
|
description = "An example project using flutter";
|
||||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
inputs.gomod2nix = {
|
||||||
|
url = "github:tweag/gomod2nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.utils.follows = "utils";
|
||||||
|
};
|
||||||
outputs = {
|
outputs = {
|
||||||
self,
|
self,
|
||||||
flake-utils,
|
flake-utils,
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
|
gomod2nix,
|
||||||
...
|
...
|
||||||
} @ inputs:
|
} @ inputs:
|
||||||
flake-utils.lib.eachDefaultSystem (system: let
|
flake-utils.lib.eachDefaultSystem (system: let
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
|
overlays = [ gomod2nix.overlays.default ];
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
devShell = pkgs.mkShell {
|
devShell = pkgs.mkShell {
|
||||||
|
@ -19,6 +26,8 @@
|
||||||
gopls
|
gopls
|
||||||
gotools
|
gotools
|
||||||
go-tools
|
go-tools
|
||||||
|
gomod2nix.packages.${system}.default
|
||||||
|
sqlite-interactive
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -5,4 +5,6 @@ go 1.22.2
|
||||||
require (
|
require (
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
google.golang.org/protobuf v1.34.2
|
google.golang.org/protobuf v1.34.2
|
||||||
|
golang.org/x/sys v0.23.0 // indirect
|
||||||
|
golang.org/x/term v0.22.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -2,3 +2,7 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||||
|
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
|
||||||
|
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
||||||
|
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
||||||
|
|
15
gomod2nix.toml
Normal file
15
gomod2nix.toml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
schema = 3
|
||||||
|
|
||||||
|
[mod]
|
||||||
|
[mod."github.com/google/uuid"]
|
||||||
|
version = "v1.6.0"
|
||||||
|
hash = "sha256-VWl9sqUzdOuhW0KzQlv0gwwUQClYkmZwSydHG2sALYw="
|
||||||
|
[mod."golang.org/x/sys"]
|
||||||
|
version = "v0.23.0"
|
||||||
|
hash = "sha256-tC6QVLu72bADgINz26FUGdmYqKgsU45bHPg7sa0ZV7w="
|
||||||
|
[mod."golang.org/x/term"]
|
||||||
|
version = "v0.22.0"
|
||||||
|
hash = "sha256-tRx/y4ZIZzGAlDJ/8JW3AycC9bRXlNuRqO4V48sAEEc="
|
||||||
|
[mod."google.golang.org/protobuf"]
|
||||||
|
version = "v1.34.2"
|
||||||
|
hash = "sha256-nMTlrDEE2dbpWz50eQMPBQXCyQh4IdjrTIccaU0F3m0="
|
135
internal/ansii/ansii.go
Normal file
135
internal/ansii/ansii.go
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
package ansii
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/term"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ANSI string
|
||||||
|
|
||||||
|
const (
|
||||||
|
reset ANSI = "\033[0m"
|
||||||
|
plain ANSI = ""
|
||||||
|
bold ANSI = "\033[1m"
|
||||||
|
underline ANSI = "\033[4m"
|
||||||
|
black ANSI = "\033[30m"
|
||||||
|
red ANSI = "\033[31m"
|
||||||
|
green ANSI = "\033[32m"
|
||||||
|
yellow ANSI = "\033[33m"
|
||||||
|
blue ANSI = "\033[34m"
|
||||||
|
purple ANSI = "\033[35m"
|
||||||
|
cyan ANSI = "\033[36m"
|
||||||
|
white ANSI = "\033[37m"
|
||||||
|
blackBg ANSI = "\033[40m"
|
||||||
|
redBg ANSI = "\033[41m"
|
||||||
|
greenBg ANSI = "\033[42m"
|
||||||
|
yellowBg ANSI = "\033[43m"
|
||||||
|
blueBg ANSI = "\033[44m"
|
||||||
|
purpleBg ANSI = "\033[45m"
|
||||||
|
cyanBg ANSI = "\033[46m"
|
||||||
|
whiteBg ANSI = "\033[47m"
|
||||||
|
clearScreen ANSI = "\033[2J"
|
||||||
|
hideCursor ANSI = "\033[?25l"
|
||||||
|
showCursor ANSI = "\033[?25h"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Offset struct {
|
||||||
|
X int
|
||||||
|
Y int
|
||||||
|
}
|
||||||
|
|
||||||
|
type style struct {
|
||||||
|
Reset ANSI
|
||||||
|
Plain ANSI
|
||||||
|
Bold ANSI
|
||||||
|
Underline ANSI
|
||||||
|
}
|
||||||
|
|
||||||
|
type color struct {
|
||||||
|
Black ANSI
|
||||||
|
Red ANSI
|
||||||
|
Green ANSI
|
||||||
|
Yellow ANSI
|
||||||
|
Blue ANSI
|
||||||
|
Purple ANSI
|
||||||
|
Cyan ANSI
|
||||||
|
White ANSI
|
||||||
|
}
|
||||||
|
|
||||||
|
type screen struct {
|
||||||
|
ClearScreen ANSI
|
||||||
|
HideCursor ANSI
|
||||||
|
ShowCursor ANSI
|
||||||
|
}
|
||||||
|
|
||||||
|
type ascii struct {
|
||||||
|
Block string
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTermSize() (width int, height int) {
|
||||||
|
var fd int = int(os.Stdout.Fd())
|
||||||
|
width, height, err := term.GetSize(fd)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(string(Screen.ClearScreen) + "Fatal: error getting terminal size.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return width, height
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeTermRaw() (*term.State, error) {
|
||||||
|
var fd int = int(os.Stdout.Fd())
|
||||||
|
return term.MakeRaw(fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RestoreTerm(prev *term.State) error {
|
||||||
|
var fd int = int(os.Stdout.Fd())
|
||||||
|
return term.Restore(fd, prev)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s screen) PlaceCursor(offset Offset) ANSI {
|
||||||
|
return ANSI(fmt.Sprintf("\033[%d;%dH", offset.Y, offset.X))
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
Styles = style{Bold: bold, Underline: underline, Reset: reset, Plain: plain}
|
||||||
|
Colors = color{Red: red, Green: green, Yellow: yellow, Blue: blue, Purple: purple, Cyan: cyan, White: white}
|
||||||
|
Screen = screen{ClearScreen: clearScreen, HideCursor: hideCursor, ShowCursor: showCursor}
|
||||||
|
Blocks = ascii{Block: "█"}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Draws a box of dimensions `height` and `width` at `offset`.
|
||||||
|
// The `offset` is the top left cell of the square.
|
||||||
|
// Blocks that would be placed off screen are clipped.
|
||||||
|
func DrawBox(builder *strings.Builder, offset Offset, height int, width int, style ANSI) {
|
||||||
|
builder.WriteString(string(style))
|
||||||
|
for hIdx := 0; hIdx < height; hIdx++ {
|
||||||
|
|
||||||
|
if hIdx == 0 || hIdx == height-1 {
|
||||||
|
for wIdx := 0; wIdx < width; wIdx++ {
|
||||||
|
DrawPixel(builder, Offset{X: offset.X + wIdx, Y: offset.Y + hIdx})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DrawPixel(builder, Offset{X: offset.X, Y: offset.Y + hIdx})
|
||||||
|
DrawPixel(builder, Offset{X: offset.X + width - 1, Y: offset.Y + hIdx})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.WriteString(string(Styles.Reset))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func DrawPixel(builder *strings.Builder, offset Offset) {
|
||||||
|
termWidth, termHeight := GetTermSize()
|
||||||
|
if offset.X > termWidth || offset.Y > termHeight || offset.X < 0 || offset.Y < 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
builder.WriteString(string(Screen.PlaceCursor(offset) + ANSI(Blocks.Block)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func DrawPixelStyle(builder *strings.Builder, offset Offset, style ANSI) {
|
||||||
|
builder.WriteString(string(style))
|
||||||
|
DrawPixel(builder, offset)
|
||||||
|
builder.WriteString(string(Styles.Reset))
|
||||||
|
}
|
|
@ -1,7 +1,195 @@
|
||||||
package renderer
|
package renderer
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sshpong/internal/ansii"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
func render() {
|
var (
|
||||||
fmt.Println("Test")
|
targetFps float64 = 60.0
|
||||||
|
targetFpMilli float64 = float64(targetFps) / 1000.0
|
||||||
|
millisecondTimeFrame float64 = float64(1 / targetFpMilli)
|
||||||
|
quit chan bool
|
||||||
|
userInput chan rune
|
||||||
|
playerX int = 10
|
||||||
|
playerY int = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
func Render() {
|
||||||
|
now := time.Now()
|
||||||
|
err := doFpsTest()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
then := time.Now()
|
||||||
|
|
||||||
|
total := float64(float64(then.UnixMicro()-now.UnixMicro()) / 1000.0)
|
||||||
|
fmt.Printf("\n\nTook %.3f milliseconds\n", total)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeCheckerBoard(height int, width int, builder *strings.Builder) {
|
||||||
|
for i := 0; i < height; i++ {
|
||||||
|
for j := 0; j < width; j++ {
|
||||||
|
if i%2 == 0 {
|
||||||
|
if j%2 == 0 {
|
||||||
|
builder.WriteString("█")
|
||||||
|
} else {
|
||||||
|
|
||||||
|
builder.WriteString(" ")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if j%2 == 0 {
|
||||||
|
builder.WriteString(" ")
|
||||||
|
} else {
|
||||||
|
builder.WriteString("█")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawScreen(frameNum int, startMs float64) (frameTimeMs float64) {
|
||||||
|
_ = frameNum
|
||||||
|
_, height := ansii.GetTermSize()
|
||||||
|
var builder = strings.Builder{}
|
||||||
|
builder.WriteString(string(ansii.Screen.ClearScreen))
|
||||||
|
// writeCheckerBoard(height, width, &builder)
|
||||||
|
// var xOffset = frameNum % width
|
||||||
|
// ansii.DrawBox(&builder, ansii.Offset{X: 0, Y: 0}, 5, 8, ansii.Colors.Purple)
|
||||||
|
ansii.DrawBox(&builder, ansii.Offset{X: playerX, Y: playerY}, 5, 1, ansii.Colors.Cyan)
|
||||||
|
ansii.DrawPixelStyle(&builder, ansii.Offset{X: playerX, Y: playerY}, ansii.Colors.Purple)
|
||||||
|
ansii.DrawPixelStyle(&builder, ansii.Offset{X: playerX, Y: playerY + 5}, ansii.Colors.Purple)
|
||||||
|
// Quit instructions
|
||||||
|
builder.WriteString(string(ansii.Screen.PlaceCursor(ansii.Offset{X: 0, Y: height})))
|
||||||
|
builder.WriteString("q to quit")
|
||||||
|
|
||||||
|
os.Stdout.WriteString(builder.String())
|
||||||
|
var frameTimeMilli = (float64(time.Now().UnixNano()) / 1_000_000.0) - startMs
|
||||||
|
// builder.WriteString(string(ansii.Screen.Coordinate(0, 0)))
|
||||||
|
return frameTimeMilli
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawFrameStats(frameNum int, frameTimeMs float64) {
|
||||||
|
width, height := ansii.GetTermSize()
|
||||||
|
var spareTimeMilli = millisecondTimeFrame - frameTimeMs
|
||||||
|
os.Stdout.WriteString(string(ansii.Screen.PlaceCursor(ansii.Offset{X: width - 12, Y: height - 2})))
|
||||||
|
os.Stdout.WriteString(fmt.Sprintf("Frame #: %d", frameNum))
|
||||||
|
os.Stdout.WriteString(string(ansii.Screen.PlaceCursor(ansii.Offset{X: width - 19, Y: height - 1})))
|
||||||
|
os.Stdout.WriteString(fmt.Sprintf("Frame Time: %.4fms", frameTimeMs))
|
||||||
|
os.Stdout.WriteString(string(ansii.Screen.PlaceCursor(ansii.Offset{X: width - 20, Y: height})))
|
||||||
|
os.Stdout.WriteString(fmt.Sprintf("Spare Time: %.4fms", spareTimeMilli))
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleInput(rawInput rune) {
|
||||||
|
action := ProcessInput(rawInput)
|
||||||
|
width, height := ansii.GetTermSize()
|
||||||
|
|
||||||
|
switch action {
|
||||||
|
case Quit:
|
||||||
|
fmt.Println("Quitting...")
|
||||||
|
close(quit)
|
||||||
|
case Left, LeftArrow:
|
||||||
|
playerX = max(playerX-1, 0)
|
||||||
|
case Right, RightArrow:
|
||||||
|
playerX = min(playerX+1, width)
|
||||||
|
case Up, UpArrow:
|
||||||
|
playerY = max(playerY-1, 0)
|
||||||
|
case Down, DownArrow:
|
||||||
|
playerY = min(playerY+1, height)
|
||||||
|
case Unknown:
|
||||||
|
default:
|
||||||
|
os.Stdout.WriteString(string(ansii.Screen.PlaceCursor(ansii.Offset{X: 0, Y: height - 2})))
|
||||||
|
os.Stdout.WriteString("Unrecognized Input: " + string(action))
|
||||||
|
close(quit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func waitForFpsLock(startMs float64) {
|
||||||
|
for {
|
||||||
|
var nowMs = float64(time.Now().UnixNano()) / 1_000_000.0
|
||||||
|
if nowMs-startMs >= millisecondTimeFrame {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func doFpsTest() error {
|
||||||
|
prev, err := ansii.MakeTermRaw()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer ansii.RestoreTerm(prev)
|
||||||
|
quit = make(chan bool, 1)
|
||||||
|
userInput = make(chan rune, 1)
|
||||||
|
|
||||||
|
// User input loop
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
buf := make([]byte, 3)
|
||||||
|
n, err := os.Stdin.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error reading from stdin: %v\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if n > 0 {
|
||||||
|
if buf[0] == 0x1b { // ESC
|
||||||
|
if n > 1 && buf[1] == '[' { // ESC [
|
||||||
|
switch buf[2] {
|
||||||
|
case 'A':
|
||||||
|
userInput <- '↑' // Up arrow
|
||||||
|
case 'B':
|
||||||
|
userInput <- '↓' // Down arrow
|
||||||
|
case 'C':
|
||||||
|
userInput <- '→' // Right arrow
|
||||||
|
case 'D':
|
||||||
|
userInput <- '←' // Left arrow
|
||||||
|
default:
|
||||||
|
userInput <- '?'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
userInput <- '?'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r, _ := utf8.DecodeRune(buf)
|
||||||
|
userInput <- r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
// Rendering loop
|
||||||
|
go func() {
|
||||||
|
for i := 0; i <= 10_000; i++ {
|
||||||
|
startMs := float64(time.Now().UnixNano()) / 1_000_000.0
|
||||||
|
select {
|
||||||
|
case <-quit:
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
frameTimeMs := drawScreen(i, startMs)
|
||||||
|
drawFrameStats(i, frameTimeMs)
|
||||||
|
waitForFpsLock(startMs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(quit)
|
||||||
|
}()
|
||||||
|
|
||||||
|
os.Stdout.WriteString(string(ansii.Screen.HideCursor))
|
||||||
|
defer os.Stdout.WriteString(string(ansii.Screen.ShowCursor))
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-quit:
|
||||||
|
fmt.Println("Exiting")
|
||||||
|
return nil
|
||||||
|
// case ui := <-userInput:
|
||||||
|
case input := <-userInput:
|
||||||
|
handleInput(input)
|
||||||
|
// fmt.Println(ui)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
25
internal/renderer/user_inputs.go
Normal file
25
internal/renderer/user_inputs.go
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package renderer
|
||||||
|
|
||||||
|
type UiAction rune
|
||||||
|
|
||||||
|
const (
|
||||||
|
Unknown UiAction = iota
|
||||||
|
Quit UiAction = 81 // 'Q'
|
||||||
|
Left UiAction = 65
|
||||||
|
Up UiAction = 87
|
||||||
|
Right UiAction = 68
|
||||||
|
Down UiAction = 83
|
||||||
|
LeftArrow UiAction = 8592
|
||||||
|
UpArrow UiAction = 8593
|
||||||
|
RightArrow UiAction = 8594
|
||||||
|
DownArrow UiAction = 8595
|
||||||
|
)
|
||||||
|
|
||||||
|
func ProcessInput(rawInput rune) (action UiAction) {
|
||||||
|
inputVal := int(rawInput)
|
||||||
|
// Convert to UpperCase
|
||||||
|
if inputVal >= 97 && inputVal <= 122 {
|
||||||
|
inputVal = inputVal - 32
|
||||||
|
}
|
||||||
|
return UiAction(inputVal)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user