program Real3D;
@use "system/screen"
@use "system/graphics"
@use "system/str"
@use "memory"
//-----------------------------------------
//@define clear_method_backbuffer 0
//-----------------------------------------

@define lib3d_clearlines 0
@define linemethod "Graphics::Line"

@define max3dobjects 1

@use "gfx/lib3d"

var  
	time,i,j,l,t2 : byte;
	objPos : array[8000] of byte;//address = $042000;

	obj1 : incbin("data/torus1.bin");
	// objPos is the location where the object is stored: rotation matrix, 
	// rotated vertices and projected 2d coordinates
	// Three matrices
	matX, matY, matZ, matT : Matrix::mat4;

	p : pointer;


procedure Render();
begin
	// Flips the projection pointers so that we always keep a copy of the previous line list for 
	
	Lib3d::FlipPointPointers(0);
	// Rotate x,y and z with some random time value
	Matrix::RotateX(#matX, -time*1);
	Matrix::RotateZ(#matY, t2);
	Matrix::RotateZ(#matZ, time*2);

	// Mul X and Y to a temp mat T	
	Matrix::MatMul3(#matX, #matY, #matT);
	// Mul together and store in the objects rotation matrix
	Matrix::MatMul3(#matT, #matZ, Lib3d::objects[0].rotmat);
	// Perform the rotation (rotation_matrix * each vertex_in_the_object)
//	Lib3d::RotateVertices(0);	
	Lib3d::RotateVerticesOptimisedZ80(0);	
	// Projects the rotated vertices in a simple manner to 2d coordinates
	
	Lib3d::ProjectSimple(0, 90  ,80,80,  100);
	Lib3d::RenderWireframe(0);

	Graphics::Line(255,255,10,255+time, time&15);

end;	

begin
	Memory::DisableInterrupts();
	

	Screen::SetMode(Screen::mode_640_480_16);
	Screen::PrintString("Realtime calculation... ");
	
	Lib3d::InitializeData(#objPos);	
	Lib3d::LoadObject(0, #obj1);


	Matrix::Identity(#matX);
	Matrix::Identity(#matY);
	Matrix::Identity(#matZ);
	
	Matrix::Identity(Lib3d::objects[0].rotmat);
	p:=Lib3d::objects[0].color;
	for i:=0 to Lib3d::objects[0].noFaces do 
	begin
		// BUG FIX 
		j:=i&3 + 5;
		p[i]:=j;
	end;
	time:=0;
	t2:=111;
	while (true) do
	begin
		Render();
		time+=1;
		if (time&1=0) then t2+=1;
	end;

end.
