Ctrl-F6: Show a split screen with the views for NTSC color TV, monochrome monitor, HGR page 1 and HGR page 2

This commit is contained in:
Ivan Izaguirre 2020-07-31 09:46:53 +02:00
parent b375869923
commit dad2a67321
4 changed files with 61 additions and 5 deletions

View File

@ -120,6 +120,7 @@ Line:
- F5: Toggle speed between real and fastest - F5: Toggle speed between real and fastest
- Ctrl-F5: Show current speed in Mhz - Ctrl-F5: Show current speed in Mhz
- F6: Toggle between NTSC color TV and green phosphor monochrome monitor - F6: Toggle between NTSC color TV and green phosphor monochrome monitor
- Ctrl-F6: Show a split screen with the views for NTSC color TV, monochrome monitor, HGR page 1 and HGR page 2.
- F7: Save current state to disk (incomplete) - F7: Save current state to disk (incomplete)
- F8: Restore state from disk (incomplete) - F8: Restore state from disk (incomplete)
- F10: Cycle character generator codepages. Only if the character generator ROM has more than one 2Kb page. - F10: Cycle character generator codepages. Only if the character generator ROM has more than one 2Kb page.

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"image"
"unsafe" "unsafe"
"github.com/ivanizag/apple2" "github.com/ivanizag/apple2"
@ -77,7 +78,12 @@ func SDLRun(a *apple2.Apple2) {
} }
if !a.IsPaused() { if !a.IsPaused() {
img := apple2.Snapshot(a) var img *image.RGBA
if kp.showPages {
img = apple2.SnapshotHGRModes(a)
} else {
img = apple2.Snapshot(a)
}
if img != nil { if img != nil {
surface, err := sdl.CreateRGBSurfaceFrom(unsafe.Pointer(&img.Pix[0]), surface, err := sdl.CreateRGBSurfaceFrom(unsafe.Pointer(&img.Pix[0]),
int32(img.Bounds().Dx()), int32(img.Bounds().Dy()), int32(img.Bounds().Dx()), int32(img.Bounds().Dy()),

View File

@ -11,6 +11,8 @@ import (
type sdlKeyboard struct { type sdlKeyboard struct {
keyChannel chan uint8 keyChannel chan uint8
a *apple2.Apple2 a *apple2.Apple2
showPages bool
} }
func newSDLKeyBoard(a *apple2.Apple2) *sdlKeyboard { func newSDLKeyBoard(a *apple2.Apple2) *sdlKeyboard {
@ -105,7 +107,11 @@ func (k *sdlKeyboard) putKey(keyEvent *sdl.KeyboardEvent) {
k.a.SendCommand(apple2.CommandToggleSpeed) k.a.SendCommand(apple2.CommandToggleSpeed)
} }
case sdl.K_F6: case sdl.K_F6:
k.a.SendCommand(apple2.CommandToggleColor) if ctrl {
k.showPages = !k.showPages
} else {
k.a.SendCommand(apple2.CommandToggleColor)
}
case sdl.K_F7: case sdl.K_F7:
k.a.SendCommand(apple2.CommandSaveState) k.a.SendCommand(apple2.CommandSaveState)
case sdl.K_F8: case sdl.K_F8:

View File

@ -17,6 +17,10 @@ References:
// Snapshot the currently visible screen // Snapshot the currently visible screen
func Snapshot(a *Apple2) *image.RGBA { func Snapshot(a *Apple2) *image.RGBA {
return activeSnapshot(a, false)
}
func activeSnapshot(a *Apple2, raw bool) *image.RGBA {
isColor := a.isColor isColor := a.isColor
isTextMode := a.io.isSoftSwitchActive(ioFlagText) isTextMode := a.io.isSoftSwitchActive(ioFlagText)
isHiResMode := a.io.isSoftSwitchActive(ioFlagHiRes) isHiResMode := a.io.isSoftSwitchActive(ioFlagHiRes)
@ -56,17 +60,42 @@ func Snapshot(a *Apple2) *image.RGBA {
snapText := snapshotTextMode(a, is80Columns, false /*isSecondPage*/, true /*isMixMode*/, lightColor) snapText := snapshotTextMode(a, is80Columns, false /*isSecondPage*/, true /*isMixMode*/, lightColor)
snap = mixSnapshots(snap, snapText) snap = mixSnapshots(snap, snapText)
} }
if isColor { if isColor && !raw {
snap = filterNTSCColor(false /*blacker*/, snap) snap = filterNTSCColor(false /*blacker*/, snap)
} }
} }
if !isSuperHighResMode { if !raw && !isSuperHighResMode {
snap = linesSeparatedFilter(snap) snap = linesSeparatedFilter(snap)
} }
return snap return snap
} }
// SnapshotAllModes to get all modes mixed
func SnapshotHGRModes(a *Apple2) *image.RGBA {
bwSnap := activeSnapshot(a, true)
if bwSnap.Bounds().Dx() == hiResWidth {
bwSnap = doubleWidthFilter(bwSnap)
}
colorSnap := filterNTSCColor(false, bwSnap)
page1Snap := filterNTSCColor(false /*blacker*/, snapshotHiResModeMono(a, false /*2nd page*/, false /*mix*/, color.White)) // HGR 1
page2Snap := filterNTSCColor(false /*blacker*/, snapshotHiResModeMono(a, true /*2nd page*/, false /*mix*/, color.White)) // HGR 2
size := image.Rect(0, 0, hiResWidth*4, hiResHeight*2)
out := image.NewRGBA(size)
for y := 0; y < hiResHeight; y++ {
for x := 0; x < hiResWidth*2; x++ {
out.Set(x, y, colorSnap.At(x, y))
out.Set(x+hiResWidth*2, y, bwSnap.At(x, y))
out.Set(x, y+hiResHeight, page1Snap.At(x, y))
out.Set(x+hiResWidth*2, y+hiResHeight, page2Snap.At(x, y))
}
}
return out
}
func mixSnapshots(top, bottom *image.RGBA) *image.RGBA { func mixSnapshots(top, bottom *image.RGBA) *image.RGBA {
topBounds := top.Bounds() topBounds := top.Bounds()
topWidth := topBounds.Dx() topWidth := topBounds.Dx()
@ -89,7 +118,7 @@ func mixSnapshots(top, bottom *image.RGBA) *image.RGBA {
} }
} }
// Copy bottom, applyng the factor // Copy bottom, applying the factor
for y := bottomBounds.Min.Y; y < bottomBounds.Max.Y; y++ { for y := bottomBounds.Min.Y; y < bottomBounds.Max.Y; y++ {
for x := bottomBounds.Min.X; x < bottomBounds.Max.X; x++ { for x := bottomBounds.Min.X; x < bottomBounds.Max.X; x++ {
c := bottom.At(x, y) c := bottom.At(x, y)
@ -149,3 +178,17 @@ func linesSeparatedFilter(in *image.RGBA) *image.RGBA {
} }
return out return out
} }
func doubleWidthFilter(in *image.RGBA) *image.RGBA {
b := in.Bounds()
size := image.Rect(0, 0, 2*b.Dx(), b.Dy())
out := image.NewRGBA(size)
for y := b.Min.Y; y < b.Max.Y; y++ {
for x := b.Min.X; x < b.Max.X; x++ {
c := in.At(x, y)
out.Set(2*x, y, c)
out.Set(2*x+1, y, c)
}
}
return out
}