ANDROID: Convert mouse coordinates between screen ones and virtual ones

In 2D graphical backend it's handled in the WindowedGraphicsManager
which we inherit from through OpenGLGraphicsManager
This commit is contained in:
Le Philousophe 2022-08-15 20:19:08 +02:00
parent 106b5c61ff
commit a13d0879f2
2 changed files with 66 additions and 17 deletions

View File

@ -383,9 +383,50 @@ void AndroidGraphics3dManager::displayMessageOnOSD(const Common::U32String &msg)
JNI::displayMessageOnOSD(msg);
}
Common::Point AndroidGraphics3dManager::convertScreenToVirtual(int &x, int &y) const {
const GLESBaseTexture *tex = getActiveTexture();
const Common::Rect &screenRect = tex->getDrawRect();
// Clip in place the coordinates that comes handy to call setMousePosition
x = CLIP<int>(x, screenRect.left, screenRect.right - 1);
y = CLIP<int>(y, screenRect.top, screenRect.bottom - 1);
// Now convert this to virtual coordinates using texture virtual size
const uint16 virtualWidth = tex->width();
const uint16 virtualHeight = tex->height();
int virtualX = ((x - screenRect.left) * virtualWidth + screenRect.width() / 2) / screenRect.width();
int virtualY = ((y - screenRect.top) * virtualHeight + screenRect.height() / 2) / screenRect.height();
return Common::Point(CLIP<int>(virtualX, 0, virtualWidth - 1),
CLIP<int>(virtualY, 0, virtualHeight - 1));
}
Common::Point AndroidGraphics3dManager::convertVirtualToScreen(int x, int y) const {
const GLESBaseTexture *tex = getActiveTexture();
const uint16 virtualWidth = tex->width();
const uint16 virtualHeight = tex->height();
const Common::Rect &screenRect = tex->getDrawRect();
int screenX = screenRect.left + (x * screenRect.width() + virtualWidth / 2) / virtualWidth;
int screenY = screenRect.top + (y * screenRect.height() + virtualHeight / 2) / virtualHeight;
return Common::Point(CLIP<int>(screenX, screenRect.left, screenRect.right - 1),
CLIP<int>(screenY, screenRect.top, screenRect.bottom - 1));
}
bool AndroidGraphics3dManager::notifyMousePosition(Common::Point &mouse) {
clipMouse(mouse);
setMousePosition(mouse.x, mouse.y);
// At entry, mouse is in screen coordinates like the texture draw rectangle
int x = mouse.x, y = mouse.y;
Common::Point vMouse = convertScreenToVirtual(x, y);
// Our internal mouse position is in screen coordinates
// convertScreenToVirtual just clipped coordinates so we are safe
setMousePosition(x, y);
// Now modify mouse to translate to virtual coordinates for the caller
mouse = vMouse;
return true;
}
@ -652,17 +693,30 @@ bool AndroidGraphics3dManager::showMouse(bool visible) {
}
void AndroidGraphics3dManager::warpMouse(int x, int y) {
// x and y are in virtual coordinates
ENTER("%d, %d", x, y);
// Check active coordinate instead of screen coordinate to avoid warping
// the mouse if it is still within the same virtual pixel
// Don't take the risk of modifying _cursorX and _cursorY
int cx = _cursorX, cy = _cursorY;
const Common::Point currentMouse = convertScreenToVirtual(cx, cy);
if (currentMouse.x == x && currentMouse.y == y) {
// Same virtual coordinates: nothing to do
return;
}
const Common::Point sMouse = convertVirtualToScreen(x, y);
// Our internal mouse position is in screen coordinates
// convertVirtualToScreen just clipped coordinates so we are safe
setMousePosition(sMouse.x, sMouse.y);
// Events pushed to Android system are in screen coordinates too
// They are converted back by notifyMousePosition later
Common::Event e;
e.type = Common::EVENT_MOUSEMOVE;
e.mouse.x = x;
e.mouse.y = y;
clipMouse(e.mouse);
setMousePosition(e.mouse.x, e.mouse.y);
e.mouse = sMouse;
dynamic_cast<OSystem_Android *>(g_system)->pushEvent(e);
}
@ -813,13 +867,6 @@ bool AndroidGraphics3dManager::lockMouse(bool lock) {
return true;
}
void AndroidGraphics3dManager::clipMouse(Common::Point &p) const {
const GLESBaseTexture *tex = getActiveTexture();
p.x = CLIP(p.x, tex->getDrawRect().left, tex->getDrawRect().right);
p.y = CLIP(p.y, tex->getDrawRect().top, tex->getDrawRect().bottom);
}
#ifdef USE_RGB_COLOR
Graphics::PixelFormat AndroidGraphics3dManager::getScreenFormat() const {
return _game_texture->getPixelFormat();

View File

@ -126,7 +126,9 @@ protected:
void updateScreenRect();
void updateCursorScaling();
const GLESBaseTexture *getActiveTexture() const;
void clipMouse(Common::Point &p) const;
Common::Point convertScreenToVirtual(int &x, int &y) const;
Common::Point convertVirtualToScreen(int x, int y) const;
void setSystemMousePosition(int x, int y) {}