zart Master Cheater
Reputation: 0
Joined: 20 Aug 2007 Posts: 351 Location: russia
|
Posted: Fri Aug 24, 2007 10:10 am Post subject: [snippet : c++] embedding/playing xm files |
|
|
A while back when I was making a keygen i wanted to add music to it like most release groups do. The use extended modules (.xm) which is a popular chiptune format so I looked into how to embed though in a program written in C++
Took me a little while but it's actually pretty easy, hacked together a few snippets i found on the web and came up with this. Most of the snippets where from minifmod sites... Though I no longer have the links to them so I can't cite them properly anyway, this is only one way to do it. You could put all your song data in a header file... but that gets messy having to increase heap size if the song is too big etc etc. It's 'easier' to place them in the header in the shortrun, but a pain in the arse in the long run.
main code;
Code: |
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include "minifmod.h"
// structure needed by minifmod
typedef struct
{
int length;
int pos;
void *data;
} MEMFILE;
// make a function to return the pointer value to our xm file
#ifdef __cplusplus
extern "C" {
unsigned char *__cdecl gmus(void);
int __cdecl gsize(void);
}
#endif
// mem open function - basicly the same thing as the original for minifmod but change a bit for us
unsigned int memopen(char *name)
{
MEMFILE *memfile;
memfile = (MEMFILE *)calloc(sizeof(MEMFILE),1);
if (!memfile) return 0;
memfile->length = gsize();
memfile->pos = 0;
memfile->data = (void *)gmus();
return (unsigned int)memfile;
}
// close pointer
void memclose(unsigned int handle)
{
MEMFILE *memfile = (MEMFILE *)handle;
free(memfile);
}
// read data
int memread(void *buffer, int size, unsigned int handle)
{
MEMFILE *memfile = (MEMFILE *)handle;
if (memfile->pos + size >= memfile->length)
size = memfile->length - memfile->pos;
memcpy(buffer, (char *)memfile->data+memfile->pos, size);
memfile->pos += size;
return size;
}
// seek the music data
void memseek(unsigned int handle, int pos, signed char mode)
{
MEMFILE *memfile = (MEMFILE *)handle;
if (mode == SEEK_SET)
memfile->pos = pos;
else if (mode == SEEK_CUR)
memfile->pos += pos;
else if (mode == SEEK_END)
memfile->pos = memfile->length + pos;
if (memfile->pos > memfile->length)
memfile->pos = memfile->length;
}
// get pointer to music data
int memtell(unsigned int handle)
{
MEMFILE *memfile = (MEMFILE *)handle;
return memfile->pos;
}
void main()
{
FMUSIC_MODULE *mod;
// setup the callbacks for minifmod
FSOUND_File_SetCallbacks ( memopen, memclose, memread, memseek, memtell );
// initialize sound
if (!FSOUND_Init(44100, 0))
{
printf("Error upon initialization\n");
return;
}
// load the music
mod = FMUSIC_LoadSong ( NULL, NULL ); //sampleloadcallback);
if (!mod)
{
printf("Error loading song\n");
return;
}
// play song
FMUSIC_PlaySong(mod);
printf("Press ESC to quit\n");
char key = 0;
do
{
int ord = 0, row = 0;
float mytime = 0;
if (kbhit())
{
key = getch();
}
} while (key != 27);
// release mem
FMUSIC_FreeSong(mod);
FSOUND_Close();
}
|
note you need minifmod.h - google it!
this is the asm code (written for the nasm compiler) to actually embed the music and give the c++ program the functionality to find it;
Code: |
SECTION .code
BITS 32
global _gmus, _gsize
_gmus:
mov eax, _datafile
ret
_gsize:
mov eax, dword _filelen
ret
SECTION .data
_datafile:
incbin "embedme.xm"
_filelen equ $-_datafile
|
note - to compile the program to include the asm you need to have an asm compiler compile the object... this is done (in MSC++) by changing the settings for the asm file to allow a custom build as follows;
commands:
D:\nasm\nasm-0.98.39\nasmw -o $(OutDir)\$(InputName).obj -f win32 $(InputDir)\$(InputName).asm
outputs:
$(Outdir)\$(InputName).obj
Change that directory to your nasm compiler
Hope this is a useful snippet, post questions here if you need a better explanation - though I though the code was pretty self explanatory.
edit: Oh yea, this is also a functional use to the kbhit() snippet i posted earlier
_________________
0x7A 0x61 0x72 0x74
TEAM RESURRECTiON |
|