mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-29 08:29:46 +00:00
Show alt text character map
This commit is contained in:
parent
e49bef397b
commit
9d040fa58b
@ -159,6 +159,7 @@ Line:
|
||||
- F7: Show the video mode and a split screen with the views for NTSC color TV, page 1, page 2 and extra info.
|
||||
- F10: Cycle character generator code pages. Only if the character generator ROM has more than one 2Kb page.
|
||||
- Ctrl-F10: Show the charater map for the current character generator page.
|
||||
- Shift-F10: When showing the character map, use altText.
|
||||
- F11: Toggle on and off the trace to console of the CPU execution
|
||||
- F12: Save a screen snapshot to a file `snapshot.png`
|
||||
- Pause: Pause the emulation
|
||||
|
@ -91,7 +91,7 @@ func sdlRun(a *izapple2.Apple2) {
|
||||
if !a.IsPaused() {
|
||||
var img *image.RGBA
|
||||
if kp.showCharGen {
|
||||
img = screen.SnapshotCharacterGenerator(a)
|
||||
img = screen.SnapshotCharacterGenerator(a, kp.showAltText)
|
||||
window.SetTitle(fmt.Sprintf("%v character map", a.Name))
|
||||
} else if kp.showPages {
|
||||
img = screen.SnapshotParts(a, screen.ScreenModeNTSC)
|
||||
|
@ -14,6 +14,7 @@ type sdlKeyboard struct {
|
||||
|
||||
showPages bool
|
||||
showCharGen bool
|
||||
showAltText bool
|
||||
}
|
||||
|
||||
func newSDLKeyBoard(a *izapple2.Apple2) *sdlKeyboard {
|
||||
@ -43,6 +44,7 @@ func (k *sdlKeyboard) putKey(keyEvent *sdl.KeyboardEvent) {
|
||||
|
||||
key := keyEvent.Keysym
|
||||
ctrl := key.Mod&sdl.KMOD_CTRL != 0
|
||||
shift := key.Mod&sdl.KMOD_SHIFT != 0
|
||||
|
||||
if ctrl {
|
||||
if key.Sym >= 'a' && key.Sym <= 'z' {
|
||||
@ -103,6 +105,8 @@ func (k *sdlKeyboard) putKey(keyEvent *sdl.KeyboardEvent) {
|
||||
case sdl.K_F10:
|
||||
if ctrl {
|
||||
k.showCharGen = !k.showCharGen
|
||||
} else if shift {
|
||||
k.showAltText = !k.showAltText
|
||||
} else {
|
||||
k.a.SendCommand(izapple2.CommandNextCharGenPage)
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ func snapshotByMode(vs VideoSource, videoMode uint16, screenMode int) *image.RGB
|
||||
videoBase := videoMode & VideoBaseMask
|
||||
mixMode := videoMode & VideoMixTextMask
|
||||
isSecondPage := (videoMode & VideoSecondPage) != 0
|
||||
isAltText := (videoMode & VideoAltText) != 0
|
||||
|
||||
var lightColor color.Color = color.White
|
||||
if screenMode == ScreenModeGreen {
|
||||
@ -53,13 +54,13 @@ func snapshotByMode(vs VideoSource, videoMode uint16, screenMode int) *image.RGB
|
||||
var ntscMask *image.Alpha
|
||||
switch videoBase {
|
||||
case VideoText40:
|
||||
snap = snapshotText40(vs, isSecondPage, lightColor)
|
||||
snap = snapshotText40(vs, isSecondPage, isAltText, lightColor)
|
||||
applyNTSCFilter = false
|
||||
case VideoText80:
|
||||
snap = snapshotText80(vs, isSecondPage, lightColor)
|
||||
snap = snapshotText80(vs, isSecondPage, isAltText, lightColor)
|
||||
applyNTSCFilter = false
|
||||
case VideoText40RGB:
|
||||
snap = snapshotText40RGB(vs, isSecondPage)
|
||||
snap = snapshotText40RGB(vs, isSecondPage, isAltText)
|
||||
applyNTSCFilter = false
|
||||
case VideoGR:
|
||||
snap = snapshotLoRes(vs, isSecondPage, lightColor)
|
||||
@ -90,11 +91,11 @@ func snapshotByMode(vs VideoSource, videoMode uint16, screenMode int) *image.RGB
|
||||
applyNTSCFilter := screenMode != ScreenModeGreen
|
||||
switch mixMode {
|
||||
case VideoMixText40:
|
||||
bottom = snapshotText40(vs, isSecondPage, lightColor)
|
||||
bottom = snapshotText40(vs, isSecondPage, isAltText, lightColor)
|
||||
case VideoMixText80:
|
||||
bottom = snapshotText80(vs, isSecondPage, lightColor)
|
||||
bottom = snapshotText80(vs, isSecondPage, isAltText, lightColor)
|
||||
case VideoMixText40RGB:
|
||||
bottom = snapshotText40RGB(vs, isSecondPage)
|
||||
bottom = snapshotText40RGB(vs, isSecondPage, isAltText)
|
||||
applyNTSCFilter = false
|
||||
}
|
||||
if applyNTSCFilter {
|
||||
|
@ -79,6 +79,10 @@ func VideoModeName(vs VideoSource) string {
|
||||
name += "-PAGE2"
|
||||
}
|
||||
|
||||
if (videoMode & VideoAltText) != 0 {
|
||||
name += "-ALT"
|
||||
}
|
||||
|
||||
switch mixMode {
|
||||
case VideoMixText40:
|
||||
name += "-MIX40"
|
||||
@ -130,7 +134,7 @@ func doubleWidthFilter(in *image.RGBA) *image.RGBA {
|
||||
}
|
||||
|
||||
// SnapshotCharacterGenerator shows the current character set
|
||||
func SnapshotCharacterGenerator(vs VideoSource) *image.RGBA {
|
||||
func SnapshotCharacterGenerator(vs VideoSource, isAltText bool) *image.RGBA {
|
||||
text := make([]uint8, textLines*text40Columns)
|
||||
for l := 0; l < textLines; l++ {
|
||||
for c := 0; c < text40Columns; c++ {
|
||||
@ -144,5 +148,5 @@ func SnapshotCharacterGenerator(vs VideoSource) *image.RGBA {
|
||||
}
|
||||
}
|
||||
|
||||
return renderText(vs, text, nil, color.White)
|
||||
return renderText(vs, text, isAltText, nil, color.White)
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ func (ts *TestScenario) GetVideoMemory(secondPage bool, ext bool) []uint8 {
|
||||
}
|
||||
|
||||
// GetCharacterPixel returns the pixel as output by the character generator
|
||||
func (ts *TestScenario) GetCharacterPixel(char uint8, rowInChar int, colInChar int) bool {
|
||||
func (ts *TestScenario) GetCharacterPixel(char uint8, rowInChar int, colInChar int, isAltText bool, isFlashedFrame bool) bool {
|
||||
// We don't have a character generator. We will return a square or blank for spaces
|
||||
if char&0x3f == 0x20 {
|
||||
return false // Space char
|
||||
|
@ -3,6 +3,7 @@ package screen
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -12,25 +13,25 @@ const (
|
||||
textLines = 24
|
||||
)
|
||||
|
||||
func snapshotText40(vs VideoSource, isSecondPage bool, light color.Color) *image.RGBA {
|
||||
func snapshotText40(vs VideoSource, isSecondPage bool, isAltText bool, light color.Color) *image.RGBA {
|
||||
text := getTextFromMemory(vs, isSecondPage, false)
|
||||
return renderText(vs, text, nil /*colorMap*/, light)
|
||||
return renderText(vs, text, isAltText, nil /*colorMap*/, light)
|
||||
}
|
||||
|
||||
func snapshotText80(vs VideoSource, isSecondPage bool, light color.Color) *image.RGBA {
|
||||
func snapshotText80(vs VideoSource, isSecondPage bool, isAltText bool, light color.Color) *image.RGBA {
|
||||
text := getText80FromMemory(vs, isSecondPage)
|
||||
return renderText(vs, text, nil /*colorMap*/, light)
|
||||
return renderText(vs, text, isAltText, nil /*colorMap*/, light)
|
||||
}
|
||||
|
||||
func snapshotText40RGB(vs VideoSource, isSecondPage bool) *image.RGBA {
|
||||
func snapshotText40RGB(vs VideoSource, isSecondPage bool, isAltText bool) *image.RGBA {
|
||||
text := getTextFromMemory(vs, isSecondPage, false)
|
||||
colorMap := getTextFromMemory(vs, isSecondPage, true)
|
||||
return renderText(vs, text, colorMap, nil)
|
||||
return renderText(vs, text, isAltText, colorMap, nil)
|
||||
}
|
||||
|
||||
func snapshotText40RGBColors(vs VideoSource, isSecondPage bool) *image.RGBA {
|
||||
colorMap := getTextFromMemory(vs, isSecondPage, true)
|
||||
return renderText(vs, nil /*text*/, colorMap, nil)
|
||||
return renderText(vs, nil /*text*/, false, colorMap, nil)
|
||||
}
|
||||
|
||||
func getText80FromMemory(vs VideoSource, isSecondPage bool) []uint8 {
|
||||
@ -77,7 +78,10 @@ func getRGBTextColor(pixel bool, colorKey uint8) color.Color {
|
||||
|
||||
}
|
||||
|
||||
func renderText(vs VideoSource, text []uint8, colorMap []uint8, light color.Color) *image.RGBA {
|
||||
func renderText(vs VideoSource, text []uint8, isAltText bool, colorMap []uint8, light color.Color) *image.RGBA {
|
||||
// Flash mode is 2Hz (host time)
|
||||
isFlashedFrame := time.Now().Nanosecond() > (1 * 1000 * 1000 * 1000 / 2)
|
||||
|
||||
columns := len(text) / textLines
|
||||
if text == nil {
|
||||
columns = text40Columns
|
||||
@ -102,7 +106,7 @@ func renderText(vs VideoSource, text []uint8, colorMap []uint8, light color.Colo
|
||||
char = 79 + 128 // Debug screen filed with O
|
||||
}
|
||||
|
||||
pixel := vs.GetCharacterPixel(char, rowInChar, colInChar)
|
||||
pixel := vs.GetCharacterPixel(char, rowInChar, colInChar, isAltText, isFlashedFrame)
|
||||
|
||||
var colour color.Color
|
||||
if colorMap != nil {
|
||||
|
@ -28,6 +28,7 @@ const (
|
||||
const (
|
||||
VideoModifiersMask uint16 = 0xf000
|
||||
VideoSecondPage uint16 = 0x1000
|
||||
VideoAltText uint16 = 0x2000
|
||||
)
|
||||
|
||||
// VideoSource provides the info to build the video output
|
||||
@ -39,7 +40,7 @@ type VideoSource interface {
|
||||
// GetVideoMemory returns a slice to the video memory pages
|
||||
GetVideoMemory(secondPage bool, ext bool) []uint8
|
||||
// GetCharactePixel returns the pixel as output by the character generator
|
||||
GetCharacterPixel(char uint8, rowInChar int, colInChar int) bool
|
||||
GetCharacterPixel(char uint8, rowInChar int, colInChar int, isAltText bool, isFlashedFrame bool) bool
|
||||
// GetSuperVideoMemory returns a slice to the SHR video memory
|
||||
GetSuperVideoMemory() []uint8
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package izapple2
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ivanizag/izapple2/screen"
|
||||
)
|
||||
|
||||
@ -34,6 +32,8 @@ func (a *Apple2) GetCurrentVideoMode() uint16 {
|
||||
isRGB160Mode := isDoubleResMode && rgbFlag1 && !rgbFlag2
|
||||
|
||||
isMixMode := a.io.isSoftSwitchActive(ioFlagMixed)
|
||||
isSecondPage := a.io.isSoftSwitchActive(ioFlagSecondPage) && !a.mmu.store80Active
|
||||
isAltText := a.isApple2e && a.io.isSoftSwitchActive(ioFlagAltChar)
|
||||
|
||||
var mode uint16
|
||||
if isSuperHighResMode {
|
||||
@ -76,10 +76,12 @@ func (a *Apple2) GetCurrentVideoMode() uint16 {
|
||||
mode |= screen.VideoMixText40
|
||||
}
|
||||
}
|
||||
isSecondPage := a.io.isSoftSwitchActive(ioFlagSecondPage) && !a.mmu.store80Active
|
||||
if isSecondPage {
|
||||
mode |= screen.VideoSecondPage
|
||||
}
|
||||
if isAltText {
|
||||
mode |= screen.VideoAltText
|
||||
}
|
||||
|
||||
return mode
|
||||
}
|
||||
@ -111,11 +113,7 @@ func (a *Apple2) GetSuperVideoMemory() []uint8 {
|
||||
}
|
||||
|
||||
// GetCharacterPixel returns the pixel as output by the character generator
|
||||
func (a *Apple2) GetCharacterPixel(char uint8, rowInChar int, colInChar int) bool {
|
||||
// Flash mode is 2Hz (host time)
|
||||
isFlashedFrame := time.Now().Nanosecond() > (1 * 1000 * 1000 * 1000 / 2)
|
||||
isAltText := a.io.isSoftSwitchActive(ioFlagAltChar)
|
||||
|
||||
func (a *Apple2) GetCharacterPixel(char uint8, rowInChar int, colInChar int, isAltText bool, isFlashedFrame bool) bool {
|
||||
var pixel bool
|
||||
if a.isApple2e {
|
||||
vid6 := (char & 0x40) != 0
|
||||
|
Loading…
Reference in New Issue
Block a user