Hi,

I've made a console Pong game. I've added some sounds but the sounds are about 10 external .wav sounds. It seems a bit like a mess when I send the game to somebody, and it's not really user friendly. I want these sounds to be included IN the .exe file or in a kind of package.

I've been trying with resources but the only results were errors :confused:

I'm using Dev C++ and OS is Windows Vista.

Hope you can help me

That's not what I had in mind, I want the files inside the exe file so it doesn't look so ugly..
.zip could do..

It doesn't work like that.

The only way to get it into one file is to zip it up, with whatever compression utility you intend to use.

> I've been trying with resources but the only results were errors
Perhaps posting some actual error messages would elicit a more useful (and targeted) response.

It works just fine.

Make sure your RC file looks something like

MySound1 RCDATA "spiff.wav"
MySound2 RCDATA "bloink.wav"

etc.

Compile it to a resource file (*.res) using whatever program you have to do that (like windres.exe that comes with GNU stuff).

Inside your program, you'll need to use the windows API to access the resources.
First, get the resource with HRSRC MySound1_rsrc = FindResource( NULL, "MySound1", RT_RCDATA ); Then, load the resource with HANDLE MySound1_handle = LoadResource( NULL, MySound1_rsrc ); If either of these functions fail the return value is 0. You do not need to call FreeResource on the MySound1_handle at any time (but you can if you are sure you are done with it).
(For those of you who are paying attention, the returned handle is not global.)

Now you have a Windows handle you can pass to ReadFile.

Hope this helps.

Comments
Excellent info! :)

Hey there. I just wanted to update my answer a little (I've looked it up to be sure).

It is actually a little easier than I thought it would be. Make your RC file

whizzing_fizzbang WAVE "whizzfizz.wav"
pop_rockets       WAVE "poprockets.wav"

etc.

Here's a little snippit of how to use it:

#include <string>
#include <windows.h>

...

void play_wav_resource( std::string resname, bool is_loop ) {
  HANDLE hfound, hsound;
  LPVOID data;

  hfound = FindResource( NULL, resname, "WAVE" );
  if (hfound != 0) {

    hsound = LoadResource( NULL, hfound );
    if (hsound != 0) {
      data = LockResource( hsound );

      if (data != NULL) SndPlaySound(
        (char *)data,
        SND_ASYNC | SND_MEMORY | (is_loop ? SND_LOOP : 0)
        );

      UnlockResource( hsound );
      }

    }
  FreeResource( hfound );
  }

void stop_wave_sound() {
  SndPlaySound( NULL, 0 );
  }

This code snippit is from this page on embedding resources (in Delphi). You can learn more stuff there. (The About.com pages have a lot of great stuff like this.)

Keep in mind that you don't actually have to free the resource until you are done with it. This routine does so because it uses the resource then it is done with it. Hence, the resource is re-loaded each time it is needed. If you plan to use the sound often, it would be better to load it once, then just use it as oft as you want. (You don't ever have to actually free it explicitly, since Windows will do that for you in this case.)

Hope this helps.

hmm.. I tried it but, I get an error.
The first error I get is a popup box containing: Could not create makefile, I/O error 32.
In the error log it says: [Build error] No rule to make target 'all'. Stop.

I got these errors before when I tried to use resouces. I might do something wrong?

After some googling, I think your build path may have spaces in it. Make sure it doesn't.

Let me know if that fixes it.

It did solve the build error, but now I get loads of errors in your play_wav function..

invalid conversion from 'void' to 'HINSTANCE__*)'
too few arguments to funtion 'void* LoadResource(HINSTANCE__*,HRSRC__*)'
invalid conversion from 'int' to 'HINSTANCE__*'

I got no idea what the hell is wrong... :-O

No need to cuss at me... :-O

There is something wrong with your windows.h includes. The LoadResource function, according to Microsoft, looks like this: HGLOBAL LoadResource( HMODULE, HRSRC ); In my MinGW (GCC) winbase.h file (which is included by windows.h), that is properly listed as: WINBASEAPI HGLOBAL WINAPI LoadResource(HINSTANCE,HRSRC); Whatever library you are using that says LoadResource takes or returns pointers of any kind, or takes more or less than two arguments, is wrong.

Make sure you have the correct windows headers.

[EDIT] Woot! 1000th post!

Comments
Congrats on the 1000th post. You are indeed an asset to this forum.

Right.. And how do I find out what headers to use?
Do I need an API main or is a normal main ok?

LOTRJ, I just typed that in. THere are bound to be some small mistakes. You are expected to use it to get started in finding the information you need to do this yourself.

The function is sndPlaySound (with a lowercase S at the beginning).

And yes, the std::string needs to be passed as a const char *: hfound = FindResource( NULL, [B]resname.c_str()[/B], "WAVE" ); Hope this helps. Use the Google if you feel stuck, and if that fails come here. I'm not being rude or cruel --this is a skill you absolutely must possess in order to learn to program. (Just like with Blender, you expect people to try a few things before throwing questions at the human dictionaries...)

More often than not I test code that I post here, but I don't plan to build an entire application with resource file just to do something you can... Make sense?

(I am at the limit of my knowledge about using the windows sound subsystem.)

I recommend you find some good references on the net about the things you want to do.
Here's a start:

C++ stuff
simple and uncluttered: http://www.cppreference.com/
complete and detailed: http://www.cplusplus.com/

Windows Waveform Audio http://msdn2.microsoft.com/en-us/library/aa910189.aspx
Windows Multimedia Reference http://technet.microsoft.com/en-us/library/ms712699(VS.85).aspx

Hope this helps.


[EDIT] Ah, you must have found your answers.

Just include <windows.h>
I think that should get you everything you need.

Enjoy! :)

Comments
Congrats on your 1st star!!! Keep it up!

I can't find much info about resources.. I found some but it was in French and I personally hate French.
I tried much.. but I think I'll just go on and wait untill I'm some more experienced.
Thanks for your help!

(If you are interested, here is the current error)

In function `void play_wav_resource(const char*, bool)':
invalid conversion from `void*' to `HRSRC__*'
initializing argument 2 of `void* LoadResource(HINSTANCE__*, HRSRC__*)'

This is the line of the error:
hsound = LoadResource( hInstance , hfound );

(I made a hInstance, because everyone on the internet does it)

Alright, I tried it myself. You are using the GCC? (I get the same error message.)

res.rc

one WAVE "c:\\WINDOWS\\Media\\notify.wav"

wave.cc

#include <iostream>
#include <limits>
#include <string>
#include <windows.h>

void play_wave_resource( std::string resname, bool is_loop ) {
  HANDLE hfound, hsound;
  LPVOID data;

  hfound = FindResource( NULL, resname.c_str(), "WAVE" );
  if (hfound != 0) {

    hsound = LoadResource( NULL, (HRSRC)hfound );
    if (hsound != 0) {
      data = LockResource( hsound );

      if (data != NULL) sndPlaySound(
        (char *)data,
        SND_ASYNC | SND_MEMORY | (is_loop ? SND_LOOP : 0)
        );

      UnlockResource( hsound );
      }

    }
  FreeResource( hfound );
  }

void stop_wave_sound() {
  sndPlaySound( NULL, 0 );
  }

int main() {
  using namespace std;

  play_wave_resource( "one", true );

  cout << "Press ENTER";
  cin.ignore( numeric_limits<streamsize>::max(), '\n' );

  stop_wave_sound();

  return EXIT_SUCCESS;
  }

To compile at DOS prompt with GCC

D:\prog\foo\wave> windres -o res.o res.rc

D:\prog\foo\wave> g++ -o wave wave.cc res.o -lwinmm

D:\prog\foo\wave> dir/b
res.o
res.rc
wave.cc
wave.exe

D:\prog\foo\wave> wave

Press enter before you've heard enough "notify" to go insane.

Let me know if you get anything different.

I'm having some error now: "no resource".. I think I can solve this myself.

(I'm using dev-cpp)

Ah, Vista must have moved the file. Just change the file path in the RC file to point to whatever WAV file you want to play.

another error came up..

make.exe: *** No rule to make target `clean'. Stop.

I dont know anything of the makefile.win. I think I am using the default one.

another error came up..

make.exe: *** No rule to make target `clean'. Stop.

I dont know anything of the makefile.win. I think I am using the default one.
I'm getting the no resources error again by the way.. I'm sure the file exists.

Arg, I don't know anything about Dev-C++ and it's auto-generated makefiles.

If you compile the program from the command prompt using the commands I gave you, it should work fine.

Once you do that, go back and figure out how to make the IDE do it.

This article has been dead for over six months. Start a new discussion instead.