+float ixtable[4096];
+
+void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist)
+{
+ int a, b, c, d;
+ float *out, v1[3], v2[3], normal[3];
+ int *u;
+ if (!ixtable[1])
+ {
+ ixtable[0] = 0;
+ for (a = 1;a < 4096;a++)
+ ixtable[a] = 1.0f / a;
+ }
+ // clear normals
+ memset(aliasvertnorm, 0, sizeof(float[3]) * vertcount);
+ memset(aliasvertusage, 0, sizeof(int) * vertcount);
+ // parse render list and accumulate surface normals
+ while(shadercount--)
+ {
+ d = *renderlist++;
+ while (d--)
+ {
+ a = renderlist[0]*3;
+ b = renderlist[1]*3;
+ c = renderlist[2]*3;
+ v1[0] = aliasvert[a+0] - aliasvert[b+0];
+ v1[1] = aliasvert[a+1] - aliasvert[b+1];
+ v1[2] = aliasvert[a+2] - aliasvert[b+2];
+ v2[0] = aliasvert[c+0] - aliasvert[b+0];
+ v2[1] = aliasvert[c+1] - aliasvert[b+1];
+ v2[2] = aliasvert[c+2] - aliasvert[b+2];
+ CrossProduct(v1, v2, normal);
+ VectorNormalize(normal);
+ // add surface normal to vertices
+ aliasvertnorm[a+0] += normal[0];
+ aliasvertnorm[a+1] += normal[1];
+ aliasvertnorm[a+2] += normal[2];
+ aliasvertusage[a]++;
+ aliasvertnorm[b+0] += normal[0];
+ aliasvertnorm[b+1] += normal[1];
+ aliasvertnorm[b+2] += normal[2];
+ aliasvertusage[b]++;
+ aliasvertnorm[c+0] += normal[0];
+ aliasvertnorm[c+1] += normal[1];
+ aliasvertnorm[c+2] += normal[2];
+ aliasvertusage[c]++;
+ renderlist += 3;
+ }
+ }
+ // average surface normals
+ out = aliasvertnorm;
+ u = aliasvertusage;
+ while(vertcount--)
+ {
+ if (*u > 1)
+ {
+ a = ixtable[*u];
+ out[0] *= a;
+ out[1] *= a;
+ out[2] *= a;
+ }
+ u++;
+ out += 3;
+ }
+}
+
+void GL_DrawZymoticModelMesh(byte *colors, zymtype1header_t *m)
+{
+ int i, c, *renderlist;
+ rtexture_t **texture;
+ if (!r_render.value)
+ return;
+ renderlist = (int *)(m->lump_render.start + (int) m);
+ texture = (rtexture_t **)(m->lump_shaders.start + (int) m);
+ glVertexPointer(3, GL_FLOAT, 0, aliasvert);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ glTexCoordPointer(2, GL_FLOAT, 0, (float *)(m->lump_texcoords.start + (int) m));
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ for (i = 0;i < m->numshaders;i++)
+ {
+ c = (*renderlist++) * 3;
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(*texture));
+ texture++;
+ glDrawElements(GL_TRIANGLES, c, GL_UNSIGNED_INT, renderlist);
+ renderlist += c;