SCP: Added a SCREENSHOT command to record the video display window.
This commit is contained in:
parent
1d6c14be3d
commit
78399f10cb
4 changed files with 97 additions and 11 deletions
19
scp.c
19
scp.c
|
@ -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
1
scp.h
|
@ -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);
|
||||
|
||||
|
|
87
sim_video.c
87
sim_video.c
|
@ -65,15 +65,16 @@ char vid_release_key[64] = "Ctrl-Right-Shift";
|
|||
|
||||
*/
|
||||
|
||||
#define EVENT_REDRAW 1 /* redraw event for SDL */
|
||||
#define EVENT_CLOSE 2 /* close event for SDL */
|
||||
#define EVENT_CURSOR 3 /* new cursor for SDL */
|
||||
#define EVENT_WARP 4 /* warp mouse position for SDL */
|
||||
#define EVENT_DRAW 5 /* draw/blit region for SDL */
|
||||
#define EVENT_SHOW 6 /* show SDL capabilities */
|
||||
#define EVENT_OPEN 7 /* vid_open request */
|
||||
#define EVENT_EXIT 8 /* program exit */
|
||||
#define MAX_EVENTS 20 /* max events in queue */
|
||||
#define EVENT_REDRAW 1 /* redraw event for SDL */
|
||||
#define EVENT_CLOSE 2 /* close event for SDL */
|
||||
#define EVENT_CURSOR 3 /* new cursor for SDL */
|
||||
#define EVENT_WARP 4 /* warp mouse position for SDL */
|
||||
#define EVENT_DRAW 5 /* draw/blit region for SDL */
|
||||
#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 {
|
||||
SIM_KEY_EVENT events[MAX_EVENTS];
|
||||
|
@ -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.
|
||||
|
@ -187,8 +189,12 @@ while (1) {
|
|||
if (event.user.code == EVENT_SHOW)
|
||||
vid_show_video_event ();
|
||||
else {
|
||||
sim_printf ("main(): Unexpected User event: %d\n", event.user.code);
|
||||
break;
|
||||
if (event.user.code == EVENT_SCREENSHOT)
|
||||
vid_screenshot_event ();
|
||||
else {
|
||||
sim_printf ("main(): Unexpected User event: %d\n", event.user.code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) */
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Add table
Reference in a new issue