program Example4;
@use "screen"
var  
	i,k,y,x,frame,time,curBank: byte = 0;
	p1,p2 : pointer;
	const maxFrames:byte=24;

	const width: byte = 40;
	


@requirefile "data/example4_chardata.bin" "Please run the Fjong raytracer file 'example4.fjo' before compiling this program"
	const charsetLocation: address = $2800;

	charsetBank1 : incbin("data/example4_chardata.bin",charsetLocation);
	screen : incbin("data/example4_screendata.bin",$6000);


/*

make sure that example4.fjo has been running for 16 frames before trying to compile this example file.

How this works: 

In example4.ras, we set up a scene with 16 frames. Using this fjong method:

  CompressCharset(0,40,0,25,  compression, 64)

we compress the current screen (fullscreen x,y from (0-40), (0-25)) to use a maximum of 64 characters. 
We also make sure that the compression level matches a maximum of 64 characters. 

After 16 frames, the compressed charset files + screen files are saved to disk as to independent files.

Now, 1 frame takes up 1/4 of a charset ($800 bytes), with a corresponding 40*25 screen of 1000 bytes for each frame. 

In this program, we simply display these 16 screens while updating the character set provided from the fjong rendering. 



*/


procedure SetScreen();
begin
	// Ugly but works, sets p1 to point to screen memory location 1000*frame 
	p1:=#screen+frame*4*250;
	

	// Enable bank switching to remove flickering
	// Copy 1000 bytes from p1 to p2
	copyfullscreen(p1, screen_char_loc);

	// Set charset location based on frame
	i:=frame/4;
	p1:=#charsetLocation;
	i:=i*8;
	asm("
		lda p1+1
		adc i
		sta p1+1
	");
	
	Screen::SetCharsetLocation(p1,0);


	
end;

/* Since we restricted each image to consist of 64 characters, we can fit 4 images into a single
256*8 charset. However, every second screen memory data must add a value of 64*frame, which we do here.

*/

procedure SetupScreenShift();
begin
	p1:=#screen;
	for i:=0 to maxFrames do begin
		k:=(i&3)*64;
		for y:=0 to 25 do begin
			for x:=0 to 40 do 
				p1[x]:=p1[x]+k;
			p1:=p1+width;
		end;	
		
	end;
end;

interrupt RasterMain();
begin
	StartIRQ(0);

	SetScreen();	
	if (time&3=0) then 
//		frame:=mod(frame + 1,maxFrames);
	frame:=frame+1;
	if (frame=maxFrames) then frame:=0;		
	inc(time);

	closeirq();
end;


begin
	Screen::Init();
	Screen::EnableVIC4();
	disableciainterrupts();
	setmemoryconfig(1,0,0);
	SetupScreenShift();
	Screen::Set40ColumnMode();
	SCREEN_BG_COL:=BLACK;
	SCREEN_FG_COL:=BLACK;
	Screen::FillColorRam80(purple+8);
	setmulticolormode();
	MULTICOLOR_CHAR_COL[2]:=BLUE;
	MULTICOLOR_CHAR_COL[1]:=WHITE;
	RasterIRQ(RasterMain(),0,0);
	EnableRasterIRQ();
	enableirq();
	Loop();

end.
