Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon Join the GFS Discord Server!
22. May 2012


In this tutorial we are going to look at playing audio with the PlayStation Suite SDK.  This chapter is pretty simple over all, so it will be rather short. In the end you will have a UI driven application that can play sound effects and songs.


To get started, we are going to need a couple audio files, one or more songs for background music and one or more songs for sound effects.  File formats are extremely limited in the SDK, all music files must be in MP3 format, while all sound effects must be in WAV format.  If you need to convert your file, I recommend you check out audacity.



For my song files, I grabbed two freely available Mozart tracks from this site and saved them as Song1.mp3 and Song2.mp3.  For sound effects I went to ( free login required ) and downloaded this and this which I saved as Sound1.wav and Sound2.wav respectively.  Of course, you can pick any mp3 or wav files you’d like, but these are the ones and the names I am going to use and the names I’ve chosen.


Now fire up UI Composer, if you haven’t already, you might want to read this tutorial, as I am not going to cover UI Composer in detail here.  Create the following UI, I called mine AudioPlayer.  Save the results and import into your project.





Let’s take a look at our GUI code in AudioPlayer.cs first, as it is the simplest.


using System; using System.Collections.Generic; using Sce.Pss.Core; using Sce.Pss.Core.Imaging; using Sce.Pss.Core.Environment; using Sce.Pss.HighLevel.UI; namespace Audio { public partial class AudioPlayer : Scene { public AudioPlayer() { InitializeWidget(); buttonNext.ButtonAction += delegate(object sender,TouchEventArgs e) { if(AppMain.currentSong ==0) AppMain.currentSong = 1; else AppMain.currentSong = 0; AppMain.songChanged = true; }; buttonPrev.ButtonAction += delegate(object sender,TouchEventArgs e) { if(AppMain.currentSong ==0) AppMain.currentSong = 1; else AppMain.currentSong = 0; AppMain.songChanged = true; }; buttonPlaySound1.ButtonAction += delegate(object sender, TouchEventArgs e) { AppMain.PlaySound("Sound1.wav"); LogText ("Playing Sound1.wav"); }; buttonPlaySound2.ButtonAction += delegate(object sender,TouchEventArgs e) { AppMain.PlaySound("Sound2.wav"); LogText ("Playing Sound2.wav"); }; } public void LogText(string outText) { this.labelOut.Text = outText; } } }


Everything here we have seen in prior tutorials.  Basically we wire up our four buttons we created in UI Composer.  nextButton and prevButton actually cheat a bit as the fact there are only two songs makes them identical in function.  Obviously if you had more songs you would require more logic.  Basically all either method do is update currentSong and songChanged values in AppMain.  We will see these variables in more detail in a second.  buttonPlaySound1 and buttonPlaySound2 simply call a PlaySound method in AppMain.  Finally LogText simply exposes the labelOut field so the AppMain class can change it’s value.



Now lets take a look at AppMain.cs:


using System; using System.Collections.Generic; using Sce.Pss.Core; using Sce.Pss.Core.Environment; using Sce.Pss.Core.Graphics; using Sce.Pss.Core.Input; using Sce.Pss.Core.Audio; using Sce.Pss.HighLevel.GameEngine2D; using Sce.Pss.HighLevel.GameEngine2D.Base; using Sce.Pss.HighLevel.UI; namespace Audio { public class AppMain { private static BgmPlayer songPlayer; private static Bgm[] songs; private static SoundPlayer soundPlayer; public static bool songChanged { get; set; } public static int currentSong { get;set; } public static void Main (string[] args) { GraphicsContext graphics = new GraphicsContext(); UISystem.Initialize(graphics); AudioPlayer audioPlayer = new AudioPlayer(); UISystem.SetScene(audioPlayer); songs = new Bgm[2]; songs[0] = new Bgm("/Application/Song1.mp3"); songs[1] = new Bgm("/Application/Song2.mp3"); songPlayer = songs[0].CreatePlayer(); songPlayer.Play(); audioPlayer.LogText("Playing song1.mp3"); while(true) { SystemEvents.CheckEvents(); List<TouchData> touchData = Touch.GetData(0); UISystem.Update (touchData); graphics.SetViewport(0, 0, graphics.Screen.Width, graphics.Screen.Height); graphics.SetClearColor(new Vector4(0,0,0,1)); graphics.SetClearDepth(1.0f); graphics.Clear(); UISystem.Render (); graphics.SwapBuffers(); if(songPlayer.Status == BgmStatus.Stopped) { if(currentSong == 0) currentSong = 1; else currentSong = 0; audioPlayer.LogText ("Song ended, swapped to song:" + currentSong.ToString()); songPlayer.Dispose(); songPlayer = songs[currentSong].CreatePlayer(); songPlayer.Play (); } if(songChanged) { songPlayer.Dispose(); songPlayer = songs[currentSong].CreatePlayer(); songPlayer.Play (); songChanged = false; audioPlayer.LogText("Song changed due to user request."); } } } public static void PlaySound(string soundName) { //if(soundPlayer != null) // soundPlayer.Dispose(); soundPlayer = new Sound("/Application/" + soundName).CreatePlayer(); soundPlayer.Play(); } } }


The UI code is identical to that we covered in the earlier UI Composer tutorial, so we will ignore those bits.  First we will declare our three audio related variables, a BgmPlayer, our Bgm songs array and our SoundPlayer.  BGM stands for Background Music ( I assume ), and these two variables represent our songs and the player required to play them.  Please note that both BgmPlayer and SoundPlayer have a dispose method and should be disposed of, something I do not do in this example ( given the primitive nature of the event loop ).  In your code, be sure to dispose of them when you are done.  The bool songChanged and currentSong are publically exposed so our UI has access to them, you will see them in action shortly.


In Main() we set up our graphics, initialize the UI system, create our UI and set it as active.  We then declare our song array to contain two songs, both of which are loaded from file using the constructor.  These (mp3 and wav) files need to be added to your project just like any other resource, right click your project-> Add Files… then right click the file, select Build Action and set it to content.  The actual BgmPlayer is created by calling Bgm.CreatePlayer(), which is what we do next, then we tell the player to start playing the song.


Next we start our never ending event loop just like before.  Unfortunately PS SDK has no callback facility to notify when a song has finished playing ( hopefully this is changed during beta! ) so we poll the songPlayer until the BgmStatus is Stopped.  If it is stopped, we simply set currentSong to our other index into the songs array.  As songPlayer has some unmanaged resources, we need to Dispose of it before creating a new player for the next song.  Next we tell the newly created player to play the next song.


Next we check if the songChanged flag was changed ( from AudioPlayer on button handlers ), if a song change has occurred, we perform the exact same logic as if a song had ended.  However instead of flipping to the next sound, the button press logic has already handled this step for us, so currentSong will already reference the next song to play.


Finally we expose a PlaySound method that was called earlier when we pressed a PlaySound1 or PlaySound2 button.  You are limited to one Bgm at a time, but this is not the case with SoundPlayer objects.  This code will allow multiple sound effects to play at once.  Remove the commented section to limit playback to a single sound effect at a time.  I am not sure what is proper form or if failing to dispose SoundPlayer before calling CreatePlayer again causes a leak, be wary!



And there you have a simple SoundPlayer application.  Normally at this point I post an image of our application in action, but that obviously doesn’t work for a tutorial like this, so I captured instead this video:


PlayStation Suite Audio Tutorial application in action



You can download the full project here.  This archive also includes all the songs and sounds used in this example.


18. May 2012



You often hear people say things like “It’s memory management that makes C++ difficult”, this is patently false.  What makes C++ so incredibly difficult for new users ( and experienced ones! ) is the complexity.  Note, I didn’t say difficulty, I said complexity.


Today was one of those perfect examples, one of those experiences that I want to point at and say “THIS IS WHY YOU SHOULD LEARN WITH A DIFFERENT LANGUAGE!”.  Yes, that was shouting. 



Here’s the story.  Today I had a reader request guidance on how to make a release build of my C++ tutorial.  This was a really good request, so I put it together in tutorial form.  Something quickly dawned on me… I’ve never built this tutorial in release mode.  It was pretty obvious that I hadn’t because, well, it didn’t work!   Oops, my bad.



Let’s take a look at what happened, I want to see if you can guess what the problem is.  A gold star to whoever gets it before I reveal the answer at the end of this post.  That gold star offer applies to C++ veterans and new developers alike, this is a somewhat tricky one, especially considering the starting point!



So, I was building Pang 9 ( my Pong tutorial ) in release mode.  I downloaded the project files from here if you want to follow along at home.  I simply extracted the project, then I downloaded the full SFML 1.6 SDK, imported the Visual Studio 2008 project into Visual Studio 2010 and compiled the DLLs for multithreaded release mode, and copied those DLLs into my release directory.  Code compiles just fine under release, so then I run it ( within Visual Studio ) and:





Uhoh… this can’t be good!  The offending line of code is right here:


sf::Music* SoundFileCache::GetSong(std::string soundName) const { std::map<std::string,sf::Music *>::iterator itr = _music.find(soundName); if(itr == _music.end()) { sf::Music * song = new sf::Music(); if(!song->OpenFromFile(soundName)) <----- EXCEPTION IS HERE { delete song; throw SoundNotFoundExeception( soundName + " was not found in call to SoundFileCache::GetSong"); } ..... SNIP ......

Well, there is a big bad pointer right above the line, that seems an obvious candidate doesn’t it?   Well don’t waste your time on that train of thought, the pointer isn’t the issue.  The .find call seems a likely candidate too, it isn’t though.


Hmm, lets start looking there, ill set a breakpoint and trace into the _music.find() call.  Oh yeah, this a release mode only bug, so our hands our tied on the debugging side of things… great.  Alright, lets take a closer look.





<Bad Ptr>.  Oooh, that’s not good.  Obviously I’ve done a bad allocation here somewhere, but that just doesn’t make sense, not with the way this data type works.  In fact, the only place these pointers are even allocated is in this actual method, and we haven’t even got to that code yet!


For some reason, our empty map ( it hasn’t been used yet, this is the first call ), is returning a Bad Ptr instead of working as expected.  This can’t be right?  But wait… that’s a red herring anyways, isn’t it, after all our exception has nothing to do with the Bad Ptr or the std::map at all, this is just the IDE sending us on a wild goose chase. We can literally boil it down to exactly two lines of code:


sf::Music * song = new sf::Music(); if(!song->OpenFromFile(soundName))


Now we are getting somewhere, we have isolated our reproduce case down to exactly a two line program!  Hmmm, both are just standard SFML calls.  Short of being out of memory, nothing here should be able to fail.  So then, what the hell is causing this problem???



// ANSWER TIME, got your guess yet?  Did you get it right and I owe you a gold star?  Let’s find out!



Well, long story short, it’s our SFML dlls built for Visual Studio 2010.  See, this is our first method call into any SFML DLL and it’s causing an explosion… but, why the heck is that???



Well, lets take a trip over to the SFML 1.6 project and check out how I built them.  All I did was download the SFML 1.6 project for Visual Studio 2008, delete all the examples and set my build mode to Release DLL and compiled everything.  Hidden between the various warnings was one very very very important but cryptic message:




A bunch of warnings as a side effect of the import process, and one extremely important warning… the ahah moment if you will:


Warning    8    warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library    C:\temp\t\SFML-1.6\build\vc2008\LINK    sfml-graphics


Say what?



Now here is the thing, with C++ libraries need to be IDENTICAL.  You link debug to debug, multithread to multithread, etc…  At the same time, you have to link Visual Studio 2010 binaries to Visual Studio 2010 binaries ( although not all versions are binary incompatible, VS 2005 and 2008 could share libraries I believe ), and this here is the source of all the trouble!


The sfml-graphics graphics library statically links to a lib called freetype, and this library isn’t compatible with Visual Studio 2010.  Download the newest version, extract it into the extlibs folder, recompile and PRESTO, problem solved.




So there you go, an unhandled exception in a call to open an audio file ended up actually being caused by a statically linked font library in a 3rd party graphics dll!



Still think it’s memory management that makes C++ tricky for beginners?  The biggest problem is, new developers run into this stuff almost immediately.  You need to conquer so much to get up and running with C++, the linker being one of the earliest and most daunting obstacles.  I honestly don’t expect anyone with a few months of programming experience to have been able to puzzle this one out.  It’s exactly these kinds of things that make people throw up their hands saying “Oh screw it, programming is too hard!”.  I don’t like a quitter, but frankly in this case… they are right!



Of course, this is by no means limited to C++.  I have had very similar experiences with Java where some XML file feeding another XML file feeding a code generator called by Maven puked out a message code like “Error, unknown problem”.  Thing is, with no other programming languages do you encounter this kind of problem until you are ready to deal with the complexity.  In C++, you start dealing with this crap on day 1.


So this, is one such reason why I say C++ isn’t a beginner friendly language!


18. May 2012


Someone on the PlayStation Suite forum recently asked if there was an implementation of the Box2D physics library that would work with PS Suite.  Initially Box2Dx looked encouraging, but in the end it relied on some unsafe ( as in the keyword ) code, plus it was quite a bit out of date.  In my searching though, I did stumble upon the Farseer XNA a prominent XNA physics library.  It depends on some XNA data types, but nicely, the library includes them!


So I set about trying to get FarSeer working with PlayStation Suite, which proved to be a fairly simple task.


First you need to create a PlayStation suite library, then copy across all of the code/folders from the archive.  Make sure it is FarSeer Physics Engine class you download, the other versions have dependencies that don’t work.  Now you have to make one very small code change.  You need to open DynamicTreeBroadPhase.cs and change internal struct Pair : … to public, like this:


public struct Pair : IComparable<Pair> //MJF made public


And that’s it.


Compile it as a PlayStation Suite library and add it as a reference to your project and you are off to the races.  You can download the DLL I compiled for PlayStation Suite right here if you don’t want to or can’t build it yourself.


Now, the reason I’m not really calling this a tutorial is, I haven’t bothered to actually take the time to figure out how to use FarSeer, I just modified their sample enough to verify it runs on the PlayStation Vita.  Due to the screwy decision to make the origin the bottom left, you need to alter their examples accordingly, but otherwise everything works fine.  Here is a sample of extremely poorly configured gravity.


using System; using System.Collections.Generic; using Sce.Pss.Core; using Sce.Pss.Core.Environment; using Sce.Pss.Core.Graphics; using Sce.Pss.Core.Input; using Sce.Pss.HighLevel.GameEngine2D; using Sce.Pss.HighLevel.GameEngine2D.Base; using FarseerPhysics.Common; using FarseerPhysics.Controllers; using FarseerPhysics.Dynamics; using FarseerPhysics.Factories; namespace FarTest { public class AppMain { private const float MeterInPixels = 64f; public static void Main() { Director.Initialize(); Scene scene = new Scene(); scene.Camera.SetViewFromViewport(); Vector2 midPoint = scene.Camera.CalcBounds().Center; // Create circle and ground sprites Texture2D texture = new Texture2D("/Application/circleSprite.png",false); TextureInfo ti = new TextureInfo(texture); SpriteUV sprite = new SpriteUV(ti); sprite.Quad.S = new Vector2(98,98); sprite.Position = new Vector2(midPoint.X - 98/2,Director.Instance.GL.Context.GetViewport().Height-98); Texture2D texture2 = new Texture2D("/Application/groundSprite.png",false); TextureInfo ti2 = new TextureInfo(texture); SpriteUV sprite2 = new SpriteUV(ti); sprite2.Quad.S = new Vector2(512,64); sprite2.Position = new Vector2(midPoint.X - 512/2,0); //Physics time World world = new World(new Microsoft.Xna.Framework.Vector2(0,-10)); Body circleBody = BodyFactory.CreateCircle(world,96f /2f,1f, new Microsoft.Xna.Framework.Vector2(sprite.Position.X,sprite.Position.Y)); circleBody.BodyType = BodyType.Dynamic; Body groundBody = BodyFactory.CreateRectangle(world,512f, 64f/2,1f, new Microsoft.Xna.Framework.Vector2(sprite2.Position.X,sprite2.Position.Y)); ; groundBody.IsStatic = true; groundBody.Restitution = 0.9f; groundBody.Friction = 0.4f; // Now update the sprite //circleBody.ApplyLinearImpulse(new Microsoft.Xna.Framework.Vector2(0,-50)); sprite.Schedule( (dt) => { sprite.Position = new Vector2(circleBody.Position.X,circleBody.Position.Y); world.Step(dt); }); scene.AddChild(sprite); scene.AddChild (sprite2); Director.Instance.RunWithScene(scene); } } }



And here are the results:





The only real gotcha in the code is to make sure you use the Microsoft.Xna.Framework.Vector2 when calling FarSeer code and PSS’s Vector2 when dealing with PSS code.



Obviously, my ground is a bit bouncy, my gravity is a bit wonky, but it is a working physics simulation! Smile


18. May 2012



At the request of a reader I put together a guide on how to build your SFML 1.6 project in release mode, then how to package it for distribution.


It’s part of the main tutorial series, but can be accessed directly here.  If you are looking into how to distribute a release version of your SFML game, be sure to check it out



In doing so, I ran into a NASTY C++ related problem, which I will mention in a post shortly!


16. May 2012






If you are going to make your game require an always on internet connection, especially for the single player game, you damned well better have stable servers!


Diablo 3 have blown it pretty big time, and things don’t seem to be getting that much better.  On the bright side, in the face of all of these Error 37’s, D3 hasn’t really affected my productivity.


If anyone but Blizzard pulled this stunt, their game would be getting 0 star reviews and shamed into oblivion.  I am curious to see how Diablo ends up being reviewed.  The worst part is, Diablo 3 is a damned good game making suffering these annoyances worthwhile… just.


What *REALLY* pisses me off though… cache my damned password!  It’s annoying enough having to deal with these errors, but having to re-enter my password every time I hit an error 37, that’s just salt in the wound!  Blizzard, if you are listening to your fans, if you can’t fix your servers, at least cache the password field!


So, if you are here killing time between Diablo error messages, could I suggest a game programming tutorial or two… Winking smile




EDIT:  20 seconds later…




Why oh why did I complain… I angered the gods, who invoked their wrath in the form a hithero unheard of Error 33. is down for maintenance.  Please try again later (Error 33).



Blizzard, seriously, you screwed up big time.



I’m pretty tolerant of DRM, I understand the motivation behind it, but this DRM that supposedly isn’t DRM, well it’s about the worst I’ve dealt with since HoMM6.  Actually it’s worse, as I could still at least play HoMM offline during the outages.


I hope every other game developer out there is taking note of the Error 37’s and 33’s and realizing what a mistake always on internet connections for single player games is!  I won’t buy another one with this feature, that’s for sure.



Oh, and if you are here from Google looking for a way to fix Error 38’s, sadly you can’t.  That ball is completely in Blizzards court.  Until they fix their servers, increase capacity or implement an offline mode ( very very unlikely ) I am afraid to say these errors are going to be a fact of Diablo life.

Totally Off Topic

See More Tutorials on!

Month List