Hi
it's been some time that i want to port this game, the only thing that have blocked me is that (in)famous FMODex lib that the game use to produce sound/music.
Alien8 is a game programmed by Ignacio Pérez Gil and available at Retrospec site http://retrospec.sgn.net/game/alien8
The game is programmed in C using Allegro 4 and FMODex (for the audio part). I have searched on the web but i didn't have found an ARMv7 version compatible with Pandora.
Now i managed to compile the game using SDL and SDL_Mixer instead of FMODex (with the help of the precious info from Sebt3 FMOD-->SDL previous port)....but... i need some more help as now the soundfx are working good..really good.... instead the music is absent (in part because the code that play music is not converted ).
The game run fine, i have added Pandora buttons control...but i like to add music playing before release..
So here is the Audio.c source
Thanks
it's been some time that i want to port this game, the only thing that have blocked me is that (in)famous FMODex lib that the game use to produce sound/music.
Alien8 is a game programmed by Ignacio Pérez Gil and available at Retrospec site http://retrospec.sgn.net/game/alien8
The game is programmed in C using Allegro 4 and FMODex (for the audio part). I have searched on the web but i didn't have found an ARMv7 version compatible with Pandora.
Now i managed to compile the game using SDL and SDL_Mixer instead of FMODex (with the help of the precious info from Sebt3 FMOD-->SDL previous port)....but... i need some more help as now the soundfx are working good..really good.... instead the music is absent (in part because the code that play music is not converted ).
The game run fine, i have added Pandora buttons control...but i like to add music playing before release..
So here is the Audio.c source
//******************************************************************************
// audio.c
// Funciones genericas de sonido.
// Por Ignacio Pérez Gil 17/03/2008.
//******************************************************************************
//******************************************************************************
// Includes.
//******************************************************************************
#include
#ifdef USE_FMOD
#include
#else
#include
#include
#endif
#include "audio.h"
//******************************************************************************
// Declaracion de estructuras de datos y variables globales.
//******************************************************************************
DATAFILE *f_msc = NULL;
DATAFILE *f_audio = NULL;
#ifdef USE_FMOD
FMOD_SYSTEM *sistema = NULL;
FMOD_SOUND *sm = NULL;
FMOD_CHANNEL *canal_musica = NULL;
#else
Mix_Chunk *sm = NULL;
Mix_Music *canal_musica = NULL;/// a test ..i don't know if right..farox
#endif
char musica_sonando=-1;
const char *msc_fin=NULL;
unsigned int long_msc_fin;
unsigned char vol_son=0;
float vol_mus=0;
char rep_snd_onda(SAMPLE *onda, char sonido, char bucle);
struct _voz // Estructura para almacenar los datos de las voces
{char activa; // Indica si la voz este activa
// 0-desactivada, 1-normal, 2-bucle, 3-no parar
int v; // Voz
} voz[16]={{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};
//******************************************************************************
// Funcion iniciar_audio()
// Inicializa el sistema de audio y carga los ficheros de sonidos y musica.
//******************************************************************************
void ini_audio(void)
{
reserve_voices(16,0);
install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL);
#ifdef USE_FMOD
FMOD_System_Create(&sistema);
FMOD_System_Init(sistema, 16, FMOD_INIT_NORMAL, NULL);
#else
SDL_InitSubSystem(SDL_INIT_AUDIO);
Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 2048);
#endif
f_msc = load_datafile("msc.dat");
f_audio = load_datafile("snd.dat");
}
//******************************************************************************
// Funcion finalizar_audio()
// Descarga los ficheros de sonidos y musica.
//******************************************************************************
void fin_audio(void)
{
#ifdef USE_FMOD
if(musica_sonando>=0) FMOD_Sound_Release(sm);
FMOD_System_Close(sistema);
FMOD_System_Release(sistema);
#else
if(musica_sonando>=0) Mix_HaltChannel(-1);
Mix_CloseAudio();
#endif
unload_datafile(f_msc);
unload_datafile(f_audio);
}
//******************************************************************************
// Funcion reproducir_musica(...)
// Inicia la reproduccion del fichero de musica n.
//******************************************************************************
void reproducir_musica(char n)
{
if(vol_mus)
{
#ifdef USE_FMOD
FMOD_System_Update(sistema);
#endif
if(musica_sonando!=n && n>=0)
{
#ifdef USE_FMOD
FMOD_CREATESOUNDEXINFO inf_tm;
if(musica_sonando>=0) FMOD_Sound_Release(sm);
#else
if(musica_sonando>=0) Mix_HaltChannel(-1);
#endif
musica_sonando=n;
#ifdef USE_FMOD
memset(&inf_tm, 0, sizeof(FMOD_CREATESOUNDEXINFO));
inf_tm.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
#endif
if(msc_fin)
{
#ifdef USE_FMOD
inf_tm.length=long_msc_fin;
FMOD_System_CreateStream(sistema, msc_fin, FMOD_HARDWARE | FMOD_LOOP_OFF | FMOD_OPENMEMORY, &inf_tm, &sm);
#else
//Mix_PlayMusic(n,-1);
#endif
}
else
{
#ifdef USE_FMOD
inf_tm.length=f_msc[n].size;
FMOD_System_CreateStream(sistema, (const char *)(f_msc[n].dat), FMOD_HARDWARE | FMOD_LOOP_NORMAL | FMOD_OPENMEMORY, &inf_tm, &sm);
#else
Mix_PlayMusic(f_msc[n].dat,-1);
#endif
}
#ifdef USE_FMOD
FMOD_System_PlaySound(sistema, FMOD_CHANNEL_FREE, sm, 1, &canal_musica);
FMOD_Channel_SetVolume(canal_musica,vol_mus);
FMOD_Channel_SetPaused(canal_musica,0);
#else
//
Mix_VolumeMusic(vol_mus);
#endif
}
}
}
//******************************************************************************
// Funcion modificar_volmus(...)
// Modifica el volumen de la musica.
//******************************************************************************
void modificar_volmus(unsigned char vol)
{
if(vol<=100)
{
vol_mus=vol;
vol_mus/=100;
if(musica_sonando>=0)
{
if(!vol_mus)
#ifdef USE_FMOD
{
FMOD_Channel_Stop(canal_musica);
musica_sonando=-1;
}
else
FMOD_Channel_SetVolume(canal_musica,vol_mus);
#else
{
Mix_HaltChannel(-1);
musica_sonando=-1;
}
else
Mix_VolumeMusic(vol_mus);
#endif
}
}
}
//******************************************************************************
// Funcion parar_musica()
// Detiene la musica que se este reproduciendo.
//******************************************************************************
void parar_musica(void)
{
#ifdef USE_FMOD
if(musica_sonando>=0)
{
FMOD_Sound_Release(sm);
musica_sonando=-1;
}
#else
if(musica_sonando>=0)
{
Mix_HaltChannel(-1);
musica_sonando=-1;
}
#endif
msc_fin=NULL;
}
//******************************************************************************
// Funcion musica_fin(...)
// Obtiene un puntero a la musica del fin del juego, que hay que reproducir
// una sola vez.
//******************************************************************************
void musica_fin(void *msc_fin_void, unsigned int long_msc_fin_void)
{
msc_fin=(const char *)msc_fin_void;
long_msc_fin=long_msc_fin_void;
}
//******************************************************************************
// Funcion reproducir_sonido(...)
// Reproduce el sonido indicado, con la opcion de buclearlo.
//******************************************************************************
char reproducir_sonido(char sonido, char bucle)
{
return rep_snd_onda(NULL,sonido,bucle);
}
//******************************************************************************
// Funcion reproducir_onda(...)
// Reproduce el sample indicado, con la opcion de buclearlo.
//******************************************************************************
char reproducir_onda(SAMPLE *onda, char bucle)
{
return rep_snd_onda(onda,0,bucle);
}
//******************************************************************************
// Funcion rep_snd_onda(...)
// Reproduce el sample o el sonido indicado, con el modo indicado.
//******************************************************************************
char rep_snd_onda(SAMPLE *onda, char sonido, char modo)
{
char f = -1;
if(!vol_son) return -1;
do // Busco la primera voz que no se este usando
{
f++;
if(voz[f].activa==1 || voz[f].activa==3)
if(voice_get_position(voz[f].v) == -1)
{
deallocate_voice(voz[f].v);
voz[f].activa = 0;
}
}while(voz[f].activa && f<15);
if(voz[f].activa) return -1; // Las 16 voces estan siendo usadas.
// Ahora f apunta a la voz que vamos a usar para el sonido.
voz[f].v = allocate_voice(onda?ondaSAMPLE *)f_audio[sonido].dat);
if(voz[f].v == -1) return -1;
voice_set_volume(voz[f].v, vol_son);
voice_set_playmode(voz[f].v, modo<0?PLAYMODE_PLAY:modo);
voice_start(voz[f].v);
if(modo<0)
voz[f].activa = 3;
else
voz[f].activa = (modo==PLAYMODE_PLAY?1:2);
return f;
}
//******************************************************************************
// Funcion pausar_sonidos()
// Pone los sonidos bucleados en pausa, y para los demas.
//******************************************************************************
void pausar_sonidos(void)
{
char f;
for(f=0;f<16;f++)
if(voz[f].activa)
{
if(voz[f].activa==1 || voz[f].activa==3)
{// Si la voz este parada o no este bucleada, aprovecho para liberarla.
deallocate_voice(voz[f].v);
voz[f].activa = 0;
}
else
voice_stop(voz[f].v);
}
}
//******************************************************************************
// Funcion reanudar_sonidos()
// Reanuda la reproduccion de los sonidos pausados.
//******************************************************************************
void reanudar_sonidos(void)
{
char f;
for(f=0;f<16;f++)
if(voz[f].activa)
voice_start(voz[f].v);
}
//******************************************************************************
// Funcion reiniciar_sonido(...)
// Vuelve a colocar un sonido al principio.
//******************************************************************************
void reiniciar_sonido(char vz)
{
if(vz>=0)
if(voz[vz].activa)
voice_set_position(voz[vz].v, 0);
}
//******************************************************************************
// Funcion modificar_volson(...)
// Modifica el volumen maximo de los sonidos.
//******************************************************************************
void modificar_volson(unsigned char vol, char vz)
{
float fvol=vol*2.55;
vol_son=(unsigned char)fvol;
if(vz>=0) voice_set_volume(voz[vz].v, vol_son);
}
//******************************************************************************
// Funcion detener_sonido(...)
// Detiene un sonido determinado.
//******************************************************************************
void detener_sonido(char vz)
{
if(vz>=0)
if(voz[vz].activa)
{
deallocate_voice(voz[vz].v);
voz[vz].activa = 0;
}
}
//******************************************************************************
// Funcion detener_sonidos(char todos)
// Detiene todos los sonidos que se estan reproduciendo.
//******************************************************************************
void detener_sonidos(char todos)
{
char f;
for(f=0;f<16;f++)
if(voz[f].activa>0 && (voz[f].activa || todos))
{
deallocate_voice(voz[f].v);
voz[f].activa = 0;
}
}
// audio.c
// Funciones genericas de sonido.
// Por Ignacio Pérez Gil 17/03/2008.
//******************************************************************************
//******************************************************************************
// Includes.
//******************************************************************************
#include
#ifdef USE_FMOD
#include
#else
#include
#include
#endif
#include "audio.h"
//******************************************************************************
// Declaracion de estructuras de datos y variables globales.
//******************************************************************************
DATAFILE *f_msc = NULL;
DATAFILE *f_audio = NULL;
#ifdef USE_FMOD
FMOD_SYSTEM *sistema = NULL;
FMOD_SOUND *sm = NULL;
FMOD_CHANNEL *canal_musica = NULL;
#else
Mix_Chunk *sm = NULL;
Mix_Music *canal_musica = NULL;/// a test ..i don't know if right..farox
#endif
char musica_sonando=-1;
const char *msc_fin=NULL;
unsigned int long_msc_fin;
unsigned char vol_son=0;
float vol_mus=0;
char rep_snd_onda(SAMPLE *onda, char sonido, char bucle);
struct _voz // Estructura para almacenar los datos de las voces
{char activa; // Indica si la voz este activa
// 0-desactivada, 1-normal, 2-bucle, 3-no parar
int v; // Voz
} voz[16]={{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};
//******************************************************************************
// Funcion iniciar_audio()
// Inicializa el sistema de audio y carga los ficheros de sonidos y musica.
//******************************************************************************
void ini_audio(void)
{
reserve_voices(16,0);
install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL);
#ifdef USE_FMOD
FMOD_System_Create(&sistema);
FMOD_System_Init(sistema, 16, FMOD_INIT_NORMAL, NULL);
#else
SDL_InitSubSystem(SDL_INIT_AUDIO);
Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 2048);
#endif
f_msc = load_datafile("msc.dat");
f_audio = load_datafile("snd.dat");
}
//******************************************************************************
// Funcion finalizar_audio()
// Descarga los ficheros de sonidos y musica.
//******************************************************************************
void fin_audio(void)
{
#ifdef USE_FMOD
if(musica_sonando>=0) FMOD_Sound_Release(sm);
FMOD_System_Close(sistema);
FMOD_System_Release(sistema);
#else
if(musica_sonando>=0) Mix_HaltChannel(-1);
Mix_CloseAudio();
#endif
unload_datafile(f_msc);
unload_datafile(f_audio);
}
//******************************************************************************
// Funcion reproducir_musica(...)
// Inicia la reproduccion del fichero de musica n.
//******************************************************************************
void reproducir_musica(char n)
{
if(vol_mus)
{
#ifdef USE_FMOD
FMOD_System_Update(sistema);
#endif
if(musica_sonando!=n && n>=0)
{
#ifdef USE_FMOD
FMOD_CREATESOUNDEXINFO inf_tm;
if(musica_sonando>=0) FMOD_Sound_Release(sm);
#else
if(musica_sonando>=0) Mix_HaltChannel(-1);
#endif
musica_sonando=n;
#ifdef USE_FMOD
memset(&inf_tm, 0, sizeof(FMOD_CREATESOUNDEXINFO));
inf_tm.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
#endif
if(msc_fin)
{
#ifdef USE_FMOD
inf_tm.length=long_msc_fin;
FMOD_System_CreateStream(sistema, msc_fin, FMOD_HARDWARE | FMOD_LOOP_OFF | FMOD_OPENMEMORY, &inf_tm, &sm);
#else
//Mix_PlayMusic(n,-1);
#endif
}
else
{
#ifdef USE_FMOD
inf_tm.length=f_msc[n].size;
FMOD_System_CreateStream(sistema, (const char *)(f_msc[n].dat), FMOD_HARDWARE | FMOD_LOOP_NORMAL | FMOD_OPENMEMORY, &inf_tm, &sm);
#else
Mix_PlayMusic(f_msc[n].dat,-1);
#endif
}
#ifdef USE_FMOD
FMOD_System_PlaySound(sistema, FMOD_CHANNEL_FREE, sm, 1, &canal_musica);
FMOD_Channel_SetVolume(canal_musica,vol_mus);
FMOD_Channel_SetPaused(canal_musica,0);
#else
//
Mix_VolumeMusic(vol_mus);
#endif
}
}
}
//******************************************************************************
// Funcion modificar_volmus(...)
// Modifica el volumen de la musica.
//******************************************************************************
void modificar_volmus(unsigned char vol)
{
if(vol<=100)
{
vol_mus=vol;
vol_mus/=100;
if(musica_sonando>=0)
{
if(!vol_mus)
#ifdef USE_FMOD
{
FMOD_Channel_Stop(canal_musica);
musica_sonando=-1;
}
else
FMOD_Channel_SetVolume(canal_musica,vol_mus);
#else
{
Mix_HaltChannel(-1);
musica_sonando=-1;
}
else
Mix_VolumeMusic(vol_mus);
#endif
}
}
}
//******************************************************************************
// Funcion parar_musica()
// Detiene la musica que se este reproduciendo.
//******************************************************************************
void parar_musica(void)
{
#ifdef USE_FMOD
if(musica_sonando>=0)
{
FMOD_Sound_Release(sm);
musica_sonando=-1;
}
#else
if(musica_sonando>=0)
{
Mix_HaltChannel(-1);
musica_sonando=-1;
}
#endif
msc_fin=NULL;
}
//******************************************************************************
// Funcion musica_fin(...)
// Obtiene un puntero a la musica del fin del juego, que hay que reproducir
// una sola vez.
//******************************************************************************
void musica_fin(void *msc_fin_void, unsigned int long_msc_fin_void)
{
msc_fin=(const char *)msc_fin_void;
long_msc_fin=long_msc_fin_void;
}
//******************************************************************************
// Funcion reproducir_sonido(...)
// Reproduce el sonido indicado, con la opcion de buclearlo.
//******************************************************************************
char reproducir_sonido(char sonido, char bucle)
{
return rep_snd_onda(NULL,sonido,bucle);
}
//******************************************************************************
// Funcion reproducir_onda(...)
// Reproduce el sample indicado, con la opcion de buclearlo.
//******************************************************************************
char reproducir_onda(SAMPLE *onda, char bucle)
{
return rep_snd_onda(onda,0,bucle);
}
//******************************************************************************
// Funcion rep_snd_onda(...)
// Reproduce el sample o el sonido indicado, con el modo indicado.
//******************************************************************************
char rep_snd_onda(SAMPLE *onda, char sonido, char modo)
{
char f = -1;
if(!vol_son) return -1;
do // Busco la primera voz que no se este usando
{
f++;
if(voz[f].activa==1 || voz[f].activa==3)
if(voice_get_position(voz[f].v) == -1)
{
deallocate_voice(voz[f].v);
voz[f].activa = 0;
}
}while(voz[f].activa && f<15);
if(voz[f].activa) return -1; // Las 16 voces estan siendo usadas.
// Ahora f apunta a la voz que vamos a usar para el sonido.
voz[f].v = allocate_voice(onda?ondaSAMPLE *)f_audio[sonido].dat);
if(voz[f].v == -1) return -1;
voice_set_volume(voz[f].v, vol_son);
voice_set_playmode(voz[f].v, modo<0?PLAYMODE_PLAY:modo);
voice_start(voz[f].v);
if(modo<0)
voz[f].activa = 3;
else
voz[f].activa = (modo==PLAYMODE_PLAY?1:2);
return f;
}
//******************************************************************************
// Funcion pausar_sonidos()
// Pone los sonidos bucleados en pausa, y para los demas.
//******************************************************************************
void pausar_sonidos(void)
{
char f;
for(f=0;f<16;f++)
if(voz[f].activa)
{
if(voz[f].activa==1 || voz[f].activa==3)
{// Si la voz este parada o no este bucleada, aprovecho para liberarla.
deallocate_voice(voz[f].v);
voz[f].activa = 0;
}
else
voice_stop(voz[f].v);
}
}
//******************************************************************************
// Funcion reanudar_sonidos()
// Reanuda la reproduccion de los sonidos pausados.
//******************************************************************************
void reanudar_sonidos(void)
{
char f;
for(f=0;f<16;f++)
if(voz[f].activa)
voice_start(voz[f].v);
}
//******************************************************************************
// Funcion reiniciar_sonido(...)
// Vuelve a colocar un sonido al principio.
//******************************************************************************
void reiniciar_sonido(char vz)
{
if(vz>=0)
if(voz[vz].activa)
voice_set_position(voz[vz].v, 0);
}
//******************************************************************************
// Funcion modificar_volson(...)
// Modifica el volumen maximo de los sonidos.
//******************************************************************************
void modificar_volson(unsigned char vol, char vz)
{
float fvol=vol*2.55;
vol_son=(unsigned char)fvol;
if(vz>=0) voice_set_volume(voz[vz].v, vol_son);
}
//******************************************************************************
// Funcion detener_sonido(...)
// Detiene un sonido determinado.
//******************************************************************************
void detener_sonido(char vz)
{
if(vz>=0)
if(voz[vz].activa)
{
deallocate_voice(voz[vz].v);
voz[vz].activa = 0;
}
}
//******************************************************************************
// Funcion detener_sonidos(char todos)
// Detiene todos los sonidos que se estan reproduciendo.
//******************************************************************************
void detener_sonidos(char todos)
{
char f;
for(f=0;f<16;f++)
if(voz[f].activa>0 && (voz[f].activa || todos))
{
deallocate_voice(voz[f].v);
voz[f].activa = 0;
}
}
Thanks