Add reverse playback support
This commit is contained in:
parent
9b877764c4
commit
048728b496
|
@ -49,7 +49,7 @@ void k053260_core::voice_t::tick(u32 cycle)
|
||||||
if (m_bitpos < 8)
|
if (m_bitpos < 8)
|
||||||
{
|
{
|
||||||
m_bitpos += 8;
|
m_bitpos += 8;
|
||||||
m_addr = bitfield(m_addr + 1, 0, 21);
|
m_addr = m_reverse ? bitfield(m_addr - 1, 0, 21) : bitfield(m_addr + 1, 0, 21);
|
||||||
m_remain--;
|
m_remain--;
|
||||||
if (m_remain < 0) // check end flag
|
if (m_remain < 0) // check end flag
|
||||||
{
|
{
|
||||||
|
@ -69,7 +69,7 @@ void k053260_core::voice_t::tick(u32 cycle)
|
||||||
if (m_adpcm)
|
if (m_adpcm)
|
||||||
{
|
{
|
||||||
m_bitpos -= 4;
|
m_bitpos -= 4;
|
||||||
const u8 nibble = bitfield(m_data, m_bitpos & 4, 4); // get nibble from ROM
|
const u8 nibble = bitfield(m_data, m_reverse ? (~m_bitpos & 4) : (m_bitpos & 4), 4); // get nibble from ROM
|
||||||
if (nibble)
|
if (nibble)
|
||||||
{
|
{
|
||||||
m_output += m_host.adpcm_lut(nibble);
|
m_output += m_host.adpcm_lut(nibble);
|
||||||
|
@ -169,6 +169,7 @@ void k053260_core::write(u8 address, u8 data)
|
||||||
case 0x28: // keyon/off toggle
|
case 0x28: // keyon/off toggle
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
|
m_voice[i].set_reverse(bitfield(data, 4 + i));
|
||||||
if (bitfield(data, i) && (!m_voice[i].enable()))
|
if (bitfield(data, i) && (!m_voice[i].enable()))
|
||||||
{ // rising edge (keyon)
|
{ // rising edge (keyon)
|
||||||
m_voice[i].keyon();
|
m_voice[i].keyon();
|
||||||
|
@ -276,6 +277,7 @@ void k053260_core::voice_t::reset()
|
||||||
m_loop = 0;
|
m_loop = 0;
|
||||||
m_adpcm = 0;
|
m_adpcm = 0;
|
||||||
m_pitch = 0;
|
m_pitch = 0;
|
||||||
|
m_reverse = 0;
|
||||||
m_start = 0;
|
m_start = 0;
|
||||||
m_length = 0;
|
m_length = 0;
|
||||||
m_volume = 0;
|
m_volume = 0;
|
||||||
|
|
|
@ -59,6 +59,7 @@ class k053260_core : public vgsound_emu_core
|
||||||
, m_loop(0)
|
, m_loop(0)
|
||||||
, m_adpcm(0)
|
, m_adpcm(0)
|
||||||
, m_pitch(0)
|
, m_pitch(0)
|
||||||
|
, m_reverse(0)
|
||||||
, m_start(0)
|
, m_start(0)
|
||||||
, m_length(0)
|
, m_length(0)
|
||||||
, m_volume(0)
|
, m_volume(0)
|
||||||
|
@ -91,6 +92,11 @@ class k053260_core : public vgsound_emu_core
|
||||||
|
|
||||||
inline void set_adpcm(bool adpcm) { m_adpcm = adpcm ? 1 : 0; }
|
inline void set_adpcm(bool adpcm) { m_adpcm = adpcm ? 1 : 0; }
|
||||||
|
|
||||||
|
inline void set_reverse(const bool reverse)
|
||||||
|
{
|
||||||
|
m_reverse = reverse ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
inline void length_inc() { m_length = (m_length + 1) & 0xffff; }
|
inline void length_inc() { m_length = (m_length + 1) & 0xffff; }
|
||||||
|
|
||||||
inline void set_pan(u8 pan) { m_pan = pan & 7; }
|
inline void set_pan(u8 pan) { m_pan = pan & 7; }
|
||||||
|
@ -114,10 +120,11 @@ class k053260_core : public vgsound_emu_core
|
||||||
u16 m_loop : 1; // loop flag
|
u16 m_loop : 1; // loop flag
|
||||||
u16 m_adpcm : 1; // ADPCM flag
|
u16 m_adpcm : 1; // ADPCM flag
|
||||||
u16 m_pitch : 12; // pitch
|
u16 m_pitch : 12; // pitch
|
||||||
|
u8 m_reverse : 1; // reverse playback
|
||||||
u32 m_start = 0; // start position
|
u32 m_start = 0; // start position
|
||||||
u16 m_length = 0; // source length
|
u16 m_length = 0; // source length
|
||||||
u8 m_volume = 0; // master volume
|
u8 m_volume = 0; // master volume
|
||||||
int m_pan = -1; // master pan
|
s32 m_pan = 4; // master pan
|
||||||
u16 m_counter = 0; // frequency counter
|
u16 m_counter = 0; // frequency counter
|
||||||
u32 m_addr = 0; // current address
|
u32 m_addr = 0; // current address
|
||||||
s32 m_remain = 0; // remain for end sample
|
s32 m_remain = 0; // remain for end sample
|
||||||
|
|
|
@ -133,7 +133,7 @@ void DivPlatformK053260::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
unsigned char keyon=regPool[0x28]|(1<<i);
|
unsigned char keyon=regPool[0x28]|(1<<i);
|
||||||
unsigned char keyoff=keyon&~(1<<i);
|
unsigned char keyoff=keyon&~(17<<i);
|
||||||
unsigned char loopon=regPool[0x2a]|(1<<i);
|
unsigned char loopon=regPool[0x2a]|(1<<i);
|
||||||
unsigned char loopoff=loopon&~(1<<i);
|
unsigned char loopoff=loopon&~(1<<i);
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
|
@ -155,10 +155,19 @@ void DivPlatformK053260::tick(bool sysTick) {
|
||||||
unsigned int length=0;
|
unsigned int length=0;
|
||||||
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
||||||
start=sampleOffK053260[chan[i].sample];
|
start=sampleOffK053260[chan[i].sample];
|
||||||
length=start+s->length8;
|
length=s->length8;
|
||||||
|
if (chan[i].reverse) {
|
||||||
|
start+=length;
|
||||||
|
keyon|=(16<<i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].audPos>0) {
|
if (chan[i].audPos>0) {
|
||||||
start=start+MIN(chan[i].audPos,s->length8);
|
if (chan[i].reverse) {
|
||||||
|
start=start-MIN(chan[i].audPos,s->length8);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
start=start+MIN(chan[i].audPos,s->length8);
|
||||||
|
}
|
||||||
length=MAX(1,length-chan[i].audPos);
|
length=MAX(1,length-chan[i].audPos);
|
||||||
}
|
}
|
||||||
start=MIN(start,getSampleMemCapacity());
|
start=MIN(start,getSampleMemCapacity());
|
||||||
|
@ -314,6 +323,12 @@ int DivPlatformK053260::dispatch(DivCommand c) {
|
||||||
chan[c.chan].audPos=c.value;
|
chan[c.chan].audPos=c.value;
|
||||||
chan[c.chan].setPos=true;
|
chan[c.chan].setPos=true;
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_SAMPLE_DIR: {
|
||||||
|
if (chan[c.chan].reverse!=(bool)(c.value&1)) {
|
||||||
|
chan[c.chan].reverse=c.value&1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
return 127;
|
return 127;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -29,7 +29,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf {
|
||||||
unsigned int audPos;
|
unsigned int audPos;
|
||||||
int sample, wave;
|
int sample, wave;
|
||||||
int panning;
|
int panning;
|
||||||
bool setPos;
|
bool setPos, reverse;
|
||||||
int macroVolMul;
|
int macroVolMul;
|
||||||
Channel():
|
Channel():
|
||||||
SharedChannel<int>(127),
|
SharedChannel<int>(127),
|
||||||
|
@ -38,6 +38,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf {
|
||||||
wave(-1),
|
wave(-1),
|
||||||
panning(4),
|
panning(4),
|
||||||
setPos(false),
|
setPos(false),
|
||||||
|
reverse(false),
|
||||||
macroVolMul(64) {}
|
macroVolMul(64) {}
|
||||||
};
|
};
|
||||||
Channel chan[4];
|
Channel chan[4];
|
||||||
|
|
|
@ -1862,7 +1862,10 @@ void DivEngine::registerSystems() {
|
||||||
{"CH1", "CH2", "CH3", "CH4"},
|
{"CH1", "CH2", "CH3", "CH4"},
|
||||||
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||||
{DIV_INS_K053260, DIV_INS_K053260, DIV_INS_K053260, DIV_INS_K053260},
|
{DIV_INS_K053260, DIV_INS_K053260, DIV_INS_K053260, DIV_INS_K053260},
|
||||||
{DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}
|
{DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA},
|
||||||
|
{
|
||||||
|
{0xdf, {DIV_CMD_SAMPLE_DIR, "DFxx: Set sample playback direction (0: normal; 1: reverse)"}}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
sysDefs[DIV_SYSTEM_DUMMY]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_DUMMY]=new DivSysDef(
|
||||||
|
|
|
@ -1101,6 +1101,7 @@ void putDispatchChan(void* data, int chanNum, int type) {
|
||||||
ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul);
|
ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul);
|
||||||
COMMON_CHAN_DEBUG_BOOL;
|
COMMON_CHAN_DEBUG_BOOL;
|
||||||
ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos");
|
ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos");
|
||||||
|
ImGui::TextColored(ch->reverse?colorOn:colorOff,">> Reverse");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue