Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #145 from Dwedit/submission-2
Savestate speedups and audio fixes
  • Loading branch information
inactive123 committed Apr 30, 2018
2 parents 823e278 + eb0cae6 commit b2667eb
Show file tree
Hide file tree
Showing 20 changed files with 774 additions and 80 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -12,3 +12,4 @@ sdl/gen_sdl2
sdl/build_sdl
sdl/build_sdl2

/libretro/msvc/msvc-2017/msvc-2017.vcxproj.user
13 changes: 11 additions & 2 deletions core/cart_hw/md_cart.c
Expand Up @@ -760,11 +760,16 @@ int md_cart_context_save(uint8 *state)
/* SRAM */
state[bufferptr++] = 0xff;
}
else
else if (base >= cart.rom && base < cart.rom + MAXROMSIZE)
{
/* ROM */
state[bufferptr++] = ((base - cart.rom) >> 16) & 0xff;
}
else
{
/* TMSS or special cartridge rom */
state[bufferptr++] = 0xfe;
}
}

/* hardware registers */
Expand Down Expand Up @@ -805,7 +810,7 @@ int md_cart_context_load(uint8 *state)
zbank_memory_map[i].write = sram_write_byte;

}
else
else if (offset < (MAXROMSIZE >> 16))
{
/* check if SRAM was mapped there before loading state */
if (m68k.memory_map[i].base == sram.sram)
Expand All @@ -821,6 +826,10 @@ int md_cart_context_load(uint8 *state)
/* ROM */
m68k.memory_map[i].base = cart.rom + (offset << 16);
}
else
{
/* TMSS or Special cartridge ROM mapped in by reset, leave it mapped */
}
}

/* hardware registers */
Expand Down
111 changes: 107 additions & 4 deletions core/cd_hw/cdd.c
Expand Up @@ -37,6 +37,11 @@
****************************************************************************************/
#include "shared.h"

static int cdd_get_audio_sample_difference(void);
static int cdd_get_audio_sample_offset_lba(void);

extern int8 audio_hard_disable;

#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
#define SUPPORTED_EXT 20
#else
Expand Down Expand Up @@ -223,10 +228,22 @@ void cdd_reset(void)
int cdd_context_save(uint8 *state)
{
int bufferptr = 0;
int audioSampleDifference = 0;
int indexValue = 0;

save_param(&cdd.cycles, sizeof(cdd.cycles));
save_param(&cdd.latency, sizeof(cdd.latency));
save_param(&cdd.index, sizeof(cdd.index));

/* If we are in an audio track, record the difference between LBA audio position and actual audio position */
if (cdd.toc.tracks[cdd.index].type == 0)
{
audioSampleDifference = cdd_get_audio_sample_difference();
}

/* Pack index (CD track number 0-99, now lower 8 bits) and difference between audioSampleOffset and LBA audio position (24-bit signed) into the 32-bit Index Value */
indexValue = (cdd.index & 0xFF) | (audioSampleDifference << 8);
save_param(&indexValue, sizeof(indexValue));

save_param(&cdd.lba, sizeof(cdd.lba));
save_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
save_param(&cdd.volume, sizeof(cdd.volume));
Expand All @@ -239,6 +256,8 @@ int cdd_context_load(uint8 *state)
{
int lba;
int bufferptr = 0;
int audioSampleDifference = 0;
int indexValue = 0;

#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
#ifdef DISABLE_MANY_OGG_OPEN_FILES
Expand All @@ -252,7 +271,15 @@ int cdd_context_load(uint8 *state)

load_param(&cdd.cycles, sizeof(cdd.cycles));
load_param(&cdd.latency, sizeof(cdd.latency));
load_param(&cdd.index, sizeof(cdd.index));
load_param(&indexValue, sizeof(indexValue));
/* unpack 32-bit Index value into Index (track number, lower 8 bits) and difference between actual sample position and LBA sample position (higher 24 bits) */
cdd.index = indexValue & 0xFF;
audioSampleDifference = indexValue >> 8;
/* force sign extension */
if (indexValue < 0)
{
audioSampleDifference |= 0xFF000000;
}
load_param(&cdd.lba, sizeof(cdd.lba));
load_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
load_param(&cdd.volume, sizeof(cdd.volume));
Expand All @@ -278,6 +305,16 @@ int cdd_context_load(uint8 *state)
{
/* CHD file offset */
cdd.chd.hunkofs = cdd.toc.tracks[cdd.index].offset + (lba * CD_FRAME_SIZE);
/* For a CD audio track, seek to the saved audio sample position */
if (cdd.toc.tracks[cdd.index].type == 0)
{
int sectorNumber;
int offsetWithinSector;
cdd.audioSampleOffset = cdd_get_audio_sample_offset_lba() + audioSampleDifference;
sectorNumber = (cdd.audioSampleOffset * 4) / CD_MAX_SECTOR_DATA;
offsetWithinSector = (cdd.audioSampleOffset * 4) - sectorNumber * CD_MAX_SECTOR_DATA;
cdd.chd.hunkofs = cdd.toc.tracks[cdd.index].offset + ((cdd.toc.tracks[cdd.index].start + sectorNumber) * CD_FRAME_SIZE) + offsetWithinSector;
}
}
else
#endif
Expand All @@ -289,18 +326,26 @@ int cdd_context_load(uint8 *state)
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
else if (cdd.toc.tracks[cdd.index].vf.seekable)
{
int trackOffset = cdd.toc.tracks[cdd.index].offset;
cdd.audioSampleOffset = cdd_get_audio_sample_offset_lba() + audioSampleDifference;
#ifdef DISABLE_MANY_OGG_OPEN_FILES
/* VORBIS file need to be opened first */
ov_open_callbacks(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0,cb);
#endif
/* VORBIS AUDIO track */
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (lba * 588) - cdd.toc.tracks[cdd.index].offset);
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (lba * 588) - trackOffset + audioSampleDifference);
}
#endif
else if (cdd.toc.tracks[cdd.index].fd)
{
/* PCM AUDIO track */
cdStreamSeek(cdd.toc.tracks[cdd.index].fd, (lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
const int SECTOR_SIZE = 2352;
int trackStart = cdd.toc.tracks[cdd.index].start;
int trackOffset = cdd.toc.tracks[cdd.index].offset;
int seekAddress;
cdd.audioSampleOffset = cdd_get_audio_sample_offset_lba() + audioSampleDifference;
seekAddress = trackStart * SECTOR_SIZE + cdd.audioSampleOffset * 4 - trackOffset;
cdStreamSeek(cdd.toc.tracks[cdd.index].fd, seekAddress, SEEK_SET);
}

return bufferptr;
Expand Down Expand Up @@ -1288,6 +1333,40 @@ void cdd_read_audio(unsigned int samples)
/* CD-DA fader volume setup (0-1024) */
int endVol = scd.regs[0x34>>1].w >> 4;

cdd.audioSampleOffset += samples;

if (audio_hard_disable)
{
if (endVol > curVol)
{
if (endVol - curVol < samples)
{
curVol = endVol;
}
else
{
curVol += samples;
}
}
else if (curVol > endVol)
{
if (curVol - endVol < samples)
{
curVol = endVol;
}
else
{
curVol -= samples;
}
}

/* save current CD-DA fader volume */
cdd.volume = curVol;

blip_end_frame(snd.blips[2], samples);
return;
}

/* read samples from current block */
#if defined(USE_LIBCHDR)
if (cdd.chd.file)
Expand Down Expand Up @@ -1635,6 +1714,7 @@ void cdd_update(void)
{
/* CHD file offset */
cdd.chd.hunkofs = cdd.toc.tracks[cdd.index].offset + (cdd.toc.tracks[cdd.index].start * CD_FRAME_SIZE);
cdd.audioSampleOffset = 0;
}
else
#endif
Expand All @@ -1646,12 +1726,14 @@ void cdd_update(void)
ov_open_callbacks(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0,cb);
#endif
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (cdd.toc.tracks[cdd.index].start * 588) - cdd.toc.tracks[cdd.index].offset);
cdd.audioSampleOffset = 0;
}
else
#endif
if (cdd.toc.tracks[cdd.index].fd)
{
cdStreamSeek(cdd.toc.tracks[cdd.index].fd, (cdd.toc.tracks[cdd.index].start * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
cdd.audioSampleOffset = 0;
}
}
}
Expand Down Expand Up @@ -1738,6 +1820,7 @@ void cdd_update(void)
{
/* CHD file offset */
cdd.chd.hunkofs = cdd.toc.tracks[cdd.index].offset + (cdd.lba * CD_FRAME_SIZE);
if (cdd.toc.tracks[cdd.index].type == 0) cdd.audioSampleOffset = cdd_get_audio_sample_offset_lba();
}
else
#endif
Expand All @@ -1759,12 +1842,14 @@ void cdd_update(void)
#endif
/* VORBIS AUDIO track */
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (cdd.lba * 588) - cdd.toc.tracks[cdd.index].offset);
cdd.audioSampleOffset = cdd_get_audio_sample_offset_lba();
}
#endif
else if (cdd.toc.tracks[cdd.index].fd)
{
/* PCM AUDIO track */
cdStreamSeek(cdd.toc.tracks[cdd.index].fd, (cdd.lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
cdd.audioSampleOffset = cdd_get_audio_sample_offset_lba();
}
}
}
Expand Down Expand Up @@ -1968,6 +2053,7 @@ void cdd_process(void)
{
/* CHD file offset */
cdd.chd.hunkofs = cdd.toc.tracks[cdd.index].offset + (lba * CD_FRAME_SIZE);
if (cdd.toc.tracks[cdd.index].type == 0) cdd.audioSampleOffset = cdd_get_audio_sample_offset_lba();
}
else
#endif
Expand All @@ -1981,12 +2067,14 @@ void cdd_process(void)
{
/* VORBIS AUDIO track */
ov_pcm_seek(&cdd.toc.tracks[index].vf, (lba * 588) - cdd.toc.tracks[index].offset);
cdd.audioSampleOffset = cdd_get_audio_sample_offset_lba();
}
#endif
else if (cdd.toc.tracks[index].fd)
{
/* PCM AUDIO track */
cdStreamSeek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET);
cdd.audioSampleOffset = cdd_get_audio_sample_offset_lba();
}

/* seek to current subcode position */
Expand Down Expand Up @@ -2074,6 +2162,7 @@ void cdd_process(void)
{
/* CHD file offset */
cdd.chd.hunkofs = cdd.toc.tracks[cdd.index].offset + (lba * CD_FRAME_SIZE);
if (cdd.toc.tracks[cdd.index].type == 0) cdd.audioSampleOffset = cdd_get_audio_sample_offset_lba();
}
else
#endif
Expand All @@ -2087,12 +2176,14 @@ void cdd_process(void)
{
/* VORBIS AUDIO track */
ov_pcm_seek(&cdd.toc.tracks[index].vf, (lba * 588) - cdd.toc.tracks[index].offset);
cdd.audioSampleOffset = cdd_get_audio_sample_offset_lba();
}
#endif
else if (cdd.toc.tracks[index].fd)
{
/* PCM AUDIO track */
cdStreamSeek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET);
cdd.audioSampleOffset = cdd_get_audio_sample_offset_lba();
}

/* seek to current subcode position */
Expand Down Expand Up @@ -2224,3 +2315,15 @@ void cdd_process(void)
scd.regs[0x3e>>1].byte.h + scd.regs[0x3e>>1].byte.l +
scd.regs[0x40>>1].byte.h) & 0x0f;
}

static int cdd_get_audio_sample_offset_lba(void)
{
const int SECTOR_SIZE = 2352;
int trackStart = cdd.toc.tracks[cdd.index].start;
return (cdd.lba - trackStart) * SECTOR_SIZE / 4;
}

static int cdd_get_audio_sample_difference(void)
{
return cdd.audioSampleOffset - cdd_get_audio_sample_offset_lba();
}
1 change: 1 addition & 0 deletions core/cd_hw/cdd.h
Expand Up @@ -115,6 +115,7 @@ typedef struct
chd_t chd;
#endif
int16 audio[2];
int audioSampleOffset;
} cdd_t;

/* Function prototypes */
Expand Down
50 changes: 50 additions & 0 deletions core/cd_hw/pcm.c
Expand Up @@ -37,6 +37,9 @@
****************************************************************************************/
#include "shared.h"

extern int8 audio_hard_disable;
#define SILENT_RUN_PCM_ADDRESS

extern int8 reset_do_not_clear_buffers;

#define PCM_SCYCLES_RATIO (384 * 4)
Expand Down Expand Up @@ -115,6 +118,47 @@ int pcm_context_load(uint8 *state)
return bufferptr;
}

static void pcm_run_silent(unsigned int length)
{
#ifdef SILENT_RUN_PCM_ADDRESS
/* Silent Version - Only updates sample address */
if (pcm.enabled)
{
int i, j;

/* run eight PCM channels */
for (j = 0; j<8; j++)
{
/* check if channel is enabled and increment is greater than zero */
if (pcm.status & (1 << j) && pcm.chan[j].fd.w > 0)
{
for (i = 0; i<length; i++)
{
/* read from current WAVE RAM address */
short data = pcm.ram[(pcm.chan[j].addr >> 11) & 0xffff];

/* loop data ? */
if (data == 0xff)
{
/* reset WAVE RAM address */
pcm.chan[j].addr = pcm.chan[j].ls.w << 11;
}
else
{
/* increment WAVE RAM address */
pcm.chan[j].addr += pcm.chan[j].fd.w;
}
}
}
}
}
#endif
/* end of blip buffer frame */
blip_end_frame(snd.blips[1], length);

pcm.cycles += length * PCM_SCYCLES_RATIO;
}

void pcm_run(unsigned int length)
{
#ifdef LOG_PCM
Expand All @@ -125,6 +169,12 @@ void pcm_run(unsigned int length)
int prev_l = pcm.out[0];
int prev_r = pcm.out[1];

if (audio_hard_disable)
{
pcm_run_silent(length);
return;
}

/* check if PCM chip is running */
if (pcm.enabled)
{
Expand Down
1 change: 1 addition & 0 deletions core/genesis.c
Expand Up @@ -323,6 +323,7 @@ void gen_reset(int hard_reset)
{
/* save default cartridge slot mapping */
cart.base = m68k.memory_map[0].base;
if (cart.base == boot_rom) cart.base = &cart.rom[0];

/* BOOT ROM is mapped at $000000-$0007FF */
m68k.memory_map[0].base = boot_rom;
Expand Down

0 comments on commit b2667eb

Please sign in to comment.