
#include "../interface.h"

void threadentry_cpu() { _system.cpu.enter(); }
void threadentry_vdp() { _system.vdp.enter(); }
void threadentry_apu() { _system.sn76489.enter(); }

void _System::init() {
	if(thread_cpu) co_delete(thread_cpu);
	if(thread_vdp) co_delete(thread_vdp);
	if(thread_apu) co_delete(thread_apu);

	clock.cpuvdp = 0;
	clock.cpuapu = 0;

	thread_app = co_active();
	thread_cpu = co_create(65536 * sizeof(void*), threadentry_cpu);
	thread_vdp = co_create(65536 * sizeof(void*), threadentry_vdp);
	thread_apu = co_create(65536 * sizeof(void*), threadentry_apu);

	thread_active = thread_cpu;
}

void _System::render() {
	color.update();
	u32* gpu_data = 0;
	u32 gpu_pitch;
	u8* ppu_data = (u8*)vdp.output();
	u16 height = vdp.getRenderHeight();

	dvideo.set_counter_pos(vdp.get_frames_executed());
	//dvideo.set_counter_pos(sn76489.get_samples_executed());

	unsigned outwidth;
	unsigned outheight;

	color.active_filter->size(outwidth, outheight, 284, height);

	if ( dvideo.lock(gpu_data, gpu_pitch, outwidth, outheight) ) {	
		color.active_filter->render(vdp._getMode(), gpu_data, gpu_pitch, ppu_data, height);		
		dvideo.unlock();
		dvideo.redraw();
	}
}

void _System::enter() {
	inputmanager.pollDevices();
	inputmanager.update();
	co_switch(thread_active);
}

void _System::exit() {
	//inputmanager.pollDevices();
	//inputmanager.update();
	co_switch(thread_app);
}
