Merge pull request #7930 from Mailaender/screenshot
Added a hotkey to take screenshots
This commit is contained in:
@@ -12,6 +12,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -328,6 +329,24 @@ namespace OpenRA
|
||||
return InvalidValueAction(value, fieldType, fieldName);
|
||||
}
|
||||
}
|
||||
else if (fieldType == typeof(ImageFormat))
|
||||
{
|
||||
switch (value.ToLowerInvariant())
|
||||
{
|
||||
case "bmp":
|
||||
return ImageFormat.Bmp;
|
||||
case "gif":
|
||||
return ImageFormat.Gif;
|
||||
case "jpg":
|
||||
case "jpeg":
|
||||
return ImageFormat.Jpeg;
|
||||
case "tif":
|
||||
case "tiff":
|
||||
return ImageFormat.Tiff;
|
||||
default:
|
||||
return ImageFormat.Png;
|
||||
}
|
||||
}
|
||||
else if (fieldType == typeof(bool))
|
||||
return ParseYesNo(value, fieldType, fieldName);
|
||||
else if (fieldType.IsArray)
|
||||
|
||||
@@ -12,6 +12,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -77,6 +78,11 @@ namespace OpenRA
|
||||
if (t == typeof(double))
|
||||
return ((double)v).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (t == typeof(ImageFormat))
|
||||
{
|
||||
return ((ImageFormat)v).ToString();
|
||||
}
|
||||
|
||||
if (t == typeof(Rectangle))
|
||||
{
|
||||
var r = (Rectangle)v;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
@@ -47,14 +48,14 @@ namespace OpenRA
|
||||
{
|
||||
IConnection connection = new NetworkConnection(host, port);
|
||||
if (recordReplay)
|
||||
connection = new ReplayRecorderConnection(connection, ChooseReplayFilename);
|
||||
connection = new ReplayRecorderConnection(connection, TimestampedFilename);
|
||||
|
||||
var om = new OrderManager(host, port, password, connection);
|
||||
JoinInner(om);
|
||||
return om;
|
||||
}
|
||||
|
||||
static string ChooseReplayFilename()
|
||||
static string TimestampedFilename()
|
||||
{
|
||||
return DateTime.UtcNow.ToString("OpenRA-yyyy-MM-ddTHHmmssZ");
|
||||
}
|
||||
@@ -399,6 +400,35 @@ namespace OpenRA
|
||||
public static void RunAfterTick(Action a) { delayedActions.Add(a); }
|
||||
public static void RunAfterDelay(int delay, Action a) { delayedActions.Add(a, delay); }
|
||||
|
||||
static void TakeScreenshotInner()
|
||||
{
|
||||
Log.Write("debug", "Taking screenshot");
|
||||
|
||||
Bitmap bitmap;
|
||||
using (new PerfTimer("Renderer.TakeScreenshot"))
|
||||
bitmap = Renderer.TakeScreenshot();
|
||||
|
||||
ThreadPool.QueueUserWorkItem(_ =>
|
||||
{
|
||||
var mod = ModData.Manifest.Mod;
|
||||
var directory = Platform.ResolvePath("^", "Screenshots", mod.Id, mod.Version);
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
var filename = TimestampedFilename();
|
||||
var format = Settings.Graphics.ScreenshotFormat;
|
||||
var extension = ImageCodecInfo.GetImageEncoders().FirstOrDefault(x => x.FormatID == format.Guid)
|
||||
.FilenameExtension.Split(';').First().ToLowerInvariant().Substring(1);
|
||||
var destination = Path.Combine(directory, string.Concat(filename, extension));
|
||||
|
||||
using (new PerfTimer("Save Screenshot ({0})".F(format)))
|
||||
bitmap.Save(destination, format);
|
||||
|
||||
bitmap.Dispose();
|
||||
|
||||
Game.RunAfterTick(() => Debug("Saved screenshot " + filename));
|
||||
});
|
||||
}
|
||||
|
||||
static void InnerLogicTick(OrderManager orderManager)
|
||||
{
|
||||
var tick = RunTime;
|
||||
@@ -482,6 +512,8 @@ namespace OpenRA
|
||||
InnerLogicTick(worldRenderer.World.OrderManager);
|
||||
}
|
||||
|
||||
public static bool TakeScreenshot = false;
|
||||
|
||||
static void RenderTick()
|
||||
{
|
||||
using (new PerfSample("render"))
|
||||
@@ -515,6 +547,12 @@ namespace OpenRA
|
||||
|
||||
using (new PerfSample("render_flip"))
|
||||
Renderer.EndFrame(new DefaultInputHandler(OrderManager.World));
|
||||
|
||||
if (TakeScreenshot)
|
||||
{
|
||||
TakeScreenshot = false;
|
||||
TakeScreenshotInner();
|
||||
}
|
||||
}
|
||||
|
||||
PerfHistory.Items["render"].Tick();
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace OpenRA
|
||||
|
||||
void Clear();
|
||||
void Present();
|
||||
Bitmap TakeScreenshot();
|
||||
void PumpInput(IInputHandler inputHandler);
|
||||
string GetClipboardText();
|
||||
void DrawPrimitives(PrimitiveType type, int firstVertex, int numVertices);
|
||||
|
||||
@@ -160,6 +160,11 @@ namespace OpenRA.Graphics
|
||||
DrawBatch(tempBuffer, 0, numVertices, type);
|
||||
}
|
||||
|
||||
public Bitmap TakeScreenshot()
|
||||
{
|
||||
return Device.TakeScreenshot();
|
||||
}
|
||||
|
||||
public void DrawBatch<T>(IVertexBuffer<T> vertices,
|
||||
int firstVertex, int numVertices, PrimitiveType type)
|
||||
where T : struct
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
@@ -94,6 +95,8 @@ namespace OpenRA
|
||||
|
||||
public string Language = "english";
|
||||
public string DefaultLanguage = "english";
|
||||
|
||||
public ImageFormat ScreenshotFormat = ImageFormat.Png;
|
||||
}
|
||||
|
||||
public class SoundSettings
|
||||
@@ -178,6 +181,7 @@ namespace OpenRA
|
||||
public Hotkey TogglePixelDoubleKey = new Hotkey(Keycode.PERIOD, Modifiers.None);
|
||||
|
||||
public Hotkey DevReloadChromeKey = new Hotkey(Keycode.C, Modifiers.Ctrl | Modifiers.Shift);
|
||||
public Hotkey TakeScreenshotKey = new Hotkey(Keycode.P, Modifiers.Ctrl);
|
||||
|
||||
public Hotkey Production01Key = new Hotkey(Keycode.F1, Modifiers.None);
|
||||
public Hotkey Production02Key = new Hotkey(Keycode.F2, Modifiers.None);
|
||||
|
||||
@@ -30,6 +30,14 @@ namespace OpenRA.Widgets
|
||||
ChromeProvider.Initialize(Game.ModData.Manifest.Chrome);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hk == Game.Settings.Keys.TakeScreenshotKey)
|
||||
{
|
||||
if (e.Event == KeyInputEvent.Down)
|
||||
Game.TakeScreenshot = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return base.HandleKeyPress(e);
|
||||
|
||||
@@ -464,7 +464,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
var hotkeys = new Dictionary<string, string>()
|
||||
{
|
||||
{ "DevReloadChromeKey", "Reload Chrome" }
|
||||
{ "DevReloadChromeKey", "Reload Chrome" },
|
||||
{ "TakeScreenshotKey", "Take screenshot" }
|
||||
};
|
||||
|
||||
var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing);
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace OpenRA.Renderer.Null
|
||||
|
||||
public void Clear() { }
|
||||
public void Present() { }
|
||||
public Bitmap TakeScreenshot() { return new Bitmap(1, 1); }
|
||||
|
||||
public string GetClipboardText() { return ""; }
|
||||
public void PumpInput(IInputHandler ih)
|
||||
|
||||
@@ -330,6 +330,31 @@ namespace OpenRA.Renderer.Sdl2
|
||||
ErrorHandler.CheckGlError();
|
||||
}
|
||||
|
||||
public Bitmap TakeScreenshot()
|
||||
{
|
||||
var rect = new Rectangle(Point.Empty, size);
|
||||
var bitmap = new Bitmap(rect.Width, rect.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
var data = bitmap.LockBits(rect,
|
||||
System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
|
||||
GL.PushClientAttrib(ClientAttribMask.ClientPixelStoreBit);
|
||||
|
||||
GL.PixelStore(PixelStoreParameter.PackRowLength, data.Stride / 4f);
|
||||
GL.PixelStore(PixelStoreParameter.PackAlignment, 1);
|
||||
|
||||
GL.ReadPixels(rect.X, rect.Y, rect.Width, rect.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
|
||||
GL.Finish();
|
||||
|
||||
GL.PopClientAttrib();
|
||||
|
||||
bitmap.UnlockBits(data);
|
||||
|
||||
// OpenGL standard defines the origin in the bottom left corner which is why this is upside-down by default.
|
||||
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public void Present() { SDL.SDL_GL_SwapWindow(window); }
|
||||
public void PumpInput(IInputHandler inputHandler) { input.PumpInput(inputHandler); }
|
||||
public string GetClipboardText() { return input.GetClipboardText(); }
|
||||
|
||||
Reference in New Issue
Block a user