SCP: Added a SCREENSHOT command to record the video display window.

This commit is contained in:
Mark Pizzolato 2015-09-17 11:49:01 -07:00
parent 1d6c14be3d
commit 78399f10cb
4 changed files with 97 additions and 11 deletions

19
scp.c
View file

@ -1660,6 +1660,13 @@ ASSERT failure have several different actions:
#define HLP_EXIT "*Commands Exiting_The_Simulator"
"2Exiting The Simulator\n"
" EXIT (synonyms QUIT and BYE) returns control to the operating system.\n"
/***************** 80 character line width template *************************/
#define HLP_SCREENSHOT "*Commands Screenshot_Video_Window"
"2Screenshot Video Window\n"
" Simulators with Video devices display the simulated video in a window\n"
" on the local system. The contents of that display can be saved in a\n"
" file with the SCREENSHOT command:\n\n"
" SCREENSHOT screenshotfile.bmp\n"
#define HLP_SPAWN "*Commands Executing_System_Commands"
"2Executing System Commands\n"
" The simulator can execute operating system commands with the ! (spawn)\n"
@ -1722,6 +1729,9 @@ static CTAB cmd_table[] = {
{ "NOEXPECT", &expect_cmd, 0, HLP_EXPECT },
{ "!", &spawn_cmd, 0, HLP_SPAWN },
{ "HELP", &help_cmd, 0, HLP_HELP },
#if defined(USE_SIM_VIDEO)
{ "SCREENSHOT", &screenshot_cmd,0, HLP_SCREENSHOT },
#endif
{ NULL, NULL, 0 }
};
@ -2589,6 +2599,15 @@ printf ("\n");
return status;
}
/* Screenshot command */
t_stat screenshot_cmd (int32 flag, char *cptr)
{
if ((cptr == NULL) || (strlen (cptr) == 0))
return SCPE_ARG;
return vid_screenshot (cptr);
}
/* Echo command */
t_stat echo_cmd (int32 flag, char *cptr)

1
scp.h
View file

@ -97,6 +97,7 @@ t_stat assert_cmd (int32 flag, char *ptr);
t_stat send_cmd (int32 flag, char *ptr);
t_stat expect_cmd (int32 flag, char *ptr);
t_stat help_cmd (int32 flag, char *ptr);
t_stat screenshot_cmd (int32 flag, char *ptr);
t_stat spawn_cmd (int32 flag, char *ptr);
t_stat echo_cmd (int32 flag, char *ptr);

View file

@ -73,6 +73,7 @@ char vid_release_key[64] = "Ctrl-Right-Shift";
#define EVENT_SHOW 6 /* show SDL capabilities */
#define EVENT_OPEN 7 /* vid_open request */
#define EVENT_EXIT 8 /* program exit */
#define EVENT_SCREENSHOT 9 /* show SDL capabilities */
#define MAX_EVENTS 20 /* max events in queue */
typedef struct {
@ -94,6 +95,7 @@ typedef struct {
int vid_thread (void* arg);
int vid_video_events (void);
void vid_show_video_event (void);
void vid_screenshot_event (void);
/*
libSDL and libSDL2 have significantly different APIs.
@ -186,12 +188,16 @@ while (1) {
else {
if (event.user.code == EVENT_SHOW)
vid_show_video_event ();
else {
if (event.user.code == EVENT_SCREENSHOT)
vid_screenshot_event ();
else {
sim_printf ("main(): Unexpected User event: %d\n", event.user.code);
break;
}
}
}
}
else {
// sim_printf ("main(): Ignoring unexpected event: %d\n", event.type);
}
@ -1459,6 +1465,10 @@ if (0) while (SDL_PeepEvents (&event, 1, SDL_GETEVENT, SD
vid_show_video_event ();
event.user.code = 0; /* Mark as done */
}
if (event.user.code == EVENT_SCREENSHOT) {
vid_screenshot_event ();
event.user.code = 0; /* Mark as done */
}
if (event.user.code != 0) {
sim_printf ("vid_thread(): Unexpected user event code: %d\n", event.user.code);
}
@ -1818,6 +1828,55 @@ while (_show_stat == -1)
return _show_stat;
}
static t_stat _vid_screenshot (const char *filename)
{
if (!vid_active) {
sim_printf ("No video display is active\n");
return SCPE_UDIS | SCPE_NOMESSAGE;
}
#if SDL_MAJOR_VERSION == 1
SDL_SaveBMP(vid_image, filename);
#else
if (1) {
SDL_Surface *sshot = sim_end ? SDL_CreateRGBSurface(0, vid_width, vid_height, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000) :
SDL_CreateRGBSurface(0, vid_width, vid_height, 32, 0x0000ff00, 0x000ff000, 0xff000000, 0x000000ff) ;
SDL_RenderReadPixels(vid_renderer, NULL, SDL_PIXELFORMAT_ARGB8888, sshot->pixels, sshot->pitch);
SDL_SaveBMP(sshot, filename);
SDL_FreeSurface(sshot);
}
#endif
return SCPE_OK;
}
static t_stat _screenshot_stat;
static const char *_screenshot_filename;
void vid_screenshot_event (void)
{
_screenshot_stat = _vid_screenshot (_screenshot_filename);
}
t_stat vid_screenshot (const char *filename)
{
SDL_Event user_event;
_screenshot_stat = -1;
_screenshot_filename = filename;
user_event.type = SDL_USEREVENT;
user_event.user.code = EVENT_SCREENSHOT;
user_event.user.data1 = NULL;
user_event.user.data2 = NULL;
#if defined (SDL_MAIN_AVAILABLE)
SDL_PushEvent (&user_event);
#else
vid_screenshot_event ();
#endif
while (_screenshot_stat == -1)
SDL_Delay (20);
return _screenshot_stat;
}
#else /* !(defined(USE_SIM_VIDEO) && defined(HAVE_LIBSDL)) */
/* Non-implemented versions */
@ -1884,4 +1943,10 @@ t_stat vid_show_video (FILE* st, UNIT* uptr, int32 val, void* desc)
fprintf (st, "video support unavailable");
return SCPE_OK;
}
t_stat vid_screenshot (char *filename)
{
sim_printf ("video support unavailable\n");
return SCPE_NOFNC|SCPE_NOMESSAGE;
}
#endif /* defined(USE_SIM_VIDEO) */

View file

@ -183,6 +183,7 @@ t_stat vid_set_release_key (FILE* st, UNIT* uptr, int32 val, void* desc);
t_stat vid_show_release_key (FILE* st, UNIT* uptr, int32 val, void* desc);
t_stat vid_show_video (FILE* st, UNIT* uptr, int32 val, void* desc);
t_stat vid_show (FILE* st, DEVICE *dptr, UNIT* uptr, int32 val, char* desc);
t_stat vid_screenshot (const char *filename);
extern t_bool vid_active;
extern uint32 vid_mono_palette[2];