Remove call to window_close(Game_wind) when stopping demo playback
Replace call to window_close(Game_wind) with returning window_event_result::close to game_handler. Applies to whenever newdemo_stop_playback() is called. Closing a window within its handler is problematic - it can result in an unstable state.
This commit is contained in:
parent
d10896f116
commit
2ecc4c4a07
|
@ -28,6 +28,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
|||
#ifdef __cplusplus
|
||||
#include "physfsx.h"
|
||||
#include "fwd-object.h"
|
||||
#include "fwd-window.h"
|
||||
|
||||
class object_signature_t;
|
||||
|
||||
|
@ -140,13 +141,13 @@ extern void newdemo_record_secret_exit_blown(int truth);
|
|||
|
||||
// Functions called during playback process...
|
||||
extern void newdemo_object_move_all();
|
||||
extern void newdemo_playback_one_frame();
|
||||
extern window_event_result newdemo_playback_one_frame();
|
||||
#ifdef dsx
|
||||
namespace dsx {
|
||||
extern void newdemo_goto_end(int to_rewrite);
|
||||
extern window_event_result newdemo_goto_end(int to_rewrite);
|
||||
}
|
||||
#endif
|
||||
extern void newdemo_goto_beginning();
|
||||
extern window_event_result newdemo_goto_beginning();
|
||||
|
||||
// Interactive functions to control playback/record;
|
||||
#ifdef dsx
|
||||
|
|
|
@ -1485,9 +1485,12 @@ window_event_result GameProcessFrame()
|
|||
|
||||
flash_frame();
|
||||
|
||||
if ( Newdemo_state == ND_STATE_PLAYBACK ) {
|
||||
newdemo_playback_one_frame();
|
||||
if ( Newdemo_state != ND_STATE_PLAYBACK ) {
|
||||
if ( Newdemo_state == ND_STATE_PLAYBACK )
|
||||
{
|
||||
result = std::max(newdemo_playback_one_frame(), result);
|
||||
if ( Newdemo_state != ND_STATE_PLAYBACK )
|
||||
{
|
||||
Assert(result == window_event_result::close);
|
||||
return window_event_result::close; // Go back to menu
|
||||
}
|
||||
}
|
||||
|
|
|
@ -458,7 +458,7 @@ static int HandleDeathInput(const d_event &event)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int HandleDemoKey(int key)
|
||||
static window_event_result HandleDemoKey(int key)
|
||||
{
|
||||
switch (key) {
|
||||
KEY_MAC(case KEY_COMMAND+KEY_1:)
|
||||
|
@ -487,6 +487,7 @@ static int HandleDemoKey(int key)
|
|||
break;
|
||||
}
|
||||
newdemo_stop_playback();
|
||||
return window_event_result::close;
|
||||
break;
|
||||
case KEY_UP:
|
||||
Newdemo_vcr_state = ND_STATE_PLAYBACK;
|
||||
|
@ -503,10 +504,10 @@ static int HandleDemoKey(int key)
|
|||
Newdemo_vcr_state = ND_STATE_ONEFRAMEFORWARD;
|
||||
break;
|
||||
case KEY_CTRLED + KEY_RIGHT:
|
||||
newdemo_goto_end(0);
|
||||
return newdemo_goto_end(0);
|
||||
break;
|
||||
case KEY_CTRLED + KEY_LEFT:
|
||||
newdemo_goto_beginning();
|
||||
return newdemo_goto_beginning();
|
||||
break;
|
||||
|
||||
KEY_MAC(case KEY_COMMAND+KEY_P:)
|
||||
|
@ -574,10 +575,10 @@ static int HandleDemoKey(int key)
|
|||
#endif
|
||||
|
||||
default:
|
||||
return 0;
|
||||
return window_event_result::ignored;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return window_event_result::handled;
|
||||
}
|
||||
|
||||
#if defined(DXX_BUILD_DESCENT_II)
|
||||
|
@ -1893,8 +1894,9 @@ window_event_result ReadControls(const d_event &event)
|
|||
}
|
||||
else if (Newdemo_state == ND_STATE_PLAYBACK )
|
||||
{
|
||||
if (HandleDemoKey(key))
|
||||
return window_event_result::handled;
|
||||
auto r = HandleDemoKey(key);
|
||||
if (r != window_event_result::ignored)
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -3269,7 +3269,7 @@ static int newdemo_read_frame_information(int rewrite)
|
|||
}
|
||||
}
|
||||
|
||||
void newdemo_goto_beginning()
|
||||
window_event_result newdemo_goto_beginning()
|
||||
{
|
||||
//if (nd_playback_v_framecount == 0)
|
||||
// return;
|
||||
|
@ -3283,10 +3283,13 @@ void newdemo_goto_beginning()
|
|||
newdemo_stop_playback();
|
||||
Newdemo_vcr_state = ND_STATE_PAUSED;
|
||||
nd_playback_v_at_eof = 0;
|
||||
|
||||
// check if we stopped playback
|
||||
return Newdemo_state == ND_STATE_NORMAL ? window_event_result::close : window_event_result::handled;
|
||||
}
|
||||
|
||||
namespace dsx {
|
||||
void newdemo_goto_end(int to_rewrite)
|
||||
window_event_result newdemo_goto_end(int to_rewrite)
|
||||
{
|
||||
short frame_length=0, byte_count=0, bshort=0;
|
||||
sbyte level=0, bbyte=0, c=0, cloaked=0;
|
||||
|
@ -3302,7 +3305,7 @@ void newdemo_goto_end(int to_rewrite)
|
|||
nm_messagebox( NULL, 1, TXT_OK, "%s\n%s\n%s", TXT_CANT_PLAYBACK, TXT_LEVEL_CANT_LOAD, TXT_DEMO_OLD_CORRUPT );
|
||||
Current_mission.reset();
|
||||
newdemo_stop_playback();
|
||||
return;
|
||||
return window_event_result::close;
|
||||
}
|
||||
if (level != Current_level_num)
|
||||
LoadLevel(level,1);
|
||||
|
@ -3336,7 +3339,7 @@ void newdemo_goto_end(int to_rewrite)
|
|||
}
|
||||
|
||||
if (to_rewrite)
|
||||
return;
|
||||
return window_event_result::handled;
|
||||
|
||||
PHYSFSX_fseek(infile, -12, SEEK_END);
|
||||
nd_read_short(&frame_length);
|
||||
|
@ -3435,7 +3438,7 @@ void newdemo_goto_end(int to_rewrite)
|
|||
}
|
||||
|
||||
if (to_rewrite)
|
||||
return;
|
||||
return window_event_result::handled;
|
||||
|
||||
PHYSFSX_fseek(infile, loc, SEEK_SET);
|
||||
}
|
||||
|
@ -3446,11 +3449,11 @@ void newdemo_goto_end(int to_rewrite)
|
|||
Newdemo_vcr_state = ND_STATE_PLAYBACK;
|
||||
newdemo_read_frame_information(0); // then the frame information
|
||||
Newdemo_vcr_state = ND_STATE_PAUSED;
|
||||
return;
|
||||
return window_event_result::handled;
|
||||
}
|
||||
}
|
||||
|
||||
static void newdemo_back_frames(int frames)
|
||||
static window_event_result newdemo_back_frames(int frames)
|
||||
{
|
||||
short last_frame_length;
|
||||
for (int i = 0; i < frames; i++)
|
||||
|
@ -3461,7 +3464,7 @@ static void newdemo_back_frames(int frames)
|
|||
|
||||
if (!nd_playback_v_at_eof && newdemo_read_frame_information(0) == -1) {
|
||||
newdemo_stop_playback();
|
||||
return;
|
||||
return window_event_result::close;
|
||||
}
|
||||
if (nd_playback_v_at_eof)
|
||||
nd_playback_v_at_eof = 0;
|
||||
|
@ -3471,6 +3474,7 @@ static void newdemo_back_frames(int frames)
|
|||
PHYSFS_seek(infile, PHYSFS_tell(infile) + 8 - last_frame_length);
|
||||
}
|
||||
|
||||
return window_event_result::handled;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3483,13 +3487,13 @@ static void newdemo_back_frames(int frames)
|
|||
* at.
|
||||
*/
|
||||
|
||||
static void interpolate_frame(fix d_play, fix d_recorded)
|
||||
static window_event_result interpolate_frame(fix d_play, fix d_recorded)
|
||||
{
|
||||
fix factor;
|
||||
static fix InterpolStep = fl2f(.01);
|
||||
|
||||
if (nd_playback_v_framecount < 1)
|
||||
return;
|
||||
return window_event_result::ignored;
|
||||
|
||||
factor = fixdiv(d_play, d_recorded);
|
||||
if (factor > F1_0)
|
||||
|
@ -3501,7 +3505,7 @@ static void interpolate_frame(fix d_play, fix d_recorded)
|
|||
Newdemo_vcr_state = ND_STATE_PAUSED;
|
||||
if (newdemo_read_frame_information(0) == -1) {
|
||||
newdemo_stop_playback();
|
||||
return;
|
||||
return window_event_result::close;
|
||||
}
|
||||
|
||||
InterpolStep -= FrameTime;
|
||||
|
@ -3566,21 +3570,27 @@ static void interpolate_frame(fix d_play, fix d_recorded)
|
|||
// with Highest_object_index and the object array (previously rendered
|
||||
// objects, etc....)
|
||||
|
||||
newdemo_back_frames(1);
|
||||
newdemo_back_frames(1);
|
||||
auto result = newdemo_back_frames(1);
|
||||
result = std::max(newdemo_back_frames(1), result);
|
||||
if (newdemo_read_frame_information(0) == -1)
|
||||
{
|
||||
newdemo_stop_playback();
|
||||
result = window_event_result::close;
|
||||
}
|
||||
Newdemo_vcr_state = ND_STATE_PLAYBACK;
|
||||
|
||||
std::copy(cur_objs.begin(), cur_objs.begin() + num_cur_objs, Objects.begin());
|
||||
Objects.set_count(num_cur_objs);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void newdemo_playback_one_frame()
|
||||
window_event_result newdemo_playback_one_frame()
|
||||
{
|
||||
int frames_back;
|
||||
static fix base_interpol_time = 0;
|
||||
static fix d_recorded = 0;
|
||||
auto result = window_event_result::handled;
|
||||
|
||||
range_for (auto &i, Players)
|
||||
{
|
||||
|
@ -3593,7 +3603,7 @@ void newdemo_playback_one_frame()
|
|||
}
|
||||
|
||||
if (Newdemo_vcr_state == ND_STATE_PAUSED) // render a frame or not
|
||||
return;
|
||||
return window_event_result::ignored;
|
||||
|
||||
Control_center_destroyed = 0;
|
||||
Countdown_seconds_left = -1;
|
||||
|
@ -3603,10 +3613,9 @@ void newdemo_playback_one_frame()
|
|||
{
|
||||
const int level = Current_level_num;
|
||||
if (nd_playback_v_framecount == 0)
|
||||
return;
|
||||
return window_event_result::ignored;
|
||||
else if ((Newdemo_vcr_state == ND_STATE_REWINDING) && (nd_playback_v_framecount < 10)) {
|
||||
newdemo_goto_beginning();
|
||||
return;
|
||||
return newdemo_goto_beginning();
|
||||
}
|
||||
if (Newdemo_vcr_state == ND_STATE_REWINDING)
|
||||
frames_back = 10;
|
||||
|
@ -3615,14 +3624,14 @@ void newdemo_playback_one_frame()
|
|||
if (nd_playback_v_at_eof) {
|
||||
PHYSFS_seek(infile, PHYSFS_tell(infile) + (shareware ? -2 : +11));
|
||||
}
|
||||
newdemo_back_frames(frames_back);
|
||||
result = newdemo_back_frames(frames_back);
|
||||
|
||||
if (level != Current_level_num)
|
||||
newdemo_pop_ctrlcen_triggers();
|
||||
|
||||
if (Newdemo_vcr_state == ND_STATE_ONEFRAMEBACKWARD) {
|
||||
if (level != Current_level_num)
|
||||
newdemo_back_frames(1);
|
||||
result = std::max(newdemo_back_frames(1), result);
|
||||
Newdemo_vcr_state = ND_STATE_PAUSED;
|
||||
}
|
||||
}
|
||||
|
@ -3636,7 +3645,10 @@ void newdemo_playback_one_frame()
|
|||
if (nd_playback_v_at_eof)
|
||||
Newdemo_vcr_state = ND_STATE_PAUSED;
|
||||
else
|
||||
{
|
||||
newdemo_stop_playback();
|
||||
result = window_event_result::close;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3649,12 +3661,18 @@ void newdemo_playback_one_frame()
|
|||
const int level = Current_level_num;
|
||||
if (newdemo_read_frame_information(0) == -1) {
|
||||
if (!nd_playback_v_at_eof)
|
||||
{
|
||||
newdemo_stop_playback();
|
||||
result = window_event_result::close;
|
||||
}
|
||||
}
|
||||
if (level != Current_level_num) {
|
||||
if (newdemo_read_frame_information(0) == -1) {
|
||||
if (!nd_playback_v_at_eof)
|
||||
{
|
||||
newdemo_stop_playback();
|
||||
result = window_event_result::close;
|
||||
}
|
||||
}
|
||||
}
|
||||
Newdemo_vcr_state = ND_STATE_PAUSED;
|
||||
|
@ -3703,11 +3721,14 @@ void newdemo_playback_one_frame()
|
|||
const int level = Current_level_num;
|
||||
if (newdemo_read_frame_information(0) == -1) {
|
||||
newdemo_stop_playback();
|
||||
return;
|
||||
return window_event_result::close;
|
||||
}
|
||||
if (level != Current_level_num) {
|
||||
if (newdemo_read_frame_information(0) == -1)
|
||||
{
|
||||
newdemo_stop_playback();
|
||||
result = window_event_result::close;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3732,24 +3753,25 @@ void newdemo_playback_one_frame()
|
|||
}
|
||||
|
||||
d_play = nd_playback_total - base_interpol_time;
|
||||
interpolate_frame(d_play, d_recorded);
|
||||
return;
|
||||
return std::max(interpolate_frame(d_play, d_recorded), result);
|
||||
}
|
||||
else {
|
||||
if (newdemo_read_frame_information(0) == -1) {
|
||||
newdemo_stop_playback();
|
||||
return;
|
||||
return window_event_result::close;
|
||||
}
|
||||
if (nd_playback_v_style == SKIP_PLAYBACK) {
|
||||
while (nd_playback_total > nd_recorded_total) {
|
||||
if (newdemo_read_frame_information(0) == -1) {
|
||||
newdemo_stop_playback();
|
||||
return;
|
||||
return window_event_result::close;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void newdemo_start_recording()
|
||||
|
@ -4083,8 +4105,12 @@ void newdemo_start_playback(const char * filename)
|
|||
HUD_clear_messages();
|
||||
if (!Game_wind)
|
||||
hide_menus();
|
||||
newdemo_playback_one_frame(); // this one loads new level
|
||||
newdemo_playback_one_frame(); // get all of the objects to renderb game
|
||||
auto result = newdemo_playback_one_frame(); // this one loads new level
|
||||
result = std::max(newdemo_playback_one_frame(), result); // get all of the objects to renderb game
|
||||
|
||||
if (result == window_event_result::close)
|
||||
return; // whoops, there was an error reading the first two frames! Abort!
|
||||
|
||||
if (!Game_wind)
|
||||
Game_wind = game_setup(); // create game environment
|
||||
}
|
||||
|
@ -4107,9 +4133,6 @@ void newdemo_stop_playback()
|
|||
|
||||
// Required for the editor
|
||||
obj_relink_all();
|
||||
|
||||
if (Game_wind)
|
||||
window_close(Game_wind); // Exit game loop
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue