if( (arg = csr_opt_arg( 'o' )) )
{
strcpy( api.output_path, arg );
- csr_path_winunix( api.output_path );
-
output_set = 1;
}
csr_stripext( api.output_path );
}
- char *base_name;
- if( !(base_name = csr_findext( api.output_path, '/' ) ))
- {
- base_name = api.output_path;
- }
-
- strcpy( api.vmf_name, base_name );
+ strcpy( api.vmf_name, csr_filename( api.output_path ) );
+ strcpy( api.vmf_folder, api.output_path );
+ csr_downlvl( api.vmf_folder );
log_info( "output_path: '%s'\n", api.output_path );
log_info( "vmf_name: '%s'\n", api.vmf_name );
-
+ log_info( "vmf_folder: '%s'\n", api.vmf_folder );
+
api.map = vmf_init( api.strings[0].str );
if( api.map )
{
float padding;
u32 resolution;
int write_txt;
- char output_path[ 512 ]; // Full path eg. /home/harry/my_map.vmf
- char vmf_name[ 128 ]; // Just the base name eg. my_map
+ char output_path[ 512 ]; // Full path to output eg. /home/harry/output
+ char vmf_name[ 128 ]; // Just the base name eg. my_map
+ char vmf_folder[ 512 ]; // Just the folder to the map eg. /home/harry/
EMSAA sampling_mode;
float min_z;
// Path handling
// -------------
-// Find file path extension, returns NULL if no ext (0x00)
+// Find file path extension, returns NULL if no ext (0x00) example: /test/file.jpg returns pointer to: jpg
char *csr_findext( char *path, char const delim );
+char *csr_findsep( char *path ); // Same as above but operates on \ and /
// gets rid of extension on string only left with (folder)+filename
void csr_stripext( char *path );
int csr_path_is_abs( char const *path );
-// Convert windows paths to unix.. sortof ( \something\\blahblah .. ) -> /something/blahblah/
-// Does not handle drive letters, idea is to increase windows compatibility will the other functions above
-void csr_path_winunix( char *path );
+// Remove one level (nop if can't) eg: /home/harry/test.file -> /home/harry/
+void csr_downlvl( char *path );
+
+// Get only the file name example: /test/file.jpg returns file.jpg
+char *csr_filename( char *path );
// Implementation
//=======================================================================================================================
+#ifdef _WIN32
+ #define CSR_FOLDER_CHAR '\\'
+#else
+ #define CSR_FOLDER_CHAR '/'
+#endif
+
#ifdef CSR_EXECUTABLE
i64 fs_file_size( FILE *fileptr )
return ptr;
}
+// Find 'seperator'.. because folders can be / or \ on windows..
+char *csr_findsep( char *path )
+{
+ char *c, *ptr;
+
+ c = path;
+ ptr = NULL;
+
+ while( *c )
+ {
+ if( *c == '/' || *c == '\\' )
+ {
+ ptr = c + 1;
+ }
+
+ c ++;
+ }
+
+ return ptr;
+}
+
void csr_stripext( char *path )
{
char *point, *start;
// Skip folders
- if( !(start = csr_findext( path, '/' )) )
+ if( !(start = csr_findsep( path )) )
{
start = path;
}
}
}
-void csr_path_winunix( char *path )
+void csr_downlvl( char *path )
{
- char *idx, *wr;
- wr = idx = path;
+ char *start_name, *c;
+
+ c = path;
+ while( *c )
+ c ++;
+ int len = c - path;
- while( *idx )
- {
- if( *idx == '\\' )
- {
- *idx = '/';
- }
-
- if( idx > path )
- {
- if( *(idx -1) == '/' && *idx == '/') idx ++;
- }
-
- *( wr ++ ) = *idx;
-
- idx ++;
- }
+ if( len )
+ path[ len -1 ] = 0x00;
- *wr = 0x00;
+ if( (start_name = csr_findsep( path ) ))
+ *start_name = 0x00;
+ else
+ path[0] = 0x00;
+}
+
+char *csr_filename( char *path )
+{
+ char *base_name;
+ if( (base_name = csr_findsep( path ) ))
+ return base_name;
+
+ return path;
}
int csr_path_is_abs( char const *path )
// Set gamedir
strcpy( fs->gamedir, path );
- csr_path_winunix( fs->gamedir );
- *csr_findext( fs->gamedir, '/' ) = 0x00;
+ csr_downlvl( fs->gamedir );
// Set exe dir
strcpy( fs->exedir, fs->gamedir );
- strcat( fs->exedir, "../" );
+ csr_downlvl( fs->exedir );
// Get all search paths from file
vdf_node *search_paths = vdf_next(vdf_next(vdf_next( info, "GameInfo", NULL ), "FileSystem", NULL ), "SearchPaths", NULL );
if( !fs->vpk )
{
- log_error( "Could not locate pak01_dir.vpk in %i searchpaths. Stock models will not load!", csr_sb_count( fs->searchpaths ) );
+ log_error( "Could not locate pak01_dir.vpk in %i searchpaths. Stock models will not load!\n", csr_sb_count( fs->searchpaths ) );
}
log_info( "fs_info:\n" );
void vmf_load_all_instances( vmf_map *map, vdf_node *vmf )
{
+ char nextvmf[ 512 ];
+ const char *base = kv_get( vmf, "csr_path", "" );
+
vdf_foreach( vmf, "entity", ent )
{
if( !strcmp( kv_get( ent, "classname", "" ), "func_instance" ))
{
// Entity is in use if file is specified, if not just ignore the entity.
- const char *path = kv_get( ent, "file", "" );
- if( strcmp( path, "" ) )
+ const char *path = kv_get( ent, "file", NULL );
+
+ if( path )
{
- if( (ent->user1 = vmf_init_subvmf( map, path )))
+ // Make relative path real
+ strcpy( nextvmf, base );
+ csr_downlvl( nextvmf );
+ strcat( nextvmf, path );
+
+ if( (ent->user1 = vmf_init_subvmf( map, nextvmf )))
{
ent->user1 --;
ent->user = VMF_FLAG_IS_INSTANCE;
strcpy( inst->name, subvmf );
if( (inst->root = vdf_open_file( subvmf )) )
- {
+ {
+ vdf_kv_append( inst->root, "csr_path", subvmf );
+
// Recursive load other instances
vmf_load_all_instances( map, inst->root );
return id+1;
return NULL;
}
+ vdf_kv_append( map->root, "csr_path", path );
+
// Prepare instances
vmf_load_all_instances( map, map->root );