diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp index b1c56a8d7..59d8af8f7 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp @@ -49,7 +49,7 @@ void k053260_core::voice_t::tick(u32 cycle) if (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--; if (m_remain < 0) // check end flag { @@ -69,7 +69,7 @@ void k053260_core::voice_t::tick(u32 cycle) if (m_adpcm) { 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) { m_output += m_host.adpcm_lut(nibble); @@ -169,6 +169,7 @@ void k053260_core::write(u8 address, u8 data) case 0x28: // keyon/off toggle for (int i = 0; i < 4; i++) { + m_voice[i].set_reverse(bitfield(data, 4 + i)); if (bitfield(data, i) && (!m_voice[i].enable())) { // rising edge (keyon) m_voice[i].keyon(); @@ -276,6 +277,7 @@ void k053260_core::voice_t::reset() m_loop = 0; m_adpcm = 0; m_pitch = 0; + m_reverse = 0; m_start = 0; m_length = 0; m_volume = 0; diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp index bfb7ea002..9eb81363d 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp @@ -59,6 +59,7 @@ class k053260_core : public vgsound_emu_core , m_loop(0) , m_adpcm(0) , m_pitch(0) + , m_reverse(0) , m_start(0) , m_length(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_reverse(const bool reverse) + { + m_reverse = reverse ? 1 : 0; + } + inline void length_inc() { m_length = (m_length + 1) & 0xffff; } 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_adpcm : 1; // ADPCM flag u16 m_pitch : 12; // pitch + u8 m_reverse : 1; // reverse playback u32 m_start = 0; // start position u16 m_length = 0; // source length u8 m_volume = 0; // master volume - int m_pan = -1; // master pan + s32 m_pan = 4; // master pan u16 m_counter = 0; // frequency counter u32 m_addr = 0; // current address s32 m_remain = 0; // remain for end sample diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index dd8364fa1..b35bc5a27 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -133,7 +133,7 @@ void DivPlatformK053260::tick(bool sysTick) { } if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { unsigned char keyon=regPool[0x28]|(1<=0 && chan[i].samplesong.sampleLen) { start=sampleOffK053260[chan[i].sample]; - length=start+s->length8; + length=s->length8; + if (chan[i].reverse) { + start+=length; + keyon|=(16<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); } start=MIN(start,getSampleMemCapacity()); @@ -314,6 +323,12 @@ int DivPlatformK053260::dispatch(DivCommand c) { chan[c.chan].audPos=c.value; chan[c.chan].setPos=true; 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: return 127; break; diff --git a/src/engine/platform/k053260.h b/src/engine/platform/k053260.h index 3b21cb4dc..42ae0565a 100644 --- a/src/engine/platform/k053260.h +++ b/src/engine/platform/k053260.h @@ -29,7 +29,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf { unsigned int audPos; int sample, wave; int panning; - bool setPos; + bool setPos, reverse; int macroVolMul; Channel(): SharedChannel(127), @@ -38,6 +38,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf { wave(-1), panning(4), setPos(false), + reverse(false), macroVolMul(64) {} }; Channel chan[4]; diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index f236fcd2c..0ce88965e 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1862,7 +1862,10 @@ void DivEngine::registerSystems() { {"CH1", "CH2", "CH3", "CH4"}, {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_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( diff --git a/src/gui/debug.cpp b/src/gui/debug.cpp index 7a01edf8e..b1cdb2920 100644 --- a/src/gui/debug.cpp +++ b/src/gui/debug.cpp @@ -1101,6 +1101,7 @@ void putDispatchChan(void* data, int chanNum, int type) { ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul); COMMON_CHAN_DEBUG_BOOL; ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos"); + ImGui::TextColored(ch->reverse?colorOn:colorOff,">> Reverse"); break; } default: