From: Thomas Debesse Date: Tue, 21 Jun 2022 04:18:35 +0000 (+0200) Subject: Merge commit 'aa4bc3893f6c0c360c91896eba46631e53b2f0d1' into master-merge X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=commitdiff_plain;h=ca0295d3b8e3340c18de1fe13f41265ba32612d4 Merge commit 'aa4bc3893f6c0c360c91896eba46631e53b2f0d1' into master-merge --- ca0295d3b8e3340c18de1fe13f41265ba32612d4 diff --cc tools/quake3/q3map2/help.c index 60631e3d,53cccff9..fe613d04 --- a/tools/quake3/q3map2/help.c +++ b/tools/quake3/q3map2/help.c @@@ -219,7 -195,8 +219,8 @@@ void HelpLight( {"-extravisnudge", "Broken feature to nudge the luxel origin to a better vis cluster"}, {"-extrawide", "Deprecated alias for `-super 2 -filter`"}, {"-extra", "Deprecated alias for `-super 2`"}, - {"-fastallocate", "Use `-fastallocate` to trade lightmap size against allocation time (useful with hi res lightmaps on large maps: reduce allocation time from days to minutes for only some extra bytes)"}, + {"-fastallocate", "Trade lightmap size against packing time (useful with hi res lightmaps on large maps: reduce allocation time from days to minutes for only some extra bytes)"}, + {"-slowallocate", "Use old (a bit more careful, but much slower) lightmaps packing algorithm (default)"}, {"-fastbounce", "Use `-fast` style lighting for radiosity"}, {"-faster", "Use a faster falloff curve for lighting; also implies `-fast`"}, {"-fastgrid", "Use `-fast` style lighting for the light grid"}, @@@ -533,8 -420,7 +534,8 @@@ void HelpMain(const char* arg help_funcs[i](); return; } - } + } + } - HelpOptions("Stages", 0, 80, stages, sizeof(stages)/sizeof(struct HelpOption)); + HelpOptions("Stages", 0, terminalColumns, stages, sizeof(stages)/sizeof(struct HelpOption)); } diff --cc tools/quake3/q3map2/light.c index f14cc43c,7d3be10e..20252c36 --- a/tools/quake3/q3map2/light.c +++ b/tools/quake3/q3map2/light.c @@@ -1771,17 -1774,7 +1771,17 @@@ void TraceGrid( int num ) } /* vortex: apply gridscale and gridambientscale here */ + if (gp->directed[i][0] || gp->directed[i][1] || gp->directed[i][2]) { + /* + * HACK: if there's a non-zero directed component, this + * lightgrid cell is useful. However, ioq3 skips grid + * cells with zero ambient. So let's force ambient to be + * nonzero unless directed is zero too. + */ + ColorToBytesNonZero(color, bgp->ambient[i], gridScale * gridAmbientScale); + } else { - ColorToBytes(color, bgp->ambient[i], gridScale * gridAmbientScale); + ColorToBytes( color, bgp->ambient[ i ], gridScale * gridAmbientScale ); + } ColorToBytes( gp->directed[ i ], bgp->directed[ i ], gridScale ); } @@@ -2035,19 -2031,13 +2035,19 @@@ void LightWorld( const char *BSPFilePat /* radiosity */ b = 1; bt = bounce; + while ( bounce > 0 ) { + qboolean storeForReal = !noBounceStore; + /* store off the bsp between bounces */ - StoreSurfaceLightmaps( fastAllocate ); + StoreSurfaceLightmaps( fastAllocate, storeForReal ); UnparseEntities(); + + if ( storeForReal ) { - Sys_Printf( "Writing %s\n", BSPFilePath ); - WriteBSPFile( BSPFilePath ); + Sys_Printf( "Writing %s\n", BSPFilePath ); + WriteBSPFile( BSPFilePath ); + } /* note it */ Sys_Printf( "\n--- Radiosity (bounce %d of %d) ---\n", b, bt ); @@@ -2153,8 -2119,7 +2153,8 @@@ int LightMain( int argc, char **argv ) const char *value; int lightmapMergeSize = 0; qboolean lightSamplesInsist = qfalse; - qboolean fastAllocate = qfalse; + qboolean fastAllocate = qtrue; + qboolean noBounceStore = qfalse; /* note it */ Sys_Printf( "--- Light ---\n" ); @@@ -2731,22 -2689,16 +2731,27 @@@ Sys_Printf( "Faster mode enabled\n" ); } - else if ( !strcmp( argv[ i ], "-fastallocate" ) ) { + else if ( !strcmp( argv[ i ], "-fastallocate" ) || !strcmp( argv[ i ], "-fastlightmapsearch" ) ) { fastAllocate = qtrue; - Sys_Printf( "Fast allocation mode enabled\n" ); + + if ( !strcmp( argv[ i ], "-fastlightmapsearch" ) ) { + Sys_Printf( "The -fastlightmapsearch argument is deprecated, use \"-fastallocate\" instead\n" ); + } + else { + Sys_Printf( "Fast lightmap allocation mode enabled\n" ); + } + } + + else if ( !strcmp( argv[ i ], "-slowallocate" ) ) { + fastAllocate = qfalse; + Sys_Printf( "Slow lightmap allocation mode enabled (default)\n" ); } + else if ( !strcmp( argv[ i ], "-slowallocate" ) ) { + fastAllocate = qfalse; + Sys_Printf( "Slow allocation mode enabled\n" ); + } + else if ( !strcmp( argv[ i ], "-fastgrid" ) ) { fastgrid = qtrue; Sys_Printf( "Fast grid lighting enabled\n" ); diff --cc tools/quake3/q3map2/lightmaps_ydnar.c index 3c08c8b6,6d61b8d7..2802ecaf --- a/tools/quake3/q3map2/lightmaps_ydnar.c +++ b/tools/quake3/q3map2/lightmaps_ydnar.c @@@ -2478,8 -2496,8 +2486,8 @@@ void FillOutLightmap( outLightmap_t *ol stores the surface lightmaps into the bsp as byte rgb triplets */ -void StoreSurfaceLightmaps( qboolean fastAllocate ){ +void StoreSurfaceLightmaps( qboolean fastAllocate, qboolean storeForReal ){ - int i, j, k, x, y, lx, ly, sx, sy, *cluster, mappedSamples; + int i, j, k, x, y, lx, ly, sx, sy, *cluster, mappedSamples, timer_start; int style, size, lightmapNum, lightmapNum2; float *normal, *luxel, *bspLuxel, *bspLuxel2, *radLuxel, samples, occludedSamples; vec3_t sample, occludedSample, dirSample, colorMins, colorMaxs; @@@ -3072,54 -3107,54 +3096,56 @@@ allocate output lightmaps ----------------------------------------------------------------- */ - /* note it */ - Sys_FPrintf( SYS_VRB, "allocating..." ); + if ( storeForReal ) { + /* note it */ + Sys_FPrintf( SYS_VRB, "allocating..." ); + timer_start = I_FloatTime(); + - /* kill all existing output lightmaps */ - if ( outLightmaps != NULL ) { - for ( i = 0; i < numOutLightmaps; i++ ) - { - free( outLightmaps[ i ].lightBits ); - free( outLightmaps[ i ].bspLightBytes ); + /* kill all existing output lightmaps */ + if ( outLightmaps != NULL ) { + for ( i = 0; i < numOutLightmaps; i++ ) + { + free( outLightmaps[ i ].lightBits ); + free( outLightmaps[ i ].bspLightBytes ); + } + free( outLightmaps ); + outLightmaps = NULL; } - free( outLightmaps ); - outLightmaps = NULL; - } - - numLightmapShaders = 0; - numOutLightmaps = 0; - numBSPLightmaps = 0; - numExtLightmaps = 0; - /* find output lightmap */ - for ( i = 0; i < numRawLightmaps; i++ ) - { - lm = &rawLightmaps[ sortLightmaps[ i ] ]; - FindOutLightmaps( lm, fastAllocate ); - } + numLightmapShaders = 0; + numOutLightmaps = 0; + numBSPLightmaps = 0; + numExtLightmaps = 0; - /* set output numbers in twinned lightmaps */ - for ( i = 0; i < numRawLightmaps; i++ ) - { - /* get lightmap */ - lm = &rawLightmaps[ sortLightmaps[ i ] ]; + /* find output lightmap */ + for ( i = 0; i < numRawLightmaps; i++ ) + { + lm = &rawLightmaps[ sortLightmaps[ i ] ]; + FindOutLightmaps( lm, fastAllocate ); + } - /* walk lightmaps */ - for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) + /* set output numbers in twinned lightmaps */ + for ( i = 0; i < numRawLightmaps; i++ ) { - /* get twin */ - lm2 = lm->twins[ lightmapNum ]; - if ( lm2 == NULL ) { - continue; - } - lightmapNum2 = lm->twinNums[ lightmapNum ]; + /* get lightmap */ + lm = &rawLightmaps[ sortLightmaps[ i ] ]; - /* find output lightmap from twin */ - lm->outLightmapNums[ lightmapNum ] = lm2->outLightmapNums[ lightmapNum2 ]; - lm->lightmapX[ lightmapNum ] = lm2->lightmapX[ lightmapNum2 ]; - lm->lightmapY[ lightmapNum ] = lm2->lightmapY[ lightmapNum2 ]; + /* walk lightmaps */ + for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) + { + /* get twin */ + lm2 = lm->twins[ lightmapNum ]; + if ( lm2 == NULL ) { + continue; + } + lightmapNum2 = lm->twinNums[ lightmapNum ]; + + /* find output lightmap from twin */ + lm->outLightmapNums[ lightmapNum ] = lm2->outLightmapNums[ lightmapNum2 ]; + lm->lightmapX[ lightmapNum ] = lm2->lightmapX[ lightmapNum2 ]; + lm->lightmapY[ lightmapNum ] = lm2->lightmapY[ lightmapNum2 ]; + } } } @@@ -3127,192 -3164,195 +3155,198 @@@ store output lightmaps ----------------------------------------------------------------- */ - /* note it */ - Sys_FPrintf( SYS_VRB, "storing..." ); + if ( storeForReal ) { + /* note it */ + Sys_FPrintf( SYS_VRB, "storing..." ); + timer_start = I_FloatTime(); + - /* count the bsp lightmaps and allocate space */ - if ( bspLightBytes != NULL ) { - free( bspLightBytes ); - } - if ( numBSPLightmaps == 0 || externalLightmaps ) { - numBSPLightBytes = 0; - bspLightBytes = NULL; - } - else - { - numBSPLightBytes = ( numBSPLightmaps * game->lightmapSize * game->lightmapSize * 3 ); - bspLightBytes = safe_malloc( numBSPLightBytes ); - memset( bspLightBytes, 0, numBSPLightBytes ); - } - - /* walk the list of output lightmaps */ - for ( i = 0; i < numOutLightmaps; i++ ) - { - /* get output lightmap */ - olm = &outLightmaps[ i ]; - - /* fill output lightmap */ - if ( lightmapFill ) { - FillOutLightmap( olm ); + /* count the bsp lightmaps and allocate space */ + if ( bspLightBytes != NULL ) { + free( bspLightBytes ); + } + if ( numBSPLightmaps == 0 || externalLightmaps ) { + numBSPLightBytes = 0; + bspLightBytes = NULL; + } + else + { + numBSPLightBytes = ( numBSPLightmaps * game->lightmapSize * game->lightmapSize * 3 ); + bspLightBytes = safe_malloc0( numBSPLightBytes ); } - /* is this a valid bsp lightmap? */ - if ( olm->lightmapNum >= 0 && !externalLightmaps ) { - /* copy lighting data */ - lb = bspLightBytes + ( olm->lightmapNum * game->lightmapSize * game->lightmapSize * 3 ); - memcpy( lb, olm->bspLightBytes, game->lightmapSize * game->lightmapSize * 3 ); + /* walk the list of output lightmaps */ + for ( i = 0; i < numOutLightmaps; i++ ) + { + /* get output lightmap */ + olm = &outLightmaps[ i ]; - /* copy direction data */ - if ( deluxemap ) { - lb = bspLightBytes + ( ( olm->lightmapNum + 1 ) * game->lightmapSize * game->lightmapSize * 3 ); - memcpy( lb, olm->bspDirBytes, game->lightmapSize * game->lightmapSize * 3 ); + /* fill output lightmap */ + if ( lightmapFill ) { + FillOutLightmap( olm ); } - } - /* external lightmap? */ - if ( olm->lightmapNum < 0 || olm->extLightmapNum >= 0 || externalLightmaps ) { - /* make a directory for the lightmaps */ - Q_mkdir( dirname ); + /* is this a valid bsp lightmap? */ + if ( olm->lightmapNum >= 0 && !externalLightmaps ) { + /* copy lighting data */ + lb = bspLightBytes + ( olm->lightmapNum * game->lightmapSize * game->lightmapSize * 3 ); + memcpy( lb, olm->bspLightBytes, game->lightmapSize * game->lightmapSize * 3 ); - /* set external lightmap number */ - olm->extLightmapNum = numExtLightmaps; + /* copy direction data */ + if ( deluxemap ) { + lb = bspLightBytes + ( ( olm->lightmapNum + 1 ) * game->lightmapSize * game->lightmapSize * 3 ); + memcpy( lb, olm->bspDirBytes, game->lightmapSize * game->lightmapSize * 3 ); + } + } + + /* external lightmap? */ + if ( olm->lightmapNum < 0 || olm->extLightmapNum >= 0 || externalLightmaps ) { + /* make a directory for the lightmaps */ + Q_mkdir( dirname ); - /* write lightmap */ - sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps ); - Sys_FPrintf( SYS_VRB, "\nwriting %s", filename ); - WriteTGA24( filename, olm->bspLightBytes, olm->customWidth, olm->customHeight, qtrue ); - numExtLightmaps++; + /* set external lightmap number */ + olm->extLightmapNum = numExtLightmaps; - /* write deluxemap */ - if ( deluxemap ) { + /* write lightmap */ sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps ); Sys_FPrintf( SYS_VRB, "\nwriting %s", filename ); - WriteTGA24( filename, olm->bspDirBytes, olm->customWidth, olm->customHeight, qtrue ); + WriteTGA24( filename, olm->bspLightBytes, olm->customWidth, olm->customHeight, qtrue ); numExtLightmaps++; - if ( debugDeluxemap ) { - olm->extLightmapNum++; + /* write deluxemap */ + if ( deluxemap ) { + sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps ); + Sys_FPrintf( SYS_VRB, "\nwriting %s", filename ); + WriteTGA24( filename, olm->bspDirBytes, olm->customWidth, olm->customHeight, qtrue ); + numExtLightmaps++; + + if ( debugDeluxemap ) { + olm->extLightmapNum++; + } } } } - } - - if ( numExtLightmaps > 0 ) { - Sys_FPrintf( SYS_VRB, "\n" ); - } - /* delete unused external lightmaps */ - for ( i = numExtLightmaps; i; i++ ) - { - /* determine if file exists */ - sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, i ); - if ( !FileExists( filename ) ) { - break; + if ( numExtLightmaps > 0 ) { + Sys_FPrintf( SYS_VRB, "\n" ); } - /* delete it */ - remove( filename ); + /* delete unused external lightmaps */ + for ( i = numExtLightmaps; i; i++ ) + { + /* determine if file exists */ + sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, i ); + if ( !FileExists( filename ) ) { + break; + } + + /* delete it */ + remove( filename ); + } } + Sys_FPrintf( SYS_VRB, "%d.", (int) ( I_FloatTime() - timer_start ) ); + /* ----------------------------------------------------------------- project the lightmaps onto the bsp surfaces ----------------------------------------------------------------- */ - /* note it */ - Sys_FPrintf( SYS_VRB, "projecting..." ); + if ( storeForReal ) { + /* note it */ + Sys_FPrintf( SYS_VRB, "projecting..." ); + timer_start = I_FloatTime(); + - /* walk the list of surfaces */ - for ( i = 0; i < numBSPDrawSurfaces; i++ ) - { - /* get the surface and info */ - ds = &bspDrawSurfaces[ i ]; - info = &surfaceInfos[ i ]; - lm = info->lm; - olm = NULL; - - /* handle surfaces with identical parent */ - if ( info->parentSurfaceNum >= 0 ) { - /* preserve original data and get parent */ - parent = &bspDrawSurfaces[ info->parentSurfaceNum ]; - memcpy( &dsTemp, ds, sizeof( *ds ) ); - - /* overwrite child with parent data */ - memcpy( ds, parent, sizeof( *ds ) ); - - /* restore key parts */ - ds->fogNum = dsTemp.fogNum; - ds->firstVert = dsTemp.firstVert; - ds->firstIndex = dsTemp.firstIndex; - memcpy( ds->lightmapVecs, dsTemp.lightmapVecs, sizeof( dsTemp.lightmapVecs ) ); - - /* set vertex data */ - dv = &bspDrawVerts[ ds->firstVert ]; - dvParent = &bspDrawVerts[ parent->firstVert ]; - for ( j = 0; j < ds->numVerts; j++ ) - { - memcpy( dv[ j ].lightmap, dvParent[ j ].lightmap, sizeof( dv[ j ].lightmap ) ); - memcpy( dv[ j ].color, dvParent[ j ].color, sizeof( dv[ j ].color ) ); - } + /* walk the list of surfaces */ + for ( i = 0; i < numBSPDrawSurfaces; i++ ) + { + /* get the surface and info */ + ds = &bspDrawSurfaces[ i ]; + info = &surfaceInfos[ i ]; + lm = info->lm; + olm = NULL; - /* skip the rest */ - continue; - } + /* handle surfaces with identical parent */ + if ( info->parentSurfaceNum >= 0 ) { + /* preserve original data and get parent */ + parent = &bspDrawSurfaces[ info->parentSurfaceNum ]; + memcpy( &dsTemp, ds, sizeof( *ds ) ); - /* handle vertex lit or approximated surfaces */ - else if ( lm == NULL || lm->outLightmapNums[ 0 ] < 0 ) { - for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) - { - ds->lightmapNum[ lightmapNum ] = -3; - ds->lightmapStyles[ lightmapNum ] = ds->vertexStyles[ lightmapNum ]; - } - } + /* overwrite child with parent data */ + memcpy( ds, parent, sizeof( *ds ) ); - /* handle lightmapped surfaces */ - else - { - /* walk lightmaps */ - for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) - { - /* set style */ - ds->lightmapStyles[ lightmapNum ] = lm->styles[ lightmapNum ]; + /* restore key parts */ + ds->fogNum = dsTemp.fogNum; + ds->firstVert = dsTemp.firstVert; + ds->firstIndex = dsTemp.firstIndex; + memcpy( ds->lightmapVecs, dsTemp.lightmapVecs, sizeof( dsTemp.lightmapVecs ) ); - /* handle unused style */ - if ( lm->styles[ lightmapNum ] == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) { + /* set vertex data */ + dv = &bspDrawVerts[ ds->firstVert ]; + dvParent = &bspDrawVerts[ parent->firstVert ]; + for ( j = 0; j < ds->numVerts; j++ ) + { + memcpy( dv[ j ].lightmap, dvParent[ j ].lightmap, sizeof( dv[ j ].lightmap ) ); + memcpy( dv[ j ].color, dvParent[ j ].color, sizeof( dv[ j ].color ) ); + } + + /* skip the rest */ + continue; + } + + /* handle vertex lit or approximated surfaces */ + else if ( lm == NULL || lm->outLightmapNums[ 0 ] < 0 ) { + for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) + { ds->lightmapNum[ lightmapNum ] = -3; - continue; + ds->lightmapStyles[ lightmapNum ] = ds->vertexStyles[ lightmapNum ]; } + } - /* get output lightmap */ - olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ]; + /* handle lightmapped surfaces */ + else + { + /* walk lightmaps */ + for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) + { + /* set style */ + ds->lightmapStyles[ lightmapNum ] = lm->styles[ lightmapNum ]; - /* set bsp lightmap number */ - ds->lightmapNum[ lightmapNum ] = olm->lightmapNum; + /* handle unused style */ + if ( lm->styles[ lightmapNum ] == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) { + ds->lightmapNum[ lightmapNum ] = -3; + continue; + } - /* deluxemap debugging makes the deluxemap visible */ - if ( deluxemap && debugDeluxemap && lightmapNum == 0 ) { - ds->lightmapNum[ lightmapNum ]++; - } + /* get output lightmap */ + olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ]; - /* calc lightmap origin in texture space */ - lmx = (float) lm->lightmapX[ lightmapNum ] / (float) olm->customWidth; - lmy = (float) lm->lightmapY[ lightmapNum ] / (float) olm->customHeight; + /* set bsp lightmap number */ + ds->lightmapNum[ lightmapNum ] = olm->lightmapNum; - /* calc lightmap st coords */ - dv = &bspDrawVerts[ ds->firstVert ]; - ydv = &yDrawVerts[ ds->firstVert ]; - for ( j = 0; j < ds->numVerts; j++ ) - { - if ( lm->solid[ lightmapNum ] ) { - dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( 0.5f / (float) olm->customWidth ); - dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( 0.5f / (float) olm->customWidth ); + /* deluxemap debugging makes the deluxemap visible */ + if ( deluxemap && debugDeluxemap && lightmapNum == 0 ) { + ds->lightmapNum[ lightmapNum ]++; } - else + + /* calc lightmap origin in texture space */ + lmx = (float) lm->lightmapX[ lightmapNum ] / (float) olm->customWidth; + lmy = (float) lm->lightmapY[ lightmapNum ] / (float) olm->customHeight; + + /* calc lightmap st coords */ + dv = &bspDrawVerts[ ds->firstVert ]; + ydv = &yDrawVerts[ ds->firstVert ]; + for ( j = 0; j < ds->numVerts; j++ ) { - dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( ydv[ j ].lightmap[ 0 ][ 0 ] / ( superSample * olm->customWidth ) ); - dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( ydv[ j ].lightmap[ 0 ][ 1 ] / ( superSample * olm->customHeight ) ); + if ( lm->solid[ lightmapNum ] ) { + dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( 0.5f / (float) olm->customWidth ); + dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( 0.5f / (float) olm->customWidth ); + } + else + { + dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( ydv[ j ].lightmap[ 0 ][ 0 ] / ( superSample * olm->customWidth ) ); + dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( ydv[ j ].lightmap[ 0 ][ 1 ] / ( superSample * olm->customHeight ) ); + } } } } diff --cc tools/quake3/q3map2/q3map2.h index e644cc8b,f6296f1b..720dec29 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@@ -1879,14 -1860,9 +1879,9 @@@ int ImportLight void SetupSurfaceLightmaps( void ); void StitchSurfaceLightmaps( void ); -void StoreSurfaceLightmaps( qboolean fastAllocate ); +void StoreSurfaceLightmaps( qboolean fastAllocate, qboolean storeForReal ); - /* exportents.c */ - void ExportEntities( void ); - int ExportEntitiesMain( int argc, char **argv ); - - /* exportents.c */ void ExportEntities( void ); int ExportEntitiesMain( int argc, char **argv );