diff --git a/.editorconfig b/.editorconfig
index 60c11a10..93d1f029 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -17,6 +17,22 @@ indent_style = space
indent_size = 4
insert_final_newline = false
trim_trailing_whitespace = true
+csharp_using_directive_placement = outside_namespace:silent
+csharp_prefer_simple_using_statement = true:suggestion
+csharp_prefer_braces = true:warning
+csharp_style_namespace_declarations = file_scoped:silent
+csharp_style_prefer_method_group_conversion = true:silent
+csharp_style_prefer_top_level_statements = false:warning
+csharp_style_prefer_primary_constructors = true:suggestion
+csharp_style_expression_bodied_methods = true:warning
+csharp_style_expression_bodied_constructors = true:warning
+csharp_style_expression_bodied_operators = true:warning
+csharp_style_expression_bodied_properties = true:warning
+csharp_style_expression_bodied_indexers = true:warning
+csharp_style_expression_bodied_accessors = true:warning
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = false:silent
+csharp_indent_labels = no_change
#########################
# File Extension Settings
@@ -350,4 +366,7 @@ dotnet_diagnostic.IDE0130.severity = suggestion
dotnet_diagnostic.IDE0060.severity = suggestion
# CA1805: Do not initialize unnecessarily
-dotnet_diagnostic.CA1805.severity = warning
\ No newline at end of file
+dotnet_diagnostic.CA1805.severity = warning
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+tab_width = 4
\ No newline at end of file
diff --git a/SFML.sln b/SFML.sln
index f25045b8..c062dbb2 100644
--- a/SFML.sln
+++ b/SFML.sln
@@ -18,6 +18,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
EndProjectSection
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{0A84335E-59C1-4969-9F5F-4D42DC7F2BFC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SFML.System.Test", "test\SFML.System.Test\SFML.System.Test.csproj", "{90D86010-580C-4D2A-8AD1-C18CD982C5A0}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -88,10 +92,25 @@ Global
{88DD6B5D-3013-4737-A77C-EC2563FCED38}.Release|x64.Build.0 = Release|x64
{88DD6B5D-3013-4737-A77C-EC2563FCED38}.Release|x86.ActiveCfg = Release|x86
{88DD6B5D-3013-4737-A77C-EC2563FCED38}.Release|x86.Build.0 = Release|x86
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0}.Debug|x64.ActiveCfg = Debug|x64
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0}.Debug|x64.Build.0 = Debug|x64
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0}.Debug|x86.ActiveCfg = Debug|x86
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0}.Debug|x86.Build.0 = Debug|x86
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0}.Release|x64.ActiveCfg = Release|x64
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0}.Release|x64.Build.0 = Release|x64
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0}.Release|x86.ActiveCfg = Release|x86
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {90D86010-580C-4D2A-8AD1-C18CD982C5A0} = {0A84335E-59C1-4969-9F5F-4D42DC7F2BFC}
+ EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {384AFDD8-7EEF-462A-B496-B5F71D0EEF1D}
EndGlobalSection
diff --git a/src/SFML.Audio/Cone.cs b/src/SFML.Audio/Cone.cs
new file mode 100644
index 00000000..420ebec8
--- /dev/null
+++ b/src/SFML.Audio/Cone.cs
@@ -0,0 +1,50 @@
+using System.Runtime.InteropServices;
+using SFML.System;
+
+namespace SFML.Audio
+{
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Structure defining the properties of a directional cone
+ ///
+ /// Sounds will play at gain 1 when they are positioned
+ /// within the inner angle of the cone. Sounds will play
+ /// at outerGain when they are positioned outside the
+ /// outer angle of the cone. The gain declines linearly
+ /// from 1 to outerGain as the sound moves from the inner
+ /// angle to the outer angle.
+ ///
+ ////////////////////////////////////////////////////////////
+ public struct Cone
+ {
+ /// Inner angle
+ public Angle InnerAngle;
+
+ /// Outer angle
+ public Angle OuterAngle;
+
+ /// Outer angle
+ public float OuterGain;
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct MarshalData
+ {
+ public float InnerAngleDegrees;
+ public float OuterAngleDegrees;
+ public float OuterGain;
+ }
+
+ // Return a marshalled version of the instance, that can directly be passed to the C API
+ internal MarshalData Marshal()
+ {
+ var data = new MarshalData
+ {
+ InnerAngleDegrees = InnerAngle.Degrees,
+ OuterAngleDegrees = OuterAngle.Degrees,
+ OuterGain = OuterGain
+ };
+
+ return data;
+ }
+ }
+}
diff --git a/src/SFML.Audio/Listener.cs b/src/SFML.Audio/Listener.cs
index bea4d727..0d2699a5 100644
--- a/src/SFML.Audio/Listener.cs
+++ b/src/SFML.Audio/Listener.cs
@@ -1,3 +1,4 @@
+using System;
using System.Runtime.InteropServices;
using System.Security;
using SFML.System;
@@ -52,6 +53,29 @@ public static Vector3f Direction
set => sfListener_setDirection(value);
}
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The velocity of the listener in the scene (default is (0, 0, -1))
+ ///
+ ////////////////////////////////////////////////////////////
+ public static Vector3f Velocity
+ {
+ get => throw new NotImplementedException("TODO Implement when CSFML is ready.");
+ set => throw new NotImplementedException("TODO Implement when CSFML is ready.");
+ }
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The cone defines how directional attenuation is applied.
+ /// The default cone of a sound is {2 * PI, 2 * PI, 1}.
+ ///
+ ////////////////////////////////////////////////////////////
+ public static Cone Cone
+ {
+ get => throw new NotImplementedException("TODO Implement when CSFML is ready.");
+ set => throw new NotImplementedException("TODO Implement when CSFML is ready.");
+ }
+
////////////////////////////////////////////////////////////
///
/// The up vector is the vector that points upward from the
diff --git a/src/SFML.Audio/Music.cs b/src/SFML.Audio/Music.cs
index 47508468..dbe9c788 100644
--- a/src/SFML.Audio/Music.cs
+++ b/src/SFML.Audio/Music.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
@@ -132,6 +133,16 @@ public Music(byte[] bytes) :
////////////////////////////////////////////////////////////
public uint SampleRate => sfMusic_getSampleRate(CPointer);
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Get the map of position in sample frame to sound channel
+ ///
+ /// This is used to map a sample in the sample stream to a
+ /// position during spatialisation.
+ ///
+ ////////////////////////////////////////////////////////////
+ public IEnumerable ChannelMap => throw new NotImplementedException("TODO CSFML implementation.");
+
////////////////////////////////////////////////////////////
///
/// Number of channels (1 = mono, 2 = stereo)
@@ -165,8 +176,8 @@ public Music(byte[] bytes) :
////////////////////////////////////////////////////////////
public bool Loop
{
- get => sfMusic_getLoop(CPointer);
- set => sfMusic_setLoop(CPointer, value);
+ get => sfMusic_isLooping(CPointer);
+ set => sfMusic_setLooping(CPointer, value);
}
////////////////////////////////////////////////////////////
@@ -421,7 +432,7 @@ public TimeSpan(Time offset, Time length)
private static extern void sfMusic_setPitch(IntPtr music, float pitch);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfMusic_setLoop(IntPtr music, bool loop);
+ private static extern void sfMusic_setLooping(IntPtr music, bool loop);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfMusic_setVolume(IntPtr music, float volume);
@@ -442,7 +453,7 @@ public TimeSpan(Time offset, Time length)
private static extern void sfMusic_setPlayingOffset(IntPtr music, Time timeOffset);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern bool sfMusic_getLoop(IntPtr music);
+ private static extern bool sfMusic_isLooping(IntPtr music);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern float sfMusic_getPitch(IntPtr music);
diff --git a/src/SFML.Audio/Sound.cs b/src/SFML.Audio/Sound.cs
index b2507b4b..62e3e687 100644
--- a/src/SFML.Audio/Sound.cs
+++ b/src/SFML.Audio/Sound.cs
@@ -29,16 +29,6 @@ public enum SoundStatus
////////////////////////////////////////////////////////////
public class Sound : ObjectBase
{
- ////////////////////////////////////////////////////////////
- ///
- /// Default constructor (invalid sound)
- ///
- ////////////////////////////////////////////////////////////
- public Sound() :
- base(sfSound_create())
- {
- }
-
////////////////////////////////////////////////////////////
///
/// Construct the sound with a buffer
@@ -46,7 +36,7 @@ public Sound() :
/// Sound buffer containing the audio data to play with the sound
////////////////////////////////////////////////////////////
public Sound(SoundBuffer buffer) :
- base(sfSound_create()) => SoundBuffer = buffer;
+ base(sfSound_create(buffer.CPointer)) => SoundBuffer = buffer;
////////////////////////////////////////////////////////////
///
@@ -125,8 +115,8 @@ public SoundBuffer SoundBuffer
////////////////////////////////////////////////////////////
public bool Loop
{
- get => sfSound_getLoop(CPointer);
- set => sfSound_setLoop(CPointer, value);
+ get => sfSound_isLooping(CPointer);
+ set => sfSound_setLooping(CPointer, value);
}
////////////////////////////////////////////////////////////
@@ -282,7 +272,7 @@ public override string ToString()
#region Imports
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfSound_create();
+ private static extern IntPtr sfSound_create(IntPtr soundBuffer);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern IntPtr sfSound_copy(IntPtr sound);
@@ -303,10 +293,10 @@ public override string ToString()
private static extern void sfSound_setBuffer(IntPtr sound, IntPtr buffer);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfSound_setLoop(IntPtr sound, bool loop);
+ private static extern void sfSound_setLooping(IntPtr sound, bool loop);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern bool sfSound_getLoop(IntPtr sound);
+ private static extern bool sfSound_isLooping(IntPtr sound);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern SoundStatus sfSound_getStatus(IntPtr sound);
diff --git a/src/SFML.Audio/SoundBuffer.cs b/src/SFML.Audio/SoundBuffer.cs
index 2eee6269..d7af42e1 100644
--- a/src/SFML.Audio/SoundBuffer.cs
+++ b/src/SFML.Audio/SoundBuffer.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
@@ -93,16 +94,20 @@ public SoundBuffer(byte[] bytes) :
/// Array of samples
/// Channel count
/// Sample rate
+ /// Map of position in sample frame to sound channel
///
////////////////////////////////////////////////////////////
- public SoundBuffer(short[] samples, uint channelCount, uint sampleRate) :
+ public SoundBuffer(short[] samples, uint channelCount, uint sampleRate, SoundChannel[] channelMapData) :
base(IntPtr.Zero)
{
unsafe
{
fixed (short* samplesPtr = samples)
{
- CPointer = sfSoundBuffer_createFromSamples(samplesPtr, (uint)samples.Length, channelCount, sampleRate);
+ fixed (SoundChannel* channels = channelMapData)
+ {
+ CPointer = sfSoundBuffer_createFromSamples(samplesPtr, (uint)samples.Length, channelCount, sampleRate, channels, (UIntPtr)channelMapData.Length);
+ }
}
}
@@ -178,6 +183,16 @@ public short[] Samples
}
}
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Get the map of position in sample frame to sound channel
+ ///
+ /// This is used to map a sample in the sample stream to a
+ /// position during spatialisation.
+ ///
+ ////////////////////////////////////////////////////////////
+ public IEnumerable ChannelMap => throw new NotImplementedException("TODO CSFML implementation.");
+
////////////////////////////////////////////////////////////
///
/// Provide a string describing the object
@@ -216,7 +231,7 @@ public override string ToString()
private static extern unsafe IntPtr sfSoundBuffer_createFromMemory(IntPtr data, UIntPtr size);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern unsafe IntPtr sfSoundBuffer_createFromSamples(short* samples, ulong sampleCount, uint channelsCount, uint sampleRate);
+ private static extern unsafe IntPtr sfSoundBuffer_createFromSamples(short* samples, ulong sampleCount, uint channelsCount, uint sampleRate, SoundChannel* channelMapData, UIntPtr channelMapSize);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern IntPtr sfSoundBuffer_copy(IntPtr soundBuffer);
diff --git a/src/SFML.Audio/SoundBufferRecorder.cs b/src/SFML.Audio/SoundBufferRecorder.cs
index 9ab0fb08..28497f18 100644
--- a/src/SFML.Audio/SoundBufferRecorder.cs
+++ b/src/SFML.Audio/SoundBufferRecorder.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
namespace SFML.Audio
@@ -70,7 +71,7 @@ protected override bool OnProcessSamples(short[] samples)
/// Called when the current capture stops
///
////////////////////////////////////////////////////////////
- protected override void OnStop() => SoundBuffer = new SoundBuffer(_samplesArray.ToArray(), 1, SampleRate);
+ protected override void OnStop() => SoundBuffer = new SoundBuffer(_samplesArray.ToArray(), 1, SampleRate, Array.Empty()); // TODO pass in a proper array?
private readonly List _samplesArray = new List();
}
diff --git a/src/SFML.Audio/SoundChannel.cs b/src/SFML.Audio/SoundChannel.cs
new file mode 100644
index 00000000..0aa04e9d
--- /dev/null
+++ b/src/SFML.Audio/SoundChannel.cs
@@ -0,0 +1,40 @@
+namespace SFML.Audio
+{
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Types of sound channels that can be read/written from sound buffers/files
+ ///
+ /// In multi-channel audio, each sound channel can be
+ /// assigned a position. The position of the channel is
+ /// used to determine where to place a sound when it
+ /// is spatialised. Assigning an incorrect sound channel
+ /// will result in multi-channel audio being positioned
+ /// incorrectly when using spatialisation.
+ ///
+ ////////////////////////////////////////////////////////////
+#pragma warning disable CS1591 // TODO: add documentation when available
+ public enum SoundChannel
+ {
+ Unspecified,
+ Mono,
+ FrontLeft,
+ FrontRight,
+ FrontCenter,
+ FrontLeftOfCenter,
+ FrontRightOfCenter,
+ LowFrequencyEffects,
+ BackLeft,
+ BackRight,
+ BackCenter,
+ SideLeft,
+ SideRight,
+ TopCenter,
+ TopFrontLeft,
+ TopFrontRight,
+ TopFrontCenter,
+ TopBackLeft,
+ TopBackRight,
+ TopBackCenter
+ }
+#pragma warning restore CS1591
+}
diff --git a/src/SFML.Audio/SoundRecorder.cs b/src/SFML.Audio/SoundRecorder.cs
index 001416ce..de39c524 100644
--- a/src/SFML.Audio/SoundRecorder.cs
+++ b/src/SFML.Audio/SoundRecorder.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using SFML.System;
@@ -89,6 +90,16 @@ public uint ChannelCount
set => sfSoundRecorder_setChannelCount(CPointer, value);
}
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Get the map of position in sample frame to sound channel
+ ///
+ /// This is used to map a sample in the sample stream to a
+ /// position during spatialisation.
+ ///
+ ////////////////////////////////////////////////////////////
+ public IEnumerable ChannelMap => throw new NotImplementedException("TODO CSFML implementation.");
+
////////////////////////////////////////////////////////////
///
/// Check if the system supports audio capture.
@@ -163,21 +174,6 @@ protected virtual void OnStop()
// Does nothing by default
}
- ////////////////////////////////////////////////////////////
- ///
- /// The processing interval controls the period
- /// between calls to the onProcessSamples function. You may
- /// want to use a small interval if you want to process the
- /// recorded data in real time, for example.
- ///
- /// Note: this is only a hint, the actual period may vary.
- /// So don't rely on this parameter to implement precise timing.
- ///
- /// The default processing interval is 100 ms.
- ///
- ////////////////////////////////////////////////////////////
- protected void SetProcessingInterval(Time interval) => sfSoundRecorder_setProcessingInterval(CPointer, interval);
-
////////////////////////////////////////////////////////////
///
/// Get the list of the names of all available audio capture devices
@@ -302,9 +298,6 @@ private bool ProcessSamples(IntPtr samples, UIntPtr nbSamples, IntPtr userData)
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern bool sfSoundRecorder_isAvailable();
- [DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfSoundRecorder_setProcessingInterval(IntPtr soundRecorder, Time interval);
-
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern unsafe IntPtr* sfSoundRecorder_getAvailableDevices(out UIntPtr count);
diff --git a/src/SFML.Audio/SoundStream.cs b/src/SFML.Audio/SoundStream.cs
index f009930d..e872a8d7 100644
--- a/src/SFML.Audio/SoundStream.cs
+++ b/src/SFML.Audio/SoundStream.cs
@@ -92,8 +92,8 @@ public SoundStream() :
////////////////////////////////////////////////////////////
public bool Loop
{
- get => sfSoundStream_getLoop(CPointer);
- set => sfSoundStream_setLoop(CPointer, value);
+ get => sfSoundStream_isLooping(CPointer);
+ set => sfSoundStream_setLooping(CPointer, value);
}
////////////////////////////////////////////////////////////
@@ -244,12 +244,20 @@ public override string ToString()
///
/// Number of channels
/// Sample rate, in samples per second
+ /// Map of position in sample frame to sound channel
////////////////////////////////////////////////////////////
- protected void Initialize(uint channelCount, uint sampleRate)
+ protected void Initialize(uint channelCount, uint sampleRate, SoundChannel[] channelMapData)
{
_getDataCallback = new GetDataCallbackType(GetData);
_seekCallback = new SeekCallbackType(Seek);
- CPointer = sfSoundStream_create(_getDataCallback, _seekCallback, channelCount, sampleRate, IntPtr.Zero);
+
+ unsafe
+ {
+ fixed (SoundChannel* data = channelMapData)
+ {
+ CPointer = sfSoundStream_create(_getDataCallback, _seekCallback, channelCount, sampleRate, data, (UIntPtr)channelMapData.Length, IntPtr.Zero);
+ }
+ }
}
////////////////////////////////////////////////////////////
@@ -340,7 +348,7 @@ private bool GetData(ref Chunk dataChunk, IntPtr userData)
#region Imports
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfSoundStream_create(GetDataCallbackType onGetData, SeekCallbackType onSeek, uint channelCount, uint sampleRate, IntPtr userData);
+ private static extern unsafe IntPtr sfSoundStream_create(GetDataCallbackType onGetData, SeekCallbackType onSeek, uint channelCount, uint sampleRate, SoundChannel* channelMapData, UIntPtr channelMapSize, IntPtr userData);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfSoundStream_destroy(IntPtr soundStream);
@@ -364,7 +372,7 @@ private bool GetData(ref Chunk dataChunk, IntPtr userData)
private static extern uint sfSoundStream_getSampleRate(IntPtr soundStream);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfSoundStream_setLoop(IntPtr soundStream, bool loop);
+ private static extern void sfSoundStream_setLooping(IntPtr soundStream, bool loop);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfSoundStream_setPitch(IntPtr soundStream, float pitch);
@@ -388,7 +396,7 @@ private bool GetData(ref Chunk dataChunk, IntPtr userData)
private static extern void sfSoundStream_setPlayingOffset(IntPtr soundStream, Time timeOffset);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern bool sfSoundStream_getLoop(IntPtr soundStream);
+ private static extern bool sfSoundStream_isLooping(IntPtr soundStream);
[DllImport(CSFML.Audio, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern float sfSoundStream_getPitch(IntPtr soundStream);
diff --git a/src/SFML.Graphics/CircleShape.cs b/src/SFML.Graphics/CircleShape.cs
index 9b3e0a84..1f7893d9 100644
--- a/src/SFML.Graphics/CircleShape.cs
+++ b/src/SFML.Graphics/CircleShape.cs
@@ -103,6 +103,18 @@ public override Vector2f GetPoint(uint index)
return new Vector2f(_radius + x, _radius + y);
}
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Get the geometric center of the circle
+ ///
+ /// The returned point is in local coordinates, that is,
+ /// the shape's transforms (position, rotation, scale) are
+ /// not taken into account.
+ ///
+ /// The geometric center of the shape
+ ////////////////////////////////////////////////////////////
+ public override Vector2f GetGeometricCenter() => throw new NotImplementedException("TODO Implement");
+
private float _radius;
private uint _pointCount;
}
diff --git a/src/SFML.Graphics/CoordinateType.cs b/src/SFML.Graphics/CoordinateType.cs
new file mode 100644
index 00000000..fd249b1c
--- /dev/null
+++ b/src/SFML.Graphics/CoordinateType.cs
@@ -0,0 +1,13 @@
+namespace SFML.Graphics
+{
+ ///
+ /// Types of texture coordinates that can be used for rendering.
+ ///
+ public enum CoordinateType
+ {
+ /// Texture coordinates in range [0 .. 1].
+ Normalized,
+ /// Texture coordinates in range [0 .. size].
+ Pixels
+ }
+}
\ No newline at end of file
diff --git a/src/SFML.Graphics/Font.cs b/src/SFML.Graphics/Font.cs
index 7abf1b86..7f572514 100644
--- a/src/SFML.Graphics/Font.cs
+++ b/src/SFML.Graphics/Font.cs
@@ -96,6 +96,23 @@ public Font(Font copy) : base(sfFont_copy(copy.CPointer)) { }
////////////////////////////////////////////////////////////
public Glyph GetGlyph(uint codePoint, uint characterSize, bool bold, float outlineThickness) => sfFont_getGlyph(CPointer, codePoint, characterSize, bold, outlineThickness);
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Determine if this font has a glyph representing the requested code point
+ ///
+ /// Most fonts only include a very limited selection of glyphs from
+ /// specific Unicode subsets, like Latin, Cyrillic, or Asian characters.
+ ///
+ /// While code points without representation will return a font specific
+ /// default character, it might be useful to verify whether specific
+ /// code points are included to determine whether a font is suited
+ /// to display text in a specific language.
+ ///
+ /// Unicode code point to check
+ /// True if the codepoint has a glyph representation, false otherwise
+ ////////////////////////////////////////////////////////////
+ public bool HasGlyph(uint codePoint) => throw new NotImplementedException("TODO Implement");
+
////////////////////////////////////////////////////////////
///
/// Get the kerning value corresponding to a given pair of
diff --git a/src/SFML.Graphics/IRenderTarget.cs b/src/SFML.Graphics/IRenderTarget.cs
index cebdcd3c..dffd5fc2 100644
--- a/src/SFML.Graphics/IRenderTarget.cs
+++ b/src/SFML.Graphics/IRenderTarget.cs
@@ -18,7 +18,6 @@ public interface IRenderTarget
////////////////////////////////////////////////////////////
Vector2u Size { get; }
-
////////////////////////////////////////////////////////////
///
/// Tell if the render target will use sRGB encoding when drawing on it
@@ -58,6 +57,20 @@ public interface IRenderTarget
////////////////////////////////////////////////////////////
IntRect GetViewport(View view);
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Get the scissor rectangle of a view, applied to this render target
+ ///
+ /// The scissor rectangle is defined in the view as a ratio. This
+ /// function simply applies this ratio to the current dimensions
+ /// of the render target to calculate the pixels rectangle
+ /// that the scissor rectangle actually covers in the target.
+ ///
+ /// The view for which we want to compute the scissor rectangle
+ /// Scissor rectangle, expressed in pixels
+ ////////////////////////////////////////////////////////////
+ IntRect GetScissor(View view);
+
////////////////////////////////////////////////////////////
///
/// Convert a point from target coordinates to world
@@ -155,6 +168,29 @@ public interface IRenderTarget
////////////////////////////////////////////////////////////
void Clear(Color color);
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Clear the stencil buffer to a specific value
+ ///
+ /// The specified value is truncated to the bit width of
+ /// the current stencil buffer.
+ ///
+ /// Stencil value to clear to
+ ////////////////////////////////////////////////////////////
+ void ClearStencil(StencilValue stencilValue);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Clear the entire target with a single color and stencil value
+ ///
+ /// The specified stencil value is truncated to the bit
+ /// width of the current stencil buffer.
+ ///
+ /// Fill color to use to clear the render target
+ /// Stencil value to clear to
+ ////////////////////////////////////////////////////////////
+ void Clear(Color color, StencilValue stencilValue);
+
////////////////////////////////////////////////////////////
///
/// Draw a drawable object to the render-target, with default render states
@@ -214,6 +250,27 @@ public interface IRenderTarget
////////////////////////////////////////////////////////////
void Draw(Vertex[] vertices, uint start, uint count, PrimitiveType type, RenderStates states);
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Activate or deactivate the render target for rendering
+ ///
+ /// This function makes the render target's context current for
+ /// future OpenGL rendering operations (so you shouldn't care
+ /// about it if you're not doing direct OpenGL stuff).
+ /// A render target's context is active only on the current thread,
+ /// if you want to make it active on another thread you have
+ /// to deactivate it on the previous thread first if it was active.
+ /// Only one context can be current in a thread, so if you
+ /// want to draw OpenGL geometry to another render target
+ /// don't forget to activate it again. Activating a render
+ /// target will automatically deactivate the previously active
+ /// context (if any).
+ ///
+ /// True to activate, false to deactivate
+ /// True if operation was successful, false otherwise
+ ////////////////////////////////////////////////////////////
+ bool SetActive(bool active);
+
////////////////////////////////////////////////////////////
///
/// Save the current OpenGL render states and matrices.
diff --git a/src/SFML.Graphics/Image.cs b/src/SFML.Graphics/Image.cs
index 274456c4..d22ccb64 100644
--- a/src/SFML.Graphics/Image.cs
+++ b/src/SFML.Graphics/Image.cs
@@ -18,22 +18,20 @@ public class Image : ObjectBase
///
/// Construct the image with black color
///
- /// Image width
- /// Image height
+ /// Width and height of the image
///
////////////////////////////////////////////////////////////
- public Image(uint width, uint height) : this(width, height, Color.Black) { }
+ public Image(Vector2u size) : this(size, Color.Black) { }
////////////////////////////////////////////////////////////
///
/// Construct the image from a single color
///
- /// Image width
- /// Image height
+ /// Width and height of the image
/// Color to fill the image with
///
////////////////////////////////////////////////////////////
- public Image(uint width, uint height, Color color) : base(sfImage_createFromColor(width, height, color))
+ public Image(Vector2u size, Color color) : base(sfImage_createFromColor(size, color))
{
if (IsInvalid)
{
@@ -128,7 +126,7 @@ public Image(Color[,] pixels) :
{
fixed (Color* pixelsPtr = transposed)
{
- CPointer = sfImage_createFromPixels(width, height, (byte*)pixelsPtr);
+ CPointer = sfImage_createFromPixels(new Vector2u(width, height), (byte*)pixelsPtr);
}
}
@@ -142,19 +140,18 @@ public Image(Color[,] pixels) :
///
/// Construct the image directly from an array of pixels
///
- /// Image width
- /// Image height
+ /// Width and height of the image
/// array containing the pixels
///
////////////////////////////////////////////////////////////
- public Image(uint width, uint height, byte[] pixels) :
+ public Image(Vector2u size, byte[] pixels) :
base(IntPtr.Zero)
{
unsafe
{
fixed (byte* pixelsPtr = pixels)
{
- CPointer = sfImage_createFromPixels(width, height, pixelsPtr);
+ CPointer = sfImage_createFromPixels(size, pixelsPtr);
}
}
@@ -232,10 +229,9 @@ public bool SaveToMemory(out byte[] output, string format)
/// be used at initialization time
///
/// Source image to copy
- /// X coordinate of the destination position
- /// Y coordinate of the destination position
+ /// Coordinates of the destination position
////////////////////////////////////////////////////////////
- public void Copy(Image source, uint destX, uint destY) => Copy(source, destX, destY, new IntRect(0, 0, 0, 0));
+ public void Copy(Image source, Vector2u dest) => Copy(source, dest, new IntRect((0, 0), (0, 0)));
////////////////////////////////////////////////////////////
///
@@ -244,11 +240,10 @@ public bool SaveToMemory(out byte[] output, string format)
/// be used at initialization time
///
/// Source image to copy
- /// X coordinate of the destination position
- /// Y coordinate of the destination position
+ /// Coordinates of the destination position
/// Sub-rectangle of the source image to copy
////////////////////////////////////////////////////////////
- public void Copy(Image source, uint destX, uint destY, IntRect sourceRect) => Copy(source, destX, destY, sourceRect, false);
+ public void Copy(Image source, Vector2u dest, IntRect sourceRect) => Copy(source, dest, sourceRect, false);
////////////////////////////////////////////////////////////
///
@@ -257,32 +252,29 @@ public bool SaveToMemory(out byte[] output, string format)
/// be used at initialization time
///
/// Source image to copy
- /// X coordinate of the destination position
- /// Y coordinate of the destination position
+ /// Coordinates of the destination position
/// Sub-rectangle of the source image to copy
/// Should the copy take in account the source transparency?
////////////////////////////////////////////////////////////
- public void Copy(Image source, uint destX, uint destY, IntRect sourceRect, bool applyAlpha) => sfImage_copyImage(CPointer, source.CPointer, destX, destY, sourceRect, applyAlpha);
+ public void Copy(Image source, Vector2u dest, IntRect sourceRect, bool applyAlpha) => sfImage_copyImage(CPointer, source.CPointer, dest, sourceRect, applyAlpha);
////////////////////////////////////////////////////////////
///
/// Get a pixel from the image
///
- /// X coordinate of pixel in the image
- /// Y coordinate of pixel in the image
+ /// Coordinates of pixel to change
/// Color of pixel (x, y)
////////////////////////////////////////////////////////////
- public Color GetPixel(uint x, uint y) => sfImage_getPixel(CPointer, x, y);
+ public Color GetPixel(Vector2u coords) => sfImage_getPixel(CPointer, coords);
////////////////////////////////////////////////////////////
///
/// Change the color of a pixel
///
- /// X coordinate of pixel in the image
- /// Y coordinate of pixel in the image
+ /// Coordinates of pixel to change
/// New color for pixel (x, y)
////////////////////////////////////////////////////////////
- public void SetPixel(uint x, uint y, Color color) => sfImage_setPixel(CPointer, x, y, color);
+ public void SetPixel(Vector2u coords, Color color) => sfImage_setPixel(CPointer, coords, color);
////////////////////////////////////////////////////////////
///
@@ -357,10 +349,10 @@ internal Image(IntPtr cPointer) : base(cPointer) { }
#region Imports
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfImage_createFromColor(uint width, uint height, Color col);
+ private static extern IntPtr sfImage_createFromColor(Vector2u size, Color col);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern unsafe IntPtr sfImage_createFromPixels(uint width, uint height, byte* pixels);
+ private static extern unsafe IntPtr sfImage_createFromPixels(Vector2u size, byte* pixels);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern IntPtr sfImage_createFromFile(string filename);
@@ -387,13 +379,13 @@ internal Image(IntPtr cPointer) : base(cPointer) { }
private static extern void sfImage_createMaskFromColor(IntPtr cPointer, Color col, byte alpha);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfImage_copyImage(IntPtr cPointer, IntPtr source, uint destX, uint destY, IntRect sourceRect, bool applyAlpha);
+ private static extern void sfImage_copyImage(IntPtr cPointer, IntPtr source, Vector2u dest, IntRect sourceRect, bool applyAlpha);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfImage_setPixel(IntPtr cPointer, uint x, uint y, Color col);
+ private static extern void sfImage_setPixel(IntPtr cPointer, Vector2u coords, Color col);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern Color sfImage_getPixel(IntPtr cPointer, uint x, uint y);
+ private static extern Color sfImage_getPixel(IntPtr cPointer, Vector2u coords);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern IntPtr sfImage_getPixelsPtr(IntPtr cPointer);
diff --git a/src/SFML.Graphics/PrimitiveType.cs b/src/SFML.Graphics/PrimitiveType.cs
index 9068f13d..c2f68e4e 100644
--- a/src/SFML.Graphics/PrimitiveType.cs
+++ b/src/SFML.Graphics/PrimitiveType.cs
@@ -1,5 +1,3 @@
-using System;
-
namespace SFML.Graphics
{
////////////////////////////////////////////////////////////
@@ -31,21 +29,6 @@ public enum PrimitiveType
TriangleStrip,
/// Connected Triangles; each point uses the first point and the previous point to form a triangle
- TriangleFan,
-
- /// Quadrilaterals; each set of four points forms a 4-sided shape
- Quads,
-
- /// DEPRECATED: Use LineStrip
- [Obsolete("LineStrip")]
- LinesStrip = LineStrip,
-
- /// DEPRECATED: Use TriangleStrip
- [Obsolete("Use TriangleStrip")]
- TrianglesStrip = TriangleStrip,
-
- /// DEPRECATED: Use TriangleFan
- [Obsolete("Use TriangleFan")]
- TrianglesFan = TriangleFan,
+ TriangleFan
}
}
diff --git a/src/SFML.Graphics/Rect.cs b/src/SFML.Graphics/Rect.cs
index 9cfe5a01..61fe5a1d 100644
--- a/src/SFML.Graphics/Rect.cs
+++ b/src/SFML.Graphics/Rect.cs
@@ -13,23 +13,6 @@ namespace SFML.Graphics
[StructLayout(LayoutKind.Sequential)]
public struct IntRect : IEquatable
{
- ////////////////////////////////////////////////////////////
- ///
- /// Construct the rectangle from its coordinates
- ///
- /// Left coordinate of the rectangle
- /// Top coordinate of the rectangle
- /// Width of the rectangle
- /// Height of the rectangle
- ////////////////////////////////////////////////////////////
- public IntRect(int left, int top, int width, int height)
- {
- Left = left;
- Top = top;
- Width = width;
- Height = height;
- }
-
////////////////////////////////////////////////////////////
///
/// Construct the rectangle from position and size
@@ -38,39 +21,30 @@ public IntRect(int left, int top, int width, int height)
/// Size of the rectangle
////////////////////////////////////////////////////////////
public IntRect(Vector2i position, Vector2i size)
- : this(position.X, position.Y, size.X, size.Y)
{
+ Position = position;
+ Size = size;
}
////////////////////////////////////////////////////////////
///
/// Check if a point is inside the rectangle's area
///
- /// X coordinate of the point to test
- /// Y coordinate of the point to test
+ /// Point to test
/// True if the point is inside
////////////////////////////////////////////////////////////
- public bool Contains(int x, int y)
+ public bool Contains(Vector2i point)
{
var minX = Math.Min(Left, Left + Width);
var maxX = Math.Max(Left, Left + Width);
var minY = Math.Min(Top, Top + Height);
var maxY = Math.Max(Top, Top + Height);
- return (x >= minX) && (x < maxX) && (y >= minY) && (y < maxY);
+ return
+ (point.X >= minX) && (point.X < maxX) &&
+ (point.Y >= minY) && (point.Y < maxY);
}
-
- ////////////////////////////////////////////////////////////
- ///
- /// Check if a point is inside the rectangle's area
- ///
- /// Vector2 position of the point to test
- /// True if the point is inside
- ////////////////////////////////////////////////////////////
- public bool Contains(Vector2i point) => Contains(point.X, point.Y);
-
-
////////////////////////////////////////////////////////////
///
/// Check if a point is inside the rectangle's area
@@ -80,7 +54,6 @@ public bool Contains(int x, int y)
////////////////////////////////////////////////////////////
public bool Contains(Vector2u point) => Contains((Vector2i)point);
-
////////////////////////////////////////////////////////////
///
/// Check if a point is inside the rectangle's area
@@ -92,22 +65,12 @@ public bool Contains(int x, int y)
////////////////////////////////////////////////////////////
///
- /// Check intersection between two rectangles
+ /// Check the intersection between two rectangles
///
/// Rectangle to test
- /// True if rectangles overlap
+ /// Intersection rectangle if intersecting, null otherwise
////////////////////////////////////////////////////////////
- public bool Intersects(IntRect rect) => Intersects(rect, out _);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Check intersection between two rectangles
- ///
- /// Rectangle to test
- /// Rectangle to be filled with overlapping rect
- /// True if rectangles overlap
- ////////////////////////////////////////////////////////////
- public bool Intersects(IntRect rect, out IntRect overlap)
+ public IntRect? FindIntersection(IntRect rect)
{
// Rectangles with negative dimensions are allowed, so we must handle them correctly
@@ -132,38 +95,14 @@ public bool Intersects(IntRect rect, out IntRect overlap)
// If the intersection is valid (positive non zero area), then there is an intersection
if ((interLeft < interRight) && (interTop < interBottom))
{
- overlap.Left = interLeft;
- overlap.Top = interTop;
- overlap.Width = interRight - interLeft;
- overlap.Height = interBottom - interTop;
- return true;
+ return new IntRect((interLeft, interTop), (interRight - interLeft, interBottom - interTop));
}
else
{
- overlap.Left = 0;
- overlap.Top = 0;
- overlap.Width = 0;
- overlap.Height = 0;
- return false;
+ return null;
}
}
- ////////////////////////////////////////////////////////////
- ///
- /// Get the position of the rectangle's top-left corner
- ///
- /// Position of rectangle
- ////////////////////////////////////////////////////////////
- public Vector2i Position => new Vector2i(Left, Top);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Get the size of the rectangle
- ///
- /// Size of rectangle
- ////////////////////////////////////////////////////////////
- public Vector2i Size => new Vector2i(Width, Height);
-
///
/// Deconstructs an IntRect into a tuple of ints
///
@@ -173,10 +112,10 @@ public bool Intersects(IntRect rect, out IntRect overlap)
/// Height of the rectangle
public void Deconstruct(out int left, out int top, out int width, out int height)
{
- left = Left;
- top = Top;
- width = Width;
- height = Height;
+ left = Position.X;
+ top = Position.Y;
+ width = Size.X;
+ height = Size.Y;
}
////////////////////////////////////////////////////////////
@@ -185,7 +124,7 @@ public void Deconstruct(out int left, out int top, out int width, out int height
///
/// String description of the object
////////////////////////////////////////////////////////////
- public override string ToString() => $"[IntRect] Left({Left}) Top({Top}) Width({Width}) Height({Height})";
+ public override string ToString() => $"[IntRect] Position({Left}, {Top}) Size({Width}, {Height})";
////////////////////////////////////////////////////////////
///
@@ -194,7 +133,7 @@ public void Deconstruct(out int left, out int top, out int width, out int height
/// Object to check
/// Object and rectangle are equal
////////////////////////////////////////////////////////////
- public override bool Equals(object obj) => (obj is IntRect) && Equals((IntRect)obj);
+ public override bool Equals(object obj) => (obj is IntRect rect) && Equals(rect);
///////////////////////////////////////////////////////////
///
@@ -243,7 +182,7 @@ public override int GetHashCode() => unchecked((int)((uint)Left ^
/// Converts a tuple of ints to an IntRect
///
/// The tuple to convert
- public static implicit operator IntRect((int Left, int Top, int Width, int Height) tuple) => new IntRect(tuple.Left, tuple.Top, tuple.Width, tuple.Height);
+ public static implicit operator IntRect((int Left, int Top, int Width, int Height) tuple) => new IntRect((tuple.Left, tuple.Top), (tuple.Width, tuple.Height));
////////////////////////////////////////////////////////////
///
@@ -252,22 +191,30 @@ public override int GetHashCode() => unchecked((int)((uint)Left ^
/// Rectangle being casted
/// Casting result
////////////////////////////////////////////////////////////
- public static explicit operator FloatRect(IntRect r) => new FloatRect(r.Left,
- r.Top,
- r.Width,
- r.Height);
+ public static explicit operator FloatRect(IntRect r) => new FloatRect(
+ (r.Left, r.Top),
+ (r.Width, r.Height));
/// Left coordinate of the rectangle
- public int Left;
+ public int Left => Position.X;
/// Top coordinate of the rectangle
- public int Top;
+ public int Top => Position.Y;
/// Width of the rectangle
- public int Width;
+ public int Width => Size.X;
/// Height of the rectangle
- public int Height;
+ public int Height => Size.Y;
+
+ /// Position of the center of the rectangle
+ public Vector2i Center => Position + (Size / 2);
+
+ /// Position of the top-left corner of the rectangle
+ public Vector2i Position;
+
+ /// Size of the rectangle
+ public Vector2i Size;
}
////////////////////////////////////////////////////////////
@@ -279,23 +226,6 @@ public override int GetHashCode() => unchecked((int)((uint)Left ^
[StructLayout(LayoutKind.Sequential)]
public struct FloatRect : IEquatable
{
- ////////////////////////////////////////////////////////////
- ///
- /// Construct the rectangle from its coordinates
- ///
- /// Left coordinate of the rectangle
- /// Top coordinate of the rectangle
- /// Width of the rectangle
- /// Height of the rectangle
- ////////////////////////////////////////////////////////////
- public FloatRect(float left, float top, float width, float height)
- {
- Left = left;
- Top = top;
- Width = width;
- Height = height;
- }
-
////////////////////////////////////////////////////////////
///
/// Construct the rectangle from position and size
@@ -304,37 +234,28 @@ public FloatRect(float left, float top, float width, float height)
/// Size of the rectangle
////////////////////////////////////////////////////////////
public FloatRect(Vector2f position, Vector2f size)
- : this(position.X, position.Y, size.X, size.Y)
{
+ Position = position;
+ Size = size;
}
////////////////////////////////////////////////////////////
///
/// Check if a point is inside the rectangle's area
///
- /// X coordinate of the point to test
- /// Y coordinate of the point to test
+ /// Point to test
/// True if the point is inside
////////////////////////////////////////////////////////////
- public bool Contains(float x, float y)
+ public bool Contains(Vector2f point)
{
var minX = Math.Min(Left, Left + Width);
var maxX = Math.Max(Left, Left + Width);
var minY = Math.Min(Top, Top + Height);
var maxY = Math.Max(Top, Top + Height);
- return (x >= minX) && (x < maxX) && (y >= minY) && (y < maxY);
+ return (point.X >= minX) && (point.X < maxX) && (point.Y >= minY) && (point.Y < maxY);
}
- ////////////////////////////////////////////////////////////
- ///
- /// Check if a point is inside the rectangle's area
- ///
- /// Vector2 position of the point to test
- /// True if the point is inside
- ////////////////////////////////////////////////////////////
- public bool Contains(Vector2f point) => Contains(point.X, point.Y);
-
////////////////////////////////////////////////////////////
///
/// Check if a point is inside the rectangle's area
@@ -344,7 +265,6 @@ public bool Contains(float x, float y)
////////////////////////////////////////////////////////////
public bool Contains(Vector2i point) => Contains((Vector2f)point);
-
////////////////////////////////////////////////////////////
///
/// Check if a point is inside the rectangle's area
@@ -361,17 +281,7 @@ public bool Contains(float x, float y)
/// Rectangle to test
/// True if rectangles overlap
////////////////////////////////////////////////////////////
- public bool Intersects(FloatRect rect) => Intersects(rect, out _);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Check intersection between two rectangles
- ///
- /// Rectangle to test
- /// Rectangle to be filled with overlapping rect
- /// True if rectangles overlap
- ////////////////////////////////////////////////////////////
- public bool Intersects(FloatRect rect, out FloatRect overlap)
+ public FloatRect? FindIntersection(FloatRect rect)
{
// Rectangles with negative dimensions are allowed, so we must handle them correctly
@@ -396,38 +306,14 @@ public bool Intersects(FloatRect rect, out FloatRect overlap)
// If the intersection is valid (positive non zero area), then there is an intersection
if ((interLeft < interRight) && (interTop < interBottom))
{
- overlap.Left = interLeft;
- overlap.Top = interTop;
- overlap.Width = interRight - interLeft;
- overlap.Height = interBottom - interTop;
- return true;
+ return new FloatRect((interLeft, interTop), (interRight - interLeft, interBottom - interTop));
}
else
{
- overlap.Left = 0;
- overlap.Top = 0;
- overlap.Width = 0;
- overlap.Height = 0;
- return false;
+ return null;
}
}
- ////////////////////////////////////////////////////////////
- ///
- /// Get the position of the rectangle's top-left corner
- ///
- /// Position of rectangle
- ////////////////////////////////////////////////////////////
- public Vector2f Position => new Vector2f(Left, Top);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Get the size of the rectangle
- ///
- /// Size of rectangle
- ////////////////////////////////////////////////////////////
- public Vector2f Size => new Vector2f(Width, Height);
-
///
/// Deconstructs a FloatRect into a tuple of floats
///
@@ -449,11 +335,7 @@ public void Deconstruct(out float left, out float top, out float width, out floa
///
/// String description of the object
////////////////////////////////////////////////////////////
- public override string ToString() => "[FloatRect]" +
- " Left(" + Left + ")" +
- " Top(" + Top + ")" +
- " Width(" + Width + ")" +
- " Height(" + Height + ")";
+ public override string ToString() => $"[FloatRect] Position({Left}, {Top}) Size({Width}, {Height})";
////////////////////////////////////////////////////////////
///
@@ -462,7 +344,7 @@ public override string ToString() => "[FloatRect]" +
/// Object to check
/// Object and rectangle are equal
////////////////////////////////////////////////////////////
- public override bool Equals(object obj) => (obj is FloatRect) && Equals((FloatRect)obj);
+ public override bool Equals(object obj) => (obj is FloatRect rect) && Equals(rect);
///////////////////////////////////////////////////////////
///
@@ -471,10 +353,9 @@ public override string ToString() => "[FloatRect]" +
/// Rectangle to check
/// Rectangles are equal
////////////////////////////////////////////////////////////
- public bool Equals(FloatRect other) => (Left == other.Left) &&
- (Top == other.Top) &&
- (Width == other.Width) &&
- (Height == other.Height);
+ public bool Equals(FloatRect other) =>
+ Position == other.Position &&
+ Size == other.Size;
////////////////////////////////////////////////////////////
///
@@ -511,7 +392,7 @@ public override int GetHashCode() => unchecked((int)((uint)Left ^
/// Converts a tuple of floats to a FloatRect
///
/// The tuple to convert
- public static implicit operator FloatRect((float Left, float Top, float Width, float Height) tuple) => new FloatRect(tuple.Left, tuple.Top, tuple.Width, tuple.Height);
+ public static implicit operator FloatRect((float Left, float Top, float Width, float Height) tuple) => new FloatRect((tuple.Left, tuple.Top), (tuple.Width, tuple.Height));
////////////////////////////////////////////////////////////
///
@@ -520,21 +401,29 @@ public override int GetHashCode() => unchecked((int)((uint)Left ^
/// Rectangle being casted
/// Casting result
////////////////////////////////////////////////////////////
- public static explicit operator IntRect(FloatRect r) => new IntRect((int)r.Left,
- (int)r.Top,
- (int)r.Width,
- (int)r.Height);
+ public static explicit operator IntRect(FloatRect r) => new IntRect(
+ ((int)r.Left, (int)r.Top),
+ ((int)r.Width, (int)r.Height));
/// Left coordinate of the rectangle
- public float Left;
+ public float Left => Position.X;
/// Top coordinate of the rectangle
- public float Top;
+ public float Top => Position.Y;
/// Width of the rectangle
- public float Width;
+ public float Width => Size.X;
/// Height of the rectangle
- public float Height;
+ public float Height => Size.Y;
+
+ /// Position of the center of the rectangle
+ public Vector2f Center => Position + (Size / 2f);
+
+ /// Position of the top-left corner of the rectangle
+ public Vector2f Position;
+
+ /// Size of the rectangle
+ public Vector2f Size;
}
}
diff --git a/src/SFML.Graphics/RectangleShape.cs b/src/SFML.Graphics/RectangleShape.cs
index d5dae6e5..edf1fc4d 100644
--- a/src/SFML.Graphics/RectangleShape.cs
+++ b/src/SFML.Graphics/RectangleShape.cs
@@ -1,3 +1,4 @@
+using System;
using SFML.System;
namespace SFML.Graphics
@@ -44,7 +45,11 @@ public RectangleShape(RectangleShape copy) :
public Vector2f Size
{
get => _size;
- set { _size = value; Update(); }
+ set
+ {
+ _size = value;
+ Update();
+ }
}
////////////////////////////////////////////////////////////
@@ -84,6 +89,19 @@ public override Vector2f GetPoint(uint index)
}
}
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Get the geometric center of the rectangle
+ ///
+ /// The returned point is in local coordinates, that is,
+ /// the shape's transforms (position, rotation, scale) are
+ /// not taken into account.
+ ///
+ ///
+ /// The geometric center of the shape
+ ////////////////////////////////////////////////////////////
+ public override Vector2f GetGeometricCenter() => throw new NotImplementedException("TODO Implement");
+
private Vector2f _size;
}
}
diff --git a/src/SFML.Graphics/RenderStates.cs b/src/SFML.Graphics/RenderStates.cs
index 0531395d..c7a5a5fd 100644
--- a/src/SFML.Graphics/RenderStates.cs
+++ b/src/SFML.Graphics/RenderStates.cs
@@ -17,7 +17,18 @@ public struct RenderStates
/// Blend mode to use
////////////////////////////////////////////////////////////
public RenderStates(BlendMode blendMode) :
- this(blendMode, Transform.Identity, null, null)
+ this(blendMode, StencilMode.Default, Transform.Identity, CoordinateType.Pixels, null, null)
+ {
+ }
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Construct a default set of render states with a custom stencil mode
+ ///
+ /// Stencil mode to use
+ ////////////////////////////////////////////////////////////
+ public RenderStates(StencilMode stencilMode) :
+ this(BlendMode.Alpha, stencilMode, Transform.Identity, CoordinateType.Pixels, null, null)
{
}
@@ -28,7 +39,7 @@ public RenderStates(BlendMode blendMode) :
/// Transform to use
////////////////////////////////////////////////////////////
public RenderStates(Transform transform) :
- this(BlendMode.Alpha, transform, null, null)
+ this(BlendMode.Alpha, StencilMode.Default, transform, CoordinateType.Pixels, null, null)
{
}
@@ -39,7 +50,7 @@ public RenderStates(Transform transform) :
/// Texture to use
////////////////////////////////////////////////////////////
public RenderStates(Texture texture) :
- this(BlendMode.Alpha, Transform.Identity, texture, null)
+ this(BlendMode.Alpha, StencilMode.Default, Transform.Identity, CoordinateType.Pixels, texture, null)
{
}
@@ -50,7 +61,7 @@ public RenderStates(Texture texture) :
/// Shader to use
////////////////////////////////////////////////////////////
public RenderStates(Shader shader) :
- this(BlendMode.Alpha, Transform.Identity, null, shader)
+ this(BlendMode.Alpha, StencilMode.Default, Transform.Identity, CoordinateType.Pixels, null, shader)
{
}
@@ -59,14 +70,18 @@ public RenderStates(Shader shader) :
/// Construct a set of render states with all its attributes
///
/// Blend mode to use
+ /// Stencil mode to use
/// Transform to use
+ /// Coordinate type to use
/// Texture to use
/// Shader to use
////////////////////////////////////////////////////////////
- public RenderStates(BlendMode blendMode, Transform transform, Texture texture, Shader shader)
+ public RenderStates(BlendMode blendMode, StencilMode stencilMode, Transform transform, CoordinateType coordinateType, Texture texture, Shader shader)
{
BlendMode = blendMode;
+ StencilMode = stencilMode;
Transform = transform;
+ CoordinateType = coordinateType;
Texture = texture;
Shader = shader;
}
@@ -80,7 +95,9 @@ public RenderStates(BlendMode blendMode, Transform transform, Texture texture, S
public RenderStates(RenderStates copy)
{
BlendMode = copy.BlendMode;
+ StencilMode = copy.StencilMode;
Transform = copy.Transform;
+ CoordinateType = copy.CoordinateType;
Texture = copy.Texture;
Shader = copy.Shader;
}
@@ -88,14 +105,20 @@ public RenderStates(RenderStates copy)
////////////////////////////////////////////////////////////
/// Special instance holding the default render states
////////////////////////////////////////////////////////////
- public static RenderStates Default => new RenderStates(BlendMode.Alpha, Transform.Identity, null, null);
+ public static RenderStates Default => new RenderStates(BlendMode.Alpha, StencilMode.Default, Transform.Identity, CoordinateType.Pixels, null, null);
/// Blending mode
public BlendMode BlendMode;
+ /// Stencil mode
+ public StencilMode StencilMode;
+
/// Transform
public Transform Transform;
+ /// Texture coordinate type
+ public CoordinateType CoordinateType;
+
/// Texture
public Texture Texture;
@@ -108,7 +131,9 @@ internal MarshalData Marshal()
var data = new MarshalData
{
BlendMode = BlendMode,
+ StencilMode = StencilMode,
Transform = Transform,
+ CoordinateType = CoordinateType,
Texture = Texture != null ? Texture.CPointer : IntPtr.Zero,
Shader = Shader != null ? Shader.CPointer : IntPtr.Zero
};
@@ -120,7 +145,9 @@ internal MarshalData Marshal()
internal struct MarshalData
{
public BlendMode BlendMode;
+ public StencilMode StencilMode;
public Transform Transform;
+ public CoordinateType CoordinateType;
public IntPtr Texture;
public IntPtr Shader;
}
diff --git a/src/SFML.Graphics/RenderTexture.cs b/src/SFML.Graphics/RenderTexture.cs
index 98dd0500..f171ef89 100644
--- a/src/SFML.Graphics/RenderTexture.cs
+++ b/src/SFML.Graphics/RenderTexture.cs
@@ -17,44 +17,23 @@ public class RenderTexture : ObjectBase, IRenderTarget
///
/// Create the render-texture with the given dimensions
///
- /// Width of the render-texture
- /// Height of the render-texture
+ /// Width and height of the render-texture
////////////////////////////////////////////////////////////
- public RenderTexture(uint width, uint height) :
- this(width, height, default(ContextSettings))
+ public RenderTexture(Vector2u size) :
+ this(size, default)
{
}
- ////////////////////////////////////////////////////////////
- ///
- /// Create the render-texture with the given dimensions and
- /// an optional depth-buffer attached
- ///
- /// Width of the render-texture
- /// Height of the render-texture
- /// Do you want a depth-buffer attached?
- ////////////////////////////////////////////////////////////
- [Obsolete("Use RenderTexture(width, height, contextSettings)")]
- public RenderTexture(uint width, uint height, bool depthBuffer) :
- base(sfRenderTexture_create(width, height, depthBuffer))
- {
- _defaultView = new View(sfRenderTexture_getDefaultView(CPointer));
- Texture = new Texture(sfRenderTexture_getTexture(CPointer));
- GC.SuppressFinalize(_defaultView);
- GC.SuppressFinalize(Texture);
- }
-
////////////////////////////////////////////////////////////
///
/// Create the render-texture with the given dimensions and
/// a ContextSettings.
///
- /// Width of the render-texture
- /// Height of the render-texture
+ /// Width and height of the render-texture
/// A ContextSettings struct representing settings for the RenderTexture
////////////////////////////////////////////////////////////
- public RenderTexture(uint width, uint height, ContextSettings contextSettings) :
- base(sfRenderTexture_createWithSettings(width, height, ref contextSettings))
+ public RenderTexture(Vector2u size, ContextSettings contextSettings) :
+ base(sfRenderTexture_create(size, ref contextSettings))
{
_defaultView = new View(sfRenderTexture_getDefaultView(CPointer));
Texture = new Texture(sfRenderTexture_getTexture(CPointer));
@@ -134,6 +113,20 @@ public bool Repeated
////////////////////////////////////////////////////////////
public IntRect GetViewport(View view) => sfRenderTexture_getViewport(CPointer, view.CPointer);
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Get the scissor rectangle of a view, applied to this render target
+ ///
+ /// The scissor rectangle is defined in the view as a ratio. This
+ /// function simply applies this ratio to the current dimensions
+ /// of the render target to calculate the pixels rectangle
+ /// that the scissor rectangle actually covers in the target.
+ ///
+ /// The view for which we want to compute the scissor rectangle
+ /// Scissor rectangle, expressed in pixels
+ ////////////////////////////////////////////////////////////
+ public IntRect GetScissor(View view) => sfRenderTexture_getScissor(CPointer, view.CPointer);
+
////////////////////////////////////////////////////////////
///
/// Convert a point from target coordinates to world
@@ -250,6 +243,29 @@ public bool Repeated
////////////////////////////////////////////////////////////
public void Clear(Color color) => sfRenderTexture_clear(CPointer, color);
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Clear the entire target with a single color and stencil value
+ ///
+ /// The specified stencil value is truncated to the bit
+ /// width of the current stencil buffer.
+ ///
+ /// Fill color to use to clear the render target
+ /// Stencil value to clear to
+ ////////////////////////////////////////////////////////////
+ public void Clear(Color color, StencilValue stencilValue) => sfRenderTexture_clearColorAndStencil(CPointer, color, stencilValue);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Clear the stencil buffer to a specific value
+ ///
+ /// The specified value is truncated to the bit width of
+ /// the current stencil buffer.
+ ///
+ /// Stencil value to clear to
+ ////////////////////////////////////////////////////////////
+ public void ClearStencil(StencilValue stencilValue) => sfRenderTexture_clearStencil(CPointer, stencilValue);
+
////////////////////////////////////////////////////////////
///
/// Update the contents of the target texture
@@ -269,7 +285,7 @@ public bool Repeated
/// The maximum anti-aliasing level supported by the system
///
////////////////////////////////////////////////////////////
- public static uint MaximumAntialiasingLevel => sfRenderTexture_getMaximumAntialiasingLevel();
+ public static uint MaximumAntiAliasingLevel => sfRenderTexture_getMaximumAntiAliasingLevel();
////////////////////////////////////////////////////////////
///
@@ -467,11 +483,8 @@ protected override void Destroy(bool disposing)
private readonly View _defaultView;
#region Imports
- [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity, Obsolete]
- private static extern IntPtr sfRenderTexture_create(uint width, uint height, bool depthBuffer);
-
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfRenderTexture_createWithSettings(uint width, uint height, ref ContextSettings settings);
+ private static extern IntPtr sfRenderTexture_create(Vector2u size, ref ContextSettings settings);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfRenderTexture_destroy(IntPtr cPointer);
@@ -479,6 +492,12 @@ protected override void Destroy(bool disposing)
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfRenderTexture_clear(IntPtr cPointer, Color clearColor);
+ [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+ private static extern void sfRenderTexture_clearStencil(IntPtr cPointer, StencilValue stencilValue);
+
+ [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+ private static extern void sfRenderTexture_clearColorAndStencil(IntPtr cPointer, Color clearColor, StencilValue stencilValue);
+
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern Vector2u sfRenderTexture_getSize(IntPtr cPointer);
@@ -503,6 +522,9 @@ protected override void Destroy(bool disposing)
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern IntRect sfRenderTexture_getViewport(IntPtr cPointer, IntPtr targetView);
+ [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+ private static extern IntRect sfRenderTexture_getScissor(IntPtr cPointer, IntPtr targetView);
+
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern Vector2i sfRenderTexture_mapCoordsToPixel(IntPtr cPointer, Vector2f point, IntPtr view);
@@ -513,7 +535,7 @@ protected override void Destroy(bool disposing)
private static extern IntPtr sfRenderTexture_getTexture(IntPtr cPointer);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern uint sfRenderTexture_getMaximumAntialiasingLevel();
+ private static extern uint sfRenderTexture_getMaximumAntiAliasingLevel();
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfRenderTexture_setSmooth(IntPtr cPointer, bool smooth);
diff --git a/src/SFML.Graphics/RenderWindow.cs b/src/SFML.Graphics/RenderWindow.cs
index 838db6c1..ae3318dc 100644
--- a/src/SFML.Graphics/RenderWindow.cs
+++ b/src/SFML.Graphics/RenderWindow.cs
@@ -17,13 +17,13 @@ public class RenderWindow : Window.Window, IRenderTarget
{
////////////////////////////////////////////////////////////
///
- /// Create the window with default style and creation settings
+ /// Create the window with default style, state and creation settings
///
/// Video mode to use
/// Title of the window
////////////////////////////////////////////////////////////
public RenderWindow(VideoMode mode, string title) :
- this(mode, title, Styles.Default, new ContextSettings(0, 0))
+ this(mode, title, Styles.Default, State.Windowed, new ContextSettings(0, 0))
{
}
@@ -34,9 +34,10 @@ public RenderWindow(VideoMode mode, string title) :
/// Video mode to use
/// Title of the window
/// Window style (Resize | Close by default)
+ /// Window state
////////////////////////////////////////////////////////////
- public RenderWindow(VideoMode mode, string title, Styles style) :
- this(mode, title, style, new ContextSettings(0, 0))
+ public RenderWindow(VideoMode mode, string title, Styles style, State state) :
+ this(mode, title, style, state, new ContextSettings(0, 0))
{
}
@@ -47,9 +48,10 @@ public RenderWindow(VideoMode mode, string title, Styles style) :
/// Video mode to use
/// Title of the window
/// Window style (Resize | Close by default)
+ /// Window state
/// Creation parameters
////////////////////////////////////////////////////////////
- public RenderWindow(VideoMode mode, string title, Styles style, ContextSettings settings) :
+ public RenderWindow(VideoMode mode, string title, Styles style, State state, ContextSettings settings) :
base(IntPtr.Zero, 0)
{
// Copy the string to a null-terminated UTF-32 byte array
@@ -59,7 +61,7 @@ public RenderWindow(VideoMode mode, string title, Styles style, ContextSettings
{
fixed (byte* titlePtr = titleAsUtf32)
{
- CPointer = sfRenderWindow_createUnicode(mode, (IntPtr)titlePtr, style, ref settings);
+ CPointer = sfRenderWindow_createUnicode(mode, (IntPtr)titlePtr, style, state, ref settings); // TODO API
}
}
Initialize();
@@ -165,17 +167,16 @@ public override void SetTitle(string title)
///
/// Change the window's icon
///
- /// Icon's width, in pixels
- /// Icon's height, in pixels
+ /// Icon's width and height, in pixels
/// Array of pixels, format must be RGBA 32 bits
////////////////////////////////////////////////////////////
- public override void SetIcon(uint width, uint height, byte[] pixels)
+ public override void SetIcon(Vector2u size, byte[] pixels)
{
unsafe
{
fixed (byte* pixelsPtr = pixels)
{
- sfRenderWindow_setIcon(CPointer, width, height, pixelsPtr);
+ sfRenderWindow_setIcon(CPointer, size, pixelsPtr); // TODO API
}
}
}
@@ -304,7 +305,7 @@ public override void SetIcon(uint width, uint height, byte[] pixels)
/// OS-specific handle of the window
///
////////////////////////////////////////////////////////////
- public override IntPtr SystemHandle => sfRenderWindow_getSystemHandle(CPointer);
+ public override IntPtr NativeHandle => sfRenderWindow_getNativeHandle(CPointer); // TODO API
////////////////////////////////////////////////////////////
///
@@ -321,6 +322,30 @@ public override void SetIcon(uint width, uint height, byte[] pixels)
////////////////////////////////////////////////////////////
public void Clear(Color color) => sfRenderWindow_clear(CPointer, color);
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Clear the entire target with a single color and stencil value
+ ///
+ /// The specified stencil value is truncated to the bit
+ /// width of the current stencil buffer.
+ ///
+ /// Fill color to use to clear the render target
+ /// Stencil value to clear to
+ ////////////////////////////////////////////////////////////
+ public void Clear(Color color, StencilValue stencilValue) => sfRenderWindow_clearColorAndStencil(CPointer, color, stencilValue);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Clear the stencil buffer to a specific value
+ ///
+ /// The specified value is truncated to the bit width of
+ /// the current stencil buffer.
+ ///
+ /// Stencil value to clear to
+ ////////////////////////////////////////////////////////////
+ public void ClearStencil(StencilValue stencilValue) => sfRenderWindow_clearStencil(CPointer, stencilValue);
+
+
////////////////////////////////////////////////////////////
///
/// Change the current active view
@@ -353,6 +378,20 @@ public override void SetIcon(uint width, uint height, byte[] pixels)
////////////////////////////////////////////////////////////
public IntRect GetViewport(View view) => sfRenderWindow_getViewport(CPointer, view.CPointer);
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Get the scissor rectangle of a view, applied to this render target
+ ///
+ /// The scissor rectangle is defined in the view as a ratio. This
+ /// function simply applies this ratio to the current dimensions
+ /// of the render target to calculate the pixels rectangle
+ /// that the scissor rectangle actually covers in the target.
+ ///
+ /// The view for which we want to compute the scissor rectangle
+ /// Scissor rectangle, expressed in pixels
+ ////////////////////////////////////////////////////////////
+ public IntRect GetScissor(View view) => sfRenderWindow_getScissor(CPointer, view.CPointer);
+
////////////////////////////////////////////////////////////
///
/// Convert a point from target coordinates to world
@@ -576,24 +615,6 @@ public void Draw(Vertex[] vertices, uint start, uint count, PrimitiveType type,
////////////////////////////////////////////////////////////
public void ResetGLStates() => sfRenderWindow_resetGLStates(CPointer);
- ////////////////////////////////////////////////////////////
- ///
- /// Capture the current contents of the window into an image.
- ///
- ///
- ///
- /// Deprecated. Use and
- /// instead:
- ///
- /// Texture texture = new Texture(window.Size);
- /// texture.update(window);
- /// Image img = texture.CopyToImage();
- ///
- ///
- ////////////////////////////////////////////////////////////
- [Obsolete("Use Texture and Texture.Update(RenderWindow)")]
- public Image Capture() => new Image(sfRenderWindow_capture(CPointer));
-
////////////////////////////////////////////////////////////
///
/// Provide a string describing the object
@@ -628,10 +649,11 @@ public override string ToString()
///
/// Internal function to get the next event (blocking)
///
+ /// Maximum time to wait ( for infinite)
/// Variable to fill with the raw pointer to the event structure
/// False if any error occurred
////////////////////////////////////////////////////////////
- protected override bool WaitEvent(out Event eventToFill) => sfRenderWindow_waitEvent(CPointer, out eventToFill);
+ protected override bool WaitEvent(Time timeout, out Event eventToFill) => sfRenderWindow_waitEvent(CPointer, timeout, out eventToFill);
////////////////////////////////////////////////////////////
///
@@ -697,7 +719,7 @@ private void Initialize()
#region Imports
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfRenderWindow_createUnicode(VideoMode mode, IntPtr title, Styles style, ref ContextSettings settings);
+ private static extern IntPtr sfRenderWindow_createUnicode(VideoMode mode, IntPtr title, Styles style, State state, ref ContextSettings settings);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern IntPtr sfRenderWindow_createFromHandle(IntPtr handle, ref ContextSettings settings);
@@ -718,7 +740,7 @@ private void Initialize()
private static extern bool sfRenderWindow_pollEvent(IntPtr cPointer, out Event evt);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern bool sfRenderWindow_waitEvent(IntPtr cPointer, out Event evt);
+ private static extern bool sfRenderWindow_waitEvent(IntPtr cPointer, Time timeout, out Event evt);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern Vector2i sfRenderWindow_getPosition(IntPtr cPointer);
@@ -739,7 +761,7 @@ private void Initialize()
private static extern void sfRenderWindow_setUnicodeTitle(IntPtr cPointer, IntPtr title);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern unsafe void sfRenderWindow_setIcon(IntPtr cPointer, uint width, uint height, byte* pixels);
+ private static extern unsafe void sfRenderWindow_setIcon(IntPtr cPointer, Vector2u size, byte* pixels);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfRenderWindow_setVisible(IntPtr cPointer, bool visible);
@@ -778,11 +800,17 @@ private void Initialize()
private static extern void sfRenderWindow_display(IntPtr cPointer);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfRenderWindow_getSystemHandle(IntPtr cPointer);
+ private static extern IntPtr sfRenderWindow_getNativeHandle(IntPtr cPointer);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfRenderWindow_clear(IntPtr cPointer, Color clearColor);
+ [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+ private static extern void sfRenderWindow_clearStencil(IntPtr cPointer, StencilValue stencilValue);
+
+ [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+ private static extern void sfRenderWindow_clearColorAndStencil(IntPtr cPointer, Color clearColor, StencilValue stencilValue);
+
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfRenderWindow_setView(IntPtr cPointer, IntPtr view);
@@ -795,6 +823,9 @@ private void Initialize()
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern IntRect sfRenderWindow_getViewport(IntPtr cPointer, IntPtr targetView);
+ [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+ private static extern IntRect sfRenderWindow_getScissor(IntPtr cPointer, IntPtr targetView);
+
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern Vector2f sfRenderWindow_mapPixelToCoords(IntPtr cPointer, Vector2i point, IntPtr view);
@@ -813,9 +844,6 @@ private void Initialize()
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfRenderWindow_resetGLStates(IntPtr cPointer);
- [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfRenderWindow_capture(IntPtr cPointer);
-
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern Vector2i sfMouse_getPositionRenderWindow(IntPtr cPointer);
diff --git a/src/SFML.Graphics/Shader.cs b/src/SFML.Graphics/Shader.cs
index 08d83032..5a34bfb5 100644
--- a/src/SFML.Graphics/Shader.cs
+++ b/src/SFML.Graphics/Shader.cs
@@ -434,155 +434,6 @@ public unsafe void SetUniformArray(string name, Glsl.Mat4[] array)
}
}
- ////////////////////////////////////////////////////////////
- ///
- /// Change a float parameter of the shader
- ///
- /// "name" is the name of the variable to change in the shader.
- /// The corresponding parameter in the shader must be a float
- /// (float GLSL type).
- ///
- ///
- /// Name of the parameter in the shader
- /// Value to assign
- ///
- ////////////////////////////////////////////////////////////
- [Obsolete("Use SetUniform()")]
- public void SetParameter(string name, float x) => sfShader_setFloatParameter(CPointer, name, x);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Change a 2-components vector parameter of the shader
- ///
- /// "name" is the name of the variable to change in the shader.
- /// The corresponding parameter in the shader must be a 2x1 vector
- /// (vec2 GLSL type).
- ///
- /// Name of the parameter in the shader
- /// First component of the value to assign
- /// Second component of the value to assign
- ////////////////////////////////////////////////////////////
- [Obsolete("Use SetUniform()")]
- public void SetParameter(string name, float x, float y) => sfShader_setFloat2Parameter(CPointer, name, x, y);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Change a 3-components vector parameter of the shader
- ///
- /// "name" is the name of the variable to change in the shader.
- /// The corresponding parameter in the shader must be a 3x1 vector
- /// (vec3 GLSL type).
- ///
- /// Name of the parameter in the shader
- /// First component of the value to assign
- /// Second component of the value to assign
- /// Third component of the value to assign
- ////////////////////////////////////////////////////////////
- [Obsolete("Use SetUniform()")]
- public void SetParameter(string name, float x, float y, float z) => sfShader_setFloat3Parameter(CPointer, name, x, y, z);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Change a 4-components vector parameter of the shader
- ///
- /// "name" is the name of the variable to change in the shader.
- /// The corresponding parameter in the shader must be a 4x1 vector
- /// (vec4 GLSL type).
- ///
- /// Name of the parameter in the shader
- /// First component of the value to assign
- /// Second component of the value to assign
- /// Third component of the value to assign
- /// Fourth component of the value to assign
- ////////////////////////////////////////////////////////////
- [Obsolete("Use SetUniform()")]
- public void SetParameter(string name, float x, float y, float z, float w) => sfShader_setFloat4Parameter(CPointer, name, x, y, z, w);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Change a 2-components vector parameter of the shader
- ///
- /// "name" is the name of the variable to change in the shader.
- /// The corresponding parameter in the shader must be a 2x1 vector
- /// (vec2 GLSL type).
- ///
- /// Name of the parameter in the shader
- /// Vector to assign
- ////////////////////////////////////////////////////////////
- [Obsolete("Use SetUniform()")]
- public void SetParameter(string name, Vector2f vector) => SetParameter(name, vector.X, vector.Y);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Change a color parameter of the shader
- ///
- /// "name" is the name of the variable to change in the shader.
- /// The corresponding parameter in the shader must be a 4x1 vector
- /// (vec4 GLSL type).
- ///
- /// Name of the parameter in the shader
- /// Color to assign
- ////////////////////////////////////////////////////////////
- [Obsolete("Use SetUniform()")]
- public void SetParameter(string name, Color color) => sfShader_setColorParameter(CPointer, name, color);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Change a matrix parameter of the shader
- ///
- /// "name" is the name of the variable to change in the shader.
- /// The corresponding parameter in the shader must be a 4x4 matrix
- /// (mat4 GLSL type).
- ///
- /// Name of the parameter in the shader
- /// Transform to assign
- ////////////////////////////////////////////////////////////
- [Obsolete("Use SetUniform()")]
- public void SetParameter(string name, Transform transform) => sfShader_setTransformParameter(CPointer, name, transform);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Change a texture parameter of the shader
- ///
- /// "name" is the name of the variable to change in the shader.
- /// The corresponding parameter in the shader must be a 2D texture
- /// (sampler2D GLSL type).
- ///
- /// It is important to note that \a texture must remain alive as long
- /// as the shader uses it, no copy is made internally.
- ///
- /// To use the texture of the object being draw, which cannot be
- /// known in advance, you can pass the special value
- /// Shader.CurrentTexture.
- ///
- /// Name of the texture in the shader
- /// Texture to assign
- ////////////////////////////////////////////////////////////
- [Obsolete("Use SetUniform()")]
- public void SetParameter(string name, Texture texture)
- {
- // Keep a reference to the Texture so it doesn't get GC'd
- _textures[name] = texture;
- sfShader_setTextureParameter(CPointer, name, texture.CPointer);
- }
-
- ////////////////////////////////////////////////////////////
- ///
- /// Change a texture parameter of the shader
- ///
- /// This overload maps a shader texture variable to the
- /// texture of the object being drawn, which cannot be
- /// known in advance. The second argument must be
- /// sf::Shader::CurrentTexture.
- /// The corresponding parameter in the shader must be a 2D texture
- /// (sampler2D GLSL type).
- ///
- /// Name of the texture in the shader
- /// Always pass the special value Shader.CurrentTexture
- ////////////////////////////////////////////////////////////
- [Obsolete("Use SetUniform()")]
- public void SetParameter(string name, CurrentTextureType current) => sfShader_setCurrentTextureParameter(CPointer, name);
-
////////////////////////////////////////////////////////////
///
/// Bind a shader for rendering
@@ -754,30 +605,6 @@ public Shader(IntPtr ptr) :
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern unsafe void sfShader_setMat4UniformArray(IntPtr shader, string name, Glsl.Mat4* data, UIntPtr length);
- [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity, Obsolete]
- private static extern void sfShader_setFloatParameter(IntPtr shader, string name, float x);
-
- [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity, Obsolete]
- private static extern void sfShader_setFloat2Parameter(IntPtr shader, string name, float x, float y);
-
- [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity, Obsolete]
- private static extern void sfShader_setFloat3Parameter(IntPtr shader, string name, float x, float y, float z);
-
- [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity, Obsolete]
- private static extern void sfShader_setFloat4Parameter(IntPtr shader, string name, float x, float y, float z, float w);
-
- [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity, Obsolete]
- private static extern void sfShader_setColorParameter(IntPtr shader, string name, Color color);
-
- [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity, Obsolete]
- private static extern void sfShader_setTransformParameter(IntPtr shader, string name, Transform transform);
-
- [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity, Obsolete]
- private static extern void sfShader_setTextureParameter(IntPtr shader, string name, IntPtr texture);
-
- [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity, Obsolete]
- private static extern void sfShader_setCurrentTextureParameter(IntPtr shader, string name);
-
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern uint sfShader_getNativeHandle(IntPtr shader);
diff --git a/src/SFML.Graphics/Shape.cs b/src/SFML.Graphics/Shape.cs
index a0429839..5558aba6 100644
--- a/src/SFML.Graphics/Shape.cs
+++ b/src/SFML.Graphics/Shape.cs
@@ -89,6 +89,19 @@ public float OutlineThickness
////////////////////////////////////////////////////////////
public abstract Vector2f GetPoint(uint index);
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Get the geometric center of the shape
+ ///
+ /// The returned point is in local coordinates, that is,
+ /// the shape's transforms (position, rotation, scale) are
+ /// not taken into account.
+ ///
+ ///
+ /// The geometric center of the shape
+ ////////////////////////////////////////////////////////////
+ public virtual Vector2f GetGeometricCenter() => sfShape_getGeometricCenter(CPointer);
+
////////////////////////////////////////////////////////////
///
/// Get the local bounding rectangle of the entity.
@@ -258,6 +271,9 @@ public Shape(Shape copy) :
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern float sfShape_getOutlineThickness(IntPtr cPointer);
+ [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+ private static extern Vector2f sfShape_getGeometricCenter(IntPtr cPointer);
+
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern FloatRect sfShape_getLocalBounds(IntPtr cPointer);
diff --git a/src/SFML.Graphics/Sprite.cs b/src/SFML.Graphics/Sprite.cs
index c74cf4a0..a64c4383 100644
--- a/src/SFML.Graphics/Sprite.cs
+++ b/src/SFML.Graphics/Sprite.cs
@@ -16,16 +16,6 @@ namespace SFML.Graphics
////////////////////////////////////////////////////////////
public class Sprite : Transformable, IDrawable
{
- ////////////////////////////////////////////////////////////
- ///
- /// Default constructor
- ///
- ////////////////////////////////////////////////////////////
- public Sprite() :
- base(sfSprite_create())
- {
- }
-
////////////////////////////////////////////////////////////
///
/// Construct the sprite from a source texture
@@ -33,7 +23,7 @@ public Sprite() :
/// Source texture to assign to the sprite
////////////////////////////////////////////////////////////
public Sprite(Texture texture) :
- base(sfSprite_create()) => Texture = texture;
+ base(sfSprite_create(texture.CPointer)) => Texture = texture;
////////////////////////////////////////////////////////////
///
@@ -43,7 +33,7 @@ public Sprite(Texture texture) :
/// Sub-rectangle of the texture to assign to the sprite
////////////////////////////////////////////////////////////
public Sprite(Texture texture, IntRect rectangle) :
- base(sfSprite_create())
+ base(sfSprite_create(texture.CPointer))
{
Texture = texture;
TextureRect = rectangle;
@@ -180,7 +170,7 @@ public void Draw(IRenderTarget target, RenderStates states)
#region Imports
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfSprite_create();
+ private static extern IntPtr sfSprite_create(IntPtr texture);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern IntPtr sfSprite_copy(IntPtr sprite);
diff --git a/src/SFML.Graphics/StencilMode.cs b/src/SFML.Graphics/StencilMode.cs
new file mode 100644
index 00000000..d5020da2
--- /dev/null
+++ b/src/SFML.Graphics/StencilMode.cs
@@ -0,0 +1,196 @@
+using System.Runtime.InteropServices;
+
+namespace SFML.Graphics
+{
+ ////////////////////////////////////////////////////////
+ ///
+ /// Enumeration of the stencil test comparisons that can be performed
+ ///
+ /// The comparisons are mapped directly to their OpenGL equivalents,
+ /// specified by glStencilFunc().
+ ///
+ ////////////////////////////////////////////////////////
+ public enum StencilComparison
+ {
+ /// The stencil test never passes
+ Never,
+
+ /// The stencil test passes if the new value is less than the value in the stencil buffer
+ Less,
+
+ /// The stencil test passes if the new value is less than or equal to the value in the stencil buffer
+ LessEqual,
+
+ /// The stencil test passes if the new value is greater than the value in the stencil buffer
+ Greater,
+
+ /// The stencil test passes if the new value is greater than or equal to the value in the stencil buffer
+ GreaterEqual,
+
+ /// The stencil test passes if the new value is strictly equal to the value in the stencil buffer
+ Equal,
+
+ /// The stencil test passes if the new value is strictly inequal to the value in the stencil buffer
+ NotEqual,
+
+ /// The stencil test always passes
+ Always
+ }
+
+ ////////////////////////////////////////////////////////
+ ///
+ /// Enumeration of the stencil buffer update operations
+ ///
+ /// The update operations are mapped directly to their OpenGL equivalents,
+ /// specified by glStencilOp().
+ ///
+ ////////////////////////////////////////////////////////
+ public enum StencilUpdateOperation
+ {
+ /// If the stencil test passes, the value in the stencil buffer is not modified
+ Keep,
+
+ /// If the stencil test passes, the value in the stencil buffer is set to zero
+ Zero,
+
+ /// If the stencil test passes, the value in the stencil buffer is set to the new value
+ Replace,
+
+ /// If the stencil test passes, the value in the stencil buffer is incremented and if required clamped
+ Increment,
+
+ /// If the stencil test passes, the value in the stencil buffer is decremented and if required clamped
+ Decrement,
+
+ /// If the stencil test passes, the value in the stencil buffer is bitwise inverted
+ Invert
+ }
+
+ ////////////////////////////////////////////////////////
+ ///
+ /// Stencil value type (also used as a mask)
+ ///
+ ////////////////////////////////////////////////////////
+ [StructLayout(LayoutKind.Sequential)]
+ public struct StencilValue
+ {
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The stored stencil value
+ ///
+ ////////////////////////////////////////////////////////////
+ public uint Value;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Convert a signed integer to a stencil value
+ ///
+ ////////////////////////////////////////////////////////////
+ public static explicit operator StencilValue(int value) => new StencilValue() { Value = (uint)value };
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Convert an unsigned integer to a stencil value
+ ///
+ ////////////////////////////////////////////////////////////
+ public static explicit operator StencilValue(uint value) => new StencilValue() { Value = value };
+ }
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Stencil modes for drawing
+ ///
+ ////////////////////////////////////////////////////////////
+ [StructLayout(LayoutKind.Sequential)]
+ public struct StencilMode
+ {
+ ///
+ /// The comparison we're performing the stencil test with
+ ///
+ public StencilComparison StencilComparison;
+
+ ///
+ /// The update operation to perform if the stencil test passes
+ ///
+ public StencilUpdateOperation StencilUpdateOperation;
+
+ ///
+ /// The reference value we're performing the stencil test with
+ ///
+ public uint StencilReference;
+
+ ///
+ /// The mask to apply to both the reference value and the value in the stencil buffer
+ ///
+ public uint StencilMask;
+
+ ///
+ /// Whether we should update the color buffer in addition to the stencil buffer
+ ///
+ public bool StencilOnly;
+
+ ///
+ /// Default values for stencil mode
+ ///
+ public static readonly StencilMode Default = new StencilMode()
+ {
+ StencilComparison = StencilComparison.Always,
+ StencilUpdateOperation = StencilUpdateOperation.Keep,
+ StencilReference = 0,
+ StencilMask = ~0u,
+ StencilOnly = false
+ };
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Compare two stencil modes and checks if they are equal
+ ///
+ /// Stencil Modes are equal
+ ////////////////////////////////////////////////////////////
+ public static bool operator ==(StencilMode left, StencilMode right) => left.Equals(right);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Compare two stencil modes and checks if they are not equal
+ ///
+ /// Stencil Modes are not equal
+ ////////////////////////////////////////////////////////////
+ public static bool operator !=(StencilMode left, StencilMode right) => !left.Equals(right);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Compare stencil mode and object and checks if they are equal
+ ///
+ /// Object to check
+ /// Object and stencil mode are equal
+ ////////////////////////////////////////////////////////////
+ public override bool Equals(object obj) => obj is StencilMode mode && Equals(mode);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Provide a integer describing the object
+ ///
+ /// Integer description of the object
+ ////////////////////////////////////////////////////////////
+ public override int GetHashCode() =>
+ StencilComparison.GetHashCode() ^
+ StencilUpdateOperation.GetHashCode() ^
+ StencilReference.GetHashCode() ^
+ StencilMask.GetHashCode() ^
+ StencilOnly.GetHashCode();
+
+ ///////////////////////////////////////////////////////////
+ ///
+ /// Compare two stencil modes and checks if they are equal
+ ///
+ /// Stencil mode to check
+ /// Stencil modes are equal
+ ////////////////////////////////////////////////////////////
+ public bool Equals(StencilMode other) =>
+ StencilComparison == other.StencilComparison &&
+ StencilUpdateOperation == other.StencilUpdateOperation &&
+ StencilReference == other.StencilReference &&
+ StencilMask == other.StencilMask &&
+ StencilOnly == other.StencilOnly;
+ }
+}
diff --git a/src/SFML.Graphics/Text.cs b/src/SFML.Graphics/Text.cs
index b6e2f612..9bec3a89 100644
--- a/src/SFML.Graphics/Text.cs
+++ b/src/SFML.Graphics/Text.cs
@@ -42,11 +42,12 @@ public enum Styles
////////////////////////////////////////////////////////////
///
- /// Default constructor
+ /// Construct the text from a
///
+ /// Font to use
////////////////////////////////////////////////////////////
- public Text() :
- this("", null)
+ public Text(Font font) :
+ this(font, "", 30)
{
}
@@ -54,11 +55,11 @@ public Text() :
///
/// Construct the text from a string and a
///
- /// String to display
/// Font to use
+ /// String to display
////////////////////////////////////////////////////////////
- public Text(string str, Font font) :
- this(str, font, 30)
+ public Text(Font font, string str) :
+ this(font, str, 30)
{
}
@@ -66,11 +67,11 @@ public Text(string str, Font font) :
///
/// Construct the text from a string, and size
///
- /// String to display
/// Font to use
+ /// String to display
/// Font size
////////////////////////////////////////////////////////////
- public Text(string str, Font font, uint characterSize) :
+ public Text(Font font, string str, uint characterSize) :
base(sfText_create())
{
DisplayedString = str;
@@ -95,28 +96,6 @@ public Text(Text copy) :
Font = copy.Font;
}
- ////////////////////////////////////////////////////////////
- ///
- /// DEPRECATED Fill of the
- ///
- ///
- ///
- /// Use instead.
- ///
- /// By default, the text's fill is opaque White.
- ///
- /// Setting the fill color to a transparent with an outline
- /// will cause the outline to be displayed in the fill area of the text.
- ///
- ///
- ////////////////////////////////////////////////////////////
- [Obsolete("Use FillColor and OutlineColor")]
- public Color Color
- {
- get => sfText_getFillColor(CPointer);
- set => sfText_setFillColor(CPointer, value);
- }
-
////////////////////////////////////////////////////////////
///
/// Fill of the
diff --git a/src/SFML.Graphics/Texture.cs b/src/SFML.Graphics/Texture.cs
index ce9f2e7f..68e06203 100644
--- a/src/SFML.Graphics/Texture.cs
+++ b/src/SFML.Graphics/Texture.cs
@@ -26,17 +26,6 @@ namespace SFML.Graphics
////////////////////////////////////////////////////////////
public class Texture : ObjectBase
{
- ///
- /// Types of texture coordinates that can be used for rendering.
- ///
- public enum TextureCoordinateType
- {
- /// Texture coordinates in range [0 .. 1].
- Normalized,
- /// Texture coordinates in range [0 .. size].
- Pixels
- }
-
////////////////////////////////////////////////////////////
///
/// Construct the texture
@@ -44,12 +33,11 @@ public enum TextureCoordinateType
///
/// Textures created this way are uninitialized and have indeterminate contents.
///
- /// Texture width
- /// Texture height
+ /// Width and height of the texture
///
////////////////////////////////////////////////////////////
- public Texture(uint width, uint height) :
- base(sfTexture_create(width, height))
+ public Texture(Vector2u size) : // TODO Vector2u + srgb
+ base(sfTexture_create(size))
{
if (IsInvalid)
{
@@ -66,7 +54,7 @@ public Texture(uint width, uint height) :
///
////////////////////////////////////////////////////////////
public Texture(string filename, bool srgb = false) :
- this(filename, new IntRect(0, 0, 0, 0), srgb)
+ this(filename, new IntRect((0, 0), (0, 0)), srgb)
{
}
@@ -106,7 +94,7 @@ public Texture(string filename, IntRect area, bool srgb = false) :
///
////////////////////////////////////////////////////////////
public Texture(Stream stream, bool srgb = false) :
- this(stream, new IntRect(0, 0, 0, 0), srgb)
+ this(stream, new IntRect((0, 0), (0, 0)), srgb)
{
}
@@ -149,7 +137,7 @@ public Texture(Stream stream, IntRect area, bool srgb = false) :
///
////////////////////////////////////////////////////////////
public Texture(Image image, bool srgb = false) :
- this(image, new IntRect(0, 0, 0, 0), srgb)
+ this(image, new IntRect((0, 0), (0, 0)), srgb)
{
}
@@ -189,7 +177,7 @@ public Texture(Image image, IntRect area, bool srgb = false) :
///
////////////////////////////////////////////////////////////
public Texture(byte[] bytes, bool srgb = false) :
- this(bytes, new IntRect(0, 0, 0, 0), srgb)
+ this(bytes, new IntRect((0, 0), (0, 0)), srgb)
{
}
@@ -263,29 +251,23 @@ public Texture(Texture copy) :
///
/// Array of pixels to copy to the texture
////////////////////////////////////////////////////////////
- public void Update(byte[] pixels)
- {
- var size = Size;
- Update(pixels, size.X, size.Y, 0, 0);
- }
+ public void Update(byte[] pixels) => Update(pixels, Size, new Vector2u());
////////////////////////////////////////////////////////////
///
/// Update a texture from an array of pixels
///
/// Array of pixels to copy to the texture
- /// Width of the pixel region contained in pixels
- /// Height of the pixel region contained in pixels
- /// X offset in the texture where to copy the source pixels
- /// Y offset in the texture where to copy the source pixels
+ /// Width and height of the pixel region contained in pixels
+ /// Coordinates of the destination position
////////////////////////////////////////////////////////////
- public void Update(byte[] pixels, uint width, uint height, uint x, uint y)
+ public void Update(byte[] pixels, Vector2u size, Vector2u dest)
{
unsafe
{
fixed (byte* ptr = pixels)
{
- sfTexture_updateFromPixels(CPointer, ptr, width, height, x, y);
+ sfTexture_updateFromPixels(CPointer, ptr, size, dest);
}
}
}
@@ -295,10 +277,9 @@ public void Update(byte[] pixels, uint width, uint height, uint x, uint y)
/// Update a part of this texture from another texture
///
/// Source texture to copy to destination texture
- /// X offset in this texture where to copy the source texture
- /// Y offset in this texture where to copy the source texture
+ /// Coordinates of the destination position
////////////////////////////////////////////////////////////
- public void Update(Texture texture, uint x, uint y) => sfTexture_updateFromTexture(CPointer, texture.CPointer, x, y);
+ public void Update(Texture texture, Vector2u dest) => sfTexture_updateFromTexture(CPointer, texture.CPointer, dest);
////////////////////////////////////////////////////////////
///
@@ -306,17 +287,16 @@ public void Update(byte[] pixels, uint width, uint height, uint x, uint y)
///
/// Image to copy to the texture
////////////////////////////////////////////////////////////
- public void Update(Image image) => Update(image, 0, 0);
+ public void Update(Image image) => Update(image, new Vector2u());
////////////////////////////////////////////////////////////
///
/// Update a texture from an image
///
/// Image to copy to the texture
- /// X offset in the texture where to copy the source pixels
- /// Y offset in the texture where to copy the source pixels
+ /// Coordinates of the destination position
////////////////////////////////////////////////////////////
- public void Update(Image image, uint x, uint y) => sfTexture_updateFromImage(CPointer, image.CPointer, x, y);
+ public void Update(Image image, Vector2u dest) => sfTexture_updateFromImage(CPointer, image.CPointer, dest); // TODO API
////////////////////////////////////////////////////////////
///
@@ -324,17 +304,16 @@ public void Update(byte[] pixels, uint width, uint height, uint x, uint y)
///
/// Window to copy to the texture
////////////////////////////////////////////////////////////
- public void Update(SFML.Window.Window window) => Update(window, 0, 0);
+ public void Update(SFML.Window.Window window) => Update(window, new Vector2u());
////////////////////////////////////////////////////////////
///
/// Update a texture from the contents of a window
///
/// Window to copy to the texture
- /// X offset in the texture where to copy the source pixels
- /// Y offset in the texture where to copy the source pixels
+ /// Coordinates of the destination position
////////////////////////////////////////////////////////////
- public void Update(SFML.Window.Window window, uint x, uint y) => sfTexture_updateFromWindow(CPointer, window.CPointer, x, y);
+ public void Update(SFML.Window.Window window, Vector2u dest) => sfTexture_updateFromWindow(CPointer, window.CPointer, dest);
////////////////////////////////////////////////////////////
///
@@ -342,17 +321,16 @@ public void Update(byte[] pixels, uint width, uint height, uint x, uint y)
///
/// Render-window to copy to the texture
////////////////////////////////////////////////////////////
- public void Update(RenderWindow window) => Update(window, 0, 0);
+ public void Update(RenderWindow window) => Update(window, new Vector2u());
////////////////////////////////////////////////////////////
///
/// Update a texture from the contents of a render-window
///
/// Render-window to copy to the texture
- /// X offset in the texture where to copy the source pixels
- /// Y offset in the texture where to copy the source pixels
+ /// Coordinates of the destination position
////////////////////////////////////////////////////////////
- public void Update(RenderWindow window, uint x, uint y) => sfTexture_updateFromRenderWindow(CPointer, window.CPointer, x, y);
+ public void Update(RenderWindow window, Vector2u dest) => sfTexture_updateFromRenderWindow(CPointer, window.CPointer, dest);
////////////////////////////////////////////////////////////
///
@@ -423,7 +401,7 @@ public bool Smooth
/// framebuffer. This can be requested during window creation.
///
////////////////////////////////////////////////////////////
- public bool Srgb => sfTexture_isSrgb(CPointer);
+ public bool IsSrgb => sfTexture_isSrgb(CPointer);
////////////////////////////////////////////////////////////
///
@@ -450,7 +428,7 @@ public bool Repeated
/// Shader to bind (can be null to use no texture)
/// Type of texture coordinates to use
////////////////////////////////////////////////////////////
- public static void Bind(Texture texture, TextureCoordinateType type) => sfTexture_bind(texture != null ? texture.CPointer : IntPtr.Zero, type);
+ public static void Bind(Texture texture, CoordinateType type) => sfTexture_bind(texture != null ? texture.CPointer : IntPtr.Zero, type);
////////////////////////////////////////////////////////////
///
@@ -515,7 +493,7 @@ protected override void Destroy(bool disposing)
#region Imports
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfTexture_create(uint width, uint height);
+ private static extern IntPtr sfTexture_create(Vector2u size);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern IntPtr sfTexture_createFromFile(string filename, ref IntRect area);
@@ -554,22 +532,22 @@ protected override void Destroy(bool disposing)
private static extern IntPtr sfTexture_copyToImage(IntPtr texture);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern unsafe void sfTexture_updateFromPixels(IntPtr texture, byte* pixels, uint width, uint height, uint x, uint y);
+ private static extern unsafe void sfTexture_updateFromPixels(IntPtr texture, byte* pixels, Vector2u size, Vector2u offset);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfTexture_updateFromTexture(IntPtr cPointer, IntPtr texture, uint x, uint y);
+ private static extern void sfTexture_updateFromTexture(IntPtr cPointer, IntPtr texture, Vector2u offset);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfTexture_updateFromImage(IntPtr texture, IntPtr image, uint x, uint y);
+ private static extern void sfTexture_updateFromImage(IntPtr texture, IntPtr image, Vector2u offset);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfTexture_updateFromWindow(IntPtr texture, IntPtr window, uint x, uint y);
+ private static extern void sfTexture_updateFromWindow(IntPtr texture, IntPtr window, Vector2u offset);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfTexture_updateFromRenderWindow(IntPtr texture, IntPtr renderWindow, uint x, uint y);
+ private static extern void sfTexture_updateFromRenderWindow(IntPtr texture, IntPtr renderWindow, Vector2u offset);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfTexture_bind(IntPtr texture, TextureCoordinateType type);
+ private static extern void sfTexture_bind(IntPtr texture, CoordinateType type);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfTexture_setSmooth(IntPtr texture, bool smooth);
diff --git a/src/SFML.Graphics/Transform.cs b/src/SFML.Graphics/Transform.cs
index b54a68b5..b23fcf99 100644
--- a/src/SFML.Graphics/Transform.cs
+++ b/src/SFML.Graphics/Transform.cs
@@ -2,6 +2,8 @@
using System.Security;
using SFML.System;
+// TODO REIMPLEMENT WITH 4x4 MATRIX
+
namespace SFML.Graphics
{
////////////////////////////////////////////////////////////
@@ -52,16 +54,6 @@ public Transform(float a00, float a01, float a02,
////////////////////////////////////////////////////////////
public Transform GetInverse() => sfTransform_getInverse(ref this);
- ////////////////////////////////////////////////////////////
- ///
- /// Transform a 2D point.
- ///
- /// X coordinate of the point to transform
- /// Y coordinate of the point to transform
- /// Transformed point
- ////////////////////////////////////////////////////////////
- public Vector2f TransformPoint(float x, float y) => TransformPoint(new Vector2f(x, y));
-
////////////////////////////////////////////////////////////
///
/// Transform a 2D point.
@@ -98,45 +90,21 @@ public Transform(float a00, float a01, float a02,
////////////////////////////////////////////////////////////
public void Combine(Transform transform) => sfTransform_combine(ref this, ref transform);
- ////////////////////////////////////////////////////////////
- ///
- /// Combine the current transform with a translation.
- ///
- /// Offset to apply on X axis
- /// Offset to apply on Y axis
- ////////////////////////////////////////////////////////////
- public void Translate(float x, float y) => sfTransform_translate(ref this, x, y);
-
////////////////////////////////////////////////////////////
///
/// Combine the current transform with a translation.
///
/// Translation offset to apply
////////////////////////////////////////////////////////////
- public void Translate(Vector2f offset) => Translate(offset.X, offset.Y);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Combine the current transform with a rotation.
- ///
- /// Rotation angle, in degrees
- ////////////////////////////////////////////////////////////
- public void Rotate(float angle) => sfTransform_rotate(ref this, angle);
+ public void Translate(Vector2f offset) => sfTransform_translate(ref this, offset);
////////////////////////////////////////////////////////////
///
/// Combine the current transform with a rotation.
- ///
- /// The center of rotation is provided for convenience as a second
- /// argument, so that you can build rotations around arbitrary points
- /// more easily (and efficiently) than the usual
- /// Translate(-center); Rotate(angle); Translate(center).
///
- /// Rotation angle, in degrees
- /// X coordinate of the center of rotation
- /// Y coordinate of the center of rotation
+ /// Rotation angle
////////////////////////////////////////////////////////////
- public void Rotate(float angle, float centerX, float centerY) => sfTransform_rotateWithCenter(ref this, angle, centerX, centerY);
+ public void Rotate(Angle angle) => sfTransform_rotate(ref this, angle.Degrees);
////////////////////////////////////////////////////////////
///
@@ -147,35 +115,10 @@ public Transform(float a00, float a01, float a02,
/// more easily (and efficiently) than the usual
/// Translate(-center); Rotate(angle); Translate(center).
///
- /// Rotation angle, in degrees
+ /// Rotation angle
/// Center of rotation
////////////////////////////////////////////////////////////
- public void Rotate(float angle, Vector2f center) => Rotate(angle, center.X, center.Y);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Combine the current transform with a scaling.
- ///
- /// Scaling factor on the X axis
- /// Scaling factor on the Y axis
- ////////////////////////////////////////////////////////////
- public void Scale(float scaleX, float scaleY) => sfTransform_scale(ref this, scaleX, scaleY);
-
- ////////////////////////////////////////////////////////////
- ///
- /// Combine the current transform with a scaling.
- ///
- /// The center of scaling is provided for convenience as a second
- /// argument, so that you can build scaling around arbitrary points
- /// more easily (and efficiently) than the usual
- /// Translate(-center); Scale(factors); Translate(center).
- ///
- /// Scaling factor on X axis
- /// Scaling factor on Y axis
- /// X coordinate of the center of scaling
- /// Y coordinate of the center of scaling
- ////////////////////////////////////////////////////////////
- public void Scale(float scaleX, float scaleY, float centerX, float centerY) => sfTransform_scaleWithCenter(ref this, scaleX, scaleY, centerX, centerY);
+ public void Rotate(Angle angle, Vector2f center) => sfTransform_rotateWithCenter(ref this, angle.Degrees, center);
////////////////////////////////////////////////////////////
///
@@ -183,7 +126,7 @@ public Transform(float a00, float a01, float a02,
///
/// Scaling factors
////////////////////////////////////////////////////////////
- public void Scale(Vector2f factors) => Scale(factors.X, factors.Y);
+ public void Scale(Vector2f factors) => sfTransform_scale(ref this, factors);
////////////////////////////////////////////////////////////
///
@@ -197,7 +140,7 @@ public Transform(float a00, float a01, float a02,
/// Scaling factors
/// Center of scaling
////////////////////////////////////////////////////////////
- public void Scale(Vector2f factors, Vector2f center) => Scale(factors.X, factors.Y, center.X, center.Y);
+ public void Scale(Vector2f factors, Vector2f center) => sfTransform_scaleWithCenter(ref this, factors, center);
////////////////////////////////////////////////////////////
///
@@ -206,7 +149,7 @@ public Transform(float a00, float a01, float a02,
/// Object to check
/// Object and transform are equal
////////////////////////////////////////////////////////////
- public override bool Equals(object obj) => (obj is Transform) && Equals((Transform)obj);
+ public override bool Equals(object obj) => (obj is Transform transform) && Equals(transform);
////////////////////////////////////////////////////////////
///
@@ -300,19 +243,19 @@ public override string ToString() => string.Format("[Transform]" +
private static extern void sfTransform_combine(ref Transform transform, ref Transform other);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfTransform_translate(ref Transform transform, float x, float y);
+ private static extern void sfTransform_translate(ref Transform transform, Vector2f offset);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfTransform_rotate(ref Transform transform, float angle);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfTransform_rotateWithCenter(ref Transform transform, float angle, float centerX, float centerY);
+ private static extern void sfTransform_rotateWithCenter(ref Transform transform, float angle, Vector2f center);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfTransform_scale(ref Transform transform, float scaleX, float scaleY);
+ private static extern void sfTransform_scale(ref Transform transform, Vector2f scale);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfTransform_scaleWithCenter(ref Transform transform, float scaleX, float scaleY, float centerX, float centerY);
+ private static extern void sfTransform_scaleWithCenter(ref Transform transform, Vector2f scale, Vector2f center);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern bool sfTransform_equal(ref Transform left, ref Transform right);
diff --git a/src/SFML.Graphics/Transformable.cs b/src/SFML.Graphics/Transformable.cs
index 52510a3a..d89f37af 100644
--- a/src/SFML.Graphics/Transformable.cs
+++ b/src/SFML.Graphics/Transformable.cs
@@ -69,7 +69,7 @@ public Vector2f Position
/// Rotation of the object
///
////////////////////////////////////////////////////////////
- public float Rotation
+ public Angle Rotation
{
get => _rotation;
set
@@ -130,8 +130,8 @@ public Transform Transform
_transformNeedUpdate = false;
var angle = -_rotation * 3.141592654F / 180.0F;
- var cosine = (float)Math.Cos(angle);
- var sine = (float)Math.Sin(angle);
+ var cosine = (float)Math.Cos(angle.Radians);
+ var sine = (float)Math.Sin(angle.Radians);
var sxc = _scale.X * cosine;
var syc = _scale.Y * cosine;
var sxs = _scale.X * sine;
@@ -190,7 +190,7 @@ protected override void Destroy(bool disposing)
private Vector2f _origin = new Vector2f(0, 0);
private Vector2f _position = new Vector2f(0, 0);
- private float _rotation;
+ private Angle _rotation;
private Vector2f _scale = new Vector2f(1, 1);
private Transform _transform;
private Transform _inverseTransform;
diff --git a/src/SFML.Graphics/View.cs b/src/SFML.Graphics/View.cs
index d01e2588..600512ee 100644
--- a/src/SFML.Graphics/View.cs
+++ b/src/SFML.Graphics/View.cs
@@ -89,10 +89,10 @@ public Vector2f Size
/// Rotation of the view, in degrees
///
////////////////////////////////////////////////////////////
- public float Rotation
+ public Angle Rotation
{
- get => sfView_getRotation(CPointer);
- set => sfView_setRotation(CPointer, value);
+ get => Angle.FromDegrees(sfView_getRotation(CPointer));
+ set => sfView_setRotation(CPointer, value.Degrees);
}
////////////////////////////////////////////////////////////
@@ -109,11 +109,26 @@ public FloatRect Viewport
////////////////////////////////////////////////////////////
///
- /// Rebuild the view from a rectangle
+ /// The scissor rectangle, expressed as a factor (between 0 and 1) of
+ /// the RenderTarget, specifies the region of the RenderTarget whose
+ /// pixels are able to be modified by draw or clear operations.
+ /// Any pixels which lie outside of the scissor rectangle will
+ /// not be modified by draw or clear operations.
+ /// For example, a scissor rectangle which only allows modifications
+ /// to the right side of the target would be defined
+ /// with View.setScissor(sf::FloatRect({0.5f, 0.f}, {0.5f, 1.f})).
+ /// By default, a view has a scissor rectangle which allows
+ /// modifications to the entire target. This is equivalent to
+ /// disabling the scissor test entirely. Passing the default
+ /// scissor rectangle to this function will also disable
+ /// scissor testing.
///
- /// Rectangle defining the position and size of the view
////////////////////////////////////////////////////////////
- public void Reset(FloatRect rectangle) => sfView_reset(CPointer, rectangle);
+ public FloatRect Scissor
+ {
+ get => sfView_getScissor(CPointer);
+ set => sfView_setScissor(CPointer, value);
+ }
////////////////////////////////////////////////////////////
///
@@ -210,7 +225,7 @@ protected override void Destroy(bool disposing)
private static extern void sfView_setViewport(IntPtr view, FloatRect viewport);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern void sfView_reset(IntPtr view, FloatRect rectangle);
+ private static extern void sfView_setScissor(IntPtr view, FloatRect viewport);
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern Vector2f sfView_getCenter(IntPtr view);
@@ -224,6 +239,9 @@ protected override void Destroy(bool disposing)
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern FloatRect sfView_getViewport(IntPtr view);
+ [DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+ private static extern FloatRect sfView_getScissor(IntPtr view);
+
[DllImport(CSFML.Graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfView_move(IntPtr view, Vector2f offset);
diff --git a/src/SFML.System/Angle.cs b/src/SFML.System/Angle.cs
new file mode 100644
index 00000000..67e11ebb
--- /dev/null
+++ b/src/SFML.System/Angle.cs
@@ -0,0 +1,335 @@
+using System;
+using System.Diagnostics;
+
+namespace SFML.System
+{
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Represents an angle value
+ ///
+ ////////////////////////////////////////////////////////////
+ public readonly struct Angle
+ {
+ private const float Tau = (float)(2 * Math.PI);
+ private const float Pi = (float)Math.PI;
+ private const double DegreesInRadian = 180.0 / Math.PI;
+ private const double RadiansInDegree = Math.PI / 180.0;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Construct an angle value from a number of radians
+ ///
+ /// Number of radians
+ /// Angle value constructed from the number of radians
+ ////////////////////////////////////////////////////////////
+ public static Angle FromRadians(float radians) => new Angle(radians);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Construct an angle value from a number of degrees
+ ///
+ /// Number of degrees
+ /// Angle value constructed from the number of degrees
+ ////////////////////////////////////////////////////////////
+ public static Angle FromDegrees(float degrees) => new Angle((float)(degrees * RadiansInDegree));
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Predefined 0 degree angle value
+ ///
+ ////////////////////////////////////////////////////////////
+ public static readonly Angle Zero;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Gets the angle's value in radians
+ ///
+ ////////////////////////////////////////////////////////////
+ public float Radians { get; }
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Gets the angle's value in degrees
+ ///
+ ////////////////////////////////////////////////////////////
+ public float Degrees => (float)(Radians * DegreesInRadian);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Wrap to a range such that -180° <= angle < 180°
+ ///
+ /// Similar to a modulo operation, this returns a copy of the angle
+ /// constrained to the range [-180°, 180°) == [-Pi, Pi).
+ /// The resulting angle represents a rotation which is equivalent to *this.
+ ///
+ /// The name "signed" originates from the similarity to signed integers:
+ ///
+ ///
+ /// |
+ /// signed |
+ /// unsigned |
+ ///
+ ///
+ /// char |
+ /// [-128, 128) |
+ /// [0, 256) |
+ ///
+ ///
+ /// Angle |
+ /// [-180°, 180°) |
+ /// [0°, 360°) |
+ ///
+ ///
+ ///
+ /// Signed angle, wrapped to [-180°, 180°)
+ ////////////////////////////////////////////////////////////
+ public Angle WrapSigned() => FromRadians(PositiveRemainder(Radians + Pi, Tau) - Pi);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Wrap to a range such that 0° <= angle < 360°
+ ///
+ /// Similar to a modulo operation, this returns a copy of the angle
+ /// constrained to the range [0°, 360°) == [0, Tau) == [0, 2*Pi).
+ /// The resulting angle represents a rotation which is equivalent to this
+ ///
+ /// The name "unsigned" originates from the similarity to unsigned integers:
+ ///
+ ///
+ /// |
+ /// signed |
+ /// unsigned |
+ ///
+ ///
+ /// char |
+ /// [-128, 128) |
+ /// [0, 256) |
+ ///
+ ///
+ /// Angle |
+ /// [-180°, 180°) |
+ /// [0°, 360°) |
+ ///
+ ///
+ ///
+ /// Unsigned angle, wrapped to [0°, 360°)
+ ////////////////////////////////////////////////////////////
+ public Angle WrapUnsigned() => FromRadians((float)PositiveRemainder(Radians, Tau));
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of == operator to compare two angle values
+ ///
+ /// Does not automatically wrap the angle value
+ /// Left operand (an angle)
+ /// Right operand (an angle)
+ /// True if both angle values are equal
+ ////////////////////////////////////////////////////////////
+ public static bool operator ==(Angle left, Angle right) => left.Radians == right.Radians;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of != operator to compare two angle values
+ ///
+ /// Does not automatically wrap the angle value
+ /// Left operand (an angle)
+ /// Right operand (an angle)
+ /// True if both angle values are different
+ ////////////////////////////////////////////////////////////
+ public static bool operator !=(Angle left, Angle right) => left.Radians != right.Radians;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of < operator to compare two angle values
+ ///
+ /// Does not automatically wrap the angle value
+ /// Left operand (an angle)
+ /// Right operand (an angle)
+ /// True if is less than
+ ////////////////////////////////////////////////////////////
+ public static bool operator <(Angle left, Angle right) => left.Radians < right.Radians;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of <= operator to compare two angle values
+ ///
+ /// Does not automatically wrap the angle value
+ /// Left operand (an angle)
+ /// Right operand (an angle)
+ /// True if is less than or equal to
+ ////////////////////////////////////////////////////////////
+ public static bool operator <=(Angle left, Angle right) => left.Radians <= right.Radians;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of > operator to compare two angle values
+ ///
+ /// Does not automatically wrap the angle value
+ /// Left operand (an angle)
+ /// Right operand (an angle)
+ /// True if is greater than
+ ////////////////////////////////////////////////////////////
+ public static bool operator >(Angle left, Angle right) => left.Radians > right.Radians;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of >= operator to compare two angle values
+ ///
+ /// Does not automatically wrap the angle value
+ /// Left operand (an angle)
+ /// Right operand (an angle)
+ /// True if is greater than or equal to
+ ////////////////////////////////////////////////////////////
+ public static bool operator >=(Angle left, Angle right) => left.Radians >= right.Radians;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of binary + operator to add two angle values
+ ///
+ /// Left operand (an angle)
+ /// Right operand (an angle)
+ /// Sum of the two angle values
+ ////////////////////////////////////////////////////////////
+ public static Angle operator +(Angle left, Angle right) => FromRadians(left.Radians + right.Radians);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of unary - operator to negate an angle value
+ ///
+ /// Represents a rotation in the opposite direction.
+ ///
+ /// Right operand (an angle)
+ /// Negative of the angle value
+ ////////////////////////////////////////////////////////////
+ public static Angle operator -(Angle right) => FromRadians(-right.Radians);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of binary - operator to substract two angle values
+ ///
+ /// Left operand (an angle)
+ /// Right operand (an angle)
+ /// Difference of the two angle values
+ ////////////////////////////////////////////////////////////
+ public static Angle operator -(Angle left, Angle right) => FromRadians(left.Radians - right.Radians);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of binary * operator to scale an angle value
+ ///
+ /// Left operand (an angle)
+ /// Right operand (a number)
+ /// multiplied by
+ ////////////////////////////////////////////////////////////
+ public static Angle operator *(Angle left, float right) => FromRadians(left.Radians * right);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of binary * operator to scale an angle value
+ ///
+ /// Left operand (a number)
+ /// Right operand (an angle)
+ /// multiplied by
+ ////////////////////////////////////////////////////////////
+ public static Angle operator *(float left, Angle right) => FromRadians(left * right.Radians);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of binary / operator to compute the ratio of two angle values
+ ///
+ /// Left operand (an angle)
+ /// Right operand (an angle)
+ /// divided by
+ ////////////////////////////////////////////////////////////
+ public static float operator /(Angle left, Angle right)
+ {
+ Debug.Assert(right.Radians != 0f, "Angle.operator/ cannot divide by 0");
+
+ return left.Radians / right.Radians;
+ }
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of binary / operator to scale an angle value
+ ///
+ /// Left operand (an angle)
+ /// Right operand (a number)
+ /// divided by
+ ////////////////////////////////////////////////////////////
+ public static Angle operator /(Angle left, float right)
+ {
+ Debug.Assert(right != 0f, "Angle.operator/ cannot divide by 0");
+
+ return FromRadians(left.Radians / right);
+ }
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of binary % operator to compute modulo of an angle value
+ ///
+ /// Right hand angle must be greater than zero.
+ ///
+ /// Examples:
+ ///
+ /// sf::degrees(90) % sf::degrees(40) // 10 degrees
+ /// sf::degrees(-90) % sf::degrees(40) // 30 degrees (not -10)
+ ///
+ ///
+ /// Left operand (an angle)
+ /// Right operand (an angle)
+ /// modulo
+ ////////////////////////////////////////////////////////////
+ public static Angle operator %(Angle left, Angle right)
+ {
+ Debug.Assert(right.Radians != 0f, "Angle.operator% cannot modulus by 0");
+
+ return FromRadians((float)PositiveRemainder(left.Radians, right.Radians));
+ }
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Compare angle and object and checks if they are equal
+ ///
+ /// Object to check
+ /// Object and angle are equal
+ ////////////////////////////////////////////////////////////
+ public override bool Equals(object obj) => (obj is Angle angle) && Equals(angle);
+
+ ///////////////////////////////////////////////////////////
+ ///
+ /// Compare two angles and checks if they are equal
+ ///
+ /// Angle to check
+ /// Angles are equal
+ ////////////////////////////////////////////////////////////
+ public bool Equals(Angle other) => Radians == other.Radians;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Provide a integer describing the object
+ ///
+ /// Integer description of the object
+ ////////////////////////////////////////////////////////////
+ public override int GetHashCode() => Radians.GetHashCode();
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Provide a string describing the object
+ ///
+ /// String description of the object
+ ////////////////////////////////////////////////////////////
+ public override string ToString() => "[Angle]" +
+ " Radians(" + Radians + ")" +
+ " Degrees(" + Degrees + ")";
+
+ private Angle(float radians) => Radians = radians;
+
+ private static float PositiveRemainder(float a, float b)
+ {
+ Debug.Assert(b > 0, "Cannot calculate remainder with non-positive divisor");
+
+ var val = a - ((int)(a / b) * b);
+ return val >= 0.0 ? val : val + b;
+ }
+ }
+}
diff --git a/src/SFML.System/Clock.cs b/src/SFML.System/Clock.cs
index cce8b5cd..90cd9894 100644
--- a/src/SFML.System/Clock.cs
+++ b/src/SFML.System/Clock.cs
@@ -14,6 +14,8 @@ public class Clock : ObjectBase
////////////////////////////////////////////////////////////
///
/// Default Constructor
+ ///
+ /// The clock starts automatically after being constructed.
///
////////////////////////////////////////////////////////////
public Clock() : base(sfClock_create()) { }
@@ -29,10 +31,33 @@ public Clock() : base(sfClock_create()) { }
////////////////////////////////////////////////////////////
///
/// Gets the time elapsed since the last call to Restart
+ /// (or the construction of the instance if Restart
+ /// has not been called).
///
////////////////////////////////////////////////////////////
public Time ElapsedTime => sfClock_getElapsedTime(CPointer);
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Check whether the clock is running
+ ///
+ ////////////////////////////////////////////////////////////
+ public bool IsRunning => sfClock_isRunning(CPointer);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Start the clock
+ ///
+ ////////////////////////////////////////////////////////////
+ public void Start() => sfClock_start(CPointer);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Stop the clock
+ ///
+ ////////////////////////////////////////////////////////////
+ public void Stop() => sfClock_stop(CPointer);
+
////////////////////////////////////////////////////////////
///
/// This function puts the time counter back to zero.
@@ -41,6 +66,16 @@ public Clock() : base(sfClock_create()) { }
////////////////////////////////////////////////////////////
public Time Restart() => sfClock_restart(CPointer);
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Reset the clock
+ ///
+ /// This function puts the time counter back to zero, returns
+ /// the elapsed time, and leaves the clock in a paused state.
+ ///
+ ////////////////////////////////////////////////////////////
+ public Time Reset() => sfClock_reset(CPointer);
+
#region Imports
[DllImport(CSFML.System, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern IntPtr sfClock_create();
@@ -51,8 +86,20 @@ public Clock() : base(sfClock_create()) { }
[DllImport(CSFML.System, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern Time sfClock_getElapsedTime(IntPtr clock);
+ [DllImport(CSFML.System, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+ private static extern bool sfClock_isRunning(IntPtr clock);
+
+ [DllImport(CSFML.System, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+ private static extern void sfClock_start(IntPtr clock);
+
+ [DllImport(CSFML.System, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+ private static extern void sfClock_stop(IntPtr clock);
+
[DllImport(CSFML.System, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern Time sfClock_restart(IntPtr clock);
+
+ [DllImport(CSFML.System, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+ private static extern Time sfClock_reset(IntPtr clock);
#endregion
}
}
diff --git a/src/SFML.System/StreamAdaptor.cs b/src/SFML.System/StreamAdaptor.cs
index 284ec043..3dddd884 100644
--- a/src/SFML.System/StreamAdaptor.cs
+++ b/src/SFML.System/StreamAdaptor.cs
@@ -19,7 +19,7 @@ public struct InputStream
///
////////////////////////////////////////////////////////////
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate long ReadCallbackType(IntPtr data, long size, IntPtr userData);
+ public delegate long ReadCallbackType(IntPtr data, UIntPtr size, IntPtr userData);
////////////////////////////////////////////////////////////
///
@@ -27,7 +27,7 @@ public struct InputStream
///
////////////////////////////////////////////////////////////
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate long SeekCallbackType(long position, IntPtr userData);
+ public delegate long SeekCallbackType(UIntPtr position, IntPtr userData);
////////////////////////////////////////////////////////////
///
@@ -148,9 +148,9 @@ public void Dispose()
/// User data -- unused
/// Number of bytes read
////////////////////////////////////////////////////////////
- private long Read(IntPtr data, long size, IntPtr userData)
+ private long Read(IntPtr data, UIntPtr size, IntPtr userData)
{
- var buffer = new byte[size];
+ var buffer = new byte[(int)size];
var count = _stream.Read(buffer, 0, (int)size);
Marshal.Copy(buffer, 0, data, count);
return count;
@@ -164,7 +164,7 @@ private long Read(IntPtr data, long size, IntPtr userData)
/// User data -- unused
/// Actual position
////////////////////////////////////////////////////////////
- private long Seek(long position, IntPtr userData) => _stream.Seek(position, SeekOrigin.Begin);
+ private long Seek(UIntPtr position, IntPtr userData) => _stream.Seek((long)position, SeekOrigin.Begin);
////////////////////////////////////////////////////////////
///
diff --git a/src/SFML.System/Time.cs b/src/SFML.System/Time.cs
index c6e41c5b..7c2a832a 100644
--- a/src/SFML.System/Time.cs
+++ b/src/SFML.System/Time.cs
@@ -119,7 +119,7 @@ namespace SFML.System
/// Object to check
/// Object and time are equal
////////////////////////////////////////////////////////////
- public override bool Equals(object obj) => (obj is Time) && Equals((Time)obj);
+ public override bool Equals(object obj) => (obj is Time time) && Equals(time);
///////////////////////////////////////////////////////////
///
diff --git a/src/SFML.System/Vector2.cs b/src/SFML.System/Vector2.cs
index 94cd8e5a..d91bab8a 100644
--- a/src/SFML.System/Vector2.cs
+++ b/src/SFML.System/Vector2.cs
@@ -25,11 +25,181 @@ public Vector2f(float x, float y)
Y = y;
}
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Construct the vector from its coordinates
+ ///
+ /// Note that this constructor is lossy: calling Length and Angle
+ /// may return values different to those provided in this constructor.
+ ///
+ /// In particular, these transforms can be applied:
+ /// * Vector2(r, phi) == Vector2(-r, phi + 180_deg)
+ /// * Vector2(r, phi) == Vector2(r, phi + n * 360_deg)
+ ///
+ /// Length of vector (can be negative)
+ /// Angle from X axis
+ ////////////////////////////////////////////////////////////
+ public Vector2f(float r, Angle phi)
+ {
+ X = (float)(r * Math.Cos(phi.Radians));
+ Y = (float)(r * Math.Sin(phi.Radians));
+ }
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Length of the vector
+ ///
+ /// If you are not interested in the actual length, but only in comparisons, consider using
+ ///
+ ////////////////////////////////////////////////////////////
+ public float Length => (float)Math.Sqrt((X * X) + (Y * Y));
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Square of vector's length
+ ///
+ /// Suitable for comparisons, more efficient than
+ ///
+ ////////////////////////////////////////////////////////////
+ public float LengthSquared => Dot(this);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Vector with same direction but length 1
+ ///
+ /// should not be a zero vector
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector2f Normalized() => this / Length;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Signed angle from to
+ ///
+ /// Neither nor should be a zero vector.
+ ///
+ ///
+ /// The smallest angle which rotates `*this` in positive
+ /// or negative direction, until it has the same direction as \a `rhs`.
+ /// The result has a sign and lies in the range [-180, 180) degrees.
+ ///
+ ////////////////////////////////////////////////////////////
+ public Angle AngleTo(Vector2f rhs) => SFML.System.Angle.FromRadians((float)Math.Atan2(Cross(rhs), Dot(rhs)));
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Signed angle from +X or (1,0) vector
+ ///
+ /// For example, the vector (1,0) corresponds to 0 degrees, (0,1) corresponds to 90 degrees.
+ ///
+ /// should not be a zero vector
+ ///
+ /// Angle in the range [-180, 180) degrees
+ ////////////////////////////////////////////////////////////
+ public Angle Angle() => SFML.System.Angle.FromRadians((float)Math.Atan2(Y, X));
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Rotate by angle
+ ///
+ /// Returns a vector with same length but different direction.
+ ///
+ /// In SFML's default coordinate system with +X right and +Y down,
+ /// this amounts to a clockwise rotation by .
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector2f RotatedBy(Angle phi)
+ {
+ var cos = Math.Cos(phi.Radians);
+ var sin = Math.Sin(phi.Radians);
+
+ return new Vector2f((float)((cos * X) - (sin * Y)), (float)((sin * X) + (cos * Y)));
+ }
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Projection of this vector onto
+ ///
+ /// must not have length zero
+ ///
+ /// Vector being projected onto. Need not be normalized
+ ////////////////////////////////////////////////////////////
+ public Vector2f ProjectedOnto(Vector2f axis) => Dot(axis) / axis.LengthSquared * axis;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Returns a perpendicular vector.
+ ///
+ /// Returns rotated by +90 degrees; (x,y) becomes (-y,x).
+ /// For example, the vector (1,0) is transformed to (0,1).
+ ///
+ /// In SFML's default coordinate system with +X right and +Y down,
+ /// this amounts to a clockwise rotation.
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector2f Perpendicular() => new Vector2f(-Y, X);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Dot product of two 2D vectors.
+ ///
+ ////////////////////////////////////////////////////////////
+ public float Dot(Vector2f rhs) => (X * rhs.X) + (Y * rhs.Y);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Z component of the cross product of two 2D vectors.
+ ///
+ /// Treats the operands as 3D vectors, computes their cross product
+ /// and returns the result's Z component (X and Y components are always zero).
+ ///
+ ////////////////////////////////////////////////////////////
+ public float Cross(Vector2f rhs) => (X * rhs.Y) - (Y * rhs.X);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Component-wise multiplication of and
+ ///
+ /// Computes (this.X * rhs.X, this.Y * rhs.Y)
+ ///
+ /// Scaling is the most common use case for component-wise multiplication/division.
+ /// This operation is also known as the Hadamard or Schur product.
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector2f ComponentWiseMul(Vector2f rhs) => new Vector2f(X * rhs.X, Y * rhs.Y);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Component-wise division of and
+ ///
+ /// Computes (this.X / rhs.X, this.Y / rhs.Y)
+ ///
+ /// Scaling is the most common use case for component-wise multiplication/division.
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector2f ComponentWiseDiv(Vector2f rhs) => new Vector2f(X / rhs.X, Y / rhs.Y);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The X unit vector (1, 0), usually facing right
+ ///
+ ////////////////////////////////////////////////////////////
+ public static readonly Vector2f UnitX = new Vector2f(1, 0);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The Y unit vector (0, 1), usually facing down
+ ///
+ ////////////////////////////////////////////////////////////
+ public static readonly Vector2f UnitY = new Vector2f(0, 1);
+
+ ////////////////////////////////////////////////////////////
///
/// Deconstructs a Vector2f into a tuple of floats
///
/// X coordinate
/// Y coordinate
+ ////////////////////////////////////////////////////////////
public void Deconstruct(out float x, out float y)
{
x = X;
@@ -130,7 +300,7 @@ public void Deconstruct(out float x, out float y)
/// Object to check
/// Object and vector are equal
////////////////////////////////////////////////////////////
- public override bool Equals(object obj) => (obj is Vector2f) && Equals((Vector2f)obj);
+ public override bool Equals(object obj) => (obj is Vector2f vec) && Equals(vec);
///////////////////////////////////////////////////////////
///
@@ -202,11 +372,87 @@ public Vector2i(int x, int y)
Y = y;
}
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Square of vector's length
+ ///
+ ////////////////////////////////////////////////////////////
+ public float LengthSquared => Dot(this);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Returns a perpendicular vector.
+ ///
+ /// Returns rotated by +90 degrees; (x,y) becomes (-y,x).
+ /// For example, the vector (1,0) is transformed to (0,1).
+ ///
+ /// In SFML's default coordinate system with +X right and +Y down,
+ /// this amounts to a clockwise rotation.
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector2i Perpendicular() => new Vector2i(-Y, X);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Dot product of two 2D vectors.
+ ///
+ ////////////////////////////////////////////////////////////
+ public float Dot(Vector2i rhs) => (X * rhs.X) + (Y * rhs.Y);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Z component of the cross product of two 2D vectors.
+ ///
+ /// Treats the operands as 3D vectors, computes their cross product
+ /// and returns the result's Z component (X and Y components are always zero).
+ ///
+ ////////////////////////////////////////////////////////////
+ public float Cross(Vector2i rhs) => (X * rhs.Y) - (Y * rhs.X);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Component-wise multiplication of and
+ ///
+ /// Computes (this.X * rhs.X, this.Y * rhs.Y)
+ ///
+ /// Scaling is the most common use case for component-wise multiplication/division.
+ /// This operation is also known as the Hadamard or Schur product.
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector2i ComponentWiseMul(Vector2i rhs) => new Vector2i(X * rhs.X, Y * rhs.Y);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Component-wise division of and
+ ///
+ /// Computes (this.X / rhs.X, this.Y / rhs.Y)
+ ///
+ /// Scaling is the most common use case for component-wise multiplication/division.
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector2i ComponentWiseDiv(Vector2i rhs) => new Vector2i(X / rhs.X, Y / rhs.Y);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The X unit vector (1, 0), usually facing right
+ ///
+ ////////////////////////////////////////////////////////////
+ public static readonly Vector2i UnitX = new Vector2i(1, 0);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The Y unit vector (0, 1), usually facing down
+ ///
+ ////////////////////////////////////////////////////////////
+ public static readonly Vector2i UnitY = new Vector2i(0, 1);
+
+ ////////////////////////////////////////////////////////////
///
/// Deconstructs a Vector2i into a tuple of ints
///
/// X coordinate
/// Y coordinate
+ ////////////////////////////////////////////////////////////
public void Deconstruct(out int x, out int y)
{
x = X;
@@ -307,7 +553,7 @@ public void Deconstruct(out int x, out int y)
/// Object to check
/// Object and vector are equal
////////////////////////////////////////////////////////////
- public override bool Equals(object obj) => (obj is Vector2i) && Equals((Vector2i)obj);
+ public override bool Equals(object obj) => (obj is Vector2i vec) && Equals(vec);
///////////////////////////////////////////////////////////
///
@@ -344,10 +590,12 @@ public void Deconstruct(out int x, out int y)
////////////////////////////////////////////////////////////
public static explicit operator Vector2u(Vector2i v) => new Vector2u((uint)v.X, (uint)v.Y);
+ ////////////////////////////////////////////////////////////
///
/// Converts a tuple of ints to a Vector2i
///
/// The tuple to convert
+ ////////////////////////////////////////////////////////////
public static implicit operator Vector2i((int X, int Y) tuple) => new Vector2i(tuple.X, tuple.Y);
/// X (horizontal) component of the vector
@@ -379,11 +627,74 @@ public Vector2u(uint x, uint y)
Y = y;
}
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Square of vector's length
+ ///
+ ////////////////////////////////////////////////////////////
+ public float LengthSquared => Dot(this);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Dot product of two 2D vectors.
+ ///
+ ////////////////////////////////////////////////////////////
+ public float Dot(Vector2u rhs) => (X * rhs.X) + (Y * rhs.Y);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Z component of the cross product of two 2D vectors.
+ ///
+ /// Treats the operands as 3D vectors, computes their cross product
+ /// and returns the result's Z component (X and Y components are always zero).
+ ///
+ ////////////////////////////////////////////////////////////
+ public float Cross(Vector2u rhs) => (X * rhs.Y) - (Y * rhs.X);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Component-wise multiplication of and
+ ///
+ /// Computes (this.X * rhs.X, this.Y * rhs.Y)
+ ///
+ /// Scaling is the most common use case for component-wise multiplication/division.
+ /// This operation is also known as the Hadamard or Schur product.
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector2u ComponentWiseMul(Vector2u rhs) => new Vector2u(X * rhs.X, Y * rhs.Y);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Component-wise division of and
+ ///
+ /// Computes (this.X / rhs.X, this.Y / rhs.Y)
+ ///
+ /// Scaling is the most common use case for component-wise multiplication/division.
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector2u ComponentWiseDiv(Vector2u rhs) => new Vector2u(X / rhs.X, Y / rhs.Y);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The X unit vector (1, 0), usually facing right
+ ///
+ ////////////////////////////////////////////////////////////
+ public static readonly Vector2u UnitX = new Vector2u(1, 0);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The Y unit vector (0, 1), usually facing down
+ ///
+ ////////////////////////////////////////////////////////////
+ public static readonly Vector2u UnitY = new Vector2u(0, 1);
+
+ ////////////////////////////////////////////////////////////
///
/// Deconstructs a Vector2u into a tuple of uints
///
/// X coordinate
/// Y coordinate
+ ////////////////////////////////////////////////////////////
public void Deconstruct(out uint x, out uint y)
{
x = X;
@@ -475,7 +786,7 @@ public void Deconstruct(out uint x, out uint y)
/// Object to check
/// Object and vector are equal
////////////////////////////////////////////////////////////
- public override bool Equals(object obj) => (obj is Vector2u) && Equals((Vector2u)obj);
+ public override bool Equals(object obj) => (obj is Vector2u vec) && Equals(vec);
///////////////////////////////////////////////////////////
///
@@ -512,10 +823,12 @@ public void Deconstruct(out uint x, out uint y)
////////////////////////////////////////////////////////////
public static explicit operator Vector2f(Vector2u v) => new Vector2f(v.X, v.Y);
+ ////////////////////////////////////////////////////////////
///
/// Converts a tuple of uints to a Vector2u
///
/// The tuple to convert
+ ////////////////////////////////////////////////////////////
public static implicit operator Vector2u((uint X, uint Y) tuple) => new Vector2u(tuple.X, tuple.Y);
/// X (horizontal) component of the vector
diff --git a/src/SFML.System/Vector3.cs b/src/SFML.System/Vector3.cs
index 5037ee4c..9d069015 100644
--- a/src/SFML.System/Vector3.cs
+++ b/src/SFML.System/Vector3.cs
@@ -27,12 +27,78 @@ public Vector3f(float x, float y, float z)
Z = z;
}
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Length of the vector
+ ///
+ /// If you are not interested in the actual length, but only in comparisons, consider using .
+ ///
+ ////////////////////////////////////////////////////////////
+ public float Length => (float)Math.Sqrt((X * X) + (Y * Y) + (Z * Z));
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Square of vector's length
+ ///
+ /// Suitable for comparisons, more efficient than
+ ///
+ ////////////////////////////////////////////////////////////
+ public float LengthSquared => Dot(this);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Vector with same direction but length 1
+ ///
+ /// should not be a zero vector
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector3f Normalized() => this / Length;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Dot product of two 3D vectors.
+ ///
+ ////////////////////////////////////////////////////////////
+ public float Dot(Vector3f rhs) => (X * rhs.X) + (Y * rhs.Y) + (Z * rhs.Z);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Cross product of two 3D vectors
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector3f Cross(Vector3f rhs) => new Vector3f((Y * rhs.Z) - (Z * rhs.Y), (Z * rhs.X) - (X * rhs.Z), (X * rhs.Y) - (Y * rhs.X));
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Component-wise multiplication of and
+ ///
+ /// Computes (this.X * rhs.X, this.Y * rhs.Y, this.Z * rhs.Z)
+ ///
+ /// Scaling is the most common use case for component-wise multiplication/division.
+ /// This operation is also known as the Hadamard or Schur product.
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector3f ComponentWiseMul(Vector3f rhs) => new Vector3f(X * rhs.X, Y * rhs.Y, Z * rhs.Z);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Component-wise division of and
+ ///
+ /// Computes (this.X / rhs.X, this.Y / rhs.Y, this.Z * rhs.Z)
+ ///
+ /// Scaling is the most common use case for component-wise multiplication/division.
+ ///
+ ////////////////////////////////////////////////////////////
+ public Vector3f ComponentWiseDiv(Vector3f rhs) => new Vector3f(X / rhs.X, Y / rhs.Y, Z / rhs.Z);
+
+ ////////////////////////////////////////////////////////////
///
/// Deconstructs a Vector3f into a tuple of floats
///
/// X coordinate
/// Y coordinate
/// Z coordinate
+ ////////////////////////////////////////////////////////////
public void Deconstruct(out float x, out float y, out float z)
{
x = X;
@@ -134,7 +200,7 @@ public void Deconstruct(out float x, out float y, out float z)
/// Object to check
/// Object and vector are equal
////////////////////////////////////////////////////////////
- public override bool Equals(object obj) => (obj is Vector3f) && Equals((Vector3f)obj);
+ public override bool Equals(object obj) => (obj is Vector3f vec) && Equals(vec);
///////////////////////////////////////////////////////////
///
@@ -153,10 +219,12 @@ public void Deconstruct(out float x, out float y, out float z)
////////////////////////////////////////////////////////////
public override int GetHashCode() => X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode();
+ ////////////////////////////////////////////////////////////
///
/// Converts a tuple of floats to a Vector3f
///
/// The tuple to convert
+ ////////////////////////////////////////////////////////////
public static implicit operator Vector3f((float X, float Y, float Z) tuple) => new Vector3f(tuple.X, tuple.Y, tuple.Z);
/// X (horizontal) component of the vector
diff --git a/src/SFML.Window/Context.cs b/src/SFML.Window/Context.cs
index 8739a662..56657ffb 100644
--- a/src/SFML.Window/Context.cs
+++ b/src/SFML.Window/Context.cs
@@ -4,6 +4,9 @@
using System.Security;
using SFML.System;
+// TODO getActiveContext
+// TODO getActiveContextId
+
namespace SFML.Window
{
//////////////////////////////////////////////////////////////////
diff --git a/src/SFML.Window/ContextSettings.cs b/src/SFML.Window/ContextSettings.cs
index 9cfe9029..4b88020b 100644
--- a/src/SFML.Window/ContextSettings.cs
+++ b/src/SFML.Window/ContextSettings.cs
@@ -84,13 +84,13 @@ public ContextSettings(uint depthBits, uint stencilBits, uint antialiasingLevel,
/// String description of the object
////////////////////////////////////////////////////////////
public override string ToString() => "[ContextSettings]" +
- " DepthBits(" + DepthBits + ")" +
- " StencilBits(" + StencilBits + ")" +
- " AntialiasingLevel(" + AntialiasingLevel + ")" +
- " MajorVersion(" + MajorVersion + ")" +
- " MinorVersion(" + MinorVersion + ")" +
- " AttributeFlags(" + AttributeFlags + ")" +
- " SRgbCapable(" + SRgbCapable + ")";
+ $" DepthBits({DepthBits})" +
+ $" StencilBits({StencilBits})" +
+ $" AntialiasingLevel({AntialiasingLevel})" +
+ $" MajorVersion({MajorVersion})" +
+ $" MinorVersion({MinorVersion})" +
+ $" AttributeFlags({AttributeFlags})" +
+ $" SRgbCapable({SRgbCapable})";
/// Depth buffer bits (0 is disabled)
public uint DepthBits;
diff --git a/src/SFML.Window/Cursor.cs b/src/SFML.Window/Cursor.cs
index fbb33a7d..c8787a77 100644
--- a/src/SFML.Window/Cursor.cs
+++ b/src/SFML.Window/Cursor.cs
@@ -5,9 +5,11 @@
namespace SFML.Window
{
+ ////////////////////////////////////////////////////////////
///
/// Cursor defines the appearance of a system cursor.
///
+ ////////////////////////////////////////////////////////////
public class Cursor : ObjectBase
{
///
@@ -164,6 +166,7 @@ public enum CursorType
NotAllowed
}
+ ////////////////////////////////////////////////////////////
///
/// Create a native system cursor
///
@@ -174,6 +177,7 @@ public enum CursorType
///
/// System cursor type
///
+ ////////////////////////////////////////////////////////////
public Cursor(CursorType type)
: base(sfCursor_createFromSystem(type))
{
@@ -183,6 +187,7 @@ public Cursor(CursorType type)
}
}
+ ////////////////////////////////////////////////////////////
///
/// Create a cursor with the provided image
///
@@ -209,7 +214,8 @@ public Cursor(CursorType type)
/// Width and height of the image
/// (x,y) location of the hotspot
///
- public Cursor(byte[] pixels, SFML.System.Vector2u size, SFML.System.Vector2u hotspot)
+ ////////////////////////////////////////////////////////////
+ public Cursor(byte[] pixels, Vector2u size, Vector2u hotspot)
: base((IntPtr)0)
{
unsafe
diff --git a/src/SFML.Window/Event.cs b/src/SFML.Window/Event.cs
index affc0c00..32d3c4f6 100644
--- a/src/SFML.Window/Event.cs
+++ b/src/SFML.Window/Event.cs
@@ -1,5 +1,5 @@
-using System;
using System.Runtime.InteropServices;
+using SFML.System;
namespace SFML.Window
{
@@ -31,10 +31,6 @@ public enum EventType
/// Event triggered when a keyboard key is released
KeyReleased,
- /// Event triggered when the mouse wheel is scrolled
- [Obsolete("Use MouseWheelScrolled")]
- MouseWheelMoved,
-
/// Event triggered when a mouse wheel is scrolled
MouseWheelScrolled,
@@ -47,6 +43,9 @@ public enum EventType
/// Event triggered when the mouse moves within the area of a window
MouseMoved,
+ /// Event triggered when the mouse moves within the area of a window, as raw mouse movement data
+ MouseMovedRaw, // TODO Sync with CSFML
+
/// Event triggered when the mouse enters the area of a window
MouseEntered,
@@ -96,16 +95,16 @@ public struct KeyEvent
public Keyboard.Scancode Scancode;
/// Is the Alt modifier pressed?
- public int Alt;
+ public bool Alt;
/// Is the Control modifier pressed?
- public int Control;
+ public bool Control;
/// Is the Shift modifier pressed?
- public int Shift;
+ public bool Shift;
/// Is the System modifier pressed?
- public int System;
+ public bool System;
}
////////////////////////////////////////////////////////////
@@ -128,48 +127,35 @@ public struct TextEvent
[StructLayout(LayoutKind.Sequential)]
public struct MouseMoveEvent
{
- /// X coordinate of the mouse cursor
- public int X;
-
- /// Y coordinate of the mouse cursor
- public int Y;
+ /// Coordinates of the mouse cursor
+ public Vector2i Position;
}
////////////////////////////////////////////////////////////
///
- /// Mouse buttons event parameters
+ /// Mouse move event parameters
///
////////////////////////////////////////////////////////////
[StructLayout(LayoutKind.Sequential)]
- public struct MouseButtonEvent
+ public struct MouseMoveRawEvent
{
- /// Code of the button (see MouseButton enum)
- public Mouse.Button Button;
-
- /// X coordinate of the mouse cursor
- public int X;
-
- /// Y coordinate of the mouse cursor
- public int Y;
+ /// Delta movement of the mouse since the last event
+ public Vector2i Delta;
}
////////////////////////////////////////////////////////////
///
- /// Mouse wheel move event parameters
+ /// Mouse buttons event parameters
///
////////////////////////////////////////////////////////////
[StructLayout(LayoutKind.Sequential)]
- [Obsolete("Use MouseWheelScrollEvent")]
- public struct MouseWheelEvent
+ public struct MouseButtonEvent
{
- /// Scroll amount
- public int Delta;
-
- /// X coordinate of the mouse cursor
- public int X;
+ /// Code of the button (see MouseButton enum)
+ public Mouse.Button Button;
- /// Y coordinate of the mouse cursor
- public int Y;
+ /// Coordinates of the mouse cursor
+ public Vector2i Position;
}
////////////////////////////////////////////////////////////
@@ -186,11 +172,8 @@ public struct MouseWheelScrollEvent
/// Scroll amount
public float Delta;
- /// X coordinate of the mouse cursor
- public int X;
-
- /// Y coordinate of the mouse cursor
- public int Y;
+ /// Coordinates of the mouse cursor
+ public Vector2i Position;
}
////////////////////////////////////////////////////////////
@@ -246,11 +229,8 @@ public struct JoystickConnectEvent
[StructLayout(LayoutKind.Sequential)]
public struct SizeEvent
{
- /// New width of the window
- public uint Width;
-
- /// New height of the window
- public uint Height;
+ /// New size of the window
+ public Vector2u Size;
}
////////////////////////////////////////////////////////////
@@ -264,11 +244,8 @@ public struct TouchEvent
/// Index of the finger in case of multi-touch events
public uint Finger;
- /// X position of the touch, relative to the left of the owner window
- public int X;
-
- /// Y position of the touch, relative to the top of the owner window
- public int Y;
+ /// Position of the touch, relative to the left of the owner window
+ public Vector2i Position;
}
////////////////////////////////////////////////////////////
@@ -282,14 +259,8 @@ public struct SensorEvent
/// Type of the sensor
public Sensor.Type Type;
- /// Current value of the sensor on X axis
- public float X;
-
- /// Current value of the sensor on Y axis
- public float Y;
-
- /// Current value of the sensor on Z axis
- public float Z;
+ /// Current value of the sensor on X, Y and Z axes
+ public Vector3f Value;
}
////////////////////////////////////////////////////////////
@@ -297,7 +268,7 @@ public struct SensorEvent
/// Event defines a system event and its parameters
///
////////////////////////////////////////////////////////////
- [StructLayout(LayoutKind.Explicit, Size = 28)]
+ [StructLayout(LayoutKind.Explicit, Size = 20)]
public struct Event
{
/// Type of event (see EventType enum)
@@ -320,14 +291,13 @@ public struct Event
[FieldOffset(4)]
public MouseMoveEvent MouseMove;
- /// Arguments for mouse button events (MouseButtonPressed, MouseButtonReleased)
+ /// Arguments for mouse move raw events (MouseMovedRaw)
[FieldOffset(4)]
- public MouseButtonEvent MouseButton;
+ public MouseMoveRawEvent MouseMoveRaw;
- /// Arguments for mouse wheel events (MouseWheelMoved)
+ /// Arguments for mouse button events (MouseButtonPressed, MouseButtonReleased)
[FieldOffset(4)]
- [Obsolete("Use MouseWheelScroll")]
- public MouseWheelEvent MouseWheel;
+ public MouseButtonEvent MouseButton;
/// Arguments for mouse wheel scroll events (MouseWheelScrolled)
[FieldOffset(4)]
diff --git a/src/SFML.Window/EventArgs.cs b/src/SFML.Window/EventArgs.cs
index 1fc4b7fc..72ed2f7e 100644
--- a/src/SFML.Window/EventArgs.cs
+++ b/src/SFML.Window/EventArgs.cs
@@ -1,4 +1,5 @@
using System;
+using SFML.System;
namespace SFML.Window
{
@@ -19,10 +20,10 @@ public KeyEventArgs(KeyEvent e)
{
Code = e.Code;
Scancode = e.Scancode;
- Alt = e.Alt != 0;
- Control = e.Control != 0;
- Shift = e.Shift != 0;
- System = e.System != 0;
+ Alt = e.Alt;
+ Control = e.Control;
+ Shift = e.Shift;
+ System = e.System;
}
////////////////////////////////////////////////////////////
@@ -71,7 +72,7 @@ public class TextEventArgs : EventArgs
///
/// Text event
////////////////////////////////////////////////////////////
- public TextEventArgs(TextEvent e) => Unicode = Char.ConvertFromUtf32((int)e.Unicode);
+ public TextEventArgs(TextEvent e) => Unicode = char.ConvertFromUtf32((int)e.Unicode);
////////////////////////////////////////////////////////////
///
@@ -99,11 +100,7 @@ public class MouseMoveEventArgs : EventArgs
///
/// Mouse move event
////////////////////////////////////////////////////////////
- public MouseMoveEventArgs(MouseMoveEvent e)
- {
- X = e.X;
- Y = e.Y;
- }
+ public MouseMoveEventArgs(MouseMoveEvent e) => Position = e.Position;
////////////////////////////////////////////////////////////
///
@@ -112,35 +109,26 @@ public MouseMoveEventArgs(MouseMoveEvent e)
/// String description of the object
////////////////////////////////////////////////////////////
public override string ToString() => "[MouseMoveEventArgs]" +
- " X(" + X + ")" +
- " Y(" + Y + ")";
-
- /// X coordinate of the mouse cursor
- public int X;
+ $" Position({Position.X}, {Position.Y})";
- /// Y coordinate of the mouse cursor
- public int Y;
+ /// Coordinates of the mouse cursor
+ public Vector2i Position;
}
////////////////////////////////////////////////////////////
///
- /// Mouse buttons event parameters
+ /// Mouse move raw event parameters
///
////////////////////////////////////////////////////////////
- public class MouseButtonEventArgs : EventArgs
+ public class MouseMoveRawEventArgs : EventArgs
{
////////////////////////////////////////////////////////////
///
- /// Construct the mouse button arguments from a mouse button event
+ /// Construct the mouse move raw arguments from a mouse move raw event
///
- /// Mouse button event
+ /// Mouse move event
////////////////////////////////////////////////////////////
- public MouseButtonEventArgs(MouseButtonEvent e)
- {
- Button = e.Button;
- X = e.X;
- Y = e.Y;
- }
+ public MouseMoveRawEventArgs(MouseMoveRawEvent e) => Delta = e.Delta;
////////////////////////////////////////////////////////////
///
@@ -148,40 +136,30 @@ public MouseButtonEventArgs(MouseButtonEvent e)
///
/// String description of the object
////////////////////////////////////////////////////////////
- public override string ToString() => "[MouseButtonEventArgs]" +
- " Button(" + Button + ")" +
- " X(" + X + ")" +
- " Y(" + Y + ")";
-
- /// Code of the button (see MouseButton enum)
- public Mouse.Button Button;
-
- /// X coordinate of the mouse cursor
- public int X;
+ public override string ToString() => "[MouseMoveRawEventArgs]" +
+ $" Delta({Delta.X}, {Delta.Y})";
- /// Y coordinate of the mouse cursor
- public int Y;
+ /// Delta movement of the mouse since last event
+ public Vector2i Delta;
}
////////////////////////////////////////////////////////////
///
- /// Mouse wheel event parameters
+ /// Mouse buttons event parameters
///
////////////////////////////////////////////////////////////
- [Obsolete("Use MouseWheelScrollEventArgs")]
- public class MouseWheelEventArgs : EventArgs
+ public class MouseButtonEventArgs : EventArgs
{
////////////////////////////////////////////////////////////
///
- /// Construct the mouse wheel arguments from a mouse wheel event
+ /// Construct the mouse button arguments from a mouse button event
///
- /// Mouse wheel event
+ /// Mouse button event
////////////////////////////////////////////////////////////
- public MouseWheelEventArgs(MouseWheelEvent e)
+ public MouseButtonEventArgs(MouseButtonEvent e)
{
- Delta = e.Delta;
- X = e.X;
- Y = e.Y;
+ Button = e.Button;
+ Position = e.Position;
}
////////////////////////////////////////////////////////////
@@ -190,19 +168,15 @@ public MouseWheelEventArgs(MouseWheelEvent e)
///
/// String description of the object
////////////////////////////////////////////////////////////
- public override string ToString() => "[MouseWheelEventArgs]" +
- " Delta(" + Delta + ")" +
- " X(" + X + ")" +
- " Y(" + Y + ")";
-
- /// Scroll amount
- public int Delta;
+ public override string ToString() => "[MouseButtonEventArgs]" +
+ $" Button({Button})" +
+ $" Position({Position.X}, {Position.Y})";
- /// X coordinate of the mouse cursor
- public int X;
+ /// Code of the button (see MouseButton enum)
+ public Mouse.Button Button;
- /// Y coordinate of the mouse cursor
- public int Y;
+ /// Coordinates of the mouse cursor
+ public Vector2i Position;
}
////////////////////////////////////////////////////////////
@@ -222,8 +196,7 @@ public MouseWheelScrollEventArgs(MouseWheelScrollEvent e)
{
Delta = e.Delta;
Wheel = e.Wheel;
- X = e.X;
- Y = e.Y;
+ Position = e.Position;
}
////////////////////////////////////////////////////////////
@@ -233,10 +206,9 @@ public MouseWheelScrollEventArgs(MouseWheelScrollEvent e)
/// String description of the object
////////////////////////////////////////////////////////////
public override string ToString() => "[MouseWheelScrollEventArgs]" +
- " Wheel(" + Wheel + ")" +
- " Delta(" + Delta + ")" +
- " X(" + X + ")" +
- " Y(" + Y + ")";
+ $" Wheel({Wheel})" +
+ $" Delta({Delta})" +
+ $" Position(${Position.X}, {Position.Y})";
/// Mouse Wheel which triggered the event
public Mouse.Wheel Wheel;
@@ -244,11 +216,8 @@ public override string ToString() => "[MouseWheelScrollEventArgs]" +
/// Scroll amount
public float Delta;
- /// X coordinate of the mouse cursor
- public int X;
-
- /// Y coordinate of the mouse cursor
- public int Y;
+ /// Coordinate of the mouse cursor
+ public Vector2i Position;
}
////////////////////////////////////////////////////////////
@@ -278,9 +247,9 @@ public JoystickMoveEventArgs(JoystickMoveEvent e)
/// String description of the object
////////////////////////////////////////////////////////////
public override string ToString() => "[JoystickMoveEventArgs]" +
- " JoystickId(" + JoystickId + ")" +
- " Axis(" + Axis + ")" +
- " Position(" + Position + ")";
+ $" JoystickId({JoystickId})" +
+ $" Axis({Axis})" +
+ $" Position({Position})";
/// Index of the joystick which triggered the event
public uint JoystickId;
@@ -318,8 +287,8 @@ public JoystickButtonEventArgs(JoystickButtonEvent e)
/// String description of the object
////////////////////////////////////////////////////////////
public override string ToString() => "[JoystickButtonEventArgs]" +
- " JoystickId(" + JoystickId + ")" +
- " Button(" + Button + ")";
+ $" JoystickId({JoystickId})" +
+ $" Button({Button})";
/// Index of the joystick which triggered the event
public uint JoystickId;
@@ -350,7 +319,7 @@ public class JoystickConnectEventArgs : EventArgs
/// String description of the object
////////////////////////////////////////////////////////////
public override string ToString() => "[JoystickConnectEventArgs]" +
- " JoystickId(" + JoystickId + ")";
+ $" JoystickId({JoystickId})";
/// Index of the joystick which triggered the event
public uint JoystickId;
@@ -369,11 +338,7 @@ public class SizeEventArgs : EventArgs
///
/// Size event
////////////////////////////////////////////////////////////
- public SizeEventArgs(SizeEvent e)
- {
- Width = e.Width;
- Height = e.Height;
- }
+ public SizeEventArgs(SizeEvent e) => Size = e.Size;
////////////////////////////////////////////////////////////
///
@@ -382,14 +347,10 @@ public SizeEventArgs(SizeEvent e)
/// String description of the object
////////////////////////////////////////////////////////////
public override string ToString() => "[SizeEventArgs]" +
- " Width(" + Width + ")" +
- " Height(" + Height + ")";
-
- /// New width of the window
- public uint Width;
+ $" Size({Size.X}, {Size.Y})";
- /// New height of the window
- public uint Height;
+ /// New size of the window
+ public Vector2u Size;
}
////////////////////////////////////////////////////////////
@@ -408,8 +369,7 @@ public class TouchEventArgs : EventArgs
public TouchEventArgs(TouchEvent e)
{
Finger = e.Finger;
- X = e.X;
- Y = e.Y;
+ Position = e.Position;
}
////////////////////////////////////////////////////////////
@@ -419,18 +379,14 @@ public TouchEventArgs(TouchEvent e)
/// String description of the object
////////////////////////////////////////////////////////////
public override string ToString() => "[TouchEventArgs]" +
- " Finger(" + Finger + ")" +
- " X(" + X + ")" +
- " Y(" + Y + ")";
+ $" Finger({Finger})" +
+ $" Position({Position.X}, {Position.Y})";
/// Index of the finger in case of multi-touch events
public uint Finger;
- /// X position of the touch, relative to the left of the owner window
- public int X;
-
- /// Y position of the touch, relative to the top of the owner window
- public int Y;
+ /// Position of the touch, relative to the left of the owner window
+ public Vector2i Position;
}
////////////////////////////////////////////////////////////
@@ -449,9 +405,7 @@ public class SensorEventArgs : EventArgs
public SensorEventArgs(SensorEvent e)
{
Type = e.Type;
- X = e.X;
- Y = e.Y;
- Z = e.Z;
+ Value = e.Value;
}
////////////////////////////////////////////////////////////
@@ -461,21 +415,13 @@ public SensorEventArgs(SensorEvent e)
/// String description of the object
////////////////////////////////////////////////////////////
public override string ToString() => "[SensorEventArgs]" +
- " Type(" + Type + ")" +
- " X(" + X + ")" +
- " Y(" + Y + ")" +
- " Z(" + Z + ")";
+ $" Type({Type})" +
+ $" Value({Value.X}, {Value.Y}, {Value.Z})";
/// Type of the sensor
public Sensor.Type Type;
- /// Current value of the sensor on X axis
- public float X;
-
- /// Current value of the sensor on Y axis
- public float Y;
-
- /// Current value of the sensor on Z axis
- public float Z;
+ /// Current value of the sensor on X, Y and Z axes
+ public Vector3f Value;
}
}
diff --git a/src/SFML.Window/Keyboard.cs b/src/SFML.Window/Keyboard.cs
index 49918b0e..ca2dbe8c 100644
--- a/src/SFML.Window/Keyboard.cs
+++ b/src/SFML.Window/Keyboard.cs
@@ -226,35 +226,16 @@ public enum Key
/// The F15 key
F15,
/// The Pause key
- Pause,
-
- /// The total number of keyboard keys
- KeyCount, // Keep last
-
- // Deprecated backwards compatible stuff
- /// DEPRECATED: Use Grave
- [Obsolete("Replace with Grave")]
- Tilde = Grave,
- /// DEPRECATED: Use Hyphen
- [Obsolete("Replace with Hyphen")]
- Dash = Hyphen,
- /// DEPRECATED: Use Backspace
- [Obsolete("Replace with Backspace")]
- BackSpace = Backspace,
- /// DEPRECATED: Use Enter
- [Obsolete("Replace with Enter")]
- Return = Enter,
- /// DEPRECATED: Use Backslash
- [Obsolete("Replace with Backslash")]
- BackSlash = Backslash,
- /// DEPRECATED: Use Semicolon
- [Obsolete("Replace with Semicolon")]
- SemiColon = Semicolon,
- /// DEPRECATED: Use Apostrophe
- [Obsolete("Replace with Apostrophe")]
- Quote = Apostrophe
+ Pause
};
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The total number of keyboard keys, ignoring
+ ///
+ ////////////////////////////////////////////////////////////
+ public static readonly uint KeyCount = (uint)Key.Pause + 1;
+
////////////////////////////////////////////////////////////
///
/// Scancodes
@@ -566,11 +547,15 @@ public enum Scancode
LaunchMail,
/// Keyboard Launch Media Select key
LaunchMediaSelect,
-
- /// Keep last -- the total number of scancodes
- ScancodeCount
}
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The total number of scancodes, ignoring
+ ///
+ ////////////////////////////////////////////////////////////
+ public static readonly uint ScancodeCount = (uint)Scancode.LaunchMediaSelect + 1;
+
////////////////////////////////////////////////////////////
///
/// Check if a key is pressed
diff --git a/src/SFML.Window/Mouse.cs b/src/SFML.Window/Mouse.cs
index b1b0ca07..33432c97 100644
--- a/src/SFML.Window/Mouse.cs
+++ b/src/SFML.Window/Mouse.cs
@@ -29,15 +29,19 @@ public enum Button
Middle,
/// The first extra mouse button
- XButton1,
+ Extra1,
/// The second extra mouse button
- XButton2,
-
- /// Keep last -- the total number of mouse buttons
- ButtonCount
+ Extra2
};
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The total number of mouse buttons
+ ///
+ ////////////////////////////////////////////////////////////
+ public static readonly uint ButtonCount = (uint)Button.Extra2 + 1;
+
////////////////////////////////////////////////////////////
///
/// Mouse wheels
@@ -46,10 +50,10 @@ public enum Button
public enum Wheel
{
/// The vertical mouse wheel
- VerticalWheel,
+ Vertical,
/// The horizontal mouse wheel
- HorizontalWheel
+ Horizontal
};
////////////////////////////////////////////////////////////
diff --git a/src/SFML.Window/Sensor.cs b/src/SFML.Window/Sensor.cs
index e004fb8a..6c8edb59 100644
--- a/src/SFML.Window/Sensor.cs
+++ b/src/SFML.Window/Sensor.cs
@@ -34,12 +34,16 @@ public enum Type
UserAcceleration,
/// Measures the absolute 3D orientation (degrees)
- Orientation,
-
- /// Keep last -- the total number of sensor types
- TypeCount
+ Orientation
};
+ ////////////////////////////////////////////////////////////
+ ///
+ /// The total number of sensor types
+ ///
+ ////////////////////////////////////////////////////////////
+ public static readonly uint Count = (uint)Type.Orientation + 1;
+
////////////////////////////////////////////////////////////
///
/// Check if a sensor is available on the underlying platform
diff --git a/src/SFML.Window/VideoMode.cs b/src/SFML.Window/VideoMode.cs
index ca374b0a..bcf0eb04 100644
--- a/src/SFML.Window/VideoMode.cs
+++ b/src/SFML.Window/VideoMode.cs
@@ -19,11 +19,10 @@ public struct VideoMode
///
/// Construct the video mode with its width and height
///
- /// Video mode width
- /// Video mode height
+ /// Video mode size
////////////////////////////////////////////////////////////
- public VideoMode(uint width, uint height) :
- this(width, height, 32)
+ public VideoMode(Vector2u size) :
+ this(size, 32)
{
}
@@ -31,14 +30,12 @@ public VideoMode(uint width, uint height) :
///
/// Construct the video mode with its width, height and depth
///
- /// Video mode width
- /// Video mode height
+ /// Video mode size
/// Video mode depth (bits per pixel)
////////////////////////////////////////////////////////////
- public VideoMode(uint width, uint height, uint bpp)
+ public VideoMode(Vector2u size, uint bpp)
{
- Width = width;
- Height = height;
+ Size = size;
BitsPerPixel = bpp;
}
@@ -87,19 +84,115 @@ public static VideoMode[] FullscreenModes
/// String description of the object
////////////////////////////////////////////////////////////
public override string ToString() => "[VideoMode]" +
- " Width(" + Width + ")" +
- " Height(" + Height + ")" +
- " BitsPerPixel(" + BitsPerPixel + ")";
+ $" Size({Size})" +
+ $" BitsPerPixel({BitsPerPixel})";
- /// Video mode width, in pixels
- public uint Width;
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Compare video mode and object and checks if they are equal
+ ///
+ /// Object to check
+ /// Object and video mode are equal
+ ////////////////////////////////////////////////////////////
+ public override bool Equals(object obj) => (obj is VideoMode mode) && Equals(mode);
+
+ ///////////////////////////////////////////////////////////
+ ///
+ /// Compare two video modes and checks if they are equal
+ ///
+ /// Video modes to check
+ /// Video modes are equal
+ ////////////////////////////////////////////////////////////
+ public bool Equals(VideoMode other) => (Size == other.Size) &&
+ (BitsPerPixel == other.BitsPerPixel);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Provide a integer describing the object
+ ///
+ /// Integer description of the object
+ ////////////////////////////////////////////////////////////
+ public override int GetHashCode() => Size.GetHashCode() ^ BitsPerPixel.GetHashCode();
- /// Video mode height, in pixels
- public uint Height;
+ /// Video mode width and height, in pixels
+ public Vector2u Size;
/// Video mode depth, in bits per pixel
public uint BitsPerPixel;
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of == operator to compare two video modes
+ ///
+ /// Left operand (a video mode)
+ /// Right operand (a video mode)
+ /// True if modes are equal
+ ////////////////////////////////////////////////////////////
+ public static bool operator ==(VideoMode left, VideoMode right) => left.Equals(right);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of != operator to compare two video modes
+ ///
+ /// Left operand (a video mode)
+ /// Right operand (a video mode)
+ /// True if modes are different
+ ////////////////////////////////////////////////////////////
+ public static bool operator !=(VideoMode left, VideoMode right) => !left.Equals(right);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of < operator to compare two video modes
+ ///
+ /// Left operand (a video mode)
+ /// Right operand (a video mode)
+ /// True if is less than
+ ////////////////////////////////////////////////////////////
+ public static bool operator <(VideoMode left, VideoMode right)
+ {
+ if (left.BitsPerPixel == right.BitsPerPixel)
+ {
+ if (left.Size.X == right.Size.X)
+ {
+ return left.Size.Y < right.Size.Y;
+ }
+
+ return left.Size.X < right.Size.X;
+ }
+
+ return left.BitsPerPixel < right.BitsPerPixel;
+ }
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of <= operator to compare two video modes
+ ///
+ /// Left operand (a video mode)
+ /// Right operand (a video mode)
+ /// True if is less than or equal to
+ ////////////////////////////////////////////////////////////
+ public static bool operator <=(VideoMode left, VideoMode right) => !(right < left);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of > operator to compare two video modes
+ ///
+ /// Left operand (a video mode)
+ /// Right operand (a video mode)
+ /// True if is greater than
+ ////////////////////////////////////////////////////////////
+ public static bool operator >(VideoMode left, VideoMode right) => right < left;
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Overload of >= operator to compare two video modes
+ ///
+ /// Left operand (a video mode)
+ /// Right operand (a video mode)
+ /// True if is greater than or equal to
+ ////////////////////////////////////////////////////////////
+ public static bool operator >=(VideoMode left, VideoMode right) => !(left < right);
+
#region Imports
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern VideoMode sfVideoMode_getDesktopMode();
diff --git a/src/SFML.Window/Window.cs b/src/SFML.Window/Window.cs
index 13209bbd..67fe05ea 100644
--- a/src/SFML.Window/Window.cs
+++ b/src/SFML.Window/Window.cs
@@ -21,7 +21,7 @@ public class Window : WindowBase
/// Title of the window
////////////////////////////////////////////////////////////
public Window(VideoMode mode, string title) :
- this(mode, title, Styles.Default, new ContextSettings(0, 0))
+ this(mode, title, Styles.Default, State.Windowed, new ContextSettings(0, 0))
{
}
@@ -32,9 +32,10 @@ public Window(VideoMode mode, string title) :
/// Video mode to use
/// Title of the window
/// Window style (Resize | Close by default)
+ /// Window state
////////////////////////////////////////////////////////////
- public Window(VideoMode mode, string title, Styles style) :
- this(mode, title, style, new ContextSettings(0, 0))
+ public Window(VideoMode mode, string title, Styles style, State state) :
+ this(mode, title, style, state, new ContextSettings(0, 0))
{
}
@@ -45,9 +46,10 @@ public Window(VideoMode mode, string title, Styles style) :
/// Video mode to use
/// Title of the window
/// Window style (Resize | Close by default)
+ /// Window state
/// Creation parameters
////////////////////////////////////////////////////////////
- public Window(VideoMode mode, string title, Styles style, ContextSettings settings) :
+ public Window(VideoMode mode, string title, Styles style, State state, ContextSettings settings) :
base(IntPtr.Zero)
{
// Copy the title to a null-terminated UTF-32 byte array
@@ -57,7 +59,7 @@ public Window(VideoMode mode, string title, Styles style, ContextSettings settin
{
fixed (byte* titlePtr = titleAsUtf32)
{
- CPointer = sfWindow_createUnicode(mode, (IntPtr)titlePtr, style, ref settings);
+ CPointer = sfWindow_createUnicode(mode, (IntPtr)titlePtr, style, state, ref settings);
}
}
}
@@ -164,17 +166,16 @@ public override void SetTitle(string title)
///
/// Change the window's icon
///
- /// Icon's width, in pixels
- /// Icon's height, in pixels
+ /// Icon's width and height, in pixels
/// Array of pixels, format must be RGBA 32 bits
////////////////////////////////////////////////////////////
- public override void SetIcon(uint width, uint height, byte[] pixels)
+ public override void SetIcon(Vector2u size, byte[] pixels)
{
unsafe
{
fixed (byte* pixelsPtr = pixels)
{
- sfWindow_setIcon(CPointer, width, height, pixelsPtr);
+ sfWindow_setIcon(CPointer, size, pixelsPtr);
}
}
}
@@ -278,7 +279,7 @@ public override void SetIcon(uint width, uint height, byte[] pixels)
/// OS-specific handle of the window
///
////////////////////////////////////////////////////////////
- public override IntPtr SystemHandle => sfWindow_getSystemHandle(CPointer);
+ public override IntPtr NativeHandle => sfWindow_getNativeHandle(CPointer);
////////////////////////////////////////////////////////////
///
@@ -383,10 +384,11 @@ protected Window(IntPtr cPointer, int dummy) :
///
/// Internal function to get the next event (blocking)
///
+ /// Maximum time to wait ( for infinite)
/// Variable to fill with the raw pointer to the event structure
/// False if any error occurred
////////////////////////////////////////////////////////////
- protected override bool WaitEvent(out Event eventToFill) => sfWindow_waitEvent(CPointer, out eventToFill);
+ protected override bool WaitEvent(Time timeout, out Event eventToFill) => sfWindow_waitEvent(CPointer, timeout, out eventToFill);
////////////////////////////////////////////////////////////
///
@@ -398,7 +400,7 @@ protected Window(IntPtr cPointer, int dummy) :
#region Imports
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfWindow_createUnicode(VideoMode mode, IntPtr title, Styles style, ref ContextSettings settings);
+ private static extern IntPtr sfWindow_createUnicode(VideoMode mode, IntPtr title, Styles style, State state, ref ContextSettings settings);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern IntPtr sfWindow_createFromHandle(IntPtr handle, ref ContextSettings settings);
@@ -416,7 +418,7 @@ protected Window(IntPtr cPointer, int dummy) :
private static extern bool sfWindow_pollEvent(IntPtr cPointer, out Event evt);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern bool sfWindow_waitEvent(IntPtr cPointer, out Event evt);
+ private static extern bool sfWindow_waitEvent(IntPtr cPointer, Time timeout, out Event evt);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfWindow_display(IntPtr cPointer);
@@ -440,7 +442,7 @@ protected Window(IntPtr cPointer, int dummy) :
private static extern void sfWindow_setUnicodeTitle(IntPtr cPointer, IntPtr title);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern unsafe void sfWindow_setIcon(IntPtr cPointer, uint width, uint height, byte* pixels);
+ private static extern unsafe void sfWindow_setIcon(IntPtr cPointer, Vector2u size, byte* pixels);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfWindow_setVisible(IntPtr cPointer, bool visible);
@@ -470,7 +472,7 @@ protected Window(IntPtr cPointer, int dummy) :
private static extern void sfWindow_setJoystickThreshold(IntPtr cPointer, float threshold);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfWindow_getSystemHandle(IntPtr cPointer);
+ private static extern IntPtr sfWindow_getNativeHandle(IntPtr cPointer);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfWindow_requestFocus(IntPtr cPointer);
diff --git a/src/SFML.Window/WindowBase.cs b/src/SFML.Window/WindowBase.cs
index ddf6794f..79b4241e 100644
--- a/src/SFML.Window/WindowBase.cs
+++ b/src/SFML.Window/WindowBase.cs
@@ -26,13 +26,23 @@ public enum Styles
/// Titlebar + close button
Close = 1 << 2,
- /// Fullscreen mode (this flag and all others are mutually exclusive))
- Fullscreen = 1 << 3,
-
/// Default window style (titlebar + resize + close)
Default = Titlebar | Resize | Close
}
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Enumeration of window states
+ ///
+ ////////////////////////////////////////////////////////////
+ public enum State
+ {
+ /// Floating window
+ Windowed,
+
+ /// Fullscreen window
+ Fullscreen
+ }
////////////////////////////////////////////////////////////
///
@@ -49,7 +59,7 @@ public class WindowBase : ObjectBase
/// Title of the window
////////////////////////////////////////////////////////////
public WindowBase(VideoMode mode, string title) :
- this(mode, title, Styles.Default)
+ this(mode, title, Styles.Default, State.Windowed)
{
}
@@ -60,8 +70,9 @@ public WindowBase(VideoMode mode, string title) :
/// Video mode to use
/// Title of the window
/// Window style (Resize | Close by default)
+ /// Window state
////////////////////////////////////////////////////////////
- public WindowBase(VideoMode mode, string title, Styles style) :
+ public WindowBase(VideoMode mode, string title, Styles style, State state) :
base(IntPtr.Zero)
{
// Copy the title to a null-terminated UTF-32 byte array
@@ -71,7 +82,7 @@ public WindowBase(VideoMode mode, string title, Styles style) :
{
fixed (byte* titlePtr = titleAsUtf32)
{
- CPointer = sfWindowBase_createUnicode(mode, (IntPtr)titlePtr, style);
+ CPointer = sfWindowBase_createUnicode(mode, (IntPtr)titlePtr, style, state);
}
}
}
@@ -152,17 +163,16 @@ public virtual void SetTitle(string title)
///
/// Change the window's icon
///
- /// Icon's width, in pixels
- /// Icon's height, in pixels
+ /// Icon's width and height, in pixels
/// Array of pixels, format must be RGBA 32 bits
////////////////////////////////////////////////////////////
- public virtual void SetIcon(uint width, uint height, byte[] pixels)
+ public virtual void SetIcon(Vector2u size, byte[] pixels)
{
unsafe
{
fixed (byte* pixelsPtr = pixels)
{
- sfWindowBase_setIcon(CPointer, width, height, pixelsPtr);
+ sfWindowBase_setIcon(CPointer, size, pixelsPtr);
}
}
}
@@ -238,7 +248,7 @@ public virtual void SetIcon(uint width, uint height, byte[] pixels)
/// OS-specific handle of the window
///
////////////////////////////////////////////////////////////
- public virtual IntPtr SystemHandle => sfWindowBase_getSystemHandle(CPointer);
+ public virtual IntPtr NativeHandle => sfWindowBase_getNativeHandle(CPointer);
////////////////////////////////////////////////////////////
///
@@ -246,9 +256,18 @@ public virtual void SetIcon(uint width, uint height, byte[] pixels)
/// event handler
///
////////////////////////////////////////////////////////////
- public void WaitAndDispatchEvents()
+ public void WaitAndDispatchEvents() => WaitAndDispatchEvents(Time.Zero);
+
+ ////////////////////////////////////////////////////////////
+ ///
+ /// Wait for a new event and dispatch it to the corresponding
+ /// event handler
+ ///
+ /// Maximum time to wait ( for infinite)
+ ////////////////////////////////////////////////////////////
+ public void WaitAndDispatchEvents(Time timeout)
{
- if (WaitEvent(out var e))
+ if (WaitEvent(timeout, out var e))
{
CallEventHandler(e);
}
@@ -338,10 +357,11 @@ protected WindowBase(IntPtr cPointer, int dummy) :
///
/// Internal function to get the next event (blocking)
///
+ /// Maximum time to wait ( for infinite)
/// Variable to fill with the raw pointer to the event structure
/// False if any error occurred
////////////////////////////////////////////////////////////
- protected virtual bool WaitEvent(out Event eventToFill) => sfWindowBase_waitEvent(CPointer, out eventToFill);
+ protected virtual bool WaitEvent(Time timeout, out Event eventToFill) => sfWindowBase_waitEvent(CPointer, timeout, out eventToFill);
////////////////////////////////////////////////////////////
///
@@ -452,13 +472,9 @@ private void CallEventHandler(Event e)
MouseMoved?.Invoke(this, new MouseMoveEventArgs(e.MouseMove));
break;
- // Disable CS0618 (Obsolete Warning). This Event will be removed in SFML.NET 3.0, but should remain supported until then.
-#pragma warning disable CS0618
- case EventType.MouseWheelMoved:
- MouseWheelMoved?.Invoke(this, new MouseWheelEventArgs(e.MouseWheel));
+ case EventType.MouseMovedRaw:
+ MouseMovedRaw?.Invoke(this, new MouseMoveRawEventArgs(e.MouseMoveRaw));
break;
- // restore CS0618
-#pragma warning restore CS0618
case EventType.MouseWheelScrolled:
MouseWheelScrolled?.Invoke(this, new MouseWheelScrollEventArgs(e.MouseWheelScroll));
@@ -514,10 +530,6 @@ private void CallEventHandler(Event e)
/// Event handler for the KeyReleased event
public event EventHandler KeyReleased;
- /// Event handler for the MouseWheelMoved event
- [Obsolete("Use MouseWheelScrolled")]
- public event EventHandler MouseWheelMoved;
-
/// Event handler for the MouseWheelScrolled event
public event EventHandler MouseWheelScrolled;
@@ -530,6 +542,9 @@ private void CallEventHandler(Event e)
/// Event handler for the MouseMoved event
public event EventHandler MouseMoved;
+ /// Event handler for the MouseMovedRaw event
+ public event EventHandler MouseMovedRaw;
+
/// Event handler for the MouseEntered event
public event EventHandler MouseEntered;
@@ -565,7 +580,7 @@ private void CallEventHandler(Event e)
#region Imports
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfWindowBase_createUnicode(VideoMode mode, IntPtr title, Styles style);
+ private static extern IntPtr sfWindowBase_createUnicode(VideoMode mode, IntPtr title, Styles style, State state);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern IntPtr sfWindowBase_createFromHandle(IntPtr handle);
@@ -583,7 +598,7 @@ private void CallEventHandler(Event e)
private static extern bool sfWindowBase_pollEvent(IntPtr cPointer, out Event evt);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern bool sfWindowBase_waitEvent(IntPtr cPointer, out Event evt);
+ private static extern bool sfWindowBase_waitEvent(IntPtr cPointer, Time timeout, out Event evt);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern Vector2i sfWindowBase_getPosition(IntPtr cPointer);
@@ -601,7 +616,7 @@ private void CallEventHandler(Event e)
private static extern void sfWindowBase_setUnicodeTitle(IntPtr cPointer, IntPtr title);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern unsafe void sfWindowBase_setIcon(IntPtr cPointer, uint width, uint height, byte* pixels);
+ private static extern unsafe void sfWindowBase_setIcon(IntPtr cPointer, Vector2u size, byte* pixels);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern void sfWindowBase_setVisible(IntPtr cPointer, bool visible);
@@ -628,7 +643,7 @@ private void CallEventHandler(Event e)
private static extern bool sfWindowBase_hasFocus(IntPtr cPointer);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
- private static extern IntPtr sfWindowBase_getSystemHandle(IntPtr cPointer);
+ private static extern IntPtr sfWindowBase_getNativeHandle(IntPtr cPointer);
[DllImport(CSFML.Window, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern bool sfWindowBase_createVulkanSurface(IntPtr cPointer, IntPtr vkInstance, out IntPtr surface, IntPtr vkAllocator);
diff --git a/test/SFML.System.Test/Angle.test.cs b/test/SFML.System.Test/Angle.test.cs
new file mode 100644
index 00000000..711cc1ec
--- /dev/null
+++ b/test/SFML.System.Test/Angle.test.cs
@@ -0,0 +1,264 @@
+namespace SFML.System.Test;
+
+public class AngleTests
+{
+ [Fact]
+ public void Construction()
+ {
+ var angle = new Angle();
+ Assert.Equal(0f, angle.Degrees);
+ Assert.Equal(0f, angle.Radians);
+ }
+
+ [Fact]
+ public void WrapSigned_WithZero()
+ => Assert.Equal(Angle.Zero, Angle.Zero.WrapSigned());
+
+ [Theory]
+ [InlineData(0, 0)]
+ [InlineData(1, 1)]
+ [InlineData(-1, -1)]
+ [InlineData(90, 90)]
+ [InlineData(-90, -90)]
+ [InlineData(180, -180)]
+ [InlineData(-180, -180)]
+ [InlineData(360, 0)]
+ [InlineData(-360, 0)]
+ [InlineData(720, 0)]
+ [InlineData(-720, 0)]
+ public void WrapSigned(float input, float expectedWrap)
+ => Assert.Equal(Angle.FromDegrees(expectedWrap).Radians, Angle.FromDegrees(input).WrapSigned().Radians, 1e-5);
+
+ [Fact]
+ public void WrapUnsigned_WithZero()
+ => Assert.Equal(Angle.Zero, Angle.Zero.WrapUnsigned());
+
+ [Theory]
+ [InlineData(0, 0)]
+ [InlineData(1, 1)]
+ [InlineData(-1, 359)]
+ [InlineData(90, 90)]
+ [InlineData(-90, 270)]
+ [InlineData(180, 180)]
+ [InlineData(-180, 180)]
+ [InlineData(360, 0)]
+ [InlineData(-360, 0)]
+ [InlineData(720, 0)]
+ [InlineData(-720, 0)]
+ public void WrapUnsigned(float input, float expectedWrap)
+ => Assert.Equal(Angle.FromDegrees(expectedWrap).Radians, Angle.FromDegrees(input).WrapUnsigned().Radians, 1e-5);
+
+ [Theory]
+ [InlineData(15, 0.26179939f)]
+ [InlineData(1000, 17.453293f)]
+ [InlineData(-4321, -75.415677f)]
+ public void Degrees(float degrees, float expectedRadians)
+ {
+ var angle = Angle.FromDegrees(degrees);
+ Assert.Equal(degrees, angle.Degrees, 1e-5);
+ Assert.Equal(expectedRadians, angle.Radians, 1e-5);
+ }
+
+ [Theory]
+ [InlineData(1, 57.2957795f)]
+ [InlineData(72, 4125.29612f)]
+ [InlineData(-200, -11459.1559f)]
+ public void Radians(float radians, float expectedDegrees)
+ {
+ var angle = Angle.FromRadians(radians);
+ Assert.Equal(radians, angle.Radians, 1e-5);
+ Assert.Equal(expectedDegrees, angle.Degrees, 1e-5);
+ }
+
+ [Fact]
+ public void Constants()
+ {
+ Assert.Equal(0f, Angle.Zero.Degrees);
+ Assert.Equal(0f, Angle.Zero.Radians);
+ }
+
+ [Fact]
+ public void OperatorEq()
+ {
+ Assert.True(new Angle() == new Angle());
+ Assert.True(new Angle() == Angle.Zero);
+ Assert.True(new Angle() == Angle.FromDegrees(0));
+ Assert.True(new Angle() == Angle.FromRadians(0));
+ Assert.True(Angle.FromDegrees(0) == Angle.FromRadians(0));
+ Assert.True(Angle.FromDegrees(15) == Angle.FromDegrees(15));
+ Assert.True(Angle.FromRadians(15) == Angle.FromRadians(15));
+ Assert.True(Angle.FromDegrees(360) == Angle.FromDegrees(360));
+ Assert.True(Angle.FromDegrees(720) == Angle.FromDegrees(720));
+ }
+
+ [Fact]
+ public void OperatorNotEq()
+ {
+ Assert.True(new Angle() != Angle.FromRadians(2));
+ Assert.True(Angle.FromDegrees(1) != Angle.FromRadians(1));
+ Assert.True(Angle.FromRadians(0) != Angle.FromRadians(0.1f));
+ }
+
+ [Fact]
+ public void OperatorLt()
+ {
+ Assert.True(Angle.FromRadians(0) < Angle.FromDegrees(0.1f));
+ Assert.True(Angle.FromDegrees(0) < Angle.FromRadians(0.1f));
+ Assert.True(Angle.FromRadians(-0.1f) < Angle.FromRadians(0f));
+ Assert.True(Angle.FromDegrees(-0.1f) < Angle.FromDegrees(0f));
+ }
+
+ [Fact]
+ public void OperatorGt()
+ {
+ Assert.True(Angle.FromRadians(0.1f) > Angle.FromDegrees(0));
+ Assert.True(Angle.FromDegrees(0.1f) > Angle.FromRadians(0));
+ Assert.True(Angle.FromRadians(0) > Angle.FromRadians(-0.1f));
+ Assert.True(Angle.FromDegrees(0) > Angle.FromDegrees(-0.1f));
+ }
+
+ [Fact]
+ public void OperatorLte()
+ {
+ Assert.True(Angle.FromRadians(0) <= Angle.FromDegrees(0.1f));
+ Assert.True(Angle.FromDegrees(0) <= Angle.FromRadians(0.1f));
+ Assert.True(Angle.FromRadians(-0.1f) <= Angle.FromRadians(0f));
+ Assert.True(Angle.FromDegrees(-0.1f) <= Angle.FromDegrees(0f));
+
+ Assert.True(new Angle() <= new Angle());
+ Assert.True(new Angle() <= Angle.Zero);
+ Assert.True(new Angle() <= Angle.FromDegrees(0));
+ Assert.True(new Angle() <= Angle.FromRadians(0));
+ Assert.True(Angle.FromDegrees(0) <= Angle.FromRadians(0));
+ Assert.True(Angle.FromDegrees(15) <= Angle.FromDegrees(15));
+ Assert.True(Angle.FromRadians(15) <= Angle.FromRadians(15));
+ Assert.True(Angle.FromDegrees(360) <= Angle.FromDegrees(360));
+ Assert.True(Angle.FromDegrees(720) <= Angle.FromDegrees(720));
+ }
+
+ [Fact]
+ public void OperatorGte()
+ {
+ Assert.True(Angle.FromRadians(0.1f) > Angle.FromDegrees(0));
+ Assert.True(Angle.FromDegrees(0.1f) > Angle.FromRadians(0));
+ Assert.True(Angle.FromRadians(0) > Angle.FromRadians(-0.1f));
+ Assert.True(Angle.FromDegrees(0) > Angle.FromDegrees(-0.1f));
+
+ Assert.True(new Angle() >= new Angle());
+ Assert.True(new Angle() >= Angle.Zero);
+ Assert.True(new Angle() >= Angle.FromDegrees(0));
+ Assert.True(new Angle() >= Angle.FromRadians(0));
+ Assert.True(Angle.FromDegrees(0) >= Angle.FromRadians(0));
+ Assert.True(Angle.FromDegrees(15) >= Angle.FromDegrees(15));
+ Assert.True(Angle.FromRadians(15) >= Angle.FromRadians(15));
+ Assert.True(Angle.FromDegrees(360) >= Angle.FromDegrees(360));
+ Assert.True(Angle.FromDegrees(720) >= Angle.FromDegrees(720));
+ }
+
+ [Fact]
+ public void OperatorNeg()
+ {
+ Assert.Equal(-new Angle(), new Angle());
+ Assert.Equal(-Angle.FromRadians(-1), Angle.FromRadians(1));
+ Assert.Equal(-Angle.FromDegrees(15), Angle.FromDegrees(-15));
+ Assert.Equal(-Angle.FromRadians(1), Angle.FromRadians(-1));
+ }
+
+ [Fact]
+ public void OperatorAdd()
+ {
+ Assert.Equal(new Angle() + new Angle(), new Angle());
+ Assert.Equal(Angle.Zero + Angle.FromRadians(0.5f), Angle.FromRadians(0.5f));
+ Assert.Equal(Angle.FromRadians(6) + Angle.FromRadians(0.5f), Angle.FromRadians(6.5f));
+ Assert.Equal(Angle.FromRadians(10) + Angle.FromRadians(0.5f), Angle.FromRadians(10.5f));
+ Assert.Equal(Angle.FromDegrees(360) + Angle.FromDegrees(360), Angle.FromDegrees(720));
+ }
+
+ [Fact]
+ public void OperatorAddAssign()
+ {
+ var angle = Angle.FromDegrees(-15);
+ angle += Angle.FromDegrees(15);
+ Assert.Equal(Angle.FromDegrees(0).Degrees, angle.Degrees, 1e-5);
+ angle += Angle.FromDegrees(10);
+ Assert.Equal(Angle.FromDegrees(10).Degrees, angle.Degrees, 1e-5);
+ }
+
+ [Fact]
+ public void OperatorSub()
+ {
+ Assert.Equal(new Angle() - new Angle(), new Angle());
+ Assert.Equal(Angle.FromRadians(1) - Angle.FromRadians(0.5f), Angle.FromRadians(0.5f));
+ Assert.Equal(Angle.Zero - Angle.FromRadians(0.5f), Angle.FromRadians(-0.5f));
+ Assert.Equal(Angle.FromDegrees(900) - Angle.FromDegrees(1), Angle.FromDegrees(899));
+ }
+
+ [Fact]
+ public void OperatorSubAssign()
+ {
+ var angle = Angle.FromDegrees(15);
+ angle -= Angle.FromDegrees(15);
+ Assert.Equal(Angle.FromDegrees(0).Degrees, angle.Degrees, 1e-5);
+ angle -= Angle.FromDegrees(10);
+ Assert.Equal(Angle.FromDegrees(-10).Degrees, angle.Degrees, 1e-5);
+ }
+
+ [Fact]
+ public void OperatorMul()
+ {
+ Assert.Equal(10 * Angle.FromRadians(0), Angle.Zero);
+ Assert.Equal((2.5f * Angle.FromDegrees(10)).Degrees, Angle.FromDegrees(25).Degrees, 1e-5);
+ Assert.Equal((10f * Angle.FromDegrees(100)).Degrees, Angle.FromDegrees(1000).Degrees, 1e-5);
+
+ Assert.Equal(10 * Angle.FromRadians(0), Angle.Zero);
+ Assert.Equal((2.5f * Angle.FromDegrees(10)).Degrees, Angle.FromDegrees(25).Degrees, 1e-5);
+ Assert.Equal((10f * Angle.FromDegrees(100)).Degrees, Angle.FromDegrees(1000).Degrees, 1e-5);
+ }
+
+ [Fact]
+ public void OperatorMulAssign()
+ {
+ var angle = Angle.FromDegrees(1);
+ angle *= 10;
+ Assert.Equal(Angle.FromDegrees(10).Degrees, angle.Degrees, 1e-5);
+ }
+
+ [Fact]
+ public void OperatorDiv()
+ {
+ Assert.Equal(Angle.Zero / 10, Angle.Zero);
+ Assert.Equal(Angle.FromDegrees(10) / 2.5f, Angle.FromDegrees(4));
+ Assert.Equal(Angle.FromRadians(12) / 3, Angle.FromRadians(4));
+
+ Assert.Equal(0f, Angle.Zero / Angle.FromDegrees(1));
+ Assert.Equal(1f, Angle.FromDegrees(10) / Angle.FromDegrees(10));
+ Assert.Equal(5f, Angle.FromRadians(10) / Angle.FromRadians(2), 1e-5);
+ }
+
+ [Fact]
+ public void OperatorDivAssign()
+ {
+ var angle = Angle.FromDegrees(60);
+ angle /= 5;
+ Assert.Equal(Angle.FromDegrees(12).Degrees, angle.Degrees, 1e-5);
+ }
+
+ [Fact]
+ public void OperatorMod()
+ {
+ Assert.Equal(Angle.Zero % Angle.FromRadians(0.5f), Angle.Zero);
+ Assert.Equal(Angle.FromRadians(10) % Angle.FromRadians(1), Angle.FromRadians(0));
+ Assert.Equal((Angle.FromDegrees(90) % Angle.FromDegrees(30)).Degrees, Angle.FromDegrees(0).Degrees, 1e-5);
+ Assert.Equal((Angle.FromDegrees(90) % Angle.FromDegrees(40)).Degrees, Angle.FromDegrees(10).Degrees, 1e-5);
+ Assert.Equal((Angle.FromDegrees(-90) % Angle.FromDegrees(30)).Degrees, Angle.FromDegrees(0).Degrees, 1e-5);
+ Assert.Equal((Angle.FromDegrees(-90) % Angle.FromDegrees(40)).Degrees, Angle.FromDegrees(30).Degrees, 1e-5);
+ }
+
+ [Fact]
+ public void OperatorModAssign()
+ {
+ var angle = Angle.FromDegrees(59);
+ angle %= Angle.FromDegrees(10);
+ Assert.Equal(Angle.FromDegrees(9).Degrees, angle.Degrees, 1e-5);
+ }
+}
\ No newline at end of file
diff --git a/test/SFML.System.Test/SFML.System.Test.csproj b/test/SFML.System.Test/SFML.System.Test.csproj
new file mode 100644
index 00000000..43bfedd4
--- /dev/null
+++ b/test/SFML.System.Test/SFML.System.Test.csproj
@@ -0,0 +1,28 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+ false
+ true
+ AnyCPU;x86;x64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+