Have you ever considered saving data into a pixel's color, but never understood what magical compression operations go on in the background?
Every pixel takes up 16 bits of storage, and this code lets you take advantage of that space.
'STORE A NUMBER FROM 0 TO 65535 (16 BITS) TO A PIXEL
DEF STORE X,Y,N
DIM PIXEL%[1]
PIXEL%[0]=N
GLOAD X,Y,1,1,PIXEL%,TRUE,TRUE
END
'RETRIEVE A NUMBER FROM A PIXEL
DEF UNSTORE(X,Y)
DIM PIXEL%[1]
GSAVE X,Y,1,1,PIXEL%,TRUE
RETURN PIXEL%[0]
END
Now, you could stop here, but we want to be able to make use of every single bit, allow larger numbers, and not have to worry about which pixel contains what data.
Using these two functions, we can construct a data structure.
Storing pixel to pixel, we will start from the bottom left hand corner of the graphics page, and work our way left to right, and then bottom to the top.
So our goal here is to have all the pixels work together to let you store any bit amount without worrying about the 0 TO 65535 (16 BIT) limitation.
Let's contruct a stack data structure:
'GLOBAL VARIABLES
VAR DATAX,DATAY=511,DATAP
DATAX is the x position of the current pixel
DATAY is the y position of the current pixel
DATAP is the bit position inside that current pixel
'PUSH SOME BITS ONTO THE GRAPHICS SCREEN
DEF PUSHDATA N,BITS
VAR I,D%
FOR I=1 TO BITS
D%=UNSTORE(DATAX,DATAY)
STORE DATAX,DATAY,D%*2+(N-2*FLOOR(N/2))
DATAP=DATAP+1
IF DATAP>15 THEN
DATAP=0
DATAX=DATAX+1
IF DATAX>511 THEN DATAX=0 DATAY=DATAY-1
ENDIF
N=N/2
NEXT
END
'POP SOME BITS OFF THE GRAPHICS SCREEN
DEF POPDATA(BITS)
VAR I,D%,N
FOR I=1 TO BITS
DATAP=DATAP-1
IF DATAP<0 THEN
DATAP=15
DATAX=DATAX-1
IF DATAX<0 THEN DATAX=511 DATAY=DATAY+1
ENDIF
D%=UNSTORE(DATAX,DATAY)
N=N*2+(D%-2*FLOOR(D%/2))
STORE DATAX,DATAY,D%/2
NEXT
RETURN N
END
So now we have a fully functional stack that is stored inside the graphics page, and can be loaded and saved along with a sprite page
Here is some test code
PUSHDATA 2147483648,31
PUSHDATA 2147483647,31
PUSHDATA 1,1
PUSHDATA 255,8
PUSHDATA 15,4
?POPDATA(4) 'BYTE
?POPDATA(8) 'CHARACTER
?POPDATA(1) 'BOOLEAN
?POPDATA(31) 'INTEGER
?POPDATA(31) 'OVERFLOWED INTEGER
The output should be 15, 255, 1, 2147483647, 0
Overflows work the exact same as they do in other programming languages
Keep in mind that if you are going to save and load this graphics page, you will also need to save the ending DATAX, DATAY, and DATAP variables, then load them along with the graphics page in order to ensure that the state of the stack remains the same.
This is the algorithm used in Fractal Canvas to save each design along with directions on how to navigate to that design (screenshot)
I hope you enjoyed this tutorial!
Thanks to 12Me21 for improving the algorithm.