Changeset View
Changeset View
Standalone View
Standalone View
source/ps/Util.cpp
Show All 31 Lines | ||||||||||||||||||||||
#include "lib/sysdep/arch/x86_x64/topology.h" | #include "lib/sysdep/arch/x86_x64/topology.h" | |||||||||||||||||||||
#endif | #endif | |||||||||||||||||||||
#include "lib/sysdep/smbios.h" | #include "lib/sysdep/smbios.h" | |||||||||||||||||||||
#include "lib/tex/tex.h" | #include "lib/tex/tex.h" | |||||||||||||||||||||
#include "i18n/L10n.h" | #include "i18n/L10n.h" | |||||||||||||||||||||
#include "lib/utf8.h" | #include "lib/utf8.h" | |||||||||||||||||||||
#include "ps/ConfigDB.h" | ||||||||||||||||||||||
#include "ps/GameSetup/Config.h" | #include "ps/GameSetup/Config.h" | |||||||||||||||||||||
#include "ps/GameSetup/GameSetup.h" | #include "ps/GameSetup/GameSetup.h" | |||||||||||||||||||||
#include "ps/Game.h" | #include "ps/Game.h" | |||||||||||||||||||||
#include "ps/CLogger.h" | #include "ps/CLogger.h" | |||||||||||||||||||||
#include "ps/Filesystem.h" | #include "ps/Filesystem.h" | |||||||||||||||||||||
#include "ps/Pyrogenesis.h" | #include "ps/Pyrogenesis.h" | |||||||||||||||||||||
#include "ps/VideoMode.h" | #include "ps/VideoMode.h" | |||||||||||||||||||||
#include "renderer/Renderer.h" | #include "renderer/Renderer.h" | |||||||||||||||||||||
▲ Show 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | const wchar_t* ErrorString(int err) | |||||||||||||||||||||
// TODO: load from language file | // TODO: load from language file | |||||||||||||||||||||
} | } | |||||||||||||||||||||
// write the specified texture to disk. | // write the specified texture to disk. | |||||||||||||||||||||
// note: <t> cannot be made const because the image may have to be | // note: <t> cannot be made const because the image may have to be | |||||||||||||||||||||
// transformed to write it out in the format determined by <fn>'s extension. | // transformed to write it out in the format determined by <fn>'s extension. | |||||||||||||||||||||
Status tex_write(Tex* t, const VfsPath& filename) | Status tex_write(Tex* t, const VfsPath& filename, int quality) | |||||||||||||||||||||
{ | { | |||||||||||||||||||||
DynArray da; | DynArray da; | |||||||||||||||||||||
RETURN_STATUS_IF_ERR(t->encode(filename.Extension(), &da)); | RETURN_STATUS_IF_ERR(t->encode(filename.Extension(), &da, quality)); | |||||||||||||||||||||
// write to disk | // write to disk | |||||||||||||||||||||
Status ret = INFO::OK; | Status ret = INFO::OK; | |||||||||||||||||||||
{ | { | |||||||||||||||||||||
std::shared_ptr<u8> file = DummySharedPtr(da.base); | std::shared_ptr<u8> file = DummySharedPtr(da.base); | |||||||||||||||||||||
const ssize_t bytes_written = g_VFS->CreateFile(filename, file, da.pos); | const ssize_t bytes_written = g_VFS->CreateFile(filename, file, da.pos); | |||||||||||||||||||||
if(bytes_written > 0) | if(bytes_written > 0) | |||||||||||||||||||||
ENSURE(bytes_written == (ssize_t)da.pos); | ENSURE(bytes_written == (ssize_t)da.pos); | |||||||||||||||||||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | ||||||||||||||||||||||
// <extension> identifies the file format that is to be written | // <extension> identifies the file format that is to be written | |||||||||||||||||||||
// (case-insensitive). examples: "bmp", "png", "jpg". | // (case-insensitive). examples: "bmp", "png", "jpg". | |||||||||||||||||||||
// BMP is good for quick output at the expense of large files. | // BMP is good for quick output at the expense of large files. | |||||||||||||||||||||
void WriteScreenshot(const VfsPath& extension) | void WriteScreenshot(const VfsPath& extension) | |||||||||||||||||||||
{ | { | |||||||||||||||||||||
// get next available numbered filename | // get next available numbered filename | |||||||||||||||||||||
// note: %04d -> always 4 digits, so sorting by filename works correctly. | // note: %04d -> always 4 digits, so sorting by filename works correctly. | |||||||||||||||||||||
const VfsPath basenameFormat(L"screenshots/screenshot%04d"); | const VfsPath basenameFormat(L"screenshots/videoscreen%04d"); | |||||||||||||||||||||
const VfsPath filenameFormat = basenameFormat.ChangeExtension(extension); | const VfsPath filenameFormat = basenameFormat.ChangeExtension(extension); | |||||||||||||||||||||
VfsPath filename; | VfsPath filename; | |||||||||||||||||||||
vfs::NextNumberedFilename(g_VFS, filenameFormat, s_nextScreenshotNumber, filename); | vfs::NextNumberedFilename(g_VFS, filenameFormat, s_nextScreenshotNumber, filename); | |||||||||||||||||||||
const size_t w = (size_t)g_xres, h = (size_t)g_yres; | const size_t w = (size_t)g_xres, h = (size_t)g_yres; | |||||||||||||||||||||
const size_t bpp = 24; | const size_t bpp = 24; | |||||||||||||||||||||
GLenum fmt = GL_RGB; | GLenum fmt = GL_RGB; | |||||||||||||||||||||
int flags = TEX_BOTTOM_UP; | int flags = TEX_BOTTOM_UP; | |||||||||||||||||||||
Show All 17 Lines | #endif | |||||||||||||||||||||
std::shared_ptr<u8> buf; | std::shared_ptr<u8> buf; | |||||||||||||||||||||
AllocateAligned(buf, hdr_size+img_size, maxSectorSize); | AllocateAligned(buf, hdr_size+img_size, maxSectorSize); | |||||||||||||||||||||
GLvoid* img = buf.get() + hdr_size; | GLvoid* img = buf.get() + hdr_size; | |||||||||||||||||||||
Tex t; | Tex t; | |||||||||||||||||||||
if(t.wrap(w, h, bpp, flags, buf, hdr_size) < 0) | if(t.wrap(w, h, bpp, flags, buf, hdr_size) < 0) | |||||||||||||||||||||
return; | return; | |||||||||||||||||||||
glReadPixels(0, 0, (GLsizei)w, (GLsizei)h, fmt, GL_UNSIGNED_BYTE, img); | glReadPixels(0, 0, (GLsizei)w, (GLsizei)h, fmt, GL_UNSIGNED_BYTE, img); | |||||||||||||||||||||
if (tex_write(&t, filename) == INFO::OK) | int quality; | |||||||||||||||||||||
CFG_GET_VAL("videorendering.jpeg_quality", quality); | ||||||||||||||||||||||
Stan: Might be smart not to get this at every frame. | ||||||||||||||||||||||
if (tex_write(&t, filename, quality) == INFO::OK) | ||||||||||||||||||||||
{ | { | |||||||||||||||||||||
OsPath realPath; | OsPath realPath; | |||||||||||||||||||||
g_VFS->GetRealPath(filename, realPath); | g_VFS->GetRealPath(filename, realPath); | |||||||||||||||||||||
LOGMESSAGERENDER(g_L10n.Translate("Screenshot written to '%s'"), realPath.string8()); | ||||||||||||||||||||||
debug_printf( | debug_printf( | |||||||||||||||||||||
CStr(g_L10n.Translate("Screenshot written to '%s'") + "\n").c_str(), | CStr(g_L10n.Translate("Screenshot written to '%s'") + "\n").c_str(), | |||||||||||||||||||||
realPath.string8().c_str()); | realPath.string8().c_str()); | |||||||||||||||||||||
} | } | |||||||||||||||||||||
else | else | |||||||||||||||||||||
LOGERROR("Error writing screenshot to '%s'", filename.string8()); | LOGERROR("Error writing screenshot to '%s'", filename.string8()); | |||||||||||||||||||||
Not Done Inline Actions
Nuke this for moar speed. Stan: Nuke this for moar speed. | ||||||||||||||||||||||
} | } | |||||||||||||||||||||
// Similar to WriteScreenshot, but generates an image of size tileWidth*tiles x tileHeight*tiles. | // Similar to WriteScreenshot, but generates an image of size tileWidth*tiles x tileHeight*tiles. | |||||||||||||||||||||
void WriteBigScreenshot(const VfsPath& extension, int tiles, int tileWidth, int tileHeight) | void WriteBigScreenshot(const VfsPath& extension, int tiles, int tileWidth, int tileHeight) | |||||||||||||||||||||
{ | { | |||||||||||||||||||||
// If the game hasn't started yet then use WriteScreenshot to generate the image. | // If the game hasn't started yet then use WriteScreenshot to generate the image. | |||||||||||||||||||||
▲ Show 20 Lines • Show All 119 Lines • ▼ Show 20 Lines | #endif | |||||||||||||||||||||
// Restore the viewport settings | // Restore the viewport settings | |||||||||||||||||||||
{ | { | |||||||||||||||||||||
g_Renderer.Resize(g_xres, g_yres); | g_Renderer.Resize(g_xres, g_yres); | |||||||||||||||||||||
SViewPort vp = { 0, 0, g_xres, g_yres }; | SViewPort vp = { 0, 0, g_xres, g_yres }; | |||||||||||||||||||||
g_Game->GetView()->SetViewport(vp); | g_Game->GetView()->SetViewport(vp); | |||||||||||||||||||||
g_Game->GetView()->GetCamera()->SetProjectionFromCamera(oldCamera); | g_Game->GetView()->GetCamera()->SetProjectionFromCamera(oldCamera); | |||||||||||||||||||||
} | } | |||||||||||||||||||||
if (tex_write(&t, filename) == INFO::OK) | if (tex_write(&t, filename, 100) == INFO::OK) | |||||||||||||||||||||
{ | { | |||||||||||||||||||||
OsPath realPath; | OsPath realPath; | |||||||||||||||||||||
g_VFS->GetRealPath(filename, realPath); | g_VFS->GetRealPath(filename, realPath); | |||||||||||||||||||||
LOGMESSAGERENDER(g_L10n.Translate("Screenshot written to '%s'"), realPath.string8()); | ||||||||||||||||||||||
debug_printf( | debug_printf( | |||||||||||||||||||||
CStr(g_L10n.Translate("Screenshot written to '%s'") + "\n").c_str(), | CStr(g_L10n.Translate("Screenshot written to '%s'") + "\n").c_str(), | |||||||||||||||||||||
realPath.string8().c_str()); | realPath.string8().c_str()); | |||||||||||||||||||||
} | } | |||||||||||||||||||||
else | else | |||||||||||||||||||||
LOGERROR("Error writing screenshot to '%s'", filename.string8()); | LOGERROR("Error writing screenshot to '%s'", filename.string8()); | |||||||||||||||||||||
free(tile_data); | free(tile_data); | |||||||||||||||||||||
Show All 19 Lines |
Wildfire Games · Phabricator
Might be smart not to get this at every frame.