DS: Initial touch support
@@ -104,6 +104,8 @@ void (*setKeys)(struct mCore*, uint32_t keys);
void (*addKeys)(struct mCore*, uint32_t keys); void (*clearKeys)(struct mCore*, uint32_t keys); + void (*setCursor)(struct mCore*, int x, int y, bool down); + int32_t (*frameCounter)(const struct mCore*); int32_t (*frameCycles)(const struct mCore*); int32_t (*frequency)(const struct mCore*);
@@ -95,6 +95,9 @@
uint32_t bios7Checksum; uint32_t bios9Checksum; int* keySource; + int* cursorSourceX; + int* cursorSourceY; + bool* touchSource; struct mRTCSource* rtcSource; struct mRumble* rumble;
@@ -22,6 +22,9 @@ struct ARMCore* arm7;
struct ARMCore* arm9; struct DSVideoSoftwareRenderer renderer; int keys; + int cursorX; + int cursorY; + bool touchDown; struct mCPUComponent* components[CPU_COMPONENT_MAX]; struct mDebuggerPlatform* debuggerPlatform; struct mCheatDevice* cheatDevice;@@ -59,6 +62,12 @@ dscore->renderer.outputBuffer = NULL;
dscore->keys = 0; ds->keySource = &dscore->keys; + dscore->cursorX = 0; + ds->cursorSourceX = &dscore->cursorX; + dscore->cursorY = 0; + ds->cursorSourceY = &dscore->cursorY; + dscore->touchDown = false; + ds->touchSource = &dscore->touchDown; #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 mDirectorySetInit(&core->dirs);@@ -308,6 +317,15 @@ struct DSCore* dscore = (struct DSCore*) core;
dscore->keys &= ~keys; } +static void _DSCoreSetCursor(struct mCore* core, int x, int y, bool down) { + struct DSCore* dscore = (struct DSCore*) core; + dscore->cursorX = x; + dscore->cursorY = y - DS_VIDEO_VERTICAL_PIXELS; + if ((down && y >= 0) || !down) { + dscore->touchDown = down; + } +} + static int32_t _DSCoreFrameCounter(const struct mCore* core) { struct DS* ds = core->board; return ds->video.frameCounter;@@ -493,6 +511,7 @@ core->saveState = _DSCoreSaveState;
core->setKeys = _DSCoreSetKeys; core->addKeys = _DSCoreAddKeys; core->clearKeys = _DSCoreClearKeys; + core->setCursor = _DSCoreSetCursor; core->frameCounter = _DSCoreFrameCounter; core->frameCycles = _DSCoreFrameCycles; core->frequency = _DSCoreFrequency;
@@ -213,6 +213,7 @@ input = *ds->keySource;
} input = ~(input >> 10) & 0x3; input |= 0x3C; + input |= ds->memory.io7[DS7_REG_EXTKEYIN >> 1] & 0xC0; return input; }@@ -259,6 +260,7 @@ void DS7IOInit(struct DS* ds) {
memset(ds->memory.io7, 0, sizeof(ds->memory.io7)); ds->memory.io7[DS_REG_IPCFIFOCNT >> 1] = 0x0101; ds->memory.io7[DS_REG_POSTFLG >> 1] = 0x0001; + ds->memory.io7[DS7_REG_EXTKEYIN >> 1] = 0x007F; } void DS7IOWrite(struct DS* ds, uint32_t address, uint16_t value) {
@@ -64,7 +64,6 @@ uint8_t oldValue = ds->memory.io7[DS7_REG_SPIDATA >> 1];
DSSPICNT control = ds->memory.io7[DS7_REG_SPICNT >> 1]; uint8_t newValue = 0; - // TODO: /PENIRQ if (ds->memory.spiBus.tscOffset > 0) { // TODO: Make generic? if (ds->memory.spiBus.tscOffset < 12) {@@ -75,15 +74,28 @@ newValue = 0;
} } else if (ds->memory.spiBus.tscControlByte) { switch (DSTSCControlByteGetChannel(ds->memory.spiBus.tscControlByte)) { + // TODO: Calibrate from firmware case DS_TSC_CHANNEL_TS_X: - mLOG(DS_SPI, STUB, "Unimplemented TSC channel X"); - ds->memory.spiBus.tscRegister = 0; + if (*ds->touchSource) { + ds->memory.spiBus.tscRegister = (*ds->cursorSourceX * 0xDD0 / DS_VIDEO_HORIZONTAL_PIXELS) + 0x100; + } else { + ds->memory.spiBus.tscRegister = 0; + } break; case DS_TSC_CHANNEL_TS_Y: - mLOG(DS_SPI, STUB, "Unimplemented TSC channel Y"); - ds->memory.spiBus.tscRegister = 0xFFF; + if (*ds->touchSource) { + ds->memory.spiBus.tscRegister = (*ds->cursorSourceY * 0xE70 / DS_VIDEO_VERTICAL_PIXELS) + 0x0B0; + } else { + ds->memory.spiBus.tscRegister = 0xFFF; + } break; case DS_TSC_CHANNEL_TEMP_0: + if (*ds->touchSource) { + ds->memory.io7[DS7_REG_EXTKEYIN >> 1] &= ~0x040; + } else { + ds->memory.io7[DS7_REG_EXTKEYIN >> 1] |= 0x040; + } + break; case DS_TSC_CHANNEL_BATTERY_V: case DS_TSC_CHANNEL_TS_Z1: case DS_TSC_CHANNEL_TS_Z2:
@@ -360,6 +360,13 @@ struct GBCore* gbcore = (struct GBCore*) core;
gbcore->keys &= ~keys; } +static void _GBCoreSetCursor(struct mCore* core, int x, int y, bool down) { + UNUSED(core); + UNUSED(x); + UNUSED(y); + UNUSED(down); +} + static int32_t _GBCoreFrameCounter(const struct mCore* core) { const struct GB* gb = core->board; return gb->video.frameCounter;@@ -595,6 +602,7 @@ core->saveState = _GBCoreSaveState;
core->setKeys = _GBCoreSetKeys; core->addKeys = _GBCoreAddKeys; core->clearKeys = _GBCoreClearKeys; + core->setCursor = _GBCoreSetCursor; core->frameCounter = _GBCoreFrameCounter; core->frameCycles = _GBCoreFrameCycles; core->frequency = _GBCoreFrequency;
@@ -373,6 +373,13 @@ struct GBACore* gbacore = (struct GBACore*) core;
gbacore->keys &= ~keys; } +static void _GBACoreSetCursor(struct mCore* core, int x, int y, bool down) { + UNUSED(core); + UNUSED(x); + UNUSED(y); + UNUSED(down); +} + static int32_t _GBACoreFrameCounter(const struct mCore* core) { const struct GBA* gba = core->board; return gba->video.frameCounter;@@ -609,6 +616,7 @@ core->saveState = _GBACoreSaveState;
core->setKeys = _GBACoreSetKeys; core->addKeys = _GBACoreAddKeys; core->clearKeys = _GBACoreClearKeys; + core->setCursor = _GBACoreSetCursor; core->frameCounter = _GBACoreFrameCounter; core->frameCycles = _GBACoreFrameCycles; core->frequency = _GBACoreFrequency;
@@ -516,6 +516,25 @@ }
} } +static void _mSDLHandleMouseButton(struct mCore* core, struct mSDLPlayer* sdlContext, const struct SDL_MouseButtonEvent* event) { + if (event->button != SDL_BUTTON_LEFT) { + return; + } + int x = event->x; + int y = event->y; +#if SDL_VERSION_ATLEAST(2, 0, 0) + int windowW; + int windowH; + SDL_GetWindowSize(sdlContext->window, &windowW, &windowH); + unsigned coreW; + unsigned coreH; + core->desiredVideoDimensions(core, &coreW, &coreH); + x = x * coreW / windowW; + y = y * coreH / windowH; +#endif + core->setCursor(core, x, y, event->state == SDL_PRESSED); +} + static void _mSDLHandleJoyButton(struct mCore* core, struct mSDLPlayer* sdlContext, const struct SDL_JoyButtonEvent* event) { int key = 0; key = mInputMapKey(sdlContext->bindings, SDL_BINDING_BUTTON, event->button);@@ -578,6 +597,10 @@ #endif
case SDL_KEYDOWN: case SDL_KEYUP: _mSDLHandleKeypress(context, sdlContext, &event->key); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + _mSDLHandleMouseButton(context->core, sdlContext, &event->button); break; case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: