diff options
Diffstat (limited to 'src/jake2/game/GameSave.java')
-rw-r--r-- | src/jake2/game/GameSave.java | 721 |
1 files changed, 164 insertions, 557 deletions
diff --git a/src/jake2/game/GameSave.java b/src/jake2/game/GameSave.java index d399b8c..ba36e06 100644 --- a/src/jake2/game/GameSave.java +++ b/src/jake2/game/GameSave.java @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // Created on 29.12.2003 by RST. -// $Id: GameSave.java,v 1.1 2004-07-07 19:59:01 hzi Exp $ +// $Id: GameSave.java,v 1.2 2004-08-20 21:29:57 salomo Exp $ package jake2.game; @@ -57,6 +57,7 @@ public class GameSave extends GameFunc { g_edicts = new edict_t[game.maxentities]; for (int i = 0; i < game.maxentities; i++) g_edicts[i] = new edict_t(i); + SV_GAME.ge.edicts = g_edicts; } public static void CreateClients() { @@ -131,16 +132,11 @@ public class GameSave extends GameFunc { // items InitItems(); - //Com_sprintf (game.helpmessage1, sizeof(game.helpmessage1), ""); game.helpmessage1 = ""; - - //Com_sprintf (game.helpmessage2, sizeof(game.helpmessage2), ""); game.helpmessage2 = ""; // initialize all entities for this game game.maxentities = (int) maxentities.value; - - //g_edicts = gi.TagMalloc(game.maxentities * sizeof(g_edicts[0]), TAG_GAME); CreateEdicts(); globals.edicts = g_edicts; @@ -149,585 +145,196 @@ public class GameSave extends GameFunc { // initialize all clients for this game game.maxclients = (int) maxclients.value; - //game.clients = gi.TagMalloc(game.maxclients * sizeof(game.clients[0]), TAG_GAME); CreateClients(); - + globals.num_edicts = game.maxclients + 1; } - ////========================================================= - // - //public static void WriteField1 (FILE *f, field_t field, byte base) - //{ - // void *p; - // int len; - // int index; - // - // if (field.flags & FFL_SPAWNTEMP) - // return; - // - // p = (void *)(base + field.ofs); - // switch (field.type) - // { - // case F_INT: - // case F_FLOAT: - // case F_ANGLEHACK: - // case F_VECTOR: - // case F_IGNORE: - // break; - // - // case F_LSTRING: - // case F_GSTRING: - // if ( *(char **)p ) - // len = strlen(*(char **)p) + 1; - // else - // len = 0; - // *(int *)p = len; - // break; - // case F_EDICT: - // if ( *(edict_t **)p == NULL) - // index = -1; - // else - // index = *(edict_t **)p - g_edicts; - // *(int *)p = index; - // break; - // case F_CLIENT: - // if ( *(gclient_t **)p == NULL) - // index = -1; - // else - // index = *(gclient_t **)p - game.clients; - // *(int *)p = index; - // break; - // case F_ITEM: - // if ( *(edict_t **)p == NULL) - // index = -1; - // else - // index = *(gitem_t **)p - itemlist; - // *(int *)p = index; - // break; - // - // //relative to code segment - // case F_FUNCTION: - // if (*(byte **)p == NULL) - // index = 0; - // else - // index = *(byte **)p - ((byte *)InitGame); - // *(int *)p = index; - // break; - // - // //relative to data segment - // case F_MMOVE: - // if (*(byte **)p == NULL) - // index = 0; - // else - // index = *(byte **)p - (byte *)&mmove_reloc; - // *(int *)p = index; - // break; - // - // default: - // gi.error ("WriteEdict: unknown field type"); - // } - //} - // - // - //void WriteField2 (FILE *f, field_t *field, byte *base) - //{ - // int len; - // void *p; - // - // if (field.flags & FFL_SPAWNTEMP) - // return; - // - // p = (void *)(base + field.ofs); - // switch (field.type) - // { - // case F_LSTRING: - // if ( *(char **)p ) - // { - // len = strlen(*(char **)p) + 1; - // fwrite (*(char **)p, len, 1, f); - // } - // break; - // } - //} - // - //void ReadField (FILE *f, field_t *field, byte *base) - //{ - // void *p; - // int len; - // int index; - // - // if (field.flags & FFL_SPAWNTEMP) - // return; - // - // p = (void *)(base + field.ofs); - // switch (field.type) - // { - // case F_INT: - // case F_FLOAT: - // case F_ANGLEHACK: - // case F_VECTOR: - // case F_IGNORE: - // break; - // - // case F_LSTRING: - // len = *(int *)p; - // if (!len) - // *(char **)p = NULL; - // else - // { - // *(char **)p = gi.TagMalloc (len, TAG_LEVEL); - // fread (*(char **)p, len, 1, f); - // } - // break; - // case F_EDICT: - // index = *(int *)p; - // if ( index == -1 ) - // *(edict_t **)p = NULL; - // else - // *(edict_t **)p = &g_edicts[index]; - // break; - // case F_CLIENT: - // index = *(int *)p; - // if ( index == -1 ) - // *(gclient_t **)p = NULL; - // else - // *(gclient_t **)p = &game.clients[index]; - // break; - // case F_ITEM: - // index = *(int *)p; - // if ( index == -1 ) - // *(gitem_t **)p = NULL; - // else - // *(gitem_t **)p = &itemlist[index]; - // break; - // - // //relative to code segment - // case F_FUNCTION: - // index = *(int *)p; - // if ( index == 0 ) - // *(byte **)p = NULL; - // else - // *(byte **)p = ((byte *)InitGame) + index; - // break; - // - // //relative to data segment - // case F_MMOVE: - // index = *(int *)p; - // if (index == 0) - // *(byte **)p = NULL; - // else - // *(byte **)p = (byte *)&mmove_reloc + index; - // break; - // - // default: - // gi.error ("ReadEdict: unknown field type"); - // } - //} - // - ////========================================================= - // - ///* - //============== - //WriteClient - // - //All pointer variables (except function pointers) must be handled specially. - //============== - //*/ - //void WriteClient (FILE *f, gclient_t *client) - //{ - // field_t *field; - // gclient_t temp; - // - // // all of the ints, floats, and vectors stay as they are - // temp = *client; - // - // // change the pointers to lengths or indexes - // for (field=clientfields ; field.name ; field++) - // { - // WriteField1 (f, field, (byte *)&temp); - // } - // - // // write the block - // fwrite (&temp, sizeof(temp), 1, f); - // - // // now write any allocated data following the edict - // for (field=clientfields ; field.name ; field++) - // { - // WriteField2 (f, field, (byte *)client); - // } - //} - // /* - ============== - ReadClient + ============ + WriteGame + + This will be called whenever the game goes to a new level, + and when the user explicitly saves the game. - All pointer variables (except function pointers) must be handled specially. - ============== + Game information include cross level data, like multi level + triggers, help computer info, and all client states. + + A single player death will automatically restore from the + last save position. + ============ */ - - //} // - - /* - //============ - //WriteGame - // - //This will be called whenever the game goes to a new level, - //and when the user explicitly saves the game. - // - //Game information include cross level data, like multi level - //triggers, help computer info, and all client states. - // - //A single player death will automatically restore from the - //last save position. - //============ - //*/ - //public static void WriteGame (String filename, boolean autosave) - //{ - // FILE *f; - // int i; - // char str[16]; - // - // if (!autosave) - // SaveClientData (); - // - // f = fopen (filename, "rw"); - // if (!f) - // gi.error ("Couldn't open %s", filename); - // - // memset (str, 0, sizeof(str)); - // strcpy (str, __DATE__); - // fwrite (str, sizeof(str), 1, f); - // - // game.autosaved = autosave; - // fwrite (&game, sizeof(game), 1, f); - // game.autosaved = false; - // - // for (i=0 ; i<game.maxclients ; i++) - // WriteClient (f, &game.clients[i]); - // - // fclose (f); - //} - // + public static void WriteGame (String filename, boolean autosave) + { + try + { + QuakeFile f; + + if (!autosave) + SaveClientData(); + + f = new QuakeFile(filename, "rw"); + + if (f == null) + gi.error ("Couldn't write to " + filename); + + game.autosaved = autosave; + game.write(f); + game.autosaved = false; + + for (int i=0 ; i<game.maxclients ; i++) + game.clients[i]. write(f); + + fclose (f); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + public static void ReadGame(String filename) { - RandomAccessFile f = null; + QuakeFile f = null; try { - f = new RandomAccessFile(filename, "r"); - - byte buf[] = new byte[(int) f.length()]; - + f = new QuakeFile(filename, "r"); Com.Printf("loading game:" + filename); - - f.readFully(buf); - - ByteBuffer bb = ByteBuffer.wrap(buf); - - bb.order(ByteOrder.LITTLE_ENDIAN); - CreateEdicts(); - game.load(bb); - //game.dump(); + game.load(f); for (int i = 0; i < game.maxclients; i++) { game.clients[i] = new gclient_t(i); - game.clients[i].load(bb); + game.clients[i].read(f); } - Com.Println(""); - Com.Println("file length:" + f.length()); - Com.Println("processed bytes:" + bb.position()); - + f.close(); } catch (Exception e) { e.printStackTrace(); - //gi.error ("File problems in "+ filename); - } //if (!f) - // gi.error ("Couldn't open %s", filename); - // - // fread (str, sizeof(str), 1, f); - // if (strcmp (str, __DATE__)) - // { - // fclose (f); - // gi.error ("Savegame from an older version.\n"); - // } - // - // CreateEdicts(); - // - // fread (game, sizeof(game), 1, f); - // - // CreateClients(); - // - // for (i=0 ; i<game.maxclients ; i++) - // ReadClient (f, game.clients[i]); - // - // fclose (f); - try { + } + } + + /* + ================= + WriteLevel + + ================= + */ + static void WriteLevel (String filename) + { + try + { + int i; + edict_t ent; + QuakeFile f; + + f= new QuakeFile(filename, "rw"); + if (f==null) + gi.error("Couldn't open for writing: " + filename); + + // write out level_locals_t + level.write(f); + + // write out all the entities + for (i= 0; i < globals.num_edicts; i++) + { + ent= g_edicts[i]; + if (!ent.inuse) + continue; + f.writeInt(i); + ent.write(f); + + } + + i= -1; + f.writeInt(-1); + f.close(); } - catch (IOException e) { - Com.Error(Defines.ERR_DROP, "Unable to load savegame"); + catch (Exception e) + { + e.printStackTrace(); } } + + + /* + ================= + ReadLevel + + SpawnEntities will allready have been called on the + level the same way it was when the level was saved. + + That is necessary to get the baselines + set up identically. + + The server will have cleared all of the world links before + calling ReadLevel. + + No clients are connected yet. + ================= + */ + static void ReadLevel (String filename) throws IOException + { + edict_t ent; + + QuakeFile f = new QuakeFile(filename, "r"); + + if (f==null) + gi.error ("Couldn't read level file " + filename); + + // wipe all the entities + Game.CreateEdicts(); + + globals.num_edicts = (int) maxclients.value + 1; - // - ////========================================================== - // - // - ///* - //============== - //WriteEdict - // - //All pointer variables (except function pointers) must be handled specially. - //============== - //*/ - //void WriteEdict (FILE *f, edict_t *ent) - //{ - // field_t *field; - // edict_t temp; - // - // // all of the ints, floats, and vectors stay as they are - // temp = *ent; - // - // // change the pointers to lengths or indexes - // for (field=fields ; field.name ; field++) - // { - // WriteField1 (f, field, (byte *)&temp); - // } - // - // // write the block - // fwrite (&temp, sizeof(temp), 1, f); - // - // // now write any allocated data following the edict - // for (field=fields ; field.name ; field++) - // { - // WriteField2 (f, field, (byte *)ent); - // } - // - //} - // - ///* - //============== - //WriteLevelLocals - // - //All pointer variables (except function pointers) must be handled specially. - //============== - //*/ - //void WriteLevelLocals (FILE *f) - //{ - // field_t *field; - // level_locals_t temp; - // - // // all of the ints, floats, and vectors stay as they are - // temp = level; - // - // // change the pointers to lengths or indexes - // for (field=levelfields ; field.name ; field++) - // { - // WriteField1 (f, field, (byte *)&temp); - // } - // - // // write the block - // fwrite (&temp, sizeof(temp), 1, f); - // - // // now write any allocated data following the edict - // for (field=levelfields ; field.name ; field++) - // { - // WriteField2 (f, field, (byte *)&level); - // } - //} - // - // - ///* - //============== - //ReadEdict - // - //All pointer variables (except function pointers) must be handled specially. - //============== - //*/ - //void ReadEdict (FILE *f, edict_t *ent) - //{ - // field_t *field; - // - // fread (ent, sizeof(*ent), 1, f); - // - // for (field=fields ; field.name ; field++) - // { - // ReadField (f, field, (byte *)ent); - // } - //} - // - ///* - //============== - //ReadLevelLocals - // - //All pointer variables (except function pointers) must be handled specially. - //============== - //*/ - //void ReadLevelLocals (FILE *f) - //{ - // field_t *field; - // - // fread (&level, sizeof(level), 1, f); - // - // for (field=levelfields ; field.name ; field++) - // { - // ReadField (f, field, (byte *)&level); - // } - //} - // - ///* - //================= - //WriteLevel - // - //================= - //*/ - //void WriteLevel (char *filename) - //{ - // int i; - // edict_t *ent; - // FILE *f; - // void *base; - // - // f = fopen (filename, "rw"); - // if (!f) - // gi.error ("Couldn't open %s", filename); - // - // // write out edict size for checking - // i = sizeof(edict_t); - // fwrite (&i, sizeof(i), 1, f); - // - // // write out a function pointer for checking - // base = (void *)InitGame; - // fwrite (&base, sizeof(base), 1, f); - // - // // write out level_locals_t - // WriteLevelLocals (f); - // - // // write out all the entities - // for (i=0 ; i<globals.num_edicts ; i++) - // { - // ent = &g_edicts[i]; - // if (!ent.inuse) - // continue; - // fwrite (&i, sizeof(i), 1, f); - // WriteEdict (f, ent); - // } - // i = -1; - // fwrite (&i, sizeof(i), 1, f); - // - // fclose (f); - //} - // - // - ///* - //================= - //ReadLevel - // - //SpawnEntities will allready have been called on the - //level the same way it was when the level was saved. - // - //That is necessary to get the baselines - //set up identically. - // - //The server will have cleared all of the world links before - //calling ReadLevel. - // - //No clients are connected yet. - //================= - //*/ - //void ReadLevel (char *filename) - //{ - // int entnum; - // FILE *f; - // int i; - // void *base; - // edict_t *ent; - // - // f = fopen (filename, "r"); - // if (!f) - // gi.error ("Couldn't open %s", filename); - // - // // free any dynamic memory allocated by loading the level - // // base state - // gi.FreeTags (TAG_LEVEL); - // - // // wipe all the entities - // memset (g_edicts, 0, game.maxentities*sizeof(g_edicts[0])); - // globals.num_edicts = maxclients.value+1; - // - // // check edict size - // fread (&i, sizeof(i), 1, f); - // if (i != sizeof(edict_t)) - // { - // fclose (f); - // gi.error ("ReadLevel: mismatched edict size"); - // } - // - // // check function pointer base address - // fread (&base, sizeof(base), 1, f); - //#ifdef _WIN32 - // if (base != (void *)InitGame) - // { - // fclose (f); - // gi.error ("ReadLevel: function pointers have moved"); - // } - //#else - // gi.dprintf("Function offsets %d\n", ((byte *)base) - ((byte *)InitGame)); - //#endif - // - // // load the level locals - // ReadLevelLocals (f); - // - // // load all the entities - // while (1) - // { - // if (fread (&entnum, sizeof(entnum), 1, f) != 1) - // { - // fclose (f); - // gi.error ("ReadLevel: failed to read entnum"); - // } - // if (entnum == -1) - // break; - // if (entnum >= globals.num_edicts) - // globals.num_edicts = entnum+1; - // - // ent = &g_edicts[entnum]; - // ReadEdict (f, ent); - // - // // let the server rebuild world links for this ent - // memset (&ent.area, 0, sizeof(ent.area)); - // gi.linkentity (ent); - // } - // - // fclose (f); - // - // // mark all clients as unconnected - // for (i=0 ; i<maxclients.value ; i++) - // { - // ent = &g_edicts[i+1]; - // ent.client = game.clients + i; - // ent.client.pers.connected = false; - // } - // - // // do any load time things at this point - // for (i=0 ; i<globals.num_edicts ; i++) - // { - // ent = &g_edicts[i]; - // - // if (!ent.inuse) - // continue; - // - // // fire any cross-level triggers - // if (ent.classname) - // if (strcmp(ent.classname, "target_crosslevel_target") == 0) - // ent.nextthink = level.time + ent.delay; - // } - //} - + // load the level locals + level.read(f); + + // load all the entities + while (true) + { + int entnum = f.readInt(); + if (entnum == -1) + break; + + if (entnum >= globals.num_edicts) + globals.num_edicts = entnum + 1; + + ent = g_edicts[entnum]; + System.out.println("readint ent" + entnum); + ent.read(f); + ent.cleararealinks(); + gi.linkentity(ent); + } + + fclose (f); + + // mark all clients as unconnected + for (int i=0 ; i<maxclients.value ; i++) + { + ent = g_edicts[i+1]; + ent.client = game.clients[i]; + ent.client.pers.connected = false; + } + + // do any load time things at this point + for (int i=0 ; i<globals.num_edicts ; i++) + { + ent = g_edicts[i]; + + if (!ent.inuse) + continue; + + // fire any cross-level triggers + if (ent.classname != null) + if (strcmp(ent.classname, "target_crosslevel_target") == 0) + ent.nextthink = level.time + ent.delay; + } + } } |