Move frontends
|
@ -3,25 +3,25 @@ cd /tmp
|
||||||
git clone https://github.com/ivanizag/izapple2
|
git clone https://github.com/ivanizag/izapple2
|
||||||
|
|
||||||
# Build izapple2console for Linux
|
# Build izapple2console for Linux
|
||||||
cd /tmp/izapple2/izapple2console
|
cd /tmp/izapple2/frontend/console
|
||||||
go build .
|
go build .
|
||||||
chown --reference /build izapple2console
|
chown --reference /build console
|
||||||
cp izapple2console /build
|
cp console /build/izapple2console
|
||||||
|
|
||||||
# Build izapple2console.exe for Windows
|
# 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 .
|
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
|
chown --reference /build izapple2console.exe
|
||||||
cp izapple2console.exe /build
|
cp izapple2console.exe /build
|
||||||
|
|
||||||
# Build izapple2sdl for Linux
|
# Build izapple2sdl for Linux
|
||||||
cd /tmp/izapple2/izapple2sdl
|
cd /tmp/izapple2/frontend/a2sdl
|
||||||
go build .
|
go build .
|
||||||
chown --reference /build izapple2sdl
|
chown --reference /build a2sdl
|
||||||
cp izapple2sdl /build
|
cp a2sdl /build/izapple2sdl
|
||||||
|
|
||||||
# Build izapple2sdl.exe for Windows
|
# 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 .
|
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
|
chown --reference /build izapple2sdl.exe
|
||||||
cp izapple2sdl.exe /build
|
cp izapple2sdl.exe /build
|
||||||
|
|
|
@ -51,7 +51,7 @@ func (k *keyboard) putKeyAction(keyEvent *fyne.KeyEvent, press bool) {
|
||||||
case fyne.KeyF1:
|
case fyne.KeyF1:
|
||||||
k.s.a.SendCommand(izapple2.CommandReset)
|
k.s.a.SendCommand(izapple2.CommandReset)
|
||||||
case fyne.KeyF12:
|
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
|
package screen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -126,74 +124,3 @@ func renderText(vs VideoSource, text []uint8, colorMap []uint8, light color.Colo
|
||||||
|
|
||||||
return img
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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) {
|
func charExpectation(t *testing.T, arg uint8, alt bool, expect string) {
|
||||||
s := textMemoryByteToString(arg, alt)
|
s := textMemoryByteToString(arg, alt, alt)
|
||||||
if s != expect {
|
if s != expect {
|
||||||
t.Errorf("For 0x%02x:%v, got %v, expected %v", arg, alt, 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)
|
is80Columns := a.io.isSoftSwitchActive(ioFlag80Col)
|
||||||
isSecondPage := a.io.isSoftSwitchActive(ioFlagSecondPage) && !a.mmu.store80Active
|
isSecondPage := a.io.isSoftSwitchActive(ioFlagSecondPage) && !a.mmu.store80Active
|
||||||
isAltText := a.isApple2e && a.io.isSoftSwitchActive(ioFlagAltChar)
|
isAltText := a.isApple2e && a.io.isSoftSwitchActive(ioFlagAltChar)
|
||||||
return screen.RenderTextModeAnsi(a, is80Columns, isSecondPage, isAltText)
|
return screen.RenderTextModeAnsi(a, is80Columns, isSecondPage, isAltText, a.isApple2e)
|
||||||
}
|
}
|
||||||
|
|