/* * PVVMUD a 3D MUD * Copyright (C) 1998-1999 Programvareverkstedet (pvv@pvv.org) * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "pvvmud.H" #include #include #include "msggos.H" #include "texture.H" /////////////////////////////////////////////////////////////////////////////// // MsgGOSError CMsgGOSError::CMsgGOSError():CMessage(MSG_GOSERROR, sizeof(BYTE)){ setName("MsgGOSError"); writeByte(1,0); // Error } CMsgGOSError::CMsgGOSError(BYTE error):CMessage(MSG_GOSERROR, sizeof(BYTE)){ setName("MsgGOSError"); writeByte(1,error); } BYTE CMsgGOSError::getError(){ return readByte(1); } /////////////////////////////////////////////////////////////////////////////// // MsgGOSRequest CMsgGOSRequest::CMsgGOSRequest():CMessage(MSG_GOSREQUEST, sizeof(BYTE) + sizeof(WORD)){ setName("MsgGOSRequest"); } CMsgGOSRequest::CMsgGOSRequest(BYTE requestType,WORD objectId):CMessage(MSG_GOSREQUEST, sizeof(BYTE) + sizeof(WORD)){ setName("MsgGOSRequest"); writeByte(1,requestType); writeWord(2,objectId); } BYTE CMsgGOSRequest::getRequestType(){ return readByte(1); } WORD CMsgGOSRequest::getObjectId(){ return readWord(2); } /////////////////////////////////////////////////////////////////////////////// // MsgGeometry CMsgGeometry::CMsgGeometry():CMsgVarLength(MSG_GEOMETRY){ setName("MsgGeometry"); } #define HEADSIZE (sizeof(DWORD)+sizeof(WORD)*4) #define VERTEXSIZE (3*sizeof(DWORD)) #define NORMALSIZE (3*sizeof(DWORD)) #define TEXCOORDSIZE (2*sizeof(DWORD)) #define POLYGONHEADSIZE (sizeof(DWORD)+4*sizeof(WORD)) CMsgGeometry::CMsgGeometry(CGeometry & geometry):CMsgVarLength(MSG_GEOMETRY){ setName("MsgGeometry"); WORD numV,numN,numTC,numP; int type,materialId,numVI,numNI,numTCI; DWORD size = sizeof(DWORD)+sizeof(WORD); // GeometryId + NumSubObjects WORD numSubObjects = 0; // Calculate size CGeometry * geo = &geometry; while (geo != NULL){ numSubObjects++; size += HEADSIZE; numV = geo->getNumVertices(); numN = geo->getNumNormals(); numTC = geo->getNumTexCoords(); numP = geo->getNumPolygons(); size += numV*VERTEXSIZE+numN*NORMALSIZE+numTC*TEXCOORDSIZE; while (numP-- > 0){ size += POLYGONHEADSIZE; CPolygon * poly = geo->getPolygon(numP); poly->get(&type,&materialId,&numVI,&numNI,&numTCI); size += (numVI + numNI + numTCI)*sizeof(WORD); } geo = geo->getNext(); } // Then the size is known setBodyLength(size); cdebug << "Geometry: size " << size << "\n"; // Write geometry writeDWord(getLength(),geometry.getId()); writeWord(MSGCURRPOS,numSubObjects); geo = &geometry; while (geo != NULL){ numV = geo->getNumVertices(); numN = geo->getNumNormals(); numTC = geo->getNumTexCoords(); numP = geo->getNumPolygons(); // Write geometry head writeWord(MSGCURRPOS,numV); writeWord(MSGCURRPOS,numN); writeWord(MSGCURRPOS,numTC); writeWord(MSGCURRPOS,numP); writeDWord(MSGCURRPOS,geo->getSubId()); // Write geometry body // Vertices while (numV-- > 0){ CVertex * vertex = geo->getVertex(numV); writeDouble(MSGCURRPOS,vertex->getZ()); writeDouble(MSGCURRPOS,vertex->getY()); writeDouble(MSGCURRPOS,vertex->getX()); } // Normals while (numN-- > 0){ CNormal * normal = geo->getNormal(numN); writeDouble(MSGCURRPOS,normal->getZ()); writeDouble(MSGCURRPOS,normal->getY()); writeDouble(MSGCURRPOS,normal->getX()); } // TexCoords while (numTC-- > 0){ CTexCoord * texCoord = geo->getTexCoord(numTC); writeDouble(MSGCURRPOS,texCoord->getV()); writeDouble(MSGCURRPOS,texCoord->getU()); } // Polygons while (numP-- > 0){ CPolygon * poly = geo->getPolygon(numP); // Write polygon head poly->get(&type,&materialId,&numVI,&numNI,&numTCI); writeDWord(MSGCURRPOS,materialId); writeWord(MSGCURRPOS,type); writeWord(MSGCURRPOS,numVI); writeWord(MSGCURRPOS,numNI); writeWord(MSGCURRPOS,numTCI); // Write polygon body // Vertex index list while (numVI-- > 0){ writeWord(MSGCURRPOS,poly->getVertexIndex(numVI)); } // Normal index list while (numNI-- > 0){ writeWord(MSGCURRPOS,poly->getNormalIndex(numNI)); } // TexCoord index list while (numTCI-- > 0){ writeWord(MSGCURRPOS,poly->getTexCoordIndex(numTCI)); } } geo = geo->getNext(); } } DWORD CMsgGeometry::getGeometryId(){ return readDWord(getLength()); } CGeometry* CMsgGeometry::getGeometry(){ // cdebug << "CMsgGeometry::getGeometry: Not impl.!\n"; CGeometry *geo = NULL; // Set the current read pointer in correct position DWORD geometryId = getGeometryId(); // Get number of subobjects and read them WORD numSubObjects = readWord(MSGCURRPOS); while (numSubObjects-- > 0){ // Read geometry head and create geometry WORD numV = readWord(MSGCURRPOS); WORD numN = readWord(MSGCURRPOS); WORD numTC = readWord(MSGCURRPOS); WORD numP = readWord(MSGCURRPOS); CGeometry * newgeo = newGeometry(geometryId,numV,numN,numTC,numP); newgeo->setNext(geo); geo = newgeo; geo->setSubId(readDWord(MSGCURRPOS)); // Read geometry body // Vertices while (numV-- > 0){ geo->setVertex(numV,readDouble(MSGCURRPOS),readDouble(MSGCURRPOS),readDouble(MSGCURRPOS)); } // Normals while (numN-- > 0){ geo->setNormal(numN,readDouble(MSGCURRPOS),readDouble(MSGCURRPOS),readDouble(MSGCURRPOS)); } // TexCoords while (numTC-- > 0){ geo->setTexCoord(numTC,readDouble(MSGCURRPOS),readDouble(MSGCURRPOS)); } // Polygons while (numP-- > 0){ int type,materialId,numVI,numNI,numTCI; // Read polygon head materialId = readDWord(MSGCURRPOS); type = readWord(MSGCURRPOS); numVI = readWord(MSGCURRPOS); numNI = readWord(MSGCURRPOS); numTCI = readWord(MSGCURRPOS); CPolygon * poly = new CPolygon(type,materialId,numVI,numNI,numTCI); // Read polygon body // Read vertex index list while (numVI-- > 0){ poly->setVertexIndex(numVI,readWord(MSGCURRPOS)); } // Read normal index list while (numNI-- > 0){ poly->setNormalIndex(numNI,readWord(MSGCURRPOS)); } // Read texCoord index list while (numTCI-- > 0){ poly->setTexCoordIndex(numTCI,readWord(MSGCURRPOS)); } geo->setPolygon(numP,poly); } } return geo; } CGeometry * CMsgGeometry::newGeometry(int geometryId, int numVertices, int numNormals, int numTexCoords, int numPolygons){ return new CGeometry(geometryId,numVertices,numNormals, numTexCoords,numPolygons); } /////////////////////////////////////////////////////////////////////////////// // MsgMaterial CMsgMaterial::CMsgMaterial():CMessage(MSG_MATERIAL,sizeof(WORD)*2+4*4+1){ setName("MsgMaterial"); } CMsgMaterial::CMsgMaterial(CMaterial & material):CMessage(MSG_MATERIAL,sizeof(WORD)*2+4*4+1){ cdebug << "CMegsMaterial\n"; setName("MsgMaterial"); writeWord(1,material.getId()); writeWord(3,material.getTextureId()); for (int ii = 0; ii < 4 ; ii++){ writeByte(5+ii,material.getAmbientByte(ii)); writeByte(9+ii,material.getDiffuseByte(ii)); writeByte(13+ii,material.getSpecularByte(ii)); writeByte(17+ii,material.getEmissionByte(ii)); } writeByte(21,material.getShininessByte()); } int CMsgMaterial::getMaterialId(){ return (short int)readWord(1); } int CMsgMaterial::getTextureId(){ return (short int)readWord(3); } BYTE CMsgMaterial::getAmbientByte(int num){ return readByte(5+num); } BYTE CMsgMaterial::getDiffuseByte(int num){ return readByte(9+num); } BYTE CMsgMaterial::getSpecularByte(int num){ return readByte(13+num); } BYTE CMsgMaterial::getEmissionByte(int num){ return readByte(17+num); } BYTE CMsgMaterial::getShininessByte(){ return readByte(21); } CMaterial* CMsgMaterial::getMaterial(){ CMaterial * material = newMaterial(getMaterialId()); material->setTextureId(getTextureId()); for (int ii = 0; ii < 4; ii++){ material->setAmbient(ii,getAmbientByte(ii)); material->setDiffuse(ii,getDiffuseByte(ii)); material->setSpecular(ii,getSpecularByte(ii)); material->setEmission(ii,getEmissionByte(ii)); } material->setShininess(getShininessByte()); return material; } CMaterial * CMsgMaterial::newMaterial(int materialId){ return new CMaterial(materialId); } /////////////////////////////////////////////////////////////////////////////// // MsgTexture CMsgTexture::CMsgTexture():CMsgVarLength(MSG_TEXTURE){ setName("MsgTexture"); } CMsgTexture::CMsgTexture(CTexture & texture):CMsgVarLength(MSG_TEXTURE){ setName("MsgTexture"); CTextureMap * map = texture.getTextureMap(); setBodyLength(sizeof(WORD)*3 + map->getWidth()*map->getHeight()*sizeof(DWORD)); writeWord(getLength(),texture.getId()); writeWord(getLength()+2,map->getWidth()); writeWord(getLength()+4,map->getHeight()); writeBuf(getLength()+6,map->getData(),map->getWidth()*map->getHeight()*sizeof(DWORD)); } WORD CMsgTexture::getTextureId(){ return readWord(getLength()); } WORD CMsgTexture::getMapWidth(){ return readWord(getLength()+2); } WORD CMsgTexture::getMapHeight(){ return readWord(getLength()+4); } CTexture * CMsgTexture::getTexture(){ CTexture * texture = newTexture(getTextureId()); WORD width = getMapWidth(); WORD height = getMapHeight(); BYTE * data = (BYTE*)malloc(width*height*sizeof(DWORD)); readBuf(getLength()+6,data,width*height*sizeof(DWORD)); CTextureMap * map = new CTextureMap(width,height,data); texture->setTextureMap(map); return texture; } CTexture * CMsgTexture::newTexture(int textureId){ return new CTexture(textureId); }