Added GIF recording and screenshot support.

This commit is contained in:
Reece Mackie 2020-04-30 14:47:06 +01:00
parent 0357230af8
commit c083aed903
4 changed files with 89 additions and 6 deletions

View File

@ -56,6 +56,12 @@ void App::Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ appli
CoreApplication::Suspending += ref new Windows::Foundation::EventHandler<Windows::ApplicationModel::SuspendingEventArgs^>(this, &App::OnSuspending);
CoreApplication::Resuming += ref new EventHandler<Platform::Object^>(this, &App::OnResuming);
// Store the app data directory
auto dataPath = Windows::Storage::ApplicationData::Current->LocalFolder->Path;
std::wstring dataPathW(dataPath->Begin());
static std::string dataPathA(dataPathW.begin(), dataPathW.end());
UWPSetDataPath(dataPathA.c_str());
}
void App::SetWindow(Windows::UI::Core::CoreWindow^ window)
@ -300,11 +306,13 @@ void App::OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::Susp
void App::OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args)
{
UWPResizeEvent(args->Size.Width, args->Size.Height);
args->Handled = true;
}
void App::OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args)
{
mWindowVisible = args->Visible;
args->Handled = true;
}
// Input event handlers
@ -319,6 +327,8 @@ void App::OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::C
if (props->IsMiddleButtonPressed) UWPMouseButtonEvent(MOUSE_MIDDLE_BUTTON, true);
if (props->IsRightButtonPressed) UWPMouseButtonEvent(MOUSE_RIGHT_BUTTON, true);
}
args->Handled = true;
}
void App::OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args)
@ -332,17 +342,21 @@ void App::OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::
if (!props->IsMiddleButtonPressed) UWPMouseButtonEvent(MOUSE_MIDDLE_BUTTON, false);
if (!props->IsRightButtonPressed) UWPMouseButtonEvent(MOUSE_RIGHT_BUTTON, false);
}
args->Handled = true;
}
void App::OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args)
{
UWPMouseWheelEvent(args->CurrentPoint->Properties->MouseWheelDelta);
args->Handled = true;
}
void App::OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args)
{
auto pos = args->CurrentPoint->Position;
UWPMousePosEvent((double)pos.X, (double)pos.Y);
args->Handled = true;
}
int App::GetRaylibKey(Windows::System::VirtualKey kVey)
@ -420,15 +434,18 @@ int App::GetRaylibKey(Windows::System::VirtualKey kVey)
void App::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
{
auto k = GetRaylibKey(args->VirtualKey);
auto controlState = (sender->GetKeyState(Windows::System::VirtualKey::Control) & Windows::UI::Core::CoreVirtualKeyStates::Down) == Windows::UI::Core::CoreVirtualKeyStates::Down;
if (k != -1)
UWPKeyDownEvent(k, true);
UWPKeyDownEvent(k, true, controlState);
args->Handled = true;
}
void App::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
{
auto k = GetRaylibKey(args->VirtualKey);
if (k != -1)
UWPKeyDownEvent(k, false);
UWPKeyDownEvent(k, false, false);
args->Handled = true;
}
// AppSource implementation

View File

@ -162,7 +162,7 @@
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<CompileAsWinRT>false</CompileAsWinRT>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;GRAPHICS_API_OPENGL_ES2;PLATFORM_UWP;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>SUPPORT_GIF_RECORDING;_CRT_SECURE_NO_WARNINGS;GRAPHICS_API_OPENGL_ES2;PLATFORM_UWP;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)packages\ANGLE.WindowsStore.2.1.13\Include;$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>

View File

@ -375,6 +375,11 @@ typedef struct CoreData {
const char *internalDataPath; // Android internal data path to write data (/data/data/<package>/files)
bool contextRebindRequired; // Used to know context rebind required
} Android;
#endif
#if defined(PLATFORM_UWP)
struct {
const char* internalDataPath; // UWP App data path
} UWP;
#endif
struct {
#if defined(PLATFORM_RPI)
@ -1891,6 +1896,10 @@ void TakeScreenshot(const char *fileName)
strcpy(path, CORE.Android.internalDataPath);
strcat(path, "/");
strcat(path, fileName);
#elif defined(PLATFORM_UWP)
strcpy(path, CORE.UWP.internalDataPath);
strcat(path, "/");
strcat(path, fileName);
#else
strcpy(path, fileName);
#endif
@ -5200,6 +5209,10 @@ bool UWPIsConfigured()
}
return pass;
}
void UWPSetDataPath(const char* path)
{
CORE.UWP.internalDataPath = path;
}
UWPQueryTimeFunc UWPGetQueryTimeFunc(void)
{
@ -5296,13 +5309,64 @@ void UWPMouseWheelEvent(int deltaY)
CORE.Input.Mouse.currentWheelMove = (int)deltaY;
}
void UWPKeyDownEvent(int key, bool down)
void UWPKeyDownEvent(int key, bool down, bool controlKey)
{
if (key == CORE.Input.Keyboard.exitKey && down)
{
// Time to close the window.
CORE.Window.shouldClose = true;
}// TODO: Could UWP possibly support GIF recording?
}
else if (key == KEY_F12 && down)
{
#if defined(SUPPORT_GIF_RECORDING)
if (controlKey)
{
if (gifRecording)
{
GifEnd();
gifRecording = false;
#if defined(PLATFORM_WEB)
// Download file from MEMFS (emscripten memory filesystem)
// saveFileFromMEMFSToDisk() function is defined in raylib/templates/web_shel/shell.html
emscripten_run_script(TextFormat("saveFileFromMEMFSToDisk('%s','%s')", TextFormat("screenrec%03i.gif", screenshotCounter - 1), TextFormat("screenrec%03i.gif", screenshotCounter - 1)));
#endif
TRACELOG(LOG_INFO, "SYSTEM: Finish animated GIF recording");
}
else
{
gifRecording = true;
gifFramesCounter = 0;
char path[512] = { 0 };
#if defined(PLATFORM_ANDROID)
strcpy(path, CORE.Android.internalDataPath);
strcat(path, TextFormat("./screenrec%03i.gif", screenshotCounter));
#elif defined(PLATFORM_UWP)
strcpy(path, CORE.UWP.internalDataPath);
strcat(path, TextFormat("./screenrec%03i.gif", screenshotCounter));
#else
strcpy(path, TextFormat("./screenrec%03i.gif", screenshotCounter));
#endif
// NOTE: delay represents the time between frames in the gif, if we capture a gif frame every
// 10 game frames and each frame trakes 16.6ms (60fps), delay between gif frames should be ~16.6*10.
GifBegin(path, CORE.Window.screen.width, CORE.Window.screen.height, (int)(GetFrameTime() * 10.0f), 8, false);
screenshotCounter++;
TRACELOG(LOG_INFO, "SYSTEM: Start animated GIF recording: %s", TextFormat("screenrec%03i.gif", screenshotCounter));
}
}
else
#endif // SUPPORT_GIF_RECORDING
#if defined(SUPPORT_SCREEN_CAPTURE)
{
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
screenshotCounter++;
}
#endif // SUPPORT_SCREEN_CAPTURE
}
else
{
CORE.Input.Keyboard.currentKeyState[key] = down;

View File

@ -36,6 +36,8 @@ extern "C" {
// Determine if UWP functions are set and ready for raylib's use.
bool UWPIsConfigured();
void UWPSetDataPath(const char* path);
// Function for getting program time.
typedef double(*UWPQueryTimeFunc)();
UWPQueryTimeFunc UWPGetQueryTimeFunc(void);
@ -71,7 +73,7 @@ void UWPSetMouseSetPosFunc(UWPMouseSetPosFunc func);
// This choice is made as platform-specific code is preferred to be kept away from raylib.h
// Call this when a Key is pressed or released.
void UWPKeyDownEvent(int key, bool down);
void UWPKeyDownEvent(int key, bool down, bool controlKey);
// Call when a mouse button state changes
void UWPMouseButtonEvent(int button, bool down);