
#include "drawing.h"
#include "cgm.h"
#include "cgm_soft.h"
#include "mosaic.h"
#include "rings.h"
#include "staraz.h"
#include "dots.h"
#include "writeri.h"
#include "kaleido.h"
#include <math.h>
#include <stdio.h>
#include <string.h>

#ifdef NOAMIKA
#include <SDL.h>
#include "cool_mzx/cool_mzx.h"
#else
#include "screen.h"
#include "theplayer.h"
#include "vbi.h"
#endif

#ifdef PSP

#define X_SCR 480
#define Y_SCR 272

#define X_FISH 240
#define Y_FISH 272
#define X_FISH_MOD 600

#define X_TXT_240 360
#define X_TXT_160 240
#define Y_TXT_80 108
#define Y_TXT_100 136
#define Y_TXT_120 163
#define Y_TXT_170 231

#else

#define X_SCR 320
#define Y_SCR 200

#define X_FISH 160
#define Y_FISH 200
#define X_FISH_MOD 400

#define X_TXT_240 240
#define X_TXT_160 160
#define Y_TXT_80 80
#define Y_TXT_100 100
#define Y_TXT_120 120
#define Y_TXT_170 170

#endif

volatile int tid=0;

#ifdef NOAMIKA
SDL_Surface *scr;
#else
void __interrupt __saveds int1(void)
{
    tid+=20;
}
void __interrupt __saveds int2(void)
{
    if(tid==-1)
        tid=0;
}
#endif

int skale,px,py;

void transu(int x,int y,int *xx,int *yy)
{
    *xx= (x*skale>>14)+X_SCR*2+px;
    *yy=-(y*skale>>14)+Y_SCR*2+py;
}

#ifdef NOAMIKA
unsigned    plookup[256]={0};
unsigned    plookup2[256]={0};
void gfx_setcolor(int n,int r,int g,int b)
{
    r&=0xff; g&=0xff; b&=0xff;
    plookup[n]=SDL_MapRGB(scr->format,r,g,b);	
    plookup2[n]=SDL_MapRGB(scr->format,r*4/5,g*4/5,b*4/5);
}
void gfx_setpalette(int first,int num,unsigned char *pal)
{
    int n;
    for(n=0;n<num;n++)
        gfx_setcolor(first+n,pal[n*3],pal[n*3+1],pal[n*3+2]);
}
#endif

void setkolor(int *pal,int br,int bg,int bb,int cols)
{
    int n,r,g,b;
    static unsigned char tmp[256*3];

    for(n=0;n<cols;n++)
    {
        r=pal[n+1]>>16;
        g=(pal[n+1]>>8)&0xff;
        b=pal[n+1]&0xff;
        tmp[n*3]=r;
        tmp[n*3+1]=g;
        tmp[n*3+2]=b;
        tmp[n*3+  128*3]=(r+br)>>1;
        tmp[n*3+1+128*3]=(g+bg)>>1;
        tmp[n*3+2+128*3]=(b+bb)>>1;
#ifdef NOAMIKA
        gfx_setcolor(n+1,r,g,b);
        gfx_setcolor(n+129,(r+br)>>1,(g+bg)>>1,(b+bb)>>1);
#endif
    }
#ifndef NOAMIKA
    gfx_setpalette(1,cols,tmp);
    gfx_setpalette(129,cols,&tmp[128*3]);
#endif
}

#ifndef PSP
#undef main
#else
/* On the PSP we need main defined as SDL_main. */
#endif
int main(int argc,char *argv[])
{
    int quit=0,n,i,*pal,last=0,pos=0,tmp,r,g,b,*pix,origtime=-1;
    FILE *f;
    static unsigned char palli[100];
	
#ifdef PSP

	static unsigned char puh[X_SCR*Y_SCR];
	static unsigned char buf[X_SCR*Y_SCR];
	static unsigned char *dest;

#else

    static unsigned char puh[320*256],buf[320*256],*dest;

#endif
    static char tst[200],
                *kriit[100]={" ","bandwagon","dcs","halcyon","pseudotoad","rno",
                             "unique","wamma","zenon",
                             "","","","","","","","","","",""};

    CGM *browni,*bootsy,*angels,*fish1,*fish2,*petteri,*trav,*travb,
        *bottle;
    double angel=0,flotari;
    void *musa;
    DRAWING *james,*afro;
#ifdef NOAMIKA
    SDL_Event e;
    int fullscreen=SDL_FULLSCREEN;
#endif

    int o_intro=-1,o_ring1=-1,o_stara=-1,o_kale=-1,o_tytsi=-1,o_greet=-1,
        o_cred1=-1,o_cred2=-1,o_travolta=-1,o_mosa=-1,o_bottle=-1;

    james=drawing_load("data/jamesbrown.txt");
    afro=drawing_load("data/afrogirl.txt");

    browni=cgm_load("data/browni.cgm");
    bootsy=cgm_load("data/bootsy.cgm");
    angels=cgm_load("data/ankels.cgm");
    fish1=cgm_load("data/fiske1.cgm");
    fish2=cgm_load("data/fiske2.cgm");
    trav=cgm_load("data/travolta.cgm");
    travb=cgm_load("data/travoltablk.cgm");
    bottle=cgm_load("data/bottles.cgm");

    pal=staraz_init();
    dots_init();
    writeri_init("data/fontti.raw");
    rings_init();
    mosaic_init(32);

#ifdef NOAMIKA

#ifdef PSP
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
	scr = SDL_SetVideoMode(X_SCR, Y_SCR, 32, SDL_HWSURFACE);
	memset(scr->pixels, 0, X_SCR * Y_SCR * 4);

#else
    if(argc>=2)
        if(!strcmp(argv[1],"-w"))
            fullscreen=0;
    if(argv[0][strlen(argv[0])-1]=='w') // Windowed (hex_pistols_window etc.)
            fullscreen=0;

    SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER);
    scr=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE|SDL_DOUBLEBUF|fullscreen);
    memset(scr->pixels,0,640*480*4);
    SDL_WM_SetCaption("Hex Pistols",NULL);
    SDL_ShowCursor(0);
#endif

    ungetc('\n',stdin);
    ungetc('2',stdin);
    mzx_init();

    musa=malloc(1000000);
    f=fopen("data/da_pope.mod","rb");
    fread(musa,1,1000000,f);
    fclose(f);
    mzx_get(musa);

    mzx_start(47);
    while(mzx_position()<0 || mzx_position()>100) // Skip bug...
        ;
    origtime=SDL_GetTicks();
#else
    musa=theplayer_load("data/P61.dapope");
    gfx_init();
    theplayer_init(musa);
    VBI_install(int1,int2);
#endif

    memset(buf, 127, X_SCR * Y_SCR);
	
    while(!quit)
    {
#ifdef NOAMIKA
        while(SDL_PollEvent(&e)>0)
        {
            if(e.type==SDL_MOUSEBUTTONDOWN)
                quit=1;
        }
#else
        if(!(*((char *)0xbfe001)&64))
            quit=1;
        
#endif
        
        dest=buf;
#ifdef NOAMIKA
        tid=SDL_GetTicks()-origtime;
        pos=mzx_position();
#else
        pos=pt_songpos*100+pt_patternpos;
#endif

        if(pos<200)
        {
            if(o_intro==-1)
            {
                setkolor(angels->pal,255,255,255,100);
                gfx_setcolor(127,255,150,150);
                gfx_setcolor(255,255,200,200);
                gfx_setcolor(128,100,90,90);
                gfx_setcolor(126,255,255,255);
                o_intro=tid;
            }
			
			memset(buf, 127, X_SCR * Y_SCR);
            
            px=0;py=20*4;
            skale=1000-(tid-o_intro)/18;
            cgm_render(angels,buf,transu);
        
            if(pos>=100 && pos<132)
                writeri(buf,X_TXT_160,Y_TXT_80,"fiture crew",1,tid,126);
            if(pos>=132)
                writeri(buf,X_TXT_160,Y_TXT_120,"on the floor",1,tid,126);
        }

        if(pos>=200 && pos<400)
        {
            if(o_ring1==-1)
            {
                gfx_setcolor(3,0,0,0);
                gfx_setcolor(1,255,180,180);
                gfx_setcolor(1+128,128,90,90);
                gfx_setcolor(2,255,60,200);
                gfx_setcolor(2+128,128,30,100);
                o_ring1=tid;
            }
            
			memset(buf, 1, X_SCR * Y_SCR);
			
            rings(buf,(pos%100/16&1)?tid*2:1000000-tid*2,18,1,2);
            writeri(buf,X_TXT_160,Y_TXT_100,"hex pistols",1,tid,3);
        }

        if(pos>=400 && pos<700)
        {
            if(o_tytsi==-1)
            {
                gfx_setcolor(1,110,200,150);
                gfx_setcolor(2,30,64,50);
                gfx_setcolor(1+128,200,255,220);
                gfx_setcolor(2+128,130,170,120);

                gfx_setcolor(126,255,255,255);

				memset(buf, 1, X_SCR * Y_SCR);
				
                o_tytsi=tid;
                last=0;
            }
        
            drawing(buf,afro,last,(tid-o_tytsi)/5,2);
            last=(tid-o_tytsi)/5;

			memcpy(puh, buf, X_SCR * Y_SCR);

            if(pos%100/4&1)
                writeri(puh,X_TXT_160,Y_TXT_100,"foxy lady!",1,tid,126);
            dest=puh;
        }

        if(pos>=700 && pos<900)
        {
            if(o_kale==-1)
            {
                gfx_setcolor(3,0,0,0);
                gfx_setcolor(1,255,255,255);
                gfx_setcolor(1+128,128,128,128);
                gfx_setcolor(2,120,120,255);
                gfx_setcolor(2+128,60,60,125);
                o_kale=tid;
            }
            
			memset(buf, 1, X_SCR * Y_SCR);
            rings(buf,tid,28,1,2);
            kaleido(buf, X_SCR, Y_SCR);
			
            tmp=pos%100; if(pos>=800) tmp+=64;

            strcpy(tst,"mi'05 mamas");
            tst[tmp/8]=0;
            writeri(buf,X_TXT_160,Y_TXT_170,tst,1,tid,3);
        }

        if(pos>=900 && pos<1100)
        {
            if(o_stara==-1)
            {
                o_stara=tid;
                setkolor(fish1->pal,0,0,0,100);
                gfx_setcolor(127,255,255,255);
            }

			memset(buf, 127, X_SCR * Y_SCR);

            staraz(buf,tid/2);
            for(n=0;n<3;n++)
            {
                px=((tid/40+n*X_FISH)%X_FISH_MOD-Y_FISH)*4;py=(n*80-80)*4;
                skale=40;
                cgm_render(fish1,buf,transu);
            }
        }

        if(pos>=1100 && pos<1500)
        {
            if(o_greet==-1)
            {
                gfx_setcolor(1,255,160,160);
                gfx_setcolor(2,100,0,0);
                gfx_setcolor(1+128,255,200,200);
                gfx_setcolor(2+128,200,100,100);
                gfx_setcolor(126,255,255,255);
                memset(buf, 1, X_SCR * Y_SCR);
                
                last=0;
                o_greet=tid;
            }
            drawing(buf,james,last,(tid-o_greet)/9,2);
            last=(tid-o_greet)/9;

			memcpy(puh, buf, X_SCR * Y_SCR);

            if(pos%100/4&1)
                writeri(puh,170,160,"greetz",0,tid,126);
            strcpy(tst,kriit[(tid-o_greet)/3600]);
            tst[(tid-o_greet)%3600/300]=0;
            writeri(puh,5,5,tst,0,tid,126);        
            dest=puh;
        }

        if(pos>=1500 && pos<1800)
        {
            if(o_travolta==-1)
            {
                setkolor(trav->pal,0,0,0,100);
                gfx_setcolor(127,255,255,255);
                o_travolta=tid;
            }
			
			memset(buf, 127, X_SCR * Y_SCR);
			
            staraz(buf,(pos%100/32&1)?tid:1000000-tid);

            if(pos>=1600 && pos<1616)
                writeri(buf,5,84,"d15c0!",0,tid,0);

            flotari=(tid-o_travolta)/200.0;
            flotari=flotari*flotari;
            px=80*4;py=100000/(100+flotari)*cos((tid-o_travolta)/1000.0);
            skale=120;
            cgm_render((pos%100/4&1)?trav:travb,buf,transu);
        }

        if(pos>=1800 && pos<2100)
        {
            if(o_mosa==-1)
            {
                setkolor(fish2->pal,0,0,0,100);
                o_mosa=tid;
                gfx_setcolor(3,0,0,0);
                gfx_setcolor(1,180,255,180);
                gfx_setcolor(2,150,255,20);
            }
            
			memset(buf, 1, X_SCR * Y_SCR);
			
            rings(buf,1000000-tid,23,2,2);
            for(n=0;n<3;n++)
            {
                px=((tid/20+n*X_FISH)%X_FISH_MOD-Y_FISH)*4;
                py=(n*60-60)*4;
                skale=40;
                cgm_render(fish2,buf,transu);
            }
            if(pos%100/32)
            {
                gfx_setcolor(2,120,210,20);
                mosaic(buf,puh);
                dest=puh;
            }
            else
            {
                gfx_setcolor(2,150,255,20);
            }
        }

        if(pos>=2100 && pos<2300)
        {
            if(o_cred1==-1)
            {
                gfx_setcolor(255,128,90,0);
                gfx_setcolor(127,255,180,0);
                setkolor(browni->pal,0,0,0,100);
                o_cred1=tid;
                petteri=browni;
            }
            if(o_cred2==-1 && pos>=2200)
            {
                setkolor(bootsy->pal,0,0,0,100);
                o_cred2=tid;
                petteri=bootsy;
            }        

			memset(buf, 127, X_SCR * Y_SCR);

            px=-60*4;
            py=0;
            angel=tid/150.0;
            skale=100+sin(angel)*30.0;
            cgm_render(petteri,buf,transu);

            if(o_cred2==-1)
            {
                switch(tid/200%3)
                {
                    case 0: strcpy(tst,"marq"); break;
                    case 1: strcpy(tst,"code"); break;
                    case 2: strcpy(tst,"grafix"); break;
                }
                writeri(buf,X_TXT_240,Y_TXT_100,tst,1,tid,0);
            }
            else
            {
                switch(tid/200%2)
                {
                    case 0: strcpy(tst,"roz"); break;
                    case 1: strcpy(tst,"funk"); break;
                }
                writeri(buf,X_TXT_240,Y_TXT_100,tst,1,tid,0);
            }
        }

        if(pos>=2300)
        {
            if(o_bottle==-1)
            {
                o_bottle=tid;
                gfx_setcolor(127,255,220,80);
            }
            
            for(n=0;n<100;n++)
            {   
                tmp=(tid-o_bottle)*255/5000;
                if(tmp>255) tmp=255;

                r=((bottle->pal[n]>>16)&0xff)*tmp+(255-tmp)*255;
                g=((bottle->pal[n]>>8)&0xff)*tmp+(255-tmp)*220;
                b=(bottle->pal[n]&0xff)*tmp+(255-tmp)*80;

                palli[n*3]=r/256;
                palli[n*3+1]=g/256;
                palli[n*3+2]=b/256;
            }
            gfx_setpalette(1,99,&palli[3]);

			memset(buf, 127, X_SCR * Y_SCR);
			
            px=-10*4;py=-30*4;
            skale=10+(tid-o_bottle)/78;
            cgm_render(bottle,buf,transu);
        }

        if(pos>=2500)
            quit=1;

#ifdef NOAMIKA
        SDL_LockSurface(scr);
        pix=scr->pixels;
		
#ifdef PSP

		tmp = 0;
		for(n = 0; n < Y_SCR; n++)
        {
            for(i=0; i < X_SCR; i++)
            {
                pix[tmp++] = plookup[dest[n * X_SCR + i]];
            }
			tmp += 512-480;
        }
#else
        for(n=0;n<200;n++)
        {
            tmp=(20+n)*1280;
            for(i=0;i<320;i++,tmp+=2)
            {
                pix[tmp]=pix[tmp+1]=plookup[dest[n*320+i]];
                pix[tmp+640]=pix[tmp+641]=plookup2[dest[n*320+i]];
            }
        }
#endif
        SDL_UnlockSurface(scr);
        SDL_Flip(scr);
#else

        gfx_blit(dest, 0, 0, X_SCR, Y_SCR);

#endif
    }

#ifdef NOAMIKA
    SDL_Quit();
#else
    theplayer_end();
    theplayer_free(musa);
    VBI_remove();
    gfx_close();
#endif
    return(0);
}
