Appending resources to .exe

Hi,

I’m using VC++ Express 2005 - does anyone know how to append resources to the .exe so I can distribute my game as a standalone executable?

Many Thanks
Ed___________________________________________________________
All New Yahoo! Mail ? Tired of unwanted email come-ons? Let our SpamGuard protect you. http://uk.docs.yahoo.com/nowyoucan.html

I’m using VC++ Express 2005 - does anyone know how to append resources to
the .exe so I can distribute my game as a standalone executable?

Resource Hacker might do what you want:

  http://www.angusj.com/resourcehacker/

Quoting Edward Byard <e_byard at yahoo.co.uk>:

*-> Hi,
*->
*-> I’m using VC++ Express 2005 - does anyone know how to append resources to
*-> the .exe so I can distribute my game as a standalone executable?
*->
*-> Many Thanks
*-> Ed

I use xpm images as header files and a bin2hex perl script that converts sound
files to a suitable format for use with SDL RWops not sure if this can be used
with ong’s for 32bit gfx----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

I’m using VC++ Express 2005 - does anyone know how to append resources to the .exe so I can distribute my game as a standalone executable?

You can add anything you want at the end of a PE (Windows) executable.
ELF (Linux) executables also support this, I think. You can build a
linked list of resources (musics, images, sounds…) at the end of the
executable and build a SDL_RWops that will read one of the entries.

I did this (well, a little bit more complicated, with compression and
stuff…) and everything works great, except that MP3 musics had to be
extracted to a regular file before being read. Apparently the code in
SDL_Mixer that detects MP3 files if not working or I have some problems
with my MP3 files and they were not being loaded properly directly from
a SDL_RWops. OGG works fine though.

Cheers,

Andre> Many Thanks

Ed

I did this (well, a little bit more complicated, with compression and
stuff…) and everything works great, except that MP3 musics had to be
extracted to a regular file before being read. Apparently the code in
SDL_Mixer that detects MP3 files if not working or I have some problems
with my MP3 files and they were not being loaded properly directly from
a SDL_RWops. OGG works fine though.

IIRC, there’s the same problem when trying to read TTF files using
SDL_ttf, too. The problem is that when creating a SDL_RWops structure from
an open file handle, you can’t limit the SDL_RWops to a subsection of the
file.

Any request to seek to the beginning/end of the SDL_RWops seeks to the
beginning/end of the containing file, not to the end of the logical file
within. This can be fixed by creating SDL_RWops manually.

struct rw_fp {
FILE *fp;
int begin, size, pos;
bool autoclose;
};

int rw_fp_seek(SDL_RWops *ctx, int offset, int whence) {
struct rw_fp data = (struct rw_fp) ctx->hidden.unknown.data1;
switch (whence) {
case SEEK_SET:
data->pos = offset;
break;
case SEEK_CUR:
data->pos += offset;
break;
case SEEK_END:
data->pos = data->size+offset;
break;
default:
return -1;
break;
}
if (data->pos<0) data->pos = 0;
if (data->pos>data->size) data->pos = data->size;
if (fseek(data->fp,data->begin+data->pos,SEEK_SET)==0)
return data->pos;
// SDL_Error(SDL_EFSEEK);
return -1;
}

int rw_fp_read(SDL_RWops *ctx, void ptr, int size, int maxnum) {
struct rw_fp data = (struct rw_fp) ctx->hidden.unknown.data1;
int n = maxnum;
int n2 = (data->size-data->pos)/size;
if (n2<n) n = n2;
// if (data->pos == data->size) return -1;
n = fread(ptr,size,n,data->fp);
data->pos += n
size;
// if (n==0 && ferror(data->fp))
// SDL_Error(SDL_EFREAD);
return n;
}

int rw_fp_write(SDL_RWops *ctx, const void ptr, int size, int num) {
struct rw_fp data = (struct rw_fp) ctx->hidden.unknown.data1;
int n = num;
int n2 = (data->size-data->pos)/size;
if (n2<n) n = n2;
// if (data->pos == data->size) return -1;
n = fwrite(ptr,size,n,data->fp);
data->pos += n
size;
// if (n==0 && ferror(data->fp))
// SDL_Error(SDL_EFWRITE);
return n;
}

int rw_fp_close(SDL_RWops *ctx) {
struct rw_fp data = (struct rw_fp) ctx->hidden.unknown.data1;
if (data->autoclose)
fclose(data->fp);
free(data);
free(ctx);
return 0;
}

SDL_RWops *rwFromFP(FILE *in, int size, bool autoclose = true) {
SDL_RWops rw = (SDL_RWops) malloc(sizeof(SDL_RWops));
if (rw==NULL) return NULL;
rw->hidden.unknown.data1 = malloc(sizeof(struct rw_fp));
if (rw->hidden.unknown.data1==NULL) {
free(rw);
return NULL;
}
struct rw_fp data = (struct rw_fp) rw->hidden.unknown.data1;
data->fp = in;
data->begin = ftell(in);
data->size = size;
data->pos = 0;
data->autoclose = autoclose;
rw->seek = rw_fp_seek;
rw->read = rw_fp_read;
rw->write = rw_fp_write;
rw->close = rw_fp_close;
return rw;
}

This allows you to create a SDL_RWops structure essentially containing
only a part of the file, which allows seeking back and forth. If others
see a need for this, I’d be glad to see this integrated into SDL.

// MartinOn Tue, 3 Apr 2007, Andre de Leiradella wrote:

Hi,On Mon, Apr 02, 2007 at 09:27 +0000, Edward Byard wrote:

I’m using VC++ Express 2005 - does anyone know how to append resources
to the .exe so I can distribute my game as a standalone executable?

There are many ways to append resources. But for distributing a standalone
executable you would need to statically link the SDL.dll. And as far as I
know now, it would be theoretically possible to do that, but nobody ever
managed to do it.

My current plan is to have a small starter application, which unpacks
everything to a temporary directory, and starts my SDL app from there.

CU,
Sec

One of the main causes of the fall of the Roman Empire
was that, lacking zero, they had no way to indicate
successful termination of their C Programs.

Hello !

There are many ways to append resources. But for distributing a standalone
executable you would need to statically link the SDL.dll. And as far as I
know now, it would be theoretically possible to do that, but nobody ever
managed to do it.

What should be so hard about linking
SDL statically to your app ?

CU

IIRC, there’s the same problem when trying to read TTF files using
SDL_ttf, too. The problem is that when creating a SDL_RWops structure from
an open file handle, you can’t limit the SDL_RWops to a subsection of the
file.

You’re right. I do essentially the same thing, but with on-the-fly decompression using bzip2. But one thing that really bothers me is having to extract MP3 files to the file system with the .mp3 extension to be able to have SDL_Mixer read it.

If someone could give me or point me to some tips about MP3 files (i.e. header structure, file signature if any) I could try to change the MP3 detecting code on SDL_Mixer…

Cheers,

Andre

You’re right. I do essentially the same thing, but with on-the-fly
decompression using bzip2. But one thing that really bothers me is
having to extract MP3 files to the file system with the .mp3 extension
to be able to have SDL_Mixer read it.

Ah, but if you do decompression you probably get the file start/end
correctly in your SDL_RWops, so that seeking works as it should. In that
case it’s probably only a problem with the MP3 file loading in SDL_Mixer,
as you suspected.

// MartinOn Wed, 4 Apr 2007, Andre de Leiradella wrote:

If I remember correctly, this is because the MP3 loading code, and many
others, do a SEEK_SET or SEEK_END style seek, meaning relative to the
overall beginning or end of your stream, not relative to where you tell
it to start. This is due to the headers and organization of these
filetypes. It is totally possible to fix this with a custom replacement
for the SDL_RWOps structure created by the RWOps open function with
custom functions which artificially restrict this seeking and even
reading/writing manually based on the ranges you give it. I believe
I’ve even done this, but can’t seem to locate my code for it at the
moment.On Thu, Apr 05, 2007 at 10:27:05AM +0300, Martin Storsj? wrote:

You’re right. I do essentially the same thing, but with on-the-fly
decompression using bzip2. But one thing that really bothers me is
having to extract MP3 files to the file system with the .mp3
extension to be able to have SDL_Mixer read it.

Ah, but if you do decompression you probably get the file start/end
correctly in your SDL_RWops, so that seeking works as it should. In
that case it’s probably only a problem with the MP3 file loading in
SDL_Mixer, as you suspected.


Steaphan Greene
Lecturer, Computer Science, Binghamton University
GPG public key: http://www.cs.binghamton.edu/~sgreene/gpg.key.txt
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20070405/b9a047da/attachment.pgp

What should be so hard about linking
SDL statically to your app ?

On Unix systems: nothing. But I’ve not seen it done on Windows systems.

From what I know, it would require me to recompile SDL, SDL_image and
all the depending libs (like zlib, libjpeg …) from source with
modifications to each of the build processes to make them static. And
just recompiling SDL on windows proved to be not as straight-forward as
on a unixoid machine beacuse you need to get things like the directx
headers right or you will get subtle bugs like e.g. a horribly lagging
audio output.

CU,
SecOn Wed, Apr 04, 2007 at 23:52 +0200, Torsten Giebl wrote:

We have always been quite clear that Win95 and Win98 are not the systems
to use if you are in a hostile security environment. We recommend Windows NT
for those environments. – Paul Leach

If I remember correctly, this is because the MP3 loading code, and many
others, do a SEEK_SET or SEEK_END style seek, meaning relative to the
overall beginning or end of your stream, not relative to where you tell
it to start. This is due to the headers and organization of these
filetypes. It is totally possible to fix this with a custom replacement
for the SDL_RWOps structure created by the RWOps open function with
custom functions which artificially restrict this seeking and even
reading/writing manually based on the ranges you give it. I believe
I’ve even done this, but can’t seem to locate my code for it at the
moment.

Yes, that’s probable. I earlier posted code for doing exactly that,
creating a SDL_RWops structure from a section of a file.

But since Andre said he’s using on-the-fly decompression using bzip2, I
assumed that he ends up with one memory block for each logical file, and
creates one SDL_RWops structure for each of them, with the correct start
and ending. If not, that’s how it should be done.

// MartinOn Thu, 5 Apr 2007, Steaphan Greene wrote:

If I remember correctly, this is because the MP3 loading code, and many
others, do a SEEK_SET or SEEK_END style seek, meaning relative to the
overall beginning or end of your stream, not relative to where you tell
it to start. This is due to the headers and organization of these
filetypes. It is totally possible to fix this with a custom replacement
for the SDL_RWOps structure created by the RWOps open function with
custom functions which artificially restrict this seeking and even
reading/writing manually based on the ranges you give it. I believe
I’ve even done this, but can’t seem to locate my code for it at the
moment.

I already do this in my code, so the problem must be something else…

Cheers,

Andre

From what I know, it would require me to recompile SDL, SDL_image and
all the depending libs (like zlib, libjpeg …) from source with
modifications to each of the build processes to make them static. And
just recompiling SDL on windows proved to be not as straight-forward as
on a unixoid machine beacuse you need to get things like the directx
headers right or you will get subtle bugs like e.g. a horribly lagging
audio output.

That sounds just like mingw-built SDL.