BBC BASIC for Windows
« GLib (compact sprite library) »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 10:18pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1 2 3  Notify Send Topic Print
 veryhotthread  Author  Topic: GLib (compact sprite library)  (Read 447 times)
David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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

 

« Last Edit: May 14th, 2016, 11:28am by David Williams » User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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
 


« Last Edit: May 13th, 2016, 9:29pm by David Williams » User IP Logged

DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx 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
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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.
--
« Last Edit: May 13th, 2016, 11:59am by David Williams » User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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
 
« Last Edit: May 15th, 2016, 11:14am by David Williams » User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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
 
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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
 
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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.
--



User IP Logged

DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: GLib (compact sprite library)
« Reply #8 on: May 22nd, 2016, 3:14pm »

Handsome, but difficult!

smiley

D
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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.
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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%
 
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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%
 
« Last Edit: Jun 27th, 2016, 06:24am by David Williams » User IP Logged

DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx 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. grin

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
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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%
 
User IP Logged

DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx 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
User IP Logged

Pages: 1 2 3  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls