From 9237d3b70f61944c359f15fd211f1798581ea46e Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Sun, 18 May 2014 06:32:14 -0700 Subject: [PATCH 01/27] Use a ForwardRange!dchar instead of dstring for Text objects --- src/dsfml/graphics/text.d | 58 ++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/src/dsfml/graphics/text.d b/src/dsfml/graphics/text.d index 5f5233b..1a7f740 100644 --- a/src/dsfml/graphics/text.d +++ b/src/dsfml/graphics/text.d @@ -44,6 +44,9 @@ import dsfml.graphics.primitivetype; import dsfml.system.vector2; +import std.range; +import std.utf; + /++ + Graphical text that can be drawn to a render target. + @@ -75,7 +78,7 @@ class Text : Drawable, Transformable private { - dstring m_string; + ForwardRange!dchar m_string; Rebindable!(const(Font)) m_font; uint m_characterSize; Style m_style; @@ -90,7 +93,7 @@ class Text : Drawable, Transformable this() { - m_string = ""; + m_string = null; m_characterSize = 30; m_style = Style.Regular; m_color = Color(255,255,255); @@ -98,9 +101,9 @@ class Text : Drawable, Transformable m_bounds = FloatRect(); } - this(dstring text, const(Font) font, uint characterSize = 30) + this(T)(T text, const(Font) font, uint characterSize = 30) if (isForwardRange!T && is(ElementType!T : dchar)) { - m_string = text; + m_string = inputRangeObject(text); m_characterSize = characterSize; m_style = Style.Regular; m_color = Color(255,255,255); @@ -185,7 +188,7 @@ class Text : Drawable, Transformable * * The returned string is a dstring, a unicode type. */ - dstring getString() const + auto getString() const { return m_string; } @@ -250,9 +253,9 @@ class Text : Drawable, Transformable * Params: * text = New string */ - void setString(dstring text) + void setString(T)(T text) if (isForwardRange!T && is(ElementType!(T) : dchar)) { - m_string = text; + m_string = inputRangeObject(text); updateGeometry(); } @@ -314,12 +317,6 @@ class Text : Drawable, Transformable return Vector2f(0,0); } - // Adjust the index if it's out of range - if(index > m_string.length) - { - index = m_string.length; - } - bool bold = (m_style & Style.Bold) != 0; float hspace = cast(float)(m_font.getGlyph(' ', m_characterSize, bold).advance); @@ -327,9 +324,21 @@ class Text : Drawable, Transformable Vector2f position; dchar prevChar = 0; - for (size_t i = 0; i < index; ++i) + size_t i; + auto iter = m_string.save(); + + while (!iter.empty) { - dchar curChar = m_string[i]; + + dchar curChar; + + try { + curChar = iter.decodeFront(); + } catch (UTFException e) { + //XXX: I tried setting it to \uFFFD and continuing, but strings that end in invalid. + // unicode don't seem to be safely iterable; + break; + } // Apply the kerning offset position.x += cast(float)(m_font.getKerning(prevChar, curChar, m_characterSize)); @@ -348,6 +357,8 @@ class Text : Drawable, Transformable // For regular characters, add the advance offset of the glyph position.x += cast(float)(m_font.getGlyph(curChar, m_characterSize, bold).advance); + if (i == index) break; + i++; } // Transform the position to global coordinates @@ -370,7 +381,7 @@ private: return; // No text: nothing to draw - if (m_string.length == 0) + if (m_string.empty) return; // Compute values related to the text style bool bold = (m_style & Style.Bold) != 0; @@ -388,10 +399,19 @@ private: // Create one quad for each character float minX = m_characterSize, minY = m_characterSize, maxX = 0, maxY = 0; dchar prevChar = 0; - for (size_t i = 0; i < m_string.length; ++i) - { - dchar curChar = m_string[i]; + auto iter = m_string.save(); + while (!iter.empty) + { + //dchar curChar = m_string[i]; + dchar curChar; + try { + curChar = iter.decodeFront(); + } catch (UTFException e) { + //XXX: I tried setting it to \uFFFD and continuing, but strings that end in invalid. + // unicode don't seem to be safely iterable; + break; + } // Apply the kerning offset x += cast(float)(m_font.getKerning(prevChar, curChar, m_characterSize)); From a380d7af03af117876ea21dfc79e4771153e04f4 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Mon, 19 May 2014 15:09:13 -0700 Subject: [PATCH 02/27] Don't return reference with getString() --- src/dsfml/graphics/text.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dsfml/graphics/text.d b/src/dsfml/graphics/text.d index 1a7f740..4086623 100644 --- a/src/dsfml/graphics/text.d +++ b/src/dsfml/graphics/text.d @@ -190,7 +190,7 @@ class Text : Drawable, Transformable */ auto getString() const { - return m_string; + return m_string.save(); } /** From a9c3169b867bbeefb676354fb0e530e1a7885c9f Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Sat, 2 Apr 2016 12:09:12 -0700 Subject: [PATCH 03/27] Begin wrapping SFML 2.3 functionality. Requires DSFMLC 2.3. --- dub.json | 20 +-- src/app.d | 5 + .../audio/{soundfile.d => inputsoundfile.d} | 66 ++++----- src/dsfml/audio/listener.d | 25 ++++ src/dsfml/audio/music.d | 4 +- src/dsfml/audio/soundbuffer.d | 2 +- src/dsfml/graphics/blendmode.d | 41 +++++- src/dsfml/graphics/font.d | 44 +++++- src/dsfml/graphics/rendertexture.d | 7 +- src/dsfml/graphics/renderwindow.d | 7 +- src/dsfml/network/ftp.d | 17 +++ src/dsfml/network/http.d | 6 +- src/dsfml/window/event.d | 55 ++++++++ src/dsfml/window/joystick.d | 33 +++++ src/dsfml/window/mouse.d | 8 ++ src/dsfml/window/package.d | 2 + src/dsfml/window/sensor.d | 127 ++++++++++++++++++ src/dsfml/window/touch.d | 111 +++++++++++++++ src/dsfml/window/window.d | 22 ++- 19 files changed, 544 insertions(+), 58 deletions(-) create mode 100644 src/app.d rename src/dsfml/audio/{soundfile.d => inputsoundfile.d} (60%) create mode 100644 src/dsfml/window/sensor.d create mode 100644 src/dsfml/window/touch.d diff --git a/dub.json b/dub.json index 5c5f27c..f83c7f1 100644 --- a/dub.json +++ b/dub.json @@ -5,11 +5,11 @@ "homepage": "https://github.com/Jebbs/DSFML", "license": "Zlib", "dependencies": { - "dsfml:audio": "~>2.1", - "dsfml:graphics": "~>2.1", - "dsfml:window": "~>2.1", - "dsfml:network": "~>2.1", - "dsfml:system": "~>2.1" + "dsfml:audio": "~>2.3", + "dsfml:graphics": "~>2.3", + "dsfml:window": "~>2.3", + "dsfml:network": "~>2.3", + "dsfml:system": "~>2.3" }, "subPackages": [ @@ -20,7 +20,7 @@ "libs": [ "dsfmlc-audio" ], "dependencies": { - "dsfml:system": "~>2.1" + "dsfml:system": "~>2.3" } }, { @@ -30,8 +30,8 @@ "libs": [ "dsfmlc-graphics" ], "dependencies": { - "dsfml:system": "~>2.1", - "dsfml:window": "~>2.1" + "dsfml:system": "~>2.3", + "dsfml:window": "~>2.3" } }, { @@ -40,7 +40,7 @@ "libs": [ "dsfmlc-window" ], "dependencies": { - "dsfml:system": "~>2.1" + "dsfml:system": "~>2.3" } }, { @@ -50,7 +50,7 @@ "libs": [ "dsfmlc-network" ], "dependencies": { - "dsfml:system": "~>2.1" + "dsfml:system": "~>2.3" } }, { diff --git a/src/app.d b/src/app.d new file mode 100644 index 0000000..e7dcc27 --- /dev/null +++ b/src/app.d @@ -0,0 +1,5 @@ +import std.stdio; + +void main() { + writeln("Hello World."); +} \ No newline at end of file diff --git a/src/dsfml/audio/soundfile.d b/src/dsfml/audio/inputsoundfile.d similarity index 60% rename from src/dsfml/audio/soundfile.d rename to src/dsfml/audio/inputsoundfile.d index 42c6271..69897ec 100644 --- a/src/dsfml/audio/soundfile.d +++ b/src/dsfml/audio/inputsoundfile.d @@ -17,7 +17,7 @@ If you use this software in a product, an acknowledgment in the product document 3. This notice may not be removed or altered from any source distribution */ -module dsfml.audio.soundfile; +module dsfml.audio.inputsoundfile; import std.string; import dsfml.system.inputstream; @@ -25,25 +25,25 @@ import dsfml.system.err; package: -struct SoundFile +struct InputSoundFile { - private sfSoundFile* m_soundFile; + private sfInputSoundFile* m_soundFile; private soundFileStream m_stream;//keeps an instance of the C++ interface stored if used void create() { - m_soundFile = sfSoundFile_create(); + m_soundFile = sfInputSoundFile_create(); } ~this() { - sfSoundFile_destroy(m_soundFile); + sfInputSoundFile_destroy(m_soundFile); } bool openReadFromFile(string filename) { import dsfml.system.string; - bool toReturn = sfSoundFile_openReadFromFile(m_soundFile, toStringz(filename)); + bool toReturn = sfInputSoundFile_openFromFile(m_soundFile, toStringz(filename)); err.write(toString(sfErr_getOutput())); return toReturn; } @@ -51,7 +51,7 @@ struct SoundFile bool openReadFromMemory(const(void)[] data) { import dsfml.system.string; - bool toReturn = sfSoundFile_openReadFromMemory(m_soundFile, data.ptr, data.length); + bool toReturn = sfInputSoundFile_openFromMemory(m_soundFile, data.ptr, data.length); err.write(toString(sfErr_getOutput())); return toReturn; } @@ -60,34 +60,34 @@ struct SoundFile import dsfml.system.string; m_stream = new soundFileStream(stream); - bool toReturn = sfSoundFile_openReadFromStream(m_soundFile, m_stream); + bool toReturn = sfInputSoundFile_openFromStream(m_soundFile, m_stream); err.write(toString(sfErr_getOutput())); return toReturn; } - bool openWrite(string filename,uint channelCount,uint sampleRate) + /*bool openWrite(string filename,uint channelCount,uint sampleRate) { import dsfml.system.string; - bool toReturn = sfSoundFile_openWrite(m_soundFile, toStringz(filename),channelCount,sampleRate); + bool toReturn = sfInputSoundFile_openForWriting(m_soundFile, toStringz(filename),channelCount,sampleRate); err.write(toString(sfErr_getOutput())); return toReturn; - } + }*/ long read(ref short[] data) { - return sfSoundFile_read(m_soundFile,data.ptr, data.length); + return sfInputSoundFile_read(m_soundFile,data.ptr, data.length); } - void write(const(short)[] data) + /*void write(const(short)[] data) { - sfSoundFile_write(m_soundFile, data.ptr, data.length); - } + sfInputSoundFile_write(m_soundFile, data.ptr, data.length); + }*/ void seek(long timeOffset) { import dsfml.system.string; - sfSoundFile_seek(m_soundFile, timeOffset); + sfInputSoundFile_seek(m_soundFile, timeOffset); //Temporary fix for a bug where attempting to write to err //throws an exception in a thread created in C++. This causes @@ -107,15 +107,15 @@ struct SoundFile long getSampleCount() { - return sfSoundFile_getSampleCount(m_soundFile); + return sfInputSoundFile_getSampleCount(m_soundFile); } uint getSampleRate() { - return sfSoundFile_getSampleRate(m_soundFile); + return sfInputSoundFile_getSampleRate(m_soundFile); } uint getChannelCount() { - return sfSoundFile_getChannelCount(m_soundFile); + return sfInputSoundFile_getChannelCount(m_soundFile); } @@ -175,32 +175,32 @@ extern(C) const(char)* sfErr_getOutput(); extern(C) { -struct sfSoundFile; +struct sfInputSoundFile; -sfSoundFile* sfSoundFile_create(); +sfInputSoundFile* sfInputSoundFile_create(); -void sfSoundFile_destroy(sfSoundFile* file); +void sfInputSoundFile_destroy(sfInputSoundFile* file); -long sfSoundFile_getSampleCount(const sfSoundFile* file); +long sfInputSoundFile_getSampleCount(const sfInputSoundFile* file); -uint sfSoundFile_getChannelCount( const sfSoundFile* file); +uint sfInputSoundFile_getChannelCount( const sfInputSoundFile* file); -uint sfSoundFile_getSampleRate(const sfSoundFile* file); +uint sfInputSoundFile_getSampleRate(const sfInputSoundFile* file); -bool sfSoundFile_openReadFromFile(sfSoundFile* file, const char* filename); +bool sfInputSoundFile_openFromFile(sfInputSoundFile* file, const char* filename); -bool sfSoundFile_openReadFromMemory(sfSoundFile* file,const(void)* data, long sizeInBytes); +bool sfInputSoundFile_openFromMemory(sfInputSoundFile* file,const(void)* data, long sizeInBytes); -bool sfSoundFile_openReadFromStream(sfSoundFile* file, soundInputStream stream); +bool sfInputSoundFile_openFromStream(sfInputSoundFile* file, soundInputStream stream); -//bool sfSoundFile_openReadFromStream(sfSoundFile* file, void* stream); +//bool sfInputSoundFile_openReadFromStream(sfInputSoundFile* file, void* stream); -bool sfSoundFile_openWrite(sfSoundFile* file, const(char)* filename,uint channelCount,uint sampleRate); +bool sfInputSoundFile_openForWriting(sfInputSoundFile* file, const(char)* filename,uint channelCount,uint sampleRate); -long sfSoundFile_read(sfSoundFile* file, short* data, long sampleCount); +long sfInputSoundFile_read(sfInputSoundFile* file, short* data, long sampleCount); -void sfSoundFile_write(sfSoundFile* file, const short* data, long sampleCount); +//void sfInputSoundFile_write(sfInputSoundFile* file, const short* data, long sampleCount); -void sfSoundFile_seek(sfSoundFile* file, long timeOffset); +void sfInputSoundFile_seek(sfInputSoundFile* file, long timeOffset); } } diff --git a/src/dsfml/audio/listener.d b/src/dsfml/audio/listener.d index 42ee7fd..9000986 100644 --- a/src/dsfml/audio/listener.d +++ b/src/dsfml/audio/listener.d @@ -59,6 +59,28 @@ final abstract class Listener } } + /** + * The upward vector of the listener in the scene. The upward vector defines the 3D axes of the listener (left, up, front) in the scene. The upward vector doesn't have to be normalized. + * + * The default listener's upward vector is (0, 1, 0). + */ + @property + { + static void UpVector(Vector3f orientation) + { + sfListener_setUpVector(orientation.x, orientation.y, orientation.z); + } + + static Vector3f UpVector() + { + Vector3f temp; + + sfListener_getUpVector(&temp.x, &temp.y, &temp.z); + + return temp; + } + } + /** * The global volume of all the sounds and musics. The volume is a number between 0 and 100; it is combined with the individual volume of each sound / music. * @@ -141,3 +163,6 @@ void sfListener_setDirection(float x, float y, float z); void sfListener_getDirection(float* x, float* y, float* z); +void sfListener_setUpVector(float x, float y, float z); + +void sfListener_getUpVector(float* x, float* y, float* z); diff --git a/src/dsfml/audio/music.d b/src/dsfml/audio/music.d index a4119f8..e0e3609 100644 --- a/src/dsfml/audio/music.d +++ b/src/dsfml/audio/music.d @@ -43,11 +43,11 @@ import dsfml.audio.soundstream; +/ class Music : SoundStream { - import dsfml.audio.soundfile; + import dsfml.audio.inputsoundfile; private { - SoundFile m_file; + InputSoundFile m_file; Duration m_duration; short[] m_samples; Mutex m_mutex; diff --git a/src/dsfml/audio/soundbuffer.d b/src/dsfml/audio/soundbuffer.d index 33de772..5054b6f 100644 --- a/src/dsfml/audio/soundbuffer.d +++ b/src/dsfml/audio/soundbuffer.d @@ -21,7 +21,7 @@ module dsfml.audio.soundbuffer; import core.time; -import dsfml.audio.soundfile; +import dsfml.audio.inputsoundfile; import dsfml.audio.sound; import dsfml.system.inputstream; diff --git a/src/dsfml/graphics/blendmode.d b/src/dsfml/graphics/blendmode.d index 285cbc3..52d82c8 100644 --- a/src/dsfml/graphics/blendmode.d +++ b/src/dsfml/graphics/blendmode.d @@ -21,10 +21,10 @@ module dsfml.graphics.blendmode; /++ + Available blending modes for drawing. + - + See_Also: http://www.sfml-dev.org/documentation/2.0/group__graphics.php#ga80c52fe2f7050d7f7573b7ed3c995388 + + See_Also: http://www.sfml-dev.org/documentation/2.3/structsf_1_1BlendMode.php + Authors: Laurent Gomila, Jeremy DeHaan +/ -enum BlendMode +/*enum BlendMode { /// Pixel = Source * Source.a + Dest * (1 - Source.a) Alpha, @@ -34,4 +34,41 @@ enum BlendMode Multiply, /// Pixel = Source. None +}*/ + +struct BlendMode +{ + enum Alpha = BlendMode(Factor.SrcAlpha, Factor.OneMinusSrcAlpha, Equation.Add, + Factor.One, Factor.OneMinusSrcAlpha, Equation.Add); + enum Add = BlendMode(Factor.SrcAlpha, Factor.One, Equation.Add, + Factor.One, Factor.One, Equation.Add); + enum Multiply = BlendMode(Factor.DstColor, Factor.Zero); + enum None = BlendMode (Factor.One, Factor.Zero); + + enum Factor + { + Zero, + One, + SrcColor, + OneMinunSrcColor, + DstColor, + OneMinusDstColor, + SrcAlpha, + OneMinusSrcAlpha, + DstAlpha, + OneMinusDstAlpha + } + + enum Equation + { + Add, + Subtract + } + + Factor colorSrcFactor = Factor.SrcAlpha; + Factor colorDstFactor = Factor.OneMinusSrcAlpha; + Equation colorEquation = Equation.Add; + Factor alphaSrcFactor = Factor.One; + Factor alphaDstFactor = Factor.OneMinusSrcAlpha; + Equation alphaEquation = Equation.Add; } \ No newline at end of file diff --git a/src/dsfml/graphics/font.d b/src/dsfml/graphics/font.d index c462d7a..2172e01 100644 --- a/src/dsfml/graphics/font.d +++ b/src/dsfml/graphics/font.d @@ -169,7 +169,7 @@ class Font * * Returns: Kerning value for first and second, in pixels */ - int getKerning (dchar first, dchar second, uint characterSize) const + float getKerning (dchar first, dchar second, uint characterSize) const { return sfFont_getKerning(sfPtr, cast(uint)first, cast(uint)second, characterSize); } @@ -184,10 +184,40 @@ class Font * * Returns: Line spacing, in pixels */ - int getLineSpacing (uint characterSize) const + float getLineSpacing (uint characterSize) const { return sfFont_getLineSpacing(sfPtr, characterSize); } + + /** + * Get the position of the underline. + * + * Underline position is the vertical offset to apply between the baseline and the underline. + * + * Params: + * characterSize = Reference character size + * + * Returns: Underline position, in pixels + */ + float getUnderlinePosition (uint characterSize) const + { + return sfFont_getUnderlinePosition(sfPtr, characterSize); + } + + /** + * Get the thickness of the underline. + * + * Underline thickness is the vertical size of the underline. + * + * Params: + * characterSize = Reference character size + * + * Returns: Underline thickness, in pixels + */ + float getUnderlineThickness (uint characterSize) const + { + return sfFont_getUnderlineThickness(sfPtr, characterSize); + } /** * Retrieve the texture containing the loaded glyphs of a certain size. @@ -329,11 +359,17 @@ void sfFont_getGlyph(const(sfFont)* font, uint codePoint, int characterSize, boo //Get the kerning value corresponding to a given pair of characters in a font -int sfFont_getKerning(const(sfFont)* font, uint first, uint second, uint characterSize); +float sfFont_getKerning(const(sfFont)* font, uint first, uint second, uint characterSize); //Get the line spacing value -int sfFont_getLineSpacing(const(sfFont)* font, uint characterSize); +float sfFont_getLineSpacing(const(sfFont)* font, uint characterSize); + +//Get the position of the underline +float sfFont_getUnderlinePosition (const(sfFont)* font, uint characterSize); + +//Get the thickness of the underline +float sfFont_getUnderlineThickness (const(sfFont)* font, uint characterSize); //Get the texture pointer for a particular font diff --git a/src/dsfml/graphics/rendertexture.d b/src/dsfml/graphics/rendertexture.d index 2634764..c174e13 100644 --- a/src/dsfml/graphics/rendertexture.d +++ b/src/dsfml/graphics/rendertexture.d @@ -277,7 +277,9 @@ class RenderTexture : RenderTarget states.shader = RenderStates.emptyShader; } - sfRenderTexture_drawPrimitives(sfPtr, vertices.ptr, cast(uint)min(uint.max, vertices.length),type,states.blendMode, states.transform.m_matrix.ptr, states.texture.sfPtr, states.shader.sfPtr); + sfRenderTexture_drawPrimitives(sfPtr, vertices.ptr, cast(uint)min(uint.max, vertices.length),type,states.blendMode.colorSrcFactor, states.blendMode.alphaDstFactor, + states.blendMode.colorEquation, states.blendMode.alphaSrcFactor, states.blendMode.alphaDstFactor, states.blendMode.alphaEquation, + states.transform.m_matrix.ptr, states.texture.sfPtr, states.shader.sfPtr); } /** @@ -478,7 +480,8 @@ void sfRenderTexture_mapCoordsToPixel(const sfRenderTexture* renderTexture, floa //Draw primitives defined by an array of vertices to a render texture -void sfRenderTexture_drawPrimitives(sfRenderTexture* renderTexture, const void* vertices, uint vertexCount, int type, int blendMode,const float* transform, const sfTexture* texture, const sfShader* shader); +void sfRenderTexture_drawPrimitives(sfRenderTexture* renderTexture, const void* vertices, uint vertexCount, int type, int colorSrcFactor, int colorDstFactor, int colorEquation, + int alphaSrcFactor, int alphaDstFactor, int alphaEquation, const float* transform, const sfTexture* texture, const sfShader* shader); //Save the current OpenGL render states and matrices void sfRenderTexture_pushGLStates(sfRenderTexture* renderTexture); diff --git a/src/dsfml/graphics/renderwindow.d b/src/dsfml/graphics/renderwindow.d index dec6385..34cc9fd 100644 --- a/src/dsfml/graphics/renderwindow.d +++ b/src/dsfml/graphics/renderwindow.d @@ -537,7 +537,9 @@ class RenderWindow : Window, RenderTarget states.shader = RenderStates.emptyShader; } - sfRenderWindow_drawPrimitives(sfPtr, vertices.ptr, cast(uint)min(uint.max, vertices.length), type,states.blendMode, states.transform.m_matrix.ptr,states.texture.sfPtr,states.shader.sfPtr); + sfRenderWindow_drawPrimitives(sfPtr, vertices.ptr, cast(uint)min(uint.max, vertices.length), type,states.blendMode.colorSrcFactor, states.blendMode.alphaDstFactor, + states.blendMode.colorEquation, states.blendMode.alphaSrcFactor, states.blendMode.alphaDstFactor, states.blendMode.alphaEquation, + states.transform.m_matrix.ptr,states.texture.sfPtr,states.shader.sfPtr); } /** @@ -939,7 +941,8 @@ void sfRenderWindow_mapCoordsToPixel(const sfRenderWindow* renderWindow, float x //Draw primitives defined by an array of vertices to a render window -void sfRenderWindow_drawPrimitives(sfRenderWindow* renderWindow,const (void)* vertices, uint vertexCount, int type, int blendMode,const(float)* transform, const(sfTexture)* texture, const(sfShader)* shader); +void sfRenderWindow_drawPrimitives(sfRenderWindow* renderWindow,const (void)* vertices, uint vertexCount, int type, int colorSrcFactor, int colorDstFactor, int colorEquation, + int alphaSrcFactor, int alphaDstFactor, int alphaEquation, const (float)* transform, const (sfTexture)* texture, const (sfShader)* shader); //Save the current OpenGL render states and matrices void sfRenderWindow_pushGLStates(sfRenderWindow* renderWindow); diff --git a/src/dsfml/network/ftp.d b/src/dsfml/network/ftp.d index 2db5afe..6eca495 100644 --- a/src/dsfml/network/ftp.d +++ b/src/dsfml/network/ftp.d @@ -266,6 +266,20 @@ class Ftp import dsfml.system.string; return new Response(sfFtp_upload(sfPtr,toStringz(localFile),toStringz(remotePath),mode)); } + + ///Send a command to the FTP server. + /// + ///While the most often used commands are provided as member functions in the Ftp class, this method can be used to send any FTP command to the server. If the command requires one or more parameters, they can be specified in parameter. If the server returns information, you can extract it from the response using getMessage(). + /// + ///Params: + /// command = Command to send. + /// parameter = Command parameter. + /// + ///Returns: Server response to the request. + Response sendCommand(string command, string parameter) { + import dsfml.system.string; + return new Response(sfFtp_sendCommand(sfPtr, toStringz(command), toStringz(parameter))); + } ///Specialization of FTP response returning a directory. class DirectoryResponse:Response @@ -627,3 +641,6 @@ sfFtpResponse* sfFtp_download(sfFtp* ftp, const(char)* distantFile, const(char)* ///Upload a file to a FTP server sfFtpResponse* sfFtp_upload(sfFtp* ftp, const(char)* localFile, const(char)* destPath, int mode); + +///Send a command to a FTP server +sfFtpResponse* sfFtp_sendCommand(sfFtp* ftp, const(char)* command, const(char)* parameter); \ No newline at end of file diff --git a/src/dsfml/network/http.d b/src/dsfml/network/http.d index 1aa43c1..cfb1e38 100644 --- a/src/dsfml/network/http.d +++ b/src/dsfml/network/http.d @@ -97,7 +97,11 @@ class Http ///Request in post mode, usually to send data to a page. Post, ///Request a page's header only. - Head + Head, + ///Request in put mode, useful for a REST API + Put, + ///Request in delete mode, useful for a REST API + Delete } package sfHttpRequest* sfPtrRequest; diff --git a/src/dsfml/window/event.d b/src/dsfml/window/event.d index 94fcf28..08e5dce 100644 --- a/src/dsfml/window/event.d +++ b/src/dsfml/window/event.d @@ -22,6 +22,7 @@ module dsfml.window.event; import dsfml.window.keyboard; import dsfml.window.mouse; +import dsfml.window.sensor; /** *Defines a system event and its parameters. @@ -125,6 +126,21 @@ struct Event ///Y position of the mouse pointer, relative to the top of the owner window int y; } + + /** + *Mouse wheel scroll events parameters (MouseWheelScrolled) + */ + struct MouseWheelScrollEvent + { + ///Which wheel (for mice with multiple ones) + Mouse.Wheel wheel; + /// Wheel offset. High precision mice may use non-integral offsets. + float delta; + /// X position of the mouse pointer, relative to the left of the owner window + int x; + /// Y position of the mouse pointer, relative to the left of the owner window + int y; + } /** *Size events parameters (Resized) @@ -145,6 +161,29 @@ struct Event /// UTF-32 unicode value of the character dchar unicode; } + /** + *Sensor event parameters + */ + + struct SensorEvent + { + ///Type of the sensor + Sensor.Type type; + float x; + float y; + float z; + } + /** + *Touch Event parameters + */ + + struct TouchEvent + { + ///Index of the finger in case of multi-touch events. + uint finger; + int x; + int y; + } enum EventType { @@ -164,6 +203,8 @@ struct Event KeyReleased, ///The mouse wheel was scrolled (data in event.mouseWheel) MouseWheelMoved, + ///The mouse wheel was scrolled (data in event.mouseWheelScroll) + MouseWheelScrolled, ///A mouse button was pressed (data in event.mouseButton) MouseButtonPressed, ///A mouse button was released (data in event.mouseButton) @@ -184,6 +225,14 @@ struct Event JoystickConnected, ///A joystick was disconnected (data in event.joystickConnect) JoystickDisconnected, + ///A touch event began (data in event.touch) + TouchBegan, + ///A touch moved (data in event.touch) + TouchMoved, + ///A touch ended (data in event.touch) + TouchEnded, + ///A sensor value changed (data in event.sensor) + SensorChanged, ///Keep last -- the total number of event types Count @@ -206,12 +255,18 @@ struct Event MouseButtonEvent mouseButton; ///Mouse wheel event parameters (Event::MouseWheelMoved) MouseWheelEvent mouseWheel; + ///Mouse wheel scroll event parameters + MouseWheelScrollEvent mouseWheelScroll; ///Joystick move event parameters (Event::JoystickMoved) JoystickMoveEvent joystickMove; ///Joystick button event parameters (Event::JoystickButtonPressed, Event::JoystickButtonReleased) JoystickButtonEvent joystickButton; ///Joystick (dis)connect event parameters (Event::JoystickConnected, Event::JoystickDisconnected) JoystickConnectEvent joystickConnect; + ///Touch event parameters + TouchEvent touch; + ///Sensor event Parameters + SensorEvent sensor; } } diff --git a/src/dsfml/window/joystick.d b/src/dsfml/window/joystick.d index bf0aa31..43a82c6 100644 --- a/src/dsfml/window/joystick.d +++ b/src/dsfml/window/joystick.d @@ -36,6 +36,16 @@ module dsfml.window.joystick; */ final abstract class Joystick { + ///Structure holding a joystick's identification; + struct Identification { + ///Name of the joystick + dstring name; + ///Manufacturer identifier + uint vendorId; + ///Product identifier + uint productId; + } + //Constants related to joysticks capabilities. enum { @@ -95,6 +105,24 @@ final abstract class Joystick return sfJoystick_getAxisPosition(joystick, axis); } + ///Get the joystick information + /// + ///Params: + /// joystick = Index of the joystick. + /// + ///Returns: Structure containing the joystick information. + static Identification getIdentification(uint joystick) { + Identification identification; + const(dchar)* name; + size_t nameSize; + + sfJoystick_getIdentification(joystick, &name, &nameSize, &identification.vendorId, &identification.productId); + + identification.name = name[0..nameSize].idup; + + return identification; + } + ///Check if a joystick supports a given axis. /// ///If the joystick is not connected, this function returns false. @@ -160,8 +188,10 @@ unittest { if(Joystick.isConnected(i)) { + auto id = Joystick.getIdentification(i); joysticks[i] = true; writeln("Joystick number ",i," is connected!"); + writefln("Type: %s, ID: %x:%x", id.name, id.vendorId, id.productId); } } @@ -205,6 +235,9 @@ bool sfJoystick_isConnected(uint joystick); //Return the number of buttons supported by a joystick uint sfJoystick_getButtonCount(uint joystick); +//Return the identification structure for a joystick +void sfJoystick_getIdentification(uint joystick, const(dchar)** name, size_t* nameLength, uint* vendorID, uint* productId); + //Check if a joystick supports a given axis bool sfJoystick_hasAxis(uint joystick, int axis); diff --git a/src/dsfml/window/mouse.d b/src/dsfml/window/mouse.d index b612066..25c8fd5 100644 --- a/src/dsfml/window/mouse.d +++ b/src/dsfml/window/mouse.d @@ -59,6 +59,14 @@ final abstract class Mouse Count } + + enum Wheel + { + ///Vertically oriented mouse wheel + VerticalWheel, + ///Horizontally oriented mouse wheel + HorizontalWheel + } ///Set the current position of the mouse in desktop coordinates. /// diff --git a/src/dsfml/window/package.d b/src/dsfml/window/package.d index d03dfac..926eabb 100644 --- a/src/dsfml/window/package.d +++ b/src/dsfml/window/package.d @@ -30,6 +30,8 @@ public import dsfml.window.joystick; import dsfml.window.keyboard; import dsfml.window.mouse; + import dsfml.window.touch; + import dsfml.window.sensor; import dsfml.window.videomode; import dsfml.window.window; import dsfml.window.windowhandle; diff --git a/src/dsfml/window/sensor.d b/src/dsfml/window/sensor.d new file mode 100644 index 0000000..b6a4068 --- /dev/null +++ b/src/dsfml/window/sensor.d @@ -0,0 +1,127 @@ +/* +DSFML - The Simple and Fast Multimedia Library for D + +Copyright (c) 2013 - 2015 Jeremy DeHaan (dehaan.jeremiah@gmail.com) + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, +and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. +If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution +*/ +///Give access to the real-time state of the sensors. +module dsfml.window.sensor; + +import dsfml.system.vector3; + + +/** +Give access to the real-time state of the sensors. + +sf::Sensor provides an interface to the state of the various sensors that a device provides. + +It only contains static functions, so it's not meant to be instantiated. + +This class allows users to query the sensors values at any time and directly, without having to deal with a window and its events. +Compared to the SensorChanged event, Sensor can retrieve the state of a sensor at any time (you don't need to store and update its +current value on your side). + +Depending on the OS and hardware of the device (phone, tablet, ...), some sensor types may not be available. You should always check the +availability of a sensor before trying to read it, with the sf::Sensor::isAvailable function. + +You may wonder why some sensor types look so similar, for example Accelerometer and Gravity / UserAcceleration. +The first one is the raw measurement of the acceleration, and takes into account both the earth gravity and the user movement. +The others are more precise: they provide these components separately, which is usually more useful. In fact they are not direct sensors, they +are computed internally based on the raw acceleration and other sensors. This is exactly the same for Gyroscope vs Orientation. + +Because sensors consume a non-negligible amount of current, they are all disabled by default. You must call sf::Sensor::setEnabled for each sensor +in which you are interested. +*/ +final abstract class Sensor +{ + ///Sensor type + enum Type + { + ///Measures the raw acceleration (m/s²) + Accelerometer, + ///Measures the raw rotation rates (°/s) + Gyroscope, + ///Measures the ambient magnetic field (micro-teslas) + Magnetometer, + ///Measures the direction and intensity of gravity, independent of device acceleration (m/s²) + Gravity, + ///Measures the direction and intensity of device cceleration, independent of the gravity (m/s²) + UserAcceleration, + ///Measures the absolute 3D orientation (°) + Orientation, + ///Keep last - the total number of sensor types + Count + } + + /** + *Check if a sensor is available on the underlying platform. + * + *Parameters + * sensor Sensor to check + * + *Returns + * True if the sensor is available, false otherwise + */ + static bool isAvailable (Type sensor) + { + return sfSensor_isAvailable(sensor); + } + + /** + *Enable or disable a sensor. + * + *All sensors are disabled by default, to avoid consuming too much battery power. Once a sensor is enabled, it starts sending events of the corresponding type. + * + *This function does nothing if the sensor is unavailable. + * + *Parameters + * sensor Sensor to enable + * enabled True to enable, false to disable + */ + static void setEnabled (Type sensor, bool enabled) + { + sfSensor_setEnabled(sensor, enabled); + } + + /** + *Get the current sensor value. + * + *Parameters + * sensor Sensor to read + * + *Returns + * The current sensor value + */ + static Vector3f getValue (Type sensor) + { + Vector3f getValue; + sfSensor_getValue(sensor, &getValue.x, &getValue.y, &getValue.z); + + return getValue; + } +} + +private extern(C) +{ + + //Check if a sensor is available + bool sfSensor_isAvailable (int sensor); + + //Enable or disable a given sensor + void sfSensor_setEnabled (int sensor, bool enabled); + + //Set the current value of teh sensor + void sfSensor_getValue (int sensor, float* x, float* y, float* z); +} diff --git a/src/dsfml/window/touch.d b/src/dsfml/window/touch.d new file mode 100644 index 0000000..96c530c --- /dev/null +++ b/src/dsfml/window/touch.d @@ -0,0 +1,111 @@ +/* +DSFML - The Simple and Fast Multimedia Library for D + +Copyright (c) 2013 - 2015 Jeremy DeHaan (dehaan.jeremiah@gmail.com) + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, +and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. +If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution +*/ + +///Provides touch input handling + +module dsfml.window.touch; + +import dsfml.system.vector2; +import dsfml.window.window; + +/** + Give access to the real-time state of the touches. + + Touch provides an interface to the state of the touches. + + It only contains static functions, so it's not meant to be instantiated. + + This class allows users to query the touches state at any time and directly, without having to deal with a window and its events. Compared to the TouchBegan, + TouchMoved and TouchEnded events, sf::Touch can retrieve the state of the touches at any time (you don't need to store and update a boolean on your side in order to + know if a touch is down), and you always get the real state of the touches, even if they happen when your window is out of focus and no event is triggered. + + The getPosition function can be used to retrieve the current position of a touch. There are two versions: one that operates in global coordinates + (relative to the desktop) and one that operates in window coordinates (relative to a specific window). + + Touches are identified by an index (the "finger"), so that in multi-touch events, individual touches can be tracked correctly. As long as + a finger touches the screen, it will keep the same index even if other fingers start or stop touching the screen in the meantime. As a consequence, active + touch indices may not always be sequential (i.e. touch number 0 may be released while touch number 1 is still down). +*/ + +final abstract class Touch +{ + /** + *Check if a touch event is currently down. + * + *Parameters + * finger Finger index + * + *Returns + * True if finger is currently touching the screen, false otherwise + */ + static bool isDown (uint finger) + { + return sfTouch_isDown (finger); + } + + /** + *Get the current position of a touch in desktop coordinates. + * + *This function returns the current touch position in global (desktop) coordinates. + * + *Parameters + * finger Finger index + * + *Returns + * Current position of finger, or undefined if it's not down + */ + static Vector2i getPosition (uint finger) + { + Vector2i getPosition; + + sfTouch_getPosition(finger, null, &getPosition.x, &getPosition.y); + + return getPosition; + } + + /** + *Get the current position of a touch in window coordinates. + * + *This function returns the current touch position in relative (window) coordinates. + * + *Parameters + * finger Finger index + * + *Returns + * Current position of finger, or undefined if it's not down + */ + static Vector2i getPosition (uint finger, const(Window) relativeTo) + { + Vector2i getPosition; + + sfTouch_getPosition(finger, relativeTo.sfPtr, &getPosition.x, &getPosition.y); + + return getPosition; + } +} + +private extern(C) +{ + + //Check if a touch event is currently down + bool sfTouch_isDown (uint finger); + + //Get the current position of a given touch + void sfTouch_getPosition(uint finger, const(sfWindow)* relativeTo, int* x, int* y); +} diff --git a/src/dsfml/window/window.d b/src/dsfml/window/window.d index 77cbb73..ddf9daf 100644 --- a/src/dsfml/window/window.d +++ b/src/dsfml/window/window.d @@ -178,7 +178,21 @@ class Window err.write(toString(sfErr_getOutput())); return toReturn; } - + + ///Request the current window to be made the active foreground window. + void requestFocus() + { + sfWindow_requestFocus(sfPtr); + } + + ///Check whether the window has the input focus + /// + ///Returns: True if the window has focus, false otherwise + bool hasFocus() const + { + return sfWindow_hasFocus(sfPtr); + } + ///Limit the framerate to a maximum fixed frequency. /// ///If a limit is set, the window will use a small delay after each call to display() to ensure that the current frame lasted long enough to match the framerate limit. SFML will try to match the given limit as much as it can, but since it internally uses sf::sleep, whose precision depends on the underlying OS, the results may be a little unprecise as well (for example, you can get 65 FPS when requesting 60). @@ -598,6 +612,12 @@ private extern(C): //Activate or deactivate a window as the current target for OpenGL rendering bool sfWindow_setActive(sfWindow* window, bool active); + + //Request the current window to be made the active foreground window. + void sfWindow_requestFocus(sfWindow* window); + + //Check whether the window has the input focus + bool sfWindow_hasFocus(const(sfWindow)* window); //Display on screen what has been rendered to the window so far void sfWindow_display(sfWindow* window); From 3ee043f4e3aa21ddafd63f3efdef2c7775efe37b Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Sat, 2 Apr 2016 12:25:34 -0700 Subject: [PATCH 04/27] Fix missing and incorrect modules in build.d --- build.d | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.d b/build.d index eae49c9..288971e 100644 --- a/build.d +++ b/build.d @@ -286,9 +286,9 @@ void initialize() //Setting up our aa with our lists of files because GDC crashes when searching for them at runtime fileList["system"] = ["clock.d", "config.d", "err.d", "inputstream.d", "lock.d", "mutex.d", "package.d", "sleep.d", "string.d", "thread.d", "vector2.d", "vector3.d"]; - fileList["audio"] = ["listener.d", "music.d", "package.d", "sound.d", "soundbuffer.d", "soundbufferrecorder.d", "soundfile.d", "soundrecorder.d", "soundsource.d", "soundstream.d"]; + fileList["audio"] = ["listener.d", "music.d", "package.d", "sound.d", "soundbuffer.d", "soundbufferrecorder.d", "inputsoundfile.d", "soundrecorder.d", "soundsource.d", "soundstream.d"]; fileList["network"] = ["ftp.d", "http.d", "ipaddress.d", "package.d", "packet.d", "socket.d", "socketselector.d", "tcplistener.d", "tcpsocket.d", "udpsocket.d"]; - fileList["window"] = ["context.d", "contextsettings.d", "event.d", "joystick.d", "keyboard.d", "mouse.d", "package.d", "videomode.d", "window.d", "windowhandle.d"]; + fileList["window"] = ["context.d", "contextsettings.d", "event.d", "joystick.d", "keyboard.d", "mouse.d", "sensor.d", "touch.d", "package.d", "videomode.d", "window.d", "windowhandle.d"]; fileList["graphics"] = ["blendmode.d", "circleshape.d", "color.d", "convexshape.d", "drawable.d", "font.d", "glyph.d", "image.d", "package.d", "primitivetype.d", "rect.d", "rectangleshape.d", "renderstates.d", "rendertarget.d", "rendertexture.d", "renderwindow.d", "shader.d", "shape.d", "sprite.d", "text.d", "texture.d", "transform.d", "transformable.d", "vertex.d", "vertexarray.d", "view.d"]; From ec916b9dc759e3e47243643b5270bde7ea332266 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Sat, 2 Apr 2016 12:38:14 -0700 Subject: [PATCH 05/27] Set continuous-integration to use DSFMLC 2.3 We'll have to revert this commit after DSFMLC PR6 gets pulled. --- .travis.yml | 3 ++- appveyor.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 44d8f93..95be919 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,8 +44,9 @@ matrix: #Build and install DSFMLC install: - cd $HOME - - git clone --depth=1 https://github.com/Jebbs/DSFMLC.git + - git clone --depth=1 https://github.com/aubade/DSFMLC.git - cd DSFMLC + - git checkout 2.3 - cmake . - make -j2 - export LIBRARY_PATH=${HOME}/DSFMLC/lib diff --git a/appveyor.yml b/appveyor.yml index f3177c6..51380e6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -187,8 +187,9 @@ build_script: - echo %VCINSTALLDIR% - '"%compilersetup%" %compilersetupargs%' - cd .. -- git clone --depth=1 https://github.com/Jebbs/DSFMLC.git +- git clone --depth=1 https://github.com/aubade/DSFMLC.git - cd DSFMLC +- git checkout 2.3 - ps: if($env:toolchain -eq "mingw"){ $env:Path = $env:compilerpath + $env:cmakepath; } From 4b95245e33990565ac64db2eeb6c8a76c443748b Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Sat, 2 Apr 2016 12:41:45 -0700 Subject: [PATCH 06/27] I fail at git-fu. --- .travis.yml | 3 +-- appveyor.yml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 95be919..9e04403 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,9 +44,8 @@ matrix: #Build and install DSFMLC install: - cd $HOME - - git clone --depth=1 https://github.com/aubade/DSFMLC.git + - git clone --depth=1 --branch 2.3 https://github.com/aubade/DSFMLC.git - cd DSFMLC - - git checkout 2.3 - cmake . - make -j2 - export LIBRARY_PATH=${HOME}/DSFMLC/lib diff --git a/appveyor.yml b/appveyor.yml index 51380e6..700a0c3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -187,9 +187,8 @@ build_script: - echo %VCINSTALLDIR% - '"%compilersetup%" %compilersetupargs%' - cd .. -- git clone --depth=1 https://github.com/aubade/DSFMLC.git +- git clone --depth=1 --branch 2.3 https://github.com/aubade/DSFMLC.git - cd DSFMLC -- git checkout 2.3 - ps: if($env:toolchain -eq "mingw"){ $env:Path = $env:compilerpath + $env:cmakepath; } From cd2d4de8c900f2031821d47f5e16481034bbde59 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Sat, 2 Apr 2016 12:45:36 -0700 Subject: [PATCH 07/27] And add the missing libxcb dependencies for SFML 2.3 --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 9e04403..5910499 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,8 @@ addons: - libsndfile1-dev - libx11-dev - libxrandr-dev + - libxcb-image0-dev + - libxcb-randr0-dev d: - dmd-2.069.2 From 06cf1fbbfe1ea8ff43902e275fcd56b349664aed Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Sat, 2 Apr 2016 12:47:48 -0700 Subject: [PATCH 08/27] needs x11-xcb too. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 5910499..40f0913 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ addons: - libpthread-stubs0-dev - libsndfile1-dev - libx11-dev + - libx11-xcb-dev - libxrandr-dev - libxcb-image0-dev - libxcb-randr0-dev From 05b9762ada3de65815b316fb5187b933d3c631a2 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Sat, 2 Apr 2016 12:55:09 -0700 Subject: [PATCH 09/27] One last time, wisened up and checked DSFMLC's travis.yml --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 40f0913..21bfefa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,9 @@ addons: - libxrandr-dev - libxcb-image0-dev - libxcb-randr0-dev + - libudev-dev + - libvorbis-dev + - libflac-dev d: - dmd-2.069.2 From 5ead9a97ce29dbde1bd68bc760c630fd56d3c487 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Sat, 2 Apr 2016 15:30:14 -0700 Subject: [PATCH 10/27] Device selection and Processing Interval control for SoundRecorder --- src/dsfml/audio/soundrecorder.d | 103 +++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/src/dsfml/audio/soundrecorder.d b/src/dsfml/audio/soundrecorder.d index ee17460..a3a9460 100644 --- a/src/dsfml/audio/soundrecorder.d +++ b/src/dsfml/audio/soundrecorder.d @@ -20,6 +20,8 @@ If you use this software in a product, an acknowledgment in the product document module dsfml.audio.soundrecorder; import core.thread; +import core.time; +import dsfml.system.string; import dsfml.system.err; @@ -89,7 +91,7 @@ class SoundRecorder import dsfml.system.string; sfSoundRecorder_start(sfPtr, theSampleRate); - err.write(toString(sfErr_getOutput())); + err.write(.toString(sfErr_getOutput())); } /// Stop the capture. @@ -110,6 +112,79 @@ class SoundRecorder return sfSoundRecorder_getSampleRate(sfPtr); } } + + /** + *Get the name of the current audio capture device. + * + *Returns + * The name of the current audio capture device + */ + string getDevice() const { + return .toString(sfSoundRecorder_getDevice(sfPtr)); + } + /** + *Set the audio capture device. + * + *This function sets the audio capture device to the device with the given name. It can be called on the fly (i.e: while recording). If you do so while recording and opening the device fails, it stops the recording. + * + *Parameters + * name The name of the audio capture device + * + *Returns + * True, if it was able to set the requested device + * + *See also + * getAvailableDevices, getDefaultDevice + */ + bool setDevice (string name) { + return sfSoundRecorder_setDevice(sfPtr, toStringz(name)); + } + + /** + *Get a list of the names of all available audio capture devices. + * + *This function returns an array of strings, containing the names of all available audio capture devices. + * + *Returns + * An array of strings containing the names + */ + static const(string)[] getAvailableDevices() { + static string[] availableDevices;//stores all available devices after the first call + + //if getAvailableDevices hasn't been called yet + if(availableDevices.length == 0) + { + const (char)** devices; + size_t counts; + + //returns uints instead of structs due to 64 bit bug + devices = sfSoundRecorder_getAvailableDevices(&counts); + + //calculate real length + availableDevices.length = counts; + + //populate availableDevices + for(uint i = 0; i < counts; i++) + { + availableDevices[i] = .toString(devices[i]); + } + + } + + return availableDevices; + } + + /** + *Get the name of the default audio capture device. + * + *This function returns the name of the default audio capture device. If none is available, an empty string is returned. + * + *Returns + * The name of the default audio capture device + */ + static string getDefaultDevice() { + return .toString(sfSoundRecorder_getDefaultDevice()); + } /** * Check if the system supports audio capture. @@ -125,6 +200,22 @@ class SoundRecorder protected { + /** + *Set the processing interval. + * + * 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. + * + * Parameters + * interval Processing interval + */ + void setProcessingInterval (Duration interval) { + sfSoundRecorder_setProcessingInterval(sfPtr, interval.total!"usecs"); + } + /** * Start capturing audio data. * @@ -213,7 +304,17 @@ void sfSoundRecorder_stop(sfSoundRecorder* soundRecorder); uint sfSoundRecorder_getSampleRate(const sfSoundRecorder* soundRecorder); +bool sfSoundRecorder_setDevice(sfSoundRecorder* soundRecorder, const(char)* name); + +const(char)* sfSoundRecorder_getDevice(const (sfSoundRecorder)* soundRecorder); + +const(char)** sfSoundRecorder_getAvailableDevices(size_t* count); + +const(char)* sfSoundRecorder_getDefaultDevice(); + bool sfSoundRecorder_isAvailable(); +void sfSoundRecorder_setProcessingInterval(sfSoundRecorder* soundRecorder, ulong time); + const(char)* sfErr_getOutput(); From 412cb3a2ca2bc9add7e2aa44763a44f6061ac986 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Sat, 2 Apr 2016 16:22:39 -0700 Subject: [PATCH 11/27] wrap OutputSoundFile Fix Glyph and Text for floating point extents Correct some InputSoundFile method names --- build.d | 2 +- src/dsfml/audio/inputsoundfile.d | 23 ++------- src/dsfml/audio/music.d | 6 +-- src/dsfml/audio/outputsoundfile.d | 78 +++++++++++++++++++++++++++++++ src/dsfml/graphics/font.d | 2 +- src/dsfml/graphics/glyph.d | 4 +- src/dsfml/graphics/text.d | 8 ++-- 7 files changed, 92 insertions(+), 31 deletions(-) create mode 100644 src/dsfml/audio/outputsoundfile.d diff --git a/build.d b/build.d index 288971e..d37c18e 100644 --- a/build.d +++ b/build.d @@ -286,7 +286,7 @@ void initialize() //Setting up our aa with our lists of files because GDC crashes when searching for them at runtime fileList["system"] = ["clock.d", "config.d", "err.d", "inputstream.d", "lock.d", "mutex.d", "package.d", "sleep.d", "string.d", "thread.d", "vector2.d", "vector3.d"]; - fileList["audio"] = ["listener.d", "music.d", "package.d", "sound.d", "soundbuffer.d", "soundbufferrecorder.d", "inputsoundfile.d", "soundrecorder.d", "soundsource.d", "soundstream.d"]; + fileList["audio"] = ["listener.d", "music.d", "package.d", "sound.d", "soundbuffer.d", "soundbufferrecorder.d", "inputsoundfile.d", "outputsoundfile.d", "soundrecorder.d", "soundsource.d", "soundstream.d"]; fileList["network"] = ["ftp.d", "http.d", "ipaddress.d", "package.d", "packet.d", "socket.d", "socketselector.d", "tcplistener.d", "tcpsocket.d", "udpsocket.d"]; fileList["window"] = ["context.d", "contextsettings.d", "event.d", "joystick.d", "keyboard.d", "mouse.d", "sensor.d", "touch.d", "package.d", "videomode.d", "window.d", "windowhandle.d"]; fileList["graphics"] = ["blendmode.d", "circleshape.d", "color.d", "convexshape.d", "drawable.d", "font.d", "glyph.d", "image.d", "package.d", "primitivetype.d", "rect.d", "rectangleshape.d", "renderstates.d", "rendertarget.d", "rendertexture.d", "renderwindow.d", "shader.d", "shape.d", "sprite.d", "text.d", "texture.d", "transform.d", "transformable.d", "vertex.d", "vertexarray.d", "view.d"]; diff --git a/src/dsfml/audio/inputsoundfile.d b/src/dsfml/audio/inputsoundfile.d index 69897ec..bfa7372 100644 --- a/src/dsfml/audio/inputsoundfile.d +++ b/src/dsfml/audio/inputsoundfile.d @@ -40,7 +40,7 @@ struct InputSoundFile sfInputSoundFile_destroy(m_soundFile); } - bool openReadFromFile(string filename) + bool openFromFile(string filename) { import dsfml.system.string; bool toReturn = sfInputSoundFile_openFromFile(m_soundFile, toStringz(filename)); @@ -48,14 +48,14 @@ struct InputSoundFile return toReturn; } - bool openReadFromMemory(const(void)[] data) + bool openFromMemory(const(void)[] data) { import dsfml.system.string; bool toReturn = sfInputSoundFile_openFromMemory(m_soundFile, data.ptr, data.length); err.write(toString(sfErr_getOutput())); return toReturn; } - bool openReadFromStream(InputStream stream) + bool openFromStream(InputStream stream) { import dsfml.system.string; m_stream = new soundFileStream(stream); @@ -65,25 +65,12 @@ struct InputSoundFile return toReturn; } - /*bool openWrite(string filename,uint channelCount,uint sampleRate) - { - import dsfml.system.string; - bool toReturn = sfInputSoundFile_openForWriting(m_soundFile, toStringz(filename),channelCount,sampleRate); - err.write(toString(sfErr_getOutput())); - return toReturn; - }*/ - long read(ref short[] data) { return sfInputSoundFile_read(m_soundFile,data.ptr, data.length); } - /*void write(const(short)[] data) - { - sfInputSoundFile_write(m_soundFile, data.ptr, data.length); - }*/ - void seek(long timeOffset) { import dsfml.system.string; @@ -193,14 +180,10 @@ bool sfInputSoundFile_openFromMemory(sfInputSoundFile* file,const(void)* data, l bool sfInputSoundFile_openFromStream(sfInputSoundFile* file, soundInputStream stream); -//bool sfInputSoundFile_openReadFromStream(sfInputSoundFile* file, void* stream); - bool sfInputSoundFile_openForWriting(sfInputSoundFile* file, const(char)* filename,uint channelCount,uint sampleRate); long sfInputSoundFile_read(sfInputSoundFile* file, short* data, long sampleCount); -//void sfInputSoundFile_write(sfInputSoundFile* file, const short* data, long sampleCount); - void sfInputSoundFile_seek(sfInputSoundFile* file, long timeOffset); } } diff --git a/src/dsfml/audio/music.d b/src/dsfml/audio/music.d index e0e3609..8e9db47 100644 --- a/src/dsfml/audio/music.d +++ b/src/dsfml/audio/music.d @@ -78,7 +78,7 @@ class Music : SoundStream //stop music if already playing stop(); - if(!m_file.openReadFromFile(filename)) + if(!m_file.openFromFile(filename)) { return false; } @@ -105,7 +105,7 @@ class Music : SoundStream { stop(); - if(!m_file.openReadFromMemory(data)) + if(!m_file.openFromMemory(data)) { return false; } @@ -131,7 +131,7 @@ class Music : SoundStream { stop(); - if(!m_file.openReadFromStream(stream)) + if(!m_file.openFromStream(stream)) { return false; } diff --git a/src/dsfml/audio/outputsoundfile.d b/src/dsfml/audio/outputsoundfile.d new file mode 100644 index 0000000..db487ed --- /dev/null +++ b/src/dsfml/audio/outputsoundfile.d @@ -0,0 +1,78 @@ +/* +DSFML - The Simple and Fast Multimedia Library for D + +Copyright (c) 2013 - 2015 Jeremy DeHaan (dehaan.jeremiah@gmail.com) + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, +and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. +If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution +*/ + +module dsfml.audio.outputsoundfile; + +import std.string; +import dsfml.system.err; + +/** + *Provide write access to sound files. + * + *This class encodes audio samples to a sound file. + * + *It is used internally by higher-level classes such as sf::SoundBuffer, but can also be useful if you want to create audio files from + *custom data sources, like generated audio samples. + */ +struct OutputSoundFile +{ + private sfOutputSoundFile* m_soundFile; + + void create() + { + m_soundFile = sfOutputSoundFile_create(); + } + + ~this() + { + sfOutputSoundFile_destroy(m_soundFile); + } + + bool openFromFile(string filename,uint channelCount,uint sampleRate) + { + import dsfml.system.string; + bool toReturn = sfOutputSoundFile_openFromFile(m_soundFile, toStringz(filename),channelCount,sampleRate); + err.write(toString(sfErr_getOutput())); + return toReturn; + } + + void write(const(short)[] data) + { + sfOutputSoundFile_write(m_soundFile, data.ptr, data.length); + } + +} + +extern(C) const(char)* sfErr_getOutput(); + + +private extern(C) +{ + +struct sfOutputSoundFile; + +sfOutputSoundFile* sfOutputSoundFile_create(); + +void sfOutputSoundFile_destroy(sfOutputSoundFile* file); + +bool sfOutputSoundFile_openFromFile(sfOutputSoundFile* file, const(char)* filename,uint channelCount,uint sampleRate); + +void sfOutputSoundFile_write(sfOutputSoundFile* file, const short* data, long sampleCount); + +} diff --git a/src/dsfml/graphics/font.d b/src/dsfml/graphics/font.d index 2172e01..07c5654 100644 --- a/src/dsfml/graphics/font.d +++ b/src/dsfml/graphics/font.d @@ -355,7 +355,7 @@ void sfFont_destroy(sfFont* font); //Get a glyph in a font -void sfFont_getGlyph(const(sfFont)* font, uint codePoint, int characterSize, bool bold, int* glyphAdvance, int* glyphBoundsLeft, int* glyphBoundsTop, int* glyphBoundsWidth, int* glyphBoundsHeight, int* glyphTextRectLeft, int* glyphTextRectTop, int* glyphTextRectWidth, int* glyphTextRectHeight); +void sfFont_getGlyph(const(sfFont)* font, uint codePoint, int characterSize, bool bold, float* glyphAdvance, float* glyphBoundsLeft, float* glyphBoundsTop, float* glyphBoundsWidth, float* glyphBoundsHeight, int* glyphTextRectLeft, int* glyphTextRectTop, int* glyphTextRectWidth, int* glyphTextRectHeight); //Get the kerning value corresponding to a given pair of characters in a font diff --git a/src/dsfml/graphics/glyph.d b/src/dsfml/graphics/glyph.d index 0898a79..11cd96f 100644 --- a/src/dsfml/graphics/glyph.d +++ b/src/dsfml/graphics/glyph.d @@ -36,7 +36,7 @@ public import dsfml.graphics.rect; +/ struct Glyph { - int advance; /// Offset to move horizontally to the next character. - IntRect bounds; /// Bounding rectangle of the glyph, in coordinates relative to the baseline. + float advance; /// Offset to move horizontally to the next character. + FloatRect bounds; /// Bounding rectangle of the glyph, in coordinates relative to the baseline. IntRect textureRect; /// Texture coordinates of the glyph inside the font's texture. } \ No newline at end of file diff --git a/src/dsfml/graphics/text.d b/src/dsfml/graphics/text.d index 561ea59..69bfb79 100644 --- a/src/dsfml/graphics/text.d +++ b/src/dsfml/graphics/text.d @@ -447,10 +447,10 @@ private: // Extract the current glyph's description Glyph glyph = m_font.getGlyph(curChar, m_characterSize, bold); - int left = glyph.bounds.left; - int top = glyph.bounds.top; - int right = glyph.bounds.left + glyph.bounds.width; - int bottom = glyph.bounds.top + glyph.bounds.height; + float left = glyph.bounds.left; + float top = glyph.bounds.top; + float right = glyph.bounds.left + glyph.bounds.width; + float bottom = glyph.bounds.top + glyph.bounds.height; float u1 = cast(float)(glyph.textureRect.left); float v1 = cast(float)(glyph.textureRect.top); From 092750dc19cbdefcdbd871ab539de402970cbcc2 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Sat, 2 Apr 2016 18:57:23 -0700 Subject: [PATCH 12/27] Add constructors for BlendMode to work more like the C++ version Correct BlendMode.Multiply and BlendMode.None. --- src/dsfml/graphics/blendmode.d | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/dsfml/graphics/blendmode.d b/src/dsfml/graphics/blendmode.d index 52d82c8..a426d73 100644 --- a/src/dsfml/graphics/blendmode.d +++ b/src/dsfml/graphics/blendmode.d @@ -71,4 +71,22 @@ struct BlendMode Factor alphaSrcFactor = Factor.One; Factor alphaDstFactor = Factor.OneMinusSrcAlpha; Equation alphaEquation = Equation.Add; + + this(Factor colorSrc, Factor colorDst, Equation colorEqua, + Factor alphaSrc, Factor alphaDst, Equation alphaEqua) + { + colorSrcFactor = colorSrc; + colorDstFactor = colorDst; + colorEquation = colorEqua; + + alphaSrcFactor = alphaSrc; + alphaDstFactor = alphaDst; + alphaEquation = alphaEquation; + } + + this(Factor srcFactor, Factor dstFactor, Equation equation = Equation.Add) { + colorSrcFactor = alphaSrcFactor = srcFactor; + colorDstFactor = alphaDstFactor = dstFactor; + colorEquation = alphaEquation = equation; + } } \ No newline at end of file From 8dae8b5ac698deada4acaed1a53f5a7b9d0f1892 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Sat, 2 Apr 2016 19:03:05 -0700 Subject: [PATCH 13/27] Remove constructors as it seems to break version of DMD < 2.068 --- src/dsfml/graphics/blendmode.d | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/dsfml/graphics/blendmode.d b/src/dsfml/graphics/blendmode.d index a426d73..39542e6 100644 --- a/src/dsfml/graphics/blendmode.d +++ b/src/dsfml/graphics/blendmode.d @@ -42,8 +42,8 @@ struct BlendMode Factor.One, Factor.OneMinusSrcAlpha, Equation.Add); enum Add = BlendMode(Factor.SrcAlpha, Factor.One, Equation.Add, Factor.One, Factor.One, Equation.Add); - enum Multiply = BlendMode(Factor.DstColor, Factor.Zero); - enum None = BlendMode (Factor.One, Factor.Zero); + enum Multiply = BlendMode(Factor.DstColor, Factor.Zero, Equation.Add, Factor.DstColor, Factor.Zero, Equation.Add); + enum None = BlendMode (Factor.One, Factor.Zero, Equation.Add, Factor.One, Factor.Zero, Equation.Add); enum Factor { @@ -71,22 +71,4 @@ struct BlendMode Factor alphaSrcFactor = Factor.One; Factor alphaDstFactor = Factor.OneMinusSrcAlpha; Equation alphaEquation = Equation.Add; - - this(Factor colorSrc, Factor colorDst, Equation colorEqua, - Factor alphaSrc, Factor alphaDst, Equation alphaEqua) - { - colorSrcFactor = colorSrc; - colorDstFactor = colorDst; - colorEquation = colorEqua; - - alphaSrcFactor = alphaSrc; - alphaDstFactor = alphaDst; - alphaEquation = alphaEquation; - } - - this(Factor srcFactor, Factor dstFactor, Equation equation = Equation.Add) { - colorSrcFactor = alphaSrcFactor = srcFactor; - colorDstFactor = alphaDstFactor = dstFactor; - colorEquation = alphaEquation = equation; - } } \ No newline at end of file From abc9e4b33520a82249c52fed7fb831a1c7598c17 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Tue, 5 Apr 2016 21:01:33 -0700 Subject: [PATCH 14/27] Allocate buffer for Joystick.Identification.name on the D-side. Fixes string corruption issue on windows. --- src/dsfml/window/joystick.d | 66 ++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/src/dsfml/window/joystick.d b/src/dsfml/window/joystick.d index 43a82c6..1b793bb 100644 --- a/src/dsfml/window/joystick.d +++ b/src/dsfml/window/joystick.d @@ -29,14 +29,14 @@ module dsfml.window.joystick; *by an index that is passed to the functions of this class. * *This class allows users to query the state of joysticks at any time and directly, without having to deal with - *a window and its events. Compared to the JoystickMoved, JoystickButtonPressed and JoystickButtonReleased events, - *Joystick can retrieve the state of axes and buttons of joysticks at any time (you don't need to store and update - *a boolean on your side in order to know if a button is pressed or released), and you always get the real state of + *a window and its events. Compared to the JoystickMoved, JoystickButtonPressed and JoystickButtonReleased events, + *Joystick can retrieve the state of axes and buttons of joysticks at any time (you don't need to store and update + *a boolean on your side in order to know if a button is pressed or released), and you always get the real state of *joysticks, even if they are moved, pressed or released when your window is out of focus and no event is triggered. */ final abstract class Joystick { - ///Structure holding a joystick's identification; + ///Structure holding a joystick's identification; struct Identification { ///Name of the joystick dstring name; @@ -45,7 +45,7 @@ final abstract class Joystick ///Product identifier uint productId; } - + //Constants related to joysticks capabilities. enum { @@ -56,7 +56,7 @@ final abstract class Joystick ///Maximum number of supported axes. JoystickAxisCount = 8 } - + ///Axes supported by SFML joysticks. enum Axis { @@ -90,7 +90,7 @@ final abstract class Joystick { return sfJoystick_getButtonCount(joystick); } - + ///Get the current position of a joystick axis. /// ///If the joystick is not connected, this function returns 0. @@ -104,7 +104,7 @@ final abstract class Joystick { return sfJoystick_getAxisPosition(joystick, axis); } - + ///Get the joystick information /// ///Params: @@ -112,17 +112,18 @@ final abstract class Joystick /// ///Returns: Structure containing the joystick information. static Identification getIdentification(uint joystick) { + import std.exception; Identification identification; - const(dchar)* name; - size_t nameSize; - - sfJoystick_getIdentification(joystick, &name, &nameSize, &identification.vendorId, &identification.productId); - - identification.name = name[0..nameSize].idup; - + dchar[] name; + name.length = sfJoystick_getIdentificationNameSize(joystick); + + sfJoystick_getIdentification(joystick, name.ptr, &identification.vendorId, &identification.productId); + + identification.name = assumeUnique(name); + return identification; } - + ///Check if a joystick supports a given axis. /// ///If the joystick is not connected, this function returns false. @@ -136,7 +137,7 @@ final abstract class Joystick { return (sfJoystick_hasAxis(joystick, axis)); } - + ///Check if a joystick button is pressed. /// ///If the joystick is not connected, this function returns false. @@ -170,7 +171,7 @@ final abstract class Joystick { sfJoystick_update(); } - + } unittest @@ -179,11 +180,11 @@ unittest { import std.stdio; - + Joystick.update(); - - bool[] joysticks = [false,false,false,false,false,false,false,false]; - + + bool[] joysticks = [false,false,false,false,false,false,false,false]; + for(uint i; i < Joystick.JoystickCount; ++i) { if(Joystick.isConnected(i)) @@ -191,17 +192,17 @@ unittest auto id = Joystick.getIdentification(i); joysticks[i] = true; writeln("Joystick number ",i," is connected!"); - writefln("Type: %s, ID: %x:%x", id.name, id.vendorId, id.productId); + writefln("Type: %s, ID: %x:%x", id.name, id.vendorId, id.productId); } } - + foreach(uint i,bool joystick;joysticks) { if(joystick) { //Check buttons uint buttonCounts = Joystick.getButtonCount(i); - + for(uint j = 0; j Date: Wed, 6 Apr 2016 22:12:07 -0700 Subject: [PATCH 15/27] Fix 2.071 compilation and deprecations --- src/dsfml/audio/soundbuffer.d | 88 +++++----- src/dsfml/audio/soundrecorder.d | 2 +- src/dsfml/audio/soundstream.d | 74 ++++----- src/dsfml/graphics/font.d | 108 ++++++------ src/dsfml/graphics/image.d | 110 ++++++------- src/dsfml/graphics/rendertexture.d | 120 +++++++------- src/dsfml/graphics/renderwindow.d | 254 ++++++++++++++--------------- src/dsfml/graphics/shader.d | 134 +++++++-------- src/dsfml/graphics/sprite.d | 49 +++--- src/dsfml/graphics/text.d | 120 +++++++------- src/dsfml/graphics/texture.d | 148 ++++++++--------- src/dsfml/network/ftp.d | 58 +++---- src/dsfml/network/http.d | 112 ++++++------- src/dsfml/network/tcplistener.d | 18 +- src/dsfml/network/tcpsocket.d | 46 +++--- src/dsfml/network/udpsocket.d | 28 ++-- src/dsfml/window/window.d | 44 ++--- 17 files changed, 758 insertions(+), 755 deletions(-) diff --git a/src/dsfml/audio/soundbuffer.d b/src/dsfml/audio/soundbuffer.d index 5054b6f..a55f090 100644 --- a/src/dsfml/audio/soundbuffer.d +++ b/src/dsfml/audio/soundbuffer.d @@ -39,17 +39,17 @@ import dsfml.system.err; /++ + Storage for audio samples defining a sound. - + + + + A sample is a 16 bits signed integer that defines the amplitude of the sound at a given time. The sound is then restituted by playing these samples at a high rate (for example, 44100 samples per second is the standard rate used for playing CDs). In short, audio samples are like texture pixels, and a SoundBuffer is similar to a Texture. - + + + + A sound buffer can be loaded from a file (see loadFromFile() for the complete list of supported formats), from memory, from a custom stream (see InputStream) or directly from an array of samples. It can also be saved back to a file. - + - + Sound buffers alone are not very useful: they hold the audio data but cannot be played. To do so, you need to use the sf::Sound class, which provides functions to play/pause/stop the sound as well as changing the way it is outputted (volume, pitch, 3D position, ...). - + + + + + Sound buffers alone are not very useful: they hold the audio data but cannot be played. To do so, you need to use the sf::Sound class, which provides functions to play/pause/stop the sound as well as changing the way it is outputted (volume, pitch, 3D position, ...). + + + This separation allows more flexibility and better performances: indeed a sf::SoundBuffer is a heavy resource, and any operation on it is slow (often too slow for real-time applications). On the other side, a sf::Sound is a lightweight object, which can use the audio data of a sound buffer and change the way it is played without actually modifying that data. Note that it is also possible to bind several Sound instances to the same SoundBuffer. - + + + + It is important to note that the Sound instance doesn't copy the buffer that it uses, it only keeps a reference to it. Thus, a SoundBuffer must not be destructed while it is used by a Sound (i.e. never write a function that uses a local SoundBuffer instance for loading a sound). - + + + + See_Also: http://www.sfml-dev.org/documentation/2.0/classsf_1_1SoundBuffer.php#details + Authors: Laurent Gomila, Jeremy DeHaan +/ @@ -61,7 +61,7 @@ class SoundBuffer { import dsfml.system.string; sfPtr = sfSoundBuffer_construct(); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } ~this() @@ -70,15 +70,15 @@ class SoundBuffer mixin(destructorOutput); sfSoundBuffer_destroy(sfPtr); } - + //TODO: copy constructor? //So many possible properties.... - /** + /** * Get the array of audio samples stored in the buffer. - * + * * The format of the returned samples is 16 bits signed integer (sf::Int16). The total number of samples in this array is given by the getSampleCount() function. - * + * * Returns: Read-only pointer to the array of sound samples */ const(short[]) getSamples() const @@ -95,9 +95,9 @@ class SoundBuffer /** * Get the sample rate of the sound. - * + * * The sample rate is the number of samples played per second. The higher, the better the quality (for example, 44100 samples/s is CD quality). - * + * * Returns: Sample rate (number of samples per second) */ uint getSampleRate() const @@ -107,9 +107,9 @@ class SoundBuffer /** * Get the number of channels used by the sound. - * + * * If the sound is mono then the number of channels will be 1, 2 for stereo, etc. - * + * * Returns: Number of channels */ uint getChannelCount() const @@ -119,7 +119,7 @@ class SoundBuffer /** * Get the total duration of the sound. - * + * * Returns: Sound duration */ Duration getDuration() const @@ -130,12 +130,12 @@ class SoundBuffer /** * Load the sound buffer from a file. - * + * * Here is a complete list of all the supported audio formats: ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam, w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64. - * + * * Params: * filename = Path of the sound file to load - * + * * Returns: True if loading succeeded, false if it failed */ bool loadFromFile(string filename) @@ -147,19 +147,19 @@ class SoundBuffer } else { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); return false; } } /** * Load the sound buffer from a file in memory. - * + * * Here is a complete list of all the supported audio formats: ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam, w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64. - * + * * Params: * data = The array of data - * + * * Returns: True if loading succeeded, false if it failed */ bool loadFromMemory(const(void)[] data) @@ -171,23 +171,23 @@ class SoundBuffer else { import dsfml.system.string; - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); return false; } } /* * Load the sound buffer from a custom stream. - * + * * Here is a complete list of all the supported audio formats: ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam, w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64. - * + * * Params: * stream = Source stream to read from - * + * * Returns: True if loading succeeded, false if it failed */ bool loadFromStream(InputStream stream) - { + { if(sfSoundBuffer_loadFromStream(sfPtr, new SoundBufferStream(stream))) { return true; @@ -195,21 +195,21 @@ class SoundBuffer else { import dsfml.system.string; - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); return false; } } /** * Load the sound buffer from an array of audio samples. - * + * * The assumed format of the audio samples is 16 bits signed integer (short). - * + * * Params: * samples = Array of samples in memory * channelCount = Number of channels (1 = mono, 2 = stereo, ...) * sampleRate = Sample rate (number of samples to play per second) - * + * * Returns: True if loading succeeded, false if it failed */ bool loadFromSamples(const(short[]) samples, uint channelCount, uint sampleRate) @@ -221,19 +221,19 @@ class SoundBuffer else { import dsfml.system.string; - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); return false; } } /** * Save the sound buffer to an audio file. - * + * * Here is a complete list of all the supported audio formats: ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam, w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64. - * + * * Params: * filename = Path of the sound file to write - * + * * Returns: True if saving succeeded, false if it failed */ bool saveToFile(string filename) @@ -246,11 +246,11 @@ class SoundBuffer else { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); return false; } } - + } @@ -288,11 +288,11 @@ unittest private extern(C++) interface sfmlInputStream { long read(void* data, long size); - + long seek(long position); - + long tell(); - + long getSize(); } @@ -315,12 +315,12 @@ private class SoundBufferStream:sfmlInputStream { return myStream.seek(position); } - + extern(C++)long tell() { return myStream.tell(); } - + extern(C++)long getSize() { return myStream.getSize(); diff --git a/src/dsfml/audio/soundrecorder.d b/src/dsfml/audio/soundrecorder.d index a3a9460..1dcaa32 100644 --- a/src/dsfml/audio/soundrecorder.d +++ b/src/dsfml/audio/soundrecorder.d @@ -60,7 +60,7 @@ class SoundRecorder callBacks = new SoundRecorderCallBacks(this); sfPtr = sfSoundRecorder_construct(callBacks); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); //Fix for some strange bug that I can't seem to track down. //This bug causes the array in SoundBufferRecorder to segfault if diff --git a/src/dsfml/audio/soundstream.d b/src/dsfml/audio/soundstream.d index 14c605e..931b4a4 100644 --- a/src/dsfml/audio/soundstream.d +++ b/src/dsfml/audio/soundstream.d @@ -32,21 +32,21 @@ import dsfml.system.err; /++ + Abstract base class for streamed audio sources. - + + + + Unlike audio buffers (see SoundBuffer), audio streams are never completely loaded in memory. - + + + + Instead, the audio data is acquired continuously while the stream is playing. This behaviour allows to play a sound with no loading delay, and keeps the memory consumption very low. - + + + + Sound sources that need to be streamed are usually big files (compressed audio musics that would eat hundreds of MB in memory) or files that would take a lot of time to be received (sounds played over the network). - + + + + SoundStream is a base class that doesn't care about the stream source, which is left to the derived class. SFML provides a built-in specialization for big files (see Music). No network stream source is provided, but you can write your own by combining this class with the network module. - + + + + A derived class has to override two virtual functions: + - onGetData fills a new chunk of audio data to be played. + - onSeek changes the current playing position in the source - + + + + It is important to note that each SoundStream is played in its own separate thread, so that the streaming loop doesn't block the rest of the program. In particular, the OnGetData and OnSeek virtual functions may sometimes be called from this separate thread. It is important to keep this in mind, because you may have to take care of synchronization issues if you share data between threads. - + + + + See_Also: http://sfml-dev.org/documentation/2.0/classsf_1_1SoundStream.php#details + Authors: Laurent Gomila, Jeremy DeHaan +/ @@ -76,7 +76,7 @@ class SoundStream:SoundSource sfSoundStream_initialize(sfPtr, channelCount, sampleRate); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } @@ -87,16 +87,16 @@ class SoundStream:SoundSource { sfSoundStream_setPitch(sfPtr, newPitch); } - + float pitch() { return sfSoundStream_getPitch(sfPtr); } } - + /** * The volume of the sound. - * + * * The volume is a vlue between 0 (mute) and 100 (full volume). The default value for the volume is 100. */ @property @@ -111,10 +111,10 @@ class SoundStream:SoundSource return sfSoundStream_getVolume(sfPtr); } } - + /** * The 3D position of the sound in the audio scene. - * + * * Only sounds with one channel (mono sounds) can be spatialized. The default position of a sound is (0, 0, 0). */ @property @@ -123,7 +123,7 @@ class SoundStream:SoundSource { sfSoundStream_setPosition(sfPtr, newPosition.x, newPosition.y, newPosition.z); } - + Vector3f position() { Vector3f temp; @@ -145,7 +145,7 @@ class SoundStream:SoundSource { sfSoundStream_setLoop(sfPtr, loop); } - + bool isLooping() { return sfSoundStream_getLoop(sfPtr); @@ -162,18 +162,18 @@ class SoundStream:SoundSource void playingOffset(Duration offset) { sfSoundStream_setPlayingOffset(sfPtr, offset.total!"usecs"); - + } - + Duration playingOffset() { return usecs(sfSoundStream_getPlayingOffset(sfPtr)); } } - + /** * Make the sound's position relative to the listener (true) or absolute (false). - * + * * Making a sound relative to the listener will ensure that it will always be played the same way regardless the position of the listener. This can be useful for non-spatialized sounds, sounds that are produced by the listener, or sounds attached to it. The default value is false (position is absolute). */ @property @@ -182,16 +182,16 @@ class SoundStream:SoundSource { sfSoundStream_setRelativeToListener(sfPtr, relative); } - + bool relativeToListener() { return sfSoundStream_isRelativeToListener(sfPtr); } } - + /** * The minimum distance of the sound. - * + * * The "minimum distance" of a sound is the maximum distance at which it is heard at its maximum volume. Further than the minimum distance, it will start to fade out according to its attenuation factor. A value of 0 ("inside the head of the listener") is an invalid value and is forbidden. The default value of the minimum distance is 1. */ @property @@ -200,18 +200,18 @@ class SoundStream:SoundSource { sfSoundStream_setMinDistance(sfPtr, distance); } - + float minDistance() { return sfSoundStream_getMinDistance(sfPtr); } } - + /** * The attenuation factor of the sound. - * - * The attenuation is a multiplicative factor which makes the sound more or less loud according to its distance from the listener. An attenuation of 0 will produce a non-attenuated sound, i.e. its volume will always be the same whether it is heard from near or from far. - * + * + * The attenuation is a multiplicative factor which makes the sound more or less loud according to its distance from the listener. An attenuation of 0 will produce a non-attenuated sound, i.e. its volume will always be the same whether it is heard from near or from far. + * * On the other hand, an attenuation value such as 100 will make the sound fade out very quickly as it gets further from the listener. The default value of the attenuation is 1. */ @property @@ -220,7 +220,7 @@ class SoundStream:SoundSource { sfSoundStream_setAttenuation(sfPtr, newAttenuation); } - + float attenuation() { return sfSoundStream_getAttenuation(sfPtr); @@ -242,7 +242,7 @@ class SoundStream:SoundSource return sfSoundStream_getChannelCount(sfPtr); } } - + /** * The stream sample rate of the stream * @@ -272,7 +272,7 @@ class SoundStream:SoundSource sfSoundStream_play(sfPtr); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } void pause() @@ -288,7 +288,7 @@ class SoundStream:SoundSource abstract bool onGetData(ref const(short)[] samples); abstract void onSeek(Duration timeOffset); - + } @@ -312,12 +312,12 @@ public: class SoundStreamCallBacks: sfmlSoundStreamCallBacks { SoundStream m_stream; - + this(SoundStream stream) { m_stream = stream; } - + extern(C++) bool onGetData(Chunk* chunk) { const(short)[] samples; @@ -330,14 +330,14 @@ class SoundStreamCallBacks: sfmlSoundStreamCallBacks return ret; } - + extern(C++) void onSeek(long time) { m_stream.onSeek(usecs(time)); } - - - + + + } private extern(C): diff --git a/src/dsfml/graphics/font.d b/src/dsfml/graphics/font.d index 07c5654..fbef984 100644 --- a/src/dsfml/graphics/font.d +++ b/src/dsfml/graphics/font.d @@ -26,16 +26,16 @@ import dsfml.system.err; /++ + Class for loading and manipulating character fonts. - + + + + Fonts can be loaded from a file, from memory or from a custom stream, and supports the most common types of fonts. - + + + + See the loadFromFile function for the complete list of supported formats. - + + + + Once it is loaded, a Font instance provides three types of information about the font: + - Global metrics, such as the line spacing + - Per-glyph metrics, such as bounding box or kerning + - Pixel representation of glyphs - + + + + Authors: Laurent Gomila, Jeremy DeHaan + See_Also: http://sfml-dev.org/documentation/2.0/classsf_1_1Font.php#details +/ @@ -58,7 +58,7 @@ class Font sfPtr = newFont; fontTexture = new Texture(sfFont_getTexturePtr(sfPtr)); } - + ~this() { import dsfml.system.config; @@ -68,12 +68,12 @@ class Font /** * Load the font from a file. - * + * * The supported font formats are: TrueType, Type 1, CFF, OpenType, SFNT, X11 PCF, Windows FNT, BDF, PFR and Type 42. Note that this function know nothing about the standard fonts installed on the user's system, thus you can't load them directly. - * + * * Params: * filename = Path of the font file to load - * + * * Returns: True if loading succeeded, false if it failed. */ bool loadFromFile(string filename) @@ -83,20 +83,20 @@ class Font bool ret = sfFont_loadFromFile(sfPtr, toStringz(filename)); if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } - + return ret; } /** * Load the font from a file in memory. - * + * * The supported font formats are: TrueType, Type 1, CFF, OpenType, SFNT, X11 PCF, Windows FNT, BDF, PFR and Type 42. Warning: SFML cannot preload all the font data in this function, so the buffer pointed by data has to remain valid as long as the font is used. - * + * * Params: * data = data holding the font file - * + * * Returns: True if loading succeeded, false if it failed. */ bool loadFromMemory(const(void)[] data) @@ -106,20 +106,20 @@ class Font bool ret = sfFont_loadFromMemory(sfPtr, data.ptr, data.length); if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } - + return ret; } /** * Load the font from a custom stream. - * + * * The supported font formats are: TrueType, Type 1, CFF, OpenType, SFNT, X11 PCF, Windows FNT, BDF, PFR and Type 42. Warning: SFML cannot preload all the font data in this function, so the contents of stream have to remain valid as long as the font is used. - * + * * Params: * stream = Source stream to read from - * + * * Returns: True if loading succeeded, false if it failed. */ bool loadFromStream(InputStream stream) @@ -132,20 +132,20 @@ class Font if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } - + return ret; } /** * Retrieve a glyph of the font. - * + * * Params: * codePoint = Unicode code point of the character ot get * characterSize = Reference character size * bols = Retrieve the bold version or the regular one? - * + * * Returns: The glyph corresponding to codePoint and characterSize */ Glyph getGlyph(dchar codePoint, uint characterSize, bool bold) const @@ -159,59 +159,59 @@ class Font /** * Get the kerning offset of two glyphs. - * + * * The kerning is an extra offset (negative) to apply between two glyphs when rendering them, to make the pair look more "natural". For example, the pair "AV" have a special kerning to make them closer than other characters. Most of the glyphs pairs have a kerning offset of zero, though. - * + * * Params: * first = Unicode code point of the first character * second = Unicode code point of the second character * characterSize = Reference character size - * + * * Returns: Kerning value for first and second, in pixels */ - float getKerning (dchar first, dchar second, uint characterSize) const + float getKerning (dchar first, dchar second, uint characterSize) const { - return sfFont_getKerning(sfPtr, cast(uint)first, cast(uint)second, characterSize); + return sfFont_getKerning(sfPtr, cast(uint)first, cast(uint)second, characterSize); } /** * Get the line spacing. - * + * * The spacing is the vertical offset to apply between consecutive lines of text. - * + * * Params: * characterSize = Reference character size - * + * * Returns: Line spacing, in pixels */ float getLineSpacing (uint characterSize) const { - return sfFont_getLineSpacing(sfPtr, characterSize); + return sfFont_getLineSpacing(sfPtr, characterSize); } - + /** * Get the position of the underline. - * + * * Underline position is the vertical offset to apply between the baseline and the underline. - * + * * Params: * characterSize = Reference character size - * + * * Returns: Underline position, in pixels */ float getUnderlinePosition (uint characterSize) const { return sfFont_getUnderlinePosition(sfPtr, characterSize); } - + /** * Get the thickness of the underline. - * + * * Underline thickness is the vertical size of the underline. - * + * * Params: * characterSize = Reference character size - * + * * Returns: Underline thickness, in pixels */ float getUnderlineThickness (uint characterSize) const @@ -221,12 +221,12 @@ class Font /** * Retrieve the texture containing the loaded glyphs of a certain size. - * + * * The contents of the returned texture changes as more glyphs are requested, thus it is not very relevant. It is mainly used internally by Text. - * + * * Params: * characterSize = Reference character size - * + * * Returns: Texture containing the glyphs of the requested size */ const(Texture) getTexture (uint characterSize) const @@ -235,11 +235,11 @@ class Font //Possible: cache last size used using sound method(mutable instance storage) import std.stdio; - + //writeln("Updating Texture"); - + sfFont_updateTexture(sfPtr, characterSize); - + //fontTexture.sfPtr = sfFont_getTexture(sfPtr, characterSize); // writeln("returning texture"); @@ -248,7 +248,7 @@ class Font /** * Performs a deep copy on the font. - * + * * Returns: The duplicated font. */ @property @@ -287,11 +287,11 @@ private: private extern(C++) interface fontInputStream { long read(void* data, long size); - + long seek(long position); - + long tell(); - + long getSize(); } @@ -299,27 +299,27 @@ private extern(C++) interface fontInputStream private class fontStream:fontInputStream { private InputStream myStream; - + this(InputStream stream) { myStream = stream; } - + extern(C++)long read(void* data, long size) { return myStream.read(data[0..cast(size_t)size]); } - + extern(C++)long seek(long position) { return myStream.seek(position); } - + extern(C++)long tell() { return myStream.tell(); } - + extern(C++)long getSize() { return myStream.getSize(); diff --git a/src/dsfml/graphics/image.d b/src/dsfml/graphics/image.d index e8e741f..a31c25d 100644 --- a/src/dsfml/graphics/image.d +++ b/src/dsfml/graphics/image.d @@ -30,32 +30,32 @@ import dsfml.system.err; /++ + Class for loading, manipulating and saving images. - + + + + Image is an abstraction to manipulate images as bidimensional arrays of pixels. - + + + + The class provides functions to load, read, write and save pixels, as well as many other useful functions. - + + + + Image can handle a unique internal representation of pixels, which is RGBA 32 bits. This means that a pixel must be composed of 8 bits red, green, blue and alpha channels – just like a Color. All the functions that return an array of pixels follow this rule, and all parameters that you pass to Image functions (such as loadFromPixels) must use this representation as well. - + + + + A Image can be copied, but it is a heavy resource and if possible you should always use [const] references to pass or return them to avoid useless copies. - + + + + Authors: Laurent Gomila, Jeremy DeHaan + See_Also: http://www.sfml-dev.org/documentation/2.0/classsf_1_1Image.php#details +/ class Image { package sfImage* sfPtr; - + this() { sfPtr = sfImage_construct(); } - + package this(sfImage* image) { sfPtr = image; } - + ~this() { import dsfml.system.config; @@ -65,29 +65,29 @@ class Image /** * Create the image and fill it with a unique color. - * + * * Params: * width = Width of the image * height = Height of the image * color = Fill color - * + * */ void create(uint width, uint height, Color color) { sfImage_createFromColor(sfPtr, width, height,color.r, color.b, color.g, color.a); } - + /** * Create the image from an array of pixels. - * + * * The pixel array is assumed to contain 32-bits RGBA pixels, and have the given width and height. If not, this is an undefined behaviour. If pixels is null, an empty image is created. - * + * * Params: * width = Width of the image * height = Height of the image * pixels = Array of pixels to copy to the image - * + * */ void create(uint width, uint height, const ref ubyte[] pixels) { @@ -96,12 +96,12 @@ class Image /** * Load the image from a file on disk. - * + * * The supported image formats are bmp, png, tga, jpg, gif, psd, hdr and pic. Some format options are not supported, like progressive jpeg. If this function fails, the image is left unchanged. - * + * * Params: * filename = Path of the image file to load - * + * * Returns: True if loading succeeded, false if it failed */ bool loadFromFile(string fileName) @@ -112,7 +112,7 @@ class Image if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; @@ -120,12 +120,12 @@ class Image /** * Load the image from a file in memory. - * + * * The supported image formats are bmp, png, tga, jpg, gif, psd, hdr and pic. Some format options are not supported, like progressive jpeg. If this function fails, the image is left unchanged. - * + * * Params: * data = Data file in memory to load - * + * * Returns: True if loading succeeded, false if it failed */ bool loadFromMemory(const(void)[] data) @@ -135,20 +135,20 @@ class Image bool ret = sfImage_loadFromMemory(sfPtr, data.ptr, data.length); if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } - + return ret; } /** * Load the image from a custom stream. - * + * * The supported image formats are bmp, png, tga, jpg, gif, psd, hdr and pic. Some format options are not supported, like progressive jpeg. If this function fails, the image is left unchanged. - * + * * Params: * stream = Source stream to read from - * + * * Returns: True if loading succeeded, false if it failed */ bool loadFromStream(InputStream stream) @@ -158,7 +158,7 @@ class Image bool ret = sfImage_loadFromStream(sfPtr, new imageStream(stream)); if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; @@ -166,17 +166,17 @@ class Image /** * Get the color of a pixel - * + * * This function doesn't check the validity of the pixel coordinates; using out-of-range values will result in an undefined behaviour. - * + * * Params: * x = X coordinate of the pixel to get * y = Y coordinate of the pixel to get - * + * * Returns: Color of the pixel at coordinates (x, y) */ Color getPixel(uint x, uint y) - { + { Color temp; sfImage_getPixel(sfPtr, x,y, &temp.r, &temp.b, &temp.g, &temp.a); return temp; @@ -184,16 +184,16 @@ class Image /** * Get the read-only array of pixels that make up the image. - * + * * The returned value points to an array of RGBA pixels made of 8 bits integers components. The size of the array is width * height * 4 (getSize().x * getSize().y * 4). Warning: the returned pointer may become invalid if you modify the image, so you should never store it for too long. - * + * * Returns: Read-only array of pixels that make up the image. */ const(ubyte)[] getPixelArray() { Vector2u size = getSize(); int length = size.x * size.y * 4; - + if(length!=0) { return sfImage_getPixelsPtr(sfPtr)[0..length]; @@ -207,7 +207,7 @@ class Image /** * Return the size (width and height) of the image. - * + * * Returns: Size of the image, in pixels. */ Vector2u getSize() @@ -219,9 +219,9 @@ class Image /** * Change the color of a pixel. - * + * * This function doesn't check the validity of the pixel coordinates, using out-of-range values will result in an undefined behaviour. - * + * * Params: * x = X coordinate of pixel to change * y = Y coordinate of pixel to change @@ -234,11 +234,11 @@ class Image /** * Copy pixels from another image onto this one. - * + * * This function does a slow pixel copy and should not be used intensively. It can be used to prepare a complex static image from several others, but if you need this kind of feature in real-time you'd better use RenderTexture. - * + * * If sourceRect is empty, the whole image is copied. If applyAlpha is set to true, the transparency of source pixels is applied. If it is false, the pixels are copied unchanged with their alpha value. - * + * * Params: * source = Source image to copy * destX = X coordinate of the destination position @@ -253,9 +253,9 @@ class Image /** * Create a transparency mask from a specified color-key. - * + * * This function sets the alpha value of every pixel matching the given color to alpha (0 by default) so that they become transparent. - * + * * Params: * color = Color to make transparent * alpha = Alpha value to assign to transparent pixels @@ -264,7 +264,7 @@ class Image { sfImage_createMaskFromColor(sfPtr,maskColor.r,maskColor.b, maskColor.g, maskColor.a, alpha); } - + @property Image dup() const { @@ -285,19 +285,19 @@ class Image /** * Save the image to a file on disk. - * + * * The format of the image is automatically deduced from the extension. The supported image formats are bmp, png, tga and jpg. The destination file is overwritten if it already exists. This function fails if the image is empty. - * + * * Params: * filename = Path of the file to save - * + * * Returns: True if saving was successful */ bool saveToFile(string fileName) { import dsfml.system.string; bool toReturn = sfImage_saveToFile(sfPtr, toStringz(fileName)); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); return toReturn; } } @@ -339,11 +339,11 @@ unittest private extern(C++) interface imageInputStream { long read(void* data, long size); - + long seek(long position); - + long tell(); - + long getSize(); } @@ -351,27 +351,27 @@ private extern(C++) interface imageInputStream private class imageStream:imageInputStream { private InputStream myStream; - + this(InputStream stream) { myStream = stream; } - + extern(C++)long read(void* data, long size) { return myStream.read(data[0..cast(size_t)size]); } - + extern(C++)long seek(long position) { return myStream.seek(position); } - + extern(C++)long tell() { return myStream.tell(); } - + extern(C++)long getSize() { return myStream.getSize(); diff --git a/src/dsfml/graphics/rendertexture.d b/src/dsfml/graphics/rendertexture.d index c174e13..4053b36 100644 --- a/src/dsfml/graphics/rendertexture.d +++ b/src/dsfml/graphics/rendertexture.d @@ -40,17 +40,17 @@ import dsfml.system.err; /++ + Target for off-screen 2D rendering into a texture. - + + + + RenderTexture is the little brother of RenderWindow. - + + + + It implements the same 2D drawing and OpenGL-related functions (see their base class RenderTarget for more details), the difference is that the result is stored in an off-screen texture rather than being show in a window. - + + + + Rendering to a texture can be useful in a variety of situations: + - precomputing a complex static texture (like a level's background from multiple tiles) + - applying post-effects to the whole scene with shaders + - creating a sprite from a 3D object rendered with OpenGL + - etc. - + + + + Authors: Laurent Gomila, Jeremy DeHaan + See_Also: http://www.sfml-dev.org/documentation/2.0/classsf_1_1RenderTexture.php#details +/ @@ -77,23 +77,23 @@ class RenderTexture : RenderTarget /** * Create the render-texture. - * - * Before calling this function, the render-texture is in an invalid state, thus it is mandatory to call it before doing anything with the render-texture. - * + * + * Before calling this function, the render-texture is in an invalid state, thus it is mandatory to call it before doing anything with the render-texture. + * * The last parameter, depthBuffer, is useful if you want to use the render-texture for 3D OpenGL rendering that requires a depth-buffer. Otherwise it is unnecessary, and you should leave this parameter to false (which is its default value). - * + * * Params: * width = Width of the render-texture * height = Height of the render-texture * depthBuffer = Do you want this render-texture to have a depth buffer? - * + * */ void create(uint width, uint height, bool depthBuffer = false) { import dsfml.system.string; sfRenderTexture_create(sfPtr, width, height, depthBuffer); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); //get view m_currentView = new View(sfRenderTexture_getView(sfPtr)); @@ -102,7 +102,7 @@ class RenderTexture : RenderTarget m_defaultView = new View(sfRenderTexture_getDefaultView(sfPtr)); } - + /** * Enable or disable texture smoothing. */ @@ -121,9 +121,9 @@ class RenderTexture : RenderTarget /** * Change the current active view. - * - * The view is like a 2D camera, it controls which part of the 2D scene is visible, and how it is viewed in the render-target. The new view will affect everything that is drawn, until another view is set. - * + * + * The view is like a 2D camera, it controls which part of the 2D scene is visible, and how it is viewed in the render-target. The new view will affect everything that is drawn, until another view is set. + * * The render target keeps its own copy of the view object, so it is not necessary to keep the original one alive after calling this function. To restore the original view of the target, you can pass the result of getDefaultView() to this function. */ @property @@ -142,9 +142,9 @@ class RenderTexture : RenderTarget /** * Get the default view of the render target. - * + * * The default view has the initial size of the render target, and never changes after the target has been created. - * + * * Returns: The default view of the render target. */ const(View) getDefaultView() const // note: if refactored, change documentation of view property above @@ -154,7 +154,7 @@ class RenderTexture : RenderTarget /** * Return the size of the rendering region of the target. - * + * * Returns: Size in pixels */ Vector2u getSize() const @@ -166,12 +166,12 @@ class RenderTexture : RenderTarget /** * Get the viewport of a view, applied to this render target. - * + * * The viewport 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 viewport actually covers in the target. - * + * * Params: * view = The view for which we want to compute the viewport - * + * * Returns: Viewport rectangle, expressed in pixels */ IntRect getViewport(const(View) view) const @@ -183,11 +183,11 @@ class RenderTexture : RenderTarget /** * Get a read-only reference to the target texture. - * + * * After drawing to the render-texture and calling Display, you can retrieve the updated texture using this function, and draw it using a sprite (for example). - * + * * The internal Texture of a render-texture is always the same instance, so that it is possible to call this function once and keep a reference to the texture even after it is modified. - * + * * Returns: Const reference to the texture. */ const(Texture) getTexture() @@ -197,11 +197,11 @@ class RenderTexture : RenderTarget /** * Activate or deactivate the render-texture for rendering. - * + * * This function makes the render-texture's context current for future OpenGL rendering operations (so you shouldn't care about it if you're not doing direct OpenGL stuff). - * + * * Only one context can be current in a thread, so if you want to draw OpenGL geometry to another render target (like a RenderWindow) don't forget to activate it again. - * + * * Params: * active = True to activate, false to deactivate */ @@ -212,9 +212,9 @@ class RenderTexture : RenderTarget /** * Clear the entire target with a single color. - * + * * This function is usually called once every frame, to clear the previous contents of the target. - * + * * Params: * color = Fill color to use to clear the render target */ @@ -225,7 +225,7 @@ class RenderTexture : RenderTarget /** * Update the contents of the target texture. - * + * * This function updates the target texture with what has been drawn so far. Like for windows, calling this function is mandatory at the end of rendering. Not calling it may leave the texture in an undefined state. */ void display() @@ -235,7 +235,7 @@ class RenderTexture : RenderTarget /** * Draw a drawable object to the render target. - * + * * Params: * drawable = Object to draw * states = Render states to use for drawing @@ -251,13 +251,13 @@ class RenderTexture : RenderTarget { states.shader = RenderStates.emptyShader; } - + drawable.draw(this, states); } /** * Draw primitives defined by an array of vertices. - * + * * Params: * vertices = Array of vertices to draw * type = Type of primitives to draw @@ -266,7 +266,7 @@ class RenderTexture : RenderTarget override void draw(const(Vertex)[] vertices, PrimitiveType type, RenderStates states = RenderStates.Default) { import std.algorithm; - + //Confirms that even a blank render states struct won't break anything during drawing if(states.texture is null) { @@ -276,20 +276,20 @@ class RenderTexture : RenderTarget { states.shader = RenderStates.emptyShader; } - + sfRenderTexture_drawPrimitives(sfPtr, vertices.ptr, cast(uint)min(uint.max, vertices.length),type,states.blendMode.colorSrcFactor, states.blendMode.alphaDstFactor, - states.blendMode.colorEquation, states.blendMode.alphaSrcFactor, states.blendMode.alphaDstFactor, states.blendMode.alphaEquation, + states.blendMode.colorEquation, states.blendMode.alphaSrcFactor, states.blendMode.alphaDstFactor, states.blendMode.alphaEquation, states.transform.m_matrix.ptr, states.texture.sfPtr, states.shader.sfPtr); } /** * Convert a point fom target coordinates to world coordinates, using the current view. - * + * * This function is an overload of the mapPixelToCoords function that implicitely uses the current view. - * + * * Params: * point = Pixel to convert - * + * * Returns: The converted point, in "world" coordinates. */ Vector2f mapPixelToCoords(Vector2i point) const @@ -301,19 +301,19 @@ class RenderTexture : RenderTarget /** * Convert a point from target coordinates to world coordinates. - * + * * This function finds the 2D position that matches the given pixel of the render-target. In other words, it does the inverse of what the graphics card does, to find the initial position of a rendered pixel. - * + * * Initially, both coordinate systems (world units and target pixels) match perfectly. But if you define a custom view or resize your render-target, this assertion is not true anymore, ie. a point located at (10, 50) in your render-target may map to the point (150, 75) in your 2D world – if the view is translated by (140, 25). - * + * * For render-windows, this function is typically used to find which point (or object) is located below the mouse cursor. - * + * * This version uses a custom view for calculations, see the other overload of the function if you want to use the current view of the render-target. - * + * * Params: * point = Pixel to convert * view = The view to use for converting the point - * + * * Returns: The converted point, in "world" coordinates. */ Vector2f mapPixelToCoords(Vector2i point, const(View) view) const @@ -325,46 +325,46 @@ class RenderTexture : RenderTarget /** * Convert a point from target coordinates to world coordinates, using the current view. - * + * * This function is an overload of the mapPixelToCoords function that implicitely uses the current view. - * + * * Params: * point = Point to convert - * + * * The converted point, in "world" coordinates */ Vector2i mapCoordsToPixel(Vector2f point) const { Vector2i temp; - sfRenderTexture_mapCoordsToPixel(sfPtr,point.x, point.y, &temp.x, &temp.y,null); + sfRenderTexture_mapCoordsToPixel(sfPtr,point.x, point.y, &temp.x, &temp.y,null); return temp; } /** * Convert a point from world coordinates to target coordinates. - * + * * This function finds the pixel of the render-target that matches the given 2D point. In other words, it goes through the same process as the graphics card, to compute the final position of a rendered point. - * + * * Initially, both coordinate systems (world units and target pixels) match perfectly. But if you define a custom view or resize your render-target, this assertion is not true anymore, ie. a point located at (150, 75) in your 2D world may map to the pixel (10, 50) of your render-target – if the view is translated by (140, 25). - * + * * This version uses a custom view for calculations, see the other overload of the function if you want to use the current view of the render-target. - * + * * Params: * point = Point to convert * view = The view to use for converting the point - * + * * Returns: The converted point, in target coordinates (pixels) */ Vector2i mapCoordsToPixel(Vector2f point, const(View) view) const { Vector2i temp; - sfRenderTexture_mapCoordsToPixel(sfPtr,point.x, point.y, &temp.x, &temp.y,view.sfPtr); + sfRenderTexture_mapCoordsToPixel(sfPtr,point.x, point.y, &temp.x, &temp.y,view.sfPtr); return temp; } /** * Restore the previously saved OpenGL render states and matrices. - * + * * See the description of pushGLStates to get a detailed description of these functions. */ void popGLStates() @@ -374,25 +374,25 @@ class RenderTexture : RenderTarget /** * Save the current OpenGL render states and matrices. - * + * * This function can be used when you mix SFML drawing and direct OpenGL rendering. Combined with PopGLStates, it ensures that: * - SFML's internal states are not messed up by your OpenGL code * - your OpenGL states are not modified by a call to an SFML function - * + * * More specifically, it must be used around the code that calls Draw functions. - * + * * Note that this function is quite expensive: it saves all the possible OpenGL states and matrices, even the ones you don't care about. Therefore it should be used wisely. It is provided for convenience, but the best results will be achieved if you handle OpenGL states yourself (because you know which states have really changed, and need to be saved and restored). Take a look at the ResetGLStates function if you do so. */ void pushGLStates() { import dsfml.system.string; sfRenderTexture_pushGLStates(sfPtr); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } /** * Reset the internal OpenGL states so that the target is ready for drawing. - * + * * This function can be used when you mix SFML drawing and direct OpenGL rendering, if you choose not to use pushGLStates/popGLStates. It makes sure that all OpenGL states needed by SFML are set, so that subsequent draw() calls will work as expected. */ void resetGLStates() diff --git a/src/dsfml/graphics/renderwindow.d b/src/dsfml/graphics/renderwindow.d index 34cc9fd..0e171bf 100644 --- a/src/dsfml/graphics/renderwindow.d +++ b/src/dsfml/graphics/renderwindow.d @@ -45,17 +45,17 @@ import dsfml.system.vector2; /++ + Window that can serve as a target for 2D drawing. - + + + + RenderWindow is the main class of the Graphics package. - + + + + It defines an OS window that can be painted using the other classes of the graphics module. - + + + + RenderWindow is derived from Window, thus it inherits all its features: events, window management, OpenGL rendering, etc. See the documentation of Window for a more complete description of all these features, as well as code examples. - + + + + On top of that, RenderWindow adds more features related to 2D drawing with the graphics module (see its base class RenderTarget for more details). - + + + + Like Window, RenderWindow is still able to render direct OpenGL stuff. It is even possible to mix together OpenGL calls and regular SFML drawing commands. - + + + + Authors: Laurent Gomila, Jeremy DeHaan + See_Also: http://sfml-dev.org/documentation/2.0/classsf_1_1RenderWindow.php#details +/ @@ -97,7 +97,7 @@ class RenderWindow : Window, RenderTarget /** * Change the position of the window on screen. - * + * * This property only works for top-level windows (i.e. it will be ignored for windows created from the handle of a child window/control). */ @property @@ -107,7 +107,7 @@ class RenderWindow : Window, RenderTarget sfRenderWindow_setPosition(sfPtr,newPosition.x, newPosition.y); return newPosition; } - + override Vector2i position() { Vector2i temp; @@ -136,9 +136,9 @@ class RenderWindow : Window, RenderTarget /** * Change the current active view. - * - * The view is like a 2D camera, it controls which part of the 2D scene is visible, and how it is viewed in the render-target. The new view will affect everything that is drawn, until another view is set. - * + * + * The view is like a 2D camera, it controls which part of the 2D scene is visible, and how it is viewed in the render-target. The new view will affect everything that is drawn, until another view is set. + * * The render target keeps its own copy of the view object, so it is not necessary to keep the original one alive after calling this function. To restore the original view of the target, you can pass the result of getDefaultView() to this function. */ @property @@ -157,9 +157,9 @@ class RenderWindow : Window, RenderTarget /** * Get the default view of the render target. - * + * * The default view has the initial size of the render target, and never changes after the target has been created. - * + * * Returns: The default view of the render target. */ const(View) getDefaultView() const // note: if refactored, change documentation of view property above @@ -169,9 +169,9 @@ class RenderWindow : Window, RenderTarget /** * Get the settings of the OpenGL context of the window. - * + * * Note that these settings may be different from what was passed to the constructor or the create() function, if one or more settings were not supported. In this case, SFML chose the closest match. - * + * * Returns: Structure containing the OpenGL context settings */ override ContextSettings getSettings() const @@ -184,23 +184,23 @@ class RenderWindow : Window, RenderTarget //this is a duplicate with the size property. Need to look into that.(Inherited from RenderTarget) /** * Return the size of the rendering region of the target. - * + * * Returns: Size in pixels */ Vector2u getSize() const { Vector2u temp; - + sfRenderWindow_getSize(sfPtr, &temp.x, &temp.y); - + return temp; } /** * Get the OS-specific handle of the window. - * + * * The type of the returned handle is WindowHandle, which is a typedef to the handle type defined by the OS. You shouldn't need to use this function, unless you have very specific stuff to implement that SFML doesn't support, or implement a temporary workaround until a bug is fixed. - * + * * Returns: System handle of the window */ override WindowHandle getSystemHandle() const @@ -210,48 +210,48 @@ class RenderWindow : Window, RenderTarget /** * Get the viewport of a view, applied to this render target. - * + * * The viewport 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 viewport actually covers in the target. - * + * * Params: * view = The view for which we want to compute the viewport - * + * * Returns: Viewport rectangle, expressed in pixels */ IntRect getViewport(const(View) view) const { IntRect temp; - + sfRenderWindow_getViewport(sfPtr, view.sfPtr, &temp.left, &temp.top, &temp.width, &temp.height); - + return temp; } /** * Get the viewport of a view, applied to this render target. - * + * * A window 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 window can be active on a thread at a time, thus the window previously active (if any) automatically gets deactivated. - * + * * Params: * active = True to activate, false to deactivate - * + * * Returns: True if operation was successful, false otherwise */ override bool setActive(bool active) { import dsfml.system.string; bool toReturn = sfRenderWindow_setActive(sfPtr, active); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); return toReturn; } /** * Limit the framerate to a maximum fixed frequency. - * + * * If a limit is set, the window will use a small delay after each call to display() to ensure that the current frame lasted long enough to match the framerate limit. - * + * * SFML will try to match the given limit as much as it can, but since it internally uses sf::sleep, whose precision depends on the underlying OS, the results may be a little unprecise as well (for example, you can get 65 FPS when requesting 60). - * + * * Params: * limit = Framerate limit, in frames per seconds (use 0 to disable limit) */ @@ -262,11 +262,11 @@ class RenderWindow : Window, RenderTarget /** * Change the window's icon. - * + * * pixels must be an array of width x height pixels in 32-bits RGBA format. - * + * * The OS default icon is used by default. - * + * * Params: * width = Icon's width, in pixels * height = Icon's height, in pixels @@ -279,11 +279,11 @@ class RenderWindow : Window, RenderTarget /** * Change the joystick threshold. - * + * * The joystick threshold is the value below which no JoystickMoved event will be generated. - * + * * The threshold value is 0.1 by default. - * + * * Params: * threshold = New threshold, in the range [0, 100] */ @@ -294,11 +294,11 @@ class RenderWindow : Window, RenderTarget /** * Enable or disable automatic key-repeat. - * + * * If key repeat is enabled, you will receive repeated KeyPressed events while keeping a key pressed. If it is disabled, you will only get a single event when the key is pressed. - * + * * Key repeat is enabled by default. - * + * * Params: * enabled = True to enable, false to disable */ @@ -309,9 +309,9 @@ class RenderWindow : Window, RenderTarget /** * Show or hide the mouse cursor. - * + * * The mouse cursor is visible by default. - * + * * Params: * enabled = True show the mouse cursor, false to hide it */ @@ -324,7 +324,7 @@ class RenderWindow : Window, RenderTarget /** * Change the title of the window - * + * * Params: * title = New title */ @@ -335,7 +335,7 @@ class RenderWindow : Window, RenderTarget } /** * Change the title of the window - * + * * Params: * title = New title */ @@ -346,7 +346,7 @@ class RenderWindow : Window, RenderTarget } /** * Change the title of the window - * + * * Params: * title = New title */ @@ -358,11 +358,11 @@ class RenderWindow : Window, RenderTarget /** * Enable or disable vertical synchronization. - * + * * Activating vertical synchronization will limit the number of frames displayed to the refresh rate of the monitor. This can avoid some visual artifacts, and limit the framerate to a good value (but not constant across different computers). - * + * * Vertical synchronization is disabled by default. - * + * * Params: * enabled = True to enable v-sync, false to deactivate it */ @@ -373,9 +373,9 @@ class RenderWindow : Window, RenderTarget /** * Show or hide the window. - * + * * The window is shown by default. - * + * * Params: * visible = True to show the window, false to hide it */ @@ -386,9 +386,9 @@ class RenderWindow : Window, RenderTarget /** * Clear the entire target with a single color. - * + * * This function is usually called once every frame, to clear the previous contents of the target. - * + * * Params: * color = Fill color to use to clear the render target */ @@ -399,7 +399,7 @@ class RenderWindow : Window, RenderTarget /** * Close the window and destroy all the attached resources. - * + * * After calling this function, the Window instance remains valid and you can call create() to recreate the window. All other functions such as pollEvent() or display() will still work (i.e. you don't have to test isOpen() every time), and will have no effect on closed windows. */ override void close() @@ -417,9 +417,9 @@ class RenderWindow : Window, RenderTarget override void create(VideoMode mode, string title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) { import dsfml.system.string; - + sfRenderWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, toStringz(stringConvert!(char,dchar)(title)), style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); //get view m_currentView = new View(sfRenderWindow_getView(sfPtr)); @@ -436,9 +436,9 @@ class RenderWindow : Window, RenderTarget override void create(VideoMode mode, wstring title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) { import dsfml.system.string; - + sfRenderWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, toStringz(stringConvert!(wchar,dchar)(title)), style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); //get view m_currentView = new View(sfRenderWindow_getView(sfPtr)); @@ -455,9 +455,9 @@ class RenderWindow : Window, RenderTarget override void create(VideoMode mode, dstring title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) { import dsfml.system.string; - + sfRenderWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, toStringz(title), style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); //get view m_currentView = new View(sfRenderWindow_getView(sfPtr)); @@ -476,7 +476,7 @@ class RenderWindow : Window, RenderTarget { import dsfml.system.string; sfRenderWindow_createFromHandle(sfPtr, handle, settings.depthBits,settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); //get view m_currentView = new View(sfRenderWindow_getView(sfPtr)); @@ -486,7 +486,7 @@ class RenderWindow : Window, RenderTarget /** * Display on screen what has been rendered to the window so far. - * + * * This function is typically called after all OpenGL rendering has been done for the current frame, in order to show it on screen. */ override void display() @@ -496,7 +496,7 @@ class RenderWindow : Window, RenderTarget /** * Draw a drawable object to the render target. - * + * * Params: * drawable = Object to draw * states = Render states to use for drawing @@ -512,13 +512,13 @@ class RenderWindow : Window, RenderTarget { states.shader = RenderStates.emptyShader; } - + drawable.draw(this,states); } /** * Draw primitives defined by an array of vertices. - * + * * Params: * vertices = Array of vertices to draw * type = Type of primitives to draw @@ -536,7 +536,7 @@ class RenderWindow : Window, RenderTarget { states.shader = RenderStates.emptyShader; } - + sfRenderWindow_drawPrimitives(sfPtr, vertices.ptr, cast(uint)min(uint.max, vertices.length), type,states.blendMode.colorSrcFactor, states.blendMode.alphaDstFactor, states.blendMode.colorEquation, states.blendMode.alphaSrcFactor, states.blendMode.alphaDstFactor, states.blendMode.alphaEquation, states.transform.m_matrix.ptr,states.texture.sfPtr,states.shader.sfPtr); @@ -544,9 +544,9 @@ class RenderWindow : Window, RenderTarget /** * Tell whether or not the window is open. - * + * * This function returns whether or not the window exists. Note that a hidden window (setVisible(false)) is open (therefore this function would return true). - * + * * Returns: True if the window is open, false if it has been closed */ override bool isOpen() @@ -556,95 +556,95 @@ class RenderWindow : Window, RenderTarget /** * Convert a point fom target coordinates to world coordinates, using the current view. - * + * * This function is an overload of the mapPixelToCoords function that implicitely uses the current view. - * + * * Params: * point = Pixel to convert - * + * * Returns: The converted point, in "world" coordinates. */ Vector2f mapPixelToCoords(Vector2i point) const { Vector2f temp; - + sfRenderWindow_mapPixelToCoords(sfPtr,point.x, point.y, &temp.x, &temp.y,null); - + return temp; } /** * Convert a point from target coordinates to world coordinates. - * + * * This function finds the 2D position that matches the given pixel of the render-target. In other words, it does the inverse of what the graphics card does, to find the initial position of a rendered pixel. - * + * * Initially, both coordinate systems (world units and target pixels) match perfectly. But if you define a custom view or resize your render-target, this assertion is not true anymore, ie. a point located at (10, 50) in your render-target may map to the point (150, 75) in your 2D world – if the view is translated by (140, 25). - * + * * For render-windows, this function is typically used to find which point (or object) is located below the mouse cursor. - * + * * This version uses a custom view for calculations, see the other overload of the function if you want to use the current view of the render-target. - * + * * Params: * point = Pixel to convert * view = The view to use for converting the point - * + * * Returns: The converted point, in "world" coordinates. */ Vector2f mapPixelToCoords(Vector2i point, const(View) view) const { Vector2f temp; - + sfRenderWindow_mapPixelToCoords(sfPtr,point.x, point.y, &temp.x, &temp.y,view.sfPtr); - + return temp; } /** * Convert a point from target coordinates to world coordinates, using the current view. - * + * * This function is an overload of the mapPixelToCoords function that implicitely uses the current view. - * + * * Params: * point = Point to convert - * + * * The converted point, in "world" coordinates */ Vector2i mapCoordsToPixel(Vector2f point) const { Vector2i temp; - + sfRenderWindow_mapCoordsToPixel(sfPtr,point.x, point.y, &temp.x, &temp.y,null); - + return temp; } /** * Convert a point from world coordinates to target coordinates. - * + * * This function finds the pixel of the render-target that matches the given 2D point. In other words, it goes through the same process as the graphics card, to compute the final position of a rendered point. - * + * * Initially, both coordinate systems (world units and target pixels) match perfectly. But if you define a custom view or resize your render-target, this assertion is not true anymore, ie. a point located at (150, 75) in your 2D world may map to the pixel (10, 50) of your render-target – if the view is translated by (140, 25). - * + * * This version uses a custom view for calculations, see the other overload of the function if you want to use the current view of the render-target. - * + * * Params: * point = Point to convert * view = The view to use for converting the point - * + * * Returns: The converted point, in target coordinates (pixels) */ Vector2i mapCoordsToPixel(Vector2f point, const(View) view) const { Vector2i temp; - + sfRenderWindow_mapCoordsToPixel(sfPtr,point.x, point.y, &temp.x, &temp.y,view.sfPtr); - + return temp; } /** * Restore the previously saved OpenGL render states and matrices. - * + * * See the description of pushGLStates to get a detailed description of these functions. */ void popGLStates() @@ -654,25 +654,25 @@ class RenderWindow : Window, RenderTarget /** * Save the current OpenGL render states and matrices. - * + * * This function can be used when you mix SFML drawing and direct OpenGL rendering. Combined with PopGLStates, it ensures that: * - SFML's internal states are not messed up by your OpenGL code * - your OpenGL states are not modified by a call to an SFML function - * + * * More specifically, it must be used around the code that calls Draw functions. - * + * * Note that this function is quite expensive: it saves all the possible OpenGL states and matrices, even the ones you don't care about. Therefore it should be used wisely. It is provided for convenience, but the best results will be achieved if you handle OpenGL states yourself (because you know which states have really changed, and need to be saved and restored). Take a look at the ResetGLStates function if you do so. */ void pushGLStates() { import dsfml.system.string; sfRenderWindow_pushGLStates(sfPtr); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } /** * Reset the internal OpenGL states so that the target is ready for drawing. - * + * * This function can be used when you mix SFML drawing and direct OpenGL rendering, if you choose not to use pushGLStates/popGLStates. It makes sure that all OpenGL states needed by SFML are set, so that subsequent draw() calls will work as expected. */ void resetGLStates() @@ -682,12 +682,12 @@ class RenderWindow : Window, RenderTarget /** * Pop the event on top of the event queue, if any, and return it. - * + * * This function is not blocking: if there's no pending event then it will return false and leave event unmodified. Note that more than one event may be present in the event queue, thus you should always call this function in a loop to make sure that you process every pending event. - * + * * Params: * event = Event to be returned - * + * * Returns: True if an event was returned, or false if the event queue was empty */ override bool pollEvent(ref Event event) @@ -697,19 +697,19 @@ class RenderWindow : Window, RenderTarget /** * Wait for an event and return it. - * + * * This function is blocking: if there's no pending event then it will wait until an event is received. After this function returns (and no error occured), the event object is always valid and filled properly. This function is typically used when you have a thread that is dedicated to events handling: you want to make this thread sleep as long as no new event is received. - * + * * Params: * event = Event to be returned - * + * * Returns: False if any error occurred */ override bool waitEvent(ref Event event) { return (sfRenderWindow_waitEvent(sfPtr, &event)); } - + //TODO: Consider adding these methods. //void onCreate //void onResize @@ -738,8 +738,8 @@ class RenderWindow : Window, RenderTarget package static void* windowPointer(Window window) { scope RenderWindow temp = new RenderWindow(); - - return temp.getWindowPtr(window); + + return temp.getWindowPtr(window); } } @@ -757,43 +757,43 @@ unittest //constructor auto window = new RenderWindow(VideoMode(800,600),"Test Window"); - + //perform each window call Vector2u windowSize = window.size; - + windowSize.x = 1000; windowSize.y = 1000; - + window.size = windowSize; - + Vector2i windowPosition = window.position; - + windowPosition.x = 100; windowPosition.y = 100; - + window.position = windowPosition; - + window.setTitle("thing");//uses the first set title - + window.setTitle("素晴らしい !"d);//forces the dstring override and uses unicode - + window.setActive(true); - + window.setJoystickThreshhold(1); - + window.setVisible(true); - + window.setFramerateLimit(60); - + window.setMouseCursorVisible(true); - + window.setVerticalSyncEnabled(true); - + auto settings = window.getSettings(); - + auto image = new Image(); image.loadFromFile("res/TestImage.png"); - + window.setIcon(image.getSize().x,image.getSize().x,image.getPixelArray()); auto texture = new Texture(); @@ -818,9 +818,9 @@ unittest } window.clear(); - + window.draw(sprite); - + window.display(); } diff --git a/src/dsfml/graphics/shader.d b/src/dsfml/graphics/shader.d index 06eddc1..715c973 100644 --- a/src/dsfml/graphics/shader.d +++ b/src/dsfml/graphics/shader.d @@ -31,24 +31,24 @@ import dsfml.system.err; /++ + Shader class (vertex and fragment). - + + + + Shaders are programs written using a specific language, executed directly by the graphics card and allowing one to apply real-time operations to the rendered entities. - + + + + There are two kinds of shaders: + - Vertex shaders, that process vertices + - Fragment (pixel) shaders, that process pixels - + + + + A DSFML Shader can be composed of either a vertex shader alone, a fragment shader alone, or both combined (see the variants of the load functions). - + + + + Shaders are written in GLSL, which is a C-like language dedicated to OpenGL shaders. You'll probably need to learn its basics before writing your own shaders for SFML. - + + + + Like any D/C/C++ program, a shader has its own variables that you can set from your D application. DSFML's Shader handles 5 different types of variables: + - floats + - vectors (2, 3, or 4 components) + - colors + - textures + - transforms (matrices) - + + + + Authors: Laurent Gomila, Jeremy DeHaan + See_Also: http://www.sfml-dev.org/documentation/2.0/classsf_1_1Shader.php#details +/ @@ -66,19 +66,19 @@ class Shader /// Special type/value that can be passed to setParameter, and that represents the texture of the object being drawn. struct CurrentTextureType {}; static CurrentTextureType CurrentTexture; - + this() { //creates an empty shader sfPtr=sfShader_construct(); } - + package this(sfShader* shader) { sfPtr = shader; } - + ~this() { import dsfml.system.config; @@ -88,13 +88,13 @@ class Shader /** * Load either the vertex or fragment shader from a file. - * + * * This function loads a single shader, either vertex or fragment, identified by the second argument. The source must be a text file containing a valid shader in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; you'll probably need to read a good documentation for it before writing your own shaders. - * + * * Params: * filename = Path of the vertex or fragment shader file to load * type = Type of shader (vertex or fragment) - * + * * Returns: True if loading succeeded, false if it failed. */ bool loadFromFile(string filename, Type type) @@ -114,7 +114,7 @@ class Shader if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; @@ -122,13 +122,13 @@ class Shader /** * Load both the vertex and fragment shaders from files. - * + * * This function loads both the vertex and the fragment shaders. If one of them fails to load, the shader is left empty (the valid shader is unloaded). The sources must be text files containing valid shaders in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; you'll probably need to read a good documentation for it before writing your own shaders. - * + * * Params: * vertexShaderFilename = Path of the vertex shader file to load * fragmentShaderFilename = Path of the fragment shader file to load - * + * * Returns: True if loading succeeded, false if it failed. */ bool loadFromFile(string vertexShaderFilename, string fragmentShaderFilename) @@ -138,7 +138,7 @@ class Shader bool ret = sfShader_loadFromFile(sfPtr, toStringz(vertexShaderFilename) , toStringz(fragmentShaderFilename)); if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; @@ -146,13 +146,13 @@ class Shader /** * Load either the vertex or fragment shader from a source code in memory. - * + * * This function loads a single shader, either vertex or fragment, identified by the second argument. The source code must be a valid shader in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; you'll probably need to read a good documentation for it before writing your own shaders. - * + * * Params: * shader = String containing the source code of the shader * type = Type of shader (vertex or fragment) - * + * * Returns: True if loading succeeded, false if it failed. */ bool loadFromMemory(string shader, Type type) @@ -171,20 +171,20 @@ class Shader } if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; } - + /** * Load both the vertex and fragment shaders from source codes in memory. - * + * * This function loads both the vertex and the fragment shaders. If one of them fails to load, the shader is left empty (the valid shader is unloaded). The sources must be valid shaders in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; you'll probably need to read a good documentation for it before writing your own shaders. - * + * * Params: * vertexShader = String containing the source code of the vertex shader * fragmentShader = String containing the source code of the fragment shader - * + * * Returns: True if loading succeeded, false if it failed. */ bool loadFromMemory(string vertexShader, string fragmentShader) @@ -194,21 +194,21 @@ class Shader bool ret = sfShader_loadFromMemory(sfPtr, toStringz(vertexShader) , toStringz(fragmentShader)); if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; } - + /** * Load either the vertex or fragment shader from a custom stream. - * + * * This function loads a single shader, either vertex or fragment, identified by the second argument. The source code must be a valid shader in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; you'll probably need to read a good documentation for it before writing your own shaders. - * + * * Params: * stream = Source stream to read from * type = Type of shader (vertex or fragment) - * + * * Returns: True if loading succeeded, false if it failed. */ bool loadFromStream(InputStream stream, Type type) @@ -227,7 +227,7 @@ class Shader } if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; @@ -235,13 +235,13 @@ class Shader /** * Load both the vertex and fragment shaders from custom streams. - * + * * This function loads a single shader, either vertex or fragment, identified by the second argument. The source code must be a valid shader in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; you'll probably need to read a good documentation for it before writing your own shaders. - * + * * Params: * vertexShaderStream = Source stream to read the vertex shader from * fragmentShaderStream = Source stream to read the fragment shader from - * + * * Returns: True if loading succeeded, false if it failed. */ bool loadFromStream(InputStream vertexShaderStream, InputStream fragmentShaderStream) @@ -251,14 +251,14 @@ class Shader bool ret = sfShader_loadFromStream(sfPtr, new shaderStream(vertexShaderStream), new shaderStream(fragmentShaderStream)); if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; } /** * Change a float parameter of the shader. - * + * * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a float (float GLSL type). * x = Value to assign @@ -278,7 +278,7 @@ class Shader /** * Change a 2-components vector parameter of the shader. - * + * * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 2x1 vector (vec2 GLSL type). * x = First component of the value to assign @@ -292,7 +292,7 @@ class Shader /** * Change a 3-components vector parameter of the shader. - * + * * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 3x1 vector (vec3 GLSL type). * x = First component of the value to assign @@ -307,7 +307,7 @@ class Shader /** * Change a 4-components vector parameter of the shader. - * + * * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 4x1 vector (vec4 GLSL type). * x = First component of the value to assign @@ -323,7 +323,7 @@ class Shader /** * Change variable length vector parameter of the shader. The length of the set of floats must be between 1 and 4. - * + * * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 4x1 vector (vec4 GLSL type). * val = The set of floats to assign. @@ -346,7 +346,7 @@ class Shader /** * Change a 2-components vector parameter of the shader. - * + * * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 2x1 vector (vec2 GLSL type). * vector = Vector to assign @@ -366,7 +366,7 @@ class Shader /** * Change a 3-components vector parameter of the shader. - * + * * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 3x1 vector (vec3 GLSL type). * vector = Vector to assign @@ -385,9 +385,9 @@ class Shader /** * Change a color vector parameter of the shader. - * + * * It is important to note that the components of the color are normalized before being passed to the shader. Therefore, they are converted from range [0 .. 255] to range [0 .. 1]. For example, a Color(255, 125, 0, 255) will be transformed to a vec4(1.0, 0.5, 0.0, 1.0) in the shader. - * + * * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 4x1 vector (vec4 GLSL type). * color = Color to assign @@ -406,7 +406,7 @@ class Shader /** * Change a matrix parameter of the shader. - * + * * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 4x4 matrix (mat4 GLSL type). * transform = Transform to assign @@ -425,11 +425,11 @@ class Shader /** * Change a texture parameter of the shader. - * + * * It is important to note that the texture parameter must remain alive as long as the shader uses it - no copoy 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. - * + * * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 2D texture (sampler2D GLSL type). * texture = Texture to assign @@ -438,22 +438,22 @@ class Shader { import dsfml.system.string; sfShader_setTextureParameter(sfPtr, toStringz(name), texture.sfPtr); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } ///ditto void opIndexAssign(const(Texture) texture, string name) { import dsfml.system.string; sfShader_setTextureParameter(sfPtr, toStringz(name), texture.sfPtr); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } /** * 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 Shader.CurrentTexture. - * + * * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 2D texture (sampler2D GLSL type). */ @@ -465,9 +465,9 @@ class Shader /** * 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 value given must be Shader.CurrentTexture. - * + * * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 2D texture (sampler2D GLSL type). */ @@ -479,9 +479,9 @@ class Shader /** * Bind a shader for rendering. - * + * * This function is not part of the graphics API, it mustn't be used when drawing SFML entities. It must be used only if you mix Shader with OpenGL code. - * + * * Params: * shader = Shader to bind. Can be null to use no shader. */ @@ -492,16 +492,16 @@ class Shader /** * Tell whether or not the system supports shaders. - * + * * This function should always be called before using the shader features. If it returns false, then any attempt to use DSFML Shader will fail. - * + * * Returns: True if shaders are supported, false otherwise */ static bool isAvailable() { import dsfml.system.string; bool toReturn = sfShader_isAvailable(); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); return toReturn; } } @@ -514,11 +514,11 @@ unittest private extern(C++) interface shaderInputStream { long read(void* data, long size); - + long seek(long position); - + long tell(); - + long getSize(); } @@ -526,27 +526,27 @@ private extern(C++) interface shaderInputStream private class shaderStream:shaderInputStream { private InputStream myStream; - + this(InputStream stream) { myStream = stream; } - + extern(C++)long read(void* data, long size) { return myStream.read(data[0..cast(size_t)size]); } - + extern(C++)long seek(long position) { return myStream.seek(position); } - + extern(C++)long tell() { return myStream.tell(); } - + extern(C++)long getSize() { return myStream.getSize(); diff --git a/src/dsfml/graphics/sprite.d b/src/dsfml/graphics/sprite.d index 4bb7acc..ab3092d 100644 --- a/src/dsfml/graphics/sprite.d +++ b/src/dsfml/graphics/sprite.d @@ -32,20 +32,21 @@ import dsfml.graphics.renderstates; import dsfml.graphics.primitivetype; import dsfml.system.vector2; +import std.typecons:Rebindable; /++ + Drawable representation of a texture, with its own transformations, color, etc. - + + + + Sprite is a drawable class that allows to easily display a texture (or a part of it) on a render target. - + + + + It inherits all the functions from Transformable: position, rotation, scale, origin. It also adds sprite-specific properties such as the texture to use, the part of it to display, and some convenience functions to change the overall color of the sprite, or to get its bounding rectangle. - + + + + Sprite works in combination with the Texture class, which loads and provides the pixel data of a given texture. - + + + + The separation of Sprite and Texture allows more flexibility and better performances: indeed a Texture is a heavy resource, and any operation on it is slow (often too slow for real-time applications). On the other side, a Sprite is a lightweight object which can use the pixel data of a Texture and draw it with its own transformation/color/blending attributes. - + + + + It is important to note that the Sprite instance doesn't copy the texture that it uses, it only keeps a reference to it. Thus, a Texture must not be destroyed while it is used by a Sprite (i.e. never write a function that uses a local Texture instance for creating a sprite). - + + + + Authors: Laurent Gomila, Jeremy DeHaan + See_Also: http://sfml-dev.org/documentation/2.0/classsf_1_1Sprite.php#details +/ @@ -66,7 +67,7 @@ class Sprite : Drawable, Transformable m_texture = null; m_textureRect = IntRect(); } - + this(const(Texture) texture) { // Constructor code @@ -82,7 +83,7 @@ class Sprite : Drawable, Transformable /** * The sub-rectangle of the texture that the sprite will display. - * + * * The texture rect is useful when you don't want to display the whole texture, but rather a part of it. By default, the texture rect covers the entire texture. */ @property @@ -105,7 +106,7 @@ class Sprite : Drawable, Transformable /** * The global color of the sprite. - * + * * This color is modulated (multiplied) with the sprite's texture. It can be used to colorize the sprite, or change its global opacity. By default, the sprite's color is opaque white. */ @property @@ -123,14 +124,14 @@ class Sprite : Drawable, Transformable { return m_vertices[0].color; } - + } /** * Get the global bounding rectangle of the entity. - * + * * The returned rectangle is in global coordinates, which means that it takes in account the transformations (translation, rotation, scale, ...) that are applied to the entity. In other words, this function returns the bounds of the sprite in the global 2D world's coordinate system. - * + * * Returns: Global bounding rectangle of the entity */ FloatRect getGlobalBounds() @@ -140,9 +141,9 @@ class Sprite : Drawable, Transformable /** * Get the local bounding rectangle of the entity. - * + * * The returned rectangle is in local coordinates, which means that it ignores the transformations (translation, rotation, scale, ...) that are applied to the entity. In other words, this function returns the bounds of the entity in the entity's coordinate system. - * + * * Returns: Local bounding rectangle of the entity */ FloatRect getLocalBounds() @@ -154,9 +155,9 @@ class Sprite : Drawable, Transformable /** * Get the source texture of the sprite. - * + * * If the sprite has no source texture, a NULL pointer is returned. The returned pointer is const, which means that you can't modify the texture when you retrieve it with this function. - * + * * Returns: The sprite's texture */ const(Texture) getTexture() @@ -166,11 +167,11 @@ class Sprite : Drawable, Transformable /** * Change the source texture of the shape. - * + * * The texture argument refers to a texture that must exist as long as the sprite uses it. Indeed, the sprite doesn't store its own copy of the texture, but rather keeps a pointer to the one that you passed to this function. If the source texture is destroyed and the sprite tries to use it, the behaviour is undefined. texture can be NULL to disable texturing. - * + * * If resetRect is true, the TextureRect property of the sprite is automatically adjusted to the size of the new texture. If it is false, the texture rect is left unchanged. - * + * * Params: * texture = New texture * resetRect = Should the texture rect be reset to the size of the new texture? @@ -181,13 +182,13 @@ class Sprite : Drawable, Transformable { textureRect(IntRect(0,0,texture.getSize().x,texture.getSize().y)); } - + m_texture = texture; } /** * Draw the sprite to a render target. - * + * * Params: * renderTarget = Target to draw to * renderStates = Current render states @@ -204,7 +205,7 @@ class Sprite : Drawable, Transformable /** * Create a new Sprite with the same data. Note that the texture is not copied, only its reference. - * + * * Returns: A new Sprite object with the same data. */ @property @@ -227,7 +228,7 @@ class Sprite : Drawable, Transformable void updatePositions() { FloatRect bounds = getLocalBounds(); - + m_vertices[0].position = Vector2f(0, 0); m_vertices[1].position = Vector2f(0, bounds.height); m_vertices[2].position = Vector2f(bounds.width, bounds.height); @@ -240,7 +241,7 @@ class Sprite : Drawable, Transformable float right = left + m_textureRect.width; float top = (m_textureRect.top); float bottom = top + m_textureRect.height; - + m_vertices[0].texCoords = Vector2f(left, top); m_vertices[1].texCoords = Vector2f(left, bottom); m_vertices[2].texCoords = Vector2f(right, bottom); diff --git a/src/dsfml/graphics/text.d b/src/dsfml/graphics/text.d index 69bfb79..b72f283 100644 --- a/src/dsfml/graphics/text.d +++ b/src/dsfml/graphics/text.d @@ -34,19 +34,21 @@ import dsfml.graphics.primitivetype; import dsfml.system.vector2; +import std.typecons:Rebindable; + /++ + Graphical text that can be drawn to a render target. - + + + + Text is a drawable class that allows to easily display some text with custom style and color on a render target. - + + + + It inherits all the functions from Transformable: position, rotation, scale, origin. It also adds text-specific properties such as the font to use, the character size, the font style (bold, italic, underlined), the global color and the text to display of course. It also provides convenience functions to calculate the graphical size of the text, or to get the global position of a given character. - + + + + Text works in combination with the Font class, which loads and provides the glyphs (visual characters) of a given font. - + + + + The separation of Font and Text allows more flexibility and better performances: indeed a Font is a heavy resource, and any operation on it is slow (often too slow for real-time applications). On the other side, a Text is a lightweight object which can combine the glyphs data and metrics of a Font to display any text on a render target. - + + + + It is important to note that the Text instance doesn't copy the font that it uses, it only keeps a reference to it. Thus, a Font must not be destructed while it is used by a Text (i.e. never write a function that uses a local Font instance for creating a text). - + + + + Authors: Laurent Gomila, Jeremy DeHaan + See_Also: http://sfml-dev.org/documentation/2.0/classsf_1_1Text.php#details +/ @@ -87,7 +89,7 @@ class Text : Drawable, Transformable m_vertices = new VertexArray(PrimitiveType.Quads,0); m_bounds = FloatRect(); } - + this(T)(immutable(T)[] text, const(Font) font, uint characterSize = 30) if (is(T == dchar)||is(T == wchar)||is(T == char)) { @@ -111,7 +113,7 @@ class Text : Drawable, Transformable /** * Get the character size. - * + * * Returns: Size of the characters, in pixels. */ uint getCharacterSize() const @@ -121,7 +123,7 @@ class Text : Drawable, Transformable /** * Get the global color of the text. - * + * * Returns: Global color of the text. */ Color getColor() const @@ -131,9 +133,9 @@ class Text : Drawable, Transformable /** * Get thet text's font. - * + * * If the text has no font attached, a NULL pointer is returned. The returned reference is const, which means that you cannot modify the font when you get it from this function. - * + * * Returns: Text's font. */ const(Font) getFont() const @@ -150,9 +152,9 @@ class Text : Drawable, Transformable /** * Get the global bounding rectangle of the entity. - * + * * The returned rectangle is in global coordinates, which means that it takes in account the transformations (translation, rotation, scale, ...) that are applied to the entity. In other words, this function returns the bounds of the sprite in the global 2D world's coordinate system. - * + * * Returns: Global bounding rectangle of the entity. */ FloatRect getGlobalBounds() @@ -162,9 +164,9 @@ class Text : Drawable, Transformable /** * Get the local bounding rectangle of the entity. - * + * * The returned rectangle is in local coordinates, which means that it ignores the transformations (translation, rotation, scale, ...) that are applied to the entity. In other words, this function returns the bounds of the entity in the entity's coordinate system. - * + * * Returns: Local bounding rectangle of the entity. */ FloatRect getLocalBounds() const @@ -175,7 +177,7 @@ class Text : Drawable, Transformable //TODO: maybe a getString!dstring or getString!wstring etc template would be appropriate? /** * Get the text's string. - * + * * The returned string is a dstring, a unicode type. */ immutable(T)[] getString(T=char)() const @@ -187,7 +189,7 @@ class Text : Drawable, Transformable /** * Get the text's style. - * + * * Returns: Text's style. */ Style getStyle() const @@ -197,9 +199,9 @@ class Text : Drawable, Transformable /** * Set the character size. - * + * * The default size is 30. - * + * * Params: * size = New character size, in pixels. */ @@ -211,9 +213,9 @@ class Text : Drawable, Transformable /** * Set the global color of the text. - * + * * By default, the text's color is opaque white. - * + * * Params: * color = New color of the text. */ @@ -225,9 +227,9 @@ class Text : Drawable, Transformable /** * Set the text's font. - * + * * The font argument refers to a font that must exist as long as the text uses it. Indeed, the text doesn't store its own copy of the font, but rather keeps a pointer to the one that you passed to this function. If the font is destroyed and the text tries to use it, the behaviour is undefined. - * + * * Params: * font = New font */ @@ -239,9 +241,9 @@ class Text : Drawable, Transformable /** * Set the text's string. - * + * * A text's string is empty by default. - * + * * Params: * text = New string */ @@ -256,7 +258,7 @@ class Text : Drawable, Transformable //TODO: Does doing binary operations on Styles like the docs suggest actually work? /** * Set the text's style. - * + * * You can pass a combination of one or more styles, for example Style.Bold | Text.Italic. */ void setStyle(Style style) @@ -267,7 +269,7 @@ class Text : Drawable, Transformable /** * Draw the object to a render target. - * + * * Params: * renderTarget = Render target to draw to * renderStates = Current render states @@ -275,11 +277,11 @@ class Text : Drawable, Transformable void draw(RenderTarget renderTarget, RenderStates renderStates) { import std.stdio; - + if ((m_font !is null) && (m_characterSize>0)) { renderStates.transform *= getTransform(); - + //only call getTexture if the size has changed if(m_characterSize != lastSizeUsed) { @@ -288,18 +290,18 @@ class Text : Drawable, Transformable //grab the new texture lastTextureUsed = m_font.getTexture(m_characterSize); } - + //writeln("Update Geometry"); updateGeometry(); - + //writeln("Setting renderstates tecture"); renderStates.texture = m_font.getTexture(m_characterSize); - + if(renderStates.texture is null) { //writeln("Texture don't exist!"); } - + //writeln("Trying to draw!"); renderTarget.draw(m_vertices, renderStates); } @@ -307,12 +309,12 @@ class Text : Drawable, Transformable /** * Return the position of the index-th character. - * + * * This function computes the visual position of a character from its index in the string. The returned position is in global coordinates (translation, rotation, scale and origin are applied). If index is out of range, the position of the end of the string is returned. - * + * * Params: * index = Index of the character - * + * * Returns: Position of the character. */ Vector2f findCharacterPos(size_t index) @@ -322,7 +324,7 @@ class Text : Drawable, Transformable { return Vector2f(0,0); } - + // Adjust the index if it's out of range if(index > m_string.length) { @@ -333,17 +335,17 @@ class Text : Drawable, Transformable float hspace = cast(float)(m_font.getGlyph(' ', m_characterSize, bold).advance); float vspace = cast(float)(m_font.getLineSpacing(m_characterSize)); - + Vector2f position; dchar prevChar = 0; for (size_t i = 0; i < index; ++i) { dchar curChar = m_string[i]; - + // Apply the kerning offset position.x += cast(float)(m_font.getKerning(prevChar, curChar, m_characterSize)); prevChar = curChar; - + // Handle special characters switch (curChar) { @@ -354,14 +356,14 @@ class Text : Drawable, Transformable default: break; } - + // For regular characters, add the advance offset of the glyph position.x += cast(float)(m_font.getGlyph(curChar, m_characterSize, bold).advance); } - + // Transform the position to global coordinates position = getTransform().transformPoint(position); - + return position; } @@ -373,7 +375,7 @@ private: // Clear the previous geometry m_vertices.clear(); m_bounds = FloatRect(); - + // No font: nothing to draw if (m_font is null) return; @@ -387,13 +389,13 @@ private: float italic = (m_style & Style.Italic) ? 0.208f : 0f; // 12 degrees float underlineOffset = m_characterSize * 0.1f; float underlineThickness = m_characterSize * (bold ? 0.1f : 0.07f); - + // Precompute the variables needed by the algorithm float hspace = cast(float)(m_font.getGlyph(' ', m_characterSize, bold).advance); float vspace = cast(float)(m_font.getLineSpacing(m_characterSize)); float x = 0f; float y = cast(float)(m_characterSize); - + // Create one quad for each character float minX = m_characterSize, minY = m_characterSize, maxX = 0, maxY = 0; dchar prevChar = 0; @@ -401,7 +403,7 @@ private: { dchar curChar = m_string[i]; - + // Apply the kerning offset x += cast(float)(m_font.getKerning(prevChar, curChar, m_characterSize)); @@ -412,20 +414,20 @@ private: { float top = y + underlineOffset; float bottom = top + underlineThickness; - + m_vertices.append(Vertex(Vector2f(0, top), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(x, top), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(x, bottom), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(0, bottom), m_color, Vector2f(1, 1))); } - + // Handle special characters if ((curChar == ' ') || (curChar == '\t') || (curChar == '\n') || (curChar == '\v')) { // Update the current bounds (min coordinates) minX = min(minX, x); minY = min(minY, y); - + final switch (curChar) { case ' ' : x += hspace; break; @@ -433,11 +435,11 @@ private: case '\n' : y += vspace; x = 0; break; case '\v' : y += vspace * 4; break; } - + // Update the current bounds (max coordinates) maxX = max(maxX, x); maxY = max(maxY, y); - + // Next glyph, no need to create a quad for whitespace continue; } @@ -446,17 +448,17 @@ private: // Extract the current glyph's description Glyph glyph = m_font.getGlyph(curChar, m_characterSize, bold); - + float left = glyph.bounds.left; float top = glyph.bounds.top; float right = glyph.bounds.left + glyph.bounds.width; float bottom = glyph.bounds.top + glyph.bounds.height; - + float u1 = cast(float)(glyph.textureRect.left); float v1 = cast(float)(glyph.textureRect.top); float u2 = cast(float)(glyph.textureRect.left + glyph.textureRect.width); float v2 = cast(float)(glyph.textureRect.top + glyph.textureRect.height); - + // Add a quad for the current character m_vertices.append(Vertex(Vector2f(x + left - italic * top, y + top), m_color, Vector2f(u1, v1))); m_vertices.append(Vertex(Vector2f(x + right - italic * top, y + top), m_color, Vector2f(u2, v1))); @@ -472,19 +474,19 @@ private: // Advance to the next character x += glyph.advance; } - + // If we're using the underlined style, add the last line if (underlined) { float top = y + underlineOffset; float bottom = top + underlineThickness; - + m_vertices.append(Vertex(Vector2f(0, top), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(x, top), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(x, bottom), m_color, Vector2f(1, 1))); m_vertices.append(Vertex(Vector2f(0, bottom), m_color, Vector2f(1, 1))); } - + // Update the bounding rectangle m_bounds.left = minX; m_bounds.top = minY; @@ -503,7 +505,7 @@ unittest writeln("Unit test for Text"); auto renderTexture = new RenderTexture(); - + renderTexture.create(100,100); auto font = new Font(); diff --git a/src/dsfml/graphics/texture.d b/src/dsfml/graphics/texture.d index 606a768..fbcd04f 100644 --- a/src/dsfml/graphics/texture.d +++ b/src/dsfml/graphics/texture.d @@ -32,21 +32,21 @@ import dsfml.system.err; /++ + Image living on the graphics card that can be used for drawing. - + + + + Texture stores pixels that can be drawn, with a sprite for example. - + + + + A texture lives in the graphics card memory, therefore it is very fast to draw a texture to a render target, or copy a render target to a texture (the graphics card can access both directly). - + + + + Being stored in the graphics card memory has some drawbacks. A texture cannot be manipulated as freely as a Image, you need to prepare the pixels first and then upload them to the texture in a single operation (see Texture::update). - + + + + Texture makes it easy to convert from/to Image, but keep in mind that these calls require transfers between the graphics card and the central memory, therefore they are slow operations. - + + + + A texture can be loaded from an image, but also directly from a file/memory/stream. The necessary shortcuts are defined so that you don't need an image first for the most common cases. However, if you want to perform some modifications on the pixels before creating the final texture, you can load your file to a Image, do whatever you need with the pixels, and then call Texture::loadFromImage. - + + + + Since they live in the graphics card memory, the pixels of a texture cannot be accessed without a slow copy first. And they cannot be accessed individually. Therefore, if you need to read the texture's pixels (like for pixel-perfect collisions), it is recommended to store the collision information separately, for example in an array of booleans. - + + + + Like Image, Texture can handle a unique internal representation of pixels, which is RGBA 32 bits. This means that a pixel must be composed of 8 bits red, green, blue and alpha channels – just like a Color. - + + + + Authors: Laurent Gomila, Jeremy DeHaan + See_Also: http://www.sfml-dev.org/documentation/2.0/classsf_1_1Texture.php#details +/ @@ -58,7 +58,7 @@ class Texture { sfPtr = sfTexture_construct(); } - + package this(sfTexture* texturePointer) { sfPtr = texturePointer; @@ -68,22 +68,22 @@ class Texture { import dsfml.system.config; mixin(destructorOutput); - sfTexture_destroy( sfPtr); + sfTexture_destroy( sfPtr); } /** * Load the texture from a file on disk. - * + * * The area argument can be used to load only a sub-rectangle of the whole image. If you want the entire image then leave the default value (which is an empty IntRect). If the area rectangle crosses the bounds of the image, it is adjusted to fit the image size. - * + * * The maximum size for a texture depends on the graphics driver and can be retrieved with the getMaximumSize function. - * + * * If this function fails, the texture is left unchanged. - * + * * Params: * filename = Path of the image file to load * area = Area of the image to load - * + * * Returns: True if loading was successful, false otherwise. */ bool loadFromFile(string filename, IntRect area = IntRect() ) @@ -93,7 +93,7 @@ class Texture bool ret = sfTexture_loadFromFile(sfPtr, toStringz(filename) ,area.left, area.top,area.width, area.height); if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; @@ -102,18 +102,18 @@ class Texture //TODO: Can this be done with a slice of bytes rather than a const(void)*? /** * Load the texture from a file in memory. - * + * * The area argument can be used to load only a sub-rectangle of the whole image. If you want the entire image then leave the default value (which is an empty IntRect). If the area rectangle crosses the bounds of the image, it is adjusted to fit the image size. - * + * * The maximum size for a texture depends on the graphics driver and can be retrieved with the getMaximumSize function. - * + * * If this function fails, the texture is left unchanged. - * + * * Params: * data = Image in memory * size = Size of the data to load, in bytes. * area = Area of the image to load - * + * * Returns: True if loading was successful, false otherwise. */ bool loadFromMemory(const(void)[] data, IntRect area = IntRect()) @@ -124,7 +124,7 @@ class Texture bool ret = sfTexture_loadFromMemory(sfPtr, data.ptr, data.length,area.left, area.top,area.width, area.height); if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; @@ -132,17 +132,17 @@ class Texture /** * Load the texture from a custom stream. - * + * * The area argument can be used to load only a sub-rectangle of the whole image. If you want the entire image then leave the default value (which is an empty IntRect). If the area rectangle crosses the bounds of the image, it is adjusted to fit the image size. - * + * * The maximum size for a texture depends on the graphics driver and can be retrieved with the getMaximumSize function. - * + * * If this function fails, the texture is left unchanged. - * + * * Params: * stream = Source stream to read from * area = Area of the image to load - * + * * Returns: True if loading was successful, false otherwise. */ bool loadFromStream(InputStream stream, IntRect area = IntRect()) @@ -152,7 +152,7 @@ class Texture bool ret = sfTexture_loadFromStream(sfPtr, new textureStream(stream), area.left, area.top,area.width, area.height); if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; @@ -160,17 +160,17 @@ class Texture /** * Load the texture from an image. - * + * * The area argument can be used to load only a sub-rectangle of the whole image. If you want the entire image then leave the default value (which is an empty IntRect). If the area rectangle crosses the bounds of the image, it is adjusted to fit the image size. - * + * * The maximum size for a texture depends on the graphics driver and can be retrieved with the getMaximumSize function. - * + * * If this function fails, the texture is left unchanged. - * + * * Params: * image = Image to load into the texture * area = Area of the image to load - * + * * Returns: True if loading was successful, false otherwise. */ bool loadFromImage(Image image, IntRect area = IntRect()) @@ -180,7 +180,7 @@ class Texture bool ret = sfTexture_loadFromImage(sfPtr, image.sfPtr, area.left, area.top,area.width, area.height); if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; @@ -188,9 +188,9 @@ class Texture /** * Get the maximum texture size allowed. - * + * * This Maximum size is defined by the graphics driver. You can expect a value of 512 pixels for low-end graphics card, and up to 8192 pixels or more for newer hardware. - * + * * Returns: Maximum size allowed for textures, in pixels. */ static uint getMaximumSize() @@ -200,7 +200,7 @@ class Texture /** * Return the size of the texture. - * + * * Returns: Size in pixels. */ Vector2u getSize() const @@ -212,9 +212,9 @@ class Texture /** * Enable or disable the smooth filter. - * + * * When the filter is activated, the texture appears smoother so that pixels are less noticeable. However if you want the texture to look exactly the same as its source file, you should leave it disabled. The smooth filter is disabled by default. - * + * * Params: * smooth = True to enable smoothing, false to disable it. */ @@ -225,11 +225,11 @@ class Texture /** * Enable or disable repeating. - * + * * Repeating is involved when using texture coordinates outside the texture rectangle [0, 0, width, height]. In this case, if repeat mode is enabled, the whole texture will be repeated as many times as needed to reach the coordinate (for example, if the X texture coordinate is 3 * width, the texture will be repeated 3 times). - * + * * If repeat mode is disabled, the "extra space" will instead be filled with border pixels. Warning: on very old graphics cards, white pixels may appear when the texture is repeated. With such cards, repeat mode can be used reliably only if the texture has power-of-two dimensions (such as 256x128). Repeating is disabled by default. - * + * * Params: * repeated = True to repeat the texture, false to disable repeating */ @@ -240,9 +240,9 @@ class Texture /** * Bind a texture for rendering. - * + * * This function is not part of the graphics API, it mustn't be used when drawing SFML entities. It must be used only if you mix Texture with OpenGL code. - * + * * Params: * texture = The texture to bind. Can be null to use no texture. */ @@ -253,23 +253,23 @@ class Texture /** * Create the texture. - * + * * If this function fails, the texture is left unchanged. - * + * * Params: * width = Width of the texture * height = Height of the texture - * + * * Returns: True if creation was successful, false otherwise. */ bool create(uint width, uint height) { import dsfml.system.string; - + bool ret = sfTexture_create(sfPtr, width, height); if(!ret) { - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } return ret; @@ -277,9 +277,9 @@ class Texture /** * Copy the texture pixels to an image. - * + * * This function performs a slow operation that downloads the texture's pixels from the graphics card and copies them to a new image, potentially applying transformations to pixels if necessary (texture may be padded or flipped). - * + * * Returns: Image containing the texture's pixels. */ Image copyToImage() const @@ -289,7 +289,7 @@ class Texture /** * Creates a new texture from the same data (this means copying the entire set of pixels). - * + * * Returns: New texture data. */ @property @@ -300,7 +300,7 @@ class Texture /** * Tell whether the texture is repeated or not. - * + * * Returns: True if repeat mode is enabled, false if it is disabled. */ bool isRepeated() const @@ -310,7 +310,7 @@ class Texture /** * Tell whether the smooth filter is enabled or not. - * + * * Returns: True if something is enabled, false if it is disabled. */ bool isSmooth() const @@ -320,13 +320,13 @@ class Texture /** * Update the texture from an image. - * + * * Although the source image can be smaller than the texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of the texture. - * + * * No additional check is performed on the size of the image, passing an image bigger than the texture will lead to an undefined behaviour. - * + * * This function does nothing if the texture was not previously created. - * + * * Params: * image = Image to copy to the texture. */ @@ -337,13 +337,13 @@ class Texture /** * Update part of the texture from an array of pixels. - * + * * The size of the pixel array must match the width and height arguments, and it must contain 32-bits RGBA pixels. - * + * * No additional check is performed on the size of the pixel array or the bounds of the area to update, passing invalid arguments will lead to an undefined behaviour. - * + * * This function does nothing if pixels is null or if the texture was not previously created. - * + * * Params: * pixels = Array of pixels to copy to the texture. * width = Width of the pixel region contained in pixels @@ -359,11 +359,11 @@ class Texture //TODO: Get this working via inheritance?(so custom window classes can do it too) /** * Update a part of the texture from the contents of a window. - * + * * No additional check is performed on the size of the window, passing an invalid combination of window size and offset will lead to an undefined behaviour. - * + * * This function does nothing if either the texture or the window was not previously created. - * + * * Params: * window = Window to copy to the texture * x = X offset in the texture where to copy the source window @@ -377,11 +377,11 @@ class Texture //Is this even safe? RenderWindow inherits from Window, so what happens? Is this bottom used or the top? /** * Update a part of the texture from the contents of a window. - * + * * No additional check is performed on the size of the window, passing an invalid combination of window size and offset will lead to an undefined behaviour. - * + * * This function does nothing if either the texture or the window was not previously created. - * + * * Params: * window = Window to copy to the texture * x = X offset in the texture where to copy the source window @@ -398,7 +398,7 @@ unittest version(DSFML_Unittest_Graphics) { import std.stdio; - + writeln("Unit test for Texture"); auto texture = new Texture(); @@ -414,11 +414,11 @@ unittest private extern(C++) interface textureInputStream { long read(void* data, long size); - + long seek(long position); - + long tell(); - + long getSize(); } @@ -441,12 +441,12 @@ private class textureStream:textureInputStream { return myStream.seek(position); } - + extern(C++)long tell() { return myStream.tell(); } - + extern(C++)long getSize() { return myStream.getSize(); diff --git a/src/dsfml/network/ftp.d b/src/dsfml/network/ftp.d index 6eca495..61f208c 100644 --- a/src/dsfml/network/ftp.d +++ b/src/dsfml/network/ftp.d @@ -37,16 +37,16 @@ class Ftp ///Enumeration of transfer modes. enum TransferMode { - ///Binary mode (file is transfered as a sequence of bytes) + ///Binary mode (file is transfered as a sequence of bytes) Binary, ///Text mode using ASCII encoding. Ascii, - ///Text mode using EBCDIC encoding. + ///Text mode using EBCDIC encoding. Ebcdic, } - + package sfFtp* sfPtr; - + ///Default Constructor. this() { @@ -71,7 +71,7 @@ class Ftp { return new DirectoryResponse(sfFtp_getWorkingDirectory(sfPtr)); } - + ///Get the contents of the given directory. /// ///This function retrieves the sub-directories and files contained in the given directory. It is not recursive. The directory parameter is relative to the current working directory. @@ -197,7 +197,7 @@ class Ftp { return new Response(sfFtp_loginAnonymous(sfPtr)); } - + ///Log in using a username and a password. /// ///Logging in is mandatory after connecting to the server. Users that are not logged in cannot perform any operation. @@ -213,7 +213,7 @@ class Ftp return new Response(sfFtp_login(sfPtr,toStringz(name), toStringz(password))); } - ///Go to the parent directory of the current one. + ///Go to the parent directory of the current one. /// ///Returns: Server response to the request. Response parentDirectory() @@ -266,7 +266,7 @@ class Ftp import dsfml.system.string; return new Response(sfFtp_upload(sfPtr,toStringz(localFile),toStringz(remotePath),mode)); } - + ///Send a command to the FTP server. /// ///While the most often used commands are provided as member functions in the Ftp class, this method can be used to send any FTP command to the server. If the command requires one or more parameters, they can be specified in parameter. If the server returns information, you can extract it from the response using getMessage(). @@ -290,11 +290,11 @@ class Ftp package this(sfFtpDirectoryResponse* FtpDirectoryResponce) { import dsfml.system.string; - - Directory = toString(sfFtpDirectoryResponse_getDirectory(FtpDirectoryResponce)); - + + Directory = dsfml.system.string.toString(sfFtpDirectoryResponse_getDirectory(FtpDirectoryResponce)); + super(sfFtpDirectoryResponse_getStatus(FtpDirectoryResponce), sfFtpDirectoryResponse_getMessage(FtpDirectoryResponce)); - + sfFtpDirectoryResponse_destroy(FtpDirectoryResponce); } @@ -306,8 +306,8 @@ class Ftp return Directory; } } - - ///Specialization of FTP response returning a filename lisiting. + + ///Specialization of FTP response returning a filename lisiting. class ListingResponse:Response { private string[] Filenames; @@ -320,15 +320,15 @@ class Ftp Filenames.length = sfFtpListingResponse_getCount(FtpListingResponce); for(int i = 0; i < Filenames.length; i++) { - Filenames[i] = toString(sfFtpListingResponse_getName(FtpListingResponce,i)); + Filenames[i] = dsfml.system.string.toString(sfFtpListingResponse_getName(FtpListingResponce,i)); } - + super(sfFtpListingResponse_getStatus(FtpListingResponce), sfFtpListingResponse_getMessage(FtpListingResponce)); - + sfFtpListingResponse_destroy(FtpListingResponce); - + } - + ///Return the array of directory/file names. /// ///Returns: Array containing the requested listing. @@ -337,8 +337,8 @@ class Ftp return Filenames; } } - - ///Define a FTP response. + + ///Define a FTP response. class Response { ///Status codes possibly returned by a FTP response. @@ -348,7 +348,7 @@ class Ftp ServiceReadySoon = 120, DataConnectionAlreadyOpened = 125, OpeningDataConnection = 150, - + Ok = 200, PointlessCommand = 202, SystemStatus = 211, @@ -364,7 +364,7 @@ class Ftp LoggedIn = 230, FileActionOk = 250, DirectoryOk = 257, - + NeedPassword = 331, NeedAccountToLogIn = 332, NeedInformation = 350, @@ -374,7 +374,7 @@ class Ftp FileActionAborted = 450, LocalError = 451, InsufficientStorageSpace = 452, - + CommandUnknown = 500, ParametersUnknown = 501, CommandNotImplemented = 502, @@ -386,7 +386,7 @@ class Ftp PageTypeUnknown = 551, NotEnoughMemory = 552, FilenameNotAllowed = 553, - + InvalidResponse = 1000, ConnectionFailed = 1001, ConnectionClosed = 1002, @@ -408,20 +408,20 @@ class Ftp { import dsfml.system.string; FtpStatus = status; - Message = toString(message); + Message = dsfml.system.string.toString(message); } ///Get the full message contained in the response. /// - ///Returns: The response message. + ///Returns: The dsfml.system.string.toString( message. string getMessage() const { return Message; } - + ///Get the status code of the response. /// - ///Returns: Status code. + ///Returns: Status code. Status getStatus() const { return FtpStatus; diff --git a/src/dsfml/network/http.d b/src/dsfml/network/http.d index cfb1e38..674ee00 100644 --- a/src/dsfml/network/http.d +++ b/src/dsfml/network/http.d @@ -32,7 +32,7 @@ import core.time; class Http { package sfHttp* sfPtr; - + ///Default constructor this() { @@ -45,14 +45,14 @@ class Http /// ///Params: /// host = Web server to connect to. - /// port = Port to use for connection. + /// port = Port to use for connection. this(string host, ushort port = 0) { import dsfml.system.string; sfPtr = sfHttp_create(); sfHttp_setHost(sfPtr, toStringz(host),port); } - + ///Destructor ~this() { @@ -60,14 +60,14 @@ class Http mixin(destructorOutput); sfHttp_destroy(sfPtr); } - + ///Set the target host. /// ///This function just stores the host address and port, it doesn't actually connect to it until you send a request. The port has a default value of 0, which means that the HTTP client will use the right port according to the protocol used (80 for HTTP, 443 for HTTPS). You should leave it like this unless you really need a port other than the standard one, or use an unknown protocol. /// ///Params: /// host = Web server to connect to. - /// port = Port to use for connection. + /// port = Port to use for connection. void setHost(string host, ushort port = 0) { import dsfml.system.string; @@ -85,18 +85,18 @@ class Http { return new Response(sfHttp_sendRequest(sfPtr,request.sfPtrRequest,timeout.total!"usecs")); } - - ///Define a HTTP request. + + ///Define a HTTP request. static class Request { - ///Enumerate the available HTTP methods for a request. + ///Enumerate the available HTTP methods for a request. enum Method { - ///Request in get mode, standard method to retrieve a page. + ///Request in get mode, standard method to retrieve a page. Get, ///Request in post mode, usually to send data to a page. Post, - ///Request a page's header only. + ///Request a page's header only. Head, ///Request in put mode, useful for a REST API Put, @@ -120,7 +120,7 @@ class Http sfHttpRequest_setMethod(sfPtrRequest, method); sfHttpRequest_setBody(sfPtrRequest,toStringz(requestBody)); } - + ///Destructor ~this() { @@ -176,7 +176,7 @@ class Http { sfHttpRequest_setMethod(sfPtrRequest,method); } - + ///Set the requested URI. /// ///The URI is the resource (usually a web page or a file) that you want to get or post. The URI is "/" (the root page) by default. @@ -189,7 +189,7 @@ class Http sfHttpRequest_setUri(sfPtrRequest,toStringz(uri)); } } - + ///Define a HTTP response. class Response { @@ -223,7 +223,7 @@ class Http InvalidResponse = 1000, ConnectionFailed = 1001 - + } package sfHttpResponse* sfPtrResponse; @@ -240,7 +240,7 @@ class Http string getBody() { import dsfml.system.string; - return toString(sfHttpResponse_getBody(sfPtrResponse)); + return dsfml.system.string.toString(sfHttpResponse_getBody(sfPtrResponse)); } ///Get the value of a field. @@ -254,7 +254,7 @@ class Http string getField(string field) { import dsfml.system.string; - return toString(sfHttpResponse_getField(sfPtrResponse,toStringz(field))); + return dsfml.system.string.toString(sfHttpResponse_getField(sfPtrResponse,toStringz(field))); } ///Get the major HTTP version number of the response. @@ -264,15 +264,15 @@ class Http { return sfHttpResponse_getMajorVersion(sfPtrResponse); } - - ///Get the minor HTTP version number of the response. + + ///Get the minor HTTP version number of the response. /// ///Returns: Minor HTTP version number. uint getMinorHttpVersion() { return sfHttpResponse_getMinorVersion(sfPtrResponse); } - + ///Get the response status code. /// ///The status code should be the first thing to be checked after receiving a response, it defines whether it is a success, a failure or anything else (see the Status enumeration). @@ -290,13 +290,13 @@ unittest version(DSFML_Unittest_Network) { import std.stdio; - + writeln("Unittest for Http"); auto http = new Http(); http.setHost("http://www.sfml-dev.org"); - + // Prepare a request to get the 'features.php' page auto request = new Http.Request("learn.php"); @@ -313,7 +313,7 @@ unittest else { writeln("Error: ", status); - } + } writeln(); } } @@ -326,71 +326,71 @@ struct sfHttp; ///Create a new HTTP request sfHttpRequest* sfHttpRequest_create(); - - + + ///Destroy a HTTP request void sfHttpRequest_destroy(sfHttpRequest* httpRequest); - - + + ///Set the value of a header field of a HTTP request void sfHttpRequest_setField(sfHttpRequest* httpRequest, const(char)* field, const(char)* value); - - + + ///Set a HTTP request method void sfHttpRequest_setMethod(sfHttpRequest* httpRequest, int method); - - + + ///Set a HTTP request URI void sfHttpRequest_setUri(sfHttpRequest* httpRequest, const(char)* uri); - - + + ///Set the HTTP version of a HTTP request void sfHttpRequest_setHttpVersion(sfHttpRequest* httpRequest,uint major, uint minor); - - + + ///Set the body of a HTTP request void sfHttpRequest_setBody(sfHttpRequest* httpRequest, const(char)* ody); - - + + //HTTP Response Functions - + ///Destroy a HTTP response void sfHttpResponse_destroy(sfHttpResponse* httpResponse); - - + + ///Get the value of a field of a HTTP response const(char)* sfHttpResponse_getField(const sfHttpResponse* httpResponse, const(char)* field); - - + + ///Get the status code of a HTTP reponse Http.Response.Status sfHttpResponse_getStatus(const sfHttpResponse* httpResponse); - - + + ///Get the major HTTP version number of a HTTP response uint sfHttpResponse_getMajorVersion(const sfHttpResponse* httpResponse); - - + + ///Get the minor HTTP version number of a HTTP response uint sfHttpResponse_getMinorVersion(const sfHttpResponse* httpResponse); - - + + ///Get the body of a HTTP response const(char)* sfHttpResponse_getBody(const sfHttpResponse* httpResponse); - - + + //HTTP Functions - + ///Create a new Http object sfHttp* sfHttp_create(); - - + + ///Destroy a Http object void sfHttp_destroy(sfHttp* http); - - + + ///Set the target host of a HTTP object void sfHttp_setHost(sfHttp* http, const(char)* host, ushort port); - - + + ///Send a HTTP request and return the server's response. sfHttpResponse* sfHttp_sendRequest(sfHttp* http, const(sfHttpRequest)* request, long timeout); diff --git a/src/dsfml/network/tcplistener.d b/src/dsfml/network/tcplistener.d index c229f22..687bc11 100644 --- a/src/dsfml/network/tcplistener.d +++ b/src/dsfml/network/tcplistener.d @@ -48,7 +48,7 @@ class TcpListener:Socket { sfPtr = sfTcpListener_create(); } - + ///Destructor ~this() { @@ -67,7 +67,7 @@ class TcpListener:Socket return sfTcpListener_getLocalPort(sfPtr); } - ///Tell whether the socket is in blocking or non-blocking mode. + ///Tell whether the socket is in blocking or non-blocking mode. /// ///In blocking mode, calls will not return until they have completed their task. For example, a call to Receive in blocking mode won't return until some data was actually received. In non-blocking mode, calls will always return immediately, using the return code to signal whether there was data available or not. By default, all sockets are blocking. /// @@ -90,9 +90,9 @@ class TcpListener:Socket { import dsfml.system.string; - Status toReturn = sfTcpListener_accept(sfPtr, socket.sfPtr); - err.write(toString(sfErr_getOutput())); - return toReturn; + Status toReturn = sfTcpListener_accept(sfPtr, socket.sfPtr); + err.write(dsfml.system.string.toString(sfErr_getOutput())); + return toReturn; } ///Start listening for connections. @@ -108,7 +108,7 @@ class TcpListener:Socket import dsfml.system.string; Status toReturn = sfTcpListener_listen(sfPtr, port); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); return toReturn; } @@ -134,7 +134,7 @@ unittest writeln("Unittest for Listener"); //socket connecting to server auto clientSocket = new TcpSocket(); - + //listener looking for new sockets auto listener = new TcpListener(); listener.listen(55002); @@ -147,11 +147,11 @@ unittest //socket on the server side connected to the client's socket auto serverSocket = new TcpSocket(); - + //accepts a new connection and binds it to the socket in the parameter listener.accept(serverSocket); - + clientSocket.disconnect(); writeln(); } diff --git a/src/dsfml/network/tcpsocket.d b/src/dsfml/network/tcpsocket.d index 2e8ae04..74d47db 100644 --- a/src/dsfml/network/tcpsocket.d +++ b/src/dsfml/network/tcpsocket.d @@ -49,13 +49,13 @@ import dsfml.system.err; class TcpSocket:Socket { package sfTcpSocket* sfPtr; - + ///Default constructor this() { sfPtr = sfTcpSocket_create(); } - + ///Destructor ~this() { @@ -82,9 +82,9 @@ class TcpSocket:Socket IpAddress getRemoteAddress() { IpAddress temp; - + sfTcpSocket_getRemoteAddress(sfPtr,temp.m_address.ptr); - + return temp; } @@ -125,7 +125,7 @@ class TcpSocket:Socket { return sfTcpSocket_connect(sfPtr, host.m_address.ptr,port, timeout.total!"usecs"); } - + ///Disconnect the socket from its remote peer. /// ///This function gracefully closes the connection. If the socket is not connected, this function has no effect. @@ -134,7 +134,7 @@ class TcpSocket:Socket sfTcpSocket_disconnect(sfPtr); } - ///Tell whether the socket is in blocking or non-blocking mode. + ///Tell whether the socket is in blocking or non-blocking mode. /// ///Returns: True if the socket is blocking, false otherwise. bool isBlocking() @@ -155,7 +155,7 @@ class TcpSocket:Socket import dsfml.system.string; Status toReturn = sfTcpSocket_send(sfPtr, data.ptr, data.length); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); return toReturn; } @@ -236,29 +236,29 @@ unittest //socket connecting to server auto clientSocket = new TcpSocket(); - + //listener looking for new sockets auto listener = new TcpListener(); listener.listen(55003); - + //get our client socket to connect to the server clientSocket.connect(IpAddress.LocalHost, 55003); - - - + + + //packet to send data auto sendPacket = new Packet(); - - + + //Packet to receive data auto receivePacket = new Packet(); - + //socket on the server side connected to the client's socket auto serverSocket = new TcpSocket(); - + //accepts a new connection and binds it to the socket in the parameter listener.accept(serverSocket); - + string temp = "I'm sending you stuff!"; //Let's greet the server! @@ -266,7 +266,7 @@ unittest //clientSocket.send(sendPacket); clientSocket.send(temp); - + //And get the data on the server side //serverSocket.receive(receivePacket); @@ -274,17 +274,17 @@ unittest size_t received; serverSocket.receive(temp2, received); - + //What did we get from the client? writeln("Gotten from client: ", cast(string)temp2[0..received]); - + //clear the packets to send/get new information sendPacket.clear(); receivePacket.clear(); - + //Respond back to the client sendPacket.write("Hello, I'm your server."); - + serverSocket.send(sendPacket); clientSocket.receive(receivePacket); @@ -293,7 +293,7 @@ unittest string message; receivePacket.read!string(message); writeln("Gotten from server: ", message); - + clientSocket.disconnect(); writeln(); } diff --git a/src/dsfml/network/udpsocket.d b/src/dsfml/network/udpsocket.d index 1b7df3b..bba5886 100644 --- a/src/dsfml/network/udpsocket.d +++ b/src/dsfml/network/udpsocket.d @@ -57,7 +57,7 @@ class UdpSocket:Socket { sfPtr = sfUdpSocket_create(); } - + ///Destructor ~this() { @@ -98,13 +98,13 @@ class UdpSocket:Socket Status bind(ushort port) { import dsfml.system.string; - + Status toReturn = sfUdpSocket_bind(sfPtr,port); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); return toReturn; } - ///Tell whether the socket is in blocking or non-blocking mode. + ///Tell whether the socket is in blocking or non-blocking mode. /// ///Returns: True if the socket is blocking, false otherwise. bool isBlocking() @@ -143,10 +143,10 @@ class UdpSocket:Socket { //temporary packet to be removed on function exit scope SfPacket temp = new SfPacket(); - + //getting packet's "to send" data temp.append(packet.onSend()); - + //send the data return sfUdpSocket_sendPacket(sfPtr, temp.sfPtr,address.m_address.ptr,port); } @@ -166,13 +166,13 @@ class UdpSocket:Socket Status receive(void[] data, out size_t sizeReceived, out IpAddress address, out ushort port) { import dsfml.system.string; - + Status status; void* temp = sfUdpSocket_receive(sfPtr, data.length, &sizeReceived, address.m_address.ptr, &port, &status); - - err.write(toString(sfErr_getOutput())); - + + err.write(dsfml.system.string.toString(sfErr_getOutput())); + data[0..sizeReceived] = temp[0..sizeReceived].dup; return status; @@ -198,10 +198,10 @@ class UdpSocket:Socket //put data into the packet so that it can process it first if it wants. packet.onRecieve(temp.getData()); - + return status; } - + ///Unbind the socket from the local port to which it is bound. /// ///The port that the socket was previously using is immediately available after this function is called. If the socket is not bound to a port, this function has no effect. @@ -209,7 +209,7 @@ class UdpSocket:Socket { sfUdpSocket_unbind(sfPtr); } - + } unittest @@ -217,7 +217,7 @@ unittest version(DSFML_Unittest_Network) { import std.stdio; - + writeln("Unittest for Udp Socket"); auto clientSocket = new UdpSocket(); diff --git a/src/dsfml/window/window.d b/src/dsfml/window/window.d index ddf9daf..bb50a66 100644 --- a/src/dsfml/window/window.d +++ b/src/dsfml/window/window.d @@ -76,7 +76,7 @@ class Window sfWindow_destroy(sfPtr); m_needsToDelete = false; } - + //TODO: Reduce to one constructor with a template parameter for the string types. Use sfWindow_createUnicode in case it has unicode in the title. //in order to envoke this constructor when using string literals, be sure to use the d suffix, i.e. "素晴らしい !"d @@ -115,7 +115,7 @@ class Window this(); create(handle, settings); } - + ~this() { import dsfml.system.config; @@ -138,7 +138,7 @@ class Window sfWindow_setPosition(sfPtr,newPosition.x, newPosition.y); return newPosition; } - + Vector2i position() { Vector2i temp; @@ -146,7 +146,7 @@ class Window return temp; } } - + ///Get's or set's the window's size. @property { @@ -175,16 +175,16 @@ class Window { import dsfml.system.string; bool toReturn = sfWindow_setActive(sfPtr, active); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); return toReturn; } - + ///Request the current window to be made the active foreground window. void requestFocus() { sfWindow_requestFocus(sfPtr); } - + ///Check whether the window has the input focus /// ///Returns: True if the window has focus, false otherwise @@ -192,7 +192,7 @@ class Window { return sfWindow_hasFocus(sfPtr); } - + ///Limit the framerate to a maximum fixed frequency. /// ///If a limit is set, the window will use a small delay after each call to display() to ensure that the current frame lasted long enough to match the framerate limit. SFML will try to match the given limit as much as it can, but since it internally uses sf::sleep, whose precision depends on the underlying OS, the results may be a little unprecise as well (for example, you can get 65 FPS when requesting 60). @@ -296,7 +296,7 @@ class Window { sfWindow_setVisible(sfPtr,visible); } - + ///Enable or disable vertical synchronization. /// ///Activating vertical synchronization will limit the number of frames displayed to the refresh rate of the monitor. This can avoid some visual artifacts, and limit the framerate to a good value (but not constant across different computers). @@ -355,7 +355,7 @@ class Window { import dsfml.system.string; sfWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, toStringz(stringConvert!(char,dchar)(title)), style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } ///Create (or recreate) the window. /// @@ -366,7 +366,7 @@ class Window { import dsfml.system.string; sfWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, toStringz(stringConvert!(wchar,dchar)(title)), style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } ///Create (or recreate) the window. /// @@ -377,7 +377,7 @@ class Window { import dsfml.system.string; sfWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, toStringz(title), style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } ///Create (or recreate) the window from an existing control. @@ -389,7 +389,7 @@ class Window { import dsfml.system.string; sfWindow_createFromHandle(sfPtr, handle, settings.depthBits,settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); - err.write(toString(sfErr_getOutput())); + err.write(dsfml.system.string.toString(sfErr_getOutput())); } ///Display on screen what has been rendered to the window so far. @@ -412,7 +412,7 @@ class Window ///Pop the event on top of the event queue, if any, and return it. /// - ///This function is not blocking: if there's no pending event then it will return false and leave event unmodified. Note that more than one event may be present in the event queue, thus you should always call this function in a loop to make sure that you process every pending event. + ///This function is not blocking: if there's no pending event then it will return false and leave event unmodified. Note that more than one event may be present in the event queue, thus you should always call this function in a loop to make sure that you process every pending event. /// ///Params: /// event = Event to be returned. @@ -422,10 +422,10 @@ class Window { return (sfWindow_pollEvent(sfPtr, &event)); } - + ///Wait for an event and return it. /// - ///This function is blocking: if there's no pending event then it will wait until an event is received. After this function returns (and no error occured), the event object is always valid and filled properly. This function is typically used when you have a thread that is dedicated to events handling: you want to make this thread sleep as long as no new event is received. + ///This function is blocking: if there's no pending event then it will wait until an event is received. After this function returns (and no error occured), the event object is always valid and filled properly. This function is typically used when you have a thread that is dedicated to events handling: you want to make this thread sleep as long as no new event is received. /// ///Params: /// event = Event to be returned. @@ -438,7 +438,7 @@ class Window //TODO: Clean this shit up. The names are so bad. :( - //Gives a way for RenderWindow to send its mouse position + //Gives a way for RenderWindow to send its mouse position protected Vector2i getMousePosition()const { Vector2i temp; @@ -470,7 +470,7 @@ class Window return window.sfPtr; } - + } unittest @@ -612,10 +612,10 @@ private extern(C): //Activate or deactivate a window as the current target for OpenGL rendering bool sfWindow_setActive(sfWindow* window, bool active); - + //Request the current window to be made the active foreground window. void sfWindow_requestFocus(sfWindow* window); - + //Check whether the window has the input focus bool sfWindow_hasFocus(const(sfWindow)* window); @@ -627,8 +627,8 @@ private extern(C): //Change the joystick threshold void sfWindow_setJoystickThreshold(sfWindow* window, float threshold); - - + + //Get the OS-specific handle of the window WindowHandle sfWindow_getSystemHandle(const(sfWindow)* window); From c86e4e2469c9ca095fc6aad1428264f57cbd0d6f Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Wed, 6 Apr 2016 23:54:46 -0700 Subject: [PATCH 16/27] bump DSFML Version number --- src/dsfml/system/config.d | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dsfml/system/config.d b/src/dsfml/system/config.d index ebaa9c9..9cb8594 100644 --- a/src/dsfml/system/config.d +++ b/src/dsfml/system/config.d @@ -30,7 +30,7 @@ static if (__VERSION__ < 2064L) enum { DSFML_VERSION_MAJOR = 2, - DSFML_VERSION_MINOR = 1 + DSFML_VERSION_MINOR = 3 } //destructor output for mixing in. @@ -42,6 +42,6 @@ enum destructorOutput =` } else { - + }`; From 7f64a557e39417e66b57b980855e12fd5d73887e Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Fri, 8 Apr 2016 18:37:04 -0700 Subject: [PATCH 17/27] Texture.flush() method --- src/dsfml/graphics/texture.d | 1051 +++++++++++++++++----------------- 1 file changed, 529 insertions(+), 522 deletions(-) diff --git a/src/dsfml/graphics/texture.d b/src/dsfml/graphics/texture.d index fbcd04f..c53a097 100644 --- a/src/dsfml/graphics/texture.d +++ b/src/dsfml/graphics/texture.d @@ -1,522 +1,529 @@ -/* -DSFML - The Simple and Fast Multimedia Library for D - -Copyright (c) 2013 - 2015 Jeremy DeHaan (dehaan.jeremiah@gmail.com) - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, including commercial applications, -and to alter it and redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. -If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source distribution -*/ - -module dsfml.graphics.texture; - - -import dsfml.graphics.rect; -import dsfml.graphics.image; -import dsfml.graphics.renderwindow; - -import dsfml.window.window; - -import dsfml.system.inputstream; -import dsfml.system.vector2; -import dsfml.system.err; - -/++ - + Image living on the graphics card that can be used for drawing. - + - + Texture stores pixels that can be drawn, with a sprite for example. - + - + A texture lives in the graphics card memory, therefore it is very fast to draw a texture to a render target, or copy a render target to a texture (the graphics card can access both directly). - + - + Being stored in the graphics card memory has some drawbacks. A texture cannot be manipulated as freely as a Image, you need to prepare the pixels first and then upload them to the texture in a single operation (see Texture::update). - + - + Texture makes it easy to convert from/to Image, but keep in mind that these calls require transfers between the graphics card and the central memory, therefore they are slow operations. - + - + A texture can be loaded from an image, but also directly from a file/memory/stream. The necessary shortcuts are defined so that you don't need an image first for the most common cases. However, if you want to perform some modifications on the pixels before creating the final texture, you can load your file to a Image, do whatever you need with the pixels, and then call Texture::loadFromImage. - + - + Since they live in the graphics card memory, the pixels of a texture cannot be accessed without a slow copy first. And they cannot be accessed individually. Therefore, if you need to read the texture's pixels (like for pixel-perfect collisions), it is recommended to store the collision information separately, for example in an array of booleans. - + - + Like Image, Texture can handle a unique internal representation of pixels, which is RGBA 32 bits. This means that a pixel must be composed of 8 bits red, green, blue and alpha channels – just like a Color. - + - + Authors: Laurent Gomila, Jeremy DeHaan - + See_Also: http://www.sfml-dev.org/documentation/2.0/classsf_1_1Texture.php#details - +/ -class Texture -{ - package sfTexture* sfPtr; - - this() - { - sfPtr = sfTexture_construct(); - } - - package this(sfTexture* texturePointer) - { - sfPtr = texturePointer; - } - - ~this() - { - import dsfml.system.config; - mixin(destructorOutput); - sfTexture_destroy( sfPtr); - } - - /** - * Load the texture from a file on disk. - * - * The area argument can be used to load only a sub-rectangle of the whole image. If you want the entire image then leave the default value (which is an empty IntRect). If the area rectangle crosses the bounds of the image, it is adjusted to fit the image size. - * - * The maximum size for a texture depends on the graphics driver and can be retrieved with the getMaximumSize function. - * - * If this function fails, the texture is left unchanged. - * - * Params: - * filename = Path of the image file to load - * area = Area of the image to load - * - * Returns: True if loading was successful, false otherwise. - */ - bool loadFromFile(string filename, IntRect area = IntRect() ) - { - import dsfml.system.string; - - bool ret = sfTexture_loadFromFile(sfPtr, toStringz(filename) ,area.left, area.top,area.width, area.height); - if(!ret) - { - err.write(dsfml.system.string.toString(sfErr_getOutput())); - } - - return ret; - } - - //TODO: Can this be done with a slice of bytes rather than a const(void)*? - /** - * Load the texture from a file in memory. - * - * The area argument can be used to load only a sub-rectangle of the whole image. If you want the entire image then leave the default value (which is an empty IntRect). If the area rectangle crosses the bounds of the image, it is adjusted to fit the image size. - * - * The maximum size for a texture depends on the graphics driver and can be retrieved with the getMaximumSize function. - * - * If this function fails, the texture is left unchanged. - * - * Params: - * data = Image in memory - * size = Size of the data to load, in bytes. - * area = Area of the image to load - * - * Returns: True if loading was successful, false otherwise. - */ - bool loadFromMemory(const(void)[] data, IntRect area = IntRect()) - { - import dsfml.system.string; - - - bool ret = sfTexture_loadFromMemory(sfPtr, data.ptr, data.length,area.left, area.top,area.width, area.height); - if(!ret) - { - err.write(dsfml.system.string.toString(sfErr_getOutput())); - } - - return ret; - } - - /** - * Load the texture from a custom stream. - * - * The area argument can be used to load only a sub-rectangle of the whole image. If you want the entire image then leave the default value (which is an empty IntRect). If the area rectangle crosses the bounds of the image, it is adjusted to fit the image size. - * - * The maximum size for a texture depends on the graphics driver and can be retrieved with the getMaximumSize function. - * - * If this function fails, the texture is left unchanged. - * - * Params: - * stream = Source stream to read from - * area = Area of the image to load - * - * Returns: True if loading was successful, false otherwise. - */ - bool loadFromStream(InputStream stream, IntRect area = IntRect()) - { - import dsfml.system.string; - - bool ret = sfTexture_loadFromStream(sfPtr, new textureStream(stream), area.left, area.top,area.width, area.height); - if(!ret) - { - err.write(dsfml.system.string.toString(sfErr_getOutput())); - } - - return ret; - } - - /** - * Load the texture from an image. - * - * The area argument can be used to load only a sub-rectangle of the whole image. If you want the entire image then leave the default value (which is an empty IntRect). If the area rectangle crosses the bounds of the image, it is adjusted to fit the image size. - * - * The maximum size for a texture depends on the graphics driver and can be retrieved with the getMaximumSize function. - * - * If this function fails, the texture is left unchanged. - * - * Params: - * image = Image to load into the texture - * area = Area of the image to load - * - * Returns: True if loading was successful, false otherwise. - */ - bool loadFromImage(Image image, IntRect area = IntRect()) - { - import dsfml.system.string; - - bool ret = sfTexture_loadFromImage(sfPtr, image.sfPtr, area.left, area.top,area.width, area.height); - if(!ret) - { - err.write(dsfml.system.string.toString(sfErr_getOutput())); - } - - return ret; - } - - /** - * Get the maximum texture size allowed. - * - * This Maximum size is defined by the graphics driver. You can expect a value of 512 pixels for low-end graphics card, and up to 8192 pixels or more for newer hardware. - * - * Returns: Maximum size allowed for textures, in pixels. - */ - static uint getMaximumSize() - { - return sfTexture_getMaximumSize(); - } - - /** - * Return the size of the texture. - * - * Returns: Size in pixels. - */ - Vector2u getSize() const - { - Vector2u temp; - sfTexture_getSize(sfPtr, &temp.x, &temp.y); - return temp; - } - - /** - * Enable or disable the smooth filter. - * - * When the filter is activated, the texture appears smoother so that pixels are less noticeable. However if you want the texture to look exactly the same as its source file, you should leave it disabled. The smooth filter is disabled by default. - * - * Params: - * smooth = True to enable smoothing, false to disable it. - */ - void setSmooth(bool smooth) - { - sfTexture_setSmooth(sfPtr, smooth);//:sfTexture_setSmooth(sfPtr, sfFalse); - } - - /** - * Enable or disable repeating. - * - * Repeating is involved when using texture coordinates outside the texture rectangle [0, 0, width, height]. In this case, if repeat mode is enabled, the whole texture will be repeated as many times as needed to reach the coordinate (for example, if the X texture coordinate is 3 * width, the texture will be repeated 3 times). - * - * If repeat mode is disabled, the "extra space" will instead be filled with border pixels. Warning: on very old graphics cards, white pixels may appear when the texture is repeated. With such cards, repeat mode can be used reliably only if the texture has power-of-two dimensions (such as 256x128). Repeating is disabled by default. - * - * Params: - * repeated = True to repeat the texture, false to disable repeating - */ - void setRepeated(bool repeated) - { - sfTexture_setRepeated(sfPtr, repeated);//:sfTexture_setRepeated(sfPtr, sfFalse); - } - - /** - * Bind a texture for rendering. - * - * This function is not part of the graphics API, it mustn't be used when drawing SFML entities. It must be used only if you mix Texture with OpenGL code. - * - * Params: - * texture = The texture to bind. Can be null to use no texture. - */ - static void bind(Texture texture) - { - (texture is null)?sfTexture_bind(null):sfTexture_bind(texture.sfPtr); - } - - /** - * Create the texture. - * - * If this function fails, the texture is left unchanged. - * - * Params: - * width = Width of the texture - * height = Height of the texture - * - * Returns: True if creation was successful, false otherwise. - */ - bool create(uint width, uint height) - { - import dsfml.system.string; - - bool ret = sfTexture_create(sfPtr, width, height); - if(!ret) - { - err.write(dsfml.system.string.toString(sfErr_getOutput())); - } - - return ret; - } - - /** - * Copy the texture pixels to an image. - * - * This function performs a slow operation that downloads the texture's pixels from the graphics card and copies them to a new image, potentially applying transformations to pixels if necessary (texture may be padded or flipped). - * - * Returns: Image containing the texture's pixels. - */ - Image copyToImage() const - { - return new Image(sfTexture_copyToImage(sfPtr)); - } - - /** - * Creates a new texture from the same data (this means copying the entire set of pixels). - * - * Returns: New texture data. - */ - @property - Texture dup() const - { - return new Texture(sfTexture_copy(sfPtr)); - } - - /** - * Tell whether the texture is repeated or not. - * - * Returns: True if repeat mode is enabled, false if it is disabled. - */ - bool isRepeated() const - { - return (sfTexture_isRepeated(sfPtr));// == sfTrue)?true:false; - } - - /** - * Tell whether the smooth filter is enabled or not. - * - * Returns: True if something is enabled, false if it is disabled. - */ - bool isSmooth() const - { - return (sfTexture_isSmooth(sfPtr));// == sfTrue)?true:false; - } - - /** - * Update the texture from an image. - * - * Although the source image can be smaller than the texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of the texture. - * - * No additional check is performed on the size of the image, passing an image bigger than the texture will lead to an undefined behaviour. - * - * This function does nothing if the texture was not previously created. - * - * Params: - * image = Image to copy to the texture. - */ - void updateFromImage(Image image, uint x, uint y) - { - sfTexture_updateFromImage(sfPtr, image.sfPtr, x, y); - } - - /** - * Update part of the texture from an array of pixels. - * - * The size of the pixel array must match the width and height arguments, and it must contain 32-bits RGBA pixels. - * - * No additional check is performed on the size of the pixel array or the bounds of the area to update, passing invalid arguments will lead to an undefined behaviour. - * - * This function does nothing if pixels is null or if the texture was not previously created. - * - * Params: - * pixels = Array of pixels to copy to the texture. - * width = Width of the pixel region contained in pixels - * height = Height of the pixel region contained in pixels - * x = X offset in the texture where to copy the source pixels - * y = Y offset in the texture where to copy the source pixels - */ - void updateFromPixels(const(ubyte)[] pixels, uint width, uint height, uint x, uint y) - { - sfTexture_updateFromPixels(sfPtr,pixels.ptr,width, height, x,y); - } - - //TODO: Get this working via inheritance?(so custom window classes can do it too) - /** - * Update a part of the texture from the contents of a window. - * - * No additional check is performed on the size of the window, passing an invalid combination of window size and offset will lead to an undefined behaviour. - * - * This function does nothing if either the texture or the window was not previously created. - * - * Params: - * window = Window to copy to the texture - * x = X offset in the texture where to copy the source window - * y = Y offset in the texture where to copy the source window - */ - void updateFromWindow(Window window, uint x, uint y) - { - sfTexture_updateFromWindow(sfPtr, RenderWindow.windowPointer(window), x, y); - } - - //Is this even safe? RenderWindow inherits from Window, so what happens? Is this bottom used or the top? - /** - * Update a part of the texture from the contents of a window. - * - * No additional check is performed on the size of the window, passing an invalid combination of window size and offset will lead to an undefined behaviour. - * - * This function does nothing if either the texture or the window was not previously created. - * - * Params: - * window = Window to copy to the texture - * x = X offset in the texture where to copy the source window - * y = Y offset in the texture where to copy the source window - */ - void updateFromWindow(RenderWindow window, uint x, uint y) - { - sfTexture_updateFromRenderWindow(sfPtr, window.sfPtr, x, y); - } -} - -unittest -{ - version(DSFML_Unittest_Graphics) - { - import std.stdio; - - writeln("Unit test for Texture"); - - auto texture = new Texture(); - - assert(texture.loadFromFile("res/TestImage.png")); - - //do things with the texture - - writeln(); - } -} - -private extern(C++) interface textureInputStream -{ - long read(void* data, long size); - - long seek(long position); - - long tell(); - - long getSize(); -} - - -private class textureStream:textureInputStream -{ - private InputStream myStream; - - this(InputStream stream) - { - myStream = stream; - } - - extern(C++)long read(void* data, long size) - { - return myStream.read(data[0..cast(size_t)size]); - } - - extern(C++)long seek(long position) - { - return myStream.seek(position); - } - - extern(C++)long tell() - { - return myStream.tell(); - } - - extern(C++)long getSize() - { - return myStream.getSize(); - } -} - - - -package extern(C) struct sfTexture; - -private extern(C): - -//Construct a new texture -sfTexture* sfTexture_construct(); - -//Create a new texture -bool sfTexture_create(sfTexture* texture, uint width, uint height); - -//Create a new texture from a file -bool sfTexture_loadFromFile(sfTexture* texture, const(char)* filename, int left, int top, int width, int height); - -//Create a new texture from a file in memory -bool sfTexture_loadFromMemory(sfTexture* texture, const(void)* data, size_t sizeInBytes, int left, int top, int width, int height); - -//Create a new texture from a custom stream -bool sfTexture_loadFromStream(sfTexture* texture, textureInputStream stream, int left, int top, int width, int height); - -//Create a new texture from an image -bool sfTexture_loadFromImage(sfTexture* texture, const(sfImage)* image, int left, int top, int width, int height); - -//Copy an existing texture -sfTexture* sfTexture_copy(const(sfTexture)* texture); - -//Destroy an existing texture -void sfTexture_destroy(sfTexture* texture); - -//Return the size of the texture -void sfTexture_getSize(const(sfTexture)* texture, uint* x, uint* y); - -//Copy a texture's pixels to an image -sfImage* sfTexture_copyToImage(const sfTexture* texture); - -//Update a texture from an array of pixels -void sfTexture_updateFromPixels(sfTexture* texture, const ubyte* pixels, uint width, uint height, uint x, uint y); - -//Update a texture from an image -void sfTexture_updateFromImage(sfTexture* texture, const sfImage* image, uint x, uint y); - -//Update a texture from the contents of a window -void sfTexture_updateFromWindow(sfTexture* texture, const(void)* window, uint x, uint y); - -//Update a texture from the contents of a render-window -void sfTexture_updateFromRenderWindow(sfTexture* texture, const sfRenderWindow* renderWindow, uint x, uint y); - -//Enable or disable the smooth filter on a texture -void sfTexture_setSmooth(sfTexture* texture, bool smooth); - -//Tell whether the smooth filter is enabled or not for a texture -bool sfTexture_isSmooth(const sfTexture* texture); - -//Enable or disable repeating for a texture -void sfTexture_setRepeated(sfTexture* texture, bool repeated); - -//Tell whether a texture is repeated or not -bool sfTexture_isRepeated(const sfTexture* texture); - -//Bind a texture for rendering -void sfTexture_bind(const sfTexture* texture); - -//Get the maximum texture size allowed -uint sfTexture_getMaximumSize(); - -const(char)* sfErr_getOutput(); +/* +DSFML - The Simple and Fast Multimedia Library for D + +Copyright (c) 2013 - 2015 Jeremy DeHaan (dehaan.jeremiah@gmail.com) + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, +and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. +If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution +*/ + +module dsfml.graphics.texture; + + +import dsfml.graphics.rect; +import dsfml.graphics.image; +import dsfml.graphics.renderwindow; + +import dsfml.window.window; + +import dsfml.system.inputstream; +import dsfml.system.vector2; +import dsfml.system.err; + +/++ + + Image living on the graphics card that can be used for drawing. + + + + Texture stores pixels that can be drawn, with a sprite for example. + + + + A texture lives in the graphics card memory, therefore it is very fast to draw a texture to a render target, or copy a render target to a texture (the graphics card can access both directly). + + + + Being stored in the graphics card memory has some drawbacks. A texture cannot be manipulated as freely as a Image, you need to prepare the pixels first and then upload them to the texture in a single operation (see Texture::update). + + + + Texture makes it easy to convert from/to Image, but keep in mind that these calls require transfers between the graphics card and the central memory, therefore they are slow operations. + + + + A texture can be loaded from an image, but also directly from a file/memory/stream. The necessary shortcuts are defined so that you don't need an image first for the most common cases. However, if you want to perform some modifications on the pixels before creating the final texture, you can load your file to a Image, do whatever you need with the pixels, and then call Texture::loadFromImage. + + + + Since they live in the graphics card memory, the pixels of a texture cannot be accessed without a slow copy first. And they cannot be accessed individually. Therefore, if you need to read the texture's pixels (like for pixel-perfect collisions), it is recommended to store the collision information separately, for example in an array of booleans. + + + + Like Image, Texture can handle a unique internal representation of pixels, which is RGBA 32 bits. This means that a pixel must be composed of 8 bits red, green, blue and alpha channels – just like a Color. + + + + Authors: Laurent Gomila, Jeremy DeHaan + + See_Also: http://www.sfml-dev.org/documentation/2.0/classsf_1_1Texture.php#details + +/ +class Texture +{ + package sfTexture* sfPtr; + + this() + { + sfPtr = sfTexture_construct(); + } + + package this(sfTexture* texturePointer) + { + sfPtr = texturePointer; + } + + ~this() + { + import dsfml.system.config; + mixin(destructorOutput); + sfTexture_destroy( sfPtr); + } + + /** + * Load the texture from a file on disk. + * + * The area argument can be used to load only a sub-rectangle of the whole image. If you want the entire image then leave the default value (which is an empty IntRect). If the area rectangle crosses the bounds of the image, it is adjusted to fit the image size. + * + * The maximum size for a texture depends on the graphics driver and can be retrieved with the getMaximumSize function. + * + * If this function fails, the texture is left unchanged. + * + * Params: + * filename = Path of the image file to load + * area = Area of the image to load + * + * Returns: True if loading was successful, false otherwise. + */ + bool loadFromFile(string filename, IntRect area = IntRect() ) + { + import dsfml.system.string; + + bool ret = sfTexture_loadFromFile(sfPtr, toStringz(filename) ,area.left, area.top,area.width, area.height); + if(!ret) + { + err.write(dsfml.system.string.toString(sfErr_getOutput())); + } + + return ret; + } + + //TODO: Can this be done with a slice of bytes rather than a const(void)*? + /** + * Load the texture from a file in memory. + * + * The area argument can be used to load only a sub-rectangle of the whole image. If you want the entire image then leave the default value (which is an empty IntRect). If the area rectangle crosses the bounds of the image, it is adjusted to fit the image size. + * + * The maximum size for a texture depends on the graphics driver and can be retrieved with the getMaximumSize function. + * + * If this function fails, the texture is left unchanged. + * + * Params: + * data = Image in memory + * size = Size of the data to load, in bytes. + * area = Area of the image to load + * + * Returns: True if loading was successful, false otherwise. + */ + bool loadFromMemory(const(void)[] data, IntRect area = IntRect()) + { + import dsfml.system.string; + + + bool ret = sfTexture_loadFromMemory(sfPtr, data.ptr, data.length,area.left, area.top,area.width, area.height); + if(!ret) + { + err.write(dsfml.system.string.toString(sfErr_getOutput())); + } + + return ret; + } + + /** + * Load the texture from a custom stream. + * + * The area argument can be used to load only a sub-rectangle of the whole image. If you want the entire image then leave the default value (which is an empty IntRect). If the area rectangle crosses the bounds of the image, it is adjusted to fit the image size. + * + * The maximum size for a texture depends on the graphics driver and can be retrieved with the getMaximumSize function. + * + * If this function fails, the texture is left unchanged. + * + * Params: + * stream = Source stream to read from + * area = Area of the image to load + * + * Returns: True if loading was successful, false otherwise. + */ + bool loadFromStream(InputStream stream, IntRect area = IntRect()) + { + import dsfml.system.string; + + bool ret = sfTexture_loadFromStream(sfPtr, new textureStream(stream), area.left, area.top,area.width, area.height); + if(!ret) + { + err.write(dsfml.system.string.toString(sfErr_getOutput())); + } + + return ret; + } + + /** + * Load the texture from an image. + * + * The area argument can be used to load only a sub-rectangle of the whole image. If you want the entire image then leave the default value (which is an empty IntRect). If the area rectangle crosses the bounds of the image, it is adjusted to fit the image size. + * + * The maximum size for a texture depends on the graphics driver and can be retrieved with the getMaximumSize function. + * + * If this function fails, the texture is left unchanged. + * + * Params: + * image = Image to load into the texture + * area = Area of the image to load + * + * Returns: True if loading was successful, false otherwise. + */ + bool loadFromImage(Image image, IntRect area = IntRect()) + { + import dsfml.system.string; + + bool ret = sfTexture_loadFromImage(sfPtr, image.sfPtr, area.left, area.top,area.width, area.height); + if(!ret) + { + err.write(dsfml.system.string.toString(sfErr_getOutput())); + } + + return ret; + } + + /** + * Get the maximum texture size allowed. + * + * This Maximum size is defined by the graphics driver. You can expect a value of 512 pixels for low-end graphics card, and up to 8192 pixels or more for newer hardware. + * + * Returns: Maximum size allowed for textures, in pixels. + */ + static uint getMaximumSize() + { + return sfTexture_getMaximumSize(); + } + + /** + * Return the size of the texture. + * + * Returns: Size in pixels. + */ + Vector2u getSize() const + { + Vector2u temp; + sfTexture_getSize(sfPtr, &temp.x, &temp.y); + return temp; + } + + /** + * Enable or disable the smooth filter. + * + * When the filter is activated, the texture appears smoother so that pixels are less noticeable. However if you want the texture to look exactly the same as its source file, you should leave it disabled. The smooth filter is disabled by default. + * + * Params: + * smooth = True to enable smoothing, false to disable it. + */ + void setSmooth(bool smooth) + { + sfTexture_setSmooth(sfPtr, smooth);//:sfTexture_setSmooth(sfPtr, sfFalse); + } + + /** + * Enable or disable repeating. + * + * Repeating is involved when using texture coordinates outside the texture rectangle [0, 0, width, height]. In this case, if repeat mode is enabled, the whole texture will be repeated as many times as needed to reach the coordinate (for example, if the X texture coordinate is 3 * width, the texture will be repeated 3 times). + * + * If repeat mode is disabled, the "extra space" will instead be filled with border pixels. Warning: on very old graphics cards, white pixels may appear when the texture is repeated. With such cards, repeat mode can be used reliably only if the texture has power-of-two dimensions (such as 256x128). Repeating is disabled by default. + * + * Params: + * repeated = True to repeat the texture, false to disable repeating + */ + void setRepeated(bool repeated) + { + sfTexture_setRepeated(sfPtr, repeated);//:sfTexture_setRepeated(sfPtr, sfFalse); + } + + /** + * Bind a texture for rendering. + * + * This function is not part of the graphics API, it mustn't be used when drawing SFML entities. It must be used only if you mix Texture with OpenGL code. + * + * Params: + * texture = The texture to bind. Can be null to use no texture. + */ + static void bind(Texture texture) + { + (texture is null)?sfTexture_bind(null):sfTexture_bind(texture.sfPtr); + } + + /** + * Create the texture. + * + * If this function fails, the texture is left unchanged. + * + * Params: + * width = Width of the texture + * height = Height of the texture + * + * Returns: True if creation was successful, false otherwise. + */ + bool create(uint width, uint height) + { + import dsfml.system.string; + + bool ret = sfTexture_create(sfPtr, width, height); + if(!ret) + { + err.write(dsfml.system.string.toString(sfErr_getOutput())); + } + + return ret; + } + + /** + * Copy the texture pixels to an image. + * + * This function performs a slow operation that downloads the texture's pixels from the graphics card and copies them to a new image, potentially applying transformations to pixels if necessary (texture may be padded or flipped). + * + * Returns: Image containing the texture's pixels. + */ + Image copyToImage() const + { + return new Image(sfTexture_copyToImage(sfPtr)); + } + + /** + * Creates a new texture from the same data (this means copying the entire set of pixels). + * + * Returns: New texture data. + */ + @property + Texture dup() const + { + return new Texture(sfTexture_copy(sfPtr)); + } + + /** + * Tell whether the texture is repeated or not. + * + * Returns: True if repeat mode is enabled, false if it is disabled. + */ + bool isRepeated() const + { + return (sfTexture_isRepeated(sfPtr));// == sfTrue)?true:false; + } + + /** + * Tell whether the smooth filter is enabled or not. + * + * Returns: True if something is enabled, false if it is disabled. + */ + bool isSmooth() const + { + return (sfTexture_isSmooth(sfPtr));// == sfTrue)?true:false; + } + + /** + * Update the texture from an image. + * + * Although the source image can be smaller than the texture, this function is usually used for updating the whole texture. The other overload, which has (x, y) additional arguments, is more convenient for updating a sub-area of the texture. + * + * No additional check is performed on the size of the image, passing an image bigger than the texture will lead to an undefined behaviour. + * + * This function does nothing if the texture was not previously created. + * + * Params: + * image = Image to copy to the texture. + */ + void updateFromImage(Image image, uint x, uint y) + { + sfTexture_updateFromImage(sfPtr, image.sfPtr, x, y); + } + + /** + * Update part of the texture from an array of pixels. + * + * The size of the pixel array must match the width and height arguments, and it must contain 32-bits RGBA pixels. + * + * No additional check is performed on the size of the pixel array or the bounds of the area to update, passing invalid arguments will lead to an undefined behaviour. + * + * This function does nothing if pixels is null or if the texture was not previously created. + * + * Params: + * pixels = Array of pixels to copy to the texture. + * width = Width of the pixel region contained in pixels + * height = Height of the pixel region contained in pixels + * x = X offset in the texture where to copy the source pixels + * y = Y offset in the texture where to copy the source pixels + */ + void updateFromPixels(const(ubyte)[] pixels, uint width, uint height, uint x, uint y) + { + sfTexture_updateFromPixels(sfPtr,pixels.ptr,width, height, x,y); + } + + //TODO: Get this working via inheritance?(so custom window classes can do it too) + /** + * Update a part of the texture from the contents of a window. + * + * No additional check is performed on the size of the window, passing an invalid combination of window size and offset will lead to an undefined behaviour. + * + * This function does nothing if either the texture or the window was not previously created. + * + * Params: + * window = Window to copy to the texture + * x = X offset in the texture where to copy the source window + * y = Y offset in the texture where to copy the source window + */ + void updateFromWindow(Window window, uint x, uint y) + { + sfTexture_updateFromWindow(sfPtr, RenderWindow.windowPointer(window), x, y); + } + + //Is this even safe? RenderWindow inherits from Window, so what happens? Is this bottom used or the top? + /** + * Update a part of the texture from the contents of a window. + * + * No additional check is performed on the size of the window, passing an invalid combination of window size and offset will lead to an undefined behaviour. + * + * This function does nothing if either the texture or the window was not previously created. + * + * Params: + * window = Window to copy to the texture + * x = X offset in the texture where to copy the source window + * y = Y offset in the texture where to copy the source window + */ + void updateFromWindow(RenderWindow window, uint x, uint y) + { + sfTexture_updateFromRenderWindow(sfPtr, window.sfPtr, x, y); + } + + static void flush() + { + sfTexture_flush(); + } +} + +unittest +{ + version(DSFML_Unittest_Graphics) + { + import std.stdio; + + writeln("Unit test for Texture"); + + auto texture = new Texture(); + + assert(texture.loadFromFile("res/TestImage.png")); + + //do things with the texture + + writeln(); + } +} + +private extern(C++) interface textureInputStream +{ + long read(void* data, long size); + + long seek(long position); + + long tell(); + + long getSize(); +} + + +private class textureStream:textureInputStream +{ + private InputStream myStream; + + this(InputStream stream) + { + myStream = stream; + } + + extern(C++)long read(void* data, long size) + { + return myStream.read(data[0..cast(size_t)size]); + } + + extern(C++)long seek(long position) + { + return myStream.seek(position); + } + + extern(C++)long tell() + { + return myStream.tell(); + } + + extern(C++)long getSize() + { + return myStream.getSize(); + } +} + + + +package extern(C) struct sfTexture; + +private extern(C): + +//Construct a new texture +sfTexture* sfTexture_construct(); + +//Create a new texture +bool sfTexture_create(sfTexture* texture, uint width, uint height); + +//Create a new texture from a file +bool sfTexture_loadFromFile(sfTexture* texture, const(char)* filename, int left, int top, int width, int height); + +//Create a new texture from a file in memory +bool sfTexture_loadFromMemory(sfTexture* texture, const(void)* data, size_t sizeInBytes, int left, int top, int width, int height); + +//Create a new texture from a custom stream +bool sfTexture_loadFromStream(sfTexture* texture, textureInputStream stream, int left, int top, int width, int height); + +//Create a new texture from an image +bool sfTexture_loadFromImage(sfTexture* texture, const(sfImage)* image, int left, int top, int width, int height); + +//Copy an existing texture +sfTexture* sfTexture_copy(const(sfTexture)* texture); + +//Destroy an existing texture +void sfTexture_destroy(sfTexture* texture); + +//Return the size of the texture +void sfTexture_getSize(const(sfTexture)* texture, uint* x, uint* y); + +//Copy a texture's pixels to an image +sfImage* sfTexture_copyToImage(const sfTexture* texture); + +//Update a texture from an array of pixels +void sfTexture_updateFromPixels(sfTexture* texture, const ubyte* pixels, uint width, uint height, uint x, uint y); + +//Update a texture from an image +void sfTexture_updateFromImage(sfTexture* texture, const sfImage* image, uint x, uint y); + +//Update a texture from the contents of a window +void sfTexture_updateFromWindow(sfTexture* texture, const(void)* window, uint x, uint y); + +//Update a texture from the contents of a render-window +void sfTexture_updateFromRenderWindow(sfTexture* texture, const sfRenderWindow* renderWindow, uint x, uint y); + +//Enable or disable the smooth filter on a texture +void sfTexture_setSmooth(sfTexture* texture, bool smooth); + +//Tell whether the smooth filter is enabled or not for a texture +bool sfTexture_isSmooth(const sfTexture* texture); + +//Enable or disable repeating for a texture +void sfTexture_setRepeated(sfTexture* texture, bool repeated); + +//Tell whether a texture is repeated or not +bool sfTexture_isRepeated(const sfTexture* texture); + +//Bind a texture for rendering +void sfTexture_bind(const sfTexture* texture); + +//Get the maximum texture size allowed +uint sfTexture_getMaximumSize(); + +void sfTexture_flush(); + +const(char)* sfErr_getOutput(); From 427deb404053e5acca9538b932b2bdfb4d8e90cb Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Fri, 6 May 2016 02:08:31 -0700 Subject: [PATCH 18/27] Pass string pointers and lengths to DSFMLC Remove redundant toStringz function Allow stringConvert to take both mutable and immutable, since it copies --- src/dsfml/audio/inputsoundfile.d | 30 ++++---- src/dsfml/audio/outputsoundfile.d | 12 +-- src/dsfml/audio/soundbuffer.d | 12 +-- src/dsfml/audio/soundrecorder.d | 78 ++++++++++---------- src/dsfml/graphics/font.d | 6 +- src/dsfml/graphics/image.d | 12 +-- src/dsfml/graphics/renderwindow.d | 41 +++++----- src/dsfml/graphics/shader.d | 119 +++++++++++++++--------------- src/dsfml/graphics/texture.d | 6 +- src/dsfml/network/ftp.d | 69 ++++++++--------- src/dsfml/network/http.d | 30 ++++---- src/dsfml/network/ipaddress.d | 37 ++++------ src/dsfml/system/string.d | 60 +-------------- src/dsfml/window/window.d | 39 +++++----- 14 files changed, 251 insertions(+), 300 deletions(-) diff --git a/src/dsfml/audio/inputsoundfile.d b/src/dsfml/audio/inputsoundfile.d index bfa7372..9c564fb 100644 --- a/src/dsfml/audio/inputsoundfile.d +++ b/src/dsfml/audio/inputsoundfile.d @@ -34,16 +34,16 @@ struct InputSoundFile { m_soundFile = sfInputSoundFile_create(); } - + ~this() { sfInputSoundFile_destroy(m_soundFile); } - bool openFromFile(string filename) + bool openFromFile(const(char)[] filename) { import dsfml.system.string; - bool toReturn = sfInputSoundFile_openFromFile(m_soundFile, toStringz(filename)); + bool toReturn = sfInputSoundFile_openFromFile(m_soundFile, filename.ptr, filename.length); err.write(toString(sfErr_getOutput())); return toReturn; } @@ -75,16 +75,16 @@ struct InputSoundFile { import dsfml.system.string; sfInputSoundFile_seek(m_soundFile, timeOffset); - + //Temporary fix for a bug where attempting to write to err //throws an exception in a thread created in C++. This causes //the program to explode. Hooray. - + //This fix will skip the call to err.write if there was no error //to report. If there is an error, well, the program will still explode, - //but the user should see the error prior to the call that will make the + //but the user should see the error prior to the call that will make the //program explode. - + string temp = toString(sfErr_getOutput()); if(temp.length > 0) { @@ -116,11 +116,11 @@ private extern(C++) interface soundInputStream { long read(void* data, long size); - + long seek(long position); - + long tell(); - + long getSize(); } @@ -128,17 +128,17 @@ extern(C++) interface soundInputStream class soundFileStream:soundInputStream { private InputStream myStream; - + this(InputStream stream) { myStream = stream; } - + extern(C++)long read(void* data, long size) { return myStream.read(data[0..cast(size_t)size]); } - + extern(C++)long seek(long position) { return myStream.seek(position); @@ -148,7 +148,7 @@ class soundFileStream:soundInputStream { return myStream.tell(); } - + extern(C++)long getSize() { return myStream.getSize(); @@ -174,7 +174,7 @@ uint sfInputSoundFile_getChannelCount( const sfInputSoundFile* file); uint sfInputSoundFile_getSampleRate(const sfInputSoundFile* file); -bool sfInputSoundFile_openFromFile(sfInputSoundFile* file, const char* filename); +bool sfInputSoundFile_openFromFile(sfInputSoundFile* file, const char* filename, size_t length); bool sfInputSoundFile_openFromMemory(sfInputSoundFile* file,const(void)* data, long sizeInBytes); diff --git a/src/dsfml/audio/outputsoundfile.d b/src/dsfml/audio/outputsoundfile.d index db487ed..f9f73ed 100644 --- a/src/dsfml/audio/outputsoundfile.d +++ b/src/dsfml/audio/outputsoundfile.d @@ -25,9 +25,9 @@ import dsfml.system.err; /** *Provide write access to sound files. * - *This class encodes audio samples to a sound file. + *This class encodes audio samples to a sound file. * - *It is used internally by higher-level classes such as sf::SoundBuffer, but can also be useful if you want to create audio files from + *It is used internally by higher-level classes such as sf::SoundBuffer, but can also be useful if you want to create audio files from *custom data sources, like generated audio samples. */ struct OutputSoundFile @@ -38,16 +38,16 @@ struct OutputSoundFile { m_soundFile = sfOutputSoundFile_create(); } - + ~this() { sfOutputSoundFile_destroy(m_soundFile); } - bool openFromFile(string filename,uint channelCount,uint sampleRate) + bool openFromFile(const(char)[] filename,uint channelCount,uint sampleRate) { import dsfml.system.string; - bool toReturn = sfOutputSoundFile_openFromFile(m_soundFile, toStringz(filename),channelCount,sampleRate); + bool toReturn = sfOutputSoundFile_openFromFile(m_soundFile, filename.ptr, filename.length,channelCount,sampleRate); err.write(toString(sfErr_getOutput())); return toReturn; } @@ -71,7 +71,7 @@ sfOutputSoundFile* sfOutputSoundFile_create(); void sfOutputSoundFile_destroy(sfOutputSoundFile* file); -bool sfOutputSoundFile_openFromFile(sfOutputSoundFile* file, const(char)* filename,uint channelCount,uint sampleRate); +bool sfOutputSoundFile_openFromFile(sfOutputSoundFile* file, const(char)* filename, size_t length, uint channelCount,uint sampleRate); void sfOutputSoundFile_write(sfOutputSoundFile* file, const short* data, long sampleCount); diff --git a/src/dsfml/audio/soundbuffer.d b/src/dsfml/audio/soundbuffer.d index a55f090..e27f668 100644 --- a/src/dsfml/audio/soundbuffer.d +++ b/src/dsfml/audio/soundbuffer.d @@ -138,10 +138,10 @@ class SoundBuffer * * Returns: True if loading succeeded, false if it failed */ - bool loadFromFile(string filename) + bool loadFromFile(const(char)[] filename) { import dsfml.system.string; - if(sfSoundBuffer_loadFromFile(sfPtr, toStringz(filename))) + if(sfSoundBuffer_loadFromFile(sfPtr, filename.ptr, filename.length)) { return true; } @@ -236,10 +236,10 @@ class SoundBuffer * * Returns: True if saving succeeded, false if it failed */ - bool saveToFile(string filename) + bool saveToFile(const(char)[] filename) { import dsfml.system.string; - if(sfSoundBuffer_saveToFile(sfPtr, toStringz(filename))) + if(sfSoundBuffer_saveToFile(sfPtr, filename.ptr, filename.length)) { return true; } @@ -333,7 +333,7 @@ private extern(C): sfSoundBuffer* sfSoundBuffer_construct(); -bool sfSoundBuffer_loadFromFile(sfSoundBuffer* soundBuffer, const char* filename); +bool sfSoundBuffer_loadFromFile(sfSoundBuffer* soundBuffer, const char* filename, size_t length); bool sfSoundBuffer_loadFromMemory(sfSoundBuffer* soundBuffer, const void* data, size_t sizeInBytes); @@ -345,7 +345,7 @@ sfSoundBuffer* sfSoundBuffer_copy(const sfSoundBuffer* soundBuffer); void sfSoundBuffer_destroy(sfSoundBuffer* soundBuffer); -bool sfSoundBuffer_saveToFile(const sfSoundBuffer* soundBuffer, const char* filename); +bool sfSoundBuffer_saveToFile(const sfSoundBuffer* soundBuffer, const char* filename, size_t length); const(short)* sfSoundBuffer_getSamples(const sfSoundBuffer* soundBuffer); diff --git a/src/dsfml/audio/soundrecorder.d b/src/dsfml/audio/soundrecorder.d index 1dcaa32..9b19b53 100644 --- a/src/dsfml/audio/soundrecorder.d +++ b/src/dsfml/audio/soundrecorder.d @@ -27,24 +27,24 @@ import dsfml.system.err; /++ + Abstract base class for capturing sound data. - + + + + SoundBuffer provides a simple interface to access the audio recording capabilities of the computer (the microphone). - + + + + As an abstract base class, it only cares about capturing sound samples, the task of making something useful with them is left to the derived class. Note that SFML provides a built-in specialization for saving the captured data to a sound buffer (see SoundBufferRecorder). - + + + + A derived class has only one virtual function to override: - + + + + onProcessSamples provides the new chunks of audio samples while the capture happens - + + + + Moreover, two additionnal virtual functions can be overriden as well if necessary: - + + + + onStart is called before the capture happens, to perform custom initializations + onStop is called after the capture ends, to perform custom cleanup - + + + + The audio capture feature may not be supported or activated on every platform, thus it is recommended to check its availability with the isAvailable() function. If it returns false, then any attempt to use an audio recorder will fail. - + + + + It is important to note that the audio capture happens in a separate thread, so that it doesn't block the rest of the program. In particular, the onProcessSamples and onStop virtual functions (but not onStart) will be called from this separate thread. It is important to keep this in mind, because you may have to take care of synchronization issues if you share data between threads. - + + + + See_Also: http://www.sfml-dev.org/documentation/2.0/classsf_1_1SoundRecorder.php#details + Authors: Laurent Gomila, Jeremy DeHaan +/ @@ -61,9 +61,9 @@ class SoundRecorder sfPtr = sfSoundRecorder_construct(callBacks); err.write(dsfml.system.string.toString(sfErr_getOutput())); - + //Fix for some strange bug that I can't seem to track down. - //This bug causes the array in SoundBufferRecorder to segfault if + //This bug causes the array in SoundBufferRecorder to segfault if //its length reaches 1024, but creating an array of this size before capturing happens //seems to fix it. This fix should allow other implementations to not segfault as well. //I will look into the cause when I have more time, but this at least renders it usable. @@ -82,7 +82,7 @@ class SoundRecorder /** * Start the capture. * The sampleRate parameter defines the number of audio samples captured per second. The higher, the better the quality (for example, 44100 samples/sec is CD quality). This function uses its own thread so that it doesn't block the rest of the program while the capture runs. Please note that only one capture can happen at the same time. - * + * * Params: * sampleRate = Desired capture rate, in number of samples per second */ @@ -102,7 +102,7 @@ class SoundRecorder /** * Get the sample rate in samples per second. - * + * * The sample rate defines the number of audio samples captured per second. The higher, the better the quality (for example, 44100 samples/sec is CD quality). */ @property @@ -112,12 +112,12 @@ class SoundRecorder return sfSoundRecorder_getSampleRate(sfPtr); } } - + /** *Get the name of the current audio capture device. * *Returns - * The name of the current audio capture device + * The name of the current audio capture device */ string getDevice() const { return .toString(sfSoundRecorder_getDevice(sfPtr)); @@ -134,53 +134,53 @@ class SoundRecorder * True, if it was able to set the requested device * *See also - * getAvailableDevices, getDefaultDevice + * getAvailableDevices, getDefaultDevice */ - bool setDevice (string name) { - return sfSoundRecorder_setDevice(sfPtr, toStringz(name)); + bool setDevice (const(char)[] name) { + return sfSoundRecorder_setDevice(sfPtr, name.ptr, name.length); } - + /** *Get a list of the names of all available audio capture devices. * *This function returns an array of strings, containing the names of all available audio capture devices. * *Returns - * An array of strings containing the names + * An array of strings containing the names */ static const(string)[] getAvailableDevices() { static string[] availableDevices;//stores all available devices after the first call - + //if getAvailableDevices hasn't been called yet if(availableDevices.length == 0) { const (char)** devices; size_t counts; - + //returns uints instead of structs due to 64 bit bug devices = sfSoundRecorder_getAvailableDevices(&counts); - + //calculate real length availableDevices.length = counts; - + //populate availableDevices for(uint i = 0; i < counts; i++) { availableDevices[i] = .toString(devices[i]); } - + } - + return availableDevices; } - + /** *Get the name of the default audio capture device. * *This function returns the name of the default audio capture device. If none is available, an empty string is returned. * *Returns - * The name of the default audio capture device + * The name of the default audio capture device */ static string getDefaultDevice() { return .toString(sfSoundRecorder_getDefaultDevice()); @@ -188,9 +188,9 @@ class SoundRecorder /** * Check if the system supports audio capture. - * + * * This function should always be called before using the audio capture features. If it returns false, then any attempt to use SoundRecorder or one of its derived classes will fail. - * + * * Returns: True if audio capture is supported, false otherwise */ static bool isAvailable() @@ -210,17 +210,17 @@ class SoundRecorder * The default processing interval is 100 ms. * * Parameters - * interval Processing interval + * interval Processing interval */ void setProcessingInterval (Duration interval) { sfSoundRecorder_setProcessingInterval(sfPtr, interval.total!"usecs"); } - + /** * Start capturing audio data. - * + * * This virtual function may be overriden by a derived class if something has to be done every time a new capture starts. If not, this function can be ignored; the default implementation does nothing. - * + * * Returns: True to the start the capture, or false to abort it. */ bool onStart() @@ -230,19 +230,19 @@ class SoundRecorder /** * Process a new chunk of recorded samples. - * + * * This virtual function is called every time a new chunk of recorded data is available. The derived class can then do whatever it wants with it (storing it, playing it, sending it over the network, etc.). - * + * * Params: * samples = Array of the new chunk of recorded samples - * + * * Returns: True to continue the capture, or false to stop it */ abstract bool onProcessSamples(const(short)[] samples); /** * Stop capturing audio data. - * + * * This virtual function may be overriden by a derived class if something has to be done every time the capture ends. If not, this function can be ignored; the default implementation does nothing. */ void onStop() @@ -304,7 +304,7 @@ void sfSoundRecorder_stop(sfSoundRecorder* soundRecorder); uint sfSoundRecorder_getSampleRate(const sfSoundRecorder* soundRecorder); -bool sfSoundRecorder_setDevice(sfSoundRecorder* soundRecorder, const(char)* name); +bool sfSoundRecorder_setDevice(sfSoundRecorder* soundRecorder, const(char)* name, size_t length); const(char)* sfSoundRecorder_getDevice(const (sfSoundRecorder)* soundRecorder); diff --git a/src/dsfml/graphics/font.d b/src/dsfml/graphics/font.d index fbef984..98c0596 100644 --- a/src/dsfml/graphics/font.d +++ b/src/dsfml/graphics/font.d @@ -76,11 +76,11 @@ class Font * * Returns: True if loading succeeded, false if it failed. */ - bool loadFromFile(string filename) + bool loadFromFile(const(char)[] filename) { import dsfml.system.string; - bool ret = sfFont_loadFromFile(sfPtr, toStringz(filename)); + bool ret = sfFont_loadFromFile(sfPtr, filename.ptr, filename.length); if(!ret) { err.write(dsfml.system.string.toString(sfErr_getOutput())); @@ -335,7 +335,7 @@ private extern(C): sfFont* sfFont_construct(); //Create a new font from a file -bool sfFont_loadFromFile(sfFont* font, const(char)* filename); +bool sfFont_loadFromFile(sfFont* font, const(char)* filename, size_t length); //Create a new image font a file in memory diff --git a/src/dsfml/graphics/image.d b/src/dsfml/graphics/image.d index a31c25d..05f344f 100644 --- a/src/dsfml/graphics/image.d +++ b/src/dsfml/graphics/image.d @@ -104,11 +104,11 @@ class Image * * Returns: True if loading succeeded, false if it failed */ - bool loadFromFile(string fileName) + bool loadFromFile(const(char)[] fileName) { import dsfml.system.string; - bool ret = sfImage_loadFromFile(sfPtr, toStringz(fileName)); + bool ret = sfImage_loadFromFile(sfPtr, fileName.ptr, fileName.length); if(!ret) { @@ -293,10 +293,10 @@ class Image * * Returns: True if saving was successful */ - bool saveToFile(string fileName) + bool saveToFile(const(char)[] fileName) { import dsfml.system.string; - bool toReturn = sfImage_saveToFile(sfPtr, toStringz(fileName)); + bool toReturn = sfImage_saveToFile(sfPtr, fileName.ptr, fileName.length); err.write(dsfml.system.string.toString(sfErr_getOutput())); return toReturn; } @@ -395,7 +395,7 @@ void sfImage_createFromColor(sfImage* image, uint width, uint height, ubyte r, u void sfImage_createFromPixels(sfImage* image, uint width, uint height, const(ubyte)* pixels); /// \brief Create an image from a file on disk -bool sfImage_loadFromFile(sfImage* image, const(char)* filename); +bool sfImage_loadFromFile(sfImage* image, const(char)* filename, size_t length); /// \brief Create an image from a file in memory bool sfImage_loadFromMemory(sfImage* image, const(void)* data, size_t size); @@ -410,7 +410,7 @@ sfImage* sfImage_copy(const(sfImage)* image); void sfImage_destroy(sfImage* image); /// \brief Save an image to a file on disk -bool sfImage_saveToFile(const sfImage* image, const char* filename); +bool sfImage_saveToFile(const sfImage* image, const char* filename, size_t length); /// \brief Return the size of an image void sfImage_getSize(const sfImage* image, uint* width, uint* height); diff --git a/src/dsfml/graphics/renderwindow.d b/src/dsfml/graphics/renderwindow.d index 0e171bf..48d19ee 100644 --- a/src/dsfml/graphics/renderwindow.d +++ b/src/dsfml/graphics/renderwindow.d @@ -328,10 +328,11 @@ class RenderWindow : Window, RenderTarget * Params: * title = New title */ - override void setTitle(string newTitle) + override void setTitle(const(char)[] newTitle) { import dsfml.system.string; - sfRenderWindow_setUnicodeTitle(sfPtr, toStringz(stringConvert!(char, dchar)(newTitle))); + auto convertedTitle = stringConvert!(char, dchar)(newTitle); + sfRenderWindow_setUnicodeTitle(sfPtr, convertedTitle.ptr, convertedTitle.length); } /** * Change the title of the window @@ -339,10 +340,11 @@ class RenderWindow : Window, RenderTarget * Params: * title = New title */ - override void setTitle(wstring newTitle) + override void setTitle(const(wchar)[] newTitle) { import dsfml.system.string; - sfRenderWindow_setUnicodeTitle(sfPtr, toStringz(stringConvert!(wchar, dchar)(newTitle))); + auto convertedTitle = stringConvert!(wchar, dchar)(newTitle); + sfRenderWindow_setUnicodeTitle(sfPtr, convertedTitle.ptr, convertedTitle.length); } /** * Change the title of the window @@ -350,10 +352,10 @@ class RenderWindow : Window, RenderTarget * Params: * title = New title */ - override void setTitle(dstring newTitle) + override void setTitle(const(dchar)[] newTitle) { - import dsfml.system.string; - sfRenderWindow_setUnicodeTitle(sfPtr, toStringz(newTitle)); + import dsfml.system.string; + sfRenderWindow_setUnicodeTitle(sfPtr, newTitle.ptr, newTitle.length); } /** @@ -414,11 +416,13 @@ class RenderWindow : Window, RenderTarget ///If the window was already created, it closes it first. If style contains Style::Fullscreen, then mode must be a valid video mode. /// ///The fourth parameter is an optional structure specifying advanced OpenGL context settings such as antialiasing, depth-buffer bits, etc. - override void create(VideoMode mode, string title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) + override void create(VideoMode mode, const(char)[] title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) { import dsfml.system.string; - sfRenderWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, toStringz(stringConvert!(char,dchar)(title)), style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); + auto convertedTitle = stringConvert!(char, dchar)(title); + + sfRenderWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, convertedTitle.ptr, convertedTitle.length, style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); err.write(dsfml.system.string.toString(sfErr_getOutput())); //get view @@ -433,11 +437,12 @@ class RenderWindow : Window, RenderTarget ///If the window was already created, it closes it first. If style contains Style::Fullscreen, then mode must be a valid video mode. /// ///The fourth parameter is an optional structure specifying advanced OpenGL context settings such as antialiasing, depth-buffer bits, etc. - override void create(VideoMode mode, wstring title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) + override void create(VideoMode mode, const(wchar)[] title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) { import dsfml.system.string; + auto convertedTitle = stringConvert!(wchar, dchar)(title); - sfRenderWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, toStringz(stringConvert!(wchar,dchar)(title)), style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); + sfRenderWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, convertedTitle.ptr, convertedTitle.length, style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); err.write(dsfml.system.string.toString(sfErr_getOutput())); //get view @@ -452,11 +457,9 @@ class RenderWindow : Window, RenderTarget ///If the window was already created, it closes it first. If style contains Style::Fullscreen, then mode must be a valid video mode. /// ///The fourth parameter is an optional structure specifying advanced OpenGL context settings such as antialiasing, depth-buffer bits, etc. - override void create(VideoMode mode, dstring title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) + override void create(VideoMode mode, const(dchar)[] title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) { - import dsfml.system.string; - - sfRenderWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, toStringz(title), style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); + sfRenderWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, title.ptr, title.length, style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); err.write(dsfml.system.string.toString(sfErr_getOutput())); //get view @@ -838,13 +841,13 @@ private extern(C): sfRenderWindow* sfRenderWindow_construct(); //Construct a new render window from settings -sfRenderWindow* sfRenderWindow_constructFromSettings(uint width, uint height, uint bitsPerPixel, const(dchar)* title, int style, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); +sfRenderWindow* sfRenderWindow_constructFromSettings(uint width, uint height, uint bitsPerPixel, const(dchar)* title, size_t titleLength, int style, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); //Construct a render window from an existing control sfRenderWindow* sfRenderWindow_constructFromHandle(WindowHandle handle, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); //Create(or recreate) a new render window from settings -void sfRenderWindow_createFromSettings(sfRenderWindow* renderWindow, uint width, uint height, uint bitsPerPixel, const(dchar)* title, int style, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); +void sfRenderWindow_createFromSettings(sfRenderWindow* renderWindow, uint width, uint height, uint bitsPerPixel, const(dchar)* title, size_t titleLength, int style, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); //Create(or recreate) a render window from an existing control void sfRenderWindow_createFromHandle(sfRenderWindow* renderWindow, WindowHandle handle, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); @@ -880,10 +883,10 @@ void sfRenderWindow_getSize(const sfRenderWindow* renderWindow, uint* width, uin void sfRenderWindow_setSize(sfRenderWindow* renderWindow, int width, int height); //Change the title of a render window -void sfRenderWindow_setTitle(sfRenderWindow* renderWindow, const(char)* title); +void sfRenderWindow_setTitle(sfRenderWindow* renderWindow, const(char)* title, size_t titleLength); //Change the title of a render window (with a UTF-32 string) -void sfRenderWindow_setUnicodeTitle(sfRenderWindow* renderWindow, const(dchar)* title); +void sfRenderWindow_setUnicodeTitle(sfRenderWindow* renderWindow, const(dchar)* title, size_t titleLength); //Change a render window's icon void sfRenderWindow_setIcon(sfRenderWindow* renderWindow, uint width, uint height, const ubyte* pixels); diff --git a/src/dsfml/graphics/shader.d b/src/dsfml/graphics/shader.d index 715c973..5cb77e9 100644 --- a/src/dsfml/graphics/shader.d +++ b/src/dsfml/graphics/shader.d @@ -97,7 +97,7 @@ class Shader * * Returns: True if loading succeeded, false if it failed. */ - bool loadFromFile(string filename, Type type) + bool loadFromFile(const(char)[] filename, Type type) { import dsfml.system.string; @@ -105,11 +105,11 @@ class Shader if(type == Type.Vertex) { - ret = sfShader_loadFromFile(sfPtr, toStringz(filename) , null); + ret = sfShader_loadFromFile(sfPtr, filename.ptr, filename.length, null, 0); } else { - ret = sfShader_loadFromFile(sfPtr, null , toStringz(filename) ); + ret = sfShader_loadFromFile(sfPtr, null, 0 , filename.ptr, filename.length); } if(!ret) @@ -131,11 +131,12 @@ class Shader * * Returns: True if loading succeeded, false if it failed. */ - bool loadFromFile(string vertexShaderFilename, string fragmentShaderFilename) + bool loadFromFile(const(char)[] vertexShaderFilename, const(char)[] fragmentShaderFilename) { import dsfml.system.string; - bool ret = sfShader_loadFromFile(sfPtr, toStringz(vertexShaderFilename) , toStringz(fragmentShaderFilename)); + bool ret = sfShader_loadFromFile(sfPtr, vertexShaderFilename.ptr, vertexShaderFilename.length, + fragmentShaderFilename.ptr, fragmentShaderFilename.length); if(!ret) { err.write(dsfml.system.string.toString(sfErr_getOutput())); @@ -155,7 +156,7 @@ class Shader * * Returns: True if loading succeeded, false if it failed. */ - bool loadFromMemory(string shader, Type type) + bool loadFromMemory(const(char)[] shader, Type type) { import dsfml.system.string; @@ -163,11 +164,11 @@ class Shader if(type == Type.Vertex) { - ret = sfShader_loadFromMemory(sfPtr, toStringz(shader) , null); + ret = sfShader_loadFromMemory(sfPtr, shader.ptr, shader.length, null, 0); } else { - ret = sfShader_loadFromMemory(sfPtr, null , toStringz(shader) ); + ret = sfShader_loadFromMemory(sfPtr, null, 0 , shader.ptr, shader.length ); } if(!ret) { @@ -187,11 +188,11 @@ class Shader * * Returns: True if loading succeeded, false if it failed. */ - bool loadFromMemory(string vertexShader, string fragmentShader) + bool loadFromMemory(const(char)[] vertexShader, const(char)[] fragmentShader) { import dsfml.system.string; - bool ret = sfShader_loadFromMemory(sfPtr, toStringz(vertexShader) , toStringz(fragmentShader)); + bool ret = sfShader_loadFromMemory(sfPtr, vertexShader.ptr, vertexShader.length , fragmentShader.ptr, fragmentShader.length); if(!ret) { err.write(dsfml.system.string.toString(sfErr_getOutput())); @@ -263,17 +264,17 @@ class Shader * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a float (float GLSL type). * x = Value to assign */ - void setParameter(string name, float x) + void setParameter(const(char)[] name, float x) { import dsfml.system.string; - sfShader_setFloatParameter(sfPtr, toStringz(name), x); + sfShader_setFloatParameter(sfPtr, name.ptr, name.length, x); } ///ditto - void opIndexAssign(float x, string name) + void opIndexAssign(float x, const(char)[] name) { import dsfml.system.string; - sfShader_setFloatParameter(sfPtr, toStringz(name), x); + sfShader_setFloatParameter(sfPtr, name.ptr, name.length, x); } /** @@ -284,10 +285,10 @@ class Shader * x = First component of the value to assign * y = Second component of the value to assign */ - void setParameter(string name, float x, float y) + void setParameter(const(char)[] name, float x, float y) { import dsfml.system.string; - sfShader_setFloat2Parameter(sfPtr, toStringz(name), x, y); + sfShader_setFloat2Parameter(sfPtr, name.ptr, name.length, x, y); } /** @@ -299,10 +300,10 @@ class Shader * y = Second component of the value to assign * z = Third component of the value to assign */ - void setParameter(string name, float x, float y, float z) + void setParameter(const(char)[] name, float x, float y, float z) { import dsfml.system.string; - sfShader_setFloat3Parameter(sfPtr, toStringz(name), x,y,z); + sfShader_setFloat3Parameter(sfPtr, name.ptr, name.length, x,y,z); } /** @@ -315,10 +316,10 @@ class Shader * z = Third component of the value to assign * w = Fourth component of the value to assign */ - void setParameter(string name, float x, float y, float z, float w) + void setParameter(const(char)[] name, float x, float y, float z, float w) { import dsfml.system.string; - sfShader_setFloat4Parameter(sfPtr, toStringz(name), x, y, z, w); + sfShader_setFloat4Parameter(sfPtr, name.ptr, name.length, x, y, z, w); } /** @@ -328,20 +329,20 @@ class Shader * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 4x1 vector (vec4 GLSL type). * val = The set of floats to assign. */ - void opIndexAssign(float[] val, string name) + void opIndexAssign(float[] val, const(char)[] name) { import dsfml.system.string; //assert to make sure that val is of proper length at run time assert((val.length >0) && (val.length <= 4)); if(val.length == 1) - sfShader_setFloatParameter(sfPtr, toStringz(name), val[0]); + sfShader_setFloatParameter(sfPtr, name.ptr, name.length, val[0]); else if(val.length == 2) - sfShader_setFloat2Parameter(sfPtr, toStringz(name), val[0], val[1]); + sfShader_setFloat2Parameter(sfPtr, name.ptr, name.length, val[0], val[1]); else if(val.length == 3) - sfShader_setFloat3Parameter(sfPtr, toStringz(name), val[0], val[1], val[2]); + sfShader_setFloat3Parameter(sfPtr, name.ptr, name.length, val[0], val[1], val[2]); else if(val.length >= 4) - sfShader_setFloat4Parameter(sfPtr, toStringz(name), val[0], val[1], val[2], val[3]); + sfShader_setFloat4Parameter(sfPtr, name.ptr, name.length, val[0], val[1], val[2], val[3]); } /** @@ -351,17 +352,17 @@ class Shader * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 2x1 vector (vec2 GLSL type). * vector = Vector to assign */ - void setParameter(string name, Vector2f vector) + void setParameter(const(char)[] name, Vector2f vector) { import dsfml.system.string; - sfShader_setFloat2Parameter(sfPtr, toStringz(name), vector.x, vector.y); + sfShader_setFloat2Parameter(sfPtr, name.ptr, name.length, vector.x, vector.y); } ///ditto - void opIndexAssign(Vector2f vector, string name) + void opIndexAssign(Vector2f vector, const(char)[] name) { import dsfml.system.string; - sfShader_setFloat2Parameter(sfPtr, toStringz(name), vector.x, vector.y); + sfShader_setFloat2Parameter(sfPtr, name.ptr, name.length, vector.x, vector.y); } /** @@ -371,16 +372,16 @@ class Shader * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 3x1 vector (vec3 GLSL type). * vector = Vector to assign */ - void setParameter(string name, Vector3f vector) + void setParameter(const(char)[] name, Vector3f vector) { import dsfml.system.string; - sfShader_setFloat3Parameter(sfPtr, toStringz(name), vector.x, vector.y, vector.z); + sfShader_setFloat3Parameter(sfPtr, name.ptr, name.length, vector.x, vector.y, vector.z); } ///ditto - void opIndexAssign(Vector3f vector, string name) + void opIndexAssign(Vector3f vector, const(char)[] name) { import dsfml.system.string; - sfShader_setFloat3Parameter(sfPtr, toStringz(name), vector.x, vector.y, vector.z); + sfShader_setFloat3Parameter(sfPtr, name.ptr, name.length, vector.x, vector.y, vector.z); } /** @@ -392,16 +393,16 @@ class Shader * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 4x1 vector (vec4 GLSL type). * color = Color to assign */ - void setParameter(string name, Color color) + void setParameter(const(char)[] name, Color color) { import dsfml.system.string; - sfShader_setColorParameter(sfPtr, toStringz(name), color.r, color.g, color.b, color.a); + sfShader_setColorParameter(sfPtr, name.ptr, name.length, color.r, color.g, color.b, color.a); } ///ditto - void opIndexAssign(Color color, string name) + void opIndexAssign(Color color, const(char)[] name) { import dsfml.system.string; - sfShader_setColorParameter(sfPtr, toStringz(name), color.r, color.g, color.b, color.a); + sfShader_setColorParameter(sfPtr, name.ptr, name.length, color.r, color.g, color.b, color.a); } /** @@ -411,16 +412,16 @@ class Shader * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 4x4 matrix (mat4 GLSL type). * transform = Transform to assign */ - void setParameter(string name, Transform transform) + void setParameter(const(char)[] name, Transform transform) { import dsfml.system.string; - sfShader_setTransformParameter(sfPtr, toStringz(name), transform.m_matrix.ptr); + sfShader_setTransformParameter(sfPtr, name.ptr, name.length, transform.m_matrix.ptr); } ///ditto - void opIndexAssign(Transform transform, string name) + void opIndexAssign(Transform transform, const(char)[] name) { import dsfml.system.string; - sfShader_setTransformParameter(sfPtr, toStringz(name), transform.m_matrix.ptr); + sfShader_setTransformParameter(sfPtr, name.ptr, name.length, transform.m_matrix.ptr); } /** @@ -434,17 +435,17 @@ class Shader * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 2D texture (sampler2D GLSL type). * texture = Texture to assign */ - void setParameter(string name, const(Texture) texture) + void setParameter(const(char)[] name, const(Texture) texture) { import dsfml.system.string; - sfShader_setTextureParameter(sfPtr, toStringz(name), texture.sfPtr); + sfShader_setTextureParameter(sfPtr, name.ptr, name.length, texture.sfPtr); err.write(dsfml.system.string.toString(sfErr_getOutput())); } ///ditto - void opIndexAssign(const(Texture) texture, string name) + void opIndexAssign(const(Texture) texture, const(char)[] name) { import dsfml.system.string; - sfShader_setTextureParameter(sfPtr, toStringz(name), texture.sfPtr); + sfShader_setTextureParameter(sfPtr, name.ptr, name.length, texture.sfPtr); err.write(dsfml.system.string.toString(sfErr_getOutput())); } @@ -457,10 +458,10 @@ class Shader * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 2D texture (sampler2D GLSL type). */ - void setParameter(string name, CurrentTextureType) + void setParameter(const(char)[] name, CurrentTextureType) { import dsfml.system.string; - sfShader_setCurrentTextureParameter(sfPtr, toStringz(name)); + sfShader_setCurrentTextureParameter(sfPtr, name.ptr, name.length); } /** @@ -471,10 +472,10 @@ class Shader * Params: * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 2D texture (sampler2D GLSL type). */ - void opIndexAssign(CurrentTextureType, string name) + void opIndexAssign(CurrentTextureType, const(char)[] name) { import dsfml.system.string; - sfShader_setCurrentTextureParameter(sfPtr, toStringz(name)); + sfShader_setCurrentTextureParameter(sfPtr, name.ptr, name.length); } /** @@ -562,10 +563,10 @@ private extern(C): sfShader* sfShader_construct(); //Load both the vertex and fragment shaders from files -bool sfShader_loadFromFile(sfShader* shader, const(char)* vertexShaderFilename, const char* fragmentShaderFilename); +bool sfShader_loadFromFile(sfShader* shader, const(char)* vertexShaderFilename, size_t vertexShaderFilenameLength, const char* fragmentShaderFilename, size_t fragmentShaderFilenameLength); //Load both the vertex and fragment shaders from source codes in memory -bool sfShader_loadFromMemory(sfShader* shader, const(char)* vertexShader, const char* fragmentShader); +bool sfShader_loadFromMemory(sfShader* shader, const(char)* vertexShader, size_t vertexShaderLength, const char* fragmentShader, size_t fragmentShaderLength); //Load both the vertex and fragment shaders from custom streams bool sfShader_loadFromStream(sfShader* shader, shaderInputStream vertexShaderStream, shaderInputStream fragmentShaderStream); @@ -574,28 +575,28 @@ bool sfShader_loadFromStream(sfShader* shader, shaderInputStream vertexShaderStr void sfShader_destroy(sfShader* shader); //Change a float parameter of a shader -void sfShader_setFloatParameter(sfShader* shader, const char* name, float x); +void sfShader_setFloatParameter(sfShader* shader, const char* name, size_t length, float x); //Change a 2-components vector parameter of a shader -void sfShader_setFloat2Parameter(sfShader* shader, const char* name, float x, float y); +void sfShader_setFloat2Parameter(sfShader* shader, const char* name, size_t length, float x, float y); //Change a 3-components vector parameter of a shader -void sfShader_setFloat3Parameter(sfShader* shader, const char* name, float x, float y, float z); +void sfShader_setFloat3Parameter(sfShader* shader, const char* name, size_t length, float x, float y, float z); //Change a 4-components vector parameter of a shader -void sfShader_setFloat4Parameter(sfShader* shader, const char* name, float x, float y, float z, float w); +void sfShader_setFloat4Parameter(sfShader* shader, const char* name, size_t length, float x, float y, float z, float w); //Change a color parameter of a shader -void sfShader_setColorParameter(sfShader* shader, const char* name, ubyte r, ubyte g, ubyte b, ubyte a); +void sfShader_setColorParameter(sfShader* shader, const char* name, size_t length, ubyte r, ubyte g, ubyte b, ubyte a); //Change a matrix parameter of a shader -void sfShader_setTransformParameter(sfShader* shader, const char* name, float* transform); +void sfShader_setTransformParameter(sfShader* shader, const char* name, size_t length, float* transform); //Change a texture parameter of a shader -void sfShader_setTextureParameter(sfShader* shader, const char* name, const sfTexture* texture); +void sfShader_setTextureParameter(sfShader* shader, const char* name, size_t length, const sfTexture* texture); //Change a texture parameter of a shader -void sfShader_setCurrentTextureParameter(sfShader* shader, const char* name); +void sfShader_setCurrentTextureParameter(sfShader* shader, const char* name, size_t length); //Bind a shader for rendering (activate it) void sfShader_bind(const sfShader* shader); diff --git a/src/dsfml/graphics/texture.d b/src/dsfml/graphics/texture.d index c53a097..693ebf0 100644 --- a/src/dsfml/graphics/texture.d +++ b/src/dsfml/graphics/texture.d @@ -86,11 +86,11 @@ class Texture * * Returns: True if loading was successful, false otherwise. */ - bool loadFromFile(string filename, IntRect area = IntRect() ) + bool loadFromFile(const(char)[] filename, IntRect area = IntRect() ) { import dsfml.system.string; - bool ret = sfTexture_loadFromFile(sfPtr, toStringz(filename) ,area.left, area.top,area.width, area.height); + bool ret = sfTexture_loadFromFile(sfPtr, filename.ptr, filename.length,area.left, area.top,area.width, area.height); if(!ret) { err.write(dsfml.system.string.toString(sfErr_getOutput())); @@ -471,7 +471,7 @@ sfTexture* sfTexture_construct(); bool sfTexture_create(sfTexture* texture, uint width, uint height); //Create a new texture from a file -bool sfTexture_loadFromFile(sfTexture* texture, const(char)* filename, int left, int top, int width, int height); +bool sfTexture_loadFromFile(sfTexture* texture, const(char)* filename, size_t length, int left, int top, int width, int height); //Create a new texture from a file in memory bool sfTexture_loadFromMemory(sfTexture* texture, const(void)* data, size_t sizeInBytes, int left, int top, int width, int height); diff --git a/src/dsfml/network/ftp.d b/src/dsfml/network/ftp.d index 61f208c..aa6282e 100644 --- a/src/dsfml/network/ftp.d +++ b/src/dsfml/network/ftp.d @@ -77,20 +77,20 @@ class Ftp ///This function retrieves the sub-directories and files contained in the given directory. It is not recursive. The directory parameter is relative to the current working directory. /// ///Returns: Server response to the request. - ListingResponse getDirectoryListing(string directory = "") + ListingResponse getDirectoryListing(const(char)[] directory = "") { import dsfml.system.string; - return new ListingResponse(sfFtp_getDirectoryListing(sfPtr, toStringz(directory))); + return new ListingResponse(sfFtp_getDirectoryListing(sfPtr, directory.ptr, directory.length)); } ///Change the current working directory. /// ///The new directory must be relative to the current one. /// ///Returns: Server response to the request. - Response changeDirectory(string directory) + Response changeDirectory(const(char)[] directory) { import dsfml.system.string; - return new Response(sfFtp_changeDirectory(sfPtr,toStringz(directory))); + return new Response(sfFtp_changeDirectory(sfPtr, directory.ptr, directory.length)); } ///Connect to the specified FTP server. @@ -106,7 +106,7 @@ class Ftp ///Returns: Server response to the request. Response connect(IpAddress address, ushort port = 21, Duration timeout = Duration.zero()) { - return new Response(sfFtp_connect(sfPtr, address.m_address.ptr, port, timeout.total!"usecs")); + return new Response(sfFtp_connect(sfPtr, address.m_address.ptr, address.m_address.length, port, timeout.total!"usecs")); } ///Connect to the specified FTP server. @@ -120,9 +120,10 @@ class Ftp /// timeout = Maximum time to wait. /// ///Returns: Server response to the request. - Response connect(string address, ushort port = 21, Duration timeout = Duration.zero()) + Response connect(const(char)[] address, ushort port = 21, Duration timeout = Duration.zero()) { - return new Response(sfFtp_connect(sfPtr, IpAddress(address).m_address.ptr, port, timeout.total!"usecs")); + auto iaddress = IpAddress(address); + return new Response(sfFtp_connect(sfPtr, iaddress.m_address.ptr, iaddress.m_address.length, port, timeout.total!"usecs")); } ///Remove an existing directory. @@ -133,10 +134,10 @@ class Ftp /// name = Name of the directory to remove. /// ///Returns: Server response to the request. - Response deleteDirectory(string name) + Response deleteDirectory(const(char)[] name) { import dsfml.system.string; - return new Response(sfFtp_deleteDirectory(sfPtr, toStringz(name))); + return new Response(sfFtp_deleteDirectory(sfPtr, name.ptr, name.length)); } ///Remove an existing file. @@ -147,10 +148,10 @@ class Ftp /// name = Name of the file to remove. /// ///Returns: Server response to the request. - Response deleteFile(string name) + Response deleteFile(const(char)[] name) { import dsfml.system.string; - return new Response(sfFtp_deleteFile(sfPtr, toStringz(name))); + return new Response(sfFtp_deleteFile(sfPtr, name.ptr, name.length)); } ///Close the connection with the server. @@ -172,10 +173,10 @@ class Ftp /// mode = Transfer mode. /// ///Returns: Server response to the request. - Response download(string remoteFile, string localPath, TransferMode mode = TransferMode.Binary) + Response download(const(char)[] remoteFile, const(char)[] localPath, TransferMode mode = TransferMode.Binary) { import dsfml.system.string; - return new Response(sfFtp_download(sfPtr, toStringz(remoteFile),toStringz(localPath),mode)); + return new Response(sfFtp_download(sfPtr, remoteFile.ptr, remoteFile.length, localPath.ptr, localPath.length ,mode)); } ///Send a null command to keep the connection alive. @@ -207,10 +208,10 @@ class Ftp /// password = The password. /// ///Returns: Server response to the request. - Response login(string name, string password) + Response login(const(char)[] name, const(char)[] password) { import dsfml.system.string; - return new Response(sfFtp_login(sfPtr,toStringz(name), toStringz(password))); + return new Response(sfFtp_login(sfPtr, name.ptr, name.length, password.ptr, password.length)); } ///Go to the parent directory of the current one. @@ -230,10 +231,10 @@ class Ftp /// name = Name of the directory to create. /// ///Returns: Server response to the request. - Response createDirectory(string name) + Response createDirectory(const(char)[] name) { import dsfml.system.string; - return new Response(sfFtp_createDirectory(sfPtr, toStringz(name))); + return new Response(sfFtp_createDirectory(sfPtr, name.ptr, name.length)); } ///Rename an existing file. @@ -245,10 +246,10 @@ class Ftp /// newName = New name of the file. /// ///Returns: Server response to the request. - Response renameFile(string file, string newName) + Response renameFile(const(char)[] file, const(char)[] newName) { import dsfml.system.string; - return new Response(sfFtp_renameFile(sfPtr,toStringz(file),toStringz(newName))); + return new Response(sfFtp_renameFile(sfPtr, file.ptr, file.length, newName.ptr, newName.length)); } ///Upload a file to the server. @@ -261,10 +262,10 @@ class Ftp /// mode = Transfer mode. /// ///Returns: Server response to the request. - Response upload(string localFile, string remotePath, TransferMode mode = TransferMode.Binary) + Response upload(const(char)[] localFile, const(char)[] remotePath, TransferMode mode = TransferMode.Binary) { import dsfml.system.string; - return new Response(sfFtp_upload(sfPtr,toStringz(localFile),toStringz(remotePath),mode)); + return new Response(sfFtp_upload(sfPtr, localFile.ptr, localFile.length, remotePath.ptr, remotePath.length, mode)); } ///Send a command to the FTP server. @@ -276,9 +277,9 @@ class Ftp /// parameter = Command parameter. /// ///Returns: Server response to the request. - Response sendCommand(string command, string parameter) { + Response sendCommand(const(char)[] command, const(char)[] parameter) { import dsfml.system.string; - return new Response(sfFtp_sendCommand(sfPtr, toStringz(command), toStringz(parameter))); + return new Response(sfFtp_sendCommand(sfPtr, command.ptr, command.length, parameter.ptr, parameter.length)); } ///Specialization of FTP response returning a directory. @@ -584,7 +585,7 @@ void sfFtp_destroy(sfFtp* ftp); ///Connect to the specified FTP server -sfFtpResponse* sfFtp_connect(sfFtp* ftp, const(char)* serverIP, ushort port, long timeout); +sfFtpResponse* sfFtp_connect(sfFtp* ftp, const(char)* serverIP, size_t length, ushort port, long timeout); ///Log in using an anonymous account @@ -592,7 +593,7 @@ sfFtpResponse* sfFtp_loginAnonymous(sfFtp* ftp); ///Log in using a username and a password -sfFtpResponse* sfFtp_login(sfFtp* ftp, const(char)* userName, const(char)* password); +sfFtpResponse* sfFtp_login(sfFtp* ftp, const(char)* userName, size_t userNameLength, const(char)* password, size_t passwordLength); ///Close the connection with the server @@ -608,11 +609,11 @@ sfFtpDirectoryResponse* sfFtp_getWorkingDirectory(sfFtp* ftp); ///Get the contents of the given directory -sfFtpListingResponse* sfFtp_getDirectoryListing(sfFtp* ftp, const(char)* directory); +sfFtpListingResponse* sfFtp_getDirectoryListing(sfFtp* ftp, const(char)* directory, size_t length); ///Change the current working directory -sfFtpResponse* sfFtp_changeDirectory(sfFtp* ftp, const(char)* directory); +sfFtpResponse* sfFtp_changeDirectory(sfFtp* ftp, const(char)* directory, size_t length); ///Go to the parent directory of the current one @@ -620,27 +621,27 @@ sfFtpResponse* sfFtp_parentDirectory(sfFtp* ftp); ///Create a new directory -sfFtpResponse* sfFtp_createDirectory(sfFtp* ftp, const(char)* name); +sfFtpResponse* sfFtp_createDirectory(sfFtp* ftp, const(char)* name, size_t length); ///Remove an existing directory -sfFtpResponse* sfFtp_deleteDirectory(sfFtp* ftp, const(char)* name); +sfFtpResponse* sfFtp_deleteDirectory(sfFtp* ftp, const(char)* name, size_t length); ///Rename an existing file -sfFtpResponse* sfFtp_renameFile(sfFtp* ftp, const(char)* file, const(char)* newName); +sfFtpResponse* sfFtp_renameFile(sfFtp* ftp, const(char)* file, size_t fileLength, const(char)* newName, size_t newNameLength); ///Remove an existing file -sfFtpResponse* sfFtp_deleteFile(sfFtp* ftp, const(char)* name); +sfFtpResponse* sfFtp_deleteFile(sfFtp* ftp, const(char)* name, size_t length); ///Download a file from a FTP server -sfFtpResponse* sfFtp_download(sfFtp* ftp, const(char)* distantFile, const(char)* destPath, int mode); +sfFtpResponse* sfFtp_download(sfFtp* ftp, const(char)* distantFile, size_t distantFileLength, const(char)* destPath, size_t destPathLength, int mode); ///Upload a file to a FTP server -sfFtpResponse* sfFtp_upload(sfFtp* ftp, const(char)* localFile, const(char)* destPath, int mode); +sfFtpResponse* sfFtp_upload(sfFtp* ftp, const(char)* localFile, size_t localFileLength, const(char)* destPath, size_t destPathLength, int mode); ///Send a command to a FTP server -sfFtpResponse* sfFtp_sendCommand(sfFtp* ftp, const(char)* command, const(char)* parameter); \ No newline at end of file +sfFtpResponse* sfFtp_sendCommand(sfFtp* ftp, const(char)* command, size_t commandLength, const(char)* parameter, size_t parameterLength); \ No newline at end of file diff --git a/src/dsfml/network/http.d b/src/dsfml/network/http.d index 674ee00..88c379b 100644 --- a/src/dsfml/network/http.d +++ b/src/dsfml/network/http.d @@ -50,7 +50,7 @@ class Http { import dsfml.system.string; sfPtr = sfHttp_create(); - sfHttp_setHost(sfPtr, toStringz(host),port); + sfHttp_setHost(sfPtr, host.ptr, host.length ,port); } ///Destructor @@ -71,7 +71,7 @@ class Http void setHost(string host, ushort port = 0) { import dsfml.system.string; - sfHttp_setHost(sfPtr, toStringz(host),port); + sfHttp_setHost(sfPtr, host.ptr, host.length,port); } ///Send a HTTP request and return the server's response. @@ -116,9 +116,9 @@ class Http { import dsfml.system.string; sfPtrRequest = sfHttpRequest_create(); - sfHttpRequest_setUri(sfPtrRequest, toStringz(uri)); + sfHttpRequest_setUri(sfPtrRequest, uri.ptr, uri.length); sfHttpRequest_setMethod(sfPtrRequest, method); - sfHttpRequest_setBody(sfPtrRequest,toStringz(requestBody)); + sfHttpRequest_setBody(sfPtrRequest, requestBody.ptr, requestBody.length); } ///Destructor @@ -138,7 +138,7 @@ class Http void setBody(string requestBody) { import dsfml.system.string; - sfHttpRequest_setBody(sfPtrRequest,toStringz(requestBody)); + sfHttpRequest_setBody(sfPtrRequest, requestBody.ptr, requestBody.length); } ///Set the value of a field. @@ -148,10 +148,10 @@ class Http ///Params: /// field = Name of the field to set. /// value = Value of the field. - void setField(string feild, string value) + void setField(string field, string value) { import dsfml.system.string; - sfHttpRequest_setField(sfPtrRequest,toStringz(feild),toStringz(value)); + sfHttpRequest_setField(sfPtrRequest, field.ptr, field.length , value.ptr, value.length); } ///Set the HTTP version for the request. @@ -186,7 +186,7 @@ class Http void setUri(string uri) { import dsfml.system.string; - sfHttpRequest_setUri(sfPtrRequest,toStringz(uri)); + sfHttpRequest_setUri(sfPtrRequest, uri.ptr, uri.length); } } @@ -251,10 +251,10 @@ class Http /// field = Name of the field to get. /// ///Returns: Value of the field, or empty string if not found. - string getField(string field) + string getField(const(char)[] field) { import dsfml.system.string; - return dsfml.system.string.toString(sfHttpResponse_getField(sfPtrResponse,toStringz(field))); + return dsfml.system.string.toString(sfHttpResponse_getField(sfPtrResponse, field.ptr, field.length)); } ///Get the major HTTP version number of the response. @@ -333,7 +333,7 @@ void sfHttpRequest_destroy(sfHttpRequest* httpRequest); ///Set the value of a header field of a HTTP request -void sfHttpRequest_setField(sfHttpRequest* httpRequest, const(char)* field, const(char)* value); +void sfHttpRequest_setField(sfHttpRequest* httpRequest, const(char)* field, size_t fieldLength, const(char)* value, size_t valueLength); ///Set a HTTP request method @@ -341,7 +341,7 @@ void sfHttpRequest_setMethod(sfHttpRequest* httpRequest, int method); ///Set a HTTP request URI -void sfHttpRequest_setUri(sfHttpRequest* httpRequest, const(char)* uri); +void sfHttpRequest_setUri(sfHttpRequest* httpRequest, const(char)* uri, size_t length); ///Set the HTTP version of a HTTP request @@ -349,7 +349,7 @@ void sfHttpRequest_setHttpVersion(sfHttpRequest* httpRequest,uint major, uint mi ///Set the body of a HTTP request -void sfHttpRequest_setBody(sfHttpRequest* httpRequest, const(char)* ody); +void sfHttpRequest_setBody(sfHttpRequest* httpRequest, const(char)* ody, size_t length); //HTTP Response Functions @@ -359,7 +359,7 @@ void sfHttpResponse_destroy(sfHttpResponse* httpResponse); ///Get the value of a field of a HTTP response -const(char)* sfHttpResponse_getField(const sfHttpResponse* httpResponse, const(char)* field); +const(char)* sfHttpResponse_getField(const sfHttpResponse* httpResponse, const(char)* field, size_t length); ///Get the status code of a HTTP reponse @@ -389,7 +389,7 @@ void sfHttp_destroy(sfHttp* http); ///Set the target host of a HTTP object -void sfHttp_setHost(sfHttp* http, const(char)* host, ushort port); +void sfHttp_setHost(sfHttp* http, const(char)* host, size_t length, ushort port); ///Send a HTTP request and return the server's response. diff --git a/src/dsfml/network/ipaddress.d b/src/dsfml/network/ipaddress.d index 5c3da25..baec5f5 100644 --- a/src/dsfml/network/ipaddress.d +++ b/src/dsfml/network/ipaddress.d @@ -40,12 +40,11 @@ struct IpAddress /// ///Params: /// address = IP address or network name. - this(string address) + this(const(char)[] address) { - import dsfml.system.string; - sfIpAddress_fromString(toStringz(address) ,m_address.ptr); + sfIpAddress_fromString(address.ptr, address.length, m_address.ptr); } - + ///Construct the address from 4 bytes. /// ///Calling IpAddress(a, b, c, d) is equivalent to calling IpAddress("a.b.c.d"), but safer as it doesn't have to parse a string to get the address components. @@ -59,7 +58,7 @@ struct IpAddress { sfIpAddress_fromBytes(byte0,byte1, byte2, byte3, m_address.ptr); } - + ///Construct the address from a 32-bits integer. /// ///This constructor uses the internal representation of the address directly. It should be used only if you got that representation from IpAddress::ToInteger(). @@ -78,7 +77,7 @@ struct IpAddress ///Returns: 32-bits unsigned integer representation of the address. int toInteger() const { - return sfIpAddress_toInteger(m_address.ptr); + return sfIpAddress_toInteger(m_address.ptr, m_address.length); } ///Get a string representation of the address. @@ -86,19 +85,15 @@ struct IpAddress ///The returned string is the decimal representation of the IP address (like "192.168.1.56"), even if it was constructed from a host name. /// ///Returns: String representation of the address - string toString() const + void toString(scope void delegate(const char[]) sink) const { - import std.conv; - //TODO: possibly cache the string? Maybe with a needsUpdatingMethod? - - //Remove any null characters from the string representation int i = 0; - while((m_address[i] != 0) ) + while(( i < m_address.length && m_address[i] != 0) ) { ++i; } //and present the string. - return m_address[0..i].to!string(); + sink(m_address[0..i]); } ///Get the computer's local address. @@ -112,7 +107,7 @@ struct IpAddress sfIpAddress_getLocalAddress(temp.m_address.ptr); return temp; } - + ///Get the computer's public address. /// ///The public address is the address of the computer from the internet point of view, i.e. something like 89.54.1.169. @@ -129,12 +124,12 @@ struct IpAddress sfIpAddress_getPublicAddress(temp.m_address.ptr, timeout.total!"usecs"); return temp; } - - ///Value representing an empty/invalid address. + + ///Value representing an empty/invalid address. static immutable(IpAddress) None; - ///The "localhost" address (for connecting a computer to itself locally) + ///The "localhost" address (for connecting a computer to itself locally) static immutable(IpAddress) LocalHost; - ///The "broadcast" address (for sending UDP messages to everyone on a local network) + ///The "broadcast" address (for sending UDP messages to everyone on a local network) static immutable(IpAddress) Broadcast; static this() @@ -149,7 +144,7 @@ unittest version(DSFML_Unittest_Network) { import std.stdio; - + writeln("Unittest for IpAdress"); @@ -175,7 +170,7 @@ private extern(C): //Note: These functions rely on passing an existing array for the ipAddress. ///Create an address from a string -void sfIpAddress_fromString(const(char)* address, char* ipAddress); +void sfIpAddress_fromString(const(char)* address, size_t addressLength, char* ipAddress); ///Create an address from 4 bytes void sfIpAddress_fromBytes(ubyte byte0, ubyte byte1, ubyte byte2, ubyte byte3, char* ipAddress); @@ -184,7 +179,7 @@ void sfIpAddress_fromBytes(ubyte byte0, ubyte byte1, ubyte byte2, ubyte byte3, c void sfIpAddress_fromInteger(uint address, char* ipAddress); ///Get an integer representation of the address -uint sfIpAddress_toInteger(const(char)* ipAddress); +uint sfIpAddress_toInteger(const(char)* ipAddress, size_t length); ///Get the computer's local address void sfIpAddress_getLocalAddress(char* ipAddress); diff --git a/src/dsfml/system/string.d b/src/dsfml/system/string.d index 8d0e2b7..a227ae9 100644 --- a/src/dsfml/system/string.d +++ b/src/dsfml/system/string.d @@ -18,7 +18,7 @@ If you use this software in a product, an acknowledgment in the product document */ /** - *A module containing functions for interacting with strings going to and from + *A module containing functions for interacting with strings going to and from *a C/C++ library as well as converting between D's string types. This module has no dependencies *except for std.utf. */ @@ -36,53 +36,14 @@ immutable(T)[] toString(T)(in const(T)* str) pure return str[0..strlen(str)].idup; } -///Returns a pointer to a C style string created from a D string type -/// -///Params: -/// str = The D style string to convert. -/// -///Returns: the C style string pointer. -const(T)* toStringz(T)(in immutable(T)[] str) nothrow - if (is(T == dchar)||is(T == wchar)||is(T == char)) -{ - //TODO: get rid of GC usage without adding dependencies? - - //a means to store the copy after returning the address - static T[] copy; - - //if str is just "" - if(str.length == 0) - { - copy = new T[1]; - copy[0] = 0; - return copy.ptr; - } - - //Already zero terminated - if(str[$-1] == 0) - { - return str.ptr; - } - //not zero terminated - else - { - copy = new T[str.length+1]; - copy[0..str.length] = str[]; - copy[$-1] = 0; - - return copy.ptr; - - } -} - ///Returns the same string in a different utf encoding /// ///Params: /// str = The string to convert. /// ///Returns: the C style string pointer. -immutable(U)[] stringConvert(T, U)(in immutable(T)[] str) pure -if ((is(T == dchar)||is(T == wchar)||is(T == char)) && +immutable(U)[] stringConvert(T, U)(in T[] str) pure +if ((is(T == dchar)||is(T == wchar)||is(T == char)) && (is(U == dchar)||is(U == wchar)||is(U == char))) { import std.utf; @@ -123,21 +84,8 @@ unittest version(DSFML_Unittest_System) { import std.stdio; - - writeln("Unit test for string functions"); - - string str1 = "Hello, World"; - wstring str2 = "Hello, World"; - dstring str3 = "Hello, World"; - - const(char)* cstr1 = toStringz(str1); - const(wchar)* cstr2 = toStringz(str2); - const(dchar)* cstr3 = toStringz(str3); - - assert(strlen(cstr1) == 12); - assert(strlen(cstr2) == 12); - assert(strlen(cstr3) == 12); + writeln("Unit test for string functions"); } } diff --git a/src/dsfml/window/window.d b/src/dsfml/window/window.d index bb50a66..0f6f80a 100644 --- a/src/dsfml/window/window.d +++ b/src/dsfml/window/window.d @@ -95,8 +95,6 @@ class Window this(T)(VideoMode mode, immutable(T)[] title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) if (is(T == dchar)||is(T == wchar)||is(T == char)) { - import dsfml.system.string; - this(); create(mode, title, style, settings); } @@ -262,28 +260,30 @@ class Window /// ///Params: /// title = New title. - void setTitle(string newTitle) + void setTitle(const(char)[] newTitle) { import dsfml.system.string; - sfWindow_setUnicodeTitle(sfPtr, toStringz(stringConvert!(char, dchar)(newTitle))); + + auto convertedTitle = stringConvert!(char, dchar)(newTitle); + sfWindow_setUnicodeTitle(sfPtr, convertedTitle.ptr, convertedTitle.length); } ///Change the title of the window. /// ///Params: /// title = New title. - void setTitle(wstring newTitle) + void setTitle(const(wchar)[] newTitle) { import dsfml.system.string; - sfWindow_setUnicodeTitle(sfPtr, toStringz(stringConvert!(wchar, dchar)(newTitle))); + auto convertedTitle = stringConvert!(wchar, dchar)(newTitle); + sfWindow_setUnicodeTitle(sfPtr, convertedTitle.ptr, convertedTitle.length); } ///Change the title of the window. /// ///Params: /// title = New title. - void setTitle(dstring newTitle) + void setTitle(const(dchar)[] newTitle) { - import dsfml.system.string; - sfWindow_setUnicodeTitle(sfPtr, toStringz(newTitle)); + sfWindow_setUnicodeTitle(sfPtr, newTitle.ptr, newTitle.length); } ///Show or hide the window. @@ -351,10 +351,12 @@ class Window ///If the window was already created, it closes it first. If style contains Style::Fullscreen, then mode must be a valid video mode. /// ///The fourth parameter is an optional structure specifying advanced OpenGL context settings such as antialiasing, depth-buffer bits, etc. - void create(VideoMode mode, string title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) + void create(VideoMode mode, const(char)[] title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) { import dsfml.system.string; - sfWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, toStringz(stringConvert!(char,dchar)(title)), style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); + + auto convertedTitle = stringConvert!(char,dchar)(title); + sfWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, convertedTitle.ptr, convertedTitle.length, style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); err.write(dsfml.system.string.toString(sfErr_getOutput())); } ///Create (or recreate) the window. @@ -362,10 +364,11 @@ class Window ///If the window was already created, it closes it first. If style contains Style::Fullscreen, then mode must be a valid video mode. /// ///The fourth parameter is an optional structure specifying advanced OpenGL context settings such as antialiasing, depth-buffer bits, etc. - void create(VideoMode mode, wstring title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) + void create(VideoMode mode, const(wchar)[] title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) { import dsfml.system.string; - sfWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, toStringz(stringConvert!(wchar,dchar)(title)), style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); + auto convertedTitle = stringConvert!(wchar,dchar)(title); + sfWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, convertedTitle.ptr, convertedTitle.length, style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); err.write(dsfml.system.string.toString(sfErr_getOutput())); } ///Create (or recreate) the window. @@ -373,10 +376,10 @@ class Window ///If the window was already created, it closes it first. If style contains Style::Fullscreen, then mode must be a valid video mode. /// ///The fourth parameter is an optional structure specifying advanced OpenGL context settings such as antialiasing, depth-buffer bits, etc. - void create(VideoMode mode, dstring title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) + void create(VideoMode mode, const(dchar)[] title, Style style = Style.DefaultStyle, ref const(ContextSettings) settings = ContextSettings.Default) { import dsfml.system.string; - sfWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, toStringz(title), style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); + sfWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, title.ptr, title.length, style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); err.write(dsfml.system.string.toString(sfErr_getOutput())); } @@ -554,7 +557,7 @@ private extern(C): sfWindow* sfWindow_construct(); //Construct a new window (with a UTF-32 title) - void sfWindow_createFromSettings(sfWindow* window, uint width, uint height, uint bitsPerPixel, const(dchar)* title, int style, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); + void sfWindow_createFromSettings(sfWindow* window, uint width, uint height, uint bitsPerPixel, const(dchar)* title, size_t titleLength, int style, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); //Construct a window from an existing control void sfWindow_createFromHandle(sfWindow* window, WindowHandle handle, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); @@ -590,10 +593,10 @@ private extern(C): void sfWindow_setSize(sfWindow* window, uint width, uint height); //Change the title of a window - void sfWindow_setTitle(sfWindow* window, const(char)* title); + void sfWindow_setTitle(sfWindow* window, const(char)* title, size_t length); //Change the title of a window (with a UTF-32 string) - void sfWindow_setUnicodeTitle(sfWindow* window, const(dchar)* title); + void sfWindow_setUnicodeTitle(sfWindow* window, const(dchar)* title, size_t length); //Change a window's icon void sfWindow_setIcon(sfWindow* window, uint width, uint height, const(ubyte)* pixels); From 9f8f94b969c74c17416d77544f0ffca22633d22d Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Fri, 6 May 2016 03:18:26 -0700 Subject: [PATCH 19/27] Version field in dub.json --- dub.json | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/dub.json b/dub.json index f83c7f1..301c3a5 100644 --- a/dub.json +++ b/dub.json @@ -3,6 +3,7 @@ "description": "DSFML binding for SFML-The Simple and Fast Multimedia Library", "authors": ["Jeremy DeHaan"], "homepage": "https://github.com/Jebbs/DSFML", + "version":"2.3.0", "license": "Zlib", "dependencies": { "dsfml:audio": "~>2.3", @@ -18,9 +19,9 @@ "targetType": "library", "sourcePaths": ["src/dsfml/audio"], "libs": [ "dsfmlc-audio" ], - "dependencies": - { - "dsfml:system": "~>2.3" + "dependencies": + { + "dsfml:system": "~>2.3" } }, { @@ -28,8 +29,8 @@ "targetType": "library", "sourcePaths": ["src/dsfml/graphics"], "libs": [ "dsfmlc-graphics" ], - "dependencies": - { + "dependencies": + { "dsfml:system": "~>2.3", "dsfml:window": "~>2.3" } @@ -38,9 +39,9 @@ "name": "window", "sourcePaths": ["src/dsfml/window"], "libs": [ "dsfmlc-window" ], - "dependencies": - { - "dsfml:system": "~>2.3" + "dependencies": + { + "dsfml:system": "~>2.3" } }, { @@ -48,9 +49,9 @@ "targetType": "library", "sourcePaths": ["src/dsfml/network"], "libs": [ "dsfmlc-network" ], - "dependencies": - { - "dsfml:system": "~>2.3" + "dependencies": + { + "dsfml:system": "~>2.3" } }, { From e7315b343f2674b57cee640f0582e4456ca055e6 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Fri, 6 May 2016 03:18:37 -0700 Subject: [PATCH 20/27] actual version info --- dub.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dub.json b/dub.json index 301c3a5..21d9937 100644 --- a/dub.json +++ b/dub.json @@ -3,7 +3,7 @@ "description": "DSFML binding for SFML-The Simple and Fast Multimedia Library", "authors": ["Jeremy DeHaan"], "homepage": "https://github.com/Jebbs/DSFML", - "version":"2.3.0", + "version":"2.3", "license": "Zlib", "dependencies": { "dsfml:audio": "~>2.3", From 174c0db49e0245f87f915d6b91b5ed58dadddd14 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Fri, 6 May 2016 03:31:33 -0700 Subject: [PATCH 21/27] dub really wants a 3-part version Update unittests to handle the non-allocating toString() method --- dub.json | 7 ++++++- src/dsfml/graphics/texture.d | 7 ------- src/dsfml/network/ipaddress.d | 2 +- src/dsfml/network/udpsocket.d | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/dub.json b/dub.json index 21d9937..c3f066d 100644 --- a/dub.json +++ b/dub.json @@ -3,7 +3,7 @@ "description": "DSFML binding for SFML-The Simple and Fast Multimedia Library", "authors": ["Jeremy DeHaan"], "homepage": "https://github.com/Jebbs/DSFML", - "version":"2.3", + "version":"2.3.0", "license": "Zlib", "dependencies": { "dsfml:audio": "~>2.3", @@ -19,6 +19,7 @@ "targetType": "library", "sourcePaths": ["src/dsfml/audio"], "libs": [ "dsfmlc-audio" ], + "dflags":["-m32mscoff"], "dependencies": { "dsfml:system": "~>2.3" @@ -29,6 +30,7 @@ "targetType": "library", "sourcePaths": ["src/dsfml/graphics"], "libs": [ "dsfmlc-graphics" ], + "dflags":["-m32mscoff"], "dependencies": { "dsfml:system": "~>2.3", @@ -39,6 +41,7 @@ "name": "window", "sourcePaths": ["src/dsfml/window"], "libs": [ "dsfmlc-window" ], + "dflags":["-m32mscoff"], "dependencies": { "dsfml:system": "~>2.3" @@ -49,6 +52,7 @@ "targetType": "library", "sourcePaths": ["src/dsfml/network"], "libs": [ "dsfmlc-network" ], + "dflags":["-m32mscoff"], "dependencies": { "dsfml:system": "~>2.3" @@ -59,6 +63,7 @@ "targetType": "library", "importPaths": ["src/"], "sourcePaths": ["src/dsfml/system"], + "dflags":["-m32mscoff"], "libs": [ "dsfmlc-system" ] } ] diff --git a/src/dsfml/graphics/texture.d b/src/dsfml/graphics/texture.d index 693ebf0..df58533 100644 --- a/src/dsfml/graphics/texture.d +++ b/src/dsfml/graphics/texture.d @@ -391,11 +391,6 @@ class Texture { sfTexture_updateFromRenderWindow(sfPtr, window.sfPtr, x, y); } - - static void flush() - { - sfTexture_flush(); - } } unittest @@ -524,6 +519,4 @@ void sfTexture_bind(const sfTexture* texture); //Get the maximum texture size allowed uint sfTexture_getMaximumSize(); -void sfTexture_flush(); - const(char)* sfErr_getOutput(); diff --git a/src/dsfml/network/ipaddress.d b/src/dsfml/network/ipaddress.d index baec5f5..f7810ff 100644 --- a/src/dsfml/network/ipaddress.d +++ b/src/dsfml/network/ipaddress.d @@ -156,7 +156,7 @@ unittest IpAddress googleIP = IpAddress("google.com"); - writeln("Google's Ip address: ",googleIP.toString()); + writeln("Google's Ip address: ",googleIP); writeln("Your local Ip Address: ", IpAddress.getLocalAddress()); diff --git a/src/dsfml/network/udpsocket.d b/src/dsfml/network/udpsocket.d index bba5886..62c70c7 100644 --- a/src/dsfml/network/udpsocket.d +++ b/src/dsfml/network/udpsocket.d @@ -252,7 +252,7 @@ unittest serverSocket.receive(temp2,received, receivedFrom, receivedPort); //What did we get?! - writeln("The data received from ", receivedFrom.toString(), " at port ", receivedPort, " was: ", cast(string)temp2[0..received]); + writeln("The data received from ", receivedFrom, " at port ", receivedPort, " was: ", cast(string)temp2[0..received]); writeln(); From bcb1ee349a67e15247ebf2f4fb33b314100d727f Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Fri, 6 May 2016 03:58:42 -0700 Subject: [PATCH 22/27] Cache names of joysticks to avoid unnecessary allocations. Using a different approach here to what the cached VideoMode and AudioDevice lists use since SFML explicitly expects joysticks to be hotpluggable. --- src/dsfml/window/joystick.d | 38 ++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/dsfml/window/joystick.d b/src/dsfml/window/joystick.d index 1b793bb..e4cc725 100644 --- a/src/dsfml/window/joystick.d +++ b/src/dsfml/window/joystick.d @@ -38,8 +38,30 @@ final abstract class Joystick { ///Structure holding a joystick's identification; struct Identification { + private static dstring[uint[2]] nameCache; + ///Index of the joystick + uint index; ///Name of the joystick - dstring name; + @property dstring name() { + //In theory, each vid:pid combination should only have one name associated with it. + auto cachedName = [vendorId, productId] in nameCache; + if (cachedName !is null) { + return *cachedName; + } else { + import std.exception; + + dchar[] retrievedName; + + retrievedName.length = sfJoystick_getIdentificationNameLength(index); + + sfJoystick_getIdentificationName(index, retrievedName.ptr); + + nameCache[[vendorId, productId]] = assumeUnique(retrievedName); + + return assumeUnique(retrievedName); + } + } + ///Manufacturer identifier uint vendorId; ///Product identifier @@ -112,14 +134,9 @@ final abstract class Joystick /// ///Returns: Structure containing the joystick information. static Identification getIdentification(uint joystick) { - import std.exception; Identification identification; - dchar[] name; - name.length = sfJoystick_getIdentificationNameSize(joystick); - sfJoystick_getIdentification(joystick, name.ptr, &identification.vendorId, &identification.productId); - - identification.name = assumeUnique(name); + sfJoystick_getIdentification(joystick, &identification.vendorId, &identification.productId); return identification; } @@ -237,10 +254,13 @@ bool sfJoystick_isConnected(uint joystick); uint sfJoystick_getButtonCount(uint joystick); //Return the length of the joystick identification structure's name -size_t sfJoystick_getIdentificationNameSize(uint joystick); +size_t sfJoystick_getIdentificationNameLength(uint joystick); + +//Write the name of the joystick into a D-allocated string buffer. +void sfJoystick_getIdentificationName (uint joystick, dchar* nameBuffer); //Return the identification structure for a joystick -void sfJoystick_getIdentification(uint joystick, dchar* nameBuffer, uint* vendorID, uint* productId); +void sfJoystick_getIdentification(uint joystick, uint* vendorID, uint* productId); //Check if a joystick supports a given axis bool sfJoystick_hasAxis(uint joystick, int axis); From ee78d8661a333f54130058a92f54c9aff6cadeb2 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Fri, 6 May 2016 04:11:31 -0700 Subject: [PATCH 23/27] make AA key immutable just for good measure. --- src/dsfml/window/joystick.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dsfml/window/joystick.d b/src/dsfml/window/joystick.d index e4cc725..42c1b57 100644 --- a/src/dsfml/window/joystick.d +++ b/src/dsfml/window/joystick.d @@ -38,7 +38,7 @@ final abstract class Joystick { ///Structure holding a joystick's identification; struct Identification { - private static dstring[uint[2]] nameCache; + private static dstring[immutable(uint)[2]] nameCache; ///Index of the joystick uint index; ///Name of the joystick From 801e3cddccfbbce5574aec506c5ec1ae83538fa8 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Fri, 6 May 2016 04:26:39 -0700 Subject: [PATCH 24/27] Switch branges on CI build files again. --- .travis.yml | 130 ++++++++-------- appveyor.yml | 408 +++++++++++++++++++++++++-------------------------- 2 files changed, 269 insertions(+), 269 deletions(-) diff --git a/.travis.yml b/.travis.yml index 21bfefa..a79653e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,65 +1,65 @@ -os: - - linux - - osx - -language: d - -sudo: false - -addons: - apt: - packages: - - libfreetype6-dev - - libgl1-mesa-dev - - libglew-dev - - libjpeg8-dev - - libopenal-dev - - libpthread-stubs0-dev - - libsndfile1-dev - - libx11-dev - - libx11-xcb-dev - - libxrandr-dev - - libxcb-image0-dev - - libxcb-randr0-dev - - libudev-dev - - libvorbis-dev - - libflac-dev - -d: - - dmd-2.069.2 - - dmd-2.068.2 - - dmd-2.067.1 - - dmd-2.066.1 - - gdc-5.2.0 - - gdc-4.9.3 - - gdc-4.8.2 - - ldc-0.16.1 - - ldc-0.16.0 - - ldc-0.15.1 - -#GDC is not supported on OS X :( -matrix: - exclude: - - os: osx - d: gdc-5.2.0 - - os: osx - d: gdc-4.9.3 - - os: osx - d: gdc-4.8.2 - -#Build and install DSFMLC -install: - - cd $HOME - - git clone --depth=1 --branch 2.3 https://github.com/aubade/DSFMLC.git - - cd DSFMLC - - cmake . - - make -j2 - - export LIBRARY_PATH=${HOME}/DSFMLC/lib - - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${HOME}/DSFMLC/lib - - cd $TRAVIS_BUILD_DIR - -script: - - ${DMD} build.d - - ./build -unittest - - +os: + - linux + - osx + +language: d + +sudo: false + +addons: + apt: + packages: + - libfreetype6-dev + - libgl1-mesa-dev + - libglew-dev + - libjpeg8-dev + - libopenal-dev + - libpthread-stubs0-dev + - libsndfile1-dev + - libx11-dev + - libx11-xcb-dev + - libxrandr-dev + - libxcb-image0-dev + - libxcb-randr0-dev + - libudev-dev + - libvorbis-dev + - libflac-dev + +d: + - dmd-2.069.2 + - dmd-2.068.2 + - dmd-2.067.1 + - dmd-2.066.1 + - gdc-5.2.0 + - gdc-4.9.3 + - gdc-4.8.2 + - ldc-0.16.1 + - ldc-0.16.0 + - ldc-0.15.1 + +#GDC is not supported on OS X :( +matrix: + exclude: + - os: osx + d: gdc-5.2.0 + - os: osx + d: gdc-4.9.3 + - os: osx + d: gdc-4.8.2 + +#Build and install DSFMLC +install: + - cd $HOME + - git clone --depth=1 --branch 2.3-passthrough https://github.com/aubade/DSFMLC.git + - cd DSFMLC + - cmake . + - make -j2 + - export LIBRARY_PATH=${HOME}/DSFMLC/lib + - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${HOME}/DSFMLC/lib + - cd $TRAVIS_BUILD_DIR + +script: + - ${DMD} build.d + - ./build -unittest + + diff --git a/appveyor.yml b/appveyor.yml index 700a0c3..0273764 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,204 +1,204 @@ -# Build version format -version: 2.1.{build} - -os: Visual Studio 2015 - -clone_depth: 1 - -#Let's blacklist gh-pages -branches: - except: - - gh-pages - -environment: - matrix: - - DC: dmd - DVersion: 2.069.2 - arch: x86 - - DC: dmd - DVersion: 2.069.2 - arch: x64 - - DC: dmd - DVersion: 2.068.2 - arch: x86 - - DC: dmd - DVersion: 2.068.2 - arch: x64 - - DC: dmd - DVersion: 2.067.1 - arch: x86 - - DC: dmd - DVersion: 2.067.1 - arch: x64 - - DC: dmd - DVersion: 2.066.1 - arch: x86 - - DC: dmd - DVersion: 2.066.1 - arch: x64 - - DC: gdc - DVersion: 5.2.0 - arch: x86 - - DC: gdc - DVersion: 5.2.0 - arch: x64 - - DC: gdc - DVersion: 4.9.3 - arch: x86 - - DC: gdc - DVersion: 4.9.3 - arch: x64 - - DC: ldc - DVersion: 0.16.1 - arch: x64 -#0.15.1 doesn't work properly on Windows due to poor x64 support. -# - DC: ldc -# DVersion: 0.15.1 -# arch: x64 - - -#Set up our powershell functions -init: -#putting these in here for now, will export to different script to be imported later maybe? -- ps: function SetUpDCompiler - { - if($env:DC -eq "dmd"){ - if($env:arch -eq "x86"){ - $env:DConf = "m32"; - } - elseif($env:arch -eq "x64"){ - $env:DConf = "m64"; - } - $env:toolchain = "msvc"; - $version = $env:DVersion; - $WebLocation = "http://downloads.dlang.org/releases/2.x/$($version)/dmd.$($version).windows.zip"; - $DownloadLocation = "c:\dmd.zip"; - (new-object net.webclient).DownloadFile($WebLocation, $DownloadLocation); - pushd c:\\; - 7z x dmd.zip > $null; - popd; - } - elseif($env:DC -eq "gdc"){ - if($env:arch -eq "x86"){ - $env:DConf = "m32"; - $version = $env:DVersion; - $WebLocation = "ftp://ftp.gdcproject.org/binaries/$($version)/i686-w64-mingw32/gdc-$($version)+2.066.1.7z"; - $mingwWebLocation = "http://dsfml.com/bins/mingw/i686-5.2.0-release-posix-dwarf-rt_v4-rev0.7z"; - } - elseif($env:arch -eq "x64"){ - $env:DConf = "m64"; - $version = $env:DVersion; - $WebLocation = "ftp://ftp.gdcproject.org/binaries/$($version)/x86_64-w64-mingw32/gdc-$($version)+2.066.1.7z"; - $mingwWebLocation = "http://dsfml.com/bins/mingw/x86_64-5.2.0-release-posix-seh-rt_v4-rev0.7z"; - } - $env:toolchain = "mingw"; - $DownloadLocation = "c:\gdc.7z"; - $mingwDownloadLocation = "c:\mingw.7z"; - (new-object net.webclient).DownloadFile($WebLocation, $DownloadLocation); - (new-object net.webclient).DownloadFile($mingwWebLocation, $mingwDownloadLocation); - pushd c:\\; - 7z x gdc.7z > $null; - 7z x mingw.7z > $null; - popd; - } - elseif($env:DC -eq "ldc"){ - if($env:arch -eq "x86"){ - $env:DConf = "m32"; - } - elseif($env:arch -eq "x64"){ - $env:DConf = "m64"; - } - $env:toolchain = "msvc"; - $version = $env:DVersion; - $WebLocation = "https://github.com/ldc-developers/ldc/releases/download/v$($version)/ldc2-$($version)-win64-msvc.zip"; - $DownloadLocation = "c:\ldc.zip"; - (new-object net.webclient).DownloadFile($WebLocation, $DownloadLocation); - pushd c:\\; - 7z x ldc.zip > $null; - popd; - } - } - - - -install: -#Install the D compiler -- ps: SetUpDCompiler - - -before_build: -#Set's up MSVC and MinGW -#We can't use the default PATH when using MinGW because another MinGW is on the path and it messes things up. -#We also have to set up MSVC because I couldn't get the script to work with IF statements. :( - - ps: if($env:toolchain -eq "msvc"){ - if($env:arch -eq "x86"){ - $env:compilersetup = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall"; - $env:compilersetupargs = "x86"; - } - elseif($env:arch -eq "x64"){ - $env:compilersetup = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall"; - $env:compilersetupargs = "amd64"; - } - $env:maketype = "NMake Makefiles"; - $env:makecommand = "nmake"; - } - elseif($env:toolchain -eq "mingw"){ - if($env:arch -eq "x86"){ - $env:compilerpath = "C:\mingw32\bin;"; - $env:cmakepath = "C:\Program Files (x86)\CMake\bin"; - } - elseif($env:arch -eq "x64"){ - $env:compilerpath = "C:\mingw64\bin;"; - $env:cmakepath = "C:\Program Files (x86)\CMake\bin"; - } - $env:compilersetup = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall"; - $env:compilersetupargs = "x86"; - $env:maketype = "MinGW Makefiles"; - $env:makecommand = "mingw32-make"; - } -#Set's up our D compiler - - ps : if($env:DC -eq "dmd"){ - $env:Dcompilerpath = "C:\dmd2\windows\bin;"; - $env:outputfile = "-ofbuild.exe"; - if($env:arch -eq "x86"){ - $env:makecommand = "nmake & implib"; - } - } - elseif($env:DC -eq "gdc"){ - $env:outputfile = "-obuild.exe"; - if($env:arch -eq "x86"){ - $env:Dcompilerpath = "C:\i686-w64-mingw32\bin;"; - } - elseif($env:arch -eq "x64"){ - $env:Dcompilerpath = "C:\x86_64-w64-mingw32\bin;"; - } - } - elseif($env:DC -eq "ldc"){ - $version = $env:DVersion; - $env:Dcompilerpath = "C:\ldc2-$($version)-win64-msvc\bin;"; - $env:outputfile = "-of=build.exe"; - $env:DC = "ldc2"; - } - - - -#Build DSFMLC and then build DSFML with it -build_script: -- echo %VCINSTALLDIR% -- '"%compilersetup%" %compilersetupargs%' -- cd .. -- git clone --depth=1 --branch 2.3 https://github.com/aubade/DSFMLC.git -- cd DSFMLC -- ps: if($env:toolchain -eq "mingw"){ - $env:Path = $env:compilerpath + $env:cmakepath; - } -- cmake -G"%maketype%" . -- '%makecommand%' -- cd "C:\\projects\\dsfml" -- ps : $env:Path = $env:Dcompilerpath + $env:Path -- ps: if($env:DC -eq "ldc2"){ - $env:compilersetup = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall"; - } -- '"%compilersetup%" %compilersetupargs%' -- '%DC% build.d %outputfile%' -- 'build.exe -%DConf% -unittest:C:\projects\DSFMLC\lib\' +# Build version format +version: 2.1.{build} + +os: Visual Studio 2015 + +clone_depth: 1 + +#Let's blacklist gh-pages +branches: + except: + - gh-pages + +environment: + matrix: + - DC: dmd + DVersion: 2.069.2 + arch: x86 + - DC: dmd + DVersion: 2.069.2 + arch: x64 + - DC: dmd + DVersion: 2.068.2 + arch: x86 + - DC: dmd + DVersion: 2.068.2 + arch: x64 + - DC: dmd + DVersion: 2.067.1 + arch: x86 + - DC: dmd + DVersion: 2.067.1 + arch: x64 + - DC: dmd + DVersion: 2.066.1 + arch: x86 + - DC: dmd + DVersion: 2.066.1 + arch: x64 + - DC: gdc + DVersion: 5.2.0 + arch: x86 + - DC: gdc + DVersion: 5.2.0 + arch: x64 + - DC: gdc + DVersion: 4.9.3 + arch: x86 + - DC: gdc + DVersion: 4.9.3 + arch: x64 + - DC: ldc + DVersion: 0.16.1 + arch: x64 +#0.15.1 doesn't work properly on Windows due to poor x64 support. +# - DC: ldc +# DVersion: 0.15.1 +# arch: x64 + + +#Set up our powershell functions +init: +#putting these in here for now, will export to different script to be imported later maybe? +- ps: function SetUpDCompiler + { + if($env:DC -eq "dmd"){ + if($env:arch -eq "x86"){ + $env:DConf = "m32"; + } + elseif($env:arch -eq "x64"){ + $env:DConf = "m64"; + } + $env:toolchain = "msvc"; + $version = $env:DVersion; + $WebLocation = "http://downloads.dlang.org/releases/2.x/$($version)/dmd.$($version).windows.zip"; + $DownloadLocation = "c:\dmd.zip"; + (new-object net.webclient).DownloadFile($WebLocation, $DownloadLocation); + pushd c:\\; + 7z x dmd.zip > $null; + popd; + } + elseif($env:DC -eq "gdc"){ + if($env:arch -eq "x86"){ + $env:DConf = "m32"; + $version = $env:DVersion; + $WebLocation = "ftp://ftp.gdcproject.org/binaries/$($version)/i686-w64-mingw32/gdc-$($version)+2.066.1.7z"; + $mingwWebLocation = "http://dsfml.com/bins/mingw/i686-5.2.0-release-posix-dwarf-rt_v4-rev0.7z"; + } + elseif($env:arch -eq "x64"){ + $env:DConf = "m64"; + $version = $env:DVersion; + $WebLocation = "ftp://ftp.gdcproject.org/binaries/$($version)/x86_64-w64-mingw32/gdc-$($version)+2.066.1.7z"; + $mingwWebLocation = "http://dsfml.com/bins/mingw/x86_64-5.2.0-release-posix-seh-rt_v4-rev0.7z"; + } + $env:toolchain = "mingw"; + $DownloadLocation = "c:\gdc.7z"; + $mingwDownloadLocation = "c:\mingw.7z"; + (new-object net.webclient).DownloadFile($WebLocation, $DownloadLocation); + (new-object net.webclient).DownloadFile($mingwWebLocation, $mingwDownloadLocation); + pushd c:\\; + 7z x gdc.7z > $null; + 7z x mingw.7z > $null; + popd; + } + elseif($env:DC -eq "ldc"){ + if($env:arch -eq "x86"){ + $env:DConf = "m32"; + } + elseif($env:arch -eq "x64"){ + $env:DConf = "m64"; + } + $env:toolchain = "msvc"; + $version = $env:DVersion; + $WebLocation = "https://github.com/ldc-developers/ldc/releases/download/v$($version)/ldc2-$($version)-win64-msvc.zip"; + $DownloadLocation = "c:\ldc.zip"; + (new-object net.webclient).DownloadFile($WebLocation, $DownloadLocation); + pushd c:\\; + 7z x ldc.zip > $null; + popd; + } + } + + + +install: +#Install the D compiler +- ps: SetUpDCompiler + + +before_build: +#Set's up MSVC and MinGW +#We can't use the default PATH when using MinGW because another MinGW is on the path and it messes things up. +#We also have to set up MSVC because I couldn't get the script to work with IF statements. :( + - ps: if($env:toolchain -eq "msvc"){ + if($env:arch -eq "x86"){ + $env:compilersetup = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall"; + $env:compilersetupargs = "x86"; + } + elseif($env:arch -eq "x64"){ + $env:compilersetup = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall"; + $env:compilersetupargs = "amd64"; + } + $env:maketype = "NMake Makefiles"; + $env:makecommand = "nmake"; + } + elseif($env:toolchain -eq "mingw"){ + if($env:arch -eq "x86"){ + $env:compilerpath = "C:\mingw32\bin;"; + $env:cmakepath = "C:\Program Files (x86)\CMake\bin"; + } + elseif($env:arch -eq "x64"){ + $env:compilerpath = "C:\mingw64\bin;"; + $env:cmakepath = "C:\Program Files (x86)\CMake\bin"; + } + $env:compilersetup = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall"; + $env:compilersetupargs = "x86"; + $env:maketype = "MinGW Makefiles"; + $env:makecommand = "mingw32-make"; + } +#Set's up our D compiler + - ps : if($env:DC -eq "dmd"){ + $env:Dcompilerpath = "C:\dmd2\windows\bin;"; + $env:outputfile = "-ofbuild.exe"; + if($env:arch -eq "x86"){ + $env:makecommand = "nmake & implib"; + } + } + elseif($env:DC -eq "gdc"){ + $env:outputfile = "-obuild.exe"; + if($env:arch -eq "x86"){ + $env:Dcompilerpath = "C:\i686-w64-mingw32\bin;"; + } + elseif($env:arch -eq "x64"){ + $env:Dcompilerpath = "C:\x86_64-w64-mingw32\bin;"; + } + } + elseif($env:DC -eq "ldc"){ + $version = $env:DVersion; + $env:Dcompilerpath = "C:\ldc2-$($version)-win64-msvc\bin;"; + $env:outputfile = "-of=build.exe"; + $env:DC = "ldc2"; + } + + + +#Build DSFMLC and then build DSFML with it +build_script: +- echo %VCINSTALLDIR% +- '"%compilersetup%" %compilersetupargs%' +- cd .. +- git clone --depth=1 --branch 2.3-stringpassthrough https://github.com/aubade/DSFMLC.git +- cd DSFMLC +- ps: if($env:toolchain -eq "mingw"){ + $env:Path = $env:compilerpath + $env:cmakepath; + } +- cmake -G"%maketype%" . +- '%makecommand%' +- cd "C:\\projects\\dsfml" +- ps : $env:Path = $env:Dcompilerpath + $env:Path +- ps: if($env:DC -eq "ldc2"){ + $env:compilersetup = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall"; + } +- '"%compilersetup%" %compilersetupargs%' +- '%DC% build.d %outputfile%' +- 'build.exe -%DConf% -unittest:C:\projects\DSFMLC\lib\' From 2af81ab2fcf53430b783838e16243e027680c2b8 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Fri, 6 May 2016 04:37:37 -0700 Subject: [PATCH 25/27] branch name typo --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a79653e..4d0cc24 100644 --- a/.travis.yml +++ b/.travis.yml @@ -50,7 +50,7 @@ matrix: #Build and install DSFMLC install: - cd $HOME - - git clone --depth=1 --branch 2.3-passthrough https://github.com/aubade/DSFMLC.git + - git clone --depth=1 --branch 2.3-stringpassthrough https://github.com/aubade/DSFMLC.git - cd DSFMLC - cmake . - make -j2 From 347f2e5b2ce7c17d485862235cc21d183638128f Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Fri, 6 May 2016 05:31:13 -0700 Subject: [PATCH 26/27] Slightly arcane AA key building syntax to hopefully make GDC happy. --- src/dsfml/window/joystick.d | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/dsfml/window/joystick.d b/src/dsfml/window/joystick.d index 42c1b57..8a32c21 100644 --- a/src/dsfml/window/joystick.d +++ b/src/dsfml/window/joystick.d @@ -44,7 +44,13 @@ final abstract class Joystick ///Name of the joystick @property dstring name() { //In theory, each vid:pid combination should only have one name associated with it. - auto cachedName = [vendorId, productId] in nameCache; + //slightly arcane syntax to make older GDC happy. + uint[2] tempkey; + tempkey[0] = vendorId; + tempkey[1] = productId; + immutable(uint)[2] key = tempkey; + + dstring* cachedName = (key in nameCache); if (cachedName !is null) { return *cachedName; } else { @@ -56,7 +62,7 @@ final abstract class Joystick sfJoystick_getIdentificationName(index, retrievedName.ptr); - nameCache[[vendorId, productId]] = assumeUnique(retrievedName); + nameCache[key] = assumeUnique(retrievedName); return assumeUnique(retrievedName); } From 014dc9acca266e0dddcf15926a3275af837bbc8c Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Fri, 6 May 2016 08:01:17 -0700 Subject: [PATCH 27/27] Make the name return code actually work the first time it's run. --- src/dsfml/window/joystick.d | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dsfml/window/joystick.d b/src/dsfml/window/joystick.d index 8a32c21..5db0ade 100644 --- a/src/dsfml/window/joystick.d +++ b/src/dsfml/window/joystick.d @@ -57,14 +57,15 @@ final abstract class Joystick import std.exception; dchar[] retrievedName; + dstring retval; retrievedName.length = sfJoystick_getIdentificationNameLength(index); sfJoystick_getIdentificationName(index, retrievedName.ptr); - nameCache[key] = assumeUnique(retrievedName); + nameCache[key] = retval = assumeUnique(retrievedName); - return assumeUnique(retrievedName); + return retval; } }