diff --git a/Sources/Plasma/FeatureLib/pfConsole/pfConsole.cpp b/Sources/Plasma/FeatureLib/pfConsole/pfConsole.cpp index a1238484..827e01ad 100644 --- a/Sources/Plasma/FeatureLib/pfConsole/pfConsole.cpp +++ b/Sources/Plasma/FeatureLib/pfConsole/pfConsole.cpp @@ -45,26 +45,29 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com // // ////////////////////////////////////////////////////////////////////////////// -#include "pfPython/cyPythonInterface.h" - -#include "HeadSpin.h" #include "pfConsole.h" #include "pfConsoleCore/pfConsoleEngine.h" -#include "plPipeline/plDebugText.h" + +#include "HeadSpin.h" +#include "plFileSystem.h" +#include "plgDispatch.h" +#include "plPipeline.h" +#include "hsTimer.h" + +#include "plGImage/plPNG.h" #include "plInputCore/plInputDevice.h" #include "plInputCore/plInputInterface.h" #include "plInputCore/plInputInterfaceMgr.h" -#include "pnInputCore/plKeyMap.h" #include "pnInputCore/plKeyDef.h" +#include "pnInputCore/plKeyMap.h" +#include "pnKeyedObject/plFixedKey.h" #include "plMessage/plInputEventMsg.h" +#include "plMessage/plCaptureRenderMsg.h" #include "plMessage/plConsoleMsg.h" #include "plMessage/plInputIfaceMgrMsg.h" -#include "pnKeyedObject/plFixedKey.h" -#include "hsTimer.h" -#include "plgDispatch.h" -#include "plPipeline.h" - #include "plNetClient/plNetClientMgr.h" +#include "plPipeline/plDebugText.h" +#include "pfPython/cyPythonInterface.h" #ifndef PLASMA_EXTERNAL_RELEASE #include "pfGameMgr/pfGameMgr.h" @@ -265,8 +268,42 @@ void pfConsole::ISetMode( uint8_t mode ) //// MsgReceive ////////////////////////////////////////////////////////////// +#include bool pfConsole::MsgReceive( plMessage *msg ) { + // Handle screenshot saving... + plCaptureRenderMsg* capMsg = plCaptureRenderMsg::ConvertNoRef(msg); + if (capMsg) { + plFileName screenshots = plFileName::Join(plFileSystem::GetUserDataPath(), "Screenshots"); + plFileSystem::CreateDir(screenshots, false); // just in case... + plString prefix = plProduct::ShortName(); + + // List all of the PNG indices we have taken up already... + plString pattern = plString::Format("%s*.png", prefix.c_str()); + std::vector images = plFileSystem::ListDir(screenshots, pattern.c_str()); + std::set indices; + std::for_each(images.begin(), images.end(), + [&] (const plFileName& fn) { + plString idx = fn.GetFileNameNoExt().Substr(prefix.GetSize()); + indices.insert(idx.ToUInt(10)); + } + ); + + // Now that we have an ordered set of indices, save this screenshot to the first one we don't have. + uint32_t num = 0; + for (auto it = indices.begin(); it != indices.end(); ++it, ++num) { + if (*it != num) + break; + } + + // Got our num, save the screenshot. + plFileName fn = plString::Format("%s%04d.png", prefix.c_str(), num); + plPNG::Instance().WriteToFile(plFileName::Join(screenshots, fn), capMsg->GetMipmap()); + + AddLineF("Saved screenshot as '%s'", fn.AsString().c_str()); + return true; + } + plControlEventMsg *ctrlMsg = plControlEventMsg::ConvertNoRef( msg ); if( ctrlMsg != nil ) { diff --git a/Sources/Plasma/FeatureLib/pfConsole/pfGameConsoleCommands.cpp b/Sources/Plasma/FeatureLib/pfConsole/pfGameConsoleCommands.cpp index 36fe5e5e..6cbfbcdf 100644 --- a/Sources/Plasma/FeatureLib/pfConsole/pfGameConsoleCommands.cpp +++ b/Sources/Plasma/FeatureLib/pfConsole/pfGameConsoleCommands.cpp @@ -72,19 +72,20 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "pfConsoleCore/pfConsoleCmd.h" #include "pfConsole.h" -#include "plPipeline.h" #include "plgDispatch.h" -#include "plGImage/plMipmap.h" -#include "plGImage/plTGAWriter.h" -#include "pfMessage/pfGameGUIMsg.h" +#include "plPipeline.h" #include "hsResMgr.h" -#include "pfGameGUIMgr/pfGUICtrlGenerator.h" -#include "plAvatar/plAvatarMgr.h" + #include "plAvatar/plAnimStage.h" #include "plAvatar/plAvBrainGeneric.h" #include "plAvatar/plAvBrainHuman.h" -#include "plMessage/plAvatarMsg.h" +#include "plAvatar/plAvatarMgr.h" +#include "plGImage/plMipmap.h" +#include "pfGameGUIMgr/pfGUICtrlGenerator.h" #include "pnKeyedObject/plFixedKey.h" +#include "plMessage/plAvatarMsg.h" +#include "pfMessage/pfGameGUIMsg.h" +#include "plPipeline/plCaptureRender.h" #define PF_SANITY_CHECK( cond, msg ) { if( !( cond ) ) { PrintString( msg ); return; } } @@ -115,52 +116,19 @@ static bool plDoesFileExist( const char *path ) PF_CONSOLE_GROUP( Game ) -#ifndef LIMIT_CONSOLE_COMMANDS -PF_CONSOLE_CMD( Game, TakeScreenshot, "...", "Takes a shot of the current frame and saves it to the given file" ) +PF_CONSOLE_CMD( Game, TakeScreenshot, "int width, int height", "Captures a screenshot" ) { - hsAssert( pfConsole::GetPipeline() != nil, "Cannot use this command before pipeline initialization" ); - - plMipmap myMipmap; - char fileName[ 512 ]; - uint32_t uniqueNumber; - - - if( numParams > 1 ) - { - PrintString( "Too many parameters to TakeScreenshot" ); - return; - } - else if( numParams == 1 ) - strcpy( fileName, (char *)params[ 0 ] ); - else - { - // Think up a filename - for( uniqueNumber = 1; uniqueNumber < 1000; uniqueNumber++ ) - { - sprintf( fileName, "screen%03d.tga", uniqueNumber ); - if( !plDoesFileExist( fileName ) ) - break; - } - if( uniqueNumber == 1000 ) - { - PrintString( "Out of filenames for TakeScreenshot" ); - return; - } - } - - if( !pfConsole::GetPipeline()->CaptureScreen( &myMipmap ) ) - PrintString( "Error capturing screenshot" ); - else - { - char str[ 512 ]; + hsAssert(pfConsole::GetPipeline(), "Game.TakeScreenShot needs a plPipeline!"); + int width = params[0]; + int height = params[1]; - plTGAWriter::Instance().WriteMipmap( fileName, &myMipmap ); - sprintf( str, "Screenshot written to '%s'.", fileName ); - PrintString( str ); - } + // Let's use plCaptureRender so that we have a really nice image. + // We'll take care of saving in pfConsole::MsgReceive + plCaptureRender::Capture(pfConsole::GetInstance()->GetKey(), width, height); } +#ifndef LIMIT_CONSOLE_COMMANDS PF_CONSOLE_CMD( Game, LoadDialog, "string dlgName", "Loads the given GUI dialog into memory" ) { plUoid lu( kGameGUIMgr_KEY );