mirror of
https://github.com/zserge/fenster.git
synced 2025-07-17 09:16:12 +03:00
28
.github/workflows/go.yml
vendored
Normal file
28
.github/workflows/go.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# This workflow will build a golang project
|
||||||
|
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
|
||||||
|
|
||||||
|
name: Go
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "main" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "main" ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: 1.x
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: go build -v ./...
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: go test -v ./...
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build example
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -20,11 +22,11 @@ func main() {
|
|||||||
// Fill screen with random noise
|
// Fill screen with random noise
|
||||||
for i := 0; i < 240; i++ {
|
for i := 0; i < 240; i++ {
|
||||||
for j := 0; j < 320; j++ {
|
for j := 0; j < 320; j++ {
|
||||||
f.SetPixel(j, i, rand.Uint32())
|
f.Set(j, i, fenster.RGB(rand.Uint32()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Wait for FPS rate
|
// Wait for FPS rate
|
||||||
sleep := 16*time.Millisecond - time.Now().Sub(lastFrame)
|
sleep := 16*time.Millisecond - time.Since(lastFrame)
|
||||||
if sleep > 0 {
|
if sleep > 0 {
|
||||||
time.Sleep(sleep)
|
time.Sleep(sleep)
|
||||||
}
|
}
|
||||||
|
BIN
examples/testdata/Testbild.png
vendored
Normal file
BIN
examples/testdata/Testbild.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
58
examples/testimage.go
Normal file
58
examples/testimage.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
//go:build example
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color/palette"
|
||||||
|
"image/draw"
|
||||||
|
"image/png"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/zserge/fenster"
|
||||||
|
)
|
||||||
|
|
||||||
|
func openImage(fname string) (image.Image, error) {
|
||||||
|
fd, err := os.Open(fname)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
return png.Decode(fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
f := fenster.New()
|
||||||
|
f.Open(320, 240, "Hello")
|
||||||
|
defer f.Close()
|
||||||
|
lastFrame := time.Now()
|
||||||
|
|
||||||
|
img, err := openImage("testdata/Testbild.png")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert to paletted image
|
||||||
|
pimg := image.NewPaletted(img.Bounds(), palette.Plan9)
|
||||||
|
draw.Draw(pimg, pimg.Bounds(), img, image.Point{}, draw.Src)
|
||||||
|
|
||||||
|
for f.Loop() {
|
||||||
|
// If escape is pressed - exit
|
||||||
|
if f.Key(27) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// rotate palette
|
||||||
|
pimg.Palette = append(pimg.Palette[1:], pimg.Palette[0])
|
||||||
|
draw.Draw(f, f.Bounds(), pimg, image.Point{}, draw.Src)
|
||||||
|
|
||||||
|
// Wait for FPS rate
|
||||||
|
sleep := 16*time.Millisecond - time.Since(lastFrame)
|
||||||
|
if sleep > 0 {
|
||||||
|
time.Sleep(sleep)
|
||||||
|
}
|
||||||
|
lastFrame = time.Now()
|
||||||
|
}
|
||||||
|
}
|
41
fenster.go
41
fenster.go
@ -9,6 +9,9 @@ package fenster
|
|||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
"runtime"
|
"runtime"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@ -22,10 +25,33 @@ type Fenster interface {
|
|||||||
Open(w, h int, title string) error
|
Open(w, h int, title string) error
|
||||||
Loop() bool
|
Loop() bool
|
||||||
Close()
|
Close()
|
||||||
Pixel(x int, y int) uint32
|
|
||||||
SetPixel(x int, y int, rgb uint32)
|
|
||||||
Key(byte) bool
|
Key(byte) bool
|
||||||
Mod() Mods
|
Mod() Mods
|
||||||
|
draw.Image
|
||||||
|
}
|
||||||
|
|
||||||
|
// RGB Color 00RRGGBB
|
||||||
|
type RGB uint32
|
||||||
|
|
||||||
|
func (c RGB) RGBA() (r uint32, g uint32, b uint32, a uint32) {
|
||||||
|
r = uint32(c>>16) & 0xff
|
||||||
|
r |= r << 8
|
||||||
|
g = uint32(c>>8) & 0xff
|
||||||
|
g |= g << 8
|
||||||
|
b = uint32(c) & 0xff
|
||||||
|
b |= b << 8
|
||||||
|
a = 0xffff
|
||||||
|
return r, g, b, a
|
||||||
|
}
|
||||||
|
|
||||||
|
var RGBModel = color.ModelFunc(rgbModel)
|
||||||
|
|
||||||
|
func rgbModel(c color.Color) color.Color {
|
||||||
|
if _, ok := c.(RGB); ok {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
r, g, b, _ := c.RGBA()
|
||||||
|
return RGB((r>>8)<<16 | (g>>8)<<8 | (b >> 8))
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mods int
|
type Mods int
|
||||||
@ -35,6 +61,11 @@ type fenster struct {
|
|||||||
buf []uint32
|
buf []uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *fenster) ColorModel() color.Model { return RGBModel }
|
||||||
|
func (f *fenster) Bounds() image.Rectangle {
|
||||||
|
return image.Rect(0, 0, int(f.f.width), int(f.f.height))
|
||||||
|
}
|
||||||
|
|
||||||
func New() Fenster { return &fenster{} }
|
func New() Fenster { return &fenster{} }
|
||||||
func (f *fenster) Open(w, h int, title string) error {
|
func (f *fenster) Open(w, h int, title string) error {
|
||||||
f.f.title = C.CString(title)
|
f.f.title = C.CString(title)
|
||||||
@ -54,5 +85,7 @@ func (f *fenster) Close() { C.fenster_close(&f.f) }
|
|||||||
func (f *fenster) Key(code byte) bool { return f.f.keys[code] != 0 }
|
func (f *fenster) Key(code byte) bool { return f.f.keys[code] != 0 }
|
||||||
func (f *fenster) Mod() Mods { return Mods(f.f.mod) }
|
func (f *fenster) Mod() Mods { return Mods(f.f.mod) }
|
||||||
|
|
||||||
func (f *fenster) Pixel(x, y int) uint32 { return f.buf[y*int(f.f.width)+x] }
|
func (f *fenster) At(x, y int) color.Color { return RGB(f.buf[y*int(f.f.width)+x]) }
|
||||||
func (f *fenster) SetPixel(x, y int, color uint32) { f.buf[y*int(f.f.width)+x] = color }
|
func (f *fenster) Set(x, y int, c color.Color) {
|
||||||
|
f.buf[y*int(f.f.width)+x] = uint32(f.ColorModel().Convert(c).(RGB))
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user