mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-11-23 19:19:22 +01:00
commit
f8d206b87d
@ -510,7 +510,7 @@ bool8 S9xInitSound (int buffer_ms, int lag_ms)
|
|||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (msu::landing_buffer)
|
if (msu::landing_buffer)
|
||||||
delete[] 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)
|
if (!msu::landing_buffer)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
@ -635,6 +635,8 @@ void S9xDeinitAPU (void)
|
|||||||
delete[] msu::resample_buffer;
|
delete[] msu::resample_buffer;
|
||||||
msu::resample_buffer = NULL;
|
msu::resample_buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
S9xMSU1DeInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int S9xAPUGetClock (int32 cpucycles)
|
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) {
|
switch((int)mode) {
|
||||||
case SourceRead:
|
case SourceRead:
|
||||||
while(length--) patched_rom[outputOffset++] = Memory.ROM[outputOffset];
|
while(length--) {
|
||||||
|
patched_rom[outputOffset] = Memory.ROM[outputOffset];
|
||||||
|
outputOffset++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TargetRead:
|
case TargetRead:
|
||||||
while(length--) patched_rom[outputOffset++] = data[addr++];
|
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"))
|
if (strcasecmp(ext, "msu1") && strcasecmp(ext, ".msu1"))
|
||||||
{
|
{
|
||||||
_makepath(fname, drive, dir, name, "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);
|
printf(" in %s", fname);
|
||||||
|
|
||||||
ret = ReadBPSPatch(new unzReader(file), offset, rom_size);
|
Stream *s = new unzStream(msu1file);
|
||||||
unzCloseCurrentFile(file);
|
ret = ReadBPSPatch(s, offset, rom_size);
|
||||||
|
s->closeStream();
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
printf("!\n");
|
printf("!\n");
|
||||||
|
@ -200,7 +200,7 @@
|
|||||||
STREAM dataStream = NULL;
|
STREAM dataStream = NULL;
|
||||||
STREAM audioStream = NULL;
|
STREAM audioStream = NULL;
|
||||||
uint32 audioLoopPos;
|
uint32 audioLoopPos;
|
||||||
size_t partial_samples;
|
size_t partial_frames;
|
||||||
|
|
||||||
// Sample buffer
|
// Sample buffer
|
||||||
int16 *bufPos, *bufBegin, *bufEnd;
|
int16 *bufPos, *bufBegin, *bufEnd;
|
||||||
@ -239,17 +239,22 @@ static int unzFindExtension(unzFile &file, const char *ext, bool restart = TRUE,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STREAM S9xMSU1OpenFile(char *msu_ext)
|
STREAM S9xMSU1OpenFile(const char *msu_ext, bool skip_unpacked)
|
||||||
{
|
{
|
||||||
char filename[MAXPATHLEN];
|
char filename[MAXPATHLEN];
|
||||||
sprintf(filename, "%s%s%s", Memory.ROMFilePath, Memory.ROMFilename, msu_ext);
|
sprintf(filename, "%s%s%s", Memory.ROMFilePath, Memory.ROMFilename, msu_ext);
|
||||||
|
|
||||||
STREAM file = OPEN_STREAM(filename, "rb");
|
STREAM file = 0;
|
||||||
if (file)
|
|
||||||
printf("Using msu file %s.\n", filename);
|
if (!skip_unpacked)
|
||||||
|
{
|
||||||
|
file = OPEN_STREAM(filename, "rb");
|
||||||
|
if (file)
|
||||||
|
printf("Using msu file %s.\n", filename);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef UNZIP_SUPPORT
|
#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)
|
if (!file)
|
||||||
{
|
{
|
||||||
char zip_filename[MAXPATHLEN];
|
char zip_filename[MAXPATHLEN];
|
||||||
@ -265,26 +270,28 @@ STREAM S9xMSU1OpenFile(char *msu_ext)
|
|||||||
file = new unzStream(unzFile);
|
file = new unzStream(unzFile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
unzCloseCurrentFile(unzFile);
|
unzClose(unzFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!file)
|
|
||||||
printf("Unable to find msu file %s.\n", filename);
|
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioOpen()
|
static void AudioClose()
|
||||||
|
{
|
||||||
|
if (audioStream)
|
||||||
|
{
|
||||||
|
CLOSE_STREAM(audioStream);
|
||||||
|
audioStream = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool AudioOpen()
|
||||||
{
|
{
|
||||||
MSU1.MSU1_STATUS |= AudioError;
|
MSU1.MSU1_STATUS |= AudioError;
|
||||||
|
|
||||||
if (audioStream)
|
AudioClose();
|
||||||
{
|
|
||||||
CLOSE_STREAM(audioStream);
|
|
||||||
audioStream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char ext[_MAX_EXT];
|
char ext[_MAX_EXT];
|
||||||
snprintf(ext, _MAX_EXT, "-%d.pcm", MSU1.MSU1_CURRENT_TRACK);
|
snprintf(ext, _MAX_EXT, "-%d.pcm", MSU1.MSU1_CURRENT_TRACK);
|
||||||
@ -305,6 +312,8 @@ bool AudioOpen()
|
|||||||
audioLoopPos = GET_LE32(&audioLoopPos);
|
audioLoopPos = GET_LE32(&audioLoopPos);
|
||||||
audioLoopPos <<= 2;
|
audioLoopPos <<= 2;
|
||||||
audioLoopPos += 8;
|
audioLoopPos += 8;
|
||||||
|
|
||||||
|
MSU1.MSU1_AUDIO_POS = 8;
|
||||||
|
|
||||||
MSU1.MSU1_STATUS &= ~AudioError;
|
MSU1.MSU1_STATUS &= ~AudioError;
|
||||||
return true;
|
return true;
|
||||||
@ -313,13 +322,18 @@ bool AudioOpen()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DataOpen()
|
static void DataClose()
|
||||||
{
|
{
|
||||||
if (dataStream)
|
if (dataStream)
|
||||||
{
|
{
|
||||||
CLOSE_STREAM(dataStream);
|
CLOSE_STREAM(dataStream);
|
||||||
dataStream = NULL;
|
dataStream = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DataOpen()
|
||||||
|
{
|
||||||
|
DataClose();
|
||||||
|
|
||||||
dataStream = S9xMSU1OpenFile(".msu");
|
dataStream = S9xMSU1OpenFile(".msu");
|
||||||
|
|
||||||
@ -347,19 +361,11 @@ void S9xResetMSU(void)
|
|||||||
bufBegin = 0;
|
bufBegin = 0;
|
||||||
bufEnd = 0;
|
bufEnd = 0;
|
||||||
|
|
||||||
partial_samples = 0;
|
partial_frames = 0;
|
||||||
|
|
||||||
if (dataStream)
|
DataClose();
|
||||||
{
|
|
||||||
CLOSE_STREAM(dataStream);
|
|
||||||
dataStream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (audioStream)
|
AudioClose();
|
||||||
{
|
|
||||||
CLOSE_STREAM(audioStream);
|
|
||||||
audioStream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings.MSU1 = S9xMSU1ROMExists();
|
Settings.MSU1 = S9xMSU1ROMExists();
|
||||||
}
|
}
|
||||||
@ -369,6 +375,13 @@ void S9xMSU1Init(void)
|
|||||||
DataOpen();
|
DataOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void S9xMSU1DeInit(void)
|
||||||
|
{
|
||||||
|
DataClose();
|
||||||
|
AudioClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool S9xMSU1ROMExists(void)
|
bool S9xMSU1ROMExists(void)
|
||||||
{
|
{
|
||||||
STREAM s = S9xMSU1OpenFile(".msu");
|
STREAM s = S9xMSU1OpenFile(".msu");
|
||||||
@ -384,7 +397,7 @@ bool S9xMSU1ROMExists(void)
|
|||||||
|
|
||||||
if (unzFile)
|
if (unzFile)
|
||||||
{
|
{
|
||||||
unzCloseCurrentFile(unzFile);
|
unzClose(unzFile);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -393,31 +406,30 @@ bool S9xMSU1ROMExists(void)
|
|||||||
|
|
||||||
void S9xMSU1Generate(size_t sample_count)
|
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)
|
if (MSU1.MSU1_STATUS & AudioPlaying && audioStream)
|
||||||
{
|
{
|
||||||
int16 sample;
|
int32 sample;
|
||||||
int bytes_read = READ_STREAM((char *)&sample, 2, audioStream);
|
int16* left = (int16*)&sample;
|
||||||
if (bytes_read == 2)
|
int16* right = left + 1;
|
||||||
{
|
|
||||||
sample = (int16)((double)(int16)GET_LE16(&sample) * (double)MSU1.MSU1_VOLUME / 255.0);
|
|
||||||
|
|
||||||
*(bufPos++) = sample;
|
int bytes_read = READ_STREAM((char *)&sample, 4, audioStream);
|
||||||
MSU1.MSU1_AUDIO_POS += 2;
|
if (bytes_read == 4)
|
||||||
partial_samples -= 3204;
|
{
|
||||||
|
*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
|
else
|
||||||
if (bytes_read >= 0)
|
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)
|
if (MSU1.MSU1_STATUS & AudioRepeating)
|
||||||
{
|
{
|
||||||
MSU1.MSU1_AUDIO_POS = audioLoopPos;
|
MSU1.MSU1_AUDIO_POS = audioLoopPos;
|
||||||
@ -437,7 +449,8 @@ void S9xMSU1Generate(size_t sample_count)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
MSU1.MSU1_STATUS &= ~(AudioPlaying | AudioRepeating);
|
MSU1.MSU1_STATUS &= ~(AudioPlaying | AudioRepeating);
|
||||||
partial_samples -= 3204;
|
partial_frames -= 3204;
|
||||||
|
*(bufPos++) = 0;
|
||||||
*(bufPos++) = 0;
|
*(bufPos++) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -449,7 +462,7 @@ uint8 S9xMSU1ReadPort(uint8 port)
|
|||||||
switch (port)
|
switch (port)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return MSU1.MSU1_STATUS;
|
return MSU1.MSU1_STATUS | MSU1_REVISION;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if (MSU1.MSU1_STATUS & DataBusy)
|
if (MSU1.MSU1_STATUS & DataBusy)
|
||||||
@ -594,5 +607,5 @@ void S9xMSU1PostLoadState(void)
|
|||||||
bufBegin = 0;
|
bufBegin = 0;
|
||||||
bufEnd = 0;
|
bufEnd = 0;
|
||||||
|
|
||||||
partial_samples = 0;
|
partial_frames = 0;
|
||||||
}
|
}
|
||||||
|
@ -196,6 +196,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys\stat.h>
|
#include <sys\stat.h>
|
||||||
|
|
||||||
|
#define MSU1_REVISION 0x02
|
||||||
|
|
||||||
struct SMSU1
|
struct SMSU1
|
||||||
{
|
{
|
||||||
uint8 MSU1_STATUS;
|
uint8 MSU1_STATUS;
|
||||||
@ -211,8 +213,7 @@ struct SMSU1
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum SMSU1_FLAG {
|
enum SMSU1_FLAG {
|
||||||
Revision = 0x02, //max: 0x07
|
Revision = 0x07, // bitmask, not the actual version number
|
||||||
AudioResume = 0x04,
|
|
||||||
AudioError = 0x08,
|
AudioError = 0x08,
|
||||||
AudioPlaying = 0x10,
|
AudioPlaying = 0x10,
|
||||||
AudioRepeating = 0x20,
|
AudioRepeating = 0x20,
|
||||||
@ -230,8 +231,9 @@ extern struct SMSU1 MSU1;
|
|||||||
|
|
||||||
void S9xResetMSU(void);
|
void S9xResetMSU(void);
|
||||||
void S9xMSU1Init(void);
|
void S9xMSU1Init(void);
|
||||||
|
void S9xMSU1DeInit(void);
|
||||||
bool S9xMSU1ROMExists(void);
|
bool S9xMSU1ROMExists(void);
|
||||||
STREAM S9xMSU1OpenFile(char *msu_ext);
|
STREAM S9xMSU1OpenFile(const char *msu_ext, bool skip_unpacked = FALSE);
|
||||||
void S9xMSU1Init(void);
|
void S9xMSU1Init(void);
|
||||||
void S9xMSU1Generate(size_t sample_count);
|
void S9xMSU1Generate(size_t sample_count);
|
||||||
uint8 S9xMSU1ReadPort(uint8 port);
|
uint8 S9xMSU1ReadPort(uint8 port);
|
||||||
|
Loading…
Reference in New Issue
Block a user