├── .github └── workflows │ ├── python-package-macos.yml │ ├── python-package-ubuntu.yml │ └── python-package-windows.yml ├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.md ├── examples ├── embedding │ ├── image.jpg │ ├── main.cpp │ └── script.py ├── extending │ ├── extension.pyx │ ├── extension.pyxbld │ ├── image.jpg │ └── main.py ├── ftp │ └── ftp.py ├── opengl │ ├── opengl.py │ └── resources │ │ ├── background.jpg │ │ ├── sansation.ttf │ │ └── texture.jpg ├── pong │ ├── data │ │ ├── ball.wav │ │ └── sansation.ttf │ └── pong.py ├── pyqt4 │ ├── data │ │ └── head_kid.png │ ├── pyqt4.py │ └── qsfml_canvas.py ├── pyqt5 │ ├── data │ │ └── head_kid.png │ ├── pyqt5.py │ └── qsfml_canvas.py ├── shader │ ├── data │ │ ├── background.jpg │ │ ├── blink.frag │ │ ├── blur.frag │ │ ├── devices.png │ │ ├── edge.frag │ │ ├── pixelate.frag │ │ ├── sansation.ttf │ │ ├── sfml.png │ │ ├── storm.vert │ │ ├── text-background.png │ │ ├── text.txt │ │ └── wave.vert │ └── shader.py ├── sockets │ └── sockets.py ├── sound │ ├── data │ │ ├── canary.wav │ │ └── orchestral.ogg │ └── sound.py ├── sound_capture │ └── sound_capture.py └── voip │ ├── client.py │ ├── server.py │ └── voip.py ├── extlibs ├── libs-msvc-universal │ ├── x64 │ │ ├── flac.lib │ │ ├── freetype.lib │ │ ├── jpeg.lib │ │ ├── ogg.lib │ │ ├── openal32.lib │ │ ├── vorbis.lib │ │ ├── vorbisenc.lib │ │ └── vorbisfile.lib │ └── x86 │ │ ├── flac.lib │ │ ├── freetype.lib │ │ ├── jpeg.lib │ │ ├── ogg.lib │ │ ├── openal32.lib │ │ ├── vorbis.lib │ │ ├── vorbisenc.lib │ │ └── vorbisfile.lib ├── x64 │ └── openal32.dll └── x86 │ └── openal32.dll ├── include └── Includes │ ├── pysfml │ ├── __init__.py │ ├── audio.pxd │ ├── graphics.pxd │ ├── network.pxd │ ├── system.pxd │ └── window.pxd │ ├── sfml.pxd │ └── sfml │ ├── __init__.py │ ├── blendmode.pxd │ ├── contextsettings.pxd │ ├── event.pxd │ ├── font.pxd │ ├── ftp.pxd │ ├── ftp │ ├── __init__.py │ └── response.pxd │ ├── http.pxd │ ├── http │ ├── __init__.py │ ├── request.pxd │ └── response.pxd │ ├── ipaddress.pxd │ ├── joystick.pxd │ ├── keyboard.pxd │ ├── listener.pxd │ ├── mouse.pxd │ ├── primitivetype.pxd │ ├── renderstates.pxd │ ├── sensor.pxd │ ├── sfml.pxd │ ├── shader.pxd │ ├── socket.pxd │ ├── soundrecorder.pxd │ ├── soundsource.pxd │ ├── soundstream.pxd │ ├── style.pxd │ ├── text.pxd │ ├── texture.pxd │ ├── time.pxd │ ├── touch.pxd │ ├── transform.pxd │ ├── udpsocket.pxd │ └── videomode.pxd ├── requirements.txt ├── setup.py └── src └── sfml ├── __init__.py ├── audio ├── DerivableSoundRecorder.cpp ├── DerivableSoundRecorder.hpp ├── DerivableSoundStream.cpp ├── DerivableSoundStream.hpp └── audio.pyx ├── graphics ├── DerivableDrawable.cpp ├── DerivableDrawable.hpp ├── DerivableRenderWindow.cpp ├── DerivableRenderWindow.hpp ├── NumericObject.cpp ├── NumericObject.hpp └── graphics.pyx ├── network └── network.pyx ├── sf.py ├── system ├── NumericObject.cpp ├── NumericObject.hpp ├── error.cpp ├── error.hpp ├── hacks.cpp ├── hacks.hpp └── system.pyx └── window ├── DerivableWindow.cpp ├── DerivableWindow.hpp └── window.pyx /.github/workflows/python-package-macos.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions 3 | 4 | name: Python package for macOS 5 | 6 | env: 7 | SFML_VERSION: 2.5.1 8 | 9 | on: 10 | push: 11 | branches: [ master ] 12 | pull_request: 13 | branches: [ master ] 14 | 15 | jobs: 16 | build: 17 | 18 | runs-on: macos-latest 19 | 20 | steps: 21 | - uses: actions/checkout@v2 22 | - name: Set up Python 3.x 23 | uses: actions/setup-python@v1 24 | with: 25 | python-version: '3.x' 26 | - name: Install dependencies 27 | run: | 28 | curl -O https://www.sfml-dev.org/files/SFML-$SFML_VERSION-macOS-clang.tar.gz 29 | tar -xvf SFML-$SFML_VERSION-macOS-clang.tar.gz 30 | working-directory: $HOME 31 | - name: Build bindings 32 | run: | 33 | python -m pip install --upgrade pip 34 | pip install -r requirements.txt 35 | python setup.py build 36 | env: 37 | CPLUS_INCLUDE_PATH: $HOME/SFML-$SFML_VERSION-macOS-clang/include 38 | LIBRARY_PATH: $HOME/SFML-$SFML_VERSION-macOS-clang/lib 39 | -------------------------------------------------------------------------------- /.github/workflows/python-package-ubuntu.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions 3 | 4 | name: Python package for Ubuntu 5 | 6 | env: 7 | SFML_VERSION: 2.5.1 8 | 9 | on: 10 | push: 11 | branches: [ master ] 12 | pull_request: 13 | branches: [ master ] 14 | 15 | jobs: 16 | build: 17 | 18 | runs-on: ubuntu-latest 19 | strategy: 20 | matrix: 21 | python-version: [3.5, 3.6, 3.7, 3.8] 22 | 23 | steps: 24 | - uses: actions/checkout@v2 25 | - name: Set up Python ${{ matrix.python-version }} 26 | uses: actions/setup-python@v1 27 | with: 28 | python-version: ${{ matrix.python-version }} 29 | - name: Install dependencies 30 | run: | 31 | python -m pip install --upgrade pip 32 | pip install -r requirements.txt 33 | sudo apt-get update 34 | sudo apt-get install libx11-dev libgl1-mesa-dev libudev-dev libopenal-dev libvorbis-dev libflac-dev libxrandr-dev libfreetype6-dev 35 | git clone https://github.com/sfml/sfml 36 | cd sfml/ 37 | git checkout tags/$SFML_VERSION 38 | cmake . 39 | make 40 | sudo make install 41 | sudo ldconfig 42 | - name: Build bindings 43 | run: | 44 | python setup.py build 45 | -------------------------------------------------------------------------------- /.github/workflows/python-package-windows.yml: -------------------------------------------------------------------------------- 1 | name: Python package for Windows 2 | 3 | env: 4 | SFML_VERSION: 2.5.1 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: windows-2019 16 | strategy: 17 | matrix: 18 | python-version: [3.7] 19 | os-architecture: ['x86', 'x64'] 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Set up Python ${{ matrix.python-version }} 24 | uses: actions/setup-python@v1 25 | with: 26 | python-version: ${{ matrix.python-version }} 27 | architecture: ${{ matrix.os-architecture }} 28 | - name: Install dependencies 29 | run: | 30 | python -m pip install --upgrade pip 31 | pip install -r requirements.txt 32 | - name: Build bindings 33 | run: | 34 | python setup.py build 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.com 2 | *.class 3 | *.dll 4 | *.exe 5 | *.o 6 | *.so 7 | 8 | *.7z 9 | *.dmg 10 | *.gz 11 | *.iso 12 | *.jar 13 | *.rar 14 | *.tar 15 | *.zip 16 | 17 | *.log 18 | *.sql 19 | *.sqlite 20 | 21 | build 22 | 23 | install* 24 | 25 | trash/ 26 | 27 | __pycache__ 28 | *.pyc 29 | *.cpp 30 | *.h 31 | 32 | *egg* 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | PySFML - Python bindings for SFML 2 | Copyright (c) 2012-2017, Jonathan De Wachter 3 | 4 | This software is provided 'as-is', without any express or implied warranty. 5 | In no event will the authors be held liable for any damages arising from the 6 | use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, including 9 | commercial applications, and to alter it and redistribute it freely, subject to 10 | the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not claim 13 | that you wrote the original software. If you use this software in a product, an 14 | acknowledgment in the product documentation would be appreciated but is not 15 | required. 16 | 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 20 | 3. This notice may not be removed or altered from any source distribution. 21 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.rst 2 | recursive-include src *.hpp 3 | recursive-include include * 4 | include extlibs/x86/openal32.dll 5 | include extlibs/x64/openal32.dll -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | 3 | This is version **2.3.2** of the official Python bindings for **SFML**, based on SFML 2.3.2, and is made available under the terms of the **zlib/libpng** license. 4 | 5 | pip install pySFML 6 | 7 | These bindings officially support Python 2.7 and the latest versions of Python 3.x but we encourage you to use the latter one. Incidentally, the documentation, tutorials and examples are written in the latest version of Python. 8 | 9 | Please visit the website (https://www.python-sfml.org/) for any complementary information on this project. Also, feel free to email us with any questions or concerns. 10 | 11 | * Jonathan De Wachter 12 | * Edwin Marshall 13 | 14 | You're also encouraged to visit (and contribute) to the wiki which gathers various piece of code, tutorials, tips and tricks. 15 | 16 | These bindings were created in large part by **Jonathan De Wachter**, with significant contributions from **Edwin Marshall**. Thanks a lot to **James Cowgill** who occasionally fixes broken builds and maintains Debian packages. Other contributors include **Jorge Araya Navarro** and **Richard Sims**. 17 | -------------------------------------------------------------------------------- /examples/embedding/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/embedding/image.jpg -------------------------------------------------------------------------------- /examples/embedding/main.cpp: -------------------------------------------------------------------------------- 1 | // Including Python.h first is mandatory! 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | // Make sure to include the SFML headers before the pySFML ones 8 | #include 9 | #include 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | // Initialization (mandatory stuff) 14 | Py_SetProgramName(argv[0]); 15 | Py_Initialize(); 16 | 17 | // Add the current path to sys.path to find our script 18 | char cwd[1024]; 19 | if (!getcwd(cwd, sizeof(cwd))) { 20 | std::cout << "Couldn't get the current path" << std::endl; 21 | return EXIT_FAILURE; } 22 | PyObject *sys = PyImport_ImportModule("sys"); 23 | PyObject *path = PyObject_GetAttrString(sys, "path"); 24 | PyList_Append(path, PyString_FromString(cwd)); 25 | 26 | // Import our script that creates a texture 27 | PyObject* script = PyImport_ImportModule("script"); 28 | if(!script) 29 | PyErr_Print(); 30 | 31 | // Retrieve the texture 32 | PyTextureObject *texture; 33 | texture = (PyTextureObject*)PyObject_GetAttrString(script, "texture"); 34 | 35 | // Create a window and display the texture for five seconds 36 | sf::RenderWindow window(sf::VideoMode(640, 480), "pySFMl - Embedding Python"); 37 | 38 | window.clear(); 39 | window.draw(sf::Sprite(*texture->p_this)); 40 | window.display(); 41 | 42 | sf::sleep(sf::seconds(5)); 43 | 44 | // Then, terminate properly... 45 | Py_Finalize(); 46 | 47 | return EXIT_SUCCESS; 48 | } 49 | -------------------------------------------------------------------------------- /examples/embedding/script.py: -------------------------------------------------------------------------------- 1 | from sfml import sf 2 | 3 | texture = sf.Texture.from_file("image.jpg") 4 | -------------------------------------------------------------------------------- /examples/extending/extension.pyx: -------------------------------------------------------------------------------- 1 | cimport libcpp.sfml as sf 2 | from pysfml.graphics cimport Image 3 | 4 | def flip_image(Image image): 5 | image.p_this.flipHorizontally() 6 | image.p_this.flipVertically() 7 | -------------------------------------------------------------------------------- /examples/extending/extension.pyxbld: -------------------------------------------------------------------------------- 1 | def make_ext(modname, pyxfilename): 2 | from distutils.extension import Extension 3 | return Extension(name=modname, 4 | include_dirs=['/usr/lib/python2.7'], 5 | libraries=['sfml-system', 'sfml-window', 'sfml-graphics'], 6 | sources=[pyxfilename], 7 | language='C++') 8 | -------------------------------------------------------------------------------- /examples/extending/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/extending/image.jpg -------------------------------------------------------------------------------- /examples/extending/main.py: -------------------------------------------------------------------------------- 1 | from sfml import sf 2 | 3 | import pyximport; pyximport.install() 4 | import extension 5 | 6 | window = sf.RenderWindow(sf.VideoMode(640, 480), "sfml") 7 | 8 | image = sf.Image.from_file("image.jpg") 9 | extension.flip_image(image) 10 | 11 | texture = sf.Texture.from_image(image) 12 | 13 | window.clear() 14 | window.draw(sf.Sprite(texture)) 15 | window.display() 16 | 17 | sf.sleep(sf.seconds(5)) 18 | -------------------------------------------------------------------------------- /examples/ftp/ftp.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sfml.network as sf 3 | 4 | # python 2.* compatability 5 | try: input = raw_input 6 | except NameError: pass 7 | 8 | # choose the server address 9 | address = input("Enter the FTP server address: ") 10 | address = sf.IpAddress.from_string(address) 11 | 12 | # create the server object which with you will communicate 13 | server = sf.Ftp() 14 | 15 | # connect to the server 16 | response = server.connect(address) 17 | print(response) 18 | if not response.ok: exit() 19 | 20 | # ask for user name and password 21 | user = input("User name: ") 22 | password = input("Password: ") 23 | 24 | # login to the server 25 | response = server.login(user, password) 26 | print(response) 27 | if not response.ok: exit() 28 | 29 | # main menu 30 | choice = 0 31 | while True: 32 | print("===========================================================") 33 | print("Choose an action:") 34 | print("1. Print working directory") 35 | print("2. Print contents of working directory") 36 | print("3. Change directory") 37 | print("4. Create directory") 38 | print("5. Delete directory") 39 | print("6. Rename file") 40 | print("7. Remove file") 41 | print("8. Download file") 42 | print("9. Upload file") 43 | print("0. Disconnect\n\n") 44 | 45 | choice = int(input("Your choice: ")) 46 | 47 | os.system('clear') 48 | 49 | if choice == 1: 50 | # print the current server directory 51 | response = server.get_working_directory() 52 | print(response) 53 | print("Current directory is {0}".format(response.get_directory())) 54 | elif choice == 2: 55 | # print the contents of the current server directory 56 | response = server.get_directory_listing() 57 | print(response) 58 | for filename in response.filenames: 59 | print(filename) 60 | elif choice == 3: 61 | # change the current directory 62 | directory = input("Choose a directory: ") 63 | response = server.change_directory(directory) 64 | print(response) 65 | elif choice == 4: 66 | # create a new directory 67 | directory = input("Name of the directory to create: ") 68 | response = server.create_directory(directory) 69 | print(response) 70 | elif choice == 5: 71 | # remove an existing directory 72 | directory = input("Name of the directory to remove: ") 73 | response = server.delete_directory(directory) 74 | print(response) 75 | elif choice == 6: 76 | # rename a file 77 | source = input("Name of the file to rename: ") 78 | destination = input("New name: ") 79 | response = server.rename_file(source, destination) 80 | print(response) 81 | elif choice == 7: 82 | # remove an existing directory 83 | filename = input("Name of the file to remove: ") 84 | response = server.delete_file(filename) 85 | print(response) 86 | elif choice == 8: 87 | # download a file from server 88 | filename = input("Filename of the file to download (relative to current directory): ") 89 | directory = input("Directory to download the file to: ") 90 | response = server.download(filename, directory) 91 | print(response) 92 | elif choice == 9: 93 | # upload a file to server 94 | filename = input("Path of the file to upload (absolute or relative to working directory): ") 95 | directory = input("Directory to upload the file to (relative to current directory): ") 96 | response = server.upload(filename, directory) 97 | print(response) 98 | elif choice == 0: 99 | break 100 | else: 101 | # wrong choice 102 | print("Invalid choice!") 103 | os.system('clear') 104 | 105 | if choice == 0: 106 | break 107 | 108 | # disconnect from the server 109 | print("Disconnecting from server...") 110 | response = server.disconnect() 111 | 112 | # wait until the user presses 'enter' key 113 | input("Press enter to exit...") 114 | -------------------------------------------------------------------------------- /examples/opengl/opengl.py: -------------------------------------------------------------------------------- 1 | import OpenGL 2 | from OpenGL.GL import * 3 | from OpenGL.GLU import * 4 | 5 | from sfml import sf 6 | 7 | # create the main window 8 | window = sf.RenderWindow(sf.VideoMode(800, 600), "pySFML - OpenGL", sf.Style.DEFAULT, sf.ContextSettings(32)) 9 | window.vertical_synchronization = True 10 | 11 | # load a font for drawing some text 12 | font = sf.Font.from_file("resources/sansation.ttf") 13 | 14 | # create a sprite for the background 15 | background_texture = sf.Texture.from_file("resources/background.jpg") 16 | background = sf.Sprite(background_texture) 17 | 18 | # load an OpenGL texture. 19 | # we could directly use a sf.Texture as an OpenGL texture (with its bind() member function), 20 | # but here we want more control on it (generate mipmaps, ...) so we create a new one from an image 21 | texture = 0 22 | image = sf.Image.from_file("resources/texture.jpg") 23 | glGenTextures(1, texture) 24 | glBindTexture(GL_TEXTURE_2D, texture) 25 | gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.size.x, image.size.y, GL_RGBA, GL_UNSIGNED_BYTE, image.pixels.data) 26 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) 27 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) 28 | 29 | # enable Z-buffer read and write 30 | glEnable(GL_DEPTH_TEST) 31 | glDepthMask(GL_TRUE) 32 | glClearDepth(1.) 33 | 34 | # setup a perspective projection 35 | glMatrixMode(GL_PROJECTION) 36 | glLoadIdentity() 37 | gluPerspective(90., 1., 1., 500.) 38 | 39 | # bind our texture 40 | glEnable(GL_TEXTURE_2D) 41 | glBindTexture(GL_TEXTURE_2D, texture) 42 | glColor4f(1., 1., 1., 1.) 43 | 44 | # create a clock for measuring the time elapsed 45 | clock = sf.Clock() 46 | 47 | # start game loop 48 | while window.is_open: 49 | 50 | # process events 51 | for event in window.events: 52 | 53 | # close window : exit 54 | if event.type == sf.Event.CLOSED: 55 | window.close() 56 | 57 | # escape key : exit 58 | if event.type == sf.Event.KEY_PRESSED and event['code'] == sf.Keyboard.ESCAPE: 59 | window.close() 60 | 61 | # adjust the viewport when the window is resized 62 | if event.type == sf.Event.RESIZED: 63 | glViewport(0, 0, event.width, event.height) 64 | 65 | # draw the background 66 | window.push_GL_states() 67 | window.draw(background) 68 | window.pop_GL_states() 69 | 70 | # activate the window before using OpenGL commands. 71 | # this is useless here because we have only one window which is 72 | # always the active one, but don't forget it if you use multiple windows 73 | window.active = True 74 | 75 | # clear the depth buffer 76 | glClear(GL_DEPTH_BUFFER_BIT); 77 | 78 | # we get the position of the mouse cursor, so that we can move the box accordingly 79 | x = sf.Mouse.get_position(window).x * 200. / window.size.x - 100. 80 | y = -sf.Mouse.get_position(window).y * 200. / window.size.y + 100. 81 | 82 | # apply some transformations 83 | glMatrixMode(GL_MODELVIEW) 84 | glLoadIdentity() 85 | glTranslatef(x, y, -100.) 86 | glRotatef(clock.elapsed_time.seconds * 50., 1., 0., 0.) 87 | glRotatef(clock.elapsed_time.seconds * 30., 0., 1., 0.) 88 | glRotatef(clock.elapsed_time.seconds * 90., 0., 0., 1.) 89 | 90 | # draw a cube 91 | size = 20. 92 | glBegin(GL_QUADS) 93 | 94 | glTexCoord2f(0, 0) 95 | glVertex3f(-size, -size, -size) 96 | glTexCoord2f(0, 1) 97 | glVertex3f(-size, size, -size) 98 | glTexCoord2f(1, 1) 99 | glVertex3f( size, size, -size) 100 | glTexCoord2f(1, 0) 101 | glVertex3f( size, -size, -size) 102 | 103 | glTexCoord2f(0, 0) 104 | glVertex3f(-size, -size, size) 105 | glTexCoord2f(0, 1) 106 | glVertex3f(-size, size, size) 107 | glTexCoord2f(1, 1) 108 | glVertex3f( size, size, size) 109 | glTexCoord2f(1, 0) 110 | glVertex3f( size, -size, size) 111 | 112 | glTexCoord2f(0, 0) 113 | glVertex3f(-size, -size, -size) 114 | glTexCoord2f(0, 1) 115 | glVertex3f(-size, size, -size) 116 | glTexCoord2f(1, 1) 117 | glVertex3f(-size, size, size) 118 | glTexCoord2f(1, 0) 119 | glVertex3f(-size, -size, size) 120 | 121 | glTexCoord2f(0, 0) 122 | glVertex3f(size, -size, -size) 123 | glTexCoord2f(0, 1) 124 | glVertex3f(size, size, -size) 125 | glTexCoord2f(1, 1) 126 | glVertex3f(size, size, size) 127 | glTexCoord2f(1, 0) 128 | glVertex3f(size, -size, size) 129 | 130 | glTexCoord2f(0, 1) 131 | glVertex3f(-size, -size, size) 132 | glTexCoord2f(0, 0) 133 | glVertex3f(-size, -size, -size) 134 | glTexCoord2f(1, 0) 135 | glVertex3f( size, -size, -size) 136 | glTexCoord2f(1, 1) 137 | glVertex3f( size, -size, size) 138 | 139 | glTexCoord2f(0, 1) 140 | glVertex3f(-size, size, size) 141 | glTexCoord2f(0, 0) 142 | glVertex3f(-size, size, -size) 143 | glTexCoord2f(1, 0) 144 | glVertex3f( size, size, -size) 145 | glTexCoord2f(1, 1) 146 | glVertex3f( size, size, size) 147 | 148 | glEnd() 149 | 150 | # draw some text on top of our OpenGL object 151 | window.push_GL_states() 152 | text = sf.Text("pySFML / OpenGL demo", font) 153 | text.color = sf.Color(255, 255, 255, 170) 154 | text.position = (230, 450) 155 | window.draw(text) 156 | window.pop_GL_states() 157 | 158 | # finally, display the rendered frame on screen 159 | window.display() 160 | 161 | # don't forget to destroy our texture 162 | glDeleteTextures(1, texture) 163 | -------------------------------------------------------------------------------- /examples/opengl/resources/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/opengl/resources/background.jpg -------------------------------------------------------------------------------- /examples/opengl/resources/sansation.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/opengl/resources/sansation.ttf -------------------------------------------------------------------------------- /examples/opengl/resources/texture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/opengl/resources/texture.jpg -------------------------------------------------------------------------------- /examples/pong/data/ball.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/pong/data/ball.wav -------------------------------------------------------------------------------- /examples/pong/data/sansation.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/pong/data/sansation.ttf -------------------------------------------------------------------------------- /examples/pong/pong.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | 3 | from math import cos, sin, fabs, pi 4 | from random import randint 5 | 6 | from sfml import sf 7 | 8 | 9 | # define some constants 10 | game_size = sf.Vector2(800, 600) 11 | paddle_size = sf.Vector2(25, 100) 12 | ball_radius = 10. 13 | 14 | # create the window of the application 15 | w, h = game_size 16 | window = sf.RenderWindow(sf.VideoMode(w, h), "pySFML - Pong") 17 | window.vertical_synchronization = True 18 | 19 | # load the sounds used in the game 20 | ball_sound_buffer = sf.SoundBuffer.from_file("data/ball.wav") 21 | ball_sound = sf.Sound(ball_sound_buffer) 22 | 23 | # create the left paddle 24 | left_paddle = sf.RectangleShape() 25 | left_paddle.size = paddle_size - (3, 3) 26 | left_paddle.outline_thickness = 3 27 | left_paddle.outline_color = sf.Color.BLACK 28 | left_paddle.fill_color = sf.Color(100, 100, 200) 29 | left_paddle.origin = paddle_size / 2 30 | 31 | # create the right paddle 32 | right_paddle = sf.RectangleShape() 33 | right_paddle.size = paddle_size - (3, 3) 34 | right_paddle.outline_thickness = 3 35 | right_paddle.outline_color = sf.Color.BLACK 36 | right_paddle.fill_color = sf.Color(200, 100, 100) 37 | right_paddle.origin = paddle_size / 2 38 | 39 | # create the ball 40 | ball = sf.CircleShape() 41 | ball.radius = ball_radius - 3 42 | ball.outline_thickness = 3 43 | ball.outline_color = sf.Color.BLACK 44 | ball.fill_color = sf.Color.WHITE 45 | ball.origin = (ball_radius / 2, ball_radius / 2) 46 | 47 | # load the font 48 | font = sf.Font.from_file("data/sansation.ttf") 49 | 50 | # initialize the pause message 51 | pause_message = sf.Text() 52 | pause_message.font = font 53 | pause_message.character_size = 40 54 | pause_message.position = (170, 150) 55 | pause_message.color = sf.Color.WHITE 56 | pause_message.string = "Welcome to pySFML pong!\nPress space to start the game" 57 | 58 | # define the paddles properties 59 | ai_timer = sf.Clock() 60 | ai_time = sf.seconds(0.1) 61 | paddle_speed = 400. 62 | right_paddle_speed = 0. 63 | ball_speed = 400. 64 | ball_angle = 0. # to be changed later 65 | 66 | clock = sf.Clock() 67 | is_playing = False 68 | 69 | while window.is_open: 70 | 71 | # handle events 72 | for event in window.events: 73 | # window closed or escape key pressed: exit 74 | if event == sf.Event.CLOSED: 75 | window.close() 76 | 77 | # space key pressed: play 78 | if event == sf.Event.KEY_PRESSED and event['code'] == sf.Keyboard.SPACE: 79 | if not is_playing: 80 | # (re)start the game 81 | is_playing = True 82 | clock.restart() 83 | 84 | # reset the position of the paddles and ball 85 | left_paddle.position = (10 + paddle_size.x / 2, game_size.y / 2) 86 | right_paddle.position = (game_size.x - 10 - paddle_size.x / 2, game_size.y / 2) 87 | ball.position = game_size / 2 88 | 89 | # reset the ball angle 90 | while True: 91 | # make sure the ball initial angle is not too much vertical 92 | ball_angle = (randint(0, 32767) % 360) * 2 * pi / 360 93 | if not fabs(cos(ball_angle)) < 0.7: break 94 | 95 | if is_playing: 96 | delta_time = clock.restart().seconds 97 | 98 | # move the player's paddle 99 | if sf.Keyboard.is_key_pressed(sf.Keyboard.UP) and left_paddle.position.y - paddle_size.y / 2 > 5: 100 | left_paddle.move((0, -paddle_speed * delta_time)) 101 | 102 | elif sf.Keyboard.is_key_pressed(sf.Keyboard.DOWN) and left_paddle.position.y + paddle_size.y / 2 < game_size.y - 5: 103 | left_paddle.position += (0, paddle_speed * delta_time) 104 | 105 | # move the computer' paddle 106 | if (right_paddle_speed < 0 and right_paddle.position.y - paddle_size.x / 2 > 5) or (right_paddle_speed > 0 and right_paddle.position.y + paddle_size.y / 2 < game_size.y - 5): 107 | right_paddle.position += (0, right_paddle_speed * delta_time) 108 | 109 | 110 | # update the computer's paddle direction according to the ball position 111 | if ai_timer.elapsed_time > ai_time: 112 | ai_timer.restart() 113 | if ball.position.y + ball_radius > right_paddle.position.y + paddle_size.y / 2: 114 | right_paddle_speed = paddle_speed 115 | elif ball.position.y - ball_radius < right_paddle.position.y - paddle_size.y / 2: 116 | right_paddle_speed = -paddle_speed 117 | else: 118 | right_paddle_speed = 0 119 | 120 | # move the ball 121 | factor = ball_speed * delta_time 122 | ball.move((cos(ball_angle) * factor, sin(ball_angle) * factor)) 123 | 124 | # check collisions between the ball and the screen 125 | if ball.position.x - ball_radius < 0: 126 | is_playing = False 127 | pause_message.string = "You lost!\nPress space to restart or\nescape to exit" 128 | 129 | if ball.position.x + ball_radius > game_size.x: 130 | is_playing = False 131 | pause_message.string = "You won !\nPress space to restart or\nescape to exit" 132 | 133 | if ball.position.y - ball_radius < 0: 134 | ball_sound.play() 135 | ball_angle = - ball_angle 136 | ball.position.y = ball_radius + 0.1 137 | 138 | if ball.position.y + ball_radius > game_size.y: 139 | ball_sound.play() 140 | ball_angle = - ball_angle 141 | ball.position.y = game_size.y - ball_radius - 0.1 142 | 143 | # check the collisions between the ball and the paddles 144 | # left paddle 145 | if ball.position.x - ball_radius < left_paddle.position.x + paddle_size.x / 2 and ball.position.x - ball_radius > left_paddle.position.x and ball.position.y + ball_radius >= left_paddle.position.y - paddle_size.y / 2 and ball.position.y - ball_radius <= left_paddle.position.y + paddle_size.y / 2: 146 | if ball.position.y > left_paddle.position.y: 147 | ball_angle = pi - ball_angle + (randint(0, 32767) % 20) * pi / 180 148 | else: 149 | ball_angle = pi - ball_angle - (randint(0, 32767) % 20) * pi / 180 150 | 151 | ball_sound.play() 152 | ball.position = (left_paddle.position.x + ball_radius + paddle_size.x / 2 + 0.1, ball.position.y) 153 | 154 | # right paddle 155 | if ball.position.x + ball_radius > right_paddle.position.x - paddle_size.x / 2 and ball.position.x + ball_radius < right_paddle.position.x and ball.position.y + ball_radius >= right_paddle.position.y - paddle_size.y / 2 and ball.position.y - ball_radius <= right_paddle.position.y + paddle_size.y / 2: 156 | if ball.position.y > right_paddle.position.y: 157 | ball_angle = pi - ball_angle + (randint(0, 32767) % 20) * pi / 180 158 | else: 159 | ball_angle = pi - ball_angle - (randint(0, 32767) % 20) * pi / 180 160 | 161 | ball_sound.play() 162 | ball.position = (right_paddle.position.x - ball_radius - paddle_size.x / 2 - 0.1, ball.position.y) 163 | 164 | window.clear(sf.Color(50, 200, 50)) 165 | 166 | if is_playing: 167 | # draw the paddles and the ball 168 | window.draw(left_paddle) 169 | window.draw(right_paddle) 170 | window.draw(ball) 171 | 172 | else: 173 | # draw the pause message 174 | window.draw(pause_message) 175 | 176 | # display things on screen 177 | window.display() 178 | -------------------------------------------------------------------------------- /examples/pyqt4/data/head_kid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/pyqt4/data/head_kid.png -------------------------------------------------------------------------------- /examples/pyqt4/pyqt4.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | try: 4 | from PyQt4.QtCore import * 5 | from PyQt4.QtGui import * 6 | except ImportError: 7 | print("Install PyQt4 from Riverbank.") 8 | 9 | from sfml import sf 10 | from qsfml_canvas import QSFMLCanvas 11 | 12 | 13 | class MyCyanCanvas(QSFMLCanvas): 14 | def __init__(self, parent, position, size): 15 | QSFMLCanvas.__init__(self, parent, position, size) 16 | 17 | def onInit(self): 18 | self.image = sf.Image.from_file("data/head_kid.png") 19 | self.texture = sf.Texture.from_image(self.image) 20 | self.sprite = sf.Sprite(self.texture) 21 | self.sprite.position = self.texture.size // (2, 2) 22 | 23 | def onUpdate(self): 24 | self.clear(sf.Color.CYAN) 25 | self.sprite.rotate(0.05) 26 | self.sprite.origin = self.texture.size // (2, 2) 27 | self.draw(self.sprite) 28 | 29 | app = QApplication(sys.argv) 30 | 31 | # create the main frame 32 | mainFrame = QFrame() 33 | mainFrame.setWindowTitle("pySFML - Qt") 34 | mainFrame.resize(400, 400) 35 | mainFrame.show() 36 | 37 | # create a SFML view inside the main frame 38 | SFMLView = MyCyanCanvas(mainFrame, QPoint(20, 20), QSize(360, 360)) 39 | SFMLView.show() 40 | 41 | app.exec_() 42 | sys.exit() 43 | -------------------------------------------------------------------------------- /examples/pyqt4/qsfml_canvas.py: -------------------------------------------------------------------------------- 1 | import sys, platform 2 | 3 | try: 4 | import sip 5 | from PyQt4.QtCore import * 6 | from PyQt4.QtGui import * 7 | except ImportError: 8 | print("Install PyQt4 and sip from Riverbank.") 9 | 10 | from sfml import sf 11 | 12 | 13 | class QSFMLCanvas(QWidget): 14 | def __init__(self, parent, position, size, frameTime=0): 15 | QWidget.__init__(self, parent) 16 | self.initialized = False 17 | 18 | w = size.width() 19 | h = size.height() 20 | 21 | self._HandledWindow = sf.HandledWindow() 22 | self._HandledWindow.view.size = (w, h) 23 | self.__dict__['draw'] = self._HandledWindow.draw 24 | self.__dict__['clear'] = self._HandledWindow.clear 25 | self.__dict__['view'] = self._HandledWindow.view 26 | self.__dict__['display'] = self._HandledWindow.display 27 | 28 | # setup some states to allow direct rendering into the widget 29 | self.setAttribute(Qt.WA_PaintOnScreen) 30 | self.setAttribute(Qt.WA_OpaquePaintEvent) 31 | self.setAttribute(Qt.WA_NoSystemBackground) 32 | 33 | # set strong focus to enable keyboard events to be received 34 | self.setFocusPolicy(Qt.StrongFocus); 35 | 36 | # setup the widget geometry 37 | self.move(position); 38 | self.resize(size); 39 | 40 | # setup the timer 41 | self.timer = QTimer() 42 | self.timer.setInterval(frameTime) 43 | 44 | def onInit(self): pass 45 | 46 | def onUpdate(self): pass 47 | 48 | def sizeHint(self): 49 | return self.size() 50 | 51 | def paintEngine(self): 52 | # let the derived class do its specific stuff 53 | self.onUpdate() 54 | 55 | # display on screen 56 | self.display() 57 | 58 | def showEvent(self, event): 59 | if not self.initialized: 60 | # under X11, we need to flush the commands sent to the server 61 | # to ensure that SFML will get an updated view of the windows 62 | # create the SFML window with the widget handle 63 | if platform.system() == 'Linux': 64 | from ctypes import cdll 65 | x11 = cdll.LoadLibrary("libX11.so") 66 | 67 | display = sip.unwrapinstance(QX11Info.display()) 68 | x11.XFlush(display) 69 | 70 | self._HandledWindow.create(self.winId()) 71 | 72 | # let the derived class do its specific stuff 73 | self.onInit() 74 | 75 | # setup the timer to trigger a refresh at specified framerate 76 | self.connect(self.timer,SIGNAL('timeout()'), self, SLOT('repaint()')) 77 | self.timer.start() 78 | 79 | self.initialized = True 80 | 81 | def paintEvent(self, event): 82 | return None 83 | -------------------------------------------------------------------------------- /examples/pyqt5/data/head_kid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/pyqt5/data/head_kid.png -------------------------------------------------------------------------------- /examples/pyqt5/pyqt5.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | try: 4 | from PyQt5.Qt import * 5 | except ImportError: 6 | print("Install PyQt5 from Riverbank.") 7 | 8 | from sfml import sf 9 | from qsfml_canvas import QSFMLCanvas 10 | 11 | 12 | class MyCyanCanvas(QSFMLCanvas): 13 | def onInit(self): 14 | self.image = sf.Image.from_file("data/head_kid.png") 15 | self.texture = sf.Texture.from_image(self.image) 16 | self.sprite = sf.Sprite(self.texture) 17 | self.sprite.position = self.texture.size // (2, 2) 18 | 19 | def onUpdate(self): 20 | self.clear(sf.Color.CYAN) 21 | self.sprite.rotate(0.05) 22 | self.sprite.origin = self.texture.size // (2, 2) 23 | self.draw(self.sprite) 24 | 25 | app = QApplication(sys.argv) 26 | 27 | # create the main frame 28 | mainFrame = QFrame() 29 | mainFrame.setWindowTitle("pySFML - Qt") 30 | mainFrame.resize(400, 400) 31 | mainFrame.show() 32 | 33 | # create a SFML view inside the main frame 34 | SFMLView = MyCyanCanvas(mainFrame, QPoint(20, 20), QSize(360, 360)) 35 | SFMLView.show() 36 | 37 | app.exec_() 38 | sys.exit() 39 | -------------------------------------------------------------------------------- /examples/pyqt5/qsfml_canvas.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | try: 4 | import sip 5 | from PyQt5.Qt import * 6 | except ImportError: 7 | print("Install PyQt4 and sip from Riverbank.") 8 | 9 | from sfml import sf 10 | 11 | 12 | class QSFMLCanvas(QWidget): 13 | def __init__(self, parent, position, size, frameTime=0): 14 | QWidget.__init__(self, parent) 15 | self.initialized = False 16 | 17 | w = size.width() 18 | h = size.height() 19 | 20 | self._HandledWindow = sf.HandledWindow() 21 | self._HandledWindow.view.size = (w, h) 22 | self.__dict__['draw'] = self._HandledWindow.draw 23 | self.__dict__['clear'] = self._HandledWindow.clear 24 | self.__dict__['view'] = self._HandledWindow.view 25 | self.__dict__['display'] = self._HandledWindow.display 26 | 27 | # setup some states to allow direct rendering into the widget 28 | self.setAttribute(Qt.WA_PaintOnScreen) 29 | self.setAttribute(Qt.WA_OpaquePaintEvent) 30 | self.setAttribute(Qt.WA_NoSystemBackground) 31 | 32 | # set strong focus to enable keyboard events to be received 33 | self.setFocusPolicy(Qt.StrongFocus); 34 | 35 | # setup the widget geometry 36 | self.move(position); 37 | self.resize(size); 38 | 39 | # setup the timer 40 | self.timer = QTimer() 41 | self.timer.setInterval(frameTime) 42 | 43 | 44 | def sizeHint(self): 45 | return self.size() 46 | 47 | def paintEngine(self): 48 | # let the derived class do its specific stuff 49 | self.onUpdate() 50 | 51 | # display on screen 52 | self.display() 53 | 54 | def showEvent(self, event): 55 | if not self.initialized: 56 | # under X11, we need to flush the commands sent to the server 57 | # to ensure that SFML will get an updated view of the windows 58 | # create the SFML window with the widget handle 59 | 60 | self._HandledWindow.create(self.winId()) 61 | 62 | # let the derived class do its specific stuff 63 | self.onInit() 64 | 65 | # setup the timer to trigger a refresh at specified framerate 66 | self.timer.timeout.connect(self.repaint) 67 | self.timer.start() 68 | 69 | self.initialized = True 70 | 71 | def paintEvent(self, event): 72 | return None 73 | -------------------------------------------------------------------------------- /examples/shader/data/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/shader/data/background.jpg -------------------------------------------------------------------------------- /examples/shader/data/blink.frag: -------------------------------------------------------------------------------- 1 | uniform sampler2D texture; 2 | uniform float blink_alpha; 3 | 4 | void main() 5 | { 6 | vec4 pixel = gl_Color; 7 | pixel.a = blink_alpha; 8 | gl_FragColor = pixel; 9 | } 10 | -------------------------------------------------------------------------------- /examples/shader/data/blur.frag: -------------------------------------------------------------------------------- 1 | uniform sampler2D texture; 2 | uniform float blur_radius; 3 | 4 | void main() 5 | { 6 | vec2 offx = vec2(blur_radius, 0.0); 7 | vec2 offy = vec2(0.0, blur_radius); 8 | 9 | vec4 pixel = texture2D(texture, gl_TexCoord[0].xy) * 4.0 + 10 | texture2D(texture, gl_TexCoord[0].xy - offx) * 2.0 + 11 | texture2D(texture, gl_TexCoord[0].xy + offx) * 2.0 + 12 | texture2D(texture, gl_TexCoord[0].xy - offy) * 2.0 + 13 | texture2D(texture, gl_TexCoord[0].xy + offy) * 2.0 + 14 | texture2D(texture, gl_TexCoord[0].xy - offx - offy) * 1.0 + 15 | texture2D(texture, gl_TexCoord[0].xy - offx + offy) * 1.0 + 16 | texture2D(texture, gl_TexCoord[0].xy + offx - offy) * 1.0 + 17 | texture2D(texture, gl_TexCoord[0].xy + offx + offy) * 1.0; 18 | 19 | gl_FragColor = gl_Color * (pixel / 16.0); 20 | } 21 | -------------------------------------------------------------------------------- /examples/shader/data/devices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/shader/data/devices.png -------------------------------------------------------------------------------- /examples/shader/data/edge.frag: -------------------------------------------------------------------------------- 1 | uniform sampler2D texture; 2 | uniform float edge_threshold; 3 | 4 | void main() 5 | { 6 | const float offset = 1.0 / 512.0; 7 | vec2 offx = vec2(offset, 0.0); 8 | vec2 offy = vec2(0.0, offset); 9 | 10 | vec4 hEdge = texture2D(texture, gl_TexCoord[0].xy - offy) * -2.0 + 11 | texture2D(texture, gl_TexCoord[0].xy + offy) * 2.0 + 12 | texture2D(texture, gl_TexCoord[0].xy - offx - offy) * -1.0 + 13 | texture2D(texture, gl_TexCoord[0].xy - offx + offy) * 1.0 + 14 | texture2D(texture, gl_TexCoord[0].xy + offx - offy) * -1.0 + 15 | texture2D(texture, gl_TexCoord[0].xy + offx + offy) * 1.0; 16 | 17 | vec4 vEdge = texture2D(texture, gl_TexCoord[0].xy - offx) * 2.0 + 18 | texture2D(texture, gl_TexCoord[0].xy + offx) * -2.0 + 19 | texture2D(texture, gl_TexCoord[0].xy - offx - offy) * 1.0 + 20 | texture2D(texture, gl_TexCoord[0].xy - offx + offy) * -1.0 + 21 | texture2D(texture, gl_TexCoord[0].xy + offx - offy) * 1.0 + 22 | texture2D(texture, gl_TexCoord[0].xy + offx + offy) * -1.0; 23 | 24 | vec3 result = sqrt(hEdge.rgb * hEdge.rgb + vEdge.rgb * vEdge.rgb); 25 | float edge = length(result); 26 | vec4 pixel = gl_Color * texture2D(texture, gl_TexCoord[0].xy); 27 | if (edge > (edge_threshold * 8.0)) 28 | pixel.rgb = vec3(0.0, 0.0, 0.0); 29 | else 30 | pixel.a = edge_threshold; 31 | gl_FragColor = pixel; 32 | } 33 | -------------------------------------------------------------------------------- /examples/shader/data/pixelate.frag: -------------------------------------------------------------------------------- 1 | uniform sampler2D texture; 2 | uniform float pixel_threshold; 3 | 4 | void main() 5 | { 6 | float factor = 1.0 / (pixel_threshold + 0.001); 7 | vec2 pos = floor(gl_TexCoord[0].xy * factor + 0.5) / factor; 8 | gl_FragColor = texture2D(texture, pos) * gl_Color; 9 | } 10 | -------------------------------------------------------------------------------- /examples/shader/data/sansation.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/shader/data/sansation.ttf -------------------------------------------------------------------------------- /examples/shader/data/sfml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/shader/data/sfml.png -------------------------------------------------------------------------------- /examples/shader/data/storm.vert: -------------------------------------------------------------------------------- 1 | uniform vec2 storm_position; 2 | uniform float storm_total_radius; 3 | uniform float storm_inner_radius; 4 | 5 | void main() 6 | { 7 | vec4 vertex = gl_ModelViewMatrix * gl_Vertex; 8 | vec2 offset = vertex.xy - storm_position; 9 | float len = length(offset); 10 | if (len < storm_total_radius) 11 | { 12 | float push_distance = storm_inner_radius + len / storm_total_radius * (storm_total_radius - storm_inner_radius); 13 | vertex.xy = storm_position + normalize(offset) * push_distance; 14 | } 15 | 16 | gl_Position = gl_ProjectionMatrix * vertex; 17 | gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; 18 | gl_FrontColor = gl_Color; 19 | } 20 | -------------------------------------------------------------------------------- /examples/shader/data/text-background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/shader/data/text-background.png -------------------------------------------------------------------------------- /examples/shader/data/text.txt: -------------------------------------------------------------------------------- 1 | Praesent suscipit augue in velit pulvinar hendrerit varius purus aliquam. 2 | Mauris mi odio, bibendum quis fringilla a, laoreet vel orci. Proin vitae vulputate tortor. 3 | Praesent cursus ultrices justo, ut feugiat ante vehicula quis. 4 | Donec fringilla scelerisque mauris et viverra. 5 | Maecenas adipiscing ornare scelerisque. Nullam at libero elit. 6 | Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. 7 | Nullam leo urna, tincidunt id semper eget, ultricies sed mi. 8 | Morbi mauris massa, commodo id dignissim vel, lobortis et elit. 9 | Fusce vel libero sed neque scelerisque venenatis. 10 | Integer mattis tincidunt quam vitae iaculis. 11 | Somewhere in time I will find you and haunt you again. 12 | Vivamus fringilla sem non velit venenatis fermentum. 13 | Vivamus varius tincidunt nisi id vehicula. 14 | Integer ullamcorper, enim vitae euismod rutrum, massa nisl semper ipsum, 15 | vestibulum sodales sem ante in massa. 16 | Vestibulum in augue non felis convallis viverra. 17 | Mauris ultricies dolor sed massa convallis sed aliquet augue fringilla. 18 | Duis erat eros, porta in accumsan in, blandit quis sem. 19 | -------------------------------------------------------------------------------- /examples/shader/data/wave.vert: -------------------------------------------------------------------------------- 1 | uniform float wave_phase; 2 | uniform vec2 wave_amplitude; 3 | 4 | void main() 5 | { 6 | vec4 vertex = gl_Vertex; 7 | vertex.x += cos(gl_Vertex.y * 0.02 + wave_phase * 3.8) * wave_amplitude.x 8 | + sin(gl_Vertex.y * 0.02 + wave_phase * 6.3) * wave_amplitude.x * 0.3; 9 | vertex.y += sin(gl_Vertex.x * 0.02 + wave_phase * 2.4) * wave_amplitude.y 10 | + cos(gl_Vertex.x * 0.02 + wave_phase * 5.2) * wave_amplitude.y * 0.3; 11 | 12 | gl_Position = gl_ModelViewProjectionMatrix * vertex; 13 | gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; 14 | gl_FrontColor = gl_Color; 15 | } 16 | -------------------------------------------------------------------------------- /examples/shader/shader.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | 3 | from random import randint 4 | from math import cos 5 | 6 | from sfml import sf 7 | 8 | class Effect(sf.Drawable): 9 | def __init__(self, name): 10 | sf.Drawable.__init__(self) 11 | 12 | self._name = name 13 | self.is_loaded = False 14 | 15 | def _get_name(self): 16 | return self._name 17 | 18 | def load(self): 19 | self.is_loaded = sf.Shader.is_available() and self.on_load() 20 | 21 | def update(self, time, x, y): 22 | if self.is_loaded: 23 | self.on_update(time, x, y) 24 | 25 | def draw(self, target, states): 26 | if self.is_loaded: 27 | self.on_draw(target, states) 28 | else: 29 | error = sf.Text("Shader not\nsupported") 30 | error.font = sf.Font.from_file("data/sansation.ttf") 31 | error.position = (320, 200) 32 | error.character_size = 36 33 | target.draw(error, states) 34 | 35 | name = property(_get_name) 36 | 37 | class Pixelate(Effect): 38 | def __init__(self): 39 | Effect.__init__(self, 'pixelate') 40 | 41 | def on_load(self): 42 | try: 43 | # load the texture and initialize the sprite 44 | self.texture = sf.Texture.from_file("data/background.jpg") 45 | self.sprite = sf.Sprite(self.texture) 46 | 47 | # load the shader 48 | self.shader = sf.Shader.from_file(fragment="data/pixelate.frag") 49 | self.shader.set_parameter("texture") 50 | 51 | except IOError as error: 52 | print("An error occured: {0}".format(error)) 53 | exit(1) 54 | 55 | return True 56 | 57 | def on_update(self, time, x, y): 58 | self.shader.set_parameter("pixel_threshold", (x + y) / 30) 59 | 60 | def on_draw(self, target, states): 61 | states.shader = self.shader 62 | target.draw(self.sprite, states) 63 | 64 | 65 | class WaveBlur(Effect): 66 | def __init__(self): 67 | Effect.__init__(self, 'wave + blur') 68 | 69 | def on_load(self): 70 | with open("data/text.txt") as file: 71 | self.text = sf.Text(file.read()) 72 | self.text.font = sf.Font.from_file("data/sansation.ttf") 73 | self.text.character_size = 22 74 | self.text.position = (30, 20) 75 | 76 | try: 77 | # load the shader 78 | self.shader = sf.Shader.from_file("data/wave.vert", "data/blur.frag") 79 | 80 | except IOError as error: 81 | print("An error occured: {0}".format(error)) 82 | exit(1) 83 | 84 | return True 85 | 86 | def on_update(self, time, x, y): 87 | self.shader.set_parameter("wave_phase", time) 88 | self.shader.set_parameter("wave_amplitude", x * 40, y * 40) 89 | self.shader.set_parameter("blur_radius", (x + y) * 0.008) 90 | 91 | def on_draw(self, target, states): 92 | states.shader = self.shader 93 | target.draw(self.text, states) 94 | 95 | 96 | class StormBlink(Effect): 97 | def __init__(self): 98 | Effect.__init__(self, 'storm + blink') 99 | 100 | self.points = sf.VertexArray() 101 | 102 | def on_load(self): 103 | # create the points 104 | self.points.primitive_type = sf.PrimitiveType.POINTS 105 | 106 | for i in range(40000): 107 | x = randint(0, 32767) % 800 108 | y = randint(0, 32767) % 600 109 | r = randint(0, 32767) % 255 110 | g = randint(0, 32767) % 255 111 | b = randint(0, 32767) % 255 112 | self.points.append(sf.Vertex(sf.Vector2(x, y), sf.Color(r, g, b))) 113 | 114 | try: 115 | # load the shader 116 | self.shader = sf.Shader.from_file("data/storm.vert", "data/blink.frag") 117 | 118 | except IOError as error: 119 | print("An error occured: {0}".format(error)) 120 | exit(1) 121 | 122 | return True 123 | 124 | def on_update(self, time, x, y): 125 | radius = 200 + cos(time) * 150 126 | self.shader.set_parameter("storm_position", x * 800, y * 600) 127 | self.shader.set_parameter("storm_inner_radius", radius / 3) 128 | self.shader.set_parameter("storm_total_radius", radius) 129 | self.shader.set_parameter("blink_alpha", 0.5 + cos(time*3) * 0.25) 130 | 131 | def on_draw(self, target, states): 132 | states.shader = self.shader 133 | target.draw(self.points, states) 134 | 135 | class Edge(Effect): 136 | def __init__(self): 137 | Effect.__init__(self, "edge post-effect") 138 | 139 | def on_load(self): 140 | # create the off-screen surface 141 | self.surface = sf.RenderTexture(800, 600) 142 | self.surface.smooth = True 143 | 144 | # load the textures 145 | self.background_texture = sf.Texture.from_file("data/sfml.png") 146 | self.background_texture.smooth = True 147 | 148 | self.entity_texture = sf.Texture.from_file("data/devices.png") 149 | self.entity_texture.smooth = True 150 | 151 | # initialize the background sprite 152 | self.background_sprite = sf.Sprite(self.background_texture) 153 | self.background_sprite.position = (135, 100) 154 | 155 | # load the moving entities 156 | self.entities = [] 157 | 158 | for i in range(6): 159 | sprite = sf.Sprite(self.entity_texture, (96 * i, 0, 96, 96)) 160 | self.entities.append(sprite) 161 | 162 | # load the shader 163 | self.shader = sf.Shader.from_file(fragment="data/edge.frag") 164 | self.shader.set_parameter("texture") 165 | 166 | return True 167 | 168 | def on_update(self, time, x, y): 169 | self.shader.set_parameter("edge_threshold", 1 - (x + y) / 2) 170 | 171 | # update the position of the moving entities 172 | for i, entity in enumerate(self.entities): 173 | x = cos(0.25 * (time * i + (len(self.entities) - i))) * 300 + 350 174 | y = cos(0.25 * (time * (len(self.entities) - i) + i)) * 200 + 250 175 | entity.position = (x, y) 176 | 177 | # render the updated scene to the off-screen surface 178 | self.surface.clear(sf.Color.WHITE) 179 | self.surface.draw(self.background_sprite) 180 | 181 | for entity in self.entities: 182 | self.surface.draw(entity) 183 | 184 | self.surface.display() 185 | 186 | def on_draw(self, target, states): 187 | states.shader = self.shader 188 | target.draw(sf.Sprite(self.surface.texture), states) 189 | 190 | 191 | if __name__ == "__main__": 192 | # create the main window 193 | window = sf.RenderWindow(sf.VideoMode(800, 600), "pySFML - Shader") 194 | window.vertical_synchronization = True 195 | 196 | # create the effects 197 | effects = (Pixelate(), WaveBlur(), StormBlink(), Edge()) 198 | current = 0 199 | 200 | # initialize them 201 | for effect in effects: effect.load() 202 | 203 | # create the message background 204 | try: 205 | text_background_texture = sf.Texture.from_file("data/text-background.png") 206 | 207 | except IOError as error: 208 | print("An error occured: {0}".format(error)) 209 | exit(1) 210 | 211 | text_background = sf.Sprite(text_background_texture) 212 | text_background.position = (0, 520) 213 | text_background.color = sf.Color(255, 255, 255, 200) 214 | 215 | # load the messages font 216 | try: 217 | font = sf.Font.from_file("data/sansation.ttf") 218 | 219 | except IOError as error: 220 | print("An error occured: {0}".format(error)) 221 | exit(1) 222 | 223 | # create the description text 224 | description = sf.Text("Current effect: {0}".format(effects[current].name), font, 20) 225 | description.position = (10, 530) 226 | description.color = sf.Color(80, 80, 80) 227 | 228 | # create the instructions text 229 | instructions = sf.Text("Press left and right arrows to change the current shader", font, 20) 230 | instructions.position = (280, 555) 231 | instructions.color = sf.Color(80, 80, 80) 232 | 233 | clock = sf.Clock() 234 | 235 | # start the game loop 236 | while window.is_open: 237 | 238 | # update the current example 239 | x = sf.Mouse.get_position(window).x / window.size.x 240 | y = sf.Mouse.get_position(window).y / window.size.y 241 | effects[current].update(clock.elapsed_time.seconds, x, y) 242 | 243 | # process events 244 | for event in window.events: 245 | 246 | # close window: exit 247 | if event == sf.Event.CLOSED: 248 | window.close() 249 | 250 | if event == sf.Event.KEY_PRESSED: 251 | # escapte key: exit 252 | if event['code'] == sf.Keyboard.ESCAPE: 253 | window.close() 254 | 255 | # left arrow key: previous shader 256 | elif event['code'] == sf.Keyboard.LEFT: 257 | if current == 0: current = len(effects) - 1 258 | else: current -= 1 259 | 260 | description.string = "Current effect: {0}".format(effects[current].name) 261 | 262 | # right arrow key: next shader 263 | elif event['code'] == sf.Keyboard.RIGHT: 264 | if current == len(effects) - 1: current = 0 265 | else: current += 1 266 | 267 | description.string = "Current effect: {0}".format(effects[current].name) 268 | 269 | 270 | # clear the window 271 | window.clear(sf.Color(255, 128, 0)) 272 | 273 | # draw the current example 274 | window.draw(effects[current]) 275 | 276 | # draw the text 277 | window.draw(text_background) 278 | window.draw(instructions) 279 | window.draw(description) 280 | 281 | # finally, display the rendered frame on screen 282 | window.display() 283 | -------------------------------------------------------------------------------- /examples/sockets/sockets.py: -------------------------------------------------------------------------------- 1 | import sfml.network as sf 2 | 3 | # python 2.* compatability 4 | try: input = raw_input 5 | except NameError: pass 6 | 7 | def run_tcp_server(): 8 | """ Launch a server. The server waits for an incoming connection, 9 | sends a message and waits for the answer. """ 10 | 11 | try: 12 | # create a server socket to accept new connections 13 | listener = sf.TcpListener() 14 | 15 | # listen to the given port for incoming connections 16 | listener.listen(PORT) 17 | 18 | print("Server is listening to port {0}, waiting for connections...".format(PORT)) 19 | 20 | # wait for a connection 21 | socket = listener.accept() 22 | print("Client connected: {0}".format(socket.remote_address)) 23 | 24 | # send a message to the connected client 25 | message = "Hi, I'm the server" 26 | socket.send(message.encode('utf-8')) 27 | print("Message sent to the client: {0}".format(message)) 28 | 29 | # recieve a message back from the client 30 | answer = socket.receive(128).decode('utf-8') 31 | print("Answer received from the client: {0}".format(answer)) 32 | 33 | except sf.SocketException as error: 34 | print("An error occured!") 35 | print(error) 36 | return 37 | 38 | def run_tcp_client(): 39 | """ Create a client. The client is connected to a server, displays 40 | the welcome message and sends an answer. """ 41 | 42 | server = input("Type the address or name of the server to connect to: ") 43 | server = sf.IpAddress.from_string(server) 44 | 45 | # create a socket for communicating with the server 46 | socket = sf.TcpSocket() 47 | 48 | # connect to the server 49 | try: 50 | socket.connect(server, PORT) 51 | print("Connected to server {0}".format(server)) 52 | 53 | # receive a message from the server 54 | message = socket.receive(128).decode('utf-8') 55 | print("Message received from the server: {0}".format(message)) 56 | 57 | # send an answer to the server 58 | answer = "Hi, I'm a client" 59 | socket.send(answer.encode('utf-8')) 60 | print("Message sent to the server: {0}".format(answer)) 61 | 62 | except sf.SocketException as error: 63 | print("An error occured!") 64 | print(error) 65 | return 66 | 67 | def run_udp_server(): 68 | """ Launch a server. The server waits for a message then sends an 69 | answer. """ 70 | 71 | # create a socket to receive a message from anyone 72 | socket = sf.UdpSocket() 73 | 74 | try: 75 | # listen to messages on the specified port 76 | socket.bind(PORT) 77 | print("Server is listening to port {0}, waiting for message...".format(PORT)) 78 | 79 | # wait for a message 80 | message, ip, port = socket.receive(128) 81 | print("Message received from client {0}: {1}".format(ip, message.decode('utf-8'))) 82 | 83 | # send an answer to the client 84 | answer = "Hi, I'm the server" 85 | socket.send(answer.encode('utf-8'), ip, port) 86 | print("Message sent to the client: {0}".format(answer)) 87 | 88 | except sf.SocketException as error: 89 | print("An error occured!") 90 | print(error) 91 | return 92 | 93 | def run_udp_client(): 94 | """ Send a message to the server, wait for the answer. """ 95 | 96 | # ask for the server address 97 | server = input("Type the address or name of the server to connect to: ") 98 | server = sf.IpAddress.from_string(server) 99 | 100 | # create a socket for communicating with the server 101 | socket = sf.UdpSocket() 102 | 103 | try: 104 | # send a message to the server 105 | message = "Hi, I'm a client" 106 | socket.send(message.encode('utf-8'), server, PORT) 107 | print("Message sent to the server: {0}".format(message)) 108 | 109 | # receive an answer from anyone (but most likely from the server) 110 | answer, ip, port = socket.receive(128) 111 | print("Message received from {0}: {1}".format(ip, answer.decode('utf-8'))) 112 | 113 | except sf.SocketException as error: 114 | print("An error occured!") 115 | print(error) 116 | return 117 | 118 | if __name__ == "__main__": 119 | # choose an arbitrary port for opening sockets 120 | PORT = 50001 121 | 122 | # TCP or UDP ? 123 | print("Do you want to use TCP (t) or UDP (u) ?") 124 | protocol = input() 125 | 126 | # client or server ? 127 | print("Do you want to be a server (s) or a client (c) ?") 128 | who = input() 129 | 130 | if protocol == 't': 131 | if who == 's': run_tcp_server() 132 | else: run_tcp_client() 133 | else: 134 | if who == 's': run_udp_server() 135 | else: run_udp_client() 136 | 137 | input("Press any key to exit...") 138 | -------------------------------------------------------------------------------- /examples/sound/data/canary.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/sound/data/canary.wav -------------------------------------------------------------------------------- /examples/sound/data/orchestral.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/examples/sound/data/orchestral.ogg -------------------------------------------------------------------------------- /examples/sound/sound.py: -------------------------------------------------------------------------------- 1 | from sfml import sf 2 | 3 | def play_sound(): 4 | # load a sound buffer from a wav file 5 | buffer = sf.SoundBuffer.from_file("data/canary.wav") 6 | 7 | # display sound informations 8 | print("canary.wav:") 9 | print("{0} seconds".format(buffer.duration)) 10 | print("{0} samples / sec".format(buffer.sample_rate)) 11 | print("{0} channels".format(buffer.channel_count)) 12 | 13 | # create a sound instance and play it 14 | sound = sf.Sound(buffer) 15 | sound.play(); 16 | 17 | # loop while the sound is playing 18 | while sound.status == sf.Sound.PLAYING: 19 | # leave some CPU time for other processes 20 | sf.sleep(sf.milliseconds(100)) 21 | 22 | def play_music(): 23 | # load an ogg music file 24 | music = sf.Music.from_file("data/orchestral.ogg") 25 | 26 | # display music informations 27 | print("orchestral.ogg:") 28 | print("{0} seconds".format(music.duration)) 29 | print("{0} samples / sec".format(music.sample_rate)) 30 | print("{0} channels".format(music.channel_count)) 31 | 32 | # play it 33 | music.play(); 34 | 35 | # loop while the music is playing 36 | while music.status == sf.Music.PLAYING: 37 | # leave some CPU time for other processes 38 | sf.sleep(sf.milliseconds(100)) 39 | 40 | if __name__ == "__main__": 41 | play_sound() 42 | play_music() 43 | 44 | input("Press enter to exit...") 45 | -------------------------------------------------------------------------------- /examples/sound_capture/sound_capture.py: -------------------------------------------------------------------------------- 1 | from sfml import sf 2 | 3 | # python 2.* compatability 4 | try: input = raw_input 5 | except NameError: pass 6 | 7 | def main(): 8 | # check that the device can capture audio 9 | if not sf.SoundRecorder.is_available(): 10 | print("Sorry, audio capture is not supported by your system") 11 | return 12 | 13 | # choose the sample rate 14 | sample_rate = int(input("Please choose the sample rate for sound capture (44100 is CD quality): ")) 15 | 16 | # wait for user input... 17 | input("Press enter to start recording audio") 18 | 19 | # here we'll use an integrated custom recorder, which saves the captured data into a sf.SoundBuffer 20 | recorder = sf.SoundBufferRecorder() 21 | 22 | # audio capture is done in a separate thread, so we can block the main thread while it is capturing 23 | recorder.start(sample_rate) 24 | input("Recording... press enter to stop") 25 | recorder.stop() 26 | 27 | # get the buffer containing the captured data 28 | buffer = recorder.buffer 29 | 30 | # display captured sound informations 31 | print("Sound information:") 32 | print("{0} seconds".format(buffer.duration)) 33 | print("{0} samples / seconds".format(buffer.sample_rate)) 34 | print("{0} channels".format(buffer.channel_count)) 35 | 36 | # choose what to do with the recorded sound data 37 | choice = input("What do you want to do with captured sound (p = play, s = save) ? ") 38 | 39 | if choice == 's': 40 | # choose the filename 41 | filename = input("Choose the file to create: ") 42 | 43 | # save the buffer 44 | buffer.to_file(filename); 45 | else: 46 | # create a sound instance and play it 47 | sound = sf.Sound(buffer) 48 | sound.play(); 49 | 50 | # wait until finished 51 | while sound.status == sf.Sound.PLAYING: 52 | # leave some CPU time for other threads 53 | sf.sleep(sf.milliseconds(100)) 54 | 55 | # finished ! 56 | print("Done !") 57 | 58 | # wait until the user presses 'enter' key 59 | input("Press enter to exit...") 60 | 61 | if __name__ == "__main__": 62 | main() 63 | -------------------------------------------------------------------------------- /examples/voip/client.py: -------------------------------------------------------------------------------- 1 | from sfml import sf 2 | from struct import pack 3 | from random import randint 4 | 5 | # python 2.* compatability 6 | try: input = raw_input 7 | except NameError: pass 8 | 9 | AUDIO_DATA, END_OF_STREAM = list(range(1, 3)) 10 | 11 | class NetworkRecorder(sf.SoundRecorder): 12 | def __init__(self, host, port): 13 | sf.SoundRecorder.__init__(self) 14 | 15 | self.host = host # address of the remote host 16 | self.port = port # remote port 17 | self.socket = sf.TcpSocket() # socket used to communicate with the server 18 | 19 | def on_start(self): 20 | try: self.socket.connect(self.host, self.port) 21 | except sf.SocketException as error: return False 22 | 23 | return True 24 | 25 | def on_process_samples(self, chunk): 26 | # pack the audio samples 27 | data = pack("B", AUDIO_DATA) 28 | data += pack("I", len(chunk.data)) 29 | data += chunk.data 30 | 31 | # send the audio packet 32 | try: self.socket.send(data) 33 | except sf.SocketException: return False 34 | 35 | return True 36 | 37 | def on_stop(self): 38 | # send a "end-of-stream" signal 39 | self.socket.send(bytes(END_OF_STREAM)) 40 | 41 | # close the socket 42 | self.socket.disconnect() 43 | 44 | def do_client(port): 45 | # check that the device can capture audio 46 | if not sf.SoundRecorder.is_available(): 47 | print("Sorry, audio capture is not supported by your system") 48 | return 49 | 50 | # ask for server address 51 | server = input("Type address or name of the server to connect to: ") 52 | server = sf.IpAddress.from_string(server) 53 | 54 | # create an instance of our custom recorder 55 | recorder = NetworkRecorder(server, port) 56 | 57 | # wait for the user input... 58 | input("Press enter to start recording audio") 59 | 60 | # start capturing audio data 61 | recorder.start(44100) 62 | input("Recording... press enter to stop") 63 | recorder.stop() 64 | -------------------------------------------------------------------------------- /examples/voip/server.py: -------------------------------------------------------------------------------- 1 | import threading 2 | from time import sleep 3 | from sfml import sf 4 | from struct import unpack 5 | 6 | # python 2.* compatability 7 | try: input = raw_input 8 | except NameError: pass 9 | 10 | AUDIO_DATA, END_OF_STREAM = list(range(1, 3)) 11 | 12 | class NetworkAudioStream(sf.SoundStream): 13 | def __init__(self): 14 | sf.SoundStream.__init__(self) 15 | 16 | self.offset = 0 17 | self.has_finished = False 18 | self.listener = sf.TcpListener() 19 | self.samples = sf.Chunk() 20 | 21 | # set the sound parameters 22 | self.initialize(1, 44100) 23 | 24 | def start(self, port): 25 | if not self.has_finished: 26 | try: 27 | # listen to the given port for incoming connections 28 | self.listener.listen(port) 29 | print("Server is listening to port {0}, waiting for connections... ".format(port)) 30 | 31 | # wait for a connection 32 | self.client = self.listener.accept() 33 | print("Client connected: {0}".format(self.client.remote_address)) 34 | 35 | except sf.SocketException: return 36 | 37 | # start playback 38 | self.play() 39 | 40 | # start receiving audio data 41 | self.receive_loop() 42 | 43 | else: 44 | # start playback 45 | self.play() 46 | 47 | def on_get_data(self, chunk): 48 | # we have reached the end of the buffer and all audio data have been played : we can stop playback 49 | if self.offset >= len(self.samples) and self.has_finished: 50 | return False 51 | 52 | # no new data has arrived since last update : wait until we get some 53 | while self.offset >= len(self.samples) and not self.has_finished: 54 | sf.sleep(sf.milliseconds(10)) 55 | 56 | # don't forget to lock as we run in two separate threads 57 | lock = threading.Lock() 58 | lock.acquire() 59 | 60 | # fill audio data to pass to the stream 61 | chunk.data = self.samples.data[self.offset*2:] 62 | 63 | # update the playing offset 64 | self.offset += len(chunk) 65 | 66 | lock.release() 67 | 68 | return True 69 | 70 | def on_seek(self, time_offset): 71 | self.offset = time_offset.milliseconds * self.sample_rate * self.channel_count // 1000 72 | 73 | def receive_loop(self): 74 | lock = threading.RLock() 75 | 76 | while not self.has_finished: 77 | # get waiting audio data from the network 78 | data = self.client.receive(1) 79 | 80 | # extract the id message 81 | id = unpack("B", data)[0] 82 | 83 | if id == AUDIO_DATA: 84 | # extract audio samples from the packet, and append it to our samples buffer 85 | data = self.client.receive(4) 86 | sample_count = unpack("I", data)[0] 87 | 88 | samples = self.client.receive(sample_count) 89 | 90 | # don't forget the other thread can access the sample array at any time 91 | lock.acquire() 92 | self.samples.data += samples 93 | lock.release() 94 | 95 | elif id == END_OF_STREAM: 96 | # end of stream reached : we stop receiving audio data 97 | print("Audio data has been 100% received!") 98 | self.has_finished = True 99 | 100 | else: 101 | # something's wrong... 102 | print("Invalid data received...") 103 | self.has_finished = True 104 | 105 | def do_server(port): 106 | # build an audio stream to play sound data as it is received through the network 107 | audio_stream = NetworkAudioStream() 108 | audio_stream.start(port) 109 | 110 | # loop until the sound playback is finished 111 | while audio_stream.status != sf.SoundStream.STOPPED: 112 | # leave some CPU time for other threads 113 | sf.sleep(sf.milliseconds(100)) 114 | 115 | 116 | # wait until the user presses 'enter' key 117 | input("Press enter to replay the sound...") 118 | 119 | # replay the sound (just to make sure replaying the received data is OK) 120 | audio_stream.play(); 121 | 122 | # loop until the sound playback is finished 123 | while audio_stream.status != sf.SoundStream.STOPPED: 124 | sf.sleep(sf.milliseconds(100)) 125 | -------------------------------------------------------------------------------- /examples/voip/voip.py: -------------------------------------------------------------------------------- 1 | from sfml import sf 2 | import client, server 3 | 4 | # python 2.* compatability 5 | try: input = raw_input 6 | except NameError: pass 7 | 8 | # choose a random port for opening sockets (ports < 1024 are reserved) 9 | PORT = 2435 10 | 11 | # client or server ? 12 | print("Do you want to be a server (s) or a client (c) ?") 13 | who = input() 14 | 15 | if who == 's': 16 | server.do_server(PORT) 17 | else: 18 | client.do_client(PORT) 19 | 20 | input("Press any key to exit...") 21 | -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x64/flac.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x64/flac.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x64/freetype.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x64/freetype.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x64/jpeg.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x64/jpeg.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x64/ogg.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x64/ogg.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x64/openal32.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x64/openal32.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x64/vorbis.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x64/vorbis.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x64/vorbisenc.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x64/vorbisenc.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x64/vorbisfile.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x64/vorbisfile.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x86/flac.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x86/flac.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x86/freetype.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x86/freetype.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x86/jpeg.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x86/jpeg.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x86/ogg.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x86/ogg.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x86/openal32.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x86/openal32.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x86/vorbis.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x86/vorbis.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x86/vorbisenc.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x86/vorbisenc.lib -------------------------------------------------------------------------------- /extlibs/libs-msvc-universal/x86/vorbisfile.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/libs-msvc-universal/x86/vorbisfile.lib -------------------------------------------------------------------------------- /extlibs/x64/openal32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/x64/openal32.dll -------------------------------------------------------------------------------- /extlibs/x86/openal32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/extlibs/x86/openal32.dll -------------------------------------------------------------------------------- /include/Includes/pysfml/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /include/Includes/pysfml/audio.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cimport sfml as sf 8 | from pysfml.system cimport Int16 9 | 10 | cdef extern from "pysfml/audio/audio.h": 11 | 12 | cdef class Chunk[type PyChunkType, object PyChunkObject]: 13 | cdef class sfml.audio.Chunk [object PyChunkObject]: 14 | cdef Int16* m_samples 15 | cdef size_t m_sampleCount 16 | cdef bint delete_this 17 | 18 | cdef extern from "pysfml/audio/audio_api.h": 19 | cdef void import_sfml__audio() 20 | 21 | cdef object create_chunk() 22 | cdef Int16* terminate_chunk(object) 23 | cdef object wrap_chunk(Int16*, unsigned int, bint) 24 | 25 | -------------------------------------------------------------------------------- /include/Includes/pysfml/graphics.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cimport sfml as sf 8 | from pysfml.system cimport Vector2 9 | from pysfml.system cimport NumericObject 10 | 11 | cdef extern from "pysfml/graphics/graphics.h": 12 | cdef class sfml.graphics.Rect [object PyRectObject]: 13 | cdef sf.Rect[NumericObject] *p_this 14 | 15 | cdef class sfml.graphics.Color [object PyColorObject]: 16 | cdef sf.Color *p_this 17 | 18 | cdef class sfml.graphics.BlendMode [object PyBlendModeObject]: 19 | cdef sf.BlendMode *p_this 20 | 21 | cdef class sfml.graphics.Image [object PyImageObject]: 22 | cdef sf.Image *p_this 23 | 24 | cdef class sfml.graphics.Texture [object PyTextureObject]: 25 | cdef sf.Texture *p_this 26 | cdef bint delete_this 27 | 28 | cdef class sfml.graphics.Drawable [object PyDrawableObject]: 29 | cdef sf.Drawable *p_drawable 30 | 31 | cdef class sfml.graphics.TransformableDrawable(Drawable) [object PyTransformableDrawableObject]: 32 | cdef sf.Transformable *p_transformable 33 | 34 | cdef class sfml.graphics.Sprite(TransformableDrawable) [object PySpriteObject]: 35 | cdef sf.Sprite *p_this 36 | cdef Texture m_texture 37 | 38 | cdef class sfml.graphics.Shape(TransformableDrawable) [object PyShapeObject]: 39 | cdef sf.Shape *p_shape 40 | cdef Texture m_texture 41 | 42 | cdef class sfml.graphics.ConvexShape(Shape) [object PyConvexShapeObject]: 43 | cdef sf.ConvexShape *p_this 44 | 45 | cdef class sfml.graphics.RenderTarget [object PyRenderTargetObject]: 46 | cdef sf.RenderTarget *p_rendertarget 47 | 48 | cdef class sfml.graphics.RenderStates [object PyRenderStatesObject]: 49 | pass 50 | 51 | cdef extern from "pysfml/graphics/graphics_api.h": 52 | cdef void import_sfml__graphics() 53 | 54 | cdef Color wrap_color(sf.Color *p) 55 | 56 | cdef Rect wrap_rect(sf.Rect[NumericObject]*) 57 | cdef Rect wrap_intrect(sf.IntRect*) 58 | cdef Rect wrap_floatrect(sf.FloatRect*) 59 | cdef sf.FloatRect to_floatrect(object) 60 | cdef sf.IntRect to_intrect(object) 61 | 62 | cdef BlendMode wrap_blendmode(sf.BlendMode*) 63 | cdef Image wrap_image(sf.Image*) 64 | cdef Texture wrap_texture(sf.Texture*, bint) 65 | cdef RenderStates wrap_renderstates(sf.RenderStates*, bint) 66 | cdef object wrap_convexshape(sf.ConvexShape*) 67 | cdef object wrap_rendertarget(sf.RenderTarget*) 68 | -------------------------------------------------------------------------------- /include/Includes/pysfml/network.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cimport sfml as sf 8 | 9 | cdef extern from "pysfml/network/network_api.h": 10 | cdef void import_sfml__network() 11 | -------------------------------------------------------------------------------- /include/Includes/pysfml/system.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cimport sfml as sf 8 | 9 | cdef extern from "pysfml/system/NumericObject.hpp": 10 | cdef cppclass NumericObject: 11 | NumericObject() 12 | NumericObject(object) 13 | 14 | object get() 15 | void set(object) 16 | 17 | cdef extern from "pysfml/system/system.h": 18 | cdef class sfml.system.Vector2 [object PyVector2Object]: 19 | cdef sf.Vector2[NumericObject] *p_this 20 | 21 | cdef class sfml.system.Vector3 [object PyVector3Object]: 22 | cdef sf.Vector3[NumericObject] *p_this 23 | 24 | cdef class sfml.system.Time [object PyTimeObject]: 25 | cdef sf.Time *p_this 26 | 27 | cdef extern from "pysfml/system/system_api.h": 28 | int import_sfml__system() 29 | 30 | object popLastErrorMessage() 31 | 32 | object wrap_string(const sf.String*) 33 | sf.String to_string(object string) 34 | 35 | cdef object wrap_vector2(sf.Vector2[NumericObject]*) 36 | cdef object wrap_vector2i(sf.Vector2i) 37 | cdef object wrap_vector2u(sf.Vector2u) 38 | cdef object wrap_vector2f(sf.Vector2f) 39 | 40 | cdef sf.Vector2i to_vector2i(object) 41 | cdef sf.Vector2u to_vector2u(object) 42 | cdef sf.Vector2f to_vector2f(object) 43 | 44 | cdef object wrap_vector3(sf.Vector3[NumericObject]*) 45 | cdef object wrap_vector3i(sf.Vector3i) 46 | cdef object wrap_vector3f(sf.Vector3f) 47 | 48 | cdef sf.Vector3i to_vector3i(object) 49 | cdef sf.Vector3f to_vector3f(object) 50 | 51 | cdef object wrap_time(sf.Time*) 52 | -------------------------------------------------------------------------------- /include/Includes/pysfml/window.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cimport sfml as sf 8 | from sfml cimport Uint8 9 | 10 | cdef extern from "pysfml/window/window.h": 11 | cdef class sfml.window.VideoMode [object PyVideoModeObject]: 12 | cdef sf.VideoMode *p_this 13 | cdef bint delete_this 14 | 15 | cdef class sfml.window.ContextSettings [object PyContextSettingsObject]: 16 | cdef sf.ContextSettings *p_this 17 | 18 | cdef class sfml.window.Event [object PyEventObject]: 19 | cdef sf.Event *p_this 20 | 21 | cdef class sfml.window.Window [object PyWindowObject]: 22 | cdef sf.Window *p_window 23 | cdef bint m_visible 24 | cdef bint m_vertical_synchronization 25 | 26 | cdef extern from "pysfml/window/window_api.h": 27 | cdef void import_sfml__window() 28 | 29 | cdef VideoMode wrap_videomode(sf.VideoMode *p, bint d) 30 | cdef ContextSettings wrap_contextsettings(sf.ContextSettings *v) 31 | -------------------------------------------------------------------------------- /include/Includes/sfml.pxd: -------------------------------------------------------------------------------- 1 | from sfml.sfml cimport * 2 | -------------------------------------------------------------------------------- /include/Includes/sfml/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/include/Includes/sfml/__init__.py -------------------------------------------------------------------------------- /include/Includes/sfml/blendmode.pxd: -------------------------------------------------------------------------------- 1 | 2 | # PySFML - Python bindings for SFML 3 | # Copyright (c) 2012-2017, Jonathan De Wachter 4 | # 5 | # This file is part of PySFML project and is available under the zlib 6 | # license. 7 | 8 | cdef extern from "SFML/Graphics.hpp" namespace "sf::BlendMode": 9 | cdef enum Factor: 10 | Zero 11 | One 12 | SrcColor 13 | OneMinusSrcColor 14 | DstColor 15 | OneMinusDstColor 16 | SrcAlpha 17 | OneMinusSrcAlpha 18 | DstAlpha 19 | OneMinusDstAlpha 20 | 21 | cdef enum Equation: 22 | Add 23 | Subtract 24 | -------------------------------------------------------------------------------- /include/Includes/sfml/contextsettings.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cdef extern from "SFML/Window.hpp" namespace "sf::ContextSettings": 8 | cdef enum Attribute: 9 | Default 10 | Core 11 | Debug 12 | -------------------------------------------------------------------------------- /include/Includes/sfml/event.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cdef extern from "SFML/Window.hpp" namespace "sf::Event": 8 | cdef enum EventType: 9 | Closed 10 | Resized 11 | LostFocus 12 | GainedFocus 13 | TextEntered 14 | KeyPressed 15 | KeyReleased 16 | MouseWheelMoved 17 | MouseWheelScrolled 18 | MouseButtonPressed 19 | MouseButtonReleased 20 | MouseMoved 21 | MouseEntered 22 | MouseLeft 23 | JoystickButtonPressed 24 | JoystickButtonReleased 25 | JoystickMoved 26 | JoystickConnected 27 | JoystickDisconnected 28 | TouchBegan 29 | TouchMoved 30 | TouchEnded 31 | SensorChanged 32 | Count 33 | -------------------------------------------------------------------------------- /include/Includes/sfml/font.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from libcpp.string cimport string 8 | 9 | cdef extern from "SFML/Window.hpp" namespace "sf::Font": 10 | 11 | cdef struct Info: 12 | string family 13 | -------------------------------------------------------------------------------- /include/Includes/sfml/ftp.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from libcpp.string cimport string 8 | from libcpp.vector cimport vector 9 | 10 | from ftp cimport response 11 | 12 | cdef extern from "SFML/Network.hpp" namespace "sf::Ftp": 13 | cdef enum TransferMode: 14 | Binary 15 | Ascii 16 | Ebcdic 17 | 18 | cdef cppclass Response: 19 | Response() 20 | Response(response.Status) 21 | Response(response.Status, const string&) 22 | bint isOk() const 23 | response.Status getStatus() const 24 | const string& getMessage() const 25 | 26 | cdef cppclass DirectoryResponse: 27 | DirectoryResponse(const Response&) 28 | const string& getDirectory() const 29 | 30 | cdef cppclass ListingResponse: 31 | ListingResponse(const Response&, const string&) 32 | const vector[string]& getListing() const 33 | -------------------------------------------------------------------------------- /include/Includes/sfml/ftp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/include/Includes/sfml/ftp/__init__.py -------------------------------------------------------------------------------- /include/Includes/sfml/ftp/response.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cdef extern from "SFML/Graphics.hpp" namespace "sf::Ftp::Response": 8 | cdef enum Status: 9 | RestartMarkerReply 10 | ServiceReadySoon 11 | DataConnectionAlreadyOpened 12 | OpeningDataConnection 13 | Ok 14 | PointlessCommand 15 | SystemStatus 16 | DirectoryStatus 17 | FileStatus 18 | HelpMessage 19 | SystemType 20 | ServiceReady 21 | ClosingConnection 22 | DataConnectionOpened 23 | ClosingDataConnection 24 | EnteringPassiveMode 25 | LoggedIn 26 | FileActionOk 27 | DirectoryOk 28 | NeedPassword 29 | NeedAccountToLogIn 30 | NeedInformation 31 | ServiceUnavailable 32 | DataConnectionUnavailable 33 | TransferAborted 34 | FileActionAborted 35 | LocalError 36 | InsufficientStorageSpace 37 | CommandUnknown 38 | ParametersUnknown 39 | CommandNotImplemented 40 | BadCommandSequence 41 | ParameterNotImplemented 42 | NotLoggedIn 43 | NeedAccountToStore 44 | FileUnavailable 45 | PageTypeUnknown 46 | NotEnoughMemory 47 | FilenameNotAllowed 48 | InvalidResponse 49 | ConnectionFailed 50 | ConnectionClosed 51 | InvalidFile 52 | -------------------------------------------------------------------------------- /include/Includes/sfml/http.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from libcpp.string cimport string 8 | 9 | from http cimport request, response 10 | 11 | cdef extern from "SFML/Network.hpp" namespace "sf::Http": 12 | cdef cppclass Request: 13 | Request(const string&) 14 | Request(const string&, request.Method) 15 | Request(const string&, request.Method, const string&) 16 | void setField(const string&, const string&) 17 | void setMethod(request.Method) 18 | void setUri(const string&) 19 | void setHttpVersion(unsigned int, unsigned int) 20 | void setBody(const string&) 21 | 22 | cdef cppclass Response: 23 | Response() 24 | const string& getField(const string&) const 25 | response.Status getStatus() const 26 | unsigned int getMajorHttpVersion() const 27 | unsigned int getMinorHttpVersion() const 28 | const string& getBody() const 29 | -------------------------------------------------------------------------------- /include/Includes/sfml/http/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intjelic/python-sfml/a757fbffaca1fdd0d07b623a806b830308a6a5c7/include/Includes/sfml/http/__init__.py -------------------------------------------------------------------------------- /include/Includes/sfml/http/request.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cdef extern from "SFML/Graphics.hpp" namespace "sf::Http::Request": 8 | cdef enum Method: 9 | Get 10 | Post 11 | Head 12 | -------------------------------------------------------------------------------- /include/Includes/sfml/http/response.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cdef extern from "SFML/Graphics.hpp" namespace "sf::Http::Response": 8 | cdef enum Status: 9 | Ok 10 | Created 11 | Accepted 12 | NoContent 13 | ResetContent 14 | PartialContent 15 | MultipleChoices 16 | MovedPermanently 17 | MovedTemporarily 18 | NotModified 19 | BadRequest 20 | Unauthorized 21 | Forbidden 22 | NotFound 23 | RangeNotSatisfiable 24 | InternalServerError 25 | NotImplemented 26 | BadGateway 27 | ServiceNotAvailable 28 | GatewayTimeout 29 | VersionNotSupported 30 | InvalidResponse 31 | ConnectionFailed 32 | -------------------------------------------------------------------------------- /include/Includes/sfml/ipaddress.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from sfml cimport Time 8 | from sfml cimport IpAddress 9 | 10 | cdef extern from "SFML/Network.hpp" namespace "sf::IpAddress": 11 | cdef IpAddress getLocalAddress() 12 | cdef IpAddress getPublicAddress() 13 | cdef IpAddress getPublicAddress(Time) 14 | 15 | IpAddress None 16 | IpAddress LocalHost 17 | IpAddress Broadcast 18 | -------------------------------------------------------------------------------- /include/Includes/sfml/joystick.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from sfml cimport String 8 | 9 | cdef extern from "SFML/Window.hpp" namespace "sf::Joystick": 10 | 11 | cdef enum: 12 | Count 13 | ButtonCount 14 | AxisCount 15 | 16 | cdef enum Axis: 17 | X 18 | Y 19 | Z 20 | R 21 | U 22 | V 23 | PovX 24 | PovY 25 | 26 | cdef struct Identification: 27 | Identification() 28 | String name 29 | unsigned int vendorId 30 | unsigned int productId 31 | 32 | bint isConnected(unsigned int) 33 | unsigned int getButtonCount(unsigned int) 34 | bint hasAxis(unsigned int, Axis) 35 | bint isButtonPressed(unsigned int, unsigned int) 36 | float getAxisPosition(unsigned int, Axis) 37 | Identification getIdentification(unsigned int) 38 | void update() 39 | -------------------------------------------------------------------------------- /include/Includes/sfml/keyboard.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cdef extern from "SFML/Window.hpp" namespace "sf::Keyboard": 8 | cdef enum Key: 9 | Unknown 10 | A 11 | B 12 | C 13 | D 14 | E 15 | F 16 | G 17 | H 18 | I 19 | J 20 | K 21 | L 22 | M 23 | N 24 | O 25 | P 26 | Q 27 | R 28 | S 29 | T 30 | U 31 | V 32 | W 33 | X 34 | Y 35 | Z 36 | Num0 37 | Num1 38 | Num2 39 | Num3 40 | Num4 41 | Num5 42 | Num6 43 | Num7 44 | Num8 45 | Num9 46 | Escape 47 | LControl 48 | LShift 49 | LAlt 50 | LSystem 51 | RControl 52 | RShift 53 | RAlt 54 | RSystem 55 | Menu 56 | LBracket 57 | RBracket 58 | SemiColon 59 | Comma 60 | Period 61 | Quote 62 | Slash 63 | BackSlash 64 | Tilde 65 | Equal 66 | Dash 67 | Space 68 | Return 69 | BackSpace 70 | Tab 71 | PageUp 72 | PageDown 73 | End 74 | Home 75 | Insert 76 | Delete 77 | Add 78 | Subtract 79 | Multiply 80 | Divide 81 | Left 82 | Right 83 | Up 84 | Down 85 | Numpad0 86 | Numpad1 87 | Numpad2 88 | Numpad3 89 | Numpad4 90 | Numpad5 91 | Numpad6 92 | Numpad7 93 | Numpad8 94 | Numpad9 95 | F1 96 | F2 97 | F3 98 | F4 99 | F5 100 | F6 101 | F7 102 | F8 103 | F9 104 | F10 105 | F11 106 | F12 107 | F13 108 | F14 109 | F15 110 | Pause 111 | KeyCount 112 | 113 | bint isKeyPressed(Key) 114 | void setVirtualKeyboardVisible(bint) 115 | -------------------------------------------------------------------------------- /include/Includes/sfml/listener.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from sfml cimport Vector3f 8 | 9 | cdef extern from "SFML/Audio.hpp" namespace "sf::Listener": 10 | cdef void setGlobalVolume(float) 11 | cdef float getGlobalVolume() 12 | cdef void setPosition(float, float, float) 13 | cdef void setPosition(const Vector3f&) 14 | cdef Vector3f getPosition() 15 | cdef void setDirection(float, float, float) 16 | cdef void setDirection(const Vector3f&) 17 | cdef Vector3f getDirection() 18 | cdef void setUpVector(float, float, float) 19 | cdef void setUpVector(const Vector3f&) 20 | cdef Vector3f getUpVector() 21 | -------------------------------------------------------------------------------- /include/Includes/sfml/mouse.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from sfml cimport Vector2i 8 | from sfml cimport Window 9 | 10 | cdef extern from "SFML/Window.hpp" namespace "sf::Mouse": 11 | cdef enum Button: 12 | Left 13 | Right 14 | Middle 15 | XButton1 16 | XButton2 17 | ButtonCount 18 | 19 | cdef enum Wheel: 20 | VerticalWheel 21 | HorizontalWheel 22 | 23 | bint isButtonPressed(Button) 24 | Vector2i getPosition() 25 | Vector2i getPosition(const Window&) 26 | void setPosition(const Vector2i&) 27 | void setPosition(const Vector2i&, const Window&) 28 | -------------------------------------------------------------------------------- /include/Includes/sfml/primitivetype.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cdef extern from "SFML/Graphics.hpp" namespace "sf": 8 | cdef enum PrimitiveType: 9 | Points 10 | Lines 11 | LinesStrip 12 | Triangles 13 | TrianglesStrip 14 | TrianglesFan 15 | Quads 16 | -------------------------------------------------------------------------------- /include/Includes/sfml/renderstates.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from sfml cimport RenderStates 8 | 9 | cdef extern from "SFML/Graphics.hpp" namespace "sf::RenderStates": 10 | cdef const RenderStates Default 11 | -------------------------------------------------------------------------------- /include/Includes/sfml/sensor.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from sfml cimport Vector3f 8 | from sfml cimport Window 9 | 10 | cdef extern from "SFML/Window.hpp" namespace "sf::Sensor": 11 | cdef enum Type: 12 | Accelerometer 13 | Gyroscope 14 | Magnetometer 15 | Gravity 16 | UserAcceleration 17 | Orientation 18 | Count 19 | 20 | bint isAvailable(Type) 21 | void setEnabled(Type, bint) 22 | Vector3f getValue(Type) 23 | -------------------------------------------------------------------------------- /include/Includes/sfml/shader.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from sfml cimport Shader 8 | 9 | cdef extern from "SFML/Graphics.hpp" namespace "sf::Shader": 10 | cdef struct CurrentTextureType: 11 | pass 12 | 13 | cdef CurrentTextureType CurrentTexture 14 | 15 | cdef enum Type: 16 | Vertex 17 | Fragment 18 | 19 | cdef bint isAvailable() 20 | cdef void bind(const Shader*) 21 | -------------------------------------------------------------------------------- /include/Includes/sfml/socket.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cdef extern from "SFML/Network.hpp" namespace "sf::Socket": 8 | cdef enum Status: 9 | Done 10 | NotReady 11 | Disconnected 12 | Error 13 | 14 | cdef enum: 15 | AnyPort 16 | -------------------------------------------------------------------------------- /include/Includes/sfml/soundrecorder.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from libcpp.string cimport string 8 | from libcpp.vector cimport vector 9 | 10 | cdef extern from "SFML/Audio.hpp" namespace "sf::SoundRecorder": 11 | cdef bint isAvailable() 12 | cdef vector[string] getAvailableDevices() 13 | cdef string getDefaultDevice() 14 | -------------------------------------------------------------------------------- /include/Includes/sfml/soundsource.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cdef extern from "SFML/Audio.hpp" namespace "sf::SoundSource": 8 | cdef enum Status: 9 | Stopped 10 | Paused 11 | Playing 12 | -------------------------------------------------------------------------------- /include/Includes/sfml/soundstream.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from sfml cimport Int16 8 | 9 | cdef extern from "SFML/Audio.hpp" namespace "sf::SoundRecorder": 10 | 11 | cdef struct Chunk: 12 | const Int16* samples 13 | size_t sampleCount 14 | -------------------------------------------------------------------------------- /include/Includes/sfml/style.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cdef extern from "SFML/Window.hpp" namespace "sf::Style": 8 | cdef enum: 9 | None 10 | Titlebar 11 | Resize 12 | Close 13 | Fullscreen 14 | Default 15 | -------------------------------------------------------------------------------- /include/Includes/sfml/text.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cdef extern from "SFML/Graphics.hpp" namespace "sf::Text": 8 | cdef enum Style: 9 | Regular 10 | Bold 11 | Italic 12 | Underlined 13 | StrikeThrough 14 | -------------------------------------------------------------------------------- /include/Includes/sfml/texture.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from sfml cimport Texture 8 | 9 | 10 | cdef extern from "SFML/Graphics.hpp" namespace "sf::Texture": 11 | cdef unsigned int getMaximumSize() 12 | 13 | cdef enum CoordinateType: 14 | Normalized 15 | Pixels 16 | 17 | cdef void bind(const Texture*) 18 | cdef void bind(const Texture*, CoordinateType) 19 | -------------------------------------------------------------------------------- /include/Includes/sfml/time.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from sfml cimport Time 8 | 9 | cdef extern from "SFML/System.hpp" namespace "sf::Time": 10 | cdef Time Zero 11 | -------------------------------------------------------------------------------- /include/Includes/sfml/touch.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from sfml cimport Vector2i 8 | from sfml cimport Window 9 | 10 | cdef extern from "SFML/Window.hpp" namespace "sf::Touch": 11 | bint isDown(unsigned int) 12 | Vector2i getPosition(unsigned int) 13 | Vector2i getPosition(unsigned int, const Window&) 14 | -------------------------------------------------------------------------------- /include/Includes/sfml/transform.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from sfml cimport Transform 8 | 9 | cdef extern from "SFML/Graphics.hpp" namespace "sf::Transform": 10 | cdef Transform Identity 11 | -------------------------------------------------------------------------------- /include/Includes/sfml/udpsocket.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | cdef extern from "SFML/Network.hpp" namespace "sf::UdpSocket": 8 | cdef enum: 9 | MaxDatagramSize 10 | -------------------------------------------------------------------------------- /include/Includes/sfml/videomode.pxd: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from libcpp.vector cimport vector 8 | from sfml cimport VideoMode 9 | 10 | cdef extern from "SFML/Graphics.hpp" namespace "sf::VideoMode": 11 | cdef VideoMode& getDesktopMode() 12 | cdef const vector[VideoMode]& getFullscreenModes() 13 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Cython -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import platform 4 | import os.path 5 | import shutil 6 | from glob import glob 7 | from subprocess import call 8 | from setuptools import setup, Command, Extension 9 | 10 | try: 11 | from Cython.Distutils import build_ext 12 | except ImportError: 13 | print("Please install Cython and try again.") 14 | exit(1) 15 | 16 | SFML_HEADERS = os.getenv('SFML_HEADERS') 17 | SFML_LIBRARIES = os.getenv('SFML_LIBRARIES') 18 | 19 | if platform.architecture()[0] == "32bit": 20 | arch = "x86" 21 | elif platform.architecture()[0] == "64bit": 22 | arch = "x64" 23 | 24 | class CythonBuildExt(build_ext): 25 | """ Updated version of cython build_ext command. 26 | 27 | This version of cython build_ext command include generated API headers to 28 | the build process of subsequent extensions. The C/C++ header files are all 29 | moved to the temporary build directory before being properly installed on 30 | the system. 31 | """ 32 | 33 | def cython_sources(self, sources, extension): 34 | 35 | # cythonize .pxd source files 36 | ret = build_ext.cython_sources(self, sources, extension) 37 | 38 | # should result the module name; e.g, graphics[.pyx] 39 | module = os.path.basename(sources[0])[:-4] 40 | 41 | # prepare a list with all header files related to the module (*.hpp, *_api.h, *.h) 42 | header_files = glob(os.path.join('src', 'sfml', module, '*.hpp')) 43 | 44 | header_files.append(os.path.join('src', 'sfml', module, module + '.h')) 45 | header_files.append(os.path.join('src', 'sfml', module, module + '_api.h')) 46 | 47 | # deal with exceptions 48 | if module == "network": 49 | header_files.remove(os.path.join('src', 'sfml', module, module + '.h')) 50 | header_files.remove(os.path.join('src', 'sfml', module, module + '_api.h')) 51 | 52 | # create the temporary destination in the build directory 53 | destination = os.path.join( 54 | self.build_temp, 'include', 'pysfml', module) 55 | 56 | if not os.path.exists(destination): 57 | os.makedirs(destination) 58 | 59 | # move all header files to the build directory 60 | for header_file in header_files: 61 | if os.path.isfile(header_file): 62 | try: 63 | shutil.copy(header_file, destination) 64 | except shutil.Error: 65 | pass 66 | 67 | # add the temporary header directory to compilation options 68 | self.compiler.include_dirs.append( 69 | os.path.join(self.build_temp, 'include')) 70 | 71 | # update data_files to install the files on the system 72 | 73 | # On Windows: C:\Python27\include\pysfml\*_api.h 74 | # On Unix: /usr/local/include/pysfml/*_api.h 75 | install_directory = os.path.join(sys.exec_prefix, 'include', 'pysfml', module) 76 | files_to_install = [os.path.join(self.build_temp, 'include', 'pysfml', module, os.path.basename(header_file)) for header_file in header_files] 77 | data_files.append((install_directory, files_to_install)) 78 | 79 | return ret 80 | 81 | include_dirs = [] 82 | library_dirs = [] 83 | 84 | include_dirs.append(os.path.join('include', 'Includes')) 85 | if SFML_HEADERS: 86 | include_dirs.append(SFML_HEADERS) 87 | 88 | if sys.hexversion >= 0x03050000: 89 | library_dirs.append(os.path.join('extlibs', 'libs-msvc-universal', arch)) 90 | 91 | if SFML_LIBRARIES: 92 | include_dirs.append(SFML_LIBRARIES) 93 | 94 | def extension(name, files, libs): return Extension( 95 | name='sfml.' + name, 96 | sources=[os.path.join('src', 'sfml', name, filename) for filename in files], 97 | include_dirs=include_dirs, 98 | library_dirs=library_dirs, 99 | language='c++', 100 | libraries=libs, 101 | define_macros=[('SFML_STATIC', '1')] if platform.system() == 'Windows' else [] 102 | ) 103 | 104 | if platform.system() == 'Windows': 105 | system_libs = [ 106 | 'winmm', 107 | 'sfml-system-s' 108 | ] 109 | window_libs = [ 110 | 'user32', 111 | 'advapi32', 112 | 'winmm', 113 | 'sfml-system-s', 114 | 'gdi32', 115 | 'opengl32', 116 | 'sfml-window-s' 117 | ] 118 | graphics_libs = [ 119 | 'user32', 120 | 'advapi32', 121 | 'winmm', 122 | 'sfml-system-s', 123 | 'gdi32', 124 | 'opengl32', 125 | 'sfml-window-s', 126 | 'freetype', 127 | 'jpeg', 128 | 'sfml-graphics-s' 129 | ] 130 | audio_libs = [ 131 | 'winmm', 132 | 'sfml-system-s', 133 | 'flac', 134 | 'vorbisenc', 135 | 'vorbisfile', 136 | 'vorbis', 137 | 'ogg', 138 | 'openal32', 139 | 'sfml-audio-s' 140 | ] 141 | network_libs = [ 142 | 'ws2_32', 143 | 'sfml-system-s', 144 | 'sfml-network-s' 145 | ] 146 | else: 147 | system_libs = ['sfml-system'] 148 | window_libs = ['sfml-system', 'sfml-window'] 149 | graphics_libs = ['sfml-system', 'sfml-window', 'sfml-graphics'] 150 | audio_libs = ['sfml-system', 'sfml-audio'] 151 | network_libs = ['sfml-system', 'sfml-network'] 152 | 153 | system = extension( 154 | 'system', 155 | ['system.pyx', 'error.cpp', 'hacks.cpp', 'NumericObject.cpp'], 156 | system_libs 157 | ) 158 | 159 | window = extension( 160 | 'window', 161 | ['window.pyx', 'DerivableWindow.cpp'], 162 | window_libs 163 | ) 164 | 165 | graphics = extension( 166 | 'graphics', 167 | ['graphics.pyx', 'DerivableRenderWindow.cpp', 'DerivableDrawable.cpp', 'NumericObject.cpp'], 168 | graphics_libs) 169 | 170 | audio = extension( 171 | 'audio', 172 | ['audio.pyx', 'DerivableSoundRecorder.cpp', 'DerivableSoundStream.cpp'], 173 | audio_libs 174 | ) 175 | 176 | network = extension( 177 | 'network', 178 | ['network.pyx'], 179 | network_libs 180 | ) 181 | 182 | major, minor, _, _, _ = sys.version_info 183 | 184 | data_files = [] 185 | if platform.system() == 'Windows': 186 | dlls = [("Lib\\site-packages\\sfml", glob('extlibs\\' + arch + '\\openal32.dll'))] 187 | data_files += dlls 188 | 189 | with open('README.md', 'r') as f: 190 | long_description = f.read() 191 | 192 | setup( 193 | name='pySFML', 194 | ext_modules=[system, window, graphics, audio, network], 195 | package_dir={'': 'src'}, 196 | packages=['sfml'], 197 | data_files=data_files, 198 | version='2.3.2.dev1', 199 | description='Python bindings for SFML', 200 | long_description=long_description, 201 | author='Jonathan de Wachter', 202 | author_email='dewachter.jonathan@gmail.com', 203 | url='http://python-sfml.org', 204 | classifiers=[ 205 | 'Development Status :: 5 - Production/Stable', 206 | 'Intended Audience :: Developers', 207 | 'License :: OSI Approved :: zlib/libpng License', 208 | 'Operating System :: OS Independent', 209 | 'Programming Language :: Python :: 3', 210 | 'Programming Language :: Cython', 211 | 'Programming Language :: C++', 212 | 'Programming Language :: Python', 213 | 'Programming Language :: Python :: Implementation :: CPython', 214 | 'Topic :: Games/Entertainment', 215 | 'Topic :: Multimedia', 216 | 'Topic :: Software Development :: Libraries :: Python Modules' 217 | ], 218 | keywords='sfml SFML simple fast multimedia system window graphics audio network pySFML PySFML python-sfml', 219 | install_requires=['Cython'], 220 | cmdclass={'build_ext': CythonBuildExt} 221 | ) 222 | -------------------------------------------------------------------------------- /src/sfml/__init__.py: -------------------------------------------------------------------------------- 1 | import sfml.system 2 | import sfml.window 3 | import sfml.graphics 4 | import sfml.audio 5 | import sfml.network 6 | -------------------------------------------------------------------------------- /src/sfml/audio/DerivableSoundRecorder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | DerivableSoundRecorder::DerivableSoundRecorder(void* pyobj): 13 | sf::SoundRecorder (), 14 | m_pyobj (static_cast(pyobj)) 15 | { 16 | import_sfml__audio(); 17 | }; 18 | 19 | bool DerivableSoundRecorder::onStart() 20 | { 21 | PyEval_InitThreads(); 22 | 23 | static char method[] = "on_start"; 24 | PyObject* r = PyObject_CallMethod(m_pyobj, method, NULL); 25 | 26 | if(!r) 27 | PyErr_Print(); 28 | 29 | return PyObject_IsTrue(r); 30 | } 31 | 32 | bool DerivableSoundRecorder::onProcessSamples(const sf::Int16* samples, std::size_t sampleCount) 33 | { 34 | static char method[] = "on_process_samples"; 35 | static char format[] = "O"; 36 | 37 | PyGILState_STATE gstate; 38 | gstate = PyGILState_Ensure(); 39 | 40 | PyObject* pyChunk = (PyObject*)(wrap_chunk((sf::Int16*)samples, sampleCount, false)); 41 | PyObject* r = PyObject_CallMethod(m_pyobj, method, format, pyChunk); 42 | 43 | if(!r) 44 | PyErr_Print(); 45 | 46 | Py_DECREF(pyChunk); 47 | PyGILState_Release(gstate); 48 | 49 | return PyObject_IsTrue(r); 50 | } 51 | 52 | void DerivableSoundRecorder::onStop() 53 | { 54 | PyGILState_STATE gstate; 55 | gstate = PyGILState_Ensure(); 56 | 57 | static char method[] = "on_stop"; 58 | PyObject* success = PyObject_CallMethod(m_pyobj, method, NULL); 59 | 60 | if(!success) 61 | PyErr_Print(); 62 | 63 | PyGILState_Release(gstate); 64 | } 65 | -------------------------------------------------------------------------------- /src/sfml/audio/DerivableSoundRecorder.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #ifndef PYSFML_AUDIO_DERIVABLESOUNDRECORDER_HPP 10 | #define PYSFML_AUDIO_DERIVABLESOUNDRECORDER_HPP 11 | 12 | #include "Python.h" 13 | #include 14 | #include 15 | 16 | class DerivableSoundRecorder : public sf::SoundRecorder 17 | { 18 | public : 19 | DerivableSoundRecorder(void* pyThis); 20 | 21 | protected: 22 | virtual bool onStart(); 23 | virtual bool onProcessSamples(const sf::Int16* samples, std::size_t sampleCount); 24 | virtual void onStop(); 25 | 26 | PyObject* m_pyobj; 27 | }; 28 | 29 | 30 | #endif // PYSFML_AUDIO_DERIVABLESOUNDRECORDER_HPP 31 | -------------------------------------------------------------------------------- /src/sfml/audio/DerivableSoundStream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #include 10 | 11 | DerivableSoundStream::DerivableSoundStream(void* pyobj): 12 | sf::SoundStream (), 13 | m_pyobj (static_cast(pyobj)) 14 | { 15 | PyEval_InitThreads(); 16 | import_sfml__system(); 17 | import_sfml__audio(); 18 | }; 19 | 20 | void DerivableSoundStream::initialize(unsigned int channelCount, unsigned int sampleRate) 21 | { 22 | sf::SoundStream::initialize(channelCount, sampleRate); 23 | } 24 | 25 | bool DerivableSoundStream::onGetData(sf::SoundStream::Chunk &data) 26 | { 27 | PyGILState_STATE gstate; 28 | gstate = PyGILState_Ensure(); 29 | 30 | static char method[] = "on_get_data"; 31 | static char format[] = "O"; 32 | 33 | PyObject* pyChunk = (PyObject*)(create_chunk()); 34 | PyObject* r = PyObject_CallMethod(m_pyobj, method, format, pyChunk); 35 | 36 | if(!r) 37 | PyErr_Print(); 38 | 39 | data.samples = static_cast(terminate_chunk(pyChunk)); 40 | data.sampleCount = PyObject_Length(pyChunk); 41 | 42 | Py_DECREF(pyChunk); 43 | 44 | PyGILState_Release(gstate); 45 | 46 | return PyObject_IsTrue(r); 47 | } 48 | 49 | void DerivableSoundStream::onSeek(sf::Time timeOffset) 50 | { 51 | PyGILState_STATE gstate; 52 | gstate = PyGILState_Ensure(); 53 | 54 | static char method[] = "on_seek"; 55 | static char format[] = "O"; 56 | 57 | sf::Time* copyTimeOffset = new sf::Time; 58 | *copyTimeOffset = timeOffset; 59 | 60 | PyObject* pyTime = (PyObject*)(wrap_time(copyTimeOffset)); 61 | PyObject* success = PyObject_CallMethod(m_pyobj, method, format, pyTime); 62 | 63 | if(!success) 64 | PyErr_Print(); 65 | 66 | Py_DECREF(pyTime); 67 | 68 | PyGILState_Release(gstate); 69 | } 70 | 71 | -------------------------------------------------------------------------------- /src/sfml/audio/DerivableSoundStream.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #ifndef PYSFML_SYSTEM_DERIVABLESOUNDSTREAM_HPP 10 | #define PYSFML_SYSTEM_DERIVABLESOUNDSTREAM_HPP 11 | 12 | #include "Python.h" 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | class DerivableSoundStream : public sf::SoundStream 19 | { 20 | public : 21 | DerivableSoundStream(void* pyThis); 22 | 23 | void initialize(unsigned int channelCount, unsigned int sampleRate); 24 | 25 | protected: 26 | virtual bool onGetData(sf::SoundStream::Chunk &data); 27 | virtual void onSeek(sf::Time timeOffset); 28 | 29 | PyObject* m_pyobj; 30 | }; 31 | 32 | #endif // PYSFML_SYSTEM_DERIVABLESOUNDSTREAM_HPP 33 | -------------------------------------------------------------------------------- /src/sfml/audio/audio.pyx: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | #from libc.stdlib cimport malloc, free 8 | #from cython.operator cimport preincrement as preinc, dereference as deref 9 | 10 | cimport cython 11 | from libc.stdlib cimport malloc, free 12 | from libc.string cimport memcpy 13 | from libcpp.string cimport string 14 | from libcpp.vector cimport vector 15 | 16 | cimport sfml as sf 17 | from sfml cimport Int8, Int16, Int32, Int64 18 | from sfml cimport Uint8, Uint16, Uint32, Uint64 19 | from pysfml.system cimport Vector3, Time 20 | from pysfml.system cimport wrap_vector3f, to_vector3f 21 | from pysfml.system cimport wrap_time, to_vector3f 22 | from pysfml.system cimport popLastErrorMessage, import_sfml__system 23 | 24 | from enum import IntEnum 25 | 26 | import_sfml__system() 27 | 28 | cdef extern from "pysfml/audio/DerivableSoundStream.hpp": 29 | cdef cppclass DerivableSoundStream: 30 | DerivableSoundStream(void*) 31 | void initialize(unsigned int, unsigned int) 32 | 33 | cdef extern from "pysfml/audio/DerivableSoundRecorder.hpp": 34 | cdef cppclass DerivableSoundRecorder: 35 | DerivableSoundRecorder(void*) 36 | 37 | 38 | cdef class Listener: 39 | def __init__(self): 40 | NotImplementedError("This class is not meant to be instantiated!") 41 | 42 | @staticmethod 43 | def get_global_volume(): 44 | return sf.listener.getGlobalVolume() 45 | 46 | @staticmethod 47 | def set_global_volume(float volume): 48 | sf.listener.setGlobalVolume(volume) 49 | 50 | @staticmethod 51 | def get_position(): 52 | cdef sf.Vector3f p = sf.listener.getPosition() 53 | return wrap_vector3f(p) 54 | 55 | @staticmethod 56 | def set_position(position): 57 | sf.listener.setPosition(to_vector3f(position)) 58 | 59 | @staticmethod 60 | def get_direction(): 61 | cdef sf.Vector3f p = sf.listener.getDirection() 62 | return wrap_vector3f(p) 63 | 64 | @staticmethod 65 | def set_direction(direction): 66 | sf.listener.setDirection(to_vector3f(direction)) 67 | 68 | @staticmethod 69 | def get_up_vector(): 70 | cdef sf.Vector3f p = sf.listener.getUpVector() 71 | return wrap_vector3f(p) 72 | 73 | @staticmethod 74 | def set_up_vector(up_vector): 75 | sf.listener.setUpVector(to_vector3f(up_vector)) 76 | 77 | cdef public class Chunk[type PyChunkType, object PyChunkObject]: 78 | cdef Int16* m_samples 79 | cdef size_t m_sampleCount 80 | cdef bint delete_this 81 | 82 | def __cinit__(self): 83 | self.m_samples = NULL 84 | self.m_sampleCount = 0 85 | self.delete_this = False 86 | 87 | def __dealloc__(self): 88 | if self.delete_this: 89 | free(self.m_samples) 90 | 91 | def __repr__(self): 92 | return "Chunk(size={0}, data={1})".format(len(self), self.data[:10]) 93 | 94 | def __len__(self): 95 | return self.m_sampleCount 96 | 97 | def __getitem__(self, size_t key): 98 | return self.m_samples[key] 99 | 100 | def __setitem__(self, size_t key, Int16 other): 101 | self.m_samples[key] = other 102 | 103 | property data: 104 | def __get__(self): 105 | return (self.m_samples)[:len(self)*2] 106 | 107 | def __set__(self, bdata): 108 | cdef char* data = bdata 109 | 110 | if len(bdata) % 2: 111 | raise ValueError("Chunk data length must be even as it represents a 16bit array") 112 | 113 | if self.delete_this: 114 | free(self.m_samples) 115 | self.m_sampleCount = 0 116 | 117 | self.m_samples = malloc(len(bdata)) 118 | memcpy(self.m_samples, data, len(bdata)) 119 | self.m_sampleCount = len(bdata) // 2 120 | 121 | self.delete_this = True 122 | 123 | cdef api object create_chunk(): 124 | cdef Chunk r = Chunk.__new__(Chunk) 125 | r.m_samples = NULL 126 | r.m_sampleCount = 0 127 | r.delete_this = False 128 | return r 129 | 130 | cdef api Int16* terminate_chunk(chunk): 131 | cdef Chunk p = chunk 132 | p.delete_this = False 133 | return p.m_samples 134 | 135 | cdef api object wrap_chunk(Int16* samples, unsigned int sample_count, bint delete): 136 | cdef Chunk r = Chunk.__new__(Chunk) 137 | r.m_samples = samples 138 | r.m_sampleCount = sample_count 139 | r.delete_this = delete 140 | return r 141 | 142 | cdef class SoundBuffer: 143 | cdef sf.SoundBuffer *p_this 144 | cdef bint delete_this 145 | 146 | def __init__(self): 147 | raise UserWarning("Use specific methods") 148 | 149 | def __dealloc__(self): 150 | if self.delete_this: 151 | del self.p_this 152 | 153 | def __repr__(self): 154 | return "SoundBuffer(sample_rate={0}, channel_count={1}, duration={2})".format(self.sample_rate, self.channel_count, self.duration) 155 | 156 | @classmethod 157 | def from_file(cls, basestring filename): 158 | cdef sf.SoundBuffer *p = new sf.SoundBuffer() 159 | 160 | if p.loadFromFile(filename.encode('UTF-8')): 161 | return wrap_soundbuffer(p) 162 | 163 | del p 164 | raise IOError(popLastErrorMessage()) 165 | 166 | @classmethod 167 | def from_memory(cls, bytes data): 168 | cdef sf.SoundBuffer *p = new sf.SoundBuffer() 169 | 170 | if p.loadFromMemory(data, len(data)): 171 | return wrap_soundbuffer(p) 172 | 173 | del p 174 | raise IOError(popLastErrorMessage()) 175 | 176 | @classmethod 177 | def from_samples(cls, Chunk samples, unsigned int channel_count, unsigned int sample_rate): 178 | cdef sf.SoundBuffer *p = new sf.SoundBuffer() 179 | 180 | if p.loadFromSamples(samples.m_samples, samples.m_sampleCount, channel_count, sample_rate): 181 | return wrap_soundbuffer(p) 182 | 183 | del p 184 | raise IOError(popLastErrorMessage()) 185 | 186 | def to_file(self, basestring filename): 187 | cdef char* encoded_filename 188 | 189 | self.p_this.saveToFile(filename.encode('UTF-8')) 190 | 191 | property samples: 192 | def __get__(self): 193 | cdef Chunk r = Chunk.__new__(Chunk) 194 | r.m_samples = self.p_this.getSamples() 195 | r.m_sampleCount = self.p_this.getSampleCount() 196 | return r 197 | 198 | property sample_rate: 199 | def __get__(self): 200 | return self.p_this.getSampleRate() 201 | 202 | property channel_count: 203 | def __get__(self): 204 | return self.p_this.getChannelCount() 205 | 206 | property duration: 207 | def __get__(self): 208 | cdef sf.Time* p = new sf.Time() 209 | p[0] = self.p_this.getDuration() 210 | return wrap_time(p) 211 | 212 | cdef SoundBuffer wrap_soundbuffer(sf.SoundBuffer *p, bint delete_this=True): 213 | cdef SoundBuffer r = SoundBuffer.__new__(SoundBuffer) 214 | r.p_this = p 215 | r.delete_this = delete_this 216 | return r 217 | 218 | class Status(IntEnum): 219 | STOPPED = sf.soundsource.Stopped 220 | PAUSED = sf.soundsource.Paused 221 | PLAYING = sf.soundsource.Playing 222 | 223 | cdef class SoundSource: 224 | cdef sf.SoundSource *p_soundsource 225 | 226 | def __init__(self, *args, **kwargs): 227 | raise UserWarning("This class is not meant to be used directly") 228 | 229 | property pitch: 230 | def __get__(self): 231 | return self.p_soundsource.getPitch() 232 | 233 | def __set__(self, float pitch): 234 | self.p_soundsource.setPitch(pitch) 235 | 236 | property volume: 237 | def __get__(self): 238 | return self.p_soundsource.getVolume() 239 | 240 | def __set__(self, float volume): 241 | self.p_soundsource.setVolume(volume) 242 | 243 | property position: 244 | def __get__(self): 245 | cdef sf.Vector3f p = self.p_soundsource.getPosition() 246 | return wrap_vector3f(p) 247 | 248 | def __set__(self, position): 249 | self.p_soundsource.setPosition(to_vector3f(position)) 250 | 251 | property relative_to_listener: 252 | def __get__(self): 253 | return self.p_soundsource.isRelativeToListener() 254 | 255 | def __set__(self, bint relative): 256 | self.p_soundsource.setRelativeToListener(relative) 257 | 258 | property min_distance: 259 | def __get__(self): 260 | return self.p_soundsource.getMinDistance() 261 | 262 | def __set__(self, float distance): 263 | self.p_soundsource.setMinDistance(distance) 264 | 265 | property attenuation: 266 | def __get__(self): 267 | return self.p_soundsource.getAttenuation() 268 | 269 | def __set__(self, float attenuation): 270 | self.p_soundsource.setAttenuation(attenuation) 271 | 272 | 273 | cdef class Sound(SoundSource): 274 | cdef sf.Sound *p_this 275 | cdef SoundBuffer m_buffer 276 | 277 | def __init__(self, SoundBuffer buffer=None): 278 | if self.p_this is NULL: 279 | self.p_this = new sf.Sound() 280 | self.p_soundsource = self.p_this 281 | 282 | if buffer: 283 | self.buffer = buffer 284 | 285 | def __dealloc__(self): 286 | self.p_soundsource = NULL 287 | 288 | if self.p_this is not NULL: 289 | del self.p_this 290 | 291 | def __repr__(self): 292 | return "Sound(buffer={0}, status={1}, playing_offset={2})".format(id(self.buffer), self.status, self.playing_offset) 293 | 294 | def play(self): 295 | self.p_this.play() 296 | 297 | def pause(self): 298 | self.p_this.pause() 299 | 300 | def stop(self): 301 | self.p_this.stop() 302 | 303 | property buffer: 304 | def __get__(self): 305 | return self.m_buffer 306 | 307 | def __set__(self, SoundBuffer buffer): 308 | self.p_this.setBuffer(buffer.p_this[0]) 309 | self.m_buffer = buffer 310 | 311 | property loop: 312 | def __get__(self): 313 | return self.p_this.getLoop() 314 | 315 | def __set__(self, bint loop): 316 | self.p_this.setLoop(loop) 317 | 318 | property playing_offset: 319 | def __get__(self): 320 | cdef sf.Time* p = new sf.Time() 321 | p[0] = self.p_this.getPlayingOffset() 322 | return wrap_time(p) 323 | 324 | def __set__(self, Time time_offset): 325 | self.p_this.setPlayingOffset(time_offset.p_this[0]) 326 | 327 | property status: 328 | def __get__(self): 329 | return self.p_this.getStatus() 330 | 331 | 332 | cdef class SoundStream(SoundSource): 333 | cdef sf.SoundStream *p_soundstream 334 | 335 | def __init__(self): 336 | if self.__class__ == SoundStream: 337 | raise NotImplementedError("SoundStream is abstract") 338 | 339 | if self.p_soundstream is NULL: 340 | self.p_soundstream = new DerivableSoundStream(self) 341 | self.p_soundsource = self.p_soundstream 342 | 343 | def __dealloc__(self): 344 | self.p_soundsource = NULL 345 | 346 | if self.p_soundstream is not NULL: 347 | del self.p_soundstream 348 | 349 | def play(self): 350 | self.p_soundstream.play() 351 | 352 | def pause(self): 353 | self.p_soundstream.pause() 354 | 355 | def stop(self): 356 | self.p_soundstream.stop() 357 | 358 | property channel_count: 359 | def __get__(self): 360 | return self.p_soundstream.getChannelCount() 361 | 362 | property sample_rate: 363 | def __get__(self): 364 | return self.p_soundstream.getSampleRate() 365 | 366 | property status: 367 | def __get__(self): 368 | return self.p_soundstream.getStatus() 369 | 370 | property playing_offset: 371 | def __get__(self): 372 | cdef sf.Time* p = new sf.Time() 373 | p[0] = self.p_soundstream.getPlayingOffset() 374 | return wrap_time(p) 375 | 376 | def __set__(self, Time time_offset): 377 | self.p_soundstream.setPlayingOffset(time_offset.p_this[0]) 378 | 379 | property loop: 380 | def __get__(self): 381 | return self.p_soundstream.getLoop() 382 | 383 | def __set__(self, bint loop): 384 | self.p_soundstream.setLoop(loop) 385 | 386 | def initialize(self, unsigned int channel_count, unsigned int sample_rate): 387 | if self.__class__ not in [Music]: 388 | (self.p_soundstream).initialize(channel_count, sample_rate) 389 | 390 | def on_get_data(self, data): 391 | pass 392 | 393 | def on_seek(self, time_offset): 394 | pass 395 | 396 | cdef class Music(SoundStream): 397 | cdef sf.Music *p_this 398 | 399 | def __init__(self, *args, **kwargs): 400 | raise UserWarning("Use specific constructor") 401 | 402 | def __dealloc__(self): 403 | self.p_soundstream = NULL 404 | 405 | if self.p_this is not NULL: 406 | del self.p_this 407 | 408 | def __repr__(self): 409 | return "Music(buffer={0}, status={1}, playing_offset={2})".format(id(self.buffer), self.status, self.playing_offset) 410 | 411 | @classmethod 412 | def from_file(cls, basestring filename): 413 | cdef sf.Music *p = new sf.Music() 414 | 415 | if p.openFromFile(filename.encode('UTF-8')): 416 | return wrap_music(p) 417 | 418 | del p 419 | raise IOError(popLastErrorMessage()) 420 | 421 | @classmethod 422 | def from_memory(cls, bytes data): 423 | cdef sf.Music *p = new sf.Music() 424 | 425 | if p.openFromMemory(data, len(data)): 426 | return wrap_music(p) 427 | 428 | del p 429 | raise IOError(popLastErrorMessage()) 430 | 431 | property duration: 432 | def __get__(self): 433 | cdef sf.Time* p = new sf.Time() 434 | p[0] = self.p_this.getDuration() 435 | return wrap_time(p) 436 | 437 | 438 | cdef Music wrap_music(sf.Music *p): 439 | cdef Music r = Music.__new__(Music) 440 | r.p_this = p 441 | r.p_soundstream = p 442 | r.p_soundsource = p 443 | return r 444 | 445 | 446 | cdef class SoundRecorder: 447 | cdef sf.SoundRecorder *p_soundrecorder 448 | 449 | def __init__(self, *args, **kwargs): 450 | if self.__class__ == SoundRecorder: 451 | raise NotImplementedError("SoundRecorder is abstract") 452 | 453 | if self.p_soundrecorder is NULL: 454 | self.p_soundrecorder = new DerivableSoundRecorder(self) 455 | 456 | def __dealloc__(self): 457 | if self.p_soundrecorder is not NULL: 458 | del self.p_soundrecorder 459 | 460 | def __repr__(self): 461 | return "SoundRecorder(sample_rate={0})".format(self.sample_rate) 462 | 463 | def start(self, unsigned int sample_rate=44100): 464 | return self.p_soundrecorder.start(sample_rate) 465 | 466 | def stop(self): 467 | with nogil: self.p_soundrecorder.stop() 468 | 469 | def set_device(self, name): 470 | return self.p_soundrecorder.setDevice(name) 471 | 472 | def get_device(self): 473 | return self.p_soundrecorder.getDevice() 474 | 475 | property sample_rate: 476 | def __get__(self): 477 | return self.p_soundrecorder.getSampleRate() 478 | 479 | @staticmethod 480 | def is_available(): 481 | return sf.soundrecorder.isAvailable() 482 | 483 | @staticmethod 484 | def get_available_devices(): 485 | return sf.soundrecorder.getAvailableDevices() 486 | 487 | @staticmethod 488 | def get_default_device(): 489 | return sf.soundrecorder.getDefaultDevice() 490 | 491 | def on_start(self): 492 | return True 493 | 494 | def on_process_samples(self, chunk): 495 | return True 496 | 497 | def on_stop(self): 498 | pass 499 | 500 | cdef class SoundBufferRecorder(SoundRecorder): 501 | cdef sf.SoundBufferRecorder *p_this 502 | cdef SoundBuffer m_buffer 503 | 504 | def __init__(self): 505 | if self.p_this is NULL: 506 | self.p_this = new sf.SoundBufferRecorder() 507 | self.p_soundrecorder = self.p_this 508 | 509 | self.m_buffer = wrap_soundbuffer(&self.p_this.getBuffer(), False) 510 | 511 | def __dealloc__(self): 512 | self.p_soundrecorder = NULL 513 | 514 | if self.p_this is not NULL: 515 | del self.p_this 516 | 517 | def __repr__(self): 518 | return "SoundBufferRecorder(buffer={0}, sample_rate={1})".format(id(self.buffer), self.sample_rate) 519 | 520 | property buffer: 521 | def __get__(self): 522 | return self.m_buffer 523 | -------------------------------------------------------------------------------- /src/sfml/graphics/DerivableDrawable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | const sf::Uint8* getPixelsPtr(PyObject* memoryview) 15 | { 16 | Py_buffer* buffer = PyMemoryView_GET_BUFFER(memoryview); 17 | return static_cast(buffer->buf); 18 | } 19 | 20 | DerivableDrawable::DerivableDrawable(PyObject* object) : 21 | m_object(object) 22 | { 23 | import_sfml__graphics(); 24 | }; 25 | 26 | void DerivableDrawable::draw(sf::RenderTarget& target_, sf::RenderStates states_) const 27 | { 28 | static char format[] = "(O, O)"; 29 | static char methodName[] = "draw"; 30 | 31 | PyObject* target = (PyObject*)(wrap_rendertarget(&target_)); 32 | PyObject* states = (PyObject*)(wrap_renderstates(&states_, false)); 33 | 34 | PyObject* success = PyObject_CallMethod(m_object, methodName, format, target, states); 35 | 36 | if(!success) 37 | PyErr_Print(); 38 | 39 | Py_DECREF(target); 40 | Py_DECREF(states); 41 | } 42 | -------------------------------------------------------------------------------- /src/sfml/graphics/DerivableDrawable.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #ifndef PYSFML_GRAPHICS_DERIVABLEDRAWABLE_HPP 10 | #define PYSFML_GRAPHICS_DERIVABLEDRAWABLE_HPP 11 | 12 | #include "Python.h" 13 | #include 14 | 15 | 16 | const sf::Uint8* getPixelsPtr(PyObject* memoryview); 17 | 18 | class DerivableDrawable : public sf::Drawable 19 | { 20 | public: 21 | DerivableDrawable(PyObject* object); 22 | 23 | private: 24 | virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; 25 | 26 | PyObject* m_object; 27 | }; 28 | 29 | #endif // PYSFML_GRAPHICS_DERIVABLEDRAWABLE_HPP 30 | -------------------------------------------------------------------------------- /src/sfml/graphics/DerivableRenderWindow.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #include 10 | 11 | DerivableRenderWindow::DerivableRenderWindow(PyObject* object) : 12 | m_object(object) 13 | { 14 | } 15 | 16 | void DerivableRenderWindow::createWindow() 17 | { 18 | sf::RenderWindow::onCreate(); 19 | } 20 | 21 | void DerivableRenderWindow::resizeWindow() 22 | { 23 | sf::RenderWindow::onResize(); 24 | } 25 | 26 | void DerivableRenderWindow::onCreate() 27 | { 28 | static char method[] = "on_create"; 29 | PyObject* success = PyObject_CallMethod(m_object, method, NULL); 30 | 31 | if(!success) 32 | PyErr_Print(); 33 | } 34 | 35 | void DerivableRenderWindow::onResize() 36 | { 37 | static char method[] = "on_resize"; 38 | PyObject* success = PyObject_CallMethod(m_object, method, NULL); 39 | 40 | if(!success) 41 | PyErr_Print(); 42 | } 43 | -------------------------------------------------------------------------------- /src/sfml/graphics/DerivableRenderWindow.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #ifndef PYSFML_GRAPHICS_DERIVABLERENDERWINDOW_HPP 10 | #define PYSFML_GRAPHICS_DERIVABLERENDERWINDOW_HPP 11 | 12 | #include "Python.h" 13 | #include 14 | 15 | class DerivableRenderWindow : public sf::RenderWindow 16 | { 17 | public: 18 | DerivableRenderWindow(PyObject* object); 19 | 20 | void createWindow(); 21 | void resizeWindow(); 22 | 23 | protected: 24 | virtual void onCreate(); 25 | virtual void onResize(); 26 | 27 | private: 28 | PyObject* m_object; 29 | }; 30 | 31 | #endif // PYSFML_GRAPHICS_DERIVABLERENDERWINDOW_HPP 32 | -------------------------------------------------------------------------------- /src/sfml/graphics/NumericObject.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #include 10 | 11 | NumericObject::NumericObject() 12 | : m_object(NULL) 13 | { 14 | } 15 | 16 | NumericObject::NumericObject(const NumericObject& copy) 17 | { 18 | m_object = copy.m_object; 19 | Py_INCREF(m_object); 20 | } 21 | 22 | NumericObject::NumericObject(PyObject* object) 23 | : m_object(object) 24 | { 25 | Py_XINCREF(m_object); 26 | } 27 | 28 | NumericObject::~NumericObject() 29 | { 30 | Py_XDECREF(m_object); 31 | } 32 | 33 | PyObject* NumericObject::get() 34 | { 35 | Py_XINCREF(m_object); 36 | return m_object; 37 | } 38 | 39 | void NumericObject::set(PyObject* object) 40 | { 41 | if (m_object) 42 | Py_DECREF(m_object); 43 | 44 | m_object = object; 45 | Py_INCREF(m_object); 46 | } 47 | 48 | NumericObject NumericObject::operator+() const 49 | { 50 | return PyNumber_Positive(const_cast(m_object)); 51 | } 52 | 53 | NumericObject NumericObject::operator-() const 54 | { 55 | return PyNumber_Negative(const_cast(m_object)); 56 | } 57 | 58 | NumericObject NumericObject::operator+(const NumericObject& object) const 59 | { 60 | return PyNumber_Add(m_object, object.m_object); 61 | } 62 | 63 | NumericObject NumericObject::operator-(const NumericObject& object) const 64 | { 65 | return PyNumber_Subtract(m_object, object.m_object); 66 | } 67 | 68 | NumericObject NumericObject::operator*(const NumericObject& object) const 69 | { 70 | return PyNumber_Multiply(m_object, object.m_object); 71 | } 72 | 73 | NumericObject NumericObject::operator/(const NumericObject& object) const 74 | { 75 | return PyNumber_TrueDivide(m_object, object.m_object); 76 | } 77 | 78 | NumericObject NumericObject::operator~() const 79 | { 80 | return PyNumber_Invert(const_cast(m_object)); 81 | } 82 | 83 | NumericObject NumericObject::operator&(const NumericObject& object) const 84 | { 85 | return PyNumber_And(m_object, object.m_object); 86 | } 87 | 88 | NumericObject NumericObject::operator|(const NumericObject& object) const 89 | { 90 | return PyNumber_Or(m_object, object.m_object); 91 | } 92 | 93 | NumericObject NumericObject::operator^(const NumericObject& object) const 94 | { 95 | return PyNumber_Xor(m_object, object.m_object); 96 | } 97 | 98 | NumericObject& NumericObject::operator+=(const NumericObject& b) 99 | { 100 | m_object = PyNumber_InPlaceAdd(m_object, b.m_object); 101 | return *this; 102 | } 103 | 104 | NumericObject& NumericObject::operator-=(const NumericObject& b) 105 | { 106 | m_object = PyNumber_InPlaceSubtract(m_object, b.m_object); 107 | return *this; 108 | } 109 | 110 | NumericObject& NumericObject::operator*=(const NumericObject& b) 111 | { 112 | m_object = PyNumber_InPlaceMultiply(m_object, b.m_object); 113 | return *this; 114 | } 115 | 116 | NumericObject& NumericObject::operator/=(const NumericObject& b) 117 | { 118 | m_object = PyNumber_InPlaceTrueDivide(m_object, b.m_object); 119 | return *this; 120 | } 121 | 122 | NumericObject& NumericObject::operator&=(const NumericObject& b) 123 | { 124 | m_object = PyNumber_InPlaceAnd(m_object, b.m_object); 125 | return *this; 126 | } 127 | 128 | NumericObject& NumericObject::operator|=(const NumericObject& b) 129 | { 130 | m_object = PyNumber_InPlaceOr(m_object, b.m_object); 131 | return *this; 132 | } 133 | 134 | NumericObject& NumericObject::operator^=(const NumericObject& b) 135 | { 136 | m_object = PyNumber_InPlaceXor(m_object, b.m_object); 137 | return *this; 138 | } 139 | 140 | bool NumericObject::operator==(const NumericObject &b) const 141 | { 142 | return PyObject_RichCompareBool(m_object, b.m_object, Py_EQ); 143 | } 144 | 145 | bool NumericObject::operator!=(const NumericObject &b) const 146 | { 147 | return PyObject_RichCompareBool(m_object, b.m_object, Py_NE); 148 | } 149 | 150 | bool NumericObject::operator<(const NumericObject &b) const 151 | { 152 | return PyObject_RichCompareBool(m_object, b.m_object, Py_LT); 153 | } 154 | 155 | bool NumericObject::operator>(const NumericObject &b) const 156 | { 157 | return PyObject_RichCompareBool(m_object, b.m_object, Py_GT); 158 | } 159 | 160 | bool NumericObject::operator<=(const NumericObject &b) const 161 | { 162 | return PyObject_RichCompareBool(m_object, b.m_object, Py_LE); 163 | } 164 | 165 | bool NumericObject::operator>=(const NumericObject &b) const 166 | { 167 | return PyObject_RichCompareBool(m_object, b.m_object, Py_GE); 168 | } 169 | -------------------------------------------------------------------------------- /src/sfml/graphics/NumericObject.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #ifndef PYSFML_GRAPHICS_NUMERICOBJECT_HPP 10 | #define PYSFML_GRAPHICS_NUMERICOBJECT_HPP 11 | 12 | #include "Python.h" 13 | #include 14 | 15 | class SFML_API_EXPORT NumericObject 16 | { 17 | public: 18 | NumericObject(); 19 | NumericObject(const NumericObject& copy); 20 | NumericObject(PyObject* object); 21 | 22 | ~NumericObject(); 23 | 24 | PyObject* get(); 25 | void set(PyObject* object); 26 | 27 | NumericObject operator+() const; 28 | NumericObject operator-() const; 29 | NumericObject operator+(const NumericObject& object) const; 30 | NumericObject operator-(const NumericObject& object) const; 31 | NumericObject operator*(const NumericObject& object) const; 32 | NumericObject operator/(const NumericObject& object) const; 33 | NumericObject operator~() const; 34 | NumericObject operator&(const NumericObject& object) const; 35 | NumericObject operator|(const NumericObject& object) const; 36 | NumericObject operator^(const NumericObject& object) const; 37 | 38 | NumericObject& operator+=(const NumericObject& b); 39 | NumericObject& operator-=(const NumericObject& b); 40 | NumericObject& operator*=(const NumericObject& b); 41 | NumericObject& operator/=(const NumericObject& b); 42 | NumericObject& operator&=(const NumericObject& b); 43 | NumericObject& operator|=(const NumericObject& b); 44 | NumericObject& operator^=(const NumericObject& b); 45 | 46 | bool operator==(const NumericObject &b) const; 47 | bool operator!=(const NumericObject &b) const; 48 | bool operator<(const NumericObject &b) const; 49 | bool operator>(const NumericObject &b) const; 50 | bool operator<=(const NumericObject &b) const; 51 | bool operator>=(const NumericObject &b) const; 52 | 53 | private: 54 | PyObject* m_object; 55 | }; 56 | 57 | #endif // PYSFML_GRAPHICS_NUMERICOBJECT_HPP 58 | -------------------------------------------------------------------------------- /src/sfml/network/network.pyx: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | #cdef extern from "pysfml/NumericObject.hpp": 8 | # pass 9 | 10 | from cython.operator cimport dereference as deref 11 | from cython.operator cimport preincrement as inc 12 | 13 | from libc.stdlib cimport * 14 | from libcpp.string cimport string 15 | from libcpp.vector cimport vector 16 | 17 | cimport sfml as sf 18 | from sfml cimport Int8, Int16, Int32, Int64 19 | from sfml cimport Uint8, Uint16, Uint32, Uint64 20 | from pysfml.system cimport Time 21 | 22 | cdef class IpAddress: 23 | cdef sf.IpAddress *p_this 24 | 25 | NONE = wrap_ipaddress(&sf.ipaddress.None) 26 | LOCAL_HOST = wrap_ipaddress(&sf.ipaddress.LocalHost) 27 | BROADCAST = wrap_ipaddress(&sf.ipaddress.Broadcast) 28 | 29 | def __init__(self): 30 | self.p_this = new sf.IpAddress() 31 | 32 | def __dealloc__(self): 33 | del self.p_this 34 | 35 | def __repr__(self): 36 | return "IpAddress(integer={0})".format(self.integer) 37 | 38 | def __str__(self): 39 | return self.string.decode('utf-8') 40 | 41 | def __richcmp__(IpAddress x, IpAddress y, int op): 42 | if op == 0: 43 | return x.p_this[0] < y.p_this[0] 44 | elif op == 2: 45 | return x.p_this[0] == y.p_this[0] 46 | elif op == 4: 47 | return x.p_this[0] > y.p_this[0] 48 | elif op == 1: 49 | return x.p_this[0] <= y.p_this[0] 50 | elif op == 3: 51 | return x.p_this[0] != y.p_this[0] 52 | elif op == 5: 53 | return x.p_this[0] >= y.p_this[0] 54 | 55 | @classmethod 56 | def from_string(self, _string): 57 | cdef string encoded_string 58 | encoded_string_temporary = _string.encode('UTF-8') 59 | encoded_string = string(encoded_string_temporary) 60 | 61 | cdef sf.IpAddress *p = new sf.IpAddress(encoded_string) 62 | return wrap_ipaddress(p) 63 | 64 | @classmethod 65 | def from_integer(self, Uint32 address): 66 | cdef sf.IpAddress *p = new sf.IpAddress(address) 67 | return wrap_ipaddress(p) 68 | 69 | @classmethod 70 | def from_bytes(self, Uint8 b1, Uint8 b2, Uint8 b3, Uint8 b4): 71 | cdef sf.IpAddress *p = new sf.IpAddress(b1, b2, b3, b4) 72 | return wrap_ipaddress(p) 73 | 74 | property string: 75 | def __get__(self): 76 | return self.p_this.toString().c_str() 77 | 78 | property integer: 79 | def __get__(self): 80 | return self.p_this.toInteger() 81 | 82 | @classmethod 83 | def get_local_address(self): 84 | cdef sf.IpAddress* p = new sf.IpAddress() 85 | p[0] = sf.ipaddress.getLocalAddress() 86 | return wrap_ipaddress(p) 87 | 88 | @classmethod 89 | def get_public_address(self, Time timeout=None): 90 | cdef sf.IpAddress* p = new sf.IpAddress() 91 | 92 | if not timeout: 93 | p[0] = sf.ipaddress.getPublicAddress() 94 | else: 95 | p[0] = sf.ipaddress.getPublicAddress(timeout.p_this[0]) 96 | 97 | return wrap_ipaddress(p) 98 | 99 | cdef wrap_ipaddress(sf.IpAddress* p): 100 | cdef IpAddress r = IpAddress.__new__(IpAddress) 101 | r.p_this = p 102 | return r 103 | 104 | cdef class Socket: 105 | DONE = sf.socket.Done 106 | NOT_READY = sf.socket.NotReady 107 | DISCONNECTED = sf.socket.Disconnected 108 | ERROR = sf.socket.Error 109 | 110 | ANY_PORT = sf.socket.AnyPort 111 | 112 | cdef sf.Socket *p_socket 113 | 114 | def __init__(self): 115 | if self.__class__ == Socket: 116 | raise NotImplementedError('Socket is abstact') 117 | 118 | property blocking: 119 | def __get__(self): 120 | return self.p_socket.isBlocking() 121 | 122 | def __set__(self, bint blocking): 123 | self.p_socket.setBlocking(blocking) 124 | 125 | 126 | class SocketException(Exception): pass 127 | class SocketNotReady(SocketException): pass 128 | class SocketDisconnected(SocketException): pass 129 | class SocketError(SocketException): pass 130 | 131 | 132 | cdef class TcpListener(Socket): 133 | cdef sf.TcpListener *p_this 134 | 135 | def __init__(self): 136 | self.p_this = new sf.TcpListener() 137 | self.p_socket = self.p_this 138 | 139 | def __dealloc__(self): 140 | del self.p_this 141 | 142 | def __repr__(self): 143 | return "TcpListener(blocking={0}, local_port={1})".format(self.blocking, self.local_port) 144 | 145 | property local_port: 146 | def __get__(self): 147 | return self.p_this.getLocalPort() 148 | 149 | def listen(self, unsigned short port): 150 | cdef sf.socket.Status status = self.p_this.listen(port) 151 | 152 | if status is not sf.socket.Done: 153 | if status is sf.socket.NotReady: 154 | raise SocketNotReady() 155 | elif status is sf.socket.Disconnected: 156 | raise SocketDisconnected() 157 | elif status is sf.socket.Error: 158 | raise SocketError() 159 | 160 | def close(self): 161 | self.p_this.close() 162 | 163 | def accept(self): 164 | cdef TcpSocket socket = TcpSocket() 165 | cdef sf.socket.Status status 166 | 167 | with nogil: 168 | status = self.p_this.accept(socket.p_this[0]) 169 | 170 | if status is not sf.socket.Done: 171 | if status is sf.socket.NotReady: 172 | raise SocketNotReady() 173 | elif status is sf.socket.Disconnected: 174 | raise SocketDisconnected() 175 | elif status is sf.socket.Error: 176 | raise SocketError() 177 | 178 | return socket 179 | 180 | 181 | cdef class TcpSocket(Socket): 182 | cdef sf.TcpSocket *p_this 183 | 184 | def __init__(self): 185 | self.p_this = new sf.TcpSocket() 186 | self.p_socket = self.p_this 187 | 188 | def __dealloc__(self): 189 | del self.p_this 190 | 191 | def __repr__(self): 192 | return "TcpSocket(blocking={0}, local_port={1}, remote_address={2}, remote_port={3})".format(self.blocking, self.local_port, self.remote_address, self.remote_port) 193 | 194 | property local_port: 195 | def __get__(self): 196 | return self.p_this.getLocalPort() 197 | 198 | property remote_address: 199 | def __get__(self): 200 | cdef sf.IpAddress *p = new sf.IpAddress() 201 | p[0] = self.p_this.getRemoteAddress() 202 | return wrap_ipaddress(p) 203 | 204 | property remote_port: 205 | def __get__(self): 206 | return self.p_this.getRemotePort() 207 | 208 | def connect(self, IpAddress remote_address, unsigned short remote_port, Time timeout=None): 209 | cdef sf.socket.Status status 210 | 211 | if not timeout: 212 | with nogil: 213 | status = self.p_this.connect(remote_address.p_this[0], remote_port) 214 | else: 215 | with nogil: 216 | status = self.p_this.connect(remote_address.p_this[0], remote_port, timeout.p_this[0]) 217 | 218 | if status is not sf.socket.Done: 219 | if status is sf.socket.NotReady: 220 | raise SocketNotReady() 221 | elif status is sf.socket.Disconnected: 222 | raise SocketDisconnected() 223 | elif status is sf.socket.Error: 224 | raise SocketError() 225 | 226 | def disconnect(self): 227 | self.p_this.disconnect() 228 | 229 | def send(self, bytes data): 230 | cdef sf.socket.Status status 231 | cdef char* cdata = data 232 | cdef size_t cdata_len = len(data) 233 | 234 | with nogil: 235 | status = self.p_this.send(cdata, cdata_len) 236 | 237 | if status is not sf.socket.Done: 238 | if status is sf.socket.NotReady: 239 | raise SocketNotReady() 240 | elif status is sf.socket.Disconnected: 241 | raise SocketDisconnected() 242 | elif status is sf.socket.Error: 243 | raise SocketError() 244 | 245 | def receive(self, size_t size): 246 | cdef char* data = malloc(size * sizeof(char)) 247 | cdef size_t received = 0 248 | cdef sf.socket.Status status 249 | 250 | with nogil: 251 | status = self.p_this.receive(data, size, received) 252 | 253 | if status is not sf.socket.Done: 254 | if status is sf.socket.NotReady: 255 | raise SocketNotReady() 256 | elif status is sf.socket.Disconnected: 257 | raise SocketDisconnected() 258 | elif status is sf.socket.Error: 259 | raise SocketError() 260 | 261 | return (data)[:received] 262 | 263 | 264 | cdef class UdpSocket(Socket): 265 | cdef sf.UdpSocket *p_this 266 | 267 | MAX_DATAGRAM_SIZE = sf.udpsocket.MaxDatagramSize 268 | 269 | def __init__(self): 270 | self.p_this = new sf.UdpSocket() 271 | self.p_socket = self.p_this 272 | 273 | def __dealloc__(self): 274 | del self.p_this 275 | 276 | def __repr__(self): 277 | return "UdpSocket(blocking={0}, local_port={1})".format(self.blocking, self.local_port) 278 | 279 | property local_port: 280 | def __get__(self): 281 | return self.p_this.getLocalPort() 282 | 283 | def bind(self, unsigned short port): 284 | cdef sf.socket.Status status = self.p_this.bind(port) 285 | 286 | if status is not sf.socket.Done: 287 | if status is sf.socket.NotReady: 288 | raise SocketNotReady() 289 | elif status is sf.socket.Disconnected: 290 | raise SocketDisconnected() 291 | elif status is sf.socket.Error: 292 | raise SocketError() 293 | 294 | def unbind(self): 295 | self.p_this.unbind() 296 | 297 | def send(self, bytes data, IpAddress remote_address, unsigned short remote_port): 298 | cdef sf.socket.Status status = self.p_this.send(data, len(data), remote_address.p_this[0], remote_port) 299 | 300 | if status is not sf.socket.Done: 301 | if status is sf.socket.NotReady: 302 | raise SocketNotReady() 303 | elif status is sf.socket.Disconnected: 304 | raise SocketDisconnected() 305 | elif status is sf.socket.Error: 306 | raise SocketError() 307 | 308 | def receive(self, size_t size): 309 | cdef char* data = malloc(size * sizeof(char)) 310 | cdef size_t received = 0 311 | cdef IpAddress remote_address = IpAddress() 312 | cdef unsigned short port = 0 313 | cdef sf.socket.Status status = self.p_this.receive(data, size, received, remote_address.p_this[0], port) 314 | 315 | if status is not sf.socket.Done: 316 | if status is sf.socket.NotReady: 317 | raise SocketNotReady() 318 | elif status is sf.socket.Disconnected: 319 | raise SocketDisconnected() 320 | elif status is sf.socket.Error: 321 | raise SocketError() 322 | 323 | return ((data)[:received], remote_address, port) 324 | 325 | 326 | cdef class SocketSelector: 327 | cdef sf.SocketSelector *p_this 328 | 329 | def __init__(self): 330 | self.p_this = new sf.SocketSelector() 331 | 332 | def __dealloc__(self): 333 | del self.p_this 334 | 335 | def __repr__(self): 336 | return "SocketSelector()" 337 | 338 | def add(self, Socket socket): 339 | self.p_this.add(socket.p_socket[0]) 340 | 341 | def remove(self, Socket socket): 342 | self.p_this.remove(socket.p_socket[0]) 343 | 344 | def clear(self): 345 | self.p_this.clear() 346 | 347 | def wait(self, Time timeout=None): 348 | cdef bint ret 349 | 350 | if not timeout: 351 | with nogil: 352 | ret = self.p_this.wait() 353 | else: 354 | with nogil: 355 | ret = self.p_this.wait(timeout.p_this[0]) 356 | 357 | return ret 358 | 359 | def is_ready(self, Socket socket): 360 | return self.p_this.isReady(socket.p_socket[0]) 361 | 362 | 363 | cdef class FtpResponse: 364 | RESTART_MARKER_REPLY = sf.ftp.response.RestartMarkerReply 365 | SERVICE_READY_SOON = sf.ftp.response.ServiceReadySoon 366 | DATA_CONNECTION_ALREADY_OPENED = sf.ftp.response.DataConnectionAlreadyOpened 367 | OPENING_DATA_CONNECTION = sf.ftp.response.OpeningDataConnection 368 | OK = sf.ftp.response.Ok 369 | POINTLESS_COMMAND = sf.ftp.response.PointlessCommand 370 | SYSTEM_STATUS = sf.ftp.response.SystemStatus 371 | DIRECTORY_STATUS = sf.ftp.response.DirectoryStatus 372 | FILE_STATUS = sf.ftp.response.FileStatus 373 | HELP_MESSAGE = sf.ftp.response.HelpMessage 374 | SYSTEM_TYPE = sf.ftp.response.SystemType 375 | SERVICE_READY = sf.ftp.response.ServiceReady 376 | CLOSING_CONNECTION = sf.ftp.response.ClosingConnection 377 | DATA_CONNECTION_OPENED = sf.ftp.response.DataConnectionOpened 378 | CLOSING_DATA_CONNECTION = sf.ftp.response.ClosingDataConnection 379 | ENTERING_PASSIVE_MODE = sf.ftp.response.EnteringPassiveMode 380 | LOGGED_IN = sf.ftp.response.LoggedIn 381 | FILE_ACTION_OK = sf.ftp.response.FileActionOk 382 | DIRECTORY_OK = sf.ftp.response.DirectoryOk 383 | NEED_PASSWORD = sf.ftp.response.NeedPassword 384 | NEED_ACCOUNT_TO_LOG_IN = sf.ftp.response.NeedAccountToLogIn 385 | NEED_INFORMATION = sf.ftp.response.NeedInformation 386 | SERVICE_UNAVAILABLE = sf.ftp.response.ServiceUnavailable 387 | DATA_CONNECTION_UNAVAILABLE = sf.ftp.response.DataConnectionUnavailable 388 | TRANSFER_ABORTED = sf.ftp.response.TransferAborted 389 | FILE_ACTION_ABORTED = sf.ftp.response.FileActionAborted 390 | LOCAL_ERROR = sf.ftp.response.LocalError 391 | INSUFFICIENT_STORAGE_SPACE = sf.ftp.response.InsufficientStorageSpace 392 | COMMAND_UNKNOWN = sf.ftp.response.CommandUnknown 393 | PARAMETERS_UNKNOWN = sf.ftp.response.ParametersUnknown 394 | COMMAND_NOT_IMPLEMENTED = sf.ftp.response.CommandNotImplemented 395 | BAD_COMMAND_SEQUENCE = sf.ftp.response.BadCommandSequence 396 | PARAMETER_NOT_IMPLEMENTED = sf.ftp.response.ParameterNotImplemented 397 | NOT_LOGGED_IN = sf.ftp.response.NotLoggedIn 398 | NEED_ACCOUNT_TO_STORE = sf.ftp.response.NeedAccountToStore 399 | FILE_UNAVAILABLE = sf.ftp.response.FileUnavailable 400 | PAGE_TYPE_UNKNOWN = sf.ftp.response.PageTypeUnknown 401 | NOT_ENOUGH_MEMORY = sf.ftp.response.NotEnoughMemory 402 | FILENAME_NOT_ALLOWED = sf.ftp.response.FilenameNotAllowed 403 | INVALID_RESPONSE = sf.ftp.response.InvalidResponse 404 | CONNECTION_FAILED = sf.ftp.response.ConnectionFailed 405 | CONNECTION_CLOSED = sf.ftp.response.ConnectionClosed 406 | INVALID_FILE = sf.ftp.response.InvalidFile 407 | 408 | cdef sf.ftp.Response *p_response 409 | 410 | def __repr__(self): 411 | return "FtpResponse(ok={0}, status={1}, message={2})".format(self.ok, self.status, self.message) 412 | 413 | property ok: 414 | def __get__(self): 415 | return self.p_response.isOk() 416 | 417 | property status: 418 | def __get__(self): 419 | return self.p_response.getStatus() 420 | 421 | property message: 422 | def __get__(self): 423 | return self.p_response.getMessage().c_str() 424 | 425 | cdef class FtpDirectoryResponse(FtpResponse): 426 | cdef sf.ftp.DirectoryResponse *p_this 427 | 428 | def __init__(self): 429 | raise NotImplementedError("Not meant to be instantiated") 430 | 431 | def __dealloc__(self): 432 | del self.p_this 433 | 434 | def __repr__(self): 435 | return "FtpDirectoryResponse(ok={0}, status={1}, message={2})".format(self.ok, self.status, self.message) 436 | 437 | def get_directory(self): 438 | return self.p_this.getDirectory().c_str() 439 | 440 | 441 | cdef class FtpListingResponse(FtpResponse): 442 | cdef sf.ftp.ListingResponse *p_this 443 | 444 | def __init__(self): 445 | raise NotImplementedError("Not meant to be instantiated") 446 | 447 | def __dealloc__(self): 448 | del self.p_this 449 | 450 | def __repr__(self): 451 | return "FtpListingResponse(ok={0}, status={1}, message={2})".format(self.ok, self.status, self.message) 452 | 453 | property filenames: 454 | def __get__(self): 455 | cdef list r = [] 456 | cdef vector[string]* filenames = &self.p_this.getListing() 457 | cdef vector[string].iterator filename = filenames.begin() 458 | cdef string temp 459 | while filename != filenames.end(): 460 | temp = deref(filename) 461 | r.append(temp.c_str()) 462 | inc(filename) 463 | 464 | return tuple(r) 465 | 466 | cdef wrap_ftpresponse(sf.ftp.Response* p): 467 | cdef FtpResponse r = FtpResponse.__new__(FtpResponse) 468 | r.p_response = p 469 | return r 470 | 471 | 472 | cdef wrap_ftpdirectoryresponse(sf.ftp.DirectoryResponse* p): 473 | cdef FtpDirectoryResponse r = FtpDirectoryResponse.__new__(FtpDirectoryResponse) 474 | r.p_this = p 475 | r.p_response = p 476 | return r 477 | 478 | 479 | cdef wrap_ftplistingresponse(sf.ftp.ListingResponse* p): 480 | cdef FtpListingResponse r = FtpListingResponse.__new__(FtpListingResponse) 481 | r.p_this = p 482 | r.p_response = p 483 | return r 484 | 485 | cdef class Ftp: 486 | BINARY = sf.ftp.Binary 487 | ASCII = sf.ftp.Ascii 488 | EBCDIC = sf.ftp.Ebcdic 489 | 490 | cdef sf.Ftp *p_this 491 | 492 | def __init__(self): 493 | self.p_this = new sf.Ftp() 494 | 495 | def __dealloc__(self): 496 | del self.p_this 497 | 498 | def __repr__(self): 499 | return "Ftp()" 500 | 501 | def connect(self, IpAddress server, unsigned short port=21, Time timeout=None): 502 | cdef sf.ftp.Response* response = new sf.ftp.Response() 503 | 504 | if not timeout: 505 | with nogil: response[0] = self.p_this.connect(server.p_this[0], port) 506 | else: 507 | with nogil: response[0] = self.p_this.connect(server.p_this[0], port, timeout.p_this[0]) 508 | 509 | return wrap_ftpresponse(response) 510 | 511 | def disconnect(self): 512 | cdef sf.ftp.Response* response = new sf.ftp.Response() 513 | response[0] = self.p_this.disconnect() 514 | return wrap_ftpresponse(response) 515 | 516 | def login(self, str name=None, str message=""): 517 | cdef sf.ftp.Response* response = new sf.ftp.Response() 518 | 519 | encoded_name_temporary = name.encode('UTF-8') 520 | encoded_message_temporary = message.encode('UTF-8') 521 | cdef char* encoded_name = encoded_name_temporary 522 | cdef char* encoded_message = encoded_message_temporary 523 | 524 | if not name: 525 | with nogil: response[0] = self.p_this.login() 526 | else: 527 | with nogil: response[0] = self.p_this.login(encoded_name, encoded_message) 528 | 529 | return wrap_ftpresponse(response) 530 | 531 | def keep_alive(self): 532 | cdef sf.ftp.Response* response = new sf.ftp.Response() 533 | 534 | with nogil: 535 | response[0] = self.p_this.keepAlive() 536 | 537 | return wrap_ftpresponse(response) 538 | 539 | def get_working_directory(self): 540 | # here Ftp::DirectoryResponse's constructors prevent us from 541 | # creating an empty object. We must cheat by passing an empty 542 | # Ftp::Reponse that we must destruct when the DirectoryResponse 543 | # is destroyed. 544 | cdef sf.ftp.Response* response = new sf.ftp.Response() 545 | cdef sf.ftp.DirectoryResponse* directory_response = new sf.ftp.DirectoryResponse(response[0]) 546 | del response 547 | 548 | with nogil: 549 | directory_response[0] = self.p_this.getWorkingDirectory() 550 | 551 | return wrap_ftpdirectoryresponse(directory_response) 552 | 553 | def get_directory_listing(self, str directory=""): 554 | # here Ftp::ListingResponse's constructors prevent us from 555 | # creating an empty object. We must cheat by passing an empty 556 | # Ftp::Reponse and a false vector of char*. We must destruct 557 | # what we had allocated to cheat on when the ListingResponse 558 | # is destroyed. 559 | cdef sf.ftp.Response* response = new sf.ftp.Response() 560 | cdef sf.ftp.ListingResponse* listing_response = new sf.ftp.ListingResponse(response[0], "") 561 | del response 562 | 563 | encoded_directory_temporary = directory.encode('UTF-8') 564 | cdef char* encoded_directory = encoded_directory_temporary 565 | 566 | with nogil: 567 | listing_response[0] = self.p_this.getDirectoryListing(encoded_directory) 568 | 569 | return wrap_ftplistingresponse(listing_response) 570 | 571 | def change_directory(self, str directory): 572 | cdef sf.ftp.Response* response = new sf.ftp.Response() 573 | 574 | encoded_directory_temporary = directory.encode('UTF-8') 575 | cdef char* encoded_directory = encoded_directory_temporary 576 | 577 | with nogil: 578 | response[0] = self.p_this.changeDirectory(encoded_directory) 579 | 580 | return wrap_ftpresponse(response) 581 | 582 | def parent_directory(self): 583 | cdef sf.ftp.Response* response = new sf.ftp.Response() 584 | 585 | with nogil: 586 | response[0] = self.p_this.parentDirectory() 587 | 588 | return wrap_ftpresponse(response) 589 | 590 | def create_directory(self, str name): 591 | cdef sf.ftp.Response* response = new sf.ftp.Response() 592 | 593 | encoded_name_temporary = name.encode('UTF-8') 594 | cdef char* encoded_name = encoded_name_temporary 595 | 596 | with nogil: 597 | response[0] = self.p_this.createDirectory(encoded_name) 598 | 599 | return wrap_ftpresponse(response) 600 | 601 | def delete_directory(self, str name): 602 | cdef sf.ftp.Response* response = new sf.ftp.Response() 603 | 604 | encoded_name_temporary = name.encode('UTF-8') 605 | cdef char* encoded_name = encoded_name_temporary 606 | 607 | with nogil: 608 | response[0] = self.p_this.deleteDirectory(encoded_name) 609 | 610 | return wrap_ftpresponse(response) 611 | 612 | def rename_file(self, str filename, str newname): 613 | cdef sf.ftp.Response* response = new sf.ftp.Response() 614 | 615 | encoded_filename_temporary = filename.encode('UTF-8') 616 | encoded_newname_temporary = newname.encode('UTF-8') 617 | cdef char* encoded_filename = encoded_filename_temporary 618 | cdef char* encoded_newname = encoded_newname_temporary 619 | 620 | with nogil: 621 | response[0] = self.p_this.renameFile(encoded_filename, encoded_newname) 622 | 623 | return wrap_ftpresponse(response) 624 | 625 | def delete_file(self, str name): 626 | cdef sf.ftp.Response* response = new sf.ftp.Response() 627 | 628 | encoded_name_temporary = name.encode('UTF-8') 629 | cdef char* encoded_name = encoded_name_temporary 630 | 631 | with nogil: 632 | response[0] = self.p_this.deleteFile(encoded_name) 633 | 634 | return wrap_ftpresponse(response) 635 | 636 | def download(self, str remotefile, str localpath, sf.ftp.TransferMode mode=sf.ftp.Binary): 637 | cdef sf.ftp.Response* response = new sf.ftp.Response() 638 | 639 | encoded_remotefile_temporary = remotefile.encode('UTF-8') 640 | encoded_localpath_temporary = localpath.encode('UTF-8') 641 | cdef char* encoded_remotefile = encoded_remotefile_temporary 642 | cdef char* encoded_localpath = encoded_localpath_temporary 643 | 644 | with nogil: 645 | response[0] = self.p_this.download(encoded_remotefile, encoded_localpath, mode) 646 | 647 | return wrap_ftpresponse(response) 648 | 649 | def upload(self, str localfile, str remotepath, sf.ftp.TransferMode mode=sf.ftp.Binary): 650 | cdef sf.ftp.Response* response = new sf.ftp.Response() 651 | 652 | encoded_localfile_temporary = localfile.encode('UTF-8') 653 | encoded_remotepath_temporary = remotepath.encode('UTF-8') 654 | cdef char* encoded_localfile = encoded_localfile_temporary 655 | cdef char* encoded_remotepath = encoded_remotepath_temporary 656 | 657 | with nogil: 658 | response[0] = self.p_this.upload(encoded_localfile, encoded_remotepath, mode) 659 | 660 | return wrap_ftpresponse(response) 661 | 662 | 663 | cdef class HttpRequest: 664 | GET = sf.http.request.Get 665 | POST = sf.http.request.Post 666 | HEAD = sf.http.request.Head 667 | 668 | cdef sf.http.Request *p_this 669 | 670 | def __init__(self, bytes uri=b"/", sf.http.request.Method method=sf.http.request.Get, bytes body=b""): 671 | self.p_this = new sf.http.Request(string(uri), method, string(body)) 672 | 673 | def __dealloc__(self): 674 | del self.p_this 675 | 676 | def __repr__(self): 677 | return "HttpRequest()" 678 | 679 | property field: 680 | def __set__(self, tuple v): 681 | cdef bytes field = v[0] 682 | cdef bytes value = v[1] 683 | self.p_this.setField(string(field), string(value)) 684 | 685 | property method: 686 | def __set__(self, sf.http.request.Method method): 687 | self.p_this.setMethod(method) 688 | 689 | property uri: 690 | def __set__(self, bytes uri): 691 | self.p_this.setUri(string(uri)) 692 | 693 | property http_version: 694 | def __set__(self, tuple value): 695 | cdef unsigned int major = value[0] 696 | cdef unsigned int minor = value[1] 697 | self.p_this.setHttpVersion(major, minor) 698 | 699 | property body: 700 | def __set__(self, bytes body): 701 | self.p_this.setBody(string(body)) 702 | 703 | 704 | cdef class HttpResponse: 705 | OK = sf.http.response.Ok 706 | CREATED = sf.http.response.Created 707 | ACCEPTED = sf.http.response.Accepted 708 | NO_CONTENT = sf.http.response.NoContent 709 | RESET_CONTENT = sf.http.response.ResetContent 710 | PARTIAL_CONTENT = sf.http.response.PartialContent 711 | MULTIPLE_CHOICES = sf.http.response.MultipleChoices 712 | MOVED_PERMANENTLY = sf.http.response.MovedPermanently 713 | MOVED_TEMPORARILY = sf.http.response.MovedTemporarily 714 | #NOT_MODIFIED = sf.http.response.NotModified 715 | #BAD_REQUEST = sf.http.response.BadRequest 716 | UNAUTHORIZED = sf.http.response.Unauthorized 717 | FORBIDDEN = sf.http.response.Forbidden 718 | NOT_FOUND = sf.http.response.NotFound 719 | RANGE_NOT_SATISFIABLE = sf.http.response.RangeNotSatisfiable 720 | INTERNAL_SERVER_ERROR = sf.http.response.InternalServerError 721 | NOT_IMPLEMENTED = sf.http.response.NotImplemented 722 | BAD_GATEWAY = sf.http.response.BadGateway 723 | SERVICE_NOT_AVAILABLE = sf.http.response.ServiceNotAvailable 724 | GATEWAY_TIMEOUT = sf.http.response.GatewayTimeout 725 | VERSION_NOT_SUPPORTED = sf.http.response.VersionNotSupported 726 | INVALID_RESPONSE = sf.http.response.InvalidResponse 727 | CONNECTION_FAILED = sf.http.response.ConnectionFailed 728 | 729 | cdef sf.http.Response *p_this 730 | 731 | def __init__(self): 732 | raise NotImplementedError("Not meant to be instantiated!") 733 | 734 | def __dealloc__(self): 735 | del self.p_this 736 | 737 | def __repr__(self): 738 | return "HttpResponse()" 739 | 740 | def get_field(self, bytes field): 741 | return self.p_this.getField(string(field)).c_str() 742 | 743 | property status: 744 | def __get__(self): 745 | return self.p_this.getStatus() 746 | 747 | property major_http_version: 748 | def __get__(self): 749 | return self.p_this.getMajorHttpVersion() 750 | 751 | property minor_http_version: 752 | def __get__(self): 753 | return self.p_this.getMinorHttpVersion() 754 | 755 | property body: 756 | def __get__(self): 757 | return self.p_this.getBody().c_str() 758 | 759 | cdef wrap_httpresponse(sf.http.Response *p): 760 | cdef HttpResponse r = HttpResponse.__new__(HttpResponse) 761 | r.p_this = p 762 | return r 763 | 764 | cdef class Http: 765 | cdef sf.Http *p_this 766 | 767 | def __init__(self, bytes host, unsigned short port=0): 768 | self.p_this = new sf.Http(string(host), port) 769 | 770 | def __dealloc__(self): 771 | del self.p_this 772 | 773 | def __repr__(self): 774 | return "Http()" 775 | 776 | def send_request(self, HttpRequest request, Time timeout=None): 777 | cdef sf.http.Response* p = new sf.http.Response() 778 | 779 | if not timeout: 780 | with nogil: p[0] = self.p_this.sendRequest(request.p_this[0]) 781 | else: 782 | with nogil: p[0] = self.p_this.sendRequest(request.p_this[0], timeout.p_this[0]) 783 | 784 | return wrap_httpresponse(p) 785 | -------------------------------------------------------------------------------- /src/sfml/sf.py: -------------------------------------------------------------------------------- 1 | """ A convenience module that imports all other modules. 2 | 3 | Example:: 4 | 5 | from sfml import sf 6 | 7 | window = sf.RenderWindow(sf.VideoMode(w, h), "pySFML - Pong") 8 | """ 9 | 10 | from sfml.system import * 11 | from sfml.window import * 12 | from sfml.graphics import * 13 | from sfml.audio import * 14 | from sfml.network import * 15 | -------------------------------------------------------------------------------- /src/sfml/system/NumericObject.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #include 10 | 11 | NumericObject::NumericObject() 12 | : m_object(NULL) 13 | { 14 | } 15 | 16 | NumericObject::NumericObject(const NumericObject& copy) 17 | { 18 | m_object = copy.m_object; 19 | Py_INCREF(m_object); 20 | } 21 | 22 | NumericObject::NumericObject(PyObject* object) 23 | : m_object(object) 24 | { 25 | Py_XINCREF(m_object); 26 | } 27 | 28 | NumericObject::~NumericObject() 29 | { 30 | Py_XDECREF(m_object); 31 | } 32 | 33 | PyObject* NumericObject::get() 34 | { 35 | Py_XINCREF(m_object); 36 | return m_object; 37 | } 38 | 39 | void NumericObject::set(PyObject* object) 40 | { 41 | if (m_object) 42 | Py_DECREF(m_object); 43 | 44 | m_object = object; 45 | Py_INCREF(m_object); 46 | } 47 | 48 | NumericObject NumericObject::operator+() const 49 | { 50 | return PyNumber_Positive(const_cast(m_object)); 51 | } 52 | 53 | NumericObject NumericObject::operator-() const 54 | { 55 | return PyNumber_Negative(const_cast(m_object)); 56 | } 57 | 58 | NumericObject NumericObject::operator+(const NumericObject& object) const 59 | { 60 | return PyNumber_Add(m_object, object.m_object); 61 | } 62 | 63 | NumericObject NumericObject::operator-(const NumericObject& object) const 64 | { 65 | return PyNumber_Subtract(m_object, object.m_object); 66 | } 67 | 68 | NumericObject NumericObject::operator*(const NumericObject& object) const 69 | { 70 | return PyNumber_Multiply(m_object, object.m_object); 71 | } 72 | 73 | NumericObject NumericObject::operator/(const NumericObject& object) const 74 | { 75 | return PyNumber_TrueDivide(m_object, object.m_object); 76 | } 77 | 78 | NumericObject NumericObject::operator~() const 79 | { 80 | return PyNumber_Invert(const_cast(m_object)); 81 | } 82 | 83 | NumericObject NumericObject::operator&(const NumericObject& object) const 84 | { 85 | return PyNumber_And(m_object, object.m_object); 86 | } 87 | 88 | NumericObject NumericObject::operator|(const NumericObject& object) const 89 | { 90 | return PyNumber_Or(m_object, object.m_object); 91 | } 92 | 93 | NumericObject NumericObject::operator^(const NumericObject& object) const 94 | { 95 | return PyNumber_Xor(m_object, object.m_object); 96 | } 97 | 98 | NumericObject& NumericObject::operator+=(const NumericObject& b) 99 | { 100 | m_object = PyNumber_InPlaceAdd(m_object, b.m_object); 101 | return *this; 102 | } 103 | 104 | NumericObject& NumericObject::operator-=(const NumericObject& b) 105 | { 106 | m_object = PyNumber_InPlaceSubtract(m_object, b.m_object); 107 | return *this; 108 | } 109 | 110 | NumericObject& NumericObject::operator*=(const NumericObject& b) 111 | { 112 | m_object = PyNumber_InPlaceMultiply(m_object, b.m_object); 113 | return *this; 114 | } 115 | 116 | NumericObject& NumericObject::operator/=(const NumericObject& b) 117 | { 118 | m_object = PyNumber_InPlaceTrueDivide(m_object, b.m_object); 119 | return *this; 120 | } 121 | 122 | NumericObject& NumericObject::operator&=(const NumericObject& b) 123 | { 124 | m_object = PyNumber_InPlaceAnd(m_object, b.m_object); 125 | return *this; 126 | } 127 | 128 | NumericObject& NumericObject::operator|=(const NumericObject& b) 129 | { 130 | m_object = PyNumber_InPlaceOr(m_object, b.m_object); 131 | return *this; 132 | } 133 | 134 | NumericObject& NumericObject::operator^=(const NumericObject& b) 135 | { 136 | m_object = PyNumber_InPlaceXor(m_object, b.m_object); 137 | return *this; 138 | } 139 | 140 | bool NumericObject::operator==(const NumericObject &b) const 141 | { 142 | return PyObject_RichCompareBool(m_object, b.m_object, Py_EQ); 143 | } 144 | 145 | bool NumericObject::operator!=(const NumericObject &b) const 146 | { 147 | return PyObject_RichCompareBool(m_object, b.m_object, Py_NE); 148 | } 149 | 150 | bool NumericObject::operator<(const NumericObject &b) const 151 | { 152 | return PyObject_RichCompareBool(m_object, b.m_object, Py_LT); 153 | } 154 | 155 | bool NumericObject::operator>(const NumericObject &b) const 156 | { 157 | return PyObject_RichCompareBool(m_object, b.m_object, Py_GT); 158 | } 159 | 160 | bool NumericObject::operator<=(const NumericObject &b) const 161 | { 162 | return PyObject_RichCompareBool(m_object, b.m_object, Py_LE); 163 | } 164 | 165 | bool NumericObject::operator>=(const NumericObject &b) const 166 | { 167 | return PyObject_RichCompareBool(m_object, b.m_object, Py_GE); 168 | } 169 | -------------------------------------------------------------------------------- /src/sfml/system/NumericObject.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #ifndef PYSFML_SYSTEM_NUMERICOBJECT_HPP 10 | #define PYSFML_SYSTEM_NUMERICOBJECT_HPP 11 | 12 | #include "Python.h" 13 | #include 14 | 15 | class SFML_API_EXPORT NumericObject 16 | { 17 | public: 18 | NumericObject(); 19 | NumericObject(const NumericObject& copy); 20 | NumericObject(PyObject* object); 21 | 22 | ~NumericObject(); 23 | 24 | PyObject* get(); 25 | void set(PyObject* object); 26 | 27 | NumericObject operator+() const; 28 | NumericObject operator-() const; 29 | NumericObject operator+(const NumericObject& object) const; 30 | NumericObject operator-(const NumericObject& object) const; 31 | NumericObject operator*(const NumericObject& object) const; 32 | NumericObject operator/(const NumericObject& object) const; 33 | NumericObject operator~() const; 34 | NumericObject operator&(const NumericObject& object) const; 35 | NumericObject operator|(const NumericObject& object) const; 36 | NumericObject operator^(const NumericObject& object) const; 37 | 38 | NumericObject& operator+=(const NumericObject& b); 39 | NumericObject& operator-=(const NumericObject& b); 40 | NumericObject& operator*=(const NumericObject& b); 41 | NumericObject& operator/=(const NumericObject& b); 42 | NumericObject& operator&=(const NumericObject& b); 43 | NumericObject& operator|=(const NumericObject& b); 44 | NumericObject& operator^=(const NumericObject& b); 45 | 46 | bool operator==(const NumericObject &b) const; 47 | bool operator!=(const NumericObject &b) const; 48 | bool operator<(const NumericObject &b) const; 49 | bool operator>(const NumericObject &b) const; 50 | bool operator<=(const NumericObject &b) const; 51 | bool operator>=(const NumericObject &b) const; 52 | 53 | private: 54 | PyObject* m_object; 55 | }; 56 | 57 | #endif // PYSFML_SYSTEM_NUMERICOBJECT_HPP 58 | -------------------------------------------------------------------------------- /src/sfml/system/error.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | static std::stringbuf buffer; 14 | 15 | // Insert our own buffer to retrieve and forward errors to Python 16 | // exceptions. This function allows to restore the Python buffer in case people 17 | // would interface Python with C++ code and so reredirect the error output. 18 | void restorePythonErrorBuffer() 19 | { 20 | sf::err().rdbuf(&buffer); 21 | } 22 | 23 | // Return the last error (if any) then clear the buffer to welcome the next one. 24 | PyObject* getLastErrorMessage() 25 | { 26 | // Get the error message then clean the buffer 27 | #if PY_MAJOR_VERSION >= 3 28 | PyObject* error = PyBytes_FromString(buffer.str().c_str()); 29 | #else 30 | PyObject* error = PyString_FromString(buffer.str().c_str()); 31 | #endif 32 | 33 | buffer.str(""); 34 | 35 | return error; 36 | } 37 | -------------------------------------------------------------------------------- /src/sfml/system/error.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #ifndef PYSFML_SYSTEM_ERROR_HPP 10 | #define PYSFML_SYSTEM_ERROR_HPP 11 | 12 | #include "Python.h" 13 | 14 | void restorePythonErrorBuffer(); 15 | PyObject* getLastErrorMessage(); 16 | 17 | #endif // PYSFML_SYSTEM_ERROR_HPP 18 | -------------------------------------------------------------------------------- /src/sfml/system/hacks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #include 10 | 11 | sf::Time Time_div_int(sf::Time left, sf::Int64 right) 12 | { 13 | return left / right; 14 | } 15 | 16 | sf::Time Time_div_float(sf::Time left, float right) 17 | { 18 | return left / right; 19 | } 20 | 21 | float Time_div_Time(sf::Time left, sf::Time right) 22 | { 23 | return left / right; 24 | } 25 | 26 | void Time_idiv_int(sf::Time& left, sf::Int64 right) 27 | { 28 | left /= right; 29 | } 30 | 31 | void Time_idiv_float(sf::Time& left, float right) 32 | { 33 | left /= right; 34 | } 35 | -------------------------------------------------------------------------------- /src/sfml/system/hacks.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PySFML - Python bindings for SFML 3 | * Copyright (c) 2012-2017, Jonathan De Wachter 4 | * 5 | * This file is part of PySFML project and is available under the zlib 6 | * license. 7 | */ 8 | 9 | #ifndef PYSFML_SYSTEM_HACKS_HPP 10 | #define PYSFML_SYSTEM_HACKS_HPP 11 | 12 | #include 13 | #include 14 | 15 | #if PY_VERSION_HEX >= 0x03000000 16 | #define PyString_AsString PyBytes_AsString 17 | #endif 18 | 19 | sf::Time Time_div_int(sf::Time left, sf::Int64 right); 20 | sf::Time Time_div_float(sf::Time left, float right); 21 | float Time_div_Time(sf::Time left, sf::Time right); 22 | 23 | void Time_idiv_int(sf::Time& left, sf::Int64 right); 24 | void Time_idiv_float(sf::Time& left, float right); 25 | 26 | #endif // PYSFML_SYSTEM_HACKS_HPP 27 | -------------------------------------------------------------------------------- /src/sfml/system/system.pyx: -------------------------------------------------------------------------------- 1 | # PySFML - Python bindings for SFML 2 | # Copyright (c) 2012-2017, Jonathan De Wachter 3 | # 4 | # This file is part of PySFML project and is available under the zlib 5 | # license. 6 | 7 | from __future__ import division 8 | 9 | cimport cython 10 | 11 | from libcpp.string cimport string 12 | from libcpp.vector cimport vector 13 | 14 | cimport sfml as sf 15 | from sfml cimport Int8, Int16, Int32, Int64 16 | from sfml cimport Uint8, Uint16, Uint32, Uint64 17 | from pysfml.system cimport NumericObject 18 | 19 | cdef extern from *: 20 | ctypedef int wchar_t 21 | ctypedef void* PyUnicodeObject 22 | object PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) 23 | 24 | cdef extern from "pysfml/system/error.hpp": 25 | void restorePythonErrorBuffer() 26 | object getLastErrorMessage() 27 | 28 | cdef extern from "pysfml/system/hacks.hpp": 29 | sf.Time Time_div_int(sf.Time left, Int64) 30 | sf.Time Time_div_float(sf.Time left, float) 31 | float Time_div_Time(sf.Time, sf.Time) 32 | void Time_idiv_int(sf.Time&, Int64) 33 | void Time_idiv_float(sf.Time&, float) 34 | 35 | __all__ = ['Time', 'sleep', 'Clock', 'seconds', 'milliseconds', 'microseconds', 36 | 'Vector2', 'Vector3'] 37 | 38 | # expose a function to restore the error handler 39 | cdef api void restoreErrorHandler(): 40 | restorePythonErrorBuffer() 41 | 42 | # expose a function to retrieve the last SFML error 43 | cdef api object popLastErrorMessage(): 44 | error = getLastErrorMessage() 45 | 46 | # remove the extra \n character (if any) 47 | if error[-1] == '\n': 48 | error = error[:-1] 49 | 50 | return error 51 | 52 | # redirect SFML errors to our stream buffer 53 | restoreErrorHandler() 54 | 55 | cdef api sf.String to_string(basestring string): 56 | # To have a portable string convertion implementation, the only 57 | # reliable encoding format is UTF-32 (wchar isn't supported on Mac 58 | # OS X. And given SFML converts into UTF-32 internally, we can 59 | # simplify the implementation by letting Python convert it into a 60 | # UTF-32 bytes array and let SFML trivially copy it. 61 | 62 | # We must discard the 4 first bytes that corresponds to the Unicode 63 | # byte order marks which SFML doesn't support, and add the NULL 64 | # character at the end. 65 | # 66 | # Check out the following string example 'My' before and after the 67 | # removal. 68 | # 69 | # b'\xff\xfe\x00\x00M\x00\x00\x00y\x00\x00\x00' 70 | # b'M\x00\x00\x00y\x00\x00\x00\x00\x00\x00\x00' 71 | # 72 | bytes_string = string.encode('UTF-32')[4:] + b'\x00\x00\x00\x00' 73 | 74 | # We must read the underlying bytes array. In Cython, this is done 75 | # in the following fashion. 76 | cdef char* bytes_pointer = bytes_string 77 | return sf.String(bytes_pointer) 78 | 79 | cdef api object wrap_string(const sf.String* p): 80 | # To simplify the implementation, we get the underlying UTF-32 81 | # strings and let Python decode it. 82 | cdef char* bytes_pointer = p.getData() 83 | 84 | # Cython won't properly make a Python bytes string because it's 85 | # going to stop at the first NULL character. Instead we specify its 86 | # length manually. 87 | bytes_string = bytes_pointer[:p.getSize()*4] 88 | 89 | return bytes_string.decode('UTF-32') 90 | 91 | cdef public class Vector2[type PyVector2Type, object PyVector2Object]: 92 | cdef sf.Vector2[NumericObject] *p_this 93 | 94 | def __cinit__(self): 95 | self.p_this = new sf.Vector2[NumericObject]() 96 | 97 | def __dealloc__(self): 98 | del self.p_this 99 | 100 | def __init__(self, x=0, y=0): 101 | self.x = x 102 | self.y = y 103 | 104 | def __repr__(self): 105 | return "Vector2(x={0}, y={1})".format(self.x, self.y) 106 | 107 | def __str__(self): 108 | return "({0}, {1})".format(self.x, self.y) 109 | 110 | def __richcmp__(Vector2 self, other_, op): 111 | cdef Vector2 other 112 | 113 | if isinstance(other_, Vector2): 114 | other = other_ 115 | else: 116 | x, y = other_ 117 | other = Vector2(x, y) 118 | 119 | if op == 2: 120 | return self.p_this[0] == other.p_this[0] 121 | elif op == 3: 122 | return self.p_this[0] != other.p_this[0] 123 | else: 124 | raise NotImplemented 125 | 126 | def __iter__(self): 127 | return iter((self.x, self.y)) 128 | 129 | def __add__(Vector2 self, other): 130 | cdef sf.Vector2[NumericObject] *p = new sf.Vector2[NumericObject]() 131 | 132 | if isinstance(other, Vector2): 133 | p[0] = self.p_this[0] + (other).p_this[0] 134 | else: 135 | x, y = other 136 | p[0] = self.p_this[0] + Vector2(x, y).p_this[0] 137 | 138 | return wrap_vector2(p) 139 | 140 | def __sub__(Vector2 self, other): 141 | cdef sf.Vector2[NumericObject] *p = new sf.Vector2[NumericObject]() 142 | 143 | if isinstance(other, Vector2): 144 | p[0] = self.p_this[0] - (other).p_this[0] 145 | else: 146 | x, y = other 147 | p[0] = self.p_this[0] - Vector2(x, y).p_this[0] 148 | 149 | return wrap_vector2(p) 150 | 151 | def __mul__(Vector2 self, other): 152 | cdef sf.Vector2[NumericObject] *p = new sf.Vector2[NumericObject]() 153 | p[0] = self.p_this[0] * NumericObject(other) 154 | 155 | return wrap_vector2(p) 156 | 157 | # Todo: I couldn't get the / operator working and as a workaround, I 158 | # reimplemented the logic in Python (I have to report this bug) 159 | def __truediv__(Vector2 self, other): 160 | return Vector2(self.x / other, self.y / other) 161 | 162 | def __iadd__(Vector2 self, other): 163 | if isinstance(other, Vector2): 164 | self.p_this[0] += (other).p_this[0] 165 | else: 166 | x, y = other 167 | self.p_this[0] += Vector2(x, y).p_this[0] 168 | 169 | return self 170 | 171 | def __isub__(Vector2 self, other): 172 | if isinstance(other, Vector2): 173 | self.p_this[0] -= (other).p_this[0] 174 | else: 175 | x, y = other 176 | self.p_this[0] -= Vector2(x, y).p_this[0] 177 | 178 | return self 179 | 180 | def __imul__(self, other): 181 | self.p_this[0] *= NumericObject(other) 182 | 183 | return self 184 | 185 | # Todo: I couldn't get the =/ operator working and as a workaround, I 186 | # reimplemented the logic in Python (I have to report this bug) 187 | def __itruediv__(Vector2 self, other): 188 | self.x /= other 189 | self.y /= other 190 | 191 | return self 192 | 193 | def __neg__(self): 194 | cdef sf.Vector2[NumericObject] *p = new sf.Vector2[NumericObject]() 195 | p[0] = -self.p_this[0] 196 | return wrap_vector2(p) 197 | 198 | def __copy__(self): 199 | cdef sf.Vector2[NumericObject] *p = new sf.Vector2[NumericObject](self.p_this[0]) 200 | return wrap_vector2(p) 201 | 202 | property x: 203 | def __get__(self): 204 | return self.p_this.x.get() 205 | 206 | def __set__(self, object x): 207 | self.p_this.x.set(x) 208 | 209 | property y: 210 | def __get__(self): 211 | return self.p_this.y.get() 212 | 213 | def __set__(self, object y): 214 | self.p_this.y.set(y) 215 | 216 | cdef api Vector2 wrap_vector2(sf.Vector2[NumericObject]* p): 217 | cdef Vector2 r = Vector2.__new__(Vector2) 218 | r.p_this = p 219 | return r 220 | 221 | cdef api object wrap_vector2i(sf.Vector2i p): 222 | cdef Vector2 r = Vector2.__new__(Vector2) 223 | r.x = p.x 224 | r.y = p.y 225 | return r 226 | 227 | cdef api object wrap_vector2u(sf.Vector2u p): 228 | cdef Vector2 r = Vector2.__new__(Vector2) 229 | r.x = p.x 230 | r.y = p.y 231 | return r 232 | 233 | cdef api object wrap_vector2f(sf.Vector2f p): 234 | cdef Vector2 r = Vector2.__new__(Vector2) 235 | r.x = p.x 236 | r.y = p.y 237 | return r 238 | 239 | cdef api sf.Vector2i to_vector2i(vector): 240 | x, y = vector 241 | return sf.Vector2i(x, y) 242 | 243 | cdef api sf.Vector2u to_vector2u(vector): 244 | x, y = vector 245 | return sf.Vector2u(x, y) 246 | 247 | cdef api sf.Vector2f to_vector2f(vector): 248 | x, y = vector 249 | return sf.Vector2f(x, y) 250 | 251 | cdef public class Vector3[type PyVector3Type, object PyVector3Object]: 252 | cdef sf.Vector3[NumericObject] *p_this 253 | 254 | def __cinit__(self): 255 | self.p_this = new sf.Vector3[NumericObject]() 256 | 257 | def __dealloc__(self): 258 | del self.p_this 259 | 260 | def __init__(self, x=0, y=0, z=0): 261 | self.x = x 262 | self.y = y 263 | self.z = z 264 | 265 | def __repr__(self): 266 | return "Vector3(x={0}, y={1}, z={2})".format(self.x, self.y, self.z) 267 | 268 | def __str__(self): 269 | return "({0}, {1}, {2})".format(self.x, self.y, self.z) 270 | 271 | def __richcmp__(Vector3 self, other_, op): 272 | cdef Vector3 other 273 | 274 | if isinstance(other_, Vector3): 275 | other = other_ 276 | else: 277 | x, y, z = other_ 278 | other = Vector3(x, y, z) 279 | 280 | if op == 2: 281 | return self.p_this[0] == other.p_this[0] 282 | elif op == 3: 283 | return self.p_this[0] != other.p_this[0] 284 | else: 285 | raise NotImplemented 286 | 287 | def __iter__(self): 288 | return iter((self.x, self.y, self.z)) 289 | 290 | def __add__(Vector3 self, other): 291 | cdef sf.Vector3[NumericObject] *p = new sf.Vector3[NumericObject]() 292 | 293 | if isinstance(other, Vector3): 294 | p[0] = self.p_this[0] + (other).p_this[0] 295 | else: 296 | x, y, z = other 297 | p[0] = self.p_this[0] + Vector3(x, y, z).p_this[0] 298 | 299 | return wrap_vector3(p) 300 | 301 | def __sub__(Vector3 self, other): 302 | cdef sf.Vector3[NumericObject] *p = new sf.Vector3[NumericObject]() 303 | 304 | if isinstance(other, Vector3): 305 | p[0] = self.p_this[0] - (other).p_this[0] 306 | else: 307 | x, y, z = other 308 | p[0] = self.p_this[0] - Vector3(x, y, z).p_this[0] 309 | 310 | return wrap_vector3(p) 311 | 312 | def __mul__(Vector3 self, other): 313 | cdef sf.Vector3[NumericObject] *p = new sf.Vector3[NumericObject]() 314 | p[0] = self.p_this[0] * NumericObject(other) 315 | 316 | return wrap_vector3(p) 317 | 318 | # Todo: I couldn't get the / operator working and as a workaround, I 319 | # reimplemented the logic in Python (I have to report this bug) 320 | def __truediv__(Vector3 self, other): 321 | return Vector3(self.x / other, self.y / other, self.z / other) 322 | 323 | def __iadd__(Vector3 self, other): 324 | if isinstance(other, Vector3): 325 | self.p_this[0] += (other).p_this[0] 326 | else: 327 | x, y, z = other 328 | self.p_this[0] += Vector3(x, y, z).p_this[0] 329 | 330 | return self 331 | 332 | def __isub__(Vector3 self, other): 333 | if isinstance(other, Vector3): 334 | self.p_this[0] -= (other).p_this[0] 335 | else: 336 | x, y, z = other 337 | self.p_this[0] -= Vector3(x, y, z).p_this[0] 338 | 339 | return self 340 | 341 | def __imul__(self, other): 342 | self.p_this[0] *= NumericObject(other) 343 | 344 | return self 345 | 346 | # Todo: I couldn't get the =/ operator working and as a workaround, I 347 | # reimplemented the logic in Python (I have to report this bug) 348 | def __itruediv__(Vector3 self, other): 349 | self.x /= other 350 | self.y /= other 351 | self.z /= other 352 | 353 | return self 354 | 355 | def __neg__(self): 356 | cdef sf.Vector3[NumericObject] *p = new sf.Vector3[NumericObject]() 357 | p[0] = -self.p_this[0] 358 | return wrap_vector3(p) 359 | 360 | def __copy__(self): 361 | cdef sf.Vector3[NumericObject] *p = new sf.Vector3[NumericObject](self.p_this[0]) 362 | return wrap_vector3(p) 363 | 364 | property x: 365 | def __get__(self): 366 | return self.p_this.x.get() 367 | 368 | def __set__(self, object x): 369 | self.p_this.x.set(x) 370 | 371 | property y: 372 | def __get__(self): 373 | return self.p_this.y.get() 374 | 375 | def __set__(self, object y): 376 | self.p_this.y.set(y) 377 | 378 | property z: 379 | def __get__(self): 380 | return self.p_this.z.get() 381 | 382 | def __set__(self, object z): 383 | self.p_this.z.set(z) 384 | 385 | cdef api object wrap_vector3(sf.Vector3[NumericObject]* p): 386 | cdef Vector3 r = Vector3.__new__(Vector3) 387 | r.p_this = p 388 | return r 389 | 390 | cdef api object wrap_vector3i(sf.Vector3i p): 391 | cdef Vector3 r = Vector3.__new__(Vector3) 392 | r.x = p.x 393 | r.y = p.y 394 | r.z = p.z 395 | return r 396 | 397 | cdef api object wrap_vector3f(sf.Vector3f p): 398 | cdef Vector3 r = Vector3.__new__(Vector3) 399 | r.x = p.x 400 | r.y = p.y 401 | r.z = p.z 402 | return r 403 | 404 | cdef api sf.Vector3i to_vector3i(vector): 405 | x, y, z = vector 406 | return sf.Vector3i(x, y, z) 407 | 408 | cdef api sf.Vector3f to_vector3f(vector): 409 | x, y, z = vector 410 | return sf.Vector3f(x, y, z) 411 | 412 | cdef public class Time[type PyTimeType, object PyTimeObject]: 413 | ZERO = wrap_time(&sf.time.Zero) 414 | 415 | cdef sf.Time *p_this 416 | 417 | def __cinit__(self): 418 | self.p_this = new sf.Time() 419 | 420 | def __dealloc__(self): 421 | del self.p_this 422 | 423 | def __repr__(self): 424 | return "Time(milliseconds={0})".format(self.milliseconds) 425 | 426 | def __str__(self): 427 | return "{0} milliseconds".format(self.milliseconds) 428 | 429 | def __richcmp__(Time x, Time y, int op): 430 | if op == 0: 431 | return x.p_this[0] < y.p_this[0] 432 | elif op == 2: 433 | return x.p_this[0] == y.p_this[0] 434 | elif op == 4: 435 | return x.p_this[0] > y.p_this[0] 436 | elif op == 1: 437 | return x.p_this[0] <= y.p_this[0] 438 | elif op == 3: 439 | return x.p_this[0] != y.p_this[0] 440 | elif op == 5: 441 | return x.p_this[0] >= y.p_this[0] 442 | 443 | def __add__(Time x, Time y): 444 | cdef sf.Time* p = new sf.Time() 445 | p[0] = x.p_this[0] + y.p_this[0] 446 | return wrap_time(p) 447 | 448 | def __sub__(Time x, Time y): 449 | cdef sf.Time* p = new sf.Time() 450 | p[0] = x.p_this[0] - y.p_this[0] 451 | return wrap_time(p) 452 | 453 | def __mul__(Time self, other): 454 | cdef sf.Time* p = new sf.Time() 455 | 456 | if isinstance(other, (int, long)): 457 | p[0] = self.p_this[0] * other 458 | elif isinstance(other, float): 459 | p[0] = self.p_this[0] * other 460 | else: 461 | return NotImplemented 462 | 463 | return wrap_time(p) 464 | 465 | def __truediv__(Time self, other): 466 | cdef sf.Time* p 467 | 468 | if isinstance(other, Time): 469 | # return self.p_this[0] / (