The above version is clearer if you want to understand the algorithm, but not very portable. Here's the same thing inside a function, no globals or Dims required! Returns an image rather than a mesh, so you can use it in 2D too.
Function DSA(fx,fz,hconst#,subk=0,jagk#=0.5,density#=1,maxh#=1,seed=-1) ;Final width, final height, height variance, subfeatures, softness ;density, alpha and RNDgen seed (so you can repeat a specific pattern) Local iterations,iterated#,jagv#,hipoint#,lopoint#,dn,size,max,sig,rs,scale#,t# Local xpos[4],ypos[4],zpos[4],dpos[4],dput[1],dd[1] Local mx=2^Ceil(Log(fx)/Log(2)) Local mz=2^Ceil(Log(fz)/Log(2)) If mx>mz Then size=mx:Else size=mz iterations=Log(size)/Log(2) max=size+1:map=CreateBank(max*max*4) If seed>-1 Then rs=RndSeed():SeedRnd seed ;So that other functions stay predictable For iterated=0 To iterations-1 jagv=jagk*((iterated/iterations)^2) For n=1 To 2^iterated For itn=1 To 2^iterated xpos[0]=(size/(2^(iterated+1)))+(n-1)*(size/(2^iterated)) ;get location... zpos[0]=(size/(2^(iterated+1)))+(itn-1)*(size/(2^iterated)) ;x1z1 etc give the square locations xpos[1]=xpos[0]:xpos[3]=xpos[0] zpos[2]=zpos[0]:zpos[4]=zpos[0] ;x4z1, x2z1, x2z3, x4z3 give the previous xpos[2]=n*(size/(2^iterated)):zpos[1]=itn*(size/(2^iterated)) ;diamond of which x0z0 is centre xpos[4]=(n-1)*(size/(2^iterated)):zpos[3]=(itn-1)*(size/(2^iterated)) dput[0]=0:dpos[2]=max*xpos[4]+zpos[3]:dpos[3]=max*xpos[2]+zpos[1]:dd[0]=2 ;Extended diagonals for quadratic/cubic smoothing If xpos[4]-((xpos[0]-xpos[4])*2)>=0 And zpos[3]-((zpos[0]-zpos[3])*2)>=0 Then dpos[1]=max*(xpos[4]-((xpos[0]-xpos[4])*2))+(zpos[3]-((zpos[0]-zpos[3])*2)):dd[0]=3 If xpos[2]+((xpos[2]-xpos[0])*2)<=size And zpos[1]+((zpos[1]-zpos[0])*2)<=size Then dpos[4]=max*(xpos[2]+((xpos[2]-xpos[0])*2))+(zpos[1]+((zpos[1]-zpos[0])*2)):dd[0]=dd[0]+2 If dd[0]>2 If dd[0]=3 Then dput[0]=quadpol(dpos[1],dpos[2],dpos[3],max*xpos[0]+zpos[0],map,max) If dd[0]=4 Then dput[0]=quadpol(dpos[2],dpos[3],dpos[4],max*xpos[0]+zpos[0],map,max) If dd[0]=5 Then dput[0]=cubepol(dpos[1],dpos[2],dpos[3],dpos[4],map) EndIf dpos[2]=max*xpos[2]+zpos[3]:dpos[3]=max*xpos[4]+zpos[1]:dd[1]=2 ;Opposite extended diagonals for quadratic/cubic smoothing If xpos[2]+((xpos[2]-xpos[0])*2)<=size And zpos[3]-((zpos[0]-zpos[3])*2)>=0 Then dpos[1]=max*(xpos[2]+((xpos[2]-xpos[0])*2))+(zpos[3]-((zpos[0]-zpos[3])*2)):dd[1]=3 If xpos[4]-((xpos[0]-xpos[4])*2)>=0 And zpos[1]+((zpos[1]-zpos[0])*2)<=size Then dpos[4]=max*(xpos[4]-((xpos[0]-xpos[4])*2))+(zpos[1]+((zpos[1]-zpos[0])*2)):dd[1]=dd[1]+2 If dd[1]>2 If dd[1]=3 Then dput[1]=quadpol(dpos[1],dpos[2],dpos[3],max*xpos[0]+zpos[0],map,max) If dd[1]=4 Then dput[1]=quadpol(dpos[2],dpos[3],dpos[4],max*xpos[0]+zpos[0],map,max) If dd[1]=5 Then dput[1]=cubepol(dpos[1],dpos[2],dpos[3],dpos[4],map) EndIf bleh1=xpos[2] bleh2=zpos[3] ypos[0]=(PeekHeight(map,max*xpos[4]+zpos[1])+PeekHeight(map,max*xpos[2]+zpos[1])+PeekHeight(map,max*xpos[2]+zpos[3])+PeekHeight(map,max*xpos[4]+zpos[3]))/4 ypos[0]=ypos[0]+hvar(hconst,iterated,subk) If dd[0]+dd[1]>4 If dd[0]>2 And dd[1]>2 ypos[0]=linpol(ypos[0],(dput[0]+dput[1])/2,jagv) Else dput[0]=linpol(ypos[0],dput[0]+dput[1],jagv) ypos[0]=linpol(ypos[0],dput[0],jagv) EndIf EndIf PokeHeight map,max*xpos[0]+zpos[0],ypos[0] If ypos[0]<lopoint Then lopoint=ypos[0] If ypos[0]>hipoint Then hipoint=ypos[0] dn=0:dd[0]=0:dd[1]=0 dput[0]=0:dput[1]=0 ypos[1]=0:dpos[1]=0 ypos[2]=0:dpos[2]=0 ypos[3]=0:dpos[3]=0 ypos[4]=0:dpos[4]=0 If zpos[1]+(zpos[1]-zpos[0])<=size ypos[1]=ypos[1]+PeekHeight(map,max*xpos[1]+(zpos[1]+(zpos[1]-zpos[0]))) dn=1 dpos[3]=max*xpos[1]+(zpos[1]+(zpos[1]-zpos[0])) dd[0]=1 EndIf dpos[2]=max*xpos[1]+zpos[0]:dd[0]=dd[0]+1 ypos[1]=ypos[1]+PeekHeight(map,max*xpos[4]+zpos[1])+PeekHeight(map,max*xpos[2]+zpos[1])+ypos[0]:dn=dn+3 ypos[1]=ypos[1]/dn:dn=0 ypos[1]=ypos[1]+hvar(hconst,iterated,subk) If dd[0]>1 If zpos[0]-(2*(zpos[1]-zpos[0]))>=0 Then dpos[1]=max*xpos[1]+(zpos[0]-(2*(zpos[1]-zpos[0]))):dd[0]=dd[0]+1 If zpos[1]+(3*(zpos[1]-zpos[0]))<=size Then dpos[4]=max*xpos[1]+(zpos[1]+(3*(zpos[1]-zpos[0]))):dd[0]=dd[0]+2 EndIf If dd[0]>2 If dd[0]=3 Then dput[0]=quadpol(dpos[1],dpos[2],dpos[3],max*xpos[0]+zpos[0],map,max) If dd[0]=4 Then dput[0]=quadpol(dpos[2],dpos[3],dpos[4],max*xpos[0]+zpos[0],map,max) If dd[0]=5 Then dput[0]=cubepol(dpos[1],dpos[2],dpos[3],dpos[4],map) EndIf dpos[2]=max*xpos[4]+zpos[1]:dpos[3]=max*xpos[2]+zpos[1]:dd[1]=2 If xpos[4]-(2*(xpos[1]-xpos[4]))>=0 Then dpos[1]=max*(xpos[4]-(2*(xpos[1]-xpos[4])))+zpos[1]:dd[1]=dd[1]+1 If xpos[2]+(2*(xpos[2]-xpos[1]))<=size Then dpos[4]=max*(xpos[2]+(2*(xpos[2]-xpos[1])))+zpos[1]::dd[1]=dd[1]+2 If dd[1]>2 If dd[1]=3 Then dput[1]=quadpol(dpos[1],dpos[2],dpos[3],max*xpos[0]+zpos[0],map,max) If dd[1]=4 Then dput[1]=quadpol(dpos[2],dpos[3],dpos[4],max*xpos[0]+zpos[0],map,max) If dd[1]=5 Then dput[1]=cubepol(dpos[1],dpos[2],dpos[3],dpos[4],map) EndIf If dd[0]+dd[1]>3 If dd[0]>2 And dd[1]>2 ypos[1]=linpol(ypos[1],(dput[0]+dput[1])/2,jagv) Else dput[0]=linpol(ypos[1],dput[0]+dput[1],jagv) ypos[1]=linpol(ypos[1],dput[0],jagv) EndIf EndIf dd[0]=0:dd[1]=0 dput[0]=0:dput[1]=0 If ypos[1]<lopoint Then lopoint=ypos[1] If ypos[1]>hipoint Then hipoint=ypos[1] If xpos[2]+(xpos[2]-xpos[0])<=size ypos[2]=ypos[2]+PeekHeight(map,max*(xpos[2]+(xpos[2]-xpos[0]))+zpos[2]) dn=1 dpos[3]=max*(xpos[2]+(xpos[2]-xpos[0]))+zpos[2] dd[0]=1 EndIf dpos[2]=max*xpos[0]+zpos[2]:dd[0]=dd[0]+1 ypos[2]=ypos[2]+PeekHeight(map,max*xpos[2]+zpos[1])+PeekHeight(map,max*xpos[2]+zpos[3])+ypos[0]:dn=dn+3 ypos[2]=ypos[2]/dn:dn=0 ypos[2]=ypos[2]+hvar(hconst,iterated,subk) If dd[0]>1 If xpos[0]-(2*(xpos[2]-xpos[0]))>=0 Then dpos[1]=max*(xpos[0]-(2*(xpos[2]-xpos[0])))+zpos[2]:dd[0]=dd[0]+1 If xpos[2]+(3*(xpos[2]-xpos[0]))<=size Then dpos[4]=max*(xpos[2]+(3*(xpos[2]-xpos[0])))+zpos[2]:dd[0]=dd[0]+2 EndIf If dd[0]>2 If dd[0]=3 Then dput[0]=quadpol(dpos[1],dpos[2],dpos[3],max*xpos[0]+zpos[0],map,max) If dd[0]=4 Then dput[0]=quadpol(dpos[2],dpos[3],dpos[4],max*xpos[0]+zpos[0],map,max) If dd[0]=5 Then dput[0]=cubepol(dpos[1],dpos[2],dpos[3],dpos[4],map) EndIf dpos[2]=max*xpos[2]+zpos[3]:dpos[3]=max*xpos[2]+zpos[1]:dd[1]=2 If zpos[3]-(2*(zpos[2]-zpos[3]))>=0 Then dpos[1]=max*xpos[2]+(zpos[3]-(2*(zpos[2]-zpos[3]))):dd[1]=dd[1]+1 If zpos[1]+(2*(zpos[1]-zpos[2]))<=size Then dpos[4]=max*xpos[2]+(zpos[1]+(2*(zpos[1]-zpos[2]))):dd[1]=dd[1]+2 If dd[1]>2 If dd[1]=3 Then dput[1]=quadpol(dpos[1],dpos[2],dpos[3],max*xpos[0]+zpos[0],map,max) If dd[1]=4 Then dput[1]=quadpol(dpos[2],dpos[3],dpos[4],max*xpos[0]+zpos[0],map,max) If dd[1]=5 Then dput[1]=cubepol(dpos[1],dpos[2],dpos[3],dpos[4],map) EndIf If dd[0]+dd[1]>3 If dd[0]>2 And dd[1]>2 ypos[2]=linpol(ypos[2],(dput[0]+dput[1])/2,jagv) Else dput[0]=linpol(ypos[2],dput[0]+dput[1],jagv) ypos[2]=linpol(ypos[2],dput[0],jagv) EndIf EndIf dd[0]=0:dd[1]=0 dput[0]=0:dput[1]=0 If ypos[2]<lopoint Then lopoint=ypos[2] If ypos[2]>hipoint Then hipoint=ypos[2] If zpos[3]-(zpos[0]-zpos[3])>=0 ypos[3]=ypos[3]+PeekHeight(map,max*xpos[3]+(zpos[3]-(zpos[0]-zpos[3]))) dn=1 dpos[2]=max*xpos[3]+(zpos[3]-(zpos[0]-zpos[3])) dd[0]=1 EndIf dpos[3]=max*xpos[3]+zpos[0]:dd[0]=dd[0]+1 ypos[3]=ypos[3]+PeekHeight(map,max*xpos[4]+zpos[3])+PeekHeight(map,max*xpos[2]+zpos[3])+ypos[0]:dn=dn+3 ypos[3]=ypos[3]/dn:dn=0 ypos[3]=ypos[3]+hvar(hconst,iterated,subk) If dd[0]>1 If zpos[3]-(3*(zpos[0]-zpos[3]))>=0 Then dpos[1]=max*xpos[3]+(zpos[3]-(3*(zpos[0]-zpos[3]))):dd[0]=dd[0]+1 If zpos[0]+(2*(zpos[0]-zpos[3]))<=size Then dpos[4]=max*xpos[3]+(zpos[0]+(2*(zpos[0]-zpos[3]))):dd[0]=dd[0]+2 EndIf If dd[0]>2 If dd[0]=3 Then dput[0]=quadpol(dpos[1],dpos[2],dpos[3],max*xpos[0]+zpos[0],map,max) If dd[0]=4 Then dput[0]=quadpol(dpos[2],dpos[3],dpos[4],max*xpos[0]+zpos[0],map,max) If dd[0]=5 Then dput[0]=cubepol(dpos[1],dpos[2],dpos[3],dpos[4],map) EndIf dpos[2]=max*xpos[4]+zpos[3]:dpos[3]=max*xpos[2]+zpos[3]:dd[1]=2 If xpos[4]-(xpos[2]-xpos[4])>=0 Then dpos[1]=max*(xpos[4]-(xpos[2]-xpos[4]))+zpos[3]:dd[1]=dd[1]+1 If xpos[2]+(xpos[2]-xpos[4])<=size Then dpos[4]=max*(xpos[2]+(xpos[2]-xpos[4]))+zpos[3]:dd[1]=dd[1]+2 If dd[1]>2 If dd[1]=3 Then dput[1]=quadpol(dpos[1],dpos[2],dpos[3],max*xpos[0]+zpos[0],map,max) If dd[1]=4 Then dput[1]=quadpol(dpos[2],dpos[3],dpos[4],max*xpos[0]+zpos[0],map,max) If dd[1]=5 Then dput[1]=cubepol(dpos[1],dpos[2],dpos[3],dpos[4],map) EndIf If dd[0]+dd[1]>3 If dd[0]>2 And dd[1]>2 ypos[3]=linpol(ypos[3],(dput[0]+dput[1])/2,jagv) Else dput[0]=linpol(ypos[3],dput[0]+dput[1],jagv) ypos[3]=linpol(ypos[3],dput[0],jagv) EndIf EndIf dd[0]=0:dd[1]=0 dput[0]=0:dput[1]=0 If ypos[3]<lopoint Then lopoint=ypos[3] If ypos[3]>hipoint Then hipoint=ypos[3] If xpos[4]-(xpos[0]-xpos[4])>=0 ypos[4]=ypos[4]+PeekHeight(map,max*(xpos[4]-(xpos[0]-xpos[4]))+zpos[4]) dn=1 dpos[2]=max*(xpos[4]-(xpos[0]-xpos[4]))+zpos[4] dd[0]=1 EndIf dpos[3]=max*xpos[0]+zpos[4]:dd[0]=dd[0]+1 ypos[4]=ypos[4]+PeekHeight(map,max*xpos[4]+zpos[1])+PeekHeight(map,max*xpos[4]+zpos[3])+ypos[0]:dn=dn+3 ypos[4]=ypos[4]/dn:dn=0 ypos[4]=ypos[4]+hvar(hconst,iterated,subk) If dd[0]>1 If xpos[4]-(3*(xpos[0]-xpos[4]))>=0 Then dpos[1]=max*(xpos[4]-(3*(xpos[0]-xpos[4])))+zpos[4]:dd[0]=dd[0]+1 If xpos[0]+(xpos[2]-xpos[4])<=size Then dpos[4]=max*(xpos[0]+(xpos[2]-xpos[4]))+zpos[4]:dd[0]=dd[0]+2 EndIf If dd[0]>2 If dd[0]=3 Then dput[0]=quadpol(dpos[1],dpos[2],dpos[3],max*xpos[0]+zpos[0],map,max) If dd[0]=4 Then dput[0]=quadpol(dpos[2],dpos[3],dpos[4],max*xpos[0]+zpos[0],map,max) If dd[0]=5 Then dput[0]=cubepol(dpos[1],dpos[2],dpos[3],dpos[4],map) EndIf dpos[2]=max*xpos[4]+zpos[3]:dpos[3]=max*xpos[4]+zpos[1]:dd[1]=2 If zpos[3]-(zpos[1]-zpos[3])>=0 Then dpos[1]=max*xpos[4]+(zpos[3]-(zpos[1]-zpos[3])):dd[1]=dd[1]+1 If zpos[1]+(zpos[1]-zpos[3])<=size Then dpos[4]=max*xpos[4]+(zpos[1]+(zpos[1]-zpos[3])):dd[1]=dd[1]+2 If dd[1]>2 If dd[1]=3 Then dput[1]=quadpol(dpos[1],dpos[2],dpos[3],max*xpos[0]+zpos[0],map,max) If dd[1]=4 Then dput[1]=quadpol(dpos[2],dpos[3],dpos[4],max*xpos[0]+zpos[0],map,max) If dd[1]=5 Then dput[1]=cubepol(dpos[1],dpos[2],dpos[3],dpos[4],map) EndIf If dd[0]+dd[1]>3 If dd[0]>2 And dd[1]>2 ypos[4]=linpol(ypos[4],(dput[0]+dput[1])/2,jagv) Else dput[0]=linpol(ypos[4],dput[0]+dput[1],jagv) ypos[4]=linpol(ypos[4],dput[0],jagv) EndIf EndIf dd[0]=0:dd[1]=0 dput[0]=0:dput[1]=0 If ypos[4]<lopoint Then lopoint=ypos[4] If ypos[4]>hipoint Then hipoint=ypos[4] PokeHeight(map,max*xpos[1]+zpos[1],ypos[1]) PokeHeight(map,max*xpos[2]+zpos[2],ypos[2]) PokeHeight(map,max*xpos[3]+zpos[3],ypos[3]) PokeHeight(map,max*xpos[4]+zpos[4],ypos[4]) Next Next Next scale=255.0/(hipoint-lopoint) hipoint=hipoint-lopoint For x=0 To size For y=0 To size t=PeekHeight(map,max*x+y) t=t-lopoint t=t-(1-density)*hipoint If t<0 Then t=0 PokeHeight(map,max*x+y,t) Next Next hipoint=hipoint*density scale=(255.0/hipoint)*maxh dsamap=CreateImage(fx,fz) LockBuffer ImageBuffer(dsamap) For x=0 To fx-1 For y=0 To fz-1 hfinal#=PeekHeight(map,(max*x+y))*scale WritePixelFast(x,y,$ff000000 Or (hfinal Shl 16) Or (hfinal Shl 8) Or hfinal,ImageBuffer(dsamap)) Next Next UnlockBuffer ImageBuffer(dsamap) FreeBank map If seed>-1 Then SeedRnd rs ;Restore to where it was before... Return dsamap End Function Function PeekHeight(bank,offset) Return PeekFloat(bank,offset*4) End Function Function PokeHeight(bank,offset,value#) PokeFloat bank,offset*4,value# End Function Function hvar#(k#,itn,f=0) Local range# itn=itn-f If itn<1 Then itn=1 range=k/(2^itn) Return Rnd(range*-1,range) End Function Function linpol#(a#,b#,x#) ;Linear interpolation Return (a*(1-x))+(b*x) End Function Function quadpol#(d,e,f,xp,bank,max) ;Quadratic interpolation Local a#,b#,c#,x# If e Mod max=xp Mod max x=0.5*Sgn(xp/max-e/max) Else x=0.5*Sgn((xp Mod max)-(e Mod max)) EndIf c#=PeekHeight(bank,e) b#=(PeekHeight(bank,f)-PeekHeight(bank,d))/2 a#=(PeekHeight(bank,d)-c)+b Return (a*(x*x))+(b*x)+c End Function Function cubepol#(v0,v1,v2,v3,bank) ;Cubic interpolation Local P#=(PeekHeight(bank,v3)-PeekHeight(bank,v2))-(PeekHeight(bank,v0)-PeekHeight(bank,v1)) Local Q#=(PeekHeight(bank,v0)-PeekHeight(bank,v1))-P Local R#=PeekHeight(bank,v2)-PeekHeight(bank,v0) Local S#=PeekHeight(bank,v1) Return (P*0.125)+(Q*0.25)+(R*0.5)+S End Function