ensiform Posted July 15, 2007 Share Posted July 15, 2007 PhysicsFS or (PhysFS for short) can be found at: http://icculus.org/physfs/ I now use this in the cgame for read/write of most of my text-format files. As well as for the game monkey script reading. I also have it on the server side as well for Shrubbot, my weapon config, the holocron point files, bot waypoint files, banlist, as well as others but just to name a few. If you look on the websvn you will also notice i posted a patch for 0-length file opening. I use this instead of the regular trap calls because theoretically you can get around some things that you are not supposed to be able to. Plus this allows for non-allowed extensions in pure servers (though most people don't use pure in JKA because of skins, models, sabers, etc) Also, it is completely virtual like the quake 3 engine is. How it works basically is you call init to the directory where jamp is. Mount fs_game directory and base. Change the zip extension to pk3 and then you can mount all pk3s and read files from pk3s as well. Note: you are only able to have 1 write directory so you would want to set that to fs_game, also if fs_game is "" you will want to forward it to base and not do both checks. The way I have mine set up is, an extra read cmd that asks for an enum of: MODPATH_BASE or MODPATH_FS_GAME if it gets MODPATH_BASE it looks in base/ if it gets MODPATH_FS_GAME it looks in fs_game/ fs_game being whatever that cvar is. You can also chain it if say you are loading a map to check if it exists, check in base and if that fails, try fs_game, and if that fails then fail completely. I'm actually using C++ to do my internal functions in ©g_physfs.cpp. Basically I have: A cvar retrieve function that returns the buffer of the string in a std::string format. And, I use new and delete for char buffers for the game monkey portion, otherwise i just use my CG_Alloc / G_Alloc and CG_Free / G_Free. Link to comment Share on other sites More sharing options...
ensiform Posted July 15, 2007 Author Share Posted July 15, 2007 A snippet of PhysFS starting up on my server: SV_PhysFS: Initializing... SV_PhysFS: Mounted: /home/jeremy/.jediacademy/ensimod to ensimod SV_PhysFS: Mounted: /home/jeremy/.jediacademy/base to base SV_PhysFS: Mounted: 21 PK3s in base SV_PhysFS: Mounted: 2 PK3s in ensimod SV_PhysFS: Set: WriteDir to: /home/jeremy/.jediacademy/ensimod ... And shutdown: SV_PhysFS: Shutting Down... Link to comment Share on other sites More sharing options...
ensiform Posted July 15, 2007 Author Share Posted July 15, 2007 NOTE: Cannot be used to open any visuals or shaders that would be used by renderer or sounds, etc... If you are just making a test of file exists, that is fine but otherwise, no don't use for that or it cannot really communicate with renderer portion of engine. Link to comment Share on other sites More sharing options...
stubert Posted July 17, 2007 Share Posted July 17, 2007 you could make it :s Link to comment Share on other sites More sharing options...
ensiform Posted July 18, 2007 Author Share Posted July 18, 2007 Not really... the shader/image load file calls are done inside the engine itself. Link to comment Share on other sites More sharing options...
stubert Posted July 18, 2007 Share Posted July 18, 2007 so? :s Link to comment Share on other sites More sharing options...
ensiform Posted July 18, 2007 Author Share Posted July 18, 2007 Not porting to ioq3 kthx. Link to comment Share on other sites More sharing options...
ensiform Posted September 19, 2007 Author Share Posted September 19, 2007 I've successfully added this to the UI module now as well. I fixed PK3 loading in that it sorts them in the correct order so that it loads in the same order as the engine does. New Functions: - PFS_isOpen - PFS_writeSync - PFS_seek - PFS_tell - PFS_eof - PFS_setBuffer - PFS_flush - PFS_fileLength - PFS_GetFileList (Very haxor, but works nicely) - PFS_getLastError GetFileList is far more advanced than the like of the regular trap_FS_GetFileList. In that it does not use a huge buffer to store each file. It uses a struct with an array of 2 buffers per item found, plus if it was in base or in the current mod folder (which is base if you are running from base). So... to properly load all the .bot files in scripts/ in g_bot.c normally looks something like so: static void G_LoadBots( void ) { vmCvar_t botsFile; int numdirs; char filename[128]; char dirlist[1024]; char* dirptr; int i; int dirlen; if ( !trap_Cvar_VariableIntegerValue( "bot_enable" ) ) { return; } g_numBots = 0; trap_Cvar_Register( &botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM ); if( *botsFile.string ) { G_LoadBotsFromFile(botsFile.string); } else { //G_LoadBotsFromFile("scripts/bots.txt"); G_LoadBotsFromFile("botfiles/bots.txt"); } // get all bots from .bot files numdirs = trap_FS_GetFileList("scripts", ".bot", dirlist, 1024 ); dirptr = dirlist; for (i = 0; i < numdirs; i++, dirptr += dirlen+1) { dirlen = strlen(dirptr); Q_strncpyz(filename, "scripts/", sizeof(filename)); Q_strcat(filename, sizeof(filename), dirptr); G_LoadBotsFromFile(filename); } // G_Printf( "%i bots parsed\n", g_numBots ); } However, all that seems rather dirty... static void G_LoadBots( void ) { vmCvar_t botsFile; int i = 0; FindInfo bots; if (!trap_Cvar_VariableIntegerValue("bot_enable")) { return; } bots.i_NumFiles = 0; g_numBots = 0; trap_Cvar_Register(&botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM); if( botsFile.string[0] ) { G_LoadBotsFromFile(botsFile.string); } else { G_LoadBotsFromFile("botfiles/bots.txt"); } PFS_GetFileList("scripts", ".bot", &bots); for(i = 0; i < bots.i_NumFiles && bots.m_Files[i].m_Real; ++i) { G_LoadBotsFromFile(bots.m_Files[i].m_Virtual); } // G_Printf( "%i bots parsed\n", g_numBots ); } m_Real includes the base/ or ensimod/ or whatever fs_game is; m_Virtual does not. There are cases where, even in the older method you needed to strip the extension. Sometimes you need to strip off the rest of the path too, but I've only seen the path one once (in UI loading of demolist & roqlist probably too) FindInfo struct: typedef struct { struct File { char m_Real[256]; char m_Virtual[256]; ModPath i_MountPoint; } m_Files[4096]; int i_NumFiles; char m_Ext[10]; } FindInfo; Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.