Show speed on screen

This commit is contained in:
Ivan Izaguirre 2024-11-01 21:35:20 +01:00
parent 4a8372ca90
commit 71ea4bd733
8 changed files with 68 additions and 22 deletions

View File

@ -34,11 +34,12 @@ type Apple2 struct {
cycleBreakpoint uint64
breakPoint bool
profile bool
showSpeed bool
paused bool
cpuTrace bool
forceCaps bool
removableMediaDrives []drive
currentFreqMHz float64
}
// GetCards returns the array of inserted cards
@ -75,6 +76,10 @@ func (a *Apple2) GetCycles() uint64 {
return a.cycles
}
func (a *Apple2) GetCurrentFreqMHz() float64 {
return a.currentFreqMHz
}
// SetCycleBreakpoint sets a cycle number to pause the emulator. 0 to disable
func (a *Apple2) SetCycleBreakpoint(cycle uint64) {
a.cycleBreakpoint = cycle

View File

@ -116,12 +116,11 @@ func (a *Apple2) Start(paused bool) {
}
}
if a.showSpeed && a.cycles-speedReferenceCycles > 1000000 {
if a.cycles-speedReferenceCycles > 1000000 {
// Calculate speed in MHz every million cycles
newTime := time.Now()
elapsedCycles := float64(a.cycles - speedReferenceCycles)
freq := 1000.0 * elapsedCycles / float64(newTime.Sub(speedReferenceTime).Nanoseconds())
fmt.Printf("Freq: %f Mhz\n", freq)
a.currentFreqMHz = 1000.0 * elapsedCycles / float64(newTime.Sub(speedReferenceTime).Nanoseconds())
speedReferenceTime = newTime
speedReferenceCycles = a.cycles
}

View File

@ -77,7 +77,7 @@ func (a *Apple2) executeCommand(command command) {
a.cycleDurationNs = 0
}
case CommandShowSpeed:
a.showSpeed = !a.showSpeed
fmt.Printf("Freq: %f Mhz\n", a.currentFreqMHz)
case CommandDumpDebugInfo:
a.dumpDebugInfo()
case CommandNextCharGenPage:

View File

@ -18,7 +18,10 @@ type ebitenKeyboard struct {
showPages bool
showCharGen bool
showAltText bool
showFreq bool
screenMode int
debug bool
}
func newEbitenKeyBoard(a *izapple2.Apple2) *ebitenKeyboard {
@ -33,14 +36,18 @@ func newEbitenKeyBoard(a *izapple2.Apple2) *ebitenKeyboard {
func (k *ebitenKeyboard) update() {
runes := ebiten.AppendInputChars(nil)
if len(runes) > 0 {
fmt.Println("Runes: ", string(runes))
if k.debug {
fmt.Println("Runes: ", string(runes))
}
k.putText(string(runes))
}
keys := inpututil.AppendJustPressedKeys(nil)
for _, key := range keys {
s := key.String()
fmt.Println("Key pressed: ", s)
if k.debug {
s := key.String()
fmt.Println("Key pressed: ", s)
}
k.putKey(key)
}
}
@ -115,7 +122,7 @@ func (k *ebitenKeyboard) putKey(key ebiten.Key) {
k.a.SendCommand(izapple2.CommandToggleCPUTrace)
case ebiten.KeyF5:
if ctrl {
k.a.SendCommand(izapple2.CommandShowSpeed)
k.showFreq = !k.showFreq
} else {
k.a.SendCommand(izapple2.CommandToggleSpeed)
}

View File

@ -84,11 +84,7 @@ func (s *ebitenSpeaker) Read(buf []byte) (n int, err error) {
// Build wave
const bytesPerSample = 8 // Two floats32, 4 bytes each, one for each channel
samples := len(buf) / bytesPerSample
//fmt.Printf("smples: %v\n", smples)
if len(s.pendingClicks) > 0 {
fmt.Printf("pendingClicks: %v\n", len(s.pendingClicks))
}
var i, r int
level := s.lastLevel
for p := 0; p < len(s.pendingClicks); p++ {
@ -125,7 +121,6 @@ func (s *ebitenSpeaker) Read(buf []byte) (n int, err error) {
// If the buffer is empty lets stop the signal
if i == 0 && level != 0.0 {
level = 0.0
fmt.Printf("Speaker buffer empty, to zero.\n")
}
// Complete the buffer if needed

View File

@ -1,31 +1,42 @@
package main
import (
"bytes"
"fmt"
"image"
"image/color"
"github.com/ivanizag/izapple2"
a_screen "github.com/ivanizag/izapple2/screen"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/examples/resources/fonts"
"github.com/hajimehoshi/ebiten/v2/text/v2"
"github.com/pkg/profile"
)
type Game struct {
a *izapple2.Apple2
image *ebiten.Image
keyboard *ebitenKeyboard
speaker *ebitenSpeaker
a *izapple2.Apple2
image *ebiten.Image
keyboard *ebitenKeyboard
speaker *ebitenSpeaker
fontSource *text.GoTextFaceSource
paused bool
title string
updates uint64
freq float64
}
const (
virtualWidth = 1128
virtualHeight = 768
hudFontSize = 50
)
var hudColor = color.RGBA{208, 241, 141, 255} // Yellow
func (g *Game) Update() error {
g.keyboard.update()
g.speaker.update()
@ -39,7 +50,7 @@ func (g *Game) Update() error {
g.paused = g.a.IsPaused()
}
if !g.a.IsPaused() {
if g.updates%3 == 0 && !g.a.IsPaused() { // 20 times per second
var img *image.RGBA
vs := g.a.GetVideoSource()
if g.keyboard.showHelp {
@ -59,6 +70,11 @@ func (g *Game) Update() error {
}
}
if g.updates%60 == 0 { // Once per second
g.freq = g.a.GetCurrentFreqMHz()
}
g.updates++
return nil
}
@ -72,6 +88,18 @@ func (g *Game) Draw(screen *ebiten.Image) {
screen.DrawImage(g.image, op)
}
if g.keyboard.showFreq {
msg := fmt.Sprintf("%0.2f Hz, FPS %0.0f", g.freq, ebiten.ActualFPS())
op := &text.DrawOptions{}
op.GeoM.Translate(20, 20)
op.ColorScale.ScaleWithColor(hudColor)
text.Draw(screen, msg, &text.GoTextFace{
Source: g.fontSource,
Size: hudFontSize,
}, op)
}
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
@ -101,16 +129,20 @@ func ebitenRun(a *izapple2.Apple2) {
title := "iz-" + a.Name + " (F1 for help)"
ebiten.SetWindowTitle(title)
go a.Run()
game := &Game{
a: a,
keyboard: newEbitenKeyBoard(a),
speaker: newEbitenSpeaker(),
}
a.SetSpeakerProvider(game.speaker)
var err error
game.fontSource, err = text.NewGoTextFaceSource(bytes.NewReader(fonts.MPlus1pRegular_ttf))
if err != nil {
panic(err)
}
go a.Run()
if err := ebiten.RunGame(game); err != nil {
fmt.Printf("Error: %v\n", err)
}
@ -140,3 +172,8 @@ side of the window to load a disk
Run izapple2 -h for more options
https://github.com/ivanizag/izapple2
`
/*
To test the WebAssembly version, run:
go run github.com/hajimehoshi/wasmserve@latest .
*/

1
go.mod
View File

@ -19,6 +19,7 @@ require (
github.com/ebitengine/hideconsole v1.0.0 // indirect
github.com/ebitengine/oto/v3 v3.3.1 // indirect
github.com/ebitengine/purego v0.8.0 // indirect
github.com/go-text/typesetting v0.2.0 // indirect
github.com/jezek/xgb v1.1.1 // indirect
golang.org/x/sync v0.8.0 // indirect
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect

2
go.sum
View File

@ -36,6 +36,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240118000515-a250818d05e3 h1:nanQfMsOs3gnuKRm0E5jXWomedE/9YIFXdmHJNZYeqc=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240118000515-a250818d05e3/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-text/typesetting v0.2.0 h1:fbzsgbmk04KiWtE+c3ZD4W2nmCRzBqrqQOvYlwAOdho=
github.com/go-text/typesetting v0.2.0/go.mod h1:2+owI/sxa73XA581LAzVuEBZ3WEEV2pXeDswCH/3i1I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=