mirror of
https://github.com/freewilll/apple2-go.git
synced 2025-01-04 12:30:20 +00:00
Added lores mode
This commit is contained in:
parent
0a7b8c81b3
commit
7ae4159424
@ -47,7 +47,7 @@ func update(screen *ebiten.Image) error {
|
||||
checkResetKeys()
|
||||
|
||||
cpu.Run(*showInstructions, breakAddress, *disableFirmwareWait, 1024000/60)
|
||||
return video.DrawTextScreen(screen)
|
||||
return video.DrawScreen(screen)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
18
mmu/io.go
18
mmu/io.go
@ -98,6 +98,11 @@ var DriveState struct {
|
||||
Q7 bool
|
||||
}
|
||||
|
||||
var VideoState struct {
|
||||
TextMode bool
|
||||
Mixed bool
|
||||
}
|
||||
|
||||
func InitIO() {
|
||||
// Empty slots that aren't yet implemented
|
||||
emptySlot(3)
|
||||
@ -113,6 +118,9 @@ func InitIO() {
|
||||
DriveState.Q6 = false
|
||||
DriveState.Q7 = false
|
||||
|
||||
VideoState.TextMode = true
|
||||
VideoState.Mixed = false
|
||||
|
||||
InitDiskImage()
|
||||
}
|
||||
|
||||
@ -125,8 +133,16 @@ func driveIsreadSequencing() bool {
|
||||
func readWrite(address uint16, isRead bool) bool {
|
||||
switch address {
|
||||
case CLRTEXT:
|
||||
panic("CLRTEXT not implemented")
|
||||
VideoState.TextMode = false
|
||||
return true
|
||||
case SETTEXT:
|
||||
VideoState.TextMode = true
|
||||
return true
|
||||
case CLRMIXED:
|
||||
VideoState.Mixed = false
|
||||
return true
|
||||
case SETMIXED:
|
||||
VideoState.Mixed = true
|
||||
return true
|
||||
case TXTPAGE1:
|
||||
return true
|
||||
|
133
video/video.go
133
video/video.go
@ -2,6 +2,7 @@ package video
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"mos6502go/mmu"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
@ -18,6 +19,7 @@ var (
|
||||
charMap *ebiten.Image
|
||||
flashCounter int
|
||||
flashOn bool
|
||||
loresSquares [16]*ebiten.Image
|
||||
)
|
||||
|
||||
func Init() {
|
||||
@ -27,9 +29,94 @@ func Init() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 16; i++ {
|
||||
loresSquares[i], err = ebiten.NewImage(7, 4, ebiten.FilterNearest)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// From
|
||||
// https://mrob.com/pub/xapple2/colors.html
|
||||
// https://archive.org/details/IIgs_2523063_Master_Color_Values
|
||||
|
||||
alpha := uint8(0xff)
|
||||
loresSquares[0x00].Fill(color.NRGBA{0, 0, 0, alpha})
|
||||
loresSquares[0x01].Fill(color.NRGBA{221, 0, 51, alpha})
|
||||
loresSquares[0x02].Fill(color.NRGBA{0, 0, 153, alpha})
|
||||
loresSquares[0x03].Fill(color.NRGBA{221, 34, 221, alpha})
|
||||
loresSquares[0x04].Fill(color.NRGBA{0, 119, 34, alpha})
|
||||
loresSquares[0x05].Fill(color.NRGBA{85, 85, 85, alpha})
|
||||
loresSquares[0x06].Fill(color.NRGBA{34, 34, 255, alpha})
|
||||
loresSquares[0x07].Fill(color.NRGBA{102, 170, 255, alpha})
|
||||
loresSquares[0x08].Fill(color.NRGBA{136, 85, 0, alpha})
|
||||
loresSquares[0x09].Fill(color.NRGBA{255, 102, 0, alpha})
|
||||
loresSquares[0x0A].Fill(color.NRGBA{170, 170, 170, alpha})
|
||||
loresSquares[0x0B].Fill(color.NRGBA{255, 153, 136, alpha})
|
||||
loresSquares[0x0C].Fill(color.NRGBA{17, 221, 0, alpha})
|
||||
loresSquares[0x0D].Fill(color.NRGBA{255, 255, 0, alpha})
|
||||
loresSquares[0x0E].Fill(color.NRGBA{68, 255, 153, alpha})
|
||||
loresSquares[0x0F].Fill(color.NRGBA{255, 255, 255, alpha})
|
||||
}
|
||||
|
||||
func DrawTextScreen(screen *ebiten.Image) error {
|
||||
func drawText(screen *ebiten.Image, x int, y int, value uint8, flashOn bool) error {
|
||||
inverted := false
|
||||
|
||||
if (value & 0xc0) == 0 {
|
||||
inverted = true
|
||||
} else if (value & 0x80) == 0 {
|
||||
value = value & 0x3f
|
||||
inverted = flashOn
|
||||
}
|
||||
|
||||
if !inverted {
|
||||
value = value & 0x7f
|
||||
}
|
||||
|
||||
if value < 0x20 {
|
||||
value += 0x40
|
||||
}
|
||||
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Scale(screenSizeFactor, screenSizeFactor)
|
||||
op.GeoM.Translate(screenSizeFactor*7*float64(x), screenSizeFactor*8*float64(y))
|
||||
|
||||
fontRow := value % 16
|
||||
fontCol := value / 16
|
||||
var fontX = (int)(15 + fontCol*12)
|
||||
var fontY = (int)(32 + fontRow*11)
|
||||
r := image.Rect(fontX, fontY, fontX+7, fontY+8)
|
||||
op.SourceRect = &r
|
||||
|
||||
if !inverted {
|
||||
op.ColorM.Scale(-1, -1, -1, 1)
|
||||
op.ColorM.Translate(1, 1, 1, 0)
|
||||
}
|
||||
|
||||
op.ColorM.Scale(0.20, 0.75, 0.20, 1)
|
||||
|
||||
return screen.DrawImage(charMap, op)
|
||||
}
|
||||
|
||||
func drawLores(screen *ebiten.Image, x int, y int, value uint8) error {
|
||||
var values [2]uint8 = [2]uint8{value & 0xf, value >> 4}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Scale(screenSizeFactor, screenSizeFactor)
|
||||
op.GeoM.Translate(screenSizeFactor*7*float64(x), screenSizeFactor*8*float64(y)+float64(i)*4)
|
||||
if err := screen.DrawImage(loresSquares[values[i]], op); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func DrawScreen(screen *ebiten.Image) error {
|
||||
topHalfIsLowRes := !mmu.VideoState.TextMode
|
||||
bottomHalfIsLowRes := !mmu.VideoState.TextMode && !mmu.VideoState.Mixed
|
||||
|
||||
flashCounter--
|
||||
if flashCounter < 0 {
|
||||
flashCounter = flashFrames
|
||||
@ -45,44 +132,18 @@ func DrawTextScreen(screen *ebiten.Image) error {
|
||||
for x := 0; x < 40; x++ {
|
||||
offset := textVideoMemory + base + x
|
||||
value := mmu.PageTable[offset>>8][offset&0xff]
|
||||
inverted := false
|
||||
|
||||
if (value & 0xc0) == 0 {
|
||||
inverted = true
|
||||
} else if (value & 0x80) == 0 {
|
||||
value = value & 0x3f
|
||||
inverted = flashOn
|
||||
topHalf := y < 20
|
||||
if (topHalf && topHalfIsLowRes) || (!topHalf && bottomHalfIsLowRes) {
|
||||
if err := drawLores(screen, x, y, value); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := drawText(screen, x, y, value, flashOn); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !inverted {
|
||||
value = value & 0x7f
|
||||
}
|
||||
|
||||
if value < 0x20 {
|
||||
value += 0x40
|
||||
}
|
||||
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Scale(screenSizeFactor, screenSizeFactor)
|
||||
op.GeoM.Translate(screenSizeFactor*7*float64(x), screenSizeFactor*8*float64(y))
|
||||
|
||||
fontRow := value % 16
|
||||
fontCol := value / 16
|
||||
var fontX = (int)(15 + fontCol*12)
|
||||
var fontY = (int)(32 + fontRow*11)
|
||||
r := image.Rect(fontX, fontY, fontX+7, fontY+8)
|
||||
op.SourceRect = &r
|
||||
|
||||
if !inverted {
|
||||
op.ColorM.Scale(-1, -1, -1, 1)
|
||||
op.ColorM.Translate(1, 1, 1, 0)
|
||||
}
|
||||
|
||||
op.ColorM.Scale(0.20, 0.75, 0.20, 1)
|
||||
|
||||
if err := screen.DrawImage(charMap, op); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user