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

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #15 on: Jun 28th, 2016, 3:01pm » |
|
David, that's efficient and works well! And there's me thinking (or perhaps not thinking) I'd need to do it via a loop.
You probably noticed that darker points (in this case, a point is a 2x2 block of pixels) sometimes overwrite lighter ones, when ideally the points should be plotted in order from dark to light according to their Z co-ordinates. One could sort them (very CPU-expensive given the number of points), or one could write an assembler routine which reads a background pixel and only overwrites it with a new one if the new one is lighter (depending on how 'lightness' is defined!). Doing it in BASIC would really slow things down, I think.
Regards, David. --
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #16 on: Sep 19th, 2016, 11:09am » |
|
Over at the 'BBC BASIC (SDL)' forum, Michael asks the question,
Quote:| The bigger question to ask you Richard, is how is a sprite image held in memory and quickly placed on the screen? |
|
This is exactly what the compact library 'GLib' is for. The library code is posted in the first post of this thread. It plots 32bpp (4 bytes per pixel) sprites, and it's pretty fast (for a software-based renderer).
I've bundled up most of the GLib example programs that I had posted to this thread into a Zip folder containing compiled EXEs and souce code.
Download:
https://drive.google.com/open?id=0B3j5sIQi9SskVnlJdmZuYWI3cTQ
David. --
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #17 on: Sep 19th, 2016, 11:31am » |
|
on Sep 19th, 2016, 11:09am, David Williams wrote:Over at the 'BBC BASIC (SDL)' forum, Michael asks the question,
This is exactly what the compact library 'GLib' is for. The library code is posted in the first post of this thread. It plots 32bpp (4 bytes per pixel) sprites, and it's pretty fast (for a software-based renderer).
I've bundled up most of the GLib example programs that I had posted to this thread into a Zip folder containing compiled EXEs and source code.
Download:
https://drive.google.com/open?id=0B3j5sIQi9SskVnlJdmZuYWI3cTQ
David. -- |
|
|
|
Logged
|
|
|
|
michael
Senior Member
member is offline


Posts: 335
|
 |
Re: GLib (compact sprite library)
« Reply #18 on: Sep 19th, 2016, 11:37pm » |
|
I see.. I looked over "Wavey Starfish" and I think I will be able to make it work for the animation overlays.. ( what is the status of GLib? is it Open Source or Public Domain or what?) I am currently working with a DIB section Ric shown me to adapt to my BMPtoCode output code..
The only huge leap is getting all the colors right and then its just a matter of converting my conditional statements to produce the proper hexadecimal value.
Your work is pretty cool. I will definitely tinker with it to see if I can adapt it to my code toon parts tools.
After a certain point, the data base will become too large to post, but hopefully, should allow a person to construct animations easily and control them with commands in code. Here is an output code image that I would need to modify :
The colors in this program were extracted from windows paint color values on a 256 color BMP file format except for the bottom right color on the default colors.
So if a person were to convert this programs color controls and plotting controls, toon creation work could be more effective.
AND once that was done, I could modify BMPtoCode to automatically generate the code needed for any Code image.
And each image would function like a customizable BBC Basic command in a future library. **** BMPtoCODE created this entire program from a 256 color BMP image. And the data statements are compressed image data
This cant be compressed any more.. It took me at least a month to work out the compression in LBB. Code: VDU 22,8
VDU 23,23,1|
OFF:VDU 5:COLOUR 0:CLG
PROC_image(100,500)
WAIT 0:END
DEF PROC_image(h,v)
LOCAL DATA
u=0:r=0:g=0:b=0:a=0:c=0:t=0
ost$=""
READ x,y:REPEAT
READ nst$,t
IF nst$="0" THEN r=0:g=0:b=0 :REM 'black 0 0 0
IF nst$="1" THEN r=192:g=128:b=64:REM ' brown 192 128 64
IF nst$="2" THEN r=64:g=64:b=192 :REM'dark blue 64 64 192
IF nst$="3" THEN r=128:g=128:b=128:REM' dark grey 128 128 128
IF nst$="4" THEN r=128:g=0:b=0:REM'dark red 128 0 0
IF nst$="5" THEN r=224:g=192:b=0 :REM'dark yellow 224 192 0
IF nst$="6" THEN r=128:g=160:b=192:REM'flat blue 128 160 192
IF nst$="7" THEN r=32:g=192:b=64 :REM'green 32 192 64
IF nst$="8" THEN r=166:g=202:b=240:REM'light blue 166 202 240
IF nst$="9" THEN r=192:g=192:b=192:REM 'light gray 192 192 192
IF nst$="a" THEN r=192:g=224:b=0:REM 'light green 192 224 0
IF nst$="b" THEN r=224:g=32:b=64:REM'light red 224 32 64
IF nst$="c" THEN r=0:g=160:b=192 :REM'medblue 0 160 192
IF nst$="d" THEN r=224:g=128:b=64 :REM 'orange 224 128 64
IF nst$="e" THEN r=224:g=160:b=192:REM'pink 224 160 192
IF nst$="f" THEN r=160:g=64:b=192:REM'purple 160 64 192
IF nst$="g" THEN r=192:g=220:b=192:REM'tan 192 220 192
IF nst$="h" THEN r=255:g=255:b=255:REM'white 255 255 255
IF nst$="i" THEN r=255:g=255:b=0:REM'yellow 255 255 0
COLOUR 0,r,g,b:GCOL 0
FOR u=0 TO t
a=a+1: MOVE h+c,v-a:DRAW h+c,v-a:IF a>x THEN c=c+1:a=0
NEXT u
UNTIL nst$="100000"
MOVE 0,0
DATA 161,161
DATA 0,9471,3,1,0,159,3,1,0,157,h,3,0,157,h,3,0,155,h,7,0,153,h,7,0,151,h,11,0,149,h,11,0,147,h,13,3,1,0,145,h
DATA 13,3,1,0,143,h,15,0,145,h,15,0,145,g,1,h,15,0,143,g,1,h,15,0,143,h,17,0,143,h,17,0,141,h,21,0,139,h,21,0,139
DATA h,21,0,139,h,21,0,137,h,25,0,135,h,25,0,135,h,27,0,133,h,27,0,133,h,27,3,1,0,131,h,27,3,1,0,129,3,1,h,29,0
DATA 129,3,1,h,29,0,129,g,1,h,29,0,129,g,1,h,29,0,129,h,31,0,129,h,31,0,129,h,31,0,129,h,31,0,129,h,13,9,1,0,1
DATA h,11,0,131,h,13,9,1,0,1,h,11,0,131,h,11,0,5,9,1,h,7,0,133,h,11,0,5,9,1,h,7,0,133,h,9,3,1,0,7,h
DATA 5,0,135,h,9,3,1,0,7,h,5,0,139,h,7,0,5,g,1,h,3,0,141,h,7,0,5,g,1,h,3,0,145,g,1,h,7,g,1,0,149
DATA g,1,h,7,g,1,100000,0
ENDPROC
And here is the current project... extracting the colors and matching them to my custom colors in my output code file:
Any suggestions would help..
It has been just experimentation / trial and error to get the current colors I have posted here..
White found (updated on edit)
If you look at the previous code you will see the colors I need .. (its good to be close to the colors that I made, otherwise the image wont be right.
There seems to be a problem with this program. Seems the graphics draws and screen size are not always the same.. When I run it multiple times the image is not always the same.
Code: REM The 3rd and 4th components of the VDU 23,22 statement must be the same as bmi.Header.Width% and bmi.Header.Height%
VDU 23,22,1024;640;16,16,16,0
DIM BITMAPINFOHEADER{Size%, Width%, Height%, Planes{l&,h&}, BitCount{l&,h&}, Compression%, SizeImage%, XPelsPerMeter%, YPelsPerMeter%, ClrUsed%, ClrImportant%}
DIM bmi{Header{} = BITMAPINFOHEADER{}}
bmi.Header.Size% = DIM(BITMAPINFOHEADER{})
bmi.Header.Width% = 1024
bmi.Header.Height% = 640
bmi.Header.Planes.l& = 1
bmi.Header.BitCount.l& = 32
SYS "CreateDIBSection", @memhdc%, bmi{}, 0, ^bits%, 0, 0 TO hbitmap%
IF hbitmap%=0 ERROR 100, "Couldn't create DIBSection"
SYS "SelectObject", @memhdc%, hbitmap% TO oldhbm%
SYS "DeleteObject", oldhbm%
SYS "InvalidateRect", @hwnd%, 0, 0
REM The code to this point sets the screen size in pixels and creates bitmap to the same size
REM To access the bitmap you need to use bit% :-
REM Each pixel is four bytes
REM You can access one at a time with "bits%?(X,Y)=8_bit_number"
REM Or all four bytes at the same time "bits%!(X,Y)=&aaRRGGBB
REM when setting X and Y remember they are pixel coordinates not graphics coordinates
X=100
Y=100
bits%?( ( X + ( Y * bmi.Header.Width% ) ) * 4 ) = 255 : REM Will put a blue dot at 100,100
X=110
bits%!( ( X + ( Y * bmi.Header.Width% ) ) * 4 ) =&FF0000
X=115
bits%!( ( X + ( Y * bmi.Header.Width% ) ) * 4 ) = &00FF00FF : REM Will put a magenta dot at 110,100
FOR loop = 300 TO 500
bits%!( ( loop + ( loop * bmi.Header.Width% ) ) * 4 ) = &400040 :REM DARK PURPLE
bits%!( ( loop +8+ ( loop * bmi.Header.Width% ) ) * 4 ) = &FF0000 :REM RED
bits%!( ( loop +15+ ( loop * bmi.Header.Width% ) ) * 4 ) = &F36E2D7 :REM CYAN
bits%!( ( loop +16+ ( loop * bmi.Header.Width% ) ) * 4 ) = &F36E2D7 :REM CYAN
bits%!( ( loop +25+ ( loop * bmi.Header.Width% ) ) * 4 ) = &0011E6380C :REM orange
bits%!( ( loop +35+ ( loop * bmi.Header.Width% ) ) * 4 ) = &00BEFA717 :REM yellow
bits%!( ( loop +45+ ( loop * bmi.Header.Width% ) ) * 4 ) = &00F360BFF :REM blue
bits%!( ( loop +55+ ( loop * bmi.Header.Width% ) ) * 4 ) = &00F36E23C :REM green
bits%!( ( loop +65+ ( loop * bmi.Header.Width% ) ) * 4 ) = &005F9C57C :REM TAN
bits%!( ( loop +80+ ( loop * bmi.Header.Width% ) ) * 4 ) = &65497 :REM light blue
bits%!( ( loop +90+ ( loop * bmi.Header.Width% ) ) * 4 ) = &654951 :REM Greyish purple?
bits%!( ( loop +91+ ( loop * bmi.Header.Width% ) ) * 4 ) = &654951 :REM greyish purple?
bits%!( ( loop +92+ ( loop * bmi.Header.Width% ) ) * 4 ) = &654951 :REM greyish purple?
bits%!( ( loop +93+ ( loop * bmi.Header.Width% ) ) * 4 ) = &654951 :REM greyish purple?
bits%!( ( loop +99+ ( loop * bmi.Header.Width% ) ) * 4 ) = &6549 :REM grass green
bits%!( ( loop +109+ ( loop * bmi.Header.Width% ) ) * 4 ) = &65 :REM ? dark blue
bits%!( ( loop +129+ ( loop * bmi.Header.Width% ) ) * 4 ) = &12632256:REM purple
bits%!( ( loop +149+ ( loop * bmi.Header.Width% ) ) * 4 ) = &167777215 :REM Dark yellow
bits%!( ( loop +159+ ( loop * bmi.Header.Width% ) ) * 4 ) = &167777:REM dark cyan
bits%!( ( loop +169+ ( loop * bmi.Header.Width% ) ) * 4 ) = &167772111:REM dark red
bits%!( ( loop +179+ ( loop * bmi.Header.Width% ) ) * 4 ) = &FFFFFF: REM BRIGHT WHITE BMPtoCODE
bits%!( ( loop +189+ ( loop * bmi.Header.Width% ) ) * 4 ) = &C0CFD0: REM GRAY? BMPtoCODE
bits%!( ( loop +199+ ( loop * bmi.Header.Width% ) ) * 4 ) = &C0C0C0: REM Light GRAY BMPtoCODE
bits%!( ( loop +209+ ( loop * bmi.Header.Width% ) ) * 4 ) = &A0013BF: REM RED BMPtocode? NOPE!! its blue
NEXT
bits%!( ( X + ( Y * bmi.Header.Width% ) ) * 4 ) = &400040 :REM DARK PURPLE
REM The reason for the "* bmi.Header.Width%" is to move the "Y" position up the screen by the correct displacement
REM and the "*4" is because each position on the bit map is four pixels
REM A simple line
REM After you have finished accessing the bit map a "*REFRESH" is needed to update the screen
*REFRESH
|
| « Last Edit: Sep 20th, 2016, 03:20am by michael » |
Logged
|
I like making program generators and like reinventing the wheel
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #19 on: Sep 21st, 2016, 11:48am » |
|
The programs linked-to below work with BB4W and BBCSDL. I get a rather inconsistent 60 to 70 fps on my Core i7 desktop PC with either BB4W and BBCSDL, and the same with BB4W on my Celeron-based laptop (duo core), but not with BBCSDL which returns roughly 30 fps. In this case, omitting the "WAIT 1" statement still isn't enough to raise the average frame rate beyond 50 fps. I have taken steps to ensure that the alpha channel of the 640x480 32bpp bitmap rendered via OSCLI "MDISPLAY ..." is totally clear so that SDL isn't attempting to alpha-blend anything. Furthermore, I have ensured that the address of the start of the bitmap pixel data (i.e. address of the first pixel in the background bitmap) is 'DWORD aligned' (i.e. divisible by 4). This certainly speeds up rendering with BB4W, because usually the pixel data of a 32bpp BMP is misaligned by 2 bytes (header size is 54 bytes, when ideally it ought to be 56!).
Links:
http://pastebin.com/FVRKZNN6
Scroll down to the 'RAW Paste Data' section, press CTRL+A to select all the code, then copy and paste into the BB4W/BBCSDL IDE.
Also, I've just added this (alpha-blended sprites over a colourful background):
http://pastebin.com/aTmyEpVd
Bonus: here's that "wavey starfish" again, compatible with BBCSDL:
http://pastebin.com/EfdUetEL
David. --
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #20 on: Sep 24th, 2016, 9:28pm » |
|
Here's another little demo (and definitely the last in the series) which works with both BB4W and BBCSDL. It is not a game as such, although you can use the Z and X keys to move your space ship, and press Enter to fire at the descending aliens.
http://pastebin.com/CWJKMLP4
The program is self-contained. You don't need to install GLib beforehand.
It also runs independent of frame rate.
When run under BBCSDL, I found that I have to clear the entire alpha channel of the 640x480 graphics 'surface' bitmap before calling *MDISPLAY. This is annoying and inefficient. But why is the alpha channel used in the first place? I use it here for fast and easy collision detection, not for alpha blending.
David. --
|
|
Logged
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: GLib (compact sprite library)
« Reply #21 on: Sep 26th, 2016, 2:18pm » |
|
Hi David,
Ooh, that's an intriguing throw-away! How are you using it for collision detection?
D
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #22 on: Sep 26th, 2016, 3:54pm » |
|
on Sep 26th, 2016, 2:18pm, DDRM wrote:| Ooh, that's an intriguing throw-away! How are you using it for collision detection? |
|
The 'alien' sprites are plotted using the routine PlotSetAlpha which, apart from merely plotting a sprite, also sets the 'invisible' and normally redundant alpha byte of all overwritten background pixels to a specified value in the range 0 to 255. This value is different for each individual alien, and is in fact the alien's index in the alien{()} structure array. Actually, the indices run from 1 up to the maximum number of aliens that may be plotted (which can't exceed 255) because writing alpha values of zero isn't terribly useful in this scheme. So once we've plotted all the aliens, and the initially-clean alpha channel of the background/surface bitmap has been scribbled all over, when it comes to plotting our missiles/plasma bolts, those are plotted using PlotGetAlphaBits. This routine plots the missile sprites but also reads the background alpha bytes (of all pixels overwritten by the missile sprite) and returns the cumulative alpha value which, if there is no collision, should be zero. If it's nonzero, then a collision of the missile with one of the aliens has taken place. But which alien? The nonzero alpha value will be the actual index of the alien we've just collided with.
I'm pretty sure that I used this collision detection method with my game 'Alien Eliminator':
https://www.youtube.com/watch?v=lgPWQKjLaaw
And with other games, too.
With BB4W, drawing the background/surface bitmap using *MDISPLAY is relatively fast irrespective of the state of the bitmap's alpha channel (whether it is completely clear, or contains nonzero alpha values), because it doesn't attempt to do any alpha blending. But with BBCSDL and *MDISPLAY, the bitmap is 'automatically' scanned for nonzero alpha values prior to rendering. If the alpha channel is clear then the bitmap is drawn fast-ish (not as fast as with BB4W), but if there is so much as one nonzero alpha value, then SDL will alpha blend the entire bitmap (or at least I think that's the case; it certainly seems to be). This is why I clear the alpha channel (when run under BBCSDL) before calling *MDISPLAY. I don't know how SDL is doing the (here unwanted) alpha channel pre-scanning, but I hope it's not using the CPU to do it!
David. --
|
|
Logged
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: GLib (compact sprite library)
« Reply #23 on: Sep 27th, 2016, 12:55pm » |
|
Hi David,
OK, that's a cute and clever idea, but now I'm struggling a bit... So all the bits where you encode the string $S% as hex to (spaces defined by) variables like PlotGetAlphaBits are essentially pre-assembled functions, which you can then call using SYS, as if they were system commands? Sneaky, if opaque! So that's kind of like Michael's BMPtoCode idea? 
With regard to the use of alpha channel values, Richard posted something on the cross-platform forum in another context that suggests that this is a "feature" of SDL rather than BB4SDL:
"What SDL does is to scan all the alpha bytes; if any of them are non-zero it (sensibly) assumes that you are using the alpha channel and applies it throughout. If none of the alpha bytes are non-zero it ignores the alpha channel entirely."
... so I wouldn't hold your breath for a version which doesn't behave that way...
Best wishes,
D
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #24 on: Sep 27th, 2016, 1:52pm » |
|
on Sep 27th, 2016, 12:55pm, DDRM wrote:OK, that's a cute and clever idea, but now I'm struggling a bit... So all the bits where you encode the string $S% as hex to (spaces defined by) variables like PlotGetAlphaBits are essentially pre-assembled functions, which you can then call using SYS, as if they were system commands? Sneaky, if opaque! |
|
The intention behind GLib is that it be compact enough to be usable with the pre-v6 trial version of BB4W. So, yes, instead of memory-consuming assembly language, I use strings of pre-assembled machine code to save some space (although each byte of machine code requires 2 bytes for its ASCII representation). I suppose I could've used DATA statements instead which might have saved yet more space, but using strings seemed more convenient to me. I know that it was possible to circumvent (perhaps to a limited extent) the 8K (or was it 12K?) limit of the pre-v6 trial version of BB4W, but I'm not clever enough to figure out how to do it!
Incidentally, the more extensive GLib2 library is DLL-based (uses even less memory than GLib). I wrote it while I was learning C. I found that I was able to write graphics functions sometimes in a matter of minutes (literally!) rather than hours. I know that compiled C can be slower than hand-coded assembler code, but not always, and it depends on the competence of the programmer. Since a C compiler understands the CPU architecture better than most human programmers, and knows how to schedule sequences of instructions for efficient execution, compiled C can be faster. Some of my C-based graphics routines are faster than their largely equivalent assembly language versions, even though they're based on the same algorithms, and this is likely due to the C compiler sequencing (pipelining) the instructions in a more efficient way than I ever possibly could.
Quote:So that's kind of like Michael's BMPtoCode idea? |
|
Hmm.. perhaps, in a sense? Just to be sure, those machine code routines don't encode any image/sprite information.
Quote:| With regard to the use of alpha channel values, Richard posted something on the cross-platform forum in another context that suggests that this is a "feature" of SDL rather than BB4SDL: |
|
I was aware of this, but if there is a way the 'pre-scanning' could be suppressed then it could save some (or rather a lot!) of CPU cycles. For a while, I did wonder why large (e.g. 640x4800 32bpp) BMP images took so long to render via *MDISPLAY (under BBCSDL). SDL was pre-scanning over 3 million pixels, even though for my particular application it wasn't necessary as no alpha blending was taking place.
I won't be able to develop one myself, but an SDL-based graphics library (which uses accelerated SDL graphics surfaces and rendering operations) is highly desirable. (GLib and GfxLib is mostly all CPU-intensive software-based rendering.) Such a library would ideally include an image loader (with appropriate conversion where necessary), and a function for synchronising graphics rendering with screen/monitor's refresh. I gather, from a brief Google search, that VBlank synchronisation is difficult or impossible with SDL in 'windowed mode'.
David. --
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #25 on: Sep 27th, 2016, 7:35pm » |
|
Just another experiment with frame rate-independent animation. I'm probably doing this wrong!
Use the Up/Down arrow keys to increase/decrease the number of sprites displayed. The frame rate will drop as the number of sprites increases, but the speed of the sprites should be roughly constant. The frame rate and number of objects are displayed in the window's title bar.
Works with BB4W and BBCSDL:
Code: *ESC OFF
NumSprTypes% = 20
MaxObjs% = 2000
M% = 3
HIMEM = LOMEM + M%*&100000
HIMEM = (HIMEM + 3) AND -4
BB4W% = (INKEY(-256) == &57)
IF BB4W% THEN
GetTicks$ = "GetTickCount"
SetWindowText$ = "SetWindowText"
ELSE
GetTicks$ = "SDL_GetTicks"
SetWindowText$ = "SDL_SetWindowTitle"
ENDIF
ScrW% = 640
ScrH% = 480
VDU 23,22,ScrW%;ScrH%;8,16,16,0 : OFF
TmpBMPBuf% = FNmalloc(4*128*128)
REM Create a 640x480 32bpp 'surface' bitmap:
DIM bmp{a%,w%,h%}
bmp.w%=ScrW%
bmp.h%=ScrH%
bmp.a%=FNcreateBMP32(bmp.w%,bmp.h%)
PROCInitGLIB(g{},bmp.w%,bmp.h%)
g.a%=bmp.a%+54
DIM spr{(NumSprTypes%-1) a%, sz%}
DIM obj{(MaxObjs%-1) type%, x, y, dx, dy}
*REFRESH OFF
GCOL 15
FOR I%=0 TO NumSprTypes%-1
spr{(I%)}.sz% = 4*(8+RND(10))
CLS
col1% = RND(64)+&100*RND(64)+&10000*RND(64)
col2% = (32+RND(255-32))+&100*(32+RND(255-32))+&10000*(32+RND(255-32))
FOR r%=spr{(I%)}.sz%/2-1 TO 1 STEP -1
f=1-r%/(spr{(I%)}.sz%/2-1)
PROClerpRGB(col1%,col2%,f,R%,G%,B%)
COLOUR 15,R%,G%,B%
CIRCLE FILL spr{(I%)}.sz%, spr{(I%)}.sz%, 2*r%
NEXT r%
file$ = @tmp$ + "spr" + STR$I%
OSCLI "GSAVE """+file$+""" "+STR$0+","+STR$0+","+STR$(2*spr{(I%)}.sz%)+","+STR$(2*spr{(I%)}.sz%)
NEXT I%
CLS : OSCLI "REFRESH" : OSCLI "REFRESH ON"
FOR I%=0 TO NumSprTypes%-1
PRINT I%
file$ = @tmp$ + "spr" + STR$I% + ".BMP"
spr{(I%)}.a% = FNLoadBMP(file$,TmpBMPBuf%,4*128*128)
NEXT I%
FOR I%=0 TO MaxObjs%-1
obj{(I%)}.type% = RND(NumSprTypes%)-1
obj{(I%)}.x = 32+RND(ScrW%-64)
obj{(I%)}.y = 32+RND(ScrH%-64)
obj{(I%)}.dx = 0.05 * SGN(RND(1)-0.5) * (0.25 + 3.75*RND(1))
obj{(I%)}.dy = 0.05 * SGN(RND(1)-0.5) * (0.25 + 3.75*RND(1))
NEXT I%
G% = g{}
NumObjs% = 1
flushKbBuf% = 0
frames% = 0
frameRate% = 0
SYS GetTicks$ TO time0%
REPEAT
SYS GetTicks$ TO t1%
SYS Clr,g{},&A0D0
P% = PlotShadow
FOR I%=0 TO NumObjs%-1
t%=obj{(I%)}.type%
a%=spr{(t%)}.a%
sz%=spr{(t%)}.sz%
SYS P%,G%,a%,sz%,sz%,obj{(I%)}.x-16,obj{(I%)}.y-16
NEXT
P% = Plot
FOR I%=0 TO NumObjs%-1
t%=obj{(I%)}.type%
a%=spr{(t%)}.a%
sz%=spr{(t%)}.sz%
SYS P%,G%,a%,sz%,sz%,obj{(I%)}.x,obj{(I%)}.y
NEXT
OSCLI "MDISPLAY "+STR$~bmp.a%
WAIT 1
SYS GetTicks$ TO t2%
dt%=t2%-t1%
FOR I%=0 TO NumObjs%-1
obj{(I%)}.x+=dt%*obj{(I%)}.dx
obj{(I%)}.y+=dt%*obj{(I%)}.dy
IF obj{(I%)}.x<-32 THEN
obj{(I%)}.dx*=-1
obj{(I%)}.x+=obj{(I%)}.dx
ENDIF
IF obj{(I%)}.x>ScrW%-32 THEN
obj{(I%)}.dx*=-1
obj{(I%)}.x+=obj{(I%)}.dx
ENDIF
IF obj{(I%)}.y<-32 THEN
obj{(I%)}.dy*=-1
obj{(I%)}.y+=obj{(I%)}.dy
ENDIF
IF obj{(I%)}.y>ScrH%-32 THEN
obj{(I%)}.dy*=-1
obj{(I%)}.y+=obj{(I%)}.dy
ENDIF
NEXT
IF INKEY-58 THEN
NumObjs%+=1
IF NumObjs%=MaxObjs% NumObjs%=MaxObjs%
ENDIF
IF INKEY-42 THEN
NumObjs%-=1
IF NumObjs%<1 NumObjs%=1
ENDIF
frames% += 1
SYS GetTicks$ TO time1%
IF time1%-time0% >= 1000 THEN
frameRate% = frames%
frames% = 0
SYS SetWindowText$, @hwnd%, STR$frameRate% + " fps | "+STR$NumObjs%+" objects"
SYS GetTicks$ TO time0%
ENDIF
IF flushKbBuf% > 0 THEN
flushKbBuf% -= 1
ELSE
*FX 21, 0
flushKbBuf% = 250
ENDIF
UNTIL FALSE
END
DEF PROClerpRGB( rgb1%, rgb2%, f, RETURN r%, RETURN g%, RETURN b% )
LOCAL r1%, g1%, b1%, r2%, g2%, b2%
r1% = (rgb1% AND &FF0000) >> 16
g1% = (rgb1% AND &FF00) >> 8
b1% = rgb1% AND &FF
r2% = (rgb2% AND &FF0000) >> 16
g2% = (rgb2% AND &FF00) >> 8
b2% = rgb2% AND &FF
r% = r1% + f*(r2%-r1%)
g% = g1% + f*(g2%-g1%)
b% = b1% + f*(b2%-b1%)
ENDPROC
DEF FNcreateBMP32( W%, H% )
LOCAL A%, S%
S% = 54 + 4*W%*H% + 6
DIM A% S%-1
A% = ((A% + 3) AND -4) + 2
A%?0 = ASC"B"
A%?1 = ASC"M"
A%!2 = 54 + 4*W%*H%
A%!6 = 0
A%!10 = 54
A%!14 = 40
A%!18 = W%
A%!22 = H%
A%?26 = 1
A%?28 = 32
A%!30 = 0
A%!34 = 4*W%*H%
A%!38 = 0
A%!42 = 0
A%!46 = 0
A%!50 = 0
= A%
DEF FNLoadBMP( file$, buf%, bufSz% )
LOCAL A%, B%, F%, W%, H%, I%, S%
F% = OPENIN( file$ )
IF F% = 0 THEN ERROR 0, "Can't find file " + file$
S% = EXT#F%
CLOSE#F%
OSCLI "LOAD """ + file$ + """ " + STR$~buf%
IF buf%?0<>ASC"B" OR buf%?1<>ASC"M" THEN
ERROR 0, file$ + " isn't a BMP file"
ENDIF
IF buf%?28 <> 24 AND buf%?28 <> 32 THEN
ERROR 0, "BMP file has invalid colour depth (must be 24 or 32)"
ENDIF
W% = buf%!18
IF (W% AND 3) <> 0 THEN ERROR 0, "BMP image width must be a multiple of 4"
H% = buf%!22
REM if H% is negative then sprite is "upside down" !
S% = 4 * W%*ABS(H%)
DIM B% S%+7
B% = (B% + 7) AND -8
A% = buf% + buf%!10
IF SGN(H%) = 1 THEN
IF buf%?28 = 24 THEN
FOR I% = B% TO B%+S%-1 STEP 4
!I% = ?A% OR &100*A%?1 OR &10000*A%?2
A% += 3
NEXT
ENDIF
ENDIF
IF SGN(H%)=-1 THEN
H%=ABS(H%)
IF buf%?28=24 THEN
A%+=3*W%*(H%-1)
FOR Y%=0 TO H%-1
Z%=A%
FOR I%=B%+4*W%*Y% TO B%+4*(W%*Y% +(W%-1))-1 STEP 4
!I%=?Z% OR &100*Z%?1 OR &10000*Z%?2
Z%+=3
NEXT
A%-=3*W%
NEXT
ENDIF
ENDIF
= B%
REM ============================================================================
DEFPROCInitGLIB(RETURN v{},W%,H%):LOCALS%,Z%:DIMv{a%,w%,h%}
v.w%=W%
v.h%=H%
Z%=FNmalloc(4096)
S%=FNmalloc(2048)
$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%+="FFFFF70424FFFFFFFF0F85610000008B552C89542434C1642434020FAF5424080354240C"
$S%+="C1E2020355288B7E04897C2438C1642438020FAF7C241C037C2418C1E702033E8B5C2410"
$S%+="33C98B048A85C0740AD12C8F81248F7F7F7F7F83C1013BCB7CE803542434037C2438FF4C"
$S%+="241475D881C48000000061C2180060":PlotShadow=FN`m(S%,33)
Z%=FNmalloc(4096)
ENDPROC
DEFFN`m(S%,O%)
LOCALA%,I%:A%=FNmalloc(LEN$S%):FORI%=0TOLEN$S%DIV2-1
A%?I%=EVAL("&"+MID$($S%,2*I%+1,2)):NEXT
IFO%>0PROC`d(A%,O%,gClip)
=A%
DEFPROC`d(B%,O%,C%):LOCALD%,P%:D%=C%-B%-O%-5:P%=B%+O%+1:!P%=D%:ENDPROC
DEFFNmalloc(N%):LOCALA%:DIM A% N%+7:A%=(A%+7) AND -8:=A%
REM ============================================================================
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #26 on: Nov 23rd, 2016, 04:55am » |
|
Anyone that has seen the latest version of GLib (0.24 beta - used by the 'Snowfall 3' demo) may have noticed that it has grown quite at lot in size, and therefore it can no longer be described as being a 'compact' library! It now stands at around 54 Kb, which I don't believe is excessive given the amount of functionality it provides. There is always the temptation to keep on adding new functions (a mistake I made with GfxLib). I will add several more useful ones, and stop there, I think.
The library incorporates a lot of Richard's work that he had kindly contributed to GfxLib and the Programmer's Reference, and he will be duly credited in the next release. For instance, the 'Snowfall 3' demo uses his MMX-based PlotRotateScaleRTR and BoxBlur routines.
Things to do:
1) Tidy up the library (drastically) 2) Write the documentation 3) Release the stable version
All by the end of this month, hopefully.
David. --
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #27 on: Nov 30th, 2016, 11:53pm » |
|
GLIB's documentation is starting to take shape:
http://www.proggies.uk/glib/glibdocs.html
I hope to have it all completed by the end of the weekend (before I run out of enthusiasm and energy!).
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: GLib (compact sprite library)
« Reply #28 on: Dec 1st, 2016, 03:33am » |
|
An old program modified for use with GLib. It downloads the latest version of GLib, and a BMP image, and stuffs them in a Windows temporary folder.
Copy, paste, run...
Code: REM "Vector balls 4"
REM Original GfxLib-based version created 16-Jan-2012
REM Modified for GLib on 01-Dec-2016
REM Uses 'PlotRotateScaleRTR' to draw the ball objects
*ESC OFF
*FLOAT 64
PROCurldownload( "http://www.proggies.uk/glib/GLIB.bbc", @tmp$+"glib_bbc.BBC" )
INSTALL @tmp$ + "glib_bbc"
PROCglib_FixWindowSize : MODE 8 : OFF
PROCglib_Init(g{}, glib{})
ON CLOSE PROCglib_Cleanup : QUIT
ON ERROR PROCglib_Cleanup : OSCLI "REFRESH ON" : ON : REPORT : PRINT " at line "; ERL : END
INSTALL @lib$+"SORTLIB" : sort% = FN_sortinit(1,0)
DIM g2{} = g{}
ballTypes% = 6 : DIM bmAddrTbl%( ballTypes%-1 )
REM bmAddrTbl%(0) = FNglib_LoadImg( @dir$+"blueball_128x128x24.BMP", -1 )
bmAddrTbl%(0) = FNLoadImgFromNet( "http://www.proggies.uk/temp/", "blueball_128x128x24.bmp" )
g2.w% = 128
g2.h% = 128
FOR I% = 1 TO ballTypes%-1
bmAddrTbl%(I%) = FNglib_CopyBitmap( glib{}, bmAddrTbl%(0), 128, 128, -1 )
g2.a% = bmAddrTbl%(I%)
SYS glib.PlotShuffleRGB%, g2{}, bmAddrTbl%(I%), 128, 128, 0, 0, I%
NEXT I%
_PREMULTIPLY = &1
_INVERT = &8
_3MRPASS = 3<<4
_2MBBPASS = 2<<6
ctrl% = _PREMULTIPLY + _INVERT + _3MRPASS + _2MBBPASS
FOR I% = 0 TO ballTypes%-1
PROCglib_CreateAlphaMask( g{}, glib{}, bmAddrTbl%(I%), 128, 128, 0, ctrl% )
NEXT I%
N% = 50
DIM bmAddr%( N%-1 ), bmAddr2%( N%-1 )
DIM x%(N%-1), y%(N%-1), z%(N%-1)
DIM x2%(N%-1), y2%(N%-1), z2%(N%-1)
minDist% = 100
R% = RND(-12345)
FOR I%=0 TO N%-1
REPEAT
valid% = TRUE
x%=-400+RND(2*400 - 1)
y%=-400+RND(2*400 - 1)
z%=-400+RND(2*400 - 1)
IF I%=0 THEN
x%(0) = x%
y%(0) = y%
z%(0) = z%
ELSE
FOR J%=0 TO I%
d% = SQR( (x%-x%(J%))^2 + (y%-y%(J%))^2 + (z%-z%(J%))^2 )
IF d% < minDist% THEN
valid% = FALSE
J% = I%
ENDIF
NEXT J%
ENDIF
UNTIL valid%
x%(I%) = x%
y%(I%) = y%
z%(I%) = z%
bmAddr%(I%) = bmAddrTbl%( RND(ballTypes%)-1 )
NEXT I%
a#=0
b#=0
c#=0
*REFRESH OFF
REPEAT
T% = TIME
bgCol% = &10000*INT(255*ABSSINRAD(T%/4.5)) + \
\ &100*INT(255*ABSSINRAD(T%/6.7)) + \
\ INT(255*ABSCOSRAD(T%/6.83))
SYS glib.Clr%, g{}, bgCol%
cosa# = COSa#
cosb# = COSb#
cosc# = COSc#
sina# = SINa#
sinb# = SINb#
sinc# = SINc#
FOR I%=0 TO N%-1
x# = x%(I%)
y# = y%(I%)
z# = z%(I%)
x1# = x#*cosa# - y#*sina#
y1# = x#*sina# + y#*cosa#
z1# = z#
y2# = y1#*cosb# - z1#*sinb#
z2# = y1#*sinb# + z1#*cosb#
x2# = x1#
z3# = z2#*cosc# - x2#*sinc#
x3# = z2#*sinc# + x2#*cosc#
y3# = y2#
x2%(I%) = x3#
y2%(I%) = y3#
z2%(I%) = z3#
NEXT I%
bmAddr2%() = bmAddr%()
C%=N% : CALL sort%, z2%(0), x2%(0), y2%(0), bmAddr2%(0)
FOR I%=0 TO N%-1
d# = 1/(&3E8+z2%(I%))
x = &140 + &2A8 * x2%(I%) * d#
y = &100 + &2A8 * y2%(I%) * d#
scale% = &10000*300/(z2%(I%)+650)
SYS glib.PlotRotateScaleRTR%, g{}, bmAddr2%(I%), 128, 128, 16*x, 16*y, 0, scale%
NEXT
a# += 0.019151
b# += 0.016316
c# += 0.012194
IF a# > 2*PI THEN a# -= 2*PI
IF b# > 2*PI THEN b# -= 2*PI
IF c# > 2*PI THEN c# -= 2*PI
PROCglib_Display
UNTIL FALSE
DEFFNLoadImgFromNet(url$,file$):LOCALA%,F%:F%=OPENIN(@tmp$+file$)
IF F%=0 PROCurldownload(url$+file$,@tmp$+file$)
CLOSE#F%
A%=FNglib_LoadImg(@tmp$+file$,0)
=A%
DEFPROCurldownload(url$,file$)
LOCALurlmon%,res%
SYS"LoadLibrary","urlmon.dll"TOurlmon%
SYS"GetProcAddress",urlmon%,"URLDownloadToFileA"TO`URLDownloadToFile`
SYS`URLDownloadToFile`,0,url$,file$,0,0TOres%
SYS"FreeLibrary",urlmon%
IFres%ERROR100,"Couldn't download "+url$
ENDPROC
|
|
Logged
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: GLib (compact sprite library)
« Reply #29 on: Dec 1st, 2016, 07:45am » |
|
Brilliant - that's really encouraging. It's very hard to use someone else's programming tools without a clear understanding of the required format etc.
Thanks!
D
|
|
Logged
|
|
|
|
|