add a take screenshot hotkey

This commit is contained in:
Matthias Mailänder
2015-04-12 10:34:08 +02:00
parent fc7df415d7
commit 2763e26d23
10 changed files with 111 additions and 3 deletions

View File

@@ -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)

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);

View File

@@ -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

View File

@@ -10,6 +10,7 @@
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using OpenRA.Graphics;
@@ -93,6 +94,8 @@ namespace OpenRA
public string Language = "english";
public string DefaultLanguage = "english";
public ImageFormat ScreenshotFormat = ImageFormat.Png;
}
public class SoundSettings
@@ -177,6 +180,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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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)

View File

@@ -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(); }