drawcube.c 11.2 KB
/********************************************************************************
						   NINTENDO64 DIsk Drive IPL4

							  N-cube drawing module

								February 27, 1997
 ********************************************************************************/

#include <ultra64.h>
#include "ipl4.h"
#include "graphics.h"
#include "static.h"

#include "BUMPMAP/bumptex.inc"


static uwlong heapMemory[8192];			/* heap for the bump mapping (64K)		*/
static char * memoryptr;				/* memory allocation pointer			*/

static void *bumpmap1;
static void *bumpmap2;
static void *bumpmap3;
static void *bumpmap4;
static void *bumpmap5;
static void *bumpmap6;
static void *bumpmap7;
static void *bumpmap8;

static void *texture1;
static void *texture2;
static void *texture3;
static void *texture4;
static void *texture5;
static void *texture6;
static void *texture7;
static void *texture8;


//////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//		Bump mapping N-Cube drawing routines
//
//
//
//
//////////////////////////////////////////////////////////////////////////////////

/********************************************************************************/
/*																				*/
/*	Allocate memory for bump mapping											*/
/*																				*/
/********************************************************************************/
extern void *
malloc(long size)
{
	char *memory = memoryptr;

	memoryptr += size;
	return((void *)memory);
}
/********************************************************************************/
/*																				*/
/*	Initialize bump mapping works												*/
/*																				*/
/********************************************************************************/
extern void
InitBumpNCube(void)
{
	memoryptr = (char *)&heapMemory[0];

	bumpmap1 = NewBumpMap(32, 32,  0.00f, 0.00f,  1.00f, 0.75f, 0.44f, 1.0f, 6.0f, 1.0f, bumptex);
	bumpmap2 = NewBumpMap(32, 32,  0.00f, 0.00f, -1.00f, 0.75f, 0.44f, 1.0f, 6.0f, 1.0f, bumptex);
	bumpmap3 = NewBumpMap(32, 32,  1.00f, 0.00f,  0.00f, 0.75f, 0.44f, 1.0f, 6.0f, 1.0f, bumptex);
	bumpmap4 = NewBumpMap(32, 32, -1.00f, 0.00f,  0.00f, 0.75f, 0.44f, 1.0f, 6.0f, 1.0f, bumptex);

	bumpmap5 = NewBumpMap(32, 32,  0.00f,-0.67f,  0.74f, 0.75f, 0.44f, 1.0f, 6.0f, 1.0f, bumptex);
	bumpmap6 = NewBumpMap(32, 32,  0.00f,-0.67f, -0.74f, 0.75f, 0.44f, 1.0f, 6.0f, 1.0f, bumptex);
	bumpmap7 = NewBumpMap(32, 32,  0.74f,-0.67f,  0.00f, 0.75f, 0.44f, 1.0f, 6.0f, 1.0f, bumptex);
	bumpmap8 = NewBumpMap(32, 32, -0.74f,-0.67f,  0.00f, 0.75f, 0.44f, 1.0f, 6.0f, 1.0f, bumptex);
}
/********************************************************************************/
/*																				*/
/*	Draw bump mapping face.														*/
/*																				*/
/********************************************************************************/
static void
DrawBumpmapFace(void *texture, GfxPtr gfxlist)
{
    gDPLoadTextureBlock(graphicp++, texture, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0,
						 G_TX_WRAP|G_TX_NOMIRROR, G_TX_WRAP|G_TX_NOMIRROR,
						 5, 5, G_TX_NOLOD, G_TX_NOLOD
	);
	gSPDisplayList(graphicp++, gfxlist);
}
/********************************************************************************/
/*																				*/
/*	Draw bump mapping N-Cube.													*/
/*																				*/
/********************************************************************************/
static void
DrawBumpmapNCube(void)
{
	gSPDisplayList (graphicp++, Gfx_BumpNCubeStart);
	gDPSetPrimColor(graphicp++, 0,0,0,0,0,96);

	DrawBumpmapFace(texture1, Gfx_BumpNCube00);
	DrawBumpmapFace(texture2, Gfx_BumpNCube01);
	DrawBumpmapFace(texture3, Gfx_BumpNCube02);
	DrawBumpmapFace(texture4, Gfx_BumpNCube03);
	DrawBumpmapFace(texture5, Gfx_BumpNCube04);
	DrawBumpmapFace(texture6, Gfx_BumpNCube05);
	DrawBumpmapFace(texture7, Gfx_BumpNCube06);
	DrawBumpmapFace(texture8, Gfx_BumpNCube07);

    gDPLoadTextureBlock(graphicp++, bumptex, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0,
						 G_TX_WRAP|G_TX_NOMIRROR, G_TX_WRAP|G_TX_NOMIRROR,
						 5, 5, G_TX_NOLOD, G_TX_NOLOD
	);
	gSPDisplayList (graphicp++, Gfx_BumpNCube08	);
	gSPDisplayList (graphicp++, Gfx_BumpNCube09	);
	gSPDisplayList (graphicp++, Gfx_BumpNCube10	);
	gSPDisplayList (graphicp++, Gfx_BumpNCube11	);
	gDPSetPrimColor(graphicp++, 0,0,0,0,0,0);
	gSPDisplayList (graphicp++, Gfx_BumpNCube12	);
	gSPDisplayList (graphicp++, Gfx_BumpNCube13	);
	gSPDisplayList (graphicp++, Gfx_BumpNCubeEnd);
}
/********************************************************************************/
/*																				*/
/*	Update bump textures.														*/
/*																				*/
/********************************************************************************/
static void
UpdateBumpTextures(CtrlNCube *ncube)
{
	AffineMtx affine;
	FVector	  radian;
//	float	  light[3] = { -173.6f, -577.35f, 984.8f };
	float	  light[3] = {  342.0f, -577.35f, 939.7f };
	FVector	  scaling  = { 1.0f, 1.0f, 1.0f };


	AngvecToRadvec(&radian, &ncube->angle);
	CreateModelAffineMtx(&affine, &ncube->position, &radian, &scaling);

	texture1 = UpdateBumpMap(bumpmap1, light, &affine[0][0], &cameraMatrix[0][0]);
	texture2 = UpdateBumpMap(bumpmap2, light, &affine[0][0], &cameraMatrix[0][0]);
	texture3 = UpdateBumpMap(bumpmap3, light, &affine[0][0], &cameraMatrix[0][0]);
	texture4 = UpdateBumpMap(bumpmap4, light, &affine[0][0], &cameraMatrix[0][0]);
	texture5 = UpdateBumpMap(bumpmap5, light, &affine[0][0], &cameraMatrix[0][0]);
	texture6 = UpdateBumpMap(bumpmap6, light, &affine[0][0], &cameraMatrix[0][0]);
	texture7 = UpdateBumpMap(bumpmap7, light, &affine[0][0], &cameraMatrix[0][0]);
	texture8 = UpdateBumpMap(bumpmap8, light, &affine[0][0], &cameraMatrix[0][0]);
}


//////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//		N-Cube drawing routines
//
//
//
//
//////////////////////////////////////////////////////////////////////////////////

/********************************************************************************/
/*																				*/
/*	Make display list.															*/
/*																				*/
/********************************************************************************/
static void
MakeDisplayList(CtrlNCube *ncube, Gfx *gfxlist, int drawmode)
{
	FVector	radian;
	FVector position = ncube->position;
	FVector scaling  = ncube->scaling;
	Mtx *	modeling = (Mtx *)AllocDynamic(sizeof(Mtx));


	position.y += 1.0f;		/* for 3D calculate error correction	 */

	if (drawmode == NCUBE_DRAW_MIRROR) {
		position.y *= -1.0f;
		scaling.y  *= -1.0f;	
		gSPClearGeometryMode(graphicp++, G_CULL_BACK );
		gSPSetGeometryMode  (graphicp++, G_CULL_FRONT);
	}
	AngvecToRadvec(&radian, &ncube->angle);
	CreateModelMatrix(modeling, &position, &radian, &scaling);
	gSPMatrix(graphicp++, K0_TO_PHYS(modeling), G_MTX_MODELVIEW |G_MTX_LOAD|G_MTX_NOPUSH);

	if (gfxlist == NULL) {
		DrawBumpmapNCube();
	} else {
		gSPDisplayList(graphicp++, gfxlist);
	}
	if (drawmode == NCUBE_DRAW_MIRROR) {
    	gSPClearGeometryMode(graphicp++, G_CULL_FRONT);
		gSPSetGeometryMode  (graphicp++, G_CULL_BACK );
	}
}
/********************************************************************************/
/*																				*/
/*	Display color combine N-Cube.												*/
/*																				*/
/********************************************************************************/
static void
DoNormalColor(CtrlNCube *ncube)
{
	gDPPipeSync	   (graphicp++);
	gDPSetPrimColor(graphicp++, 0,0,ncube->color.r,ncube->color.g,ncube->color.b,ncube->color.a);

	if (ncube->flag & NCUBE_FLAG_MIRROR)  MakeDisplayList(ncube, Gfx_NCube, NCUBE_DRAW_MIRROR);
	if (ncube->flag & NCUBE_FLAG_NORMAL)  MakeDisplayList(ncube, Gfx_NCube, NCUBE_DRAW_NORMAL);
}
/********************************************************************************/
/*																				*/
/*	Display color combine N-Cube.												*/
/*																				*/
/********************************************************************************/
static void
DoColorCombine(CtrlNCube *ncube)
{
	gDPPipeSync	   (graphicp++);
	gDPSetPrimColor(graphicp++, 0,0,ncube->color.r,ncube->color.g,ncube->color.b,ncube->color.a);

	if (ncube->flag & NCUBE_FLAG_MIRROR)  MakeDisplayList(ncube, Gfx_MilkNCube, NCUBE_DRAW_MIRROR);
	if (ncube->flag & NCUBE_FLAG_NORMAL)  MakeDisplayList(ncube, Gfx_MilkNCube, NCUBE_DRAW_NORMAL);
}
/********************************************************************************/
/*																				*/
/*	Display texture combine N-Cube.												*/
/*																				*/
/********************************************************************************/
static void
DoTextureCombine(CtrlNCube *ncube)
{
	gDPPipeSync	   (graphicp++);
	gDPSetPrimColor(graphicp++, 0,0,0,0,0,ncube->color.a);

	gDPLoadMultiTile(graphicp++, ncube->texture1, 0, G_TX_RENDERTILE,
			G_IM_FMT_RGBA, G_IM_SIZ_16b,
			32, 32, 0,0,31,31, 0,
			G_TX_WRAP|G_TX_NOMIRROR, G_TX_WRAP|G_TX_NOMIRROR,
			5, 5,
			G_TX_NOLOD, G_TX_NOLOD
	);
	if (ncube->flag & NCUBE_FLAG_MIRROR)  MakeDisplayList(ncube, Gfx_TMixNCube, NCUBE_DRAW_MIRROR);
	if (ncube->flag & NCUBE_FLAG_NORMAL)  MakeDisplayList(ncube, Gfx_TMixNCube, NCUBE_DRAW_NORMAL);
}
/********************************************************************************/
/*																				*/
/*	Display texture over lap.													*/
/*																				*/
/********************************************************************************/
static void
DoTextureOverLap(CtrlNCube *ncube)
{
	gDPPipeSync	   (graphicp++);
	gDPSetPrimColor(graphicp++, 0,0,0,0,0,ncube->color.a);

	gDPLoadMultiTile(graphicp++, ncube->texture1, 0, G_TX_RENDERTILE,
			G_IM_FMT_RGBA, G_IM_SIZ_16b,
			32, 32, 0,0,31,31, 0,
			G_TX_WRAP|G_TX_NOMIRROR, G_TX_WRAP|G_TX_NOMIRROR,
			5, 5,
			G_TX_NOLOD, G_TX_NOLOD
	);
	gDPLoadMultiTile(graphicp++, ncube->texture2, 256, G_TX_RENDERTILE+1,
			G_IM_FMT_RGBA, G_IM_SIZ_16b,
			32, 32, 0,0,31,31, 0,
			G_TX_WRAP|G_TX_NOMIRROR, G_TX_WRAP|G_TX_NOMIRROR,
			5, 5,
			G_TX_NOLOD, G_TX_NOLOD
	);
	if (ncube->flag & NCUBE_FLAG_MIRROR)  MakeDisplayList(ncube, Gfx_TextNCube, NCUBE_DRAW_MIRROR);
	if (ncube->flag & NCUBE_FLAG_NORMAL)  MakeDisplayList(ncube, Gfx_TextNCube, NCUBE_DRAW_NORMAL);
}
/********************************************************************************/
/*																				*/
/*	Display bump mapping N-Cube.												*/
/*																				*/
/********************************************************************************/
static void
DoBumpMapping(CtrlNCube *ncube)
{
	gDPPipeSync	   (graphicp++);
	gDPSetPrimColor(graphicp++, 0,0,ncube->color.r,ncube->color.g,ncube->color.b,ncube->color.a);

	UpdateBumpTextures(ncube);
	if (ncube->flag & NCUBE_FLAG_MIRROR)  MakeDisplayList(ncube, NULL, NCUBE_DRAW_MIRROR);
	if (ncube->flag & NCUBE_FLAG_NORMAL)  MakeDisplayList(ncube, NULL, NCUBE_DRAW_NORMAL);
}
/********************************************************************************/
/*																				*/
/*	Display texture morph N-Cube.												*/
/*																				*/
/********************************************************************************/
extern void
DisplayNCube(CtrlNCube *ncube)
{
	switch (ncube->type) {
		case NCUBE_TYPE_COLOR	  : DoNormalColor	(ncube);		break;
		case NCUBE_TYPE_COLCOMBINE: DoColorCombine  (ncube);		break;
		case NCUBE_TYPE_TXTCOMBINE: DoTextureCombine(ncube);		break;
		case NCUBE_TYPE_TXTOVERLAP: DoTextureOverLap(ncube);		break;
		case NCUBE_TYPE_BUMPMAP	  : DoBumpMapping	(ncube);		break;
	}
}