mirror of
https://github.com/irmen/prog8.git
synced 2024-12-26 14:29:35 +00:00
added bmp viewer
This commit is contained in:
parent
3ba37df29d
commit
5134ea76bf
189
examples/cx16/imgviewer/bmpviewer.p8
Normal file
189
examples/cx16/imgviewer/bmpviewer.p8
Normal file
@ -0,0 +1,189 @@
|
||||
%target cx16
|
||||
%import graphics
|
||||
%import textio
|
||||
%import diskio
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
graphics.enable_bitmap_mode()
|
||||
|
||||
if strlen(diskio.status(8)) ; trick to check if we're running on sdcard or host system shared folder
|
||||
show_pics_sdcard()
|
||||
else {
|
||||
txt.print("only works with files on\nsdcard image!\n")
|
||||
}
|
||||
|
||||
repeat {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
sub show_pics_sdcard() {
|
||||
|
||||
; load and show all *.bmp pictures on the disk.
|
||||
; this only works in the emulator V38 with an sd-card image with the files on it.
|
||||
|
||||
str[20] filename_ptrs
|
||||
ubyte num_files = diskio.list_files(8, ".bmp", true, &filename_ptrs, len(filename_ptrs))
|
||||
if num_files {
|
||||
while num_files {
|
||||
num_files--
|
||||
bmp.show_bmp_image(filename_ptrs[num_files])
|
||||
cx16.wait(120)
|
||||
}
|
||||
} else {
|
||||
txt.print("no *.bmp files found\n")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bmp {
|
||||
|
||||
sub show_bmp_image(uword filenameptr) {
|
||||
ubyte load_ok = false
|
||||
txt.print(filenameptr)
|
||||
txt.chrout('\n')
|
||||
|
||||
ubyte[$36] header
|
||||
uword size
|
||||
uword width
|
||||
uword height
|
||||
ubyte bpp
|
||||
uword offsetx
|
||||
uword offsety
|
||||
ubyte[256] palette0
|
||||
ubyte[256] palette1
|
||||
ubyte[256] palette2
|
||||
ubyte[256] palette3
|
||||
uword total_read = 0
|
||||
|
||||
palette0[0] = 0
|
||||
palette1[0] = 0
|
||||
palette2[0] = 0
|
||||
palette3[0] = 0
|
||||
|
||||
if diskio.f_open(8, filenameptr) {
|
||||
size = diskio.f_read(header, $36)
|
||||
if size==$36 {
|
||||
total_read = $36
|
||||
if header[0]=='b' and header[1]=='m' {
|
||||
uword bm_data_offset = mkword(header[11], header[10])
|
||||
uword header_size = mkword(header[$f], header[$e])
|
||||
width = mkword(header[$13], header[$12])
|
||||
height = mkword(header[$17], header[$16])
|
||||
bpp = header[$1c]
|
||||
uword num_colors = header[$2e]
|
||||
if num_colors == 0
|
||||
num_colors = 2**bpp
|
||||
uword skip_hdr = header_size - 40
|
||||
repeat skip_hdr
|
||||
void c64.CHRIN()
|
||||
total_read += skip_hdr
|
||||
size = diskio.f_read(&palette0, num_colors*4)
|
||||
if size==num_colors*4 {
|
||||
total_read += size
|
||||
repeat bm_data_offset - total_read
|
||||
void c64.CHRIN()
|
||||
txt.clear_screen()
|
||||
graphics.clear_screen(1, 0)
|
||||
set_palette(&palette0, num_colors)
|
||||
decode_bitmap()
|
||||
load_ok = true
|
||||
}
|
||||
} else
|
||||
txt.print("not a bmp file!\n")
|
||||
}
|
||||
|
||||
diskio.f_close()
|
||||
}
|
||||
|
||||
if not load_ok {
|
||||
txt.print("load error!\n")
|
||||
txt.print(diskio.status(8))
|
||||
}
|
||||
|
||||
|
||||
sub start_plot() {
|
||||
offsetx = 0
|
||||
offsety = 0
|
||||
if width < graphics.WIDTH
|
||||
offsetx = (graphics.WIDTH - width - 1) / 2
|
||||
if height < graphics.HEIGHT
|
||||
offsety = (graphics.HEIGHT - height - 1) / 2
|
||||
if width > graphics.WIDTH
|
||||
width = graphics.WIDTH
|
||||
if height > graphics.HEIGHT-1
|
||||
height = graphics.HEIGHT-1
|
||||
}
|
||||
|
||||
sub set_cursor(uword x, uword y) {
|
||||
cx16.r0=offsetx+x
|
||||
cx16.r1=offsety+y
|
||||
cx16.FB_cursor_position()
|
||||
}
|
||||
|
||||
sub decode_bitmap() {
|
||||
start_plot()
|
||||
uword bits_width = width * bpp
|
||||
ubyte pad_bytes = (((bits_width + 31) >> 5) << 2) - ((bits_width + 7) >> 3) as ubyte
|
||||
|
||||
uword x
|
||||
uword y
|
||||
ubyte b
|
||||
for y in height-1 downto 0 {
|
||||
set_cursor(0, y)
|
||||
when bpp {
|
||||
8 -> {
|
||||
for x in 0 to width-1
|
||||
cx16.FB_set_pixel(c64.CHRIN())
|
||||
}
|
||||
4 -> {
|
||||
for x in 0 to width-1 step 2 {
|
||||
b = c64.CHRIN()
|
||||
cx16.FB_set_pixel(b>>4)
|
||||
cx16.FB_set_pixel(b&15)
|
||||
}
|
||||
}
|
||||
2 -> {
|
||||
for x in 0 to width-1 step 4 {
|
||||
b = c64.CHRIN()
|
||||
cx16.FB_set_pixel(b>>6)
|
||||
cx16.FB_set_pixel(b>>4 & 3)
|
||||
cx16.FB_set_pixel(b>>2 & 3)
|
||||
cx16.FB_set_pixel(b & 3)
|
||||
}
|
||||
}
|
||||
1 -> {
|
||||
for x in 0 to width-1 step 8 {
|
||||
cx16.r0 = c64.CHRIN()
|
||||
cx16.FB_set_8_pixels_opaque(255, 255, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repeat pad_bytes
|
||||
void c64.CHRIN()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub set_palette(uword palletteptr, uword num_colors) {
|
||||
uword vera_palette_ptr = $fa00
|
||||
ubyte red
|
||||
ubyte greenblue
|
||||
|
||||
; 4 bytes per color entry (BGRA), adjust color depth from 8 to 4 bits per channel.
|
||||
repeat num_colors {
|
||||
red = @(palletteptr+2) >> 4
|
||||
greenblue = @(palletteptr+1) & %11110000
|
||||
greenblue |= @(palletteptr+0) >> 4 ; add Blue
|
||||
palletteptr+=4
|
||||
cx16.vpoke(1, vera_palette_ptr, greenblue)
|
||||
vera_palette_ptr++
|
||||
cx16.vpoke(1, vera_palette_ptr, red)
|
||||
vera_palette_ptr++
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -36,7 +36,7 @@ main {
|
||||
}
|
||||
}
|
||||
|
||||
sub set_palette(uword palletteptr, uword num_colors) {
|
||||
sub set_palette_8rgb(uword palletteptr, uword num_colors) {
|
||||
uword vera_palette_ptr = $fa00
|
||||
ubyte red
|
||||
ubyte greenblue
|
||||
@ -119,7 +119,7 @@ iff {
|
||||
height /= 2 ; interlaced: just skip every odd scanline later
|
||||
if camg & $0080 and have_cmap
|
||||
make_ehb_palette()
|
||||
main.set_palette(&cmap, num_colors)
|
||||
main.set_palette_8rgb(&cmap, num_colors)
|
||||
if compression
|
||||
decode_rle()
|
||||
else
|
||||
|
@ -55,16 +55,12 @@ main {
|
||||
uword num_colors = 2**bits_per_pixel
|
||||
if number_of_planes == 1 {
|
||||
if (width & 7) == 0 {
|
||||
txt.print_uw(width)
|
||||
txt.chrout('x')
|
||||
txt.print_uw(height)
|
||||
txt.print(", ")
|
||||
txt.print_uw(num_colors)
|
||||
txt.print(" colors\n")
|
||||
txt.clear_screen()
|
||||
graphics.clear_screen(1, 0)
|
||||
if palette_format==2
|
||||
set_grayscale_palette()
|
||||
else if num_colors == 16
|
||||
set_palette(&header + $10, 16)
|
||||
set_palette_8rgb(&header + $10, 16)
|
||||
else if num_colors == 2
|
||||
set_monochrome_palette()
|
||||
when bits_per_pixel {
|
||||
@ -73,8 +69,6 @@ main {
|
||||
1 -> load_ok = bitmap.do1bpp(width, height)
|
||||
}
|
||||
if load_ok {
|
||||
txt.clear_screen()
|
||||
graphics.clear_screen(1, 0)
|
||||
load_ok = c64.CHRIN()
|
||||
if load_ok == 12 {
|
||||
; there is 256 colors of palette data at the end
|
||||
@ -83,7 +77,7 @@ main {
|
||||
size = diskio.f_read(palette_mem, 3*256)
|
||||
if size==3*256 {
|
||||
load_ok = true
|
||||
set_palette(palette_mem, num_colors)
|
||||
set_palette_8rgb(palette_mem, num_colors)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -131,7 +125,7 @@ main {
|
||||
}
|
||||
}
|
||||
|
||||
sub set_palette(uword palletteptr, uword num_colors) {
|
||||
sub set_palette_8rgb(uword palletteptr, uword num_colors) {
|
||||
uword vera_palette_ptr = $fa00
|
||||
ubyte red
|
||||
ubyte greenblue
|
||||
|
Loading…
Reference in New Issue
Block a user