REM. Warping bitmap
REM. Version 1.2 // 16-Mar-2012
REM. Requires GFXLIB version 2.03 or higher
*ESC OFF
*FLOAT 64
ON ERROR PROCerror( REPORT$, TRUE )
REM. Make 5 MB of RAM available for this program
M% = 5 : HIMEM = LOMEM + M%*&100000
REM. Set window title
ProgTitle$ = "Warping bitmap"
SYS "SetWindowText", @hwnd%, ProgTitle$
REM. Set window dimensions
WinW% = 480
WinH% = 480
PROCfixWindowSize
VDU 23, 22, WinW%; WinH%; 8, 16, 16, 0 : OFF
REM. Install and initialise GFXLIB and required modules
INSTALL @lib$ + "GFXLIB2.BBC" : PROCInitGFXLIB
INSTALL @lib$ + "GFXLIB_modules\ClrX.BBC" : PROCInitModule
INSTALL @lib$ + "GFXLIB_modules\PlotRotateScale2.BBC" : PROCInitModule
INSTALL @lib$ + "GFXLIB_modules\BPlotBMRow.BBC" : PROCInitModule
INSTALL @lib$ + "GFXLIB_modules\BPlotBMRowList.BBC" : PROCInitModule
INSTALL @lib$ + "GFXLIB_modules\BPlotBMColumn.BBC" : PROCInitModule
INSTALL @lib$ + "GFXLIB_modules\BPlotBMColumnList.BBC" : PROCInitModule
GetTickCount% = FNSYS_NameToAddress( "GetTickCount" )
TIME = 0
REM. Load the 400x96 "GFXLIB" graphic
bm% = FNLoadImg( @dir$ + "gfxlib_400x96x8.BMP", 0 )
REM. Set up two 480x480 32-bpp bitmap buffers
bm2% = FNmalloc( 4 * 480 * 480 )
bm3% = FNmalloc( 4 * 480 * 480 )
REM. Set up bitmap pixel rows and columns lists
REM. (for use with GFXLIB_BPlotBMRowList and GFXLIB_BPlotBColumnList)
DIM rowList{(479) row%, x%, y%}
DIM colList{(479) col%, x%, y%}
FOR I% = 0 TO 479
rowList{( I% )}.row% = I%
rowList{( I% )}.y% = I%
colList{( I% )}.col% = I%
colList{( I% )}.x% = I%
NEXT I%
REM. Bitmap rotation angle
angle = 0
REM. Frame counter (gets reset every second)
numFrames% = 0
REM. Turn off automatic window refresh
*REFRESH OFF
REM. Start the timer
SYS GetTickCount% TO time0%
REM. +---------------+
REM. | The main loop |
REM. +---------------+
REPEAT
REM. Clear the main program window
SYS GFXLIB_Clr%, dispVars{}, 0
REM. Set up some time-dependent values
T% = TIME
a = T% / 100
b = T% / 500
c = 32*SIN(T% / 1000)
d = T% / 333
REM. This loop could be made more efficient
FOR I% = 0 TO 479
rowList{(I%)}.x% = 64 * SIN(I%/100 + a) * COS(I%/300 + b)
colList{(I%)}.y% = 64 * COS(I%/200 + c) * SIN(I%/450 + d)
NEXT
REM. Make the angle and scale of the 480x480 "GFXLIB" bitmap vary with time
angle = 360 * SIN(T%/1000)*COS(T%/2000)
scale = 3 + 2*SIN(T%/500)
REM. Render the rotated and scaled "GFXLIB" bitmap to bm2
SYS GFXLIB_ClrX%, dispVars{}, bm2%, 480, 480, 0
SYS GFXLIB_SaveDispVars%, dispVars{}
SYS GFXLIB_SetDispVars2%, dispVars{}, bm2%, 480, 480
SYS GFXLIB_PlotRotateScale2%, dispVars{}, bm%, 400, 96, 240, 240, &10000*angle, &10000*scale
SYS GFXLIB_RestoreDispVars%, dispVars{}
REM. Write the horizontal pixel rows of bm2 to bm3
SYS GFXLIB_ClrX%, dispVars{}, bm3%, 480, 480, 0
SYS GFXLIB_SaveDispVars%, dispVars{}
SYS GFXLIB_SetDispVars2%, dispVars{}, bm3%, 480, 480
SYS GFXLIB_BPlotBMRowList%, dispVars{}, bm2%, 480, 480, ^rowList{(0)}.row%, 480
SYS GFXLIB_RestoreDispVars%, dispVars{}
REM. Write the vertical pixel columns of bm3 to our program window
SYS GFXLIB_BPlotBMColumnList%, dispVars{}, bm3%, 480, 480, ^colList{(0)}.col%, 480
REM. Update the program window
PROCdisplay
REM. Increment frame number; update fps value every second
SYS GetTickCount% TO time1%
IF time1%-time0% >= 1000 THEN
SYS "SetWindowText", @hwnd%, ProgTitle$ + " | " +STR$numFrames% + " fps"
SYS GetTickCount% TO time0%
numFrames% = 0
ELSE
numFrames% += 1
ENDIF
UNTIL FALSE
END
:
:
:
:
DEF PROCfixWindowSize
LOCAL GWL_STYLE, WS_THICKFRAME, WS_MAXIMIZEBOX, ws%
GWL_STYLE = -16
WS_THICKFRAME = &40000
WS_MAXIMIZEBOX = &10000
SYS "GetWindowLong", @hwnd%, GWL_STYLE TO ws%
SYS "SetWindowLong", @hwnd%, GWL_STYLE, ws% AND NOT (WS_THICKFRAME+WS_MAXIMIZEBOX)
ENDPROC
:
:
:
:
DEF PROCerror( s$, L% )
LOCAL hprocess%
SYS "GetCurrentProcess" TO hprocess%
SYS "SetPriorityClass", hprocess%, &20
OSCLI "REFRESH ON" : CLS : ON
COLOUR 1, &FF, &FF, &FF
COLOUR 1
PRINT TAB(1,1)s$;
IF L% THEN
PRINT " at line "; ERL;
ENDIF
VDU 7
REPEAT UNTIL INKEY(1)=0
ENDPROC