UI to select screen modes

This commit is contained in:
Ivan Izaguirre 2020-10-16 15:05:38 +02:00 committed by Iván Izaguirre
parent a9b8fe76df
commit 4ec3bff858
9 changed files with 40 additions and 55 deletions

View File

@ -191,8 +191,6 @@ Only valid on SDL mode
cpu speed in Mhz, use 0 for full speed. Use F5 to toggle. (default 1.0227142857142857)
-model string
set base model. Models available 2plus, 2e, 2enh, base64a (default "2enh")
-mono
emulate a green phosphor monitor instead of a NTSC color TV. Use F6 to toggle.
-nsc int
add a DS1216 No-Slot-Clock on the main ROM (use 0) or a slot ROM. -1 for none (default -1)
-panicSS

View File

@ -18,7 +18,6 @@ type Apple2 struct {
isApple2e bool
commandChannel chan int
cycleDurationNs float64 // Current speed. Inverse of the cpu clock in Ghz
isColor bool
fastMode bool
fastRequestsCounter int
profile bool
@ -126,8 +125,6 @@ const (
CommandToggleSpeed = iota + 1
// CommandShowSpeed toggles printinf the current freq in Mhz
CommandShowSpeed
// CommandToggleColor toggles between NTSC color TV and Green phospor monitor
CommandToggleColor
// CommandDumpDebugInfo dumps useful info
CommandDumpDebugInfo
// CommandNextCharGenPage cycles the CharGen page if several
@ -159,8 +156,6 @@ func (a *Apple2) executeCommand(command int) {
}
case CommandShowSpeed:
a.showSpeed = !a.showSpeed
case CommandToggleColor:
a.isColor = !a.isColor
case CommandDumpDebugInfo:
a.dumpDebugInfo()
case CommandNextCharGenPage:

View File

@ -15,9 +15,8 @@ func newApple2() *Apple2 {
return &a
}
func (a *Apple2) setup(isColor bool, clockMhz float64, fastMode bool, traceMLI bool) {
func (a *Apple2) setup(clockMhz float64, fastMode bool, traceMLI bool) {
a.commandChannel = make(chan int, 100)
a.isColor = isColor
a.fastMode = fastMode
if traceMLI {
a.traceMLI = newTraceProDOS(a)

View File

@ -81,10 +81,6 @@ func MainApple() *Apple2 {
"nsc",
-1,
"add a DS1216 No-Slot-Clock on the main ROM (use 0) or a slot ROM. -1 for none")
mono := flag.Bool(
"mono",
false,
"emulate a green phosphor monitor instead of a NTSC color TV. Use F6 to toggle.")
rgbCard := flag.Bool(
"rgb",
true,
@ -155,7 +151,7 @@ func MainApple() *Apple2 {
}
a := newApple2()
a.setup(!*mono, *cpuClock, *fastDisk, *traceMLI)
a.setup(*cpuClock, *fastDisk, *traceMLI)
a.io.setTrace(*traceSS)
a.io.setTraceRegistrations(*traceSSReg)
a.io.setPanicNotImplemented(*panicSS)

View File

@ -88,7 +88,7 @@ func sdlRun(a *izapple2.Apple2) {
img = a.SnapshotParts()
window.SetTitle(fmt.Sprintf("%v %v %vx%v", a.Name, a.VideoModeName(), img.Rect.Dx()/2, img.Rect.Dy()/2))
} else {
img = a.Snapshot()
img = a.Snapshot(izapple2.ScreenModeNTSC)
}
if img != nil {
surface, err := sdl.CreateRGBSurfaceFrom(unsafe.Pointer(&img.Pix[0]),

View File

@ -94,8 +94,6 @@ func (k *sdlKeyboard) putKey(keyEvent *sdl.KeyboardEvent) {
} else {
k.a.SendCommand(izapple2.CommandToggleSpeed)
}
case sdl.K_F6:
k.a.SendCommand(izapple2.CommandToggleColor)
case sdl.K_F7:
k.showPages = !k.showPages
case sdl.K_F9:
@ -106,7 +104,7 @@ func (k *sdlKeyboard) putKey(keyEvent *sdl.KeyboardEvent) {
k.a.SendCommand(izapple2.CommandToggleCPUTrace)
case sdl.K_F12:
case sdl.K_PRINTSCREEN:
err := izapple2.SaveSnapshot(k.a, "snapshot.png")
err := izapple2.SaveSnapshot(k.a, izapple2.ScreenModeNTSC, "snapshot.png")
if err != nil {
fmt.Printf("Error saving snapshoot: %v.\n.", err)
} else {

View File

@ -40,6 +40,15 @@ const (
videoSecondPage uint16 = 0x1000
)
const (
// ScreenModeGreen to render as a green phosphor monitor
ScreenModeGreen = iota
// ScreenModePlain to render in color with filled areas
ScreenModePlain
//ScreenModeNTSC shows spaces between pixels
ScreenModeNTSC
)
func getCurrentVideoMode(a *Apple2) uint16 {
isTextMode := a.io.isSoftSwitchActive(ioFlagText)
isHiResMode := a.io.isSoftSwitchActive(ioFlagHiRes)
@ -106,22 +115,19 @@ func getCurrentVideoMode(a *Apple2) uint16 {
return mode
}
func snapshotByMode(a *Apple2, videoMode uint16) *image.RGBA {
func snapshotByMode(a *Apple2, videoMode uint16, screenMode int) *image.RGBA {
videoBase := videoMode & videoBaseMask
mixMode := videoMode & videoMixTextMask
isSecondPage := (videoMode & videoSecondPage) != 0
var lightColor color.Color
if a.isColor {
lightColor = color.White
} else {
var lightColor color.Color = color.White
if screenMode == ScreenModeGreen {
// Color for typical Apple ][ period green P1 phosphor monitors
// See: https://superuser.com/questions/361297/what-colour-is-the-dark-green-on-old-fashioned-green-screen-computer-displays
lightColor = color.RGBA{65, 255, 0, 255}
}
applyNTSCFilter := a.isColor
applyNTSCFilter := screenMode != ScreenModeGreen
var snap *image.RGBA
var ntscMask *image.Alpha
switch videoBase {
@ -155,12 +161,12 @@ func snapshotByMode(a *Apple2, videoMode uint16) *image.RGBA {
}
if applyNTSCFilter {
snap = filterNTSCColor(snap, ntscMask)
snap = filterNTSCColor(snap, ntscMask, screenMode)
}
if mixMode != 0 {
var bottom *image.RGBA
applyNTSCFilter := a.isColor
applyNTSCFilter := screenMode != ScreenModeGreen
switch mixMode {
case videoMixText40:
bottom = snapshotText40Mode(a, isSecondPage, lightColor)
@ -171,7 +177,7 @@ func snapshotByMode(a *Apple2, videoMode uint16) *image.RGBA {
applyNTSCFilter = false
}
if applyNTSCFilter {
bottom = filterNTSCColor(bottom, ntscMask)
bottom = filterNTSCColor(bottom, ntscMask, screenMode)
}
snap = mixSnapshots(snap, bottom)
}
@ -180,11 +186,11 @@ func snapshotByMode(a *Apple2, videoMode uint16) *image.RGBA {
}
// Snapshot the currently visible screen
func (a *Apple2) Snapshot() *image.RGBA {
func (a *Apple2) Snapshot(screenMode int) *image.RGBA {
videoMode := getCurrentVideoMode(a)
snap := snapshotByMode(a, videoMode)
snap := snapshotByMode(a, videoMode, screenMode)
if snap.Bounds().Dy() == hiResHeight {
if screenMode == ScreenModeNTSC && snap.Bounds().Dy() == hiResHeight {
// Apply the filter to regular CRT snapshots with 192 lines. Not to SHR
snap = linesSeparatedFilter(snap)
}
@ -207,8 +213,8 @@ func mixSnapshots(top, bottom *image.RGBA) *image.RGBA {
}
// SaveSnapshot saves a snapshot of the screen to a png file
func SaveSnapshot(a *Apple2, filename string) error {
img := a.Snapshot()
func SaveSnapshot(a *Apple2, screenMode int, filename string) error {
img := a.Snapshot(screenMode)
img = squarishPixelsFilter(img)
f, err := os.Create(filename)

View File

@ -12,9 +12,9 @@ func (a *Apple2) SnapshotParts() *image.RGBA {
mixMode := videoMode & videoMixTextMask
modifiers := videoMode & videoModifiersMask
snapScreen := snapshotByMode(a, videoMode)
snapPage1 := snapshotByMode(a, videoMode&^videoSecondPage)
snapPage2 := snapshotByMode(a, videoMode|videoSecondPage)
snapScreen := snapshotByMode(a, videoMode, ScreenModePlain)
snapPage1 := snapshotByMode(a, videoMode&^videoSecondPage, ScreenModePlain)
snapPage2 := snapshotByMode(a, videoMode|videoSecondPage, ScreenModePlain)
var snapAux *image.RGBA
/*
@ -28,11 +28,11 @@ func (a *Apple2) SnapshotParts() *image.RGBA {
} else {
switch mixMode {
case videoMixText80:
snapAux = snapshotByMode(a, videoText80|modifiers)
snapAux = snapshotByMode(a, videoText80|modifiers, ScreenModePlain)
case videoMixText40RGB:
snapAux = snapshotByMode(a, videoText40RGB|modifiers)
snapAux = snapshotByMode(a, videoText40RGB|modifiers, ScreenModePlain)
default:
snapAux = snapshotByMode(a, videoText40|modifiers)
snapAux = snapshotByMode(a, videoText40|modifiers, ScreenModePlain)
}
}
@ -46,18 +46,14 @@ func (a *Apple2) VideoModeName() string {
mixMode := videoMode & videoMixTextMask
var name string
applyNTSCFilter := a.isColor
switch videoBase {
case videoText40:
name = "TEXT40COL"
applyNTSCFilter = false
case videoText80:
name = "TEXT80COL"
applyNTSCFilter = false
case videoText40RGB:
name = "TEXT40COLRGB"
applyNTSCFilter = false
case videoGR:
name = "GR"
case videoDGR:
@ -68,14 +64,12 @@ func (a *Apple2) VideoModeName() string {
name = "DHGR"
case videoMono560:
name = "Mono560"
applyNTSCFilter = false
case videoRGBMix:
name = "RGMMIX"
case videoRGB160:
name = "RGB160"
case videoSHR:
name = "SHR"
applyNTSCFilter = false
default:
name = "Unknown video mode"
}
@ -93,9 +87,6 @@ func (a *Apple2) VideoModeName() string {
name += "-MIX40RGB"
}
if applyNTSCFilter {
name += "-NTSC"
}
return name
}

View File

@ -49,14 +49,16 @@ var rgbColorMap = [16]color.Color{
color.RGBA{255, 255, 255, 255}, // White
}
func filterNTSCColor(in *image.RGBA, mask *image.Alpha) *image.RGBA {
func filterNTSCColor(in *image.RGBA, mask *image.Alpha, screenMode int) *image.RGBA {
colorMap := ntscColorMap // or rgbColorMap
attenuatedColorMap := make([]color.Color, 16, 16)
for i := 0; i < len(colorMap); i++ {
r, g, b, _ := colorMap[i].RGBA()
attenuatedColorMap[i] = color.RGBA64{
uint16(r / 2), uint16(g / 2), uint16(b / 2),
65535,
attenuatedColorMap := ntscColorMap
if screenMode == ScreenModeNTSC {
for i := 0; i < len(colorMap); i++ {
r, g, b, _ := colorMap[i].RGBA()
attenuatedColorMap[i] = color.RGBA64{
uint16(r / 2), uint16(g / 2), uint16(b / 2),
65535,
}
}
}