
/*
	Ninja Sample
	
	COPYRIGHT (C) SEGA ENTERSRISES,LTD.

	Sample By Akira Matsuo

	1997.11.7
*/

#include <Ninja.h>

/* Surface Color */
#define _R  0xff
#define _G  0xff
#define _B  0xff
/* Back Surface Color */
#define _BSR  0xff
#define _BSG  0x80
#define _BSB  0x80
/* Light Direction */
#define _LX 0.f
#define _LY 0.f
#define _LZ -1.f

/*
#define NPOLY 24
#define STAGE 24
#define RADIUS 200.f
#define HEIGHT 200.f
*/
Int NPOLY;
Int STAGE;
Float RADIUS;
Float HEIGHT;

NJS_POINT3COL vertex;
/* NJS_POINT3COL sphere[NPOLY*STAGE]; */
NJS_POINT3COL sphere[576];
Uint32 _alpha_;
Int _alpha_flag_;

void make_sphere();
void flat_shade2(NJS_VECTOR light, int i);
void MallocP3C(NJS_POINT3COL *p3c, Uint32 n); /* See Sample.c */
void FreeP3C(NJS_POINT3COL *p3c);             /* See Sample.c */


void Sphere(Uint32 attr)
{
    static int vinit = 0;
    static NJS_VECTOR light;
    static float rot = 0.f;
    int i;

    if(vinit == 0){
        light.x = _LX;
        light.y = -_LY;
        light.z = _LZ;
        njUnitVector(&light);
        vinit++;
    }

    make_sphere();
    for(i = 0; i < (NPOLY*STAGE); i++){
        flat_shade2(light, i);
        njDrawPolygon3D(&(sphere[i]), 4, attr);
    }

    FreeP3C(&vertex);
    for(i = 0; i < (NPOLY*STAGE); i++){
        FreeP3C(&(sphere[i]));
    }

}



void make_sphere()
{
    int i, j, index;
    static Float rate = 1.f;
    static Float dir = 0.01f;
    Float SinVal = njSin(NJM_DEG_ANG(360/NPOLY));
    Float CosVal = njCos(NJM_DEG_ANG(360/NPOLY));

    MallocP3C(&vertex, NPOLY*(STAGE+1));
    for(i = 0; i < NPOLY*STAGE; i++){
        MallocP3C(&(sphere[i]), 4);
    }

    index = 0;

    for(i = 0; i < (STAGE+1); i++){
        Float x, y, z = 0.f;
        x = (float)(RADIUS * njSin(NJM_DEG_ANG(i*180/STAGE))+0.05);
        y = (float)(HEIGHT * njCos(NJM_DEG_ANG(i*180/STAGE)));
        for(j = 0; j < NPOLY; j++){
            vertex.p[index].x = (x*CosVal)+(z*SinVal);
            vertex.p[index].z = -(x*SinVal)+(z*CosVal);
            vertex.p[index].y = y;
            vertex.tex[index].tex.u = 256/(NPOLY+1)*j;
            vertex.tex[index].tex.v = 256/STAGE*i;
            x = vertex.p[index].x;
            z = vertex.p[index].z;
            index++;
        }
    }
    index = 0;
    for(i = 0; i < STAGE; i++){
        for(j = 0; j < NPOLY; j++){
            sphere[index].p[0] = vertex.p[i*NPOLY+j];
            sphere[index].p[1] = vertex.p[(j == (NPOLY-1)) ? i*NPOLY : i*NPOLY+j+1];
            sphere[index].p[2] = vertex.p[(j == (NPOLY-1)) ? (i+1)*NPOLY : (i+1)*NPOLY+j+1];
            sphere[index].p[3] = vertex.p[(i+1)*NPOLY+j];
            sphere[index].tex[0].tex.u = vertex.tex[i*NPOLY+j].tex.u;
            sphere[index].tex[0].tex.v = vertex.tex[i*NPOLY+j].tex.v;
            sphere[index].tex[1].tex.u = (j == (NPOLY-1)) ? 256: vertex.tex[i*NPOLY+j+1].tex.u;/* 255.f; */
            sphere[index].tex[1].tex.v = vertex.tex[(j == (NPOLY-1)) ? i*NPOLY : i*NPOLY+j+1].tex.v;/* 255.f; */
            sphere[index].tex[2].tex.u = (j == (NPOLY-1)) ? 256: vertex.tex[(i+1)*NPOLY+j+1].tex.u;/* 255.f; */
            sphere[index].tex[2].tex.v = vertex.tex[(j == (NPOLY-1)) ? (i+1)*NPOLY : (i+1)*NPOLY+j+1].tex.v;/* 255.f; */
            sphere[index].tex[3].tex.u = vertex.tex[(i+1)*NPOLY+j].tex.u;
            sphere[index].tex[3].tex.v = vertex.tex[(i+1)*NPOLY+j].tex.v;
            index++;
        }
    }
}



void flat_shade2(NJS_VECTOR light, int i)
{
    NJS_VECTOR normal;
    float dotproduct, s1, s2, deg;
    NJS_POINT3 p[3];

    njCalcPoint(NULL, &(sphere[i].p[0]), &(p[0]));
    njCalcPoint(NULL, &(sphere[i].p[1]), &(p[1]));
    njCalcPoint(NULL, &(sphere[i].p[2]), &(p[2]));
    njGetPlaneNormal(p, &normal);
    dotproduct = njInnerProduct(&normal, &light);
    s1 = njScalor(&normal);
    s2 = njScalor(&light);
    deg = dotproduct/(s1*s2);
    if (deg > 0.f) {
        int j;
        for(j = 0; j <4; j++){
            sphere[i].col[j].argb.a = (Uint8)(_alpha_flag_ ? _alpha_ : 0x80);
		    sphere[i].col[j].argb.r = (Uint8)(_BSR * deg);
		    sphere[i].col[j].argb.g = (Uint8)(_BSG * deg);
		    sphere[i].col[j].argb.b = (Uint8)(_BSB * deg);
        }
    }
    else{
        int j;
        for(j = 0; j <4; j++){
		    sphere[i].col[j].argb.a = (Uint8)(_alpha_flag_ ? _alpha_ : 0x80);
		    sphere[i].col[j].argb.r = (Uint8)(_R * -deg);
		    sphere[i].col[j].argb.g = (Uint8)(_G * -deg);
		    sphere[i].col[j].argb.b = (Uint8)(_B * -deg);
        }
    }
}



