From: Rudolf Polzer Date: Wed, 26 Sep 2012 07:32:14 +0000 (+0200) Subject: make the cpp hack for ACCUMULATE_FUNCTION optional X-Git-Tag: xonotic-v0.7.0~213 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=1598454bfcd2651b16f34f7fc237e1c51fd377d2;p=xonotic%2Fxonotic-data.pk3dir.git make the cpp hack for ACCUMULATE_FUNCTION optional I had found a way to achieve the same using DP_QC_ENTITYDATA, FRIK_FILE string handling, and DP_QC_ENTITYSTRING. --- diff --git a/qcsrc/client/Main.qc b/qcsrc/client/Main.qc index 076b255a3..c71c787c6 100644 --- a/qcsrc/client/Main.qc +++ b/qcsrc/client/Main.qc @@ -152,8 +152,8 @@ void CSQC_Init(void) GetTeam(COLOR_SPECTATOR, true); // add specs first // needs to be done so early because of the constants they create - RegisterWeapons(); - RegisterGametypes(); + CALL_ACCUMULATED_FUNCTION(RegisterWeapons); + CALL_ACCUMULATED_FUNCTION(RegisterGametypes); WaypointSprite_Load(); diff --git a/qcsrc/common/util-pre.qh b/qcsrc/common/util-pre.qh index b65193d44..da86e9801 100644 --- a/qcsrc/common/util-pre.qh +++ b/qcsrc/common/util-pre.qh @@ -1,6 +1,9 @@ #pragma flag enable subscope #pragma flag enable lo +// FTEQCC can do this +#define HAVE_YO_DAWG_CPP + #ifndef NOCOMPAT //# define WORKAROUND_XON010 //# define COMPAT_XON010_CHANNELS diff --git a/qcsrc/common/util.qh b/qcsrc/common/util.qh index 49e51b0ff..faa605f88 100644 --- a/qcsrc/common/util.qh +++ b/qcsrc/common/util.qh @@ -1,12 +1,13 @@ // a dummy macro that prevents the "hanging ;" warning #define ENDS_WITH_CURLY_BRACE +#ifdef HAVE_YO_DAWG_CPP // TODO make ascii art pic of xzibit // YO DAWG! // I HERD YO LIEK MACROS // SO I PUT A MACRO DEFINITION IN YO MACRO DEFINITION // SO YO CAN EXPAND MACROS WHILE YO EXPAND MACROS -#define ACCUMULATE_FUNCTION(func,otherfunc) \ +# define ACCUMULATE_FUNCTION(func,otherfunc) \ #ifdef func \ void __merge__##otherfunc() { func(); otherfunc(); } \ #undef func \ @@ -14,6 +15,27 @@ #else \ #define func otherfunc \ #endif +# define CALL_ACCUMULATED_FUNCTION(func) \ + func() +#else +# define ACCUMULATE_FUNCTION(func,otherfunc) \ + .void _ACCUMULATE_##func##__##otherfunc; +void ACCUMULATE_call(string func) +{ + float i; + float n = numentityfields(); + string funcprefix = strcat("_ACCUMULATE_", func, "__"); + float funcprefixlen = strlen(funcprefix); + for(i = 0; i < n; ++i) + { + string name = entityfieldname(i); + if(substring(name, 0, funcprefixlen) == funcprefix) + callfunction(substring(name, funcprefixlen, -1)); + } +} +# define CALL_ACCUMULATED_FUNCTION(func) \ + ACCUMULATE_call(#func) +#endif // this returns a tempstring containing a copy of s with additional \n newlines added, it also replaces \n in the text with a real newline // NOTE: s IS allowed to be a tempstring diff --git a/qcsrc/dpdefs/csprogsdefs.qc b/qcsrc/dpdefs/csprogsdefs.qc index 7b0644e3e..c9b9ce9cb 100644 --- a/qcsrc/dpdefs/csprogsdefs.qc +++ b/qcsrc/dpdefs/csprogsdefs.qc @@ -1403,6 +1403,39 @@ void() example_skel_player_delete = // END OF EXAMPLES FOR FTE_CSQC_SKELETONOBJECTS // +//DP_QC_ENTITYDATA +//idea: KrimZon +//darkplaces implementation: KrimZon +//builtin definitions: +float() numentityfields = #496; +string(float fieldnum) entityfieldname = #497; +float(float fieldnum) entityfieldtype = #498; +string(float fieldnum, entity ent) getentityfieldstring = #499; +float(float fieldnum, entity ent, string s) putentityfieldstring = #500; +//constants: +//Returned by entityfieldtype +float FIELD_STRING = 1; +float FIELD_FLOAT = 2; +float FIELD_VECTOR = 3; +float FIELD_ENTITY = 4; +float FIELD_FUNCTION = 6; +//description: +//Versatile functions intended for storing data from specific entities between level changes, but can be customized for some kind of partial savegame. +//WARNING: .entity fields cannot be saved and restored between map loads as they will leave dangling pointers. +//numentityfields returns the number of entity fields. NOT offsets. Vectors comprise 4 fields: v, v_x, v_y and v_z. +//entityfieldname returns the name as a string, eg. "origin" or "classname" or whatever. +//entityfieldtype returns a value that the constants represent, but the field may be of another type in more exotic progs.dat formats or compilers. +//getentityfieldstring returns data as would be written to a savegame, eg... "0.05" (float), "0 0 1" (vector), or "Hello World!" (string). Function names can also be returned. +//putentityfieldstring puts the data returned by getentityfieldstring back into the entity. + +//DP_QC_ENTITYSTRING +void(string s) loadfromdata = #529; +void(string s) loadfromfile = #530; +void(string s) callfunction = #605; +void(float fh, entity e) writetofile = #606; +float(string s) isfunction = #607; +void(entity e, string s) parseentitydata = #608; + // assorted builtins const float STAT_MOVEVARS_TICRATE = 240; const float STAT_MOVEVARS_TIMESCALE = 241; diff --git a/qcsrc/dpdefs/menudefs.qc b/qcsrc/dpdefs/menudefs.qc index ad8666ed3..c11987461 100644 --- a/qcsrc/dpdefs/menudefs.qc +++ b/qcsrc/dpdefs/menudefs.qc @@ -504,6 +504,31 @@ float(string url, float id) uri_get = #513; float(string url, float id, string content_type, string data) uri_post = #513; float(string url, float id, string content_type, string delim, float buf) uri_postbuf = #513; +//DP_QC_ENTITYDATA +//idea: KrimZon +//darkplaces implementation: KrimZon +//builtin definitions: +float() numentityfields = #496; +string(float fieldnum) entityfieldname = #497; +float(float fieldnum) entityfieldtype = #498; +string(float fieldnum, entity ent) getentityfieldstring = #499; +float(float fieldnum, entity ent, string s) putentityfieldstring = #500; +//constants: +//Returned by entityfieldtype +float FIELD_STRING = 1; +float FIELD_FLOAT = 2; +float FIELD_VECTOR = 3; +float FIELD_ENTITY = 4; +float FIELD_FUNCTION = 6; +//description: +//Versatile functions intended for storing data from specific entities between level changes, but can be customized for some kind of partial savegame. +//WARNING: .entity fields cannot be saved and restored between map loads as they will leave dangling pointers. +//numentityfields returns the number of entity fields. NOT offsets. Vectors comprise 4 fields: v, v_x, v_y and v_z. +//entityfieldname returns the name as a string, eg. "origin" or "classname" or whatever. +//entityfieldtype returns a value that the constants represent, but the field may be of another type in more exotic progs.dat formats or compilers. +//getentityfieldstring returns data as would be written to a savegame, eg... "0.05" (float), "0 0 1" (vector), or "Hello World!" (string). Function names can also be returned. +//putentityfieldstring puts the data returned by getentityfieldstring back into the entity. + // assorted undocumented extensions string(string, float) netaddress_resolve = #625; string(string search, string replace, string subject) strreplace = #484; diff --git a/qcsrc/menu/menu.qc b/qcsrc/menu/menu.qc index b4c7ce746..d3bf2ec62 100644 --- a/qcsrc/menu/menu.qc +++ b/qcsrc/menu/menu.qc @@ -73,8 +73,8 @@ void m_init() } // needs to be done so early because of the constants they create - RegisterWeapons(); - RegisterGametypes(); + CALL_ACCUMULATED_FUNCTION(RegisterWeapons); + CALL_ACCUMULATED_FUNCTION(RegisterGametypes); float ddsload = cvar("r_texture_dds_load"); float texcomp = cvar("gl_texturecompression"); diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 120fa6716..4cd5cc810 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -551,8 +551,8 @@ void spawnfunc___init_dedicated_server(void) self.classname = "worldspawn"; // safeguard against various stuff ;) // needs to be done so early because of the constants they create - RegisterWeapons(); - RegisterGametypes(); + CALL_ACCUMULATED_FUNCTION(RegisterWeapons); + CALL_ACCUMULATED_FUNCTION(RegisterGametypes); MapInfo_Enumerate(); MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); @@ -560,7 +560,6 @@ void spawnfunc___init_dedicated_server(void) void Map_MarkAsRecent(string m); float world_already_spawned; -void RegisterWeapons(); void Nagger_Init(); void ClientInit_Spawn(); void WeaponStats_Init(); @@ -598,8 +597,8 @@ void spawnfunc_worldspawn (void) } // needs to be done so early because of the constants they create - RegisterWeapons(); - RegisterGametypes(); + CALL_ACCUMULATED_FUNCTION(RegisterWeapons); + CALL_ACCUMULATED_FUNCTION(RegisterGametypes); ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));