diff options
Diffstat (limited to 'Src/Winamp/plush')
-rw-r--r-- | Src/Winamp/plush/CAM.C | 52 | ||||
-rw-r--r-- | Src/Winamp/plush/CLIP.C | 255 | ||||
-rw-r--r-- | Src/Winamp/plush/LIGHT.C | 46 | ||||
-rw-r--r-- | Src/Winamp/plush/MAKE.C | 480 | ||||
-rw-r--r-- | Src/Winamp/plush/MAT.C | 453 | ||||
-rw-r--r-- | Src/Winamp/plush/MATH.C | 67 | ||||
-rw-r--r-- | Src/Winamp/plush/OBJ.C | 179 | ||||
-rw-r--r-- | Src/Winamp/plush/PF_PTEX.C | 459 | ||||
-rw-r--r-- | Src/Winamp/plush/PF_SOLID.C | 271 | ||||
-rw-r--r-- | Src/Winamp/plush/PF_TEX.C | 584 | ||||
-rw-r--r-- | Src/Winamp/plush/PF_TRANS.C | 263 | ||||
-rw-r--r-- | Src/Winamp/plush/PLUSH.C | 286 | ||||
-rw-r--r-- | Src/Winamp/plush/PLUSH.H | 720 | ||||
-rw-r--r-- | Src/Winamp/plush/PL_CONF.H | 45 | ||||
-rw-r--r-- | Src/Winamp/plush/PL_DEFS.H | 62 | ||||
-rw-r--r-- | Src/Winamp/plush/PL_TYPES.H | 162 | ||||
-rw-r--r-- | Src/Winamp/plush/PUTFACE.H | 54 | ||||
-rw-r--r-- | Src/Winamp/plush/READ_3DS.C | 244 | ||||
-rw-r--r-- | Src/Winamp/plush/READ_COB.C | 182 | ||||
-rw-r--r-- | Src/Winamp/plush/READ_JAW.C | 69 | ||||
-rw-r--r-- | Src/Winamp/plush/READ_PCX.C | 162 | ||||
-rw-r--r-- | Src/Winamp/plush/RENDER.C | 301 | ||||
-rw-r--r-- | Src/Winamp/plush/SPLINE.C | 49 | ||||
-rw-r--r-- | Src/Winamp/plush/TEXT.C | 123 |
24 files changed, 5568 insertions, 0 deletions
diff --git a/Src/Winamp/plush/CAM.C b/Src/Winamp/plush/CAM.C new file mode 100644 index 00000000..3d122a13 --- /dev/null +++ b/Src/Winamp/plush/CAM.C @@ -0,0 +1,52 @@ +/****************************************************************************** +Plush Version 1.2 +cam.c +Camera Control +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +void plCamDelete(pl_Cam *c) { + if (c) free(c); +} + +void plCamSetTarget(pl_Cam *c, pl_Float x, pl_Float y, pl_Float z) { + double dx, dy, dz; + dx = x - c->X; + dy = y - c->Y; + dz = z - c->Z; + c->Roll = 0; + if (dz > 0.0001f) { + c->Pan = (pl_Float) (-atan(dx/dz)*(180.0/PL_PI)); + dz /= cos(c->Pan*(PL_PI/180.0)); + c->Pitch = (pl_Float) (atan(dy/dz)*(180.0/PL_PI)); + } else if (dz < -0.0001f) { + c->Pan = (pl_Float) (180.0-atan(dx/dz)*(180.0/PL_PI)); + dz /= cos((c->Pan-180.0f)*(PL_PI/180.0)); + c->Pitch = (pl_Float) (-atan(dy/dz)*(180.0/PL_PI)); + } else { + c->Pan = 0.0f; + c->Pitch = -90.0f; + } +} + +pl_Cam *plCamCreate(pl_uInt sw, pl_uInt sh, pl_Float ar, pl_Float fov, + pl_uChar *fb, pl_ZBuffer *zb) { + pl_Cam *c; + c = malloc(sizeof(pl_Cam)); + if (!c) return 0; + memset(c,0,sizeof(pl_Cam)); + c->Fov = fov; + c->AspectRatio = ar; + c->ClipRight = c->ScreenWidth = sw; + c->ClipBottom = c->ScreenHeight = sh; + c->CenterX = sw>>1; + c->CenterY = sh>>1; + c->ClipBack = 8.0e30f; + c->frameBuffer = fb; + c->zBuffer = zb; + c->Sort = 1; + if (zb) c->Sort = 0; + return (c); +} diff --git a/Src/Winamp/plush/CLIP.C b/Src/Winamp/plush/CLIP.C new file mode 100644 index 00000000..5cbd06fe --- /dev/null +++ b/Src/Winamp/plush/CLIP.C @@ -0,0 +1,255 @@ +/****************************************************************************** +Plush Version 1.2 +clip.c +3D Frustum Clipping +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +#define NUM_CLIP_PLANES 5 + +typedef struct +{ + pl_Vertex newVertices[8]; + double Shades[8]; + double MappingU[8]; + double MappingV[8]; + double eMappingU[8]; + double eMappingV[8]; +} _clipInfo; + + +static _clipInfo m_cl[2]; + + +static double m_clipPlanes[NUM_CLIP_PLANES][4]; +static pl_Cam *m_cam; +static pl_sInt32 m_cx, m_cy; +static double m_fov; +static double m_adj_asp; + +static void _FindNormal(double x2, double x3, + double y2, double y3, + double zv, + double *res); + + /* Returns: 0 if nothing gets in, 1 or 2 if pout1 & pout2 get in */ +static pl_uInt _ClipToPlane(pl_uInt numVerts, double *plane); + +void plClipSetFrustum(pl_Cam *cam) { + m_adj_asp = 1.0 / cam->AspectRatio; + m_fov = plMin(plMax(cam->Fov,1.0),179.0); + m_fov = (1.0/tan(m_fov*(PL_PI/360.0)))*(double) (cam->ClipRight-cam->ClipLeft); + m_cx = cam->CenterX<<20; + m_cy = cam->CenterY<<20; + m_cam = cam; + memset(m_clipPlanes,0,sizeof(m_clipPlanes)); + + /* Back */ + m_clipPlanes[0][2] = -1.0; + m_clipPlanes[0][3] = -cam->ClipBack; + + /* Left */ + m_clipPlanes[1][3] = 0.00000001; + if (cam->ClipLeft == cam->CenterX) { + m_clipPlanes[1][0] = 1.0; + } + else _FindNormal(-100,-100, + 100, -100, + m_fov*-100.0/(cam->ClipLeft-cam->CenterX), + m_clipPlanes[1]); + if (cam->ClipLeft > cam->CenterX) { + m_clipPlanes[1][0] = -m_clipPlanes[1][0]; + m_clipPlanes[1][1] = -m_clipPlanes[1][1]; + m_clipPlanes[1][2] = -m_clipPlanes[1][2]; + } + + /* Right */ + m_clipPlanes[2][3] = 0.00000001; + if (cam->ClipRight == cam->CenterX) { + m_clipPlanes[2][0] = -1.0; + } + else _FindNormal(100,100, + -100, 100, + m_fov*100.0/(cam->ClipRight-cam->CenterX), + m_clipPlanes[2]); + if (cam->ClipRight < cam->CenterX) { + m_clipPlanes[2][0] = -m_clipPlanes[2][0]; + m_clipPlanes[2][1] = -m_clipPlanes[2][1]; + m_clipPlanes[2][2] = -m_clipPlanes[2][2]; + } + /* Top */ + m_clipPlanes[3][3] = 0.00000001; + if (cam->ClipTop == cam->CenterY) { + m_clipPlanes[3][1] = -1.0; + } else _FindNormal(100, -100, + 100, 100, + m_fov*m_adj_asp*100.0/(cam->CenterY-cam->ClipTop), + m_clipPlanes[3]); + if (cam->ClipTop > cam->CenterY) { + m_clipPlanes[3][0] = -m_clipPlanes[3][0]; + m_clipPlanes[3][1] = -m_clipPlanes[3][1]; + m_clipPlanes[3][2] = -m_clipPlanes[3][2]; + } + + /* Bottom */ + m_clipPlanes[4][3] = 0.00000001; + if (cam->ClipBottom == cam->CenterY) { + m_clipPlanes[4][1] = 1.0; + } else _FindNormal(-100, 100, + -100, -100, + m_fov*m_adj_asp*-100.0/(cam->CenterY-cam->ClipBottom), + m_clipPlanes[4]); + if (cam->ClipBottom < cam->CenterY) { + m_clipPlanes[4][0] = -m_clipPlanes[4][0]; + m_clipPlanes[4][1] = -m_clipPlanes[4][1]; + m_clipPlanes[4][2] = -m_clipPlanes[4][2]; + } +} + + +void plClipRenderFace(pl_Face *face) { + pl_uInt k, a, w, numVerts, q; + double tmp, tmp2; + pl_Face newface; + + for (a = 0; a < 3; a ++) { + m_cl[0].newVertices[a] = *(face->Vertices[a]); + m_cl[0].Shades[a] = face->Shades[a]; + m_cl[0].MappingU[a] = face->MappingU[a]; + m_cl[0].MappingV[a] = face->MappingV[a]; + m_cl[0].eMappingU[a] = face->eMappingU[a]; + m_cl[0].eMappingV[a] = face->eMappingV[a]; + } + + numVerts = 3; + q = 0; + a = (m_clipPlanes[0][3] < 0.0 ? 0 : 1); + while (a < NUM_CLIP_PLANES && numVerts > 2) + { + numVerts = _ClipToPlane(numVerts, m_clipPlanes[a]); + memcpy(&m_cl[0],&m_cl[1],sizeof(m_cl)/2); + a++; + } + if (numVerts > 2) { + memcpy(&newface,face,sizeof(pl_Face)); + for (k = 2; k < numVerts; k ++) { + newface.fShade = plMax(0,plMin(face->fShade,1)); + for (a = 0; a < 3; a ++) { + if (a == 0) w = 0; + else w = a+(k-2); + newface.Vertices[a] = m_cl[0].newVertices+w; + newface.Shades[a] = (pl_Float) m_cl[0].Shades[w]; + newface.MappingU[a] = (pl_sInt32)m_cl[0].MappingU[w]; + newface.MappingV[a] = (pl_sInt32)m_cl[0].MappingV[w]; + newface.eMappingU[a] = (pl_sInt32)m_cl[0].eMappingU[w]; + newface.eMappingV[a] = (pl_sInt32)m_cl[0].eMappingV[w]; + newface.Scrz[a] = 1.0f/newface.Vertices[a]->xformedz; + tmp2 = m_fov * newface.Scrz[a]; + tmp = tmp2*newface.Vertices[a]->xformedx; + tmp2 *= newface.Vertices[a]->xformedy; + newface.Scrx[a] = m_cx + ((pl_sInt32)((tmp*(float) (1<<20)))); + newface.Scry[a] = m_cy - ((pl_sInt32)((tmp2*m_adj_asp*(float) (1<<20)))); + } + newface.Material->_PutFace(m_cam,&newface); + plRender_TriStats[3] ++; + } + plRender_TriStats[2] ++; + } +} + +pl_sInt plClipNeeded(pl_Face *face) { + double dr,dl,db,dt; + double f; + dr = (m_cam->ClipRight-m_cam->CenterX); + dl = (m_cam->ClipLeft-m_cam->CenterX); + db = (m_cam->ClipBottom-m_cam->CenterY); + dt = (m_cam->ClipTop-m_cam->CenterY); + f = m_fov*m_adj_asp; + return ((m_cam->ClipBack <= 0.0 || + face->Vertices[0]->xformedz <= m_cam->ClipBack || + face->Vertices[1]->xformedz <= m_cam->ClipBack || + face->Vertices[2]->xformedz <= m_cam->ClipBack) && + (face->Vertices[0]->xformedz >= 0 || + face->Vertices[1]->xformedz >= 0 || + face->Vertices[2]->xformedz >= 0) && + (face->Vertices[0]->xformedx*m_fov<=dr*face->Vertices[0]->xformedz || + face->Vertices[1]->xformedx*m_fov<=dr*face->Vertices[1]->xformedz || + face->Vertices[2]->xformedx*m_fov<=dr*face->Vertices[2]->xformedz) && + (face->Vertices[0]->xformedx*m_fov>=dl*face->Vertices[0]->xformedz || + face->Vertices[1]->xformedx*m_fov>=dl*face->Vertices[1]->xformedz || + face->Vertices[2]->xformedx*m_fov>=dl*face->Vertices[2]->xformedz) && + (face->Vertices[0]->xformedy*f<=db*face->Vertices[0]->xformedz || + face->Vertices[1]->xformedy*f<=db*face->Vertices[1]->xformedz || + face->Vertices[2]->xformedy*f<=db*face->Vertices[2]->xformedz) && + (face->Vertices[0]->xformedy*f>=dt*face->Vertices[0]->xformedz || + face->Vertices[1]->xformedy*f>=dt*face->Vertices[1]->xformedz || + face->Vertices[2]->xformedy*f>=dt*face->Vertices[2]->xformedz)); +} + + + +static void _FindNormal(double x2, double x3,double y2, double y3, + double zv, double *res) { + res[0] = zv*(y2-y3); + res[1] = zv*(x3-x2); + res[2] = x2*y3 - y2*x3; +} + + /* Returns: 0 if nothing gets in, 1 or 2 if pout1 & pout2 get in */ +static pl_uInt _ClipToPlane(pl_uInt numVerts, double *plane) +{ + pl_uInt i, nextvert, curin, nextin; + double curdot, nextdot, scale; + pl_uInt invert, outvert; + invert = 0; + outvert = 0; + curdot = m_cl[0].newVertices[0].xformedx*plane[0] + + m_cl[0].newVertices[0].xformedy*plane[1] + + m_cl[0].newVertices[0].xformedz*plane[2]; + curin = (curdot >= plane[3]); + + for (i=0 ; i < numVerts; i++) { + nextvert = (i + 1) % numVerts; + if (curin) { + m_cl[1].Shades[outvert] = m_cl[0].Shades[invert]; + m_cl[1].MappingU[outvert] = m_cl[0].MappingU[invert]; + m_cl[1].MappingV[outvert] = m_cl[0].MappingV[invert]; + m_cl[1].eMappingU[outvert] = m_cl[0].eMappingU[invert]; + m_cl[1].eMappingV[outvert] = m_cl[0].eMappingV[invert]; + m_cl[1].newVertices[outvert++] = m_cl[0].newVertices[invert]; + } + nextdot = m_cl[0].newVertices[nextvert].xformedx*plane[0] + + m_cl[0].newVertices[nextvert].xformedy*plane[1] + + m_cl[0].newVertices[nextvert].xformedz*plane[2]; + nextin = (nextdot >= plane[3]); + if (curin != nextin) { + scale = (plane[3] - curdot) / (nextdot - curdot); + m_cl[1].newVertices[outvert].xformedx = (pl_Float) (m_cl[0].newVertices[invert].xformedx + + (m_cl[0].newVertices[nextvert].xformedx - m_cl[0].newVertices[invert].xformedx) + * scale); + m_cl[1].newVertices[outvert].xformedy = (pl_Float) (m_cl[0].newVertices[invert].xformedy + + (m_cl[0].newVertices[nextvert].xformedy - m_cl[0].newVertices[invert].xformedy) + * scale); + m_cl[1].newVertices[outvert].xformedz = (pl_Float) (m_cl[0].newVertices[invert].xformedz + + (m_cl[0].newVertices[nextvert].xformedz - m_cl[0].newVertices[invert].xformedz) + * scale); + m_cl[1].Shades[outvert] = m_cl[0].Shades[invert] + + (m_cl[0].Shades[nextvert] - m_cl[0].Shades[invert]) * scale; + m_cl[1].MappingU[outvert] = m_cl[0].MappingU[invert] + + (m_cl[0].MappingU[nextvert] - m_cl[0].MappingU[invert]) * scale; + m_cl[1].MappingV[outvert] = m_cl[0].MappingV[invert] + + (m_cl[0].MappingV[nextvert] - m_cl[0].MappingV[invert]) * scale; + m_cl[1].eMappingU[outvert] = m_cl[0].eMappingU[invert] + + (m_cl[0].eMappingU[nextvert] - m_cl[0].eMappingU[invert]) * scale; + m_cl[1].eMappingV[outvert] = m_cl[0].eMappingV[invert] + + (m_cl[0].eMappingV[nextvert] - m_cl[0].eMappingV[invert]) * scale; + outvert++; + } + curdot = nextdot; + curin = nextin; + invert++; + } + return outvert; +} diff --git a/Src/Winamp/plush/LIGHT.C b/Src/Winamp/plush/LIGHT.C new file mode 100644 index 00000000..69f3b79a --- /dev/null +++ b/Src/Winamp/plush/LIGHT.C @@ -0,0 +1,46 @@ +/****************************************************************************** +Plush Version 1.2 +light.c +Light Control +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +pl_Light *plLightSet(pl_Light *light, pl_uChar mode, pl_Float x, pl_Float y, + pl_Float z, pl_Float intensity, pl_Float halfDist) { + pl_Float m[16], m2[16]; + light->Type = mode; + light->Intensity = intensity; + light->HalfDistSquared = halfDist*halfDist; + switch (mode) { + case PL_LIGHT_VECTOR: + plMatrixRotate(m,1,x); + plMatrixRotate(m2,2,y); + plMatrixMultiply(m,m2); + plMatrixRotate(m2,3,z); + plMatrixMultiply(m,m2); + plMatrixApply(m,0.0,0.0,-1.0,&light->Xp, &light->Yp, &light->Zp); + break; + case PL_LIGHT_POINT_ANGLE: + case PL_LIGHT_POINT_DISTANCE: + case PL_LIGHT_POINT: + light->Xp = x; + light->Yp = y; + light->Zp = z; + break; + } + return light; +} + +pl_Light *plLightCreate() { + pl_Light *l; + l = malloc(sizeof(pl_Light)); + if (!l) return 0; + memset(l,0,sizeof(pl_Light)); + return (l); +} + +void plLightDelete(pl_Light *l) { + if (l) free(l); +} diff --git a/Src/Winamp/plush/MAKE.C b/Src/Winamp/plush/MAKE.C new file mode 100644 index 00000000..9f59a1c2 --- /dev/null +++ b/Src/Winamp/plush/MAKE.C @@ -0,0 +1,480 @@ +/****************************************************************************** +Plush Version 1.2 +make.c +Object Primitives +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************* + Notes: + Most of these routines are highly unoptimized. + They could all use some work, such as more capable divisions (Box is + most notable), etc... The mapping coordinates are all set up nicely, + though. +******************************************************************************/ + +#include "plush.h" + +pl_Obj *plMakeTorus(pl_Float r1, pl_Float r2, pl_uInt divrot, pl_uInt divrad, + pl_Mat *m) { + pl_Obj *o; + pl_Vertex *v; + pl_Face *f; + pl_uInt x, y; + double ravg, rt, a, da, al, dal; + pl_sInt32 U,V,dU,dV; + if (divrot < 3) divrot = 3; + if (divrad < 3) divrad = 3; + ravg = (r1+r2)*0.5; + rt = (r2-r1)*0.5; + o = plObjCreate(divrad*divrot,divrad*divrot*2); + if (!o) return 0; + v = o->Vertices; + a = 0.0; + da = 2*PL_PI/divrot; + for (y = 0; y < divrot; y ++) { + al = 0.0; + dal = 2*PL_PI/divrad; + for (x = 0; x < divrad; x ++) { + v->x = (pl_Float) (cos((double) a)*(ravg + cos((double) al)*rt)); + v->z = (pl_Float) (sin((double) a)*(ravg + cos((double) al)*rt)); + v->y = (pl_Float) (sin((double) al)*rt); + v++; + al += dal; + } + a += da; + } + v = o->Vertices; + f = o->Faces; + dV = 65535/divrad; + dU = 65535/divrot; + U = 0; + for (y = 0; y < divrot; y ++) { + V = -32768; + for (x = 0; x < divrad; x ++) { + f->Vertices[0] = v+x+y*divrad; + f->MappingU[0] = U; + f->MappingV[0] = V; + f->Vertices[1] = v+(x+1==divrad?0:x+1)+y*divrad; + f->MappingU[1] = U; + f->MappingV[1] = V+dV; + f->Vertices[2] = v+x+(y+1==divrot?0:(y+1)*divrad); + f->MappingU[2] = U+dU; + f->MappingV[2] = V; + f->Material = m; + f++; + f->Vertices[0] = v+x+(y+1==divrot?0:(y+1)*divrad); + f->MappingU[0] = U+dU; + f->MappingV[0] = V; + f->Vertices[1] = v+(x+1==divrad?0:x+1)+y*divrad; + f->MappingU[1] = U; + f->MappingV[1] = V+dV; + f->Vertices[2] = v+(x+1==divrad?0:x+1)+(y+1==divrot?0:(y+1)*divrad); + f->MappingU[2] = U+dU; + f->MappingV[2] = V+dV; + f->Material = m; + f++; + V += dV; + } + U += dU; + } + plObjCalcNormals(o); + return (o); +} + +pl_Obj *plMakeSphere(pl_Float r, pl_uInt divr, pl_uInt divh, pl_Mat *m) { + pl_Obj *o; + pl_Vertex *v; + pl_Face *f; + pl_uInt x, y; + double a, da, yp, ya, yda, yf; + pl_sInt32 U,V,dU,dV; + if (divh < 3) divh = 3; + if (divr < 3) divr = 3; + o = plObjCreate(2+(divh-2)*(divr),2*divr+(divh-3)*divr*2); + if (!o) return 0; + v = o->Vertices; + v->x = v->z = 0.0; v->y = r; v++; + v->x = v->z = 0.0; v->y = -r; v++; + ya = 0.0; + yda = PL_PI/(divh-1); + da = (PL_PI*2.0)/divr; + for (y = 0; y < divh - 2; y ++) { + ya += yda; + yp = cos((double) ya)*r; + yf = sin((double) ya)*r; + a = 0.0; + for (x = 0; x < divr; x ++) { + v->y = (pl_Float) yp; + v->x = (pl_Float) (cos((double) a)*yf); + v->z = (pl_Float) (sin((double) a)*yf); + v++; + a += da; + } + } + f = o->Faces; + v = o->Vertices + 2; + a = 0.0; + U = 0; + dU = 65535/divr; + dV = V = 65535/divh; + for (x = 0; x < divr; x ++) { + f->Vertices[0] = o->Vertices; + f->Vertices[1] = v + (x+1==divr ? 0 : x+1); + f->Vertices[2] = v + x; + f->MappingU[0] = U; + f->MappingV[0] = 0; + f->MappingU[1] = U+dU; + f->MappingV[1] = V; + f->MappingU[2] = U; + f->MappingV[2] = V; + f->Material = m; + f++; + U += dU; + } + da = 1.0/(divr+1); + v = o->Vertices + 2; + for (x = 0; x < (divh-3); x ++) { + U = 0; + for (y = 0; y < divr; y ++) { + f->Vertices[0] = v+y; + f->Vertices[1] = v+divr+(y+1==divr?0:y+1); + f->Vertices[2] = v+y+divr; + f->MappingU[0] = U; + f->MappingV[0] = V; + f->MappingU[1] = U+dU; + f->MappingV[1] = V+dV; + f->MappingU[2] = U; + f->MappingV[2] = V+dV; + f->Material = m; f++; + f->Vertices[0] = v+y; + f->Vertices[1] = v+(y+1==divr?0:y+1); + f->Vertices[2] = v+(y+1==divr?0:y+1)+divr; + f->MappingU[0] = U; + f->MappingV[0] = V; + f->MappingU[1] = U+dU; + f->MappingV[1] = V; + f->MappingU[2] = U+dU; + f->MappingV[2] = V+dV; + f->Material = m; f++; + U += dU; + } + V += dV; + v += divr; + } + v = o->Vertices + o->NumVertices - divr; + U = 0; + for (x = 0; x < divr; x ++) { + f->Vertices[0] = o->Vertices + 1; + f->Vertices[1] = v + x; + f->Vertices[2] = v + (x+1==divr ? 0 : x+1); + f->MappingU[0] = U; + f->MappingV[0] = 65535; + f->MappingU[1] = U; + f->MappingV[1] = V; + f->MappingU[2] = U+dU; + f->MappingV[2] = V; + f->Material = m; + f++; + U += dU; + } + plObjCalcNormals(o); + return (o); +} + +pl_Obj *plMakeCylinder(pl_Float r, pl_Float h, pl_uInt divr, pl_Bool captop, + pl_Bool capbottom, pl_Mat *m) { + pl_Obj *o; + pl_Vertex *v, *topverts, *bottomverts, *topcapvert=0, *bottomcapvert=0; + pl_Face *f; + pl_uInt32 i; + double a, da; + if (divr < 3) divr = 3; + o = plObjCreate(divr*2+((divr==3)?0:(captop?1:0)+(capbottom?1:0)), + divr*2+(divr==3 ? (captop ? 1 : 0) + (capbottom ? 1 : 0) : + (captop ? divr : 0) + (capbottom ? divr : 0))); + if (!o) return 0; + a = 0.0; + da = (2.0*PL_PI)/divr; + v = o->Vertices; + topverts = v; + for (i = 0; i < divr; i ++) { + v->y = h/2.0f; + v->x = (pl_Float) (r*cos((double) a)); + v->z = (pl_Float)(r*sin(a)); + v->xformedx = (pl_Float) (32768.0 + (32768.0*cos((double) a))); // temp + v->xformedy = (pl_Float) (32768.0 + (32768.0*sin((double) a))); // use xf + v++; + a += da; + } + bottomverts = v; + a = 0.0; + for (i = 0; i < divr; i ++) { + v->y = -h/2.0f; + v->x = (pl_Float) (r*cos((double) a)); + v->z = (pl_Float) (r*sin(a)); + v->xformedx = (pl_Float) (32768.0 + (32768.0*cos((double) a))); + v->xformedy = (pl_Float) (32768.0 + (32768.0*sin((double) a))); + v++; a += da; + } + if (captop && divr != 3) { + topcapvert = v; + v->y = h / 2.0f; + v->x = v->z = 0.0f; + v++; + } + if (capbottom && divr != 3) { + bottomcapvert = v; + v->y = -h / 2.0f; + v->x = v->z = 0.0f; + v++; + } + f = o->Faces; + for (i = 0; i < divr; i ++) { + f->Vertices[0] = bottomverts + i; + f->Vertices[1] = topverts + i; + f->Vertices[2] = bottomverts + (i == divr-1 ? 0 : i+1); + f->MappingV[0] = f->MappingV[2] = 65535; f->MappingV[1] = 0; + f->MappingU[0] = f->MappingU[1] = (i<<16)/divr; + f->MappingU[2] = ((i+1)<<16)/divr; + f->Material = m; f++; + f->Vertices[0] = bottomverts + (i == divr-1 ? 0 : i+1); + f->Vertices[1] = topverts + i; + f->Vertices[2] = topverts + (i == divr-1 ? 0 : i+1); + f->MappingV[1] = f->MappingV[2] = 0; f->MappingV[0] = 65535; + f->MappingU[0] = f->MappingU[2] = ((i+1)<<16)/divr; + f->MappingU[1] = (i<<16)/divr; + f->Material = m; f++; + } + if (captop) { + if (divr == 3) { + f->Vertices[0] = topverts + 0; + f->Vertices[1] = topverts + 2; + f->Vertices[2] = topverts + 1; + f->MappingU[0] = (pl_sInt32) topverts[0].xformedx; + f->MappingV[0] = (pl_sInt32) topverts[0].xformedy; + f->MappingU[1] = (pl_sInt32) topverts[1].xformedx; + f->MappingV[1] = (pl_sInt32) topverts[1].xformedy; + f->MappingU[2] = (pl_sInt32) topverts[2].xformedx; + f->MappingV[2] = (pl_sInt32) topverts[2].xformedy; + f->Material = m; f++; + } else { + for (i = 0; i < divr; i ++) { + f->Vertices[0] = topverts + (i == divr-1 ? 0 : i + 1); + f->Vertices[1] = topverts + i; + f->Vertices[2] = topcapvert; + f->MappingU[0] = (pl_sInt32) topverts[(i==divr-1?0:i+1)].xformedx; + f->MappingV[0] = (pl_sInt32) topverts[(i==divr-1?0:i+1)].xformedy; + f->MappingU[1] = (pl_sInt32) topverts[i].xformedx; + f->MappingV[1] = (pl_sInt32) topverts[i].xformedy; + f->MappingU[2] = f->MappingV[2] = 32768; + f->Material = m; f++; + } + } + } + if (capbottom) { + if (divr == 3) { + f->Vertices[0] = bottomverts + 0; + f->Vertices[1] = bottomverts + 1; + f->Vertices[2] = bottomverts + 2; + f->MappingU[0] = (pl_sInt32) bottomverts[0].xformedx; + f->MappingV[0] = (pl_sInt32) bottomverts[0].xformedy; + f->MappingU[1] = (pl_sInt32) bottomverts[1].xformedx; + f->MappingV[1] = (pl_sInt32) bottomverts[1].xformedy; + f->MappingU[2] = (pl_sInt32) bottomverts[2].xformedx; + f->MappingV[2] = (pl_sInt32) bottomverts[2].xformedy; + f->Material = m; f++; + } else { + for (i = 0; i < divr; i ++) { + f->Vertices[0] = bottomverts + i; + f->Vertices[1] = bottomverts + (i == divr-1 ? 0 : i + 1); + f->Vertices[2] = bottomcapvert; + f->MappingU[0] = (pl_sInt32) bottomverts[i].xformedx; + f->MappingV[0] = (pl_sInt32) bottomverts[i].xformedy; + f->MappingU[1] = (pl_sInt32) bottomverts[(i==divr-1?0:i+1)].xformedx; + f->MappingV[1] = (pl_sInt32) bottomverts[(i==divr-1?0:i+1)].xformedy; + f->MappingU[2] = f->MappingV[2] = 32768; + f->Material = m; f++; + } + } + } + plObjCalcNormals(o); + return (o); +} + +pl_Obj *plMakeCone(pl_Float r, pl_Float h, pl_uInt div, + pl_Bool cap, pl_Mat *m) { + pl_Obj *o; + pl_Vertex *v; + pl_Face *f; + pl_uInt32 i; + double a, da; + if (div < 3) div = 3; + o = plObjCreate(div + (div == 3 ? 1 : (cap ? 2 : 1)), + div + (div == 3 ? 1 : (cap ? div : 0))); + if (!o) return 0; + v = o->Vertices; + v->x = v->z = 0; v->y = h/2; + v->xformedx = 1<<15; + v->xformedy = 1<<15; + v++; + a = 0.0; + da = (2.0*PL_PI)/div; + for (i = 1; i <= div; i ++) { + v->y = h/-2.0f; + v->x = (pl_Float) (r*cos((double) a)); + v->z = (pl_Float) (r*sin((double) a)); + v->xformedx = (pl_Float) (32768.0 + (cos((double) a)*32768.0)); + v->xformedy = (pl_Float) (32768.0 + (sin((double) a)*32768.0)); + a += da; + v++; + } + if (cap && div != 3) { + v->y = h / -2.0f; + v->x = v->z = 0.0f; + v->xformedx = (pl_Float) (1<<15); + v->xformedy = (pl_Float) (1<<15); + v++; + } + f = o->Faces; + for (i = 1; i <= div; i ++) { + f->Vertices[0] = o->Vertices; + f->Vertices[1] = o->Vertices + (i == div ? 1 : i + 1); + f->Vertices[2] = o->Vertices + i; + f->MappingU[0] = (pl_sInt32) o->Vertices[0].xformedx; + f->MappingV[0] = (pl_sInt32) o->Vertices[0].xformedy; + f->MappingU[1] = (pl_sInt32) o->Vertices[(i==div?1:i+1)].xformedx; + f->MappingV[1] = (pl_sInt32) o->Vertices[(i==div?1:i+1)].xformedy; + f->MappingU[2] = (pl_sInt32) o->Vertices[i].xformedx; + f->MappingV[2] = (pl_sInt32) o->Vertices[i].xformedy; + f->Material = m; + f++; + } + if (cap) { + if (div == 3) { + f->Vertices[0] = o->Vertices + 1; + f->Vertices[1] = o->Vertices + 2; + f->Vertices[2] = o->Vertices + 3; + f->MappingU[0] = (pl_sInt32) o->Vertices[1].xformedx; + f->MappingV[0] = (pl_sInt32) o->Vertices[1].xformedy; + f->MappingU[1] = (pl_sInt32) o->Vertices[2].xformedx; + f->MappingV[1] = (pl_sInt32) o->Vertices[2].xformedy; + f->MappingU[2] = (pl_sInt32) o->Vertices[3].xformedx; + f->MappingV[2] = (pl_sInt32) o->Vertices[3].xformedy; + f->Material = m; + f++; + } else { + for (i = 1; i <= div; i ++) { + f->Vertices[0] = o->Vertices + div + 1; + f->Vertices[1] = o->Vertices + i; + f->Vertices[2] = o->Vertices + (i==div ? 1 : i+1); + f->MappingU[0] = (pl_sInt32) o->Vertices[div+1].xformedx; + f->MappingV[0] = (pl_sInt32) o->Vertices[div+1].xformedy; + f->MappingU[1] = (pl_sInt32) o->Vertices[i].xformedx; + f->MappingV[1] = (pl_sInt32) o->Vertices[i].xformedy; + f->MappingU[2] = (pl_sInt32) o->Vertices[i==div?1:i+1].xformedx; + f->MappingV[2] = (pl_sInt32) o->Vertices[i==div?1:i+1].xformedy; + f->Material = m; + f++; + } + } + } + plObjCalcNormals(o); + return (o); +} + +static pl_uChar verts[6*6] = { + 0,4,1, 1,4,5, 0,1,2, 3,2,1, 2,3,6, 3,7,6, + 6,7,4, 4,7,5, 1,7,3, 7,1,5, 2,6,0, 4,0,6 +}; +static pl_uChar map[24*2*3] = { + 1,0, 1,1, 0,0, 0,0, 1,1, 0,1, + 0,0, 1,0, 0,1, 1,1, 0,1, 1,0, + 0,0, 1,0, 0,1, 1,0, 1,1, 0,1, + 0,0, 1,0, 0,1, 0,1, 1,0, 1,1, + 1,0, 0,1, 0,0, 0,1, 1,0, 1,1, + 1,0, 1,1, 0,0, 0,1, 0,0, 1,1 +}; + + +pl_Obj *plMakeBox(pl_Float w, pl_Float d, pl_Float h, pl_Mat *m) { + pl_uChar *mm = map; + pl_uChar *vv = verts; + pl_Obj *o; + pl_Vertex *v; + pl_Face *f; + pl_uInt x; + o = plObjCreate(8,12); + if (!o) return 0; + v = o->Vertices; + v->x = -w/2; v->y = h/2; v->z = d/2; v++; + v->x = w/2; v->y = h/2; v->z = d/2; v++; + v->x = -w/2; v->y = h/2; v->z = -d/2; v++; + v->x = w/2; v->y = h/2; v->z = -d/2; v++; + v->x = -w/2; v->y = -h/2; v->z = d/2; v++; + v->x = w/2; v->y = -h/2; v->z = d/2; v++; + v->x = -w/2; v->y = -h/2; v->z = -d/2; v++; + v->x = w/2; v->y = -h/2; v->z = -d/2; v++; + f = o->Faces; + for (x = 0; x < 12; x ++) { + f->Vertices[0] = o->Vertices + *vv++; + f->Vertices[1] = o->Vertices + *vv++; + f->Vertices[2] = o->Vertices + *vv++; + f->MappingU[0] = (pl_sInt32) ((double)*mm++ * 65535.0); + f->MappingV[0] = (pl_sInt32) ((double)*mm++ * 65535.0); + f->MappingU[1] = (pl_sInt32) ((double)*mm++ * 65535.0); + f->MappingV[1] = (pl_sInt32) ((double)*mm++ * 65535.0); + f->MappingU[2] = (pl_sInt32) ((double)*mm++ * 65535.0); + f->MappingV[2] = (pl_sInt32) ((double)*mm++ * 65535.0); + f->Material = m; + f++; + } + + plObjCalcNormals(o); + return (o); +} + +pl_Obj *plMakePlane(pl_Float w, pl_Float d, pl_uInt res, pl_Mat *m) { + pl_Obj *o; + pl_Vertex *v; + pl_Face *f; + pl_uInt x, y; + o = plObjCreate((res+1)*(res+1),res*res*2); + if (!o) return 0; + v = o->Vertices; + for (y = 0; y <= res; y ++) { + for (x = 0; x <= res; x ++) { + v->y = 0; + v->x = ((x*w)/res) - w/2; + v->z = ((y*d)/res) - d/2; + v++; + } + } + f = o->Faces; + for (y = 0; y < res; y ++) { + for (x = 0; x < res; x ++) { + f->Vertices[0] = o->Vertices + x+(y*(res+1)); + f->MappingU[0] = (x<<16)/res; + f->MappingV[0] = (y<<16)/res; + f->Vertices[2] = o->Vertices + x+1+(y*(res+1)); + f->MappingU[2] = ((x+1)<<16)/res; + f->MappingV[2] = (y<<16)/res; + f->Vertices[1] = o->Vertices + x+((y+1)*(res+1)); + f->MappingU[1] = (x<<16)/res; + f->MappingV[1] = ((y+1)<<16)/res; + f->Material = m; + f++; + f->Vertices[0] = o->Vertices + x+((y+1)*(res+1)); + f->MappingU[0] = (x<<16)/res; + f->MappingV[0] = ((y+1)<<16)/res; + f->Vertices[2] = o->Vertices + x+1+(y*(res+1)); + f->MappingU[2] = ((x+1)<<16)/res; + f->MappingV[2] = (y<<16)/res; + f->Vertices[1] = o->Vertices + x+1+((y+1)*(res+1)); + f->MappingU[1] = ((x+1)<<16)/res; + f->MappingV[1] = ((y+1)<<16)/res; + f->Material = m; + f++; + } + } + plObjCalcNormals(o); + return (o); +} diff --git a/Src/Winamp/plush/MAT.C b/Src/Winamp/plush/MAT.C new file mode 100644 index 00000000..801e8d34 --- /dev/null +++ b/Src/Winamp/plush/MAT.C @@ -0,0 +1,453 @@ +/****************************************************************************** +Plush Version 1.2 +mat.c +Material Control +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +static void _plGenerateSinglePalette(pl_Mat *); +static void _plGeneratePhongPalette(pl_Mat *); +static void _plGenerateTextureEnvPalette(pl_Mat *); +static void _plGenerateTexturePalette(pl_Mat *, pl_Texture *); +static void _plGeneratePhongTexturePalette(pl_Mat *, pl_Texture *); +static void _plGeneratePhongTransparentPalette(pl_Mat *m); +static void _plGenerateTransparentPalette(pl_Mat *); +static void _plSetMaterialPutFace(pl_Mat *m); +static void _plMatSetupTransparent(pl_Mat *m, pl_uChar *pal); + +pl_Mat *plMatCreate() { + pl_Mat *m; + m = (pl_Mat *) malloc(sizeof(pl_Mat)); + if (!m) return 0; + memset(m,0,sizeof(pl_Mat)); + m->EnvScaling = 1.0f; + m->TexScaling = 1.0f; + m->Ambient[0] = m->Ambient[1] = m->Ambient[2] = 0; + m->Diffuse[0] = m->Diffuse[1] = m->Diffuse[2] = 128; + m->Specular[0] = m->Specular[1] = m->Specular[2] = 128; + m->Shininess = 4; + m->NumGradients = 32; + m->FadeDist = 1000.0; + m->zBufferable = 1; + return m; +} + +void plMatDelete(pl_Mat *m) { + if (m) { + if (m->_ReMapTable) free(m->_ReMapTable); + if (m->_RequestedColors) free(m->_RequestedColors); + if (m->_AddTable) free(m->_AddTable); + free(m); + } +} + +void plMatInit(pl_Mat *m) { + if (m->Shininess < 1) m->Shininess = 1; + m->_ft = ((m->Environment ? PL_FILL_ENVIRONMENT : 0) | + (m->Texture ? PL_FILL_TEXTURE : 0)); + m->_st = m->ShadeType; + + if (m->Transparent) m->_ft = PL_FILL_TRANSPARENT; + + if (m->_ft == (PL_FILL_TEXTURE|PL_FILL_ENVIRONMENT)) + m->_st = PL_SHADE_NONE; + + if (m->_ft == PL_FILL_SOLID) { + if (m->_st == PL_SHADE_NONE) _plGenerateSinglePalette(m); + else _plGeneratePhongPalette(m); + } else if (m->_ft == PL_FILL_TEXTURE) { + if (m->_st == PL_SHADE_NONE) + _plGenerateTexturePalette(m,m->Texture); + else _plGeneratePhongTexturePalette(m,m->Texture); + } else if (m->_ft == PL_FILL_ENVIRONMENT) { + if (m->_st == PL_SHADE_NONE) + _plGenerateTexturePalette(m,m->Environment); + else _plGeneratePhongTexturePalette(m,m->Environment); + } else if (m->_ft == (PL_FILL_ENVIRONMENT|PL_FILL_TEXTURE)) + _plGenerateTextureEnvPalette(m); + else if (m->_ft == PL_FILL_TRANSPARENT) { + if (m->_st == PL_SHADE_NONE) _plGenerateTransparentPalette(m); + else _plGeneratePhongTransparentPalette(m); + } + _plSetMaterialPutFace(m); +} + +static void _plMatSetupTransparent(pl_Mat *m, pl_uChar *pal) { + pl_uInt x, intensity; + if (m->Transparent) + { + if (m->_AddTable) free(m->_AddTable); + m->_AddTable = (pl_uInt16 *) malloc(256*sizeof(pl_uInt16)); + for (x = 0; x < 256; x ++) { + intensity = *pal++; + intensity += *pal++; + intensity += *pal++; + m->_AddTable[x] = ((intensity*(m->_ColorsUsed-m->_tsfact))/768); + } + } +} + +void plMatMapToPal(pl_Mat *m, pl_uChar *pal, pl_sInt pstart, pl_sInt pend) { + pl_sInt32 j, r, g, b, bestdiff, r2, g2, b2; + pl_sInt bestpos,k; + pl_uInt32 i; + pl_uChar *p; + if (!m->_RequestedColors) plMatInit(m); + if (!m->_RequestedColors) return; + if (m->_ReMapTable) free(m->_ReMapTable); + m->_ReMapTable = (pl_uChar *) malloc(m->_ColorsUsed); + for (i = 0; i < m->_ColorsUsed; i ++) { + bestdiff = 1000000000; + bestpos = pstart; + r = m->_RequestedColors[i*3]; + g = m->_RequestedColors[i*3+1]; + b = m->_RequestedColors[i*3+2]; + p = pal + pstart*3; + for (k = pstart; k <= (pl_sInt)pend; k ++) { + r2 = p[0] - r; + g2 = p[1] - g; + b2 = p[2] - b; + p += 3; + j = r2*r2+g2*g2+b2*b2; + if (j < bestdiff) { + bestdiff = j; + bestpos = k; + } + } + m->_ReMapTable[i] = bestpos; + } + _plMatSetupTransparent(m,pal); +} + +static void _plGenerateSinglePalette(pl_Mat *m) { + m->_ColorsUsed = 1; + if (m->_RequestedColors) free(m->_RequestedColors); + m->_RequestedColors = (pl_uChar *) malloc(3); + m->_RequestedColors[0] = plMin(plMax(m->Ambient[0],0),255); + m->_RequestedColors[1] = plMin(plMax(m->Ambient[1],0),255); + m->_RequestedColors[2] = plMin(plMax(m->Ambient[2],0),255); +} + +static void _plGeneratePhongPalette(pl_Mat *m) { + pl_uInt i = m->NumGradients, x; + pl_sInt c; + pl_uChar *pal; + double a, da, ca, cb; + m->_ColorsUsed = m->NumGradients; + if (m->_RequestedColors) free(m->_RequestedColors); + pal = m->_RequestedColors = (pl_uChar *) malloc(m->_ColorsUsed*3); + a = PL_PI/2.0; + + if (m->NumGradients > 1) da = -PL_PI/((m->NumGradients-1)<<1); + else da=0.0; + + do { + if (m->NumGradients == 1) ca = 1; + else { + ca = cos((double) a); + a += da; + } + cb = pow((double) ca, (double) m->Shininess); + for (x = 0; x < 3; x ++) { + c = (pl_sInt) ((cb*m->Specular[x])+(ca*m->Diffuse[x])+m->Ambient[x]); + *(pal++) = plMax(0,plMin(c,255)); + } + } while (--i); +} + +static void _plGenerateTextureEnvPalette(pl_Mat *m) { + pl_sInt c; + pl_uInt whichlevel,whichindex; + pl_uChar *texpal, *envpal, *pal; + m->_ColorsUsed = m->Texture->NumColors*m->Environment->NumColors; + if (m->_RequestedColors) free(m->_RequestedColors); + pal = m->_RequestedColors = (pl_uChar *) malloc(m->_ColorsUsed*3); + envpal = m->Environment->PaletteData; + if (m->_AddTable) free(m->_AddTable); + m->_AddTable = (pl_uInt16 *) malloc(m->Environment->NumColors*sizeof(pl_uInt16)); + for (whichlevel = 0; whichlevel < m->Environment->NumColors; whichlevel++) { + texpal = m->Texture->PaletteData; + switch (m->TexEnvMode) + { + case PL_TEXENV_MUL: // multiply + for (whichindex = 0; whichindex < m->Texture->NumColors; whichindex++) { + *pal++ = (pl_uChar) (((pl_sInt) (*texpal++) * (pl_sInt) envpal[0])>>8); + *pal++ = (pl_uChar) (((pl_sInt) (*texpal++) * (pl_sInt) envpal[1])>>8); + *pal++ = (pl_uChar) (((pl_sInt) (*texpal++) * (pl_sInt) envpal[2])>>8); + } + break; + case PL_TEXENV_AVG: // average + for (whichindex = 0; whichindex < m->Texture->NumColors; whichindex++) { + *pal++ = (pl_uChar) (((pl_sInt) (*texpal++) + (pl_sInt) envpal[0])>>1); + *pal++ = (pl_uChar) (((pl_sInt) (*texpal++) + (pl_sInt) envpal[1])>>1); + *pal++ = (pl_uChar) (((pl_sInt) (*texpal++) + (pl_sInt) envpal[2])>>1); + } + break; + case PL_TEXENV_TEXMINUSENV: // tex-env + for (whichindex = 0; whichindex < m->Texture->NumColors; whichindex++) { + c = (pl_sInt) (*texpal++) - (pl_sInt) envpal[0]; *pal++ = plMax(0,plMin(255,c)); + c = (pl_sInt) (*texpal++) - (pl_sInt) envpal[1]; *pal++ = plMax(0,plMin(255,c)); + c = (pl_sInt) (*texpal++) - (pl_sInt) envpal[2]; *pal++ = plMax(0,plMin(255,c)); + } + break; + case PL_TEXENV_ENVMINUSTEX: // env-tex + for (whichindex = 0; whichindex < m->Texture->NumColors; whichindex++) { + c = -(pl_sInt) (*texpal++) - (pl_sInt) envpal[0]; *pal++ = plMax(0,plMin(255,c)); + c = -(pl_sInt) (*texpal++) - (pl_sInt) envpal[1]; *pal++ = plMax(0,plMin(255,c)); + c = -(pl_sInt) (*texpal++) - (pl_sInt) envpal[2]; *pal++ = plMax(0,plMin(255,c)); + } + break; + case PL_TEXENV_MIN: + for (whichindex = 0; whichindex < m->Texture->NumColors; whichindex++) { + *pal++ = plMin(texpal[0],envpal[0]); + *pal++ = plMin(texpal[1],envpal[1]); + *pal++ = plMin(texpal[2],envpal[2]); + texpal+=3; + } + break; + case PL_TEXENV_MAX: + break; + for (whichindex = 0; whichindex < m->Texture->NumColors; whichindex++) { + *pal++ = plMax(texpal[0],envpal[0]); + *pal++ = plMax(texpal[1],envpal[1]); + *pal++ = plMax(texpal[2],envpal[2]); + texpal+=3; + } + default: // add + for (whichindex = 0; whichindex < m->Texture->NumColors; whichindex++) { + c = (pl_sInt) (*texpal++) + (pl_sInt) envpal[0]; *pal++ = plMax(0,plMin(255,c)); + c = (pl_sInt) (*texpal++) + (pl_sInt) envpal[1]; *pal++ = plMax(0,plMin(255,c)); + c = (pl_sInt) (*texpal++) + (pl_sInt) envpal[2]; *pal++ = plMax(0,plMin(255,c)); + } + break; + } + envpal += 3; + m->_AddTable[whichlevel] = whichlevel*m->Texture->NumColors; + } +} + +static void _plGenerateTexturePalette(pl_Mat *m, pl_Texture *t) { + pl_uChar *ppal, *pal; + pl_sInt c, i, x; + m->_ColorsUsed = t->NumColors; + if (m->_RequestedColors) free(m->_RequestedColors); + pal = m->_RequestedColors = (pl_uChar *) malloc(m->_ColorsUsed*3); + ppal = t->PaletteData; + i = t->NumColors; + do { + for (x = 0; x < 3; x ++) { + c = m->Ambient[x] + *ppal++; + *(pal++) = plMax(0,plMin(c,255)); + } + } while (--i); +} + +static void _plGeneratePhongTexturePalette(pl_Mat *m, pl_Texture *t) { + double a, ca, da, cb; + pl_uInt16 *addtable; + pl_uChar *ppal, *pal; + pl_sInt c, i, i2, x; + pl_uInt num_shades; + + if (t->NumColors) num_shades = (m->NumGradients / t->NumColors); + else num_shades=1; + + if (!num_shades) num_shades = 1; + m->_ColorsUsed = num_shades*t->NumColors; + if (m->_RequestedColors) free(m->_RequestedColors); + pal = m->_RequestedColors = (pl_uChar *) malloc(m->_ColorsUsed*3); + a = PL_PI/2.0; + if (num_shades>1) da = (-PL_PI/2.0)/(num_shades-1); + else da=0.0; + i2 = num_shades; + do { + ppal = t->PaletteData; + ca = cos((double) a); + a += da; + cb = pow(ca, (double) m->Shininess); + i = t->NumColors; + do { + for (x = 0; x < 3; x ++) { + c = (pl_sInt) ((cb*m->Specular[x])+(ca*m->Diffuse[x])+m->Ambient[x] + *ppal++); + *(pal++) = plMax(0,plMin(c,255)); + } + } while (--i); + } while (--i2); + ca = 0; + if (m->_AddTable) free(m->_AddTable); + m->_AddTable = (pl_uInt16 *) malloc(256*sizeof(pl_uInt16)); + addtable = m->_AddTable; + i = 256; + do { + a = sin(ca) * num_shades; + ca += PL_PI/512.0; + *addtable++ = ((pl_sInt) a)*t->NumColors; + } while (--i); +} + +static void _plGeneratePhongTransparentPalette(pl_Mat *m) { + m->_tsfact = (pl_sInt) (m->NumGradients*(1.0/(1+m->Transparent))); + _plGeneratePhongPalette(m); +} + +static void _plGenerateTransparentPalette(pl_Mat *m) { + m->_tsfact = 0; + _plGeneratePhongPalette(m); +} + +static void _plSetMaterialPutFace(pl_Mat *m) { + m->_PutFace = 0; + switch (m->_ft) { + case PL_FILL_TRANSPARENT: switch(m->_st) { + case PL_SHADE_NONE: case PL_SHADE_FLAT: + case PL_SHADE_FLAT_DISTANCE: case PL_SHADE_FLAT_DISTANCE|PL_SHADE_FLAT: + m->_PutFace = plPF_TransF; + break; + case PL_SHADE_GOURAUD: case PL_SHADE_GOURAUD_DISTANCE: + case PL_SHADE_GOURAUD|PL_SHADE_GOURAUD_DISTANCE: + m->_PutFace = plPF_TransG; + break; + } + break; + case PL_FILL_SOLID: switch(m->_st) { + case PL_SHADE_NONE: case PL_SHADE_FLAT: + case PL_SHADE_FLAT_DISTANCE: case PL_SHADE_FLAT_DISTANCE|PL_SHADE_FLAT: + m->_PutFace = plPF_SolidF; + break; + case PL_SHADE_GOURAUD: case PL_SHADE_GOURAUD_DISTANCE: + case PL_SHADE_GOURAUD|PL_SHADE_GOURAUD_DISTANCE: + m->_PutFace = plPF_SolidG; + break; + } + break; + case PL_FILL_ENVIRONMENT: + case PL_FILL_TEXTURE: + if (m->PerspectiveCorrect) switch (m->_st) { + case PL_SHADE_NONE: case PL_SHADE_FLAT: + case PL_SHADE_FLAT_DISTANCE: case PL_SHADE_FLAT_DISTANCE|PL_SHADE_FLAT: + m->_PutFace = plPF_PTexF; + break; + case PL_SHADE_GOURAUD: case PL_SHADE_GOURAUD_DISTANCE: + case PL_SHADE_GOURAUD|PL_SHADE_GOURAUD_DISTANCE: + m->_PutFace = plPF_PTexG; + break; + } + else switch (m->_st) { + case PL_SHADE_NONE: case PL_SHADE_FLAT: + case PL_SHADE_FLAT_DISTANCE: case PL_SHADE_FLAT_DISTANCE|PL_SHADE_FLAT: + m->_PutFace = plPF_TexF; + break; + case PL_SHADE_GOURAUD: case PL_SHADE_GOURAUD_DISTANCE: + case PL_SHADE_GOURAUD|PL_SHADE_GOURAUD_DISTANCE: + m->_PutFace = plPF_TexG; + break; + } + break; + case PL_FILL_TEXTURE|PL_FILL_ENVIRONMENT: + m->_PutFace = plPF_TexEnv; + break; + } +} + +typedef struct __ct { + pl_uChar r,g,b; + pl_Bool visited; + struct __ct *next; +} _ct; + +static int mdist(_ct *a, _ct *b) { + return ((a->r-b->r)*(a->r-b->r)+(a->g-b->g)*(a->g-b->g)+(a->b-b->b)*(a->b-b->b)); +} + +void plMatMakeOptPal(pl_uChar *p, pl_sInt pstart, + pl_sInt pend, pl_Mat **materials, pl_sInt nmats) { + pl_uChar *allColors = 0; + pl_sInt numColors = 0, nc, x; + pl_sInt len = pend + 1 - pstart; + pl_sInt32 current, newnext, bestdist, thisdist; + _ct *colorBlock, *best, *cp; + + for (x = 0; x < nmats; x ++) { + if (materials[x]) { + if (!materials[x]->_RequestedColors) plMatInit(materials[x]); + if (materials[x]->_RequestedColors) numColors+=materials[x]->_ColorsUsed; + } + } + if (!numColors) return; + + allColors=(pl_uChar*)malloc(numColors*3); + numColors=0; + + for (x = 0; x < nmats; x ++) { + if (materials[x]) { + if (materials[x]->_RequestedColors) + memcpy(allColors + (numColors*3), materials[x]->_RequestedColors, + materials[x]->_ColorsUsed*3); + numColors += materials[x]->_ColorsUsed; + } + } + + if (numColors <= len) { + memcpy(p+pstart*3,allColors,numColors*3); + free(allColors); + return; + } + + colorBlock = (_ct *) malloc(sizeof(_ct)*numColors); + for (x = 0; x < numColors; x++) { + colorBlock[x].r = allColors[x*3]; + colorBlock[x].g = allColors[x*3+1]; + colorBlock[x].b = allColors[x*3+2]; + colorBlock[x].visited = 0; + colorBlock[x].next = 0; + } + free(allColors); + + /* Build a list, starting at color 0 */ + current = 0; + nc = numColors; + do { + newnext = -1; + bestdist = 300000000; + colorBlock[current].visited = 1; + for (x = 0; x < nc; x ++) { + if (!colorBlock[x].visited) { + thisdist = mdist(colorBlock + x, colorBlock + current); + if (thisdist < 5) { colorBlock[x].visited = 1; numColors--; } + else if (thisdist < bestdist) { bestdist = thisdist; newnext = x; } + } + } + if (newnext != -1) { + colorBlock[current].next = colorBlock + newnext; + current = newnext; + } + } while (newnext != -1); + colorBlock[current].next = 0; /* terminate the list */ + + /* we now have a linked list starting at colorBlock, which is each one and + it's closest neighbor */ + + while (numColors > len) { + bestdist = mdist(colorBlock,colorBlock->next); + for (best = cp = colorBlock; cp->next; cp = cp->next) { + if (bestdist > (thisdist = mdist(cp,cp->next))) { + best = cp; + bestdist = thisdist; + } + } + best->r = ((int) best->r + (int) best->next->r)>>1; + best->g = ((int) best->g + (int) best->next->g)>>1; + best->b = ((int) best->b + (int) best->next->b)>>1; + best->next = best->next->next; + numColors--; + } + x = pstart*3; + for (cp = colorBlock; cp; cp = cp->next) { + p[x++] = cp->r; + p[x++] = cp->g; + p[x++] = cp->b; + } + free(colorBlock); +} diff --git a/Src/Winamp/plush/MATH.C b/Src/Winamp/plush/MATH.C new file mode 100644 index 00000000..ef66ca89 --- /dev/null +++ b/Src/Winamp/plush/MATH.C @@ -0,0 +1,67 @@ +/****************************************************************************** +Plush Version 1.2 +math.c +Math and Matrix Control +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +void plMatrixRotate(pl_Float matrix[], pl_uChar m, pl_Float Deg) { + pl_uChar m1, m2; + double c,s; + double d= Deg * PL_PI / 180.0; + memset(matrix,0,sizeof(pl_Float)*16); + matrix[((m-1)<<2)+m-1] = matrix[15] = 1.0; + m1 = (m % 3); + m2 = ((m1+1) % 3); + c = cos(d); s = sin(d); + matrix[(m1<<2)+m1]=(pl_Float)c; matrix[(m1<<2)+m2]=(pl_Float)s; + matrix[(m2<<2)+m2]=(pl_Float)c; matrix[(m2<<2)+m1]=(pl_Float)-s; +} + +void plMatrixTranslate(pl_Float m[], pl_Float x, pl_Float y, pl_Float z) { + memset(m,0,sizeof(pl_Float)*16); + m[0] = m[4+1] = m[8+2] = m[12+3] = 1.0; + m[0+3] = x; m[4+3] = y; m[8+3] = z; +} + +void plMatrixMultiply(pl_Float *dest, pl_Float src[]) { + pl_Float temp[16]; + pl_uInt i; + memcpy(temp,dest,sizeof(pl_Float)*16); + for (i = 0; i < 16; i += 4) { + *dest++ = src[i+0]*temp[(0<<2)+0]+src[i+1]*temp[(1<<2)+0]+ + src[i+2]*temp[(2<<2)+0]+src[i+3]*temp[(3<<2)+0]; + *dest++ = src[i+0]*temp[(0<<2)+1]+src[i+1]*temp[(1<<2)+1]+ + src[i+2]*temp[(2<<2)+1]+src[i+3]*temp[(3<<2)+1]; + *dest++ = src[i+0]*temp[(0<<2)+2]+src[i+1]*temp[(1<<2)+2]+ + src[i+2]*temp[(2<<2)+2]+src[i+3]*temp[(3<<2)+2]; + *dest++ = src[i+0]*temp[(0<<2)+3]+src[i+1]*temp[(1<<2)+3]+ + src[i+2]*temp[(2<<2)+3]+src[i+3]*temp[(3<<2)+3]; + } +} + +void plMatrixApply(pl_Float *m, pl_Float x, pl_Float y, pl_Float z, + pl_Float *outx, pl_Float *outy, pl_Float *outz) { + *outx = x*m[0] + y*m[1] + z*m[2] + m[3]; + *outy = x*m[4] + y*m[5] + z*m[6] + m[7]; + *outz = x*m[8] + y*m[9] + z*m[10] + m[11]; +} + +pl_Float plDotProduct(pl_Float x1, pl_Float y1, pl_Float z1, + pl_Float x2, pl_Float y2, pl_Float z2) { + return ((x1*x2)+(y1*y2)+(z1*z2)); +} + +void plNormalizeVector(pl_Float *x, pl_Float *y, pl_Float *z) { + double length; + length = (*x)*(*x)+(*y)*(*y)+(*z)*(*z); + if (length > 0.0000000001) { + pl_Float t = (pl_Float)sqrt(length); + *x /= t; + *y /= t; + *z /= t; + } else *x = *y = *z = 0.0; +} + diff --git a/Src/Winamp/plush/OBJ.C b/Src/Winamp/plush/OBJ.C new file mode 100644 index 00000000..79d9fce0 --- /dev/null +++ b/Src/Winamp/plush/OBJ.C @@ -0,0 +1,179 @@ +/****************************************************************************** +Plush Version 1.2 +obj.c +Object control +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +pl_Obj *plObjScale(pl_Obj *o, pl_Float s) { + pl_uInt32 i = o->NumVertices; + pl_Vertex *v = o->Vertices; + while (i--) { + v->x *= s; v->y *= s; v->z *= s; v++; + } + for (i = 0; i < PL_MAX_CHILDREN; i ++) + if (o->Children[i]) plObjScale(o->Children[i],s); + return o; +} + +pl_Obj *plObjStretch(pl_Obj *o, pl_Float x, pl_Float y, pl_Float z) { + pl_uInt32 i = o->NumVertices; + pl_Vertex *v = o->Vertices; + while (i--) { + v->x *= x; v->y *= y; v->z *= z; v++; + } + for (i = 0; i < PL_MAX_CHILDREN; i ++) + if (o->Children[i]) plObjStretch(o->Children[i],x,y,z); + return o; +} + +pl_Obj *plObjTranslate(pl_Obj *o, pl_Float x, pl_Float y, pl_Float z) { + pl_uInt32 i = o->NumVertices; + pl_Vertex *v = o->Vertices; + while (i--) { + v->x += x; v->y += y; v->z += z; v++; + } + return o; +} + +pl_Obj *plObjFlipNormals(pl_Obj *o) { + pl_uInt32 i = o->NumVertices; + pl_Vertex *v = o->Vertices; + pl_Face *f = o->Faces; + while (i--) { + v->nx = - v->nx; v->ny = - v->ny; v->nz = - v->nz; v++; + } + i = o->NumFaces; + while (i--) { + f->nx = - f->nx; f->ny = - f->ny; f->nz = - f->nz; + f++; + } + for (i = 0; i < PL_MAX_CHILDREN; i ++) + if (o->Children[i]) plObjFlipNormals(o->Children[i]); + return o; +} + +void plObjDelete(pl_Obj *o) { + pl_uInt i; + if (o) { + for (i = 0; i < PL_MAX_CHILDREN; i ++) + if (o->Children[i]) plObjDelete(o->Children[i]); + if (o->Vertices) free(o->Vertices); + if (o->Faces) free(o->Faces); + free(o); + } +} + +pl_Obj *plObjCreate(pl_uInt32 nv, pl_uInt32 nf) { + pl_Obj *o; + if (!(o = (pl_Obj *) malloc(sizeof(pl_Obj)))) return 0; + memset(o,0,sizeof(pl_Obj)); + o->GenMatrix = 1; + o->BackfaceCull = 1; + o->NumVertices = nv; + o->NumFaces = nf; + if (nv && !(o->Vertices=(pl_Vertex *) malloc(sizeof(pl_Vertex)*nv))) { + free(o); + return 0; + } + if (nf && !(o->Faces = (pl_Face *) malloc(sizeof(pl_Face)*nf))) { + free(o->Vertices); + free(o); + return 0; + } + memset(o->Vertices,0,sizeof(pl_Vertex)*nv); + memset(o->Faces,0,sizeof(pl_Face)*nf); + return o; +} + +pl_Obj *plObjClone(pl_Obj *o) { + pl_Face *iff, *of; + pl_uInt32 i; + pl_Obj *out; + if (!(out = plObjCreate(o->NumVertices,o->NumFaces))) return 0; + for (i = 0; i < PL_MAX_CHILDREN; i ++) + if (o->Children[i]) out->Children[i] = plObjClone(o->Children[i]); + out->Xa = o->Xa; out->Ya = o->Ya; out->Za = o->Za; + out->Xp = o->Xp; out->Yp = o->Yp; out->Zp = o->Zp; + out->BackfaceCull = o->BackfaceCull; + out->BackfaceIllumination = o->BackfaceIllumination; + out->GenMatrix = o->GenMatrix; + memcpy(out->Vertices, o->Vertices, sizeof(pl_Vertex) * o->NumVertices); + iff = o->Faces; + of = out->Faces; + i = out->NumFaces; + while (i--) { + of->Vertices[0] = (pl_Vertex *) + out->Vertices + (iff->Vertices[0] - o->Vertices); + of->Vertices[1] = (pl_Vertex *) + out->Vertices + (iff->Vertices[1] - o->Vertices); + of->Vertices[2] = (pl_Vertex *) + out->Vertices + (iff->Vertices[2] - o->Vertices); + of->MappingU[0] = iff->MappingU[0]; + of->MappingV[0] = iff->MappingV[0]; + of->MappingU[1] = iff->MappingU[1]; + of->MappingV[1] = iff->MappingV[1]; + of->MappingU[2] = iff->MappingU[2]; + of->MappingV[2] = iff->MappingV[2]; + of->nx = iff->nx; + of->ny = iff->ny; + of->nz = iff->nz; + of->Material = iff->Material; + of++; + iff++; + } + return out; +} + +void plObjSetMat(pl_Obj *o, pl_Mat *m, pl_Bool th) { + pl_sInt32 i = o->NumFaces; + pl_Face *f = o->Faces; + while (i--) (f++)->Material = m; + if (th) for (i = 0; i < PL_MAX_CHILDREN; i++) + if (o->Children[i]) plObjSetMat(o->Children[i],m,th); +} + +void plObjCalcNormals(pl_Obj *obj) { + pl_uInt32 i; + pl_Vertex *v = obj->Vertices; + pl_Face *f = obj->Faces; + double x1, x2, y1, y2, z1, z2; + i = obj->NumVertices; + while (i--) { + v->nx = 0.0; v->ny = 0.0; v->nz = 0.0; + v++; + } + i = obj->NumFaces; + while (i--) { + x1 = f->Vertices[0]->x-f->Vertices[1]->x; + x2 = f->Vertices[0]->x-f->Vertices[2]->x; + y1 = f->Vertices[0]->y-f->Vertices[1]->y; + y2 = f->Vertices[0]->y-f->Vertices[2]->y; + z1 = f->Vertices[0]->z-f->Vertices[1]->z; + z2 = f->Vertices[0]->z-f->Vertices[2]->z; + f->nx = (pl_Float) (y1*z2 - z1*y2); + f->ny = (pl_Float) (z1*x2 - x1*z2); + f->nz = (pl_Float) (x1*y2 - y1*x2); + plNormalizeVector(&f->nx, &f->ny, &f->nz); + f->Vertices[0]->nx += f->nx; + f->Vertices[0]->ny += f->ny; + f->Vertices[0]->nz += f->nz; + f->Vertices[1]->nx += f->nx; + f->Vertices[1]->ny += f->ny; + f->Vertices[1]->nz += f->nz; + f->Vertices[2]->nx += f->nx; + f->Vertices[2]->ny += f->ny; + f->Vertices[2]->nz += f->nz; + f++; + } + v = obj->Vertices; + i = obj->NumVertices; + do { + plNormalizeVector(&v->nx, &v->ny, &v->nz); + v++; + } while (--i); + for (i = 0; i < PL_MAX_CHILDREN; i ++) + if (obj->Children[i]) plObjCalcNormals(obj->Children[i]); +} diff --git a/Src/Winamp/plush/PF_PTEX.C b/Src/Winamp/plush/PF_PTEX.C new file mode 100644 index 00000000..eb1d0381 --- /dev/null +++ b/Src/Winamp/plush/PF_PTEX.C @@ -0,0 +1,459 @@ +/****************************************************************************** +Plush Version 1.2 +pf_ptex.c +Perspective Correct Texture Mapping Rasterizers +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" +#include "putface.h" + +void plPF_PTexF(pl_Cam *cam, pl_Face *TriFace) { + pl_uChar i0, i1, i2; + pl_uChar *gmem = cam->frameBuffer; + pl_uChar *remap = TriFace->Material->_ReMapTable; + pl_ZBuffer *zbuf = cam->zBuffer; + pl_Float MappingU1, MappingU2, MappingU3; + pl_Float MappingV1, MappingV2, MappingV3; + pl_sInt32 MappingU_AND, MappingV_AND; + pl_uChar *texture; + pl_uChar vshift; + pl_uInt16 bc; + pl_Texture *Texture; + pl_sInt32 iShade; + + pl_uChar nm, nmb; + pl_sInt n; + pl_Float U1,V1,U2,V2,dU1=0,dU2=0,dV1=0,dV2=0,dUL=0,dVL=0,UL,VL; + pl_sInt32 iUL, iVL, idUL=0, idVL=0, iULnext, iVLnext; + + pl_sInt32 scrwidth = cam->ScreenWidth; + pl_sInt32 X1, X2, dX1=0, dX2=0, XL1, Xlen; + pl_ZBuffer Z1, dZ1=0, dZ2=0, Z2, dZL=0, ZL, pZL, pdZL; + pl_sInt32 Y1, Y2, Y0, dY; + pl_uChar stat; + + pl_Bool zb = (zbuf&&TriFace->Material->zBufferable) ? 1 : 0; + + if (TriFace->Material->Environment) Texture = TriFace->Material->Environment; + else Texture = TriFace->Material->Texture; + + if (!Texture) return; + texture = Texture->Data; + iShade = (pl_sInt32)(TriFace->fShade*256.0); + if (iShade < 0) iShade=0; + if (iShade > 255) iShade=255; + + if (!TriFace->Material->_AddTable) bc=0; + else bc = TriFace->Material->_AddTable[iShade]; + nm = TriFace->Material->PerspectiveCorrect; + nmb = 0; while (nm) { nmb++; nm >>= 1; } + nmb = plMin(6,nmb); + nm = 1<<nmb; + MappingV_AND = ((1<<Texture->Height)-1)<<Texture->Width; + MappingU_AND = (1<<Texture->Width)-1; + vshift = 16 - Texture->Width; + + if (TriFace->Material->Environment) { + PUTFACE_SORT_ENV(); + } else { + PUTFACE_SORT_TEX(); + } + + MappingU1 *= TriFace->Scrz[i0]/65536.0f; + MappingV1 *= TriFace->Scrz[i0]/65536.0f; + MappingU2 *= TriFace->Scrz[i1]/65536.0f; + MappingV2 *= TriFace->Scrz[i1]/65536.0f; + MappingU3 *= TriFace->Scrz[i2]/65536.0f; + MappingV3 *= TriFace->Scrz[i2]/65536.0f; + + U1 = U2 = MappingU1; + V1 = V2 = MappingV1; + X2 = X1 = TriFace->Scrx[i0]; + Z2 = Z1 = TriFace->Scrz[i0]; + Y0 = (TriFace->Scry[i0]+(1<<19))>>20; + Y1 = (TriFace->Scry[i1]+(1<<19))>>20; + Y2 = (TriFace->Scry[i2]+(1<<19))>>20; + + dY = Y2-Y0; + if (dY) { + dX2 = (TriFace->Scrx[i2] - X1) / dY; + dZ2 = (TriFace->Scrz[i2] - Z1) / dY; + dU2 = (MappingU3 - U1) / dY; + dV2 = (MappingV3 - V1) / dY; + } + dY = Y1-Y0; + if (dY) { + dX1 = (TriFace->Scrx[i1] - X1) / dY; + dZ1 = (TriFace->Scrz[i1] - Z1) / dY; + dU1 = (MappingU2 - U1) / dY; + dV1 = (MappingV2 - V1) / dY; + if (dX2 < dX1) { + XL1 = dX2; dX2 = dX1; dX1 = XL1; + dUL = dU1; dU1 = dU2; dU2 = dUL; + dVL = dV1; dV1 = dV2; dV2 = dVL; + dZL = dZ1; dZ1 = dZ2; dZ2 = dZL; + stat = 2; + } else stat = 1; + } else { + if (TriFace->Scrx[i1] > X1) { + X2 = TriFace->Scrx[i1]; + Z2 = TriFace->Scrz[i1]; + U2 = MappingU2; + V2 = MappingV2; + stat = 2|4; + } else { + X1 = TriFace->Scrx[i1]; + Z1 = TriFace->Scrz[i1]; + U1 = MappingU2; + V1 = MappingV2; + stat = 1|8; + } + } + + gmem += (Y0 * cam->ScreenWidth); + zbuf += (Y0 * cam->ScreenWidth); + + XL1 = ((dX1-dX2)*dY+(1<<19))>>20; + if (XL1) { + dUL = ((dU1-dU2)*dY)/XL1; + dVL = ((dV1-dV2)*dY)/XL1; + dZL = ((dZ1-dZ2)*dY)/XL1; + } else { + XL1 = ((X2-X1+(1<<19))>>20); + if (XL1) { + dUL = (U2-U1)/XL1; + dVL = (V2-V1)/XL1; + dZL = (Z2-Z1)/XL1; + } + } + + pdZL = dZL * nm; + dUL *= nm; + dVL *= nm; + + while (Y0 < Y2) { + if (Y0 == Y1) { + dY = Y2-((TriFace->Scry[i1]+(1<<19))>>20); + if (dY) { + if (stat & 1) { + X1 = TriFace->Scrx[i1]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 2) { + X2 = TriFace->Scrx[i1]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 4) { + X1 = TriFace->Scrx[i0]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + if (stat & 8) { + X2 = TriFace->Scrx[i0]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + dZ1 = (TriFace->Scrz[i2]-Z1)/dY; + dV1 = (MappingV3 - V1) / dY; + dU1 = (MappingU3 - U1) / dY; + } + } + XL1 = (X1+(1<<19))>>20; + Xlen = ((X2+(1<<19))>>20) - XL1; + if (Xlen > 0) { + register pl_Float t; + pZL = ZL = Z1; + UL = U1; + VL = V1; + gmem += XL1; + zbuf += XL1; + XL1 += Xlen-scrwidth; + t = 65536.0f/ZL; + iUL = iULnext = ((pl_sInt32) (UL*t)); + iVL = iVLnext = ((pl_sInt32) (VL*t)); + do { + UL += dUL; + VL += dVL; + iUL = iULnext; + iVL = iVLnext; + pZL += pdZL; + t = 65536.0f/pZL; + iULnext = ((pl_sInt32) (UL*t)); + iVLnext = ((pl_sInt32) (VL*t)); + idUL = (iULnext - iUL)>>nmb; + idVL = (iVLnext - iVL)>>nmb; + n = nm; + Xlen -= n; + if (Xlen < 0) n += Xlen; + if (zb) do { + if (*zbuf < ZL) { + *zbuf = ZL; + *gmem = remap[bc + texture[((iUL>>16)&MappingU_AND) + + ((iVL>>vshift)&MappingV_AND)]]; + } + zbuf++; + gmem++; + ZL += dZL; + iUL += idUL; + iVL += idVL; + } while (--n); + else do { + *gmem++ = remap[bc + texture[((iUL>>16)&MappingU_AND) + + ((iVL>>vshift)&MappingV_AND)]]; + iUL += idUL; + iVL += idVL; + } while (--n); + } while (Xlen > 0); + gmem -= XL1; + zbuf -= XL1; + } else { + zbuf += cam->ScreenWidth; + gmem += cam->ScreenWidth; + } + Z1 += dZ1; + U1 += dU1; + V1 += dV1; + X1 += dX1; + X2 += dX2; + Y0++; + } +} + +void plPF_PTexG(pl_Cam *cam, pl_Face *TriFace) { + pl_uChar i0, i1, i2; + pl_Float MappingU1, MappingU2, MappingU3; + pl_Float MappingV1, MappingV2, MappingV3; + + pl_Texture *Texture; + pl_Bool zb = (cam->zBuffer&&TriFace->Material->zBufferable) ? 1 : 0; + + pl_uChar nm, nmb; + pl_uInt n; + pl_sInt32 MappingU_AND, MappingV_AND; + pl_uChar vshift; + pl_uChar *texture; + pl_uInt16 *addtable; + pl_uChar *remap = TriFace->Material->_ReMapTable; + pl_sInt32 iUL, iVL, idUL, idVL, iULnext, iVLnext; + pl_Float U2,V2,dU2=0,dV2=0,dUL=0,dVL=0,UL,VL; + pl_sInt32 XL1, Xlen; + pl_sInt32 C2, dC2=0, CL, dCL=0; + pl_Float ZL, Z2, dZ2=0, dZL=0, pdZL, pZL; + + pl_sInt32 Y2, dY; + pl_uChar stat; + + /* Cache line */ + pl_sInt32 Y0,Y1; + pl_sInt32 C1, dC1=0, X2, dX2=0, X1, dX1=0; + + /* Cache line */ + pl_Float dU1=0, U1, dZ1=0, Z1, V1, dV1=0; + pl_sInt32 scrwidth = cam->ScreenWidth; + pl_uChar *gmem = cam->frameBuffer; + pl_ZBuffer *zbuf = cam->zBuffer; + + if (TriFace->Material->Environment) Texture = TriFace->Material->Environment; + else Texture = TriFace->Material->Texture; + + if (!Texture) return; + texture = Texture->Data; + addtable = TriFace->Material->_AddTable; + if (!addtable) return; + + nm = TriFace->Material->PerspectiveCorrect; + nmb = 0; while (nm) { nmb++; nm >>= 1; } + nmb = plMin(6,nmb); + nm = 1<<nmb; + MappingV_AND = ((1<<Texture->Height)-1)<<Texture->Width; + MappingU_AND = (1<<Texture->Width)-1; + vshift = 16 - Texture->Width; + + if (TriFace->Material->Environment) { + PUTFACE_SORT_ENV(); + } else { + PUTFACE_SORT_TEX(); + } + + MappingU1 *= TriFace->Scrz[i0]/65536.0f; + MappingV1 *= TriFace->Scrz[i0]/65536.0f; + MappingU2 *= TriFace->Scrz[i1]/65536.0f; + MappingV2 *= TriFace->Scrz[i1]/65536.0f; + MappingU3 *= TriFace->Scrz[i2]/65536.0f; + MappingV3 *= TriFace->Scrz[i2]/65536.0f; + TriFace->Shades[0] *= 65536.0f; + TriFace->Shades[1] *= 65536.0f; + TriFace->Shades[2] *= 65536.0f; + + C1 = C2 = (pl_sInt32) TriFace->Shades[i0]; + U1 = U2 = MappingU1; + V1 = V2 = MappingV1; + X2 = X1 = TriFace->Scrx[i0]; + Z2 = Z1 = TriFace->Scrz[i0]; + Y0 = (TriFace->Scry[i0]+(1<<19))>>20; + Y1 = (TriFace->Scry[i1]+(1<<19))>>20; + Y2 = (TriFace->Scry[i2]+(1<<19))>>20; + + dY = Y2-Y0; + if (dY) { + dX2 = (TriFace->Scrx[i2] - X1) / dY; + dZ2 = (TriFace->Scrz[i2] - Z1) / dY; + dC2 = (pl_sInt32) ((TriFace->Shades[i2] - C1) / dY); + dU2 = (MappingU3 - U1) / dY; + dV2 = (MappingV3 - V1) / dY; + } + dY = Y1-Y0; + if (dY) { + dX1 = (TriFace->Scrx[i1] - X1) / dY; + dZ1 = (TriFace->Scrz[i1] - Z1) / dY; + dC1 = (pl_sInt32) ((TriFace->Shades[i1] - C1) / dY); + dU1 = (MappingU2 - U1) / dY; + dV1 = (MappingV2 - V1) / dY; + if (dX2 < dX1) { + dX2 ^= dX1; dX1 ^= dX2; dX2 ^= dX1; + dUL = dU1; dU1 = dU2; dU2 = dUL; + dVL = dV1; dV1 = dV2; dV2 = dVL; + dZL = dZ1; dZ1 = dZ2; dZ2 = dZL; + dCL = dC1; dC1 = dC2; dC2 = dCL; + stat = 2; + } else stat = 1; + } else { + if (TriFace->Scrx[i1] > X1) { + X2 = TriFace->Scrx[i1]; + Z2 = TriFace->Scrz[i1]; + C2 = (pl_sInt32)TriFace->Shades[i1]; + U2 = MappingU2; + V2 = MappingV2; + stat = 2|4; + } else { + X1 = TriFace->Scrx[i1]; + Z1 = TriFace->Scrz[i1]; + C1 = (pl_sInt32)TriFace->Shades[i1]; + U1 = MappingU2; + V1 = MappingV2; + stat = 1|8; + } + } + + gmem += (Y0 * scrwidth); + zbuf += (Y0 * scrwidth); + + XL1 = (((dX1-dX2)*dY+(1<<19))>>20); + if (XL1) { + dUL = ((dU1-dU2)*dY)/XL1; + dVL = ((dV1-dV2)*dY)/XL1; + dZL = ((dZ1-dZ2)*dY)/XL1; + dCL = ((dC1-dC2)*dY)/XL1; + } else { + XL1 = ((X2-X1+(1<<19))>>20); + if (XL1) { + dUL = (U2-U1)/XL1; + dVL = (V2-V1)/XL1; + dZL = (Z2-Z1)/XL1; + dCL = (C2-C1)/XL1; + } + } + + pdZL = dZL * nm; + dUL *= nm; + dVL *= nm; + Y1 -= Y0; + Y0 = Y2-Y0; + while (Y0--) { + if (!Y1--) { + dY = Y2-((TriFace->Scry[i1]+(1<<19))>>20); + if (dY) { + if (stat & 1) { + X1 = TriFace->Scrx[i1]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 2) { + X2 = TriFace->Scrx[i1]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 4) { + X1 = TriFace->Scrx[i0]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + if (stat & 8) { + X2 = TriFace->Scrx[i0]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + dZ1 = (TriFace->Scrz[i2]-Z1)/dY; + dC1 = (pl_sInt32)((TriFace->Shades[i2]-C1)/dY); + dV1 = (MappingV3 - V1) / dY; + dU1 = (MappingU3 - U1) / dY; + } + } + XL1 = (X1+(1<<19))>>20; + Xlen = ((X2+(1<<19))>>20) - XL1; + if (Xlen > 0) { + register pl_Float t; + CL = C1; + pZL = ZL = Z1; + UL = U1; + VL = V1; + gmem += XL1; + zbuf += XL1; + XL1 += Xlen-scrwidth; + t = 65536.0f / ZL; + iUL = iULnext = ((pl_sInt32) (UL*t)); + iVL = iVLnext = ((pl_sInt32) (VL*t)); + do { + UL += dUL; + VL += dVL; + iUL = iULnext; + iVL = iVLnext; + pZL += pdZL; + t = 65536.0f/pZL; + iULnext = ((pl_sInt32) (UL*t)); + iVLnext = ((pl_sInt32) (VL*t)); + idUL = (iULnext - iUL)>>nmb; + idVL = (iVLnext - iVL)>>nmb; + n = nm; + Xlen -= n; + if (Xlen < 0) n += Xlen; + if (zb) do { + if (*zbuf < ZL) { + int av; + if (CL < 0) av=addtable[0]; + else if (CL > (255<<8)) av=addtable[255]; + else av=addtable[CL>>8]; + *zbuf = ZL; + *gmem = remap[av + + texture[((iUL>>16)&MappingU_AND) + + ((iVL>>vshift)&MappingV_AND)]]; + } + zbuf++; + gmem++; + ZL += dZL; + CL += dCL; + iUL += idUL; + iVL += idVL; + } while (--n); + else do { + int av; + if (CL < 0) av=addtable[0]; + else if (CL > (255<<8)) av=addtable[255]; + else av=addtable[CL>>8]; + *gmem++ = remap[av + + texture[((iUL>>16)&MappingU_AND) + + ((iVL>>vshift)&MappingV_AND)]]; + CL += dCL; + iUL += idUL; + iVL += idVL; + } while (--n); + } while (Xlen > 0); + gmem -= XL1; + zbuf -= XL1; + } else { + zbuf += scrwidth; + gmem += scrwidth; + } + Z1 += dZ1; + U1 += dU1; + V1 += dV1; + X1 += dX1; + X2 += dX2; + C1 += dC1; + } +} diff --git a/Src/Winamp/plush/PF_SOLID.C b/Src/Winamp/plush/PF_SOLID.C new file mode 100644 index 00000000..f306b177 --- /dev/null +++ b/Src/Winamp/plush/PF_SOLID.C @@ -0,0 +1,271 @@ +/****************************************************************************** +Plush Version 1.2 +pf_solid.c +Solid Rasterizers +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" +#include "putface.h" + +void plPF_SolidF(pl_Cam *cam, pl_Face *TriFace) { + pl_uChar i0, i1, i2; + + pl_uChar *gmem = cam->frameBuffer; + pl_ZBuffer *zbuf = cam->zBuffer; + + pl_sInt32 X1, X2, dX1=0, dX2=0, XL1, XL2; + pl_ZBuffer dZL=0, dZ1=0, dZ2=0, Z1, ZL, Z2, Z3; + pl_sInt32 Y1, Y2, Y0, dY; + pl_uChar stat; + pl_Bool zb = (zbuf&&TriFace->Material->zBufferable) ? 1 : 0; + pl_uChar bc; + pl_sInt32 shade; + + PUTFACE_SORT(); + + shade=(pl_sInt32) (TriFace->fShade*(TriFace->Material->_ColorsUsed-1)); + if (shade < 0) shade=0; + if (shade > (pl_sInt32) TriFace->Material->_ColorsUsed-1) shade=TriFace->Material->_ColorsUsed-1; + bc=TriFace->Material->_ReMapTable[shade]; + + X2 = X1 = TriFace->Scrx[i0]; + Z1 = TriFace->Scrz[i0]; + Z2 = TriFace->Scrz[i1]; + Z3 = TriFace->Scrz[i2]; + Y0 = (TriFace->Scry[i0]+(1<<19)) >> 20; + Y1 = (TriFace->Scry[i1]+(1<<19)) >> 20; + Y2 = (TriFace->Scry[i2]+(1<<19)) >> 20; + + dY = Y2-Y0; + if (dY) { + dX2 = (TriFace->Scrx[i2] - X1) / dY; + dZ2 = (Z3 - Z1) / dY; + } + dY = Y1-Y0; + if (dY) { + dX1 = (TriFace->Scrx[i1] - X1) / dY; + dZ1 = (Z2 - Z1) / dY; + if (dX2 < dX1) { + dX2 ^= dX1; dX1 ^= dX2; dX2 ^= dX1; + dZL = dZ1; dZ1 = dZ2; dZ2 = dZL; + stat = 2; + } else stat = 1; + Z2 = Z1; + } else { + if (TriFace->Scrx[i1] > X1) { + X2 = TriFace->Scrx[i1]; + stat = 2|4; + } else { + X1 = TriFace->Scrx[i1]; + ZL = Z1; Z1 = Z2; Z2 = ZL; + stat = 1|8; + } + } + + if (zb) { + XL1 = ((dX1-dX2)*dY+(1<<19))>>20; + if (XL1) dZL = ((dZ1-dZ2)*dY)/XL1; + else { + XL1 = (X2-X1+(1<<19))>>20; + if (zb && XL1) dZL = (Z2-Z1)/XL1; + else dZL = 0.0; + } + } + + gmem += (Y0 * cam->ScreenWidth); + zbuf += (Y0 * cam->ScreenWidth); + + while (Y0 < Y2) { + if (Y0 == Y1) { + dY = Y2 - ((TriFace->Scry[i1]+(1<<19))>>20); + if (dY) { + if (stat & 1) { + X1 = TriFace->Scrx[i1]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 2) { + X2 = TriFace->Scrx[i1]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 4) { + X1 = TriFace->Scrx[i0]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + if (stat & 8) { + X2 = TriFace->Scrx[i0]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + dZ1 = (Z3-Z1)/dY; + } + } + XL1 = (X1+(1<<19))>>20; + XL2 = (X2+(1<<19))>>20; + ZL = Z1; + XL2 -= XL1; + if (XL2 > 0) { + zbuf += XL1; + gmem += XL1; + XL1 += XL2; + if (zb) do { + if (*zbuf < ZL) { + *zbuf = ZL; + *gmem = bc; + } + gmem++; + zbuf++; + ZL += dZL; + } while (--XL2); + else do *gmem++ = bc; while (--XL2); + gmem -= XL1; + zbuf -= XL1; + } + gmem += cam->ScreenWidth; + zbuf += cam->ScreenWidth; + Z1 += dZ1; + X1 += dX1; + X2 += dX2; + Y0++; + } +} + +void plPF_SolidG(pl_Cam *cam, pl_Face *TriFace) { + pl_uChar i0, i1, i2; + pl_uChar *gmem = cam->frameBuffer; + pl_uChar *remap = TriFace->Material->_ReMapTable; + pl_ZBuffer *zbuf = cam->zBuffer; + pl_ZBuffer dZL=0, dZ1=0, dZ2=0, Z1, Z2, ZL, Z3; + pl_sInt32 dX1=0, dX2=0, X1, X2, XL1, XL2; + pl_sInt32 C1, C2, dC1=0, dC2=0, dCL=0, CL, C3; + pl_sInt32 Y1, Y2, Y0, dY; + pl_uChar stat; + pl_Bool zb = (zbuf&&TriFace->Material->zBufferable) ? 1 : 0; + + pl_Float nc = (TriFace->Material->_ColorsUsed-1)*65536.0f; + pl_sInt32 maxColor=((TriFace->Material->_ColorsUsed-1)<<16); + pl_sInt32 maxColorNonShift=TriFace->Material->_ColorsUsed-1; + + PUTFACE_SORT(); + + + C1 = (pl_sInt32) (TriFace->Shades[i0]*nc); + C2 = (pl_sInt32) (TriFace->Shades[i1]*nc); + C3 = (pl_sInt32) (TriFace->Shades[i2]*nc); + X2 = X1 = TriFace->Scrx[i0]; + Z1 = TriFace->Scrz[i0]; + Z2 = TriFace->Scrz[i1]; + Z3 = TriFace->Scrz[i2]; + + Y0 = (TriFace->Scry[i0]+(1<<19))>>20; + Y1 = (TriFace->Scry[i1]+(1<<19))>>20; + Y2 = (TriFace->Scry[i2]+(1<<19))>>20; + + dY = Y2 - Y0; + if (dY) { + dX2 = (TriFace->Scrx[i2] - X1) / dY; + dC2 = (C3 - C1) / dY; + dZ2 = (Z3 - Z1) / dY; + } + dY = Y1 - Y0; + if (dY) { + dX1 = (TriFace->Scrx[i1] - X1) / dY; + dC1 = (C2 - C1) / dY; + dZ1 = (Z2 - Z1) / dY; + if (dX2 < dX1) { + dX2 ^= dX1; dX1 ^= dX2; dX2 ^= dX1; + dC2 ^= dC1; dC1 ^= dC2; dC2 ^= dC1; + dZL = dZ1; dZ1 = dZ2; dZ2 = dZL; + stat = 2; + } else stat = 1; + Z2 = Z1; + C2 = C1; + } else { + if (TriFace->Scrx[i1] > X1) { + X2 = TriFace->Scrx[i1]; + stat = 2|4; + } else { + X1 = C1; C1 = C2; C2 = X1; + ZL = Z1; Z1 = Z2; Z2 = ZL; + X1 = TriFace->Scrx[i1]; + stat = 1|8; + } + } + + gmem += (Y0 * cam->ScreenWidth); + zbuf += (Y0 * cam->ScreenWidth); + + XL1 = (((dX1-dX2)*dY+(1<<19))>>20); + if (XL1) { + dCL = ((dC1-dC2)*dY)/XL1; + dZL = ((dZ1-dZ2)*dY)/XL1; + } else { + XL1 = ((X2-X1+(1<<19))>>20); + if (XL1) { + dCL = (C2-C1)/XL1; + dZL = (Z2-Z1)/XL1; + } + } + + while (Y0 < Y2) { + if (Y0 == Y1) { + dY = Y2 - ((TriFace->Scry[i1]+(1<<19))>>20); + if (dY) { + dZ1 = (Z3-Z1)/dY; + dC1 = (C3-C1) / dY; + if (stat & 1) { + X1 = TriFace->Scrx[i1]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 2) { + X2 = TriFace->Scrx[i1]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 4) { + X1 = TriFace->Scrx[i0]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + if (stat & 8) { + X2 = TriFace->Scrx[i0]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + } + } + CL = C1; + XL1 = (X1+(1<<19))>>20; + XL2 = (X2+(1<<19))>>20; + ZL = Z1; + XL2 -= XL1; + if (XL2 > 0) { + gmem += XL1; + zbuf += XL1; + XL1 += XL2; + if (zb) do { + if (*zbuf < ZL) { + *zbuf = ZL; + if (CL >= maxColor) *gmem=remap[maxColorNonShift]; + else if (CL > 0) *gmem = remap[CL>>16]; + else *gmem = remap[0]; + } + gmem++; + zbuf++; + ZL += dZL; + CL += dCL; + } while (--XL2); + else do { + if (CL >= maxColor) *gmem++=remap[maxColorNonShift]; + else if (CL > 0) *gmem++ = remap[CL>>16]; + else *gmem++ = remap[0]; + CL += dCL; + } while (--XL2); + gmem -= XL1; + zbuf -= XL1; + } + gmem += cam->ScreenWidth; + zbuf += cam->ScreenWidth; + X1 += dX1; + X2 += dX2; + C1 += dC1; + Z1 += dZ1; + Y0++; + } +} diff --git a/Src/Winamp/plush/PF_TEX.C b/Src/Winamp/plush/PF_TEX.C new file mode 100644 index 00000000..b9879169 --- /dev/null +++ b/Src/Winamp/plush/PF_TEX.C @@ -0,0 +1,584 @@ +/****************************************************************************** +Plush Version 1.2 +pf_tex.c +Affine Texture Mapping Rasterizers +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" +#include "putface.h" + + +void plPF_TexEnv(pl_Cam *cam, pl_Face *TriFace) { + pl_uChar i0, i1, i2; + pl_uChar *gmem = cam->frameBuffer; + pl_uChar *remap; + pl_ZBuffer *zbuf = cam->zBuffer; + + pl_sInt32 MappingU1, MappingU2, MappingU3; + pl_sInt32 MappingV1, MappingV2, MappingV3; + pl_sInt32 MappingU_AND, MappingV_AND; + pl_sInt32 eMappingU1, eMappingU2, eMappingU3; + pl_sInt32 eMappingV1, eMappingV2, eMappingV3; + pl_sInt32 eMappingU_AND, eMappingV_AND; + + pl_uChar *texture, *environment; + pl_uChar vshift; + pl_uChar evshift; + pl_uInt16 *addtable; + pl_Texture *Texture, *Environment; + pl_uChar stat; + pl_Bool zb = (zbuf&&TriFace->Material->zBufferable) ? 1 : 0; + + pl_sInt32 U1, V1, U2, V2, dU1=0, dU2=0, dV1=0, dV2=0, dUL=0, dVL=0, UL, VL; + pl_sInt32 eU1, eV1, eU2, eV2, edU1=0, edU2=0, edV1=0, + edV2=0, edUL=0, edVL=0, eUL, eVL; + pl_sInt32 X1, X2, dX1=0, dX2=0, XL1, XL2; + pl_Float Z1, ZL, dZ1=0, dZ2=0, dZL=0, Z2; + pl_sInt32 Y1, Y2, Y0, dY; + + Environment = TriFace->Material->Environment; + Texture = TriFace->Material->Texture; + + if (!Texture || !Environment) return; + texture = Texture->Data; + environment = Environment->Data; + addtable = TriFace->Material->_AddTable; + remap = TriFace->Material->_ReMapTable; + + MappingV_AND = ((1<<Texture->Height)-1)<<Texture->Width; + MappingU_AND = (1<<Texture->Width)-1; + vshift = 16 - Texture->Width; + eMappingV_AND = ((1<<Environment->Height)-1)<<Environment->Width; + eMappingU_AND = (1<<Environment->Width)-1; + evshift = 16 - Environment->Width; + + PUTFACE_SORT_TEX(); + + eMappingU1=(pl_sInt32) (TriFace->eMappingU[i0]*Environment->uScale*TriFace->Material->EnvScaling); + eMappingV1=(pl_sInt32) (TriFace->eMappingV[i0]*Environment->vScale*TriFace->Material->EnvScaling); + eMappingU2=(pl_sInt32) (TriFace->eMappingU[i1]*Environment->uScale*TriFace->Material->EnvScaling); + eMappingV2=(pl_sInt32) (TriFace->eMappingV[i1]*Environment->vScale*TriFace->Material->EnvScaling); + eMappingU3=(pl_sInt32) (TriFace->eMappingU[i2]*Environment->uScale*TriFace->Material->EnvScaling); + eMappingV3=(pl_sInt32) (TriFace->eMappingV[i2]*Environment->vScale*TriFace->Material->EnvScaling); + + U1 = U2 = MappingU1; + V1 = V2 = MappingV1; + eU1 = eU2 = eMappingU1; + eV1 = eV2 = eMappingV1; + X2 = X1 = TriFace->Scrx[i0]; + Z2 = Z1 = TriFace->Scrz[i0]; + Y0 = (TriFace->Scry[i0]+(1<<19))>>20; + Y1 = (TriFace->Scry[i1]+(1<<19))>>20; + Y2 = (TriFace->Scry[i2]+(1<<19))>>20; + + dY = Y2 - Y0; + if (dY) { + dU2 = (MappingU3 - U1) / dY; + dV2 = (MappingV3 - V1) / dY; + edU2 = (eMappingU3 - eU1) / dY; + edV2 = (eMappingV3 - eV1) / dY; + dX2 = (TriFace->Scrx[i2] - X1) / dY; + dZ2 = (TriFace->Scrz[i2] - Z1) / dY; + } + dY = Y1-Y0; + if (dY) { + dX1 = (TriFace->Scrx[i1] - X1) / dY; + dU1 = (MappingU2 - U1) / dY; + dV1 = (MappingV2 - V1) / dY; + edU1 = (eMappingU2 - eU1) / dY; + edV1 = (eMappingV2 - eV1) / dY; + dZ1 = (TriFace->Scrz[i1] - Z1) / dY; + if (dX2 < dX1) { + dX2 ^= dX1; dX1 ^= dX2; dX2 ^= dX1; + dU2 ^= dU1; dU1 ^= dU2; dU2 ^= dU1; + dV2 ^= dV1; dV1 ^= dV2; dV2 ^= dV1; + edU2 ^= edU1; edU1 ^= edU2; edU2 ^= edU1; + edV2 ^= edV1; edV1 ^= edV2; edV2 ^= edV1; + dZL = dZ1; dZ1 = dZ2; dZ2 = dZL; + stat = 2; + } else stat = 1; + } else { + if (TriFace->Scrx[i1] > X1) { + X2 = TriFace->Scrx[i1]; + Z2 = TriFace->Scrz[i1]; + U2 = MappingU2; + V2 = MappingV2; + eU2 = eMappingU2; + eV2 = eMappingV2; + stat = 2|4; + } else { + X1 = TriFace->Scrx[i1]; + Z1 = TriFace->Scrz[i1]; + U1 = MappingU2; + V1 = MappingV2; + eU1 = eMappingU2; + eV1 = eMappingV2; + stat = 1|8; + } + } + + gmem += (Y0 * cam->ScreenWidth); + zbuf += (Y0 * cam->ScreenWidth); + + XL1 = (((dX1-dX2)*dY+(1<<19))>>20); + if (XL1) { + dUL = ((dU1-dU2)*dY)/XL1; + dVL = ((dV1-dV2)*dY)/XL1; + edUL = ((edU1-edU2)*dY)/XL1; + edVL = ((edV1-edV2)*dY)/XL1; + dZL = ((dZ1-dZ2)*dY)/XL1; + } else { + XL1 = ((X2-X1+(1<<19))>>20); + if (XL1) { + edUL = (eU2-eU1)/XL1; + edVL = (eV2-eV1)/XL1; + dUL = (U2-U1)/XL1; + dVL = (V2-V1)/XL1; + dZL = (Z2-Z1)/XL1; + } + } + + while (Y0 < Y2) { + if (Y0 == Y1) { + dY = Y2 - ((TriFace->Scry[i1]+(1<<19))>>20); + if (dY) { + if (stat & 1) { + X1 = TriFace->Scrx[i1]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 2) { + X2 = TriFace->Scrx[i1]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 4) { + X1 = TriFace->Scrx[i0]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + if (stat & 8) { + X2 = TriFace->Scrx[i0]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + dZ1 = (TriFace->Scrz[i2]-Z1)/dY; + dV1 = (MappingV3 - V1) / dY; + dU1 = (MappingU3 - U1) / dY; + edV1 = (eMappingV3 - eV1) / dY; + edU1 = (eMappingU3 - eU1) / dY; + } + } + XL1 = (X1+(1<<19))>>20; + XL2 = (X2+(1<<19))>>20; + ZL = Z1; + UL = U1; + VL = V1; + eUL = eU1; + eVL = eV1; + if ((XL2-XL1) > 0) { + XL2 -= XL1; + gmem += XL1; + zbuf += XL1; + XL1 += XL2; + if (zb) do { + if (*zbuf < ZL) { + *zbuf = ZL; + *gmem = remap[addtable[environment[ + ((eUL>>16)&eMappingU_AND)+((eVL>>evshift)&eMappingV_AND)]] + + texture[((UL>>16)&MappingU_AND) + + ((VL>>vshift)&MappingV_AND)]]; + } + zbuf++; + gmem++; + ZL += dZL; + UL += dUL; + VL += dVL; + eUL += edUL; + eVL += edVL; + } while (--XL2); + else do { + *gmem++ = remap[addtable[environment[ + ((eUL>>16)&eMappingU_AND)+((eVL>>evshift)&eMappingV_AND)]] + + texture[((UL>>16)&MappingU_AND) + + ((VL>>vshift)&MappingV_AND)]]; + UL += dUL; + VL += dVL; + eUL += edUL; + eVL += edVL; + } while (--XL2); + gmem -= XL1; + zbuf -= XL1; + } + zbuf += cam->ScreenWidth; + gmem += cam->ScreenWidth; + Z1 += dZ1; + X1 += dX1; + X2 += dX2; + U1 += dU1; + V1 += dV1; + eU1 += edU1; + eV1 += edV1; + Y0++; + } +} + +void plPF_TexF(pl_Cam *cam, pl_Face *TriFace) { + pl_uChar i0, i1, i2; + pl_uChar *gmem = cam->frameBuffer; + pl_ZBuffer *zbuf = cam->zBuffer; + pl_sInt32 MappingU1, MappingU2, MappingU3; + pl_sInt32 MappingV1, MappingV2, MappingV3; + pl_sInt32 MappingU_AND, MappingV_AND; + pl_uChar *texture; + pl_uChar vshift; + pl_uInt bc; + pl_uChar *remap; + pl_Texture *Texture; + pl_uChar stat; + + pl_ZBuffer Z1, ZL, dZ1=0, dZL=0, Z2, dZ2=0; + pl_sInt32 dU1=0, dV1=0, dU2=0, dV2=0, U1, V1, U2, V2; + pl_sInt32 dUL=0, dVL=0, UL, VL; + pl_sInt32 X1, X2, dX1=0, dX2=0, XL1, XL2; + pl_sInt32 Y1, Y2, Y0, dY; + pl_Bool zb = (zbuf&&TriFace->Material->zBufferable) ? 1 : 0; + pl_sInt shade; + + if (TriFace->Material->Environment) Texture = TriFace->Material->Environment; + else Texture = TriFace->Material->Texture; + + if (!Texture) return; + remap = TriFace->Material->_ReMapTable; + if (TriFace->Material->_AddTable) + { + shade=(pl_sInt)(TriFace->fShade*255.0f); + if (shade < 0) shade=0; + if (shade > 255) shade=255; + bc = TriFace->Material->_AddTable[shade]; + } + else bc=0; + texture = Texture->Data; + vshift = 16 - Texture->Width; + MappingV_AND = ((1<<Texture->Height)-1)<<Texture->Width; + MappingU_AND = (1<<Texture->Width)-1; + + if (TriFace->Material->Environment) { + PUTFACE_SORT_ENV(); + } else { + PUTFACE_SORT_TEX(); + } + + U1 = U2 = MappingU1; + V1 = V2 = MappingV1; + X2 = X1 = TriFace->Scrx[i0]; + Z2 = Z1 = TriFace->Scrz[i0]; + Y0 = (TriFace->Scry[i0]+(1<<19))>>20; + Y1 = (TriFace->Scry[i1]+(1<<19))>>20; + Y2 = (TriFace->Scry[i2]+(1<<19))>>20; + + dY = Y2 - Y0; + if (dY) { + dX2 = (TriFace->Scrx[i2] - X1) / dY; + dV2 = (MappingV3 - V1) / dY; + dU2 = (MappingU3 - U1) / dY; + dZ2 = (TriFace->Scrz[i2] - Z1) / dY; + } + dY = Y1-Y0; + if (dY) { + dX1 = (TriFace->Scrx[i1] - X1) / dY; + dZ1 = (TriFace->Scrz[i1] - Z1) / dY; + dU1 = (MappingU2 - U1) / dY; + dV1 = (MappingV2 - V1) / dY; + if (dX2 < dX1) { + dX2 ^= dX1; dX1 ^= dX2; dX2 ^= dX1; + dU2 ^= dU1; dU1 ^= dU2; dU2 ^= dU1; + dV2 ^= dV1; dV1 ^= dV2; dV2 ^= dV1; + dZL = dZ1; dZ1 = dZ2; dZ2 = dZL; + stat = 2; + } else stat = 1; + } else { + if (TriFace->Scrx[i1] > X1) { + X2 = TriFace->Scrx[i1]; + Z2 = TriFace->Scrz[i1]; + U2 = MappingU2; + V2 = MappingV2; + stat = 2|4; + } else { + X1 = TriFace->Scrx[i1]; + Z1 = TriFace->Scrz[i1]; + U1 = MappingU2; + V1 = MappingV2; + stat = 1|8; + } + } + + gmem += (Y0 * cam->ScreenWidth); + zbuf += (Y0 * cam->ScreenWidth); + + XL1 = (((dX1-dX2)*dY+(1<<19))>>20); + if (XL1) { + dUL = ((dU1-dU2)*dY)/XL1; + dVL = ((dV1-dV2)*dY)/XL1; + dZL = ((dZ1-dZ2)*dY)/XL1; + } else { + XL1 = ((X2-X1+(1<<19))>>20); + if (XL1) { + dUL = (U2-U1)/XL1; + dVL = (V2-V1)/XL1; + dZL = (Z2-Z1)/XL1; + } + } + + while (Y0 < Y2) { + if (Y0 == Y1) { + dY = Y2 - ((TriFace->Scry[i1]+(1<<19))>>20); + if (dY) { + if (stat & 1) { + X1 = TriFace->Scrx[i1]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 2) { + X2 = TriFace->Scrx[i1]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 4) { + X1 = TriFace->Scrx[i0]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + if (stat & 8) { + X2 = TriFace->Scrx[i0]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + dZ1 = (TriFace->Scrz[i2]-Z1) / dY; + dV1 = (MappingV3 - V1) / dY; + dU1 = (MappingU3 - U1) / dY; + } + } + XL1 = (X1+(1<<19))>>20; + XL2 = (X2+(1<<19))>>20; + ZL = Z1; + UL = U1; + VL = V1; + if ((XL2-XL1) > 0) { + XL2 -= XL1; + gmem += XL1; + zbuf += XL1; + XL1 += XL2; + if (zb) do { + if (*zbuf < ZL) { + *zbuf = ZL; + *gmem = remap[bc + texture[((UL >> 16)&MappingU_AND) + + ((VL>>vshift)&MappingV_AND)]]; + } + zbuf++; + gmem++; + ZL += dZL; + UL += dUL; + VL += dVL; + } while (--XL2); + else do { + *gmem++ = remap[bc + texture[((UL >> 16)&MappingU_AND) + + ((VL>>vshift)&MappingV_AND)]]; + UL += dUL; + VL += dVL; + } while (--XL2); + gmem -= XL1; + zbuf -= XL1; + } + zbuf += cam->ScreenWidth; + gmem += cam->ScreenWidth; + X1 += dX1; + X2 += dX2; + U1 += dU1; + V1 += dV1; + Z1 += dZ1; + Y0++; + } +} + +void plPF_TexG(pl_Cam *cam, pl_Face *TriFace) { + pl_uChar i0, i1, i2; + pl_uChar *gmem = cam->frameBuffer; + pl_ZBuffer *zbuf = cam->zBuffer; + pl_sInt32 MappingU1, MappingU2, MappingU3; + pl_sInt32 MappingV1, MappingV2, MappingV3; + pl_sInt32 MappingU_AND, MappingV_AND; + pl_uChar *texture; + pl_uChar *remap; + pl_uChar vshift; + pl_uInt16 *addtable; + pl_Texture *Texture; + + pl_sInt32 U1, V1, U2, V2, dU1=0, dU2=0, dV1=0, dV2=0, dUL=0, dVL=0, UL, VL; + pl_sInt32 X1, X2, dX1=0, dX2=0, XL1, XL2; + pl_sInt32 C1, C2, dC1=0, dC2=0, CL, dCL=0; + pl_ZBuffer Z1, ZL, dZ1=0, dZ2=0, dZL=0, Z2; + pl_sInt32 Y1, Y2, Y0, dY; + pl_uChar stat; + + pl_Bool zb = (zbuf&&TriFace->Material->zBufferable) ? 1 : 0; + + if (TriFace->Material->Environment) Texture = TriFace->Material->Environment; + else Texture = TriFace->Material->Texture; + + if (!Texture) return; + remap = TriFace->Material->_ReMapTable; + texture = Texture->Data; + addtable = TriFace->Material->_AddTable; + vshift = 16 - Texture->Width; + MappingV_AND = ((1<<Texture->Height)-1)<<Texture->Width; + MappingU_AND = (1<<Texture->Width)-1; + + if (TriFace->Material->Environment) { + PUTFACE_SORT_ENV(); + } else { + PUTFACE_SORT_TEX(); + } + + C1 = C2 = TriFace->Shades[i0]*65535.0f; + U1 = U2 = MappingU1; + V1 = V2 = MappingV1; + X2 = X1 = TriFace->Scrx[i0]; + Z2 = Z1 = TriFace->Scrz[i0]; + Y0 = (TriFace->Scry[i0]+(1<<19))>>20; + Y1 = (TriFace->Scry[i1]+(1<<19))>>20; + Y2 = (TriFace->Scry[i2]+(1<<19))>>20; + + dY = Y2 - Y0; + if (dY) { + dX2 = (TriFace->Scrx[i2] - X1) / dY; + dZ2 = (TriFace->Scrz[i2] - Z1) / dY; + dC2 = (TriFace->Shades[i2]*65535.0f - C1) / dY; + dU2 = (MappingU3 - U1) / dY; + dV2 = (MappingV3 - V1) / dY; + } + dY = Y1-Y0; + if (dY) { + dX1 = (TriFace->Scrx[i1] - X1) / dY; + dZ1 = (TriFace->Scrz[i1] - Z1) / dY; + dC1 = (TriFace->Shades[i1]*65535.0f - C1) / dY; + dU1 = (MappingU2 - U1) / dY; + dV1 = (MappingV2 - V1) / dY; + if (dX2 < dX1) { + dX2 ^= dX1; dX1 ^= dX2; dX2 ^= dX1; + dU2 ^= dU1; dU1 ^= dU2; dU2 ^= dU1; + dV2 ^= dV1; dV1 ^= dV2; dV2 ^= dV1; + dC2 ^= dC1; dC1 ^= dC2; dC2 ^= dC1; + dZL = dZ1; dZ1 = dZ2; dZ2 = dZL; + stat = 2; + } else stat = 1; + } else { + if (TriFace->Scrx[i1] > X1) { + X2 = TriFace->Scrx[i1]; + Z2 = TriFace->Scrz[i1]; + C2 = TriFace->Shades[i1]*65535.0f; + U2 = MappingU2; + V2 = MappingV2; + stat = 2|4; + } else { + X1 = TriFace->Scrx[i1]; + Z1 = TriFace->Scrz[i1]; + C1 = TriFace->Shades[i1]*65535.0f; + U1 = MappingU2; + V1 = MappingV2; + stat = 1|8; + } + } + + gmem += (Y0 * cam->ScreenWidth); + zbuf += (Y0 * cam->ScreenWidth); + + XL1 = (((dX1-dX2)*dY+(1<<19))>>20); + if (XL1) { + dUL = ((dU1-dU2)*dY)/XL1; + dVL = ((dV1-dV2)*dY)/XL1; + if (zb) dZL = ((dZ1-dZ2)*dY)/XL1; + dCL = ((dC1-dC2)*dY)/XL1; + } else { + XL1 = ((X2-X1+(1<<19))>>20); + if (XL1) { + dUL = (U2-U1)/XL1; + dVL = (V2-V1)/XL1; + if (zb) dZL = (Z2-Z1)/XL1; + dCL = (C2-C1)/(XL1); + } + } + while (Y0 < Y2) { + if (Y0 == Y1) { + dY = Y2 - ((TriFace->Scry[i1]+(1<<19))>>20); + if (dY) { + if (stat & 1) { + X1 = TriFace->Scrx[i1]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 2) { + X2 = TriFace->Scrx[i1]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 4) { + X1 = TriFace->Scrx[i0]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + if (stat & 8) { + X2 = TriFace->Scrx[i0]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + dZ1 = (TriFace->Scrz[i2]-Z1)/dY; + dV1 = (MappingV3 - V1) / dY; + dU1 = (MappingU3 - U1) / dY; + dC1 = (TriFace->Shades[i2]*65535.0f-C1)/dY; + } + } + XL1 = (X1+(1<<19))>>20; + XL2 = (X2+(1<<19))>>20; + CL = C1; + ZL = Z1; + UL = U1; + VL = V1; + if ((XL2-XL1) > 0) { + XL2 -= XL1; + gmem += XL1; + zbuf += XL1; + XL1 += XL2; + if (zb) do { + if (*zbuf < ZL) { + int av; + if (CL < 0) av=addtable[0]; + else if (CL > (255<<8)) av=addtable[255]; + else av=addtable[CL>>8]; + *zbuf = ZL; + *gmem = remap[av + + texture[((UL>>16)&MappingU_AND) + + ((VL>>vshift)&MappingV_AND)]]; + } + zbuf++; + gmem++; + ZL += dZL; + CL += dCL; + UL += dUL; + VL += dVL; + } while (--XL2); + else do { + int av; + if (CL < 0) av=addtable[0]; + else if (CL > (255<<8)) av=addtable[255]; + else av=addtable[CL>>8]; + *gmem++ = remap[av + + texture[((UL>>16)&MappingU_AND) + + ((VL>>vshift)&MappingV_AND)]]; + CL += dCL; + UL += dUL; + VL += dVL; + } while (--XL2); + gmem -= XL1; + zbuf -= XL1; + } + zbuf += cam->ScreenWidth; + gmem += cam->ScreenWidth; + Z1 += dZ1; + X1 += dX1; + X2 += dX2; + C1 += dC1; + U1 += dU1; + V1 += dV1; + Y0++; + } +} diff --git a/Src/Winamp/plush/PF_TRANS.C b/Src/Winamp/plush/PF_TRANS.C new file mode 100644 index 00000000..d82365ee --- /dev/null +++ b/Src/Winamp/plush/PF_TRANS.C @@ -0,0 +1,263 @@ +/****************************************************************************** +Plush Version 1.2 +pf_trans.c +Solid Translucent Rasterizers +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" +#include "putface.h" + +void plPF_TransF(pl_Cam *cam, pl_Face *TriFace) { + pl_uChar i0, i1, i2; + pl_uChar *gmem = cam->frameBuffer; + pl_uChar *remap = TriFace->Material->_ReMapTable; + pl_ZBuffer *zbuf = cam->zBuffer; + pl_sInt32 X1, X2, dX1=0, dX2=0, XL1, XL2; + pl_ZBuffer Z1, ZL, dZ1=0, dZL=0, dZ2=0, Z2; + pl_sInt32 Y1, Y2, Y0, dY; + pl_uInt16 *lookuptable = TriFace->Material->_AddTable; + pl_uChar stat; + pl_sInt32 bc = (pl_sInt32) TriFace->fShade*TriFace->Material->_tsfact; + pl_Bool zb = (zbuf&&TriFace->Material->zBufferable) ? 1 : 0; + + PUTFACE_SORT(); + + if (bc < 0) bc=0; + if (bc > (pl_sInt32) TriFace->Material->_tsfact-1) bc=TriFace->Material->_tsfact-1; + remap+=bc; + + X2 = X1 = TriFace->Scrx[i0]; + Z2 = Z1 = TriFace->Scrz[i0]; + Y0 = (TriFace->Scry[i0]+(1<<19))>>20; + Y1 = (TriFace->Scry[i1]+(1<<19))>>20; + Y2 = (TriFace->Scry[i2]+(1<<19))>>20; + + dY = Y2 - Y0; + if (dY) { + dX2 = (TriFace->Scrx[i2] - X1) / dY; + dZ2 = (TriFace->Scrz[i2] - Z1) / dY; + } + dY = Y1-Y0; + if (dY) { + dX1 = (TriFace->Scrx[i1] - X1) / dY; + dZ1 = (TriFace->Scrz[i1] - Z1) / dY; + if (dX2 < dX1) { + dX2 ^= dX1; dX1 ^= dX2; dX2 ^= dX1; + dZL = dZ1; dZ1 = dZ2; dZ2 = dZL; + stat = 2; + } else stat = 1; + } else { + if (TriFace->Scrx[i1] > X1) { + X2 = TriFace->Scrx[i1]; + Z2 = TriFace->Scrz[i1]; + stat= 2|4; + } else { + X1 = TriFace->Scrx[i1]; + Z1 = TriFace->Scrz[i1]; + stat= 1|8; + } + } + + gmem += (Y0 * cam->ScreenWidth); + zbuf += (Y0 * cam->ScreenWidth); + if (zb) { + XL1 = (((dX1-dX2)*dY+(1<<19))>>20); + if (XL1) dZL = ((dZ1-dZ2)*dY)/XL1; + else { + XL1 = ((X2-X1+(1<<19))>>20); + if (XL1) dZL = (Z2-Z1)/XL1; + } + } + + while (Y0 < Y2) { + if (Y0 == Y1) { + dY = Y2 - ((TriFace->Scry[i1]+(1<<19))>>20); + if (dY) { + if (stat & 1) { + X1 = TriFace->Scrx[i1]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 2) { + X2 = TriFace->Scrx[i1]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 4) { + X1 = TriFace->Scrx[i0]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + if (stat & 8) { + X2 = TriFace->Scrx[i0]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + dZ1 = (TriFace->Scrz[i2]- Z1)/dY; + } + } + XL1 = (X1+(1<<19))>>20; + XL2 = (X2+(1<<19))>>20; + ZL = Z1; + if ((XL2-XL1) > 0) { + XL2 -= XL1; + zbuf += XL1; + gmem += XL1; + XL1 += XL2; + if (zb) do { + if (*zbuf < ZL) { + *zbuf = ZL; + *gmem = remap[lookuptable[*gmem]]; + } + gmem++; + zbuf++; + ZL += dZL; + } while (--XL2); + else do *gmem++ = remap[lookuptable[*gmem]]; while (--XL2); + gmem -= XL1; + zbuf -= XL1; + } + gmem += cam->ScreenWidth; + zbuf += cam->ScreenWidth; + Z1 += dZ1; + X1 += dX1; + X2 += dX2; + Y0 ++; + } +} + +void plPF_TransG(pl_Cam *cam, pl_Face *TriFace) { + pl_uChar i0, i1, i2; + pl_uChar *gmem = cam->frameBuffer; + pl_uChar *remap = TriFace->Material->_ReMapTable; + pl_ZBuffer *zbuf = cam->zBuffer; + pl_sInt32 X1, X2, dX1=0, dX2=0, XL1, XL2; + pl_ZBuffer Z1, ZL, dZ1=0, dZL=0, dZ2=0, Z2; + pl_sInt32 dC1=0, dCL=0, CL, C1, C2, dC2=0; + pl_sInt32 Y1, Y2, Y0, dY; + pl_Float nc = (TriFace->Material->_tsfact*65536.0f); + pl_uInt16 *lookuptable = TriFace->Material->_AddTable; + pl_Bool zb = (zbuf&&TriFace->Material->zBufferable) ? 1 : 0; + pl_uChar stat; + + pl_sInt32 maxColor=((TriFace->Material->_tsfact-1)<<16); + pl_sInt32 maxColorNonShift=TriFace->Material->_tsfact-1; + + PUTFACE_SORT(); + + C1 = C2 = (pl_sInt32) (TriFace->Shades[i0]*nc); + X2 = X1 = TriFace->Scrx[i0]; + Z2 = Z1 = TriFace->Scrz[i0]; + Y0 = (TriFace->Scry[i0]+(1<<19))>>20; + Y1 = (TriFace->Scry[i1]+(1<<19))>>20; + Y2 = (TriFace->Scry[i2]+(1<<19))>>20; + + dY = Y2 - Y0; + if (dY) { + dX2 = (TriFace->Scrx[i2] - X1) / dY; + dC2 = (pl_sInt32) ((TriFace->Shades[i2]*nc - C1) / dY); + dZ2 = (TriFace->Scrz[i2] - Z1) / dY; + } + dY = Y1-Y0; + if (dY) { + dX1 = (TriFace->Scrx[i1] - X1) / dY; + dZ1 = (TriFace->Scrz[i1] - Z1) / dY; + dC1 = (pl_sInt32) ((TriFace->Shades[i1]*nc - C1) / dY); + if (dX2 < dX1) { + dX2 ^= dX1; dX1 ^= dX2; dX2 ^= dX1; + dC2 ^= dC1; dC1 ^= dC2; dC2 ^= dC1; + dZL = dZ1; dZ1 = dZ2; dZ2 = dZL; + stat = 2; + } else stat = 1; + } else { + if (TriFace->Scrx[i1] > X1) { + X2 = TriFace->Scrx[i1]; + Z2 = TriFace->Scrz[i1]; + C2 = (pl_sInt32) (TriFace->Shades[i1]*nc); + stat = 2|4; + } else { + X1 = TriFace->Scrx[i1]; + Z1 = TriFace->Scrz[i1]; + C1 = (pl_sInt32) (TriFace->Shades[i1]*nc); + stat = 1|8; + } + } + + gmem += (Y0 * cam->ScreenWidth); + zbuf += (Y0 * cam->ScreenWidth); + XL1 = (((dX1-dX2)*dY+(1<<19))>>20); + if (XL1) { + dCL = ((dC1-dC2)*dY)/XL1; + dZL = ((dZ1-dZ2)*dY)/XL1; + } else { + XL1 = ((X2-X1+(1<<19))>>20); + if (XL1) { + dCL = (C2-C1)/XL1; + dZL = (Z2-Z1)/XL1; + } + } + + while (Y0 < Y2) { + if (Y0 == Y1) { + dY = Y2 - ((TriFace->Scry[i1]+(1<<19))>>20); + if (dY) { + if (stat & 1) { + X1 = TriFace->Scrx[i1]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 2) { + X2 = TriFace->Scrx[i1]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY; + } + if (stat & 4) { + X1 = TriFace->Scrx[i0]; + dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + if (stat & 8) { + X2 = TriFace->Scrx[i0]; + dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY; + } + dZ1 = (TriFace->Scrz[i2]-Z1)/dY; + dC1 = (pl_sInt32) ((TriFace->Shades[i2]*nc - C1) / dY); + } + } + CL = C1; + XL1 = (X1+(1<<19))>>20; + XL2 = (X2+(1<<19))>>20; + ZL = Z1; + if ((XL2-XL1) > 0) { + XL2 -= XL1; + zbuf += XL1; + gmem += XL1; + XL1 += XL2; + if (zb) do { + if (*zbuf < ZL) { + int av; + if (CL >= maxColor) av=maxColorNonShift; + else if (CL > 0) av=CL>>16; + else av=0; + *zbuf = ZL; + *gmem = remap[av + lookuptable[*gmem]]; + } + gmem++; + CL += dCL; + zbuf++; + ZL += dZL; + } while (--XL2); + else do { + int av; + if (CL >= maxColor) av=maxColorNonShift; + else if (CL > 0) av=CL>>16; + else av=0; + *gmem++ = remap[av + lookuptable[*gmem]]; + CL += dCL; + } while (--XL2); + gmem -= XL1; + zbuf -= XL1; + } + gmem += cam->ScreenWidth; + zbuf += cam->ScreenWidth; + Z1 += dZ1; + X1 += dX1; + X2 += dX2; + C1 += dC1; + Y0++; + } +} diff --git a/Src/Winamp/plush/PLUSH.C b/Src/Winamp/plush/PLUSH.C new file mode 100644 index 00000000..173fb389 --- /dev/null +++ b/Src/Winamp/plush/PLUSH.C @@ -0,0 +1,286 @@ +/****************************************************************************** +Plush Version 1.2 +plush.c +Misc code and data +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +pl_uChar plText_DefaultFont[256*16] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 60, 66, 129, 231, 165, 153, 129, 153, 66, 60, 0, 0, 0, 0, + 0, 0, 60, 126, 255, 153, 219, 231, 255, 231, 126, 60, 0, 0, 0, 0, + 0, 0, 0, 0, 102, 255, 255, 255, 255, 126, 60, 24, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 60, 126, 255, 126, 60, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 24, 60, 60, 90, 255, 255, 90, 24, 60, 0, 0, 0, 0, + 0, 0, 0, 24, 60, 126, 255, 255, 255, 90, 24, 60, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 60, 60, 24, 0, 0, 0, 0, 0, 0, + 255,255,255, 255, 255, 255, 231, 195, 195, 231, 255, 255, 255, 255, 255, 255, + 0, 0, 0, 0, 0, 60, 102, 66, 66, 102, 60, 0, 0, 0, 0, 0, + 255,255,255, 255, 255, 195, 153, 189, 189, 153, 195, 255, 255, 255, 255, 255, + 0, 0, 15, 7, 13, 24, 62, 99, 195, 195, 198, 124, 0, 0, 0, 0, + 0, 0, 126, 195, 195, 195, 126, 24, 24, 30, 120, 24, 0, 0, 0, 0, + 0, 0, 8, 12, 14, 11, 8, 8, 8, 120, 248, 112, 0, 0, 0, 0, + 0, 16, 24, 28, 22, 26, 22, 18, 114, 242, 98, 14, 30, 12, 0, 0, + 0, 0, 24, 24, 219, 126, 60, 255, 60, 126, 219, 24, 24, 0, 0, 0, + 0, 0, 96, 112, 120, 124, 126, 126, 124, 120, 112, 96, 0, 0, 0, 0, + 0, 0, 6, 14, 30, 62, 126, 126, 62, 30, 14, 6, 0, 0, 0, 0, + 0, 0, 16, 56, 124, 254, 56, 56, 56, 56, 254, 124, 56, 16, 0, 0, + 0, 0, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 0, 0, 0, 0, + 0, 0, 63, 123, 219, 219, 219, 127, 59, 27, 27, 27, 0, 0, 0, 0, + 0, 31, 48, 120, 220, 206, 231, 115, 59, 30, 12, 24, 48, 224, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 126, 126, 126, 126, 0, 0, 0, 0, + 0, 0, 16, 56, 124, 254, 56, 56, 56, 254, 124, 56, 16, 0, 254, 0, + 0, 0, 16, 56, 124, 254, 56, 56, 56, 56, 56, 56, 56, 56, 0, 0, + 0, 0, 56, 56, 56, 56, 56, 56, 56, 56, 254, 124, 56, 16, 0, 0, + 0, 0, 0, 0, 0, 8, 12, 254, 255, 254, 12, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 16, 48, 127, 255, 127, 48, 16, 0, 0, 0, 0, + 0, 0, 204, 102, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 36, 102, 255, 255, 102, 36, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 60, 60, 126, 126, 255, 255, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 126, 126, 60, 60, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, 0, 0, 0, 0, + 0, 0, 51, 102, 204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 51, 51, 255, 102, 102, 102, 102, 255, 204, 204, 0, 0, 0, 0, + 0, 24, 126, 219, 216, 120, 28, 30, 27, 219, 219, 126, 24, 0, 0, 0, + 0, 0, 96, 209, 179, 102, 12, 24, 54, 109, 203, 6, 0, 0, 0, 0, + 0, 0, 28, 54, 102, 60, 56, 108, 199, 198, 110, 59, 0, 0, 0, 0, + 0, 0, 12, 24, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 12, 24, 48, 48, 96, 96, 96, 96, 48, 48, 24, 12, 0, 0, 0, + 0, 48, 24, 12, 12, 6, 6, 6, 6, 12, 12, 24, 48, 0, 0, 0, + 0, 0, 102, 60, 255, 60, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 24, 24, 126, 24, 24, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 24, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 0, 0, 0, 0, + 0, 0, 6, 4, 12, 8, 24, 16, 48, 32, 96, 64, 192, 0, 0, 0, + 0, 0, 62, 99, 195, 195, 195, 207, 219, 243, 198, 124, 0, 0, 0, 0, + 0, 0, 12, 28, 60, 108, 12, 12, 12, 12, 12, 12, 0, 0, 0, 0, + 0, 0, 62, 99, 195, 3, 6, 12, 24, 48, 99, 255, 0, 0, 0, 0, + 0, 0, 255, 198, 12, 24, 62, 3, 3, 195, 198, 124, 0, 0, 0, 0, + 0, 0, 6, 14, 30, 54, 102, 199, 222, 246, 6, 6, 0, 0, 0, 0, + 0, 0, 31, 240, 192, 220, 246, 3, 3, 195, 198, 124, 0, 0, 0, 0, + 0, 0, 60, 102, 198, 192, 220, 246, 198, 198, 204, 120, 0, 0, 0, 0, + 0, 0, 255, 195, 6, 12, 12, 24, 24, 48, 48, 48, 0, 0, 0, 0, + 0, 0, 60, 102, 198, 108, 62, 99, 195, 195, 198, 124, 0, 0, 0, 0, + 0, 0, 60, 102, 198, 198, 222, 118, 6, 198, 204, 120, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 24, 0, 0, 0, 24, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 24, 0, 0, 0, 24, 24, 48, 0, 0, 0, 0, + 0, 0, 6, 12, 24, 48, 96, 96, 48, 24, 12, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 255, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 96, 48, 24, 12, 6, 6, 12, 24, 48, 96, 0, 0, 0, 0, + 0, 0, 62, 99, 198, 12, 24, 48, 48, 0, 48, 48, 0, 0, 0, 0, + 0, 0, 30, 51, 111, 219, 219, 219, 222, 216, 198, 220, 112, 0, 0, 0, + 0, 0, 24, 24, 60, 36, 102, 110, 122, 227, 195, 195, 0, 0, 0, 0, + 0, 0, 30, 51, 227, 198, 220, 247, 195, 198, 220, 240, 0, 0, 0, 0, + 0, 0, 30, 51, 96, 192, 192, 192, 192, 192, 99, 62, 0, 0, 0, 0, + 0, 0, 252, 198, 195, 195, 195, 195, 195, 198, 220, 240, 0, 0, 0, 0, + 0, 0, 30, 240, 192, 192, 220, 240, 192, 192, 222, 240, 0, 0, 0, 0, + 0, 0, 30, 240, 192, 192, 220, 240, 192, 192, 192, 192, 0, 0, 0, 0, + 0, 0, 62, 99, 192, 192, 192, 207, 195, 195, 102, 60, 0, 0, 0, 0, + 0, 0, 195, 195, 195, 195, 207, 251, 195, 195, 195, 195, 0, 0, 0, 0, + 0, 0, 28, 56, 24, 24, 24, 24, 24, 24, 28, 56, 0, 0, 0, 0, + 0, 0, 3, 3, 3, 3, 3, 3, 195, 195, 99, 62, 0, 0, 0, 0, + 0, 0, 195, 198, 220, 240, 224, 240, 216, 204, 198, 195, 0, 0, 0, 0, + 0, 0, 192, 192, 192, 192, 192, 192, 192, 192, 222, 240, 0, 0, 0, 0, + 0, 0, 195, 195, 231, 239, 251, 211, 195, 195, 195, 195, 0, 0, 0, 0, + 0, 0, 195, 195, 227, 243, 211, 219, 207, 199, 195, 195, 0, 0, 0, 0, + 0, 0, 62, 99, 195, 195, 195, 195, 195, 195, 198, 124, 0, 0, 0, 0, + 0, 0, 30, 51, 227, 195, 198, 220, 240, 192, 192, 192, 0, 0, 0, 0, + 0, 0, 62, 99, 195, 195, 195, 195, 243, 222, 204, 124, 6, 3, 0, 0, + 0, 0, 30, 51, 227, 195, 198, 252, 216, 204, 198, 195, 0, 0, 0, 0, + 0, 0, 126, 195, 192, 112, 28, 6, 3, 195, 195, 126, 0, 0, 0, 0, + 0, 0, 15, 248, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, + 0, 0, 195, 195, 195, 195, 195, 195, 198, 198, 204, 120, 0, 0, 0, 0, + 0, 0, 195, 195, 195, 195, 102, 102, 124, 56, 48, 48, 0, 0, 0, 0, + 0, 0, 195, 195, 195, 195, 219, 219, 219, 255, 231, 195, 0, 0, 0, 0, + 0, 0, 195, 195, 102, 102, 60, 60, 102, 102, 195, 195, 0, 0, 0, 0, + 0, 0, 195, 195, 102, 102, 60, 24, 24, 24, 24, 24, 0, 0, 0, 0, + 0, 0, 31, 246, 4, 12, 24, 16, 48, 32, 111, 248, 0, 0, 0, 0, + 0, 62, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 62, 0, 0, 0, + 0, 0, 192, 64, 96, 32, 48, 16, 24, 8, 12, 4, 6, 0, 0, 0, + 0, 124, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 124, 0, 0, 0, + 0, 24, 60, 102, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, + 0, 0, 48, 24, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 62, 99, 31, 115, 195, 207, 123, 0, 0, 0, 0, + 0, 0, 192, 192, 192, 220, 246, 195, 195, 198, 220, 240, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 51, 96, 192, 192, 195, 126, 0, 0, 0, 0, + 0, 0, 3, 3, 3, 31, 115, 195, 199, 207, 219, 115, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 62, 99, 206, 248, 192, 195, 126, 0, 0, 0, 0, + 0, 0, 30, 51, 48, 48, 60, 240, 48, 48, 48, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 63, 99, 195, 199, 207, 219, 115, 3, 195, 126, 0, + 0, 0, 192, 192, 192, 206, 219, 243, 227, 195, 195, 195, 0, 0, 0, 0, + 0, 0, 24, 24, 0, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, + 0, 0, 12, 12, 0, 12, 12, 12, 12, 12, 12, 12, 204, 204, 120, 0, + 0, 0, 192, 192, 192, 198, 204, 216, 248, 236, 198, 195, 0, 0, 0, 0, + 0, 0, 56, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 230, 219, 219, 219, 195, 195, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 206, 219, 243, 227, 195, 195, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 62, 99, 195, 195, 195, 198, 124, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 206, 219, 243, 227, 195, 198, 252, 192, 192, 192, 0, + 0, 0, 0, 0, 0, 115, 219, 207, 199, 195, 99, 63, 3, 3, 3, 0, + 0, 0, 0, 0, 0, 206, 219, 243, 224, 192, 192, 192, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 126, 195, 112, 30, 3, 195, 126, 0, 0, 0, 0, + 0, 0, 16, 48, 48, 60, 240, 48, 48, 54, 60, 24, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 195, 195, 195, 199, 207, 219, 115, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 195, 195, 195, 102, 108, 56, 24, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 195, 195, 195, 219, 219, 255, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 195, 102, 60, 24, 60, 102, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 195, 195, 195, 195, 195, 102, 62, 12, 216, 112, 0, + 0, 0, 0, 0, 0, 255, 6, 12, 24, 48, 96, 255, 0, 0, 0, 0, + 0, 14, 24, 24, 24, 24, 112, 112, 24, 24, 24, 24, 14, 0, 0, 0, + 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, + 0, 112, 24, 24, 24, 24, 14, 14, 24, 24, 24, 24, 112, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 118, 220, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 16, 56, 108, 198, 198, 198, 254, 0, 0, 0, 0, 0, + 0, 0, 30, 51, 96, 192, 192, 192, 192, 192, 99, 62, 12, 24, 240, 0, + 0, 0, 102, 102, 0, 195, 195, 195, 199, 207, 219, 115, 0, 0, 0, 0, + 0, 6, 12, 24, 0, 62, 99, 206, 248, 192, 195, 126, 0, 0, 0, 0, + 12, 30, 51, 96, 0, 62, 99, 31, 115, 195, 207, 123, 0, 0, 0, 0, + 0, 0, 54, 54, 0, 62, 99, 31, 115, 195, 207, 123, 0, 0, 0, 0, + 0, 48, 24, 12, 0, 62, 99, 31, 115, 195, 207, 123, 0, 0, 0, 0, + 28, 54, 54, 28, 0, 62, 99, 31, 115, 195, 207, 123, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 51, 96, 192, 192, 195, 126, 12, 24, 240, 0, + 24, 60, 102, 192, 0, 62, 99, 206, 248, 192, 195, 126, 0, 0, 0, 0, + 0, 0, 102, 102, 0, 62, 99, 206, 248, 192, 195, 126, 0, 0, 0, 0, + 0, 96, 48, 24, 0, 62, 99, 206, 248, 192, 195, 126, 0, 0, 0, 0, + 0, 0, 102, 102, 0, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, + 24, 60, 102, 192, 0, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, + 0, 96, 48, 24, 0, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, + 102, 102, 24, 24, 60, 36, 102, 102, 126, 195, 195, 195, 0, 0, 0, 0, + 24, 36, 36, 24, 60, 36, 102, 102, 126, 195, 195, 195, 0, 0, 0, 0, + 24, 48, 96, 30, 240, 192, 222, 240, 192, 192, 222, 240, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 126, 219, 59, 126, 220, 219, 110, 0, 0, 0, 0, + 0, 0, 63, 62, 60, 108, 111, 110, 124, 204, 207, 206, 0, 0, 0, 0, + 24, 60, 102, 192, 0, 62, 99, 195, 195, 195, 198, 124, 0, 0, 0, 0, + 0, 0, 102, 102, 0, 62, 99, 195, 195, 195, 198, 124, 0, 0, 0, 0, + 0, 96, 48, 24, 0, 62, 99, 195, 195, 195, 198, 124, 0, 0, 0, 0, + 24, 60, 102, 192, 0, 195, 195, 195, 199, 207, 219, 115, 0, 0, 0, 0, + 0, 96, 48, 24, 0, 195, 195, 195, 199, 207, 219, 115, 0, 0, 0, 0, + 0, 0, 102, 102, 0, 195, 195, 195, 195, 195, 102, 62, 12, 216, 112, 0, + 102, 0, 62, 99, 195, 195, 195, 195, 195, 195, 198, 124, 0, 0, 0, 0, + 102, 0, 195, 195, 195, 195, 195, 195, 198, 198, 204, 120, 0, 0, 0, 0, + 0, 0, 0, 8, 8, 30, 59, 104, 200, 200, 203, 126, 8, 8, 0, 0, + 0, 0, 60, 102, 96, 248, 96, 248, 96, 96, 99, 126, 0, 0, 0, 0, + 0, 0, 195, 195, 102, 102, 60, 24, 126, 24, 126, 24, 24, 0, 0, 0, + 0, 0, 30, 51, 227, 195, 198, 220, 248, 204, 222, 204, 15, 14, 4, 0, + 0, 0, 30, 51, 48, 48, 60, 240, 48, 48, 48, 48, 224, 0, 0, 0, + 0, 6, 12, 24, 0, 62, 99, 31, 115, 195, 207, 123, 0, 0, 0, 0, + 0, 6, 12, 24, 0, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, + 0, 6, 12, 24, 0, 62, 99, 195, 195, 195, 198, 124, 0, 0, 0, 0, + 0, 12, 24, 48, 0, 195, 195, 195, 199, 207, 219, 115, 0, 0, 0, 0, + 0, 3, 118, 220, 0, 206, 219, 243, 227, 195, 195, 195, 0, 0, 0, 0, + 3, 118, 220, 0, 195, 227, 243, 211, 219, 207, 199, 195, 0, 0, 0, 0, + 0, 0, 62, 99, 31, 115, 195, 207, 123, 0, 0, 255, 0, 0, 0, 0, + 0, 0, 62, 99, 195, 195, 195, 198, 124, 0, 0, 255, 0, 0, 0, 0, + 0, 0, 12, 12, 0, 12, 12, 24, 48, 99, 198, 124, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 254, 192, 192, 192, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 254, 6, 6, 6, 0, 0, 0, 0, 0, 0, + 0, 96, 225, 99, 102, 108, 24, 48, 96, 206, 155, 6, 13, 31, 0, 0, + 0, 96, 225, 99, 102, 108, 24, 48, 102, 206, 151, 62, 6, 6, 0, 0, + 0, 0, 24, 24, 0, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 54, 108, 216, 216, 108, 54, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 108, 54, 27, 27, 54, 108, 192, 0, 0, 0, 0, + 130, 16, 130, 16, 130, 16, 130, 16, 130, 16, 130, 16, 130, 16, 130, 16, + 0, 149, 0, 169, 0, 149, 0, 169, 0, 149, 0, 169, 0, 149, 0, 169, + 146, 73, 146, 73, 146, 73, 146, 73, 146, 73, 146, 73, 146, 73, 146, 73, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 248, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 248, 248, 248, 24, 24, 24, 24, 24, 24, 24, + 60, 60, 60, 60, 60, 60, 60, 60, 252, 60, 60, 60, 60, 60, 60, 60, + 0, 0, 0, 0, 0, 0, 0, 0, 252, 60, 60, 60, 60, 60, 60, 60, + 0, 0, 0, 0, 0, 0, 248, 248, 248, 24, 24, 24, 24, 24, 24, 24, + 60, 60, 60, 60, 60, 60, 252, 252, 252, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 0, 0, 0, 0, 0, 0, 252, 252, 252, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 252, 252, 252, 0, 0, 0, 0, 0, 0, 0, + 60, 60, 60, 60, 60, 60, 60, 60, 252, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 248, 248, 248, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 248, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 31, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 255, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 255, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 31, 24, 24, 24, 24, 24, 24, 24, + 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 255, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 31, 31, 31, 24, 24, 24, 24, 24, 24, 24, + 60, 60, 60, 60, 60, 60, 60, 60, 63, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 63, 63, 63, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, + 60, 60, 60, 60, 60, 60, 255, 255, 255, 60, 60, 60, 60, 60, 60, 60, + 24, 24, 24, 24, 24, 24, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, + 60, 60, 60, 60, 60, 60, 60, 60, 255, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 255, 255, 255, 24, 24, 24, 24, 24, 24, 24, + 0, 0, 0, 0, 0, 0, 0, 0, 255, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 63, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 31, 31, 31, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 31, 31, 31, 24, 24, 24, 24, 24, 24, 24, + 0, 0, 0, 0, 0, 0, 0, 0, 63, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 255, 60, 60, 60, 60, 60, 60, 60, + 24, 24, 24, 24, 24, 24, 255, 255, 255, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 248, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 31, 24, 24, 24, 24, 24, 24, 24, + 255, 255, 255,255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, + 240, 240, 240, 240,240,240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 118, 204, 204, 204, 222, 115, 0, 0, 0, 0, + 0, 0, 30, 51, 227, 194, 204, 194, 195, 195, 206, 216, 192, 192, 0, 0, + 0, 0, 31, 243, 195, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 126, 230, 102, 102, 102, 102, 68, 0, 0, 0, 0, + 0, 0, 31, 240, 96, 48, 24, 48, 96, 192, 223, 240, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 127, 240, 216, 216, 216, 216, 112, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 99, 99, 99, 99, 103, 111, 123, 96, 96, 192, 0, + 0, 0, 0, 0, 111, 184, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, + 0, 0, 24, 24, 126, 219, 219, 219, 219, 126, 24, 24, 0, 0, 0, 0, + 0, 0, 0, 60, 102, 195, 195, 255, 195, 195, 102, 60, 0, 0, 0, 0, + 0, 0, 60, 102, 195, 195, 195, 195, 102, 36, 165, 231, 0, 0, 0, 0, + 0, 7, 28, 48, 24, 12, 62, 102, 198, 198, 204, 120, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 110, 219, 219, 219, 118, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 4, 124, 206, 214, 230, 124, 64, 128, 0, 0, 0, 0, + 0, 0, 30, 48, 96, 96, 126, 96, 96, 96, 48, 30, 0, 0, 0, 0, + 0, 0, 0, 126, 195, 195, 195, 195, 195, 195, 195, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 24, 126, 24, 24, 0, 0, 126, 0, 0, 0, 0, + 0, 0, 0, 48, 24, 12, 6, 12, 24, 48, 0, 126, 0, 0, 0, 0, + 0, 0, 0, 12, 24, 48, 96, 48, 24, 12, 0, 126, 0, 0, 0, 0, + 0, 0, 0, 14, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 216, 216, 112, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 24, 0, 255, 0, 24, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 118, 220, 0, 118, 220, 0, 0, 0, 0, 0, 0, + 0, 0, 60, 102, 102, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 24, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 2, 6, 4, 12, 8, 216, 80, 112, 32, 0, 0, 0, 0, + 0, 0, 220, 246, 230, 198, 198, 198, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 120, 204, 24, 48, 100, 252, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 126, 126, 126, 126, 126, 126, 126, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* Can't find another place to put this... */ +void plTexDelete(pl_Texture *t) { + if (t != NULL) + { + if (t->Data != NULL) + { + free(t->Data); + t->Data = NULL; + } + if (t->PaletteData != NULL) + { + free(t->PaletteData); + t->PaletteData = NULL; + } + free(t); + t = NULL; + } +} diff --git a/Src/Winamp/plush/PLUSH.H b/Src/Winamp/plush/PLUSH.H new file mode 100644 index 00000000..6d68e8c0 --- /dev/null +++ b/Src/Winamp/plush/PLUSH.H @@ -0,0 +1,720 @@ +/****************************************************************************** + plush.h + PLUSH 3D VERSION 1.2 MAIN HEADER + Copyright (c) 1996-2000 Justin Frankel + Copyright (c) 1998-2000 Nullsoft, Inc. + + For more information on Plush and the latest updates, please visit + http://www.nullsoft.com + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Justin Frankel + justin@nullsoft.com + +******************************************************************************/ + +#ifndef _PLUSH_H_ +#define _PLUSH_H_ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "pl_conf.h" +#include "pl_defs.h" +#include "pl_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern pl_uChar plText_DefaultFont[256*16]; /* Default 8x16 font for plText* */ +extern pl_uInt32 plRender_TriStats[4]; /* Three different triangle counts from + the last plRender() block: + 0: initial tris + 1: tris after culling + 2: final polys after real clipping + 3: final tris after tesselation + */ + +/****************************************************************************** +** Material Functions (mat.c) +******************************************************************************/ + +/* + plMatCreate() creates a material. + Parameters: + none + Returns: + a pointer to the material on success, 0 on failure +*/ +pl_Mat *plMatCreate(); + +/* + plMatDelete() deletes a material that was created with plMatCreate(). + Parameters: + m: a pointer to the material to be deleted + Returns: + nothing +*/ +void plMatDelete(pl_Mat *m); + +/* + plMatInit() initializes a material that was created with plMatCreate(). + Parameters: + m: a pointer to the material to be intialized + Returns: + nothing + Notes: + you *must* do this before calling plMatMapToPal() or plMatMakeOptPal(). +*/ +void plMatInit(pl_Mat *m); + +/* + plMatMapToPal() maps a material that was created with plMatCreate() and + initialized with plMatInit() to a palette. + Parameters: + mat: material to map + pal: a 768 byte array of unsigned chars, each 3 being a rgb triplet + (0-255, *not* the cheesy vga 0-63) + pstart: starting offset to use colors of, usually 0 + pend: ending offset to use colors of, usually 255 + Returns: + nothing + Notes: + Mapping a material with > 2000 colors can take up to a second or two. + Be careful, and go easy on plMat.NumGradients ;) +*/ +void plMatMapToPal(pl_Mat *m, pl_uChar *pal, pl_sInt pstart, pl_sInt pend); + + +/* + plMatMakeOptPal() makes an almost optimal palette from materials + created with plMatCreate() and initialized with plMatInit(). + Paramters: + p: palette to create + pstart: first color entry to use + pend: last color entry to use + materials: an array of pointers to materials to generate the palette from + nmats: number of materials + Returns: + nothing +*/ +void plMatMakeOptPal(pl_uChar *p, pl_sInt pstart, + pl_sInt pend, pl_Mat **materials, pl_sInt nmats); + + +/****************************************************************************** +** Object Functions (obj.c) +******************************************************************************/ + +/* + plObjCreate() allocates an object + Paramters: + np: Number of vertices in object + nf: Number of faces in object + Returns: + a pointer to the object on success, 0 on failure +*/ +pl_Obj *plObjCreate(pl_uInt32 np, pl_uInt32 nf); + +/* + plObjDelete() frees an object and all of it's subobjects + that was allocated with plObjCreate(); + Paramters: + o: object to delete + Returns: + nothing +*/ +void plObjDelete(pl_Obj *o); + +/* + plObjClone() creates an exact but independent duplicate of an object and + all of it's subobjects + Paramters: + o: the object to clone + Returns: + a pointer to the new object on success, 0 on failure +*/ +pl_Obj *plObjClone(pl_Obj *o); + +/* + plObjScale() scales an object, and all of it's subobjects. + Paramters: + o: a pointer to the object to scale + s: the scaling factor + Returns: + a pointer to o. + Notes: This scales it slowly, by going through each vertex and scaling it's + position. Avoid doing this in realtime. +*/ +pl_Obj *plObjScale(pl_Obj *o, pl_Float s); + +/* + plObjStretch() stretches an object, and all of it's subobjects + Parameters: + o: a pointer to the object to stretch + x,y,z: the x y and z stretch factors + Returns: + a pointer to o. + Notes: same as plObjScale(). Note that the normals are preserved. +*/ +pl_Obj *plObjStretch(pl_Obj *o, pl_Float x, pl_Float y, pl_Float z); + +/* + plObjTranslate() translates an object + Parameters: + o: a pointer to the object to translate + x,y,z: translation in object space + Returns: + a pointer to o + Notes: same has plObjScale(). +*/ +pl_Obj *plObjTranslate(pl_Obj *o, pl_Float x, pl_Float y, pl_Float z); + +/* + plObjFlipNormals() flips all vertex and face normals of and object + and allo of it's subobjects. + Parameters: + o: a pointer to the object to flip normals of + Returns: + a pointer to o + Notes: + Not especially fast. + A call to plObjFlipNormals() or plObjCalcNormals() will restore the normals +*/ +pl_Obj *plObjFlipNormals(pl_Obj *o); + +/* + plObjSetMat() sets the material of all faces in an object. + Paramters: + o: the object to set the material of + m: the material to set it to + th: "transcend hierarchy". If set, it will set the + material of all subobjects too. + Returns: + nothing +*/ +void plObjSetMat(pl_Obj *o, pl_Mat *m, pl_Bool th); + +/* + plObjCalcNormals() calculates all face and vertex normals for an object + and all subobjects. + Paramters: + obj: the object + Returns: + nothing +*/ +void plObjCalcNormals(pl_Obj *obj); + +/****************************************************************************** +** Frustum Clipping Functions (clip.c) +******************************************************************************/ + +/* + plClipSetFrustum() sets up the clipping frustum. + Parameters: + cam: a camera allocated with plCamCreate(). + Returns: + nothing + Notes: + Sets up the internal structures. + DO NOT CALL THIS ROUTINE FROM WITHIN A plRender*() block. +*/ +void plClipSetFrustum(pl_Cam *cam); + +/* + plClipRenderFace() renders a face and clips it to the frustum initialized + with plClipSetFrustum(). + Parameters: + face: the face to render + Returns: + nothing + Notes: this is used internally by plRender*(), so be careful. Kinda slow too. +*/ +void plClipRenderFace(pl_Face *face); + +/* + plClipNeeded() decides whether the face is in the frustum, intersecting + the frustum, or completely out of the frustum craeted with + plClipSetFrustum(). + Parameters: + face: the face to check + Returns: + 0: the face is out of the frustum, no drawing necessary + 1: the face is intersecting the frustum, splitting and drawing necessary + Notes: this is used internally by plRender*(), so be careful. Kinda slow too. +*/ +pl_sInt plClipNeeded(pl_Face *face); + +/****************************************************************************** +** Light Handling Routines (light.c) +******************************************************************************/ + +/* + plLightCreate() creates a new light + Parameters: + none + Returns: + a pointer to the light +*/ +pl_Light *plLightCreate(); + +/* + plLightSet() sets up a light allocated with plLightCreate() + Parameters: + light: the light to set up + mode: the mode of the light (PL_LIGHT_*) + x,y,z: either the position of the light (PL_LIGHT_POINT*) or the angle + in degrees of the light (PL_LIGHT_VECTOR) + intensity: the intensity of the light (0.0-1.0) + halfDist: the distance at which PL_LIGHT_POINT_DISTANCE is 1/2 intensity + Returns: + a pointer to light. +*/ +pl_Light *plLightSet(pl_Light *light, pl_uChar mode, pl_Float x, pl_Float y, + pl_Float z, pl_Float intensity, pl_Float halfDist); + +/* + plLightDelete() frees a light allocated with plLightCreate(). + Paramters: + l: light to delete + Returns: + nothing +*/ +void plLightDelete(pl_Light *l); + +/* PUT ME SOMEWHERE */ +/* +** plTexDelete() frees all memory associated with "t" +*/ +void plTexDelete(pl_Texture *t); + + +/****************************************************************************** +** Camera Handling Routines (cam.c) +******************************************************************************/ + +/* + plCamCreate() allocates a new camera + Parameters: + sw: screen width + sh: screen height + ar: aspect ratio (usually 1.0) + fov: field of view (usually 45-120) + fb: pointer to framebuffer + zb: pointer to Z buffer (or NULL) + Returns: + a pointer to the newly allocated camera +*/ +pl_Cam *plCamCreate(pl_uInt sw, pl_uInt sh, pl_Float ar, pl_Float fov, + pl_uChar *fb, pl_ZBuffer *zb); + +/* + plCamSetTarget() sets the target of a camera allocated with plCamCreate(). + Parameters: + c: the camera to set the target of + x,y,z: the worldspace coordinate of the target + Returns: + nothing + Notes: + Sets the pitch and pan of the camera. Does not touch the roll. +*/ +void plCamSetTarget(pl_Cam *c, pl_Float x, pl_Float y, pl_Float z); + +/* + plCamDelete() frees all memory associated with a camera excluding + framebuffers and Z buffers + Paramters: + c: camera to free + Returns: + nothing +*/ +void plCamDelete(pl_Cam *c); + +/****************************************************************************** +** Easy Rendering Interface (render.c) +******************************************************************************/ + +/* + plRenderBegin() begins the rendering process. + Parameters: + Camera: camera to use for rendering + Returns: + nothing + Notes: + Only one rendering process can occur at a time. + Uses plClip*(), so don't use them within or around a plRender() block. +*/ +void plRenderBegin(pl_Cam *Camera); + +/* + plRenderLight() adds a light to the scene. + Parameters: + light: light to add to scene + Returns: + nothing + Notes: Any objects rendered before will be unaffected by this. +*/ +void plRenderLight(pl_Light *light); + +/* + plRenderObj() adds an object and all of it's subobjects to the scene. + Parameters: + obj: object to render + Returns: + nothing + Notes: if Camera->Sort is zero, objects are rendered in the order that + they are added to the scene. +*/ +void plRenderObj(pl_Obj *obj); + +/* + plRenderEnd() actually does the rendering, and closes the rendering process + Paramters: + none + Returns: + nothing +*/ +void plRenderEnd(); + +/****************************************************************************** +** Object Primitives Code (make.c) +******************************************************************************/ + +/* + plMakePlane() makes a plane centered at the origin facing up the y axis. + Parameters: + w: width of the plane (along the x axis) + d: depth of the plane (along the z axis) + res: resolution of plane, i.e. subdivisions + m: material to use + Returns: + pointer to object created. +*/ +pl_Obj *plMakePlane(pl_Float w, pl_Float d, pl_uInt res, pl_Mat *m); + +/* + plMakeBox() makes a box centered at the origin + Parameters: + w: width of the box (x axis) + d: depth of the box (z axis) + h: height of the box (y axis) + Returns: + pointer to object created. +*/ +pl_Obj *plMakeBox(pl_Float w, pl_Float d, pl_Float h, pl_Mat *m); + +/* + plMakeCone() makes a cone centered at the origin + Parameters: + r: radius of the cone (x-z axis) + h: height of the cone (y axis) + div: division of cone (>=3) + cap: close the big end? + m: material to use + Returns: + pointer to object created. +*/ +pl_Obj *plMakeCone(pl_Float r, pl_Float h, pl_uInt div, pl_Bool cap, pl_Mat *m); + +/* + plMakeCylinder() makes a cylinder centered at the origin + Parameters: + r: radius of the cylinder (x-z axis) + h: height of the cylinder (y axis) + divr: division of of cylinder (around the circle) (>=3) + captop: close the top + capbottom: close the bottom + m: material to use + Returns: + pointer to object created. +*/ +pl_Obj *plMakeCylinder(pl_Float r, pl_Float h, pl_uInt divr, pl_Bool captop, + pl_Bool capbottom, pl_Mat *m); + +/* + plMakeSphere() makes a sphere centered at the origin. + Parameters: + r: radius of the sphere + divr: division of the sphere (around the y axis) (>=3) + divh: division of the sphere (around the x,z axis) (>=3) + m: material to use + Returns: + pointer to object created. +*/ +pl_Obj *plMakeSphere(pl_Float r, pl_uInt divr, pl_uInt divh, pl_Mat *m); + +/* + plMakeTorus() makes a torus centered at the origin + Parameters: + r1: inner radius of the torus + r2: outer radius of the torus + divrot: division of the torus (around the y axis) (>=3) + divrad: division of the radius of the torus (x>=3) + m: material to use + Returns: + pointer to object created. +*/ +pl_Obj *plMakeTorus(pl_Float r1, pl_Float r2, pl_uInt divrot, + pl_uInt divrad, pl_Mat *m); + +/****************************************************************************** +** File Readers (read_*.c) +******************************************************************************/ + +/* + plRead3DSObj() reads a 3DS object + Parameters: + fn: filename of object to read + m: material to assign it + Returns: + pointer to object + Notes: + This reader organizes multiple objects like so: + 1) the first object is returned + 2) the second object is the first's first child + 3) the third object is the second's first child + 4) etc +*/ +pl_Obj *plRead3DSObj(char *fn, pl_Mat *m); + +/* + plReadCOBObj() reads an ascii .COB object + Parameters: + fn: filename of object to read + mat: material to assign it + Returns: + pointer to object + Notes: + This is Caligari's ASCII object format. + This reader doesn't handle multiple objects. It just reads the first one. + Polygons with lots of sides are not always tesselated correctly. Just + use the "Tesselate" button from within truespace to improve the results. +*/ +pl_Obj *plReadCOBObj(char *fn, pl_Mat *mat); + +/* + plReadJAWObj() reads a .JAW object. + Parameters: + fn: filename of object to read + m: material to assign it + Returns: + pointer to object + Notes: + For information on the .JAW format, please see the jaw3D homepage, + http://www.tc.umn.edu/nlhome/g346/kari0022/jaw3d/ +*/ +pl_Obj *plReadJAWObj(char *fn, pl_Mat *m); + +/* + plReadPCXTex() reads a 8bpp PCX texture + Parameters: + fn: filename of texture to read + rescale: will rescale image if not whole log2 dimensions (USE THIS) + optimize: will optimize colors (USE THIS TOO) + Returns: + pointer to texture + Notes: + The PCX must be a 8bpp zSoft version 5 PCX. The texture's palette will + be optimized, and the texture might be scaled up so that it's dimensions + will be a nice power of two. +*/ +pl_Texture *plReadPCXTex(char *fn, pl_Bool rescale, pl_Bool optimize); + +/****************************************************************************** +** Math Code (math.c) +******************************************************************************/ + +/* + plMatrixRotate() generates a rotation matrix + Parameters: + matrix: an array of 16 pl_Floats that is a 4x4 matrix + m: the axis to rotate around, 1=X, 2=Y, 3=Z. + Deg: the angle in degrees to rotate + Returns: + nothing +*/ +void plMatrixRotate(pl_Float matrix[], pl_uChar m, pl_Float Deg); + +/* + plMatrixTranslate() generates a translation matrix + Parameters: + m: the matrix (see plMatrixRotate for more info) + x,y,z: the translation coordinates + Returns: + nothing +*/ +void plMatrixTranslate(pl_Float m[], pl_Float x, pl_Float y, pl_Float z); + +/* + plMatrixMultiply() multiplies two matrices + Parameters: + dest: destination matrix will be multipled by src + src: source matrix + Returns: + nothing + Notes: + this is the same as dest = dest*src (since the order *does* matter); +*/ +void plMatrixMultiply(pl_Float *dest, pl_Float src[]); + +/* + plMatrixApply() applies a matrix. + Parameters: + m: matrix to apply + x,y,z: input coordinate + outx,outy,outz: pointers to output coords. + Returns: + nothing + Notes: + applies the matrix to the 3d point to produce the transformed 3d point +*/ +void plMatrixApply(pl_Float *m, pl_Float x, pl_Float y, pl_Float z, + pl_Float *outx, pl_Float *outy, pl_Float *outz); + +/* + plNormalizeVector() makes a vector a unit vector + Parameters: + x,y,z: pointers to the vector + Returns: + nothing +*/ +void plNormalizeVector(pl_Float *x, pl_Float *y, pl_Float *z); + +/* + plDotProduct() returns the dot product of two vectors + Parameters: + x1,y1,z1: the first vector + x2,y2,z2: the second vector + Returns: + the dot product of the two vectors +*/ +pl_Float plDotProduct(pl_Float x1, pl_Float y1, pl_Float z1, + pl_Float x2, pl_Float y2, pl_Float z2); + +/****************************************************************************** +** Spline Interpolation (spline.c) +******************************************************************************/ + +/* + plSplineInit() initializes a spline + Parameters: + s: the spline + Returns: + nothing + Notes: + Intializes the spline. Do this once, or when you change any of the settings +*/ +void plSplineInit(pl_Spline *s); + +/* + plSplineGetPoint() gets a point on the spline + Parameters: + s: spline + frame: time into spline. 0.0 is start, 1.0 is second key point, etc. + out: a pointer to an array of s->keyWidth floats that will be filled in. + Returns: + nothing +*/ +void plSplineGetPoint(pl_Spline *s, pl_Float frame, pl_Float *out); + +/****************************************************************************** +** 8xX Bitmapped Text +******************************************************************************/ +/* + plTextSetFont() sets the font to be used by the plText*() functions. + Parameters: + font: a pointer to a 8xX bitmapped font + height: the height of the font (X) + Returns: + nothing +*/ + +void plTextSetFont(pl_uChar *font, pl_uChar height); + +/* + plTextPutChar() puts a character to a camera + Parameters: + cam: The camera. If the camera has a zBuffer, it will be used. + x: the x screen position of the left of the text + y: the y screen position of the top of the text + z: the depth of the text (used when cam->zBuffer is set) + color: the color to make the text + c: the character to put. Special characters such as '\n' aren't handled. + Returns: + nothing +*/ + +void plTextPutChar(pl_Cam *cam, pl_sInt x, pl_sInt y, pl_Float z, + pl_uChar color, pl_uChar c); + +/* + plTextPutString() puts an array of characters to a camera + Parameters: + cam: The camera. If the camera has a zBuffer, it will be used. + x: the x screen position of the left of the text + y: the y screen position of the top of the text + z: the depth of the text (used when cam->zBuffer is set) + color: the color to make the text + string: + the characters to put. '\n' and '\t' are handled as one would expect + Returns: + nothing +*/ +void plTextPutStr(pl_Cam *cam, pl_sInt x, pl_sInt y, pl_Float z, + pl_uChar color, pl_sChar *string); + +/* + plTextPrintf() is printf() for graphics + Parameters: + cam: The camera. If the camera has a zBuffer, it will be used. + x: the x screen position of the left of the text + y: the y screen position of the top of the text + z: the depth of the text (used when cam->zBuffer is set) + color: the color to make the text + format: + the characters to put, with printf() formatting codes. + '\n' and '\t' are handled as one would expect + ...: any additional parameters specified by format + Returns: + nothing +*/ +void plTextPrintf(pl_Cam *cam, pl_sInt x, pl_sInt y, pl_Float z, + pl_uChar color, pl_sChar *format, ...); + +/****************************************************************************** +** Built-in Rasterizers +******************************************************************************/ + +void plPF_SolidF(pl_Cam *, pl_Face *); +void plPF_SolidG(pl_Cam *, pl_Face *); +void plPF_TexF(pl_Cam *, pl_Face *); +void plPF_TexG(pl_Cam *, pl_Face *); +void plPF_TexEnv(pl_Cam *, pl_Face *); +void plPF_PTexF(pl_Cam *, pl_Face *); +void plPF_PTexG(pl_Cam *, pl_Face *); +void plPF_TransF(pl_Cam *, pl_Face *); +void plPF_TransG(pl_Cam *, pl_Face *); + +#ifdef __cplusplus +} +#endif + +#endif /* !_PLUSH_H_ */ diff --git a/Src/Winamp/plush/PL_CONF.H b/Src/Winamp/plush/PL_CONF.H new file mode 100644 index 00000000..e5be4287 --- /dev/null +++ b/Src/Winamp/plush/PL_CONF.H @@ -0,0 +1,45 @@ +/****************************************************************************** + pl_conf.h + PLUSH 3D VERSION 1.2 CONFIGURATION HEADER + Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#ifndef _PL_CONF_H_ +#define _PL_CONF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Maximum children per object */ +#define PL_MAX_CHILDREN (16) + +/* Maximum lights per scene -- if you exceed this, they will be ignored */ +#define PL_MAX_LIGHTS (32) + +/* Maximum number of triangles per scene -- if you exceed this, entire +objects will be ignored. You can increase this if you need it. It takes +approximately 8*PL_MAX_TRIANGLES bytes of memory. i.e. the default of +16384 consumes 128kbytes of memory. not really a big deal, +*/ + +#define PL_MAX_TRIANGLES (16384) + +typedef float pl_ZBuffer; /* z-buffer type (must be float) */ +typedef float pl_Float; /* General floating point */ +typedef float pl_IEEEFloat32; /* IEEE 32 bit floating point */ +typedef signed long int pl_sInt32; /* signed 32 bit integer */ +typedef unsigned long int pl_uInt32; /* unsigned 32 bit integer */ +typedef signed short int pl_sInt16; /* signed 16 bit integer */ +typedef unsigned short int pl_uInt16; /* unsigned 16 bit integer */ +typedef signed int pl_sInt; /* signed optimal integer */ +typedef unsigned int pl_uInt; /* unsigned optimal integer */ +typedef int pl_Bool; /* boolean */ +typedef unsigned char pl_uChar; /* unsigned 8 bit integer */ +typedef signed char pl_sChar; /* signed 8 bit integer */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_PL_CONF_H_ */ diff --git a/Src/Winamp/plush/PL_DEFS.H b/Src/Winamp/plush/PL_DEFS.H new file mode 100644 index 00000000..f101810f --- /dev/null +++ b/Src/Winamp/plush/PL_DEFS.H @@ -0,0 +1,62 @@ +/****************************************************************************** + pl_defs.h + PLUSH 3D VERSION 1.2 CONSTANTS DEFINITION HEADER + Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#ifndef _PL_DEFS_H_ +#define _PL_DEFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* pi! */ +#define PL_PI 3.14159265359 + +/* Utility min() and max() functions */ +#define plMin(x,y) (( ( x ) > ( y ) ? ( y ) : ( x ))) +#define plMax(x,y) (( ( x ) < ( y ) ? ( y ) : ( x ))) + +/* +** Shade modes. Used with plMat.ShadeType +** Note that (PL_SHADE_GOURAUD|PL_SHADE_GOURAUD_DISTANCE) and +** (PL_SHADE_FLAT|PL_SHADE_FLAT_DISTANCE) are valid shading modes. +*/ +#define PL_SHADE_NONE (1) +#define PL_SHADE_FLAT (2) +#define PL_SHADE_FLAT_DISTANCE (4) +#define PL_SHADE_GOURAUD (8) +#define PL_SHADE_GOURAUD_DISTANCE (16) + +/* +** Light modes. Used with plLight.Type or plLightSet(). +** Note that PL_LIGHT_POINT_ANGLE assumes no falloff and uses the angle between +** the light and the point, PL_LIGHT_POINT_DISTANCE has falloff with proportion +** to distance**2 (see plLightSet() for setting it), PL_LIGHT_POINT does both. +*/ +#define PL_LIGHT_NONE (0x0) +#define PL_LIGHT_VECTOR (0x1) +#define PL_LIGHT_POINT (0x2|0x4) +#define PL_LIGHT_POINT_DISTANCE (0x2) +#define PL_LIGHT_POINT_ANGLE (0x4) + +/* Used internally; PL_FILL_* are stored in plMat._st. */ +#define PL_FILL_SOLID (0x0) +#define PL_FILL_TEXTURE (0x1) +#define PL_FILL_ENVIRONMENT (0x2) +#define PL_FILL_TRANSPARENT (0x4) + +#define PL_TEXENV_ADD (0) +#define PL_TEXENV_MUL (1) +#define PL_TEXENV_AVG (2) +#define PL_TEXENV_TEXMINUSENV (3) +#define PL_TEXENV_ENVMINUSTEX (4) +#define PL_TEXENV_MIN (5) +#define PL_TEXENV_MAX (6) + +#ifdef __cplusplus +} +#endif + +#endif /* !_PL_DEFS_H_ */ diff --git a/Src/Winamp/plush/PL_TYPES.H b/Src/Winamp/plush/PL_TYPES.H new file mode 100644 index 00000000..f6cb7c48 --- /dev/null +++ b/Src/Winamp/plush/PL_TYPES.H @@ -0,0 +1,162 @@ +/****************************************************************************** + pl_types.h + PLUSH 3D VERSION 1.2 TYPES DEFINITION HEADER + Copyright (c) 1996-2000 Justin Frankel +******************************************************************************/ + +#ifndef _PL_TYPES_H_ +#define _PL_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Texture type. Read textures with plReadPCXTex(), and assign them to +** plMat.Environment or plMat.Texture. +*/ +typedef struct _pl_Texture { + pl_uChar *Data; /* Texture data */ + pl_uChar *PaletteData; /* Palette data (NumColors bytes) */ + pl_uChar Width, Height; /* Log2 of dimensions */ + pl_uInt iWidth, iHeight; /* Integer dimensions */ + pl_Float uScale, vScale; /* Scaling (usually 2**Width, 2**Height) */ + pl_uInt NumColors; /* Number of colors used in texture */ +} pl_Texture; + +/* +** Material type. Create materials with plMatCreate(). +*/ +typedef struct _pl_Mat { + pl_sInt Ambient[3]; /* RGB of surface (0-255 is a good range) */ + pl_sInt Diffuse[3]; /* RGB of diffuse (0-255 is a good range) */ + pl_sInt Specular[3]; /* RGB of "specular" highlights (0-255) */ + pl_uInt Shininess; /* Shininess of material. 1 is dullest */ + pl_Float FadeDist; /* For distance fading, distance at + which intensity is 0 */ + pl_uChar ShadeType; /* Shade type: PL_SHADE_* */ + pl_uChar Transparent; /* Transparency index (0 = none), 4 = alot + Note: transparencies disable textures */ + pl_uChar PerspectiveCorrect; /* Correct textures every n pixels */ + pl_Texture *Texture; /* Texture map (see pl_Texture) above */ + pl_Texture *Environment; /* Environment map (ditto) */ + pl_Float TexScaling; /* Texture map scaling */ + pl_Float EnvScaling; /* Environment map scaling */ + pl_uChar TexEnvMode; /* TexEnv combining mode (PL_TEXENV_*) */ + pl_Bool zBufferable; /* Can this material be zbuffered? */ + pl_uInt NumGradients; /* Desired number of gradients to be used */ + /* The following are used mostly internally */ + pl_uInt _ColorsUsed; /* Number of colors actually used */ + pl_uChar _st, _ft; /* The shadetype and filltype */ + pl_uInt _tsfact; /* Translucent shading factor */ + pl_uInt16 *_AddTable; /* Shading/Translucent/etc table */ + pl_uChar *_ReMapTable; /* Table to remap colors to palette */ + pl_uChar *_RequestedColors; /* _ColorsUsed colors, desired colors */ + void (*_PutFace)(); /* Function that renders the triangle with this + material */ +} pl_Mat; + +/* +** Vertex, used within pl_Obj +*/ +typedef struct _pl_Vertex { + pl_Float x, y, z; /* Vertex coordinate (objectspace) */ + pl_Float xformedx, xformedy, xformedz; + /* Transformed vertex + coordinate (cameraspace) */ + pl_Float nx, ny, nz; /* Unit vertex normal (objectspace) */ + pl_Float xformednx, xformedny, xformednz; + /* Transformed unit vertex normal + (cameraspace) */ +} pl_Vertex; + +/* +** Face +*/ +typedef struct _pl_Face { + pl_Vertex *Vertices[3]; /* Vertices of triangle */ + pl_Float nx, ny, nz; /* Normal of triangle (object space) */ + pl_Mat *Material; /* Material of triangle */ + pl_sInt32 Scrx[3], Scry[3]; /* Projected screen coordinates + (12.20 fixed point) */ + pl_Float Scrz[3]; /* Projected 1/Z coordinates */ + pl_sInt32 MappingU[3], MappingV[3]; + /* 16.16 Texture mapping coordinates */ + pl_sInt32 eMappingU[3], eMappingV[3]; + /* 16.16 Environment map coordinates */ + pl_Float fShade; /* Flat intensity */ + pl_Float sLighting; /* Face static lighting. Should usually be 0.0 */ + pl_Float Shades[3]; /* Vertex intensity */ + pl_Float vsLighting[3]; /* Vertex static lighting. Should be 0.0 */ +} pl_Face; + +/* +** Object +*/ +typedef struct _pl_Obj { + pl_uInt32 NumVertices; /* Number of vertices */ + pl_uInt32 NumFaces; /* Number of faces */ + pl_Vertex *Vertices; /* Array of vertices */ + pl_Face *Faces; /* Array of faces */ + struct _pl_Obj *Children[PL_MAX_CHILDREN]; + /* Children */ + pl_Bool BackfaceCull; /* Are backfacing polys drawn? */ + pl_Bool BackfaceIllumination; /* Illuminated by lights behind them? */ + pl_Bool GenMatrix; /* Generate Matrix from the following + if set */ + pl_Float Xp, Yp, Zp, Xa, Ya, Za; /* Position and rotation of object: + Note: rotations are around + X then Y then Z. Measured in degrees */ + pl_Float Matrix[16]; /* Transformation matrix */ + pl_Float RotMatrix[16]; /* Rotation only matrix (for normals) */ +} pl_Obj; + +/* +** Spline type. See plSpline*(). +*/ +typedef struct _pl_Spline { + pl_Float *keys; /* Key data, keyWidth*numKeys */ + pl_sInt keyWidth; /* Number of floats per key */ + pl_sInt numKeys; /* Number of keys */ + pl_Float cont; /* Continuity. Should be -1.0 -> 1.0 */ + pl_Float bias; /* Bias. -1.0 -> 1.0 */ + pl_Float tens; /* Tension. -1.0 -> 1.0 */ +} pl_Spline; + +/* +** Light type. See plLight*(). +*/ +typedef struct _pl_Light { + pl_uChar Type; /* Type of light: PL_LIGHT_* */ + pl_Float Xp, Yp, Zp; /* If Type=PL_LIGHT_POINT*, + this is Position (PL_LIGHT_POINT_*), + otherwise if PL_LIGHT_VECTOR, + Unit vector */ + pl_Float Intensity; /* Intensity. 0.0 is off, 1.0 is full */ + pl_Float HalfDistSquared; /* Distance squared at which + PL_LIGHT_POINT_DISTANCE is 50% */ +} pl_Light; + +/* +** Camera Type. +*/ +typedef struct _pl_Cam { + pl_Float Fov; /* FOV in degrees valid range is 1-179 */ + pl_Float AspectRatio; /* Aspect ratio (usually 1.0) */ + pl_sChar Sort; /* Sort polygons, -1 f-t-b, 1 b-t-f, 0 no */ + pl_Float ClipBack; /* Far clipping ( < 0.0 is none) */ + pl_sInt ClipTop, ClipLeft; /* Screen Clipping */ + pl_sInt ClipBottom, ClipRight; + pl_uInt ScreenWidth, ScreenHeight; /* Screen dimensions */ + pl_sInt CenterX, CenterY; /* Center of screen */ + pl_Float X, Y, Z; /* Camera position in worldspace */ + pl_Float Pitch, Pan, Roll; /* Camera angle in degrees in worldspace */ + pl_uChar *frameBuffer; /* Framebuffer (ScreenWidth*ScreenHeight) */ + pl_ZBuffer *zBuffer; /* Z Buffer (NULL if none) */ +} pl_Cam; + +#ifdef __cplusplus +} +#endif + +#endif /* !_PL_TYPES_H_ */ diff --git a/Src/Winamp/plush/PUTFACE.H b/Src/Winamp/plush/PUTFACE.H new file mode 100644 index 00000000..c79e789b --- /dev/null +++ b/Src/Winamp/plush/PUTFACE.H @@ -0,0 +1,54 @@ +/****************************************************************************** +Plush Version 1.2 +putface.h +Triangle Vertex Sorting Code for pf_*.c +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#ifndef _PUTFACE_H_ +#define _PUTFACE_H_ + +#define PUTFACE_SORT() \ + i0 = 0; i1 = 1; i2 = 2; \ + if (TriFace->Scry[0] > TriFace->Scry[1]) { \ + i0 = 1; i1 = 0; \ + } \ + if (TriFace->Scry[i0] > TriFace->Scry[2]) { \ + i2 ^= i0; i0 ^= i2; i2 ^= i0; \ + } \ + if (TriFace->Scry[i1] > TriFace->Scry[i2]) { \ + i2 ^= i1; i1 ^= i2; i2 ^= i1; \ + } + + +#define PUTFACE_SORT_ENV() \ + PUTFACE_SORT(); \ + MappingU1=TriFace->eMappingU[i0]*Texture->uScale*\ + TriFace->Material->EnvScaling;\ + MappingV1=TriFace->eMappingV[i0]*Texture->vScale*\ + TriFace->Material->EnvScaling;\ + MappingU2=TriFace->eMappingU[i1]*Texture->uScale*\ + TriFace->Material->EnvScaling;\ + MappingV2=TriFace->eMappingV[i1]*Texture->vScale*\ + TriFace->Material->EnvScaling;\ + MappingU3=TriFace->eMappingU[i2]*Texture->uScale*\ + TriFace->Material->EnvScaling;\ + MappingV3=TriFace->eMappingV[i2]*Texture->vScale*\ + TriFace->Material->EnvScaling; + +#define PUTFACE_SORT_TEX() \ + PUTFACE_SORT(); \ + MappingU1=TriFace->MappingU[i0]*Texture->uScale*\ + TriFace->Material->TexScaling;\ + MappingV1=TriFace->MappingV[i0]*Texture->vScale*\ + TriFace->Material->TexScaling;\ + MappingU2=TriFace->MappingU[i1]*Texture->uScale*\ + TriFace->Material->TexScaling;\ + MappingV2=TriFace->MappingV[i1]*Texture->vScale*\ + TriFace->Material->TexScaling;\ + MappingU3=TriFace->MappingU[i2]*Texture->uScale*\ + TriFace->Material->TexScaling;\ + MappingV3=TriFace->MappingV[i2]*Texture->vScale*\ + TriFace->Material->TexScaling; + +#endif /* !_PUTFACE_H_ */ diff --git a/Src/Winamp/plush/READ_3DS.C b/Src/Winamp/plush/READ_3DS.C new file mode 100644 index 00000000..90db94e9 --- /dev/null +++ b/Src/Winamp/plush/READ_3DS.C @@ -0,0 +1,244 @@ +/****************************************************************************** +Plush Version 1.2 +read_3ds.c +3DS Object Reader +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +typedef struct { + pl_uInt16 id; + void (*func)(FILE *f, pl_uInt32 p); +} _pl_3DSChunk; + +static pl_Obj *obj; +static pl_Obj *bobj; +static pl_Obj *lobj; +static pl_sInt16 currentobj; +static pl_Mat *_m; + +static pl_Float _pl3DSReadFloat(FILE *f); +static pl_uInt32 _pl3DSReadDWord(FILE *f); +static pl_uInt16 _pl3DSReadWord(FILE *f); +static void _pl3DSChunkReader(FILE *f, pl_uInt32 p); +static void _pl3DSRGBFReader(FILE *f, pl_uInt32 p); +static void _pl3DSRGBBReader(FILE *f, pl_uInt32 p); +static void _pl3DSASCIIZReader(FILE *f, pl_uInt32 p, char *as); +static void _pl3DSObjBlockReader(FILE *f, pl_uInt32 p); +static void _pl3DSTriMeshReader(FILE *f, pl_uInt32 p); +static void _pl3DSVertListReader(FILE *f, pl_uInt32 p); +static void _pl3DSFaceListReader(FILE *f, pl_uInt32 p); +static void _pl3DSFaceMatReader(FILE *f, pl_uInt32 p); +static void MapListReader(FILE *f, pl_uInt32 p); +static pl_sInt16 _pl3DSFindChunk(pl_uInt16 id); + +static _pl_3DSChunk _pl3DSChunkNames[] = { + {0x4D4D,NULL}, /* Main */ + {0x3D3D,NULL}, /* Object Mesh */ + {0x4000,_pl3DSObjBlockReader}, + {0x4100,_pl3DSTriMeshReader}, + {0x4110,_pl3DSVertListReader}, + {0x4120,_pl3DSFaceListReader}, + {0x4130,_pl3DSFaceMatReader}, + {0x4140,MapListReader}, + {0xAFFF,NULL}, /* Material */ + {0xA010,NULL}, /* Ambient */ + {0xA020,NULL}, /* Diff */ + {0xA030,NULL}, /* Specular */ + {0xA200,NULL}, /* Texture */ + {0x0010,_pl3DSRGBFReader}, + {0x0011,_pl3DSRGBBReader}, +}; + +pl_Obj *plRead3DSObj(char *fn, pl_Mat *m) { + FILE *f; + pl_uInt32 p; + _m = m; + obj = bobj = lobj = 0; + currentobj = 0; + f = fopen(fn, "rb"); + if (!f) return 0; + fseek(f, 0, 2); + p = ftell(f); + rewind(f); + _pl3DSChunkReader(f, p); + fclose(f); + return bobj; +} + +static pl_Float _pl3DSReadFloat(FILE *f) { + pl_uInt32 *i; + pl_IEEEFloat32 c; + i = (pl_uInt32 *) &c; + *i = _pl3DSReadDWord(f); + return ((pl_Float) c); +} + +static pl_uInt32 _pl3DSReadDWord(FILE *f) { + pl_uInt32 r; + r = fgetc(f); + r |= fgetc(f)<<8; + r |= fgetc(f)<<16; + r |= fgetc(f)<<24; + return r; +} + +static pl_uInt16 _pl3DSReadWord(FILE *f) { + pl_uInt16 r; + r = fgetc(f); + r |= fgetc(f)<<8; + return r; +} + +static void _pl3DSRGBFReader(FILE *f, pl_uInt32 p) { + pl_Float c[3]; + c[0] = _pl3DSReadFloat(f); + c[1] = _pl3DSReadFloat(f); + c[2] = _pl3DSReadFloat(f); +} + +static void _pl3DSRGBBReader(FILE *f, pl_uInt32 p) { + unsigned char c[3]; + if (fread(&c, sizeof(c), 1, f) != 1) return; +} + +static void _pl3DSASCIIZReader(FILE *f, pl_uInt32 p, char *as) { + char c; + if (!as) while ((c = fgetc(f)) != EOF && c != '\0'); + else { + while ((c = fgetc(f)) != EOF && c != '\0') *as++ = c; + *as = 0; + } +} + +static void _pl3DSObjBlockReader(FILE *f, pl_uInt32 p) { + _pl3DSASCIIZReader(f,p,0); + _pl3DSChunkReader(f, p); +} + +static void _pl3DSTriMeshReader(FILE *f, pl_uInt32 p) { + pl_uInt32 i; + pl_Face *face; + obj = plObjCreate(0,0); + _pl3DSChunkReader(f, p); + i = obj->NumFaces; + face = obj->Faces; + while (i--) { + face->Vertices[0] = obj->Vertices + (pl_uInt32) face->Vertices[0]; + face->Vertices[1] = obj->Vertices + (pl_uInt32) face->Vertices[1]; + face->Vertices[2] = obj->Vertices + (pl_uInt32) face->Vertices[2]; + face->MappingU[0] = face->Vertices[0]->xformedx; + face->MappingV[0] = face->Vertices[0]->xformedy; + face->MappingU[1] = face->Vertices[1]->xformedx; + face->MappingV[1] = face->Vertices[1]->xformedy; + face->MappingU[2] = face->Vertices[2]->xformedx; + face->MappingV[2] = face->Vertices[2]->xformedy; + face++; + } + plObjCalcNormals(obj); + if (currentobj == 0) { + currentobj = 1; + lobj = bobj = obj; + } else { + lobj->Children[0] = obj; + lobj = obj; + } +} + +static void _pl3DSVertListReader(FILE *f, pl_uInt32 p) { + pl_uInt16 nv; + pl_Vertex *v; + nv = _pl3DSReadWord(f); + obj->NumVertices = nv; + v = obj->Vertices = (pl_Vertex *) calloc(sizeof(pl_Vertex)*nv,1); + while (nv--) { + v->x = _pl3DSReadFloat(f); + v->y = _pl3DSReadFloat(f); + v->z = _pl3DSReadFloat(f); + if (feof(f)) return; + v++; + } +} + +static void _pl3DSFaceListReader(FILE *f, pl_uInt32 p) { + pl_uInt16 nv; + pl_uInt16 c[3]; + pl_uInt16 flags; + pl_Face *face; + + nv = _pl3DSReadWord(f); + obj->NumFaces = nv; + face = obj->Faces = (pl_Face *) calloc(sizeof(pl_Face)*nv,1); + while (nv--) { + c[0] = _pl3DSReadWord(f); + c[1] = _pl3DSReadWord(f); + c[2] = _pl3DSReadWord(f); + flags = _pl3DSReadWord(f); + if (feof(f)) return; + face->Vertices[0] = (pl_Vertex *) (c[0]&0x0000FFFF); + face->Vertices[1] = (pl_Vertex *) (c[1]&0x0000FFFF); + face->Vertices[2] = (pl_Vertex *) (c[2]&0x0000FFFF); + face->Material = _m; + face++; + } + _pl3DSChunkReader(f, p); +} + +static void _pl3DSFaceMatReader(FILE *f, pl_uInt32 p) { + pl_uInt16 n, nf; + + _pl3DSASCIIZReader(f, p,0); + + n = _pl3DSReadWord(f); + while (n--) { + nf = _pl3DSReadWord(f); + } +} + +static void MapListReader(FILE *f, pl_uInt32 p) { + pl_uInt16 nv; + pl_Float c[2]; + pl_Vertex *v; + nv = _pl3DSReadWord(f); + v = obj->Vertices; + if (nv == obj->NumVertices) while (nv--) { + c[0] = _pl3DSReadFloat(f); + c[1] = _pl3DSReadFloat(f); + if (feof(f)) return; + v->xformedx = (pl_sInt32) (c[0]*65536.0); + v->xformedy = (pl_sInt32) (c[1]*65536.0); + v++; + } +} + +static pl_sInt16 _pl3DSFindChunk(pl_uInt16 id) { + pl_sInt16 i; + for (i = 0; i < sizeof(_pl3DSChunkNames)/sizeof(_pl3DSChunkNames[0]); i++) + if (id == _pl3DSChunkNames[i].id) return i; + return -1; +} + +static void _pl3DSChunkReader(FILE *f, pl_uInt32 p) { + pl_uInt32 hlen; + pl_uInt16 hid; + pl_sInt16 n; + pl_uInt32 pc; + + while (ftell(f) < (int)p) { + pc = ftell(f); + hid = _pl3DSReadWord(f); if (feof(f)) return; + hlen = _pl3DSReadDWord(f); if (feof(f)) return; + if (hlen == 0) return; + n = _pl3DSFindChunk(hid); + if (n < 0) fseek(f, pc + hlen, 0); + else { + pc += hlen; + if (_pl3DSChunkNames[n].func != NULL) _pl3DSChunkNames[n].func(f, pc); + else _pl3DSChunkReader(f, pc); + fseek(f, pc, 0); + } + if (ferror(f)) break; + } +} + diff --git a/Src/Winamp/plush/READ_COB.C b/Src/Winamp/plush/READ_COB.C new file mode 100644 index 00000000..20233d20 --- /dev/null +++ b/Src/Winamp/plush/READ_COB.C @@ -0,0 +1,182 @@ +/****************************************************************************** +Plush Version 1.2 +read_cob.c +ASCII COB Object Reader +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +#define PL_COB_MAX_LINELENGTH 1024 + +pl_Obj *plReadCOBObj(char *fn, pl_Mat *mat) { + FILE *fp = fopen(fn,"rt"); + long int p1,m1,p2,m2,p3,m3; + char temp_string[PL_COB_MAX_LINELENGTH]; + float TransMatrix[4][4]; + pl_Obj *obj; + pl_sInt32 x,i2; + long int numVertices, numMappingVertices, numFaces, i; + pl_sInt32 *MappingVertices = 0; + if (!fp) return 0; + + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + if (memcmp("Caligari",temp_string,8)) { fclose(fp); return 0; } + + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("Transform",temp_string,9)); + if (feof(fp)) { fclose(fp); return 0; } + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + sscanf(temp_string,"%f %f %f %f", + &TransMatrix[0][0],&TransMatrix[0][1],&TransMatrix[0][2],&TransMatrix[0][3]); + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + sscanf(temp_string,"%f %f %f %f", + &TransMatrix[1][0],&TransMatrix[1][1],&TransMatrix[1][2],&TransMatrix[1][3]); + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + sscanf(temp_string,"%f %f %f %f", + &TransMatrix[2][0],&TransMatrix[2][1],&TransMatrix[2][2],&TransMatrix[2][3]); + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + sscanf(temp_string,"%f %f %f %f", + &TransMatrix[3][0],&TransMatrix[3][1],&TransMatrix[3][2],&TransMatrix[3][3]); + + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("World Vertices",temp_string,12)); + if (feof(fp) || sscanf(temp_string,"World Vertices %ld",&numVertices) != 1) + { fclose(fp); return 0; } + + rewind(fp); + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("Texture Vertices",temp_string,16)); + if (feof(fp) || + sscanf(temp_string,"Texture Vertices %ld",&numMappingVertices) != 1) { + fclose(fp); return 0; + } + + rewind(fp); + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("Faces",temp_string,5)); + if (feof(fp) || sscanf(temp_string,"Faces %ld",&numFaces) != 1) { + fclose(fp); return 0; + } + for (x = numFaces; x; x--) { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + if (feof(fp) || sscanf(temp_string+4," verts %ld",&i) != 1 || i < 3) { + fclose(fp); + return 0; + } + numFaces += i-3; + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } + obj = plObjCreate(numVertices,numFaces); + if (!obj) { fclose(fp); return 0; } + rewind(fp); + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("World Vertices",temp_string,12)); + if (feof(fp)) { plObjDelete(obj); fclose(fp); return 0; } + for (x = 0; x < numVertices; x ++) { + float xp, yp, zp; + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + if (feof(fp) || + sscanf(temp_string,"%f %f %f", &xp, &yp, &zp) != 3) { + plObjDelete(obj); fclose(fp); return 0; + } + obj->Vertices[x].x = (TransMatrix[0][0]*xp+TransMatrix[0][1]*yp+ + TransMatrix[0][2]*zp+TransMatrix[0][3]); + obj->Vertices[x].y = (TransMatrix[1][0]*xp+TransMatrix[1][1]*yp+ + TransMatrix[1][2]*zp+TransMatrix[1][3]); + obj->Vertices[x].z = (TransMatrix[2][0]*xp+TransMatrix[2][1]*yp+ + TransMatrix[2][2]*zp+TransMatrix[2][3]); + } + rewind(fp); + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("Texture Vertices",temp_string,16)); + if (!feof(fp)) { + MappingVertices = (pl_sInt32 *) + malloc(sizeof(pl_sInt32) * numMappingVertices * 2); + if (MappingVertices) { + for (x = 0; x < numMappingVertices; x ++) { + float p1, p2; + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + if (feof(fp) || sscanf(temp_string,"%f %f", &p1, &p2) != 2) { + free(MappingVertices); plObjDelete(obj); fclose(fp); return 0; + } + MappingVertices[x*2] = (pl_sInt32) (p1*65536.0); + MappingVertices[x*2+1] = (pl_sInt32) (p2*65536.0); + } + } + } + rewind(fp); + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("Faces",temp_string,5)); + if (feof(fp)) { + if (MappingVertices) free(MappingVertices); + plObjDelete(obj); fclose(fp); return 0; + } + for (x = 0; x < numFaces; x ++) { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + sscanf(temp_string+4," verts %ld",&i); + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + if (i == 3) { + if (feof(fp) || sscanf(temp_string,"<%ld,%ld> <%ld,%ld> <%ld,%ld>", + &p3,&m3,&p2,&m2,&p1,&m1) != 6) { + if (MappingVertices) free(MappingVertices); + plObjDelete(obj); fclose(fp); return 0; + } + obj->Faces[x].Vertices[0] = obj->Vertices + p1; + obj->Faces[x].Vertices[1] = obj->Vertices + p2; + obj->Faces[x].Vertices[2] = obj->Vertices + p3; + if (MappingVertices) { + obj->Faces[x].MappingU[0] = MappingVertices[m1*2]; + obj->Faces[x].MappingV[0] = MappingVertices[m1*2+1]; + obj->Faces[x].MappingU[1] = MappingVertices[m2*2]; + obj->Faces[x].MappingV[1] = MappingVertices[m2*2+1]; + obj->Faces[x].MappingU[2] = MappingVertices[m3*2]; + obj->Faces[x].MappingV[2] = MappingVertices[m3*2+1]; + } + obj->Faces[x].Material = mat; + } else { + long int p[16],m[16]; + if (feof(fp)) { + if (MappingVertices) free(MappingVertices); + plObjDelete(obj); fclose(fp); return 0; + } + sscanf(temp_string, + "<%ld,%ld> <%ld,%ld> <%ld,%ld> <%ld,%ld> " + "<%ld,%ld> <%ld,%ld> <%ld,%ld> <%ld,%ld> " + "<%ld,%ld> <%ld,%ld> <%ld,%ld> <%ld,%ld> " + "<%ld,%ld> <%ld,%ld> <%ld,%ld> <%ld,%ld> ", + p+0,m+0,p+1,m+1,p+2,m+2,p+3,m+3, + p+4,m+4,p+5,m+5,p+6,m+6,p+7,m+7, + p+8,m+8,p+9,m+9,p+10,m+10,p+11,m+11, + p+12,m+12,p+13,m+13,p+14,m+14,p+15,m+15); + for (i2 = 1; i2 < (i-1); i2 ++) { + obj->Faces[x].Vertices[0] = obj->Vertices + p[0]; + obj->Faces[x].Vertices[1] = obj->Vertices + p[i2+1]; + obj->Faces[x].Vertices[2] = obj->Vertices + p[i2]; + if (MappingVertices) { + obj->Faces[x].MappingU[0] = MappingVertices[m[0]*2]; + obj->Faces[x].MappingV[0] = MappingVertices[m[0]*2+1]; + obj->Faces[x].MappingU[1] = MappingVertices[m[i2+1]*2]; + obj->Faces[x].MappingV[1] = MappingVertices[m[i2+1]*2+1]; + obj->Faces[x].MappingU[2] = MappingVertices[m[i2]*2]; + obj->Faces[x].MappingV[2] = MappingVertices[m[i2]*2+1]; + } + obj->Faces[x].Material = mat; + x++; + } + x--; + } + } + obj->BackfaceCull = 1; + if (MappingVertices) free(MappingVertices); + plObjCalcNormals(obj); + fclose(fp); + return obj; +} diff --git a/Src/Winamp/plush/READ_JAW.C b/Src/Winamp/plush/READ_JAW.C new file mode 100644 index 00000000..18ed1ce2 --- /dev/null +++ b/Src/Winamp/plush/READ_JAW.C @@ -0,0 +1,69 @@ +/****************************************************************************** +Plush Version 1.2 +read_jaw.c +Jaw3D Object Reader +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************* + Notes on .JAW files: + This is a file format created by Jawed Karim for Jaw3D + (http://jaw3d.home.ml.org). + -- updated 11/6/00 - www.jawed.com + It is very simple, and lets one easily create ones own models using only + a text editor. The format is pretty simple: + The first line must be "Light: (x,y,z)" where x,y, and z are the x y and + z components of the lightsource vector (I think ;) + A series of lines, numbered 0 to n, in the format of + "i: x y z", where i is the vertex number (which should be listed in + order, and x y and z are the coordinates of that vertex. + A series of lines, having the format "tri a, b, c" where a b and c are + the vertices that the face uses. It is unclear at this time which + way the vertices are listed (ccw or cw), so just make em consistent + and you can always use plFlipObjectNormals() on the loaded object. + That is it! (I told ya it was simple). +******************************************************************************/ + +#include "plush.h" + +pl_Obj *plReadJAWObj(char *filename, pl_Mat *m) { + FILE *jawfile; + pl_Obj *obj; + pl_uInt32 i; + pl_sInt crap; + char line[256]; + pl_uInt32 total_points = 0, total_polys = 0; + if ((jawfile = fopen(filename, "r")) == NULL) return 0; + fgets(line, 256, jawfile); /* Ignores lightsource info */ + while (fgets(line, 256, jawfile) != NULL) + if (strstr(line, ":") != NULL) total_points++; + + rewind(jawfile); fgets(line, 256, jawfile); + while (fgets(line, 256, jawfile) != NULL) + if (strstr(line, "tri") != NULL) total_polys++; + + rewind(jawfile); fgets(line, 256, jawfile); + obj = plObjCreate(total_points,total_polys); + + i = 0; + while (fgets(line, 256, jawfile) != NULL) if (strstr(line, ":") != NULL) { + float x, y, z; + sscanf(line, "%d: %f %f %f",&crap,&x,&y,&z); + obj->Vertices[i].x = (pl_Float) x; + obj->Vertices[i].y = (pl_Float) y; + obj->Vertices[i].z = (pl_Float) z; + i++; + } + rewind(jawfile); fgets(line, 256, jawfile); + i = 0; + while (fgets(line, 256, jawfile) != NULL) if (strstr(line, "tri") != NULL) { + pl_uInt32 a,b,c; + sscanf(line, "tri %ld, %ld, %ld", &a, &b, &c); + obj->Faces[i].Vertices[0] = obj->Vertices + a; + obj->Faces[i].Vertices[1] = obj->Vertices + c; + obj->Faces[i].Vertices[2] = obj->Vertices + b; + obj->Faces[i].Material = m; + i++; + } + fclose(jawfile); + plObjCalcNormals(obj); + return obj; +} diff --git a/Src/Winamp/plush/READ_PCX.C b/Src/Winamp/plush/READ_PCX.C new file mode 100644 index 00000000..e1de3825 --- /dev/null +++ b/Src/Winamp/plush/READ_PCX.C @@ -0,0 +1,162 @@ +/****************************************************************************** +Plush Version 1.2 +read_pcx.c +PCX Texture Reader +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +static pl_uInt _plHiBit(pl_uInt16); +static pl_uInt _plOptimizeImage(pl_uChar *, pl_uChar *, pl_uInt32); +static pl_sInt _plReadPCX(char *filename, pl_uInt16 *width, pl_uInt16 *height, + pl_uChar **pal, pl_uChar **data); +static void _plRescaleImage(pl_uChar *in, pl_uChar *out, pl_uInt inx, + pl_uInt iny, pl_uInt outx, pl_uInt outy); + +pl_Texture *plReadPCXTex(char *fn, pl_Bool rescale, pl_Bool optimize) { + pl_uChar *data, *pal; + pl_uInt16 x, y; + pl_Texture *t; + if (_plReadPCX(fn,&x,&y,&pal,&data) < 0) return 0; + t = (pl_Texture *) malloc(sizeof(pl_Texture)); + if (!t) return 0; + t->Width = _plHiBit(x); + t->Height = _plHiBit(y); + if (rescale && (1 << t->Width != x || 1 << t->Height != y)) { + pl_uChar nx, ny, *newdata; + nx = t->Width; + if ((1 << t->Width) != x) nx++; + ny = t->Height; + if ((1 << t->Height) != y) ny++; + newdata = (pl_uChar *) malloc((1<<nx)*(1<<ny)); + if (!newdata) { + free(t); + free(data); + free(pal); + return 0; + } + _plRescaleImage(data,newdata,x,y,1<<nx,1<<ny); + free(data); + data = newdata; + t->Width = nx; + t->Height = ny; + x = 1<<nx; y = 1<<ny; + } + t->iWidth = x; + t->iHeight = y; + t->uScale = (pl_Float) (1<<t->Width); + t->vScale = (pl_Float) (1<<t->Height); + if (optimize) t->NumColors = _plOptimizeImage(pal, data,x*y); + else t->NumColors = 256; + t->Data = data; + t->PaletteData = pal; + return t; +} + + +static pl_uInt _plHiBit(pl_uInt16 x) { + pl_uInt i = 16, mask = 1<<15; + while (mask) { + if (x & mask) return i; + mask >>= 1; i--; + } + return 0; +} + +static pl_uInt _plOptimizeImage(pl_uChar *pal, pl_uChar *data, pl_uInt32 len) { + pl_uChar colors[256], *dd = data; + pl_uChar remap[256]; + pl_sInt32 lastused, firstunused; + pl_uInt32 x; + memset(colors,0,256); + for (x = 0; x < len; x ++) colors[(pl_uInt) *dd++] = 1; + lastused = -1; + for (x = 0; x < 256; x ++) remap[x] = (pl_uChar)x; + lastused = 255; + firstunused = 0; + for (;;) { + while (firstunused < 256 && colors[firstunused]) firstunused++; + if (firstunused > 255) break; + while (lastused >= 0 && !colors[lastused]) lastused--; + if (lastused < 0) break; + if (lastused <= firstunused) break; + pal[firstunused*3] = pal[lastused*3]; + pal[firstunused*3+1] = pal[lastused*3+1]; + pal[firstunused*3+2] = pal[lastused*3+2]; + colors[lastused] = 0; + colors[firstunused] = 1; + remap[lastused] = (pl_uChar) firstunused; + } + x = len; + while (x--) *data++ = remap[(pl_uInt) *data]; + return (lastused+1); +} + +static pl_sInt _plReadPCX(char *filename, pl_uInt16 *width, pl_uInt16 *height, + pl_uChar **pal, pl_uChar **data) { + pl_uInt16 sx, sy, ex, ey; + FILE *fp = fopen(filename,"rb"); + pl_uChar *data2; + if (!fp) return -1; + fgetc(fp); + if (fgetc(fp) != 5) { fclose(fp); return -2; } + if (fgetc(fp) != 1) { fclose(fp); return -2; } + if (fgetc(fp) != 8) { fclose(fp); return -3; } + sx = fgetc(fp); sx |= fgetc(fp)<<8; + sy = fgetc(fp); sy |= fgetc(fp)<<8; + ex = fgetc(fp); ex |= fgetc(fp)<<8; + ey = fgetc(fp); ey |= fgetc(fp)<<8; + *width = ex - sx + 1; + *height = ey - sy + 1; + fseek(fp,128,SEEK_SET); + if (feof(fp)) { fclose(fp); return -4; } + *data = (pl_uChar *) malloc((*width) * (*height)); + if (!*data) { fclose(fp); return -128; } + sx = *height; + data2 = *data; + do { + int xpos = 0; + do { + char c = fgetc(fp); + if ((c & 192) == 192) { + char oc = fgetc(fp); + c &= ~192; + do { + *(data2++) = oc; + xpos++; + } while (--c && xpos < *width); + } else { + *(data2++) = c; + xpos++; + } + } while (xpos < *width); + } while (--sx); + if (feof(fp)) { fclose(fp); free(*data); return -5; } + fseek(fp,-769,SEEK_END); + if (fgetc(fp) != 12) { fclose(fp); free(*data); return -6; } + *pal = (pl_uChar *) malloc(768); + if (!*pal) { fclose(fp); free(*data); return -7; } + fread(*pal,3,256,fp); + fclose(fp); + return 0; +} + +static void _plRescaleImage(pl_uChar *in, pl_uChar *out, pl_uInt inx, + pl_uInt iny, pl_uInt outx, pl_uInt outy) { + pl_uInt x; + pl_uInt32 X, dX, dY, Y; + dX = (inx<<16) / outx; + dY = (iny<<16) / outy; + Y = 0; + do { + pl_uChar *ptr = in + inx*(Y>>16); + X = 0; + Y += dY; + x = outx; + do { + *out++ = ptr[X>>16]; + X += dX; + } while (--x); + } while (--outy); +} diff --git a/Src/Winamp/plush/RENDER.C b/Src/Winamp/plush/RENDER.C new file mode 100644 index 00000000..665e96fa --- /dev/null +++ b/Src/Winamp/plush/RENDER.C @@ -0,0 +1,301 @@ +/****************************************************************************** +Plush Version 1.2 +render.c +Rendering code: this includes transformation, lighting, etc +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +typedef struct { + pl_Float zd; + pl_Face *face; +} _faceInfo; + +typedef struct { + pl_Light *light; + pl_Float l[3]; +} _lightInfo; + +#define MACRO_plMatrixApply(m,x,y,z,outx,outy,outz) \ + ( outx ) = ( x )*( m )[0] + ( y )*( m )[1] + ( z )*( m )[2] + ( m )[3];\ + ( outy ) = ( x )*( m )[4] + ( y )*( m )[5] + ( z )*( m )[6] + ( m )[7];\ + ( outz ) = ( x )*( m )[8] + ( y )*( m )[9] + ( z )*( m )[10] + ( m )[11] + +#define MACRO_plDotProduct(x1,y1,z1,x2,y2,z2) \ + ((( x1 )*( x2 ))+(( y1 )*( y2 ))+(( z1 )*( z2 ))) + +#define MACRO_plNormalizeVector(x,y,z) { \ + register double length; \ + length = ( x )*( x )+( y )*( y )+( z )*( z ); \ + if (length > 0.0000000001) { \ + pl_Float l = (pl_Float) sqrt(length); \ + ( x ) /= l; \ + ( y ) /= l; \ + ( z ) /= l; \ + } \ +} + +pl_uInt32 plRender_TriStats[4]; + +static pl_uInt32 _numfaces; +static _faceInfo _faces[PL_MAX_TRIANGLES]; + +static pl_Float _cMatrix[16]; +static pl_uInt32 _numlights; +static _lightInfo _lights[PL_MAX_LIGHTS]; +static pl_Cam *_cam; +static void _RenderObj(pl_Obj *, pl_Float *, pl_Float *); +static void _sift_down(int L, int U, int dir); +static void _hsort(_faceInfo *base, int nel, int dir); + +void plRenderBegin(pl_Cam *Camera) { + pl_Float tempMatrix[16]; + memset(plRender_TriStats,0,sizeof(plRender_TriStats)); + _cam = Camera; + _numlights = 0; + _numfaces = 0; + plMatrixRotate(_cMatrix,2,-Camera->Pan); + plMatrixRotate(tempMatrix,1,-Camera->Pitch); + plMatrixMultiply(_cMatrix,tempMatrix); + plMatrixRotate(tempMatrix,3,-Camera->Roll); + plMatrixMultiply(_cMatrix,tempMatrix); + plClipSetFrustum(_cam); +} + +void plRenderLight(pl_Light *light) { + pl_Float *pl, xp, yp, zp; + if (light->Type == PL_LIGHT_NONE || _numlights >= PL_MAX_LIGHTS) return; + pl = _lights[_numlights].l; + if (light->Type == PL_LIGHT_VECTOR) { + xp = light->Xp; + yp = light->Yp; + zp = light->Zp; + MACRO_plMatrixApply(_cMatrix,xp,yp,zp,pl[0],pl[1],pl[2]); + } else if (light->Type & PL_LIGHT_POINT) { + xp = light->Xp-_cam->X; + yp = light->Yp-_cam->Y; + zp = light->Zp-_cam->Z; + MACRO_plMatrixApply(_cMatrix,xp,yp,zp,pl[0],pl[1],pl[2]); + } + _lights[_numlights++].light = light; +} + +static void _RenderObj(pl_Obj *obj, pl_Float *bmatrix, pl_Float *bnmatrix) { + pl_uInt32 i, x, facepos; + pl_Float nx = 0.0, ny = 0.0, nz = 0.0; + double tmp, tmp2; + pl_Float oMatrix[16], nMatrix[16], tempMatrix[16]; + + pl_Vertex *vertex; + pl_Face *face; + pl_Light *light; + + if (obj->GenMatrix) { + plMatrixRotate(nMatrix,1,obj->Xa); + plMatrixRotate(tempMatrix,2,obj->Ya); + plMatrixMultiply(nMatrix,tempMatrix); + plMatrixRotate(tempMatrix,3,obj->Za); + plMatrixMultiply(nMatrix,tempMatrix); + memcpy(oMatrix,nMatrix,sizeof(pl_Float)*16); + } else memcpy(nMatrix,obj->RotMatrix,sizeof(pl_Float)*16); + + if (bnmatrix) plMatrixMultiply(nMatrix,bnmatrix); + + if (obj->GenMatrix) { + plMatrixTranslate(tempMatrix, obj->Xp, obj->Yp, obj->Zp); + plMatrixMultiply(oMatrix,tempMatrix); + } else memcpy(oMatrix,obj->Matrix,sizeof(pl_Float)*16); + if (bmatrix) plMatrixMultiply(oMatrix,bmatrix); + + for (i = 0; i < PL_MAX_CHILDREN; i ++) + if (obj->Children[i]) _RenderObj(obj->Children[i],oMatrix,nMatrix); + if (!obj->NumFaces || !obj->NumVertices) return; + + plMatrixTranslate(tempMatrix, -_cam->X, -_cam->Y, -_cam->Z); + plMatrixMultiply(oMatrix,tempMatrix); + plMatrixMultiply(oMatrix,_cMatrix); + plMatrixMultiply(nMatrix,_cMatrix); + + x = obj->NumVertices; + vertex = obj->Vertices; + + do { + MACRO_plMatrixApply(oMatrix,vertex->x,vertex->y,vertex->z, + vertex->xformedx, vertex->xformedy, vertex->xformedz); + MACRO_plMatrixApply(nMatrix,vertex->nx,vertex->ny,vertex->nz, + vertex->xformednx,vertex->xformedny,vertex->xformednz); + vertex++; + } while (--x); + + face = obj->Faces; + facepos = _numfaces; + + if (_numfaces + obj->NumFaces >= PL_MAX_TRIANGLES) // exceeded maximum face coutn + { + return; + } + + plRender_TriStats[0] += obj->NumFaces; + _numfaces += obj->NumFaces; + x = obj->NumFaces; + + do { + if (obj->BackfaceCull || face->Material->_st & PL_SHADE_FLAT) + { + MACRO_plMatrixApply(nMatrix,face->nx,face->ny,face->nz,nx,ny,nz); + } + if (!obj->BackfaceCull || (MACRO_plDotProduct(nx,ny,nz, + face->Vertices[0]->xformedx, face->Vertices[0]->xformedy, + face->Vertices[0]->xformedz) < 0.0000001)) { + if (plClipNeeded(face)) { + if (face->Material->_st & (PL_SHADE_FLAT|PL_SHADE_FLAT_DISTANCE)) { + tmp = face->sLighting; + if (face->Material->_st & PL_SHADE_FLAT) { + for (i = 0; i < _numlights; i ++) { + tmp2 = 0.0; + light = _lights[i].light; + if (light->Type & PL_LIGHT_POINT_ANGLE) { + double nx2 = _lights[i].l[0] - face->Vertices[0]->xformedx; + double ny2 = _lights[i].l[1] - face->Vertices[0]->xformedy; + double nz2 = _lights[i].l[2] - face->Vertices[0]->xformedz; + MACRO_plNormalizeVector(nx2,ny2,nz2); + tmp2 = MACRO_plDotProduct(nx,ny,nz,nx2,ny2,nz2)*light->Intensity; + } + if (light->Type & PL_LIGHT_POINT_DISTANCE) { + double nx2 = _lights[i].l[0] - face->Vertices[0]->xformedx; + double ny2 = _lights[i].l[1] - face->Vertices[0]->xformedy; + double nz2 = _lights[i].l[2] - face->Vertices[0]->xformedz; + if (light->Type & PL_LIGHT_POINT_ANGLE) { + nx2 = (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/ + light->HalfDistSquared)); + tmp2 *= plMax(0,plMin(1.0,nx2))*light->Intensity; + } else { + tmp2 = (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/ + light->HalfDistSquared)); + tmp2 = plMax(0,plMin(1.0,tmp2))*light->Intensity; + } + } + if (light->Type == PL_LIGHT_VECTOR) + tmp2 = MACRO_plDotProduct(nx,ny,nz,_lights[i].l[0],_lights[i].l[1],_lights[i].l[2]) + * light->Intensity; + if (tmp2 > 0.0) tmp += tmp2; + else if (obj->BackfaceIllumination) tmp -= tmp2; + } /* End of light loop */ + } /* End of flat shading if */ + if (face->Material->_st & PL_SHADE_FLAT_DISTANCE) + tmp += 1.0-(face->Vertices[0]->xformedz+face->Vertices[1]->xformedz+ + face->Vertices[2]->xformedz) / + (face->Material->FadeDist*3.0); + face->fShade = (pl_Float) tmp; + } else face->fShade = 0.0; /* End of flatmask lighting if */ + if (face->Material->_ft & PL_FILL_ENVIRONMENT) { + face->eMappingU[0] = 32768 + (pl_sInt32) (face->Vertices[0]->xformednx*32768.0); + face->eMappingV[0] = 32768 - (pl_sInt32) (face->Vertices[0]->xformedny*32768.0); + face->eMappingU[1] = 32768 + (pl_sInt32) (face->Vertices[1]->xformednx*32768.0); + face->eMappingV[1] = 32768 - (pl_sInt32) (face->Vertices[1]->xformedny*32768.0); + face->eMappingU[2] = 32768 + (pl_sInt32) (face->Vertices[2]->xformednx*32768.0); + face->eMappingV[2] = 32768 - (pl_sInt32) (face->Vertices[2]->xformedny*32768.0); + } + if (face->Material->_st &(PL_SHADE_GOURAUD|PL_SHADE_GOURAUD_DISTANCE)) { + register pl_uChar a; + for (a = 0; a < 3; a ++) { + tmp = face->vsLighting[a]; + if (face->Material->_st & PL_SHADE_GOURAUD) { + for (i = 0; i < _numlights ; i++) { + tmp2 = 0.0; + light = _lights[i].light; + if (light->Type & PL_LIGHT_POINT_ANGLE) { + nx = _lights[i].l[0] - face->Vertices[a]->xformedx; + ny = _lights[i].l[1] - face->Vertices[a]->xformedy; + nz = _lights[i].l[2] - face->Vertices[a]->xformedz; + MACRO_plNormalizeVector(nx,ny,nz); + tmp2 = MACRO_plDotProduct(face->Vertices[a]->xformednx, + face->Vertices[a]->xformedny, + face->Vertices[a]->xformednz, + nx,ny,nz) * light->Intensity; + } + if (light->Type & PL_LIGHT_POINT_DISTANCE) { + double nx2 = _lights[i].l[0] - face->Vertices[a]->xformedx; + double ny2 = _lights[i].l[1] - face->Vertices[a]->xformedy; + double nz2 = _lights[i].l[2] - face->Vertices[a]->xformedz; + if (light->Type & PL_LIGHT_POINT_ANGLE) { + double t= (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/light->HalfDistSquared)); + tmp2 *= plMax(0,plMin(1.0,t))*light->Intensity; + } else { + tmp2 = (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/light->HalfDistSquared)); + tmp2 = plMax(0,plMin(1.0,tmp2))*light->Intensity; + } + } + if (light->Type == PL_LIGHT_VECTOR) + tmp2 = MACRO_plDotProduct(face->Vertices[a]->xformednx, + face->Vertices[a]->xformedny, + face->Vertices[a]->xformednz, + _lights[i].l[0],_lights[i].l[1],_lights[i].l[2]) + * light->Intensity; + if (tmp2 > 0.0) tmp += tmp2; + else if (obj->BackfaceIllumination) tmp -= tmp2; + } /* End of light loop */ + } /* End of gouraud shading if */ + if (face->Material->_st & PL_SHADE_GOURAUD_DISTANCE) + tmp += 1.0-face->Vertices[a]->xformedz/face->Material->FadeDist; + face->Shades[a] = (pl_Float) tmp; + } /* End of vertex loop for */ + } /* End of gouraud shading mask if */ + _faces[facepos].zd = face->Vertices[0]->xformedz+ + face->Vertices[1]->xformedz+face->Vertices[2]->xformedz; + _faces[facepos++].face = face; + plRender_TriStats[1] ++; + } /* Is it in our area Check */ + } /* Backface Check */ + _numfaces = facepos; + face++; + } while (--x); /* Face loop */ +} + +void plRenderObj(pl_Obj *obj) { + _RenderObj(obj,0,0); +} + +void plRenderEnd() { + _faceInfo *f; + if (_cam->Sort > 0) _hsort(_faces,_numfaces,0); + else if (_cam->Sort < 0) _hsort(_faces,_numfaces,1); + f = _faces; + while (_numfaces--) { + if (f->face->Material && f->face->Material->_PutFace) + { + plClipRenderFace(f->face); + } + f++; + } + _numfaces=0; + _numlights = 0; +} + +static _faceInfo *Base, tmp; + +static void _hsort(_faceInfo *base, int nel, int dir) { + static int i; + Base=base-1; + for (i=nel/2; i>0; i--) _sift_down(i,nel,dir); + for (i=nel; i>1; ) { + tmp = base[0]; base[0] = Base[i]; Base[i] = tmp; + _sift_down(1,i-=1,dir); + } +} + +#define Comp(x,y) (( x ).zd < ( y ).zd ? 1 : 0) + +static void _sift_down(int L, int U, int dir) { + static int c; + while (1) { + c=L+L; + if (c>U) break; + if ( (c < U) && dir^Comp(Base[c+1],Base[c])) c++; + if (dir^Comp(Base[L],Base[c])) return; + tmp = Base[L]; Base[L] = Base[c]; Base[c] = tmp; + L=c; + } +} +#undef Comp diff --git a/Src/Winamp/plush/SPLINE.C b/Src/Winamp/plush/SPLINE.C new file mode 100644 index 00000000..5a426f15 --- /dev/null +++ b/Src/Winamp/plush/SPLINE.C @@ -0,0 +1,49 @@ +/****************************************************************************** +Plush Version 1.2 +spline.c +n-th Dimensional Spline Interpolator +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +void plSplineGetPoint(pl_Spline *s, pl_Float frame, pl_Float *out) { + pl_sInt32 i, i_1, i0, i1, i2; + pl_Float time1,time2,time3; + pl_Float t1,t2,t3,t4,u1,u2,u3,u4,v1,v2,v3; + pl_Float a,b,c,d; + + pl_Float *keys = s->keys; + + a = (1-s->tens)*(1+s->cont)*(1+s->bias); + b = (1-s->tens)*(1-s->cont)*(1-s->bias); + c = (1-s->tens)*(1-s->cont)*(1+s->bias); + d = (1-s->tens)*(1+s->cont)*(1-s->bias); + v1 = t1 = -a / 2.0; u1 = a; + u2 = (-6-2*a+2*b+c)/2.0; v2 = (a-b)/2.0; t2 = (4+a-b-c) / 2.0; + t3 = (-4+b+c-d) / 2.0; + u3 = (6-2*b-c+d)/2.0; + v3 = b/2.0; + t4 = d/2.0; u4 = -t4; + + i0 = (pl_uInt) frame; + i_1 = i0 - 1; + while (i_1 < 0) i_1 += s->numKeys; + i1 = i0 + 1; + while (i1 >= s->numKeys) i1 -= s->numKeys; + i2 = i0 + 2; + while (i2 >= s->numKeys) i2 -= s->numKeys; + time1 = frame - (pl_Float) ((pl_uInt) frame); + time2 = time1*time1; + time3 = time2*time1; + i0 *= s->keyWidth; + i1 *= s->keyWidth; + i2 *= s->keyWidth; + i_1 *= s->keyWidth; + for (i = 0; i < s->keyWidth; i ++) { + a = t1*keys[i+i_1]+t2*keys[i+i0]+t3*keys[i+i1]+t4*keys[i+i2]; + b = u1*keys[i+i_1]+u2*keys[i+i0]+u3*keys[i+i1]+u4*keys[i+i2]; + c = v1*keys[i+i_1]+v2*keys[i+i0]+v3*keys[i+i1]; + *out++ = a*time3 + b*time2 + c*time1 + keys[i+i0]; + } +} diff --git a/Src/Winamp/plush/TEXT.C b/Src/Winamp/plush/TEXT.C new file mode 100644 index 00000000..ff555bb9 --- /dev/null +++ b/Src/Winamp/plush/TEXT.C @@ -0,0 +1,123 @@ +/****************************************************************************** +Plush Version 1.1 +text.c +Text code and data (8xX bitmapped) +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" +#include <stdarg.h> + +static pl_uChar font_height = 16; + +static pl_uChar *current_font = plText_DefaultFont; + +void plTextSetFont(pl_uChar *font, pl_uChar height) { + current_font = font; + font_height = height; +} + +void plTextPutChar(pl_Cam *cam, pl_sInt x, pl_sInt y, pl_Float z, + pl_uChar color, pl_uChar c) { + pl_uChar *font = current_font + (c*font_height); + pl_sInt offset = x+(y*cam->ScreenWidth); + pl_ZBuffer zz = (pl_ZBuffer) (1.0/z); + pl_sInt xx = x, a; + pl_uChar len = font_height; + pl_uChar ch; + pl_uChar *outmem; + pl_ZBuffer *zbuffer; + if (y+font_height < cam->ClipTop || y >= cam->ClipBottom) return; + if (y < cam->ClipTop) { + font += (cam->ClipTop-y); + offset += (cam->ClipTop-y)*cam->ScreenWidth; + len -= (cam->ClipTop-y); + y = cam->ClipTop; + } + if (y+font_height >= cam->ClipBottom) { + len = cam->ClipBottom-y; + } + if (len > 0) { + if (cam->zBuffer && z != 0.0) do { + outmem = cam->frameBuffer + offset; + zbuffer = cam->zBuffer + offset; + offset += cam->ScreenWidth; + xx = x; + ch = *font++; + a = 128; + while (a) { + if (xx >= cam->ClipRight) break; + if (xx++ >= cam->ClipLeft) + if (ch & a) + if (zz > *zbuffer) { + *zbuffer = zz; + *outmem = color; + } + zbuffer++; + outmem++; + a >>= 1; + } + if (a) break; + } while (--len); + else do { + outmem = cam->frameBuffer + offset; + offset += cam->ScreenWidth; + xx = x; + ch = *font++; + a = 128; + while (a) { + if (xx >= cam->ClipRight) break; + if (xx++ >= cam->ClipLeft) if (ch & a) *outmem = color; + outmem++; + a >>= 1; + } + if (a) break; + } while (--len); + } +} + +void plTextPutStr(pl_Cam *cam, pl_sInt x, pl_sInt y, pl_Float z, + pl_uChar color, pl_sChar *string) { + pl_sInt xx = x; + while (*string) { + switch (*string) { + case '\n': y += font_height; xx = x; break; + case ' ': xx += 8; break; + case '\r': break; + case '\t': xx += 8*5; break; + default: + plTextPutChar(cam,xx,y,z,color,(pl_uChar) *string); + xx += 8; + break; + } + string++; + } +} + +void plTextPutStrW(pl_Cam* cam, pl_sInt x, pl_sInt y, pl_Float z, + pl_uChar color, const wchar_t* string) { + pl_sInt xx = x; + while (*string) { + switch (*string) { + case L'\n': y += font_height; xx = x; break; + case L' ': xx += 8; break; + case L'\r': break; + case L'\t': xx += 8 * 5; break; + default: + plTextPutChar(cam, xx, y, z, color, (pl_uChar)*string); + xx += 8; + break; + } + string++; + } +} + +void plTextPrintf(pl_Cam *cam, pl_sInt x, pl_sInt y, pl_Float z, + pl_uChar color, pl_sChar *format, ...) { + va_list arglist; + pl_sChar str[256]; + va_start(arglist, format); + vsprintf((char *)str, (char *) format,arglist); + va_end(arglist); + plTextPutStr(cam,x,y,z,color,str); +} |