mirror of https://github.com/mgba-emu/mgba.git
DS: Initial touch support
This commit is contained in:
parent
e7d6cba361
commit
0cb9c41a4a
|
@ -104,6 +104,8 @@ struct mCore {
|
|||
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 @@ struct DS {
|
|||
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 DSCore {
|
|||
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 @@ static bool _DSCoreInit(struct mCore* core) {
|
|||
|
||||
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 @@ static void _DSCoreClearKeys(struct mCore* core, uint32_t keys) {
|
|||
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 @@ struct mCore* DSCoreCreate(void) {
|
|||
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 @@ static uint16_t DSIOReadExKeyInput(struct DS* ds) {
|
|||
}
|
||||
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) {
|
||||
|
|
22
src/ds/spi.c
22
src/ds/spi.c
|
@ -64,7 +64,6 @@ static void _tscEvent(struct mTiming* timing, void* context, uint32_t cyclesLate
|
|||
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 @@ static void _tscEvent(struct mTiming* timing, void* context, uint32_t cyclesLate
|
|||
}
|
||||
} 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 @@ static void _GBCoreClearKeys(struct mCore* core, uint32_t keys) {
|
|||
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 @@ struct mCore* GBCoreCreate(void) {
|
|||
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 @@ static void _GBACoreClearKeys(struct mCore* core, uint32_t keys) {
|
|||
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 @@ struct mCore* GBACoreCreate(void) {
|
|||
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 _mSDLHandleKeypress(struct mCoreThread* context, struct mSDLPlayer*
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -579,6 +598,10 @@ void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext,
|
|||
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:
|
||||
_mSDLHandleJoyButton(context->core, sdlContext, &event->jbutton);
|
||||
|
|
Loading…
Reference in New Issue