| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239 |
- /*
- ** Command & Conquer Generals(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : Max2W3d *
- * *
- * $Archive:: /Commando/Code/Tools/max2w3d/w3dmtl.cpp $*
- * *
- * $Author:: Greg_h $*
- * *
- * $Modtime:: 8/22/01 7:47a $*
- * *
- * $Revision:: 32 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "w3dmtl.h"
- #include <Max.h>
- #include <StdMat.h>
- #include "gamemtl.h"
- #include "realcrc.h"
- static W3dRGBStruct Color_To_W3d(Color & c)
- {
- W3dRGBStruct wc;
- wc.R = (c.r * 255.0f);
- wc.G = (c.g * 255.0f);
- wc.B = (c.b * 255.0f);
- wc.pad = 0;
- return wc;
- }
- /*
- Implementation of W3dMapClass
- */
- W3dMapClass::W3dMapClass(const W3dMapClass & that)
- {
- Set_Filename(that.Filename);
- if (that.AnimInfo) {
- Set_Anim_Info(that.AnimInfo);
- }
- }
-
- W3dMapClass & W3dMapClass::operator = (const W3dMapClass & that)
- {
- if (this != &that) {
- Set_Filename(that.Filename);
- Set_Anim_Info(that.AnimInfo);
- }
- return *this;
- }
- W3dMapClass::~W3dMapClass(void)
- {
- if (Filename) free(Filename);
- if (AnimInfo) delete AnimInfo;
- }
- void W3dMapClass::Reset(void)
- {
- if (Filename) free(Filename);
- if (AnimInfo) delete AnimInfo;
- Filename = NULL;
- AnimInfo = NULL;
- }
- void W3dMapClass::Set_Filename(const char * fullpath)
- {
- if (Filename) {
- free(Filename);
- }
- if (fullpath) {
- char name[_MAX_FNAME];
- char exten[_MAX_EXT];
- char fname[_MAX_FNAME+_MAX_EXT+2];
- _splitpath(fullpath,NULL,NULL,name,exten);
- _makepath(fname,NULL,NULL,name,exten);
- //strupr(fname); (gth) need to preserve case since unix/PS2 is case sensitive...
- Filename = strdup(fname);
- } else {
- Filename = NULL;
- }
- }
- void W3dMapClass::Set_Anim_Info(const W3dTextureInfoStruct * info)
- {
- if (info == NULL) {
- if (AnimInfo) {
- delete AnimInfo;
- AnimInfo = NULL;
- return;
- }
- } else {
- if (AnimInfo == NULL) {
- AnimInfo = new W3dTextureInfoStruct;
- }
- *AnimInfo = *info;
- }
- }
- void W3dMapClass::Set_Anim_Info(int framecount,float framerate)
- {
- if (AnimInfo == NULL) {
- AnimInfo = new W3dTextureInfoStruct;
- }
- AnimInfo->FrameCount = framecount;
- AnimInfo->FrameRate = framerate;
- }
- /*
-
- Implementation of W3dMaterialClass
- */
- W3dMaterialClass::W3dMaterialClass(void)
- {
- PassCount = 0;
- SortLevel = SORT_LEVEL_NONE;
- for (int pass = 0; pass < MAX_PASSES; pass++) {
- Materials[pass] = NULL;
- W3d_Shader_Reset(&(Shaders[pass]));
- for (int stage = 0; stage < MAX_STAGES; stage++) {
- Textures[pass][stage] = NULL;
- MapChannel[pass][stage] = 1;
- MapperArgs[pass][stage] = NULL;
- }
- }
- }
- W3dMaterialClass::~W3dMaterialClass(void)
- {
- Free();
- }
- void W3dMaterialClass::Free(void)
- {
- for (int pass = 0; pass < MAX_PASSES; pass++) {
-
- if (Materials[pass]) {
- delete Materials[pass];
- Materials[pass] = NULL;
- }
- for (int stage = 0; stage < MAX_STAGES; stage++) {
- if (Textures[pass][stage]) {
- delete Textures[pass][stage];
- Textures[pass][stage] = NULL;
- }
- if (MapperArgs[pass][stage]) {
- delete [] MapperArgs[pass][stage];
- MapperArgs[pass][stage] = NULL;
- }
- }
- }
- }
- void W3dMaterialClass::Reset(void)
- {
- Free();
- SortLevel = SORT_LEVEL_NONE;
- for (int pass=0; pass < MAX_PASSES; pass++) {
- W3d_Shader_Reset(&(Shaders[pass]));
-
- for (int stage=0; stage < MAX_STAGES; stage++) {
- MapChannel[pass][stage] = 1;
- }
- }
- }
- void W3dMaterialClass::Set_Surface_Type(unsigned int type)
- {
- SurfaceType = type;
- }
- void W3dMaterialClass::Set_Sort_Level(int level)
- {
- assert(level <= MAX_SORT_LEVEL);
- SortLevel = level;
- }
- void W3dMaterialClass::Set_Pass_Count(int count)
- {
- assert(count >= 0);
- assert(count < MAX_PASSES);
- PassCount = count;
- }
- void W3dMaterialClass::Set_Vertex_Material(const W3dVertexMaterialStruct & vmat,int pass)
- {
- assert(pass >= 0);
- assert(pass < PassCount);
- if (Materials[pass] == NULL) {
- Materials[pass] = new W3dVertexMaterialStruct;
- }
- *(Materials[pass]) = vmat;
- }
- void W3dMaterialClass::Set_Mapper_Args(const char *args_buffer, int pass, int stage)
- {
- assert(pass >= 0);
- assert(pass < PassCount);
- assert(stage >= 0);
- assert(stage < MAX_STAGES);
- if (MapperArgs[pass][stage] != NULL) {
- delete [] MapperArgs[pass][stage];
- MapperArgs[pass][stage] = NULL;
- }
- if (args_buffer) {
- int len = strlen(args_buffer);
- MapperArgs[pass][stage] = new char [len + 1];
- strcpy(MapperArgs[pass][stage], args_buffer);
- }
- }
- void W3dMaterialClass::Set_Shader(const W3dShaderStruct & shader,int pass)
- {
- assert(pass >= 0);
- assert(pass < PassCount);
- Shaders[pass] = shader;
- }
- void W3dMaterialClass::Set_Texture(const W3dMapClass & map,int pass,int stage)
- {
- assert(pass >= 0);
- assert(pass < PassCount);
- if (Textures[pass][stage] == NULL) {
- Textures[pass][stage] = new W3dMapClass;
- }
- *(Textures[pass][stage]) = map;
- }
- void W3dMaterialClass::Set_Map_Channel(int pass,int stage,int channel)
- {
- assert(pass >= 0);
- assert(pass < PassCount);
- MapChannel[pass][stage] = channel;
- }
- unsigned int W3dMaterialClass::Get_Surface_Type(void) const
- {
- return SurfaceType;
- }
- int W3dMaterialClass::Get_Sort_Level(void) const
- {
- return SortLevel;
- }
- int W3dMaterialClass::Get_Pass_Count(void) const
- {
- return PassCount;
- }
- W3dVertexMaterialStruct * W3dMaterialClass::Get_Vertex_Material(int pass ) const
- {
- assert(pass >= 0);
- assert(pass < PassCount);
-
- return Materials[pass];
- }
- const char * W3dMaterialClass::Get_Mapper_Args(int pass, int stage) const
- {
- assert(pass >= 0);
- assert(pass < PassCount);
- assert(stage >= 0);
- assert(stage < MAX_STAGES);
-
- return MapperArgs[pass][stage];
- }
- W3dShaderStruct W3dMaterialClass::Get_Shader(int pass) const
- {
- assert(pass >= 0);
- assert(pass < PassCount);
- return Shaders[pass];
- }
- W3dMapClass * W3dMaterialClass::Get_Texture(int pass,int stage) const
- {
- assert(pass >= 0);
- assert(pass < PassCount);
- assert(stage >= 0);
- assert(stage < MAX_STAGES);
-
- return Textures[pass][stage];
- }
- int W3dMaterialClass::Get_Map_Channel(int pass,int stage) const
- {
- assert(pass >= 0);
- assert(pass < PassCount);
- assert(stage >= 0);
- assert(stage < MAX_STAGES);
- return MapChannel[pass][stage];
- }
- void W3dMaterialClass::Init(Mtl * mtl, char *materialColorTexture)
- {
- bool ps2_mat = false;
- Reset();
- if (mtl->ClassID() == PS2GameMaterialClassID)
- {
- ps2_mat = true;
- }
- if ((mtl->ClassID() == GameMaterialClassID) || ps2_mat) {
- Init((GameMtl*)mtl, materialColorTexture); ///@todo: Fix this for substituted textures.
- return;
- }
- Texmap * tmap;
- PassCount = 1;
- tmap = mtl->GetSubTexmap(ID_RL);
- if (tmap && tmap->ClassID() == Class_ID(BMTEX_CLASS_ID,0)) {
- PassCount++;
- }
- W3dVertexMaterialStruct mat;
- W3dShaderStruct shader;
- W3dMapClass tex;
- /*
- ** Setting up the diffuse color pass
- */
- W3d_Shader_Reset(&shader);
- mat.Attributes = 0;
- mat.Emissive.R = mat.Emissive.G = mat.Emissive.B = 0; //(uint8)(255 .0f * mtl->GetSelfIllum());
-
- Color diffuse = mtl->GetDiffuse();
- mat.Diffuse.R = (uint8)(diffuse.r * 255.0f);
- mat.Diffuse.G = (uint8)(diffuse.g * 255.0f);
- mat.Diffuse.B = (uint8)(diffuse.b * 255.0f);
- mat.Ambient = mat.Diffuse;
- Color specular = mtl->GetSpecular();
- mat.Specular.R = (uint8)(specular.r * 255.0f);
- mat.Specular.G = (uint8)(specular.g * 255.0f);
- mat.Specular.B = (uint8)(specular.b * 255.0f);
- mat.Shininess = mtl->GetShininess();
- mat.Opacity = 1.0f - mtl->GetXParency();
- mat.Translucency = 0.0f;
- tmap = mtl->GetSubTexmap(ID_DI);
- if (tmap && tmap->ClassID() == Class_ID(BMTEX_CLASS_ID,0)) {
- char * tname = ((BitmapTex *)tmap)->GetMapName();
- if (tname) {
- tex.Set_Filename(tname);
- mat.Diffuse.R = mat.Diffuse.G = mat.Diffuse.B = 255;
- W3d_Shader_Set_Texturing(&shader,W3DSHADER_TEXTURING_ENABLE);
- Set_Texture(tex,0,0);
- }
- }
- if (materialColorTexture && !mtl->GetSubTexmap(ID_DI) && !mtl->GetSubTexmap(ID_RL))
- { //no textures on material, substitute textures to improve rendering speed.
- tex.Set_Filename(materialColorTexture); ///@todo: Fix this to procedural name/path
- W3d_Shader_Set_Texturing(&shader,W3DSHADER_TEXTURING_ENABLE);
- //This texture will hold solid pixels of material color, don't need any filtering.
- // W3dTextureInfoStruct texinfo;
- // memset(&texinfo,0,sizeof(texinfo));
- // texinfo.Attributes = texinfo.Attributes | /*W3DTEXTURE_NO_LOD|*/W3DTEXTURE_CLAMP_U | W3DTEXTURE_CLAMP_V;
- // tex.Set_Anim_Info(&texinfo);
- Set_Texture(tex,0,0);
- }
- if (mat.Opacity != 1.0f) {
- W3d_Shader_Set_Dest_Blend_Func(&shader,W3DSHADER_DESTBLENDFUNC_ONE_MINUS_SRC_ALPHA);
- W3d_Shader_Set_Src_Blend_Func(&shader,W3DSHADER_SRCBLENDFUNC_SRC_ALPHA);
- }
-
- Set_Vertex_Material(mat,0);
- Set_Shader(shader,0);
- /*
- ** Setting up the reflection pass (envmap)
- */
- if (PassCount == 2) {
- W3d_Shader_Reset(&shader);
- if (ps2_mat)
- {
- W3d_Shader_Set_Pri_Gradient(&shader,PSS_PRIGRADIENT_MODULATE);
- }
- else
- {
- W3d_Shader_Set_Pri_Gradient(&shader,W3DSHADER_PRIGRADIENT_MODULATE);
- }
- W3d_Shader_Set_Sec_Gradient(&shader,W3DSHADER_SECGRADIENT_DISABLE);
- W3d_Shader_Set_Depth_Mask(&shader,W3DSHADER_DEPTHMASK_WRITE_DISABLE);
- W3d_Shader_Set_Dest_Blend_Func(&shader,W3DSHADER_DESTBLENDFUNC_ONE);
- W3d_Shader_Set_Src_Blend_Func(&shader,W3DSHADER_SRCBLENDFUNC_ONE);
- W3d_Shader_Set_Texturing(&shader,W3DSHADER_TEXTURING_ENABLE);
- // PS2 specific paramaters.
- W3d_Shader_Set_PS2_Param_A(&shader, PSS_SRC);
- W3d_Shader_Set_PS2_Param_B(&shader, PSS_ZERO);
- W3d_Shader_Set_PS2_Param_B(&shader, PSS_ONE);
- W3d_Shader_Set_PS2_Param_B(&shader, PSS_DEST);
- W3d_Vertex_Material_Reset(&mat);
- mat.Diffuse.R = mat.Diffuse.G = mat.Diffuse.B = 128;
- mat.Attributes &= W3DVERTMAT_STAGE0_MAPPING_MASK;
- mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_ENVIRONMENT;
- tmap = mtl->GetSubTexmap(ID_RL);
- if (tmap && tmap->ClassID() == Class_ID(BMTEX_CLASS_ID,0)) {
- char * tname = ((BitmapTex *)tmap)->GetMapName();
- if (tname) {
- tex.Set_Filename(tname);
- Set_Texture(tex,1);
- }
- }
- Set_Vertex_Material(mat,1);
- Set_Shader(shader,1);
- }
- }
- void W3dMaterialClass::Init(GameMtl * gamemtl, char *materialColorTexture)
- {
- Reset();
- PassCount = gamemtl->Get_Pass_Count();
- Set_Surface_Type (gamemtl->Get_Surface_Type ());
- Set_Sort_Level(gamemtl->Get_Sort_Level());
- for (int pass=0;pass<gamemtl->Get_Pass_Count(); pass++) {
- /*
- ** set up the shader
- */
- W3dShaderStruct shader;
- W3d_Shader_Reset(&shader);
- shader.DepthCompare = gamemtl->Get_Depth_Compare(pass);
- shader.DepthMask = gamemtl->Get_Depth_Mask(pass);
- shader.AlphaTest = gamemtl->Get_Alpha_Test(pass);
- shader.DestBlend = gamemtl->Get_Dest_Blend(pass);
- shader.PriGradient = gamemtl->Get_Pri_Gradient(pass);
- shader.SecGradient = gamemtl->Get_Sec_Gradient(pass);
- shader.SrcBlend = gamemtl->Get_Src_Blend(pass);
- shader.DetailColorFunc = gamemtl->Get_Detail_Color_Func(pass);
- shader.DetailAlphaFunc = gamemtl->Get_Detail_Alpha_Func(pass);
- shader.Texturing = W3DSHADER_TEXTURING_DISABLE;
- shader.PostDetailColorFunc = gamemtl->Get_Detail_Color_Func(pass); // (gth) set up the post-detail options
- shader.PostDetailAlphaFunc = gamemtl->Get_Detail_Alpha_Func(pass);
- // PS2 specific paramaters.
- W3d_Shader_Set_PS2_Param_A(&shader, gamemtl->Get_PS2_Shader_Param_A(pass));
- W3d_Shader_Set_PS2_Param_B(&shader, gamemtl->Get_PS2_Shader_Param_B(pass));
- W3d_Shader_Set_PS2_Param_C(&shader, gamemtl->Get_PS2_Shader_Param_C(pass));
- W3d_Shader_Set_PS2_Param_D(&shader, gamemtl->Get_PS2_Shader_Param_D(pass));
- /*
- ** set up the vertex material
- */
- W3dVertexMaterialStruct mat;
- mat.Attributes = 0;
-
- if (gamemtl->Get_Copy_Specular_To_Diffuse(pass)) {
- mat.Attributes |= W3DVERTMAT_COPY_SPECULAR_TO_DIFFUSE;
- }
- // mapping type for stage 0
- switch(gamemtl->Get_Mapping_Type(pass, 0))
- {
- case GAMEMTL_MAPPING_UV: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_UV; break;
- case GAMEMTL_MAPPING_ENV: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_ENVIRONMENT; break;
- case GAMEMTL_MAPPING_CHEAP_ENV: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_CHEAP_ENVIRONMENT; break;
- case GAMEMTL_MAPPING_SCREEN: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_SCREEN; break;
- case GAMEMTL_MAPPING_LINEAR_OFFSET: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_LINEAR_OFFSET; break;
- case GAMEMTL_MAPPING_SILHOUETTE: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_SILHOUETTE; break;
- case GAMEMTL_MAPPING_SCALE: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_SCALE; break;
- case GAMEMTL_MAPPING_GRID: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_GRID; break;
- case GAMEMTL_MAPPING_ROTATE: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_ROTATE; break;
- case GAMEMTL_MAPPING_SINE_LINEAR_OFFSET: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_SINE_LINEAR_OFFSET; break;
- case GAMEMTL_MAPPING_STEP_LINEAR_OFFSET: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_STEP_LINEAR_OFFSET; break;
- case GAMEMTL_MAPPING_ZIGZAG_LINEAR_OFFSET: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_ZIGZAG_LINEAR_OFFSET; break;
- case GAMEMTL_MAPPING_WS_CLASSIC_ENV: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_WS_CLASSIC_ENV; break;
- case GAMEMTL_MAPPING_WS_ENVIRONMENT: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_WS_ENVIRONMENT; break;
- case GAMEMTL_MAPPING_GRID_CLASSIC_ENV: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_GRID_CLASSIC_ENV; break;
- case GAMEMTL_MAPPING_GRID_ENVIRONMENT: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_GRID_ENVIRONMENT; break;
- case GAMEMTL_MAPPING_RANDOM: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_RANDOM; break;
- case GAMEMTL_MAPPING_EDGE: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_EDGE; break;
- case GAMEMTL_MAPPING_BUMPENV: mat.Attributes |= W3DVERTMAT_STAGE0_MAPPING_BUMPENV; break;
- };
- // mapping type for stage 1
- switch(gamemtl->Get_Mapping_Type(pass, 1))
- {
- case GAMEMTL_MAPPING_UV: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_UV; break;
- case GAMEMTL_MAPPING_ENV: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_ENVIRONMENT; break;
- case GAMEMTL_MAPPING_CHEAP_ENV: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_CHEAP_ENVIRONMENT; break;
- case GAMEMTL_MAPPING_SCREEN: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_SCREEN; break;
- case GAMEMTL_MAPPING_LINEAR_OFFSET: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_LINEAR_OFFSET; break;
- case GAMEMTL_MAPPING_SILHOUETTE: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_SILHOUETTE; break;
- case GAMEMTL_MAPPING_SCALE: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_SCALE; break;
- case GAMEMTL_MAPPING_GRID: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_GRID; break;
- case GAMEMTL_MAPPING_ROTATE: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_ROTATE; break;
- case GAMEMTL_MAPPING_SINE_LINEAR_OFFSET: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_SINE_LINEAR_OFFSET; break;
- case GAMEMTL_MAPPING_STEP_LINEAR_OFFSET: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_STEP_LINEAR_OFFSET; break;
- case GAMEMTL_MAPPING_ZIGZAG_LINEAR_OFFSET: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_ZIGZAG_LINEAR_OFFSET; break;
- case GAMEMTL_MAPPING_WS_CLASSIC_ENV: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_WS_CLASSIC_ENV; break;
- case GAMEMTL_MAPPING_WS_ENVIRONMENT: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_WS_ENVIRONMENT; break;
- case GAMEMTL_MAPPING_GRID_CLASSIC_ENV: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_GRID_CLASSIC_ENV; break;
- case GAMEMTL_MAPPING_GRID_ENVIRONMENT: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_GRID_ENVIRONMENT; break;
- case GAMEMTL_MAPPING_RANDOM: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_RANDOM; break;
- case GAMEMTL_MAPPING_EDGE: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_EDGE; break;
- case GAMEMTL_MAPPING_BUMPENV: mat.Attributes |= W3DVERTMAT_STAGE1_MAPPING_BUMPENV; break;
- };
- switch(gamemtl->Get_PSX_Translucency(pass))
- {
- case GAMEMTL_PSX_TRANS_NONE: mat.Attributes |= W3DVERTMAT_PSX_TRANS_NONE; break;
- case GAMEMTL_PSX_TRANS_100: mat.Attributes |= W3DVERTMAT_PSX_TRANS_100; break;
- case GAMEMTL_PSX_TRANS_50: mat.Attributes |= W3DVERTMAT_PSX_TRANS_50; break;
- case GAMEMTL_PSX_TRANS_25: mat.Attributes |= W3DVERTMAT_PSX_TRANS_25; break;
- case GAMEMTL_PSX_TRANS_MINUS_100:mat.Attributes |= W3DVERTMAT_PSX_TRANS_MINUS_100; break;
- };
- if (!gamemtl->Get_PSX_Lighting(pass)) {
- mat.Attributes |= W3DVERTMAT_PSX_NO_RT_LIGHTING;
- }
- mat.Ambient = Color_To_W3d(gamemtl->Get_Ambient(pass,0));
- mat.Diffuse = Color_To_W3d(gamemtl->Get_Diffuse(pass,0));
- mat.Specular = Color_To_W3d(gamemtl->Get_Specular(pass,0));
- mat.Emissive = Color_To_W3d(gamemtl->Get_Emissive(pass,0));
- mat.Shininess = gamemtl->Get_Shininess(pass,0);
- mat.Opacity = gamemtl->Get_Opacity(pass,0);
- mat.Translucency = gamemtl->Get_Translucency(pass,0);
- /*
- ** install the two textures if present
- */
- W3dMapClass w3dmap;
- BitmapTex * tex = NULL;
- for (int stage=0; stage < MAX_STAGES; stage++) {
-
- if (gamemtl->Get_Texture_Enable(pass,stage) && gamemtl->Get_Texture(pass,stage)) {
-
- w3dmap.Reset();
-
- // get the filename for the w3dmap texture
- tex = (BitmapTex *)gamemtl->Get_Texture(pass,stage);
- assert(tex->GetMapName());
- w3dmap.Set_Filename(tex->GetMapName());
-
- // get the animation and flags for the w3dmap texture
- W3dTextureInfoStruct texinfo;
- memset(&texinfo,0,sizeof(texinfo));
-
- texinfo.AnimType = gamemtl->Get_Texture_Anim_Type(pass,stage);
- if (gamemtl->Get_Texture_Publish(pass,stage)) {
- texinfo.Attributes = texinfo.Attributes | W3DTEXTURE_PUBLISH;
- }
- if (gamemtl->Get_Texture_No_LOD(pass,stage)) {
- texinfo.Attributes = texinfo.Attributes | W3DTEXTURE_NO_LOD;
- }
- if (gamemtl->Get_Texture_Clamp_U(pass,stage)) {
- texinfo.Attributes = texinfo.Attributes | W3DTEXTURE_CLAMP_U;
- }
- if (gamemtl->Get_Texture_Clamp_V(pass,stage)) {
- texinfo.Attributes = texinfo.Attributes | W3DTEXTURE_CLAMP_V;
- }
- if (gamemtl->Get_Texture_Alpha_Bitmap(pass,stage)) {
- texinfo.Attributes = texinfo.Attributes | W3DTEXTURE_ALPHA_BITMAP;
- }
- texinfo.Attributes = texinfo.Attributes | (
- (gamemtl->Get_Texture_Hint(pass,stage) << W3DTEXTURE_HINT_SHIFT)
- & W3DTEXTURE_HINT_MASK);
- // If the shader indicates bump-environment mapping mark this texture as a bumpmap.
- if ((stage == 0) && (gamemtl->Get_Pri_Gradient (pass) == W3DSHADER_PRIGRADIENT_BUMPENVMAP)) {
- texinfo.Attributes |= W3DTEXTURE_TYPE_BUMPMAP;
- }
- texinfo.FrameCount = gamemtl->Get_Texture_Frame_Count(pass,stage);
- texinfo.FrameRate = gamemtl->Get_Texture_Frame_Rate(pass,stage);
- if ((texinfo.FrameCount > 1) || (texinfo.Attributes != 0)) {
- w3dmap.Set_Anim_Info(&texinfo);
- }
-
- // plug it in and turn on texturing in the shader
- Set_Texture(w3dmap,pass,stage);
- shader.Texturing = W3DSHADER_TEXTURING_ENABLE;
-
- // copy over the mapping channel
- Set_Map_Channel(pass,stage,gamemtl->Get_Map_Channel(pass,stage));
-
- // copy over the mapper args
- Set_Mapper_Args(gamemtl->Get_Mapping_Arg_Buffer(pass, stage), pass, stage);
- } else {
- if (materialColorTexture)
- { //no textures on material, substitute textures to improve rendering speed.
- w3dmap.Reset();
- w3dmap.Set_Filename(materialColorTexture);
-
- // plug it in and turn on texturing in the shader
- Set_Texture(w3dmap,pass,stage);
- shader.Texturing = W3DSHADER_TEXTURING_ENABLE;
- }
- break; // break out of the loop (and dont put in stage 1 if stage 0 is missing...)
- }
- }
- Set_Shader(shader,pass);
- Set_Vertex_Material(mat,pass);
- }
- }
- bool W3dMaterialClass::Is_Multi_Pass_Transparent(void) const
- {
- return ((PassCount >= 2) && (Get_Shader(0).DestBlend != W3DSHADER_DESTBLENDFUNC_ZERO));
- }
- /*
-
- Implementation of W3dMaterialDescClass::VertClass
- */
- W3dMaterialDescClass::VertMatClass::VertMatClass(void) :
- PassIndex(-1),
- Crc(0),
- Name(NULL)
- {
- for (int stage=0; stage < W3dMaterialClass::MAX_STAGES; ++stage) {
- MapperArgs[stage] = NULL;
- }
- }
- W3dMaterialDescClass::VertMatClass::~VertMatClass(void)
- {
- if (Name) free(Name);
- for (int stage=0; stage < W3dMaterialClass::MAX_STAGES; ++stage) {
- if (MapperArgs[stage]) {
- delete [] (MapperArgs[stage]);
- MapperArgs[stage] = NULL;
- }
- }
- }
- W3dMaterialDescClass::VertMatClass &
- W3dMaterialDescClass::VertMatClass::operator = (const VertMatClass & that)
- {
- if (this != &that) {
- Material = that.Material;
- PassIndex = that.PassIndex;
- Crc = that.Crc;
- Set_Name(that.Name);
- for (int stage=0; stage < W3dMaterialClass::MAX_STAGES; stage++) {
- Set_Mapper_Args(that.MapperArgs[stage], stage);
- }
- }
- return *this;
- }
- bool W3dMaterialDescClass::VertMatClass::operator != (const VertMatClass & that)
- {
- return !(*this == that);
- }
- bool W3dMaterialDescClass::VertMatClass::operator == (const VertMatClass & that)
- {
- assert(0); return false;
- }
- void W3dMaterialDescClass::VertMatClass::Set_Name(const char * name)
- {
- if (Name) free(Name);
-
- if (name) {
- Name = strdup(name);
- } else {
- Name = NULL;
- }
- }
- void W3dMaterialDescClass::VertMatClass::Set_Mapper_Args(const char * args, int stage)
- {
- if (MapperArgs[stage]) {
- delete [] (MapperArgs[stage]);
- MapperArgs[stage] = NULL;
- }
-
- if (args) {
- int len = strlen(args);
- MapperArgs[stage] = new char [len + 1];
- strcpy(MapperArgs[stage], args);
- } else {
- MapperArgs[stage] = NULL;
- }
- }
- /*
-
- Implementation of W3dMaterialDescClass
- */
- W3dMaterialDescClass::MaterialRemapClass::MaterialRemapClass(void)
- {
- PassCount = -1;
- for (int pass=0; pass<W3dMaterialClass::MAX_PASSES; pass++) {
- VertexMaterialIdx[pass] = -1;
- ShaderIdx[pass] = -1;
- for (int stage=0; stage<W3dMaterialClass::MAX_STAGES; stage++) {
- TextureIdx[pass][stage] = -1;
- }
- }
- }
- bool W3dMaterialDescClass::MaterialRemapClass::operator != (const MaterialRemapClass & that)
- {
- return !(*this == that);
- }
- bool W3dMaterialDescClass::MaterialRemapClass::operator == (const MaterialRemapClass & that)
- {
- for (int pass=0; pass<W3dMaterialClass::MAX_PASSES; pass++) {
-
- if (VertexMaterialIdx[pass] != that.VertexMaterialIdx[pass]) return false;
- if (ShaderIdx[pass] != that.ShaderIdx[pass]) return false;
- for (int stage=0; stage<W3dMaterialClass::MAX_STAGES; stage++) {
-
- if (TextureIdx[pass][stage] != that.TextureIdx[pass][stage]) return false;
- }
- }
- return true;
- }
- W3dMaterialDescClass::W3dMaterialDescClass(void)
- {
- Reset();
- }
- W3dMaterialDescClass::~W3dMaterialDescClass(void)
- {
- }
- void W3dMaterialDescClass::Reset(void)
- {
- PassCount = -1;
- SortLevel = -1;
- MaterialRemaps.Clear();
- Shaders.Clear();
- VertexMaterials.Clear();
- Textures.Clear();
- }
- W3dMaterialDescClass::ErrorType W3dMaterialDescClass::Add_Material(const W3dMaterialClass & mat,const char * name)
- {
- /*
- ** If passes hasn't been set yet, set it.
- */
- if (PassCount == -1) {
- PassCount = mat.Get_Pass_Count();
- }
- /*
- ** Same for sort level.
- */
- if (SortLevel == -1) {
- SortLevel = mat.Get_Sort_Level();
- }
- /*
- ** Verify that this material uses the same number of passes that any
- ** other materials we have use.
- */
- if (mat.Get_Pass_Count() != PassCount) {
- return INCONSISTENT_PASSES;
- }
- if (mat.Is_Multi_Pass_Transparent()) {
- char msg[100];
- sprintf(msg,"Enable Multipass-Transparency?");
- HWND window=GetForegroundWindow();
- if (IDYES!=MessageBox(window,msg,"Confirmation",MB_YESNO|MB_ICONINFORMATION|MB_TASKMODAL))
- return MULTIPASS_TRANSPARENT;
- }
- /*
- ** Verify that this material uses the same sort level as all other
- ** materials used on this mesh.
- */
- if (mat.Get_Sort_Level() != SortLevel) {
- return INCONSISTENT_SORT_LEVEL;
- }
-
- /*
- ** Ok, lets re-index this material and store the unique parts
- */
- MaterialRemapClass remap;
- for (int pass=0; pass<PassCount; pass++) {
- remap.VertexMaterialIdx[pass] = Add_Vertex_Material(
- mat.Get_Vertex_Material(pass),mat.Get_Mapper_Args(pass, 0),mat.Get_Mapper_Args(pass, 1),pass,name);
- remap.ShaderIdx[pass] = Add_Shader(mat.Get_Shader(pass),pass);
-
- for (int stage=0; stage<W3dMaterialClass::MAX_STAGES; stage++) {
- remap.TextureIdx[pass][stage] = Add_Texture(mat.Get_Texture(pass,stage),pass,stage);
- remap.MapChannel[pass][stage] = mat.Get_Map_Channel(pass,stage);
-
- }
- }
- MaterialRemaps.Add(remap);
- return OK;
- }
- int W3dMaterialDescClass::Material_Count(void)
- {
- return MaterialRemaps.Count();
- }
- int W3dMaterialDescClass::Pass_Count(void)
- {
- return PassCount;
- }
- int W3dMaterialDescClass::Vertex_Material_Count(void)
- {
- return VertexMaterials.Count();
- }
- int W3dMaterialDescClass::Shader_Count(void)
- {
- return Shaders.Count();
- }
- int W3dMaterialDescClass::Texture_Count(void)
- {
- return Textures.Count();
- }
- int W3dMaterialDescClass::Get_Sort_Level(void)
- {
- return SortLevel;
- }
- W3dVertexMaterialStruct * W3dMaterialDescClass::Get_Vertex_Material(int vmat_index)
- {
- assert(vmat_index >= 0);
- assert(vmat_index < VertexMaterials.Count());
- return &(VertexMaterials[vmat_index].Material);
- }
- const char * W3dMaterialDescClass::Get_Mapper_Args(int vmat_index, int stage)
- {
- assert(vmat_index >= 0);
- assert(vmat_index < VertexMaterials.Count());
- assert(stage >= 0);
- assert(stage < W3dMaterialClass::MAX_STAGES);
- return VertexMaterials[vmat_index].MapperArgs[stage];
- }
- W3dShaderStruct * W3dMaterialDescClass::Get_Shader(int shader_index)
- {
- assert(shader_index >= 0);
- assert(shader_index < Shaders.Count());
- return &(Shaders[shader_index].Shader);
- }
- W3dMapClass * W3dMaterialDescClass::Get_Texture(int texture_index)
- {
- assert(texture_index >= 0);
- assert(texture_index < Textures.Count());
- return &(Textures[texture_index].Map);
- }
- int W3dMaterialDescClass::Get_Vertex_Material_Index(int mat_index,int pass)
- {
- assert(mat_index >= 0);
- assert(mat_index < MaterialRemaps.Count());
- assert(pass >= 0);
- assert(pass < PassCount);
- return MaterialRemaps[mat_index].VertexMaterialIdx[pass];
- }
- int W3dMaterialDescClass::Get_Shader_Index(int mat_index,int pass)
- {
- assert(mat_index >= 0);
- assert(mat_index < MaterialRemaps.Count());
- assert(pass >= 0);
- assert(pass < PassCount);
- return MaterialRemaps[mat_index].ShaderIdx[pass];
- }
- int W3dMaterialDescClass::Get_Texture_Index(int mat_index,int pass,int stage)
- {
- assert(mat_index >= 0);
- assert(mat_index < MaterialRemaps.Count());
- assert(pass >= 0);
- assert(pass < PassCount);
- assert(stage >= 0);
- assert(stage < W3dMaterialClass::MAX_STAGES);
- return MaterialRemaps[mat_index].TextureIdx[pass][stage];
- }
- W3dVertexMaterialStruct * W3dMaterialDescClass::Get_Vertex_Material(int mat_index,int pass)
- {
- int index = Get_Vertex_Material_Index(mat_index,pass);
- if (index == -1) {
- return NULL;
- } else {
- return Get_Vertex_Material(index);
- }
- }
- const char * W3dMaterialDescClass::Get_Mapper_Args(int mat_index,int pass,int stage)
- {
- int index = Get_Vertex_Material_Index(mat_index,pass);
- if (index == -1) {
- return NULL;
- } else {
- return Get_Mapper_Args(index,stage);
- }
- }
- W3dShaderStruct * W3dMaterialDescClass::Get_Shader(int mat_index,int pass)
- {
- int index = Get_Shader_Index(mat_index,pass);
- if (index == -1) {
- return NULL;
- } else {
- return Get_Shader(index);
- }
- }
- W3dMapClass * W3dMaterialDescClass::Get_Texture(int mat_index,int pass,int stage)
- {
- int index = Get_Texture_Index(mat_index,pass,stage);
- if (index == -1) {
- return NULL;
- } else {
- return Get_Texture(index);
- }
- }
- int W3dMaterialDescClass::Get_Map_Channel(int mat_index,int pass,int stage)
- {
- return MaterialRemaps[mat_index].MapChannel[pass][stage];
- }
- const char * W3dMaterialDescClass::Get_Vertex_Material_Name(int mat_index,int pass)
- {
- int index = Get_Vertex_Material_Index(mat_index,pass);
- if (index == -1) {
- return NULL;
- } else {
- return VertexMaterials[index].Name;
- }
- }
- const char * W3dMaterialDescClass::Get_Vertex_Material_Name(int vmat_index)
- {
- return VertexMaterials[vmat_index].Name;
- }
- bool W3dMaterialDescClass::Stage_Needs_Texture_Coordinates(int pass,int stage)
- {
- for (int mi=0; mi<MaterialRemaps.Count();mi++) {
- W3dShaderStruct * shader = Get_Shader(mi,pass);
-
- if (shader) {
- if (stage == 0) {
- if (W3d_Shader_Get_Texturing(shader) == W3DSHADER_TEXTURING_ENABLE) return true;
- }
- if (stage == 1) {
- if ((W3d_Shader_Get_Detail_Color_Func(shader) != W3DSHADER_DETAILCOLORFUNC_DISABLE) ||
- (W3d_Shader_Get_Detail_Alpha_Func(shader) != W3DSHADER_DETAILALPHAFUNC_DISABLE)) {
- return true;
- }
- }
- }
- }
- return false;
- }
- bool W3dMaterialDescClass::Pass_Uses_Vertex_Alpha(int pass)
- {
- /*
- ** Only the last alpha pass gets vertex alpha
- */
- int max_alpha_pass = -1;
- for (int pi=0; pi<Pass_Count(); pi++) {
- if (Pass_Uses_Alpha(pi)) {
- max_alpha_pass = pi;
- }
- }
- return (max_alpha_pass == pass);
- }
- bool W3dMaterialDescClass::Pass_Uses_Alpha(int pass)
- {
- for (int mi=0; mi<MaterialRemaps.Count(); mi++) {
- W3dShaderStruct * shader = Get_Shader(mi,pass);
-
- int dst_blend = W3d_Shader_Get_Dest_Blend_Func(shader);
- int src_blend = W3d_Shader_Get_Src_Blend_Func(shader);
- int alpha_test = W3d_Shader_Get_Alpha_Test(shader);
- if ( (dst_blend == W3DSHADER_DESTBLENDFUNC_SRC_ALPHA) ||
- (dst_blend == W3DSHADER_DESTBLENDFUNC_ONE_MINUS_SRC_ALPHA) ||
- (src_blend == W3DSHADER_SRCBLENDFUNC_SRC_ALPHA) ||
- (src_blend == W3DSHADER_SRCBLENDFUNC_ONE_MINUS_SRC_ALPHA) ||
- (alpha_test != 0) )
- {
- return true;
- }
- }
- return false;
- }
- int W3dMaterialDescClass::Add_Vertex_Material(W3dVertexMaterialStruct * vmat,
- const char *mapper_args0,const char *mapper_args1,int pass,const char * name)
- {
- if (vmat == NULL) {
- return -1;
- }
- int crc = Compute_Crc(*vmat, mapper_args0, mapper_args1);
- for (int vi=0; vi<VertexMaterials.Count(); vi++) {
- if ((crc == VertexMaterials[vi].Crc) && (pass == VertexMaterials[vi].PassIndex)) {
- break;
- }
- }
- if (vi == VertexMaterials.Count()) {
- VertMatClass vm;
- vm.Material = *vmat;
- vm.Crc = crc;
- vm.PassIndex = pass;
- vm.Set_Name(name);
- vm.Set_Mapper_Args(mapper_args0, 0);
- vm.Set_Mapper_Args(mapper_args1, 1);
- VertexMaterials.Add(vm);
- }
-
- return vi;
- }
- int W3dMaterialDescClass::Add_Shader(const W3dShaderStruct & shader,int pass)
- {
- int crc = Compute_Crc(shader);
- for (int si=0; si<Shaders.Count(); si++) {
- if (crc == Shaders[si].Crc) break;
- }
-
- if (si == Shaders.Count()) {
- ShadeClass s;
- s.Shader = shader;
- s.Crc = crc;
- Shaders.Add(s);
- }
-
- return si;
- }
- int W3dMaterialDescClass::Add_Texture(W3dMapClass * map,int pass,int stage)
- {
- if ((map == NULL) || (map->Filename == NULL)) {
- return -1;
- }
- int crc = Compute_Crc(*map);
- for (int ti=0; ti<Textures.Count(); ti++) {
- if (crc == Textures[ti].Crc) {
- break;
- }
- }
- if (ti == Textures.Count()) {
- TexClass tex;
- tex.Map = *map;
- tex.Crc = crc;
- Textures.Add(tex);
- }
- return ti;
- }
- unsigned long W3dMaterialDescClass::Compute_Crc(const W3dVertexMaterialStruct & vmat,
- const char *mapper_args0,
- const char *mapper_args1)
- {
- unsigned long crc = 0;
- crc = CRC_Memory((const unsigned char *)&vmat.Attributes,sizeof(vmat.Attributes),crc);
- crc = CRC_Memory((const unsigned char *)&vmat.Ambient,sizeof(vmat.Ambient),crc);
- crc = CRC_Memory((const unsigned char *)&vmat.Diffuse,sizeof(vmat.Diffuse),crc);
- crc = CRC_Memory((const unsigned char *)&vmat.Specular,sizeof(vmat.Specular),crc);
- crc = CRC_Memory((const unsigned char *)&vmat.Emissive,sizeof(vmat.Emissive),crc);
- crc = CRC_Memory((const unsigned char *)&vmat.Shininess,sizeof(vmat.Shininess),crc);
- crc = CRC_Memory((const unsigned char *)&vmat.Opacity,sizeof(vmat.Opacity),crc);
- crc = CRC_Memory((const unsigned char *)&vmat.Translucency,sizeof(vmat.Translucency),crc);
- // Add mapper args string to crc. We are stripping out spaces, tabs, and
- // leading/trailing newlines before computing the CRC so two strings will
- // only differ if they have visible differences.
- crc = Add_String_To_Crc(mapper_args0, crc);
- crc = Add_String_To_Crc(mapper_args1, crc);
- return crc;
- }
- unsigned long W3dMaterialDescClass::Compute_Crc(const W3dShaderStruct & shader)
- {
- unsigned long crc = 0;
- crc = CRC_Memory((const unsigned char *)&shader,sizeof(shader),crc);
- return crc;
- }
- unsigned long W3dMaterialDescClass::Compute_Crc(const W3dMapClass & map)
- {
- unsigned long crc = 0;
- if (map.AnimInfo != NULL) {
- crc = CRC_Memory((const unsigned char *)&map.AnimInfo->Attributes,sizeof(map.AnimInfo->Attributes),crc);
- crc = CRC_Memory((const unsigned char *)&map.AnimInfo->AnimType,sizeof(map.AnimInfo->AnimType),crc);
- crc = CRC_Memory((const unsigned char *)&map.AnimInfo->FrameCount,sizeof(map.AnimInfo->FrameCount),crc);
- crc = CRC_Memory((const unsigned char *)&map.AnimInfo->FrameRate,sizeof(map.AnimInfo->FrameRate),crc);
- }
- crc = CRC_Stringi(map.Filename, crc);
- return crc;
- }
- unsigned long W3dMaterialDescClass::Add_String_To_Crc(const char *str, unsigned long in_crc)
- {
- unsigned long out_crc = in_crc;
- if (str) {
- int len = strlen(str);
- char *temp = new char[len + 1];
- const char *p_in = str;
- // skip leading spaces, tabs, newlines
- for (; *p_in == ' ' || *p_in == '\t' || *p_in == '\r' || *p_in == '\n'; p_in++);
- // copy string, skipping spaces and tabs
- char * p_out = temp;
- int count = 0;
- for (; *p_in; p_in++) {
- for (; *p_in == ' ' || *p_in == '\t'; p_in++);
- if (!(*p_in)) break;
- *p_out = *p_in;
- p_out++;
- count++;
- }
- *p_out = 0;
- // Erase any trailing newlines:
- if (count) {
- // p_out now points to the ending null - make it point to the
- // character before it (the last character of the string proper)
- p_out--;
- for (; *p_out == '\r' || *p_out == '\n'; p_out--) {
- *p_out = '\000';
- count--;
- }
- }
- out_crc = CRC_Memory((const unsigned char *)temp,count,in_crc);
- delete [] temp;
- }
- return out_crc;
- }
|