Author |
Topic: GLib (compact sprite library) (Read 447 times) |
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
GLib (compact sprite library)
« Thread started on: May 13th, 2016, 06:22am » |
|
Code:
DEFFNGetGLIBVer:="0.07"
DEFPROCInitGLIB(RETURN v{}):`v=@vdu%:LOCALS%,Z%:DIMv{a%,w%,h%}
v.a%=FN`cds:v.w%=`v!208:v.h%=`v!212:Z%=FN`ga(4096,TRUE):S%=FN`ga(2048,TRUE)
$S%="608B5C2424C703FFFFFFFF8B7C24383B7C24280F8DC70000008B74243C3B74242C0F8DB9"
$S%+="0000008B4C24308B54243483F9007D03F7D99083FA007D03F7DA90F7D93BF90F8E970000"
$S%+="00F7DA3BF20F8E8D000000F7D9F7DAC70300000000C7430400000000C7430800000000C7"
$S%+="430C00000000894B10895314897B1889731C8BEF03E93B6C24287E0E2B6C2428296B10C7"
$S%+="4304FFFFFFFF83FF007D14297B0C017B10C7431800000000C74304FFFFFFFF8BEE03EA3B"
$S%+="6C242C7E0E2B6C242C296B14C74304FFFFFFFF83FE007D14297308017314C7431C000000"
$S%+="00C74304FFFFFFFF61C21C0060":gClip=FN`m(S%,0)
$S%="608B6C24248B4424288B7D008B4D040FAF4D08FCF3AB61C2080000":Clr=FN`m(S%,0)
$S%="608BEC81EC800000008B75248BC4FF7538FF7534FF7530FF752CFF7608FF760450E8F6FE"
$S%+="FFFFF70424FFFFFFFF0F855A0000008B552C89542434C1642434020FAF5424080354240C"
$S%+="C1E2020355288B7E04897C2438C1642438020FAF7C241C037C2418C1E702033E8B5C2410"
$S%+="33C98B048A85C0740389048F83C1013BCB7CEF03542434037C2438FF4C241475DF81C480"
$S%+="00000061C2180060":Plot=FN`m(S%,33)
$S%="608BEC81EC800000008B75248BC4FF7538FF7534FF7530FF752CFF7608FF760450E85FFE"
$S%+="FFFFF70424FFFFFFFF0F85570000008B552C89542434C1642434020FAF5424080354240C"
$S%+="C1E2020355288B7E04897C2438C1642438020FAF7C241C037C2418C1E702033E8BF28B5C"
$S%+="24108B4424348B5424388B6C241456578BCBFCF3A55F5E03F003FA4D7FF081C480000000"
$S%+="61C218008B":BPlot=FN`m(S%,33)
$S%="608BEC83EC409BDBE39BD93C24668B04246625FFF3660D000C66890424D92C248B553483"
$S%+="FA000F8E480100008B7D3883FF000F8E3C0100006800000100DB0424DB452CDA7534D8C9"
$S%+="DB5C2404DB4530DA7538DEC9DB5C240883C4048B45248B5D3CF7DA3BDA0F8E090100003B"
$S%+="58040F8D000100008B4D40F7DF3BCF0F8EF30000003B48080F8DEA000000F7DAF7DF895C"
$S%+="2408894C240C89542410897C2414C744241800000000C744241C000000008B7004C1E602"
$S%+="8974242083FB007D10C744240800000000015C2410295C241C8B50042B55343BDA7E0B8B"
$S%+="70042B7424088974241083F9007D10C744240C00000000014C2414294C24188B50082B55"
$S%+="383BCA7E0B8B70082B74240C897424148B74240C0FAF700403742408C1E60203308B5D28"
$S%+="33FF8BCF034C24180FAF4C2404C1E9100FAF4D2CC1E102575055538B4424108B6C242C03"
$S%+="D98B7C24204F8BD703D50FAFD0C1EA108B1493F7C2FFFFFF0074038914BE4F7DE55B5D58"
$S%+="5F03742420473B7C24147CAE83C44061C220008B":PlotScaled=FN`m(S%,0)
$S%="608BEC81EC800000008B75248BC4FF7538FF7534FF7530FF752CFF7608FF760450E85FFE"
$S%+="FFFFF70424FFFFFFFF0F85610000008B552C89542434C1642434020FAF5424080354240C"
$S%+="C1E2020355288B7E04897C2438C1642438020FAF7C241C037C2418C1E702033E8B5C2410"
$S%+="33C98B048A85C0740AD12C8F81248F7F7F7F7F83C1013BCB7CE803542434037C2438FF4C"
$S%+="241475D881C48000000061C2180060":PlotShadow=FN`m(S%,33)
$S%="608BEC81EC800000008B75248BC4FF7538FF7534FF7530FF752CFF7608FF760450E8C1FD"
$S%+="FFFFF70424FFFFFFFF0F856E0000008B552C89542434C1642434020FAF5424080354240C"
$S%+="C1E2020355288B7E04897C2438C1642438020FAF7C241C037C2418C1E702033E8B5C2410"
$S%+="33C98B048A85C074178B348F25FEFEFE0081E6FEFEFE00D1E8D1EE03C689048F83C1013B"
$S%+="CB7CDB03542434037C2438FF4C241475CB81C48000000061C2180060"
PlotAvg=FN`m(S%,33)
$S%="8B7424048B4C24088B5E048B54240C3BCB73133B5608730E8B060FAFD38B7C241003D189"
$S%+="3C90C2100000":PlotPixel=FN`m(S%,0)
$S%="8B6C24048B45008B5D048B4D088B5424088B7C240C8B742410E81B00000083C201E81300"
$S%+="000083C701E80B00000083EA01E803000000C21000603BD3730C3BF973080FAFFB03FA89"
$S%+="34B861C300":PlotPoint=FN`m(S%,0)
$S%="33C08B6C24048B7C24083B7D0473178B74240C3B7508730E0FAF7504037424088B7D008B"
$S%+="04B7C20C0000":ReadPixel=FN`m(S%,0)
$S%="8B6C24048B7C24083B7D0473418B74240C3B750873380FAF7504037424088B7D0033C00F"
$S%+="B644B7028B5C241089030FB644B7018B5C241489030FB604B78B5C241889030FB644B703"
$S%+="8B5C241C8903C21C0000":ReadRGBA=FN`m(S%,0)
$S%="608BEC81EC800000008B75248BC4FF7538FF7534FF7530FF752CFF7608FF760450E85FFE"
$S%+="FFFFF70424FFFFFFFF0F85670000008B552C89542434C1642434020FAF5424080354240C"
$S%+="C1E2020355288B7E04897C2438C1642438020FAF7C241C037C2418C1E702033E8B5C2410"
$S%+="8B753CC1E61833C98B048A85C0740A25FFFFFF000BC689048F83C1013BCB7CE803542434"
$S%+="037C2438FF4C241475D881C48000000061C21C0060":PlotSetAlpha=FN`m(S%,33)
$S%="608BEC81EC800000008B75248BC4FF7538FF7534FF7530FF752CFF7608FF760450E8BBFD"
$S%+="FFFFF70424FFFFFFFF0F85720000008B552C89542434C1642434020FAF5424080354240C"
$S%+="C1E2020355288B7E04897C2438C1642438020FAF7C241C037C2418C1E702033E8B5C2410"
$S%+="518B4D3C83C118BE01000000D3E65933C98B048A85C0740C0BC681248F000000FF09048F"
$S%+="83C1013BCB7CE603542434037C2438FF4C241475D681C48000000061C21C0060"
PlotSetAlphaBit=FN`m(S%,33)
$S%="608BEC81EC800000008B75248BC4FF7538FF7534FF7530FF752CFF7608FF760450E80CFD"
$S%+="FFFFF70424FFFFFFFF0F855F0000008B552C89542434C1642434020FAF5424080354240C"
$S%+="C1E2020355288B7E04897C2438C1642438020FAF7C241C037C2418C1E702033E8B5C2410"
$S%+="33F633C98B048A85C074060B348F89048F83C1013BCB7CEC03542434037C2438FF4C2414"
$S%+="75DC81C480000000C1EE188BC68944241C61C2180060"
PlotGetAlphaBits=FN`m(S%,33)
$S%="608BEC81EC800000008B75248BC4FF7538FF7534FF7530FF752CFF7608FF760450E85FFE"
$S%+="FFFFF70424FFFFFFFF0F85690000008B552C89542434C1642434020FAF5424080354240C"
$S%+="C1E2020355288B7E04897C2438C1642438020FAF7C241C037C2418C1E702033E8B5C2410"
$S%+="33C98B048AA9000000FF740F3D000000FF722725FFFFFF0089048F83C1013BCB7CE00354"
$S%+="2434037C2438FF4C241475D081C48000000061C218008BF0C1EE180FB66C8A020FB6448F"
$S%+="022BE80FAFEEC1FD0803C588448F020FB66C8A010FB6448F012BE80FAFEEC1FD0803C588"
$S%+="448F010FB62C8A0FB6048F2BE80FAFEEC1FD0803C588048FC6448F030083C1013BCB0F8C"
$S%+="6EFFFFFF03542434037C2438FF4C24140F855AFFFFFF81C48000000061C2180060"
PlotAlphaBlend=FN`m(S%,33)
Z%=FN`ga(4096,TRUE)
ENDPROC
DEFPROCDisplay(W%):PRIVATEI%:IFI%=0 I%=FN`s("InvalidateRect")
SYSI%,@hwnd%,0,0:IFW%PROC`w
*REFRESH
ENDPROC
DEFFNLoadImg(p$,A%):LOCALK%,X%,Y%,W%,H%,M%:X%=0:Y%=0:K%=FN`l(p$,X%,Y%,0)
IFK%=0ERROR100,"LoadImg failed"
A%=FN`g(K%,A%,W%,H%):SYS"DeleteObject",K%:SYS"RtlMoveMemory",A%,A%+54,4*W%*H%
=A%
DEFPROCCleanup:PROC`n(3,0):ENDPROC
DEFFN`m(S%,O%):LOCALA%,I%:A%=FN`ga(LEN$S%,TRUE):FORI%=0TOLEN$S%DIV2-1
A%?I%=EVAL("&"+MID$($S%,2*I%+1,2)):NEXT
IFO%>0PROC`d(A%,O%,gClip)
=A%
DEFFN`cds:LOCALA%,B%,H%,O%:DIMB%19:!B%=44:B%!4=`v!208:B%!8=`v!212:B%!12=&200001
SYS"CreateDIBSection",@memhdc%,B%,0,^A%,0,0TOH%:IFH%=0ERROR100,"`cds failed"
SYS"SelectObject",@memhdc%,H%TOO%:SYS"DeleteObject",O%:CLS:=A%
DEFPROC`w:PRIVATEB%,G%,I%,S%,W%:LOCALL%,P%,T%:IFS%=0 S%=FN`s("Sleep")
IFB%=0SYS"timeBeginPeriod",1:B%=1
IFI%=0PROC`7(I%,G%)
L%=0:P%=^T%:REPEAT:L%=T%:SYSS%,1:SYSG%,I%,P%:UNTILT%<L%:ENDPROC
DEFPROC`7(RETURN I%,RETURN G%):LOCALD%,E%,J%,K%,L%
SYS"LoadLibrary","DDRAW.DLL"TOD%:IFD%=0 ERROR100,"`7 failed"
SYS"GetProcAddress",D%,"DirectDrawCreateEx"TOE%:DIMJ%19,L%95:J%=J%+3AND-4
L%=L%+3AND-4:!J%=&15E65EC0:J%!4=&11D23B9C:J%!8=&60002FB9:J%!12=&5BEA9797
SYSE%,0,^K%,J%,0:L%=!K%:I%=K%:G%=L%!64
ENDPROC
DEFFN`l(f$,RETURN X%,RETURN Y%,R%)
LOCALi{},b{},x%,y%,H%,C%,P%,O%,Q%,T%
DIMi{a%,b%,c%,d%},T% LOCAL 513
i.a%=&7BF80980:i.b%=&101ABF32:i.c%=&AA00BB8B:i.d%=&AB0C3000
SYS"MultiByteToWideChar",0,0,f$,-1,T%,256
SYS"LoadLibrary","OLEAUT32.DLL"TOO%
SYS"GetProcAddress",O%,"OleLoadPicturePath"TOQ%:IFQ%=0 THEN=0
SYSQ%,T%,0,0,0,i{},^P%:IFP%=0 THEN=0
SYS!(!P%+12),P%,^H%:IFH%=0 THEN=0
DIMb{T%,W%,H%,B%,P{l&,h&},p{l&,h&},s%}:SYS"GetObject",H%,DIM(b{}),b{}
x%=b.W%:y%=b.H%:IFX%=0 X%=x%
IFY%=0 Y%=y%
IFR%THEN
IFX%/Y%>x%/y% X%=Y%*x%/y%ELSEY%=X%*y%/x%
ENDIF
SYS"CopyImage",H%,0,X%,Y%,0TOC%:SYS"DeleteObject",H%:SYS!(!P%+8),P%:=C%
DEFFN`g(h%,RETURN D%,RETURN W%,RETURN H%):LOCALB%,S%,R%:DIMB%LOCAL26
B%=B%+3AND-4:SYS"GetObject",h%,24,B%TOR%
IFR%=0 ERROR100,"GetObject failed"
W%=B%!4:H%=B%!8:S%=54+4*W%*H%:IFD%=0DIMD% S%+7:D%=D%+7AND-8
IFD%=-1D%=FN`ga(54+4*W%*H%,TRUE)
$$D%=STRING$(53,CHR$0)
!D%=19778:D%!2=S%:D%!10=54:D%!14=40:D%!18=W%:D%!22=H%:D%!26=&200001
SYS"GetDIBits",@memhdc%,h%,0,H%,D%+54,D%+14,0TOR%
IFR%<>H% ERROR100,"GetDIBits failed"
=D%
DEFPROC`n(O%,V%):LOCALi,m:m=1000:PRIVATED%
IFD%=0THEN
D%=FN`ga(4*m,FALSE):IFD%=0 ERROR100,"GlobalAlloc failed"
FORi=0TOm-1:D%!(4*i)=0:NEXT
ENDIF
CASEO%OF
WHEN1:i=0:WHILED%!(4*i)<>0ANDi<m:i+=1:ENDWHILE
IFi>=m ERROR100,"Obj list full"
D%!(4*i)=V%
WHEN2:i=0:WHILED%!(4*i)<>V%ANDi<m:i+=1:ENDWHILE
IFi<m SYS"GlobalFree",V%:D%!(4*i)=0
WHEN3:FORi=0TOm-1
IFD%!(4*i)<>0SYS"GlobalFree",D%!(4*i):D%!(4*i)=0
NEXT:SYS"GlobalFree",D%:D%=0
ENDCASE
ENDPROC
DEFFN`s(f$):LOCALP%:DIMP%LOCAL5:[OPT 0:call f$:]:=P%!-4+P%
DEFPROC`d(B%,O%,C%):LOCALD%,P%:D%=C%-B%-O%-5:P%=B%+O%+1:!P%=D%:ENDPROC
DEFFN`ga(S%,F%):LOCALA%:SYS"GlobalAlloc",64,S%TOA%:IFF%PROC`n(1,A%)
=A%
DEF FNGrab(v{},A%,X%,Y%,W%,H%)
LOCALB%,D%,L%,I%,O%
IFA%=-1A%=FN`ga(4*W%*H%,TRUE)
D%=A%
FOR L%=Y% TO Y%+H%-1
B%=v.a%+4*(L%*v.w%+X%):FORI%=B%TOB%+4*W%-1STEP4:!D%=!I%:D%+=4:NEXT
NEXT
=A%
DEFPROCFWS:LOCALW%:SYS"GetWindowLong",@hwnd%,-16TOW%
SYS "SetWindowLong",@hwnd%,-16,W%AND&FFFAFFFF
ENDPROC
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #1 on: May 13th, 2016, 06:26am » |
|
This program ("Wavey Starfish") demonstrates GLib's PlotScaled routine. Copy and paste the following code into the BB4W IDE, then tack-on the GLib library from the first post in this thread (or INSTALL it, if you prefer).
Code:
REM "Wavey Starfish"
REM Requires GLIB 0.06 (or later)
MODE 8 : OFF
ON ERROR OSCLI"REFRESH ON":ON:CLS:REPORT:PRINT " at line ";ERL:END
REM If GLIB is an external library file (GLIB.BBC) then
REM include the following line:
REM INSTALL @lib$ + "GLIB"
PROCInitGLIB( g{} )
ON CLOSE PROC`n(3,0):QUIT
sprSz% = 64
nSpokes% = 10
maxSprSz% = sprSz%
minSprSz% = 4
maxR% = 300
minR% = 50
cx% = g.w% / 2
cy% = g.h% / 2
REM Draw a ball on the screen:
GCOL 1
FOR R% = sprSz%/2-1 TO 1 STEP -1
i = 1-(R%/(sprSz%/2))^4
COLOUR 1, 255*i, 100*i, 255*i
CIRCLE FILL sprSz%, sprSz%, 2*R%
NEXT R%
REM Copy the ball into a sprite/bitmap:
ballSpr% = FNGrab(g{}, -1, 0, 0, sprSz%, sprSz%)
TIME = 0
*REFRESH OFF
REPEAT
SYS Clr, g{}, &204060 : REM dark blue background
FOR R% = minR% TO maxR% STEP 25
f = (R%-minR%)/(maxR%-minR%)
sz% = minSprSz% + maxSprSz%*(1-f)
angleInc = 100*f*SIN(TIME/150)
FOR I% = 0 TO nSpokes%-1
i = 100*SIN(TIME/250)
angle = I%*(360/nSpokes%) + angleInc + i
X% = cx% + R%*SINRAD(angle)
Y% = cy% + R%*COSRAD(angle)
SYS PlotScaled, g{}, ballSpr%, sprSz%, sprSz%, sz%, sz%, \
\ X%-sz%/2, Y%-sz%/2
NEXT I%
NEXT R%
PROCDisplay(TRUE)
UNTIL FALSE
PROC`n(3,0) : REM free memory
END
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: GLib (compact sprite library)
« Reply #2 on: May 13th, 2016, 11:30am » |
|
Hi David,
Ooh, looks like that (particularly the library bit) will repay a bit of study! Are you in the market for providing a bit of documentation for the library functions?
Are your sprites 32 bit bitmaps, with black set to transparent?
Best wishes,
D
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #3 on: May 13th, 2016, 11:58am » |
|
on May 13th, 2016, 11:30am, DDRM wrote:Ooh, looks like that (particularly the library bit) will repay a bit of study! Are you in the market for providing a bit of documentation for the library functions? |
|
If anyone is wondering why the GLib code is so cryptic (certainly cryptic enough to cause me problems!), it's because it was originally designed so that it could be employed within the limitations of the Trial version of 'BBC BASIC for Windows' (I can't, off-hand, remember what the memory limitations were). This meant making it as compact as possible, and necessitated the use of short or single-character variable names and functions, and pre-assembled machine code.
I will shortly put up some documentation for it, including some commented example programs.
There's some routines I'd like to add (actually, there's quite a few routines I'd like to add but they would bloat the library, and I won't be able to fit the whole thing into one post!). I like being able to fit it all in one post. (Last time I checked, I only had 34 free characters available! (some more trimming to do, then...))
Quote:Are your sprites 32 bit bitmaps, with black set to transparent? |
|
Yes, 32bpp (ARGB) bitmaps, although any bitmap header data is ignored (which is why you must specify the height and width of the sprite you wish to plot, and the start address of the sprite's pixel data).
Black pixels are assumed to be transparent by some of the plotting routines. I will document which plotters ignore black pixels, and which ones don't.
David. --
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #4 on: May 15th, 2016, 11:07am » |
|
The program listed below will have to function as the rather perfunctory GLib documentation for the time being. It was written in a hurry, sorry. There ought to be enough information in there to put some sprites/bitmaps on the screen (which is GLib's purpose), but I'm willing to respond to any technical questions anyone may have regarding GLib.
Code:
REM GLib examples
REM Glossary
REM ========
REM
REM bmAddr ... bitmap address (memory address of ARGB32 bitmap image)
REM bmW ... bitmap width (in pixels)
REM bmH ... bitmap height (in pixels)
REM ARGB32 ... 32-bit pixel colour format used by GLib.
REM Each pixel in an ARGB32 bitmap image takes up 4 bytes (32 bits per pixel).
REM A = 8-bit alpha value (only used by PlotAlphaBlend); range 0 to 255
REM R = 8-bit red component (range 0 to 255)
REM G = 8-bit green component (range 0 to 255)
REM B = 8-bit blue component (range 0 to 255)
REM In hexadecimal, ARGB32 has the form &AARRGGBB
REM Examples:
REM White &00FFFFFF
REM Orange &00FF8000
REM Green &0000FF00
REM Blue with 50% alpha &7F0000FF
REM If GLib is an external file (i.e. in BB4W's standard LIB folder),
REM then include the following line:
INSTALL @lib$ + "GLIB"
REM If not, then tack the GLib library on to the end of this program.
REM It's good practice to call PROCCleanup upon closing the program,
REM or if an error is trapped:
ON CLOSE PROCCleanup : QUIT
ON ERROR PROCCleanup : CLS : REPORT : PRINT " at line "; ERL : END
REM Fix program window size (a 'built-in' GLib subroutine):
PROCFWS
REM Set up a 640x512 program window:
MODE 8 : OFF
WinW% = @vdu%!208
WinH% = @vdu%!212
REM Initialise GLib (GLib subroutine):
PROCInitGLIB( g{} )
REM The structure returned by PROCInitGLIB has three members:
REM
REM a% ... the 'screen' or 'frame buffer' address (currently a DIB section)
REM w% ... screen/frame buffer width
REM h% ... screen/frame buffer height
REM Load 512x512 JPEG image from BB4W's 'GRAPHICS' folder:
path$ = LEFT$( @lib$, LEN@lib$-4 ) + "EXAMPLES\GRAPHICS\"
file$ = path$ + "WORLD.JPG"
worldImg% = FNLoadImg(file$, -1)
REM FNLoadImg automatically loads the JPEG image, and converts it to
REM the required raw ARGB32 pixel format required by GLib.
REM The parameter specified as -1 in this case tells FNLoadImg to allocate
REM the memory required to hold the ARGB32 bitmap. Otherwise, you must
REM specify the address at which the ARGB32 bitmap will be placed, having
REM reserved the memory block (of sufficient size!) yourself.
REM Create a sprite (a colourful spiral) by drawing it on the screen
REM using BB4W's native graphics commands, then 'grab' it as a sprite/bitmap:
DIM spiral{ a%, w%, h% }
r = 0
FOR angle = 0 TO 1000
GCOL RND(15)
x = WinW% + r*SINRAD(angle)
y = WinH% + r*COSRAD(angle)
CIRCLE FILL x, y, 8
r += 0.1
NEXT angle
PROCgetMinMaxRect( g{}, minX%, minY%, maxX%, maxY% )
spiral.w% = maxX% - minX%
spiral.h% = maxY% - minY%
spiral.a% = FNGrab( g{}, -1, minX%, minY%, spiral.w%, spiral.h% )
REM Create another sprite, but this time one with an alpha mask.
REM When plotted with PlotAlphaBlend, this sprite will appear as a fuzzy red blob.
CLS
DIM ball{ a%, w%, h% }
GCOL 1 : CIRCLE FILL 200, 200, 80
PROCgetMinMaxRect( g{}, minX%, minY%, maxX%, maxY% )
ball.w% = maxX% - minX%
ball.h% = maxY% - minY%
ball.a% = FNGrab( g{}, -1, minX%, minY%, ball.w%, ball.h% )
m = SQR((ball.w%/2)^2 + (ball.h%/2)^2)
FOR Y% = 0 TO ball.h%-1
FOR X% = 0 TO ball.w%-1
d = SQR((X%-ball.w%/2)^2 + (Y%-ball.h%/2)^2)
ball.a%?(4*(Y%*ball.w%+X%) + 3) = 255*(1 - d/m)^2
NEXT
NEXT
REM Now actually draw stuff...
REM Clear the program window (fill it with dark blue).
REM Clr takes parameters g{}, ARGB32
SYS Clr, g{}, &000040
REM Plot the 512x512 'world' image at coordinates x=30, y=20.
REM BPlot takes parameters g{}, bmAddr, bmW, bmH, x, y
REM BPlot is well-suited to drawing background images. It's very fast.
REM All pixels (including black ones) in the bitmap image are plotted.
SYS BPlot, g{}, worldImg%, 512, 512, 30, 20
REM Use PlotPixel to draw 1000 randomly coloured pixels in the lower half of the window.
REM PlotPixel takes parameters g{}, x, y, ARGB32
FOR I% = 1 TO 1000
SYS PlotPixel, g{}, RND(WinW%), RND(WinH%/2), RND(&FFFFFF)
NEXT I%
REM Draw 1000 randomly coloured points in the upper half of the window.
REM A point is a 2x2 square block of pixels.
REM PlotPoint takes parameters g{}, x, y, ARGB32
FOR I% = 1 TO 1000
SYS PlotPoint, g{}, RND(WinW%), WinH%/2+RND(WinH%/2), RND(&FFFFFF)
NEXT I%
REM Draw 10 randomly positioned spiral sprites (the one we created earlier).
REM Plot takes the same parameters as BPlot - g{}, bmAddr, bmW, bmH, x, y
REM Black pixels are not plotted (i.e. they are assumed to be transparent)
FOR I% = 1 TO 10
SYS Plot, g{}, spiral.a%, spiral.w%, spiral.h%, RND(WinW%), RND(WinH%)
NEXT I%
REM Draw 10 randomly positioned, colour-averaged spiral sprites using PlotAvg.
REM PlotAvg takes parameters g{}, bmAddr, bmW, bmH, x, y
REM Black pixels are not plotted (i.e. they are considered to be transparent)
FOR I% = 1 TO 10
SYS PlotAvg, g{}, spiral.a%, spiral.w%, spiral.h%, RND(WinW%), RND(WinH%)
NEXT I%
REM Draw the spiral sprite stretched horizontally and vertically to varying extents.
REM PlotScaled takes parameters g{}, bmAddr, bmW, bmH, newW, newH, x, y
REM Black pixels are not plotted.
FOR I% = 1 TO 10
newW% = RND(300)
newH% = RND(300)
SYS PlotScaled, g{}, spiral.a%, spiral.w%, spiral.h%, newW%, newH%, RND(WinW%), RND(WinH%)
NEXT I%
REM Draw alpha-blended sprites.
REM PlotAlphaBlend takes parameters g{}, bmAddr, bmW, bmH, x, y
REM Black pixels in the sprite are processed by this routine.
FOR I% = 1 TO 10
SYS PlotAlphaBlend, g{}, ball.a%, ball.w%, ball.h%, RND(WinW%), RND(WinH%)
NEXT I%
REM Draw translucent shadows (actually 'silhouettes' of the spiral sprite).
REM PlotShadow takes parameters g{}, bmAddr, bmW, bmH, x, y
REM Black pixels are not plotted.
FOR I% = 1 TO 20
SYS PlotShadow, g{}, spiral.a%, spiral.w%, spiral.h%, RND(WinW%), RND(WinH%)
NEXT I%
REM Update the program window:
PROCDisplay(FALSE)
PROCCleanup
END
DEF PROCgetMinMaxRect(v{}, RETURN minX%, RETURN minY%, RETURN maxX%, RETURN maxY%)
LOCAL A%, B%, H%, W%, X%, Y%
minX% = 100000000
minY% = 100000000
maxX% = -100000000
maxY% = -100000000
A% = v.a%
W% = v.w%
H% = v.h%
FOR Y% = 0 TO H%-1
B% = A% + 4*Y%*W%
FOR X% = 0 TO W%-1
IF B%!(4*X%) THEN
IF X% < minX% THEN
minX% = X%
ENDIF
IF X% > maxX% THEN
maxX% = X%
ENDIF
IF Y% < minY% THEN
minY% = Y%
ENDIF
IF Y% > maxY% THEN
maxY% = Y%
ENDIF
ENDIF
NEXT
NEXT
ENDPROC
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #5 on: May 15th, 2016, 12:40pm » |
|
If GLib isn't installed in your BB4W LIB folder, then either do that, or append the library (from the first post in this thread) to the end of this program:
Code:
REM "Ring of Balls"
REM Requires GLIB 0.07 (or later)
REM If GLib is in BB4W's LIB folder, then include the following line:
INSTALL @lib$ + "GLIB"
REM Otherwise, append the GLib library to the end of this program.
PROCFWS : REM Fix Window Size
MODE 8 : REM 640x512
OFF
nBalls% = 16
REM Get window width and height:
winW% = @vdu%!208
winH% = @vdu%!212
PROCInitGLIB( g{} )
ON ERROR OSCLI"REFRESH ON":ON:PROCCleanup:REPORT:PRINT ERL:END
ON CLOSE PROCCleanup:QUIT
REM Create a 32bpp bitmap of dimensions winW% by 10*winH%:
bgW% = winW%
bgH% = 10 * winH%
PRINT "Generating colourful ";bgW%;"x";bgH%;" bitmap..."
bg% = FN`ga( 4*bgW%*bgH%, TRUE )
I% = bg%
k = 3*PI/(bgW%-1)
FOR Y% = 0 TO bgH%-1
yf = 16*PI*Y%/(bgH%-1)
sin_yf = SIN(yf)
sin_yf_2 = SIN(yf/2)
FOR X% = 0 TO bgW%-1
xf = k*X%
blue& = 128 + 64*(sin_yf+COS(xf))
red& = 128 + 64*(sin_yf_2+SIN(xf+yf))
!I% = blue& + &10000*red&
I% += 4
NEXT
NEXT
REM Create a green ball sprite:
DIM ball{a%, w%, h%}
CLS
GCOL 15
FOR R% = 64 TO 1 STEP -1
r = 1 - R%/64
COLOUR 15, r*10, r*255, r*100
CIRCLE FILL winW%, winH%, R%
NEXT R%
PROCgetMinMaxRect( g{}, minX%, minY%, maxX%, maxY% )
ball.w% = maxX% - minX% + 1
ball.h% = maxY% - minY% + 1
ball.a% = FNGrab( g{}, -1, minX%, minY%, ball.w%, ball.h% )
h% = bgH% - winH%
TIME = 0
*REFRESH OFF
REPEAT
t = TIME / 120
REM Draw the moving background image:
y% = -0.5*(h% + h%*SIN(TIME/350))
SYS BPlot, g{}, bg%, bgW%, bgH%, 0, y%
REM Draw the ring of balls
REM Draw ball shadows:
FOR I% = 0 TO nBalls%-1
angle = 2*PI*I%/(nBalls%-1) + t
x% = winW%/2 + 200*SIN(angle) - ball.w%/2
y% = winH%/2 + 200*COS(angle) - ball.h%/2
SYS PlotShadow, g{}, ball.a%, ball.w%, ball.h%, x%-24, y%-32
NEXT I%
REM Draw the balls proper:
FOR I% = 0 TO nBalls%-1
angle = 2*PI*I%/(nBalls%-1) + t
x% = winW%/2 + 200*SIN(angle) - ball.w%/2
y% = winH%/2 + 200*COS(angle) - ball.h%/2
SYS Plot, g{}, ball.a%, ball.w%, ball.h%, x%, y%
NEXT I%
REM Update the program window
REM (with VSync synchronisation):
PROCDisplay( TRUE )
UNTIL FALSE
END
:
:
:
:
DEF PROCgetMinMaxRect(v{}, RETURN minX%, RETURN minY%, RETURN maxX%, RETURN maxY%)
LOCAL A%, B%, H%, W%, X%, Y%
minX% = 100000000
minY% = 100000000
maxX% = -100000000
maxY% = -100000000
A% = v.a%
W% = v.w%
H% = v.h%
FOR Y% = 0 TO H%-1
B% = A% + 4*Y%*W%
FOR X% = 0 TO W%-1
IF B%!(4*X%) THEN
IF X% < minX% THEN
minX% = X%
ENDIF
IF X% > maxX% THEN
maxX% = X%
ENDIF
IF Y% < minY% THEN
minY% = Y%
ENDIF
IF Y% > maxY% THEN
maxY% = Y%
ENDIF
ENDIF
NEXT
NEXT
ENDPROC
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #6 on: May 18th, 2016, 09:49am » |
|
Code:
REM Thick antialiased lines using GDI+.
REM Here, GLib is used in conjunction with GDI+.
REM Fairly consistent 60 fps for 60 lines on my laptop.
REM
REM This program calls GdipDrawLine directly, and performs
REM 'inline' conversion to 4-byte floats in order to reduce
REM overheads.
nLines% = 30
*ESC OFF
REM If you don't yet have GLib installed in the BB4W's LIB folder,
REM either append GLib to the end of this program, or install it
REM in the LIB folder.
INSTALL @lib$ + "GLIB"
PROCInitGLIB( g{} )
INSTALL @lib$ + "GDIPLIB"
PROCFWS : REM Fix Window Size
MODE 8 : OFF
ON ERROR PROCCleanup : REPORT : PRINT ERL : END
ON CLOSE PROCCleanup : QUIT
SetBoundsRect = FN`s("SetBoundsRect")
GetBoundsRect = FN`s("GetBoundsRect")
OffsetRect = FN`s("OffsetRect")
InvalidateRect = FN`s("InvalidateRect")
GetTickCount = FN`s("GetTickCount")
REM The following bit of assembler code
REM is the work of RTR:
DIM f4% 10
P% = f4%
[OPT 2
mov esi,[ebp+2]:mov edi,[ebp+7]
fld qword [esi]:fstp dword [edi]
ret
]
f32# = 0.0 : pf32% = ^f32# + 4 : !pf32% = &3FF00000
PROC_gdipinit
ON ERROR PROCCleanup : PROC_gdipexit : REPORT : PRINT ERL : END
ON CLOSE PROCCleanup : PROC_gdipexit : QUIT
DIM rc{l%,t%,r%,b%}
yellowPen% = FN_gdipcreatepen(&FFFFFF00, 2+&200, 2)
greenPen% = FN_gdipcreatepen(&FF00FF00, 2+&200, 4)
bluePen% = FN_gdipcreatepen(&FF0080FF, 2+&200, 8)
orangePen% = FN_gdipcreatepen(&FFFF8000, 2+&200, 6)
gdipGfxPtr% = FN_gdipg
SYS SetBoundsRect, @memhdc%, 0, 5
SYS GetBoundsRect, @memhdc%, rc{}, 0
DIM line{( nLines%-1 ) x1, y1, x2, y2, dx1, dx2, dy1, dy2, pen%}
ScrW% = @vdu%!208
ScrH% = @vdu%!212
FOR I% = 0 TO nLines%-1
line{(I%)}.x1 = RND( @vdu%!208 )
line{(I%)}.y1 = RND( @vdu%!212 )
line{(I%)}.x2 = RND( @vdu%!208 )
line{(I%)}.y2 = RND( @vdu%!212 )
line{(I%)}.dx1 = 2*RND(1)*SGN(RND(1)-0.5)
line{(I%)}.dx2 = 2*RND(1)*SGN(RND(1)-0.5)
line{(I%)}.dy1 = 2*RND(1)*SGN(RND(1)-0.5)
line{(I%)}.dy2 = 2*RND(1)*SGN(RND(1)-0.5)
CASE RND(4) OF
WHEN 1 : line{(I%)}.pen% = yellowPen%
WHEN 2 : line{(I%)}.pen% = greenPen%
WHEN 3 : line{(I%)}.pen% = bluePen%
WHEN 4 : line{(I%)}.pen% = orangePen%
ENDCASE
NEXT I%
REM Line endpoints variables:
x1% = 0 : y1% = 0 : x2% = 0 : y2% = 0
frame% = 0
frameRate% = 0
*REFRESH OFF
SYS GetTickCount TO time0%
REPEAT
SYS Clr, g{}, 0
FOR I% = 0 TO nLines%-1
f64# = line{(I%)}.x1 : f64# *= f32# : CALL f4%,f64#,x1%
f64# = line{(I%)}.y1 : f64# *= f32# : CALL f4%,f64#,y1%
f64# = line{(I%)}.x2 : f64# *= f32# : CALL f4%,f64#,x2%
f64# = line{(I%)}.y2 : f64# *= f32# : CALL f4%,f64#,y2%
SYS `GdipDrawLine`, gdipGfxPtr%, line{(I%)}.pen%, x1%, y1%, x2%, y2%, @memhdc%
line{(I%)}.x1 += line{(I%)}.dx1
line{(I%)}.y1 += line{(I%)}.dy1
line{(I%)}.x2 += line{(I%)}.dx2
line{(I%)}.y2 += line{(I%)}.dy2
IF line{(I%)}.x1 < 0 OR line{(I%)}.x1 >= ScrW% line{(I%)}.dx1 *= -1
IF line{(I%)}.x2 < 0 OR line{(I%)}.x2 >= ScrW% line{(I%)}.dx2 *= -1
IF line{(I%)}.y1 < 0 OR line{(I%)}.y1 >= ScrH% line{(I%)}.dy1 *= -1
IF line{(I%)}.y2 < 0 OR line{(I%)}.y2 >= ScrH% line{(I%)}.dy2 *= -1
NEXT I%
PRINT TAB(2,1);frameRate%;" fps"
PROCDisplay(TRUE)
frame% += 1
SYS GetTickCount TO time1%
IF time1%-time0% >= 1000 THEN
frameRate% = frame%
frame% = 0
SYS GetTickCount TO time0%
ENDIF
UNTIL FALSE
END
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #7 on: May 22nd, 2016, 08:59am » |
|
An unfinished/buggy "Asteroids"-style game:
http://pastebin.com/86rn3bnU
(Scroll down to the bottom of the Pastebin window to the section titled "RAW Paste Data", then click somewhere inside that box and press CTRL+A to select all the code, followed by CTRL+C to copy it into the Windows clipboard, then within the BB4W IDE press CTRL+V to paste in the program listing. Or do it your own way!)
This was never meant to be a game (and really isn't much of a game at all). It was supposed to be a GLib/GDI+ demo with a couple of random 'asteroids' moving across the screen, but then one thing led to another. It's basically is just a demo, not a proper game.
Use the left/right arrow keys to spin around, and use the 'up' arrow key to thrust, and space bar to fire. From level 4 onwards, thicker (and generally faster) asteroids appear which take more hits to destroy.
60 fps on all three of my machines.
For possibly improved performance (if the animation gets jittery), compile the program and then run it.
David. --
|
|
Logged
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: GLib (compact sprite library)
« Reply #8 on: May 22nd, 2016, 3:14pm » |
|
Handsome, but difficult!

D
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #9 on: Jun 19th, 2016, 3:14pm » |
|
Here's a little demo of GLib's capabilities (a work-in-progress game that I had started, but probably won't finish). Nothing much happens yet, sadly.
Use the arrow keys to move around.
Copy and paste the code from Pastebin into the BB4W IDE. The GLib library is already appended at the end of the program, so it doesn't need to reside in BB4W's LIB folder.
http://pastebin.com/Ag9eH66e
(Scroll down to the section titled 'RAW Paste Data' and then left-click somewhere inside the window, press CTRL A to select all the code, then CTRL C to copy it to the clipboard, and then press CTRL V inside the BB4W IDE to paste it.)
The scrolling is very smooth on my desktop PC, but on my laptop it's a bit jerky. I don't know why. Background processes most likely to blame. The program uses less than 15% CPU on my machines.
David.
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #10 on: Jun 26th, 2016, 09:11am » |
|
Code: REM Fern 3D
REM Requires GLib to run
*ESC OFF
*FLOAT 64
INSTALL @lib$ + "GLIB"
PROCFWS : MODE 8 : OFF
PROCInitGLIB( g{} )
ON ERROR PROCCleanup : REPORT : END
ON CLOSE PROCCleanup : QUIT
P% = PlotPixel
Q% = PlotPoint
R% = ReadPixel
G% = g{}
nPts% = FNgetFernPoints( 12345678, FALSE )
DIM p(nPts%-1,2), q(nPts%-1,2), m(2,2)
dummy% = FNgetFernPoints( 12345678, TRUE )
minX = 10000000
maxX = -minX
minY = 10000000
maxY = -minY
FOR I% = 0 TO nPts%-1
IF p(I%,0) < minX THEN minX = p(I%,0)
IF p(I%,0) > maxX THEN maxX = p(I%,0)
IF p(I%,1) < minY THEN minY = p(I%,1)
IF p(I%,1) > maxY THEN maxY = p(I%,1)
NEXT I%
FOR I% = 0 TO nPts%-1
p(I%,0) -= (maxX - minX)/2
p(I%,1) -= (maxY - minY)/2
p(I%,2) = 250
NEXT I%
*REFRESH OFF
REPEAT
T% = TIME
A = T%/122
B = T%/176
C = T%/312
D = 2*PI*SIN(T%/520)
E = 3*PI*COS(T%/720)
sA = SIN(A)
cA = COS(A)
sB = SIN(B)
cB = COS(B)
sC = SIN(C)
cC = COS(C)
m() = (cB*cC), -cB*sC, sB, cA*sC+sA*sB*cC, cA*cC-sA*sB*sC, -sA*cB, sA*sC-cA*sB*cC, sA*cC+cA*sB*sC, cA*cB
q() = p().m()
SYS Clr, G%, &000040
FOR I% = 0 TO nPts%-1
SYS Q%, G%, 320+q(I%,0), 256+q(I%,1), &E020
NEXT
PROCDisplay(TRUE)
UNTIL FALSE
END
DEF FNgetFernPoints( rndseed%, store_coords% )
LOCAL A%, C%, I%, S%, r, x, y, newx, newy
S% = RND(-ABS(rndseed%))
C% = 0
x = 0
y = 0
SYS Clr, g{}, 0
FOR I% = 1 TO 80000
r = RND(1)
CASE TRUE OF
WHEN r<=0.1 A=0: B=0: C=0: D=0.16: E=0: F=0
WHEN r>0.1 AND r<=0.86 A=.85: B=.04: C=-.04: D=.85: E=0: F=1.6
WHEN r>0.86 AND r<=0.93 A=.2: B=-.26: C=.23: D=.22: E=0: F=1.6
WHEN r>0.93 A=-.15: B =.28: C=.26: D=.24: E=0: F=.44
ENDCASE
newx=A*x+B*y+E
newy=C*x+D*y+F
x=newx
y=newy
SYS R%, G%, 300+48*x, 16+48*y TO A%
IF A% = 0 THEN
IF store_coords% THEN
SYS P%, G%, 300+48*x, 16+48*y, &E020
p(C%,0) = 48*x
p(C%,1) = 48*y
p(C%,2) = 0
ELSE
SYS P%, G%, 300+48*x, 16+48*y, &E020
ENDIF
C% += 1
ENDIF
NEXT
= C%
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #11 on: Jun 27th, 2016, 06:23am » |
|
This one's slightly different:
(Reminder: Obtain the GLib library from the first post in this thread and either append it to the end of this program (remove the INSTALL statement in that case), or put it in the usual place (BB4W's LIB folder)).
Code: REM Fern 3D
REM Requires GLib to run
*ESC OFF
*FLOAT 64
INSTALL @lib$ + "GLIB" : REM remove this line if GLib library is appended to end of this program
PROCFWS : MODE 8 : OFF
PROCInitGLIB( g{} )
ON ERROR PROCCleanup : REPORT : END
ON CLOSE PROCCleanup : QUIT
P% = PlotPixel
Q% = PlotPoint
R% = ReadPixel
G% = g{}
REM Create colour-graduated background bitmap:
WinW% = @vdu%!208
WinH% = @vdu%!212
bg% = FN`ga(4*WinW%*WinH%, 1)
FOR Y% = 0 TO WinH%-1
A% = 4*Y%*WinW%
f = 1 - Y%/(WinH%-1)
C% = INT(255*0.5*f) + &100*INT(255*0.15*f) + &10000*INT(255*0.075*f)
FOR I% = bg%+A% TO bg%+A%+4*WinW%-1 STEP 4
!I% = C%
NEXT I%
NEXT Y%
nPts% = FNgetFernPoints( 12345678, FALSE )
DIM p(nPts%-1,2), q(nPts%-1,2), m(2,2)
dummy% = FNgetFernPoints( 12345678, TRUE )
minX = 10000000
maxX = -minX
minY = 10000000
maxY = -minY
FOR I% = 0 TO nPts%-1
IF p(I%,0) < minX THEN minX = p(I%,0)
IF p(I%,0) > maxX THEN maxX = p(I%,0)
IF p(I%,1) < minY THEN minY = p(I%,1)
IF p(I%,1) > maxY THEN maxY = p(I%,1)
NEXT I%
dx_max = maxX - minX
dy_max = maxY - minY
cx = dx_max/2
cy = dy_max/2
d_max = SQR(cx^2 + cy^2)
FOR I% = 0 TO nPts%-1
x = p(I%,0)
y = p(I%,1)
p(I%,2) = 100 + 100*SQR((x-cx)^2 + (y-cy)^2)/d_max
p(I%,0) -= cx
p(I%,1) -= cy
NEXT I%
k = 255 * 1/700
*REFRESH OFF
REPEAT
T% = TIME
A = T%/122
B = T%/176
C = T%/312
D = 2*PI*SIN(T%/520)
E = 3*PI*COS(T%/720)
sA = SIN(A)
cA = COS(A)
sB = SIN(B)
cB = COS(B)
sC = SIN(C)
cC = COS(C)
m() = (cB*cC), -cB*sC, sB, cA*sC+sA*sB*cC, cA*cC-sA*sB*sC, -sA*cB, sA*sC-cA*sB*cC, sA*cC+cA*sB*sC, cA*cB
q() = p().m()
REMSYS Clr, G%, &000040
SYS BPlot, G%, bg%, WinW%, WinH%, 0, 0
FOR I% = 0 TO nPts%-1
SYS Q%, G%, 320+q(I%,0), 256+q(I%,1), &100*INT(255-k*(350+q(I%,2)))
NEXT
PROCDisplay(TRUE)
UNTIL FALSE
END
DEF FNgetFernPoints( rndseed%, store_coords% )
LOCAL A%, C%, I%, S%, r, x, y, newx, newy
S% = RND(-ABS(rndseed%))
C% = 0
x = 0
y = 0
SYS Clr, g{}, 0
FOR I% = 1 TO 80000
r = RND(1)
CASE TRUE OF
WHEN r<=0.1 A=0: B=0: C=0: D=0.16: E=0: F=0
WHEN r>0.1 AND r<=0.86 A=.85: B=.04: C=-.04: D=.85: E=0: F=1.6
WHEN r>0.86 AND r<=0.93 A=.2: B=-.26: C=.23: D=.22: E=0: F=1.6
WHEN r>0.93 A=-.15: B =.28: C=.26: D=.24: E=0: F=.44
ENDCASE
newx=A*x+B*y+E
newy=C*x+D*y+F
x=newx
y=newy
SYS R%, G%, 300+48*x, 16+48*y TO A%
IF A% = 0 THEN
IF store_coords% THEN
SYS P%, G%, 300+48*x, 16+48*y, &E020
p(C%,0) = 48*x
p(C%,1) = 48*y
p(C%,2) = 0
ELSE
SYS P%, G%, 300+48*x, 16+48*y, &E020
ENDIF
C% += 1
ENDIF
NEXT
= C%
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: GLib (compact sprite library)
« Reply #12 on: Jun 28th, 2016, 08:44am » |
|
Hi David,
I get a fail with PROCFWS: where/what is it? It doesn't seem too critical, because simply deleting it results in a working program. 
I like the way you make the fern flat and then map in the z coordinate by distance, and the nice use of matrix multiplication to the rotation mapping all at once - those matrix functions are blindingly fast, aren't they? A great feature of BB4W.
If you scaled the z mappings in your matrix m() by one of your rotation angles, could you make it "blow in the breeze"?
Best wishes,
D
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #13 on: Jun 28th, 2016, 10:34am » |
|
on Jun 28th, 2016, 08:44am, DDRM wrote:I get a fail with PROCFWS: where/what is it? It doesn't seem too critical, because simply deleting it results in a working program. ;D |
|
That was a subroutine I added to a more recent version of GLib than the one you may have in your LIB folder. Version 0.07 is the latest version, and the library code is listed in the first post of this thread. 'FWS' stands for 'Fix Window Size'. The reason for the cryptic name is in keeping with GLib's original need to be usable with the old, memory-limited trial version of BB4W.
Quote:If you scaled the z mappings in your matrix m() by one of your rotation angles, could you make it "blow in the breeze"? |
|
That's a nice idea, but with 18,907 points to 'process', the frame rate would probably take quite a hit! I may give it a try nevertheless, even if I need to resort to assembler code for speed.
I've included a slightly more efficient version of the program below (it uses a colour table, and hexadecimal constants in the point-plotting loop because the interpreter converts them to binary slightly faster than base 10).
David. --
Code:
REM Fern 3D (v3)
REM Requires GLib to run
*ESC OFF
*FLOAT 64
INSTALL @lib$ + "GLIB" : REM remove this line if GLib library is appended to end of this program
PROCFWS : MODE 8 : OFF
PROCInitGLIB( g{} )
ON ERROR PROCCleanup : REPORT : END
ON CLOSE PROCCleanup : QUIT
P% = PlotPixel
Q% = PlotPoint
R% = ReadPixel
G% = g{}
REM Create colour-graduated background bitmap:
WinW% = @vdu%!208
WinH% = @vdu%!212
bg% = FN`ga(4*WinW%*WinH%, 1)
FOR Y% = 0 TO WinH%-1
A% = 4*Y%*WinW%
f = 1 - Y%/(WinH%-1)
C% = INT(255*0.5*f) + &100*INT(255*0.15*f) + &10000*INT(255*0.075*f)
FOR I% = bg%+A% TO bg%+A%+4*WinW%-1 STEP 4
!I% = C%
NEXT I%
NEXT Y%
nPts% = FNgetFernPoints( 12345678, FALSE )
DIM p(nPts%-1,2), q(nPts%-1,2), m(2,2)
dummy% = FNgetFernPoints( 12345678, TRUE )
minX = 10000000
maxX = -minX
minY = 10000000
maxY = -minY
FOR I% = 0 TO nPts%-1
IF p(I%,0) < minX THEN minX = p(I%,0)
IF p(I%,0) > maxX THEN maxX = p(I%,0)
IF p(I%,1) < minY THEN minY = p(I%,1)
IF p(I%,1) > maxY THEN maxY = p(I%,1)
NEXT I%
dx_max = maxX - minX
dy_max = maxY - minY
cx = dx_max/2
cy = dy_max/2
d_max = SQR(cx^2 + cy^2)
FOR I% = 0 TO nPts%-1
x = p(I%,0)
y = p(I%,1)
p(I%,2) = 50 + 150*SQR((x-cx)^2 + (y-cy)^2)/d_max
p(I%,0) -= cx
p(I%,1) -= cy
NEXT I%
k = 1/700
DIM C%( 700 )
FOR I% = 0 TO 700
C%(I%) = &100*INT(255*k*I%) + INT(64*k*I%)
NEXT I%
*REFRESH OFF
REPEAT
T% = TIME
A = T%/122
B = T%/176
C = T%/312
D = 2*PI*SIN(T%/520)
E = 3*PI*COS(T%/720)
sA = SIN(A)
cA = COS(A)
sB = SIN(B)
cB = COS(B)
sC = SIN(C)
cC = COS(C)
m() = cB*cC, -cB*sC, sB, cA*sC+sA*sB*cC, cA*cC-sA*sB*sC, -sA*cB, sA*sC-cA*sB*cC, sA*cC+cA*sB*sC, cA*cB
q() = p().m()
SYS BPlot, G%, bg%, WinW%, WinH%, 0, 0
FOR I% = 0 TO nPts%-1
SYS Q%, G%, &140+q(I%,0), &100+q(I%,1), C%(&15E+q(I%,2))
NEXT
PROCDisplay(TRUE)
UNTIL FALSE
END
DEF FNgetFernPoints( rndseed%, store_coords% )
LOCAL A%, C%, I%, S%, r, x, y, newx, newy
S% = RND(-ABS(rndseed%))
C% = 0
x = 0
y = 0
SYS Clr, g{}, 0
FOR I% = 1 TO 80000
r = RND(1)
CASE TRUE OF
WHEN r<=0.1 A=0: B=0: C=0: D=0.16: E=0: F=0
WHEN r>0.1 AND r<=0.86 A=.85: B=.04: C=-.04: D=.85: E=0: F=1.6
WHEN r>0.86 AND r<=0.93 A=.2: B=-.26: C=.23: D=.22: E=0: F=1.6
WHEN r>0.93 A=-.15: B =.28: C=.26: D=.24: E=0: F=.44
ENDCASE
newx=A*x+B*y+E
newy=C*x+D*y+F
x=newx
y=newy
SYS R%, G%, 300+48*x, 16+48*y TO A%
IF A% = 0 THEN
IF store_coords% THEN
SYS P%, G%, 300+48*x, 16+48*y, &E020
p(C%,0) = 48*x
p(C%,1) = 48*y
p(C%,2) = 0
ELSE
SYS P%, G%, 300+48*x, 16+48*y, &E020
ENDIF
C% += 1
ENDIF
NEXT
= C%
|
|
Logged
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: GLib (compact sprite library)
« Reply #14 on: Jun 28th, 2016, 11:09am » |
|
Hi David,
Aha! I now have the updated version (007, I think. I'll be careful not to offend it!), and the problem has gone away.
The point of my "waving" suggestion was that I think you could do it by altering the contents of the m matrix, so there should be essentially 0 time cost. I may be misunderstanding how it works, though, I haven't worked through it carefully. You might need an intermediate array equivalent to p and q, to hold the "blown" XYZ data (i.e with the z coordinates transformed by Cos(angle)), but even that should be fast.
OK, I had a go: Code:
REM Near the top: probably a sledgehammer! Make space for extra array
HIMEM=LOMEM+4E7
.
REM With the other array declarations (included)
DIM p(nPts%-1,2), q(nPts%-1,2), m(2,2),dt(nPts%-1,2)
.
REM Highjacking your mapping section
m()=1,0,0,0,1,0,0,0,cA
dt()=p().m()
m() = cB*cC, -cB*sC, sB, cA*sC+sA*sB*cC, cA*cC-sA*sB*sC, -sA*cB, sA*sC-cA*sB*cC, sA*cC+cA*sB*sC, cA*cB
q() = dt().m()
Best wishes,
D
|
|
Logged
|
|
|
|
|