Added the trunk/branches/tags directories at repository root, and moved previous root into trunk/

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/trunk@1002 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
laurentgom 2009-01-28 16:18:34 +00:00
commit 2f524481c1
974 changed files with 295448 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -0,0 +1,16 @@
texture framebuffer
float offset
effect
{
vec2 offx = vec2(offset, 0.0);
vec2 offy = vec2(0.0, offset);
vec4 c0 = framebuffer(_in);
vec4 c1 = framebuffer(_in - offy);
vec4 c2 = framebuffer(_in + offy);
vec4 c3 = framebuffer(_in - offx);
vec4 c4 = framebuffer(_in + offx);
_out = c0 * 0.2 + c1 * 0.2 + c2 * 0.2 + c3 * 0.2 + c4 * 0.2;
}

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,10 @@
texture framebuffer
vec3 color
effect
{
vec4 pixel = framebuffer(_in);
float gray = pixel.r * 0.39 + pixel.g * 0.50 + pixel.b * 0.11;
_out = vec4(gray * color, 1.0) * 0.6 + pixel * 0.4;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

View file

@ -0,0 +1,12 @@
texture framebuffer
vec2 mouse
effect
{
float len = distance(_in, mouse) * 7.0;
if (len < 1.0)
_out = framebuffer(_in + (_in - mouse) * len);
else
_out = framebuffer(_in);
}

View file

@ -0,0 +1,6 @@
texture framebuffer
effect
{
_out = framebuffer(_in);
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -0,0 +1,12 @@
texture framebuffer
texture wave
vec2 offset
effect
{
vec2 texoffset = wave(_in * offset).xy;
texoffset -= vec2(0.5, 0.5);
texoffset *= 0.05;
_out = framebuffer(_in + texoffset);
}

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,230 @@
module dflsample;
import dsfml.system.all;
import dsfml.window.all;
// DFL and Derelict must be present.
import dfl.all;
import Derelict.opengl.gl;
import Derelict.opengl.glu;
// An enum for each controls methods
enum ControlMethod
{
MOUSE,
KEYBOARD
}
void main()
{
DerelictGL.load();
DerelictGLU.load();
//Start the message loop
Application.run(new MyForm());
}
//A simple form with a groupbox to choose input method and the openGL control
class MyForm : Form
{
GLControl m_gl;
GroupBox m_gbx;
RadioButton m_rb1;
RadioButton m_rb2;
this()
{
m_gbx = new GroupBox();
m_gbx.dock = DockStyle.TOP;
m_gbx.height = 40;
m_gbx.text = "Choose your input";
this.controls.add(m_gbx);
m_rb1 = new RadioButton();
m_rb1.text = "Mouse";
m_rb1.location = Point(10, 15);
m_rb1.checked = true;
m_rb1.click ~= &radioButtonClick;
m_gbx.controls.add(m_rb1);
m_rb2 = new RadioButton();
m_rb2.text = "Keyboard";
m_rb2.location = Point(m_rb1.width + 10, 15);
m_rb2.click ~= &radioButtonClick;
m_gbx.controls.add(m_rb2);
m_gl = new GLControl();
m_gl.dock = DockStyle.FILL;
m_gl.controlMethod = ControlMethod.MOUSE;
this.controls.add(m_gl);
this.text = "DFL Opengl Integration Sample";
}
private void radioButtonClick(Control c, EventArgs ea)
{
m_gl.controlMethod(c.text == "Mouse" ? ControlMethod.MOUSE : ControlMethod.KEYBOARD);
m_gl.focus();
}
}
//Our OpenGL control
class GLControl : Control
{
Window m_win;
Input i;
Timer m_timer;
GLfloat rotx = 0.f, roty = 0.f;
ControlMethod m_method = ControlMethod.MOUSE;
this ()
{
super();
this.setStyle(ControlStyles.SELECTABLE | ControlStyles.ALL_PAINTING_IN_WM_PAINT | ControlStyles.WANT_ALL_KEYS, true);
//We set a timer to ensure periodic refresh of the window
m_timer = new Timer();
m_timer.interval(10);
m_timer.tick ~= &this.onTick;
}
public void controlMethod(ControlMethod m)
{
m_method = m;
}
//Override of the onHandleCreated method of Control
//integration of DSFML window in a control need a valid handle
protected void onHandleCreated(EventArgs ea)
{
super.onHandleCreated(ea);
//Construction of the window
m_win = new Window(cast(WindowHandle)this.handle);
//Get the input for further use
i = m_win.getInput();
//Now that the Window is instanciated, we can start the timer.
m_timer.start();
//Some opengl initializations functions
glClearDepth(1.f);
glClearColor(0.f, 0.f, 0.f, 0.f);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 1.f, 1.f, 500.f);
}
//We handle Mouse leaving and entering the control to hide or show the cursor
protected void onMouseEnter(MouseEventArgs mea)
{
super.onMouseEnter(mea);
Cursor.current.hide();
}
protected void onMouseLeave(MouseEventArgs mea)
{
super.onMouseLeave(mea);
Cursor.current.show();
}
//If the window is resize, we need to modify openGL view
protected void onResize(EventArgs ea)
{
super.onResize(ea);
glViewport(0, 0, this.width, this.height);
}
protected void onTick(Timer t, EventArgs ea)
{
draw();
}
protected void onPaint(PaintEventArgs pea)
{
super.onPaint(pea);
draw();
}
private void handleKeys()
{
if (i.isKeyDown(KeyCode.UP))
rotx += 1.f;
if (i.isKeyDown(KeyCode.DOWN))
rotx += -1.f;
if (i.isKeyDown(KeyCode.LEFT))
roty += -1.f;
if (i.isKeyDown(KeyCode.RIGHT))
roty += 1.f;
}
private void handleMousePos()
{
rotx = i.getMouseY() - (this.height / 2.0);
roty = i.getMouseX() - (this.width / 2.0);
}
private void draw()
{
if (m_method == ControlMethod.KEYBOARD)
handleKeys();
else
handleMousePos();
m_win.setActive(true);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.f, 0.f, -200.f);
glRotatef(rotx, 1.f, 0.f, 0.f);
glRotatef(roty, 0.f, 1.f, 0.f);
glBegin(GL_QUADS);
glColor3f(1.f, 0.f, 0.f);
glVertex3f(-50.f, -50.f, -50.f);
glVertex3f(-50.f, 50.f, -50.f);
glVertex3f( 50.f, 50.f, -50.f);
glVertex3f( 50.f, -50.f, -50.f);
glColor3f(0.f, 1.f, 0.f);
glVertex3f(-50.f, -50.f, 50.f);
glVertex3f(-50.f, 50.f, 50.f);
glVertex3f( 50.f, 50.f, 50.f);
glVertex3f( 50.f, -50.f, 50.f);
glColor3f(0.f, 0.f, 1.f);
glVertex3f(-50.f, -50.f, -50.f);
glVertex3f(-50.f, 50.f, -50.f);
glVertex3f(-50.f, 50.f, 50.f);
glVertex3f(-50.f, -50.f, 50.f);
glColor3f(1.f, 1.f, 0.f);
glVertex3f(50.f, -50.f, -50.f);
glVertex3f(50.f, 50.f, -50.f);
glVertex3f(50.f, 50.f, 50.f);
glVertex3f(50.f, -50.f, 50.f);
glColor3f(1.f, 0.f, 1.f);
glVertex3f(-50.f, -50.f, 50.f);
glVertex3f(-50.f, -50.f, -50.f);
glVertex3f( 50.f, -50.f, -50.f);
glVertex3f( 50.f, -50.f, 50.f);
glColor3f(0.f, 1.f, 1.f);
glVertex3f(-50.f, 50.f, 50.f);
glVertex3f(-50.f, 50.f, -50.f);
glVertex3f( 50.f, 50.f, -50.f);
glVertex3f( 50.f, 50.f, 50.f);
glEnd();
m_win.display();
}
}

View file

@ -0,0 +1,33 @@
[*]
buildflags += -I../../import -Ivoip
[pong/pong.d]
target = bin/pong
[postFX/postFX.d]
target = bin/postFX
[socket/socketclient.d]
target = bin/client
[socket/socketserver.d]
target = bin/server
[sound3d/sound3d.d]
target = bin/sound3d
[soundstream/soundstream.d]
target = bin/soundstream
[view/view.d]
target = bin/view
[voip/entry.d]
target = bin/voip
version (Windows){
version (DFL){
[dfl/dflsample.d]
target = bin/dflSample
}
}

View file

@ -0,0 +1,183 @@
module pong;
import dsfml.system.all;
import dsfml.audio.all;
import dsfml.window.all;
import dsfml.graphics.all;
version (Tango)
{
import tango.io.Stdout;
import tango.math.Math;
}
else
{
import std.math;
}
void main()
{
// Defines PI
const float PI = 3.14159f;
// Create the window of the application
RenderWindow app = new RenderWindow(VideoMode(800, 600, 32), "SFML Pong");
app.useVerticalSync(true);
Input i = app.getInput();
// Load the sounds used in the game
Sound BallSound = new Sound(new SoundBuffer("Data/ball.wav"));
// Load the images used in the game
Image PaddleImage = new Image("Data/paddle.tga");
Image BallImage = new Image("Data/ball.tga");
// Initialize the end text
String End = new String(""c);
Font font = new Font("Data/cheeseburger.ttf");
End.setFont(font);
End.setSize(60.f);
End.move(150.f, 200.f);
End.setColor(Color(50, 50, 250));
// Create the sprites of the background, the paddles and the ball
Sprite LeftPaddle = new Sprite(PaddleImage);
Sprite RightPaddle = new Sprite(PaddleImage);
Sprite Ball = new Sprite(BallImage);
LeftPaddle.move(10, (app.getView().getRect().getHeight() - LeftPaddle.getSize().y) / 2);
RightPaddle.move(app.getView().getRect().getWidth() - RightPaddle.getSize().x - 10, (app.getView().getRect().getHeight() - RightPaddle.getSize().y) / 2);
Ball.move((app.getView().getRect().getWidth() - Ball.getSize().x) / 2, (app.getView().getRect().getHeight() - Ball.getSize().y) / 2);
// Define the paddles properties
Clock AITimer = new Clock();
const float AITime = 0.1f;
float LeftPaddleSpeed = 400.f;
float RightPaddleSpeed = 400.f;
// Define the ball properties
float BallSpeed = 400.f;
float BallAngle = 0.f;
do
{
// Make sure the ball initial angle is not too much vertical
BallAngle = Randomizer.random(0.f, 2 * PI);
} while (abs(cos(BallAngle)) < 0.7f);
bool IsPlaying = true;
Event evt;
while (app.isOpened())
{
app.clear(Color(255, 255, 255, 255));
// Handle events
while (app.getEvent(evt))
{
// Window closed or escape key pressed : exit
if ((evt.Type == Event.EventType.CLOSED) ||
((evt.Type == Event.EventType.KEYPRESSED) && (evt.Key.Code == KeyCode.ESCAPE)))
{
app.close();
break;
}
}
if (IsPlaying)
{
// Move the player's paddle
if (i.isKeyDown(KeyCode.UP) && (LeftPaddle.getPosition().y > 5.f))
LeftPaddle.move(0.f, -LeftPaddleSpeed * app.getFrameTime());
if (i.isKeyDown(KeyCode.DOWN) && (LeftPaddle.getPosition().y < app.getView().getRect().getHeight() - LeftPaddle.getSize().y - 5.f))
LeftPaddle.move(0.f, LeftPaddleSpeed * app.getFrameTime());
// Move the computer's paddle
if (((RightPaddleSpeed < 0.f) && (RightPaddle.getPosition().y > 5.f)) ||
((RightPaddleSpeed > 0.f) && (RightPaddle.getPosition().y < app.getView().getRect().getHeight() - RightPaddle.getSize().y - 5.f)))
{
RightPaddle.move(0.f, RightPaddleSpeed * app.getFrameTime());
}
// Update the computer's paddle direction according to the ball position
if (AITimer.getElapsedTime() > AITime)
{
AITimer.reset();
if ((RightPaddleSpeed < 0) && (Ball.getPosition().y + Ball.getSize().y > RightPaddle.getPosition().y + RightPaddle.getSize().y))
RightPaddleSpeed = -RightPaddleSpeed;
if ((RightPaddleSpeed > 0) && (Ball.getPosition().y < RightPaddle.getPosition().y))
RightPaddleSpeed = -RightPaddleSpeed;
}
// Move the ball
float Factor = BallSpeed * app.getFrameTime();
Ball.move(cos(BallAngle) * Factor, sin(BallAngle) * Factor);
// Check collisions between the ball and the screen
if (Ball.getPosition().x < 0.f)
{
IsPlaying = false;
End.setText("You lost !\n(press escape to exit)"c);
}
if (Ball.getPosition().x + Ball.getSize().x > app.getView().getRect().getWidth())
{
IsPlaying = false;
End.setText("You won !\n(press escape to exit)"c);
}
if (Ball.getPosition().y < 0.f)
{
BallSound.play();
BallAngle = -BallAngle;
Ball.setY(0.1f);
}
if (Ball.getPosition().y + Ball.getSize().y > app.getView().getRect().getHeight())
{
BallSound.play();
BallAngle = -BallAngle;
Ball.setY(app.getView().getRect().getHeight() - Ball.getSize().y - 0.1f);
}
// Check the collisions between the ball and the paddles
// Left Paddle
if (Ball.getPosition().x < LeftPaddle.getPosition().x + LeftPaddle.getSize().x &&
Ball.getPosition().x > LeftPaddle.getPosition().x + (LeftPaddle.getSize().x / 2.0f) &&
Ball.getPosition().y + Ball.getSize().y >= LeftPaddle.getPosition().y &&
Ball.getPosition().y <= LeftPaddle.getPosition().y + LeftPaddle.getSize().y)
{
BallSound.play();
BallAngle = PI - BallAngle;
Ball.setX(LeftPaddle.getPosition().x + LeftPaddle.getSize().x + 0.1f);
}
// Right Paddle
if (Ball.getPosition().x + Ball.getSize().x > RightPaddle.getPosition().x &&
Ball.getPosition().x + Ball.getSize().x < RightPaddle.getPosition().x + (RightPaddle.getSize().x / 2.0f) &&
Ball.getPosition().y + Ball.getSize().y >= RightPaddle.getPosition().y &&
Ball.getPosition().y <= RightPaddle.getPosition().y + RightPaddle.getSize().y)
{
BallSound.play();
BallAngle = PI - BallAngle;
Ball.setX(RightPaddle.getPosition().x - Ball.getSize().x - 0.1f);
}
}
// Draw the background, paddles and ball sprites
app.draw(LeftPaddle);
app.draw(RightPaddle);
app.draw(Ball);
// If the game is over, display the end message
if (!IsPlaying)
app.draw(End);
// Display things on screen
app.display();
}
}

View file

@ -0,0 +1,117 @@
module postfx;
import dsfml.graphics.all;
import dsfml.system.all;
import dsfml.window.all;
const char[][5] EFFECTS = ["nothing", "blur", "colorize", "fisheye", "wave"];
void main()
{
int actualIndex;
// Check that the system can use post effects
if (PostFX.canUsePostFX() == false)
assert(0, "Your system doesn't support Post Effects.");
// Create the main window
RenderWindow app = new RenderWindow(VideoMode(800, 600), "SFML PostFX");
app.setFramerateLimit(100);
// Load a cute background image to display :)
Sprite background = new Sprite(new Image("Data/background.jpg"));
// Load the image needed for the wave effect
Image WaveImage = new Image("Data/wave.jpg");
// Load all effects
PostFX[char[]] Effects;
foreach(char[] c; EFFECTS)
{
Effects[c] = new PostFX("Data/" ~ c ~ ".sfx");
}
PostFX currentEffect = Effects[EFFECTS[actualIndex]];
// Do specific initializations
Effects["nothing"].setTexture("framebuffer", null);
Effects["blur"].setTexture("framebuffer", null);
Effects["blur"].setParameter("offset", 0.f);
Effects["colorize"].setTexture("framebuffer", null);
Effects["colorize"].setParameter("color", 1.f, 1.f, 1.f);
Effects["fisheye"].setTexture("framebuffer", null);
Effects["wave"].setTexture("framebuffer", null);
Effects["wave"].setTexture("wave", WaveImage);
Font f = new Font("Data/cheeseburger.ttf");
// Define a string for displaying current effect description
String curFXStr = new String("Current effect is " ~ EFFECTS[actualIndex]);
curFXStr.setFont(f);
curFXStr.setPosition(20.f, 0.f);
// Define a string for displaying help
String infoStr = new String("Move your mouse to change the effect parameters\nPress numpad + and - to change effect\nWarning : some effects may not work\ndepending on your graphics card"c);
infoStr.setFont(f);
infoStr.setPosition(20.f, 460.f);
infoStr.setColor(Color(200, 100, 150));
// Start the game loop
while (app.isOpened())
{
// Process events
Event evt;
while (app.getEvent(evt))
{
// Close window : exit
if (evt.Type == Event.EventType.CLOSED ||
evt.Type == Event.EventType.KEYPRESSED && evt.Key.Code == KeyCode.ESCAPE)
app.close();
if (evt.Type == Event.EventType.KEYPRESSED)
{
// Add key : next effect
if (evt.Key.Code == KeyCode.ADD)
{
if (actualIndex == 4)
actualIndex = 0;
else
actualIndex++;
currentEffect = Effects[EFFECTS[actualIndex]];
curFXStr.setText("Current effect is " ~ EFFECTS[actualIndex]);
}
// Subtract key : previous effect
if (evt.Key.Code == KeyCode.SUBTRACT)
{
if (actualIndex == 0)
actualIndex = 4;
else
actualIndex--;
currentEffect = Effects[EFFECTS[actualIndex]];
curFXStr.setText("Current effect is " ~ EFFECTS[actualIndex]);
}
}
}
// Get the mouse position in the range [0, 1]
float X = app.getInput().getMouseX() / cast(float) app.getWidth();
float Y = app.getInput().getMouseY() / cast(float) app.getHeight();
// Update the current effect
if (EFFECTS[actualIndex] == "blur") currentEffect.setParameter("offset", X * Y * 0.1f);
else if (EFFECTS[actualIndex] == "colorize") currentEffect.setParameter("color", 0.3f, X, Y);
else if (EFFECTS[actualIndex] == "fisheye") currentEffect.setParameter("mouse", X, 1.f - Y);
else if (EFFECTS[actualIndex] == "wave") currentEffect.setParameter("offset", X, Y);
// Draw background and apply the post-fx
app.draw(background);
app.draw(currentEffect);
// Draw interface strings
app.draw(curFXStr);
app.draw(infoStr);
// Finally, display the rendered frame on screen
app.display();
}
}

View file

@ -0,0 +1,66 @@
module socketclient;
import dsfml.system.all;
import dsfml.network.all;
version (Tango)
{
import tango.io.Console;
import tango.io.Stdout;
}
else
{
import std.stdio;
}
void main()
{
//The TCP socket
SocketTCP client = new SocketTCP();
//Try to connect to server (on localhost for this sample)
client.connect(9000, IPAddress.LOCALHOST);
display("Connected to server."w);
//Prepare a packet with a string
Packet p = new Packet();
p.set("Hello from the client !"w);
if (client.send(p) != SocketStatus.DONE) // Assert on error
assert(0);
//Clear the packet
p.clear();
//Wait for the response of the server and display it
if (client.receive(p) != SocketStatus.DONE)
assert(0);
wchar[] c;
p.get(c);
display("Packet received : "w ~ c);
read();
}
void display(wchar[] c)
{
version (Tango)
{
Stdout(c).newline;
}
else
{
writefln("%s", c);
}
}
void read()
{
version (Tango)
{
Cin.get();
}
else
{
readln();
}
}

View file

@ -0,0 +1,83 @@
module socketserver;
import dsfml.system.all;
import dsfml.network.all;
version (Tango)
{
import tango.io.Console;
import tango.io.Stdout;
}
else
{
import std.stdio;
}
void main()
{
//We create a TCP socket for listening incomming client
SocketTCP listener = new SocketTCP();
//Set a random port for the listener
if (!listener.listen(9000))
assert(0);
//Creation of TCP socket
SocketTCP client = new SocketTCP();
IPAddress ipClient;
display("Waiting for client."w);
if (listener.accept(client, ipClient) == SocketStatus.DONE) //This call blocks until client connection
{
display("New client connected."w);
//The packet for retrieving the client message
Packet p = new Packet();
display("Waiting for data"w);
if (client.receive(p) != SocketStatus.DONE) //Assert on reception error
assert(0);
//Display the string send by the client
wchar[] c;
p.get(c);
display("Packet received : "w ~ c);
//Clear the packet (We could use a new one)
p.clear();
//and send response to client
client.send(p.set("Hello from the server !"w));
}
read();
}
/**
* Multilib string display
*/
void display(wchar[] c)
{
version (Tango)
{
Stdout(c).newline;
}
else
{
writefln("%s", c);
}
}
/**
* Dummy function to prevent console closing on windows
*/
void read()
{
version (Tango)
{
Cin.get();
}
else
{
readln();
}
}

View file

@ -0,0 +1,190 @@
module sound3d;
import dsfml.system.all;
import dsfml.window.all;
import dsfml.graphics.all;
import dsfml.audio.all;
void main()
{
//We create our window with a limit of 100 and a white backcolor.
RenderWindow app = new RenderWindow (VideoMode(800, 600, 32), "Sound Spatialization Sample");
app.useVerticalSync(true);
Font f = new Font("Data/cheeseburger.ttf", 34);
//Some instructions
String s = new String("Click anywhere on screen to change listener position.\nPress + or - to modify the speed of the car."c, f);
s.setPosition(20, 30);
s.setColor(Color.BLACK);
//We prepare our images and the sound
char[][2] images = ["Data/bluerallyecarleft.bmp", "Data/bluerallyecarright.bmp"];
Car c = new Car(images, "Data/car_idle.wav");
int carSpeed = 100;
//Set default position for the car and the listener
c.setPosition(Vector2f(0, 300));
SoundListener.setPosition(Vector2f(400, 300));
c.startPlaying();
//Start the main loop
while (app.isOpened())
{
app.clear(Color.WHITE);
Event evt;
//The event loop
while (app.getEvent(evt))
{
// if the window is closed, we can leave the game loop
if (evt.Type == Event.EventType.CLOSED)
app.close();
// we handle the click event to change listener position
else if (evt.Type == Event.EventType.MOUSEBUTTONPRESSED && evt.MouseButton.Button == MouseButtons.LEFT)
{
Input i = app.getInput();
SoundListener.setPosition(Vector2f(i.getMouseX(), i.getMouseY()));
}
// and eventual keys press
else if (evt.Type == Event.EventType.KEYPRESSED)
{
//Change the car speed
if (evt.Key.Code == KeyCode.ADD)
{
carSpeed += 25;
}
else if (evt.Key.Code == KeyCode.SUBTRACT)
{
carSpeed -= 25;
}
}
}
//We move constantly our car.
c.move(Vector2f(app.getFrameTime() * carSpeed, 0));
//Draw all the sprite and string on render window
app.draw(s);
app.draw(c.getSprite());
app.draw(SoundListener.getSprite());
//And finally display the window
app.display();
}
}
// Encapsulate the listener position and the visor sprite.
// There is only one listener so all the methods are statics.
class SoundListener
{
static Sprite s_crosshair;
static Vector2f s_p;
static this()
{
Image crosshairImg = new Image("Data/crosshair.tga");
crosshairImg.createMaskFromColor(Color.WHITE);
s_crosshair = new Sprite(crosshairImg);
s_crosshair.setCenter(Vector2f(s_crosshair.getSize().x / 2, s_crosshair.getSize().y / 2));
//Listener.setTarget(1.f, 0.f, 0.f);
}
// Adjust position of the listener
static void setPosition(Vector2f p)
{
Listener.setPosition(p.x, p.y, 5.f);
s_crosshair.setPosition(p);
}
static Sprite getSprite()
{
return s_crosshair;
}
}
// Class encapsulating all data for our car
class Car
{
Vector2f m_actual;
Sprite m_sprite;
Sound m_sound;
bool reverse;
Image[2] imgs;
//Constructor with with a fixed size string array of image path, and a string for the sound path
this (char[][2] images, char[] soundFilename)
{
//load images and create filter
imgs[0] = new Image(images[0]); imgs[1] = new Image(images[1]);
foreach(img; imgs)
img.createMaskFromColor(Color(97, 68, 43));
m_sprite = new Sprite(imgs[0]);
m_sprite.setCenter(Vector2f(m_sprite.getSize().x / 2, m_sprite.getSize().y / 2));
SoundBuffer buff = new SoundBuffer(soundFilename);
//load our sound with loop enabled
m_sound = new Sound(buff, true);
m_sound.setAttenuation(.05f);
}
// Begin the sound play
void startPlaying()
{
m_sound.play();
}
// Set the position of the car on the window
// Used to setup the begin car window and sound location
void setPosition(Vector2f p)
{
m_sprite.setPosition(p);
m_sound.setPosition(p.x, 0, p.y);
}
//Move the car (visual and sound position)
//If the car leave the screen, we change the sprite image and reverse moving
void move(Vector2f vec)
{
// if the car is beyond the right screen limit
if (!reverse && m_sprite.getPosition().x > 850)
{
m_sprite.setImage(imgs[1]);
reverse = true;
}
// same as above but for left limit
else if (reverse && vec.x + m_sprite.getPosition().x < -50)
{
m_sprite.setImage(imgs[0]);
reverse = false;
}
if (reverse)
vec = -vec;
m_sprite.move(vec);
Vector2f pos = m_sprite.getPosition();
m_sound.setPosition(pos.x , pos.y, 0);
}
Sprite getSprite()
{
return m_sprite;
}
}

View file

@ -0,0 +1,91 @@
module soundstream;
import dsfml.system.all;
import dsfml.audio.all;
version (Tango)
{
import tango.io.Console;
import tango.io.Stdout;
}
else
{
import std.stdio;
}
// SoundStream is an abstract class.
// You need to implement onStart() and onGetData()
// Don't forget to call initialize() before any usage or playback will fail.
class MySoundStream : SoundStream
{
SoundBuffer m_buff;
short[] m_data;
size_t m_cursor;
this()
{
// We initialize the stream with some sound informations
super(1, 11025);
// We create a sound buffer to load samples from files
m_buff = new SoundBuffer("Data/car_idle.wav");
m_data = m_buff.getSamples[0..m_buff.getSamplesCount];
}
protected:
bool onStart()
{
// No specifics things to do, just return true.
return true;
}
bool onGetData(out short[] data)
{
// We ensure that we have enough data to send
if (m_cursor + this.getSampleRate > m_data.length)
return false;
// Assign data in the buffer ...
data = m_data[m_cursor..m_cursor + this.getSampleRate];
// ... and increment the cursor
m_cursor += this.getSampleRate;
return true;
}
}
void main()
{
MySoundStream stream = new MySoundStream();
display("Playing sound !\n Press enter to stop playback.");
stream.play();
read();
stream.stop();
}
void display(char[] c)
{
version (Tango)
{
Stdout(c).newline;
}
else
{
writefln("%s", c);
}
}
/**
* Dummy function to prevent console closing on windows
*/
void read()
{
version (Tango)
{
Cin.get();
}
else
{
readln();
}
}

View file

@ -0,0 +1,69 @@
module view;
import dsfml.system.all;
import dsfml.window.all;
import dsfml.graphics.all;
void main()
{
RenderWindow window = new RenderWindow(VideoMode(800, 600), "View sample");
window.setFramerateLimit(100);
Input input = window.getInput();
Vector2f top;
Rect!(float) bound;
Shape s;
bool mousePressed;
Sprite background = new Sprite(new Image("Data/background.jpg"));
Font f = new Font("Data/cheeseburger.ttf");
String str = new String("Create a selection of the background with your mouse.\nPress Enter to zoom to this selection.\nPress Escape to return to the default view."c, f);
while (window.isOpened())
{
Event evt;
while (window.getEvent(evt))
{
if ( evt.Type == Event.EventType.MOUSEBUTTONPRESSED &&
evt.MouseButton.Button == MouseButtons.LEFT)
{
top = window.convertCoords(input.getMouseX(), input.getMouseY());
mousePressed = true;
}
else if ( evt.Type == Event.EventType.MOUSEBUTTONRELEASED &&
evt.MouseButton.Button == MouseButtons.LEFT)
{
mousePressed = false;
}
else if ( evt.Type == Event.EventType.MOUSEMOVED &&
mousePressed)
{
Vector2f bottom = window.convertCoords(input.getMouseX(), input.getMouseY());
bound = new Rect!(float)(top.x, top.y, bottom.x, bottom.y);
s = Shape.rectangle(top.x, top.y, bottom.x, bottom.y, Color(0, 0, 0, 0), 1, Color.BLACK);
}
else if ( evt.Type == Event.EventType.KEYPRESSED &&
evt.Key.Code == KeyCode.RETURN)
{
if (bound !is null)
window.setView(new View(bound));
s = null;
}
else if ( evt.Type == Event.EventType.KEYPRESSED &&
evt.Key.Code == KeyCode.ESCAPE)
{
window.setView(window.getDefaultView());
}
else if ( evt.Type == Event.EventType.CLOSED)
window.close();
}
window.draw(background);
window.draw(str);
if (s !is null) window.draw(s);
window.display();
}
}

View file

@ -0,0 +1,72 @@
module client;
import util;
// Specialization of audio recorder for sending recorded audio
// data through the network
class NetworkRecorder : SoundRecorder
{
public:
// Constructor
this(SocketTCP Socket)
{
mySocket = Socket;
}
~this()
{
delete mySocket;
}
protected:
override bool onStart()
{
return true;
}
override void onStop()
{
}
override bool onProcessSamples(short[] samples)
{
// Pack the audio samples into a network packet
Packet PacketOut = new Packet();
PacketOut.set(AudioData);
PacketOut.append((cast(byte*)samples.ptr)[0..samples.length * short.sizeof]);
// Send the audio packet to the server
return mySocket.send(PacketOut) == SocketStatus.DONE;
}
SocketTCP mySocket; ///< Socket used to communicate with the server
}
void runClient(IPAddress adr, int port)
{
// Create a TCP socket for communicating with server
SocketTCP Socket = new SocketTCP();
// Connect to the specified server
if (!Socket.connect(port, adr))
return;
// Wait for user input...
Cout("Press enter to start recording audio").newline;
Cin.get();
// Create a instance of our custom recorder
NetworkRecorder Recorder = new NetworkRecorder(Socket);
// Start capturing audio data
Recorder.start(44100);
Cout("Press enter to stop recording audio").newline;
Cin.get();
Recorder.stop();
// Send a "end-of-stream" packet
Packet PacketOut = new Packet();
PacketOut.set(EndOfStream);
Socket.send(PacketOut);
}

View file

@ -0,0 +1,46 @@
module entry;
import util;
import server;
import client;
int main(char[][] args)
{
char[][] argc = args.dup;
if (argc.length > 1)
{
if ( argc[1] == "-c" &&
argc.length == 4)
{
IPAddress adr = IPAddress(argc[2]);
if (adr.isValid() &&
parse(argc[3]) <= 60000 &&
parse(argc[3]) >= 1000)
{
runClient(adr, parse(argc[3]));
}
else
printUsage();
}
else if ( argc[1] == "-s" &&
argc.length == 3 &&
parse(argc[2]) <= 60000 &&
parse(argc[2]) >= 1000)
{
runServer(parse(argc[2]));
}
else
printUsage();
}
else
printUsage();
return 0;
}
void printUsage()
{
Cout("Usage :\n voip.exe [-c [ip address] | -s] [port] \n -c = run as client\n -s = run as server\n ip address = address of the server\n port = port between 1000 and 65000\n").newline;
}

View file

@ -0,0 +1,162 @@
module server;
import util;
class NetworkAudioStream : SoundStream
{
public:
static this()
{
s_sync = new Object();
}
// Default constructor
this()
{
myListener = new SocketTCP();
myClient = new SocketTCP();
// Set the sound parameters
super(1, 44100);
}
// Destructor
~this()
{
// Close the sockets
delete myClient;
delete myListener;
}
// Run the server, stream audio data from the client
void start(int Port)
{
if (!myHasFinished)
{
// Listen to the given port for incoming connections
if (!myListener.listen(Port))
return;
Cout("Listening").newline;
myListener.accept(myClient);
Cout("New Client").newline;
// Start playback
play();
// Start receiving audio data
receiveLoop();
}
else
{
// Start playback
play();
}
}
protected:
override bool onStart()
{
// Reset the playing offset
myOffset = 0;
return true;
}
override bool onGetData(out short[] data)
{
// We have reached the end of the buffer and all audio data have been played : we can stop playback
if ((myOffset == mySamples.length) && myHasFinished)
return false;
// No new data has arrived since last update : wait until we get some
while (myOffset == mySamples.length && !myHasFinished)
sleep(0.01f);
synchronized(s_sync)
{
myTempBuffer = mySamples[myOffset..mySamples.length];
// Update the playing offset
myOffset += myTempBuffer.length;
}
data = myTempBuffer;
return true;
}
private:
void receiveLoop()
{
while (!myHasFinished)
{
// Get waiting audio data from the network
Packet PacketIn = new Packet();
if (myClient.receive(PacketIn) != SocketStatus.DONE)
break;
// Extract the message ID
ubyte Id;
PacketIn.get(Id);
if (Id == AudioData)
{
// Extract audio samples from the packet, and append it to our samples buffer
synchronized(s_sync)
{
byte* temp = PacketIn.getData().ptr;
temp++;
mySamples ~= (cast(short*)temp)[0..(PacketIn.getDataSize - byte.sizeof ) / short.sizeof];
}
}
else if (Id == EndOfStream)
{
// End of stream reached : we stop receiving audio data
myHasFinished = true;
}
else
{
// Something's wrong...
myHasFinished = true;
}
}
}
SocketTCP myListener;
SocketTCP myClient;
short[] mySamples;
short[] myTempBuffer;
size_t myOffset;
bool myHasFinished;
static Object s_sync;
};
// Launch a server and wait for incoming audio data from
// a connected client
void runServer(int Port)
{
// Build an audio stream to play sound data as it is received through the network
NetworkAudioStream audioStream = new NetworkAudioStream;
audioStream.start(Port);
// Loop until the sound playback is finished
while (audioStream.getStatus() != SoundStatus.STOPPED)
{
// Leave some CPU time for other threads
sleep(0.1f);
}
Cout("Enter to replay").newline;
Cin.get();
// Replay the sound (just to make sure replaying the received data is OK)
audioStream.play();
// Loop until the sound playback is finished
while (audioStream.getStatus() != SoundStatus.STOPPED)
{
// Leave some CPU time for other threads
sleep(0.1f);
}
}

View file

@ -0,0 +1,49 @@
module util;
const ubyte AudioData = 1;
const ubyte EndOfStream = 2;
public import dsfml.system.all;
public import dsfml.audio.all;
public import dsfml.network.all;
version(Tango)
{
public import tango.io.Console;
public import tango.text.convert.Integer;
}
else
{
public import std.stdio;
//simple abstraction of Cout & Cin for phobos
class Cout
{
static Cout s_c;
static this()
{
s_c = new Cout();
}
static Cout opCall(char[] str)
{
writefln("%s", str);
return s_c;
}
void newline()
{
}
}
class Cin
{
static char[] get()
{
return readln();
}
}
public import std.string : atoi;
alias atoi parse;
}