Skip to content

Instantly share code, notes, and snippets.

@peterhellberg
Last active April 16, 2021 14:53
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peterhellberg/52d644a37caf8dfbcb515e93970a8dcf to your computer and use it in GitHub Desktop.
Save peterhellberg/52d644a37caf8dfbcb515e93970a8dcf to your computer and use it in GitHub Desktop.
Renderer for an answer to "Why was the Kickstart 1.x “Insert floppy” graphic so bad?" https://retrocomputing.stackexchange.com/a/13940
package main
import (
"image"
"image/draw"
"github.com/peterhellberg/gfx"
)
const width, height = 320, 200
var (
offset = gfx.Pt(70, 40)
palette = gfx.Palette{
gfx.ColorNRGBA(0xFF, 0xFF, 0xFF, 0xFF),
gfx.ColorNRGBA(0x00, 0x00, 0x00, 0xFF),
gfx.ColorNRGBA(0x77, 0x77, 0xCC, 0xFF),
gfx.ColorNRGBA(0xBB, 0xBB, 0xBB, 0xFF),
}
)
func main() {
var isDrawing, inFloodFill bool
var lineColor, fillColor uint8
var from, to image.Point
dst := gfx.NewPaletted(width, height, palette, palette[0])
for i := 0; i < len(data); i += 2 {
f, s := data[i], data[i+1]
switch f {
case 0xFF:
isDrawing = false
if s == 0xFF {
break
}
lineColor = s
continue
case 0xFE:
isDrawing = false
inFloodFill = true
fillColor = s
continue
}
if !isDrawing {
from = pt(f, s)
isDrawing = true
} else {
to = pt(f, s)
line(dst, from, to, lineColor)
from = pt(f, s)
}
if inFloodFill {
inFloodFill = false
flood(dst, pt(f, s), fillColor)
}
}
gfx.SavePNG("/tmp/gfx-kickstart-insert-floppy.png", gfx.NewScaledPalettedImage(dst, 8))
}
func pt(x, y byte) image.Point {
return gfx.Pt(int(x), int(y))
}
func line(dst draw.Image, a, b image.Point, index uint8) {
c := palette.Color(int(index))
gfx.DrawIntLine(dst, offset.X+a.X, offset.Y+a.Y, offset.X+b.X, offset.Y+b.Y, c)
}
func flood(dst *gfx.Paletted, p image.Point, index uint8) {
target := dst.ColorIndexAt(p.X, p.Y)
queue := []image.Point{p.Add(offset)}
for len(queue) > 0 {
p, queue = queue[0], queue[1:]
if p.In(dst.Bounds()) {
if dst.ColorIndexAt(p.X, p.Y) == target {
dst.SetColorIndex(p.X, p.Y, index)
queue = append(queue,
p.Add(gfx.Pt(0, 1)),
p.Add(gfx.Pt(1, 0)),
p.Add(gfx.Pt(0, -1)),
p.Add(gfx.Pt(-1, 0)),
)
}
}
}
}
var data = []byte{
0xFF, 0x01, 0x23, 0x0B, 0x3A, 0x0B, 0x3A, 0x21, 0x71, 0x21, 0x71, 0x0B, 0x7D, 0x0B, 0x88,
0x16, 0x88, 0x5E, 0x7F, 0x5E, 0x7F, 0x38, 0x40, 0x38, 0x3E, 0x36, 0x35, 0x36, 0x34, 0x38,
0x2D, 0x38, 0x2D, 0x41, 0x23, 0x48, 0x23, 0x0B, 0xFE, 0x02, 0x25, 0x45, 0xFF, 0x01, 0x21,
0x48, 0x21, 0x0A, 0x7E, 0x0A, 0x8A, 0x16, 0x8A, 0x5F, 0x56, 0x5F, 0x56, 0x64, 0x52, 0x6C,
0x4E, 0x71, 0x4A, 0x74, 0x44, 0x7D, 0x3C, 0x81, 0x3C, 0x8C, 0x0A, 0x8C, 0x0A, 0x6D, 0x09,
0x6D, 0x09, 0x51, 0x0D, 0x4B, 0x14, 0x45, 0x15, 0x41, 0x19, 0x3A, 0x1E, 0x37, 0x21, 0x36,
0x21, 0x36, 0x1E, 0x38, 0x1A, 0x3A, 0x16, 0x41, 0x15, 0x45, 0x0E, 0x4B, 0x0A, 0x51, 0x0A,
0x6C, 0x0B, 0x6D, 0x0B, 0x8B, 0x28, 0x8B, 0x28, 0x76, 0x30, 0x76, 0x34, 0x72, 0x34, 0x5F,
0x32, 0x5C, 0x32, 0x52, 0x41, 0x45, 0x41, 0x39, 0x3E, 0x37, 0x3B, 0x37, 0x3E, 0x3A, 0x3E,
0x41, 0x3D, 0x42, 0x36, 0x42, 0x33, 0x3F, 0x2A, 0x46, 0x1E, 0x4C, 0x12, 0x55, 0x12, 0x54,
0x1E, 0x4B, 0x1A, 0x4A, 0x17, 0x47, 0x1A, 0x49, 0x1E, 0x4A, 0x21, 0x48, 0xFF, 0x01, 0x32,
0x3D, 0x34, 0x36, 0x3C, 0x37, 0x3D, 0x3A, 0x3D, 0x41, 0x36, 0x41, 0x32, 0x3D, 0xFF, 0x01,
0x33, 0x5C, 0x33, 0x52, 0x42, 0x45, 0x42, 0x39, 0x7D, 0x39, 0x7D, 0x5E, 0x34, 0x5E, 0x33,
0x5A, 0xFF, 0x01, 0x3C, 0x0B, 0x6F, 0x0B, 0x6F, 0x20, 0x3C, 0x20, 0x3C, 0x0B, 0xFF, 0x01,
0x60, 0x0E, 0x6B, 0x0E, 0x6B, 0x1C, 0x60, 0x1C, 0x60, 0x0E, 0xFE, 0x03, 0x3E, 0x1F, 0xFF,
0x01, 0x62, 0x0F, 0x69, 0x0F, 0x69, 0x1B, 0x62, 0x1B, 0x62, 0x0F, 0xFE, 0x02, 0x63, 0x1A,
0xFF, 0x01, 0x2F, 0x39, 0x32, 0x39, 0x32, 0x3B, 0x2F, 0x3F, 0x2F, 0x39, 0xFF, 0x01, 0x29,
0x8B, 0x29, 0x77, 0x30, 0x77, 0x35, 0x72, 0x35, 0x69, 0x39, 0x6B, 0x41, 0x6B, 0x41, 0x6D,
0x45, 0x72, 0x49, 0x72, 0x49, 0x74, 0x43, 0x7D, 0x3B, 0x80, 0x3B, 0x8B, 0x29, 0x8B, 0xFF,
0x01, 0x35, 0x5F, 0x35, 0x64, 0x3A, 0x61, 0x35, 0x5F, 0xFF, 0x01, 0x39, 0x62, 0x35, 0x64,
0x35, 0x5F, 0x4A, 0x5F, 0x40, 0x69, 0x3F, 0x69, 0x41, 0x67, 0x3C, 0x62, 0x39, 0x62, 0xFF,
0x01, 0x4E, 0x5F, 0x55, 0x5F, 0x55, 0x64, 0x51, 0x6C, 0x4E, 0x70, 0x49, 0x71, 0x46, 0x71,
0x43, 0x6D, 0x43, 0x6A, 0x4E, 0x5F, 0xFF, 0x01, 0x44, 0x6A, 0x44, 0x6D, 0x46, 0x70, 0x48,
0x70, 0x4C, 0x6F, 0x4D, 0x6C, 0x49, 0x69, 0x44, 0x6A, 0xFF, 0x01, 0x36, 0x68, 0x3E, 0x6A,
0x40, 0x67, 0x3C, 0x63, 0x39, 0x63, 0x36, 0x65, 0x36, 0x68, 0xFF, 0x01, 0x7E, 0x0B, 0x89,
0x16, 0x89, 0x5E, 0xFE, 0x01, 0x22, 0x0B, 0xFE, 0x01, 0x3B, 0x0B, 0xFE, 0x01, 0x61, 0x0F,
0xFE, 0x01, 0x6A, 0x1B, 0xFE, 0x01, 0x70, 0x0F, 0xFE, 0x01, 0x7E, 0x5E, 0xFE, 0x01, 0x4B,
0x60, 0xFE, 0x01, 0x2E, 0x39, 0xFF, 0xFF,
}
@peterhellberg
Copy link
Author

peterhellberg commented Apr 2, 2021

gfx-kickstart-insert-floppy-001

@peterhellberg
Copy link
Author

gfx-kickstart-insert-floppy-002

@peterhellberg
Copy link
Author

gfx-kickstart-insert-floppy-003

@peterhellberg
Copy link
Author

I found this video of the ROM image being rendered on an Amiga:
https://www.youtube.com/watch?v=gXhxE4j6dm0

Their AMOS program that renders the image

Screen Open 0,640,256,4,Lowres
Curs Off : Flash Off : Cls 0 : Ink 1 : OFFSETX=70 : OFFSETY=40
Palette $FFF,$0,$77C,$BBB : Rem white, black, blue, grey 
Wait Key 
LASTX=OFFSETX : LASTY=OFFSETY : TYPE=0 : FINISHED=False
While Not FINISHED
  Read B1$ : Read B2$
  B1=Val("$"+B1$) : B2=Val("$"+B2$)
  If B1=255 and B2=255 : Rem exit 
    FINISHED=True
  Else If B1=255 : Rem Start new line 
    Ink B2 : TYPE=2
  Else If B1=254 : Rem Fill area
    Ink B2 : TYPE=1
  Else If TYPE=0 : Rem Draw line
    Polyline OFFSETX+LASTX,OFFSETY+LASTY To OFFSETX+B1,OFFSETY+B2
    LASTX=B1 : LASTY=B2
  Else : Rem If TYPE was set on previous bytes
    If TYPE=1 : Rem Fill     
      Paint OFFSETX+B1,OFFSETY+B2 : TYPE=0
    Else If TYPE=2 : Rem Set start coords 
      LASTX=B1 : LASTY=B2 : TYPE=0
    End If 
  End If 
  Wait 5
Wend 
Wait Key 
End 

Data "FF","01","23","0B","3A","0B","3A","21","71","21","71","0B","7D","0B","88","16","88","5E","7F","5E","7F",
"38","40","38"
Data "3E","36","35","36","34","38","2D","38","2D","41","23","48","23","0B","FE","02","25","45","FF","01","21",
"48","21","0A"
Data "7E","0A","8A","16","8A","5F","56","5F","56","64","52","6C","4E","71","4A","74","44","7D","3C","81","3C",
"8C","0A","8C"
Data "0A","6D","09","6D","09","51","0D","4B","14","45","15","41","19","3A","1E","37","21","36","21","36","1E",
"38","1A","3A"
Data "16","41","15","45","0E","4B","0A","51","0A","6C","0B","6D","0B","8B","28","8B","28","76","30","76","34",
"72","34","5F"
Data "32","5C","32","52","41","45","41","39","3E","37","3B","37","3E","3A","3E","41","3D","42","36","42","33",
"3F","2A","46"
Data "1E","4C","12","55","12","54","1E","4B","1A","4A","17","47","1A","49","1E","4A","21","48","FF","01","32",
"3D","34","36"
Data "3C","37","3D","3A","3D","41","36","41","32","3D","FF","01","33","5C","33","52","42","45","42","39","7D",
"39","7D","5E"
Data "34","5E","33","5A","FF","01","3C","0B","6F","0B","6F","20","3C","20","3C","0B","FF","01","60","0E","6B",
"0E","6B","1C"
Data "60","1C","60","0E","FE","03","3E","1F","FF","01","62","0F","69","0F","69","1B","62","1B","62","0F","FE",
"02","63","1A"
Data "FF","01","2F","39","32","39","32","3B","2F","3F","2F","39","FF","01","29","8B","29","77","30","77","35",
"72","35","69"
Data "39","6B","41","6B","41","6D","45","72","49","72","49","74","43","7D","3B","80","3B","8B","29","8B","FF",
"01","35","5F"
Data "35","64","3A","61","35","5F","FF","01","39","62","35","64","35","5F","4A","5F","40","69","3F","69","41",
"67","3C","62"
Data "39","62","FF","01","4E","5F","55","5F","55","64","51","6C","4E","70","49","71","46","71","43","6D","43",
"6A","4E","5F"
Data "FF","01","44","6A","44","6D","46","70","48","70","4C","6F","4D","6C","49","69","44","6A","FF","01","36",
"68","3E","6A"
Data "40","67","3C","63","39","63","36","65","36","68","FF","01","7E","0B","89","16","89","5E","FE","01","22",
"0B","FE","01"
Data "3B","0B","FE","01","61","0F","FE","01","6A","1B","FE","01","70","0F","FE","01","7E","5E","FE","01","4B",
"60","FE","01"
Data "2E","39","FF","FF"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment