/* =============== Cmd_Skin Skins aren't actually stored in the file, only a reference is saved out to the header file. =============== */ static void process_skin(char *name, char *savename) { byte *palette; byte *pixels; int width, height; byte *cropped; int y; // load the image printf ("loading %s\n", name); Load256Image (name, &pixels, &palette, &width, &height); RemapZero (pixels, palette, width, height); // crop it to the proper size cropped = malloc (model.skinwidth*model.skinheight); for (y=0 ; y<model.skinheight ; y++) { memcpy (cropped+y*model.skinwidth, pixels+y*width, model.skinwidth); } // save off the new image printf ("saving %s\n", savename); CreatePath (savename); WritePCXfile (savename, cropped, model.skinwidth, model.skinheight, palette); free (pixels); free (palette); free (cropped); }
/* ============== Load32BitImage Any of the return pointers can be NULL if you don't want them. ============== */ void Load32BitImage(const char *name, unsigned **pixels, int *width, int *height) { char ext[128]; byte *palette; byte *pixels8; byte *pixels32; int size; int i; int v; ExtractFileExtension(name, ext); if(!Q_stricmp(ext, "tga")) { LoadTGA(name, (byte **) pixels, width, height); } else { Load256Image(name, &pixels8, &palette, width, height); if(!pixels) { return; } size = *width * *height; pixels32 = safe_malloc(size * 4); *pixels = (unsigned *)pixels32; for(i = 0; i < size; i++) { v = pixels8[i]; pixels32[i * 4 + 0] = palette[v * 3 + 0]; pixels32[i * 4 + 1] = palette[v * 3 + 1]; pixels32[i * 4 + 2] = palette[v * 3 + 2]; pixels32[i * 4 + 3] = 0xff; } } }
/* ================ LoadAlphaMap ================ */ byte *LoadAlphaMap( int *num_layers, int *alphawidth, int *alphaheight ) { int *alphamap32; byte *alphamap; const char *alphamapname; char ext[ 128 ]; int width; int height; int layers; int size; int i; assert( alphawidth ); assert( alphaheight ); assert( num_layers ); layers = atoi( ValueForKey( mapent, "layers" ) ); if ( layers < 1 ) { Error ("SetTerrainTextures: invalid value for 'layers' (%d)", layers ); } alphamapname = ValueForKey( mapent, "alphamap" ); if ( !alphamapname[ 0 ] ) { Error ("LoadAlphaMap: No alphamap specified on terrain" ); } ExtractFileExtension( alphamapname, ext); if ( !Q_stricmp( ext, "tga" ) ) { Load32BitImage( ExpandGamePath( alphamapname ), &alphamap32, &width, &height ); size = width * height; alphamap = malloc( size ); for( i = 0; i < size; i++ ) { alphamap[ i ] = ( ( alphamap32[ i ] & 0xff ) * layers ) / 256; if ( alphamap[ i ] >= layers ) { alphamap[ i ] = layers - 1; } } } else { Load256Image( ExpandGamePath( alphamapname ), &alphamap, NULL, &width, &height ); size = width * height; for( i = 0; i < size; i++ ) { if ( alphamap[ i ] >= layers ) { alphamap[ i ] = layers - 1; } } } if ( ( width < 2 ) || ( height < 2 ) ) { Error ("LoadAlphaMap: alphamap width/height must be at least 2x2." ); } *num_layers = layers; *alphawidth = width; *alphaheight = height; return alphamap; }
/* =============== Cmd_Load =============== */ void Cmd_Load (void) { char *name; GetToken (false); if (g_release) return; name = ExpandPathAndArchive(token); // load the image logprint ("loading %s\n", name); Load256Image (name, &byteimage, &lbmpalette, &byteimagewidth, &byteimageheight); RemapZero (byteimage, lbmpalette, byteimagewidth, byteimageheight); }
/* =============== Cmd_Skin Skins aren't actually stored in the file, only a reference is saved out to the header file. =============== */ void Cmd_Skin (void) { byte *palette; byte *pixels; int width, height; byte *cropped; int y; char name[1024], savename[1024]; GetScriptToken (false); if (model.num_skins == MAX_MD2SKINS) Error ("model.num_skins == MAX_MD2SKINS"); if (g_skipmodel) return; #if 1 sprintf (name, "%s/%s.pcx", cddir, token); sprintf (savename, "%s/!%s.pcx", g_outputDir, token); sprintf (g_skins[model.num_skins], "%s/!%s.pcx", cdpartial, token); #else sprintf (name, "%s/%s.lbm", cdarchive, token); strcpy (name, ExpandPathAndArchive( name ) ); // sprintf (name, "%s/%s.lbm", cddir, token); if (ScriptTokenAvailable()) { GetScriptToken (false); sprintf (g_skins[model.num_skins], "%s.pcx", token); sprintf (savename, "%s%s.pcx", g_outputDir, g_skins[model.num_skins]); } else { sprintf (savename, "%s/%s.pcx", g_outputDir, token); sprintf (g_skins[model.num_skins], "%s/%s.pcx", cdpartial, token); } #endif model.num_skins++; if (g_skipmodel || g_release || g_archive) return; // load the image printf ("loading %s\n", name); Load256Image (name, &pixels, &palette, &width, &height); // RemapZero (pixels, palette, width, height); // crop it to the proper size cropped = (byte *) SafeMalloc (model.skinwidth*model.skinheight, "Cmd_Skin"); for (y=0 ; y<model.skinheight ; y++) { memcpy (cropped+y*model.skinwidth, pixels+y*width, model.skinwidth); } // save off the new image printf ("saving %s\n", savename); CreatePath (savename); WritePCXfile (savename, cropped, model.skinwidth, model.skinheight, palette); free (pixels); free (palette); free (cropped); }
/* ================= Cmd_Base ================= */ void Cmd_Base (void) { vec3_t base_xyz[MAX_VERTS]; triangle_t *ptri; int i, j, k; #if 1 #else int time1; #endif char file1[1024]; char file2[1024]; GetScriptToken (false); if (g_skipmodel || g_release || g_archive) return; printf ("---------------------\n"); #if 1 sprintf (file1, "%s/%s", cdpartial, token); printf ("%s ", file1); ExpandPathAndArchive (file1); sprintf (file1, "%s/%s", cddir, token); #else sprintf (file1, "%s/%s.%s", cdarchive, token, trifileext); printf ("%s\n", file1); ExpandPathAndArchive (file1); sprintf (file1, "%s/%s.%s", cddir, token, trifileext); time1 = FileTime (file1); if (time1 == -1) Error ("%s doesn't exist", file1); #endif // // load the base triangles // if (do3ds) Load3DSTriangleList (file1, &ptri, &model.num_tris, NULL, NULL); else LoadTriangleList (file1, &ptri, &model.num_tris, NULL, NULL); GetScriptToken (false); sprintf (file2, "%s/%s.pcx", cddir, token); // sprintf (trans_file, "%s/!%s_a.pcx", cddir, token); printf ("skin: %s\n", file2); Load256Image (file2, &BasePixels, &BasePalette, &BaseWidth, &BaseHeight); if (BaseWidth != SKINPAGE_WIDTH || BaseHeight != SKINPAGE_HEIGHT) { if (g_allow_newskin) { ScaleWidth = BaseWidth; ScaleHeight = BaseHeight; } else { Error("Invalid skin page size: (%d,%d) should be (%d,%d)", BaseWidth,BaseHeight,SKINPAGE_WIDTH,SKINPAGE_HEIGHT); } } else { ScaleWidth = (float)ExtractNumber(BasePixels, ENCODED_WIDTH_X, ENCODED_WIDTH_Y); ScaleHeight = (float)ExtractNumber(BasePixels, ENCODED_HEIGHT_X, ENCODED_HEIGHT_Y); } // // get the ST values // BuildST (ptri, model.num_tris,false); // // run through all the base triangles, storing each unique vertex in the // base vertex list and setting the indirect triangles to point to the base // vertices // for (i=0 ; i<model.num_tris ; i++) { for (j=0 ; j<3 ; j++) { // get the xyz index for (k=0 ; k<model.num_xyz ; k++) if (VectorCompare (ptri[i].verts[j], base_xyz[k])) break; // this vertex is already in the base vertex list if (k == model.num_xyz) { // new index VectorCopy (ptri[i].verts[j], base_xyz[model.num_xyz]); if(clustered) ReplaceClusterIndex(k, ptri[i].indicies[j], (int **)&clusters, (IntListNode_t **)&vertLists, (int *)&num_verts, (int *)&new_num_verts); model.num_xyz++; } triangles[i].index_xyz[j] = k; // get the st index for (k=0 ; k<model.num_st ; k++) if (triangle_st[i][j][0] == base_st[k].s && triangle_st[i][j][1] == base_st[k].t) break; // this vertex is already in the base vertex list if (k == model.num_st) { // new index base_st[model.num_st].s = triangle_st[i][j][0]; base_st[model.num_st].t = triangle_st[i][j][1]; model.num_st++; } triangles[i].index_st[j] = k; } } // build triangle strips / fans BuildGlCmds (); }
/* ====================== CalcTextureReflectivity_Quake2 ====================== */ void CalcTextureReflectivity_Quake2( void ){ int i; int j, k, texels; int color[3]; int texel; byte *palette; char path[1024]; float r, scale; miptex_t *mt; sprintf( path, "%spics/colormap.pcx", gamedir ); // get the game palette Load256Image( path, NULL, &palette, NULL, NULL ); // allways set index 0 even if no textures texture_reflectivity[0][0] = 0.5; texture_reflectivity[0][1] = 0.5; texture_reflectivity[0][2] = 0.5; for ( i = 0 ; i < numtexinfo ; i++ ) { // see if an earlier texinfo allready got the value for ( j = 0 ; j < i ; j++ ) { if ( !strcmp( texinfo[i].texture, texinfo[j].texture ) ) { VectorCopy( texture_reflectivity[j], texture_reflectivity[i] ); break; } } if ( j != i ) { continue; } // load the wal file sprintf( path, "%stextures/%s.wal", gamedir, texinfo[i].texture ); if ( TryLoadFile( path, (void **)&mt ) == -1 ) { Sys_Printf( "Couldn't load %s\n", path ); texture_reflectivity[i][0] = 0.5; texture_reflectivity[i][1] = 0.5; texture_reflectivity[i][2] = 0.5; continue; } texels = LittleLong( mt->width ) * LittleLong( mt->height ); color[0] = color[1] = color[2] = 0; for ( j = 0 ; j < texels ; j++ ) { texel = ( (byte *)mt )[LittleLong( mt->offsets[0] ) + j]; for ( k = 0 ; k < 3 ; k++ ) color[k] += palette[texel * 3 + k]; } for ( j = 0 ; j < 3 ; j++ ) { r = color[j] / texels / 255.0; texture_reflectivity[i][j] = r; } // scale the reflectivity up, because the textures are // so dim scale = ColorNormalize( texture_reflectivity[i], texture_reflectivity[i] ); if ( scale < 0.5 ) { scale *= 2; VectorScale( texture_reflectivity[i], scale, texture_reflectivity[i] ); } #if 0 texture_reflectivity[i][0] = 0.5; texture_reflectivity[i][1] = 0.5; texture_reflectivity[i][2] = 0.5; #endif } }