program Twister;
@use "graphics"
@requirefile "resources/data/data.bin" "Please execute the Fjong raytracer file 'resources/data/twister.fjo' before compiling this program"


/*

	The obligatory TRSE Twister(tm) effect!

*/

var	

   	k,l,i,time,tt,t2,j: integer = 0; 
 	n : long;
 	done : integer = 0;
   	t_tab : incbin("resources/data/table.bin");
   	t_data : incbin("resources/data/data.bin");
   	
// 2 bitplanes
	
   	screen_data : array[320*200] of byte chipmem;
// Sine table
@donotremove text   	
	text: string = ("ABCDEFGHIJKLMNABCDEFGHIJKLMNABCDEFGHIJKLMN");

	table2: pointer of integer;
		
	sine32 : array[256] of byte = buildtable("(Math.sin(i/256.0*2*3.14159)*127+127)/20.0");
	tp : pointer of byte;





procedure RenderTwister(xp : pointer of long; tx:integer);
var 
  dst : pointer of long;
begin
	table2 := #t_tab;
	tt:=0-tx; // Text goes up
	t2:=tx; // Twist goes down
	tp:=#text;
	dst := #screen_data;
	dst:=dst+xp;
	j:=0;
	for i:=0 to 128 do
	begin
		j:=sine32[(i+t2)&255]; // Twist turning
		k:=((tx-j)&15); // Current rotation frame
		l:=(i-tt); // Current shift & text position in y
		j:=l>>5; // j:=l/32 - find current character
	 	j:=(tp[j]-1)&31; // Look up current character, store in j
	 	// Look up : each charater is 32 height * 16 frames * 2 = 32*32 = shl 10 == shl 5 shl 5 
	 	n:=j*(32*32);
	 	
		l:=l&31;
		// Look up actual table: Frame (k) + line (l) + letter (n)
		k:=table2[k<<6+ l +n];


		// Copy 2x2 rows of data
		memcpyunroll(#t_data,k,dst,0,2,4);
		j:=k;
		k:=k+8;
		dst:=dst+40;
		memcpyunroll(#t_data,k,dst,0,2,4);
		dst:=dst+40;
		
		k:=j;

		memcpyunroll(#t_data,k,dst,0,2,4);
		k:=k+8;
		dst:=dst+40;
		memcpyunroll(#t_data,k,dst,0,2,4);
		dst:=dst+40;
		

	end;
	
end;





interrupt Raster();
begin
	RenderTwister(10,time/2);
	time:=time+1;
	
end;


procedure Init();
begin
	fill(#screen_data,0,320*200);
	// Set four colours	
	poke16(#copper_palette,2+4*1,$0555);	
	poke16(#copper_palette,2+4*2,$0800);	
	poke16(#copper_palette,2+4*3,$0F00);	
	poke16(#copper_palette,2+4*4,$0F32);	
	// Set up sine table	


end;


begin	
	Graphics::SetupDefaultScreen(#screen_data,2);
	Init();
	vbirq(Raster());
	EnableInterrupt(VB_IRQ);
	asm("
		bra *
	");
end.
