izapple2/frontend/a2sdl/main.go

175 lines
3.9 KiB
Go
Raw Permalink Normal View History

package main
2019-04-13 18:29:31 +00:00
import (
"fmt"
"image"
2019-04-21 22:18:14 +00:00
"unsafe"
2020-10-03 21:38:26 +00:00
"github.com/ivanizag/izapple2"
2020-10-16 18:41:34 +00:00
"github.com/ivanizag/izapple2/screen"
2020-10-03 21:38:26 +00:00
2020-01-11 16:13:29 +00:00
"github.com/pkg/profile"
2019-04-13 18:29:31 +00:00
"github.com/veandco/go-sdl2/sdl"
)
func main() {
2024-01-06 20:48:23 +00:00
a, err := izapple2.CreateConfiguredApple()
if err != nil {
fmt.Printf("Error: %v\n", err)
}
2019-12-22 13:32:54 +00:00
if a != nil {
2020-09-23 16:09:18 +00:00
if a.IsProfiling() {
// See the log with:
2020-10-03 21:38:26 +00:00
// go tool pprof --pdf ~/go/bin/izapple2sdl /tmp/profile329536248/cpu.pprof > profile.pdf
2020-09-23 16:09:18 +00:00
defer profile.Start().Stop()
}
2020-10-10 15:35:25 +00:00
sdlRun(a)
2019-12-22 13:32:54 +00:00
}
}
2020-10-10 15:35:25 +00:00
func sdlRun(a *izapple2.Apple2) {
2019-05-09 22:09:15 +00:00
2020-10-04 17:41:07 +00:00
window, renderer, err := sdl.CreateWindowAndRenderer(4*40*7+8, 4*24*8,
2019-04-21 22:18:14 +00:00
sdl.WINDOW_SHOWN)
2019-04-13 18:29:31 +00:00
if err != nil {
panic("Failed to create window")
}
2019-04-21 22:18:14 +00:00
window.SetResizable(true)
2019-04-13 18:29:31 +00:00
defer window.Destroy()
defer renderer.Destroy()
2024-02-13 22:39:00 +00:00
title := "iz-" + a.Name + " (F1 for help)"
window.SetTitle(title)
2019-04-13 18:29:31 +00:00
2024-01-25 17:19:47 +00:00
sdl.SetHint(sdl.HINT_RENDER_SCALE_QUALITY, "best")
2019-05-05 10:38:24 +00:00
kp := newSDLKeyBoard(a)
2019-08-05 22:37:27 +00:00
s := newSDLSpeaker()
s.start()
2019-05-09 22:09:15 +00:00
a.SetSpeakerProvider(s)
2019-08-05 22:37:27 +00:00
j := newSDLJoysticks(true)
2019-08-05 22:37:27 +00:00
a.SetJoysticksProvider(j)
2021-01-24 22:25:52 +00:00
m := newSDLMouse()
a.SetMouseProvider(m)
2019-09-23 21:35:39 +00:00
go a.Run()
2019-04-13 18:29:31 +00:00
2023-04-04 16:35:13 +00:00
var x int32
2020-03-14 02:29:12 +00:00
paused := false
2019-04-13 18:29:31 +00:00
running := true
for running {
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
switch t := event.(type) {
case *sdl.QuitEvent:
2020-10-03 21:38:26 +00:00
a.SendCommand(izapple2.CommandKill)
2019-04-13 18:29:31 +00:00
running = false
case *sdl.KeyboardEvent:
kp.putKey(t)
j.putKey(t)
2019-04-13 18:29:31 +00:00
case *sdl.TextInputEvent:
2020-10-10 15:35:25 +00:00
kp.putText(t.GetText())
2019-08-05 22:37:27 +00:00
case *sdl.JoyAxisEvent:
j.putAxisEvent(t)
case *sdl.JoyButtonEvent:
j.putButtonEvent(t)
case *sdl.MouseMotionEvent:
w, h := window.GetSize()
j.putMouseMotionEvent(t, w, h)
2021-01-24 22:25:52 +00:00
m.putMouseMotionEvent(t, w, h)
2023-04-04 16:35:13 +00:00
x = t.X
case *sdl.MouseButtonEvent:
j.putMouseButtonEvent(t)
2021-01-24 22:25:52 +00:00
m.putMouseButtonEvent(t)
2023-04-04 16:35:13 +00:00
case *sdl.DropEvent:
switch t.Type {
case sdl.DROPFILE:
w, _ := window.GetSize()
drive := int(2 * x / w)
fmt.Printf("Loading '%s' in drive %v\n", t.File, drive+1)
a.SendLoadDisk(drive, t.File)
}
2019-04-13 18:29:31 +00:00
}
}
2019-04-21 22:18:14 +00:00
2020-03-14 02:29:12 +00:00
if paused != a.IsPaused() {
if a.IsPaused() {
2024-02-13 22:39:00 +00:00
window.SetTitle(title + " - PAUSED!")
2020-03-14 02:29:12 +00:00
} else {
2024-02-13 22:39:00 +00:00
window.SetTitle(title)
2020-03-14 02:29:12 +00:00
}
paused = a.IsPaused()
}
if !a.IsPaused() {
var img *image.RGBA
2024-02-13 22:39:00 +00:00
if kp.showHelp {
img = screen.SnapshotMessageGenerator(a, helpMessage)
} else if kp.showCharGen {
2021-03-01 23:19:18 +00:00
img = screen.SnapshotCharacterGenerator(a, kp.showAltText)
window.SetTitle(fmt.Sprintf("%v character map", a.Name))
} else if kp.showPages {
img = screen.SnapshotParts(a, kp.screenMode)
2020-10-16 18:41:34 +00:00
window.SetTitle(fmt.Sprintf("%v %v %vx%v", a.Name, screen.VideoModeName(a), img.Rect.Dx()/2, img.Rect.Dy()/2))
} else {
img = screen.Snapshot(a, kp.screenMode)
}
if img != nil {
surface, err := sdl.CreateRGBSurfaceFrom(unsafe.Pointer(&img.Pix[0]),
int32(img.Bounds().Dx()), int32(img.Bounds().Dy()),
32, 4*img.Bounds().Dx(),
0x0000ff, 0x0000ff00, 0x00ff0000, 0xff000000)
// Valid for little endian. Should we reverse for big endian?
// 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff)
if err != nil {
panic(err)
}
texture, err := renderer.CreateTextureFromSurface(surface)
if err != nil {
panic(err)
}
renderer.Clear()
2020-10-04 14:59:00 +00:00
renderer.Copy(texture, nil, nil)
renderer.Present()
surface.Free()
texture.Destroy()
2019-04-26 16:08:30 +00:00
}
}
2019-05-04 17:49:11 +00:00
sdl.Delay(1000 / 30)
2019-04-13 18:29:31 +00:00
}
}
2024-02-13 22:39:00 +00:00
var helpMessage = `
F1: Show/Hide help
Ctrl-F2: Reset
2024-03-24 19:15:16 +00:00
F4: Show/Hide CPU trace
2024-02-13 22:39:00 +00:00
F5: Fast/Normal speed
Ctrl-F5: Show speed
F6: Next screen mode
F7: Show/Hide pages
F10: Next character set
Ctrl-F10: Show/Hide character set
Shift-F10: Show/Hide alternate text
F12: Save screen snapshot
Pause: Pause the emulation
Drop a file on the left or right
side of the window to load a disk
Run izapple2 -h for more options
More info at
https://github.com/ivanizag/izapple2
`
///////////////////////////////////////