prog8/examples/cx16/imageviewer/pcx_module.p8

171 lines
5.6 KiB
Plaintext
Raw Normal View History

2020-12-12 00:17:30 +00:00
%target cx16
%import graphics
%import textio
%import diskio
2020-12-14 13:30:18 +00:00
pcx_module {
2020-12-12 00:17:30 +00:00
2020-12-14 14:34:52 +00:00
sub show_image(uword filenameptr) -> ubyte {
2020-12-12 00:17:30 +00:00
ubyte load_ok = false
if diskio.f_open(8, filenameptr) {
ubyte[128] header
uword size = diskio.f_read(header, 128)
if size==128 {
if header[0] == $0a and header[2] == 1 {
ubyte bits_per_pixel = header[3]
if bits_per_pixel==1 or bits_per_pixel==4 or bits_per_pixel==8 {
uword width = mkword(header[$09], header[$08]) - mkword(header[$05], header[$04]) + 1
uword height = mkword(header[$0b], header[$0a]) - mkword(header[$07], header[$06]) + 1
ubyte number_of_planes = header[$41]
uword palette_format = mkword(header[$45], header[$44])
uword num_colors = 2**bits_per_pixel
if number_of_planes == 1 {
if (width & 7) == 0 {
2020-12-14 01:12:26 +00:00
graphics.clear_screen(1, 0)
2020-12-12 00:17:30 +00:00
if palette_format==2
2020-12-14 13:30:18 +00:00
palette.set_grayscale()
2020-12-12 00:17:30 +00:00
else if num_colors == 16
2020-12-14 13:30:18 +00:00
palette.set_rgb8(&header + $10, 16)
2020-12-12 00:17:30 +00:00
else if num_colors == 2
2020-12-14 13:30:18 +00:00
palette.set_monochrome()
2020-12-12 00:17:30 +00:00
when bits_per_pixel {
8 -> load_ok = bitmap.do8bpp(width, height)
4 -> load_ok = bitmap.do4bpp(width, height)
1 -> load_ok = bitmap.do1bpp(width, height)
}
if load_ok {
load_ok = c64.CHRIN()
if load_ok == 12 {
; there is 256 colors of palette data at the end
uword palette_mem = progend()
load_ok = false
size = diskio.f_read(palette_mem, 3*256)
if size==3*256 {
load_ok = true
2020-12-14 14:34:52 +00:00
palette.set_rgb8(palette_mem, num_colors)
2020-12-12 00:17:30 +00:00
}
}
}
} else
txt.print("width not multiple of 8!\n")
} else
txt.print("has >256 colors!\n")
}
}
}
diskio.f_close()
}
2020-12-14 14:34:52 +00:00
return load_ok
2020-12-12 00:17:30 +00:00
}
}
bitmap {
uword offsetx
uword offsety
uword py
uword px
2020-12-12 02:32:15 +00:00
ubyte y_ok
2020-12-12 00:17:30 +00:00
ubyte status
2020-12-12 02:32:15 +00:00
sub start_plot(uword width, uword height) {
2020-12-12 00:17:30 +00:00
offsetx = 0
offsety = 0
2020-12-12 02:32:15 +00:00
y_ok = true
2020-12-12 00:17:30 +00:00
py = 0
px = 0
if width < graphics.WIDTH
2020-12-12 02:32:15 +00:00
offsetx = (graphics.WIDTH - width - 1) / 2
2020-12-12 00:17:30 +00:00
if height < graphics.HEIGHT
2020-12-12 02:32:15 +00:00
offsety = (graphics.HEIGHT - height - 1) / 2
2020-12-12 00:17:30 +00:00
status = (not c64.READST()) or c64.READST()==64
}
2020-12-12 02:32:15 +00:00
sub next_scanline() {
px = 0
py++
y_ok = py < graphics.HEIGHT-1
2020-12-21 22:45:26 +00:00
cx16.FB_cursor_position(offsetx, offsety+py)
2020-12-12 02:32:15 +00:00
status = (not c64.READST()) or c64.READST()==64
}
2020-12-12 00:17:30 +00:00
sub do1bpp(uword width, uword height) -> ubyte {
2020-12-12 02:32:15 +00:00
start_plot(width, height)
2020-12-21 22:45:26 +00:00
cx16.FB_cursor_position(offsetx, offsety)
2020-12-12 00:17:30 +00:00
while py < height and status {
ubyte b = c64.CHRIN()
if b>>6==3 {
2020-12-12 02:32:15 +00:00
b &= %00111111
ubyte dat = c64.CHRIN()
repeat b {
if y_ok
cx16.FB_set_8_pixels_opaque(255, 255, 0, dat)
2020-12-12 02:32:15 +00:00
px += 8
2020-12-12 00:17:30 +00:00
}
} else {
if y_ok
cx16.FB_set_8_pixels_opaque(255, 255, 0, b)
2020-12-12 02:32:15 +00:00
px += 8
2020-12-12 00:17:30 +00:00
}
2020-12-12 02:32:15 +00:00
if px==width
next_scanline()
2020-12-12 00:17:30 +00:00
}
return status
}
sub do4bpp(uword width, uword height) -> ubyte {
2020-12-12 02:32:15 +00:00
start_plot(width, height)
2020-12-21 22:45:26 +00:00
cx16.FB_cursor_position(offsetx, offsety)
2020-12-12 00:17:30 +00:00
while py < height and status {
ubyte b = c64.CHRIN()
if b>>6==3 {
2020-12-12 02:32:15 +00:00
b &= %00111111
ubyte dat = c64.CHRIN()
2020-12-12 00:17:30 +00:00
if y_ok
2020-12-12 02:32:15 +00:00
repeat b {
cx16.FB_set_pixel(dat>>4)
cx16.FB_set_pixel(dat & 15)
2020-12-12 00:17:30 +00:00
}
2020-12-12 02:32:15 +00:00
px += b*2
2020-12-12 00:17:30 +00:00
} else {
if y_ok {
2020-12-12 02:32:15 +00:00
cx16.FB_set_pixel(b>>4)
2020-12-12 00:17:30 +00:00
cx16.FB_set_pixel(b & 15)
}
2020-12-12 02:32:15 +00:00
px += 2
2020-12-12 00:17:30 +00:00
}
2020-12-12 02:32:15 +00:00
if px==width
next_scanline()
2020-12-12 00:17:30 +00:00
}
return status
}
sub do8bpp(uword width, uword height) -> ubyte {
2020-12-12 02:32:15 +00:00
start_plot(width, height)
2020-12-21 22:45:26 +00:00
cx16.FB_cursor_position(offsetx, offsety)
2020-12-12 00:17:30 +00:00
while py < height and status {
ubyte b = c64.CHRIN()
if b>>6==3 {
2020-12-12 02:32:15 +00:00
b &= %00111111
ubyte dat = c64.CHRIN()
2020-12-12 00:17:30 +00:00
if y_ok
2020-12-12 02:32:15 +00:00
repeat b
cx16.FB_set_pixel(dat)
px += b
2020-12-12 00:17:30 +00:00
} else {
if y_ok
cx16.FB_set_pixel(b)
px++
}
2020-12-12 02:32:15 +00:00
if px==width
next_scanline()
2020-12-12 00:17:30 +00:00
}
return status
}
}