// Liquid3D - Moteur 3D C++ NDS par Morukutsu
// Surcouche de l'ulibrary de Brunni
// Version alpha 1

#include "Liquid3D.h"

namespace L3D
{
	int VideoCore::vcount, VideoCore::hcount;
	int VideoCore::cpuUsage, VideoCore::cpuCount;
	int32 VideoCore::viewportRatio, VideoCore::fov, VideoCore::near, VideoCore::far;

	// - - - - - - - - -
	// Classe VideoCore
	// - - - - - - - - - 
	void HBLFuncWrapper()
	{
		//s16 vcount = REG_VCOUNT;
		VideoCore::cpuCount++;
		//VideoCore::hcount++;
	}

	void VBLFuncWrapper()
	{
		//VideoCore::vcount++;
	}

	void VideoCore::Init(UL_INIT_FLAGS flags)
	{
		//Init de la lib et des variables
		ulInit(flags);
		vcount = hcount = 0;
		cpuCount = 0;

		//Inits caméra
		viewportRatio = divf32(256<<12, 192<<12);
		fov = 70 * DEGREES_IN_CIRCLE / 360;
		near = floattof32(0.1);
		far = inttof32(40);
	}

	void VideoCore::InitGfx(int mode)
	{
		switch(mode)
		{
		case GFX_MODE_3D:
			ulInitGfx();
			break;
		case GFX_MODE_DUAL3D:
			ulInitGfx();
			ulInitDualScreenMode();
			break;
		}
	}

	void VideoCore::InitInterrupts(int flags)
	{	
		if(flags & GFX_INTERRUPT_HBL)
		{
			irqSet(IRQ_HBLANK, HBLFuncWrapper);
			irqEnable(IRQ_HBLANK);
		}
		if(flags & GFX_INTERRUPT_VBL)
		{
			irqSet(IRQ_VBLANK, VBLFuncWrapper);
			irqEnable(IRQ_VBLANK);
		}
	}

	void VideoCore::StartDrawing2D()
	{
		//Paramètrages
		ulStartDrawing2D();
		
		//Vue & Projection
		glMatrixMode(GL_PROJECTION);
		MATRIX_IDENTITY = 0;

		glOrthof32(0, 256, 192, 0, inttof32(1), inttof32(-1));

		glMatrixMode(GL_TEXTURE);
		MATRIX_IDENTITY = 0;
	
		glMatrixMode(GL_MODELVIEW);
		MATRIX_IDENTITY = 0;
		
		MATRIX_SCALE = inttof32(1);
		MATRIX_SCALE = inttof32(1); 
		MATRIX_SCALE = inttof32(1);

		glMatrixMode(GL_PROJECTION);
	}

	void VideoCore::StartDrawing3D()
	{
		//glEnable(GL_BLEND);
		//glEnable(GL_TEXTURE_2D);

		//ulDisableEdgeAntialiasing();
		//GFX_CONTROL &= ~GL_OUTLINE;

		GFX_COLOR = 0x7fff;

		glMatrixMode(GL_TEXTURE);
		//Load identity
		MATRIX_IDENTITY = 0;
		
		glMatrixMode(GL_MODELVIEW);
		MATRIX_IDENTITY = 0;

		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspectivef32(fov, viewportRatio, near, far);	
	}

	void VideoCore::EndDrawing()
	{
		ulEndDrawing();
	}

	void VideoCore::EndFrame()
	{
		ulEndFrame();
	}

	void VideoCore::SyncFrame(int mode)
	{
		cpuUsage = div32(cpuCount * 100, 263);
		switch(mode)
		{
		case GFX_SYNC_60:
			swiWaitForVBlank();
			break;
		case GFX_SYNC_SKIP:
			if(cpuUsage <= 100)
				swiWaitForVBlank();
			break;
		};
		cpuCount = 0;
		ulEndFrame();
	}

};