mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-12-24 02:01:49 +01:00
MSU1 fixes backported
The following fixes are backported from the Snes9x master branch: - Release msu data and audio streams on exit, use unzClose when closing - Fix MSU-1 channel swap on loop - Ensure all MSU-1 reads are stereo channel aligned - Clean up S9xMSU1Generate code - Fix MSU1 swapping. - Fix casting on MSU1 volume - Get rid of "Unable to find msu file" console spam
This commit is contained in:
parent
8ea78dde4a
commit
74f3ee4caf
@ -510,7 +510,7 @@ bool8 S9xInitSound (int buffer_ms, int lag_ms)
|
||||
return (FALSE);
|
||||
if (msu::landing_buffer)
|
||||
delete[] msu::landing_buffer;
|
||||
msu::landing_buffer = new uint8[msu::buffer_size * 2];
|
||||
msu::landing_buffer = (uint8*) new uint32[msu::buffer_size / 2]; // Ensure 4-byte alignment
|
||||
if (!msu::landing_buffer)
|
||||
return (FALSE);
|
||||
|
||||
@ -635,6 +635,8 @@ void S9xDeinitAPU (void)
|
||||
delete[] msu::resample_buffer;
|
||||
msu::resample_buffer = NULL;
|
||||
}
|
||||
|
||||
S9xMSU1DeInit();
|
||||
}
|
||||
|
||||
static inline int S9xAPUGetClock (int32 cpucycles)
|
||||
|
@ -17,7 +17,7 @@ class Resampler : public ring_buffer
|
||||
{
|
||||
}
|
||||
|
||||
~Resampler ()
|
||||
virtual ~Resampler ()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -4082,7 +4082,10 @@ static bool8 ReadBPSPatch (Reader *r, long, int32 &rom_size)
|
||||
|
||||
switch((int)mode) {
|
||||
case SourceRead:
|
||||
while(length--) patched_rom[outputOffset++] = Memory.ROM[outputOffset];
|
||||
while(length--) {
|
||||
patched_rom[outputOffset] = Memory.ROM[outputOffset];
|
||||
outputOffset++;
|
||||
}
|
||||
break;
|
||||
case TargetRead:
|
||||
while(length--) patched_rom[outputOffset++] = data[addr++];
|
||||
@ -4337,7 +4340,7 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
|
||||
}
|
||||
}
|
||||
|
||||
// Mercurial Magic (MSU-1 distribution pack)
|
||||
// Mercurial Magic (MSU-1 distribution pack)
|
||||
if (strcasecmp(ext, "msu1") && strcasecmp(ext, ".msu1"))
|
||||
{
|
||||
_makepath(fname, drive, dir, name, "msu1");
|
||||
@ -4350,8 +4353,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
|
||||
{
|
||||
printf(" in %s", fname);
|
||||
|
||||
ret = ReadBPSPatch(new unzReader(file), offset, rom_size);
|
||||
unzCloseCurrentFile(file);
|
||||
Stream *s = new unzStream(msu1file);
|
||||
ret = ReadBPSPatch(s, offset, rom_size);
|
||||
s->closeStream();
|
||||
|
||||
if (ret)
|
||||
printf("!\n");
|
||||
|
@ -200,7 +200,7 @@
|
||||
STREAM dataStream = NULL;
|
||||
STREAM audioStream = NULL;
|
||||
uint32 audioLoopPos;
|
||||
size_t partial_samples;
|
||||
size_t partial_frames;
|
||||
|
||||
// Sample buffer
|
||||
int16 *bufPos, *bufBegin, *bufEnd;
|
||||
@ -239,17 +239,22 @@ static int unzFindExtension(unzFile &file, const char *ext, bool restart = TRUE,
|
||||
}
|
||||
#endif
|
||||
|
||||
STREAM S9xMSU1OpenFile(char *msu_ext)
|
||||
STREAM S9xMSU1OpenFile(const char *msu_ext, bool skip_unpacked)
|
||||
{
|
||||
char filename[MAXPATHLEN];
|
||||
sprintf(filename, "%s%s%s", Memory.ROMFilePath, Memory.ROMFilename, msu_ext);
|
||||
|
||||
STREAM file = OPEN_STREAM(filename, "rb");
|
||||
if (file)
|
||||
printf("Using msu file %s.\n", filename);
|
||||
STREAM file = 0;
|
||||
|
||||
if (!skip_unpacked)
|
||||
{
|
||||
file = OPEN_STREAM(filename, "rb");
|
||||
if (file)
|
||||
printf("Using msu file %s.\n", filename);
|
||||
}
|
||||
|
||||
#ifdef UNZIP_SUPPORT
|
||||
// look for msu file in .msu1 (Mercurial Magic pack) if not found in rom dir
|
||||
// look for msu1 pack file in the rom or patch dir if msu data file not found in rom dir
|
||||
if (!file)
|
||||
{
|
||||
char zip_filename[MAXPATHLEN];
|
||||
@ -265,26 +270,28 @@ STREAM S9xMSU1OpenFile(char *msu_ext)
|
||||
file = new unzStream(unzFile);
|
||||
}
|
||||
else
|
||||
unzCloseCurrentFile(unzFile);
|
||||
unzClose(unzFile);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!file)
|
||||
printf("Unable to find msu file %s.\n", filename);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
bool AudioOpen()
|
||||
static void AudioClose()
|
||||
{
|
||||
if (audioStream)
|
||||
{
|
||||
CLOSE_STREAM(audioStream);
|
||||
audioStream = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static bool AudioOpen()
|
||||
{
|
||||
MSU1.MSU1_STATUS |= AudioError;
|
||||
|
||||
if (audioStream)
|
||||
{
|
||||
CLOSE_STREAM(audioStream);
|
||||
audioStream = NULL;
|
||||
}
|
||||
AudioClose();
|
||||
|
||||
char ext[_MAX_EXT];
|
||||
snprintf(ext, _MAX_EXT, "-%d.pcm", MSU1.MSU1_CURRENT_TRACK);
|
||||
@ -305,6 +312,8 @@ bool AudioOpen()
|
||||
audioLoopPos = GET_LE32(&audioLoopPos);
|
||||
audioLoopPos <<= 2;
|
||||
audioLoopPos += 8;
|
||||
|
||||
MSU1.MSU1_AUDIO_POS = 8;
|
||||
|
||||
MSU1.MSU1_STATUS &= ~AudioError;
|
||||
return true;
|
||||
@ -313,13 +322,18 @@ bool AudioOpen()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DataOpen()
|
||||
static void DataClose()
|
||||
{
|
||||
if (dataStream)
|
||||
{
|
||||
CLOSE_STREAM(dataStream);
|
||||
dataStream = NULL;
|
||||
}
|
||||
if (dataStream)
|
||||
{
|
||||
CLOSE_STREAM(dataStream);
|
||||
dataStream = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static bool DataOpen()
|
||||
{
|
||||
DataClose();
|
||||
|
||||
dataStream = S9xMSU1OpenFile(".msu");
|
||||
|
||||
@ -347,19 +361,11 @@ void S9xResetMSU(void)
|
||||
bufBegin = 0;
|
||||
bufEnd = 0;
|
||||
|
||||
partial_samples = 0;
|
||||
partial_frames = 0;
|
||||
|
||||
if (dataStream)
|
||||
{
|
||||
CLOSE_STREAM(dataStream);
|
||||
dataStream = NULL;
|
||||
}
|
||||
DataClose();
|
||||
|
||||
if (audioStream)
|
||||
{
|
||||
CLOSE_STREAM(audioStream);
|
||||
audioStream = NULL;
|
||||
}
|
||||
AudioClose();
|
||||
|
||||
Settings.MSU1 = S9xMSU1ROMExists();
|
||||
}
|
||||
@ -369,6 +375,13 @@ void S9xMSU1Init(void)
|
||||
DataOpen();
|
||||
}
|
||||
|
||||
void S9xMSU1DeInit(void)
|
||||
{
|
||||
DataClose();
|
||||
AudioClose();
|
||||
}
|
||||
|
||||
|
||||
bool S9xMSU1ROMExists(void)
|
||||
{
|
||||
STREAM s = S9xMSU1OpenFile(".msu");
|
||||
@ -384,7 +397,7 @@ bool S9xMSU1ROMExists(void)
|
||||
|
||||
if (unzFile)
|
||||
{
|
||||
unzCloseCurrentFile(unzFile);
|
||||
unzClose(unzFile);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -393,31 +406,30 @@ bool S9xMSU1ROMExists(void)
|
||||
|
||||
void S9xMSU1Generate(size_t sample_count)
|
||||
{
|
||||
partial_samples += 4410 * sample_count;
|
||||
partial_frames += 4410 * (sample_count / 2);
|
||||
|
||||
while (((uintptr_t)bufPos < (uintptr_t)bufEnd) && partial_samples > 3204)
|
||||
while ((bufPos < (bufEnd - 2)) && partial_frames >= 3204)
|
||||
{
|
||||
if (MSU1.MSU1_STATUS & AudioPlaying && audioStream)
|
||||
{
|
||||
int16 sample;
|
||||
int bytes_read = READ_STREAM((char *)&sample, 2, audioStream);
|
||||
if (bytes_read == 2)
|
||||
{
|
||||
sample = (int16)((double)(int16)GET_LE16(&sample) * (double)MSU1.MSU1_VOLUME / 255.0);
|
||||
int32 sample;
|
||||
int16* left = (int16*)&sample;
|
||||
int16* right = left + 1;
|
||||
|
||||
*(bufPos++) = sample;
|
||||
MSU1.MSU1_AUDIO_POS += 2;
|
||||
partial_samples -= 3204;
|
||||
int bytes_read = READ_STREAM((char *)&sample, 4, audioStream);
|
||||
if (bytes_read == 4)
|
||||
{
|
||||
*left = ((int32)(int16)GET_LE16(left) * MSU1.MSU1_VOLUME / 255);
|
||||
*right = ((int32)(int16)GET_LE16(right) * MSU1.MSU1_VOLUME / 255);
|
||||
|
||||
*(bufPos++) = *left;
|
||||
*(bufPos++) = *right;
|
||||
MSU1.MSU1_AUDIO_POS += 4;
|
||||
partial_frames -= 3204;
|
||||
}
|
||||
else
|
||||
if (bytes_read >= 0)
|
||||
{
|
||||
sample = (int16)((double)(int16)GET_LE16(&sample) * (double)MSU1.MSU1_VOLUME / 255.0);
|
||||
|
||||
*(bufPos++) = sample;
|
||||
MSU1.MSU1_AUDIO_POS += 2;
|
||||
partial_samples -= 3204;
|
||||
|
||||
if (MSU1.MSU1_STATUS & AudioRepeating)
|
||||
{
|
||||
MSU1.MSU1_AUDIO_POS = audioLoopPos;
|
||||
@ -437,7 +449,8 @@ void S9xMSU1Generate(size_t sample_count)
|
||||
else
|
||||
{
|
||||
MSU1.MSU1_STATUS &= ~(AudioPlaying | AudioRepeating);
|
||||
partial_samples -= 3204;
|
||||
partial_frames -= 3204;
|
||||
*(bufPos++) = 0;
|
||||
*(bufPos++) = 0;
|
||||
}
|
||||
}
|
||||
@ -449,7 +462,7 @@ uint8 S9xMSU1ReadPort(uint8 port)
|
||||
switch (port)
|
||||
{
|
||||
case 0:
|
||||
return MSU1.MSU1_STATUS;
|
||||
return MSU1.MSU1_STATUS | MSU1_REVISION;
|
||||
case 1:
|
||||
{
|
||||
if (MSU1.MSU1_STATUS & DataBusy)
|
||||
@ -594,5 +607,5 @@ void S9xMSU1PostLoadState(void)
|
||||
bufBegin = 0;
|
||||
bufEnd = 0;
|
||||
|
||||
partial_samples = 0;
|
||||
partial_frames = 0;
|
||||
}
|
||||
|
@ -196,6 +196,8 @@
|
||||
#include <stdint.h>
|
||||
#include <sys\stat.h>
|
||||
|
||||
#define MSU1_REVISION 0x02
|
||||
|
||||
struct SMSU1
|
||||
{
|
||||
uint8 MSU1_STATUS;
|
||||
@ -211,8 +213,7 @@ struct SMSU1
|
||||
};
|
||||
|
||||
enum SMSU1_FLAG {
|
||||
Revision = 0x02, //max: 0x07
|
||||
AudioResume = 0x04,
|
||||
Revision = 0x07, // bitmask, not the actual version number
|
||||
AudioError = 0x08,
|
||||
AudioPlaying = 0x10,
|
||||
AudioRepeating = 0x20,
|
||||
@ -230,8 +231,9 @@ extern struct SMSU1 MSU1;
|
||||
|
||||
void S9xResetMSU(void);
|
||||
void S9xMSU1Init(void);
|
||||
void S9xMSU1DeInit(void);
|
||||
bool S9xMSU1ROMExists(void);
|
||||
STREAM S9xMSU1OpenFile(char *msu_ext);
|
||||
STREAM S9xMSU1OpenFile(const char *msu_ext, bool skip_unpacked = FALSE);
|
||||
void S9xMSU1Init(void);
|
||||
void S9xMSU1Generate(size_t sample_count);
|
||||
uint8 S9xMSU1ReadPort(uint8 port);
|
||||
|
Loading…
Reference in New Issue
Block a user