program Tutorial3_plasma;

var
	// some plasma variables
	c,val,c2x, c2y,ax, ay : byte;
	x,y : byte;
	colorP: pointer;	

	const baseCharacter : byte = $68;
// charset will be placed at $2000 in bank 1	
	const charsetLocation : address = $2000;

	// Use custom charset
	charset : IncBin("resources/charsets/charset.bin", charsetLocation);
	// nice colors
    fade : array [] of byte = ($41,$3e,$51,$51,$44,$5e,$61,$71,$71,$71,$71,$61,$5e,$44,12,$51,$3e,$41,$71,$71); // PLUS4 colors

	// mini sine table
    siny : array[screen_height] of byte; 
	sinx : array[screen_width] of byte; 

	// Lookup table for division by 16
	lookupDiv16 : array[256] of byte;


// Define y_start as a global preprocessor constant
@define y_start "5"



// Plasma procedure

procedure Plasma();
begin
c2x:=ax;
	c2y:=ay;
	
	// Set up y-sine table
	for x:=0 to screen_height do begin 
		siny[x]:=  sine[c2x] + sine[c2y];
		c2x:=c2x+4;
		c2y:=c2y+9;
	end;

	ax:=ax+3;
	ay:=ay-5;

	// Set up x-sine table
	for x:=0 to screen_width do begin 
		sinx[x] := sine[c2x] + sine[c2y];
		c2x:=c2x+3;
		c2y:=c2y+7;
	end;
	// Move cursor to (1,y)
	moveto(1,@y_start, hi(screen_char_loc));
	// moveto could also be replaced with : screenmemory:=$0400 + @y_start*40;

	colorP:=#screen_col_loc + @y_start*screen_width;

	for y:=@y_start to 23 do begin
		val:=siny[y];
		for x:=1 to 36 do begin
			// here, we take (sin[x]+val) and divide by 16. However, since this is a slow procedure,
			// we have created a lookup table instead!
			c:=lookupDiv16[ (sinx[x] +val) ];
			// Set the screen memory
			screenmemory[x]:=c + baseCharacter;
			// Set color memory
			colorP[x] := fade[ c ];
		end;
		// Increase screen memory pointer by 40 (next row)
		screenmemory:=screenmemory+screen_width;
		// Increase color pointer by 40 (next row)
		colorP:=colorP+screen_width;
	end;

end;

procedure InitDivision16();
begin
	for x:=0 to 256 do lookupDiv16[x]:=x/16; // Simply store values divided by 16
end;

begin
	// Set color background
	screen_bg_col:=black;
	screen_fg_col:=black;
	// Set charmap location at $2000
	SetCharsetLocation(charsetLocation);
	InitDivision16();
	ax:=1;
	ay:=5;

	// Clear screen and color memory
	ClearScreen(key_space, screen_char_loc);
	// Main loop
	while (true) do begin
		waitForRaster(200 - 3*8);
		Plasma();
	end;
end.
