REM. Sprite plotter and clipper using DrawIconRTR.bin relocatable module
MODE 8 : OFF
ON ERROR OSCLI "REFRESH ON" : ON : CLS : REPORT : PRINT " at line "; ERL : VDU 7 : END
DIM mc% 255
OSCLI "LOAD """ + @lib$ + "DrawIconRTR.bin"" " + STR$~mc%
DrawIconRTR% = mc% + 3
REM. Create then select a 32-bpp ARGB 'DIBSection' (of dimensions
REM. @vdu%!208 by @vdu%!212 pixels) into BB4W's DC:
pBuffer% = FN_createDIBSection( @vdu%!208, @vdu%!212 )
DIM Buffer{T%,W%,H%,B%,P%,M%}
Buffer.W% = @vdu%!208
Buffer.H% = @vdu%!212
Buffer.M% = pBuffer%
REM. Create a 'test' 128x80, 32-bpp ARGB bitmap to be drawn using PROC_drawBitmap
REM. Feel free to experiment with the dimensions
REM. (HIMEM may need to be adjusted if bitmap is too big!)
bmW% = 128
bmH% = 80
bm% = FN_createTestBitmap( bmW%, bmH% )
DIM Bitmap{T%,W%,H%,B%,P%,M%}
Bitmap.W% = bmW%
Bitmap.H% = bmH%
Bitmap.M% = bm%
DIM pt{X%,Y%}
*REFRESH OFF
scale = 1.0
REPEAT
WAIT 2 : CLS
PRINT "Left button to scale up, right button to scale down, middle button to reflect";
SYS "GetCursorPos", pt{}
SYS "ScreenToClient", @hwnd%, pt{}
dx% = bmW%*scale
dy% = bmH%*scale
IF INKEY(-11) dx% = -dx%
IF INKEY(-10) scale *= 1.05
IF INKEY(-12) scale /= 1.05
SYS DrawIconRTR%, Buffer{}, pt.X%-ABS(dx%/2), pt.Y%-ABS(dy%/2), \
\ Bitmap{}, dx%, dy%
SYS "InvalidateRect", @hwnd%, 0, 0
*REFRESH
UNTIL FALSE
END
REM. ------------------------------------------------------------------------
REM. The code contained within this function (FN_createDIBSection) is the
REM. the work of Richard Russell, hereby acknowledged. :)
REM. ------------------------------------------------------------------------
DEF FN_createDIBSection( W%, H% )
LOCAL bits%
DIM BITMAPINFOHEADER{Size%, Width%, Height%, Planes{l&,h&}, BitCount{l&,h&}, \
\ Compression%, SizeImage%, XPelsPerMeter%, YPelsPerMeter%, \
\ ClrUsed%, ClrImportant%}
DIM bmi{Header{} = BITMAPINFOHEADER{}}
bmi.Header.Size% = DIM(BITMAPINFOHEADER{})
bmi.Header.Width% = W%
bmi.Header.Height% = H%
bmi.Header.Planes.l& = 1
bmi.Header.BitCount.l& = 32
SYS "CreateDIBSection", @memhdc%, bmi{}, 0, ^bits%, 0, 0 TO hbitmap%
IF hbitmap% = 0 ERROR 100, "Couldn't create DIBSection"
SYS "SelectObject", @memhdc%, hbitmap% TO oldhbm%
SYS "DeleteObject", oldhbm%
CLS
= bits%
DEF FN_createTestBitmap( bmW%, bmH% )
LOCAL bm%, I%, X%, Y%, r%
DIM bm% 4 * bmW%*bmH% +3 : REM. Needs extra 4 bytes (not 3!) for memory alignment
bm% = (bm% + 3) AND -4 : REM. Ensures bitmap base address is DWORD-aligned (divisible by 4)
REM. Fill our bitmap with the colour "SlateBlue" (= &6A5ACD)
FOR I% = bm% TO bm% + (4*bmW%*bmH% - 1) STEP 4
!I% = &6A5ACD
NEXT I%
REM. Give our bitmap a bright yellow border
FOR X% = 0 TO bmW%-1
bm%!(4*X%) = &FFFF00
bm%!(4*(bmW%*(bmH%-1) + X%)) = &FFFF00
NEXT X%
FOR Y% = 0 TO bmH%-1
bm%!(4*Y%*bmW%) = &FFFF00
bm%!(4*(Y%*bmW% + (bmW%-1))) = &FFFF00
NEXT Y%
REM. Draw a sine wave on the bitmap
FOR X% = 0 TO bmW%-1
Y% = bmH%DIV2 + bmH%DIV4*SIN(4*PI * X%/(bmW%-1))
bm%!(4*(Y%*bmW% + X%)) = &FFFFFF
NEXT X%
REM. Draw a circle on our bitmap
FOR I% = 0 TO 359
r% = 0.25 * SQR((bmW%/2)^2 + (bmH%/2)^2)
X% = bmW%/2 + r%*SINRADI%
Y% = bmH%/2 + r%*COSRADI%
IF X% < 0 X% = 0
IF Y% < 0 Y% = 0
IF X% > bmW%-1 X% = bmW%-1
IF Y% > bmH%-1 Y% = bmH%-1
bm%!(4*(Y%*bmW% + X%)) = &00FF00
NEXT I%
= bm%
REM. -----------------
REM. PlotSpeedTest.BBC
REM. -----------------
REM.
REM. Compare -- not too scientifically! -- plotting speeds of
REM. DrawIconRTR and GFXLIB_PlotScaleBlend
MODE 8
SOUND 1, 0, 0, 0 : SOUND OFF
ON ERROR OSCLI "REFRESH ON" : ON : CLS : REPORT : PRINT " at line "; ERL : VDU 7 : END
INSTALL @lib$ + "GFXLIB2.BBC" : PROCInitGFXLIB(d{}, 0)
INSTALL @lib$ + "GFXLIB_modules\PlotScaleBlend.BBC" : PROCInitModule
GetTickCount% = FNSYS_NameToAddress( "GetTickCount" )
DIM mc% 255
OSCLI "LOAD """ + @lib$ + "DrawIconRTR.bin"" " + STR$~mc%
DrawIconRTR% = mc% + 3
DIM Buffer{T%,W%,H%,B%,P%,M%}
Buffer.W% = @vdu%!208 : Buffer.H% = @vdu%!212 : Buffer.M% = d.bmBuffAddr%
REM. Create a 'test' 128x80, 32-bpp ARGB bitmap
bmW% = 128 : bmH% = 80 : bm% = FN_createTestBitmap( bmW%, bmH% )
DIM Bitmap{T%,W%,H%,B%,P%,M%}
Bitmap.W% = bmW% : Bitmap.H% = bmH% : Bitmap.M% = bm%
COLOUR 15 : PRINT '" DrawIconRTR vs. GFXLIB_PlotScaleBlend"' : COLOUR 7
INPUT '" Enter a scale factor (1.0) "; scale
INPUT '" How many iterations? (10000) "; N%
IF N% <= 0 THEN N% = 10000
IF scale = 0 THEN scale = 1.0
IF scale < 0 THEN scale *= -1.0
DIM pt{X%,Y%}
dx% = bmW%*scale
dy% = bmH%*scale
pt.X% = 320
pt.Y% = 256
bmW2% = scale * bmW%
bmH2% = scale * bmH%
OFF : WAIT 50
SYS "GetCurrentProcess" TO hprocess%
SYS "SetPriorityClass", hprocess%, &80
REM. Display the 'test bitmap' using DrawIconRTR
SYS DrawIconRTR%, Buffer{}, pt.X%, pt.Y%, Bitmap{}, dx%, dy%
SYS "InvalidateRect", @hwnd%, 0, 0
*REFRESH
REM. Time DrawIconRTR%
PRINT '" Timing DrawIconRTR ("; N%; " calls; scale factor: ";scale;")..." : WAIT 50
*REFRESH OFF
SYS GetTickCount% TO timeA_0%
FOR I% = 1 TO N%
SYS DrawIconRTR%, Buffer{}, pt.X%, pt.Y%, Bitmap{}, dx%, dy%
NEXT
SYS GetTickCount% TO timeA_1%
*REFRESH ON
REM. Display the 'test bitmap' using GFXLIB_PlotScaleBlend
SYS GFXLIB_PlotScaleBlend%, d{}, bm%, bmW%, bmH%, bmW2%, bmH2%, pt.X%, pt.Y%, 254
SYS "InvalidateRect", @hwnd%, 0, 0
*REFRESH
REM. Time GFXLIB_PlotScaleBlend
PRINT '" Timing GFXLIB_PlotScaleBlend ("; N%; " calls; scale factor: ";scale;")..." : WAIT 50
*REFRESH OFF
SYS GetTickCount% TO timeB_0%
FOR I% = 1 TO N%
SYS GFXLIB_PlotScaleBlend%, d{}, bm%, bmW%, bmH%, bmW2%, bmH2%, pt.X%, pt.Y%, 254
NEXT
SYS GetTickCount% TO timeB_1%
*REFRESH ON
SYS "GetCurrentProcess" TO hprocess%
SYS "SetPriorityClass", hprocess%, &20
PRINT '" " + STRING$(40,"-")'
PRINT '" DrawIconRTR took "; (timeA_1% - timeA_0%)/1000; " s."
PRINT '" GFXLIB_PlotScaleBlend took "; (timeB_1% - timeB_0%)/1000; " s."
COLOUR 3 : PRINT ''" Finished." : COLOUR 7
SOUND 1, -10, 220, 1
ON
END
DEF FN_createTestBitmap( bmW%, bmH% )
LOCAL bm%, I%, X%, Y%, r%
DIM bm% 4 * bmW%*bmH% +3 : REM. Needs extra 4 bytes (not 3!) for memory alignment
bm% = (bm% + 3) AND -4 : REM. Ensures bitmap base address is DWORD-aligned (divisible by 4)
REM. Fill our bitmap with the colour "SlateBlue" (= &6A5ACD)
FOR I% = bm% TO bm% + (4*bmW%*bmH% - 1) STEP 4
!I% = &6A5ACD
NEXT I%
REM. Give our bitmap a bright yellow border
FOR X% = 0 TO bmW%-1
bm%!(4*X%) = &FFFF00
bm%!(4*(bmW%*(bmH%-1) + X%)) = &FFFF00
NEXT X%
FOR Y% = 0 TO bmH%-1
bm%!(4*Y%*bmW%) = &FFFF00
bm%!(4*(Y%*bmW% + (bmW%-1))) = &FFFF00
NEXT Y%
REM. Draw a sine wave on the bitmap
FOR X% = 0 TO bmW%-1
Y% = bmH%DIV2 + bmH%DIV4*SIN(4*PI * X%/(bmW%-1))
bm%!(4*(Y%*bmW% + X%)) = &FFFFFF
NEXT X%
REM. Draw a circle on our bitmap
FOR I% = 0 TO 359
r% = 0.25 * SQR((bmW%/2)^2 + (bmH%/2)^2)
X% = bmW%/2 + r%*SINRADI%
Y% = bmH%/2 + r%*COSRADI%
IF X% < 0 X% = 0
IF Y% < 0 Y% = 0
IF X% > bmW%-1 X% = bmW%-1
IF Y% > bmH%-1 Y% = bmH%-1
bm%!(4*(Y%*bmW% + X%)) = &00FF00
NEXT I%
= bm%