g_save.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #include "g_local.h"
  16. #define Function(f) {#f, f}
  17. mmove_t mmove_reloc;
  18. field_t fields[] = {
  19. {"classname", FOFS(classname), F_LSTRING},
  20. {"model", FOFS(model), F_LSTRING},
  21. {"spawnflags", FOFS(spawnflags), F_INT},
  22. {"speed", FOFS(speed), F_FLOAT},
  23. {"accel", FOFS(accel), F_FLOAT},
  24. {"decel", FOFS(decel), F_FLOAT},
  25. {"target", FOFS(target), F_LSTRING},
  26. {"targetname", FOFS(targetname), F_LSTRING},
  27. {"pathtarget", FOFS(pathtarget), F_LSTRING},
  28. {"deathtarget", FOFS(deathtarget), F_LSTRING},
  29. {"killtarget", FOFS(killtarget), F_LSTRING},
  30. {"combattarget", FOFS(combattarget), F_LSTRING},
  31. {"message", FOFS(message), F_LSTRING},
  32. {"team", FOFS(team), F_LSTRING},
  33. {"wait", FOFS(wait), F_FLOAT},
  34. {"delay", FOFS(delay), F_FLOAT},
  35. {"random", FOFS(random), F_FLOAT},
  36. {"move_origin", FOFS(move_origin), F_VECTOR},
  37. {"move_angles", FOFS(move_angles), F_VECTOR},
  38. {"style", FOFS(style), F_INT},
  39. {"count", FOFS(count), F_INT},
  40. {"health", FOFS(health), F_INT},
  41. {"sounds", FOFS(sounds), F_INT},
  42. {"light", 0, F_IGNORE},
  43. {"dmg", FOFS(dmg), F_INT},
  44. {"mass", FOFS(mass), F_INT},
  45. {"volume", FOFS(volume), F_FLOAT},
  46. {"attenuation", FOFS(attenuation), F_FLOAT},
  47. {"map", FOFS(map), F_LSTRING},
  48. {"origin", FOFS(s.origin), F_VECTOR},
  49. {"angles", FOFS(s.angles), F_VECTOR},
  50. {"angle", FOFS(s.angles), F_ANGLEHACK},
  51. {"goalentity", FOFS(goalentity), F_EDICT, FFL_NOSPAWN},
  52. {"movetarget", FOFS(movetarget), F_EDICT, FFL_NOSPAWN},
  53. {"enemy", FOFS(enemy), F_EDICT, FFL_NOSPAWN},
  54. {"oldenemy", FOFS(oldenemy), F_EDICT, FFL_NOSPAWN},
  55. {"activator", FOFS(activator), F_EDICT, FFL_NOSPAWN},
  56. {"groundentity", FOFS(groundentity), F_EDICT, FFL_NOSPAWN},
  57. {"teamchain", FOFS(teamchain), F_EDICT, FFL_NOSPAWN},
  58. {"teammaster", FOFS(teammaster), F_EDICT, FFL_NOSPAWN},
  59. {"owner", FOFS(owner), F_EDICT, FFL_NOSPAWN},
  60. {"mynoise", FOFS(mynoise), F_EDICT, FFL_NOSPAWN},
  61. {"mynoise2", FOFS(mynoise2), F_EDICT, FFL_NOSPAWN},
  62. {"target_ent", FOFS(target_ent), F_EDICT, FFL_NOSPAWN},
  63. {"chain", FOFS(chain), F_EDICT, FFL_NOSPAWN},
  64. {"prethink", FOFS(prethink), F_FUNCTION, FFL_NOSPAWN},
  65. {"think", FOFS(think), F_FUNCTION, FFL_NOSPAWN},
  66. {"blocked", FOFS(blocked), F_FUNCTION, FFL_NOSPAWN},
  67. {"touch", FOFS(touch), F_FUNCTION, FFL_NOSPAWN},
  68. {"use", FOFS(use), F_FUNCTION, FFL_NOSPAWN},
  69. {"pain", FOFS(pain), F_FUNCTION, FFL_NOSPAWN},
  70. {"die", FOFS(die), F_FUNCTION, FFL_NOSPAWN},
  71. {"stand", FOFS(monsterinfo.stand), F_FUNCTION, FFL_NOSPAWN},
  72. {"idle", FOFS(monsterinfo.idle), F_FUNCTION, FFL_NOSPAWN},
  73. {"search", FOFS(monsterinfo.search), F_FUNCTION, FFL_NOSPAWN},
  74. {"walk", FOFS(monsterinfo.walk), F_FUNCTION, FFL_NOSPAWN},
  75. {"run", FOFS(monsterinfo.run), F_FUNCTION, FFL_NOSPAWN},
  76. {"dodge", FOFS(monsterinfo.dodge), F_FUNCTION, FFL_NOSPAWN},
  77. {"attack", FOFS(monsterinfo.attack), F_FUNCTION, FFL_NOSPAWN},
  78. {"melee", FOFS(monsterinfo.melee), F_FUNCTION, FFL_NOSPAWN},
  79. {"sight", FOFS(monsterinfo.sight), F_FUNCTION, FFL_NOSPAWN},
  80. {"checkattack", FOFS(monsterinfo.checkattack), F_FUNCTION, FFL_NOSPAWN},
  81. {"currentmove", FOFS(monsterinfo.currentmove), F_MMOVE, FFL_NOSPAWN},
  82. {"endfunc", FOFS(moveinfo.endfunc), F_FUNCTION, FFL_NOSPAWN},
  83. // temp spawn vars -- only valid when the spawn function is called
  84. {"lip", STOFS(lip), F_INT, FFL_SPAWNTEMP},
  85. {"distance", STOFS(distance), F_INT, FFL_SPAWNTEMP},
  86. {"height", STOFS(height), F_INT, FFL_SPAWNTEMP},
  87. {"noise", STOFS(noise), F_LSTRING, FFL_SPAWNTEMP},
  88. {"pausetime", STOFS(pausetime), F_FLOAT, FFL_SPAWNTEMP},
  89. {"item", STOFS(item), F_LSTRING, FFL_SPAWNTEMP},
  90. //need for item field in edict struct, FFL_SPAWNTEMP item will be skipped on saves
  91. {"item", FOFS(item), F_ITEM},
  92. {"gravity", STOFS(gravity), F_LSTRING, FFL_SPAWNTEMP},
  93. {"sky", STOFS(sky), F_LSTRING, FFL_SPAWNTEMP},
  94. {"skyrotate", STOFS(skyrotate), F_FLOAT, FFL_SPAWNTEMP},
  95. {"skyaxis", STOFS(skyaxis), F_VECTOR, FFL_SPAWNTEMP},
  96. {"minyaw", STOFS(minyaw), F_FLOAT, FFL_SPAWNTEMP},
  97. {"maxyaw", STOFS(maxyaw), F_FLOAT, FFL_SPAWNTEMP},
  98. {"minpitch", STOFS(minpitch), F_FLOAT, FFL_SPAWNTEMP},
  99. {"maxpitch", STOFS(maxpitch), F_FLOAT, FFL_SPAWNTEMP},
  100. {"nextmap", STOFS(nextmap), F_LSTRING, FFL_SPAWNTEMP},
  101. {0, 0, 0, 0}
  102. };
  103. field_t levelfields[] =
  104. {
  105. {"changemap", LLOFS(changemap), F_LSTRING},
  106. {"sight_client", LLOFS(sight_client), F_EDICT},
  107. {"sight_entity", LLOFS(sight_entity), F_EDICT},
  108. {"sound_entity", LLOFS(sound_entity), F_EDICT},
  109. {"sound2_entity", LLOFS(sound2_entity), F_EDICT},
  110. {NULL, 0, F_INT}
  111. };
  112. field_t clientfields[] =
  113. {
  114. {"pers.weapon", CLOFS(pers.weapon), F_ITEM},
  115. {"pers.lastweapon", CLOFS(pers.lastweapon), F_ITEM},
  116. {"newweapon", CLOFS(newweapon), F_ITEM},
  117. {NULL, 0, F_INT}
  118. };
  119. /*
  120. ============
  121. InitGame
  122. This will be called when the dll is first loaded, which
  123. only happens when a new game is started or a save game
  124. is loaded.
  125. ============
  126. */
  127. void InitGame (void)
  128. {
  129. gi.dprintf ("==== InitGame ====\n");
  130. gun_x = gi.cvar ("gun_x", "0", 0);
  131. gun_y = gi.cvar ("gun_y", "0", 0);
  132. gun_z = gi.cvar ("gun_z", "0", 0);
  133. //FIXME: sv_ prefix is wrong for these
  134. sv_rollspeed = gi.cvar ("sv_rollspeed", "200", 0);
  135. sv_rollangle = gi.cvar ("sv_rollangle", "2", 0);
  136. sv_maxvelocity = gi.cvar ("sv_maxvelocity", "2000", 0);
  137. sv_gravity = gi.cvar ("sv_gravity", "800", 0);
  138. // noset vars
  139. dedicated = gi.cvar ("dedicated", "0", CVAR_NOSET);
  140. // latched vars
  141. sv_cheats = gi.cvar ("cheats", "0", CVAR_SERVERINFO|CVAR_LATCH);
  142. gi.cvar ("gamename", GAMEVERSION , CVAR_SERVERINFO | CVAR_LATCH);
  143. gi.cvar ("gamedate", __DATE__ , CVAR_SERVERINFO | CVAR_LATCH);
  144. maxclients = gi.cvar ("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH);
  145. maxspectators = gi.cvar ("maxspectators", "4", CVAR_SERVERINFO);
  146. deathmatch = gi.cvar ("deathmatch", "0", CVAR_LATCH);
  147. coop = gi.cvar ("coop", "0", CVAR_LATCH);
  148. skill = gi.cvar ("skill", "1", CVAR_LATCH);
  149. maxentities = gi.cvar ("maxentities", "1024", CVAR_LATCH);
  150. // change anytime vars
  151. dmflags = gi.cvar ("dmflags", "0", CVAR_SERVERINFO);
  152. fraglimit = gi.cvar ("fraglimit", "0", CVAR_SERVERINFO);
  153. timelimit = gi.cvar ("timelimit", "0", CVAR_SERVERINFO);
  154. password = gi.cvar ("password", "", CVAR_USERINFO);
  155. spectator_password = gi.cvar ("spectator_password", "", CVAR_USERINFO);
  156. filterban = gi.cvar ("filterban", "1", 0);
  157. g_select_empty = gi.cvar ("g_select_empty", "0", CVAR_ARCHIVE);
  158. run_pitch = gi.cvar ("run_pitch", "0.002", 0);
  159. run_roll = gi.cvar ("run_roll", "0.005", 0);
  160. bob_up = gi.cvar ("bob_up", "0.005", 0);
  161. bob_pitch = gi.cvar ("bob_pitch", "0.002", 0);
  162. bob_roll = gi.cvar ("bob_roll", "0.002", 0);
  163. // flood control
  164. flood_msgs = gi.cvar ("flood_msgs", "4", 0);
  165. flood_persecond = gi.cvar ("flood_persecond", "4", 0);
  166. flood_waitdelay = gi.cvar ("flood_waitdelay", "10", 0);
  167. // dm map list
  168. sv_maplist = gi.cvar ("sv_maplist", "", 0);
  169. // items
  170. InitItems ();
  171. Com_sprintf (game.helpmessage1, sizeof(game.helpmessage1), "");
  172. Com_sprintf (game.helpmessage2, sizeof(game.helpmessage2), "");
  173. // initialize all entities for this game
  174. game.maxentities = maxentities->value;
  175. g_edicts = gi.TagMalloc (game.maxentities * sizeof(g_edicts[0]), TAG_GAME);
  176. globals.edicts = g_edicts;
  177. globals.max_edicts = game.maxentities;
  178. // initialize all clients for this game
  179. game.maxclients = maxclients->value;
  180. game.clients = gi.TagMalloc (game.maxclients * sizeof(game.clients[0]), TAG_GAME);
  181. globals.num_edicts = game.maxclients+1;
  182. }
  183. //=========================================================
  184. void WriteField1 (FILE *f, field_t *field, byte *base)
  185. {
  186. void *p;
  187. int len;
  188. int index;
  189. if (field->flags & FFL_SPAWNTEMP)
  190. return;
  191. p = (void *)(base + field->ofs);
  192. switch (field->type)
  193. {
  194. case F_INT:
  195. case F_FLOAT:
  196. case F_ANGLEHACK:
  197. case F_VECTOR:
  198. case F_IGNORE:
  199. break;
  200. case F_LSTRING:
  201. case F_GSTRING:
  202. if ( *(char **)p )
  203. len = strlen(*(char **)p) + 1;
  204. else
  205. len = 0;
  206. *(int *)p = len;
  207. break;
  208. case F_EDICT:
  209. if ( *(edict_t **)p == NULL)
  210. index = -1;
  211. else
  212. index = *(edict_t **)p - g_edicts;
  213. *(int *)p = index;
  214. break;
  215. case F_CLIENT:
  216. if ( *(gclient_t **)p == NULL)
  217. index = -1;
  218. else
  219. index = *(gclient_t **)p - game.clients;
  220. *(int *)p = index;
  221. break;
  222. case F_ITEM:
  223. if ( *(edict_t **)p == NULL)
  224. index = -1;
  225. else
  226. index = *(gitem_t **)p - itemlist;
  227. *(int *)p = index;
  228. break;
  229. //relative to code segment
  230. case F_FUNCTION:
  231. if (*(byte **)p == NULL)
  232. index = 0;
  233. else
  234. index = *(byte **)p - ((byte *)InitGame);
  235. *(int *)p = index;
  236. break;
  237. //relative to data segment
  238. case F_MMOVE:
  239. if (*(byte **)p == NULL)
  240. index = 0;
  241. else
  242. index = *(byte **)p - (byte *)&mmove_reloc;
  243. *(int *)p = index;
  244. break;
  245. default:
  246. gi.error ("WriteEdict: unknown field type");
  247. }
  248. }
  249. void WriteField2 (FILE *f, field_t *field, byte *base)
  250. {
  251. int len;
  252. void *p;
  253. if (field->flags & FFL_SPAWNTEMP)
  254. return;
  255. p = (void *)(base + field->ofs);
  256. switch (field->type)
  257. {
  258. case F_LSTRING:
  259. if ( *(char **)p )
  260. {
  261. len = strlen(*(char **)p) + 1;
  262. fwrite (*(char **)p, len, 1, f);
  263. }
  264. break;
  265. }
  266. }
  267. void ReadField (FILE *f, field_t *field, byte *base)
  268. {
  269. void *p;
  270. int len;
  271. int index;
  272. if (field->flags & FFL_SPAWNTEMP)
  273. return;
  274. p = (void *)(base + field->ofs);
  275. switch (field->type)
  276. {
  277. case F_INT:
  278. case F_FLOAT:
  279. case F_ANGLEHACK:
  280. case F_VECTOR:
  281. case F_IGNORE:
  282. break;
  283. case F_LSTRING:
  284. len = *(int *)p;
  285. if (!len)
  286. *(char **)p = NULL;
  287. else
  288. {
  289. *(char **)p = gi.TagMalloc (len, TAG_LEVEL);
  290. fread (*(char **)p, len, 1, f);
  291. }
  292. break;
  293. case F_EDICT:
  294. index = *(int *)p;
  295. if ( index == -1 )
  296. *(edict_t **)p = NULL;
  297. else
  298. *(edict_t **)p = &g_edicts[index];
  299. break;
  300. case F_CLIENT:
  301. index = *(int *)p;
  302. if ( index == -1 )
  303. *(gclient_t **)p = NULL;
  304. else
  305. *(gclient_t **)p = &game.clients[index];
  306. break;
  307. case F_ITEM:
  308. index = *(int *)p;
  309. if ( index == -1 )
  310. *(gitem_t **)p = NULL;
  311. else
  312. *(gitem_t **)p = &itemlist[index];
  313. break;
  314. //relative to code segment
  315. case F_FUNCTION:
  316. index = *(int *)p;
  317. if ( index == 0 )
  318. *(byte **)p = NULL;
  319. else
  320. *(byte **)p = ((byte *)InitGame) + index;
  321. break;
  322. //relative to data segment
  323. case F_MMOVE:
  324. index = *(int *)p;
  325. if (index == 0)
  326. *(byte **)p = NULL;
  327. else
  328. *(byte **)p = (byte *)&mmove_reloc + index;
  329. break;
  330. default:
  331. gi.error ("ReadEdict: unknown field type");
  332. }
  333. }
  334. //=========================================================
  335. /*
  336. ==============
  337. WriteClient
  338. All pointer variables (except function pointers) must be handled specially.
  339. ==============
  340. */
  341. void WriteClient (FILE *f, gclient_t *client)
  342. {
  343. field_t *field;
  344. gclient_t temp;
  345. // all of the ints, floats, and vectors stay as they are
  346. temp = *client;
  347. // change the pointers to lengths or indexes
  348. for (field=clientfields ; field->name ; field++)
  349. {
  350. WriteField1 (f, field, (byte *)&temp);
  351. }
  352. // write the block
  353. fwrite (&temp, sizeof(temp), 1, f);
  354. // now write any allocated data following the edict
  355. for (field=clientfields ; field->name ; field++)
  356. {
  357. WriteField2 (f, field, (byte *)client);
  358. }
  359. }
  360. /*
  361. ==============
  362. ReadClient
  363. All pointer variables (except function pointers) must be handled specially.
  364. ==============
  365. */
  366. void ReadClient (FILE *f, gclient_t *client)
  367. {
  368. field_t *field;
  369. fread (client, sizeof(*client), 1, f);
  370. for (field=clientfields ; field->name ; field++)
  371. {
  372. ReadField (f, field, (byte *)client);
  373. }
  374. }
  375. /*
  376. ============
  377. WriteGame
  378. This will be called whenever the game goes to a new level,
  379. and when the user explicitly saves the game.
  380. Game information include cross level data, like multi level
  381. triggers, help computer info, and all client states.
  382. A single player death will automatically restore from the
  383. last save position.
  384. ============
  385. */
  386. void WriteGame (char *filename, qboolean autosave)
  387. {
  388. FILE *f;
  389. int i;
  390. char str[16];
  391. if (!autosave)
  392. SaveClientData ();
  393. f = fopen (filename, "wb");
  394. if (!f)
  395. gi.error ("Couldn't open %s", filename);
  396. memset (str, 0, sizeof(str));
  397. strcpy (str, __DATE__);
  398. fwrite (str, sizeof(str), 1, f);
  399. game.autosaved = autosave;
  400. fwrite (&game, sizeof(game), 1, f);
  401. game.autosaved = false;
  402. for (i=0 ; i<game.maxclients ; i++)
  403. WriteClient (f, &game.clients[i]);
  404. fclose (f);
  405. }
  406. void ReadGame (char *filename)
  407. {
  408. FILE *f;
  409. int i;
  410. char str[16];
  411. gi.FreeTags (TAG_GAME);
  412. f = fopen (filename, "rb");
  413. if (!f)
  414. gi.error ("Couldn't open %s", filename);
  415. fread (str, sizeof(str), 1, f);
  416. if (strcmp (str, __DATE__))
  417. {
  418. fclose (f);
  419. gi.error ("Savegame from an older version.\n");
  420. }
  421. g_edicts = gi.TagMalloc (game.maxentities * sizeof(g_edicts[0]), TAG_GAME);
  422. globals.edicts = g_edicts;
  423. fread (&game, sizeof(game), 1, f);
  424. game.clients = gi.TagMalloc (game.maxclients * sizeof(game.clients[0]), TAG_GAME);
  425. for (i=0 ; i<game.maxclients ; i++)
  426. ReadClient (f, &game.clients[i]);
  427. fclose (f);
  428. }
  429. //==========================================================
  430. /*
  431. ==============
  432. WriteEdict
  433. All pointer variables (except function pointers) must be handled specially.
  434. ==============
  435. */
  436. void WriteEdict (FILE *f, edict_t *ent)
  437. {
  438. field_t *field;
  439. edict_t temp;
  440. // all of the ints, floats, and vectors stay as they are
  441. temp = *ent;
  442. // change the pointers to lengths or indexes
  443. for (field=fields ; field->name ; field++)
  444. {
  445. WriteField1 (f, field, (byte *)&temp);
  446. }
  447. // write the block
  448. fwrite (&temp, sizeof(temp), 1, f);
  449. // now write any allocated data following the edict
  450. for (field=fields ; field->name ; field++)
  451. {
  452. WriteField2 (f, field, (byte *)ent);
  453. }
  454. }
  455. /*
  456. ==============
  457. WriteLevelLocals
  458. All pointer variables (except function pointers) must be handled specially.
  459. ==============
  460. */
  461. void WriteLevelLocals (FILE *f)
  462. {
  463. field_t *field;
  464. level_locals_t temp;
  465. // all of the ints, floats, and vectors stay as they are
  466. temp = level;
  467. // change the pointers to lengths or indexes
  468. for (field=levelfields ; field->name ; field++)
  469. {
  470. WriteField1 (f, field, (byte *)&temp);
  471. }
  472. // write the block
  473. fwrite (&temp, sizeof(temp), 1, f);
  474. // now write any allocated data following the edict
  475. for (field=levelfields ; field->name ; field++)
  476. {
  477. WriteField2 (f, field, (byte *)&level);
  478. }
  479. }
  480. /*
  481. ==============
  482. ReadEdict
  483. All pointer variables (except function pointers) must be handled specially.
  484. ==============
  485. */
  486. void ReadEdict (FILE *f, edict_t *ent)
  487. {
  488. field_t *field;
  489. fread (ent, sizeof(*ent), 1, f);
  490. for (field=fields ; field->name ; field++)
  491. {
  492. ReadField (f, field, (byte *)ent);
  493. }
  494. }
  495. /*
  496. ==============
  497. ReadLevelLocals
  498. All pointer variables (except function pointers) must be handled specially.
  499. ==============
  500. */
  501. void ReadLevelLocals (FILE *f)
  502. {
  503. field_t *field;
  504. fread (&level, sizeof(level), 1, f);
  505. for (field=levelfields ; field->name ; field++)
  506. {
  507. ReadField (f, field, (byte *)&level);
  508. }
  509. }
  510. /*
  511. =================
  512. WriteLevel
  513. =================
  514. */
  515. void WriteLevel (char *filename)
  516. {
  517. int i;
  518. edict_t *ent;
  519. FILE *f;
  520. void *base;
  521. f = fopen (filename, "wb");
  522. if (!f)
  523. gi.error ("Couldn't open %s", filename);
  524. // write out edict size for checking
  525. i = sizeof(edict_t);
  526. fwrite (&i, sizeof(i), 1, f);
  527. // write out a function pointer for checking
  528. base = (void *)InitGame;
  529. fwrite (&base, sizeof(base), 1, f);
  530. // write out level_locals_t
  531. WriteLevelLocals (f);
  532. // write out all the entities
  533. for (i=0 ; i<globals.num_edicts ; i++)
  534. {
  535. ent = &g_edicts[i];
  536. if (!ent->inuse)
  537. continue;
  538. fwrite (&i, sizeof(i), 1, f);
  539. WriteEdict (f, ent);
  540. }
  541. i = -1;
  542. fwrite (&i, sizeof(i), 1, f);
  543. fclose (f);
  544. }
  545. /*
  546. =================
  547. ReadLevel
  548. SpawnEntities will allready have been called on the
  549. level the same way it was when the level was saved.
  550. That is necessary to get the baselines
  551. set up identically.
  552. The server will have cleared all of the world links before
  553. calling ReadLevel.
  554. No clients are connected yet.
  555. =================
  556. */
  557. void ReadLevel (char *filename)
  558. {
  559. int entnum;
  560. FILE *f;
  561. int i;
  562. void *base;
  563. edict_t *ent;
  564. f = fopen (filename, "rb");
  565. if (!f)
  566. gi.error ("Couldn't open %s", filename);
  567. // free any dynamic memory allocated by loading the level
  568. // base state
  569. gi.FreeTags (TAG_LEVEL);
  570. // wipe all the entities
  571. memset (g_edicts, 0, game.maxentities*sizeof(g_edicts[0]));
  572. globals.num_edicts = maxclients->value+1;
  573. // check edict size
  574. fread (&i, sizeof(i), 1, f);
  575. if (i != sizeof(edict_t))
  576. {
  577. fclose (f);
  578. gi.error ("ReadLevel: mismatched edict size");
  579. }
  580. // check function pointer base address
  581. fread (&base, sizeof(base), 1, f);
  582. #ifdef _WIN32
  583. if (base != (void *)InitGame)
  584. {
  585. fclose (f);
  586. gi.error ("ReadLevel: function pointers have moved");
  587. }
  588. #else
  589. gi.dprintf("Function offsets %d\n", ((byte *)base) - ((byte *)InitGame));
  590. #endif
  591. // load the level locals
  592. ReadLevelLocals (f);
  593. // load all the entities
  594. while (1)
  595. {
  596. if (fread (&entnum, sizeof(entnum), 1, f) != 1)
  597. {
  598. fclose (f);
  599. gi.error ("ReadLevel: failed to read entnum");
  600. }
  601. if (entnum == -1)
  602. break;
  603. if (entnum >= globals.num_edicts)
  604. globals.num_edicts = entnum+1;
  605. ent = &g_edicts[entnum];
  606. ReadEdict (f, ent);
  607. // let the server rebuild world links for this ent
  608. memset (&ent->area, 0, sizeof(ent->area));
  609. gi.linkentity (ent);
  610. }
  611. fclose (f);
  612. // mark all clients as unconnected
  613. for (i=0 ; i<maxclients->value ; i++)
  614. {
  615. ent = &g_edicts[i+1];
  616. ent->client = game.clients + i;
  617. ent->client->pers.connected = false;
  618. }
  619. // do any load time things at this point
  620. for (i=0 ; i<globals.num_edicts ; i++)
  621. {
  622. ent = &g_edicts[i];
  623. if (!ent->inuse)
  624. continue;
  625. // fire any cross-level triggers
  626. if (ent->classname)
  627. if (strcmp(ent->classname, "target_crosslevel_target") == 0)
  628. ent->nextthink = level.time + ent->delay;
  629. }
  630. }