@ -31,7 +31,7 @@
# define SCREENHEIGHT 240
# define NUMVERTEXNORMALS 162
static in t anorms [ NUMVERTEXNORMALS ] [ 3 ] = {
static shor t anorms [ NUMVERTEXNORMALS ] [ 3 ] = {
# include "ps1anorms.h"
} ;
@ -78,6 +78,21 @@ typedef struct
ps1mdl_t playerModel , shamblerModel ;
ps1skin_t playerSkin , shamblerSkin ;
SVECTOR rot = { 0 } ;
VECTOR pos = { - 200 , 128 , 64 } ;
MATRIX color_mtx = {
ONE , 0 , 0 ,
ONE , 0 , 0 ,
ONE , 0 , 0
} ;
MATRIX light_mtx = {
ONE , 0 , 0 ,
0 , 0 , 0 ,
0 , 0 , 0
} ;
void loadModel ( const u_long * data , ps1mdl_t * mdl )
{
const char * bytes = ( const char * ) data ;
@ -168,6 +183,10 @@ void init(void)
loadModel ( mdl_shambler , & shamblerModel ) ;
loadSkin ( tim_shambler_f , tim_shambler_b , & shamblerSkin ) ;
InitGeom ( ) ;
gte_SetGeomOffset ( SCREENWIDTH > > 1 , SCREENHEIGHT > > 1 ) ;
gte_SetGeomScreen ( SCREENWIDTH > > 1 ) ; / / Screen depth for FOV control
/ / Set texture page for the entire drawing environment . Nice in some cases perhaps , but not what we need .
/ / draw [ 0 ] . tpage = getTPage ( playerFrontTex . mode & 0x3 , 0 , playerFrontTex . prect - > x , playerFrontTex . prect - > y ) ;
/ / draw [ 1 ] . tpage = getTPage ( playerFrontTex . mode & 0x3 , 0 , playerFrontTex . prect - > x , playerFrontTex . prect - > y ) ;
@ -326,10 +345,13 @@ static int fakeLight(const int *norm)
return lit ;
}
SVECTOR outPos ;
void drawModel ( ps1mdl_t * model , ps1skin_t * skin , int xOffset , int frameCounter )
{
ps1texture_t * tex ;
short u0 , u1 , u2 , uoffs , voffs ;
int p ;
int frameNum = frameCounter % model - > header - > frameCount ;
int vertOffs = frameNum * model - > header - > vertexCount ;
@ -343,20 +365,31 @@ void drawModel(ps1mdl_t *model, ps1skin_t *skin, int xOffset, int frameCounter)
ps1mdl_vertex_t * v1 = & model - > vertices [ tri - > vertexIndex [ 1 ] + vertOffs ] ;
ps1mdl_vertex_t * v2 = & model - > vertices [ tri - > vertexIndex [ 2 ] + vertOffs ] ;
/ / Normally you ' d have GTE do this but we ' re just going for a quick hack now
unsigned short depth = ( ( unsigned short ) v0 - > position [ 1 ] + ( unsigned short ) v1 - > position [ 1 ] + ( unsigned short ) v2 - > position [ 1 ] ) / 3 ;
if ( depth > = OTLEN )
/ / Swizzle the coordinates because Quake Z is up
SVECTOR pos0 = { v0 - > position [ 0 ] , - v0 - > position [ 2 ] , v0 - > position [ 1 ] } ;
SVECTOR pos1 = { v1 - > position [ 0 ] , - v1 - > position [ 2 ] , v1 - > position [ 1 ] } ;
SVECTOR pos2 = { v2 - > position [ 0 ] , - v2 - > position [ 2 ] , v2 - > position [ 1 ] } ;
gte_ldv3 ( & pos0 , & pos1 , & pos2 ) ;
gte_rtpt ( ) ; / / Rotation , Translation and Perspective triplet ( all three vertices at once )
/ / Normal clipping for backface culling
gte_nclip ( ) ;
gte_stopz ( & p ) ;
if ( p < 0 )
continue ;
/ / Average Z for depth sorting
gte_avsz3 ( ) ;
gte_stotz ( & p ) ;
unsigned short depth = p ; / / p > > 2 ;
if ( depth < 0 | | depth > = OTLEN )
continue ;
ps1mdl_texcoord_t * tc0 = & model - > texCoords [ tri - > vertexIndex [ 0 ] ] ;
ps1mdl_texcoord_t * tc1 = & model - > texCoords [ tri - > vertexIndex [ 1 ] ] ;
ps1mdl_texcoord_t * tc2 = & model - > texCoords [ tri - > vertexIndex [ 2 ] ] ;
/ / Calculate some Lambert shading based on a static light vector
int lit0 = fakeLight ( anorms [ v0 - > normalIndex ] ) ;
int lit1 = fakeLight ( anorms [ v1 - > normalIndex ] ) ;
int lit2 = fakeLight ( anorms [ v2 - > normalIndex ] ) ;
if ( tri - > frontFace )
{
u0 = tc0 - > u , u1 = tc1 - > u , u2 = tc2 - > u ;
@ -375,11 +408,25 @@ void drawModel(ps1mdl_t *model, ps1skin_t *skin, int xOffset, int frameCounter)
POLY_GT3 * poly = ( POLY_GT3 * ) nextpri ;
setPolyGT3 ( poly ) ;
setXY3 ( poly , xOffset + v0 - > position [ 0 ] , 240 - v0 - > position [ 2 ] , xOffset + v1 - > position [ 0 ] , 240 - v1 - > position [ 2 ] , xOffset + v2 - > position [ 0 ] , 240 - v2 - > position [ 2 ] ) ;
/ / Store transformed vertex coordinates in screen space
gte_stsxy0 ( & poly - > x0 ) ;
gte_stsxy1 ( & poly - > x1 ) ;
gte_stsxy2 ( & poly - > x2 ) ;
/ / Copy some values for on - screen debugging
outPos . vx = poly - > x0 ;
outPos . vy = poly - > y0 ;
outPos . vz = p ;
/ / Calculate vertex color based on normal
gte_ldrgb ( & poly - > r0 ) ;
gte_ldv3 ( anorms [ v0 - > normalIndex ] , anorms [ v1 - > normalIndex ] , anorms [ v2 - > normalIndex ] ) ;
gte_nct ( ) ;
gte_strgb3 ( & poly - > r0 , & poly - > r1 , & poly - > r2 ) ;
/ / Set texture parameters
setUV3 ( poly , uoffs + u0 , voffs + tc0 - > v , uoffs + u1 , voffs + tc1 - > v , uoffs + u2 , voffs + tc2 - > v ) ;
setRGB0 ( poly , lit0 , lit0 , lit0 ) ;
setRGB1 ( poly , lit1 , lit1 , lit1 ) ;
setRGB2 ( poly , lit2 , lit2 , lit2 ) ;
setClut ( poly , tex - > crect . x , tex - > crect . y ) ;
setTPage ( poly , tex - > mode & 0x3 , 0 , tex - > prect . x , tex - > prect . y ) ;
@ -392,30 +439,28 @@ void drawStuff(int counter)
{
ClearOTagR ( ot [ db ] , OTLEN ) ;
/ / Print the obligatory hello world and counter to show that the
/ / program isn ' t locking up to the last created text stream
FntPrint ( - 1 , " COUNTER=%d, SIN=%d \n " , counter , isin ( counter ) ) ;
FntPrint ( - 1 , " Image x %d y %d w %d h %d mode 0x%x \n " , playerSkin . front . prect . x , playerSkin . front . prect . y , playerSkin . front . prect . w , playerSkin . front . prect . h , playerSkin . front . mode ) ;
FntPrint ( - 1 , " Model: %d tris, %d verts \n " , playerModel . header - > triangleCount , playerModel . header - > vertexCount ) ;
FntPrint ( - 1 , " Trsf: (%d, %d, %d) \n " , outPos . vx , outPos . vy , outPos . vz ) ;
/ / Draw the last created text stream
FntFlush ( - 1 ) ;
drawModel ( & playerModel , & playerSkin , - 40 , counter > > 2 ) ;
drawModel ( & shamblerModel , & shamblerSkin , 80 , counter > > 2 ) ;
gte_SetBackColor ( 48 , 48 , 48 ) ; / / Ambient light color
gte_SetColorMatrix ( & color_mtx ) ; / / Light color and direction
/ / int r , g , b ;
/ / lerpcol ( 255 , 255 , 0 , 255 , 0 , 0 , ( icos ( counter * 32 ) + 4096 ) > > 1 , & r , & g , & b ) ;
/ / addTile ( 32 , 32 , 64 , 64 , r , g , b ) ;
MATRIX mtx , lmtx ;
RotMatrix ( & rot , & mtx ) ;
TransMatrix ( & mtx , & pos ) ;
/ / lerpcol ( 0 , 255 , 255 , 0 , 255 , 0 , ( icos ( counter * 24 + 512 ) + 4096 ) > > 1 , & r , & g , & b ) ;
/ / addTile ( 128 , 160 , 48 , 48 , r , g , b ) ;
MulMatrix0 ( & light_mtx , & mtx , & lmtx ) ;
/ / addColoredTriangle ( 260 , 140 , 220 , 220 , 300 , 220 , 0xFF0000 , 0x00FF00 , 0x0000FF , 0 ) ;
/ / addTexturedTriangle ( 260 , 40 , 220 , 120 , 300 , 120 , 0 , 94 , 74 , 124 , 58 , 1 , & playerSkin . front ) ;
/ / addTexturedSprite ( 20 , 140 , 80 , 80 , & playerSkin . front ) ;
/ / addTexturedSprite ( 80 , 40 , 154 , 114 , & shamblerSkin . front ) ;
gte_SetRotMatrix ( & mtx ) ;
gte_SetTransMatrix ( & mtx ) ;
gte_SetLightMatrix ( & lmtx ) ;
drawModel ( & playerModel , & playerSkin , - 40 , counter > > 2 ) ;
/ / drawModel ( & shamblerModel , & shamblerSkin , 80 , counter > > 2 ) ;
}
/ / Main function , program entrypoint