From 739bad8e2452f8f96b43604c545c416281ccf6ea Mon Sep 17 00:00:00 2001 From: Garux Date: Tue, 21 Oct 2025 23:49:45 +0500 Subject: [PATCH] * -format map_220: bsp to map of Valve220 format conversion --- ...mplete_list_of_command_line_parameters.htm | 2 +- docs/changelog-custom.txt | 1 + tools/quake3/q3map2/convert_bsp.cpp | 10 +- tools/quake3/q3map2/convert_map.cpp | 215 +++++++++++------- tools/quake3/q3map2/help.cpp | 2 +- tools/quake3/q3map2/q3map2.h | 1 + 6 files changed, 141 insertions(+), 90 deletions(-) diff --git a/docs/Complete_list_of_command_line_parameters.htm b/docs/Complete_list_of_command_line_parameters.htm index 58cc8073..5368ed00 100644 --- a/docs/Complete_list_of_command_line_parameters.htm +++ b/docs/Complete_list_of_command_line_parameters.htm @@ -322,7 +322,7 @@ td.formatted_questions ol { margin-top: 0px; margin-bottom: 0px; }
  • -deluxemapsastexcoord: Save deluxemap names and texcoords instead of textures (only when writing ase and obj)
  • -de F: Distance epsilon for the conversion (only when reading map)
  • -fast: fast bsp to map conversion mode (without texture alignments)
  • -
  • -format converter: Select the converter, default ase (available: map, map_bp, ase, obj, or game names)
  • +
  • -format converter: Select the converter, default ase (available: map, map_bp, map_220, ase, obj, or game names)
  • -lightmapsastexcoord: Save lightmap names and texcoords instead of textures (only when writing ase and obj)
  • -meta: Combine adjacent triangles of the same texture to surfaces (only when reading map)
  • -modelclip: Decompile model autoclip brushes during bsp to map conversion (they are skipped by default)
  • diff --git a/docs/changelog-custom.txt b/docs/changelog-custom.txt index 8a2d9456..c9eeb941 100644 --- a/docs/changelog-custom.txt +++ b/docs/changelog-custom.txt @@ -189,6 +189,7 @@ Q3map2: * -modelclip: Decompile model autoclip brushes during bsp to map conversion (they are skipped by default) * -wtf: During bsp to map conversion use common/WTF on faces with failed texture alignment deduction * fix AP texture alignment deduction during bsp to map decompilation + * -format map_220: bsp to map of Valve220 format conversion diff --git a/tools/quake3/q3map2/convert_bsp.cpp b/tools/quake3/q3map2/convert_bsp.cpp index ecd2bc7c..44e3695e 100644 --- a/tools/quake3/q3map2/convert_bsp.cpp +++ b/tools/quake3/q3map2/convert_bsp.cpp @@ -1038,7 +1038,7 @@ int ConvertBSPMain( Args& args ){ /* arg checking */ if ( args.empty() ) { - Sys_Printf( "Usage: q3map2 -convert [-format ] [-shadersasbitmap|-lightmapsastexcoord|-deluxemapsastexcoord] [-readbsp|-readmap [-meta|-patchmeta]] [-v] \n" ); + Sys_Printf( "Usage: q3map2 -convert [-format ] [-shadersasbitmap|-lightmapsastexcoord|-deluxemapsastexcoord] [-readbsp|-readmap [-meta|-patchmeta]] [-v] \n" ); return 0; } @@ -1056,12 +1056,16 @@ int ConvertBSPMain( Args& args ){ convertFunc = ConvertBSPToOBJ; map_allowed = false; } + else if ( striEqual( fmt, "map" ) ) { + convertFunc = ConvertBSPToMap; + map_allowed = true; + } else if ( striEqual( fmt, "map_bp" ) ) { convertFunc = ConvertBSPToMap_BP; map_allowed = true; } - else if ( striEqual( fmt, "map" ) ) { - convertFunc = ConvertBSPToMap; + else if ( striEqual( fmt, "map_220" ) ) { + convertFunc = ConvertBSPToMap_220; map_allowed = true; } else diff --git a/tools/quake3/q3map2/convert_map.cpp b/tools/quake3/q3map2/convert_map.cpp index c2914c7e..d495aaf3 100644 --- a/tools/quake3/q3map2/convert_map.cpp +++ b/tools/quake3/q3map2/convert_map.cpp @@ -131,9 +131,12 @@ exwinding: } #define FRAC( x ) ( ( x ) - floor( x ) ) -static void ConvertOriginBrush( FILE *f, int num, const Vector3& origin, bool brushPrimitives ){ - int originSize = 256; - +static void ConvertOriginBrush( FILE *f, int num, const Vector3& origin, EBrushType brushType ){ + const int ext = 8; // extent, box size is 2x + const int size = ext * 2; + const int texSize = 64; // can find out from shader + const float texScale = float( size ) / texSize; + // 6: +Z +Y +X -Z -Y -X char pattern[6][7][4] = { { "+++", "+-+", "-++", "- ", " + ", " - ", "- " }, { "+++", "-++", "++-", "- ", " +", "+ ", " +" }, @@ -147,44 +150,54 @@ static void ConvertOriginBrush( FILE *f, int num, const Vector3& origin, bool br /* start brush */ fprintf( f, "\t// brush %d\n", num ); fprintf( f, "\t{\n" ); - if ( brushPrimitives ) { + if ( brushType == EBrushType::Bp ) { fprintf( f, "\tbrushDef\n" ); fprintf( f, "\t{\n" ); } /* print brush side */ - /* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) common/caulk 0 48 0 0.500000 0.500000 0 0 0 */ + /* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) common/caulk 0 48 90 0.5 0.5 0 0 0 */ + /* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) common/caulk [ 1 0 0 0 ] [ 0 -1 0 48 ] 90 0.5 0.5 0 0 0 */ + /* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) ( ( 0 0.03125 0 ) ( -0.03125 0 0.75 ) ) common/caulk 0 0 0 */ for ( int i = 0; i < 6; ++i ) { - if ( brushPrimitives ) { - fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s %d 0 0\n", - origin[0] + 8 * S( i, 0, 0 ), origin[1] + 8 * S( i, 0, 1 ), origin[2] + 8 * S( i, 0, 2 ), - origin[0] + 8 * S( i, 1, 0 ), origin[1] + 8 * S( i, 1, 1 ), origin[2] + 8 * S( i, 1, 2 ), - origin[0] + 8 * S( i, 2, 0 ), origin[1] + 8 * S( i, 2, 1 ), origin[2] + 8 * S( i, 2, 2 ), - 1.0f / 16.0f, 0.0f, FRAC( ( S( i, 5, 0 ) * origin[0] + S( i, 5, 1 ) * origin[1] + S( i, 5, 2 ) * origin[2] ) / 16.0 + 0.5 ), - 0.0f, 1.0f / 16.0f, FRAC( ( S( i, 6, 0 ) * origin[0] + S( i, 6, 1 ) * origin[1] + S( i, 6, 2 ) * origin[2] ) / 16.0 + 0.5 ), + fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ", + origin[0] + ext * S( i, 0, 0 ), origin[1] + ext * S( i, 0, 1 ), origin[2] + ext * S( i, 0, 2 ), + origin[0] + ext * S( i, 1, 0 ), origin[1] + ext * S( i, 1, 1 ), origin[2] + ext * S( i, 1, 2 ), + origin[0] + ext * S( i, 2, 0 ), origin[1] + ext * S( i, 2, 1 ), origin[2] + ext * S( i, 2, 2 ) + ); + if ( brushType == EBrushType::Quake ){ + fprintf( f, "%s %.8f %.8f 0 %.8f %.8f 0 0 0\n", "common/origin", - 0 + FRAC( ( S( i, 3, 0 ) * origin[0] + S( i, 3, 1 ) * origin[1] + S( i, 3, 2 ) * origin[2] ) / size + 0.5 ) * texSize, + FRAC( ( S( i, 4, 0 ) * origin[0] + S( i, 4, 1 ) * origin[1] + S( i, 4, 2 ) * origin[2] ) / size + 0.5 ) * texSize, + texScale, texScale ); } - else - { - fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) %s %.8f %.8f %.8f %.8f %.8f %d 0 0\n", - origin[0] + 8 * S( i, 0, 0 ), origin[1] + 8 * S( i, 0, 1 ), origin[2] + 8 * S( i, 0, 2 ), - origin[0] + 8 * S( i, 1, 0 ), origin[1] + 8 * S( i, 1, 1 ), origin[2] + 8 * S( i, 1, 2 ), - origin[0] + 8 * S( i, 2, 0 ), origin[1] + 8 * S( i, 2, 1 ), origin[2] + 8 * S( i, 2, 2 ), + else if ( brushType == EBrushType::Valve220 ){ + const Vector3 texX( S( i, 3, 0 ), S( i, 3, 1 ), S( i, 3, 2 ) ); + const Vector3 texY( S( i, 4, 0 ), S( i, 4, 1 ), S( i, 4, 2 ) ); + fprintf( f, "%s [ %.8f %.8f %.8f %.8f ] [ %.8f %.8f %.8f %.8f ] 0 %.8f %.8f 0 0 0\n", "common/origin", - FRAC( ( S( i, 3, 0 ) * origin[0] + S( i, 3, 1 ) * origin[1] + S( i, 3, 2 ) * origin[2] ) / 16.0 + 0.5 ) * originSize, - FRAC( ( S( i, 4, 0 ) * origin[0] + S( i, 4, 1 ) * origin[1] + S( i, 4, 2 ) * origin[2] ) / 16.0 + 0.5 ) * originSize, - 0.0f, 16.0 / originSize, 16.0 / originSize, - 0 + texX.x(), texX.y(), texX.z(), + FRAC( ( S( i, 3, 0 ) * origin[0] + S( i, 3, 1 ) * origin[1] + S( i, 3, 2 ) * origin[2] ) / size + 0.5 ) * texSize, + texY.x(), texY.y(), texY.z(), + FRAC( ( S( i, 4, 0 ) * origin[0] + S( i, 4, 1 ) * origin[1] + S( i, 4, 2 ) * origin[2] ) / size + 0.5 ) * texSize, + texScale, texScale + ); + } + else if ( brushType == EBrushType::Bp ) { + fprintf( f, "( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s 0 0 0\n", + 1.0f / size, 0.0f, FRAC( ( S( i, 5, 0 ) * origin[0] + S( i, 5, 1 ) * origin[1] + S( i, 5, 2 ) * origin[2] ) / size + 0.5 ), + 0.0f, 1.0f / size, FRAC( ( S( i, 6, 0 ) * origin[0] + S( i, 6, 1 ) * origin[1] + S( i, 6, 2 ) * origin[2] ) / size + 0.5 ), + "common/origin" ); } } #undef S /* end brush */ - if ( brushPrimitives ) { + if ( brushType == EBrushType::Bp ) { fprintf( f, "\t}\n" ); } fprintf( f, "\t}\n\n" ); @@ -238,7 +251,7 @@ static void bspBrush_to_buildBrush( const bspBrush_t& brush ){ } } -static void ConvertBrushFast( FILE *f, const bspModel_t& model, int bspBrushNum, const Vector3& origin, bool brushPrimitives ){ +static void ConvertBrushFast( FILE *f, const bspModel_t& model, int bspBrushNum, const Vector3& origin, EBrushType brushType ){ bspBrush_to_buildBrush( bspBrushes[bspBrushNum] ); @@ -250,7 +263,7 @@ static void ConvertBrushFast( FILE *f, const bspModel_t& model, int bspBrushNum, /* start brush */ fprintf( f, "\t// brush %d\n", bspBrushNum ); fprintf( f, "\t{\n" ); - if ( brushPrimitives ) { + if ( brushType == EBrushType::Bp ) { fprintf( f, "\tbrushDef\n" ); fprintf( f, "\t{\n" ); } @@ -281,39 +294,44 @@ static void ConvertBrushFast( FILE *f, const bspModel_t& model, int bspBrushNum, } { - if ( brushPrimitives ) { - fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s %d 0 0\n", - pts[ 0 ][ 0 ], pts[ 0 ][ 1 ], pts[ 0 ][ 2 ], - pts[ 1 ][ 0 ], pts[ 1 ][ 1 ], pts[ 1 ][ 2 ], - pts[ 2 ][ 0 ], pts[ 2 ][ 1 ], pts[ 2 ][ 2 ], - 1.0f / 32.0f, 0.0f, 0.0f, - 0.0f, 1.0f / 32.0f, 0.0f, + fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ", + pts[ 0 ][ 0 ], pts[ 0 ][ 1 ], pts[ 0 ][ 2 ], + pts[ 1 ][ 0 ], pts[ 1 ][ 1 ], pts[ 1 ][ 2 ], + pts[ 2 ][ 0 ], pts[ 2 ][ 1 ], pts[ 2 ][ 2 ] + ); + if ( brushType == EBrushType::Quake ) { + fprintf( f, "%s %.8f %.8f %.8f %.8f %.8f 0 0 0\n", texture, - 0 + 0.0f, 0.0f, 0.0f, 0.5f, 0.5f ); } - else - { - fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) %s %.8f %.8f %.8f %.8f %.8f %d 0 0\n", - pts[ 0 ][ 0 ], pts[ 0 ][ 1 ], pts[ 0 ][ 2 ], - pts[ 1 ][ 0 ], pts[ 1 ][ 1 ], pts[ 1 ][ 2 ], - pts[ 2 ][ 0 ], pts[ 2 ][ 1 ], pts[ 2 ][ 2 ], + else if ( brushType == EBrushType::Valve220 ) { + Vector3 texX, texY; + ComputeAxisBase( buildPlane.normal(), texX, texY ); + fprintf( f, "%s [ %.8f %.8f %.8f %.8f ] [ %.8f %.8f %.8f %.8f ] 0 0.5 0.5 0 0 0\n", texture, - 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, - 0 + texX.x(), texX.y(), texX.z(), 0.f, + texY.x(), texY.y(), texY.z(), 0.f + ); + } + else if ( brushType == EBrushType::Bp ) { + fprintf( f, "( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s 0 0 0\n", + 1.0f / 32.0f, 0.0f, 0.0f, + 0.0f, 1.0f / 32.0f, 0.0f, + texture ); } } } /* end brush */ - if ( brushPrimitives ) { + if ( brushType == EBrushType::Bp ) { fprintf( f, "\t}\n" ); } fprintf( f, "\t}\n\n" ); } -static void ConvertBrush( FILE *f, const bspModel_t& model, int bspBrushNum, const Vector3& origin, bool brushPrimitives ){ +static void ConvertBrush( FILE *f, const bspModel_t& model, int bspBrushNum, const Vector3& origin, EBrushType brushType ){ bspBrush_to_buildBrush( bspBrushes[bspBrushNum] ); @@ -326,7 +344,7 @@ static void ConvertBrush( FILE *f, const bspModel_t& model, int bspBrushNum, con /* start brush */ fprintf( f, "\t// brush %d\n", bspBrushNum ); fprintf( f, "\t{\n" ); - if ( brushPrimitives ) { + if ( brushType == EBrushType::Bp ) { fprintf( f, "\tbrushDef\n" ); fprintf( f, "\t{\n" ); } @@ -417,6 +435,12 @@ static void ConvertBrush( FILE *f, const bspModel_t& model, int bspBrushNum, con pts[ 2 ] = pts[ 0 ] + vecs[ 1 ] * 256.0f; //Sys_Printf( "not\n" ); } + /* print planepoints */ + fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ", + pts[ 0 ][ 0 ], pts[ 0 ][ 1 ], pts[ 0 ][ 2 ], + pts[ 1 ][ 0 ], pts[ 1 ][ 1 ], pts[ 1 ][ 2 ], + pts[ 2 ][ 0 ], pts[ 2 ][ 1 ], pts[ 2 ][ 2 ] + ); if ( vert[0] != nullptr && vert[1] != nullptr && vert[2] != nullptr ) { const Vector3 verts[3] = { vert[0]->xyz + origin, @@ -424,7 +448,7 @@ static void ConvertBrush( FILE *f, const bspModel_t& model, int bspBrushNum, con vert[2]->xyz + origin }; const Vector2 sts[3] = { vert[0]->st, vert[1]->st, vert[2]->st }; - if ( brushPrimitives ) { + if ( brushType == EBrushType::Bp || brushType == EBrushType::Valve220 ) { BasicVector2 xyI, xyJ, xyK; BasicVector2 stI, stJ, stK; double D, D0, D1, D2; @@ -483,19 +507,36 @@ static void ConvertBrush( FILE *f, const bspModel_t& model, int bspBrushNum, con } /* print brush side */ - /* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) common/caulk 0 48 0 0.500000 0.500000 0 0 0 */ - fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s %d 0 0\n", - pts[ 0 ][ 0 ], pts[ 0 ][ 1 ], pts[ 0 ][ 2 ], - pts[ 1 ][ 0 ], pts[ 1 ][ 1 ], pts[ 1 ][ 2 ], - pts[ 2 ][ 0 ], pts[ 2 ][ 1 ], pts[ 2 ][ 2 ], - buildSide.texMat[0][0], buildSide.texMat[0][1], FRAC( buildSide.texMat[0][2] ), - buildSide.texMat[1][0], buildSide.texMat[1][1], FRAC( buildSide.texMat[1][2] ), - texture, - contentFlag - ); + if( brushType == EBrushType::Bp ){ + /* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) ( ( 0 0.03125 0 ) ( -0.03125 0 0.75 ) ) common/caulk 0 0 0 */ + fprintf( f, "( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s %d 0 0\n", + buildSide.texMat[0][0], buildSide.texMat[0][1], FRAC( buildSide.texMat[0][2] ), + buildSide.texMat[1][0], buildSide.texMat[1][1], FRAC( buildSide.texMat[1][2] ), + texture, + contentFlag + ); + } + else if( brushType == EBrushType::Valve220 ){ + // brush_primit.cpp Valve220_from_BP() + const double scale[2]{ 1.0 / ( vector2_length( buildSide.texMat[0].vec2() ) * buildSide.shaderInfo->shaderWidth ), + 1.0 / ( vector2_length( buildSide.texMat[1].vec2() ) * buildSide.shaderInfo->shaderHeight ) }; + const double shift[2]{ FRAC( buildSide.texMat[0][2] ) * buildSide.shaderInfo->shaderWidth, + FRAC( buildSide.texMat[1][2] ) * buildSide.shaderInfo->shaderHeight }; + + const DoubleVector3 basis_s = vector3_normalised( texX * buildSide.texMat[0][0] + texY * buildSide.texMat[0][1] ); + const DoubleVector3 basis_t = vector3_normalised( texX * buildSide.texMat[1][0] + texY * buildSide.texMat[1][1] ); + + /* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) common/caulk [ 1 0 0 0 ] [ 0 -1 0 48 ] 90 0.5 0.5 0 0 0 */ + fprintf( f, "%s [ %.8f %.8f %.8f %.8f ] [ %.8f %.8f %.8f %.8f ] 0 %.8f %.8f %d 0 0\n", + texture, + basis_s.x(), basis_s.y(), basis_s.z(), shift[0], + basis_t.x(), basis_t.y(), basis_t.z(), shift[1], + scale[0], scale[1], + contentFlag + ); + } } - else - { + else if ( brushType == EBrushType::Quake ) { // invert QuakeTextureVecs int sv, tv; BasicVector2 stI, stJ, stK; @@ -595,10 +636,7 @@ static void ConvertBrush( FILE *f, const bspModel_t& model, int bspBrushNum, con #endif /* print brush side */ /* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) common/caulk 0 48 0 0.500000 0.500000 0 0 0 */ - fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) %s %.8f %.8f %.8f %.8f %.8f %d 0 0\n", - pts[ 0 ][ 0 ], pts[ 0 ][ 1 ], pts[ 0 ][ 2 ], - pts[ 1 ][ 0 ], pts[ 1 ][ 1 ], pts[ 1 ][ 2 ], - pts[ 2 ][ 0 ], pts[ 2 ][ 1 ], pts[ 2 ][ 2 ], + fprintf( f, "%s %.8f %.8f %.8f %.8f %.8f %d 0 0\n", texture, shift[0], shift[1], rotate, scale[0], scale[1], contentFlag @@ -616,25 +654,28 @@ static void ConvertBrush( FILE *f, const bspModel_t& model, int bspBrushNum, con texture = "common/WTF"; } - if ( brushPrimitives ) { - fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s %d 0 0\n", - pts[ 0 ][ 0 ], pts[ 0 ][ 1 ], pts[ 0 ][ 2 ], - pts[ 1 ][ 0 ], pts[ 1 ][ 1 ], pts[ 1 ][ 2 ], - pts[ 2 ][ 0 ], pts[ 2 ][ 1 ], pts[ 2 ][ 2 ], - 1.0f / 16.0f, 0.0f, 0.0f, - 0.0f, 1.0f / 16.0f, 0.0f, + if ( brushType == EBrushType::Quake ) { + fprintf( f, "%s %.8f %.8f %.8f %.8f %.8f %d 0 0\n", texture, + 0.0f, 0.0f, 0.0f, 0.25f, 0.25f, contentFlag ); } - else - { - fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) %s %.8f %.8f %.8f %.8f %.8f %d 0 0\n", - pts[ 0 ][ 0 ], pts[ 0 ][ 1 ], pts[ 0 ][ 2 ], - pts[ 1 ][ 0 ], pts[ 1 ][ 1 ], pts[ 1 ][ 2 ], - pts[ 2 ][ 0 ], pts[ 2 ][ 1 ], pts[ 2 ][ 2 ], + else if ( brushType == EBrushType::Valve220 ) { + Vector3 texX, texY; + ComputeAxisBase( buildPlane.normal(), texX, texY ); + fprintf( f, "%s [ %.8f %.8f %.8f %.8f ] [ %.8f %.8f %.8f %.8f ] 0 0.5 0.5 %d 0 0\n", + texture, + texX.x(), texX.y(), texX.z(), 0.f, + texY.x(), texY.y(), texY.z(), 0.f, + contentFlag + ); + } + else if ( brushType == EBrushType::Bp ) { + fprintf( f, "( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s %d 0 0\n", + 1.0f / 16.0f, 0.0f, 0.0f, + 0.0f, 1.0f / 16.0f, 0.0f, texture, - 0.0f, 0.0f, 0.0f, 0.25f, 0.25f, contentFlag ); } @@ -642,7 +683,7 @@ static void ConvertBrush( FILE *f, const bspModel_t& model, int bspBrushNum, con } /* end brush */ - if ( brushPrimitives ) { + if ( brushType == EBrushType::Bp ) { fprintf( f, "\t}\n" ); } fprintf( f, "\t}\n\n" ); @@ -787,18 +828,18 @@ static void ConvertPatch( FILE *f, int num, const bspDrawSurface_t& ds, const Ve exports a bsp model to a map file */ -static void ConvertModel( FILE *f, const bspModel_t& model, const Vector3& origin, bool brushPrimitives ){ +static void ConvertModel( FILE *f, const bspModel_t& model, const Vector3& origin, EBrushType brushType ){ if ( origin != g_vector3_identity ) { - ConvertOriginBrush( f, -1, origin, brushPrimitives ); + ConvertOriginBrush( f, -1, origin, brushType ); } /* go through each brush in the model */ for ( int i = 0; i < model.numBSPBrushes; ++i ) { if( fast ) - ConvertBrushFast( f, model, model.firstBSPBrush + i, origin, brushPrimitives ); + ConvertBrushFast( f, model, model.firstBSPBrush + i, origin, brushType ); else - ConvertBrush( f, model, model.firstBSPBrush + i, origin, brushPrimitives ); + ConvertBrush( f, model, model.firstBSPBrush + i, origin, brushType ); } /* go through each drawsurf in the model */ @@ -852,7 +893,7 @@ static void ConvertEPairs( FILE *f, const entity_t& e, bool skip_origin ){ exports an quake map file from the bsp */ -static int ConvertBSPToMap_Ext( char *bspName, bool brushPrimitives ){ +static int ConvertBSPToMap_Ext( char *bspName, EBrushType brushType ){ /* setup brush conversion prerequisites */ { /* convert bsp planes to map planes */ @@ -920,7 +961,7 @@ static int ConvertBSPToMap_Ext( char *bspName, bool brushPrimitives ){ /* only handle bsp models */ if ( modelNum >= 0 ) { /* convert model */ - ConvertModel( f, bspModels[ modelNum ], e.vectorForKey( "origin" ), brushPrimitives ); + ConvertModel( f, bspModels[ modelNum ], e.vectorForKey( "origin" ), brushType ); } /* end entity */ @@ -935,9 +976,13 @@ static int ConvertBSPToMap_Ext( char *bspName, bool brushPrimitives ){ } int ConvertBSPToMap( char *bspName ){ - return ConvertBSPToMap_Ext( bspName, false ); + return ConvertBSPToMap_Ext( bspName, EBrushType::Quake ); } int ConvertBSPToMap_BP( char *bspName ){ - return ConvertBSPToMap_Ext( bspName, true ); + return ConvertBSPToMap_Ext( bspName, EBrushType::Bp ); +} + +int ConvertBSPToMap_220( char *bspName ){ + return ConvertBSPToMap_Ext( bspName, EBrushType::Valve220 ); } diff --git a/tools/quake3/q3map2/help.cpp b/tools/quake3/q3map2/help.cpp index 9d0321b0..7a360cdb 100644 --- a/tools/quake3/q3map2/help.cpp +++ b/tools/quake3/q3map2/help.cpp @@ -314,7 +314,7 @@ static void HelpConvert() { "-deluxemapsastexcoord", "Save deluxemap names and texcoords instead of textures (only when writing ase and obj)" }, { "-de ", "Distance epsilon for the conversion (only when reading map)" }, { "-fast", "fast bsp to map conversion mode (without texture alignments)" }, - { "-format ", "Select the converter, default ase (available: map, map_bp, ase, obj, or game names)" }, + { "-format ", "Select the converter, default ase (available: map, map_bp, map_220, ase, obj, or game names)" }, { "-lightmapsastexcoord", "Save lightmap names and texcoords instead of textures (only when writing ase and obj)" }, { "-meta", "Combine adjacent triangles of the same texture to surfaces (only when reading map)" }, { "-modelclip", "Decompile model autoclip brushes during bsp to map conversion (they are skipped by default)" }, diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 3403fdbb..f3e5bbc1 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -1443,6 +1443,7 @@ int ConvertBSPMain( Args& args ); /* convert_map.c */ int ConvertBSPToMap( char *bspName ); int ConvertBSPToMap_BP( char *bspName ); +int ConvertBSPToMap_220( char *bspName ); /* convert_ase.c */