Cleaned the variables used for newdemo code; Instead of giving both old and new values to special recording functions, added new variables to demo code serving this purpose and also checking for redundant record calls which only would waste bytes; Removed duplicated-object-id-hack which did not work as expected and caused jittering on playback; In that process, found a bug where Num_open_doors might nor be set correctly - cleaned that up a little and got also rid of one aweful goto; Made sure cloaked walls are recorded FPS-independent but rather fade-value-dependent

This commit is contained in:
zicodxx 2010-07-15 05:40:25 +00:00
parent 280b635dbe
commit 2cb3bac259
5 changed files with 250 additions and 326 deletions

View file

@ -1,5 +1,9 @@
D1X-Rebirth Changelog
20100715
--------
main/wall.c, main/newdemo.c, main/newdemo.h, main/gauges.c: Cleaned the variables used for newdemo code; Instead of giving both old and new values to special recording functions, added new variables to demo code serving this purpose and also checking for redundant record calls which only would waste bytes; Removed duplicated-object-id-hack which did not work as expected and caused jittering on playback; In that process, found a bug where Num_open_doors might nor be set correctly - cleaned that up a little and got also rid of one aweful goto
20100713
--------
include/args.h, main/net_udp.c, main/collide.c, main/multi.c, main/inferno.c, main/object.c, main/wall.c, main/state.c, main/hud.c, main/weapon.c, main/hostage.c, main/hudmsg.h, main/newdemo.c, main/net_ipx.c, main/fuelcen.c, main/ai.c, main/endlevel.c, main/powerup.c, main/game.c, main/gauges.c, main/gauges.h, main/gamecntl.c, misc/args.c, d1x.ini, arch/ogl/gr.c, arch/sdl/jukebox.c: Added expandable classes for HUD messages (like D1X but slacked) to better handle Multi messages or redundant messages; Rewrote HUD code completely; Changes -playermessages to -multimessages since this is more appropriate; Removed remnants of -mprofile

View file

@ -330,14 +330,7 @@ grs_bitmap *WinBoxOverlay[2] = { NULL, NULL }; // Overlay subbitmaps for both we
static int score_display;
static fix score_time;
static int old_score = -1;
static int old_energy = -1;
static int old_shields = -1;
static int old_flags = -1;
static int old_weapon[2] = {-1, -1};
static int old_ammo_count[2] = {-1, -1};
static int old_lives = -1;
static int old_prox = -1;
static int invulnerable_frame = 0;
int weapon_box_states[2];
fix weapon_box_fade_values[2];
@ -948,18 +941,8 @@ void hud_show_energy(void)
gr_printf(FSPACX(1), (grd_curcanv->cv_bitmap.bm_h-LINE_SPACING),"%s: %i", TXT_ENERGY, f2ir(Players[Player_num].energy));
}
if (Newdemo_state==ND_STATE_RECORDING ) {
int energy = f2ir(Players[Player_num].energy);
if (energy != old_energy) {
#ifdef SHAREWARE
newdemo_record_player_energy(energy);
#else
newdemo_record_player_energy(old_energy, energy);
#endif
old_energy = energy;
}
}
if (Newdemo_state==ND_STATE_RECORDING )
newdemo_record_player_energy(f2ir(Players[Player_num].energy));
}
void show_bomb_count(int x,int y,int bg_color,int always_show,int right_align)
@ -1140,20 +1123,12 @@ void hud_show_weapons(void)
show_bomb_count(grd_curcanv->cv_bitmap.bm_w-FSPACX(1), y-(LINE_SPACING*3),-1,1, 1);
}
#ifndef SHAREWARE
if (Primary_weapon == VULCAN_INDEX) {
if (Players[Player_num].primary_ammo[Primary_weapon] != old_ammo_count[0]) {
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_primary_ammo(old_ammo_count[0], Players[Player_num].primary_ammo[Primary_weapon]);
old_ammo_count[0] = Players[Player_num].primary_ammo[Primary_weapon];
}
}
if (Players[Player_num].secondary_ammo[Secondary_weapon] != old_ammo_count[1]) {
if (Primary_weapon == VULCAN_INDEX)
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_secondary_ammo(old_ammo_count[1], Players[Player_num].secondary_ammo[Secondary_weapon]);
old_ammo_count[1] = Players[Player_num].secondary_ammo[Secondary_weapon];
}
#endif
newdemo_record_primary_ammo(Players[Player_num].primary_ammo[Primary_weapon]);
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_secondary_ammo(Players[Player_num].secondary_ammo[Secondary_weapon]);
}
void hud_show_cloak_invuln(void)
@ -1212,18 +1187,8 @@ void hud_show_shield(void)
}
}
if (Newdemo_state==ND_STATE_RECORDING ) {
int shields = f2ir(Players[Player_num].shields);
if (shields != old_shields) {
#ifdef SHAREWARE
newdemo_record_player_shields(shields);
#else
newdemo_record_player_shields(old_shields, shields);
#endif
old_shields = shields;
}
}
if (Newdemo_state==ND_STATE_RECORDING )
newdemo_record_player_shields(f2ir(Players[Player_num].shields));
}
//draw the icons for number of lives
@ -1488,17 +1453,7 @@ void close_gauges()
void init_gauges()
{
if ( ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP)) || ((Newdemo_state == ND_STATE_PLAYBACK) && (Newdemo_game_mode & GM_MULTI) && !(Newdemo_game_mode & GM_MULTI_COOP)) )
old_score = -99;
else
old_score = -1;
old_energy = -1;
old_shields = -1;
old_flags = -1;
old_lives = -1;
old_weapon[0] = old_weapon[1] = -1;
old_ammo_count[0] = old_ammo_count[1] = -1;
}
void draw_energy_bar(int energy)
@ -1805,13 +1760,11 @@ void draw_weapon_box(int weapon_type,int weapon_num)
{
draw_weapon_info(weapon_type,weapon_num);
old_weapon[weapon_type] = weapon_num;
old_ammo_count[weapon_type]=-1;
weapon_box_states[weapon_type] = WS_SET;
}
if (weapon_box_states[weapon_type] == WS_FADING_OUT) {
draw_weapon_info(weapon_type,old_weapon[weapon_type]);
old_ammo_count[weapon_type]=-1;
weapon_box_fade_values[weapon_type] -= FrameTime * FADE_SCALE;
if (weapon_box_fade_values[weapon_type] <= 0)
{
@ -1830,7 +1783,6 @@ void draw_weapon_box(int weapon_type,int weapon_num)
else
{
draw_weapon_info(weapon_type,weapon_num);
old_ammo_count[weapon_type]=-1;
weapon_box_fade_values[weapon_type] += FrameTime * FADE_SCALE;
if (weapon_box_fade_values[weapon_type] >= i2f(GR_FADE_LEVELS-1)) {
weapon_box_states[weapon_type] = WS_SET;
@ -1842,7 +1794,6 @@ void draw_weapon_box(int weapon_type,int weapon_num)
{
draw_weapon_info(weapon_type, weapon_num);
old_weapon[weapon_type] = weapon_num;
old_ammo_count[weapon_type] = -1;
}
@ -1866,31 +1817,20 @@ void draw_weapon_boxes()
draw_weapon_box(0,Primary_weapon);
if (weapon_box_states[0] == WS_SET)
if (Players[Player_num].primary_ammo[Primary_weapon] != old_ammo_count[0])
if (Primary_weapon == VULCAN_INDEX)
{
#ifndef SHAREWARE
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_primary_ammo(old_ammo_count[0], Players[Player_num].primary_ammo[Primary_weapon]);
#endif
draw_primary_ammo_info(f2i(VULCAN_AMMO_SCALE * Players[Player_num].primary_ammo[Primary_weapon]));
old_ammo_count[0] = Players[Player_num].primary_ammo[Primary_weapon];
}
if (Primary_weapon == VULCAN_INDEX)
{
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_primary_ammo(Players[Player_num].primary_ammo[Primary_weapon]);
draw_primary_ammo_info(f2i(VULCAN_AMMO_SCALE * Players[Player_num].primary_ammo[Primary_weapon]));
}
draw_weapon_box(1,Secondary_weapon);
if (weapon_box_states[1] == WS_SET)
if (Players[Player_num].secondary_ammo[Secondary_weapon] != old_ammo_count[1] || Players[Player_num].secondary_ammo[2] != old_prox)
{
old_prox=Players[Player_num].secondary_ammo[2];
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_secondary_ammo(Players[Player_num].secondary_ammo[Secondary_weapon]);
#ifndef SHAREWARE
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_secondary_ammo(old_ammo_count[1], Players[Player_num].secondary_ammo[Secondary_weapon]);
#endif
draw_secondary_ammo_info(Players[Player_num].secondary_ammo[Secondary_weapon]);
old_ammo_count[1] = Players[Player_num].secondary_ammo[Secondary_weapon];
}
draw_secondary_ammo_info(Players[Player_num].secondary_ammo[Secondary_weapon]);
if(PlayerCfg.HudMode!=0)
{
@ -2283,10 +2223,8 @@ void draw_hud()
hud_show_keys();
hud_show_cloak_invuln();
if ( ( Newdemo_state==ND_STATE_RECORDING ) && ( Players[Player_num].flags != old_flags )) {
newdemo_record_player_flags(old_flags, Players[Player_num].flags);
old_flags = Players[Player_num].flags;
}
if (Newdemo_state==ND_STATE_RECORDING)
newdemo_record_player_flags(Players[Player_num].flags);
}
#ifdef NETWORK
@ -2338,15 +2276,8 @@ void render_gauges()
if (PlayerCfg.CockpitMode[1] == CM_FULL_COCKPIT) {
if (Newdemo_state == ND_STATE_RECORDING && (energy != old_energy))
{
newdemo_record_player_energy(
#ifndef SHAREWARE
old_energy,
#endif
energy);
old_energy = energy;
}
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_player_energy(energy);
draw_energy_bar(energy);
draw_numerical_display(shields, energy);
if (!PlayerCfg.HudMode)
@ -2355,26 +2286,15 @@ void render_gauges()
if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
draw_invulnerable_ship();
old_shields = shields ^ 1;
} else { // Draw the shield gauge
if (Newdemo_state == ND_STATE_RECORDING && (shields != old_shields))
{
newdemo_record_player_shields(
#ifndef SHAREWARE
old_shields,
#endif
shields);
old_shields = shields;
}
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_player_shields(shields);
draw_shield_bar(shields);
}
draw_numerical_display(shields, energy);
if (Newdemo_state == ND_STATE_RECORDING && (Players[Player_num].flags != old_flags))
{
newdemo_record_player_flags(old_flags, Players[Player_num].flags);
old_flags = Players[Player_num].flags;
}
if (Newdemo_state==ND_STATE_RECORDING)
newdemo_record_player_flags(Players[Player_num].flags);
draw_keys();
show_homing_warning();
@ -2382,15 +2302,8 @@ void render_gauges()
} else if (PlayerCfg.CockpitMode[1] == CM_STATUS_BAR) {
if (Newdemo_state == ND_STATE_RECORDING && (energy != old_energy))
{
newdemo_record_player_energy(
#ifndef SHAREWARE
old_energy,
#endif
energy);
old_energy = energy;
}
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_player_energy(energy);
sb_draw_energy_bar(energy);
if (!PlayerCfg.HudMode)
show_bomb_count(HUD_SCALE_X(SB_BOMB_COUNT_X), HUD_SCALE_Y(SB_BOMB_COUNT_Y), gr_find_closest_color(0, 0, 0), 0, 0);
@ -2400,52 +2313,28 @@ void render_gauges()
if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE)
{
draw_invulnerable_ship();
old_shields = shields ^ 1;
}
else
{ // Draw the shield gauge
if (Newdemo_state == ND_STATE_RECORDING && (shields != old_shields))
{
newdemo_record_player_shields(
#ifndef SHAREWARE
old_shields,
#endif
shields);
old_shields = shields;
}
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_player_shields(shields);
sb_draw_shield_bar(shields);
}
sb_draw_shield_num(shields);
if (Newdemo_state == ND_STATE_RECORDING && (Players[Player_num].flags != old_flags))
{
newdemo_record_player_flags(old_flags, Players[Player_num].flags);
old_flags = Players[Player_num].flags;
}
if (Newdemo_state==ND_STATE_RECORDING)
newdemo_record_player_flags(Players[Player_num].flags);
sb_draw_keys();
// May want to record this in a demo...
if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
{
sb_show_lives();
old_lives = Players[Player_num].net_killed_total;
}
else
{
sb_show_lives();
old_lives = Players[Player_num].lives;
}
sb_show_lives();
if ((Game_mode&GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
{
sb_show_score();
old_score = Players[Player_num].net_kills_total;
}
else
{
sb_show_score();
old_score = Players[Player_num].score;
sb_show_score_added();
}
} else

View file

@ -151,40 +151,57 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#define DEMO_GAME_TYPE_SHAREWARE 1
#define DEMO_GAME_TYPE 2
char nd_save_callsign[CALLSIGN_LEN+1];
// In- and Out-files
PHYSFS_file *infile;
PHYSFS_file *outfile = NULL;
// Some globals
int Newdemo_state = 0;
int Newdemo_game_mode = 0;
int Newdemo_vcr_state = 0;
int Newdemo_start_frame = -1;
int Newdemo_frame_number = -1;
unsigned int Newdemo_size;
int Newdemo_num_written;
sbyte Newdemo_no_space;
sbyte Newdemo_at_eof;
sbyte Newdemo_do_interpolate = 1;
sbyte Newdemo_warning_given = 0;
sbyte Newdemo_cntrlcen_destroyed = 0;
static sbyte nd_bad_read;
int NewdemoFrameCount;
short frame_bytes_written = 0;
fix nd_playback_total;
fix nd_recorded_total;
fix nd_recorded_time;
sbyte playback_style;
int Newdemo_show_percentage=1;
sbyte Newdemo_do_interpolate = 1;
int Newdemo_num_written;
// local var used for swapping endian demos
static int swap_endian = 0;
ubyte Newdemo_dead = 0, Newdemo_rear = 0;
// playback variables
static unsigned int nd_playback_v_demosize;
static char nd_playback_v_save_callsign[CALLSIGN_LEN+1];
static sbyte nd_playback_v_at_eof;
static sbyte nd_playback_v_cntrlcen_destroyed = 0;
static sbyte nd_playback_v_bad_read;
static int nd_playback_v_framecount;
static fix nd_playback_total, nd_recorded_total, nd_recorded_time;
static sbyte nd_playback_v_style;
static ubyte nd_playback_v_dead = 0, nd_playback_v_rear = 0;
// record variables
#define REC_DELAY F1_0/20
static int nd_record_v_start_frame = -1;
static int nd_record_v_frame_number = -1;
static short nd_record_v_framebytes_written = 0;
static int nd_record_v_recordframe = 1;
static fix nd_record_v_recordframe_last_time = 0;
static sbyte nd_record_v_no_space;
static int nd_record_v_countdown_seconds_left = 0;
static int nd_record_v_player_energy = -1;
static int nd_record_v_player_shields = -1;
static uint nd_record_v_player_flags = -1;
static int nd_record_v_weapon_type = -1;
static int nd_record_v_weapon_num = -1;
static fix nd_record_v_homing_distance = -1;
static int nd_record_v_primary_ammo = -1;
static int nd_record_v_secondary_ammo = -1;
void newdemo_record_oneframeevent_update(int wallupdate);
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 );
extern window *game_setup(void);
PHYSFS_file *infile;
PHYSFS_file *outfile = NULL;
int newdemo_get_percent_done() {
if ( Newdemo_state == ND_STATE_PLAYBACK ) {
return (PHYSFS_tell(infile) * 100) / Newdemo_size;
return (PHYSFS_tell(infile) * 100) / nd_playback_v_demosize;
}
if ( Newdemo_state == ND_STATE_RECORDING ) {
return PHYSFS_tell(outfile);
@ -229,7 +246,7 @@ int newdemo_read( void *buffer, int elsize, int nelem )
int num_read;
num_read = PHYSFS_read(infile, buffer, elsize, nelem);
if (num_read < nelem || PHYSFS_eof(infile))
nd_bad_read = -1;
nd_playback_v_bad_read = -1;
return num_read;
}
@ -251,15 +268,15 @@ int newdemo_write( void *buffer, int elsize, int nelem )
int num_written, total_size;
total_size = elsize * nelem;
frame_bytes_written += total_size;
nd_record_v_framebytes_written += total_size;
Newdemo_num_written += total_size;
Assert(outfile != NULL);
num_written = PHYSFS_write(outfile, buffer, elsize, nelem);
if (num_written == nelem && !Newdemo_no_space)
if (num_written == nelem && !nd_record_v_no_space)
return num_written;
Newdemo_no_space=2;
nd_record_v_no_space=2;
newdemo_stop_recording();
return -1;
}
@ -797,15 +814,11 @@ void nd_write_object(object *obj)
}
int RecordFrame=1;
static fix last_rec_time=0;
#define REC_DELAY F1_0/20
void newdemo_record_start_demo()
{
int i;
last_rec_time=GameTime-REC_DELAY; // make sure first frame is recorded!
nd_record_v_recordframe_last_time=GameTime-REC_DELAY; // make sure first frame is recorded!
stop_time();
nd_write_byte(ND_EVENT_START_DEMO);
@ -846,6 +859,12 @@ void newdemo_record_start_demo()
// NOTE LINK TO ABOVE!!!
nd_write_int(Players[Player_num].score);
nd_record_v_weapon_type = -1;
nd_record_v_weapon_num = -1;
nd_record_v_homing_distance = -1;
nd_record_v_primary_ammo = -1;
nd_record_v_secondary_ammo = -1;
for (i = 0; i < MAX_PRIMARY_WEAPONS; i++)
nd_write_short((short)Players[Player_num].primary_ammo[i]);
@ -858,12 +877,16 @@ void newdemo_record_start_demo()
nd_write_string(Current_mission_filename);
nd_record_v_player_energy = (sbyte)(f2ir(Players[Player_num].energy));
nd_write_byte((sbyte)(f2ir(Players[Player_num].energy)));
nd_record_v_player_shields = (sbyte)(f2ir(Players[Player_num].shields));
nd_write_byte((sbyte)(f2ir(Players[Player_num].shields)));
nd_record_v_player_flags = Players[Player_num].flags;
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;
nd_record_v_countdown_seconds_left = 0;
nd_record_v_start_frame = nd_record_v_frame_number = 0;
newdemo_set_new_level(Current_level_num);
newdemo_record_oneframeevent_update(1);
start_time();
@ -872,46 +895,46 @@ void newdemo_record_start_demo()
void newdemo_record_start_frame(fix frame_time )
{
if (Newdemo_no_space) {
if (nd_record_v_no_space) {
newdemo_stop_playback();
return;
}
// Make demo recording waste a bit less space.
// First check if if at least REC_DELAY has passed since last recorded frame. If yes, record frame and set RecordFrame true.
// RecordFrame will be used for various other frame-by-frame events to drop some unnecessary bytes.
// First check if if at least REC_DELAY has passed since last recorded frame. If yes, record frame and set nd_record_v_recordframe true.
// nd_record_v_recordframe will be used for various other frame-by-frame events to drop some unnecessary bytes.
// frame_time must be modified to get the right playback speed.
if (last_rec_time > GameTime)
last_rec_time=GameTime-REC_DELAY;
if (nd_record_v_recordframe_last_time > GameTime)
nd_record_v_recordframe_last_time=GameTime-REC_DELAY;
if (last_rec_time + REC_DELAY <= GameTime || frame_time >= REC_DELAY)
if (nd_record_v_recordframe_last_time + REC_DELAY <= GameTime || frame_time >= REC_DELAY)
{
if (frame_time < REC_DELAY)
frame_time = REC_DELAY;
last_rec_time = GameTime-(GameTime-(last_rec_time + REC_DELAY));
RecordFrame=1;
nd_record_v_recordframe_last_time = GameTime-(GameTime-(nd_record_v_recordframe_last_time + REC_DELAY));
nd_record_v_recordframe=1;
stop_time();
Newdemo_frame_number -= Newdemo_start_frame;
nd_record_v_frame_number -= nd_record_v_start_frame;
nd_write_byte(ND_EVENT_START_FRAME);
nd_write_short(frame_bytes_written - 1); // from previous frame
frame_bytes_written=3;
nd_write_int(Newdemo_frame_number);
Newdemo_frame_number++;
nd_write_short(nd_record_v_framebytes_written - 1); // from previous frame
nd_record_v_framebytes_written=3;
nd_write_int(nd_record_v_frame_number);
nd_record_v_frame_number++;
nd_write_int(frame_time);
start_time();
}
else
{
RecordFrame=0;
nd_record_v_recordframe=0;
}
}
void newdemo_record_render_object(object * obj)
{
if (!RecordFrame)
if (!nd_record_v_recordframe)
return;
stop_time();
nd_write_byte(ND_EVENT_RENDER_OBJECT);
@ -921,7 +944,7 @@ void newdemo_record_render_object(object * obj)
void newdemo_record_viewer_object(object * obj)
{
if (!RecordFrame)
if (!nd_record_v_recordframe)
return;
stop_time();
nd_write_byte(ND_EVENT_VIEWER_OBJECT);
@ -1011,7 +1034,7 @@ void newdemo_record_hostage_rescued( int hostage_number )
void newdemo_record_morph_frame(morph_data *md)
{
if (!RecordFrame)
if (!nd_record_v_recordframe)
return;
stop_time();
nd_write_byte( ND_EVENT_MORPH_FRAME );
@ -1030,9 +1053,12 @@ void newdemo_record_wall_toggle( int segnum, int side )
void newdemo_record_control_center_destroyed()
{
if (nd_record_v_countdown_seconds_left == Countdown_seconds_left)
return;
stop_time();
nd_write_byte( ND_EVENT_CONTROL_CENTER_DESTROYED );
nd_write_int( Countdown_seconds_left );
nd_record_v_countdown_seconds_left = Countdown_seconds_left;
start_time();
}
@ -1046,7 +1072,7 @@ void newdemo_record_hud_message( char * message )
void newdemo_record_palette_effect(short r, short g, short b )
{
if (!RecordFrame)
if (!nd_record_v_recordframe)
return;
stop_time();
nd_write_byte( ND_EVENT_PALETTE_EFFECT );
@ -1056,34 +1082,45 @@ void newdemo_record_palette_effect(short r, short g, short b )
start_time();
}
void newdemo_record_player_energy(int old_energy, int energy)
void newdemo_record_player_energy(int energy)
{
if (nd_record_v_player_energy == energy)
return;
stop_time();
nd_write_byte( ND_EVENT_PLAYER_ENERGY );
nd_write_byte((sbyte) old_energy);
nd_write_byte((sbyte) nd_record_v_player_energy);
nd_write_byte((sbyte) energy);
nd_record_v_player_energy = energy;
start_time();
}
void newdemo_record_player_shields(int old_shield, int shield)
void newdemo_record_player_shields(int shield)
{
if (nd_record_v_player_shields == shield)
return;
stop_time();
nd_write_byte( ND_EVENT_PLAYER_SHIELD );
nd_write_byte((sbyte)old_shield);
nd_write_byte((sbyte)nd_record_v_player_shields);
nd_write_byte((sbyte)shield);
nd_record_v_player_shields = shield;
start_time();
}
void newdemo_record_player_flags(uint oflags, uint flags)
void newdemo_record_player_flags(uint flags)
{
if (nd_record_v_player_flags == flags)
return;
stop_time();
nd_write_byte( ND_EVENT_PLAYER_FLAGS );
nd_write_int(((short)oflags << 16) | (short)flags);
nd_write_int(((short)nd_record_v_player_flags << 16) | (short)flags);
nd_record_v_player_flags = flags;
start_time();
}
void newdemo_record_player_weapon(int weapon_type, int weapon_num)
{
if (nd_record_v_weapon_type == weapon_type && nd_record_v_weapon_num == weapon_num)
return;
stop_time();
nd_write_byte( ND_EVENT_PLAYER_WEAPON );
nd_write_byte((sbyte)weapon_type);
@ -1092,6 +1129,8 @@ void newdemo_record_player_weapon(int weapon_type, int weapon_num)
nd_write_byte((sbyte)Secondary_weapon);
else
nd_write_byte((sbyte)Primary_weapon);
nd_record_v_weapon_type = weapon_type;
nd_record_v_weapon_num = weapon_num;
start_time();
}
@ -1107,9 +1146,12 @@ void newdemo_record_effect_blowup(short segment, int side, vms_vector *pnt)
void newdemo_record_homing_distance(fix distance)
{
if ((nd_record_v_homing_distance>>16) == (distance>>16))
return;
stop_time();
nd_write_byte(ND_EVENT_HOMING_DISTANCE);
nd_write_short((short)(distance>>16));
nd_record_v_homing_distance = distance;
start_time();
}
@ -1246,31 +1288,33 @@ void newdemo_record_multi_score(int pnum, int score)
start_time();
}
void newdemo_record_primary_ammo(int old_ammo, int new_ammo)
void newdemo_record_primary_ammo(int new_ammo)
{
if (!RecordFrame)
if (nd_record_v_primary_ammo == new_ammo)
return;
stop_time();
nd_write_byte(ND_EVENT_PRIMARY_AMMO);
if (old_ammo < 0)
if (nd_record_v_primary_ammo < 0)
nd_write_short((short)new_ammo);
else
nd_write_short((short)old_ammo);
nd_write_short((short)nd_record_v_primary_ammo);
nd_write_short((short)new_ammo);
nd_record_v_primary_ammo = new_ammo;
start_time();
}
void newdemo_record_secondary_ammo(int old_ammo, int new_ammo)
void newdemo_record_secondary_ammo(int new_ammo)
{
if (!RecordFrame)
if (nd_record_v_secondary_ammo == new_ammo)
return;
stop_time();
nd_write_byte(ND_EVENT_SECONDARY_AMMO);
if (old_ammo < 0)
if (nd_record_v_secondary_ammo < 0)
nd_write_short((short)new_ammo);
else
nd_write_short((short)old_ammo);
nd_write_short((short)nd_record_v_secondary_ammo);
nd_write_short((short)new_ammo);
nd_record_v_secondary_ammo = new_ammo;
start_time();
}
@ -1362,7 +1406,7 @@ int newdemo_read_demo_start(enum purpose_type purpose)
nd_read_byte(&c);
if (purpose == PURPOSE_REWRITE)
nd_write_byte(c);
if ((c != ND_EVENT_START_DEMO) || nd_bad_read) {
if ((c != ND_EVENT_START_DEMO) || nd_playback_v_bad_read) {
nm_messagebox( NULL, 1, TXT_OK, "%s %s", TXT_CANT_PLAYBACK, TXT_DEMO_CORRUPT );
return 1;
}
@ -1619,7 +1663,7 @@ int newdemo_read_frame_information(int rewrite)
while( !done ) {
nd_read_byte(&c);
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite && (c != ND_EVENT_EOF))
nd_write_byte(c);
@ -1630,26 +1674,26 @@ int newdemo_read_frame_information(int rewrite)
done=1;
nd_read_short(&last_frame_length);
nd_read_int(&NewdemoFrameCount);
nd_read_int(&nd_playback_v_framecount);
nd_read_int((int *)&nd_recorded_time);
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite)
{
nd_write_short(last_frame_length);
frame_bytes_written = 3;
nd_write_int(NewdemoFrameCount);
nd_record_v_framebytes_written = 3;
nd_write_int(nd_playback_v_framecount);
nd_write_int(nd_recorded_time);
break;
}
if (Newdemo_vcr_state == ND_STATE_PLAYBACK)
nd_recorded_total += nd_recorded_time;
NewdemoFrameCount--;
nd_playback_v_framecount--;
break;
}
case ND_EVENT_VIEWER_OBJECT: // Followed by an object structure
nd_read_object(Viewer);
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite)
{
nd_write_object(Viewer);
@ -1676,7 +1720,7 @@ int newdemo_read_frame_information(int rewrite)
break;
obj = &Objects[objnum];
nd_read_object(obj);
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite)
{
nd_write_object(obj);
@ -1718,7 +1762,7 @@ int newdemo_read_frame_information(int rewrite)
case ND_EVENT_SOUND:
nd_read_int(&soundno);
if (nd_bad_read) {done = -1; break; }
if (nd_playback_v_bad_read) {done = -1; break; }
if (rewrite)
{
nd_write_int(soundno);
@ -1732,7 +1776,7 @@ int newdemo_read_frame_information(int rewrite)
nd_read_int(&soundno);
nd_read_int(&angle);
nd_read_int(&volume);
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite)
{
nd_write_int(soundno);
@ -1748,7 +1792,7 @@ int newdemo_read_frame_information(int rewrite)
nd_read_int(&soundno);
nd_read_int(&angle);
nd_read_int(&volume);
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite)
{
nd_write_int(soundno);
@ -1811,7 +1855,7 @@ int newdemo_read_frame_information(int rewrite)
nd_read_int(&side);
nd_read_fix(&damage);
nd_read_int(&player);
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite)
{
nd_write_int(segnum);
@ -1829,7 +1873,7 @@ int newdemo_read_frame_information(int rewrite)
nd_read_int(&segnum);
nd_read_int(&side);
nd_read_int(&objnum);
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite)
{
nd_write_int(segnum);
@ -1845,7 +1889,7 @@ int newdemo_read_frame_information(int rewrite)
int hostage_number;
nd_read_int(&hostage_number);
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite)
{
nd_write_int(hostage_number);
@ -1870,7 +1914,7 @@ int newdemo_read_frame_information(int rewrite)
break;
obj = &Objects[objnum];
nd_read_object(obj);
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite)
{
nd_write_object(obj);
@ -1890,7 +1934,7 @@ int newdemo_read_frame_information(int rewrite)
case ND_EVENT_WALL_TOGGLE:
nd_read_int(&segnum);
nd_read_int(&side);
if (nd_bad_read) {done = -1; break; }
if (nd_playback_v_bad_read) {done = -1; break; }
if (rewrite)
{
nd_write_int(segnum);
@ -1904,15 +1948,15 @@ int newdemo_read_frame_information(int rewrite)
case ND_EVENT_CONTROL_CENTER_DESTROYED:
nd_read_int(&Countdown_seconds_left);
Control_center_destroyed = 1;
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite)
{
nd_write_int(Countdown_seconds_left);
break;
}
if (!Newdemo_cntrlcen_destroyed) {
if (!nd_playback_v_cntrlcen_destroyed) {
newdemo_pop_ctrlcen_triggers();
Newdemo_cntrlcen_destroyed = 1;
nd_playback_v_cntrlcen_destroyed = 1;
}
break;
@ -1920,7 +1964,7 @@ int newdemo_read_frame_information(int rewrite)
char hud_msg[60];
nd_read_string(&(hud_msg[0]));
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite)
{
nd_write_string(&(hud_msg[0]));
@ -1944,7 +1988,7 @@ int newdemo_read_frame_information(int rewrite)
nd_read_short(&r);
nd_read_short(&g);
nd_read_short(&b);
if (nd_bad_read) { done = -1; break; }
if (nd_playback_v_bad_read) { done = -1; break; }
if (rewrite)
{
nd_write_short(r);
@ -1968,7 +2012,7 @@ int newdemo_read_frame_information(int rewrite)
}
nd_read_byte((sbyte *)&energy);
if (nd_bad_read) {done = -1; break; }
if (nd_playback_v_bad_read) {done = -1; break; }
if (rewrite)
{
nd_write_byte(energy);
@ -1999,7 +2043,7 @@ int newdemo_read_frame_information(int rewrite)
nd_write_byte(old_shield);
}
nd_read_byte((sbyte *)&shield);
if (nd_bad_read) {done = -1; break; }
if (nd_playback_v_bad_read) {done = -1; break; }
if (rewrite)
{
nd_write_byte(shield);
@ -2023,7 +2067,7 @@ int newdemo_read_frame_information(int rewrite)
uint oflags;
nd_read_int((int *)&(Players[Player_num].flags));
if (nd_bad_read) {done = -1; break; }
if (nd_playback_v_bad_read) {done = -1; break; }
if (rewrite)
{
nd_write_int(Players[Player_num].flags);
@ -2146,32 +2190,32 @@ int newdemo_read_frame_information(int rewrite)
case ND_EVENT_LETTERBOX:
if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) {
Newdemo_dead = 1;
nd_playback_v_dead = 1;
} else if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD))
Newdemo_dead = 0;
nd_playback_v_dead = 0;
break;
case ND_EVENT_REARVIEW:
if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) {
Newdemo_rear = 1;
nd_playback_v_rear = 1;
} else if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) {
Newdemo_rear = 0;
nd_playback_v_rear = 0;
}
break;
case ND_EVENT_RESTORE_COCKPIT:
if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) {
Newdemo_dead = 1;
nd_playback_v_dead = 1;
} else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD))
Newdemo_dead = 0;
nd_playback_v_dead = 0;
break;
case ND_EVENT_RESTORE_REARVIEW:
if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD)) {
Newdemo_rear = 1;
nd_playback_v_rear = 1;
} else if ((Newdemo_vcr_state == ND_STATE_PLAYBACK) || (Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD)) {
Newdemo_rear = 0;
nd_playback_v_rear = 0;
}
break;
@ -2550,7 +2594,7 @@ int newdemo_read_frame_information(int rewrite)
#endif
LoadLevel((int)loaded_level);
piggy_load_level_data();
Newdemo_cntrlcen_destroyed = 0;
nd_playback_v_cntrlcen_destroyed = 0;
reset_palette_add(); // get palette back to normal
palette_save(); // initialise for palette_restore()
@ -2562,8 +2606,8 @@ int newdemo_read_frame_information(int rewrite)
case ND_EVENT_EOF: {
done=-1;
PHYSFS_seek(infile, PHYSFS_tell(infile) - 1); // get back to the EOF marker
Newdemo_at_eof = 1;
NewdemoFrameCount++;
nd_playback_v_at_eof = 1;
nd_playback_v_framecount++;
break;
}
@ -2573,15 +2617,15 @@ int newdemo_read_frame_information(int rewrite)
}
// Now set up cockpit and views according to what we read out. Note that the demo itself cannot determinate the right views since it does not use a good portion of the real game code.
if (Newdemo_dead)
if (nd_playback_v_dead)
{
Rear_view = 0;
if (PlayerCfg.CockpitMode[1] != CM_LETTERBOX)
select_cockpit(CM_LETTERBOX);
}
else if (Newdemo_rear)
else if (nd_playback_v_rear)
{
Rear_view = Newdemo_rear;
Rear_view = nd_playback_v_rear;
if (PlayerCfg.CockpitMode[0] == CM_FULL_COCKPIT)
select_cockpit(CM_REAR_VIEW);
}
@ -2592,7 +2636,7 @@ int newdemo_read_frame_information(int rewrite)
select_cockpit(PlayerCfg.CockpitMode[0]);
}
if (nd_bad_read) {
if (nd_playback_v_bad_read) {
nm_messagebox( NULL, 1, TXT_OK, "%s %s", TXT_DEMO_ERR_READING, TXT_DEMO_OLD_CORRUPT );
}
@ -2601,7 +2645,7 @@ int newdemo_read_frame_information(int rewrite)
void newdemo_goto_beginning()
{
//if (NewdemoFrameCount == 0)
//if (nd_playback_v_framecount == 0)
// return;
PHYSFS_seek(infile, 0);
Newdemo_vcr_state = ND_STATE_PLAYBACK;
@ -2612,7 +2656,7 @@ void newdemo_goto_beginning()
if (newdemo_read_frame_information(0) == -1)
newdemo_stop_playback();
Newdemo_vcr_state = ND_STATE_PAUSED;
Newdemo_at_eof = 0;
nd_playback_v_at_eof = 0;
}
void newdemo_goto_end(int to_rewrite)
@ -2730,8 +2774,8 @@ void newdemo_goto_end(int to_rewrite)
}
cfseek(infile, -frame_length, SEEK_CUR);
nd_read_int(&NewdemoFrameCount); // get the frame count
NewdemoFrameCount--;
nd_read_int(&nd_playback_v_framecount); // get the frame count
nd_playback_v_framecount--;
cfseek(infile, 4, SEEK_CUR);
Newdemo_vcr_state = ND_STATE_PLAYBACK;
newdemo_read_frame_information(0); // then the frame information
@ -2750,12 +2794,12 @@ void newdemo_back_frames(int frames)
nd_read_short(&last_frame_length);
PHYSFS_seek(infile, PHYSFS_tell(infile) + 8 - last_frame_length);
if (!Newdemo_at_eof && newdemo_read_frame_information(0) == -1) {
if (!nd_playback_v_at_eof && newdemo_read_frame_information(0) == -1) {
newdemo_stop_playback();
return;
}
if (Newdemo_at_eof)
Newdemo_at_eof = 0;
if (nd_playback_v_at_eof)
nd_playback_v_at_eof = 0;
PHYSFS_seek(infile, PHYSFS_tell(infile) - 10);
nd_read_short(&last_frame_length);
@ -2781,7 +2825,7 @@ void interpolate_frame(fix d_play, fix d_recorded)
object *cur_objs;
static fix InterpolStep = fl2f(.01);
if (NewdemoFrameCount < 1)
if (nd_playback_v_framecount < 1)
return;
factor = fixdiv(d_play, d_recorded);
@ -2815,20 +2859,11 @@ void interpolate_frame(fix d_play, fix d_recorded)
sbyte render_type = cur_objs[i].render_type;
fix delta_x, delta_y, delta_z;
/*
* HACK: Good 'ol Descent does not check for duplicate signatures when creating objects.
* So in case our two objects have a huge distance, we assume they are different.
* Interpolating would not make much sense in that case nevertheless.
*/
if (vm_vec_dist(&cur_objs[i].pos, &Objects[j].pos) > (Objects[j].size*2))
continue;
// 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;
@ -2909,9 +2944,9 @@ void newdemo_playback_one_frame()
if ((Newdemo_vcr_state == ND_STATE_REWINDING) || (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD))
{
level = Current_level_num;
if (NewdemoFrameCount == 0)
if (nd_playback_v_framecount == 0)
return;
else if ((Newdemo_vcr_state == ND_STATE_REWINDING) && (NewdemoFrameCount < 10)) {
else if ((Newdemo_vcr_state == ND_STATE_REWINDING) && (nd_playback_v_framecount < 10)) {
newdemo_goto_beginning();
return;
}
@ -2919,7 +2954,7 @@ void newdemo_playback_one_frame()
frames_back = 10;
else
frames_back = 1;
if (Newdemo_at_eof) {
if (nd_playback_v_at_eof) {
PHYSFS_seek(infile, PHYSFS_tell(infile) + (shareware ? -2 : +11));
}
newdemo_back_frames(frames_back);
@ -2934,13 +2969,13 @@ void newdemo_playback_one_frame()
}
}
else if (Newdemo_vcr_state == ND_STATE_FASTFORWARD) {
if (!Newdemo_at_eof)
if (!nd_playback_v_at_eof)
{
for (i = 0; i < 10; i++)
{
if (newdemo_read_frame_information(0) == -1)
{
if (Newdemo_at_eof)
if (nd_playback_v_at_eof)
Newdemo_vcr_state = ND_STATE_PAUSED;
else
newdemo_stop_playback();
@ -2952,15 +2987,15 @@ void newdemo_playback_one_frame()
Newdemo_vcr_state = ND_STATE_PAUSED;
}
else if (Newdemo_vcr_state == ND_STATE_ONEFRAMEFORWARD) {
if (!Newdemo_at_eof) {
if (!nd_playback_v_at_eof) {
level = Current_level_num;
if (newdemo_read_frame_information(0) == -1) {
if (!Newdemo_at_eof)
if (!nd_playback_v_at_eof)
newdemo_stop_playback();
}
if (level != Current_level_num) {
if (newdemo_read_frame_information(0) == -1) {
if (!Newdemo_at_eof)
if (!nd_playback_v_at_eof)
newdemo_stop_playback();
}
}
@ -2975,20 +3010,19 @@ void newdemo_playback_one_frame()
// skip frames based on where the playback time is relative to the
// recorded time.
if (NewdemoFrameCount <= 0)
if (nd_playback_v_framecount <= 0)
nd_playback_total = nd_recorded_total; // baseline total playback time
else
nd_playback_total += FrameTime;
if (playback_style == NORMAL_PLAYBACK)
if (nd_playback_v_style == NORMAL_PLAYBACK)
{
if (nd_playback_total > nd_recorded_total)
playback_style = SKIP_PLAYBACK;
nd_playback_v_style = SKIP_PLAYBACK;
//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;
nd_playback_v_style = INTERPOLATE_PLAYBACK;
nd_playback_total = nd_recorded_total + FrameTime; // baseline playback time
base_interpol_time = nd_recorded_total;
d_recorded = nd_recorded_time; // baseline delta recorded
@ -2996,7 +3030,7 @@ void newdemo_playback_one_frame()
}
if ((playback_style == INTERPOLATE_PLAYBACK) && Newdemo_do_interpolate) {
if ((nd_playback_v_style == INTERPOLATE_PLAYBACK) && Newdemo_do_interpolate) {
fix d_play = 0;
if (nd_recorded_total - nd_playback_total < FrameTime) {
@ -3036,14 +3070,6 @@ void newdemo_playback_one_frame()
for (i = 0; i <= num_objs; i++) {
for (j = 0; j <= Highest_object_index; j++) {
if (cur_objs[i].signature == Objects[j].signature) {
/*
* HACK: Good 'ol Descent does not check for duplicate signatures when creating objects.
* So in case our two objects have a huge distance, we assume they are different.
* Interpolating would not make much sense in that case nevertheless.
*/
if (vm_vec_dist(&cur_objs[i].pos, &Objects[j].pos) > (Objects[j].size*2))
continue;
memcpy(&(Objects[j].orient), &(cur_objs[i].orient), sizeof(vms_matrix));
memcpy(&(Objects[j].pos), &(cur_objs[i].pos), sizeof(vms_vector));
break;
@ -3065,7 +3091,7 @@ void newdemo_playback_one_frame()
newdemo_stop_playback();
return;
}
if (playback_style == SKIP_PLAYBACK) {
if (nd_playback_v_style == SKIP_PLAYBACK) {
while (nd_playback_total > nd_recorded_total) {
if (newdemo_read_frame_information(0) == -1) {
newdemo_stop_playback();
@ -3080,7 +3106,7 @@ void newdemo_playback_one_frame()
void newdemo_start_recording()
{
Newdemo_num_written = 0;
Newdemo_no_space=0;
nd_record_v_no_space=0;
Newdemo_state = ND_STATE_RECORDING;
PHYSFS_mkdir(DEMO_DIR); //always try making directory - could only exist in read-only path
@ -3103,7 +3129,7 @@ void newdemo_write_end()
int i;
nd_write_byte(ND_EVENT_EOF);
nd_write_short(frame_bytes_written - 1);
nd_write_short(nd_record_v_framebytes_written - 1);
if (Game_mode & GM_MULTI) {
for (i = 0; i < N_players; i++) {
if (Players[i].flags & PLAYER_FLAGS_CLOAKED)
@ -3119,7 +3145,7 @@ void newdemo_write_end()
if (!shareware)
{
byte_count += 10; // from frame_bytes_written
byte_count += 10; // from nd_record_v_framebytes_written
nd_write_byte((sbyte)(f2ir(Players[Player_num].energy)));
nd_write_byte((sbyte)(f2ir(Players[Player_num].shields)));
@ -3176,7 +3202,7 @@ void newdemo_stop_recording()
exit = 0;
if (!Newdemo_no_space)
if (!nd_record_v_no_space)
{
newdemo_record_oneframeevent_update(0);
newdemo_write_end();
@ -3209,10 +3235,10 @@ try_again:
;
Newmenu_allowed_chars = demoname_allowed_chars;
if (!Newdemo_no_space) {
if (!nd_record_v_no_space) {
m[0].type=NM_TYPE_INPUT; m[0].text_len = PATH_MAX - 1; m[0].text = filename;
exit = newmenu_do( NULL, TXT_SAVE_DEMO_AS, 1, &(m[0]), NULL, NULL );
} else if (Newdemo_no_space == 2) {
} else if (nd_record_v_no_space == 2) {
m[ 0].type = NM_TYPE_TEXT; m[ 0].text = TXT_DEMO_SAVE_NOSPACE;
m[ 1].type = NM_TYPE_INPUT;m[ 1].text_len = PATH_MAX - 1; m[1].text = filename;
exit = newmenu_do( NULL, NULL, 2, m, NULL, NULL );
@ -3247,7 +3273,7 @@ try_again:
goto try_again;
}
if (Newdemo_no_space)
if (nd_record_v_no_space)
strcat(fullname, m[1].text);
else
strcat(fullname, m[0].text);
@ -3326,11 +3352,11 @@ void newdemo_start_playback(char * filename)
return;
}
nd_bad_read = 0;
nd_playback_v_bad_read = 0;
#ifdef NETWORK
change_playernum_to(0); // force playernum to 0
#endif
strncpy(nd_save_callsign, Players[Player_num].callsign, CALLSIGN_LEN);
strncpy(nd_playback_v_save_callsign, Players[Player_num].callsign, CALLSIGN_LEN);
Players[Player_num].lives=0;
Viewer = ConsoleObject = &Objects[0]; // play properly as if console player
@ -3342,12 +3368,12 @@ void newdemo_start_playback(char * filename)
Game_mode = GM_NORMAL;
Newdemo_state = ND_STATE_PLAYBACK;
Newdemo_vcr_state = ND_STATE_PLAYBACK;
Newdemo_size = PHYSFS_fileLength(infile);
nd_bad_read = 0;
Newdemo_at_eof = 0;
NewdemoFrameCount = 0;
playback_style = NORMAL_PLAYBACK;
Newdemo_dead = Newdemo_rear = 0;
nd_playback_v_demosize = PHYSFS_fileLength(infile);
nd_playback_v_bad_read = 0;
nd_playback_v_at_eof = 0;
nd_playback_v_framecount = 0;
nd_playback_v_style = NORMAL_PLAYBACK;
nd_playback_v_dead = nd_playback_v_rear = 0;
HUD_clear_messages();
if (!Game_wind)
hide_menus();
@ -3364,9 +3390,9 @@ void newdemo_stop_playback()
#ifdef NETWORK
change_playernum_to(0); //this is reality
#endif
strncpy(Players[Player_num].callsign, nd_save_callsign, CALLSIGN_LEN);
strncpy(Players[Player_num].callsign, nd_playback_v_save_callsign, CALLSIGN_LEN);
Rear_view=0;
Newdemo_dead = Newdemo_rear = 0;
nd_playback_v_dead = nd_playback_v_rear = 0;
Newdemo_game_mode = Game_mode = GM_GAME_OVER;
if (Game_wind)
window_close(Game_wind); // Exit game loop
@ -3387,7 +3413,7 @@ int newdemo_swap_endian(char *filename)
if (infile==NULL)
goto read_error;
Newdemo_size = PHYSFS_fileLength(infile); // should be exactly the same size
nd_playback_v_demosize = PHYSFS_fileLength(infile); // should be exactly the same size
outfile = PHYSFSX_openWriteBuffered(DEMO_FILENAME);
if (outfile==NULL)
{
@ -3396,9 +3422,9 @@ int newdemo_swap_endian(char *filename)
}
Newdemo_num_written = 0;
nd_bad_read = 0;
nd_playback_v_bad_read = 0;
swap_endian = 1;
Newdemo_at_eof = 0;
nd_playback_v_at_eof = 0;
Newdemo_state = ND_STATE_NORMAL; // not doing anything special really
if (newdemo_read_demo_start(PURPOSE_REWRITE)) {
@ -3414,7 +3440,7 @@ int newdemo_swap_endian(char *filename)
newdemo_write_end(); // and write it
swap_endian = 0;
complete = Newdemo_size == Newdemo_num_written;
complete = nd_playback_v_demosize == Newdemo_num_written;
PHYSFS_close(infile);
PHYSFS_close(outfile);
outfile = NULL;
@ -3433,10 +3459,10 @@ int newdemo_swap_endian(char *filename)
read_error:
{
nm_messagebox( NULL, 1, TXT_OK, complete ? "Demo %s converted%s" : "Error converting demo\n%s\n%s", filename,
complete ? "" : (Newdemo_at_eof ? TXT_DEMO_CORRUPT : PHYSFS_getLastError()));
complete ? "" : (nd_playback_v_at_eof ? TXT_DEMO_CORRUPT : PHYSFS_getLastError()));
}
return Newdemo_at_eof;
return nd_playback_v_at_eof;
}
#ifndef NDEBUG

View file

@ -65,9 +65,9 @@ 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);
extern void newdemo_record_player_energy(int, int);
extern void newdemo_record_player_shields(int, int);
extern void newdemo_record_player_flags(uint, uint);
extern void newdemo_record_player_energy(int);
extern void newdemo_record_player_shields(int);
extern void newdemo_record_player_flags(uint);
extern void newdemo_record_player_weapon(int, int);
extern void newdemo_record_effect_blowup(short, int, vms_vector *);
extern void newdemo_record_homing_distance(fix);
@ -88,8 +88,8 @@ extern void newdemo_record_multi_reconnect(int pnum);
extern void newdemo_record_multi_disconnect(int pnum);
extern void newdemo_record_player_score(int score);
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_primary_ammo(int new_ammo);
extern void newdemo_record_secondary_ammo(int new_ammo);
extern void newdemo_record_door_opening(int segnum, int side);
extern void newdemo_record_laser_level(sbyte old_level, sbyte new_level);

View file

@ -361,21 +361,26 @@ void wall_open_door(segment *seg, int side)
break;
}
if (i>=Num_open_doors && (Game_mode & GM_MULTI))
goto FastFix;
Assert(i<Num_open_doors); //didn't find door!
Assert( d!=NULL ); // Get John!
d->time = WallAnims[w->clip_num].play_time - d->time;
if (d->time < 0)
if (i>=Num_open_doors) // likely in demo playback or multiplayer
{
d = &ActiveDoors[Num_open_doors];
d->time = 0;
Num_open_doors++;
Assert( Num_open_doors < MAX_DOORS );
}
else
{
Assert( d!=NULL ); // Get John!
d->time = WallAnims[w->clip_num].play_time - d->time;
if (d->time < 0)
d->time = 0;
}
}
else { //create new door
Assert(w->state == WALL_DOOR_CLOSED);
FastFix:
d = &ActiveDoors[Num_open_doors];
d->time = 0;
Num_open_doors++;