/* Copyright (C) 1999-2007 id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. GtkRadiant 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. GtkRadiant 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 GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // // writes quake3 map format from internal objects // static int g_count_entities; static int g_count_brushes; #include "plugin.h" extern int g_MapVersion; void Float_Write(float data, IDataStream *out) { if (data == (int)data) out->printf("%i ", (int)data); else out->printf("%f ", data); } void Patch_Write(patchMesh_t *pPatch, IDataStream *out) { int i, j; const char *str; // write shader name and matrix dimensions str = pPatch->pShader->getName(); if (strchr(str, ' ')) { Sys_FPrintf(SYS_WRN, "WARNING: Patch_Write: shader names with spaces are not allowed, ignoring '%s'\n", str); str = SHADER_NOT_FOUND; } if(!strncmp(str, "textures/", 9)) str+=9; out->printf("patchDef2\n{\n%s\n( %i %i 0 0 0 )\n", str, pPatch->width, pPatch->height); // write matrix out->printf("(\n"); for(i=0; iwidth; i++) { out->printf("( "); for(j=0; jheight; j++) { out->printf("( "); Float_Write(pPatch->ctrl[i][j].xyz[0], out); Float_Write(pPatch->ctrl[i][j].xyz[1], out); Float_Write(pPatch->ctrl[i][j].xyz[2], out); Float_Write(pPatch->ctrl[i][j].st[0], out); Float_Write(pPatch->ctrl[i][j].st[1], out); out->printf(") "); } out->printf(")\n"); } out->printf(")\n}\n"); } void Face_Write (face_t *face, IDataStream *out, bool bAlternateTexdef = false) { int i, j; const char *str; // write planepts for(i=0; i<3; i++) { out->printf("( "); for(j=0; j<3; j++) { Float_Write(face->planepts[i][j], out); } out->printf(") "); } if(bAlternateTexdef) { // write alternate texdef out->printf("( ( "); for (i=0;i<3;i++) Float_Write(face->brushprimit_texdef.coords[0][i], out); out->printf(") ( "); for (i=0;i<3;i++) Float_Write(face->brushprimit_texdef.coords[1][i], out); out->printf(") ) "); } // write shader name str = face->texdef.GetName(); if (strchr(str, ' ')) { Sys_FPrintf(SYS_WRN, "WARNING: Face_Write: shader names with spaces are not allowed, ignoring '%s'\n", str); str = SHADER_NOT_FOUND; } if(!strncmp(str, "textures/", 9)) str+=9; // Strip all remaining paths. // FIXME: Hydra - this is actually a HalfLife specific bit, not Q2 map format specific. if (g_MapVersion == MAPVERSION_HL) { char *pos; while ( pos = (char*)strchr( str, '/' ) ) { str = pos+1; // to speed optimize, change the "while" to an "if" } } out->printf("%s ", str); if(!bAlternateTexdef) { // write texdef out->printf("%i %i %i %f %f ", (int)face->texdef.shift[0], (int)face->texdef.shift[1], (int)face->texdef.rotate, face->texdef.scale[0], face->texdef.scale[1]); } if (g_MapVersion == MAPVERSION_Q3) { // write surface flags out->printf("%i %i %i\n", face->texdef.contents, face->texdef.flags, face->texdef.value); } if ( (g_MapVersion == MAPVERSION_HL) || (g_MapVersion == MAPVERSION_Q2) ) { // write surface flags if non-zero values. if (face->texdef.contents || face->texdef.flags || face->texdef.value) { out->printf("%i %i %i\n", face->texdef.contents, face->texdef.flags, face->texdef.value); } else { out->printf("\n"); } } } void Primitive_Write (brush_t *pBrush, IDataStream *out) { if ( (g_MapVersion == MAPVERSION_Q2) && (pBrush->patchBrush) ) { Sys_FPrintf(SYS_WRN, "WARNING: Primitive_Write: Patches are not supported in Quake2, ignoring Brush %d\n", g_count_brushes++); } else { out->printf("// brush %i\n", g_count_brushes++); out->printf("{\n"); if(pBrush->patchBrush) Patch_Write(pBrush->pPatch, out); else if(pBrush->bBrushDef) { out->printf("brushDef\n{\n"); for(face_t *face = pBrush->brush_faces; face != NULL; face = face->next) Face_Write (face, out, true); out->printf("}\n"); } else for(face_t *face = pBrush->brush_faces; face != NULL; face = face->next) Face_Write (face, out); out->printf("}\n"); } } void Entity_Write(entity_t *pEntity, IDataStream *out) { epair_t *pEpair; CPtrArray *brushes = (CPtrArray*)pEntity->pData; out->printf("// entity %i\n", g_count_entities++); out->printf("{\n"); for(pEpair = pEntity->epairs; pEpair != NULL; pEpair = pEpair->next) out->printf("\"%s\" \"%s\"\n", pEpair->key, pEpair->value); g_count_brushes = 0; for(int i=0; iGetSize(); i++) Primitive_Write((brush_t*)brushes->GetAt(i), out); out->printf("}\n"); } void Map_Write (CPtrArray *map, IDataStream *out) { g_count_entities = 0; for(int i=0; iGetSize(); i++) Entity_Write((entity_t*)map->GetAt(i), out); } void Map_WriteQ3 (CPtrArray *map, IDataStream *out) { g_MapVersion = MAPVERSION_Q3; Map_Write (map,out); } void Map_WriteHL (CPtrArray *map, IDataStream *out) { g_MapVersion = MAPVERSION_HL; Map_Write (map,out); } void Map_WriteQ2 (CPtrArray *map, IDataStream *out) { g_MapVersion = MAPVERSION_Q2; Map_Write (map,out); }