mirror of
https://github.com/dborth/vbagx.git
synced 2025-07-09 15:05:49 +02:00

* "Match Wii Game" controls option! Games that have a Wii equivalent can be played using the controls for that Wii game. For example all Zelda games can be played with Twilight Princess controls. See the Instructions section below for important details. * Rotation/Tilt sensor games all work * Solar sensors (Boktai 1/2/3) * Rumble (except for games that rely on Gameboy Player) * Keyboard * PAL support, finally! * New scaling options, choose how much stretching you want * Colourised games now partially work but still have distortion * "Corvette" no longer has a screwed up palette (but still crashes) * Triggers net reconnection on SMB failure * Source code refactored, and project file added * Instructions section added to this readme file
175 lines
3.7 KiB
C++
175 lines
3.7 KiB
C++
/****************************************************************************
|
|
* Visual Boy Advance GX
|
|
*
|
|
* Tantric September 2008
|
|
*
|
|
* audio.cpp
|
|
*
|
|
* Head and tail audio mixer
|
|
***************************************************************************/
|
|
|
|
#include <gccore.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "audio.h"
|
|
|
|
extern int ConfigRequested;
|
|
|
|
/** Locals **/
|
|
static int head = 0;
|
|
static int tail = 0;
|
|
static int gameType = 0;
|
|
|
|
#define MIXBUFFSIZE 0x10000
|
|
static u8 mixerdata[MIXBUFFSIZE];
|
|
#define MIXERMASK ((MIXBUFFSIZE >> 2) - 1)
|
|
#define SWAP(x) ((x>>16)|(x<<16)) // for reversing stereo channels
|
|
|
|
static u8 soundbuffer[2][3840] ATTRIBUTE_ALIGN(32);
|
|
static int whichab = 0;
|
|
static int IsPlaying = 0;
|
|
|
|
/****************************************************************************
|
|
* MIXER_GetSamples
|
|
***************************************************************************/
|
|
static int MIXER_GetSamples(u8 *dstbuffer, int maxlen)
|
|
{
|
|
u32 *src = (u32 *)mixerdata;
|
|
u32 *dst = (u32 *)dstbuffer;
|
|
u32 intlen = maxlen >> 2;
|
|
|
|
memset(dstbuffer, 0, maxlen);
|
|
|
|
while( ( head != tail ) && intlen )
|
|
{
|
|
*dst++ = src[tail++];
|
|
tail &= MIXERMASK;
|
|
intlen--;
|
|
}
|
|
|
|
return 3200;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* AudioPlayer
|
|
***************************************************************************/
|
|
|
|
static void AudioPlayer()
|
|
{
|
|
if ( !ConfigRequested )
|
|
{
|
|
int len = MIXER_GetSamples(soundbuffer[whichab], 3200);
|
|
DCFlushRange(soundbuffer[whichab],len);
|
|
AUDIO_InitDMA((u32)soundbuffer[whichab],len);
|
|
AUDIO_StartDMA();
|
|
whichab ^= 1;
|
|
IsPlaying = 1;
|
|
}
|
|
else
|
|
IsPlaying = 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* StopAudio
|
|
***************************************************************************/
|
|
|
|
void StopAudio()
|
|
{
|
|
AUDIO_StopDMA();
|
|
IsPlaying = 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* SetAudioRate
|
|
***************************************************************************/
|
|
|
|
void SetAudioRate(int type)
|
|
{
|
|
gameType = type;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* InitialiseSound
|
|
***************************************************************************/
|
|
|
|
void InitialiseSound()
|
|
{
|
|
AUDIO_Init(NULL); // Start audio subsystem
|
|
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ);
|
|
AUDIO_RegisterDMACallback(AudioPlayer);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* SoundDriver
|
|
***************************************************************************/
|
|
|
|
SoundWii::SoundWii()
|
|
{
|
|
memset(soundbuffer, 0, 3840*2);
|
|
memset(mixerdata, 0, MIXBUFFSIZE);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* SoundWii::write
|
|
*
|
|
* Upsample from 11025 to 48000
|
|
* 11025 == 15052
|
|
* 22050 == 30106
|
|
* 44100 == 60211
|
|
*
|
|
* Audio officianados should look away now !
|
|
****************************************************************************/
|
|
|
|
void SoundWii::write(u16 * finalWave, int length)
|
|
{
|
|
u32 *src = (u32 *)finalWave;
|
|
u32 *dst = (u32 *)mixerdata;
|
|
u32 intlen = (3200 >> 2);
|
|
u32 fixofs = 0;
|
|
u32 fixinc;
|
|
|
|
if (gameType == 2) // length = 1468 - GBA
|
|
fixinc = 30065;
|
|
else // length = 2940 - GB
|
|
fixinc = 60211;
|
|
|
|
do
|
|
{
|
|
// Do simple linear interpolate, and swap channels from L-R to R-L
|
|
dst[head++] = SWAP(src[fixofs >> 16]);
|
|
head &= MIXERMASK;
|
|
fixofs += fixinc;
|
|
}
|
|
while( --intlen );
|
|
|
|
// Restart Sound Processing if stopped
|
|
if (IsPlaying == 0)
|
|
{
|
|
ConfigRequested = 0;
|
|
AudioPlayer();
|
|
}
|
|
}
|
|
|
|
bool SoundWii::init(long sampleRate)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
SoundWii::~SoundWii()
|
|
{
|
|
}
|
|
|
|
void SoundWii::pause()
|
|
{
|
|
}
|
|
|
|
void SoundWii::resume()
|
|
{
|
|
}
|
|
|
|
void SoundWii::reset()
|
|
{
|
|
}
|