REM "Bouncy Balls" // v1.00 (08-Feb-2017)
REM Tested with BB4W, BBCSDL (Win32), BBCSDL Android (ARM).
REM Not yet tested with BBCSDL under Mac OS-X or Linux.
REM There is currently no VSync ("Vertical Synchronization"),
REM so the animation is unlikely to be as smooth as it could be.
REM +-------------------------------------------------------------------+
REM | |
REM | This code is experimental and is not intended to be instructive |
REM | |
REM +-------------------------------------------------------------------+
ON ERROR PROCerror
HIMEM = LOMEM + 2*&100000 : HIMEM = (HIMEM + 7) AND -8
Balls% = 50
Wait% = TRUE : REM Setting to FALSE may improve performance (results in higher CPU usage)
REM -------------------------------------
BB4W% = (INKEY(-256) == &57)
IF BB4W% THEN
GetTicks$ = "GetTickCount"
SetWindowText$ = "SetWindowText"
ELSE
GetTicks$ = "SDL_GetTicks"
SetWindowText$ = "SDL_SetWindowTitle"
ENDIF
REM -------------------------------------
REM This code segment is the work of RTR:
p = PI
CASE !^p OF
WHEN &2168C235: cpu$ = "x86"
WHEN &54442D18: cpu$ = "ARM"
OTHERWISE: QUIT
ENDCASE
REM -------------------------------------
WinW% = 640
WinH% = 480
VDU 23,22,WinW%;WinH%;8,16,16,0 : OFF
DIM bmp{a%, w%, h%}
bmp% = FNCreateBMP_RGB565(WinW%, WinH%)
bmp.a% = bmp% + 70
bmp.w% = WinW%
bmp.h% = WinH%
S% = FNmalloc(2000)
CASE cpu$ OF
WHEN "x86":
$S%="60C7401CFFFFFFFF8B78143B78040F8DC00000008B70183B70080F8DB40000008B480C8B501083F9007D03F7D99083FA007D03F7DA90F7D93BF90F8E94000000"
$S%+="F7DA3BF20F8E8A000000F7D9F7DAC7401C00000000C7402000000000C7402400000000C740280000000089482C8950308978348970388BEF03E93B68047E0D2B"
$S%+="680429682CC74020FFFFFFFF83FF007D1429782801782CC7403400000000C74020FFFFFFFF8BEE03EA3B68087E0D2B6808296830C74020FFFFFFFF83FE007D14"
$S%+="297024017030C7403800000000C74020FFFFFFFF61C3"
ClipBitmap%=FNmcode(S%)
$S%="608BF88BC325FFFF00008BD8C1E3100BC3B900580200FCF3AB61C3"
Clr16_640x480%=FNmcode(S%)
$S%="6083EC208B53048B7B088950048978088B51048B790889500C8978108B510C8B7910895014897818FF10F7401CFFFFFFFF0F85530000008B1B8B098B7804893C"
$S%+="24D124240FAF7838037834D1E703FB8B700C89742404D16424040FAF7024037028D1E603F18B502C8B683033C9668B044E66A9FFFF74046689044F413BCA7CED"
$S%+="033C24037424044D75E183C42061C3"
Plot%=FNmcode(S%)
$S%="608BF88BF30FAFD133ED0FB604AF0FB65CAF010FB64CAF0269C01F1F000069DB3F3F000069C91F1F0000C1E81083D000C1EB1083D300C1E91083D100C1E305C1"
$S%+="E10B0BC30BC16689046E453BEA7CBB61C3"
ConvBmRGB565%=FNmcode(S%)
WHEN "ARM":
$S%="FF5F2DE900C0E0E31CC080E504B080E27E009BE8010055E1FF9FBDA8020056E1FF9FBDA8030075E1FF9FBDD8040076E1FF9FBDD894D08FE594E08FE500D0A0E3"
$S%+="00E0E0E31CD080E520D080E50070A0E30080A0E30390A0E104A0A0E103B085E001005BE101B04BC00B9049C020E080C5000055E3058048B0059089B00050A0B3"
$S%+="20E080B504B086E002005BE102B04BC00BA04AC020E080C5000056E3067047B006A08AB00060A0B320E080B5247080E5288080E52C9080E530A080E5345080E5"
$S%+="386080E504D09FE504E09FE5FF9FBDE80000000000000000"
ClipBitmap%=FNmcode(S%)
$S%="FF5F2DE9BCD08FE5BCE08FE50118A0E12118A0E1011881E10120A0E10230A0E10240A0E10250A0E10260A0E10270A0E10280A0E10290A0E102A0A0E102B0A0E1"
$S%+="02C0A0E102D0A0E102E0A0E11E1EA0E3FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8"
$S%+="FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC7FA0E8FC03A0E8011051E2E4FFFF1A04D09FE5"
$S%+="04E09FE5FF9FBDE80000000000000000"
Clr16_640x480%=FNmcode(S%)
$S%="FF5F2DE9044091E5085091E5046092E5087092E50C8092E5109092E5044080E5085080E50C6080E5107080E5148080E5189080E500C090E53CFF2FE11CC090E5"
$S%+="00005CE3FF9FBD18001091E5002092E5245090E5287090E52C8090E5309090E534A090E538B090E550D08FE550E08FE59BA42AE08A1081E0957627E0872082E0"
$S%+="FFC0A0E30CC48CE10030A0E3B35092E10C0015E1B3508111023083E2880053E1F9FFFFBA862082E0841081E0019059E2F4FFFF1A04D09FE504E09FE5FF9FBDE8"
$S%+="0000000000000000"
Plot%=FNmcode(S%)
$S%="FF5F2DE9930202E00030A0E3FFA0A0E354B09FE554C09FE5035190E725680AE025740AE005800AE09C0606E09C0707E09C0808E02668B0E10060A6E22778B0E1"
$S%+="0070A7E22888B0E10080A8E2878288E1868588E18340A0E1B48081E1013083E2020053E1EBFFFFBAFF9FBDE81F1F00003F3F0000"
ConvBmRGB565%=FNmcode(S%)
OTHERWISE: QUIT
ENDCASE
REMbinpath$ = @dir$ + "binaries/" + cpu$ + "/"
REMClipBitmap% = FNLoadData( binpath$ + "clipbitmap_" +cpu$+".dat" )
REMClr16_640x480% = FNLoadData( binpath$ + "clr16_640x480_" +cpu$+".dat" )
REMBPlot% = FNLoadData( binpath$ + "bplot16_" +cpu$+".dat" )
REMPlot% = FNLoadData( binpath$ + "plot16_" +cpu$+".dat" )
REMConvBmRGB565% = FNLoadData( binpath$ + "convbmrgb8888torgb565_" +cpu$+".dat" )
DIM ball{(Balls%-1) x, y, dx, amp, theta}
DIM ballBm{a%, w%, h%}
REMballBm.a% = FNLoadData( @dir$ + "ball_64x64_32bpp.bmp" )
ballBm.w% = 64
ballBm.h% = 64
ballBm.a% = FNmalloc( 4 * ballBm.w% * ballBm.h% )
x0% = ballBm.w% / 2
y0% = ballBm.h% / 2
maxD_sq% = x0%^2 + y0%^2
maxR_sq% = (ballBm.w%/2 - 1)^2
FOR Y% = 0 TO ballBm.h%-1
FOR X% = 0 TO ballBm.w%-1
d_sq% = (x0%-X%)^2 + (y0%-Y%)^2
IF d_sq% <= maxR_sq% THEN
k = 1-(d_sq%/maxD_sq%)
R% = k * &FF
G% = k * &B0
B% = k * &30
!(ballBm.a% + (Y%*ballBm.w% + X% << 2)) = &10000*R% OR &100*G% OR B%
ENDIF
NEXT
NEXT
A% = ballBm.a% : REM source 32bpp bitmap
B% = A% : REM dest 16bpp bitmap buffer
C% = ballBm.w%
D% = ballBm.h%
CALL ConvBmRGB565%
FOR I% = 0 TO Balls%-1
ball{(I%)}.x = RND(WinW% - ballBm.w%) - 1
ball{(I%)}.dx = (0.05 + 0.2*RND(1)) * SGN(RND(1)-0.5)
ball{(I%)}.theta = 2*PI*RND(1)
ball{(I%)}.amp = 100 + RND(WinH%)
ball{(I%)}.y = 0
NEXT I%
clipVars% = FNmalloc( 64 )
bfVars% = FNmalloc( 16 )
bmVars% = FNmalloc( 32 )
clipVars%!0 = ClipBitmap%
bfVars%!0 = bmp.a%
bfVars%!4 = bmp.w%
bfVars%!8 = bmp.h%
bmVars%!0 = ballBm.a%
bmVars%!4 = ballBm.w%
bmVars%!8 = ballBm.h%
pass% = FALSE
REPEAT
SYS GetTicks$ TO t0%
A% = bfVars%!0
B% = &188E : REM dark blue (RGB565)
CALL Clr16_640x480%
IF pass% THEN
A% = clipVars%
B% = bfVars%
C% = bmVars%
FOR I% = 0 TO Balls%-1
bmVars%!12 = ball{(I%)}.x
bmVars%!16 = ball{(I%)}.y
CALL Plot%
NEXT I%
ELSE
pass% = TRUE
ENDIF
OSCLI "MDISPLAY "+STR$~bmp%
IF Wait% THEN WAIT 1
SYS GetTicks$ TO t1%
dt% = t1% - t0%
FOR I% = 0 TO Balls%-1
ball{(I%)}.x += dt% * ball{(I%)}.dx
ball{(I%)}.y = ball{(I%)}.amp*ABSSINball{(I%)}.theta
ball{(I%)}.theta += dt% * 0.001
IF ball{(I%)}.x < -32 THEN
ball{(I%)}.x = -32
ball{(I%)}.dx *= -1
ENDIF
IF ball{(I%)}.x > WinW%-32 THEN
ball{(I%)}.x = WinW%-32
ball{(I%)}.dx *= -1
ENDIF
NEXT
UNTIL FALSE
END
DEF PROCerror
CLS : ON : SOUND 1, -15, 200, 3
COLOUR 15, 255, 255, 255 : COLOUR 15
PRINT '" " + REPORT$ + " at line " + STR$ERL
COLOUR 15, 200, 200, 200
PRINT ''" Closing in 3 seconds...";
WAIT 300
QUIT
ENDPROC
DEF FNCreateBMP_RGB565(W%, H%)
LOCAL A%, S%
S% = 70 + 2*W%*H%
DIM A% S%+15
A% = ((A% + 7) AND -8) + 2
A%?0 = ASC"B"
A%?1 = ASC"M"
A%!2 = S%
A%!10 = 70
A%!14 = 56
A%!18 = W%
A%!22 = H%
A%?26 = 1
A%?28 = 16
A%!30 = 3
A%!34 = 2*W%*H%
A%!38 = 11808
A%!42 = 11808
A%!54 = &0000F800
A%!58 = &000007E0
A%!62 = &0000001F
= A% : REM Bitmap data starts at A%+70
DEF FNLoadData( f$ )
LOCAL A%, F%, S%
F% = OPENIN( f$ )
IF F% = 0 THEN PRINT "Can't load "+f$ : WAIT 200 : QUIT
S% = EXT#F%
CLOSE#F%
DIM A% S%+15
A% = (A% + 7) AND -8
OSCLI "LOAD """ + f$ + """ " + STR$~A%
= A%
DEF FNmalloc( N% )
LOCAL A%
DIM A% N%+15
A% = (A% + 7) AND -8
= A%
DEF FNmcode(S%)
LOCAL A%, I%
A%=FNmalloc(LEN$S%)
FOR I%=0 TO LEN$S%DIV2-1
A%?I%=EVAL("&"+MID$($S%,2*I%+1,2))
NEXT
=A%