mirror of
https://github.com/ivanizag/izapple2.git
synced 2025-01-14 07:30:04 +00:00
Show speed on screen
This commit is contained in:
parent
4a8372ca90
commit
71ea4bd733
@ -34,11 +34,12 @@ type Apple2 struct {
|
|||||||
cycleBreakpoint uint64
|
cycleBreakpoint uint64
|
||||||
breakPoint bool
|
breakPoint bool
|
||||||
profile bool
|
profile bool
|
||||||
showSpeed bool
|
|
||||||
paused bool
|
paused bool
|
||||||
cpuTrace bool
|
cpuTrace bool
|
||||||
forceCaps bool
|
forceCaps bool
|
||||||
removableMediaDrives []drive
|
removableMediaDrives []drive
|
||||||
|
|
||||||
|
currentFreqMHz float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCards returns the array of inserted cards
|
// GetCards returns the array of inserted cards
|
||||||
@ -75,6 +76,10 @@ func (a *Apple2) GetCycles() uint64 {
|
|||||||
return a.cycles
|
return a.cycles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Apple2) GetCurrentFreqMHz() float64 {
|
||||||
|
return a.currentFreqMHz
|
||||||
|
}
|
||||||
|
|
||||||
// SetCycleBreakpoint sets a cycle number to pause the emulator. 0 to disable
|
// SetCycleBreakpoint sets a cycle number to pause the emulator. 0 to disable
|
||||||
func (a *Apple2) SetCycleBreakpoint(cycle uint64) {
|
func (a *Apple2) SetCycleBreakpoint(cycle uint64) {
|
||||||
a.cycleBreakpoint = cycle
|
a.cycleBreakpoint = cycle
|
||||||
|
@ -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
|
// Calculate speed in MHz every million cycles
|
||||||
newTime := time.Now()
|
newTime := time.Now()
|
||||||
elapsedCycles := float64(a.cycles - speedReferenceCycles)
|
elapsedCycles := float64(a.cycles - speedReferenceCycles)
|
||||||
freq := 1000.0 * elapsedCycles / float64(newTime.Sub(speedReferenceTime).Nanoseconds())
|
a.currentFreqMHz = 1000.0 * elapsedCycles / float64(newTime.Sub(speedReferenceTime).Nanoseconds())
|
||||||
fmt.Printf("Freq: %f Mhz\n", freq)
|
|
||||||
speedReferenceTime = newTime
|
speedReferenceTime = newTime
|
||||||
speedReferenceCycles = a.cycles
|
speedReferenceCycles = a.cycles
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ func (a *Apple2) executeCommand(command command) {
|
|||||||
a.cycleDurationNs = 0
|
a.cycleDurationNs = 0
|
||||||
}
|
}
|
||||||
case CommandShowSpeed:
|
case CommandShowSpeed:
|
||||||
a.showSpeed = !a.showSpeed
|
fmt.Printf("Freq: %f Mhz\n", a.currentFreqMHz)
|
||||||
case CommandDumpDebugInfo:
|
case CommandDumpDebugInfo:
|
||||||
a.dumpDebugInfo()
|
a.dumpDebugInfo()
|
||||||
case CommandNextCharGenPage:
|
case CommandNextCharGenPage:
|
||||||
|
@ -18,7 +18,10 @@ type ebitenKeyboard struct {
|
|||||||
showPages bool
|
showPages bool
|
||||||
showCharGen bool
|
showCharGen bool
|
||||||
showAltText bool
|
showAltText bool
|
||||||
|
showFreq bool
|
||||||
screenMode int
|
screenMode int
|
||||||
|
|
||||||
|
debug bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newEbitenKeyBoard(a *izapple2.Apple2) *ebitenKeyboard {
|
func newEbitenKeyBoard(a *izapple2.Apple2) *ebitenKeyboard {
|
||||||
@ -33,14 +36,18 @@ func newEbitenKeyBoard(a *izapple2.Apple2) *ebitenKeyboard {
|
|||||||
func (k *ebitenKeyboard) update() {
|
func (k *ebitenKeyboard) update() {
|
||||||
runes := ebiten.AppendInputChars(nil)
|
runes := ebiten.AppendInputChars(nil)
|
||||||
if len(runes) > 0 {
|
if len(runes) > 0 {
|
||||||
fmt.Println("Runes: ", string(runes))
|
if k.debug {
|
||||||
|
fmt.Println("Runes: ", string(runes))
|
||||||
|
}
|
||||||
k.putText(string(runes))
|
k.putText(string(runes))
|
||||||
}
|
}
|
||||||
|
|
||||||
keys := inpututil.AppendJustPressedKeys(nil)
|
keys := inpututil.AppendJustPressedKeys(nil)
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
s := key.String()
|
if k.debug {
|
||||||
fmt.Println("Key pressed: ", s)
|
s := key.String()
|
||||||
|
fmt.Println("Key pressed: ", s)
|
||||||
|
}
|
||||||
k.putKey(key)
|
k.putKey(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +122,7 @@ func (k *ebitenKeyboard) putKey(key ebiten.Key) {
|
|||||||
k.a.SendCommand(izapple2.CommandToggleCPUTrace)
|
k.a.SendCommand(izapple2.CommandToggleCPUTrace)
|
||||||
case ebiten.KeyF5:
|
case ebiten.KeyF5:
|
||||||
if ctrl {
|
if ctrl {
|
||||||
k.a.SendCommand(izapple2.CommandShowSpeed)
|
k.showFreq = !k.showFreq
|
||||||
} else {
|
} else {
|
||||||
k.a.SendCommand(izapple2.CommandToggleSpeed)
|
k.a.SendCommand(izapple2.CommandToggleSpeed)
|
||||||
}
|
}
|
||||||
|
@ -84,11 +84,7 @@ func (s *ebitenSpeaker) Read(buf []byte) (n int, err error) {
|
|||||||
// Build wave
|
// Build wave
|
||||||
const bytesPerSample = 8 // Two floats32, 4 bytes each, one for each channel
|
const bytesPerSample = 8 // Two floats32, 4 bytes each, one for each channel
|
||||||
samples := len(buf) / bytesPerSample
|
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
|
var i, r int
|
||||||
level := s.lastLevel
|
level := s.lastLevel
|
||||||
for p := 0; p < len(s.pendingClicks); p++ {
|
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 the buffer is empty lets stop the signal
|
||||||
if i == 0 && level != 0.0 {
|
if i == 0 && level != 0.0 {
|
||||||
level = 0.0
|
level = 0.0
|
||||||
fmt.Printf("Speaker buffer empty, to zero.\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete the buffer if needed
|
// Complete the buffer if needed
|
||||||
|
@ -1,31 +1,42 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
|
|
||||||
"github.com/ivanizag/izapple2"
|
"github.com/ivanizag/izapple2"
|
||||||
a_screen "github.com/ivanizag/izapple2/screen"
|
a_screen "github.com/ivanizag/izapple2/screen"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/examples/resources/fonts"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/text/v2"
|
||||||
"github.com/pkg/profile"
|
"github.com/pkg/profile"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
a *izapple2.Apple2
|
a *izapple2.Apple2
|
||||||
image *ebiten.Image
|
image *ebiten.Image
|
||||||
keyboard *ebitenKeyboard
|
keyboard *ebitenKeyboard
|
||||||
speaker *ebitenSpeaker
|
speaker *ebitenSpeaker
|
||||||
|
fontSource *text.GoTextFaceSource
|
||||||
|
|
||||||
paused bool
|
paused bool
|
||||||
title string
|
title string
|
||||||
|
|
||||||
|
updates uint64
|
||||||
|
freq float64
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
virtualWidth = 1128
|
virtualWidth = 1128
|
||||||
virtualHeight = 768
|
virtualHeight = 768
|
||||||
|
hudFontSize = 50
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var hudColor = color.RGBA{208, 241, 141, 255} // Yellow
|
||||||
|
|
||||||
func (g *Game) Update() error {
|
func (g *Game) Update() error {
|
||||||
g.keyboard.update()
|
g.keyboard.update()
|
||||||
g.speaker.update()
|
g.speaker.update()
|
||||||
@ -39,7 +50,7 @@ func (g *Game) Update() error {
|
|||||||
g.paused = g.a.IsPaused()
|
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
|
var img *image.RGBA
|
||||||
vs := g.a.GetVideoSource()
|
vs := g.a.GetVideoSource()
|
||||||
if g.keyboard.showHelp {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +88,18 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
|||||||
|
|
||||||
screen.DrawImage(g.image, op)
|
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) {
|
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)"
|
title := "iz-" + a.Name + " (F1 for help)"
|
||||||
ebiten.SetWindowTitle(title)
|
ebiten.SetWindowTitle(title)
|
||||||
|
|
||||||
go a.Run()
|
|
||||||
|
|
||||||
game := &Game{
|
game := &Game{
|
||||||
a: a,
|
a: a,
|
||||||
keyboard: newEbitenKeyBoard(a),
|
keyboard: newEbitenKeyBoard(a),
|
||||||
speaker: newEbitenSpeaker(),
|
speaker: newEbitenSpeaker(),
|
||||||
}
|
}
|
||||||
|
|
||||||
a.SetSpeakerProvider(game.speaker)
|
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 {
|
if err := ebiten.RunGame(game); err != nil {
|
||||||
fmt.Printf("Error: %v\n", err)
|
fmt.Printf("Error: %v\n", err)
|
||||||
}
|
}
|
||||||
@ -140,3 +172,8 @@ side of the window to load a disk
|
|||||||
Run izapple2 -h for more options
|
Run izapple2 -h for more options
|
||||||
https://github.com/ivanizag/izapple2
|
https://github.com/ivanizag/izapple2
|
||||||
`
|
`
|
||||||
|
|
||||||
|
/*
|
||||||
|
To test the WebAssembly version, run:
|
||||||
|
go run github.com/hajimehoshi/wasmserve@latest .
|
||||||
|
*/
|
||||||
|
1
go.mod
1
go.mod
@ -19,6 +19,7 @@ require (
|
|||||||
github.com/ebitengine/hideconsole v1.0.0 // indirect
|
github.com/ebitengine/hideconsole v1.0.0 // indirect
|
||||||
github.com/ebitengine/oto/v3 v3.3.1 // indirect
|
github.com/ebitengine/oto/v3 v3.3.1 // indirect
|
||||||
github.com/ebitengine/purego v0.8.0 // 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
|
github.com/jezek/xgb v1.1.1 // indirect
|
||||||
golang.org/x/sync v0.8.0 // indirect
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -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 h1:nanQfMsOs3gnuKRm0E5jXWomedE/9YIFXdmHJNZYeqc=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240118000515-a250818d05e3/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
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-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.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 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
|
Loading…
x
Reference in New Issue
Block a user