#include "data/inspired_01.h"
#include "data/inspired_02.h"
#include "data/inspired_03.h"
#include "data/inspired_04.h"
#include "data/inspired_05.h"
#include "data/inspired_06.h"
#include "data/inspired_07.h"
#include "data/inspired_08.h"
#include "data/inspired_09.h"
#include "data/inspired_10.h"
#include "data/inspired_11.h"
#include "data/inspired_12.h"
#include "data/inspired_13.h"
#include "data/inspired_14.h"
#include "data/inspired_15.h"
#include "data/inspired_16.h"

#include "data/inspired_back.h"



const unsigned char inspired_palette_bg  [16]={ 0x30,0x11,0x2a,0x28,0x30,0x11,0x00,0x0f,0x30,0x30,0x10,0x00,0x30,0x20,0x30,0x10 };
const unsigned char inspired_palette_spr [16]={ 0x30,0x17,0x27,0x30,0x30,0x27,0x37,0x30,0x30,0x17,0x27,0x38,0x30,0x17,0x27,0x38 };

const unsigned char inspired_palette_fade[]={
	0x30,0x30,0x10,0x00,
	0x30,0x30,0x31,0x10,
	0x30,0x30,0x32,0x32,
	0x30,0x20,0x30,0x32,
	0x30,0x30,0x30,0x30
};



#define INSP_FADE_IN_FRAME		(60*2)
#define INSP_COINS_IN_FRAME		(64*3)
#define INSP_COINS_OUT_FRAME	(64*11)
#define INSP_FADE_OUT_FRAME		(60*12)

#define SIDE_A_COLOR			0x11
#define SIDE_B_COLOR			0x2a


const signed char sin_table[256]={
	0,2,5,8,11,13,16,19,
	22,24,27,30,33,35,38,41,
	43,46,48,51,53,56,58,60,
	63,65,67,70,72,74,76,78,
	80,82,84,86,88,89,91,93,
	94,96,97,99,100,101,103,104,
	105,106,107,108,109,109,110,111,
	111,112,112,113,113,113,113,113,
	114,113,113,113,113,113,112,112,
	111,111,110,109,109,108,107,106,
	105,104,103,101,100,99,97,96,
	94,93,91,89,88,86,84,82,
	80,78,76,74,72,70,67,65,
	63,60,58,56,53,51,48,46,
	43,41,38,35,33,30,27,24,
	22,19,16,13,11,8,5,2,
	0,-2,-5,-8,-11,-13,-16,-19,
	-22,-24,-27,-30,-33,-35,-38,-41,
	-43,-46,-48,-51,-53,-56,-58,-60,
	-63,-65,-67,-70,-72,-74,-76,-78,
	-80,-82,-84,-86,-88,-89,-91,-93,
	-94,-96,-97,-99,-100,-101,-103,-104,
	-105,-106,-107,-108,-109,-109,-110,-111,
	-111,-112,-112,-113,-113,-113,-113,-113,
	-114,-113,-113,-113,-113,-113,-112,-112,
	-111,-111,-110,-109,-109,-108,-107,-106,
	-105,-104,-103,-101,-100,-99,-97,-96,
	-94,-93,-91,-89,-88,-86,-84,-82,
	-80,-78,-76,-74,-72,-70,-67,-65,
	-63,-60,-58,-56,-53,-51,-48,-46,
	-43,-41,-38,-35,-33,-30,-27,-24,
	-22,-19,-16,-13,-11,-8,-5,-2,
};

const unsigned char palette_spr_normal[16]={ 0x0f,0x30,0x38,0x2c,0x0f,0x29,0x25,0x16,0x0f,0x11,0x01,0x30,0x0f,0x12,0x21,0x30 };
const unsigned char palette_spr_dark  [16]={ 0x0f,0x10,0x18,0x0c,0x0f,0x09,0x05,0x06,0x0f,0x01,0x01,0x10,0x0f,0x12,0x21,0x30 };

#define INSPIRED_NT_ADR		0x20e9

#define COINS_ALL			8

#define COIN_ORBIT_CX		128-8
#define COIN_ORBIT_CY		114-8

unsigned int  coin_angle;
  signed int  coin_nx;
  signed int  coin_ny;
unsigned char coin_list_pos;

unsigned char orbit_angle;
  signed int  orbit_c;
  signed int  orbit_s;

const unsigned char* is_src;

#pragma bssseg (push,"SHAREDRAM1")
#pragma dataseg(push,"SHAREDRAM1")

unsigned char coin_list_px[256];
unsigned char coin_list_py[256];

#pragma dataseg(pop);
#pragma bssseg (pop);

const unsigned char flash_sequence[]={0x38,0x28,0x38,0x30,0x30,0x38};




signed char sin(unsigned char angle)
{
	if(angle<128) return sin_table[angle]; else return -sin_table[angle&127];
}



signed char cos(unsigned char angle)
{
	return sin(angle+64);
}



void update_coins(unsigned int frame)
{
	unsigned char i,sx,sy,pos,pal;

	oam_off=0;
	
	coin_nx=sin(coin_angle);
	coin_ny=cos(coin_angle)<<1;

	orbit_c=sin(orbit_angle);
	orbit_s=cos(orbit_angle);

	if(frame<INSP_COINS_OUT_FRAME)
	{
		coin_list_px[coin_list_pos&255]=COIN_ORBIT_CX+((coin_nx*orbit_c-coin_ny*orbit_s)>>8);
		coin_list_py[coin_list_pos&255]=COIN_ORBIT_CY+((coin_nx*orbit_s+coin_ny*orbit_c)>>9);
	}
	else
	{
		coin_list_px[coin_list_pos&255]=0;
		coin_list_py[coin_list_pos&255]=240;
	}

	pos=coin_list_pos;

	for(i=0;i<COINS_ALL;++i)
	{
		sx=coin_list_px[pos&255];
		sy=coin_list_py[pos&255];

		if((pos+32)&64)
		{
			pal=0;
		}
		else
		{
			pal=1|OAM_BEHIND;
		}

		oam_spr(sx+0,sy,0xde,pal,oam_off); oam_off+=4;
		oam_spr(sx+8,sy,0xdf,pal,oam_off); oam_off+=4; sy+=8;
		oam_spr(sx+0,sy,0xee,pal,oam_off); oam_off+=4;
		oam_spr(sx+8,sy,0xef,pal,oam_off); oam_off+=4;

		pos-=10;
	}

	++coin_list_pos;
	
	coin_angle+=2;
	
	if(!(frame&3)) orbit_angle+=1;
}



void e_inspired(void)
{
	unsigned char i,chr,anim,bright,fade_ptr,flash;
	unsigned int off,coins_delay,frame;
	
	oam_clear_fast();
	oam_size(0);

	chr=CHR_FONT;

	mmc3_chr_bank(chr+0,2);
	mmc3_chr_bank(chr+1,3);
	mmc3_chr_bank(chr+2,4);
	mmc3_chr_bank(chr+3,5);
		
	mmc3_set_mirroring(M_HORIZONTAL);
	
	set_irq_handler(IRQ_INSPIRED);
	set_nmi_handler(NMI_NORMAL);
	
	pal_bg (inspired_palette_bg);
	pal_spr(inspired_palette_spr);
	pal_bright(0);
	
	vram_adr(NAMETABLE_A);
	vram_unrle(inspired_back);

	memfill(update_list,NT_UPD_EOF,sizeof(update_list));
	
	bright=0;
	frame=0;
	anim=0;
	fade_ptr=4*4;
	flash=0;
	
	coin_angle=64+128;
	orbit_angle=0;

	coin_list_pos=0;
	coins_delay=INSP_COINS_IN_FRAME;


	for(off=0;off<256;++off)
	{
		coin_list_px[off]=0;
		coin_list_py[off]=240;
	}
	
	scroll(0,0);
	
	mmc3_irq_enable(199);
	
	ppu_on_all();
	
	while(1)
	{
		pal_col(0x06,inspired_palette_fade[fade_ptr+2]);
		pal_col(0x07,inspired_palette_fade[fade_ptr+3]);
		
		if(frame>INSP_FADE_IN_FRAME)
		{
			if(!(frame&15)) if(fade_ptr) fade_ptr-=4;
		}
		

		if(anim&64)
		{
			pal_col(1,SIDE_B_COLOR);
			pal_col(2,SIDE_A_COLOR);
		}
		else
		{
			pal_col(1,SIDE_A_COLOR);
			pal_col(2,SIDE_B_COLOR);
		}
		
		if(playdump_sync)
		{
			playdump_sync=0;
			flash=5;
		}
		
		if(flash)
		{
			pal_col(2,flash_sequence[flash]);
			--flash;
		}
		
		chr=CHR_INSPIRED+((anim&63)/4)*4;
		
		mmc3_chr_bank(chr+0,0);
		mmc3_chr_bank(chr+2,1);

		switch((anim&63)/4)
		{
		case 0: is_src=inspired_01_data; break;
		case 1: is_src=inspired_02_data; break;
		case 2: is_src=inspired_03_data; break;
		case 3: is_src=inspired_04_data; break;
		case 4: is_src=inspired_05_data; break;
		case 5: is_src=inspired_06_data; break;
		case 6: is_src=inspired_07_data; break;
		case 7: is_src=inspired_08_data; break;
		case 8: is_src=inspired_09_data; break;
		case 9: is_src=inspired_10_data; break;
		case 10: is_src=inspired_11_data; break;
		case 11: is_src=inspired_12_data; break;
		case 12: is_src=inspired_13_data; break;
		case 13: is_src=inspired_14_data; break;
		case 14: is_src=inspired_15_data; break;
		case 15: is_src=inspired_16_data; break;
		}
		
		is_src+=((anim&3)*(14*14));
		
		memcpy(update_list,is_src,14*14);
		
		if(coins_delay)
		{
			--coins_delay;
		}
		else
		{
			update_coins(frame);
		}
		
		pal_bright(bright);
		
		oam_update();
		
		ppu_wait_nmi();
		
		if(frame<100)
		{
			if(!(frame&15))
			{
				if(bright<4) ++bright;
			}
		}
		else
		if(frame>INSP_FADE_OUT_FRAME)
		{
			if(!(frame&15))
			{
				if(bright<7) ++bright; else break;
			}
		}
		
		++frame;
		++anim;
	}
	
	for(i=0;i<32;++i) pal_col(i,0x30);
	
	do
	{
		--bright;
		pal_bright(bright);
		delay(4);
	} while(bright);
	
	ppu_off();
}