diff --git a/CHANGELOG.txt b/CHANGELOG.txt index db1ce578f..c127b5009 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -7,6 +7,7 @@ main/newdemo.c: Added a new code to properly re-record view/cockpit-events at be arch/sdl/window.c, main/automap.c, main/escort.c, main/game.c, main/gamecntl.c, main/kconfig.c, main/menu.c, main/net_ipx.c, main/net_udp.c, main/newmenu.c: Make response to EVENT_WINDOW_CLOSE conform to 'handling' system - returning 1 means abort closing main/kconfig.c, main/newmenu.c: Tidy up newmenu_show/hide_cursor calls main/newmenu.c: Allow user to abort close, for whatever reason (helps with my next commit) +main/gamesave.c, main/newdemo.c, main/object.c, main/object.h, main/state.c: Improved Object signature assignment and made sure there will be no duplicates; Also used short-ranged values only so Demo system won't screw up 20100127 -------- diff --git a/main/gamesave.c b/main/gamesave.c index 65950e57c..678ec6554 100644 --- a/main/gamesave.c +++ b/main/gamesave.c @@ -786,7 +786,7 @@ int load_game_data(CFILE *LoadFile) } //===================== READ PLAYER INFO ========================== - Object_next_signature = 0; + //===================== READ OBJECT INFO ========================== @@ -801,7 +801,7 @@ int load_game_data(CFILE *LoadFile) read_object(&Objects[i], LoadFile, game_top_fileinfo_version); - Objects[i].signature = Object_next_signature++; + Objects[i].signature = obj_get_signature(); verify_object( &Objects[i] ); } diff --git a/main/newdemo.c b/main/newdemo.c index 756c3bbfc..b19ea478a 100644 --- a/main/newdemo.c +++ b/main/newdemo.c @@ -454,6 +454,7 @@ object *prev_obj=NULL; //ptr to last object read in void nd_read_object(object *obj) { memset(obj, 0, sizeof(object)); + short shortsig = 0; /* * Do render type first, since with render_type == RT_NONE, we @@ -466,20 +467,8 @@ void nd_read_object(object *obj) nd_read_byte((sbyte *) &(obj->id)); nd_read_byte((sbyte *) &(obj->flags)); - nd_read_short((short *)&(obj->signature)); - - /* This doesn't make sense, since the object signature is supposed to - be an int, but a short is probably half the size on many platforms. - The problem then is that probably only half the signature will be - initialized. This is definitely not portable. - - See the typedef struct object's signature field in object.h to see - what I mean. The compiler warning with my gcc 4.2.3 seems to be - warranted. - - Kip (kip@thevertigo.com) - */ - + nd_read_short(&shortsig); + obj->signature = shortsig; // It's OKAY! We made sure, obj->signature is never has a value which short cannot handle!!! We cannot do this otherwise, without breaking the demo format! nd_read_shortpos(obj); if ((obj->type == OBJ_ROBOT) && (obj->id == SPECIAL_REACTOR_ROBOT)) @@ -690,6 +679,7 @@ void nd_read_object(object *obj) void nd_write_object(object *obj) { int life; + short shortsig = 0; if ((obj->type == OBJ_ROBOT) && (obj->id == SPECIAL_REACTOR_ROBOT)) Int3(); @@ -705,7 +695,8 @@ void nd_write_object(object *obj) nd_write_byte(obj->id); nd_write_byte(obj->flags); - nd_write_short((short)obj->signature); + shortsig = obj->signature; // It's OKAY! We made sure, obj->signature is never has a value which short cannot handle!!! We cannot do this otherwise, without breaking the demo format! + nd_write_short(shortsig); nd_write_shortpos(obj); if ((obj->type != OBJ_HOSTAGE) && (obj->type != OBJ_ROBOT) && (obj->type != OBJ_PLAYER) && (obj->type != OBJ_POWERUP) && (obj->type != OBJ_CLUTTER)) { diff --git a/main/object.c b/main/object.c index f411fd85e..910b20ffa 100644 --- a/main/object.c +++ b/main/object.c @@ -1031,7 +1031,29 @@ void obj_unlink(int objnum) Assert(Objects[0].prev != 0); } -int Object_next_signature = 1; //player gets 0, others start at 1 +// Returns a new, unique signature for a new object +int obj_get_signature() +{ + static short sig = 0; // Yes! Short! a) We do not need higher values b) the demo system only stores shorts + int free = 0, i = 0; + + while (!free) + { + free = 1; + sig++; + if (sig < 0) + sig = 0; + for (i = 0; i <= MAX_OBJECTS; i++) + { + if ((sig == Objects[i].signature) && (Objects[i].type != OBJ_NONE)) + { + free = 0; + } + } + } + + return sig; +} int Debris_object_count=0; @@ -1217,7 +1239,7 @@ int obj_create(ubyte type,ubyte id,int segnum,vms_vector *pos, // in uninitialized fields. memset( obj, 0, sizeof(object) ); - obj->signature = Object_next_signature++; + obj->signature = obj_get_signature(); obj->type = type; obj->id = id; obj->last_pos = *pos; @@ -1311,7 +1333,7 @@ int obj_create_copy(int objnum, vms_vector *new_pos, int newsegnum) obj_link(newobjnum,newsegnum); - obj->signature = Object_next_signature++; + obj->signature = obj_get_signature(); //we probably should initialize sub-structures here diff --git a/main/object.h b/main/object.h index 0c423ddb7..f1c147257 100644 --- a/main/object.h +++ b/main/object.h @@ -423,6 +423,9 @@ extern void extract_shortpos(object *objp, shortpos *spp, int swap_bytes); // between levels if clear_all is set, clear even proximity bombs void clear_transient_objects(int clear_all); +// Returns a new, unique signature for a new object +int obj_get_signature(); + // returns the number of a free object, updating Highest_object_index. // Generally, obj_create() should be called to get an object, since it // fills in important fields and does the linking. returns -1 if no diff --git a/main/state.c b/main/state.c index 26f182370..ac6173cb1 100644 --- a/main/state.c +++ b/main/state.c @@ -894,7 +894,6 @@ int state_restore_all_sub(char *filename, int secret_restore) Highest_object_index = i-1; object_read_n_swap(Objects, i, swap, fp); - Object_next_signature = 0; for (i=0; i<=Highest_object_index; i++ ) { obj = &Objects[i]; obj->rtype.pobj_info.alt_textures = -1; @@ -902,8 +901,6 @@ int state_restore_all_sub(char *filename, int secret_restore) obj->next = obj->prev = obj->segnum = -1; if ( obj->type != OBJ_NONE ) { obj_link(i,segnum); - if ( obj->signature > Object_next_signature ) - Object_next_signature = obj->signature; } //look for, and fix, boss with bogus shields @@ -921,8 +918,7 @@ int state_restore_all_sub(char *filename, int secret_restore) } special_reset_objects(); - Object_next_signature++; - + // 1 = Didn't die on secret level. // 2 = Died on secret level. if (secret_restore && (Current_level_num >= 0)) {