git repos / saland

commit 8ed0dc99

Poul Sander · 2021-06-01 18:57
8ed0dc99608a98f8d4dc727823458be6ade98181 patch · browse files
parent e5011b5ba18473e1ea136b796b3a0e6a015d7521

Add screenshot feature on F9

Changed files

A data/sounds/AUTH
A data/sounds/cameraclick.ogg
A data/sounds/pop.ogg
A data/sounds/typing.ogg
M src/os.cpp before
M src/os.hpp before
M src/saland.cpp before
diff --git a/data/sounds/AUTH b/data/sounds/AUTH new file mode 100644 index 0000000..8da0fb9 --- /dev/null +++ b/data/sounds/AUTH
@@ -0,0 +1,5 @@
+/sound/
+pop.ogg openarena-svn887:/sound/weapons/rocket/rockf1a.wav
+cameraclick.ogg openarean-svn887:/sound/misc/w_pkup.wav
+typing.ogg openarena-svn887:/sound/world/clack.wav
+
diff --git a/data/sounds/cameraclick.ogg b/data/sounds/cameraclick.ogg new file mode 100644 index 0000000..0c1f9a9
Binary files /dev/null and b/data/sounds/cameraclick.ogg differ
diff --git a/data/sounds/pop.ogg b/data/sounds/pop.ogg new file mode 100644 index 0000000..9e9fc51
Binary files /dev/null and b/data/sounds/pop.ogg differ
diff --git a/data/sounds/typing.ogg b/data/sounds/typing.ogg new file mode 100644 index 0000000..83d95c9
Binary files /dev/null and b/data/sounds/typing.ogg differ
diff --git a/src/os.cpp b/src/os.cpp index 413982c..2536021 100644 --- a/src/os.cpp +++ b/src/os.cpp
@@ -49,6 +49,31 @@ void setPathToSaveFiles(const std::string& path) {
overrideSavePath = path;
}
+bool OsPathIsRelative(const std::string& path) {
+#if defined(_WIN32)
+ return PathIsRelativeW(win32_utf8_to_utf16(path.c_str()).c_str());
+#else
+ return path[0] != '/';
+#endif
+}
+
+void OsCreateFolder(const std::string& path) {
+#if defined(__unix__)
+ std::string cmd = "mkdir -p '"+path+"/'";
+ int retcode = system(cmd.c_str());
+ if (retcode != 0) {
+ std::cerr << "Failed to create: " << path+"/" << "\n";
+ }
+#elif defined(_WIN32)
+ //Now for Windows NT/2k/xp/2k3 etc.
+ CreateDirectoryW(win32_utf8_to_utf16(pf.getSaveGamesFolder1().c_str()).c_str(), nullptr);
+ std::string tempA = path;
+ CreateDirectoryW(win32_utf8_to_utf16(tempA.c_str()).c_str(), nullptr);
+#else
+ std::cerr << "Failed to create: \"" << path << "\"\n";
+#endif
+}
+
void OsCreateSaveFolder() {
#if defined(__unix__)
std::string cmd = "mkdir -p '"+getPathToSaveFiles()+"/'";
diff --git a/src/os.hpp b/src/os.hpp index 5a3f681..309003c 100644 --- a/src/os.hpp +++ b/src/os.hpp
@@ -35,3 +35,13 @@ std::string getMyDocumentsPath();
void setPathToSaveFiles(const std::string& path);
void OsCreateSaveFolder();
+
+bool OsPathIsRelative(const std::string& path);
+
+/**
+ * Create a folder
+ * The folder path is created recursively
+ * Fails silently if failing to create the path
+ * @param path The folder to create
+ */
+void OsCreateFolder(const std::string& path);
diff --git a/src/saland.cpp b/src/saland.cpp index 1f2e2bf..39ebac3 100644 --- a/src/saland.cpp +++ b/src/saland.cpp
@@ -128,6 +128,54 @@ private:
sago::SagoTextBox testBox;
};
+
+std::string pathToScreenShots() {
+ Config::getInstance()->setDefault("screenshot_dir", "screenshots");
+ std::string screenshot_dir = Config::getInstance()->getString("screenshot_dir");
+ if (OsPathIsRelative(screenshot_dir)) {
+ return getPathToSaveFiles() + "/" + screenshot_dir;
+ }
+ return screenshot_dir;
+}
+
+static SDL_Window* win = nullptr;
+
+//writeScreenShot saves the screen as a bmp file, it uses the time to get a unique filename
+void writeScreenShot() {
+ if (globalData.verboseLevel) {
+ std::cout << "Saving screenshot" << "\n";
+ }
+ int rightNow = (int)time(nullptr);
+ SDL_Surface* infoSurface = SDL_GetWindowSurface(win);
+ if (!infoSurface) {
+ std::cerr << "Could not get infoSurface. No screenshot written. Be aware that the screenshot feature only works with software render\n";
+ return;
+ }
+ std::vector<char> pixels(infoSurface->w * infoSurface->h * infoSurface->format->BytesPerPixel);
+ int errorCode = SDL_RenderReadPixels(globalData.screen, &infoSurface->clip_rect, infoSurface->format->format, static_cast<void*>(pixels.data()), infoSurface->w * infoSurface->format->BytesPerPixel);
+ if (errorCode) {
+ SDL_FreeSurface(infoSurface);
+ std::cerr << "Could not do SDL_RenderReadPixels. Error code: " << errorCode << ". No screenshot written\n";
+ return;
+ }
+ SDL_Surface* sreenshotSurface = SDL_CreateRGBSurfaceFrom(static_cast<void*>(pixels.data()), infoSurface->w, infoSurface->h, infoSurface->format->BitsPerPixel, infoSurface->w * infoSurface->format->BytesPerPixel, infoSurface->format->Rmask, infoSurface->format->Gmask, infoSurface->format->Bmask, infoSurface->format->Amask);
+ SDL_FreeSurface(infoSurface);
+ if (!sreenshotSurface) {
+ std::cerr << "Could not get sreenshotSurface. No screenshot written\n";
+ return;
+ }
+ OsCreateFolder(pathToScreenShots());
+ std::string buf = pathToScreenShots() + "/screenshot"+std::to_string(rightNow)+".bmp";
+ SDL_SaveBMP(sreenshotSurface, buf.c_str());
+ SDL_FreeSurface(sreenshotSurface);
+ if (!globalData.NoSound) {
+ if (globalData.SoundEnabled) {
+ Mix_PlayChannel(1, globalData.dataHolder->getSoundHandler("cameraclick").get(), 0);
+ }
+ }
+}
+
+
/**
* This function reads the mouse coordinates from a relevant event.
* Unlike SDL_GetMouseState this works even if SDL_RenderSetLogicalSize is used
@@ -166,6 +214,7 @@ void RunGameState(sago::GameStateInterface& state ) {
SDL_Delay(1);
SDL_Event event;
+ bool mustWriteScreenshot = false;
while ( SDL_PollEvent(&event) ) {
if ( event.type == SDL_QUIT ) {
@@ -183,8 +232,14 @@ void RunGameState(sago::GameStateInterface& state ) {
globalData.fullscreen = !globalData.fullscreen;
globalData.resetVideo = true;
}
+ if ( event.key.keysym.sym == SDLK_F9 ) {
+ mustWriteScreenshot = true;
+ }
}
+ if (mustWriteScreenshot) {
+ writeScreenShot();
+ }
bool processed = false;
state.ProcessInput(event, processed);
@@ -206,7 +261,6 @@ void startWorld() {
RunGameState(g);
}
-static SDL_Window* win = nullptr;
void ResetFullscreen() {
sago::SagoDataHolder& dataHolder = *globalData.dataHolder;