mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2026-05-16 16:35:47 +08:00
R26_dev8 - First public commit
This commit is contained in:
+121
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CodeWalker
|
||||
{
|
||||
public class Cache<TKey, TVal> where TVal : Cacheable<TKey>
|
||||
{
|
||||
public long MaxMemoryUsage = 536870912; //512mb
|
||||
public long CurrentMemoryUsage = 0;
|
||||
public double CacheTime = 5.0; //seconds to keep something that's not used
|
||||
|
||||
private LinkedList<TVal> loadedList = new LinkedList<TVal>();
|
||||
private Dictionary<TKey, LinkedListNode<TVal>> loadedListDict = new Dictionary<TKey, LinkedListNode<TVal>>();
|
||||
|
||||
public Cache()
|
||||
{
|
||||
}
|
||||
public Cache(long maxMemoryUsage, double cacheTime)
|
||||
{
|
||||
MaxMemoryUsage = maxMemoryUsage;
|
||||
CacheTime = cacheTime;
|
||||
}
|
||||
|
||||
public TVal TryGet(TKey key)
|
||||
{
|
||||
LinkedListNode<TVal> lln = null;
|
||||
if (loadedListDict.TryGetValue(key, out lln))
|
||||
{
|
||||
loadedList.Remove(lln);
|
||||
loadedList.AddLast(lln);
|
||||
lln.Value.LastUseTime = DateTime.Now;
|
||||
}
|
||||
return (lln != null) ? lln.Value : null;
|
||||
}
|
||||
public bool TryAdd(TKey key, TVal item)
|
||||
{
|
||||
if (item.MemoryUsage == 0)
|
||||
{
|
||||
}
|
||||
item.Key = key;
|
||||
if (CanAdd())
|
||||
{
|
||||
var lln = loadedList.AddLast(item);
|
||||
loadedListDict.Add(key, lln);
|
||||
Interlocked.Add(ref CurrentMemoryUsage, item.MemoryUsage);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//cache full, check the front of the list for oldest..
|
||||
var oldlln = loadedList.First;
|
||||
var cachetime = CacheTime;
|
||||
int iter = 0, maxiter = 2;
|
||||
while (!CanAdd() && (iter<maxiter))
|
||||
{
|
||||
while ((!CanAdd()) && (oldlln != null) && ((DateTime.Now - oldlln.Value.LastUseTime).TotalSeconds > cachetime))
|
||||
{
|
||||
Interlocked.Add(ref CurrentMemoryUsage, -oldlln.Value.MemoryUsage);
|
||||
loadedListDict.Remove(oldlln.Value.Key);
|
||||
loadedList.Remove(oldlln); //gc should free up memory later..
|
||||
oldlln.Value = null;
|
||||
oldlln = null;
|
||||
//GC.Collect();
|
||||
oldlln = loadedList.First;
|
||||
}
|
||||
cachetime *= 0.5;
|
||||
iter++;
|
||||
}
|
||||
if (CanAdd()) //see if there's enough memory now...
|
||||
{
|
||||
var newlln = loadedList.AddLast(item);
|
||||
loadedListDict.Add(key, newlln);
|
||||
Interlocked.Add(ref CurrentMemoryUsage, item.MemoryUsage);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//really shouldn't get here, but it's possible under stress.
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanAdd()
|
||||
{
|
||||
return Interlocked.Read(ref CurrentMemoryUsage) < MaxMemoryUsage;
|
||||
}
|
||||
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
loadedList.Clear();
|
||||
loadedListDict.Clear();
|
||||
CurrentMemoryUsage = 0;
|
||||
}
|
||||
|
||||
public void Remove(TKey key)
|
||||
{
|
||||
LinkedListNode<TVal> n;
|
||||
if (loadedListDict.TryGetValue(key, out n))
|
||||
{
|
||||
loadedListDict.Remove(key);
|
||||
loadedList.Remove(n);
|
||||
CurrentMemoryUsage -= n.Value.MemoryUsage;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public abstract class Cacheable<TKey>
|
||||
{
|
||||
public TKey Key;
|
||||
public DateTime LastUseTime = DateTime.Now;
|
||||
public long MemoryUsage;
|
||||
}
|
||||
|
||||
}
|
||||
+2411
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
||||
using SharpDX;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CodeWalker
|
||||
{
|
||||
public static class MatrixExtensions
|
||||
{
|
||||
|
||||
public static Vector3 MultiplyW(this Matrix m, Vector3 v)
|
||||
{
|
||||
float x = (((m.M11 * v.X) + (m.M21 * v.Y)) + (m.M31 * v.Z)) + m.M41;
|
||||
float y = (((m.M12 * v.X) + (m.M22 * v.Y)) + (m.M32 * v.Z)) + m.M42;
|
||||
float z = (((m.M13 * v.X) + (m.M23 * v.Y)) + (m.M33 * v.Z)) + m.M43;
|
||||
float w = (((m.M14 * v.X) + (m.M24 * v.Y)) + (m.M34 * v.Z)) + m.M44;
|
||||
float iw = 1.0f / Math.Abs(w);
|
||||
return new Vector3(x * iw, y * iw, z * iw);
|
||||
}
|
||||
public static Vector3 Multiply(this Matrix m, Vector3 v)
|
||||
{
|
||||
float x = (((m.M11 * v.X) + (m.M21 * v.Y)) + (m.M31 * v.Z)) + m.M41;
|
||||
float y = (((m.M12 * v.X) + (m.M22 * v.Y)) + (m.M32 * v.Z)) + m.M42;
|
||||
float z = (((m.M13 * v.X) + (m.M23 * v.Y)) + (m.M33 * v.Z)) + m.M43;
|
||||
return new Vector3(x, y, z);
|
||||
//this quick mul ignores W...
|
||||
}
|
||||
|
||||
public static Vector4 Multiply(this Matrix m, Vector4 v)
|
||||
{
|
||||
float x = (((m.M11 * v.X) + (m.M21 * v.Y)) + (m.M31 * v.Z)) + m.M41;
|
||||
float y = (((m.M12 * v.X) + (m.M22 * v.Y)) + (m.M32 * v.Z)) + m.M42;
|
||||
float z = (((m.M13 * v.X) + (m.M23 * v.Y)) + (m.M33 * v.Z)) + m.M43;
|
||||
float w = (((m.M14 * v.X) + (m.M24 * v.Y)) + (m.M34 * v.Z)) + m.M44;
|
||||
return new Vector4(x, y, z, w);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using SharpDX;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CodeWalker
|
||||
{
|
||||
|
||||
|
||||
|
||||
public static class QuaternionExtension
|
||||
{
|
||||
public static Vector3 Multiply(this Quaternion a, Vector3 b)
|
||||
{
|
||||
float axx = a.X * 2.0f;
|
||||
float ayy = a.Y * 2.0f;
|
||||
float azz = a.Z * 2.0f;
|
||||
float awxx = a.W * axx;
|
||||
float awyy = a.W * ayy;
|
||||
float awzz = a.W * azz;
|
||||
float axxx = a.X * axx;
|
||||
float axyy = a.X * ayy;
|
||||
float axzz = a.X * azz;
|
||||
float ayyy = a.Y * ayy;
|
||||
float ayzz = a.Y * azz;
|
||||
float azzz = a.Z * azz;
|
||||
return new Vector3(((b.X * ((1.0f - ayyy) - azzz)) + (b.Y * (axyy - awzz))) + (b.Z * (axzz + awyy)),
|
||||
((b.X * (axyy + awzz)) + (b.Y * ((1.0f - axxx) - azzz))) + (b.Z * (ayzz - awxx)),
|
||||
((b.X * (axzz - awyy)) + (b.Y * (ayzz + awxx))) + (b.Z * ((1.0f - axxx) - ayyy)));
|
||||
}
|
||||
|
||||
public static Matrix ToMatrix(this Quaternion q)
|
||||
{
|
||||
float xx = q.X * q.X;
|
||||
float yy = q.Y * q.Y;
|
||||
float zz = q.Z * q.Z;
|
||||
float xy = q.X * q.Y;
|
||||
float zw = q.Z * q.W;
|
||||
float zx = q.Z * q.X;
|
||||
float yw = q.Y * q.W;
|
||||
float yz = q.Y * q.Z;
|
||||
float xw = q.X * q.W;
|
||||
Matrix result = new Matrix();
|
||||
result.M11 = 1.0f - (2.0f * (yy + zz));
|
||||
result.M12 = 2.0f * (xy + zw);
|
||||
result.M13 = 2.0f * (zx - yw);
|
||||
result.M14 = 0.0f;
|
||||
result.M21 = 2.0f * (xy - zw);
|
||||
result.M22 = 1.0f - (2.0f * (zz + xx));
|
||||
result.M23 = 2.0f * (yz + xw);
|
||||
result.M24 = 0.0f;
|
||||
result.M31 = 2.0f * (zx + yw);
|
||||
result.M32 = 2.0f * (yz - xw);
|
||||
result.M33 = 1.0f - (2.0f * (yy + xx));
|
||||
result.M34 = 0.0f;
|
||||
result.M41 = 0.0f;
|
||||
result.M42 = 0.0f;
|
||||
result.M43 = 0.0f;
|
||||
result.M44 = 1.0f;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Vector4 ToVector4(this Quaternion q)
|
||||
{
|
||||
return new Vector4(q.X, q.Y, q.Z, q.W);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX.WIC;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CodeWalker.Utils
|
||||
{
|
||||
public class TextureLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// Loads a bitmap using WIC.
|
||||
/// </summary>
|
||||
/// <param name="deviceManager"></param>
|
||||
/// <param name="filename"></param>
|
||||
/// <returns></returns>
|
||||
public static BitmapSource LoadBitmap(ImagingFactory2 factory, string filename)
|
||||
{
|
||||
var bitmapDecoder = new BitmapDecoder(
|
||||
factory,
|
||||
filename,
|
||||
DecodeOptions.CacheOnDemand
|
||||
);
|
||||
|
||||
var formatConverter = new FormatConverter(factory);
|
||||
|
||||
formatConverter.Initialize(
|
||||
bitmapDecoder.GetFrame(0),
|
||||
PixelFormat.Format32bppPRGBA,
|
||||
BitmapDitherType.None,
|
||||
null,
|
||||
0.0,
|
||||
BitmapPaletteType.Custom);
|
||||
|
||||
return formatConverter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="SharpDX.Direct3D11.Texture2D"/> from a WIC <see cref="SharpDX.WIC.BitmapSource"/>
|
||||
/// </summary>
|
||||
/// <param name="device">The Direct3D11 device</param>
|
||||
/// <param name="bitmapSource">The WIC bitmap source</param>
|
||||
/// <returns>A Texture2D</returns>
|
||||
public static SharpDX.Direct3D11.Texture2D CreateTexture2DFromBitmap(Device device, SharpDX.WIC.BitmapSource bitmapSource)
|
||||
{
|
||||
// Allocate DataStream to receive the WIC image pixels
|
||||
int stride = bitmapSource.Size.Width * 4;
|
||||
using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true))
|
||||
{
|
||||
// Copy the content of the WIC to the buffer
|
||||
bitmapSource.CopyPixels(stride, buffer);
|
||||
return new Texture2D(device, new Texture2DDescription()
|
||||
{
|
||||
Width = bitmapSource.Size.Width,
|
||||
Height = bitmapSource.Size.Height,
|
||||
ArraySize = 1,
|
||||
BindFlags = BindFlags.ShaderResource,
|
||||
Usage = ResourceUsage.Immutable,
|
||||
CpuAccessFlags = CpuAccessFlags.None,
|
||||
Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
|
||||
MipLevels = 1,
|
||||
OptionFlags = ResourceOptionFlags.None,
|
||||
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
|
||||
}, new SharpDX.DataRectangle(buffer.DataPointer, stride));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//create a bitmap from a texture2D. DOES NOT WORK
|
||||
public static System.Drawing.Bitmap GetTextureBitmap(Device device, Texture2D tex, int mipSlice)
|
||||
{
|
||||
int w = tex.Description.Width;
|
||||
int h = tex.Description.Height;
|
||||
|
||||
var textureCopy = new Texture2D(device, new Texture2DDescription
|
||||
{
|
||||
Width = w,
|
||||
Height = h,
|
||||
MipLevels = tex.Description.MipLevels,
|
||||
ArraySize = 1,
|
||||
Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
|
||||
Usage = ResourceUsage.Staging,
|
||||
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
|
||||
BindFlags = BindFlags.None,
|
||||
CpuAccessFlags = CpuAccessFlags.Read,
|
||||
OptionFlags = ResourceOptionFlags.None
|
||||
});
|
||||
DataStream dataStream;// = new DataStream(8 * tex.Description.Width * tex.Description.Height, true, true);
|
||||
|
||||
DeviceContext context = device.ImmediateContext;
|
||||
|
||||
//context.CopyResource(tex, textureCopy);
|
||||
context.CopySubresourceRegion(tex, mipSlice, null, textureCopy, 0);
|
||||
|
||||
|
||||
var dataBox = context.MapSubresource(
|
||||
textureCopy,
|
||||
mipSlice,
|
||||
0,
|
||||
MapMode.Read,
|
||||
SharpDX.Direct3D11.MapFlags.None,
|
||||
out dataStream);
|
||||
|
||||
//int bytesize = w * h * 4;
|
||||
//byte[] pixels = new byte[bytesize];
|
||||
//dataStream.Read(pixels, 0, bytesize);
|
||||
//dataStream.Position = 0;
|
||||
|
||||
var dataRectangle = new DataRectangle
|
||||
{
|
||||
DataPointer = dataStream.DataPointer,
|
||||
Pitch = dataBox.RowPitch
|
||||
};
|
||||
|
||||
|
||||
ImagingFactory wicf = new ImagingFactory();
|
||||
|
||||
var b = new SharpDX.WIC.Bitmap(wicf, w, h, SharpDX.WIC.PixelFormat.Format32bppBGRA, dataRectangle);
|
||||
|
||||
|
||||
var s = new MemoryStream();
|
||||
using (var bitmapEncoder = new PngBitmapEncoder(wicf, s))
|
||||
{
|
||||
using (var bitmapFrameEncode = new BitmapFrameEncode(bitmapEncoder))
|
||||
{
|
||||
bitmapFrameEncode.Initialize();
|
||||
bitmapFrameEncode.SetSize(b.Size.Width, b.Size.Height);
|
||||
var pixelFormat = PixelFormat.FormatDontCare;
|
||||
bitmapFrameEncode.SetPixelFormat(ref pixelFormat);
|
||||
bitmapFrameEncode.WriteSource(b);
|
||||
bitmapFrameEncode.Commit();
|
||||
bitmapEncoder.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
context.UnmapSubresource(textureCopy, 0);
|
||||
textureCopy.Dispose();
|
||||
b.Dispose();
|
||||
|
||||
|
||||
|
||||
s.Position = 0;
|
||||
var bmp = new System.Drawing.Bitmap(s);
|
||||
|
||||
|
||||
|
||||
//Palette pal = new Palette(wf);
|
||||
//b.CopyPalette(pal);
|
||||
|
||||
//byte[] pixels = new byte[w * h * 4];
|
||||
//b.CopyPixels(pixels, w * 4);
|
||||
//GCHandle handle = GCHandle.Alloc(pixels, GCHandleType.Pinned);
|
||||
//var hptr = handle.AddrOfPinnedObject();
|
||||
//System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(w, h, w * 4, System.Drawing.Imaging.PixelFormat.Format32bppArgb, hptr);
|
||||
//handle.Free();
|
||||
|
||||
//System.Threading.Thread.Sleep(1000);
|
||||
|
||||
//System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
|
||||
//System.Drawing.Imaging.BitmapData data = bmp.LockBits(
|
||||
// new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size),
|
||||
// System.Drawing.Imaging.ImageLockMode.WriteOnly,
|
||||
// System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
|
||||
////b.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
|
||||
//b.CopyPixels(data.Stride, data.Scan0, data.Height * data.Stride);
|
||||
//bmp.UnlockBits(data);
|
||||
|
||||
|
||||
var c1 = bmp.GetPixel(10, 2);
|
||||
|
||||
|
||||
//dataStream.Dispose();
|
||||
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+448
@@ -0,0 +1,448 @@
|
||||
using SharpDX;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Point = System.Drawing.Point;
|
||||
|
||||
namespace CodeWalker
|
||||
{
|
||||
////public static class Utils
|
||||
////{
|
||||
|
||||
|
||||
|
||||
//// //unused
|
||||
//// //public static Bitmap ResizeImage(Image image, int width, int height)
|
||||
//// //{
|
||||
//// // var destRect = new Rectangle(0, 0, width, height);
|
||||
//// // var destImage = new Bitmap(width, height);
|
||||
//// // destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
|
||||
//// // using (var graphics = Graphics.FromImage(destImage))
|
||||
//// // {
|
||||
//// // graphics.CompositingMode = CompositingMode.SourceCopy;
|
||||
//// // graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||
//// // graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
//// // graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||
//// // graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
//// // using (var wrapMode = new ImageAttributes())
|
||||
//// // {
|
||||
//// // wrapMode.SetWrapMode(WrapMode.TileFlipXY);
|
||||
//// // graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
|
||||
//// // }
|
||||
//// // }
|
||||
//// // return destImage;
|
||||
//// //}
|
||||
|
||||
|
||||
////}
|
||||
|
||||
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static class ListViewExtensions
|
||||
{
|
||||
//from stackoverflow:
|
||||
//https://stackoverflow.com/questions/254129/how-to-i-display-a-sort-arrow-in-the-header-of-a-list-view-column-using-c
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct HDITEM
|
||||
{
|
||||
public Mask mask;
|
||||
public int cxy;
|
||||
[MarshalAs(UnmanagedType.LPTStr)] public string pszText;
|
||||
public IntPtr hbm;
|
||||
public int cchTextMax;
|
||||
public Format fmt;
|
||||
public IntPtr lParam;
|
||||
// _WIN32_IE >= 0x0300
|
||||
public int iImage;
|
||||
public int iOrder;
|
||||
// _WIN32_IE >= 0x0500
|
||||
public uint type;
|
||||
public IntPtr pvFilter;
|
||||
// _WIN32_WINNT >= 0x0600
|
||||
public uint state;
|
||||
|
||||
[Flags]
|
||||
public enum Mask
|
||||
{
|
||||
Format = 0x4, // HDI_FORMAT
|
||||
};
|
||||
|
||||
[Flags]
|
||||
public enum Format
|
||||
{
|
||||
SortDown = 0x200, // HDF_SORTDOWN
|
||||
SortUp = 0x400, // HDF_SORTUP
|
||||
};
|
||||
};
|
||||
|
||||
public const int LVM_FIRST = 0x1000;
|
||||
public const int LVM_GETHEADER = LVM_FIRST + 31;
|
||||
|
||||
public const int HDM_FIRST = 0x1200;
|
||||
public const int HDM_GETITEM = HDM_FIRST + 11;
|
||||
public const int HDM_SETITEM = HDM_FIRST + 12;
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, ref HDITEM lParam);
|
||||
|
||||
public static void SetSortIcon(this ListView listViewControl, int columnIndex, SortOrder order)
|
||||
{
|
||||
IntPtr columnHeader = SendMessage(listViewControl.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
|
||||
for (int columnNumber = 0; columnNumber <= listViewControl.Columns.Count - 1; columnNumber++)
|
||||
{
|
||||
var columnPtr = new IntPtr(columnNumber);
|
||||
var item = new HDITEM
|
||||
{
|
||||
mask = HDITEM.Mask.Format
|
||||
};
|
||||
|
||||
if (SendMessage(columnHeader, HDM_GETITEM, columnPtr, ref item) == IntPtr.Zero)
|
||||
{
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
if (order != SortOrder.None && columnNumber == columnIndex)
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case SortOrder.Ascending:
|
||||
item.fmt &= ~HDITEM.Format.SortDown;
|
||||
item.fmt |= HDITEM.Format.SortUp;
|
||||
break;
|
||||
case SortOrder.Descending:
|
||||
item.fmt &= ~HDITEM.Format.SortUp;
|
||||
item.fmt |= HDITEM.Format.SortDown;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item.fmt &= ~HDITEM.Format.SortDown & ~HDITEM.Format.SortUp;
|
||||
}
|
||||
|
||||
if (SendMessage(columnHeader, HDM_SETITEM, columnPtr, ref item) == IntPtr.Zero)
|
||||
{
|
||||
throw new Win32Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//private const int LVM_FIRST = 0x1000;
|
||||
private const int LVM_SETITEMSTATE = LVM_FIRST + 43;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
public struct LVITEM
|
||||
{
|
||||
public int mask;
|
||||
public int iItem;
|
||||
public int iSubItem;
|
||||
public int state;
|
||||
public int stateMask;
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
public string pszText;
|
||||
public int cchTextMax;
|
||||
public int iImage;
|
||||
public IntPtr lParam;
|
||||
public int iIndent;
|
||||
public int iGroupId;
|
||||
public int cColumns;
|
||||
public IntPtr puColumns;
|
||||
};
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr SendMessageLVItem(IntPtr hWnd, int msg, int wParam, ref LVITEM lvi);
|
||||
|
||||
/// <summary>
|
||||
/// Select all rows on the given listview
|
||||
/// </summary>
|
||||
/// <param name="list">The listview whose items are to be selected</param>
|
||||
public static void SelectAllItems(this ListView list)
|
||||
{
|
||||
SetItemState(list, -1, 2, 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deselect all rows on the given listview
|
||||
/// </summary>
|
||||
/// <param name="list">The listview whose items are to be deselected</param>
|
||||
public static void DeselectAllItems(this ListView list)
|
||||
{
|
||||
SetItemState(list, -1, 2, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the item state on the given item
|
||||
/// </summary>
|
||||
/// <param name="list">The listview whose item's state is to be changed</param>
|
||||
/// <param name="itemIndex">The index of the item to be changed</param>
|
||||
/// <param name="mask">Which bits of the value are to be set?</param>
|
||||
/// <param name="value">The value to be set</param>
|
||||
public static void SetItemState(ListView list, int itemIndex, int mask, int value)
|
||||
{
|
||||
LVITEM lvItem = new LVITEM();
|
||||
lvItem.stateMask = mask;
|
||||
lvItem.state = value;
|
||||
SendMessageLVItem(list.Handle, LVM_SETITEMSTATE, itemIndex, ref lvItem);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class TextBoxExtension
|
||||
{
|
||||
private const int EM_SETTABSTOPS = 0x00CB;
|
||||
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, int[] lParam);
|
||||
|
||||
public static Point GetCaretPosition(this TextBox textBox)
|
||||
{
|
||||
Point point = new Point(0, 0);
|
||||
|
||||
if (textBox.Focused)
|
||||
{
|
||||
point.X = textBox.SelectionStart - textBox.GetFirstCharIndexOfCurrentLine() + 1;
|
||||
point.Y = textBox.GetLineFromCharIndex(textBox.SelectionStart) + 1;
|
||||
}
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
public static void SetTabStopWidth(this TextBox textbox, int width)
|
||||
{
|
||||
SendMessage(textbox.Handle, EM_SETTABSTOPS, 1, new int[] { width * 4 });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class TextUtil
|
||||
{
|
||||
|
||||
public static string GetBytesReadable(long i)
|
||||
{
|
||||
//shamelessly stolen from stackoverflow, and a bit mangled
|
||||
|
||||
// Returns the human-readable file size for an arbitrary, 64-bit file size
|
||||
// The default format is "0.### XB", e.g. "4.2 KB" or "1.434 GB"
|
||||
// Get absolute value
|
||||
long absolute_i = (i < 0 ? -i : i);
|
||||
// Determine the suffix and readable value
|
||||
string suffix;
|
||||
double readable;
|
||||
if (absolute_i >= 0x1000000000000000) // Exabyte
|
||||
{
|
||||
suffix = "EB";
|
||||
readable = (i >> 50);
|
||||
}
|
||||
else if (absolute_i >= 0x4000000000000) // Petabyte
|
||||
{
|
||||
suffix = "PB";
|
||||
readable = (i >> 40);
|
||||
}
|
||||
else if (absolute_i >= 0x10000000000) // Terabyte
|
||||
{
|
||||
suffix = "TB";
|
||||
readable = (i >> 30);
|
||||
}
|
||||
else if (absolute_i >= 0x40000000) // Gigabyte
|
||||
{
|
||||
suffix = "GB";
|
||||
readable = (i >> 20);
|
||||
}
|
||||
else if (absolute_i >= 0x100000) // Megabyte
|
||||
{
|
||||
suffix = "MB";
|
||||
readable = (i >> 10);
|
||||
}
|
||||
else if (absolute_i >= 0x400) // Kilobyte
|
||||
{
|
||||
suffix = "KB";
|
||||
readable = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
return i.ToString("0 bytes"); // Byte
|
||||
}
|
||||
// Divide by 1024 to get fractional value
|
||||
readable = (readable / 1024);
|
||||
|
||||
string fmt = "0.### ";
|
||||
if (readable > 1000)
|
||||
{
|
||||
fmt = "0";
|
||||
}
|
||||
else if (readable > 100)
|
||||
{
|
||||
fmt = "0.#";
|
||||
}
|
||||
else if (readable > 10)
|
||||
{
|
||||
fmt = "0.##";
|
||||
}
|
||||
|
||||
// Return formatted number with suffix
|
||||
return readable.ToString(fmt) + suffix;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class FloatUtil
|
||||
{
|
||||
public static bool TryParse(string s, out float f)
|
||||
{
|
||||
f = 0.0f;
|
||||
if (float.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out f))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static float Parse(string s)
|
||||
{
|
||||
float f;
|
||||
TryParse(s, out f);
|
||||
return f;
|
||||
}
|
||||
public static string ToString(float f)
|
||||
{
|
||||
var c = CultureInfo.InvariantCulture;
|
||||
return f.ToString(c);
|
||||
}
|
||||
|
||||
|
||||
public static string GetVector2String(Vector2 v)
|
||||
{
|
||||
var c = CultureInfo.InvariantCulture;
|
||||
return v.X.ToString(c) + ", " + v.Y.ToString(c);
|
||||
}
|
||||
public static string GetVector3String(Vector3 v)
|
||||
{
|
||||
var c = CultureInfo.InvariantCulture;
|
||||
return v.X.ToString(c) + ", " + v.Y.ToString(c) + ", " + v.Z.ToString(c);
|
||||
}
|
||||
public static string GetVector3String(Vector3 v, string format)
|
||||
{
|
||||
var c = CultureInfo.InvariantCulture;
|
||||
return v.X.ToString(format, c) + ", " + v.Y.ToString(format, c) + ", " + v.Z.ToString(format, c);
|
||||
}
|
||||
|
||||
public static Vector3 ParseVector3String(string s)
|
||||
{
|
||||
Vector3 p = new Vector3(0.0f);
|
||||
string[] ss = s.Split(',');
|
||||
if (ss.Length > 0)
|
||||
{
|
||||
FloatUtil.TryParse(ss[0].Trim(), out p.X);
|
||||
}
|
||||
if (ss.Length > 1)
|
||||
{
|
||||
FloatUtil.TryParse(ss[1].Trim(), out p.Y);
|
||||
}
|
||||
if (ss.Length > 2)
|
||||
{
|
||||
FloatUtil.TryParse(ss[2].Trim(), out p.Z);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static string GetVector4String(Vector4 v)
|
||||
{
|
||||
var c = CultureInfo.InvariantCulture;
|
||||
return v.X.ToString(c) + ", " + v.Y.ToString(c) + ", " + v.Z.ToString(c) + ", " + v.W.ToString(c);
|
||||
}
|
||||
public static Vector4 ParseVector4String(string s)
|
||||
{
|
||||
Vector4 p = new Vector4(0.0f);
|
||||
string[] ss = s.Split(',');
|
||||
if (ss.Length > 0)
|
||||
{
|
||||
FloatUtil.TryParse(ss[0].Trim(), out p.X);
|
||||
}
|
||||
if (ss.Length > 1)
|
||||
{
|
||||
FloatUtil.TryParse(ss[1].Trim(), out p.Y);
|
||||
}
|
||||
if (ss.Length > 2)
|
||||
{
|
||||
FloatUtil.TryParse(ss[2].Trim(), out p.Z);
|
||||
}
|
||||
if (ss.Length > 3)
|
||||
{
|
||||
FloatUtil.TryParse(ss[3].Trim(), out p.W);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//unused
|
||||
//public class AccurateTimer
|
||||
//{
|
||||
// private delegate void TimerEventDel(int id, int msg, IntPtr user, int dw1, int dw2);
|
||||
// private const int TIME_PERIODIC = 1;
|
||||
// private const int EVENT_TYPE = TIME_PERIODIC;// + 0x100; // TIME_KILL_SYNCHRONOUS causes a hang ?!
|
||||
// [DllImport("winmm.dll")]
|
||||
// private static extern int timeBeginPeriod(int msec);
|
||||
// [DllImport("winmm.dll")]
|
||||
// private static extern int timeEndPeriod(int msec);
|
||||
// [DllImport("winmm.dll")]
|
||||
// private static extern int timeSetEvent(int delay, int resolution, TimerEventDel handler, IntPtr user, int eventType);
|
||||
// [DllImport("winmm.dll")]
|
||||
// private static extern int timeKillEvent(int id);
|
||||
// Action mAction;
|
||||
// Form mForm;
|
||||
// private int mTimerId;
|
||||
// private TimerEventDel mHandler; // NOTE: declare at class scope so garbage collector doesn't release it!!!
|
||||
// public AccurateTimer(Form form, Action action, int delay)
|
||||
// {
|
||||
// mAction = action;
|
||||
// mForm = form;
|
||||
// timeBeginPeriod(1);
|
||||
// mHandler = new TimerEventDel(TimerCallback);
|
||||
// mTimerId = timeSetEvent(delay, 0, mHandler, IntPtr.Zero, EVENT_TYPE);
|
||||
// }
|
||||
// public void Stop()
|
||||
// {
|
||||
// int err = timeKillEvent(mTimerId);
|
||||
// timeEndPeriod(1);
|
||||
// System.Threading.Thread.Sleep(100);// Ensure callbacks are drained
|
||||
// }
|
||||
// private void TimerCallback(int id, int msg, IntPtr user, int dw1, int dw2)
|
||||
// {
|
||||
// if (mTimerId != 0) mForm.BeginInvoke(mAction);
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using SharpDX;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CodeWalker
|
||||
{
|
||||
public static class Vectors
|
||||
{
|
||||
|
||||
public static Vector3 XYZ(this Vector4 v)
|
||||
{
|
||||
return new Vector3(v.X, v.Y, v.Z);
|
||||
}
|
||||
|
||||
|
||||
public static Vector4 Floor(this Vector4 v)
|
||||
{
|
||||
return new Vector4((float)Math.Floor(v.X), (float)Math.Floor(v.Y), (float)Math.Floor(v.Z), (float)Math.Floor(v.W));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public struct Vector2I
|
||||
{
|
||||
public int X;
|
||||
public int Y;
|
||||
|
||||
public Vector2I(int x, int y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
public Vector2I(Vector2 v)
|
||||
{
|
||||
X = (int)Math.Floor(v.X);
|
||||
Y = (int)Math.Floor(v.Y);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return X.ToString() + ", " + Y.ToString();
|
||||
}
|
||||
|
||||
|
||||
public static Vector2I operator +(Vector2I a, Vector2I b)
|
||||
{
|
||||
return new Vector2I(a.X + b.X, a.Y + b.Y);
|
||||
}
|
||||
|
||||
public static Vector2I operator -(Vector2I a, Vector2I b)
|
||||
{
|
||||
return new Vector2I(a.X - b.X, a.Y - b.Y);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
using SharpDX;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace CodeWalker
|
||||
{
|
||||
public static class Xml
|
||||
{
|
||||
|
||||
public static string GetStringAttribute(XmlNode node, string attribute)
|
||||
{
|
||||
if (node == null) return null;
|
||||
return node.Attributes[attribute]?.InnerText;
|
||||
}
|
||||
public static bool GetBoolAttribute(XmlNode node, string attribute)
|
||||
{
|
||||
if (node == null) return false;
|
||||
string val = node.Attributes[attribute]?.InnerText;
|
||||
bool b;
|
||||
bool.TryParse(val, out b);
|
||||
return b;
|
||||
}
|
||||
public static int GetIntAttribute(XmlNode node, string attribute)
|
||||
{
|
||||
if (node == null) return 0;
|
||||
string val = node.Attributes[attribute]?.InnerText;
|
||||
int i;
|
||||
int.TryParse(val, out i);
|
||||
return i;
|
||||
}
|
||||
public static float GetFloatAttribute(XmlNode node, string attribute)
|
||||
{
|
||||
if (node == null) return 0;
|
||||
string val = node.Attributes[attribute]?.InnerText;
|
||||
float f;
|
||||
FloatUtil.TryParse(val, out f);
|
||||
return f;
|
||||
}
|
||||
|
||||
public static string GetChildInnerText(XmlNode node, string name)
|
||||
{
|
||||
if (node == null) return null;
|
||||
return node.SelectSingleNode(name)?.InnerText;
|
||||
}
|
||||
|
||||
public static bool GetChildBoolAttribute(XmlNode node, string name, string attribute)
|
||||
{
|
||||
if (node == null) return false;
|
||||
string val = node.SelectSingleNode(name)?.Attributes[attribute]?.InnerText;
|
||||
bool b;
|
||||
bool.TryParse(val, out b);
|
||||
return b;
|
||||
}
|
||||
public static int GetChildIntAttribute(XmlNode node, string name, string attribute)
|
||||
{
|
||||
if (node == null) return 0;
|
||||
string val = node.SelectSingleNode(name)?.Attributes[attribute]?.InnerText;
|
||||
int i;
|
||||
int.TryParse(val, out i);
|
||||
return i;
|
||||
}
|
||||
public static float GetChildFloatAttribute(XmlNode node, string name, string attribute)
|
||||
{
|
||||
if (node == null) return 0;
|
||||
string val = node.SelectSingleNode(name)?.Attributes[attribute]?.InnerText;
|
||||
float f;
|
||||
FloatUtil.TryParse(val, out f);
|
||||
return f;
|
||||
}
|
||||
public static string GetChildStringAttribute(XmlNode node, string name, string attribute)
|
||||
{
|
||||
if (node == null) return string.Empty;
|
||||
string val = node.SelectSingleNode(name)?.Attributes[attribute]?.InnerText;
|
||||
return val;
|
||||
}
|
||||
public static Vector3 GetChildVector3Attributes(XmlNode node, string name, string x, string y, string z)
|
||||
{
|
||||
float fx = GetChildFloatAttribute(node, name, x);
|
||||
float fy = GetChildFloatAttribute(node, name, y);
|
||||
float fz = GetChildFloatAttribute(node, name, z);
|
||||
return new Vector3(fx, fy, fz);
|
||||
}
|
||||
|
||||
public static XmlElement GetChild(XmlElement element, string name)
|
||||
{
|
||||
return element.SelectSingleNode(name) as XmlElement;
|
||||
}
|
||||
|
||||
public static XmlElement AddChild(XmlDocument doc, XmlNode node, string name)
|
||||
{
|
||||
XmlElement child = doc.CreateElement(name);
|
||||
node.AppendChild(child);
|
||||
return child;
|
||||
}
|
||||
public static XmlElement AddChildWithInnerText(XmlDocument doc, XmlNode node, string name, string innerText)
|
||||
{
|
||||
XmlElement child = AddChild(doc, node, name);
|
||||
child.InnerText = innerText;
|
||||
return child;
|
||||
}
|
||||
public static XmlElement AddChildWithAttribute(XmlDocument doc, XmlNode node, string name, string attributeName, string attributeValue)
|
||||
{
|
||||
XmlElement child = AddChild(doc, node, name);
|
||||
child.SetAttribute(attributeName, attributeValue);
|
||||
return child;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user