Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: a5b1c24cd7
Fetching contributors…

Cannot retrieve contributors at this time

file 130 lines (110 sloc) 3.076 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
package rog

import (
"fmt"
)

// Console is a double buffered grid of unicode characters that can be rendered to an image.Image.
type Console struct {
bg, fg [][]RGB
ch [][]rune
w, h int
}

// NewConsole creates an empty console.
func NewConsole(width, height int) *Console {
bg := make([][]RGB, height)
fg := make([][]RGB, height)
ch := make([][]rune, height)

for y := 0; y < height; y++ {
bg[y] = make([]RGB, width)
fg[y] = make([]RGB, width)
ch[y] = make([]rune, width)
}

con := &Console{bg, fg, ch, width, height}

for x := 0; x < con.w; x++ {
for y := 0; y < con.h; y++ {
con.bg[y][x] = Black
con.fg[y][x] = White
con.ch[y][x] = ' '
}
}

return con
}

func (con *Console) put(x, y, i, t int, fg, bg Blender, ch rune) {
    if x < 0 || x >= con.w || y < 0 || y >= con.h {
        return
    }

if ch > 0 {
con.ch[y][x] = ch
}

if bg != nil {
con.bg[y][x] = bg.Blend(con.bg[y][x], i, t)
}

if fg != nil {
con.fg[y][x] = fg.Blend(con.bg[y][x], i, t)
}
}

func (con *Console) set(i, j, x, y, w, h int, fg, bg Blender, data string, rest ...interface{}) {
if len(rest) > 0 {
data = fmt.Sprintf(data, rest...)
}
t := len(data)
if t > 0 {
if h == 0 {
h = con.h - y
}
for k, r := range data {
if i == x+w {
j += 1
i = x
}
if j == y+h {
break
}
con.put(i, j, k, t, fg, bg, r)
i += 1
}
} else {
con.put(i, j, 0, 0, fg, bg, -1)
}
}

// Set draws a string starting at x,y onto the console, wrapping at the bounds if needed.
func (con *Console) Set(x, y int, fg, bg Blender, data string, rest ...interface{}) {
con.set(x, y, 0, 0, con.w, con.h, fg, bg, data, rest...)
}

// SetR draws a string starting at x,y onto the console, wrapping at the bounds created by x, y, w, h if needed.
// If h is 0, the text will cut off at the bottom of the console, otherwise it will cut off after the y+h row.
func (con *Console) SetR(x, y, w, h int, fg, bg Blender, data string, rest ...interface{}) {
con.set(x, y, x, y, w, h, fg, bg, data, rest...)
}

// Get returns the fg, bg colors and rune of the cell.
func (con *Console) Get(x, y int) (RGB, RGB, rune) {
return con.fg[y][x], con.bg[y][x], con.ch[y][x]
}

// Fill draws a rect on the root console using ch.
func (con *Console) Fill(x, y, w, h int, fg, bg Blender, ch rune) {
for i := x; i < x+w; i++ {
for j := y; j < y+h; j++ {
con.Set(i, j, fg, bg, string(ch))
}
}
}

// Clear is a short hand to fill the entire screen with the given colors and rune.
func (con *Console) Clear(fg, bg Blender, ch rune) {
con.Fill(0, 0, con.w, con.h, fg, bg, ch)
}

// Blit draws con onto this console with top left starting at x, y.
func (con *Console) Blit(o *Console, x, y int) {
for i := 0; i < o.Width(); i++ {
for j := 0; j < o.Height(); j++ {
fg, bg, ch := o.Get(i, j)
con.Set(x+i, y+j, fg, bg, string(ch))
}
}
}

// Width returns the width of the console in cells.
func (con *Console) Width() int {
return con.w
}

// Height returns the height of the console in cells.
func (con *Console) Height() int {
return con.h
}
Something went wrong with that request. Please try again.