Replying to:12Me21
It might be faster to COPY between two arrays instead of using SHIFT/POP (though I don't know if this significantly affects the overall speed)
How would that work? Does COPY wrap around?
Root / Submissions / [.]
COMMON DEF NORMALIZE2D D#,SIZEX,SIZEY DIM MINV#=MIN(D#) DIM MAXV#=MAX(D#) DIM RANGE#=MAXV#-MINV# DIM X,Y FOR Y=0 TO SIZEY-1 FOR X=0 TO SIZEX-1 D#[X,Y]=(D#[X,Y]-MINV#)/RANGE# NEXT NEXT ENDThis function is included in Random's Big Dumb Library Now we can do Diamond Square. Diamond square works on a chunk system like minecraft: each chunk is 2N wide and tall and the overall array is a series of these chunks. The array that's returned is JUST a 2D array of values though; the chunks are "imaginary" and are only used in the algorithm. The parameters are: Feature Size (N), Width (Chunks across), Height (Chunks down), Seed (same seed = same noise), Decay (lower=smoother noise). The final dimensions of the returned noise array is (2N*Width+1,2N*Height+1). The Feature Size (N parameter) determines how "big" all the bumps are. Larger N = larger bumps, but remember it scales up by powers of 2 so don't go larger than 8 or so (28 is 256). At 1, the array will be nearly random static noise like the first picture. Experiment with N to find a good feature size for your needs. The decay is inverse smoothness: from 0 to 0.5, it will be exceptionally smooth. From 0.5 on it gets more rough: at 1 (the highest value you should give), it looks like you mixed the static with the good noise. Again, just experiment to find the value you like. It's a parameter for a reason. In our function, we use a seeded random number generator. SB comes with 8 different generators: we're using #7. If you need a different one, just change S.
COMMON DEF DIAMONDSQUARE#(N,WD,HT,SEED,DECAY#) DIM S=7 DIM BLOCK=POW(2,N) DIM SIZEX=BLOCK*WD+1 DIM SIZEY=BLOCK*HT+1 DIM ENDX=SIZEX-1 DIM ENDY=SIZEY-1 DIM D#[SIZEX,SIZEY] 'Final noise array. DIM P,RDEC#,OFS,HLF,X,Y,NUM,BX,BY DIM TOP,BOTTOM,LEFT,RIGHT,REDUX 'Optimization stuff RANDOMIZE S,SEED 'Corners (DS uses initial 4 corner values of each chunk to generate entire array) FOR Y=0 TO HT FOR X=0 TO WD D#[X*BLOCK,Y*BLOCK]=RNDF(S) NEXT NEXT 'Shrinking chunk series (look up Diamond Square to see what this is) FOR P=N TO 1 STEP -1 RDEC#=POW(DECAY#,N-P)*0.25 'Decaying randomness (plus a magic constant shrinking) OFS=POW(2,P) HLF=OFS/2 'Diamonds FOR Y=HLF TO ENDY STEP OFS FOR X=HLF TO ENDX STEP OFS D#[X,Y]=(D#[X-HLF,Y-HLF]+D#[X+HLF,Y-HLF]+D#[X-HLF,Y+HLF]+D#[X+HLF,Y+HLF])/4+(0.5-RNDF(S))*RDEC# NEXT NEXT 'Squares FOR Y=0 TO ENDY STEP HLF NUM=4 'All these TOP/BOTTOM/LEFT/RIGHT checks are because the square step might go out of bounds and we need to handle that IF Y>0 THEN TOP=Y-HLF ELSE TOP=Y:NUM=3 IF Y<ENDY THEN BOTTOM=Y+HLF ELSE BOTTOM=Y:NUM=3 FOR X=HLF*((Y AND (OFS-1))==0) TO ENDX STEP OFS REDUX=0 IF X>0 THEN LEFT=X-HLF ELSE LEFT=X:REDUX=1 IF X<ENDX THEN RIGHT=X+HLF ELSE RIGHT=X:REDUX=1 D#[X,Y]=(D#[X,TOP]+D#[X,BOTTOM]+D#[LEFT,Y]+D#[RIGHT,Y])/(NUM-REDUX)+(0.5-RNDF(S))*RDEC# NEXT NEXT NEXT NORMALIZE2D D#,SIZEX,SIZEY RETURN D# ENDThis function is included in Random's Big Dumb Library
COMMON DEF LERP(A#,B#,T#) T#=MIN(ABS(T#),1) RETURN A#+T#*(B#-A#) END 'Shift is how much of each color to use. 0=all col1, 1=all col2, 0.5=half and half COMMON DEF BLENDCOLORS(COL1,COL2,SHIFT#) DIM C1R,C1G,C1B,C2R,C2G,C2B,A1,A2 RGBREAD COL1 OUT A1,C1R,C1G,C1B RGBREAD COL2 OUT A2,C2R,C2G,C2B RETURN RGB(FLOOR(LERP(A1,A2,SHIFT#)),FLOOR(LERP(C1R,C2R,SHIFT#)),FLOOR(LERP(C1G,C2G,SHIFT#)),FLOOR(LERP(C1B,C2B,SHIFT#))) ENDThese functions are included in Random's Big Dumb Library
DIM N=5 DIM WD=8 DIM HT=8 DIM DECAY#=0.8 DIM DS#[0,0] 'Raw Diamond Square data DIM PCNT=256 'How many colors in the whole palette (try to keep it under 256; more is unnecessary) DIM PL[PCNT] 'The palette of blended colors DIM CCNT=4 'The separate pure colors to use in the plasma (count) DIM COLS[CCNT] 'This is a red and blue plasma like in the video. We insert black between to make it look cooler COLS[0]=#RED COLS[1]=#BLACK COLS[2]=#BLUE COLS[3]=#BLACK 'Use MILLISEC as seed to make it random plasma each time DS#=DIAMONDSQUARE#(N,WD,HT,MILLISEC,DECAY#) 'Convert DS raw to palette data. Remember how big the DS array is: DIM SIZEX=POW(2,N)*WD+1 DIM SIZEY=POW(2,N)*HT+1 DIM X,Y,C,I,P DIM PD[SIZEY,SIZEX] 'Diamond Square data converted to palette range. We reverse X and Y because of how SB does GLOAD FOR X=0 TO SIZEX-1 FOR Y=0 TO SIZEY-1 PD[Y,X]=CEIL((PCNT-1)*DS#[X,Y]) NEXT NEXT 'Generate the base plasma palette. Iterate over each color, then spread out the blending over the palette range FOR C=0 TO CCNT-1 FOR I=0 TO PCNT/CCNT P=C*PCNT/CCNT+I IF P>=PCNT THEN BREAK PL[P]=BLENDCOLORS(COLS[C],COLS[(C+1)MOD CCNT],I/(PCNT/CCNT)) NEXT NEXT 'Now just display the plasma. Remember that GLOAD needs the correct width and height of the array. Also remember we're rotating the palette WHILE TRUE GLOAD 0,0,SIZEX,SIZEY,PD,PL,FALSE C=SHIFT(PL) PUSH PL,C VSYNC WENDIf you have any questions or if the code doesn't work, please let me know. I might've made a typo or something.
source: 12345 dest: ..... ..123 'copy 1 54123 'copy 2