This was originally written by Fletchie and modified by Boris (where are you?) I got this from the off-line forum (any chance of making it available again since that info is now useful?) The code worked like a charm right away:
autodefine "off"
def fps,ext:int
def t,n,nn:int
type pixel
def x:float
def y:float
def c:int
endtype
const total=10000
def test[total]:pixel
def vx[total]:float
def vy[total]:float
def an,x,y:float
createscreen 640,480,32
for t=1 to 200 /* A bit of a delay for screen warm-up */
fillscreen 0
flip
next t
nn=1001
do
fillscreen 0
if nn>20
nn=0
gosub set_pixels
endif
nn=nn+1
WritePixelGroupFast(test,total,backbuffer)
for t=0 to total-1 /* Add the x,y velocities... */
vx[t]=vx[t]*.995
vy[t]=vy[t]+.05
test[t].x=test[t].x+vx[t]
test[t].y=test[t].y+vy[t]
next t
writetext 0,0,str$(fps)
fps = flip
until keydown(1)
end
sub set_pixels
def start:int
def force:float
ext=rand(10,400)
select 1
case ext<100:fillscreen 0x111111
case ext<300:fillscreen 0x222222
case ext<370:fillscreen 0x333333
default:fillscreen 0x999999
endselect
start=rand(0,total-ext)
x=rand(0,640)
y=rand(0,480)
force=rand(1,4)*1000
for n=start to start+ext
test[n].x=x
test[n].y=y
test[n].c=rgb(rand(0,255),rand(0,255),rand(0,255))
an=rand(0,35999)/100f
vx[n]=fsind(an)*rand(50,5000)/force
vy[n]=fcosd(an)*rand(50,5000)/force
next n
return
endsub
def bpointer,bpitch:int
def pp:pointer
def pcount:int
sub WritePixelGroupFast(p:pointer,qty:int,w:window)
lockbuffer w
bpointer=getbufferpointer()
bpitch=getbufferpitch()
pp=p
pcount=qty
_asm
push ebp
push ebp
mov ebp,[$pp]
mov ecx,[$pcount]
mov esi,[$bpitch]
mov edi,[$bpointer]
another:
; mov ebx,[ebp+72] ; Enabling this increases fps slightly (kinda pre-caching), needs a bit of extra space at the end of an array
fld dword [ebp]
fistp dword [esp]
mov ebx,[esp]
cmp ebx,639 ; one less than screen width
jg nextone
test ebx,0x8000000
jnz nextone
fld dword [ebp+4]
shl bx,2
mov eax,esi
fistp dword [esp]
cmp dword [esp],479 ; one less than screen height
jg nextone
test dword [esp],0x80000000
jnz nextone
mul dword [esp]
add eax,ebx
add eax,edi
mov ebx,[ebp+8]
mov dword [eax],ebx
nextone:
add ebp,12
loop another
pop ebp
pop ebp
_endasm
unlockbuffer w
return
endsub