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 pixels(infoSurface->w * infoSurface->h * infoSurface->format->BytesPerPixel); + int errorCode = SDL_RenderReadPixels(globalData.screen, &infoSurface->clip_rect, infoSurface->format->format, static_cast(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(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;