program fullscreen_scroller_with_colors;
@use "tables/luminosities"
var  
	time, val, color, colorShift,i,j,k : byte = 0;  
	g_currentBank: byte = 0;
	temp_colorCopy : array[40] of byte;
	src,dst:pointer;
	g_vscroll : byte;
	
/*
	
	Full screen y-scrolling.
	Swapping between two buffers, copying data for each frame


*/

	const char : byte = 80;
	add1,add2 : integer;
@define charsetLoc $2800

   mainChar: IncBin("resources/charsets/charset.bin",@charsetLoc);


procedure SwitchBank();
begin
	if g_currentBank=0 then 
	begin
		SetBank(VIC_BANK1);
		add2:=0;
		add1:=$4000;
		src:=#screen_char_loc2;
		dst:=#screen_char_loc+screen_width;
	end
	else 
	begin
		SetBank(VIC_BANK0);
		add2:=$4000;
		add1:=0;
		src:=#screen_char_loc;
		dst:=#screen_char_loc2+screen_width;
		
	end;

	g_currentBank:=(g_currentBank+1)&1;
end;



procedure CopyFast(cnt :byte);
begin
	for i:=0 to cnt do
	begin
		memcpyunroll(src,0,dst,40*4);
		src+=40*4;
		dst+=40*4;
	end;
end;


/*
	Main method. Increases the scroll value. 
	Makes sure that various parts of the screen are copied
	for various values of the scroll register (since copying all data + color data would be impossible).

*/
procedure VerticalScroll();
begin
		g_vscroll:=(g_vscroll+1)&7;
		

		if g_vscroll=0 then SwitchBank();
		if g_vscroll=1 then CopyFast(3);
		if g_vscroll=2 then CopyFast(3);

		scrolly(g_vscroll);


end;



// Print a single line at the top of the screen on the current bank
procedure PrintLine();
begin
	j:=sine[time]/8;
	k:=sine[j*time/64]/2;
	for i:=0 to screen_width do begin
		// Chose the center of a nice sine functions so that the background looks
		// like a canal		
		val:=sine[(i*4 + j+k)+30]/16 + char;
		
		if val<64 then
			val:=key_space;

		if g_currentBank=1 then
			poke(screen_char_loc, i, val)
		else
			poke(screen_char_loc2, i, val);
	
	end;

end;

// Print a line of colors at $D800

// Raster update
interrupt Update();

begin
	startirq(1);
	hideBorderY(1);
	time:=time+1;

	VerticalScroll();
	// Only print a new line when scrolling index is 7
	if g_vscroll=7 then 
		PrintLine();



	closeirq();
end;

procedure Setup();
begin
	blockmemcpy(^@charsetLoc,^@charsetLoc+bank_size,8);
	screen_bg_col:=black;
	screen_fg_col:=black;

	setcharsetlocation(@charsetLoc);
	SwitchBank();
	hideBorderY(0);
end;


begin
	Setup();
	preventirq();
	StartRasterChain(Update(), 250,1);
	Loop();
end.
