izapple2/screen/textToAnsi.go

95 lines
2.5 KiB
Go

package screen
import (
"fmt"
"strings"
)
// RenderTextModeAnsi returns the text mode contents using ANSI escape codes for reverse and flash
func RenderTextModeAnsi(vs VideoSource, is80Columns bool, isSecondPage bool, isAltText bool, isApple2e bool) string {
//func DumpTextModeAnsi(a *Apple2) string {
// is80Columns := a.io.isSoftSwitchActive(ioFlag80Col)
// isSecondPage := a.io.isSoftSwitchActive(ioFlagSecondPage) && !a.mmu.store80Active
// isAltText := a.isApple2e && a.io.isSoftSwitchActive(ioFlagAltChar)
var text []uint8
if is80Columns {
text = getText80FromMemory(vs, isSecondPage)
} else {
text = getTextFromMemory(vs, isSecondPage, false)
}
columns := len(text) / textLines
content := "\n"
content += fmt.Sprintln(strings.Repeat("#", columns+4))
for l := 0; l < textLines; l++ {
line := ""
for c := 0; c < columns; c++ {
char := text[l*columns+c]
line += textMemoryByteToString(char, isAltText, isApple2e, true)
}
content += fmt.Sprintf("# %v #\n", line)
}
content += fmt.Sprintln(strings.Repeat("#", columns+4))
return content
}
/*
See Apple IIe reference manual. Table 2-5
---------Ascii----II+------IIe------AltChar--AltCEnh
$00-$1f Control Upp Inv Upp Inv Upp Inv Upp Inv
$20-$3f Symbols Sym Inv Sym Inv Sym Inv Upp Inv
$40-$5f UpperCa Upp Fla Upp Fla Upp Inv Mouse
$60-$7f LowerCa Sym Fla Sym Fla Low Inv Low Inv
$80-$9f Upp Nor Upp Nor Upp Nor Upp Nor
$a0-$bf Sym Nor Sym Nor Sym Nor Sym Nor
$c0-$df Upp Nor Upp Nor Upp Nor Upp Nor
$e0-$ff Low Nor Low Nor Low Nor Low Nor
----------------------------------------------------
*/
func textMemoryByteToString(value uint8, isAltCharSet bool, isApple2e bool, ansi bool) string {
// Normal, inverse or flash
topBits := value >> 6
isInverse := topBits == 0
isFlash := topBits == 1
if isFlash && isAltCharSet {
isFlash = false
isInverse = true
}
// Move blocks
value = value & 0x7f
if !isApple2e {
// No uppercase
value = value & 0x3f
}
if isFlash || isInverse && !isAltCharSet {
// No flash or inverse lowercase
value = value & 0x3f
}
if value < 0x20 {
// Control is Uppercase
value += 0x40
}
// Render
if value == 0x7f {
// DEL is full box
value = '_'
}
if ansi && isFlash {
if value == ' ' {
// Flashing space in Apple is the full box. It can't be done with ANSI codes
value = '_'
}
return fmt.Sprintf("\033[5m%v\033[0m", string(value))
} else if ansi && isInverse {
return fmt.Sprintf("\033[7m%v\033[0m", string(value))
} else {
return string(value)
}
}