mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-10-31 20:09:02 +00:00
98 lines
2.3 KiB
Go
98 lines
2.3 KiB
Go
package screen
|
|
|
|
import (
|
|
"image"
|
|
"image/color"
|
|
)
|
|
|
|
const (
|
|
shrWidth = 640
|
|
shrWidthBytes = 640 / 4
|
|
shrHeight = 200
|
|
palettesCount = 256
|
|
|
|
shrScanLineControlOffset = uint16(0x7d00)
|
|
shrColorPalettesOffset = uint16(0x7e00)
|
|
)
|
|
|
|
func snapshotSuperHiRes(vs VideoSource) *image.RGBA {
|
|
data := vs.GetSuperVideoMemory()
|
|
return renderSuperHiRes(data)
|
|
}
|
|
|
|
func renderSuperHiRes(data []uint8) *image.RGBA {
|
|
// See "Apple IIGS Hardware Reference", chapter 4, page 91
|
|
// http://www.applelogic.org/files/GSHARDWAREREF.pdf
|
|
size := image.Rect(0, 0, shrWidth, shrHeight)
|
|
img := image.NewRGBA(size)
|
|
|
|
// Load the palettes
|
|
colors := make([]color.Color, palettesCount)
|
|
iMem := uint16(0)
|
|
for i := 0; i < palettesCount; i++ {
|
|
b0 := data[iMem+shrColorPalettesOffset]
|
|
iMem++
|
|
b1 := data[iMem+shrColorPalettesOffset]
|
|
iMem++
|
|
|
|
red := (b1 & 0x0f) << 4
|
|
green := b0 & 0xf0
|
|
blue := (b0 & 0x0f) << 4
|
|
|
|
colors[i] = color.RGBA{red, green, blue, 255}
|
|
}
|
|
|
|
// See "Apple IIGS Hardware Reference", table 4-21
|
|
palettesSelectionTable := []uint8{0x4, 0x0, 0xc, 0x8}
|
|
|
|
// Build the lines
|
|
for y := 0; y < shrHeight; y++ {
|
|
controlByte := data[uint16(y)+shrScanLineControlOffset]
|
|
is640Wide := (controlByte & 0x80) != 0
|
|
isColorFill := (controlByte & 0x20) != 0
|
|
paletteIndex := (controlByte & 0x0f) << 4
|
|
|
|
lineAddress := uint16(shrWidthBytes * y)
|
|
lineBytes := data[lineAddress : lineAddress+shrWidthBytes]
|
|
if is640Wide {
|
|
// Line is 640 pixels, two bits per pixel
|
|
x := 0
|
|
for i := 0; i < shrWidthBytes; i++ {
|
|
b := lineBytes[i]
|
|
for j := 3; j >= 0; j-- {
|
|
p := (b >> (uint(j) * 2)) & 0x03
|
|
offset := palettesSelectionTable[j]
|
|
color := colors[paletteIndex+offset+p]
|
|
img.Set(x, y, color)
|
|
x++
|
|
}
|
|
}
|
|
} else {
|
|
// Line is 320 pixels, two pixels per byte
|
|
x := 0
|
|
previousColor := uint8(0)
|
|
for i := 0; i < shrWidthBytes; i++ {
|
|
p0 := (lineBytes[i] & 0xf0) >> 4
|
|
if isColorFill && p0 == 0 {
|
|
p0 = previousColor
|
|
} else {
|
|
previousColor = p0
|
|
}
|
|
p1 := lineBytes[i] & 0x0f
|
|
if isColorFill && p1 == 0 {
|
|
p1 = previousColor
|
|
} else {
|
|
previousColor = p1
|
|
}
|
|
img.Set(x, y, colors[paletteIndex+p0])
|
|
img.Set(x+1, y, colors[paletteIndex+p0])
|
|
img.Set(x+2, y, colors[paletteIndex+p1])
|
|
img.Set(x+3, y, colors[paletteIndex+p1])
|
|
x += 4
|
|
}
|
|
}
|
|
}
|
|
|
|
return img
|
|
}
|