; $$$$$$$$$$$$$$$$$$$ ABAKIS $$$$$$$$$$$$$$$$$$$$$ ; *************** STAR^2 SOFTWARE **************** ; ;;;;;;;;;;;;;;;;;;; IMAGE ;;;;;;;;;;;;;;;;;;;;;; ; image class/object/structure macro IMAGE a { a: void a#.p integer a#.x, a#.y, a#.w, a#.h integer a#.bpp=32, a#.key, a#.alpha } virtual at 0 ?image.p dd 0 ?image.x dd 0 ?image.y dd 0 ?image.w dd 0 ?image.h dd 0 ?image.bpp dd 32 ?image.key dd 0 ?image.alpha dd 0 END virtual ?image.box fix ?image.x ; create image file/s with header: ; 8 bytes: ; byte s='I' ; signature ; byte v=0 ; version: AABBCC.VV ; int16 w, h ; size: w:h ; byte bpp ; bpp: 32/24/16/15/8 ; byte n ; # colors or 0=256+ ; byte pixels[w*h*(bpp/8)] ; or *2 if 15 macro IMAGE [p] { forward local w, h w=0 h=0 define ?s 0 match a==b, p \{ \local ..q ..q: inject.image b, 32 load w word from ..q+2 load h word from ..q+4 a: void a\#.p=..q+8 integer a\#.x, a\#.y, a\#.w=w, a\#.h=h integer a\#.bpp, a\#.key, a\#.alpha define ?s 1 \} IF ?s eq 0 IMAGE p END IF } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; load 24PP .BMP, store as .IMAGE 15/16/24/32. ; for OSs, ROMs. warning: causes slow compile ; with 1+ MB worth of images. to compile fast ; without images, comment "; IMAGE name='abc'" macro inject.image name, bpp { local i, p, a, r, g, b,\ x, y, w, h, wb virtual at 0 p:: file CD#'media/'#name#'.bmp' END virtual IF ~bpp in <15,16,24,32> 'Invalid BPP' name END IF load a word from p:0 IF a<>'BM' 'Invalid signature' name END IF load a byte from p:1Ch IF a<>24 'Must be 24BPP' name END IF load w dword from p:12h load h dword from p:16h db 'I', 0 dw w, h db bpp, 0 a=((3-((w*3)+3)) and 3) wb=(w*3)+a y=h WHILE y>0 o=36h+((y-1)*wb) x=0 WHILE x<w i=o+(x*3) load b byte from p:i load g byte from p:i+1 load r byte from p:i+2 IF bpp=32 dd (r shl 16) or (g shl 8) or b ELSE IF bpp=24 db r, g, b ; or b, g, r ELSE IF bpp=16 r=((r and 11111b)/8) shl 11 g=((g and 111111b)/4) shl 5 b=((b and 11111b)/8) dw r or g or b ELSE IF bpp=15 r=((r and 11111b)/8) shl 10 g=((g and 11111b)/8) shl 5 b=((b and 11111b)/8) dw r or g or b END IF x=x+1 END WHILE y=y-1 END WHILE } ; insert 8BPP .BMP as .IMAGE with palette. ; note: must use special .8 drawing macro inject.image.8 name { local i, p, a, c,\ x, y, w, h, wb virtual at 0 p:: file CD#'media/'#name#'.bmp' END virtual load a word from p:0 IF a<>'BM' 'Invalid signature' name END IF load a byte from p:1Ch IF a<>8 'Must be 8BPP' name END IF load w dword from p:12h load h dword from p:16h db 'I', 0 dw w, h db 8, 0 i=0 WHILE i<256 o=36h+(i*4) load b byte from p:o load g byte from p:o+1 load r byte from p:o+2 db b, g, r, 0 i=i+1 END WHILE a=((3-(w+3)) and 3) wb=w+a y=h WHILE y>0 o=436h+((y-1)*wb) x=0 WHILE x<w load c byte from p:o+x db c x=x+1 END WHILE y=y-1 END WHILE } macro IMAGE8 [p] { forward local w, h w=0 h=0 define ?s 0 match a==b, p \{ \local ..q ..q: inject.image.8 b load w word from ..q+2 load h word from ..q+4 a: void a\#.p=..q+408h integer a\#.x, a\#.y, a\#.w=w, a\#.h=h integer a\#.bpp, a\#.key, a\#.alpha ; ... void a\#.palette=..q+8 define ?s 1 \} IF ?s eq 0 'Error: 8BPP must specify file' END IF } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; unfinished, unorganized... ; 2-DO: convert to functions. create one ; good draw.scanline.x with bpp and type ; BIT flags: ; draw.scanline.x p, x, y, w, 32,\ ; G.KEY or G.ALPHA or G.GRAY or G.INVERT.X macro move.image i, x, y { . i#.x=x, i#.y=y } macro draw.image i, x, y { IF ~x eq move.image i, x, y END IF draw.bitmap i#.p, i#.x, i#.y, i#.w, i#.h } macro draw.image.t i, x, y { IF ~x eq move.image i, x, y END IF draw.bitmap.t i#.p, i#.x, i#.y, i#.w, i#.h } ; draw with inverted x/y macro draw.image.ix i, x, y { IF ~x eq move.image i, x, y END IF draw.bitmap.ix i#.p,\ i#.x, i#.y, i#.w, i#.h } macro draw.image.iy i, x, y { IF ~x eq move.image i, x, y END IF draw.bitmap.iy i#.p, i#.x, i#.y, i#.w, i#.h } macro draw.image.ixy i, x, y, ix, iy { IF ~x eq move.image i, x, y END IF draw.bitmap.ixy i#.p, i#.x, i#.y, i#.w, i#.h } macro draw.image.v i, x, y, c { IF ~x eq move.image i, x, y END IF draw.bitmap.v i#.p, i#.x, i#.y, i#.w, i#.h, c } ; draw rotated. warning: no clipping function draw.scanline.rl, pixels, x, y, w alias p=r0, s=r1, n=r2 vga.xy x, y . s=w, s--, s*4, s+pixels, n=screen.pitch loop w, (u32) *p=*s--, p+n, endl endf 1 function draw.scanline.rr, pixels, x, y, w alias p=r0, s=r1, n=r2 vga.xy x, y . s=pixels, n=screen.pitch loop w, (u32) *p=*s++, p+n, endl endf 1 function draw.bitmap.rl, pixels, x, y, w, h locals i, p try visible x, y, w, h . p=pixels loop h draw.scanline.rl p, x, y, w . r0=w, r0*4, p+r0, x++ endl endf 1 function draw.bitmap.rr, pixels, x, y, w, h locals i, p try visible x, y, w, h . r0=w, r0--, x+r0, p=pixels loop h draw.scanline.rr p, x, y, w . r0=w, r0*4, p+r0, x-- endl endf 1 macro draw.image.rl i, x, y { IF ~x eq move.image i, x, y END IF draw.bitmap.rl i#.p, i#.x, i#.y, i#.w, i#.h } macro draw.image.rr i, x, y { IF ~x eq move.image i, x, y END IF draw.bitmap.rr i#.p, i#.x, i#.y, i#.w, i#.h } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 8BPP with palette... macro draw.image.8 i, x, y { IF ~x eq move.image i, x, y END IF . palette.p=i#.palette draw.bitmap.8 i#.p, i#.x, i#.y, i#.w, i#.h } macro draw.image.v.8 i, x, y, c { IF ~x eq move.image i, x, y END IF . palette.p=i#.palette draw.bitmap.v.8 i#.p, i#.x, i#.y, i#.w, i#.h, c } function draw.image.v8, im, x, y, co locals p, w, h . r0=im . (u32) r1=*(r0+?image.p), p=r1 . (u32) r1=*(r0+?image.w), w=r1 . (u32) r1=*(r0+?image.h), h=r1 draw.bitmap.v.8 p, x, y, w, h, co endf function draw.bitmap.viy.8, pixels,\ x, y, w, h, c locals i, p try visible x, y, w, h . r0=h, y+r0, p=pixels loop h draw.scanline.v.8 p, x, y, w, c . r0=w, p+r0, y-- endl endf 1 function draw.image.viy.8, im, x, y, co locals p, w, h . r0=im . (u32) r1=*(r0+?image.p), p=r1 . (u32) r1=*(r0+?image.w), w=r1 . (u32) r1=*(r0+?image.h), h=r1 draw.bitmap.viy.8 p, x, y, w, h, co endf ;;;;;;;;;;;;;;;;;;; LOAD .BMP ;;;;;;;;;;;;;;;;;;;; ; load 8BPP .BMP as 32BIT pixel array. ; if success, return allocated pixels address ; in r0 and w/h in r1/r2. return 0 if error function load.bmp, file locals image, palette,\ p, s, x, y, w, h, a catch .error ; load file, get size then allocate ; 32BPP image... try file=load.file file . r1=[r0+18], r2=[r0+22] . w=r1, h=r2, r1*r2, r1*4 try image=allocate r1 ; create and load palette... try palette=allocate 1024 . r0=file, r0+54 memory.copy palette, r0, 1024 align.n w, 4 ; get alignment value . a=r1 ; 0-3 bytes ; advance to p/ixels data, point ; s/ource at first pixel in last ; line then read image upside down . p=image, r0=file, r0+54, r0+1024 . r1=w, r1+a, r2=h, r2--, r1*r2 . r0+r1, s=r0, y=h loop y, x=w loop x, r2=s, r1=*r2, r1*4 . r1+palette, r0=p, (u32) *r0=*r1 . p+4, s++ endl . r0=w, r0*2, r0+a, s-r0 endl destroy file, palette . r0=image, r1=w, r2=h return .error: destroy image, file, palette endf 0