commit fea20558ac615af98d326d214fc635561ae8006c Author: Sasha Koshka Date: Mon Oct 31 15:51:28 2022 -0400 Initial commit diff --git a/application.go b/application.go new file mode 100644 index 0000000..4af336b --- /dev/null +++ b/application.go @@ -0,0 +1,89 @@ +package stone + +import "time" +import "image/color" + +type Application struct { + DamageBuffer + + title string + backend Backend + config Config +} + +func (application *Application) SetSize (width, height int) { + application.DamageBuffer.SetSize(width, height) + // application.updateWindowSize() +} + +func (application *Application) SetTitle (title string) { + application.title = title + application.backend.SetTitle(title) +} + +func (application *Application) Run (callback func (application *Application)) { + // default values for certain parameters + width, height := application.Size() + if width < 1 { width = 80 } + if height < 1 { height = 20 } + application.DamageBuffer.SetSize(width, height) + + // TODO: load these from a file + application.config.colors = [4]color.Color { + color.RGBA { R: 0x00, G: 0x00, B: 0x00, A: 0xFF }, + color.RGBA { R: 0xFF, G: 0xFF, B: 0xFF, A: 0xFF }, + color.RGBA { R: 0x00, G: 0x00, B: 0x00, A: 0xFF }, + color.RGBA { R: 0xFF, G: 0xFF, B: 0xFF, A: 0xFF }, + } + + application.backend.Run(callback) +} + +func (application *Application) Await (timeout time.Duration) (keepRunning bool) { + keepRunning = application.Await(timeout) + return +} + +func (application *Application) Poll () (keepRunning bool) { + keepRunning = application.Poll() + return +} + +func (application *Application) Title () (title string) { + title = application.title + return +} + +func (application *Application) Config () (config *Config) { + config = &application.config + return +} + +// func (application *Application) Resized () (resized bool) { + // resized = application.boundsDirty + // return +// } + + +// // updateWindowSize updates the window size according to the buffer size. +// func (application *Application) updateWindowSize () { + // if application.window == nil { return } + // application.window.SetBounds(application.calculateWindowSize()) +// } + +// updateBufferSize updats the buffer size according to the window size. +// func (application *Application) updateBufferSize () { + // if application.window == nil { + // panic("call to application.updateBufferSize before window exists") + // } + // + // windowBounds := application.window.Bounds().Max + // + // if windowBounds != application.previousBounds { + // application.previousBounds = windowBounds + // application.boundsDirty = true + // application.DamageBuffer.SetSize ( + // int(windowBounds.X) / application.metrics.cellWidth, + // int(windowBounds.Y) / application.metrics.cellHeight) + // } +// } diff --git a/backend.go b/backend.go new file mode 100644 index 0000000..05832e5 --- /dev/null +++ b/backend.go @@ -0,0 +1,41 @@ +package stone + +import "time" +import "errors" + +type Backend interface { + Run (callback func (application *Application)) () + Await (timeout time.Duration) (keepRunning bool) + Poll () (keepRunning bool) + SetTitle (title string) + JustPressed (button Button) (pressed bool) + JustReleased (button Button) (released bool) + Pressed (button Button) (pressed bool) + Repeated (button Button) (repeated bool) + Typed () (text string) + Resized () (resized bool) +} + +type BackendFactory func (application *Application) (backend Backend, err error) + +var factories []BackendFactory + +func RegisterBackend (factory BackendFactory) { + factories = append(factories, factory) +} + +func instantiateBackend (application *Application) (backend Backend, err error) { + // find a suitable backend + for _, factory := range factories { + backend, err = factory(application) + if err == nil && backend != nil { return } + } + + // if none were found, but there was no error produced, produce an + // error + if err == nil { + err = errors.New("no available backends") + } + + return +} diff --git a/backends/pixel/pixel.go b/backends/pixel/pixel.go new file mode 100644 index 0000000..21bff3f --- /dev/null +++ b/backends/pixel/pixel.go @@ -0,0 +1,146 @@ +package pixel + +import "time" +import "golang.org/x/image/font" +import "github.com/faiface/pixel" +import "github.com/faiface/pixel/pixelgl" +import "golang.org/x/image/font/basicfont" +import "git.tebibyte.media/sashakoshka/stone" + +type Backend struct { + window *pixelgl.Window + boundsDirty bool + previousBounds pixel.Vec + fontFace font.Face + application *stone.Application + config *stone.Config + + metrics struct { + cellWidth int + cellHeight int + } +} + +func (backend *Backend) Run (callback func (application *stone.Application)) { + if backend.fontFace == nil { + backend.fontFace = basicfont.Face7x13 + } + + faceMetrics := backend.fontFace.Metrics() + backend.metrics.cellHeight = faceMetrics.Height.Round() + // FIXME?: this might not be the best way to get the cell width + faceAdvance, ok := backend.fontFace.GlyphAdvance('M') + if ok { + backend.metrics.cellWidth = faceAdvance.Round() + } else { + backend.metrics.cellWidth = backend.metrics.cellHeight / 2 + } + + pixelgl.Run (func () { + var err error + backend.window, err = pixelgl.NewWindow (pixelgl.WindowConfig { + Resizable: true, + Undecorated: true, + VSync: true, + NoIconify: true, + Title: backend.application.Title(), + Bounds: backend.calculateWindowSize(), + }) + backend.Poll() + + if err != nil { panic(err.Error()) } + callback(backend.application) + }) +} + +func (backend *Backend) Await (timeout time.Duration) (keepRunning bool) { + if backend.window == nil { + panic("call to Backend.Await before window exists") + } + + backend.draw() + backend.window.UpdateInputWait(timeout) + backend.processEvents() + keepRunning = !backend.window.Closed() + return +} + +func (backend *Backend) Poll () (keepRunning bool) { + if backend.window == nil { + panic("call to Backend.Poll before window exists") + } + + backend.draw() + backend.window.UpdateInput() + backend.processEvents() + keepRunning = !backend.window.Closed() + return +} + +func (backend *Backend) SetTitle (title string) { + if backend.window != nil { + backend.window.SetTitle(title) + } +} + +func (backend *Backend) draw () { + didDrawing := false + + if backend.boundsDirty { + backend.window.Clear ( + backend.config.Color(stone.ColorApplication)) + backend.boundsDirty = false + didDrawing = true + } else { + // TODO: clear out dirty cells before drawing them (we don't + // want to clear them out if we have already just cleared + // everything out) + + + } + + // TODO: draw dirty cells. + width, height := backend.application.Size() + for x := 0; x < width; x ++ { + for y := 0; y < height; y ++ { + clean := backend.application.Clean(x, y) + // cell := application.content[index] + if clean { continue } + + // draw cell + + didDrawing = true // TODO: set didDrawing up there ^ + backend.application.MarkClean(x, y) + } + } + + if didDrawing { + backend.window.SwapBuffers() + } +} + +func (backend *Backend) processEvents () { + +} + +func (backend *Backend) calculateWindowSize () (bounds pixel.Rect) { + width, height := backend.application.Size() + bounds = pixel.R ( + 0, 0, + float64(width * backend.metrics.cellWidth), + float64(height * backend.metrics.cellHeight)) + return +} + +func factory (application *stone.Application) (output stone.Backend, err error) { + backend := &Backend { + application: application, + config: application.Config(), + } + output = backend + return +} + +func init () { + stone.RegisterBackend(factory) +} diff --git a/buffer.go b/buffer.go new file mode 100644 index 0000000..55145b8 --- /dev/null +++ b/buffer.go @@ -0,0 +1,109 @@ +package stone + +type Color uint8 + +const ( + ColorBackground Color = 0x0 + ColorSelection Color = 0x1 + ColorForeground Color = 0x2 + ColorApplication Color = 0x3 +) + +type Style uint8 + +const ( + StyleNormal Style = iota + StyleBold Style = iota >> 1 + StyleItalic + StyleBoldItalic Style = StyleBold | StyleItalic +) + +type Cell struct { + color Color + style Style + content rune +} + +func (cell Cell) Color (color Color) { + color = cell.color + return +} + +func (cell Cell) Style (style Style) { + style = cell.style + return +} + +func (cell Cell) Rune (content rune) { + content = cell.content + return +} + +type Buffer struct { + content []Cell + width int + height int +} + +func (buffer *Buffer) Size () (width, height int) { + width = buffer.width + height = buffer.height + return +} + +func (buffer *Buffer) SetSize (width, height int) { + buffer.width = width + buffer.height = height + buffer.content = make([]Cell, width * height) +} + +func (buffer *Buffer) Cell (x, y int) (cell Cell) { + cell = buffer.content[x + y * buffer.width] + return +} + +func (buffer *Buffer) SetColor (x, y int, color Color) { + buffer.content[x + y * buffer.width].color = color +} + +func (buffer *Buffer) SetStyle (x, y int, style Style) { + buffer.content[x + y * buffer.width].style = style +} + +func (buffer *Buffer) SetRune (x, y int, content rune) { + buffer.content[x + y * buffer.width].content = content +} + +type DamageBuffer struct { + Buffer + clean []bool +} + +func (buffer *DamageBuffer) SetSize (width, height int) { + buffer.Buffer.SetSize(width, height) + buffer.clean = make([]bool, width * height) +} + +func (buffer *DamageBuffer) SetColor (x, y int, color Color) { + buffer.Buffer.SetColor(x, y, color) + buffer.clean[x + y * buffer.width] = false +} + +func (buffer *DamageBuffer) SetStyle (x, y int, style Style) { + buffer.Buffer.SetStyle(x, y, style) + buffer.clean[x + y * buffer.width] = false +} + +func (buffer *DamageBuffer) SetRune (x, y int, content rune) { + buffer.Buffer.SetRune(x, y, content) + buffer.clean[x + y * buffer.width] = false +} + +func (buffer *DamageBuffer) Clean (x, y int) (clean bool) { + clean = buffer.clean[x + y * buffer.width] + return +} + +func (buffer *DamageBuffer) MarkClean (x, y int) { + buffer.clean[x + y * buffer.width] = true +} diff --git a/config.go b/config.go new file mode 100644 index 0000000..c203153 --- /dev/null +++ b/config.go @@ -0,0 +1,30 @@ +package stone + +import "image/color" + +type Config struct { + colors [4]color.Color + padding int + fontSize int + fontName string +} + +func (config *Config) Color (index Color) (value color.Color) { + value = config.colors[index] + return +} + +func (config *Config) Padding () (padding int) { + padding = config.padding + return +} + +func (config *Config) FontSize () (fontSize int) { + fontSize = config.fontSize + return +} + +func (config *Config) FontName () (fontName string) { + fontName = config.fontName + return +} diff --git a/examples/hello/main.go b/examples/hello/main.go new file mode 100644 index 0000000..e9439ec --- /dev/null +++ b/examples/hello/main.go @@ -0,0 +1,27 @@ +package main + +import "git.tebibyte.media/sashakoshka/stone" +import _ "git.tebibyte.media/sashakoshka/stone/backends/pixel" + +func main () { + application := stone.Application { } + application.Run(run) +} + +func run (application *stone.Application) { + for application.Await(0) { + if application.Resized() { + application.SetRune(0, 0, 'h') + application.SetRune(1, 0, 'e') + application.SetRune(2, 0, 'l') + application.SetRune(3, 0, 'l') + application.SetRune(4, 0, 'o') + application.SetRune(5, 0, 'r') + application.SetRune(6, 0, 'l') + application.SetRune(7, 0, 'd') + application.SetRune(8, 0, '!') + application.SetRune(4, 4, ':') + application.SetRune(5, 4, '3') + } + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..a697e8f --- /dev/null +++ b/go.mod @@ -0,0 +1,15 @@ +module git.tebibyte.media/sashakoshka/stone + +go 1.19 + +require github.com/faiface/pixel v0.10.0 + +require ( + github.com/faiface/glhf v0.0.0-20181018222622-82a6317ac380 // indirect + github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 // indirect + github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 // indirect + github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72 // indirect + github.com/go-gl/mathgl v0.0.0-20190416160123-c4601bc793c7 // indirect + github.com/pkg/errors v0.8.1 // indirect + golang.org/x/image v0.0.0-20190523035834-f03afa92d3ff // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..6f3f951 --- /dev/null +++ b/go.sum @@ -0,0 +1,26 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/faiface/glhf v0.0.0-20181018222622-82a6317ac380 h1:FvZ0mIGh6b3kOITxUnxS3tLZMh7yEoHo75v3/AgUqg0= +github.com/faiface/glhf v0.0.0-20181018222622-82a6317ac380/go.mod h1:zqnPFFIuYFFxl7uH2gYByJwIVKG7fRqlqQCbzAnHs9g= +github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= +github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3/go.mod h1:VEPNJUlxl5KdWjDvz6Q1l+rJlxF2i6xqDeGuGAxa87M= +github.com/faiface/pixel v0.10.0 h1:EHm3ZdQw2Ck4y51cZqFfqQpwLqNHOoXwbNEc9Dijql0= +github.com/faiface/pixel v0.10.0/go.mod h1:lU0YYcW77vL0F1CG8oX51GXurymL45MXd57otHNLK7A= +github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 h1:SCYMcCJ89LjRGwEa0tRluNRiMjZHalQZrVrvTbPh+qw= +github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72 h1:b+9H1GAsx5RsjvDFLoS5zkNBzIQMuVKUYQDmxU3N5XE= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/mathgl v0.0.0-20190416160123-c4601bc793c7 h1:THttjeRn1iiz69E875U6gAik8KTWk/JYAHoSVpUxBBI= +github.com/go-gl/mathgl v0.0.0-20190416160123-c4601bc793c7/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190523035834-f03afa92d3ff h1:+2zgJKVDVAz/BWSsuniCmU1kLCjL88Z8/kv39xCI9NQ= +golang.org/x/image v0.0.0-20190523035834-f03afa92d3ff/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/input.go b/input.go new file mode 100644 index 0000000..69f9e4d --- /dev/null +++ b/input.go @@ -0,0 +1,146 @@ +package stone + +// FIXME: do not require import of glfw. this may require linking it, and also +// including the glfw go lib in the binary. horrible. we need to copy the key +// codes here ourselves. +import "github.com/go-gl/glfw/v3.3/glfw" + +type Button int + +const ( + MouseButton1 Button = Button(glfw.MouseButton1) + MouseButton2 Button = Button(glfw.MouseButton2) + MouseButton3 Button = Button(glfw.MouseButton3) + MouseButton4 Button = Button(glfw.MouseButton4) + MouseButton5 Button = Button(glfw.MouseButton5) + MouseButton6 Button = Button(glfw.MouseButton6) + MouseButton7 Button = Button(glfw.MouseButton7) + MouseButton8 Button = Button(glfw.MouseButton8) + MouseButtonLast Button = Button(glfw.MouseButtonLast) + MouseButtonLeft Button = Button(glfw.MouseButtonLeft) + MouseButtonRight Button = Button(glfw.MouseButtonRight) + MouseButtonMiddle Button = Button(glfw.MouseButtonMiddle) + + KeyUnknown Button = Button(glfw.KeyUnknown) + KeySpace Button = Button(glfw.KeySpace) + KeyApostrophe Button = Button(glfw.KeyApostrophe) + KeyComma Button = Button(glfw.KeyComma) + KeyMinus Button = Button(glfw.KeyMinus) + KeyPeriod Button = Button(glfw.KeyPeriod) + KeySlash Button = Button(glfw.KeySlash) + Key0 Button = Button(glfw.Key0) + Key1 Button = Button(glfw.Key1) + Key2 Button = Button(glfw.Key2) + Key3 Button = Button(glfw.Key3) + Key4 Button = Button(glfw.Key4) + Key5 Button = Button(glfw.Key5) + Key6 Button = Button(glfw.Key6) + Key7 Button = Button(glfw.Key7) + Key8 Button = Button(glfw.Key8) + Key9 Button = Button(glfw.Key9) + KeySemicolon Button = Button(glfw.KeySemicolon) + KeyEqual Button = Button(glfw.KeyEqual) + KeyA Button = Button(glfw.KeyA) + KeyB Button = Button(glfw.KeyB) + KeyC Button = Button(glfw.KeyC) + KeyD Button = Button(glfw.KeyD) + KeyE Button = Button(glfw.KeyE) + KeyF Button = Button(glfw.KeyF) + KeyG Button = Button(glfw.KeyG) + KeyH Button = Button(glfw.KeyH) + KeyI Button = Button(glfw.KeyI) + KeyJ Button = Button(glfw.KeyJ) + KeyK Button = Button(glfw.KeyK) + KeyL Button = Button(glfw.KeyL) + KeyM Button = Button(glfw.KeyM) + KeyN Button = Button(glfw.KeyN) + KeyO Button = Button(glfw.KeyO) + KeyP Button = Button(glfw.KeyP) + KeyQ Button = Button(glfw.KeyQ) + KeyR Button = Button(glfw.KeyR) + KeyS Button = Button(glfw.KeyS) + KeyT Button = Button(glfw.KeyT) + KeyU Button = Button(glfw.KeyU) + KeyV Button = Button(glfw.KeyV) + KeyW Button = Button(glfw.KeyW) + KeyX Button = Button(glfw.KeyX) + KeyY Button = Button(glfw.KeyY) + KeyZ Button = Button(glfw.KeyZ) + KeyLeftBracket Button = Button(glfw.KeyLeftBracket) + KeyBackslash Button = Button(glfw.KeyBackslash) + KeyRightBracket Button = Button(glfw.KeyRightBracket) + KeyGraveAccent Button = Button(glfw.KeyGraveAccent) + KeyWorld1 Button = Button(glfw.KeyWorld1) + KeyWorld2 Button = Button(glfw.KeyWorld2) + KeyEscape Button = Button(glfw.KeyEscape) + KeyEnter Button = Button(glfw.KeyEnter) + KeyTab Button = Button(glfw.KeyTab) + KeyBackspace Button = Button(glfw.KeyBackspace) + KeyInsert Button = Button(glfw.KeyInsert) + KeyDelete Button = Button(glfw.KeyDelete) + KeyRight Button = Button(glfw.KeyRight) + KeyLeft Button = Button(glfw.KeyLeft) + KeyDown Button = Button(glfw.KeyDown) + KeyUp Button = Button(glfw.KeyUp) + KeyPageUp Button = Button(glfw.KeyPageUp) + KeyPageDown Button = Button(glfw.KeyPageDown) + KeyHome Button = Button(glfw.KeyHome) + KeyEnd Button = Button(glfw.KeyEnd) + KeyCapsLock Button = Button(glfw.KeyCapsLock) + KeyScrollLock Button = Button(glfw.KeyScrollLock) + KeyNumLock Button = Button(glfw.KeyNumLock) + KeyPrintScreen Button = Button(glfw.KeyPrintScreen) + KeyPause Button = Button(glfw.KeyPause) + KeyF1 Button = Button(glfw.KeyF1) + KeyF2 Button = Button(glfw.KeyF2) + KeyF3 Button = Button(glfw.KeyF3) + KeyF4 Button = Button(glfw.KeyF4) + KeyF5 Button = Button(glfw.KeyF5) + KeyF6 Button = Button(glfw.KeyF6) + KeyF7 Button = Button(glfw.KeyF7) + KeyF8 Button = Button(glfw.KeyF8) + KeyF9 Button = Button(glfw.KeyF9) + KeyF10 Button = Button(glfw.KeyF10) + KeyF11 Button = Button(glfw.KeyF11) + KeyF12 Button = Button(glfw.KeyF12) + KeyF13 Button = Button(glfw.KeyF13) + KeyF14 Button = Button(glfw.KeyF14) + KeyF15 Button = Button(glfw.KeyF15) + KeyF16 Button = Button(glfw.KeyF16) + KeyF17 Button = Button(glfw.KeyF17) + KeyF18 Button = Button(glfw.KeyF18) + KeyF19 Button = Button(glfw.KeyF19) + KeyF20 Button = Button(glfw.KeyF20) + KeyF21 Button = Button(glfw.KeyF21) + KeyF22 Button = Button(glfw.KeyF22) + KeyF23 Button = Button(glfw.KeyF23) + KeyF24 Button = Button(glfw.KeyF24) + KeyF25 Button = Button(glfw.KeyF25) + KeyKP0 Button = Button(glfw.KeyKP0) + KeyKP1 Button = Button(glfw.KeyKP1) + KeyKP2 Button = Button(glfw.KeyKP2) + KeyKP3 Button = Button(glfw.KeyKP3) + KeyKP4 Button = Button(glfw.KeyKP4) + KeyKP5 Button = Button(glfw.KeyKP5) + KeyKP6 Button = Button(glfw.KeyKP6) + KeyKP7 Button = Button(glfw.KeyKP7) + KeyKP8 Button = Button(glfw.KeyKP8) + KeyKP9 Button = Button(glfw.KeyKP9) + KeyKPDecimal Button = Button(glfw.KeyKPDecimal) + KeyKPDivide Button = Button(glfw.KeyKPDivide) + KeyKPMultiply Button = Button(glfw.KeyKPMultiply) + KeyKPSubtract Button = Button(glfw.KeyKPSubtract) + KeyKPAdd Button = Button(glfw.KeyKPAdd) + KeyKPEnter Button = Button(glfw.KeyKPEnter) + KeyKPEqual Button = Button(glfw.KeyKPEqual) + KeyLeftShift Button = Button(glfw.KeyLeftShift) + KeyLeftControl Button = Button(glfw.KeyLeftControl) + KeyLeftAlt Button = Button(glfw.KeyLeftAlt) + KeyLeftSuper Button = Button(glfw.KeyLeftSuper) + KeyRightShift Button = Button(glfw.KeyRightShift) + KeyRightControl Button = Button(glfw.KeyRightControl) + KeyRightAlt Button = Button(glfw.KeyRightAlt) + KeyRightSuper Button = Button(glfw.KeyRightSuper) + KeyMenu Button = Button(glfw.KeyMenu) + KeyLast Button = Button(glfw.KeyLast) +) diff --git a/stone.go b/stone.go new file mode 100644 index 0000000..7fa45eb --- /dev/null +++ b/stone.go @@ -0,0 +1,2 @@ +package stone +