program Plasma;
@use "system/screen"


@define OPTIMISED 1

var  
	// some plasma variables
	val,val2,c2x, c2y,ax, ay,time : byte;
	x,y,shift,h : byte;
	dst,zp : ^byte;
	// mini sine table
	const width : byte = 256/8;
	const height : byte = 48;	
	// The tables must be aligned at $xx00
    siny : array[height] of byte at $7F00; 
	sinx : array[width] of byte at $7E00; 
	sin : array[256] of byte = buildsinetable(127);

	data : incbin("data/smooth_data.bin", $7D00);
	

// Plasma procedure

procedure Calculate();
begin
	c2x:=ax;
	c2y:=ay;
	
	// Set up y-sine table
	for x:=0 to height do begin 
		siny[x]:=  sin[c2x] + sin[c2y] - time;
		c2x:=c2x+7;
		c2y:=c2y+5;
	end;

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

	// Set up x-sine table
	for x:=0 to width do begin 
		sinx[x] := sin[c2x] + sin[c2y];
		c2x:=c2x-9;
		c2y:=c2y+7;

	end;
	
end;


procedure Plasma0();
begin
	h:=shift;
	for y:=0 to height offpage do 
	begin
		val:=siny[y];
		dst:=Screen::ytab[h];
@if OPTIMISED = "0"
		for x:=0 to width do 
		begin
			dst[x]:=data[ (sinx[x] +val) ];
			// Set color memory
		end;
@else
		asm("
		ld a,[val]
		ld c,a
		ld iy,[dst]
		ld ix,sinx ; sin table
		ld hl,data ; data lookup for screen
		repeat 32
			
		ld a,c ; current value
		add a,[ix+{i}] ; add sine value
		; lookup in data[e] 
		ld l,a
		; now out it!
		ld a,[hl]
		ld [iy+[i]],a
		
		repend
		
		");


@endif
		h+=4;
	end;

end;


begin
		

	while (true) do
	begin
		Calculate();
		time+=1;
		shift:=(shift+1)&3;
		Plasma0()
	end;


end.
