diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c5f513f5b..f1678b101 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,9 @@ D1X-Rebirth Changelog +20091115 +-------- +main/gamecntl.c, main/newdemo.c, main/newdemo.h, main/newmenu.c, main/text.c: Add endian converter for demos, read shareware demos, various bugfixes to demo system + 20091005 -------- d1x-rebirth.xcodeproj/project.pbxproj, include/physfsx.h, main/ai.c, main/ai.h, main/cntrlcen.c, main/cntrlcen.h, main/fuelcen.c, main/fuelcen.h, main/object.c, main/object.h, main/player.c, main/player.h, main/state.c, main/switch.c, main/switch.h, main/wall.c, main/wall.h, SConstruct: Read big endian savegames on little endian computers and vice versa diff --git a/main/gamecntl.c b/main/gamecntl.c index e65d4af16..969cb80c6 100644 --- a/main/gamecntl.c +++ b/main/gamecntl.c @@ -442,7 +442,7 @@ void HandleDemoKey(int key) Newdemo_vcr_state = ND_STATE_ONEFRAMEFORWARD; break; case KEY_CTRLED + KEY_RIGHT: - newdemo_goto_end(); + newdemo_goto_end(0); break; case KEY_CTRLED + KEY_LEFT: newdemo_goto_beginning(); diff --git a/main/newdemo.c b/main/newdemo.c index 9d2218081..3f1bb5dd7 100644 --- a/main/newdemo.c +++ b/main/newdemo.c @@ -1,3 +1,4 @@ +/* $Id: newdemo.c,v 1.1.1.1 2006/03/17 19:57:03 zicodxx Exp $ */ /* THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO @@ -7,16 +8,30 @@ IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ +/* + * + * Code to make a complete demo playback system. + * + */ + + #include #include -#include // for memset -#include -#include +#include +#include // for memset #include + +#if !(defined(__APPLE__) && defined(__MACH__)) +#include +#else +#include +#endif + +#include "u_mem.h" #include "inferno.h" #include "game.h" #include "gr.h" @@ -28,6 +43,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "laser.h" #include "key.h" #include "gameseg.h" + #include "object.h" #include "physics.h" #include "slew.h" @@ -41,10 +57,13 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "ai.h" #include "hostage.h" #include "morph.h" + #include "powerup.h" #include "fuelcen.h" + #include "sounds.h" #include "collide.h" + #include "lighting.h" #include "newdemo.h" #include "gameseq.h" @@ -64,7 +83,6 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "mission.h" #include "piggy.h" #include "byteswap.h" -#include "u_mem.h" #include "physfsx.h" #include "console.h" #include "playsave.h" @@ -107,8 +125,6 @@ void DoJasonInterpolate (fix recorded_time); #define ND_EVENT_MULTI_CLOAK 29 // followed by player num #define ND_EVENT_MULTI_DECLOAK 30 // followed by player num #define ND_EVENT_RESTORE_REARVIEW 31 // restore cockpit after rearview mode - -#ifndef SHAREWARE #define ND_EVENT_MULTI_DEATH 32 // with player number #define ND_EVENT_MULTI_KILL 33 // with player number #define ND_EVENT_MULTI_CONNECT 34 // with player number @@ -119,30 +135,24 @@ void DoJasonInterpolate (fix recorded_time); #define ND_EVENT_PRIMARY_AMMO 39 // with old/new ammo count #define ND_EVENT_SECONDARY_AMMO 40 // with old/new ammo count #define ND_EVENT_DOOR_OPENING 41 // with segment/side -#endif #define ND_EVENT_LASER_LEVEL 42 // with old/new level -#define ND_EVENT_LINK_SOUND_TO_OBJ 43 // record digi_link_sound_to_object3 -#define ND_EVENT_KILL_SOUND_TO_OBJ 44 // record digi_kill_sound_linked_to_object +#define ND_EVENT_LINK_SOUND_TO_OBJ 43 // record digi_link_sound_to_object3 +#define ND_EVENT_KILL_SOUND_TO_OBJ 44 // record digi_kill_sound_linked_to_object #define NORMAL_PLAYBACK 0 #define SKIP_PLAYBACK 1 #define INTERPOLATE_PLAYBACK 2 #define INTERPOL_FACTOR (F1_0 + (F1_0/5)) -#ifdef SHAREWARE -#define DEMO_VERSION 5 -#else +#define DEMO_VERSION_SHAREWARE 5 #define DEMO_VERSION 13 -#endif #define DEMO_FILENAME DEMO_DIR "tmpdemo.dem" + #define DEMO_MAX_LEVELS 29 -#ifdef SHAREWARE -#define DEMO_GAME_TYPE 1 -#else +#define DEMO_GAME_TYPE_SHAREWARE 1 #define DEMO_GAME_TYPE 2 -#endif char nd_save_callsign[CALLSIGN_LEN+1]; int Newdemo_state = 0; @@ -154,8 +164,7 @@ int Newdemo_num_written; int Newdemo_old_cockpit; sbyte Newdemo_no_space; sbyte Newdemo_at_eof; -sbyte Newdemo_do_interpolate = 1; -sbyte Newdemo_players_cloaked; +sbyte Newdemo_do_interpolate = 1; // ZICO - I HATE not-interpolated playbacks... sbyte Newdemo_warning_given = 0; sbyte Newdemo_cntrlcen_destroyed = 0; static sbyte nd_bad_read; @@ -168,6 +177,7 @@ sbyte playback_style; sbyte First_time_playback=1; fix JasonPlaybackTotal=0; int Newdemo_show_percentage=1; +static int swap_endian = 0; extern int digi_link_sound_to_object3( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance, int loop_start, int loop_end ); @@ -351,11 +361,15 @@ static void nd_read_byte(sbyte *b) static void nd_read_short(short *s) { newdemo_read(s, 2, 1); + if (swap_endian) + *s = SWAPSHORT(*s); } static void nd_read_int(int *i) { newdemo_read(i, 4, 1); + if (swap_endian) + *i = SWAPINT(*i); } static void nd_read_string(char *str) @@ -369,11 +383,15 @@ static void nd_read_string(char *str) static void nd_read_fix(fix *f) { newdemo_read(f, sizeof(fix), 1); + if (swap_endian) + *f = SWAPINT(*f); } static void nd_read_fixang(fixang *f) { newdemo_read(f, sizeof(fixang), 1); + if (swap_endian) + *f = SWAPSHORT(*f); } static void nd_read_vector(vms_vector *v) @@ -419,6 +437,7 @@ static void nd_read_shortpos(object *obj) } object *prev_obj=NULL; //ptr to last object read in +static int shareware = 0; // reading shareware demo? void nd_read_object(object *obj) { @@ -435,7 +454,7 @@ void nd_read_object(object *obj) nd_read_byte((sbyte *) &(obj->id)); nd_read_byte((sbyte *) &(obj->flags)); - nd_read_short((short *)&(obj->signature)); + 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. @@ -512,7 +531,7 @@ void nd_read_object(object *obj) obj->lifeleft = (fix)((int)obj->lifeleft << 12); } - if (obj->type == OBJ_ROBOT) { + if ((obj->type == OBJ_ROBOT) && !shareware) { if (Robot_info[obj->id].boss_flag) { sbyte cloaked; @@ -801,9 +820,7 @@ static fix last_rec_time=0; void newdemo_record_start_demo() { -#ifndef SHAREWARE int i; -#endif last_rec_time=GameTime-REC_DELAY; // make sure first frame is recorded! @@ -812,25 +829,21 @@ void newdemo_record_start_demo() nd_write_byte(DEMO_VERSION); nd_write_byte(DEMO_GAME_TYPE); nd_write_fix(GameTime); + +#ifdef NETWORK if (Game_mode & GM_MULTI) nd_write_int(Game_mode | (Player_num << 16)); else +#endif + // NOTE LINK TO ABOVE!!! nd_write_int(Game_mode); - #ifdef NETWORK -#ifdef SHAREWARE - if (Game_mode & GM_MULTI) - nd_write_byte(Netgame.team_vector); -#else + if (Game_mode & GM_TEAM) { nd_write_byte(Netgame.team_vector); nd_write_string(Netgame.team_name[0]); nd_write_string(Netgame.team_name[1]); } -#endif -#endif - -#ifndef SHAREWARE if (Game_mode & GM_MULTI) { nd_write_byte((sbyte)N_players); @@ -846,6 +859,8 @@ void newdemo_record_start_demo() } } } else +#endif + // NOTE LINK TO ABOVE!!! nd_write_int(Players[Player_num].score); for (i = 0; i < MAX_PRIMARY_WEAPONS; i++) @@ -860,11 +875,9 @@ void newdemo_record_start_demo() nd_write_string(Current_mission_filename); -#endif - nd_write_byte((sbyte)(f2ir(Players[Player_num].energy))); nd_write_byte((sbyte)(f2ir(Players[Player_num].shields))); - nd_write_int(Players[Player_num].flags); // be sure players flags are set + nd_write_int(Players[Player_num].flags); // be sure players flags are set nd_write_byte((sbyte)Primary_weapon); nd_write_byte((sbyte)Secondary_weapon); Newdemo_start_frame = Newdemo_frame_number = 0; @@ -889,16 +902,16 @@ void newdemo_record_start_frame(fix frame_time ) if (last_rec_time + REC_DELAY <= GameTime || frame_time >= REC_DELAY) { - last_rec_time = GameTime-(GameTime-(last_rec_time + REC_DELAY)); if (frame_time < REC_DELAY) frame_time = REC_DELAY; + last_rec_time = GameTime-(GameTime-(last_rec_time + REC_DELAY)); RecordFrame=1; - + stop_time(); Newdemo_frame_number -= Newdemo_start_frame; nd_write_byte(ND_EVENT_START_FRAME); - nd_write_short(frame_bytes_written - 1); // from previous frame + nd_write_short(frame_bytes_written - 1); // from previous frame frame_bytes_written=3; nd_write_int(Newdemo_frame_number); Newdemo_frame_number++; @@ -909,6 +922,7 @@ void newdemo_record_start_frame(fix frame_time ) { RecordFrame=0; } + } void newdemo_record_render_object(object * obj) @@ -931,14 +945,16 @@ void newdemo_record_viewer_object(object * obj) start_time(); } -void newdemo_record_sound( int soundno ) { +void newdemo_record_sound( int soundno ) +{ stop_time(); nd_write_byte(ND_EVENT_SOUND); nd_write_int( soundno ); start_time(); } -void newdemo_record_sound_3d( int soundno, int angle, int volume ) { +void newdemo_record_sound_3d( int soundno, int angle, int volume ) +{ stop_time(); nd_write_byte( ND_EVENT_SOUND_3D ); nd_write_int( soundno ); @@ -947,7 +963,8 @@ void newdemo_record_sound_3d( int soundno, int angle, int volume ) { start_time(); } -void newdemo_record_sound_3d_once( int soundno, int angle, int volume ) { +void newdemo_record_sound_3d_once( int soundno, int angle, int volume ) +{ stop_time(); nd_write_byte( ND_EVENT_SOUND_3D_ONCE ); nd_write_int( soundno ); @@ -956,6 +973,7 @@ void newdemo_record_sound_3d_once( int soundno, int angle, int volume ) { start_time(); } + void newdemo_record_link_sound_to_object3( int soundno, short objnum, fix max_volume, fix max_distance, int loop_start, int loop_end ) { stop_time(); @@ -977,6 +995,7 @@ void newdemo_record_kill_sound_linked_to_object( int objnum ) start_time(); } + void newdemo_record_wall_hit_process( int segnum, int side, int damage, int playernum ) { stop_time(); @@ -998,14 +1017,16 @@ void newdemo_record_trigger( int segnum, int side, int objnum ) start_time(); } -void newdemo_record_hostage_rescued( int hostage_number ) { +void newdemo_record_hostage_rescued( int hostage_number ) +{ stop_time(); nd_write_byte( ND_EVENT_HOSTAGE_RESCUED ); nd_write_int( hostage_number ); start_time(); } -void newdemo_record_morph_frame(morph_data *md) { +void newdemo_record_morph_frame(morph_data *md) +{ if (!RecordFrame) return; stop_time(); @@ -1014,7 +1035,8 @@ void newdemo_record_morph_frame(morph_data *md) { start_time(); } -void newdemo_record_wall_toggle( int segnum, int side ) { +void newdemo_record_wall_toggle( int segnum, int side ) +{ stop_time(); nd_write_byte( ND_EVENT_WALL_TOGGLE ); nd_write_int( segnum ); @@ -1050,32 +1072,20 @@ void newdemo_record_palette_effect(short r, short g, short b ) start_time(); } -#ifdef SHAREWARE -void newdemo_record_player_energy(int energy) -#else void newdemo_record_player_energy(int old_energy, int energy) -#endif { stop_time(); nd_write_byte( ND_EVENT_PLAYER_ENERGY ); -#ifndef SHAREWARE nd_write_byte((sbyte) old_energy); -#endif nd_write_byte((sbyte) energy); start_time(); } -#ifdef SHAREWARE -void newdemo_record_player_shields(int shield) -#else void newdemo_record_player_shields(int old_shield, int shield) -#endif { stop_time(); nd_write_byte( ND_EVENT_PLAYER_SHIELD ); -#ifndef SHAREWARE nd_write_byte((sbyte)old_shield); -#endif nd_write_byte((sbyte)shield); start_time(); } @@ -1094,12 +1104,10 @@ void newdemo_record_player_weapon(int weapon_type, int weapon_num) nd_write_byte( ND_EVENT_PLAYER_WEAPON ); nd_write_byte((sbyte)weapon_type); nd_write_byte((sbyte)weapon_num); -#ifndef SHAREWARE if (weapon_type) nd_write_byte((sbyte)Secondary_weapon); else nd_write_byte((sbyte)Primary_weapon); -#endif start_time(); } @@ -1189,8 +1197,6 @@ void newdemo_record_multi_decloak(int pnum) start_time(); } -#ifndef SHAREWARE - void newdemo_record_multi_death(int pnum) { stop_time(); @@ -1252,7 +1258,7 @@ void newdemo_record_multi_score(int pnum, int score) stop_time(); nd_write_byte(ND_EVENT_MULTI_SCORE); nd_write_byte((sbyte)pnum); - nd_write_int(score - Players[pnum].score); // called before score is changed!!!! + nd_write_int(score - Players[pnum].score); // called before score is changed!!!! start_time(); } @@ -1293,15 +1299,13 @@ void newdemo_record_door_opening(int segnum, int side) start_time(); } -#endif - void newdemo_record_laser_level(sbyte old_level, sbyte new_level) { - stop_time(); - nd_write_byte(ND_EVENT_LASER_LEVEL); - nd_write_byte(old_level); - nd_write_byte(new_level); - start_time(); + stop_time(); + nd_write_byte(ND_EVENT_LASER_LEVEL); + nd_write_byte(old_level); + nd_write_byte(new_level); + start_time(); } @@ -1314,17 +1318,25 @@ void newdemo_set_new_level(int level_num) start_time(); } -int newdemo_read_demo_start(int rnd_demo) +enum purpose_type { - sbyte version=0, game_type=0, c=0; + PURPOSE_CHOSE_PLAY = 0, + PURPOSE_RANDOM_PLAY, + PURPOSE_REWRITE +}; + +int newdemo_read_demo_start(enum purpose_type purpose) +{ + sbyte i=0, version=0, game_type=0, laser_level=0, c=0; ubyte energy=0, shield=0; - char text[128]; - sbyte i=0, laser_level=0; - char current_mission[9]; + char text[128], current_mission[9]; Rear_view=0; + shareware = 0; - nd_read_byte((sbyte *)&c); + nd_read_byte(&c); + if (purpose == PURPOSE_REWRITE) + nd_write_byte(c); if ((c != ND_EVENT_START_DEMO) || nd_bad_read) { newmenu_item m[1]; @@ -1334,8 +1346,12 @@ int newdemo_read_demo_start(int rnd_demo) return 1; } nd_read_byte(&version); - if (version < DEMO_VERSION) { - if (!rnd_demo) { + if (purpose == PURPOSE_REWRITE) + nd_write_byte(version); + if (version == DEMO_VERSION_SHAREWARE) + shareware = 1; + else if (version < DEMO_VERSION) { + if (purpose == PURPOSE_CHOSE_PLAY) { newmenu_item m[1]; sprintf(text, "%s %s", TXT_CANT_PLAYBACK, TXT_DEMO_OLD); m[ 0].type = NM_TYPE_TEXT; m[ 0].text = text; @@ -1344,24 +1360,28 @@ int newdemo_read_demo_start(int rnd_demo) return 1; } nd_read_byte(&game_type); - if (game_type != DEMO_GAME_TYPE) { - newmenu_item m[3]; + if (purpose == PURPOSE_REWRITE) + nd_write_byte(game_type); + if ((game_type == DEMO_GAME_TYPE_SHAREWARE) && shareware) + shareware = shareware; // all good + else if (game_type != DEMO_GAME_TYPE) { + newmenu_item m[1]; - sprintf(text, "%s %s", TXT_CANT_PLAYBACK, TXT_RECORDED); + sprintf(text, "%s %s", TXT_CANT_PLAYBACK, TXT_DEMO_OLD); m[ 0].type = NM_TYPE_TEXT; m[ 0].text = text; -#ifdef SHAREWARE - m[ 1].type = NM_TYPE_TEXT; m[ 1].text = TXT_WITH_REGISTERED; -#else - m[ 1].type = NM_TYPE_TEXT; m[ 1].text = TXT_WITH_SHAREWARE; -#endif - m[ 2].type = NM_TYPE_TEXT; m[ 2].text = TXT_OF_DESCENT; - newmenu_do( NULL, NULL, sizeof(m)/sizeof(*m), m, NULL ); + return 1; } nd_read_fix(&GameTime); nd_read_int(&Game_mode); -JasonPlaybackTotal=0; + if (purpose == PURPOSE_REWRITE) + { + nd_write_fix(GameTime); + nd_write_int(Game_mode); + } + + JasonPlaybackTotal=0; #ifndef NETWORK if (Game_mode & GM_MULTI) { nm_messagebox( NULL, 1, "Ok", "can't playback net game\nwith this version of code\n" ); @@ -1371,100 +1391,166 @@ JasonPlaybackTotal=0; #ifdef NETWORK change_playernum_to((Game_mode >> 16) & 0x7); -#ifdef SHAREWARE - if (Game_mode & GM_TEAM) - nd_read_byte((sbyte *)&(Netgame.team_vector)); + if (shareware) + { + if (Game_mode & GM_TEAM) + { + nd_read_byte((sbyte *)&(Netgame.team_vector)); + if (purpose == PURPOSE_REWRITE) + nd_write_byte(Netgame.team_vector); + } - for (i =0 ; i < MAX_PLAYERS; i++) { - Players[i].cloak_time = 0; - Players[i].invulnerable_time = 0; - } -#else - if (Game_mode & GM_TEAM) { - nd_read_byte((sbyte *)&(Netgame.team_vector)); - nd_read_string(Netgame.team_name[0]); - nd_read_string(Netgame.team_name[1]); - } - if (Game_mode & GM_MULTI) { - - multi_new_game(); - nd_read_byte((sbyte *)&N_players); - for (i = 0 ; i < N_players; i++) { + for (i =0 ; i < MAX_PLAYERS; i++) { Players[i].cloak_time = 0; Players[i].invulnerable_time = 0; - nd_read_string(Players[i].callsign); - nd_read_byte(&(Players[i].connected)); - - if (Game_mode & GM_MULTI_COOP) { - nd_read_int(&(Players[i].score)); - } else { - nd_read_short((short *)&(Players[i].net_killed_total)); - nd_read_short((short *)&(Players[i].net_kills_total)); + } + } + else + { + if (Game_mode & GM_TEAM) { + nd_read_byte((sbyte *) &(Netgame.team_vector)); + nd_read_string(Netgame.team_name[0]); + nd_read_string(Netgame.team_name[1]); + if (purpose == PURPOSE_REWRITE) + { + nd_write_byte(Netgame.team_vector); + nd_write_string(Netgame.team_name[0]); + nd_write_string(Netgame.team_name[1]); } } - multi_sort_kill_list(); - } else + if (Game_mode & GM_MULTI) { + + if (purpose != PURPOSE_REWRITE) + multi_new_game(); + nd_read_byte(&c); + N_players = (int)c; + // changed this to above two lines -- breaks on the mac because of + // endian issues + // nd_read_byte((sbyte *)&N_players); + if (purpose == PURPOSE_REWRITE) + nd_write_byte(N_players); + for (i = 0 ; i < N_players; i++) { + Players[i].cloak_time = 0; + Players[i].invulnerable_time = 0; + nd_read_string(Players[i].callsign); + nd_read_byte(&(Players[i].connected)); + if (purpose == PURPOSE_REWRITE) + { + nd_write_string(Players[i].callsign); + nd_write_byte(Players[i].connected); + } + + if (Game_mode & GM_MULTI_COOP) { + nd_read_int(&(Players[i].score)); + if (purpose == PURPOSE_REWRITE) + nd_write_int(Players[i].score); + } else { + nd_read_short((short *)&(Players[i].net_killed_total)); + nd_read_short((short *)&(Players[i].net_kills_total)); + if (purpose == PURPOSE_REWRITE) + { + nd_write_short(Players[i].net_killed_total); + nd_write_short(Players[i].net_kills_total); + } + } + } + if (purpose != PURPOSE_REWRITE) + multi_sort_kill_list(); + } + } #endif -#endif // - nd_read_int(&(Players[Player_num].score)); // Note link to above if! +#ifdef NETWORK + if (!(Game_mode & GM_MULTI)) +#endif + { + nd_read_int(&(Players[Player_num].score)); // Note link to above if! + if (purpose == PURPOSE_REWRITE) + nd_write_int(Players[Player_num].score); + } for (i = 0; i < MAX_PRIMARY_WEAPONS; i++) + { nd_read_short((short*)&(Players[Player_num].primary_ammo[i])); + if (purpose == PURPOSE_REWRITE) + nd_write_short(Players[Player_num].primary_ammo[i]); + } for (i = 0; i < MAX_SECONDARY_WEAPONS; i++) - nd_read_short((short*)&(Players[Player_num].secondary_ammo[i])); + { + nd_read_short((short*)&(Players[Player_num].secondary_ammo[i])); + if (purpose == PURPOSE_REWRITE) + nd_write_short(Players[Player_num].secondary_ammo[i]); + } nd_read_byte(&laser_level); - if (laser_level != Players[Player_num].laser_level) { + if ((purpose != PURPOSE_REWRITE) && (laser_level != Players[Player_num].laser_level)) { Players[Player_num].laser_level = laser_level; update_laser_weapon_info(); } + else if (purpose == PURPOSE_REWRITE) + nd_write_byte(laser_level); -// Support for missions + // Support for missions nd_read_string(current_mission); -#ifndef SHAREWARE + if (purpose == PURPOSE_REWRITE) + nd_write_string(current_mission); + if (!shareware) + { #ifdef DEST_SAT - if (!strcmp(current_mission, "")) - strcpy(current_mission, "DESTSAT"); + if (!strcmp(current_mission, "")) + strcpy(current_mission, "DESTSAT"); #endif - if (!load_mission_by_name(current_mission)) { - newmenu_item m[1]; + if ((purpose != PURPOSE_REWRITE) && !load_mission_by_name(current_mission)) { + if (purpose == PURPOSE_CHOSE_PLAY) { + newmenu_item m[1]; - sprintf(text, TXT_NOMISSION4DEMO, current_mission); - m[ 0].type = NM_TYPE_TEXT; m[ 0].text = text; - newmenu_do( NULL, NULL, sizeof(m)/sizeof(*m), m, NULL ); - return 1; + sprintf(text, TXT_NOMISSION4DEMO, current_mission); + m[ 0].type = NM_TYPE_TEXT; m[ 0].text = text; + newmenu_do( NULL, NULL, sizeof(m)/sizeof(*m), m, NULL ); + } + return 1; + } } -#endif //#endif nd_recorded_total = 0; nd_playback_total = 0; - nd_read_byte((sbyte *)&energy); - nd_read_byte((sbyte *)&shield); + nd_read_byte((sbyte*)&energy); + nd_read_byte((sbyte*)&shield); + if (purpose == PURPOSE_REWRITE) + { + nd_write_byte(energy); + nd_write_byte(shield); + } nd_read_int((int *)&(Players[Player_num].flags)); + if (purpose == PURPOSE_REWRITE) + nd_write_int(Players[Player_num].flags); if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) { Players[Player_num].cloak_time = GameTime - (CLOAK_TIME_MAX / 2); - Newdemo_players_cloaked |= (1 << Player_num); } if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) Players[Player_num].invulnerable_time = GameTime - (INVULNERABLE_TIME_MAX / 2); nd_read_byte((sbyte *)&Primary_weapon); nd_read_byte((sbyte *)&Secondary_weapon); + if (purpose == PURPOSE_REWRITE) + { + nd_write_byte(Primary_weapon); + nd_write_byte(Secondary_weapon); + } // Next bit of code to fix problem that I introduced between 1.0 and 1.1 // check the next byte -- it _will_ be a load_new_level event. If it is // not, then we must shift all bytes up by one. -#ifdef SHAREWARE + if (shareware) { unsigned char c; - c = fgetc(infile); + nd_read_byte((sbyte *)&c); if (c != ND_EVENT_NEW_LEVEL) { int flags; @@ -1476,9 +1562,8 @@ JasonPlaybackTotal=0; Primary_weapon = Secondary_weapon; Secondary_weapon = c; } else - ungetc(c, infile); + PHYSFS_seek(infile, PHYSFS_tell(infile) - 1); } -#endif Players[Player_num].energy = i2f(energy); Players[Player_num].shields = i2f(shield); @@ -1509,11 +1594,11 @@ void newdemo_pop_ctrlcen_triggers() #define N_PLAYER_SHIP_TEXTURES 6 -int newdemo_read_frame_information() +int newdemo_read_frame_information(int rewrite) { int done, segnum, side, objnum, soundno, angle, volume, i; object *obj; - ubyte c; + sbyte c; static sbyte saved_letter_cockpit = CM_FULL_COCKPIT, saved_rearview_cockpit = CM_FULL_COCKPIT; done = 0; @@ -1526,36 +1611,53 @@ int newdemo_read_frame_information() Players[Player_num].homing_object_dist = -F1_0; prev_obj = NULL; - - while( !done ) { - nd_read_byte((sbyte *)&c); + + while( !done ) { + nd_read_byte(&c); if (nd_bad_read) { done = -1; break; } + if (rewrite && (c != ND_EVENT_EOF)) + nd_write_byte(c); - switch( c ) { + switch( c ) { - case ND_EVENT_START_FRAME: { // Followed by an integer frame number, then a fix FrameTime + case ND_EVENT_START_FRAME: { // Followed by an integer frame number, then a fix FrameTime short last_frame_length; done=1; nd_read_short(&last_frame_length); nd_read_int(&NewdemoFrameCount); nd_read_int((int *)&nd_recorded_time); + if (nd_bad_read) { done = -1; break; } + if (rewrite) + { + nd_write_short(last_frame_length); + frame_bytes_written = 3; + nd_write_int(NewdemoFrameCount); + nd_write_int(nd_recorded_time); + break; + } if (Newdemo_vcr_state == ND_STATE_PLAYBACK) nd_recorded_total += nd_recorded_time; NewdemoFrameCount--; - if (nd_bad_read) { done = -1; break; } break; } - case ND_EVENT_VIEWER_OBJECT: // Followed by an object structure + case ND_EVENT_VIEWER_OBJECT: // Followed by an object structure nd_read_object(Viewer); + if (nd_bad_read) { done = -1; break; } + if (rewrite) + { + nd_write_object(Viewer); + break; + } if (Newdemo_vcr_state != ND_STATE_PAUSED) { - if (nd_bad_read) { done = -1; break; } segnum = Viewer->segnum; Viewer->next = Viewer->prev = Viewer->segnum = -1; -/* since we have multiple level recording, it can be the case that when rewinding the demo, the viewer is in a segment - that is greater than the highest index of segments. Bash the viewer to segment 0 for bogus view. HACK */ + // HACK HACK HACK -- since we have multiple level recording, it can be the case + // HACK HACK HACK -- that when rewinding the demo, the viewer is in a segment + // HACK HACK HACK -- that is greater than the highest index of segments. Bash + // HACK HACK HACK -- the viewer to segment 0 for bogus view. if (segnum > Highest_segment_index) segnum = 0; @@ -1563,24 +1665,30 @@ int newdemo_read_frame_information() } break; - case ND_EVENT_RENDER_OBJECT: // Followed by an object structure + case ND_EVENT_RENDER_OBJECT: // Followed by an object structure objnum = obj_allocate(); if (objnum==-1) break; obj = &Objects[objnum]; nd_read_object(obj); if (nd_bad_read) { done = -1; break; } + if (rewrite) + { + nd_write_object(obj); + break; + } if (Newdemo_vcr_state != ND_STATE_PAUSED) { segnum = obj->segnum; obj->next = obj->prev = obj->segnum = -1; -// don't render objects is segments greater than Highest_segment_index (see above) + // HACK HACK HACK -- don't render objects is segments greater than Highest_segment_index + // HACK HACK HACK -- (see above) if (segnum > Highest_segment_index) break; obj_link(obj-Objects,segnum); - #ifdef NETWORK +#ifdef NETWORK if ((obj->type == OBJ_PLAYER) && (Game_mode & GM_MULTI)) { int player; @@ -1599,13 +1707,18 @@ int newdemo_read_frame_information() multi_player_textures[player][5] = ObjBitmaps[ObjBitmapPtrs[First_multi_bitmap_num+(player)*2+1]]; obj->rtype.pobj_info.alt_textures = player+1; } - #endif +#endif } break; case ND_EVENT_SOUND: nd_read_int(&soundno); if (nd_bad_read) {done = -1; break; } + if (rewrite) + { + nd_write_int(soundno); + break; + } if (Newdemo_vcr_state == ND_STATE_PLAYBACK) digi_play_sample( soundno, F1_0 ); break; @@ -1615,6 +1728,13 @@ int newdemo_read_frame_information() nd_read_int(&angle); nd_read_int(&volume); if (nd_bad_read) { done = -1; break; } + if (rewrite) + { + nd_write_int(soundno); + nd_write_int(angle); + nd_write_int(volume); + break; + } if (Newdemo_vcr_state == ND_STATE_PLAYBACK) digi_play_sample_3d( soundno, angle, volume, 0 ); break; @@ -1624,10 +1744,60 @@ int newdemo_read_frame_information() nd_read_int(&angle); nd_read_int(&volume); if (nd_bad_read) { done = -1; break; } + if (rewrite) + { + nd_write_int(soundno); + nd_write_int(angle); + nd_write_int(volume); + break; + } if (Newdemo_vcr_state == ND_STATE_PLAYBACK) digi_play_sample_3d( soundno, angle, volume, 1 ); break; + case ND_EVENT_LINK_SOUND_TO_OBJ: + { + int soundno, objnum, max_volume, max_distance, loop_start, loop_end; + int signature; + nd_read_int( &soundno ); + nd_read_int( &signature ); + nd_read_int( &max_volume ); + nd_read_int( &max_distance ); + nd_read_int( &loop_start ); + nd_read_int( &loop_end ); + if (rewrite) + { + nd_write_int( soundno ); + nd_write_int( signature ); + nd_write_int( max_volume ); + nd_write_int( max_distance ); + nd_write_int( loop_start ); + nd_write_int( loop_end ); + break; + } + objnum = newdemo_find_object( signature ); + if ( objnum > -1 && Newdemo_vcr_state == ND_STATE_PLAYBACK) { // @mk, 2/22/96, John told me to. + digi_link_sound_to_object3( soundno, objnum, 1, max_volume, max_distance, loop_start, loop_end ); + } + } + break; + + case ND_EVENT_KILL_SOUND_TO_OBJ: + { + int objnum, signature; + nd_read_int( &signature ); + if (rewrite) + { + nd_write_int( signature ); + break; + } + objnum = newdemo_find_object( signature ); + if ( objnum > -1 && Newdemo_vcr_state == ND_STATE_PLAYBACK) { // @mk, 2/22/96, John told me to. + digi_kill_sound_linked_to_object(objnum); + } + } + break; + case ND_EVENT_WALL_HIT_PROCESS: { int player, segnum; fix damage; @@ -1637,6 +1807,14 @@ int newdemo_read_frame_information() nd_read_fix(&damage); nd_read_int(&player); if (nd_bad_read) { done = -1; break; } + if (rewrite) + { + nd_write_int(segnum); + nd_write_int(side); + nd_write_fix(damage); + nd_write_int(player); + break; + } if (Newdemo_vcr_state != ND_STATE_PAUSED) wall_hit_process(&Segments[segnum], side, damage, player, &(Objects[0]) ); break; @@ -1647,6 +1825,13 @@ int newdemo_read_frame_information() nd_read_int(&side); nd_read_int(&objnum); if (nd_bad_read) { done = -1; break; } + if (rewrite) + { + nd_write_int(segnum); + nd_write_int(side); + nd_write_int(objnum); + break; + } if (Newdemo_vcr_state != ND_STATE_PAUSED) check_trigger(&Segments[segnum], side, objnum); break; @@ -1656,6 +1841,11 @@ int newdemo_read_frame_information() nd_read_int(&hostage_number); if (nd_bad_read) { done = -1; break; } + if (rewrite) + { + nd_write_int(hostage_number); + break; + } if (Newdemo_vcr_state != ND_STATE_PAUSED) hostage_rescue( hostage_number ); break; @@ -1675,9 +1865,14 @@ int newdemo_read_frame_information() break; obj = &Objects[objnum]; nd_read_object(obj); + if (nd_bad_read) { done = -1; break; } + if (rewrite) + { + nd_write_object(obj); + break; + } obj->render_type = RT_POLYOBJ; if (Newdemo_vcr_state != ND_STATE_PAUSED) { - if (nd_bad_read) { done = -1; break; } if (Newdemo_vcr_state != ND_STATE_PAUSED) { segnum = obj->segnum; obj->next = obj->prev = obj->segnum = -1; @@ -1691,6 +1886,12 @@ int newdemo_read_frame_information() nd_read_int(&segnum); nd_read_int(&side); if (nd_bad_read) {done = -1; break; } + if (rewrite) + { + nd_write_int(segnum); + nd_write_int(side); + break; + } if (Newdemo_vcr_state != ND_STATE_PAUSED) wall_toggle(&Segments[segnum], side); break; @@ -1699,6 +1900,11 @@ int newdemo_read_frame_information() nd_read_int(&Fuelcen_seconds_left); Control_center_destroyed = 1; if (nd_bad_read) { done = -1; break; } + if (rewrite) + { + nd_write_int(Fuelcen_seconds_left); + break; + } if (!Newdemo_cntrlcen_destroyed) { newdemo_pop_ctrlcen_triggers(); Newdemo_cntrlcen_destroyed = 1; @@ -1711,6 +1917,11 @@ int newdemo_read_frame_information() nd_read_string(&(hud_msg[0])); if (nd_bad_read) { done = -1; break; } + if (rewrite) + { + nd_write_string(&(hud_msg[0])); + break; + } #if 0 // adb: would cause noise for non-D1X... if (hud_msg[0] == '\x01') class = ((unsigned char)hud_msg[1]) | @@ -1730,51 +1941,77 @@ int newdemo_read_frame_information() nd_read_short(&g); nd_read_short(&b); if (nd_bad_read) { done = -1; break; } + if (rewrite) + { + nd_write_short(r); + nd_write_short(g); + nd_write_short(b); + break; + } PALETTE_FLASH_SET(r,g,b); break; } case ND_EVENT_PLAYER_ENERGY: { ubyte energy; -#ifndef SHAREWARE ubyte old_energy; - nd_read_byte((sbyte *)&old_energy); -#endif - nd_read_byte((sbyte *)&energy); - if (nd_bad_read) {done = -1; break; } -#ifdef SHAREWARE - Players[Player_num].energy = i2f(energy); -#else - if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { - Players[Player_num].energy = i2f(energy); - } else if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { - if (old_energy != 255) - Players[Player_num].energy = i2f(old_energy); + if (!shareware) + { + nd_read_byte((sbyte *)&old_energy); + if (rewrite) + nd_write_byte(old_energy); + } + nd_read_byte((sbyte *)&energy); + + if (nd_bad_read) {done = -1; break; } + if (rewrite) + { + nd_write_byte(energy); + break; + } + if (shareware) + Players[Player_num].energy = i2f(energy); + else + { + if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { + Players[Player_num].energy = i2f(energy); + } else if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { + if (old_energy != 255) + Players[Player_num].energy = i2f(old_energy); + } } -#endif break; } case ND_EVENT_PLAYER_SHIELD: { ubyte shield; -#ifndef SHAREWARE ubyte old_shield; - nd_read_byte((sbyte *)&old_shield); -#endif + if (!shareware) + { + nd_read_byte((sbyte *)&old_shield); + if (rewrite) + nd_write_byte(old_shield); + } nd_read_byte((sbyte *)&shield); if (nd_bad_read) {done = -1; break; } -#ifdef SHAREWARE - Players[Player_num].shields = i2f(shield); -#else - if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { - Players[Player_num].shields = i2f(shield); - } else if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { - if (old_shield != 255) - Players[Player_num].shields = i2f(old_shield); + if (rewrite) + { + nd_write_byte(shield); + break; + } + if (shareware) + Players[Player_num].shields = i2f(shield); + else + { + if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { + Players[Player_num].shields = i2f(shield); + } else if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { + if (old_shield != 255) + Players[Player_num].shields = i2f(old_shield); + } } -#endif break; } @@ -1783,18 +2020,21 @@ int newdemo_read_frame_information() nd_read_int((int *)&(Players[Player_num].flags)); if (nd_bad_read) {done = -1; break; } - + if (rewrite) + { + nd_write_int(Players[Player_num].flags); + break; + } + oflags = Players[Player_num].flags >> 16; Players[Player_num].flags &= 0xffff; - if (((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) && (oflags != 0xffff)) { + if ((Newdemo_vcr_state == ND_STATE_REWINDING) || ((Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD) && (oflags != 0xffff)) ) { if (!(oflags & PLAYER_FLAGS_CLOAKED) && (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED)) { Players[Player_num].cloak_time = 0; - Newdemo_players_cloaked &= ~(1 << Player_num); } if ((oflags & PLAYER_FLAGS_CLOAKED) && !(Players[Player_num].flags & PLAYER_FLAGS_CLOAKED)) { Players[Player_num].cloak_time = GameTime - (CLOAK_TIME_MAX / 2); - Newdemo_players_cloaked |= (1 << Player_num); } if (!(oflags & PLAYER_FLAGS_INVULNERABLE) && (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE)) Players[Player_num].invulnerable_time = 0; @@ -1804,28 +2044,33 @@ int newdemo_read_frame_information() } else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { if (!(oflags & PLAYER_FLAGS_CLOAKED) && (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED)) { Players[Player_num].cloak_time = GameTime - (CLOAK_TIME_MAX / 2); - Newdemo_players_cloaked |= (1 << Player_num); } if ((oflags & PLAYER_FLAGS_CLOAKED) && !(Players[Player_num].flags & PLAYER_FLAGS_CLOAKED)) { Players[Player_num].cloak_time = 0; - Newdemo_players_cloaked &= ~(1 << Player_num); } if (!(oflags & PLAYER_FLAGS_INVULNERABLE) && (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE)) Players[Player_num].invulnerable_time = GameTime - (INVULNERABLE_TIME_MAX / 2); if ((oflags & PLAYER_FLAGS_INVULNERABLE) && !(Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE)) Players[Player_num].invulnerable_time = 0; } - update_laser_weapon_info(); // in case of quad laser change + update_laser_weapon_info(); // in case of quad laser change break; } -#ifdef SHAREWARE - case ND_EVENT_PLAYER_WEAPON: { - sbyte weapon_type, weapon_num; - - nd_read_byte(&weapon_type); - nd_read_byte(&weapon_num); + case ND_EVENT_PLAYER_WEAPON: + if (shareware) + { + ubyte weapon_type, weapon_num; + nd_read_byte((sbyte *)&weapon_type); + nd_read_byte((sbyte *)&weapon_num); + if (rewrite) + { + nd_write_byte(weapon_type); + nd_write_byte(weapon_num); + break; + } + if (weapon_type == 0) Primary_weapon = (int)weapon_num; else @@ -1833,14 +2078,21 @@ int newdemo_read_frame_information() break; } -#else - case ND_EVENT_PLAYER_WEAPON: { - sbyte weapon_type, weapon_num; - sbyte old_weapon; + else + { + ubyte weapon_type, weapon_num; + ubyte old_weapon; - nd_read_byte(&weapon_type); - nd_read_byte(&weapon_num); - nd_read_byte(&old_weapon); + nd_read_byte((sbyte *)&weapon_type); + nd_read_byte((sbyte *)&weapon_num); + nd_read_byte((sbyte *)&old_weapon); + if (rewrite) + { + nd_write_byte(weapon_type); + nd_write_byte(weapon_num); + nd_write_byte(old_weapon); + break; + } if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { if (weapon_type == 0) Primary_weapon = (int)weapon_num; @@ -1854,8 +2106,6 @@ int newdemo_read_frame_information() } break; } -#endif - case ND_EVENT_EFFECT_BLOWUP: { short segnum; @@ -1865,6 +2115,13 @@ int newdemo_read_frame_information() nd_read_short(&segnum); nd_read_byte(&side); nd_read_vector(&pnt); + if (rewrite) + { + nd_write_short(segnum); + nd_write_byte(side); + nd_write_vector(&pnt); + break; + } if (Newdemo_vcr_state != ND_STATE_PAUSED) check_effect_blowup(&(Segments[segnum]), side, &pnt); break; @@ -1874,6 +2131,11 @@ int newdemo_read_frame_information() short distance; nd_read_short(&distance); + if (rewrite) + { + nd_write_short(distance); + break; + } Players[Player_num].homing_object_dist = i2f((int)(distance << 16)); break; } @@ -1893,7 +2155,7 @@ int newdemo_read_frame_information() select_cockpit(CM_REAR_VIEW); Rear_view=1; } else if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { - if (saved_rearview_cockpit == CM_REAR_VIEW) // hack to be sure we get a good cockpit on restore + if (saved_rearview_cockpit == CM_REAR_VIEW) // hack to be sure we get a good cockpit on restore saved_rearview_cockpit = CM_FULL_COCKPIT; select_cockpit(saved_rearview_cockpit); Rear_view=0; @@ -1916,7 +2178,7 @@ int newdemo_read_frame_information() select_cockpit(CM_REAR_VIEW); Rear_view=1; } else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { - if (saved_rearview_cockpit == CM_REAR_VIEW) // hack to be sure we get a good cockpit on restore + if (saved_rearview_cockpit == CM_REAR_VIEW) // hack to be sure we get a good cockpit on restore saved_rearview_cockpit = CM_FULL_COCKPIT; select_cockpit(saved_rearview_cockpit); Rear_view=0; @@ -1924,29 +2186,47 @@ int newdemo_read_frame_information() break; - case ND_EVENT_WALL_SET_TMAP_NUM1: { + case ND_EVENT_WALL_SET_TMAP_NUM1: { short seg, cseg, tmap; - ubyte side,cside; + sbyte side,cside; nd_read_short(&seg); - nd_read_byte((sbyte *)&side); + nd_read_byte(&side); nd_read_short(&cseg); - nd_read_byte((sbyte *)&cside); + nd_read_byte(&cside); nd_read_short( &tmap ); + if (rewrite) + { + nd_write_short(seg); + nd_write_byte(side); + nd_write_short(cseg); + nd_write_byte(cside); + nd_write_short(tmap); + break; + } if ((Newdemo_vcr_state != ND_STATE_PAUSED) && (Newdemo_vcr_state != ND_STATE_REWINDING) && (Newdemo_vcr_state != ND_STATE_ONEFRAMEBACKWARD)) Segments[seg].sides[side].tmap_num = Segments[cseg].sides[cside].tmap_num = tmap; break; } - case ND_EVENT_WALL_SET_TMAP_NUM2: { + case ND_EVENT_WALL_SET_TMAP_NUM2: { short seg, cseg, tmap; - ubyte side,cside; + sbyte side,cside; nd_read_short(&seg); - nd_read_byte((sbyte *)&side); + nd_read_byte(&side); nd_read_short(&cseg); - nd_read_byte((sbyte *)&cside); + nd_read_byte(&cside); nd_read_short( &tmap ); + if (rewrite) + { + nd_write_short(seg); + nd_write_byte(side); + nd_write_short(cseg); + nd_write_byte(cside); + nd_write_short(tmap); + break; + } if ((Newdemo_vcr_state != ND_STATE_PAUSED) && (Newdemo_vcr_state != ND_STATE_REWINDING) && (Newdemo_vcr_state != ND_STATE_ONEFRAMEBACKWARD)) { Assert(tmap!=0 && Segments[seg].sides[side].tmap_num2!=0); Segments[seg].sides[side].tmap_num2 = Segments[cseg].sides[cside].tmap_num2 = tmap; @@ -1958,14 +2238,17 @@ int newdemo_read_frame_information() sbyte pnum; nd_read_byte(&pnum); + if (rewrite) + { + nd_write_byte(pnum); + break; + } if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { Players[pnum].flags &= ~PLAYER_FLAGS_CLOAKED; Players[pnum].cloak_time = 0; - Newdemo_players_cloaked &= ~(1 << pnum); } else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { Players[pnum].flags |= PLAYER_FLAGS_CLOAKED; Players[pnum].cloak_time = GameTime - (CLOAK_TIME_MAX / 2); - Newdemo_players_cloaked |= (1 << pnum); } break; } @@ -1974,24 +2257,31 @@ int newdemo_read_frame_information() sbyte pnum; nd_read_byte(&pnum); - + if (rewrite) + { + nd_write_byte(pnum); + break; + } + if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { Players[pnum].flags |= PLAYER_FLAGS_CLOAKED; Players[pnum].cloak_time = GameTime - (CLOAK_TIME_MAX / 2); - Newdemo_players_cloaked |= (1 << pnum); } else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { Players[pnum].flags &= ~PLAYER_FLAGS_CLOAKED; Players[pnum].cloak_time = 0; - Newdemo_players_cloaked &= ~(1 << pnum); } break; } -#ifndef SHAREWARE case ND_EVENT_MULTI_DEATH: { sbyte pnum; nd_read_byte(&pnum); + if (rewrite) + { + nd_write_byte(pnum); + break; + } if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) Players[pnum].net_killed_total--; else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) @@ -1999,25 +2289,31 @@ int newdemo_read_frame_information() break; } -#ifdef NETWORK +#ifdef NETWORK case ND_EVENT_MULTI_KILL: { sbyte pnum, kill; nd_read_byte(&pnum); nd_read_byte(&kill); + if (rewrite) + { + nd_write_byte(pnum); + nd_write_byte(kill); + break; + } if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { Players[pnum].net_kills_total -= kill; - if (Game_mode & GM_TEAM) - team_kills[get_team(pnum)] -= kill; - } else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { + if (Game_mode & GM_TEAM) + team_kills[get_team(pnum)] -= kill; + } else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) { Players[pnum].net_kills_total += kill; - if (Game_mode & GM_TEAM) - team_kills[get_team(pnum)] += kill; + if (Game_mode & GM_TEAM) + team_kills[get_team(pnum)] += kill; } multi_sort_kill_list(); break; } - + case ND_EVENT_MULTI_CONNECT: { sbyte pnum, new_player; int killed_total, kills_total; @@ -2031,6 +2327,18 @@ int newdemo_read_frame_information() nd_read_int(&kills_total); } nd_read_string(new_callsign); + if (rewrite) + { + nd_write_byte(pnum); + nd_write_byte(new_player); + if (!new_player) { + nd_write_string(old_callsign); + nd_write_int(killed_total); + nd_write_int(kills_total); + } + nd_write_string(new_callsign); + break; + } if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { Players[pnum].connected = 0; if (!new_player) { @@ -2055,6 +2363,11 @@ int newdemo_read_frame_information() sbyte pnum; nd_read_byte(&pnum); + if (rewrite) + { + nd_write_byte(pnum); + break; + } if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) Players[pnum].connected = 0; else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) @@ -2066,6 +2379,11 @@ int newdemo_read_frame_information() sbyte pnum; nd_read_byte(&pnum); + if (rewrite) + { + nd_write_byte(pnum); + break; + } if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) Players[pnum].connected = 1; else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) @@ -2079,6 +2397,12 @@ int newdemo_read_frame_information() nd_read_byte(&pnum); nd_read_int(&score); + if (rewrite) + { + nd_write_byte(pnum); + nd_write_int(score); + break; + } if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) Players[pnum].score -= score; else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) @@ -2086,12 +2410,17 @@ int newdemo_read_frame_information() multi_sort_kill_list(); break; } -#endif +#endif // NETWORK case ND_EVENT_PLAYER_SCORE: { int score; nd_read_int(&score); + if (rewrite) + { + nd_write_int(score); + break; + } if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) Players[Player_num].score -= score; else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) @@ -2101,11 +2430,17 @@ int newdemo_read_frame_information() case ND_EVENT_PRIMARY_AMMO: { - short old_ammo, new_ammo; - - nd_read_short(&old_ammo); - nd_read_short(&new_ammo); + unsigned short old_ammo, new_ammo; + nd_read_short((short *)&old_ammo); + nd_read_short((short *)&new_ammo); + if (rewrite) + { + nd_write_short(old_ammo); + nd_write_short(new_ammo); + break; + } + if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) Players[Player_num].primary_ammo[Primary_weapon] = old_ammo; else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) @@ -2118,7 +2453,13 @@ int newdemo_read_frame_information() nd_read_short(&old_ammo); nd_read_short(&new_ammo); - + if (rewrite) + { + nd_write_short(old_ammo); + nd_write_short(new_ammo); + break; + } + if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) Players[Player_num].secondary_ammo[Secondary_weapon] = old_ammo; else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) @@ -2132,6 +2473,12 @@ int newdemo_read_frame_information() nd_read_short(&segnum); nd_read_byte(&side); + if (rewrite) + { + nd_write_short(segnum); + nd_write_byte(side); + break; + } if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { int anim_num; int cside; @@ -2142,9 +2489,9 @@ int newdemo_read_frame_information() cside = find_connect_side(segp, csegp); anim_num = Walls[segp->sides[side].wall_num].clip_num; - if (WallAnims[anim_num].flags & WCF_TMAP1) { + if (WallAnims[anim_num].flags & WCF_TMAP1) { segp->sides[side].tmap_num = csegp->sides[cside].tmap_num = WallAnims[anim_num].frames[0]; - } else { + } else { segp->sides[side].tmap_num2 = csegp->sides[cside].tmap_num2 = WallAnims[anim_num].frames[0]; } } @@ -2156,6 +2503,12 @@ int newdemo_read_frame_information() nd_read_byte(&old_level); nd_read_byte(&new_level); + if (rewrite) + { + nd_write_byte(old_level); + nd_write_byte(new_level); + break; + } if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { Players[Player_num].laser_level = old_level; update_laser_weapon_info(); @@ -2166,13 +2519,17 @@ int newdemo_read_frame_information() break; } -#endif - - case ND_EVENT_NEW_LEVEL: { + case ND_EVENT_NEW_LEVEL: { sbyte new_level, old_level, loaded_level; - + nd_read_byte (&new_level); nd_read_byte (&old_level); + if (rewrite) + { + nd_write_byte (new_level); + nd_write_byte (old_level); + break; + } if (Newdemo_vcr_state == ND_STATE_PAUSED) break; @@ -2209,47 +2566,19 @@ int newdemo_read_frame_information() piggy_load_level_data(); Newdemo_cntrlcen_destroyed = 0; - reset_palette_add(); // get palette back to normal + reset_palette_add(); // get palette back to normal start_time(); break; } case ND_EVENT_EOF: { done=-1; - PHYSFS_seek(infile, PHYSFS_tell(infile) - 1); // get back to the EOF marker + PHYSFS_seek(infile, PHYSFS_tell(infile) - 1); // get back to the EOF marker Newdemo_at_eof = 1; NewdemoFrameCount++; break; } - case ND_EVENT_LINK_SOUND_TO_OBJ: - { - int soundno, objnum, max_volume, max_distance, loop_start, loop_end; - int signature; - nd_read_int( &soundno ); - nd_read_int( &signature ); - nd_read_int( &max_volume ); - nd_read_int( &max_distance ); - nd_read_int( &loop_start ); - nd_read_int( &loop_end ); - objnum = newdemo_find_object( signature ); - if ( objnum > -1 && Newdemo_vcr_state == ND_STATE_PLAYBACK) { // @mk, 2/22/96, John told me to. - digi_link_sound_to_object3( soundno, objnum, 1, max_volume, max_distance, loop_start, loop_end ); - } - } - break; - - case ND_EVENT_KILL_SOUND_TO_OBJ: - { - int objnum, signature; - nd_read_int( &signature ); - objnum = newdemo_find_object( signature ); - if ( objnum > -1 && Newdemo_vcr_state == ND_STATE_PLAYBACK) { // @mk, 2/22/96, John told me to. - digi_kill_sound_linked_to_object(objnum); - } - } - break; - default: Int3(); } @@ -2267,154 +2596,148 @@ int newdemo_read_frame_information() void newdemo_goto_beginning() { -// if (NewdemoFrameCount == 0) -// return; + //if (NewdemoFrameCount == 0) + // return; PHYSFS_seek(infile, 0); Newdemo_vcr_state = ND_STATE_PLAYBACK; if (newdemo_read_demo_start(0)) newdemo_stop_playback(); - if (newdemo_read_frame_information() == -1) + if (newdemo_read_frame_information(0) == -1) newdemo_stop_playback(); - if (newdemo_read_frame_information() == -1) + if (newdemo_read_frame_information(0) == -1) newdemo_stop_playback(); Newdemo_vcr_state = ND_STATE_PAUSED; Newdemo_at_eof = 0; } -#ifdef SHAREWARE -void newdemo_goto_end() -{ - short frame_length=0; - sbyte level=0; - int i=0; - - cfseek(infile, -2, SEEK_END); - nd_read_byte(&level); - - if ((level < Last_secret_level) || (level > Last_level)) { - newmenu_item m[3]; - - m[ 0].type = NM_TYPE_TEXT; m[ 0].text = TXT_CANT_PLAYBACK; - m[ 1].type = NM_TYPE_TEXT; m[ 1].text = TXT_LEVEL_CANT_LOAD; - m[ 2].type = NM_TYPE_TEXT; m[ 2].text = TXT_DEMO_OLD_CORRUPT; - newmenu_do( NULL, NULL, sizeof(m)/sizeof(*m), m, NULL ); - newdemo_stop_playback(); - return; - } - - if (level != Current_level_num) { - LoadLevel(level); - piggy_load_level_data(); - } - if (Game_mode & GM_MULTI) { - cfseek(infile, -10, SEEK_END); - nd_read_byte(&Newdemo_players_cloaked); - for (i = 0; i < MAX_PLAYERS; i++) { - if ((1 << i) & Newdemo_players_cloaked) - Players[i].flags |= PLAYER_FLAGS_CLOAKED; - Players[i].cloak_time = GameTime - (CLOAK_TIME_MAX / 2); - } - } - cfseek(infile, -12, SEEK_END); - nd_read_short(&frame_length); - cfseek(infile, -frame_length, SEEK_CUR); - nd_read_int(&NewdemoFrameCount); // get the frame count - NewdemoFrameCount--; - cfseek(infile, 4, SEEK_CUR); - newdemo_read_frame_information(); // then the frame information - Newdemo_vcr_state = ND_STATE_PAUSED; - return; -} -#else -void newdemo_goto_end() +void newdemo_goto_end(int to_rewrite) { short frame_length=0, byte_count=0, bshort=0; - sbyte level=0, bbyte=0, laser_level=0; + sbyte level=0, bbyte=0, laser_level=0, c=0, cloaked=0; ubyte energy=0, shield=0; int i=0, loc=0, bint=0; cfseek(infile, -2, SEEK_END); nd_read_byte(&level); - if ((level < Last_secret_level) || (level > Last_level)) { - newmenu_item m[3]; + if (!to_rewrite) + { + if ((level < Last_secret_level) || (level > Last_level)) { + newmenu_item m[3]; - m[ 0].type = NM_TYPE_TEXT; m[ 0].text = TXT_CANT_PLAYBACK; - m[ 1].type = NM_TYPE_TEXT; m[ 1].text = TXT_LEVEL_CANT_LOAD; - m[ 2].type = NM_TYPE_TEXT; m[ 2].text = TXT_DEMO_OLD_CORRUPT; - newmenu_do( NULL, NULL, sizeof(m)/sizeof(*m), m, NULL ); - newdemo_stop_playback(); - return; + m[ 0].type = NM_TYPE_TEXT; m[ 0].text = TXT_CANT_PLAYBACK; + m[ 1].type = NM_TYPE_TEXT; m[ 1].text = TXT_LEVEL_CANT_LOAD; + m[ 2].type = NM_TYPE_TEXT; m[ 2].text = TXT_DEMO_OLD_CORRUPT; + newmenu_do( NULL, NULL, sizeof(m)/sizeof(*m), m, NULL ); + newdemo_stop_playback(); + return; + } + if (level != Current_level_num) + { + LoadLevel(level); + piggy_load_level_data(); + } } - - if (level != Current_level_num) { - LoadLevel(level); - piggy_load_level_data(); - } - cfseek(infile, -4, SEEK_END); - nd_read_short(&byte_count); - cfseek(infile, -2 - byte_count, SEEK_CUR); - - nd_read_short(&frame_length); - loc = cftell(infile); - if (Game_mode & GM_MULTI) - nd_read_byte(&Newdemo_players_cloaked); else - nd_read_byte(&bbyte); - nd_read_byte(&bbyte); - nd_read_short(&bshort); - nd_read_int(&bint); - - nd_read_byte((sbyte *)&energy); - nd_read_byte((sbyte *)&shield); - Players[Player_num].energy = i2f(energy); - Players[Player_num].shields = i2f(shield); - nd_read_int((int *)&(Players[Player_num].flags)); - if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) { - Players[Player_num].cloak_time = GameTime - (CLOAK_TIME_MAX / 2); - Newdemo_players_cloaked |= (1 << Player_num); - } - if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) - Players[Player_num].invulnerable_time = GameTime - (INVULNERABLE_TIME_MAX / 2); - nd_read_byte((sbyte *)&Primary_weapon); - nd_read_byte((sbyte *)&Secondary_weapon); - for (i = 0; i < MAX_PRIMARY_WEAPONS; i++) - nd_read_short((short *)&(Players[Player_num].primary_ammo[i])); - for (i = 0; i < MAX_SECONDARY_WEAPONS; i++) - nd_read_short((short *)&(Players[Player_num].secondary_ammo[i])); - nd_read_byte(&laser_level); - if (laser_level != Players[Player_num].laser_level) { - Players[Player_num].laser_level = laser_level; - update_laser_weapon_info(); - } + Current_level_num = level; - if (Game_mode & GM_MULTI) { - nd_read_byte((sbyte *)&N_players); - for (i = 0; i < N_players; i++) { - nd_read_string(Players[i].callsign); - nd_read_byte(&(Players[i].connected)); - if (Game_mode & GM_MULTI_COOP) { - nd_read_int(&(Players[i].score)); - } else { - nd_read_short((short *)&(Players[i].net_killed_total)); - nd_read_short((short *)&(Players[i].net_kills_total)); + if (shareware) + { + if (Game_mode & GM_MULTI) { + cfseek(infile, -10, SEEK_END); + nd_read_byte(&cloaked); + for (i = 0; i < MAX_PLAYERS; i++) { + if ((1 << i) & cloaked) + Players[i].flags |= PLAYER_FLAGS_CLOAKED; + Players[i].cloak_time = GameTime - (CLOAK_TIME_MAX / 2); } } - } else { - nd_read_int(&(Players[Player_num].score)); + + if (to_rewrite) + return; + + cfseek(infile, -12, SEEK_END); + nd_read_short(&frame_length); + } + else + { + cfseek(infile, -4, SEEK_END); + nd_read_short(&byte_count); + cfseek(infile, -2 - byte_count, SEEK_CUR); + + nd_read_short(&frame_length); + loc = cftell(infile); + if (Game_mode & GM_MULTI) + { + nd_read_byte(&cloaked); + for (i = 0; i < MAX_PLAYERS; i++) + if (cloaked & (1 << i)) + Players[i].flags |= PLAYER_FLAGS_CLOAKED; + } + else + nd_read_byte(&bbyte); + nd_read_byte(&bbyte); + nd_read_short(&bshort); + nd_read_int(&bint); + + nd_read_byte((sbyte *)&energy); + nd_read_byte((sbyte *)&shield); + Players[Player_num].energy = i2f(energy); + Players[Player_num].shields = i2f(shield); + nd_read_int((int *)&(Players[Player_num].flags)); + if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) { + Players[Player_num].cloak_time = GameTime - (CLOAK_TIME_MAX / 2); + } + if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) + Players[Player_num].invulnerable_time = GameTime - (INVULNERABLE_TIME_MAX / 2); + nd_read_byte((sbyte *)&Primary_weapon); + nd_read_byte((sbyte *)&Secondary_weapon); + for (i = 0; i < MAX_PRIMARY_WEAPONS; i++) + nd_read_short((short *)&(Players[Player_num].primary_ammo[i])); + for (i = 0; i < MAX_SECONDARY_WEAPONS; i++) + nd_read_short((short *)&(Players[Player_num].secondary_ammo[i])); + nd_read_byte(&laser_level); + if (laser_level != Players[Player_num].laser_level) { + Players[Player_num].laser_level = laser_level; + if (!to_rewrite) + update_laser_weapon_info(); + } + + if (Game_mode & GM_MULTI) { + nd_read_byte(&c); + N_players = (int)c; + // see newdemo_read_start_demo for explanation of + // why this is commented out + // nd_read_byte((sbyte *)&N_players); + for (i = 0; i < N_players; i++) { + nd_read_string(Players[i].callsign); + nd_read_byte(&(Players[i].connected)); + if (Game_mode & GM_MULTI_COOP) { + nd_read_int(&(Players[i].score)); + } else { + nd_read_short((short *)&(Players[i].net_killed_total)); + nd_read_short((short *)&(Players[i].net_kills_total)); + } + } + } else { + nd_read_int(&(Players[Player_num].score)); + } + + if (to_rewrite) + return; + + cfseek(infile, loc, SEEK_SET); } - cfseek(infile, loc, SEEK_SET); cfseek(infile, -frame_length, SEEK_CUR); - nd_read_int(&NewdemoFrameCount); // get the frame count + nd_read_int(&NewdemoFrameCount); // get the frame count NewdemoFrameCount--; cfseek(infile, 4, SEEK_CUR); Newdemo_vcr_state = ND_STATE_PLAYBACK; - newdemo_read_frame_information(); // then the frame information + newdemo_read_frame_information(0); // then the frame information Newdemo_vcr_state = ND_STATE_PAUSED; return; } -#endif void newdemo_back_frames(int frames) { @@ -2424,10 +2747,10 @@ void newdemo_back_frames(int frames) for (i = 0; i < frames; i++) { PHYSFS_seek(infile, PHYSFS_tell(infile) - 10); - nd_read_short(&last_frame_length); + nd_read_short(&last_frame_length); PHYSFS_seek(infile, PHYSFS_tell(infile) + 8 - last_frame_length); - if (!Newdemo_at_eof && newdemo_read_frame_information() == -1) { + if (!Newdemo_at_eof && newdemo_read_frame_information(0) == -1) { newdemo_stop_playback(); return; } @@ -2435,7 +2758,7 @@ void newdemo_back_frames(int frames) Newdemo_at_eof = 0; PHYSFS_seek(infile, PHYSFS_tell(infile) - 10); - nd_read_short(&last_frame_length); + nd_read_short(&last_frame_length); PHYSFS_seek(infile, PHYSFS_tell(infile) + 8 - last_frame_length); } @@ -2471,7 +2794,7 @@ void interpolate_frame(fix d_play, fix d_recorded) memcpy(&(cur_objs[i]), &(Objects[i]), sizeof(object)); Newdemo_vcr_state = ND_STATE_PAUSED; - if (newdemo_read_frame_information() == -1) { + if (newdemo_read_frame_information(0) == -1) { d_free(cur_objs); newdemo_stop_playback(); return; @@ -2480,24 +2803,24 @@ void interpolate_frame(fix d_play, fix d_recorded) for (i = 0; i <= num_cur_objs; i++) { for (j = 0; j <= Highest_object_index; j++) { if (cur_objs[i].signature == Objects[j].signature) { - ubyte render_type = cur_objs[i].render_type; - fix delta_x, delta_y, delta_z; + sbyte render_type = cur_objs[i].render_type; + fix delta_x, delta_y, delta_z; -// Extract the angles from the object orientation matrix. -// Some of this code taken from ai_turn_towards_vector -// Don't do the interpolation on certain render types which don't use an orientation matrix + // Extract the angles from the object orientation matrix. + // Some of this code taken from ai_turn_towards_vector + // Don't do the interpolation on certain render types which don't use an orientation matrix if (!((render_type == RT_LASER) || (render_type == RT_FIREBALL) || (render_type == RT_POWERUP))) { - vms_vector fvec1, fvec2, rvec1, rvec2; - fix mag1; - - fvec1 = cur_objs[i].orient.fvec; - vm_vec_scale(&fvec1, F1_0-factor); - fvec2 = Objects[j].orient.fvec; - vm_vec_scale(&fvec2, factor); - vm_vec_add2(&fvec1, &fvec2); - mag1 = vm_vec_normalize_quick(&fvec1); + vms_vector fvec1, fvec2, rvec1, rvec2; + fix mag1; + + fvec1 = cur_objs[i].orient.fvec; + vm_vec_scale(&fvec1, F1_0-factor); + fvec2 = Objects[j].orient.fvec; + vm_vec_scale(&fvec2, factor); + vm_vec_add2(&fvec1, &fvec2); + mag1 = vm_vec_normalize_quick(&fvec1); if (mag1 > F1_0/256) { rvec1 = cur_objs[i].orient.rvec; vm_vec_scale(&rvec1, F1_0-factor); @@ -2509,8 +2832,8 @@ void interpolate_frame(fix d_play, fix d_recorded) } } -// Interpolate the object position. This is just straight linear -// interpolation. + // Interpolate the object position. This is just straight linear + // interpolation. delta_x = Objects[j].pos.x - cur_objs[i].pos.x; delta_y = Objects[j].pos.y - cur_objs[i].pos.y; @@ -2527,14 +2850,14 @@ void interpolate_frame(fix d_play, fix d_recorded) } } -// get back to original position in the demo file. Reread the current -// frame information again to reset all of the object stuff not covered -// with Highest_object_index and the object array (previously rendered -// objects, etc....) + // get back to original position in the demo file. Reread the current + // frame information again to reset all of the object stuff not covered + // with Highest_object_index and the object array (previously rendered + // objects, etc....) newdemo_back_frames(1); newdemo_back_frames(1); - if (newdemo_read_frame_information() == -1) + if (newdemo_read_frame_information(0) == -1) newdemo_stop_playback(); Newdemo_vcr_state = ND_STATE_PLAYBACK; @@ -2551,13 +2874,13 @@ void newdemo_playback_one_frame() static fix d_recorded = 0; for (i = 0; i < MAX_PLAYERS; i++) - if (Newdemo_players_cloaked & (1 << i)) + if (Players[i].flags & PLAYER_FLAGS_CLOAKED) Players[i].cloak_time = GameTime - (CLOAK_TIME_MAX / 2); if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) Players[Player_num].invulnerable_time = GameTime - (INVULNERABLE_TIME_MAX / 2); - - if (Newdemo_vcr_state == ND_STATE_PAUSED) // render a frame or not + + if (Newdemo_vcr_state == ND_STATE_PAUSED) // render a frame or not return; if (Newdemo_vcr_state == ND_STATE_PLAYBACK) @@ -2565,7 +2888,7 @@ void newdemo_playback_one_frame() Control_center_destroyed = 0; Fuelcen_seconds_left = -1; - PALETTE_FLASH_SET(0,0,0); //clear flash + PALETTE_FLASH_SET(0,0,0); //clear flash if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) { @@ -2581,11 +2904,7 @@ void newdemo_playback_one_frame() else frames_back = 1; if (Newdemo_at_eof) { -#ifdef SHAREWARE - PHYSFS_seek(infile, PHYSFS_tell(infile) - 2); -#else - PHYSFS_seek(infile, PHYSFS_tell(infile) + 11); -#endif + PHYSFS_seek(infile, PHYSFS_tell(infile) + shareware ? -2 : 11); } newdemo_back_frames(frames_back); @@ -2603,7 +2922,7 @@ void newdemo_playback_one_frame() { for (i = 0; i < 10; i++) { - if (newdemo_read_frame_information() == -1) + if (newdemo_read_frame_information(0) == -1) { if (Newdemo_at_eof) Newdemo_vcr_state = ND_STATE_PAUSED; @@ -2611,7 +2930,7 @@ void newdemo_playback_one_frame() newdemo_stop_playback(); break; } - } + } } else Newdemo_vcr_state = ND_STATE_PAUSED; @@ -2619,12 +2938,12 @@ void newdemo_playback_one_frame() else if (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD) { if (!Newdemo_at_eof) { level = Current_level_num; - if (newdemo_read_frame_information() == -1) { + if (newdemo_read_frame_information(0) == -1) { if (!Newdemo_at_eof) newdemo_stop_playback(); } if (level != Current_level_num) { - if (newdemo_read_frame_information() == -1) { + if (newdemo_read_frame_information(0) == -1) { if (!Newdemo_at_eof) newdemo_stop_playback(); } @@ -2635,13 +2954,13 @@ void newdemo_playback_one_frame() } else { -// First, uptate the total playback time to date. Then we check to see -// if we need to change the playback style to interpolate frames or -// skip frames based on where the playback time is relative to the -// recorded time. + // First, uptate the total playback time to date. Then we check to see + // if we need to change the playback style to interpolate frames or + // skip frames based on where the playback time is relative to the + // recorded time. if (NewdemoFrameCount <= 0) - nd_playback_total = nd_recorded_total; // baseline total playback time + nd_playback_total = nd_recorded_total; // baseline total playback time else nd_playback_total += FrameTime; @@ -2650,7 +2969,7 @@ void newdemo_playback_one_frame() if (nd_playback_total > nd_recorded_total) playback_style = SKIP_PLAYBACK; - //if ((nd_playback_total * INTERPOL_FACTOR) < nd_recorded_total) // no matter how we look at it: this does not make ANY sense! + //if ((nd_playback_total * INTERPOL_FACTOR) < nd_recorded_total) // no matte rhow we look at it: this does not make ANY sense! if (nd_recorded_total > 0 && nd_recorded_time > 0) { playback_style = INTERPOLATE_PLAYBACK; @@ -2660,6 +2979,7 @@ void newdemo_playback_one_frame() } } + if ((playback_style == INTERPOLATE_PLAYBACK) && Newdemo_do_interpolate) { fix d_play = 0; @@ -2680,22 +3000,22 @@ void newdemo_playback_one_frame() memcpy(&(cur_objs[i]), &(Objects[i]), sizeof(object)); level = Current_level_num; - if (newdemo_read_frame_information() == -1) { + if (newdemo_read_frame_information(0) == -1) { d_free(cur_objs); newdemo_stop_playback(); return; } if (level != Current_level_num) { d_free(cur_objs); - if (newdemo_read_frame_information() == -1) + if (newdemo_read_frame_information(0) == -1) newdemo_stop_playback(); break; } -// for each new object in the frame just read in, determine if there is -// a corresponding object that we have been interpolating. If so, then -// copy that interpolated object to the new Objects array so that the -// interpolated position and orientation can be preserved. + // for each new object in the frame just read in, determine if there is + // a corresponding object that we have been interpolating. If so, then + // copy that interpolated object to the new Objects array so that the + // interpolated position and orientation can be preserved. for (i = 0; i <= num_objs; i++) { for (j = 0; j <= Highest_object_index; j++) { @@ -2717,13 +3037,13 @@ void newdemo_playback_one_frame() return; } else { - if (newdemo_read_frame_information() == -1) { + if (newdemo_read_frame_information(0) == -1) { newdemo_stop_playback(); return; } if (playback_style == SKIP_PLAYBACK) { while (nd_playback_total > nd_recorded_total) { - if (newdemo_read_frame_information() == -1) { + if (newdemo_read_frame_information(0) == -1) { newdemo_stop_playback(); return; } @@ -2755,41 +3075,31 @@ void newdemo_start_recording() Newdemo_no_space=0; Newdemo_state = ND_STATE_RECORDING; - if (!cfexist(DEMO_DIR)) //dir doesn't exist? - PHYSFS_mkdir(DEMO_DIR); //try making directory + PHYSFS_mkdir(DEMO_DIR); //always try making directory - could only exist in read-only path outfile = PHYSFSX_openWriteBuffered(DEMO_FILENAME); if (outfile == NULL) { - nm_messagebox(NULL, 1, TXT_OK, "Cannot open demo temp file"); Newdemo_state = ND_STATE_NORMAL; + nm_messagebox(NULL, 1, TXT_OK, "Cannot open demo temp file"); } else newdemo_record_start_demo(); } -char demoname_allowed_chars[] = "azAZ09__--"; -void newdemo_stop_recording() +void newdemo_write_end() { - newmenu_item m[6]; - int l, exit; - static char filename[15] = "", *s; - static ubyte tmpcnt = 0; - ubyte cloaked = 0; - char fullname[15+FILENAME_LEN] = DEMO_DIR; -#ifndef SHAREWARE + sbyte cloaked = 0; unsigned short byte_count = 0; -#endif - - exit = 0; + int i; nd_write_byte(ND_EVENT_EOF); nd_write_short(frame_bytes_written - 1); if (Game_mode & GM_MULTI) { - for (l = 0; l < N_players; l++) { - if (Players[l].flags & PLAYER_FLAGS_CLOAKED) - cloaked |= (1 << l); + for (i = 0; i < N_players; i++) { + if (Players[i].flags & PLAYER_FLAGS_CLOAKED) + cloaked |= (1 << i); } nd_write_byte(cloaked); nd_write_byte(ND_EVENT_EOF); @@ -2798,76 +3108,91 @@ void newdemo_stop_recording() } nd_write_short(ND_EVENT_EOF); nd_write_int(ND_EVENT_EOF); - -#ifndef SHAREWARE - byte_count += 10; // from frame_bytes_written - - nd_write_byte((sbyte)(f2ir(Players[Player_num].energy))); - nd_write_byte((sbyte)(f2ir(Players[Player_num].shields))); - nd_write_int(Players[Player_num].flags); // be sure players flags are set - nd_write_byte((sbyte)Primary_weapon); - nd_write_byte((sbyte)Secondary_weapon); - byte_count += 8; - - for (l = 0; l < MAX_PRIMARY_WEAPONS; l++) - nd_write_short((short)Players[Player_num].primary_ammo[l]); - - for (l = 0; l < MAX_SECONDARY_WEAPONS; l++) - nd_write_short((short)Players[Player_num].secondary_ammo[l]); - byte_count += (sizeof(short) * (MAX_PRIMARY_WEAPONS + MAX_SECONDARY_WEAPONS)); - - nd_write_byte(Players[Player_num].laser_level); - byte_count++; - - if (Game_mode & GM_MULTI) { - nd_write_byte((sbyte)N_players); + + if (!shareware) + { + byte_count += 10; // from frame_bytes_written + + nd_write_byte((sbyte)(f2ir(Players[Player_num].energy))); + nd_write_byte((sbyte)(f2ir(Players[Player_num].shields))); + nd_write_int(Players[Player_num].flags); // be sure players flags are set + nd_write_byte((sbyte)Primary_weapon); + nd_write_byte((sbyte)Secondary_weapon); + byte_count += 8; + + for (i = 0; i < MAX_PRIMARY_WEAPONS; i++) + nd_write_short((short)Players[Player_num].primary_ammo[i]); + + for (i = 0; i < MAX_SECONDARY_WEAPONS; i++) + nd_write_short((short)Players[Player_num].secondary_ammo[i]); + byte_count += (sizeof(short) * (MAX_PRIMARY_WEAPONS + MAX_SECONDARY_WEAPONS)); + + nd_write_byte(Players[Player_num].laser_level); byte_count++; - for (l = 0; l < N_players; l++) { - nd_write_string(Players[l].callsign); - byte_count += (strlen(Players[l].callsign) + 2); - nd_write_byte(Players[l].connected); - if (Game_mode & GM_MULTI_COOP) { - nd_write_int(Players[l].score); - byte_count += 5; - } else { - nd_write_short((short)Players[l].net_killed_total); - nd_write_short((short)Players[l].net_kills_total); - byte_count += 5; + + if (Game_mode & GM_MULTI) { + nd_write_byte((sbyte)N_players); + byte_count++; + for (i = 0; i < N_players; i++) { + nd_write_string(Players[i].callsign); + byte_count += (strlen(Players[i].callsign) + 2); + nd_write_byte(Players[i].connected); + if (Game_mode & GM_MULTI_COOP) { + nd_write_int(Players[i].score); + byte_count += 5; + } else { + nd_write_short((short)Players[i].net_killed_total); + nd_write_short((short)Players[i].net_kills_total); + byte_count += 5; + } } + } else { + nd_write_int(Players[Player_num].score); + byte_count += 4; } - } else { - nd_write_int(Players[Player_num].score); - byte_count += 4; + nd_write_short(byte_count); } - nd_write_short(byte_count); -#endif - + nd_write_byte(Current_level_num); nd_write_byte(ND_EVENT_EOF); +} + +char demoname_allowed_chars[] = "azAZ09__--"; +void newdemo_stop_recording() +{ + newmenu_item m[6]; + int exit; + static char filename[15] = "", *s; + static sbyte tmpcnt = 0; + char fullname[15+FILENAME_LEN] = DEMO_DIR; + + exit = 0; + + if (!Newdemo_no_space) + newdemo_write_end(); - l = PHYSFS_tell(outfile); PHYSFS_close(outfile); outfile = NULL; Newdemo_state = ND_STATE_NORMAL; gr_palette_load( gr_palette ); if (filename[0] != '\0') { - int num, i = strlen(filename) - 1; - char newfile[15]; + int num, i = strlen(filename) - 1; + char newfile[15]; - while (isdigit(filename[i])) { - i--; - if (i == -1) - break; - } - i++; - num = atoi(&(filename[i])); - num++; - filename[i] = '\0'; - sprintf (newfile, "%s%d", filename, num); - strncpy(filename, newfile, 8); - filename[8] = '\0'; - } + while (isdigit(filename[i])) { + i--; + if (i == -1) + break; + } + i++; + num = atoi(&(filename[i])); + num++; + filename[i] = '\0'; + sprintf (newfile, "%s%d", filename, num); + strncpy(filename, newfile, 8); + filename[8] = '\0'; + } try_again: ; @@ -2887,24 +3212,24 @@ try_again: } Newmenu_allowed_chars = NULL; - if (exit == -2) { // got bumped out from network menu + if (exit == -2) { // got bumped out from network menu char save_file[7+FILENAME_LEN]; if (filename[0] != '\0') { strcpy(save_file, DEMO_DIR); strcat(save_file, filename); strcat(save_file, ".dem"); - } else + } else sprintf (save_file, "%stmp%d.dem", DEMO_DIR, tmpcnt++); remove(save_file); PHYSFSX_rename(DEMO_FILENAME, save_file); return; } - if (exit == -1) { // pressed ESC - PHYSFS_delete(DEMO_FILENAME); // might as well remove the file - return; // return without doing anything + if (exit == -1) { // pressed ESC + PHYSFS_delete(DEMO_FILENAME); // might as well remove the file + return; // return without doing anything } - + if (filename[0]==0) //null string goto try_again; @@ -3009,6 +3334,7 @@ void newdemo_start_playback(char * filename) return; } + Newdemo_state = ND_STATE_PLAYBACK; Newdemo_vcr_state = ND_STATE_PLAYBACK; Newdemo_old_cockpit = PlayerCfg.CockpitMode; @@ -3016,7 +3342,6 @@ void newdemo_start_playback(char * filename) nd_bad_read = 0; Newdemo_at_eof = 0; NewdemoFrameCount = 0; - Newdemo_players_cloaked = 0; playback_style = NORMAL_PLAYBACK; Function_mode = FMODE_GAME; HUD_clear_messages(); @@ -3026,20 +3351,91 @@ void newdemo_start_playback(char * filename) void newdemo_stop_playback() { - PHYSFS_close( infile ); + PHYSFS_close(infile); Newdemo_state = ND_STATE_NORMAL; - #ifdef NETWORK - change_playernum_to(0); //this is reality - #endif +#ifdef NETWORK + change_playernum_to(0); //this is reality +#endif strncpy(Players[Player_num].callsign, nd_save_callsign, CALLSIGN_LEN); PlayerCfg.CockpitMode = Newdemo_old_cockpit; Rear_view=0; Game_mode = GM_GAME_OVER; Function_mode = FMODE_MENU; - longjmp(LeaveGame,0); // Exit game loop + longjmp(LeaveGame,0); // Exit game loop } +int newdemo_swap_endian(char *filename) +{ + char inpath[PATH_MAX+FILENAME_LEN] = DEMO_DIR; + int complete = 0; + + if (filename) + strcat(inpath, filename); + else + return 0; + + infile = PHYSFSX_openReadBuffered(inpath); + if (infile==NULL) + goto read_error; + + Newdemo_size = PHYSFS_fileLength(infile); // should be exactly the same size + outfile = PHYSFSX_openWriteBuffered(DEMO_FILENAME); + if (outfile==NULL) + { + PHYSFS_close(infile); + goto read_error; + } + + Newdemo_num_written = 0; + nd_bad_read = 0; + swap_endian = 1; + Newdemo_at_eof = 0; + Newdemo_state = ND_STATE_NORMAL; // not doing anything special really + + if (newdemo_read_demo_start(PURPOSE_REWRITE)) { + PHYSFS_close(infile); + PHYSFS_close(outfile); + swap_endian = 0; + return 0; + } + + while (newdemo_read_frame_information(1) == 1) {} // rewrite all frames + + newdemo_goto_end(1); // get end of demo data + newdemo_write_end(); // and write it + + swap_endian = 0; + complete = Newdemo_size == Newdemo_num_written; + PHYSFS_close(infile); + PHYSFS_close(outfile); + outfile = NULL; + + if (complete) + { + char bakpath[PATH_MAX+FILENAME_LEN]; + + change_filename_extension(bakpath, inpath, DEMO_BACKUP_EXT); + PHYSFSX_rename(inpath, bakpath); + PHYSFSX_rename(DEMO_FILENAME, inpath); + } + else + PHYSFS_delete(DEMO_FILENAME); // clean up the mess + +read_error: + { + newmenu_item m[2]; + char text[32 + PATH_MAX]; + + sprintf(text, complete ? "Demo %s converted" : "Error converting demo\n%s", filename); + m[ 0].type = NM_TYPE_TEXT; m[ 0].text = text; + m[ 1].type = NM_TYPE_TEXT; m[ 1].text = Newdemo_at_eof ? "Demo may be corrupt" : (char *) PHYSFS_getLastError(); + newmenu_do( NULL, NULL, 1 + !complete, m, NULL ); + } + + return Newdemo_at_eof; +} + #ifndef NDEBUG #define BUF_SIZE 16384 @@ -3073,7 +3469,7 @@ void newdemo_strip_frames(char *outname, int bytes_to_strip) newdemo_stop_playback(); return; } - newdemo_goto_end(); + newdemo_goto_end(0); trailer_start = PHYSFS_tell(infile); PHYSFS_seek(infile, PHYSFS_tell(infile) + 11); bytes_back = 0; @@ -3124,7 +3520,7 @@ void DoJasonInterpolate (fix recorded_time) if (the_delay < f0_0) { while (JasonPlaybackTotal > nd_recorded_total) - if (newdemo_read_frame_information() == -1) + if (newdemo_read_frame_information(0) == -1) { newdemo_stop_playback(); return; diff --git a/main/newdemo.h b/main/newdemo.h index aa9c16940..bfc4b432b 100644 --- a/main/newdemo.h +++ b/main/newdemo.h @@ -1,3 +1,4 @@ +/* $Id: newdemo.h,v 1.1.1.1 2006/03/17 19:57:04 zicodxx Exp $ */ /* THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO @@ -7,15 +8,17 @@ IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ + /* * - * . + * header for demo playback system * */ + #ifndef _NEWDEMO_H #define _NEWDEMO_H @@ -29,6 +32,11 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #define ND_STATE_ONEFRAMEBACKWARD 7 #define DEMO_DIR "demos/" +#if WORDS_BIGENDIAN +#define DEMO_BACKUP_EXT "386" +#else +#define DEMO_BACKUP_EXT "ppc" +#endif // Gives state of recorder extern int Newdemo_state; @@ -56,13 +64,8 @@ extern void newdemo_record_wall_toggle(int segnum, int side ); extern void newdemo_record_control_center_destroyed(); extern void newdemo_record_hud_message(char *s); extern void newdemo_record_palette_effect(short r, short g, short b); -#ifdef SHAREWARE -extern void newdemo_record_player_energy(int); -extern void newdemo_record_player_shields(int); -#else extern void newdemo_record_player_energy(int, int); extern void newdemo_record_player_shields(int, int); -#endif extern void newdemo_record_player_flags(uint, uint); extern void newdemo_record_player_weapon(int, int); extern void newdemo_record_effect_blowup(short, int, vms_vector *); @@ -77,7 +80,6 @@ extern void newdemo_record_multi_decloak(int pnum); extern void newdemo_set_new_level(int level_num); extern void newdemo_record_restore_rearview(void); -#ifndef SHAREWARE extern void newdemo_record_multi_death(int pnum); extern void newdemo_record_multi_kill(int pnum, sbyte kill); extern void newdemo_record_multi_connect(int pnum, int new_player, char *new_callsign); @@ -88,14 +90,12 @@ extern void newdemo_record_multi_score(int pnum, int score); extern void newdemo_record_primary_ammo(int old_ammo, int new_ammo); extern void newdemo_record_secondary_ammo(int old_ammo, int new_ammo); extern void newdemo_record_door_opening(int segnum, int side); -#endif - extern void newdemo_record_laser_level(sbyte old_level, sbyte new_level); // Functions called during playback process... extern void newdemo_object_move_all(); extern void newdemo_playback_one_frame(); -extern void newdemo_goto_end(); +extern void newdemo_goto_end(int to_rewrite); extern void newdemo_goto_beginning(); // Interactive functions to control playback/record; @@ -104,9 +104,12 @@ extern void newdemo_stop_playback(); extern void newdemo_start_recording(); extern void newdemo_stop_recording(); +extern int newdemo_swap_endian(char *filename); + extern int newdemo_get_percent_done(); extern void newdemo_record_link_sound_to_object3( int soundno, short objnum, fix max_volume, fix max_distance, int loop_start, int loop_end ); extern int newdemo_find_object( int signature ); extern void newdemo_record_kill_sound_linked_to_object( int objnum ); -#endif + +#endif // _NEWDEMO_H diff --git a/main/newmenu.c b/main/newmenu.c index b2e5dffc1..0ee2c72df 100644 --- a/main/newmenu.c +++ b/main/newmenu.c @@ -7,7 +7,7 @@ IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ @@ -17,7 +17,6 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. * */ - #include #include #include @@ -29,15 +28,15 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include #endif -#include "error.h" #include "pstypes.h" +#include "error.h" #include "gr.h" #include "songs.h" #include "key.h" #include "palette.h" #include "game.h" #include "text.h" -#include "newdemo.h" +#include "menu.h" #include "newmenu.h" #include "gamefont.h" #include "iff.h" @@ -49,13 +48,13 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "multi.h" #include "endlevel.h" #include "screens.h" -#include "kconfig.h" #include "player.h" -#include "timer.h" +#include "newdemo.h" +#include "kconfig.h" #include "vers_id.h" -#include "automap.h" -#include "menu.h" +#include "timer.h" #include "playsave.h" +#include "automap.h" #include "rbaudio.h" #ifdef OGL @@ -1701,6 +1700,26 @@ ReadFileNames: } } break; + case KEY_CTRLED+KEY_C: + if (demo_mode) + { + int x = 1; + char bakname[PATH_MAX]; + + // Get backup .bak name + change_filename_extension(bakname, &filenames[citem*(FILENAME_LEN+1)]+((demo_mode && filenames[citem*(FILENAME_LEN+1)]=='$')?1:0), "bak"); + x = nm_messagebox( NULL, 2, TXT_YES, TXT_NO, "Are you sure you want to\n" + "swap the endianness of\n" + "%s? If the file is\n" + "already endian native, D1X\n" + "will likely crash. A backup\n" + "%s will be created", &filenames[citem*(FILENAME_LEN+1)]+((demo_mode && filenames[citem*(FILENAME_LEN+1)]=='$')?1:0), bakname ); + if (x) + break; + + newdemo_swap_endian(&filenames[citem*(FILENAME_LEN+1)]); + } + break; case KEY_HOME: case KEY_PAD7: citem = 0; diff --git a/main/text.c b/main/text.c index 736f7f792..3d9d9b70c 100644 --- a/main/text.c +++ b/main/text.c @@ -1,3 +1,4 @@ +/* $Id: text.c,v 1.1.1.1 2006/03/17 19:56:37 zicodxx Exp $ */ /* THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO @@ -7,25 +8,24 @@ IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ + /* * * Code for localizable text * */ - #ifdef RCS static char rcsid[] = "$Id: text.c,v 1.1.1.1 2006/03/17 19:43:44 zicodxx Exp $"; #endif -#include #include #include -//#include "cfile.h" +#include "pstypes.h" #include "cfile.h" #include "u_mem.h" #include "error.h" @@ -33,11 +33,9 @@ static char rcsid[] = "$Id: text.c,v 1.1.1.1 2006/03/17 19:43:44 zicodxx Exp $"; #include "inferno.h" #include "text.h" #include "args.h" -#include "compbit.h" char *text; - char *Text_string[N_TEXT_STRINGS]; void free_text() @@ -45,7 +43,8 @@ void free_text() //added on 9/13/98 by adb to free all text d_free(Text_string[145]); //end addition - adb - d_free(text); + d_free(Text_string[330]); + d_free(text); } // rotates a byte left one bit, preserving the bit falling off the right @@ -214,8 +213,10 @@ void load_text() if ((tfile = cfopen(filename,"rb")) == NULL) { filename="descent.txb"; - if ((ifile = cfopen(filename, "rb")) == NULL) + if ((ifile = cfopen(filename, "rb")) == NULL) { Error("Cannot open file DESCENT.TEX or DESCENT.TXB"); + return; + } have_binary = 1; len = cfilelength(ifile); @@ -276,46 +277,55 @@ void load_text() Error("Not enough strings in text file - expecting %d (or at least %d), found %d",N_TEXT_STRINGS,N_TEXT_STRINGS_SHAREWARE,i); } } - + if ( tptr ) *tptr++ = 0; - if (have_binary) { - for (p=Text_string[i]; p < tptr - 1; p++) { - encode_rotate_left(p); - *p = *p ^ BITMAP_TBL_XOR; - encode_rotate_left(p); - } - } + if (have_binary) + decode_text_line(Text_string[i]); //scan for special chars (like \n) for (p=Text_string[i];(p=strchr(p,'\\'));) { - char newchar=0;//get rid of compiler warning + char newchar; if (p[1] == 'n') newchar = '\n'; else if (p[1] == 't') newchar = '\t'; else if (p[1] == '\\') newchar = '\\'; else - Error("Unsupported key sequence <\\%c> on line %d of file <%s>",p[1],i+1,filename); + Error("Unsupported key sequence <\\%c> on line %d of file <%s>",p[1],i+1,filename); p[0] = newchar; // strcpy(p+1,p+2); MALLOC(buf,char,len+1); strcpy(buf,p+2); strcpy(p+1,buf); - p++; d_free(buf); + p++; } switch(i) { - case 145: - Text_string[i]=(char *) d_malloc(sizeof(char) * 48); - strcpy(Text_string[i],"Sidewinder &\nThrustmaster FCS &\nWingman Extreme"); + char *extra; + char *str; + + case 145: + Text_string[i]=(char *) d_malloc(sizeof(char) * 48); + strcpy(Text_string[i],"Sidewinder &\nThrustmaster FCS &\nWingman Extreme"); + break; + + case 330: + extra = "\n converts format\nIntel <-> PowerPC"; + str = d_malloc(strlen(Text_string[i]) + strlen(extra) + 1); + if (!str) + break; + strcpy(str, Text_string[i]); + strcat(str, extra); + Text_string[i] = str; + break; } } -// Assert(tptr==text+len || tptr==text+len-2); - + //Assert(tptr==text+len || tptr==text+len-2); + }