From 8d445577d200a14590aa315ea5c1b2367df083b6 Mon Sep 17 00:00:00 2001 From: "E.S. Quinn" Date: Mon, 23 May 2016 16:42:21 -0700 Subject: [PATCH] String passthrough, D-side Accept const(char)[] where feasible Cache Joystick Identification --- .travis.yml | 130 ++-- appveyor.yml | 408 +++++------ dub.json | 23 +- 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 | 40 +- src/dsfml/graphics/shader.d | 119 ++-- src/dsfml/graphics/text.d | 2 +- src/dsfml/graphics/texture.d | 1044 ++++++++++++++--------------- src/dsfml/network/ftp.d | 69 +- src/dsfml/network/http.d | 30 +- src/dsfml/network/ipaddress.d | 39 +- src/dsfml/network/udpsocket.d | 2 +- src/dsfml/system/string.d | 60 +- src/dsfml/window/joystick.d | 45 +- src/dsfml/window/window.d | 39 +- 20 files changed, 1090 insertions(+), 1110 deletions(-) diff --git a/.travis.yml b/.travis.yml index 21bfefa..1a43253 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 https://github.com/Jebbs/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..667b6bd 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 https://github.com/Jebbs/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\' 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" } }, { 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..66fff5d 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,10 @@ 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 +842,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 +884,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/text.d b/src/dsfml/graphics/text.d index b72f283..a114747 100644 --- a/src/dsfml/graphics/text.d +++ b/src/dsfml/graphics/text.d @@ -34,7 +34,7 @@ import dsfml.graphics.primitivetype; import dsfml.system.vector2; -import std.typecons:Rebindable; +import std.typecons: Rebindable; /++ + Graphical text that can be drawn to a render target. diff --git a/src/dsfml/graphics/texture.d b/src/dsfml/graphics/texture.d index fbcd04f..df58533 100644 --- a/src/dsfml/graphics/texture.d +++ b/src/dsfml/graphics/texture.d @@ -1,522 +1,522 @@ -/* -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(const(char)[] filename, IntRect area = IntRect() ) + { + import dsfml.system.string; + + 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())); + } + + 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, 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); + +//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(); 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..f7810ff 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"); @@ -161,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()); @@ -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/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(); 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/joystick.d b/src/dsfml/window/joystick.d index 1b793bb..5db0ade 100644 --- a/src/dsfml/window/joystick.d +++ b/src/dsfml/window/joystick.d @@ -38,8 +38,37 @@ final abstract class Joystick { ///Structure holding a joystick's identification; struct Identification { + private static dstring[immutable(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. + //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 { + import std.exception; + + dchar[] retrievedName; + dstring retval; + + retrievedName.length = sfJoystick_getIdentificationNameLength(index); + + sfJoystick_getIdentificationName(index, retrievedName.ptr); + + nameCache[key] = retval = assumeUnique(retrievedName); + + return retval; + } + } + ///Manufacturer identifier uint vendorId; ///Product identifier @@ -112,14 +141,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 +261,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); 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);