add a take screenshot hotkey
This commit is contained in:
@@ -12,6 +12,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@@ -328,6 +329,24 @@ namespace OpenRA
|
|||||||
return InvalidValueAction(value, fieldType, fieldName);
|
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))
|
else if (fieldType == typeof(bool))
|
||||||
return ParseYesNo(value, fieldType, fieldName);
|
return ParseYesNo(value, fieldType, fieldName);
|
||||||
else if (fieldType.IsArray)
|
else if (fieldType.IsArray)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@@ -77,6 +78,11 @@ namespace OpenRA
|
|||||||
if (t == typeof(double))
|
if (t == typeof(double))
|
||||||
return ((double)v).ToString(CultureInfo.InvariantCulture);
|
return ((double)v).ToString(CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
|
if (t == typeof(ImageFormat))
|
||||||
|
{
|
||||||
|
return ((ImageFormat)v).ToString();
|
||||||
|
}
|
||||||
|
|
||||||
if (t == typeof(Rectangle))
|
if (t == typeof(Rectangle))
|
||||||
{
|
{
|
||||||
var r = (Rectangle)v;
|
var r = (Rectangle)v;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
@@ -47,14 +48,14 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
IConnection connection = new NetworkConnection(host, port);
|
IConnection connection = new NetworkConnection(host, port);
|
||||||
if (recordReplay)
|
if (recordReplay)
|
||||||
connection = new ReplayRecorderConnection(connection, ChooseReplayFilename);
|
connection = new ReplayRecorderConnection(connection, TimestampedFilename);
|
||||||
|
|
||||||
var om = new OrderManager(host, port, password, connection);
|
var om = new OrderManager(host, port, password, connection);
|
||||||
JoinInner(om);
|
JoinInner(om);
|
||||||
return om;
|
return om;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string ChooseReplayFilename()
|
static string TimestampedFilename()
|
||||||
{
|
{
|
||||||
return DateTime.UtcNow.ToString("OpenRA-yyyy-MM-ddTHHmmssZ");
|
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 RunAfterTick(Action a) { delayedActions.Add(a); }
|
||||||
public static void RunAfterDelay(int delay, Action a) { delayedActions.Add(a, delay); }
|
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)
|
static void InnerLogicTick(OrderManager orderManager)
|
||||||
{
|
{
|
||||||
var tick = RunTime;
|
var tick = RunTime;
|
||||||
@@ -482,6 +512,8 @@ namespace OpenRA
|
|||||||
InnerLogicTick(worldRenderer.World.OrderManager);
|
InnerLogicTick(worldRenderer.World.OrderManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool TakeScreenshot = false;
|
||||||
|
|
||||||
static void RenderTick()
|
static void RenderTick()
|
||||||
{
|
{
|
||||||
using (new PerfSample("render"))
|
using (new PerfSample("render"))
|
||||||
@@ -515,6 +547,12 @@ namespace OpenRA
|
|||||||
|
|
||||||
using (new PerfSample("render_flip"))
|
using (new PerfSample("render_flip"))
|
||||||
Renderer.EndFrame(new DefaultInputHandler(OrderManager.World));
|
Renderer.EndFrame(new DefaultInputHandler(OrderManager.World));
|
||||||
|
|
||||||
|
if (TakeScreenshot)
|
||||||
|
{
|
||||||
|
TakeScreenshot = false;
|
||||||
|
TakeScreenshotInner();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PerfHistory.Items["render"].Tick();
|
PerfHistory.Items["render"].Tick();
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
void Present();
|
void Present();
|
||||||
|
Bitmap TakeScreenshot();
|
||||||
void PumpInput(IInputHandler inputHandler);
|
void PumpInput(IInputHandler inputHandler);
|
||||||
string GetClipboardText();
|
string GetClipboardText();
|
||||||
void DrawPrimitives(PrimitiveType type, int firstVertex, int numVertices);
|
void DrawPrimitives(PrimitiveType type, int firstVertex, int numVertices);
|
||||||
|
|||||||
@@ -160,6 +160,11 @@ namespace OpenRA.Graphics
|
|||||||
DrawBatch(tempBuffer, 0, numVertices, type);
|
DrawBatch(tempBuffer, 0, numVertices, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Bitmap TakeScreenshot()
|
||||||
|
{
|
||||||
|
return Device.TakeScreenshot();
|
||||||
|
}
|
||||||
|
|
||||||
public void DrawBatch<T>(IVertexBuffer<T> vertices,
|
public void DrawBatch<T>(IVertexBuffer<T> vertices,
|
||||||
int firstVertex, int numVertices, PrimitiveType type)
|
int firstVertex, int numVertices, PrimitiveType type)
|
||||||
where T : struct
|
where T : struct
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
@@ -93,6 +94,8 @@ namespace OpenRA
|
|||||||
|
|
||||||
public string Language = "english";
|
public string Language = "english";
|
||||||
public string DefaultLanguage = "english";
|
public string DefaultLanguage = "english";
|
||||||
|
|
||||||
|
public ImageFormat ScreenshotFormat = ImageFormat.Png;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SoundSettings
|
public class SoundSettings
|
||||||
@@ -177,6 +180,7 @@ namespace OpenRA
|
|||||||
public Hotkey TogglePixelDoubleKey = new Hotkey(Keycode.PERIOD, Modifiers.None);
|
public Hotkey TogglePixelDoubleKey = new Hotkey(Keycode.PERIOD, Modifiers.None);
|
||||||
|
|
||||||
public Hotkey DevReloadChromeKey = new Hotkey(Keycode.C, Modifiers.Ctrl | Modifiers.Shift);
|
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 Production01Key = new Hotkey(Keycode.F1, Modifiers.None);
|
||||||
public Hotkey Production02Key = new Hotkey(Keycode.F2, Modifiers.None);
|
public Hotkey Production02Key = new Hotkey(Keycode.F2, Modifiers.None);
|
||||||
|
|||||||
@@ -30,6 +30,14 @@ namespace OpenRA.Widgets
|
|||||||
ChromeProvider.Initialize(Game.ModData.Manifest.Chrome);
|
ChromeProvider.Initialize(Game.ModData.Manifest.Chrome);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hk == Game.Settings.Keys.TakeScreenshotKey)
|
||||||
|
{
|
||||||
|
if (e.Event == KeyInputEvent.Down)
|
||||||
|
Game.TakeScreenshot = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.HandleKeyPress(e);
|
return base.HandleKeyPress(e);
|
||||||
|
|||||||
@@ -464,7 +464,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
{
|
{
|
||||||
var hotkeys = new Dictionary<string, string>()
|
var hotkeys = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "DevReloadChromeKey", "Reload Chrome" }
|
{ "DevReloadChromeKey", "Reload Chrome" },
|
||||||
|
{ "TakeScreenshotKey", "Take screenshot" }
|
||||||
};
|
};
|
||||||
|
|
||||||
var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing);
|
var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing);
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ namespace OpenRA.Renderer.Null
|
|||||||
|
|
||||||
public void Clear() { }
|
public void Clear() { }
|
||||||
public void Present() { }
|
public void Present() { }
|
||||||
|
public Bitmap TakeScreenshot() { return new Bitmap(1, 1); }
|
||||||
|
|
||||||
public string GetClipboardText() { return ""; }
|
public string GetClipboardText() { return ""; }
|
||||||
public void PumpInput(IInputHandler ih)
|
public void PumpInput(IInputHandler ih)
|
||||||
|
|||||||
@@ -330,6 +330,31 @@ namespace OpenRA.Renderer.Sdl2
|
|||||||
ErrorHandler.CheckGlError();
|
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 Present() { SDL.SDL_GL_SwapWindow(window); }
|
||||||
public void PumpInput(IInputHandler inputHandler) { input.PumpInput(inputHandler); }
|
public void PumpInput(IInputHandler inputHandler) { input.PumpInput(inputHandler); }
|
||||||
public string GetClipboardText() { return input.GetClipboardText(); }
|
public string GetClipboardText() { return input.GetClipboardText(); }
|
||||||
|
|||||||
Reference in New Issue
Block a user