Move frontends
@ -3,25 +3,25 @@ cd /tmp
|
||||
git clone https://github.com/ivanizag/izapple2
|
||||
|
||||
# Build izapple2console for Linux
|
||||
cd /tmp/izapple2/izapple2console
|
||||
cd /tmp/izapple2/frontend/console
|
||||
go build .
|
||||
chown --reference /build izapple2console
|
||||
cp izapple2console /build
|
||||
chown --reference /build console
|
||||
cp console /build/izapple2console
|
||||
|
||||
# Build izapple2console.exe for Windows
|
||||
cd /tmp/izapple2/izapple2console
|
||||
cd /tmp/izapple2/frontend/console
|
||||
env CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc GOOS=windows CGO_LDFLAGS="-L/usr/x86_64-w64-mingw32/lib" CGO_FLAGS="-I/usr/x86_64-w64-mingw32/include -D_REENTRANT" go build -o izapple2console.exe .
|
||||
chown --reference /build izapple2console.exe
|
||||
cp izapple2console.exe /build
|
||||
|
||||
# Build izapple2sdl for Linux
|
||||
cd /tmp/izapple2/izapple2sdl
|
||||
cd /tmp/izapple2/frontend/a2sdl
|
||||
go build .
|
||||
chown --reference /build izapple2sdl
|
||||
cp izapple2sdl /build
|
||||
chown --reference /build a2sdl
|
||||
cp a2sdl /build/izapple2sdl
|
||||
|
||||
# Build izapple2sdl.exe for Windows
|
||||
cd /tmp/izapple2/izapple2sdl
|
||||
cd /tmp/izapple2/frontend/a2sdl
|
||||
env CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc GOOS=windows CGO_LDFLAGS="-L/usr/x86_64-w64-mingw32/lib -lSDL2" CGO_FLAGS="-I/usr/x86_64-w64-mingw32/include -D_REENTRANT" go build -o izapple2sdl.exe .
|
||||
chown --reference /build izapple2sdl.exe
|
||||
cp izapple2sdl.exe /build
|
||||
|
@ -51,7 +51,7 @@ func (k *keyboard) putKeyAction(keyEvent *fyne.KeyEvent, press bool) {
|
||||
case fyne.KeyF1:
|
||||
k.s.a.SendCommand(izapple2.CommandReset)
|
||||
case fyne.KeyF12:
|
||||
screen.AddScenario(k.s.a, "../screen/test_resources/")
|
||||
screen.AddScenario(k.s.a, "../../screen/test_resources/")
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 518 B After Width: | Height: | Size: 518 B |
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 332 B |
Before Width: | Height: | Size: 449 B After Width: | Height: | Size: 449 B |
Before Width: | Height: | Size: 464 B After Width: | Height: | Size: 464 B |
Before Width: | Height: | Size: 416 B After Width: | Height: | Size: 416 B |
Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 386 B |
Before Width: | Height: | Size: 851 B After Width: | Height: | Size: 851 B |
Before Width: | Height: | Size: 325 B After Width: | Height: | Size: 325 B |
Before Width: | Height: | Size: 618 B After Width: | Height: | Size: 618 B |
Before Width: | Height: | Size: 626 B After Width: | Height: | Size: 626 B |
Before Width: | Height: | Size: 395 B After Width: | Height: | Size: 395 B |
@ -1,10 +1,8 @@
|
||||
package screen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -126,74 +124,3 @@ func renderText(vs VideoSource, text []uint8, colorMap []uint8, light color.Colo
|
||||
|
||||
return img
|
||||
}
|
||||
|
||||
// RenderTextModeAnsi returns the text mode contents using ANSI escape codes for reverse and flash
|
||||
func RenderTextModeAnsi(vs VideoSource, is80Columns bool, isSecondPage bool, isAltText 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)
|
||||
}
|
||||
content += fmt.Sprintf("# %v #\n", line)
|
||||
}
|
||||
|
||||
content += fmt.Sprintln(strings.Repeat("#", columns+4))
|
||||
return content
|
||||
}
|
||||
|
||||
func textMemoryByteToString(value uint8, isAltCharSet bool) string {
|
||||
// See https://en.wikipedia.org/wiki/Apple_II_character_set
|
||||
// Supports the new lowercase characters in the Apple2e
|
||||
// Only ascii from 0x20 to 0x5F is visible
|
||||
topBits := value >> 6
|
||||
isInverse := topBits == 0
|
||||
isFlash := topBits == 1
|
||||
if isFlash && isAltCharSet {
|
||||
// On the Apple2e with lowercase chars there is not flash mode.
|
||||
isFlash = false
|
||||
isInverse = true
|
||||
}
|
||||
|
||||
if isAltCharSet {
|
||||
value = value & 0x7F
|
||||
} else {
|
||||
value = value & 0x3F
|
||||
}
|
||||
|
||||
if value < 0x20 {
|
||||
value += 0x40
|
||||
}
|
||||
|
||||
if value == 0x7f {
|
||||
// DEL is full box
|
||||
value = '_'
|
||||
}
|
||||
|
||||
if 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 isInverse {
|
||||
return fmt.Sprintf("\033[7m%v\033[0m", string(value))
|
||||
} else {
|
||||
return string(value)
|
||||
}
|
||||
}
|
||||
|
94
screen/textToAnsi.go
Normal file
@ -0,0 +1,94 @@
|
||||
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)
|
||||
}
|
||||
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) 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 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 isInverse {
|
||||
return fmt.Sprintf("\033[7m%v\033[0m", string(value))
|
||||
} else {
|
||||
return string(value)
|
||||
}
|
||||
}
|
@ -26,7 +26,7 @@ func TestTextMemoryByteToString(t *testing.T) {
|
||||
}
|
||||
|
||||
func charExpectation(t *testing.T, arg uint8, alt bool, expect string) {
|
||||
s := textMemoryByteToString(arg, alt)
|
||||
s := textMemoryByteToString(arg, alt, alt)
|
||||
if s != expect {
|
||||
t.Errorf("For 0x%02x:%v, got %v, expected %v", arg, alt, s, expect)
|
||||
}
|
||||
|
@ -144,5 +144,5 @@ 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)
|
||||
return screen.RenderTextModeAnsi(a, is80Columns, isSecondPage, isAltText)
|
||||
return screen.RenderTextModeAnsi(a, is80Columns, isSecondPage, isAltText, a.isApple2e)
|
||||
}
|
||||
|