record at 50ms simulation per frame

Change bare "5" to more descriptive "recording_frame_duration_hundredths".

Create APPLE2Einterface events that allow interface to limit main loop speed.

Implement rate limiting on start_record and release limiting on stop_record.

During recording, simulation will not run at clock rate.
This commit is contained in:
Brad Grantham 2018-08-08 16:18:16 -07:00
parent 6028d62786
commit 2c437b27da
3 changed files with 29 additions and 8 deletions

View File

@ -41,6 +41,9 @@ volatile bool exit_on_memory_fallthrough = true;
volatile bool run_fast = false;
volatile bool pause_cpu = false;
bool run_rate_limited = false;
int rate_limit_millis;
// XXX - this should be handled through a function passed to MAINboard
APPLE2Einterface::ModeHistory mode_history;
@ -3053,8 +3056,14 @@ enum APPLE2Einterface::EventType process_events(MAINboard *board, bus_frontend&
pause_cpu = e.value;
} else if(e.type == APPLE2Einterface::SPEED) {
run_fast = e.value;
} else if(e.type == APPLE2Einterface::QUIT)
return e.type;
} else if(e.type == APPLE2Einterface::QUIT) {
return e.type;
} else if(e.type == APPLE2Einterface::REQUEST_ITERATION_PERIOD_IN_MILLIS) {
run_rate_limited = true;
rate_limit_millis = e.value;
} else if(e.type == APPLE2Einterface::WITHDRAW_ITERATION_PERIOD_REQUEST) {
run_rate_limited = false;
}
}
return APPLE2Einterface::NONE;
}
@ -3215,10 +3224,13 @@ int main(int argc, char **argv)
if(pause_cpu)
clocks_per_slice = 0;
else {
if(run_fast)
if(run_rate_limited) {
clocks_per_slice = machine_clock_rate / 1000 * rate_limit_millis;
} else if(run_fast) {
clocks_per_slice = machine_clock_rate / 5;
else
} else {
clocks_per_slice = millis_per_slice * machine_clock_rate / 1000 * 1.05;
}
}
clk_t prev_clock = clk;
while(clk - prev_clock < clocks_per_slice) {
@ -3243,7 +3255,7 @@ int main(int argc, char **argv)
auto elapsed_millis = chrono::duration_cast<chrono::milliseconds>(now - then);
if(!run_fast || pause_cpu)
this_thread::sleep_for(chrono::milliseconds(millis_per_slice) - elapsed_millis);
this_thread::sleep_for(chrono::milliseconds(clocks_per_slice * 1000 / machine_clock_rate) - elapsed_millis);
then = now;

View File

@ -179,6 +179,7 @@ render_target::render_target(int w, int h)
const int apple2_screen_width = 280;
const int apple2_screen_height = 192;
const int recording_scale = 2;
const int recording_frame_duration_hundredths = 5;
chrono::time_point<chrono::system_clock> start_time;
@ -1753,6 +1754,7 @@ static void stop_record()
if (gif_recording) {
GifEnd(&gif_writer);
gif_recording = false;
event_queue.push_back({WITHDRAW_ITERATION_PERIOD_REQUEST, 0});
}
}
@ -1769,7 +1771,8 @@ static void start_record()
rendertarget_for_recording = new render_target(apple2_screen_width * recording_scale, apple2_screen_height * recording_scale);
}
GifBegin(&gif_writer, "out.gif", apple2_screen_width * recording_scale, apple2_screen_height * recording_scale, 5);
GifBegin(&gif_writer, "out.gif", apple2_screen_width * recording_scale, apple2_screen_height * recording_scale, recording_frame_duration_hundredths);
event_queue.push_back({REQUEST_ITERATION_PERIOD_IN_MILLIS, recording_frame_duration_hundredths * 10});
gif_recording = true;
}
@ -1886,7 +1889,7 @@ void add_rendertarget_to_gif(double now, render_target *rt)
save_rgba_to_ppm(image_recorded, apple2_screen_width * recording_scale, apple2_screen_height * recording_scale, "screen.ppm");
}
GifWriteFrame(&gif_writer, image_recorded, apple2_screen_width * recording_scale, apple2_screen_height * recording_scale, 5, 8, true);
GifWriteFrame(&gif_writer, image_recorded, apple2_screen_width * recording_scale, apple2_screen_height * recording_scale, recording_frame_duration_hundredths, 8, true);
rt->stop_reading();
}

View File

@ -3,7 +3,13 @@
namespace APPLE2Einterface
{
enum EventType {NONE, KEYDOWN, KEYUP, RESET, REBOOT, PASTE, SPEED, QUIT, PAUSE, EJECT_FLOPPY, INSERT_FLOPPY};
enum EventType
{
NONE, KEYDOWN, KEYUP, RESET, REBOOT, PASTE, SPEED, QUIT, PAUSE, EJECT_FLOPPY, INSERT_FLOPPY,
REQUEST_ITERATION_PERIOD_IN_MILLIS, /* request fixed simulation time period between calls to iterate() */
WITHDRAW_ITERATION_PERIOD_REQUEST, /* withdraw request for fixed simulation time */
};
const int LEFT_SHIFT = 340;
const int LEFT_CONTROL = 341;