~apreiml/octachip

322d29ccbad84921a151e64d4e808b8107007b34 — Armin Preiml 3 years ago
chip 8: display init
3 files changed, 133 insertions(+), 0 deletions(-)

A go.mod
A main.go
A vm.go
A  => go.mod +8 -0
@@ 1,8 @@
module git.sr.ht/~apreiml/octachip

go 1.16

require (
	github.com/faiface/pixel v0.10.0 // indirect
	golang.org/x/image v0.0.0-20210504121937-7319ad40d33e // indirect
)

A  => main.go +7 -0
@@ 1,7 @@
package main

func main() {
	vm := &Chip8{}

	vm.Run()
}

A  => vm.go +118 -0
@@ 1,118 @@
package main

import (
	"fmt"
	"math"
	"time"

	"github.com/faiface/pixel"
	"github.com/faiface/pixel/pixelgl"
	"golang.org/x/image/colornames"
)

const (
	memSize     = 4 * 1024
	memReserved = 0x200
	romStart    = memReserved
)

type Chip8 struct {
	mem [memSize]byte
	v   [16]byte
	i   uint16
	dt  byte
	st  byte
	pc  uint16
	sp  byte
}

func (c *Chip8) LoadRom(rom []byte) error {
	copy(c.mem[romStart:], rom)
	return nil
}

func run() {
	d := NewDisplay(640, 320)
	cfg := pixelgl.WindowConfig{
		Title:  "Octa-Chip",
		Bounds: d.bounds,
		VSync:  true,
	}

	d.buffer[0] = 1
	d.buffer[2] = 1

	d.buffer[64] = 1
	d.buffer[64+4] = 1

	d.buffer[31*64] = 1

	win, err := pixelgl.NewWindow(cfg)
	if err != nil {
		panic(err)
	}

	win.Clear(colornames.Black)

	go func() {
		i := 10
		ticker := time.NewTicker(time.Second)
		for {
			select {
			case <-ticker.C:
				d.buffer[i] = 1
				i += 2
				fmt.Println(i)
			}
		}
	}()

	for !win.Closed() {
		sprite := pixel.NewSprite(d, d.Bounds())
		sprite.Draw(win, pixel.IM.Moved(win.Bounds().Center()))
		win.Update()
	}
}

func (c *Chip8) Run() {
	pixelgl.Run(run)
}

type Display struct {
	bounds       pixel.Rect
	xm, ym       float64
	buffer       []byte
	modeX, modeY int
}

func NewDisplay(w, h float64) *Display {
	modeX := 64
	modeY := 32

	return &Display{
		bounds: pixel.R(0, 0, w, h),
		xm:     w / float64(modeX),
		ym:     h / float64(modeY),
		modeX:  modeX,
		modeY:  modeY,
		buffer: make([]byte, modeX*modeY),
	}
}

func (d Display) Bounds() pixel.Rect {
	return d.bounds
}

func (d Display) Color(at pixel.Vec) pixel.RGBA {
	x := int(math.Floor(at.X / d.xm))
	y := int(math.Floor(at.Y / d.ym))

	y = d.modeY - y - 1

	idx := y*d.modeX + x
	set := d.buffer[idx]
	if set == 1 {
		return pixel.RGB(1, 1, 1)
	}
	return pixel.RGB(255, 255, 255)
}