diff --git a/src/DSi_SPI_TSC.cpp b/src/DSi_SPI_TSC.cpp index dbb60c10..009fd98e 100644 --- a/src/DSi_SPI_TSC.cpp +++ b/src/DSi_SPI_TSC.cpp @@ -88,6 +88,8 @@ void DSi_TSC::SetTouchCoords(u16 x, u16 y) TouchX = x; TouchY = y; + DeltaX = DeltaY = 0; + u8 oldpress = Bank3Regs[0x0E] & 0x01; if (y == 0xFFF) @@ -121,6 +123,22 @@ void DSi_TSC::SetTouchCoords(u16 x, u16 y) } } +void DSi_TSC::MoveTouchCoords(u16 x, u16 y) +{ + if (TSCMode == 0x00) return TSC::MoveTouchCoords(x, y); + + if (Bank3Regs[0x0E] & 0x01) + { + return SetTouchCoords(x, y); + } + + DeltaX = (x << 4) - (TouchX & ~0x8000); + DeltaY = (y << 4) - (TouchY & ~0x8000); + + Bank3Regs[0x09] = 0x80; + Bank3Regs[0x0E] &= ~0x01; +} + void DSi_TSC::MicInputFrame(const s16* data, int samples) { if (TSCMode == 0x00) return TSC::MicInputFrame(data, samples); @@ -162,8 +180,9 @@ void DSi_TSC::Write(u8 val) { // X coordinates - if (id & 0x01) Data = TouchX >> 8; - else Data = TouchX & 0xFF; + u16 touchX = TouchX + CreateTouchOffset(DeltaX); + if (id & 0x01) Data = touchX >> 8; + else Data = touchX & 0xFF; TouchX &= 0x7FFF; } @@ -171,8 +190,9 @@ void DSi_TSC::Write(u8 val) { // Y coordinates - if (id & 0x01) Data = TouchY >> 8; - else Data = TouchY & 0xFF; + u16 touchY = TouchY + CreateTouchOffset(DeltaY); + if (id & 0x01) Data = touchY >> 8; + else Data = touchY & 0xFF; TouchY &= 0x7FFF; // checkme } diff --git a/src/DSi_SPI_TSC.h b/src/DSi_SPI_TSC.h index f20f7ac1..b3dc94ae 100644 --- a/src/DSi_SPI_TSC.h +++ b/src/DSi_SPI_TSC.h @@ -40,6 +40,7 @@ public: void SetMode(u8 mode); void SetTouchCoords(u16 x, u16 y) override; + void MoveTouchCoords(u16 x, u16 y) override; void MicInputFrame(const s16* data, int samples) override; void Write(u8 val) override; diff --git a/src/NDS.cpp b/src/NDS.cpp index 1023d3c0..4d830848 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -1122,6 +1122,11 @@ void NDS::TouchScreen(u16 x, u16 y) SPI.GetTSC()->SetTouchCoords(x, y); } +void NDS::MoveTouch(u16 x, u16 y) +{ + SPI.GetTSC()->MoveTouchCoords(x, y); +} + void NDS::ReleaseScreen() { SPI.GetTSC()->SetTouchCoords(0x000, 0xFFF); diff --git a/src/NDS.h b/src/NDS.h index b2bfb385..d578275c 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -392,6 +392,7 @@ public: // TODO: Encapsulate the rest of these members bool IsRunning() const noexcept { return Running; } void TouchScreen(u16 x, u16 y); + void MoveTouch(u16 x, u16 y); void ReleaseScreen(); void SetKeyMask(u32 mask); diff --git a/src/SPI.cpp b/src/SPI.cpp index 6ab94c3a..39b7c38f 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -352,6 +352,12 @@ void PowerMan::Write(u8 val) } +s16 TSC::CreateTouchOffset(s16 delta) const +{ + // 560190 cycles per frame + s64 cyclepos = (s64)NDS.GetSysClockCycles(2); + return (cyclepos * delta) / 560190; +} TSC::TSC(melonDS::NDS& nds) : SPIDevice(nds) { @@ -392,6 +398,8 @@ void TSC::SetTouchCoords(u16 x, u16 y) TouchX = x; TouchY = y; + DeltaX = DeltaY = 0; + if (y == 0xFFF) { // released @@ -404,6 +412,17 @@ void TSC::SetTouchCoords(u16 x, u16 y) NDS.KeyInput &= ~(1 << (16+6)); } +void TSC::MoveTouchCoords(u16 x, u16 y) +{ + if (NDS.KeyInput & (1 << (16+6))) + { + return SetTouchCoords(x, y); + } + + DeltaX = (x << 4) - TouchX; + DeltaY = (y << 4) - TouchY; +} + void TSC::MicInputFrame(const s16* data, int samples) { if (!data) @@ -433,8 +452,8 @@ void TSC::Write(u8 val) switch (ControlByte & 0x70) { - case 0x10: ConvResult = TouchY; break; - case 0x50: ConvResult = TouchX; break; + case 0x10: ConvResult = TouchY + CreateTouchOffset(DeltaY); break; + case 0x50: ConvResult = TouchX + CreateTouchOffset(DeltaX); break; case 0x60: { diff --git a/src/SPI.h b/src/SPI.h index 350708ef..f7a5b6c9 100644 --- a/src/SPI.h +++ b/src/SPI.h @@ -121,6 +121,7 @@ public: virtual void DoSavestate(Savestate* file) override; virtual void SetTouchCoords(u16 x, u16 y); + virtual void MoveTouchCoords(u16 x, u16 y); virtual void MicInputFrame(const s16* data, int samples); virtual void Write(u8 val) override; @@ -131,9 +132,12 @@ protected: u16 ConvResult; u16 TouchX, TouchY; + s16 DeltaX, DeltaY; s16 MicBuffer[1024]; int MicBufferLen; + + s16 CreateTouchOffset(s16 delta) const; };