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

	Sample By Akira Matsuo

	1997.10.20
*/

#include <Ninja.h>



#define _R  0xff
#define _G  0xff
#define _B  0xff
#define _BSR  0xff
#define _BSG  0x80
#define _BSB  0x80
#define _LX 0.f
#define _LY 0.2f
#define _LZ -1.f

#define NPOLY 24
#define RADIUS 400.f
#define HEIGHT 800.f
#define STAGE 20
#define THICK HEIGHT/STAGE

extern NJS_POINT3COL vertex;
NJS_POINT3COL cylinder[NPOLY*STAGE];

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


void Cylinder(Uint32 attr)
{
    static int vinit = 0;
    static NJS_VECTOR light;
    int i;

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

    make_cylinder();
    for(i = 0; i < (NPOLY*STAGE); i++){
        flat_shade(light, i);
        njDrawPolygon3D(&(cylinder[i]), 4, attr);
    }
    FreeP3C(&vertex);
    for(i = 0; i < (NPOLY*STAGE); i++){
        FreeP3C(&(cylinder[i]));
    }

}



void make_cylinder()
{
    static Float rate_a = 0;
    static Float dir_a = -2;

    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(&(cylinder[i]), 4);
    }

    index = 0;
    if(rate >= 1.f || rate <= -1.f)
        dir *= -1;
    rate += dir;

    if(rate_a >= 180 || rate_a <= 0)
        dir_a *= -1;
    rate_a += dir_a;

    for(i = 0; i < (STAGE+1); i++){
        Float x = RADIUS, z = 0.f;
        x = RADIUS * (1.f-(njSin(NJM_DEG_ANG(540/STAGE*i))*rate));
        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 = THICK*i;
            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++){
            cylinder[index].p[0] = vertex.p[i*NPOLY+j];
            cylinder[index].p[1] = vertex.p[(j == (NPOLY-1)) ? i*NPOLY : i*NPOLY+j+1];
            cylinder[index].p[2] = vertex.p[(j == (NPOLY-1)) ? (i+1)*NPOLY : (i+1)*NPOLY+j+1];
            cylinder[index].p[3] = vertex.p[(i+1)*NPOLY+j];
            cylinder[index].tex[0].tex.u = vertex.tex[i*NPOLY+j].tex.u;
            cylinder[index].tex[0].tex.v = vertex.tex[i*NPOLY+j].tex.v;
            cylinder[index].tex[1].tex.u = (j == (NPOLY-1)) ? 256: vertex.tex[i*NPOLY+j+1].tex.u;/* 255.f; */
            cylinder[index].tex[1].tex.v = vertex.tex[(j == (NPOLY-1)) ? i*NPOLY : i*NPOLY+j+1].tex.v;/* 255.f; */
            cylinder[index].tex[2].tex.u = (j == (NPOLY-1)) ? 256: vertex.tex[(i+1)*NPOLY+j+1].tex.u;/* 255.f; */
            cylinder[index].tex[2].tex.v = vertex.tex[(j == (NPOLY-1)) ? (i+1)*NPOLY : (i+1)*NPOLY+j+1].tex.v;/* 255.f; */
            cylinder[index].tex[3].tex.u = vertex.tex[(i+1)*NPOLY+j].tex.u;
            cylinder[index].tex[3].tex.v = vertex.tex[(i+1)*NPOLY+j].tex.v;
            index++;
        }
    }
}


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

    njCalcPoint(NULL, &(cylinder[i].p[0]), &(p[0]));
    njCalcPoint(NULL, &(cylinder[i].p[1]), &(p[1]));
    njCalcPoint(NULL, &(cylinder[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++){
		    cylinder[i].col[j].argb.a = 0x80;
		    cylinder[i].col[j].argb.r = (Uint8)(_R * deg);
		    cylinder[i].col[j].argb.g = (Uint8)(_G * deg);
		    cylinder[i].col[j].argb.b = (Uint8)(_B * deg);
        }
    }
    else{
        int j;
        for(j = 0; j <4; j++){
		    cylinder[i].col[j].argb.a = 0xff;
		    cylinder[i].col[j].argb.r = (Uint8)(_BSR * -deg);
		    cylinder[i].col[j].argb.g = (Uint8)(_BSG * -deg);
		    cylinder[i].col[j].argb.b = (Uint8)(_BSB * -deg);
        }
    }
}
  

