diff options
Diffstat (limited to 'src/baseq2/g_save.c')
-rw-r--r-- | src/baseq2/g_save.c | 453 |
1 files changed, 238 insertions, 215 deletions
diff --git a/src/baseq2/g_save.c b/src/baseq2/g_save.c index 25d608b..8477306 100644 --- a/src/baseq2/g_save.c +++ b/src/baseq2/g_save.c @@ -8,7 +8,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -32,25 +32,25 @@ typedef struct { } save_field_t; #ifdef _DEBUG -#define _FA(type,name,size) {type,#name,_OFS(name),size} +#define _FA(type, name, size) { type, #name, _OFS(name), size } #else -#define _FA(type,name,size) {type,_OFS(name),size} +#define _FA(type, name, size) { type, _OFS(name), size } #endif -#define _F(type,name) _FA(type,name,1) -#define SZ(name,size) _FA(F_ZSTRING,name,size) -#define BA(name,size) _FA(F_BYTE,name,size) -#define B(name) BA(name,1) -#define SA(name,size) _FA(F_SHORT,name,size) -#define S(name) SA(name,1) -#define IA(name,size) _FA(F_INT,name,size) -#define I(name) IA(name,1) -#define FA(name,size) _FA(F_FLOAT,name,size) -#define F(name) FA(name,1) -#define L(name) _F(F_LSTRING,name) -#define V(name) _F(F_VECTOR,name) -#define T(name) _F(F_ITEM,name) -#define E(name) _F(F_EDICT,name) -#define P(name,type) _FA(F_POINTER,name,type) +#define _F(type, name) _FA(type, name, 1) +#define SZ(name, size) _FA(F_ZSTRING, name, size) +#define BA(name, size) _FA(F_BYTE, name, size) +#define B(name) BA(name, 1) +#define SA(name, size) _FA(F_SHORT, name, size) +#define S(name) SA(name, 1) +#define IA(name, size) _FA(F_INT, name, size) +#define I(name) IA(name, 1) +#define FA(name, size) _FA(F_FLOAT, name, size) +#define F(name) FA(name, 1) +#define L(name) _F(F_LSTRING, name) +#define V(name) _F(F_VECTOR, name) +#define T(name) _F(F_ITEM, name) +#define E(name) _F(F_EDICT, name) +#define P(name, type) _FA(F_POINTER, name, type) static const save_field_t entityfields[] = { #define _OFS FOFS @@ -181,7 +181,7 @@ static const save_field_t entityfields[] = { V(move_origin), V(move_angles), - + I(light_level), I(style), @@ -312,7 +312,7 @@ static const save_field_t clientfields[] = { I(ps.gunframe), FA(ps.blend, 4), - + F(ps.fov), I(ps.rdflags), @@ -432,313 +432,334 @@ static const save_field_t gamefields[] = { //========================================================= -static void write_data( void *buf, size_t len, FILE *f ) { - if( fwrite( buf, 1, len, f ) != len ) { - gi.error( "%s: couldn't write %"PRIz" bytes", __func__, len ); +static void write_data(void *buf, size_t len, FILE *f) +{ + if (fwrite(buf, 1, len, f) != len) { + gi.error("%s: couldn't write %"PRIz" bytes", __func__, len); } } -static void write_short( FILE *f, short v ) { - v = LittleShort( v ); - write_data( &v, sizeof( v ), f ); +static void write_short(FILE *f, short v) +{ + v = LittleShort(v); + write_data(&v, sizeof(v), f); } -static void write_int( FILE *f, int v ) { - v = LittleLong( v ); - write_data( &v, sizeof( v ), f ); +static void write_int(FILE *f, int v) +{ + v = LittleLong(v); + write_data(&v, sizeof(v), f); } -static void write_float( FILE *f, float v ) { - v = LittleFloat( v ); - write_data( &v, sizeof( v ), f ); +static void write_float(FILE *f, float v) +{ + v = LittleFloat(v); + write_data(&v, sizeof(v), f); } -static void write_string( FILE *f, char *s ) { +static void write_string(FILE *f, char *s) +{ size_t len; - if( !s ) { - write_int( f, -1 ); + if (!s) { + write_int(f, -1); return; } - len = strlen( s ); - write_int( f, len ); - write_data( s, len, f ); + len = strlen(s); + write_int(f, len); + write_data(s, len, f); } -static void write_vector( FILE *f, vec_t *v ) { - write_float( f, v[0] ); - write_float( f, v[1] ); - write_float( f, v[2] ); +static void write_vector(FILE *f, vec_t *v) +{ + write_float(f, v[0]); + write_float(f, v[1]); + write_float(f, v[2]); } -static void write_index( FILE *f, void *p, size_t size, void *start, int max_index ) { +static void write_index(FILE *f, void *p, size_t size, void *start, int max_index) +{ size_t diff; - if( !p ) { - write_int( f, -1 ); + if (!p) { + write_int(f, -1); return; } - if( p < start || ( byte * )p > ( byte * )start + max_index * size ) { - gi.error( "%s: pointer out of range: %p", __func__, p ); + if (p < start || (byte *)p > (byte *)start + max_index * size) { + gi.error("%s: pointer out of range: %p", __func__, p); } diff = p - start; - if( diff % size ) { - gi.error( "%s: misaligned pointer: %p", __func__, p ); + if (diff % size) { + gi.error("%s: misaligned pointer: %p", __func__, p); } - write_int( f, ( int )( diff / size ) ); + write_int(f, (int)(diff / size)); } -static void write_pointer( FILE *f, void *p, ptr_type_t type ) { +static void write_pointer(FILE *f, void *p, ptr_type_t type) +{ const save_ptr_t *ptr; int i; - if( !p ) { - write_int( f, -1 ); - return; + if (!p) { + write_int(f, -1); + return; } - for( i = 0, ptr = save_ptrs; i < num_save_ptrs; i++, ptr++ ) { - if( ptr->type == type && ptr->ptr == p ) { - write_int( f, i ); + for (i = 0, ptr = save_ptrs; i < num_save_ptrs; i++, ptr++) { + if (ptr->type == type && ptr->ptr == p) { + write_int(f, i); return; } } - gi.error( "%s: unknown pointer: %p", __func__, p ); + gi.error("%s: unknown pointer: %p", __func__, p); } -static void write_field( FILE *f, const save_field_t *field, void *base ) { +static void write_field(FILE *f, const save_field_t *field, void *base) +{ void *p = (byte *)base + field->ofs; int i; - switch( field->type ) { + switch (field->type) { case F_BYTE: - write_data( p, field->size, f ); + write_data(p, field->size, f); break; case F_SHORT: - for( i = 0; i < field->size; i++ ) { - write_short( f, (( short * )p)[i] ); + for (i = 0; i < field->size; i++) { + write_short(f, ((short *)p)[i]); } break; case F_INT: - for( i = 0; i < field->size; i++ ) { - write_int( f, (( int * )p)[i] ); + for (i = 0; i < field->size; i++) { + write_int(f, ((int *)p)[i]); } break; case F_FLOAT: - for( i = 0; i < field->size; i++ ) { - write_float( f, (( float * )p)[i] ); + for (i = 0; i < field->size; i++) { + write_float(f, ((float *)p)[i]); } break; case F_VECTOR: - write_vector( f, ( vec_t * )p ); + write_vector(f, (vec_t *)p); break; case F_ZSTRING: - write_string( f, ( char * )p ); + write_string(f, (char *)p); break; case F_LSTRING: - write_string( f, *( char ** )p ); + write_string(f, *(char **)p); break; case F_EDICT: - write_index( f, *( void ** )p, sizeof( edict_t ), g_edicts, MAX_EDICTS - 1 ); + write_index(f, *(void **)p, sizeof(edict_t), g_edicts, MAX_EDICTS - 1); break; case F_CLIENT: - write_index( f, *( void ** )p, sizeof( gclient_t ), game.clients, game.maxclients - 1 ); + write_index(f, *(void **)p, sizeof(gclient_t), game.clients, game.maxclients - 1); break; case F_ITEM: - write_index( f, *( void ** )p, sizeof( gitem_t ), itemlist, game.num_items - 1 ); + write_index(f, *(void **)p, sizeof(gitem_t), itemlist, game.num_items - 1); break; case F_POINTER: - write_pointer( f, *( void ** )p, field->size ); + write_pointer(f, *(void **)p, field->size); break; default: - gi.error( "%s: unknown field type", __func__ ); + gi.error("%s: unknown field type", __func__); } } -static void write_fields( FILE *f, const save_field_t *fields, void *base ) { +static void write_fields(FILE *f, const save_field_t *fields, void *base) +{ const save_field_t *field; - for( field = fields; field->type; field++ ) { - write_field( f, field, base ); + for (field = fields; field->type; field++) { + write_field(f, field, base); } } -static void read_data( void *buf, size_t len, FILE *f ) { - if( fread( buf, 1, len, f ) != len ) { - gi.error( "%s: couldn't read %"PRIz" bytes", __func__, len ); +static void read_data(void *buf, size_t len, FILE *f) +{ + if (fread(buf, 1, len, f) != len) { + gi.error("%s: couldn't read %"PRIz" bytes", __func__, len); } } -static int read_short( FILE *f ) { +static int read_short(FILE *f) +{ short v; - read_data( &v, sizeof( v ), f ); - v = LittleShort( v ); + read_data(&v, sizeof(v), f); + v = LittleShort(v); return v; } -static int read_int( FILE *f ) { +static int read_int(FILE *f) +{ int v; - read_data( &v, sizeof( v ), f ); - v = LittleLong( v ); + read_data(&v, sizeof(v), f); + v = LittleLong(v); return v; } -static float read_float( FILE *f ) { +static float read_float(FILE *f) +{ float v; - read_data( &v, sizeof( v ), f ); - v = LittleFloat( v ); + read_data(&v, sizeof(v), f); + v = LittleFloat(v); return v; } -static char *read_string( FILE *f ) { +static char *read_string(FILE *f) +{ int len; char *s; - len = read_int( f ); - if( len == -1 ) { + len = read_int(f); + if (len == -1) { return NULL; } - if( len < 0 || len > 65536 ) { - gi.error( "%s: bad length", __func__ ); + if (len < 0 || len > 65536) { + gi.error("%s: bad length", __func__); } - s = gi.TagMalloc( len + 1, TAG_LEVEL ); - read_data( s, len, f ); + s = gi.TagMalloc(len + 1, TAG_LEVEL); + read_data(s, len, f); s[len] = 0; return s; } -static void read_zstring( FILE *f, char *s, size_t size ) { +static void read_zstring(FILE *f, char *s, size_t size) +{ int len; - len = read_int( f ); - if( len < 0 || len >= size ) { - gi.error( "%s: bad length", __func__ ); + len = read_int(f); + if (len < 0 || len >= size) { + gi.error("%s: bad length", __func__); } - read_data( s, len, f ); + read_data(s, len, f); s[len] = 0; } -static void read_vector( FILE *f, vec_t *v ) { - v[0] = read_float( f ); - v[1] = read_float( f ); - v[2] = read_float( f ); +static void read_vector(FILE *f, vec_t *v) +{ + v[0] = read_float(f); + v[1] = read_float(f); + v[2] = read_float(f); } -static void *read_index( FILE *f, size_t size, void *start, int max_index ) { +static void *read_index(FILE *f, size_t size, void *start, int max_index) +{ int index; byte *p; - index = read_int( f ); - if( index == -1 ) { + index = read_int(f); + if (index == -1) { return NULL; } - if( index < 0 || index > max_index ) { - gi.error( "%s: bad index", __func__ ); + if (index < 0 || index > max_index) { + gi.error("%s: bad index", __func__); } - p = ( byte * )start + index * size; + p = (byte *)start + index * size; return p; } -static void *read_pointer( FILE *f, ptr_type_t type ) { +static void *read_pointer(FILE *f, ptr_type_t type) +{ int index; const save_ptr_t *ptr; - index = read_int( f ); - if( index == -1 ) { + index = read_int(f); + if (index == -1) { return NULL; } - if( index < 0 || index >= num_save_ptrs ) { - gi.error( "%s: bad index", __func__ ); + if (index < 0 || index >= num_save_ptrs) { + gi.error("%s: bad index", __func__); } ptr = &save_ptrs[index]; - if( ptr->type != type ) { - gi.error( "%s: type mismatch", __func__ ); + if (ptr->type != type) { + gi.error("%s: type mismatch", __func__); } return ptr->ptr; } -static void read_field( FILE *f, const save_field_t *field, void *base ) { - void *p = ( byte * )base + field->ofs; +static void read_field(FILE *f, const save_field_t *field, void *base) +{ + void *p = (byte *)base + field->ofs; int i; - switch( field->type ) { + switch (field->type) { case F_BYTE: - read_data( p, field->size, f ); + read_data(p, field->size, f); break; case F_SHORT: - for( i = 0; i < field->size; i++ ) { - (( short * )p)[i] = read_short( f ); + for (i = 0; i < field->size; i++) { + ((short *)p)[i] = read_short(f); } break; case F_INT: - for( i = 0; i < field->size; i++ ) { - (( int * )p)[i] = read_int( f ); + for (i = 0; i < field->size; i++) { + ((int *)p)[i] = read_int(f); } break; case F_FLOAT: - for( i = 0; i < field->size; i++ ) { - (( float * )p)[i] = read_float( f ); + for (i = 0; i < field->size; i++) { + ((float *)p)[i] = read_float(f); } break; case F_VECTOR: - read_vector( f, ( vec_t * )p ); + read_vector(f, (vec_t *)p); break; case F_LSTRING: - *( char ** )p = read_string( f ); + *(char **)p = read_string(f); break; case F_ZSTRING: - read_zstring( f, ( char * )p, field->size ); + read_zstring(f, (char *)p, field->size); break; case F_EDICT: - *( edict_t ** )p = read_index( f, sizeof( edict_t ), g_edicts, game.maxentities - 1 ); + *(edict_t **)p = read_index(f, sizeof(edict_t), g_edicts, game.maxentities - 1); break; case F_CLIENT: - *( gclient_t ** )p = read_index( f, sizeof( gclient_t ), game.clients, game.maxclients - 1 ); + *(gclient_t **)p = read_index(f, sizeof(gclient_t), game.clients, game.maxclients - 1); break; case F_ITEM: - *( gitem_t ** )p = read_index( f, sizeof( gitem_t ), itemlist, game.num_items - 1 ); + *(gitem_t **)p = read_index(f, sizeof(gitem_t), itemlist, game.num_items - 1); break; case F_POINTER: - *( void ** )p = read_pointer( f, field->size ); + *(void **)p = read_pointer(f, field->size); break; default: - gi.error( "%s: unknown field type", __func__ ); + gi.error("%s: unknown field type", __func__); } } -static void read_fields( FILE *f, const save_field_t *fields, void *base ) { +static void read_fields(FILE *f, const save_field_t *fields, void *base) +{ const save_field_t *field; - for( field = fields; field->type; field++ ) { - read_field( f, field, base ); + for (field = fields; field->type; field++) { + read_field(f, field, base); } } @@ -762,75 +783,77 @@ A single player death will automatically restore from the last save position. ============ */ -void WriteGame (const char *filename, qboolean autosave) { +void WriteGame(const char *filename, qboolean autosave) +{ FILE *f; int i; if (!autosave) - SaveClientData (); + SaveClientData(); - f = fopen (filename, "wb"); + f = fopen(filename, "wb"); if (!f) - gi.error ("Couldn't open %s", filename); + gi.error("Couldn't open %s", filename); - write_int( f, SAVE_MAGIC1 ); - write_int( f, SAVE_VERSION ); + write_int(f, SAVE_MAGIC1); + write_int(f, SAVE_VERSION); game.autosaved = autosave; - write_fields( f, gamefields, &game ); + write_fields(f, gamefields, &game); game.autosaved = qfalse; - for( i = 0; i < game.maxclients; i++ ) { - write_fields( f, clientfields, &game.clients[i] ); + for (i = 0; i < game.maxclients; i++) { + write_fields(f, clientfields, &game.clients[i]); } - fclose (f); + fclose(f); } -void ReadGame (const char *filename) { +void ReadGame(const char *filename) +{ FILE *f; int i; - gi.FreeTags (TAG_GAME); + gi.FreeTags(TAG_GAME); - f = fopen (filename, "rb"); + f = fopen(filename, "rb"); if (!f) - gi.error ("Couldn't open %s", filename); + gi.error("Couldn't open %s", filename); - i = read_int( f ); - if( i != SAVE_MAGIC1 ) { - fclose (f); - gi.error ("Not a save game"); + i = read_int(f); + if (i != SAVE_MAGIC1) { + fclose(f); + gi.error("Not a save game"); } - i = read_int( f ); - if( i != SAVE_VERSION ) { - fclose (f); - gi.error ("Savegame from an older version.\n"); + i = read_int(f); + if (i != SAVE_VERSION) { + fclose(f); + gi.error("Savegame from an older version.\n"); } - read_fields( f, gamefields, &game ); + read_fields(f, gamefields, &game); // should agree with server's version - if( game.maxclients != (int)maxclients->value ) { - fclose (f); - gi.error ("Savegame has bad maxclients.\n"); + if (game.maxclients != (int)maxclients->value) { + fclose(f); + gi.error("Savegame has bad maxclients.\n"); } - if( game.maxentities <= game.maxclients || game.maxentities > MAX_EDICTS ) { - fclose (f); - gi.error ("Savegame has bad maxentities.\n"); + if (game.maxentities <= game.maxclients || game.maxentities > MAX_EDICTS) { + fclose(f); + gi.error("Savegame has bad maxentities.\n"); } - g_edicts = gi.TagMalloc (game.maxentities * sizeof(g_edicts[0]), TAG_GAME); + g_edicts = gi.TagMalloc(game.maxentities * sizeof(g_edicts[0]), TAG_GAME); globals.edicts = g_edicts; globals.max_edicts = game.maxentities; - game.clients = gi.TagMalloc (game.maxclients * sizeof(game.clients[0]), TAG_GAME); - for( i = 0; i < game.maxclients; i++ ) { - read_fields( f, clientfields, &game.clients[i] ); + game.clients = gi.TagMalloc(game.maxclients * sizeof(game.clients[0]), TAG_GAME); + for (i = 0; i < game.maxclients; i++) { + read_fields(f, clientfields, &game.clients[i]); } - fclose (f); + fclose(f); } //========================================================== @@ -842,32 +865,33 @@ WriteLevel ================= */ -void WriteLevel (const char *filename) { +void WriteLevel(const char *filename) +{ int i; edict_t *ent; FILE *f; - f = fopen (filename, "wb"); + f = fopen(filename, "wb"); if (!f) - gi.error ("Couldn't open %s", filename); + gi.error("Couldn't open %s", filename); - write_int( f, SAVE_MAGIC2 ); - write_int( f, SAVE_VERSION ); + write_int(f, SAVE_MAGIC2); + write_int(f, SAVE_VERSION); // write out level_locals_t - write_fields( f, levelfields, &level ); + write_fields(f, levelfields, &level); // write out all the entities - for( i = 0; i < globals.num_edicts; i++ ) { + for (i = 0; i < globals.num_edicts; i++) { ent = &g_edicts[i]; if (!ent->inuse) continue; - write_int( f, i ); - write_fields( f, entityfields, ent ); + write_int(f, i); + write_fields(f, entityfields, ent); } - write_int( f, -1 ); + write_int(f, -1); - fclose (f); + fclose(f); } @@ -887,7 +911,8 @@ calling ReadLevel. No clients are connected yet. ================= */ -void ReadLevel (const char *filename) { +void ReadLevel(const char *filename) +{ int entnum; FILE *f; int i; @@ -895,65 +920,63 @@ void ReadLevel (const char *filename) { // free any dynamic memory allocated by loading the level // base state - gi.FreeTags (TAG_LEVEL); + gi.FreeTags(TAG_LEVEL); - f = fopen (filename, "rb"); + f = fopen(filename, "rb"); if (!f) - gi.error ("Couldn't open %s", filename); + gi.error("Couldn't open %s", filename); // wipe all the entities - memset (g_edicts, 0, game.maxentities*sizeof(g_edicts[0])); - globals.num_edicts = maxclients->value+1; + memset(g_edicts, 0, game.maxentities * sizeof(g_edicts[0])); + globals.num_edicts = maxclients->value + 1; - i = read_int( f ); - if( i != SAVE_MAGIC2 ) { - fclose (f); - gi.error ("Not a save game"); + i = read_int(f); + if (i != SAVE_MAGIC2) { + fclose(f); + gi.error("Not a save game"); } - i = read_int( f ); - if( i != SAVE_VERSION ) { - fclose (f); - gi.error ("Savegame from an older version.\n"); + i = read_int(f); + if (i != SAVE_VERSION) { + fclose(f); + gi.error("Savegame from an older version.\n"); } // load the level locals - read_fields( f, levelfields, &level ); + read_fields(f, levelfields, &level); // load all the entities - while( 1 ) { - entnum = read_int( f ); - if( entnum == -1 ) + while (1) { + entnum = read_int(f); + if (entnum == -1) break; - if( entnum < 0 || entnum >= game.maxentities ) { - gi.error( "%s: bad entity number", __func__ ); + if (entnum < 0 || entnum >= game.maxentities) { + gi.error("%s: bad entity number", __func__); } - if( entnum >= globals.num_edicts ) + if (entnum >= globals.num_edicts) globals.num_edicts = entnum + 1; ent = &g_edicts[entnum]; - read_fields( f, entityfields, ent ); + read_fields(f, entityfields, ent); ent->inuse = qtrue; ent->s.number = entnum; // let the server rebuild world links for this ent - memset (&ent->area, 0, sizeof(ent->area)); - gi.linkentity (ent); + memset(&ent->area, 0, sizeof(ent->area)); + gi.linkentity(ent); } - fclose (f); + fclose(f); // mark all clients as unconnected - for (i=0 ; i<maxclients->value ; i++) - { - ent = &g_edicts[i+1]; + for (i = 0 ; i < maxclients->value ; i++) { + ent = &g_edicts[i + 1]; ent->client = game.clients + i; ent->client->pers.connected = qfalse; } // do any load time things at this point - for (i=0 ; i<globals.num_edicts ; i++) - { + for (i = 0 ; i < globals.num_edicts ; i++) { ent = &g_edicts[i]; if (!ent->inuse) |