Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a testpattern proof #37

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions internal/cops/display/terminal.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package display

import (
"io"
"log"
"os"

"github.com/borkshop/bork/internal/cops/terminal"
Expand All @@ -11,22 +12,22 @@ import (
type Terminal struct {
*Display

out *os.File
term terminal.Terminal
model ColorModel
buf []byte
cur Cursor
ColorModel ColorModel
out *os.File
term terminal.Terminal
buf []byte
cur Cursor
}

// NewTerminal takes control of a terminal, readying it for rendering by
// putting it in raw mode, clearing it, and hiding the cursor.
func NewTerminal(out *os.File) (*Terminal, error) {
term := &Terminal{
out: out,
term: terminal.New(out.Fd()),
model: Model24, // TODO #choices
buf: make([]byte, 0, 65536),
cur: Start,
out: out,
term: terminal.New(out.Fd()),
ColorModel: Model24, // TODO #choices
buf: make([]byte, 0, 65536),
cur: Start,
}
return term, term.open()
}
Expand Down Expand Up @@ -74,10 +75,12 @@ func (term *Terminal) flush() error {
}
attempts := 5 // TODO sanity check: is this even worthwhile?
n, err := term.out.Write(term.buf)
log.Printf("display.Terminal flushed %q", term.buf[:n])
for attempts > 1 && err == io.ErrShortWrite {
attempts--
term.buf = term.buf[:copy(term.buf, term.buf[n:])]
n, err = term.out.Write(term.buf)
log.Printf("display.Terminal flushed %q", term.buf[:n])
}
term.buf = term.buf[:0]
return err
Expand All @@ -96,7 +99,7 @@ func (term *Terminal) UpdateSize() error {
}

func (term Terminal) fullRender(cur Cursor, buf []byte) ([]byte, Cursor) {
return Render(buf, cur, term.Display, term.model)
return Render(buf, cur, term.Display, term.ColorModel)
}

// Render the display buffer to the terminal.
Expand Down
148 changes: 148 additions & 0 deletions proofs/testpattern/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package main

import (
"fmt"
"image/color"
"log"
"os"
"os/signal"
"strconv"
"syscall"

"github.com/borkshop/bork/internal/cops/display"
"github.com/borkshop/bork/internal/input"
)

func colorGB(x, y int) (f, b color.RGBA) {
f.A = 0xff
b.A = 0xff
f.G += uint8(y)
b.B += uint8(x)
return f, b
}

func colorEights(x, y int) (f, b color.RGBA) {
return display.Colors[y%8], display.Colors[x%8]
}

type xyColorFunc func(x, y int) (f, b color.RGBA)

func fgOnly(cf xyColorFunc) xyColorFunc {
return func(x, y int) (f, b color.RGBA) {
f, _ = cf(x, y)
b = display.Colors[0]
return f, b
}
}

func bgOnly(cf xyColorFunc) xyColorFunc {
return func(x, y int) (f, b color.RGBA) {
_, b = cf(x, y)
f = display.Colors[7]
return f, b
}
}

func run() (rerr error) {
f, err := os.Create("debug.log")
if err != nil {
return err
}
log.SetOutput(f)

term, err := display.NewTerminal(os.Stdout)
if err != nil {
return err
}
defer func() {
if cerr := term.Close(); rerr == nil {
rerr = cerr
}
}()

commands, mute := input.Channel(os.Stdin)
defer mute()

sigwinch := make(chan os.Signal)
signal.Notify(sigwinch, syscall.SIGWINCH)

var colorFunc xyColorFunc = colorGB

for {
sz := term.Display.Rect.Size()
for y := 0; y < sz.Y; y++ {
for x := 0; x < sz.X; x++ {
t := strconv.Itoa(y % 10)
f, b := colorFunc(x, y)
term.Display.SetRGBA(x, y, t, f, b)
// term.Display.Set(x, y, t, nil, nil)
}
}

if err := term.Render(); err != nil {
return err
}

select {
case <-sigwinch:
if err := term.UpdateSize(); err != nil {
return err
}
log.Printf("display resized to %v", term.Bounds())

case command := <-commands:
switch c := command.(type) {
case rune:
switch c {
case 'q':
colorFunc = colorEights
log.Printf("using colorFunc = colorEights")
case 'w':
colorFunc = colorGB
log.Printf("using colorFunc = colorGB")
case 'a':
colorFunc = fgOnly(colorEights)
log.Printf("using colorFunc = fgOnly(colorEights)")
case 's':
colorFunc = fgOnly(colorGB)
log.Printf("using colorFunc = fgOnly(colorGB)")
case 'z':
colorFunc = bgOnly(colorEights)
log.Printf("using colorFunc = bgOnly(colorEights)")
case 'x':
colorFunc = bgOnly(colorGB)
log.Printf("using colorFunc = bgOnly(colorGB)")

case '1':
term.ColorModel = display.Model0
log.Printf("using ColorModel = Model0")
case '2':
term.ColorModel = display.Model3
log.Printf("using ColorModel = Model3")
case '3':
term.ColorModel = display.Model4
log.Printf("using ColorModel = Model4")
case '4':
term.ColorModel = display.Model8
log.Printf("using ColorModel = Model8")
case '5':
term.ColorModel = display.Model24
log.Printf("using ColorModel = Model24")
case '6':
term.ColorModel = display.ModelCompat24
log.Printf("using ColorModel = ModelCompat24")

case '', '':
return nil
}
}
}

}
}

func main() {
if err := run(); err != nil {
fmt.Printf("%v\n", err)
}
}